diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md index e630b3dbfc..c99a8b49fa 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -6,9 +6,9 @@ labels: ISSUE NEEDS REVIEW assignees: '' --- -### Have you first reported the issue on the rocknix discord and checked rocknix.org for a solution? -[ROCKNIX DISCORD](https://discord.gg/NG6wGmSe) - +### Have you first checked existing issues and documentation for a solution? +[ArchR GitHub Issues](https://github.com/archr-linux/distribution/issues) + ### Describe the bug @@ -20,7 +20,7 @@ Steps to reproduce the behavior: 3. See error ### Information - - ROCKNIX Version: [e.g. 20240517] + - ArchR Version: [e.g. 20260316] - Hardware Platform: [e.g. Powkiddy RGB20SX] ### Log file diff --git a/.github/release-body.md b/.github/release-body.md index 7361ea559b..4b3b2dc4df 100644 --- a/.github/release-body.md +++ b/.github/release-body.md @@ -1,12 +1,12 @@ -        [![Latest Version](https://img.shields.io/github/release/ROCKNIX/distribution.svg?color=5998FF&label=latest%20version&style=flat-square)](https://github.com/ROCKNIX/distribution/releases/latest) [![Activity](https://img.shields.io/github/commit-activity/m/ROCKNIX/distribution?color=5998FF&style=flat-square)](https://github.com/ROCKNIX/distribution/commits) [![Pull Requests](https://img.shields.io/github/issues-pr-closed/ROCKNIX/distribution?color=5998FF&style=flat-square)](https://github.com/ROCKNIX/distribution/pulls) [![Discord Server](https://img.shields.io/discord/948029830325235753?color=5998FF&label=chat&style=flat-square)](https://discord.gg/seTxckZjJy) +   # -ROCKNIX is a community developed Linux distribution for handheld gaming devices. Our goal is to produce an operating system that has the features and capabilities that we need, and to have fun as we develop it. +ArchR is a community developed Linux distribution for handheld gaming devices, forked from [ROCKNIX](https://github.com/ROCKNIX/distribution). Our goal is to produce an operating system that has the features and capabilities that we need, and to have fun as we develop it. ## Licenses -ROCKNIX is a Linux distribution that is made up of many open-source components. Components are provided under their respective licenses. This distribution includes components licensed for non-commercial use only. +ArchR is a Linux distribution forked from ROCKNIX, made up of many open-source components. Components are provided under their respective licenses. This distribution includes components licensed for non-commercial use only. -### ROCKNIX Branding -ROCKNIX branding and images are licensed under a [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-nc-sa/4.0/). +### ArchR Branding +ArchR branding and images are licensed under a [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-nc-sa/4.0/). #### You are free to * Share — copy and redistribute the material in any medium or format @@ -17,8 +17,8 @@ ROCKNIX branding and images are licensed under a [Creative Commons Attribution-N * NonCommercial — You may not use the material for commercial purposes. * ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original. -### ROCKNIX Software -Copyright (C) 2024 ROCKNIX (https://github.com/ROCKNIX) +### ArchR Software +Copyright (C) 2024-2026 ArchR (https://github.com/archr-linux). Derived from ROCKNIX, Copyright (C) 2024 ROCKNIX (https://github.com/ROCKNIX). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -33,77 +33,77 @@ See the License for the specific language governing permissions and limitations under the License. ## Installation -* Download the latest version of ROCKNIX. +* Download the latest version of ArchR. * Decompress the image. * Write the image to an SDCARD using an imaging tool. Common imaging tools include [Balena Etcher](https://www.balena.io/etcher/), [Raspberry Pi Imager](https://www.raspberrypi.com/software/), and [Win32 Disk Imager](https://sourceforge.net/projects/win32diskimager/). If you're skilled with the command line, dd works fine too. ### Installation Package Downloads | **Device/Platform** | **Download Package** | **Documentation** | |------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------| -| **Anbernic RG351P/M/V, Game Console R33S/R35S/R36S, ODROID Go Advance, ODROID Go Super, Magicx XU10, Powkiddy V10/RGB10** | [ROCKNIX-RK3326.aarch64-$DATE-a.img.gz](https://github.com/ROCKNIX/distribution/releases/download/$DATE/ROCKNIX-RK3326.aarch64-$DATE-a.img.gz) | [documentation](/documentation/PER_DEVICE_DOCUMENTATION/RK3326/) | -| **Magicx XU Mini M, Powkiddy RGB10X** | [ROCKNIX-RK3326.aarch64-$DATE-b.img.gz](https://github.com/ROCKNIX/distribution/releases/download/$DATE/ROCKNIX-RK3326.aarch64-$DATE-b.img.gz) | [documentation](/documentation/PER_DEVICE_DOCUMENTATION/RK3326/) | -| **Anbernic RG353P/M/V/VS/PS, RG503, RGARC-D/S, Powkiddy RK2023, RGB10 Max 3, RGB30, RGB20SX, RGB20 Pro** | [ROCKNIX-RK3566.aarch64-$DATE-Generic.img.gz](https://github.com/ROCKNIX/distribution/releases/download/$DATE/ROCKNIX-RK3566.aarch64-$DATE-Generic.img.gz) | [documentation](/documentation/PER_DEVICE_DOCUMENTATION/RK3566/) | -| **Anbernic RG552** | [ROCKNIX-RK3399.aarch64-$DATE.img.gz](https://github.com/ROCKNIX/distribution/releases/download/$DATE/ROCKNIX-RK3399.aarch64-$DATE.img.gz) | [documentation](/documentation/PER_DEVICE_DOCUMENTATION/RK3399/) | -| **Anbernic RG35XX PLUS/H/SP/2024, RG40XX V/H, RGCUBEXX, RG34XX SP, RG28XX [Must Follow Install Instructions](https://rocknix.org/configure/h700-installation/)** | [ROCKNIX-H700.aarch64-$DATE.img.gz](https://github.com/ROCKNIX/distribution/releases/download/$DATE/ROCKNIX-H700.aarch64-$DATE.img.gz) | [documentation](/documentation/PER_DEVICE_DOCUMENTATION/H700/) | -| **Hardkernel ODROID Go Ultra, Powkiddy RGB10 Max 3 Pro** | [ROCKNIX-S922X.aarch64-$DATE.img.gz](https://github.com/ROCKNIX/distribution/releases/download/$DATE/ROCKNIX-S922X.aarch64-$DATE.img.gz) | [documentation](/documentation/PER_DEVICE_DOCUMENTATION/S922X/) | -| **Gameforce Ace (default). Orange Pi 5 / 5 Plus, Radxa Rock 5a / 5b / 5b+ / CM5, and Indiedroid Nova** | [ROCKNIX-RK3588.aarch64-$DATE.img.gz](https://github.com/ROCKNIX/distribution/releases/download/$DATE/ROCKNIX-RK3588.aarch64-$DATE.img.gz) | [documentation](/documentation/PER_DEVICE_DOCUMENTATION/RK3588/) | -| **Powkiddy x55** | [ROCKNIX-RK3566.aarch64-$DATE-Powkiddy_x55.img.gz](https://github.com/ROCKNIX/distribution/releases/download/$DATE/ROCKNIX-RK3566.aarch64-$DATE-Powkiddy_x55.img.gz) | [documentation](/documentation/PER_DEVICE_DOCUMENTATION/RK3566-X55/) | -| **Retroid Pocket 5, Pocket Mini, Pocket Mini V2, Pocket Flip2** | [ROCKNIX-SM8250.aarch64-$DATE.img.gz](https://github.com/ROCKNIX/distribution/releases/download/$DATE/ROCKNIX-SM8250.aarch64-$DATE.img.gz) | [documentation](/documentation/PER_DEVICE_DOCUMENTATION/SM8250/) | -| **Ayn Odin 2, Odin 2 Mini, Odin 2 Portal, Thor, Ayaneo Pocket ACE/EVO/DMG/DS** | [ROCKNIX-SM8550.aarch64-$DATE.img.gz](https://github.com/ROCKNIX/distribution/releases/download/$DATE/ROCKNIX-SM8550.aarch64-$DATE.img.gz) | [documentation](/documentation/PER_DEVICE_DOCUMENTATION/SM8550/) | -| **Ayaneo Pocket S2** | [ROCKNIX-SM8650.aarch64-$DATE.img.gz](https://github.com/ROCKNIX/distribution/releases/download/$DATE/ROCKNIX-SM8650.aarch64-$DATE.img.gz) | [documentation](/documentation/PER_DEVICE_DOCUMENTATION/SM8650/) | +| **Anbernic RG351P/M/V, Game Console R33S/R35S/R36S, ODROID Go Advance, ODROID Go Super, Magicx XU10, Powkiddy V10/RGB10** | [ArchR-RK3326.aarch64-$DATE-a.img.gz](https://github.com/archr-linux/Arch-R/releases/download/$DATE/ArchR-RK3326.aarch64-$DATE-a.img.gz) | [documentation](/documentation/PER_DEVICE_DOCUMENTATION/RK3326/) | +| **Magicx XU Mini M, Powkiddy RGB10X** | [ArchR-RK3326.aarch64-$DATE-b.img.gz](https://github.com/archr-linux/Arch-R/releases/download/$DATE/ArchR-RK3326.aarch64-$DATE-b.img.gz) | [documentation](/documentation/PER_DEVICE_DOCUMENTATION/RK3326/) | +| **Anbernic RG353P/M/V/VS/PS, RG503, RGARC-D/S, Powkiddy RK2023, RGB10 Max 3, RGB30, RGB20SX, RGB20 Pro** | [ArchR-RK3566.aarch64-$DATE-Generic.img.gz](https://github.com/archr-linux/Arch-R/releases/download/$DATE/ArchR-RK3566.aarch64-$DATE-Generic.img.gz) | [documentation](/documentation/PER_DEVICE_DOCUMENTATION/RK3566/) | +| **Anbernic RG552** | [ArchR-RK3399.aarch64-$DATE.img.gz](https://github.com/archr-linux/Arch-R/releases/download/$DATE/ArchR-RK3399.aarch64-$DATE.img.gz) | [documentation](/documentation/PER_DEVICE_DOCUMENTATION/RK3399/) | +| **Anbernic RG35XX PLUS/H/SP/2024, RG40XX V/H, RGCUBEXX, RG34XX SP, RG28XX [Must Follow Install Instructions](https://github.com/archr-linux/Arch-R/wiki/h700-installation)** | [ArchR-H700.aarch64-$DATE.img.gz](https://github.com/archr-linux/Arch-R/releases/download/$DATE/ArchR-H700.aarch64-$DATE.img.gz) | [documentation](/documentation/PER_DEVICE_DOCUMENTATION/H700/) | +| **Hardkernel ODROID Go Ultra, Powkiddy RGB10 Max 3 Pro** | [ArchR-S922X.aarch64-$DATE.img.gz](https://github.com/archr-linux/Arch-R/releases/download/$DATE/ArchR-S922X.aarch64-$DATE.img.gz) | [documentation](/documentation/PER_DEVICE_DOCUMENTATION/S922X/) | +| **Gameforce Ace (default). Orange Pi 5 / 5 Plus, Radxa Rock 5a / 5b / 5b+ / CM5, and Indiedroid Nova** | [ArchR-RK3588.aarch64-$DATE.img.gz](https://github.com/archr-linux/Arch-R/releases/download/$DATE/ArchR-RK3588.aarch64-$DATE.img.gz) | [documentation](/documentation/PER_DEVICE_DOCUMENTATION/RK3588/) | +| **Powkiddy x55** | [ArchR-RK3566.aarch64-$DATE-Powkiddy_x55.img.gz](https://github.com/archr-linux/Arch-R/releases/download/$DATE/ArchR-RK3566.aarch64-$DATE-Powkiddy_x55.img.gz) | [documentation](/documentation/PER_DEVICE_DOCUMENTATION/RK3566-X55/) | +| **Retroid Pocket 5, Pocket Mini, Pocket Mini V2, Pocket Flip2** | [ArchR-SM8250.aarch64-$DATE.img.gz](https://github.com/archr-linux/Arch-R/releases/download/$DATE/ArchR-SM8250.aarch64-$DATE.img.gz) | [documentation](/documentation/PER_DEVICE_DOCUMENTATION/SM8250/) | +| **Ayn Odin 2, Odin 2 Mini, Odin 2 Portal, Thor, Ayaneo Pocket ACE/EVO/DMG/DS** | [ArchR-SM8550.aarch64-$DATE.img.gz](https://github.com/archr-linux/Arch-R/releases/download/$DATE/ArchR-SM8550.aarch64-$DATE.img.gz) | [documentation](/documentation/PER_DEVICE_DOCUMENTATION/SM8550/) | +| **Ayaneo Pocket S2** | [ArchR-SM8650.aarch64-$DATE.img.gz](https://github.com/archr-linux/Arch-R/releases/download/$DATE/ArchR-SM8650.aarch64-$DATE.img.gz) | [documentation](/documentation/PER_DEVICE_DOCUMENTATION/SM8650/) | ## Upgrading * Download and install the update online via the System Settings menu. * If you are unable to update online -* Download the latest version of ROCKNIX from Github +* Download the latest version of ArchR from Github * Copy the update to your device over the network to your device's update share. * Reboot the device, and the update will begin automatically. ### Update Package Downloads | **Device/Platform** | **Download Package** | |---------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------| -| **Anbernic RG351P/M/V, Game Console R33S/R35S/R36S, ODROID Go Advance, ODROID Go Super, Magicx XU10, XU Mini M, Powkiddy V10/RGB10/RGB10X** | [ROCKNIX-RK3326.aarch64-$DATE.tar](https://github.com/ROCKNIX/distribution/releases/download/$DATE/ROCKNIX-RK3326.aarch64-$DATE.tar) | -| **Anbernic RG353P/M/V/VS/PS, RG503, RGARC-D/S, Powkiddy RK2023, RGB10 Max 3, RGB30, RGB20SX, RGB20 Pro, X55** | [ROCKNIX-RK3566.aarch64-$DATE.tar](https://github.com/ROCKNIX/distribution/releases/download/$DATE/ROCKNIX-RK3566.aarch64-$DATE.tar) | -| **Anbernic RG552** | [ROCKNIX-RK3399.aarch64-$DATE.tar](https://github.com/ROCKNIX/distribution/releases/download/$DATE/ROCKNIX-RK3399.aarch64-$DATE.tar) | -| **Anbernic RG35XX PLUS/H/SP/2024, RG40XX V/H, RGCUBEXX, RG34XX SP, RG28XX** | [ROCKNIX-H700.aarch64-$DATE.tar](https://github.com/ROCKNIX/distribution/releases/download/$DATE/ROCKNIX-H700.aarch64-$DATE.tar) | -| **Hardkernel ODROID Go Ultra, Powkiddy RGB10 Max 3 Pro** | [ROCKNIX-S922X.aarch64-$DATE.tar](https://github.com/ROCKNIX/distribution/releases/download/$DATE/ROCKNIX-S922X.aarch64-$DATE.tar) | -| **Gameforce Ace, Orange Pi 5 / 5 Plus, Radxa Rock 5a / 5b / 5b+ / CM5 and Indiedroid Nova** | [ROCKNIX-RK3588.aarch64-$DATE.tar](https://github.com/ROCKNIX/distribution/releases/download/$DATE/ROCKNIX-RK3588.aarch64-$DATE.tar) | -| **Retroid Pocket 5, Pocket Mini, Pocket Mini V2, Pocket Flip2** | [ROCKNIX-SM8250.aarch64-$DATE.tar](https://github.com/ROCKNIX/distribution/releases/download/$DATE/ROCKNIX-SM8250.aarch64-$DATE.tar) | -| **Ayn Odin 2, Odin 2 Mini, Odin 2 Portal, Thor, Ayaneo Pocket ACE/EVO/DMG/DS** | [ROCKNIX-SM8550.aarch64-$DATE.tar](https://github.com/ROCKNIX/distribution/releases/download/$DATE/ROCKNIX-SM8550.aarch64-$DATE.tar) | -| **Ayaneo Pocket S2** | [ROCKNIX-SM8650.aarch64-$DATE.tar](https://github.com/ROCKNIX/distribution/releases/download/$DATE/ROCKNIX-SM8650.aarch64-$DATE.tar) | +| **Anbernic RG351P/M/V, Game Console R33S/R35S/R36S, ODROID Go Advance, ODROID Go Super, Magicx XU10, XU Mini M, Powkiddy V10/RGB10/RGB10X** | [ArchR-RK3326.aarch64-$DATE.tar](https://github.com/archr-linux/Arch-R/releases/download/$DATE/ArchR-RK3326.aarch64-$DATE.tar) | +| **Anbernic RG353P/M/V/VS/PS, RG503, RGARC-D/S, Powkiddy RK2023, RGB10 Max 3, RGB30, RGB20SX, RGB20 Pro, X55** | [ArchR-RK3566.aarch64-$DATE.tar](https://github.com/archr-linux/Arch-R/releases/download/$DATE/ArchR-RK3566.aarch64-$DATE.tar) | +| **Anbernic RG552** | [ArchR-RK3399.aarch64-$DATE.tar](https://github.com/archr-linux/Arch-R/releases/download/$DATE/ArchR-RK3399.aarch64-$DATE.tar) | +| **Anbernic RG35XX PLUS/H/SP/2024, RG40XX V/H, RGCUBEXX, RG34XX SP, RG28XX** | [ArchR-H700.aarch64-$DATE.tar](https://github.com/archr-linux/Arch-R/releases/download/$DATE/ArchR-H700.aarch64-$DATE.tar) | +| **Hardkernel ODROID Go Ultra, Powkiddy RGB10 Max 3 Pro** | [ArchR-S922X.aarch64-$DATE.tar](https://github.com/archr-linux/Arch-R/releases/download/$DATE/ArchR-S922X.aarch64-$DATE.tar) | +| **Gameforce Ace, Orange Pi 5 / 5 Plus, Radxa Rock 5a / 5b / 5b+ / CM5 and Indiedroid Nova** | [ArchR-RK3588.aarch64-$DATE.tar](https://github.com/archr-linux/Arch-R/releases/download/$DATE/ArchR-RK3588.aarch64-$DATE.tar) | +| **Retroid Pocket 5, Pocket Mini, Pocket Mini V2, Pocket Flip2** | [ArchR-SM8250.aarch64-$DATE.tar](https://github.com/archr-linux/Arch-R/releases/download/$DATE/ArchR-SM8250.aarch64-$DATE.tar) | +| **Ayn Odin 2, Odin 2 Mini, Odin 2 Portal, Thor, Ayaneo Pocket ACE/EVO/DMG/DS** | [ArchR-SM8550.aarch64-$DATE.tar](https://github.com/archr-linux/Arch-R/releases/download/$DATE/ArchR-SM8550.aarch64-$DATE.tar) | +| **Ayaneo Pocket S2** | [ArchR-SM8650.aarch64-$DATE.tar](https://github.com/archr-linux/Arch-R/releases/download/$DATE/ArchR-SM8650.aarch64-$DATE.tar) | ## Documentation ### Contribute -* [Building ROCKNIX](https://rocknix.org/contribute/build/) -* [Code of Conduct](https://rocknix.org/contribute/code-of-conduct/) -* [Contributing to ROCKNIX](https://rocknix.org/contribute/) -* [Modifying ROCKNIX](https://rocknix.org/contribute/modify/) -* [Adding Hardware Quirks](https://rocknix.org/contribute/quirks/) -* [Creating Packages](https://rocknix.org/contribute/packages/) +* [Building ArchR](https://github.com/archr-linux/distribution/wiki/contribute/build/) +* [Code of Conduct](https://github.com/archr-linux/distribution/wiki/contribute/code-of-conduct/) +* [Contributing to ArchR](https://github.com/archr-linux/distribution/wiki/contribute/) +* [Modifying ArchR](https://github.com/archr-linux/distribution/wiki/contribute/modify/) +* [Adding Hardware Quirks](https://github.com/archr-linux/distribution/wiki/contribute/quirks/) +* [Creating Packages](https://github.com/archr-linux/distribution/wiki/contribute/packages/) * [Pull Request Template](/PULL_REQUEST_TEMPLATE.md) ### Play -* [Installing ROCKNIX](https://rocknix.org/play/install/) -* [Updating ROCKNIX](https://rocknix.org/play/update/) -* [Controls](https://rocknix.org/play/controls/) -* [Netplay](https://rocknix.org/play/netplay/) -* [Configuring Moonlight](https://rocknix.org/systems/moonlight/) +* [Installing ArchR](https://github.com/archr-linux/distribution/wiki/play/install/) +* [Updating ArchR](https://github.com/archr-linux/distribution/wiki/play/update/) +* [Controls](https://github.com/archr-linux/distribution/wiki/play/controls/) +* [Netplay](https://github.com/archr-linux/distribution/wiki/play/netplay/) +* [Configuring Moonlight](https://github.com/archr-linux/distribution/wiki/systems/moonlight/) * [Device Specific Documentation](/documentation/PER_DEVICE_DOCUMENTATION) ### Configure -* [Optimizations](https://rocknix.org/configure/optimizations/) -* [Shaders](https://rocknix.org/configure/shaders/) -* [Cloud Sync](https://rocknix.org/configure/cloud-sync/) -* [VPN](https://rocknix.org/configure/vpn/) +* [Optimizations](https://github.com/archr-linux/distribution/wiki/configure/optimizations/) +* [Shaders](https://github.com/archr-linux/distribution/wiki/configure/shaders/) +* [Cloud Sync](https://github.com/archr-linux/distribution/wiki/configure/cloud-sync/) +* [VPN](https://github.com/archr-linux/distribution/wiki/configure/vpn/) ### Other -* [Frequently Asked Questions](https://rocknix.org/faqs/) -* [Donating to ROCKNIX](https://rocknix.org/donations/) +* [Frequently Asked Questions](https://github.com/archr-linux/distribution/wiki/faqs/) +* [Donating to ArchR](https://github.com/archr-linux/Arch-R) ## Change Log @@ -116,4 +116,4 @@ limitations under the License. ### Bug Fixes * Fixed...? -**Full Changelog**: https://github.com/ROCKNIX/distribution/compare/$LAST_TAG...$DATE +**Full Changelog**: https://github.com/archr-linux/Arch-R/compare/$LAST_TAG...$DATE diff --git a/.github/workflows/build-aarch64-emu-libretro.yml b/.github/workflows/build-aarch64-emu-libretro.yml index 47140425c0..afcf7707e7 100644 --- a/.github/workflows/build-aarch64-emu-libretro.yml +++ b/.github/workflows/build-aarch64-emu-libretro.yml @@ -125,7 +125,7 @@ jobs: command: | ./scripts/get_env > .env set -e - { docker run --init --env-file .env --rm --user $(id -u):$(id -g) -v ${PWD}:${PWD} -w ${PWD} "ghcr.io/${{ inputs.OWNER_LC }}/rocknix-build:latest" \ + { docker run --init --env-file .env --rm --user $(id -u):$(id -g) -v ${PWD}:${PWD} -w ${PWD} "ghcr.io/${{ inputs.OWNER_LC }}/archr-build:latest" \ bash -c "./scripts/build_mt emulators"; echo $? > docker_exit_code; } | tee output.log | grep -E --color=never --line-buffered "^GET|^UNPACK|^BUILD|^INSTALL" || true exit_code=$( .env set -e - { docker run --init --env-file .env --rm --user $(id -u):$(id -g) -v ${PWD}:${PWD} -w ${PWD} "ghcr.io/${{ inputs.OWNER_LC }}/rocknix-build:latest" \ + { docker run --init --env-file .env --rm --user $(id -u):$(id -g) -v ${PWD}:${PWD} -w ${PWD} "ghcr.io/${{ inputs.OWNER_LC }}/archr-build:latest" \ bash -c "./scripts/build_mt emulators"; echo $? > docker_exit_code; } | tee output.log | grep -E --color=never --line-buffered "^GET|^UNPACK|^BUILD|^INSTALL" || true exit_code=$( .env - docker run --init --env-file .env --rm --user $(id -u):$(id -g) -v ${PWD}:${PWD} -w ${PWD} "ghcr.io/${{ inputs.OWNER_LC }}/rocknix-build:latest" \ + docker run --init --env-file .env --rm --user $(id -u):$(id -g) -v ${PWD}:${PWD} -w ${PWD} "ghcr.io/${{ inputs.OWNER_LC }}/archr-build:latest" \ bash -c "./scripts/clean retroarch" # clean to rebuild emulationstation with credentials - name: Clean emulationstation run: | ./scripts/get_env > .env - docker run --init --env-file .env --rm --user $(id -u):$(id -g) -v ${PWD}:${PWD} -w ${PWD} "ghcr.io/${{ inputs.OWNER_LC }}/rocknix-build:latest" \ + docker run --init --env-file .env --rm --user $(id -u):$(id -g) -v ${PWD}:${PWD} -w ${PWD} "ghcr.io/${{ inputs.OWNER_LC }}/archr-build:latest" \ bash -c "./scripts/clean emulationstation" - name: build run: | ./scripts/get_env > .env set -e - { docker run --init --env-file .env --rm --user $(id -u):$(id -g) -v ${PWD}:${PWD} -w ${PWD} "ghcr.io/${{ inputs.OWNER_LC }}/rocknix-build:latest" \ + { docker run --init --env-file .env --rm --user $(id -u):$(id -g) -v ${PWD}:${PWD} -w ${PWD} "ghcr.io/${{ inputs.OWNER_LC }}/archr-build:latest" \ bash -c "./scripts/build_distro"; echo $? > docker_exit_code; } | tee output.log | grep -E --color=never --line-buffered "^GET|^UNPACK|^BUILD|^INSTALL" || true exit_code=$(> $GITHUB_ENV - uses: actions/upload-artifact@v7 with: - name: ROCKNIX-image-${{ inputs.DEVICE }}-${{ env.DATE }} + name: ArchR-image-${{ inputs.DEVICE }}-${{ env.DATE }} path: | - target/ROCKNIX-*.img.gz - target/ROCKNIX-*.img.gz.sha256 + target/ArchR-*.img.gz + target/ArchR-*.img.gz.sha256 compression-level: 0 if-no-files-found: error - uses: actions/upload-artifact@v7 with: - name: ROCKNIX-update-${{ inputs.DEVICE }}-${{ env.DATE }} + name: ArchR-update-${{ inputs.DEVICE }}-${{ env.DATE }} path: | - target/ROCKNIX-*.tar - target/ROCKNIX-*.tar.sha256 + target/ArchR-*.tar + target/ArchR-*.tar.sha256 compression-level: 0 if-no-files-found: error diff --git a/.github/workflows/build-aarch64-mame-lr.yml b/.github/workflows/build-aarch64-mame-lr.yml index 1e57073422..0c51765674 100644 --- a/.github/workflows/build-aarch64-mame-lr.yml +++ b/.github/workflows/build-aarch64-mame-lr.yml @@ -73,7 +73,7 @@ jobs: command: | ./scripts/get_env > .env set -e - { docker run --init --env-file .env --rm --user $(id -u):$(id -g) -v ${PWD}:${PWD} -w ${PWD} "ghcr.io/${{ inputs.OWNER_LC }}/rocknix-build:latest" \ + { docker run --init --env-file .env --rm --user $(id -u):$(id -g) -v ${PWD}:${PWD} -w ${PWD} "ghcr.io/${{ inputs.OWNER_LC }}/archr-build:latest" \ bash -c "./scripts/build_mt mame-lr"; echo $? > docker_exit_code; } | tee output.log | grep -E --color=never --line-buffered "^GET|^UNPACK|^BUILD|^INSTALL" || true exit_code=$( .env touch timestamp_before set -e - { docker run --init --env-file .env --rm --user $(id -u):$(id -g) -v ${PWD}:${PWD} -w ${PWD} "ghcr.io/${{ inputs.OWNER_LC }}/rocknix-build:latest" \ + { docker run --init --env-file .env --rm --user $(id -u):$(id -g) -v ${PWD}:${PWD} -w ${PWD} "ghcr.io/${{ inputs.OWNER_LC }}/archr-build:latest" \ bash -c "./scripts/build_mt qt6 modules"; echo $? > docker_exit_code; } | tee output.log | grep -E --color=never --line-buffered "^GET|^UNPACK|^BUILD|^INSTALL" || true exit_code=$( .env set -e - { docker run --init --env-file .env --rm --user $(id -u):$(id -g) -v ${PWD}:${PWD} -w ${PWD} "ghcr.io/${{ inputs.OWNER_LC }}/rocknix-build:latest" \ + { docker run --init --env-file .env --rm --user $(id -u):$(id -g) -v ${PWD}:${PWD} -w ${PWD} "ghcr.io/${{ inputs.OWNER_LC }}/archr-build:latest" \ bash -c "./scripts/build_mt toolchain alsa-lib"; echo $? > docker_exit_code; } | tee output.log | grep -E --color=never --line-buffered "^GET|^UNPACK|^BUILD|^INSTALL" || true exit_code=$( .env set -e - { docker run --init --env-file .env --rm --user $(id -u):$(id -g) -v ${PWD}:${PWD} -w ${PWD} "ghcr.io/${{ inputs.OWNER_LC }}/rocknix-build:latest" \ + { docker run --init --env-file .env --rm --user $(id -u):$(id -g) -v ${PWD}:${PWD} -w ${PWD} "ghcr.io/${{ inputs.OWNER_LC }}/archr-build:latest" \ bash -c "./scripts/build_distro "; echo $? > docker_exit_code; } | tee output.log | grep -E --color=never --line-buffered "^GET|^UNPACK|^BUILD|^INSTALL" || true exit_code=$(> $GITHUB_ENV - uses: actions/upload-artifact@v7 with: - name: ROCKNIX-base-image-${{ inputs.DEVICE }}-${{ env.DATE }} + name: ArchR-base-image-${{ inputs.DEVICE }}-${{ env.DATE }} path: | - target/ROCKNIX-*.img.gz - target/ROCKNIX-*.img.gz.sha256 + target/ArchR-*.img.gz + target/ArchR-*.img.gz.sha256 compression-level: 0 if-no-files-found: error @@ -106,7 +106,7 @@ jobs: command: | ./scripts/get_env > .env set -e - { docker run --init --env-file .env --rm --user $(id -u):$(id -g) -v ${PWD}:${PWD} -w ${PWD} "ghcr.io/${{ inputs.OWNER_LC }}/rocknix-build:latest" \ + { docker run --init --env-file .env --rm --user $(id -u):$(id -g) -v ${PWD}:${PWD} -w ${PWD} "ghcr.io/${{ inputs.OWNER_LC }}/archr-build:latest" \ bash -c "./scripts/build_mt modules "; echo $? > docker_exit_code; } | tee output.log | grep -E --color=never --line-buffered "^GET|^UNPACK|^BUILD|^INSTALL" || true exit_code=$( .env set -e - { docker run --init --env-file .env --rm --user $(id -u):$(id -g) -v ${PWD}:${PWD} -w ${PWD} "ghcr.io/${{ inputs.OWNER_LC }}/rocknix-build:latest" \ + { docker run --init --env-file .env --rm --user $(id -u):$(id -g) -v ${PWD}:${PWD} -w ${PWD} "ghcr.io/${{ inputs.OWNER_LC }}/archr-build:latest" \ bash -c "./scripts/build_distro"; echo $? > docker_exit_code; } | tee output.log | grep -E --color=never --line-buffered "^GET|^UNPACK|^BUILD|^INSTALL" || true exit_code=$( filelist.txt - find build.ROCKNIX-${{ inputs.DEVICE }}.arm/build -maxdepth 1 -type d -name 'box86-*' | head -n 1 | while read boxdir; do + find build.ArchR-${{ inputs.DEVICE }}.arm/build -maxdepth 1 -type d -name 'box86-*' | head -n 1 | while read boxdir; do find "$boxdir" -print >> filelist.txt done diff --git a/.github/workflows/build-docker-image.yml b/.github/workflows/build-docker-image.yml index 1aaf015d1a..3dc3f52c03 100644 --- a/.github/workflows/build-docker-image.yml +++ b/.github/workflows/build-docker-image.yml @@ -27,4 +27,4 @@ jobs: context: . file: Dockerfile push: ${{ github.event_name != 'pull_request' }} - tags: ghcr.io/${{ inputs.OWNER_LC }}/rocknix-build:latest \ No newline at end of file + tags: ghcr.io/${{ inputs.OWNER_LC }}/archr-build:latest \ No newline at end of file diff --git a/.github/workflows/build-nightly.yml b/.github/workflows/build-nightly.yml index 36bebde282..28b5d3f03b 100644 --- a/.github/workflows/build-nightly.yml +++ b/.github/workflows/build-nightly.yml @@ -66,7 +66,7 @@ on: jobs: set-envs: - if: (github.event_name != 'schedule') || (github.repository == 'ROCKNIX/distribution' && github.ref_name == 'next') + if: (github.event_name != 'schedule') || (github.repository == 'archr-linux/distribution' && github.ref_name == 'next') environment: name: ${{ github.event_name == 'pull_request' && 'pr-approval' || 'auto' }} runs-on: ubuntu-24.04 @@ -107,12 +107,12 @@ jobs: if [[ -n "$SELECTED_MATRIX" ]]; then SELECTED_MATRIX="$SELECTED_MATRIX," fi - SELECTED_MATRIX="$SELECTED_MATRIX{\"device\":\"$D\",\"project\":\"ROCKNIX\"}" + SELECTED_MATRIX="$SELECTED_MATRIX{\"device\":\"$D\",\"project\":\"ArchR\"}" fi done if [[ -z "$SELECTED_MATRIX" ]]; then - MATRIX='[{"device":"RK3326","project":"ROCKNIX"},{"device":"RK3399","project":"ROCKNIX"},{"device":"RK3566","project":"ROCKNIX"},{"device":"RK3588","project":"ROCKNIX"},{"device":"S922X","project":"ROCKNIX"},{"device":"H700","project":"ROCKNIX"},{"device":"SDM845","project":"ROCKNIX"},{"device":"SM8250","project":"ROCKNIX"},{"device":"SM8550","project":"ROCKNIX"},{"device":"SM8650","project":"ROCKNIX"}]' + MATRIX='[{"device":"RK3326","project":"ArchR"},{"device":"RK3399","project":"ArchR"},{"device":"RK3566","project":"ArchR"},{"device":"RK3588","project":"ArchR"},{"device":"S922X","project":"ArchR"},{"device":"H700","project":"ArchR"},{"device":"SDM845","project":"ArchR"},{"device":"SM8250","project":"ArchR"},{"device":"SM8550","project":"ArchR"},{"device":"SM8650","project":"ArchR"}]' else MATRIX="[$SELECTED_MATRIX]" fi @@ -120,7 +120,7 @@ jobs: echo "matrix=$MATRIX" >> $GITHUB_OUTPUT build-docker: - if: github.event_name != 'schedule' || (github.repository == 'ROCKNIX/distribution' && github.ref_name == 'next') + if: github.event_name != 'schedule' || (github.repository == 'archr-linux/distribution' && github.ref_name == 'next') name: Docker needs: set-envs uses: ./.github/workflows/build-docker-image.yml @@ -128,7 +128,7 @@ jobs: OWNER_LC: ${{ needs.set-envs.outputs.OWNER_LC }} build-devices: - if: (github.event_name != 'schedule') || (github.repository == 'ROCKNIX/distribution' && github.ref_name == 'next') + if: (github.event_name != 'schedule') || (github.repository == 'archr-linux/distribution' && github.ref_name == 'next') name: Build Devices needs: - set-envs @@ -147,7 +147,7 @@ jobs: OFFICIAL: ${{ needs.set-envs.outputs.OFFICIAL }} rerun-failed-jobs: - if: always() && !cancelled() && (contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')) && fromJSON(github.run_attempt) < 3 && github.ref_name == 'next' && (github.event_name != 'schedule' || github.repository == 'ROCKNIX/distribution') + if: always() && !cancelled() && (contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')) && fromJSON(github.run_attempt) < 3 && github.ref_name == 'next' && (github.event_name != 'schedule' || github.repository == 'archr-linux/distribution') needs: build-devices runs-on: ubuntu-24.04 steps: @@ -157,7 +157,7 @@ jobs: run: gh workflow run retry-workflow.yml -F run_id=${{ github.run_id }} release-nightly: - if: ${{ always() && !cancelled() && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') && github.repository_owner == 'ROCKNIX' && needs.set-envs.outputs.NIGHTLY == 'yes' && github.event_name != 'pull_request' }} + if: ${{ always() && !cancelled() && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') && github.repository_owner == 'archr-linux' && needs.set-envs.outputs.NIGHTLY == 'yes' && github.event_name != 'pull_request' }} name: Release nightly needs: build-devices runs-on: ubuntu-24.04 @@ -181,12 +181,12 @@ jobs: - name: Download artifacts uses: actions/download-artifact@v8 with: - pattern: ROCKNIX-image* + pattern: ArchR-image* merge-multiple: true - name: Download artifacts uses: actions/download-artifact@v8 with: - pattern: ROCKNIX-update* + pattern: ArchR-update* merge-multiple: true - name: get date run: echo "DATE=$(date +'%Y%m%d')" >> $GITHUB_ENV @@ -206,7 +206,7 @@ jobs: if [ $(git rev-list $COMMIT..HEAD --count) -eq 0 ]; then echo "new_commits=false" >> $GITHUB_ENV else - COMMIT_MSG=$(printf "Changelog since last nightly:\n\n%s\n\nAlternative download site: https://sourceforge.net/projects/rocknix/files/nightly/%s/" \ + COMMIT_MSG=$(printf "Changelog since last nightly:\n\n%s\n\nAlternative download site: https://sourceforge.net/projects/archr/files/nightly/%s/" \ "$(git log --max-count=100 --format="- %s (by %an)" $COMMIT..$GITHUB_SHA | grep -v "Merge pull request")" \ "$(date +%Y%m%d)") echo "commit_msg<> "$GITHUB_OUTPUT" @@ -222,7 +222,7 @@ jobs: uses: ncipollo/release-action@v1 with: tag: nightly-${{ env.DATE }} - artifacts: ROCKNIX-* + artifacts: ArchR-* allowUpdates: true makeLatest: true prerelease: true @@ -242,11 +242,11 @@ jobs: run: | FILES=$(find . -type f \( -name "*.tar" -o -name "*.img.gz" -o -name "*.sha256" \)) for FILE in $FILES; do - rsync -e ssh "$FILE" tiopex@frs.sourceforge.net:/home/frs/project/rocknix/nightly/${{ env.DATE }}/ + rsync -e ssh "$FILE" tiopex@frs.sourceforge.net:/home/frs/project/archr/nightly/${{ env.DATE }}/ done release-official: - if: ${{ always() && !cancelled() && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') && github.repository_owner == 'ROCKNIX' && needs.set-envs.outputs.OFFICIAL == 'yes' }} + if: ${{ always() && !cancelled() && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') && github.repository_owner == 'archr-linux' && needs.set-envs.outputs.OFFICIAL == 'yes' }} name: Release official needs: build-devices runs-on: ubuntu-24.04 @@ -269,12 +269,12 @@ jobs: - name: Download artifacts uses: actions/download-artifact@v8 with: - pattern: ROCKNIX-image* + pattern: ArchR-image* merge-multiple: true - name: Download artifacts uses: actions/download-artifact@v8 with: - pattern: ROCKNIX-update* + pattern: ArchR-update* merge-multiple: true - name: get date run: echo "DATE=$(date +'%Y%m%d')" >> $GITHUB_ENV @@ -302,7 +302,7 @@ jobs: with: tag: ${{ env.DATE }} commit: ${{ github.sha }} - artifacts: ROCKNIX-* + artifacts: ArchR-* allowUpdates: false makeLatest: true token: ${{ steps.app-token.outputs.token }} diff --git a/.github/workflows/update-kernel-configs-docs.yml b/.github/workflows/update-kernel-configs-docs.yml index 1ce00dfc98..c6e85ff020 100644 --- a/.github/workflows/update-kernel-configs-docs.yml +++ b/.github/workflows/update-kernel-configs-docs.yml @@ -5,7 +5,7 @@ on: workflow_call: push: paths: - - 'projects/ROCKNIX/packages/linux/package.mk' + - 'projects/ArchR/packages/linux/package.mk' branches: - next @@ -25,23 +25,23 @@ jobs: matrix: include: - device: RK3326 - project: ROCKNIX + project: ArchR - device: RK3399 - project: ROCKNIX + project: ArchR - device: RK3566 - project: ROCKNIX + project: ArchR - device: RK3588 - project: ROCKNIX + project: ArchR - device: S922X - project: ROCKNIX + project: ArchR - device: H700 - project: ROCKNIX + project: ArchR - device: SM8250 - project: ROCKNIX + project: ArchR - device: SM8550 - project: ROCKNIX + project: ArchR - device: SM8650 - project: ROCKNIX + project: ArchR runs-on: ubuntu-22.04 steps: - name: Checkout diff --git a/.github/workflows/update-mirror-sources.yml b/.github/workflows/update-mirror-sources.yml index e030a5fced..19d3d88031 100644 --- a/.github/workflows/update-mirror-sources.yml +++ b/.github/workflows/update-mirror-sources.yml @@ -8,7 +8,7 @@ on: jobs: update-mirror-sources: - if: (github.event_name != 'schedule') || (github.repository == 'ROCKNIX/distribution' && github.ref_name == 'next') + if: (github.event_name != 'schedule') || (github.repository == 'archr-linux/distribution' && github.ref_name == 'next') name: Update mirror sources runs-on: ubuntu-24.04 env: @@ -36,14 +36,14 @@ jobs: uses: corrupt952/actions-retry-command@v1.0.7 with: command: | - PROJECT=ROCKNIX DEVICE=RK3326 ./tools/download-tool - PROJECT=ROCKNIX DEVICE=RK3399 ./tools/download-tool - PROJECT=ROCKNIX DEVICE=RK3566 ./tools/download-tool - PROJECT=ROCKNIX DEVICE=RK3588 ./tools/download-tool - PROJECT=ROCKNIX DEVICE=H700 ./tools/download-tool - PROJECT=ROCKNIX DEVICE=S922X ./tools/download-tool - PROJECT=ROCKNIX DEVICE=SM8250 ./tools/download-tool - PROJECT=ROCKNIX DEVICE=SM8550 ./tools/download-tool + PROJECT=ArchR DEVICE=RK3326 ./tools/download-tool + PROJECT=ArchR DEVICE=RK3399 ./tools/download-tool + PROJECT=ArchR DEVICE=RK3566 ./tools/download-tool + PROJECT=ArchR DEVICE=RK3588 ./tools/download-tool + PROJECT=ArchR DEVICE=H700 ./tools/download-tool + PROJECT=ArchR DEVICE=S922X ./tools/download-tool + PROJECT=ArchR DEVICE=SM8250 ./tools/download-tool + PROJECT=ArchR DEVICE=SM8550 ./tools/download-tool max_attempts: 6 retry_interval: 10 - name: print number of downloaded artifacts diff --git a/.gitignore b/.gitignore index 76fd9ee48e..846037a8fe 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ /build.*/ /builds /.fakeroot.* +.claude # automatically downloaded source files /sources/ @@ -34,6 +35,11 @@ mkpkg-temp # crap .DS_Store .directory +Thumbs.db + +# temp scripts (debug/install helpers) +fix-debug.sh +install-debug.sh # ignore git repos from update scripts tools/mkpkg/*.git @@ -41,10 +47,131 @@ tools/mkpkg/*.git # ignore old linux configs projects/**/*.old -# ROCKNIX -/.rocknix +# Stock DTBs and reference files (binary, not needed for build) +config/archr-dts/R36S-DTB/R36S/ +config/archr-dts/R36S-DTB/R46H/*.dtb +config/archr-dts/R36S-DTB/R46H/boot.ini +config/archr-dts/R36S-DTB/RGB20S/*.dtb +config/archr-dts/R36S-DTB/RGB20S/boot.ini +config/archr-dts/R36S-Clones-DTB/*/*.dtb +config/archr-dts/R36S-Clones-DTB/*/extlinux/ +*.dtb.orig +*.dtb.tony + +# Generated MIPI overlay output (regenerated by generator.sh) +config/mipi-generator/output/ + +# Generated DTBO overlays in u-boot config (copied from mipi-generator output) +projects/ArchR/devices/RK3326/packages/u-boot/config/overlays_original/*.dtbo +projects/ArchR/devices/RK3326/packages/u-boot/config/overlays_clone/*.dtbo + +# ArchR +/.archr /.cache /.doc_cache /.env /.es_cache /.config + +# Upstream/legacy distributions (not used by ArchR) +distributions/ROCKNIX/ +distributions/LibreELEC/ +distributions/LEIoT/ + +# Upstream/other platform projects (not used by PROJECT=ArchR) +projects/ROCKNIX/ +projects/Allwinner/ +projects/Amlogic/ +projects/ARM/ +projects/Generic/ +projects/NXP/ +projects/Qualcomm/ +projects/Rockchip/ +projects/RPi/ +projects/Samsung/ + +# Non-R36S device directories +projects/ArchR/devices/H700/ +projects/ArchR/devices/RK3399/ +projects/ArchR/devices/RK3566/ +projects/ArchR/devices/RK3588/ +projects/ArchR/devices/S922X/ +projects/ArchR/devices/SDM845/ +projects/ArchR/devices/SM8250/ +projects/ArchR/devices/SM8550/ +projects/ArchR/devices/SM8650/ + +# Non-R36S device documentation +documentation/PER_DEVICE_DOCUMENTATION/H700/ +documentation/PER_DEVICE_DOCUMENTATION/RK3399/ +documentation/PER_DEVICE_DOCUMENTATION/RK3566/ +documentation/PER_DEVICE_DOCUMENTATION/RK3588/ +documentation/PER_DEVICE_DOCUMENTATION/S922X/ +documentation/PER_DEVICE_DOCUMENTATION/SDM845/ +documentation/PER_DEVICE_DOCUMENTATION/SM8250/ +documentation/PER_DEVICE_DOCUMENTATION/SM8550/ +documentation/PER_DEVICE_DOCUMENTATION/SM8650/ + +# Kodi/mediacenter (MEDIACENTER not set in ArchR) +packages/mediacenter/ + +# Driver addons (DRIVER_ADDONS_SUPPORT=no in ArchR) +packages/linux-driver-addons/ + +# Kodi addons (no MEDIACENTER in ArchR) +packages/addons/ + +# Platform-specific bootloaders/tools (not RK3326) +packages/tools/bcm2835-bootloader/ +packages/tools/bcm2835-utils/ +packages/tools/bcmstat/ +packages/tools/rpi-eeprom/ +packages/tools/amlogic-boot-fip/ +packages/tools/exynos-boot-fip/ + +# Firmware not used by R36S (FIRMWARE=esp8089-firmware only) +packages/linux-firmware/brcmfmac_sdio-firmware/ +packages/linux-firmware/brcmfmac_sdio-firmware-imx/ +packages/linux-firmware/brcmfmac_sdio-firmware-rpi/ +packages/linux-firmware/dvb-firmware/ +packages/linux-firmware/firmware-dragonboard/ +packages/linux-firmware/firmware-imx/ +packages/linux-firmware/iwlwifi-firmware/ + +# Non-R36S CI workflows +.github/workflows/build-aarch64-emu-libretro.yml +.github/workflows/build-aarch64-emu-standalone.yml +.github/workflows/build-aarch64-qt6.yml +.github/workflows/build-aarch64-mame-lr.yml + +# Emulators not used by RK3326 (too heavy or Vulkan-only) +projects/ArchR/packages/emulators/standalone/aethersx2-sa/ +projects/ArchR/packages/emulators/standalone/azahar-sa/ +projects/ArchR/packages/emulators/standalone/bigpemu-sa/ +projects/ArchR/packages/emulators/standalone/cemu-sa/ +projects/ArchR/packages/emulators/standalone/rpcs3-sa/ +projects/ArchR/packages/emulators/standalone/supermodel-sa/ +projects/ArchR/packages/emulators/standalone/xemu-sa/ +projects/ArchR/packages/emulators/standalone/skyemu-sa/ +projects/ArchR/packages/emulators/libretro/kronos-lr/ + +# Graphics packages not used by RK3326 (no Vulkan on Mali G31) +projects/ArchR/packages/graphics/libmali-vulkan/ +projects/ArchR/packages/graphics/vulkan-wsi-layer/ + +# Qualcomm/non-RK3326 tools +projects/ArchR/packages/tools/archr-abl/ +projects/ArchR/packages/tools/qcom-abl/ + +# Platform-specific base packages (not used by RK3326) +packages/audio/rpi-cirrus-config/ +packages/tools/crust/ +packages/tools/mkbootimg/ +packages/tools/grub/ +packages/linux-firmware/firmware-dragonboard/ +packages/linux-firmware/firmware-imx/ +packages/graphics/nvidia/ +packages/multimedia/intel-vaapi-driver/ +packages/multimedia/media-driver/ +packages/multimedia/gmmlib/ +packages/sysutils/open-vm-tools/ diff --git a/Dockerfile b/Dockerfile index 9b53a9f111..3a98a2e3f1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,32 +1,43 @@ -FROM ubuntu:jammy +FROM archlinux:latest -ARG DEBIAN_FRONTEND=noninteractive SHELL ["/usr/bin/bash", "-c"] -RUN apt-get update --fix-missing\ - && apt-get dist-upgrade -y \ - && apt-get install -y locales sudo +# Update system and install base packages +RUN pacman -Syu --noconfirm && \ + pacman -S --noconfirm --needed \ + base-devel bc jdk-openjdk file gawk git go gperf \ + perl-json perl-xml-parser ncurses lzop make patchutils \ + python python-setuptools parted unzip wget curl \ + xorg-mkfontscale libxslt zip vim zstd rdfind automake \ + xmlstarlet rsync which sudo rpcsvc-proto perl-parse-yapp xorg-bdftopcf -RUN locale-gen en_US.UTF-8 \ - && update-locale LANG=en_US.UTF-8 LANGUAGE=en_US:en +# Downgrade GCC to 14.x to avoid gnulib _Generic conflicts with GCC 15+ +RUN cd /tmp && \ + curl -LO 'https://archive.archlinux.org/packages/g/gcc/gcc-14.2.1%2Br134%2Bgab884fffe3fc-1-x86_64.pkg.tar.zst' && \ + curl -LO 'https://archive.archlinux.org/packages/g/gcc-libs/gcc-libs-14.2.1%2Br134%2Bgab884fffe3fc-1-x86_64.pkg.tar.zst' && \ + pacman -U --noconfirm --overwrite='*' /tmp/gcc-*.pkg.tar.zst && \ + rm -f /tmp/gcc-*.pkg.tar.zst + +# Create build user +RUN useradd -m -s /bin/bash docker && \ + echo 'docker ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers + +# Set locale +RUN echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen && \ + locale-gen ENV LANG=en_US.UTF-8 \ LANGUAGE=en_US:en \ LC_ALL=en_US.UTF-8 -RUN adduser --disabled-password --gecos '' docker \ - && adduser docker sudo \ - && echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers - -RUN apt-get install -y \ - bc default-jre file gawk gcc git golang-go gperf libjson-perl libncurses5-dev \ - libparse-yapp-perl libxml-parser-perl lzop make patchutils python-is-python3 \ - python3 parted unzip wget curl xfonts-utils xsltproc zip xxd zstd rdfind automake \ - xmlstarlet rsync +# Ensure Perl tools (pod2man, yapp, etc.) are in standard PATH +RUN for f in /usr/bin/core_perl/*; do [ -f "$f" ] && ln -sf "$f" /usr/bin/ 2>/dev/null; done; \ + for f in /usr/bin/vendor_perl/*; do [ -f "$f" ] && ln -sf "$f" /usr/bin/ 2>/dev/null; done; \ + true ### Cross compiling on ARM -RUN if [ "$(uname -m)" = "aarch64" ]; then apt-get install -y --no-install-recommends qemu-user-binfmt libc6-dev-amd64-cross; fi -RUN if [ ! -d /lib64 ]; then ln -sf /usr/x86_64-rocknix-linux-gnu/lib64 /lib64; fi -RUN if [ ! -d /lib/x86_64-rocknix-linux-gnu ]; then ln -sf /usr/x86_64-rocknix-linux-gnu/lib /lib/x86_64-rocknix-linux-gnu; fi +RUN if [ "$(uname -m)" = "aarch64" ]; then pacman -S --noconfirm qemu-user-static; fi +RUN if [ ! -d /lib64 ]; then ln -sf /usr/x86_64-archr-linux-gnu/lib64 /lib64 2>/dev/null || true; fi +RUN if [ ! -d /lib/x86_64-archr-linux-gnu ]; then ln -sf /usr/x86_64-archr-linux-gnu/lib /lib/x86_64-archr-linux-gnu 2>/dev/null || true; fi RUN mkdir -p /work && chown docker /work diff --git a/LICENSE.md b/LICENSE.md index f2c57de614..1935d7295f 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,14 +1,14 @@ -      [![Latest Version](https://img.shields.io/github/release/ROCKNIX/distribution.svg?color=FF5555&label=latest%20version&style=flat-square)](https://github.com/ROCKNIX/distribution/releases/latest) [![Activity](https://img.shields.io/github/commit-activity/m/ROCKNIX/distribution?color=FF5555&style=flat-square)](https://github.com/ROCKNIX/distribution/commits) [![Pull Requests](https://img.shields.io/github/issues-pr-closed/ROCKNIX/distribution?color=FF5555&style=flat-square)](https://github.com/ROCKNIX/distribution/pulls) [![Discord Server](https://img.shields.io/discord/948029830325235753?color=FF5555&label=chat&style=flat-square)](https://discord.gg/seTxckZjJy) + --- ## Licenses -ROCKNIX is a Linux distribution that is made up of many open-source components. Components are provided under their respective licenses. This distribution includes components licensed for non-commercial use only. +ArchR is a Linux distribution forked from [ROCKNIX](https://github.com/ROCKNIX/distribution), made up of many open-source components. Components are provided under their respective licenses. This distribution includes components licensed for non-commercial use only. -### ROCKNIX Branding +### ArchR Branding -ROCKNIX branding and images are licensed under a [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-nc-sa/4.0/). +ArchR branding and images are licensed under a [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-nc-sa/4.0/). Original ROCKNIX branding remains the property of the ROCKNIX project. You are free to: @@ -21,11 +21,13 @@ Under the following terms: - NonCommercial: You may not use the material for commercial purposes. - ShareAlike: If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original. -### ROCKNIX Software +### ArchR Software -Copyright 2024 ROCKNIX (https://github.com/ROCKNIX) +Copyright 2024-2026 ArchR (https://github.com/archr-linux) -Original software and scripts developed by the ROCKNIX team are licensed under the terms of the [GNU GPL Version 2](https://choosealicense.com/licenses/gpl-2.0/). The full license can be found in this project's licenses folder. +Original software and scripts developed by the ArchR team are licensed under the terms of the [GNU GPL Version 2](https://choosealicense.com/licenses/gpl-2.0/). The full license can be found in this project's licenses folder. + +Portions of this software are derived from ROCKNIX, Copyright 2024 ROCKNIX (https://github.com/ROCKNIX). ### Bundled Works -All other software is provided under each component's respective license. These licenses can be found in the software sources or in this project's licenses folder. Modifications to bundled software and scripts by the ROCKNIX team are licensed under the terms of the software being modified. +All other software is provided under each component's respective license. These licenses can be found in the software sources or in this project's licenses folder. Modifications to bundled software and scripts by the ArchR team are licensed under the terms of the software being modified. diff --git a/Makefile b/Makefile index 2565db3ff8..2201a22892 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ --include $(HOME)/.ROCKNIX/options +-include $(HOME)/.archr/options all: world @@ -26,7 +26,7 @@ src-pkg: docs: ./tools/foreach './scripts/clean emulators && ./scripts/build emulators' -world: RK3588 RK3566 RK3326 RK3399 S922X SM8250 SM8550 H700 SM8650 +world: RK3326 kconfig-olddefconfig-%: DEVICE=$* ./tools/adjust_kernel_config olddefconfig @@ -34,57 +34,13 @@ kconfig-olddefconfig-%: kconfig-menuconfig-%: DEVICE=$* ./tools/adjust_kernel_config menuconfig -RK3588: - unset DEVICE_ROOT - PROJECT=ROCKNIX DEVICE=RK3588 ARCH=arm ./scripts/build_distro - PROJECT=ROCKNIX DEVICE=RK3588 ARCH=aarch64 ./scripts/build_distro - -S922X: - unset DEVICE_ROOT - PROJECT=ROCKNIX DEVICE=S922X ARCH=arm ./scripts/build_distro - PROJECT=ROCKNIX DEVICE=S922X ARCH=aarch64 ./scripts/build_distro - -RK3566: - unset DEVICE_ROOT - DEVICE_ROOT=RK3566 PROJECT=ROCKNIX DEVICE=RK3566 ARCH=arm ./scripts/build_distro - DEVICE_ROOT=RK3566 PROJECT=ROCKNIX DEVICE=RK3566 ARCH=aarch64 ./scripts/build_distro - RK3326: unset DEVICE_ROOT - PROJECT=ROCKNIX DEVICE=RK3326 ARCH=arm ./scripts/build_distro - PROJECT=ROCKNIX DEVICE=RK3326 ARCH=aarch64 ./scripts/build_distro - -RK3399: - unset DEVICE_ROOT - PROJECT=ROCKNIX DEVICE=RK3399 ARCH=arm ./scripts/build_distro - PROJECT=ROCKNIX DEVICE=RK3399 ARCH=aarch64 ./scripts/build_distro - -H700: - unset DEVICE_ROOT - PROJECT=ROCKNIX DEVICE=H700 ARCH=arm ./scripts/build_distro - PROJECT=ROCKNIX DEVICE=H700 ARCH=aarch64 ./scripts/build_distro - -SDM845: - unset DEVICE_ROOT - PROJECT=ROCKNIX DEVICE=SDM845 ARCH=arm ./scripts/build_distro - PROJECT=ROCKNIX DEVICE=SDM845 ARCH=aarch64 ./scripts/build_distro - -SM8250: - unset DEVICE_ROOT - PROJECT=ROCKNIX DEVICE=SM8250 ARCH=arm ./scripts/build_distro - PROJECT=ROCKNIX DEVICE=SM8250 ARCH=aarch64 ./scripts/build_distro - -SM8550: - unset DEVICE_ROOT - PROJECT=ROCKNIX DEVICE=SM8550 ARCH=arm ./scripts/build_distro - PROJECT=ROCKNIX DEVICE=SM8550 ARCH=aarch64 ./scripts/build_distro - -SM8650: - unset DEVICE_ROOT - PROJECT=ROCKNIX DEVICE=SM8650 ARCH=aarch64 ./scripts/build_distro + PROJECT=ArchR DEVICE=RK3326 ARCH=arm ./scripts/build_distro + PROJECT=ArchR DEVICE=RK3326 ARCH=aarch64 ./scripts/build_distro update: - PROJECT=ROCKNIX DEVICE=RK3588 ARCH=aarch64 ./scripts/update_packages + PROJECT=ArchR DEVICE=RK3326 ARCH=aarch64 ./scripts/update_packages package: ./scripts/build ${PACKAGE} @@ -94,17 +50,17 @@ package-clean: ## Docker builds - overview # docker-* commands just wire up docker to call the normal make command via docker -# For example: make docker-SM8250 will use docker to call: make SM8250 +# For example: make docker-RK3326 will use docker to call: make RK3326 # All variables are scoped to docker-* commands to prevent weird collisions/behavior with non-docker commands -docker-%: DOCKER_IMAGE := "ghcr.io/rocknix/rocknix-build:latest" +docker-%: DOCKER_IMAGE := "archr-build:latest" # DOCKER_WORK_DIR is the directory in the Docker image - it is set to /work by default # Anytime this directory changes, you must run `make clean` similarly to moving the distribution directory docker-%: DOCKER_WORK_DIR := $(shell if [ -n "${DOCKER_WORK_DIR}" ]; then echo ${DOCKER_WORK_DIR}; else echo "$$(pwd)" ; fi) -# ${HOME}/.ROCKNIX/options is a global options file containing developer and build settings. -docker-%: GLOBAL_SETTINGS := $(shell if [ -f "${HOME}/.ROCKNIX/options" ]; then echo "-v \"${HOME}/.ROCKNIX/options:${HOME}/.ROCKNIX/options\""; else echo ""; fi) +# ${HOME}/.archr/options is a global options file containing developer and build settings. +docker-%: GLOBAL_SETTINGS := $(shell if [ -f "${HOME}/.archr/options" ]; then echo "-v \"${HOME}/.archr/options:${HOME}/.archr/options\""; else echo ""; fi) # LOCAL_SSH_KEYS_FILE is a variable that contains the location of the authorized keys file for development build use. It will be mounted into the container if it exists. docker-%: LOCAL_SSH_KEYS_FILE := $(shell if [ -n "${LOCAL_SSH_KEYS_FILE}" ]; then echo "-v \"${LOCAL_SSH_KEYS_FILE}:${LOCAL_SSH_KEYS_FILE}\""; else echo ""; fi) @@ -152,4 +108,4 @@ docker-image-pull: # Wire up docker to call equivalent make files using % to match and $* to pass the value matched by % docker-%: - BUILD_DIR=$(DOCKER_WORK_DIR) $(DOCKER_CMD) run $(PODMAN_ARGS) $(INTERACTIVE) --init --env-file .env --rm --user $(UID):$(GID) $(GLOBAL_SETTINGS) $(LOCAL_SSH_KEYS_FILE) $(EMULATIONSTATION_SRC) -v $(PWD):$(DOCKER_WORK_DIR) -w $(DOCKER_WORK_DIR) $(DOCKER_EXTRA_OPTS) $(DOCKER_IMAGE) $(COMMAND) + BUILD_DIR="$(DOCKER_WORK_DIR)" $(DOCKER_CMD) run $(PODMAN_ARGS) $(INTERACTIVE) --init --env-file .env --rm --user $(UID):$(GID) $(GLOBAL_SETTINGS) $(LOCAL_SSH_KEYS_FILE) $(EMULATIONSTATION_SRC) -v "$(PWD)":"$(DOCKER_WORK_DIR)" -v /tmp:/tmp -w "$(DOCKER_WORK_DIR)" $(DOCKER_EXTRA_OPTS) $(DOCKER_IMAGE) $(COMMAND) diff --git a/README.md b/README.md index a627dc3fa6..8f47ce622f 100644 --- a/README.md +++ b/README.md @@ -1,63 +1,179 @@ -      [![Latest Version](https://img.shields.io/github/release/ROCKNIX/distribution.svg?color=FF5555&label=latest%20version&style=flat-square)](https://github.com/ROCKNIX/distribution/releases/latest) [![Activity](https://img.shields.io/github/commit-activity/m/ROCKNIX/distribution?color=FF5555&style=flat-square)](https://github.com/ROCKNIX/distribution/commits) [![Pull Requests](https://img.shields.io/github/issues-pr-closed/ROCKNIX/distribution?color=FF5555&style=flat-square)](https://github.com/ROCKNIX/distribution/pulls) [![Discord Server](https://img.shields.io/discord/948029830325235753?color=FF5555&label=chat&style=flat-square)](https://discord.gg/seTxckZjJy) +

+ Arch R +

+ +

+ Arch Linux-based gaming distribution for handheld devices. +

+ +

+ Latest Version + Activity + Pull Requests +

--- -ROCKNIX is an immutable Linux distribution for handheld gaming devices developed by a small community of enthusiasts. Our goal is to produce an operating system that has the features and capabilities that we need, and to have fun as we develop it. +Arch R is a custom Linux distribution for the **R36S** handheld gaming console and all its variants, built on top of [ROCKNIX](https://github.com/ROCKNIX/distribution) with an Arch Linux-based build environment. It supports **16 board profiles** and **20 display panels** across original and clone hardware. ## Features -* ROCKNIX has a very active community of developers and users. -* Integrated cross-device local and remote network play. -* In-game touch support on supported devices. -* Fine grain control for battery life or performance. -* Includes support for playing Music and Video. -* Bluetooth audio and controller support. -* Support for HDMI audio and video out, and USB audio. -* Device to device and device to cloud sync with Syncthing and rclone. -* VPN support with Wireguard, Tailscale, and ZeroTier. -* Includes built-in support for scraping and retroachievements. +- Arch Linux-based build system with Docker support. +- Kernel 6.12 LTS with board auto-detection via SARADC. +- Mesa Panfrost open-source GPU driver (GLES 3.1, no proprietary blobs). +- EmulationStation frontend with RetroArch and 18+ cores pre-installed. +- Full audio support with speaker/headphone auto-switch. +- Battery monitoring with capacity reporting and LED warning. +- 20 pre-generated MIPI panel overlays (7 original + 13 clone variants). +- Separate images for original and clone boards, both with hardware auto-detection. +- Integrated cross-device local and remote network play. +- Fine-grained control for battery life and performance. +- Bluetooth audio and controller support. +- HDMI audio/video output, USB audio. +- Device sync with Syncthing and rclone. +- VPN support with WireGuard, Tailscale, and ZeroTier. +- Built-in scraping and RetroAchievements. -## Screenshots +## Supported Hardware - - - - - - - - - -
+### Boards + +| Board | Image | +|-------|-------| +| R36S (original), R33S | Original | +| Odroid Go Advance / v1.1 / Super | Original | +| Anbernic RG351V / RG351M | Original | +| GameForce Chi, MagicX XU10 | Original | +| K36 / R36S clones / EE Clone | Clone | +| Powkiddy RGB10 / RGB10X / RGB20S | Clone | +| MagicX XU-Mini-M, BatLexp G350 | Clone | + +### Display Panels + +Arch R ships 20 pre-generated MIPI panel overlays covering all known R36S display variants. Panel selection is done by copying the correct `.dtbo` file to `overlays/mipi-panel.dtbo` on the boot partition. + +## Quick Start + +Download the latest images from [Releases](https://github.com/archr-linux/Arch-R/releases): + +- **Original image** -- for genuine R36S and compatible boards. +- **Clone image** -- for K36 clones and compatible boards. + +Flash to a MicroSD card: + +```bash +xz -d ArchR-R36S-*.img.xz +sudo dd if=ArchR-R36S-*.img of=/dev/sdX bs=4M status=progress +sync +``` + +Insert the SD card and power on. The correct board DTB is selected automatically. + +## Building from Source + +### Requirements + +- Docker (recommended) or native Linux build environment +- ~40 GB free disk space +- ~8 GB RAM recommended + +### Build + +```bash +git clone https://github.com/archr-linux/Arch-R.git +cd Arch-R + +# Build Docker image (first time only) +make docker-image-build + +# Build for R36S (all variants) +make docker-RK3326 +``` + +Output images are generated in `target/`. + +### Build Commands + +| Command | Description | +|---------|-------------| +| `make docker-RK3326` | Full build inside Docker | +| `make RK3326` | Native build (requires all dependencies) | +| `make docker-image-build` | Build the Docker build environment | +| `make clean` | Remove build artifacts | + +## Architecture + +Arch R separates **board configuration** from **panel configuration**: + +- **Board DTB** = hardware profile (GPIOs, PMIC, joypad, audio codec). Selected automatically by U-Boot via SARADC. +- **Panel overlay** = display init sequence and timings. Applied on top of the board DTB at boot time. + +This means the same image works on all boards of a variant. Only the panel overlay needs to match the specific display. + +### Boot Flow + +``` +Power On + U-Boot (BSP or mainline) + boot.scr: read SARADC hwrev, select board DTB + sysboot: load kernel + DTB + overlay from extlinux.conf + Kernel 6.12 + initramfs + mount root (ext4) + storage + switch_root to systemd + systemd + archr-autostart (quirks, governors, audio) + EmulationStation +``` + +### Partition Layout + +| Partition | Filesystem | Label | Purpose | +|-----------|-----------|-------|---------| +| 1 | FAT32 | ARCHR | Boot (kernel, DTBs, overlays, boot.scr) | +| 2 | ext4 | ARCHR_ROOT | Root filesystem | +| 3 | ext4 | STORAGE | User data, ROMs, configs | ## Community -The ROCKNIX community utilizes Discord for discussion, if you would like to join us please use this link: [https://discord.gg/seTxckZjJy](https://discord.gg/seTxckZjJy) +Contributions are welcome. Please open issues or pull requests on [GitHub](https://github.com/archr-linux/Arch-R). ## Licenses -**ROCKNIX** is a fork of [JELOS](https://github.com/JustEnoughLinuxOS/distribution/), all licenses apply and credit to the JELOS team. +**Arch R** is a fork of [ROCKNIX](https://github.com/ROCKNIX/distribution), which is a fork of [JELOS](https://github.com/JustEnoughLinuxOS/distribution/). All upstream licenses apply. You are free to: -- Share: copy and redistribute the material in any medium or format -- Adapt: remix, transform, and build upon the material +- **Share**: copy and redistribute the material in any medium or format. +- **Adapt**: remix, transform, and build upon the material. Under the following terms: -- Attribution: You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. -- NonCommercial: You may not use the material for commercial purposes. -- ShareAlike: If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original. +- **Attribution**: You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. +- **NonCommercial**: You may not use the material for commercial purposes. +- **ShareAlike**: If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original. -### ROCKNIX Software +### Arch R Software -Copyright (C) 2024-present [ROCKNIX](https://github.com/ROCKNIX) +Copyright (C) 2026-present [Arch R](https://github.com/archr-linux/Arch-R) -Original software and scripts developed by the ROCKNIX are licensed under the terms of the [GNU GPL Version 2](https://choosealicense.com/licenses/gpl-2.0/). The full license can be found in this project's licenses folder. +Original software and scripts developed by Arch R are licensed under the terms of the [GNU GPL Version 2](https://choosealicense.com/licenses/gpl-2.0/). The full license can be found in this project's licenses folder. ### Bundled Works -All other software is provided under each component's respective license. These licenses can be found in the software sources or in this project's licenses folder. Modifications to bundled software and scripts by the JELOS team are licensed under the terms of the software being modified. + +All other software is provided under each component's respective license. These licenses can be found in the software sources or in this project's licenses folder. Modifications to bundled software and scripts by upstream projects are licensed under the terms of the software being modified. ## Credits -Like any Linux distribution, this project is not the work of one person. It is the work of many persons all over the world who have developed the open source bits without which this project could not exist. Special thanks to CoreELEC, LibreELEC, JELOS, and to developers and contributors across the open source community. +Like any Linux distribution, this project is not the work of one person. It is the work of many people around the world who have developed the open-source components without which this project could not exist. + +Special thanks to: + +- **[ROCKNIX](https://github.com/ROCKNIX/distribution)** -- the upstream distribution that Arch R is forked from. ROCKNIX provided the complete build system, device support, EmulationStation integration, and the foundation for handheld gaming on Linux. +- **[JELOS](https://github.com/JustEnoughLinuxOS/distribution/)** -- the project that ROCKNIX was originally forked from. +- **[CoreELEC](https://coreelec.org/)** and **[LibreELEC](https://libreelec.tv/)** -- the embedded Linux distributions whose build system forms the backbone of this project. +- **[Hardkernel](https://www.hardkernel.com/)** -- for the Odroid Go Advance BSP U-Boot and kernel device trees. +- **[Rockchip](https://www.rock-chips.com/)** -- for the RK3326 SoC and rkbin firmware. +- **[Mesa](https://mesa3d.org/)** -- for the Panfrost open-source GPU driver. +- **[RetroArch](https://www.retroarch.com/)** and **[Libretro](https://www.libretro.com/)** -- for the emulation framework and cores. +- **[EmulationStation](https://emulationstation.org/)** -- for the frontend. +- All developers and contributors across the open-source community who made this possible. diff --git a/config/archr-dts/R36S-DTB/DTS/Panel0.dts b/config/archr-dts/R36S-DTB/DTS/Panel0.dts new file mode 100644 index 0000000000..58cae809aa --- /dev/null +++ b/config/archr-dts/R36S-DTB/DTS/Panel0.dts @@ -0,0 +1,4053 @@ +/dts-v1/; + +/ { + compatible = "rockchip,rk3326-odroidgo3-linux\0rockchip,rk3326"; + interrupt-parent = <0x01>; + #address-cells = <0x02>; + #size-cells = <0x02>; + model = "Hardkernel ODROID-GO3"; + + ddr_timing { + compatible = "rockchip,ddr-timing"; + ddr2_speed_bin = <0x00>; + ddr3_speed_bin = <0x15>; + ddr4_speed_bin = <0x0c>; + pd_idle = <0x0d>; + sr_idle = <0x5d>; + sr_mc_gate_idle = <0x00>; + srpd_lite_idle = <0x00>; + standby_idle = <0x00>; + auto_pd_dis_freq = <0x42a>; + auto_sr_dis_freq = <0x320>; + ddr2_dll_dis_freq = <0x12c>; + ddr3_dll_dis_freq = <0x12c>; + ddr4_dll_dis_freq = <0x271>; + phy_dll_dis_freq = <0x190>; + ddr2_odt_dis_freq = <0x64>; + phy_ddr2_odt_dis_freq = <0x64>; + ddr2_drv = <0x01>; + ddr2_odt = <0x96>; + phy_ddr2_ca_drv = <0x15>; + phy_ddr2_ck_drv = <0x12>; + phy_ddr2_dq_drv = <0x15>; + phy_ddr2_odt = <0x02>; + ddr3_odt_dis_freq = <0x190>; + phy_ddr3_odt_dis_freq = <0x190>; + ddr3_drv = <0x28>; + ddr3_odt = <0x78>; + phy_ddr3_ca_drv = <0x15>; + phy_ddr3_ck_drv = <0x12>; + phy_ddr3_dq_drv = <0x15>; + phy_ddr3_odt = <0x02>; + phy_lpddr2_odt_dis_freq = <0x29a>; + lpddr2_drv = <0x28>; + phy_lpddr2_ca_drv = <0x16>; + phy_lpddr2_ck_drv = <0x13>; + phy_lpddr2_dq_drv = <0x16>; + phy_lpddr2_odt = <0x00>; + lpddr3_odt_dis_freq = <0x190>; + phy_lpddr3_odt_dis_freq = <0x190>; + lpddr3_drv = <0x28>; + lpddr3_odt = <0xf0>; + phy_lpddr3_ca_drv = <0x16>; + phy_lpddr3_ck_drv = <0x13>; + phy_lpddr3_dq_drv = <0x16>; + phy_lpddr3_odt = <0x02>; + lpddr4_odt_dis_freq = <0x320>; + phy_lpddr4_odt_dis_freq = <0x320>; + lpddr4_drv = <0x3c>; + lpddr4_dq_odt = <0x28>; + lpddr4_ca_odt = <0x28>; + phy_lpddr4_ca_drv = <0x14>; + phy_lpddr4_ck_cs_drv = <0x06>; + phy_lpddr4_dq_drv = <0x06>; + phy_lpddr4_odt = <0x10>; + ddr4_odt_dis_freq = <0x29a>; + phy_ddr4_odt_dis_freq = <0x29a>; + ddr4_drv = <0x22>; + ddr4_odt = <0xf0>; + phy_ddr4_ca_drv = <0x16>; + phy_ddr4_ck_drv = <0x13>; + phy_ddr4_dq_drv = <0x16>; + phy_ddr4_odt = <0x02>; + ddr3a1_ddr4a9_de-skew = <0x06>; + ddr3a0_ddr4a10_de-skew = <0x07>; + ddr3a3_ddr4a6_de-skew = <0x07>; + ddr3a2_ddr4a4_de-skew = <0x07>; + ddr3a5_ddr4a8_de-skew = <0x07>; + ddr3a4_ddr4a5_de-skew = <0x07>; + ddr3a7_ddr4a11_de-skew = <0x07>; + ddr3a6_ddr4a7_de-skew = <0x06>; + ddr3a9_ddr4a0_de-skew = <0x07>; + ddr3a8_ddr4a13_de-skew = <0x07>; + ddr3a11_ddr4a3_de-skew = <0x07>; + ddr3a10_ddr4cs0_de-skew = <0x07>; + ddr3a13_ddr4a2_de-skew = <0x07>; + ddr3a12_ddr4ba1_de-skew = <0x07>; + ddr3a15_ddr4odt0_de-skew = <0x07>; + ddr3a14_ddr4a1_de-skew = <0x07>; + ddr3ba1_ddr4a15_de-skew = <0x07>; + ddr3ba0_ddr4bg0_de-skew = <0x07>; + ddr3ras_ddr4cke_de-skew = <0x07>; + ddr3ba2_ddr4ba0_de-skew = <0x07>; + ddr3we_ddr4bg1_de-skew = <0x07>; + ddr3cas_ddr4a12_de-skew = <0x07>; + ddr3ckn_ddr4ckn_de-skew = <0x07>; + ddr3ckp_ddr4ckp_de-skew = <0x07>; + ddr3cke_ddr4a16_de-skew = <0x07>; + ddr3odt0_ddr4a14_de-skew = <0x07>; + ddr3cs0_ddr4act_de-skew = <0x06>; + ddr3reset_ddr4reset_de-skew = <0x07>; + ddr3cs1_ddr4cs1_de-skew = <0x06>; + ddr3odt1_ddr4odt1_de-skew = <0x07>; + cs0_dm0_rx_de-skew = <0x07>; + cs0_dm0_tx_de-skew = <0x07>; + cs0_dq0_rx_de-skew = <0x08>; + cs0_dq0_tx_de-skew = <0x08>; + cs0_dq1_rx_de-skew = <0x09>; + cs0_dq1_tx_de-skew = <0x08>; + cs0_dq2_rx_de-skew = <0x08>; + cs0_dq2_tx_de-skew = <0x08>; + cs0_dq3_rx_de-skew = <0x08>; + cs0_dq3_tx_de-skew = <0x08>; + cs0_dq4_rx_de-skew = <0x09>; + cs0_dq4_tx_de-skew = <0x08>; + cs0_dq5_rx_de-skew = <0x09>; + cs0_dq5_tx_de-skew = <0x08>; + cs0_dq6_rx_de-skew = <0x09>; + cs0_dq6_tx_de-skew = <0x08>; + cs0_dq7_rx_de-skew = <0x08>; + cs0_dq7_tx_de-skew = <0x08>; + cs0_dqs0_rx_de-skew = <0x06>; + cs0_dqs0p_tx_de-skew = <0x09>; + cs0_dqs0n_tx_de-skew = <0x09>; + cs0_dm1_rx_de-skew = <0x07>; + cs0_dm1_tx_de-skew = <0x06>; + cs0_dq8_rx_de-skew = <0x08>; + cs0_dq8_tx_de-skew = <0x07>; + cs0_dq9_rx_de-skew = <0x09>; + cs0_dq9_tx_de-skew = <0x07>; + cs0_dq10_rx_de-skew = <0x08>; + cs0_dq10_tx_de-skew = <0x08>; + cs0_dq11_rx_de-skew = <0x08>; + cs0_dq11_tx_de-skew = <0x07>; + cs0_dq12_rx_de-skew = <0x08>; + cs0_dq12_tx_de-skew = <0x08>; + cs0_dq13_rx_de-skew = <0x09>; + cs0_dq13_tx_de-skew = <0x07>; + cs0_dq14_rx_de-skew = <0x09>; + cs0_dq14_tx_de-skew = <0x08>; + cs0_dq15_rx_de-skew = <0x09>; + cs0_dq15_tx_de-skew = <0x07>; + cs0_dqs1_rx_de-skew = <0x07>; + cs0_dqs1p_tx_de-skew = <0x09>; + cs0_dqs1n_tx_de-skew = <0x09>; + cs0_dm2_rx_de-skew = <0x07>; + cs0_dm2_tx_de-skew = <0x07>; + cs0_dq16_rx_de-skew = <0x09>; + cs0_dq16_tx_de-skew = <0x09>; + cs0_dq17_rx_de-skew = <0x07>; + cs0_dq17_tx_de-skew = <0x09>; + cs0_dq18_rx_de-skew = <0x07>; + cs0_dq18_tx_de-skew = <0x08>; + cs0_dq19_rx_de-skew = <0x07>; + cs0_dq19_tx_de-skew = <0x09>; + cs0_dq20_rx_de-skew = <0x09>; + cs0_dq20_tx_de-skew = <0x09>; + cs0_dq21_rx_de-skew = <0x09>; + cs0_dq21_tx_de-skew = <0x09>; + cs0_dq22_rx_de-skew = <0x08>; + cs0_dq22_tx_de-skew = <0x09>; + cs0_dq23_rx_de-skew = <0x08>; + cs0_dq23_tx_de-skew = <0x09>; + cs0_dqs2_rx_de-skew = <0x06>; + cs0_dqs2p_tx_de-skew = <0x09>; + cs0_dqs2n_tx_de-skew = <0x09>; + cs0_dm3_rx_de-skew = <0x07>; + cs0_dm3_tx_de-skew = <0x07>; + cs0_dq24_rx_de-skew = <0x08>; + cs0_dq24_tx_de-skew = <0x08>; + cs0_dq25_rx_de-skew = <0x09>; + cs0_dq25_tx_de-skew = <0x09>; + cs0_dq26_rx_de-skew = <0x09>; + cs0_dq26_tx_de-skew = <0x08>; + cs0_dq27_rx_de-skew = <0x09>; + cs0_dq27_tx_de-skew = <0x08>; + cs0_dq28_rx_de-skew = <0x09>; + cs0_dq28_tx_de-skew = <0x09>; + cs0_dq29_rx_de-skew = <0x09>; + cs0_dq29_tx_de-skew = <0x09>; + cs0_dq30_rx_de-skew = <0x08>; + cs0_dq30_tx_de-skew = <0x08>; + cs0_dq31_rx_de-skew = <0x08>; + cs0_dq31_tx_de-skew = <0x08>; + cs0_dqs3_rx_de-skew = <0x07>; + cs0_dqs3p_tx_de-skew = <0x09>; + cs0_dqs3n_tx_de-skew = <0x09>; + cs1_dm0_rx_de-skew = <0x07>; + cs1_dm0_tx_de-skew = <0x07>; + cs1_dq0_rx_de-skew = <0x08>; + cs1_dq0_tx_de-skew = <0x08>; + cs1_dq1_rx_de-skew = <0x09>; + cs1_dq1_tx_de-skew = <0x08>; + cs1_dq2_rx_de-skew = <0x08>; + cs1_dq2_tx_de-skew = <0x08>; + cs1_dq3_rx_de-skew = <0x08>; + cs1_dq3_tx_de-skew = <0x08>; + cs1_dq4_rx_de-skew = <0x08>; + cs1_dq4_tx_de-skew = <0x08>; + cs1_dq5_rx_de-skew = <0x09>; + cs1_dq5_tx_de-skew = <0x08>; + cs1_dq6_rx_de-skew = <0x09>; + cs1_dq6_tx_de-skew = <0x08>; + cs1_dq7_rx_de-skew = <0x08>; + cs1_dq7_tx_de-skew = <0x08>; + cs1_dqs0_rx_de-skew = <0x06>; + cs1_dqs0p_tx_de-skew = <0x09>; + cs1_dqs0n_tx_de-skew = <0x09>; + cs1_dm1_rx_de-skew = <0x07>; + cs1_dm1_tx_de-skew = <0x07>; + cs1_dq8_rx_de-skew = <0x08>; + cs1_dq8_tx_de-skew = <0x08>; + cs1_dq9_rx_de-skew = <0x08>; + cs1_dq9_tx_de-skew = <0x07>; + cs1_dq10_rx_de-skew = <0x07>; + cs1_dq10_tx_de-skew = <0x08>; + cs1_dq11_rx_de-skew = <0x08>; + cs1_dq11_tx_de-skew = <0x08>; + cs1_dq12_rx_de-skew = <0x08>; + cs1_dq12_tx_de-skew = <0x07>; + cs1_dq13_rx_de-skew = <0x08>; + cs1_dq13_tx_de-skew = <0x08>; + cs1_dq14_rx_de-skew = <0x08>; + cs1_dq14_tx_de-skew = <0x08>; + cs1_dq15_rx_de-skew = <0x08>; + cs1_dq15_tx_de-skew = <0x07>; + cs1_dqs1_rx_de-skew = <0x07>; + cs1_dqs1p_tx_de-skew = <0x09>; + cs1_dqs1n_tx_de-skew = <0x09>; + cs1_dm2_rx_de-skew = <0x07>; + cs1_dm2_tx_de-skew = <0x08>; + cs1_dq16_rx_de-skew = <0x08>; + cs1_dq16_tx_de-skew = <0x09>; + cs1_dq17_rx_de-skew = <0x08>; + cs1_dq17_tx_de-skew = <0x09>; + cs1_dq18_rx_de-skew = <0x07>; + cs1_dq18_tx_de-skew = <0x08>; + cs1_dq19_rx_de-skew = <0x08>; + cs1_dq19_tx_de-skew = <0x09>; + cs1_dq20_rx_de-skew = <0x09>; + cs1_dq20_tx_de-skew = <0x09>; + cs1_dq21_rx_de-skew = <0x09>; + cs1_dq21_tx_de-skew = <0x09>; + cs1_dq22_rx_de-skew = <0x08>; + cs1_dq22_tx_de-skew = <0x09>; + cs1_dq23_rx_de-skew = <0x08>; + cs1_dq23_tx_de-skew = <0x09>; + cs1_dqs2_rx_de-skew = <0x06>; + cs1_dqs2p_tx_de-skew = <0x09>; + cs1_dqs2n_tx_de-skew = <0x09>; + cs1_dm3_rx_de-skew = <0x07>; + cs1_dm3_tx_de-skew = <0x07>; + cs1_dq24_rx_de-skew = <0x08>; + cs1_dq24_tx_de-skew = <0x09>; + cs1_dq25_rx_de-skew = <0x09>; + cs1_dq25_tx_de-skew = <0x09>; + cs1_dq26_rx_de-skew = <0x09>; + cs1_dq26_tx_de-skew = <0x08>; + cs1_dq27_rx_de-skew = <0x08>; + cs1_dq27_tx_de-skew = <0x08>; + cs1_dq28_rx_de-skew = <0x09>; + cs1_dq28_tx_de-skew = <0x09>; + cs1_dq29_rx_de-skew = <0x09>; + cs1_dq29_tx_de-skew = <0x09>; + cs1_dq30_rx_de-skew = <0x09>; + cs1_dq30_tx_de-skew = <0x08>; + cs1_dq31_rx_de-skew = <0x08>; + cs1_dq31_tx_de-skew = <0x08>; + cs1_dqs3_rx_de-skew = <0x07>; + cs1_dqs3p_tx_de-skew = <0x09>; + cs1_dqs3n_tx_de-skew = <0x09>; + phandle = <0xaf>; + }; + + aliases { + ethernet0 = "/ethernet@ff360000"; + i2c0 = "/i2c@ff180000"; + i2c1 = "/i2c@ff190000"; + i2c2 = "/i2c@ff1a0000"; + i2c3 = "/i2c@ff1b0000"; + serial0 = "/serial@ff030000"; + serial1 = "/serial@ff158000"; + serial2 = "/serial@ff160000"; + serial3 = "/serial@ff168000"; + serial4 = "/serial@ff170000"; + serial5 = "/serial@ff178000"; + spi0 = "/spi@ff1d0000"; + spi1 = "/spi@ff1d8000"; + }; + + cpus { + #address-cells = <0x02>; + #size-cells = <0x00>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x00>; + enable-method = "psci"; + clocks = <0x02 0x07>; + #cooling-cells = <0x02>; + dynamic-power-coefficient = <0x5a>; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + cpu-supply = <0x06>; + phandle = <0x09>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x01>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0a>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x02>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0b>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x03>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0c>; + }; + + idle-states { + entry-method = "psci"; + + cpu-sleep { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x10000>; + entry-latency-us = <0x78>; + exit-latency-us = <0xfa>; + min-residency-us = <0x384>; + phandle = <0x04>; + }; + + cluster-sleep { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x1010000>; + entry-latency-us = <0x190>; + exit-latency-us = <0x1f4>; + min-residency-us = <0x7d0>; + phandle = <0x05>; + }; + }; + }; + + cpu0-opp-table { + compatible = "operating-points-v2"; + opp-shared; + rockchip,temp-hysteresis = <0x1388>; + rockchip,low-temp = <0x00>; + rockchip,low-temp-min-volt = <0xf4240>; + rockchip,low-temp-adjust-volt = <0x00 0x5e8 0xc350>; + clocks = <0x02 0x01>; + rockchip,avs-scale = <0x04>; + rockchip,max-volt = <0x149970>; + rockchip,evb-irdrop = <0x61a8>; + nvmem-cells = <0x07 0x08>; + nvmem-cell-names = "cpu_leakage\0performance"; + rockchip,bin-scaling-sel = <0x00 0x0d 0x01 0x0d>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-freq = <0x639c0>; + rockchip,pvtm-volt = <0xf4240>; + rockchip,pvtm-ch = <0x00 0x00>; + rockchip,pvtm-sample-time = <0x3e8>; + rockchip,pvtm-number = <0x0a>; + rockchip,pvtm-error = <0x3e8>; + rockchip,pvtm-ref-temp = <0x28>; + rockchip,pvtm-temp-prop = <0xffffffc8 0xffffffc8>; + rockchip,thermal-zone = "soc-thermal"; + rockchip,avs = <0x01>; + phandle = <0x03>; + + opp-1008000000 { + opp-hz = <0x00 0x3c14dc00>; + opp-microvolt = <0x11edd8 0x11edd8 0x149970>; + opp-microvolt-L0 = <0x11edd8 0x11edd8 0x149970>; + opp-microvolt-L1 = <0x112a88 0x112a88 0x149970>; + opp-microvolt-L2 = <0x112a88 0x112a88 0x149970>; + opp-microvolt-L3 = <0x100590 0x100590 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1200000000 { + opp-hz = <0x00 0x47868c00>; + opp-microvolt = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L0 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L1 = <0x137478 0x137478 0x149970>; + opp-microvolt-L2 = <0x1312d0 0x1312d0 0x149970>; + opp-microvolt-L3 = <0x124f80 0x124f80 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1248000000 { + opp-hz = <0x00 0x4a62f800>; + opp-microvolt = <0x149970 0x149970 0x149970>; + opp-microvolt-L0 = <0x149970 0x149970 0x149970>; + opp-microvolt-L1 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L2 = <0x137478 0x137478 0x149970>; + opp-microvolt-L3 = <0x12b128 0x12b128 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1296000000 { + opp-hz = <0x00 0x4d3f6400>; + opp-microvolt = <0x149970 0x149970 0x149970>; + opp-microvolt-L0 = <0x149970 0x149970 0x149970>; + opp-microvolt-L1 = <0x149970 0x149970 0x149970>; + opp-microvolt-L2 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L3 = <0x1312d0 0x1312d0 0x149970>; + clock-latency-ns = <0x9c40>; + }; + }; + + arm-pmu { + compatible = "arm,cortex-a53-pmu"; + interrupts = <0x00 0x64 0x04 0x00 0x65 0x04 0x00 0x66 0x04 0x00 0x67 0x04>; + interrupt-affinity = <0x09 0x0a 0x0b 0x0c>; + }; + + bus-soc { + compatible = "rockchip,px30-bus"; + rockchip,busfreq-policy = "autocs"; + phandle = <0xc4>; + + soc-bus0 { + bus-id = <0x00>; + timer-us = <0x14>; + enable-msk = <0x40f7>; + status = "disabled"; + }; + + soc-bus1 { + bus-id = <0x01>; + timer-us = <0xc8>; + enable-msk = <0x40bf>; + status = "disabled"; + }; + + soc-bus2 { + bus-id = <0x02>; + timer-us = <0xc8>; + enable-msk = <0x4007>; + status = "disabled"; + }; + }; + + bus-apll { + compatible = "rockchip,px30-bus"; + rockchip,busfreq-policy = "clkfreq"; + clocks = <0x02 0x01>; + clock-names = "bus"; + operating-points-v2 = <0x0d>; + status = "okay"; + bus-supply = <0x0e>; + phandle = <0xc5>; + }; + + bus-apll-opp-table { + compatible = "operating-points-v2"; + opp-shared; + phandle = <0x0d>; + + opp-1512000000 { + opp-hz = <0x00 0x5a1f4a00>; + opp-microvolt = <0xf4240>; + }; + + opp-1008000000 { + opp-hz = <0x00 0x3c14dc00>; + opp-microvolt = <0xe7ef0>; + }; + }; + + cpuinfo { + compatible = "rockchip,cpuinfo"; + nvmem-cells = <0x0f>; + nvmem-cell-names = "id"; + }; + + display-subsystem { + compatible = "rockchip,display-subsystem"; + ports = <0x10>; + status = "okay"; + logo-memory-region = <0x11>; + phandle = <0xc6>; + + route { + + route-lvds { + status = "disabled"; + logo,uboot = "logo.bmp"; + logo,kernel = "logo_kernel.bmp"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x12>; + phandle = <0xc7>; + }; + + route-dsi { + status = "okay"; + logo,uboot = "logo.bmp"; + logo,kernel = "logo_kernel.bmp"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x13>; + phandle = <0xc8>; + }; + + route-rgb { + status = "disabled"; + logo,uboot = "logo.bmp"; + logo,kernel = "logo_kernel.bmp"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x14>; + phandle = <0xc9>; + }; + }; + }; + + firmware { + + optee { + compatible = "linaro,optee-tz"; + method = "smc"; + }; + }; + + external-gmac-clock { + compatible = "fixed-clock"; + clock-frequency = <0x2faf080>; + clock-output-names = "gmac_clkin"; + #clock-cells = <0x00>; + phandle = <0xca>; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + rockchip-suspend { + compatible = "rockchip,pm-px30"; + status = "okay"; + rockchip,sleep-debug-en = <0x01>; + rockchip,sleep-mode-config = <0x20702>; + rockchip,wakeup-config = <0x85>; + phandle = <0xcb>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <0x01 0x0d 0xf04 0x01 0x0e 0xf04 0x01 0x0b 0xf04 0x01 0x0a 0xf04>; + }; + + xin24m { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x16e3600>; + clock-output-names = "xin24m"; + phandle = <0xcc>; + }; + + xin32k { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x8000>; + clock-output-names = "xin32k"; + phandle = <0xcd>; + }; + + power-management@ff000000 { + compatible = "rockchip,px30-pmu\0syscon\0simple-mfd"; + reg = <0x00 0xff000000 0x00 0x1000>; + phandle = <0xce>; + + power-controller { + compatible = "rockchip,px30-power-controller"; + #power-domain-cells = <0x01>; + #address-cells = <0x01>; + #size-cells = <0x00>; + phandle = <0x8a>; + + pd_usb@5 { + reg = <0x05>; + clocks = <0x02 0x103 0x02 0x102 0x02 0x3c>; + pm_qos = <0x15 0x16>; + }; + + pd_sdcard@7 { + reg = <0x07>; + clocks = <0x02 0xf7 0x02 0x3b>; + pm_qos = <0x17>; + }; + + pd_gmac@9 { + reg = <0x09>; + clocks = <0x02 0xb2 0x02 0x143 0x02 0x40 0x02 0x3f>; + pm_qos = <0x18>; + }; + + pd_mmc_nand@10 { + reg = <0x0a>; + clocks = <0x02 0xfe 0x02 0x100 0x02 0xff 0x02 0x101 0x02 0x39 0x02 0x37 0x02 0x38 0x02 0x3a>; + pm_qos = <0x19 0x1a 0x1b 0x1c>; + }; + + pd_vpu@11 { + reg = <0x0b>; + clocks = <0x02 0xaf 0x02 0xf4 0x02 0x4b>; + pm_qos = <0x1d 0x1e>; + }; + + pd_vo@12 { + reg = <0x0c>; + clocks = <0x02 0xb7 0x02 0xb5 0x02 0xb6 0x02 0x96 0x02 0x97 0x02 0xfd 0x02 0xfb 0x02 0xfc 0x02 0x144 0x02 0x35 0x02 0x36>; + pm_qos = <0x1f 0x20 0x21 0x22>; + }; + + pd_vi@13 { + reg = <0x0d>; + clocks = <0x02 0xb3 0x02 0xb4 0x02 0xf9 0x02 0xfa 0x02 0x33>; + pm_qos = <0x23 0x24 0x25 0x26 0x27>; + }; + + pd_gpu@14 { + reg = <0x0e>; + clocks = <0x02 0x49>; + pm_qos = <0x28>; + }; + }; + }; + + syscon@ff010000 { + compatible = "rockchip,px30-pmugrf\0syscon\0simple-mfd"; + reg = <0x00 0xff010000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0xac>; + + io-domains { + compatible = "rockchip,px30-pmu-io-voltage-domain"; + status = "okay"; + pmuio1-supply = <0x29>; + pmuio2-supply = <0x29>; + phandle = <0xcf>; + }; + + reboot-mode { + compatible = "syscon-reboot-mode"; + offset = <0x200>; + mode-bootloader = <0x5242c301>; + mode-charge = <0x5242c30b>; + mode-fastboot = <0x5242c309>; + mode-loader = <0x5242c301>; + mode-normal = <0x5242c300>; + mode-recovery = <0x5242c303>; + mode-ums = <0x5242c30c>; + }; + + pmu-pvtm { + compatible = "rockchip,px30-pmu-pvtm"; + clocks = <0x2a 0x07>; + clock-names = "pmu"; + status = "okay"; + phandle = <0xd0>; + }; + }; + + serial@ff030000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff030000 0x00 0x100>; + interrupts = <0x00 0x0f 0x04>; + clocks = <0x2a 0x06 0x2a 0x15>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x00 0x2b 0x01>; + pinctrl-names = "default"; + pinctrl-0 = <0x2c 0x2d 0x2e>; + status = "disabled"; + phandle = <0xd1>; + }; + + i2s@ff060000 { + compatible = "rockchip,px30-i2s-tdm"; + reg = <0x00 0xff060000 0x00 0x1000>; + interrupts = <0x00 0x0c 0x04>; + clocks = <0x02 0x10 0x02 0x12 0x02 0x106>; + clock-names = "mclk_tx\0mclk_rx\0hclk"; + dmas = <0x2b 0x10 0x2b 0x11>; + dma-names = "tx\0rx"; + resets = <0x02 0x84 0x02 0xbf>; + reset-names = "tx-m\0rx-m"; + rockchip,cru = <0x02>; + rockchip,grf = <0x2f>; + pinctrl-names = "default"; + pinctrl-0 = <0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x3a 0x3b>; + status = "disabled"; + phandle = <0xd2>; + }; + + i2s@ff070000 { + compatible = "rockchip,px30-i2s\0rockchip,rk3066-i2s"; + reg = <0x00 0xff070000 0x00 0x1000>; + interrupts = <0x00 0x0d 0x04>; + clocks = <0x02 0x14 0x02 0x107>; + clock-names = "i2s_clk\0i2s_hclk"; + dmas = <0x2b 0x12 0x2b 0x13>; + dma-names = "tx\0rx"; + resets = <0x02 0x86 0x02 0x85>; + reset-names = "reset-m\0reset-h"; + pinctrl-names = "default"; + pinctrl-0 = <0x3c 0x3d 0x3e 0x3f>; + status = "okay"; + #sound-dai-cells = <0x00>; + phandle = <0xc2>; + }; + + i2s@ff080000 { + compatible = "rockchip,px30-i2s\0rockchip,rk3066-i2s"; + reg = <0x00 0xff080000 0x00 0x1000>; + interrupts = <0x00 0x0e 0x04>; + clocks = <0x02 0x16 0x02 0x108>; + clock-names = "i2s_clk\0i2s_hclk"; + dmas = <0x2b 0x14 0x2b 0x15>; + dma-names = "tx\0rx"; + resets = <0x02 0x88 0x02 0x87>; + reset-names = "reset-m\0reset-h"; + pinctrl-names = "default"; + pinctrl-0 = <0x40 0x41 0x42 0x43>; + status = "disabled"; + phandle = <0xd3>; + }; + + pdm@ff0a0000 { + compatible = "rockchip,px30-pdm\0rockchip,pdm"; + reg = <0x00 0xff0a0000 0x00 0x1000>; + clocks = <0x02 0x0f 0x02 0x105>; + clock-names = "pdm_clk\0pdm_hclk"; + dmas = <0x2b 0x18>; + dma-names = "rx"; + resets = <0x02 0x82>; + reset-names = "pdm-m"; + pinctrl-names = "default"; + pinctrl-0 = <0x44 0x45 0x46 0x47 0x48 0x49>; + status = "disabled"; + phandle = <0xd4>; + }; + + crypto@ff0b0000 { + compatible = "rockchip,px30-crypto"; + reg = <0x00 0xff0b0000 0x00 0x4000>; + interrupts = <0x00 0x52 0x04>; + clocks = <0x02 0xac 0x02 0xf1 0x02 0x30 0x02 0x31>; + clock-names = "aclk\0hclk\0sclk\0apb_pclk"; + resets = <0x02 0x74>; + reset-names = "crypto-rst"; + status = "disabled"; + phandle = <0xd5>; + }; + + rng@ff0b0000 { + compatible = "rockchip,cryptov2-rng"; + reg = <0x00 0xff0b0000 0x00 0x4000>; + clocks = <0x02 0x30 0x02 0x31 0x02 0xac 0x02 0xf1>; + clock-names = "clk_crypto\0clk_crypto_apk\0aclk_crypto\0hclk_crypto"; + assigned-clocks = <0x02 0x30 0x02 0x31 0x02 0xac 0x02 0xf1>; + assigned-clock-rates = <0x8f0d180 0x8f0d180 0xbebc200 0x5f5e100>; + resets = <0x02 0x74>; + reset-names = "reset"; + status = "okay"; + phandle = <0xd6>; + }; + + interrupt-controller@ff131000 { + compatible = "arm,gic-400"; + #interrupt-cells = <0x03>; + #address-cells = <0x00>; + interrupt-controller; + reg = <0x00 0xff131000 0x00 0x1000 0x00 0xff132000 0x00 0x2000 0x00 0xff134000 0x00 0x2000 0x00 0xff136000 0x00 0x2000>; + interrupts = <0x01 0x09 0xf04>; + phandle = <0x01>; + }; + + syscon@ff140000 { + compatible = "rockchip,px30-grf\0syscon\0simple-mfd"; + reg = <0x00 0xff140000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0x2f>; + + io-domains { + compatible = "rockchip,px30-io-voltage-domain"; + status = "okay"; + vccio1-supply = <0x4a>; + vccio2-supply = <0x4a>; + vccio3-supply = <0x4b>; + vccio4-supply = <0x4b>; + vccio5-supply = <0x4b>; + vccio6-supply = <0x4b>; + phandle = <0xd7>; + }; + + lvds { + compatible = "rockchip,px30-lvds"; + phys = <0x4c>; + phy-names = "phy"; + status = "disabled"; + phandle = <0xd8>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x12>; + phandle = <0xa2>; + }; + }; + }; + }; + + rgb { + compatible = "rockchip,px30-rgb"; + pinctrl-names = "default\0sleep"; + pinctrl-0 = <0x4d>; + pinctrl-1 = <0x4e>; + status = "disabled"; + phys = <0x4c>; + phy-names = "phy"; + phandle = <0xd9>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x14>; + phandle = <0xa4>; + }; + }; + }; + }; + }; + + syscon@ff148000 { + compatible = "syscon\0simple-mfd"; + reg = <0x00 0xff148000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0xda>; + + pvtm { + compatible = "rockchip,px30-pvtm"; + clocks = <0x02 0x4a>; + clock-names = "core"; + status = "okay"; + phandle = <0xdb>; + }; + }; + + serial@ff158000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff158000 0x00 0x100>; + interrupts = <0x00 0x10 0x04>; + clocks = <0x02 0x18 0x02 0x149>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x02 0x2b 0x03>; + pinctrl-names = "default"; + pinctrl-0 = <0x4f 0x50>; + status = "okay"; + phandle = <0xdc>; + }; + + serial@ff160000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff160000 0x00 0x100>; + interrupts = <0x00 0x11 0x04>; + clocks = <0x02 0x19 0x02 0x14a>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x04 0x2b 0x05>; + pinctrl-names = "default"; + pinctrl-0 = <0x51>; + status = "disabled"; + phandle = <0xdd>; + }; + + serial@ff168000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff168000 0x00 0x100>; + interrupts = <0x00 0x12 0x04>; + clocks = <0x02 0x1a 0x02 0x14b>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x06 0x2b 0x07>; + pinctrl-names = "default"; + pinctrl-0 = <0x52 0x53 0x54>; + status = "disabled"; + phandle = <0xde>; + }; + + serial@ff170000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff170000 0x00 0x100>; + interrupts = <0x00 0x13 0x04>; + clocks = <0x02 0x1b 0x02 0x14c>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x08 0x2b 0x09>; + pinctrl-names = "default"; + pinctrl-0 = <0x55 0x56 0x57>; + status = "disabled"; + phandle = <0xdf>; + }; + + serial@ff178000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff178000 0x00 0x100>; + interrupts = <0x00 0x14 0x04>; + clocks = <0x02 0x1c 0x02 0x14d>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x0a 0x2b 0x0b>; + pinctrl-names = "default"; + pinctrl-0 = <0x58 0x59 0x5a>; + status = "disabled"; + phandle = <0xe0>; + }; + + i2c@ff180000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff180000 0x00 0x1000>; + clocks = <0x02 0x1d 0x02 0x14e>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x07 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x5b>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + clock-frequency = <0x61a80>; + i2c-scl-rising-time-ns = <0x118>; + i2c-scl-falling-time-ns = <0x10>; + phandle = <0xe1>; + + pmic@20 { + compatible = "rockchip,rk817"; + reg = <0x20>; + interrupt-parent = <0x5c>; + interrupts = <0x0a 0x08>; + pinctrl-names = "default\0pmic-sleep\0pmic-power-off\0pmic-reset"; + pinctrl-0 = <0x5d>; + pinctrl-1 = <0x5e 0x5f>; + pinctrl-2 = <0x60 0x61>; + pinctrl-3 = <0x62 0x63>; + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <0x01>; + clock-output-names = "rk808-clkout1\0rk808-clkout2"; + pmic-reset-func = <0x01>; + vcc1-supply = <0x64>; + vcc2-supply = <0x64>; + vcc3-supply = <0x64>; + vcc4-supply = <0x64>; + vcc5-supply = <0x64>; + vcc6-supply = <0x64>; + vcc7-supply = <0x64>; + vcc8-supply = <0x64>; + vcc9-supply = <0x65>; + phandle = <0xe2>; + + pwrkey { + status = "okay"; + }; + + pinctrl_rk8xx { + gpio-controller; + #gpio-cells = <0x02>; + phandle = <0xe3>; + + rk817_ts_gpio1 { + pins = "gpio_ts"; + function = "pin_fun1"; + phandle = <0xe4>; + }; + + rk817_gt_gpio2 { + pins = "gpio_gt"; + function = "pin_fun1"; + phandle = <0xe5>; + }; + + rk817_pin_ts { + pins = "gpio_ts"; + function = "pin_fun0"; + phandle = <0xe6>; + }; + + rk817_pin_gt { + pins = "gpio_gt"; + function = "pin_fun0"; + phandle = <0xe7>; + }; + + rk817_slppin_null { + pins = "gpio_slp"; + function = "pin_fun0"; + phandle = <0xe8>; + }; + + rk817_slppin_slp { + pins = "gpio_slp"; + function = "pin_fun1"; + phandle = <0x5f>; + }; + + rk817_slppin_pwrdn { + pins = "gpio_slp"; + function = "pin_fun2"; + phandle = <0x61>; + }; + + rk817_slppin_rst { + pins = "gpio_slp"; + function = "pin_fun3"; + phandle = <0x63>; + }; + }; + + regulators { + + DCDC_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xe7ef0>; + regulator-max-microvolt = <0x118c30>; + regulator-ramp-delay = <0x1771>; + regulator-initial-mode = <0x02>; + regulator-name = "vdd_logic"; + phandle = <0x0e>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0xe7ef0>; + }; + }; + + DCDC_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xe7ef0>; + regulator-max-microvolt = <0x149970>; + regulator-ramp-delay = <0x1771>; + regulator-initial-mode = <0x02>; + regulator-name = "vdd_arm"; + phandle = <0x06>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0xe7ef0>; + }; + }; + + DCDC_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x02>; + regulator-name = "vcc_ddr"; + phandle = <0xe9>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + DCDC_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-initial-mode = <0x02>; + regulator-name = "vcc_3v3"; + phandle = <0x4b>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG1 { + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + regulator-name = "vcc_1v0"; + phandle = <0xea>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0xf4240>; + }; + }; + + LDO_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + regulator-name = "vcc1v8_soc"; + phandle = <0x88>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x1b7740>; + }; + }; + + LDO_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + regulator-name = "vcc1v0_soc"; + phandle = <0xeb>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0xf4240>; + }; + }; + + LDO_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "vcc3v3_pmu"; + phandle = <0x29>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + regulator-name = "vccio_sd"; + phandle = <0x4a>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x1b7740>; + }; + }; + + LDO_REG6 { + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x2dc6c0>; + regulator-boot-on; + regulator-name = "vcc_sd"; + phandle = <0x93>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x2dc6c0>; + }; + }; + + LDO_REG7 { + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "vcc_backlight"; + phandle = <0x9e>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG8 { + regulator-min-microvolt = <0x2ab980>; + regulator-max-microvolt = <0x2ab980>; + regulator-name = "vcc_lcd"; + phandle = <0x9f>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x2ab980>; + }; + }; + + BOOST { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x4c4b40>; + regulator-max-microvolt = <0x5265c0>; + regulator-name = "boost"; + phandle = <0x65>; + }; + + OTG_SWITCH { + regulator-boot-on; + regulator-name = "otg_switch"; + phandle = <0xec>; + }; + }; + + battery { + compatible = "rk817,battery"; + ocv_table = <0xc5d 0xc94 0xcd0 0xd02 0xd34 0xd66 0xd98 0xdca 0xdfc 0xe2e 0xe56 0xe7e 0xea6 0xece 0xef6 0xf1e 0xf46 0xf6e 0xf96 0xf9b 0xfa0>; + design_capacity = <0xd34>; + design_qmax = <0xe86>; + bat_res = <0x64>; + sleep_enter_current = <0x12c>; + sleep_exit_current = <0x12c>; + sleep_filter_current = <0x64>; + power_off_thresd = <0xbb8>; + zero_algorithm_vol = <0xf0a>; + max_soc_offset = <0x3c>; + monitor_sec = <0x05>; + virtual_power = <0x00>; + sample_res = <0x0a>; + }; + + charger { + compatible = "rk817,charger"; + min_input_voltage = <0x1194>; + max_input_current = <0x5dc>; + max_chrg_current = <0x7d0>; + max_chrg_voltage = <0x1068>; + chrg_term_mode = <0x00>; + chrg_finish_cur = <0x34>; + virtual_power = <0x00>; + sample_res = <0x0a>; + dc_det_gpio = <0x5c 0x0b 0x00>; + bat_low_gpio = <0x66 0x0d 0x00>; + extcon = <0x67>; + }; + + codec { + #sound-dai-cells = <0x00>; + compatible = "rockchip,rk817-codec"; + clocks = <0x02 0x15>; + clock-names = "mclk"; + pinctrl-names = "default"; + pinctrl-0 = <0x68>; + hp-volume = <0x14>; + spk-volume = <0x03>; + status = "okay"; + phandle = <0xc3>; + }; + }; + }; + + i2c@ff190000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff190000 0x00 0x1000>; + clocks = <0x02 0x1e 0x02 0x14f>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x08 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x69>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + clock-frequency = <0x61a80>; + phandle = <0xed>; + }; + + i2c@ff1a0000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff1a0000 0x00 0x1000>; + clocks = <0x02 0x1f 0x02 0x150>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x09 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x6a>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xee>; + }; + + i2c@ff1b0000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff1b0000 0x00 0x1000>; + clocks = <0x02 0x20 0x02 0x151>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x0a 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x6b>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xef>; + }; + + spi@ff1d0000 { + compatible = "rockchip,px30-spi\0rockchip,rk3066-spi"; + reg = <0x00 0xff1d0000 0x00 0x1000>; + interrupts = <0x00 0x1a 0x04>; + #address-cells = <0x01>; + #size-cells = <0x00>; + clocks = <0x02 0x24 0x02 0x155>; + clock-names = "spiclk\0apb_pclk"; + dmas = <0x2b 0x0c 0x2b 0x0d>; + dma-names = "tx\0rx"; + pinctrl-names = "default\0high_speed"; + pinctrl-0 = <0x6c 0x6d 0x6e 0x6f>; + pinctrl-1 = <0x70 0x6d 0x71 0x72>; + status = "disabled"; + phandle = <0xf0>; + }; + + spi@ff1d8000 { + compatible = "rockchip,px30-spi\0rockchip,rk3066-spi"; + reg = <0x00 0xff1d8000 0x00 0x1000>; + interrupts = <0x00 0x1b 0x04>; + #address-cells = <0x01>; + #size-cells = <0x00>; + clocks = <0x02 0x25 0x02 0x156>; + clock-names = "spiclk\0apb_pclk"; + dmas = <0x2b 0x0e 0x2b 0x0f>; + dma-names = "tx\0rx"; + pinctrl-names = "default\0high_speed"; + pinctrl-0 = <0x73 0x74 0x75 0x76 0x77>; + pinctrl-1 = <0x78 0x74 0x75 0x79 0x7a>; + status = "disabled"; + phandle = <0xf1>; + }; + + watchdog@ff1e0000 { + compatible = "snps,dw-wdt"; + reg = <0x00 0xff1e0000 0x00 0x100>; + clocks = <0x02 0x15b>; + interrupts = <0x00 0x25 0x04>; + resets = <0x02 0xb5>; + reset-names = "reset"; + status = "disabled"; + phandle = <0xf2>; + }; + + pwm@ff200000 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200000 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7b>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "okay"; + phandle = <0xbc>; + }; + + pwm@ff200010 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200010 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7c>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "okay"; + phandle = <0xc1>; + }; + + pwm@ff200020 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200020 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7d>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf3>; + }; + + pwm@ff200030 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200030 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7e>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf4>; + }; + + pwm@ff208000 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208000 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7f>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf5>; + }; + + pwm@ff208010 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208010 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x80>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf6>; + }; + + pwm@ff208020 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208020 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x81>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf7>; + }; + + pwm@ff208030 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208030 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x82>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf8>; + }; + + rktimer@ff210000 { + compatible = "rockchip,rk3288-timer"; + reg = <0x00 0xff210000 0x00 0x1000>; + interrupts = <0x00 0x1e 0x04>; + clocks = <0x02 0x159 0x02 0x26>; + clock-names = "pclk\0timer"; + phandle = <0xf9>; + }; + + amba { + compatible = "simple-bus"; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + + dmac@ff240000 { + compatible = "arm,pl330\0arm,primecell"; + reg = <0x00 0xff240000 0x00 0x4000>; + interrupts = <0x00 0x01 0x04 0x00 0x02 0x04>; + clocks = <0x02 0xbb>; + clock-names = "apb_pclk"; + #dma-cells = <0x01>; + peripherals-req-type-burst; + phandle = <0x2b>; + }; + }; + + thermal-zones { + phandle = <0xfa>; + + soc-thermal { + polling-delay-passive = <0x14>; + polling-delay = <0x3e8>; + sustainable-power = <0x2ee>; + thermal-sensors = <0x83 0x00>; + phandle = <0xfb>; + + trips { + + trip-point-0 { + temperature = <0x11170>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0xfc>; + }; + + trip-point-1 { + temperature = <0x14c08>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0x84>; + }; + + soc-crit { + temperature = <0x1c138>; + hysteresis = <0x7d0>; + type = "critical"; + phandle = <0xfd>; + }; + }; + + cooling-maps { + + map0 { + trip = <0x84>; + cooling-device = <0x09 0xffffffff 0xffffffff>; + contribution = <0x1000>; + }; + + map1 { + trip = <0x84>; + cooling-device = <0x85 0xffffffff 0xffffffff>; + contribution = <0x1000>; + }; + }; + }; + + gpu-thermal { + polling-delay-passive = <0x64>; + polling-delay = <0x3e8>; + thermal-sensors = <0x83 0x01>; + phandle = <0xfe>; + }; + }; + + tsadc@ff280000 { + compatible = "rockchip,px30-tsadc"; + reg = <0x00 0xff280000 0x00 0x100>; + interrupts = <0x00 0x24 0x04>; + rockchip,grf = <0x2f>; + clocks = <0x02 0x2c 0x02 0x158>; + clock-names = "tsadc\0apb_pclk"; + assigned-clocks = <0x02 0x2c>; + assigned-clock-rates = <0xc350>; + resets = <0x02 0xa8>; + reset-names = "tsadc-apb"; + #thermal-sensor-cells = <0x01>; + rockchip,hw-tshut-temp = <0x1d4c0>; + status = "okay"; + pinctrl-names = "gpio\0otpout"; + pinctrl-0 = <0x86>; + pinctrl-1 = <0x87>; + phandle = <0x83>; + }; + + saradc@ff288000 { + compatible = "rockchip,px30-saradc\0rockchip,rk3399-saradc"; + reg = <0x00 0xff288000 0x00 0x100>; + interrupts = <0x00 0x54 0x04>; + #io-channel-cells = <0x01>; + clocks = <0x02 0x2d 0x02 0x157>; + clock-names = "saradc\0apb_pclk"; + resets = <0x02 0xa5>; + reset-names = "saradc-apb"; + status = "okay"; + vref-supply = <0x88>; + phandle = <0xbe>; + }; + + otp@ff290000 { + compatible = "rockchip,px30-otp"; + reg = <0x00 0xff290000 0x00 0x4000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + clocks = <0x02 0x2f 0x02 0x15a 0x02 0x161>; + clock-names = "clk_otp\0pclk_otp\0pclk_otp_phy"; + resets = <0x02 0xb4>; + reset-names = "otp_phy"; + phandle = <0xff>; + + id@7 { + reg = <0x07 0x10>; + phandle = <0x0f>; + }; + + cpu-leakage@17 { + reg = <0x17 0x01>; + phandle = <0x07>; + }; + + performance@1e { + reg = <0x1e 0x01>; + bits = <0x04 0x03>; + phandle = <0x08>; + }; + }; + + clock-controller@ff2b0000 { + compatible = "rockchip,px30-cru"; + reg = <0x00 0xff2b0000 0x00 0x1000>; + rockchip,grf = <0x2f>; + rockchip,boost = <0x89>; + #clock-cells = <0x01>; + #reset-cells = <0x01>; + assigned-clocks = <0x02 0x04>; + assigned-clock-rates = <0x3dfd2400>; + phandle = <0x02>; + }; + + cpu-boost@ff2b8000 { + compatible = "syscon"; + reg = <0x00 0xff2b8000 0x00 0x1000>; + rockchip,boost-low-con0 = <0x1032>; + rockchip,boost-low-con1 = <0x1441>; + rockchip,boost-high-con0 = <0x1036>; + rockchip,boost-high-con1 = <0x1441>; + rockchip,boost-backup-pll = <0x01>; + rockchip,boost-backup-pll-usage = <0x00>; + rockchip,boost-switch-threshold = <0x249f00>; + rockchip,boost-statis-threshold = <0x100>; + rockchip,boost-statis-enable = <0x00>; + rockchip,boost-enable = <0x00>; + phandle = <0x89>; + }; + + pmu-clock-controller@ff2bc000 { + compatible = "rockchip,px30-pmucru"; + reg = <0x00 0xff2bc000 0x00 0x1000>; + rockchip,grf = <0x2f>; + #clock-cells = <0x01>; + #reset-cells = <0x01>; + assigned-clocks = <0x2a 0x01 0x2a 0x08 0x2a 0x05 0x02 0x07 0x02 0xab 0x02 0xb0 0x02 0xf0 0x02 0xf5 0x02 0x140 0x02 0x49>; + assigned-clock-rates = <0x47868c00 0x5f5e100 0x18cba80 0x23c34600 0xbebc200 0xbebc200 0x8f0d180 0x8f0d180 0x5f5e100 0xbebc200>; + phandle = <0x2a>; + }; + + syscon@ff2c0000 { + compatible = "rockchip,px30-usb2phy-grf\0syscon\0simple-mfd"; + reg = <0x00 0xff2c0000 0x00 0x10000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0x100>; + + usb2-phy@100 { + compatible = "rockchip,px30-usb2phy\0rockchip,rk3328-usb2phy"; + reg = <0x100 0x10>; + clocks = <0x2a 0x0a>; + clock-names = "phyclk"; + #clock-cells = <0x00>; + assigned-clocks = <0x02 0x0e 0x02 0x55>; + assigned-clock-parents = <0x67 0x02 0x0e>; + clock-output-names = "usb480m_phy"; + status = "okay"; + phandle = <0x67>; + + host-port { + #phy-cells = <0x00>; + interrupts = <0x00 0x44 0x04>; + interrupt-names = "linestate"; + status = "okay"; + phandle = <0x8c>; + }; + + otg-port { + #phy-cells = <0x00>; + interrupts = <0x00 0x42 0x04 0x00 0x41 0x04 0x00 0x40 0x04>; + interrupt-names = "otg-bvalid\0otg-id\0linestate"; + status = "disabled"; + phandle = <0x8b>; + }; + }; + }; + + video-phy@ff2e0000 { + compatible = "rockchip,px30-video-phy"; + reg = <0x00 0xff2e0000 0x00 0x10000 0x00 0xff450000 0x00 0x10000>; + clocks = <0x2a 0x0b 0x02 0x145 0x02 0x144>; + clock-names = "ref\0pclk_phy\0pclk_host"; + #clock-cells = <0x00>; + resets = <0x02 0x3e>; + reset-names = "rst"; + power-domains = <0x8a 0x0c>; + #phy-cells = <0x00>; + status = "okay"; + phandle = <0x4c>; + }; + + mipi-dphy-rx0@ff2f0000 { + compatible = "rockchip,rk3326-mipi-dphy"; + reg = <0x00 0xff2f0000 0x00 0x4000>; + clocks = <0x02 0x146>; + clock-names = "dphy-ref"; + power-domains = <0x8a 0x0d>; + rockchip,grf = <0x2f>; + status = "okay"; + phandle = <0x101>; + }; + + usb@ff300000 { + compatible = "rockchip,px30-usb\0rockchip,rk3066-usb\0snps,dwc2"; + reg = <0x00 0xff300000 0x00 0x40000>; + interrupts = <0x00 0x3e 0x04>; + clocks = <0x02 0x102>; + clock-names = "otg"; + power-domains = <0x8a 0x05>; + dr_mode = "otg"; + g-np-tx-fifo-size = <0x10>; + g-rx-fifo-size = <0x118>; + g-tx-fifo-size = <0x100 0x80 0x80 0x40 0x20 0x10>; + g-use-dma; + phys = <0x8b>; + phy-names = "usb2-phy"; + status = "okay"; + phandle = <0x102>; + }; + + usb@ff340000 { + compatible = "generic-ehci"; + reg = <0x00 0xff340000 0x00 0x10000>; + interrupts = <0x00 0x3c 0x04>; + clocks = <0x02 0x103 0x67>; + clock-names = "usbhost\0utmi"; + power-domains = <0x8a 0x05>; + phys = <0x8c>; + phy-names = "usb"; + status = "disabled"; + phandle = <0x103>; + }; + + usb@ff350000 { + compatible = "generic-ohci"; + reg = <0x00 0xff350000 0x00 0x10000>; + interrupts = <0x00 0x3d 0x04>; + clocks = <0x02 0x103 0x67>; + clock-names = "usbhost\0utmi"; + power-domains = <0x8a 0x05>; + phys = <0x8c>; + phy-names = "usb"; + status = "disabled"; + phandle = <0x104>; + }; + + ethernet@ff360000 { + compatible = "rockchip,px30-gmac"; + reg = <0x00 0xff360000 0x00 0x10000>; + rockchip,grf = <0x2f>; + interrupts = <0x00 0x2b 0x04>; + interrupt-names = "macirq"; + clocks = <0x02 0x3e 0x02 0x3f 0x02 0x3f 0x02 0x40 0x02 0x41 0x02 0xb2 0x02 0x143 0x02 0x4c>; + clock-names = "stmmaceth\0mac_clk_rx\0mac_clk_tx\0clk_mac_ref\0clk_mac_refout\0aclk_mac\0pclk_mac\0clk_mac_speed"; + phy-mode = "rmii"; + pinctrl-names = "default"; + pinctrl-0 = <0x8d 0x8e>; + resets = <0x02 0x5e>; + reset-names = "stmmaceth"; + power-domains = <0x8a 0x09>; + status = "disabled"; + phandle = <0x105>; + }; + + dwmmc@ff370000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff370000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0xf7 0x02 0x3b 0x02 0x43 0x02 0x44>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x3b>; + assigned-clock-parents = <0x02 0x57>; + power-domains = <0x8a 0x07>; + fifo-depth = <0x100>; + interrupts = <0x00 0x36 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x8f 0x90 0x91 0x92>; + status = "okay"; + bus-width = <0x04>; + cap-mmc-highspeed; + cap-sd-highspeed; + supports-sd; + card-detect-delay = <0x320>; + ignore-pm-notify; + cd-gpios = <0x5c 0x03 0x01>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <0x4a>; + vmmc-supply = <0x93>; + phandle = <0x106>; + }; + + dwmmc@ff380000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff380000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0xff 0x02 0x38 0x02 0x45 0x02 0x46>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x38>; + assigned-clock-parents = <0x02 0x51>; + power-domains = <0x8a 0x0a>; + fifo-depth = <0x100>; + interrupts = <0x00 0x37 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x94 0x95 0x96>; + status = "okay"; + bus-width = <0x04>; + cap-mmc-highspeed; + cap-sd-highspeed; + supports-sd; + card-detect-delay = <0x320>; + ignore-pm-notify; + cd-gpios = <0x97 0x0e 0x01>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <0x4a>; + vmmc-supply = <0x93>; + phandle = <0x107>; + }; + + dwmmc@ff390000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff390000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0x100 0x02 0x39 0x02 0x47 0x02 0x48>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x39>; + assigned-clock-parents = <0x02 0x53>; + power-domains = <0x8a 0x0a>; + fifo-depth = <0x100>; + interrupts = <0x00 0x35 0x04>; + status = "disabled"; + phandle = <0x108>; + }; + + nandc@ff3b0000 { + compatible = "rockchip,rk-nandc"; + reg = <0x00 0xff3b0000 0x00 0x4000>; + interrupts = <0x00 0x39 0x04>; + nandc_id = <0x00>; + clocks = <0x02 0x37 0x02 0xfe>; + clock-names = "clk_nandc\0hclk_nandc"; + assigned-clocks = <0x02 0x37>; + assigned-clock-parents = <0x02 0x4f>; + power-domains = <0x8a 0x0a>; + status = "disabled"; + phandle = <0x109>; + }; + + sfc@ff3a0000 { + compatible = "rockchip,sfc"; + reg = <0x00 0xff3a0000 0x00 0x4000>; + interrupts = <0x00 0x38 0x04>; + clocks = <0x02 0x3a 0x02 0x101>; + clock-names = "clk_sfc\0hclk_sfc"; + assigned-clocks = <0x02 0x3a>; + assigned-clock-rates = <0x989680>; + status = "disabled"; + phandle = <0x10a>; + }; + + gpu@ff400000 { + compatible = "arm,malit602\0arm,malit60x\0arm,malit6xx\0arm,mali-midgard"; + reg = <0x00 0xff400000 0x00 0x4000>; + interrupts = <0x00 0x2d 0x04 0x00 0x2e 0x04 0x00 0x2f 0x04>; + interrupt-names = "GPU\0MMU\0JOB"; + clocks = <0x02 0x49>; + clock-names = "clk_mali"; + power-domains = <0x8a 0x0e>; + #cooling-cells = <0x02>; + operating-points-v2 = <0x98>; + status = "okay"; + mali-supply = <0x0e>; + phandle = <0x85>; + + power_model { + compatible = "arm,mali-simple-power-model"; + static-coefficient = <0x64578>; + dynamic-coefficient = <0x2dd>; + ts = <0x7d00 0x125c 0xffffffb0 0x02>; + thermal-zone = "gpu-thermal"; + }; + }; + + gpu-opp-table { + compatible = "operating-points-v2"; + rockchip,thermal-zone = "soc-thermal"; + rockchip,temp-hysteresis = <0x1388>; + rockchip,low-temp = <0x00>; + rockchip,low-temp-min-volt = <0xf4240>; + rockchip,low-temp-adjust-volt = <0x00 0x1e0 0xc350>; + rockchip,max-volt = <0x11edd8>; + rockchip,evb-irdrop = <0x61a8>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-ch = <0x00 0x00>; + phandle = <0x98>; + + opp-400000000 { + opp-hz = <0x00 0x17d78400>; + opp-microvolt = <0x100590>; + opp-microvolt-L0 = <0x100590>; + opp-microvolt-L1 = <0xfa3e8>; + opp-microvolt-L2 = <0xee098>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-480000000 { + opp-hz = <0x00 0x1c9c3800>; + opp-microvolt = <0x112a88>; + opp-microvolt-L0 = <0x112a88>; + opp-microvolt-L1 = <0x10c8e0>; + opp-microvolt-L2 = <0x100590>; + opp-microvolt-L3 = <0xf4240>; + }; + + opp-520000000 { + opp-hz = <0x00 0x1efe9200>; + opp-microvolt = <0x118c30>; + opp-microvolt-L0 = <0x118c30>; + opp-microvolt-L1 = <0x118c30>; + opp-microvolt-L2 = <0x10c8e0>; + opp-microvolt-L3 = <0x100590>; + }; + }; + + hevc_service@ff440000 { + compatible = "rockchip,hevc_sub"; + iommu_enabled = <0x01>; + reg = <0x00 0xff440000 0x00 0x400>; + interrupts = <0x00 0x31 0x04>; + interrupt-names = "irq_dec"; + dev_mode = <0x01>; + iommus = <0x99>; + allocator = <0x01>; + phandle = <0x9c>; + }; + + vpu_service@ff442000 { + compatible = "rockchip,vpu_sub"; + iommu_enabled = <0x01>; + reg = <0x00 0xff442000 0x00 0x800>; + interrupts = <0x00 0x50 0x04 0x00 0x4f 0x04>; + interrupt-names = "irq_enc\0irq_dec"; + dev_mode = <0x00>; + iommus = <0x9a>; + allocator = <0x01>; + phandle = <0x9b>; + }; + + vpu_combo { + compatible = "rockchip,vpu_combo"; + subcnt = <0x02>; + rockchip,grf = <0x2f>; + rockchip,sub = <0x9b 0x9c>; + clocks = <0x02 0xaf 0x02 0xf4 0x02 0x4b>; + clock-names = "aclk_vcodec\0hclk_vcodec\0clk_core"; + resets = <0x02 0x24 0x02 0x26 0x02 0x25 0x02 0x27 0x02 0x3f>; + reset-names = "video_a\0video_h\0niu_a\0niu_h\0video_core"; + power-domains = <0x8a 0x0b>; + mode_bit = <0x0f>; + mode_ctrl = <0x410>; + status = "okay"; + phandle = <0x10b>; + }; + + iommu@ff440440 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff440440 0x00 0x40 0x00 0xff440480 0x00 0x40>; + interrupts = <0x00 0x32 0x04>; + interrupt-names = "hevc_mmu"; + clocks = <0x02 0xaf 0x02 0xf4>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0b>; + #iommu-cells = <0x00>; + phandle = <0x99>; + }; + + iommu@ff442800 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff442800 0x00 0x100>; + interrupts = <0x00 0x51 0x04>; + interrupt-names = "vpu_mmu"; + clocks = <0x02 0xaf 0x02 0xf4>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0b>; + #iommu-cells = <0x00>; + phandle = <0x9a>; + }; + + dsi@ff450000 { + compatible = "rockchip,px30-mipi-dsi"; + reg = <0x00 0xff450000 0x00 0x10000>; + interrupts = <0x00 0x4b 0x04>; + clocks = <0x02 0x144 0x4c>; + clock-names = "pclk\0hs_clk"; + resets = <0x02 0x3d>; + reset-names = "apb"; + phys = <0x4c>; + phy-names = "mipi_dphy"; + power-domains = <0x8a 0x0c>; + rockchip,grf = <0x2f>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + phandle = <0x10c>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x13>; + status = "okay"; + phandle = <0xa3>; + }; + }; + }; + + panel@0 { + compatible = "elida,kd35t133\0simple-panel-dsi"; + reg = <0x00>; + backlight = <0x9d>; + backlight-supply = <0x9e>; + power-supply = <0x9f>; + reset-gpios = <0x97 0x10 0x01>; + prepare-delay-ms = <0x02>; + reset-delay-ms = <0x01>; + init-delay-ms = <0x14>; + enable-delay-ms = <0x78>; + disable-delay-ms = <0x32>; + unprepare-delay-ms = <0x14>; + width-mm = <0x34>; + height-mm = <0x46>; + dsi,flags = <0xa03>; + dsi,format = <0x00>; + dsi,lanes = <0x04>; + panel-init-sequence = [39 00 04 b9 f1 12 83 39 00 06 b1 00 00 00 da 80 39 00 04 b2 00 13 70 39 00 0b b3 10 10 28 28 03 ff 00 00 00 00 15 00 02 b4 80 15 00 03 b5 0a 0a 15 00 03 b6 7f 7f 39 00 05 b8 26 62 f0 63 39 00 1c ba 33 81 05 f9 0e 0e 20 00 00 00 00 00 00 00 44 25 00 90 0a 00 00 01 4f 01 00 00 37 15 00 02 bc 47 39 00 04 bf 02 11 00 39 00 0a c0 73 73 50 50 00 00 12 50 00 39 00 0d c1 53 c0 32 32 77 e1 dd dd 77 77 33 33 39 00 07 c6 82 00 bf ff 00 ff 39 00 07 c7 b8 00 0a 00 00 00 39 00 05 c8 10 40 1e 02 15 00 02 cc 0b 39 00 23 e0 00 07 0d 37 35 3f 41 44 06 0c 0d 0f 11 10 12 14 1a 00 07 0d 37 35 3f 41 44 06 0c 0d 0f 11 10 12 14 1a 39 00 0f e3 07 07 0b 0b 0b 0b 00 00 00 00 ff 00 c0 10 39 00 40 e9 c8 10 02 00 00 b0 b1 11 31 23 28 80 b0 b1 27 08 00 04 02 00 00 00 00 04 02 00 00 00 88 88 ba 60 24 08 88 88 88 88 88 88 88 ba 71 35 18 88 88 88 88 88 00 00 00 01 00 00 00 00 00 00 00 00 00 39 00 3e ea 97 0a 82 02 03 07 00 00 00 00 00 00 81 88 ba 17 53 88 88 88 88 88 88 80 88 ba 06 42 88 88 88 88 88 88 23 00 00 02 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 39 00 04 ef ff ff 01 05 c8 01 11 05 32 01 29]; + panel-exit-sequence = <0x5140128 0x50a0110>; + + display-timings { + native-mode = <0xa0>; + + 60Hz { + clock-frequency = <0x2faf080>; + hactive = <0x280>; + vactive = <0x1e0>; + hfront-porch = <0x1c2>; + hsync-len = <0x2e>; + hback-porch = <0x1c2>; + vfront-porch = <0x11>; + vsync-len = <0x05>; + vback-porch = <0x0d>; + hsync-active = <0x00>; + vsync-active = <0x00>; + de-active = <0x00>; + pixelclk-active = <0x01>; + phandle = <0xa0>; + }; + + 50Hz { + clock-frequency = <0x1851960>; + hactive = <0x280>; + vactive = <0x1e0>; + hfront-porch = <0xbc>; + hsync-len = <0x02>; + hback-porch = <0xbe>; + vfront-porch = <0x0d>; + vsync-len = <0x02>; + vback-porch = <0x05>; + hsync-active = <0x00>; + vsync-active = <0x00>; + de-active = <0x00>; + pixelclk-active = <0x00>; + phandle = <0x10d>; + }; + + 75Hz { + clock-frequency = <0x1d2eb40>; + hactive = <0x280>; + vactive = <0x1e0>; + hfront-porch = <0x57>; + hsync-len = <0x02>; + hback-porch = <0x57>; + vfront-porch = <0x0d>; + vsync-len = <0x02>; + vback-porch = <0x05>; + hsync-active = <0x00>; + vsync-active = <0x00>; + de-active = <0x00>; + pixelclk-active = <0x00>; + phandle = <0x10e>; + }; + }; + }; + }; + + vop@ff460000 { + compatible = "rockchip,px30-vop-big"; + reg = <0x00 0xff460000 0x00 0x1fc 0x00 0xff460a00 0x00 0x400>; + rockchip,grf = <0x2f>; + reg-names = "regs\0gamma_lut"; + interrupts = <0x00 0x4d 0x04>; + clocks = <0x02 0xb5 0x02 0x96 0x02 0xfb>; + clock-names = "aclk_vop\0dclk_vop\0hclk_vop"; + power-domains = <0x8a 0x0c>; + iommus = <0xa1>; + status = "okay"; + phandle = <0x10f>; + + port { + #address-cells = <0x01>; + #size-cells = <0x00>; + phandle = <0x10>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0xa2>; + phandle = <0x12>; + }; + + endpoint@1 { + reg = <0x01>; + remote-endpoint = <0xa3>; + phandle = <0x13>; + }; + + endpoint@2 { + reg = <0x02>; + remote-endpoint = <0xa4>; + phandle = <0x14>; + }; + }; + }; + + iommu@ff460f00 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff460f00 0x00 0x100>; + interrupts = <0x00 0x4d 0x04>; + interrupt-names = "vopb_mmu"; + clocks = <0x02 0xb5 0x02 0xfb>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0c>; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xa1>; + }; + + rk_rga@ff480000 { + compatible = "rockchip,rga2"; + reg = <0x00 0xff480000 0x00 0x1000>; + interrupts = <0x00 0x4c 0x04>; + clocks = <0x02 0xb7 0x02 0xfd 0x02 0x35>; + clock-names = "aclk_rga\0hclk_rga\0clk_rga"; + power-domains = <0x8a 0x0c>; + dma-coherent; + status = "okay"; + phandle = <0x110>; + }; + + cif@ff490000 { + compatible = "rockchip,cif"; + reg = <0x00 0xff490000 0x00 0x200>; + interrupts = <0x00 0x45 0x04>; + clocks = <0x02 0xb3 0x02 0xf9 0x02 0x160 0x02 0x34>; + clock-names = "aclk_cif0\0hclk_cif0\0pclk_cif\0cif0_out"; + resets = <0x02 0x2c 0x02 0x2d 0x02 0x2e>; + reset-names = "rst_cif_a\0rst_cif_h\0rst_cif_pclkin"; + power-domains = <0x8a 0x0d>; + pinctrl-names = "cif_pin_all"; + pinctrl-0 = <0xa5>; + iommus = <0xa6>; + status = "disabled"; + phandle = <0x111>; + }; + + cif-new@ff490000 { + compatible = "rockchip,px30-cif"; + reg = <0x00 0xff490000 0x00 0x200>; + interrupts = <0x00 0x45 0x04>; + clocks = <0x02 0xb3 0x02 0xf9 0x02 0x160 0x02 0x34>; + clock-names = "aclk_cif\0hclk_cif\0pclk_cif\0cif_out"; + resets = <0x02 0x2c 0x02 0x2d 0x02 0x2e>; + reset-names = "rst_cif_a\0rst_cif_h\0rst_cif_pclkin"; + power-domains = <0x8a 0x0d>; + iommus = <0xa6>; + status = "disabled"; + phandle = <0x112>; + }; + + iommu@ff490800 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff490800 0x00 0x100>; + interrupts = <0x00 0x45 0x04>; + interrupt-names = "vip_mmu"; + clocks = <0x02 0xb3 0x02 0xf9>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0d>; + rk_iommu,disable_reset_quirk; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xa6>; + }; + + rk_isp@ff4a0000 { + compatible = "rockchip,px30-isp\0rockchip,isp"; + reg = <0x00 0xff4a0000 0x00 0x8000>; + interrupts = <0x00 0x46 0x04>; + clocks = <0x02 0xb4 0x02 0xfa 0x02 0x33 0x02 0x33 0x02 0x15f 0x02 0x34 0x02 0x34 0x02 0x146>; + clock-names = "aclk_isp\0hclk_isp\0clk_isp\0clk_isp_jpe\0pclkin_isp\0clk_cif_pll\0clk_cif_out\0pclk_dphyrx"; + resets = <0x02 0x2b 0x02 0x2f>; + reset-names = "rst_isp\0rst_mipicsiphy"; + power-domains = <0x8a 0x0d>; + pinctrl-names = "default\0isp_dvp8bit2\0isp_dvp10bit\0isp_dvp12bit"; + pinctrl-0 = <0xa7>; + pinctrl-1 = <0xa5>; + pinctrl-2 = <0xa5 0xa8>; + pinctrl-3 = <0xa9 0xa5 0xa8>; + rockchip,isp,mipiphy = <0x01>; + rockchip,isp,csiphy,reg = <0xff2f0000 0x4000>; + rockchip,grf = <0x2f>; + rockchip,cru = <0x02>; + rockchip,isp,iommu-enable = <0x01>; + iommus = <0xaa>; + status = "disabled"; + phandle = <0x113>; + }; + + rkisp1@ff4a0000 { + compatible = "rockchip,rk3326-rkisp1"; + reg = <0x00 0xff4a0000 0x00 0x8000>; + interrupts = <0x00 0x46 0x04 0x00 0x49 0x04 0x00 0x4a 0x04>; + interrupt-names = "isp_irq\0mi_irq\0mipi_irq"; + clocks = <0x02 0xb4 0x02 0xfa 0x02 0x33 0x02 0x15f>; + clock-names = "aclk_isp\0hclk_isp\0clk_isp\0pclk_isp"; + devfreq = <0xab>; + power-domains = <0x8a 0x0d>; + iommus = <0xaa>; + rockchip,grf = <0x2f>; + status = "okay"; + phandle = <0x114>; + }; + + iommu@ff4a8000 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff4a8000 0x00 0x100>; + interrupts = <0x00 0x46 0x04>; + interrupt-names = "isp_mmu"; + clocks = <0x02 0xb4 0x02 0xfa>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0d>; + rk_iommu,disable_reset_quirk; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xaa>; + }; + + qos@ff518000 { + compatible = "syscon"; + reg = <0x00 0xff518000 0x00 0x20>; + phandle = <0x18>; + }; + + qos@ff520000 { + compatible = "syscon"; + reg = <0x00 0xff520000 0x00 0x20>; + phandle = <0x28>; + }; + + qos@ff52c000 { + compatible = "syscon"; + reg = <0x00 0xff52c000 0x00 0x20>; + phandle = <0x17>; + }; + + qos@ff538000 { + compatible = "syscon"; + reg = <0x00 0xff538000 0x00 0x20>; + phandle = <0x19>; + }; + + qos@ff538080 { + compatible = "syscon"; + reg = <0x00 0xff538080 0x00 0x20>; + phandle = <0x1a>; + }; + + qos@ff538100 { + compatible = "syscon"; + reg = <0x00 0xff538100 0x00 0x20>; + phandle = <0x1b>; + }; + + qos@ff538180 { + compatible = "syscon"; + reg = <0x00 0xff538180 0x00 0x20>; + phandle = <0x1c>; + }; + + qos@ff540000 { + compatible = "syscon"; + reg = <0x00 0xff540000 0x00 0x20>; + phandle = <0x15>; + }; + + qos@ff540080 { + compatible = "syscon"; + reg = <0x00 0xff540080 0x00 0x20>; + phandle = <0x16>; + }; + + qos@ff548000 { + compatible = "syscon"; + reg = <0x00 0xff548000 0x00 0x20>; + phandle = <0x23>; + }; + + qos@ff548080 { + compatible = "syscon"; + reg = <0x00 0xff548080 0x00 0x20>; + phandle = <0x24>; + }; + + qos@ff548100 { + compatible = "syscon"; + reg = <0x00 0xff548100 0x00 0x20>; + phandle = <0x25>; + }; + + qos@ff548180 { + compatible = "syscon"; + reg = <0x00 0xff548180 0x00 0x20>; + phandle = <0x26>; + }; + + qos@ff548200 { + compatible = "syscon"; + reg = <0x00 0xff548200 0x00 0x20>; + phandle = <0x27>; + }; + + qos@ff550000 { + compatible = "syscon"; + reg = <0x00 0xff550000 0x00 0x20>; + phandle = <0x1f>; + }; + + qos@ff550080 { + compatible = "syscon"; + reg = <0x00 0xff550080 0x00 0x20>; + phandle = <0x20>; + }; + + qos@ff550100 { + compatible = "syscon"; + reg = <0x00 0xff550100 0x00 0x20>; + phandle = <0x21>; + }; + + qos@ff550180 { + compatible = "syscon"; + reg = <0x00 0xff550180 0x00 0x20>; + phandle = <0x22>; + }; + + qos@ff558000 { + compatible = "syscon"; + reg = <0x00 0xff558000 0x00 0x20>; + phandle = <0x1d>; + }; + + qos@ff558080 { + compatible = "syscon"; + reg = <0x00 0xff558080 0x00 0x20>; + phandle = <0x1e>; + }; + + dfi@ff610000 { + reg = <0x00 0xff610000 0x00 0x400>; + compatible = "rockchip,px30-dfi"; + rockchip,pmugrf = <0xac>; + status = "okay"; + phandle = <0xad>; + }; + + dmc { + compatible = "rockchip,px30-dmc"; + interrupts = <0x00 0x69 0x04>; + interrupt-names = "complete_irq"; + devfreq-events = <0xad>; + clocks = <0x02 0x54>; + clock-names = "dmc_clk"; + operating-points-v2 = <0xae>; + ddr_timing = <0xaf>; + upthreshold = <0x28>; + downdifferential = <0x14>; + system-status-freq = <0x01 0x80e80 0x08 0x6ddd0 0x02 0x2f5d0 0x20 0x6ddd0 0x1000 0x80e80 0x4000 0xa2990 0x2000 0xa2990>; + auto-min-freq = <0x50140>; + auto-freq-en = <0x01>; + #cooling-cells = <0x02>; + status = "okay"; + center-supply = <0x0e>; + phandle = <0xab>; + + ddr_power_model { + compatible = "ddr_power_model"; + dynamic-power-coefficient = <0x78>; + static-power-coefficient = <0xc8>; + ts = <0x7d00 0x125c 0xffffffb0 0x02>; + thermal-zone = "soc-thermal"; + phandle = <0x115>; + }; + }; + + dmc-opp-table { + compatible = "operating-points-v2"; + rockchip,max-volt = <0x118c30>; + rockchip,evb-irdrop = <0x61a8>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-ch = <0x00 0x00>; + phandle = <0xae>; + + opp-528000000 { + opp-hz = <0x00 0x1f78a400>; + opp-microvolt = <0xee098>; + opp-microvolt-L0 = <0xee098>; + opp-microvolt-L1 = <0xee098>; + opp-microvolt-L2 = <0xe7ef0>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-666000000 { + opp-hz = <0x00 0x27b25a80>; + opp-microvolt = <0x100590>; + opp-microvolt-L0 = <0x100590>; + opp-microvolt-L1 = <0xf4240>; + opp-microvolt-L2 = <0xee098>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-786000000 { + opp-hz = <0x00 0x2ed96880>; + opp-microvolt = <0x10c8e0>; + opp-microvolt-L0 = <0x10c8e0>; + opp-microvolt-L1 = <0x100590>; + opp-microvolt-L2 = <0xfa3e8>; + opp-microvolt-L3 = <0xf4240>; + status = "okay"; + }; + }; + + rockchip-system-monitor { + compatible = "rockchip,system-monitor"; + rockchip,thermal-zone = "soc-thermal"; + rockchip,polling-delay = <0xc8>; + phandle = <0x116>; + }; + + pinctrl { + compatible = "rockchip,px30-pinctrl"; + rockchip,grf = <0x2f>; + rockchip,pmu = <0xac>; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + phandle = <0x117>; + + gpio0@ff040000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff040000 0x00 0x100>; + interrupts = <0x00 0x03 0x04>; + clocks = <0x2a 0x14>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x5c>; + }; + + gpio1@ff250000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff250000 0x00 0x100>; + interrupts = <0x00 0x04 0x04>; + clocks = <0x02 0x15c>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0xbf>; + }; + + gpio2@ff260000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff260000 0x00 0x100>; + interrupts = <0x00 0x05 0x04>; + clocks = <0x02 0x15d>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x66>; + }; + + gpio3@ff270000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff270000 0x00 0x100>; + interrupts = <0x00 0x06 0x04>; + clocks = <0x02 0x15e>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x97>; + }; + + pcfg-pull-up { + bias-pull-up; + phandle = <0xb2>; + }; + + pcfg-pull-down { + bias-pull-down; + phandle = <0x118>; + }; + + pcfg-pull-none { + bias-disable; + phandle = <0xb1>; + }; + + pcfg-pull-none-2ma { + bias-disable; + drive-strength = <0x02>; + phandle = <0x119>; + }; + + pcfg-pull-up-2ma { + bias-pull-up; + drive-strength = <0x02>; + phandle = <0x11a>; + }; + + pcfg-pull-up-4ma { + bias-pull-up; + drive-strength = <0x04>; + phandle = <0xb3>; + }; + + pcfg-pull-none-4ma { + bias-disable; + drive-strength = <0x04>; + phandle = <0x11b>; + }; + + pcfg-pull-down-4ma { + bias-pull-down; + drive-strength = <0x04>; + phandle = <0x11c>; + }; + + pcfg-pull-none-8ma { + bias-disable; + drive-strength = <0x08>; + phandle = <0xb6>; + }; + + pcfg-pull-up-8ma { + bias-pull-up; + drive-strength = <0x08>; + phandle = <0xb4>; + }; + + pcfg-pull-none-12ma { + bias-disable; + drive-strength = <0x0c>; + phandle = <0xb8>; + }; + + pcfg-pull-up-12ma { + bias-pull-up; + drive-strength = <0x0c>; + phandle = <0xb7>; + }; + + pcfg-pull-none-smt { + bias-disable; + input-schmitt-enable; + phandle = <0xb0>; + }; + + pcfg-output-high { + output-high; + phandle = <0x11d>; + }; + + pcfg-output-low { + output-low; + phandle = <0xb9>; + }; + + pcfg-input-high { + bias-pull-up; + input-enable; + phandle = <0xb5>; + }; + + pcfg-input { + input-enable; + phandle = <0x11e>; + }; + + i2c0 { + + i2c0-xfer { + rockchip,pins = <0x00 0x08 0x01 0xb0 0x00 0x09 0x01 0xb0>; + phandle = <0x5b>; + }; + }; + + i2c1 { + + i2c1-xfer { + rockchip,pins = <0x00 0x12 0x01 0xb0 0x00 0x13 0x01 0xb0>; + phandle = <0x69>; + }; + }; + + i2c2 { + + i2c2-xfer { + rockchip,pins = <0x02 0x0f 0x02 0xb0 0x02 0x10 0x02 0xb0>; + phandle = <0x6a>; + }; + }; + + i2c3 { + + i2c3-xfer { + rockchip,pins = <0x01 0x0c 0x04 0xb0 0x01 0x0d 0x04 0xb0>; + phandle = <0x6b>; + }; + }; + + tsadc { + + tsadc-otp-gpio { + rockchip,pins = <0x00 0x06 0x00 0xb1>; + phandle = <0x86>; + }; + + tsadc-otp-out { + rockchip,pins = <0x00 0x06 0x01 0xb1>; + phandle = <0x87>; + }; + }; + + uart0 { + + uart0-xfer { + rockchip,pins = <0x00 0x0a 0x01 0xb2 0x00 0x0b 0x01 0xb2>; + phandle = <0x2c>; + }; + + uart0-cts { + rockchip,pins = <0x00 0x0c 0x01 0xb1>; + phandle = <0x2d>; + }; + + uart0-rts { + rockchip,pins = <0x00 0x0d 0x01 0xb1>; + phandle = <0x2e>; + }; + + uart0-rts-gpio { + rockchip,pins = <0x00 0x0d 0x00 0xb1>; + phandle = <0x11f>; + }; + }; + + uart1 { + + uart1-xfer { + rockchip,pins = <0x01 0x11 0x01 0xb2 0x01 0x10 0x01 0xb2>; + phandle = <0x4f>; + }; + + uart1-cts { + rockchip,pins = <0x01 0x12 0x01 0xb1>; + phandle = <0x50>; + }; + + uart1-rts { + rockchip,pins = <0x01 0x13 0x01 0xb1>; + phandle = <0x120>; + }; + + uart1-rts-gpio { + rockchip,pins = <0x01 0x13 0x00 0xb1>; + phandle = <0x121>; + }; + }; + + uart2-m0 { + + uart2m0-xfer { + rockchip,pins = <0x01 0x1a 0x02 0xb2 0x01 0x1b 0x02 0xb2>; + phandle = <0x51>; + }; + }; + + uart2-m1 { + + uart2m1-xfer { + rockchip,pins = <0x02 0x0c 0x02 0xb2 0x02 0x0e 0x02 0xb2>; + phandle = <0xba>; + }; + }; + + uart3-m0 { + + uart3m0-xfer { + rockchip,pins = <0x00 0x10 0x02 0xb2 0x00 0x11 0x02 0xb2>; + phandle = <0x122>; + }; + + uart3m0-cts { + rockchip,pins = <0x00 0x12 0x02 0xb1>; + phandle = <0x123>; + }; + + uart3m0-rts { + rockchip,pins = <0x00 0x13 0x02 0xb1>; + phandle = <0x124>; + }; + + uart3m0-rts-gpio { + rockchip,pins = <0x00 0x13 0x00 0xb1>; + phandle = <0x125>; + }; + }; + + uart3-m1 { + + uart3m1-xfer { + rockchip,pins = <0x01 0x0e 0x02 0xb2 0x01 0x0f 0x02 0xb2>; + phandle = <0x52>; + }; + + uart3m1-cts { + rockchip,pins = <0x01 0x0c 0x02 0xb1>; + phandle = <0x53>; + }; + + uart3m1-rts { + rockchip,pins = <0x01 0x0d 0x02 0xb1>; + phandle = <0x54>; + }; + + uart3m1-rts-gpio { + rockchip,pins = <0x01 0x0d 0x00 0xb1>; + phandle = <0x126>; + }; + }; + + uart4 { + + uart4-xfer { + rockchip,pins = <0x01 0x1c 0x02 0xb2 0x01 0x1d 0x02 0xb2>; + phandle = <0x55>; + }; + + uart4-cts { + rockchip,pins = <0x01 0x1e 0x02 0xb1>; + phandle = <0x56>; + }; + + uart4-rts { + rockchip,pins = <0x01 0x1f 0x02 0xb1>; + phandle = <0x57>; + }; + }; + + uart5 { + + uart5-xfer { + rockchip,pins = <0x03 0x02 0x04 0xb2 0x03 0x01 0x04 0xb2>; + phandle = <0x58>; + }; + + uart5-cts { + rockchip,pins = <0x03 0x03 0x04 0xb1>; + phandle = <0x59>; + }; + + uart5-rts { + rockchip,pins = <0x03 0x05 0x04 0xb1>; + phandle = <0x5a>; + }; + }; + + spi0 { + + spi0-clk { + rockchip,pins = <0x01 0x0f 0x03 0xb3>; + phandle = <0x6c>; + }; + + spi0-csn { + rockchip,pins = <0x01 0x0e 0x03 0xb3>; + phandle = <0x6d>; + }; + + spi0-miso { + rockchip,pins = <0x01 0x0d 0x03 0xb3>; + phandle = <0x6e>; + }; + + spi0-mosi { + rockchip,pins = <0x01 0x0c 0x03 0xb3>; + phandle = <0x6f>; + }; + + spi0-clk-hs { + rockchip,pins = <0x01 0x0f 0x03 0xb4>; + phandle = <0x70>; + }; + + spi0-miso-hs { + rockchip,pins = <0x01 0x0d 0x03 0xb4>; + phandle = <0x71>; + }; + + spi0-mosi-hs { + rockchip,pins = <0x01 0x0c 0x03 0xb4>; + phandle = <0x72>; + }; + }; + + spi1 { + + spi1-clk { + rockchip,pins = <0x03 0x0f 0x04 0xb3>; + phandle = <0x73>; + }; + + spi1-csn0 { + rockchip,pins = <0x03 0x09 0x04 0xb3>; + phandle = <0x74>; + }; + + spi1-csn1 { + rockchip,pins = <0x03 0x0a 0x02 0xb3>; + phandle = <0x75>; + }; + + spi1-miso { + rockchip,pins = <0x03 0x0e 0x04 0xb3>; + phandle = <0x76>; + }; + + spi1-mosi { + rockchip,pins = <0x03 0x0c 0x04 0xb3>; + phandle = <0x77>; + }; + + spi1-clk-hs { + rockchip,pins = <0x03 0x0f 0x04 0xb4>; + phandle = <0x78>; + }; + + spi1-miso-hs { + rockchip,pins = <0x03 0x0e 0x04 0xb4>; + phandle = <0x79>; + }; + + spi1-mosi-hs { + rockchip,pins = <0x03 0x0c 0x04 0xb4>; + phandle = <0x7a>; + }; + }; + + pdm { + + pdm-clk0m0 { + rockchip,pins = <0x03 0x16 0x02 0xb1>; + phandle = <0x44>; + }; + + pdm-clk0m1 { + rockchip,pins = <0x02 0x16 0x01 0xb1>; + phandle = <0x127>; + }; + + pdm-clk1 { + rockchip,pins = <0x03 0x17 0x02 0xb1>; + phandle = <0x45>; + }; + + pdm-sdi0m0 { + rockchip,pins = <0x03 0x1b 0x02 0xb1>; + phandle = <0x46>; + }; + + pdm-sdi0m1 { + rockchip,pins = <0x02 0x15 0x02 0xb1>; + phandle = <0x128>; + }; + + pdm-sdi1 { + rockchip,pins = <0x03 0x18 0x02 0xb1>; + phandle = <0x47>; + }; + + pdm-sdi2 { + rockchip,pins = <0x03 0x19 0x02 0xb1>; + phandle = <0x48>; + }; + + pdm-sdi3 { + rockchip,pins = <0x03 0x1a 0x02 0xb1>; + phandle = <0x49>; + }; + + pdm-clk0m0-sleep { + rockchip,pins = <0x03 0x16 0x00 0xb5>; + phandle = <0x129>; + }; + + pdm-clk0m1-sleep { + rockchip,pins = <0x02 0x16 0x00 0xb5>; + phandle = <0x12a>; + }; + + pdm-clk1-sleep { + rockchip,pins = <0x03 0x17 0x00 0xb5>; + phandle = <0x12b>; + }; + + pdm-sdi0m0-sleep { + rockchip,pins = <0x03 0x1b 0x00 0xb5>; + phandle = <0x12c>; + }; + + pdm-sdi0m1-sleep { + rockchip,pins = <0x02 0x15 0x00 0xb5>; + phandle = <0x12d>; + }; + + pdm-sdi1-sleep { + rockchip,pins = <0x03 0x18 0x00 0xb5>; + phandle = <0x12e>; + }; + + pdm-sdi2-sleep { + rockchip,pins = <0x03 0x19 0x00 0xb5>; + phandle = <0x12f>; + }; + + pdm-sdi3-sleep { + rockchip,pins = <0x03 0x1a 0x00 0xb5>; + phandle = <0x130>; + }; + }; + + i2s0 { + + i2s0-8ch-mclk { + rockchip,pins = <0x03 0x11 0x02 0xb1>; + phandle = <0x131>; + }; + + i2s0-8ch-sclktx { + rockchip,pins = <0x03 0x13 0x02 0xb1>; + phandle = <0x30>; + }; + + i2s0-8ch-sclkrx { + rockchip,pins = <0x03 0x0c 0x02 0xb1>; + phandle = <0x31>; + }; + + i2s0-8ch-lrcktx { + rockchip,pins = <0x03 0x12 0x02 0xb1>; + phandle = <0x32>; + }; + + i2s0-8ch-lrckrx { + rockchip,pins = <0x03 0x0d 0x02 0xb1>; + phandle = <0x33>; + }; + + i2s0-8ch-sdo0 { + rockchip,pins = <0x03 0x14 0x02 0xb1>; + phandle = <0x38>; + }; + + i2s0-8ch-sdo1 { + rockchip,pins = <0x03 0x10 0x02 0xb1>; + phandle = <0x39>; + }; + + i2s0-8ch-sdo2 { + rockchip,pins = <0x03 0x0f 0x02 0xb1>; + phandle = <0x3a>; + }; + + i2s0-8ch-sdo3 { + rockchip,pins = <0x03 0x0e 0x02 0xb1>; + phandle = <0x3b>; + }; + + i2s0-8ch-sdi0 { + rockchip,pins = <0x03 0x15 0x02 0xb1>; + phandle = <0x34>; + }; + + i2s0-8ch-sdi1 { + rockchip,pins = <0x03 0x0b 0x02 0xb1>; + phandle = <0x35>; + }; + + i2s0-8ch-sdi2 { + rockchip,pins = <0x03 0x09 0x02 0xb1>; + phandle = <0x36>; + }; + + i2s0-8ch-sdi3 { + rockchip,pins = <0x03 0x08 0x02 0xb1>; + phandle = <0x37>; + }; + }; + + i2s1 { + + i2s1-2ch-mclk { + rockchip,pins = <0x02 0x13 0x01 0xb1>; + phandle = <0x68>; + }; + + i2s1-2ch-sclk { + rockchip,pins = <0x02 0x12 0x01 0xb1>; + phandle = <0x3c>; + }; + + i2s1-2ch-lrck { + rockchip,pins = <0x02 0x11 0x01 0xb1>; + phandle = <0x3d>; + }; + + i2s1-2ch-sdi { + rockchip,pins = <0x02 0x15 0x01 0xb1>; + phandle = <0x3e>; + }; + + i2s1-2ch-sdo { + rockchip,pins = <0x02 0x14 0x01 0xb1>; + phandle = <0x3f>; + }; + }; + + i2s2 { + + i2s2-2ch-mclk { + rockchip,pins = <0x03 0x01 0x02 0xb1>; + phandle = <0x132>; + }; + + i2s2-2ch-sclk { + rockchip,pins = <0x03 0x02 0x02 0xb1>; + phandle = <0x40>; + }; + + i2s2-2ch-lrck { + rockchip,pins = <0x03 0x03 0x02 0xb1>; + phandle = <0x41>; + }; + + i2s2-2ch-sdi { + rockchip,pins = <0x03 0x05 0x02 0xb1>; + phandle = <0x42>; + }; + + i2s2-2ch-sdo { + rockchip,pins = <0x03 0x07 0x02 0xb1>; + phandle = <0x43>; + }; + }; + + sdmmc { + + sdmmc-clk { + rockchip,pins = <0x01 0x1e 0x01 0xb6>; + phandle = <0x8f>; + }; + + sdmmc-cmd { + rockchip,pins = <0x01 0x1f 0x01 0xb4>; + phandle = <0x90>; + }; + + sdmmc-det { + rockchip,pins = <0x00 0x03 0x01 0xb4>; + phandle = <0x91>; + }; + + sdmmc-bus1 { + rockchip,pins = <0x01 0x1a 0x01 0xb4>; + phandle = <0x133>; + }; + + sdmmc-bus4 { + rockchip,pins = <0x01 0x1a 0x01 0xb4 0x01 0x1b 0x01 0xb4 0x01 0x1c 0x01 0xb4 0x01 0x1d 0x01 0xb4>; + phandle = <0x92>; + }; + + sdmmc-gpio { + rockchip,pins = <0x01 0x1a 0x00 0xb3 0x01 0x1b 0x00 0xb3 0x01 0x1c 0x00 0xb3 0x01 0x1d 0x00 0xb3 0x01 0x1e 0x00 0xb3 0x01 0x1f 0x00 0xb3>; + phandle = <0x134>; + }; + }; + + sdio { + + sdio-clk { + rockchip,pins = <0x01 0x15 0x01 0xb1>; + phandle = <0x96>; + }; + + sdio-cmd { + rockchip,pins = <0x01 0x14 0x01 0xb2>; + phandle = <0x95>; + }; + + sdio-bus4 { + rockchip,pins = <0x01 0x16 0x01 0xb2 0x01 0x17 0x01 0xb2 0x01 0x18 0x01 0xb2 0x01 0x19 0x01 0xb2>; + phandle = <0x94>; + }; + + sdio-gpio { + rockchip,pins = <0x01 0x16 0x00 0xb2 0x01 0x17 0x00 0xb2 0x01 0x18 0x00 0xb2 0x01 0x19 0x00 0xb2 0x01 0x14 0x00 0xb2 0x01 0x15 0x00 0xb2>; + phandle = <0x135>; + }; + }; + + emmc { + + emmc-clk { + rockchip,pins = <0x01 0x09 0x02 0xb6>; + phandle = <0x136>; + }; + + emmc-cmd { + rockchip,pins = <0x01 0x0a 0x02 0xb4>; + phandle = <0x137>; + }; + + emmc-pwren { + rockchip,pins = <0x01 0x08 0x02 0xb1>; + phandle = <0x138>; + }; + + emmc-rstnout { + rockchip,pins = <0x01 0x0b 0x02 0xb1>; + phandle = <0x139>; + }; + + emmc-bus1 { + rockchip,pins = <0x01 0x00 0x02 0xb4>; + phandle = <0x13a>; + }; + + emmc-bus4 { + rockchip,pins = <0x01 0x00 0x02 0xb4 0x01 0x01 0x02 0xb4 0x01 0x02 0x02 0xb4 0x01 0x03 0x02 0xb4>; + phandle = <0x13b>; + }; + + emmc-bus8 { + rockchip,pins = <0x01 0x00 0x02 0xb4 0x01 0x01 0x02 0xb4 0x01 0x02 0x02 0xb4 0x01 0x03 0x02 0xb4 0x01 0x04 0x02 0xb4 0x01 0x05 0x02 0xb4 0x01 0x06 0x02 0xb4 0x01 0x07 0x02 0xb4>; + phandle = <0x13c>; + }; + }; + + flash { + + flash-cs0 { + rockchip,pins = <0x01 0x08 0x01 0xb1>; + phandle = <0x13d>; + }; + + flash-rdy { + rockchip,pins = <0x01 0x09 0x01 0xb1>; + phandle = <0x13e>; + }; + + flash-dqs { + rockchip,pins = <0x01 0x0a 0x01 0xb1>; + phandle = <0x13f>; + }; + + flash-ale { + rockchip,pins = <0x01 0x0b 0x01 0xb1>; + phandle = <0x140>; + }; + + flash-cle { + rockchip,pins = <0x01 0x0c 0x01 0xb1>; + phandle = <0x141>; + }; + + flash-wrn { + rockchip,pins = <0x01 0x0d 0x01 0xb1>; + phandle = <0x142>; + }; + + flash-csl { + rockchip,pins = <0x01 0x0e 0x01 0xb1>; + phandle = <0x143>; + }; + + flash-rdn { + rockchip,pins = <0x01 0x0f 0x01 0xb1>; + phandle = <0x144>; + }; + + flash-bus8 { + rockchip,pins = <0x01 0x00 0x01 0xb7 0x01 0x01 0x01 0xb7 0x01 0x02 0x01 0xb7 0x01 0x03 0x01 0xb7 0x01 0x04 0x01 0xb7 0x01 0x05 0x01 0xb7 0x01 0x06 0x01 0xb7 0x01 0x07 0x01 0xb7>; + phandle = <0x145>; + }; + }; + + lcdc { + + lcdc-m0-rgb-pins { + rockchip,pins = <0x03 0x00 0x01 0xb6 0x03 0x01 0x01 0xb6 0x03 0x02 0x01 0xb6 0x03 0x03 0x01 0xb6 0x03 0x04 0x01 0xb6 0x03 0x05 0x01 0xb6 0x03 0x06 0x01 0xb6 0x03 0x07 0x01 0xb6 0x03 0x08 0x01 0xb6 0x03 0x09 0x01 0xb6 0x03 0x0a 0x01 0xb6 0x03 0x0b 0x01 0xb6 0x03 0x0c 0x01 0xb6 0x03 0x0d 0x01 0xb6 0x03 0x0e 0x01 0xb6 0x03 0x0f 0x01 0xb6 0x03 0x10 0x01 0xb6 0x03 0x11 0x01 0xb6 0x03 0x12 0x01 0xb6 0x03 0x13 0x01 0xb6 0x03 0x14 0x01 0xb6 0x03 0x15 0x01 0xb6 0x03 0x16 0x01 0xb6 0x03 0x17 0x01 0xb6 0x03 0x18 0x01 0xb6 0x03 0x19 0x01 0xb6 0x03 0x1a 0x01 0xb6 0x03 0x1b 0x01 0xb6>; + phandle = <0x146>; + }; + + lcdc-m0-sleep-pins { + rockchip,pins = <0x03 0x00 0x00 0xb1 0x03 0x01 0x00 0xb1 0x03 0x02 0x00 0xb1 0x03 0x03 0x00 0xb1 0x03 0x04 0x00 0xb1 0x03 0x05 0x00 0xb1 0x03 0x06 0x00 0xb1 0x03 0x07 0x00 0xb1 0x03 0x08 0x00 0xb1 0x03 0x09 0x00 0xb1 0x03 0x0a 0x00 0xb1 0x03 0x0b 0x00 0xb1 0x03 0x0c 0x00 0xb1 0x03 0x0d 0x00 0xb1 0x03 0x0e 0x00 0xb1 0x03 0x0f 0x00 0xb1 0x03 0x10 0x00 0xb1 0x03 0x11 0x00 0xb1 0x03 0x12 0x00 0xb1 0x03 0x13 0x00 0xb1 0x03 0x14 0x00 0xb1 0x03 0x15 0x00 0xb1 0x03 0x16 0x00 0xb1 0x03 0x17 0x00 0xb1 0x03 0x18 0x00 0xb1 0x03 0x19 0x00 0xb1 0x03 0x1a 0x00 0xb1 0x03 0x1b 0x00 0xb1>; + phandle = <0x147>; + }; + + lcdc-m1-rgb-pins { + rockchip,pins = <0x03 0x00 0x01 0xb6 0x03 0x04 0x01 0xb6 0x03 0x06 0x01 0xb6 0x03 0x0a 0x01 0xb6 0x03 0x0b 0x01 0xb6 0x03 0x0d 0x01 0xb6 0x03 0x10 0x01 0xb6 0x03 0x11 0x01 0xb6 0x03 0x12 0x01 0xb6 0x03 0x13 0x01 0xb6 0x03 0x14 0x01 0xb6 0x03 0x15 0x01 0xb6 0x03 0x16 0x01 0xb6 0x03 0x17 0x01 0xb6 0x03 0x18 0x01 0xb6 0x03 0x19 0x01 0xb6 0x03 0x1a 0x01 0xb6 0x03 0x1b 0x01 0xb6>; + phandle = <0x4d>; + }; + + lcdc-m1-sleep-pins { + rockchip,pins = <0x03 0x00 0x00 0xb1 0x03 0x04 0x00 0xb1 0x03 0x06 0x00 0xb1 0x03 0x0a 0x00 0xb1 0x03 0x0b 0x00 0xb1 0x03 0x0d 0x00 0xb1 0x03 0x10 0x00 0xb1 0x03 0x11 0x00 0xb1 0x03 0x12 0x00 0xb1 0x03 0x13 0x00 0xb1 0x03 0x14 0x00 0xb1 0x03 0x15 0x00 0xb1 0x03 0x16 0x00 0xb1 0x03 0x17 0x00 0xb1 0x03 0x18 0x00 0xb1 0x03 0x19 0x00 0xb1 0x03 0x1a 0x00 0xb1 0x03 0x1b 0x00 0xb1>; + phandle = <0x4e>; + }; + }; + + pwm0 { + + pwm0-pin { + rockchip,pins = <0x00 0x0f 0x01 0xb1>; + phandle = <0x7b>; + }; + }; + + pwm1 { + + pwm1-pin { + rockchip,pins = <0x00 0x10 0x01 0xb1>; + phandle = <0x7c>; + }; + }; + + pwm2 { + + pwm2-pin { + rockchip,pins = <0x02 0x0d 0x01 0xb1>; + phandle = <0x7d>; + }; + }; + + pwm3 { + + pwm3-pin { + rockchip,pins = <0x00 0x11 0x01 0xb1>; + phandle = <0x7e>; + }; + }; + + pwm4 { + + pwm4-pin { + rockchip,pins = <0x03 0x12 0x03 0xb1>; + phandle = <0x7f>; + }; + }; + + pwm5 { + + pwm5-pin { + rockchip,pins = <0x03 0x13 0x03 0xb1>; + phandle = <0x80>; + }; + }; + + pwm6 { + + pwm6-pin { + rockchip,pins = <0x03 0x14 0x03 0xb1>; + phandle = <0x81>; + }; + }; + + pwm7 { + + pwm7-pin { + rockchip,pins = <0x03 0x15 0x03 0xb1>; + phandle = <0x82>; + }; + }; + + gmac { + + rmii-pins { + rockchip,pins = <0x02 0x00 0x02 0xb8 0x02 0x01 0x02 0xb8 0x02 0x02 0x02 0xb8 0x02 0x03 0x02 0xb1 0x02 0x04 0x02 0xb1 0x02 0x05 0x02 0xb1 0x02 0x06 0x02 0xb1 0x02 0x07 0x02 0xb1 0x02 0x09 0x02 0xb1>; + phandle = <0x8d>; + }; + + mac-refclk-12ma { + rockchip,pins = <0x02 0x0a 0x02 0xb8>; + phandle = <0x8e>; + }; + + mac-refclk { + rockchip,pins = <0x02 0x0a 0x02 0xb1>; + phandle = <0x148>; + }; + }; + + cif-m0 { + + cif-clkout-m0 { + rockchip,pins = <0x02 0x0b 0x01 0xb8>; + phandle = <0xa7>; + }; + + dvp-d2d9-m0 { + rockchip,pins = <0x02 0x00 0x01 0xb1 0x02 0x01 0x01 0xb1 0x02 0x02 0x01 0xb1 0x02 0x03 0x01 0xb1 0x02 0x04 0x01 0xb1 0x02 0x05 0x01 0xb1 0x02 0x06 0x01 0xb1 0x02 0x07 0x01 0xb1 0x02 0x08 0x01 0xb1 0x02 0x09 0x01 0xb1 0x02 0x0a 0x01 0xb1 0x02 0x0b 0x01 0xb1>; + phandle = <0xa5>; + }; + + dvp-d0d1-m0 { + rockchip,pins = <0x02 0x0c 0x01 0xb1 0x02 0x0e 0x01 0xb1>; + phandle = <0xa9>; + }; + + d10-d11-m0 { + rockchip,pins = <0x02 0x0f 0x01 0xb1 0x02 0x10 0x01 0xb1>; + phandle = <0xa8>; + }; + }; + + cif-m1 { + + cif-clkout-m1 { + rockchip,pins = <0x03 0x18 0x03 0xb1>; + phandle = <0x149>; + }; + + dvp-d2d9-m1 { + rockchip,pins = <0x03 0x03 0x03 0xb1 0x03 0x05 0x03 0xb1 0x03 0x07 0x03 0xb1 0x03 0x08 0x03 0xb1 0x03 0x09 0x03 0xb1 0x03 0x0c 0x03 0xb1 0x03 0x0e 0x03 0xb1 0x03 0x0f 0x03 0xb1 0x03 0x19 0x03 0xb1 0x03 0x1a 0x03 0xb1 0x03 0x1b 0x03 0xb1 0x03 0x18 0x03 0xb1>; + phandle = <0x14a>; + }; + + dvp-d0d1-m1 { + rockchip,pins = <0x03 0x01 0x03 0xb1 0x03 0x02 0x03 0xb1>; + phandle = <0x14b>; + }; + + d10-d11-m1 { + rockchip,pins = <0x03 0x16 0x03 0xb1 0x03 0x17 0x03 0xb1>; + phandle = <0x14c>; + }; + }; + + isp { + + isp-prelight { + rockchip,pins = <0x03 0x19 0x04 0xb1>; + phandle = <0x14d>; + }; + }; + + pmic { + + pmic_int { + rockchip,pins = <0x00 0x0a 0x00 0xb2 0x00 0x0b 0x00 0xb1>; + phandle = <0x5d>; + }; + + soc_slppin_gpio { + rockchip,pins = <0x00 0x04 0x00 0xb9>; + phandle = <0x60>; + }; + + soc_slppin_slp { + rockchip,pins = <0x00 0x04 0x01 0xb1>; + phandle = <0x5e>; + }; + + soc_slppin_rst { + rockchip,pins = <0x00 0x04 0x02 0xb1>; + phandle = <0x62>; + }; + }; + + leds { + + led-pins { + rockchip,pins = <0x00 0x11 0x00 0xb1>; + phandle = <0xc0>; + }; + }; + + btns { + + btn-pins { + rockchip,pins = <0x01 0x0c 0x00 0xb2 0x01 0x0d 0x00 0xb2 0x01 0x0e 0x00 0xb2 0x01 0x0f 0x00 0xb2 0x01 0x02 0x00 0xb2 0x01 0x05 0x00 0xb2 0x01 0x06 0x00 0xb2 0x01 0x07 0x00 0xb2 0x02 0x00 0x00 0xb2 0x02 0x01 0x00 0xb2 0x02 0x02 0x00 0xb2 0x02 0x03 0x00 0xb2 0x02 0x04 0x00 0xb2 0x02 0x05 0x00 0xb2 0x02 0x06 0x00 0xb2 0x02 0x07 0x00 0xb2 0x03 0x09 0x00 0xb2 0x03 0x0a 0x00 0xb2 0x03 0x0c 0x00 0xb2 0x03 0x0f 0x00 0xb2>; + phandle = <0xbd>; + }; + }; + }; + + chosen { + bootargs = [00]; + }; + + fiq-debugger { + compatible = "rockchip,fiq-debugger"; + rockchip,serial-id = <0x02>; + rockchip,wake-irq = <0x00>; + rockchip,irq-mode-enable = <0x00>; + rockchip,baudrate = <0x1c200>; + interrupts = <0x00 0x7f 0x08>; + pinctrl-names = "default"; + pinctrl-0 = <0xba>; + status = "okay"; + }; + + ramoops { + compatible = "ramoops"; + record-size = <0x00 0x20000>; + console-size = <0x00 0x80000>; + ftrace-size = <0x00 0x00>; + pmsg-size = <0x00 0x00>; + memory-region = <0xbb>; + }; + + reserved-memory { + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + + drm-logo@00000000 { + compatible = "rockchip,drm-logo"; + reg = <0x00 0x00 0x00 0x00>; + phandle = <0x11>; + }; + + region@110000 { + reg = <0x00 0x110000 0x00 0xf0000>; + reg-names = "ramoops_mem"; + phandle = <0xbb>; + }; + }; + + odroidgo3-keys { + compatible = "gpio-keys"; + #address-cells = <0x01>; + #size-cells = <0x00>; + autorepeat; + phandle = <0x14e>; + + button@0 { + label = "GPIO BTN-VOLUP"; + linux,code = <0x73>; + gpios = <0x66 0x00 0x01>; + }; + + button@1 { + label = "GPIO BTN-VOLDN"; + linux,code = <0x72>; + gpios = <0x66 0x01 0x01>; + }; + }; + + odroidgo3-joypad { + compatible = "odroidgo3-joypad"; + pwms = <0xbc 0x00 0xbebc200 0x00>; + pwm-names = "enable"; + rumble-boost-weak = <0x00>; + rumble-boost-strong = <0x00>; + joypad-name = "GO-Super Gamepad"; + joypad-product = <0x1100>; + joypad-revision = <0x100>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <0xbd>; + pinctrl-1 = <0x7b>; + io-channel-names = "amux_adc"; + io-channels = <0xbe 0x01>; + amux-count = <0x04>; + amux-a-gpios = <0x97 0x0b 0x01>; + amux-b-gpios = <0x97 0x08 0x01>; + amux-en-gpios = <0x97 0x0d 0x01>; + button-adc-scale = <0x02>; + button-adc-deadzone = <0x40>; + button-adc-fuzz = <0x20>; + button-adc-flat = <0x20>; + abs_x-p-tuning = <0xc8>; + abs_x-n-tuning = <0xc8>; + abs_y-p-tuning = <0xc8>; + abs_y-n-tuning = <0xc8>; + abs_rx-p-tuning = <0xc8>; + abs_rx-n-tuning = <0xc8>; + abs_ry-p-tuning = <0xc8>; + abs_ry-n-tuning = <0xc8>; + poll-interval = <0x0a>; + invert-absx; + invert-absy; + phandle = <0x14f>; + + sw1 { + gpios = <0xbf 0x0c 0x01>; + label = "GPIO DPAD-UP"; + linux,code = <0x220>; + }; + + sw2 { + gpios = <0xbf 0x0d 0x01>; + label = "GPIO DPAD-DOWN"; + linux,code = <0x221>; + }; + + sw3 { + gpios = <0xbf 0x0e 0x01>; + label = "GPIO DPAD-LEFT"; + linux,code = <0x222>; + }; + + sw4 { + gpios = <0xbf 0x0f 0x01>; + label = "GPIO DPAD-RIGHT"; + linux,code = <0x223>; + }; + + sw5 { + gpios = <0xbf 0x02 0x01>; + label = "GPIO KEY BTN-A"; + linux,code = <0x131>; + }; + + sw6 { + gpios = <0xbf 0x05 0x01>; + label = "GPIO BTN-B"; + linux,code = <0x130>; + }; + + sw7 { + gpios = <0xbf 0x06 0x01>; + label = "GPIO BTN-Y"; + linux,code = <0x134>; + }; + + sw8 { + gpios = <0xbf 0x07 0x01>; + label = "GPIO BTN-X"; + linux,code = <0x133>; + }; + + sw11 { + gpios = <0x66 0x02 0x01>; + label = "GPIO F3"; + linux,code = <0x2c2>; + }; + + sw12 { + gpios = <0x66 0x03 0x01>; + label = "GPIO F4"; + linux,code = <0x2c3>; + }; + + sw13 { + gpios = <0x66 0x04 0x01>; + label = "GPIO F5"; + linux,code = <0x2c4>; + }; + + sw15 { + gpios = <0x66 0x06 0x01>; + label = "GPIO TOP-LEFT"; + linux,code = <0x136>; + }; + + sw16 { + gpios = <0x66 0x07 0x01>; + label = "GPIO TOP-RIGHT"; + linux,code = <0x137>; + }; + + sw19 { + gpios = <0x97 0x09 0x01>; + label = "GPIO F1"; + linux,code = <0x2c0>; + }; + + sw20 { + gpios = <0x97 0x0f 0x01>; + label = "GPIO TOP-RIGHT2"; + linux,code = <0x139>; + }; + + sw21 { + gpios = <0x97 0x0a 0x01>; + label = "GPIO TOP-LEFT2"; + linux,code = <0x138>; + }; + + sw22 { + gpios = <0x97 0x0c 0x01>; + label = "GPIO F2"; + linux,code = <0x2c1>; + }; + }; + + gpio_leds { + compatible = "gpio-leds"; + pinctrl-names = "led_pins"; + pinctrl-0 = <0xc0>; + phandle = <0x150>; + + heartbeat { + label = "blue:heartbeat"; + gpios = <0x5c 0x11 0x00>; + linux,default-trigger = "heartbeat"; + }; + }; + + backlight { + compatible = "pwm-backlight"; + pwms = <0xc1 0x00 0x9c40 0x00>; + brightness-levels = <0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2a 0x2b 0x2c 0x2d 0x2e 0x2f 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x3a 0x3b 0x3c 0x3d 0x3e 0x3f 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48 0x49 0x4a 0x4b 0x4c 0x4d 0x4e 0x4f 0x50 0x51 0x52 0x53 0x54 0x55 0x56 0x57 0x58 0x59 0x5a 0x5b 0x5c 0x5d 0x5e 0x5f 0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69 0x6a 0x6b 0x6c 0x6d 0x6e 0x6f 0x70 0x71 0x72 0x73 0x74 0x75 0x76 0x77 0x78 0x79 0x7a 0x7b 0x7c 0x7d 0x7e 0x7f 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90 0x91 0x92 0x93 0x94 0x95 0x96 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f 0xa0>; + default-brightness-level = <0x50>; + phandle = <0x9d>; + }; + + rk817-sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,name = "rockchip,rk817-codec"; + simple-audio-card,mclk-fs = <0x100>; + simple-audio-card,widgets = "Microphone\0Mic Jack\0Headphone\0Headphone Jack"; + simple-audio-card,routing = "MIC_IN\0Mic Jack\0Headphone Jack\0HPOL\0Headphone Jack\0HPOR"; + simple-audio-card,hp-det-gpio = <0x66 0x16 0x01>; + simple-audio-card,codec-hp-det = <0x01>; + + simple-audio-card,cpu { + sound-dai = <0xc2>; + }; + + simple-audio-card,codec { + sound-dai = <0xc3>; + }; + }; + + vccsys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v8_sys"; + regulator-always-on; + regulator-min-microvolt = <0x39fbc0>; + regulator-max-microvolt = <0x39fbc0>; + phandle = <0x64>; + }; + + __symbols__ { + ddr_timing = "/ddr_timing"; + cpu0 = "/cpus/cpu@0"; + cpu1 = "/cpus/cpu@1"; + cpu2 = "/cpus/cpu@2"; + cpu3 = "/cpus/cpu@3"; + CPU_SLEEP = "/cpus/idle-states/cpu-sleep"; + CLUSTER_SLEEP = "/cpus/idle-states/cluster-sleep"; + cpu0_opp_table = "/cpu0-opp-table"; + bus_soc = "/bus-soc"; + bus_apll = "/bus-apll"; + bus_apll_opp_table = "/bus-apll-opp-table"; + display_subsystem = "/display-subsystem"; + route_lvds = "/display-subsystem/route/route-lvds"; + route_dsi = "/display-subsystem/route/route-dsi"; + route_rgb = "/display-subsystem/route/route-rgb"; + gmac_clkin = "/external-gmac-clock"; + rockchip_suspend = "/rockchip-suspend"; + xin24m = "/xin24m"; + xin32k = "/xin32k"; + pmu = "/power-management@ff000000"; + power = "/power-management@ff000000/power-controller"; + pmugrf = "/syscon@ff010000"; + pmu_io_domains = "/syscon@ff010000/io-domains"; + pmu_pvtm = "/syscon@ff010000/pmu-pvtm"; + uart0 = "/serial@ff030000"; + i2s0_8ch = "/i2s@ff060000"; + i2s1_2ch = "/i2s@ff070000"; + i2s2_2ch = "/i2s@ff080000"; + pdm = "/pdm@ff0a0000"; + crypto = "/crypto@ff0b0000"; + rng = "/rng@ff0b0000"; + gic = "/interrupt-controller@ff131000"; + grf = "/syscon@ff140000"; + io_domains = "/syscon@ff140000/io-domains"; + lvds = "/syscon@ff140000/lvds"; + lvds_in_vopb = "/syscon@ff140000/lvds/ports/port@0/endpoint@0"; + rgb = "/syscon@ff140000/rgb"; + rgb_in_vopb = "/syscon@ff140000/rgb/ports/port@0/endpoint@0"; + core_grf = "/syscon@ff148000"; + pvtm = "/syscon@ff148000/pvtm"; + uart1 = "/serial@ff158000"; + uart2 = "/serial@ff160000"; + uart3 = "/serial@ff168000"; + uart4 = "/serial@ff170000"; + uart5 = "/serial@ff178000"; + i2c0 = "/i2c@ff180000"; + rk817 = "/i2c@ff180000/pmic@20"; + pinctrl_rk8xx = "/i2c@ff180000/pmic@20/pinctrl_rk8xx"; + rk817_ts_gpio1 = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_ts_gpio1"; + rk817_gt_gpio2 = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_gt_gpio2"; + rk817_pin_ts = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_pin_ts"; + rk817_pin_gt = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_pin_gt"; + rk817_slppin_null = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_null"; + rk817_slppin_slp = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_slp"; + rk817_slppin_pwrdn = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_pwrdn"; + rk817_slppin_rst = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_rst"; + vdd_logic = "/i2c@ff180000/pmic@20/regulators/DCDC_REG1"; + vdd_arm = "/i2c@ff180000/pmic@20/regulators/DCDC_REG2"; + vcc_ddr = "/i2c@ff180000/pmic@20/regulators/DCDC_REG3"; + vcc_3v3 = "/i2c@ff180000/pmic@20/regulators/DCDC_REG4"; + vcc_1v0 = "/i2c@ff180000/pmic@20/regulators/LDO_REG1"; + vcc1v8_soc = "/i2c@ff180000/pmic@20/regulators/LDO_REG2"; + vdd1v0_soc = "/i2c@ff180000/pmic@20/regulators/LDO_REG3"; + vcc3v3_pmu = "/i2c@ff180000/pmic@20/regulators/LDO_REG4"; + vccio_sd = "/i2c@ff180000/pmic@20/regulators/LDO_REG5"; + vcc_sd = "/i2c@ff180000/pmic@20/regulators/LDO_REG6"; + vcc_backlight = "/i2c@ff180000/pmic@20/regulators/LDO_REG7"; + vcc_lcd = "/i2c@ff180000/pmic@20/regulators/LDO_REG8"; + dcdc_boost = "/i2c@ff180000/pmic@20/regulators/BOOST"; + otg_switch = "/i2c@ff180000/pmic@20/regulators/OTG_SWITCH"; + rk817_codec = "/i2c@ff180000/pmic@20/codec"; + i2c1 = "/i2c@ff190000"; + i2c2 = "/i2c@ff1a0000"; + i2c3 = "/i2c@ff1b0000"; + spi0 = "/spi@ff1d0000"; + spi1 = "/spi@ff1d8000"; + wdt = "/watchdog@ff1e0000"; + pwm0 = "/pwm@ff200000"; + pwm1 = "/pwm@ff200010"; + pwm2 = "/pwm@ff200020"; + pwm3 = "/pwm@ff200030"; + pwm4 = "/pwm@ff208000"; + pwm5 = "/pwm@ff208010"; + pwm6 = "/pwm@ff208020"; + pwm7 = "/pwm@ff208030"; + rktimer = "/rktimer@ff210000"; + dmac = "/amba/dmac@ff240000"; + thermal_zones = "/thermal-zones"; + soc_thermal = "/thermal-zones/soc-thermal"; + threshold = "/thermal-zones/soc-thermal/trips/trip-point-0"; + target = "/thermal-zones/soc-thermal/trips/trip-point-1"; + soc_crit = "/thermal-zones/soc-thermal/trips/soc-crit"; + gpu_thermal = "/thermal-zones/gpu-thermal"; + tsadc = "/tsadc@ff280000"; + saradc = "/saradc@ff288000"; + otp = "/otp@ff290000"; + otp_id = "/otp@ff290000/id@7"; + cpu_leakage = "/otp@ff290000/cpu-leakage@17"; + performance = "/otp@ff290000/performance@1e"; + cru = "/clock-controller@ff2b0000"; + cpu_boost = "/cpu-boost@ff2b8000"; + pmucru = "/pmu-clock-controller@ff2bc000"; + usb2phy_grf = "/syscon@ff2c0000"; + u2phy = "/syscon@ff2c0000/usb2-phy@100"; + u2phy_host = "/syscon@ff2c0000/usb2-phy@100/host-port"; + u2phy_otg = "/syscon@ff2c0000/usb2-phy@100/otg-port"; + video_phy = "/video-phy@ff2e0000"; + mipi_dphy_rx0 = "/mipi-dphy-rx0@ff2f0000"; + usb20_otg = "/usb@ff300000"; + usb_host0_ehci = "/usb@ff340000"; + usb_host0_ohci = "/usb@ff350000"; + gmac = "/ethernet@ff360000"; + sdmmc = "/dwmmc@ff370000"; + sdio = "/dwmmc@ff380000"; + emmc = "/dwmmc@ff390000"; + nandc0 = "/nandc@ff3b0000"; + sfc = "/sfc@ff3a0000"; + gpu = "/gpu@ff400000"; + gpu_opp_table = "/gpu-opp-table"; + hevc = "/hevc_service@ff440000"; + vpu = "/vpu_service@ff442000"; + vpu_combo = "/vpu_combo"; + hevc_mmu = "/iommu@ff440440"; + vpu_mmu = "/iommu@ff442800"; + dsi = "/dsi@ff450000"; + dsi_in_vopb = "/dsi@ff450000/ports/port@0/endpoint@0"; + timing0 = "/dsi@ff450000/panel@0/display-timings/60Hz"; + timing1 = "/dsi@ff450000/panel@0/display-timings/50Hz"; + timing2 = "/dsi@ff450000/panel@0/display-timings/75Hz"; + vopb = "/vop@ff460000"; + vopb_out = "/vop@ff460000/port"; + vopb_out_lvds = "/vop@ff460000/port/endpoint@0"; + vopb_out_dsi = "/vop@ff460000/port/endpoint@1"; + vopb_out_rgb = "/vop@ff460000/port/endpoint@2"; + vopb_mmu = "/iommu@ff460f00"; + rk_rga = "/rk_rga@ff480000"; + cif = "/cif@ff490000"; + cif_new = "/cif-new@ff490000"; + vip_mmu = "/iommu@ff490800"; + rk_isp = "/rk_isp@ff4a0000"; + rkisp1 = "/rkisp1@ff4a0000"; + isp_mmu = "/iommu@ff4a8000"; + qos_gmac = "/qos@ff518000"; + qos_gpu = "/qos@ff520000"; + qos_sdmmc = "/qos@ff52c000"; + qos_emmc = "/qos@ff538000"; + qos_nand = "/qos@ff538080"; + qos_sdio = "/qos@ff538100"; + qos_sfc = "/qos@ff538180"; + qos_usb_host = "/qos@ff540000"; + qos_usb_otg = "/qos@ff540080"; + qos_isp_128 = "/qos@ff548000"; + qos_isp_rd = "/qos@ff548080"; + qos_isp_wr = "/qos@ff548100"; + qos_isp_m1 = "/qos@ff548180"; + qos_vip = "/qos@ff548200"; + qos_rga_rd = "/qos@ff550000"; + qos_rga_wr = "/qos@ff550080"; + qos_vop_m0 = "/qos@ff550100"; + qos_vop_m1 = "/qos@ff550180"; + qos_vpu = "/qos@ff558000"; + qos_vpu_r128 = "/qos@ff558080"; + dfi = "/dfi@ff610000"; + dmc = "/dmc"; + ddr_power_model = "/dmc/ddr_power_model"; + dmc_opp_table = "/dmc-opp-table"; + rockchip_system_monitor = "/rockchip-system-monitor"; + pinctrl = "/pinctrl"; + gpio0 = "/pinctrl/gpio0@ff040000"; + gpio1 = "/pinctrl/gpio1@ff250000"; + gpio2 = "/pinctrl/gpio2@ff260000"; + gpio3 = "/pinctrl/gpio3@ff270000"; + pcfg_pull_up = "/pinctrl/pcfg-pull-up"; + pcfg_pull_down = "/pinctrl/pcfg-pull-down"; + pcfg_pull_none = "/pinctrl/pcfg-pull-none"; + pcfg_pull_none_2ma = "/pinctrl/pcfg-pull-none-2ma"; + pcfg_pull_up_2ma = "/pinctrl/pcfg-pull-up-2ma"; + pcfg_pull_up_4ma = "/pinctrl/pcfg-pull-up-4ma"; + pcfg_pull_none_4ma = "/pinctrl/pcfg-pull-none-4ma"; + pcfg_pull_down_4ma = "/pinctrl/pcfg-pull-down-4ma"; + pcfg_pull_none_8ma = "/pinctrl/pcfg-pull-none-8ma"; + pcfg_pull_up_8ma = "/pinctrl/pcfg-pull-up-8ma"; + pcfg_pull_none_12ma = "/pinctrl/pcfg-pull-none-12ma"; + pcfg_pull_up_12ma = "/pinctrl/pcfg-pull-up-12ma"; + pcfg_pull_none_smt = "/pinctrl/pcfg-pull-none-smt"; + pcfg_output_high = "/pinctrl/pcfg-output-high"; + pcfg_output_low = "/pinctrl/pcfg-output-low"; + pcfg_input_high = "/pinctrl/pcfg-input-high"; + pcfg_input = "/pinctrl/pcfg-input"; + i2c0_xfer = "/pinctrl/i2c0/i2c0-xfer"; + i2c1_xfer = "/pinctrl/i2c1/i2c1-xfer"; + i2c2_xfer = "/pinctrl/i2c2/i2c2-xfer"; + i2c3_xfer = "/pinctrl/i2c3/i2c3-xfer"; + tsadc_otp_gpio = "/pinctrl/tsadc/tsadc-otp-gpio"; + tsadc_otp_out = "/pinctrl/tsadc/tsadc-otp-out"; + uart0_xfer = "/pinctrl/uart0/uart0-xfer"; + uart0_cts = "/pinctrl/uart0/uart0-cts"; + uart0_rts = "/pinctrl/uart0/uart0-rts"; + uart0_rts_gpio = "/pinctrl/uart0/uart0-rts-gpio"; + uart1_xfer = "/pinctrl/uart1/uart1-xfer"; + uart1_cts = "/pinctrl/uart1/uart1-cts"; + uart1_rts = "/pinctrl/uart1/uart1-rts"; + uart1_rts_gpio = "/pinctrl/uart1/uart1-rts-gpio"; + uart2m0_xfer = "/pinctrl/uart2-m0/uart2m0-xfer"; + uart2m1_xfer = "/pinctrl/uart2-m1/uart2m1-xfer"; + uart3m0_xfer = "/pinctrl/uart3-m0/uart3m0-xfer"; + uart3m0_cts = "/pinctrl/uart3-m0/uart3m0-cts"; + uart3m0_rts = "/pinctrl/uart3-m0/uart3m0-rts"; + uart3m0_rts_gpio = "/pinctrl/uart3-m0/uart3m0-rts-gpio"; + uart3m1_xfer = "/pinctrl/uart3-m1/uart3m1-xfer"; + uart3m1_cts = "/pinctrl/uart3-m1/uart3m1-cts"; + uart3m1_rts = "/pinctrl/uart3-m1/uart3m1-rts"; + uart3m1_rts_gpio = "/pinctrl/uart3-m1/uart3m1-rts-gpio"; + uart4_xfer = "/pinctrl/uart4/uart4-xfer"; + uart4_cts = "/pinctrl/uart4/uart4-cts"; + uart4_rts = "/pinctrl/uart4/uart4-rts"; + uart5_xfer = "/pinctrl/uart5/uart5-xfer"; + uart5_cts = "/pinctrl/uart5/uart5-cts"; + uart5_rts = "/pinctrl/uart5/uart5-rts"; + spi0_clk = "/pinctrl/spi0/spi0-clk"; + spi0_csn = "/pinctrl/spi0/spi0-csn"; + spi0_miso = "/pinctrl/spi0/spi0-miso"; + spi0_mosi = "/pinctrl/spi0/spi0-mosi"; + spi0_clk_hs = "/pinctrl/spi0/spi0-clk-hs"; + spi0_miso_hs = "/pinctrl/spi0/spi0-miso-hs"; + spi0_mosi_hs = "/pinctrl/spi0/spi0-mosi-hs"; + spi1_clk = "/pinctrl/spi1/spi1-clk"; + spi1_csn0 = "/pinctrl/spi1/spi1-csn0"; + spi1_csn1 = "/pinctrl/spi1/spi1-csn1"; + spi1_miso = "/pinctrl/spi1/spi1-miso"; + spi1_mosi = "/pinctrl/spi1/spi1-mosi"; + spi1_clk_hs = "/pinctrl/spi1/spi1-clk-hs"; + spi1_miso_hs = "/pinctrl/spi1/spi1-miso-hs"; + spi1_mosi_hs = "/pinctrl/spi1/spi1-mosi-hs"; + pdm_clk0m0 = "/pinctrl/pdm/pdm-clk0m0"; + pdm_clk0m1 = "/pinctrl/pdm/pdm-clk0m1"; + pdm_clk1 = "/pinctrl/pdm/pdm-clk1"; + pdm_sdi0m0 = "/pinctrl/pdm/pdm-sdi0m0"; + pdm_sdi0m1 = "/pinctrl/pdm/pdm-sdi0m1"; + pdm_sdi1 = "/pinctrl/pdm/pdm-sdi1"; + pdm_sdi2 = "/pinctrl/pdm/pdm-sdi2"; + pdm_sdi3 = "/pinctrl/pdm/pdm-sdi3"; + pdm_clk0m0_sleep = "/pinctrl/pdm/pdm-clk0m0-sleep"; + pdm_clk0m_sleep1 = "/pinctrl/pdm/pdm-clk0m1-sleep"; + pdm_clk1_sleep = "/pinctrl/pdm/pdm-clk1-sleep"; + pdm_sdi0m0_sleep = "/pinctrl/pdm/pdm-sdi0m0-sleep"; + pdm_sdi0m1_sleep = "/pinctrl/pdm/pdm-sdi0m1-sleep"; + pdm_sdi1_sleep = "/pinctrl/pdm/pdm-sdi1-sleep"; + pdm_sdi2_sleep = "/pinctrl/pdm/pdm-sdi2-sleep"; + pdm_sdi3_sleep = "/pinctrl/pdm/pdm-sdi3-sleep"; + i2s0_8ch_mclk = "/pinctrl/i2s0/i2s0-8ch-mclk"; + i2s0_8ch_sclktx = "/pinctrl/i2s0/i2s0-8ch-sclktx"; + i2s0_8ch_sclkrx = "/pinctrl/i2s0/i2s0-8ch-sclkrx"; + i2s0_8ch_lrcktx = "/pinctrl/i2s0/i2s0-8ch-lrcktx"; + i2s0_8ch_lrckrx = "/pinctrl/i2s0/i2s0-8ch-lrckrx"; + i2s0_8ch_sdo0 = "/pinctrl/i2s0/i2s0-8ch-sdo0"; + i2s0_8ch_sdo1 = "/pinctrl/i2s0/i2s0-8ch-sdo1"; + i2s0_8ch_sdo2 = "/pinctrl/i2s0/i2s0-8ch-sdo2"; + i2s0_8ch_sdo3 = "/pinctrl/i2s0/i2s0-8ch-sdo3"; + i2s0_8ch_sdi0 = "/pinctrl/i2s0/i2s0-8ch-sdi0"; + i2s0_8ch_sdi1 = "/pinctrl/i2s0/i2s0-8ch-sdi1"; + i2s0_8ch_sdi2 = "/pinctrl/i2s0/i2s0-8ch-sdi2"; + i2s0_8ch_sdi3 = "/pinctrl/i2s0/i2s0-8ch-sdi3"; + i2s1_2ch_mclk = "/pinctrl/i2s1/i2s1-2ch-mclk"; + i2s1_2ch_sclk = "/pinctrl/i2s1/i2s1-2ch-sclk"; + i2s1_2ch_lrck = "/pinctrl/i2s1/i2s1-2ch-lrck"; + i2s1_2ch_sdi = "/pinctrl/i2s1/i2s1-2ch-sdi"; + i2s1_2ch_sdo = "/pinctrl/i2s1/i2s1-2ch-sdo"; + i2s2_2ch_mclk = "/pinctrl/i2s2/i2s2-2ch-mclk"; + i2s2_2ch_sclk = "/pinctrl/i2s2/i2s2-2ch-sclk"; + i2s2_2ch_lrck = "/pinctrl/i2s2/i2s2-2ch-lrck"; + i2s2_2ch_sdi = "/pinctrl/i2s2/i2s2-2ch-sdi"; + i2s2_2ch_sdo = "/pinctrl/i2s2/i2s2-2ch-sdo"; + sdmmc_clk = "/pinctrl/sdmmc/sdmmc-clk"; + sdmmc_cmd = "/pinctrl/sdmmc/sdmmc-cmd"; + sdmmc_det = "/pinctrl/sdmmc/sdmmc-det"; + sdmmc_bus1 = "/pinctrl/sdmmc/sdmmc-bus1"; + sdmmc_bus4 = "/pinctrl/sdmmc/sdmmc-bus4"; + sdmmc_gpio = "/pinctrl/sdmmc/sdmmc-gpio"; + sdio_clk = "/pinctrl/sdio/sdio-clk"; + sdio_cmd = "/pinctrl/sdio/sdio-cmd"; + sdio_bus4 = "/pinctrl/sdio/sdio-bus4"; + sdio_gpio = "/pinctrl/sdio/sdio-gpio"; + emmc_clk = "/pinctrl/emmc/emmc-clk"; + emmc_cmd = "/pinctrl/emmc/emmc-cmd"; + emmc_pwren = "/pinctrl/emmc/emmc-pwren"; + emmc_rstnout = "/pinctrl/emmc/emmc-rstnout"; + emmc_bus1 = "/pinctrl/emmc/emmc-bus1"; + emmc_bus4 = "/pinctrl/emmc/emmc-bus4"; + emmc_bus8 = "/pinctrl/emmc/emmc-bus8"; + flash_cs0 = "/pinctrl/flash/flash-cs0"; + flash_rdy = "/pinctrl/flash/flash-rdy"; + flash_dqs = "/pinctrl/flash/flash-dqs"; + flash_ale = "/pinctrl/flash/flash-ale"; + flash_cle = "/pinctrl/flash/flash-cle"; + flash_wrn = "/pinctrl/flash/flash-wrn"; + flash_csl = "/pinctrl/flash/flash-csl"; + flash_rdn = "/pinctrl/flash/flash-rdn"; + flash_bus8 = "/pinctrl/flash/flash-bus8"; + lcdc_m0_rgb_pins = "/pinctrl/lcdc/lcdc-m0-rgb-pins"; + lcdc_m0_sleep_pins = "/pinctrl/lcdc/lcdc-m0-sleep-pins"; + lcdc_m1_rgb_pins = "/pinctrl/lcdc/lcdc-m1-rgb-pins"; + lcdc_m1_sleep_pins = "/pinctrl/lcdc/lcdc-m1-sleep-pins"; + pwm0_pin = "/pinctrl/pwm0/pwm0-pin"; + pwm1_pin = "/pinctrl/pwm1/pwm1-pin"; + pwm2_pin = "/pinctrl/pwm2/pwm2-pin"; + pwm3_pin = "/pinctrl/pwm3/pwm3-pin"; + pwm4_pin = "/pinctrl/pwm4/pwm4-pin"; + pwm5_pin = "/pinctrl/pwm5/pwm5-pin"; + pwm6_pin = "/pinctrl/pwm6/pwm6-pin"; + pwm7_pin = "/pinctrl/pwm7/pwm7-pin"; + rmii_pins = "/pinctrl/gmac/rmii-pins"; + mac_refclk_12ma = "/pinctrl/gmac/mac-refclk-12ma"; + mac_refclk = "/pinctrl/gmac/mac-refclk"; + cif_clkout_m0 = "/pinctrl/cif-m0/cif-clkout-m0"; + dvp_d2d9_m0 = "/pinctrl/cif-m0/dvp-d2d9-m0"; + dvp_d0d1_m0 = "/pinctrl/cif-m0/dvp-d0d1-m0"; + dvp_d10d11_m0 = "/pinctrl/cif-m0/d10-d11-m0"; + cif_clkout_m1 = "/pinctrl/cif-m1/cif-clkout-m1"; + dvp_d2d9_m1 = "/pinctrl/cif-m1/dvp-d2d9-m1"; + dvp_d0d1_m1 = "/pinctrl/cif-m1/dvp-d0d1-m1"; + dvp_d10d11_m1 = "/pinctrl/cif-m1/d10-d11-m1"; + isp_prelight = "/pinctrl/isp/isp-prelight"; + pmic_int = "/pinctrl/pmic/pmic_int"; + soc_slppin_gpio = "/pinctrl/pmic/soc_slppin_gpio"; + soc_slppin_slp = "/pinctrl/pmic/soc_slppin_slp"; + soc_slppin_rst = "/pinctrl/pmic/soc_slppin_rst"; + led_pins = "/pinctrl/leds/led-pins"; + btn_pins = "/pinctrl/btns/btn-pins"; + drm_logo = "/reserved-memory/drm-logo@00000000"; + ramoops_mem = "/reserved-memory/region@110000"; + gpio_keys = "/odroidgo3-keys"; + joypad = "/odroidgo3-joypad"; + leds = "/gpio_leds"; + backlight = "/backlight"; + vccsys = "/vccsys"; + }; +}; diff --git a/config/archr-dts/R36S-DTB/DTS/Panel1.dts b/config/archr-dts/R36S-DTB/DTS/Panel1.dts new file mode 100644 index 0000000000..f72f03b8d7 --- /dev/null +++ b/config/archr-dts/R36S-DTB/DTS/Panel1.dts @@ -0,0 +1,4063 @@ +/dts-v1/; + +/ { + compatible = "rockchip,rk3326-odroidgo3-linux\0rockchip,rk3326"; + interrupt-parent = <0x01>; + #address-cells = <0x02>; + #size-cells = <0x02>; + model = "Game Console R35S/R36S fix by AeolusUX"; + + ddr_timing { + compatible = "rockchip,ddr-timing"; + ddr2_speed_bin = <0x00>; + ddr3_speed_bin = <0x15>; + ddr4_speed_bin = <0x0c>; + pd_idle = <0x0d>; + sr_idle = <0x5d>; + sr_mc_gate_idle = <0x00>; + srpd_lite_idle = <0x00>; + standby_idle = <0x00>; + auto_pd_dis_freq = <0x42a>; + auto_sr_dis_freq = <0x320>; + ddr2_dll_dis_freq = <0x12c>; + ddr3_dll_dis_freq = <0x12c>; + ddr4_dll_dis_freq = <0x271>; + phy_dll_dis_freq = <0x190>; + ddr2_odt_dis_freq = <0x64>; + phy_ddr2_odt_dis_freq = <0x64>; + ddr2_drv = <0x01>; + ddr2_odt = <0x96>; + phy_ddr2_ca_drv = <0x15>; + phy_ddr2_ck_drv = <0x12>; + phy_ddr2_dq_drv = <0x15>; + phy_ddr2_odt = <0x02>; + ddr3_odt_dis_freq = <0x190>; + phy_ddr3_odt_dis_freq = <0x190>; + ddr3_drv = <0x28>; + ddr3_odt = <0x78>; + phy_ddr3_ca_drv = <0x15>; + phy_ddr3_ck_drv = <0x12>; + phy_ddr3_dq_drv = <0x15>; + phy_ddr3_odt = <0x02>; + phy_lpddr2_odt_dis_freq = <0x29a>; + lpddr2_drv = <0x28>; + phy_lpddr2_ca_drv = <0x16>; + phy_lpddr2_ck_drv = <0x13>; + phy_lpddr2_dq_drv = <0x16>; + phy_lpddr2_odt = <0x00>; + lpddr3_odt_dis_freq = <0x190>; + phy_lpddr3_odt_dis_freq = <0x190>; + lpddr3_drv = <0x28>; + lpddr3_odt = <0xf0>; + phy_lpddr3_ca_drv = <0x16>; + phy_lpddr3_ck_drv = <0x13>; + phy_lpddr3_dq_drv = <0x16>; + phy_lpddr3_odt = <0x02>; + lpddr4_odt_dis_freq = <0x320>; + phy_lpddr4_odt_dis_freq = <0x320>; + lpddr4_drv = <0x3c>; + lpddr4_dq_odt = <0x28>; + lpddr4_ca_odt = <0x28>; + phy_lpddr4_ca_drv = <0x14>; + phy_lpddr4_ck_cs_drv = <0x06>; + phy_lpddr4_dq_drv = <0x06>; + phy_lpddr4_odt = <0x10>; + ddr4_odt_dis_freq = <0x29a>; + phy_ddr4_odt_dis_freq = <0x29a>; + ddr4_drv = <0x22>; + ddr4_odt = <0xf0>; + phy_ddr4_ca_drv = <0x16>; + phy_ddr4_ck_drv = <0x13>; + phy_ddr4_dq_drv = <0x16>; + phy_ddr4_odt = <0x02>; + ddr3a1_ddr4a9_de-skew = <0x06>; + ddr3a0_ddr4a10_de-skew = <0x07>; + ddr3a3_ddr4a6_de-skew = <0x07>; + ddr3a2_ddr4a4_de-skew = <0x07>; + ddr3a5_ddr4a8_de-skew = <0x07>; + ddr3a4_ddr4a5_de-skew = <0x07>; + ddr3a7_ddr4a11_de-skew = <0x07>; + ddr3a6_ddr4a7_de-skew = <0x06>; + ddr3a9_ddr4a0_de-skew = <0x07>; + ddr3a8_ddr4a13_de-skew = <0x07>; + ddr3a11_ddr4a3_de-skew = <0x07>; + ddr3a10_ddr4cs0_de-skew = <0x07>; + ddr3a13_ddr4a2_de-skew = <0x07>; + ddr3a12_ddr4ba1_de-skew = <0x07>; + ddr3a15_ddr4odt0_de-skew = <0x07>; + ddr3a14_ddr4a1_de-skew = <0x07>; + ddr3ba1_ddr4a15_de-skew = <0x07>; + ddr3ba0_ddr4bg0_de-skew = <0x07>; + ddr3ras_ddr4cke_de-skew = <0x07>; + ddr3ba2_ddr4ba0_de-skew = <0x07>; + ddr3we_ddr4bg1_de-skew = <0x07>; + ddr3cas_ddr4a12_de-skew = <0x07>; + ddr3ckn_ddr4ckn_de-skew = <0x07>; + ddr3ckp_ddr4ckp_de-skew = <0x07>; + ddr3cke_ddr4a16_de-skew = <0x07>; + ddr3odt0_ddr4a14_de-skew = <0x07>; + ddr3cs0_ddr4act_de-skew = <0x06>; + ddr3reset_ddr4reset_de-skew = <0x07>; + ddr3cs1_ddr4cs1_de-skew = <0x06>; + ddr3odt1_ddr4odt1_de-skew = <0x07>; + cs0_dm0_rx_de-skew = <0x07>; + cs0_dm0_tx_de-skew = <0x07>; + cs0_dq0_rx_de-skew = <0x08>; + cs0_dq0_tx_de-skew = <0x08>; + cs0_dq1_rx_de-skew = <0x09>; + cs0_dq1_tx_de-skew = <0x08>; + cs0_dq2_rx_de-skew = <0x08>; + cs0_dq2_tx_de-skew = <0x08>; + cs0_dq3_rx_de-skew = <0x08>; + cs0_dq3_tx_de-skew = <0x08>; + cs0_dq4_rx_de-skew = <0x09>; + cs0_dq4_tx_de-skew = <0x08>; + cs0_dq5_rx_de-skew = <0x09>; + cs0_dq5_tx_de-skew = <0x08>; + cs0_dq6_rx_de-skew = <0x09>; + cs0_dq6_tx_de-skew = <0x08>; + cs0_dq7_rx_de-skew = <0x08>; + cs0_dq7_tx_de-skew = <0x08>; + cs0_dqs0_rx_de-skew = <0x06>; + cs0_dqs0p_tx_de-skew = <0x09>; + cs0_dqs0n_tx_de-skew = <0x09>; + cs0_dm1_rx_de-skew = <0x07>; + cs0_dm1_tx_de-skew = <0x06>; + cs0_dq8_rx_de-skew = <0x08>; + cs0_dq8_tx_de-skew = <0x07>; + cs0_dq9_rx_de-skew = <0x09>; + cs0_dq9_tx_de-skew = <0x07>; + cs0_dq10_rx_de-skew = <0x08>; + cs0_dq10_tx_de-skew = <0x08>; + cs0_dq11_rx_de-skew = <0x08>; + cs0_dq11_tx_de-skew = <0x07>; + cs0_dq12_rx_de-skew = <0x08>; + cs0_dq12_tx_de-skew = <0x08>; + cs0_dq13_rx_de-skew = <0x09>; + cs0_dq13_tx_de-skew = <0x07>; + cs0_dq14_rx_de-skew = <0x09>; + cs0_dq14_tx_de-skew = <0x08>; + cs0_dq15_rx_de-skew = <0x09>; + cs0_dq15_tx_de-skew = <0x07>; + cs0_dqs1_rx_de-skew = <0x07>; + cs0_dqs1p_tx_de-skew = <0x09>; + cs0_dqs1n_tx_de-skew = <0x09>; + cs0_dm2_rx_de-skew = <0x07>; + cs0_dm2_tx_de-skew = <0x07>; + cs0_dq16_rx_de-skew = <0x09>; + cs0_dq16_tx_de-skew = <0x09>; + cs0_dq17_rx_de-skew = <0x07>; + cs0_dq17_tx_de-skew = <0x09>; + cs0_dq18_rx_de-skew = <0x07>; + cs0_dq18_tx_de-skew = <0x08>; + cs0_dq19_rx_de-skew = <0x07>; + cs0_dq19_tx_de-skew = <0x09>; + cs0_dq20_rx_de-skew = <0x09>; + cs0_dq20_tx_de-skew = <0x09>; + cs0_dq21_rx_de-skew = <0x09>; + cs0_dq21_tx_de-skew = <0x09>; + cs0_dq22_rx_de-skew = <0x08>; + cs0_dq22_tx_de-skew = <0x09>; + cs0_dq23_rx_de-skew = <0x08>; + cs0_dq23_tx_de-skew = <0x09>; + cs0_dqs2_rx_de-skew = <0x06>; + cs0_dqs2p_tx_de-skew = <0x09>; + cs0_dqs2n_tx_de-skew = <0x09>; + cs0_dm3_rx_de-skew = <0x07>; + cs0_dm3_tx_de-skew = <0x07>; + cs0_dq24_rx_de-skew = <0x08>; + cs0_dq24_tx_de-skew = <0x08>; + cs0_dq25_rx_de-skew = <0x09>; + cs0_dq25_tx_de-skew = <0x09>; + cs0_dq26_rx_de-skew = <0x09>; + cs0_dq26_tx_de-skew = <0x08>; + cs0_dq27_rx_de-skew = <0x09>; + cs0_dq27_tx_de-skew = <0x08>; + cs0_dq28_rx_de-skew = <0x09>; + cs0_dq28_tx_de-skew = <0x09>; + cs0_dq29_rx_de-skew = <0x09>; + cs0_dq29_tx_de-skew = <0x09>; + cs0_dq30_rx_de-skew = <0x08>; + cs0_dq30_tx_de-skew = <0x08>; + cs0_dq31_rx_de-skew = <0x08>; + cs0_dq31_tx_de-skew = <0x08>; + cs0_dqs3_rx_de-skew = <0x07>; + cs0_dqs3p_tx_de-skew = <0x09>; + cs0_dqs3n_tx_de-skew = <0x09>; + cs1_dm0_rx_de-skew = <0x07>; + cs1_dm0_tx_de-skew = <0x07>; + cs1_dq0_rx_de-skew = <0x08>; + cs1_dq0_tx_de-skew = <0x08>; + cs1_dq1_rx_de-skew = <0x09>; + cs1_dq1_tx_de-skew = <0x08>; + cs1_dq2_rx_de-skew = <0x08>; + cs1_dq2_tx_de-skew = <0x08>; + cs1_dq3_rx_de-skew = <0x08>; + cs1_dq3_tx_de-skew = <0x08>; + cs1_dq4_rx_de-skew = <0x08>; + cs1_dq4_tx_de-skew = <0x08>; + cs1_dq5_rx_de-skew = <0x09>; + cs1_dq5_tx_de-skew = <0x08>; + cs1_dq6_rx_de-skew = <0x09>; + cs1_dq6_tx_de-skew = <0x08>; + cs1_dq7_rx_de-skew = <0x08>; + cs1_dq7_tx_de-skew = <0x08>; + cs1_dqs0_rx_de-skew = <0x06>; + cs1_dqs0p_tx_de-skew = <0x09>; + cs1_dqs0n_tx_de-skew = <0x09>; + cs1_dm1_rx_de-skew = <0x07>; + cs1_dm1_tx_de-skew = <0x07>; + cs1_dq8_rx_de-skew = <0x08>; + cs1_dq8_tx_de-skew = <0x08>; + cs1_dq9_rx_de-skew = <0x08>; + cs1_dq9_tx_de-skew = <0x07>; + cs1_dq10_rx_de-skew = <0x07>; + cs1_dq10_tx_de-skew = <0x08>; + cs1_dq11_rx_de-skew = <0x08>; + cs1_dq11_tx_de-skew = <0x08>; + cs1_dq12_rx_de-skew = <0x08>; + cs1_dq12_tx_de-skew = <0x07>; + cs1_dq13_rx_de-skew = <0x08>; + cs1_dq13_tx_de-skew = <0x08>; + cs1_dq14_rx_de-skew = <0x08>; + cs1_dq14_tx_de-skew = <0x08>; + cs1_dq15_rx_de-skew = <0x08>; + cs1_dq15_tx_de-skew = <0x07>; + cs1_dqs1_rx_de-skew = <0x07>; + cs1_dqs1p_tx_de-skew = <0x09>; + cs1_dqs1n_tx_de-skew = <0x09>; + cs1_dm2_rx_de-skew = <0x07>; + cs1_dm2_tx_de-skew = <0x08>; + cs1_dq16_rx_de-skew = <0x08>; + cs1_dq16_tx_de-skew = <0x09>; + cs1_dq17_rx_de-skew = <0x08>; + cs1_dq17_tx_de-skew = <0x09>; + cs1_dq18_rx_de-skew = <0x07>; + cs1_dq18_tx_de-skew = <0x08>; + cs1_dq19_rx_de-skew = <0x08>; + cs1_dq19_tx_de-skew = <0x09>; + cs1_dq20_rx_de-skew = <0x09>; + cs1_dq20_tx_de-skew = <0x09>; + cs1_dq21_rx_de-skew = <0x09>; + cs1_dq21_tx_de-skew = <0x09>; + cs1_dq22_rx_de-skew = <0x08>; + cs1_dq22_tx_de-skew = <0x09>; + cs1_dq23_rx_de-skew = <0x08>; + cs1_dq23_tx_de-skew = <0x09>; + cs1_dqs2_rx_de-skew = <0x06>; + cs1_dqs2p_tx_de-skew = <0x09>; + cs1_dqs2n_tx_de-skew = <0x09>; + cs1_dm3_rx_de-skew = <0x07>; + cs1_dm3_tx_de-skew = <0x07>; + cs1_dq24_rx_de-skew = <0x08>; + cs1_dq24_tx_de-skew = <0x09>; + cs1_dq25_rx_de-skew = <0x09>; + cs1_dq25_tx_de-skew = <0x09>; + cs1_dq26_rx_de-skew = <0x09>; + cs1_dq26_tx_de-skew = <0x08>; + cs1_dq27_rx_de-skew = <0x08>; + cs1_dq27_tx_de-skew = <0x08>; + cs1_dq28_rx_de-skew = <0x09>; + cs1_dq28_tx_de-skew = <0x09>; + cs1_dq29_rx_de-skew = <0x09>; + cs1_dq29_tx_de-skew = <0x09>; + cs1_dq30_rx_de-skew = <0x09>; + cs1_dq30_tx_de-skew = <0x08>; + cs1_dq31_rx_de-skew = <0x08>; + cs1_dq31_tx_de-skew = <0x08>; + cs1_dqs3_rx_de-skew = <0x07>; + cs1_dqs3p_tx_de-skew = <0x09>; + cs1_dqs3n_tx_de-skew = <0x09>; + phandle = <0xaf>; + }; + + aliases { + ethernet0 = "/ethernet@ff360000"; + i2c0 = "/i2c@ff180000"; + i2c1 = "/i2c@ff190000"; + i2c2 = "/i2c@ff1a0000"; + i2c3 = "/i2c@ff1b0000"; + serial0 = "/serial@ff030000"; + serial1 = "/serial@ff158000"; + serial2 = "/serial@ff160000"; + serial3 = "/serial@ff168000"; + serial4 = "/serial@ff170000"; + serial5 = "/serial@ff178000"; + spi0 = "/spi@ff1d0000"; + spi1 = "/spi@ff1d8000"; + }; + + cpus { + #address-cells = <0x02>; + #size-cells = <0x00>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x00>; + enable-method = "psci"; + clocks = <0x02 0x07>; + #cooling-cells = <0x02>; + dynamic-power-coefficient = <0x5a>; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + cpu-supply = <0x06>; + phandle = <0x09>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x01>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0a>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x02>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0b>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x03>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0c>; + }; + + idle-states { + entry-method = "psci"; + + cpu-sleep { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x10000>; + entry-latency-us = <0x78>; + exit-latency-us = <0xfa>; + min-residency-us = <0x384>; + phandle = <0x04>; + }; + + cluster-sleep { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x1010000>; + entry-latency-us = <0x190>; + exit-latency-us = <0x1f4>; + min-residency-us = <0x7d0>; + phandle = <0x05>; + }; + }; + }; + + cpu0-opp-table { + compatible = "operating-points-v2"; + opp-shared; + rockchip,temp-hysteresis = <0x1388>; + rockchip,low-temp = <0x00>; + rockchip,low-temp-min-volt = <0xf4240>; + rockchip,low-temp-adjust-volt = <0x00 0x5e8 0xc350>; + clocks = <0x02 0x01>; + rockchip,avs-scale = <0x04>; + rockchip,max-volt = <0x149970>; + rockchip,evb-irdrop = <0x61a8>; + nvmem-cells = <0x07 0x08>; + nvmem-cell-names = "cpu_leakage\0performance"; + rockchip,bin-scaling-sel = <0x00 0x0d 0x01 0x0d>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-freq = <0x639c0>; + rockchip,pvtm-volt = <0xf4240>; + rockchip,pvtm-ch = <0x00 0x00>; + rockchip,pvtm-sample-time = <0x3e8>; + rockchip,pvtm-number = <0x0a>; + rockchip,pvtm-error = <0x3e8>; + rockchip,pvtm-ref-temp = <0x28>; + rockchip,pvtm-temp-prop = <0xffffffc8 0xffffffc8>; + rockchip,thermal-zone = "soc-thermal"; + rockchip,avs = <0x01>; + phandle = <0x03>; + + opp-1008000000 { + opp-hz = <0x00 0x3c14dc00>; + opp-microvolt = <0x11edd8 0x11edd8 0x149970>; + opp-microvolt-L0 = <0x11edd8 0x11edd8 0x149970>; + opp-microvolt-L1 = <0x112a88 0x112a88 0x149970>; + opp-microvolt-L2 = <0x112a88 0x112a88 0x149970>; + opp-microvolt-L3 = <0x100590 0x100590 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1200000000 { + opp-hz = <0x00 0x47868c00>; + opp-microvolt = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L0 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L1 = <0x137478 0x137478 0x149970>; + opp-microvolt-L2 = <0x1312d0 0x1312d0 0x149970>; + opp-microvolt-L3 = <0x124f80 0x124f80 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1248000000 { + opp-hz = <0x00 0x4a62f800>; + opp-microvolt = <0x149970 0x149970 0x149970>; + opp-microvolt-L0 = <0x149970 0x149970 0x149970>; + opp-microvolt-L1 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L2 = <0x137478 0x137478 0x149970>; + opp-microvolt-L3 = <0x12b128 0x12b128 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1296000000 { + opp-hz = <0x00 0x4d3f6400>; + opp-microvolt = <0x149970 0x149970 0x149970>; + opp-microvolt-L0 = <0x149970 0x149970 0x149970>; + opp-microvolt-L1 = <0x149970 0x149970 0x149970>; + opp-microvolt-L2 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L3 = <0x1312d0 0x1312d0 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1512000000 { + opp-hz = <0x00 0x5a1f4a00>; + opp-microvolt = <0x149970 0x149970 0x149970>; + opp-microvolt-L0 = <0x149970 0x149970 0x149970>; + opp-microvolt-L1 = <0x149970 0x149970 0x149970>; + opp-microvolt-L2 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L3 = <0x1312d0 0x1312d0 0x149970>; + clock-latency-ns = <0x9c40>; + }; + }; + + arm-pmu { + compatible = "arm,cortex-a53-pmu"; + interrupts = <0x00 0x64 0x04 0x00 0x65 0x04 0x00 0x66 0x04 0x00 0x67 0x04>; + interrupt-affinity = <0x09 0x0a 0x0b 0x0c>; + }; + + bus-soc { + compatible = "rockchip,px30-bus"; + rockchip,busfreq-policy = "autocs"; + phandle = <0xc4>; + + soc-bus0 { + bus-id = <0x00>; + timer-us = <0x14>; + enable-msk = <0x40f7>; + status = "disabled"; + }; + + soc-bus1 { + bus-id = <0x01>; + timer-us = <0xc8>; + enable-msk = <0x40bf>; + status = "disabled"; + }; + + soc-bus2 { + bus-id = <0x02>; + timer-us = <0xc8>; + enable-msk = <0x4007>; + status = "disabled"; + }; + }; + + bus-apll { + compatible = "rockchip,px30-bus"; + rockchip,busfreq-policy = "clkfreq"; + clocks = <0x02 0x01>; + clock-names = "bus"; + operating-points-v2 = <0x0d>; + status = "okay"; + bus-supply = <0x0e>; + phandle = <0xc5>; + }; + + bus-apll-opp-table { + compatible = "operating-points-v2"; + opp-shared; + phandle = <0x0d>; + + opp-1512000000 { + opp-hz = <0x00 0x5a1f4a00>; + opp-microvolt = <0xf4240>; + }; + + opp-1008000000 { + opp-hz = <0x00 0x3c14dc00>; + opp-microvolt = <0xe7ef0>; + }; + }; + + cpuinfo { + compatible = "rockchip,cpuinfo"; + nvmem-cells = <0x0f>; + nvmem-cell-names = "id"; + }; + + display-subsystem { + compatible = "rockchip,display-subsystem"; + ports = <0x10>; + status = "okay"; + logo-memory-region = <0x11>; + phandle = <0xc6>; + + route { + + route-lvds { + status = "disabled"; + logo,uboot = "logo.gif"; + logo,kernel = "logo_kernel.gif"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x12>; + phandle = <0xc7>; + }; + + route-dsi { + status = "okay"; + logo,uboot = "logo.gif"; + logo,kernel = "logo_kernel.gif"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x13>; + phandle = <0xc8>; + }; + + route-rgb { + status = "disabled"; + logo,uboot = "logo.gif"; + logo,kernel = "logo_kernel.gif"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x14>; + phandle = <0xc9>; + }; + }; + }; + + firmware { + + optee { + compatible = "linaro,optee-tz"; + method = "smc"; + }; + }; + + external-gmac-clock { + compatible = "fixed-clock"; + clock-frequency = <0x2faf080>; + clock-output-names = "gmac_clkin"; + #clock-cells = <0x00>; + phandle = <0xca>; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + rockchip-suspend { + compatible = "rockchip,pm-px30"; + status = "okay"; + rockchip,sleep-debug-en = <0x01>; + rockchip,sleep-mode-config = <0x20702>; + rockchip,wakeup-config = <0x85>; + phandle = <0xcb>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <0x01 0x0d 0xf04 0x01 0x0e 0xf04 0x01 0x0b 0xf04 0x01 0x0a 0xf04>; + }; + + xin24m { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x16e3600>; + clock-output-names = "xin24m"; + phandle = <0xcc>; + }; + + xin32k { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x8000>; + clock-output-names = "xin32k"; + phandle = <0xcd>; + }; + + power-management@ff000000 { + compatible = "rockchip,px30-pmu\0syscon\0simple-mfd"; + reg = <0x00 0xff000000 0x00 0x1000>; + phandle = <0xce>; + + power-controller { + compatible = "rockchip,px30-power-controller"; + #power-domain-cells = <0x01>; + #address-cells = <0x01>; + #size-cells = <0x00>; + phandle = <0x8a>; + + pd_usb@5 { + reg = <0x05>; + clocks = <0x02 0x103 0x02 0x102 0x02 0x3c>; + pm_qos = <0x15 0x16>; + }; + + pd_sdcard@7 { + reg = <0x07>; + clocks = <0x02 0xf7 0x02 0x3b>; + pm_qos = <0x17>; + }; + + pd_gmac@9 { + reg = <0x09>; + clocks = <0x02 0xb2 0x02 0x143 0x02 0x40 0x02 0x3f>; + pm_qos = <0x18>; + }; + + pd_mmc_nand@10 { + reg = <0x0a>; + clocks = <0x02 0xfe 0x02 0x100 0x02 0xff 0x02 0x101 0x02 0x39 0x02 0x37 0x02 0x38 0x02 0x3a>; + pm_qos = <0x19 0x1a 0x1b 0x1c>; + }; + + pd_vpu@11 { + reg = <0x0b>; + clocks = <0x02 0xaf 0x02 0xf4 0x02 0x4b>; + pm_qos = <0x1d 0x1e>; + }; + + pd_vo@12 { + reg = <0x0c>; + clocks = <0x02 0xb7 0x02 0xb5 0x02 0xb6 0x02 0x96 0x02 0x97 0x02 0xfd 0x02 0xfb 0x02 0xfc 0x02 0x144 0x02 0x35 0x02 0x36>; + pm_qos = <0x1f 0x20 0x21 0x22>; + }; + + pd_vi@13 { + reg = <0x0d>; + clocks = <0x02 0xb3 0x02 0xb4 0x02 0xf9 0x02 0xfa 0x02 0x33>; + pm_qos = <0x23 0x24 0x25 0x26 0x27>; + }; + + pd_gpu@14 { + reg = <0x0e>; + clocks = <0x02 0x49>; + pm_qos = <0x28>; + }; + }; + }; + + syscon@ff010000 { + compatible = "rockchip,px30-pmugrf\0syscon\0simple-mfd"; + reg = <0x00 0xff010000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0xac>; + + io-domains { + compatible = "rockchip,px30-pmu-io-voltage-domain"; + status = "okay"; + pmuio1-supply = <0x29>; + pmuio2-supply = <0x29>; + phandle = <0xcf>; + }; + + reboot-mode { + compatible = "syscon-reboot-mode"; + offset = <0x200>; + mode-bootloader = <0x5242c301>; + mode-charge = <0x5242c30b>; + mode-fastboot = <0x5242c309>; + mode-loader = <0x5242c301>; + mode-normal = <0x5242c300>; + mode-recovery = <0x5242c303>; + mode-ums = <0x5242c30c>; + }; + + pmu-pvtm { + compatible = "rockchip,px30-pmu-pvtm"; + clocks = <0x2a 0x07>; + clock-names = "pmu"; + status = "okay"; + phandle = <0xd0>; + }; + }; + + serial@ff030000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff030000 0x00 0x100>; + interrupts = <0x00 0x0f 0x04>; + clocks = <0x2a 0x06 0x2a 0x15>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x00 0x2b 0x01>; + pinctrl-names = "default"; + pinctrl-0 = <0x2c 0x2d 0x2e>; + status = "disabled"; + phandle = <0xd1>; + }; + + i2s@ff060000 { + compatible = "rockchip,px30-i2s-tdm"; + reg = <0x00 0xff060000 0x00 0x1000>; + interrupts = <0x00 0x0c 0x04>; + clocks = <0x02 0x10 0x02 0x12 0x02 0x106>; + clock-names = "mclk_tx\0mclk_rx\0hclk"; + dmas = <0x2b 0x10 0x2b 0x11>; + dma-names = "tx\0rx"; + resets = <0x02 0x84 0x02 0xbf>; + reset-names = "tx-m\0rx-m"; + rockchip,cru = <0x02>; + rockchip,grf = <0x2f>; + pinctrl-names = "default"; + pinctrl-0 = <0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x3a 0x3b>; + status = "disabled"; + phandle = <0xd2>; + }; + + i2s@ff070000 { + compatible = "rockchip,px30-i2s\0rockchip,rk3066-i2s"; + reg = <0x00 0xff070000 0x00 0x1000>; + interrupts = <0x00 0x0d 0x04>; + clocks = <0x02 0x14 0x02 0x107>; + clock-names = "i2s_clk\0i2s_hclk"; + dmas = <0x2b 0x12 0x2b 0x13>; + dma-names = "tx\0rx"; + resets = <0x02 0x86 0x02 0x85>; + reset-names = "reset-m\0reset-h"; + pinctrl-names = "default"; + pinctrl-0 = <0x3c 0x3d 0x3e 0x3f>; + status = "okay"; + #sound-dai-cells = <0x00>; + phandle = <0xc2>; + }; + + i2s@ff080000 { + compatible = "rockchip,px30-i2s\0rockchip,rk3066-i2s"; + reg = <0x00 0xff080000 0x00 0x1000>; + interrupts = <0x00 0x0e 0x04>; + clocks = <0x02 0x16 0x02 0x108>; + clock-names = "i2s_clk\0i2s_hclk"; + dmas = <0x2b 0x14 0x2b 0x15>; + dma-names = "tx\0rx"; + resets = <0x02 0x88 0x02 0x87>; + reset-names = "reset-m\0reset-h"; + pinctrl-names = "default"; + pinctrl-0 = <0x40 0x41 0x42 0x43>; + status = "disabled"; + phandle = <0xd3>; + }; + + pdm@ff0a0000 { + compatible = "rockchip,px30-pdm\0rockchip,pdm"; + reg = <0x00 0xff0a0000 0x00 0x1000>; + clocks = <0x02 0x0f 0x02 0x105>; + clock-names = "pdm_clk\0pdm_hclk"; + dmas = <0x2b 0x18>; + dma-names = "rx"; + resets = <0x02 0x82>; + reset-names = "pdm-m"; + pinctrl-names = "default"; + pinctrl-0 = <0x44 0x45 0x46 0x47 0x48 0x49>; + status = "disabled"; + phandle = <0xd4>; + }; + + crypto@ff0b0000 { + compatible = "rockchip,px30-crypto"; + reg = <0x00 0xff0b0000 0x00 0x4000>; + interrupts = <0x00 0x52 0x04>; + clocks = <0x02 0xac 0x02 0xf1 0x02 0x30 0x02 0x31>; + clock-names = "aclk\0hclk\0sclk\0apb_pclk"; + resets = <0x02 0x74>; + reset-names = "crypto-rst"; + status = "disabled"; + phandle = <0xd5>; + }; + + rng@ff0b0000 { + compatible = "rockchip,cryptov2-rng"; + reg = <0x00 0xff0b0000 0x00 0x4000>; + clocks = <0x02 0x30 0x02 0x31 0x02 0xac 0x02 0xf1>; + clock-names = "clk_crypto\0clk_crypto_apk\0aclk_crypto\0hclk_crypto"; + assigned-clocks = <0x02 0x30 0x02 0x31 0x02 0xac 0x02 0xf1>; + assigned-clock-rates = <0x8f0d180 0x8f0d180 0xbebc200 0x5f5e100>; + resets = <0x02 0x74>; + reset-names = "reset"; + status = "okay"; + phandle = <0xd6>; + }; + + interrupt-controller@ff131000 { + compatible = "arm,gic-400"; + #interrupt-cells = <0x03>; + #address-cells = <0x00>; + interrupt-controller; + reg = <0x00 0xff131000 0x00 0x1000 0x00 0xff132000 0x00 0x2000 0x00 0xff134000 0x00 0x2000 0x00 0xff136000 0x00 0x2000>; + interrupts = <0x01 0x09 0xf04>; + phandle = <0x01>; + }; + + syscon@ff140000 { + compatible = "rockchip,px30-grf\0syscon\0simple-mfd"; + reg = <0x00 0xff140000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0x2f>; + + io-domains { + compatible = "rockchip,px30-io-voltage-domain"; + status = "okay"; + vccio1-supply = <0x4a>; + vccio2-supply = <0x4a>; + vccio3-supply = <0x4b>; + vccio4-supply = <0x4b>; + vccio5-supply = <0x4b>; + vccio6-supply = <0x4b>; + phandle = <0xd7>; + }; + + lvds { + compatible = "rockchip,px30-lvds"; + phys = <0x4c>; + phy-names = "phy"; + status = "disabled"; + phandle = <0xd8>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x12>; + phandle = <0xa2>; + }; + }; + }; + }; + + rgb { + compatible = "rockchip,px30-rgb"; + pinctrl-names = "default\0sleep"; + pinctrl-0 = <0x4d>; + pinctrl-1 = <0x4e>; + status = "disabled"; + phys = <0x4c>; + phy-names = "phy"; + phandle = <0xd9>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x14>; + phandle = <0xa4>; + }; + }; + }; + }; + }; + + syscon@ff148000 { + compatible = "syscon\0simple-mfd"; + reg = <0x00 0xff148000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0xda>; + + pvtm { + compatible = "rockchip,px30-pvtm"; + clocks = <0x02 0x4a>; + clock-names = "core"; + status = "okay"; + phandle = <0xdb>; + }; + }; + + serial@ff158000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff158000 0x00 0x100>; + interrupts = <0x00 0x10 0x04>; + clocks = <0x02 0x18 0x02 0x149>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x02 0x2b 0x03>; + pinctrl-names = "default"; + pinctrl-0 = <0x4f 0x50>; + status = "okay"; + phandle = <0xdc>; + }; + + serial@ff160000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff160000 0x00 0x100>; + interrupts = <0x00 0x11 0x04>; + clocks = <0x02 0x19 0x02 0x14a>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x04 0x2b 0x05>; + pinctrl-names = "default"; + pinctrl-0 = <0x51>; + status = "disabled"; + phandle = <0xdd>; + }; + + serial@ff168000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff168000 0x00 0x100>; + interrupts = <0x00 0x12 0x04>; + clocks = <0x02 0x1a 0x02 0x14b>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x06 0x2b 0x07>; + pinctrl-names = "default"; + pinctrl-0 = <0x52 0x53 0x54>; + status = "disabled"; + phandle = <0xde>; + }; + + serial@ff170000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff170000 0x00 0x100>; + interrupts = <0x00 0x13 0x04>; + clocks = <0x02 0x1b 0x02 0x14c>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x08 0x2b 0x09>; + pinctrl-names = "default"; + pinctrl-0 = <0x55 0x56 0x57>; + status = "disabled"; + phandle = <0xdf>; + }; + + serial@ff178000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff178000 0x00 0x100>; + interrupts = <0x00 0x14 0x04>; + clocks = <0x02 0x1c 0x02 0x14d>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x0a 0x2b 0x0b>; + pinctrl-names = "default"; + pinctrl-0 = <0x58 0x59 0x5a>; + status = "disabled"; + phandle = <0xe0>; + }; + + i2c@ff180000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff180000 0x00 0x1000>; + clocks = <0x02 0x1d 0x02 0x14e>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x07 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x5b>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + clock-frequency = <0x61a80>; + i2c-scl-rising-time-ns = <0x118>; + i2c-scl-falling-time-ns = <0x10>; + phandle = <0xe1>; + + pmic@20 { + compatible = "rockchip,rk817"; + reg = <0x20>; + interrupt-parent = <0x5c>; + interrupts = <0x0a 0x08>; + pinctrl-names = "default\0pmic-sleep\0pmic-power-off\0pmic-reset"; + pinctrl-0 = <0x5d>; + pinctrl-1 = <0x5e 0x5f>; + pinctrl-2 = <0x60 0x61>; + pinctrl-3 = <0x62 0x63>; + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <0x01>; + clock-output-names = "rk808-clkout1\0rk808-clkout2"; + pmic-reset-func = <0x01>; + vcc1-supply = <0x64>; + vcc2-supply = <0x64>; + vcc3-supply = <0x64>; + vcc4-supply = <0x64>; + vcc5-supply = <0x64>; + vcc6-supply = <0x64>; + vcc7-supply = <0x64>; + vcc8-supply = <0x64>; + vcc9-supply = <0x65>; + phandle = <0xe2>; + + pwrkey { + status = "okay"; + }; + + pinctrl_rk8xx { + gpio-controller; + #gpio-cells = <0x02>; + phandle = <0xe3>; + + rk817_ts_gpio1 { + pins = "gpio_ts"; + function = "pin_fun1"; + phandle = <0xe4>; + }; + + rk817_gt_gpio2 { + pins = "gpio_gt"; + function = "pin_fun1"; + phandle = <0xe5>; + }; + + rk817_pin_ts { + pins = "gpio_ts"; + function = "pin_fun0"; + phandle = <0xe6>; + }; + + rk817_pin_gt { + pins = "gpio_gt"; + function = "pin_fun0"; + phandle = <0xe7>; + }; + + rk817_slppin_null { + pins = "gpio_slp"; + function = "pin_fun0"; + phandle = <0xe8>; + }; + + rk817_slppin_slp { + pins = "gpio_slp"; + function = "pin_fun1"; + phandle = <0x5f>; + }; + + rk817_slppin_pwrdn { + pins = "gpio_slp"; + function = "pin_fun2"; + phandle = <0x61>; + }; + + rk817_slppin_rst { + pins = "gpio_slp"; + function = "pin_fun3"; + phandle = <0x63>; + }; + }; + + regulators { + + DCDC_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xe7ef0>; + regulator-max-microvolt = <0x118c30>; + regulator-ramp-delay = <0x1771>; + regulator-initial-mode = <0x02>; + regulator-name = "vdd_logic"; + phandle = <0x0e>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0xe7ef0>; + }; + }; + + DCDC_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xe7ef0>; + regulator-max-microvolt = <0x149970>; + regulator-ramp-delay = <0x1771>; + regulator-initial-mode = <0x02>; + regulator-name = "vdd_arm"; + phandle = <0x06>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0xe7ef0>; + }; + }; + + DCDC_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x02>; + regulator-name = "vcc_ddr"; + phandle = <0xe9>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + DCDC_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-initial-mode = <0x02>; + regulator-name = "vcc_3v3"; + phandle = <0x4b>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG1 { + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + regulator-name = "vcc_1v0"; + phandle = <0xea>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0xf4240>; + }; + }; + + LDO_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + regulator-name = "vcc1v8_soc"; + phandle = <0x88>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x1b7740>; + }; + }; + + LDO_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + regulator-name = "vcc1v0_soc"; + phandle = <0xeb>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0xf4240>; + }; + }; + + LDO_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "vcc3v3_pmu"; + phandle = <0x29>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + regulator-name = "vccio_sd"; + phandle = <0x4a>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x1b7740>; + }; + }; + + LDO_REG6 { + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x2dc6c0>; + regulator-boot-on; + regulator-name = "vcc_sd"; + phandle = <0x93>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x2dc6c0>; + }; + }; + + LDO_REG7 { + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "vcc_backlight"; + phandle = <0x9e>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG8 { + regulator-min-microvolt = <0x2ab980>; + regulator-max-microvolt = <0x2ab980>; + regulator-name = "vcc_lcd"; + phandle = <0x9f>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x2ab980>; + }; + }; + + BOOST { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x4c4b40>; + regulator-max-microvolt = <0x5265c0>; + regulator-name = "boost"; + phandle = <0x65>; + }; + + OTG_SWITCH { + regulator-boot-on; + regulator-name = "otg_switch"; + phandle = <0xec>; + }; + }; + + battery { + compatible = "rk817,battery"; + ocv_table = <0xc5d 0xc94 0xcd0 0xd02 0xd34 0xd66 0xd98 0xdca 0xdfc 0xe2e 0xe56 0xe7e 0xea6 0xece 0xef6 0xf1e 0xf46 0xf6e 0xf96 0xf9b 0xfa0>; + design_capacity = <0xd34>; + design_qmax = <0xe86>; + bat_res = <0x64>; + sleep_enter_current = <0x12c>; + sleep_exit_current = <0x12c>; + sleep_filter_current = <0x64>; + power_off_thresd = <0xbb8>; + zero_algorithm_vol = <0xf0a>; + max_soc_offset = <0x3c>; + monitor_sec = <0x05>; + virtual_power = <0x00>; + sample_res = <0x0a>; + }; + + charger { + compatible = "rk817,charger"; + min_input_voltage = <0x1194>; + max_input_current = <0x5dc>; + max_chrg_current = <0x7d0>; + max_chrg_voltage = <0x1068>; + chrg_term_mode = <0x00>; + chrg_finish_cur = <0x34>; + virtual_power = <0x00>; + sample_res = <0x0a>; + dc_det_gpio = <0x5c 0x0b 0x00>; + bat_low_gpio = <0x66 0x0d 0x00>; + extcon = <0x67>; + }; + + codec { + #sound-dai-cells = <0x00>; + compatible = "rockchip,rk817-codec"; + clocks = <0x02 0x15>; + clock-names = "mclk"; + pinctrl-names = "default"; + pinctrl-0 = <0x68>; + hp-volume = <0x14>; + spk-volume = <0x03>; + status = "okay"; + phandle = <0xc3>; + }; + }; + }; + + i2c@ff190000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff190000 0x00 0x1000>; + clocks = <0x02 0x1e 0x02 0x14f>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x08 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x69>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + clock-frequency = <0x61a80>; + phandle = <0xed>; + }; + + i2c@ff1a0000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff1a0000 0x00 0x1000>; + clocks = <0x02 0x1f 0x02 0x150>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x09 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x6a>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xee>; + }; + + i2c@ff1b0000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff1b0000 0x00 0x1000>; + clocks = <0x02 0x20 0x02 0x151>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x0a 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x6b>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xef>; + }; + + spi@ff1d0000 { + compatible = "rockchip,px30-spi\0rockchip,rk3066-spi"; + reg = <0x00 0xff1d0000 0x00 0x1000>; + interrupts = <0x00 0x1a 0x04>; + #address-cells = <0x01>; + #size-cells = <0x00>; + clocks = <0x02 0x24 0x02 0x155>; + clock-names = "spiclk\0apb_pclk"; + dmas = <0x2b 0x0c 0x2b 0x0d>; + dma-names = "tx\0rx"; + pinctrl-names = "default\0high_speed"; + pinctrl-0 = <0x6c 0x6d 0x6e 0x6f>; + pinctrl-1 = <0x70 0x6d 0x71 0x72>; + status = "disabled"; + phandle = <0xf0>; + }; + + spi@ff1d8000 { + compatible = "rockchip,px30-spi\0rockchip,rk3066-spi"; + reg = <0x00 0xff1d8000 0x00 0x1000>; + interrupts = <0x00 0x1b 0x04>; + #address-cells = <0x01>; + #size-cells = <0x00>; + clocks = <0x02 0x25 0x02 0x156>; + clock-names = "spiclk\0apb_pclk"; + dmas = <0x2b 0x0e 0x2b 0x0f>; + dma-names = "tx\0rx"; + pinctrl-names = "default\0high_speed"; + pinctrl-0 = <0x73 0x74 0x75 0x76 0x77>; + pinctrl-1 = <0x78 0x74 0x75 0x79 0x7a>; + status = "disabled"; + phandle = <0xf1>; + }; + + watchdog@ff1e0000 { + compatible = "snps,dw-wdt"; + reg = <0x00 0xff1e0000 0x00 0x100>; + clocks = <0x02 0x15b>; + interrupts = <0x00 0x25 0x04>; + resets = <0x02 0xb5>; + reset-names = "reset"; + status = "disabled"; + phandle = <0xf2>; + }; + + pwm@ff200000 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200000 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7b>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "okay"; + phandle = <0xbc>; + }; + + pwm@ff200010 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200010 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7c>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "okay"; + phandle = <0xc1>; + }; + + pwm@ff200020 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200020 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7d>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf3>; + }; + + pwm@ff200030 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200030 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7e>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf4>; + }; + + pwm@ff208000 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208000 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7f>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf5>; + }; + + pwm@ff208010 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208010 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x80>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf6>; + }; + + pwm@ff208020 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208020 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x81>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf7>; + }; + + pwm@ff208030 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208030 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x82>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf8>; + }; + + rktimer@ff210000 { + compatible = "rockchip,rk3288-timer"; + reg = <0x00 0xff210000 0x00 0x1000>; + interrupts = <0x00 0x1e 0x04>; + clocks = <0x02 0x159 0x02 0x26>; + clock-names = "pclk\0timer"; + phandle = <0xf9>; + }; + + amba { + compatible = "simple-bus"; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + + dmac@ff240000 { + compatible = "arm,pl330\0arm,primecell"; + reg = <0x00 0xff240000 0x00 0x4000>; + interrupts = <0x00 0x01 0x04 0x00 0x02 0x04>; + clocks = <0x02 0xbb>; + clock-names = "apb_pclk"; + #dma-cells = <0x01>; + peripherals-req-type-burst; + phandle = <0x2b>; + }; + }; + + thermal-zones { + phandle = <0xfa>; + + soc-thermal { + polling-delay-passive = <0x14>; + polling-delay = <0x3e8>; + sustainable-power = <0x2ee>; + thermal-sensors = <0x83 0x00>; + phandle = <0xfb>; + + trips { + + trip-point-0 { + temperature = <0x11170>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0xfc>; + }; + + trip-point-1 { + temperature = <0x14c08>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0x84>; + }; + + soc-crit { + temperature = <0x1c138>; + hysteresis = <0x7d0>; + type = "critical"; + phandle = <0xfd>; + }; + }; + + cooling-maps { + + map0 { + trip = <0x84>; + cooling-device = <0x09 0xffffffff 0xffffffff>; + contribution = <0x1000>; + }; + + map1 { + trip = <0x84>; + cooling-device = <0x85 0xffffffff 0xffffffff>; + contribution = <0x1000>; + }; + }; + }; + + gpu-thermal { + polling-delay-passive = <0x64>; + polling-delay = <0x3e8>; + thermal-sensors = <0x83 0x01>; + phandle = <0xfe>; + }; + }; + + tsadc@ff280000 { + compatible = "rockchip,px30-tsadc"; + reg = <0x00 0xff280000 0x00 0x100>; + interrupts = <0x00 0x24 0x04>; + rockchip,grf = <0x2f>; + clocks = <0x02 0x2c 0x02 0x158>; + clock-names = "tsadc\0apb_pclk"; + assigned-clocks = <0x02 0x2c>; + assigned-clock-rates = <0xc350>; + resets = <0x02 0xa8>; + reset-names = "tsadc-apb"; + #thermal-sensor-cells = <0x01>; + rockchip,hw-tshut-temp = <0x1d4c0>; + status = "okay"; + pinctrl-names = "gpio\0otpout"; + pinctrl-0 = <0x86>; + pinctrl-1 = <0x87>; + phandle = <0x83>; + }; + + saradc@ff288000 { + compatible = "rockchip,px30-saradc\0rockchip,rk3399-saradc"; + reg = <0x00 0xff288000 0x00 0x100>; + interrupts = <0x00 0x54 0x04>; + #io-channel-cells = <0x01>; + clocks = <0x02 0x2d 0x02 0x157>; + clock-names = "saradc\0apb_pclk"; + resets = <0x02 0xa5>; + reset-names = "saradc-apb"; + status = "okay"; + vref-supply = <0x88>; + phandle = <0xbe>; + }; + + otp@ff290000 { + compatible = "rockchip,px30-otp"; + reg = <0x00 0xff290000 0x00 0x4000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + clocks = <0x02 0x2f 0x02 0x15a 0x02 0x161>; + clock-names = "clk_otp\0pclk_otp\0pclk_otp_phy"; + resets = <0x02 0xb4>; + reset-names = "otp_phy"; + phandle = <0xff>; + + id@7 { + reg = <0x07 0x10>; + phandle = <0x0f>; + }; + + cpu-leakage@17 { + reg = <0x17 0x01>; + phandle = <0x07>; + }; + + performance@1e { + reg = <0x1e 0x01>; + bits = <0x04 0x03>; + phandle = <0x08>; + }; + }; + + clock-controller@ff2b0000 { + compatible = "rockchip,px30-cru"; + reg = <0x00 0xff2b0000 0x00 0x1000>; + rockchip,grf = <0x2f>; + rockchip,boost = <0x89>; + #clock-cells = <0x01>; + #reset-cells = <0x01>; + assigned-clocks = <0x02 0x04>; + assigned-clock-rates = <0x3dfd2400>; + phandle = <0x02>; + }; + + cpu-boost@ff2b8000 { + compatible = "syscon"; + reg = <0x00 0xff2b8000 0x00 0x1000>; + rockchip,boost-low-con0 = <0x1032>; + rockchip,boost-low-con1 = <0x1441>; + rockchip,boost-high-con0 = <0x1036>; + rockchip,boost-high-con1 = <0x1441>; + rockchip,boost-backup-pll = <0x01>; + rockchip,boost-backup-pll-usage = <0x00>; + rockchip,boost-switch-threshold = <0x249f00>; + rockchip,boost-statis-threshold = <0x100>; + rockchip,boost-statis-enable = <0x00>; + rockchip,boost-enable = <0x00>; + phandle = <0x89>; + }; + + pmu-clock-controller@ff2bc000 { + compatible = "rockchip,px30-pmucru"; + reg = <0x00 0xff2bc000 0x00 0x1000>; + rockchip,grf = <0x2f>; + #clock-cells = <0x01>; + #reset-cells = <0x01>; + assigned-clocks = <0x2a 0x01 0x2a 0x08 0x2a 0x05 0x02 0x07 0x02 0xab 0x02 0xb0 0x02 0xf0 0x02 0xf5 0x02 0x140 0x02 0x49>; + assigned-clock-rates = <0x47868c00 0x5f5e100 0x18cba80 0x23c34600 0xbebc200 0xbebc200 0x8f0d180 0x8f0d180 0x5f5e100 0xbebc200>; + phandle = <0x2a>; + }; + + syscon@ff2c0000 { + compatible = "rockchip,px30-usb2phy-grf\0syscon\0simple-mfd"; + reg = <0x00 0xff2c0000 0x00 0x10000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0x100>; + + usb2-phy@100 { + compatible = "rockchip,px30-usb2phy\0rockchip,rk3328-usb2phy"; + reg = <0x100 0x10>; + clocks = <0x2a 0x0a>; + clock-names = "phyclk"; + #clock-cells = <0x00>; + assigned-clocks = <0x02 0x0e 0x02 0x55>; + assigned-clock-parents = <0x67 0x02 0x0e>; + clock-output-names = "usb480m_phy"; + status = "okay"; + phandle = <0x67>; + + host-port { + #phy-cells = <0x00>; + interrupts = <0x00 0x44 0x04>; + interrupt-names = "linestate"; + status = "okay"; + phandle = <0x8c>; + }; + + otg-port { + #phy-cells = <0x00>; + interrupts = <0x00 0x42 0x04 0x00 0x41 0x04 0x00 0x40 0x04>; + interrupt-names = "otg-bvalid\0otg-id\0linestate"; + status = "disabled"; + phandle = <0x8b>; + }; + }; + }; + + video-phy@ff2e0000 { + compatible = "rockchip,px30-video-phy"; + reg = <0x00 0xff2e0000 0x00 0x10000 0x00 0xff450000 0x00 0x10000>; + clocks = <0x2a 0x0b 0x02 0x145 0x02 0x144>; + clock-names = "ref\0pclk_phy\0pclk_host"; + #clock-cells = <0x00>; + resets = <0x02 0x3e>; + reset-names = "rst"; + power-domains = <0x8a 0x0c>; + #phy-cells = <0x00>; + status = "okay"; + phandle = <0x4c>; + }; + + mipi-dphy-rx0@ff2f0000 { + compatible = "rockchip,rk3326-mipi-dphy"; + reg = <0x00 0xff2f0000 0x00 0x4000>; + clocks = <0x02 0x146>; + clock-names = "dphy-ref"; + power-domains = <0x8a 0x0d>; + rockchip,grf = <0x2f>; + status = "okay"; + phandle = <0x101>; + }; + + usb@ff300000 { + compatible = "rockchip,px30-usb\0rockchip,rk3066-usb\0snps,dwc2"; + reg = <0x00 0xff300000 0x00 0x40000>; + interrupts = <0x00 0x3e 0x04>; + clocks = <0x02 0x102>; + clock-names = "otg"; + power-domains = <0x8a 0x05>; + dr_mode = "otg"; + g-np-tx-fifo-size = <0x10>; + g-rx-fifo-size = <0x118>; + g-tx-fifo-size = <0x100 0x80 0x80 0x40 0x20 0x10>; + g-use-dma; + phys = <0x8b>; + phy-names = "usb2-phy"; + status = "okay"; + phandle = <0x102>; + }; + + usb@ff340000 { + compatible = "generic-ehci"; + reg = <0x00 0xff340000 0x00 0x10000>; + interrupts = <0x00 0x3c 0x04>; + clocks = <0x02 0x103 0x67>; + clock-names = "usbhost\0utmi"; + power-domains = <0x8a 0x05>; + phys = <0x8c>; + phy-names = "usb"; + status = "disabled"; + phandle = <0x103>; + }; + + usb@ff350000 { + compatible = "generic-ohci"; + reg = <0x00 0xff350000 0x00 0x10000>; + interrupts = <0x00 0x3d 0x04>; + clocks = <0x02 0x103 0x67>; + clock-names = "usbhost\0utmi"; + power-domains = <0x8a 0x05>; + phys = <0x8c>; + phy-names = "usb"; + status = "disabled"; + phandle = <0x104>; + }; + + ethernet@ff360000 { + compatible = "rockchip,px30-gmac"; + reg = <0x00 0xff360000 0x00 0x10000>; + rockchip,grf = <0x2f>; + interrupts = <0x00 0x2b 0x04>; + interrupt-names = "macirq"; + clocks = <0x02 0x3e 0x02 0x3f 0x02 0x3f 0x02 0x40 0x02 0x41 0x02 0xb2 0x02 0x143 0x02 0x4c>; + clock-names = "stmmaceth\0mac_clk_rx\0mac_clk_tx\0clk_mac_ref\0clk_mac_refout\0aclk_mac\0pclk_mac\0clk_mac_speed"; + phy-mode = "rmii"; + pinctrl-names = "default"; + pinctrl-0 = <0x8d 0x8e>; + resets = <0x02 0x5e>; + reset-names = "stmmaceth"; + power-domains = <0x8a 0x09>; + status = "disabled"; + phandle = <0x105>; + }; + + dwmmc@ff370000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff370000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0xf7 0x02 0x3b 0x02 0x43 0x02 0x44>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x3b>; + assigned-clock-parents = <0x02 0x57>; + power-domains = <0x8a 0x07>; + fifo-depth = <0x100>; + interrupts = <0x00 0x36 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x8f 0x90 0x91 0x92>; + status = "okay"; + bus-width = <0x04>; + cap-mmc-highspeed; + cap-sd-highspeed; + supports-sd; + card-detect-delay = <0x320>; + ignore-pm-notify; + cd-gpios = <0x5c 0x03 0x01>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <0x4a>; + vmmc-supply = <0x93>; + phandle = <0x106>; + }; + + dwmmc@ff380000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff380000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0xff 0x02 0x38 0x02 0x45 0x02 0x46>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x38>; + assigned-clock-parents = <0x02 0x51>; + power-domains = <0x8a 0x0a>; + fifo-depth = <0x100>; + interrupts = <0x00 0x37 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x94 0x95 0x96>; + status = "okay"; + bus-width = <0x04>; + cap-mmc-highspeed; + cap-sd-highspeed; + supports-sd; + card-detect-delay = <0x320>; + ignore-pm-notify; + cd-gpios = <0x97 0x0e 0x01>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <0x4a>; + vmmc-supply = <0x93>; + phandle = <0x107>; + }; + + dwmmc@ff390000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff390000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0x100 0x02 0x39 0x02 0x47 0x02 0x48>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x39>; + assigned-clock-parents = <0x02 0x53>; + power-domains = <0x8a 0x0a>; + fifo-depth = <0x100>; + interrupts = <0x00 0x35 0x04>; + status = "disabled"; + phandle = <0x108>; + }; + + nandc@ff3b0000 { + compatible = "rockchip,rk-nandc"; + reg = <0x00 0xff3b0000 0x00 0x4000>; + interrupts = <0x00 0x39 0x04>; + nandc_id = <0x00>; + clocks = <0x02 0x37 0x02 0xfe>; + clock-names = "clk_nandc\0hclk_nandc"; + assigned-clocks = <0x02 0x37>; + assigned-clock-parents = <0x02 0x4f>; + power-domains = <0x8a 0x0a>; + status = "disabled"; + phandle = <0x109>; + }; + + sfc@ff3a0000 { + compatible = "rockchip,sfc"; + reg = <0x00 0xff3a0000 0x00 0x4000>; + interrupts = <0x00 0x38 0x04>; + clocks = <0x02 0x3a 0x02 0x101>; + clock-names = "clk_sfc\0hclk_sfc"; + assigned-clocks = <0x02 0x3a>; + assigned-clock-rates = <0x989680>; + status = "disabled"; + phandle = <0x10a>; + }; + + gpu@ff400000 { + compatible = "arm,malit602\0arm,malit60x\0arm,malit6xx\0arm,mali-midgard"; + reg = <0x00 0xff400000 0x00 0x4000>; + interrupts = <0x00 0x2d 0x04 0x00 0x2e 0x04 0x00 0x2f 0x04>; + interrupt-names = "GPU\0MMU\0JOB"; + clocks = <0x02 0x49>; + clock-names = "clk_mali"; + power-domains = <0x8a 0x0e>; + #cooling-cells = <0x02>; + operating-points-v2 = <0x98>; + status = "okay"; + mali-supply = <0x0e>; + phandle = <0x85>; + + power_model { + compatible = "arm,mali-simple-power-model"; + static-coefficient = <0x64578>; + dynamic-coefficient = <0x2dd>; + ts = <0x7d00 0x125c 0xffffffb0 0x02>; + thermal-zone = "gpu-thermal"; + }; + }; + + gpu-opp-table { + compatible = "operating-points-v2"; + rockchip,thermal-zone = "soc-thermal"; + rockchip,temp-hysteresis = <0x1388>; + rockchip,low-temp = <0x00>; + rockchip,low-temp-min-volt = <0xf4240>; + rockchip,low-temp-adjust-volt = <0x00 0x1e0 0xc350>; + rockchip,max-volt = <0x11edd8>; + rockchip,evb-irdrop = <0x61a8>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-ch = <0x00 0x00>; + phandle = <0x98>; + + opp-400000000 { + opp-hz = <0x00 0x17d78400>; + opp-microvolt = <0x100590>; + opp-microvolt-L0 = <0x100590>; + opp-microvolt-L1 = <0xfa3e8>; + opp-microvolt-L2 = <0xee098>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-480000000 { + opp-hz = <0x00 0x1c9c3800>; + opp-microvolt = <0x112a88>; + opp-microvolt-L0 = <0x112a88>; + opp-microvolt-L1 = <0x10c8e0>; + opp-microvolt-L2 = <0x100590>; + opp-microvolt-L3 = <0xf4240>; + }; + + opp-520000000 { + opp-hz = <0x00 0x1efe9200>; + opp-microvolt = <0x118c30>; + opp-microvolt-L0 = <0x118c30>; + opp-microvolt-L1 = <0x118c30>; + opp-microvolt-L2 = <0x10c8e0>; + opp-microvolt-L3 = <0x100590>; + }; + }; + + hevc_service@ff440000 { + compatible = "rockchip,hevc_sub"; + iommu_enabled = <0x01>; + reg = <0x00 0xff440000 0x00 0x400>; + interrupts = <0x00 0x31 0x04>; + interrupt-names = "irq_dec"; + dev_mode = <0x01>; + iommus = <0x99>; + allocator = <0x01>; + phandle = <0x9c>; + }; + + vpu_service@ff442000 { + compatible = "rockchip,vpu_sub"; + iommu_enabled = <0x01>; + reg = <0x00 0xff442000 0x00 0x800>; + interrupts = <0x00 0x50 0x04 0x00 0x4f 0x04>; + interrupt-names = "irq_enc\0irq_dec"; + dev_mode = <0x00>; + iommus = <0x9a>; + allocator = <0x01>; + phandle = <0x9b>; + }; + + vpu_combo { + compatible = "rockchip,vpu_combo"; + subcnt = <0x02>; + rockchip,grf = <0x2f>; + rockchip,sub = <0x9b 0x9c>; + clocks = <0x02 0xaf 0x02 0xf4 0x02 0x4b>; + clock-names = "aclk_vcodec\0hclk_vcodec\0clk_core"; + resets = <0x02 0x24 0x02 0x26 0x02 0x25 0x02 0x27 0x02 0x3f>; + reset-names = "video_a\0video_h\0niu_a\0niu_h\0video_core"; + power-domains = <0x8a 0x0b>; + mode_bit = <0x0f>; + mode_ctrl = <0x410>; + status = "okay"; + phandle = <0x10b>; + }; + + iommu@ff440440 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff440440 0x00 0x40 0x00 0xff440480 0x00 0x40>; + interrupts = <0x00 0x32 0x04>; + interrupt-names = "hevc_mmu"; + clocks = <0x02 0xaf 0x02 0xf4>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0b>; + #iommu-cells = <0x00>; + phandle = <0x99>; + }; + + iommu@ff442800 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff442800 0x00 0x100>; + interrupts = <0x00 0x51 0x04>; + interrupt-names = "vpu_mmu"; + clocks = <0x02 0xaf 0x02 0xf4>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0b>; + #iommu-cells = <0x00>; + phandle = <0x9a>; + }; + + dsi@ff450000 { + compatible = "rockchip,px30-mipi-dsi"; + reg = <0x00 0xff450000 0x00 0x10000>; + interrupts = <0x00 0x4b 0x04>; + clocks = <0x02 0x144 0x4c>; + clock-names = "pclk\0hs_clk"; + resets = <0x02 0x3d>; + reset-names = "apb"; + phys = <0x4c>; + phy-names = "mipi_dphy"; + power-domains = <0x8a 0x0c>; + rockchip,grf = <0x2f>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + phandle = <0x10c>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x13>; + status = "okay"; + phandle = <0xa3>; + }; + }; + }; + + panel@0 { + compatible = "elida,kd35t133\0simple-panel-dsi"; + reg = <0x00>; + backlight = <0x9d>; + backlight-supply = <0x9e>; + power-supply = <0x9f>; + reset-gpios = <0x97 0x10 0x01>; + reset-delay-ms = <0x96>; + init-delay-ms = <0x14>; + enable-delay-ms = <0x78>; + prepare-delay-ms = <0x14>; + unprepare-delay-ms = <0x14>; + disable-delay-ms = <0x32>; + width-mm = <0x34>; + height-mm = <0x46>; + dsi,flags = <0xa03>; + dsi,format = <0x00>; + dsi,lanes = <0x04>; + panel-init-sequence = [39 00 03 e0 ab ba 39 00 03 e1 ba ab 39 00 05 b1 10 01 47 ff 39 00 07 b2 0c 08 04 50 50 14 39 00 04 b3 56 12 e0 39 00 04 b4 33 30 04 39 00 08 b6 b0 00 00 10 00 10 00 39 00 06 b8 05 12 29 49 48 39 00 27 b9 7f 63 52 45 42 34 39 24 3e 3d 3c 59 46 4d 3e 3d 30 22 00 7f 63 52 45 42 34 39 24 3e 3d 3c 59 46 4d 3e 3d 30 22 00 39 00 11 c0 32 10 12 34 22 22 22 22 90 04 90 04 0f 00 00 c1 39 00 0b c1 12 9f 8e 89 90 04 90 04 54 40 39 00 0d c2 77 09 08 89 08 11 22 33 44 87 18 00 39 00 17 c3 88 4a 24 24 1e 1f 12 0c 0e 10 04 06 24 24 02 02 02 02 02 02 02 02 39 00 17 c4 09 0b 24 24 1e 1f 13 0d 0f 11 05 07 24 24 02 02 02 02 02 02 02 02 39 00 03 c6 46 55 39 00 07 c8 12 00 31 42 34 16 39 00 03 ca 18 43 39 00 09 cd 0e 64 64 2c 16 6b 06 b3 39 00 05 d2 e3 2b 38 08 39 00 0c d4 00 01 00 0e 04 44 08 10 00 00 00 39 00 09 e6 80 09 ff ff ff ff ff ff 39 00 06 f0 12 03 20 00 ff 15 00 02 f3 03 05 c8 01 11 05 14 01 29]; + panel-exit-sequence = <0x5140128 0x50a0110>; + + display-timings { + native-mode = <0xa0>; + + 60Hz { + clock-frequency = <0x1ba8140>; + hactive = <0x280>; + vactive = <0x1e0>; + hfront-porch = <0x50>; + hsync-len = <0x14>; + hback-porch = <0x50>; + vfront-porch = <0x14>; + vsync-len = <0x04>; + vback-porch = <0x0c>; + hsync-active = <0x00>; + vsync-active = <0x00>; + de-active = <0x00>; + pixelclk-active = <0x01>; + phandle = <0xa0>; + }; + + 50Hz { + clock-frequency = <0x1ba8140>; + hactive = <0x280>; + vactive = <0x1e0>; + hfront-porch = <0x50>; + hsync-len = <0x14>; + hback-porch = <0x50>; + vfront-porch = <0x14>; + vsync-len = <0x04>; + vback-porch = <0x0c>; + hsync-active = <0x00>; + vsync-active = <0x00>; + de-active = <0x00>; + pixelclk-active = <0x01>; + phandle = <0xa00>; + }; + + 75Hz { + clock-frequency = <0x1ba8140>; + hactive = <0x280>; + vactive = <0x1e0>; + hfront-porch = <0x50>; + hsync-len = <0x14>; + hback-porch = <0x50>; + vfront-porch = <0x14>; + vsync-len = <0x04>; + vback-porch = <0x0c>; + hsync-active = <0x00>; + vsync-active = <0x00>; + de-active = <0x00>; + pixelclk-active = <0x01>; + phandle = <0xa01>; + }; + }; + }; + }; + + vop@ff460000 { + compatible = "rockchip,px30-vop-big"; + reg = <0x00 0xff460000 0x00 0x1fc 0x00 0xff460a00 0x00 0x400>; + rockchip,grf = <0x2f>; + reg-names = "regs\0gamma_lut"; + interrupts = <0x00 0x4d 0x04>; + clocks = <0x02 0xb5 0x02 0x96 0x02 0xfb>; + clock-names = "aclk_vop\0dclk_vop\0hclk_vop"; + power-domains = <0x8a 0x0c>; + iommus = <0xa1>; + status = "okay"; + phandle = <0x10f>; + + port { + #address-cells = <0x01>; + #size-cells = <0x00>; + phandle = <0x10>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0xa2>; + phandle = <0x12>; + }; + + endpoint@1 { + reg = <0x01>; + remote-endpoint = <0xa3>; + phandle = <0x13>; + }; + + endpoint@2 { + reg = <0x02>; + remote-endpoint = <0xa4>; + phandle = <0x14>; + }; + }; + }; + + iommu@ff460f00 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff460f00 0x00 0x100>; + interrupts = <0x00 0x4d 0x04>; + interrupt-names = "vopb_mmu"; + clocks = <0x02 0xb5 0x02 0xfb>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0c>; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xa1>; + }; + + rk_rga@ff480000 { + compatible = "rockchip,rga2"; + reg = <0x00 0xff480000 0x00 0x1000>; + interrupts = <0x00 0x4c 0x04>; + clocks = <0x02 0xb7 0x02 0xfd 0x02 0x35>; + clock-names = "aclk_rga\0hclk_rga\0clk_rga"; + power-domains = <0x8a 0x0c>; + dma-coherent; + status = "okay"; + phandle = <0x110>; + }; + + cif@ff490000 { + compatible = "rockchip,cif"; + reg = <0x00 0xff490000 0x00 0x200>; + interrupts = <0x00 0x45 0x04>; + clocks = <0x02 0xb3 0x02 0xf9 0x02 0x160 0x02 0x34>; + clock-names = "aclk_cif0\0hclk_cif0\0pclk_cif\0cif0_out"; + resets = <0x02 0x2c 0x02 0x2d 0x02 0x2e>; + reset-names = "rst_cif_a\0rst_cif_h\0rst_cif_pclkin"; + power-domains = <0x8a 0x0d>; + pinctrl-names = "cif_pin_all"; + pinctrl-0 = <0xa5>; + iommus = <0xa6>; + status = "disabled"; + phandle = <0x111>; + }; + + cif-new@ff490000 { + compatible = "rockchip,px30-cif"; + reg = <0x00 0xff490000 0x00 0x200>; + interrupts = <0x00 0x45 0x04>; + clocks = <0x02 0xb3 0x02 0xf9 0x02 0x160 0x02 0x34>; + clock-names = "aclk_cif\0hclk_cif\0pclk_cif\0cif_out"; + resets = <0x02 0x2c 0x02 0x2d 0x02 0x2e>; + reset-names = "rst_cif_a\0rst_cif_h\0rst_cif_pclkin"; + power-domains = <0x8a 0x0d>; + iommus = <0xa6>; + status = "disabled"; + phandle = <0x112>; + }; + + iommu@ff490800 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff490800 0x00 0x100>; + interrupts = <0x00 0x45 0x04>; + interrupt-names = "vip_mmu"; + clocks = <0x02 0xb3 0x02 0xf9>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0d>; + rk_iommu,disable_reset_quirk; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xa6>; + }; + + rk_isp@ff4a0000 { + compatible = "rockchip,px30-isp\0rockchip,isp"; + reg = <0x00 0xff4a0000 0x00 0x8000>; + interrupts = <0x00 0x46 0x04>; + clocks = <0x02 0xb4 0x02 0xfa 0x02 0x33 0x02 0x33 0x02 0x15f 0x02 0x34 0x02 0x34 0x02 0x146>; + clock-names = "aclk_isp\0hclk_isp\0clk_isp\0clk_isp_jpe\0pclkin_isp\0clk_cif_pll\0clk_cif_out\0pclk_dphyrx"; + resets = <0x02 0x2b 0x02 0x2f>; + reset-names = "rst_isp\0rst_mipicsiphy"; + power-domains = <0x8a 0x0d>; + pinctrl-names = "default\0isp_dvp8bit2\0isp_dvp10bit\0isp_dvp12bit"; + pinctrl-0 = <0xa7>; + pinctrl-1 = <0xa5>; + pinctrl-2 = <0xa5 0xa8>; + pinctrl-3 = <0xa9 0xa5 0xa8>; + rockchip,isp,mipiphy = <0x01>; + rockchip,isp,csiphy,reg = <0xff2f0000 0x4000>; + rockchip,grf = <0x2f>; + rockchip,cru = <0x02>; + rockchip,isp,iommu-enable = <0x01>; + iommus = <0xaa>; + status = "disabled"; + phandle = <0x113>; + }; + + rkisp1@ff4a0000 { + compatible = "rockchip,rk3326-rkisp1"; + reg = <0x00 0xff4a0000 0x00 0x8000>; + interrupts = <0x00 0x46 0x04 0x00 0x49 0x04 0x00 0x4a 0x04>; + interrupt-names = "isp_irq\0mi_irq\0mipi_irq"; + clocks = <0x02 0xb4 0x02 0xfa 0x02 0x33 0x02 0x15f>; + clock-names = "aclk_isp\0hclk_isp\0clk_isp\0pclk_isp"; + devfreq = <0xab>; + power-domains = <0x8a 0x0d>; + iommus = <0xaa>; + rockchip,grf = <0x2f>; + status = "okay"; + phandle = <0x114>; + }; + + iommu@ff4a8000 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff4a8000 0x00 0x100>; + interrupts = <0x00 0x46 0x04>; + interrupt-names = "isp_mmu"; + clocks = <0x02 0xb4 0x02 0xfa>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0d>; + rk_iommu,disable_reset_quirk; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xaa>; + }; + + qos@ff518000 { + compatible = "syscon"; + reg = <0x00 0xff518000 0x00 0x20>; + phandle = <0x18>; + }; + + qos@ff520000 { + compatible = "syscon"; + reg = <0x00 0xff520000 0x00 0x20>; + phandle = <0x28>; + }; + + qos@ff52c000 { + compatible = "syscon"; + reg = <0x00 0xff52c000 0x00 0x20>; + phandle = <0x17>; + }; + + qos@ff538000 { + compatible = "syscon"; + reg = <0x00 0xff538000 0x00 0x20>; + phandle = <0x19>; + }; + + qos@ff538080 { + compatible = "syscon"; + reg = <0x00 0xff538080 0x00 0x20>; + phandle = <0x1a>; + }; + + qos@ff538100 { + compatible = "syscon"; + reg = <0x00 0xff538100 0x00 0x20>; + phandle = <0x1b>; + }; + + qos@ff538180 { + compatible = "syscon"; + reg = <0x00 0xff538180 0x00 0x20>; + phandle = <0x1c>; + }; + + qos@ff540000 { + compatible = "syscon"; + reg = <0x00 0xff540000 0x00 0x20>; + phandle = <0x15>; + }; + + qos@ff540080 { + compatible = "syscon"; + reg = <0x00 0xff540080 0x00 0x20>; + phandle = <0x16>; + }; + + qos@ff548000 { + compatible = "syscon"; + reg = <0x00 0xff548000 0x00 0x20>; + phandle = <0x23>; + }; + + qos@ff548080 { + compatible = "syscon"; + reg = <0x00 0xff548080 0x00 0x20>; + phandle = <0x24>; + }; + + qos@ff548100 { + compatible = "syscon"; + reg = <0x00 0xff548100 0x00 0x20>; + phandle = <0x25>; + }; + + qos@ff548180 { + compatible = "syscon"; + reg = <0x00 0xff548180 0x00 0x20>; + phandle = <0x26>; + }; + + qos@ff548200 { + compatible = "syscon"; + reg = <0x00 0xff548200 0x00 0x20>; + phandle = <0x27>; + }; + + qos@ff550000 { + compatible = "syscon"; + reg = <0x00 0xff550000 0x00 0x20>; + phandle = <0x1f>; + }; + + qos@ff550080 { + compatible = "syscon"; + reg = <0x00 0xff550080 0x00 0x20>; + phandle = <0x20>; + }; + + qos@ff550100 { + compatible = "syscon"; + reg = <0x00 0xff550100 0x00 0x20>; + phandle = <0x21>; + }; + + qos@ff550180 { + compatible = "syscon"; + reg = <0x00 0xff550180 0x00 0x20>; + phandle = <0x22>; + }; + + qos@ff558000 { + compatible = "syscon"; + reg = <0x00 0xff558000 0x00 0x20>; + phandle = <0x1d>; + }; + + qos@ff558080 { + compatible = "syscon"; + reg = <0x00 0xff558080 0x00 0x20>; + phandle = <0x1e>; + }; + + dfi@ff610000 { + reg = <0x00 0xff610000 0x00 0x400>; + compatible = "rockchip,px30-dfi"; + rockchip,pmugrf = <0xac>; + status = "okay"; + phandle = <0xad>; + }; + + dmc { + compatible = "rockchip,px30-dmc"; + interrupts = <0x00 0x69 0x04>; + interrupt-names = "complete_irq"; + devfreq-events = <0xad>; + clocks = <0x02 0x54>; + clock-names = "dmc_clk"; + operating-points-v2 = <0xae>; + ddr_timing = <0xaf>; + upthreshold = <0x28>; + downdifferential = <0x14>; + system-status-freq = <0x01 0x80e80 0x08 0x6ddd0 0x02 0x2f5d0 0x20 0x6ddd0 0x1000 0x80e80 0x4000 0xa2990 0x2000 0xa2990>; + auto-min-freq = <0x50140>; + auto-freq-en = <0x01>; + #cooling-cells = <0x02>; + status = "okay"; + center-supply = <0x0e>; + phandle = <0xab>; + + ddr_power_model { + compatible = "ddr_power_model"; + dynamic-power-coefficient = <0x78>; + static-power-coefficient = <0xc8>; + ts = <0x7d00 0x125c 0xffffffb0 0x02>; + thermal-zone = "soc-thermal"; + phandle = <0x115>; + }; + }; + + dmc-opp-table { + compatible = "operating-points-v2"; + rockchip,max-volt = <0x118c30>; + rockchip,evb-irdrop = <0x61a8>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-ch = <0x00 0x00>; + phandle = <0xae>; + + opp-528000000 { + opp-hz = <0x00 0x1f78a400>; + opp-microvolt = <0xee098>; + opp-microvolt-L0 = <0xee098>; + opp-microvolt-L1 = <0xee098>; + opp-microvolt-L2 = <0xe7ef0>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-666000000 { + opp-hz = <0x00 0x27b25a80>; + opp-microvolt = <0x100590>; + opp-microvolt-L0 = <0x100590>; + opp-microvolt-L1 = <0xf4240>; + opp-microvolt-L2 = <0xee098>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-786000000 { + opp-hz = <0x00 0x2ed96880>; + opp-microvolt = <0x10c8e0>; + opp-microvolt-L0 = <0x10c8e0>; + opp-microvolt-L1 = <0x100590>; + opp-microvolt-L2 = <0xfa3e8>; + opp-microvolt-L3 = <0xf4240>; + status = "okay"; + }; + }; + + rockchip-system-monitor { + compatible = "rockchip,system-monitor"; + rockchip,thermal-zone = "soc-thermal"; + rockchip,polling-delay = <0xc8>; + phandle = <0x116>; + }; + + pinctrl { + compatible = "rockchip,px30-pinctrl"; + rockchip,grf = <0x2f>; + rockchip,pmu = <0xac>; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + phandle = <0x117>; + + gpio0@ff040000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff040000 0x00 0x100>; + interrupts = <0x00 0x03 0x04>; + clocks = <0x2a 0x14>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x5c>; + }; + + gpio1@ff250000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff250000 0x00 0x100>; + interrupts = <0x00 0x04 0x04>; + clocks = <0x02 0x15c>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0xbf>; + }; + + gpio2@ff260000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff260000 0x00 0x100>; + interrupts = <0x00 0x05 0x04>; + clocks = <0x02 0x15d>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x66>; + }; + + gpio3@ff270000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff270000 0x00 0x100>; + interrupts = <0x00 0x06 0x04>; + clocks = <0x02 0x15e>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x97>; + }; + + pcfg-pull-up { + bias-pull-up; + phandle = <0xb2>; + }; + + pcfg-pull-down { + bias-pull-down; + phandle = <0x118>; + }; + + pcfg-pull-none { + bias-disable; + phandle = <0xb1>; + }; + + pcfg-pull-none-2ma { + bias-disable; + drive-strength = <0x02>; + phandle = <0x119>; + }; + + pcfg-pull-up-2ma { + bias-pull-up; + drive-strength = <0x02>; + phandle = <0x11a>; + }; + + pcfg-pull-up-4ma { + bias-pull-up; + drive-strength = <0x04>; + phandle = <0xb3>; + }; + + pcfg-pull-none-4ma { + bias-disable; + drive-strength = <0x04>; + phandle = <0x11b>; + }; + + pcfg-pull-down-4ma { + bias-pull-down; + drive-strength = <0x04>; + phandle = <0x11c>; + }; + + pcfg-pull-none-8ma { + bias-disable; + drive-strength = <0x08>; + phandle = <0xb6>; + }; + + pcfg-pull-up-8ma { + bias-pull-up; + drive-strength = <0x08>; + phandle = <0xb4>; + }; + + pcfg-pull-none-12ma { + bias-disable; + drive-strength = <0x0c>; + phandle = <0xb8>; + }; + + pcfg-pull-up-12ma { + bias-pull-up; + drive-strength = <0x0c>; + phandle = <0xb7>; + }; + + pcfg-pull-none-smt { + bias-disable; + input-schmitt-enable; + phandle = <0xb0>; + }; + + pcfg-output-high { + output-high; + phandle = <0x11d>; + }; + + pcfg-output-low { + output-low; + phandle = <0xb9>; + }; + + pcfg-input-high { + bias-pull-up; + input-enable; + phandle = <0xb5>; + }; + + pcfg-input { + input-enable; + phandle = <0x11e>; + }; + + i2c0 { + + i2c0-xfer { + rockchip,pins = <0x00 0x08 0x01 0xb0 0x00 0x09 0x01 0xb0>; + phandle = <0x5b>; + }; + }; + + i2c1 { + + i2c1-xfer { + rockchip,pins = <0x00 0x12 0x01 0xb0 0x00 0x13 0x01 0xb0>; + phandle = <0x69>; + }; + }; + + i2c2 { + + i2c2-xfer { + rockchip,pins = <0x02 0x0f 0x02 0xb0 0x02 0x10 0x02 0xb0>; + phandle = <0x6a>; + }; + }; + + i2c3 { + + i2c3-xfer { + rockchip,pins = <0x01 0x0c 0x04 0xb0 0x01 0x0d 0x04 0xb0>; + phandle = <0x6b>; + }; + }; + + tsadc { + + tsadc-otp-gpio { + rockchip,pins = <0x00 0x06 0x00 0xb1>; + phandle = <0x86>; + }; + + tsadc-otp-out { + rockchip,pins = <0x00 0x06 0x01 0xb1>; + phandle = <0x87>; + }; + }; + + uart0 { + + uart0-xfer { + rockchip,pins = <0x00 0x0a 0x01 0xb2 0x00 0x0b 0x01 0xb2>; + phandle = <0x2c>; + }; + + uart0-cts { + rockchip,pins = <0x00 0x0c 0x01 0xb1>; + phandle = <0x2d>; + }; + + uart0-rts { + rockchip,pins = <0x00 0x0d 0x01 0xb1>; + phandle = <0x2e>; + }; + + uart0-rts-gpio { + rockchip,pins = <0x00 0x0d 0x00 0xb1>; + phandle = <0x11f>; + }; + }; + + uart1 { + + uart1-xfer { + rockchip,pins = <0x01 0x11 0x01 0xb2 0x01 0x10 0x01 0xb2>; + phandle = <0x4f>; + }; + + uart1-cts { + rockchip,pins = <0x01 0x12 0x01 0xb1>; + phandle = <0x50>; + }; + + uart1-rts { + rockchip,pins = <0x01 0x13 0x01 0xb1>; + phandle = <0x120>; + }; + + uart1-rts-gpio { + rockchip,pins = <0x01 0x13 0x00 0xb1>; + phandle = <0x121>; + }; + }; + + uart2-m0 { + + uart2m0-xfer { + rockchip,pins = <0x01 0x1a 0x02 0xb2 0x01 0x1b 0x02 0xb2>; + phandle = <0x51>; + }; + }; + + uart2-m1 { + + uart2m1-xfer { + rockchip,pins = <0x02 0x0c 0x02 0xb2 0x02 0x0e 0x02 0xb2>; + phandle = <0xba>; + }; + }; + + uart3-m0 { + + uart3m0-xfer { + rockchip,pins = <0x00 0x10 0x02 0xb2 0x00 0x11 0x02 0xb2>; + phandle = <0x122>; + }; + + uart3m0-cts { + rockchip,pins = <0x00 0x12 0x02 0xb1>; + phandle = <0x123>; + }; + + uart3m0-rts { + rockchip,pins = <0x00 0x13 0x02 0xb1>; + phandle = <0x124>; + }; + + uart3m0-rts-gpio { + rockchip,pins = <0x00 0x13 0x00 0xb1>; + phandle = <0x125>; + }; + }; + + uart3-m1 { + + uart3m1-xfer { + rockchip,pins = <0x01 0x0e 0x02 0xb2 0x01 0x0f 0x02 0xb2>; + phandle = <0x52>; + }; + + uart3m1-cts { + rockchip,pins = <0x01 0x0c 0x02 0xb1>; + phandle = <0x53>; + }; + + uart3m1-rts { + rockchip,pins = <0x01 0x0d 0x02 0xb1>; + phandle = <0x54>; + }; + + uart3m1-rts-gpio { + rockchip,pins = <0x01 0x0d 0x00 0xb1>; + phandle = <0x126>; + }; + }; + + uart4 { + + uart4-xfer { + rockchip,pins = <0x01 0x1c 0x02 0xb2 0x01 0x1d 0x02 0xb2>; + phandle = <0x55>; + }; + + uart4-cts { + rockchip,pins = <0x01 0x1e 0x02 0xb1>; + phandle = <0x56>; + }; + + uart4-rts { + rockchip,pins = <0x01 0x1f 0x02 0xb1>; + phandle = <0x57>; + }; + }; + + uart5 { + + uart5-xfer { + rockchip,pins = <0x03 0x02 0x04 0xb2 0x03 0x01 0x04 0xb2>; + phandle = <0x58>; + }; + + uart5-cts { + rockchip,pins = <0x03 0x03 0x04 0xb1>; + phandle = <0x59>; + }; + + uart5-rts { + rockchip,pins = <0x03 0x05 0x04 0xb1>; + phandle = <0x5a>; + }; + }; + + spi0 { + + spi0-clk { + rockchip,pins = <0x01 0x0f 0x03 0xb3>; + phandle = <0x6c>; + }; + + spi0-csn { + rockchip,pins = <0x01 0x0e 0x03 0xb3>; + phandle = <0x6d>; + }; + + spi0-miso { + rockchip,pins = <0x01 0x0d 0x03 0xb3>; + phandle = <0x6e>; + }; + + spi0-mosi { + rockchip,pins = <0x01 0x0c 0x03 0xb3>; + phandle = <0x6f>; + }; + + spi0-clk-hs { + rockchip,pins = <0x01 0x0f 0x03 0xb4>; + phandle = <0x70>; + }; + + spi0-miso-hs { + rockchip,pins = <0x01 0x0d 0x03 0xb4>; + phandle = <0x71>; + }; + + spi0-mosi-hs { + rockchip,pins = <0x01 0x0c 0x03 0xb4>; + phandle = <0x72>; + }; + }; + + spi1 { + + spi1-clk { + rockchip,pins = <0x03 0x0f 0x04 0xb3>; + phandle = <0x73>; + }; + + spi1-csn0 { + rockchip,pins = <0x03 0x09 0x04 0xb3>; + phandle = <0x74>; + }; + + spi1-csn1 { + rockchip,pins = <0x03 0x0a 0x02 0xb3>; + phandle = <0x75>; + }; + + spi1-miso { + rockchip,pins = <0x03 0x0e 0x04 0xb3>; + phandle = <0x76>; + }; + + spi1-mosi { + rockchip,pins = <0x03 0x0c 0x04 0xb3>; + phandle = <0x77>; + }; + + spi1-clk-hs { + rockchip,pins = <0x03 0x0f 0x04 0xb4>; + phandle = <0x78>; + }; + + spi1-miso-hs { + rockchip,pins = <0x03 0x0e 0x04 0xb4>; + phandle = <0x79>; + }; + + spi1-mosi-hs { + rockchip,pins = <0x03 0x0c 0x04 0xb4>; + phandle = <0x7a>; + }; + }; + + pdm { + + pdm-clk0m0 { + rockchip,pins = <0x03 0x16 0x02 0xb1>; + phandle = <0x44>; + }; + + pdm-clk0m1 { + rockchip,pins = <0x02 0x16 0x01 0xb1>; + phandle = <0x127>; + }; + + pdm-clk1 { + rockchip,pins = <0x03 0x17 0x02 0xb1>; + phandle = <0x45>; + }; + + pdm-sdi0m0 { + rockchip,pins = <0x03 0x1b 0x02 0xb1>; + phandle = <0x46>; + }; + + pdm-sdi0m1 { + rockchip,pins = <0x02 0x15 0x02 0xb1>; + phandle = <0x128>; + }; + + pdm-sdi1 { + rockchip,pins = <0x03 0x18 0x02 0xb1>; + phandle = <0x47>; + }; + + pdm-sdi2 { + rockchip,pins = <0x03 0x19 0x02 0xb1>; + phandle = <0x48>; + }; + + pdm-sdi3 { + rockchip,pins = <0x03 0x1a 0x02 0xb1>; + phandle = <0x49>; + }; + + pdm-clk0m0-sleep { + rockchip,pins = <0x03 0x16 0x00 0xb5>; + phandle = <0x129>; + }; + + pdm-clk0m1-sleep { + rockchip,pins = <0x02 0x16 0x00 0xb5>; + phandle = <0x12a>; + }; + + pdm-clk1-sleep { + rockchip,pins = <0x03 0x17 0x00 0xb5>; + phandle = <0x12b>; + }; + + pdm-sdi0m0-sleep { + rockchip,pins = <0x03 0x1b 0x00 0xb5>; + phandle = <0x12c>; + }; + + pdm-sdi0m1-sleep { + rockchip,pins = <0x02 0x15 0x00 0xb5>; + phandle = <0x12d>; + }; + + pdm-sdi1-sleep { + rockchip,pins = <0x03 0x18 0x00 0xb5>; + phandle = <0x12e>; + }; + + pdm-sdi2-sleep { + rockchip,pins = <0x03 0x19 0x00 0xb5>; + phandle = <0x12f>; + }; + + pdm-sdi3-sleep { + rockchip,pins = <0x03 0x1a 0x00 0xb5>; + phandle = <0x130>; + }; + }; + + i2s0 { + + i2s0-8ch-mclk { + rockchip,pins = <0x03 0x11 0x02 0xb1>; + phandle = <0x131>; + }; + + i2s0-8ch-sclktx { + rockchip,pins = <0x03 0x13 0x02 0xb1>; + phandle = <0x30>; + }; + + i2s0-8ch-sclkrx { + rockchip,pins = <0x03 0x0c 0x02 0xb1>; + phandle = <0x31>; + }; + + i2s0-8ch-lrcktx { + rockchip,pins = <0x03 0x12 0x02 0xb1>; + phandle = <0x32>; + }; + + i2s0-8ch-lrckrx { + rockchip,pins = <0x03 0x0d 0x02 0xb1>; + phandle = <0x33>; + }; + + i2s0-8ch-sdo0 { + rockchip,pins = <0x03 0x14 0x02 0xb1>; + phandle = <0x38>; + }; + + i2s0-8ch-sdo1 { + rockchip,pins = <0x03 0x10 0x02 0xb1>; + phandle = <0x39>; + }; + + i2s0-8ch-sdo2 { + rockchip,pins = <0x03 0x0f 0x02 0xb1>; + phandle = <0x3a>; + }; + + i2s0-8ch-sdo3 { + rockchip,pins = <0x03 0x0e 0x02 0xb1>; + phandle = <0x3b>; + }; + + i2s0-8ch-sdi0 { + rockchip,pins = <0x03 0x15 0x02 0xb1>; + phandle = <0x34>; + }; + + i2s0-8ch-sdi1 { + rockchip,pins = <0x03 0x0b 0x02 0xb1>; + phandle = <0x35>; + }; + + i2s0-8ch-sdi2 { + rockchip,pins = <0x03 0x09 0x02 0xb1>; + phandle = <0x36>; + }; + + i2s0-8ch-sdi3 { + rockchip,pins = <0x03 0x08 0x02 0xb1>; + phandle = <0x37>; + }; + }; + + i2s1 { + + i2s1-2ch-mclk { + rockchip,pins = <0x02 0x13 0x01 0xb1>; + phandle = <0x68>; + }; + + i2s1-2ch-sclk { + rockchip,pins = <0x02 0x12 0x01 0xb1>; + phandle = <0x3c>; + }; + + i2s1-2ch-lrck { + rockchip,pins = <0x02 0x11 0x01 0xb1>; + phandle = <0x3d>; + }; + + i2s1-2ch-sdi { + rockchip,pins = <0x02 0x15 0x01 0xb1>; + phandle = <0x3e>; + }; + + i2s1-2ch-sdo { + rockchip,pins = <0x02 0x14 0x01 0xb1>; + phandle = <0x3f>; + }; + }; + + i2s2 { + + i2s2-2ch-mclk { + rockchip,pins = <0x03 0x01 0x02 0xb1>; + phandle = <0x132>; + }; + + i2s2-2ch-sclk { + rockchip,pins = <0x03 0x02 0x02 0xb1>; + phandle = <0x40>; + }; + + i2s2-2ch-lrck { + rockchip,pins = <0x03 0x03 0x02 0xb1>; + phandle = <0x41>; + }; + + i2s2-2ch-sdi { + rockchip,pins = <0x03 0x05 0x02 0xb1>; + phandle = <0x42>; + }; + + i2s2-2ch-sdo { + rockchip,pins = <0x03 0x07 0x02 0xb1>; + phandle = <0x43>; + }; + }; + + sdmmc { + + sdmmc-clk { + rockchip,pins = <0x01 0x1e 0x01 0xb6>; + phandle = <0x8f>; + }; + + sdmmc-cmd { + rockchip,pins = <0x01 0x1f 0x01 0xb4>; + phandle = <0x90>; + }; + + sdmmc-det { + rockchip,pins = <0x00 0x03 0x01 0xb4>; + phandle = <0x91>; + }; + + sdmmc-bus1 { + rockchip,pins = <0x01 0x1a 0x01 0xb4>; + phandle = <0x133>; + }; + + sdmmc-bus4 { + rockchip,pins = <0x01 0x1a 0x01 0xb4 0x01 0x1b 0x01 0xb4 0x01 0x1c 0x01 0xb4 0x01 0x1d 0x01 0xb4>; + phandle = <0x92>; + }; + + sdmmc-gpio { + rockchip,pins = <0x01 0x1a 0x00 0xb3 0x01 0x1b 0x00 0xb3 0x01 0x1c 0x00 0xb3 0x01 0x1d 0x00 0xb3 0x01 0x1e 0x00 0xb3 0x01 0x1f 0x00 0xb3>; + phandle = <0x134>; + }; + }; + + sdio { + + sdio-clk { + rockchip,pins = <0x01 0x15 0x01 0xb1>; + phandle = <0x96>; + }; + + sdio-cmd { + rockchip,pins = <0x01 0x14 0x01 0xb2>; + phandle = <0x95>; + }; + + sdio-bus4 { + rockchip,pins = <0x01 0x16 0x01 0xb2 0x01 0x17 0x01 0xb2 0x01 0x18 0x01 0xb2 0x01 0x19 0x01 0xb2>; + phandle = <0x94>; + }; + + sdio-gpio { + rockchip,pins = <0x01 0x16 0x00 0xb2 0x01 0x17 0x00 0xb2 0x01 0x18 0x00 0xb2 0x01 0x19 0x00 0xb2 0x01 0x14 0x00 0xb2 0x01 0x15 0x00 0xb2>; + phandle = <0x135>; + }; + }; + + emmc { + + emmc-clk { + rockchip,pins = <0x01 0x09 0x02 0xb6>; + phandle = <0x136>; + }; + + emmc-cmd { + rockchip,pins = <0x01 0x0a 0x02 0xb4>; + phandle = <0x137>; + }; + + emmc-pwren { + rockchip,pins = <0x01 0x08 0x02 0xb1>; + phandle = <0x138>; + }; + + emmc-rstnout { + rockchip,pins = <0x01 0x0b 0x02 0xb1>; + phandle = <0x139>; + }; + + emmc-bus1 { + rockchip,pins = <0x01 0x00 0x02 0xb4>; + phandle = <0x13a>; + }; + + emmc-bus4 { + rockchip,pins = <0x01 0x00 0x02 0xb4 0x01 0x01 0x02 0xb4 0x01 0x02 0x02 0xb4 0x01 0x03 0x02 0xb4>; + phandle = <0x13b>; + }; + + emmc-bus8 { + rockchip,pins = <0x01 0x00 0x02 0xb4 0x01 0x01 0x02 0xb4 0x01 0x02 0x02 0xb4 0x01 0x03 0x02 0xb4 0x01 0x04 0x02 0xb4 0x01 0x05 0x02 0xb4 0x01 0x06 0x02 0xb4 0x01 0x07 0x02 0xb4>; + phandle = <0x13c>; + }; + }; + + flash { + + flash-cs0 { + rockchip,pins = <0x01 0x08 0x01 0xb1>; + phandle = <0x13d>; + }; + + flash-rdy { + rockchip,pins = <0x01 0x09 0x01 0xb1>; + phandle = <0x13e>; + }; + + flash-dqs { + rockchip,pins = <0x01 0x0a 0x01 0xb1>; + phandle = <0x13f>; + }; + + flash-ale { + rockchip,pins = <0x01 0x0b 0x01 0xb1>; + phandle = <0x140>; + }; + + flash-cle { + rockchip,pins = <0x01 0x0c 0x01 0xb1>; + phandle = <0x141>; + }; + + flash-wrn { + rockchip,pins = <0x01 0x0d 0x01 0xb1>; + phandle = <0x142>; + }; + + flash-csl { + rockchip,pins = <0x01 0x0e 0x01 0xb1>; + phandle = <0x143>; + }; + + flash-rdn { + rockchip,pins = <0x01 0x0f 0x01 0xb1>; + phandle = <0x144>; + }; + + flash-bus8 { + rockchip,pins = <0x01 0x00 0x01 0xb7 0x01 0x01 0x01 0xb7 0x01 0x02 0x01 0xb7 0x01 0x03 0x01 0xb7 0x01 0x04 0x01 0xb7 0x01 0x05 0x01 0xb7 0x01 0x06 0x01 0xb7 0x01 0x07 0x01 0xb7>; + phandle = <0x145>; + }; + }; + + lcdc { + + lcdc-m0-rgb-pins { + rockchip,pins = <0x03 0x00 0x01 0xb6 0x03 0x01 0x01 0xb6 0x03 0x02 0x01 0xb6 0x03 0x03 0x01 0xb6 0x03 0x04 0x01 0xb6 0x03 0x05 0x01 0xb6 0x03 0x06 0x01 0xb6 0x03 0x07 0x01 0xb6 0x03 0x08 0x01 0xb6 0x03 0x09 0x01 0xb6 0x03 0x0a 0x01 0xb6 0x03 0x0b 0x01 0xb6 0x03 0x0c 0x01 0xb6 0x03 0x0d 0x01 0xb6 0x03 0x0e 0x01 0xb6 0x03 0x0f 0x01 0xb6 0x03 0x10 0x01 0xb6 0x03 0x11 0x01 0xb6 0x03 0x12 0x01 0xb6 0x03 0x13 0x01 0xb6 0x03 0x14 0x01 0xb6 0x03 0x15 0x01 0xb6 0x03 0x16 0x01 0xb6 0x03 0x17 0x01 0xb6 0x03 0x18 0x01 0xb6 0x03 0x19 0x01 0xb6 0x03 0x1a 0x01 0xb6 0x03 0x1b 0x01 0xb6>; + phandle = <0x146>; + }; + + lcdc-m0-sleep-pins { + rockchip,pins = <0x03 0x00 0x00 0xb1 0x03 0x01 0x00 0xb1 0x03 0x02 0x00 0xb1 0x03 0x03 0x00 0xb1 0x03 0x04 0x00 0xb1 0x03 0x05 0x00 0xb1 0x03 0x06 0x00 0xb1 0x03 0x07 0x00 0xb1 0x03 0x08 0x00 0xb1 0x03 0x09 0x00 0xb1 0x03 0x0a 0x00 0xb1 0x03 0x0b 0x00 0xb1 0x03 0x0c 0x00 0xb1 0x03 0x0d 0x00 0xb1 0x03 0x0e 0x00 0xb1 0x03 0x0f 0x00 0xb1 0x03 0x10 0x00 0xb1 0x03 0x11 0x00 0xb1 0x03 0x12 0x00 0xb1 0x03 0x13 0x00 0xb1 0x03 0x14 0x00 0xb1 0x03 0x15 0x00 0xb1 0x03 0x16 0x00 0xb1 0x03 0x17 0x00 0xb1 0x03 0x18 0x00 0xb1 0x03 0x19 0x00 0xb1 0x03 0x1a 0x00 0xb1 0x03 0x1b 0x00 0xb1>; + phandle = <0x147>; + }; + + lcdc-m1-rgb-pins { + rockchip,pins = <0x03 0x00 0x01 0xb6 0x03 0x04 0x01 0xb6 0x03 0x06 0x01 0xb6 0x03 0x0a 0x01 0xb6 0x03 0x0b 0x01 0xb6 0x03 0x0d 0x01 0xb6 0x03 0x10 0x01 0xb6 0x03 0x11 0x01 0xb6 0x03 0x12 0x01 0xb6 0x03 0x13 0x01 0xb6 0x03 0x14 0x01 0xb6 0x03 0x15 0x01 0xb6 0x03 0x16 0x01 0xb6 0x03 0x17 0x01 0xb6 0x03 0x18 0x01 0xb6 0x03 0x19 0x01 0xb6 0x03 0x1a 0x01 0xb6 0x03 0x1b 0x01 0xb6>; + phandle = <0x4d>; + }; + + lcdc-m1-sleep-pins { + rockchip,pins = <0x03 0x00 0x00 0xb1 0x03 0x04 0x00 0xb1 0x03 0x06 0x00 0xb1 0x03 0x0a 0x00 0xb1 0x03 0x0b 0x00 0xb1 0x03 0x0d 0x00 0xb1 0x03 0x10 0x00 0xb1 0x03 0x11 0x00 0xb1 0x03 0x12 0x00 0xb1 0x03 0x13 0x00 0xb1 0x03 0x14 0x00 0xb1 0x03 0x15 0x00 0xb1 0x03 0x16 0x00 0xb1 0x03 0x17 0x00 0xb1 0x03 0x18 0x00 0xb1 0x03 0x19 0x00 0xb1 0x03 0x1a 0x00 0xb1 0x03 0x1b 0x00 0xb1>; + phandle = <0x4e>; + }; + }; + + pwm0 { + + pwm0-pin { + rockchip,pins = <0x00 0x0f 0x01 0xb1>; + phandle = <0x7b>; + }; + }; + + pwm1 { + + pwm1-pin { + rockchip,pins = <0x00 0x10 0x01 0xb1>; + phandle = <0x7c>; + }; + }; + + pwm2 { + + pwm2-pin { + rockchip,pins = <0x02 0x0d 0x01 0xb1>; + phandle = <0x7d>; + }; + }; + + pwm3 { + + pwm3-pin { + rockchip,pins = <0x00 0x11 0x01 0xb1>; + phandle = <0x7e>; + }; + }; + + pwm4 { + + pwm4-pin { + rockchip,pins = <0x03 0x12 0x03 0xb1>; + phandle = <0x7f>; + }; + }; + + pwm5 { + + pwm5-pin { + rockchip,pins = <0x03 0x13 0x03 0xb1>; + phandle = <0x80>; + }; + }; + + pwm6 { + + pwm6-pin { + rockchip,pins = <0x03 0x14 0x03 0xb1>; + phandle = <0x81>; + }; + }; + + pwm7 { + + pwm7-pin { + rockchip,pins = <0x03 0x15 0x03 0xb1>; + phandle = <0x82>; + }; + }; + + gmac { + + rmii-pins { + rockchip,pins = <0x02 0x00 0x02 0xb8 0x02 0x01 0x02 0xb8 0x02 0x02 0x02 0xb8 0x02 0x03 0x02 0xb1 0x02 0x04 0x02 0xb1 0x02 0x05 0x02 0xb1 0x02 0x06 0x02 0xb1 0x02 0x07 0x02 0xb1 0x02 0x09 0x02 0xb1>; + phandle = <0x8d>; + }; + + mac-refclk-12ma { + rockchip,pins = <0x02 0x0a 0x02 0xb8>; + phandle = <0x8e>; + }; + + mac-refclk { + rockchip,pins = <0x02 0x0a 0x02 0xb1>; + phandle = <0x148>; + }; + }; + + cif-m0 { + + cif-clkout-m0 { + rockchip,pins = <0x02 0x0b 0x01 0xb8>; + phandle = <0xa7>; + }; + + dvp-d2d9-m0 { + rockchip,pins = <0x02 0x00 0x01 0xb1 0x02 0x01 0x01 0xb1 0x02 0x02 0x01 0xb1 0x02 0x03 0x01 0xb1 0x02 0x04 0x01 0xb1 0x02 0x05 0x01 0xb1 0x02 0x06 0x01 0xb1 0x02 0x07 0x01 0xb1 0x02 0x08 0x01 0xb1 0x02 0x09 0x01 0xb1 0x02 0x0a 0x01 0xb1 0x02 0x0b 0x01 0xb1>; + phandle = <0xa5>; + }; + + dvp-d0d1-m0 { + rockchip,pins = <0x02 0x0c 0x01 0xb1 0x02 0x0e 0x01 0xb1>; + phandle = <0xa9>; + }; + + d10-d11-m0 { + rockchip,pins = <0x02 0x0f 0x01 0xb1 0x02 0x10 0x01 0xb1>; + phandle = <0xa8>; + }; + }; + + cif-m1 { + + cif-clkout-m1 { + rockchip,pins = <0x03 0x18 0x03 0xb1>; + phandle = <0x149>; + }; + + dvp-d2d9-m1 { + rockchip,pins = <0x03 0x03 0x03 0xb1 0x03 0x05 0x03 0xb1 0x03 0x07 0x03 0xb1 0x03 0x08 0x03 0xb1 0x03 0x09 0x03 0xb1 0x03 0x0c 0x03 0xb1 0x03 0x0e 0x03 0xb1 0x03 0x0f 0x03 0xb1 0x03 0x19 0x03 0xb1 0x03 0x1a 0x03 0xb1 0x03 0x1b 0x03 0xb1 0x03 0x18 0x03 0xb1>; + phandle = <0x14a>; + }; + + dvp-d0d1-m1 { + rockchip,pins = <0x03 0x01 0x03 0xb1 0x03 0x02 0x03 0xb1>; + phandle = <0x14b>; + }; + + d10-d11-m1 { + rockchip,pins = <0x03 0x16 0x03 0xb1 0x03 0x17 0x03 0xb1>; + phandle = <0x14c>; + }; + }; + + isp { + + isp-prelight { + rockchip,pins = <0x03 0x19 0x04 0xb1>; + phandle = <0x14d>; + }; + }; + + pmic { + + pmic_int { + rockchip,pins = <0x00 0x0a 0x00 0xb2 0x00 0x0b 0x00 0xb1>; + phandle = <0x5d>; + }; + + soc_slppin_gpio { + rockchip,pins = <0x00 0x04 0x00 0xb9>; + phandle = <0x60>; + }; + + soc_slppin_slp { + rockchip,pins = <0x00 0x04 0x01 0xb1>; + phandle = <0x5e>; + }; + + soc_slppin_rst { + rockchip,pins = <0x00 0x04 0x02 0xb1>; + phandle = <0x62>; + }; + }; + + leds { + + led-pins { + rockchip,pins = <0x00 0x11 0x00 0xb1>; + phandle = <0xc0>; + }; + }; + + btns { + + btn-pins { + rockchip,pins = <0x01 0x0c 0x00 0xb2 0x01 0x0d 0x00 0xb2 0x01 0x0e 0x00 0xb2 0x01 0x0f 0x00 0xb2 0x01 0x02 0x00 0xb2 0x01 0x05 0x00 0xb2 0x01 0x06 0x00 0xb2 0x01 0x07 0x00 0xb2 0x02 0x00 0x00 0xb2 0x02 0x01 0x00 0xb2 0x02 0x02 0x00 0xb2 0x02 0x03 0x00 0xb2 0x02 0x04 0x00 0xb2 0x02 0x05 0x00 0xb2 0x02 0x06 0x00 0xb2 0x02 0x07 0x00 0xb2 0x03 0x09 0x00 0xb2 0x03 0x0a 0x00 0xb2 0x03 0x0c 0x00 0xb2 0x03 0x0f 0x00 0xb2>; + phandle = <0xbd>; + }; + }; + }; + + chosen { + bootargs = [00]; + }; + + fiq-debugger { + compatible = "rockchip,fiq-debugger"; + rockchip,serial-id = <0x02>; + rockchip,wake-irq = <0x00>; + rockchip,irq-mode-enable = <0x00>; + rockchip,baudrate = <0x1c200>; + interrupts = <0x00 0x7f 0x08>; + pinctrl-names = "default"; + pinctrl-0 = <0xba>; + status = "okay"; + }; + + ramoops { + compatible = "ramoops"; + record-size = <0x00 0x20000>; + console-size = <0x00 0x80000>; + ftrace-size = <0x00 0x00>; + pmsg-size = <0x00 0x00>; + memory-region = <0xbb>; + }; + + reserved-memory { + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + + drm-logo@00000000 { + compatible = "rockchip,drm-logo"; + reg = <0x00 0x00 0x00 0x00>; + phandle = <0x11>; + }; + + region@110000 { + reg = <0x00 0x110000 0x00 0xf0000>; + reg-names = "ramoops_mem"; + phandle = <0xbb>; + }; + }; + + odroidgo3-keys { + compatible = "gpio-keys"; + #address-cells = <0x01>; + #size-cells = <0x00>; + autorepeat; + phandle = <0x14e>; + + button@0 { + label = "GPIO BTN-VOLUP"; + linux,code = <0x73>; + gpios = <0x66 0x00 0x01>; + }; + + button@1 { + label = "GPIO BTN-VOLDN"; + linux,code = <0x72>; + gpios = <0x66 0x01 0x01>; + }; + }; + + odroidgo3-joypad { + compatible = "odroidgo3-joypad"; + pwms = <0xbc 0x00 0xbebc200 0x00>; + pwm-names = "enable"; + rumble-boost-weak = <0x00>; + rumble-boost-strong = <0x00>; + joypad-name = "GO-Super Gamepad"; + joypad-product = <0x1100>; + joypad-revision = <0x100>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <0xbd>; + pinctrl-1 = <0x7b>; + io-channel-names = "amux_adc"; + io-channels = <0xbe 0x01>; + amux-count = <0x04>; + amux-a-gpios = <0x97 0x0b 0x01>; + amux-b-gpios = <0x97 0x08 0x01>; + amux-en-gpios = <0x97 0x0d 0x01>; + button-adc-scale = <0x02>; + button-adc-deadzone = <0x40>; + button-adc-fuzz = <0x20>; + button-adc-flat = <0x20>; + abs_x-p-tuning = <0xc8>; + abs_x-n-tuning = <0xc8>; + abs_y-p-tuning = <0xc8>; + abs_y-n-tuning = <0xc8>; + abs_rx-p-tuning = <0xc8>; + abs_rx-n-tuning = <0xc8>; + abs_ry-p-tuning = <0xc8>; + abs_ry-n-tuning = <0xc8>; + poll-interval = <0x0a>; + invert-absx; + invert-absy; + phandle = <0x14f>; + + sw1 { + gpios = <0xbf 0x0c 0x01>; + label = "GPIO DPAD-UP"; + linux,code = <0x220>; + }; + + sw2 { + gpios = <0xbf 0x0d 0x01>; + label = "GPIO DPAD-DOWN"; + linux,code = <0x221>; + }; + + sw3 { + gpios = <0xbf 0x0e 0x01>; + label = "GPIO DPAD-LEFT"; + linux,code = <0x222>; + }; + + sw4 { + gpios = <0xbf 0x0f 0x01>; + label = "GPIO DPAD-RIGHT"; + linux,code = <0x223>; + }; + + sw5 { + gpios = <0xbf 0x02 0x01>; + label = "GPIO KEY BTN-A"; + linux,code = <0x131>; + }; + + sw6 { + gpios = <0xbf 0x05 0x01>; + label = "GPIO BTN-B"; + linux,code = <0x130>; + }; + + sw7 { + gpios = <0xbf 0x06 0x01>; + label = "GPIO BTN-Y"; + linux,code = <0x134>; + }; + + sw8 { + gpios = <0xbf 0x07 0x01>; + label = "GPIO BTN-X"; + linux,code = <0x133>; + }; + + sw11 { + gpios = <0x66 0x02 0x01>; + label = "GPIO F3"; + linux,code = <0x2c2>; + }; + + sw12 { + gpios = <0x66 0x03 0x01>; + label = "GPIO F4"; + linux,code = <0x2c3>; + }; + + sw15 { + gpios = <0x66 0x06 0x01>; + label = "GPIO TOP-LEFT"; + linux,code = <0x136>; + }; + + sw16 { + gpios = <0x66 0x07 0x01>; + label = "GPIO TOP-RIGHT"; + linux,code = <0x137>; + }; + + sw19 { + gpios = <0x97 0x09 0x01>; + label = "GPIO F1"; + linux,code = <0x2c0>; + }; + + sw20 { + gpios = <0x97 0x0f 0x01>; + label = "GPIO TOP-RIGHT2"; + linux,code = <0x139>; + }; + + sw21 { + gpios = <0x97 0x0a 0x01>; + label = "GPIO TOP-LEFT2"; + linux,code = <0x138>; + }; + + sw22 { + gpios = <0x97 0x0c 0x01>; + label = "GPIO F2"; + linux,code = <0x2c1>; + }; + + sw13 { + gpios = <0x66 0x04 0x01>; + label = "GPIO F5"; + linux,code = <0x2c4>; + }; + }; + + gpio_leds { + compatible = "gpio-leds"; + pinctrl-names = "led_pins"; + pinctrl-0 = <0xc0>; + phandle = <0x150>; + + heartbeat { + label = "blue:heartbeat"; + gpios = <0x5c 0x11 0x00>; + linux,default-trigger = "heartbeat"; + }; + }; + + backlight { + compatible = "pwm-backlight"; + pwms = <0xc1 0x00 0xf519 0x00>; + brightness-levels = <0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2a 0x2b 0x2c 0x2d 0x2e 0x2f 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x3a 0x3b 0x3c 0x3d 0x3e 0x3f 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48 0x49 0x4a 0x4b 0x4c 0x4d 0x4e 0x4f 0x50 0x51 0x52 0x53 0x54 0x55 0x56 0x57 0x58 0x59 0x5a 0x5b 0x5c 0x5d 0x5e 0x5f 0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69 0x6a 0x6b 0x6c 0x6d 0x6e 0x6f 0x70 0x71 0x72 0x73 0x74 0x75 0x76 0x77 0x78 0x79 0x7a 0x7b 0x7c 0x7d 0x7e 0x7f 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90 0x91 0x92 0x93 0x94 0x95 0x96 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f 0xa0>; + default-brightness-level = <0x33>; + phandle = <0x9d>; + }; + + rk817-sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,name = "rockchip,rk817-codec"; + simple-audio-card,mclk-fs = <0x100>; + simple-audio-card,widgets = "Microphone\0Mic Jack\0Headphone\0Headphone Jack"; + simple-audio-card,routing = "MIC_IN\0Mic Jack\0Headphone Jack\0HPOL\0Headphone Jack\0HPOR"; + simple-audio-card,hp-det-gpio = <0x66 0x16 0x01>; + simple-audio-card,codec-hp-det = <0x01>; + + simple-audio-card,cpu { + sound-dai = <0xc2>; + }; + + simple-audio-card,codec { + sound-dai = <0xc3>; + }; + }; + + vccsys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v8_sys"; + regulator-always-on; + regulator-min-microvolt = <0x39fbc0>; + regulator-max-microvolt = <0x39fbc0>; + phandle = <0x64>; + }; + + __symbols__ { + ddr_timing = "/ddr_timing"; + cpu0 = "/cpus/cpu@0"; + cpu1 = "/cpus/cpu@1"; + cpu2 = "/cpus/cpu@2"; + cpu3 = "/cpus/cpu@3"; + CPU_SLEEP = "/cpus/idle-states/cpu-sleep"; + CLUSTER_SLEEP = "/cpus/idle-states/cluster-sleep"; + cpu0_opp_table = "/cpu0-opp-table"; + bus_soc = "/bus-soc"; + bus_apll = "/bus-apll"; + bus_apll_opp_table = "/bus-apll-opp-table"; + display_subsystem = "/display-subsystem"; + route_lvds = "/display-subsystem/route/route-lvds"; + route_dsi = "/display-subsystem/route/route-dsi"; + route_rgb = "/display-subsystem/route/route-rgb"; + gmac_clkin = "/external-gmac-clock"; + rockchip_suspend = "/rockchip-suspend"; + xin24m = "/xin24m"; + xin32k = "/xin32k"; + pmu = "/power-management@ff000000"; + power = "/power-management@ff000000/power-controller"; + pmugrf = "/syscon@ff010000"; + pmu_io_domains = "/syscon@ff010000/io-domains"; + pmu_pvtm = "/syscon@ff010000/pmu-pvtm"; + uart0 = "/serial@ff030000"; + i2s0_8ch = "/i2s@ff060000"; + i2s1_2ch = "/i2s@ff070000"; + i2s2_2ch = "/i2s@ff080000"; + pdm = "/pdm@ff0a0000"; + crypto = "/crypto@ff0b0000"; + rng = "/rng@ff0b0000"; + gic = "/interrupt-controller@ff131000"; + grf = "/syscon@ff140000"; + io_domains = "/syscon@ff140000/io-domains"; + lvds = "/syscon@ff140000/lvds"; + lvds_in_vopb = "/syscon@ff140000/lvds/ports/port@0/endpoint@0"; + rgb = "/syscon@ff140000/rgb"; + rgb_in_vopb = "/syscon@ff140000/rgb/ports/port@0/endpoint@0"; + core_grf = "/syscon@ff148000"; + pvtm = "/syscon@ff148000/pvtm"; + uart1 = "/serial@ff158000"; + uart2 = "/serial@ff160000"; + uart3 = "/serial@ff168000"; + uart4 = "/serial@ff170000"; + uart5 = "/serial@ff178000"; + i2c0 = "/i2c@ff180000"; + rk817 = "/i2c@ff180000/pmic@20"; + pinctrl_rk8xx = "/i2c@ff180000/pmic@20/pinctrl_rk8xx"; + rk817_ts_gpio1 = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_ts_gpio1"; + rk817_gt_gpio2 = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_gt_gpio2"; + rk817_pin_ts = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_pin_ts"; + rk817_pin_gt = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_pin_gt"; + rk817_slppin_null = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_null"; + rk817_slppin_slp = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_slp"; + rk817_slppin_pwrdn = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_pwrdn"; + rk817_slppin_rst = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_rst"; + vdd_logic = "/i2c@ff180000/pmic@20/regulators/DCDC_REG1"; + vdd_arm = "/i2c@ff180000/pmic@20/regulators/DCDC_REG2"; + vcc_ddr = "/i2c@ff180000/pmic@20/regulators/DCDC_REG3"; + vcc_3v3 = "/i2c@ff180000/pmic@20/regulators/DCDC_REG4"; + vcc_1v0 = "/i2c@ff180000/pmic@20/regulators/LDO_REG1"; + vcc1v8_soc = "/i2c@ff180000/pmic@20/regulators/LDO_REG2"; + vdd1v0_soc = "/i2c@ff180000/pmic@20/regulators/LDO_REG3"; + vcc3v3_pmu = "/i2c@ff180000/pmic@20/regulators/LDO_REG4"; + vccio_sd = "/i2c@ff180000/pmic@20/regulators/LDO_REG5"; + vcc_sd = "/i2c@ff180000/pmic@20/regulators/LDO_REG6"; + vcc_backlight = "/i2c@ff180000/pmic@20/regulators/LDO_REG7"; + vcc_lcd = "/i2c@ff180000/pmic@20/regulators/LDO_REG8"; + dcdc_boost = "/i2c@ff180000/pmic@20/regulators/BOOST"; + otg_switch = "/i2c@ff180000/pmic@20/regulators/OTG_SWITCH"; + rk817_codec = "/i2c@ff180000/pmic@20/codec"; + i2c1 = "/i2c@ff190000"; + i2c2 = "/i2c@ff1a0000"; + i2c3 = "/i2c@ff1b0000"; + spi0 = "/spi@ff1d0000"; + spi1 = "/spi@ff1d8000"; + wdt = "/watchdog@ff1e0000"; + pwm0 = "/pwm@ff200000"; + pwm1 = "/pwm@ff200010"; + pwm2 = "/pwm@ff200020"; + pwm3 = "/pwm@ff200030"; + pwm4 = "/pwm@ff208000"; + pwm5 = "/pwm@ff208010"; + pwm6 = "/pwm@ff208020"; + pwm7 = "/pwm@ff208030"; + rktimer = "/rktimer@ff210000"; + dmac = "/amba/dmac@ff240000"; + thermal_zones = "/thermal-zones"; + soc_thermal = "/thermal-zones/soc-thermal"; + threshold = "/thermal-zones/soc-thermal/trips/trip-point-0"; + target = "/thermal-zones/soc-thermal/trips/trip-point-1"; + soc_crit = "/thermal-zones/soc-thermal/trips/soc-crit"; + gpu_thermal = "/thermal-zones/gpu-thermal"; + tsadc = "/tsadc@ff280000"; + saradc = "/saradc@ff288000"; + otp = "/otp@ff290000"; + otp_id = "/otp@ff290000/id@7"; + cpu_leakage = "/otp@ff290000/cpu-leakage@17"; + performance = "/otp@ff290000/performance@1e"; + cru = "/clock-controller@ff2b0000"; + cpu_boost = "/cpu-boost@ff2b8000"; + pmucru = "/pmu-clock-controller@ff2bc000"; + usb2phy_grf = "/syscon@ff2c0000"; + u2phy = "/syscon@ff2c0000/usb2-phy@100"; + u2phy_host = "/syscon@ff2c0000/usb2-phy@100/host-port"; + u2phy_otg = "/syscon@ff2c0000/usb2-phy@100/otg-port"; + video_phy = "/video-phy@ff2e0000"; + mipi_dphy_rx0 = "/mipi-dphy-rx0@ff2f0000"; + usb20_otg = "/usb@ff300000"; + usb_host0_ehci = "/usb@ff340000"; + usb_host0_ohci = "/usb@ff350000"; + gmac = "/ethernet@ff360000"; + sdmmc = "/dwmmc@ff370000"; + sdio = "/dwmmc@ff380000"; + emmc = "/dwmmc@ff390000"; + nandc0 = "/nandc@ff3b0000"; + sfc = "/sfc@ff3a0000"; + gpu = "/gpu@ff400000"; + gpu_opp_table = "/gpu-opp-table"; + hevc = "/hevc_service@ff440000"; + vpu = "/vpu_service@ff442000"; + vpu_combo = "/vpu_combo"; + hevc_mmu = "/iommu@ff440440"; + vpu_mmu = "/iommu@ff442800"; + dsi = "/dsi@ff450000"; + dsi_in_vopb = "/dsi@ff450000/ports/port@0/endpoint@0"; + timing0 = "/dsi@ff450000/panel@0/display-timings/60Hz"; + timing1 = "/dsi@ff450000/panel@0/display-timings/50Hz"; + timing2 = "/dsi@ff450000/panel@0/display-timings/75Hz"; + vopb = "/vop@ff460000"; + vopb_out = "/vop@ff460000/port"; + vopb_out_lvds = "/vop@ff460000/port/endpoint@0"; + vopb_out_dsi = "/vop@ff460000/port/endpoint@1"; + vopb_out_rgb = "/vop@ff460000/port/endpoint@2"; + vopb_mmu = "/iommu@ff460f00"; + rk_rga = "/rk_rga@ff480000"; + cif = "/cif@ff490000"; + cif_new = "/cif-new@ff490000"; + vip_mmu = "/iommu@ff490800"; + rk_isp = "/rk_isp@ff4a0000"; + rkisp1 = "/rkisp1@ff4a0000"; + isp_mmu = "/iommu@ff4a8000"; + qos_gmac = "/qos@ff518000"; + qos_gpu = "/qos@ff520000"; + qos_sdmmc = "/qos@ff52c000"; + qos_emmc = "/qos@ff538000"; + qos_nand = "/qos@ff538080"; + qos_sdio = "/qos@ff538100"; + qos_sfc = "/qos@ff538180"; + qos_usb_host = "/qos@ff540000"; + qos_usb_otg = "/qos@ff540080"; + qos_isp_128 = "/qos@ff548000"; + qos_isp_rd = "/qos@ff548080"; + qos_isp_wr = "/qos@ff548100"; + qos_isp_m1 = "/qos@ff548180"; + qos_vip = "/qos@ff548200"; + qos_rga_rd = "/qos@ff550000"; + qos_rga_wr = "/qos@ff550080"; + qos_vop_m0 = "/qos@ff550100"; + qos_vop_m1 = "/qos@ff550180"; + qos_vpu = "/qos@ff558000"; + qos_vpu_r128 = "/qos@ff558080"; + dfi = "/dfi@ff610000"; + dmc = "/dmc"; + ddr_power_model = "/dmc/ddr_power_model"; + dmc_opp_table = "/dmc-opp-table"; + rockchip_system_monitor = "/rockchip-system-monitor"; + pinctrl = "/pinctrl"; + gpio0 = "/pinctrl/gpio0@ff040000"; + gpio1 = "/pinctrl/gpio1@ff250000"; + gpio2 = "/pinctrl/gpio2@ff260000"; + gpio3 = "/pinctrl/gpio3@ff270000"; + pcfg_pull_up = "/pinctrl/pcfg-pull-up"; + pcfg_pull_down = "/pinctrl/pcfg-pull-down"; + pcfg_pull_none = "/pinctrl/pcfg-pull-none"; + pcfg_pull_none_2ma = "/pinctrl/pcfg-pull-none-2ma"; + pcfg_pull_up_2ma = "/pinctrl/pcfg-pull-up-2ma"; + pcfg_pull_up_4ma = "/pinctrl/pcfg-pull-up-4ma"; + pcfg_pull_none_4ma = "/pinctrl/pcfg-pull-none-4ma"; + pcfg_pull_down_4ma = "/pinctrl/pcfg-pull-down-4ma"; + pcfg_pull_none_8ma = "/pinctrl/pcfg-pull-none-8ma"; + pcfg_pull_up_8ma = "/pinctrl/pcfg-pull-up-8ma"; + pcfg_pull_none_12ma = "/pinctrl/pcfg-pull-none-12ma"; + pcfg_pull_up_12ma = "/pinctrl/pcfg-pull-up-12ma"; + pcfg_pull_none_smt = "/pinctrl/pcfg-pull-none-smt"; + pcfg_output_high = "/pinctrl/pcfg-output-high"; + pcfg_output_low = "/pinctrl/pcfg-output-low"; + pcfg_input_high = "/pinctrl/pcfg-input-high"; + pcfg_input = "/pinctrl/pcfg-input"; + i2c0_xfer = "/pinctrl/i2c0/i2c0-xfer"; + i2c1_xfer = "/pinctrl/i2c1/i2c1-xfer"; + i2c2_xfer = "/pinctrl/i2c2/i2c2-xfer"; + i2c3_xfer = "/pinctrl/i2c3/i2c3-xfer"; + tsadc_otp_gpio = "/pinctrl/tsadc/tsadc-otp-gpio"; + tsadc_otp_out = "/pinctrl/tsadc/tsadc-otp-out"; + uart0_xfer = "/pinctrl/uart0/uart0-xfer"; + uart0_cts = "/pinctrl/uart0/uart0-cts"; + uart0_rts = "/pinctrl/uart0/uart0-rts"; + uart0_rts_gpio = "/pinctrl/uart0/uart0-rts-gpio"; + uart1_xfer = "/pinctrl/uart1/uart1-xfer"; + uart1_cts = "/pinctrl/uart1/uart1-cts"; + uart1_rts = "/pinctrl/uart1/uart1-rts"; + uart1_rts_gpio = "/pinctrl/uart1/uart1-rts-gpio"; + uart2m0_xfer = "/pinctrl/uart2-m0/uart2m0-xfer"; + uart2m1_xfer = "/pinctrl/uart2-m1/uart2m1-xfer"; + uart3m0_xfer = "/pinctrl/uart3-m0/uart3m0-xfer"; + uart3m0_cts = "/pinctrl/uart3-m0/uart3m0-cts"; + uart3m0_rts = "/pinctrl/uart3-m0/uart3m0-rts"; + uart3m0_rts_gpio = "/pinctrl/uart3-m0/uart3m0-rts-gpio"; + uart3m1_xfer = "/pinctrl/uart3-m1/uart3m1-xfer"; + uart3m1_cts = "/pinctrl/uart3-m1/uart3m1-cts"; + uart3m1_rts = "/pinctrl/uart3-m1/uart3m1-rts"; + uart3m1_rts_gpio = "/pinctrl/uart3-m1/uart3m1-rts-gpio"; + uart4_xfer = "/pinctrl/uart4/uart4-xfer"; + uart4_cts = "/pinctrl/uart4/uart4-cts"; + uart4_rts = "/pinctrl/uart4/uart4-rts"; + uart5_xfer = "/pinctrl/uart5/uart5-xfer"; + uart5_cts = "/pinctrl/uart5/uart5-cts"; + uart5_rts = "/pinctrl/uart5/uart5-rts"; + spi0_clk = "/pinctrl/spi0/spi0-clk"; + spi0_csn = "/pinctrl/spi0/spi0-csn"; + spi0_miso = "/pinctrl/spi0/spi0-miso"; + spi0_mosi = "/pinctrl/spi0/spi0-mosi"; + spi0_clk_hs = "/pinctrl/spi0/spi0-clk-hs"; + spi0_miso_hs = "/pinctrl/spi0/spi0-miso-hs"; + spi0_mosi_hs = "/pinctrl/spi0/spi0-mosi-hs"; + spi1_clk = "/pinctrl/spi1/spi1-clk"; + spi1_csn0 = "/pinctrl/spi1/spi1-csn0"; + spi1_csn1 = "/pinctrl/spi1/spi1-csn1"; + spi1_miso = "/pinctrl/spi1/spi1-miso"; + spi1_mosi = "/pinctrl/spi1/spi1-mosi"; + spi1_clk_hs = "/pinctrl/spi1/spi1-clk-hs"; + spi1_miso_hs = "/pinctrl/spi1/spi1-miso-hs"; + spi1_mosi_hs = "/pinctrl/spi1/spi1-mosi-hs"; + pdm_clk0m0 = "/pinctrl/pdm/pdm-clk0m0"; + pdm_clk0m1 = "/pinctrl/pdm/pdm-clk0m1"; + pdm_clk1 = "/pinctrl/pdm/pdm-clk1"; + pdm_sdi0m0 = "/pinctrl/pdm/pdm-sdi0m0"; + pdm_sdi0m1 = "/pinctrl/pdm/pdm-sdi0m1"; + pdm_sdi1 = "/pinctrl/pdm/pdm-sdi1"; + pdm_sdi2 = "/pinctrl/pdm/pdm-sdi2"; + pdm_sdi3 = "/pinctrl/pdm/pdm-sdi3"; + pdm_clk0m0_sleep = "/pinctrl/pdm/pdm-clk0m0-sleep"; + pdm_clk0m_sleep1 = "/pinctrl/pdm/pdm-clk0m1-sleep"; + pdm_clk1_sleep = "/pinctrl/pdm/pdm-clk1-sleep"; + pdm_sdi0m0_sleep = "/pinctrl/pdm/pdm-sdi0m0-sleep"; + pdm_sdi0m1_sleep = "/pinctrl/pdm/pdm-sdi0m1-sleep"; + pdm_sdi1_sleep = "/pinctrl/pdm/pdm-sdi1-sleep"; + pdm_sdi2_sleep = "/pinctrl/pdm/pdm-sdi2-sleep"; + pdm_sdi3_sleep = "/pinctrl/pdm/pdm-sdi3-sleep"; + i2s0_8ch_mclk = "/pinctrl/i2s0/i2s0-8ch-mclk"; + i2s0_8ch_sclktx = "/pinctrl/i2s0/i2s0-8ch-sclktx"; + i2s0_8ch_sclkrx = "/pinctrl/i2s0/i2s0-8ch-sclkrx"; + i2s0_8ch_lrcktx = "/pinctrl/i2s0/i2s0-8ch-lrcktx"; + i2s0_8ch_lrckrx = "/pinctrl/i2s0/i2s0-8ch-lrckrx"; + i2s0_8ch_sdo0 = "/pinctrl/i2s0/i2s0-8ch-sdo0"; + i2s0_8ch_sdo1 = "/pinctrl/i2s0/i2s0-8ch-sdo1"; + i2s0_8ch_sdo2 = "/pinctrl/i2s0/i2s0-8ch-sdo2"; + i2s0_8ch_sdo3 = "/pinctrl/i2s0/i2s0-8ch-sdo3"; + i2s0_8ch_sdi0 = "/pinctrl/i2s0/i2s0-8ch-sdi0"; + i2s0_8ch_sdi1 = "/pinctrl/i2s0/i2s0-8ch-sdi1"; + i2s0_8ch_sdi2 = "/pinctrl/i2s0/i2s0-8ch-sdi2"; + i2s0_8ch_sdi3 = "/pinctrl/i2s0/i2s0-8ch-sdi3"; + i2s1_2ch_mclk = "/pinctrl/i2s1/i2s1-2ch-mclk"; + i2s1_2ch_sclk = "/pinctrl/i2s1/i2s1-2ch-sclk"; + i2s1_2ch_lrck = "/pinctrl/i2s1/i2s1-2ch-lrck"; + i2s1_2ch_sdi = "/pinctrl/i2s1/i2s1-2ch-sdi"; + i2s1_2ch_sdo = "/pinctrl/i2s1/i2s1-2ch-sdo"; + i2s2_2ch_mclk = "/pinctrl/i2s2/i2s2-2ch-mclk"; + i2s2_2ch_sclk = "/pinctrl/i2s2/i2s2-2ch-sclk"; + i2s2_2ch_lrck = "/pinctrl/i2s2/i2s2-2ch-lrck"; + i2s2_2ch_sdi = "/pinctrl/i2s2/i2s2-2ch-sdi"; + i2s2_2ch_sdo = "/pinctrl/i2s2/i2s2-2ch-sdo"; + sdmmc_clk = "/pinctrl/sdmmc/sdmmc-clk"; + sdmmc_cmd = "/pinctrl/sdmmc/sdmmc-cmd"; + sdmmc_det = "/pinctrl/sdmmc/sdmmc-det"; + sdmmc_bus1 = "/pinctrl/sdmmc/sdmmc-bus1"; + sdmmc_bus4 = "/pinctrl/sdmmc/sdmmc-bus4"; + sdmmc_gpio = "/pinctrl/sdmmc/sdmmc-gpio"; + sdio_clk = "/pinctrl/sdio/sdio-clk"; + sdio_cmd = "/pinctrl/sdio/sdio-cmd"; + sdio_bus4 = "/pinctrl/sdio/sdio-bus4"; + sdio_gpio = "/pinctrl/sdio/sdio-gpio"; + emmc_clk = "/pinctrl/emmc/emmc-clk"; + emmc_cmd = "/pinctrl/emmc/emmc-cmd"; + emmc_pwren = "/pinctrl/emmc/emmc-pwren"; + emmc_rstnout = "/pinctrl/emmc/emmc-rstnout"; + emmc_bus1 = "/pinctrl/emmc/emmc-bus1"; + emmc_bus4 = "/pinctrl/emmc/emmc-bus4"; + emmc_bus8 = "/pinctrl/emmc/emmc-bus8"; + flash_cs0 = "/pinctrl/flash/flash-cs0"; + flash_rdy = "/pinctrl/flash/flash-rdy"; + flash_dqs = "/pinctrl/flash/flash-dqs"; + flash_ale = "/pinctrl/flash/flash-ale"; + flash_cle = "/pinctrl/flash/flash-cle"; + flash_wrn = "/pinctrl/flash/flash-wrn"; + flash_csl = "/pinctrl/flash/flash-csl"; + flash_rdn = "/pinctrl/flash/flash-rdn"; + flash_bus8 = "/pinctrl/flash/flash-bus8"; + lcdc_m0_rgb_pins = "/pinctrl/lcdc/lcdc-m0-rgb-pins"; + lcdc_m0_sleep_pins = "/pinctrl/lcdc/lcdc-m0-sleep-pins"; + lcdc_m1_rgb_pins = "/pinctrl/lcdc/lcdc-m1-rgb-pins"; + lcdc_m1_sleep_pins = "/pinctrl/lcdc/lcdc-m1-sleep-pins"; + pwm0_pin = "/pinctrl/pwm0/pwm0-pin"; + pwm1_pin = "/pinctrl/pwm1/pwm1-pin"; + pwm2_pin = "/pinctrl/pwm2/pwm2-pin"; + pwm3_pin = "/pinctrl/pwm3/pwm3-pin"; + pwm4_pin = "/pinctrl/pwm4/pwm4-pin"; + pwm5_pin = "/pinctrl/pwm5/pwm5-pin"; + pwm6_pin = "/pinctrl/pwm6/pwm6-pin"; + pwm7_pin = "/pinctrl/pwm7/pwm7-pin"; + rmii_pins = "/pinctrl/gmac/rmii-pins"; + mac_refclk_12ma = "/pinctrl/gmac/mac-refclk-12ma"; + mac_refclk = "/pinctrl/gmac/mac-refclk"; + cif_clkout_m0 = "/pinctrl/cif-m0/cif-clkout-m0"; + dvp_d2d9_m0 = "/pinctrl/cif-m0/dvp-d2d9-m0"; + dvp_d0d1_m0 = "/pinctrl/cif-m0/dvp-d0d1-m0"; + dvp_d10d11_m0 = "/pinctrl/cif-m0/d10-d11-m0"; + cif_clkout_m1 = "/pinctrl/cif-m1/cif-clkout-m1"; + dvp_d2d9_m1 = "/pinctrl/cif-m1/dvp-d2d9-m1"; + dvp_d0d1_m1 = "/pinctrl/cif-m1/dvp-d0d1-m1"; + dvp_d10d11_m1 = "/pinctrl/cif-m1/d10-d11-m1"; + isp_prelight = "/pinctrl/isp/isp-prelight"; + pmic_int = "/pinctrl/pmic/pmic_int"; + soc_slppin_gpio = "/pinctrl/pmic/soc_slppin_gpio"; + soc_slppin_slp = "/pinctrl/pmic/soc_slppin_slp"; + soc_slppin_rst = "/pinctrl/pmic/soc_slppin_rst"; + led_pins = "/pinctrl/leds/led-pins"; + btn_pins = "/pinctrl/btns/btn-pins"; + drm_logo = "/reserved-memory/drm-logo@00000000"; + ramoops_mem = "/reserved-memory/region@110000"; + gpio_keys = "/odroidgo3-keys"; + joypad = "/odroidgo3-joypad"; + leds = "/gpio_leds"; + backlight = "/backlight"; + vccsys = "/vccsys"; + }; +}; diff --git a/config/archr-dts/R36S-DTB/DTS/Panel2.dts b/config/archr-dts/R36S-DTB/DTS/Panel2.dts new file mode 100644 index 0000000000..2db0b5a537 --- /dev/null +++ b/config/archr-dts/R36S-DTB/DTS/Panel2.dts @@ -0,0 +1,4063 @@ +/dts-v1/; + +/ { + compatible = "rockchip,rk3326-odroidgo3-linux\0rockchip,rk3326"; + interrupt-parent = <0x01>; + #address-cells = <0x02>; + #size-cells = <0x02>; + model = "Game Console R35S/R36S fix by AeolusUX"; + + ddr_timing { + compatible = "rockchip,ddr-timing"; + ddr2_speed_bin = <0x00>; + ddr3_speed_bin = <0x15>; + ddr4_speed_bin = <0x0c>; + pd_idle = <0x0d>; + sr_idle = <0x5d>; + sr_mc_gate_idle = <0x00>; + srpd_lite_idle = <0x00>; + standby_idle = <0x00>; + auto_pd_dis_freq = <0x42a>; + auto_sr_dis_freq = <0x320>; + ddr2_dll_dis_freq = <0x12c>; + ddr3_dll_dis_freq = <0x12c>; + ddr4_dll_dis_freq = <0x271>; + phy_dll_dis_freq = <0x190>; + ddr2_odt_dis_freq = <0x64>; + phy_ddr2_odt_dis_freq = <0x64>; + ddr2_drv = <0x01>; + ddr2_odt = <0x96>; + phy_ddr2_ca_drv = <0x15>; + phy_ddr2_ck_drv = <0x12>; + phy_ddr2_dq_drv = <0x15>; + phy_ddr2_odt = <0x02>; + ddr3_odt_dis_freq = <0x190>; + phy_ddr3_odt_dis_freq = <0x190>; + ddr3_drv = <0x28>; + ddr3_odt = <0x78>; + phy_ddr3_ca_drv = <0x15>; + phy_ddr3_ck_drv = <0x12>; + phy_ddr3_dq_drv = <0x15>; + phy_ddr3_odt = <0x02>; + phy_lpddr2_odt_dis_freq = <0x29a>; + lpddr2_drv = <0x28>; + phy_lpddr2_ca_drv = <0x16>; + phy_lpddr2_ck_drv = <0x13>; + phy_lpddr2_dq_drv = <0x16>; + phy_lpddr2_odt = <0x00>; + lpddr3_odt_dis_freq = <0x190>; + phy_lpddr3_odt_dis_freq = <0x190>; + lpddr3_drv = <0x28>; + lpddr3_odt = <0xf0>; + phy_lpddr3_ca_drv = <0x16>; + phy_lpddr3_ck_drv = <0x13>; + phy_lpddr3_dq_drv = <0x16>; + phy_lpddr3_odt = <0x02>; + lpddr4_odt_dis_freq = <0x320>; + phy_lpddr4_odt_dis_freq = <0x320>; + lpddr4_drv = <0x3c>; + lpddr4_dq_odt = <0x28>; + lpddr4_ca_odt = <0x28>; + phy_lpddr4_ca_drv = <0x14>; + phy_lpddr4_ck_cs_drv = <0x06>; + phy_lpddr4_dq_drv = <0x06>; + phy_lpddr4_odt = <0x10>; + ddr4_odt_dis_freq = <0x29a>; + phy_ddr4_odt_dis_freq = <0x29a>; + ddr4_drv = <0x22>; + ddr4_odt = <0xf0>; + phy_ddr4_ca_drv = <0x16>; + phy_ddr4_ck_drv = <0x13>; + phy_ddr4_dq_drv = <0x16>; + phy_ddr4_odt = <0x02>; + ddr3a1_ddr4a9_de-skew = <0x06>; + ddr3a0_ddr4a10_de-skew = <0x07>; + ddr3a3_ddr4a6_de-skew = <0x07>; + ddr3a2_ddr4a4_de-skew = <0x07>; + ddr3a5_ddr4a8_de-skew = <0x07>; + ddr3a4_ddr4a5_de-skew = <0x07>; + ddr3a7_ddr4a11_de-skew = <0x07>; + ddr3a6_ddr4a7_de-skew = <0x06>; + ddr3a9_ddr4a0_de-skew = <0x07>; + ddr3a8_ddr4a13_de-skew = <0x07>; + ddr3a11_ddr4a3_de-skew = <0x07>; + ddr3a10_ddr4cs0_de-skew = <0x07>; + ddr3a13_ddr4a2_de-skew = <0x07>; + ddr3a12_ddr4ba1_de-skew = <0x07>; + ddr3a15_ddr4odt0_de-skew = <0x07>; + ddr3a14_ddr4a1_de-skew = <0x07>; + ddr3ba1_ddr4a15_de-skew = <0x07>; + ddr3ba0_ddr4bg0_de-skew = <0x07>; + ddr3ras_ddr4cke_de-skew = <0x07>; + ddr3ba2_ddr4ba0_de-skew = <0x07>; + ddr3we_ddr4bg1_de-skew = <0x07>; + ddr3cas_ddr4a12_de-skew = <0x07>; + ddr3ckn_ddr4ckn_de-skew = <0x07>; + ddr3ckp_ddr4ckp_de-skew = <0x07>; + ddr3cke_ddr4a16_de-skew = <0x07>; + ddr3odt0_ddr4a14_de-skew = <0x07>; + ddr3cs0_ddr4act_de-skew = <0x06>; + ddr3reset_ddr4reset_de-skew = <0x07>; + ddr3cs1_ddr4cs1_de-skew = <0x06>; + ddr3odt1_ddr4odt1_de-skew = <0x07>; + cs0_dm0_rx_de-skew = <0x07>; + cs0_dm0_tx_de-skew = <0x07>; + cs0_dq0_rx_de-skew = <0x08>; + cs0_dq0_tx_de-skew = <0x08>; + cs0_dq1_rx_de-skew = <0x09>; + cs0_dq1_tx_de-skew = <0x08>; + cs0_dq2_rx_de-skew = <0x08>; + cs0_dq2_tx_de-skew = <0x08>; + cs0_dq3_rx_de-skew = <0x08>; + cs0_dq3_tx_de-skew = <0x08>; + cs0_dq4_rx_de-skew = <0x09>; + cs0_dq4_tx_de-skew = <0x08>; + cs0_dq5_rx_de-skew = <0x09>; + cs0_dq5_tx_de-skew = <0x08>; + cs0_dq6_rx_de-skew = <0x09>; + cs0_dq6_tx_de-skew = <0x08>; + cs0_dq7_rx_de-skew = <0x08>; + cs0_dq7_tx_de-skew = <0x08>; + cs0_dqs0_rx_de-skew = <0x06>; + cs0_dqs0p_tx_de-skew = <0x09>; + cs0_dqs0n_tx_de-skew = <0x09>; + cs0_dm1_rx_de-skew = <0x07>; + cs0_dm1_tx_de-skew = <0x06>; + cs0_dq8_rx_de-skew = <0x08>; + cs0_dq8_tx_de-skew = <0x07>; + cs0_dq9_rx_de-skew = <0x09>; + cs0_dq9_tx_de-skew = <0x07>; + cs0_dq10_rx_de-skew = <0x08>; + cs0_dq10_tx_de-skew = <0x08>; + cs0_dq11_rx_de-skew = <0x08>; + cs0_dq11_tx_de-skew = <0x07>; + cs0_dq12_rx_de-skew = <0x08>; + cs0_dq12_tx_de-skew = <0x08>; + cs0_dq13_rx_de-skew = <0x09>; + cs0_dq13_tx_de-skew = <0x07>; + cs0_dq14_rx_de-skew = <0x09>; + cs0_dq14_tx_de-skew = <0x08>; + cs0_dq15_rx_de-skew = <0x09>; + cs0_dq15_tx_de-skew = <0x07>; + cs0_dqs1_rx_de-skew = <0x07>; + cs0_dqs1p_tx_de-skew = <0x09>; + cs0_dqs1n_tx_de-skew = <0x09>; + cs0_dm2_rx_de-skew = <0x07>; + cs0_dm2_tx_de-skew = <0x07>; + cs0_dq16_rx_de-skew = <0x09>; + cs0_dq16_tx_de-skew = <0x09>; + cs0_dq17_rx_de-skew = <0x07>; + cs0_dq17_tx_de-skew = <0x09>; + cs0_dq18_rx_de-skew = <0x07>; + cs0_dq18_tx_de-skew = <0x08>; + cs0_dq19_rx_de-skew = <0x07>; + cs0_dq19_tx_de-skew = <0x09>; + cs0_dq20_rx_de-skew = <0x09>; + cs0_dq20_tx_de-skew = <0x09>; + cs0_dq21_rx_de-skew = <0x09>; + cs0_dq21_tx_de-skew = <0x09>; + cs0_dq22_rx_de-skew = <0x08>; + cs0_dq22_tx_de-skew = <0x09>; + cs0_dq23_rx_de-skew = <0x08>; + cs0_dq23_tx_de-skew = <0x09>; + cs0_dqs2_rx_de-skew = <0x06>; + cs0_dqs2p_tx_de-skew = <0x09>; + cs0_dqs2n_tx_de-skew = <0x09>; + cs0_dm3_rx_de-skew = <0x07>; + cs0_dm3_tx_de-skew = <0x07>; + cs0_dq24_rx_de-skew = <0x08>; + cs0_dq24_tx_de-skew = <0x08>; + cs0_dq25_rx_de-skew = <0x09>; + cs0_dq25_tx_de-skew = <0x09>; + cs0_dq26_rx_de-skew = <0x09>; + cs0_dq26_tx_de-skew = <0x08>; + cs0_dq27_rx_de-skew = <0x09>; + cs0_dq27_tx_de-skew = <0x08>; + cs0_dq28_rx_de-skew = <0x09>; + cs0_dq28_tx_de-skew = <0x09>; + cs0_dq29_rx_de-skew = <0x09>; + cs0_dq29_tx_de-skew = <0x09>; + cs0_dq30_rx_de-skew = <0x08>; + cs0_dq30_tx_de-skew = <0x08>; + cs0_dq31_rx_de-skew = <0x08>; + cs0_dq31_tx_de-skew = <0x08>; + cs0_dqs3_rx_de-skew = <0x07>; + cs0_dqs3p_tx_de-skew = <0x09>; + cs0_dqs3n_tx_de-skew = <0x09>; + cs1_dm0_rx_de-skew = <0x07>; + cs1_dm0_tx_de-skew = <0x07>; + cs1_dq0_rx_de-skew = <0x08>; + cs1_dq0_tx_de-skew = <0x08>; + cs1_dq1_rx_de-skew = <0x09>; + cs1_dq1_tx_de-skew = <0x08>; + cs1_dq2_rx_de-skew = <0x08>; + cs1_dq2_tx_de-skew = <0x08>; + cs1_dq3_rx_de-skew = <0x08>; + cs1_dq3_tx_de-skew = <0x08>; + cs1_dq4_rx_de-skew = <0x08>; + cs1_dq4_tx_de-skew = <0x08>; + cs1_dq5_rx_de-skew = <0x09>; + cs1_dq5_tx_de-skew = <0x08>; + cs1_dq6_rx_de-skew = <0x09>; + cs1_dq6_tx_de-skew = <0x08>; + cs1_dq7_rx_de-skew = <0x08>; + cs1_dq7_tx_de-skew = <0x08>; + cs1_dqs0_rx_de-skew = <0x06>; + cs1_dqs0p_tx_de-skew = <0x09>; + cs1_dqs0n_tx_de-skew = <0x09>; + cs1_dm1_rx_de-skew = <0x07>; + cs1_dm1_tx_de-skew = <0x07>; + cs1_dq8_rx_de-skew = <0x08>; + cs1_dq8_tx_de-skew = <0x08>; + cs1_dq9_rx_de-skew = <0x08>; + cs1_dq9_tx_de-skew = <0x07>; + cs1_dq10_rx_de-skew = <0x07>; + cs1_dq10_tx_de-skew = <0x08>; + cs1_dq11_rx_de-skew = <0x08>; + cs1_dq11_tx_de-skew = <0x08>; + cs1_dq12_rx_de-skew = <0x08>; + cs1_dq12_tx_de-skew = <0x07>; + cs1_dq13_rx_de-skew = <0x08>; + cs1_dq13_tx_de-skew = <0x08>; + cs1_dq14_rx_de-skew = <0x08>; + cs1_dq14_tx_de-skew = <0x08>; + cs1_dq15_rx_de-skew = <0x08>; + cs1_dq15_tx_de-skew = <0x07>; + cs1_dqs1_rx_de-skew = <0x07>; + cs1_dqs1p_tx_de-skew = <0x09>; + cs1_dqs1n_tx_de-skew = <0x09>; + cs1_dm2_rx_de-skew = <0x07>; + cs1_dm2_tx_de-skew = <0x08>; + cs1_dq16_rx_de-skew = <0x08>; + cs1_dq16_tx_de-skew = <0x09>; + cs1_dq17_rx_de-skew = <0x08>; + cs1_dq17_tx_de-skew = <0x09>; + cs1_dq18_rx_de-skew = <0x07>; + cs1_dq18_tx_de-skew = <0x08>; + cs1_dq19_rx_de-skew = <0x08>; + cs1_dq19_tx_de-skew = <0x09>; + cs1_dq20_rx_de-skew = <0x09>; + cs1_dq20_tx_de-skew = <0x09>; + cs1_dq21_rx_de-skew = <0x09>; + cs1_dq21_tx_de-skew = <0x09>; + cs1_dq22_rx_de-skew = <0x08>; + cs1_dq22_tx_de-skew = <0x09>; + cs1_dq23_rx_de-skew = <0x08>; + cs1_dq23_tx_de-skew = <0x09>; + cs1_dqs2_rx_de-skew = <0x06>; + cs1_dqs2p_tx_de-skew = <0x09>; + cs1_dqs2n_tx_de-skew = <0x09>; + cs1_dm3_rx_de-skew = <0x07>; + cs1_dm3_tx_de-skew = <0x07>; + cs1_dq24_rx_de-skew = <0x08>; + cs1_dq24_tx_de-skew = <0x09>; + cs1_dq25_rx_de-skew = <0x09>; + cs1_dq25_tx_de-skew = <0x09>; + cs1_dq26_rx_de-skew = <0x09>; + cs1_dq26_tx_de-skew = <0x08>; + cs1_dq27_rx_de-skew = <0x08>; + cs1_dq27_tx_de-skew = <0x08>; + cs1_dq28_rx_de-skew = <0x09>; + cs1_dq28_tx_de-skew = <0x09>; + cs1_dq29_rx_de-skew = <0x09>; + cs1_dq29_tx_de-skew = <0x09>; + cs1_dq30_rx_de-skew = <0x09>; + cs1_dq30_tx_de-skew = <0x08>; + cs1_dq31_rx_de-skew = <0x08>; + cs1_dq31_tx_de-skew = <0x08>; + cs1_dqs3_rx_de-skew = <0x07>; + cs1_dqs3p_tx_de-skew = <0x09>; + cs1_dqs3n_tx_de-skew = <0x09>; + phandle = <0xaf>; + }; + + aliases { + ethernet0 = "/ethernet@ff360000"; + i2c0 = "/i2c@ff180000"; + i2c1 = "/i2c@ff190000"; + i2c2 = "/i2c@ff1a0000"; + i2c3 = "/i2c@ff1b0000"; + serial0 = "/serial@ff030000"; + serial1 = "/serial@ff158000"; + serial2 = "/serial@ff160000"; + serial3 = "/serial@ff168000"; + serial4 = "/serial@ff170000"; + serial5 = "/serial@ff178000"; + spi0 = "/spi@ff1d0000"; + spi1 = "/spi@ff1d8000"; + }; + + cpus { + #address-cells = <0x02>; + #size-cells = <0x00>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x00>; + enable-method = "psci"; + clocks = <0x02 0x07>; + #cooling-cells = <0x02>; + dynamic-power-coefficient = <0x5a>; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + cpu-supply = <0x06>; + phandle = <0x09>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x01>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0a>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x02>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0b>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x03>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0c>; + }; + + idle-states { + entry-method = "psci"; + + cpu-sleep { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x10000>; + entry-latency-us = <0x78>; + exit-latency-us = <0xfa>; + min-residency-us = <0x384>; + phandle = <0x04>; + }; + + cluster-sleep { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x1010000>; + entry-latency-us = <0x190>; + exit-latency-us = <0x1f4>; + min-residency-us = <0x7d0>; + phandle = <0x05>; + }; + }; + }; + + cpu0-opp-table { + compatible = "operating-points-v2"; + opp-shared; + rockchip,temp-hysteresis = <0x1388>; + rockchip,low-temp = <0x00>; + rockchip,low-temp-min-volt = <0xf4240>; + rockchip,low-temp-adjust-volt = <0x00 0x5e8 0xc350>; + clocks = <0x02 0x01>; + rockchip,avs-scale = <0x04>; + rockchip,max-volt = <0x149970>; + rockchip,evb-irdrop = <0x61a8>; + nvmem-cells = <0x07 0x08>; + nvmem-cell-names = "cpu_leakage\0performance"; + rockchip,bin-scaling-sel = <0x00 0x0d 0x01 0x0d>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-freq = <0x639c0>; + rockchip,pvtm-volt = <0xf4240>; + rockchip,pvtm-ch = <0x00 0x00>; + rockchip,pvtm-sample-time = <0x3e8>; + rockchip,pvtm-number = <0x0a>; + rockchip,pvtm-error = <0x3e8>; + rockchip,pvtm-ref-temp = <0x28>; + rockchip,pvtm-temp-prop = <0xffffffc8 0xffffffc8>; + rockchip,thermal-zone = "soc-thermal"; + rockchip,avs = <0x01>; + phandle = <0x03>; + + opp-1008000000 { + opp-hz = <0x00 0x3c14dc00>; + opp-microvolt = <0x11edd8 0x11edd8 0x149970>; + opp-microvolt-L0 = <0x11edd8 0x11edd8 0x149970>; + opp-microvolt-L1 = <0x112a88 0x112a88 0x149970>; + opp-microvolt-L2 = <0x112a88 0x112a88 0x149970>; + opp-microvolt-L3 = <0x100590 0x100590 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1200000000 { + opp-hz = <0x00 0x47868c00>; + opp-microvolt = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L0 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L1 = <0x137478 0x137478 0x149970>; + opp-microvolt-L2 = <0x1312d0 0x1312d0 0x149970>; + opp-microvolt-L3 = <0x124f80 0x124f80 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1248000000 { + opp-hz = <0x00 0x4a62f800>; + opp-microvolt = <0x149970 0x149970 0x149970>; + opp-microvolt-L0 = <0x149970 0x149970 0x149970>; + opp-microvolt-L1 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L2 = <0x137478 0x137478 0x149970>; + opp-microvolt-L3 = <0x12b128 0x12b128 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1296000000 { + opp-hz = <0x00 0x4d3f6400>; + opp-microvolt = <0x149970 0x149970 0x149970>; + opp-microvolt-L0 = <0x149970 0x149970 0x149970>; + opp-microvolt-L1 = <0x149970 0x149970 0x149970>; + opp-microvolt-L2 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L3 = <0x1312d0 0x1312d0 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1512000000 { + opp-hz = <0x00 0x5a1f4a00>; + opp-microvolt = <0x149970 0x149970 0x149970>; + opp-microvolt-L0 = <0x149970 0x149970 0x149970>; + opp-microvolt-L1 = <0x149970 0x149970 0x149970>; + opp-microvolt-L2 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L3 = <0x1312d0 0x1312d0 0x149970>; + clock-latency-ns = <0x9c40>; + }; + }; + + arm-pmu { + compatible = "arm,cortex-a53-pmu"; + interrupts = <0x00 0x64 0x04 0x00 0x65 0x04 0x00 0x66 0x04 0x00 0x67 0x04>; + interrupt-affinity = <0x09 0x0a 0x0b 0x0c>; + }; + + bus-soc { + compatible = "rockchip,px30-bus"; + rockchip,busfreq-policy = "autocs"; + phandle = <0xc4>; + + soc-bus0 { + bus-id = <0x00>; + timer-us = <0x14>; + enable-msk = <0x40f7>; + status = "disabled"; + }; + + soc-bus1 { + bus-id = <0x01>; + timer-us = <0xc8>; + enable-msk = <0x40bf>; + status = "disabled"; + }; + + soc-bus2 { + bus-id = <0x02>; + timer-us = <0xc8>; + enable-msk = <0x4007>; + status = "disabled"; + }; + }; + + bus-apll { + compatible = "rockchip,px30-bus"; + rockchip,busfreq-policy = "clkfreq"; + clocks = <0x02 0x01>; + clock-names = "bus"; + operating-points-v2 = <0x0d>; + status = "okay"; + bus-supply = <0x0e>; + phandle = <0xc5>; + }; + + bus-apll-opp-table { + compatible = "operating-points-v2"; + opp-shared; + phandle = <0x0d>; + + opp-1512000000 { + opp-hz = <0x00 0x5a1f4a00>; + opp-microvolt = <0xf4240>; + }; + + opp-1008000000 { + opp-hz = <0x00 0x3c14dc00>; + opp-microvolt = <0xe7ef0>; + }; + }; + + cpuinfo { + compatible = "rockchip,cpuinfo"; + nvmem-cells = <0x0f>; + nvmem-cell-names = "id"; + }; + + display-subsystem { + compatible = "rockchip,display-subsystem"; + ports = <0x10>; + status = "okay"; + logo-memory-region = <0x11>; + phandle = <0xc6>; + + route { + + route-lvds { + status = "disabled"; + logo,uboot = "logo.gif"; + logo,kernel = "logo_kernel.gif"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x12>; + phandle = <0xc7>; + }; + + route-dsi { + status = "okay"; + logo,uboot = "logo.gif"; + logo,kernel = "logo_kernel.gif"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x13>; + phandle = <0xc8>; + }; + + route-rgb { + status = "disabled"; + logo,uboot = "logo.gif"; + logo,kernel = "logo_kernel.gif"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x14>; + phandle = <0xc9>; + }; + }; + }; + + firmware { + + optee { + compatible = "linaro,optee-tz"; + method = "smc"; + }; + }; + + external-gmac-clock { + compatible = "fixed-clock"; + clock-frequency = <0x2faf080>; + clock-output-names = "gmac_clkin"; + #clock-cells = <0x00>; + phandle = <0xca>; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + rockchip-suspend { + compatible = "rockchip,pm-px30"; + status = "okay"; + rockchip,sleep-debug-en = <0x01>; + rockchip,sleep-mode-config = <0x20702>; + rockchip,wakeup-config = <0x85>; + phandle = <0xcb>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <0x01 0x0d 0xf04 0x01 0x0e 0xf04 0x01 0x0b 0xf04 0x01 0x0a 0xf04>; + }; + + xin24m { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x16e3600>; + clock-output-names = "xin24m"; + phandle = <0xcc>; + }; + + xin32k { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x8000>; + clock-output-names = "xin32k"; + phandle = <0xcd>; + }; + + power-management@ff000000 { + compatible = "rockchip,px30-pmu\0syscon\0simple-mfd"; + reg = <0x00 0xff000000 0x00 0x1000>; + phandle = <0xce>; + + power-controller { + compatible = "rockchip,px30-power-controller"; + #power-domain-cells = <0x01>; + #address-cells = <0x01>; + #size-cells = <0x00>; + phandle = <0x8a>; + + pd_usb@5 { + reg = <0x05>; + clocks = <0x02 0x103 0x02 0x102 0x02 0x3c>; + pm_qos = <0x15 0x16>; + }; + + pd_sdcard@7 { + reg = <0x07>; + clocks = <0x02 0xf7 0x02 0x3b>; + pm_qos = <0x17>; + }; + + pd_gmac@9 { + reg = <0x09>; + clocks = <0x02 0xb2 0x02 0x143 0x02 0x40 0x02 0x3f>; + pm_qos = <0x18>; + }; + + pd_mmc_nand@10 { + reg = <0x0a>; + clocks = <0x02 0xfe 0x02 0x100 0x02 0xff 0x02 0x101 0x02 0x39 0x02 0x37 0x02 0x38 0x02 0x3a>; + pm_qos = <0x19 0x1a 0x1b 0x1c>; + }; + + pd_vpu@11 { + reg = <0x0b>; + clocks = <0x02 0xaf 0x02 0xf4 0x02 0x4b>; + pm_qos = <0x1d 0x1e>; + }; + + pd_vo@12 { + reg = <0x0c>; + clocks = <0x02 0xb7 0x02 0xb5 0x02 0xb6 0x02 0x96 0x02 0x97 0x02 0xfd 0x02 0xfb 0x02 0xfc 0x02 0x144 0x02 0x35 0x02 0x36>; + pm_qos = <0x1f 0x20 0x21 0x22>; + }; + + pd_vi@13 { + reg = <0x0d>; + clocks = <0x02 0xb3 0x02 0xb4 0x02 0xf9 0x02 0xfa 0x02 0x33>; + pm_qos = <0x23 0x24 0x25 0x26 0x27>; + }; + + pd_gpu@14 { + reg = <0x0e>; + clocks = <0x02 0x49>; + pm_qos = <0x28>; + }; + }; + }; + + syscon@ff010000 { + compatible = "rockchip,px30-pmugrf\0syscon\0simple-mfd"; + reg = <0x00 0xff010000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0xac>; + + io-domains { + compatible = "rockchip,px30-pmu-io-voltage-domain"; + status = "okay"; + pmuio1-supply = <0x29>; + pmuio2-supply = <0x29>; + phandle = <0xcf>; + }; + + reboot-mode { + compatible = "syscon-reboot-mode"; + offset = <0x200>; + mode-bootloader = <0x5242c301>; + mode-charge = <0x5242c30b>; + mode-fastboot = <0x5242c309>; + mode-loader = <0x5242c301>; + mode-normal = <0x5242c300>; + mode-recovery = <0x5242c303>; + mode-ums = <0x5242c30c>; + }; + + pmu-pvtm { + compatible = "rockchip,px30-pmu-pvtm"; + clocks = <0x2a 0x07>; + clock-names = "pmu"; + status = "okay"; + phandle = <0xd0>; + }; + }; + + serial@ff030000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff030000 0x00 0x100>; + interrupts = <0x00 0x0f 0x04>; + clocks = <0x2a 0x06 0x2a 0x15>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x00 0x2b 0x01>; + pinctrl-names = "default"; + pinctrl-0 = <0x2c 0x2d 0x2e>; + status = "disabled"; + phandle = <0xd1>; + }; + + i2s@ff060000 { + compatible = "rockchip,px30-i2s-tdm"; + reg = <0x00 0xff060000 0x00 0x1000>; + interrupts = <0x00 0x0c 0x04>; + clocks = <0x02 0x10 0x02 0x12 0x02 0x106>; + clock-names = "mclk_tx\0mclk_rx\0hclk"; + dmas = <0x2b 0x10 0x2b 0x11>; + dma-names = "tx\0rx"; + resets = <0x02 0x84 0x02 0xbf>; + reset-names = "tx-m\0rx-m"; + rockchip,cru = <0x02>; + rockchip,grf = <0x2f>; + pinctrl-names = "default"; + pinctrl-0 = <0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x3a 0x3b>; + status = "disabled"; + phandle = <0xd2>; + }; + + i2s@ff070000 { + compatible = "rockchip,px30-i2s\0rockchip,rk3066-i2s"; + reg = <0x00 0xff070000 0x00 0x1000>; + interrupts = <0x00 0x0d 0x04>; + clocks = <0x02 0x14 0x02 0x107>; + clock-names = "i2s_clk\0i2s_hclk"; + dmas = <0x2b 0x12 0x2b 0x13>; + dma-names = "tx\0rx"; + resets = <0x02 0x86 0x02 0x85>; + reset-names = "reset-m\0reset-h"; + pinctrl-names = "default"; + pinctrl-0 = <0x3c 0x3d 0x3e 0x3f>; + status = "okay"; + #sound-dai-cells = <0x00>; + phandle = <0xc2>; + }; + + i2s@ff080000 { + compatible = "rockchip,px30-i2s\0rockchip,rk3066-i2s"; + reg = <0x00 0xff080000 0x00 0x1000>; + interrupts = <0x00 0x0e 0x04>; + clocks = <0x02 0x16 0x02 0x108>; + clock-names = "i2s_clk\0i2s_hclk"; + dmas = <0x2b 0x14 0x2b 0x15>; + dma-names = "tx\0rx"; + resets = <0x02 0x88 0x02 0x87>; + reset-names = "reset-m\0reset-h"; + pinctrl-names = "default"; + pinctrl-0 = <0x40 0x41 0x42 0x43>; + status = "disabled"; + phandle = <0xd3>; + }; + + pdm@ff0a0000 { + compatible = "rockchip,px30-pdm\0rockchip,pdm"; + reg = <0x00 0xff0a0000 0x00 0x1000>; + clocks = <0x02 0x0f 0x02 0x105>; + clock-names = "pdm_clk\0pdm_hclk"; + dmas = <0x2b 0x18>; + dma-names = "rx"; + resets = <0x02 0x82>; + reset-names = "pdm-m"; + pinctrl-names = "default"; + pinctrl-0 = <0x44 0x45 0x46 0x47 0x48 0x49>; + status = "disabled"; + phandle = <0xd4>; + }; + + crypto@ff0b0000 { + compatible = "rockchip,px30-crypto"; + reg = <0x00 0xff0b0000 0x00 0x4000>; + interrupts = <0x00 0x52 0x04>; + clocks = <0x02 0xac 0x02 0xf1 0x02 0x30 0x02 0x31>; + clock-names = "aclk\0hclk\0sclk\0apb_pclk"; + resets = <0x02 0x74>; + reset-names = "crypto-rst"; + status = "disabled"; + phandle = <0xd5>; + }; + + rng@ff0b0000 { + compatible = "rockchip,cryptov2-rng"; + reg = <0x00 0xff0b0000 0x00 0x4000>; + clocks = <0x02 0x30 0x02 0x31 0x02 0xac 0x02 0xf1>; + clock-names = "clk_crypto\0clk_crypto_apk\0aclk_crypto\0hclk_crypto"; + assigned-clocks = <0x02 0x30 0x02 0x31 0x02 0xac 0x02 0xf1>; + assigned-clock-rates = <0x8f0d180 0x8f0d180 0xbebc200 0x5f5e100>; + resets = <0x02 0x74>; + reset-names = "reset"; + status = "okay"; + phandle = <0xd6>; + }; + + interrupt-controller@ff131000 { + compatible = "arm,gic-400"; + #interrupt-cells = <0x03>; + #address-cells = <0x00>; + interrupt-controller; + reg = <0x00 0xff131000 0x00 0x1000 0x00 0xff132000 0x00 0x2000 0x00 0xff134000 0x00 0x2000 0x00 0xff136000 0x00 0x2000>; + interrupts = <0x01 0x09 0xf04>; + phandle = <0x01>; + }; + + syscon@ff140000 { + compatible = "rockchip,px30-grf\0syscon\0simple-mfd"; + reg = <0x00 0xff140000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0x2f>; + + io-domains { + compatible = "rockchip,px30-io-voltage-domain"; + status = "okay"; + vccio1-supply = <0x4a>; + vccio2-supply = <0x4a>; + vccio3-supply = <0x4b>; + vccio4-supply = <0x4b>; + vccio5-supply = <0x4b>; + vccio6-supply = <0x4b>; + phandle = <0xd7>; + }; + + lvds { + compatible = "rockchip,px30-lvds"; + phys = <0x4c>; + phy-names = "phy"; + status = "disabled"; + phandle = <0xd8>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x12>; + phandle = <0xa2>; + }; + }; + }; + }; + + rgb { + compatible = "rockchip,px30-rgb"; + pinctrl-names = "default\0sleep"; + pinctrl-0 = <0x4d>; + pinctrl-1 = <0x4e>; + status = "disabled"; + phys = <0x4c>; + phy-names = "phy"; + phandle = <0xd9>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x14>; + phandle = <0xa4>; + }; + }; + }; + }; + }; + + syscon@ff148000 { + compatible = "syscon\0simple-mfd"; + reg = <0x00 0xff148000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0xda>; + + pvtm { + compatible = "rockchip,px30-pvtm"; + clocks = <0x02 0x4a>; + clock-names = "core"; + status = "okay"; + phandle = <0xdb>; + }; + }; + + serial@ff158000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff158000 0x00 0x100>; + interrupts = <0x00 0x10 0x04>; + clocks = <0x02 0x18 0x02 0x149>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x02 0x2b 0x03>; + pinctrl-names = "default"; + pinctrl-0 = <0x4f 0x50>; + status = "okay"; + phandle = <0xdc>; + }; + + serial@ff160000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff160000 0x00 0x100>; + interrupts = <0x00 0x11 0x04>; + clocks = <0x02 0x19 0x02 0x14a>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x04 0x2b 0x05>; + pinctrl-names = "default"; + pinctrl-0 = <0x51>; + status = "disabled"; + phandle = <0xdd>; + }; + + serial@ff168000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff168000 0x00 0x100>; + interrupts = <0x00 0x12 0x04>; + clocks = <0x02 0x1a 0x02 0x14b>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x06 0x2b 0x07>; + pinctrl-names = "default"; + pinctrl-0 = <0x52 0x53 0x54>; + status = "disabled"; + phandle = <0xde>; + }; + + serial@ff170000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff170000 0x00 0x100>; + interrupts = <0x00 0x13 0x04>; + clocks = <0x02 0x1b 0x02 0x14c>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x08 0x2b 0x09>; + pinctrl-names = "default"; + pinctrl-0 = <0x55 0x56 0x57>; + status = "disabled"; + phandle = <0xdf>; + }; + + serial@ff178000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff178000 0x00 0x100>; + interrupts = <0x00 0x14 0x04>; + clocks = <0x02 0x1c 0x02 0x14d>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x0a 0x2b 0x0b>; + pinctrl-names = "default"; + pinctrl-0 = <0x58 0x59 0x5a>; + status = "disabled"; + phandle = <0xe0>; + }; + + i2c@ff180000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff180000 0x00 0x1000>; + clocks = <0x02 0x1d 0x02 0x14e>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x07 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x5b>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + clock-frequency = <0x61a80>; + i2c-scl-rising-time-ns = <0x118>; + i2c-scl-falling-time-ns = <0x10>; + phandle = <0xe1>; + + pmic@20 { + compatible = "rockchip,rk817"; + reg = <0x20>; + interrupt-parent = <0x5c>; + interrupts = <0x0a 0x08>; + pinctrl-names = "default\0pmic-sleep\0pmic-power-off\0pmic-reset"; + pinctrl-0 = <0x5d>; + pinctrl-1 = <0x5e 0x5f>; + pinctrl-2 = <0x60 0x61>; + pinctrl-3 = <0x62 0x63>; + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <0x01>; + clock-output-names = "rk808-clkout1\0rk808-clkout2"; + pmic-reset-func = <0x01>; + vcc1-supply = <0x64>; + vcc2-supply = <0x64>; + vcc3-supply = <0x64>; + vcc4-supply = <0x64>; + vcc5-supply = <0x64>; + vcc6-supply = <0x64>; + vcc7-supply = <0x64>; + vcc8-supply = <0x64>; + vcc9-supply = <0x65>; + phandle = <0xe2>; + + pwrkey { + status = "okay"; + }; + + pinctrl_rk8xx { + gpio-controller; + #gpio-cells = <0x02>; + phandle = <0xe3>; + + rk817_ts_gpio1 { + pins = "gpio_ts"; + function = "pin_fun1"; + phandle = <0xe4>; + }; + + rk817_gt_gpio2 { + pins = "gpio_gt"; + function = "pin_fun1"; + phandle = <0xe5>; + }; + + rk817_pin_ts { + pins = "gpio_ts"; + function = "pin_fun0"; + phandle = <0xe6>; + }; + + rk817_pin_gt { + pins = "gpio_gt"; + function = "pin_fun0"; + phandle = <0xe7>; + }; + + rk817_slppin_null { + pins = "gpio_slp"; + function = "pin_fun0"; + phandle = <0xe8>; + }; + + rk817_slppin_slp { + pins = "gpio_slp"; + function = "pin_fun1"; + phandle = <0x5f>; + }; + + rk817_slppin_pwrdn { + pins = "gpio_slp"; + function = "pin_fun2"; + phandle = <0x61>; + }; + + rk817_slppin_rst { + pins = "gpio_slp"; + function = "pin_fun3"; + phandle = <0x63>; + }; + }; + + regulators { + + DCDC_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xe7ef0>; + regulator-max-microvolt = <0x118c30>; + regulator-ramp-delay = <0x1771>; + regulator-initial-mode = <0x02>; + regulator-name = "vdd_logic"; + phandle = <0x0e>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0xe7ef0>; + }; + }; + + DCDC_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xe7ef0>; + regulator-max-microvolt = <0x149970>; + regulator-ramp-delay = <0x1771>; + regulator-initial-mode = <0x02>; + regulator-name = "vdd_arm"; + phandle = <0x06>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0xe7ef0>; + }; + }; + + DCDC_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x02>; + regulator-name = "vcc_ddr"; + phandle = <0xe9>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + DCDC_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-initial-mode = <0x02>; + regulator-name = "vcc_3v3"; + phandle = <0x4b>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG1 { + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + regulator-name = "vcc_1v0"; + phandle = <0xea>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0xf4240>; + }; + }; + + LDO_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + regulator-name = "vcc1v8_soc"; + phandle = <0x88>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x1b7740>; + }; + }; + + LDO_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + regulator-name = "vcc1v0_soc"; + phandle = <0xeb>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0xf4240>; + }; + }; + + LDO_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "vcc3v3_pmu"; + phandle = <0x29>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + regulator-name = "vccio_sd"; + phandle = <0x4a>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x1b7740>; + }; + }; + + LDO_REG6 { + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x2dc6c0>; + regulator-boot-on; + regulator-name = "vcc_sd"; + phandle = <0x93>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x2dc6c0>; + }; + }; + + LDO_REG7 { + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "vcc_backlight"; + phandle = <0x9e>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG8 { + regulator-min-microvolt = <0x2ab980>; + regulator-max-microvolt = <0x2ab980>; + regulator-name = "vcc_lcd"; + phandle = <0x9f>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x2ab980>; + }; + }; + + BOOST { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x4c4b40>; + regulator-max-microvolt = <0x5265c0>; + regulator-name = "boost"; + phandle = <0x65>; + }; + + OTG_SWITCH { + regulator-boot-on; + regulator-name = "otg_switch"; + phandle = <0xec>; + }; + }; + + battery { + compatible = "rk817,battery"; + ocv_table = <0xc5d 0xc94 0xcd0 0xd02 0xd34 0xd66 0xd98 0xdca 0xdfc 0xe2e 0xe56 0xe7e 0xea6 0xece 0xef6 0xf1e 0xf46 0xf6e 0xf96 0xf9b 0xfa0>; + design_capacity = <0xd34>; + design_qmax = <0xe86>; + bat_res = <0x64>; + sleep_enter_current = <0x12c>; + sleep_exit_current = <0x12c>; + sleep_filter_current = <0x64>; + power_off_thresd = <0xbb8>; + zero_algorithm_vol = <0xf0a>; + max_soc_offset = <0x3c>; + monitor_sec = <0x05>; + virtual_power = <0x00>; + sample_res = <0x0a>; + }; + + charger { + compatible = "rk817,charger"; + min_input_voltage = <0x1194>; + max_input_current = <0x5dc>; + max_chrg_current = <0x7d0>; + max_chrg_voltage = <0x1068>; + chrg_term_mode = <0x00>; + chrg_finish_cur = <0x34>; + virtual_power = <0x00>; + sample_res = <0x0a>; + dc_det_gpio = <0x5c 0x0b 0x00>; + bat_low_gpio = <0x66 0x0d 0x00>; + extcon = <0x67>; + }; + + codec { + #sound-dai-cells = <0x00>; + compatible = "rockchip,rk817-codec"; + clocks = <0x02 0x15>; + clock-names = "mclk"; + pinctrl-names = "default"; + pinctrl-0 = <0x68>; + hp-volume = <0x14>; + spk-volume = <0x03>; + status = "okay"; + phandle = <0xc3>; + }; + }; + }; + + i2c@ff190000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff190000 0x00 0x1000>; + clocks = <0x02 0x1e 0x02 0x14f>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x08 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x69>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + clock-frequency = <0x61a80>; + phandle = <0xed>; + }; + + i2c@ff1a0000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff1a0000 0x00 0x1000>; + clocks = <0x02 0x1f 0x02 0x150>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x09 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x6a>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xee>; + }; + + i2c@ff1b0000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff1b0000 0x00 0x1000>; + clocks = <0x02 0x20 0x02 0x151>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x0a 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x6b>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xef>; + }; + + spi@ff1d0000 { + compatible = "rockchip,px30-spi\0rockchip,rk3066-spi"; + reg = <0x00 0xff1d0000 0x00 0x1000>; + interrupts = <0x00 0x1a 0x04>; + #address-cells = <0x01>; + #size-cells = <0x00>; + clocks = <0x02 0x24 0x02 0x155>; + clock-names = "spiclk\0apb_pclk"; + dmas = <0x2b 0x0c 0x2b 0x0d>; + dma-names = "tx\0rx"; + pinctrl-names = "default\0high_speed"; + pinctrl-0 = <0x6c 0x6d 0x6e 0x6f>; + pinctrl-1 = <0x70 0x6d 0x71 0x72>; + status = "disabled"; + phandle = <0xf0>; + }; + + spi@ff1d8000 { + compatible = "rockchip,px30-spi\0rockchip,rk3066-spi"; + reg = <0x00 0xff1d8000 0x00 0x1000>; + interrupts = <0x00 0x1b 0x04>; + #address-cells = <0x01>; + #size-cells = <0x00>; + clocks = <0x02 0x25 0x02 0x156>; + clock-names = "spiclk\0apb_pclk"; + dmas = <0x2b 0x0e 0x2b 0x0f>; + dma-names = "tx\0rx"; + pinctrl-names = "default\0high_speed"; + pinctrl-0 = <0x73 0x74 0x75 0x76 0x77>; + pinctrl-1 = <0x78 0x74 0x75 0x79 0x7a>; + status = "disabled"; + phandle = <0xf1>; + }; + + watchdog@ff1e0000 { + compatible = "snps,dw-wdt"; + reg = <0x00 0xff1e0000 0x00 0x100>; + clocks = <0x02 0x15b>; + interrupts = <0x00 0x25 0x04>; + resets = <0x02 0xb5>; + reset-names = "reset"; + status = "disabled"; + phandle = <0xf2>; + }; + + pwm@ff200000 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200000 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7b>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "okay"; + phandle = <0xbc>; + }; + + pwm@ff200010 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200010 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7c>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "okay"; + phandle = <0xc1>; + }; + + pwm@ff200020 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200020 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7d>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf3>; + }; + + pwm@ff200030 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200030 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7e>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf4>; + }; + + pwm@ff208000 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208000 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7f>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf5>; + }; + + pwm@ff208010 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208010 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x80>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf6>; + }; + + pwm@ff208020 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208020 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x81>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf7>; + }; + + pwm@ff208030 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208030 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x82>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf8>; + }; + + rktimer@ff210000 { + compatible = "rockchip,rk3288-timer"; + reg = <0x00 0xff210000 0x00 0x1000>; + interrupts = <0x00 0x1e 0x04>; + clocks = <0x02 0x159 0x02 0x26>; + clock-names = "pclk\0timer"; + phandle = <0xf9>; + }; + + amba { + compatible = "simple-bus"; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + + dmac@ff240000 { + compatible = "arm,pl330\0arm,primecell"; + reg = <0x00 0xff240000 0x00 0x4000>; + interrupts = <0x00 0x01 0x04 0x00 0x02 0x04>; + clocks = <0x02 0xbb>; + clock-names = "apb_pclk"; + #dma-cells = <0x01>; + peripherals-req-type-burst; + phandle = <0x2b>; + }; + }; + + thermal-zones { + phandle = <0xfa>; + + soc-thermal { + polling-delay-passive = <0x14>; + polling-delay = <0x3e8>; + sustainable-power = <0x2ee>; + thermal-sensors = <0x83 0x00>; + phandle = <0xfb>; + + trips { + + trip-point-0 { + temperature = <0x11170>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0xfc>; + }; + + trip-point-1 { + temperature = <0x14c08>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0x84>; + }; + + soc-crit { + temperature = <0x1c138>; + hysteresis = <0x7d0>; + type = "critical"; + phandle = <0xfd>; + }; + }; + + cooling-maps { + + map0 { + trip = <0x84>; + cooling-device = <0x09 0xffffffff 0xffffffff>; + contribution = <0x1000>; + }; + + map1 { + trip = <0x84>; + cooling-device = <0x85 0xffffffff 0xffffffff>; + contribution = <0x1000>; + }; + }; + }; + + gpu-thermal { + polling-delay-passive = <0x64>; + polling-delay = <0x3e8>; + thermal-sensors = <0x83 0x01>; + phandle = <0xfe>; + }; + }; + + tsadc@ff280000 { + compatible = "rockchip,px30-tsadc"; + reg = <0x00 0xff280000 0x00 0x100>; + interrupts = <0x00 0x24 0x04>; + rockchip,grf = <0x2f>; + clocks = <0x02 0x2c 0x02 0x158>; + clock-names = "tsadc\0apb_pclk"; + assigned-clocks = <0x02 0x2c>; + assigned-clock-rates = <0xc350>; + resets = <0x02 0xa8>; + reset-names = "tsadc-apb"; + #thermal-sensor-cells = <0x01>; + rockchip,hw-tshut-temp = <0x1d4c0>; + status = "okay"; + pinctrl-names = "gpio\0otpout"; + pinctrl-0 = <0x86>; + pinctrl-1 = <0x87>; + phandle = <0x83>; + }; + + saradc@ff288000 { + compatible = "rockchip,px30-saradc\0rockchip,rk3399-saradc"; + reg = <0x00 0xff288000 0x00 0x100>; + interrupts = <0x00 0x54 0x04>; + #io-channel-cells = <0x01>; + clocks = <0x02 0x2d 0x02 0x157>; + clock-names = "saradc\0apb_pclk"; + resets = <0x02 0xa5>; + reset-names = "saradc-apb"; + status = "okay"; + vref-supply = <0x88>; + phandle = <0xbe>; + }; + + otp@ff290000 { + compatible = "rockchip,px30-otp"; + reg = <0x00 0xff290000 0x00 0x4000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + clocks = <0x02 0x2f 0x02 0x15a 0x02 0x161>; + clock-names = "clk_otp\0pclk_otp\0pclk_otp_phy"; + resets = <0x02 0xb4>; + reset-names = "otp_phy"; + phandle = <0xff>; + + id@7 { + reg = <0x07 0x10>; + phandle = <0x0f>; + }; + + cpu-leakage@17 { + reg = <0x17 0x01>; + phandle = <0x07>; + }; + + performance@1e { + reg = <0x1e 0x01>; + bits = <0x04 0x03>; + phandle = <0x08>; + }; + }; + + clock-controller@ff2b0000 { + compatible = "rockchip,px30-cru"; + reg = <0x00 0xff2b0000 0x00 0x1000>; + rockchip,grf = <0x2f>; + rockchip,boost = <0x89>; + #clock-cells = <0x01>; + #reset-cells = <0x01>; + assigned-clocks = <0x02 0x04>; + assigned-clock-rates = <0x3dfd2400>; + phandle = <0x02>; + }; + + cpu-boost@ff2b8000 { + compatible = "syscon"; + reg = <0x00 0xff2b8000 0x00 0x1000>; + rockchip,boost-low-con0 = <0x1032>; + rockchip,boost-low-con1 = <0x1441>; + rockchip,boost-high-con0 = <0x1036>; + rockchip,boost-high-con1 = <0x1441>; + rockchip,boost-backup-pll = <0x01>; + rockchip,boost-backup-pll-usage = <0x00>; + rockchip,boost-switch-threshold = <0x249f00>; + rockchip,boost-statis-threshold = <0x100>; + rockchip,boost-statis-enable = <0x00>; + rockchip,boost-enable = <0x00>; + phandle = <0x89>; + }; + + pmu-clock-controller@ff2bc000 { + compatible = "rockchip,px30-pmucru"; + reg = <0x00 0xff2bc000 0x00 0x1000>; + rockchip,grf = <0x2f>; + #clock-cells = <0x01>; + #reset-cells = <0x01>; + assigned-clocks = <0x2a 0x01 0x2a 0x08 0x2a 0x05 0x02 0x07 0x02 0xab 0x02 0xb0 0x02 0xf0 0x02 0xf5 0x02 0x140 0x02 0x49>; + assigned-clock-rates = <0x47868c00 0x5f5e100 0x18cba80 0x23c34600 0xbebc200 0xbebc200 0x8f0d180 0x8f0d180 0x5f5e100 0xbebc200>; + phandle = <0x2a>; + }; + + syscon@ff2c0000 { + compatible = "rockchip,px30-usb2phy-grf\0syscon\0simple-mfd"; + reg = <0x00 0xff2c0000 0x00 0x10000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0x100>; + + usb2-phy@100 { + compatible = "rockchip,px30-usb2phy\0rockchip,rk3328-usb2phy"; + reg = <0x100 0x10>; + clocks = <0x2a 0x0a>; + clock-names = "phyclk"; + #clock-cells = <0x00>; + assigned-clocks = <0x02 0x0e 0x02 0x55>; + assigned-clock-parents = <0x67 0x02 0x0e>; + clock-output-names = "usb480m_phy"; + status = "okay"; + phandle = <0x67>; + + host-port { + #phy-cells = <0x00>; + interrupts = <0x00 0x44 0x04>; + interrupt-names = "linestate"; + status = "okay"; + phandle = <0x8c>; + }; + + otg-port { + #phy-cells = <0x00>; + interrupts = <0x00 0x42 0x04 0x00 0x41 0x04 0x00 0x40 0x04>; + interrupt-names = "otg-bvalid\0otg-id\0linestate"; + status = "disabled"; + phandle = <0x8b>; + }; + }; + }; + + video-phy@ff2e0000 { + compatible = "rockchip,px30-video-phy"; + reg = <0x00 0xff2e0000 0x00 0x10000 0x00 0xff450000 0x00 0x10000>; + clocks = <0x2a 0x0b 0x02 0x145 0x02 0x144>; + clock-names = "ref\0pclk_phy\0pclk_host"; + #clock-cells = <0x00>; + resets = <0x02 0x3e>; + reset-names = "rst"; + power-domains = <0x8a 0x0c>; + #phy-cells = <0x00>; + status = "okay"; + phandle = <0x4c>; + }; + + mipi-dphy-rx0@ff2f0000 { + compatible = "rockchip,rk3326-mipi-dphy"; + reg = <0x00 0xff2f0000 0x00 0x4000>; + clocks = <0x02 0x146>; + clock-names = "dphy-ref"; + power-domains = <0x8a 0x0d>; + rockchip,grf = <0x2f>; + status = "okay"; + phandle = <0x101>; + }; + + usb@ff300000 { + compatible = "rockchip,px30-usb\0rockchip,rk3066-usb\0snps,dwc2"; + reg = <0x00 0xff300000 0x00 0x40000>; + interrupts = <0x00 0x3e 0x04>; + clocks = <0x02 0x102>; + clock-names = "otg"; + power-domains = <0x8a 0x05>; + dr_mode = "otg"; + g-np-tx-fifo-size = <0x10>; + g-rx-fifo-size = <0x118>; + g-tx-fifo-size = <0x100 0x80 0x80 0x40 0x20 0x10>; + g-use-dma; + phys = <0x8b>; + phy-names = "usb2-phy"; + status = "okay"; + phandle = <0x102>; + }; + + usb@ff340000 { + compatible = "generic-ehci"; + reg = <0x00 0xff340000 0x00 0x10000>; + interrupts = <0x00 0x3c 0x04>; + clocks = <0x02 0x103 0x67>; + clock-names = "usbhost\0utmi"; + power-domains = <0x8a 0x05>; + phys = <0x8c>; + phy-names = "usb"; + status = "disabled"; + phandle = <0x103>; + }; + + usb@ff350000 { + compatible = "generic-ohci"; + reg = <0x00 0xff350000 0x00 0x10000>; + interrupts = <0x00 0x3d 0x04>; + clocks = <0x02 0x103 0x67>; + clock-names = "usbhost\0utmi"; + power-domains = <0x8a 0x05>; + phys = <0x8c>; + phy-names = "usb"; + status = "disabled"; + phandle = <0x104>; + }; + + ethernet@ff360000 { + compatible = "rockchip,px30-gmac"; + reg = <0x00 0xff360000 0x00 0x10000>; + rockchip,grf = <0x2f>; + interrupts = <0x00 0x2b 0x04>; + interrupt-names = "macirq"; + clocks = <0x02 0x3e 0x02 0x3f 0x02 0x3f 0x02 0x40 0x02 0x41 0x02 0xb2 0x02 0x143 0x02 0x4c>; + clock-names = "stmmaceth\0mac_clk_rx\0mac_clk_tx\0clk_mac_ref\0clk_mac_refout\0aclk_mac\0pclk_mac\0clk_mac_speed"; + phy-mode = "rmii"; + pinctrl-names = "default"; + pinctrl-0 = <0x8d 0x8e>; + resets = <0x02 0x5e>; + reset-names = "stmmaceth"; + power-domains = <0x8a 0x09>; + status = "disabled"; + phandle = <0x105>; + }; + + dwmmc@ff370000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff370000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0xf7 0x02 0x3b 0x02 0x43 0x02 0x44>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x3b>; + assigned-clock-parents = <0x02 0x57>; + power-domains = <0x8a 0x07>; + fifo-depth = <0x100>; + interrupts = <0x00 0x36 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x8f 0x90 0x91 0x92>; + status = "okay"; + bus-width = <0x04>; + cap-mmc-highspeed; + cap-sd-highspeed; + supports-sd; + card-detect-delay = <0x320>; + ignore-pm-notify; + cd-gpios = <0x5c 0x03 0x01>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <0x4a>; + vmmc-supply = <0x93>; + phandle = <0x106>; + }; + + dwmmc@ff380000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff380000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0xff 0x02 0x38 0x02 0x45 0x02 0x46>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x38>; + assigned-clock-parents = <0x02 0x51>; + power-domains = <0x8a 0x0a>; + fifo-depth = <0x100>; + interrupts = <0x00 0x37 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x94 0x95 0x96>; + status = "okay"; + bus-width = <0x04>; + cap-mmc-highspeed; + cap-sd-highspeed; + supports-sd; + card-detect-delay = <0x320>; + ignore-pm-notify; + cd-gpios = <0x97 0x0e 0x01>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <0x4a>; + vmmc-supply = <0x93>; + phandle = <0x107>; + }; + + dwmmc@ff390000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff390000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0x100 0x02 0x39 0x02 0x47 0x02 0x48>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x39>; + assigned-clock-parents = <0x02 0x53>; + power-domains = <0x8a 0x0a>; + fifo-depth = <0x100>; + interrupts = <0x00 0x35 0x04>; + status = "disabled"; + phandle = <0x108>; + }; + + nandc@ff3b0000 { + compatible = "rockchip,rk-nandc"; + reg = <0x00 0xff3b0000 0x00 0x4000>; + interrupts = <0x00 0x39 0x04>; + nandc_id = <0x00>; + clocks = <0x02 0x37 0x02 0xfe>; + clock-names = "clk_nandc\0hclk_nandc"; + assigned-clocks = <0x02 0x37>; + assigned-clock-parents = <0x02 0x4f>; + power-domains = <0x8a 0x0a>; + status = "disabled"; + phandle = <0x109>; + }; + + sfc@ff3a0000 { + compatible = "rockchip,sfc"; + reg = <0x00 0xff3a0000 0x00 0x4000>; + interrupts = <0x00 0x38 0x04>; + clocks = <0x02 0x3a 0x02 0x101>; + clock-names = "clk_sfc\0hclk_sfc"; + assigned-clocks = <0x02 0x3a>; + assigned-clock-rates = <0x989680>; + status = "disabled"; + phandle = <0x10a>; + }; + + gpu@ff400000 { + compatible = "arm,malit602\0arm,malit60x\0arm,malit6xx\0arm,mali-midgard"; + reg = <0x00 0xff400000 0x00 0x4000>; + interrupts = <0x00 0x2d 0x04 0x00 0x2e 0x04 0x00 0x2f 0x04>; + interrupt-names = "GPU\0MMU\0JOB"; + clocks = <0x02 0x49>; + clock-names = "clk_mali"; + power-domains = <0x8a 0x0e>; + #cooling-cells = <0x02>; + operating-points-v2 = <0x98>; + status = "okay"; + mali-supply = <0x0e>; + phandle = <0x85>; + + power_model { + compatible = "arm,mali-simple-power-model"; + static-coefficient = <0x64578>; + dynamic-coefficient = <0x2dd>; + ts = <0x7d00 0x125c 0xffffffb0 0x02>; + thermal-zone = "gpu-thermal"; + }; + }; + + gpu-opp-table { + compatible = "operating-points-v2"; + rockchip,thermal-zone = "soc-thermal"; + rockchip,temp-hysteresis = <0x1388>; + rockchip,low-temp = <0x00>; + rockchip,low-temp-min-volt = <0xf4240>; + rockchip,low-temp-adjust-volt = <0x00 0x1e0 0xc350>; + rockchip,max-volt = <0x11edd8>; + rockchip,evb-irdrop = <0x61a8>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-ch = <0x00 0x00>; + phandle = <0x98>; + + opp-400000000 { + opp-hz = <0x00 0x17d78400>; + opp-microvolt = <0x100590>; + opp-microvolt-L0 = <0x100590>; + opp-microvolt-L1 = <0xfa3e8>; + opp-microvolt-L2 = <0xee098>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-480000000 { + opp-hz = <0x00 0x1c9c3800>; + opp-microvolt = <0x112a88>; + opp-microvolt-L0 = <0x112a88>; + opp-microvolt-L1 = <0x10c8e0>; + opp-microvolt-L2 = <0x100590>; + opp-microvolt-L3 = <0xf4240>; + }; + + opp-520000000 { + opp-hz = <0x00 0x1efe9200>; + opp-microvolt = <0x118c30>; + opp-microvolt-L0 = <0x118c30>; + opp-microvolt-L1 = <0x118c30>; + opp-microvolt-L2 = <0x10c8e0>; + opp-microvolt-L3 = <0x100590>; + }; + }; + + hevc_service@ff440000 { + compatible = "rockchip,hevc_sub"; + iommu_enabled = <0x01>; + reg = <0x00 0xff440000 0x00 0x400>; + interrupts = <0x00 0x31 0x04>; + interrupt-names = "irq_dec"; + dev_mode = <0x01>; + iommus = <0x99>; + allocator = <0x01>; + phandle = <0x9c>; + }; + + vpu_service@ff442000 { + compatible = "rockchip,vpu_sub"; + iommu_enabled = <0x01>; + reg = <0x00 0xff442000 0x00 0x800>; + interrupts = <0x00 0x50 0x04 0x00 0x4f 0x04>; + interrupt-names = "irq_enc\0irq_dec"; + dev_mode = <0x00>; + iommus = <0x9a>; + allocator = <0x01>; + phandle = <0x9b>; + }; + + vpu_combo { + compatible = "rockchip,vpu_combo"; + subcnt = <0x02>; + rockchip,grf = <0x2f>; + rockchip,sub = <0x9b 0x9c>; + clocks = <0x02 0xaf 0x02 0xf4 0x02 0x4b>; + clock-names = "aclk_vcodec\0hclk_vcodec\0clk_core"; + resets = <0x02 0x24 0x02 0x26 0x02 0x25 0x02 0x27 0x02 0x3f>; + reset-names = "video_a\0video_h\0niu_a\0niu_h\0video_core"; + power-domains = <0x8a 0x0b>; + mode_bit = <0x0f>; + mode_ctrl = <0x410>; + status = "okay"; + phandle = <0x10b>; + }; + + iommu@ff440440 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff440440 0x00 0x40 0x00 0xff440480 0x00 0x40>; + interrupts = <0x00 0x32 0x04>; + interrupt-names = "hevc_mmu"; + clocks = <0x02 0xaf 0x02 0xf4>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0b>; + #iommu-cells = <0x00>; + phandle = <0x99>; + }; + + iommu@ff442800 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff442800 0x00 0x100>; + interrupts = <0x00 0x51 0x04>; + interrupt-names = "vpu_mmu"; + clocks = <0x02 0xaf 0x02 0xf4>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0b>; + #iommu-cells = <0x00>; + phandle = <0x9a>; + }; + + dsi@ff450000 { + compatible = "rockchip,px30-mipi-dsi"; + reg = <0x00 0xff450000 0x00 0x10000>; + interrupts = <0x00 0x4b 0x04>; + clocks = <0x02 0x144 0x4c>; + clock-names = "pclk\0hs_clk"; + resets = <0x02 0x3d>; + reset-names = "apb"; + phys = <0x4c>; + phy-names = "mipi_dphy"; + power-domains = <0x8a 0x0c>; + rockchip,grf = <0x2f>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + phandle = <0x10c>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x13>; + status = "okay"; + phandle = <0xa3>; + }; + }; + }; + + panel@0 { + compatible = "elida,kd35t133\0simple-panel-dsi"; + reg = <0x00>; + backlight = <0x9d>; + backlight-supply = <0x9e>; + power-supply = <0x9f>; + reset-gpios = <0x97 0x10 0x01>; + reset-delay-ms = <0x96>; + init-delay-ms = <0x14>; + enable-delay-ms = <0x78>; + prepare-delay-ms = <0x14>; + unprepare-delay-ms = <0x14>; + disable-delay-ms = <0x32>; + width-mm = <0x34>; + height-mm = <0x46>; + dsi,flags = <0xa03>; + dsi,format = <0x00>; + dsi,lanes = <0x04>; + panel-init-sequence = [15 00 02 ff 30 15 00 02 ff 52 15 00 02 ff 01 15 00 02 e3 00 15 00 02 40 0a 15 00 02 03 40 15 00 02 04 00 15 00 02 05 03 15 00 02 24 12 15 00 02 25 1e 15 00 02 26 6f 15 00 02 27 52 15 00 02 28 67 15 00 02 29 01 15 00 02 2a df 15 00 02 37 9c 15 00 02 38 a7 15 00 02 39 53 15 00 02 44 00 15 00 02 49 3c 15 00 02 59 fe 15 00 02 5c 00 15 00 02 80 20 15 00 02 91 77 15 00 02 92 77 15 00 02 a0 55 15 00 02 a1 50 15 00 02 a4 9c 15 00 02 a7 02 15 00 02 a8 01 15 00 02 a9 21 15 00 02 aa fc 15 00 02 ab 28 15 00 02 ac 06 15 00 02 ad 06 15 00 02 ae 06 15 00 02 af 03 15 00 02 b0 08 15 00 02 b1 26 15 00 02 b2 28 15 00 02 b3 28 15 00 02 b4 33 15 00 02 b5 08 15 00 02 b6 26 15 00 02 b7 08 15 00 02 b8 26 15 00 02 ff 30 15 00 02 ff 52 15 00 02 ff 02 15 00 02 b0 0b 15 00 02 b1 16 15 00 02 b2 17 15 00 02 b3 2c 15 00 02 b4 32 15 00 02 b5 3b 15 00 02 b6 29 15 00 02 b7 40 15 00 02 b8 0d 15 00 02 b9 05 15 00 02 ba 12 15 00 02 bb 10 15 00 02 bc 12 15 00 02 bd 15 15 00 02 be 19 15 00 02 bf 0e 15 00 02 c0 16 15 00 02 c1 0a 15 00 02 d0 0c 15 00 02 d1 17 15 00 02 d2 14 15 00 02 d3 2e 15 00 02 d4 32 15 00 02 d5 3c 15 00 02 d6 22 15 00 02 d7 3d 15 00 02 d8 0d 15 00 02 d9 07 15 00 02 da 13 15 00 02 db 13 15 00 02 dc 11 15 00 02 dd 15 15 00 02 de 19 15 00 02 df 10 15 00 02 e0 17 15 00 02 e1 0a 15 00 02 ff 30 15 00 02 ff 52 15 00 02 ff 03 15 00 02 00 2a 15 00 02 01 2a 15 00 02 02 2a 15 00 02 03 2a 15 00 02 04 61 15 00 02 05 80 15 00 02 06 c7 15 00 02 07 01 15 00 02 08 82 15 00 02 09 83 15 00 02 30 2a 15 00 02 31 2a 15 00 02 32 2a 15 00 02 33 2a 15 00 02 34 a1 15 00 02 35 c5 15 00 02 36 80 15 00 02 37 23 15 00 02 40 82 15 00 02 41 83 15 00 02 42 80 15 00 02 43 81 15 00 02 44 55 15 00 02 45 e6 15 00 02 46 e5 15 00 02 47 55 15 00 02 48 e8 15 00 02 49 e7 15 00 02 50 02 15 00 02 51 01 15 00 02 52 04 15 00 02 53 03 15 00 02 54 55 15 00 02 55 ea 15 00 02 56 e9 15 00 02 57 55 15 00 02 58 ec 15 00 02 59 eb 15 00 02 7e 02 15 00 02 7f 80 15 00 02 e0 5a 15 00 02 b1 00 15 00 02 b4 0e 15 00 02 b5 0f 15 00 02 b6 04 15 00 02 b7 07 15 00 02 b8 06 15 00 02 b9 05 15 00 02 ba 0f 15 00 02 c7 00 15 00 02 ca 0e 15 00 02 cb 0f 15 00 02 cc 04 15 00 02 cd 07 15 00 02 ce 06 15 00 02 cf 05 15 00 02 d0 0f 15 00 02 81 0f 15 00 02 84 0e 15 00 02 85 0f 15 00 02 86 07 15 00 02 87 04 15 00 02 88 05 15 00 02 89 06 15 00 02 8a 00 15 00 02 97 0f 15 00 02 9a 0e 15 00 02 9b 0f 15 00 02 9c 07 15 00 02 9d 04 15 00 02 9e 05 15 00 02 9f 06 15 00 02 a0 00 15 00 02 ff 30 15 00 02 ff 52 15 00 02 ff 02 15 00 02 01 01 15 00 02 02 da 15 00 02 03 ba 15 00 02 04 a8 15 00 02 05 9a 15 00 02 06 70 15 00 02 07 ff 15 00 02 08 91 15 00 02 09 90 15 00 02 0a ff 15 00 02 0b 8f 15 00 02 0c 60 15 00 02 0d 58 15 00 02 0e 48 15 00 02 0f 38 15 00 02 10 2b 15 00 02 ff 30 15 00 02 ff 52 15 00 02 ff 00 15 00 02 36 02 15 00 02 3a 70 05 c8 01 11 05 14 01 29]; + panel-exit-sequence = <0x5140128 0x50a0110>; + + display-timings { + native-mode = <0xa0>; + + 60Hz { + clock-frequency = <0x1ba8140>; + hactive = <0x280>; + vactive = <0x1e0>; + hfront-porch = <0x2e>; + hsync-len = <0x02>; + hback-porch = <0x2c>; + vfront-porch = <0x10>; + vsync-len = <0x02>; + vback-porch = <0x0e>; + hsync-active = <0x00>; + vsync-active = <0x00>; + de-active = <0x00>; + pixelclk-active = <0x01>; + phandle = <0xa0>; + }; + + 50Hz { + clock-frequency = <0x1ba8140>; + hactive = <0x280>; + vactive = <0x1e0>; + hfront-porch = <0x2e>; + hsync-len = <0x02>; + hback-porch = <0x2c>; + vfront-porch = <0x10>; + vsync-len = <0x02>; + vback-porch = <0x0e>; + hsync-active = <0x00>; + vsync-active = <0x00>; + de-active = <0x00>; + pixelclk-active = <0x01>; + phandle = <0xa00>; + }; + + 75Hz { + clock-frequency = <0x1ba8140>; + hactive = <0x280>; + vactive = <0x1e0>; + hfront-porch = <0x2e>; + hsync-len = <0x02>; + hback-porch = <0x2c>; + vfront-porch = <0x10>; + vsync-len = <0x02>; + vback-porch = <0x0e>; + hsync-active = <0x00>; + vsync-active = <0x00>; + de-active = <0x00>; + pixelclk-active = <0x01>; + phandle = <0xa01>; + }; + }; + }; + }; + + vop@ff460000 { + compatible = "rockchip,px30-vop-big"; + reg = <0x00 0xff460000 0x00 0x1fc 0x00 0xff460a00 0x00 0x400>; + rockchip,grf = <0x2f>; + reg-names = "regs\0gamma_lut"; + interrupts = <0x00 0x4d 0x04>; + clocks = <0x02 0xb5 0x02 0x96 0x02 0xfb>; + clock-names = "aclk_vop\0dclk_vop\0hclk_vop"; + power-domains = <0x8a 0x0c>; + iommus = <0xa1>; + status = "okay"; + phandle = <0x10f>; + + port { + #address-cells = <0x01>; + #size-cells = <0x00>; + phandle = <0x10>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0xa2>; + phandle = <0x12>; + }; + + endpoint@1 { + reg = <0x01>; + remote-endpoint = <0xa3>; + phandle = <0x13>; + }; + + endpoint@2 { + reg = <0x02>; + remote-endpoint = <0xa4>; + phandle = <0x14>; + }; + }; + }; + + iommu@ff460f00 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff460f00 0x00 0x100>; + interrupts = <0x00 0x4d 0x04>; + interrupt-names = "vopb_mmu"; + clocks = <0x02 0xb5 0x02 0xfb>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0c>; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xa1>; + }; + + rk_rga@ff480000 { + compatible = "rockchip,rga2"; + reg = <0x00 0xff480000 0x00 0x1000>; + interrupts = <0x00 0x4c 0x04>; + clocks = <0x02 0xb7 0x02 0xfd 0x02 0x35>; + clock-names = "aclk_rga\0hclk_rga\0clk_rga"; + power-domains = <0x8a 0x0c>; + dma-coherent; + status = "okay"; + phandle = <0x110>; + }; + + cif@ff490000 { + compatible = "rockchip,cif"; + reg = <0x00 0xff490000 0x00 0x200>; + interrupts = <0x00 0x45 0x04>; + clocks = <0x02 0xb3 0x02 0xf9 0x02 0x160 0x02 0x34>; + clock-names = "aclk_cif0\0hclk_cif0\0pclk_cif\0cif0_out"; + resets = <0x02 0x2c 0x02 0x2d 0x02 0x2e>; + reset-names = "rst_cif_a\0rst_cif_h\0rst_cif_pclkin"; + power-domains = <0x8a 0x0d>; + pinctrl-names = "cif_pin_all"; + pinctrl-0 = <0xa5>; + iommus = <0xa6>; + status = "disabled"; + phandle = <0x111>; + }; + + cif-new@ff490000 { + compatible = "rockchip,px30-cif"; + reg = <0x00 0xff490000 0x00 0x200>; + interrupts = <0x00 0x45 0x04>; + clocks = <0x02 0xb3 0x02 0xf9 0x02 0x160 0x02 0x34>; + clock-names = "aclk_cif\0hclk_cif\0pclk_cif\0cif_out"; + resets = <0x02 0x2c 0x02 0x2d 0x02 0x2e>; + reset-names = "rst_cif_a\0rst_cif_h\0rst_cif_pclkin"; + power-domains = <0x8a 0x0d>; + iommus = <0xa6>; + status = "disabled"; + phandle = <0x112>; + }; + + iommu@ff490800 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff490800 0x00 0x100>; + interrupts = <0x00 0x45 0x04>; + interrupt-names = "vip_mmu"; + clocks = <0x02 0xb3 0x02 0xf9>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0d>; + rk_iommu,disable_reset_quirk; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xa6>; + }; + + rk_isp@ff4a0000 { + compatible = "rockchip,px30-isp\0rockchip,isp"; + reg = <0x00 0xff4a0000 0x00 0x8000>; + interrupts = <0x00 0x46 0x04>; + clocks = <0x02 0xb4 0x02 0xfa 0x02 0x33 0x02 0x33 0x02 0x15f 0x02 0x34 0x02 0x34 0x02 0x146>; + clock-names = "aclk_isp\0hclk_isp\0clk_isp\0clk_isp_jpe\0pclkin_isp\0clk_cif_pll\0clk_cif_out\0pclk_dphyrx"; + resets = <0x02 0x2b 0x02 0x2f>; + reset-names = "rst_isp\0rst_mipicsiphy"; + power-domains = <0x8a 0x0d>; + pinctrl-names = "default\0isp_dvp8bit2\0isp_dvp10bit\0isp_dvp12bit"; + pinctrl-0 = <0xa7>; + pinctrl-1 = <0xa5>; + pinctrl-2 = <0xa5 0xa8>; + pinctrl-3 = <0xa9 0xa5 0xa8>; + rockchip,isp,mipiphy = <0x01>; + rockchip,isp,csiphy,reg = <0xff2f0000 0x4000>; + rockchip,grf = <0x2f>; + rockchip,cru = <0x02>; + rockchip,isp,iommu-enable = <0x01>; + iommus = <0xaa>; + status = "disabled"; + phandle = <0x113>; + }; + + rkisp1@ff4a0000 { + compatible = "rockchip,rk3326-rkisp1"; + reg = <0x00 0xff4a0000 0x00 0x8000>; + interrupts = <0x00 0x46 0x04 0x00 0x49 0x04 0x00 0x4a 0x04>; + interrupt-names = "isp_irq\0mi_irq\0mipi_irq"; + clocks = <0x02 0xb4 0x02 0xfa 0x02 0x33 0x02 0x15f>; + clock-names = "aclk_isp\0hclk_isp\0clk_isp\0pclk_isp"; + devfreq = <0xab>; + power-domains = <0x8a 0x0d>; + iommus = <0xaa>; + rockchip,grf = <0x2f>; + status = "okay"; + phandle = <0x114>; + }; + + iommu@ff4a8000 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff4a8000 0x00 0x100>; + interrupts = <0x00 0x46 0x04>; + interrupt-names = "isp_mmu"; + clocks = <0x02 0xb4 0x02 0xfa>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0d>; + rk_iommu,disable_reset_quirk; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xaa>; + }; + + qos@ff518000 { + compatible = "syscon"; + reg = <0x00 0xff518000 0x00 0x20>; + phandle = <0x18>; + }; + + qos@ff520000 { + compatible = "syscon"; + reg = <0x00 0xff520000 0x00 0x20>; + phandle = <0x28>; + }; + + qos@ff52c000 { + compatible = "syscon"; + reg = <0x00 0xff52c000 0x00 0x20>; + phandle = <0x17>; + }; + + qos@ff538000 { + compatible = "syscon"; + reg = <0x00 0xff538000 0x00 0x20>; + phandle = <0x19>; + }; + + qos@ff538080 { + compatible = "syscon"; + reg = <0x00 0xff538080 0x00 0x20>; + phandle = <0x1a>; + }; + + qos@ff538100 { + compatible = "syscon"; + reg = <0x00 0xff538100 0x00 0x20>; + phandle = <0x1b>; + }; + + qos@ff538180 { + compatible = "syscon"; + reg = <0x00 0xff538180 0x00 0x20>; + phandle = <0x1c>; + }; + + qos@ff540000 { + compatible = "syscon"; + reg = <0x00 0xff540000 0x00 0x20>; + phandle = <0x15>; + }; + + qos@ff540080 { + compatible = "syscon"; + reg = <0x00 0xff540080 0x00 0x20>; + phandle = <0x16>; + }; + + qos@ff548000 { + compatible = "syscon"; + reg = <0x00 0xff548000 0x00 0x20>; + phandle = <0x23>; + }; + + qos@ff548080 { + compatible = "syscon"; + reg = <0x00 0xff548080 0x00 0x20>; + phandle = <0x24>; + }; + + qos@ff548100 { + compatible = "syscon"; + reg = <0x00 0xff548100 0x00 0x20>; + phandle = <0x25>; + }; + + qos@ff548180 { + compatible = "syscon"; + reg = <0x00 0xff548180 0x00 0x20>; + phandle = <0x26>; + }; + + qos@ff548200 { + compatible = "syscon"; + reg = <0x00 0xff548200 0x00 0x20>; + phandle = <0x27>; + }; + + qos@ff550000 { + compatible = "syscon"; + reg = <0x00 0xff550000 0x00 0x20>; + phandle = <0x1f>; + }; + + qos@ff550080 { + compatible = "syscon"; + reg = <0x00 0xff550080 0x00 0x20>; + phandle = <0x20>; + }; + + qos@ff550100 { + compatible = "syscon"; + reg = <0x00 0xff550100 0x00 0x20>; + phandle = <0x21>; + }; + + qos@ff550180 { + compatible = "syscon"; + reg = <0x00 0xff550180 0x00 0x20>; + phandle = <0x22>; + }; + + qos@ff558000 { + compatible = "syscon"; + reg = <0x00 0xff558000 0x00 0x20>; + phandle = <0x1d>; + }; + + qos@ff558080 { + compatible = "syscon"; + reg = <0x00 0xff558080 0x00 0x20>; + phandle = <0x1e>; + }; + + dfi@ff610000 { + reg = <0x00 0xff610000 0x00 0x400>; + compatible = "rockchip,px30-dfi"; + rockchip,pmugrf = <0xac>; + status = "okay"; + phandle = <0xad>; + }; + + dmc { + compatible = "rockchip,px30-dmc"; + interrupts = <0x00 0x69 0x04>; + interrupt-names = "complete_irq"; + devfreq-events = <0xad>; + clocks = <0x02 0x54>; + clock-names = "dmc_clk"; + operating-points-v2 = <0xae>; + ddr_timing = <0xaf>; + upthreshold = <0x28>; + downdifferential = <0x14>; + system-status-freq = <0x01 0x80e80 0x08 0x6ddd0 0x02 0x2f5d0 0x20 0x6ddd0 0x1000 0x80e80 0x4000 0xa2990 0x2000 0xa2990>; + auto-min-freq = <0x50140>; + auto-freq-en = <0x01>; + #cooling-cells = <0x02>; + status = "okay"; + center-supply = <0x0e>; + phandle = <0xab>; + + ddr_power_model { + compatible = "ddr_power_model"; + dynamic-power-coefficient = <0x78>; + static-power-coefficient = <0xc8>; + ts = <0x7d00 0x125c 0xffffffb0 0x02>; + thermal-zone = "soc-thermal"; + phandle = <0x115>; + }; + }; + + dmc-opp-table { + compatible = "operating-points-v2"; + rockchip,max-volt = <0x118c30>; + rockchip,evb-irdrop = <0x61a8>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-ch = <0x00 0x00>; + phandle = <0xae>; + + opp-528000000 { + opp-hz = <0x00 0x1f78a400>; + opp-microvolt = <0xee098>; + opp-microvolt-L0 = <0xee098>; + opp-microvolt-L1 = <0xee098>; + opp-microvolt-L2 = <0xe7ef0>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-666000000 { + opp-hz = <0x00 0x27b25a80>; + opp-microvolt = <0x100590>; + opp-microvolt-L0 = <0x100590>; + opp-microvolt-L1 = <0xf4240>; + opp-microvolt-L2 = <0xee098>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-786000000 { + opp-hz = <0x00 0x2ed96880>; + opp-microvolt = <0x10c8e0>; + opp-microvolt-L0 = <0x10c8e0>; + opp-microvolt-L1 = <0x100590>; + opp-microvolt-L2 = <0xfa3e8>; + opp-microvolt-L3 = <0xf4240>; + status = "okay"; + }; + }; + + rockchip-system-monitor { + compatible = "rockchip,system-monitor"; + rockchip,thermal-zone = "soc-thermal"; + rockchip,polling-delay = <0xc8>; + phandle = <0x116>; + }; + + pinctrl { + compatible = "rockchip,px30-pinctrl"; + rockchip,grf = <0x2f>; + rockchip,pmu = <0xac>; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + phandle = <0x117>; + + gpio0@ff040000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff040000 0x00 0x100>; + interrupts = <0x00 0x03 0x04>; + clocks = <0x2a 0x14>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x5c>; + }; + + gpio1@ff250000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff250000 0x00 0x100>; + interrupts = <0x00 0x04 0x04>; + clocks = <0x02 0x15c>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0xbf>; + }; + + gpio2@ff260000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff260000 0x00 0x100>; + interrupts = <0x00 0x05 0x04>; + clocks = <0x02 0x15d>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x66>; + }; + + gpio3@ff270000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff270000 0x00 0x100>; + interrupts = <0x00 0x06 0x04>; + clocks = <0x02 0x15e>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x97>; + }; + + pcfg-pull-up { + bias-pull-up; + phandle = <0xb2>; + }; + + pcfg-pull-down { + bias-pull-down; + phandle = <0x118>; + }; + + pcfg-pull-none { + bias-disable; + phandle = <0xb1>; + }; + + pcfg-pull-none-2ma { + bias-disable; + drive-strength = <0x02>; + phandle = <0x119>; + }; + + pcfg-pull-up-2ma { + bias-pull-up; + drive-strength = <0x02>; + phandle = <0x11a>; + }; + + pcfg-pull-up-4ma { + bias-pull-up; + drive-strength = <0x04>; + phandle = <0xb3>; + }; + + pcfg-pull-none-4ma { + bias-disable; + drive-strength = <0x04>; + phandle = <0x11b>; + }; + + pcfg-pull-down-4ma { + bias-pull-down; + drive-strength = <0x04>; + phandle = <0x11c>; + }; + + pcfg-pull-none-8ma { + bias-disable; + drive-strength = <0x08>; + phandle = <0xb6>; + }; + + pcfg-pull-up-8ma { + bias-pull-up; + drive-strength = <0x08>; + phandle = <0xb4>; + }; + + pcfg-pull-none-12ma { + bias-disable; + drive-strength = <0x0c>; + phandle = <0xb8>; + }; + + pcfg-pull-up-12ma { + bias-pull-up; + drive-strength = <0x0c>; + phandle = <0xb7>; + }; + + pcfg-pull-none-smt { + bias-disable; + input-schmitt-enable; + phandle = <0xb0>; + }; + + pcfg-output-high { + output-high; + phandle = <0x11d>; + }; + + pcfg-output-low { + output-low; + phandle = <0xb9>; + }; + + pcfg-input-high { + bias-pull-up; + input-enable; + phandle = <0xb5>; + }; + + pcfg-input { + input-enable; + phandle = <0x11e>; + }; + + i2c0 { + + i2c0-xfer { + rockchip,pins = <0x00 0x08 0x01 0xb0 0x00 0x09 0x01 0xb0>; + phandle = <0x5b>; + }; + }; + + i2c1 { + + i2c1-xfer { + rockchip,pins = <0x00 0x12 0x01 0xb0 0x00 0x13 0x01 0xb0>; + phandle = <0x69>; + }; + }; + + i2c2 { + + i2c2-xfer { + rockchip,pins = <0x02 0x0f 0x02 0xb0 0x02 0x10 0x02 0xb0>; + phandle = <0x6a>; + }; + }; + + i2c3 { + + i2c3-xfer { + rockchip,pins = <0x01 0x0c 0x04 0xb0 0x01 0x0d 0x04 0xb0>; + phandle = <0x6b>; + }; + }; + + tsadc { + + tsadc-otp-gpio { + rockchip,pins = <0x00 0x06 0x00 0xb1>; + phandle = <0x86>; + }; + + tsadc-otp-out { + rockchip,pins = <0x00 0x06 0x01 0xb1>; + phandle = <0x87>; + }; + }; + + uart0 { + + uart0-xfer { + rockchip,pins = <0x00 0x0a 0x01 0xb2 0x00 0x0b 0x01 0xb2>; + phandle = <0x2c>; + }; + + uart0-cts { + rockchip,pins = <0x00 0x0c 0x01 0xb1>; + phandle = <0x2d>; + }; + + uart0-rts { + rockchip,pins = <0x00 0x0d 0x01 0xb1>; + phandle = <0x2e>; + }; + + uart0-rts-gpio { + rockchip,pins = <0x00 0x0d 0x00 0xb1>; + phandle = <0x11f>; + }; + }; + + uart1 { + + uart1-xfer { + rockchip,pins = <0x01 0x11 0x01 0xb2 0x01 0x10 0x01 0xb2>; + phandle = <0x4f>; + }; + + uart1-cts { + rockchip,pins = <0x01 0x12 0x01 0xb1>; + phandle = <0x50>; + }; + + uart1-rts { + rockchip,pins = <0x01 0x13 0x01 0xb1>; + phandle = <0x120>; + }; + + uart1-rts-gpio { + rockchip,pins = <0x01 0x13 0x00 0xb1>; + phandle = <0x121>; + }; + }; + + uart2-m0 { + + uart2m0-xfer { + rockchip,pins = <0x01 0x1a 0x02 0xb2 0x01 0x1b 0x02 0xb2>; + phandle = <0x51>; + }; + }; + + uart2-m1 { + + uart2m1-xfer { + rockchip,pins = <0x02 0x0c 0x02 0xb2 0x02 0x0e 0x02 0xb2>; + phandle = <0xba>; + }; + }; + + uart3-m0 { + + uart3m0-xfer { + rockchip,pins = <0x00 0x10 0x02 0xb2 0x00 0x11 0x02 0xb2>; + phandle = <0x122>; + }; + + uart3m0-cts { + rockchip,pins = <0x00 0x12 0x02 0xb1>; + phandle = <0x123>; + }; + + uart3m0-rts { + rockchip,pins = <0x00 0x13 0x02 0xb1>; + phandle = <0x124>; + }; + + uart3m0-rts-gpio { + rockchip,pins = <0x00 0x13 0x00 0xb1>; + phandle = <0x125>; + }; + }; + + uart3-m1 { + + uart3m1-xfer { + rockchip,pins = <0x01 0x0e 0x02 0xb2 0x01 0x0f 0x02 0xb2>; + phandle = <0x52>; + }; + + uart3m1-cts { + rockchip,pins = <0x01 0x0c 0x02 0xb1>; + phandle = <0x53>; + }; + + uart3m1-rts { + rockchip,pins = <0x01 0x0d 0x02 0xb1>; + phandle = <0x54>; + }; + + uart3m1-rts-gpio { + rockchip,pins = <0x01 0x0d 0x00 0xb1>; + phandle = <0x126>; + }; + }; + + uart4 { + + uart4-xfer { + rockchip,pins = <0x01 0x1c 0x02 0xb2 0x01 0x1d 0x02 0xb2>; + phandle = <0x55>; + }; + + uart4-cts { + rockchip,pins = <0x01 0x1e 0x02 0xb1>; + phandle = <0x56>; + }; + + uart4-rts { + rockchip,pins = <0x01 0x1f 0x02 0xb1>; + phandle = <0x57>; + }; + }; + + uart5 { + + uart5-xfer { + rockchip,pins = <0x03 0x02 0x04 0xb2 0x03 0x01 0x04 0xb2>; + phandle = <0x58>; + }; + + uart5-cts { + rockchip,pins = <0x03 0x03 0x04 0xb1>; + phandle = <0x59>; + }; + + uart5-rts { + rockchip,pins = <0x03 0x05 0x04 0xb1>; + phandle = <0x5a>; + }; + }; + + spi0 { + + spi0-clk { + rockchip,pins = <0x01 0x0f 0x03 0xb3>; + phandle = <0x6c>; + }; + + spi0-csn { + rockchip,pins = <0x01 0x0e 0x03 0xb3>; + phandle = <0x6d>; + }; + + spi0-miso { + rockchip,pins = <0x01 0x0d 0x03 0xb3>; + phandle = <0x6e>; + }; + + spi0-mosi { + rockchip,pins = <0x01 0x0c 0x03 0xb3>; + phandle = <0x6f>; + }; + + spi0-clk-hs { + rockchip,pins = <0x01 0x0f 0x03 0xb4>; + phandle = <0x70>; + }; + + spi0-miso-hs { + rockchip,pins = <0x01 0x0d 0x03 0xb4>; + phandle = <0x71>; + }; + + spi0-mosi-hs { + rockchip,pins = <0x01 0x0c 0x03 0xb4>; + phandle = <0x72>; + }; + }; + + spi1 { + + spi1-clk { + rockchip,pins = <0x03 0x0f 0x04 0xb3>; + phandle = <0x73>; + }; + + spi1-csn0 { + rockchip,pins = <0x03 0x09 0x04 0xb3>; + phandle = <0x74>; + }; + + spi1-csn1 { + rockchip,pins = <0x03 0x0a 0x02 0xb3>; + phandle = <0x75>; + }; + + spi1-miso { + rockchip,pins = <0x03 0x0e 0x04 0xb3>; + phandle = <0x76>; + }; + + spi1-mosi { + rockchip,pins = <0x03 0x0c 0x04 0xb3>; + phandle = <0x77>; + }; + + spi1-clk-hs { + rockchip,pins = <0x03 0x0f 0x04 0xb4>; + phandle = <0x78>; + }; + + spi1-miso-hs { + rockchip,pins = <0x03 0x0e 0x04 0xb4>; + phandle = <0x79>; + }; + + spi1-mosi-hs { + rockchip,pins = <0x03 0x0c 0x04 0xb4>; + phandle = <0x7a>; + }; + }; + + pdm { + + pdm-clk0m0 { + rockchip,pins = <0x03 0x16 0x02 0xb1>; + phandle = <0x44>; + }; + + pdm-clk0m1 { + rockchip,pins = <0x02 0x16 0x01 0xb1>; + phandle = <0x127>; + }; + + pdm-clk1 { + rockchip,pins = <0x03 0x17 0x02 0xb1>; + phandle = <0x45>; + }; + + pdm-sdi0m0 { + rockchip,pins = <0x03 0x1b 0x02 0xb1>; + phandle = <0x46>; + }; + + pdm-sdi0m1 { + rockchip,pins = <0x02 0x15 0x02 0xb1>; + phandle = <0x128>; + }; + + pdm-sdi1 { + rockchip,pins = <0x03 0x18 0x02 0xb1>; + phandle = <0x47>; + }; + + pdm-sdi2 { + rockchip,pins = <0x03 0x19 0x02 0xb1>; + phandle = <0x48>; + }; + + pdm-sdi3 { + rockchip,pins = <0x03 0x1a 0x02 0xb1>; + phandle = <0x49>; + }; + + pdm-clk0m0-sleep { + rockchip,pins = <0x03 0x16 0x00 0xb5>; + phandle = <0x129>; + }; + + pdm-clk0m1-sleep { + rockchip,pins = <0x02 0x16 0x00 0xb5>; + phandle = <0x12a>; + }; + + pdm-clk1-sleep { + rockchip,pins = <0x03 0x17 0x00 0xb5>; + phandle = <0x12b>; + }; + + pdm-sdi0m0-sleep { + rockchip,pins = <0x03 0x1b 0x00 0xb5>; + phandle = <0x12c>; + }; + + pdm-sdi0m1-sleep { + rockchip,pins = <0x02 0x15 0x00 0xb5>; + phandle = <0x12d>; + }; + + pdm-sdi1-sleep { + rockchip,pins = <0x03 0x18 0x00 0xb5>; + phandle = <0x12e>; + }; + + pdm-sdi2-sleep { + rockchip,pins = <0x03 0x19 0x00 0xb5>; + phandle = <0x12f>; + }; + + pdm-sdi3-sleep { + rockchip,pins = <0x03 0x1a 0x00 0xb5>; + phandle = <0x130>; + }; + }; + + i2s0 { + + i2s0-8ch-mclk { + rockchip,pins = <0x03 0x11 0x02 0xb1>; + phandle = <0x131>; + }; + + i2s0-8ch-sclktx { + rockchip,pins = <0x03 0x13 0x02 0xb1>; + phandle = <0x30>; + }; + + i2s0-8ch-sclkrx { + rockchip,pins = <0x03 0x0c 0x02 0xb1>; + phandle = <0x31>; + }; + + i2s0-8ch-lrcktx { + rockchip,pins = <0x03 0x12 0x02 0xb1>; + phandle = <0x32>; + }; + + i2s0-8ch-lrckrx { + rockchip,pins = <0x03 0x0d 0x02 0xb1>; + phandle = <0x33>; + }; + + i2s0-8ch-sdo0 { + rockchip,pins = <0x03 0x14 0x02 0xb1>; + phandle = <0x38>; + }; + + i2s0-8ch-sdo1 { + rockchip,pins = <0x03 0x10 0x02 0xb1>; + phandle = <0x39>; + }; + + i2s0-8ch-sdo2 { + rockchip,pins = <0x03 0x0f 0x02 0xb1>; + phandle = <0x3a>; + }; + + i2s0-8ch-sdo3 { + rockchip,pins = <0x03 0x0e 0x02 0xb1>; + phandle = <0x3b>; + }; + + i2s0-8ch-sdi0 { + rockchip,pins = <0x03 0x15 0x02 0xb1>; + phandle = <0x34>; + }; + + i2s0-8ch-sdi1 { + rockchip,pins = <0x03 0x0b 0x02 0xb1>; + phandle = <0x35>; + }; + + i2s0-8ch-sdi2 { + rockchip,pins = <0x03 0x09 0x02 0xb1>; + phandle = <0x36>; + }; + + i2s0-8ch-sdi3 { + rockchip,pins = <0x03 0x08 0x02 0xb1>; + phandle = <0x37>; + }; + }; + + i2s1 { + + i2s1-2ch-mclk { + rockchip,pins = <0x02 0x13 0x01 0xb1>; + phandle = <0x68>; + }; + + i2s1-2ch-sclk { + rockchip,pins = <0x02 0x12 0x01 0xb1>; + phandle = <0x3c>; + }; + + i2s1-2ch-lrck { + rockchip,pins = <0x02 0x11 0x01 0xb1>; + phandle = <0x3d>; + }; + + i2s1-2ch-sdi { + rockchip,pins = <0x02 0x15 0x01 0xb1>; + phandle = <0x3e>; + }; + + i2s1-2ch-sdo { + rockchip,pins = <0x02 0x14 0x01 0xb1>; + phandle = <0x3f>; + }; + }; + + i2s2 { + + i2s2-2ch-mclk { + rockchip,pins = <0x03 0x01 0x02 0xb1>; + phandle = <0x132>; + }; + + i2s2-2ch-sclk { + rockchip,pins = <0x03 0x02 0x02 0xb1>; + phandle = <0x40>; + }; + + i2s2-2ch-lrck { + rockchip,pins = <0x03 0x03 0x02 0xb1>; + phandle = <0x41>; + }; + + i2s2-2ch-sdi { + rockchip,pins = <0x03 0x05 0x02 0xb1>; + phandle = <0x42>; + }; + + i2s2-2ch-sdo { + rockchip,pins = <0x03 0x07 0x02 0xb1>; + phandle = <0x43>; + }; + }; + + sdmmc { + + sdmmc-clk { + rockchip,pins = <0x01 0x1e 0x01 0xb6>; + phandle = <0x8f>; + }; + + sdmmc-cmd { + rockchip,pins = <0x01 0x1f 0x01 0xb4>; + phandle = <0x90>; + }; + + sdmmc-det { + rockchip,pins = <0x00 0x03 0x01 0xb4>; + phandle = <0x91>; + }; + + sdmmc-bus1 { + rockchip,pins = <0x01 0x1a 0x01 0xb4>; + phandle = <0x133>; + }; + + sdmmc-bus4 { + rockchip,pins = <0x01 0x1a 0x01 0xb4 0x01 0x1b 0x01 0xb4 0x01 0x1c 0x01 0xb4 0x01 0x1d 0x01 0xb4>; + phandle = <0x92>; + }; + + sdmmc-gpio { + rockchip,pins = <0x01 0x1a 0x00 0xb3 0x01 0x1b 0x00 0xb3 0x01 0x1c 0x00 0xb3 0x01 0x1d 0x00 0xb3 0x01 0x1e 0x00 0xb3 0x01 0x1f 0x00 0xb3>; + phandle = <0x134>; + }; + }; + + sdio { + + sdio-clk { + rockchip,pins = <0x01 0x15 0x01 0xb1>; + phandle = <0x96>; + }; + + sdio-cmd { + rockchip,pins = <0x01 0x14 0x01 0xb2>; + phandle = <0x95>; + }; + + sdio-bus4 { + rockchip,pins = <0x01 0x16 0x01 0xb2 0x01 0x17 0x01 0xb2 0x01 0x18 0x01 0xb2 0x01 0x19 0x01 0xb2>; + phandle = <0x94>; + }; + + sdio-gpio { + rockchip,pins = <0x01 0x16 0x00 0xb2 0x01 0x17 0x00 0xb2 0x01 0x18 0x00 0xb2 0x01 0x19 0x00 0xb2 0x01 0x14 0x00 0xb2 0x01 0x15 0x00 0xb2>; + phandle = <0x135>; + }; + }; + + emmc { + + emmc-clk { + rockchip,pins = <0x01 0x09 0x02 0xb6>; + phandle = <0x136>; + }; + + emmc-cmd { + rockchip,pins = <0x01 0x0a 0x02 0xb4>; + phandle = <0x137>; + }; + + emmc-pwren { + rockchip,pins = <0x01 0x08 0x02 0xb1>; + phandle = <0x138>; + }; + + emmc-rstnout { + rockchip,pins = <0x01 0x0b 0x02 0xb1>; + phandle = <0x139>; + }; + + emmc-bus1 { + rockchip,pins = <0x01 0x00 0x02 0xb4>; + phandle = <0x13a>; + }; + + emmc-bus4 { + rockchip,pins = <0x01 0x00 0x02 0xb4 0x01 0x01 0x02 0xb4 0x01 0x02 0x02 0xb4 0x01 0x03 0x02 0xb4>; + phandle = <0x13b>; + }; + + emmc-bus8 { + rockchip,pins = <0x01 0x00 0x02 0xb4 0x01 0x01 0x02 0xb4 0x01 0x02 0x02 0xb4 0x01 0x03 0x02 0xb4 0x01 0x04 0x02 0xb4 0x01 0x05 0x02 0xb4 0x01 0x06 0x02 0xb4 0x01 0x07 0x02 0xb4>; + phandle = <0x13c>; + }; + }; + + flash { + + flash-cs0 { + rockchip,pins = <0x01 0x08 0x01 0xb1>; + phandle = <0x13d>; + }; + + flash-rdy { + rockchip,pins = <0x01 0x09 0x01 0xb1>; + phandle = <0x13e>; + }; + + flash-dqs { + rockchip,pins = <0x01 0x0a 0x01 0xb1>; + phandle = <0x13f>; + }; + + flash-ale { + rockchip,pins = <0x01 0x0b 0x01 0xb1>; + phandle = <0x140>; + }; + + flash-cle { + rockchip,pins = <0x01 0x0c 0x01 0xb1>; + phandle = <0x141>; + }; + + flash-wrn { + rockchip,pins = <0x01 0x0d 0x01 0xb1>; + phandle = <0x142>; + }; + + flash-csl { + rockchip,pins = <0x01 0x0e 0x01 0xb1>; + phandle = <0x143>; + }; + + flash-rdn { + rockchip,pins = <0x01 0x0f 0x01 0xb1>; + phandle = <0x144>; + }; + + flash-bus8 { + rockchip,pins = <0x01 0x00 0x01 0xb7 0x01 0x01 0x01 0xb7 0x01 0x02 0x01 0xb7 0x01 0x03 0x01 0xb7 0x01 0x04 0x01 0xb7 0x01 0x05 0x01 0xb7 0x01 0x06 0x01 0xb7 0x01 0x07 0x01 0xb7>; + phandle = <0x145>; + }; + }; + + lcdc { + + lcdc-m0-rgb-pins { + rockchip,pins = <0x03 0x00 0x01 0xb6 0x03 0x01 0x01 0xb6 0x03 0x02 0x01 0xb6 0x03 0x03 0x01 0xb6 0x03 0x04 0x01 0xb6 0x03 0x05 0x01 0xb6 0x03 0x06 0x01 0xb6 0x03 0x07 0x01 0xb6 0x03 0x08 0x01 0xb6 0x03 0x09 0x01 0xb6 0x03 0x0a 0x01 0xb6 0x03 0x0b 0x01 0xb6 0x03 0x0c 0x01 0xb6 0x03 0x0d 0x01 0xb6 0x03 0x0e 0x01 0xb6 0x03 0x0f 0x01 0xb6 0x03 0x10 0x01 0xb6 0x03 0x11 0x01 0xb6 0x03 0x12 0x01 0xb6 0x03 0x13 0x01 0xb6 0x03 0x14 0x01 0xb6 0x03 0x15 0x01 0xb6 0x03 0x16 0x01 0xb6 0x03 0x17 0x01 0xb6 0x03 0x18 0x01 0xb6 0x03 0x19 0x01 0xb6 0x03 0x1a 0x01 0xb6 0x03 0x1b 0x01 0xb6>; + phandle = <0x146>; + }; + + lcdc-m0-sleep-pins { + rockchip,pins = <0x03 0x00 0x00 0xb1 0x03 0x01 0x00 0xb1 0x03 0x02 0x00 0xb1 0x03 0x03 0x00 0xb1 0x03 0x04 0x00 0xb1 0x03 0x05 0x00 0xb1 0x03 0x06 0x00 0xb1 0x03 0x07 0x00 0xb1 0x03 0x08 0x00 0xb1 0x03 0x09 0x00 0xb1 0x03 0x0a 0x00 0xb1 0x03 0x0b 0x00 0xb1 0x03 0x0c 0x00 0xb1 0x03 0x0d 0x00 0xb1 0x03 0x0e 0x00 0xb1 0x03 0x0f 0x00 0xb1 0x03 0x10 0x00 0xb1 0x03 0x11 0x00 0xb1 0x03 0x12 0x00 0xb1 0x03 0x13 0x00 0xb1 0x03 0x14 0x00 0xb1 0x03 0x15 0x00 0xb1 0x03 0x16 0x00 0xb1 0x03 0x17 0x00 0xb1 0x03 0x18 0x00 0xb1 0x03 0x19 0x00 0xb1 0x03 0x1a 0x00 0xb1 0x03 0x1b 0x00 0xb1>; + phandle = <0x147>; + }; + + lcdc-m1-rgb-pins { + rockchip,pins = <0x03 0x00 0x01 0xb6 0x03 0x04 0x01 0xb6 0x03 0x06 0x01 0xb6 0x03 0x0a 0x01 0xb6 0x03 0x0b 0x01 0xb6 0x03 0x0d 0x01 0xb6 0x03 0x10 0x01 0xb6 0x03 0x11 0x01 0xb6 0x03 0x12 0x01 0xb6 0x03 0x13 0x01 0xb6 0x03 0x14 0x01 0xb6 0x03 0x15 0x01 0xb6 0x03 0x16 0x01 0xb6 0x03 0x17 0x01 0xb6 0x03 0x18 0x01 0xb6 0x03 0x19 0x01 0xb6 0x03 0x1a 0x01 0xb6 0x03 0x1b 0x01 0xb6>; + phandle = <0x4d>; + }; + + lcdc-m1-sleep-pins { + rockchip,pins = <0x03 0x00 0x00 0xb1 0x03 0x04 0x00 0xb1 0x03 0x06 0x00 0xb1 0x03 0x0a 0x00 0xb1 0x03 0x0b 0x00 0xb1 0x03 0x0d 0x00 0xb1 0x03 0x10 0x00 0xb1 0x03 0x11 0x00 0xb1 0x03 0x12 0x00 0xb1 0x03 0x13 0x00 0xb1 0x03 0x14 0x00 0xb1 0x03 0x15 0x00 0xb1 0x03 0x16 0x00 0xb1 0x03 0x17 0x00 0xb1 0x03 0x18 0x00 0xb1 0x03 0x19 0x00 0xb1 0x03 0x1a 0x00 0xb1 0x03 0x1b 0x00 0xb1>; + phandle = <0x4e>; + }; + }; + + pwm0 { + + pwm0-pin { + rockchip,pins = <0x00 0x0f 0x01 0xb1>; + phandle = <0x7b>; + }; + }; + + pwm1 { + + pwm1-pin { + rockchip,pins = <0x00 0x10 0x01 0xb1>; + phandle = <0x7c>; + }; + }; + + pwm2 { + + pwm2-pin { + rockchip,pins = <0x02 0x0d 0x01 0xb1>; + phandle = <0x7d>; + }; + }; + + pwm3 { + + pwm3-pin { + rockchip,pins = <0x00 0x11 0x01 0xb1>; + phandle = <0x7e>; + }; + }; + + pwm4 { + + pwm4-pin { + rockchip,pins = <0x03 0x12 0x03 0xb1>; + phandle = <0x7f>; + }; + }; + + pwm5 { + + pwm5-pin { + rockchip,pins = <0x03 0x13 0x03 0xb1>; + phandle = <0x80>; + }; + }; + + pwm6 { + + pwm6-pin { + rockchip,pins = <0x03 0x14 0x03 0xb1>; + phandle = <0x81>; + }; + }; + + pwm7 { + + pwm7-pin { + rockchip,pins = <0x03 0x15 0x03 0xb1>; + phandle = <0x82>; + }; + }; + + gmac { + + rmii-pins { + rockchip,pins = <0x02 0x00 0x02 0xb8 0x02 0x01 0x02 0xb8 0x02 0x02 0x02 0xb8 0x02 0x03 0x02 0xb1 0x02 0x04 0x02 0xb1 0x02 0x05 0x02 0xb1 0x02 0x06 0x02 0xb1 0x02 0x07 0x02 0xb1 0x02 0x09 0x02 0xb1>; + phandle = <0x8d>; + }; + + mac-refclk-12ma { + rockchip,pins = <0x02 0x0a 0x02 0xb8>; + phandle = <0x8e>; + }; + + mac-refclk { + rockchip,pins = <0x02 0x0a 0x02 0xb1>; + phandle = <0x148>; + }; + }; + + cif-m0 { + + cif-clkout-m0 { + rockchip,pins = <0x02 0x0b 0x01 0xb8>; + phandle = <0xa7>; + }; + + dvp-d2d9-m0 { + rockchip,pins = <0x02 0x00 0x01 0xb1 0x02 0x01 0x01 0xb1 0x02 0x02 0x01 0xb1 0x02 0x03 0x01 0xb1 0x02 0x04 0x01 0xb1 0x02 0x05 0x01 0xb1 0x02 0x06 0x01 0xb1 0x02 0x07 0x01 0xb1 0x02 0x08 0x01 0xb1 0x02 0x09 0x01 0xb1 0x02 0x0a 0x01 0xb1 0x02 0x0b 0x01 0xb1>; + phandle = <0xa5>; + }; + + dvp-d0d1-m0 { + rockchip,pins = <0x02 0x0c 0x01 0xb1 0x02 0x0e 0x01 0xb1>; + phandle = <0xa9>; + }; + + d10-d11-m0 { + rockchip,pins = <0x02 0x0f 0x01 0xb1 0x02 0x10 0x01 0xb1>; + phandle = <0xa8>; + }; + }; + + cif-m1 { + + cif-clkout-m1 { + rockchip,pins = <0x03 0x18 0x03 0xb1>; + phandle = <0x149>; + }; + + dvp-d2d9-m1 { + rockchip,pins = <0x03 0x03 0x03 0xb1 0x03 0x05 0x03 0xb1 0x03 0x07 0x03 0xb1 0x03 0x08 0x03 0xb1 0x03 0x09 0x03 0xb1 0x03 0x0c 0x03 0xb1 0x03 0x0e 0x03 0xb1 0x03 0x0f 0x03 0xb1 0x03 0x19 0x03 0xb1 0x03 0x1a 0x03 0xb1 0x03 0x1b 0x03 0xb1 0x03 0x18 0x03 0xb1>; + phandle = <0x14a>; + }; + + dvp-d0d1-m1 { + rockchip,pins = <0x03 0x01 0x03 0xb1 0x03 0x02 0x03 0xb1>; + phandle = <0x14b>; + }; + + d10-d11-m1 { + rockchip,pins = <0x03 0x16 0x03 0xb1 0x03 0x17 0x03 0xb1>; + phandle = <0x14c>; + }; + }; + + isp { + + isp-prelight { + rockchip,pins = <0x03 0x19 0x04 0xb1>; + phandle = <0x14d>; + }; + }; + + pmic { + + pmic_int { + rockchip,pins = <0x00 0x0a 0x00 0xb2 0x00 0x0b 0x00 0xb1>; + phandle = <0x5d>; + }; + + soc_slppin_gpio { + rockchip,pins = <0x00 0x04 0x00 0xb9>; + phandle = <0x60>; + }; + + soc_slppin_slp { + rockchip,pins = <0x00 0x04 0x01 0xb1>; + phandle = <0x5e>; + }; + + soc_slppin_rst { + rockchip,pins = <0x00 0x04 0x02 0xb1>; + phandle = <0x62>; + }; + }; + + leds { + + led-pins { + rockchip,pins = <0x00 0x11 0x00 0xb1>; + phandle = <0xc0>; + }; + }; + + btns { + + btn-pins { + rockchip,pins = <0x01 0x0c 0x00 0xb2 0x01 0x0d 0x00 0xb2 0x01 0x0e 0x00 0xb2 0x01 0x0f 0x00 0xb2 0x01 0x02 0x00 0xb2 0x01 0x05 0x00 0xb2 0x01 0x06 0x00 0xb2 0x01 0x07 0x00 0xb2 0x02 0x00 0x00 0xb2 0x02 0x01 0x00 0xb2 0x02 0x02 0x00 0xb2 0x02 0x03 0x00 0xb2 0x02 0x04 0x00 0xb2 0x02 0x05 0x00 0xb2 0x02 0x06 0x00 0xb2 0x02 0x07 0x00 0xb2 0x03 0x09 0x00 0xb2 0x03 0x0a 0x00 0xb2 0x03 0x0c 0x00 0xb2 0x03 0x0f 0x00 0xb2>; + phandle = <0xbd>; + }; + }; + }; + + chosen { + bootargs = [00]; + }; + + fiq-debugger { + compatible = "rockchip,fiq-debugger"; + rockchip,serial-id = <0x02>; + rockchip,wake-irq = <0x00>; + rockchip,irq-mode-enable = <0x00>; + rockchip,baudrate = <0x1c200>; + interrupts = <0x00 0x7f 0x08>; + pinctrl-names = "default"; + pinctrl-0 = <0xba>; + status = "okay"; + }; + + ramoops { + compatible = "ramoops"; + record-size = <0x00 0x20000>; + console-size = <0x00 0x80000>; + ftrace-size = <0x00 0x00>; + pmsg-size = <0x00 0x00>; + memory-region = <0xbb>; + }; + + reserved-memory { + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + + drm-logo@00000000 { + compatible = "rockchip,drm-logo"; + reg = <0x00 0x00 0x00 0x00>; + phandle = <0x11>; + }; + + region@110000 { + reg = <0x00 0x110000 0x00 0xf0000>; + reg-names = "ramoops_mem"; + phandle = <0xbb>; + }; + }; + + odroidgo3-keys { + compatible = "gpio-keys"; + #address-cells = <0x01>; + #size-cells = <0x00>; + autorepeat; + phandle = <0x14e>; + + button@0 { + label = "GPIO BTN-VOLUP"; + linux,code = <0x73>; + gpios = <0x66 0x00 0x01>; + }; + + button@1 { + label = "GPIO BTN-VOLDN"; + linux,code = <0x72>; + gpios = <0x66 0x01 0x01>; + }; + }; + + odroidgo3-joypad { + compatible = "odroidgo3-joypad"; + pwms = <0xbc 0x00 0xbebc200 0x00>; + pwm-names = "enable"; + rumble-boost-weak = <0x00>; + rumble-boost-strong = <0x00>; + joypad-name = "GO-Super Gamepad"; + joypad-product = <0x1100>; + joypad-revision = <0x100>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <0xbd>; + pinctrl-1 = <0x7b>; + io-channel-names = "amux_adc"; + io-channels = <0xbe 0x01>; + amux-count = <0x04>; + amux-a-gpios = <0x97 0x0b 0x01>; + amux-b-gpios = <0x97 0x08 0x01>; + amux-en-gpios = <0x97 0x0d 0x01>; + button-adc-scale = <0x02>; + button-adc-deadzone = <0x40>; + button-adc-fuzz = <0x20>; + button-adc-flat = <0x20>; + abs_x-p-tuning = <0xc8>; + abs_x-n-tuning = <0xc8>; + abs_y-p-tuning = <0xc8>; + abs_y-n-tuning = <0xc8>; + abs_rx-p-tuning = <0xc8>; + abs_rx-n-tuning = <0xc8>; + abs_ry-p-tuning = <0xc8>; + abs_ry-n-tuning = <0xc8>; + poll-interval = <0x0a>; + invert-absx; + invert-absy; + phandle = <0x14f>; + + sw1 { + gpios = <0xbf 0x0c 0x01>; + label = "GPIO DPAD-UP"; + linux,code = <0x220>; + }; + + sw2 { + gpios = <0xbf 0x0d 0x01>; + label = "GPIO DPAD-DOWN"; + linux,code = <0x221>; + }; + + sw3 { + gpios = <0xbf 0x0e 0x01>; + label = "GPIO DPAD-LEFT"; + linux,code = <0x222>; + }; + + sw4 { + gpios = <0xbf 0x0f 0x01>; + label = "GPIO DPAD-RIGHT"; + linux,code = <0x223>; + }; + + sw5 { + gpios = <0xbf 0x02 0x01>; + label = "GPIO KEY BTN-A"; + linux,code = <0x131>; + }; + + sw6 { + gpios = <0xbf 0x05 0x01>; + label = "GPIO BTN-B"; + linux,code = <0x130>; + }; + + sw7 { + gpios = <0xbf 0x06 0x01>; + label = "GPIO BTN-Y"; + linux,code = <0x134>; + }; + + sw8 { + gpios = <0xbf 0x07 0x01>; + label = "GPIO BTN-X"; + linux,code = <0x133>; + }; + + sw11 { + gpios = <0x66 0x02 0x01>; + label = "GPIO F3"; + linux,code = <0x2c2>; + }; + + sw12 { + gpios = <0x66 0x03 0x01>; + label = "GPIO F4"; + linux,code = <0x2c3>; + }; + + sw15 { + gpios = <0x66 0x06 0x01>; + label = "GPIO TOP-LEFT"; + linux,code = <0x136>; + }; + + sw16 { + gpios = <0x66 0x07 0x01>; + label = "GPIO TOP-RIGHT"; + linux,code = <0x137>; + }; + + sw19 { + gpios = <0x97 0x09 0x01>; + label = "GPIO F1"; + linux,code = <0x2c0>; + }; + + sw20 { + gpios = <0x97 0x0f 0x01>; + label = "GPIO TOP-RIGHT2"; + linux,code = <0x139>; + }; + + sw21 { + gpios = <0x97 0x0a 0x01>; + label = "GPIO TOP-LEFT2"; + linux,code = <0x138>; + }; + + sw22 { + gpios = <0x97 0x0c 0x01>; + label = "GPIO F2"; + linux,code = <0x2c1>; + }; + + sw13 { + gpios = <0x66 0x04 0x01>; + label = "GPIO F5"; + linux,code = <0x2c4>; + }; + }; + + gpio_leds { + compatible = "gpio-leds"; + pinctrl-names = "led_pins"; + pinctrl-0 = <0xc0>; + phandle = <0x150>; + + heartbeat { + label = "blue:heartbeat"; + gpios = <0x5c 0x11 0x00>; + linux,default-trigger = "heartbeat"; + }; + }; + + backlight { + compatible = "pwm-backlight"; + pwms = <0xc1 0x00 0xf519 0x00>; + brightness-levels = <0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2a 0x2b 0x2c 0x2d 0x2e 0x2f 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x3a 0x3b 0x3c 0x3d 0x3e 0x3f 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48 0x49 0x4a 0x4b 0x4c 0x4d 0x4e 0x4f 0x50 0x51 0x52 0x53 0x54 0x55 0x56 0x57 0x58 0x59 0x5a 0x5b 0x5c 0x5d 0x5e 0x5f 0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69 0x6a 0x6b 0x6c 0x6d 0x6e 0x6f 0x70 0x71 0x72 0x73 0x74 0x75 0x76 0x77 0x78 0x79 0x7a 0x7b 0x7c 0x7d 0x7e 0x7f 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90 0x91 0x92 0x93 0x94 0x95 0x96 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f 0xa0>; + default-brightness-level = <0x33>; + phandle = <0x9d>; + }; + + rk817-sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,name = "rockchip,rk817-codec"; + simple-audio-card,mclk-fs = <0x100>; + simple-audio-card,widgets = "Microphone\0Mic Jack\0Headphone\0Headphone Jack"; + simple-audio-card,routing = "MIC_IN\0Mic Jack\0Headphone Jack\0HPOL\0Headphone Jack\0HPOR"; + simple-audio-card,hp-det-gpio = <0x66 0x16 0x01>; + simple-audio-card,codec-hp-det = <0x01>; + + simple-audio-card,cpu { + sound-dai = <0xc2>; + }; + + simple-audio-card,codec { + sound-dai = <0xc3>; + }; + }; + + vccsys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v8_sys"; + regulator-always-on; + regulator-min-microvolt = <0x39fbc0>; + regulator-max-microvolt = <0x39fbc0>; + phandle = <0x64>; + }; + + __symbols__ { + ddr_timing = "/ddr_timing"; + cpu0 = "/cpus/cpu@0"; + cpu1 = "/cpus/cpu@1"; + cpu2 = "/cpus/cpu@2"; + cpu3 = "/cpus/cpu@3"; + CPU_SLEEP = "/cpus/idle-states/cpu-sleep"; + CLUSTER_SLEEP = "/cpus/idle-states/cluster-sleep"; + cpu0_opp_table = "/cpu0-opp-table"; + bus_soc = "/bus-soc"; + bus_apll = "/bus-apll"; + bus_apll_opp_table = "/bus-apll-opp-table"; + display_subsystem = "/display-subsystem"; + route_lvds = "/display-subsystem/route/route-lvds"; + route_dsi = "/display-subsystem/route/route-dsi"; + route_rgb = "/display-subsystem/route/route-rgb"; + gmac_clkin = "/external-gmac-clock"; + rockchip_suspend = "/rockchip-suspend"; + xin24m = "/xin24m"; + xin32k = "/xin32k"; + pmu = "/power-management@ff000000"; + power = "/power-management@ff000000/power-controller"; + pmugrf = "/syscon@ff010000"; + pmu_io_domains = "/syscon@ff010000/io-domains"; + pmu_pvtm = "/syscon@ff010000/pmu-pvtm"; + uart0 = "/serial@ff030000"; + i2s0_8ch = "/i2s@ff060000"; + i2s1_2ch = "/i2s@ff070000"; + i2s2_2ch = "/i2s@ff080000"; + pdm = "/pdm@ff0a0000"; + crypto = "/crypto@ff0b0000"; + rng = "/rng@ff0b0000"; + gic = "/interrupt-controller@ff131000"; + grf = "/syscon@ff140000"; + io_domains = "/syscon@ff140000/io-domains"; + lvds = "/syscon@ff140000/lvds"; + lvds_in_vopb = "/syscon@ff140000/lvds/ports/port@0/endpoint@0"; + rgb = "/syscon@ff140000/rgb"; + rgb_in_vopb = "/syscon@ff140000/rgb/ports/port@0/endpoint@0"; + core_grf = "/syscon@ff148000"; + pvtm = "/syscon@ff148000/pvtm"; + uart1 = "/serial@ff158000"; + uart2 = "/serial@ff160000"; + uart3 = "/serial@ff168000"; + uart4 = "/serial@ff170000"; + uart5 = "/serial@ff178000"; + i2c0 = "/i2c@ff180000"; + rk817 = "/i2c@ff180000/pmic@20"; + pinctrl_rk8xx = "/i2c@ff180000/pmic@20/pinctrl_rk8xx"; + rk817_ts_gpio1 = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_ts_gpio1"; + rk817_gt_gpio2 = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_gt_gpio2"; + rk817_pin_ts = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_pin_ts"; + rk817_pin_gt = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_pin_gt"; + rk817_slppin_null = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_null"; + rk817_slppin_slp = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_slp"; + rk817_slppin_pwrdn = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_pwrdn"; + rk817_slppin_rst = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_rst"; + vdd_logic = "/i2c@ff180000/pmic@20/regulators/DCDC_REG1"; + vdd_arm = "/i2c@ff180000/pmic@20/regulators/DCDC_REG2"; + vcc_ddr = "/i2c@ff180000/pmic@20/regulators/DCDC_REG3"; + vcc_3v3 = "/i2c@ff180000/pmic@20/regulators/DCDC_REG4"; + vcc_1v0 = "/i2c@ff180000/pmic@20/regulators/LDO_REG1"; + vcc1v8_soc = "/i2c@ff180000/pmic@20/regulators/LDO_REG2"; + vdd1v0_soc = "/i2c@ff180000/pmic@20/regulators/LDO_REG3"; + vcc3v3_pmu = "/i2c@ff180000/pmic@20/regulators/LDO_REG4"; + vccio_sd = "/i2c@ff180000/pmic@20/regulators/LDO_REG5"; + vcc_sd = "/i2c@ff180000/pmic@20/regulators/LDO_REG6"; + vcc_backlight = "/i2c@ff180000/pmic@20/regulators/LDO_REG7"; + vcc_lcd = "/i2c@ff180000/pmic@20/regulators/LDO_REG8"; + dcdc_boost = "/i2c@ff180000/pmic@20/regulators/BOOST"; + otg_switch = "/i2c@ff180000/pmic@20/regulators/OTG_SWITCH"; + rk817_codec = "/i2c@ff180000/pmic@20/codec"; + i2c1 = "/i2c@ff190000"; + i2c2 = "/i2c@ff1a0000"; + i2c3 = "/i2c@ff1b0000"; + spi0 = "/spi@ff1d0000"; + spi1 = "/spi@ff1d8000"; + wdt = "/watchdog@ff1e0000"; + pwm0 = "/pwm@ff200000"; + pwm1 = "/pwm@ff200010"; + pwm2 = "/pwm@ff200020"; + pwm3 = "/pwm@ff200030"; + pwm4 = "/pwm@ff208000"; + pwm5 = "/pwm@ff208010"; + pwm6 = "/pwm@ff208020"; + pwm7 = "/pwm@ff208030"; + rktimer = "/rktimer@ff210000"; + dmac = "/amba/dmac@ff240000"; + thermal_zones = "/thermal-zones"; + soc_thermal = "/thermal-zones/soc-thermal"; + threshold = "/thermal-zones/soc-thermal/trips/trip-point-0"; + target = "/thermal-zones/soc-thermal/trips/trip-point-1"; + soc_crit = "/thermal-zones/soc-thermal/trips/soc-crit"; + gpu_thermal = "/thermal-zones/gpu-thermal"; + tsadc = "/tsadc@ff280000"; + saradc = "/saradc@ff288000"; + otp = "/otp@ff290000"; + otp_id = "/otp@ff290000/id@7"; + cpu_leakage = "/otp@ff290000/cpu-leakage@17"; + performance = "/otp@ff290000/performance@1e"; + cru = "/clock-controller@ff2b0000"; + cpu_boost = "/cpu-boost@ff2b8000"; + pmucru = "/pmu-clock-controller@ff2bc000"; + usb2phy_grf = "/syscon@ff2c0000"; + u2phy = "/syscon@ff2c0000/usb2-phy@100"; + u2phy_host = "/syscon@ff2c0000/usb2-phy@100/host-port"; + u2phy_otg = "/syscon@ff2c0000/usb2-phy@100/otg-port"; + video_phy = "/video-phy@ff2e0000"; + mipi_dphy_rx0 = "/mipi-dphy-rx0@ff2f0000"; + usb20_otg = "/usb@ff300000"; + usb_host0_ehci = "/usb@ff340000"; + usb_host0_ohci = "/usb@ff350000"; + gmac = "/ethernet@ff360000"; + sdmmc = "/dwmmc@ff370000"; + sdio = "/dwmmc@ff380000"; + emmc = "/dwmmc@ff390000"; + nandc0 = "/nandc@ff3b0000"; + sfc = "/sfc@ff3a0000"; + gpu = "/gpu@ff400000"; + gpu_opp_table = "/gpu-opp-table"; + hevc = "/hevc_service@ff440000"; + vpu = "/vpu_service@ff442000"; + vpu_combo = "/vpu_combo"; + hevc_mmu = "/iommu@ff440440"; + vpu_mmu = "/iommu@ff442800"; + dsi = "/dsi@ff450000"; + dsi_in_vopb = "/dsi@ff450000/ports/port@0/endpoint@0"; + timing0 = "/dsi@ff450000/panel@0/display-timings/60Hz"; + timing1 = "/dsi@ff450000/panel@0/display-timings/50Hz"; + timing2 = "/dsi@ff450000/panel@0/display-timings/75Hz"; + vopb = "/vop@ff460000"; + vopb_out = "/vop@ff460000/port"; + vopb_out_lvds = "/vop@ff460000/port/endpoint@0"; + vopb_out_dsi = "/vop@ff460000/port/endpoint@1"; + vopb_out_rgb = "/vop@ff460000/port/endpoint@2"; + vopb_mmu = "/iommu@ff460f00"; + rk_rga = "/rk_rga@ff480000"; + cif = "/cif@ff490000"; + cif_new = "/cif-new@ff490000"; + vip_mmu = "/iommu@ff490800"; + rk_isp = "/rk_isp@ff4a0000"; + rkisp1 = "/rkisp1@ff4a0000"; + isp_mmu = "/iommu@ff4a8000"; + qos_gmac = "/qos@ff518000"; + qos_gpu = "/qos@ff520000"; + qos_sdmmc = "/qos@ff52c000"; + qos_emmc = "/qos@ff538000"; + qos_nand = "/qos@ff538080"; + qos_sdio = "/qos@ff538100"; + qos_sfc = "/qos@ff538180"; + qos_usb_host = "/qos@ff540000"; + qos_usb_otg = "/qos@ff540080"; + qos_isp_128 = "/qos@ff548000"; + qos_isp_rd = "/qos@ff548080"; + qos_isp_wr = "/qos@ff548100"; + qos_isp_m1 = "/qos@ff548180"; + qos_vip = "/qos@ff548200"; + qos_rga_rd = "/qos@ff550000"; + qos_rga_wr = "/qos@ff550080"; + qos_vop_m0 = "/qos@ff550100"; + qos_vop_m1 = "/qos@ff550180"; + qos_vpu = "/qos@ff558000"; + qos_vpu_r128 = "/qos@ff558080"; + dfi = "/dfi@ff610000"; + dmc = "/dmc"; + ddr_power_model = "/dmc/ddr_power_model"; + dmc_opp_table = "/dmc-opp-table"; + rockchip_system_monitor = "/rockchip-system-monitor"; + pinctrl = "/pinctrl"; + gpio0 = "/pinctrl/gpio0@ff040000"; + gpio1 = "/pinctrl/gpio1@ff250000"; + gpio2 = "/pinctrl/gpio2@ff260000"; + gpio3 = "/pinctrl/gpio3@ff270000"; + pcfg_pull_up = "/pinctrl/pcfg-pull-up"; + pcfg_pull_down = "/pinctrl/pcfg-pull-down"; + pcfg_pull_none = "/pinctrl/pcfg-pull-none"; + pcfg_pull_none_2ma = "/pinctrl/pcfg-pull-none-2ma"; + pcfg_pull_up_2ma = "/pinctrl/pcfg-pull-up-2ma"; + pcfg_pull_up_4ma = "/pinctrl/pcfg-pull-up-4ma"; + pcfg_pull_none_4ma = "/pinctrl/pcfg-pull-none-4ma"; + pcfg_pull_down_4ma = "/pinctrl/pcfg-pull-down-4ma"; + pcfg_pull_none_8ma = "/pinctrl/pcfg-pull-none-8ma"; + pcfg_pull_up_8ma = "/pinctrl/pcfg-pull-up-8ma"; + pcfg_pull_none_12ma = "/pinctrl/pcfg-pull-none-12ma"; + pcfg_pull_up_12ma = "/pinctrl/pcfg-pull-up-12ma"; + pcfg_pull_none_smt = "/pinctrl/pcfg-pull-none-smt"; + pcfg_output_high = "/pinctrl/pcfg-output-high"; + pcfg_output_low = "/pinctrl/pcfg-output-low"; + pcfg_input_high = "/pinctrl/pcfg-input-high"; + pcfg_input = "/pinctrl/pcfg-input"; + i2c0_xfer = "/pinctrl/i2c0/i2c0-xfer"; + i2c1_xfer = "/pinctrl/i2c1/i2c1-xfer"; + i2c2_xfer = "/pinctrl/i2c2/i2c2-xfer"; + i2c3_xfer = "/pinctrl/i2c3/i2c3-xfer"; + tsadc_otp_gpio = "/pinctrl/tsadc/tsadc-otp-gpio"; + tsadc_otp_out = "/pinctrl/tsadc/tsadc-otp-out"; + uart0_xfer = "/pinctrl/uart0/uart0-xfer"; + uart0_cts = "/pinctrl/uart0/uart0-cts"; + uart0_rts = "/pinctrl/uart0/uart0-rts"; + uart0_rts_gpio = "/pinctrl/uart0/uart0-rts-gpio"; + uart1_xfer = "/pinctrl/uart1/uart1-xfer"; + uart1_cts = "/pinctrl/uart1/uart1-cts"; + uart1_rts = "/pinctrl/uart1/uart1-rts"; + uart1_rts_gpio = "/pinctrl/uart1/uart1-rts-gpio"; + uart2m0_xfer = "/pinctrl/uart2-m0/uart2m0-xfer"; + uart2m1_xfer = "/pinctrl/uart2-m1/uart2m1-xfer"; + uart3m0_xfer = "/pinctrl/uart3-m0/uart3m0-xfer"; + uart3m0_cts = "/pinctrl/uart3-m0/uart3m0-cts"; + uart3m0_rts = "/pinctrl/uart3-m0/uart3m0-rts"; + uart3m0_rts_gpio = "/pinctrl/uart3-m0/uart3m0-rts-gpio"; + uart3m1_xfer = "/pinctrl/uart3-m1/uart3m1-xfer"; + uart3m1_cts = "/pinctrl/uart3-m1/uart3m1-cts"; + uart3m1_rts = "/pinctrl/uart3-m1/uart3m1-rts"; + uart3m1_rts_gpio = "/pinctrl/uart3-m1/uart3m1-rts-gpio"; + uart4_xfer = "/pinctrl/uart4/uart4-xfer"; + uart4_cts = "/pinctrl/uart4/uart4-cts"; + uart4_rts = "/pinctrl/uart4/uart4-rts"; + uart5_xfer = "/pinctrl/uart5/uart5-xfer"; + uart5_cts = "/pinctrl/uart5/uart5-cts"; + uart5_rts = "/pinctrl/uart5/uart5-rts"; + spi0_clk = "/pinctrl/spi0/spi0-clk"; + spi0_csn = "/pinctrl/spi0/spi0-csn"; + spi0_miso = "/pinctrl/spi0/spi0-miso"; + spi0_mosi = "/pinctrl/spi0/spi0-mosi"; + spi0_clk_hs = "/pinctrl/spi0/spi0-clk-hs"; + spi0_miso_hs = "/pinctrl/spi0/spi0-miso-hs"; + spi0_mosi_hs = "/pinctrl/spi0/spi0-mosi-hs"; + spi1_clk = "/pinctrl/spi1/spi1-clk"; + spi1_csn0 = "/pinctrl/spi1/spi1-csn0"; + spi1_csn1 = "/pinctrl/spi1/spi1-csn1"; + spi1_miso = "/pinctrl/spi1/spi1-miso"; + spi1_mosi = "/pinctrl/spi1/spi1-mosi"; + spi1_clk_hs = "/pinctrl/spi1/spi1-clk-hs"; + spi1_miso_hs = "/pinctrl/spi1/spi1-miso-hs"; + spi1_mosi_hs = "/pinctrl/spi1/spi1-mosi-hs"; + pdm_clk0m0 = "/pinctrl/pdm/pdm-clk0m0"; + pdm_clk0m1 = "/pinctrl/pdm/pdm-clk0m1"; + pdm_clk1 = "/pinctrl/pdm/pdm-clk1"; + pdm_sdi0m0 = "/pinctrl/pdm/pdm-sdi0m0"; + pdm_sdi0m1 = "/pinctrl/pdm/pdm-sdi0m1"; + pdm_sdi1 = "/pinctrl/pdm/pdm-sdi1"; + pdm_sdi2 = "/pinctrl/pdm/pdm-sdi2"; + pdm_sdi3 = "/pinctrl/pdm/pdm-sdi3"; + pdm_clk0m0_sleep = "/pinctrl/pdm/pdm-clk0m0-sleep"; + pdm_clk0m_sleep1 = "/pinctrl/pdm/pdm-clk0m1-sleep"; + pdm_clk1_sleep = "/pinctrl/pdm/pdm-clk1-sleep"; + pdm_sdi0m0_sleep = "/pinctrl/pdm/pdm-sdi0m0-sleep"; + pdm_sdi0m1_sleep = "/pinctrl/pdm/pdm-sdi0m1-sleep"; + pdm_sdi1_sleep = "/pinctrl/pdm/pdm-sdi1-sleep"; + pdm_sdi2_sleep = "/pinctrl/pdm/pdm-sdi2-sleep"; + pdm_sdi3_sleep = "/pinctrl/pdm/pdm-sdi3-sleep"; + i2s0_8ch_mclk = "/pinctrl/i2s0/i2s0-8ch-mclk"; + i2s0_8ch_sclktx = "/pinctrl/i2s0/i2s0-8ch-sclktx"; + i2s0_8ch_sclkrx = "/pinctrl/i2s0/i2s0-8ch-sclkrx"; + i2s0_8ch_lrcktx = "/pinctrl/i2s0/i2s0-8ch-lrcktx"; + i2s0_8ch_lrckrx = "/pinctrl/i2s0/i2s0-8ch-lrckrx"; + i2s0_8ch_sdo0 = "/pinctrl/i2s0/i2s0-8ch-sdo0"; + i2s0_8ch_sdo1 = "/pinctrl/i2s0/i2s0-8ch-sdo1"; + i2s0_8ch_sdo2 = "/pinctrl/i2s0/i2s0-8ch-sdo2"; + i2s0_8ch_sdo3 = "/pinctrl/i2s0/i2s0-8ch-sdo3"; + i2s0_8ch_sdi0 = "/pinctrl/i2s0/i2s0-8ch-sdi0"; + i2s0_8ch_sdi1 = "/pinctrl/i2s0/i2s0-8ch-sdi1"; + i2s0_8ch_sdi2 = "/pinctrl/i2s0/i2s0-8ch-sdi2"; + i2s0_8ch_sdi3 = "/pinctrl/i2s0/i2s0-8ch-sdi3"; + i2s1_2ch_mclk = "/pinctrl/i2s1/i2s1-2ch-mclk"; + i2s1_2ch_sclk = "/pinctrl/i2s1/i2s1-2ch-sclk"; + i2s1_2ch_lrck = "/pinctrl/i2s1/i2s1-2ch-lrck"; + i2s1_2ch_sdi = "/pinctrl/i2s1/i2s1-2ch-sdi"; + i2s1_2ch_sdo = "/pinctrl/i2s1/i2s1-2ch-sdo"; + i2s2_2ch_mclk = "/pinctrl/i2s2/i2s2-2ch-mclk"; + i2s2_2ch_sclk = "/pinctrl/i2s2/i2s2-2ch-sclk"; + i2s2_2ch_lrck = "/pinctrl/i2s2/i2s2-2ch-lrck"; + i2s2_2ch_sdi = "/pinctrl/i2s2/i2s2-2ch-sdi"; + i2s2_2ch_sdo = "/pinctrl/i2s2/i2s2-2ch-sdo"; + sdmmc_clk = "/pinctrl/sdmmc/sdmmc-clk"; + sdmmc_cmd = "/pinctrl/sdmmc/sdmmc-cmd"; + sdmmc_det = "/pinctrl/sdmmc/sdmmc-det"; + sdmmc_bus1 = "/pinctrl/sdmmc/sdmmc-bus1"; + sdmmc_bus4 = "/pinctrl/sdmmc/sdmmc-bus4"; + sdmmc_gpio = "/pinctrl/sdmmc/sdmmc-gpio"; + sdio_clk = "/pinctrl/sdio/sdio-clk"; + sdio_cmd = "/pinctrl/sdio/sdio-cmd"; + sdio_bus4 = "/pinctrl/sdio/sdio-bus4"; + sdio_gpio = "/pinctrl/sdio/sdio-gpio"; + emmc_clk = "/pinctrl/emmc/emmc-clk"; + emmc_cmd = "/pinctrl/emmc/emmc-cmd"; + emmc_pwren = "/pinctrl/emmc/emmc-pwren"; + emmc_rstnout = "/pinctrl/emmc/emmc-rstnout"; + emmc_bus1 = "/pinctrl/emmc/emmc-bus1"; + emmc_bus4 = "/pinctrl/emmc/emmc-bus4"; + emmc_bus8 = "/pinctrl/emmc/emmc-bus8"; + flash_cs0 = "/pinctrl/flash/flash-cs0"; + flash_rdy = "/pinctrl/flash/flash-rdy"; + flash_dqs = "/pinctrl/flash/flash-dqs"; + flash_ale = "/pinctrl/flash/flash-ale"; + flash_cle = "/pinctrl/flash/flash-cle"; + flash_wrn = "/pinctrl/flash/flash-wrn"; + flash_csl = "/pinctrl/flash/flash-csl"; + flash_rdn = "/pinctrl/flash/flash-rdn"; + flash_bus8 = "/pinctrl/flash/flash-bus8"; + lcdc_m0_rgb_pins = "/pinctrl/lcdc/lcdc-m0-rgb-pins"; + lcdc_m0_sleep_pins = "/pinctrl/lcdc/lcdc-m0-sleep-pins"; + lcdc_m1_rgb_pins = "/pinctrl/lcdc/lcdc-m1-rgb-pins"; + lcdc_m1_sleep_pins = "/pinctrl/lcdc/lcdc-m1-sleep-pins"; + pwm0_pin = "/pinctrl/pwm0/pwm0-pin"; + pwm1_pin = "/pinctrl/pwm1/pwm1-pin"; + pwm2_pin = "/pinctrl/pwm2/pwm2-pin"; + pwm3_pin = "/pinctrl/pwm3/pwm3-pin"; + pwm4_pin = "/pinctrl/pwm4/pwm4-pin"; + pwm5_pin = "/pinctrl/pwm5/pwm5-pin"; + pwm6_pin = "/pinctrl/pwm6/pwm6-pin"; + pwm7_pin = "/pinctrl/pwm7/pwm7-pin"; + rmii_pins = "/pinctrl/gmac/rmii-pins"; + mac_refclk_12ma = "/pinctrl/gmac/mac-refclk-12ma"; + mac_refclk = "/pinctrl/gmac/mac-refclk"; + cif_clkout_m0 = "/pinctrl/cif-m0/cif-clkout-m0"; + dvp_d2d9_m0 = "/pinctrl/cif-m0/dvp-d2d9-m0"; + dvp_d0d1_m0 = "/pinctrl/cif-m0/dvp-d0d1-m0"; + dvp_d10d11_m0 = "/pinctrl/cif-m0/d10-d11-m0"; + cif_clkout_m1 = "/pinctrl/cif-m1/cif-clkout-m1"; + dvp_d2d9_m1 = "/pinctrl/cif-m1/dvp-d2d9-m1"; + dvp_d0d1_m1 = "/pinctrl/cif-m1/dvp-d0d1-m1"; + dvp_d10d11_m1 = "/pinctrl/cif-m1/d10-d11-m1"; + isp_prelight = "/pinctrl/isp/isp-prelight"; + pmic_int = "/pinctrl/pmic/pmic_int"; + soc_slppin_gpio = "/pinctrl/pmic/soc_slppin_gpio"; + soc_slppin_slp = "/pinctrl/pmic/soc_slppin_slp"; + soc_slppin_rst = "/pinctrl/pmic/soc_slppin_rst"; + led_pins = "/pinctrl/leds/led-pins"; + btn_pins = "/pinctrl/btns/btn-pins"; + drm_logo = "/reserved-memory/drm-logo@00000000"; + ramoops_mem = "/reserved-memory/region@110000"; + gpio_keys = "/odroidgo3-keys"; + joypad = "/odroidgo3-joypad"; + leds = "/gpio_leds"; + backlight = "/backlight"; + vccsys = "/vccsys"; + }; +}; diff --git a/config/archr-dts/R36S-DTB/DTS/Panel3.dts b/config/archr-dts/R36S-DTB/DTS/Panel3.dts new file mode 100644 index 0000000000..6fd4f4e74a --- /dev/null +++ b/config/archr-dts/R36S-DTB/DTS/Panel3.dts @@ -0,0 +1,4063 @@ +/dts-v1/; + +/ { + compatible = "rockchip,rk3326-odroidgo3-linux\0rockchip,rk3326"; + interrupt-parent = <0x01>; + #address-cells = <0x02>; + #size-cells = <0x02>; + model = "Game Console R35S/R36S fix by AeolusUX"; + + ddr_timing { + compatible = "rockchip,ddr-timing"; + ddr2_speed_bin = <0x00>; + ddr3_speed_bin = <0x15>; + ddr4_speed_bin = <0x0c>; + pd_idle = <0x0d>; + sr_idle = <0x5d>; + sr_mc_gate_idle = <0x00>; + srpd_lite_idle = <0x00>; + standby_idle = <0x00>; + auto_pd_dis_freq = <0x42a>; + auto_sr_dis_freq = <0x320>; + ddr2_dll_dis_freq = <0x12c>; + ddr3_dll_dis_freq = <0x12c>; + ddr4_dll_dis_freq = <0x271>; + phy_dll_dis_freq = <0x190>; + ddr2_odt_dis_freq = <0x64>; + phy_ddr2_odt_dis_freq = <0x64>; + ddr2_drv = <0x01>; + ddr2_odt = <0x96>; + phy_ddr2_ca_drv = <0x15>; + phy_ddr2_ck_drv = <0x12>; + phy_ddr2_dq_drv = <0x15>; + phy_ddr2_odt = <0x02>; + ddr3_odt_dis_freq = <0x190>; + phy_ddr3_odt_dis_freq = <0x190>; + ddr3_drv = <0x28>; + ddr3_odt = <0x78>; + phy_ddr3_ca_drv = <0x15>; + phy_ddr3_ck_drv = <0x12>; + phy_ddr3_dq_drv = <0x15>; + phy_ddr3_odt = <0x02>; + phy_lpddr2_odt_dis_freq = <0x29a>; + lpddr2_drv = <0x28>; + phy_lpddr2_ca_drv = <0x16>; + phy_lpddr2_ck_drv = <0x13>; + phy_lpddr2_dq_drv = <0x16>; + phy_lpddr2_odt = <0x00>; + lpddr3_odt_dis_freq = <0x190>; + phy_lpddr3_odt_dis_freq = <0x190>; + lpddr3_drv = <0x28>; + lpddr3_odt = <0xf0>; + phy_lpddr3_ca_drv = <0x16>; + phy_lpddr3_ck_drv = <0x13>; + phy_lpddr3_dq_drv = <0x16>; + phy_lpddr3_odt = <0x02>; + lpddr4_odt_dis_freq = <0x320>; + phy_lpddr4_odt_dis_freq = <0x320>; + lpddr4_drv = <0x3c>; + lpddr4_dq_odt = <0x28>; + lpddr4_ca_odt = <0x28>; + phy_lpddr4_ca_drv = <0x14>; + phy_lpddr4_ck_cs_drv = <0x06>; + phy_lpddr4_dq_drv = <0x06>; + phy_lpddr4_odt = <0x10>; + ddr4_odt_dis_freq = <0x29a>; + phy_ddr4_odt_dis_freq = <0x29a>; + ddr4_drv = <0x22>; + ddr4_odt = <0xf0>; + phy_ddr4_ca_drv = <0x16>; + phy_ddr4_ck_drv = <0x13>; + phy_ddr4_dq_drv = <0x16>; + phy_ddr4_odt = <0x02>; + ddr3a1_ddr4a9_de-skew = <0x06>; + ddr3a0_ddr4a10_de-skew = <0x07>; + ddr3a3_ddr4a6_de-skew = <0x07>; + ddr3a2_ddr4a4_de-skew = <0x07>; + ddr3a5_ddr4a8_de-skew = <0x07>; + ddr3a4_ddr4a5_de-skew = <0x07>; + ddr3a7_ddr4a11_de-skew = <0x07>; + ddr3a6_ddr4a7_de-skew = <0x06>; + ddr3a9_ddr4a0_de-skew = <0x07>; + ddr3a8_ddr4a13_de-skew = <0x07>; + ddr3a11_ddr4a3_de-skew = <0x07>; + ddr3a10_ddr4cs0_de-skew = <0x07>; + ddr3a13_ddr4a2_de-skew = <0x07>; + ddr3a12_ddr4ba1_de-skew = <0x07>; + ddr3a15_ddr4odt0_de-skew = <0x07>; + ddr3a14_ddr4a1_de-skew = <0x07>; + ddr3ba1_ddr4a15_de-skew = <0x07>; + ddr3ba0_ddr4bg0_de-skew = <0x07>; + ddr3ras_ddr4cke_de-skew = <0x07>; + ddr3ba2_ddr4ba0_de-skew = <0x07>; + ddr3we_ddr4bg1_de-skew = <0x07>; + ddr3cas_ddr4a12_de-skew = <0x07>; + ddr3ckn_ddr4ckn_de-skew = <0x07>; + ddr3ckp_ddr4ckp_de-skew = <0x07>; + ddr3cke_ddr4a16_de-skew = <0x07>; + ddr3odt0_ddr4a14_de-skew = <0x07>; + ddr3cs0_ddr4act_de-skew = <0x06>; + ddr3reset_ddr4reset_de-skew = <0x07>; + ddr3cs1_ddr4cs1_de-skew = <0x06>; + ddr3odt1_ddr4odt1_de-skew = <0x07>; + cs0_dm0_rx_de-skew = <0x07>; + cs0_dm0_tx_de-skew = <0x07>; + cs0_dq0_rx_de-skew = <0x08>; + cs0_dq0_tx_de-skew = <0x08>; + cs0_dq1_rx_de-skew = <0x09>; + cs0_dq1_tx_de-skew = <0x08>; + cs0_dq2_rx_de-skew = <0x08>; + cs0_dq2_tx_de-skew = <0x08>; + cs0_dq3_rx_de-skew = <0x08>; + cs0_dq3_tx_de-skew = <0x08>; + cs0_dq4_rx_de-skew = <0x09>; + cs0_dq4_tx_de-skew = <0x08>; + cs0_dq5_rx_de-skew = <0x09>; + cs0_dq5_tx_de-skew = <0x08>; + cs0_dq6_rx_de-skew = <0x09>; + cs0_dq6_tx_de-skew = <0x08>; + cs0_dq7_rx_de-skew = <0x08>; + cs0_dq7_tx_de-skew = <0x08>; + cs0_dqs0_rx_de-skew = <0x06>; + cs0_dqs0p_tx_de-skew = <0x09>; + cs0_dqs0n_tx_de-skew = <0x09>; + cs0_dm1_rx_de-skew = <0x07>; + cs0_dm1_tx_de-skew = <0x06>; + cs0_dq8_rx_de-skew = <0x08>; + cs0_dq8_tx_de-skew = <0x07>; + cs0_dq9_rx_de-skew = <0x09>; + cs0_dq9_tx_de-skew = <0x07>; + cs0_dq10_rx_de-skew = <0x08>; + cs0_dq10_tx_de-skew = <0x08>; + cs0_dq11_rx_de-skew = <0x08>; + cs0_dq11_tx_de-skew = <0x07>; + cs0_dq12_rx_de-skew = <0x08>; + cs0_dq12_tx_de-skew = <0x08>; + cs0_dq13_rx_de-skew = <0x09>; + cs0_dq13_tx_de-skew = <0x07>; + cs0_dq14_rx_de-skew = <0x09>; + cs0_dq14_tx_de-skew = <0x08>; + cs0_dq15_rx_de-skew = <0x09>; + cs0_dq15_tx_de-skew = <0x07>; + cs0_dqs1_rx_de-skew = <0x07>; + cs0_dqs1p_tx_de-skew = <0x09>; + cs0_dqs1n_tx_de-skew = <0x09>; + cs0_dm2_rx_de-skew = <0x07>; + cs0_dm2_tx_de-skew = <0x07>; + cs0_dq16_rx_de-skew = <0x09>; + cs0_dq16_tx_de-skew = <0x09>; + cs0_dq17_rx_de-skew = <0x07>; + cs0_dq17_tx_de-skew = <0x09>; + cs0_dq18_rx_de-skew = <0x07>; + cs0_dq18_tx_de-skew = <0x08>; + cs0_dq19_rx_de-skew = <0x07>; + cs0_dq19_tx_de-skew = <0x09>; + cs0_dq20_rx_de-skew = <0x09>; + cs0_dq20_tx_de-skew = <0x09>; + cs0_dq21_rx_de-skew = <0x09>; + cs0_dq21_tx_de-skew = <0x09>; + cs0_dq22_rx_de-skew = <0x08>; + cs0_dq22_tx_de-skew = <0x09>; + cs0_dq23_rx_de-skew = <0x08>; + cs0_dq23_tx_de-skew = <0x09>; + cs0_dqs2_rx_de-skew = <0x06>; + cs0_dqs2p_tx_de-skew = <0x09>; + cs0_dqs2n_tx_de-skew = <0x09>; + cs0_dm3_rx_de-skew = <0x07>; + cs0_dm3_tx_de-skew = <0x07>; + cs0_dq24_rx_de-skew = <0x08>; + cs0_dq24_tx_de-skew = <0x08>; + cs0_dq25_rx_de-skew = <0x09>; + cs0_dq25_tx_de-skew = <0x09>; + cs0_dq26_rx_de-skew = <0x09>; + cs0_dq26_tx_de-skew = <0x08>; + cs0_dq27_rx_de-skew = <0x09>; + cs0_dq27_tx_de-skew = <0x08>; + cs0_dq28_rx_de-skew = <0x09>; + cs0_dq28_tx_de-skew = <0x09>; + cs0_dq29_rx_de-skew = <0x09>; + cs0_dq29_tx_de-skew = <0x09>; + cs0_dq30_rx_de-skew = <0x08>; + cs0_dq30_tx_de-skew = <0x08>; + cs0_dq31_rx_de-skew = <0x08>; + cs0_dq31_tx_de-skew = <0x08>; + cs0_dqs3_rx_de-skew = <0x07>; + cs0_dqs3p_tx_de-skew = <0x09>; + cs0_dqs3n_tx_de-skew = <0x09>; + cs1_dm0_rx_de-skew = <0x07>; + cs1_dm0_tx_de-skew = <0x07>; + cs1_dq0_rx_de-skew = <0x08>; + cs1_dq0_tx_de-skew = <0x08>; + cs1_dq1_rx_de-skew = <0x09>; + cs1_dq1_tx_de-skew = <0x08>; + cs1_dq2_rx_de-skew = <0x08>; + cs1_dq2_tx_de-skew = <0x08>; + cs1_dq3_rx_de-skew = <0x08>; + cs1_dq3_tx_de-skew = <0x08>; + cs1_dq4_rx_de-skew = <0x08>; + cs1_dq4_tx_de-skew = <0x08>; + cs1_dq5_rx_de-skew = <0x09>; + cs1_dq5_tx_de-skew = <0x08>; + cs1_dq6_rx_de-skew = <0x09>; + cs1_dq6_tx_de-skew = <0x08>; + cs1_dq7_rx_de-skew = <0x08>; + cs1_dq7_tx_de-skew = <0x08>; + cs1_dqs0_rx_de-skew = <0x06>; + cs1_dqs0p_tx_de-skew = <0x09>; + cs1_dqs0n_tx_de-skew = <0x09>; + cs1_dm1_rx_de-skew = <0x07>; + cs1_dm1_tx_de-skew = <0x07>; + cs1_dq8_rx_de-skew = <0x08>; + cs1_dq8_tx_de-skew = <0x08>; + cs1_dq9_rx_de-skew = <0x08>; + cs1_dq9_tx_de-skew = <0x07>; + cs1_dq10_rx_de-skew = <0x07>; + cs1_dq10_tx_de-skew = <0x08>; + cs1_dq11_rx_de-skew = <0x08>; + cs1_dq11_tx_de-skew = <0x08>; + cs1_dq12_rx_de-skew = <0x08>; + cs1_dq12_tx_de-skew = <0x07>; + cs1_dq13_rx_de-skew = <0x08>; + cs1_dq13_tx_de-skew = <0x08>; + cs1_dq14_rx_de-skew = <0x08>; + cs1_dq14_tx_de-skew = <0x08>; + cs1_dq15_rx_de-skew = <0x08>; + cs1_dq15_tx_de-skew = <0x07>; + cs1_dqs1_rx_de-skew = <0x07>; + cs1_dqs1p_tx_de-skew = <0x09>; + cs1_dqs1n_tx_de-skew = <0x09>; + cs1_dm2_rx_de-skew = <0x07>; + cs1_dm2_tx_de-skew = <0x08>; + cs1_dq16_rx_de-skew = <0x08>; + cs1_dq16_tx_de-skew = <0x09>; + cs1_dq17_rx_de-skew = <0x08>; + cs1_dq17_tx_de-skew = <0x09>; + cs1_dq18_rx_de-skew = <0x07>; + cs1_dq18_tx_de-skew = <0x08>; + cs1_dq19_rx_de-skew = <0x08>; + cs1_dq19_tx_de-skew = <0x09>; + cs1_dq20_rx_de-skew = <0x09>; + cs1_dq20_tx_de-skew = <0x09>; + cs1_dq21_rx_de-skew = <0x09>; + cs1_dq21_tx_de-skew = <0x09>; + cs1_dq22_rx_de-skew = <0x08>; + cs1_dq22_tx_de-skew = <0x09>; + cs1_dq23_rx_de-skew = <0x08>; + cs1_dq23_tx_de-skew = <0x09>; + cs1_dqs2_rx_de-skew = <0x06>; + cs1_dqs2p_tx_de-skew = <0x09>; + cs1_dqs2n_tx_de-skew = <0x09>; + cs1_dm3_rx_de-skew = <0x07>; + cs1_dm3_tx_de-skew = <0x07>; + cs1_dq24_rx_de-skew = <0x08>; + cs1_dq24_tx_de-skew = <0x09>; + cs1_dq25_rx_de-skew = <0x09>; + cs1_dq25_tx_de-skew = <0x09>; + cs1_dq26_rx_de-skew = <0x09>; + cs1_dq26_tx_de-skew = <0x08>; + cs1_dq27_rx_de-skew = <0x08>; + cs1_dq27_tx_de-skew = <0x08>; + cs1_dq28_rx_de-skew = <0x09>; + cs1_dq28_tx_de-skew = <0x09>; + cs1_dq29_rx_de-skew = <0x09>; + cs1_dq29_tx_de-skew = <0x09>; + cs1_dq30_rx_de-skew = <0x09>; + cs1_dq30_tx_de-skew = <0x08>; + cs1_dq31_rx_de-skew = <0x08>; + cs1_dq31_tx_de-skew = <0x08>; + cs1_dqs3_rx_de-skew = <0x07>; + cs1_dqs3p_tx_de-skew = <0x09>; + cs1_dqs3n_tx_de-skew = <0x09>; + phandle = <0xaf>; + }; + + aliases { + ethernet0 = "/ethernet@ff360000"; + i2c0 = "/i2c@ff180000"; + i2c1 = "/i2c@ff190000"; + i2c2 = "/i2c@ff1a0000"; + i2c3 = "/i2c@ff1b0000"; + serial0 = "/serial@ff030000"; + serial1 = "/serial@ff158000"; + serial2 = "/serial@ff160000"; + serial3 = "/serial@ff168000"; + serial4 = "/serial@ff170000"; + serial5 = "/serial@ff178000"; + spi0 = "/spi@ff1d0000"; + spi1 = "/spi@ff1d8000"; + }; + + cpus { + #address-cells = <0x02>; + #size-cells = <0x00>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x00>; + enable-method = "psci"; + clocks = <0x02 0x07>; + #cooling-cells = <0x02>; + dynamic-power-coefficient = <0x5a>; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + cpu-supply = <0x06>; + phandle = <0x09>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x01>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0a>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x02>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0b>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x03>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0c>; + }; + + idle-states { + entry-method = "psci"; + + cpu-sleep { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x10000>; + entry-latency-us = <0x78>; + exit-latency-us = <0xfa>; + min-residency-us = <0x384>; + phandle = <0x04>; + }; + + cluster-sleep { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x1010000>; + entry-latency-us = <0x190>; + exit-latency-us = <0x1f4>; + min-residency-us = <0x7d0>; + phandle = <0x05>; + }; + }; + }; + + cpu0-opp-table { + compatible = "operating-points-v2"; + opp-shared; + rockchip,temp-hysteresis = <0x1388>; + rockchip,low-temp = <0x00>; + rockchip,low-temp-min-volt = <0xf4240>; + rockchip,low-temp-adjust-volt = <0x00 0x5e8 0xc350>; + clocks = <0x02 0x01>; + rockchip,avs-scale = <0x04>; + rockchip,max-volt = <0x149970>; + rockchip,evb-irdrop = <0x61a8>; + nvmem-cells = <0x07 0x08>; + nvmem-cell-names = "cpu_leakage\0performance"; + rockchip,bin-scaling-sel = <0x00 0x0d 0x01 0x0d>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-freq = <0x639c0>; + rockchip,pvtm-volt = <0xf4240>; + rockchip,pvtm-ch = <0x00 0x00>; + rockchip,pvtm-sample-time = <0x3e8>; + rockchip,pvtm-number = <0x0a>; + rockchip,pvtm-error = <0x3e8>; + rockchip,pvtm-ref-temp = <0x28>; + rockchip,pvtm-temp-prop = <0xffffffc8 0xffffffc8>; + rockchip,thermal-zone = "soc-thermal"; + rockchip,avs = <0x01>; + phandle = <0x03>; + + opp-1008000000 { + opp-hz = <0x00 0x3c14dc00>; + opp-microvolt = <0x11edd8 0x11edd8 0x149970>; + opp-microvolt-L0 = <0x11edd8 0x11edd8 0x149970>; + opp-microvolt-L1 = <0x112a88 0x112a88 0x149970>; + opp-microvolt-L2 = <0x112a88 0x112a88 0x149970>; + opp-microvolt-L3 = <0x100590 0x100590 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1200000000 { + opp-hz = <0x00 0x47868c00>; + opp-microvolt = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L0 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L1 = <0x137478 0x137478 0x149970>; + opp-microvolt-L2 = <0x1312d0 0x1312d0 0x149970>; + opp-microvolt-L3 = <0x124f80 0x124f80 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1248000000 { + opp-hz = <0x00 0x4a62f800>; + opp-microvolt = <0x149970 0x149970 0x149970>; + opp-microvolt-L0 = <0x149970 0x149970 0x149970>; + opp-microvolt-L1 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L2 = <0x137478 0x137478 0x149970>; + opp-microvolt-L3 = <0x12b128 0x12b128 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1296000000 { + opp-hz = <0x00 0x4d3f6400>; + opp-microvolt = <0x149970 0x149970 0x149970>; + opp-microvolt-L0 = <0x149970 0x149970 0x149970>; + opp-microvolt-L1 = <0x149970 0x149970 0x149970>; + opp-microvolt-L2 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L3 = <0x1312d0 0x1312d0 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1512000000 { + opp-hz = <0x00 0x5a1f4a00>; + opp-microvolt = <0x149970 0x149970 0x149970>; + opp-microvolt-L0 = <0x149970 0x149970 0x149970>; + opp-microvolt-L1 = <0x149970 0x149970 0x149970>; + opp-microvolt-L2 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L3 = <0x1312d0 0x1312d0 0x149970>; + clock-latency-ns = <0x9c40>; + }; + }; + + arm-pmu { + compatible = "arm,cortex-a53-pmu"; + interrupts = <0x00 0x64 0x04 0x00 0x65 0x04 0x00 0x66 0x04 0x00 0x67 0x04>; + interrupt-affinity = <0x09 0x0a 0x0b 0x0c>; + }; + + bus-soc { + compatible = "rockchip,px30-bus"; + rockchip,busfreq-policy = "autocs"; + phandle = <0xc4>; + + soc-bus0 { + bus-id = <0x00>; + timer-us = <0x14>; + enable-msk = <0x40f7>; + status = "disabled"; + }; + + soc-bus1 { + bus-id = <0x01>; + timer-us = <0xc8>; + enable-msk = <0x40bf>; + status = "disabled"; + }; + + soc-bus2 { + bus-id = <0x02>; + timer-us = <0xc8>; + enable-msk = <0x4007>; + status = "disabled"; + }; + }; + + bus-apll { + compatible = "rockchip,px30-bus"; + rockchip,busfreq-policy = "clkfreq"; + clocks = <0x02 0x01>; + clock-names = "bus"; + operating-points-v2 = <0x0d>; + status = "okay"; + bus-supply = <0x0e>; + phandle = <0xc5>; + }; + + bus-apll-opp-table { + compatible = "operating-points-v2"; + opp-shared; + phandle = <0x0d>; + + opp-1512000000 { + opp-hz = <0x00 0x5a1f4a00>; + opp-microvolt = <0xf4240>; + }; + + opp-1008000000 { + opp-hz = <0x00 0x3c14dc00>; + opp-microvolt = <0xe7ef0>; + }; + }; + + cpuinfo { + compatible = "rockchip,cpuinfo"; + nvmem-cells = <0x0f>; + nvmem-cell-names = "id"; + }; + + display-subsystem { + compatible = "rockchip,display-subsystem"; + ports = <0x10>; + status = "okay"; + logo-memory-region = <0x11>; + phandle = <0xc6>; + + route { + + route-lvds { + status = "disabled"; + logo,uboot = "logo.gif"; + logo,kernel = "logo_kernel.gif"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x12>; + phandle = <0xc7>; + }; + + route-dsi { + status = "okay"; + logo,uboot = "logo.gif"; + logo,kernel = "logo_kernel.gif"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x13>; + phandle = <0xc8>; + }; + + route-rgb { + status = "disabled"; + logo,uboot = "logo.gif"; + logo,kernel = "logo_kernel.gif"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x14>; + phandle = <0xc9>; + }; + }; + }; + + firmware { + + optee { + compatible = "linaro,optee-tz"; + method = "smc"; + }; + }; + + external-gmac-clock { + compatible = "fixed-clock"; + clock-frequency = <0x2faf080>; + clock-output-names = "gmac_clkin"; + #clock-cells = <0x00>; + phandle = <0xca>; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + rockchip-suspend { + compatible = "rockchip,pm-px30"; + status = "okay"; + rockchip,sleep-debug-en = <0x01>; + rockchip,sleep-mode-config = <0x20702>; + rockchip,wakeup-config = <0x85>; + phandle = <0xcb>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <0x01 0x0d 0xf04 0x01 0x0e 0xf04 0x01 0x0b 0xf04 0x01 0x0a 0xf04>; + }; + + xin24m { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x16e3600>; + clock-output-names = "xin24m"; + phandle = <0xcc>; + }; + + xin32k { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x8000>; + clock-output-names = "xin32k"; + phandle = <0xcd>; + }; + + power-management@ff000000 { + compatible = "rockchip,px30-pmu\0syscon\0simple-mfd"; + reg = <0x00 0xff000000 0x00 0x1000>; + phandle = <0xce>; + + power-controller { + compatible = "rockchip,px30-power-controller"; + #power-domain-cells = <0x01>; + #address-cells = <0x01>; + #size-cells = <0x00>; + phandle = <0x8a>; + + pd_usb@5 { + reg = <0x05>; + clocks = <0x02 0x103 0x02 0x102 0x02 0x3c>; + pm_qos = <0x15 0x16>; + }; + + pd_sdcard@7 { + reg = <0x07>; + clocks = <0x02 0xf7 0x02 0x3b>; + pm_qos = <0x17>; + }; + + pd_gmac@9 { + reg = <0x09>; + clocks = <0x02 0xb2 0x02 0x143 0x02 0x40 0x02 0x3f>; + pm_qos = <0x18>; + }; + + pd_mmc_nand@10 { + reg = <0x0a>; + clocks = <0x02 0xfe 0x02 0x100 0x02 0xff 0x02 0x101 0x02 0x39 0x02 0x37 0x02 0x38 0x02 0x3a>; + pm_qos = <0x19 0x1a 0x1b 0x1c>; + }; + + pd_vpu@11 { + reg = <0x0b>; + clocks = <0x02 0xaf 0x02 0xf4 0x02 0x4b>; + pm_qos = <0x1d 0x1e>; + }; + + pd_vo@12 { + reg = <0x0c>; + clocks = <0x02 0xb7 0x02 0xb5 0x02 0xb6 0x02 0x96 0x02 0x97 0x02 0xfd 0x02 0xfb 0x02 0xfc 0x02 0x144 0x02 0x35 0x02 0x36>; + pm_qos = <0x1f 0x20 0x21 0x22>; + }; + + pd_vi@13 { + reg = <0x0d>; + clocks = <0x02 0xb3 0x02 0xb4 0x02 0xf9 0x02 0xfa 0x02 0x33>; + pm_qos = <0x23 0x24 0x25 0x26 0x27>; + }; + + pd_gpu@14 { + reg = <0x0e>; + clocks = <0x02 0x49>; + pm_qos = <0x28>; + }; + }; + }; + + syscon@ff010000 { + compatible = "rockchip,px30-pmugrf\0syscon\0simple-mfd"; + reg = <0x00 0xff010000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0xac>; + + io-domains { + compatible = "rockchip,px30-pmu-io-voltage-domain"; + status = "okay"; + pmuio1-supply = <0x29>; + pmuio2-supply = <0x29>; + phandle = <0xcf>; + }; + + reboot-mode { + compatible = "syscon-reboot-mode"; + offset = <0x200>; + mode-bootloader = <0x5242c301>; + mode-charge = <0x5242c30b>; + mode-fastboot = <0x5242c309>; + mode-loader = <0x5242c301>; + mode-normal = <0x5242c300>; + mode-recovery = <0x5242c303>; + mode-ums = <0x5242c30c>; + }; + + pmu-pvtm { + compatible = "rockchip,px30-pmu-pvtm"; + clocks = <0x2a 0x07>; + clock-names = "pmu"; + status = "okay"; + phandle = <0xd0>; + }; + }; + + serial@ff030000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff030000 0x00 0x100>; + interrupts = <0x00 0x0f 0x04>; + clocks = <0x2a 0x06 0x2a 0x15>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x00 0x2b 0x01>; + pinctrl-names = "default"; + pinctrl-0 = <0x2c 0x2d 0x2e>; + status = "disabled"; + phandle = <0xd1>; + }; + + i2s@ff060000 { + compatible = "rockchip,px30-i2s-tdm"; + reg = <0x00 0xff060000 0x00 0x1000>; + interrupts = <0x00 0x0c 0x04>; + clocks = <0x02 0x10 0x02 0x12 0x02 0x106>; + clock-names = "mclk_tx\0mclk_rx\0hclk"; + dmas = <0x2b 0x10 0x2b 0x11>; + dma-names = "tx\0rx"; + resets = <0x02 0x84 0x02 0xbf>; + reset-names = "tx-m\0rx-m"; + rockchip,cru = <0x02>; + rockchip,grf = <0x2f>; + pinctrl-names = "default"; + pinctrl-0 = <0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x3a 0x3b>; + status = "disabled"; + phandle = <0xd2>; + }; + + i2s@ff070000 { + compatible = "rockchip,px30-i2s\0rockchip,rk3066-i2s"; + reg = <0x00 0xff070000 0x00 0x1000>; + interrupts = <0x00 0x0d 0x04>; + clocks = <0x02 0x14 0x02 0x107>; + clock-names = "i2s_clk\0i2s_hclk"; + dmas = <0x2b 0x12 0x2b 0x13>; + dma-names = "tx\0rx"; + resets = <0x02 0x86 0x02 0x85>; + reset-names = "reset-m\0reset-h"; + pinctrl-names = "default"; + pinctrl-0 = <0x3c 0x3d 0x3e 0x3f>; + status = "okay"; + #sound-dai-cells = <0x00>; + phandle = <0xc2>; + }; + + i2s@ff080000 { + compatible = "rockchip,px30-i2s\0rockchip,rk3066-i2s"; + reg = <0x00 0xff080000 0x00 0x1000>; + interrupts = <0x00 0x0e 0x04>; + clocks = <0x02 0x16 0x02 0x108>; + clock-names = "i2s_clk\0i2s_hclk"; + dmas = <0x2b 0x14 0x2b 0x15>; + dma-names = "tx\0rx"; + resets = <0x02 0x88 0x02 0x87>; + reset-names = "reset-m\0reset-h"; + pinctrl-names = "default"; + pinctrl-0 = <0x40 0x41 0x42 0x43>; + status = "disabled"; + phandle = <0xd3>; + }; + + pdm@ff0a0000 { + compatible = "rockchip,px30-pdm\0rockchip,pdm"; + reg = <0x00 0xff0a0000 0x00 0x1000>; + clocks = <0x02 0x0f 0x02 0x105>; + clock-names = "pdm_clk\0pdm_hclk"; + dmas = <0x2b 0x18>; + dma-names = "rx"; + resets = <0x02 0x82>; + reset-names = "pdm-m"; + pinctrl-names = "default"; + pinctrl-0 = <0x44 0x45 0x46 0x47 0x48 0x49>; + status = "disabled"; + phandle = <0xd4>; + }; + + crypto@ff0b0000 { + compatible = "rockchip,px30-crypto"; + reg = <0x00 0xff0b0000 0x00 0x4000>; + interrupts = <0x00 0x52 0x04>; + clocks = <0x02 0xac 0x02 0xf1 0x02 0x30 0x02 0x31>; + clock-names = "aclk\0hclk\0sclk\0apb_pclk"; + resets = <0x02 0x74>; + reset-names = "crypto-rst"; + status = "disabled"; + phandle = <0xd5>; + }; + + rng@ff0b0000 { + compatible = "rockchip,cryptov2-rng"; + reg = <0x00 0xff0b0000 0x00 0x4000>; + clocks = <0x02 0x30 0x02 0x31 0x02 0xac 0x02 0xf1>; + clock-names = "clk_crypto\0clk_crypto_apk\0aclk_crypto\0hclk_crypto"; + assigned-clocks = <0x02 0x30 0x02 0x31 0x02 0xac 0x02 0xf1>; + assigned-clock-rates = <0x8f0d180 0x8f0d180 0xbebc200 0x5f5e100>; + resets = <0x02 0x74>; + reset-names = "reset"; + status = "okay"; + phandle = <0xd6>; + }; + + interrupt-controller@ff131000 { + compatible = "arm,gic-400"; + #interrupt-cells = <0x03>; + #address-cells = <0x00>; + interrupt-controller; + reg = <0x00 0xff131000 0x00 0x1000 0x00 0xff132000 0x00 0x2000 0x00 0xff134000 0x00 0x2000 0x00 0xff136000 0x00 0x2000>; + interrupts = <0x01 0x09 0xf04>; + phandle = <0x01>; + }; + + syscon@ff140000 { + compatible = "rockchip,px30-grf\0syscon\0simple-mfd"; + reg = <0x00 0xff140000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0x2f>; + + io-domains { + compatible = "rockchip,px30-io-voltage-domain"; + status = "okay"; + vccio1-supply = <0x4a>; + vccio2-supply = <0x4a>; + vccio3-supply = <0x4b>; + vccio4-supply = <0x4b>; + vccio5-supply = <0x4b>; + vccio6-supply = <0x4b>; + phandle = <0xd7>; + }; + + lvds { + compatible = "rockchip,px30-lvds"; + phys = <0x4c>; + phy-names = "phy"; + status = "disabled"; + phandle = <0xd8>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x12>; + phandle = <0xa2>; + }; + }; + }; + }; + + rgb { + compatible = "rockchip,px30-rgb"; + pinctrl-names = "default\0sleep"; + pinctrl-0 = <0x4d>; + pinctrl-1 = <0x4e>; + status = "disabled"; + phys = <0x4c>; + phy-names = "phy"; + phandle = <0xd9>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x14>; + phandle = <0xa4>; + }; + }; + }; + }; + }; + + syscon@ff148000 { + compatible = "syscon\0simple-mfd"; + reg = <0x00 0xff148000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0xda>; + + pvtm { + compatible = "rockchip,px30-pvtm"; + clocks = <0x02 0x4a>; + clock-names = "core"; + status = "okay"; + phandle = <0xdb>; + }; + }; + + serial@ff158000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff158000 0x00 0x100>; + interrupts = <0x00 0x10 0x04>; + clocks = <0x02 0x18 0x02 0x149>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x02 0x2b 0x03>; + pinctrl-names = "default"; + pinctrl-0 = <0x4f 0x50>; + status = "okay"; + phandle = <0xdc>; + }; + + serial@ff160000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff160000 0x00 0x100>; + interrupts = <0x00 0x11 0x04>; + clocks = <0x02 0x19 0x02 0x14a>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x04 0x2b 0x05>; + pinctrl-names = "default"; + pinctrl-0 = <0x51>; + status = "disabled"; + phandle = <0xdd>; + }; + + serial@ff168000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff168000 0x00 0x100>; + interrupts = <0x00 0x12 0x04>; + clocks = <0x02 0x1a 0x02 0x14b>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x06 0x2b 0x07>; + pinctrl-names = "default"; + pinctrl-0 = <0x52 0x53 0x54>; + status = "disabled"; + phandle = <0xde>; + }; + + serial@ff170000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff170000 0x00 0x100>; + interrupts = <0x00 0x13 0x04>; + clocks = <0x02 0x1b 0x02 0x14c>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x08 0x2b 0x09>; + pinctrl-names = "default"; + pinctrl-0 = <0x55 0x56 0x57>; + status = "disabled"; + phandle = <0xdf>; + }; + + serial@ff178000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff178000 0x00 0x100>; + interrupts = <0x00 0x14 0x04>; + clocks = <0x02 0x1c 0x02 0x14d>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x0a 0x2b 0x0b>; + pinctrl-names = "default"; + pinctrl-0 = <0x58 0x59 0x5a>; + status = "disabled"; + phandle = <0xe0>; + }; + + i2c@ff180000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff180000 0x00 0x1000>; + clocks = <0x02 0x1d 0x02 0x14e>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x07 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x5b>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + clock-frequency = <0x61a80>; + i2c-scl-rising-time-ns = <0x118>; + i2c-scl-falling-time-ns = <0x10>; + phandle = <0xe1>; + + pmic@20 { + compatible = "rockchip,rk817"; + reg = <0x20>; + interrupt-parent = <0x5c>; + interrupts = <0x0a 0x08>; + pinctrl-names = "default\0pmic-sleep\0pmic-power-off\0pmic-reset"; + pinctrl-0 = <0x5d>; + pinctrl-1 = <0x5e 0x5f>; + pinctrl-2 = <0x60 0x61>; + pinctrl-3 = <0x62 0x63>; + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <0x01>; + clock-output-names = "rk808-clkout1\0rk808-clkout2"; + pmic-reset-func = <0x01>; + vcc1-supply = <0x64>; + vcc2-supply = <0x64>; + vcc3-supply = <0x64>; + vcc4-supply = <0x64>; + vcc5-supply = <0x64>; + vcc6-supply = <0x64>; + vcc7-supply = <0x64>; + vcc8-supply = <0x64>; + vcc9-supply = <0x65>; + phandle = <0xe2>; + + pwrkey { + status = "okay"; + }; + + pinctrl_rk8xx { + gpio-controller; + #gpio-cells = <0x02>; + phandle = <0xe3>; + + rk817_ts_gpio1 { + pins = "gpio_ts"; + function = "pin_fun1"; + phandle = <0xe4>; + }; + + rk817_gt_gpio2 { + pins = "gpio_gt"; + function = "pin_fun1"; + phandle = <0xe5>; + }; + + rk817_pin_ts { + pins = "gpio_ts"; + function = "pin_fun0"; + phandle = <0xe6>; + }; + + rk817_pin_gt { + pins = "gpio_gt"; + function = "pin_fun0"; + phandle = <0xe7>; + }; + + rk817_slppin_null { + pins = "gpio_slp"; + function = "pin_fun0"; + phandle = <0xe8>; + }; + + rk817_slppin_slp { + pins = "gpio_slp"; + function = "pin_fun1"; + phandle = <0x5f>; + }; + + rk817_slppin_pwrdn { + pins = "gpio_slp"; + function = "pin_fun2"; + phandle = <0x61>; + }; + + rk817_slppin_rst { + pins = "gpio_slp"; + function = "pin_fun3"; + phandle = <0x63>; + }; + }; + + regulators { + + DCDC_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xe7ef0>; + regulator-max-microvolt = <0x118c30>; + regulator-ramp-delay = <0x1771>; + regulator-initial-mode = <0x02>; + regulator-name = "vdd_logic"; + phandle = <0x0e>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0xe7ef0>; + }; + }; + + DCDC_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xe7ef0>; + regulator-max-microvolt = <0x149970>; + regulator-ramp-delay = <0x1771>; + regulator-initial-mode = <0x02>; + regulator-name = "vdd_arm"; + phandle = <0x06>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0xe7ef0>; + }; + }; + + DCDC_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x02>; + regulator-name = "vcc_ddr"; + phandle = <0xe9>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + DCDC_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-initial-mode = <0x02>; + regulator-name = "vcc_3v3"; + phandle = <0x4b>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG1 { + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + regulator-name = "vcc_1v0"; + phandle = <0xea>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0xf4240>; + }; + }; + + LDO_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + regulator-name = "vcc1v8_soc"; + phandle = <0x88>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x1b7740>; + }; + }; + + LDO_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + regulator-name = "vcc1v0_soc"; + phandle = <0xeb>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0xf4240>; + }; + }; + + LDO_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "vcc3v3_pmu"; + phandle = <0x29>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + regulator-name = "vccio_sd"; + phandle = <0x4a>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x1b7740>; + }; + }; + + LDO_REG6 { + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x2dc6c0>; + regulator-boot-on; + regulator-name = "vcc_sd"; + phandle = <0x93>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x2dc6c0>; + }; + }; + + LDO_REG7 { + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "vcc_backlight"; + phandle = <0x9e>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG8 { + regulator-min-microvolt = <0x2ab980>; + regulator-max-microvolt = <0x2ab980>; + regulator-name = "vcc_lcd"; + phandle = <0x9f>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x2ab980>; + }; + }; + + BOOST { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x4c4b40>; + regulator-max-microvolt = <0x5265c0>; + regulator-name = "boost"; + phandle = <0x65>; + }; + + OTG_SWITCH { + regulator-boot-on; + regulator-name = "otg_switch"; + phandle = <0xec>; + }; + }; + + battery { + compatible = "rk817,battery"; + ocv_table = <0xc5d 0xc94 0xcd0 0xd02 0xd34 0xd66 0xd98 0xdca 0xdfc 0xe2e 0xe56 0xe7e 0xea6 0xece 0xef6 0xf1e 0xf46 0xf6e 0xf96 0xf9b 0xfa0>; + design_capacity = <0xd34>; + design_qmax = <0xe86>; + bat_res = <0x64>; + sleep_enter_current = <0x12c>; + sleep_exit_current = <0x12c>; + sleep_filter_current = <0x64>; + power_off_thresd = <0xbb8>; + zero_algorithm_vol = <0xf0a>; + max_soc_offset = <0x3c>; + monitor_sec = <0x05>; + virtual_power = <0x00>; + sample_res = <0x0a>; + }; + + charger { + compatible = "rk817,charger"; + min_input_voltage = <0x1194>; + max_input_current = <0x5dc>; + max_chrg_current = <0x7d0>; + max_chrg_voltage = <0x1068>; + chrg_term_mode = <0x00>; + chrg_finish_cur = <0x34>; + virtual_power = <0x00>; + sample_res = <0x0a>; + dc_det_gpio = <0x5c 0x0b 0x00>; + bat_low_gpio = <0x66 0x0d 0x00>; + extcon = <0x67>; + }; + + codec { + #sound-dai-cells = <0x00>; + compatible = "rockchip,rk817-codec"; + clocks = <0x02 0x15>; + clock-names = "mclk"; + pinctrl-names = "default"; + pinctrl-0 = <0x68>; + hp-volume = <0x14>; + spk-volume = <0x03>; + status = "okay"; + phandle = <0xc3>; + }; + }; + }; + + i2c@ff190000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff190000 0x00 0x1000>; + clocks = <0x02 0x1e 0x02 0x14f>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x08 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x69>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + clock-frequency = <0x61a80>; + phandle = <0xed>; + }; + + i2c@ff1a0000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff1a0000 0x00 0x1000>; + clocks = <0x02 0x1f 0x02 0x150>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x09 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x6a>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xee>; + }; + + i2c@ff1b0000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff1b0000 0x00 0x1000>; + clocks = <0x02 0x20 0x02 0x151>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x0a 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x6b>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xef>; + }; + + spi@ff1d0000 { + compatible = "rockchip,px30-spi\0rockchip,rk3066-spi"; + reg = <0x00 0xff1d0000 0x00 0x1000>; + interrupts = <0x00 0x1a 0x04>; + #address-cells = <0x01>; + #size-cells = <0x00>; + clocks = <0x02 0x24 0x02 0x155>; + clock-names = "spiclk\0apb_pclk"; + dmas = <0x2b 0x0c 0x2b 0x0d>; + dma-names = "tx\0rx"; + pinctrl-names = "default\0high_speed"; + pinctrl-0 = <0x6c 0x6d 0x6e 0x6f>; + pinctrl-1 = <0x70 0x6d 0x71 0x72>; + status = "disabled"; + phandle = <0xf0>; + }; + + spi@ff1d8000 { + compatible = "rockchip,px30-spi\0rockchip,rk3066-spi"; + reg = <0x00 0xff1d8000 0x00 0x1000>; + interrupts = <0x00 0x1b 0x04>; + #address-cells = <0x01>; + #size-cells = <0x00>; + clocks = <0x02 0x25 0x02 0x156>; + clock-names = "spiclk\0apb_pclk"; + dmas = <0x2b 0x0e 0x2b 0x0f>; + dma-names = "tx\0rx"; + pinctrl-names = "default\0high_speed"; + pinctrl-0 = <0x73 0x74 0x75 0x76 0x77>; + pinctrl-1 = <0x78 0x74 0x75 0x79 0x7a>; + status = "disabled"; + phandle = <0xf1>; + }; + + watchdog@ff1e0000 { + compatible = "snps,dw-wdt"; + reg = <0x00 0xff1e0000 0x00 0x100>; + clocks = <0x02 0x15b>; + interrupts = <0x00 0x25 0x04>; + resets = <0x02 0xb5>; + reset-names = "reset"; + status = "disabled"; + phandle = <0xf2>; + }; + + pwm@ff200000 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200000 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7b>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "okay"; + phandle = <0xbc>; + }; + + pwm@ff200010 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200010 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7c>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "okay"; + phandle = <0xc1>; + }; + + pwm@ff200020 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200020 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7d>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf3>; + }; + + pwm@ff200030 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200030 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7e>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf4>; + }; + + pwm@ff208000 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208000 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7f>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf5>; + }; + + pwm@ff208010 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208010 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x80>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf6>; + }; + + pwm@ff208020 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208020 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x81>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf7>; + }; + + pwm@ff208030 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208030 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x82>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf8>; + }; + + rktimer@ff210000 { + compatible = "rockchip,rk3288-timer"; + reg = <0x00 0xff210000 0x00 0x1000>; + interrupts = <0x00 0x1e 0x04>; + clocks = <0x02 0x159 0x02 0x26>; + clock-names = "pclk\0timer"; + phandle = <0xf9>; + }; + + amba { + compatible = "simple-bus"; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + + dmac@ff240000 { + compatible = "arm,pl330\0arm,primecell"; + reg = <0x00 0xff240000 0x00 0x4000>; + interrupts = <0x00 0x01 0x04 0x00 0x02 0x04>; + clocks = <0x02 0xbb>; + clock-names = "apb_pclk"; + #dma-cells = <0x01>; + peripherals-req-type-burst; + phandle = <0x2b>; + }; + }; + + thermal-zones { + phandle = <0xfa>; + + soc-thermal { + polling-delay-passive = <0x14>; + polling-delay = <0x3e8>; + sustainable-power = <0x2ee>; + thermal-sensors = <0x83 0x00>; + phandle = <0xfb>; + + trips { + + trip-point-0 { + temperature = <0x11170>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0xfc>; + }; + + trip-point-1 { + temperature = <0x14c08>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0x84>; + }; + + soc-crit { + temperature = <0x1c138>; + hysteresis = <0x7d0>; + type = "critical"; + phandle = <0xfd>; + }; + }; + + cooling-maps { + + map0 { + trip = <0x84>; + cooling-device = <0x09 0xffffffff 0xffffffff>; + contribution = <0x1000>; + }; + + map1 { + trip = <0x84>; + cooling-device = <0x85 0xffffffff 0xffffffff>; + contribution = <0x1000>; + }; + }; + }; + + gpu-thermal { + polling-delay-passive = <0x64>; + polling-delay = <0x3e8>; + thermal-sensors = <0x83 0x01>; + phandle = <0xfe>; + }; + }; + + tsadc@ff280000 { + compatible = "rockchip,px30-tsadc"; + reg = <0x00 0xff280000 0x00 0x100>; + interrupts = <0x00 0x24 0x04>; + rockchip,grf = <0x2f>; + clocks = <0x02 0x2c 0x02 0x158>; + clock-names = "tsadc\0apb_pclk"; + assigned-clocks = <0x02 0x2c>; + assigned-clock-rates = <0xc350>; + resets = <0x02 0xa8>; + reset-names = "tsadc-apb"; + #thermal-sensor-cells = <0x01>; + rockchip,hw-tshut-temp = <0x1d4c0>; + status = "okay"; + pinctrl-names = "gpio\0otpout"; + pinctrl-0 = <0x86>; + pinctrl-1 = <0x87>; + phandle = <0x83>; + }; + + saradc@ff288000 { + compatible = "rockchip,px30-saradc\0rockchip,rk3399-saradc"; + reg = <0x00 0xff288000 0x00 0x100>; + interrupts = <0x00 0x54 0x04>; + #io-channel-cells = <0x01>; + clocks = <0x02 0x2d 0x02 0x157>; + clock-names = "saradc\0apb_pclk"; + resets = <0x02 0xa5>; + reset-names = "saradc-apb"; + status = "okay"; + vref-supply = <0x88>; + phandle = <0xbe>; + }; + + otp@ff290000 { + compatible = "rockchip,px30-otp"; + reg = <0x00 0xff290000 0x00 0x4000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + clocks = <0x02 0x2f 0x02 0x15a 0x02 0x161>; + clock-names = "clk_otp\0pclk_otp\0pclk_otp_phy"; + resets = <0x02 0xb4>; + reset-names = "otp_phy"; + phandle = <0xff>; + + id@7 { + reg = <0x07 0x10>; + phandle = <0x0f>; + }; + + cpu-leakage@17 { + reg = <0x17 0x01>; + phandle = <0x07>; + }; + + performance@1e { + reg = <0x1e 0x01>; + bits = <0x04 0x03>; + phandle = <0x08>; + }; + }; + + clock-controller@ff2b0000 { + compatible = "rockchip,px30-cru"; + reg = <0x00 0xff2b0000 0x00 0x1000>; + rockchip,grf = <0x2f>; + rockchip,boost = <0x89>; + #clock-cells = <0x01>; + #reset-cells = <0x01>; + assigned-clocks = <0x02 0x04>; + assigned-clock-rates = <0x3dfd2400>; + phandle = <0x02>; + }; + + cpu-boost@ff2b8000 { + compatible = "syscon"; + reg = <0x00 0xff2b8000 0x00 0x1000>; + rockchip,boost-low-con0 = <0x1032>; + rockchip,boost-low-con1 = <0x1441>; + rockchip,boost-high-con0 = <0x1036>; + rockchip,boost-high-con1 = <0x1441>; + rockchip,boost-backup-pll = <0x01>; + rockchip,boost-backup-pll-usage = <0x00>; + rockchip,boost-switch-threshold = <0x249f00>; + rockchip,boost-statis-threshold = <0x100>; + rockchip,boost-statis-enable = <0x00>; + rockchip,boost-enable = <0x00>; + phandle = <0x89>; + }; + + pmu-clock-controller@ff2bc000 { + compatible = "rockchip,px30-pmucru"; + reg = <0x00 0xff2bc000 0x00 0x1000>; + rockchip,grf = <0x2f>; + #clock-cells = <0x01>; + #reset-cells = <0x01>; + assigned-clocks = <0x2a 0x01 0x2a 0x08 0x2a 0x05 0x02 0x07 0x02 0xab 0x02 0xb0 0x02 0xf0 0x02 0xf5 0x02 0x140 0x02 0x49>; + assigned-clock-rates = <0x47868c00 0x5f5e100 0x18cba80 0x23c34600 0xbebc200 0xbebc200 0x8f0d180 0x8f0d180 0x5f5e100 0xbebc200>; + phandle = <0x2a>; + }; + + syscon@ff2c0000 { + compatible = "rockchip,px30-usb2phy-grf\0syscon\0simple-mfd"; + reg = <0x00 0xff2c0000 0x00 0x10000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0x100>; + + usb2-phy@100 { + compatible = "rockchip,px30-usb2phy\0rockchip,rk3328-usb2phy"; + reg = <0x100 0x10>; + clocks = <0x2a 0x0a>; + clock-names = "phyclk"; + #clock-cells = <0x00>; + assigned-clocks = <0x02 0x0e 0x02 0x55>; + assigned-clock-parents = <0x67 0x02 0x0e>; + clock-output-names = "usb480m_phy"; + status = "okay"; + phandle = <0x67>; + + host-port { + #phy-cells = <0x00>; + interrupts = <0x00 0x44 0x04>; + interrupt-names = "linestate"; + status = "okay"; + phandle = <0x8c>; + }; + + otg-port { + #phy-cells = <0x00>; + interrupts = <0x00 0x42 0x04 0x00 0x41 0x04 0x00 0x40 0x04>; + interrupt-names = "otg-bvalid\0otg-id\0linestate"; + status = "disabled"; + phandle = <0x8b>; + }; + }; + }; + + video-phy@ff2e0000 { + compatible = "rockchip,px30-video-phy"; + reg = <0x00 0xff2e0000 0x00 0x10000 0x00 0xff450000 0x00 0x10000>; + clocks = <0x2a 0x0b 0x02 0x145 0x02 0x144>; + clock-names = "ref\0pclk_phy\0pclk_host"; + #clock-cells = <0x00>; + resets = <0x02 0x3e>; + reset-names = "rst"; + power-domains = <0x8a 0x0c>; + #phy-cells = <0x00>; + status = "okay"; + phandle = <0x4c>; + }; + + mipi-dphy-rx0@ff2f0000 { + compatible = "rockchip,rk3326-mipi-dphy"; + reg = <0x00 0xff2f0000 0x00 0x4000>; + clocks = <0x02 0x146>; + clock-names = "dphy-ref"; + power-domains = <0x8a 0x0d>; + rockchip,grf = <0x2f>; + status = "okay"; + phandle = <0x101>; + }; + + usb@ff300000 { + compatible = "rockchip,px30-usb\0rockchip,rk3066-usb\0snps,dwc2"; + reg = <0x00 0xff300000 0x00 0x40000>; + interrupts = <0x00 0x3e 0x04>; + clocks = <0x02 0x102>; + clock-names = "otg"; + power-domains = <0x8a 0x05>; + dr_mode = "otg"; + g-np-tx-fifo-size = <0x10>; + g-rx-fifo-size = <0x118>; + g-tx-fifo-size = <0x100 0x80 0x80 0x40 0x20 0x10>; + g-use-dma; + phys = <0x8b>; + phy-names = "usb2-phy"; + status = "okay"; + phandle = <0x102>; + }; + + usb@ff340000 { + compatible = "generic-ehci"; + reg = <0x00 0xff340000 0x00 0x10000>; + interrupts = <0x00 0x3c 0x04>; + clocks = <0x02 0x103 0x67>; + clock-names = "usbhost\0utmi"; + power-domains = <0x8a 0x05>; + phys = <0x8c>; + phy-names = "usb"; + status = "disabled"; + phandle = <0x103>; + }; + + usb@ff350000 { + compatible = "generic-ohci"; + reg = <0x00 0xff350000 0x00 0x10000>; + interrupts = <0x00 0x3d 0x04>; + clocks = <0x02 0x103 0x67>; + clock-names = "usbhost\0utmi"; + power-domains = <0x8a 0x05>; + phys = <0x8c>; + phy-names = "usb"; + status = "disabled"; + phandle = <0x104>; + }; + + ethernet@ff360000 { + compatible = "rockchip,px30-gmac"; + reg = <0x00 0xff360000 0x00 0x10000>; + rockchip,grf = <0x2f>; + interrupts = <0x00 0x2b 0x04>; + interrupt-names = "macirq"; + clocks = <0x02 0x3e 0x02 0x3f 0x02 0x3f 0x02 0x40 0x02 0x41 0x02 0xb2 0x02 0x143 0x02 0x4c>; + clock-names = "stmmaceth\0mac_clk_rx\0mac_clk_tx\0clk_mac_ref\0clk_mac_refout\0aclk_mac\0pclk_mac\0clk_mac_speed"; + phy-mode = "rmii"; + pinctrl-names = "default"; + pinctrl-0 = <0x8d 0x8e>; + resets = <0x02 0x5e>; + reset-names = "stmmaceth"; + power-domains = <0x8a 0x09>; + status = "disabled"; + phandle = <0x105>; + }; + + dwmmc@ff370000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff370000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0xf7 0x02 0x3b 0x02 0x43 0x02 0x44>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x3b>; + assigned-clock-parents = <0x02 0x57>; + power-domains = <0x8a 0x07>; + fifo-depth = <0x100>; + interrupts = <0x00 0x36 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x8f 0x90 0x91 0x92>; + status = "okay"; + bus-width = <0x04>; + cap-mmc-highspeed; + cap-sd-highspeed; + supports-sd; + card-detect-delay = <0x320>; + ignore-pm-notify; + cd-gpios = <0x5c 0x03 0x01>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <0x4a>; + vmmc-supply = <0x93>; + phandle = <0x106>; + }; + + dwmmc@ff380000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff380000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0xff 0x02 0x38 0x02 0x45 0x02 0x46>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x38>; + assigned-clock-parents = <0x02 0x51>; + power-domains = <0x8a 0x0a>; + fifo-depth = <0x100>; + interrupts = <0x00 0x37 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x94 0x95 0x96>; + status = "okay"; + bus-width = <0x04>; + cap-mmc-highspeed; + cap-sd-highspeed; + supports-sd; + card-detect-delay = <0x320>; + ignore-pm-notify; + cd-gpios = <0x97 0x0e 0x01>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <0x4a>; + vmmc-supply = <0x93>; + phandle = <0x107>; + }; + + dwmmc@ff390000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff390000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0x100 0x02 0x39 0x02 0x47 0x02 0x48>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x39>; + assigned-clock-parents = <0x02 0x53>; + power-domains = <0x8a 0x0a>; + fifo-depth = <0x100>; + interrupts = <0x00 0x35 0x04>; + status = "disabled"; + phandle = <0x108>; + }; + + nandc@ff3b0000 { + compatible = "rockchip,rk-nandc"; + reg = <0x00 0xff3b0000 0x00 0x4000>; + interrupts = <0x00 0x39 0x04>; + nandc_id = <0x00>; + clocks = <0x02 0x37 0x02 0xfe>; + clock-names = "clk_nandc\0hclk_nandc"; + assigned-clocks = <0x02 0x37>; + assigned-clock-parents = <0x02 0x4f>; + power-domains = <0x8a 0x0a>; + status = "disabled"; + phandle = <0x109>; + }; + + sfc@ff3a0000 { + compatible = "rockchip,sfc"; + reg = <0x00 0xff3a0000 0x00 0x4000>; + interrupts = <0x00 0x38 0x04>; + clocks = <0x02 0x3a 0x02 0x101>; + clock-names = "clk_sfc\0hclk_sfc"; + assigned-clocks = <0x02 0x3a>; + assigned-clock-rates = <0x989680>; + status = "disabled"; + phandle = <0x10a>; + }; + + gpu@ff400000 { + compatible = "arm,malit602\0arm,malit60x\0arm,malit6xx\0arm,mali-midgard"; + reg = <0x00 0xff400000 0x00 0x4000>; + interrupts = <0x00 0x2d 0x04 0x00 0x2e 0x04 0x00 0x2f 0x04>; + interrupt-names = "GPU\0MMU\0JOB"; + clocks = <0x02 0x49>; + clock-names = "clk_mali"; + power-domains = <0x8a 0x0e>; + #cooling-cells = <0x02>; + operating-points-v2 = <0x98>; + status = "okay"; + mali-supply = <0x0e>; + phandle = <0x85>; + + power_model { + compatible = "arm,mali-simple-power-model"; + static-coefficient = <0x64578>; + dynamic-coefficient = <0x2dd>; + ts = <0x7d00 0x125c 0xffffffb0 0x02>; + thermal-zone = "gpu-thermal"; + }; + }; + + gpu-opp-table { + compatible = "operating-points-v2"; + rockchip,thermal-zone = "soc-thermal"; + rockchip,temp-hysteresis = <0x1388>; + rockchip,low-temp = <0x00>; + rockchip,low-temp-min-volt = <0xf4240>; + rockchip,low-temp-adjust-volt = <0x00 0x1e0 0xc350>; + rockchip,max-volt = <0x11edd8>; + rockchip,evb-irdrop = <0x61a8>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-ch = <0x00 0x00>; + phandle = <0x98>; + + opp-400000000 { + opp-hz = <0x00 0x17d78400>; + opp-microvolt = <0x100590>; + opp-microvolt-L0 = <0x100590>; + opp-microvolt-L1 = <0xfa3e8>; + opp-microvolt-L2 = <0xee098>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-480000000 { + opp-hz = <0x00 0x1c9c3800>; + opp-microvolt = <0x112a88>; + opp-microvolt-L0 = <0x112a88>; + opp-microvolt-L1 = <0x10c8e0>; + opp-microvolt-L2 = <0x100590>; + opp-microvolt-L3 = <0xf4240>; + }; + + opp-520000000 { + opp-hz = <0x00 0x1efe9200>; + opp-microvolt = <0x118c30>; + opp-microvolt-L0 = <0x118c30>; + opp-microvolt-L1 = <0x118c30>; + opp-microvolt-L2 = <0x10c8e0>; + opp-microvolt-L3 = <0x100590>; + }; + }; + + hevc_service@ff440000 { + compatible = "rockchip,hevc_sub"; + iommu_enabled = <0x01>; + reg = <0x00 0xff440000 0x00 0x400>; + interrupts = <0x00 0x31 0x04>; + interrupt-names = "irq_dec"; + dev_mode = <0x01>; + iommus = <0x99>; + allocator = <0x01>; + phandle = <0x9c>; + }; + + vpu_service@ff442000 { + compatible = "rockchip,vpu_sub"; + iommu_enabled = <0x01>; + reg = <0x00 0xff442000 0x00 0x800>; + interrupts = <0x00 0x50 0x04 0x00 0x4f 0x04>; + interrupt-names = "irq_enc\0irq_dec"; + dev_mode = <0x00>; + iommus = <0x9a>; + allocator = <0x01>; + phandle = <0x9b>; + }; + + vpu_combo { + compatible = "rockchip,vpu_combo"; + subcnt = <0x02>; + rockchip,grf = <0x2f>; + rockchip,sub = <0x9b 0x9c>; + clocks = <0x02 0xaf 0x02 0xf4 0x02 0x4b>; + clock-names = "aclk_vcodec\0hclk_vcodec\0clk_core"; + resets = <0x02 0x24 0x02 0x26 0x02 0x25 0x02 0x27 0x02 0x3f>; + reset-names = "video_a\0video_h\0niu_a\0niu_h\0video_core"; + power-domains = <0x8a 0x0b>; + mode_bit = <0x0f>; + mode_ctrl = <0x410>; + status = "okay"; + phandle = <0x10b>; + }; + + iommu@ff440440 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff440440 0x00 0x40 0x00 0xff440480 0x00 0x40>; + interrupts = <0x00 0x32 0x04>; + interrupt-names = "hevc_mmu"; + clocks = <0x02 0xaf 0x02 0xf4>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0b>; + #iommu-cells = <0x00>; + phandle = <0x99>; + }; + + iommu@ff442800 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff442800 0x00 0x100>; + interrupts = <0x00 0x51 0x04>; + interrupt-names = "vpu_mmu"; + clocks = <0x02 0xaf 0x02 0xf4>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0b>; + #iommu-cells = <0x00>; + phandle = <0x9a>; + }; + + dsi@ff450000 { + compatible = "rockchip,px30-mipi-dsi"; + reg = <0x00 0xff450000 0x00 0x10000>; + interrupts = <0x00 0x4b 0x04>; + clocks = <0x02 0x144 0x4c>; + clock-names = "pclk\0hs_clk"; + resets = <0x02 0x3d>; + reset-names = "apb"; + phys = <0x4c>; + phy-names = "mipi_dphy"; + power-domains = <0x8a 0x0c>; + rockchip,grf = <0x2f>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + phandle = <0x10c>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x13>; + status = "okay"; + phandle = <0xa3>; + }; + }; + }; + + panel@0 { + compatible = "elida,kd35t133\0simple-panel-dsi"; + reg = <0x00>; + backlight = <0x9d>; + backlight-supply = <0x9e>; + power-supply = <0x9f>; + reset-gpios = <0x97 0x10 0x01>; + reset-delay-ms = <0x96>; + init-delay-ms = <0x14>; + enable-delay-ms = <0x78>; + prepare-delay-ms = <0x14>; + unprepare-delay-ms = <0x14>; + disable-delay-ms = <0x32>; + width-mm = <0x34>; + height-mm = <0x46>; + dsi,flags = <0xa03>; + dsi,format = <0x00>; + dsi,lanes = <0x04>; + panel-init-sequence = [15 00 02 ff 30 15 00 02 ff 52 15 00 02 ff 01 15 00 02 e3 00 15 00 02 04 00 15 00 02 05 03 15 00 02 24 12 15 00 02 25 1e 15 00 02 26 6f 15 00 02 27 52 15 00 02 28 67 15 00 02 29 01 15 00 02 2a df 15 00 02 37 9c 15 00 02 38 a7 15 00 02 39 53 15 00 02 44 00 15 00 02 49 3c 15 00 02 59 fe 15 00 02 5c 00 15 00 02 80 20 15 00 02 91 77 15 00 02 92 77 15 00 02 a0 55 15 00 02 a1 50 15 00 02 a4 9c 15 00 02 a7 02 15 00 02 a8 01 15 00 02 a9 21 15 00 02 aa fc 15 00 02 ab 28 15 00 02 ac 06 15 00 02 ad 06 15 00 02 ae 06 15 00 02 af 03 15 00 02 b0 08 15 00 02 b1 26 15 00 02 b2 28 15 00 02 b3 28 15 00 02 b4 33 15 00 02 b5 08 15 00 02 b6 26 15 00 02 b7 08 15 00 02 b8 26 15 00 02 c0 00 15 00 02 c1 00 15 00 02 c2 00 15 00 02 ff 30 15 00 02 ff 52 15 00 02 ff 02 15 00 02 b0 0b 15 00 02 b1 16 15 00 02 b2 17 15 00 02 b3 2c 15 00 02 b4 32 15 00 02 b5 3b 15 00 02 b6 29 15 00 02 b7 40 15 00 02 b8 0d 15 00 02 b9 05 15 00 02 ba 12 15 00 02 bb 10 15 00 02 bc 12 15 00 02 bd 15 15 00 02 be 19 15 00 02 bf 0e 15 00 02 c0 16 15 00 02 c1 0a 15 00 02 d0 0c 15 00 02 d1 17 15 00 02 d2 14 15 00 02 d3 2e 15 00 02 d4 32 15 00 02 d5 3c 15 00 02 d6 22 15 00 02 d7 3d 15 00 02 d8 0d 15 00 02 d9 07 15 00 02 da 13 15 00 02 db 13 15 00 02 dc 11 15 00 02 dd 15 15 00 02 de 19 15 00 02 df 10 15 00 02 e0 17 15 00 02 e1 0a 15 00 02 ff 30 15 00 02 ff 52 15 00 02 ff 03 15 00 02 00 2a 15 00 02 01 2a 15 00 02 02 2a 15 00 02 03 2a 15 00 02 04 61 15 00 02 05 80 15 00 02 06 c7 15 00 02 07 01 15 00 02 08 82 15 00 02 09 83 15 00 02 30 2a 15 00 02 31 2a 15 00 02 32 2a 15 00 02 33 2a 15 00 02 34 a1 15 00 02 35 c5 15 00 02 36 80 15 00 02 37 23 15 00 02 40 82 15 00 02 41 83 15 00 02 42 80 15 00 02 43 81 15 00 02 44 55 15 00 02 45 e6 15 00 02 46 e5 15 00 02 47 55 15 00 02 48 e8 15 00 02 49 e7 15 00 02 50 02 15 00 02 51 01 15 00 02 52 04 15 00 02 53 03 15 00 02 54 55 15 00 02 55 ea 15 00 02 56 e9 15 00 02 57 55 15 00 02 58 ec 15 00 02 59 eb 15 00 02 7e 02 15 00 02 7f 80 15 00 02 e0 5a 15 00 02 b1 00 15 00 02 b4 0e 15 00 02 b5 0f 15 00 02 b6 04 15 00 02 b7 07 15 00 02 b8 06 15 00 02 b9 05 15 00 02 ba 0f 15 00 02 c7 00 15 00 02 ca 0e 15 00 02 cb 0f 15 00 02 cc 04 15 00 02 cd 07 15 00 02 ce 06 15 00 02 cf 05 15 00 02 d0 0f 15 00 02 81 0f 15 00 02 84 0e 15 00 02 85 0f 15 00 02 86 07 15 00 02 87 04 15 00 02 88 05 15 00 02 89 06 15 00 02 8a 00 15 00 02 97 0f 15 00 02 9a 0e 15 00 02 9b 0f 15 00 02 9c 07 15 00 02 9d 04 15 00 02 9e 05 15 00 02 9f 06 15 00 02 a0 00 15 00 02 ff 30 15 00 02 ff 52 15 00 02 ff 02 15 00 02 01 01 15 00 02 02 da 15 00 02 03 ba 15 00 02 04 a8 15 00 02 05 9a 15 00 02 06 70 15 00 02 07 ff 15 00 02 08 91 15 00 02 09 90 15 00 02 0a ff 15 00 02 0b 8f 15 00 02 0c 60 15 00 02 0d 58 15 00 02 0e 48 15 00 02 0f 38 15 00 02 10 2b 15 00 02 ff 30 15 00 02 ff 52 15 00 02 ff 00 15 00 02 36 02 15 00 02 3a 70 05 c8 01 11 05 14 01 29]; + panel-exit-sequence = <0x5140128 0x50a0110>; + + display-timings { + native-mode = <0xa0>; + + 60Hz { + clock-frequency = <0x1ba8140>; + hactive = <0x280>; + vactive = <0x1e0>; + hfront-porch = <0x2e>; + hsync-len = <0x02>; + hback-porch = <0x2c>; + vfront-porch = <0x10>; + vsync-len = <0x02>; + vback-porch = <0x0e>; + hsync-active = <0x00>; + vsync-active = <0x00>; + de-active = <0x00>; + pixelclk-active = <0x01>; + phandle = <0xa0>; + }; + + 50Hz { + clock-frequency = <0x1ba8140>; + hactive = <0x280>; + vactive = <0x1e0>; + hfront-porch = <0x2e>; + hsync-len = <0x02>; + hback-porch = <0x2c>; + vfront-porch = <0x10>; + vsync-len = <0x02>; + vback-porch = <0x0e>; + hsync-active = <0x00>; + vsync-active = <0x00>; + de-active = <0x00>; + pixelclk-active = <0x01>; + phandle = <0xa00>; + }; + + 75Hz { + clock-frequency = <0x1ba8140>; + hactive = <0x280>; + vactive = <0x1e0>; + hfront-porch = <0x2e>; + hsync-len = <0x02>; + hback-porch = <0x2c>; + vfront-porch = <0x10>; + vsync-len = <0x02>; + vback-porch = <0x0e>; + hsync-active = <0x00>; + vsync-active = <0x00>; + de-active = <0x00>; + pixelclk-active = <0x01>; + phandle = <0xa01>; + }; + }; + }; + }; + + vop@ff460000 { + compatible = "rockchip,px30-vop-big"; + reg = <0x00 0xff460000 0x00 0x1fc 0x00 0xff460a00 0x00 0x400>; + rockchip,grf = <0x2f>; + reg-names = "regs\0gamma_lut"; + interrupts = <0x00 0x4d 0x04>; + clocks = <0x02 0xb5 0x02 0x96 0x02 0xfb>; + clock-names = "aclk_vop\0dclk_vop\0hclk_vop"; + power-domains = <0x8a 0x0c>; + iommus = <0xa1>; + status = "okay"; + phandle = <0x10f>; + + port { + #address-cells = <0x01>; + #size-cells = <0x00>; + phandle = <0x10>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0xa2>; + phandle = <0x12>; + }; + + endpoint@1 { + reg = <0x01>; + remote-endpoint = <0xa3>; + phandle = <0x13>; + }; + + endpoint@2 { + reg = <0x02>; + remote-endpoint = <0xa4>; + phandle = <0x14>; + }; + }; + }; + + iommu@ff460f00 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff460f00 0x00 0x100>; + interrupts = <0x00 0x4d 0x04>; + interrupt-names = "vopb_mmu"; + clocks = <0x02 0xb5 0x02 0xfb>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0c>; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xa1>; + }; + + rk_rga@ff480000 { + compatible = "rockchip,rga2"; + reg = <0x00 0xff480000 0x00 0x1000>; + interrupts = <0x00 0x4c 0x04>; + clocks = <0x02 0xb7 0x02 0xfd 0x02 0x35>; + clock-names = "aclk_rga\0hclk_rga\0clk_rga"; + power-domains = <0x8a 0x0c>; + dma-coherent; + status = "okay"; + phandle = <0x110>; + }; + + cif@ff490000 { + compatible = "rockchip,cif"; + reg = <0x00 0xff490000 0x00 0x200>; + interrupts = <0x00 0x45 0x04>; + clocks = <0x02 0xb3 0x02 0xf9 0x02 0x160 0x02 0x34>; + clock-names = "aclk_cif0\0hclk_cif0\0pclk_cif\0cif0_out"; + resets = <0x02 0x2c 0x02 0x2d 0x02 0x2e>; + reset-names = "rst_cif_a\0rst_cif_h\0rst_cif_pclkin"; + power-domains = <0x8a 0x0d>; + pinctrl-names = "cif_pin_all"; + pinctrl-0 = <0xa5>; + iommus = <0xa6>; + status = "disabled"; + phandle = <0x111>; + }; + + cif-new@ff490000 { + compatible = "rockchip,px30-cif"; + reg = <0x00 0xff490000 0x00 0x200>; + interrupts = <0x00 0x45 0x04>; + clocks = <0x02 0xb3 0x02 0xf9 0x02 0x160 0x02 0x34>; + clock-names = "aclk_cif\0hclk_cif\0pclk_cif\0cif_out"; + resets = <0x02 0x2c 0x02 0x2d 0x02 0x2e>; + reset-names = "rst_cif_a\0rst_cif_h\0rst_cif_pclkin"; + power-domains = <0x8a 0x0d>; + iommus = <0xa6>; + status = "disabled"; + phandle = <0x112>; + }; + + iommu@ff490800 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff490800 0x00 0x100>; + interrupts = <0x00 0x45 0x04>; + interrupt-names = "vip_mmu"; + clocks = <0x02 0xb3 0x02 0xf9>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0d>; + rk_iommu,disable_reset_quirk; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xa6>; + }; + + rk_isp@ff4a0000 { + compatible = "rockchip,px30-isp\0rockchip,isp"; + reg = <0x00 0xff4a0000 0x00 0x8000>; + interrupts = <0x00 0x46 0x04>; + clocks = <0x02 0xb4 0x02 0xfa 0x02 0x33 0x02 0x33 0x02 0x15f 0x02 0x34 0x02 0x34 0x02 0x146>; + clock-names = "aclk_isp\0hclk_isp\0clk_isp\0clk_isp_jpe\0pclkin_isp\0clk_cif_pll\0clk_cif_out\0pclk_dphyrx"; + resets = <0x02 0x2b 0x02 0x2f>; + reset-names = "rst_isp\0rst_mipicsiphy"; + power-domains = <0x8a 0x0d>; + pinctrl-names = "default\0isp_dvp8bit2\0isp_dvp10bit\0isp_dvp12bit"; + pinctrl-0 = <0xa7>; + pinctrl-1 = <0xa5>; + pinctrl-2 = <0xa5 0xa8>; + pinctrl-3 = <0xa9 0xa5 0xa8>; + rockchip,isp,mipiphy = <0x01>; + rockchip,isp,csiphy,reg = <0xff2f0000 0x4000>; + rockchip,grf = <0x2f>; + rockchip,cru = <0x02>; + rockchip,isp,iommu-enable = <0x01>; + iommus = <0xaa>; + status = "disabled"; + phandle = <0x113>; + }; + + rkisp1@ff4a0000 { + compatible = "rockchip,rk3326-rkisp1"; + reg = <0x00 0xff4a0000 0x00 0x8000>; + interrupts = <0x00 0x46 0x04 0x00 0x49 0x04 0x00 0x4a 0x04>; + interrupt-names = "isp_irq\0mi_irq\0mipi_irq"; + clocks = <0x02 0xb4 0x02 0xfa 0x02 0x33 0x02 0x15f>; + clock-names = "aclk_isp\0hclk_isp\0clk_isp\0pclk_isp"; + devfreq = <0xab>; + power-domains = <0x8a 0x0d>; + iommus = <0xaa>; + rockchip,grf = <0x2f>; + status = "okay"; + phandle = <0x114>; + }; + + iommu@ff4a8000 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff4a8000 0x00 0x100>; + interrupts = <0x00 0x46 0x04>; + interrupt-names = "isp_mmu"; + clocks = <0x02 0xb4 0x02 0xfa>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0d>; + rk_iommu,disable_reset_quirk; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xaa>; + }; + + qos@ff518000 { + compatible = "syscon"; + reg = <0x00 0xff518000 0x00 0x20>; + phandle = <0x18>; + }; + + qos@ff520000 { + compatible = "syscon"; + reg = <0x00 0xff520000 0x00 0x20>; + phandle = <0x28>; + }; + + qos@ff52c000 { + compatible = "syscon"; + reg = <0x00 0xff52c000 0x00 0x20>; + phandle = <0x17>; + }; + + qos@ff538000 { + compatible = "syscon"; + reg = <0x00 0xff538000 0x00 0x20>; + phandle = <0x19>; + }; + + qos@ff538080 { + compatible = "syscon"; + reg = <0x00 0xff538080 0x00 0x20>; + phandle = <0x1a>; + }; + + qos@ff538100 { + compatible = "syscon"; + reg = <0x00 0xff538100 0x00 0x20>; + phandle = <0x1b>; + }; + + qos@ff538180 { + compatible = "syscon"; + reg = <0x00 0xff538180 0x00 0x20>; + phandle = <0x1c>; + }; + + qos@ff540000 { + compatible = "syscon"; + reg = <0x00 0xff540000 0x00 0x20>; + phandle = <0x15>; + }; + + qos@ff540080 { + compatible = "syscon"; + reg = <0x00 0xff540080 0x00 0x20>; + phandle = <0x16>; + }; + + qos@ff548000 { + compatible = "syscon"; + reg = <0x00 0xff548000 0x00 0x20>; + phandle = <0x23>; + }; + + qos@ff548080 { + compatible = "syscon"; + reg = <0x00 0xff548080 0x00 0x20>; + phandle = <0x24>; + }; + + qos@ff548100 { + compatible = "syscon"; + reg = <0x00 0xff548100 0x00 0x20>; + phandle = <0x25>; + }; + + qos@ff548180 { + compatible = "syscon"; + reg = <0x00 0xff548180 0x00 0x20>; + phandle = <0x26>; + }; + + qos@ff548200 { + compatible = "syscon"; + reg = <0x00 0xff548200 0x00 0x20>; + phandle = <0x27>; + }; + + qos@ff550000 { + compatible = "syscon"; + reg = <0x00 0xff550000 0x00 0x20>; + phandle = <0x1f>; + }; + + qos@ff550080 { + compatible = "syscon"; + reg = <0x00 0xff550080 0x00 0x20>; + phandle = <0x20>; + }; + + qos@ff550100 { + compatible = "syscon"; + reg = <0x00 0xff550100 0x00 0x20>; + phandle = <0x21>; + }; + + qos@ff550180 { + compatible = "syscon"; + reg = <0x00 0xff550180 0x00 0x20>; + phandle = <0x22>; + }; + + qos@ff558000 { + compatible = "syscon"; + reg = <0x00 0xff558000 0x00 0x20>; + phandle = <0x1d>; + }; + + qos@ff558080 { + compatible = "syscon"; + reg = <0x00 0xff558080 0x00 0x20>; + phandle = <0x1e>; + }; + + dfi@ff610000 { + reg = <0x00 0xff610000 0x00 0x400>; + compatible = "rockchip,px30-dfi"; + rockchip,pmugrf = <0xac>; + status = "okay"; + phandle = <0xad>; + }; + + dmc { + compatible = "rockchip,px30-dmc"; + interrupts = <0x00 0x69 0x04>; + interrupt-names = "complete_irq"; + devfreq-events = <0xad>; + clocks = <0x02 0x54>; + clock-names = "dmc_clk"; + operating-points-v2 = <0xae>; + ddr_timing = <0xaf>; + upthreshold = <0x28>; + downdifferential = <0x14>; + system-status-freq = <0x01 0x80e80 0x08 0x6ddd0 0x02 0x2f5d0 0x20 0x6ddd0 0x1000 0x80e80 0x4000 0xa2990 0x2000 0xa2990>; + auto-min-freq = <0x50140>; + auto-freq-en = <0x01>; + #cooling-cells = <0x02>; + status = "okay"; + center-supply = <0x0e>; + phandle = <0xab>; + + ddr_power_model { + compatible = "ddr_power_model"; + dynamic-power-coefficient = <0x78>; + static-power-coefficient = <0xc8>; + ts = <0x7d00 0x125c 0xffffffb0 0x02>; + thermal-zone = "soc-thermal"; + phandle = <0x115>; + }; + }; + + dmc-opp-table { + compatible = "operating-points-v2"; + rockchip,max-volt = <0x118c30>; + rockchip,evb-irdrop = <0x61a8>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-ch = <0x00 0x00>; + phandle = <0xae>; + + opp-528000000 { + opp-hz = <0x00 0x1f78a400>; + opp-microvolt = <0xee098>; + opp-microvolt-L0 = <0xee098>; + opp-microvolt-L1 = <0xee098>; + opp-microvolt-L2 = <0xe7ef0>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-666000000 { + opp-hz = <0x00 0x27b25a80>; + opp-microvolt = <0x100590>; + opp-microvolt-L0 = <0x100590>; + opp-microvolt-L1 = <0xf4240>; + opp-microvolt-L2 = <0xee098>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-786000000 { + opp-hz = <0x00 0x2ed96880>; + opp-microvolt = <0x10c8e0>; + opp-microvolt-L0 = <0x10c8e0>; + opp-microvolt-L1 = <0x100590>; + opp-microvolt-L2 = <0xfa3e8>; + opp-microvolt-L3 = <0xf4240>; + status = "okay"; + }; + }; + + rockchip-system-monitor { + compatible = "rockchip,system-monitor"; + rockchip,thermal-zone = "soc-thermal"; + rockchip,polling-delay = <0xc8>; + phandle = <0x116>; + }; + + pinctrl { + compatible = "rockchip,px30-pinctrl"; + rockchip,grf = <0x2f>; + rockchip,pmu = <0xac>; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + phandle = <0x117>; + + gpio0@ff040000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff040000 0x00 0x100>; + interrupts = <0x00 0x03 0x04>; + clocks = <0x2a 0x14>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x5c>; + }; + + gpio1@ff250000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff250000 0x00 0x100>; + interrupts = <0x00 0x04 0x04>; + clocks = <0x02 0x15c>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0xbf>; + }; + + gpio2@ff260000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff260000 0x00 0x100>; + interrupts = <0x00 0x05 0x04>; + clocks = <0x02 0x15d>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x66>; + }; + + gpio3@ff270000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff270000 0x00 0x100>; + interrupts = <0x00 0x06 0x04>; + clocks = <0x02 0x15e>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x97>; + }; + + pcfg-pull-up { + bias-pull-up; + phandle = <0xb2>; + }; + + pcfg-pull-down { + bias-pull-down; + phandle = <0x118>; + }; + + pcfg-pull-none { + bias-disable; + phandle = <0xb1>; + }; + + pcfg-pull-none-2ma { + bias-disable; + drive-strength = <0x02>; + phandle = <0x119>; + }; + + pcfg-pull-up-2ma { + bias-pull-up; + drive-strength = <0x02>; + phandle = <0x11a>; + }; + + pcfg-pull-up-4ma { + bias-pull-up; + drive-strength = <0x04>; + phandle = <0xb3>; + }; + + pcfg-pull-none-4ma { + bias-disable; + drive-strength = <0x04>; + phandle = <0x11b>; + }; + + pcfg-pull-down-4ma { + bias-pull-down; + drive-strength = <0x04>; + phandle = <0x11c>; + }; + + pcfg-pull-none-8ma { + bias-disable; + drive-strength = <0x08>; + phandle = <0xb6>; + }; + + pcfg-pull-up-8ma { + bias-pull-up; + drive-strength = <0x08>; + phandle = <0xb4>; + }; + + pcfg-pull-none-12ma { + bias-disable; + drive-strength = <0x0c>; + phandle = <0xb8>; + }; + + pcfg-pull-up-12ma { + bias-pull-up; + drive-strength = <0x0c>; + phandle = <0xb7>; + }; + + pcfg-pull-none-smt { + bias-disable; + input-schmitt-enable; + phandle = <0xb0>; + }; + + pcfg-output-high { + output-high; + phandle = <0x11d>; + }; + + pcfg-output-low { + output-low; + phandle = <0xb9>; + }; + + pcfg-input-high { + bias-pull-up; + input-enable; + phandle = <0xb5>; + }; + + pcfg-input { + input-enable; + phandle = <0x11e>; + }; + + i2c0 { + + i2c0-xfer { + rockchip,pins = <0x00 0x08 0x01 0xb0 0x00 0x09 0x01 0xb0>; + phandle = <0x5b>; + }; + }; + + i2c1 { + + i2c1-xfer { + rockchip,pins = <0x00 0x12 0x01 0xb0 0x00 0x13 0x01 0xb0>; + phandle = <0x69>; + }; + }; + + i2c2 { + + i2c2-xfer { + rockchip,pins = <0x02 0x0f 0x02 0xb0 0x02 0x10 0x02 0xb0>; + phandle = <0x6a>; + }; + }; + + i2c3 { + + i2c3-xfer { + rockchip,pins = <0x01 0x0c 0x04 0xb0 0x01 0x0d 0x04 0xb0>; + phandle = <0x6b>; + }; + }; + + tsadc { + + tsadc-otp-gpio { + rockchip,pins = <0x00 0x06 0x00 0xb1>; + phandle = <0x86>; + }; + + tsadc-otp-out { + rockchip,pins = <0x00 0x06 0x01 0xb1>; + phandle = <0x87>; + }; + }; + + uart0 { + + uart0-xfer { + rockchip,pins = <0x00 0x0a 0x01 0xb2 0x00 0x0b 0x01 0xb2>; + phandle = <0x2c>; + }; + + uart0-cts { + rockchip,pins = <0x00 0x0c 0x01 0xb1>; + phandle = <0x2d>; + }; + + uart0-rts { + rockchip,pins = <0x00 0x0d 0x01 0xb1>; + phandle = <0x2e>; + }; + + uart0-rts-gpio { + rockchip,pins = <0x00 0x0d 0x00 0xb1>; + phandle = <0x11f>; + }; + }; + + uart1 { + + uart1-xfer { + rockchip,pins = <0x01 0x11 0x01 0xb2 0x01 0x10 0x01 0xb2>; + phandle = <0x4f>; + }; + + uart1-cts { + rockchip,pins = <0x01 0x12 0x01 0xb1>; + phandle = <0x50>; + }; + + uart1-rts { + rockchip,pins = <0x01 0x13 0x01 0xb1>; + phandle = <0x120>; + }; + + uart1-rts-gpio { + rockchip,pins = <0x01 0x13 0x00 0xb1>; + phandle = <0x121>; + }; + }; + + uart2-m0 { + + uart2m0-xfer { + rockchip,pins = <0x01 0x1a 0x02 0xb2 0x01 0x1b 0x02 0xb2>; + phandle = <0x51>; + }; + }; + + uart2-m1 { + + uart2m1-xfer { + rockchip,pins = <0x02 0x0c 0x02 0xb2 0x02 0x0e 0x02 0xb2>; + phandle = <0xba>; + }; + }; + + uart3-m0 { + + uart3m0-xfer { + rockchip,pins = <0x00 0x10 0x02 0xb2 0x00 0x11 0x02 0xb2>; + phandle = <0x122>; + }; + + uart3m0-cts { + rockchip,pins = <0x00 0x12 0x02 0xb1>; + phandle = <0x123>; + }; + + uart3m0-rts { + rockchip,pins = <0x00 0x13 0x02 0xb1>; + phandle = <0x124>; + }; + + uart3m0-rts-gpio { + rockchip,pins = <0x00 0x13 0x00 0xb1>; + phandle = <0x125>; + }; + }; + + uart3-m1 { + + uart3m1-xfer { + rockchip,pins = <0x01 0x0e 0x02 0xb2 0x01 0x0f 0x02 0xb2>; + phandle = <0x52>; + }; + + uart3m1-cts { + rockchip,pins = <0x01 0x0c 0x02 0xb1>; + phandle = <0x53>; + }; + + uart3m1-rts { + rockchip,pins = <0x01 0x0d 0x02 0xb1>; + phandle = <0x54>; + }; + + uart3m1-rts-gpio { + rockchip,pins = <0x01 0x0d 0x00 0xb1>; + phandle = <0x126>; + }; + }; + + uart4 { + + uart4-xfer { + rockchip,pins = <0x01 0x1c 0x02 0xb2 0x01 0x1d 0x02 0xb2>; + phandle = <0x55>; + }; + + uart4-cts { + rockchip,pins = <0x01 0x1e 0x02 0xb1>; + phandle = <0x56>; + }; + + uart4-rts { + rockchip,pins = <0x01 0x1f 0x02 0xb1>; + phandle = <0x57>; + }; + }; + + uart5 { + + uart5-xfer { + rockchip,pins = <0x03 0x02 0x04 0xb2 0x03 0x01 0x04 0xb2>; + phandle = <0x58>; + }; + + uart5-cts { + rockchip,pins = <0x03 0x03 0x04 0xb1>; + phandle = <0x59>; + }; + + uart5-rts { + rockchip,pins = <0x03 0x05 0x04 0xb1>; + phandle = <0x5a>; + }; + }; + + spi0 { + + spi0-clk { + rockchip,pins = <0x01 0x0f 0x03 0xb3>; + phandle = <0x6c>; + }; + + spi0-csn { + rockchip,pins = <0x01 0x0e 0x03 0xb3>; + phandle = <0x6d>; + }; + + spi0-miso { + rockchip,pins = <0x01 0x0d 0x03 0xb3>; + phandle = <0x6e>; + }; + + spi0-mosi { + rockchip,pins = <0x01 0x0c 0x03 0xb3>; + phandle = <0x6f>; + }; + + spi0-clk-hs { + rockchip,pins = <0x01 0x0f 0x03 0xb4>; + phandle = <0x70>; + }; + + spi0-miso-hs { + rockchip,pins = <0x01 0x0d 0x03 0xb4>; + phandle = <0x71>; + }; + + spi0-mosi-hs { + rockchip,pins = <0x01 0x0c 0x03 0xb4>; + phandle = <0x72>; + }; + }; + + spi1 { + + spi1-clk { + rockchip,pins = <0x03 0x0f 0x04 0xb3>; + phandle = <0x73>; + }; + + spi1-csn0 { + rockchip,pins = <0x03 0x09 0x04 0xb3>; + phandle = <0x74>; + }; + + spi1-csn1 { + rockchip,pins = <0x03 0x0a 0x02 0xb3>; + phandle = <0x75>; + }; + + spi1-miso { + rockchip,pins = <0x03 0x0e 0x04 0xb3>; + phandle = <0x76>; + }; + + spi1-mosi { + rockchip,pins = <0x03 0x0c 0x04 0xb3>; + phandle = <0x77>; + }; + + spi1-clk-hs { + rockchip,pins = <0x03 0x0f 0x04 0xb4>; + phandle = <0x78>; + }; + + spi1-miso-hs { + rockchip,pins = <0x03 0x0e 0x04 0xb4>; + phandle = <0x79>; + }; + + spi1-mosi-hs { + rockchip,pins = <0x03 0x0c 0x04 0xb4>; + phandle = <0x7a>; + }; + }; + + pdm { + + pdm-clk0m0 { + rockchip,pins = <0x03 0x16 0x02 0xb1>; + phandle = <0x44>; + }; + + pdm-clk0m1 { + rockchip,pins = <0x02 0x16 0x01 0xb1>; + phandle = <0x127>; + }; + + pdm-clk1 { + rockchip,pins = <0x03 0x17 0x02 0xb1>; + phandle = <0x45>; + }; + + pdm-sdi0m0 { + rockchip,pins = <0x03 0x1b 0x02 0xb1>; + phandle = <0x46>; + }; + + pdm-sdi0m1 { + rockchip,pins = <0x02 0x15 0x02 0xb1>; + phandle = <0x128>; + }; + + pdm-sdi1 { + rockchip,pins = <0x03 0x18 0x02 0xb1>; + phandle = <0x47>; + }; + + pdm-sdi2 { + rockchip,pins = <0x03 0x19 0x02 0xb1>; + phandle = <0x48>; + }; + + pdm-sdi3 { + rockchip,pins = <0x03 0x1a 0x02 0xb1>; + phandle = <0x49>; + }; + + pdm-clk0m0-sleep { + rockchip,pins = <0x03 0x16 0x00 0xb5>; + phandle = <0x129>; + }; + + pdm-clk0m1-sleep { + rockchip,pins = <0x02 0x16 0x00 0xb5>; + phandle = <0x12a>; + }; + + pdm-clk1-sleep { + rockchip,pins = <0x03 0x17 0x00 0xb5>; + phandle = <0x12b>; + }; + + pdm-sdi0m0-sleep { + rockchip,pins = <0x03 0x1b 0x00 0xb5>; + phandle = <0x12c>; + }; + + pdm-sdi0m1-sleep { + rockchip,pins = <0x02 0x15 0x00 0xb5>; + phandle = <0x12d>; + }; + + pdm-sdi1-sleep { + rockchip,pins = <0x03 0x18 0x00 0xb5>; + phandle = <0x12e>; + }; + + pdm-sdi2-sleep { + rockchip,pins = <0x03 0x19 0x00 0xb5>; + phandle = <0x12f>; + }; + + pdm-sdi3-sleep { + rockchip,pins = <0x03 0x1a 0x00 0xb5>; + phandle = <0x130>; + }; + }; + + i2s0 { + + i2s0-8ch-mclk { + rockchip,pins = <0x03 0x11 0x02 0xb1>; + phandle = <0x131>; + }; + + i2s0-8ch-sclktx { + rockchip,pins = <0x03 0x13 0x02 0xb1>; + phandle = <0x30>; + }; + + i2s0-8ch-sclkrx { + rockchip,pins = <0x03 0x0c 0x02 0xb1>; + phandle = <0x31>; + }; + + i2s0-8ch-lrcktx { + rockchip,pins = <0x03 0x12 0x02 0xb1>; + phandle = <0x32>; + }; + + i2s0-8ch-lrckrx { + rockchip,pins = <0x03 0x0d 0x02 0xb1>; + phandle = <0x33>; + }; + + i2s0-8ch-sdo0 { + rockchip,pins = <0x03 0x14 0x02 0xb1>; + phandle = <0x38>; + }; + + i2s0-8ch-sdo1 { + rockchip,pins = <0x03 0x10 0x02 0xb1>; + phandle = <0x39>; + }; + + i2s0-8ch-sdo2 { + rockchip,pins = <0x03 0x0f 0x02 0xb1>; + phandle = <0x3a>; + }; + + i2s0-8ch-sdo3 { + rockchip,pins = <0x03 0x0e 0x02 0xb1>; + phandle = <0x3b>; + }; + + i2s0-8ch-sdi0 { + rockchip,pins = <0x03 0x15 0x02 0xb1>; + phandle = <0x34>; + }; + + i2s0-8ch-sdi1 { + rockchip,pins = <0x03 0x0b 0x02 0xb1>; + phandle = <0x35>; + }; + + i2s0-8ch-sdi2 { + rockchip,pins = <0x03 0x09 0x02 0xb1>; + phandle = <0x36>; + }; + + i2s0-8ch-sdi3 { + rockchip,pins = <0x03 0x08 0x02 0xb1>; + phandle = <0x37>; + }; + }; + + i2s1 { + + i2s1-2ch-mclk { + rockchip,pins = <0x02 0x13 0x01 0xb1>; + phandle = <0x68>; + }; + + i2s1-2ch-sclk { + rockchip,pins = <0x02 0x12 0x01 0xb1>; + phandle = <0x3c>; + }; + + i2s1-2ch-lrck { + rockchip,pins = <0x02 0x11 0x01 0xb1>; + phandle = <0x3d>; + }; + + i2s1-2ch-sdi { + rockchip,pins = <0x02 0x15 0x01 0xb1>; + phandle = <0x3e>; + }; + + i2s1-2ch-sdo { + rockchip,pins = <0x02 0x14 0x01 0xb1>; + phandle = <0x3f>; + }; + }; + + i2s2 { + + i2s2-2ch-mclk { + rockchip,pins = <0x03 0x01 0x02 0xb1>; + phandle = <0x132>; + }; + + i2s2-2ch-sclk { + rockchip,pins = <0x03 0x02 0x02 0xb1>; + phandle = <0x40>; + }; + + i2s2-2ch-lrck { + rockchip,pins = <0x03 0x03 0x02 0xb1>; + phandle = <0x41>; + }; + + i2s2-2ch-sdi { + rockchip,pins = <0x03 0x05 0x02 0xb1>; + phandle = <0x42>; + }; + + i2s2-2ch-sdo { + rockchip,pins = <0x03 0x07 0x02 0xb1>; + phandle = <0x43>; + }; + }; + + sdmmc { + + sdmmc-clk { + rockchip,pins = <0x01 0x1e 0x01 0xb6>; + phandle = <0x8f>; + }; + + sdmmc-cmd { + rockchip,pins = <0x01 0x1f 0x01 0xb4>; + phandle = <0x90>; + }; + + sdmmc-det { + rockchip,pins = <0x00 0x03 0x01 0xb4>; + phandle = <0x91>; + }; + + sdmmc-bus1 { + rockchip,pins = <0x01 0x1a 0x01 0xb4>; + phandle = <0x133>; + }; + + sdmmc-bus4 { + rockchip,pins = <0x01 0x1a 0x01 0xb4 0x01 0x1b 0x01 0xb4 0x01 0x1c 0x01 0xb4 0x01 0x1d 0x01 0xb4>; + phandle = <0x92>; + }; + + sdmmc-gpio { + rockchip,pins = <0x01 0x1a 0x00 0xb3 0x01 0x1b 0x00 0xb3 0x01 0x1c 0x00 0xb3 0x01 0x1d 0x00 0xb3 0x01 0x1e 0x00 0xb3 0x01 0x1f 0x00 0xb3>; + phandle = <0x134>; + }; + }; + + sdio { + + sdio-clk { + rockchip,pins = <0x01 0x15 0x01 0xb1>; + phandle = <0x96>; + }; + + sdio-cmd { + rockchip,pins = <0x01 0x14 0x01 0xb2>; + phandle = <0x95>; + }; + + sdio-bus4 { + rockchip,pins = <0x01 0x16 0x01 0xb2 0x01 0x17 0x01 0xb2 0x01 0x18 0x01 0xb2 0x01 0x19 0x01 0xb2>; + phandle = <0x94>; + }; + + sdio-gpio { + rockchip,pins = <0x01 0x16 0x00 0xb2 0x01 0x17 0x00 0xb2 0x01 0x18 0x00 0xb2 0x01 0x19 0x00 0xb2 0x01 0x14 0x00 0xb2 0x01 0x15 0x00 0xb2>; + phandle = <0x135>; + }; + }; + + emmc { + + emmc-clk { + rockchip,pins = <0x01 0x09 0x02 0xb6>; + phandle = <0x136>; + }; + + emmc-cmd { + rockchip,pins = <0x01 0x0a 0x02 0xb4>; + phandle = <0x137>; + }; + + emmc-pwren { + rockchip,pins = <0x01 0x08 0x02 0xb1>; + phandle = <0x138>; + }; + + emmc-rstnout { + rockchip,pins = <0x01 0x0b 0x02 0xb1>; + phandle = <0x139>; + }; + + emmc-bus1 { + rockchip,pins = <0x01 0x00 0x02 0xb4>; + phandle = <0x13a>; + }; + + emmc-bus4 { + rockchip,pins = <0x01 0x00 0x02 0xb4 0x01 0x01 0x02 0xb4 0x01 0x02 0x02 0xb4 0x01 0x03 0x02 0xb4>; + phandle = <0x13b>; + }; + + emmc-bus8 { + rockchip,pins = <0x01 0x00 0x02 0xb4 0x01 0x01 0x02 0xb4 0x01 0x02 0x02 0xb4 0x01 0x03 0x02 0xb4 0x01 0x04 0x02 0xb4 0x01 0x05 0x02 0xb4 0x01 0x06 0x02 0xb4 0x01 0x07 0x02 0xb4>; + phandle = <0x13c>; + }; + }; + + flash { + + flash-cs0 { + rockchip,pins = <0x01 0x08 0x01 0xb1>; + phandle = <0x13d>; + }; + + flash-rdy { + rockchip,pins = <0x01 0x09 0x01 0xb1>; + phandle = <0x13e>; + }; + + flash-dqs { + rockchip,pins = <0x01 0x0a 0x01 0xb1>; + phandle = <0x13f>; + }; + + flash-ale { + rockchip,pins = <0x01 0x0b 0x01 0xb1>; + phandle = <0x140>; + }; + + flash-cle { + rockchip,pins = <0x01 0x0c 0x01 0xb1>; + phandle = <0x141>; + }; + + flash-wrn { + rockchip,pins = <0x01 0x0d 0x01 0xb1>; + phandle = <0x142>; + }; + + flash-csl { + rockchip,pins = <0x01 0x0e 0x01 0xb1>; + phandle = <0x143>; + }; + + flash-rdn { + rockchip,pins = <0x01 0x0f 0x01 0xb1>; + phandle = <0x144>; + }; + + flash-bus8 { + rockchip,pins = <0x01 0x00 0x01 0xb7 0x01 0x01 0x01 0xb7 0x01 0x02 0x01 0xb7 0x01 0x03 0x01 0xb7 0x01 0x04 0x01 0xb7 0x01 0x05 0x01 0xb7 0x01 0x06 0x01 0xb7 0x01 0x07 0x01 0xb7>; + phandle = <0x145>; + }; + }; + + lcdc { + + lcdc-m0-rgb-pins { + rockchip,pins = <0x03 0x00 0x01 0xb6 0x03 0x01 0x01 0xb6 0x03 0x02 0x01 0xb6 0x03 0x03 0x01 0xb6 0x03 0x04 0x01 0xb6 0x03 0x05 0x01 0xb6 0x03 0x06 0x01 0xb6 0x03 0x07 0x01 0xb6 0x03 0x08 0x01 0xb6 0x03 0x09 0x01 0xb6 0x03 0x0a 0x01 0xb6 0x03 0x0b 0x01 0xb6 0x03 0x0c 0x01 0xb6 0x03 0x0d 0x01 0xb6 0x03 0x0e 0x01 0xb6 0x03 0x0f 0x01 0xb6 0x03 0x10 0x01 0xb6 0x03 0x11 0x01 0xb6 0x03 0x12 0x01 0xb6 0x03 0x13 0x01 0xb6 0x03 0x14 0x01 0xb6 0x03 0x15 0x01 0xb6 0x03 0x16 0x01 0xb6 0x03 0x17 0x01 0xb6 0x03 0x18 0x01 0xb6 0x03 0x19 0x01 0xb6 0x03 0x1a 0x01 0xb6 0x03 0x1b 0x01 0xb6>; + phandle = <0x146>; + }; + + lcdc-m0-sleep-pins { + rockchip,pins = <0x03 0x00 0x00 0xb1 0x03 0x01 0x00 0xb1 0x03 0x02 0x00 0xb1 0x03 0x03 0x00 0xb1 0x03 0x04 0x00 0xb1 0x03 0x05 0x00 0xb1 0x03 0x06 0x00 0xb1 0x03 0x07 0x00 0xb1 0x03 0x08 0x00 0xb1 0x03 0x09 0x00 0xb1 0x03 0x0a 0x00 0xb1 0x03 0x0b 0x00 0xb1 0x03 0x0c 0x00 0xb1 0x03 0x0d 0x00 0xb1 0x03 0x0e 0x00 0xb1 0x03 0x0f 0x00 0xb1 0x03 0x10 0x00 0xb1 0x03 0x11 0x00 0xb1 0x03 0x12 0x00 0xb1 0x03 0x13 0x00 0xb1 0x03 0x14 0x00 0xb1 0x03 0x15 0x00 0xb1 0x03 0x16 0x00 0xb1 0x03 0x17 0x00 0xb1 0x03 0x18 0x00 0xb1 0x03 0x19 0x00 0xb1 0x03 0x1a 0x00 0xb1 0x03 0x1b 0x00 0xb1>; + phandle = <0x147>; + }; + + lcdc-m1-rgb-pins { + rockchip,pins = <0x03 0x00 0x01 0xb6 0x03 0x04 0x01 0xb6 0x03 0x06 0x01 0xb6 0x03 0x0a 0x01 0xb6 0x03 0x0b 0x01 0xb6 0x03 0x0d 0x01 0xb6 0x03 0x10 0x01 0xb6 0x03 0x11 0x01 0xb6 0x03 0x12 0x01 0xb6 0x03 0x13 0x01 0xb6 0x03 0x14 0x01 0xb6 0x03 0x15 0x01 0xb6 0x03 0x16 0x01 0xb6 0x03 0x17 0x01 0xb6 0x03 0x18 0x01 0xb6 0x03 0x19 0x01 0xb6 0x03 0x1a 0x01 0xb6 0x03 0x1b 0x01 0xb6>; + phandle = <0x4d>; + }; + + lcdc-m1-sleep-pins { + rockchip,pins = <0x03 0x00 0x00 0xb1 0x03 0x04 0x00 0xb1 0x03 0x06 0x00 0xb1 0x03 0x0a 0x00 0xb1 0x03 0x0b 0x00 0xb1 0x03 0x0d 0x00 0xb1 0x03 0x10 0x00 0xb1 0x03 0x11 0x00 0xb1 0x03 0x12 0x00 0xb1 0x03 0x13 0x00 0xb1 0x03 0x14 0x00 0xb1 0x03 0x15 0x00 0xb1 0x03 0x16 0x00 0xb1 0x03 0x17 0x00 0xb1 0x03 0x18 0x00 0xb1 0x03 0x19 0x00 0xb1 0x03 0x1a 0x00 0xb1 0x03 0x1b 0x00 0xb1>; + phandle = <0x4e>; + }; + }; + + pwm0 { + + pwm0-pin { + rockchip,pins = <0x00 0x0f 0x01 0xb1>; + phandle = <0x7b>; + }; + }; + + pwm1 { + + pwm1-pin { + rockchip,pins = <0x00 0x10 0x01 0xb1>; + phandle = <0x7c>; + }; + }; + + pwm2 { + + pwm2-pin { + rockchip,pins = <0x02 0x0d 0x01 0xb1>; + phandle = <0x7d>; + }; + }; + + pwm3 { + + pwm3-pin { + rockchip,pins = <0x00 0x11 0x01 0xb1>; + phandle = <0x7e>; + }; + }; + + pwm4 { + + pwm4-pin { + rockchip,pins = <0x03 0x12 0x03 0xb1>; + phandle = <0x7f>; + }; + }; + + pwm5 { + + pwm5-pin { + rockchip,pins = <0x03 0x13 0x03 0xb1>; + phandle = <0x80>; + }; + }; + + pwm6 { + + pwm6-pin { + rockchip,pins = <0x03 0x14 0x03 0xb1>; + phandle = <0x81>; + }; + }; + + pwm7 { + + pwm7-pin { + rockchip,pins = <0x03 0x15 0x03 0xb1>; + phandle = <0x82>; + }; + }; + + gmac { + + rmii-pins { + rockchip,pins = <0x02 0x00 0x02 0xb8 0x02 0x01 0x02 0xb8 0x02 0x02 0x02 0xb8 0x02 0x03 0x02 0xb1 0x02 0x04 0x02 0xb1 0x02 0x05 0x02 0xb1 0x02 0x06 0x02 0xb1 0x02 0x07 0x02 0xb1 0x02 0x09 0x02 0xb1>; + phandle = <0x8d>; + }; + + mac-refclk-12ma { + rockchip,pins = <0x02 0x0a 0x02 0xb8>; + phandle = <0x8e>; + }; + + mac-refclk { + rockchip,pins = <0x02 0x0a 0x02 0xb1>; + phandle = <0x148>; + }; + }; + + cif-m0 { + + cif-clkout-m0 { + rockchip,pins = <0x02 0x0b 0x01 0xb8>; + phandle = <0xa7>; + }; + + dvp-d2d9-m0 { + rockchip,pins = <0x02 0x00 0x01 0xb1 0x02 0x01 0x01 0xb1 0x02 0x02 0x01 0xb1 0x02 0x03 0x01 0xb1 0x02 0x04 0x01 0xb1 0x02 0x05 0x01 0xb1 0x02 0x06 0x01 0xb1 0x02 0x07 0x01 0xb1 0x02 0x08 0x01 0xb1 0x02 0x09 0x01 0xb1 0x02 0x0a 0x01 0xb1 0x02 0x0b 0x01 0xb1>; + phandle = <0xa5>; + }; + + dvp-d0d1-m0 { + rockchip,pins = <0x02 0x0c 0x01 0xb1 0x02 0x0e 0x01 0xb1>; + phandle = <0xa9>; + }; + + d10-d11-m0 { + rockchip,pins = <0x02 0x0f 0x01 0xb1 0x02 0x10 0x01 0xb1>; + phandle = <0xa8>; + }; + }; + + cif-m1 { + + cif-clkout-m1 { + rockchip,pins = <0x03 0x18 0x03 0xb1>; + phandle = <0x149>; + }; + + dvp-d2d9-m1 { + rockchip,pins = <0x03 0x03 0x03 0xb1 0x03 0x05 0x03 0xb1 0x03 0x07 0x03 0xb1 0x03 0x08 0x03 0xb1 0x03 0x09 0x03 0xb1 0x03 0x0c 0x03 0xb1 0x03 0x0e 0x03 0xb1 0x03 0x0f 0x03 0xb1 0x03 0x19 0x03 0xb1 0x03 0x1a 0x03 0xb1 0x03 0x1b 0x03 0xb1 0x03 0x18 0x03 0xb1>; + phandle = <0x14a>; + }; + + dvp-d0d1-m1 { + rockchip,pins = <0x03 0x01 0x03 0xb1 0x03 0x02 0x03 0xb1>; + phandle = <0x14b>; + }; + + d10-d11-m1 { + rockchip,pins = <0x03 0x16 0x03 0xb1 0x03 0x17 0x03 0xb1>; + phandle = <0x14c>; + }; + }; + + isp { + + isp-prelight { + rockchip,pins = <0x03 0x19 0x04 0xb1>; + phandle = <0x14d>; + }; + }; + + pmic { + + pmic_int { + rockchip,pins = <0x00 0x0a 0x00 0xb2 0x00 0x0b 0x00 0xb1>; + phandle = <0x5d>; + }; + + soc_slppin_gpio { + rockchip,pins = <0x00 0x04 0x00 0xb9>; + phandle = <0x60>; + }; + + soc_slppin_slp { + rockchip,pins = <0x00 0x04 0x01 0xb1>; + phandle = <0x5e>; + }; + + soc_slppin_rst { + rockchip,pins = <0x00 0x04 0x02 0xb1>; + phandle = <0x62>; + }; + }; + + leds { + + led-pins { + rockchip,pins = <0x00 0x11 0x00 0xb1>; + phandle = <0xc0>; + }; + }; + + btns { + + btn-pins { + rockchip,pins = <0x01 0x0c 0x00 0xb2 0x01 0x0d 0x00 0xb2 0x01 0x0e 0x00 0xb2 0x01 0x0f 0x00 0xb2 0x01 0x02 0x00 0xb2 0x01 0x05 0x00 0xb2 0x01 0x06 0x00 0xb2 0x01 0x07 0x00 0xb2 0x02 0x00 0x00 0xb2 0x02 0x01 0x00 0xb2 0x02 0x02 0x00 0xb2 0x02 0x03 0x00 0xb2 0x02 0x04 0x00 0xb2 0x02 0x05 0x00 0xb2 0x02 0x06 0x00 0xb2 0x02 0x07 0x00 0xb2 0x03 0x09 0x00 0xb2 0x03 0x0a 0x00 0xb2 0x03 0x0c 0x00 0xb2 0x03 0x0f 0x00 0xb2>; + phandle = <0xbd>; + }; + }; + }; + + chosen { + bootargs = [00]; + }; + + fiq-debugger { + compatible = "rockchip,fiq-debugger"; + rockchip,serial-id = <0x02>; + rockchip,wake-irq = <0x00>; + rockchip,irq-mode-enable = <0x00>; + rockchip,baudrate = <0x1c200>; + interrupts = <0x00 0x7f 0x08>; + pinctrl-names = "default"; + pinctrl-0 = <0xba>; + status = "okay"; + }; + + ramoops { + compatible = "ramoops"; + record-size = <0x00 0x20000>; + console-size = <0x00 0x80000>; + ftrace-size = <0x00 0x00>; + pmsg-size = <0x00 0x00>; + memory-region = <0xbb>; + }; + + reserved-memory { + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + + drm-logo@00000000 { + compatible = "rockchip,drm-logo"; + reg = <0x00 0x00 0x00 0x00>; + phandle = <0x11>; + }; + + region@110000 { + reg = <0x00 0x110000 0x00 0xf0000>; + reg-names = "ramoops_mem"; + phandle = <0xbb>; + }; + }; + + odroidgo3-keys { + compatible = "gpio-keys"; + #address-cells = <0x01>; + #size-cells = <0x00>; + autorepeat; + phandle = <0x14e>; + + button@0 { + label = "GPIO BTN-VOLUP"; + linux,code = <0x73>; + gpios = <0x66 0x00 0x01>; + }; + + button@1 { + label = "GPIO BTN-VOLDN"; + linux,code = <0x72>; + gpios = <0x66 0x01 0x01>; + }; + }; + + odroidgo3-joypad { + compatible = "odroidgo3-joypad"; + pwms = <0xbc 0x00 0xbebc200 0x00>; + pwm-names = "enable"; + rumble-boost-weak = <0x00>; + rumble-boost-strong = <0x00>; + joypad-name = "GO-Super Gamepad"; + joypad-product = <0x1100>; + joypad-revision = <0x100>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <0xbd>; + pinctrl-1 = <0x7b>; + io-channel-names = "amux_adc"; + io-channels = <0xbe 0x01>; + amux-count = <0x04>; + amux-a-gpios = <0x97 0x0b 0x01>; + amux-b-gpios = <0x97 0x08 0x01>; + amux-en-gpios = <0x97 0x0d 0x01>; + button-adc-scale = <0x02>; + button-adc-deadzone = <0x40>; + button-adc-fuzz = <0x20>; + button-adc-flat = <0x20>; + abs_x-p-tuning = <0xc8>; + abs_x-n-tuning = <0xc8>; + abs_y-p-tuning = <0xc8>; + abs_y-n-tuning = <0xc8>; + abs_rx-p-tuning = <0xc8>; + abs_rx-n-tuning = <0xc8>; + abs_ry-p-tuning = <0xc8>; + abs_ry-n-tuning = <0xc8>; + poll-interval = <0x0a>; + invert-absx; + invert-absy; + phandle = <0x14f>; + + sw1 { + gpios = <0xbf 0x0c 0x01>; + label = "GPIO DPAD-UP"; + linux,code = <0x220>; + }; + + sw2 { + gpios = <0xbf 0x0d 0x01>; + label = "GPIO DPAD-DOWN"; + linux,code = <0x221>; + }; + + sw3 { + gpios = <0xbf 0x0e 0x01>; + label = "GPIO DPAD-LEFT"; + linux,code = <0x222>; + }; + + sw4 { + gpios = <0xbf 0x0f 0x01>; + label = "GPIO DPAD-RIGHT"; + linux,code = <0x223>; + }; + + sw5 { + gpios = <0xbf 0x02 0x01>; + label = "GPIO KEY BTN-A"; + linux,code = <0x131>; + }; + + sw6 { + gpios = <0xbf 0x05 0x01>; + label = "GPIO BTN-B"; + linux,code = <0x130>; + }; + + sw7 { + gpios = <0xbf 0x06 0x01>; + label = "GPIO BTN-Y"; + linux,code = <0x134>; + }; + + sw8 { + gpios = <0xbf 0x07 0x01>; + label = "GPIO BTN-X"; + linux,code = <0x133>; + }; + + sw11 { + gpios = <0x66 0x02 0x01>; + label = "GPIO F3"; + linux,code = <0x2c2>; + }; + + sw12 { + gpios = <0x66 0x03 0x01>; + label = "GPIO F4"; + linux,code = <0x2c3>; + }; + + sw15 { + gpios = <0x66 0x06 0x01>; + label = "GPIO TOP-LEFT"; + linux,code = <0x136>; + }; + + sw16 { + gpios = <0x66 0x07 0x01>; + label = "GPIO TOP-RIGHT"; + linux,code = <0x137>; + }; + + sw19 { + gpios = <0x97 0x09 0x01>; + label = "GPIO F1"; + linux,code = <0x2c0>; + }; + + sw20 { + gpios = <0x97 0x0f 0x01>; + label = "GPIO TOP-RIGHT2"; + linux,code = <0x139>; + }; + + sw21 { + gpios = <0x97 0x0a 0x01>; + label = "GPIO TOP-LEFT2"; + linux,code = <0x138>; + }; + + sw22 { + gpios = <0x97 0x0c 0x01>; + label = "GPIO F2"; + linux,code = <0x2c1>; + }; + + sw13 { + gpios = <0x66 0x04 0x01>; + label = "GPIO F5"; + linux,code = <0x2c4>; + }; + }; + + gpio_leds { + compatible = "gpio-leds"; + pinctrl-names = "led_pins"; + pinctrl-0 = <0xc0>; + phandle = <0x150>; + + heartbeat { + label = "blue:heartbeat"; + gpios = <0x5c 0x11 0x00>; + linux,default-trigger = "heartbeat"; + }; + }; + + backlight { + compatible = "pwm-backlight"; + pwms = <0xc1 0x00 0xf519 0x00>; + brightness-levels = <0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2a 0x2b 0x2c 0x2d 0x2e 0x2f 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x3a 0x3b 0x3c 0x3d 0x3e 0x3f 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48 0x49 0x4a 0x4b 0x4c 0x4d 0x4e 0x4f 0x50 0x51 0x52 0x53 0x54 0x55 0x56 0x57 0x58 0x59 0x5a 0x5b 0x5c 0x5d 0x5e 0x5f 0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69 0x6a 0x6b 0x6c 0x6d 0x6e 0x6f 0x70 0x71 0x72 0x73 0x74 0x75 0x76 0x77 0x78 0x79 0x7a 0x7b 0x7c 0x7d 0x7e 0x7f 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90 0x91 0x92 0x93 0x94 0x95 0x96 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f 0xa0>; + default-brightness-level = <0x33>; + phandle = <0x9d>; + }; + + rk817-sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,name = "rockchip,rk817-codec"; + simple-audio-card,mclk-fs = <0x100>; + simple-audio-card,widgets = "Microphone\0Mic Jack\0Headphone\0Headphone Jack"; + simple-audio-card,routing = "MIC_IN\0Mic Jack\0Headphone Jack\0HPOL\0Headphone Jack\0HPOR"; + simple-audio-card,hp-det-gpio = <0x66 0x16 0x01>; + simple-audio-card,codec-hp-det = <0x01>; + + simple-audio-card,cpu { + sound-dai = <0xc2>; + }; + + simple-audio-card,codec { + sound-dai = <0xc3>; + }; + }; + + vccsys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v8_sys"; + regulator-always-on; + regulator-min-microvolt = <0x39fbc0>; + regulator-max-microvolt = <0x39fbc0>; + phandle = <0x64>; + }; + + __symbols__ { + ddr_timing = "/ddr_timing"; + cpu0 = "/cpus/cpu@0"; + cpu1 = "/cpus/cpu@1"; + cpu2 = "/cpus/cpu@2"; + cpu3 = "/cpus/cpu@3"; + CPU_SLEEP = "/cpus/idle-states/cpu-sleep"; + CLUSTER_SLEEP = "/cpus/idle-states/cluster-sleep"; + cpu0_opp_table = "/cpu0-opp-table"; + bus_soc = "/bus-soc"; + bus_apll = "/bus-apll"; + bus_apll_opp_table = "/bus-apll-opp-table"; + display_subsystem = "/display-subsystem"; + route_lvds = "/display-subsystem/route/route-lvds"; + route_dsi = "/display-subsystem/route/route-dsi"; + route_rgb = "/display-subsystem/route/route-rgb"; + gmac_clkin = "/external-gmac-clock"; + rockchip_suspend = "/rockchip-suspend"; + xin24m = "/xin24m"; + xin32k = "/xin32k"; + pmu = "/power-management@ff000000"; + power = "/power-management@ff000000/power-controller"; + pmugrf = "/syscon@ff010000"; + pmu_io_domains = "/syscon@ff010000/io-domains"; + pmu_pvtm = "/syscon@ff010000/pmu-pvtm"; + uart0 = "/serial@ff030000"; + i2s0_8ch = "/i2s@ff060000"; + i2s1_2ch = "/i2s@ff070000"; + i2s2_2ch = "/i2s@ff080000"; + pdm = "/pdm@ff0a0000"; + crypto = "/crypto@ff0b0000"; + rng = "/rng@ff0b0000"; + gic = "/interrupt-controller@ff131000"; + grf = "/syscon@ff140000"; + io_domains = "/syscon@ff140000/io-domains"; + lvds = "/syscon@ff140000/lvds"; + lvds_in_vopb = "/syscon@ff140000/lvds/ports/port@0/endpoint@0"; + rgb = "/syscon@ff140000/rgb"; + rgb_in_vopb = "/syscon@ff140000/rgb/ports/port@0/endpoint@0"; + core_grf = "/syscon@ff148000"; + pvtm = "/syscon@ff148000/pvtm"; + uart1 = "/serial@ff158000"; + uart2 = "/serial@ff160000"; + uart3 = "/serial@ff168000"; + uart4 = "/serial@ff170000"; + uart5 = "/serial@ff178000"; + i2c0 = "/i2c@ff180000"; + rk817 = "/i2c@ff180000/pmic@20"; + pinctrl_rk8xx = "/i2c@ff180000/pmic@20/pinctrl_rk8xx"; + rk817_ts_gpio1 = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_ts_gpio1"; + rk817_gt_gpio2 = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_gt_gpio2"; + rk817_pin_ts = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_pin_ts"; + rk817_pin_gt = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_pin_gt"; + rk817_slppin_null = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_null"; + rk817_slppin_slp = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_slp"; + rk817_slppin_pwrdn = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_pwrdn"; + rk817_slppin_rst = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_rst"; + vdd_logic = "/i2c@ff180000/pmic@20/regulators/DCDC_REG1"; + vdd_arm = "/i2c@ff180000/pmic@20/regulators/DCDC_REG2"; + vcc_ddr = "/i2c@ff180000/pmic@20/regulators/DCDC_REG3"; + vcc_3v3 = "/i2c@ff180000/pmic@20/regulators/DCDC_REG4"; + vcc_1v0 = "/i2c@ff180000/pmic@20/regulators/LDO_REG1"; + vcc1v8_soc = "/i2c@ff180000/pmic@20/regulators/LDO_REG2"; + vdd1v0_soc = "/i2c@ff180000/pmic@20/regulators/LDO_REG3"; + vcc3v3_pmu = "/i2c@ff180000/pmic@20/regulators/LDO_REG4"; + vccio_sd = "/i2c@ff180000/pmic@20/regulators/LDO_REG5"; + vcc_sd = "/i2c@ff180000/pmic@20/regulators/LDO_REG6"; + vcc_backlight = "/i2c@ff180000/pmic@20/regulators/LDO_REG7"; + vcc_lcd = "/i2c@ff180000/pmic@20/regulators/LDO_REG8"; + dcdc_boost = "/i2c@ff180000/pmic@20/regulators/BOOST"; + otg_switch = "/i2c@ff180000/pmic@20/regulators/OTG_SWITCH"; + rk817_codec = "/i2c@ff180000/pmic@20/codec"; + i2c1 = "/i2c@ff190000"; + i2c2 = "/i2c@ff1a0000"; + i2c3 = "/i2c@ff1b0000"; + spi0 = "/spi@ff1d0000"; + spi1 = "/spi@ff1d8000"; + wdt = "/watchdog@ff1e0000"; + pwm0 = "/pwm@ff200000"; + pwm1 = "/pwm@ff200010"; + pwm2 = "/pwm@ff200020"; + pwm3 = "/pwm@ff200030"; + pwm4 = "/pwm@ff208000"; + pwm5 = "/pwm@ff208010"; + pwm6 = "/pwm@ff208020"; + pwm7 = "/pwm@ff208030"; + rktimer = "/rktimer@ff210000"; + dmac = "/amba/dmac@ff240000"; + thermal_zones = "/thermal-zones"; + soc_thermal = "/thermal-zones/soc-thermal"; + threshold = "/thermal-zones/soc-thermal/trips/trip-point-0"; + target = "/thermal-zones/soc-thermal/trips/trip-point-1"; + soc_crit = "/thermal-zones/soc-thermal/trips/soc-crit"; + gpu_thermal = "/thermal-zones/gpu-thermal"; + tsadc = "/tsadc@ff280000"; + saradc = "/saradc@ff288000"; + otp = "/otp@ff290000"; + otp_id = "/otp@ff290000/id@7"; + cpu_leakage = "/otp@ff290000/cpu-leakage@17"; + performance = "/otp@ff290000/performance@1e"; + cru = "/clock-controller@ff2b0000"; + cpu_boost = "/cpu-boost@ff2b8000"; + pmucru = "/pmu-clock-controller@ff2bc000"; + usb2phy_grf = "/syscon@ff2c0000"; + u2phy = "/syscon@ff2c0000/usb2-phy@100"; + u2phy_host = "/syscon@ff2c0000/usb2-phy@100/host-port"; + u2phy_otg = "/syscon@ff2c0000/usb2-phy@100/otg-port"; + video_phy = "/video-phy@ff2e0000"; + mipi_dphy_rx0 = "/mipi-dphy-rx0@ff2f0000"; + usb20_otg = "/usb@ff300000"; + usb_host0_ehci = "/usb@ff340000"; + usb_host0_ohci = "/usb@ff350000"; + gmac = "/ethernet@ff360000"; + sdmmc = "/dwmmc@ff370000"; + sdio = "/dwmmc@ff380000"; + emmc = "/dwmmc@ff390000"; + nandc0 = "/nandc@ff3b0000"; + sfc = "/sfc@ff3a0000"; + gpu = "/gpu@ff400000"; + gpu_opp_table = "/gpu-opp-table"; + hevc = "/hevc_service@ff440000"; + vpu = "/vpu_service@ff442000"; + vpu_combo = "/vpu_combo"; + hevc_mmu = "/iommu@ff440440"; + vpu_mmu = "/iommu@ff442800"; + dsi = "/dsi@ff450000"; + dsi_in_vopb = "/dsi@ff450000/ports/port@0/endpoint@0"; + timing0 = "/dsi@ff450000/panel@0/display-timings/60Hz"; + timing1 = "/dsi@ff450000/panel@0/display-timings/50Hz"; + timing2 = "/dsi@ff450000/panel@0/display-timings/75Hz"; + vopb = "/vop@ff460000"; + vopb_out = "/vop@ff460000/port"; + vopb_out_lvds = "/vop@ff460000/port/endpoint@0"; + vopb_out_dsi = "/vop@ff460000/port/endpoint@1"; + vopb_out_rgb = "/vop@ff460000/port/endpoint@2"; + vopb_mmu = "/iommu@ff460f00"; + rk_rga = "/rk_rga@ff480000"; + cif = "/cif@ff490000"; + cif_new = "/cif-new@ff490000"; + vip_mmu = "/iommu@ff490800"; + rk_isp = "/rk_isp@ff4a0000"; + rkisp1 = "/rkisp1@ff4a0000"; + isp_mmu = "/iommu@ff4a8000"; + qos_gmac = "/qos@ff518000"; + qos_gpu = "/qos@ff520000"; + qos_sdmmc = "/qos@ff52c000"; + qos_emmc = "/qos@ff538000"; + qos_nand = "/qos@ff538080"; + qos_sdio = "/qos@ff538100"; + qos_sfc = "/qos@ff538180"; + qos_usb_host = "/qos@ff540000"; + qos_usb_otg = "/qos@ff540080"; + qos_isp_128 = "/qos@ff548000"; + qos_isp_rd = "/qos@ff548080"; + qos_isp_wr = "/qos@ff548100"; + qos_isp_m1 = "/qos@ff548180"; + qos_vip = "/qos@ff548200"; + qos_rga_rd = "/qos@ff550000"; + qos_rga_wr = "/qos@ff550080"; + qos_vop_m0 = "/qos@ff550100"; + qos_vop_m1 = "/qos@ff550180"; + qos_vpu = "/qos@ff558000"; + qos_vpu_r128 = "/qos@ff558080"; + dfi = "/dfi@ff610000"; + dmc = "/dmc"; + ddr_power_model = "/dmc/ddr_power_model"; + dmc_opp_table = "/dmc-opp-table"; + rockchip_system_monitor = "/rockchip-system-monitor"; + pinctrl = "/pinctrl"; + gpio0 = "/pinctrl/gpio0@ff040000"; + gpio1 = "/pinctrl/gpio1@ff250000"; + gpio2 = "/pinctrl/gpio2@ff260000"; + gpio3 = "/pinctrl/gpio3@ff270000"; + pcfg_pull_up = "/pinctrl/pcfg-pull-up"; + pcfg_pull_down = "/pinctrl/pcfg-pull-down"; + pcfg_pull_none = "/pinctrl/pcfg-pull-none"; + pcfg_pull_none_2ma = "/pinctrl/pcfg-pull-none-2ma"; + pcfg_pull_up_2ma = "/pinctrl/pcfg-pull-up-2ma"; + pcfg_pull_up_4ma = "/pinctrl/pcfg-pull-up-4ma"; + pcfg_pull_none_4ma = "/pinctrl/pcfg-pull-none-4ma"; + pcfg_pull_down_4ma = "/pinctrl/pcfg-pull-down-4ma"; + pcfg_pull_none_8ma = "/pinctrl/pcfg-pull-none-8ma"; + pcfg_pull_up_8ma = "/pinctrl/pcfg-pull-up-8ma"; + pcfg_pull_none_12ma = "/pinctrl/pcfg-pull-none-12ma"; + pcfg_pull_up_12ma = "/pinctrl/pcfg-pull-up-12ma"; + pcfg_pull_none_smt = "/pinctrl/pcfg-pull-none-smt"; + pcfg_output_high = "/pinctrl/pcfg-output-high"; + pcfg_output_low = "/pinctrl/pcfg-output-low"; + pcfg_input_high = "/pinctrl/pcfg-input-high"; + pcfg_input = "/pinctrl/pcfg-input"; + i2c0_xfer = "/pinctrl/i2c0/i2c0-xfer"; + i2c1_xfer = "/pinctrl/i2c1/i2c1-xfer"; + i2c2_xfer = "/pinctrl/i2c2/i2c2-xfer"; + i2c3_xfer = "/pinctrl/i2c3/i2c3-xfer"; + tsadc_otp_gpio = "/pinctrl/tsadc/tsadc-otp-gpio"; + tsadc_otp_out = "/pinctrl/tsadc/tsadc-otp-out"; + uart0_xfer = "/pinctrl/uart0/uart0-xfer"; + uart0_cts = "/pinctrl/uart0/uart0-cts"; + uart0_rts = "/pinctrl/uart0/uart0-rts"; + uart0_rts_gpio = "/pinctrl/uart0/uart0-rts-gpio"; + uart1_xfer = "/pinctrl/uart1/uart1-xfer"; + uart1_cts = "/pinctrl/uart1/uart1-cts"; + uart1_rts = "/pinctrl/uart1/uart1-rts"; + uart1_rts_gpio = "/pinctrl/uart1/uart1-rts-gpio"; + uart2m0_xfer = "/pinctrl/uart2-m0/uart2m0-xfer"; + uart2m1_xfer = "/pinctrl/uart2-m1/uart2m1-xfer"; + uart3m0_xfer = "/pinctrl/uart3-m0/uart3m0-xfer"; + uart3m0_cts = "/pinctrl/uart3-m0/uart3m0-cts"; + uart3m0_rts = "/pinctrl/uart3-m0/uart3m0-rts"; + uart3m0_rts_gpio = "/pinctrl/uart3-m0/uart3m0-rts-gpio"; + uart3m1_xfer = "/pinctrl/uart3-m1/uart3m1-xfer"; + uart3m1_cts = "/pinctrl/uart3-m1/uart3m1-cts"; + uart3m1_rts = "/pinctrl/uart3-m1/uart3m1-rts"; + uart3m1_rts_gpio = "/pinctrl/uart3-m1/uart3m1-rts-gpio"; + uart4_xfer = "/pinctrl/uart4/uart4-xfer"; + uart4_cts = "/pinctrl/uart4/uart4-cts"; + uart4_rts = "/pinctrl/uart4/uart4-rts"; + uart5_xfer = "/pinctrl/uart5/uart5-xfer"; + uart5_cts = "/pinctrl/uart5/uart5-cts"; + uart5_rts = "/pinctrl/uart5/uart5-rts"; + spi0_clk = "/pinctrl/spi0/spi0-clk"; + spi0_csn = "/pinctrl/spi0/spi0-csn"; + spi0_miso = "/pinctrl/spi0/spi0-miso"; + spi0_mosi = "/pinctrl/spi0/spi0-mosi"; + spi0_clk_hs = "/pinctrl/spi0/spi0-clk-hs"; + spi0_miso_hs = "/pinctrl/spi0/spi0-miso-hs"; + spi0_mosi_hs = "/pinctrl/spi0/spi0-mosi-hs"; + spi1_clk = "/pinctrl/spi1/spi1-clk"; + spi1_csn0 = "/pinctrl/spi1/spi1-csn0"; + spi1_csn1 = "/pinctrl/spi1/spi1-csn1"; + spi1_miso = "/pinctrl/spi1/spi1-miso"; + spi1_mosi = "/pinctrl/spi1/spi1-mosi"; + spi1_clk_hs = "/pinctrl/spi1/spi1-clk-hs"; + spi1_miso_hs = "/pinctrl/spi1/spi1-miso-hs"; + spi1_mosi_hs = "/pinctrl/spi1/spi1-mosi-hs"; + pdm_clk0m0 = "/pinctrl/pdm/pdm-clk0m0"; + pdm_clk0m1 = "/pinctrl/pdm/pdm-clk0m1"; + pdm_clk1 = "/pinctrl/pdm/pdm-clk1"; + pdm_sdi0m0 = "/pinctrl/pdm/pdm-sdi0m0"; + pdm_sdi0m1 = "/pinctrl/pdm/pdm-sdi0m1"; + pdm_sdi1 = "/pinctrl/pdm/pdm-sdi1"; + pdm_sdi2 = "/pinctrl/pdm/pdm-sdi2"; + pdm_sdi3 = "/pinctrl/pdm/pdm-sdi3"; + pdm_clk0m0_sleep = "/pinctrl/pdm/pdm-clk0m0-sleep"; + pdm_clk0m_sleep1 = "/pinctrl/pdm/pdm-clk0m1-sleep"; + pdm_clk1_sleep = "/pinctrl/pdm/pdm-clk1-sleep"; + pdm_sdi0m0_sleep = "/pinctrl/pdm/pdm-sdi0m0-sleep"; + pdm_sdi0m1_sleep = "/pinctrl/pdm/pdm-sdi0m1-sleep"; + pdm_sdi1_sleep = "/pinctrl/pdm/pdm-sdi1-sleep"; + pdm_sdi2_sleep = "/pinctrl/pdm/pdm-sdi2-sleep"; + pdm_sdi3_sleep = "/pinctrl/pdm/pdm-sdi3-sleep"; + i2s0_8ch_mclk = "/pinctrl/i2s0/i2s0-8ch-mclk"; + i2s0_8ch_sclktx = "/pinctrl/i2s0/i2s0-8ch-sclktx"; + i2s0_8ch_sclkrx = "/pinctrl/i2s0/i2s0-8ch-sclkrx"; + i2s0_8ch_lrcktx = "/pinctrl/i2s0/i2s0-8ch-lrcktx"; + i2s0_8ch_lrckrx = "/pinctrl/i2s0/i2s0-8ch-lrckrx"; + i2s0_8ch_sdo0 = "/pinctrl/i2s0/i2s0-8ch-sdo0"; + i2s0_8ch_sdo1 = "/pinctrl/i2s0/i2s0-8ch-sdo1"; + i2s0_8ch_sdo2 = "/pinctrl/i2s0/i2s0-8ch-sdo2"; + i2s0_8ch_sdo3 = "/pinctrl/i2s0/i2s0-8ch-sdo3"; + i2s0_8ch_sdi0 = "/pinctrl/i2s0/i2s0-8ch-sdi0"; + i2s0_8ch_sdi1 = "/pinctrl/i2s0/i2s0-8ch-sdi1"; + i2s0_8ch_sdi2 = "/pinctrl/i2s0/i2s0-8ch-sdi2"; + i2s0_8ch_sdi3 = "/pinctrl/i2s0/i2s0-8ch-sdi3"; + i2s1_2ch_mclk = "/pinctrl/i2s1/i2s1-2ch-mclk"; + i2s1_2ch_sclk = "/pinctrl/i2s1/i2s1-2ch-sclk"; + i2s1_2ch_lrck = "/pinctrl/i2s1/i2s1-2ch-lrck"; + i2s1_2ch_sdi = "/pinctrl/i2s1/i2s1-2ch-sdi"; + i2s1_2ch_sdo = "/pinctrl/i2s1/i2s1-2ch-sdo"; + i2s2_2ch_mclk = "/pinctrl/i2s2/i2s2-2ch-mclk"; + i2s2_2ch_sclk = "/pinctrl/i2s2/i2s2-2ch-sclk"; + i2s2_2ch_lrck = "/pinctrl/i2s2/i2s2-2ch-lrck"; + i2s2_2ch_sdi = "/pinctrl/i2s2/i2s2-2ch-sdi"; + i2s2_2ch_sdo = "/pinctrl/i2s2/i2s2-2ch-sdo"; + sdmmc_clk = "/pinctrl/sdmmc/sdmmc-clk"; + sdmmc_cmd = "/pinctrl/sdmmc/sdmmc-cmd"; + sdmmc_det = "/pinctrl/sdmmc/sdmmc-det"; + sdmmc_bus1 = "/pinctrl/sdmmc/sdmmc-bus1"; + sdmmc_bus4 = "/pinctrl/sdmmc/sdmmc-bus4"; + sdmmc_gpio = "/pinctrl/sdmmc/sdmmc-gpio"; + sdio_clk = "/pinctrl/sdio/sdio-clk"; + sdio_cmd = "/pinctrl/sdio/sdio-cmd"; + sdio_bus4 = "/pinctrl/sdio/sdio-bus4"; + sdio_gpio = "/pinctrl/sdio/sdio-gpio"; + emmc_clk = "/pinctrl/emmc/emmc-clk"; + emmc_cmd = "/pinctrl/emmc/emmc-cmd"; + emmc_pwren = "/pinctrl/emmc/emmc-pwren"; + emmc_rstnout = "/pinctrl/emmc/emmc-rstnout"; + emmc_bus1 = "/pinctrl/emmc/emmc-bus1"; + emmc_bus4 = "/pinctrl/emmc/emmc-bus4"; + emmc_bus8 = "/pinctrl/emmc/emmc-bus8"; + flash_cs0 = "/pinctrl/flash/flash-cs0"; + flash_rdy = "/pinctrl/flash/flash-rdy"; + flash_dqs = "/pinctrl/flash/flash-dqs"; + flash_ale = "/pinctrl/flash/flash-ale"; + flash_cle = "/pinctrl/flash/flash-cle"; + flash_wrn = "/pinctrl/flash/flash-wrn"; + flash_csl = "/pinctrl/flash/flash-csl"; + flash_rdn = "/pinctrl/flash/flash-rdn"; + flash_bus8 = "/pinctrl/flash/flash-bus8"; + lcdc_m0_rgb_pins = "/pinctrl/lcdc/lcdc-m0-rgb-pins"; + lcdc_m0_sleep_pins = "/pinctrl/lcdc/lcdc-m0-sleep-pins"; + lcdc_m1_rgb_pins = "/pinctrl/lcdc/lcdc-m1-rgb-pins"; + lcdc_m1_sleep_pins = "/pinctrl/lcdc/lcdc-m1-sleep-pins"; + pwm0_pin = "/pinctrl/pwm0/pwm0-pin"; + pwm1_pin = "/pinctrl/pwm1/pwm1-pin"; + pwm2_pin = "/pinctrl/pwm2/pwm2-pin"; + pwm3_pin = "/pinctrl/pwm3/pwm3-pin"; + pwm4_pin = "/pinctrl/pwm4/pwm4-pin"; + pwm5_pin = "/pinctrl/pwm5/pwm5-pin"; + pwm6_pin = "/pinctrl/pwm6/pwm6-pin"; + pwm7_pin = "/pinctrl/pwm7/pwm7-pin"; + rmii_pins = "/pinctrl/gmac/rmii-pins"; + mac_refclk_12ma = "/pinctrl/gmac/mac-refclk-12ma"; + mac_refclk = "/pinctrl/gmac/mac-refclk"; + cif_clkout_m0 = "/pinctrl/cif-m0/cif-clkout-m0"; + dvp_d2d9_m0 = "/pinctrl/cif-m0/dvp-d2d9-m0"; + dvp_d0d1_m0 = "/pinctrl/cif-m0/dvp-d0d1-m0"; + dvp_d10d11_m0 = "/pinctrl/cif-m0/d10-d11-m0"; + cif_clkout_m1 = "/pinctrl/cif-m1/cif-clkout-m1"; + dvp_d2d9_m1 = "/pinctrl/cif-m1/dvp-d2d9-m1"; + dvp_d0d1_m1 = "/pinctrl/cif-m1/dvp-d0d1-m1"; + dvp_d10d11_m1 = "/pinctrl/cif-m1/d10-d11-m1"; + isp_prelight = "/pinctrl/isp/isp-prelight"; + pmic_int = "/pinctrl/pmic/pmic_int"; + soc_slppin_gpio = "/pinctrl/pmic/soc_slppin_gpio"; + soc_slppin_slp = "/pinctrl/pmic/soc_slppin_slp"; + soc_slppin_rst = "/pinctrl/pmic/soc_slppin_rst"; + led_pins = "/pinctrl/leds/led-pins"; + btn_pins = "/pinctrl/btns/btn-pins"; + drm_logo = "/reserved-memory/drm-logo@00000000"; + ramoops_mem = "/reserved-memory/region@110000"; + gpio_keys = "/odroidgo3-keys"; + joypad = "/odroidgo3-joypad"; + leds = "/gpio_leds"; + backlight = "/backlight"; + vccsys = "/vccsys"; + }; +}; diff --git a/config/archr-dts/R36S-DTB/DTS/Panel4-V22.dts b/config/archr-dts/R36S-DTB/DTS/Panel4-V22.dts new file mode 100644 index 0000000000..dd9948e821 --- /dev/null +++ b/config/archr-dts/R36S-DTB/DTS/Panel4-V22.dts @@ -0,0 +1,4075 @@ + +/dts-v1/; + +/ { + compatible = "rockchip,rk3326-odroidgo3-linux\0rockchip,rk3326"; + interrupt-parent = <0x01>; + #address-cells = <0x02>; + #size-cells = <0x02>; + model = "Game Console R36S V22"; + + + ddr_timing { + compatible = "rockchip,ddr-timing"; + ddr2_speed_bin = <0x00>; + ddr3_speed_bin = <0x15>; + ddr4_speed_bin = <0x0c>; + pd_idle = <0x0d>; + sr_idle = <0x5d>; + sr_mc_gate_idle = <0x00>; + srpd_lite_idle = <0x00>; + standby_idle = <0x00>; + auto_pd_dis_freq = <0x42a>; + auto_sr_dis_freq = <0x320>; + ddr2_dll_dis_freq = <0x12c>; + ddr3_dll_dis_freq = <0x12c>; + ddr4_dll_dis_freq = <0x271>; + phy_dll_dis_freq = <0x190>; + ddr2_odt_dis_freq = <0x64>; + phy_ddr2_odt_dis_freq = <0x64>; + ddr2_drv = <0x01>; + ddr2_odt = <0x96>; + phy_ddr2_ca_drv = <0x15>; + phy_ddr2_ck_drv = <0x12>; + phy_ddr2_dq_drv = <0x15>; + phy_ddr2_odt = <0x02>; + ddr3_odt_dis_freq = <0x190>; + phy_ddr3_odt_dis_freq = <0x190>; + ddr3_drv = <0x28>; + ddr3_odt = <0x78>; + phy_ddr3_ca_drv = <0x15>; + phy_ddr3_ck_drv = <0x12>; + phy_ddr3_dq_drv = <0x15>; + phy_ddr3_odt = <0x02>; + phy_lpddr2_odt_dis_freq = <0x29a>; + lpddr2_drv = <0x28>; + phy_lpddr2_ca_drv = <0x16>; + phy_lpddr2_ck_drv = <0x13>; + phy_lpddr2_dq_drv = <0x16>; + phy_lpddr2_odt = <0x00>; + lpddr3_odt_dis_freq = <0x190>; + phy_lpddr3_odt_dis_freq = <0x190>; + lpddr3_drv = <0x28>; + lpddr3_odt = <0xf0>; + phy_lpddr3_ca_drv = <0x16>; + phy_lpddr3_ck_drv = <0x13>; + phy_lpddr3_dq_drv = <0x16>; + phy_lpddr3_odt = <0x02>; + lpddr4_odt_dis_freq = <0x320>; + phy_lpddr4_odt_dis_freq = <0x320>; + lpddr4_drv = <0x3c>; + lpddr4_dq_odt = <0x28>; + lpddr4_ca_odt = <0x28>; + phy_lpddr4_ca_drv = <0x14>; + phy_lpddr4_ck_cs_drv = <0x06>; + phy_lpddr4_dq_drv = <0x06>; + phy_lpddr4_odt = <0x10>; + ddr4_odt_dis_freq = <0x29a>; + phy_ddr4_odt_dis_freq = <0x29a>; + ddr4_drv = <0x22>; + ddr4_odt = <0xf0>; + phy_ddr4_ca_drv = <0x16>; + phy_ddr4_ck_drv = <0x13>; + phy_ddr4_dq_drv = <0x16>; + phy_ddr4_odt = <0x02>; + ddr3a1_ddr4a9_de-skew = <0x06>; + ddr3a0_ddr4a10_de-skew = <0x07>; + ddr3a3_ddr4a6_de-skew = <0x07>; + ddr3a2_ddr4a4_de-skew = <0x07>; + ddr3a5_ddr4a8_de-skew = <0x07>; + ddr3a4_ddr4a5_de-skew = <0x07>; + ddr3a7_ddr4a11_de-skew = <0x07>; + ddr3a6_ddr4a7_de-skew = <0x06>; + ddr3a9_ddr4a0_de-skew = <0x07>; + ddr3a8_ddr4a13_de-skew = <0x07>; + ddr3a11_ddr4a3_de-skew = <0x07>; + ddr3a10_ddr4cs0_de-skew = <0x07>; + ddr3a13_ddr4a2_de-skew = <0x07>; + ddr3a12_ddr4ba1_de-skew = <0x07>; + ddr3a15_ddr4odt0_de-skew = <0x07>; + ddr3a14_ddr4a1_de-skew = <0x07>; + ddr3ba1_ddr4a15_de-skew = <0x07>; + ddr3ba0_ddr4bg0_de-skew = <0x07>; + ddr3ras_ddr4cke_de-skew = <0x07>; + ddr3ba2_ddr4ba0_de-skew = <0x07>; + ddr3we_ddr4bg1_de-skew = <0x07>; + ddr3cas_ddr4a12_de-skew = <0x07>; + ddr3ckn_ddr4ckn_de-skew = <0x07>; + ddr3ckp_ddr4ckp_de-skew = <0x07>; + ddr3cke_ddr4a16_de-skew = <0x07>; + ddr3odt0_ddr4a14_de-skew = <0x07>; + ddr3cs0_ddr4act_de-skew = <0x06>; + ddr3reset_ddr4reset_de-skew = <0x07>; + ddr3cs1_ddr4cs1_de-skew = <0x06>; + ddr3odt1_ddr4odt1_de-skew = <0x07>; + cs0_dm0_rx_de-skew = <0x07>; + cs0_dm0_tx_de-skew = <0x07>; + cs0_dq0_rx_de-skew = <0x08>; + cs0_dq0_tx_de-skew = <0x08>; + cs0_dq1_rx_de-skew = <0x09>; + cs0_dq1_tx_de-skew = <0x08>; + cs0_dq2_rx_de-skew = <0x08>; + cs0_dq2_tx_de-skew = <0x08>; + cs0_dq3_rx_de-skew = <0x08>; + cs0_dq3_tx_de-skew = <0x08>; + cs0_dq4_rx_de-skew = <0x09>; + cs0_dq4_tx_de-skew = <0x08>; + cs0_dq5_rx_de-skew = <0x09>; + cs0_dq5_tx_de-skew = <0x08>; + cs0_dq6_rx_de-skew = <0x09>; + cs0_dq6_tx_de-skew = <0x08>; + cs0_dq7_rx_de-skew = <0x08>; + cs0_dq7_tx_de-skew = <0x08>; + cs0_dqs0_rx_de-skew = <0x06>; + cs0_dqs0p_tx_de-skew = <0x09>; + cs0_dqs0n_tx_de-skew = <0x09>; + cs0_dm1_rx_de-skew = <0x07>; + cs0_dm1_tx_de-skew = <0x06>; + cs0_dq8_rx_de-skew = <0x08>; + cs0_dq8_tx_de-skew = <0x07>; + cs0_dq9_rx_de-skew = <0x09>; + cs0_dq9_tx_de-skew = <0x07>; + cs0_dq10_rx_de-skew = <0x08>; + cs0_dq10_tx_de-skew = <0x08>; + cs0_dq11_rx_de-skew = <0x08>; + cs0_dq11_tx_de-skew = <0x07>; + cs0_dq12_rx_de-skew = <0x08>; + cs0_dq12_tx_de-skew = <0x08>; + cs0_dq13_rx_de-skew = <0x09>; + cs0_dq13_tx_de-skew = <0x07>; + cs0_dq14_rx_de-skew = <0x09>; + cs0_dq14_tx_de-skew = <0x08>; + cs0_dq15_rx_de-skew = <0x09>; + cs0_dq15_tx_de-skew = <0x07>; + cs0_dqs1_rx_de-skew = <0x07>; + cs0_dqs1p_tx_de-skew = <0x09>; + cs0_dqs1n_tx_de-skew = <0x09>; + cs0_dm2_rx_de-skew = <0x07>; + cs0_dm2_tx_de-skew = <0x07>; + cs0_dq16_rx_de-skew = <0x09>; + cs0_dq16_tx_de-skew = <0x09>; + cs0_dq17_rx_de-skew = <0x07>; + cs0_dq17_tx_de-skew = <0x09>; + cs0_dq18_rx_de-skew = <0x07>; + cs0_dq18_tx_de-skew = <0x08>; + cs0_dq19_rx_de-skew = <0x07>; + cs0_dq19_tx_de-skew = <0x09>; + cs0_dq20_rx_de-skew = <0x09>; + cs0_dq20_tx_de-skew = <0x09>; + cs0_dq21_rx_de-skew = <0x09>; + cs0_dq21_tx_de-skew = <0x09>; + cs0_dq22_rx_de-skew = <0x08>; + cs0_dq22_tx_de-skew = <0x09>; + cs0_dq23_rx_de-skew = <0x08>; + cs0_dq23_tx_de-skew = <0x09>; + cs0_dqs2_rx_de-skew = <0x06>; + cs0_dqs2p_tx_de-skew = <0x09>; + cs0_dqs2n_tx_de-skew = <0x09>; + cs0_dm3_rx_de-skew = <0x07>; + cs0_dm3_tx_de-skew = <0x07>; + cs0_dq24_rx_de-skew = <0x08>; + cs0_dq24_tx_de-skew = <0x08>; + cs0_dq25_rx_de-skew = <0x09>; + cs0_dq25_tx_de-skew = <0x09>; + cs0_dq26_rx_de-skew = <0x09>; + cs0_dq26_tx_de-skew = <0x08>; + cs0_dq27_rx_de-skew = <0x09>; + cs0_dq27_tx_de-skew = <0x08>; + cs0_dq28_rx_de-skew = <0x09>; + cs0_dq28_tx_de-skew = <0x09>; + cs0_dq29_rx_de-skew = <0x09>; + cs0_dq29_tx_de-skew = <0x09>; + cs0_dq30_rx_de-skew = <0x08>; + cs0_dq30_tx_de-skew = <0x08>; + cs0_dq31_rx_de-skew = <0x08>; + cs0_dq31_tx_de-skew = <0x08>; + cs0_dqs3_rx_de-skew = <0x07>; + cs0_dqs3p_tx_de-skew = <0x09>; + cs0_dqs3n_tx_de-skew = <0x09>; + cs1_dm0_rx_de-skew = <0x07>; + cs1_dm0_tx_de-skew = <0x07>; + cs1_dq0_rx_de-skew = <0x08>; + cs1_dq0_tx_de-skew = <0x08>; + cs1_dq1_rx_de-skew = <0x09>; + cs1_dq1_tx_de-skew = <0x08>; + cs1_dq2_rx_de-skew = <0x08>; + cs1_dq2_tx_de-skew = <0x08>; + cs1_dq3_rx_de-skew = <0x08>; + cs1_dq3_tx_de-skew = <0x08>; + cs1_dq4_rx_de-skew = <0x08>; + cs1_dq4_tx_de-skew = <0x08>; + cs1_dq5_rx_de-skew = <0x09>; + cs1_dq5_tx_de-skew = <0x08>; + cs1_dq6_rx_de-skew = <0x09>; + cs1_dq6_tx_de-skew = <0x08>; + cs1_dq7_rx_de-skew = <0x08>; + cs1_dq7_tx_de-skew = <0x08>; + cs1_dqs0_rx_de-skew = <0x06>; + cs1_dqs0p_tx_de-skew = <0x09>; + cs1_dqs0n_tx_de-skew = <0x09>; + cs1_dm1_rx_de-skew = <0x07>; + cs1_dm1_tx_de-skew = <0x07>; + cs1_dq8_rx_de-skew = <0x08>; + cs1_dq8_tx_de-skew = <0x08>; + cs1_dq9_rx_de-skew = <0x08>; + cs1_dq9_tx_de-skew = <0x07>; + cs1_dq10_rx_de-skew = <0x07>; + cs1_dq10_tx_de-skew = <0x08>; + cs1_dq11_rx_de-skew = <0x08>; + cs1_dq11_tx_de-skew = <0x08>; + cs1_dq12_rx_de-skew = <0x08>; + cs1_dq12_tx_de-skew = <0x07>; + cs1_dq13_rx_de-skew = <0x08>; + cs1_dq13_tx_de-skew = <0x08>; + cs1_dq14_rx_de-skew = <0x08>; + cs1_dq14_tx_de-skew = <0x08>; + cs1_dq15_rx_de-skew = <0x08>; + cs1_dq15_tx_de-skew = <0x07>; + cs1_dqs1_rx_de-skew = <0x07>; + cs1_dqs1p_tx_de-skew = <0x09>; + cs1_dqs1n_tx_de-skew = <0x09>; + cs1_dm2_rx_de-skew = <0x07>; + cs1_dm2_tx_de-skew = <0x08>; + cs1_dq16_rx_de-skew = <0x08>; + cs1_dq16_tx_de-skew = <0x09>; + cs1_dq17_rx_de-skew = <0x08>; + cs1_dq17_tx_de-skew = <0x09>; + cs1_dq18_rx_de-skew = <0x07>; + cs1_dq18_tx_de-skew = <0x08>; + cs1_dq19_rx_de-skew = <0x08>; + cs1_dq19_tx_de-skew = <0x09>; + cs1_dq20_rx_de-skew = <0x09>; + cs1_dq20_tx_de-skew = <0x09>; + cs1_dq21_rx_de-skew = <0x09>; + cs1_dq21_tx_de-skew = <0x09>; + cs1_dq22_rx_de-skew = <0x08>; + cs1_dq22_tx_de-skew = <0x09>; + cs1_dq23_rx_de-skew = <0x08>; + cs1_dq23_tx_de-skew = <0x09>; + cs1_dqs2_rx_de-skew = <0x06>; + cs1_dqs2p_tx_de-skew = <0x09>; + cs1_dqs2n_tx_de-skew = <0x09>; + cs1_dm3_rx_de-skew = <0x07>; + cs1_dm3_tx_de-skew = <0x07>; + cs1_dq24_rx_de-skew = <0x08>; + cs1_dq24_tx_de-skew = <0x09>; + cs1_dq25_rx_de-skew = <0x09>; + cs1_dq25_tx_de-skew = <0x09>; + cs1_dq26_rx_de-skew = <0x09>; + cs1_dq26_tx_de-skew = <0x08>; + cs1_dq27_rx_de-skew = <0x08>; + cs1_dq27_tx_de-skew = <0x08>; + cs1_dq28_rx_de-skew = <0x09>; + cs1_dq28_tx_de-skew = <0x09>; + cs1_dq29_rx_de-skew = <0x09>; + cs1_dq29_tx_de-skew = <0x09>; + cs1_dq30_rx_de-skew = <0x09>; + cs1_dq30_tx_de-skew = <0x08>; + cs1_dq31_rx_de-skew = <0x08>; + cs1_dq31_tx_de-skew = <0x08>; + cs1_dqs3_rx_de-skew = <0x07>; + cs1_dqs3p_tx_de-skew = <0x09>; + cs1_dqs3n_tx_de-skew = <0x09>; + phandle = <0xaf>; + }; + + aliases { + ethernet0 = "/ethernet@ff360000"; + i2c0 = "/i2c@ff180000"; + i2c1 = "/i2c@ff190000"; + i2c2 = "/i2c@ff1a0000"; + i2c3 = "/i2c@ff1b0000"; + serial0 = "/serial@ff030000"; + serial1 = "/serial@ff158000"; + serial2 = "/serial@ff160000"; + serial3 = "/serial@ff168000"; + serial4 = "/serial@ff170000"; + serial5 = "/serial@ff178000"; + spi0 = "/spi@ff1d0000"; + spi1 = "/spi@ff1d8000"; + }; + + cpus { + #address-cells = <0x02>; + #size-cells = <0x00>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x00>; + enable-method = "psci"; + clocks = <0x02 0x07>; + #cooling-cells = <0x02>; + dynamic-power-coefficient = <0x5a>; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + cpu-supply = <0x06>; + phandle = <0x09>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x01>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0a>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x02>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0b>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x03>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0c>; + }; + + idle-states { + entry-method = "psci"; + + cpu-sleep { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x10000>; + entry-latency-us = <0x78>; + exit-latency-us = <0xfa>; + min-residency-us = <0x384>; + phandle = <0x04>; + }; + + cluster-sleep { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x1010000>; + entry-latency-us = <0x190>; + exit-latency-us = <0x1f4>; + min-residency-us = <0x7d0>; + phandle = <0x05>; + }; + }; + }; + + cpu0-opp-table { + compatible = "operating-points-v2"; + opp-shared; + rockchip,temp-hysteresis = <0x1388>; + rockchip,low-temp = <0x00>; + rockchip,low-temp-min-volt = <0xf4240>; + rockchip,low-temp-adjust-volt = <0x00 0x5e8 0xc350>; + clocks = <0x02 0x01>; + rockchip,avs-scale = <0x04>; + rockchip,max-volt = <0x149970>; + rockchip,evb-irdrop = <0x61a8>; + nvmem-cells = <0x07 0x08>; + nvmem-cell-names = "cpu_leakage\0performance"; + rockchip,bin-scaling-sel = <0x00 0x0d 0x01 0x0d>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-freq = <0x639c0>; + rockchip,pvtm-volt = <0xf4240>; + rockchip,pvtm-ch = <0x00 0x00>; + rockchip,pvtm-sample-time = <0x3e8>; + rockchip,pvtm-number = <0x0a>; + rockchip,pvtm-error = <0x3e8>; + rockchip,pvtm-ref-temp = <0x28>; + rockchip,pvtm-temp-prop = <0xffffffc8 0xffffffc8>; + rockchip,thermal-zone = "soc-thermal"; + rockchip,avs = <0x01>; + phandle = <0x03>; + + opp-1008000000 { + opp-hz = <0x00 0x3c14dc00>; + opp-microvolt = <0x11edd8 0x11edd8 0x149970>; + opp-microvolt-L0 = <0x11edd8 0x11edd8 0x149970>; + opp-microvolt-L1 = <0x112a88 0x112a88 0x149970>; + opp-microvolt-L2 = <0x112a88 0x112a88 0x149970>; + opp-microvolt-L3 = <0x100590 0x100590 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1200000000 { + opp-hz = <0x00 0x47868c00>; + opp-microvolt = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L0 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L1 = <0x137478 0x137478 0x149970>; + opp-microvolt-L2 = <0x1312d0 0x1312d0 0x149970>; + opp-microvolt-L3 = <0x124f80 0x124f80 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1248000000 { + opp-hz = <0x00 0x4a62f800>; + opp-microvolt = <0x149970 0x149970 0x149970>; + opp-microvolt-L0 = <0x149970 0x149970 0x149970>; + opp-microvolt-L1 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L2 = <0x137478 0x137478 0x149970>; + opp-microvolt-L3 = <0x12b128 0x12b128 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1296000000 { + opp-hz = <0x00 0x4d3f6400>; + opp-microvolt = <0x149970 0x149970 0x149970>; + opp-microvolt-L0 = <0x149970 0x149970 0x149970>; + opp-microvolt-L1 = <0x149970 0x149970 0x149970>; + opp-microvolt-L2 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L3 = <0x1312d0 0x1312d0 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1512000000 { + opp-hz = <0x00 0x5a1f4a00>; + opp-microvolt = <0x149970 0x149970 0x149970>; + opp-microvolt-L0 = <0x149970 0x149970 0x149970>; + opp-microvolt-L1 = <0x149970 0x149970 0x149970>; + opp-microvolt-L2 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L3 = <0x1312d0 0x1312d0 0x149970>; + clock-latency-ns = <0x9c40>; + }; + }; + + arm-pmu { + compatible = "arm,cortex-a53-pmu"; + interrupts = <0x00 0x64 0x04 0x00 0x65 0x04 0x00 0x66 0x04 0x00 0x67 0x04>; + interrupt-affinity = <0x09 0x0a 0x0b 0x0c>; + }; + + bus-soc { + compatible = "rockchip,px30-bus"; + rockchip,busfreq-policy = "autocs"; + phandle = <0xc4>; + + soc-bus0 { + bus-id = <0x00>; + timer-us = <0x14>; + enable-msk = <0x40f7>; + status = "disabled"; + }; + + soc-bus1 { + bus-id = <0x01>; + timer-us = <0xc8>; + enable-msk = <0x40bf>; + status = "disabled"; + }; + + soc-bus2 { + bus-id = <0x02>; + timer-us = <0xc8>; + enable-msk = <0x4007>; + status = "disabled"; + }; + }; + + bus-apll { + compatible = "rockchip,px30-bus"; + rockchip,busfreq-policy = "clkfreq"; + clocks = <0x02 0x01>; + clock-names = "bus"; + operating-points-v2 = <0x0d>; + status = "okay"; + bus-supply = <0x0e>; + phandle = <0xc5>; + }; + + bus-apll-opp-table { + compatible = "operating-points-v2"; + opp-shared; + phandle = <0x0d>; + + opp-1512000000 { + opp-hz = <0x00 0x5a1f4a00>; + opp-microvolt = <0xf4240>; + }; + + opp-1008000000 { + opp-hz = <0x00 0x3c14dc00>; + opp-microvolt = <0xe7ef0>; + }; + }; + + cpuinfo { + compatible = "rockchip,cpuinfo"; + nvmem-cells = <0x0f>; + nvmem-cell-names = "id"; + }; + + display-subsystem { + compatible = "rockchip,display-subsystem"; + ports = <0x10>; + status = "okay"; + logo-memory-region = <0x11>; + phandle = <0xc6>; + + route { + + route-lvds { + status = "disabled"; + logo,uboot = "logo.gif"; + logo,kernel = "logo_kernel.gif"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x12>; + phandle = <0xc7>; + }; + + route-dsi { + status = "okay"; + logo,uboot = "logo.gif"; + logo,kernel = "logo_kernel.gif"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x13>; + phandle = <0xc8>; + }; + + route-rgb { + status = "disabled"; + logo,uboot = "logo.gif"; + logo,kernel = "logo_kernel.gif"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x14>; + phandle = <0xc9>; + }; + }; + }; + + firmware { + + optee { + compatible = "linaro,optee-tz"; + method = "smc"; + }; + }; + + external-gmac-clock { + compatible = "fixed-clock"; + clock-frequency = <0x2faf080>; + clock-output-names = "gmac_clkin"; + #clock-cells = <0x00>; + phandle = <0xca>; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + rockchip-suspend { + compatible = "rockchip,pm-px30"; + status = "okay"; + rockchip,sleep-debug-en = <0x01>; + rockchip,sleep-mode-config = <0x20702>; + rockchip,wakeup-config = <0x85>; + phandle = <0xcb>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <0x01 0x0d 0xf04 0x01 0x0e 0xf04 0x01 0x0b 0xf04 0x01 0x0a 0xf04>; + }; + + xin24m { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x16e3600>; + clock-output-names = "xin24m"; + phandle = <0xcc>; + }; + + xin32k { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x8000>; + clock-output-names = "xin32k"; + phandle = <0xcd>; + }; + + power-management@ff000000 { + compatible = "rockchip,px30-pmu\0syscon\0simple-mfd"; + reg = <0x00 0xff000000 0x00 0x1000>; + phandle = <0xce>; + + power-controller { + compatible = "rockchip,px30-power-controller"; + #power-domain-cells = <0x01>; + #address-cells = <0x01>; + #size-cells = <0x00>; + phandle = <0x8a>; + + pd_usb@5 { + reg = <0x05>; + clocks = <0x02 0x103 0x02 0x102 0x02 0x3c>; + pm_qos = <0x15 0x16>; + }; + + pd_sdcard@7 { + reg = <0x07>; + clocks = <0x02 0xf7 0x02 0x3b>; + pm_qos = <0x17>; + }; + + pd_gmac@9 { + reg = <0x09>; + clocks = <0x02 0xb2 0x02 0x143 0x02 0x40 0x02 0x3f>; + pm_qos = <0x18>; + }; + + pd_mmc_nand@10 { + reg = <0x0a>; + clocks = <0x02 0xfe 0x02 0x100 0x02 0xff 0x02 0x101 0x02 0x39 0x02 0x37 0x02 0x38 0x02 0x3a>; + pm_qos = <0x19 0x1a 0x1b 0x1c>; + }; + + pd_vpu@11 { + reg = <0x0b>; + clocks = <0x02 0xaf 0x02 0xf4 0x02 0x4b>; + pm_qos = <0x1d 0x1e>; + }; + + pd_vo@12 { + reg = <0x0c>; + clocks = <0x02 0xb7 0x02 0xb5 0x02 0xb6 0x02 0x96 0x02 0x97 0x02 0xfd 0x02 0xfb 0x02 0xfc 0x02 0x144 0x02 0x35 0x02 0x36>; + pm_qos = <0x1f 0x20 0x21 0x22>; + }; + + pd_vi@13 { + reg = <0x0d>; + clocks = <0x02 0xb3 0x02 0xb4 0x02 0xf9 0x02 0xfa 0x02 0x33>; + pm_qos = <0x23 0x24 0x25 0x26 0x27>; + }; + + pd_gpu@14 { + reg = <0x0e>; + clocks = <0x02 0x49>; + pm_qos = <0x28>; + }; + }; + }; + + syscon@ff010000 { + compatible = "rockchip,px30-pmugrf\0syscon\0simple-mfd"; + reg = <0x00 0xff010000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0xac>; + + io-domains { + compatible = "rockchip,px30-pmu-io-voltage-domain"; + status = "okay"; + pmuio1-supply = <0x29>; + pmuio2-supply = <0x29>; + phandle = <0xcf>; + }; + + reboot-mode { + compatible = "syscon-reboot-mode"; + offset = <0x200>; + mode-bootloader = <0x5242c301>; + mode-charge = <0x5242c30b>; + mode-fastboot = <0x5242c309>; + mode-loader = <0x5242c301>; + mode-normal = <0x5242c300>; + mode-recovery = <0x5242c303>; + mode-ums = <0x5242c30c>; + }; + + pmu-pvtm { + compatible = "rockchip,px30-pmu-pvtm"; + clocks = <0x2a 0x07>; + clock-names = "pmu"; + status = "okay"; + phandle = <0xd0>; + }; + }; + + serial@ff030000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff030000 0x00 0x100>; + interrupts = <0x00 0x0f 0x04>; + clocks = <0x2a 0x06 0x2a 0x15>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x00 0x2b 0x01>; + pinctrl-names = "default"; + pinctrl-0 = <0x2c 0x2d 0x2e>; + status = "disabled"; + phandle = <0xd1>; + }; + + i2s@ff060000 { + compatible = "rockchip,px30-i2s-tdm"; + reg = <0x00 0xff060000 0x00 0x1000>; + interrupts = <0x00 0x0c 0x04>; + clocks = <0x02 0x10 0x02 0x12 0x02 0x106>; + clock-names = "mclk_tx\0mclk_rx\0hclk"; + dmas = <0x2b 0x10 0x2b 0x11>; + dma-names = "tx\0rx"; + resets = <0x02 0x84 0x02 0xbf>; + reset-names = "tx-m\0rx-m"; + rockchip,cru = <0x02>; + rockchip,grf = <0x2f>; + pinctrl-names = "default"; + pinctrl-0 = <0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x3a 0x3b>; + status = "disabled"; + phandle = <0xd2>; + }; + + i2s@ff070000 { + compatible = "rockchip,px30-i2s\0rockchip,rk3066-i2s"; + reg = <0x00 0xff070000 0x00 0x1000>; + interrupts = <0x00 0x0d 0x04>; + clocks = <0x02 0x14 0x02 0x107>; + clock-names = "i2s_clk\0i2s_hclk"; + dmas = <0x2b 0x12 0x2b 0x13>; + dma-names = "tx\0rx"; + resets = <0x02 0x86 0x02 0x85>; + reset-names = "reset-m\0reset-h"; + pinctrl-names = "default"; + pinctrl-0 = <0x3c 0x3d 0x3e 0x3f>; + status = "okay"; + #sound-dai-cells = <0x00>; + phandle = <0xc2>; + }; + + i2s@ff080000 { + compatible = "rockchip,px30-i2s\0rockchip,rk3066-i2s"; + reg = <0x00 0xff080000 0x00 0x1000>; + interrupts = <0x00 0x0e 0x04>; + clocks = <0x02 0x16 0x02 0x108>; + clock-names = "i2s_clk\0i2s_hclk"; + dmas = <0x2b 0x14 0x2b 0x15>; + dma-names = "tx\0rx"; + resets = <0x02 0x88 0x02 0x87>; + reset-names = "reset-m\0reset-h"; + pinctrl-names = "default"; + pinctrl-0 = <0x40 0x41 0x42 0x43>; + status = "disabled"; + phandle = <0xd3>; + }; + + pdm@ff0a0000 { + compatible = "rockchip,px30-pdm\0rockchip,pdm"; + reg = <0x00 0xff0a0000 0x00 0x1000>; + clocks = <0x02 0x0f 0x02 0x105>; + clock-names = "pdm_clk\0pdm_hclk"; + dmas = <0x2b 0x18>; + dma-names = "rx"; + resets = <0x02 0x82>; + reset-names = "pdm-m"; + pinctrl-names = "default"; + pinctrl-0 = <0x44 0x45 0x46 0x47 0x48 0x49>; + status = "disabled"; + phandle = <0xd4>; + }; + + crypto@ff0b0000 { + compatible = "rockchip,px30-crypto"; + reg = <0x00 0xff0b0000 0x00 0x4000>; + interrupts = <0x00 0x52 0x04>; + clocks = <0x02 0xac 0x02 0xf1 0x02 0x30 0x02 0x31>; + clock-names = "aclk\0hclk\0sclk\0apb_pclk"; + resets = <0x02 0x74>; + reset-names = "crypto-rst"; + status = "disabled"; + phandle = <0xd5>; + }; + + rng@ff0b0000 { + compatible = "rockchip,cryptov2-rng"; + reg = <0x00 0xff0b0000 0x00 0x4000>; + clocks = <0x02 0x30 0x02 0x31 0x02 0xac 0x02 0xf1>; + clock-names = "clk_crypto\0clk_crypto_apk\0aclk_crypto\0hclk_crypto"; + assigned-clocks = <0x02 0x30 0x02 0x31 0x02 0xac 0x02 0xf1>; + assigned-clock-rates = <0x8f0d180 0x8f0d180 0xbebc200 0x5f5e100>; + resets = <0x02 0x74>; + reset-names = "reset"; + status = "okay"; + phandle = <0xd6>; + }; + + interrupt-controller@ff131000 { + compatible = "arm,gic-400"; + #interrupt-cells = <0x03>; + #address-cells = <0x00>; + interrupt-controller; + reg = <0x00 0xff131000 0x00 0x1000 0x00 0xff132000 0x00 0x2000 0x00 0xff134000 0x00 0x2000 0x00 0xff136000 0x00 0x2000>; + interrupts = <0x01 0x09 0xf04>; + phandle = <0x01>; + }; + + syscon@ff140000 { + compatible = "rockchip,px30-grf\0syscon\0simple-mfd"; + reg = <0x00 0xff140000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0x2f>; + + io-domains { + compatible = "rockchip,px30-io-voltage-domain"; + status = "okay"; + vccio1-supply = <0x4a>; + vccio2-supply = <0x4a>; + vccio3-supply = <0x4b>; + vccio4-supply = <0x4b>; + vccio5-supply = <0x4b>; + vccio6-supply = <0x4b>; + phandle = <0xd7>; + }; + + lvds { + compatible = "rockchip,px30-lvds"; + phys = <0x4c>; + phy-names = "phy"; + status = "disabled"; + phandle = <0xd8>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x12>; + phandle = <0xa2>; + }; + }; + }; + }; + + rgb { + compatible = "rockchip,px30-rgb"; + pinctrl-names = "default\0sleep"; + pinctrl-0 = <0x4d>; + pinctrl-1 = <0x4e>; + status = "disabled"; + phys = <0x4c>; + phy-names = "phy"; + phandle = <0xd9>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x14>; + phandle = <0xa4>; + }; + }; + }; + }; + }; + + syscon@ff148000 { + compatible = "syscon\0simple-mfd"; + reg = <0x00 0xff148000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0xda>; + + pvtm { + compatible = "rockchip,px30-pvtm"; + clocks = <0x02 0x4a>; + clock-names = "core"; + status = "okay"; + phandle = <0xdb>; + }; + }; + + serial@ff158000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff158000 0x00 0x100>; + interrupts = <0x00 0x10 0x04>; + clocks = <0x02 0x18 0x02 0x149>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x02 0x2b 0x03>; + pinctrl-names = "default"; + pinctrl-0 = <0x4f 0x50>; + status = "okay"; + phandle = <0xdc>; + }; + + serial@ff160000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff160000 0x00 0x100>; + interrupts = <0x00 0x11 0x04>; + clocks = <0x02 0x19 0x02 0x14a>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x04 0x2b 0x05>; + pinctrl-names = "default"; + pinctrl-0 = <0x51>; + status = "disabled"; + phandle = <0xdd>; + }; + + serial@ff168000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff168000 0x00 0x100>; + interrupts = <0x00 0x12 0x04>; + clocks = <0x02 0x1a 0x02 0x14b>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x06 0x2b 0x07>; + pinctrl-names = "default"; + pinctrl-0 = <0x52 0x53 0x54>; + status = "disabled"; + phandle = <0xde>; + }; + + serial@ff170000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff170000 0x00 0x100>; + interrupts = <0x00 0x13 0x04>; + clocks = <0x02 0x1b 0x02 0x14c>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x08 0x2b 0x09>; + pinctrl-names = "default"; + pinctrl-0 = <0x55 0x56 0x57>; + status = "disabled"; + phandle = <0xdf>; + }; + + serial@ff178000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff178000 0x00 0x100>; + interrupts = <0x00 0x14 0x04>; + clocks = <0x02 0x1c 0x02 0x14d>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x0a 0x2b 0x0b>; + pinctrl-names = "default"; + pinctrl-0 = <0x58 0x59 0x5a>; + status = "disabled"; + phandle = <0xe0>; + }; + + i2c@ff180000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff180000 0x00 0x1000>; + clocks = <0x02 0x1d 0x02 0x14e>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x07 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x5b>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + clock-frequency = <0x61a80>; + i2c-scl-rising-time-ns = <0x118>; + i2c-scl-falling-time-ns = <0x10>; + phandle = <0xe1>; + + pmic@20 { + compatible = "rockchip,rk817"; + reg = <0x20>; + interrupt-parent = <0x5c>; + interrupts = <0x0a 0x08>; + pinctrl-names = "default\0pmic-sleep\0pmic-power-off\0pmic-reset"; + pinctrl-0 = <0x5d>; + pinctrl-1 = <0x5e 0x5f>; + pinctrl-2 = <0x60 0x61>; + pinctrl-3 = <0x62 0x63>; + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <0x01>; + clock-output-names = "rk808-clkout1\0rk808-clkout2"; + pmic-reset-func = <0x01>; + vcc1-supply = <0x64>; + vcc2-supply = <0x64>; + vcc3-supply = <0x64>; + vcc4-supply = <0x64>; + vcc5-supply = <0x64>; + vcc6-supply = <0x64>; + vcc7-supply = <0x64>; + vcc8-supply = <0x64>; + vcc9-supply = <0x65>; + phandle = <0xe2>; + + pwrkey { + status = "okay"; + }; + + pinctrl_rk8xx { + gpio-controller; + #gpio-cells = <0x02>; + phandle = <0xe3>; + + rk817_ts_gpio1 { + pins = "gpio_ts"; + function = "pin_fun1"; + phandle = <0xe4>; + }; + + rk817_gt_gpio2 { + pins = "gpio_gt"; + function = "pin_fun1"; + phandle = <0xe5>; + }; + + rk817_pin_ts { + pins = "gpio_ts"; + function = "pin_fun0"; + phandle = <0xe6>; + }; + + rk817_pin_gt { + pins = "gpio_gt"; + function = "pin_fun0"; + phandle = <0xe7>; + }; + + rk817_slppin_null { + pins = "gpio_slp"; + function = "pin_fun0"; + phandle = <0xe8>; + }; + + rk817_slppin_slp { + pins = "gpio_slp"; + function = "pin_fun1"; + phandle = <0x5f>; + }; + + rk817_slppin_pwrdn { + pins = "gpio_slp"; + function = "pin_fun2"; + phandle = <0x61>; + }; + + rk817_slppin_rst { + pins = "gpio_slp"; + function = "pin_fun3"; + phandle = <0x63>; + }; + }; + + regulators { + + DCDC_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xe7ef0>; + regulator-max-microvolt = <0x118c30>; + regulator-ramp-delay = <0x1771>; + regulator-initial-mode = <0x02>; + regulator-name = "vdd_logic"; + phandle = <0x0e>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0xe7ef0>; + }; + }; + + DCDC_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xe7ef0>; + regulator-max-microvolt = <0x149970>; + regulator-ramp-delay = <0x1771>; + regulator-initial-mode = <0x02>; + regulator-name = "vdd_arm"; + phandle = <0x06>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0xe7ef0>; + }; + }; + + DCDC_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x02>; + regulator-name = "vcc_ddr"; + phandle = <0xe9>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + DCDC_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-initial-mode = <0x02>; + regulator-name = "vcc_3v3"; + phandle = <0x4b>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG1 { + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + regulator-name = "vcc_1v0"; + phandle = <0xea>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0xf4240>; + }; + }; + + LDO_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + regulator-name = "vcc1v8_soc"; + phandle = <0x88>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x1b7740>; + }; + }; + + LDO_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + regulator-name = "vcc1v0_soc"; + phandle = <0xeb>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0xf4240>; + }; + }; + + LDO_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "vcc3v3_pmu"; + phandle = <0x29>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + regulator-name = "vccio_sd"; + phandle = <0x4a>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x1b7740>; + }; + }; + + LDO_REG6 { + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x2dc6c0>; + regulator-boot-on; + regulator-name = "vcc_sd"; + phandle = <0x93>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x2dc6c0>; + }; + }; + + LDO_REG7 { + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "vcc_backlight"; + phandle = <0x9e>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG8 { + regulator-min-microvolt = <0x2ab980>; + regulator-max-microvolt = <0x2ab980>; + regulator-name = "vcc_lcd"; + phandle = <0x9f>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x2ab980>; + }; + }; + + BOOST { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x4c4b40>; + regulator-max-microvolt = <0x5265c0>; + regulator-name = "boost"; + phandle = <0x65>; + }; + + OTG_SWITCH { + regulator-boot-on; + regulator-name = "otg_switch"; + phandle = <0xec>; + }; + }; + + battery { + compatible = "rk817,battery"; + ocv_table = <0xc5d 0xc94 0xcd0 0xd02 0xd34 0xd66 0xd98 0xdca 0xdfc 0xe2e 0xe56 0xe7e 0xea6 0xece 0xef6 0xf1e 0xf46 0xf6e 0xf96 0xf9b 0xfa0>; + design_capacity = <0xd34>; + design_qmax = <0xe86>; + bat_res = <0x64>; + sleep_enter_current = <0x12c>; + sleep_exit_current = <0x12c>; + sleep_filter_current = <0x64>; + power_off_thresd = <0xbb8>; + zero_algorithm_vol = <0xf0a>; + max_soc_offset = <0x3c>; + monitor_sec = <0x05>; + virtual_power = <0x00>; + sample_res = <0x0a>; + }; + + charger { + compatible = "rk817,charger"; + min_input_voltage = <0x1194>; + max_input_current = <0x5dc>; + max_chrg_current = <0x7d0>; + max_chrg_voltage = <0x1068>; + chrg_term_mode = <0x00>; + chrg_finish_cur = <0x34>; + virtual_power = <0x00>; + sample_res = <0x0a>; + dc_det_gpio = <0x5c 0x0b 0x00>; + bat_low_gpio = <0x66 0x0d 0x00>; + extcon = <0x67>; + }; + + codec { + #sound-dai-cells = <0x00>; + compatible = "rockchip,rk817-codec"; + clocks = <0x02 0x15>; + clock-names = "mclk"; + pinctrl-names = "default"; + pinctrl-0 = <0x68>; + hp-volume = <0x14>; + spk-volume = <0x03>; + status = "okay"; + phandle = <0xc3>; + }; + }; + }; + + i2c@ff190000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff190000 0x00 0x1000>; + clocks = <0x02 0x1e 0x02 0x14f>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x08 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x69>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + clock-frequency = <0x61a80>; + phandle = <0xed>; + }; + + i2c@ff1a0000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff1a0000 0x00 0x1000>; + clocks = <0x02 0x1f 0x02 0x150>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x09 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x6a>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xee>; + }; + + i2c@ff1b0000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff1b0000 0x00 0x1000>; + clocks = <0x02 0x20 0x02 0x151>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x0a 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x6b>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xef>; + }; + + spi@ff1d0000 { + compatible = "rockchip,px30-spi\0rockchip,rk3066-spi"; + reg = <0x00 0xff1d0000 0x00 0x1000>; + interrupts = <0x00 0x1a 0x04>; + #address-cells = <0x01>; + #size-cells = <0x00>; + clocks = <0x02 0x24 0x02 0x155>; + clock-names = "spiclk\0apb_pclk"; + dmas = <0x2b 0x0c 0x2b 0x0d>; + dma-names = "tx\0rx"; + pinctrl-names = "default\0high_speed"; + pinctrl-0 = <0x6c 0x6d 0x6e 0x6f>; + pinctrl-1 = <0x70 0x6d 0x71 0x72>; + status = "disabled"; + phandle = <0xf0>; + }; + + spi@ff1d8000 { + compatible = "rockchip,px30-spi\0rockchip,rk3066-spi"; + reg = <0x00 0xff1d8000 0x00 0x1000>; + interrupts = <0x00 0x1b 0x04>; + #address-cells = <0x01>; + #size-cells = <0x00>; + clocks = <0x02 0x25 0x02 0x156>; + clock-names = "spiclk\0apb_pclk"; + dmas = <0x2b 0x0e 0x2b 0x0f>; + dma-names = "tx\0rx"; + pinctrl-names = "default\0high_speed"; + pinctrl-0 = <0x73 0x74 0x75 0x76 0x77>; + pinctrl-1 = <0x78 0x74 0x75 0x79 0x7a>; + status = "disabled"; + phandle = <0xf1>; + }; + + watchdog@ff1e0000 { + compatible = "snps,dw-wdt"; + reg = <0x00 0xff1e0000 0x00 0x100>; + clocks = <0x02 0x15b>; + interrupts = <0x00 0x25 0x04>; + resets = <0x02 0xb5>; + reset-names = "reset"; + status = "disabled"; + phandle = <0xf2>; + }; + + pwm@ff200000 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200000 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7b>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "okay"; + phandle = <0xbc>; + }; + + pwm@ff200010 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200010 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7c>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "okay"; + phandle = <0xc1>; + }; + + pwm@ff200020 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200020 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7d>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf3>; + }; + + pwm@ff200030 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200030 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7e>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf4>; + }; + + pwm@ff208000 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208000 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7f>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf5>; + }; + + pwm@ff208010 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208010 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x80>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf6>; + }; + + pwm@ff208020 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208020 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x81>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf7>; + }; + + pwm@ff208030 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208030 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x82>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf8>; + }; + + rktimer@ff210000 { + compatible = "rockchip,rk3288-timer"; + reg = <0x00 0xff210000 0x00 0x1000>; + interrupts = <0x00 0x1e 0x04>; + clocks = <0x02 0x159 0x02 0x26>; + clock-names = "pclk\0timer"; + phandle = <0xf9>; + }; + + amba { + compatible = "simple-bus"; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + + dmac@ff240000 { + compatible = "arm,pl330\0arm,primecell"; + reg = <0x00 0xff240000 0x00 0x4000>; + interrupts = <0x00 0x01 0x04 0x00 0x02 0x04>; + clocks = <0x02 0xbb>; + clock-names = "apb_pclk"; + #dma-cells = <0x01>; + peripherals-req-type-burst; + phandle = <0x2b>; + }; + }; + + thermal-zones { + phandle = <0xfa>; + + soc-thermal { + polling-delay-passive = <0x14>; + polling-delay = <0x3e8>; + sustainable-power = <0x2ee>; + thermal-sensors = <0x83 0x00>; + phandle = <0xfb>; + + trips { + + trip-point-0 { + temperature = <0x11170>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0xfc>; + }; + + trip-point-1 { + temperature = <0x14c08>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0x84>; + }; + + soc-crit { + temperature = <0x1c138>; + hysteresis = <0x7d0>; + type = "critical"; + phandle = <0xfd>; + }; + }; + + cooling-maps { + + map0 { + trip = <0x84>; + cooling-device = <0x09 0xffffffff 0xffffffff>; + contribution = <0x1000>; + }; + + map1 { + trip = <0x84>; + cooling-device = <0x85 0xffffffff 0xffffffff>; + contribution = <0x1000>; + }; + }; + }; + + gpu-thermal { + polling-delay-passive = <0x64>; + polling-delay = <0x3e8>; + thermal-sensors = <0x83 0x01>; + phandle = <0xfe>; + }; + }; + + tsadc@ff280000 { + compatible = "rockchip,px30-tsadc"; + reg = <0x00 0xff280000 0x00 0x100>; + interrupts = <0x00 0x24 0x04>; + rockchip,grf = <0x2f>; + clocks = <0x02 0x2c 0x02 0x158>; + clock-names = "tsadc\0apb_pclk"; + assigned-clocks = <0x02 0x2c>; + assigned-clock-rates = <0xc350>; + resets = <0x02 0xa8>; + reset-names = "tsadc-apb"; + #thermal-sensor-cells = <0x01>; + rockchip,hw-tshut-temp = <0x1d4c0>; + status = "okay"; + pinctrl-names = "gpio\0otpout"; + pinctrl-0 = <0x86>; + pinctrl-1 = <0x87>; + phandle = <0x83>; + }; + + saradc@ff288000 { + compatible = "rockchip,px30-saradc\0rockchip,rk3399-saradc"; + reg = <0x00 0xff288000 0x00 0x100>; + interrupts = <0x00 0x54 0x04>; + #io-channel-cells = <0x01>; + clocks = <0x02 0x2d 0x02 0x157>; + clock-names = "saradc\0apb_pclk"; + resets = <0x02 0xa5>; + reset-names = "saradc-apb"; + status = "okay"; + vref-supply = <0x88>; + phandle = <0xbe>; + }; + + otp@ff290000 { + compatible = "rockchip,px30-otp"; + reg = <0x00 0xff290000 0x00 0x4000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + clocks = <0x02 0x2f 0x02 0x15a 0x02 0x161>; + clock-names = "clk_otp\0pclk_otp\0pclk_otp_phy"; + resets = <0x02 0xb4>; + reset-names = "otp_phy"; + phandle = <0xff>; + + id@7 { + reg = <0x07 0x10>; + phandle = <0x0f>; + }; + + cpu-leakage@17 { + reg = <0x17 0x01>; + phandle = <0x07>; + }; + + performance@1e { + reg = <0x1e 0x01>; + bits = <0x04 0x03>; + phandle = <0x08>; + }; + }; + + clock-controller@ff2b0000 { + compatible = "rockchip,px30-cru"; + reg = <0x00 0xff2b0000 0x00 0x1000>; + rockchip,grf = <0x2f>; + rockchip,boost = <0x89>; + #clock-cells = <0x01>; + #reset-cells = <0x01>; + assigned-clocks = <0x02 0x04>; + assigned-clock-rates = <0x3dfd2400>; + phandle = <0x02>; + }; + + cpu-boost@ff2b8000 { + compatible = "syscon"; + reg = <0x00 0xff2b8000 0x00 0x1000>; + rockchip,boost-low-con0 = <0x1032>; + rockchip,boost-low-con1 = <0x1441>; + rockchip,boost-high-con0 = <0x1036>; + rockchip,boost-high-con1 = <0x1441>; + rockchip,boost-backup-pll = <0x01>; + rockchip,boost-backup-pll-usage = <0x00>; + rockchip,boost-switch-threshold = <0x249f00>; + rockchip,boost-statis-threshold = <0x100>; + rockchip,boost-statis-enable = <0x00>; + rockchip,boost-enable = <0x00>; + phandle = <0x89>; + }; + + pmu-clock-controller@ff2bc000 { + compatible = "rockchip,px30-pmucru"; + reg = <0x00 0xff2bc000 0x00 0x1000>; + rockchip,grf = <0x2f>; + #clock-cells = <0x01>; + #reset-cells = <0x01>; + assigned-clocks = <0x2a 0x01 0x2a 0x08 0x2a 0x05 0x02 0x07 0x02 0xab 0x02 0xb0 0x02 0xf0 0x02 0xf5 0x02 0x140 0x02 0x49>; + assigned-clock-rates = <0x47868c00 0x5f5e100 0x18cba80 0x23c34600 0xbebc200 0xbebc200 0x8f0d180 0x8f0d180 0x5f5e100 0xbebc200>; + phandle = <0x2a>; + }; + + syscon@ff2c0000 { + compatible = "rockchip,px30-usb2phy-grf\0syscon\0simple-mfd"; + reg = <0x00 0xff2c0000 0x00 0x10000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0x100>; + + usb2-phy@100 { + compatible = "rockchip,px30-usb2phy\0rockchip,rk3328-usb2phy"; + reg = <0x100 0x10>; + clocks = <0x2a 0x0a>; + clock-names = "phyclk"; + #clock-cells = <0x00>; + assigned-clocks = <0x02 0x0e 0x02 0x55>; + assigned-clock-parents = <0x67 0x02 0x0e>; + clock-output-names = "usb480m_phy"; + status = "okay"; + phandle = <0x67>; + + host-port { + #phy-cells = <0x00>; + interrupts = <0x00 0x44 0x04>; + interrupt-names = "linestate"; + status = "okay"; + phandle = <0x8c>; + }; + + otg-port { + #phy-cells = <0x00>; + interrupts = <0x00 0x42 0x04 0x00 0x41 0x04 0x00 0x40 0x04>; + interrupt-names = "otg-bvalid\0otg-id\0linestate"; + status = "disabled"; + phandle = <0x8b>; + }; + }; + }; + + video-phy@ff2e0000 { + compatible = "rockchip,px30-video-phy"; + reg = <0x00 0xff2e0000 0x00 0x10000 0x00 0xff450000 0x00 0x10000>; + clocks = <0x2a 0x0b 0x02 0x145 0x02 0x144>; + clock-names = "ref\0pclk_phy\0pclk_host"; + #clock-cells = <0x00>; + resets = <0x02 0x3e>; + reset-names = "rst"; + power-domains = <0x8a 0x0c>; + #phy-cells = <0x00>; + status = "okay"; + phandle = <0x4c>; + }; + + mipi-dphy-rx0@ff2f0000 { + compatible = "rockchip,rk3326-mipi-dphy"; + reg = <0x00 0xff2f0000 0x00 0x4000>; + clocks = <0x02 0x146>; + clock-names = "dphy-ref"; + power-domains = <0x8a 0x0d>; + rockchip,grf = <0x2f>; + status = "okay"; + phandle = <0x101>; + }; + + usb@ff300000 { + compatible = "rockchip,px30-usb\0rockchip,rk3066-usb\0snps,dwc2"; + reg = <0x00 0xff300000 0x00 0x40000>; + interrupts = <0x00 0x3e 0x04>; + clocks = <0x02 0x102>; + clock-names = "otg"; + power-domains = <0x8a 0x05>; + dr_mode = "otg"; + g-np-tx-fifo-size = <0x10>; + g-rx-fifo-size = <0x118>; + g-tx-fifo-size = <0x100 0x80 0x80 0x40 0x20 0x10>; + g-use-dma; + phys = <0x8b>; + phy-names = "usb2-phy"; + status = "okay"; + phandle = <0x102>; + vbus-supply = <&vcc_host>; + }; + + usb@ff340000 { + compatible = "generic-ehci"; + reg = <0x00 0xff340000 0x00 0x10000>; + interrupts = <0x00 0x3c 0x04>; + clocks = <0x02 0x103 0x67>; + clock-names = "usbhost\0utmi"; + power-domains = <0x8a 0x05>; + phys = <0x8c>; + phy-names = "usb"; + status = "disabled"; + phandle = <0x103>; + }; + + usb@ff350000 { + compatible = "generic-ohci"; + reg = <0x00 0xff350000 0x00 0x10000>; + interrupts = <0x00 0x3d 0x04>; + clocks = <0x02 0x103 0x67>; + clock-names = "usbhost\0utmi"; + power-domains = <0x8a 0x05>; + phys = <0x8c>; + phy-names = "usb"; + status = "disabled"; + phandle = <0x104>; + }; + + ethernet@ff360000 { + compatible = "rockchip,px30-gmac"; + reg = <0x00 0xff360000 0x00 0x10000>; + rockchip,grf = <0x2f>; + interrupts = <0x00 0x2b 0x04>; + interrupt-names = "macirq"; + clocks = <0x02 0x3e 0x02 0x3f 0x02 0x3f 0x02 0x40 0x02 0x41 0x02 0xb2 0x02 0x143 0x02 0x4c>; + clock-names = "stmmaceth\0mac_clk_rx\0mac_clk_tx\0clk_mac_ref\0clk_mac_refout\0aclk_mac\0pclk_mac\0clk_mac_speed"; + phy-mode = "rmii"; + pinctrl-names = "default"; + pinctrl-0 = <0x8d 0x8e>; + resets = <0x02 0x5e>; + reset-names = "stmmaceth"; + power-domains = <0x8a 0x09>; + status = "disabled"; + phandle = <0x105>; + }; + + dwmmc@ff370000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff370000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0xf7 0x02 0x3b 0x02 0x43 0x02 0x44>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x3b>; + assigned-clock-parents = <0x02 0x57>; + power-domains = <0x8a 0x07>; + fifo-depth = <0x100>; + interrupts = <0x00 0x36 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x8f 0x90 0x91 0x92>; + status = "okay"; + bus-width = <0x04>; + cap-mmc-highspeed; + cap-sd-highspeed; + supports-sd; + card-detect-delay = <0x320>; + ignore-pm-notify; + cd-gpios = <0x5c 0x03 0x01>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <0x4a>; + vmmc-supply = <0x93>; + phandle = <0x106>; + }; + + dwmmc@ff380000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff380000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0xff 0x02 0x38 0x02 0x45 0x02 0x46>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x38>; + assigned-clock-parents = <0x02 0x51>; + power-domains = <0x8a 0x0a>; + fifo-depth = <0x100>; + interrupts = <0x00 0x37 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x94 0x95 0x96>; + status = "okay"; + bus-width = <0x04>; + cap-mmc-highspeed; + cap-sd-highspeed; + supports-sd; + card-detect-delay = <0x320>; + ignore-pm-notify; + cd-gpios = <0x97 0x0e 0x01>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <0x4a>; + vmmc-supply = <0x93>; + phandle = <0x107>; + }; + + dwmmc@ff390000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff390000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0x100 0x02 0x39 0x02 0x47 0x02 0x48>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x39>; + assigned-clock-parents = <0x02 0x53>; + power-domains = <0x8a 0x0a>; + fifo-depth = <0x100>; + interrupts = <0x00 0x35 0x04>; + status = "disabled"; + phandle = <0x108>; + }; + + nandc@ff3b0000 { + compatible = "rockchip,rk-nandc"; + reg = <0x00 0xff3b0000 0x00 0x4000>; + interrupts = <0x00 0x39 0x04>; + nandc_id = <0x00>; + clocks = <0x02 0x37 0x02 0xfe>; + clock-names = "clk_nandc\0hclk_nandc"; + assigned-clocks = <0x02 0x37>; + assigned-clock-parents = <0x02 0x4f>; + power-domains = <0x8a 0x0a>; + status = "disabled"; + phandle = <0x109>; + }; + + sfc@ff3a0000 { + compatible = "rockchip,sfc"; + reg = <0x00 0xff3a0000 0x00 0x4000>; + interrupts = <0x00 0x38 0x04>; + clocks = <0x02 0x3a 0x02 0x101>; + clock-names = "clk_sfc\0hclk_sfc"; + assigned-clocks = <0x02 0x3a>; + assigned-clock-rates = <0x989680>; + status = "disabled"; + phandle = <0x10a>; + }; + + gpu@ff400000 { + compatible = "arm,malit602\0arm,malit60x\0arm,malit6xx\0arm,mali-midgard"; + reg = <0x00 0xff400000 0x00 0x4000>; + interrupts = <0x00 0x2d 0x04 0x00 0x2e 0x04 0x00 0x2f 0x04>; + interrupt-names = "GPU\0MMU\0JOB"; + clocks = <0x02 0x49>; + clock-names = "clk_mali"; + power-domains = <0x8a 0x0e>; + #cooling-cells = <0x02>; + operating-points-v2 = <0x98>; + status = "okay"; + mali-supply = <0x0e>; + phandle = <0x85>; + + power_model { + compatible = "arm,mali-simple-power-model"; + static-coefficient = <0x64578>; + dynamic-coefficient = <0x2dd>; + ts = <0x7d00 0x125c 0xffffffb0 0x02>; + thermal-zone = "gpu-thermal"; + }; + }; + + gpu-opp-table { + compatible = "operating-points-v2"; + rockchip,thermal-zone = "soc-thermal"; + rockchip,temp-hysteresis = <0x1388>; + rockchip,low-temp = <0x00>; + rockchip,low-temp-min-volt = <0xf4240>; + rockchip,low-temp-adjust-volt = <0x00 0x1e0 0xc350>; + rockchip,max-volt = <0x11edd8>; + rockchip,evb-irdrop = <0x61a8>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-ch = <0x00 0x00>; + phandle = <0x98>; + + opp-400000000 { + opp-hz = <0x00 0x17d78400>; + opp-microvolt = <0x100590>; + opp-microvolt-L0 = <0x100590>; + opp-microvolt-L1 = <0xfa3e8>; + opp-microvolt-L2 = <0xee098>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-480000000 { + opp-hz = <0x00 0x1c9c3800>; + opp-microvolt = <0x112a88>; + opp-microvolt-L0 = <0x112a88>; + opp-microvolt-L1 = <0x10c8e0>; + opp-microvolt-L2 = <0x100590>; + opp-microvolt-L3 = <0xf4240>; + }; + + opp-520000000 { + opp-hz = <0x00 0x1efe9200>; + opp-microvolt = <0x118c30>; + opp-microvolt-L0 = <0x118c30>; + opp-microvolt-L1 = <0x118c30>; + opp-microvolt-L2 = <0x10c8e0>; + opp-microvolt-L3 = <0x100590>; + }; + }; + + hevc_service@ff440000 { + compatible = "rockchip,hevc_sub"; + iommu_enabled = <0x01>; + reg = <0x00 0xff440000 0x00 0x400>; + interrupts = <0x00 0x31 0x04>; + interrupt-names = "irq_dec"; + dev_mode = <0x01>; + iommus = <0x99>; + allocator = <0x01>; + phandle = <0x9c>; + }; + + vpu_service@ff442000 { + compatible = "rockchip,vpu_sub"; + iommu_enabled = <0x01>; + reg = <0x00 0xff442000 0x00 0x800>; + interrupts = <0x00 0x50 0x04 0x00 0x4f 0x04>; + interrupt-names = "irq_enc\0irq_dec"; + dev_mode = <0x00>; + iommus = <0x9a>; + allocator = <0x01>; + phandle = <0x9b>; + }; + + vpu_combo { + compatible = "rockchip,vpu_combo"; + subcnt = <0x02>; + rockchip,grf = <0x2f>; + rockchip,sub = <0x9b 0x9c>; + clocks = <0x02 0xaf 0x02 0xf4 0x02 0x4b>; + clock-names = "aclk_vcodec\0hclk_vcodec\0clk_core"; + resets = <0x02 0x24 0x02 0x26 0x02 0x25 0x02 0x27 0x02 0x3f>; + reset-names = "video_a\0video_h\0niu_a\0niu_h\0video_core"; + power-domains = <0x8a 0x0b>; + mode_bit = <0x0f>; + mode_ctrl = <0x410>; + status = "okay"; + phandle = <0x10b>; + }; + + iommu@ff440440 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff440440 0x00 0x40 0x00 0xff440480 0x00 0x40>; + interrupts = <0x00 0x32 0x04>; + interrupt-names = "hevc_mmu"; + clocks = <0x02 0xaf 0x02 0xf4>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0b>; + #iommu-cells = <0x00>; + phandle = <0x99>; + }; + + iommu@ff442800 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff442800 0x00 0x100>; + interrupts = <0x00 0x51 0x04>; + interrupt-names = "vpu_mmu"; + clocks = <0x02 0xaf 0x02 0xf4>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0b>; + #iommu-cells = <0x00>; + phandle = <0x9a>; + }; + + dsi@ff450000 { + compatible = "rockchip,px30-mipi-dsi"; + reg = <0x00 0xff450000 0x00 0x10000>; + interrupts = <0x00 0x4b 0x04>; + clocks = <0x02 0x144 0x4c>; + clock-names = "pclk\0hs_clk"; + resets = <0x02 0x3d>; + reset-names = "apb"; + phys = <0x4c>; + phy-names = "mipi_dphy"; + power-domains = <0x8a 0x0c>; + rockchip,grf = <0x2f>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + phandle = <0x10c>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x13>; + status = "okay"; + phandle = <0xa3>; + }; + }; + }; + + panel@0 { + compatible = "elida,kd35t133\0simple-panel-dsi"; + reg = <0x00>; + backlight = <0x9d>; + backlight-supply = <0x9e>; + power-supply = <0x9f>; + reset-gpios = <0x97 0x10 0x01>; + reset-delay-ms = <0x96>; + init-delay-ms = <0x14>; + enable-delay-ms = <0x78>; + prepare-delay-ms = <0x14>; + unprepare-delay-ms = <0x14>; + disable-delay-ms = <0x32>; + width-mm = <0x34>; + height-mm = <0x46>; + dsi,flags = <0xa03>; + dsi,format = <0x00>; + dsi,lanes = <0x04>; + panel-init-sequence = [15 00 02 ff 30 15 00 02 ff 52 15 00 02 ff 01 15 00 02 e3 00 15 00 02 25 10 15 00 02 28 6f 15 00 02 29 01 15 00 02 2a df 15 00 02 2c 22 15 00 02 c3 0f 15 00 02 37 9c 15 00 02 38 a7 15 00 02 39 41 15 00 02 80 20 15 00 02 91 67 15 00 02 92 67 15 00 02 a0 55 15 00 02 a1 50 15 00 02 a3 58 15 00 02 a4 9c 15 00 02 a7 02 15 00 02 a8 01 15 00 02 a9 21 15 00 02 aa fc 15 00 02 ab 28 15 00 02 ac 06 15 00 02 ad 06 15 00 02 ae 06 15 00 02 af 03 15 00 02 b0 08 15 00 02 b1 26 15 00 02 b2 28 15 00 02 b3 28 15 00 02 b4 03 15 00 02 b5 08 15 00 02 b6 26 15 00 02 b7 08 15 00 02 b8 26 15 00 02 2c 22 15 00 02 5c 40 15 00 02 c0 00 15 00 02 c1 00 15 00 02 c2 00 15 00 02 ff 30 15 00 02 ff 52 15 00 02 ff 02 15 00 02 b0 02 15 00 02 d0 02 15 00 02 b1 0f 15 00 02 d1 10 15 00 02 b2 11 15 00 02 d2 12 15 00 02 b3 32 15 00 02 d3 33 15 00 02 b4 36 15 00 02 d4 36 15 00 02 b5 3c 15 00 02 d5 3c 15 00 02 b6 20 15 00 02 d6 20 15 00 02 b7 3e 15 00 02 d7 3e 15 00 02 b8 0e 15 00 02 d8 0d 15 00 02 b9 05 15 00 02 d9 05 15 00 02 ba 11 15 00 02 da 12 15 00 02 bb 11 15 00 02 db 11 15 00 02 bc 13 15 00 02 dc 14 15 00 02 bd 14 15 00 02 dd 14 15 00 02 be 16 15 00 02 de 18 15 00 02 bf 0e 15 00 02 df 0f 15 00 02 c0 17 15 00 02 e0 17 15 00 02 c1 07 15 00 02 e1 08 15 00 02 ff 30 15 00 02 ff 52 15 00 02 ff 03 15 00 02 08 8a 15 00 02 09 8b 15 00 02 30 00 15 00 02 31 00 15 00 02 32 00 15 00 02 33 00 15 00 02 34 61 15 00 02 35 d4 15 00 02 36 24 15 00 02 37 03 15 00 02 40 86 15 00 02 41 87 15 00 02 42 84 15 00 02 43 85 15 00 02 44 11 15 00 02 45 de 15 00 02 46 dd 15 00 02 47 11 15 00 02 48 e0 15 00 02 49 df 15 00 02 50 82 15 00 02 51 83 15 00 02 52 80 15 00 02 53 81 15 00 02 54 11 15 00 02 55 e2 15 00 02 56 e1 15 00 02 57 11 15 00 02 58 e4 15 00 02 59 e3 15 00 02 82 0f 15 00 02 83 0f 15 00 02 84 00 15 00 02 85 0f 15 00 02 86 0f 15 00 02 87 0e 15 00 02 88 0e 15 00 02 89 06 15 00 02 8a 06 15 00 02 8b 07 15 00 02 8c 07 15 00 02 8d 04 15 00 02 8e 04 15 00 02 8f 05 15 00 02 90 05 15 00 02 98 0f 15 00 02 99 0f 15 00 02 9a 00 15 00 02 9b 0f 15 00 02 9c 0f 15 00 02 9d 0e 15 00 02 9e 0e 15 00 02 9f 06 15 00 02 a0 06 15 00 02 a1 07 15 00 02 a2 07 15 00 02 a3 04 15 00 02 a4 04 15 00 02 a5 05 15 00 02 a6 05 15 00 02 e0 02 15 00 02 e1 52 15 00 02 ff 30 15 00 02 ff 52 15 00 02 ff 00 15 00 02 36 02 05 c8 01 11 05 14 01 29]; + panel-exit-sequence = <0x5140128 0x50a0110>; + + display-timings { + native-mode = <0xa0>; + + 60Hz { + clock-frequency = <0x3750280>; + hactive = <0x280>; + vactive = <0x1e0>; + hfront-porch = <0x12c>; + hsync-len = <0xc8>; + hback-porch = <0x12c>; + vfront-porch = <0x11>; + vsync-len = <0x05>; + vback-porch = <0x0d>; + hsync-active = <0x00>; + vsync-active = <0x00>; + de-active = <0x00>; + pixelclk-active = <0x01>; + phandle = <0xa0>; + }; + + 50Hz { + clock-frequency = <0x3750280>; + hactive = <0x280>; + vactive = <0x1e0>; + hfront-porch = <0x12c>; + hsync-len = <0xc8>; + hback-porch = <0x12c>; + vfront-porch = <0x11>; + vsync-len = <0x05>; + vback-porch = <0x0d>; + hsync-active = <0x00>; + vsync-active = <0x00>; + de-active = <0x00>; + pixelclk-active = <0x01>; + phandle = <0xa00>; + }; + + 75Hz { + clock-frequency = <0x3750280>; + hactive = <0x280>; + vactive = <0x1e0>; + hfront-porch = <0x12c>; + hsync-len = <0xc8>; + hback-porch = <0x12c>; + vfront-porch = <0x11>; + vsync-len = <0x05>; + vback-porch = <0x0d>; + hsync-active = <0x00>; + vsync-active = <0x00>; + de-active = <0x00>; + pixelclk-active = <0x01>; + phandle = <0xa01>; + }; + }; + }; + }; + + vop@ff460000 { + compatible = "rockchip,px30-vop-big"; + reg = <0x00 0xff460000 0x00 0x1fc 0x00 0xff460a00 0x00 0x400>; + rockchip,grf = <0x2f>; + reg-names = "regs\0gamma_lut"; + interrupts = <0x00 0x4d 0x04>; + clocks = <0x02 0xb5 0x02 0x96 0x02 0xfb>; + clock-names = "aclk_vop\0dclk_vop\0hclk_vop"; + power-domains = <0x8a 0x0c>; + iommus = <0xa1>; + status = "okay"; + phandle = <0x10f>; + + port { + #address-cells = <0x01>; + #size-cells = <0x00>; + phandle = <0x10>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0xa2>; + phandle = <0x12>; + }; + + endpoint@1 { + reg = <0x01>; + remote-endpoint = <0xa3>; + phandle = <0x13>; + }; + + endpoint@2 { + reg = <0x02>; + remote-endpoint = <0xa4>; + phandle = <0x14>; + }; + }; + }; + + iommu@ff460f00 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff460f00 0x00 0x100>; + interrupts = <0x00 0x4d 0x04>; + interrupt-names = "vopb_mmu"; + clocks = <0x02 0xb5 0x02 0xfb>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0c>; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xa1>; + }; + + rk_rga@ff480000 { + compatible = "rockchip,rga2"; + reg = <0x00 0xff480000 0x00 0x1000>; + interrupts = <0x00 0x4c 0x04>; + clocks = <0x02 0xb7 0x02 0xfd 0x02 0x35>; + clock-names = "aclk_rga\0hclk_rga\0clk_rga"; + power-domains = <0x8a 0x0c>; + dma-coherent; + status = "okay"; + phandle = <0x110>; + }; + + cif@ff490000 { + compatible = "rockchip,cif"; + reg = <0x00 0xff490000 0x00 0x200>; + interrupts = <0x00 0x45 0x04>; + clocks = <0x02 0xb3 0x02 0xf9 0x02 0x160 0x02 0x34>; + clock-names = "aclk_cif0\0hclk_cif0\0pclk_cif\0cif0_out"; + resets = <0x02 0x2c 0x02 0x2d 0x02 0x2e>; + reset-names = "rst_cif_a\0rst_cif_h\0rst_cif_pclkin"; + power-domains = <0x8a 0x0d>; + pinctrl-names = "cif_pin_all"; + pinctrl-0 = <0xa5>; + iommus = <0xa6>; + status = "disabled"; + phandle = <0x111>; + }; + + cif-new@ff490000 { + compatible = "rockchip,px30-cif"; + reg = <0x00 0xff490000 0x00 0x200>; + interrupts = <0x00 0x45 0x04>; + clocks = <0x02 0xb3 0x02 0xf9 0x02 0x160 0x02 0x34>; + clock-names = "aclk_cif\0hclk_cif\0pclk_cif\0cif_out"; + resets = <0x02 0x2c 0x02 0x2d 0x02 0x2e>; + reset-names = "rst_cif_a\0rst_cif_h\0rst_cif_pclkin"; + power-domains = <0x8a 0x0d>; + iommus = <0xa6>; + status = "disabled"; + phandle = <0x112>; + }; + + iommu@ff490800 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff490800 0x00 0x100>; + interrupts = <0x00 0x45 0x04>; + interrupt-names = "vip_mmu"; + clocks = <0x02 0xb3 0x02 0xf9>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0d>; + rk_iommu,disable_reset_quirk; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xa6>; + }; + + rk_isp@ff4a0000 { + compatible = "rockchip,px30-isp\0rockchip,isp"; + reg = <0x00 0xff4a0000 0x00 0x8000>; + interrupts = <0x00 0x46 0x04>; + clocks = <0x02 0xb4 0x02 0xfa 0x02 0x33 0x02 0x33 0x02 0x15f 0x02 0x34 0x02 0x34 0x02 0x146>; + clock-names = "aclk_isp\0hclk_isp\0clk_isp\0clk_isp_jpe\0pclkin_isp\0clk_cif_pll\0clk_cif_out\0pclk_dphyrx"; + resets = <0x02 0x2b 0x02 0x2f>; + reset-names = "rst_isp\0rst_mipicsiphy"; + power-domains = <0x8a 0x0d>; + pinctrl-names = "default\0isp_dvp8bit2\0isp_dvp10bit\0isp_dvp12bit"; + pinctrl-0 = <0xa7>; + pinctrl-1 = <0xa5>; + pinctrl-2 = <0xa5 0xa8>; + pinctrl-3 = <0xa9 0xa5 0xa8>; + rockchip,isp,mipiphy = <0x01>; + rockchip,isp,csiphy,reg = <0xff2f0000 0x4000>; + rockchip,grf = <0x2f>; + rockchip,cru = <0x02>; + rockchip,isp,iommu-enable = <0x01>; + iommus = <0xaa>; + status = "disabled"; + phandle = <0x113>; + }; + + rkisp1@ff4a0000 { + compatible = "rockchip,rk3326-rkisp1"; + reg = <0x00 0xff4a0000 0x00 0x8000>; + interrupts = <0x00 0x46 0x04 0x00 0x49 0x04 0x00 0x4a 0x04>; + interrupt-names = "isp_irq\0mi_irq\0mipi_irq"; + clocks = <0x02 0xb4 0x02 0xfa 0x02 0x33 0x02 0x15f>; + clock-names = "aclk_isp\0hclk_isp\0clk_isp\0pclk_isp"; + devfreq = <0xab>; + power-domains = <0x8a 0x0d>; + iommus = <0xaa>; + rockchip,grf = <0x2f>; + status = "okay"; + phandle = <0x114>; + }; + + iommu@ff4a8000 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff4a8000 0x00 0x100>; + interrupts = <0x00 0x46 0x04>; + interrupt-names = "isp_mmu"; + clocks = <0x02 0xb4 0x02 0xfa>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0d>; + rk_iommu,disable_reset_quirk; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xaa>; + }; + + qos@ff518000 { + compatible = "syscon"; + reg = <0x00 0xff518000 0x00 0x20>; + phandle = <0x18>; + }; + + qos@ff520000 { + compatible = "syscon"; + reg = <0x00 0xff520000 0x00 0x20>; + phandle = <0x28>; + }; + + qos@ff52c000 { + compatible = "syscon"; + reg = <0x00 0xff52c000 0x00 0x20>; + phandle = <0x17>; + }; + + qos@ff538000 { + compatible = "syscon"; + reg = <0x00 0xff538000 0x00 0x20>; + phandle = <0x19>; + }; + + qos@ff538080 { + compatible = "syscon"; + reg = <0x00 0xff538080 0x00 0x20>; + phandle = <0x1a>; + }; + + qos@ff538100 { + compatible = "syscon"; + reg = <0x00 0xff538100 0x00 0x20>; + phandle = <0x1b>; + }; + + qos@ff538180 { + compatible = "syscon"; + reg = <0x00 0xff538180 0x00 0x20>; + phandle = <0x1c>; + }; + + qos@ff540000 { + compatible = "syscon"; + reg = <0x00 0xff540000 0x00 0x20>; + phandle = <0x15>; + }; + + qos@ff540080 { + compatible = "syscon"; + reg = <0x00 0xff540080 0x00 0x20>; + phandle = <0x16>; + }; + + qos@ff548000 { + compatible = "syscon"; + reg = <0x00 0xff548000 0x00 0x20>; + phandle = <0x23>; + }; + + qos@ff548080 { + compatible = "syscon"; + reg = <0x00 0xff548080 0x00 0x20>; + phandle = <0x24>; + }; + + qos@ff548100 { + compatible = "syscon"; + reg = <0x00 0xff548100 0x00 0x20>; + phandle = <0x25>; + }; + + qos@ff548180 { + compatible = "syscon"; + reg = <0x00 0xff548180 0x00 0x20>; + phandle = <0x26>; + }; + + qos@ff548200 { + compatible = "syscon"; + reg = <0x00 0xff548200 0x00 0x20>; + phandle = <0x27>; + }; + + qos@ff550000 { + compatible = "syscon"; + reg = <0x00 0xff550000 0x00 0x20>; + phandle = <0x1f>; + }; + + qos@ff550080 { + compatible = "syscon"; + reg = <0x00 0xff550080 0x00 0x20>; + phandle = <0x20>; + }; + + qos@ff550100 { + compatible = "syscon"; + reg = <0x00 0xff550100 0x00 0x20>; + phandle = <0x21>; + }; + + qos@ff550180 { + compatible = "syscon"; + reg = <0x00 0xff550180 0x00 0x20>; + phandle = <0x22>; + }; + + qos@ff558000 { + compatible = "syscon"; + reg = <0x00 0xff558000 0x00 0x20>; + phandle = <0x1d>; + }; + + qos@ff558080 { + compatible = "syscon"; + reg = <0x00 0xff558080 0x00 0x20>; + phandle = <0x1e>; + }; + + dfi@ff610000 { + reg = <0x00 0xff610000 0x00 0x400>; + compatible = "rockchip,px30-dfi"; + rockchip,pmugrf = <0xac>; + status = "okay"; + phandle = <0xad>; + }; + + dmc { + compatible = "rockchip,px30-dmc"; + interrupts = <0x00 0x69 0x04>; + interrupt-names = "complete_irq"; + devfreq-events = <0xad>; + clocks = <0x02 0x54>; + clock-names = "dmc_clk"; + operating-points-v2 = <0xae>; + ddr_timing = <0xaf>; + upthreshold = <0x28>; + downdifferential = <0x14>; + system-status-freq = <0x01 0x80e80 0x08 0x6ddd0 0x02 0x2f5d0 0x20 0x6ddd0 0x1000 0x80e80 0x4000 0xa2990 0x2000 0xa2990>; + auto-min-freq = <0x50140>; + auto-freq-en = <0x01>; + #cooling-cells = <0x02>; + status = "okay"; + center-supply = <0x0e>; + phandle = <0xab>; + + ddr_power_model { + compatible = "ddr_power_model"; + dynamic-power-coefficient = <0x78>; + static-power-coefficient = <0xc8>; + ts = <0x7d00 0x125c 0xffffffb0 0x02>; + thermal-zone = "soc-thermal"; + phandle = <0x115>; + }; + }; + + dmc-opp-table { + compatible = "operating-points-v2"; + rockchip,max-volt = <0x118c30>; + rockchip,evb-irdrop = <0x61a8>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-ch = <0x00 0x00>; + phandle = <0xae>; + + opp-528000000 { + opp-hz = <0x00 0x1f78a400>; + opp-microvolt = <0xee098>; + opp-microvolt-L0 = <0xee098>; + opp-microvolt-L1 = <0xee098>; + opp-microvolt-L2 = <0xe7ef0>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-666000000 { + opp-hz = <0x00 0x27b25a80>; + opp-microvolt = <0x100590>; + opp-microvolt-L0 = <0x100590>; + opp-microvolt-L1 = <0xf4240>; + opp-microvolt-L2 = <0xee098>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-786000000 { + opp-hz = <0x00 0x2ed96880>; + opp-microvolt = <0x10c8e0>; + opp-microvolt-L0 = <0x10c8e0>; + opp-microvolt-L1 = <0x100590>; + opp-microvolt-L2 = <0xfa3e8>; + opp-microvolt-L3 = <0xf4240>; + status = "okay"; + }; + }; + + rockchip-system-monitor { + compatible = "rockchip,system-monitor"; + rockchip,thermal-zone = "soc-thermal"; + rockchip,polling-delay = <0xc8>; + phandle = <0x116>; + }; + + pinctrl { + compatible = "rockchip,px30-pinctrl"; + rockchip,grf = <0x2f>; + rockchip,pmu = <0xac>; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + phandle = <0x117>; + + gpio0@ff040000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff040000 0x00 0x100>; + interrupts = <0x00 0x03 0x04>; + clocks = <0x2a 0x14>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x5c>; + }; + + gpio1@ff250000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff250000 0x00 0x100>; + interrupts = <0x00 0x04 0x04>; + clocks = <0x02 0x15c>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0xbf>; + }; + + gpio2@ff260000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff260000 0x00 0x100>; + interrupts = <0x00 0x05 0x04>; + clocks = <0x02 0x15d>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x66>; + }; + + gpio3@ff270000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff270000 0x00 0x100>; + interrupts = <0x00 0x06 0x04>; + clocks = <0x02 0x15e>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x97>; + }; + + pcfg-pull-up { + bias-pull-up; + phandle = <0xb2>; + }; + + pcfg-pull-down { + bias-pull-down; + phandle = <0x118>; + }; + + pcfg-pull-none { + bias-disable; + phandle = <0xb1>; + }; + + pcfg-pull-none-2ma { + bias-disable; + drive-strength = <0x02>; + phandle = <0x119>; + }; + + pcfg-pull-up-2ma { + bias-pull-up; + drive-strength = <0x02>; + phandle = <0x11a>; + }; + + pcfg-pull-up-4ma { + bias-pull-up; + drive-strength = <0x04>; + phandle = <0xb3>; + }; + + pcfg-pull-none-4ma { + bias-disable; + drive-strength = <0x04>; + phandle = <0x11b>; + }; + + pcfg-pull-down-4ma { + bias-pull-down; + drive-strength = <0x04>; + phandle = <0x11c>; + }; + + pcfg-pull-none-8ma { + bias-disable; + drive-strength = <0x08>; + phandle = <0xb6>; + }; + + pcfg-pull-up-8ma { + bias-pull-up; + drive-strength = <0x08>; + phandle = <0xb4>; + }; + + pcfg-pull-none-12ma { + bias-disable; + drive-strength = <0x0c>; + phandle = <0xb8>; + }; + + pcfg-pull-up-12ma { + bias-pull-up; + drive-strength = <0x0c>; + phandle = <0xb7>; + }; + + pcfg-pull-none-smt { + bias-disable; + input-schmitt-enable; + phandle = <0xb0>; + }; + + pcfg-output-high { + output-high; + phandle = <0x11d>; + }; + + pcfg-output-low { + output-low; + phandle = <0xb9>; + }; + + pcfg-input-high { + bias-pull-up; + input-enable; + phandle = <0xb5>; + }; + + pcfg-input { + input-enable; + phandle = <0x11e>; + }; + + i2c0 { + + i2c0-xfer { + rockchip,pins = <0x00 0x08 0x01 0xb0 0x00 0x09 0x01 0xb0>; + phandle = <0x5b>; + }; + }; + + i2c1 { + + i2c1-xfer { + rockchip,pins = <0x00 0x12 0x01 0xb0 0x00 0x13 0x01 0xb0>; + phandle = <0x69>; + }; + }; + + i2c2 { + + i2c2-xfer { + rockchip,pins = <0x02 0x0f 0x02 0xb0 0x02 0x10 0x02 0xb0>; + phandle = <0x6a>; + }; + }; + + i2c3 { + + i2c3-xfer { + rockchip,pins = <0x01 0x0c 0x04 0xb0 0x01 0x0d 0x04 0xb0>; + phandle = <0x6b>; + }; + }; + + tsadc { + + tsadc-otp-gpio { + rockchip,pins = <0x00 0x06 0x00 0xb1>; + phandle = <0x86>; + }; + + tsadc-otp-out { + rockchip,pins = <0x00 0x06 0x01 0xb1>; + phandle = <0x87>; + }; + }; + + uart0 { + + uart0-xfer { + rockchip,pins = <0x00 0x0a 0x01 0xb2 0x00 0x0b 0x01 0xb2>; + phandle = <0x2c>; + }; + + uart0-cts { + rockchip,pins = <0x00 0x0c 0x01 0xb1>; + phandle = <0x2d>; + }; + + uart0-rts { + rockchip,pins = <0x00 0x0d 0x01 0xb1>; + phandle = <0x2e>; + }; + + uart0-rts-gpio { + rockchip,pins = <0x00 0x0d 0x00 0xb1>; + phandle = <0x11f>; + }; + }; + + uart1 { + + uart1-xfer { + rockchip,pins = <0x01 0x11 0x01 0xb2 0x01 0x10 0x01 0xb2>; + phandle = <0x4f>; + }; + + uart1-cts { + rockchip,pins = <0x01 0x12 0x01 0xb1>; + phandle = <0x50>; + }; + + uart1-rts { + rockchip,pins = <0x01 0x13 0x01 0xb1>; + phandle = <0x120>; + }; + + uart1-rts-gpio { + rockchip,pins = <0x01 0x13 0x00 0xb1>; + phandle = <0x121>; + }; + }; + + uart2-m0 { + + uart2m0-xfer { + rockchip,pins = <0x01 0x1a 0x02 0xb2 0x01 0x1b 0x02 0xb2>; + phandle = <0x51>; + }; + }; + + uart2-m1 { + + uart2m1-xfer { + rockchip,pins = <0x02 0x0c 0x02 0xb2 0x02 0x0e 0x02 0xb2>; + phandle = <0xba>; + }; + }; + + uart3-m0 { + + uart3m0-xfer { + rockchip,pins = <0x00 0x10 0x02 0xb2 0x00 0x11 0x02 0xb2>; + phandle = <0x122>; + }; + + uart3m0-cts { + rockchip,pins = <0x00 0x12 0x02 0xb1>; + phandle = <0x123>; + }; + + uart3m0-rts { + rockchip,pins = <0x00 0x13 0x02 0xb1>; + phandle = <0x124>; + }; + + uart3m0-rts-gpio { + rockchip,pins = <0x00 0x13 0x00 0xb1>; + phandle = <0x125>; + }; + }; + + uart3-m1 { + + uart3m1-xfer { + rockchip,pins = <0x01 0x0e 0x02 0xb2 0x01 0x0f 0x02 0xb2>; + phandle = <0x52>; + }; + + uart3m1-cts { + rockchip,pins = <0x01 0x0c 0x02 0xb1>; + phandle = <0x53>; + }; + + uart3m1-rts { + rockchip,pins = <0x01 0x0d 0x02 0xb1>; + phandle = <0x54>; + }; + + uart3m1-rts-gpio { + rockchip,pins = <0x01 0x0d 0x00 0xb1>; + phandle = <0x126>; + }; + }; + + uart4 { + + uart4-xfer { + rockchip,pins = <0x01 0x1c 0x02 0xb2 0x01 0x1d 0x02 0xb2>; + phandle = <0x55>; + }; + + uart4-cts { + rockchip,pins = <0x01 0x1e 0x02 0xb1>; + phandle = <0x56>; + }; + + uart4-rts { + rockchip,pins = <0x01 0x1f 0x02 0xb1>; + phandle = <0x57>; + }; + }; + + uart5 { + + uart5-xfer { + rockchip,pins = <0x03 0x02 0x04 0xb2 0x03 0x01 0x04 0xb2>; + phandle = <0x58>; + }; + + uart5-cts { + rockchip,pins = <0x03 0x03 0x04 0xb1>; + phandle = <0x59>; + }; + + uart5-rts { + rockchip,pins = <0x03 0x05 0x04 0xb1>; + phandle = <0x5a>; + }; + }; + + spi0 { + + spi0-clk { + rockchip,pins = <0x01 0x0f 0x03 0xb3>; + phandle = <0x6c>; + }; + + spi0-csn { + rockchip,pins = <0x01 0x0e 0x03 0xb3>; + phandle = <0x6d>; + }; + + spi0-miso { + rockchip,pins = <0x01 0x0d 0x03 0xb3>; + phandle = <0x6e>; + }; + + spi0-mosi { + rockchip,pins = <0x01 0x0c 0x03 0xb3>; + phandle = <0x6f>; + }; + + spi0-clk-hs { + rockchip,pins = <0x01 0x0f 0x03 0xb4>; + phandle = <0x70>; + }; + + spi0-miso-hs { + rockchip,pins = <0x01 0x0d 0x03 0xb4>; + phandle = <0x71>; + }; + + spi0-mosi-hs { + rockchip,pins = <0x01 0x0c 0x03 0xb4>; + phandle = <0x72>; + }; + }; + + spi1 { + + spi1-clk { + rockchip,pins = <0x03 0x0f 0x04 0xb3>; + phandle = <0x73>; + }; + + spi1-csn0 { + rockchip,pins = <0x03 0x09 0x04 0xb3>; + phandle = <0x74>; + }; + + spi1-csn1 { + rockchip,pins = <0x03 0x0a 0x02 0xb3>; + phandle = <0x75>; + }; + + spi1-miso { + rockchip,pins = <0x03 0x0e 0x04 0xb3>; + phandle = <0x76>; + }; + + spi1-mosi { + rockchip,pins = <0x03 0x0c 0x04 0xb3>; + phandle = <0x77>; + }; + + spi1-clk-hs { + rockchip,pins = <0x03 0x0f 0x04 0xb4>; + phandle = <0x78>; + }; + + spi1-miso-hs { + rockchip,pins = <0x03 0x0e 0x04 0xb4>; + phandle = <0x79>; + }; + + spi1-mosi-hs { + rockchip,pins = <0x03 0x0c 0x04 0xb4>; + phandle = <0x7a>; + }; + }; + + pdm { + + pdm-clk0m0 { + rockchip,pins = <0x03 0x16 0x02 0xb1>; + phandle = <0x44>; + }; + + pdm-clk0m1 { + rockchip,pins = <0x02 0x16 0x01 0xb1>; + phandle = <0x127>; + }; + + pdm-clk1 { + rockchip,pins = <0x03 0x17 0x02 0xb1>; + phandle = <0x45>; + }; + + pdm-sdi0m0 { + rockchip,pins = <0x03 0x1b 0x02 0xb1>; + phandle = <0x46>; + }; + + pdm-sdi0m1 { + rockchip,pins = <0x02 0x15 0x02 0xb1>; + phandle = <0x128>; + }; + + pdm-sdi1 { + rockchip,pins = <0x03 0x18 0x02 0xb1>; + phandle = <0x47>; + }; + + pdm-sdi2 { + rockchip,pins = <0x03 0x19 0x02 0xb1>; + phandle = <0x48>; + }; + + pdm-sdi3 { + rockchip,pins = <0x03 0x1a 0x02 0xb1>; + phandle = <0x49>; + }; + + pdm-clk0m0-sleep { + rockchip,pins = <0x03 0x16 0x00 0xb5>; + phandle = <0x129>; + }; + + pdm-clk0m1-sleep { + rockchip,pins = <0x02 0x16 0x00 0xb5>; + phandle = <0x12a>; + }; + + pdm-clk1-sleep { + rockchip,pins = <0x03 0x17 0x00 0xb5>; + phandle = <0x12b>; + }; + + pdm-sdi0m0-sleep { + rockchip,pins = <0x03 0x1b 0x00 0xb5>; + phandle = <0x12c>; + }; + + pdm-sdi0m1-sleep { + rockchip,pins = <0x02 0x15 0x00 0xb5>; + phandle = <0x12d>; + }; + + pdm-sdi1-sleep { + rockchip,pins = <0x03 0x18 0x00 0xb5>; + phandle = <0x12e>; + }; + + pdm-sdi2-sleep { + rockchip,pins = <0x03 0x19 0x00 0xb5>; + phandle = <0x12f>; + }; + + pdm-sdi3-sleep { + rockchip,pins = <0x03 0x1a 0x00 0xb5>; + phandle = <0x130>; + }; + }; + + i2s0 { + + i2s0-8ch-mclk { + rockchip,pins = <0x03 0x11 0x02 0xb1>; + phandle = <0x131>; + }; + + i2s0-8ch-sclktx { + rockchip,pins = <0x03 0x13 0x02 0xb1>; + phandle = <0x30>; + }; + + i2s0-8ch-sclkrx { + rockchip,pins = <0x03 0x0c 0x02 0xb1>; + phandle = <0x31>; + }; + + i2s0-8ch-lrcktx { + rockchip,pins = <0x03 0x12 0x02 0xb1>; + phandle = <0x32>; + }; + + i2s0-8ch-lrckrx { + rockchip,pins = <0x03 0x0d 0x02 0xb1>; + phandle = <0x33>; + }; + + i2s0-8ch-sdo0 { + rockchip,pins = <0x03 0x14 0x02 0xb1>; + phandle = <0x38>; + }; + + i2s0-8ch-sdo1 { + rockchip,pins = <0x03 0x10 0x02 0xb1>; + phandle = <0x39>; + }; + + i2s0-8ch-sdo2 { + rockchip,pins = <0x03 0x0f 0x02 0xb1>; + phandle = <0x3a>; + }; + + i2s0-8ch-sdo3 { + rockchip,pins = <0x03 0x0e 0x02 0xb1>; + phandle = <0x3b>; + }; + + i2s0-8ch-sdi0 { + rockchip,pins = <0x03 0x15 0x02 0xb1>; + phandle = <0x34>; + }; + + i2s0-8ch-sdi1 { + rockchip,pins = <0x03 0x0b 0x02 0xb1>; + phandle = <0x35>; + }; + + i2s0-8ch-sdi2 { + rockchip,pins = <0x03 0x09 0x02 0xb1>; + phandle = <0x36>; + }; + + i2s0-8ch-sdi3 { + rockchip,pins = <0x03 0x08 0x02 0xb1>; + phandle = <0x37>; + }; + }; + + i2s1 { + + i2s1-2ch-mclk { + rockchip,pins = <0x02 0x13 0x01 0xb1>; + phandle = <0x68>; + }; + + i2s1-2ch-sclk { + rockchip,pins = <0x02 0x12 0x01 0xb1>; + phandle = <0x3c>; + }; + + i2s1-2ch-lrck { + rockchip,pins = <0x02 0x11 0x01 0xb1>; + phandle = <0x3d>; + }; + + i2s1-2ch-sdi { + rockchip,pins = <0x02 0x15 0x01 0xb1>; + phandle = <0x3e>; + }; + + i2s1-2ch-sdo { + rockchip,pins = <0x02 0x14 0x01 0xb1>; + phandle = <0x3f>; + }; + }; + + i2s2 { + + i2s2-2ch-mclk { + rockchip,pins = <0x03 0x01 0x02 0xb1>; + phandle = <0x132>; + }; + + i2s2-2ch-sclk { + rockchip,pins = <0x03 0x02 0x02 0xb1>; + phandle = <0x40>; + }; + + i2s2-2ch-lrck { + rockchip,pins = <0x03 0x03 0x02 0xb1>; + phandle = <0x41>; + }; + + i2s2-2ch-sdi { + rockchip,pins = <0x03 0x05 0x02 0xb1>; + phandle = <0x42>; + }; + + i2s2-2ch-sdo { + rockchip,pins = <0x03 0x07 0x02 0xb1>; + phandle = <0x43>; + }; + }; + + sdmmc { + + sdmmc-clk { + rockchip,pins = <0x01 0x1e 0x01 0xb6>; + phandle = <0x8f>; + }; + + sdmmc-cmd { + rockchip,pins = <0x01 0x1f 0x01 0xb4>; + phandle = <0x90>; + }; + + sdmmc-det { + rockchip,pins = <0x00 0x03 0x01 0xb4>; + phandle = <0x91>; + }; + + sdmmc-bus1 { + rockchip,pins = <0x01 0x1a 0x01 0xb4>; + phandle = <0x133>; + }; + + sdmmc-bus4 { + rockchip,pins = <0x01 0x1a 0x01 0xb4 0x01 0x1b 0x01 0xb4 0x01 0x1c 0x01 0xb4 0x01 0x1d 0x01 0xb4>; + phandle = <0x92>; + }; + + sdmmc-gpio { + rockchip,pins = <0x01 0x1a 0x00 0xb3 0x01 0x1b 0x00 0xb3 0x01 0x1c 0x00 0xb3 0x01 0x1d 0x00 0xb3 0x01 0x1e 0x00 0xb3 0x01 0x1f 0x00 0xb3>; + phandle = <0x134>; + }; + }; + + sdio { + + sdio-clk { + rockchip,pins = <0x01 0x15 0x01 0xb1>; + phandle = <0x96>; + }; + + sdio-cmd { + rockchip,pins = <0x01 0x14 0x01 0xb2>; + phandle = <0x95>; + }; + + sdio-bus4 { + rockchip,pins = <0x01 0x16 0x01 0xb2 0x01 0x17 0x01 0xb2 0x01 0x18 0x01 0xb2 0x01 0x19 0x01 0xb2>; + phandle = <0x94>; + }; + + sdio-gpio { + rockchip,pins = <0x01 0x16 0x00 0xb2 0x01 0x17 0x00 0xb2 0x01 0x18 0x00 0xb2 0x01 0x19 0x00 0xb2 0x01 0x14 0x00 0xb2 0x01 0x15 0x00 0xb2>; + phandle = <0x135>; + }; + }; + + emmc { + + emmc-clk { + rockchip,pins = <0x01 0x09 0x02 0xb6>; + phandle = <0x136>; + }; + + emmc-cmd { + rockchip,pins = <0x01 0x0a 0x02 0xb4>; + phandle = <0x137>; + }; + + emmc-pwren { + rockchip,pins = <0x01 0x08 0x02 0xb1>; + phandle = <0x138>; + }; + + emmc-rstnout { + rockchip,pins = <0x01 0x0b 0x02 0xb1>; + phandle = <0x139>; + }; + + emmc-bus1 { + rockchip,pins = <0x01 0x00 0x02 0xb4>; + phandle = <0x13a>; + }; + + emmc-bus4 { + rockchip,pins = <0x01 0x00 0x02 0xb4 0x01 0x01 0x02 0xb4 0x01 0x02 0x02 0xb4 0x01 0x03 0x02 0xb4>; + phandle = <0x13b>; + }; + + emmc-bus8 { + rockchip,pins = <0x01 0x00 0x02 0xb4 0x01 0x01 0x02 0xb4 0x01 0x02 0x02 0xb4 0x01 0x03 0x02 0xb4 0x01 0x04 0x02 0xb4 0x01 0x05 0x02 0xb4 0x01 0x06 0x02 0xb4 0x01 0x07 0x02 0xb4>; + phandle = <0x13c>; + }; + }; + + flash { + + flash-cs0 { + rockchip,pins = <0x01 0x08 0x01 0xb1>; + phandle = <0x13d>; + }; + + flash-rdy { + rockchip,pins = <0x01 0x09 0x01 0xb1>; + phandle = <0x13e>; + }; + + flash-dqs { + rockchip,pins = <0x01 0x0a 0x01 0xb1>; + phandle = <0x13f>; + }; + + flash-ale { + rockchip,pins = <0x01 0x0b 0x01 0xb1>; + phandle = <0x140>; + }; + + flash-cle { + rockchip,pins = <0x01 0x0c 0x01 0xb1>; + phandle = <0x141>; + }; + + flash-wrn { + rockchip,pins = <0x01 0x0d 0x01 0xb1>; + phandle = <0x142>; + }; + + flash-csl { + rockchip,pins = <0x01 0x0e 0x01 0xb1>; + phandle = <0x143>; + }; + + flash-rdn { + rockchip,pins = <0x01 0x0f 0x01 0xb1>; + phandle = <0x144>; + }; + + flash-bus8 { + rockchip,pins = <0x01 0x00 0x01 0xb7 0x01 0x01 0x01 0xb7 0x01 0x02 0x01 0xb7 0x01 0x03 0x01 0xb7 0x01 0x04 0x01 0xb7 0x01 0x05 0x01 0xb7 0x01 0x06 0x01 0xb7 0x01 0x07 0x01 0xb7>; + phandle = <0x145>; + }; + }; + + lcdc { + + lcdc-m0-rgb-pins { + rockchip,pins = <0x03 0x00 0x01 0xb6 0x03 0x01 0x01 0xb6 0x03 0x02 0x01 0xb6 0x03 0x03 0x01 0xb6 0x03 0x04 0x01 0xb6 0x03 0x05 0x01 0xb6 0x03 0x06 0x01 0xb6 0x03 0x07 0x01 0xb6 0x03 0x08 0x01 0xb6 0x03 0x09 0x01 0xb6 0x03 0x0a 0x01 0xb6 0x03 0x0b 0x01 0xb6 0x03 0x0c 0x01 0xb6 0x03 0x0d 0x01 0xb6 0x03 0x0e 0x01 0xb6 0x03 0x0f 0x01 0xb6 0x03 0x10 0x01 0xb6 0x03 0x11 0x01 0xb6 0x03 0x12 0x01 0xb6 0x03 0x13 0x01 0xb6 0x03 0x14 0x01 0xb6 0x03 0x15 0x01 0xb6 0x03 0x16 0x01 0xb6 0x03 0x17 0x01 0xb6 0x03 0x18 0x01 0xb6 0x03 0x19 0x01 0xb6 0x03 0x1a 0x01 0xb6 0x03 0x1b 0x01 0xb6>; + phandle = <0x146>; + }; + + lcdc-m0-sleep-pins { + rockchip,pins = <0x03 0x00 0x00 0xb1 0x03 0x01 0x00 0xb1 0x03 0x02 0x00 0xb1 0x03 0x03 0x00 0xb1 0x03 0x04 0x00 0xb1 0x03 0x05 0x00 0xb1 0x03 0x06 0x00 0xb1 0x03 0x07 0x00 0xb1 0x03 0x08 0x00 0xb1 0x03 0x09 0x00 0xb1 0x03 0x0a 0x00 0xb1 0x03 0x0b 0x00 0xb1 0x03 0x0c 0x00 0xb1 0x03 0x0d 0x00 0xb1 0x03 0x0e 0x00 0xb1 0x03 0x0f 0x00 0xb1 0x03 0x10 0x00 0xb1 0x03 0x11 0x00 0xb1 0x03 0x12 0x00 0xb1 0x03 0x13 0x00 0xb1 0x03 0x14 0x00 0xb1 0x03 0x15 0x00 0xb1 0x03 0x16 0x00 0xb1 0x03 0x17 0x00 0xb1 0x03 0x18 0x00 0xb1 0x03 0x19 0x00 0xb1 0x03 0x1a 0x00 0xb1 0x03 0x1b 0x00 0xb1>; + phandle = <0x147>; + }; + + lcdc-m1-rgb-pins { + rockchip,pins = <0x03 0x00 0x01 0xb6 0x03 0x04 0x01 0xb6 0x03 0x06 0x01 0xb6 0x03 0x0a 0x01 0xb6 0x03 0x0b 0x01 0xb6 0x03 0x0d 0x01 0xb6 0x03 0x10 0x01 0xb6 0x03 0x11 0x01 0xb6 0x03 0x12 0x01 0xb6 0x03 0x13 0x01 0xb6 0x03 0x14 0x01 0xb6 0x03 0x15 0x01 0xb6 0x03 0x16 0x01 0xb6 0x03 0x17 0x01 0xb6 0x03 0x18 0x01 0xb6 0x03 0x19 0x01 0xb6 0x03 0x1a 0x01 0xb6 0x03 0x1b 0x01 0xb6>; + phandle = <0x4d>; + }; + + lcdc-m1-sleep-pins { + rockchip,pins = <0x03 0x00 0x00 0xb1 0x03 0x04 0x00 0xb1 0x03 0x06 0x00 0xb1 0x03 0x0a 0x00 0xb1 0x03 0x0b 0x00 0xb1 0x03 0x0d 0x00 0xb1 0x03 0x10 0x00 0xb1 0x03 0x11 0x00 0xb1 0x03 0x12 0x00 0xb1 0x03 0x13 0x00 0xb1 0x03 0x14 0x00 0xb1 0x03 0x15 0x00 0xb1 0x03 0x16 0x00 0xb1 0x03 0x17 0x00 0xb1 0x03 0x18 0x00 0xb1 0x03 0x19 0x00 0xb1 0x03 0x1a 0x00 0xb1 0x03 0x1b 0x00 0xb1>; + phandle = <0x4e>; + }; + }; + + pwm0 { + + pwm0-pin { + rockchip,pins = <0x00 0x0f 0x01 0xb1>; + phandle = <0x7b>; + }; + }; + + pwm1 { + + pwm1-pin { + rockchip,pins = <0x00 0x10 0x01 0xb1>; + phandle = <0x7c>; + }; + }; + + pwm2 { + + pwm2-pin { + rockchip,pins = <0x02 0x0d 0x01 0xb1>; + phandle = <0x7d>; + }; + }; + + pwm3 { + + pwm3-pin { + rockchip,pins = <0x00 0x11 0x01 0xb1>; + phandle = <0x7e>; + }; + }; + + pwm4 { + + pwm4-pin { + rockchip,pins = <0x03 0x12 0x03 0xb1>; + phandle = <0x7f>; + }; + }; + + pwm5 { + + pwm5-pin { + rockchip,pins = <0x03 0x13 0x03 0xb1>; + phandle = <0x80>; + }; + }; + + pwm6 { + + pwm6-pin { + rockchip,pins = <0x03 0x14 0x03 0xb1>; + phandle = <0x81>; + }; + }; + + pwm7 { + + pwm7-pin { + rockchip,pins = <0x03 0x15 0x03 0xb1>; + phandle = <0x82>; + }; + }; + + gmac { + + rmii-pins { + rockchip,pins = <0x02 0x00 0x02 0xb8 0x02 0x01 0x02 0xb8 0x02 0x02 0x02 0xb8 0x02 0x03 0x02 0xb1 0x02 0x04 0x02 0xb1 0x02 0x05 0x02 0xb1 0x02 0x06 0x02 0xb1 0x02 0x07 0x02 0xb1 0x02 0x09 0x02 0xb1>; + phandle = <0x8d>; + }; + + mac-refclk-12ma { + rockchip,pins = <0x02 0x0a 0x02 0xb8>; + phandle = <0x8e>; + }; + + mac-refclk { + rockchip,pins = <0x02 0x0a 0x02 0xb1>; + phandle = <0x148>; + }; + }; + + cif-m0 { + + cif-clkout-m0 { + rockchip,pins = <0x02 0x0b 0x01 0xb8>; + phandle = <0xa7>; + }; + + dvp-d2d9-m0 { + rockchip,pins = <0x02 0x00 0x01 0xb1 0x02 0x01 0x01 0xb1 0x02 0x02 0x01 0xb1 0x02 0x03 0x01 0xb1 0x02 0x04 0x01 0xb1 0x02 0x05 0x01 0xb1 0x02 0x06 0x01 0xb1 0x02 0x07 0x01 0xb1 0x02 0x08 0x01 0xb1 0x02 0x09 0x01 0xb1 0x02 0x0a 0x01 0xb1 0x02 0x0b 0x01 0xb1>; + phandle = <0xa5>; + }; + + dvp-d0d1-m0 { + rockchip,pins = <0x02 0x0c 0x01 0xb1 0x02 0x0e 0x01 0xb1>; + phandle = <0xa9>; + }; + + d10-d11-m0 { + rockchip,pins = <0x02 0x0f 0x01 0xb1 0x02 0x10 0x01 0xb1>; + phandle = <0xa8>; + }; + }; + + cif-m1 { + + cif-clkout-m1 { + rockchip,pins = <0x03 0x18 0x03 0xb1>; + phandle = <0x149>; + }; + + dvp-d2d9-m1 { + rockchip,pins = <0x03 0x03 0x03 0xb1 0x03 0x05 0x03 0xb1 0x03 0x07 0x03 0xb1 0x03 0x08 0x03 0xb1 0x03 0x09 0x03 0xb1 0x03 0x0c 0x03 0xb1 0x03 0x0e 0x03 0xb1 0x03 0x0f 0x03 0xb1 0x03 0x19 0x03 0xb1 0x03 0x1a 0x03 0xb1 0x03 0x1b 0x03 0xb1 0x03 0x18 0x03 0xb1>; + phandle = <0x14a>; + }; + + dvp-d0d1-m1 { + rockchip,pins = <0x03 0x01 0x03 0xb1 0x03 0x02 0x03 0xb1>; + phandle = <0x14b>; + }; + + d10-d11-m1 { + rockchip,pins = <0x03 0x16 0x03 0xb1 0x03 0x17 0x03 0xb1>; + phandle = <0x14c>; + }; + }; + + isp { + + isp-prelight { + rockchip,pins = <0x03 0x19 0x04 0xb1>; + phandle = <0x14d>; + }; + }; + + pmic { + + pmic_int { + rockchip,pins = <0x00 0x0a 0x00 0xb2 0x00 0x0b 0x00 0xb1>; + phandle = <0x5d>; + }; + + soc_slppin_gpio { + rockchip,pins = <0x00 0x04 0x00 0xb9>; + phandle = <0x60>; + }; + + soc_slppin_slp { + rockchip,pins = <0x00 0x04 0x01 0xb1>; + phandle = <0x5e>; + }; + + soc_slppin_rst { + rockchip,pins = <0x00 0x04 0x02 0xb1>; + phandle = <0x62>; + }; + }; + + leds { + + led-pins { + rockchip,pins = <0x00 0x11 0x00 0xb1>; + phandle = <0xc0>; + }; + }; + + btns { + + btn-pins { + rockchip,pins = <0x01 0x0c 0x00 0xb2 0x01 0x0d 0x00 0xb2 0x01 0x0e 0x00 0xb2 0x01 0x0f 0x00 0xb2 0x01 0x02 0x00 0xb2 0x01 0x05 0x00 0xb2 0x01 0x06 0x00 0xb2 0x01 0x07 0x00 0xb2 0x02 0x00 0x00 0xb2 0x02 0x01 0x00 0xb2 0x02 0x02 0x00 0xb2 0x02 0x03 0x00 0xb2 0x02 0x04 0x00 0xb2 0x02 0x05 0x00 0xb2 0x02 0x06 0x00 0xb2 0x02 0x07 0x00 0xb2 0x03 0x09 0x00 0xb2 0x03 0x0a 0x00 0xb2 0x03 0x0c 0x00 0xb2 0x03 0x0f 0x00 0xb2>; + phandle = <0xbd>; + }; + }; + }; + + chosen { + bootargs = [00]; + }; + + fiq-debugger { + compatible = "rockchip,fiq-debugger"; + rockchip,serial-id = <0x02>; + rockchip,wake-irq = <0x00>; + rockchip,irq-mode-enable = <0x00>; + rockchip,baudrate = <0x1c200>; + interrupts = <0x00 0x7f 0x08>; + pinctrl-names = "default"; + pinctrl-0 = <0xba>; + status = "okay"; + }; + + ramoops { + compatible = "ramoops"; + record-size = <0x00 0x20000>; + console-size = <0x00 0x80000>; + ftrace-size = <0x00 0x00>; + pmsg-size = <0x00 0x00>; + memory-region = <0xbb>; + }; + + reserved-memory { + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + + drm-logo@00000000 { + compatible = "rockchip,drm-logo"; + reg = <0x00 0x00 0x00 0x00>; + phandle = <0x11>; + }; + + region@110000 { + reg = <0x00 0x110000 0x00 0xf0000>; + reg-names = "ramoops_mem"; + phandle = <0xbb>; + }; + }; + + odroidgo3-keys { + compatible = "gpio-keys"; + #address-cells = <0x01>; + #size-cells = <0x00>; + autorepeat; + phandle = <0x14e>; + + button@0 { + label = "GPIO BTN-VOLUP"; + linux,code = <0x73>; + gpios = <0x66 0x00 0x01>; + }; + + button@1 { + label = "GPIO BTN-VOLDN"; + linux,code = <0x72>; + gpios = <0x66 0x01 0x01>; + }; + }; + + odroidgo3-joypad { + compatible = "odroidgo3-joypad"; + pwms = <0xbc 0x00 0xbebc200 0x00>; + pwm-names = "enable"; + rumble-boost-weak = <0x00>; + rumble-boost-strong = <0x00>; + joypad-name = "GO-Super Gamepad"; + joypad-product = <0x1100>; + joypad-revision = <0x100>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <0xbd>; + pinctrl-1 = <0x7b>; + io-channel-names = "amux_adc"; + io-channels = <0xbe 0x01>; + amux-count = <0x04>; + amux-a-gpios = <0x97 0x0b 0x01>; + amux-b-gpios = <0x97 0x08 0x01>; + amux-en-gpios = <0x97 0x0d 0x01>; + button-adc-scale = <0x02>; + button-adc-deadzone = <0x40>; + button-adc-fuzz = <0x20>; + button-adc-flat = <0x20>; + abs_x-p-tuning = <0xc8>; + abs_x-n-tuning = <0xc8>; + abs_y-p-tuning = <0xc8>; + abs_y-n-tuning = <0xc8>; + abs_rx-p-tuning = <0xc8>; + abs_rx-n-tuning = <0xc8>; + abs_ry-p-tuning = <0xc8>; + abs_ry-n-tuning = <0xc8>; + poll-interval = <0x0a>; + invert-absx; + invert-absy; + phandle = <0x14f>; + + sw1 { + gpios = <0xbf 0x0c 0x01>; + label = "GPIO DPAD-UP"; + linux,code = <0x220>; + }; + + sw2 { + gpios = <0xbf 0x0d 0x01>; + label = "GPIO DPAD-DOWN"; + linux,code = <0x221>; + }; + + sw3 { + gpios = <0xbf 0x0e 0x01>; + label = "GPIO DPAD-LEFT"; + linux,code = <0x222>; + }; + + sw4 { + gpios = <0xbf 0x0f 0x01>; + label = "GPIO DPAD-RIGHT"; + linux,code = <0x223>; + }; + + sw5 { + gpios = <0xbf 0x02 0x01>; + label = "GPIO KEY BTN-A"; + linux,code = <0x131>; + }; + + sw6 { + gpios = <0xbf 0x05 0x01>; + label = "GPIO BTN-B"; + linux,code = <0x130>; + }; + + sw7 { + gpios = <0xbf 0x06 0x01>; + label = "GPIO BTN-Y"; + linux,code = <0x134>; + }; + + sw8 { + gpios = <0xbf 0x07 0x01>; + label = "GPIO BTN-X"; + linux,code = <0x133>; + }; + + sw11 { + gpios = <0x66 0x02 0x01>; + label = "GPIO F3"; + linux,code = <0x2c2>; + }; + + sw12 { + gpios = <0x66 0x03 0x01>; + label = "GPIO F4"; + linux,code = <0x2c3>; + }; + + sw15 { + gpios = <0x66 0x06 0x01>; + label = "GPIO TOP-LEFT"; + linux,code = <0x136>; + }; + + sw16 { + gpios = <0x66 0x07 0x01>; + label = "GPIO TOP-RIGHT"; + linux,code = <0x137>; + }; + + sw19 { + gpios = <0x97 0x09 0x01>; + label = "GPIO F1"; + linux,code = <0x2c0>; + }; + + sw20 { + gpios = <0x97 0x0f 0x01>; + label = "GPIO TOP-RIGHT2"; + linux,code = <0x139>; + }; + + sw21 { + gpios = <0x97 0x0a 0x01>; + label = "GPIO TOP-LEFT2"; + linux,code = <0x138>; + }; + + sw22 { + gpios = <0x97 0x0c 0x01>; + label = "GPIO F2"; + linux,code = <0x2c1>; + }; + + sw13 { + gpios = <0x66 0x04 0x01>; + label = "GPIO F5"; + linux,code = <0x2c4>; + }; + }; + + gpio_leds { + compatible = "gpio-leds"; + pinctrl-names = "led_pins"; + pinctrl-0 = <0xc0>; + phandle = <0x150>; + + heartbeat { + label = "blue:heartbeat"; + gpios = <0x5c 0x11 0x00>; + linux,default-trigger = "heartbeat"; + }; + }; + + backlight { + compatible = "pwm-backlight"; + pwms = <0xc1 0x00 0xf519 0x00>; + brightness-levels = <0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2a 0x2b 0x2c 0x2d 0x2e 0x2f 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x3a 0x3b 0x3c 0x3d 0x3e 0x3f 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48 0x49 0x4a 0x4b 0x4c 0x4d 0x4e 0x4f 0x50 0x51 0x52 0x53 0x54 0x55 0x56 0x57 0x58 0x59 0x5a 0x5b 0x5c 0x5d 0x5e 0x5f 0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69 0x6a 0x6b 0x6c 0x6d 0x6e 0x6f 0x70 0x71 0x72 0x73 0x74 0x75 0x76 0x77 0x78 0x79 0x7a 0x7b 0x7c 0x7d 0x7e 0x7f 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90 0x91 0x92 0x93 0x94 0x95 0x96 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f 0xa0>; + default-brightness-level = <0x33>; + phandle = <0x9d>; + }; + + rk817-sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,name = "rockchip,rk817-codec"; + simple-audio-card,mclk-fs = <0x100>; + simple-audio-card,widgets = "Microphone\0Mic Jack\0Headphone\0Headphone Jack"; + simple-audio-card,routing = "MIC_IN\0Mic Jack\0Headphone Jack\0HPOL\0Headphone Jack\0HPOR"; + simple-audio-card,hp-det-gpio = <0x66 0x16 0x01>; + simple-audio-card,codec-hp-det = <0x01>; + + simple-audio-card,cpu { + sound-dai = <0xc2>; + }; + + simple-audio-card,codec { + sound-dai = <0xc3>; + }; + }; + + vccsys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v8_sys"; + regulator-always-on; + regulator-min-microvolt = <0x39fbc0>; + regulator-max-microvolt = <0x39fbc0>; + phandle = <0x64>; + }; + + vcc_host: vcc_host { + compatible = "regulator-fixed"; + regulator-name = "vcc-host"; + gpio = <0x5c 0x0f 0x00>; + enable-active-high; + regulator-always-on; + vin-supply = <0x64>; + }; + + __symbols__ { + ddr_timing = "/ddr_timing"; + cpu0 = "/cpus/cpu@0"; + cpu1 = "/cpus/cpu@1"; + cpu2 = "/cpus/cpu@2"; + cpu3 = "/cpus/cpu@3"; + CPU_SLEEP = "/cpus/idle-states/cpu-sleep"; + CLUSTER_SLEEP = "/cpus/idle-states/cluster-sleep"; + cpu0_opp_table = "/cpu0-opp-table"; + bus_soc = "/bus-soc"; + bus_apll = "/bus-apll"; + bus_apll_opp_table = "/bus-apll-opp-table"; + display_subsystem = "/display-subsystem"; + route_lvds = "/display-subsystem/route/route-lvds"; + route_dsi = "/display-subsystem/route/route-dsi"; + route_rgb = "/display-subsystem/route/route-rgb"; + gmac_clkin = "/external-gmac-clock"; + rockchip_suspend = "/rockchip-suspend"; + xin24m = "/xin24m"; + xin32k = "/xin32k"; + pmu = "/power-management@ff000000"; + power = "/power-management@ff000000/power-controller"; + pmugrf = "/syscon@ff010000"; + pmu_io_domains = "/syscon@ff010000/io-domains"; + pmu_pvtm = "/syscon@ff010000/pmu-pvtm"; + uart0 = "/serial@ff030000"; + i2s0_8ch = "/i2s@ff060000"; + i2s1_2ch = "/i2s@ff070000"; + i2s2_2ch = "/i2s@ff080000"; + pdm = "/pdm@ff0a0000"; + crypto = "/crypto@ff0b0000"; + rng = "/rng@ff0b0000"; + gic = "/interrupt-controller@ff131000"; + grf = "/syscon@ff140000"; + io_domains = "/syscon@ff140000/io-domains"; + lvds = "/syscon@ff140000/lvds"; + lvds_in_vopb = "/syscon@ff140000/lvds/ports/port@0/endpoint@0"; + rgb = "/syscon@ff140000/rgb"; + rgb_in_vopb = "/syscon@ff140000/rgb/ports/port@0/endpoint@0"; + core_grf = "/syscon@ff148000"; + pvtm = "/syscon@ff148000/pvtm"; + uart1 = "/serial@ff158000"; + uart2 = "/serial@ff160000"; + uart3 = "/serial@ff168000"; + uart4 = "/serial@ff170000"; + uart5 = "/serial@ff178000"; + i2c0 = "/i2c@ff180000"; + rk817 = "/i2c@ff180000/pmic@20"; + pinctrl_rk8xx = "/i2c@ff180000/pmic@20/pinctrl_rk8xx"; + rk817_ts_gpio1 = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_ts_gpio1"; + rk817_gt_gpio2 = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_gt_gpio2"; + rk817_pin_ts = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_pin_ts"; + rk817_pin_gt = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_pin_gt"; + rk817_slppin_null = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_null"; + rk817_slppin_slp = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_slp"; + rk817_slppin_pwrdn = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_pwrdn"; + rk817_slppin_rst = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_rst"; + vdd_logic = "/i2c@ff180000/pmic@20/regulators/DCDC_REG1"; + vdd_arm = "/i2c@ff180000/pmic@20/regulators/DCDC_REG2"; + vcc_ddr = "/i2c@ff180000/pmic@20/regulators/DCDC_REG3"; + vcc_3v3 = "/i2c@ff180000/pmic@20/regulators/DCDC_REG4"; + vcc_1v0 = "/i2c@ff180000/pmic@20/regulators/LDO_REG1"; + vcc1v8_soc = "/i2c@ff180000/pmic@20/regulators/LDO_REG2"; + vdd1v0_soc = "/i2c@ff180000/pmic@20/regulators/LDO_REG3"; + vcc3v3_pmu = "/i2c@ff180000/pmic@20/regulators/LDO_REG4"; + vccio_sd = "/i2c@ff180000/pmic@20/regulators/LDO_REG5"; + vcc_sd = "/i2c@ff180000/pmic@20/regulators/LDO_REG6"; + vcc_backlight = "/i2c@ff180000/pmic@20/regulators/LDO_REG7"; + vcc_lcd = "/i2c@ff180000/pmic@20/regulators/LDO_REG8"; + dcdc_boost = "/i2c@ff180000/pmic@20/regulators/BOOST"; + otg_switch = "/i2c@ff180000/pmic@20/regulators/OTG_SWITCH"; + rk817_codec = "/i2c@ff180000/pmic@20/codec"; + i2c1 = "/i2c@ff190000"; + i2c2 = "/i2c@ff1a0000"; + i2c3 = "/i2c@ff1b0000"; + spi0 = "/spi@ff1d0000"; + spi1 = "/spi@ff1d8000"; + wdt = "/watchdog@ff1e0000"; + pwm0 = "/pwm@ff200000"; + pwm1 = "/pwm@ff200010"; + pwm2 = "/pwm@ff200020"; + pwm3 = "/pwm@ff200030"; + pwm4 = "/pwm@ff208000"; + pwm5 = "/pwm@ff208010"; + pwm6 = "/pwm@ff208020"; + pwm7 = "/pwm@ff208030"; + rktimer = "/rktimer@ff210000"; + dmac = "/amba/dmac@ff240000"; + thermal_zones = "/thermal-zones"; + soc_thermal = "/thermal-zones/soc-thermal"; + threshold = "/thermal-zones/soc-thermal/trips/trip-point-0"; + target = "/thermal-zones/soc-thermal/trips/trip-point-1"; + soc_crit = "/thermal-zones/soc-thermal/trips/soc-crit"; + gpu_thermal = "/thermal-zones/gpu-thermal"; + tsadc = "/tsadc@ff280000"; + saradc = "/saradc@ff288000"; + otp = "/otp@ff290000"; + otp_id = "/otp@ff290000/id@7"; + cpu_leakage = "/otp@ff290000/cpu-leakage@17"; + performance = "/otp@ff290000/performance@1e"; + cru = "/clock-controller@ff2b0000"; + cpu_boost = "/cpu-boost@ff2b8000"; + pmucru = "/pmu-clock-controller@ff2bc000"; + usb2phy_grf = "/syscon@ff2c0000"; + u2phy = "/syscon@ff2c0000/usb2-phy@100"; + u2phy_host = "/syscon@ff2c0000/usb2-phy@100/host-port"; + u2phy_otg = "/syscon@ff2c0000/usb2-phy@100/otg-port"; + video_phy = "/video-phy@ff2e0000"; + mipi_dphy_rx0 = "/mipi-dphy-rx0@ff2f0000"; + usb20_otg = "/usb@ff300000"; + usb_host0_ehci = "/usb@ff340000"; + usb_host0_ohci = "/usb@ff350000"; + gmac = "/ethernet@ff360000"; + sdmmc = "/dwmmc@ff370000"; + sdio = "/dwmmc@ff380000"; + emmc = "/dwmmc@ff390000"; + nandc0 = "/nandc@ff3b0000"; + sfc = "/sfc@ff3a0000"; + gpu = "/gpu@ff400000"; + gpu_opp_table = "/gpu-opp-table"; + hevc = "/hevc_service@ff440000"; + vpu = "/vpu_service@ff442000"; + vpu_combo = "/vpu_combo"; + hevc_mmu = "/iommu@ff440440"; + vpu_mmu = "/iommu@ff442800"; + dsi = "/dsi@ff450000"; + dsi_in_vopb = "/dsi@ff450000/ports/port@0/endpoint@0"; + timing0 = "/dsi@ff450000/panel@0/display-timings/60Hz"; + timing1 = "/dsi@ff450000/panel@0/display-timings/50Hz"; + timing2 = "/dsi@ff450000/panel@0/display-timings/75Hz"; + vopb = "/vop@ff460000"; + vopb_out = "/vop@ff460000/port"; + vopb_out_lvds = "/vop@ff460000/port/endpoint@0"; + vopb_out_dsi = "/vop@ff460000/port/endpoint@1"; + vopb_out_rgb = "/vop@ff460000/port/endpoint@2"; + vopb_mmu = "/iommu@ff460f00"; + rk_rga = "/rk_rga@ff480000"; + cif = "/cif@ff490000"; + cif_new = "/cif-new@ff490000"; + vip_mmu = "/iommu@ff490800"; + rk_isp = "/rk_isp@ff4a0000"; + rkisp1 = "/rkisp1@ff4a0000"; + isp_mmu = "/iommu@ff4a8000"; + qos_gmac = "/qos@ff518000"; + qos_gpu = "/qos@ff520000"; + qos_sdmmc = "/qos@ff52c000"; + qos_emmc = "/qos@ff538000"; + qos_nand = "/qos@ff538080"; + qos_sdio = "/qos@ff538100"; + qos_sfc = "/qos@ff538180"; + qos_usb_host = "/qos@ff540000"; + qos_usb_otg = "/qos@ff540080"; + qos_isp_128 = "/qos@ff548000"; + qos_isp_rd = "/qos@ff548080"; + qos_isp_wr = "/qos@ff548100"; + qos_isp_m1 = "/qos@ff548180"; + qos_vip = "/qos@ff548200"; + qos_rga_rd = "/qos@ff550000"; + qos_rga_wr = "/qos@ff550080"; + qos_vop_m0 = "/qos@ff550100"; + qos_vop_m1 = "/qos@ff550180"; + qos_vpu = "/qos@ff558000"; + qos_vpu_r128 = "/qos@ff558080"; + dfi = "/dfi@ff610000"; + dmc = "/dmc"; + ddr_power_model = "/dmc/ddr_power_model"; + dmc_opp_table = "/dmc-opp-table"; + rockchip_system_monitor = "/rockchip-system-monitor"; + pinctrl = "/pinctrl"; + gpio0 = "/pinctrl/gpio0@ff040000"; + gpio1 = "/pinctrl/gpio1@ff250000"; + gpio2 = "/pinctrl/gpio2@ff260000"; + gpio3 = "/pinctrl/gpio3@ff270000"; + pcfg_pull_up = "/pinctrl/pcfg-pull-up"; + pcfg_pull_down = "/pinctrl/pcfg-pull-down"; + pcfg_pull_none = "/pinctrl/pcfg-pull-none"; + pcfg_pull_none_2ma = "/pinctrl/pcfg-pull-none-2ma"; + pcfg_pull_up_2ma = "/pinctrl/pcfg-pull-up-2ma"; + pcfg_pull_up_4ma = "/pinctrl/pcfg-pull-up-4ma"; + pcfg_pull_none_4ma = "/pinctrl/pcfg-pull-none-4ma"; + pcfg_pull_down_4ma = "/pinctrl/pcfg-pull-down-4ma"; + pcfg_pull_none_8ma = "/pinctrl/pcfg-pull-none-8ma"; + pcfg_pull_up_8ma = "/pinctrl/pcfg-pull-up-8ma"; + pcfg_pull_none_12ma = "/pinctrl/pcfg-pull-none-12ma"; + pcfg_pull_up_12ma = "/pinctrl/pcfg-pull-up-12ma"; + pcfg_pull_none_smt = "/pinctrl/pcfg-pull-none-smt"; + pcfg_output_high = "/pinctrl/pcfg-output-high"; + pcfg_output_low = "/pinctrl/pcfg-output-low"; + pcfg_input_high = "/pinctrl/pcfg-input-high"; + pcfg_input = "/pinctrl/pcfg-input"; + i2c0_xfer = "/pinctrl/i2c0/i2c0-xfer"; + i2c1_xfer = "/pinctrl/i2c1/i2c1-xfer"; + i2c2_xfer = "/pinctrl/i2c2/i2c2-xfer"; + i2c3_xfer = "/pinctrl/i2c3/i2c3-xfer"; + tsadc_otp_gpio = "/pinctrl/tsadc/tsadc-otp-gpio"; + tsadc_otp_out = "/pinctrl/tsadc/tsadc-otp-out"; + uart0_xfer = "/pinctrl/uart0/uart0-xfer"; + uart0_cts = "/pinctrl/uart0/uart0-cts"; + uart0_rts = "/pinctrl/uart0/uart0-rts"; + uart0_rts_gpio = "/pinctrl/uart0/uart0-rts-gpio"; + uart1_xfer = "/pinctrl/uart1/uart1-xfer"; + uart1_cts = "/pinctrl/uart1/uart1-cts"; + uart1_rts = "/pinctrl/uart1/uart1-rts"; + uart1_rts_gpio = "/pinctrl/uart1/uart1-rts-gpio"; + uart2m0_xfer = "/pinctrl/uart2-m0/uart2m0-xfer"; + uart2m1_xfer = "/pinctrl/uart2-m1/uart2m1-xfer"; + uart3m0_xfer = "/pinctrl/uart3-m0/uart3m0-xfer"; + uart3m0_cts = "/pinctrl/uart3-m0/uart3m0-cts"; + uart3m0_rts = "/pinctrl/uart3-m0/uart3m0-rts"; + uart3m0_rts_gpio = "/pinctrl/uart3-m0/uart3m0-rts-gpio"; + uart3m1_xfer = "/pinctrl/uart3-m1/uart3m1-xfer"; + uart3m1_cts = "/pinctrl/uart3-m1/uart3m1-cts"; + uart3m1_rts = "/pinctrl/uart3-m1/uart3m1-rts"; + uart3m1_rts_gpio = "/pinctrl/uart3-m1/uart3m1-rts-gpio"; + uart4_xfer = "/pinctrl/uart4/uart4-xfer"; + uart4_cts = "/pinctrl/uart4/uart4-cts"; + uart4_rts = "/pinctrl/uart4/uart4-rts"; + uart5_xfer = "/pinctrl/uart5/uart5-xfer"; + uart5_cts = "/pinctrl/uart5/uart5-cts"; + uart5_rts = "/pinctrl/uart5/uart5-rts"; + spi0_clk = "/pinctrl/spi0/spi0-clk"; + spi0_csn = "/pinctrl/spi0/spi0-csn"; + spi0_miso = "/pinctrl/spi0/spi0-miso"; + spi0_mosi = "/pinctrl/spi0/spi0-mosi"; + spi0_clk_hs = "/pinctrl/spi0/spi0-clk-hs"; + spi0_miso_hs = "/pinctrl/spi0/spi0-miso-hs"; + spi0_mosi_hs = "/pinctrl/spi0/spi0-mosi-hs"; + spi1_clk = "/pinctrl/spi1/spi1-clk"; + spi1_csn0 = "/pinctrl/spi1/spi1-csn0"; + spi1_csn1 = "/pinctrl/spi1/spi1-csn1"; + spi1_miso = "/pinctrl/spi1/spi1-miso"; + spi1_mosi = "/pinctrl/spi1/spi1-mosi"; + spi1_clk_hs = "/pinctrl/spi1/spi1-clk-hs"; + spi1_miso_hs = "/pinctrl/spi1/spi1-miso-hs"; + spi1_mosi_hs = "/pinctrl/spi1/spi1-mosi-hs"; + pdm_clk0m0 = "/pinctrl/pdm/pdm-clk0m0"; + pdm_clk0m1 = "/pinctrl/pdm/pdm-clk0m1"; + pdm_clk1 = "/pinctrl/pdm/pdm-clk1"; + pdm_sdi0m0 = "/pinctrl/pdm/pdm-sdi0m0"; + pdm_sdi0m1 = "/pinctrl/pdm/pdm-sdi0m1"; + pdm_sdi1 = "/pinctrl/pdm/pdm-sdi1"; + pdm_sdi2 = "/pinctrl/pdm/pdm-sdi2"; + pdm_sdi3 = "/pinctrl/pdm/pdm-sdi3"; + pdm_clk0m0_sleep = "/pinctrl/pdm/pdm-clk0m0-sleep"; + pdm_clk0m_sleep1 = "/pinctrl/pdm/pdm-clk0m1-sleep"; + pdm_clk1_sleep = "/pinctrl/pdm/pdm-clk1-sleep"; + pdm_sdi0m0_sleep = "/pinctrl/pdm/pdm-sdi0m0-sleep"; + pdm_sdi0m1_sleep = "/pinctrl/pdm/pdm-sdi0m1-sleep"; + pdm_sdi1_sleep = "/pinctrl/pdm/pdm-sdi1-sleep"; + pdm_sdi2_sleep = "/pinctrl/pdm/pdm-sdi2-sleep"; + pdm_sdi3_sleep = "/pinctrl/pdm/pdm-sdi3-sleep"; + i2s0_8ch_mclk = "/pinctrl/i2s0/i2s0-8ch-mclk"; + i2s0_8ch_sclktx = "/pinctrl/i2s0/i2s0-8ch-sclktx"; + i2s0_8ch_sclkrx = "/pinctrl/i2s0/i2s0-8ch-sclkrx"; + i2s0_8ch_lrcktx = "/pinctrl/i2s0/i2s0-8ch-lrcktx"; + i2s0_8ch_lrckrx = "/pinctrl/i2s0/i2s0-8ch-lrckrx"; + i2s0_8ch_sdo0 = "/pinctrl/i2s0/i2s0-8ch-sdo0"; + i2s0_8ch_sdo1 = "/pinctrl/i2s0/i2s0-8ch-sdo1"; + i2s0_8ch_sdo2 = "/pinctrl/i2s0/i2s0-8ch-sdo2"; + i2s0_8ch_sdo3 = "/pinctrl/i2s0/i2s0-8ch-sdo3"; + i2s0_8ch_sdi0 = "/pinctrl/i2s0/i2s0-8ch-sdi0"; + i2s0_8ch_sdi1 = "/pinctrl/i2s0/i2s0-8ch-sdi1"; + i2s0_8ch_sdi2 = "/pinctrl/i2s0/i2s0-8ch-sdi2"; + i2s0_8ch_sdi3 = "/pinctrl/i2s0/i2s0-8ch-sdi3"; + i2s1_2ch_mclk = "/pinctrl/i2s1/i2s1-2ch-mclk"; + i2s1_2ch_sclk = "/pinctrl/i2s1/i2s1-2ch-sclk"; + i2s1_2ch_lrck = "/pinctrl/i2s1/i2s1-2ch-lrck"; + i2s1_2ch_sdi = "/pinctrl/i2s1/i2s1-2ch-sdi"; + i2s1_2ch_sdo = "/pinctrl/i2s1/i2s1-2ch-sdo"; + i2s2_2ch_mclk = "/pinctrl/i2s2/i2s2-2ch-mclk"; + i2s2_2ch_sclk = "/pinctrl/i2s2/i2s2-2ch-sclk"; + i2s2_2ch_lrck = "/pinctrl/i2s2/i2s2-2ch-lrck"; + i2s2_2ch_sdi = "/pinctrl/i2s2/i2s2-2ch-sdi"; + i2s2_2ch_sdo = "/pinctrl/i2s2/i2s2-2ch-sdo"; + sdmmc_clk = "/pinctrl/sdmmc/sdmmc-clk"; + sdmmc_cmd = "/pinctrl/sdmmc/sdmmc-cmd"; + sdmmc_det = "/pinctrl/sdmmc/sdmmc-det"; + sdmmc_bus1 = "/pinctrl/sdmmc/sdmmc-bus1"; + sdmmc_bus4 = "/pinctrl/sdmmc/sdmmc-bus4"; + sdmmc_gpio = "/pinctrl/sdmmc/sdmmc-gpio"; + sdio_clk = "/pinctrl/sdio/sdio-clk"; + sdio_cmd = "/pinctrl/sdio/sdio-cmd"; + sdio_bus4 = "/pinctrl/sdio/sdio-bus4"; + sdio_gpio = "/pinctrl/sdio/sdio-gpio"; + emmc_clk = "/pinctrl/emmc/emmc-clk"; + emmc_cmd = "/pinctrl/emmc/emmc-cmd"; + emmc_pwren = "/pinctrl/emmc/emmc-pwren"; + emmc_rstnout = "/pinctrl/emmc/emmc-rstnout"; + emmc_bus1 = "/pinctrl/emmc/emmc-bus1"; + emmc_bus4 = "/pinctrl/emmc/emmc-bus4"; + emmc_bus8 = "/pinctrl/emmc/emmc-bus8"; + flash_cs0 = "/pinctrl/flash/flash-cs0"; + flash_rdy = "/pinctrl/flash/flash-rdy"; + flash_dqs = "/pinctrl/flash/flash-dqs"; + flash_ale = "/pinctrl/flash/flash-ale"; + flash_cle = "/pinctrl/flash/flash-cle"; + flash_wrn = "/pinctrl/flash/flash-wrn"; + flash_csl = "/pinctrl/flash/flash-csl"; + flash_rdn = "/pinctrl/flash/flash-rdn"; + flash_bus8 = "/pinctrl/flash/flash-bus8"; + lcdc_m0_rgb_pins = "/pinctrl/lcdc/lcdc-m0-rgb-pins"; + lcdc_m0_sleep_pins = "/pinctrl/lcdc/lcdc-m0-sleep-pins"; + lcdc_m1_rgb_pins = "/pinctrl/lcdc/lcdc-m1-rgb-pins"; + lcdc_m1_sleep_pins = "/pinctrl/lcdc/lcdc-m1-sleep-pins"; + pwm0_pin = "/pinctrl/pwm0/pwm0-pin"; + pwm1_pin = "/pinctrl/pwm1/pwm1-pin"; + pwm2_pin = "/pinctrl/pwm2/pwm2-pin"; + pwm3_pin = "/pinctrl/pwm3/pwm3-pin"; + pwm4_pin = "/pinctrl/pwm4/pwm4-pin"; + pwm5_pin = "/pinctrl/pwm5/pwm5-pin"; + pwm6_pin = "/pinctrl/pwm6/pwm6-pin"; + pwm7_pin = "/pinctrl/pwm7/pwm7-pin"; + rmii_pins = "/pinctrl/gmac/rmii-pins"; + mac_refclk_12ma = "/pinctrl/gmac/mac-refclk-12ma"; + mac_refclk = "/pinctrl/gmac/mac-refclk"; + cif_clkout_m0 = "/pinctrl/cif-m0/cif-clkout-m0"; + dvp_d2d9_m0 = "/pinctrl/cif-m0/dvp-d2d9-m0"; + dvp_d0d1_m0 = "/pinctrl/cif-m0/dvp-d0d1-m0"; + dvp_d10d11_m0 = "/pinctrl/cif-m0/d10-d11-m0"; + cif_clkout_m1 = "/pinctrl/cif-m1/cif-clkout-m1"; + dvp_d2d9_m1 = "/pinctrl/cif-m1/dvp-d2d9-m1"; + dvp_d0d1_m1 = "/pinctrl/cif-m1/dvp-d0d1-m1"; + dvp_d10d11_m1 = "/pinctrl/cif-m1/d10-d11-m1"; + isp_prelight = "/pinctrl/isp/isp-prelight"; + pmic_int = "/pinctrl/pmic/pmic_int"; + soc_slppin_gpio = "/pinctrl/pmic/soc_slppin_gpio"; + soc_slppin_slp = "/pinctrl/pmic/soc_slppin_slp"; + soc_slppin_rst = "/pinctrl/pmic/soc_slppin_rst"; + led_pins = "/pinctrl/leds/led-pins"; + btn_pins = "/pinctrl/btns/btn-pins"; + drm_logo = "/reserved-memory/drm-logo@00000000"; + ramoops_mem = "/reserved-memory/region@110000"; + gpio_keys = "/odroidgo3-keys"; + joypad = "/odroidgo3-joypad"; + leds = "/gpio_leds"; + backlight = "/backlight"; + vccsys = "/vccsys"; + }; +}; diff --git a/config/archr-dts/R36S-DTB/DTS/Panel4.dts b/config/archr-dts/R36S-DTB/DTS/Panel4.dts new file mode 100644 index 0000000000..c45f3e1efe --- /dev/null +++ b/config/archr-dts/R36S-DTB/DTS/Panel4.dts @@ -0,0 +1,4063 @@ +/dts-v1/; + +/ { + compatible = "rockchip,rk3326-odroidgo3-linux\0rockchip,rk3326"; + interrupt-parent = <0x01>; + #address-cells = <0x02>; + #size-cells = <0x02>; + model = "Game Console R35S/R36S fix by lxc"; + + ddr_timing { + compatible = "rockchip,ddr-timing"; + ddr2_speed_bin = <0x00>; + ddr3_speed_bin = <0x15>; + ddr4_speed_bin = <0x0c>; + pd_idle = <0x0d>; + sr_idle = <0x5d>; + sr_mc_gate_idle = <0x00>; + srpd_lite_idle = <0x00>; + standby_idle = <0x00>; + auto_pd_dis_freq = <0x42a>; + auto_sr_dis_freq = <0x320>; + ddr2_dll_dis_freq = <0x12c>; + ddr3_dll_dis_freq = <0x12c>; + ddr4_dll_dis_freq = <0x271>; + phy_dll_dis_freq = <0x190>; + ddr2_odt_dis_freq = <0x64>; + phy_ddr2_odt_dis_freq = <0x64>; + ddr2_drv = <0x01>; + ddr2_odt = <0x96>; + phy_ddr2_ca_drv = <0x15>; + phy_ddr2_ck_drv = <0x12>; + phy_ddr2_dq_drv = <0x15>; + phy_ddr2_odt = <0x02>; + ddr3_odt_dis_freq = <0x190>; + phy_ddr3_odt_dis_freq = <0x190>; + ddr3_drv = <0x28>; + ddr3_odt = <0x78>; + phy_ddr3_ca_drv = <0x15>; + phy_ddr3_ck_drv = <0x12>; + phy_ddr3_dq_drv = <0x15>; + phy_ddr3_odt = <0x02>; + phy_lpddr2_odt_dis_freq = <0x29a>; + lpddr2_drv = <0x28>; + phy_lpddr2_ca_drv = <0x16>; + phy_lpddr2_ck_drv = <0x13>; + phy_lpddr2_dq_drv = <0x16>; + phy_lpddr2_odt = <0x00>; + lpddr3_odt_dis_freq = <0x190>; + phy_lpddr3_odt_dis_freq = <0x190>; + lpddr3_drv = <0x28>; + lpddr3_odt = <0xf0>; + phy_lpddr3_ca_drv = <0x16>; + phy_lpddr3_ck_drv = <0x13>; + phy_lpddr3_dq_drv = <0x16>; + phy_lpddr3_odt = <0x02>; + lpddr4_odt_dis_freq = <0x320>; + phy_lpddr4_odt_dis_freq = <0x320>; + lpddr4_drv = <0x3c>; + lpddr4_dq_odt = <0x28>; + lpddr4_ca_odt = <0x28>; + phy_lpddr4_ca_drv = <0x14>; + phy_lpddr4_ck_cs_drv = <0x06>; + phy_lpddr4_dq_drv = <0x06>; + phy_lpddr4_odt = <0x10>; + ddr4_odt_dis_freq = <0x29a>; + phy_ddr4_odt_dis_freq = <0x29a>; + ddr4_drv = <0x22>; + ddr4_odt = <0xf0>; + phy_ddr4_ca_drv = <0x16>; + phy_ddr4_ck_drv = <0x13>; + phy_ddr4_dq_drv = <0x16>; + phy_ddr4_odt = <0x02>; + ddr3a1_ddr4a9_de-skew = <0x06>; + ddr3a0_ddr4a10_de-skew = <0x07>; + ddr3a3_ddr4a6_de-skew = <0x07>; + ddr3a2_ddr4a4_de-skew = <0x07>; + ddr3a5_ddr4a8_de-skew = <0x07>; + ddr3a4_ddr4a5_de-skew = <0x07>; + ddr3a7_ddr4a11_de-skew = <0x07>; + ddr3a6_ddr4a7_de-skew = <0x06>; + ddr3a9_ddr4a0_de-skew = <0x07>; + ddr3a8_ddr4a13_de-skew = <0x07>; + ddr3a11_ddr4a3_de-skew = <0x07>; + ddr3a10_ddr4cs0_de-skew = <0x07>; + ddr3a13_ddr4a2_de-skew = <0x07>; + ddr3a12_ddr4ba1_de-skew = <0x07>; + ddr3a15_ddr4odt0_de-skew = <0x07>; + ddr3a14_ddr4a1_de-skew = <0x07>; + ddr3ba1_ddr4a15_de-skew = <0x07>; + ddr3ba0_ddr4bg0_de-skew = <0x07>; + ddr3ras_ddr4cke_de-skew = <0x07>; + ddr3ba2_ddr4ba0_de-skew = <0x07>; + ddr3we_ddr4bg1_de-skew = <0x07>; + ddr3cas_ddr4a12_de-skew = <0x07>; + ddr3ckn_ddr4ckn_de-skew = <0x07>; + ddr3ckp_ddr4ckp_de-skew = <0x07>; + ddr3cke_ddr4a16_de-skew = <0x07>; + ddr3odt0_ddr4a14_de-skew = <0x07>; + ddr3cs0_ddr4act_de-skew = <0x06>; + ddr3reset_ddr4reset_de-skew = <0x07>; + ddr3cs1_ddr4cs1_de-skew = <0x06>; + ddr3odt1_ddr4odt1_de-skew = <0x07>; + cs0_dm0_rx_de-skew = <0x07>; + cs0_dm0_tx_de-skew = <0x07>; + cs0_dq0_rx_de-skew = <0x08>; + cs0_dq0_tx_de-skew = <0x08>; + cs0_dq1_rx_de-skew = <0x09>; + cs0_dq1_tx_de-skew = <0x08>; + cs0_dq2_rx_de-skew = <0x08>; + cs0_dq2_tx_de-skew = <0x08>; + cs0_dq3_rx_de-skew = <0x08>; + cs0_dq3_tx_de-skew = <0x08>; + cs0_dq4_rx_de-skew = <0x09>; + cs0_dq4_tx_de-skew = <0x08>; + cs0_dq5_rx_de-skew = <0x09>; + cs0_dq5_tx_de-skew = <0x08>; + cs0_dq6_rx_de-skew = <0x09>; + cs0_dq6_tx_de-skew = <0x08>; + cs0_dq7_rx_de-skew = <0x08>; + cs0_dq7_tx_de-skew = <0x08>; + cs0_dqs0_rx_de-skew = <0x06>; + cs0_dqs0p_tx_de-skew = <0x09>; + cs0_dqs0n_tx_de-skew = <0x09>; + cs0_dm1_rx_de-skew = <0x07>; + cs0_dm1_tx_de-skew = <0x06>; + cs0_dq8_rx_de-skew = <0x08>; + cs0_dq8_tx_de-skew = <0x07>; + cs0_dq9_rx_de-skew = <0x09>; + cs0_dq9_tx_de-skew = <0x07>; + cs0_dq10_rx_de-skew = <0x08>; + cs0_dq10_tx_de-skew = <0x08>; + cs0_dq11_rx_de-skew = <0x08>; + cs0_dq11_tx_de-skew = <0x07>; + cs0_dq12_rx_de-skew = <0x08>; + cs0_dq12_tx_de-skew = <0x08>; + cs0_dq13_rx_de-skew = <0x09>; + cs0_dq13_tx_de-skew = <0x07>; + cs0_dq14_rx_de-skew = <0x09>; + cs0_dq14_tx_de-skew = <0x08>; + cs0_dq15_rx_de-skew = <0x09>; + cs0_dq15_tx_de-skew = <0x07>; + cs0_dqs1_rx_de-skew = <0x07>; + cs0_dqs1p_tx_de-skew = <0x09>; + cs0_dqs1n_tx_de-skew = <0x09>; + cs0_dm2_rx_de-skew = <0x07>; + cs0_dm2_tx_de-skew = <0x07>; + cs0_dq16_rx_de-skew = <0x09>; + cs0_dq16_tx_de-skew = <0x09>; + cs0_dq17_rx_de-skew = <0x07>; + cs0_dq17_tx_de-skew = <0x09>; + cs0_dq18_rx_de-skew = <0x07>; + cs0_dq18_tx_de-skew = <0x08>; + cs0_dq19_rx_de-skew = <0x07>; + cs0_dq19_tx_de-skew = <0x09>; + cs0_dq20_rx_de-skew = <0x09>; + cs0_dq20_tx_de-skew = <0x09>; + cs0_dq21_rx_de-skew = <0x09>; + cs0_dq21_tx_de-skew = <0x09>; + cs0_dq22_rx_de-skew = <0x08>; + cs0_dq22_tx_de-skew = <0x09>; + cs0_dq23_rx_de-skew = <0x08>; + cs0_dq23_tx_de-skew = <0x09>; + cs0_dqs2_rx_de-skew = <0x06>; + cs0_dqs2p_tx_de-skew = <0x09>; + cs0_dqs2n_tx_de-skew = <0x09>; + cs0_dm3_rx_de-skew = <0x07>; + cs0_dm3_tx_de-skew = <0x07>; + cs0_dq24_rx_de-skew = <0x08>; + cs0_dq24_tx_de-skew = <0x08>; + cs0_dq25_rx_de-skew = <0x09>; + cs0_dq25_tx_de-skew = <0x09>; + cs0_dq26_rx_de-skew = <0x09>; + cs0_dq26_tx_de-skew = <0x08>; + cs0_dq27_rx_de-skew = <0x09>; + cs0_dq27_tx_de-skew = <0x08>; + cs0_dq28_rx_de-skew = <0x09>; + cs0_dq28_tx_de-skew = <0x09>; + cs0_dq29_rx_de-skew = <0x09>; + cs0_dq29_tx_de-skew = <0x09>; + cs0_dq30_rx_de-skew = <0x08>; + cs0_dq30_tx_de-skew = <0x08>; + cs0_dq31_rx_de-skew = <0x08>; + cs0_dq31_tx_de-skew = <0x08>; + cs0_dqs3_rx_de-skew = <0x07>; + cs0_dqs3p_tx_de-skew = <0x09>; + cs0_dqs3n_tx_de-skew = <0x09>; + cs1_dm0_rx_de-skew = <0x07>; + cs1_dm0_tx_de-skew = <0x07>; + cs1_dq0_rx_de-skew = <0x08>; + cs1_dq0_tx_de-skew = <0x08>; + cs1_dq1_rx_de-skew = <0x09>; + cs1_dq1_tx_de-skew = <0x08>; + cs1_dq2_rx_de-skew = <0x08>; + cs1_dq2_tx_de-skew = <0x08>; + cs1_dq3_rx_de-skew = <0x08>; + cs1_dq3_tx_de-skew = <0x08>; + cs1_dq4_rx_de-skew = <0x08>; + cs1_dq4_tx_de-skew = <0x08>; + cs1_dq5_rx_de-skew = <0x09>; + cs1_dq5_tx_de-skew = <0x08>; + cs1_dq6_rx_de-skew = <0x09>; + cs1_dq6_tx_de-skew = <0x08>; + cs1_dq7_rx_de-skew = <0x08>; + cs1_dq7_tx_de-skew = <0x08>; + cs1_dqs0_rx_de-skew = <0x06>; + cs1_dqs0p_tx_de-skew = <0x09>; + cs1_dqs0n_tx_de-skew = <0x09>; + cs1_dm1_rx_de-skew = <0x07>; + cs1_dm1_tx_de-skew = <0x07>; + cs1_dq8_rx_de-skew = <0x08>; + cs1_dq8_tx_de-skew = <0x08>; + cs1_dq9_rx_de-skew = <0x08>; + cs1_dq9_tx_de-skew = <0x07>; + cs1_dq10_rx_de-skew = <0x07>; + cs1_dq10_tx_de-skew = <0x08>; + cs1_dq11_rx_de-skew = <0x08>; + cs1_dq11_tx_de-skew = <0x08>; + cs1_dq12_rx_de-skew = <0x08>; + cs1_dq12_tx_de-skew = <0x07>; + cs1_dq13_rx_de-skew = <0x08>; + cs1_dq13_tx_de-skew = <0x08>; + cs1_dq14_rx_de-skew = <0x08>; + cs1_dq14_tx_de-skew = <0x08>; + cs1_dq15_rx_de-skew = <0x08>; + cs1_dq15_tx_de-skew = <0x07>; + cs1_dqs1_rx_de-skew = <0x07>; + cs1_dqs1p_tx_de-skew = <0x09>; + cs1_dqs1n_tx_de-skew = <0x09>; + cs1_dm2_rx_de-skew = <0x07>; + cs1_dm2_tx_de-skew = <0x08>; + cs1_dq16_rx_de-skew = <0x08>; + cs1_dq16_tx_de-skew = <0x09>; + cs1_dq17_rx_de-skew = <0x08>; + cs1_dq17_tx_de-skew = <0x09>; + cs1_dq18_rx_de-skew = <0x07>; + cs1_dq18_tx_de-skew = <0x08>; + cs1_dq19_rx_de-skew = <0x08>; + cs1_dq19_tx_de-skew = <0x09>; + cs1_dq20_rx_de-skew = <0x09>; + cs1_dq20_tx_de-skew = <0x09>; + cs1_dq21_rx_de-skew = <0x09>; + cs1_dq21_tx_de-skew = <0x09>; + cs1_dq22_rx_de-skew = <0x08>; + cs1_dq22_tx_de-skew = <0x09>; + cs1_dq23_rx_de-skew = <0x08>; + cs1_dq23_tx_de-skew = <0x09>; + cs1_dqs2_rx_de-skew = <0x06>; + cs1_dqs2p_tx_de-skew = <0x09>; + cs1_dqs2n_tx_de-skew = <0x09>; + cs1_dm3_rx_de-skew = <0x07>; + cs1_dm3_tx_de-skew = <0x07>; + cs1_dq24_rx_de-skew = <0x08>; + cs1_dq24_tx_de-skew = <0x09>; + cs1_dq25_rx_de-skew = <0x09>; + cs1_dq25_tx_de-skew = <0x09>; + cs1_dq26_rx_de-skew = <0x09>; + cs1_dq26_tx_de-skew = <0x08>; + cs1_dq27_rx_de-skew = <0x08>; + cs1_dq27_tx_de-skew = <0x08>; + cs1_dq28_rx_de-skew = <0x09>; + cs1_dq28_tx_de-skew = <0x09>; + cs1_dq29_rx_de-skew = <0x09>; + cs1_dq29_tx_de-skew = <0x09>; + cs1_dq30_rx_de-skew = <0x09>; + cs1_dq30_tx_de-skew = <0x08>; + cs1_dq31_rx_de-skew = <0x08>; + cs1_dq31_tx_de-skew = <0x08>; + cs1_dqs3_rx_de-skew = <0x07>; + cs1_dqs3p_tx_de-skew = <0x09>; + cs1_dqs3n_tx_de-skew = <0x09>; + phandle = <0xaf>; + }; + + aliases { + ethernet0 = "/ethernet@ff360000"; + i2c0 = "/i2c@ff180000"; + i2c1 = "/i2c@ff190000"; + i2c2 = "/i2c@ff1a0000"; + i2c3 = "/i2c@ff1b0000"; + serial0 = "/serial@ff030000"; + serial1 = "/serial@ff158000"; + serial2 = "/serial@ff160000"; + serial3 = "/serial@ff168000"; + serial4 = "/serial@ff170000"; + serial5 = "/serial@ff178000"; + spi0 = "/spi@ff1d0000"; + spi1 = "/spi@ff1d8000"; + }; + + cpus { + #address-cells = <0x02>; + #size-cells = <0x00>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x00>; + enable-method = "psci"; + clocks = <0x02 0x07>; + #cooling-cells = <0x02>; + dynamic-power-coefficient = <0x5a>; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + cpu-supply = <0x06>; + phandle = <0x09>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x01>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0a>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x02>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0b>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x03>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0c>; + }; + + idle-states { + entry-method = "psci"; + + cpu-sleep { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x10000>; + entry-latency-us = <0x78>; + exit-latency-us = <0xfa>; + min-residency-us = <0x384>; + phandle = <0x04>; + }; + + cluster-sleep { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x1010000>; + entry-latency-us = <0x190>; + exit-latency-us = <0x1f4>; + min-residency-us = <0x7d0>; + phandle = <0x05>; + }; + }; + }; + + cpu0-opp-table { + compatible = "operating-points-v2"; + opp-shared; + rockchip,temp-hysteresis = <0x1388>; + rockchip,low-temp = <0x00>; + rockchip,low-temp-min-volt = <0xf4240>; + rockchip,low-temp-adjust-volt = <0x00 0x5e8 0xc350>; + clocks = <0x02 0x01>; + rockchip,avs-scale = <0x04>; + rockchip,max-volt = <0x149970>; + rockchip,evb-irdrop = <0x61a8>; + nvmem-cells = <0x07 0x08>; + nvmem-cell-names = "cpu_leakage\0performance"; + rockchip,bin-scaling-sel = <0x00 0x0d 0x01 0x0d>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-freq = <0x639c0>; + rockchip,pvtm-volt = <0xf4240>; + rockchip,pvtm-ch = <0x00 0x00>; + rockchip,pvtm-sample-time = <0x3e8>; + rockchip,pvtm-number = <0x0a>; + rockchip,pvtm-error = <0x3e8>; + rockchip,pvtm-ref-temp = <0x28>; + rockchip,pvtm-temp-prop = <0xffffffc8 0xffffffc8>; + rockchip,thermal-zone = "soc-thermal"; + rockchip,avs = <0x01>; + phandle = <0x03>; + + opp-1008000000 { + opp-hz = <0x00 0x3c14dc00>; + opp-microvolt = <0x11edd8 0x11edd8 0x149970>; + opp-microvolt-L0 = <0x11edd8 0x11edd8 0x149970>; + opp-microvolt-L1 = <0x112a88 0x112a88 0x149970>; + opp-microvolt-L2 = <0x112a88 0x112a88 0x149970>; + opp-microvolt-L3 = <0x100590 0x100590 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1200000000 { + opp-hz = <0x00 0x47868c00>; + opp-microvolt = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L0 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L1 = <0x137478 0x137478 0x149970>; + opp-microvolt-L2 = <0x1312d0 0x1312d0 0x149970>; + opp-microvolt-L3 = <0x124f80 0x124f80 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1248000000 { + opp-hz = <0x00 0x4a62f800>; + opp-microvolt = <0x149970 0x149970 0x149970>; + opp-microvolt-L0 = <0x149970 0x149970 0x149970>; + opp-microvolt-L1 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L2 = <0x137478 0x137478 0x149970>; + opp-microvolt-L3 = <0x12b128 0x12b128 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1296000000 { + opp-hz = <0x00 0x4d3f6400>; + opp-microvolt = <0x149970 0x149970 0x149970>; + opp-microvolt-L0 = <0x149970 0x149970 0x149970>; + opp-microvolt-L1 = <0x149970 0x149970 0x149970>; + opp-microvolt-L2 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L3 = <0x1312d0 0x1312d0 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1512000000 { + opp-hz = <0x00 0x5a1f4a00>; + opp-microvolt = <0x149970 0x149970 0x149970>; + opp-microvolt-L0 = <0x149970 0x149970 0x149970>; + opp-microvolt-L1 = <0x149970 0x149970 0x149970>; + opp-microvolt-L2 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L3 = <0x1312d0 0x1312d0 0x149970>; + clock-latency-ns = <0x9c40>; + }; + }; + + arm-pmu { + compatible = "arm,cortex-a53-pmu"; + interrupts = <0x00 0x64 0x04 0x00 0x65 0x04 0x00 0x66 0x04 0x00 0x67 0x04>; + interrupt-affinity = <0x09 0x0a 0x0b 0x0c>; + }; + + bus-soc { + compatible = "rockchip,px30-bus"; + rockchip,busfreq-policy = "autocs"; + phandle = <0xc4>; + + soc-bus0 { + bus-id = <0x00>; + timer-us = <0x14>; + enable-msk = <0x40f7>; + status = "disabled"; + }; + + soc-bus1 { + bus-id = <0x01>; + timer-us = <0xc8>; + enable-msk = <0x40bf>; + status = "disabled"; + }; + + soc-bus2 { + bus-id = <0x02>; + timer-us = <0xc8>; + enable-msk = <0x4007>; + status = "disabled"; + }; + }; + + bus-apll { + compatible = "rockchip,px30-bus"; + rockchip,busfreq-policy = "clkfreq"; + clocks = <0x02 0x01>; + clock-names = "bus"; + operating-points-v2 = <0x0d>; + status = "okay"; + bus-supply = <0x0e>; + phandle = <0xc5>; + }; + + bus-apll-opp-table { + compatible = "operating-points-v2"; + opp-shared; + phandle = <0x0d>; + + opp-1512000000 { + opp-hz = <0x00 0x5a1f4a00>; + opp-microvolt = <0xf4240>; + }; + + opp-1008000000 { + opp-hz = <0x00 0x3c14dc00>; + opp-microvolt = <0xe7ef0>; + }; + }; + + cpuinfo { + compatible = "rockchip,cpuinfo"; + nvmem-cells = <0x0f>; + nvmem-cell-names = "id"; + }; + + display-subsystem { + compatible = "rockchip,display-subsystem"; + ports = <0x10>; + status = "okay"; + logo-memory-region = <0x11>; + phandle = <0xc6>; + + route { + + route-lvds { + status = "disabled"; + logo,uboot = "logo.gif"; + logo,kernel = "logo_kernel.gif"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x12>; + phandle = <0xc7>; + }; + + route-dsi { + status = "okay"; + logo,uboot = "logo.gif"; + logo,kernel = "logo_kernel.gif"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x13>; + phandle = <0xc8>; + }; + + route-rgb { + status = "disabled"; + logo,uboot = "logo.gif"; + logo,kernel = "logo_kernel.gif"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x14>; + phandle = <0xc9>; + }; + }; + }; + + firmware { + + optee { + compatible = "linaro,optee-tz"; + method = "smc"; + }; + }; + + external-gmac-clock { + compatible = "fixed-clock"; + clock-frequency = <0x2faf080>; + clock-output-names = "gmac_clkin"; + #clock-cells = <0x00>; + phandle = <0xca>; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + rockchip-suspend { + compatible = "rockchip,pm-px30"; + status = "okay"; + rockchip,sleep-debug-en = <0x01>; + rockchip,sleep-mode-config = <0x20702>; + rockchip,wakeup-config = <0x85>; + phandle = <0xcb>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <0x01 0x0d 0xf04 0x01 0x0e 0xf04 0x01 0x0b 0xf04 0x01 0x0a 0xf04>; + }; + + xin24m { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x16e3600>; + clock-output-names = "xin24m"; + phandle = <0xcc>; + }; + + xin32k { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x8000>; + clock-output-names = "xin32k"; + phandle = <0xcd>; + }; + + power-management@ff000000 { + compatible = "rockchip,px30-pmu\0syscon\0simple-mfd"; + reg = <0x00 0xff000000 0x00 0x1000>; + phandle = <0xce>; + + power-controller { + compatible = "rockchip,px30-power-controller"; + #power-domain-cells = <0x01>; + #address-cells = <0x01>; + #size-cells = <0x00>; + phandle = <0x8a>; + + pd_usb@5 { + reg = <0x05>; + clocks = <0x02 0x103 0x02 0x102 0x02 0x3c>; + pm_qos = <0x15 0x16>; + }; + + pd_sdcard@7 { + reg = <0x07>; + clocks = <0x02 0xf7 0x02 0x3b>; + pm_qos = <0x17>; + }; + + pd_gmac@9 { + reg = <0x09>; + clocks = <0x02 0xb2 0x02 0x143 0x02 0x40 0x02 0x3f>; + pm_qos = <0x18>; + }; + + pd_mmc_nand@10 { + reg = <0x0a>; + clocks = <0x02 0xfe 0x02 0x100 0x02 0xff 0x02 0x101 0x02 0x39 0x02 0x37 0x02 0x38 0x02 0x3a>; + pm_qos = <0x19 0x1a 0x1b 0x1c>; + }; + + pd_vpu@11 { + reg = <0x0b>; + clocks = <0x02 0xaf 0x02 0xf4 0x02 0x4b>; + pm_qos = <0x1d 0x1e>; + }; + + pd_vo@12 { + reg = <0x0c>; + clocks = <0x02 0xb7 0x02 0xb5 0x02 0xb6 0x02 0x96 0x02 0x97 0x02 0xfd 0x02 0xfb 0x02 0xfc 0x02 0x144 0x02 0x35 0x02 0x36>; + pm_qos = <0x1f 0x20 0x21 0x22>; + }; + + pd_vi@13 { + reg = <0x0d>; + clocks = <0x02 0xb3 0x02 0xb4 0x02 0xf9 0x02 0xfa 0x02 0x33>; + pm_qos = <0x23 0x24 0x25 0x26 0x27>; + }; + + pd_gpu@14 { + reg = <0x0e>; + clocks = <0x02 0x49>; + pm_qos = <0x28>; + }; + }; + }; + + syscon@ff010000 { + compatible = "rockchip,px30-pmugrf\0syscon\0simple-mfd"; + reg = <0x00 0xff010000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0xac>; + + io-domains { + compatible = "rockchip,px30-pmu-io-voltage-domain"; + status = "okay"; + pmuio1-supply = <0x29>; + pmuio2-supply = <0x29>; + phandle = <0xcf>; + }; + + reboot-mode { + compatible = "syscon-reboot-mode"; + offset = <0x200>; + mode-bootloader = <0x5242c301>; + mode-charge = <0x5242c30b>; + mode-fastboot = <0x5242c309>; + mode-loader = <0x5242c301>; + mode-normal = <0x5242c300>; + mode-recovery = <0x5242c303>; + mode-ums = <0x5242c30c>; + }; + + pmu-pvtm { + compatible = "rockchip,px30-pmu-pvtm"; + clocks = <0x2a 0x07>; + clock-names = "pmu"; + status = "okay"; + phandle = <0xd0>; + }; + }; + + serial@ff030000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff030000 0x00 0x100>; + interrupts = <0x00 0x0f 0x04>; + clocks = <0x2a 0x06 0x2a 0x15>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x00 0x2b 0x01>; + pinctrl-names = "default"; + pinctrl-0 = <0x2c 0x2d 0x2e>; + status = "disabled"; + phandle = <0xd1>; + }; + + i2s@ff060000 { + compatible = "rockchip,px30-i2s-tdm"; + reg = <0x00 0xff060000 0x00 0x1000>; + interrupts = <0x00 0x0c 0x04>; + clocks = <0x02 0x10 0x02 0x12 0x02 0x106>; + clock-names = "mclk_tx\0mclk_rx\0hclk"; + dmas = <0x2b 0x10 0x2b 0x11>; + dma-names = "tx\0rx"; + resets = <0x02 0x84 0x02 0xbf>; + reset-names = "tx-m\0rx-m"; + rockchip,cru = <0x02>; + rockchip,grf = <0x2f>; + pinctrl-names = "default"; + pinctrl-0 = <0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x3a 0x3b>; + status = "disabled"; + phandle = <0xd2>; + }; + + i2s@ff070000 { + compatible = "rockchip,px30-i2s\0rockchip,rk3066-i2s"; + reg = <0x00 0xff070000 0x00 0x1000>; + interrupts = <0x00 0x0d 0x04>; + clocks = <0x02 0x14 0x02 0x107>; + clock-names = "i2s_clk\0i2s_hclk"; + dmas = <0x2b 0x12 0x2b 0x13>; + dma-names = "tx\0rx"; + resets = <0x02 0x86 0x02 0x85>; + reset-names = "reset-m\0reset-h"; + pinctrl-names = "default"; + pinctrl-0 = <0x3c 0x3d 0x3e 0x3f>; + status = "okay"; + #sound-dai-cells = <0x00>; + phandle = <0xc2>; + }; + + i2s@ff080000 { + compatible = "rockchip,px30-i2s\0rockchip,rk3066-i2s"; + reg = <0x00 0xff080000 0x00 0x1000>; + interrupts = <0x00 0x0e 0x04>; + clocks = <0x02 0x16 0x02 0x108>; + clock-names = "i2s_clk\0i2s_hclk"; + dmas = <0x2b 0x14 0x2b 0x15>; + dma-names = "tx\0rx"; + resets = <0x02 0x88 0x02 0x87>; + reset-names = "reset-m\0reset-h"; + pinctrl-names = "default"; + pinctrl-0 = <0x40 0x41 0x42 0x43>; + status = "disabled"; + phandle = <0xd3>; + }; + + pdm@ff0a0000 { + compatible = "rockchip,px30-pdm\0rockchip,pdm"; + reg = <0x00 0xff0a0000 0x00 0x1000>; + clocks = <0x02 0x0f 0x02 0x105>; + clock-names = "pdm_clk\0pdm_hclk"; + dmas = <0x2b 0x18>; + dma-names = "rx"; + resets = <0x02 0x82>; + reset-names = "pdm-m"; + pinctrl-names = "default"; + pinctrl-0 = <0x44 0x45 0x46 0x47 0x48 0x49>; + status = "disabled"; + phandle = <0xd4>; + }; + + crypto@ff0b0000 { + compatible = "rockchip,px30-crypto"; + reg = <0x00 0xff0b0000 0x00 0x4000>; + interrupts = <0x00 0x52 0x04>; + clocks = <0x02 0xac 0x02 0xf1 0x02 0x30 0x02 0x31>; + clock-names = "aclk\0hclk\0sclk\0apb_pclk"; + resets = <0x02 0x74>; + reset-names = "crypto-rst"; + status = "disabled"; + phandle = <0xd5>; + }; + + rng@ff0b0000 { + compatible = "rockchip,cryptov2-rng"; + reg = <0x00 0xff0b0000 0x00 0x4000>; + clocks = <0x02 0x30 0x02 0x31 0x02 0xac 0x02 0xf1>; + clock-names = "clk_crypto\0clk_crypto_apk\0aclk_crypto\0hclk_crypto"; + assigned-clocks = <0x02 0x30 0x02 0x31 0x02 0xac 0x02 0xf1>; + assigned-clock-rates = <0x8f0d180 0x8f0d180 0xbebc200 0x5f5e100>; + resets = <0x02 0x74>; + reset-names = "reset"; + status = "okay"; + phandle = <0xd6>; + }; + + interrupt-controller@ff131000 { + compatible = "arm,gic-400"; + #interrupt-cells = <0x03>; + #address-cells = <0x00>; + interrupt-controller; + reg = <0x00 0xff131000 0x00 0x1000 0x00 0xff132000 0x00 0x2000 0x00 0xff134000 0x00 0x2000 0x00 0xff136000 0x00 0x2000>; + interrupts = <0x01 0x09 0xf04>; + phandle = <0x01>; + }; + + syscon@ff140000 { + compatible = "rockchip,px30-grf\0syscon\0simple-mfd"; + reg = <0x00 0xff140000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0x2f>; + + io-domains { + compatible = "rockchip,px30-io-voltage-domain"; + status = "okay"; + vccio1-supply = <0x4a>; + vccio2-supply = <0x4a>; + vccio3-supply = <0x4b>; + vccio4-supply = <0x4b>; + vccio5-supply = <0x4b>; + vccio6-supply = <0x4b>; + phandle = <0xd7>; + }; + + lvds { + compatible = "rockchip,px30-lvds"; + phys = <0x4c>; + phy-names = "phy"; + status = "disabled"; + phandle = <0xd8>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x12>; + phandle = <0xa2>; + }; + }; + }; + }; + + rgb { + compatible = "rockchip,px30-rgb"; + pinctrl-names = "default\0sleep"; + pinctrl-0 = <0x4d>; + pinctrl-1 = <0x4e>; + status = "disabled"; + phys = <0x4c>; + phy-names = "phy"; + phandle = <0xd9>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x14>; + phandle = <0xa4>; + }; + }; + }; + }; + }; + + syscon@ff148000 { + compatible = "syscon\0simple-mfd"; + reg = <0x00 0xff148000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0xda>; + + pvtm { + compatible = "rockchip,px30-pvtm"; + clocks = <0x02 0x4a>; + clock-names = "core"; + status = "okay"; + phandle = <0xdb>; + }; + }; + + serial@ff158000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff158000 0x00 0x100>; + interrupts = <0x00 0x10 0x04>; + clocks = <0x02 0x18 0x02 0x149>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x02 0x2b 0x03>; + pinctrl-names = "default"; + pinctrl-0 = <0x4f 0x50>; + status = "okay"; + phandle = <0xdc>; + }; + + serial@ff160000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff160000 0x00 0x100>; + interrupts = <0x00 0x11 0x04>; + clocks = <0x02 0x19 0x02 0x14a>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x04 0x2b 0x05>; + pinctrl-names = "default"; + pinctrl-0 = <0x51>; + status = "disabled"; + phandle = <0xdd>; + }; + + serial@ff168000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff168000 0x00 0x100>; + interrupts = <0x00 0x12 0x04>; + clocks = <0x02 0x1a 0x02 0x14b>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x06 0x2b 0x07>; + pinctrl-names = "default"; + pinctrl-0 = <0x52 0x53 0x54>; + status = "disabled"; + phandle = <0xde>; + }; + + serial@ff170000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff170000 0x00 0x100>; + interrupts = <0x00 0x13 0x04>; + clocks = <0x02 0x1b 0x02 0x14c>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x08 0x2b 0x09>; + pinctrl-names = "default"; + pinctrl-0 = <0x55 0x56 0x57>; + status = "disabled"; + phandle = <0xdf>; + }; + + serial@ff178000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff178000 0x00 0x100>; + interrupts = <0x00 0x14 0x04>; + clocks = <0x02 0x1c 0x02 0x14d>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x0a 0x2b 0x0b>; + pinctrl-names = "default"; + pinctrl-0 = <0x58 0x59 0x5a>; + status = "disabled"; + phandle = <0xe0>; + }; + + i2c@ff180000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff180000 0x00 0x1000>; + clocks = <0x02 0x1d 0x02 0x14e>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x07 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x5b>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + clock-frequency = <0x61a80>; + i2c-scl-rising-time-ns = <0x118>; + i2c-scl-falling-time-ns = <0x10>; + phandle = <0xe1>; + + pmic@20 { + compatible = "rockchip,rk817"; + reg = <0x20>; + interrupt-parent = <0x5c>; + interrupts = <0x0a 0x08>; + pinctrl-names = "default\0pmic-sleep\0pmic-power-off\0pmic-reset"; + pinctrl-0 = <0x5d>; + pinctrl-1 = <0x5e 0x5f>; + pinctrl-2 = <0x60 0x61>; + pinctrl-3 = <0x62 0x63>; + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <0x01>; + clock-output-names = "rk808-clkout1\0rk808-clkout2"; + pmic-reset-func = <0x01>; + vcc1-supply = <0x64>; + vcc2-supply = <0x64>; + vcc3-supply = <0x64>; + vcc4-supply = <0x64>; + vcc5-supply = <0x64>; + vcc6-supply = <0x64>; + vcc7-supply = <0x64>; + vcc8-supply = <0x64>; + vcc9-supply = <0x65>; + phandle = <0xe2>; + + pwrkey { + status = "okay"; + }; + + pinctrl_rk8xx { + gpio-controller; + #gpio-cells = <0x02>; + phandle = <0xe3>; + + rk817_ts_gpio1 { + pins = "gpio_ts"; + function = "pin_fun1"; + phandle = <0xe4>; + }; + + rk817_gt_gpio2 { + pins = "gpio_gt"; + function = "pin_fun1"; + phandle = <0xe5>; + }; + + rk817_pin_ts { + pins = "gpio_ts"; + function = "pin_fun0"; + phandle = <0xe6>; + }; + + rk817_pin_gt { + pins = "gpio_gt"; + function = "pin_fun0"; + phandle = <0xe7>; + }; + + rk817_slppin_null { + pins = "gpio_slp"; + function = "pin_fun0"; + phandle = <0xe8>; + }; + + rk817_slppin_slp { + pins = "gpio_slp"; + function = "pin_fun1"; + phandle = <0x5f>; + }; + + rk817_slppin_pwrdn { + pins = "gpio_slp"; + function = "pin_fun2"; + phandle = <0x61>; + }; + + rk817_slppin_rst { + pins = "gpio_slp"; + function = "pin_fun3"; + phandle = <0x63>; + }; + }; + + regulators { + + DCDC_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xe7ef0>; + regulator-max-microvolt = <0x118c30>; + regulator-ramp-delay = <0x1771>; + regulator-initial-mode = <0x02>; + regulator-name = "vdd_logic"; + phandle = <0x0e>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0xe7ef0>; + }; + }; + + DCDC_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xe7ef0>; + regulator-max-microvolt = <0x149970>; + regulator-ramp-delay = <0x1771>; + regulator-initial-mode = <0x02>; + regulator-name = "vdd_arm"; + phandle = <0x06>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0xe7ef0>; + }; + }; + + DCDC_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x02>; + regulator-name = "vcc_ddr"; + phandle = <0xe9>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + DCDC_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-initial-mode = <0x02>; + regulator-name = "vcc_3v3"; + phandle = <0x4b>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG1 { + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + regulator-name = "vcc_1v0"; + phandle = <0xea>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0xf4240>; + }; + }; + + LDO_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + regulator-name = "vcc1v8_soc"; + phandle = <0x88>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x1b7740>; + }; + }; + + LDO_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + regulator-name = "vcc1v0_soc"; + phandle = <0xeb>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0xf4240>; + }; + }; + + LDO_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "vcc3v3_pmu"; + phandle = <0x29>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + regulator-name = "vccio_sd"; + phandle = <0x4a>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x1b7740>; + }; + }; + + LDO_REG6 { + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x2dc6c0>; + regulator-boot-on; + regulator-name = "vcc_sd"; + phandle = <0x93>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x2dc6c0>; + }; + }; + + LDO_REG7 { + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "vcc_backlight"; + phandle = <0x9e>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG8 { + regulator-min-microvolt = <0x2ab980>; + regulator-max-microvolt = <0x2ab980>; + regulator-name = "vcc_lcd"; + phandle = <0x9f>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x2ab980>; + }; + }; + + BOOST { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x4c4b40>; + regulator-max-microvolt = <0x5265c0>; + regulator-name = "boost"; + phandle = <0x65>; + }; + + OTG_SWITCH { + regulator-boot-on; + regulator-name = "otg_switch"; + phandle = <0xec>; + }; + }; + + battery { + compatible = "rk817,battery"; + ocv_table = <0xc5d 0xc94 0xcd0 0xd02 0xd34 0xd66 0xd98 0xdca 0xdfc 0xe2e 0xe56 0xe7e 0xea6 0xece 0xef6 0xf1e 0xf46 0xf6e 0xf96 0xf9b 0xfa0>; + design_capacity = <0xd34>; + design_qmax = <0xe86>; + bat_res = <0x64>; + sleep_enter_current = <0x12c>; + sleep_exit_current = <0x12c>; + sleep_filter_current = <0x64>; + power_off_thresd = <0xbb8>; + zero_algorithm_vol = <0xf0a>; + max_soc_offset = <0x3c>; + monitor_sec = <0x05>; + virtual_power = <0x00>; + sample_res = <0x0a>; + }; + + charger { + compatible = "rk817,charger"; + min_input_voltage = <0x1194>; + max_input_current = <0x5dc>; + max_chrg_current = <0x7d0>; + max_chrg_voltage = <0x1068>; + chrg_term_mode = <0x00>; + chrg_finish_cur = <0x34>; + virtual_power = <0x00>; + sample_res = <0x0a>; + dc_det_gpio = <0x5c 0x0b 0x00>; + bat_low_gpio = <0x66 0x0d 0x00>; + extcon = <0x67>; + }; + + codec { + #sound-dai-cells = <0x00>; + compatible = "rockchip,rk817-codec"; + clocks = <0x02 0x15>; + clock-names = "mclk"; + pinctrl-names = "default"; + pinctrl-0 = <0x68>; + hp-volume = <0x14>; + spk-volume = <0x03>; + status = "okay"; + phandle = <0xc3>; + }; + }; + }; + + i2c@ff190000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff190000 0x00 0x1000>; + clocks = <0x02 0x1e 0x02 0x14f>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x08 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x69>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + clock-frequency = <0x61a80>; + phandle = <0xed>; + }; + + i2c@ff1a0000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff1a0000 0x00 0x1000>; + clocks = <0x02 0x1f 0x02 0x150>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x09 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x6a>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xee>; + }; + + i2c@ff1b0000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff1b0000 0x00 0x1000>; + clocks = <0x02 0x20 0x02 0x151>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x0a 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x6b>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xef>; + }; + + spi@ff1d0000 { + compatible = "rockchip,px30-spi\0rockchip,rk3066-spi"; + reg = <0x00 0xff1d0000 0x00 0x1000>; + interrupts = <0x00 0x1a 0x04>; + #address-cells = <0x01>; + #size-cells = <0x00>; + clocks = <0x02 0x24 0x02 0x155>; + clock-names = "spiclk\0apb_pclk"; + dmas = <0x2b 0x0c 0x2b 0x0d>; + dma-names = "tx\0rx"; + pinctrl-names = "default\0high_speed"; + pinctrl-0 = <0x6c 0x6d 0x6e 0x6f>; + pinctrl-1 = <0x70 0x6d 0x71 0x72>; + status = "disabled"; + phandle = <0xf0>; + }; + + spi@ff1d8000 { + compatible = "rockchip,px30-spi\0rockchip,rk3066-spi"; + reg = <0x00 0xff1d8000 0x00 0x1000>; + interrupts = <0x00 0x1b 0x04>; + #address-cells = <0x01>; + #size-cells = <0x00>; + clocks = <0x02 0x25 0x02 0x156>; + clock-names = "spiclk\0apb_pclk"; + dmas = <0x2b 0x0e 0x2b 0x0f>; + dma-names = "tx\0rx"; + pinctrl-names = "default\0high_speed"; + pinctrl-0 = <0x73 0x74 0x75 0x76 0x77>; + pinctrl-1 = <0x78 0x74 0x75 0x79 0x7a>; + status = "disabled"; + phandle = <0xf1>; + }; + + watchdog@ff1e0000 { + compatible = "snps,dw-wdt"; + reg = <0x00 0xff1e0000 0x00 0x100>; + clocks = <0x02 0x15b>; + interrupts = <0x00 0x25 0x04>; + resets = <0x02 0xb5>; + reset-names = "reset"; + status = "disabled"; + phandle = <0xf2>; + }; + + pwm@ff200000 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200000 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7b>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "okay"; + phandle = <0xbc>; + }; + + pwm@ff200010 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200010 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7c>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "okay"; + phandle = <0xc1>; + }; + + pwm@ff200020 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200020 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7d>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf3>; + }; + + pwm@ff200030 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200030 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7e>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf4>; + }; + + pwm@ff208000 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208000 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7f>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf5>; + }; + + pwm@ff208010 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208010 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x80>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf6>; + }; + + pwm@ff208020 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208020 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x81>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf7>; + }; + + pwm@ff208030 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208030 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x82>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf8>; + }; + + rktimer@ff210000 { + compatible = "rockchip,rk3288-timer"; + reg = <0x00 0xff210000 0x00 0x1000>; + interrupts = <0x00 0x1e 0x04>; + clocks = <0x02 0x159 0x02 0x26>; + clock-names = "pclk\0timer"; + phandle = <0xf9>; + }; + + amba { + compatible = "simple-bus"; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + + dmac@ff240000 { + compatible = "arm,pl330\0arm,primecell"; + reg = <0x00 0xff240000 0x00 0x4000>; + interrupts = <0x00 0x01 0x04 0x00 0x02 0x04>; + clocks = <0x02 0xbb>; + clock-names = "apb_pclk"; + #dma-cells = <0x01>; + peripherals-req-type-burst; + phandle = <0x2b>; + }; + }; + + thermal-zones { + phandle = <0xfa>; + + soc-thermal { + polling-delay-passive = <0x14>; + polling-delay = <0x3e8>; + sustainable-power = <0x2ee>; + thermal-sensors = <0x83 0x00>; + phandle = <0xfb>; + + trips { + + trip-point-0 { + temperature = <0x11170>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0xfc>; + }; + + trip-point-1 { + temperature = <0x14c08>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0x84>; + }; + + soc-crit { + temperature = <0x1c138>; + hysteresis = <0x7d0>; + type = "critical"; + phandle = <0xfd>; + }; + }; + + cooling-maps { + + map0 { + trip = <0x84>; + cooling-device = <0x09 0xffffffff 0xffffffff>; + contribution = <0x1000>; + }; + + map1 { + trip = <0x84>; + cooling-device = <0x85 0xffffffff 0xffffffff>; + contribution = <0x1000>; + }; + }; + }; + + gpu-thermal { + polling-delay-passive = <0x64>; + polling-delay = <0x3e8>; + thermal-sensors = <0x83 0x01>; + phandle = <0xfe>; + }; + }; + + tsadc@ff280000 { + compatible = "rockchip,px30-tsadc"; + reg = <0x00 0xff280000 0x00 0x100>; + interrupts = <0x00 0x24 0x04>; + rockchip,grf = <0x2f>; + clocks = <0x02 0x2c 0x02 0x158>; + clock-names = "tsadc\0apb_pclk"; + assigned-clocks = <0x02 0x2c>; + assigned-clock-rates = <0xc350>; + resets = <0x02 0xa8>; + reset-names = "tsadc-apb"; + #thermal-sensor-cells = <0x01>; + rockchip,hw-tshut-temp = <0x1d4c0>; + status = "okay"; + pinctrl-names = "gpio\0otpout"; + pinctrl-0 = <0x86>; + pinctrl-1 = <0x87>; + phandle = <0x83>; + }; + + saradc@ff288000 { + compatible = "rockchip,px30-saradc\0rockchip,rk3399-saradc"; + reg = <0x00 0xff288000 0x00 0x100>; + interrupts = <0x00 0x54 0x04>; + #io-channel-cells = <0x01>; + clocks = <0x02 0x2d 0x02 0x157>; + clock-names = "saradc\0apb_pclk"; + resets = <0x02 0xa5>; + reset-names = "saradc-apb"; + status = "okay"; + vref-supply = <0x88>; + phandle = <0xbe>; + }; + + otp@ff290000 { + compatible = "rockchip,px30-otp"; + reg = <0x00 0xff290000 0x00 0x4000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + clocks = <0x02 0x2f 0x02 0x15a 0x02 0x161>; + clock-names = "clk_otp\0pclk_otp\0pclk_otp_phy"; + resets = <0x02 0xb4>; + reset-names = "otp_phy"; + phandle = <0xff>; + + id@7 { + reg = <0x07 0x10>; + phandle = <0x0f>; + }; + + cpu-leakage@17 { + reg = <0x17 0x01>; + phandle = <0x07>; + }; + + performance@1e { + reg = <0x1e 0x01>; + bits = <0x04 0x03>; + phandle = <0x08>; + }; + }; + + clock-controller@ff2b0000 { + compatible = "rockchip,px30-cru"; + reg = <0x00 0xff2b0000 0x00 0x1000>; + rockchip,grf = <0x2f>; + rockchip,boost = <0x89>; + #clock-cells = <0x01>; + #reset-cells = <0x01>; + assigned-clocks = <0x02 0x04>; + assigned-clock-rates = <0x3dfd2400>; + phandle = <0x02>; + }; + + cpu-boost@ff2b8000 { + compatible = "syscon"; + reg = <0x00 0xff2b8000 0x00 0x1000>; + rockchip,boost-low-con0 = <0x1032>; + rockchip,boost-low-con1 = <0x1441>; + rockchip,boost-high-con0 = <0x1036>; + rockchip,boost-high-con1 = <0x1441>; + rockchip,boost-backup-pll = <0x01>; + rockchip,boost-backup-pll-usage = <0x00>; + rockchip,boost-switch-threshold = <0x249f00>; + rockchip,boost-statis-threshold = <0x100>; + rockchip,boost-statis-enable = <0x00>; + rockchip,boost-enable = <0x00>; + phandle = <0x89>; + }; + + pmu-clock-controller@ff2bc000 { + compatible = "rockchip,px30-pmucru"; + reg = <0x00 0xff2bc000 0x00 0x1000>; + rockchip,grf = <0x2f>; + #clock-cells = <0x01>; + #reset-cells = <0x01>; + assigned-clocks = <0x2a 0x01 0x2a 0x08 0x2a 0x05 0x02 0x07 0x02 0xab 0x02 0xb0 0x02 0xf0 0x02 0xf5 0x02 0x140 0x02 0x49>; + assigned-clock-rates = <0x47868c00 0x5f5e100 0x18cba80 0x23c34600 0xbebc200 0xbebc200 0x8f0d180 0x8f0d180 0x5f5e100 0xbebc200>; + phandle = <0x2a>; + }; + + syscon@ff2c0000 { + compatible = "rockchip,px30-usb2phy-grf\0syscon\0simple-mfd"; + reg = <0x00 0xff2c0000 0x00 0x10000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0x100>; + + usb2-phy@100 { + compatible = "rockchip,px30-usb2phy\0rockchip,rk3328-usb2phy"; + reg = <0x100 0x10>; + clocks = <0x2a 0x0a>; + clock-names = "phyclk"; + #clock-cells = <0x00>; + assigned-clocks = <0x02 0x0e 0x02 0x55>; + assigned-clock-parents = <0x67 0x02 0x0e>; + clock-output-names = "usb480m_phy"; + status = "okay"; + phandle = <0x67>; + + host-port { + #phy-cells = <0x00>; + interrupts = <0x00 0x44 0x04>; + interrupt-names = "linestate"; + status = "okay"; + phandle = <0x8c>; + }; + + otg-port { + #phy-cells = <0x00>; + interrupts = <0x00 0x42 0x04 0x00 0x41 0x04 0x00 0x40 0x04>; + interrupt-names = "otg-bvalid\0otg-id\0linestate"; + status = "disabled"; + phandle = <0x8b>; + }; + }; + }; + + video-phy@ff2e0000 { + compatible = "rockchip,px30-video-phy"; + reg = <0x00 0xff2e0000 0x00 0x10000 0x00 0xff450000 0x00 0x10000>; + clocks = <0x2a 0x0b 0x02 0x145 0x02 0x144>; + clock-names = "ref\0pclk_phy\0pclk_host"; + #clock-cells = <0x00>; + resets = <0x02 0x3e>; + reset-names = "rst"; + power-domains = <0x8a 0x0c>; + #phy-cells = <0x00>; + status = "okay"; + phandle = <0x4c>; + }; + + mipi-dphy-rx0@ff2f0000 { + compatible = "rockchip,rk3326-mipi-dphy"; + reg = <0x00 0xff2f0000 0x00 0x4000>; + clocks = <0x02 0x146>; + clock-names = "dphy-ref"; + power-domains = <0x8a 0x0d>; + rockchip,grf = <0x2f>; + status = "okay"; + phandle = <0x101>; + }; + + usb@ff300000 { + compatible = "rockchip,px30-usb\0rockchip,rk3066-usb\0snps,dwc2"; + reg = <0x00 0xff300000 0x00 0x40000>; + interrupts = <0x00 0x3e 0x04>; + clocks = <0x02 0x102>; + clock-names = "otg"; + power-domains = <0x8a 0x05>; + dr_mode = "otg"; + g-np-tx-fifo-size = <0x10>; + g-rx-fifo-size = <0x118>; + g-tx-fifo-size = <0x100 0x80 0x80 0x40 0x20 0x10>; + g-use-dma; + phys = <0x8b>; + phy-names = "usb2-phy"; + status = "okay"; + phandle = <0x102>; + }; + + usb@ff340000 { + compatible = "generic-ehci"; + reg = <0x00 0xff340000 0x00 0x10000>; + interrupts = <0x00 0x3c 0x04>; + clocks = <0x02 0x103 0x67>; + clock-names = "usbhost\0utmi"; + power-domains = <0x8a 0x05>; + phys = <0x8c>; + phy-names = "usb"; + status = "disabled"; + phandle = <0x103>; + }; + + usb@ff350000 { + compatible = "generic-ohci"; + reg = <0x00 0xff350000 0x00 0x10000>; + interrupts = <0x00 0x3d 0x04>; + clocks = <0x02 0x103 0x67>; + clock-names = "usbhost\0utmi"; + power-domains = <0x8a 0x05>; + phys = <0x8c>; + phy-names = "usb"; + status = "disabled"; + phandle = <0x104>; + }; + + ethernet@ff360000 { + compatible = "rockchip,px30-gmac"; + reg = <0x00 0xff360000 0x00 0x10000>; + rockchip,grf = <0x2f>; + interrupts = <0x00 0x2b 0x04>; + interrupt-names = "macirq"; + clocks = <0x02 0x3e 0x02 0x3f 0x02 0x3f 0x02 0x40 0x02 0x41 0x02 0xb2 0x02 0x143 0x02 0x4c>; + clock-names = "stmmaceth\0mac_clk_rx\0mac_clk_tx\0clk_mac_ref\0clk_mac_refout\0aclk_mac\0pclk_mac\0clk_mac_speed"; + phy-mode = "rmii"; + pinctrl-names = "default"; + pinctrl-0 = <0x8d 0x8e>; + resets = <0x02 0x5e>; + reset-names = "stmmaceth"; + power-domains = <0x8a 0x09>; + status = "disabled"; + phandle = <0x105>; + }; + + dwmmc@ff370000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff370000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0xf7 0x02 0x3b 0x02 0x43 0x02 0x44>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x3b>; + assigned-clock-parents = <0x02 0x57>; + power-domains = <0x8a 0x07>; + fifo-depth = <0x100>; + interrupts = <0x00 0x36 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x8f 0x90 0x91 0x92>; + status = "okay"; + bus-width = <0x04>; + cap-mmc-highspeed; + cap-sd-highspeed; + supports-sd; + card-detect-delay = <0x320>; + ignore-pm-notify; + cd-gpios = <0x5c 0x03 0x01>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <0x4a>; + vmmc-supply = <0x93>; + phandle = <0x106>; + }; + + dwmmc@ff380000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff380000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0xff 0x02 0x38 0x02 0x45 0x02 0x46>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x38>; + assigned-clock-parents = <0x02 0x51>; + power-domains = <0x8a 0x0a>; + fifo-depth = <0x100>; + interrupts = <0x00 0x37 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x94 0x95 0x96>; + status = "okay"; + bus-width = <0x04>; + cap-mmc-highspeed; + cap-sd-highspeed; + supports-sd; + card-detect-delay = <0x320>; + ignore-pm-notify; + cd-gpios = <0x97 0x0e 0x01>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <0x4a>; + vmmc-supply = <0x93>; + phandle = <0x107>; + }; + + dwmmc@ff390000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff390000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0x100 0x02 0x39 0x02 0x47 0x02 0x48>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x39>; + assigned-clock-parents = <0x02 0x53>; + power-domains = <0x8a 0x0a>; + fifo-depth = <0x100>; + interrupts = <0x00 0x35 0x04>; + status = "disabled"; + phandle = <0x108>; + }; + + nandc@ff3b0000 { + compatible = "rockchip,rk-nandc"; + reg = <0x00 0xff3b0000 0x00 0x4000>; + interrupts = <0x00 0x39 0x04>; + nandc_id = <0x00>; + clocks = <0x02 0x37 0x02 0xfe>; + clock-names = "clk_nandc\0hclk_nandc"; + assigned-clocks = <0x02 0x37>; + assigned-clock-parents = <0x02 0x4f>; + power-domains = <0x8a 0x0a>; + status = "disabled"; + phandle = <0x109>; + }; + + sfc@ff3a0000 { + compatible = "rockchip,sfc"; + reg = <0x00 0xff3a0000 0x00 0x4000>; + interrupts = <0x00 0x38 0x04>; + clocks = <0x02 0x3a 0x02 0x101>; + clock-names = "clk_sfc\0hclk_sfc"; + assigned-clocks = <0x02 0x3a>; + assigned-clock-rates = <0x989680>; + status = "disabled"; + phandle = <0x10a>; + }; + + gpu@ff400000 { + compatible = "arm,malit602\0arm,malit60x\0arm,malit6xx\0arm,mali-midgard"; + reg = <0x00 0xff400000 0x00 0x4000>; + interrupts = <0x00 0x2d 0x04 0x00 0x2e 0x04 0x00 0x2f 0x04>; + interrupt-names = "GPU\0MMU\0JOB"; + clocks = <0x02 0x49>; + clock-names = "clk_mali"; + power-domains = <0x8a 0x0e>; + #cooling-cells = <0x02>; + operating-points-v2 = <0x98>; + status = "okay"; + mali-supply = <0x0e>; + phandle = <0x85>; + + power_model { + compatible = "arm,mali-simple-power-model"; + static-coefficient = <0x64578>; + dynamic-coefficient = <0x2dd>; + ts = <0x7d00 0x125c 0xffffffb0 0x02>; + thermal-zone = "gpu-thermal"; + }; + }; + + gpu-opp-table { + compatible = "operating-points-v2"; + rockchip,thermal-zone = "soc-thermal"; + rockchip,temp-hysteresis = <0x1388>; + rockchip,low-temp = <0x00>; + rockchip,low-temp-min-volt = <0xf4240>; + rockchip,low-temp-adjust-volt = <0x00 0x1e0 0xc350>; + rockchip,max-volt = <0x11edd8>; + rockchip,evb-irdrop = <0x61a8>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-ch = <0x00 0x00>; + phandle = <0x98>; + + opp-400000000 { + opp-hz = <0x00 0x17d78400>; + opp-microvolt = <0x100590>; + opp-microvolt-L0 = <0x100590>; + opp-microvolt-L1 = <0xfa3e8>; + opp-microvolt-L2 = <0xee098>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-480000000 { + opp-hz = <0x00 0x1c9c3800>; + opp-microvolt = <0x112a88>; + opp-microvolt-L0 = <0x112a88>; + opp-microvolt-L1 = <0x10c8e0>; + opp-microvolt-L2 = <0x100590>; + opp-microvolt-L3 = <0xf4240>; + }; + + opp-520000000 { + opp-hz = <0x00 0x1efe9200>; + opp-microvolt = <0x118c30>; + opp-microvolt-L0 = <0x118c30>; + opp-microvolt-L1 = <0x118c30>; + opp-microvolt-L2 = <0x10c8e0>; + opp-microvolt-L3 = <0x100590>; + }; + }; + + hevc_service@ff440000 { + compatible = "rockchip,hevc_sub"; + iommu_enabled = <0x01>; + reg = <0x00 0xff440000 0x00 0x400>; + interrupts = <0x00 0x31 0x04>; + interrupt-names = "irq_dec"; + dev_mode = <0x01>; + iommus = <0x99>; + allocator = <0x01>; + phandle = <0x9c>; + }; + + vpu_service@ff442000 { + compatible = "rockchip,vpu_sub"; + iommu_enabled = <0x01>; + reg = <0x00 0xff442000 0x00 0x800>; + interrupts = <0x00 0x50 0x04 0x00 0x4f 0x04>; + interrupt-names = "irq_enc\0irq_dec"; + dev_mode = <0x00>; + iommus = <0x9a>; + allocator = <0x01>; + phandle = <0x9b>; + }; + + vpu_combo { + compatible = "rockchip,vpu_combo"; + subcnt = <0x02>; + rockchip,grf = <0x2f>; + rockchip,sub = <0x9b 0x9c>; + clocks = <0x02 0xaf 0x02 0xf4 0x02 0x4b>; + clock-names = "aclk_vcodec\0hclk_vcodec\0clk_core"; + resets = <0x02 0x24 0x02 0x26 0x02 0x25 0x02 0x27 0x02 0x3f>; + reset-names = "video_a\0video_h\0niu_a\0niu_h\0video_core"; + power-domains = <0x8a 0x0b>; + mode_bit = <0x0f>; + mode_ctrl = <0x410>; + status = "okay"; + phandle = <0x10b>; + }; + + iommu@ff440440 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff440440 0x00 0x40 0x00 0xff440480 0x00 0x40>; + interrupts = <0x00 0x32 0x04>; + interrupt-names = "hevc_mmu"; + clocks = <0x02 0xaf 0x02 0xf4>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0b>; + #iommu-cells = <0x00>; + phandle = <0x99>; + }; + + iommu@ff442800 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff442800 0x00 0x100>; + interrupts = <0x00 0x51 0x04>; + interrupt-names = "vpu_mmu"; + clocks = <0x02 0xaf 0x02 0xf4>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0b>; + #iommu-cells = <0x00>; + phandle = <0x9a>; + }; + + dsi@ff450000 { + compatible = "rockchip,px30-mipi-dsi"; + reg = <0x00 0xff450000 0x00 0x10000>; + interrupts = <0x00 0x4b 0x04>; + clocks = <0x02 0x144 0x4c>; + clock-names = "pclk\0hs_clk"; + resets = <0x02 0x3d>; + reset-names = "apb"; + phys = <0x4c>; + phy-names = "mipi_dphy"; + power-domains = <0x8a 0x0c>; + rockchip,grf = <0x2f>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + phandle = <0x10c>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x13>; + status = "okay"; + phandle = <0xa3>; + }; + }; + }; + + panel@0 { + compatible = "elida,kd35t133\0simple-panel-dsi"; + reg = <0x00>; + backlight = <0x9d>; + backlight-supply = <0x9e>; + power-supply = <0x9f>; + reset-gpios = <0x97 0x10 0x01>; + reset-delay-ms = <0x96>; + init-delay-ms = <0x14>; + enable-delay-ms = <0x78>; + prepare-delay-ms = <0x14>; + unprepare-delay-ms = <0x14>; + disable-delay-ms = <0x32>; + width-mm = <0x34>; + height-mm = <0x46>; + dsi,flags = <0xa03>; + dsi,format = <0x00>; + dsi,lanes = <0x04>; + panel-init-sequence = [15 00 02 ff 30 15 00 02 ff 52 15 00 02 ff 01 15 00 02 e3 00 15 00 02 25 10 15 00 02 28 6f 15 00 02 29 01 15 00 02 2a df 15 00 02 2c 22 15 00 02 c3 0f 15 00 02 37 9c 15 00 02 38 a7 15 00 02 39 41 15 00 02 80 20 15 00 02 91 67 15 00 02 92 67 15 00 02 a0 55 15 00 02 a1 50 15 00 02 a3 58 15 00 02 a4 9c 15 00 02 a7 02 15 00 02 a8 01 15 00 02 a9 21 15 00 02 aa fc 15 00 02 ab 28 15 00 02 ac 06 15 00 02 ad 06 15 00 02 ae 06 15 00 02 af 03 15 00 02 b0 08 15 00 02 b1 26 15 00 02 b2 28 15 00 02 b3 28 15 00 02 b4 03 15 00 02 b5 08 15 00 02 b6 26 15 00 02 b7 08 15 00 02 b8 26 15 00 02 2c 22 15 00 02 5c 40 15 00 02 c0 00 15 00 02 c1 00 15 00 02 c2 00 15 00 02 ff 30 15 00 02 ff 52 15 00 02 ff 02 15 00 02 b0 02 15 00 02 d0 02 15 00 02 b1 0f 15 00 02 d1 10 15 00 02 b2 11 15 00 02 d2 12 15 00 02 b3 32 15 00 02 d3 33 15 00 02 b4 36 15 00 02 d4 36 15 00 02 b5 3c 15 00 02 d5 3c 15 00 02 b6 20 15 00 02 d6 20 15 00 02 b7 3e 15 00 02 d7 3e 15 00 02 b8 0e 15 00 02 d8 0d 15 00 02 b9 05 15 00 02 d9 05 15 00 02 ba 11 15 00 02 da 12 15 00 02 bb 11 15 00 02 db 11 15 00 02 bc 13 15 00 02 dc 14 15 00 02 bd 14 15 00 02 dd 14 15 00 02 be 16 15 00 02 de 18 15 00 02 bf 0e 15 00 02 df 0f 15 00 02 c0 17 15 00 02 e0 17 15 00 02 c1 07 15 00 02 e1 08 15 00 02 ff 30 15 00 02 ff 52 15 00 02 ff 03 15 00 02 08 8a 15 00 02 09 8b 15 00 02 30 00 15 00 02 31 00 15 00 02 32 00 15 00 02 33 00 15 00 02 34 61 15 00 02 35 d4 15 00 02 36 24 15 00 02 37 03 15 00 02 40 86 15 00 02 41 87 15 00 02 42 84 15 00 02 43 85 15 00 02 44 11 15 00 02 45 de 15 00 02 46 dd 15 00 02 47 11 15 00 02 48 e0 15 00 02 49 df 15 00 02 50 82 15 00 02 51 83 15 00 02 52 80 15 00 02 53 81 15 00 02 54 11 15 00 02 55 e2 15 00 02 56 e1 15 00 02 57 11 15 00 02 58 e4 15 00 02 59 e3 15 00 02 82 0f 15 00 02 83 0f 15 00 02 84 00 15 00 02 85 0f 15 00 02 86 0f 15 00 02 87 0e 15 00 02 88 0e 15 00 02 89 06 15 00 02 8a 06 15 00 02 8b 07 15 00 02 8c 07 15 00 02 8d 04 15 00 02 8e 04 15 00 02 8f 05 15 00 02 90 05 15 00 02 98 0f 15 00 02 99 0f 15 00 02 9a 00 15 00 02 9b 0f 15 00 02 9c 0f 15 00 02 9d 0e 15 00 02 9e 0e 15 00 02 9f 06 15 00 02 a0 06 15 00 02 a1 07 15 00 02 a2 07 15 00 02 a3 04 15 00 02 a4 04 15 00 02 a5 05 15 00 02 a6 05 15 00 02 e0 02 15 00 02 e1 52 15 00 02 ff 30 15 00 02 ff 52 15 00 02 ff 00 15 00 02 36 02 15 00 02 11 00 15 00 02 29 00 05 c8 01 11 05 14 01 29]; + panel-exit-sequence = <0x5140128 0x50a0110>; + + display-timings { + native-mode = <0xa0>; + + 60Hz { + clock-frequency = <0x1ba8140>; + hactive = <0x280>; + vactive = <0x1e0>; + hfront-porch = <0x2e>; + hsync-len = <0x02>; + hback-porch = <0x2c>; + vfront-porch = <0xa5>; + vsync-len = <0x02>; + vback-porch = <0x0e>; + hsync-active = <0x00>; + vsync-active = <0x00>; + de-active = <0x00>; + pixelclk-active = <0x01>; + phandle = <0xaa1>; + }; + + 50Hz { + clock-frequency = <0x1ba8140>; + hactive = <0x280>; + vactive = <0x1e0>; + hfront-porch = <0x2e>; + hsync-len = <0x02>; + hback-porch = <0x2c>; + vfront-porch = <0x10>; + vsync-len = <0x02>; + vback-porch = <0x0e>; + hsync-active = <0x00>; + vsync-active = <0x00>; + de-active = <0x00>; + pixelclk-active = <0x01>; + phandle = <0xa00>; + }; + + 75Hz { + clock-frequency = <0x1ba8140>; + hactive = <0x280>; + vactive = <0x1e0>; + hfront-porch = <0x2e>; + hsync-len = <0x02>; + hback-porch = <0x2c>; + vfront-porch = <0x10>; + vsync-len = <0x02>; + vback-porch = <0x0e>; + hsync-active = <0x00>; + vsync-active = <0x00>; + de-active = <0x00>; + pixelclk-active = <0x01>; + phandle = <0xa01>; + }; + }; + }; + }; + + vop@ff460000 { + compatible = "rockchip,px30-vop-big"; + reg = <0x00 0xff460000 0x00 0x1fc 0x00 0xff460a00 0x00 0x400>; + rockchip,grf = <0x2f>; + reg-names = "regs\0gamma_lut"; + interrupts = <0x00 0x4d 0x04>; + clocks = <0x02 0xb5 0x02 0x96 0x02 0xfb>; + clock-names = "aclk_vop\0dclk_vop\0hclk_vop"; + power-domains = <0x8a 0x0c>; + iommus = <0xa1>; + status = "okay"; + phandle = <0x10f>; + + port { + #address-cells = <0x01>; + #size-cells = <0x00>; + phandle = <0x10>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0xa2>; + phandle = <0x12>; + }; + + endpoint@1 { + reg = <0x01>; + remote-endpoint = <0xa3>; + phandle = <0x13>; + }; + + endpoint@2 { + reg = <0x02>; + remote-endpoint = <0xa4>; + phandle = <0x14>; + }; + }; + }; + + iommu@ff460f00 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff460f00 0x00 0x100>; + interrupts = <0x00 0x4d 0x04>; + interrupt-names = "vopb_mmu"; + clocks = <0x02 0xb5 0x02 0xfb>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0c>; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xa1>; + }; + + rk_rga@ff480000 { + compatible = "rockchip,rga2"; + reg = <0x00 0xff480000 0x00 0x1000>; + interrupts = <0x00 0x4c 0x04>; + clocks = <0x02 0xb7 0x02 0xfd 0x02 0x35>; + clock-names = "aclk_rga\0hclk_rga\0clk_rga"; + power-domains = <0x8a 0x0c>; + dma-coherent; + status = "okay"; + phandle = <0x110>; + }; + + cif@ff490000 { + compatible = "rockchip,cif"; + reg = <0x00 0xff490000 0x00 0x200>; + interrupts = <0x00 0x45 0x04>; + clocks = <0x02 0xb3 0x02 0xf9 0x02 0x160 0x02 0x34>; + clock-names = "aclk_cif0\0hclk_cif0\0pclk_cif\0cif0_out"; + resets = <0x02 0x2c 0x02 0x2d 0x02 0x2e>; + reset-names = "rst_cif_a\0rst_cif_h\0rst_cif_pclkin"; + power-domains = <0x8a 0x0d>; + pinctrl-names = "cif_pin_all"; + pinctrl-0 = <0xa5>; + iommus = <0xa6>; + status = "disabled"; + phandle = <0x111>; + }; + + cif-new@ff490000 { + compatible = "rockchip,px30-cif"; + reg = <0x00 0xff490000 0x00 0x200>; + interrupts = <0x00 0x45 0x04>; + clocks = <0x02 0xb3 0x02 0xf9 0x02 0x160 0x02 0x34>; + clock-names = "aclk_cif\0hclk_cif\0pclk_cif\0cif_out"; + resets = <0x02 0x2c 0x02 0x2d 0x02 0x2e>; + reset-names = "rst_cif_a\0rst_cif_h\0rst_cif_pclkin"; + power-domains = <0x8a 0x0d>; + iommus = <0xa6>; + status = "disabled"; + phandle = <0x112>; + }; + + iommu@ff490800 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff490800 0x00 0x100>; + interrupts = <0x00 0x45 0x04>; + interrupt-names = "vip_mmu"; + clocks = <0x02 0xb3 0x02 0xf9>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0d>; + rk_iommu,disable_reset_quirk; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xa6>; + }; + + rk_isp@ff4a0000 { + compatible = "rockchip,px30-isp\0rockchip,isp"; + reg = <0x00 0xff4a0000 0x00 0x8000>; + interrupts = <0x00 0x46 0x04>; + clocks = <0x02 0xb4 0x02 0xfa 0x02 0x33 0x02 0x33 0x02 0x15f 0x02 0x34 0x02 0x34 0x02 0x146>; + clock-names = "aclk_isp\0hclk_isp\0clk_isp\0clk_isp_jpe\0pclkin_isp\0clk_cif_pll\0clk_cif_out\0pclk_dphyrx"; + resets = <0x02 0x2b 0x02 0x2f>; + reset-names = "rst_isp\0rst_mipicsiphy"; + power-domains = <0x8a 0x0d>; + pinctrl-names = "default\0isp_dvp8bit2\0isp_dvp10bit\0isp_dvp12bit"; + pinctrl-0 = <0xa7>; + pinctrl-1 = <0xa5>; + pinctrl-2 = <0xa5 0xa8>; + pinctrl-3 = <0xa9 0xa5 0xa8>; + rockchip,isp,mipiphy = <0x01>; + rockchip,isp,csiphy,reg = <0xff2f0000 0x4000>; + rockchip,grf = <0x2f>; + rockchip,cru = <0x02>; + rockchip,isp,iommu-enable = <0x01>; + iommus = <0xaa>; + status = "disabled"; + phandle = <0x113>; + }; + + rkisp1@ff4a0000 { + compatible = "rockchip,rk3326-rkisp1"; + reg = <0x00 0xff4a0000 0x00 0x8000>; + interrupts = <0x00 0x46 0x04 0x00 0x49 0x04 0x00 0x4a 0x04>; + interrupt-names = "isp_irq\0mi_irq\0mipi_irq"; + clocks = <0x02 0xb4 0x02 0xfa 0x02 0x33 0x02 0x15f>; + clock-names = "aclk_isp\0hclk_isp\0clk_isp\0pclk_isp"; + devfreq = <0xab>; + power-domains = <0x8a 0x0d>; + iommus = <0xaa>; + rockchip,grf = <0x2f>; + status = "okay"; + phandle = <0x114>; + }; + + iommu@ff4a8000 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff4a8000 0x00 0x100>; + interrupts = <0x00 0x46 0x04>; + interrupt-names = "isp_mmu"; + clocks = <0x02 0xb4 0x02 0xfa>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0d>; + rk_iommu,disable_reset_quirk; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xaa>; + }; + + qos@ff518000 { + compatible = "syscon"; + reg = <0x00 0xff518000 0x00 0x20>; + phandle = <0x18>; + }; + + qos@ff520000 { + compatible = "syscon"; + reg = <0x00 0xff520000 0x00 0x20>; + phandle = <0x28>; + }; + + qos@ff52c000 { + compatible = "syscon"; + reg = <0x00 0xff52c000 0x00 0x20>; + phandle = <0x17>; + }; + + qos@ff538000 { + compatible = "syscon"; + reg = <0x00 0xff538000 0x00 0x20>; + phandle = <0x19>; + }; + + qos@ff538080 { + compatible = "syscon"; + reg = <0x00 0xff538080 0x00 0x20>; + phandle = <0x1a>; + }; + + qos@ff538100 { + compatible = "syscon"; + reg = <0x00 0xff538100 0x00 0x20>; + phandle = <0x1b>; + }; + + qos@ff538180 { + compatible = "syscon"; + reg = <0x00 0xff538180 0x00 0x20>; + phandle = <0x1c>; + }; + + qos@ff540000 { + compatible = "syscon"; + reg = <0x00 0xff540000 0x00 0x20>; + phandle = <0x15>; + }; + + qos@ff540080 { + compatible = "syscon"; + reg = <0x00 0xff540080 0x00 0x20>; + phandle = <0x16>; + }; + + qos@ff548000 { + compatible = "syscon"; + reg = <0x00 0xff548000 0x00 0x20>; + phandle = <0x23>; + }; + + qos@ff548080 { + compatible = "syscon"; + reg = <0x00 0xff548080 0x00 0x20>; + phandle = <0x24>; + }; + + qos@ff548100 { + compatible = "syscon"; + reg = <0x00 0xff548100 0x00 0x20>; + phandle = <0x25>; + }; + + qos@ff548180 { + compatible = "syscon"; + reg = <0x00 0xff548180 0x00 0x20>; + phandle = <0x26>; + }; + + qos@ff548200 { + compatible = "syscon"; + reg = <0x00 0xff548200 0x00 0x20>; + phandle = <0x27>; + }; + + qos@ff550000 { + compatible = "syscon"; + reg = <0x00 0xff550000 0x00 0x20>; + phandle = <0x1f>; + }; + + qos@ff550080 { + compatible = "syscon"; + reg = <0x00 0xff550080 0x00 0x20>; + phandle = <0x20>; + }; + + qos@ff550100 { + compatible = "syscon"; + reg = <0x00 0xff550100 0x00 0x20>; + phandle = <0x21>; + }; + + qos@ff550180 { + compatible = "syscon"; + reg = <0x00 0xff550180 0x00 0x20>; + phandle = <0x22>; + }; + + qos@ff558000 { + compatible = "syscon"; + reg = <0x00 0xff558000 0x00 0x20>; + phandle = <0x1d>; + }; + + qos@ff558080 { + compatible = "syscon"; + reg = <0x00 0xff558080 0x00 0x20>; + phandle = <0x1e>; + }; + + dfi@ff610000 { + reg = <0x00 0xff610000 0x00 0x400>; + compatible = "rockchip,px30-dfi"; + rockchip,pmugrf = <0xac>; + status = "okay"; + phandle = <0xad>; + }; + + dmc { + compatible = "rockchip,px30-dmc"; + interrupts = <0x00 0x69 0x04>; + interrupt-names = "complete_irq"; + devfreq-events = <0xad>; + clocks = <0x02 0x54>; + clock-names = "dmc_clk"; + operating-points-v2 = <0xae>; + ddr_timing = <0xaf>; + upthreshold = <0x28>; + downdifferential = <0x14>; + system-status-freq = <0x01 0x80e80 0x08 0x6ddd0 0x02 0x2f5d0 0x20 0x6ddd0 0x1000 0x80e80 0x4000 0xa2990 0x2000 0xa2990>; + auto-min-freq = <0x50140>; + auto-freq-en = <0x01>; + #cooling-cells = <0x02>; + status = "okay"; + center-supply = <0x0e>; + phandle = <0xab>; + + ddr_power_model { + compatible = "ddr_power_model"; + dynamic-power-coefficient = <0x78>; + static-power-coefficient = <0xc8>; + ts = <0x7d00 0x125c 0xffffffb0 0x02>; + thermal-zone = "soc-thermal"; + phandle = <0x115>; + }; + }; + + dmc-opp-table { + compatible = "operating-points-v2"; + rockchip,max-volt = <0x118c30>; + rockchip,evb-irdrop = <0x61a8>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-ch = <0x00 0x00>; + phandle = <0xae>; + + opp-528000000 { + opp-hz = <0x00 0x1f78a400>; + opp-microvolt = <0xee098>; + opp-microvolt-L0 = <0xee098>; + opp-microvolt-L1 = <0xee098>; + opp-microvolt-L2 = <0xe7ef0>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-666000000 { + opp-hz = <0x00 0x27b25a80>; + opp-microvolt = <0x100590>; + opp-microvolt-L0 = <0x100590>; + opp-microvolt-L1 = <0xf4240>; + opp-microvolt-L2 = <0xee098>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-786000000 { + opp-hz = <0x00 0x2ed96880>; + opp-microvolt = <0x10c8e0>; + opp-microvolt-L0 = <0x10c8e0>; + opp-microvolt-L1 = <0x100590>; + opp-microvolt-L2 = <0xfa3e8>; + opp-microvolt-L3 = <0xf4240>; + status = "okay"; + }; + }; + + rockchip-system-monitor { + compatible = "rockchip,system-monitor"; + rockchip,thermal-zone = "soc-thermal"; + rockchip,polling-delay = <0xc8>; + phandle = <0x116>; + }; + + pinctrl { + compatible = "rockchip,px30-pinctrl"; + rockchip,grf = <0x2f>; + rockchip,pmu = <0xac>; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + phandle = <0x117>; + + gpio0@ff040000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff040000 0x00 0x100>; + interrupts = <0x00 0x03 0x04>; + clocks = <0x2a 0x14>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x5c>; + }; + + gpio1@ff250000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff250000 0x00 0x100>; + interrupts = <0x00 0x04 0x04>; + clocks = <0x02 0x15c>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0xbf>; + }; + + gpio2@ff260000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff260000 0x00 0x100>; + interrupts = <0x00 0x05 0x04>; + clocks = <0x02 0x15d>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x66>; + }; + + gpio3@ff270000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff270000 0x00 0x100>; + interrupts = <0x00 0x06 0x04>; + clocks = <0x02 0x15e>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x97>; + }; + + pcfg-pull-up { + bias-pull-up; + phandle = <0xb2>; + }; + + pcfg-pull-down { + bias-pull-down; + phandle = <0x118>; + }; + + pcfg-pull-none { + bias-disable; + phandle = <0xb1>; + }; + + pcfg-pull-none-2ma { + bias-disable; + drive-strength = <0x02>; + phandle = <0x119>; + }; + + pcfg-pull-up-2ma { + bias-pull-up; + drive-strength = <0x02>; + phandle = <0x11a>; + }; + + pcfg-pull-up-4ma { + bias-pull-up; + drive-strength = <0x04>; + phandle = <0xb3>; + }; + + pcfg-pull-none-4ma { + bias-disable; + drive-strength = <0x04>; + phandle = <0x11b>; + }; + + pcfg-pull-down-4ma { + bias-pull-down; + drive-strength = <0x04>; + phandle = <0x11c>; + }; + + pcfg-pull-none-8ma { + bias-disable; + drive-strength = <0x08>; + phandle = <0xb6>; + }; + + pcfg-pull-up-8ma { + bias-pull-up; + drive-strength = <0x08>; + phandle = <0xb4>; + }; + + pcfg-pull-none-12ma { + bias-disable; + drive-strength = <0x0c>; + phandle = <0xb8>; + }; + + pcfg-pull-up-12ma { + bias-pull-up; + drive-strength = <0x0c>; + phandle = <0xb7>; + }; + + pcfg-pull-none-smt { + bias-disable; + input-schmitt-enable; + phandle = <0xb0>; + }; + + pcfg-output-high { + output-high; + phandle = <0x11d>; + }; + + pcfg-output-low { + output-low; + phandle = <0xb9>; + }; + + pcfg-input-high { + bias-pull-up; + input-enable; + phandle = <0xb5>; + }; + + pcfg-input { + input-enable; + phandle = <0x11e>; + }; + + i2c0 { + + i2c0-xfer { + rockchip,pins = <0x00 0x08 0x01 0xb0 0x00 0x09 0x01 0xb0>; + phandle = <0x5b>; + }; + }; + + i2c1 { + + i2c1-xfer { + rockchip,pins = <0x00 0x12 0x01 0xb0 0x00 0x13 0x01 0xb0>; + phandle = <0x69>; + }; + }; + + i2c2 { + + i2c2-xfer { + rockchip,pins = <0x02 0x0f 0x02 0xb0 0x02 0x10 0x02 0xb0>; + phandle = <0x6a>; + }; + }; + + i2c3 { + + i2c3-xfer { + rockchip,pins = <0x01 0x0c 0x04 0xb0 0x01 0x0d 0x04 0xb0>; + phandle = <0x6b>; + }; + }; + + tsadc { + + tsadc-otp-gpio { + rockchip,pins = <0x00 0x06 0x00 0xb1>; + phandle = <0x86>; + }; + + tsadc-otp-out { + rockchip,pins = <0x00 0x06 0x01 0xb1>; + phandle = <0x87>; + }; + }; + + uart0 { + + uart0-xfer { + rockchip,pins = <0x00 0x0a 0x01 0xb2 0x00 0x0b 0x01 0xb2>; + phandle = <0x2c>; + }; + + uart0-cts { + rockchip,pins = <0x00 0x0c 0x01 0xb1>; + phandle = <0x2d>; + }; + + uart0-rts { + rockchip,pins = <0x00 0x0d 0x01 0xb1>; + phandle = <0x2e>; + }; + + uart0-rts-gpio { + rockchip,pins = <0x00 0x0d 0x00 0xb1>; + phandle = <0x11f>; + }; + }; + + uart1 { + + uart1-xfer { + rockchip,pins = <0x01 0x11 0x01 0xb2 0x01 0x10 0x01 0xb2>; + phandle = <0x4f>; + }; + + uart1-cts { + rockchip,pins = <0x01 0x12 0x01 0xb1>; + phandle = <0x50>; + }; + + uart1-rts { + rockchip,pins = <0x01 0x13 0x01 0xb1>; + phandle = <0x120>; + }; + + uart1-rts-gpio { + rockchip,pins = <0x01 0x13 0x00 0xb1>; + phandle = <0x121>; + }; + }; + + uart2-m0 { + + uart2m0-xfer { + rockchip,pins = <0x01 0x1a 0x02 0xb2 0x01 0x1b 0x02 0xb2>; + phandle = <0x51>; + }; + }; + + uart2-m1 { + + uart2m1-xfer { + rockchip,pins = <0x02 0x0c 0x02 0xb2 0x02 0x0e 0x02 0xb2>; + phandle = <0xba>; + }; + }; + + uart3-m0 { + + uart3m0-xfer { + rockchip,pins = <0x00 0x10 0x02 0xb2 0x00 0x11 0x02 0xb2>; + phandle = <0x122>; + }; + + uart3m0-cts { + rockchip,pins = <0x00 0x12 0x02 0xb1>; + phandle = <0x123>; + }; + + uart3m0-rts { + rockchip,pins = <0x00 0x13 0x02 0xb1>; + phandle = <0x124>; + }; + + uart3m0-rts-gpio { + rockchip,pins = <0x00 0x13 0x00 0xb1>; + phandle = <0x125>; + }; + }; + + uart3-m1 { + + uart3m1-xfer { + rockchip,pins = <0x01 0x0e 0x02 0xb2 0x01 0x0f 0x02 0xb2>; + phandle = <0x52>; + }; + + uart3m1-cts { + rockchip,pins = <0x01 0x0c 0x02 0xb1>; + phandle = <0x53>; + }; + + uart3m1-rts { + rockchip,pins = <0x01 0x0d 0x02 0xb1>; + phandle = <0x54>; + }; + + uart3m1-rts-gpio { + rockchip,pins = <0x01 0x0d 0x00 0xb1>; + phandle = <0x126>; + }; + }; + + uart4 { + + uart4-xfer { + rockchip,pins = <0x01 0x1c 0x02 0xb2 0x01 0x1d 0x02 0xb2>; + phandle = <0x55>; + }; + + uart4-cts { + rockchip,pins = <0x01 0x1e 0x02 0xb1>; + phandle = <0x56>; + }; + + uart4-rts { + rockchip,pins = <0x01 0x1f 0x02 0xb1>; + phandle = <0x57>; + }; + }; + + uart5 { + + uart5-xfer { + rockchip,pins = <0x03 0x02 0x04 0xb2 0x03 0x01 0x04 0xb2>; + phandle = <0x58>; + }; + + uart5-cts { + rockchip,pins = <0x03 0x03 0x04 0xb1>; + phandle = <0x59>; + }; + + uart5-rts { + rockchip,pins = <0x03 0x05 0x04 0xb1>; + phandle = <0x5a>; + }; + }; + + spi0 { + + spi0-clk { + rockchip,pins = <0x01 0x0f 0x03 0xb3>; + phandle = <0x6c>; + }; + + spi0-csn { + rockchip,pins = <0x01 0x0e 0x03 0xb3>; + phandle = <0x6d>; + }; + + spi0-miso { + rockchip,pins = <0x01 0x0d 0x03 0xb3>; + phandle = <0x6e>; + }; + + spi0-mosi { + rockchip,pins = <0x01 0x0c 0x03 0xb3>; + phandle = <0x6f>; + }; + + spi0-clk-hs { + rockchip,pins = <0x01 0x0f 0x03 0xb4>; + phandle = <0x70>; + }; + + spi0-miso-hs { + rockchip,pins = <0x01 0x0d 0x03 0xb4>; + phandle = <0x71>; + }; + + spi0-mosi-hs { + rockchip,pins = <0x01 0x0c 0x03 0xb4>; + phandle = <0x72>; + }; + }; + + spi1 { + + spi1-clk { + rockchip,pins = <0x03 0x0f 0x04 0xb3>; + phandle = <0x73>; + }; + + spi1-csn0 { + rockchip,pins = <0x03 0x09 0x04 0xb3>; + phandle = <0x74>; + }; + + spi1-csn1 { + rockchip,pins = <0x03 0x0a 0x02 0xb3>; + phandle = <0x75>; + }; + + spi1-miso { + rockchip,pins = <0x03 0x0e 0x04 0xb3>; + phandle = <0x76>; + }; + + spi1-mosi { + rockchip,pins = <0x03 0x0c 0x04 0xb3>; + phandle = <0x77>; + }; + + spi1-clk-hs { + rockchip,pins = <0x03 0x0f 0x04 0xb4>; + phandle = <0x78>; + }; + + spi1-miso-hs { + rockchip,pins = <0x03 0x0e 0x04 0xb4>; + phandle = <0x79>; + }; + + spi1-mosi-hs { + rockchip,pins = <0x03 0x0c 0x04 0xb4>; + phandle = <0x7a>; + }; + }; + + pdm { + + pdm-clk0m0 { + rockchip,pins = <0x03 0x16 0x02 0xb1>; + phandle = <0x44>; + }; + + pdm-clk0m1 { + rockchip,pins = <0x02 0x16 0x01 0xb1>; + phandle = <0x127>; + }; + + pdm-clk1 { + rockchip,pins = <0x03 0x17 0x02 0xb1>; + phandle = <0x45>; + }; + + pdm-sdi0m0 { + rockchip,pins = <0x03 0x1b 0x02 0xb1>; + phandle = <0x46>; + }; + + pdm-sdi0m1 { + rockchip,pins = <0x02 0x15 0x02 0xb1>; + phandle = <0x128>; + }; + + pdm-sdi1 { + rockchip,pins = <0x03 0x18 0x02 0xb1>; + phandle = <0x47>; + }; + + pdm-sdi2 { + rockchip,pins = <0x03 0x19 0x02 0xb1>; + phandle = <0x48>; + }; + + pdm-sdi3 { + rockchip,pins = <0x03 0x1a 0x02 0xb1>; + phandle = <0x49>; + }; + + pdm-clk0m0-sleep { + rockchip,pins = <0x03 0x16 0x00 0xb5>; + phandle = <0x129>; + }; + + pdm-clk0m1-sleep { + rockchip,pins = <0x02 0x16 0x00 0xb5>; + phandle = <0x12a>; + }; + + pdm-clk1-sleep { + rockchip,pins = <0x03 0x17 0x00 0xb5>; + phandle = <0x12b>; + }; + + pdm-sdi0m0-sleep { + rockchip,pins = <0x03 0x1b 0x00 0xb5>; + phandle = <0x12c>; + }; + + pdm-sdi0m1-sleep { + rockchip,pins = <0x02 0x15 0x00 0xb5>; + phandle = <0x12d>; + }; + + pdm-sdi1-sleep { + rockchip,pins = <0x03 0x18 0x00 0xb5>; + phandle = <0x12e>; + }; + + pdm-sdi2-sleep { + rockchip,pins = <0x03 0x19 0x00 0xb5>; + phandle = <0x12f>; + }; + + pdm-sdi3-sleep { + rockchip,pins = <0x03 0x1a 0x00 0xb5>; + phandle = <0x130>; + }; + }; + + i2s0 { + + i2s0-8ch-mclk { + rockchip,pins = <0x03 0x11 0x02 0xb1>; + phandle = <0x131>; + }; + + i2s0-8ch-sclktx { + rockchip,pins = <0x03 0x13 0x02 0xb1>; + phandle = <0x30>; + }; + + i2s0-8ch-sclkrx { + rockchip,pins = <0x03 0x0c 0x02 0xb1>; + phandle = <0x31>; + }; + + i2s0-8ch-lrcktx { + rockchip,pins = <0x03 0x12 0x02 0xb1>; + phandle = <0x32>; + }; + + i2s0-8ch-lrckrx { + rockchip,pins = <0x03 0x0d 0x02 0xb1>; + phandle = <0x33>; + }; + + i2s0-8ch-sdo0 { + rockchip,pins = <0x03 0x14 0x02 0xb1>; + phandle = <0x38>; + }; + + i2s0-8ch-sdo1 { + rockchip,pins = <0x03 0x10 0x02 0xb1>; + phandle = <0x39>; + }; + + i2s0-8ch-sdo2 { + rockchip,pins = <0x03 0x0f 0x02 0xb1>; + phandle = <0x3a>; + }; + + i2s0-8ch-sdo3 { + rockchip,pins = <0x03 0x0e 0x02 0xb1>; + phandle = <0x3b>; + }; + + i2s0-8ch-sdi0 { + rockchip,pins = <0x03 0x15 0x02 0xb1>; + phandle = <0x34>; + }; + + i2s0-8ch-sdi1 { + rockchip,pins = <0x03 0x0b 0x02 0xb1>; + phandle = <0x35>; + }; + + i2s0-8ch-sdi2 { + rockchip,pins = <0x03 0x09 0x02 0xb1>; + phandle = <0x36>; + }; + + i2s0-8ch-sdi3 { + rockchip,pins = <0x03 0x08 0x02 0xb1>; + phandle = <0x37>; + }; + }; + + i2s1 { + + i2s1-2ch-mclk { + rockchip,pins = <0x02 0x13 0x01 0xb1>; + phandle = <0x68>; + }; + + i2s1-2ch-sclk { + rockchip,pins = <0x02 0x12 0x01 0xb1>; + phandle = <0x3c>; + }; + + i2s1-2ch-lrck { + rockchip,pins = <0x02 0x11 0x01 0xb1>; + phandle = <0x3d>; + }; + + i2s1-2ch-sdi { + rockchip,pins = <0x02 0x15 0x01 0xb1>; + phandle = <0x3e>; + }; + + i2s1-2ch-sdo { + rockchip,pins = <0x02 0x14 0x01 0xb1>; + phandle = <0x3f>; + }; + }; + + i2s2 { + + i2s2-2ch-mclk { + rockchip,pins = <0x03 0x01 0x02 0xb1>; + phandle = <0x132>; + }; + + i2s2-2ch-sclk { + rockchip,pins = <0x03 0x02 0x02 0xb1>; + phandle = <0x40>; + }; + + i2s2-2ch-lrck { + rockchip,pins = <0x03 0x03 0x02 0xb1>; + phandle = <0x41>; + }; + + i2s2-2ch-sdi { + rockchip,pins = <0x03 0x05 0x02 0xb1>; + phandle = <0x42>; + }; + + i2s2-2ch-sdo { + rockchip,pins = <0x03 0x07 0x02 0xb1>; + phandle = <0x43>; + }; + }; + + sdmmc { + + sdmmc-clk { + rockchip,pins = <0x01 0x1e 0x01 0xb6>; + phandle = <0x8f>; + }; + + sdmmc-cmd { + rockchip,pins = <0x01 0x1f 0x01 0xb4>; + phandle = <0x90>; + }; + + sdmmc-det { + rockchip,pins = <0x00 0x03 0x01 0xb4>; + phandle = <0x91>; + }; + + sdmmc-bus1 { + rockchip,pins = <0x01 0x1a 0x01 0xb4>; + phandle = <0x133>; + }; + + sdmmc-bus4 { + rockchip,pins = <0x01 0x1a 0x01 0xb4 0x01 0x1b 0x01 0xb4 0x01 0x1c 0x01 0xb4 0x01 0x1d 0x01 0xb4>; + phandle = <0x92>; + }; + + sdmmc-gpio { + rockchip,pins = <0x01 0x1a 0x00 0xb3 0x01 0x1b 0x00 0xb3 0x01 0x1c 0x00 0xb3 0x01 0x1d 0x00 0xb3 0x01 0x1e 0x00 0xb3 0x01 0x1f 0x00 0xb3>; + phandle = <0x134>; + }; + }; + + sdio { + + sdio-clk { + rockchip,pins = <0x01 0x15 0x01 0xb1>; + phandle = <0x96>; + }; + + sdio-cmd { + rockchip,pins = <0x01 0x14 0x01 0xb2>; + phandle = <0x95>; + }; + + sdio-bus4 { + rockchip,pins = <0x01 0x16 0x01 0xb2 0x01 0x17 0x01 0xb2 0x01 0x18 0x01 0xb2 0x01 0x19 0x01 0xb2>; + phandle = <0x94>; + }; + + sdio-gpio { + rockchip,pins = <0x01 0x16 0x00 0xb2 0x01 0x17 0x00 0xb2 0x01 0x18 0x00 0xb2 0x01 0x19 0x00 0xb2 0x01 0x14 0x00 0xb2 0x01 0x15 0x00 0xb2>; + phandle = <0x135>; + }; + }; + + emmc { + + emmc-clk { + rockchip,pins = <0x01 0x09 0x02 0xb6>; + phandle = <0x136>; + }; + + emmc-cmd { + rockchip,pins = <0x01 0x0a 0x02 0xb4>; + phandle = <0x137>; + }; + + emmc-pwren { + rockchip,pins = <0x01 0x08 0x02 0xb1>; + phandle = <0x138>; + }; + + emmc-rstnout { + rockchip,pins = <0x01 0x0b 0x02 0xb1>; + phandle = <0x139>; + }; + + emmc-bus1 { + rockchip,pins = <0x01 0x00 0x02 0xb4>; + phandle = <0x13a>; + }; + + emmc-bus4 { + rockchip,pins = <0x01 0x00 0x02 0xb4 0x01 0x01 0x02 0xb4 0x01 0x02 0x02 0xb4 0x01 0x03 0x02 0xb4>; + phandle = <0x13b>; + }; + + emmc-bus8 { + rockchip,pins = <0x01 0x00 0x02 0xb4 0x01 0x01 0x02 0xb4 0x01 0x02 0x02 0xb4 0x01 0x03 0x02 0xb4 0x01 0x04 0x02 0xb4 0x01 0x05 0x02 0xb4 0x01 0x06 0x02 0xb4 0x01 0x07 0x02 0xb4>; + phandle = <0x13c>; + }; + }; + + flash { + + flash-cs0 { + rockchip,pins = <0x01 0x08 0x01 0xb1>; + phandle = <0x13d>; + }; + + flash-rdy { + rockchip,pins = <0x01 0x09 0x01 0xb1>; + phandle = <0x13e>; + }; + + flash-dqs { + rockchip,pins = <0x01 0x0a 0x01 0xb1>; + phandle = <0x13f>; + }; + + flash-ale { + rockchip,pins = <0x01 0x0b 0x01 0xb1>; + phandle = <0x140>; + }; + + flash-cle { + rockchip,pins = <0x01 0x0c 0x01 0xb1>; + phandle = <0x141>; + }; + + flash-wrn { + rockchip,pins = <0x01 0x0d 0x01 0xb1>; + phandle = <0x142>; + }; + + flash-csl { + rockchip,pins = <0x01 0x0e 0x01 0xb1>; + phandle = <0x143>; + }; + + flash-rdn { + rockchip,pins = <0x01 0x0f 0x01 0xb1>; + phandle = <0x144>; + }; + + flash-bus8 { + rockchip,pins = <0x01 0x00 0x01 0xb7 0x01 0x01 0x01 0xb7 0x01 0x02 0x01 0xb7 0x01 0x03 0x01 0xb7 0x01 0x04 0x01 0xb7 0x01 0x05 0x01 0xb7 0x01 0x06 0x01 0xb7 0x01 0x07 0x01 0xb7>; + phandle = <0x145>; + }; + }; + + lcdc { + + lcdc-m0-rgb-pins { + rockchip,pins = <0x03 0x00 0x01 0xb6 0x03 0x01 0x01 0xb6 0x03 0x02 0x01 0xb6 0x03 0x03 0x01 0xb6 0x03 0x04 0x01 0xb6 0x03 0x05 0x01 0xb6 0x03 0x06 0x01 0xb6 0x03 0x07 0x01 0xb6 0x03 0x08 0x01 0xb6 0x03 0x09 0x01 0xb6 0x03 0x0a 0x01 0xb6 0x03 0x0b 0x01 0xb6 0x03 0x0c 0x01 0xb6 0x03 0x0d 0x01 0xb6 0x03 0x0e 0x01 0xb6 0x03 0x0f 0x01 0xb6 0x03 0x10 0x01 0xb6 0x03 0x11 0x01 0xb6 0x03 0x12 0x01 0xb6 0x03 0x13 0x01 0xb6 0x03 0x14 0x01 0xb6 0x03 0x15 0x01 0xb6 0x03 0x16 0x01 0xb6 0x03 0x17 0x01 0xb6 0x03 0x18 0x01 0xb6 0x03 0x19 0x01 0xb6 0x03 0x1a 0x01 0xb6 0x03 0x1b 0x01 0xb6>; + phandle = <0x146>; + }; + + lcdc-m0-sleep-pins { + rockchip,pins = <0x03 0x00 0x00 0xb1 0x03 0x01 0x00 0xb1 0x03 0x02 0x00 0xb1 0x03 0x03 0x00 0xb1 0x03 0x04 0x00 0xb1 0x03 0x05 0x00 0xb1 0x03 0x06 0x00 0xb1 0x03 0x07 0x00 0xb1 0x03 0x08 0x00 0xb1 0x03 0x09 0x00 0xb1 0x03 0x0a 0x00 0xb1 0x03 0x0b 0x00 0xb1 0x03 0x0c 0x00 0xb1 0x03 0x0d 0x00 0xb1 0x03 0x0e 0x00 0xb1 0x03 0x0f 0x00 0xb1 0x03 0x10 0x00 0xb1 0x03 0x11 0x00 0xb1 0x03 0x12 0x00 0xb1 0x03 0x13 0x00 0xb1 0x03 0x14 0x00 0xb1 0x03 0x15 0x00 0xb1 0x03 0x16 0x00 0xb1 0x03 0x17 0x00 0xb1 0x03 0x18 0x00 0xb1 0x03 0x19 0x00 0xb1 0x03 0x1a 0x00 0xb1 0x03 0x1b 0x00 0xb1>; + phandle = <0x147>; + }; + + lcdc-m1-rgb-pins { + rockchip,pins = <0x03 0x00 0x01 0xb6 0x03 0x04 0x01 0xb6 0x03 0x06 0x01 0xb6 0x03 0x0a 0x01 0xb6 0x03 0x0b 0x01 0xb6 0x03 0x0d 0x01 0xb6 0x03 0x10 0x01 0xb6 0x03 0x11 0x01 0xb6 0x03 0x12 0x01 0xb6 0x03 0x13 0x01 0xb6 0x03 0x14 0x01 0xb6 0x03 0x15 0x01 0xb6 0x03 0x16 0x01 0xb6 0x03 0x17 0x01 0xb6 0x03 0x18 0x01 0xb6 0x03 0x19 0x01 0xb6 0x03 0x1a 0x01 0xb6 0x03 0x1b 0x01 0xb6>; + phandle = <0x4d>; + }; + + lcdc-m1-sleep-pins { + rockchip,pins = <0x03 0x00 0x00 0xb1 0x03 0x04 0x00 0xb1 0x03 0x06 0x00 0xb1 0x03 0x0a 0x00 0xb1 0x03 0x0b 0x00 0xb1 0x03 0x0d 0x00 0xb1 0x03 0x10 0x00 0xb1 0x03 0x11 0x00 0xb1 0x03 0x12 0x00 0xb1 0x03 0x13 0x00 0xb1 0x03 0x14 0x00 0xb1 0x03 0x15 0x00 0xb1 0x03 0x16 0x00 0xb1 0x03 0x17 0x00 0xb1 0x03 0x18 0x00 0xb1 0x03 0x19 0x00 0xb1 0x03 0x1a 0x00 0xb1 0x03 0x1b 0x00 0xb1>; + phandle = <0x4e>; + }; + }; + + pwm0 { + + pwm0-pin { + rockchip,pins = <0x00 0x0f 0x01 0xb1>; + phandle = <0x7b>; + }; + }; + + pwm1 { + + pwm1-pin { + rockchip,pins = <0x00 0x10 0x01 0xb1>; + phandle = <0x7c>; + }; + }; + + pwm2 { + + pwm2-pin { + rockchip,pins = <0x02 0x0d 0x01 0xb1>; + phandle = <0x7d>; + }; + }; + + pwm3 { + + pwm3-pin { + rockchip,pins = <0x00 0x11 0x01 0xb1>; + phandle = <0x7e>; + }; + }; + + pwm4 { + + pwm4-pin { + rockchip,pins = <0x03 0x12 0x03 0xb1>; + phandle = <0x7f>; + }; + }; + + pwm5 { + + pwm5-pin { + rockchip,pins = <0x03 0x13 0x03 0xb1>; + phandle = <0x80>; + }; + }; + + pwm6 { + + pwm6-pin { + rockchip,pins = <0x03 0x14 0x03 0xb1>; + phandle = <0x81>; + }; + }; + + pwm7 { + + pwm7-pin { + rockchip,pins = <0x03 0x15 0x03 0xb1>; + phandle = <0x82>; + }; + }; + + gmac { + + rmii-pins { + rockchip,pins = <0x02 0x00 0x02 0xb8 0x02 0x01 0x02 0xb8 0x02 0x02 0x02 0xb8 0x02 0x03 0x02 0xb1 0x02 0x04 0x02 0xb1 0x02 0x05 0x02 0xb1 0x02 0x06 0x02 0xb1 0x02 0x07 0x02 0xb1 0x02 0x09 0x02 0xb1>; + phandle = <0x8d>; + }; + + mac-refclk-12ma { + rockchip,pins = <0x02 0x0a 0x02 0xb8>; + phandle = <0x8e>; + }; + + mac-refclk { + rockchip,pins = <0x02 0x0a 0x02 0xb1>; + phandle = <0x148>; + }; + }; + + cif-m0 { + + cif-clkout-m0 { + rockchip,pins = <0x02 0x0b 0x01 0xb8>; + phandle = <0xa7>; + }; + + dvp-d2d9-m0 { + rockchip,pins = <0x02 0x00 0x01 0xb1 0x02 0x01 0x01 0xb1 0x02 0x02 0x01 0xb1 0x02 0x03 0x01 0xb1 0x02 0x04 0x01 0xb1 0x02 0x05 0x01 0xb1 0x02 0x06 0x01 0xb1 0x02 0x07 0x01 0xb1 0x02 0x08 0x01 0xb1 0x02 0x09 0x01 0xb1 0x02 0x0a 0x01 0xb1 0x02 0x0b 0x01 0xb1>; + phandle = <0xa5>; + }; + + dvp-d0d1-m0 { + rockchip,pins = <0x02 0x0c 0x01 0xb1 0x02 0x0e 0x01 0xb1>; + phandle = <0xa9>; + }; + + d10-d11-m0 { + rockchip,pins = <0x02 0x0f 0x01 0xb1 0x02 0x10 0x01 0xb1>; + phandle = <0xa8>; + }; + }; + + cif-m1 { + + cif-clkout-m1 { + rockchip,pins = <0x03 0x18 0x03 0xb1>; + phandle = <0x149>; + }; + + dvp-d2d9-m1 { + rockchip,pins = <0x03 0x03 0x03 0xb1 0x03 0x05 0x03 0xb1 0x03 0x07 0x03 0xb1 0x03 0x08 0x03 0xb1 0x03 0x09 0x03 0xb1 0x03 0x0c 0x03 0xb1 0x03 0x0e 0x03 0xb1 0x03 0x0f 0x03 0xb1 0x03 0x19 0x03 0xb1 0x03 0x1a 0x03 0xb1 0x03 0x1b 0x03 0xb1 0x03 0x18 0x03 0xb1>; + phandle = <0x14a>; + }; + + dvp-d0d1-m1 { + rockchip,pins = <0x03 0x01 0x03 0xb1 0x03 0x02 0x03 0xb1>; + phandle = <0x14b>; + }; + + d10-d11-m1 { + rockchip,pins = <0x03 0x16 0x03 0xb1 0x03 0x17 0x03 0xb1>; + phandle = <0x14c>; + }; + }; + + isp { + + isp-prelight { + rockchip,pins = <0x03 0x19 0x04 0xb1>; + phandle = <0x14d>; + }; + }; + + pmic { + + pmic_int { + rockchip,pins = <0x00 0x0a 0x00 0xb2 0x00 0x0b 0x00 0xb1>; + phandle = <0x5d>; + }; + + soc_slppin_gpio { + rockchip,pins = <0x00 0x04 0x00 0xb9>; + phandle = <0x60>; + }; + + soc_slppin_slp { + rockchip,pins = <0x00 0x04 0x01 0xb1>; + phandle = <0x5e>; + }; + + soc_slppin_rst { + rockchip,pins = <0x00 0x04 0x02 0xb1>; + phandle = <0x62>; + }; + }; + + leds { + + led-pins { + rockchip,pins = <0x00 0x11 0x00 0xb1>; + phandle = <0xc0>; + }; + }; + + btns { + + btn-pins { + rockchip,pins = <0x01 0x0c 0x00 0xb2 0x01 0x0d 0x00 0xb2 0x01 0x0e 0x00 0xb2 0x01 0x0f 0x00 0xb2 0x01 0x02 0x00 0xb2 0x01 0x05 0x00 0xb2 0x01 0x06 0x00 0xb2 0x01 0x07 0x00 0xb2 0x02 0x00 0x00 0xb2 0x02 0x01 0x00 0xb2 0x02 0x02 0x00 0xb2 0x02 0x03 0x00 0xb2 0x02 0x04 0x00 0xb2 0x02 0x05 0x00 0xb2 0x02 0x06 0x00 0xb2 0x02 0x07 0x00 0xb2 0x03 0x09 0x00 0xb2 0x03 0x0a 0x00 0xb2 0x03 0x0c 0x00 0xb2 0x03 0x0f 0x00 0xb2>; + phandle = <0xbd>; + }; + }; + }; + + chosen { + bootargs = [00]; + }; + + fiq-debugger { + compatible = "rockchip,fiq-debugger"; + rockchip,serial-id = <0x02>; + rockchip,wake-irq = <0x00>; + rockchip,irq-mode-enable = <0x00>; + rockchip,baudrate = <0x1c200>; + interrupts = <0x00 0x7f 0x08>; + pinctrl-names = "default"; + pinctrl-0 = <0xba>; + status = "okay"; + }; + + ramoops { + compatible = "ramoops"; + record-size = <0x00 0x20000>; + console-size = <0x00 0x80000>; + ftrace-size = <0x00 0x00>; + pmsg-size = <0x00 0x00>; + memory-region = <0xbb>; + }; + + reserved-memory { + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + + drm-logo@00000000 { + compatible = "rockchip,drm-logo"; + reg = <0x00 0x00 0x00 0x00>; + phandle = <0x11>; + }; + + region@110000 { + reg = <0x00 0x110000 0x00 0xf0000>; + reg-names = "ramoops_mem"; + phandle = <0xbb>; + }; + }; + + odroidgo3-keys { + compatible = "gpio-keys"; + #address-cells = <0x01>; + #size-cells = <0x00>; + autorepeat; + phandle = <0x14e>; + + button@0 { + label = "GPIO BTN-VOLUP"; + linux,code = <0x73>; + gpios = <0x66 0x00 0x01>; + }; + + button@1 { + label = "GPIO BTN-VOLDN"; + linux,code = <0x72>; + gpios = <0x66 0x01 0x01>; + }; + }; + + odroidgo3-joypad { + compatible = "odroidgo3-joypad"; + pwms = <0xbc 0x00 0xbebc200 0x00>; + pwm-names = "enable"; + rumble-boost-weak = <0x00>; + rumble-boost-strong = <0x00>; + joypad-name = "GO-Super Gamepad"; + joypad-product = <0x1100>; + joypad-revision = <0x100>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <0xbd>; + pinctrl-1 = <0x7b>; + io-channel-names = "amux_adc"; + io-channels = <0xbe 0x01>; + amux-count = <0x04>; + amux-a-gpios = <0x97 0x0b 0x01>; + amux-b-gpios = <0x97 0x08 0x01>; + amux-en-gpios = <0x97 0x0d 0x01>; + button-adc-scale = <0x02>; + button-adc-deadzone = <0x40>; + button-adc-fuzz = <0x20>; + button-adc-flat = <0x20>; + abs_x-p-tuning = <0xc8>; + abs_x-n-tuning = <0xc8>; + abs_y-p-tuning = <0xc8>; + abs_y-n-tuning = <0xc8>; + abs_rx-p-tuning = <0xc8>; + abs_rx-n-tuning = <0xc8>; + abs_ry-p-tuning = <0xc8>; + abs_ry-n-tuning = <0xc8>; + poll-interval = <0x0a>; + invert-absx; + invert-absy; + phandle = <0x14f>; + + sw1 { + gpios = <0xbf 0x0c 0x01>; + label = "GPIO DPAD-UP"; + linux,code = <0x220>; + }; + + sw2 { + gpios = <0xbf 0x0d 0x01>; + label = "GPIO DPAD-DOWN"; + linux,code = <0x221>; + }; + + sw3 { + gpios = <0xbf 0x0e 0x01>; + label = "GPIO DPAD-LEFT"; + linux,code = <0x222>; + }; + + sw4 { + gpios = <0xbf 0x0f 0x01>; + label = "GPIO DPAD-RIGHT"; + linux,code = <0x223>; + }; + + sw5 { + gpios = <0xbf 0x02 0x01>; + label = "GPIO KEY BTN-A"; + linux,code = <0x131>; + }; + + sw6 { + gpios = <0xbf 0x05 0x01>; + label = "GPIO BTN-B"; + linux,code = <0x130>; + }; + + sw7 { + gpios = <0xbf 0x06 0x01>; + label = "GPIO BTN-Y"; + linux,code = <0x134>; + }; + + sw8 { + gpios = <0xbf 0x07 0x01>; + label = "GPIO BTN-X"; + linux,code = <0x133>; + }; + + sw11 { + gpios = <0x66 0x02 0x01>; + label = "GPIO F3"; + linux,code = <0x2c2>; + }; + + sw12 { + gpios = <0x66 0x03 0x01>; + label = "GPIO F4"; + linux,code = <0x2c3>; + }; + + sw15 { + gpios = <0x66 0x06 0x01>; + label = "GPIO TOP-LEFT"; + linux,code = <0x136>; + }; + + sw16 { + gpios = <0x66 0x07 0x01>; + label = "GPIO TOP-RIGHT"; + linux,code = <0x137>; + }; + + sw19 { + gpios = <0x97 0x09 0x01>; + label = "GPIO F1"; + linux,code = <0x2c0>; + }; + + sw20 { + gpios = <0x97 0x0f 0x01>; + label = "GPIO TOP-RIGHT2"; + linux,code = <0x139>; + }; + + sw21 { + gpios = <0x97 0x0a 0x01>; + label = "GPIO TOP-LEFT2"; + linux,code = <0x138>; + }; + + sw22 { + gpios = <0x97 0x0c 0x01>; + label = "GPIO F2"; + linux,code = <0x2c1>; + }; + + sw13 { + gpios = <0x66 0x04 0x01>; + label = "GPIO F5"; + linux,code = <0x2c4>; + }; + }; + + gpio_leds { + compatible = "gpio-leds"; + pinctrl-names = "led_pins"; + pinctrl-0 = <0xc0>; + phandle = <0x150>; + + heartbeat { + label = "blue:heartbeat"; + gpios = <0x5c 0x11 0x00>; + linux,default-trigger = "heartbeat"; + }; + }; + + backlight { + compatible = "pwm-backlight"; + pwms = <0xc1 0x00 0xf519 0x00>; + brightness-levels = <0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2a 0x2b 0x2c 0x2d 0x2e 0x2f 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x3a 0x3b 0x3c 0x3d 0x3e 0x3f 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48 0x49 0x4a 0x4b 0x4c 0x4d 0x4e 0x4f 0x50 0x51 0x52 0x53 0x54 0x55 0x56 0x57 0x58 0x59 0x5a 0x5b 0x5c 0x5d 0x5e 0x5f 0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69 0x6a 0x6b 0x6c 0x6d 0x6e 0x6f 0x70 0x71 0x72 0x73 0x74 0x75 0x76 0x77 0x78 0x79 0x7a 0x7b 0x7c 0x7d 0x7e 0x7f 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90 0x91 0x92 0x93 0x94 0x95 0x96 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f 0xa0>; + default-brightness-level = <0x33>; + phandle = <0x9d>; + }; + + rk817-sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,name = "rockchip,rk817-codec"; + simple-audio-card,mclk-fs = <0x100>; + simple-audio-card,widgets = "Microphone\0Mic Jack\0Headphone\0Headphone Jack"; + simple-audio-card,routing = "MIC_IN\0Mic Jack\0Headphone Jack\0HPOL\0Headphone Jack\0HPOR"; + simple-audio-card,hp-det-gpio = <0x66 0x16 0x01>; + simple-audio-card,codec-hp-det = <0x01>; + + simple-audio-card,cpu { + sound-dai = <0xc2>; + }; + + simple-audio-card,codec { + sound-dai = <0xc3>; + }; + }; + + vccsys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v8_sys"; + regulator-always-on; + regulator-min-microvolt = <0x39fbc0>; + regulator-max-microvolt = <0x39fbc0>; + phandle = <0x64>; + }; + + __symbols__ { + ddr_timing = "/ddr_timing"; + cpu0 = "/cpus/cpu@0"; + cpu1 = "/cpus/cpu@1"; + cpu2 = "/cpus/cpu@2"; + cpu3 = "/cpus/cpu@3"; + CPU_SLEEP = "/cpus/idle-states/cpu-sleep"; + CLUSTER_SLEEP = "/cpus/idle-states/cluster-sleep"; + cpu0_opp_table = "/cpu0-opp-table"; + bus_soc = "/bus-soc"; + bus_apll = "/bus-apll"; + bus_apll_opp_table = "/bus-apll-opp-table"; + display_subsystem = "/display-subsystem"; + route_lvds = "/display-subsystem/route/route-lvds"; + route_dsi = "/display-subsystem/route/route-dsi"; + route_rgb = "/display-subsystem/route/route-rgb"; + gmac_clkin = "/external-gmac-clock"; + rockchip_suspend = "/rockchip-suspend"; + xin24m = "/xin24m"; + xin32k = "/xin32k"; + pmu = "/power-management@ff000000"; + power = "/power-management@ff000000/power-controller"; + pmugrf = "/syscon@ff010000"; + pmu_io_domains = "/syscon@ff010000/io-domains"; + pmu_pvtm = "/syscon@ff010000/pmu-pvtm"; + uart0 = "/serial@ff030000"; + i2s0_8ch = "/i2s@ff060000"; + i2s1_2ch = "/i2s@ff070000"; + i2s2_2ch = "/i2s@ff080000"; + pdm = "/pdm@ff0a0000"; + crypto = "/crypto@ff0b0000"; + rng = "/rng@ff0b0000"; + gic = "/interrupt-controller@ff131000"; + grf = "/syscon@ff140000"; + io_domains = "/syscon@ff140000/io-domains"; + lvds = "/syscon@ff140000/lvds"; + lvds_in_vopb = "/syscon@ff140000/lvds/ports/port@0/endpoint@0"; + rgb = "/syscon@ff140000/rgb"; + rgb_in_vopb = "/syscon@ff140000/rgb/ports/port@0/endpoint@0"; + core_grf = "/syscon@ff148000"; + pvtm = "/syscon@ff148000/pvtm"; + uart1 = "/serial@ff158000"; + uart2 = "/serial@ff160000"; + uart3 = "/serial@ff168000"; + uart4 = "/serial@ff170000"; + uart5 = "/serial@ff178000"; + i2c0 = "/i2c@ff180000"; + rk817 = "/i2c@ff180000/pmic@20"; + pinctrl_rk8xx = "/i2c@ff180000/pmic@20/pinctrl_rk8xx"; + rk817_ts_gpio1 = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_ts_gpio1"; + rk817_gt_gpio2 = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_gt_gpio2"; + rk817_pin_ts = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_pin_ts"; + rk817_pin_gt = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_pin_gt"; + rk817_slppin_null = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_null"; + rk817_slppin_slp = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_slp"; + rk817_slppin_pwrdn = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_pwrdn"; + rk817_slppin_rst = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_rst"; + vdd_logic = "/i2c@ff180000/pmic@20/regulators/DCDC_REG1"; + vdd_arm = "/i2c@ff180000/pmic@20/regulators/DCDC_REG2"; + vcc_ddr = "/i2c@ff180000/pmic@20/regulators/DCDC_REG3"; + vcc_3v3 = "/i2c@ff180000/pmic@20/regulators/DCDC_REG4"; + vcc_1v0 = "/i2c@ff180000/pmic@20/regulators/LDO_REG1"; + vcc1v8_soc = "/i2c@ff180000/pmic@20/regulators/LDO_REG2"; + vdd1v0_soc = "/i2c@ff180000/pmic@20/regulators/LDO_REG3"; + vcc3v3_pmu = "/i2c@ff180000/pmic@20/regulators/LDO_REG4"; + vccio_sd = "/i2c@ff180000/pmic@20/regulators/LDO_REG5"; + vcc_sd = "/i2c@ff180000/pmic@20/regulators/LDO_REG6"; + vcc_backlight = "/i2c@ff180000/pmic@20/regulators/LDO_REG7"; + vcc_lcd = "/i2c@ff180000/pmic@20/regulators/LDO_REG8"; + dcdc_boost = "/i2c@ff180000/pmic@20/regulators/BOOST"; + otg_switch = "/i2c@ff180000/pmic@20/regulators/OTG_SWITCH"; + rk817_codec = "/i2c@ff180000/pmic@20/codec"; + i2c1 = "/i2c@ff190000"; + i2c2 = "/i2c@ff1a0000"; + i2c3 = "/i2c@ff1b0000"; + spi0 = "/spi@ff1d0000"; + spi1 = "/spi@ff1d8000"; + wdt = "/watchdog@ff1e0000"; + pwm0 = "/pwm@ff200000"; + pwm1 = "/pwm@ff200010"; + pwm2 = "/pwm@ff200020"; + pwm3 = "/pwm@ff200030"; + pwm4 = "/pwm@ff208000"; + pwm5 = "/pwm@ff208010"; + pwm6 = "/pwm@ff208020"; + pwm7 = "/pwm@ff208030"; + rktimer = "/rktimer@ff210000"; + dmac = "/amba/dmac@ff240000"; + thermal_zones = "/thermal-zones"; + soc_thermal = "/thermal-zones/soc-thermal"; + threshold = "/thermal-zones/soc-thermal/trips/trip-point-0"; + target = "/thermal-zones/soc-thermal/trips/trip-point-1"; + soc_crit = "/thermal-zones/soc-thermal/trips/soc-crit"; + gpu_thermal = "/thermal-zones/gpu-thermal"; + tsadc = "/tsadc@ff280000"; + saradc = "/saradc@ff288000"; + otp = "/otp@ff290000"; + otp_id = "/otp@ff290000/id@7"; + cpu_leakage = "/otp@ff290000/cpu-leakage@17"; + performance = "/otp@ff290000/performance@1e"; + cru = "/clock-controller@ff2b0000"; + cpu_boost = "/cpu-boost@ff2b8000"; + pmucru = "/pmu-clock-controller@ff2bc000"; + usb2phy_grf = "/syscon@ff2c0000"; + u2phy = "/syscon@ff2c0000/usb2-phy@100"; + u2phy_host = "/syscon@ff2c0000/usb2-phy@100/host-port"; + u2phy_otg = "/syscon@ff2c0000/usb2-phy@100/otg-port"; + video_phy = "/video-phy@ff2e0000"; + mipi_dphy_rx0 = "/mipi-dphy-rx0@ff2f0000"; + usb20_otg = "/usb@ff300000"; + usb_host0_ehci = "/usb@ff340000"; + usb_host0_ohci = "/usb@ff350000"; + gmac = "/ethernet@ff360000"; + sdmmc = "/dwmmc@ff370000"; + sdio = "/dwmmc@ff380000"; + emmc = "/dwmmc@ff390000"; + nandc0 = "/nandc@ff3b0000"; + sfc = "/sfc@ff3a0000"; + gpu = "/gpu@ff400000"; + gpu_opp_table = "/gpu-opp-table"; + hevc = "/hevc_service@ff440000"; + vpu = "/vpu_service@ff442000"; + vpu_combo = "/vpu_combo"; + hevc_mmu = "/iommu@ff440440"; + vpu_mmu = "/iommu@ff442800"; + dsi = "/dsi@ff450000"; + dsi_in_vopb = "/dsi@ff450000/ports/port@0/endpoint@0"; + timing0 = "/dsi@ff450000/panel@0/display-timings/60Hz"; + timing1 = "/dsi@ff450000/panel@0/display-timings/50Hz"; + timing2 = "/dsi@ff450000/panel@0/display-timings/75Hz"; + vopb = "/vop@ff460000"; + vopb_out = "/vop@ff460000/port"; + vopb_out_lvds = "/vop@ff460000/port/endpoint@0"; + vopb_out_dsi = "/vop@ff460000/port/endpoint@1"; + vopb_out_rgb = "/vop@ff460000/port/endpoint@2"; + vopb_mmu = "/iommu@ff460f00"; + rk_rga = "/rk_rga@ff480000"; + cif = "/cif@ff490000"; + cif_new = "/cif-new@ff490000"; + vip_mmu = "/iommu@ff490800"; + rk_isp = "/rk_isp@ff4a0000"; + rkisp1 = "/rkisp1@ff4a0000"; + isp_mmu = "/iommu@ff4a8000"; + qos_gmac = "/qos@ff518000"; + qos_gpu = "/qos@ff520000"; + qos_sdmmc = "/qos@ff52c000"; + qos_emmc = "/qos@ff538000"; + qos_nand = "/qos@ff538080"; + qos_sdio = "/qos@ff538100"; + qos_sfc = "/qos@ff538180"; + qos_usb_host = "/qos@ff540000"; + qos_usb_otg = "/qos@ff540080"; + qos_isp_128 = "/qos@ff548000"; + qos_isp_rd = "/qos@ff548080"; + qos_isp_wr = "/qos@ff548100"; + qos_isp_m1 = "/qos@ff548180"; + qos_vip = "/qos@ff548200"; + qos_rga_rd = "/qos@ff550000"; + qos_rga_wr = "/qos@ff550080"; + qos_vop_m0 = "/qos@ff550100"; + qos_vop_m1 = "/qos@ff550180"; + qos_vpu = "/qos@ff558000"; + qos_vpu_r128 = "/qos@ff558080"; + dfi = "/dfi@ff610000"; + dmc = "/dmc"; + ddr_power_model = "/dmc/ddr_power_model"; + dmc_opp_table = "/dmc-opp-table"; + rockchip_system_monitor = "/rockchip-system-monitor"; + pinctrl = "/pinctrl"; + gpio0 = "/pinctrl/gpio0@ff040000"; + gpio1 = "/pinctrl/gpio1@ff250000"; + gpio2 = "/pinctrl/gpio2@ff260000"; + gpio3 = "/pinctrl/gpio3@ff270000"; + pcfg_pull_up = "/pinctrl/pcfg-pull-up"; + pcfg_pull_down = "/pinctrl/pcfg-pull-down"; + pcfg_pull_none = "/pinctrl/pcfg-pull-none"; + pcfg_pull_none_2ma = "/pinctrl/pcfg-pull-none-2ma"; + pcfg_pull_up_2ma = "/pinctrl/pcfg-pull-up-2ma"; + pcfg_pull_up_4ma = "/pinctrl/pcfg-pull-up-4ma"; + pcfg_pull_none_4ma = "/pinctrl/pcfg-pull-none-4ma"; + pcfg_pull_down_4ma = "/pinctrl/pcfg-pull-down-4ma"; + pcfg_pull_none_8ma = "/pinctrl/pcfg-pull-none-8ma"; + pcfg_pull_up_8ma = "/pinctrl/pcfg-pull-up-8ma"; + pcfg_pull_none_12ma = "/pinctrl/pcfg-pull-none-12ma"; + pcfg_pull_up_12ma = "/pinctrl/pcfg-pull-up-12ma"; + pcfg_pull_none_smt = "/pinctrl/pcfg-pull-none-smt"; + pcfg_output_high = "/pinctrl/pcfg-output-high"; + pcfg_output_low = "/pinctrl/pcfg-output-low"; + pcfg_input_high = "/pinctrl/pcfg-input-high"; + pcfg_input = "/pinctrl/pcfg-input"; + i2c0_xfer = "/pinctrl/i2c0/i2c0-xfer"; + i2c1_xfer = "/pinctrl/i2c1/i2c1-xfer"; + i2c2_xfer = "/pinctrl/i2c2/i2c2-xfer"; + i2c3_xfer = "/pinctrl/i2c3/i2c3-xfer"; + tsadc_otp_gpio = "/pinctrl/tsadc/tsadc-otp-gpio"; + tsadc_otp_out = "/pinctrl/tsadc/tsadc-otp-out"; + uart0_xfer = "/pinctrl/uart0/uart0-xfer"; + uart0_cts = "/pinctrl/uart0/uart0-cts"; + uart0_rts = "/pinctrl/uart0/uart0-rts"; + uart0_rts_gpio = "/pinctrl/uart0/uart0-rts-gpio"; + uart1_xfer = "/pinctrl/uart1/uart1-xfer"; + uart1_cts = "/pinctrl/uart1/uart1-cts"; + uart1_rts = "/pinctrl/uart1/uart1-rts"; + uart1_rts_gpio = "/pinctrl/uart1/uart1-rts-gpio"; + uart2m0_xfer = "/pinctrl/uart2-m0/uart2m0-xfer"; + uart2m1_xfer = "/pinctrl/uart2-m1/uart2m1-xfer"; + uart3m0_xfer = "/pinctrl/uart3-m0/uart3m0-xfer"; + uart3m0_cts = "/pinctrl/uart3-m0/uart3m0-cts"; + uart3m0_rts = "/pinctrl/uart3-m0/uart3m0-rts"; + uart3m0_rts_gpio = "/pinctrl/uart3-m0/uart3m0-rts-gpio"; + uart3m1_xfer = "/pinctrl/uart3-m1/uart3m1-xfer"; + uart3m1_cts = "/pinctrl/uart3-m1/uart3m1-cts"; + uart3m1_rts = "/pinctrl/uart3-m1/uart3m1-rts"; + uart3m1_rts_gpio = "/pinctrl/uart3-m1/uart3m1-rts-gpio"; + uart4_xfer = "/pinctrl/uart4/uart4-xfer"; + uart4_cts = "/pinctrl/uart4/uart4-cts"; + uart4_rts = "/pinctrl/uart4/uart4-rts"; + uart5_xfer = "/pinctrl/uart5/uart5-xfer"; + uart5_cts = "/pinctrl/uart5/uart5-cts"; + uart5_rts = "/pinctrl/uart5/uart5-rts"; + spi0_clk = "/pinctrl/spi0/spi0-clk"; + spi0_csn = "/pinctrl/spi0/spi0-csn"; + spi0_miso = "/pinctrl/spi0/spi0-miso"; + spi0_mosi = "/pinctrl/spi0/spi0-mosi"; + spi0_clk_hs = "/pinctrl/spi0/spi0-clk-hs"; + spi0_miso_hs = "/pinctrl/spi0/spi0-miso-hs"; + spi0_mosi_hs = "/pinctrl/spi0/spi0-mosi-hs"; + spi1_clk = "/pinctrl/spi1/spi1-clk"; + spi1_csn0 = "/pinctrl/spi1/spi1-csn0"; + spi1_csn1 = "/pinctrl/spi1/spi1-csn1"; + spi1_miso = "/pinctrl/spi1/spi1-miso"; + spi1_mosi = "/pinctrl/spi1/spi1-mosi"; + spi1_clk_hs = "/pinctrl/spi1/spi1-clk-hs"; + spi1_miso_hs = "/pinctrl/spi1/spi1-miso-hs"; + spi1_mosi_hs = "/pinctrl/spi1/spi1-mosi-hs"; + pdm_clk0m0 = "/pinctrl/pdm/pdm-clk0m0"; + pdm_clk0m1 = "/pinctrl/pdm/pdm-clk0m1"; + pdm_clk1 = "/pinctrl/pdm/pdm-clk1"; + pdm_sdi0m0 = "/pinctrl/pdm/pdm-sdi0m0"; + pdm_sdi0m1 = "/pinctrl/pdm/pdm-sdi0m1"; + pdm_sdi1 = "/pinctrl/pdm/pdm-sdi1"; + pdm_sdi2 = "/pinctrl/pdm/pdm-sdi2"; + pdm_sdi3 = "/pinctrl/pdm/pdm-sdi3"; + pdm_clk0m0_sleep = "/pinctrl/pdm/pdm-clk0m0-sleep"; + pdm_clk0m_sleep1 = "/pinctrl/pdm/pdm-clk0m1-sleep"; + pdm_clk1_sleep = "/pinctrl/pdm/pdm-clk1-sleep"; + pdm_sdi0m0_sleep = "/pinctrl/pdm/pdm-sdi0m0-sleep"; + pdm_sdi0m1_sleep = "/pinctrl/pdm/pdm-sdi0m1-sleep"; + pdm_sdi1_sleep = "/pinctrl/pdm/pdm-sdi1-sleep"; + pdm_sdi2_sleep = "/pinctrl/pdm/pdm-sdi2-sleep"; + pdm_sdi3_sleep = "/pinctrl/pdm/pdm-sdi3-sleep"; + i2s0_8ch_mclk = "/pinctrl/i2s0/i2s0-8ch-mclk"; + i2s0_8ch_sclktx = "/pinctrl/i2s0/i2s0-8ch-sclktx"; + i2s0_8ch_sclkrx = "/pinctrl/i2s0/i2s0-8ch-sclkrx"; + i2s0_8ch_lrcktx = "/pinctrl/i2s0/i2s0-8ch-lrcktx"; + i2s0_8ch_lrckrx = "/pinctrl/i2s0/i2s0-8ch-lrckrx"; + i2s0_8ch_sdo0 = "/pinctrl/i2s0/i2s0-8ch-sdo0"; + i2s0_8ch_sdo1 = "/pinctrl/i2s0/i2s0-8ch-sdo1"; + i2s0_8ch_sdo2 = "/pinctrl/i2s0/i2s0-8ch-sdo2"; + i2s0_8ch_sdo3 = "/pinctrl/i2s0/i2s0-8ch-sdo3"; + i2s0_8ch_sdi0 = "/pinctrl/i2s0/i2s0-8ch-sdi0"; + i2s0_8ch_sdi1 = "/pinctrl/i2s0/i2s0-8ch-sdi1"; + i2s0_8ch_sdi2 = "/pinctrl/i2s0/i2s0-8ch-sdi2"; + i2s0_8ch_sdi3 = "/pinctrl/i2s0/i2s0-8ch-sdi3"; + i2s1_2ch_mclk = "/pinctrl/i2s1/i2s1-2ch-mclk"; + i2s1_2ch_sclk = "/pinctrl/i2s1/i2s1-2ch-sclk"; + i2s1_2ch_lrck = "/pinctrl/i2s1/i2s1-2ch-lrck"; + i2s1_2ch_sdi = "/pinctrl/i2s1/i2s1-2ch-sdi"; + i2s1_2ch_sdo = "/pinctrl/i2s1/i2s1-2ch-sdo"; + i2s2_2ch_mclk = "/pinctrl/i2s2/i2s2-2ch-mclk"; + i2s2_2ch_sclk = "/pinctrl/i2s2/i2s2-2ch-sclk"; + i2s2_2ch_lrck = "/pinctrl/i2s2/i2s2-2ch-lrck"; + i2s2_2ch_sdi = "/pinctrl/i2s2/i2s2-2ch-sdi"; + i2s2_2ch_sdo = "/pinctrl/i2s2/i2s2-2ch-sdo"; + sdmmc_clk = "/pinctrl/sdmmc/sdmmc-clk"; + sdmmc_cmd = "/pinctrl/sdmmc/sdmmc-cmd"; + sdmmc_det = "/pinctrl/sdmmc/sdmmc-det"; + sdmmc_bus1 = "/pinctrl/sdmmc/sdmmc-bus1"; + sdmmc_bus4 = "/pinctrl/sdmmc/sdmmc-bus4"; + sdmmc_gpio = "/pinctrl/sdmmc/sdmmc-gpio"; + sdio_clk = "/pinctrl/sdio/sdio-clk"; + sdio_cmd = "/pinctrl/sdio/sdio-cmd"; + sdio_bus4 = "/pinctrl/sdio/sdio-bus4"; + sdio_gpio = "/pinctrl/sdio/sdio-gpio"; + emmc_clk = "/pinctrl/emmc/emmc-clk"; + emmc_cmd = "/pinctrl/emmc/emmc-cmd"; + emmc_pwren = "/pinctrl/emmc/emmc-pwren"; + emmc_rstnout = "/pinctrl/emmc/emmc-rstnout"; + emmc_bus1 = "/pinctrl/emmc/emmc-bus1"; + emmc_bus4 = "/pinctrl/emmc/emmc-bus4"; + emmc_bus8 = "/pinctrl/emmc/emmc-bus8"; + flash_cs0 = "/pinctrl/flash/flash-cs0"; + flash_rdy = "/pinctrl/flash/flash-rdy"; + flash_dqs = "/pinctrl/flash/flash-dqs"; + flash_ale = "/pinctrl/flash/flash-ale"; + flash_cle = "/pinctrl/flash/flash-cle"; + flash_wrn = "/pinctrl/flash/flash-wrn"; + flash_csl = "/pinctrl/flash/flash-csl"; + flash_rdn = "/pinctrl/flash/flash-rdn"; + flash_bus8 = "/pinctrl/flash/flash-bus8"; + lcdc_m0_rgb_pins = "/pinctrl/lcdc/lcdc-m0-rgb-pins"; + lcdc_m0_sleep_pins = "/pinctrl/lcdc/lcdc-m0-sleep-pins"; + lcdc_m1_rgb_pins = "/pinctrl/lcdc/lcdc-m1-rgb-pins"; + lcdc_m1_sleep_pins = "/pinctrl/lcdc/lcdc-m1-sleep-pins"; + pwm0_pin = "/pinctrl/pwm0/pwm0-pin"; + pwm1_pin = "/pinctrl/pwm1/pwm1-pin"; + pwm2_pin = "/pinctrl/pwm2/pwm2-pin"; + pwm3_pin = "/pinctrl/pwm3/pwm3-pin"; + pwm4_pin = "/pinctrl/pwm4/pwm4-pin"; + pwm5_pin = "/pinctrl/pwm5/pwm5-pin"; + pwm6_pin = "/pinctrl/pwm6/pwm6-pin"; + pwm7_pin = "/pinctrl/pwm7/pwm7-pin"; + rmii_pins = "/pinctrl/gmac/rmii-pins"; + mac_refclk_12ma = "/pinctrl/gmac/mac-refclk-12ma"; + mac_refclk = "/pinctrl/gmac/mac-refclk"; + cif_clkout_m0 = "/pinctrl/cif-m0/cif-clkout-m0"; + dvp_d2d9_m0 = "/pinctrl/cif-m0/dvp-d2d9-m0"; + dvp_d0d1_m0 = "/pinctrl/cif-m0/dvp-d0d1-m0"; + dvp_d10d11_m0 = "/pinctrl/cif-m0/d10-d11-m0"; + cif_clkout_m1 = "/pinctrl/cif-m1/cif-clkout-m1"; + dvp_d2d9_m1 = "/pinctrl/cif-m1/dvp-d2d9-m1"; + dvp_d0d1_m1 = "/pinctrl/cif-m1/dvp-d0d1-m1"; + dvp_d10d11_m1 = "/pinctrl/cif-m1/d10-d11-m1"; + isp_prelight = "/pinctrl/isp/isp-prelight"; + pmic_int = "/pinctrl/pmic/pmic_int"; + soc_slppin_gpio = "/pinctrl/pmic/soc_slppin_gpio"; + soc_slppin_slp = "/pinctrl/pmic/soc_slppin_slp"; + soc_slppin_rst = "/pinctrl/pmic/soc_slppin_rst"; + led_pins = "/pinctrl/leds/led-pins"; + btn_pins = "/pinctrl/btns/btn-pins"; + drm_logo = "/reserved-memory/drm-logo@00000000"; + ramoops_mem = "/reserved-memory/region@110000"; + gpio_keys = "/odroidgo3-keys"; + joypad = "/odroidgo3-joypad"; + leds = "/gpio_leds"; + backlight = "/backlight"; + vccsys = "/vccsys"; + }; +}; diff --git a/config/archr-dts/R36S-DTB/DTS/Panel5.dts b/config/archr-dts/R36S-DTB/DTS/Panel5.dts new file mode 100644 index 0000000000..6d5b540b37 --- /dev/null +++ b/config/archr-dts/R36S-DTB/DTS/Panel5.dts @@ -0,0 +1,4079 @@ +/dts-v1/; + +/ { + compatible = "rockchip,rk3326-odroidgo3-linux\0rockchip,rk3326"; + interrupt-parent = <0x01>; + #address-cells = <0x02>; + #size-cells = <0x02>; + model = "Rockchip RK3326"; + + ddr_timing { + compatible = "rockchip,ddr-timing"; + ddr2_speed_bin = <0x00>; + ddr3_speed_bin = <0x15>; + ddr4_speed_bin = <0x0c>; + pd_idle = <0x0d>; + sr_idle = <0x5d>; + sr_mc_gate_idle = <0x00>; + srpd_lite_idle = <0x00>; + standby_idle = <0x00>; + auto_pd_dis_freq = <0x42a>; + auto_sr_dis_freq = <0x320>; + ddr2_dll_dis_freq = <0x12c>; + ddr3_dll_dis_freq = <0x12c>; + ddr4_dll_dis_freq = <0x271>; + phy_dll_dis_freq = <0x190>; + ddr2_odt_dis_freq = <0x64>; + phy_ddr2_odt_dis_freq = <0x64>; + ddr2_drv = <0x01>; + ddr2_odt = <0x96>; + phy_ddr2_ca_drv = <0x15>; + phy_ddr2_ck_drv = <0x12>; + phy_ddr2_dq_drv = <0x15>; + phy_ddr2_odt = <0x02>; + ddr3_odt_dis_freq = <0x190>; + phy_ddr3_odt_dis_freq = <0x190>; + ddr3_drv = <0x28>; + ddr3_odt = <0x78>; + phy_ddr3_ca_drv = <0x15>; + phy_ddr3_ck_drv = <0x12>; + phy_ddr3_dq_drv = <0x15>; + phy_ddr3_odt = <0x02>; + phy_lpddr2_odt_dis_freq = <0x29a>; + lpddr2_drv = <0x28>; + phy_lpddr2_ca_drv = <0x16>; + phy_lpddr2_ck_drv = <0x13>; + phy_lpddr2_dq_drv = <0x16>; + phy_lpddr2_odt = <0x00>; + lpddr3_odt_dis_freq = <0x190>; + phy_lpddr3_odt_dis_freq = <0x190>; + lpddr3_drv = <0x28>; + lpddr3_odt = <0xf0>; + phy_lpddr3_ca_drv = <0x16>; + phy_lpddr3_ck_drv = <0x13>; + phy_lpddr3_dq_drv = <0x16>; + phy_lpddr3_odt = <0x02>; + lpddr4_odt_dis_freq = <0x320>; + phy_lpddr4_odt_dis_freq = <0x320>; + lpddr4_drv = <0x3c>; + lpddr4_dq_odt = <0x28>; + lpddr4_ca_odt = <0x28>; + phy_lpddr4_ca_drv = <0x14>; + phy_lpddr4_ck_cs_drv = <0x06>; + phy_lpddr4_dq_drv = <0x06>; + phy_lpddr4_odt = <0x10>; + ddr4_odt_dis_freq = <0x29a>; + phy_ddr4_odt_dis_freq = <0x29a>; + ddr4_drv = <0x22>; + ddr4_odt = <0xf0>; + phy_ddr4_ca_drv = <0x16>; + phy_ddr4_ck_drv = <0x13>; + phy_ddr4_dq_drv = <0x16>; + phy_ddr4_odt = <0x02>; + ddr3a1_ddr4a9_de-skew = <0x06>; + ddr3a0_ddr4a10_de-skew = <0x07>; + ddr3a3_ddr4a6_de-skew = <0x07>; + ddr3a2_ddr4a4_de-skew = <0x07>; + ddr3a5_ddr4a8_de-skew = <0x07>; + ddr3a4_ddr4a5_de-skew = <0x07>; + ddr3a7_ddr4a11_de-skew = <0x07>; + ddr3a6_ddr4a7_de-skew = <0x06>; + ddr3a9_ddr4a0_de-skew = <0x07>; + ddr3a8_ddr4a13_de-skew = <0x07>; + ddr3a11_ddr4a3_de-skew = <0x07>; + ddr3a10_ddr4cs0_de-skew = <0x07>; + ddr3a13_ddr4a2_de-skew = <0x07>; + ddr3a12_ddr4ba1_de-skew = <0x07>; + ddr3a15_ddr4odt0_de-skew = <0x07>; + ddr3a14_ddr4a1_de-skew = <0x07>; + ddr3ba1_ddr4a15_de-skew = <0x07>; + ddr3ba0_ddr4bg0_de-skew = <0x07>; + ddr3ras_ddr4cke_de-skew = <0x07>; + ddr3ba2_ddr4ba0_de-skew = <0x07>; + ddr3we_ddr4bg1_de-skew = <0x07>; + ddr3cas_ddr4a12_de-skew = <0x07>; + ddr3ckn_ddr4ckn_de-skew = <0x07>; + ddr3ckp_ddr4ckp_de-skew = <0x07>; + ddr3cke_ddr4a16_de-skew = <0x07>; + ddr3odt0_ddr4a14_de-skew = <0x07>; + ddr3cs0_ddr4act_de-skew = <0x06>; + ddr3reset_ddr4reset_de-skew = <0x07>; + ddr3cs1_ddr4cs1_de-skew = <0x06>; + ddr3odt1_ddr4odt1_de-skew = <0x07>; + cs0_dm0_rx_de-skew = <0x07>; + cs0_dm0_tx_de-skew = <0x07>; + cs0_dq0_rx_de-skew = <0x08>; + cs0_dq0_tx_de-skew = <0x08>; + cs0_dq1_rx_de-skew = <0x09>; + cs0_dq1_tx_de-skew = <0x08>; + cs0_dq2_rx_de-skew = <0x08>; + cs0_dq2_tx_de-skew = <0x08>; + cs0_dq3_rx_de-skew = <0x08>; + cs0_dq3_tx_de-skew = <0x08>; + cs0_dq4_rx_de-skew = <0x09>; + cs0_dq4_tx_de-skew = <0x08>; + cs0_dq5_rx_de-skew = <0x09>; + cs0_dq5_tx_de-skew = <0x08>; + cs0_dq6_rx_de-skew = <0x09>; + cs0_dq6_tx_de-skew = <0x08>; + cs0_dq7_rx_de-skew = <0x08>; + cs0_dq7_tx_de-skew = <0x08>; + cs0_dqs0_rx_de-skew = <0x06>; + cs0_dqs0p_tx_de-skew = <0x09>; + cs0_dqs0n_tx_de-skew = <0x09>; + cs0_dm1_rx_de-skew = <0x07>; + cs0_dm1_tx_de-skew = <0x06>; + cs0_dq8_rx_de-skew = <0x08>; + cs0_dq8_tx_de-skew = <0x07>; + cs0_dq9_rx_de-skew = <0x09>; + cs0_dq9_tx_de-skew = <0x07>; + cs0_dq10_rx_de-skew = <0x08>; + cs0_dq10_tx_de-skew = <0x08>; + cs0_dq11_rx_de-skew = <0x08>; + cs0_dq11_tx_de-skew = <0x07>; + cs0_dq12_rx_de-skew = <0x08>; + cs0_dq12_tx_de-skew = <0x08>; + cs0_dq13_rx_de-skew = <0x09>; + cs0_dq13_tx_de-skew = <0x07>; + cs0_dq14_rx_de-skew = <0x09>; + cs0_dq14_tx_de-skew = <0x08>; + cs0_dq15_rx_de-skew = <0x09>; + cs0_dq15_tx_de-skew = <0x07>; + cs0_dqs1_rx_de-skew = <0x07>; + cs0_dqs1p_tx_de-skew = <0x09>; + cs0_dqs1n_tx_de-skew = <0x09>; + cs0_dm2_rx_de-skew = <0x07>; + cs0_dm2_tx_de-skew = <0x07>; + cs0_dq16_rx_de-skew = <0x09>; + cs0_dq16_tx_de-skew = <0x09>; + cs0_dq17_rx_de-skew = <0x07>; + cs0_dq17_tx_de-skew = <0x09>; + cs0_dq18_rx_de-skew = <0x07>; + cs0_dq18_tx_de-skew = <0x08>; + cs0_dq19_rx_de-skew = <0x07>; + cs0_dq19_tx_de-skew = <0x09>; + cs0_dq20_rx_de-skew = <0x09>; + cs0_dq20_tx_de-skew = <0x09>; + cs0_dq21_rx_de-skew = <0x09>; + cs0_dq21_tx_de-skew = <0x09>; + cs0_dq22_rx_de-skew = <0x08>; + cs0_dq22_tx_de-skew = <0x09>; + cs0_dq23_rx_de-skew = <0x08>; + cs0_dq23_tx_de-skew = <0x09>; + cs0_dqs2_rx_de-skew = <0x06>; + cs0_dqs2p_tx_de-skew = <0x09>; + cs0_dqs2n_tx_de-skew = <0x09>; + cs0_dm3_rx_de-skew = <0x07>; + cs0_dm3_tx_de-skew = <0x07>; + cs0_dq24_rx_de-skew = <0x08>; + cs0_dq24_tx_de-skew = <0x08>; + cs0_dq25_rx_de-skew = <0x09>; + cs0_dq25_tx_de-skew = <0x09>; + cs0_dq26_rx_de-skew = <0x09>; + cs0_dq26_tx_de-skew = <0x08>; + cs0_dq27_rx_de-skew = <0x09>; + cs0_dq27_tx_de-skew = <0x08>; + cs0_dq28_rx_de-skew = <0x09>; + cs0_dq28_tx_de-skew = <0x09>; + cs0_dq29_rx_de-skew = <0x09>; + cs0_dq29_tx_de-skew = <0x09>; + cs0_dq30_rx_de-skew = <0x08>; + cs0_dq30_tx_de-skew = <0x08>; + cs0_dq31_rx_de-skew = <0x08>; + cs0_dq31_tx_de-skew = <0x08>; + cs0_dqs3_rx_de-skew = <0x07>; + cs0_dqs3p_tx_de-skew = <0x09>; + cs0_dqs3n_tx_de-skew = <0x09>; + cs1_dm0_rx_de-skew = <0x07>; + cs1_dm0_tx_de-skew = <0x07>; + cs1_dq0_rx_de-skew = <0x08>; + cs1_dq0_tx_de-skew = <0x08>; + cs1_dq1_rx_de-skew = <0x09>; + cs1_dq1_tx_de-skew = <0x08>; + cs1_dq2_rx_de-skew = <0x08>; + cs1_dq2_tx_de-skew = <0x08>; + cs1_dq3_rx_de-skew = <0x08>; + cs1_dq3_tx_de-skew = <0x08>; + cs1_dq4_rx_de-skew = <0x08>; + cs1_dq4_tx_de-skew = <0x08>; + cs1_dq5_rx_de-skew = <0x09>; + cs1_dq5_tx_de-skew = <0x08>; + cs1_dq6_rx_de-skew = <0x09>; + cs1_dq6_tx_de-skew = <0x08>; + cs1_dq7_rx_de-skew = <0x08>; + cs1_dq7_tx_de-skew = <0x08>; + cs1_dqs0_rx_de-skew = <0x06>; + cs1_dqs0p_tx_de-skew = <0x09>; + cs1_dqs0n_tx_de-skew = <0x09>; + cs1_dm1_rx_de-skew = <0x07>; + cs1_dm1_tx_de-skew = <0x07>; + cs1_dq8_rx_de-skew = <0x08>; + cs1_dq8_tx_de-skew = <0x08>; + cs1_dq9_rx_de-skew = <0x08>; + cs1_dq9_tx_de-skew = <0x07>; + cs1_dq10_rx_de-skew = <0x07>; + cs1_dq10_tx_de-skew = <0x08>; + cs1_dq11_rx_de-skew = <0x08>; + cs1_dq11_tx_de-skew = <0x08>; + cs1_dq12_rx_de-skew = <0x08>; + cs1_dq12_tx_de-skew = <0x07>; + cs1_dq13_rx_de-skew = <0x08>; + cs1_dq13_tx_de-skew = <0x08>; + cs1_dq14_rx_de-skew = <0x08>; + cs1_dq14_tx_de-skew = <0x08>; + cs1_dq15_rx_de-skew = <0x08>; + cs1_dq15_tx_de-skew = <0x07>; + cs1_dqs1_rx_de-skew = <0x07>; + cs1_dqs1p_tx_de-skew = <0x09>; + cs1_dqs1n_tx_de-skew = <0x09>; + cs1_dm2_rx_de-skew = <0x07>; + cs1_dm2_tx_de-skew = <0x08>; + cs1_dq16_rx_de-skew = <0x08>; + cs1_dq16_tx_de-skew = <0x09>; + cs1_dq17_rx_de-skew = <0x08>; + cs1_dq17_tx_de-skew = <0x09>; + cs1_dq18_rx_de-skew = <0x07>; + cs1_dq18_tx_de-skew = <0x08>; + cs1_dq19_rx_de-skew = <0x08>; + cs1_dq19_tx_de-skew = <0x09>; + cs1_dq20_rx_de-skew = <0x09>; + cs1_dq20_tx_de-skew = <0x09>; + cs1_dq21_rx_de-skew = <0x09>; + cs1_dq21_tx_de-skew = <0x09>; + cs1_dq22_rx_de-skew = <0x08>; + cs1_dq22_tx_de-skew = <0x09>; + cs1_dq23_rx_de-skew = <0x08>; + cs1_dq23_tx_de-skew = <0x09>; + cs1_dqs2_rx_de-skew = <0x06>; + cs1_dqs2p_tx_de-skew = <0x09>; + cs1_dqs2n_tx_de-skew = <0x09>; + cs1_dm3_rx_de-skew = <0x07>; + cs1_dm3_tx_de-skew = <0x07>; + cs1_dq24_rx_de-skew = <0x08>; + cs1_dq24_tx_de-skew = <0x09>; + cs1_dq25_rx_de-skew = <0x09>; + cs1_dq25_tx_de-skew = <0x09>; + cs1_dq26_rx_de-skew = <0x09>; + cs1_dq26_tx_de-skew = <0x08>; + cs1_dq27_rx_de-skew = <0x08>; + cs1_dq27_tx_de-skew = <0x08>; + cs1_dq28_rx_de-skew = <0x09>; + cs1_dq28_tx_de-skew = <0x09>; + cs1_dq29_rx_de-skew = <0x09>; + cs1_dq29_tx_de-skew = <0x09>; + cs1_dq30_rx_de-skew = <0x09>; + cs1_dq30_tx_de-skew = <0x08>; + cs1_dq31_rx_de-skew = <0x08>; + cs1_dq31_tx_de-skew = <0x08>; + cs1_dqs3_rx_de-skew = <0x07>; + cs1_dqs3p_tx_de-skew = <0x09>; + cs1_dqs3n_tx_de-skew = <0x09>; + phandle = <0xab>; + }; + + aliases { + ethernet0 = "/ethernet@ff360000"; + i2c0 = "/i2c@ff180000"; + i2c1 = "/i2c@ff190000"; + i2c2 = "/i2c@ff1a0000"; + i2c3 = "/i2c@ff1b0000"; + serial0 = "/serial@ff030000"; + serial1 = "/serial@ff158000"; + serial2 = "/serial@ff160000"; + serial3 = "/serial@ff168000"; + serial4 = "/serial@ff170000"; + serial5 = "/serial@ff178000"; + spi0 = "/spi@ff1d0000"; + spi1 = "/spi@ff1d8000"; + }; + + cpus { + #address-cells = <0x02>; + #size-cells = <0x00>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x00>; + enable-method = "psci"; + clocks = <0x02 0x07>; + #cooling-cells = <0x02>; + dynamic-power-coefficient = <0x5a>; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + cpu-supply = <0x06>; + phandle = <0x09>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x01>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0a>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x02>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0b>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x03>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0c>; + }; + + idle-states { + entry-method = "psci"; + + cpu-sleep { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x10000>; + entry-latency-us = <0x78>; + exit-latency-us = <0xfa>; + min-residency-us = <0x384>; + phandle = <0x04>; + }; + + cluster-sleep { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x1010000>; + entry-latency-us = <0x190>; + exit-latency-us = <0x1f4>; + min-residency-us = <0x7d0>; + phandle = <0x05>; + }; + }; + }; + + cpu0-opp-table { + compatible = "operating-points-v2"; + opp-shared; + rockchip,temp-hysteresis = <0x1388>; + rockchip,low-temp = <0x00>; + rockchip,low-temp-min-volt = <0xf4240>; + rockchip,low-temp-adjust-volt = <0x00 0x5e8 0xc350>; + clocks = <0x02 0x01>; + rockchip,avs-scale = <0x04>; + rockchip,max-volt = <0x149970>; + rockchip,evb-irdrop = <0x61a8>; + nvmem-cells = <0x07 0x08>; + nvmem-cell-names = "cpu_leakage\0performance"; + rockchip,bin-scaling-sel = <0x00 0x0d 0x01 0x0d>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-freq = <0x639c0>; + rockchip,pvtm-volt = <0xf4240>; + rockchip,pvtm-ch = <0x00 0x00>; + rockchip,pvtm-sample-time = <0x3e8>; + rockchip,pvtm-number = <0x0a>; + rockchip,pvtm-error = <0x3e8>; + rockchip,pvtm-ref-temp = <0x28>; + rockchip,pvtm-temp-prop = <0xffffffc8 0xffffffc8>; + rockchip,thermal-zone = "soc-thermal"; + rockchip,avs = <0x01>; + phandle = <0x03>; + + opp-1008000000 { + opp-hz = <0x00 0x3c14dc00>; + opp-microvolt = <0x11edd8 0x11edd8 0x149970>; + opp-microvolt-L0 = <0x11edd8 0x11edd8 0x149970>; + opp-microvolt-L1 = <0x112a88 0x112a88 0x149970>; + opp-microvolt-L2 = <0x112a88 0x112a88 0x149970>; + opp-microvolt-L3 = <0x100590 0x100590 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1200000000 { + opp-hz = <0x00 0x47868c00>; + opp-microvolt = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L0 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L1 = <0x137478 0x137478 0x149970>; + opp-microvolt-L2 = <0x1312d0 0x1312d0 0x149970>; + opp-microvolt-L3 = <0x124f80 0x124f80 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1248000000 { + opp-hz = <0x00 0x4a62f800>; + opp-microvolt = <0x149970 0x149970 0x149970>; + opp-microvolt-L0 = <0x149970 0x149970 0x149970>; + opp-microvolt-L1 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L2 = <0x137478 0x137478 0x149970>; + opp-microvolt-L3 = <0x12b128 0x12b128 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1296000000 { + opp-hz = <0x00 0x4d3f6400>; + opp-microvolt = <0x149970 0x149970 0x149970>; + opp-microvolt-L0 = <0x149970 0x149970 0x149970>; + opp-microvolt-L1 = <0x149970 0x149970 0x149970>; + opp-microvolt-L2 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L3 = <0x1312d0 0x1312d0 0x149970>; + clock-latency-ns = <0x9c40>; + }; + }; + + arm-pmu { + compatible = "arm,cortex-a53-pmu"; + interrupts = <0x00 0x64 0x04 0x00 0x65 0x04 0x00 0x66 0x04 0x00 0x67 0x04>; + interrupt-affinity = <0x09 0x0a 0x0b 0x0c>; + }; + + bus-soc { + compatible = "rockchip,px30-bus"; + rockchip,busfreq-policy = "autocs"; + phandle = <0xc1>; + + soc-bus0 { + bus-id = <0x00>; + timer-us = <0x14>; + enable-msk = <0x40f7>; + status = "disabled"; + }; + + soc-bus1 { + bus-id = <0x01>; + timer-us = <0xc8>; + enable-msk = <0x40bf>; + status = "disabled"; + }; + + soc-bus2 { + bus-id = <0x02>; + timer-us = <0xc8>; + enable-msk = <0x4007>; + status = "disabled"; + }; + }; + + bus-apll { + compatible = "rockchip,px30-bus"; + rockchip,busfreq-policy = "clkfreq"; + clocks = <0x02 0x01>; + clock-names = "bus"; + operating-points-v2 = <0x0d>; + status = "okay"; + bus-supply = <0x0e>; + phandle = <0xc2>; + }; + + bus-apll-opp-table { + compatible = "operating-points-v2"; + opp-shared; + phandle = <0x0d>; + + opp-1512000000 { + opp-hz = <0x00 0x5a1f4a00>; + opp-microvolt = <0xf4240>; + }; + + opp-1008000000 { + opp-hz = <0x00 0x3c14dc00>; + opp-microvolt = <0xe7ef0>; + }; + }; + + cpuinfo { + compatible = "rockchip,cpuinfo"; + nvmem-cells = <0x0f>; + nvmem-cell-names = "id"; + }; + + display-subsystem { + compatible = "rockchip,display-subsystem"; + ports = <0x10>; + status = "okay"; + logo-memory-region = <0x11>; + phandle = <0xc3>; + + route { + + route-lvds { + status = "disabled"; + logo,uboot = "logo.bmp"; + logo,kernel = "logo_kernel.bmp"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x12>; + phandle = <0xc4>; + }; + + route-dsi { + status = "okay"; + logo,uboot = "logo.bmp"; + logo,kernel = "logo_kernel.bmp"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x13>; + phandle = <0xc5>; + }; + + route-rgb { + status = "disabled"; + logo,uboot = "logo.bmp"; + logo,kernel = "logo_kernel.bmp"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x14>; + phandle = <0xc6>; + }; + }; + }; + + firmware { + + optee { + compatible = "linaro,optee-tz"; + method = "smc"; + }; + }; + + external-gmac-clock { + compatible = "fixed-clock"; + clock-frequency = <0x2faf080>; + clock-output-names = "gmac_clkin"; + #clock-cells = <0x00>; + phandle = <0xc7>; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + rockchip-suspend { + compatible = "rockchip,pm-px30"; + status = "okay"; + rockchip,sleep-debug-en = <0x01>; + rockchip,sleep-mode-config = <0x20702>; + rockchip,wakeup-config = <0x85>; + phandle = <0xc8>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <0x01 0x0d 0xf04 0x01 0x0e 0xf04 0x01 0x0b 0xf04 0x01 0x0a 0xf04>; + }; + + xin24m { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x16e3600>; + clock-output-names = "xin24m"; + phandle = <0xc9>; + }; + + xin32k { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x8000>; + clock-output-names = "xin32k"; + phandle = <0xca>; + }; + + power-management@ff000000 { + compatible = "rockchip,px30-pmu\0syscon\0simple-mfd"; + reg = <0x00 0xff000000 0x00 0x1000>; + phandle = <0xcb>; + + power-controller { + compatible = "rockchip,px30-power-controller"; + #power-domain-cells = <0x01>; + #address-cells = <0x01>; + #size-cells = <0x00>; + phandle = <0x87>; + + pd_usb@5 { + reg = <0x05>; + clocks = <0x02 0x103 0x02 0x102 0x02 0x3c>; + pm_qos = <0x15 0x16>; + }; + + pd_sdcard@7 { + reg = <0x07>; + clocks = <0x02 0xf7 0x02 0x3b>; + pm_qos = <0x17>; + }; + + pd_gmac@9 { + reg = <0x09>; + clocks = <0x02 0xb2 0x02 0x143 0x02 0x40 0x02 0x3f>; + pm_qos = <0x18>; + }; + + pd_mmc_nand@10 { + reg = <0x0a>; + clocks = <0x02 0xfe 0x02 0x100 0x02 0xff 0x02 0x101 0x02 0x39 0x02 0x37 0x02 0x38 0x02 0x3a>; + pm_qos = <0x19 0x1a 0x1b 0x1c>; + }; + + pd_vpu@11 { + reg = <0x0b>; + clocks = <0x02 0xaf 0x02 0xf4 0x02 0x4b>; + pm_qos = <0x1d 0x1e>; + }; + + pd_vo@12 { + reg = <0x0c>; + clocks = <0x02 0xb7 0x02 0xb5 0x02 0xb6 0x02 0x96 0x02 0x97 0x02 0xfd 0x02 0xfb 0x02 0xfc 0x02 0x144 0x02 0x35 0x02 0x36>; + pm_qos = <0x1f 0x20 0x21 0x22>; + }; + + pd_vi@13 { + reg = <0x0d>; + clocks = <0x02 0xb3 0x02 0xb4 0x02 0xf9 0x02 0xfa 0x02 0x33>; + pm_qos = <0x23 0x24 0x25 0x26 0x27>; + }; + + pd_gpu@14 { + reg = <0x0e>; + clocks = <0x02 0x49>; + pm_qos = <0x28>; + }; + }; + }; + + syscon@ff010000 { + compatible = "rockchip,px30-pmugrf\0syscon\0simple-mfd"; + reg = <0x00 0xff010000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0xa8>; + + io-domains { + compatible = "rockchip,px30-pmu-io-voltage-domain"; + status = "okay"; + pmuio1-supply = <0x29>; + pmuio2-supply = <0x29>; + phandle = <0xcc>; + }; + + reboot-mode { + compatible = "syscon-reboot-mode"; + offset = <0x200>; + mode-bootloader = <0x5242c301>; + mode-charge = <0x5242c30b>; + mode-fastboot = <0x5242c309>; + mode-loader = <0x5242c301>; + mode-normal = <0x5242c300>; + mode-recovery = <0x5242c303>; + mode-ums = <0x5242c30c>; + }; + + pmu-pvtm { + compatible = "rockchip,px30-pmu-pvtm"; + clocks = <0x2a 0x07>; + clock-names = "pmu"; + status = "okay"; + phandle = <0xcd>; + }; + }; + + serial@ff030000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff030000 0x00 0x100>; + interrupts = <0x00 0x0f 0x04>; + clocks = <0x2a 0x06 0x2a 0x15>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x00 0x2b 0x01>; + pinctrl-names = "default"; + pinctrl-0 = <0x2c 0x2d 0x2e>; + status = "disabled"; + phandle = <0xce>; + }; + + i2s@ff060000 { + compatible = "rockchip,px30-i2s-tdm"; + reg = <0x00 0xff060000 0x00 0x1000>; + interrupts = <0x00 0x0c 0x04>; + clocks = <0x02 0x10 0x02 0x12 0x02 0x106>; + clock-names = "mclk_tx\0mclk_rx\0hclk"; + dmas = <0x2b 0x10 0x2b 0x11>; + dma-names = "tx\0rx"; + resets = <0x02 0x84 0x02 0xbf>; + reset-names = "tx-m\0rx-m"; + rockchip,cru = <0x02>; + rockchip,grf = <0x2f>; + pinctrl-names = "default"; + pinctrl-0 = <0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x3a 0x3b>; + status = "disabled"; + phandle = <0xcf>; + }; + + i2s@ff070000 { + compatible = "rockchip,px30-i2s\0rockchip,rk3066-i2s"; + reg = <0x00 0xff070000 0x00 0x1000>; + interrupts = <0x00 0x0d 0x04>; + clocks = <0x02 0x14 0x02 0x107>; + clock-names = "i2s_clk\0i2s_hclk"; + dmas = <0x2b 0x12 0x2b 0x13>; + dma-names = "tx\0rx"; + resets = <0x02 0x86 0x02 0x85>; + reset-names = "reset-m\0reset-h"; + pinctrl-names = "default"; + pinctrl-0 = <0x3c 0x3d 0x3e 0x3f>; + status = "okay"; + #sound-dai-cells = <0x00>; + phandle = <0xbd>; + }; + + i2s@ff080000 { + compatible = "rockchip,px30-i2s\0rockchip,rk3066-i2s"; + reg = <0x00 0xff080000 0x00 0x1000>; + interrupts = <0x00 0x0e 0x04>; + clocks = <0x02 0x16 0x02 0x108>; + clock-names = "i2s_clk\0i2s_hclk"; + dmas = <0x2b 0x14 0x2b 0x15>; + dma-names = "tx\0rx"; + resets = <0x02 0x88 0x02 0x87>; + reset-names = "reset-m\0reset-h"; + pinctrl-names = "default"; + pinctrl-0 = <0x40 0x41 0x42 0x43>; + status = "disabled"; + phandle = <0xd0>; + }; + + pdm@ff0a0000 { + compatible = "rockchip,px30-pdm\0rockchip,pdm"; + reg = <0x00 0xff0a0000 0x00 0x1000>; + clocks = <0x02 0x0f 0x02 0x105>; + clock-names = "pdm_clk\0pdm_hclk"; + dmas = <0x2b 0x18>; + dma-names = "rx"; + resets = <0x02 0x82>; + reset-names = "pdm-m"; + pinctrl-names = "default"; + pinctrl-0 = <0x44 0x45 0x46 0x47 0x48>; + status = "disabled"; + phandle = <0xd1>; + }; + + crypto@ff0b0000 { + compatible = "rockchip,px30-crypto"; + reg = <0x00 0xff0b0000 0x00 0x4000>; + interrupts = <0x00 0x52 0x04>; + clocks = <0x02 0xac 0x02 0xf1 0x02 0x30 0x02 0x31>; + clock-names = "aclk\0hclk\0sclk\0apb_pclk"; + resets = <0x02 0x74>; + reset-names = "crypto-rst"; + status = "disabled"; + phandle = <0xd2>; + }; + + rng@ff0b0000 { + compatible = "rockchip,cryptov2-rng"; + reg = <0x00 0xff0b0000 0x00 0x4000>; + clocks = <0x02 0x30 0x02 0x31 0x02 0xac 0x02 0xf1>; + clock-names = "clk_crypto\0clk_crypto_apk\0aclk_crypto\0hclk_crypto"; + assigned-clocks = <0x02 0x30 0x02 0x31 0x02 0xac 0x02 0xf1>; + assigned-clock-rates = <0x8f0d180 0x8f0d180 0xbebc200 0x5f5e100>; + resets = <0x02 0x74>; + reset-names = "reset"; + status = "okay"; + phandle = <0xd3>; + }; + + interrupt-controller@ff131000 { + compatible = "arm,gic-400"; + #interrupt-cells = <0x03>; + #address-cells = <0x00>; + interrupt-controller; + reg = <0x00 0xff131000 0x00 0x1000 0x00 0xff132000 0x00 0x2000 0x00 0xff134000 0x00 0x2000 0x00 0xff136000 0x00 0x2000>; + interrupts = <0x01 0x09 0xf04>; + phandle = <0x01>; + }; + + syscon@ff140000 { + compatible = "rockchip,px30-grf\0syscon\0simple-mfd"; + reg = <0x00 0xff140000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0x2f>; + + io-domains { + compatible = "rockchip,px30-io-voltage-domain"; + status = "okay"; + vccio1-supply = <0x49>; + vccio2-supply = <0x49>; + vccio3-supply = <0x4a>; + vccio4-supply = <0x4a>; + vccio5-supply = <0x4a>; + vccio6-supply = <0x4a>; + phandle = <0xd4>; + }; + + lvds { + compatible = "rockchip,px30-lvds"; + phys = <0x4b>; + phy-names = "phy"; + status = "disabled"; + phandle = <0xd5>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x12>; + phandle = <0x9e>; + }; + }; + }; + }; + + rgb { + compatible = "rockchip,px30-rgb"; + pinctrl-names = "default\0sleep"; + pinctrl-0 = <0x4c>; + pinctrl-1 = <0x4d>; + status = "disabled"; + phys = <0x4b>; + phy-names = "phy"; + phandle = <0xd6>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x14>; + phandle = <0xa0>; + }; + }; + }; + }; + }; + + syscon@ff148000 { + compatible = "syscon\0simple-mfd"; + reg = <0x00 0xff148000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0xd7>; + + pvtm { + compatible = "rockchip,px30-pvtm"; + clocks = <0x02 0x4a>; + clock-names = "core"; + status = "okay"; + phandle = <0xd8>; + }; + }; + + serial@ff158000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff158000 0x00 0x100>; + interrupts = <0x00 0x10 0x04>; + clocks = <0x02 0x18 0x02 0x149>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x02 0x2b 0x03>; + pinctrl-names = "default"; + status = "disabled"; + phandle = <0xd9>; + }; + + serial@ff160000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff160000 0x00 0x100>; + interrupts = <0x00 0x11 0x04>; + clocks = <0x02 0x19 0x02 0x14a>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x04 0x2b 0x05>; + pinctrl-names = "default"; + pinctrl-0 = <0x4e>; + status = "disabled"; + phandle = <0xda>; + }; + + serial@ff168000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff168000 0x00 0x100>; + interrupts = <0x00 0x12 0x04>; + clocks = <0x02 0x1a 0x02 0x14b>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x06 0x2b 0x07>; + pinctrl-names = "default"; + pinctrl-0 = <0x4f 0x50 0x51>; + status = "disabled"; + phandle = <0xdb>; + }; + + serial@ff170000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff170000 0x00 0x100>; + interrupts = <0x00 0x13 0x04>; + clocks = <0x02 0x1b 0x02 0x14c>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x08 0x2b 0x09>; + pinctrl-names = "default"; + pinctrl-0 = <0x52 0x53 0x54>; + status = "disabled"; + phandle = <0xdc>; + }; + + serial@ff178000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff178000 0x00 0x100>; + interrupts = <0x00 0x14 0x04>; + clocks = <0x02 0x1c 0x02 0x14d>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x0a 0x2b 0x0b>; + pinctrl-names = "default"; + pinctrl-0 = <0x55 0x56 0x57>; + status = "disabled"; + phandle = <0xdd>; + }; + + i2c@ff180000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff180000 0x00 0x1000>; + clocks = <0x02 0x1d 0x02 0x14e>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x07 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x58>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + clock-frequency = <0x61a80>; + i2c-scl-rising-time-ns = <0x118>; + i2c-scl-falling-time-ns = <0x10>; + phandle = <0xde>; + + pmic@20 { + compatible = "rockchip,rk817"; + reg = <0x20>; + interrupt-parent = <0x59>; + interrupts = <0x07 0x08>; + pinctrl-names = "default\0pmic-sleep\0pmic-power-off\0pmic-reset"; + pinctrl-0 = <0x5a>; + pinctrl-1 = <0x5b 0x5c>; + pinctrl-2 = <0x5d 0x5e>; + pinctrl-3 = <0x5f 0x60>; + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <0x01>; + clock-output-names = "rk808-clkout1\0rk808-clkout2"; + pmic-reset-func = <0x01>; + vcc1-supply = <0x61>; + vcc2-supply = <0x61>; + vcc3-supply = <0x61>; + vcc4-supply = <0x61>; + vcc5-supply = <0x61>; + vcc6-supply = <0x61>; + vcc7-supply = <0x61>; + vcc8-supply = <0x61>; + vcc9-supply = <0x62>; + phandle = <0xdf>; + + pwrkey { + status = "okay"; + }; + + pinctrl_rk8xx { + gpio-controller; + #gpio-cells = <0x02>; + phandle = <0xe0>; + + rk817_ts_gpio1 { + pins = "gpio_ts"; + function = "pin_fun1"; + phandle = <0xe1>; + }; + + rk817_gt_gpio2 { + pins = "gpio_gt"; + function = "pin_fun1"; + phandle = <0xe2>; + }; + + rk817_pin_ts { + pins = "gpio_ts"; + function = "pin_fun0"; + phandle = <0xe3>; + }; + + rk817_pin_gt { + pins = "gpio_gt"; + function = "pin_fun0"; + phandle = <0xe4>; + }; + + rk817_slppin_null { + pins = "gpio_slp"; + function = "pin_fun0"; + phandle = <0xe5>; + }; + + rk817_slppin_slp { + pins = "gpio_slp"; + function = "pin_fun1"; + phandle = <0x5c>; + }; + + rk817_slppin_pwrdn { + pins = "gpio_slp"; + function = "pin_fun2"; + phandle = <0x5e>; + }; + + rk817_slppin_rst { + pins = "gpio_slp"; + function = "pin_fun3"; + phandle = <0x60>; + }; + }; + + regulators { + + DCDC_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xe7ef0>; + regulator-max-microvolt = <0x149970>; + regulator-ramp-delay = <0x1771>; + regulator-initial-mode = <0x02>; + regulator-name = "vdd_logic"; + phandle = <0x0e>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0xe7ef0>; + }; + }; + + DCDC_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xe7ef0>; + regulator-max-microvolt = <0x149970>; + regulator-ramp-delay = <0x1771>; + regulator-initial-mode = <0x02>; + regulator-name = "vdd_arm"; + phandle = <0x06>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0xe7ef0>; + }; + }; + + DCDC_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x02>; + regulator-name = "vcc_ddr"; + phandle = <0xe6>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + DCDC_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-initial-mode = <0x02>; + regulator-name = "vcc_3v3"; + phandle = <0x4a>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + regulator-name = "vcc_1v0"; + phandle = <0xe7>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0xf4240>; + }; + }; + + LDO_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + regulator-name = "vcc1v8_soc"; + phandle = <0x85>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x1b7740>; + }; + }; + + LDO_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + regulator-name = "vcc1v0_soc"; + phandle = <0xe8>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0xf4240>; + }; + }; + + LDO_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x2dc6c0>; + regulator-max-microvolt = <0x2dc6c0>; + regulator-name = "vcc3v3_pmu"; + phandle = <0x29>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x2dc6c0>; + }; + }; + + LDO_REG5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "vccio_sd"; + phandle = <0x49>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG6 { + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "vcc_sd"; + phandle = <0x90>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG7 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "vcc2v8_dvp"; + phandle = <0xe9>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG8 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "vcc_lcd"; + phandle = <0x9a>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG9 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x10c8e0>; + regulator-max-microvolt = <0x10c8e0>; + regulator-name = "vdd_11"; + phandle = <0xea>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x10c8e0>; + }; + }; + + BOOST { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x47b760>; + regulator-max-microvolt = <0x5265c0>; + regulator-name = "boost"; + phandle = <0x62>; + }; + + OTG_SWITCH { + regulator-boot-on; + regulator-name = "otg_switch"; + phandle = <0xeb>; + }; + }; + + battery { + compatible = "rk817,battery"; + ocv_table = <0xd48 0xd6e 0xd9e 0xdc1 0xdde 0xdf3 0xe02 0xe0f 0xe1c 0xe2c 0xe47 0xe69 0xe87 0xeaa 0xed2 0xefe 0xf2f 0xf66 0xfa5 0xff7 0x1051>; + design_capacity = <0xc54>; + design_qmax = <0xd8f>; + bat_res = <0x84>; + sleep_enter_current = <0x12c>; + sleep_exit_current = <0x12c>; + sleep_filter_current = <0x64>; + power_off_thresd = <0xce4>; + zero_algorithm_vol = <0xf0a>; + max_soc_offset = <0x3c>; + monitor_sec = <0x05>; + virtual_power = <0x00>; + sample_res = <0x0a>; + }; + + charger { + compatible = "rk817,charger"; + min_input_voltage = <0x1194>; + max_input_current = <0x5dc>; + max_chrg_current = <0x7d0>; + max_chrg_voltage = <0x1068>; + chrg_term_mode = <0x00>; + chrg_finish_cur = <0x34>; + virtual_power = <0x00>; + sample_res = <0x0a>; + dc_det_gpio = <0x63 0x17 0x00>; + chg_led_gpio = <0x59 0x01 0x00>; + extcon = <0x64>; + }; + + codec { + #sound-dai-cells = <0x00>; + compatible = "rockchip,rk817-codec"; + clocks = <0x02 0x15>; + clock-names = "mclk"; + pinctrl-names = "default"; + pinctrl-0 = <0x65>; + spk-ctl-gpios = <0x63 0x14 0x00>; + hp-volume = <0x14>; + spk-volume = <0x01>; + status = "okay"; + phandle = <0xbe>; + }; + }; + }; + + i2c@ff190000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff190000 0x00 0x1000>; + clocks = <0x02 0x1e 0x02 0x14f>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x08 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x66>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + clock-frequency = <0x61a80>; + phandle = <0xec>; + }; + + i2c@ff1a0000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff1a0000 0x00 0x1000>; + clocks = <0x02 0x1f 0x02 0x150>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x09 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x67>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xed>; + }; + + i2c@ff1b0000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff1b0000 0x00 0x1000>; + clocks = <0x02 0x20 0x02 0x151>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x0a 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x68>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xee>; + }; + + spi@ff1d0000 { + compatible = "rockchip,px30-spi\0rockchip,rk3066-spi"; + reg = <0x00 0xff1d0000 0x00 0x1000>; + interrupts = <0x00 0x1a 0x04>; + #address-cells = <0x01>; + #size-cells = <0x00>; + clocks = <0x02 0x24 0x02 0x155>; + clock-names = "spiclk\0apb_pclk"; + dmas = <0x2b 0x0c 0x2b 0x0d>; + dma-names = "tx\0rx"; + pinctrl-names = "default\0high_speed"; + pinctrl-0 = <0x69 0x6a 0x6b 0x6c>; + pinctrl-1 = <0x6d 0x6a 0x6e 0x6f>; + status = "disabled"; + phandle = <0xef>; + }; + + spi@ff1d8000 { + compatible = "rockchip,px30-spi\0rockchip,rk3066-spi"; + reg = <0x00 0xff1d8000 0x00 0x1000>; + interrupts = <0x00 0x1b 0x04>; + #address-cells = <0x01>; + #size-cells = <0x00>; + clocks = <0x02 0x25 0x02 0x156>; + clock-names = "spiclk\0apb_pclk"; + dmas = <0x2b 0x0e 0x2b 0x0f>; + dma-names = "tx\0rx"; + pinctrl-names = "default\0high_speed"; + pinctrl-0 = <0x70 0x71 0x72 0x73 0x74>; + pinctrl-1 = <0x75 0x71 0x72 0x76 0x77>; + status = "disabled"; + phandle = <0xf0>; + }; + + watchdog@ff1e0000 { + compatible = "snps,dw-wdt"; + reg = <0x00 0xff1e0000 0x00 0x100>; + clocks = <0x02 0x15b>; + interrupts = <0x00 0x25 0x04>; + resets = <0x02 0xb5>; + reset-names = "reset"; + status = "disabled"; + phandle = <0xf1>; + }; + + pwm@ff200000 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200000 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x78>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "okay"; + phandle = <0xb8>; + }; + + pwm@ff200010 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200010 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x79>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "okay"; + phandle = <0xbc>; + }; + + pwm@ff200020 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200020 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7a>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf2>; + }; + + pwm@ff200030 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200030 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7b>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf3>; + }; + + pwm@ff208000 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208000 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7c>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf4>; + }; + + pwm@ff208010 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208010 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7d>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf5>; + }; + + pwm@ff208020 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208020 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7e>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf6>; + }; + + pwm@ff208030 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208030 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7f>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf7>; + }; + + rktimer@ff210000 { + compatible = "rockchip,rk3288-timer"; + reg = <0x00 0xff210000 0x00 0x1000>; + interrupts = <0x00 0x1e 0x04>; + clocks = <0x02 0x159 0x02 0x26>; + clock-names = "pclk\0timer"; + phandle = <0xf8>; + }; + + amba { + compatible = "simple-bus"; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + + dmac@ff240000 { + compatible = "arm,pl330\0arm,primecell"; + reg = <0x00 0xff240000 0x00 0x4000>; + interrupts = <0x00 0x01 0x04 0x00 0x02 0x04>; + clocks = <0x02 0xbb>; + clock-names = "apb_pclk"; + #dma-cells = <0x01>; + peripherals-req-type-burst; + phandle = <0x2b>; + }; + }; + + thermal-zones { + phandle = <0xf9>; + + soc-thermal { + polling-delay-passive = <0x14>; + polling-delay = <0x3e8>; + sustainable-power = <0x2ee>; + thermal-sensors = <0x80 0x00>; + phandle = <0xfa>; + + trips { + + trip-point-0 { + temperature = <0x11170>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0xfb>; + }; + + trip-point-1 { + temperature = <0x14c08>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0x81>; + }; + + soc-crit { + temperature = <0x1c138>; + hysteresis = <0x7d0>; + type = "critical"; + phandle = <0xfc>; + }; + }; + + cooling-maps { + + map0 { + trip = <0x81>; + cooling-device = <0x09 0xffffffff 0xffffffff>; + contribution = <0x1000>; + }; + + map1 { + trip = <0x81>; + cooling-device = <0x82 0xffffffff 0xffffffff>; + contribution = <0x1000>; + }; + }; + }; + + gpu-thermal { + polling-delay-passive = <0x64>; + polling-delay = <0x3e8>; + thermal-sensors = <0x80 0x01>; + phandle = <0xfd>; + }; + }; + + tsadc@ff280000 { + compatible = "rockchip,px30-tsadc"; + reg = <0x00 0xff280000 0x00 0x100>; + interrupts = <0x00 0x24 0x04>; + rockchip,grf = <0x2f>; + clocks = <0x02 0x2c 0x02 0x158>; + clock-names = "tsadc\0apb_pclk"; + assigned-clocks = <0x02 0x2c>; + assigned-clock-rates = <0xc350>; + resets = <0x02 0xa8>; + reset-names = "tsadc-apb"; + #thermal-sensor-cells = <0x01>; + rockchip,hw-tshut-temp = <0x1d4c0>; + status = "okay"; + pinctrl-names = "gpio\0otpout"; + pinctrl-0 = <0x83>; + pinctrl-1 = <0x84>; + phandle = <0x80>; + }; + + saradc@ff288000 { + compatible = "rockchip,px30-saradc\0rockchip,rk3399-saradc"; + reg = <0x00 0xff288000 0x00 0x100>; + interrupts = <0x00 0x54 0x04>; + #io-channel-cells = <0x01>; + clocks = <0x02 0x2d 0x02 0x157>; + clock-names = "saradc\0apb_pclk"; + resets = <0x02 0xa5>; + reset-names = "saradc-apb"; + status = "okay"; + vref-supply = <0x85>; + phandle = <0xba>; + }; + + otp@ff290000 { + compatible = "rockchip,px30-otp"; + reg = <0x00 0xff290000 0x00 0x4000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + clocks = <0x02 0x2f 0x02 0x15a 0x02 0x161>; + clock-names = "clk_otp\0pclk_otp\0pclk_otp_phy"; + resets = <0x02 0xb4>; + reset-names = "otp_phy"; + phandle = <0xfe>; + + id@7 { + reg = <0x07 0x10>; + phandle = <0x0f>; + }; + + cpu-leakage@17 { + reg = <0x17 0x01>; + phandle = <0x07>; + }; + + performance@1e { + reg = <0x1e 0x01>; + bits = <0x04 0x03>; + phandle = <0x08>; + }; + }; + + clock-controller@ff2b0000 { + compatible = "rockchip,px30-cru"; + reg = <0x00 0xff2b0000 0x00 0x1000>; + rockchip,grf = <0x2f>; + rockchip,boost = <0x86>; + #clock-cells = <0x01>; + #reset-cells = <0x01>; + assigned-clocks = <0x02 0x04>; + assigned-clock-rates = <0x3dfd2400>; + phandle = <0x02>; + }; + + cpu-boost@ff2b8000 { + compatible = "syscon"; + reg = <0x00 0xff2b8000 0x00 0x1000>; + rockchip,boost-low-con0 = <0x1032>; + rockchip,boost-low-con1 = <0x1441>; + rockchip,boost-high-con0 = <0x1036>; + rockchip,boost-high-con1 = <0x1441>; + rockchip,boost-backup-pll = <0x01>; + rockchip,boost-backup-pll-usage = <0x00>; + rockchip,boost-switch-threshold = <0x249f00>; + rockchip,boost-statis-threshold = <0x100>; + rockchip,boost-statis-enable = <0x00>; + rockchip,boost-enable = <0x00>; + phandle = <0x86>; + }; + + pmu-clock-controller@ff2bc000 { + compatible = "rockchip,px30-pmucru"; + reg = <0x00 0xff2bc000 0x00 0x1000>; + rockchip,grf = <0x2f>; + #clock-cells = <0x01>; + #reset-cells = <0x01>; + assigned-clocks = <0x2a 0x01 0x2a 0x08 0x2a 0x05 0x02 0x07 0x02 0xab 0x02 0xb0 0x02 0xf0 0x02 0xf5 0x02 0x140 0x02 0x49>; + assigned-clock-rates = <0x47868c00 0x5f5e100 0x18cba80 0x23c34600 0xbebc200 0xbebc200 0x8f0d180 0x8f0d180 0x5f5e100 0xbebc200>; + phandle = <0x2a>; + }; + + syscon@ff2c0000 { + compatible = "rockchip,px30-usb2phy-grf\0syscon\0simple-mfd"; + reg = <0x00 0xff2c0000 0x00 0x10000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0xff>; + + usb2-phy@100 { + compatible = "rockchip,px30-usb2phy\0rockchip,rk3328-usb2phy"; + reg = <0x100 0x10>; + clocks = <0x2a 0x0a>; + clock-names = "phyclk"; + #clock-cells = <0x00>; + assigned-clocks = <0x02 0x0e 0x02 0x55>; + assigned-clock-parents = <0x64 0x02 0x0e>; + clock-output-names = "usb480m_phy"; + status = "okay"; + phandle = <0x64>; + + host-port { + #phy-cells = <0x00>; + interrupts = <0x00 0x44 0x04>; + interrupt-names = "linestate"; + status = "okay"; + phandle = <0x89>; + }; + + otg-port { + #phy-cells = <0x00>; + interrupts = <0x00 0x42 0x04 0x00 0x41 0x04 0x00 0x40 0x04>; + interrupt-names = "otg-bvalid\0otg-id\0linestate"; + status = "disabled"; + phandle = <0x88>; + }; + }; + }; + + video-phy@ff2e0000 { + compatible = "rockchip,px30-video-phy"; + reg = <0x00 0xff2e0000 0x00 0x10000 0x00 0xff450000 0x00 0x10000>; + clocks = <0x2a 0x0b 0x02 0x145 0x02 0x144>; + clock-names = "ref\0pclk_phy\0pclk_host"; + #clock-cells = <0x00>; + resets = <0x02 0x3e>; + reset-names = "rst"; + power-domains = <0x87 0x0c>; + #phy-cells = <0x00>; + status = "okay"; + phandle = <0x4b>; + }; + + mipi-dphy-rx0@ff2f0000 { + compatible = "rockchip,rk3326-mipi-dphy"; + reg = <0x00 0xff2f0000 0x00 0x4000>; + clocks = <0x02 0x146>; + clock-names = "dphy-ref"; + power-domains = <0x87 0x0d>; + rockchip,grf = <0x2f>; + status = "okay"; + phandle = <0x100>; + }; + + usb@ff300000 { + compatible = "rockchip,px30-usb\0rockchip,rk3066-usb\0snps,dwc2"; + reg = <0x00 0xff300000 0x00 0x40000>; + interrupts = <0x00 0x3e 0x04>; + clocks = <0x02 0x102>; + clock-names = "otg"; + power-domains = <0x87 0x05>; + dr_mode = "otg"; + g-np-tx-fifo-size = <0x10>; + g-rx-fifo-size = <0x118>; + g-tx-fifo-size = <0x100 0x80 0x80 0x40 0x20 0x10>; + g-use-dma; + phys = <0x88>; + phy-names = "usb2-phy"; + status = "okay"; + phandle = <0x101>; + }; + + usb@ff340000 { + compatible = "generic-ehci"; + reg = <0x00 0xff340000 0x00 0x10000>; + interrupts = <0x00 0x3c 0x04>; + clocks = <0x02 0x103 0x64>; + clock-names = "usbhost\0utmi"; + power-domains = <0x87 0x05>; + phys = <0x89>; + phy-names = "usb"; + status = "disabled"; + phandle = <0x102>; + }; + + usb@ff350000 { + compatible = "generic-ohci"; + reg = <0x00 0xff350000 0x00 0x10000>; + interrupts = <0x00 0x3d 0x04>; + clocks = <0x02 0x103 0x64>; + clock-names = "usbhost\0utmi"; + power-domains = <0x87 0x05>; + phys = <0x89>; + phy-names = "usb"; + status = "disabled"; + phandle = <0x103>; + }; + + ethernet@ff360000 { + compatible = "rockchip,px30-gmac"; + reg = <0x00 0xff360000 0x00 0x10000>; + rockchip,grf = <0x2f>; + interrupts = <0x00 0x2b 0x04>; + interrupt-names = "macirq"; + clocks = <0x02 0x3e 0x02 0x3f 0x02 0x3f 0x02 0x40 0x02 0x41 0x02 0xb2 0x02 0x143 0x02 0x4c>; + clock-names = "stmmaceth\0mac_clk_rx\0mac_clk_tx\0clk_mac_ref\0clk_mac_refout\0aclk_mac\0pclk_mac\0clk_mac_speed"; + phy-mode = "rmii"; + pinctrl-names = "default"; + pinctrl-0 = <0x8a 0x8b>; + resets = <0x02 0x5e>; + reset-names = "stmmaceth"; + power-domains = <0x87 0x09>; + status = "disabled"; + phandle = <0x104>; + }; + + dwmmc@ff370000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff370000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0xf7 0x02 0x3b 0x02 0x43 0x02 0x44>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x3b>; + assigned-clock-parents = <0x02 0x57>; + power-domains = <0x87 0x07>; + fifo-depth = <0x100>; + interrupts = <0x00 0x36 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x8c 0x8d 0x8e 0x8f>; + status = "okay"; + bus-width = <0x04>; + cap-mmc-highspeed; + cap-sd-highspeed; + supports-sd; + card-detect-delay = <0x320>; + ignore-pm-notify; + cd-gpios = <0x59 0x03 0x01>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <0x49>; + vmmc-supply = <0x90>; + phandle = <0x105>; + }; + + dwmmc@ff380000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff380000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0xff 0x02 0x38 0x02 0x45 0x02 0x46>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x38>; + assigned-clock-parents = <0x02 0x51>; + power-domains = <0x87 0x0a>; + fifo-depth = <0x100>; + interrupts = <0x00 0x37 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x91 0x92 0x93>; + status = "okay"; + bus-width = <0x04>; + cap-mmc-highspeed; + cap-sd-highspeed; + supports-sd; + card-detect-delay = <0x320>; + ignore-pm-notify; + cd-gpios = <0x59 0x0a 0x01>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <0x49>; + vmmc-supply = <0x90>; + phandle = <0x106>; + }; + + dwmmc@ff390000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff390000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0x100 0x02 0x39 0x02 0x47 0x02 0x48>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x39>; + assigned-clock-parents = <0x02 0x53>; + power-domains = <0x87 0x0a>; + fifo-depth = <0x100>; + interrupts = <0x00 0x35 0x04>; + status = "okay"; + phandle = <0x107>; + }; + + nandc@ff3b0000 { + compatible = "rockchip,rk-nandc"; + reg = <0x00 0xff3b0000 0x00 0x4000>; + interrupts = <0x00 0x39 0x04>; + nandc_id = <0x00>; + clocks = <0x02 0x37 0x02 0xfe>; + clock-names = "clk_nandc\0hclk_nandc"; + assigned-clocks = <0x02 0x37>; + assigned-clock-parents = <0x02 0x4f>; + power-domains = <0x87 0x0a>; + status = "disabled"; + phandle = <0x108>; + }; + + sfc@ff3a0000 { + compatible = "rockchip,sfc"; + reg = <0x00 0xff3a0000 0x00 0x4000>; + interrupts = <0x00 0x38 0x04>; + clocks = <0x02 0x3a 0x02 0x101>; + clock-names = "clk_sfc\0hclk_sfc"; + assigned-clocks = <0x02 0x3a>; + assigned-clock-rates = <0x989680>; + status = "disabled"; + phandle = <0x109>; + }; + + gpu@ff400000 { + compatible = "arm,malit602\0arm,malit60x\0arm,malit6xx\0arm,mali-midgard"; + reg = <0x00 0xff400000 0x00 0x4000>; + interrupts = <0x00 0x2d 0x04 0x00 0x2e 0x04 0x00 0x2f 0x04>; + interrupt-names = "GPU\0MMU\0JOB"; + clocks = <0x02 0x49>; + clock-names = "clk_mali"; + power-domains = <0x87 0x0e>; + #cooling-cells = <0x02>; + operating-points-v2 = <0x94>; + status = "okay"; + mali-supply = <0x0e>; + phandle = <0x82>; + + power_model { + compatible = "arm,mali-simple-power-model"; + static-coefficient = <0x64578>; + dynamic-coefficient = <0x2dd>; + ts = <0x7d00 0x125c 0xffffffb0 0x02>; + thermal-zone = "gpu-thermal"; + }; + }; + + gpu-opp-table { + compatible = "operating-points-v2"; + rockchip,thermal-zone = "soc-thermal"; + rockchip,temp-hysteresis = <0x1388>; + rockchip,low-temp = <0x00>; + rockchip,low-temp-min-volt = <0xf4240>; + rockchip,low-temp-adjust-volt = <0x00 0x1e0 0xc350>; + rockchip,max-volt = <0x11edd8>; + rockchip,evb-irdrop = <0x61a8>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-ch = <0x00 0x00>; + phandle = <0x94>; + + opp-400000000 { + opp-hz = <0x00 0x17d78400>; + opp-microvolt = <0x100590>; + opp-microvolt-L0 = <0x100590>; + opp-microvolt-L1 = <0xfa3e8>; + opp-microvolt-L2 = <0xee098>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-480000000 { + opp-hz = <0x00 0x1c9c3800>; + opp-microvolt = <0x112a88>; + opp-microvolt-L0 = <0x112a88>; + opp-microvolt-L1 = <0x10c8e0>; + opp-microvolt-L2 = <0x100590>; + opp-microvolt-L3 = <0xf4240>; + }; + + opp-520000000 { + opp-hz = <0x00 0x1efe9200>; + opp-microvolt = <0x118c30>; + opp-microvolt-L0 = <0x118c30>; + opp-microvolt-L1 = <0x118c30>; + opp-microvolt-L2 = <0x10c8e0>; + opp-microvolt-L3 = <0x100590>; + }; + }; + + hevc_service@ff440000 { + compatible = "rockchip,hevc_sub"; + iommu_enabled = <0x01>; + reg = <0x00 0xff440000 0x00 0x400>; + interrupts = <0x00 0x31 0x04>; + interrupt-names = "irq_dec"; + dev_mode = <0x01>; + iommus = <0x95>; + allocator = <0x01>; + phandle = <0x98>; + }; + + vpu_service@ff442000 { + compatible = "rockchip,vpu_sub"; + iommu_enabled = <0x01>; + reg = <0x00 0xff442000 0x00 0x800>; + interrupts = <0x00 0x50 0x04 0x00 0x4f 0x04>; + interrupt-names = "irq_enc\0irq_dec"; + dev_mode = <0x00>; + iommus = <0x96>; + allocator = <0x01>; + phandle = <0x97>; + }; + + vpu_combo { + compatible = "rockchip,vpu_combo"; + subcnt = <0x02>; + rockchip,grf = <0x2f>; + rockchip,sub = <0x97 0x98>; + clocks = <0x02 0xaf 0x02 0xf4 0x02 0x4b>; + clock-names = "aclk_vcodec\0hclk_vcodec\0clk_core"; + resets = <0x02 0x24 0x02 0x26 0x02 0x25 0x02 0x27 0x02 0x3f>; + reset-names = "video_a\0video_h\0niu_a\0niu_h\0video_core"; + power-domains = <0x87 0x0b>; + mode_bit = <0x0f>; + mode_ctrl = <0x410>; + status = "okay"; + phandle = <0x10a>; + }; + + iommu@ff440440 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff440440 0x00 0x40 0x00 0xff440480 0x00 0x40>; + interrupts = <0x00 0x32 0x04>; + interrupt-names = "hevc_mmu"; + clocks = <0x02 0xaf 0x02 0xf4>; + clock-names = "aclk\0hclk"; + power-domains = <0x87 0x0b>; + #iommu-cells = <0x00>; + phandle = <0x95>; + }; + + iommu@ff442800 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff442800 0x00 0x100>; + interrupts = <0x00 0x51 0x04>; + interrupt-names = "vpu_mmu"; + clocks = <0x02 0xaf 0x02 0xf4>; + clock-names = "aclk\0hclk"; + power-domains = <0x87 0x0b>; + #iommu-cells = <0x00>; + phandle = <0x96>; + }; + + dsi@ff450000 { + compatible = "rockchip,px30-mipi-dsi"; + reg = <0x00 0xff450000 0x00 0x10000>; + interrupts = <0x00 0x4b 0x04>; + clocks = <0x02 0x144 0x4b>; + clock-names = "pclk\0hs_clk"; + resets = <0x02 0x3d>; + reset-names = "apb"; + phys = <0x4b>; + phy-names = "mipi_dphy"; + power-domains = <0x87 0x0c>; + rockchip,grf = <0x2f>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + phandle = <0x10b>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x13>; + status = "okay"; + phandle = <0x9f>; + }; + }; + }; + + panel@0 { + compatible = "elida,kd35t133\0simple-panel-dsi"; + reg = <0x00>; + backlight = <0x99>; + power-supply = <0x9a>; + enable-gpios = <0x9b 0x12 0x01>; + reset-gpios = <0x63 0x10 0x01>; + led-red-gpios = <0x59 0x05 0x00>; + led-blue1-gpios = <0x59 0x00 0x00>; + prepare-delay-ms = <0x64>; + reset-delay-ms = <0x32>; + init-delay-ms = <0x14>; + enable-delay-ms = <0xc8>; + disable-delay-ms = <0x32>; + unprepare-delay-ms = <0x14>; + width-mm = <0x47>; + height-mm = <0x47>; + dsi,flags = <0xa03>; + dsi,format = <0x00>; + dsi,lanes = <0x04>; + panel-init-sequence = [39 00 04 b9 f1 12 83 39 00 1c ba 33 81 05 f9 0e 0e 20 00 00 00 00 00 00 00 44 25 00 91 0a 00 00 02 4f d1 00 00 37 15 00 02 b8 25 39 00 04 bf 02 11 00 39 00 0b b3 0c 10 0a 50 03 ff 00 00 00 00 39 00 0a c0 73 73 50 50 00 00 08 70 00 15 00 02 bc 46 15 00 02 cc 0b 15 00 02 b4 80 39 00 04 b2 00 13 f0 39 00 0f e3 07 07 0b 0b 03 0b 00 00 00 00 ff 00 c0 10 39 00 0d c1 53 00 1e 1e 77 e1 cc dd 67 77 33 33 39 00 03 b5 10 10 39 00 03 b6 6c 7c 39 00 40 e9 08 00 0e 00 00 b0 b1 11 31 23 28 10 b0 b1 27 08 00 04 02 00 00 00 00 04 02 00 00 00 88 88 ba 60 24 08 88 88 88 88 88 88 88 ba 71 35 18 88 88 88 88 88 00 00 00 01 00 00 00 00 00 00 00 00 00 39 00 3e ea 97 0a 82 02 13 07 00 00 00 00 00 00 80 88 ba 17 53 88 88 88 88 88 88 81 88 ba 06 42 88 88 88 88 88 88 23 10 00 02 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 39 00 23 e0 00 07 0b 27 2d 3f 3b 37 05 0a 0b 0f 11 0f 12 12 18 00 07 0b 27 2d 3f 3b 37 05 0a 0b 0f 11 0f 12 12 18 05 96 01 11 05 32 01 29]; + panel-exit-sequence = <0x5140128 0x50a0110>; + + display-timings { + native-mode = <0x9c>; + + 60Hz { + clock-frequency = <0x2625a00>; + hactive = <0x280>; + vactive = <0x1e0>; + hback-porch = <0x78>; + hfront-porch = <0x78>; + vback-porch = <0x0d>; + vfront-porch = <0x11>; + hsync-len = <0x78>; + vsync-len = <0x05>; + hsync-active = <0x00>; + vsync-active = <0x00>; + de-active = <0x00>; + pixelclk-active = <0x00>; + phandle = <0x9c>; + }; + + 50Hz { + clock-frequency = <0x1851960>; + hactive = <0x280>; + vactive = <0x1e0>; + hfront-porch = <0xbc>; + hsync-len = <0x02>; + hback-porch = <0xbe>; + vfront-porch = <0x0d>; + vsync-len = <0x02>; + vback-porch = <0x05>; + hsync-active = <0x00>; + vsync-active = <0x00>; + de-active = <0x00>; + pixelclk-active = <0x00>; + phandle = <0x10c>; + }; + + 75Hz { + clock-frequency = <0x1d2eb40>; + hactive = <0x280>; + vactive = <0x1e0>; + hfront-porch = <0x57>; + hsync-len = <0x02>; + hback-porch = <0x57>; + vfront-porch = <0x0d>; + vsync-len = <0x02>; + vback-porch = <0x05>; + hsync-active = <0x00>; + vsync-active = <0x00>; + de-active = <0x00>; + pixelclk-active = <0x00>; + phandle = <0x10d>; + }; + }; + }; + }; + + vop@ff460000 { + compatible = "rockchip,px30-vop-big"; + reg = <0x00 0xff460000 0x00 0x1fc 0x00 0xff460a00 0x00 0x400>; + rockchip,grf = <0x2f>; + reg-names = "regs\0gamma_lut"; + interrupts = <0x00 0x4d 0x04>; + clocks = <0x02 0xb5 0x02 0x96 0x02 0xfb>; + clock-names = "aclk_vop\0dclk_vop\0hclk_vop"; + power-domains = <0x87 0x0c>; + iommus = <0x9d>; + status = "okay"; + phandle = <0x10e>; + + port { + #address-cells = <0x01>; + #size-cells = <0x00>; + phandle = <0x10>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x9e>; + phandle = <0x12>; + }; + + endpoint@1 { + reg = <0x01>; + remote-endpoint = <0x9f>; + phandle = <0x13>; + }; + + endpoint@2 { + reg = <0x02>; + remote-endpoint = <0xa0>; + phandle = <0x14>; + }; + }; + }; + + iommu@ff460f00 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff460f00 0x00 0x100>; + interrupts = <0x00 0x4d 0x04>; + interrupt-names = "vopb_mmu"; + clocks = <0x02 0xb5 0x02 0xfb>; + clock-names = "aclk\0hclk"; + power-domains = <0x87 0x0c>; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0x9d>; + }; + + rk_rga@ff480000 { + compatible = "rockchip,rga2"; + reg = <0x00 0xff480000 0x00 0x1000>; + interrupts = <0x00 0x4c 0x04>; + clocks = <0x02 0xb7 0x02 0xfd 0x02 0x35>; + clock-names = "aclk_rga\0hclk_rga\0clk_rga"; + power-domains = <0x87 0x0c>; + dma-coherent; + status = "okay"; + phandle = <0x10f>; + }; + + cif@ff490000 { + compatible = "rockchip,cif"; + reg = <0x00 0xff490000 0x00 0x200>; + interrupts = <0x00 0x45 0x04>; + clocks = <0x02 0xb3 0x02 0xf9 0x02 0x160 0x02 0x34>; + clock-names = "aclk_cif0\0hclk_cif0\0pclk_cif\0cif0_out"; + resets = <0x02 0x2c 0x02 0x2d 0x02 0x2e>; + reset-names = "rst_cif_a\0rst_cif_h\0rst_cif_pclkin"; + power-domains = <0x87 0x0d>; + pinctrl-names = "cif_pin_all"; + pinctrl-0 = <0xa1>; + iommus = <0xa2>; + status = "disabled"; + phandle = <0x110>; + }; + + cif-new@ff490000 { + compatible = "rockchip,px30-cif"; + reg = <0x00 0xff490000 0x00 0x200>; + interrupts = <0x00 0x45 0x04>; + clocks = <0x02 0xb3 0x02 0xf9 0x02 0x160 0x02 0x34>; + clock-names = "aclk_cif\0hclk_cif\0pclk_cif\0cif_out"; + resets = <0x02 0x2c 0x02 0x2d 0x02 0x2e>; + reset-names = "rst_cif_a\0rst_cif_h\0rst_cif_pclkin"; + power-domains = <0x87 0x0d>; + iommus = <0xa2>; + status = "disabled"; + phandle = <0x111>; + }; + + iommu@ff490800 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff490800 0x00 0x100>; + interrupts = <0x00 0x45 0x04>; + interrupt-names = "vip_mmu"; + clocks = <0x02 0xb3 0x02 0xf9>; + clock-names = "aclk\0hclk"; + power-domains = <0x87 0x0d>; + rk_iommu,disable_reset_quirk; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xa2>; + }; + + rk_isp@ff4a0000 { + compatible = "rockchip,px30-isp\0rockchip,isp"; + reg = <0x00 0xff4a0000 0x00 0x8000>; + interrupts = <0x00 0x46 0x04>; + clocks = <0x02 0xb4 0x02 0xfa 0x02 0x33 0x02 0x33 0x02 0x15f 0x02 0x34 0x02 0x34 0x02 0x146>; + clock-names = "aclk_isp\0hclk_isp\0clk_isp\0clk_isp_jpe\0pclkin_isp\0clk_cif_pll\0clk_cif_out\0pclk_dphyrx"; + resets = <0x02 0x2b 0x02 0x2f>; + reset-names = "rst_isp\0rst_mipicsiphy"; + power-domains = <0x87 0x0d>; + pinctrl-names = "default\0isp_dvp8bit2\0isp_dvp10bit\0isp_dvp12bit"; + pinctrl-0 = <0xa3>; + pinctrl-1 = <0xa1>; + pinctrl-2 = <0xa1 0xa4>; + pinctrl-3 = <0xa5 0xa1 0xa4>; + rockchip,isp,mipiphy = <0x01>; + rockchip,isp,csiphy,reg = <0xff2f0000 0x4000>; + rockchip,grf = <0x2f>; + rockchip,cru = <0x02>; + rockchip,isp,iommu-enable = <0x01>; + iommus = <0xa6>; + status = "disabled"; + phandle = <0x112>; + }; + + rkisp1@ff4a0000 { + compatible = "rockchip,rk3326-rkisp1"; + reg = <0x00 0xff4a0000 0x00 0x8000>; + interrupts = <0x00 0x46 0x04 0x00 0x49 0x04 0x00 0x4a 0x04>; + interrupt-names = "isp_irq\0mi_irq\0mipi_irq"; + clocks = <0x02 0xb4 0x02 0xfa 0x02 0x33 0x02 0x15f>; + clock-names = "aclk_isp\0hclk_isp\0clk_isp\0pclk_isp"; + devfreq = <0xa7>; + power-domains = <0x87 0x0d>; + iommus = <0xa6>; + rockchip,grf = <0x2f>; + status = "okay"; + phandle = <0x113>; + }; + + iommu@ff4a8000 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff4a8000 0x00 0x100>; + interrupts = <0x00 0x46 0x04>; + interrupt-names = "isp_mmu"; + clocks = <0x02 0xb4 0x02 0xfa>; + clock-names = "aclk\0hclk"; + power-domains = <0x87 0x0d>; + rk_iommu,disable_reset_quirk; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xa6>; + }; + + qos@ff518000 { + compatible = "syscon"; + reg = <0x00 0xff518000 0x00 0x20>; + phandle = <0x18>; + }; + + qos@ff520000 { + compatible = "syscon"; + reg = <0x00 0xff520000 0x00 0x20>; + phandle = <0x28>; + }; + + qos@ff52c000 { + compatible = "syscon"; + reg = <0x00 0xff52c000 0x00 0x20>; + phandle = <0x17>; + }; + + qos@ff538000 { + compatible = "syscon"; + reg = <0x00 0xff538000 0x00 0x20>; + phandle = <0x19>; + }; + + qos@ff538080 { + compatible = "syscon"; + reg = <0x00 0xff538080 0x00 0x20>; + phandle = <0x1a>; + }; + + qos@ff538100 { + compatible = "syscon"; + reg = <0x00 0xff538100 0x00 0x20>; + phandle = <0x1b>; + }; + + qos@ff538180 { + compatible = "syscon"; + reg = <0x00 0xff538180 0x00 0x20>; + phandle = <0x1c>; + }; + + qos@ff540000 { + compatible = "syscon"; + reg = <0x00 0xff540000 0x00 0x20>; + phandle = <0x15>; + }; + + qos@ff540080 { + compatible = "syscon"; + reg = <0x00 0xff540080 0x00 0x20>; + phandle = <0x16>; + }; + + qos@ff548000 { + compatible = "syscon"; + reg = <0x00 0xff548000 0x00 0x20>; + phandle = <0x23>; + }; + + qos@ff548080 { + compatible = "syscon"; + reg = <0x00 0xff548080 0x00 0x20>; + phandle = <0x24>; + }; + + qos@ff548100 { + compatible = "syscon"; + reg = <0x00 0xff548100 0x00 0x20>; + phandle = <0x25>; + }; + + qos@ff548180 { + compatible = "syscon"; + reg = <0x00 0xff548180 0x00 0x20>; + phandle = <0x26>; + }; + + qos@ff548200 { + compatible = "syscon"; + reg = <0x00 0xff548200 0x00 0x20>; + phandle = <0x27>; + }; + + qos@ff550000 { + compatible = "syscon"; + reg = <0x00 0xff550000 0x00 0x20>; + phandle = <0x1f>; + }; + + qos@ff550080 { + compatible = "syscon"; + reg = <0x00 0xff550080 0x00 0x20>; + phandle = <0x20>; + }; + + qos@ff550100 { + compatible = "syscon"; + reg = <0x00 0xff550100 0x00 0x20>; + phandle = <0x21>; + }; + + qos@ff550180 { + compatible = "syscon"; + reg = <0x00 0xff550180 0x00 0x20>; + phandle = <0x22>; + }; + + qos@ff558000 { + compatible = "syscon"; + reg = <0x00 0xff558000 0x00 0x20>; + phandle = <0x1d>; + }; + + qos@ff558080 { + compatible = "syscon"; + reg = <0x00 0xff558080 0x00 0x20>; + phandle = <0x1e>; + }; + + dfi@ff610000 { + reg = <0x00 0xff610000 0x00 0x400>; + compatible = "rockchip,px30-dfi"; + rockchip,pmugrf = <0xa8>; + status = "disabled"; + phandle = <0xa9>; + }; + + dmc { + compatible = "rockchip,px30-dmc"; + interrupts = <0x00 0x69 0x04>; + interrupt-names = "complete_irq"; + devfreq-events = <0xa9>; + clocks = <0x02 0x54>; + clock-names = "dmc_clk"; + operating-points-v2 = <0xaa>; + ddr_timing = <0xab>; + upthreshold = <0x28>; + downdifferential = <0x14>; + system-status-freq = <0x01 0x80e80 0x08 0x6ddd0 0x02 0x2f5d0 0x20 0x6ddd0 0x1000 0x80e80 0x4000 0xa2990 0x2000 0xa2990>; + auto-min-freq = <0x50140>; + auto-freq-en = <0x01>; + #cooling-cells = <0x02>; + status = "disabled"; + center-supply = <0x0e>; + phandle = <0xa7>; + + ddr_power_model { + compatible = "ddr_power_model"; + dynamic-power-coefficient = <0x78>; + static-power-coefficient = <0xc8>; + ts = <0x7d00 0x125c 0xffffffb0 0x02>; + thermal-zone = "soc-thermal"; + phandle = <0x114>; + }; + }; + + dmc-opp-table { + compatible = "operating-points-v2"; + rockchip,max-volt = <0x118c30>; + rockchip,evb-irdrop = <0x61a8>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-ch = <0x00 0x00>; + phandle = <0xaa>; + + opp-528000000 { + opp-hz = <0x00 0x1f78a400>; + opp-microvolt = <0xee098>; + opp-microvolt-L0 = <0xee098>; + opp-microvolt-L1 = <0xee098>; + opp-microvolt-L2 = <0xe7ef0>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-666000000 { + opp-hz = <0x00 0x27b25a80>; + opp-microvolt = <0x100590>; + opp-microvolt-L0 = <0x100590>; + opp-microvolt-L1 = <0xf4240>; + opp-microvolt-L2 = <0xee098>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-786000000 { + opp-hz = <0x00 0x2ed96880>; + opp-microvolt = <0x10c8e0>; + opp-microvolt-L0 = <0x10c8e0>; + opp-microvolt-L1 = <0x100590>; + opp-microvolt-L2 = <0xfa3e8>; + opp-microvolt-L3 = <0xf4240>; + status = "okay"; + }; + }; + + rockchip-system-monitor { + compatible = "rockchip,system-monitor"; + rockchip,thermal-zone = "soc-thermal"; + rockchip,polling-delay = <0xc8>; + phandle = <0x115>; + }; + + pinctrl { + compatible = "rockchip,px30-pinctrl"; + rockchip,grf = <0x2f>; + rockchip,pmu = <0xa8>; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + phandle = <0x116>; + + gpio0@ff040000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff040000 0x00 0x100>; + interrupts = <0x00 0x03 0x04>; + clocks = <0x2a 0x14>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x59>; + }; + + gpio1@ff250000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff250000 0x00 0x100>; + interrupts = <0x00 0x04 0x04>; + clocks = <0x02 0x15c>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x9b>; + }; + + gpio2@ff260000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff260000 0x00 0x100>; + interrupts = <0x00 0x05 0x04>; + clocks = <0x02 0x15d>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0xbf>; + }; + + gpio3@ff270000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff270000 0x00 0x100>; + interrupts = <0x00 0x06 0x04>; + clocks = <0x02 0x15e>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x63>; + }; + + pcfg-pull-up { + bias-pull-up; + phandle = <0xae>; + }; + + pcfg-pull-down { + bias-pull-down; + phandle = <0x117>; + }; + + pcfg-pull-none { + bias-disable; + phandle = <0xad>; + }; + + pcfg-pull-none-2ma { + bias-disable; + drive-strength = <0x02>; + phandle = <0x118>; + }; + + pcfg-pull-up-2ma { + bias-pull-up; + drive-strength = <0x02>; + phandle = <0x119>; + }; + + pcfg-pull-up-4ma { + bias-pull-up; + drive-strength = <0x04>; + phandle = <0xaf>; + }; + + pcfg-pull-none-4ma { + bias-disable; + drive-strength = <0x04>; + phandle = <0x11a>; + }; + + pcfg-pull-down-4ma { + bias-pull-down; + drive-strength = <0x04>; + phandle = <0x11b>; + }; + + pcfg-pull-none-8ma { + bias-disable; + drive-strength = <0x08>; + phandle = <0xb2>; + }; + + pcfg-pull-up-8ma { + bias-pull-up; + drive-strength = <0x08>; + phandle = <0xb0>; + }; + + pcfg-pull-none-12ma { + bias-disable; + drive-strength = <0x0c>; + phandle = <0xb4>; + }; + + pcfg-pull-up-12ma { + bias-pull-up; + drive-strength = <0x0c>; + phandle = <0xb3>; + }; + + pcfg-pull-none-smt { + bias-disable; + input-schmitt-enable; + phandle = <0xac>; + }; + + pcfg-output-high { + output-high; + phandle = <0x11c>; + }; + + pcfg-output-low { + output-low; + phandle = <0xb5>; + }; + + pcfg-input-high { + bias-pull-up; + input-enable; + phandle = <0xb1>; + }; + + pcfg-input { + input-enable; + phandle = <0x11d>; + }; + + i2c0 { + + i2c0-xfer { + rockchip,pins = <0x00 0x08 0x01 0xac 0x00 0x09 0x01 0xac>; + phandle = <0x58>; + }; + }; + + i2c1 { + + i2c1-xfer { + rockchip,pins = <0x00 0x12 0x01 0xac 0x00 0x13 0x01 0xac>; + phandle = <0x66>; + }; + }; + + i2c2 { + + i2c2-xfer { + rockchip,pins = <0x02 0x0f 0x02 0xac 0x02 0x10 0x02 0xac>; + phandle = <0x67>; + }; + }; + + i2c3 { + + i2c3-xfer { + rockchip,pins = <0x01 0x0c 0x04 0xac 0x01 0x0d 0x04 0xac>; + phandle = <0x68>; + }; + }; + + tsadc { + + tsadc-otp-gpio { + rockchip,pins = <0x00 0x06 0x00 0xad>; + phandle = <0x83>; + }; + + tsadc-otp-out { + rockchip,pins = <0x00 0x06 0x01 0xad>; + phandle = <0x84>; + }; + }; + + uart0 { + + uart0-xfer { + rockchip,pins = <0x00 0x0a 0x01 0xae 0x00 0x0b 0x01 0xae>; + phandle = <0x2c>; + }; + + uart0-cts { + rockchip,pins = <0x00 0x0c 0x01 0xad>; + phandle = <0x2d>; + }; + + uart0-rts { + rockchip,pins = <0x00 0x0d 0x01 0xad>; + phandle = <0x2e>; + }; + + uart0-rts-gpio { + rockchip,pins = <0x00 0x0d 0x00 0xad>; + phandle = <0x11e>; + }; + }; + + uart1 { + + uart1-xfer { + rockchip,pins = <0x01 0x11 0x01 0xae 0x01 0x10 0x01 0xae>; + phandle = <0x11f>; + }; + + uart1-cts { + rockchip,pins = <0x01 0x12 0x01 0xad>; + phandle = <0x120>; + }; + + uart1-rts { + rockchip,pins = <0x01 0x13 0x01 0xad>; + phandle = <0x121>; + }; + + uart1-rts-gpio { + rockchip,pins = <0x01 0x13 0x00 0xad>; + phandle = <0x122>; + }; + }; + + uart2-m0 { + + uart2m0-xfer { + rockchip,pins = <0x01 0x1a 0x02 0xae 0x01 0x1b 0x02 0xae>; + phandle = <0x4e>; + }; + }; + + uart2-m1 { + + uart2m1-xfer { + rockchip,pins = <0x02 0x0c 0x02 0xae 0x02 0x0e 0x02 0xae>; + phandle = <0xb6>; + }; + }; + + uart3-m0 { + + uart3m0-xfer { + rockchip,pins = <0x00 0x10 0x02 0xae 0x00 0x11 0x02 0xae>; + phandle = <0x123>; + }; + + uart3m0-cts { + rockchip,pins = <0x00 0x12 0x02 0xad>; + phandle = <0x124>; + }; + + uart3m0-rts { + rockchip,pins = <0x00 0x13 0x02 0xad>; + phandle = <0x125>; + }; + + uart3m0-rts-gpio { + rockchip,pins = <0x00 0x13 0x00 0xad>; + phandle = <0x126>; + }; + }; + + uart3-m1 { + + uart3m1-xfer { + rockchip,pins = <0x01 0x0e 0x02 0xae 0x01 0x0f 0x02 0xae>; + phandle = <0x4f>; + }; + + uart3m1-cts { + rockchip,pins = <0x01 0x0c 0x02 0xad>; + phandle = <0x50>; + }; + + uart3m1-rts { + rockchip,pins = <0x01 0x0d 0x02 0xad>; + phandle = <0x51>; + }; + + uart3m1-rts-gpio { + rockchip,pins = <0x01 0x0d 0x00 0xad>; + phandle = <0x127>; + }; + }; + + uart4 { + + uart4-xfer { + rockchip,pins = <0x01 0x1c 0x02 0xae 0x01 0x1d 0x02 0xae>; + phandle = <0x52>; + }; + + uart4-cts { + rockchip,pins = <0x01 0x1e 0x02 0xad>; + phandle = <0x53>; + }; + + uart4-rts { + rockchip,pins = <0x01 0x1f 0x02 0xad>; + phandle = <0x54>; + }; + }; + + uart5 { + + uart5-xfer { + rockchip,pins = <0x03 0x02 0x04 0xae 0x03 0x01 0x04 0xae>; + phandle = <0x55>; + }; + + uart5-cts { + rockchip,pins = <0x03 0x03 0x04 0xad>; + phandle = <0x56>; + }; + + uart5-rts { + rockchip,pins = <0x03 0x05 0x04 0xad>; + phandle = <0x57>; + }; + }; + + spi0 { + + spi0-clk { + rockchip,pins = <0x01 0x0f 0x03 0xaf>; + phandle = <0x69>; + }; + + spi0-csn { + rockchip,pins = <0x01 0x0e 0x03 0xaf>; + phandle = <0x6a>; + }; + + spi0-miso { + rockchip,pins = <0x01 0x0d 0x03 0xaf>; + phandle = <0x6b>; + }; + + spi0-mosi { + rockchip,pins = <0x01 0x0c 0x03 0xaf>; + phandle = <0x6c>; + }; + + spi0-clk-hs { + rockchip,pins = <0x01 0x0f 0x03 0xb0>; + phandle = <0x6d>; + }; + + spi0-miso-hs { + rockchip,pins = <0x01 0x0d 0x03 0xb0>; + phandle = <0x6e>; + }; + + spi0-mosi-hs { + rockchip,pins = <0x01 0x0c 0x03 0xb0>; + phandle = <0x6f>; + }; + }; + + spi1 { + + spi1-clk { + rockchip,pins = <0x03 0x0f 0x04 0xaf>; + phandle = <0x70>; + }; + + spi1-csn0 { + rockchip,pins = <0x03 0x09 0x04 0xaf>; + phandle = <0x71>; + }; + + spi1-csn1 { + rockchip,pins = <0x03 0x0a 0x02 0xaf>; + phandle = <0x72>; + }; + + spi1-miso { + rockchip,pins = <0x03 0x0e 0x04 0xaf>; + phandle = <0x73>; + }; + + spi1-mosi { + rockchip,pins = <0x03 0x0c 0x04 0xaf>; + phandle = <0x74>; + }; + + spi1-clk-hs { + rockchip,pins = <0x03 0x0f 0x04 0xb0>; + phandle = <0x75>; + }; + + spi1-miso-hs { + rockchip,pins = <0x03 0x0e 0x04 0xb0>; + phandle = <0x76>; + }; + + spi1-mosi-hs { + rockchip,pins = <0x03 0x0c 0x04 0xb0>; + phandle = <0x77>; + }; + }; + + pdm { + + pdm-clk0m1 { + rockchip,pins = <0x02 0x16 0x01 0xad>; + phandle = <0x128>; + }; + + pdm-clk1 { + rockchip,pins = <0x03 0x17 0x02 0xad>; + phandle = <0x44>; + }; + + pdm-sdi0m0 { + rockchip,pins = <0x03 0x1b 0x02 0xad>; + phandle = <0x45>; + }; + + pdm-sdi0m1 { + rockchip,pins = <0x02 0x15 0x02 0xad>; + phandle = <0x129>; + }; + + pdm-sdi1 { + rockchip,pins = <0x03 0x18 0x02 0xad>; + phandle = <0x46>; + }; + + pdm-sdi2 { + rockchip,pins = <0x03 0x19 0x02 0xad>; + phandle = <0x47>; + }; + + pdm-sdi3 { + rockchip,pins = <0x03 0x1a 0x02 0xad>; + phandle = <0x48>; + }; + + pdm-clk0m1-sleep { + rockchip,pins = <0x02 0x16 0x00 0xb1>; + phandle = <0x12a>; + }; + + pdm-clk1-sleep { + rockchip,pins = <0x03 0x17 0x00 0xb1>; + phandle = <0x12b>; + }; + + pdm-sdi0m0-sleep { + rockchip,pins = <0x03 0x1b 0x00 0xb1>; + phandle = <0x12c>; + }; + + pdm-sdi0m1-sleep { + rockchip,pins = <0x02 0x15 0x00 0xb1>; + phandle = <0x12d>; + }; + + pdm-sdi1-sleep { + rockchip,pins = <0x03 0x18 0x00 0xb1>; + phandle = <0x12e>; + }; + + pdm-sdi2-sleep { + rockchip,pins = <0x03 0x19 0x00 0xb1>; + phandle = <0x12f>; + }; + + pdm-sdi3-sleep { + rockchip,pins = <0x03 0x1a 0x00 0xb1>; + phandle = <0x130>; + }; + }; + + i2s0 { + + i2s0-8ch-mclk { + rockchip,pins = <0x03 0x11 0x02 0xad>; + phandle = <0x131>; + }; + + i2s0-8ch-sclktx { + rockchip,pins = <0x03 0x13 0x02 0xad>; + phandle = <0x30>; + }; + + i2s0-8ch-sclkrx { + rockchip,pins = <0x03 0x0c 0x02 0xad>; + phandle = <0x31>; + }; + + i2s0-8ch-lrcktx { + rockchip,pins = <0x03 0x12 0x02 0xad>; + phandle = <0x32>; + }; + + i2s0-8ch-lrckrx { + rockchip,pins = <0x03 0x0d 0x02 0xad>; + phandle = <0x33>; + }; + + i2s0-8ch-sdo0 { + rockchip,pins = <0x03 0x14 0x02 0xad>; + phandle = <0x38>; + }; + + i2s0-8ch-sdo1 { + rockchip,pins = <0x03 0x10 0x02 0xad>; + phandle = <0x39>; + }; + + i2s0-8ch-sdo2 { + rockchip,pins = <0x03 0x0f 0x02 0xad>; + phandle = <0x3a>; + }; + + i2s0-8ch-sdo3 { + rockchip,pins = <0x03 0x0e 0x02 0xad>; + phandle = <0x3b>; + }; + + i2s0-8ch-sdi0 { + rockchip,pins = <0x03 0x15 0x02 0xad>; + phandle = <0x34>; + }; + + i2s0-8ch-sdi1 { + rockchip,pins = <0x03 0x0b 0x02 0xad>; + phandle = <0x35>; + }; + + i2s0-8ch-sdi2 { + rockchip,pins = <0x03 0x09 0x02 0xad>; + phandle = <0x36>; + }; + + i2s0-8ch-sdi3 { + rockchip,pins = <0x03 0x08 0x02 0xad>; + phandle = <0x37>; + }; + }; + + i2s1 { + + i2s1-2ch-mclk { + rockchip,pins = <0x02 0x13 0x01 0xad>; + phandle = <0x65>; + }; + + i2s1-2ch-sclk { + rockchip,pins = <0x02 0x12 0x01 0xad>; + phandle = <0x3c>; + }; + + i2s1-2ch-lrck { + rockchip,pins = <0x02 0x11 0x01 0xad>; + phandle = <0x3d>; + }; + + i2s1-2ch-sdi { + rockchip,pins = <0x02 0x15 0x01 0xad>; + phandle = <0x3e>; + }; + + i2s1-2ch-sdo { + rockchip,pins = <0x02 0x14 0x01 0xad>; + phandle = <0x3f>; + }; + }; + + i2s2 { + + i2s2-2ch-mclk { + rockchip,pins = <0x03 0x01 0x02 0xad>; + phandle = <0x132>; + }; + + i2s2-2ch-sclk { + rockchip,pins = <0x03 0x02 0x02 0xad>; + phandle = <0x40>; + }; + + i2s2-2ch-lrck { + rockchip,pins = <0x03 0x03 0x02 0xad>; + phandle = <0x41>; + }; + + i2s2-2ch-sdi { + rockchip,pins = <0x03 0x05 0x02 0xad>; + phandle = <0x42>; + }; + + i2s2-2ch-sdo { + rockchip,pins = <0x03 0x07 0x02 0xad>; + phandle = <0x43>; + }; + }; + + sdmmc { + + sdmmc-clk { + rockchip,pins = <0x01 0x1e 0x01 0xb2>; + phandle = <0x8c>; + }; + + sdmmc-cmd { + rockchip,pins = <0x01 0x1f 0x01 0xb0>; + phandle = <0x8d>; + }; + + sdmmc-det { + rockchip,pins = <0x00 0x03 0x01 0xb0>; + phandle = <0x8e>; + }; + + sdmmc-bus1 { + rockchip,pins = <0x01 0x1a 0x01 0xb0>; + phandle = <0x133>; + }; + + sdmmc-bus4 { + rockchip,pins = <0x01 0x1a 0x01 0xb0 0x01 0x1b 0x01 0xb0 0x01 0x1c 0x01 0xb0 0x01 0x1d 0x01 0xb0>; + phandle = <0x8f>; + }; + + sdmmc-gpio { + rockchip,pins = <0x01 0x1a 0x00 0xaf 0x01 0x1b 0x00 0xaf 0x01 0x1c 0x00 0xaf 0x01 0x1d 0x00 0xaf 0x01 0x1e 0x00 0xaf 0x01 0x1f 0x00 0xaf>; + phandle = <0x134>; + }; + }; + + sdio { + + sdio-clk { + rockchip,pins = <0x01 0x15 0x01 0xad>; + phandle = <0x93>; + }; + + sdio-cmd { + rockchip,pins = <0x01 0x14 0x01 0xae>; + phandle = <0x92>; + }; + + sdio-bus4 { + rockchip,pins = <0x01 0x16 0x01 0xae 0x01 0x17 0x01 0xae 0x01 0x18 0x01 0xae 0x01 0x19 0x01 0xae>; + phandle = <0x91>; + }; + + sdio-gpio { + rockchip,pins = <0x01 0x16 0x00 0xae 0x01 0x17 0x00 0xae 0x01 0x18 0x00 0xae 0x01 0x19 0x00 0xae 0x01 0x14 0x00 0xae 0x01 0x15 0x00 0xae>; + phandle = <0x135>; + }; + }; + + emmc { + + emmc-clk { + rockchip,pins = <0x01 0x09 0x02 0xb2>; + phandle = <0x136>; + }; + + emmc-cmd { + rockchip,pins = <0x01 0x0a 0x02 0xb0>; + phandle = <0x137>; + }; + + emmc-pwren { + rockchip,pins = <0x01 0x08 0x02 0xad>; + phandle = <0x138>; + }; + + emmc-rstnout { + rockchip,pins = <0x01 0x0b 0x02 0xad>; + phandle = <0x139>; + }; + + emmc-bus1 { + rockchip,pins = <0x01 0x00 0x02 0xb0>; + phandle = <0x13a>; + }; + + emmc-bus4 { + rockchip,pins = <0x01 0x00 0x02 0xb0 0x01 0x01 0x02 0xb0 0x01 0x02 0x02 0xb0 0x01 0x03 0x02 0xb0>; + phandle = <0x13b>; + }; + + emmc-bus8 { + rockchip,pins = <0x01 0x00 0x02 0xb0 0x01 0x01 0x02 0xb0 0x01 0x02 0x02 0xb0 0x01 0x03 0x02 0xb0 0x01 0x04 0x02 0xb0 0x01 0x05 0x02 0xb0 0x01 0x06 0x02 0xb0 0x01 0x07 0x02 0xb0>; + phandle = <0x13c>; + }; + }; + + flash { + + flash-cs0 { + rockchip,pins = <0x01 0x08 0x01 0xad>; + phandle = <0x13d>; + }; + + flash-rdy { + rockchip,pins = <0x01 0x09 0x01 0xad>; + phandle = <0x13e>; + }; + + flash-dqs { + rockchip,pins = <0x01 0x0a 0x01 0xad>; + phandle = <0x13f>; + }; + + flash-ale { + rockchip,pins = <0x01 0x0b 0x01 0xad>; + phandle = <0x140>; + }; + + flash-cle { + rockchip,pins = <0x01 0x0c 0x01 0xad>; + phandle = <0x141>; + }; + + flash-wrn { + rockchip,pins = <0x01 0x0d 0x01 0xad>; + phandle = <0x142>; + }; + + flash-csl { + rockchip,pins = <0x01 0x0e 0x01 0xad>; + phandle = <0x143>; + }; + + flash-rdn { + rockchip,pins = <0x01 0x0f 0x01 0xad>; + phandle = <0x144>; + }; + + flash-bus8 { + rockchip,pins = <0x01 0x00 0x01 0xb3 0x01 0x01 0x01 0xb3 0x01 0x02 0x01 0xb3 0x01 0x03 0x01 0xb3 0x01 0x04 0x01 0xb3 0x01 0x05 0x01 0xb3 0x01 0x06 0x01 0xb3 0x01 0x07 0x01 0xb3>; + phandle = <0x145>; + }; + }; + + lcdc { + + lcdc-m0-rgb-pins { + rockchip,pins = <0x03 0x00 0x01 0xb2 0x03 0x01 0x01 0xb2 0x03 0x02 0x01 0xb2 0x03 0x03 0x01 0xb2 0x03 0x04 0x01 0xb2 0x03 0x05 0x01 0xb2 0x03 0x06 0x01 0xb2 0x03 0x07 0x01 0xb2 0x03 0x08 0x01 0xb2 0x03 0x09 0x01 0xb2 0x03 0x0a 0x01 0xb2 0x03 0x0b 0x01 0xb2 0x03 0x0c 0x01 0xb2 0x03 0x0d 0x01 0xb2 0x03 0x0e 0x01 0xb2 0x03 0x0f 0x01 0xb2 0x03 0x10 0x01 0xb2 0x03 0x11 0x01 0xb2 0x03 0x12 0x01 0xb2 0x03 0x13 0x01 0xb2 0x03 0x14 0x01 0xb2 0x03 0x15 0x01 0xb2 0x03 0x16 0x01 0xb2 0x03 0x17 0x01 0xb2 0x03 0x18 0x01 0xb2 0x03 0x19 0x01 0xb2 0x03 0x1a 0x01 0xb2 0x03 0x1b 0x01 0xb2>; + phandle = <0x146>; + }; + + lcdc-m0-sleep-pins { + rockchip,pins = <0x03 0x00 0x00 0xad 0x03 0x01 0x00 0xad 0x03 0x02 0x00 0xad 0x03 0x03 0x00 0xad 0x03 0x04 0x00 0xad 0x03 0x05 0x00 0xad 0x03 0x06 0x00 0xad 0x03 0x07 0x00 0xad 0x03 0x08 0x00 0xad 0x03 0x09 0x00 0xad 0x03 0x0a 0x00 0xad 0x03 0x0b 0x00 0xad 0x03 0x0c 0x00 0xad 0x03 0x0d 0x00 0xad 0x03 0x0e 0x00 0xad 0x03 0x0f 0x00 0xad 0x03 0x10 0x00 0xad 0x03 0x11 0x00 0xad 0x03 0x12 0x00 0xad 0x03 0x13 0x00 0xad 0x03 0x14 0x00 0xad 0x03 0x15 0x00 0xad 0x03 0x16 0x00 0xad 0x03 0x17 0x00 0xad 0x03 0x18 0x00 0xad 0x03 0x19 0x00 0xad 0x03 0x1a 0x00 0xad 0x03 0x1b 0x00 0xad>; + phandle = <0x147>; + }; + + lcdc-m1-rgb-pins { + rockchip,pins = <0x03 0x00 0x01 0xb2 0x03 0x04 0x01 0xb2 0x03 0x06 0x01 0xb2 0x03 0x0a 0x01 0xb2 0x03 0x0b 0x01 0xb2 0x03 0x0d 0x01 0xb2 0x03 0x10 0x01 0xb2 0x03 0x11 0x01 0xb2 0x03 0x12 0x01 0xb2 0x03 0x13 0x01 0xb2 0x03 0x14 0x01 0xb2 0x03 0x15 0x01 0xb2 0x03 0x16 0x01 0xb2 0x03 0x17 0x01 0xb2 0x03 0x18 0x01 0xb2 0x03 0x19 0x01 0xb2 0x03 0x1a 0x01 0xb2 0x03 0x1b 0x01 0xb2>; + phandle = <0x4c>; + }; + + lcdc-m1-sleep-pins { + rockchip,pins = <0x03 0x00 0x00 0xad 0x03 0x04 0x00 0xad 0x03 0x06 0x00 0xad 0x03 0x0a 0x00 0xad 0x03 0x0b 0x00 0xad 0x03 0x0d 0x00 0xad 0x03 0x10 0x00 0xad 0x03 0x11 0x00 0xad 0x03 0x12 0x00 0xad 0x03 0x13 0x00 0xad 0x03 0x14 0x00 0xad 0x03 0x15 0x00 0xad 0x03 0x16 0x00 0xad 0x03 0x17 0x00 0xad 0x03 0x18 0x00 0xad 0x03 0x19 0x00 0xad 0x03 0x1a 0x00 0xad 0x03 0x1b 0x00 0xad>; + phandle = <0x4d>; + }; + }; + + pwm0 { + + pwm0-pin { + rockchip,pins = <0x00 0x0f 0x01 0xad>; + phandle = <0x78>; + }; + }; + + pwm1 { + + pwm1-pin { + rockchip,pins = <0x00 0x10 0x01 0xad>; + phandle = <0x79>; + }; + }; + + pwm2 { + + pwm2-pin { + rockchip,pins = <0x02 0x0d 0x01 0xad>; + phandle = <0x7a>; + }; + }; + + pwm3 { + + pwm3-pin { + rockchip,pins = <0x00 0x11 0x01 0xad>; + phandle = <0x7b>; + }; + }; + + pwm4 { + + pwm4-pin { + rockchip,pins = <0x03 0x12 0x03 0xad>; + phandle = <0x7c>; + }; + }; + + pwm5 { + + pwm5-pin { + rockchip,pins = <0x03 0x13 0x03 0xad>; + phandle = <0x7d>; + }; + }; + + pwm6 { + + pwm6-pin { + rockchip,pins = <0x03 0x14 0x03 0xad>; + phandle = <0x7e>; + }; + }; + + pwm7 { + + pwm7-pin { + rockchip,pins = <0x03 0x15 0x03 0xad>; + phandle = <0x7f>; + }; + }; + + gmac { + + rmii-pins { + rockchip,pins = <0x02 0x00 0x02 0xb4 0x02 0x01 0x02 0xb4 0x02 0x02 0x02 0xb4 0x02 0x03 0x02 0xad 0x02 0x04 0x02 0xad 0x02 0x05 0x02 0xad 0x02 0x06 0x02 0xad 0x02 0x07 0x02 0xad 0x02 0x09 0x02 0xad>; + phandle = <0x8a>; + }; + + mac-refclk-12ma { + rockchip,pins = <0x02 0x0a 0x02 0xb4>; + phandle = <0x8b>; + }; + + mac-refclk { + rockchip,pins = <0x02 0x0a 0x02 0xad>; + phandle = <0x148>; + }; + }; + + cif-m0 { + + cif-clkout-m0 { + rockchip,pins = <0x02 0x0b 0x01 0xb4>; + phandle = <0xa3>; + }; + + dvp-d2d9-m0 { + rockchip,pins = <0x02 0x00 0x01 0xad 0x02 0x01 0x01 0xad 0x02 0x02 0x01 0xad 0x02 0x03 0x01 0xad 0x02 0x04 0x01 0xad 0x02 0x05 0x01 0xad 0x02 0x06 0x01 0xad 0x02 0x07 0x01 0xad 0x02 0x08 0x01 0xad 0x02 0x09 0x01 0xad 0x02 0x0a 0x01 0xad 0x02 0x0b 0x01 0xad>; + phandle = <0xa1>; + }; + + dvp-d0d1-m0 { + rockchip,pins = <0x02 0x0c 0x01 0xad 0x02 0x0e 0x01 0xad>; + phandle = <0xa5>; + }; + + d10-d11-m0 { + rockchip,pins = <0x02 0x0f 0x01 0xad 0x02 0x10 0x01 0xad>; + phandle = <0xa4>; + }; + }; + + cif-m1 { + + cif-clkout-m1 { + rockchip,pins = <0x03 0x18 0x03 0xad>; + phandle = <0x149>; + }; + + dvp-d2d9-m1 { + rockchip,pins = <0x03 0x03 0x03 0xad 0x03 0x05 0x03 0xad 0x03 0x07 0x03 0xad 0x03 0x08 0x03 0xad 0x03 0x09 0x03 0xad 0x03 0x0c 0x03 0xad 0x03 0x0e 0x03 0xad 0x03 0x0f 0x03 0xad 0x03 0x19 0x03 0xad 0x03 0x1a 0x03 0xad 0x03 0x1b 0x03 0xad 0x03 0x18 0x03 0xad>; + phandle = <0x14a>; + }; + + dvp-d0d1-m1 { + rockchip,pins = <0x03 0x01 0x03 0xad 0x03 0x02 0x03 0xad>; + phandle = <0x14b>; + }; + + d10-d11-m1 { + rockchip,pins = <0x03 0x17 0x03 0xad>; + phandle = <0x14c>; + }; + }; + + isp { + + isp-prelight { + rockchip,pins = <0x03 0x19 0x04 0xad>; + phandle = <0x14d>; + }; + }; + + pmic { + + pmic_int { + rockchip,pins = <0x00 0x07 0x00 0xae 0x03 0x17 0x00 0xad>; + phandle = <0x5a>; + }; + + soc_slppin_gpio { + rockchip,pins = <0x00 0x04 0x00 0xb5>; + phandle = <0x5d>; + }; + + soc_slppin_slp { + rockchip,pins = <0x00 0x04 0x01 0xad>; + phandle = <0x5b>; + }; + + soc_slppin_rst { + rockchip,pins = <0x00 0x04 0x02 0xad>; + phandle = <0x5f>; + }; + }; + + headphone { + + hp-det { + rockchip,pins = <0x02 0x16 0x00 0xad>; + phandle = <0xc0>; + }; + }; + + leds { + + led-pins { + rockchip,pins = <0x00 0x01 0x00 0xad>; + phandle = <0xbb>; + }; + }; + + btns { + + btn-pins { + rockchip,pins = <0x03 0x0c 0x00 0xae 0x01 0x0d 0x00 0xae 0x03 0x0e 0x00 0xae 0x01 0x0f 0x00 0xae 0x01 0x02 0x00 0xae 0x01 0x05 0x00 0xae 0x01 0x06 0x00 0xae 0x01 0x07 0x00 0xae 0x02 0x00 0x00 0xae 0x02 0x01 0x00 0xae 0x02 0x02 0x00 0xae 0x02 0x03 0x00 0xae 0x02 0x04 0x00 0xae 0x02 0x05 0x00 0xae 0x02 0x06 0x00 0xae 0x02 0x07 0x00 0xae 0x00 0x0f 0x00 0xae 0x03 0x0a 0x00 0xae>; + phandle = <0xb9>; + }; + }; + }; + + chosen { + bootargs = [00]; + }; + + fiq-debugger { + compatible = "rockchip,fiq-debugger"; + rockchip,serial-id = <0x02>; + rockchip,wake-irq = <0x00>; + rockchip,irq-mode-enable = <0x00>; + rockchip,baudrate = <0x16e360>; + interrupts = <0x00 0x7f 0x08>; + pinctrl-names = "default"; + pinctrl-0 = <0xb6>; + status = "okay"; + }; + + ramoops { + compatible = "ramoops"; + record-size = <0x00 0x20000>; + console-size = <0x00 0x80000>; + ftrace-size = <0x00 0x00>; + pmsg-size = <0x00 0x00>; + memory-region = <0xb7>; + }; + + reserved-memory { + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + + drm-logo@00000000 { + compatible = "rockchip,drm-logo"; + reg = <0x00 0x00 0x00 0x00>; + phandle = <0x11>; + }; + + region@110000 { + reg = <0x00 0x110000 0x00 0xf0000>; + reg-names = "ramoops_mem"; + phandle = <0xb7>; + }; + }; + + odroidgo3-keys { + compatible = "gpio-keys"; + #address-cells = <0x01>; + #size-cells = <0x00>; + autorepeat; + phandle = <0x14e>; + + button@0 { + label = "GPIO BTN-VOLUP"; + linux,code = <0x73>; + gpios = <0x63 0x16 0x01>; + }; + + button@1 { + label = "GPIO BTN-VOLDN"; + linux,code = <0x72>; + gpios = <0x63 0x15 0x01>; + }; + }; + + odroidgo3-joypad { + compatible = "odroidgo3-joypad"; + pwms = <0xb8 0x00 0xbebc200 0x00>; + pwm-names = "enable"; + rumble-boost-weak = <0x00>; + rumble-boost-strong = <0x00>; + joypad-name = "GO-Super Gamepad"; + joypad-product = <0x1100>; + joypad-revision = <0x100>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <0xb9>; + pinctrl-1 = <0x78>; + io-channel-names = "amux_adc"; + io-channels = <0xba 0x01>; + amux-count = <0x04>; + amux-a-gpios = <0x59 0x0d 0x01>; + amux-b-gpios = <0x59 0x0c 0x01>; + amux-en-gpios = <0x59 0x11 0x01>; + button-adc-scale = <0x02>; + button-adc-deadzone = <0x40>; + button-adc-fuzz = <0x20>; + button-adc-flat = <0x20>; + abs_x-p-tuning = <0xc8>; + abs_x-n-tuning = <0xc8>; + abs_y-p-tuning = <0xc8>; + abs_y-n-tuning = <0xc8>; + abs_rx-p-tuning = <0xc8>; + abs_rx-n-tuning = <0xc8>; + abs_ry-p-tuning = <0xc8>; + abs_ry-n-tuning = <0xc8>; + poll-interval = <0x0a>; + invert-absx; + invert-absy; + phandle = <0x14f>; + + sw1 { + gpios = <0x63 0x07 0x01>; + label = "GPIO DPAD-UP"; + linux,code = <0x220>; + }; + + sw2 { + gpios = <0x63 0x08 0x01>; + label = "GPIO DPAD-DOWN"; + linux,code = <0x221>; + }; + + sw3 { + gpios = <0x63 0x0a 0x01>; + label = "GPIO DPAD-LEFT"; + linux,code = <0x222>; + }; + + sw4 { + gpios = <0x63 0x09 0x01>; + label = "GPIO DPAD-RIGHT"; + linux,code = <0x223>; + }; + + sw5 { + gpios = <0x63 0x0e 0x01>; + label = "GPIO KEY BTN-A"; + linux,code = <0x131>; + }; + + sw6 { + gpios = <0x63 0x0c 0x01>; + label = "GPIO BTN-B"; + linux,code = <0x130>; + }; + + sw7 { + gpios = <0x63 0x0b 0x01>; + label = "GPIO BTN-Y"; + linux,code = <0x134>; + }; + + sw8 { + gpios = <0x63 0x0d 0x01>; + label = "GPIO BTN-X"; + linux,code = <0x133>; + }; + + sw11 { + gpios = <0x59 0x0b 0x01>; + label = "GPIO F3"; + linux,code = <0x2c2>; + }; + + sw12 { + gpios = <0x63 0x1b 0x01>; + label = "GPIO F4"; + linux,code = <0x2c3>; + }; + + sw15 { + gpios = <0x63 0x03 0x01>; + label = "GPIO TOP-LEFT"; + linux,code = <0x136>; + }; + + sw16 { + gpios = <0x63 0x00 0x01>; + label = "GPIO TOP-RIGHT"; + linux,code = <0x137>; + }; + + sw19 { + gpios = <0x63 0x04 0x01>; + label = "GPIO F1"; + linux,code = <0x2c4>; + }; + + sw20 { + gpios = <0x63 0x02 0x01>; + label = "GPIO TOP-LEFT2"; + linux,code = <0x138>; + }; + + sw21 { + gpios = <0x63 0x01 0x01>; + label = "GPIO TOP-RIGHT2"; + linux,code = <0x139>; + }; + + sw22 { + gpios = <0x63 0x06 0x01>; + label = "GPIO F2"; + linux,code = <0x2c1>; + }; + + sw13 { + gpios = <0x63 0x05 0x01>; + label = "GPIO F5"; + linux,code = <0x2c0>; + }; + }; + + gpio_leds { + status = "disabled"; + compatible = "gpio-leds"; + pinctrl-names = "led_pins"; + pinctrl-0 = <0xbb>; + phandle = <0x150>; + + heartbeat { + label = "blue:heartbeat"; + gpios = <0x59 0x01 0x00>; + linux,default-trigger = "heartbeat"; + }; + }; + + backlight { + compatible = "pwm-backlight"; + pwms = <0xbc 0x00 0x9c40 0x00>; + brightness-levels = <0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2a 0x2b 0x2c 0x2d 0x2e 0x2f 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x3a 0x3b 0x3c 0x3d 0x3e 0x3f 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48 0x49 0x4a 0x4b 0x4c 0x4d 0x4e 0x4f 0x50 0x51 0x52 0x53 0x54 0x55 0x56 0x57 0x58 0x59 0x5a 0x5b 0x5c 0x5d 0x5e 0x5f 0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69 0x6a 0x6b 0x6c 0x6d 0x6e 0x6f 0x70 0x71 0x72 0x73 0x74 0x75 0x76 0x77 0x78 0x79 0x7a 0x7b 0x7c 0x7d 0x7e 0x7f 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90 0x91 0x92 0x93 0x94 0x95 0x96 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f 0xa0>; + default-brightness-level = <0x50>; + phandle = <0x99>; + }; + + rk817-sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,name = "rockchip,rk817-codec"; + simple-audio-card,mclk-fs = <0x100>; + simple-audio-card,widgets = "Microphone\0Mic Jack\0Headphone\0Headphone Jack"; + simple-audio-card,routing = "MIC_IN\0Mic Jack\0Headphone Jack\0HPOL\0Headphone Jack\0HPOR"; + + simple-audio-card,cpu { + sound-dai = <0xbd>; + }; + + simple-audio-card,codec { + sound-dai = <0xbe>; + }; + }; + + rk_headset { + compatible = "rockchip_headset"; + headset_gpio = <0xbf 0x16 0x00>; + pinctrl-names = "default"; + pinctrl-0 = <0xc0>; + }; + + vccsys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v8_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x39fbc0>; + regulator-max-microvolt = <0x39fbc0>; + phandle = <0x61>; + }; + + __symbols__ { + ddr_timing = "/ddr_timing"; + cpu0 = "/cpus/cpu@0"; + cpu1 = "/cpus/cpu@1"; + cpu2 = "/cpus/cpu@2"; + cpu3 = "/cpus/cpu@3"; + CPU_SLEEP = "/cpus/idle-states/cpu-sleep"; + CLUSTER_SLEEP = "/cpus/idle-states/cluster-sleep"; + cpu0_opp_table = "/cpu0-opp-table"; + bus_soc = "/bus-soc"; + bus_apll = "/bus-apll"; + bus_apll_opp_table = "/bus-apll-opp-table"; + display_subsystem = "/display-subsystem"; + route_lvds = "/display-subsystem/route/route-lvds"; + route_dsi = "/display-subsystem/route/route-dsi"; + route_rgb = "/display-subsystem/route/route-rgb"; + gmac_clkin = "/external-gmac-clock"; + rockchip_suspend = "/rockchip-suspend"; + xin24m = "/xin24m"; + xin32k = "/xin32k"; + pmu = "/power-management@ff000000"; + power = "/power-management@ff000000/power-controller"; + pmugrf = "/syscon@ff010000"; + pmu_io_domains = "/syscon@ff010000/io-domains"; + pmu_pvtm = "/syscon@ff010000/pmu-pvtm"; + uart0 = "/serial@ff030000"; + i2s0_8ch = "/i2s@ff060000"; + i2s1_2ch = "/i2s@ff070000"; + i2s2_2ch = "/i2s@ff080000"; + pdm = "/pdm@ff0a0000"; + crypto = "/crypto@ff0b0000"; + rng = "/rng@ff0b0000"; + gic = "/interrupt-controller@ff131000"; + grf = "/syscon@ff140000"; + io_domains = "/syscon@ff140000/io-domains"; + lvds = "/syscon@ff140000/lvds"; + lvds_in_vopb = "/syscon@ff140000/lvds/ports/port@0/endpoint@0"; + rgb = "/syscon@ff140000/rgb"; + rgb_in_vopb = "/syscon@ff140000/rgb/ports/port@0/endpoint@0"; + core_grf = "/syscon@ff148000"; + pvtm = "/syscon@ff148000/pvtm"; + uart1 = "/serial@ff158000"; + uart2 = "/serial@ff160000"; + uart3 = "/serial@ff168000"; + uart4 = "/serial@ff170000"; + uart5 = "/serial@ff178000"; + i2c0 = "/i2c@ff180000"; + rk817 = "/i2c@ff180000/pmic@20"; + pinctrl_rk8xx = "/i2c@ff180000/pmic@20/pinctrl_rk8xx"; + rk817_ts_gpio1 = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_ts_gpio1"; + rk817_gt_gpio2 = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_gt_gpio2"; + rk817_pin_ts = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_pin_ts"; + rk817_pin_gt = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_pin_gt"; + rk817_slppin_null = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_null"; + rk817_slppin_slp = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_slp"; + rk817_slppin_pwrdn = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_pwrdn"; + rk817_slppin_rst = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_rst"; + vdd_logic = "/i2c@ff180000/pmic@20/regulators/DCDC_REG1"; + vdd_arm = "/i2c@ff180000/pmic@20/regulators/DCDC_REG2"; + vcc_ddr = "/i2c@ff180000/pmic@20/regulators/DCDC_REG3"; + vcc_3v3 = "/i2c@ff180000/pmic@20/regulators/DCDC_REG4"; + vcc_1v0 = "/i2c@ff180000/pmic@20/regulators/LDO_REG1"; + vcc1v8_soc = "/i2c@ff180000/pmic@20/regulators/LDO_REG2"; + vdd1v0_soc = "/i2c@ff180000/pmic@20/regulators/LDO_REG3"; + vcc3v3_pmu = "/i2c@ff180000/pmic@20/regulators/LDO_REG4"; + vccio_sd = "/i2c@ff180000/pmic@20/regulators/LDO_REG5"; + vcc_sd = "/i2c@ff180000/pmic@20/regulators/LDO_REG6"; + vcc2v8_dvp = "/i2c@ff180000/pmic@20/regulators/LDO_REG7"; + vcc_lcd = "/i2c@ff180000/pmic@20/regulators/LDO_REG8"; + vdd_11 = "/i2c@ff180000/pmic@20/regulators/LDO_REG9"; + dcdc_boost = "/i2c@ff180000/pmic@20/regulators/BOOST"; + otg_switch = "/i2c@ff180000/pmic@20/regulators/OTG_SWITCH"; + rk817_codec = "/i2c@ff180000/pmic@20/codec"; + i2c1 = "/i2c@ff190000"; + i2c2 = "/i2c@ff1a0000"; + i2c3 = "/i2c@ff1b0000"; + spi0 = "/spi@ff1d0000"; + spi1 = "/spi@ff1d8000"; + wdt = "/watchdog@ff1e0000"; + pwm0 = "/pwm@ff200000"; + pwm1 = "/pwm@ff200010"; + pwm2 = "/pwm@ff200020"; + pwm3 = "/pwm@ff200030"; + pwm4 = "/pwm@ff208000"; + pwm5 = "/pwm@ff208010"; + pwm6 = "/pwm@ff208020"; + pwm7 = "/pwm@ff208030"; + rktimer = "/rktimer@ff210000"; + dmac = "/amba/dmac@ff240000"; + thermal_zones = "/thermal-zones"; + soc_thermal = "/thermal-zones/soc-thermal"; + threshold = "/thermal-zones/soc-thermal/trips/trip-point-0"; + target = "/thermal-zones/soc-thermal/trips/trip-point-1"; + soc_crit = "/thermal-zones/soc-thermal/trips/soc-crit"; + gpu_thermal = "/thermal-zones/gpu-thermal"; + tsadc = "/tsadc@ff280000"; + saradc = "/saradc@ff288000"; + otp = "/otp@ff290000"; + otp_id = "/otp@ff290000/id@7"; + cpu_leakage = "/otp@ff290000/cpu-leakage@17"; + performance = "/otp@ff290000/performance@1e"; + cru = "/clock-controller@ff2b0000"; + cpu_boost = "/cpu-boost@ff2b8000"; + pmucru = "/pmu-clock-controller@ff2bc000"; + usb2phy_grf = "/syscon@ff2c0000"; + u2phy = "/syscon@ff2c0000/usb2-phy@100"; + u2phy_host = "/syscon@ff2c0000/usb2-phy@100/host-port"; + u2phy_otg = "/syscon@ff2c0000/usb2-phy@100/otg-port"; + video_phy = "/video-phy@ff2e0000"; + mipi_dphy_rx0 = "/mipi-dphy-rx0@ff2f0000"; + usb20_otg = "/usb@ff300000"; + usb_host0_ehci = "/usb@ff340000"; + usb_host0_ohci = "/usb@ff350000"; + gmac = "/ethernet@ff360000"; + sdmmc = "/dwmmc@ff370000"; + sdio = "/dwmmc@ff380000"; + emmc = "/dwmmc@ff390000"; + nandc0 = "/nandc@ff3b0000"; + sfc = "/sfc@ff3a0000"; + gpu = "/gpu@ff400000"; + gpu_opp_table = "/gpu-opp-table"; + hevc = "/hevc_service@ff440000"; + vpu = "/vpu_service@ff442000"; + vpu_combo = "/vpu_combo"; + hevc_mmu = "/iommu@ff440440"; + vpu_mmu = "/iommu@ff442800"; + dsi = "/dsi@ff450000"; + dsi_in_vopb = "/dsi@ff450000/ports/port@0/endpoint@0"; + timing0 = "/dsi@ff450000/panel@0/display-timings/60Hz"; + timing1 = "/dsi@ff450000/panel@0/display-timings/50Hz"; + timing2 = "/dsi@ff450000/panel@0/display-timings/75Hz"; + vopb = "/vop@ff460000"; + vopb_out = "/vop@ff460000/port"; + vopb_out_lvds = "/vop@ff460000/port/endpoint@0"; + vopb_out_dsi = "/vop@ff460000/port/endpoint@1"; + vopb_out_rgb = "/vop@ff460000/port/endpoint@2"; + vopb_mmu = "/iommu@ff460f00"; + rk_rga = "/rk_rga@ff480000"; + cif = "/cif@ff490000"; + cif_new = "/cif-new@ff490000"; + vip_mmu = "/iommu@ff490800"; + rk_isp = "/rk_isp@ff4a0000"; + rkisp1 = "/rkisp1@ff4a0000"; + isp_mmu = "/iommu@ff4a8000"; + qos_gmac = "/qos@ff518000"; + qos_gpu = "/qos@ff520000"; + qos_sdmmc = "/qos@ff52c000"; + qos_emmc = "/qos@ff538000"; + qos_nand = "/qos@ff538080"; + qos_sdio = "/qos@ff538100"; + qos_sfc = "/qos@ff538180"; + qos_usb_host = "/qos@ff540000"; + qos_usb_otg = "/qos@ff540080"; + qos_isp_128 = "/qos@ff548000"; + qos_isp_rd = "/qos@ff548080"; + qos_isp_wr = "/qos@ff548100"; + qos_isp_m1 = "/qos@ff548180"; + qos_vip = "/qos@ff548200"; + qos_rga_rd = "/qos@ff550000"; + qos_rga_wr = "/qos@ff550080"; + qos_vop_m0 = "/qos@ff550100"; + qos_vop_m1 = "/qos@ff550180"; + qos_vpu = "/qos@ff558000"; + qos_vpu_r128 = "/qos@ff558080"; + dfi = "/dfi@ff610000"; + dmc = "/dmc"; + ddr_power_model = "/dmc/ddr_power_model"; + dmc_opp_table = "/dmc-opp-table"; + rockchip_system_monitor = "/rockchip-system-monitor"; + pinctrl = "/pinctrl"; + gpio0 = "/pinctrl/gpio0@ff040000"; + gpio1 = "/pinctrl/gpio1@ff250000"; + gpio2 = "/pinctrl/gpio2@ff260000"; + gpio3 = "/pinctrl/gpio3@ff270000"; + pcfg_pull_up = "/pinctrl/pcfg-pull-up"; + pcfg_pull_down = "/pinctrl/pcfg-pull-down"; + pcfg_pull_none = "/pinctrl/pcfg-pull-none"; + pcfg_pull_none_2ma = "/pinctrl/pcfg-pull-none-2ma"; + pcfg_pull_up_2ma = "/pinctrl/pcfg-pull-up-2ma"; + pcfg_pull_up_4ma = "/pinctrl/pcfg-pull-up-4ma"; + pcfg_pull_none_4ma = "/pinctrl/pcfg-pull-none-4ma"; + pcfg_pull_down_4ma = "/pinctrl/pcfg-pull-down-4ma"; + pcfg_pull_none_8ma = "/pinctrl/pcfg-pull-none-8ma"; + pcfg_pull_up_8ma = "/pinctrl/pcfg-pull-up-8ma"; + pcfg_pull_none_12ma = "/pinctrl/pcfg-pull-none-12ma"; + pcfg_pull_up_12ma = "/pinctrl/pcfg-pull-up-12ma"; + pcfg_pull_none_smt = "/pinctrl/pcfg-pull-none-smt"; + pcfg_output_high = "/pinctrl/pcfg-output-high"; + pcfg_output_low = "/pinctrl/pcfg-output-low"; + pcfg_input_high = "/pinctrl/pcfg-input-high"; + pcfg_input = "/pinctrl/pcfg-input"; + i2c0_xfer = "/pinctrl/i2c0/i2c0-xfer"; + i2c1_xfer = "/pinctrl/i2c1/i2c1-xfer"; + i2c2_xfer = "/pinctrl/i2c2/i2c2-xfer"; + i2c3_xfer = "/pinctrl/i2c3/i2c3-xfer"; + tsadc_otp_gpio = "/pinctrl/tsadc/tsadc-otp-gpio"; + tsadc_otp_out = "/pinctrl/tsadc/tsadc-otp-out"; + uart0_xfer = "/pinctrl/uart0/uart0-xfer"; + uart0_cts = "/pinctrl/uart0/uart0-cts"; + uart0_rts = "/pinctrl/uart0/uart0-rts"; + uart0_rts_gpio = "/pinctrl/uart0/uart0-rts-gpio"; + uart1_xfer = "/pinctrl/uart1/uart1-xfer"; + uart1_cts = "/pinctrl/uart1/uart1-cts"; + uart1_rts = "/pinctrl/uart1/uart1-rts"; + uart1_rts_gpio = "/pinctrl/uart1/uart1-rts-gpio"; + uart2m0_xfer = "/pinctrl/uart2-m0/uart2m0-xfer"; + uart2m1_xfer = "/pinctrl/uart2-m1/uart2m1-xfer"; + uart3m0_xfer = "/pinctrl/uart3-m0/uart3m0-xfer"; + uart3m0_cts = "/pinctrl/uart3-m0/uart3m0-cts"; + uart3m0_rts = "/pinctrl/uart3-m0/uart3m0-rts"; + uart3m0_rts_gpio = "/pinctrl/uart3-m0/uart3m0-rts-gpio"; + uart3m1_xfer = "/pinctrl/uart3-m1/uart3m1-xfer"; + uart3m1_cts = "/pinctrl/uart3-m1/uart3m1-cts"; + uart3m1_rts = "/pinctrl/uart3-m1/uart3m1-rts"; + uart3m1_rts_gpio = "/pinctrl/uart3-m1/uart3m1-rts-gpio"; + uart4_xfer = "/pinctrl/uart4/uart4-xfer"; + uart4_cts = "/pinctrl/uart4/uart4-cts"; + uart4_rts = "/pinctrl/uart4/uart4-rts"; + uart5_xfer = "/pinctrl/uart5/uart5-xfer"; + uart5_cts = "/pinctrl/uart5/uart5-cts"; + uart5_rts = "/pinctrl/uart5/uart5-rts"; + spi0_clk = "/pinctrl/spi0/spi0-clk"; + spi0_csn = "/pinctrl/spi0/spi0-csn"; + spi0_miso = "/pinctrl/spi0/spi0-miso"; + spi0_mosi = "/pinctrl/spi0/spi0-mosi"; + spi0_clk_hs = "/pinctrl/spi0/spi0-clk-hs"; + spi0_miso_hs = "/pinctrl/spi0/spi0-miso-hs"; + spi0_mosi_hs = "/pinctrl/spi0/spi0-mosi-hs"; + spi1_clk = "/pinctrl/spi1/spi1-clk"; + spi1_csn0 = "/pinctrl/spi1/spi1-csn0"; + spi1_csn1 = "/pinctrl/spi1/spi1-csn1"; + spi1_miso = "/pinctrl/spi1/spi1-miso"; + spi1_mosi = "/pinctrl/spi1/spi1-mosi"; + spi1_clk_hs = "/pinctrl/spi1/spi1-clk-hs"; + spi1_miso_hs = "/pinctrl/spi1/spi1-miso-hs"; + spi1_mosi_hs = "/pinctrl/spi1/spi1-mosi-hs"; + pdm_clk0m1 = "/pinctrl/pdm/pdm-clk0m1"; + pdm_clk1 = "/pinctrl/pdm/pdm-clk1"; + pdm_sdi0m0 = "/pinctrl/pdm/pdm-sdi0m0"; + pdm_sdi0m1 = "/pinctrl/pdm/pdm-sdi0m1"; + pdm_sdi1 = "/pinctrl/pdm/pdm-sdi1"; + pdm_sdi2 = "/pinctrl/pdm/pdm-sdi2"; + pdm_sdi3 = "/pinctrl/pdm/pdm-sdi3"; + pdm_clk0m_sleep1 = "/pinctrl/pdm/pdm-clk0m1-sleep"; + pdm_clk1_sleep = "/pinctrl/pdm/pdm-clk1-sleep"; + pdm_sdi0m0_sleep = "/pinctrl/pdm/pdm-sdi0m0-sleep"; + pdm_sdi0m1_sleep = "/pinctrl/pdm/pdm-sdi0m1-sleep"; + pdm_sdi1_sleep = "/pinctrl/pdm/pdm-sdi1-sleep"; + pdm_sdi2_sleep = "/pinctrl/pdm/pdm-sdi2-sleep"; + pdm_sdi3_sleep = "/pinctrl/pdm/pdm-sdi3-sleep"; + i2s0_8ch_mclk = "/pinctrl/i2s0/i2s0-8ch-mclk"; + i2s0_8ch_sclktx = "/pinctrl/i2s0/i2s0-8ch-sclktx"; + i2s0_8ch_sclkrx = "/pinctrl/i2s0/i2s0-8ch-sclkrx"; + i2s0_8ch_lrcktx = "/pinctrl/i2s0/i2s0-8ch-lrcktx"; + i2s0_8ch_lrckrx = "/pinctrl/i2s0/i2s0-8ch-lrckrx"; + i2s0_8ch_sdo0 = "/pinctrl/i2s0/i2s0-8ch-sdo0"; + i2s0_8ch_sdo1 = "/pinctrl/i2s0/i2s0-8ch-sdo1"; + i2s0_8ch_sdo2 = "/pinctrl/i2s0/i2s0-8ch-sdo2"; + i2s0_8ch_sdo3 = "/pinctrl/i2s0/i2s0-8ch-sdo3"; + i2s0_8ch_sdi0 = "/pinctrl/i2s0/i2s0-8ch-sdi0"; + i2s0_8ch_sdi1 = "/pinctrl/i2s0/i2s0-8ch-sdi1"; + i2s0_8ch_sdi2 = "/pinctrl/i2s0/i2s0-8ch-sdi2"; + i2s0_8ch_sdi3 = "/pinctrl/i2s0/i2s0-8ch-sdi3"; + i2s1_2ch_mclk = "/pinctrl/i2s1/i2s1-2ch-mclk"; + i2s1_2ch_sclk = "/pinctrl/i2s1/i2s1-2ch-sclk"; + i2s1_2ch_lrck = "/pinctrl/i2s1/i2s1-2ch-lrck"; + i2s1_2ch_sdi = "/pinctrl/i2s1/i2s1-2ch-sdi"; + i2s1_2ch_sdo = "/pinctrl/i2s1/i2s1-2ch-sdo"; + i2s2_2ch_mclk = "/pinctrl/i2s2/i2s2-2ch-mclk"; + i2s2_2ch_sclk = "/pinctrl/i2s2/i2s2-2ch-sclk"; + i2s2_2ch_lrck = "/pinctrl/i2s2/i2s2-2ch-lrck"; + i2s2_2ch_sdi = "/pinctrl/i2s2/i2s2-2ch-sdi"; + i2s2_2ch_sdo = "/pinctrl/i2s2/i2s2-2ch-sdo"; + sdmmc_clk = "/pinctrl/sdmmc/sdmmc-clk"; + sdmmc_cmd = "/pinctrl/sdmmc/sdmmc-cmd"; + sdmmc_det = "/pinctrl/sdmmc/sdmmc-det"; + sdmmc_bus1 = "/pinctrl/sdmmc/sdmmc-bus1"; + sdmmc_bus4 = "/pinctrl/sdmmc/sdmmc-bus4"; + sdmmc_gpio = "/pinctrl/sdmmc/sdmmc-gpio"; + sdio_clk = "/pinctrl/sdio/sdio-clk"; + sdio_cmd = "/pinctrl/sdio/sdio-cmd"; + sdio_bus4 = "/pinctrl/sdio/sdio-bus4"; + sdio_gpio = "/pinctrl/sdio/sdio-gpio"; + emmc_clk = "/pinctrl/emmc/emmc-clk"; + emmc_cmd = "/pinctrl/emmc/emmc-cmd"; + emmc_pwren = "/pinctrl/emmc/emmc-pwren"; + emmc_rstnout = "/pinctrl/emmc/emmc-rstnout"; + emmc_bus1 = "/pinctrl/emmc/emmc-bus1"; + emmc_bus4 = "/pinctrl/emmc/emmc-bus4"; + emmc_bus8 = "/pinctrl/emmc/emmc-bus8"; + flash_cs0 = "/pinctrl/flash/flash-cs0"; + flash_rdy = "/pinctrl/flash/flash-rdy"; + flash_dqs = "/pinctrl/flash/flash-dqs"; + flash_ale = "/pinctrl/flash/flash-ale"; + flash_cle = "/pinctrl/flash/flash-cle"; + flash_wrn = "/pinctrl/flash/flash-wrn"; + flash_csl = "/pinctrl/flash/flash-csl"; + flash_rdn = "/pinctrl/flash/flash-rdn"; + flash_bus8 = "/pinctrl/flash/flash-bus8"; + lcdc_m0_rgb_pins = "/pinctrl/lcdc/lcdc-m0-rgb-pins"; + lcdc_m0_sleep_pins = "/pinctrl/lcdc/lcdc-m0-sleep-pins"; + lcdc_m1_rgb_pins = "/pinctrl/lcdc/lcdc-m1-rgb-pins"; + lcdc_m1_sleep_pins = "/pinctrl/lcdc/lcdc-m1-sleep-pins"; + pwm0_pin = "/pinctrl/pwm0/pwm0-pin"; + pwm1_pin = "/pinctrl/pwm1/pwm1-pin"; + pwm2_pin = "/pinctrl/pwm2/pwm2-pin"; + pwm3_pin = "/pinctrl/pwm3/pwm3-pin"; + pwm4_pin = "/pinctrl/pwm4/pwm4-pin"; + pwm5_pin = "/pinctrl/pwm5/pwm5-pin"; + pwm6_pin = "/pinctrl/pwm6/pwm6-pin"; + pwm7_pin = "/pinctrl/pwm7/pwm7-pin"; + rmii_pins = "/pinctrl/gmac/rmii-pins"; + mac_refclk_12ma = "/pinctrl/gmac/mac-refclk-12ma"; + mac_refclk = "/pinctrl/gmac/mac-refclk"; + cif_clkout_m0 = "/pinctrl/cif-m0/cif-clkout-m0"; + dvp_d2d9_m0 = "/pinctrl/cif-m0/dvp-d2d9-m0"; + dvp_d0d1_m0 = "/pinctrl/cif-m0/dvp-d0d1-m0"; + dvp_d10d11_m0 = "/pinctrl/cif-m0/d10-d11-m0"; + cif_clkout_m1 = "/pinctrl/cif-m1/cif-clkout-m1"; + dvp_d2d9_m1 = "/pinctrl/cif-m1/dvp-d2d9-m1"; + dvp_d0d1_m1 = "/pinctrl/cif-m1/dvp-d0d1-m1"; + dvp_d10d11_m1 = "/pinctrl/cif-m1/d10-d11-m1"; + isp_prelight = "/pinctrl/isp/isp-prelight"; + pmic_int = "/pinctrl/pmic/pmic_int"; + soc_slppin_gpio = "/pinctrl/pmic/soc_slppin_gpio"; + soc_slppin_slp = "/pinctrl/pmic/soc_slppin_slp"; + soc_slppin_rst = "/pinctrl/pmic/soc_slppin_rst"; + hp_det = "/pinctrl/headphone/hp-det"; + led_pins = "/pinctrl/leds/led-pins"; + btn_pins = "/pinctrl/btns/btn-pins"; + drm_logo = "/reserved-memory/drm-logo@00000000"; + ramoops_mem = "/reserved-memory/region@110000"; + gpio_keys = "/odroidgo3-keys"; + joypad = "/odroidgo3-joypad"; + leds = "/gpio_leds"; + backlight = "/backlight"; + vccsys = "/vccsys"; + }; +}; diff --git a/config/archr-dts/R36S-DTB/DTS/R35S-Rumble.dts b/config/archr-dts/R36S-DTB/DTS/R35S-Rumble.dts new file mode 100644 index 0000000000..5d5f9b1a61 --- /dev/null +++ b/config/archr-dts/R36S-DTB/DTS/R35S-Rumble.dts @@ -0,0 +1,4071 @@ +/dts-v1/; + +/ { + compatible = "rockchip,rk3326-odroidgo3-linux\0rockchip,rk3326"; + interrupt-parent = <0x01>; + #address-cells = <0x02>; + #size-cells = <0x02>; + model = "Game Console R35S/R36S fix by lxc"; + + ddr_timing { + compatible = "rockchip,ddr-timing"; + ddr2_speed_bin = <0x00>; + ddr3_speed_bin = <0x15>; + ddr4_speed_bin = <0x0c>; + pd_idle = <0x0d>; + sr_idle = <0x5d>; + sr_mc_gate_idle = <0x00>; + srpd_lite_idle = <0x00>; + standby_idle = <0x00>; + auto_pd_dis_freq = <0x42a>; + auto_sr_dis_freq = <0x320>; + ddr2_dll_dis_freq = <0x12c>; + ddr3_dll_dis_freq = <0x12c>; + ddr4_dll_dis_freq = <0x271>; + phy_dll_dis_freq = <0x190>; + ddr2_odt_dis_freq = <0x64>; + phy_ddr2_odt_dis_freq = <0x64>; + ddr2_drv = <0x01>; + ddr2_odt = <0x96>; + phy_ddr2_ca_drv = <0x15>; + phy_ddr2_ck_drv = <0x12>; + phy_ddr2_dq_drv = <0x15>; + phy_ddr2_odt = <0x02>; + ddr3_odt_dis_freq = <0x190>; + phy_ddr3_odt_dis_freq = <0x190>; + ddr3_drv = <0x28>; + ddr3_odt = <0x78>; + phy_ddr3_ca_drv = <0x15>; + phy_ddr3_ck_drv = <0x12>; + phy_ddr3_dq_drv = <0x15>; + phy_ddr3_odt = <0x02>; + phy_lpddr2_odt_dis_freq = <0x29a>; + lpddr2_drv = <0x28>; + phy_lpddr2_ca_drv = <0x16>; + phy_lpddr2_ck_drv = <0x13>; + phy_lpddr2_dq_drv = <0x16>; + phy_lpddr2_odt = <0x00>; + lpddr3_odt_dis_freq = <0x190>; + phy_lpddr3_odt_dis_freq = <0x190>; + lpddr3_drv = <0x28>; + lpddr3_odt = <0xf0>; + phy_lpddr3_ca_drv = <0x16>; + phy_lpddr3_ck_drv = <0x13>; + phy_lpddr3_dq_drv = <0x16>; + phy_lpddr3_odt = <0x02>; + lpddr4_odt_dis_freq = <0x320>; + phy_lpddr4_odt_dis_freq = <0x320>; + lpddr4_drv = <0x3c>; + lpddr4_dq_odt = <0x28>; + lpddr4_ca_odt = <0x28>; + phy_lpddr4_ca_drv = <0x14>; + phy_lpddr4_ck_cs_drv = <0x06>; + phy_lpddr4_dq_drv = <0x06>; + phy_lpddr4_odt = <0x10>; + ddr4_odt_dis_freq = <0x29a>; + phy_ddr4_odt_dis_freq = <0x29a>; + ddr4_drv = <0x22>; + ddr4_odt = <0xf0>; + phy_ddr4_ca_drv = <0x16>; + phy_ddr4_ck_drv = <0x13>; + phy_ddr4_dq_drv = <0x16>; + phy_ddr4_odt = <0x02>; + ddr3a1_ddr4a9_de-skew = <0x06>; + ddr3a0_ddr4a10_de-skew = <0x07>; + ddr3a3_ddr4a6_de-skew = <0x07>; + ddr3a2_ddr4a4_de-skew = <0x07>; + ddr3a5_ddr4a8_de-skew = <0x07>; + ddr3a4_ddr4a5_de-skew = <0x07>; + ddr3a7_ddr4a11_de-skew = <0x07>; + ddr3a6_ddr4a7_de-skew = <0x06>; + ddr3a9_ddr4a0_de-skew = <0x07>; + ddr3a8_ddr4a13_de-skew = <0x07>; + ddr3a11_ddr4a3_de-skew = <0x07>; + ddr3a10_ddr4cs0_de-skew = <0x07>; + ddr3a13_ddr4a2_de-skew = <0x07>; + ddr3a12_ddr4ba1_de-skew = <0x07>; + ddr3a15_ddr4odt0_de-skew = <0x07>; + ddr3a14_ddr4a1_de-skew = <0x07>; + ddr3ba1_ddr4a15_de-skew = <0x07>; + ddr3ba0_ddr4bg0_de-skew = <0x07>; + ddr3ras_ddr4cke_de-skew = <0x07>; + ddr3ba2_ddr4ba0_de-skew = <0x07>; + ddr3we_ddr4bg1_de-skew = <0x07>; + ddr3cas_ddr4a12_de-skew = <0x07>; + ddr3ckn_ddr4ckn_de-skew = <0x07>; + ddr3ckp_ddr4ckp_de-skew = <0x07>; + ddr3cke_ddr4a16_de-skew = <0x07>; + ddr3odt0_ddr4a14_de-skew = <0x07>; + ddr3cs0_ddr4act_de-skew = <0x06>; + ddr3reset_ddr4reset_de-skew = <0x07>; + ddr3cs1_ddr4cs1_de-skew = <0x06>; + ddr3odt1_ddr4odt1_de-skew = <0x07>; + cs0_dm0_rx_de-skew = <0x07>; + cs0_dm0_tx_de-skew = <0x07>; + cs0_dq0_rx_de-skew = <0x08>; + cs0_dq0_tx_de-skew = <0x08>; + cs0_dq1_rx_de-skew = <0x09>; + cs0_dq1_tx_de-skew = <0x08>; + cs0_dq2_rx_de-skew = <0x08>; + cs0_dq2_tx_de-skew = <0x08>; + cs0_dq3_rx_de-skew = <0x08>; + cs0_dq3_tx_de-skew = <0x08>; + cs0_dq4_rx_de-skew = <0x09>; + cs0_dq4_tx_de-skew = <0x08>; + cs0_dq5_rx_de-skew = <0x09>; + cs0_dq5_tx_de-skew = <0x08>; + cs0_dq6_rx_de-skew = <0x09>; + cs0_dq6_tx_de-skew = <0x08>; + cs0_dq7_rx_de-skew = <0x08>; + cs0_dq7_tx_de-skew = <0x08>; + cs0_dqs0_rx_de-skew = <0x06>; + cs0_dqs0p_tx_de-skew = <0x09>; + cs0_dqs0n_tx_de-skew = <0x09>; + cs0_dm1_rx_de-skew = <0x07>; + cs0_dm1_tx_de-skew = <0x06>; + cs0_dq8_rx_de-skew = <0x08>; + cs0_dq8_tx_de-skew = <0x07>; + cs0_dq9_rx_de-skew = <0x09>; + cs0_dq9_tx_de-skew = <0x07>; + cs0_dq10_rx_de-skew = <0x08>; + cs0_dq10_tx_de-skew = <0x08>; + cs0_dq11_rx_de-skew = <0x08>; + cs0_dq11_tx_de-skew = <0x07>; + cs0_dq12_rx_de-skew = <0x08>; + cs0_dq12_tx_de-skew = <0x08>; + cs0_dq13_rx_de-skew = <0x09>; + cs0_dq13_tx_de-skew = <0x07>; + cs0_dq14_rx_de-skew = <0x09>; + cs0_dq14_tx_de-skew = <0x08>; + cs0_dq15_rx_de-skew = <0x09>; + cs0_dq15_tx_de-skew = <0x07>; + cs0_dqs1_rx_de-skew = <0x07>; + cs0_dqs1p_tx_de-skew = <0x09>; + cs0_dqs1n_tx_de-skew = <0x09>; + cs0_dm2_rx_de-skew = <0x07>; + cs0_dm2_tx_de-skew = <0x07>; + cs0_dq16_rx_de-skew = <0x09>; + cs0_dq16_tx_de-skew = <0x09>; + cs0_dq17_rx_de-skew = <0x07>; + cs0_dq17_tx_de-skew = <0x09>; + cs0_dq18_rx_de-skew = <0x07>; + cs0_dq18_tx_de-skew = <0x08>; + cs0_dq19_rx_de-skew = <0x07>; + cs0_dq19_tx_de-skew = <0x09>; + cs0_dq20_rx_de-skew = <0x09>; + cs0_dq20_tx_de-skew = <0x09>; + cs0_dq21_rx_de-skew = <0x09>; + cs0_dq21_tx_de-skew = <0x09>; + cs0_dq22_rx_de-skew = <0x08>; + cs0_dq22_tx_de-skew = <0x09>; + cs0_dq23_rx_de-skew = <0x08>; + cs0_dq23_tx_de-skew = <0x09>; + cs0_dqs2_rx_de-skew = <0x06>; + cs0_dqs2p_tx_de-skew = <0x09>; + cs0_dqs2n_tx_de-skew = <0x09>; + cs0_dm3_rx_de-skew = <0x07>; + cs0_dm3_tx_de-skew = <0x07>; + cs0_dq24_rx_de-skew = <0x08>; + cs0_dq24_tx_de-skew = <0x08>; + cs0_dq25_rx_de-skew = <0x09>; + cs0_dq25_tx_de-skew = <0x09>; + cs0_dq26_rx_de-skew = <0x09>; + cs0_dq26_tx_de-skew = <0x08>; + cs0_dq27_rx_de-skew = <0x09>; + cs0_dq27_tx_de-skew = <0x08>; + cs0_dq28_rx_de-skew = <0x09>; + cs0_dq28_tx_de-skew = <0x09>; + cs0_dq29_rx_de-skew = <0x09>; + cs0_dq29_tx_de-skew = <0x09>; + cs0_dq30_rx_de-skew = <0x08>; + cs0_dq30_tx_de-skew = <0x08>; + cs0_dq31_rx_de-skew = <0x08>; + cs0_dq31_tx_de-skew = <0x08>; + cs0_dqs3_rx_de-skew = <0x07>; + cs0_dqs3p_tx_de-skew = <0x09>; + cs0_dqs3n_tx_de-skew = <0x09>; + cs1_dm0_rx_de-skew = <0x07>; + cs1_dm0_tx_de-skew = <0x07>; + cs1_dq0_rx_de-skew = <0x08>; + cs1_dq0_tx_de-skew = <0x08>; + cs1_dq1_rx_de-skew = <0x09>; + cs1_dq1_tx_de-skew = <0x08>; + cs1_dq2_rx_de-skew = <0x08>; + cs1_dq2_tx_de-skew = <0x08>; + cs1_dq3_rx_de-skew = <0x08>; + cs1_dq3_tx_de-skew = <0x08>; + cs1_dq4_rx_de-skew = <0x08>; + cs1_dq4_tx_de-skew = <0x08>; + cs1_dq5_rx_de-skew = <0x09>; + cs1_dq5_tx_de-skew = <0x08>; + cs1_dq6_rx_de-skew = <0x09>; + cs1_dq6_tx_de-skew = <0x08>; + cs1_dq7_rx_de-skew = <0x08>; + cs1_dq7_tx_de-skew = <0x08>; + cs1_dqs0_rx_de-skew = <0x06>; + cs1_dqs0p_tx_de-skew = <0x09>; + cs1_dqs0n_tx_de-skew = <0x09>; + cs1_dm1_rx_de-skew = <0x07>; + cs1_dm1_tx_de-skew = <0x07>; + cs1_dq8_rx_de-skew = <0x08>; + cs1_dq8_tx_de-skew = <0x08>; + cs1_dq9_rx_de-skew = <0x08>; + cs1_dq9_tx_de-skew = <0x07>; + cs1_dq10_rx_de-skew = <0x07>; + cs1_dq10_tx_de-skew = <0x08>; + cs1_dq11_rx_de-skew = <0x08>; + cs1_dq11_tx_de-skew = <0x08>; + cs1_dq12_rx_de-skew = <0x08>; + cs1_dq12_tx_de-skew = <0x07>; + cs1_dq13_rx_de-skew = <0x08>; + cs1_dq13_tx_de-skew = <0x08>; + cs1_dq14_rx_de-skew = <0x08>; + cs1_dq14_tx_de-skew = <0x08>; + cs1_dq15_rx_de-skew = <0x08>; + cs1_dq15_tx_de-skew = <0x07>; + cs1_dqs1_rx_de-skew = <0x07>; + cs1_dqs1p_tx_de-skew = <0x09>; + cs1_dqs1n_tx_de-skew = <0x09>; + cs1_dm2_rx_de-skew = <0x07>; + cs1_dm2_tx_de-skew = <0x08>; + cs1_dq16_rx_de-skew = <0x08>; + cs1_dq16_tx_de-skew = <0x09>; + cs1_dq17_rx_de-skew = <0x08>; + cs1_dq17_tx_de-skew = <0x09>; + cs1_dq18_rx_de-skew = <0x07>; + cs1_dq18_tx_de-skew = <0x08>; + cs1_dq19_rx_de-skew = <0x08>; + cs1_dq19_tx_de-skew = <0x09>; + cs1_dq20_rx_de-skew = <0x09>; + cs1_dq20_tx_de-skew = <0x09>; + cs1_dq21_rx_de-skew = <0x09>; + cs1_dq21_tx_de-skew = <0x09>; + cs1_dq22_rx_de-skew = <0x08>; + cs1_dq22_tx_de-skew = <0x09>; + cs1_dq23_rx_de-skew = <0x08>; + cs1_dq23_tx_de-skew = <0x09>; + cs1_dqs2_rx_de-skew = <0x06>; + cs1_dqs2p_tx_de-skew = <0x09>; + cs1_dqs2n_tx_de-skew = <0x09>; + cs1_dm3_rx_de-skew = <0x07>; + cs1_dm3_tx_de-skew = <0x07>; + cs1_dq24_rx_de-skew = <0x08>; + cs1_dq24_tx_de-skew = <0x09>; + cs1_dq25_rx_de-skew = <0x09>; + cs1_dq25_tx_de-skew = <0x09>; + cs1_dq26_rx_de-skew = <0x09>; + cs1_dq26_tx_de-skew = <0x08>; + cs1_dq27_rx_de-skew = <0x08>; + cs1_dq27_tx_de-skew = <0x08>; + cs1_dq28_rx_de-skew = <0x09>; + cs1_dq28_tx_de-skew = <0x09>; + cs1_dq29_rx_de-skew = <0x09>; + cs1_dq29_tx_de-skew = <0x09>; + cs1_dq30_rx_de-skew = <0x09>; + cs1_dq30_tx_de-skew = <0x08>; + cs1_dq31_rx_de-skew = <0x08>; + cs1_dq31_tx_de-skew = <0x08>; + cs1_dqs3_rx_de-skew = <0x07>; + cs1_dqs3p_tx_de-skew = <0x09>; + cs1_dqs3n_tx_de-skew = <0x09>; + phandle = <0xaf>; + }; + + aliases { + ethernet0 = "/ethernet@ff360000"; + i2c0 = "/i2c@ff180000"; + i2c1 = "/i2c@ff190000"; + i2c2 = "/i2c@ff1a0000"; + i2c3 = "/i2c@ff1b0000"; + serial0 = "/serial@ff030000"; + serial1 = "/serial@ff158000"; + serial2 = "/serial@ff160000"; + serial3 = "/serial@ff168000"; + serial4 = "/serial@ff170000"; + serial5 = "/serial@ff178000"; + spi0 = "/spi@ff1d0000"; + spi1 = "/spi@ff1d8000"; + }; + + cpus { + #address-cells = <0x02>; + #size-cells = <0x00>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x00>; + enable-method = "psci"; + clocks = <0x02 0x07>; + #cooling-cells = <0x02>; + dynamic-power-coefficient = <0x5a>; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + cpu-supply = <0x06>; + phandle = <0x09>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x01>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0a>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x02>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0b>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x03>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0c>; + }; + + idle-states { + entry-method = "psci"; + + cpu-sleep { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x10000>; + entry-latency-us = <0x78>; + exit-latency-us = <0xfa>; + min-residency-us = <0x384>; + phandle = <0x04>; + }; + + cluster-sleep { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x1010000>; + entry-latency-us = <0x190>; + exit-latency-us = <0x1f4>; + min-residency-us = <0x7d0>; + phandle = <0x05>; + }; + }; + }; + + cpu0-opp-table { + compatible = "operating-points-v2"; + opp-shared; + rockchip,temp-hysteresis = <0x1388>; + rockchip,low-temp = <0x00>; + rockchip,low-temp-min-volt = <0xf4240>; + rockchip,low-temp-adjust-volt = <0x00 0x5e8 0xc350>; + clocks = <0x02 0x01>; + rockchip,avs-scale = <0x04>; + rockchip,max-volt = <0x149970>; + rockchip,evb-irdrop = <0x61a8>; + nvmem-cells = <0x07 0x08>; + nvmem-cell-names = "cpu_leakage\0performance"; + rockchip,bin-scaling-sel = <0x00 0x0d 0x01 0x0d>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-freq = <0x639c0>; + rockchip,pvtm-volt = <0xf4240>; + rockchip,pvtm-ch = <0x00 0x00>; + rockchip,pvtm-sample-time = <0x3e8>; + rockchip,pvtm-number = <0x0a>; + rockchip,pvtm-error = <0x3e8>; + rockchip,pvtm-ref-temp = <0x28>; + rockchip,pvtm-temp-prop = <0xffffffc8 0xffffffc8>; + rockchip,thermal-zone = "soc-thermal"; + rockchip,avs = <0x01>; + phandle = <0x03>; + + opp-1008000000 { + opp-hz = <0x00 0x3c14dc00>; + opp-microvolt = <0x11edd8 0x11edd8 0x149970>; + opp-microvolt-L0 = <0x11edd8 0x11edd8 0x149970>; + opp-microvolt-L1 = <0x112a88 0x112a88 0x149970>; + opp-microvolt-L2 = <0x112a88 0x112a88 0x149970>; + opp-microvolt-L3 = <0x100590 0x100590 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1200000000 { + opp-hz = <0x00 0x47868c00>; + opp-microvolt = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L0 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L1 = <0x137478 0x137478 0x149970>; + opp-microvolt-L2 = <0x1312d0 0x1312d0 0x149970>; + opp-microvolt-L3 = <0x124f80 0x124f80 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1248000000 { + opp-hz = <0x00 0x4a62f800>; + opp-microvolt = <0x149970 0x149970 0x149970>; + opp-microvolt-L0 = <0x149970 0x149970 0x149970>; + opp-microvolt-L1 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L2 = <0x137478 0x137478 0x149970>; + opp-microvolt-L3 = <0x12b128 0x12b128 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1296000000 { + opp-hz = <0x00 0x4d3f6400>; + opp-microvolt = <0x149970 0x149970 0x149970>; + opp-microvolt-L0 = <0x149970 0x149970 0x149970>; + opp-microvolt-L1 = <0x149970 0x149970 0x149970>; + opp-microvolt-L2 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L3 = <0x1312d0 0x1312d0 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1512000000 { + opp-hz = <0x00 0x5a1f4a00>; + opp-microvolt = <0x149970 0x149970 0x149970>; + opp-microvolt-L0 = <0x149970 0x149970 0x149970>; + opp-microvolt-L1 = <0x149970 0x149970 0x149970>; + opp-microvolt-L2 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L3 = <0x1312d0 0x1312d0 0x149970>; + clock-latency-ns = <0x9c40>; + }; + }; + + arm-pmu { + compatible = "arm,cortex-a53-pmu"; + interrupts = <0x00 0x64 0x04 0x00 0x65 0x04 0x00 0x66 0x04 0x00 0x67 0x04>; + interrupt-affinity = <0x09 0x0a 0x0b 0x0c>; + }; + + bus-soc { + compatible = "rockchip,px30-bus"; + rockchip,busfreq-policy = "autocs"; + phandle = <0xc4>; + + soc-bus0 { + bus-id = <0x00>; + timer-us = <0x14>; + enable-msk = <0x40f7>; + status = "disabled"; + }; + + soc-bus1 { + bus-id = <0x01>; + timer-us = <0xc8>; + enable-msk = <0x40bf>; + status = "disabled"; + }; + + soc-bus2 { + bus-id = <0x02>; + timer-us = <0xc8>; + enable-msk = <0x4007>; + status = "disabled"; + }; + }; + + bus-apll { + compatible = "rockchip,px30-bus"; + rockchip,busfreq-policy = "clkfreq"; + clocks = <0x02 0x01>; + clock-names = "bus"; + operating-points-v2 = <0x0d>; + status = "okay"; + bus-supply = <0x0e>; + phandle = <0xc5>; + }; + + bus-apll-opp-table { + compatible = "operating-points-v2"; + opp-shared; + phandle = <0x0d>; + + opp-1512000000 { + opp-hz = <0x00 0x5a1f4a00>; + opp-microvolt = <0xf4240>; + }; + + opp-1008000000 { + opp-hz = <0x00 0x3c14dc00>; + opp-microvolt = <0xe7ef0>; + }; + }; + + cpuinfo { + compatible = "rockchip,cpuinfo"; + nvmem-cells = <0x0f>; + nvmem-cell-names = "id"; + }; + + display-subsystem { + compatible = "rockchip,display-subsystem"; + ports = <0x10>; + status = "okay"; + logo-memory-region = <0x11>; + phandle = <0xc6>; + + route { + + route-lvds { + status = "disabled"; + logo,uboot = "logo.gif"; + logo,kernel = "logo_kernel.gif"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x12>; + phandle = <0xc7>; + }; + + route-dsi { + status = "okay"; + logo,uboot = "logo.gif"; + logo,kernel = "logo_kernel.gif"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x13>; + phandle = <0xc8>; + }; + + route-rgb { + status = "disabled"; + logo,uboot = "logo.gif"; + logo,kernel = "logo_kernel.gif"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x14>; + phandle = <0xc9>; + }; + }; + }; + + firmware { + + optee { + compatible = "linaro,optee-tz"; + method = "smc"; + }; + }; + + external-gmac-clock { + compatible = "fixed-clock"; + clock-frequency = <0x2faf080>; + clock-output-names = "gmac_clkin"; + #clock-cells = <0x00>; + phandle = <0xca>; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + rockchip-suspend { + compatible = "rockchip,pm-px30"; + status = "okay"; + rockchip,sleep-debug-en = <0x01>; + rockchip,sleep-mode-config = <0x20702>; + rockchip,wakeup-config = <0x85>; + phandle = <0xcb>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <0x01 0x0d 0xf04 0x01 0x0e 0xf04 0x01 0x0b 0xf04 0x01 0x0a 0xf04>; + }; + + xin24m { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x16e3600>; + clock-output-names = "xin24m"; + phandle = <0xcc>; + }; + + xin32k { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x8000>; + clock-output-names = "xin32k"; + phandle = <0xcd>; + }; + + power-management@ff000000 { + compatible = "rockchip,px30-pmu\0syscon\0simple-mfd"; + reg = <0x00 0xff000000 0x00 0x1000>; + phandle = <0xce>; + + power-controller { + compatible = "rockchip,px30-power-controller"; + #power-domain-cells = <0x01>; + #address-cells = <0x01>; + #size-cells = <0x00>; + phandle = <0x8a>; + + pd_usb@5 { + reg = <0x05>; + clocks = <0x02 0x103 0x02 0x102 0x02 0x3c>; + pm_qos = <0x15 0x16>; + }; + + pd_sdcard@7 { + reg = <0x07>; + clocks = <0x02 0xf7 0x02 0x3b>; + pm_qos = <0x17>; + }; + + pd_gmac@9 { + reg = <0x09>; + clocks = <0x02 0xb2 0x02 0x143 0x02 0x40 0x02 0x3f>; + pm_qos = <0x18>; + }; + + pd_mmc_nand@10 { + reg = <0x0a>; + clocks = <0x02 0xfe 0x02 0x100 0x02 0xff 0x02 0x101 0x02 0x39 0x02 0x37 0x02 0x38 0x02 0x3a>; + pm_qos = <0x19 0x1a 0x1b 0x1c>; + }; + + pd_vpu@11 { + reg = <0x0b>; + clocks = <0x02 0xaf 0x02 0xf4 0x02 0x4b>; + pm_qos = <0x1d 0x1e>; + }; + + pd_vo@12 { + reg = <0x0c>; + clocks = <0x02 0xb7 0x02 0xb5 0x02 0xb6 0x02 0x96 0x02 0x97 0x02 0xfd 0x02 0xfb 0x02 0xfc 0x02 0x144 0x02 0x35 0x02 0x36>; + pm_qos = <0x1f 0x20 0x21 0x22>; + }; + + pd_vi@13 { + reg = <0x0d>; + clocks = <0x02 0xb3 0x02 0xb4 0x02 0xf9 0x02 0xfa 0x02 0x33>; + pm_qos = <0x23 0x24 0x25 0x26 0x27>; + }; + + pd_gpu@14 { + reg = <0x0e>; + clocks = <0x02 0x49>; + pm_qos = <0x28>; + }; + }; + }; + + syscon@ff010000 { + compatible = "rockchip,px30-pmugrf\0syscon\0simple-mfd"; + reg = <0x00 0xff010000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0xac>; + + io-domains { + compatible = "rockchip,px30-pmu-io-voltage-domain"; + status = "okay"; + pmuio1-supply = <0x29>; + pmuio2-supply = <0x29>; + phandle = <0xcf>; + }; + + reboot-mode { + compatible = "syscon-reboot-mode"; + offset = <0x200>; + mode-bootloader = <0x5242c301>; + mode-charge = <0x5242c30b>; + mode-fastboot = <0x5242c309>; + mode-loader = <0x5242c301>; + mode-normal = <0x5242c300>; + mode-recovery = <0x5242c303>; + mode-ums = <0x5242c30c>; + }; + + pmu-pvtm { + compatible = "rockchip,px30-pmu-pvtm"; + clocks = <0x2a 0x07>; + clock-names = "pmu"; + status = "okay"; + phandle = <0xd0>; + }; + }; + + serial@ff030000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff030000 0x00 0x100>; + interrupts = <0x00 0x0f 0x04>; + clocks = <0x2a 0x06 0x2a 0x15>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x00 0x2b 0x01>; + pinctrl-names = "default"; + pinctrl-0 = <0x2c 0x2d 0x2e>; + status = "disabled"; + phandle = <0xd1>; + }; + + i2s@ff060000 { + compatible = "rockchip,px30-i2s-tdm"; + reg = <0x00 0xff060000 0x00 0x1000>; + interrupts = <0x00 0x0c 0x04>; + clocks = <0x02 0x10 0x02 0x12 0x02 0x106>; + clock-names = "mclk_tx\0mclk_rx\0hclk"; + dmas = <0x2b 0x10 0x2b 0x11>; + dma-names = "tx\0rx"; + resets = <0x02 0x84 0x02 0xbf>; + reset-names = "tx-m\0rx-m"; + rockchip,cru = <0x02>; + rockchip,grf = <0x2f>; + pinctrl-names = "default"; + pinctrl-0 = <0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x3a 0x3b>; + status = "disabled"; + phandle = <0xd2>; + }; + + i2s@ff070000 { + compatible = "rockchip,px30-i2s\0rockchip,rk3066-i2s"; + reg = <0x00 0xff070000 0x00 0x1000>; + interrupts = <0x00 0x0d 0x04>; + clocks = <0x02 0x14 0x02 0x107>; + clock-names = "i2s_clk\0i2s_hclk"; + dmas = <0x2b 0x12 0x2b 0x13>; + dma-names = "tx\0rx"; + resets = <0x02 0x86 0x02 0x85>; + reset-names = "reset-m\0reset-h"; + pinctrl-names = "default"; + pinctrl-0 = <0x3c 0x3d 0x3e 0x3f>; + status = "okay"; + #sound-dai-cells = <0x00>; + phandle = <0xc2>; + }; + + i2s@ff080000 { + compatible = "rockchip,px30-i2s\0rockchip,rk3066-i2s"; + reg = <0x00 0xff080000 0x00 0x1000>; + interrupts = <0x00 0x0e 0x04>; + clocks = <0x02 0x16 0x02 0x108>; + clock-names = "i2s_clk\0i2s_hclk"; + dmas = <0x2b 0x14 0x2b 0x15>; + dma-names = "tx\0rx"; + resets = <0x02 0x88 0x02 0x87>; + reset-names = "reset-m\0reset-h"; + pinctrl-names = "default"; + pinctrl-0 = <0x40 0x41 0x42 0x43>; + status = "disabled"; + phandle = <0xd3>; + }; + + pdm@ff0a0000 { + compatible = "rockchip,px30-pdm\0rockchip,pdm"; + reg = <0x00 0xff0a0000 0x00 0x1000>; + clocks = <0x02 0x0f 0x02 0x105>; + clock-names = "pdm_clk\0pdm_hclk"; + dmas = <0x2b 0x18>; + dma-names = "rx"; + resets = <0x02 0x82>; + reset-names = "pdm-m"; + pinctrl-names = "default"; + pinctrl-0 = <0x44 0x45 0x46 0x47 0x48 0x49>; + status = "disabled"; + phandle = <0xd4>; + }; + + crypto@ff0b0000 { + compatible = "rockchip,px30-crypto"; + reg = <0x00 0xff0b0000 0x00 0x4000>; + interrupts = <0x00 0x52 0x04>; + clocks = <0x02 0xac 0x02 0xf1 0x02 0x30 0x02 0x31>; + clock-names = "aclk\0hclk\0sclk\0apb_pclk"; + resets = <0x02 0x74>; + reset-names = "crypto-rst"; + status = "disabled"; + phandle = <0xd5>; + }; + + rng@ff0b0000 { + compatible = "rockchip,cryptov2-rng"; + reg = <0x00 0xff0b0000 0x00 0x4000>; + clocks = <0x02 0x30 0x02 0x31 0x02 0xac 0x02 0xf1>; + clock-names = "clk_crypto\0clk_crypto_apk\0aclk_crypto\0hclk_crypto"; + assigned-clocks = <0x02 0x30 0x02 0x31 0x02 0xac 0x02 0xf1>; + assigned-clock-rates = <0x8f0d180 0x8f0d180 0xbebc200 0x5f5e100>; + resets = <0x02 0x74>; + reset-names = "reset"; + status = "okay"; + phandle = <0xd6>; + }; + + interrupt-controller@ff131000 { + compatible = "arm,gic-400"; + #interrupt-cells = <0x03>; + #address-cells = <0x00>; + interrupt-controller; + reg = <0x00 0xff131000 0x00 0x1000 0x00 0xff132000 0x00 0x2000 0x00 0xff134000 0x00 0x2000 0x00 0xff136000 0x00 0x2000>; + interrupts = <0x01 0x09 0xf04>; + phandle = <0x01>; + }; + + syscon@ff140000 { + compatible = "rockchip,px30-grf\0syscon\0simple-mfd"; + reg = <0x00 0xff140000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0x2f>; + + io-domains { + compatible = "rockchip,px30-io-voltage-domain"; + status = "okay"; + vccio1-supply = <0x4a>; + vccio2-supply = <0x4a>; + vccio3-supply = <0x4b>; + vccio4-supply = <0x4b>; + vccio5-supply = <0x4b>; + vccio6-supply = <0x4b>; + phandle = <0xd7>; + }; + + lvds { + compatible = "rockchip,px30-lvds"; + phys = <0x4c>; + phy-names = "phy"; + status = "disabled"; + phandle = <0xd8>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x12>; + phandle = <0xa2>; + }; + }; + }; + }; + + rgb { + compatible = "rockchip,px30-rgb"; + pinctrl-names = "default\0sleep"; + pinctrl-0 = <0x4d>; + pinctrl-1 = <0x4e>; + status = "disabled"; + phys = <0x4c>; + phy-names = "phy"; + phandle = <0xd9>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x14>; + phandle = <0xa4>; + }; + }; + }; + }; + }; + + syscon@ff148000 { + compatible = "syscon\0simple-mfd"; + reg = <0x00 0xff148000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0xda>; + + pvtm { + compatible = "rockchip,px30-pvtm"; + clocks = <0x02 0x4a>; + clock-names = "core"; + status = "okay"; + phandle = <0xdb>; + }; + }; + + serial@ff158000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff158000 0x00 0x100>; + interrupts = <0x00 0x10 0x04>; + clocks = <0x02 0x18 0x02 0x149>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x02 0x2b 0x03>; + pinctrl-names = "default"; + pinctrl-0 = <0x4f 0x50>; + status = "okay"; + phandle = <0xdc>; + }; + + serial@ff160000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff160000 0x00 0x100>; + interrupts = <0x00 0x11 0x04>; + clocks = <0x02 0x19 0x02 0x14a>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x04 0x2b 0x05>; + pinctrl-names = "default"; + pinctrl-0 = <0x51>; + status = "disabled"; + phandle = <0xdd>; + }; + + serial@ff168000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff168000 0x00 0x100>; + interrupts = <0x00 0x12 0x04>; + clocks = <0x02 0x1a 0x02 0x14b>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x06 0x2b 0x07>; + pinctrl-names = "default"; + pinctrl-0 = <0x52 0x53 0x54>; + status = "disabled"; + phandle = <0xde>; + }; + + serial@ff170000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff170000 0x00 0x100>; + interrupts = <0x00 0x13 0x04>; + clocks = <0x02 0x1b 0x02 0x14c>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x08 0x2b 0x09>; + pinctrl-names = "default"; + pinctrl-0 = <0x55 0x56 0x57>; + status = "disabled"; + phandle = <0xdf>; + }; + + serial@ff178000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff178000 0x00 0x100>; + interrupts = <0x00 0x14 0x04>; + clocks = <0x02 0x1c 0x02 0x14d>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x0a 0x2b 0x0b>; + pinctrl-names = "default"; + pinctrl-0 = <0x58 0x59 0x5a>; + status = "disabled"; + phandle = <0xe0>; + }; + + i2c@ff180000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff180000 0x00 0x1000>; + clocks = <0x02 0x1d 0x02 0x14e>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x07 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x5b>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + clock-frequency = <0x61a80>; + i2c-scl-rising-time-ns = <0x118>; + i2c-scl-falling-time-ns = <0x10>; + phandle = <0xe1>; + + pmic@20 { + compatible = "rockchip,rk817"; + reg = <0x20>; + interrupt-parent = <0x5c>; + interrupts = <0x0a 0x08>; + pinctrl-names = "default\0pmic-sleep\0pmic-power-off\0pmic-reset"; + pinctrl-0 = <0x5d>; + pinctrl-1 = <0x5e 0x5f>; + pinctrl-2 = <0x60 0x61>; + pinctrl-3 = <0x62 0x63>; + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <0x01>; + clock-output-names = "rk808-clkout1\0rk808-clkout2"; + pmic-reset-func = <0x01>; + vcc1-supply = <0x64>; + vcc2-supply = <0x64>; + vcc3-supply = <0x64>; + vcc4-supply = <0x64>; + vcc5-supply = <0x64>; + vcc6-supply = <0x64>; + vcc7-supply = <0x64>; + vcc8-supply = <0x64>; + vcc9-supply = <0x65>; + phandle = <0xe2>; + + pwrkey { + status = "okay"; + }; + + pinctrl_rk8xx { + gpio-controller; + #gpio-cells = <0x02>; + phandle = <0xe3>; + + rk817_ts_gpio1 { + pins = "gpio_ts"; + function = "pin_fun1"; + phandle = <0xe4>; + }; + + rk817_gt_gpio2 { + pins = "gpio_gt"; + function = "pin_fun1"; + phandle = <0xe5>; + }; + + rk817_pin_ts { + pins = "gpio_ts"; + function = "pin_fun0"; + phandle = <0xe6>; + }; + + rk817_pin_gt { + pins = "gpio_gt"; + function = "pin_fun0"; + phandle = <0xe7>; + }; + + rk817_slppin_null { + pins = "gpio_slp"; + function = "pin_fun0"; + phandle = <0xe8>; + }; + + rk817_slppin_slp { + pins = "gpio_slp"; + function = "pin_fun1"; + phandle = <0x5f>; + }; + + rk817_slppin_pwrdn { + pins = "gpio_slp"; + function = "pin_fun2"; + phandle = <0x61>; + }; + + rk817_slppin_rst { + pins = "gpio_slp"; + function = "pin_fun3"; + phandle = <0x63>; + }; + }; + + regulators { + + DCDC_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xe7ef0>; + regulator-max-microvolt = <0x118c30>; + regulator-ramp-delay = <0x1771>; + regulator-initial-mode = <0x02>; + regulator-name = "vdd_logic"; + phandle = <0x0e>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0xe7ef0>; + }; + }; + + DCDC_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xe7ef0>; + regulator-max-microvolt = <0x149970>; + regulator-ramp-delay = <0x1771>; + regulator-initial-mode = <0x02>; + regulator-name = "vdd_arm"; + phandle = <0x06>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0xe7ef0>; + }; + }; + + DCDC_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x02>; + regulator-name = "vcc_ddr"; + phandle = <0xe9>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + DCDC_REG4 { + regulator-always-on; + #regulator-boot-on; + regulator-init-microvolt = <0x1e8480>; + regulator-min-microvolt = <0x1e8480>; + regulator-max-microvolt = <0x231860>; + regulator-initial-mode = <0x02>; + regulator-name = "vcc_3v3"; + phandle = <0x4b>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x1e8480>; + }; + }; + + LDO_REG1 { + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + regulator-name = "vcc_1v0"; + phandle = <0xea>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0xf4240>; + }; + }; + + LDO_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + regulator-name = "vcc1v8_soc"; + phandle = <0x88>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x1b7740>; + }; + }; + + LDO_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + regulator-name = "vcc1v0_soc"; + phandle = <0xeb>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0xf4240>; + }; + }; + + LDO_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "vcc3v3_pmu"; + phandle = <0x29>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + regulator-name = "vccio_sd"; + phandle = <0x4a>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x1b7740>; + }; + }; + + LDO_REG6 { + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x2dc6c0>; + regulator-boot-on; + regulator-name = "vcc_sd"; + phandle = <0x93>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x2dc6c0>; + }; + }; + + LDO_REG7 { + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "vcc_backlight"; + phandle = <0x9e>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG8 { + regulator-min-microvolt = <0x2ab980>; + regulator-max-microvolt = <0x2ab980>; + regulator-name = "vcc_lcd"; + phandle = <0x9f>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x2ab980>; + }; + }; + + BOOST { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x4c4b40>; + regulator-max-microvolt = <0x5265c0>; + regulator-name = "boost"; + phandle = <0x65>; + }; + + OTG_SWITCH { + regulator-boot-on; + regulator-name = "otg_switch"; + phandle = <0xec>; + }; + }; + + battery { + compatible = "rk817,battery"; + ocv_table = <0xc5d 0xc94 0xcd0 0xd02 0xd34 0xd66 0xd98 0xdca 0xdfc 0xe2e 0xe56 0xe7e 0xea6 0xece 0xef6 0xf1e 0xf46 0xf6e 0xf96 0xf9b 0xfa0>; + design_capacity = <0xd34>; + design_qmax = <0xe86>; + bat_res = <0x64>; + sleep_enter_current = <0x12c>; + sleep_exit_current = <0x12c>; + sleep_filter_current = <0x64>; + power_off_thresd = <0xbb8>; + zero_algorithm_vol = <0xf0a>; + max_soc_offset = <0x3c>; + monitor_sec = <0x05>; + virtual_power = <0x00>; + sample_res = <0x0a>; + }; + + charger { + compatible = "rk817,charger"; + min_input_voltage = <0x1194>; + max_input_current = <0x5dc>; + max_chrg_current = <0x7d0>; + max_chrg_voltage = <0x1068>; + chrg_term_mode = <0x00>; + chrg_finish_cur = <0x34>; + virtual_power = <0x00>; + sample_res = <0x0a>; + dc_det_gpio = <0x5c 0x0b 0x00>; + bat_low_gpio = <0x66 0x0d 0x00>; + extcon = <0x67>; + }; + + codec { + #sound-dai-cells = <0x00>; + compatible = "rockchip,rk817-codec"; + clocks = <0x02 0x15>; + clock-names = "mclk"; + pinctrl-names = "default"; + pinctrl-0 = <0x68>; + hp-volume = <0x14>; + spk-volume = <0x03>; + status = "okay"; + phandle = <0xc3>; + }; + }; + }; + + i2c@ff190000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff190000 0x00 0x1000>; + clocks = <0x02 0x1e 0x02 0x14f>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x08 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x69>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + clock-frequency = <0x61a80>; + phandle = <0xed>; + }; + + i2c@ff1a0000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff1a0000 0x00 0x1000>; + clocks = <0x02 0x1f 0x02 0x150>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x09 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x6a>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xee>; + }; + + i2c@ff1b0000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff1b0000 0x00 0x1000>; + clocks = <0x02 0x20 0x02 0x151>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x0a 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x6b>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xef>; + }; + + spi@ff1d0000 { + compatible = "rockchip,px30-spi\0rockchip,rk3066-spi"; + reg = <0x00 0xff1d0000 0x00 0x1000>; + interrupts = <0x00 0x1a 0x04>; + #address-cells = <0x01>; + #size-cells = <0x00>; + clocks = <0x02 0x24 0x02 0x155>; + clock-names = "spiclk\0apb_pclk"; + dmas = <0x2b 0x0c 0x2b 0x0d>; + dma-names = "tx\0rx"; + pinctrl-names = "default\0high_speed"; + pinctrl-0 = <0x6c 0x6d 0x6e 0x6f>; + pinctrl-1 = <0x70 0x6d 0x71 0x72>; + status = "disabled"; + phandle = <0xf0>; + }; + + spi@ff1d8000 { + compatible = "rockchip,px30-spi\0rockchip,rk3066-spi"; + reg = <0x00 0xff1d8000 0x00 0x1000>; + interrupts = <0x00 0x1b 0x04>; + #address-cells = <0x01>; + #size-cells = <0x00>; + clocks = <0x02 0x25 0x02 0x156>; + clock-names = "spiclk\0apb_pclk"; + dmas = <0x2b 0x0e 0x2b 0x0f>; + dma-names = "tx\0rx"; + pinctrl-names = "default\0high_speed"; + pinctrl-0 = <0x73 0x74 0x75 0x76 0x77>; + pinctrl-1 = <0x78 0x74 0x75 0x79 0x7a>; + status = "disabled"; + phandle = <0xf1>; + }; + + watchdog@ff1e0000 { + compatible = "snps,dw-wdt"; + reg = <0x00 0xff1e0000 0x00 0x100>; + clocks = <0x02 0x15b>; + interrupts = <0x00 0x25 0x04>; + resets = <0x02 0xb5>; + reset-names = "reset"; + status = "disabled"; + phandle = <0xf2>; + }; + + pwm@ff200000 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200000 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7b>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "okay"; + phandle = <0xbc>; + }; + + pwm@ff200010 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200010 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7c>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "okay"; + phandle = <0xc1>; + }; + + pwm@ff200020 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200020 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7d>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf3>; + }; + + pwm@ff200030 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200030 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7e>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf4>; + }; + + pwm@ff208000 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208000 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7f>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf5>; + }; + + pwm@ff208010 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208010 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x80>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf6>; + }; + + pwm@ff208020 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208020 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x81>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf7>; + }; + + pwm@ff208030 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208030 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x82>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf8>; + }; + + rktimer@ff210000 { + compatible = "rockchip,rk3288-timer"; + reg = <0x00 0xff210000 0x00 0x1000>; + interrupts = <0x00 0x1e 0x04>; + clocks = <0x02 0x159 0x02 0x26>; + clock-names = "pclk\0timer"; + phandle = <0xf9>; + }; + + amba { + compatible = "simple-bus"; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + + dmac@ff240000 { + compatible = "arm,pl330\0arm,primecell"; + reg = <0x00 0xff240000 0x00 0x4000>; + interrupts = <0x00 0x01 0x04 0x00 0x02 0x04>; + clocks = <0x02 0xbb>; + clock-names = "apb_pclk"; + #dma-cells = <0x01>; + peripherals-req-type-burst; + phandle = <0x2b>; + }; + }; + + thermal-zones { + phandle = <0xfa>; + + soc-thermal { + polling-delay-passive = <0x14>; + polling-delay = <0x3e8>; + sustainable-power = <0x2ee>; + thermal-sensors = <0x83 0x00>; + phandle = <0xfb>; + + trips { + + trip-point-0 { + temperature = <0x11170>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0xfc>; + }; + + trip-point-1 { + temperature = <0x14c08>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0x84>; + }; + + soc-crit { + temperature = <0x1c138>; + hysteresis = <0x7d0>; + type = "critical"; + phandle = <0xfd>; + }; + }; + + cooling-maps { + + map0 { + trip = <0x84>; + cooling-device = <0x09 0xffffffff 0xffffffff>; + contribution = <0x1000>; + }; + + map1 { + trip = <0x84>; + cooling-device = <0x85 0xffffffff 0xffffffff>; + contribution = <0x1000>; + }; + }; + }; + + gpu-thermal { + polling-delay-passive = <0x64>; + polling-delay = <0x3e8>; + thermal-sensors = <0x83 0x01>; + phandle = <0xfe>; + }; + }; + + tsadc@ff280000 { + compatible = "rockchip,px30-tsadc"; + reg = <0x00 0xff280000 0x00 0x100>; + interrupts = <0x00 0x24 0x04>; + rockchip,grf = <0x2f>; + clocks = <0x02 0x2c 0x02 0x158>; + clock-names = "tsadc\0apb_pclk"; + assigned-clocks = <0x02 0x2c>; + assigned-clock-rates = <0xc350>; + resets = <0x02 0xa8>; + reset-names = "tsadc-apb"; + #thermal-sensor-cells = <0x01>; + rockchip,hw-tshut-temp = <0x1d4c0>; + status = "okay"; + pinctrl-names = "gpio\0otpout"; + pinctrl-0 = <0x86>; + pinctrl-1 = <0x87>; + phandle = <0x83>; + }; + + saradc@ff288000 { + compatible = "rockchip,px30-saradc\0rockchip,rk3399-saradc"; + reg = <0x00 0xff288000 0x00 0x100>; + interrupts = <0x00 0x54 0x04>; + #io-channel-cells = <0x01>; + clocks = <0x02 0x2d 0x02 0x157>; + clock-names = "saradc\0apb_pclk"; + resets = <0x02 0xa5>; + reset-names = "saradc-apb"; + status = "okay"; + vref-supply = <0x88>; + phandle = <0xbe>; + }; + + otp@ff290000 { + compatible = "rockchip,px30-otp"; + reg = <0x00 0xff290000 0x00 0x4000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + clocks = <0x02 0x2f 0x02 0x15a 0x02 0x161>; + clock-names = "clk_otp\0pclk_otp\0pclk_otp_phy"; + resets = <0x02 0xb4>; + reset-names = "otp_phy"; + phandle = <0xff>; + + id@7 { + reg = <0x07 0x10>; + phandle = <0x0f>; + }; + + cpu-leakage@17 { + reg = <0x17 0x01>; + phandle = <0x07>; + }; + + performance@1e { + reg = <0x1e 0x01>; + bits = <0x04 0x03>; + phandle = <0x08>; + }; + }; + + clock-controller@ff2b0000 { + compatible = "rockchip,px30-cru"; + reg = <0x00 0xff2b0000 0x00 0x1000>; + rockchip,grf = <0x2f>; + rockchip,boost = <0x89>; + #clock-cells = <0x01>; + #reset-cells = <0x01>; + assigned-clocks = <0x02 0x04>; + assigned-clock-rates = <0x3dfd2400>; + phandle = <0x02>; + }; + + cpu-boost@ff2b8000 { + compatible = "syscon"; + reg = <0x00 0xff2b8000 0x00 0x1000>; + rockchip,boost-low-con0 = <0x1032>; + rockchip,boost-low-con1 = <0x1441>; + rockchip,boost-high-con0 = <0x1036>; + rockchip,boost-high-con1 = <0x1441>; + rockchip,boost-backup-pll = <0x01>; + rockchip,boost-backup-pll-usage = <0x00>; + rockchip,boost-switch-threshold = <0x249f00>; + rockchip,boost-statis-threshold = <0x100>; + rockchip,boost-statis-enable = <0x00>; + rockchip,boost-enable = <0x00>; + phandle = <0x89>; + }; + + pmu-clock-controller@ff2bc000 { + compatible = "rockchip,px30-pmucru"; + reg = <0x00 0xff2bc000 0x00 0x1000>; + rockchip,grf = <0x2f>; + #clock-cells = <0x01>; + #reset-cells = <0x01>; + assigned-clocks = <0x2a 0x01 0x2a 0x08 0x2a 0x05 0x02 0x07 0x02 0xab 0x02 0xb0 0x02 0xf0 0x02 0xf5 0x02 0x140 0x02 0x49>; + assigned-clock-rates = <0x47868c00 0x5f5e100 0x18cba80 0x23c34600 0xbebc200 0xbebc200 0x8f0d180 0x8f0d180 0x5f5e100 0xbebc200>; + phandle = <0x2a>; + }; + + syscon@ff2c0000 { + compatible = "rockchip,px30-usb2phy-grf\0syscon\0simple-mfd"; + reg = <0x00 0xff2c0000 0x00 0x10000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0x100>; + + usb2-phy@100 { + compatible = "rockchip,px30-usb2phy\0rockchip,rk3328-usb2phy"; + reg = <0x100 0x10>; + clocks = <0x2a 0x0a>; + clock-names = "phyclk"; + #clock-cells = <0x00>; + assigned-clocks = <0x02 0x0e 0x02 0x55>; + assigned-clock-parents = <0x67 0x02 0x0e>; + clock-output-names = "usb480m_phy"; + status = "okay"; + phandle = <0x67>; + + host-port { + #phy-cells = <0x00>; + interrupts = <0x00 0x44 0x04>; + interrupt-names = "linestate"; + status = "okay"; + phandle = <0x8c>; + }; + + otg-port { + #phy-cells = <0x00>; + interrupts = <0x00 0x42 0x04 0x00 0x41 0x04 0x00 0x40 0x04>; + interrupt-names = "otg-bvalid\0otg-id\0linestate"; + status = "disabled"; + phandle = <0x8b>; + }; + }; + }; + + video-phy@ff2e0000 { + compatible = "rockchip,px30-video-phy"; + reg = <0x00 0xff2e0000 0x00 0x10000 0x00 0xff450000 0x00 0x10000>; + clocks = <0x2a 0x0b 0x02 0x145 0x02 0x144>; + clock-names = "ref\0pclk_phy\0pclk_host"; + #clock-cells = <0x00>; + resets = <0x02 0x3e>; + reset-names = "rst"; + power-domains = <0x8a 0x0c>; + #phy-cells = <0x00>; + status = "okay"; + phandle = <0x4c>; + }; + + mipi-dphy-rx0@ff2f0000 { + compatible = "rockchip,rk3326-mipi-dphy"; + reg = <0x00 0xff2f0000 0x00 0x4000>; + clocks = <0x02 0x146>; + clock-names = "dphy-ref"; + power-domains = <0x8a 0x0d>; + rockchip,grf = <0x2f>; + status = "okay"; + phandle = <0x101>; + }; + + usb@ff300000 { + compatible = "rockchip,px30-usb\0rockchip,rk3066-usb\0snps,dwc2"; + reg = <0x00 0xff300000 0x00 0x40000>; + interrupts = <0x00 0x3e 0x04>; + clocks = <0x02 0x102>; + clock-names = "otg"; + power-domains = <0x8a 0x05>; + dr_mode = "otg"; + g-np-tx-fifo-size = <0x10>; + g-rx-fifo-size = <0x118>; + g-tx-fifo-size = <0x100 0x80 0x80 0x40 0x20 0x10>; + g-use-dma; + phys = <0x8b>; + phy-names = "usb2-phy"; + status = "okay"; + phandle = <0x102>; + }; + + usb@ff340000 { + compatible = "generic-ehci"; + reg = <0x00 0xff340000 0x00 0x10000>; + interrupts = <0x00 0x3c 0x04>; + clocks = <0x02 0x103 0x67>; + clock-names = "usbhost\0utmi"; + power-domains = <0x8a 0x05>; + phys = <0x8c>; + phy-names = "usb"; + status = "disabled"; + phandle = <0x103>; + }; + + usb@ff350000 { + compatible = "generic-ohci"; + reg = <0x00 0xff350000 0x00 0x10000>; + interrupts = <0x00 0x3d 0x04>; + clocks = <0x02 0x103 0x67>; + clock-names = "usbhost\0utmi"; + power-domains = <0x8a 0x05>; + phys = <0x8c>; + phy-names = "usb"; + status = "disabled"; + phandle = <0x104>; + }; + + ethernet@ff360000 { + compatible = "rockchip,px30-gmac"; + reg = <0x00 0xff360000 0x00 0x10000>; + rockchip,grf = <0x2f>; + interrupts = <0x00 0x2b 0x04>; + interrupt-names = "macirq"; + clocks = <0x02 0x3e 0x02 0x3f 0x02 0x3f 0x02 0x40 0x02 0x41 0x02 0xb2 0x02 0x143 0x02 0x4c>; + clock-names = "stmmaceth\0mac_clk_rx\0mac_clk_tx\0clk_mac_ref\0clk_mac_refout\0aclk_mac\0pclk_mac\0clk_mac_speed"; + phy-mode = "rmii"; + pinctrl-names = "default"; + pinctrl-0 = <0x8d 0x8e>; + resets = <0x02 0x5e>; + reset-names = "stmmaceth"; + power-domains = <0x8a 0x09>; + status = "disabled"; + phandle = <0x105>; + }; + + dwmmc@ff370000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff370000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0xf7 0x02 0x3b 0x02 0x43 0x02 0x44>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x3b>; + assigned-clock-parents = <0x02 0x57>; + power-domains = <0x8a 0x07>; + fifo-depth = <0x100>; + interrupts = <0x00 0x36 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x8f 0x90 0x91 0x92>; + status = "okay"; + bus-width = <0x04>; + cap-mmc-highspeed; + cap-sd-highspeed; + supports-sd; + card-detect-delay = <0x320>; + ignore-pm-notify; + cd-gpios = <0x5c 0x03 0x01>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <0x4a>; + vmmc-supply = <0x93>; + phandle = <0x106>; + }; + + dwmmc@ff380000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff380000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0xff 0x02 0x38 0x02 0x45 0x02 0x46>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x38>; + assigned-clock-parents = <0x02 0x51>; + power-domains = <0x8a 0x0a>; + fifo-depth = <0x100>; + interrupts = <0x00 0x37 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x94 0x95 0x96>; + status = "okay"; + bus-width = <0x04>; + cap-mmc-highspeed; + cap-sd-highspeed; + supports-sd; + card-detect-delay = <0x320>; + ignore-pm-notify; + cd-gpios = <0x97 0x0e 0x01>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <0x4a>; + vmmc-supply = <0x93>; + phandle = <0x107>; + }; + + dwmmc@ff390000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff390000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0x100 0x02 0x39 0x02 0x47 0x02 0x48>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x39>; + assigned-clock-parents = <0x02 0x53>; + power-domains = <0x8a 0x0a>; + fifo-depth = <0x100>; + interrupts = <0x00 0x35 0x04>; + status = "disabled"; + phandle = <0x108>; + }; + + nandc@ff3b0000 { + compatible = "rockchip,rk-nandc"; + reg = <0x00 0xff3b0000 0x00 0x4000>; + interrupts = <0x00 0x39 0x04>; + nandc_id = <0x00>; + clocks = <0x02 0x37 0x02 0xfe>; + clock-names = "clk_nandc\0hclk_nandc"; + assigned-clocks = <0x02 0x37>; + assigned-clock-parents = <0x02 0x4f>; + power-domains = <0x8a 0x0a>; + status = "disabled"; + phandle = <0x109>; + }; + + sfc@ff3a0000 { + compatible = "rockchip,sfc"; + reg = <0x00 0xff3a0000 0x00 0x4000>; + interrupts = <0x00 0x38 0x04>; + clocks = <0x02 0x3a 0x02 0x101>; + clock-names = "clk_sfc\0hclk_sfc"; + assigned-clocks = <0x02 0x3a>; + assigned-clock-rates = <0x989680>; + status = "disabled"; + phandle = <0x10a>; + }; + + gpu@ff400000 { + compatible = "arm,malit602\0arm,malit60x\0arm,malit6xx\0arm,mali-midgard"; + reg = <0x00 0xff400000 0x00 0x4000>; + interrupts = <0x00 0x2d 0x04 0x00 0x2e 0x04 0x00 0x2f 0x04>; + interrupt-names = "GPU\0MMU\0JOB"; + clocks = <0x02 0x49>; + clock-names = "clk_mali"; + power-domains = <0x8a 0x0e>; + #cooling-cells = <0x02>; + operating-points-v2 = <0x98>; + status = "okay"; + mali-supply = <0x0e>; + phandle = <0x85>; + + power_model { + compatible = "arm,mali-simple-power-model"; + static-coefficient = <0x64578>; + dynamic-coefficient = <0x2dd>; + ts = <0x7d00 0x125c 0xffffffb0 0x02>; + thermal-zone = "gpu-thermal"; + }; + }; + + gpu-opp-table { + compatible = "operating-points-v2"; + rockchip,thermal-zone = "soc-thermal"; + rockchip,temp-hysteresis = <0x1388>; + rockchip,low-temp = <0x00>; + rockchip,low-temp-min-volt = <0xf4240>; + rockchip,low-temp-adjust-volt = <0x00 0x1e0 0xc350>; + rockchip,max-volt = <0x11edd8>; + rockchip,evb-irdrop = <0x61a8>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-ch = <0x00 0x00>; + phandle = <0x98>; + + opp-400000000 { + opp-hz = <0x00 0x17d78400>; + opp-microvolt = <0x100590>; + opp-microvolt-L0 = <0x100590>; + opp-microvolt-L1 = <0xfa3e8>; + opp-microvolt-L2 = <0xee098>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-480000000 { + opp-hz = <0x00 0x1c9c3800>; + opp-microvolt = <0x112a88>; + opp-microvolt-L0 = <0x112a88>; + opp-microvolt-L1 = <0x10c8e0>; + opp-microvolt-L2 = <0x100590>; + opp-microvolt-L3 = <0xf4240>; + }; + + opp-520000000 { + opp-hz = <0x00 0x1efe9200>; + opp-microvolt = <0x118c30>; + opp-microvolt-L0 = <0x118c30>; + opp-microvolt-L1 = <0x118c30>; + opp-microvolt-L2 = <0x10c8e0>; + opp-microvolt-L3 = <0x100590>; + }; + }; + + hevc_service@ff440000 { + compatible = "rockchip,hevc_sub"; + iommu_enabled = <0x01>; + reg = <0x00 0xff440000 0x00 0x400>; + interrupts = <0x00 0x31 0x04>; + interrupt-names = "irq_dec"; + dev_mode = <0x01>; + iommus = <0x99>; + allocator = <0x01>; + phandle = <0x9c>; + }; + + vpu_service@ff442000 { + compatible = "rockchip,vpu_sub"; + iommu_enabled = <0x01>; + reg = <0x00 0xff442000 0x00 0x800>; + interrupts = <0x00 0x50 0x04 0x00 0x4f 0x04>; + interrupt-names = "irq_enc\0irq_dec"; + dev_mode = <0x00>; + iommus = <0x9a>; + allocator = <0x01>; + phandle = <0x9b>; + }; + + vpu_combo { + compatible = "rockchip,vpu_combo"; + subcnt = <0x02>; + rockchip,grf = <0x2f>; + rockchip,sub = <0x9b 0x9c>; + clocks = <0x02 0xaf 0x02 0xf4 0x02 0x4b>; + clock-names = "aclk_vcodec\0hclk_vcodec\0clk_core"; + resets = <0x02 0x24 0x02 0x26 0x02 0x25 0x02 0x27 0x02 0x3f>; + reset-names = "video_a\0video_h\0niu_a\0niu_h\0video_core"; + power-domains = <0x8a 0x0b>; + mode_bit = <0x0f>; + mode_ctrl = <0x410>; + status = "okay"; + phandle = <0x10b>; + }; + + iommu@ff440440 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff440440 0x00 0x40 0x00 0xff440480 0x00 0x40>; + interrupts = <0x00 0x32 0x04>; + interrupt-names = "hevc_mmu"; + clocks = <0x02 0xaf 0x02 0xf4>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0b>; + #iommu-cells = <0x00>; + phandle = <0x99>; + }; + + iommu@ff442800 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff442800 0x00 0x100>; + interrupts = <0x00 0x51 0x04>; + interrupt-names = "vpu_mmu"; + clocks = <0x02 0xaf 0x02 0xf4>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0b>; + #iommu-cells = <0x00>; + phandle = <0x9a>; + }; + + dsi@ff450000 { + compatible = "rockchip,px30-mipi-dsi"; + reg = <0x00 0xff450000 0x00 0x10000>; + interrupts = <0x00 0x4b 0x04>; + clocks = <0x02 0x144 0x4c>; + clock-names = "pclk\0hs_clk"; + resets = <0x02 0x3d>; + reset-names = "apb"; + phys = <0x4c>; + phy-names = "mipi_dphy"; + power-domains = <0x8a 0x0c>; + rockchip,grf = <0x2f>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + phandle = <0x10c>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x13>; + status = "okay"; + phandle = <0xa3>; + }; + }; + }; + + panel@0 { + compatible = "elida,kd35t133\0simple-panel-dsi"; + reg = <0x00>; + backlight = <0x9d>; + backlight-supply = <0x9e>; + power-supply = <0x9f>; + reset-gpios = <0x97 0x10 0x01>; + reset-delay-ms = <0x96>; + init-delay-ms = <0x14>; + enable-delay-ms = <0x78>; + prepare-delay-ms = <0x14>; + unprepare-delay-ms = <0x14>; + disable-delay-ms = <0x32>; + width-mm = <0x34>; + height-mm = <0x46>; + dsi,flags = <0xa03>; + dsi,format = <0x00>; + dsi,lanes = <0x04>; + panel-init-sequence = [15 00 02 ff 30 15 00 02 ff 52 15 00 02 ff 01 15 00 02 e3 00 15 00 02 25 10 15 00 02 28 6f 15 00 02 29 01 15 00 02 2a df 15 00 02 2c 22 15 00 02 c3 0f 15 00 02 37 9c 15 00 02 38 a7 15 00 02 39 41 15 00 02 80 20 15 00 02 91 67 15 00 02 92 67 15 00 02 a0 55 15 00 02 a1 50 15 00 02 a3 58 15 00 02 a4 9c 15 00 02 a7 02 15 00 02 a8 01 15 00 02 a9 21 15 00 02 aa fc 15 00 02 ab 28 15 00 02 ac 06 15 00 02 ad 06 15 00 02 ae 06 15 00 02 af 03 15 00 02 b0 08 15 00 02 b1 26 15 00 02 b2 28 15 00 02 b3 28 15 00 02 b4 03 15 00 02 b5 08 15 00 02 b6 26 15 00 02 b7 08 15 00 02 b8 26 15 00 02 2c 22 15 00 02 5c 40 15 00 02 c0 00 15 00 02 c1 00 15 00 02 c2 00 15 00 02 ff 30 15 00 02 ff 52 15 00 02 ff 02 15 00 02 b0 02 15 00 02 d0 02 15 00 02 b1 0f 15 00 02 d1 10 15 00 02 b2 11 15 00 02 d2 12 15 00 02 b3 32 15 00 02 d3 33 15 00 02 b4 36 15 00 02 d4 36 15 00 02 b5 3c 15 00 02 d5 3c 15 00 02 b6 20 15 00 02 d6 20 15 00 02 b7 3e 15 00 02 d7 3e 15 00 02 b8 0e 15 00 02 d8 0d 15 00 02 b9 05 15 00 02 d9 05 15 00 02 ba 11 15 00 02 da 12 15 00 02 bb 11 15 00 02 db 11 15 00 02 bc 13 15 00 02 dc 14 15 00 02 bd 14 15 00 02 dd 14 15 00 02 be 16 15 00 02 de 18 15 00 02 bf 0e 15 00 02 df 0f 15 00 02 c0 17 15 00 02 e0 17 15 00 02 c1 07 15 00 02 e1 08 15 00 02 ff 30 15 00 02 ff 52 15 00 02 ff 03 15 00 02 08 8a 15 00 02 09 8b 15 00 02 30 00 15 00 02 31 00 15 00 02 32 00 15 00 02 33 00 15 00 02 34 61 15 00 02 35 d4 15 00 02 36 24 15 00 02 37 03 15 00 02 40 86 15 00 02 41 87 15 00 02 42 84 15 00 02 43 85 15 00 02 44 11 15 00 02 45 de 15 00 02 46 dd 15 00 02 47 11 15 00 02 48 e0 15 00 02 49 df 15 00 02 50 82 15 00 02 51 83 15 00 02 52 80 15 00 02 53 81 15 00 02 54 11 15 00 02 55 e2 15 00 02 56 e1 15 00 02 57 11 15 00 02 58 e4 15 00 02 59 e3 15 00 02 82 0f 15 00 02 83 0f 15 00 02 84 00 15 00 02 85 0f 15 00 02 86 0f 15 00 02 87 0e 15 00 02 88 0e 15 00 02 89 06 15 00 02 8a 06 15 00 02 8b 07 15 00 02 8c 07 15 00 02 8d 04 15 00 02 8e 04 15 00 02 8f 05 15 00 02 90 05 15 00 02 98 0f 15 00 02 99 0f 15 00 02 9a 00 15 00 02 9b 0f 15 00 02 9c 0f 15 00 02 9d 0e 15 00 02 9e 0e 15 00 02 9f 06 15 00 02 a0 06 15 00 02 a1 07 15 00 02 a2 07 15 00 02 a3 04 15 00 02 a4 04 15 00 02 a5 05 15 00 02 a6 05 15 00 02 e0 02 15 00 02 e1 52 15 00 02 ff 30 15 00 02 ff 52 15 00 02 ff 00 15 00 02 36 02 15 00 02 11 00 15 00 02 29 00 05 c8 01 11 05 14 01 29]; + panel-exit-sequence = <0x5140128 0x50a0110>; + + display-timings { + native-mode = <0xa0>; + + 60Hz { + clock-frequency = <0x1ba8140>; + hactive = <0x280>; + vactive = <0x1e0>; + hfront-porch = <0x2e>; + hsync-len = <0x02>; + hback-porch = <0x2c>; + vfront-porch = <0xa5>; + vsync-len = <0x02>; + vback-porch = <0x0e>; + hsync-active = <0x00>; + vsync-active = <0x00>; + de-active = <0x00>; + pixelclk-active = <0x01>; + phandle = <0xaa1>; + }; + + 50Hz { + clock-frequency = <0x1ba8140>; + hactive = <0x280>; + vactive = <0x1e0>; + hfront-porch = <0x2e>; + hsync-len = <0x02>; + hback-porch = <0x2c>; + vfront-porch = <0x10>; + vsync-len = <0x02>; + vback-porch = <0x0e>; + hsync-active = <0x00>; + vsync-active = <0x00>; + de-active = <0x00>; + pixelclk-active = <0x01>; + phandle = <0xa00>; + }; + + 75Hz { + clock-frequency = <0x1ba8140>; + hactive = <0x280>; + vactive = <0x1e0>; + hfront-porch = <0x2e>; + hsync-len = <0x02>; + hback-porch = <0x2c>; + vfront-porch = <0x10>; + vsync-len = <0x02>; + vback-porch = <0x0e>; + hsync-active = <0x00>; + vsync-active = <0x00>; + de-active = <0x00>; + pixelclk-active = <0x01>; + phandle = <0xa01>; + }; + }; + }; + }; + + vop@ff460000 { + compatible = "rockchip,px30-vop-big"; + reg = <0x00 0xff460000 0x00 0x1fc 0x00 0xff460a00 0x00 0x400>; + rockchip,grf = <0x2f>; + reg-names = "regs\0gamma_lut"; + interrupts = <0x00 0x4d 0x04>; + clocks = <0x02 0xb5 0x02 0x96 0x02 0xfb>; + clock-names = "aclk_vop\0dclk_vop\0hclk_vop"; + power-domains = <0x8a 0x0c>; + iommus = <0xa1>; + status = "okay"; + phandle = <0x10f>; + + port { + #address-cells = <0x01>; + #size-cells = <0x00>; + phandle = <0x10>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0xa2>; + phandle = <0x12>; + }; + + endpoint@1 { + reg = <0x01>; + remote-endpoint = <0xa3>; + phandle = <0x13>; + }; + + endpoint@2 { + reg = <0x02>; + remote-endpoint = <0xa4>; + phandle = <0x14>; + }; + }; + }; + + iommu@ff460f00 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff460f00 0x00 0x100>; + interrupts = <0x00 0x4d 0x04>; + interrupt-names = "vopb_mmu"; + clocks = <0x02 0xb5 0x02 0xfb>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0c>; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xa1>; + }; + + rk_rga@ff480000 { + compatible = "rockchip,rga2"; + reg = <0x00 0xff480000 0x00 0x1000>; + interrupts = <0x00 0x4c 0x04>; + clocks = <0x02 0xb7 0x02 0xfd 0x02 0x35>; + clock-names = "aclk_rga\0hclk_rga\0clk_rga"; + power-domains = <0x8a 0x0c>; + dma-coherent; + status = "okay"; + phandle = <0x110>; + }; + + cif@ff490000 { + compatible = "rockchip,cif"; + reg = <0x00 0xff490000 0x00 0x200>; + interrupts = <0x00 0x45 0x04>; + clocks = <0x02 0xb3 0x02 0xf9 0x02 0x160 0x02 0x34>; + clock-names = "aclk_cif0\0hclk_cif0\0pclk_cif\0cif0_out"; + resets = <0x02 0x2c 0x02 0x2d 0x02 0x2e>; + reset-names = "rst_cif_a\0rst_cif_h\0rst_cif_pclkin"; + power-domains = <0x8a 0x0d>; + pinctrl-names = "cif_pin_all"; + pinctrl-0 = <0xa5>; + iommus = <0xa6>; + status = "disabled"; + phandle = <0x111>; + }; + + cif-new@ff490000 { + compatible = "rockchip,px30-cif"; + reg = <0x00 0xff490000 0x00 0x200>; + interrupts = <0x00 0x45 0x04>; + clocks = <0x02 0xb3 0x02 0xf9 0x02 0x160 0x02 0x34>; + clock-names = "aclk_cif\0hclk_cif\0pclk_cif\0cif_out"; + resets = <0x02 0x2c 0x02 0x2d 0x02 0x2e>; + reset-names = "rst_cif_a\0rst_cif_h\0rst_cif_pclkin"; + power-domains = <0x8a 0x0d>; + iommus = <0xa6>; + status = "disabled"; + phandle = <0x112>; + }; + + iommu@ff490800 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff490800 0x00 0x100>; + interrupts = <0x00 0x45 0x04>; + interrupt-names = "vip_mmu"; + clocks = <0x02 0xb3 0x02 0xf9>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0d>; + rk_iommu,disable_reset_quirk; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xa6>; + }; + + rk_isp@ff4a0000 { + compatible = "rockchip,px30-isp\0rockchip,isp"; + reg = <0x00 0xff4a0000 0x00 0x8000>; + interrupts = <0x00 0x46 0x04>; + clocks = <0x02 0xb4 0x02 0xfa 0x02 0x33 0x02 0x33 0x02 0x15f 0x02 0x34 0x02 0x34 0x02 0x146>; + clock-names = "aclk_isp\0hclk_isp\0clk_isp\0clk_isp_jpe\0pclkin_isp\0clk_cif_pll\0clk_cif_out\0pclk_dphyrx"; + resets = <0x02 0x2b 0x02 0x2f>; + reset-names = "rst_isp\0rst_mipicsiphy"; + power-domains = <0x8a 0x0d>; + pinctrl-names = "default\0isp_dvp8bit2\0isp_dvp10bit\0isp_dvp12bit"; + pinctrl-0 = <0xa7>; + pinctrl-1 = <0xa5>; + pinctrl-2 = <0xa5 0xa8>; + pinctrl-3 = <0xa9 0xa5 0xa8>; + rockchip,isp,mipiphy = <0x01>; + rockchip,isp,csiphy,reg = <0xff2f0000 0x4000>; + rockchip,grf = <0x2f>; + rockchip,cru = <0x02>; + rockchip,isp,iommu-enable = <0x01>; + iommus = <0xaa>; + status = "disabled"; + phandle = <0x113>; + }; + + rkisp1@ff4a0000 { + compatible = "rockchip,rk3326-rkisp1"; + reg = <0x00 0xff4a0000 0x00 0x8000>; + interrupts = <0x00 0x46 0x04 0x00 0x49 0x04 0x00 0x4a 0x04>; + interrupt-names = "isp_irq\0mi_irq\0mipi_irq"; + clocks = <0x02 0xb4 0x02 0xfa 0x02 0x33 0x02 0x15f>; + clock-names = "aclk_isp\0hclk_isp\0clk_isp\0pclk_isp"; + devfreq = <0xab>; + power-domains = <0x8a 0x0d>; + iommus = <0xaa>; + rockchip,grf = <0x2f>; + status = "okay"; + phandle = <0x114>; + }; + + iommu@ff4a8000 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff4a8000 0x00 0x100>; + interrupts = <0x00 0x46 0x04>; + interrupt-names = "isp_mmu"; + clocks = <0x02 0xb4 0x02 0xfa>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0d>; + rk_iommu,disable_reset_quirk; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xaa>; + }; + + qos@ff518000 { + compatible = "syscon"; + reg = <0x00 0xff518000 0x00 0x20>; + phandle = <0x18>; + }; + + qos@ff520000 { + compatible = "syscon"; + reg = <0x00 0xff520000 0x00 0x20>; + phandle = <0x28>; + }; + + qos@ff52c000 { + compatible = "syscon"; + reg = <0x00 0xff52c000 0x00 0x20>; + phandle = <0x17>; + }; + + qos@ff538000 { + compatible = "syscon"; + reg = <0x00 0xff538000 0x00 0x20>; + phandle = <0x19>; + }; + + qos@ff538080 { + compatible = "syscon"; + reg = <0x00 0xff538080 0x00 0x20>; + phandle = <0x1a>; + }; + + qos@ff538100 { + compatible = "syscon"; + reg = <0x00 0xff538100 0x00 0x20>; + phandle = <0x1b>; + }; + + qos@ff538180 { + compatible = "syscon"; + reg = <0x00 0xff538180 0x00 0x20>; + phandle = <0x1c>; + }; + + qos@ff540000 { + compatible = "syscon"; + reg = <0x00 0xff540000 0x00 0x20>; + phandle = <0x15>; + }; + + qos@ff540080 { + compatible = "syscon"; + reg = <0x00 0xff540080 0x00 0x20>; + phandle = <0x16>; + }; + + qos@ff548000 { + compatible = "syscon"; + reg = <0x00 0xff548000 0x00 0x20>; + phandle = <0x23>; + }; + + qos@ff548080 { + compatible = "syscon"; + reg = <0x00 0xff548080 0x00 0x20>; + phandle = <0x24>; + }; + + qos@ff548100 { + compatible = "syscon"; + reg = <0x00 0xff548100 0x00 0x20>; + phandle = <0x25>; + }; + + qos@ff548180 { + compatible = "syscon"; + reg = <0x00 0xff548180 0x00 0x20>; + phandle = <0x26>; + }; + + qos@ff548200 { + compatible = "syscon"; + reg = <0x00 0xff548200 0x00 0x20>; + phandle = <0x27>; + }; + + qos@ff550000 { + compatible = "syscon"; + reg = <0x00 0xff550000 0x00 0x20>; + phandle = <0x1f>; + }; + + qos@ff550080 { + compatible = "syscon"; + reg = <0x00 0xff550080 0x00 0x20>; + phandle = <0x20>; + }; + + qos@ff550100 { + compatible = "syscon"; + reg = <0x00 0xff550100 0x00 0x20>; + phandle = <0x21>; + }; + + qos@ff550180 { + compatible = "syscon"; + reg = <0x00 0xff550180 0x00 0x20>; + phandle = <0x22>; + }; + + qos@ff558000 { + compatible = "syscon"; + reg = <0x00 0xff558000 0x00 0x20>; + phandle = <0x1d>; + }; + + qos@ff558080 { + compatible = "syscon"; + reg = <0x00 0xff558080 0x00 0x20>; + phandle = <0x1e>; + }; + + dfi@ff610000 { + reg = <0x00 0xff610000 0x00 0x400>; + compatible = "rockchip,px30-dfi"; + rockchip,pmugrf = <0xac>; + status = "okay"; + phandle = <0xad>; + }; + + dmc { + compatible = "rockchip,px30-dmc"; + interrupts = <0x00 0x69 0x04>; + interrupt-names = "complete_irq"; + devfreq-events = <0xad>; + clocks = <0x02 0x54>; + clock-names = "dmc_clk"; + operating-points-v2 = <0xae>; + ddr_timing = <0xaf>; + upthreshold = <0x28>; + downdifferential = <0x14>; + system-status-freq = <0x01 0x80e80 0x08 0x6ddd0 0x02 0x2f5d0 0x20 0x6ddd0 0x1000 0x80e80 0x4000 0xa2990 0x2000 0xa2990>; + auto-min-freq = <0x50140>; + auto-freq-en = <0x01>; + #cooling-cells = <0x02>; + status = "okay"; + center-supply = <0x0e>; + phandle = <0xab>; + + ddr_power_model { + compatible = "ddr_power_model"; + dynamic-power-coefficient = <0x78>; + static-power-coefficient = <0xc8>; + ts = <0x7d00 0x125c 0xffffffb0 0x02>; + thermal-zone = "soc-thermal"; + phandle = <0x115>; + }; + }; + + dmc-opp-table { + compatible = "operating-points-v2"; + rockchip,max-volt = <0x118c30>; + rockchip,evb-irdrop = <0x61a8>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-ch = <0x00 0x00>; + phandle = <0xae>; + + opp-528000000 { + opp-hz = <0x00 0x1f78a400>; + opp-microvolt = <0xee098>; + opp-microvolt-L0 = <0xee098>; + opp-microvolt-L1 = <0xee098>; + opp-microvolt-L2 = <0xe7ef0>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-666000000 { + opp-hz = <0x00 0x27b25a80>; + opp-microvolt = <0x100590>; + opp-microvolt-L0 = <0x100590>; + opp-microvolt-L1 = <0xf4240>; + opp-microvolt-L2 = <0xee098>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-786000000 { + opp-hz = <0x00 0x2ed96880>; + opp-microvolt = <0x10c8e0>; + opp-microvolt-L0 = <0x10c8e0>; + opp-microvolt-L1 = <0x100590>; + opp-microvolt-L2 = <0xfa3e8>; + opp-microvolt-L3 = <0xf4240>; + status = "okay"; + }; + }; + + rockchip-system-monitor { + compatible = "rockchip,system-monitor"; + rockchip,thermal-zone = "soc-thermal"; + rockchip,polling-delay = <0xc8>; + phandle = <0x116>; + }; + + pinctrl { + compatible = "rockchip,px30-pinctrl"; + rockchip,grf = <0x2f>; + rockchip,pmu = <0xac>; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + phandle = <0x117>; + + gpio0@ff040000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff040000 0x00 0x100>; + interrupts = <0x00 0x03 0x04>; + clocks = <0x2a 0x14>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x5c>; + + pwm0_hold_low { + gpio-hog; + gpios = <0x0f 0x00>; + output-low; + line-name = "rumble_en_hold_low"; + }; + }; + + gpio1@ff250000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff250000 0x00 0x100>; + interrupts = <0x00 0x04 0x04>; + clocks = <0x02 0x15c>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0xbf>; + }; + + gpio2@ff260000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff260000 0x00 0x100>; + interrupts = <0x00 0x05 0x04>; + clocks = <0x02 0x15d>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x66>; + }; + + gpio3@ff270000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff270000 0x00 0x100>; + interrupts = <0x00 0x06 0x04>; + clocks = <0x02 0x15e>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x97>; + }; + + pcfg-pull-up { + bias-pull-up; + phandle = <0xb2>; + }; + + pcfg-pull-down { + bias-pull-down; + phandle = <0x118>; + }; + + pcfg-pull-none { + bias-disable; + phandle = <0xb1>; + }; + + pcfg-pull-none-2ma { + bias-disable; + drive-strength = <0x02>; + phandle = <0x119>; + }; + + pcfg-pull-up-2ma { + bias-pull-up; + drive-strength = <0x02>; + phandle = <0x11a>; + }; + + pcfg-pull-up-4ma { + bias-pull-up; + drive-strength = <0x04>; + phandle = <0xb3>; + }; + + pcfg-pull-none-4ma { + bias-disable; + drive-strength = <0x04>; + phandle = <0x11b>; + }; + + pcfg-pull-down-4ma { + bias-pull-down; + drive-strength = <0x04>; + phandle = <0x11c>; + }; + + pcfg-pull-none-8ma { + bias-disable; + drive-strength = <0x08>; + phandle = <0xb6>; + }; + + pcfg-pull-up-8ma { + bias-pull-up; + drive-strength = <0x08>; + phandle = <0xb4>; + }; + + pcfg-pull-none-12ma { + bias-disable; + drive-strength = <0x0c>; + phandle = <0xb8>; + }; + + pcfg-pull-up-12ma { + bias-pull-up; + drive-strength = <0x0c>; + phandle = <0xb7>; + }; + + pcfg-pull-none-smt { + bias-disable; + input-schmitt-enable; + phandle = <0xb0>; + }; + + pcfg-output-high { + output-high; + phandle = <0x11d>; + }; + + pcfg-output-low { + output-low; + phandle = <0xb9>; + }; + + pcfg-input-high { + bias-pull-up; + input-enable; + phandle = <0xb5>; + }; + + pcfg-input { + input-enable; + phandle = <0x11e>; + }; + + i2c0 { + + i2c0-xfer { + rockchip,pins = <0x00 0x08 0x01 0xb0 0x00 0x09 0x01 0xb0>; + phandle = <0x5b>; + }; + }; + + i2c1 { + + i2c1-xfer { + rockchip,pins = <0x00 0x12 0x01 0xb0 0x00 0x13 0x01 0xb0>; + phandle = <0x69>; + }; + }; + + i2c2 { + + i2c2-xfer { + rockchip,pins = <0x02 0x0f 0x02 0xb0 0x02 0x10 0x02 0xb0>; + phandle = <0x6a>; + }; + }; + + i2c3 { + + i2c3-xfer { + rockchip,pins = <0x01 0x0c 0x04 0xb0 0x01 0x0d 0x04 0xb0>; + phandle = <0x6b>; + }; + }; + + tsadc { + + tsadc-otp-gpio { + rockchip,pins = <0x00 0x06 0x00 0xb1>; + phandle = <0x86>; + }; + + tsadc-otp-out { + rockchip,pins = <0x00 0x06 0x01 0xb1>; + phandle = <0x87>; + }; + }; + + uart0 { + + uart0-xfer { + rockchip,pins = <0x00 0x0a 0x01 0xb2 0x00 0x0b 0x01 0xb2>; + phandle = <0x2c>; + }; + + uart0-cts { + rockchip,pins = <0x00 0x0c 0x01 0xb1>; + phandle = <0x2d>; + }; + + uart0-rts { + rockchip,pins = <0x00 0x0d 0x01 0xb1>; + phandle = <0x2e>; + }; + + uart0-rts-gpio { + rockchip,pins = <0x00 0x0d 0x00 0xb1>; + phandle = <0x11f>; + }; + }; + + uart1 { + + uart1-xfer { + rockchip,pins = <0x01 0x11 0x01 0xb2 0x01 0x10 0x01 0xb2>; + phandle = <0x4f>; + }; + + uart1-cts { + rockchip,pins = <0x01 0x12 0x01 0xb1>; + phandle = <0x50>; + }; + + uart1-rts { + rockchip,pins = <0x01 0x13 0x01 0xb1>; + phandle = <0x120>; + }; + + uart1-rts-gpio { + rockchip,pins = <0x01 0x13 0x00 0xb1>; + phandle = <0x121>; + }; + }; + + uart2-m0 { + + uart2m0-xfer { + rockchip,pins = <0x01 0x1a 0x02 0xb2 0x01 0x1b 0x02 0xb2>; + phandle = <0x51>; + }; + }; + + uart2-m1 { + + uart2m1-xfer { + rockchip,pins = <0x02 0x0c 0x02 0xb2 0x02 0x0e 0x02 0xb2>; + phandle = <0xba>; + }; + }; + + uart3-m0 { + + uart3m0-xfer { + rockchip,pins = <0x00 0x10 0x02 0xb2 0x00 0x11 0x02 0xb2>; + phandle = <0x122>; + }; + + uart3m0-cts { + rockchip,pins = <0x00 0x12 0x02 0xb1>; + phandle = <0x123>; + }; + + uart3m0-rts { + rockchip,pins = <0x00 0x13 0x02 0xb1>; + phandle = <0x124>; + }; + + uart3m0-rts-gpio { + rockchip,pins = <0x00 0x13 0x00 0xb1>; + phandle = <0x125>; + }; + }; + + uart3-m1 { + + uart3m1-xfer { + rockchip,pins = <0x01 0x0e 0x02 0xb2 0x01 0x0f 0x02 0xb2>; + phandle = <0x52>; + }; + + uart3m1-cts { + rockchip,pins = <0x01 0x0c 0x02 0xb1>; + phandle = <0x53>; + }; + + uart3m1-rts { + rockchip,pins = <0x01 0x0d 0x02 0xb1>; + phandle = <0x54>; + }; + + uart3m1-rts-gpio { + rockchip,pins = <0x01 0x0d 0x00 0xb1>; + phandle = <0x126>; + }; + }; + + uart4 { + + uart4-xfer { + rockchip,pins = <0x01 0x1c 0x02 0xb2 0x01 0x1d 0x02 0xb2>; + phandle = <0x55>; + }; + + uart4-cts { + rockchip,pins = <0x01 0x1e 0x02 0xb1>; + phandle = <0x56>; + }; + + uart4-rts { + rockchip,pins = <0x01 0x1f 0x02 0xb1>; + phandle = <0x57>; + }; + }; + + uart5 { + + uart5-xfer { + rockchip,pins = <0x03 0x02 0x04 0xb2 0x03 0x01 0x04 0xb2>; + phandle = <0x58>; + }; + + uart5-cts { + rockchip,pins = <0x03 0x03 0x04 0xb1>; + phandle = <0x59>; + }; + + uart5-rts { + rockchip,pins = <0x03 0x05 0x04 0xb1>; + phandle = <0x5a>; + }; + }; + + spi0 { + + spi0-clk { + rockchip,pins = <0x01 0x0f 0x03 0xb3>; + phandle = <0x6c>; + }; + + spi0-csn { + rockchip,pins = <0x01 0x0e 0x03 0xb3>; + phandle = <0x6d>; + }; + + spi0-miso { + rockchip,pins = <0x01 0x0d 0x03 0xb3>; + phandle = <0x6e>; + }; + + spi0-mosi { + rockchip,pins = <0x01 0x0c 0x03 0xb3>; + phandle = <0x6f>; + }; + + spi0-clk-hs { + rockchip,pins = <0x01 0x0f 0x03 0xb4>; + phandle = <0x70>; + }; + + spi0-miso-hs { + rockchip,pins = <0x01 0x0d 0x03 0xb4>; + phandle = <0x71>; + }; + + spi0-mosi-hs { + rockchip,pins = <0x01 0x0c 0x03 0xb4>; + phandle = <0x72>; + }; + }; + + spi1 { + + spi1-clk { + rockchip,pins = <0x03 0x0f 0x04 0xb3>; + phandle = <0x73>; + }; + + spi1-csn0 { + rockchip,pins = <0x03 0x09 0x04 0xb3>; + phandle = <0x74>; + }; + + spi1-csn1 { + rockchip,pins = <0x03 0x0a 0x02 0xb3>; + phandle = <0x75>; + }; + + spi1-miso { + rockchip,pins = <0x03 0x0e 0x04 0xb3>; + phandle = <0x76>; + }; + + spi1-mosi { + rockchip,pins = <0x03 0x0c 0x04 0xb3>; + phandle = <0x77>; + }; + + spi1-clk-hs { + rockchip,pins = <0x03 0x0f 0x04 0xb4>; + phandle = <0x78>; + }; + + spi1-miso-hs { + rockchip,pins = <0x03 0x0e 0x04 0xb4>; + phandle = <0x79>; + }; + + spi1-mosi-hs { + rockchip,pins = <0x03 0x0c 0x04 0xb4>; + phandle = <0x7a>; + }; + }; + + pdm { + + pdm-clk0m0 { + rockchip,pins = <0x03 0x16 0x02 0xb1>; + phandle = <0x44>; + }; + + pdm-clk0m1 { + rockchip,pins = <0x02 0x16 0x01 0xb1>; + phandle = <0x127>; + }; + + pdm-clk1 { + rockchip,pins = <0x03 0x17 0x02 0xb1>; + phandle = <0x45>; + }; + + pdm-sdi0m0 { + rockchip,pins = <0x03 0x1b 0x02 0xb1>; + phandle = <0x46>; + }; + + pdm-sdi0m1 { + rockchip,pins = <0x02 0x15 0x02 0xb1>; + phandle = <0x128>; + }; + + pdm-sdi1 { + rockchip,pins = <0x03 0x18 0x02 0xb1>; + phandle = <0x47>; + }; + + pdm-sdi2 { + rockchip,pins = <0x03 0x19 0x02 0xb1>; + phandle = <0x48>; + }; + + pdm-sdi3 { + rockchip,pins = <0x03 0x1a 0x02 0xb1>; + phandle = <0x49>; + }; + + pdm-clk0m0-sleep { + rockchip,pins = <0x03 0x16 0x00 0xb5>; + phandle = <0x129>; + }; + + pdm-clk0m1-sleep { + rockchip,pins = <0x02 0x16 0x00 0xb5>; + phandle = <0x12a>; + }; + + pdm-clk1-sleep { + rockchip,pins = <0x03 0x17 0x00 0xb5>; + phandle = <0x12b>; + }; + + pdm-sdi0m0-sleep { + rockchip,pins = <0x03 0x1b 0x00 0xb5>; + phandle = <0x12c>; + }; + + pdm-sdi0m1-sleep { + rockchip,pins = <0x02 0x15 0x00 0xb5>; + phandle = <0x12d>; + }; + + pdm-sdi1-sleep { + rockchip,pins = <0x03 0x18 0x00 0xb5>; + phandle = <0x12e>; + }; + + pdm-sdi2-sleep { + rockchip,pins = <0x03 0x19 0x00 0xb5>; + phandle = <0x12f>; + }; + + pdm-sdi3-sleep { + rockchip,pins = <0x03 0x1a 0x00 0xb5>; + phandle = <0x130>; + }; + }; + + i2s0 { + + i2s0-8ch-mclk { + rockchip,pins = <0x03 0x11 0x02 0xb1>; + phandle = <0x131>; + }; + + i2s0-8ch-sclktx { + rockchip,pins = <0x03 0x13 0x02 0xb1>; + phandle = <0x30>; + }; + + i2s0-8ch-sclkrx { + rockchip,pins = <0x03 0x0c 0x02 0xb1>; + phandle = <0x31>; + }; + + i2s0-8ch-lrcktx { + rockchip,pins = <0x03 0x12 0x02 0xb1>; + phandle = <0x32>; + }; + + i2s0-8ch-lrckrx { + rockchip,pins = <0x03 0x0d 0x02 0xb1>; + phandle = <0x33>; + }; + + i2s0-8ch-sdo0 { + rockchip,pins = <0x03 0x14 0x02 0xb1>; + phandle = <0x38>; + }; + + i2s0-8ch-sdo1 { + rockchip,pins = <0x03 0x10 0x02 0xb1>; + phandle = <0x39>; + }; + + i2s0-8ch-sdo2 { + rockchip,pins = <0x03 0x0f 0x02 0xb1>; + phandle = <0x3a>; + }; + + i2s0-8ch-sdo3 { + rockchip,pins = <0x03 0x0e 0x02 0xb1>; + phandle = <0x3b>; + }; + + i2s0-8ch-sdi0 { + rockchip,pins = <0x03 0x15 0x02 0xb1>; + phandle = <0x34>; + }; + + i2s0-8ch-sdi1 { + rockchip,pins = <0x03 0x0b 0x02 0xb1>; + phandle = <0x35>; + }; + + i2s0-8ch-sdi2 { + rockchip,pins = <0x03 0x09 0x02 0xb1>; + phandle = <0x36>; + }; + + i2s0-8ch-sdi3 { + rockchip,pins = <0x03 0x08 0x02 0xb1>; + phandle = <0x37>; + }; + }; + + i2s1 { + + i2s1-2ch-mclk { + rockchip,pins = <0x02 0x13 0x01 0xb1>; + phandle = <0x68>; + }; + + i2s1-2ch-sclk { + rockchip,pins = <0x02 0x12 0x01 0xb1>; + phandle = <0x3c>; + }; + + i2s1-2ch-lrck { + rockchip,pins = <0x02 0x11 0x01 0xb1>; + phandle = <0x3d>; + }; + + i2s1-2ch-sdi { + rockchip,pins = <0x02 0x15 0x01 0xb1>; + phandle = <0x3e>; + }; + + i2s1-2ch-sdo { + rockchip,pins = <0x02 0x14 0x01 0xb1>; + phandle = <0x3f>; + }; + }; + + i2s2 { + + i2s2-2ch-mclk { + rockchip,pins = <0x03 0x01 0x02 0xb1>; + phandle = <0x132>; + }; + + i2s2-2ch-sclk { + rockchip,pins = <0x03 0x02 0x02 0xb1>; + phandle = <0x40>; + }; + + i2s2-2ch-lrck { + rockchip,pins = <0x03 0x03 0x02 0xb1>; + phandle = <0x41>; + }; + + i2s2-2ch-sdi { + rockchip,pins = <0x03 0x05 0x02 0xb1>; + phandle = <0x42>; + }; + + i2s2-2ch-sdo { + rockchip,pins = <0x03 0x07 0x02 0xb1>; + phandle = <0x43>; + }; + }; + + sdmmc { + + sdmmc-clk { + rockchip,pins = <0x01 0x1e 0x01 0xb6>; + phandle = <0x8f>; + }; + + sdmmc-cmd { + rockchip,pins = <0x01 0x1f 0x01 0xb4>; + phandle = <0x90>; + }; + + sdmmc-det { + rockchip,pins = <0x00 0x03 0x01 0xb4>; + phandle = <0x91>; + }; + + sdmmc-bus1 { + rockchip,pins = <0x01 0x1a 0x01 0xb4>; + phandle = <0x133>; + }; + + sdmmc-bus4 { + rockchip,pins = <0x01 0x1a 0x01 0xb4 0x01 0x1b 0x01 0xb4 0x01 0x1c 0x01 0xb4 0x01 0x1d 0x01 0xb4>; + phandle = <0x92>; + }; + + sdmmc-gpio { + rockchip,pins = <0x01 0x1a 0x00 0xb3 0x01 0x1b 0x00 0xb3 0x01 0x1c 0x00 0xb3 0x01 0x1d 0x00 0xb3 0x01 0x1e 0x00 0xb3 0x01 0x1f 0x00 0xb3>; + phandle = <0x134>; + }; + }; + + sdio { + + sdio-clk { + rockchip,pins = <0x01 0x15 0x01 0xb1>; + phandle = <0x96>; + }; + + sdio-cmd { + rockchip,pins = <0x01 0x14 0x01 0xb2>; + phandle = <0x95>; + }; + + sdio-bus4 { + rockchip,pins = <0x01 0x16 0x01 0xb2 0x01 0x17 0x01 0xb2 0x01 0x18 0x01 0xb2 0x01 0x19 0x01 0xb2>; + phandle = <0x94>; + }; + + sdio-gpio { + rockchip,pins = <0x01 0x16 0x00 0xb2 0x01 0x17 0x00 0xb2 0x01 0x18 0x00 0xb2 0x01 0x19 0x00 0xb2 0x01 0x14 0x00 0xb2 0x01 0x15 0x00 0xb2>; + phandle = <0x135>; + }; + }; + + emmc { + + emmc-clk { + rockchip,pins = <0x01 0x09 0x02 0xb6>; + phandle = <0x136>; + }; + + emmc-cmd { + rockchip,pins = <0x01 0x0a 0x02 0xb4>; + phandle = <0x137>; + }; + + emmc-pwren { + rockchip,pins = <0x01 0x08 0x02 0xb1>; + phandle = <0x138>; + }; + + emmc-rstnout { + rockchip,pins = <0x01 0x0b 0x02 0xb1>; + phandle = <0x139>; + }; + + emmc-bus1 { + rockchip,pins = <0x01 0x00 0x02 0xb4>; + phandle = <0x13a>; + }; + + emmc-bus4 { + rockchip,pins = <0x01 0x00 0x02 0xb4 0x01 0x01 0x02 0xb4 0x01 0x02 0x02 0xb4 0x01 0x03 0x02 0xb4>; + phandle = <0x13b>; + }; + + emmc-bus8 { + rockchip,pins = <0x01 0x00 0x02 0xb4 0x01 0x01 0x02 0xb4 0x01 0x02 0x02 0xb4 0x01 0x03 0x02 0xb4 0x01 0x04 0x02 0xb4 0x01 0x05 0x02 0xb4 0x01 0x06 0x02 0xb4 0x01 0x07 0x02 0xb4>; + phandle = <0x13c>; + }; + }; + + flash { + + flash-cs0 { + rockchip,pins = <0x01 0x08 0x01 0xb1>; + phandle = <0x13d>; + }; + + flash-rdy { + rockchip,pins = <0x01 0x09 0x01 0xb1>; + phandle = <0x13e>; + }; + + flash-dqs { + rockchip,pins = <0x01 0x0a 0x01 0xb1>; + phandle = <0x13f>; + }; + + flash-ale { + rockchip,pins = <0x01 0x0b 0x01 0xb1>; + phandle = <0x140>; + }; + + flash-cle { + rockchip,pins = <0x01 0x0c 0x01 0xb1>; + phandle = <0x141>; + }; + + flash-wrn { + rockchip,pins = <0x01 0x0d 0x01 0xb1>; + phandle = <0x142>; + }; + + flash-csl { + rockchip,pins = <0x01 0x0e 0x01 0xb1>; + phandle = <0x143>; + }; + + flash-rdn { + rockchip,pins = <0x01 0x0f 0x01 0xb1>; + phandle = <0x144>; + }; + + flash-bus8 { + rockchip,pins = <0x01 0x00 0x01 0xb7 0x01 0x01 0x01 0xb7 0x01 0x02 0x01 0xb7 0x01 0x03 0x01 0xb7 0x01 0x04 0x01 0xb7 0x01 0x05 0x01 0xb7 0x01 0x06 0x01 0xb7 0x01 0x07 0x01 0xb7>; + phandle = <0x145>; + }; + }; + + lcdc { + + lcdc-m0-rgb-pins { + rockchip,pins = <0x03 0x00 0x01 0xb6 0x03 0x01 0x01 0xb6 0x03 0x02 0x01 0xb6 0x03 0x03 0x01 0xb6 0x03 0x04 0x01 0xb6 0x03 0x05 0x01 0xb6 0x03 0x06 0x01 0xb6 0x03 0x07 0x01 0xb6 0x03 0x08 0x01 0xb6 0x03 0x09 0x01 0xb6 0x03 0x0a 0x01 0xb6 0x03 0x0b 0x01 0xb6 0x03 0x0c 0x01 0xb6 0x03 0x0d 0x01 0xb6 0x03 0x0e 0x01 0xb6 0x03 0x0f 0x01 0xb6 0x03 0x10 0x01 0xb6 0x03 0x11 0x01 0xb6 0x03 0x12 0x01 0xb6 0x03 0x13 0x01 0xb6 0x03 0x14 0x01 0xb6 0x03 0x15 0x01 0xb6 0x03 0x16 0x01 0xb6 0x03 0x17 0x01 0xb6 0x03 0x18 0x01 0xb6 0x03 0x19 0x01 0xb6 0x03 0x1a 0x01 0xb6 0x03 0x1b 0x01 0xb6>; + phandle = <0x146>; + }; + + lcdc-m0-sleep-pins { + rockchip,pins = <0x03 0x00 0x00 0xb1 0x03 0x01 0x00 0xb1 0x03 0x02 0x00 0xb1 0x03 0x03 0x00 0xb1 0x03 0x04 0x00 0xb1 0x03 0x05 0x00 0xb1 0x03 0x06 0x00 0xb1 0x03 0x07 0x00 0xb1 0x03 0x08 0x00 0xb1 0x03 0x09 0x00 0xb1 0x03 0x0a 0x00 0xb1 0x03 0x0b 0x00 0xb1 0x03 0x0c 0x00 0xb1 0x03 0x0d 0x00 0xb1 0x03 0x0e 0x00 0xb1 0x03 0x0f 0x00 0xb1 0x03 0x10 0x00 0xb1 0x03 0x11 0x00 0xb1 0x03 0x12 0x00 0xb1 0x03 0x13 0x00 0xb1 0x03 0x14 0x00 0xb1 0x03 0x15 0x00 0xb1 0x03 0x16 0x00 0xb1 0x03 0x17 0x00 0xb1 0x03 0x18 0x00 0xb1 0x03 0x19 0x00 0xb1 0x03 0x1a 0x00 0xb1 0x03 0x1b 0x00 0xb1>; + phandle = <0x147>; + }; + + lcdc-m1-rgb-pins { + rockchip,pins = <0x03 0x00 0x01 0xb6 0x03 0x04 0x01 0xb6 0x03 0x06 0x01 0xb6 0x03 0x0a 0x01 0xb6 0x03 0x0b 0x01 0xb6 0x03 0x0d 0x01 0xb6 0x03 0x10 0x01 0xb6 0x03 0x11 0x01 0xb6 0x03 0x12 0x01 0xb6 0x03 0x13 0x01 0xb6 0x03 0x14 0x01 0xb6 0x03 0x15 0x01 0xb6 0x03 0x16 0x01 0xb6 0x03 0x17 0x01 0xb6 0x03 0x18 0x01 0xb6 0x03 0x19 0x01 0xb6 0x03 0x1a 0x01 0xb6 0x03 0x1b 0x01 0xb6>; + phandle = <0x4d>; + }; + + lcdc-m1-sleep-pins { + rockchip,pins = <0x03 0x00 0x00 0xb1 0x03 0x04 0x00 0xb1 0x03 0x06 0x00 0xb1 0x03 0x0a 0x00 0xb1 0x03 0x0b 0x00 0xb1 0x03 0x0d 0x00 0xb1 0x03 0x10 0x00 0xb1 0x03 0x11 0x00 0xb1 0x03 0x12 0x00 0xb1 0x03 0x13 0x00 0xb1 0x03 0x14 0x00 0xb1 0x03 0x15 0x00 0xb1 0x03 0x16 0x00 0xb1 0x03 0x17 0x00 0xb1 0x03 0x18 0x00 0xb1 0x03 0x19 0x00 0xb1 0x03 0x1a 0x00 0xb1 0x03 0x1b 0x00 0xb1>; + phandle = <0x4e>; + }; + }; + + pwm0 { + + pwm0-pin { + rockchip,pins = <0x00 0x0f 0x01 0x118>; + phandle = <0x7b>; + }; + }; + + pwm1 { + + pwm1-pin { + rockchip,pins = <0x00 0x10 0x01 0xb1>; + phandle = <0x7c>; + }; + }; + + pwm2 { + + pwm2-pin { + rockchip,pins = <0x02 0x0d 0x01 0xb1>; + phandle = <0x7d>; + }; + }; + + pwm3 { + + pwm3-pin { + rockchip,pins = <0x00 0x11 0x01 0xb1>; + phandle = <0x7e>; + }; + }; + + pwm4 { + + pwm4-pin { + rockchip,pins = <0x03 0x12 0x03 0xb1>; + phandle = <0x7f>; + }; + }; + + pwm5 { + + pwm5-pin { + rockchip,pins = <0x03 0x13 0x03 0xb1>; + phandle = <0x80>; + }; + }; + + pwm6 { + + pwm6-pin { + rockchip,pins = <0x03 0x14 0x03 0xb1>; + phandle = <0x81>; + }; + }; + + pwm7 { + + pwm7-pin { + rockchip,pins = <0x03 0x15 0x03 0xb1>; + phandle = <0x82>; + }; + }; + + gmac { + + rmii-pins { + rockchip,pins = <0x02 0x00 0x02 0xb8 0x02 0x01 0x02 0xb8 0x02 0x02 0x02 0xb8 0x02 0x03 0x02 0xb1 0x02 0x04 0x02 0xb1 0x02 0x05 0x02 0xb1 0x02 0x06 0x02 0xb1 0x02 0x07 0x02 0xb1 0x02 0x09 0x02 0xb1>; + phandle = <0x8d>; + }; + + mac-refclk-12ma { + rockchip,pins = <0x02 0x0a 0x02 0xb8>; + phandle = <0x8e>; + }; + + mac-refclk { + rockchip,pins = <0x02 0x0a 0x02 0xb1>; + phandle = <0x148>; + }; + }; + + cif-m0 { + + cif-clkout-m0 { + rockchip,pins = <0x02 0x0b 0x01 0xb8>; + phandle = <0xa7>; + }; + + dvp-d2d9-m0 { + rockchip,pins = <0x02 0x00 0x01 0xb1 0x02 0x01 0x01 0xb1 0x02 0x02 0x01 0xb1 0x02 0x03 0x01 0xb1 0x02 0x04 0x01 0xb1 0x02 0x05 0x01 0xb1 0x02 0x06 0x01 0xb1 0x02 0x07 0x01 0xb1 0x02 0x08 0x01 0xb1 0x02 0x09 0x01 0xb1 0x02 0x0a 0x01 0xb1 0x02 0x0b 0x01 0xb1>; + phandle = <0xa5>; + }; + + dvp-d0d1-m0 { + rockchip,pins = <0x02 0x0c 0x01 0xb1 0x02 0x0e 0x01 0xb1>; + phandle = <0xa9>; + }; + + d10-d11-m0 { + rockchip,pins = <0x02 0x0f 0x01 0xb1 0x02 0x10 0x01 0xb1>; + phandle = <0xa8>; + }; + }; + + cif-m1 { + + cif-clkout-m1 { + rockchip,pins = <0x03 0x18 0x03 0xb1>; + phandle = <0x149>; + }; + + dvp-d2d9-m1 { + rockchip,pins = <0x03 0x03 0x03 0xb1 0x03 0x05 0x03 0xb1 0x03 0x07 0x03 0xb1 0x03 0x08 0x03 0xb1 0x03 0x09 0x03 0xb1 0x03 0x0c 0x03 0xb1 0x03 0x0e 0x03 0xb1 0x03 0x0f 0x03 0xb1 0x03 0x19 0x03 0xb1 0x03 0x1a 0x03 0xb1 0x03 0x1b 0x03 0xb1 0x03 0x18 0x03 0xb1>; + phandle = <0x14a>; + }; + + dvp-d0d1-m1 { + rockchip,pins = <0x03 0x01 0x03 0xb1 0x03 0x02 0x03 0xb1>; + phandle = <0x14b>; + }; + + d10-d11-m1 { + rockchip,pins = <0x03 0x16 0x03 0xb1 0x03 0x17 0x03 0xb1>; + phandle = <0x14c>; + }; + }; + + isp { + + isp-prelight { + rockchip,pins = <0x03 0x19 0x04 0xb1>; + phandle = <0x14d>; + }; + }; + + pmic { + + pmic_int { + rockchip,pins = <0x00 0x0a 0x00 0xb2 0x00 0x0b 0x00 0xb1>; + phandle = <0x5d>; + }; + + soc_slppin_gpio { + rockchip,pins = <0x00 0x04 0x00 0xb9>; + phandle = <0x60>; + }; + + soc_slppin_slp { + rockchip,pins = <0x00 0x04 0x01 0xb1>; + phandle = <0x5e>; + }; + + soc_slppin_rst { + rockchip,pins = <0x00 0x04 0x02 0xb1>; + phandle = <0x62>; + }; + }; + + leds { + + led-pins { + rockchip,pins = <0x00 0x11 0x00 0xb1>; + phandle = <0xc0>; + }; + }; + + btns { + + btn-pins { + rockchip,pins = <0x01 0x0c 0x00 0xb2 0x01 0x0d 0x00 0xb2 0x01 0x0e 0x00 0xb2 0x01 0x0f 0x00 0xb2 0x01 0x02 0x00 0xb2 0x01 0x05 0x00 0xb2 0x01 0x06 0x00 0xb2 0x01 0x07 0x00 0xb2 0x02 0x00 0x00 0xb2 0x02 0x01 0x00 0xb2 0x02 0x02 0x00 0xb2 0x02 0x03 0x00 0xb2 0x02 0x04 0x00 0xb2 0x02 0x05 0x00 0xb2 0x02 0x06 0x00 0xb2 0x02 0x07 0x00 0xb2 0x03 0x09 0x00 0xb2 0x03 0x0a 0x00 0xb2 0x03 0x0c 0x00 0xb2 0x03 0x0f 0x00 0xb2>; + phandle = <0xbd>; + }; + }; + }; + + chosen { + bootargs = [00]; + }; + + fiq-debugger { + compatible = "rockchip,fiq-debugger"; + rockchip,serial-id = <0x02>; + rockchip,wake-irq = <0x00>; + rockchip,irq-mode-enable = <0x00>; + rockchip,baudrate = <0x1c200>; + interrupts = <0x00 0x7f 0x08>; + pinctrl-names = "default"; + pinctrl-0 = <0xba>; + status = "okay"; + }; + + ramoops { + compatible = "ramoops"; + record-size = <0x00 0x20000>; + console-size = <0x00 0x80000>; + ftrace-size = <0x00 0x00>; + pmsg-size = <0x00 0x00>; + memory-region = <0xbb>; + }; + + reserved-memory { + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + + drm-logo@00000000 { + compatible = "rockchip,drm-logo"; + reg = <0x00 0x00 0x00 0x00>; + phandle = <0x11>; + }; + + region@110000 { + reg = <0x00 0x110000 0x00 0xf0000>; + reg-names = "ramoops_mem"; + phandle = <0xbb>; + }; + }; + + odroidgo3-keys { + compatible = "gpio-keys"; + #address-cells = <0x01>; + #size-cells = <0x00>; + autorepeat; + phandle = <0x14e>; + + button@0 { + label = "GPIO BTN-VOLUP"; + linux,code = <0x73>; + gpios = <0x66 0x00 0x01>; + }; + + button@1 { + label = "GPIO BTN-VOLDN"; + linux,code = <0x72>; + gpios = <0x66 0x01 0x01>; + }; + }; + + odroidgo3-joypad { + compatible = "odroidgo3-joypad"; + pwms = <0xbc 0x00 0x1312d00 0x00>; + pwm-names = "enable"; + motor-supply = <0x200>; + rumble-boost-weak = <0x00>; + rumble-boost-strong = <0x00>; + joypad-name = "GO-Super Gamepad"; + joypad-product = <0x1100>; + joypad-revision = <0x100>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <0xbd>; + io-channel-names = "amux_adc"; + io-channels = <0xbe 0x01>; + amux-count = <0x04>; + amux-a-gpios = <0x97 0x0b 0x01>; + amux-b-gpios = <0x97 0x08 0x01>; + amux-en-gpios = <0x97 0x0d 0x01>; + button-adc-scale = <0x02>; + button-adc-deadzone = <0x40>; + button-adc-fuzz = <0x20>; + button-adc-flat = <0x20>; + abs_x-p-tuning = <0xc8>; + abs_x-n-tuning = <0xc8>; + abs_y-p-tuning = <0xc8>; + abs_y-n-tuning = <0xc8>; + abs_rx-p-tuning = <0xc8>; + abs_rx-n-tuning = <0xc8>; + abs_ry-p-tuning = <0xc8>; + abs_ry-n-tuning = <0xc8>; + poll-interval = <0x0a>; + invert-absx; + invert-absy; + phandle = <0x14f>; + + sw1 { + gpios = <0xbf 0x0c 0x01>; + label = "GPIO DPAD-UP"; + linux,code = <0x220>; + }; + + sw2 { + gpios = <0xbf 0x0d 0x01>; + label = "GPIO DPAD-DOWN"; + linux,code = <0x221>; + }; + + sw3 { + gpios = <0xbf 0x0e 0x01>; + label = "GPIO DPAD-LEFT"; + linux,code = <0x222>; + }; + + sw4 { + gpios = <0xbf 0x0f 0x01>; + label = "GPIO DPAD-RIGHT"; + linux,code = <0x223>; + }; + + sw5 { + gpios = <0xbf 0x02 0x01>; + label = "GPIO KEY BTN-A"; + linux,code = <0x131>; + }; + + sw6 { + gpios = <0xbf 0x05 0x01>; + label = "GPIO BTN-B"; + linux,code = <0x130>; + }; + + sw7 { + gpios = <0xbf 0x06 0x01>; + label = "GPIO BTN-Y"; + linux,code = <0x134>; + }; + + sw8 { + gpios = <0xbf 0x07 0x01>; + label = "GPIO BTN-X"; + linux,code = <0x133>; + }; + + sw11 { + gpios = <0x66 0x02 0x01>; + label = "GPIO F3"; + linux,code = <0x2c2>; + }; + + sw12 { + gpios = <0x66 0x03 0x01>; + label = "GPIO F4"; + linux,code = <0x2c3>; + }; + + sw15 { + gpios = <0x66 0x06 0x01>; + label = "GPIO TOP-LEFT"; + linux,code = <0x136>; + }; + + sw16 { + gpios = <0x66 0x07 0x01>; + label = "GPIO TOP-RIGHT"; + linux,code = <0x137>; + }; + + sw19 { + gpios = <0x97 0x09 0x01>; + label = "GPIO F1"; + linux,code = <0x2c0>; + }; + + sw20 { + gpios = <0x97 0x0f 0x01>; + label = "GPIO TOP-RIGHT2"; + linux,code = <0x139>; + }; + + sw21 { + gpios = <0x97 0x0a 0x01>; + label = "GPIO TOP-LEFT2"; + linux,code = <0x138>; + }; + + sw22 { + gpios = <0x97 0x0c 0x01>; + label = "GPIO F2"; + linux,code = <0x2c1>; + }; + + sw13 { + gpios = <0x66 0x04 0x01>; + label = "GPIO F5"; + linux,code = <0x2c4>; + }; + }; + + gpio_leds { + compatible = "gpio-leds"; + pinctrl-names = "led_pins"; + pinctrl-0 = <0xc0>; + phandle = <0x150>; + + heartbeat { + label = "blue:heartbeat"; + gpios = <0x5c 0x11 0x00>; + linux,default-trigger = "heartbeat"; + }; + }; + + backlight { + compatible = "pwm-backlight"; + pwms = <0xc1 0x00 0xf519 0x00>; + brightness-levels = <0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2a 0x2b 0x2c 0x2d 0x2e 0x2f 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x3a 0x3b 0x3c 0x3d 0x3e 0x3f 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48 0x49 0x4a 0x4b 0x4c 0x4d 0x4e 0x4f 0x50 0x51 0x52 0x53 0x54 0x55 0x56 0x57 0x58 0x59 0x5a 0x5b 0x5c 0x5d 0x5e 0x5f 0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69 0x6a 0x6b 0x6c 0x6d 0x6e 0x6f 0x70 0x71 0x72 0x73 0x74 0x75 0x76 0x77 0x78 0x79 0x7a 0x7b 0x7c 0x7d 0x7e 0x7f 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90 0x91 0x92 0x93 0x94 0x95 0x96 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f 0xa0>; + default-brightness-level = <0x33>; + phandle = <0x9d>; + }; + + rk817-sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,name = "rockchip,rk817-codec"; + simple-audio-card,mclk-fs = <0x100>; + simple-audio-card,widgets = "Microphone\0Mic Jack\0Headphone\0Headphone Jack"; + simple-audio-card,routing = "MIC_IN\0Mic Jack\0Headphone Jack\0HPOL\0Headphone Jack\0HPOR"; + simple-audio-card,hp-det-gpio = <0x66 0x16 0x01>; + simple-audio-card,codec-hp-det = <0x01>; + + simple-audio-card,cpu { + sound-dai = <0xc2>; + }; + + simple-audio-card,codec { + sound-dai = <0xc3>; + }; + }; + + vccsys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v8_sys"; + regulator-always-on; + regulator-min-microvolt = <0x39fbc0>; + regulator-max-microvolt = <0x39fbc0>; + phandle = <0x64>; + }; + + __symbols__ { + ddr_timing = "/ddr_timing"; + cpu0 = "/cpus/cpu@0"; + cpu1 = "/cpus/cpu@1"; + cpu2 = "/cpus/cpu@2"; + cpu3 = "/cpus/cpu@3"; + CPU_SLEEP = "/cpus/idle-states/cpu-sleep"; + CLUSTER_SLEEP = "/cpus/idle-states/cluster-sleep"; + cpu0_opp_table = "/cpu0-opp-table"; + bus_soc = "/bus-soc"; + bus_apll = "/bus-apll"; + bus_apll_opp_table = "/bus-apll-opp-table"; + display_subsystem = "/display-subsystem"; + route_lvds = "/display-subsystem/route/route-lvds"; + route_dsi = "/display-subsystem/route/route-dsi"; + route_rgb = "/display-subsystem/route/route-rgb"; + gmac_clkin = "/external-gmac-clock"; + rockchip_suspend = "/rockchip-suspend"; + xin24m = "/xin24m"; + xin32k = "/xin32k"; + pmu = "/power-management@ff000000"; + power = "/power-management@ff000000/power-controller"; + pmugrf = "/syscon@ff010000"; + pmu_io_domains = "/syscon@ff010000/io-domains"; + pmu_pvtm = "/syscon@ff010000/pmu-pvtm"; + uart0 = "/serial@ff030000"; + i2s0_8ch = "/i2s@ff060000"; + i2s1_2ch = "/i2s@ff070000"; + i2s2_2ch = "/i2s@ff080000"; + pdm = "/pdm@ff0a0000"; + crypto = "/crypto@ff0b0000"; + rng = "/rng@ff0b0000"; + gic = "/interrupt-controller@ff131000"; + grf = "/syscon@ff140000"; + io_domains = "/syscon@ff140000/io-domains"; + lvds = "/syscon@ff140000/lvds"; + lvds_in_vopb = "/syscon@ff140000/lvds/ports/port@0/endpoint@0"; + rgb = "/syscon@ff140000/rgb"; + rgb_in_vopb = "/syscon@ff140000/rgb/ports/port@0/endpoint@0"; + core_grf = "/syscon@ff148000"; + pvtm = "/syscon@ff148000/pvtm"; + uart1 = "/serial@ff158000"; + uart2 = "/serial@ff160000"; + uart3 = "/serial@ff168000"; + uart4 = "/serial@ff170000"; + uart5 = "/serial@ff178000"; + i2c0 = "/i2c@ff180000"; + rk817 = "/i2c@ff180000/pmic@20"; + pinctrl_rk8xx = "/i2c@ff180000/pmic@20/pinctrl_rk8xx"; + rk817_ts_gpio1 = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_ts_gpio1"; + rk817_gt_gpio2 = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_gt_gpio2"; + rk817_pin_ts = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_pin_ts"; + rk817_pin_gt = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_pin_gt"; + rk817_slppin_null = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_null"; + rk817_slppin_slp = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_slp"; + rk817_slppin_pwrdn = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_pwrdn"; + rk817_slppin_rst = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_rst"; + vdd_logic = "/i2c@ff180000/pmic@20/regulators/DCDC_REG1"; + vdd_arm = "/i2c@ff180000/pmic@20/regulators/DCDC_REG2"; + vcc_ddr = "/i2c@ff180000/pmic@20/regulators/DCDC_REG3"; + vcc_3v3 = "/i2c@ff180000/pmic@20/regulators/DCDC_REG4"; + vcc_1v0 = "/i2c@ff180000/pmic@20/regulators/LDO_REG1"; + vcc1v8_soc = "/i2c@ff180000/pmic@20/regulators/LDO_REG2"; + vdd1v0_soc = "/i2c@ff180000/pmic@20/regulators/LDO_REG3"; + vcc3v3_pmu = "/i2c@ff180000/pmic@20/regulators/LDO_REG4"; + vccio_sd = "/i2c@ff180000/pmic@20/regulators/LDO_REG5"; + vcc_sd = "/i2c@ff180000/pmic@20/regulators/LDO_REG6"; + vcc_backlight = "/i2c@ff180000/pmic@20/regulators/LDO_REG7"; + vcc_lcd = "/i2c@ff180000/pmic@20/regulators/LDO_REG8"; + dcdc_boost = "/i2c@ff180000/pmic@20/regulators/BOOST"; + otg_switch = "/i2c@ff180000/pmic@20/regulators/OTG_SWITCH"; + rk817_codec = "/i2c@ff180000/pmic@20/codec"; + i2c1 = "/i2c@ff190000"; + i2c2 = "/i2c@ff1a0000"; + i2c3 = "/i2c@ff1b0000"; + spi0 = "/spi@ff1d0000"; + spi1 = "/spi@ff1d8000"; + wdt = "/watchdog@ff1e0000"; + pwm0 = "/pwm@ff200000"; + pwm1 = "/pwm@ff200010"; + pwm2 = "/pwm@ff200020"; + pwm3 = "/pwm@ff200030"; + pwm4 = "/pwm@ff208000"; + pwm5 = "/pwm@ff208010"; + pwm6 = "/pwm@ff208020"; + pwm7 = "/pwm@ff208030"; + rktimer = "/rktimer@ff210000"; + dmac = "/amba/dmac@ff240000"; + thermal_zones = "/thermal-zones"; + soc_thermal = "/thermal-zones/soc-thermal"; + threshold = "/thermal-zones/soc-thermal/trips/trip-point-0"; + target = "/thermal-zones/soc-thermal/trips/trip-point-1"; + soc_crit = "/thermal-zones/soc-thermal/trips/soc-crit"; + gpu_thermal = "/thermal-zones/gpu-thermal"; + tsadc = "/tsadc@ff280000"; + saradc = "/saradc@ff288000"; + otp = "/otp@ff290000"; + otp_id = "/otp@ff290000/id@7"; + cpu_leakage = "/otp@ff290000/cpu-leakage@17"; + performance = "/otp@ff290000/performance@1e"; + cru = "/clock-controller@ff2b0000"; + cpu_boost = "/cpu-boost@ff2b8000"; + pmucru = "/pmu-clock-controller@ff2bc000"; + usb2phy_grf = "/syscon@ff2c0000"; + u2phy = "/syscon@ff2c0000/usb2-phy@100"; + u2phy_host = "/syscon@ff2c0000/usb2-phy@100/host-port"; + u2phy_otg = "/syscon@ff2c0000/usb2-phy@100/otg-port"; + video_phy = "/video-phy@ff2e0000"; + mipi_dphy_rx0 = "/mipi-dphy-rx0@ff2f0000"; + usb20_otg = "/usb@ff300000"; + usb_host0_ehci = "/usb@ff340000"; + usb_host0_ohci = "/usb@ff350000"; + gmac = "/ethernet@ff360000"; + sdmmc = "/dwmmc@ff370000"; + sdio = "/dwmmc@ff380000"; + emmc = "/dwmmc@ff390000"; + nandc0 = "/nandc@ff3b0000"; + sfc = "/sfc@ff3a0000"; + gpu = "/gpu@ff400000"; + gpu_opp_table = "/gpu-opp-table"; + hevc = "/hevc_service@ff440000"; + vpu = "/vpu_service@ff442000"; + vpu_combo = "/vpu_combo"; + hevc_mmu = "/iommu@ff440440"; + vpu_mmu = "/iommu@ff442800"; + dsi = "/dsi@ff450000"; + dsi_in_vopb = "/dsi@ff450000/ports/port@0/endpoint@0"; + timing0 = "/dsi@ff450000/panel@0/display-timings/60Hz"; + timing1 = "/dsi@ff450000/panel@0/display-timings/50Hz"; + timing2 = "/dsi@ff450000/panel@0/display-timings/75Hz"; + vopb = "/vop@ff460000"; + vopb_out = "/vop@ff460000/port"; + vopb_out_lvds = "/vop@ff460000/port/endpoint@0"; + vopb_out_dsi = "/vop@ff460000/port/endpoint@1"; + vopb_out_rgb = "/vop@ff460000/port/endpoint@2"; + vopb_mmu = "/iommu@ff460f00"; + rk_rga = "/rk_rga@ff480000"; + cif = "/cif@ff490000"; + cif_new = "/cif-new@ff490000"; + vip_mmu = "/iommu@ff490800"; + rk_isp = "/rk_isp@ff4a0000"; + rkisp1 = "/rkisp1@ff4a0000"; + isp_mmu = "/iommu@ff4a8000"; + qos_gmac = "/qos@ff518000"; + qos_gpu = "/qos@ff520000"; + qos_sdmmc = "/qos@ff52c000"; + qos_emmc = "/qos@ff538000"; + qos_nand = "/qos@ff538080"; + qos_sdio = "/qos@ff538100"; + qos_sfc = "/qos@ff538180"; + qos_usb_host = "/qos@ff540000"; + qos_usb_otg = "/qos@ff540080"; + qos_isp_128 = "/qos@ff548000"; + qos_isp_rd = "/qos@ff548080"; + qos_isp_wr = "/qos@ff548100"; + qos_isp_m1 = "/qos@ff548180"; + qos_vip = "/qos@ff548200"; + qos_rga_rd = "/qos@ff550000"; + qos_rga_wr = "/qos@ff550080"; + qos_vop_m0 = "/qos@ff550100"; + qos_vop_m1 = "/qos@ff550180"; + qos_vpu = "/qos@ff558000"; + qos_vpu_r128 = "/qos@ff558080"; + dfi = "/dfi@ff610000"; + dmc = "/dmc"; + ddr_power_model = "/dmc/ddr_power_model"; + dmc_opp_table = "/dmc-opp-table"; + rockchip_system_monitor = "/rockchip-system-monitor"; + pinctrl = "/pinctrl"; + gpio0 = "/pinctrl/gpio0@ff040000"; + gpio1 = "/pinctrl/gpio1@ff250000"; + gpio2 = "/pinctrl/gpio2@ff260000"; + gpio3 = "/pinctrl/gpio3@ff270000"; + pcfg_pull_up = "/pinctrl/pcfg-pull-up"; + pcfg_pull_down = "/pinctrl/pcfg-pull-down"; + pcfg_pull_none = "/pinctrl/pcfg-pull-none"; + pcfg_pull_none_2ma = "/pinctrl/pcfg-pull-none-2ma"; + pcfg_pull_up_2ma = "/pinctrl/pcfg-pull-up-2ma"; + pcfg_pull_up_4ma = "/pinctrl/pcfg-pull-up-4ma"; + pcfg_pull_none_4ma = "/pinctrl/pcfg-pull-none-4ma"; + pcfg_pull_down_4ma = "/pinctrl/pcfg-pull-down-4ma"; + pcfg_pull_none_8ma = "/pinctrl/pcfg-pull-none-8ma"; + pcfg_pull_up_8ma = "/pinctrl/pcfg-pull-up-8ma"; + pcfg_pull_none_12ma = "/pinctrl/pcfg-pull-none-12ma"; + pcfg_pull_up_12ma = "/pinctrl/pcfg-pull-up-12ma"; + pcfg_pull_none_smt = "/pinctrl/pcfg-pull-none-smt"; + pcfg_output_high = "/pinctrl/pcfg-output-high"; + pcfg_output_low = "/pinctrl/pcfg-output-low"; + pcfg_input_high = "/pinctrl/pcfg-input-high"; + pcfg_input = "/pinctrl/pcfg-input"; + i2c0_xfer = "/pinctrl/i2c0/i2c0-xfer"; + i2c1_xfer = "/pinctrl/i2c1/i2c1-xfer"; + i2c2_xfer = "/pinctrl/i2c2/i2c2-xfer"; + i2c3_xfer = "/pinctrl/i2c3/i2c3-xfer"; + tsadc_otp_gpio = "/pinctrl/tsadc/tsadc-otp-gpio"; + tsadc_otp_out = "/pinctrl/tsadc/tsadc-otp-out"; + uart0_xfer = "/pinctrl/uart0/uart0-xfer"; + uart0_cts = "/pinctrl/uart0/uart0-cts"; + uart0_rts = "/pinctrl/uart0/uart0-rts"; + uart0_rts_gpio = "/pinctrl/uart0/uart0-rts-gpio"; + uart1_xfer = "/pinctrl/uart1/uart1-xfer"; + uart1_cts = "/pinctrl/uart1/uart1-cts"; + uart1_rts = "/pinctrl/uart1/uart1-rts"; + uart1_rts_gpio = "/pinctrl/uart1/uart1-rts-gpio"; + uart2m0_xfer = "/pinctrl/uart2-m0/uart2m0-xfer"; + uart2m1_xfer = "/pinctrl/uart2-m1/uart2m1-xfer"; + uart3m0_xfer = "/pinctrl/uart3-m0/uart3m0-xfer"; + uart3m0_cts = "/pinctrl/uart3-m0/uart3m0-cts"; + uart3m0_rts = "/pinctrl/uart3-m0/uart3m0-rts"; + uart3m0_rts_gpio = "/pinctrl/uart3-m0/uart3m0-rts-gpio"; + uart3m1_xfer = "/pinctrl/uart3-m1/uart3m1-xfer"; + uart3m1_cts = "/pinctrl/uart3-m1/uart3m1-cts"; + uart3m1_rts = "/pinctrl/uart3-m1/uart3m1-rts"; + uart3m1_rts_gpio = "/pinctrl/uart3-m1/uart3m1-rts-gpio"; + uart4_xfer = "/pinctrl/uart4/uart4-xfer"; + uart4_cts = "/pinctrl/uart4/uart4-cts"; + uart4_rts = "/pinctrl/uart4/uart4-rts"; + uart5_xfer = "/pinctrl/uart5/uart5-xfer"; + uart5_cts = "/pinctrl/uart5/uart5-cts"; + uart5_rts = "/pinctrl/uart5/uart5-rts"; + spi0_clk = "/pinctrl/spi0/spi0-clk"; + spi0_csn = "/pinctrl/spi0/spi0-csn"; + spi0_miso = "/pinctrl/spi0/spi0-miso"; + spi0_mosi = "/pinctrl/spi0/spi0-mosi"; + spi0_clk_hs = "/pinctrl/spi0/spi0-clk-hs"; + spi0_miso_hs = "/pinctrl/spi0/spi0-miso-hs"; + spi0_mosi_hs = "/pinctrl/spi0/spi0-mosi-hs"; + spi1_clk = "/pinctrl/spi1/spi1-clk"; + spi1_csn0 = "/pinctrl/spi1/spi1-csn0"; + spi1_csn1 = "/pinctrl/spi1/spi1-csn1"; + spi1_miso = "/pinctrl/spi1/spi1-miso"; + spi1_mosi = "/pinctrl/spi1/spi1-mosi"; + spi1_clk_hs = "/pinctrl/spi1/spi1-clk-hs"; + spi1_miso_hs = "/pinctrl/spi1/spi1-miso-hs"; + spi1_mosi_hs = "/pinctrl/spi1/spi1-mosi-hs"; + pdm_clk0m0 = "/pinctrl/pdm/pdm-clk0m0"; + pdm_clk0m1 = "/pinctrl/pdm/pdm-clk0m1"; + pdm_clk1 = "/pinctrl/pdm/pdm-clk1"; + pdm_sdi0m0 = "/pinctrl/pdm/pdm-sdi0m0"; + pdm_sdi0m1 = "/pinctrl/pdm/pdm-sdi0m1"; + pdm_sdi1 = "/pinctrl/pdm/pdm-sdi1"; + pdm_sdi2 = "/pinctrl/pdm/pdm-sdi2"; + pdm_sdi3 = "/pinctrl/pdm/pdm-sdi3"; + pdm_clk0m0_sleep = "/pinctrl/pdm/pdm-clk0m0-sleep"; + pdm_clk0m_sleep1 = "/pinctrl/pdm/pdm-clk0m1-sleep"; + pdm_clk1_sleep = "/pinctrl/pdm/pdm-clk1-sleep"; + pdm_sdi0m0_sleep = "/pinctrl/pdm/pdm-sdi0m0-sleep"; + pdm_sdi0m1_sleep = "/pinctrl/pdm/pdm-sdi0m1-sleep"; + pdm_sdi1_sleep = "/pinctrl/pdm/pdm-sdi1-sleep"; + pdm_sdi2_sleep = "/pinctrl/pdm/pdm-sdi2-sleep"; + pdm_sdi3_sleep = "/pinctrl/pdm/pdm-sdi3-sleep"; + i2s0_8ch_mclk = "/pinctrl/i2s0/i2s0-8ch-mclk"; + i2s0_8ch_sclktx = "/pinctrl/i2s0/i2s0-8ch-sclktx"; + i2s0_8ch_sclkrx = "/pinctrl/i2s0/i2s0-8ch-sclkrx"; + i2s0_8ch_lrcktx = "/pinctrl/i2s0/i2s0-8ch-lrcktx"; + i2s0_8ch_lrckrx = "/pinctrl/i2s0/i2s0-8ch-lrckrx"; + i2s0_8ch_sdo0 = "/pinctrl/i2s0/i2s0-8ch-sdo0"; + i2s0_8ch_sdo1 = "/pinctrl/i2s0/i2s0-8ch-sdo1"; + i2s0_8ch_sdo2 = "/pinctrl/i2s0/i2s0-8ch-sdo2"; + i2s0_8ch_sdo3 = "/pinctrl/i2s0/i2s0-8ch-sdo3"; + i2s0_8ch_sdi0 = "/pinctrl/i2s0/i2s0-8ch-sdi0"; + i2s0_8ch_sdi1 = "/pinctrl/i2s0/i2s0-8ch-sdi1"; + i2s0_8ch_sdi2 = "/pinctrl/i2s0/i2s0-8ch-sdi2"; + i2s0_8ch_sdi3 = "/pinctrl/i2s0/i2s0-8ch-sdi3"; + i2s1_2ch_mclk = "/pinctrl/i2s1/i2s1-2ch-mclk"; + i2s1_2ch_sclk = "/pinctrl/i2s1/i2s1-2ch-sclk"; + i2s1_2ch_lrck = "/pinctrl/i2s1/i2s1-2ch-lrck"; + i2s1_2ch_sdi = "/pinctrl/i2s1/i2s1-2ch-sdi"; + i2s1_2ch_sdo = "/pinctrl/i2s1/i2s1-2ch-sdo"; + i2s2_2ch_mclk = "/pinctrl/i2s2/i2s2-2ch-mclk"; + i2s2_2ch_sclk = "/pinctrl/i2s2/i2s2-2ch-sclk"; + i2s2_2ch_lrck = "/pinctrl/i2s2/i2s2-2ch-lrck"; + i2s2_2ch_sdi = "/pinctrl/i2s2/i2s2-2ch-sdi"; + i2s2_2ch_sdo = "/pinctrl/i2s2/i2s2-2ch-sdo"; + sdmmc_clk = "/pinctrl/sdmmc/sdmmc-clk"; + sdmmc_cmd = "/pinctrl/sdmmc/sdmmc-cmd"; + sdmmc_det = "/pinctrl/sdmmc/sdmmc-det"; + sdmmc_bus1 = "/pinctrl/sdmmc/sdmmc-bus1"; + sdmmc_bus4 = "/pinctrl/sdmmc/sdmmc-bus4"; + sdmmc_gpio = "/pinctrl/sdmmc/sdmmc-gpio"; + sdio_clk = "/pinctrl/sdio/sdio-clk"; + sdio_cmd = "/pinctrl/sdio/sdio-cmd"; + sdio_bus4 = "/pinctrl/sdio/sdio-bus4"; + sdio_gpio = "/pinctrl/sdio/sdio-gpio"; + emmc_clk = "/pinctrl/emmc/emmc-clk"; + emmc_cmd = "/pinctrl/emmc/emmc-cmd"; + emmc_pwren = "/pinctrl/emmc/emmc-pwren"; + emmc_rstnout = "/pinctrl/emmc/emmc-rstnout"; + emmc_bus1 = "/pinctrl/emmc/emmc-bus1"; + emmc_bus4 = "/pinctrl/emmc/emmc-bus4"; + emmc_bus8 = "/pinctrl/emmc/emmc-bus8"; + flash_cs0 = "/pinctrl/flash/flash-cs0"; + flash_rdy = "/pinctrl/flash/flash-rdy"; + flash_dqs = "/pinctrl/flash/flash-dqs"; + flash_ale = "/pinctrl/flash/flash-ale"; + flash_cle = "/pinctrl/flash/flash-cle"; + flash_wrn = "/pinctrl/flash/flash-wrn"; + flash_csl = "/pinctrl/flash/flash-csl"; + flash_rdn = "/pinctrl/flash/flash-rdn"; + flash_bus8 = "/pinctrl/flash/flash-bus8"; + lcdc_m0_rgb_pins = "/pinctrl/lcdc/lcdc-m0-rgb-pins"; + lcdc_m0_sleep_pins = "/pinctrl/lcdc/lcdc-m0-sleep-pins"; + lcdc_m1_rgb_pins = "/pinctrl/lcdc/lcdc-m1-rgb-pins"; + lcdc_m1_sleep_pins = "/pinctrl/lcdc/lcdc-m1-sleep-pins"; + pwm0_pin = "/pinctrl/pwm0/pwm0-pin"; + pwm1_pin = "/pinctrl/pwm1/pwm1-pin"; + pwm2_pin = "/pinctrl/pwm2/pwm2-pin"; + pwm3_pin = "/pinctrl/pwm3/pwm3-pin"; + pwm4_pin = "/pinctrl/pwm4/pwm4-pin"; + pwm5_pin = "/pinctrl/pwm5/pwm5-pin"; + pwm6_pin = "/pinctrl/pwm6/pwm6-pin"; + pwm7_pin = "/pinctrl/pwm7/pwm7-pin"; + rmii_pins = "/pinctrl/gmac/rmii-pins"; + mac_refclk_12ma = "/pinctrl/gmac/mac-refclk-12ma"; + mac_refclk = "/pinctrl/gmac/mac-refclk"; + cif_clkout_m0 = "/pinctrl/cif-m0/cif-clkout-m0"; + dvp_d2d9_m0 = "/pinctrl/cif-m0/dvp-d2d9-m0"; + dvp_d0d1_m0 = "/pinctrl/cif-m0/dvp-d0d1-m0"; + dvp_d10d11_m0 = "/pinctrl/cif-m0/d10-d11-m0"; + cif_clkout_m1 = "/pinctrl/cif-m1/cif-clkout-m1"; + dvp_d2d9_m1 = "/pinctrl/cif-m1/dvp-d2d9-m1"; + dvp_d0d1_m1 = "/pinctrl/cif-m1/dvp-d0d1-m1"; + dvp_d10d11_m1 = "/pinctrl/cif-m1/d10-d11-m1"; + isp_prelight = "/pinctrl/isp/isp-prelight"; + pmic_int = "/pinctrl/pmic/pmic_int"; + soc_slppin_gpio = "/pinctrl/pmic/soc_slppin_gpio"; + soc_slppin_slp = "/pinctrl/pmic/soc_slppin_slp"; + soc_slppin_rst = "/pinctrl/pmic/soc_slppin_rst"; + led_pins = "/pinctrl/leds/led-pins"; + btn_pins = "/pinctrl/btns/btn-pins"; + drm_logo = "/reserved-memory/drm-logo@00000000"; + ramoops_mem = "/reserved-memory/region@110000"; + gpio_keys = "/odroidgo3-keys"; + joypad = "/odroidgo3-joypad"; + leds = "/gpio_leds"; + backlight = "/backlight"; + vccsys = "/vccsys"; + }; +}; diff --git a/config/archr-dts/R36S-DTB/DTS/R36S-Plus.dts b/config/archr-dts/R36S-DTB/DTS/R36S-Plus.dts new file mode 100644 index 0000000000..a6a3d3e9d2 --- /dev/null +++ b/config/archr-dts/R36S-DTB/DTS/R36S-Plus.dts @@ -0,0 +1,4018 @@ +/dts-v1/; + +/ { + compatible = "rockchip,rk3326-odroidgo3-linux\0rockchip,rk3326"; + interrupt-parent = <0x01>; + #address-cells = <0x02>; + #size-cells = <0x02>; + model = "Hardkernel ODROID-GO3"; + + ddr_timing { + compatible = "rockchip,ddr-timing"; + ddr2_speed_bin = <0x00>; + ddr3_speed_bin = <0x15>; + ddr4_speed_bin = <0x0c>; + pd_idle = <0x0d>; + sr_idle = <0x5d>; + sr_mc_gate_idle = <0x00>; + srpd_lite_idle = <0x00>; + standby_idle = <0x00>; + auto_pd_dis_freq = <0x42a>; + auto_sr_dis_freq = <0x320>; + ddr2_dll_dis_freq = <0x12c>; + ddr3_dll_dis_freq = <0x12c>; + ddr4_dll_dis_freq = <0x271>; + phy_dll_dis_freq = <0x190>; + ddr2_odt_dis_freq = <0x64>; + phy_ddr2_odt_dis_freq = <0x64>; + ddr2_drv = <0x01>; + ddr2_odt = <0x96>; + phy_ddr2_ca_drv = <0x15>; + phy_ddr2_ck_drv = <0x12>; + phy_ddr2_dq_drv = <0x15>; + phy_ddr2_odt = <0x02>; + ddr3_odt_dis_freq = <0x190>; + phy_ddr3_odt_dis_freq = <0x190>; + ddr3_drv = <0x28>; + ddr3_odt = <0x78>; + phy_ddr3_ca_drv = <0x15>; + phy_ddr3_ck_drv = <0x12>; + phy_ddr3_dq_drv = <0x15>; + phy_ddr3_odt = <0x02>; + phy_lpddr2_odt_dis_freq = <0x29a>; + lpddr2_drv = <0x28>; + phy_lpddr2_ca_drv = <0x16>; + phy_lpddr2_ck_drv = <0x13>; + phy_lpddr2_dq_drv = <0x16>; + phy_lpddr2_odt = <0x00>; + lpddr3_odt_dis_freq = <0x190>; + phy_lpddr3_odt_dis_freq = <0x190>; + lpddr3_drv = <0x28>; + lpddr3_odt = <0xf0>; + phy_lpddr3_ca_drv = <0x16>; + phy_lpddr3_ck_drv = <0x13>; + phy_lpddr3_dq_drv = <0x16>; + phy_lpddr3_odt = <0x02>; + lpddr4_odt_dis_freq = <0x320>; + phy_lpddr4_odt_dis_freq = <0x320>; + lpddr4_drv = <0x3c>; + lpddr4_dq_odt = <0x28>; + lpddr4_ca_odt = <0x28>; + phy_lpddr4_ca_drv = <0x14>; + phy_lpddr4_ck_cs_drv = <0x06>; + phy_lpddr4_dq_drv = <0x06>; + phy_lpddr4_odt = <0x10>; + ddr4_odt_dis_freq = <0x29a>; + phy_ddr4_odt_dis_freq = <0x29a>; + ddr4_drv = <0x22>; + ddr4_odt = <0xf0>; + phy_ddr4_ca_drv = <0x16>; + phy_ddr4_ck_drv = <0x13>; + phy_ddr4_dq_drv = <0x16>; + phy_ddr4_odt = <0x02>; + ddr3a1_ddr4a9_de-skew = <0x06>; + ddr3a0_ddr4a10_de-skew = <0x07>; + ddr3a3_ddr4a6_de-skew = <0x07>; + ddr3a2_ddr4a4_de-skew = <0x07>; + ddr3a5_ddr4a8_de-skew = <0x07>; + ddr3a4_ddr4a5_de-skew = <0x07>; + ddr3a7_ddr4a11_de-skew = <0x07>; + ddr3a6_ddr4a7_de-skew = <0x06>; + ddr3a9_ddr4a0_de-skew = <0x07>; + ddr3a8_ddr4a13_de-skew = <0x07>; + ddr3a11_ddr4a3_de-skew = <0x07>; + ddr3a10_ddr4cs0_de-skew = <0x07>; + ddr3a13_ddr4a2_de-skew = <0x07>; + ddr3a12_ddr4ba1_de-skew = <0x07>; + ddr3a15_ddr4odt0_de-skew = <0x07>; + ddr3a14_ddr4a1_de-skew = <0x07>; + ddr3ba1_ddr4a15_de-skew = <0x07>; + ddr3ba0_ddr4bg0_de-skew = <0x07>; + ddr3ras_ddr4cke_de-skew = <0x07>; + ddr3ba2_ddr4ba0_de-skew = <0x07>; + ddr3we_ddr4bg1_de-skew = <0x07>; + ddr3cas_ddr4a12_de-skew = <0x07>; + ddr3ckn_ddr4ckn_de-skew = <0x07>; + ddr3ckp_ddr4ckp_de-skew = <0x07>; + ddr3cke_ddr4a16_de-skew = <0x07>; + ddr3odt0_ddr4a14_de-skew = <0x07>; + ddr3cs0_ddr4act_de-skew = <0x06>; + ddr3reset_ddr4reset_de-skew = <0x07>; + ddr3cs1_ddr4cs1_de-skew = <0x06>; + ddr3odt1_ddr4odt1_de-skew = <0x07>; + cs0_dm0_rx_de-skew = <0x07>; + cs0_dm0_tx_de-skew = <0x07>; + cs0_dq0_rx_de-skew = <0x08>; + cs0_dq0_tx_de-skew = <0x08>; + cs0_dq1_rx_de-skew = <0x09>; + cs0_dq1_tx_de-skew = <0x08>; + cs0_dq2_rx_de-skew = <0x08>; + cs0_dq2_tx_de-skew = <0x08>; + cs0_dq3_rx_de-skew = <0x08>; + cs0_dq3_tx_de-skew = <0x08>; + cs0_dq4_rx_de-skew = <0x09>; + cs0_dq4_tx_de-skew = <0x08>; + cs0_dq5_rx_de-skew = <0x09>; + cs0_dq5_tx_de-skew = <0x08>; + cs0_dq6_rx_de-skew = <0x09>; + cs0_dq6_tx_de-skew = <0x08>; + cs0_dq7_rx_de-skew = <0x08>; + cs0_dq7_tx_de-skew = <0x08>; + cs0_dqs0_rx_de-skew = <0x06>; + cs0_dqs0p_tx_de-skew = <0x09>; + cs0_dqs0n_tx_de-skew = <0x09>; + cs0_dm1_rx_de-skew = <0x07>; + cs0_dm1_tx_de-skew = <0x06>; + cs0_dq8_rx_de-skew = <0x08>; + cs0_dq8_tx_de-skew = <0x07>; + cs0_dq9_rx_de-skew = <0x09>; + cs0_dq9_tx_de-skew = <0x07>; + cs0_dq10_rx_de-skew = <0x08>; + cs0_dq10_tx_de-skew = <0x08>; + cs0_dq11_rx_de-skew = <0x08>; + cs0_dq11_tx_de-skew = <0x07>; + cs0_dq12_rx_de-skew = <0x08>; + cs0_dq12_tx_de-skew = <0x08>; + cs0_dq13_rx_de-skew = <0x09>; + cs0_dq13_tx_de-skew = <0x07>; + cs0_dq14_rx_de-skew = <0x09>; + cs0_dq14_tx_de-skew = <0x08>; + cs0_dq15_rx_de-skew = <0x09>; + cs0_dq15_tx_de-skew = <0x07>; + cs0_dqs1_rx_de-skew = <0x07>; + cs0_dqs1p_tx_de-skew = <0x09>; + cs0_dqs1n_tx_de-skew = <0x09>; + cs0_dm2_rx_de-skew = <0x07>; + cs0_dm2_tx_de-skew = <0x07>; + cs0_dq16_rx_de-skew = <0x09>; + cs0_dq16_tx_de-skew = <0x09>; + cs0_dq17_rx_de-skew = <0x07>; + cs0_dq17_tx_de-skew = <0x09>; + cs0_dq18_rx_de-skew = <0x07>; + cs0_dq18_tx_de-skew = <0x08>; + cs0_dq19_rx_de-skew = <0x07>; + cs0_dq19_tx_de-skew = <0x09>; + cs0_dq20_rx_de-skew = <0x09>; + cs0_dq20_tx_de-skew = <0x09>; + cs0_dq21_rx_de-skew = <0x09>; + cs0_dq21_tx_de-skew = <0x09>; + cs0_dq22_rx_de-skew = <0x08>; + cs0_dq22_tx_de-skew = <0x09>; + cs0_dq23_rx_de-skew = <0x08>; + cs0_dq23_tx_de-skew = <0x09>; + cs0_dqs2_rx_de-skew = <0x06>; + cs0_dqs2p_tx_de-skew = <0x09>; + cs0_dqs2n_tx_de-skew = <0x09>; + cs0_dm3_rx_de-skew = <0x07>; + cs0_dm3_tx_de-skew = <0x07>; + cs0_dq24_rx_de-skew = <0x08>; + cs0_dq24_tx_de-skew = <0x08>; + cs0_dq25_rx_de-skew = <0x09>; + cs0_dq25_tx_de-skew = <0x09>; + cs0_dq26_rx_de-skew = <0x09>; + cs0_dq26_tx_de-skew = <0x08>; + cs0_dq27_rx_de-skew = <0x09>; + cs0_dq27_tx_de-skew = <0x08>; + cs0_dq28_rx_de-skew = <0x09>; + cs0_dq28_tx_de-skew = <0x09>; + cs0_dq29_rx_de-skew = <0x09>; + cs0_dq29_tx_de-skew = <0x09>; + cs0_dq30_rx_de-skew = <0x08>; + cs0_dq30_tx_de-skew = <0x08>; + cs0_dq31_rx_de-skew = <0x08>; + cs0_dq31_tx_de-skew = <0x08>; + cs0_dqs3_rx_de-skew = <0x07>; + cs0_dqs3p_tx_de-skew = <0x09>; + cs0_dqs3n_tx_de-skew = <0x09>; + cs1_dm0_rx_de-skew = <0x07>; + cs1_dm0_tx_de-skew = <0x07>; + cs1_dq0_rx_de-skew = <0x08>; + cs1_dq0_tx_de-skew = <0x08>; + cs1_dq1_rx_de-skew = <0x09>; + cs1_dq1_tx_de-skew = <0x08>; + cs1_dq2_rx_de-skew = <0x08>; + cs1_dq2_tx_de-skew = <0x08>; + cs1_dq3_rx_de-skew = <0x08>; + cs1_dq3_tx_de-skew = <0x08>; + cs1_dq4_rx_de-skew = <0x08>; + cs1_dq4_tx_de-skew = <0x08>; + cs1_dq5_rx_de-skew = <0x09>; + cs1_dq5_tx_de-skew = <0x08>; + cs1_dq6_rx_de-skew = <0x09>; + cs1_dq6_tx_de-skew = <0x08>; + cs1_dq7_rx_de-skew = <0x08>; + cs1_dq7_tx_de-skew = <0x08>; + cs1_dqs0_rx_de-skew = <0x06>; + cs1_dqs0p_tx_de-skew = <0x09>; + cs1_dqs0n_tx_de-skew = <0x09>; + cs1_dm1_rx_de-skew = <0x07>; + cs1_dm1_tx_de-skew = <0x07>; + cs1_dq8_rx_de-skew = <0x08>; + cs1_dq8_tx_de-skew = <0x08>; + cs1_dq9_rx_de-skew = <0x08>; + cs1_dq9_tx_de-skew = <0x07>; + cs1_dq10_rx_de-skew = <0x07>; + cs1_dq10_tx_de-skew = <0x08>; + cs1_dq11_rx_de-skew = <0x08>; + cs1_dq11_tx_de-skew = <0x08>; + cs1_dq12_rx_de-skew = <0x08>; + cs1_dq12_tx_de-skew = <0x07>; + cs1_dq13_rx_de-skew = <0x08>; + cs1_dq13_tx_de-skew = <0x08>; + cs1_dq14_rx_de-skew = <0x08>; + cs1_dq14_tx_de-skew = <0x08>; + cs1_dq15_rx_de-skew = <0x08>; + cs1_dq15_tx_de-skew = <0x07>; + cs1_dqs1_rx_de-skew = <0x07>; + cs1_dqs1p_tx_de-skew = <0x09>; + cs1_dqs1n_tx_de-skew = <0x09>; + cs1_dm2_rx_de-skew = <0x07>; + cs1_dm2_tx_de-skew = <0x08>; + cs1_dq16_rx_de-skew = <0x08>; + cs1_dq16_tx_de-skew = <0x09>; + cs1_dq17_rx_de-skew = <0x08>; + cs1_dq17_tx_de-skew = <0x09>; + cs1_dq18_rx_de-skew = <0x07>; + cs1_dq18_tx_de-skew = <0x08>; + cs1_dq19_rx_de-skew = <0x08>; + cs1_dq19_tx_de-skew = <0x09>; + cs1_dq20_rx_de-skew = <0x09>; + cs1_dq20_tx_de-skew = <0x09>; + cs1_dq21_rx_de-skew = <0x09>; + cs1_dq21_tx_de-skew = <0x09>; + cs1_dq22_rx_de-skew = <0x08>; + cs1_dq22_tx_de-skew = <0x09>; + cs1_dq23_rx_de-skew = <0x08>; + cs1_dq23_tx_de-skew = <0x09>; + cs1_dqs2_rx_de-skew = <0x06>; + cs1_dqs2p_tx_de-skew = <0x09>; + cs1_dqs2n_tx_de-skew = <0x09>; + cs1_dm3_rx_de-skew = <0x07>; + cs1_dm3_tx_de-skew = <0x07>; + cs1_dq24_rx_de-skew = <0x08>; + cs1_dq24_tx_de-skew = <0x09>; + cs1_dq25_rx_de-skew = <0x09>; + cs1_dq25_tx_de-skew = <0x09>; + cs1_dq26_rx_de-skew = <0x09>; + cs1_dq26_tx_de-skew = <0x08>; + cs1_dq27_rx_de-skew = <0x08>; + cs1_dq27_tx_de-skew = <0x08>; + cs1_dq28_rx_de-skew = <0x09>; + cs1_dq28_tx_de-skew = <0x09>; + cs1_dq29_rx_de-skew = <0x09>; + cs1_dq29_tx_de-skew = <0x09>; + cs1_dq30_rx_de-skew = <0x09>; + cs1_dq30_tx_de-skew = <0x08>; + cs1_dq31_rx_de-skew = <0x08>; + cs1_dq31_tx_de-skew = <0x08>; + cs1_dqs3_rx_de-skew = <0x07>; + cs1_dqs3p_tx_de-skew = <0x09>; + cs1_dqs3n_tx_de-skew = <0x09>; + phandle = <0xaf>; + }; + + aliases { + ethernet0 = "/ethernet@ff360000"; + i2c0 = "/i2c@ff180000"; + i2c1 = "/i2c@ff190000"; + i2c2 = "/i2c@ff1a0000"; + i2c3 = "/i2c@ff1b0000"; + serial0 = "/serial@ff030000"; + serial1 = "/serial@ff158000"; + serial2 = "/serial@ff160000"; + serial3 = "/serial@ff168000"; + serial4 = "/serial@ff170000"; + serial5 = "/serial@ff178000"; + spi0 = "/spi@ff1d0000"; + spi1 = "/spi@ff1d8000"; + }; + + cpus { + #address-cells = <0x02>; + #size-cells = <0x00>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x00>; + enable-method = "psci"; + clocks = <0x02 0x07>; + #cooling-cells = <0x02>; + dynamic-power-coefficient = <0x5a>; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + cpu-supply = <0x06>; + phandle = <0x09>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x01>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0a>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x02>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0b>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x03>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0c>; + }; + + idle-states { + entry-method = "psci"; + + cpu-sleep { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x10000>; + entry-latency-us = <0x78>; + exit-latency-us = <0xfa>; + min-residency-us = <0x384>; + phandle = <0x04>; + }; + + cluster-sleep { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x1010000>; + entry-latency-us = <0x190>; + exit-latency-us = <0x1f4>; + min-residency-us = <0x7d0>; + phandle = <0x05>; + }; + }; + }; + + cpu0-opp-table { + compatible = "operating-points-v2"; + opp-shared; + rockchip,temp-hysteresis = <0x1388>; + rockchip,low-temp = <0x00>; + rockchip,low-temp-min-volt = <0xf4240>; + rockchip,low-temp-adjust-volt = <0x00 0x5e8 0xc350>; + clocks = <0x02 0x01>; + rockchip,avs-scale = <0x04>; + rockchip,max-volt = <0x149970>; + rockchip,evb-irdrop = <0x61a8>; + nvmem-cells = <0x07 0x08>; + nvmem-cell-names = "cpu_leakage\0performance"; + rockchip,bin-scaling-sel = <0x00 0x0d 0x01 0x0d>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-freq = <0x639c0>; + rockchip,pvtm-volt = <0xf4240>; + rockchip,pvtm-ch = <0x00 0x00>; + rockchip,pvtm-sample-time = <0x3e8>; + rockchip,pvtm-number = <0x0a>; + rockchip,pvtm-error = <0x3e8>; + rockchip,pvtm-ref-temp = <0x28>; + rockchip,pvtm-temp-prop = <0xffffffc8 0xffffffc8>; + rockchip,thermal-zone = "soc-thermal"; + rockchip,avs = <0x01>; + phandle = <0x03>; + + opp-1008000000 { + opp-hz = <0x00 0x3c14dc00>; + opp-microvolt = <0x11edd8 0x11edd8 0x149970>; + opp-microvolt-L0 = <0x11edd8 0x11edd8 0x149970>; + opp-microvolt-L1 = <0x112a88 0x112a88 0x149970>; + opp-microvolt-L2 = <0x112a88 0x112a88 0x149970>; + opp-microvolt-L3 = <0x100590 0x100590 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1200000000 { + opp-hz = <0x00 0x47868c00>; + opp-microvolt = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L0 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L1 = <0x137478 0x137478 0x149970>; + opp-microvolt-L2 = <0x1312d0 0x1312d0 0x149970>; + opp-microvolt-L3 = <0x124f80 0x124f80 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1248000000 { + opp-hz = <0x00 0x4a62f800>; + opp-microvolt = <0x149970 0x149970 0x149970>; + opp-microvolt-L0 = <0x149970 0x149970 0x149970>; + opp-microvolt-L1 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L2 = <0x137478 0x137478 0x149970>; + opp-microvolt-L3 = <0x12b128 0x12b128 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1296000000 { + opp-hz = <0x00 0x4d3f6400>; + opp-microvolt = <0x149970 0x149970 0x149970>; + opp-microvolt-L0 = <0x149970 0x149970 0x149970>; + opp-microvolt-L1 = <0x149970 0x149970 0x149970>; + opp-microvolt-L2 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L3 = <0x1312d0 0x1312d0 0x149970>; + clock-latency-ns = <0x9c40>; + }; + }; + + arm-pmu { + compatible = "arm,cortex-a53-pmu"; + interrupts = <0x00 0x64 0x04 0x00 0x65 0x04 0x00 0x66 0x04 0x00 0x67 0x04>; + interrupt-affinity = <0x09 0x0a 0x0b 0x0c>; + }; + + bus-soc { + compatible = "rockchip,px30-bus"; + rockchip,busfreq-policy = "autocs"; + phandle = <0xc4>; + + soc-bus0 { + bus-id = <0x00>; + timer-us = <0x14>; + enable-msk = <0x40f7>; + status = "disabled"; + }; + + soc-bus1 { + bus-id = <0x01>; + timer-us = <0xc8>; + enable-msk = <0x40bf>; + status = "disabled"; + }; + + soc-bus2 { + bus-id = <0x02>; + timer-us = <0xc8>; + enable-msk = <0x4007>; + status = "disabled"; + }; + }; + + bus-apll { + compatible = "rockchip,px30-bus"; + rockchip,busfreq-policy = "clkfreq"; + clocks = <0x02 0x01>; + clock-names = "bus"; + operating-points-v2 = <0x0d>; + status = "okay"; + bus-supply = <0x0e>; + phandle = <0xc5>; + }; + + bus-apll-opp-table { + compatible = "operating-points-v2"; + opp-shared; + phandle = <0x0d>; + + opp-1512000000 { + opp-hz = <0x00 0x5a1f4a00>; + opp-microvolt = <0xf4240>; + }; + + opp-1008000000 { + opp-hz = <0x00 0x3c14dc00>; + opp-microvolt = <0xe7ef0>; + }; + }; + + cpuinfo { + compatible = "rockchip,cpuinfo"; + nvmem-cells = <0x0f>; + nvmem-cell-names = "id"; + }; + + display-subsystem { + compatible = "rockchip,display-subsystem"; + ports = <0x10>; + status = "okay"; + logo-memory-region = <0x11>; + phandle = <0xc6>; + + route { + + route-lvds { + status = "disabled"; + logo,uboot = "logo.bmp"; + logo,kernel = "logo_kernel.bmp"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x12>; + phandle = <0xc7>; + }; + + route-dsi { + status = "okay"; + logo,uboot = "logo.bmp"; + logo,kernel = "logo_kernel.bmp"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x13>; + phandle = <0xc8>; + }; + + route-rgb { + status = "disabled"; + logo,uboot = "logo.bmp"; + logo,kernel = "logo_kernel.bmp"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x14>; + phandle = <0xc9>; + }; + }; + }; + + firmware { + + optee { + compatible = "linaro,optee-tz"; + method = "smc"; + }; + }; + + external-gmac-clock { + compatible = "fixed-clock"; + clock-frequency = <0x2faf080>; + clock-output-names = "gmac_clkin"; + #clock-cells = <0x00>; + phandle = <0xca>; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + rockchip-suspend { + compatible = "rockchip,pm-px30"; + status = "okay"; + rockchip,sleep-debug-en = <0x01>; + rockchip,sleep-mode-config = <0x20702>; + rockchip,wakeup-config = <0x85>; + phandle = <0xcb>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <0x01 0x0d 0xf04 0x01 0x0e 0xf04 0x01 0x0b 0xf04 0x01 0x0a 0xf04>; + }; + + xin24m { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x16e3600>; + clock-output-names = "xin24m"; + phandle = <0xcc>; + }; + + xin32k { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x8000>; + clock-output-names = "xin32k"; + phandle = <0xcd>; + }; + + power-management@ff000000 { + compatible = "rockchip,px30-pmu\0syscon\0simple-mfd"; + reg = <0x00 0xff000000 0x00 0x1000>; + phandle = <0xce>; + + power-controller { + compatible = "rockchip,px30-power-controller"; + #power-domain-cells = <0x01>; + #address-cells = <0x01>; + #size-cells = <0x00>; + phandle = <0x8a>; + + pd_usb@5 { + reg = <0x05>; + clocks = <0x02 0x103 0x02 0x102 0x02 0x3c>; + pm_qos = <0x15 0x16>; + }; + + pd_sdcard@7 { + reg = <0x07>; + clocks = <0x02 0xf7 0x02 0x3b>; + pm_qos = <0x17>; + }; + + pd_gmac@9 { + reg = <0x09>; + clocks = <0x02 0xb2 0x02 0x143 0x02 0x40 0x02 0x3f>; + pm_qos = <0x18>; + }; + + pd_mmc_nand@10 { + reg = <0x0a>; + clocks = <0x02 0xfe 0x02 0x100 0x02 0xff 0x02 0x101 0x02 0x39 0x02 0x37 0x02 0x38 0x02 0x3a>; + pm_qos = <0x19 0x1a 0x1b 0x1c>; + }; + + pd_vpu@11 { + reg = <0x0b>; + clocks = <0x02 0xaf 0x02 0xf4 0x02 0x4b>; + pm_qos = <0x1d 0x1e>; + }; + + pd_vo@12 { + reg = <0x0c>; + clocks = <0x02 0xb7 0x02 0xb5 0x02 0xb6 0x02 0x96 0x02 0x97 0x02 0xfd 0x02 0xfb 0x02 0xfc 0x02 0x144 0x02 0x35 0x02 0x36>; + pm_qos = <0x1f 0x20 0x21 0x22>; + }; + + pd_vi@13 { + reg = <0x0d>; + clocks = <0x02 0xb3 0x02 0xb4 0x02 0xf9 0x02 0xfa 0x02 0x33>; + pm_qos = <0x23 0x24 0x25 0x26 0x27>; + }; + + pd_gpu@14 { + reg = <0x0e>; + clocks = <0x02 0x49>; + pm_qos = <0x28>; + }; + }; + }; + + syscon@ff010000 { + compatible = "rockchip,px30-pmugrf\0syscon\0simple-mfd"; + reg = <0x00 0xff010000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0xac>; + + io-domains { + compatible = "rockchip,px30-pmu-io-voltage-domain"; + status = "okay"; + pmuio1-supply = <0x29>; + pmuio2-supply = <0x29>; + phandle = <0xcf>; + }; + + reboot-mode { + compatible = "syscon-reboot-mode"; + offset = <0x200>; + mode-bootloader = <0x5242c301>; + mode-charge = <0x5242c30b>; + mode-fastboot = <0x5242c309>; + mode-loader = <0x5242c301>; + mode-normal = <0x5242c300>; + mode-recovery = <0x5242c303>; + mode-ums = <0x5242c30c>; + }; + + pmu-pvtm { + compatible = "rockchip,px30-pmu-pvtm"; + clocks = <0x2a 0x07>; + clock-names = "pmu"; + status = "okay"; + phandle = <0xd0>; + }; + }; + + serial@ff030000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff030000 0x00 0x100>; + interrupts = <0x00 0x0f 0x04>; + clocks = <0x2a 0x06 0x2a 0x15>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x00 0x2b 0x01>; + pinctrl-names = "default"; + pinctrl-0 = <0x2c 0x2d 0x2e>; + status = "disabled"; + phandle = <0xd1>; + }; + + i2s@ff060000 { + compatible = "rockchip,px30-i2s-tdm"; + reg = <0x00 0xff060000 0x00 0x1000>; + interrupts = <0x00 0x0c 0x04>; + clocks = <0x02 0x10 0x02 0x12 0x02 0x106>; + clock-names = "mclk_tx\0mclk_rx\0hclk"; + dmas = <0x2b 0x10 0x2b 0x11>; + dma-names = "tx\0rx"; + resets = <0x02 0x84 0x02 0xbf>; + reset-names = "tx-m\0rx-m"; + rockchip,cru = <0x02>; + rockchip,grf = <0x2f>; + pinctrl-names = "default"; + pinctrl-0 = <0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x3a 0x3b>; + status = "disabled"; + phandle = <0xd2>; + }; + + i2s@ff070000 { + compatible = "rockchip,px30-i2s\0rockchip,rk3066-i2s"; + reg = <0x00 0xff070000 0x00 0x1000>; + interrupts = <0x00 0x0d 0x04>; + clocks = <0x02 0x14 0x02 0x107>; + clock-names = "i2s_clk\0i2s_hclk"; + dmas = <0x2b 0x12 0x2b 0x13>; + dma-names = "tx\0rx"; + resets = <0x02 0x86 0x02 0x85>; + reset-names = "reset-m\0reset-h"; + pinctrl-names = "default"; + pinctrl-0 = <0x3c 0x3d 0x3e 0x3f>; + status = "okay"; + #sound-dai-cells = <0x00>; + phandle = <0xc2>; + }; + + i2s@ff080000 { + compatible = "rockchip,px30-i2s\0rockchip,rk3066-i2s"; + reg = <0x00 0xff080000 0x00 0x1000>; + interrupts = <0x00 0x0e 0x04>; + clocks = <0x02 0x16 0x02 0x108>; + clock-names = "i2s_clk\0i2s_hclk"; + dmas = <0x2b 0x14 0x2b 0x15>; + dma-names = "tx\0rx"; + resets = <0x02 0x88 0x02 0x87>; + reset-names = "reset-m\0reset-h"; + pinctrl-names = "default"; + pinctrl-0 = <0x40 0x41 0x42 0x43>; + status = "disabled"; + phandle = <0xd3>; + }; + + pdm@ff0a0000 { + compatible = "rockchip,px30-pdm\0rockchip,pdm"; + reg = <0x00 0xff0a0000 0x00 0x1000>; + clocks = <0x02 0x0f 0x02 0x105>; + clock-names = "pdm_clk\0pdm_hclk"; + dmas = <0x2b 0x18>; + dma-names = "rx"; + resets = <0x02 0x82>; + reset-names = "pdm-m"; + pinctrl-names = "default"; + pinctrl-0 = <0x44 0x45 0x46 0x47 0x48 0x49>; + status = "disabled"; + phandle = <0xd4>; + }; + + crypto@ff0b0000 { + compatible = "rockchip,px30-crypto"; + reg = <0x00 0xff0b0000 0x00 0x4000>; + interrupts = <0x00 0x52 0x04>; + clocks = <0x02 0xac 0x02 0xf1 0x02 0x30 0x02 0x31>; + clock-names = "aclk\0hclk\0sclk\0apb_pclk"; + resets = <0x02 0x74>; + reset-names = "crypto-rst"; + status = "disabled"; + phandle = <0xd5>; + }; + + rng@ff0b0000 { + compatible = "rockchip,cryptov2-rng"; + reg = <0x00 0xff0b0000 0x00 0x4000>; + clocks = <0x02 0x30 0x02 0x31 0x02 0xac 0x02 0xf1>; + clock-names = "clk_crypto\0clk_crypto_apk\0aclk_crypto\0hclk_crypto"; + assigned-clocks = <0x02 0x30 0x02 0x31 0x02 0xac 0x02 0xf1>; + assigned-clock-rates = <0x8f0d180 0x8f0d180 0xbebc200 0x5f5e100>; + resets = <0x02 0x74>; + reset-names = "reset"; + status = "okay"; + phandle = <0xd6>; + }; + + interrupt-controller@ff131000 { + compatible = "arm,gic-400"; + #interrupt-cells = <0x03>; + #address-cells = <0x00>; + interrupt-controller; + reg = <0x00 0xff131000 0x00 0x1000 0x00 0xff132000 0x00 0x2000 0x00 0xff134000 0x00 0x2000 0x00 0xff136000 0x00 0x2000>; + interrupts = <0x01 0x09 0xf04>; + phandle = <0x01>; + }; + + syscon@ff140000 { + compatible = "rockchip,px30-grf\0syscon\0simple-mfd"; + reg = <0x00 0xff140000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0x2f>; + + io-domains { + compatible = "rockchip,px30-io-voltage-domain"; + status = "okay"; + vccio1-supply = <0x4a>; + vccio2-supply = <0x4a>; + vccio3-supply = <0x4b>; + vccio4-supply = <0x4b>; + vccio5-supply = <0x4b>; + vccio6-supply = <0x4b>; + phandle = <0xd7>; + }; + + lvds { + compatible = "rockchip,px30-lvds"; + phys = <0x4c>; + phy-names = "phy"; + status = "disabled"; + phandle = <0xd8>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x12>; + phandle = <0xa2>; + }; + }; + }; + }; + + rgb { + compatible = "rockchip,px30-rgb"; + pinctrl-names = "default\0sleep"; + pinctrl-0 = <0x4d>; + pinctrl-1 = <0x4e>; + status = "disabled"; + phys = <0x4c>; + phy-names = "phy"; + phandle = <0xd9>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x14>; + phandle = <0xa4>; + }; + }; + }; + }; + }; + + syscon@ff148000 { + compatible = "syscon\0simple-mfd"; + reg = <0x00 0xff148000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0xda>; + + pvtm { + compatible = "rockchip,px30-pvtm"; + clocks = <0x02 0x4a>; + clock-names = "core"; + status = "okay"; + phandle = <0xdb>; + }; + }; + + serial@ff158000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff158000 0x00 0x100>; + interrupts = <0x00 0x10 0x04>; + clocks = <0x02 0x18 0x02 0x149>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x02 0x2b 0x03>; + pinctrl-names = "default"; + pinctrl-0 = <0x4f 0x50>; + status = "okay"; + phandle = <0xdc>; + }; + + serial@ff160000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff160000 0x00 0x100>; + interrupts = <0x00 0x11 0x04>; + clocks = <0x02 0x19 0x02 0x14a>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x04 0x2b 0x05>; + pinctrl-names = "default"; + pinctrl-0 = <0x51>; + status = "disabled"; + phandle = <0xdd>; + }; + + serial@ff168000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff168000 0x00 0x100>; + interrupts = <0x00 0x12 0x04>; + clocks = <0x02 0x1a 0x02 0x14b>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x06 0x2b 0x07>; + pinctrl-names = "default"; + pinctrl-0 = <0x52 0x53 0x54>; + status = "disabled"; + phandle = <0xde>; + }; + + serial@ff170000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff170000 0x00 0x100>; + interrupts = <0x00 0x13 0x04>; + clocks = <0x02 0x1b 0x02 0x14c>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x08 0x2b 0x09>; + pinctrl-names = "default"; + pinctrl-0 = <0x55 0x56 0x57>; + status = "disabled"; + phandle = <0xdf>; + }; + + serial@ff178000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff178000 0x00 0x100>; + interrupts = <0x00 0x14 0x04>; + clocks = <0x02 0x1c 0x02 0x14d>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x0a 0x2b 0x0b>; + pinctrl-names = "default"; + pinctrl-0 = <0x58 0x59 0x5a>; + status = "disabled"; + phandle = <0xe0>; + }; + + i2c@ff180000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff180000 0x00 0x1000>; + clocks = <0x02 0x1d 0x02 0x14e>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x07 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x5b>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + clock-frequency = <0x61a80>; + i2c-scl-rising-time-ns = <0x118>; + i2c-scl-falling-time-ns = <0x10>; + phandle = <0xe1>; + + pmic@20 { + compatible = "rockchip,rk817"; + reg = <0x20>; + interrupt-parent = <0x5c>; + interrupts = <0x0a 0x08>; + pinctrl-names = "default\0pmic-sleep\0pmic-power-off\0pmic-reset"; + pinctrl-0 = <0x5d>; + pinctrl-1 = <0x5e 0x5f>; + pinctrl-2 = <0x60 0x61>; + pinctrl-3 = <0x62 0x63>; + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <0x01>; + clock-output-names = "rk808-clkout1\0rk808-clkout2"; + pmic-reset-func = <0x01>; + vcc1-supply = <0x64>; + vcc2-supply = <0x64>; + vcc3-supply = <0x64>; + vcc4-supply = <0x64>; + vcc5-supply = <0x64>; + vcc6-supply = <0x64>; + vcc7-supply = <0x64>; + vcc8-supply = <0x64>; + vcc9-supply = <0x65>; + phandle = <0xe2>; + + pwrkey { + status = "okay"; + }; + + pinctrl_rk8xx { + gpio-controller; + #gpio-cells = <0x02>; + phandle = <0xe3>; + + rk817_ts_gpio1 { + pins = "gpio_ts"; + function = "pin_fun1"; + phandle = <0xe4>; + }; + + rk817_gt_gpio2 { + pins = "gpio_gt"; + function = "pin_fun1"; + phandle = <0xe5>; + }; + + rk817_pin_ts { + pins = "gpio_ts"; + function = "pin_fun0"; + phandle = <0xe6>; + }; + + rk817_pin_gt { + pins = "gpio_gt"; + function = "pin_fun0"; + phandle = <0xe7>; + }; + + rk817_slppin_null { + pins = "gpio_slp"; + function = "pin_fun0"; + phandle = <0xe8>; + }; + + rk817_slppin_slp { + pins = "gpio_slp"; + function = "pin_fun1"; + phandle = <0x5f>; + }; + + rk817_slppin_pwrdn { + pins = "gpio_slp"; + function = "pin_fun2"; + phandle = <0x61>; + }; + + rk817_slppin_rst { + pins = "gpio_slp"; + function = "pin_fun3"; + phandle = <0x63>; + }; + }; + + regulators { + + DCDC_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xe7ef0>; + regulator-max-microvolt = <0x118c30>; + regulator-ramp-delay = <0x1771>; + regulator-initial-mode = <0x02>; + regulator-name = "vdd_logic"; + phandle = <0x0e>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0xe7ef0>; + }; + }; + + DCDC_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xe7ef0>; + regulator-max-microvolt = <0x149970>; + regulator-ramp-delay = <0x1771>; + regulator-initial-mode = <0x02>; + regulator-name = "vdd_arm"; + phandle = <0x06>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0xe7ef0>; + }; + }; + + DCDC_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x02>; + regulator-name = "vcc_ddr"; + phandle = <0xe9>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + DCDC_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-initial-mode = <0x02>; + regulator-name = "vcc_3v3"; + phandle = <0x4b>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG1 { + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + regulator-name = "vcc_1v0"; + phandle = <0xea>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0xf4240>; + }; + }; + + LDO_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + regulator-name = "vcc1v8_soc"; + phandle = <0x88>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x1b7740>; + }; + }; + + LDO_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + regulator-name = "vcc1v0_soc"; + phandle = <0xeb>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0xf4240>; + }; + }; + + LDO_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "vcc3v3_pmu"; + phandle = <0x29>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + regulator-name = "vccio_sd"; + phandle = <0x4a>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x1b7740>; + }; + }; + + LDO_REG6 { + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x2dc6c0>; + regulator-boot-on; + regulator-name = "vcc_sd"; + phandle = <0x93>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x2dc6c0>; + }; + }; + + LDO_REG7 { + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "vcc_backlight"; + phandle = <0x9e>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG8 { + regulator-min-microvolt = <0x2ab980>; + regulator-max-microvolt = <0x2ab980>; + regulator-name = "vcc_lcd"; + phandle = <0x9f>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x2ab980>; + }; + }; + + BOOST { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x4c4b40>; + regulator-max-microvolt = <0x5265c0>; + regulator-name = "boost"; + phandle = <0x65>; + }; + + OTG_SWITCH { + regulator-boot-on; + regulator-name = "otg_switch"; + phandle = <0xec>; + }; + }; + + battery { + compatible = "rk817,battery"; + ocv_table = <0xc5d 0xc94 0xcd0 0xd02 0xd34 0xd66 0xd98 0xdca 0xdfc 0xe2e 0xe56 0xe7e 0xea6 0xece 0xef6 0xf1e 0xf46 0xf6e 0xf96 0xf9b 0xfa0>; + design_capacity = <0xd34>; + design_qmax = <0xe86>; + bat_res = <0x64>; + sleep_enter_current = <0x12c>; + sleep_exit_current = <0x12c>; + sleep_filter_current = <0x64>; + power_off_thresd = <0xbb8>; + zero_algorithm_vol = <0xf0a>; + max_soc_offset = <0x3c>; + monitor_sec = <0x05>; + virtual_power = <0x00>; + sample_res = <0x0a>; + }; + + charger { + compatible = "rk817,charger"; + min_input_voltage = <0x1194>; + max_input_current = <0x5dc>; + max_chrg_current = <0x7d0>; + max_chrg_voltage = <0x1068>; + chrg_term_mode = <0x00>; + chrg_finish_cur = <0x34>; + virtual_power = <0x00>; + sample_res = <0x0a>; + dc_det_gpio = <0x5c 0x0b 0x00>; + bat_low_gpio = <0x66 0x0d 0x00>; + extcon = <0x67>; + }; + + codec { + #sound-dai-cells = <0x00>; + compatible = "rockchip,rk817-codec"; + clocks = <0x02 0x15>; + clock-names = "mclk"; + pinctrl-names = "default"; + pinctrl-0 = <0x68>; + hp-volume = <0x14>; + spk-volume = <0x03>; + status = "okay"; + phandle = <0xc3>; + }; + }; + }; + + i2c@ff190000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff190000 0x00 0x1000>; + clocks = <0x02 0x1e 0x02 0x14f>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x08 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x69>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + clock-frequency = <0x61a80>; + phandle = <0xed>; + }; + + i2c@ff1a0000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff1a0000 0x00 0x1000>; + clocks = <0x02 0x1f 0x02 0x150>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x09 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x6a>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xee>; + }; + + i2c@ff1b0000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff1b0000 0x00 0x1000>; + clocks = <0x02 0x20 0x02 0x151>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x0a 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x6b>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xef>; + }; + + spi@ff1d0000 { + compatible = "rockchip,px30-spi\0rockchip,rk3066-spi"; + reg = <0x00 0xff1d0000 0x00 0x1000>; + interrupts = <0x00 0x1a 0x04>; + #address-cells = <0x01>; + #size-cells = <0x00>; + clocks = <0x02 0x24 0x02 0x155>; + clock-names = "spiclk\0apb_pclk"; + dmas = <0x2b 0x0c 0x2b 0x0d>; + dma-names = "tx\0rx"; + pinctrl-names = "default\0high_speed"; + pinctrl-0 = <0x6c 0x6d 0x6e 0x6f>; + pinctrl-1 = <0x70 0x6d 0x71 0x72>; + status = "disabled"; + phandle = <0xf0>; + }; + + spi@ff1d8000 { + compatible = "rockchip,px30-spi\0rockchip,rk3066-spi"; + reg = <0x00 0xff1d8000 0x00 0x1000>; + interrupts = <0x00 0x1b 0x04>; + #address-cells = <0x01>; + #size-cells = <0x00>; + clocks = <0x02 0x25 0x02 0x156>; + clock-names = "spiclk\0apb_pclk"; + dmas = <0x2b 0x0e 0x2b 0x0f>; + dma-names = "tx\0rx"; + pinctrl-names = "default\0high_speed"; + pinctrl-0 = <0x73 0x74 0x75 0x76 0x77>; + pinctrl-1 = <0x78 0x74 0x75 0x79 0x7a>; + status = "disabled"; + phandle = <0xf1>; + }; + + watchdog@ff1e0000 { + compatible = "snps,dw-wdt"; + reg = <0x00 0xff1e0000 0x00 0x100>; + clocks = <0x02 0x15b>; + interrupts = <0x00 0x25 0x04>; + resets = <0x02 0xb5>; + reset-names = "reset"; + status = "disabled"; + phandle = <0xf2>; + }; + + pwm@ff200000 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200000 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7b>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "okay"; + phandle = <0xbc>; + }; + + pwm@ff200010 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200010 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7c>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "okay"; + phandle = <0xc1>; + }; + + pwm@ff200020 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200020 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7d>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf3>; + }; + + pwm@ff200030 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200030 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7e>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf4>; + }; + + pwm@ff208000 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208000 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7f>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf5>; + }; + + pwm@ff208010 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208010 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x80>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf6>; + }; + + pwm@ff208020 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208020 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x81>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf7>; + }; + + pwm@ff208030 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208030 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x82>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf8>; + }; + + rktimer@ff210000 { + compatible = "rockchip,rk3288-timer"; + reg = <0x00 0xff210000 0x00 0x1000>; + interrupts = <0x00 0x1e 0x04>; + clocks = <0x02 0x159 0x02 0x26>; + clock-names = "pclk\0timer"; + phandle = <0xf9>; + }; + + amba { + compatible = "simple-bus"; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + + dmac@ff240000 { + compatible = "arm,pl330\0arm,primecell"; + reg = <0x00 0xff240000 0x00 0x4000>; + interrupts = <0x00 0x01 0x04 0x00 0x02 0x04>; + clocks = <0x02 0xbb>; + clock-names = "apb_pclk"; + #dma-cells = <0x01>; + peripherals-req-type-burst; + phandle = <0x2b>; + }; + }; + + thermal-zones { + phandle = <0xfa>; + + soc-thermal { + polling-delay-passive = <0x14>; + polling-delay = <0x3e8>; + sustainable-power = <0x2ee>; + thermal-sensors = <0x83 0x00>; + phandle = <0xfb>; + + trips { + + trip-point-0 { + temperature = <0x11170>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0xfc>; + }; + + trip-point-1 { + temperature = <0x14c08>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0x84>; + }; + + soc-crit { + temperature = <0x1c138>; + hysteresis = <0x7d0>; + type = "critical"; + phandle = <0xfd>; + }; + }; + + cooling-maps { + + map0 { + trip = <0x84>; + cooling-device = <0x09 0xffffffff 0xffffffff>; + contribution = <0x1000>; + }; + + map1 { + trip = <0x84>; + cooling-device = <0x85 0xffffffff 0xffffffff>; + contribution = <0x1000>; + }; + }; + }; + + gpu-thermal { + polling-delay-passive = <0x64>; + polling-delay = <0x3e8>; + thermal-sensors = <0x83 0x01>; + phandle = <0xfe>; + }; + }; + + tsadc@ff280000 { + compatible = "rockchip,px30-tsadc"; + reg = <0x00 0xff280000 0x00 0x100>; + interrupts = <0x00 0x24 0x04>; + rockchip,grf = <0x2f>; + clocks = <0x02 0x2c 0x02 0x158>; + clock-names = "tsadc\0apb_pclk"; + assigned-clocks = <0x02 0x2c>; + assigned-clock-rates = <0xc350>; + resets = <0x02 0xa8>; + reset-names = "tsadc-apb"; + #thermal-sensor-cells = <0x01>; + rockchip,hw-tshut-temp = <0x1d4c0>; + status = "okay"; + pinctrl-names = "gpio\0otpout"; + pinctrl-0 = <0x86>; + pinctrl-1 = <0x87>; + phandle = <0x83>; + }; + + saradc@ff288000 { + compatible = "rockchip,px30-saradc\0rockchip,rk3399-saradc"; + reg = <0x00 0xff288000 0x00 0x100>; + interrupts = <0x00 0x54 0x04>; + #io-channel-cells = <0x01>; + clocks = <0x02 0x2d 0x02 0x157>; + clock-names = "saradc\0apb_pclk"; + resets = <0x02 0xa5>; + reset-names = "saradc-apb"; + status = "okay"; + vref-supply = <0x88>; + phandle = <0xbe>; + }; + + otp@ff290000 { + compatible = "rockchip,px30-otp"; + reg = <0x00 0xff290000 0x00 0x4000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + clocks = <0x02 0x2f 0x02 0x15a 0x02 0x161>; + clock-names = "clk_otp\0pclk_otp\0pclk_otp_phy"; + resets = <0x02 0xb4>; + reset-names = "otp_phy"; + phandle = <0xff>; + + id@7 { + reg = <0x07 0x10>; + phandle = <0x0f>; + }; + + cpu-leakage@17 { + reg = <0x17 0x01>; + phandle = <0x07>; + }; + + performance@1e { + reg = <0x1e 0x01>; + bits = <0x04 0x03>; + phandle = <0x08>; + }; + }; + + clock-controller@ff2b0000 { + compatible = "rockchip,px30-cru"; + reg = <0x00 0xff2b0000 0x00 0x1000>; + rockchip,grf = <0x2f>; + rockchip,boost = <0x89>; + #clock-cells = <0x01>; + #reset-cells = <0x01>; + assigned-clocks = <0x02 0x04>; + assigned-clock-rates = <0x3dfd2400>; + phandle = <0x02>; + }; + + cpu-boost@ff2b8000 { + compatible = "syscon"; + reg = <0x00 0xff2b8000 0x00 0x1000>; + rockchip,boost-low-con0 = <0x1032>; + rockchip,boost-low-con1 = <0x1441>; + rockchip,boost-high-con0 = <0x1036>; + rockchip,boost-high-con1 = <0x1441>; + rockchip,boost-backup-pll = <0x01>; + rockchip,boost-backup-pll-usage = <0x00>; + rockchip,boost-switch-threshold = <0x249f00>; + rockchip,boost-statis-threshold = <0x100>; + rockchip,boost-statis-enable = <0x00>; + rockchip,boost-enable = <0x00>; + phandle = <0x89>; + }; + + pmu-clock-controller@ff2bc000 { + compatible = "rockchip,px30-pmucru"; + reg = <0x00 0xff2bc000 0x00 0x1000>; + rockchip,grf = <0x2f>; + #clock-cells = <0x01>; + #reset-cells = <0x01>; + assigned-clocks = <0x2a 0x01 0x2a 0x08 0x2a 0x05 0x02 0x07 0x02 0xab 0x02 0xb0 0x02 0xf0 0x02 0xf5 0x02 0x140 0x02 0x49>; + assigned-clock-rates = <0x47868c00 0x5f5e100 0x18cba80 0x23c34600 0xbebc200 0xbebc200 0x8f0d180 0x8f0d180 0x5f5e100 0xbebc200>; + phandle = <0x2a>; + }; + + syscon@ff2c0000 { + compatible = "rockchip,px30-usb2phy-grf\0syscon\0simple-mfd"; + reg = <0x00 0xff2c0000 0x00 0x10000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0x100>; + + usb2-phy@100 { + compatible = "rockchip,px30-usb2phy\0rockchip,rk3328-usb2phy"; + reg = <0x100 0x10>; + clocks = <0x2a 0x0a>; + clock-names = "phyclk"; + #clock-cells = <0x00>; + assigned-clocks = <0x02 0x0e 0x02 0x55>; + assigned-clock-parents = <0x67 0x02 0x0e>; + clock-output-names = "usb480m_phy"; + status = "okay"; + phandle = <0x67>; + + host-port { + #phy-cells = <0x00>; + interrupts = <0x00 0x44 0x04>; + interrupt-names = "linestate"; + status = "okay"; + phandle = <0x8c>; + }; + + otg-port { + #phy-cells = <0x00>; + interrupts = <0x00 0x42 0x04 0x00 0x41 0x04 0x00 0x40 0x04>; + interrupt-names = "otg-bvalid\0otg-id\0linestate"; + status = "disabled"; + phandle = <0x8b>; + }; + }; + }; + + video-phy@ff2e0000 { + compatible = "rockchip,px30-video-phy"; + reg = <0x00 0xff2e0000 0x00 0x10000 0x00 0xff450000 0x00 0x10000>; + clocks = <0x2a 0x0b 0x02 0x145 0x02 0x144>; + clock-names = "ref\0pclk_phy\0pclk_host"; + #clock-cells = <0x00>; + resets = <0x02 0x3e>; + reset-names = "rst"; + power-domains = <0x8a 0x0c>; + #phy-cells = <0x00>; + status = "okay"; + phandle = <0x4c>; + }; + + mipi-dphy-rx0@ff2f0000 { + compatible = "rockchip,rk3326-mipi-dphy"; + reg = <0x00 0xff2f0000 0x00 0x4000>; + clocks = <0x02 0x146>; + clock-names = "dphy-ref"; + power-domains = <0x8a 0x0d>; + rockchip,grf = <0x2f>; + status = "okay"; + phandle = <0x101>; + }; + + usb@ff300000 { + compatible = "rockchip,px30-usb\0rockchip,rk3066-usb\0snps,dwc2"; + reg = <0x00 0xff300000 0x00 0x40000>; + interrupts = <0x00 0x3e 0x04>; + clocks = <0x02 0x102>; + clock-names = "otg"; + power-domains = <0x8a 0x05>; + dr_mode = "otg"; + g-np-tx-fifo-size = <0x10>; + g-rx-fifo-size = <0x118>; + g-tx-fifo-size = <0x100 0x80 0x80 0x40 0x20 0x10>; + g-use-dma; + phys = <0x8b>; + phy-names = "usb2-phy"; + status = "okay"; + phandle = <0x102>; + }; + + usb@ff340000 { + compatible = "generic-ehci"; + reg = <0x00 0xff340000 0x00 0x10000>; + interrupts = <0x00 0x3c 0x04>; + clocks = <0x02 0x103 0x67>; + clock-names = "usbhost\0utmi"; + power-domains = <0x8a 0x05>; + phys = <0x8c>; + phy-names = "usb"; + status = "disabled"; + phandle = <0x103>; + }; + + usb@ff350000 { + compatible = "generic-ohci"; + reg = <0x00 0xff350000 0x00 0x10000>; + interrupts = <0x00 0x3d 0x04>; + clocks = <0x02 0x103 0x67>; + clock-names = "usbhost\0utmi"; + power-domains = <0x8a 0x05>; + phys = <0x8c>; + phy-names = "usb"; + status = "disabled"; + phandle = <0x104>; + }; + + ethernet@ff360000 { + compatible = "rockchip,px30-gmac"; + reg = <0x00 0xff360000 0x00 0x10000>; + rockchip,grf = <0x2f>; + interrupts = <0x00 0x2b 0x04>; + interrupt-names = "macirq"; + clocks = <0x02 0x3e 0x02 0x3f 0x02 0x3f 0x02 0x40 0x02 0x41 0x02 0xb2 0x02 0x143 0x02 0x4c>; + clock-names = "stmmaceth\0mac_clk_rx\0mac_clk_tx\0clk_mac_ref\0clk_mac_refout\0aclk_mac\0pclk_mac\0clk_mac_speed"; + phy-mode = "rmii"; + pinctrl-names = "default"; + pinctrl-0 = <0x8d 0x8e>; + resets = <0x02 0x5e>; + reset-names = "stmmaceth"; + power-domains = <0x8a 0x09>; + status = "disabled"; + phandle = <0x105>; + }; + + dwmmc@ff370000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff370000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0xf7 0x02 0x3b 0x02 0x43 0x02 0x44>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x3b>; + assigned-clock-parents = <0x02 0x57>; + power-domains = <0x8a 0x07>; + fifo-depth = <0x100>; + interrupts = <0x00 0x36 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x8f 0x90 0x91 0x92>; + status = "okay"; + bus-width = <0x04>; + cap-mmc-highspeed; + cap-sd-highspeed; + supports-sd; + card-detect-delay = <0x320>; + ignore-pm-notify; + cd-gpios = <0x5c 0x03 0x01>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <0x4a>; + vmmc-supply = <0x93>; + phandle = <0x106>; + }; + + dwmmc@ff380000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff380000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0xff 0x02 0x38 0x02 0x45 0x02 0x46>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x38>; + assigned-clock-parents = <0x02 0x51>; + power-domains = <0x8a 0x0a>; + fifo-depth = <0x100>; + interrupts = <0x00 0x37 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x94 0x95 0x96>; + status = "okay"; + bus-width = <0x04>; + cap-mmc-highspeed; + cap-sd-highspeed; + supports-sd; + card-detect-delay = <0x320>; + ignore-pm-notify; + cd-gpios = <0x97 0x0e 0x01>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <0x4a>; + vmmc-supply = <0x93>; + phandle = <0x107>; + }; + + dwmmc@ff390000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff390000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0x100 0x02 0x39 0x02 0x47 0x02 0x48>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x39>; + assigned-clock-parents = <0x02 0x53>; + power-domains = <0x8a 0x0a>; + fifo-depth = <0x100>; + interrupts = <0x00 0x35 0x04>; + status = "disabled"; + phandle = <0x108>; + }; + + nandc@ff3b0000 { + compatible = "rockchip,rk-nandc"; + reg = <0x00 0xff3b0000 0x00 0x4000>; + interrupts = <0x00 0x39 0x04>; + nandc_id = <0x00>; + clocks = <0x02 0x37 0x02 0xfe>; + clock-names = "clk_nandc\0hclk_nandc"; + assigned-clocks = <0x02 0x37>; + assigned-clock-parents = <0x02 0x4f>; + power-domains = <0x8a 0x0a>; + status = "disabled"; + phandle = <0x109>; + }; + + sfc@ff3a0000 { + compatible = "rockchip,sfc"; + reg = <0x00 0xff3a0000 0x00 0x4000>; + interrupts = <0x00 0x38 0x04>; + clocks = <0x02 0x3a 0x02 0x101>; + clock-names = "clk_sfc\0hclk_sfc"; + assigned-clocks = <0x02 0x3a>; + assigned-clock-rates = <0x989680>; + status = "disabled"; + phandle = <0x10a>; + }; + + gpu@ff400000 { + compatible = "arm,malit602\0arm,malit60x\0arm,malit6xx\0arm,mali-midgard"; + reg = <0x00 0xff400000 0x00 0x4000>; + interrupts = <0x00 0x2d 0x04 0x00 0x2e 0x04 0x00 0x2f 0x04>; + interrupt-names = "GPU\0MMU\0JOB"; + clocks = <0x02 0x49>; + clock-names = "clk_mali"; + power-domains = <0x8a 0x0e>; + #cooling-cells = <0x02>; + operating-points-v2 = <0x98>; + status = "okay"; + mali-supply = <0x0e>; + phandle = <0x85>; + + power_model { + compatible = "arm,mali-simple-power-model"; + static-coefficient = <0x64578>; + dynamic-coefficient = <0x2dd>; + ts = <0x7d00 0x125c 0xffffffb0 0x02>; + thermal-zone = "gpu-thermal"; + }; + }; + + gpu-opp-table { + compatible = "operating-points-v2"; + rockchip,thermal-zone = "soc-thermal"; + rockchip,temp-hysteresis = <0x1388>; + rockchip,low-temp = <0x00>; + rockchip,low-temp-min-volt = <0xf4240>; + rockchip,low-temp-adjust-volt = <0x00 0x1e0 0xc350>; + rockchip,max-volt = <0x11edd8>; + rockchip,evb-irdrop = <0x61a8>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-ch = <0x00 0x00>; + phandle = <0x98>; + + opp-400000000 { + opp-hz = <0x00 0x17d78400>; + opp-microvolt = <0x100590>; + opp-microvolt-L0 = <0x100590>; + opp-microvolt-L1 = <0xfa3e8>; + opp-microvolt-L2 = <0xee098>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-480000000 { + opp-hz = <0x00 0x1c9c3800>; + opp-microvolt = <0x112a88>; + opp-microvolt-L0 = <0x112a88>; + opp-microvolt-L1 = <0x10c8e0>; + opp-microvolt-L2 = <0x100590>; + opp-microvolt-L3 = <0xf4240>; + }; + + opp-520000000 { + opp-hz = <0x00 0x1efe9200>; + opp-microvolt = <0x118c30>; + opp-microvolt-L0 = <0x118c30>; + opp-microvolt-L1 = <0x118c30>; + opp-microvolt-L2 = <0x10c8e0>; + opp-microvolt-L3 = <0x100590>; + }; + }; + + hevc_service@ff440000 { + compatible = "rockchip,hevc_sub"; + iommu_enabled = <0x01>; + reg = <0x00 0xff440000 0x00 0x400>; + interrupts = <0x00 0x31 0x04>; + interrupt-names = "irq_dec"; + dev_mode = <0x01>; + iommus = <0x99>; + allocator = <0x01>; + phandle = <0x9c>; + }; + + vpu_service@ff442000 { + compatible = "rockchip,vpu_sub"; + iommu_enabled = <0x01>; + reg = <0x00 0xff442000 0x00 0x800>; + interrupts = <0x00 0x50 0x04 0x00 0x4f 0x04>; + interrupt-names = "irq_enc\0irq_dec"; + dev_mode = <0x00>; + iommus = <0x9a>; + allocator = <0x01>; + phandle = <0x9b>; + }; + + vpu_combo { + compatible = "rockchip,vpu_combo"; + subcnt = <0x02>; + rockchip,grf = <0x2f>; + rockchip,sub = <0x9b 0x9c>; + clocks = <0x02 0xaf 0x02 0xf4 0x02 0x4b>; + clock-names = "aclk_vcodec\0hclk_vcodec\0clk_core"; + resets = <0x02 0x24 0x02 0x26 0x02 0x25 0x02 0x27 0x02 0x3f>; + reset-names = "video_a\0video_h\0niu_a\0niu_h\0video_core"; + power-domains = <0x8a 0x0b>; + mode_bit = <0x0f>; + mode_ctrl = <0x410>; + status = "okay"; + phandle = <0x10b>; + }; + + iommu@ff440440 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff440440 0x00 0x40 0x00 0xff440480 0x00 0x40>; + interrupts = <0x00 0x32 0x04>; + interrupt-names = "hevc_mmu"; + clocks = <0x02 0xaf 0x02 0xf4>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0b>; + #iommu-cells = <0x00>; + phandle = <0x99>; + }; + + iommu@ff442800 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff442800 0x00 0x100>; + interrupts = <0x00 0x51 0x04>; + interrupt-names = "vpu_mmu"; + clocks = <0x02 0xaf 0x02 0xf4>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0b>; + #iommu-cells = <0x00>; + phandle = <0x9a>; + }; + + dsi@ff450000 { + compatible = "rockchip,px30-mipi-dsi"; + reg = <0x00 0xff450000 0x00 0x10000>; + interrupts = <0x00 0x4b 0x04>; + clocks = <0x02 0x144 0x4c>; + clock-names = "pclk\0hs_clk"; + resets = <0x02 0x3d>; + reset-names = "apb"; + phys = <0x4c>; + phy-names = "mipi_dphy"; + power-domains = <0x8a 0x0c>; + rockchip,grf = <0x2f>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + phandle = <0x10c>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x13>; + status = "okay"; + phandle = <0xa3>; + }; + }; + }; + + panel@0 { + compatible = "sitronix,st7703\0simple-panel-dsi"; + reg = <0x00>; + backlight = <0x9d>; + power-supply = <0x9f>; + prepare-delay-ms = <0x14>; + reset-delay-ms = <0x14>; + init-delay-ms = <0x14>; + enable-delay-ms = <0x78>; + disable-delay-ms = <0x14>; + unprepare-delay-ms = <0x14>; + width-mm = <0x99>; + height-mm = <0x55>; + dsi,flags = <0xa03>; + dsi,format = <0x00>; + dsi,lanes = <0x04>; + panel-init-sequence = [05 fa 01 11 39 00 04 b9 f1 12 83 39 00 1c ba 33 81 05 f9 0e 0e 20 00 00 00 00 00 00 00 44 25 00 90 0a 00 00 01 4f 01 00 00 37 39 00 05 b8 25 22 f0 63 39 00 04 bf 02 11 00 39 00 0b b3 10 10 28 28 03 ff 00 00 00 00 39 00 0a c0 73 73 50 50 00 00 12 70 00 15 00 02 bc 46 15 00 02 cc 0b 15 00 02 b4 80 39 00 04 b2 3c 12 30 39 00 0f e3 07 07 0b 0b 03 0b 00 00 00 00 ff 00 c0 10 39 00 0d c1 36 00 32 32 77 f1 cc cc 77 77 33 33 39 00 03 b5 0a 0a 39 00 03 b6 88 88 39 00 40 e9 c8 10 0a 10 0f a1 80 12 31 23 47 86 a1 80 47 08 00 00 0d 00 00 00 00 00 0d 00 00 00 48 02 8b af 46 02 88 88 88 88 88 48 13 8b af 57 13 88 88 88 88 88 00 00 00 00 00 00 00 00 00 00 00 00 00 39 00 3e ea 96 12 01 01 01 78 02 00 00 00 00 00 4f 31 8b a8 31 75 88 88 88 88 88 4f 20 8b a8 20 64 88 88 88 88 88 23 00 00 01 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 40 a1 80 00 00 00 00 39 00 23 e0 00 0a 0f 29 3b 3f 42 39 06 0d 10 13 15 14 15 10 17 00 0a 0f 29 3b 3f 42 39 06 0d 10 13 15 14 15 10 17 05 32 01 29]; + panel-exit-sequence = <0x5140128 0x50a0110>; + reset-gpios = <0x97 0x10 0x01>; + + display-timings { + native-mode = <0xa0>; + + 60Hz { + clock-frequency = <0x22cf220>; + hactive = <0x2d0>; + vactive = <0x2d0>; + hfront-porch = <0x2d>; + hsync-len = <0x04>; + hback-porch = <0x2d>; + vfront-porch = <0x0f>; + vsync-len = <0x03>; + vback-porch = <0x0b>; + hsync-active = <0x00>; + vsync-active = <0x00>; + de-active = <0x00>; + pixelclk-active = <0x00>; + phandle = <0xa0>; + }; + }; + }; + }; + + vop@ff460000 { + compatible = "rockchip,px30-vop-big"; + reg = <0x00 0xff460000 0x00 0x1fc 0x00 0xff460a00 0x00 0x400>; + rockchip,grf = <0x2f>; + reg-names = "regs\0gamma_lut"; + interrupts = <0x00 0x4d 0x04>; + clocks = <0x02 0xb5 0x02 0x96 0x02 0xfb>; + clock-names = "aclk_vop\0dclk_vop\0hclk_vop"; + power-domains = <0x8a 0x0c>; + iommus = <0xa1>; + status = "okay"; + phandle = <0x10f>; + + port { + #address-cells = <0x01>; + #size-cells = <0x00>; + phandle = <0x10>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0xa2>; + phandle = <0x12>; + }; + + endpoint@1 { + reg = <0x01>; + remote-endpoint = <0xa3>; + phandle = <0x13>; + }; + + endpoint@2 { + reg = <0x02>; + remote-endpoint = <0xa4>; + phandle = <0x14>; + }; + }; + }; + + iommu@ff460f00 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff460f00 0x00 0x100>; + interrupts = <0x00 0x4d 0x04>; + interrupt-names = "vopb_mmu"; + clocks = <0x02 0xb5 0x02 0xfb>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0c>; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xa1>; + }; + + rk_rga@ff480000 { + compatible = "rockchip,rga2"; + reg = <0x00 0xff480000 0x00 0x1000>; + interrupts = <0x00 0x4c 0x04>; + clocks = <0x02 0xb7 0x02 0xfd 0x02 0x35>; + clock-names = "aclk_rga\0hclk_rga\0clk_rga"; + power-domains = <0x8a 0x0c>; + dma-coherent; + status = "okay"; + phandle = <0x110>; + }; + + cif@ff490000 { + compatible = "rockchip,cif"; + reg = <0x00 0xff490000 0x00 0x200>; + interrupts = <0x00 0x45 0x04>; + clocks = <0x02 0xb3 0x02 0xf9 0x02 0x160 0x02 0x34>; + clock-names = "aclk_cif0\0hclk_cif0\0pclk_cif\0cif0_out"; + resets = <0x02 0x2c 0x02 0x2d 0x02 0x2e>; + reset-names = "rst_cif_a\0rst_cif_h\0rst_cif_pclkin"; + power-domains = <0x8a 0x0d>; + pinctrl-names = "cif_pin_all"; + pinctrl-0 = <0xa5>; + iommus = <0xa6>; + status = "disabled"; + phandle = <0x111>; + }; + + cif-new@ff490000 { + compatible = "rockchip,px30-cif"; + reg = <0x00 0xff490000 0x00 0x200>; + interrupts = <0x00 0x45 0x04>; + clocks = <0x02 0xb3 0x02 0xf9 0x02 0x160 0x02 0x34>; + clock-names = "aclk_cif\0hclk_cif\0pclk_cif\0cif_out"; + resets = <0x02 0x2c 0x02 0x2d 0x02 0x2e>; + reset-names = "rst_cif_a\0rst_cif_h\0rst_cif_pclkin"; + power-domains = <0x8a 0x0d>; + iommus = <0xa6>; + status = "disabled"; + phandle = <0x112>; + }; + + iommu@ff490800 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff490800 0x00 0x100>; + interrupts = <0x00 0x45 0x04>; + interrupt-names = "vip_mmu"; + clocks = <0x02 0xb3 0x02 0xf9>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0d>; + rk_iommu,disable_reset_quirk; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xa6>; + }; + + rk_isp@ff4a0000 { + compatible = "rockchip,px30-isp\0rockchip,isp"; + reg = <0x00 0xff4a0000 0x00 0x8000>; + interrupts = <0x00 0x46 0x04>; + clocks = <0x02 0xb4 0x02 0xfa 0x02 0x33 0x02 0x33 0x02 0x15f 0x02 0x34 0x02 0x34 0x02 0x146>; + clock-names = "aclk_isp\0hclk_isp\0clk_isp\0clk_isp_jpe\0pclkin_isp\0clk_cif_pll\0clk_cif_out\0pclk_dphyrx"; + resets = <0x02 0x2b 0x02 0x2f>; + reset-names = "rst_isp\0rst_mipicsiphy"; + power-domains = <0x8a 0x0d>; + pinctrl-names = "default\0isp_dvp8bit2\0isp_dvp10bit\0isp_dvp12bit"; + pinctrl-0 = <0xa7>; + pinctrl-1 = <0xa5>; + pinctrl-2 = <0xa5 0xa8>; + pinctrl-3 = <0xa9 0xa5 0xa8>; + rockchip,isp,mipiphy = <0x01>; + rockchip,isp,csiphy,reg = <0xff2f0000 0x4000>; + rockchip,grf = <0x2f>; + rockchip,cru = <0x02>; + rockchip,isp,iommu-enable = <0x01>; + iommus = <0xaa>; + status = "disabled"; + phandle = <0x113>; + }; + + rkisp1@ff4a0000 { + compatible = "rockchip,rk3326-rkisp1"; + reg = <0x00 0xff4a0000 0x00 0x8000>; + interrupts = <0x00 0x46 0x04 0x00 0x49 0x04 0x00 0x4a 0x04>; + interrupt-names = "isp_irq\0mi_irq\0mipi_irq"; + clocks = <0x02 0xb4 0x02 0xfa 0x02 0x33 0x02 0x15f>; + clock-names = "aclk_isp\0hclk_isp\0clk_isp\0pclk_isp"; + devfreq = <0xab>; + power-domains = <0x8a 0x0d>; + iommus = <0xaa>; + rockchip,grf = <0x2f>; + status = "okay"; + phandle = <0x114>; + }; + + iommu@ff4a8000 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff4a8000 0x00 0x100>; + interrupts = <0x00 0x46 0x04>; + interrupt-names = "isp_mmu"; + clocks = <0x02 0xb4 0x02 0xfa>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0d>; + rk_iommu,disable_reset_quirk; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xaa>; + }; + + qos@ff518000 { + compatible = "syscon"; + reg = <0x00 0xff518000 0x00 0x20>; + phandle = <0x18>; + }; + + qos@ff520000 { + compatible = "syscon"; + reg = <0x00 0xff520000 0x00 0x20>; + phandle = <0x28>; + }; + + qos@ff52c000 { + compatible = "syscon"; + reg = <0x00 0xff52c000 0x00 0x20>; + phandle = <0x17>; + }; + + qos@ff538000 { + compatible = "syscon"; + reg = <0x00 0xff538000 0x00 0x20>; + phandle = <0x19>; + }; + + qos@ff538080 { + compatible = "syscon"; + reg = <0x00 0xff538080 0x00 0x20>; + phandle = <0x1a>; + }; + + qos@ff538100 { + compatible = "syscon"; + reg = <0x00 0xff538100 0x00 0x20>; + phandle = <0x1b>; + }; + + qos@ff538180 { + compatible = "syscon"; + reg = <0x00 0xff538180 0x00 0x20>; + phandle = <0x1c>; + }; + + qos@ff540000 { + compatible = "syscon"; + reg = <0x00 0xff540000 0x00 0x20>; + phandle = <0x15>; + }; + + qos@ff540080 { + compatible = "syscon"; + reg = <0x00 0xff540080 0x00 0x20>; + phandle = <0x16>; + }; + + qos@ff548000 { + compatible = "syscon"; + reg = <0x00 0xff548000 0x00 0x20>; + phandle = <0x23>; + }; + + qos@ff548080 { + compatible = "syscon"; + reg = <0x00 0xff548080 0x00 0x20>; + phandle = <0x24>; + }; + + qos@ff548100 { + compatible = "syscon"; + reg = <0x00 0xff548100 0x00 0x20>; + phandle = <0x25>; + }; + + qos@ff548180 { + compatible = "syscon"; + reg = <0x00 0xff548180 0x00 0x20>; + phandle = <0x26>; + }; + + qos@ff548200 { + compatible = "syscon"; + reg = <0x00 0xff548200 0x00 0x20>; + phandle = <0x27>; + }; + + qos@ff550000 { + compatible = "syscon"; + reg = <0x00 0xff550000 0x00 0x20>; + phandle = <0x1f>; + }; + + qos@ff550080 { + compatible = "syscon"; + reg = <0x00 0xff550080 0x00 0x20>; + phandle = <0x20>; + }; + + qos@ff550100 { + compatible = "syscon"; + reg = <0x00 0xff550100 0x00 0x20>; + phandle = <0x21>; + }; + + qos@ff550180 { + compatible = "syscon"; + reg = <0x00 0xff550180 0x00 0x20>; + phandle = <0x22>; + }; + + qos@ff558000 { + compatible = "syscon"; + reg = <0x00 0xff558000 0x00 0x20>; + phandle = <0x1d>; + }; + + qos@ff558080 { + compatible = "syscon"; + reg = <0x00 0xff558080 0x00 0x20>; + phandle = <0x1e>; + }; + + dfi@ff610000 { + reg = <0x00 0xff610000 0x00 0x400>; + compatible = "rockchip,px30-dfi"; + rockchip,pmugrf = <0xac>; + status = "okay"; + phandle = <0xad>; + }; + + dmc { + compatible = "rockchip,px30-dmc"; + interrupts = <0x00 0x69 0x04>; + interrupt-names = "complete_irq"; + devfreq-events = <0xad>; + clocks = <0x02 0x54>; + clock-names = "dmc_clk"; + operating-points-v2 = <0xae>; + ddr_timing = <0xaf>; + upthreshold = <0x28>; + downdifferential = <0x14>; + system-status-freq = <0x01 0x80e80 0x08 0x6ddd0 0x02 0x2f5d0 0x20 0x6ddd0 0x1000 0x80e80 0x4000 0xa2990 0x2000 0xa2990>; + auto-min-freq = <0x50140>; + auto-freq-en = <0x01>; + #cooling-cells = <0x02>; + status = "okay"; + center-supply = <0x0e>; + phandle = <0xab>; + + ddr_power_model { + compatible = "ddr_power_model"; + dynamic-power-coefficient = <0x78>; + static-power-coefficient = <0xc8>; + ts = <0x7d00 0x125c 0xffffffb0 0x02>; + thermal-zone = "soc-thermal"; + phandle = <0x115>; + }; + }; + + dmc-opp-table { + compatible = "operating-points-v2"; + rockchip,max-volt = <0x118c30>; + rockchip,evb-irdrop = <0x61a8>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-ch = <0x00 0x00>; + phandle = <0xae>; + + opp-528000000 { + opp-hz = <0x00 0x1f78a400>; + opp-microvolt = <0xee098>; + opp-microvolt-L0 = <0xee098>; + opp-microvolt-L1 = <0xee098>; + opp-microvolt-L2 = <0xe7ef0>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-666000000 { + opp-hz = <0x00 0x27b25a80>; + opp-microvolt = <0x100590>; + opp-microvolt-L0 = <0x100590>; + opp-microvolt-L1 = <0xf4240>; + opp-microvolt-L2 = <0xee098>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-786000000 { + opp-hz = <0x00 0x2ed96880>; + opp-microvolt = <0x10c8e0>; + opp-microvolt-L0 = <0x10c8e0>; + opp-microvolt-L1 = <0x100590>; + opp-microvolt-L2 = <0xfa3e8>; + opp-microvolt-L3 = <0xf4240>; + status = "okay"; + }; + }; + + rockchip-system-monitor { + compatible = "rockchip,system-monitor"; + rockchip,thermal-zone = "soc-thermal"; + rockchip,polling-delay = <0xc8>; + phandle = <0x116>; + }; + + pinctrl { + compatible = "rockchip,px30-pinctrl"; + rockchip,grf = <0x2f>; + rockchip,pmu = <0xac>; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + phandle = <0x117>; + + gpio0@ff040000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff040000 0x00 0x100>; + interrupts = <0x00 0x03 0x04>; + clocks = <0x2a 0x14>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x5c>; + }; + + gpio1@ff250000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff250000 0x00 0x100>; + interrupts = <0x00 0x04 0x04>; + clocks = <0x02 0x15c>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0xbf>; + }; + + gpio2@ff260000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff260000 0x00 0x100>; + interrupts = <0x00 0x05 0x04>; + clocks = <0x02 0x15d>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x66>; + }; + + gpio3@ff270000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff270000 0x00 0x100>; + interrupts = <0x00 0x06 0x04>; + clocks = <0x02 0x15e>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x97>; + }; + + pcfg-pull-up { + bias-pull-up; + phandle = <0xb2>; + }; + + pcfg-pull-down { + bias-pull-down; + phandle = <0x118>; + }; + + pcfg-pull-none { + bias-disable; + phandle = <0xb1>; + }; + + pcfg-pull-none-2ma { + bias-disable; + drive-strength = <0x02>; + phandle = <0x119>; + }; + + pcfg-pull-up-2ma { + bias-pull-up; + drive-strength = <0x02>; + phandle = <0x11a>; + }; + + pcfg-pull-up-4ma { + bias-pull-up; + drive-strength = <0x04>; + phandle = <0xb3>; + }; + + pcfg-pull-none-4ma { + bias-disable; + drive-strength = <0x04>; + phandle = <0x11b>; + }; + + pcfg-pull-down-4ma { + bias-pull-down; + drive-strength = <0x04>; + phandle = <0x11c>; + }; + + pcfg-pull-none-8ma { + bias-disable; + drive-strength = <0x08>; + phandle = <0xb6>; + }; + + pcfg-pull-up-8ma { + bias-pull-up; + drive-strength = <0x08>; + phandle = <0xb4>; + }; + + pcfg-pull-none-12ma { + bias-disable; + drive-strength = <0x0c>; + phandle = <0xb8>; + }; + + pcfg-pull-up-12ma { + bias-pull-up; + drive-strength = <0x0c>; + phandle = <0xb7>; + }; + + pcfg-pull-none-smt { + bias-disable; + input-schmitt-enable; + phandle = <0xb0>; + }; + + pcfg-output-high { + output-high; + phandle = <0x11d>; + }; + + pcfg-output-low { + output-low; + phandle = <0xb9>; + }; + + pcfg-input-high { + bias-pull-up; + input-enable; + phandle = <0xb5>; + }; + + pcfg-input { + input-enable; + phandle = <0x11e>; + }; + + i2c0 { + + i2c0-xfer { + rockchip,pins = <0x00 0x08 0x01 0xb0 0x00 0x09 0x01 0xb0>; + phandle = <0x5b>; + }; + }; + + i2c1 { + + i2c1-xfer { + rockchip,pins = <0x00 0x12 0x01 0xb0 0x00 0x13 0x01 0xb0>; + phandle = <0x69>; + }; + }; + + i2c2 { + + i2c2-xfer { + rockchip,pins = <0x02 0x0f 0x02 0xb0 0x02 0x10 0x02 0xb0>; + phandle = <0x6a>; + }; + }; + + i2c3 { + + i2c3-xfer { + rockchip,pins = <0x01 0x0c 0x04 0xb0 0x01 0x0d 0x04 0xb0>; + phandle = <0x6b>; + }; + }; + + tsadc { + + tsadc-otp-gpio { + rockchip,pins = <0x00 0x06 0x00 0xb1>; + phandle = <0x86>; + }; + + tsadc-otp-out { + rockchip,pins = <0x00 0x06 0x01 0xb1>; + phandle = <0x87>; + }; + }; + + uart0 { + + uart0-xfer { + rockchip,pins = <0x00 0x0a 0x01 0xb2 0x00 0x0b 0x01 0xb2>; + phandle = <0x2c>; + }; + + uart0-cts { + rockchip,pins = <0x00 0x0c 0x01 0xb1>; + phandle = <0x2d>; + }; + + uart0-rts { + rockchip,pins = <0x00 0x0d 0x01 0xb1>; + phandle = <0x2e>; + }; + + uart0-rts-gpio { + rockchip,pins = <0x00 0x0d 0x00 0xb1>; + phandle = <0x11f>; + }; + }; + + uart1 { + + uart1-xfer { + rockchip,pins = <0x01 0x11 0x01 0xb2 0x01 0x10 0x01 0xb2>; + phandle = <0x4f>; + }; + + uart1-cts { + rockchip,pins = <0x01 0x12 0x01 0xb1>; + phandle = <0x50>; + }; + + uart1-rts { + rockchip,pins = <0x01 0x13 0x01 0xb1>; + phandle = <0x120>; + }; + + uart1-rts-gpio { + rockchip,pins = <0x01 0x13 0x00 0xb1>; + phandle = <0x121>; + }; + }; + + uart2-m0 { + + uart2m0-xfer { + rockchip,pins = <0x01 0x1a 0x02 0xb2 0x01 0x1b 0x02 0xb2>; + phandle = <0x51>; + }; + }; + + uart2-m1 { + + uart2m1-xfer { + rockchip,pins = <0x02 0x0c 0x02 0xb2 0x02 0x0e 0x02 0xb2>; + phandle = <0xba>; + }; + }; + + uart3-m0 { + + uart3m0-xfer { + rockchip,pins = <0x00 0x10 0x02 0xb2 0x00 0x11 0x02 0xb2>; + phandle = <0x122>; + }; + + uart3m0-cts { + rockchip,pins = <0x00 0x12 0x02 0xb1>; + phandle = <0x123>; + }; + + uart3m0-rts { + rockchip,pins = <0x00 0x13 0x02 0xb1>; + phandle = <0x124>; + }; + + uart3m0-rts-gpio { + rockchip,pins = <0x00 0x13 0x00 0xb1>; + phandle = <0x125>; + }; + }; + + uart3-m1 { + + uart3m1-xfer { + rockchip,pins = <0x01 0x0e 0x02 0xb2 0x01 0x0f 0x02 0xb2>; + phandle = <0x52>; + }; + + uart3m1-cts { + rockchip,pins = <0x01 0x0c 0x02 0xb1>; + phandle = <0x53>; + }; + + uart3m1-rts { + rockchip,pins = <0x01 0x0d 0x02 0xb1>; + phandle = <0x54>; + }; + + uart3m1-rts-gpio { + rockchip,pins = <0x01 0x0d 0x00 0xb1>; + phandle = <0x126>; + }; + }; + + uart4 { + + uart4-xfer { + rockchip,pins = <0x01 0x1c 0x02 0xb2 0x01 0x1d 0x02 0xb2>; + phandle = <0x55>; + }; + + uart4-cts { + rockchip,pins = <0x01 0x1e 0x02 0xb1>; + phandle = <0x56>; + }; + + uart4-rts { + rockchip,pins = <0x01 0x1f 0x02 0xb1>; + phandle = <0x57>; + }; + }; + + uart5 { + + uart5-xfer { + rockchip,pins = <0x03 0x02 0x04 0xb2 0x03 0x01 0x04 0xb2>; + phandle = <0x58>; + }; + + uart5-cts { + rockchip,pins = <0x03 0x03 0x04 0xb1>; + phandle = <0x59>; + }; + + uart5-rts { + rockchip,pins = <0x03 0x05 0x04 0xb1>; + phandle = <0x5a>; + }; + }; + + spi0 { + + spi0-clk { + rockchip,pins = <0x01 0x0f 0x03 0xb3>; + phandle = <0x6c>; + }; + + spi0-csn { + rockchip,pins = <0x01 0x0e 0x03 0xb3>; + phandle = <0x6d>; + }; + + spi0-miso { + rockchip,pins = <0x01 0x0d 0x03 0xb3>; + phandle = <0x6e>; + }; + + spi0-mosi { + rockchip,pins = <0x01 0x0c 0x03 0xb3>; + phandle = <0x6f>; + }; + + spi0-clk-hs { + rockchip,pins = <0x01 0x0f 0x03 0xb4>; + phandle = <0x70>; + }; + + spi0-miso-hs { + rockchip,pins = <0x01 0x0d 0x03 0xb4>; + phandle = <0x71>; + }; + + spi0-mosi-hs { + rockchip,pins = <0x01 0x0c 0x03 0xb4>; + phandle = <0x72>; + }; + }; + + spi1 { + + spi1-clk { + rockchip,pins = <0x03 0x0f 0x04 0xb3>; + phandle = <0x73>; + }; + + spi1-csn0 { + rockchip,pins = <0x03 0x09 0x04 0xb3>; + phandle = <0x74>; + }; + + spi1-csn1 { + rockchip,pins = <0x03 0x0a 0x02 0xb3>; + phandle = <0x75>; + }; + + spi1-miso { + rockchip,pins = <0x03 0x0e 0x04 0xb3>; + phandle = <0x76>; + }; + + spi1-mosi { + rockchip,pins = <0x03 0x0c 0x04 0xb3>; + phandle = <0x77>; + }; + + spi1-clk-hs { + rockchip,pins = <0x03 0x0f 0x04 0xb4>; + phandle = <0x78>; + }; + + spi1-miso-hs { + rockchip,pins = <0x03 0x0e 0x04 0xb4>; + phandle = <0x79>; + }; + + spi1-mosi-hs { + rockchip,pins = <0x03 0x0c 0x04 0xb4>; + phandle = <0x7a>; + }; + }; + + pdm { + + pdm-clk0m0 { + rockchip,pins = <0x03 0x16 0x02 0xb1>; + phandle = <0x44>; + }; + + pdm-clk0m1 { + rockchip,pins = <0x02 0x16 0x01 0xb1>; + phandle = <0x127>; + }; + + pdm-clk1 { + rockchip,pins = <0x03 0x17 0x02 0xb1>; + phandle = <0x45>; + }; + + pdm-sdi0m0 { + rockchip,pins = <0x03 0x1b 0x02 0xb1>; + phandle = <0x46>; + }; + + pdm-sdi0m1 { + rockchip,pins = <0x02 0x15 0x02 0xb1>; + phandle = <0x128>; + }; + + pdm-sdi1 { + rockchip,pins = <0x03 0x18 0x02 0xb1>; + phandle = <0x47>; + }; + + pdm-sdi2 { + rockchip,pins = <0x03 0x19 0x02 0xb1>; + phandle = <0x48>; + }; + + pdm-sdi3 { + rockchip,pins = <0x03 0x1a 0x02 0xb1>; + phandle = <0x49>; + }; + + pdm-clk0m0-sleep { + rockchip,pins = <0x03 0x16 0x00 0xb5>; + phandle = <0x129>; + }; + + pdm-clk0m1-sleep { + rockchip,pins = <0x02 0x16 0x00 0xb5>; + phandle = <0x12a>; + }; + + pdm-clk1-sleep { + rockchip,pins = <0x03 0x17 0x00 0xb5>; + phandle = <0x12b>; + }; + + pdm-sdi0m0-sleep { + rockchip,pins = <0x03 0x1b 0x00 0xb5>; + phandle = <0x12c>; + }; + + pdm-sdi0m1-sleep { + rockchip,pins = <0x02 0x15 0x00 0xb5>; + phandle = <0x12d>; + }; + + pdm-sdi1-sleep { + rockchip,pins = <0x03 0x18 0x00 0xb5>; + phandle = <0x12e>; + }; + + pdm-sdi2-sleep { + rockchip,pins = <0x03 0x19 0x00 0xb5>; + phandle = <0x12f>; + }; + + pdm-sdi3-sleep { + rockchip,pins = <0x03 0x1a 0x00 0xb5>; + phandle = <0x130>; + }; + }; + + i2s0 { + + i2s0-8ch-mclk { + rockchip,pins = <0x03 0x11 0x02 0xb1>; + phandle = <0x131>; + }; + + i2s0-8ch-sclktx { + rockchip,pins = <0x03 0x13 0x02 0xb1>; + phandle = <0x30>; + }; + + i2s0-8ch-sclkrx { + rockchip,pins = <0x03 0x0c 0x02 0xb1>; + phandle = <0x31>; + }; + + i2s0-8ch-lrcktx { + rockchip,pins = <0x03 0x12 0x02 0xb1>; + phandle = <0x32>; + }; + + i2s0-8ch-lrckrx { + rockchip,pins = <0x03 0x0d 0x02 0xb1>; + phandle = <0x33>; + }; + + i2s0-8ch-sdo0 { + rockchip,pins = <0x03 0x14 0x02 0xb1>; + phandle = <0x38>; + }; + + i2s0-8ch-sdo1 { + rockchip,pins = <0x03 0x10 0x02 0xb1>; + phandle = <0x39>; + }; + + i2s0-8ch-sdo2 { + rockchip,pins = <0x03 0x0f 0x02 0xb1>; + phandle = <0x3a>; + }; + + i2s0-8ch-sdo3 { + rockchip,pins = <0x03 0x0e 0x02 0xb1>; + phandle = <0x3b>; + }; + + i2s0-8ch-sdi0 { + rockchip,pins = <0x03 0x15 0x02 0xb1>; + phandle = <0x34>; + }; + + i2s0-8ch-sdi1 { + rockchip,pins = <0x03 0x0b 0x02 0xb1>; + phandle = <0x35>; + }; + + i2s0-8ch-sdi2 { + rockchip,pins = <0x03 0x09 0x02 0xb1>; + phandle = <0x36>; + }; + + i2s0-8ch-sdi3 { + rockchip,pins = <0x03 0x08 0x02 0xb1>; + phandle = <0x37>; + }; + }; + + i2s1 { + + i2s1-2ch-mclk { + rockchip,pins = <0x02 0x13 0x01 0xb1>; + phandle = <0x68>; + }; + + i2s1-2ch-sclk { + rockchip,pins = <0x02 0x12 0x01 0xb1>; + phandle = <0x3c>; + }; + + i2s1-2ch-lrck { + rockchip,pins = <0x02 0x11 0x01 0xb1>; + phandle = <0x3d>; + }; + + i2s1-2ch-sdi { + rockchip,pins = <0x02 0x15 0x01 0xb1>; + phandle = <0x3e>; + }; + + i2s1-2ch-sdo { + rockchip,pins = <0x02 0x14 0x01 0xb1>; + phandle = <0x3f>; + }; + }; + + i2s2 { + + i2s2-2ch-mclk { + rockchip,pins = <0x03 0x01 0x02 0xb1>; + phandle = <0x132>; + }; + + i2s2-2ch-sclk { + rockchip,pins = <0x03 0x02 0x02 0xb1>; + phandle = <0x40>; + }; + + i2s2-2ch-lrck { + rockchip,pins = <0x03 0x03 0x02 0xb1>; + phandle = <0x41>; + }; + + i2s2-2ch-sdi { + rockchip,pins = <0x03 0x05 0x02 0xb1>; + phandle = <0x42>; + }; + + i2s2-2ch-sdo { + rockchip,pins = <0x03 0x07 0x02 0xb1>; + phandle = <0x43>; + }; + }; + + sdmmc { + + sdmmc-clk { + rockchip,pins = <0x01 0x1e 0x01 0xb6>; + phandle = <0x8f>; + }; + + sdmmc-cmd { + rockchip,pins = <0x01 0x1f 0x01 0xb4>; + phandle = <0x90>; + }; + + sdmmc-det { + rockchip,pins = <0x00 0x03 0x01 0xb4>; + phandle = <0x91>; + }; + + sdmmc-bus1 { + rockchip,pins = <0x01 0x1a 0x01 0xb4>; + phandle = <0x133>; + }; + + sdmmc-bus4 { + rockchip,pins = <0x01 0x1a 0x01 0xb4 0x01 0x1b 0x01 0xb4 0x01 0x1c 0x01 0xb4 0x01 0x1d 0x01 0xb4>; + phandle = <0x92>; + }; + + sdmmc-gpio { + rockchip,pins = <0x01 0x1a 0x00 0xb3 0x01 0x1b 0x00 0xb3 0x01 0x1c 0x00 0xb3 0x01 0x1d 0x00 0xb3 0x01 0x1e 0x00 0xb3 0x01 0x1f 0x00 0xb3>; + phandle = <0x134>; + }; + }; + + sdio { + + sdio-clk { + rockchip,pins = <0x01 0x15 0x01 0xb1>; + phandle = <0x96>; + }; + + sdio-cmd { + rockchip,pins = <0x01 0x14 0x01 0xb2>; + phandle = <0x95>; + }; + + sdio-bus4 { + rockchip,pins = <0x01 0x16 0x01 0xb2 0x01 0x17 0x01 0xb2 0x01 0x18 0x01 0xb2 0x01 0x19 0x01 0xb2>; + phandle = <0x94>; + }; + + sdio-gpio { + rockchip,pins = <0x01 0x16 0x00 0xb2 0x01 0x17 0x00 0xb2 0x01 0x18 0x00 0xb2 0x01 0x19 0x00 0xb2 0x01 0x14 0x00 0xb2 0x01 0x15 0x00 0xb2>; + phandle = <0x135>; + }; + }; + + emmc { + + emmc-clk { + rockchip,pins = <0x01 0x09 0x02 0xb6>; + phandle = <0x136>; + }; + + emmc-cmd { + rockchip,pins = <0x01 0x0a 0x02 0xb4>; + phandle = <0x137>; + }; + + emmc-pwren { + rockchip,pins = <0x01 0x08 0x02 0xb1>; + phandle = <0x138>; + }; + + emmc-rstnout { + rockchip,pins = <0x01 0x0b 0x02 0xb1>; + phandle = <0x139>; + }; + + emmc-bus1 { + rockchip,pins = <0x01 0x00 0x02 0xb4>; + phandle = <0x13a>; + }; + + emmc-bus4 { + rockchip,pins = <0x01 0x00 0x02 0xb4 0x01 0x01 0x02 0xb4 0x01 0x02 0x02 0xb4 0x01 0x03 0x02 0xb4>; + phandle = <0x13b>; + }; + + emmc-bus8 { + rockchip,pins = <0x01 0x00 0x02 0xb4 0x01 0x01 0x02 0xb4 0x01 0x02 0x02 0xb4 0x01 0x03 0x02 0xb4 0x01 0x04 0x02 0xb4 0x01 0x05 0x02 0xb4 0x01 0x06 0x02 0xb4 0x01 0x07 0x02 0xb4>; + phandle = <0x13c>; + }; + }; + + flash { + + flash-cs0 { + rockchip,pins = <0x01 0x08 0x01 0xb1>; + phandle = <0x13d>; + }; + + flash-rdy { + rockchip,pins = <0x01 0x09 0x01 0xb1>; + phandle = <0x13e>; + }; + + flash-dqs { + rockchip,pins = <0x01 0x0a 0x01 0xb1>; + phandle = <0x13f>; + }; + + flash-ale { + rockchip,pins = <0x01 0x0b 0x01 0xb1>; + phandle = <0x140>; + }; + + flash-cle { + rockchip,pins = <0x01 0x0c 0x01 0xb1>; + phandle = <0x141>; + }; + + flash-wrn { + rockchip,pins = <0x01 0x0d 0x01 0xb1>; + phandle = <0x142>; + }; + + flash-csl { + rockchip,pins = <0x01 0x0e 0x01 0xb1>; + phandle = <0x143>; + }; + + flash-rdn { + rockchip,pins = <0x01 0x0f 0x01 0xb1>; + phandle = <0x144>; + }; + + flash-bus8 { + rockchip,pins = <0x01 0x00 0x01 0xb7 0x01 0x01 0x01 0xb7 0x01 0x02 0x01 0xb7 0x01 0x03 0x01 0xb7 0x01 0x04 0x01 0xb7 0x01 0x05 0x01 0xb7 0x01 0x06 0x01 0xb7 0x01 0x07 0x01 0xb7>; + phandle = <0x145>; + }; + }; + + lcdc { + + lcdc-m0-rgb-pins { + rockchip,pins = <0x03 0x00 0x01 0xb6 0x03 0x01 0x01 0xb6 0x03 0x02 0x01 0xb6 0x03 0x03 0x01 0xb6 0x03 0x04 0x01 0xb6 0x03 0x05 0x01 0xb6 0x03 0x06 0x01 0xb6 0x03 0x07 0x01 0xb6 0x03 0x08 0x01 0xb6 0x03 0x09 0x01 0xb6 0x03 0x0a 0x01 0xb6 0x03 0x0b 0x01 0xb6 0x03 0x0c 0x01 0xb6 0x03 0x0d 0x01 0xb6 0x03 0x0e 0x01 0xb6 0x03 0x0f 0x01 0xb6 0x03 0x10 0x01 0xb6 0x03 0x11 0x01 0xb6 0x03 0x12 0x01 0xb6 0x03 0x13 0x01 0xb6 0x03 0x14 0x01 0xb6 0x03 0x15 0x01 0xb6 0x03 0x16 0x01 0xb6 0x03 0x17 0x01 0xb6 0x03 0x18 0x01 0xb6 0x03 0x19 0x01 0xb6 0x03 0x1a 0x01 0xb6 0x03 0x1b 0x01 0xb6>; + phandle = <0x146>; + }; + + lcdc-m0-sleep-pins { + rockchip,pins = <0x03 0x00 0x00 0xb1 0x03 0x01 0x00 0xb1 0x03 0x02 0x00 0xb1 0x03 0x03 0x00 0xb1 0x03 0x04 0x00 0xb1 0x03 0x05 0x00 0xb1 0x03 0x06 0x00 0xb1 0x03 0x07 0x00 0xb1 0x03 0x08 0x00 0xb1 0x03 0x09 0x00 0xb1 0x03 0x0a 0x00 0xb1 0x03 0x0b 0x00 0xb1 0x03 0x0c 0x00 0xb1 0x03 0x0d 0x00 0xb1 0x03 0x0e 0x00 0xb1 0x03 0x0f 0x00 0xb1 0x03 0x10 0x00 0xb1 0x03 0x11 0x00 0xb1 0x03 0x12 0x00 0xb1 0x03 0x13 0x00 0xb1 0x03 0x14 0x00 0xb1 0x03 0x15 0x00 0xb1 0x03 0x16 0x00 0xb1 0x03 0x17 0x00 0xb1 0x03 0x18 0x00 0xb1 0x03 0x19 0x00 0xb1 0x03 0x1a 0x00 0xb1 0x03 0x1b 0x00 0xb1>; + phandle = <0x147>; + }; + + lcdc-m1-rgb-pins { + rockchip,pins = <0x03 0x00 0x01 0xb6 0x03 0x04 0x01 0xb6 0x03 0x06 0x01 0xb6 0x03 0x0a 0x01 0xb6 0x03 0x0b 0x01 0xb6 0x03 0x0d 0x01 0xb6 0x03 0x10 0x01 0xb6 0x03 0x11 0x01 0xb6 0x03 0x12 0x01 0xb6 0x03 0x13 0x01 0xb6 0x03 0x14 0x01 0xb6 0x03 0x15 0x01 0xb6 0x03 0x16 0x01 0xb6 0x03 0x17 0x01 0xb6 0x03 0x18 0x01 0xb6 0x03 0x19 0x01 0xb6 0x03 0x1a 0x01 0xb6 0x03 0x1b 0x01 0xb6>; + phandle = <0x4d>; + }; + + lcdc-m1-sleep-pins { + rockchip,pins = <0x03 0x00 0x00 0xb1 0x03 0x04 0x00 0xb1 0x03 0x06 0x00 0xb1 0x03 0x0a 0x00 0xb1 0x03 0x0b 0x00 0xb1 0x03 0x0d 0x00 0xb1 0x03 0x10 0x00 0xb1 0x03 0x11 0x00 0xb1 0x03 0x12 0x00 0xb1 0x03 0x13 0x00 0xb1 0x03 0x14 0x00 0xb1 0x03 0x15 0x00 0xb1 0x03 0x16 0x00 0xb1 0x03 0x17 0x00 0xb1 0x03 0x18 0x00 0xb1 0x03 0x19 0x00 0xb1 0x03 0x1a 0x00 0xb1 0x03 0x1b 0x00 0xb1>; + phandle = <0x4e>; + }; + }; + + pwm0 { + + pwm0-pin { + rockchip,pins = <0x00 0x0f 0x01 0xb1>; + phandle = <0x7b>; + }; + }; + + pwm1 { + + pwm1-pin { + rockchip,pins = <0x00 0x10 0x01 0xb1>; + phandle = <0x7c>; + }; + }; + + pwm2 { + + pwm2-pin { + rockchip,pins = <0x02 0x0d 0x01 0xb1>; + phandle = <0x7d>; + }; + }; + + pwm3 { + + pwm3-pin { + rockchip,pins = <0x00 0x11 0x01 0xb1>; + phandle = <0x7e>; + }; + }; + + pwm4 { + + pwm4-pin { + rockchip,pins = <0x03 0x12 0x03 0xb1>; + phandle = <0x7f>; + }; + }; + + pwm5 { + + pwm5-pin { + rockchip,pins = <0x03 0x13 0x03 0xb1>; + phandle = <0x80>; + }; + }; + + pwm6 { + + pwm6-pin { + rockchip,pins = <0x03 0x14 0x03 0xb1>; + phandle = <0x81>; + }; + }; + + pwm7 { + + pwm7-pin { + rockchip,pins = <0x03 0x15 0x03 0xb1>; + phandle = <0x82>; + }; + }; + + gmac { + + rmii-pins { + rockchip,pins = <0x02 0x00 0x02 0xb8 0x02 0x01 0x02 0xb8 0x02 0x02 0x02 0xb8 0x02 0x03 0x02 0xb1 0x02 0x04 0x02 0xb1 0x02 0x05 0x02 0xb1 0x02 0x06 0x02 0xb1 0x02 0x07 0x02 0xb1 0x02 0x09 0x02 0xb1>; + phandle = <0x8d>; + }; + + mac-refclk-12ma { + rockchip,pins = <0x02 0x0a 0x02 0xb8>; + phandle = <0x8e>; + }; + + mac-refclk { + rockchip,pins = <0x02 0x0a 0x02 0xb1>; + phandle = <0x148>; + }; + }; + + cif-m0 { + + cif-clkout-m0 { + rockchip,pins = <0x02 0x0b 0x01 0xb8>; + phandle = <0xa7>; + }; + + dvp-d2d9-m0 { + rockchip,pins = <0x02 0x00 0x01 0xb1 0x02 0x01 0x01 0xb1 0x02 0x02 0x01 0xb1 0x02 0x03 0x01 0xb1 0x02 0x04 0x01 0xb1 0x02 0x05 0x01 0xb1 0x02 0x06 0x01 0xb1 0x02 0x07 0x01 0xb1 0x02 0x08 0x01 0xb1 0x02 0x09 0x01 0xb1 0x02 0x0a 0x01 0xb1 0x02 0x0b 0x01 0xb1>; + phandle = <0xa5>; + }; + + dvp-d0d1-m0 { + rockchip,pins = <0x02 0x0c 0x01 0xb1 0x02 0x0e 0x01 0xb1>; + phandle = <0xa9>; + }; + + d10-d11-m0 { + rockchip,pins = <0x02 0x0f 0x01 0xb1 0x02 0x10 0x01 0xb1>; + phandle = <0xa8>; + }; + }; + + cif-m1 { + + cif-clkout-m1 { + rockchip,pins = <0x03 0x18 0x03 0xb1>; + phandle = <0x149>; + }; + + dvp-d2d9-m1 { + rockchip,pins = <0x03 0x03 0x03 0xb1 0x03 0x05 0x03 0xb1 0x03 0x07 0x03 0xb1 0x03 0x08 0x03 0xb1 0x03 0x09 0x03 0xb1 0x03 0x0c 0x03 0xb1 0x03 0x0e 0x03 0xb1 0x03 0x0f 0x03 0xb1 0x03 0x19 0x03 0xb1 0x03 0x1a 0x03 0xb1 0x03 0x1b 0x03 0xb1 0x03 0x18 0x03 0xb1>; + phandle = <0x14a>; + }; + + dvp-d0d1-m1 { + rockchip,pins = <0x03 0x01 0x03 0xb1 0x03 0x02 0x03 0xb1>; + phandle = <0x14b>; + }; + + d10-d11-m1 { + rockchip,pins = <0x03 0x16 0x03 0xb1 0x03 0x17 0x03 0xb1>; + phandle = <0x14c>; + }; + }; + + isp { + + isp-prelight { + rockchip,pins = <0x03 0x19 0x04 0xb1>; + phandle = <0x14d>; + }; + }; + + pmic { + + pmic_int { + rockchip,pins = <0x00 0x0a 0x00 0xb2 0x00 0x0b 0x00 0xb1>; + phandle = <0x5d>; + }; + + soc_slppin_gpio { + rockchip,pins = <0x00 0x04 0x00 0xb9>; + phandle = <0x60>; + }; + + soc_slppin_slp { + rockchip,pins = <0x00 0x04 0x01 0xb1>; + phandle = <0x5e>; + }; + + soc_slppin_rst { + rockchip,pins = <0x00 0x04 0x02 0xb1>; + phandle = <0x62>; + }; + }; + + leds { + + led-pins { + rockchip,pins = <0x00 0x11 0x00 0xb1>; + phandle = <0xc0>; + }; + }; + + btns { + + btn-pins { + rockchip,pins = <0x01 0x0c 0x00 0xb2 0x01 0x0d 0x00 0xb2 0x01 0x0e 0x00 0xb2 0x01 0x0f 0x00 0xb2 0x01 0x02 0x00 0xb2 0x01 0x05 0x00 0xb2 0x01 0x06 0x00 0xb2 0x01 0x07 0x00 0xb2 0x02 0x00 0x00 0xb2 0x02 0x01 0x00 0xb2 0x02 0x02 0x00 0xb2 0x02 0x03 0x00 0xb2 0x02 0x04 0x00 0xb2 0x02 0x05 0x00 0xb2 0x02 0x06 0x00 0xb2 0x02 0x07 0x00 0xb2 0x03 0x09 0x00 0xb2 0x03 0x0a 0x00 0xb2 0x03 0x0c 0x00 0xb2 0x03 0x0f 0x00 0xb2>; + phandle = <0xbd>; + }; + }; + }; + + chosen { + bootargs = [00]; + }; + + fiq-debugger { + compatible = "rockchip,fiq-debugger"; + rockchip,serial-id = <0x02>; + rockchip,wake-irq = <0x00>; + rockchip,irq-mode-enable = <0x00>; + rockchip,baudrate = <0x1c200>; + interrupts = <0x00 0x7f 0x08>; + pinctrl-names = "default"; + pinctrl-0 = <0xba>; + status = "okay"; + }; + + ramoops { + compatible = "ramoops"; + record-size = <0x00 0x20000>; + console-size = <0x00 0x80000>; + ftrace-size = <0x00 0x00>; + pmsg-size = <0x00 0x00>; + memory-region = <0xbb>; + }; + + reserved-memory { + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + + drm-logo@00000000 { + compatible = "rockchip,drm-logo"; + reg = <0x00 0x00 0x00 0x00>; + phandle = <0x11>; + }; + + region@110000 { + reg = <0x00 0x110000 0x00 0xf0000>; + reg-names = "ramoops_mem"; + phandle = <0xbb>; + }; + }; + + odroidgo3-keys { + compatible = "gpio-keys"; + #address-cells = <0x01>; + #size-cells = <0x00>; + autorepeat; + phandle = <0x14e>; + + button@0 { + label = "GPIO BTN-VOLUP"; + linux,code = <0x73>; + gpios = <0x66 0x00 0x01>; + }; + + button@1 { + label = "GPIO BTN-VOLDN"; + linux,code = <0x72>; + gpios = <0x66 0x01 0x01>; + }; + }; + + odroidgo3-joypad { + compatible = "odroidgo3-joypad"; + pwms = <0xbc 0x00 0xbebc200 0x00>; + pwm-names = "enable"; + rumble-boost-weak = <0x00>; + rumble-boost-strong = <0x00>; + joypad-name = "GO-Super Gamepad"; + joypad-product = <0x1100>; + joypad-revision = <0x100>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <0xbd>; + pinctrl-1 = <0x7b>; + io-channel-names = "amux_adc"; + io-channels = <0xbe 0x01>; + amux-count = <0x04>; + amux-a-gpios = <0x97 0x0b 0x01>; + amux-b-gpios = <0x97 0x08 0x01>; + amux-en-gpios = <0x97 0x0d 0x01>; + button-adc-scale = <0x02>; + button-adc-deadzone = <0x40>; + button-adc-fuzz = <0x20>; + button-adc-flat = <0x20>; + abs_x-p-tuning = <0xc8>; + abs_x-n-tuning = <0xc8>; + abs_y-p-tuning = <0xc8>; + abs_y-n-tuning = <0xc8>; + abs_rx-p-tuning = <0xc8>; + abs_rx-n-tuning = <0xc8>; + abs_ry-p-tuning = <0xc8>; + abs_ry-n-tuning = <0xc8>; + poll-interval = <0x0a>; + invert-absx; + invert-absy; + phandle = <0x14f>; + + sw1 { + gpios = <0xbf 0x0c 0x01>; + label = "GPIO DPAD-UP"; + linux,code = <0x220>; + }; + + sw2 { + gpios = <0xbf 0x0d 0x01>; + label = "GPIO DPAD-DOWN"; + linux,code = <0x221>; + }; + + sw3 { + gpios = <0xbf 0x0e 0x01>; + label = "GPIO DPAD-LEFT"; + linux,code = <0x222>; + }; + + sw4 { + gpios = <0xbf 0x0f 0x01>; + label = "GPIO DPAD-RIGHT"; + linux,code = <0x223>; + }; + + sw5 { + gpios = <0xbf 0x02 0x01>; + label = "GPIO KEY BTN-A"; + linux,code = <0x131>; + }; + + sw6 { + gpios = <0xbf 0x05 0x01>; + label = "GPIO BTN-B"; + linux,code = <0x130>; + }; + + sw7 { + gpios = <0xbf 0x06 0x01>; + label = "GPIO BTN-Y"; + linux,code = <0x134>; + }; + + sw8 { + gpios = <0xbf 0x07 0x01>; + label = "GPIO BTN-X"; + linux,code = <0x133>; + }; + + sw11 { + gpios = <0x66 0x02 0x01>; + label = "GPIO F3"; + linux,code = <0x2c2>; + }; + + sw12 { + gpios = <0x66 0x03 0x01>; + label = "GPIO F4"; + linux,code = <0x2c3>; + }; + + sw13 { + gpios = <0x66 0x04 0x01>; + label = "GPIO F5"; + linux,code = <0x2c4>; + }; + + sw15 { + gpios = <0x66 0x06 0x01>; + label = "GPIO TOP-LEFT"; + linux,code = <0x136>; + }; + + sw16 { + gpios = <0x66 0x07 0x01>; + label = "GPIO TOP-RIGHT"; + linux,code = <0x137>; + }; + + sw19 { + gpios = <0x97 0x09 0x01>; + label = "GPIO F1"; + linux,code = <0x2c0>; + }; + + sw20 { + gpios = <0x97 0x0f 0x01>; + label = "GPIO TOP-RIGHT2"; + linux,code = <0x139>; + }; + + sw21 { + gpios = <0x97 0x0a 0x01>; + label = "GPIO TOP-LEFT2"; + linux,code = <0x138>; + }; + + sw22 { + gpios = <0x97 0x0c 0x01>; + label = "GPIO F2"; + linux,code = <0x2c1>; + }; + }; + + gpio_leds { + compatible = "gpio-leds"; + pinctrl-names = "led_pins"; + pinctrl-0 = <0xc0>; + phandle = <0x150>; + + heartbeat { + label = "blue:heartbeat"; + gpios = <0x5c 0x11 0x00>; + linux,default-trigger = "heartbeat"; + }; + }; + + backlight { + compatible = "pwm-backlight"; + pwms = <0xc1 0x00 0x9c40 0x00>; + brightness-levels = <0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2a 0x2b 0x2c 0x2d 0x2e 0x2f 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x3a 0x3b 0x3c 0x3d 0x3e 0x3f 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48 0x49 0x4a 0x4b 0x4c 0x4d 0x4e 0x4f 0x50 0x51 0x52 0x53 0x54 0x55 0x56 0x57 0x58 0x59 0x5a 0x5b 0x5c 0x5d 0x5e 0x5f 0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69 0x6a 0x6b 0x6c 0x6d 0x6e 0x6f 0x70 0x71 0x72 0x73 0x74 0x75 0x76 0x77 0x78 0x79 0x7a 0x7b 0x7c 0x7d 0x7e 0x7f 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90 0x91 0x92 0x93 0x94 0x95 0x96 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f 0xa0>; + default-brightness-level = <0x50>; + phandle = <0x9d>; + }; + + rk817-sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,name = "rockchip,rk817-codec"; + simple-audio-card,mclk-fs = <0x100>; + simple-audio-card,widgets = "Microphone\0Mic Jack\0Headphone\0Headphone Jack"; + simple-audio-card,routing = "MIC_IN\0Mic Jack\0Headphone Jack\0HPOL\0Headphone Jack\0HPOR"; + simple-audio-card,hp-det-gpio = <0x66 0x16 0x01>; + simple-audio-card,codec-hp-det = <0x01>; + + simple-audio-card,cpu { + sound-dai = <0xc2>; + }; + + simple-audio-card,codec { + sound-dai = <0xc3>; + }; + }; + + vccsys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v8_sys"; + regulator-always-on; + regulator-min-microvolt = <0x39fbc0>; + regulator-max-microvolt = <0x39fbc0>; + phandle = <0x64>; + }; + + __symbols__ { + ddr_timing = "/ddr_timing"; + cpu0 = "/cpus/cpu@0"; + cpu1 = "/cpus/cpu@1"; + cpu2 = "/cpus/cpu@2"; + cpu3 = "/cpus/cpu@3"; + CPU_SLEEP = "/cpus/idle-states/cpu-sleep"; + CLUSTER_SLEEP = "/cpus/idle-states/cluster-sleep"; + cpu0_opp_table = "/cpu0-opp-table"; + bus_soc = "/bus-soc"; + bus_apll = "/bus-apll"; + bus_apll_opp_table = "/bus-apll-opp-table"; + display_subsystem = "/display-subsystem"; + route_lvds = "/display-subsystem/route/route-lvds"; + route_dsi = "/display-subsystem/route/route-dsi"; + route_rgb = "/display-subsystem/route/route-rgb"; + gmac_clkin = "/external-gmac-clock"; + rockchip_suspend = "/rockchip-suspend"; + xin24m = "/xin24m"; + xin32k = "/xin32k"; + pmu = "/power-management@ff000000"; + power = "/power-management@ff000000/power-controller"; + pmugrf = "/syscon@ff010000"; + pmu_io_domains = "/syscon@ff010000/io-domains"; + pmu_pvtm = "/syscon@ff010000/pmu-pvtm"; + uart0 = "/serial@ff030000"; + i2s0_8ch = "/i2s@ff060000"; + i2s1_2ch = "/i2s@ff070000"; + i2s2_2ch = "/i2s@ff080000"; + pdm = "/pdm@ff0a0000"; + crypto = "/crypto@ff0b0000"; + rng = "/rng@ff0b0000"; + gic = "/interrupt-controller@ff131000"; + grf = "/syscon@ff140000"; + io_domains = "/syscon@ff140000/io-domains"; + lvds = "/syscon@ff140000/lvds"; + lvds_in_vopb = "/syscon@ff140000/lvds/ports/port@0/endpoint@0"; + rgb = "/syscon@ff140000/rgb"; + rgb_in_vopb = "/syscon@ff140000/rgb/ports/port@0/endpoint@0"; + core_grf = "/syscon@ff148000"; + pvtm = "/syscon@ff148000/pvtm"; + uart1 = "/serial@ff158000"; + uart2 = "/serial@ff160000"; + uart3 = "/serial@ff168000"; + uart4 = "/serial@ff170000"; + uart5 = "/serial@ff178000"; + i2c0 = "/i2c@ff180000"; + rk817 = "/i2c@ff180000/pmic@20"; + pinctrl_rk8xx = "/i2c@ff180000/pmic@20/pinctrl_rk8xx"; + rk817_ts_gpio1 = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_ts_gpio1"; + rk817_gt_gpio2 = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_gt_gpio2"; + rk817_pin_ts = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_pin_ts"; + rk817_pin_gt = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_pin_gt"; + rk817_slppin_null = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_null"; + rk817_slppin_slp = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_slp"; + rk817_slppin_pwrdn = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_pwrdn"; + rk817_slppin_rst = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_rst"; + vdd_logic = "/i2c@ff180000/pmic@20/regulators/DCDC_REG1"; + vdd_arm = "/i2c@ff180000/pmic@20/regulators/DCDC_REG2"; + vcc_ddr = "/i2c@ff180000/pmic@20/regulators/DCDC_REG3"; + vcc_3v3 = "/i2c@ff180000/pmic@20/regulators/DCDC_REG4"; + vcc_1v0 = "/i2c@ff180000/pmic@20/regulators/LDO_REG1"; + vcc1v8_soc = "/i2c@ff180000/pmic@20/regulators/LDO_REG2"; + vdd1v0_soc = "/i2c@ff180000/pmic@20/regulators/LDO_REG3"; + vcc3v3_pmu = "/i2c@ff180000/pmic@20/regulators/LDO_REG4"; + vccio_sd = "/i2c@ff180000/pmic@20/regulators/LDO_REG5"; + vcc_sd = "/i2c@ff180000/pmic@20/regulators/LDO_REG6"; + vcc_backlight = "/i2c@ff180000/pmic@20/regulators/LDO_REG7"; + vcc_lcd = "/i2c@ff180000/pmic@20/regulators/LDO_REG8"; + dcdc_boost = "/i2c@ff180000/pmic@20/regulators/BOOST"; + otg_switch = "/i2c@ff180000/pmic@20/regulators/OTG_SWITCH"; + rk817_codec = "/i2c@ff180000/pmic@20/codec"; + i2c1 = "/i2c@ff190000"; + i2c2 = "/i2c@ff1a0000"; + i2c3 = "/i2c@ff1b0000"; + spi0 = "/spi@ff1d0000"; + spi1 = "/spi@ff1d8000"; + wdt = "/watchdog@ff1e0000"; + pwm0 = "/pwm@ff200000"; + pwm1 = "/pwm@ff200010"; + pwm2 = "/pwm@ff200020"; + pwm3 = "/pwm@ff200030"; + pwm4 = "/pwm@ff208000"; + pwm5 = "/pwm@ff208010"; + pwm6 = "/pwm@ff208020"; + pwm7 = "/pwm@ff208030"; + rktimer = "/rktimer@ff210000"; + dmac = "/amba/dmac@ff240000"; + thermal_zones = "/thermal-zones"; + soc_thermal = "/thermal-zones/soc-thermal"; + threshold = "/thermal-zones/soc-thermal/trips/trip-point-0"; + target = "/thermal-zones/soc-thermal/trips/trip-point-1"; + soc_crit = "/thermal-zones/soc-thermal/trips/soc-crit"; + gpu_thermal = "/thermal-zones/gpu-thermal"; + tsadc = "/tsadc@ff280000"; + saradc = "/saradc@ff288000"; + otp = "/otp@ff290000"; + otp_id = "/otp@ff290000/id@7"; + cpu_leakage = "/otp@ff290000/cpu-leakage@17"; + performance = "/otp@ff290000/performance@1e"; + cru = "/clock-controller@ff2b0000"; + cpu_boost = "/cpu-boost@ff2b8000"; + pmucru = "/pmu-clock-controller@ff2bc000"; + usb2phy_grf = "/syscon@ff2c0000"; + u2phy = "/syscon@ff2c0000/usb2-phy@100"; + u2phy_host = "/syscon@ff2c0000/usb2-phy@100/host-port"; + u2phy_otg = "/syscon@ff2c0000/usb2-phy@100/otg-port"; + video_phy = "/video-phy@ff2e0000"; + mipi_dphy_rx0 = "/mipi-dphy-rx0@ff2f0000"; + usb20_otg = "/usb@ff300000"; + usb_host0_ehci = "/usb@ff340000"; + usb_host0_ohci = "/usb@ff350000"; + gmac = "/ethernet@ff360000"; + sdmmc = "/dwmmc@ff370000"; + sdio = "/dwmmc@ff380000"; + emmc = "/dwmmc@ff390000"; + nandc0 = "/nandc@ff3b0000"; + sfc = "/sfc@ff3a0000"; + gpu = "/gpu@ff400000"; + gpu_opp_table = "/gpu-opp-table"; + hevc = "/hevc_service@ff440000"; + vpu = "/vpu_service@ff442000"; + vpu_combo = "/vpu_combo"; + hevc_mmu = "/iommu@ff440440"; + vpu_mmu = "/iommu@ff442800"; + dsi = "/dsi@ff450000"; + dsi_in_vopb = "/dsi@ff450000/ports/port@0/endpoint@0"; + timing0 = "/dsi@ff450000/panel@0/display-timings/60Hz"; + timing1 = "/dsi@ff450000/panel@0/display-timings/50Hz"; + timing2 = "/dsi@ff450000/panel@0/display-timings/75Hz"; + vopb = "/vop@ff460000"; + vopb_out = "/vop@ff460000/port"; + vopb_out_lvds = "/vop@ff460000/port/endpoint@0"; + vopb_out_dsi = "/vop@ff460000/port/endpoint@1"; + vopb_out_rgb = "/vop@ff460000/port/endpoint@2"; + vopb_mmu = "/iommu@ff460f00"; + rk_rga = "/rk_rga@ff480000"; + cif = "/cif@ff490000"; + cif_new = "/cif-new@ff490000"; + vip_mmu = "/iommu@ff490800"; + rk_isp = "/rk_isp@ff4a0000"; + rkisp1 = "/rkisp1@ff4a0000"; + isp_mmu = "/iommu@ff4a8000"; + qos_gmac = "/qos@ff518000"; + qos_gpu = "/qos@ff520000"; + qos_sdmmc = "/qos@ff52c000"; + qos_emmc = "/qos@ff538000"; + qos_nand = "/qos@ff538080"; + qos_sdio = "/qos@ff538100"; + qos_sfc = "/qos@ff538180"; + qos_usb_host = "/qos@ff540000"; + qos_usb_otg = "/qos@ff540080"; + qos_isp_128 = "/qos@ff548000"; + qos_isp_rd = "/qos@ff548080"; + qos_isp_wr = "/qos@ff548100"; + qos_isp_m1 = "/qos@ff548180"; + qos_vip = "/qos@ff548200"; + qos_rga_rd = "/qos@ff550000"; + qos_rga_wr = "/qos@ff550080"; + qos_vop_m0 = "/qos@ff550100"; + qos_vop_m1 = "/qos@ff550180"; + qos_vpu = "/qos@ff558000"; + qos_vpu_r128 = "/qos@ff558080"; + dfi = "/dfi@ff610000"; + dmc = "/dmc"; + ddr_power_model = "/dmc/ddr_power_model"; + dmc_opp_table = "/dmc-opp-table"; + rockchip_system_monitor = "/rockchip-system-monitor"; + pinctrl = "/pinctrl"; + gpio0 = "/pinctrl/gpio0@ff040000"; + gpio1 = "/pinctrl/gpio1@ff250000"; + gpio2 = "/pinctrl/gpio2@ff260000"; + gpio3 = "/pinctrl/gpio3@ff270000"; + pcfg_pull_up = "/pinctrl/pcfg-pull-up"; + pcfg_pull_down = "/pinctrl/pcfg-pull-down"; + pcfg_pull_none = "/pinctrl/pcfg-pull-none"; + pcfg_pull_none_2ma = "/pinctrl/pcfg-pull-none-2ma"; + pcfg_pull_up_2ma = "/pinctrl/pcfg-pull-up-2ma"; + pcfg_pull_up_4ma = "/pinctrl/pcfg-pull-up-4ma"; + pcfg_pull_none_4ma = "/pinctrl/pcfg-pull-none-4ma"; + pcfg_pull_down_4ma = "/pinctrl/pcfg-pull-down-4ma"; + pcfg_pull_none_8ma = "/pinctrl/pcfg-pull-none-8ma"; + pcfg_pull_up_8ma = "/pinctrl/pcfg-pull-up-8ma"; + pcfg_pull_none_12ma = "/pinctrl/pcfg-pull-none-12ma"; + pcfg_pull_up_12ma = "/pinctrl/pcfg-pull-up-12ma"; + pcfg_pull_none_smt = "/pinctrl/pcfg-pull-none-smt"; + pcfg_output_high = "/pinctrl/pcfg-output-high"; + pcfg_output_low = "/pinctrl/pcfg-output-low"; + pcfg_input_high = "/pinctrl/pcfg-input-high"; + pcfg_input = "/pinctrl/pcfg-input"; + i2c0_xfer = "/pinctrl/i2c0/i2c0-xfer"; + i2c1_xfer = "/pinctrl/i2c1/i2c1-xfer"; + i2c2_xfer = "/pinctrl/i2c2/i2c2-xfer"; + i2c3_xfer = "/pinctrl/i2c3/i2c3-xfer"; + tsadc_otp_gpio = "/pinctrl/tsadc/tsadc-otp-gpio"; + tsadc_otp_out = "/pinctrl/tsadc/tsadc-otp-out"; + uart0_xfer = "/pinctrl/uart0/uart0-xfer"; + uart0_cts = "/pinctrl/uart0/uart0-cts"; + uart0_rts = "/pinctrl/uart0/uart0-rts"; + uart0_rts_gpio = "/pinctrl/uart0/uart0-rts-gpio"; + uart1_xfer = "/pinctrl/uart1/uart1-xfer"; + uart1_cts = "/pinctrl/uart1/uart1-cts"; + uart1_rts = "/pinctrl/uart1/uart1-rts"; + uart1_rts_gpio = "/pinctrl/uart1/uart1-rts-gpio"; + uart2m0_xfer = "/pinctrl/uart2-m0/uart2m0-xfer"; + uart2m1_xfer = "/pinctrl/uart2-m1/uart2m1-xfer"; + uart3m0_xfer = "/pinctrl/uart3-m0/uart3m0-xfer"; + uart3m0_cts = "/pinctrl/uart3-m0/uart3m0-cts"; + uart3m0_rts = "/pinctrl/uart3-m0/uart3m0-rts"; + uart3m0_rts_gpio = "/pinctrl/uart3-m0/uart3m0-rts-gpio"; + uart3m1_xfer = "/pinctrl/uart3-m1/uart3m1-xfer"; + uart3m1_cts = "/pinctrl/uart3-m1/uart3m1-cts"; + uart3m1_rts = "/pinctrl/uart3-m1/uart3m1-rts"; + uart3m1_rts_gpio = "/pinctrl/uart3-m1/uart3m1-rts-gpio"; + uart4_xfer = "/pinctrl/uart4/uart4-xfer"; + uart4_cts = "/pinctrl/uart4/uart4-cts"; + uart4_rts = "/pinctrl/uart4/uart4-rts"; + uart5_xfer = "/pinctrl/uart5/uart5-xfer"; + uart5_cts = "/pinctrl/uart5/uart5-cts"; + uart5_rts = "/pinctrl/uart5/uart5-rts"; + spi0_clk = "/pinctrl/spi0/spi0-clk"; + spi0_csn = "/pinctrl/spi0/spi0-csn"; + spi0_miso = "/pinctrl/spi0/spi0-miso"; + spi0_mosi = "/pinctrl/spi0/spi0-mosi"; + spi0_clk_hs = "/pinctrl/spi0/spi0-clk-hs"; + spi0_miso_hs = "/pinctrl/spi0/spi0-miso-hs"; + spi0_mosi_hs = "/pinctrl/spi0/spi0-mosi-hs"; + spi1_clk = "/pinctrl/spi1/spi1-clk"; + spi1_csn0 = "/pinctrl/spi1/spi1-csn0"; + spi1_csn1 = "/pinctrl/spi1/spi1-csn1"; + spi1_miso = "/pinctrl/spi1/spi1-miso"; + spi1_mosi = "/pinctrl/spi1/spi1-mosi"; + spi1_clk_hs = "/pinctrl/spi1/spi1-clk-hs"; + spi1_miso_hs = "/pinctrl/spi1/spi1-miso-hs"; + spi1_mosi_hs = "/pinctrl/spi1/spi1-mosi-hs"; + pdm_clk0m0 = "/pinctrl/pdm/pdm-clk0m0"; + pdm_clk0m1 = "/pinctrl/pdm/pdm-clk0m1"; + pdm_clk1 = "/pinctrl/pdm/pdm-clk1"; + pdm_sdi0m0 = "/pinctrl/pdm/pdm-sdi0m0"; + pdm_sdi0m1 = "/pinctrl/pdm/pdm-sdi0m1"; + pdm_sdi1 = "/pinctrl/pdm/pdm-sdi1"; + pdm_sdi2 = "/pinctrl/pdm/pdm-sdi2"; + pdm_sdi3 = "/pinctrl/pdm/pdm-sdi3"; + pdm_clk0m0_sleep = "/pinctrl/pdm/pdm-clk0m0-sleep"; + pdm_clk0m_sleep1 = "/pinctrl/pdm/pdm-clk0m1-sleep"; + pdm_clk1_sleep = "/pinctrl/pdm/pdm-clk1-sleep"; + pdm_sdi0m0_sleep = "/pinctrl/pdm/pdm-sdi0m0-sleep"; + pdm_sdi0m1_sleep = "/pinctrl/pdm/pdm-sdi0m1-sleep"; + pdm_sdi1_sleep = "/pinctrl/pdm/pdm-sdi1-sleep"; + pdm_sdi2_sleep = "/pinctrl/pdm/pdm-sdi2-sleep"; + pdm_sdi3_sleep = "/pinctrl/pdm/pdm-sdi3-sleep"; + i2s0_8ch_mclk = "/pinctrl/i2s0/i2s0-8ch-mclk"; + i2s0_8ch_sclktx = "/pinctrl/i2s0/i2s0-8ch-sclktx"; + i2s0_8ch_sclkrx = "/pinctrl/i2s0/i2s0-8ch-sclkrx"; + i2s0_8ch_lrcktx = "/pinctrl/i2s0/i2s0-8ch-lrcktx"; + i2s0_8ch_lrckrx = "/pinctrl/i2s0/i2s0-8ch-lrckrx"; + i2s0_8ch_sdo0 = "/pinctrl/i2s0/i2s0-8ch-sdo0"; + i2s0_8ch_sdo1 = "/pinctrl/i2s0/i2s0-8ch-sdo1"; + i2s0_8ch_sdo2 = "/pinctrl/i2s0/i2s0-8ch-sdo2"; + i2s0_8ch_sdo3 = "/pinctrl/i2s0/i2s0-8ch-sdo3"; + i2s0_8ch_sdi0 = "/pinctrl/i2s0/i2s0-8ch-sdi0"; + i2s0_8ch_sdi1 = "/pinctrl/i2s0/i2s0-8ch-sdi1"; + i2s0_8ch_sdi2 = "/pinctrl/i2s0/i2s0-8ch-sdi2"; + i2s0_8ch_sdi3 = "/pinctrl/i2s0/i2s0-8ch-sdi3"; + i2s1_2ch_mclk = "/pinctrl/i2s1/i2s1-2ch-mclk"; + i2s1_2ch_sclk = "/pinctrl/i2s1/i2s1-2ch-sclk"; + i2s1_2ch_lrck = "/pinctrl/i2s1/i2s1-2ch-lrck"; + i2s1_2ch_sdi = "/pinctrl/i2s1/i2s1-2ch-sdi"; + i2s1_2ch_sdo = "/pinctrl/i2s1/i2s1-2ch-sdo"; + i2s2_2ch_mclk = "/pinctrl/i2s2/i2s2-2ch-mclk"; + i2s2_2ch_sclk = "/pinctrl/i2s2/i2s2-2ch-sclk"; + i2s2_2ch_lrck = "/pinctrl/i2s2/i2s2-2ch-lrck"; + i2s2_2ch_sdi = "/pinctrl/i2s2/i2s2-2ch-sdi"; + i2s2_2ch_sdo = "/pinctrl/i2s2/i2s2-2ch-sdo"; + sdmmc_clk = "/pinctrl/sdmmc/sdmmc-clk"; + sdmmc_cmd = "/pinctrl/sdmmc/sdmmc-cmd"; + sdmmc_det = "/pinctrl/sdmmc/sdmmc-det"; + sdmmc_bus1 = "/pinctrl/sdmmc/sdmmc-bus1"; + sdmmc_bus4 = "/pinctrl/sdmmc/sdmmc-bus4"; + sdmmc_gpio = "/pinctrl/sdmmc/sdmmc-gpio"; + sdio_clk = "/pinctrl/sdio/sdio-clk"; + sdio_cmd = "/pinctrl/sdio/sdio-cmd"; + sdio_bus4 = "/pinctrl/sdio/sdio-bus4"; + sdio_gpio = "/pinctrl/sdio/sdio-gpio"; + emmc_clk = "/pinctrl/emmc/emmc-clk"; + emmc_cmd = "/pinctrl/emmc/emmc-cmd"; + emmc_pwren = "/pinctrl/emmc/emmc-pwren"; + emmc_rstnout = "/pinctrl/emmc/emmc-rstnout"; + emmc_bus1 = "/pinctrl/emmc/emmc-bus1"; + emmc_bus4 = "/pinctrl/emmc/emmc-bus4"; + emmc_bus8 = "/pinctrl/emmc/emmc-bus8"; + flash_cs0 = "/pinctrl/flash/flash-cs0"; + flash_rdy = "/pinctrl/flash/flash-rdy"; + flash_dqs = "/pinctrl/flash/flash-dqs"; + flash_ale = "/pinctrl/flash/flash-ale"; + flash_cle = "/pinctrl/flash/flash-cle"; + flash_wrn = "/pinctrl/flash/flash-wrn"; + flash_csl = "/pinctrl/flash/flash-csl"; + flash_rdn = "/pinctrl/flash/flash-rdn"; + flash_bus8 = "/pinctrl/flash/flash-bus8"; + lcdc_m0_rgb_pins = "/pinctrl/lcdc/lcdc-m0-rgb-pins"; + lcdc_m0_sleep_pins = "/pinctrl/lcdc/lcdc-m0-sleep-pins"; + lcdc_m1_rgb_pins = "/pinctrl/lcdc/lcdc-m1-rgb-pins"; + lcdc_m1_sleep_pins = "/pinctrl/lcdc/lcdc-m1-sleep-pins"; + pwm0_pin = "/pinctrl/pwm0/pwm0-pin"; + pwm1_pin = "/pinctrl/pwm1/pwm1-pin"; + pwm2_pin = "/pinctrl/pwm2/pwm2-pin"; + pwm3_pin = "/pinctrl/pwm3/pwm3-pin"; + pwm4_pin = "/pinctrl/pwm4/pwm4-pin"; + pwm5_pin = "/pinctrl/pwm5/pwm5-pin"; + pwm6_pin = "/pinctrl/pwm6/pwm6-pin"; + pwm7_pin = "/pinctrl/pwm7/pwm7-pin"; + rmii_pins = "/pinctrl/gmac/rmii-pins"; + mac_refclk_12ma = "/pinctrl/gmac/mac-refclk-12ma"; + mac_refclk = "/pinctrl/gmac/mac-refclk"; + cif_clkout_m0 = "/pinctrl/cif-m0/cif-clkout-m0"; + dvp_d2d9_m0 = "/pinctrl/cif-m0/dvp-d2d9-m0"; + dvp_d0d1_m0 = "/pinctrl/cif-m0/dvp-d0d1-m0"; + dvp_d10d11_m0 = "/pinctrl/cif-m0/d10-d11-m0"; + cif_clkout_m1 = "/pinctrl/cif-m1/cif-clkout-m1"; + dvp_d2d9_m1 = "/pinctrl/cif-m1/dvp-d2d9-m1"; + dvp_d0d1_m1 = "/pinctrl/cif-m1/dvp-d0d1-m1"; + dvp_d10d11_m1 = "/pinctrl/cif-m1/d10-d11-m1"; + isp_prelight = "/pinctrl/isp/isp-prelight"; + pmic_int = "/pinctrl/pmic/pmic_int"; + soc_slppin_gpio = "/pinctrl/pmic/soc_slppin_gpio"; + soc_slppin_slp = "/pinctrl/pmic/soc_slppin_slp"; + soc_slppin_rst = "/pinctrl/pmic/soc_slppin_rst"; + led_pins = "/pinctrl/leds/led-pins"; + btn_pins = "/pinctrl/btns/btn-pins"; + drm_logo = "/reserved-memory/drm-logo@00000000"; + ramoops_mem = "/reserved-memory/region@110000"; + gpio_keys = "/odroidgo3-keys"; + joypad = "/odroidgo3-joypad"; + leds = "/gpio_leds"; + backlight = "/backlight"; + vccsys = "/vccsys"; + }; +}; diff --git a/config/archr-dts/R36S-DTB/DTS/R46H.dts b/config/archr-dts/R36S-DTB/DTS/R46H.dts new file mode 100644 index 0000000000..3a6b53fc42 --- /dev/null +++ b/config/archr-dts/R36S-DTB/DTS/R46H.dts @@ -0,0 +1,4038 @@ +/dts-v1/; + +/ { + compatible = "rockchip,rk3326-odroidgo3-linux\0rockchip,rk3326"; + interrupt-parent = <0x01>; + #address-cells = <0x02>; + #size-cells = <0x02>; + model = "Hardkernel ODROID-GO3"; + + ddr_timing { + compatible = "rockchip,ddr-timing"; + ddr2_speed_bin = <0x00>; + ddr3_speed_bin = <0x15>; + ddr4_speed_bin = <0x0c>; + pd_idle = <0x0d>; + sr_idle = <0x5d>; + sr_mc_gate_idle = <0x00>; + srpd_lite_idle = <0x00>; + standby_idle = <0x00>; + auto_pd_dis_freq = <0x42a>; + auto_sr_dis_freq = <0x320>; + ddr2_dll_dis_freq = <0x12c>; + ddr3_dll_dis_freq = <0x12c>; + ddr4_dll_dis_freq = <0x271>; + phy_dll_dis_freq = <0x190>; + ddr2_odt_dis_freq = <0x64>; + phy_ddr2_odt_dis_freq = <0x64>; + ddr2_drv = <0x01>; + ddr2_odt = <0x96>; + phy_ddr2_ca_drv = <0x15>; + phy_ddr2_ck_drv = <0x12>; + phy_ddr2_dq_drv = <0x15>; + phy_ddr2_odt = <0x02>; + ddr3_odt_dis_freq = <0x190>; + phy_ddr3_odt_dis_freq = <0x190>; + ddr3_drv = <0x28>; + ddr3_odt = <0x78>; + phy_ddr3_ca_drv = <0x15>; + phy_ddr3_ck_drv = <0x12>; + phy_ddr3_dq_drv = <0x15>; + phy_ddr3_odt = <0x02>; + phy_lpddr2_odt_dis_freq = <0x29a>; + lpddr2_drv = <0x28>; + phy_lpddr2_ca_drv = <0x16>; + phy_lpddr2_ck_drv = <0x13>; + phy_lpddr2_dq_drv = <0x16>; + phy_lpddr2_odt = <0x00>; + lpddr3_odt_dis_freq = <0x190>; + phy_lpddr3_odt_dis_freq = <0x190>; + lpddr3_drv = <0x28>; + lpddr3_odt = <0xf0>; + phy_lpddr3_ca_drv = <0x16>; + phy_lpddr3_ck_drv = <0x13>; + phy_lpddr3_dq_drv = <0x16>; + phy_lpddr3_odt = <0x02>; + lpddr4_odt_dis_freq = <0x320>; + phy_lpddr4_odt_dis_freq = <0x320>; + lpddr4_drv = <0x3c>; + lpddr4_dq_odt = <0x28>; + lpddr4_ca_odt = <0x28>; + phy_lpddr4_ca_drv = <0x14>; + phy_lpddr4_ck_cs_drv = <0x06>; + phy_lpddr4_dq_drv = <0x06>; + phy_lpddr4_odt = <0x10>; + ddr4_odt_dis_freq = <0x29a>; + phy_ddr4_odt_dis_freq = <0x29a>; + ddr4_drv = <0x22>; + ddr4_odt = <0xf0>; + phy_ddr4_ca_drv = <0x16>; + phy_ddr4_ck_drv = <0x13>; + phy_ddr4_dq_drv = <0x16>; + phy_ddr4_odt = <0x02>; + ddr3a1_ddr4a9_de-skew = <0x06>; + ddr3a0_ddr4a10_de-skew = <0x07>; + ddr3a3_ddr4a6_de-skew = <0x07>; + ddr3a2_ddr4a4_de-skew = <0x07>; + ddr3a5_ddr4a8_de-skew = <0x07>; + ddr3a4_ddr4a5_de-skew = <0x07>; + ddr3a7_ddr4a11_de-skew = <0x07>; + ddr3a6_ddr4a7_de-skew = <0x06>; + ddr3a9_ddr4a0_de-skew = <0x07>; + ddr3a8_ddr4a13_de-skew = <0x07>; + ddr3a11_ddr4a3_de-skew = <0x07>; + ddr3a10_ddr4cs0_de-skew = <0x07>; + ddr3a13_ddr4a2_de-skew = <0x07>; + ddr3a12_ddr4ba1_de-skew = <0x07>; + ddr3a15_ddr4odt0_de-skew = <0x07>; + ddr3a14_ddr4a1_de-skew = <0x07>; + ddr3ba1_ddr4a15_de-skew = <0x07>; + ddr3ba0_ddr4bg0_de-skew = <0x07>; + ddr3ras_ddr4cke_de-skew = <0x07>; + ddr3ba2_ddr4ba0_de-skew = <0x07>; + ddr3we_ddr4bg1_de-skew = <0x07>; + ddr3cas_ddr4a12_de-skew = <0x07>; + ddr3ckn_ddr4ckn_de-skew = <0x07>; + ddr3ckp_ddr4ckp_de-skew = <0x07>; + ddr3cke_ddr4a16_de-skew = <0x07>; + ddr3odt0_ddr4a14_de-skew = <0x07>; + ddr3cs0_ddr4act_de-skew = <0x06>; + ddr3reset_ddr4reset_de-skew = <0x07>; + ddr3cs1_ddr4cs1_de-skew = <0x06>; + ddr3odt1_ddr4odt1_de-skew = <0x07>; + cs0_dm0_rx_de-skew = <0x07>; + cs0_dm0_tx_de-skew = <0x07>; + cs0_dq0_rx_de-skew = <0x08>; + cs0_dq0_tx_de-skew = <0x08>; + cs0_dq1_rx_de-skew = <0x09>; + cs0_dq1_tx_de-skew = <0x08>; + cs0_dq2_rx_de-skew = <0x08>; + cs0_dq2_tx_de-skew = <0x08>; + cs0_dq3_rx_de-skew = <0x08>; + cs0_dq3_tx_de-skew = <0x08>; + cs0_dq4_rx_de-skew = <0x09>; + cs0_dq4_tx_de-skew = <0x08>; + cs0_dq5_rx_de-skew = <0x09>; + cs0_dq5_tx_de-skew = <0x08>; + cs0_dq6_rx_de-skew = <0x09>; + cs0_dq6_tx_de-skew = <0x08>; + cs0_dq7_rx_de-skew = <0x08>; + cs0_dq7_tx_de-skew = <0x08>; + cs0_dqs0_rx_de-skew = <0x06>; + cs0_dqs0p_tx_de-skew = <0x09>; + cs0_dqs0n_tx_de-skew = <0x09>; + cs0_dm1_rx_de-skew = <0x07>; + cs0_dm1_tx_de-skew = <0x06>; + cs0_dq8_rx_de-skew = <0x08>; + cs0_dq8_tx_de-skew = <0x07>; + cs0_dq9_rx_de-skew = <0x09>; + cs0_dq9_tx_de-skew = <0x07>; + cs0_dq10_rx_de-skew = <0x08>; + cs0_dq10_tx_de-skew = <0x08>; + cs0_dq11_rx_de-skew = <0x08>; + cs0_dq11_tx_de-skew = <0x07>; + cs0_dq12_rx_de-skew = <0x08>; + cs0_dq12_tx_de-skew = <0x08>; + cs0_dq13_rx_de-skew = <0x09>; + cs0_dq13_tx_de-skew = <0x07>; + cs0_dq14_rx_de-skew = <0x09>; + cs0_dq14_tx_de-skew = <0x08>; + cs0_dq15_rx_de-skew = <0x09>; + cs0_dq15_tx_de-skew = <0x07>; + cs0_dqs1_rx_de-skew = <0x07>; + cs0_dqs1p_tx_de-skew = <0x09>; + cs0_dqs1n_tx_de-skew = <0x09>; + cs0_dm2_rx_de-skew = <0x07>; + cs0_dm2_tx_de-skew = <0x07>; + cs0_dq16_rx_de-skew = <0x09>; + cs0_dq16_tx_de-skew = <0x09>; + cs0_dq17_rx_de-skew = <0x07>; + cs0_dq17_tx_de-skew = <0x09>; + cs0_dq18_rx_de-skew = <0x07>; + cs0_dq18_tx_de-skew = <0x08>; + cs0_dq19_rx_de-skew = <0x07>; + cs0_dq19_tx_de-skew = <0x09>; + cs0_dq20_rx_de-skew = <0x09>; + cs0_dq20_tx_de-skew = <0x09>; + cs0_dq21_rx_de-skew = <0x09>; + cs0_dq21_tx_de-skew = <0x09>; + cs0_dq22_rx_de-skew = <0x08>; + cs0_dq22_tx_de-skew = <0x09>; + cs0_dq23_rx_de-skew = <0x08>; + cs0_dq23_tx_de-skew = <0x09>; + cs0_dqs2_rx_de-skew = <0x06>; + cs0_dqs2p_tx_de-skew = <0x09>; + cs0_dqs2n_tx_de-skew = <0x09>; + cs0_dm3_rx_de-skew = <0x07>; + cs0_dm3_tx_de-skew = <0x07>; + cs0_dq24_rx_de-skew = <0x08>; + cs0_dq24_tx_de-skew = <0x08>; + cs0_dq25_rx_de-skew = <0x09>; + cs0_dq25_tx_de-skew = <0x09>; + cs0_dq26_rx_de-skew = <0x09>; + cs0_dq26_tx_de-skew = <0x08>; + cs0_dq27_rx_de-skew = <0x09>; + cs0_dq27_tx_de-skew = <0x08>; + cs0_dq28_rx_de-skew = <0x09>; + cs0_dq28_tx_de-skew = <0x09>; + cs0_dq29_rx_de-skew = <0x09>; + cs0_dq29_tx_de-skew = <0x09>; + cs0_dq30_rx_de-skew = <0x08>; + cs0_dq30_tx_de-skew = <0x08>; + cs0_dq31_rx_de-skew = <0x08>; + cs0_dq31_tx_de-skew = <0x08>; + cs0_dqs3_rx_de-skew = <0x07>; + cs0_dqs3p_tx_de-skew = <0x09>; + cs0_dqs3n_tx_de-skew = <0x09>; + cs1_dm0_rx_de-skew = <0x07>; + cs1_dm0_tx_de-skew = <0x07>; + cs1_dq0_rx_de-skew = <0x08>; + cs1_dq0_tx_de-skew = <0x08>; + cs1_dq1_rx_de-skew = <0x09>; + cs1_dq1_tx_de-skew = <0x08>; + cs1_dq2_rx_de-skew = <0x08>; + cs1_dq2_tx_de-skew = <0x08>; + cs1_dq3_rx_de-skew = <0x08>; + cs1_dq3_tx_de-skew = <0x08>; + cs1_dq4_rx_de-skew = <0x08>; + cs1_dq4_tx_de-skew = <0x08>; + cs1_dq5_rx_de-skew = <0x09>; + cs1_dq5_tx_de-skew = <0x08>; + cs1_dq6_rx_de-skew = <0x09>; + cs1_dq6_tx_de-skew = <0x08>; + cs1_dq7_rx_de-skew = <0x08>; + cs1_dq7_tx_de-skew = <0x08>; + cs1_dqs0_rx_de-skew = <0x06>; + cs1_dqs0p_tx_de-skew = <0x09>; + cs1_dqs0n_tx_de-skew = <0x09>; + cs1_dm1_rx_de-skew = <0x07>; + cs1_dm1_tx_de-skew = <0x07>; + cs1_dq8_rx_de-skew = <0x08>; + cs1_dq8_tx_de-skew = <0x08>; + cs1_dq9_rx_de-skew = <0x08>; + cs1_dq9_tx_de-skew = <0x07>; + cs1_dq10_rx_de-skew = <0x07>; + cs1_dq10_tx_de-skew = <0x08>; + cs1_dq11_rx_de-skew = <0x08>; + cs1_dq11_tx_de-skew = <0x08>; + cs1_dq12_rx_de-skew = <0x08>; + cs1_dq12_tx_de-skew = <0x07>; + cs1_dq13_rx_de-skew = <0x08>; + cs1_dq13_tx_de-skew = <0x08>; + cs1_dq14_rx_de-skew = <0x08>; + cs1_dq14_tx_de-skew = <0x08>; + cs1_dq15_rx_de-skew = <0x08>; + cs1_dq15_tx_de-skew = <0x07>; + cs1_dqs1_rx_de-skew = <0x07>; + cs1_dqs1p_tx_de-skew = <0x09>; + cs1_dqs1n_tx_de-skew = <0x09>; + cs1_dm2_rx_de-skew = <0x07>; + cs1_dm2_tx_de-skew = <0x08>; + cs1_dq16_rx_de-skew = <0x08>; + cs1_dq16_tx_de-skew = <0x09>; + cs1_dq17_rx_de-skew = <0x08>; + cs1_dq17_tx_de-skew = <0x09>; + cs1_dq18_rx_de-skew = <0x07>; + cs1_dq18_tx_de-skew = <0x08>; + cs1_dq19_rx_de-skew = <0x08>; + cs1_dq19_tx_de-skew = <0x09>; + cs1_dq20_rx_de-skew = <0x09>; + cs1_dq20_tx_de-skew = <0x09>; + cs1_dq21_rx_de-skew = <0x09>; + cs1_dq21_tx_de-skew = <0x09>; + cs1_dq22_rx_de-skew = <0x08>; + cs1_dq22_tx_de-skew = <0x09>; + cs1_dq23_rx_de-skew = <0x08>; + cs1_dq23_tx_de-skew = <0x09>; + cs1_dqs2_rx_de-skew = <0x06>; + cs1_dqs2p_tx_de-skew = <0x09>; + cs1_dqs2n_tx_de-skew = <0x09>; + cs1_dm3_rx_de-skew = <0x07>; + cs1_dm3_tx_de-skew = <0x07>; + cs1_dq24_rx_de-skew = <0x08>; + cs1_dq24_tx_de-skew = <0x09>; + cs1_dq25_rx_de-skew = <0x09>; + cs1_dq25_tx_de-skew = <0x09>; + cs1_dq26_rx_de-skew = <0x09>; + cs1_dq26_tx_de-skew = <0x08>; + cs1_dq27_rx_de-skew = <0x08>; + cs1_dq27_tx_de-skew = <0x08>; + cs1_dq28_rx_de-skew = <0x09>; + cs1_dq28_tx_de-skew = <0x09>; + cs1_dq29_rx_de-skew = <0x09>; + cs1_dq29_tx_de-skew = <0x09>; + cs1_dq30_rx_de-skew = <0x09>; + cs1_dq30_tx_de-skew = <0x08>; + cs1_dq31_rx_de-skew = <0x08>; + cs1_dq31_tx_de-skew = <0x08>; + cs1_dqs3_rx_de-skew = <0x07>; + cs1_dqs3p_tx_de-skew = <0x09>; + cs1_dqs3n_tx_de-skew = <0x09>; + phandle = <0xae>; + }; + + aliases { + ethernet0 = "/ethernet@ff360000"; + i2c0 = "/i2c@ff180000"; + i2c1 = "/i2c@ff190000"; + i2c2 = "/i2c@ff1a0000"; + i2c3 = "/i2c@ff1b0000"; + serial0 = "/serial@ff030000"; + serial1 = "/serial@ff158000"; + serial2 = "/serial@ff160000"; + serial3 = "/serial@ff168000"; + serial4 = "/serial@ff170000"; + serial5 = "/serial@ff178000"; + spi0 = "/spi@ff1d0000"; + spi1 = "/spi@ff1d8000"; + }; + + cpus { + #address-cells = <0x02>; + #size-cells = <0x00>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x00>; + enable-method = "psci"; + clocks = <0x02 0x07>; + #cooling-cells = <0x02>; + dynamic-power-coefficient = <0x5a>; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + cpu-supply = <0x06>; + phandle = <0x09>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x01>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0a>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x02>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0b>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x03>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0c>; + }; + + idle-states { + entry-method = "psci"; + + cpu-sleep { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x10000>; + entry-latency-us = <0x78>; + exit-latency-us = <0xfa>; + min-residency-us = <0x384>; + phandle = <0x04>; + }; + + cluster-sleep { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x1010000>; + entry-latency-us = <0x190>; + exit-latency-us = <0x1f4>; + min-residency-us = <0x7d0>; + phandle = <0x05>; + }; + }; + }; + + cpu0-opp-table { + compatible = "operating-points-v2"; + opp-shared; + rockchip,temp-hysteresis = <0x1388>; + rockchip,low-temp = <0x00>; + rockchip,low-temp-min-volt = <0xf4240>; + rockchip,low-temp-adjust-volt = <0x00 0x5e8 0xc350>; + clocks = <0x02 0x01>; + rockchip,avs-scale = <0x04>; + rockchip,max-volt = <0x149970>; + rockchip,evb-irdrop = <0x61a8>; + nvmem-cells = <0x07 0x08>; + nvmem-cell-names = "cpu_leakage\0performance"; + rockchip,bin-scaling-sel = <0x00 0x0d 0x01 0x0d>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-freq = <0x639c0>; + rockchip,pvtm-volt = <0xf4240>; + rockchip,pvtm-ch = <0x00 0x00>; + rockchip,pvtm-sample-time = <0x3e8>; + rockchip,pvtm-number = <0x0a>; + rockchip,pvtm-error = <0x3e8>; + rockchip,pvtm-ref-temp = <0x28>; + rockchip,pvtm-temp-prop = <0xffffffc8 0xffffffc8>; + rockchip,thermal-zone = "soc-thermal"; + rockchip,avs = <0x01>; + phandle = <0x03>; + + opp-1008000000 { + opp-hz = <0x00 0x3c14dc00>; + opp-microvolt = <0x11edd8 0x11edd8 0x149970>; + opp-microvolt-L0 = <0x11edd8 0x11edd8 0x149970>; + opp-microvolt-L1 = <0x112a88 0x112a88 0x149970>; + opp-microvolt-L2 = <0x112a88 0x112a88 0x149970>; + opp-microvolt-L3 = <0x100590 0x100590 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1200000000 { + opp-hz = <0x00 0x47868c00>; + opp-microvolt = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L0 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L1 = <0x137478 0x137478 0x149970>; + opp-microvolt-L2 = <0x1312d0 0x1312d0 0x149970>; + opp-microvolt-L3 = <0x124f80 0x124f80 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1248000000 { + opp-hz = <0x00 0x4a62f800>; + opp-microvolt = <0x149970 0x149970 0x149970>; + opp-microvolt-L0 = <0x149970 0x149970 0x149970>; + opp-microvolt-L1 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L2 = <0x137478 0x137478 0x149970>; + opp-microvolt-L3 = <0x12b128 0x12b128 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1296000000 { + opp-hz = <0x00 0x4d3f6400>; + opp-microvolt = <0x149970 0x149970 0x149970>; + opp-microvolt-L0 = <0x149970 0x149970 0x149970>; + opp-microvolt-L1 = <0x149970 0x149970 0x149970>; + opp-microvolt-L2 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L3 = <0x1312d0 0x1312d0 0x149970>; + clock-latency-ns = <0x9c40>; + }; + }; + + arm-pmu { + compatible = "arm,cortex-a53-pmu"; + interrupts = <0x00 0x64 0x04 0x00 0x65 0x04 0x00 0x66 0x04 0x00 0x67 0x04>; + interrupt-affinity = <0x09 0x0a 0x0b 0x0c>; + }; + + bus-soc { + compatible = "rockchip,px30-bus"; + rockchip,busfreq-policy = "autocs"; + phandle = <0xc6>; + + soc-bus0 { + bus-id = <0x00>; + timer-us = <0x14>; + enable-msk = <0x40f7>; + status = "disabled"; + }; + + soc-bus1 { + bus-id = <0x01>; + timer-us = <0xc8>; + enable-msk = <0x40bf>; + status = "disabled"; + }; + + soc-bus2 { + bus-id = <0x02>; + timer-us = <0xc8>; + enable-msk = <0x4007>; + status = "disabled"; + }; + }; + + bus-apll { + compatible = "rockchip,px30-bus"; + rockchip,busfreq-policy = "clkfreq"; + clocks = <0x02 0x01>; + clock-names = "bus"; + operating-points-v2 = <0x0d>; + status = "okay"; + bus-supply = <0x0e>; + phandle = <0xc7>; + }; + + bus-apll-opp-table { + compatible = "operating-points-v2"; + opp-shared; + phandle = <0x0d>; + + opp-1512000000 { + opp-hz = <0x00 0x5a1f4a00>; + opp-microvolt = <0xf4240>; + }; + + opp-1008000000 { + opp-hz = <0x00 0x3c14dc00>; + opp-microvolt = <0xe7ef0>; + }; + }; + + cpuinfo { + compatible = "rockchip,cpuinfo"; + nvmem-cells = <0x0f>; + nvmem-cell-names = "id"; + }; + + display-subsystem { + compatible = "rockchip,display-subsystem"; + ports = <0x10>; + status = "okay"; + logo-memory-region = <0x11>; + phandle = <0xc8>; + + route { + + route-lvds { + status = "disabled"; + logo,uboot = "logo.bmp"; + logo,kernel = "logo_kernel.bmp"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x12>; + phandle = <0xc9>; + }; + + route-dsi { + status = "okay"; + logo,uboot = "logo.bmp"; + logo,kernel = "logo_kernel.bmp"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x13>; + phandle = <0xca>; + }; + + route-rgb { + status = "disabled"; + logo,uboot = "logo.bmp"; + logo,kernel = "logo_kernel.bmp"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x14>; + phandle = <0xcb>; + }; + }; + }; + + firmware { + + optee { + compatible = "linaro,optee-tz"; + method = "smc"; + }; + }; + + external-gmac-clock { + compatible = "fixed-clock"; + clock-frequency = <0x2faf080>; + clock-output-names = "gmac_clkin"; + #clock-cells = <0x00>; + phandle = <0xcc>; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + rockchip-suspend { + compatible = "rockchip,pm-px30"; + status = "okay"; + rockchip,sleep-debug-en = <0x01>; + rockchip,sleep-mode-config = <0x20702>; + rockchip,wakeup-config = <0x85>; + phandle = <0xcd>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <0x01 0x0d 0xf04 0x01 0x0e 0xf04 0x01 0x0b 0xf04 0x01 0x0a 0xf04>; + }; + + xin24m { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x16e3600>; + clock-output-names = "xin24m"; + phandle = <0xce>; + }; + + xin32k { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x8000>; + clock-output-names = "xin32k"; + phandle = <0xcf>; + }; + + power-management@ff000000 { + compatible = "rockchip,px30-pmu\0syscon\0simple-mfd"; + reg = <0x00 0xff000000 0x00 0x1000>; + phandle = <0xd0>; + + power-controller { + compatible = "rockchip,px30-power-controller"; + #power-domain-cells = <0x01>; + #address-cells = <0x01>; + #size-cells = <0x00>; + phandle = <0x8a>; + + pd_usb@5 { + reg = <0x05>; + clocks = <0x02 0x103 0x02 0x102 0x02 0x3c>; + pm_qos = <0x15 0x16>; + }; + + pd_sdcard@7 { + reg = <0x07>; + clocks = <0x02 0xf7 0x02 0x3b>; + pm_qos = <0x17>; + }; + + pd_gmac@9 { + reg = <0x09>; + clocks = <0x02 0xb2 0x02 0x143 0x02 0x40 0x02 0x3f>; + pm_qos = <0x18>; + }; + + pd_mmc_nand@10 { + reg = <0x0a>; + clocks = <0x02 0xfe 0x02 0x100 0x02 0xff 0x02 0x101 0x02 0x39 0x02 0x37 0x02 0x38 0x02 0x3a>; + pm_qos = <0x19 0x1a 0x1b 0x1c>; + }; + + pd_vpu@11 { + reg = <0x0b>; + clocks = <0x02 0xaf 0x02 0xf4 0x02 0x4b>; + pm_qos = <0x1d 0x1e>; + }; + + pd_vo@12 { + reg = <0x0c>; + clocks = <0x02 0xb7 0x02 0xb5 0x02 0xb6 0x02 0x96 0x02 0x97 0x02 0xfd 0x02 0xfb 0x02 0xfc 0x02 0x144 0x02 0x35 0x02 0x36>; + pm_qos = <0x1f 0x20 0x21 0x22>; + }; + + pd_vi@13 { + reg = <0x0d>; + clocks = <0x02 0xb3 0x02 0xb4 0x02 0xf9 0x02 0xfa 0x02 0x33>; + pm_qos = <0x23 0x24 0x25 0x26 0x27>; + }; + + pd_gpu@14 { + reg = <0x0e>; + clocks = <0x02 0x49>; + pm_qos = <0x28>; + }; + }; + }; + + syscon@ff010000 { + compatible = "rockchip,px30-pmugrf\0syscon\0simple-mfd"; + reg = <0x00 0xff010000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0xab>; + + io-domains { + compatible = "rockchip,px30-pmu-io-voltage-domain"; + status = "okay"; + pmuio1-supply = <0x29>; + pmuio2-supply = <0x29>; + phandle = <0xd1>; + }; + + reboot-mode { + compatible = "syscon-reboot-mode"; + offset = <0x200>; + mode-bootloader = <0x5242c301>; + mode-charge = <0x5242c30b>; + mode-fastboot = <0x5242c309>; + mode-loader = <0x5242c301>; + mode-normal = <0x5242c300>; + mode-recovery = <0x5242c303>; + mode-ums = <0x5242c30c>; + }; + + pmu-pvtm { + compatible = "rockchip,px30-pmu-pvtm"; + clocks = <0x2a 0x07>; + clock-names = "pmu"; + status = "okay"; + phandle = <0xd2>; + }; + }; + + serial@ff030000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff030000 0x00 0x100>; + interrupts = <0x00 0x0f 0x04>; + clocks = <0x2a 0x06 0x2a 0x15>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x00 0x2b 0x01>; + pinctrl-names = "default"; + pinctrl-0 = <0x2c 0x2d 0x2e>; + status = "disabled"; + phandle = <0xd3>; + }; + + i2s@ff060000 { + compatible = "rockchip,px30-i2s-tdm"; + reg = <0x00 0xff060000 0x00 0x1000>; + interrupts = <0x00 0x0c 0x04>; + clocks = <0x02 0x10 0x02 0x12 0x02 0x106>; + clock-names = "mclk_tx\0mclk_rx\0hclk"; + dmas = <0x2b 0x10 0x2b 0x11>; + dma-names = "tx\0rx"; + resets = <0x02 0x84 0x02 0xbf>; + reset-names = "tx-m\0rx-m"; + rockchip,cru = <0x02>; + rockchip,grf = <0x2f>; + pinctrl-names = "default"; + pinctrl-0 = <0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x3a 0x3b>; + status = "disabled"; + phandle = <0xd4>; + }; + + i2s@ff070000 { + compatible = "rockchip,px30-i2s\0rockchip,rk3066-i2s"; + reg = <0x00 0xff070000 0x00 0x1000>; + interrupts = <0x00 0x0d 0x04>; + clocks = <0x02 0x14 0x02 0x107>; + clock-names = "i2s_clk\0i2s_hclk"; + dmas = <0x2b 0x12 0x2b 0x13>; + dma-names = "tx\0rx"; + resets = <0x02 0x86 0x02 0x85>; + reset-names = "reset-m\0reset-h"; + pinctrl-names = "default"; + pinctrl-0 = <0x3c 0x3d 0x3e 0x3f>; + status = "okay"; + #sound-dai-cells = <0x00>; + phandle = <0xc4>; + }; + + i2s@ff080000 { + compatible = "rockchip,px30-i2s\0rockchip,rk3066-i2s"; + reg = <0x00 0xff080000 0x00 0x1000>; + interrupts = <0x00 0x0e 0x04>; + clocks = <0x02 0x16 0x02 0x108>; + clock-names = "i2s_clk\0i2s_hclk"; + dmas = <0x2b 0x14 0x2b 0x15>; + dma-names = "tx\0rx"; + resets = <0x02 0x88 0x02 0x87>; + reset-names = "reset-m\0reset-h"; + pinctrl-names = "default"; + pinctrl-0 = <0x40 0x41 0x42 0x43>; + status = "disabled"; + phandle = <0xd5>; + }; + + pdm@ff0a0000 { + compatible = "rockchip,px30-pdm\0rockchip,pdm"; + reg = <0x00 0xff0a0000 0x00 0x1000>; + clocks = <0x02 0x0f 0x02 0x105>; + clock-names = "pdm_clk\0pdm_hclk"; + dmas = <0x2b 0x18>; + dma-names = "rx"; + resets = <0x02 0x82>; + reset-names = "pdm-m"; + pinctrl-names = "default"; + pinctrl-0 = <0x44 0x45 0x46 0x47 0x48 0x49>; + status = "disabled"; + phandle = <0xd6>; + }; + + crypto@ff0b0000 { + compatible = "rockchip,px30-crypto"; + reg = <0x00 0xff0b0000 0x00 0x4000>; + interrupts = <0x00 0x52 0x04>; + clocks = <0x02 0xac 0x02 0xf1 0x02 0x30 0x02 0x31>; + clock-names = "aclk\0hclk\0sclk\0apb_pclk"; + resets = <0x02 0x74>; + reset-names = "crypto-rst"; + status = "disabled"; + phandle = <0xd7>; + }; + + rng@ff0b0000 { + compatible = "rockchip,cryptov2-rng"; + reg = <0x00 0xff0b0000 0x00 0x4000>; + clocks = <0x02 0x30 0x02 0x31 0x02 0xac 0x02 0xf1>; + clock-names = "clk_crypto\0clk_crypto_apk\0aclk_crypto\0hclk_crypto"; + assigned-clocks = <0x02 0x30 0x02 0x31 0x02 0xac 0x02 0xf1>; + assigned-clock-rates = <0x8f0d180 0x8f0d180 0xbebc200 0x5f5e100>; + resets = <0x02 0x74>; + reset-names = "reset"; + status = "okay"; + phandle = <0xd8>; + }; + + interrupt-controller@ff131000 { + compatible = "arm,gic-400"; + #interrupt-cells = <0x03>; + #address-cells = <0x00>; + interrupt-controller; + reg = <0x00 0xff131000 0x00 0x1000 0x00 0xff132000 0x00 0x2000 0x00 0xff134000 0x00 0x2000 0x00 0xff136000 0x00 0x2000>; + interrupts = <0x01 0x09 0xf04>; + phandle = <0x01>; + }; + + syscon@ff140000 { + compatible = "rockchip,px30-grf\0syscon\0simple-mfd"; + reg = <0x00 0xff140000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0x2f>; + + io-domains { + compatible = "rockchip,px30-io-voltage-domain"; + status = "okay"; + vccio1-supply = <0x4a>; + vccio2-supply = <0x4a>; + vccio3-supply = <0x4b>; + vccio4-supply = <0x4b>; + vccio5-supply = <0x4b>; + vccio6-supply = <0x4b>; + phandle = <0xd9>; + }; + + lvds { + compatible = "rockchip,px30-lvds"; + phys = <0x4c>; + phy-names = "phy"; + status = "disabled"; + phandle = <0xda>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x12>; + phandle = <0xa1>; + }; + }; + }; + }; + + rgb { + compatible = "rockchip,px30-rgb"; + pinctrl-names = "default\0sleep"; + pinctrl-0 = <0x4d>; + pinctrl-1 = <0x4e>; + status = "disabled"; + phys = <0x4c>; + phy-names = "phy"; + phandle = <0xdb>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x14>; + phandle = <0xa3>; + }; + }; + }; + }; + }; + + syscon@ff148000 { + compatible = "syscon\0simple-mfd"; + reg = <0x00 0xff148000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0xdc>; + + pvtm { + compatible = "rockchip,px30-pvtm"; + clocks = <0x02 0x4a>; + clock-names = "core"; + status = "okay"; + phandle = <0xdd>; + }; + }; + + serial@ff158000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff158000 0x00 0x100>; + interrupts = <0x00 0x10 0x04>; + clocks = <0x02 0x18 0x02 0x149>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x02 0x2b 0x03>; + pinctrl-names = "default"; + pinctrl-0 = <0x4f 0x50>; + status = "okay"; + phandle = <0xde>; + }; + + serial@ff160000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff160000 0x00 0x100>; + interrupts = <0x00 0x11 0x04>; + clocks = <0x02 0x19 0x02 0x14a>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x04 0x2b 0x05>; + pinctrl-names = "default"; + pinctrl-0 = <0x51>; + status = "disabled"; + phandle = <0xdf>; + }; + + serial@ff168000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff168000 0x00 0x100>; + interrupts = <0x00 0x12 0x04>; + clocks = <0x02 0x1a 0x02 0x14b>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x06 0x2b 0x07>; + pinctrl-names = "default"; + pinctrl-0 = <0x52 0x53 0x54>; + status = "disabled"; + phandle = <0xe0>; + }; + + serial@ff170000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff170000 0x00 0x100>; + interrupts = <0x00 0x13 0x04>; + clocks = <0x02 0x1b 0x02 0x14c>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x08 0x2b 0x09>; + pinctrl-names = "default"; + pinctrl-0 = <0x55 0x56 0x57>; + status = "disabled"; + phandle = <0xe1>; + }; + + serial@ff178000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff178000 0x00 0x100>; + interrupts = <0x00 0x14 0x04>; + clocks = <0x02 0x1c 0x02 0x14d>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x0a 0x2b 0x0b>; + pinctrl-names = "default"; + pinctrl-0 = <0x58 0x59 0x5a>; + status = "disabled"; + phandle = <0xe2>; + }; + + i2c@ff180000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff180000 0x00 0x1000>; + clocks = <0x02 0x1d 0x02 0x14e>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x07 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x5b>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + clock-frequency = <0x61a80>; + i2c-scl-rising-time-ns = <0x118>; + i2c-scl-falling-time-ns = <0x10>; + phandle = <0xe3>; + + pmic@20 { + compatible = "rockchip,rk817"; + reg = <0x20>; + interrupt-parent = <0x5c>; + interrupts = <0x0a 0x08>; + pinctrl-names = "default\0pmic-sleep\0pmic-power-off\0pmic-reset"; + pinctrl-0 = <0x5d>; + pinctrl-1 = <0x5e 0x5f>; + pinctrl-2 = <0x60 0x61>; + pinctrl-3 = <0x62 0x63>; + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <0x01>; + clock-output-names = "rk808-clkout1\0rk808-clkout2"; + pmic-reset-func = <0x01>; + vcc1-supply = <0x64>; + vcc2-supply = <0x64>; + vcc3-supply = <0x64>; + vcc4-supply = <0x64>; + vcc5-supply = <0x64>; + vcc6-supply = <0x64>; + vcc7-supply = <0x64>; + vcc8-supply = <0x64>; + vcc9-supply = <0x65>; + phandle = <0xe4>; + + pwrkey { + status = "okay"; + }; + + pinctrl_rk8xx { + gpio-controller; + #gpio-cells = <0x02>; + phandle = <0xe5>; + + rk817_ts_gpio1 { + pins = "gpio_ts"; + function = "pin_fun1"; + phandle = <0xe6>; + }; + + rk817_gt_gpio2 { + pins = "gpio_gt"; + function = "pin_fun1"; + phandle = <0xe7>; + }; + + rk817_pin_ts { + pins = "gpio_ts"; + function = "pin_fun0"; + phandle = <0xe8>; + }; + + rk817_pin_gt { + pins = "gpio_gt"; + function = "pin_fun0"; + phandle = <0xe9>; + }; + + rk817_slppin_null { + pins = "gpio_slp"; + function = "pin_fun0"; + phandle = <0xea>; + }; + + rk817_slppin_slp { + pins = "gpio_slp"; + function = "pin_fun1"; + phandle = <0x5f>; + }; + + rk817_slppin_pwrdn { + pins = "gpio_slp"; + function = "pin_fun2"; + phandle = <0x61>; + }; + + rk817_slppin_rst { + pins = "gpio_slp"; + function = "pin_fun3"; + phandle = <0x63>; + }; + }; + + regulators { + + DCDC_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xe7ef0>; + regulator-max-microvolt = <0x118c30>; + regulator-ramp-delay = <0x1771>; + regulator-initial-mode = <0x02>; + regulator-name = "vdd_logic"; + phandle = <0x0e>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0xe7ef0>; + }; + }; + + DCDC_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xe7ef0>; + regulator-max-microvolt = <0x149970>; + regulator-ramp-delay = <0x1771>; + regulator-initial-mode = <0x02>; + regulator-name = "vdd_arm"; + phandle = <0x06>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0xe7ef0>; + }; + }; + + DCDC_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x02>; + regulator-name = "vcc_ddr"; + phandle = <0xeb>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + DCDC_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-initial-mode = <0x02>; + regulator-name = "vcc_3v3"; + phandle = <0x4b>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG1 { + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + regulator-name = "vcc_1v0"; + phandle = <0xec>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0xf4240>; + }; + }; + + LDO_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + regulator-name = "vcc1v8_soc"; + phandle = <0x88>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x1b7740>; + }; + }; + + LDO_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + regulator-name = "vcc1v0_soc"; + phandle = <0xed>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0xf4240>; + }; + }; + + LDO_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "vcc3v3_pmu"; + phandle = <0x29>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + regulator-name = "vccio_sd"; + phandle = <0x4a>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x1b7740>; + }; + }; + + LDO_REG6 { + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x2dc6c0>; + regulator-boot-on; + regulator-name = "vcc_sd"; + phandle = <0x93>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x2dc6c0>; + }; + }; + + LDO_REG7 { + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "vcc_backlight"; + regulator-always-on; + phandle = <0xc3>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG8 { + regulator-min-microvolt = <0x2ab980>; + regulator-max-microvolt = <0x2ab980>; + regulator-name = "vcc_lcd"; + phandle = <0x9e>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x2ab980>; + }; + }; + + BOOST { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x4c4b40>; + regulator-max-microvolt = <0x5265c0>; + regulator-name = "boost"; + phandle = <0x65>; + }; + + OTG_SWITCH { + regulator-boot-on; + regulator-name = "otg_switch"; + phandle = <0xee>; + }; + }; + + battery { + compatible = "rk817,battery"; + ocv_table = <0xc5d 0xc94 0xcd0 0xd02 0xd34 0xd66 0xd98 0xdca 0xdfc 0xe2e 0xe56 0xe7e 0xea6 0xece 0xef6 0xf1e 0xf46 0xf6e 0xf96 0xf9b 0xfa0>; + design_capacity = <0xd34>; + design_qmax = <0xe86>; + bat_res = <0x64>; + sleep_enter_current = <0x12c>; + sleep_exit_current = <0x12c>; + sleep_filter_current = <0x64>; + power_off_thresd = <0xbb8>; + zero_algorithm_vol = <0xf0a>; + max_soc_offset = <0x3c>; + monitor_sec = <0x05>; + virtual_power = <0x00>; + sample_res = <0x0a>; + }; + + charger { + compatible = "rk817,charger"; + min_input_voltage = <0x1194>; + max_input_current = <0x5dc>; + max_chrg_current = <0x7d0>; + max_chrg_voltage = <0x1068>; + chrg_term_mode = <0x00>; + chrg_finish_cur = <0x34>; + virtual_power = <0x00>; + sample_res = <0x0a>; + dc_det_gpio = <0x5c 0x0b 0x00>; + bat_low_gpio = <0x66 0x0d 0x00>; + extcon = <0x67>; + }; + + codec { + #sound-dai-cells = <0x00>; + compatible = "rockchip,rk817-codec"; + clocks = <0x02 0x15>; + clock-names = "mclk"; + pinctrl-names = "default"; + pinctrl-0 = <0x68>; + hp-volume = <0x14>; + spk-volume = <0x03>; + status = "okay"; + phandle = <0xc5>; + }; + }; + }; + + i2c@ff190000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff190000 0x00 0x1000>; + clocks = <0x02 0x1e 0x02 0x14f>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x08 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x69>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + clock-frequency = <0x61a80>; + phandle = <0xef>; + }; + + i2c@ff1a0000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff1a0000 0x00 0x1000>; + clocks = <0x02 0x1f 0x02 0x150>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x09 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x6a>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xf0>; + }; + + i2c@ff1b0000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff1b0000 0x00 0x1000>; + clocks = <0x02 0x20 0x02 0x151>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x0a 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x6b>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xf1>; + }; + + spi@ff1d0000 { + compatible = "rockchip,px30-spi\0rockchip,rk3066-spi"; + reg = <0x00 0xff1d0000 0x00 0x1000>; + interrupts = <0x00 0x1a 0x04>; + #address-cells = <0x01>; + #size-cells = <0x00>; + clocks = <0x02 0x24 0x02 0x155>; + clock-names = "spiclk\0apb_pclk"; + dmas = <0x2b 0x0c 0x2b 0x0d>; + dma-names = "tx\0rx"; + pinctrl-names = "default\0high_speed"; + pinctrl-0 = <0x6c 0x6d 0x6e 0x6f>; + pinctrl-1 = <0x70 0x6d 0x71 0x72>; + status = "disabled"; + phandle = <0xf2>; + }; + + spi@ff1d8000 { + compatible = "rockchip,px30-spi\0rockchip,rk3066-spi"; + reg = <0x00 0xff1d8000 0x00 0x1000>; + interrupts = <0x00 0x1b 0x04>; + #address-cells = <0x01>; + #size-cells = <0x00>; + clocks = <0x02 0x25 0x02 0x156>; + clock-names = "spiclk\0apb_pclk"; + dmas = <0x2b 0x0e 0x2b 0x0f>; + dma-names = "tx\0rx"; + pinctrl-names = "default\0high_speed"; + pinctrl-0 = <0x73 0x74 0x75 0x76 0x77>; + pinctrl-1 = <0x78 0x74 0x75 0x79 0x7a>; + status = "disabled"; + phandle = <0xf3>; + }; + + watchdog@ff1e0000 { + compatible = "snps,dw-wdt"; + reg = <0x00 0xff1e0000 0x00 0x100>; + clocks = <0x02 0x15b>; + interrupts = <0x00 0x25 0x04>; + resets = <0x02 0xb5>; + reset-names = "reset"; + status = "disabled"; + phandle = <0xf4>; + }; + + pwm@ff200000 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200000 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7b>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "okay"; + phandle = <0xbc>; + }; + + pwm@ff200010 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200010 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7c>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "okay"; + phandle = <0xc2>; + }; + + pwm@ff200020 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200020 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7d>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf5>; + }; + + pwm@ff200030 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200030 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7e>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf6>; + }; + + pwm@ff208000 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208000 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7f>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf7>; + }; + + pwm@ff208010 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208010 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x80>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf8>; + }; + + pwm@ff208020 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208020 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x81>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf9>; + }; + + pwm@ff208030 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208030 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x82>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xfa>; + }; + + rktimer@ff210000 { + compatible = "rockchip,rk3288-timer"; + reg = <0x00 0xff210000 0x00 0x1000>; + interrupts = <0x00 0x1e 0x04>; + clocks = <0x02 0x159 0x02 0x26>; + clock-names = "pclk\0timer"; + phandle = <0xfb>; + }; + + amba { + compatible = "simple-bus"; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + + dmac@ff240000 { + compatible = "arm,pl330\0arm,primecell"; + reg = <0x00 0xff240000 0x00 0x4000>; + interrupts = <0x00 0x01 0x04 0x00 0x02 0x04>; + clocks = <0x02 0xbb>; + clock-names = "apb_pclk"; + #dma-cells = <0x01>; + peripherals-req-type-burst; + phandle = <0x2b>; + }; + }; + + thermal-zones { + phandle = <0xfc>; + + soc-thermal { + polling-delay-passive = <0x14>; + polling-delay = <0x3e8>; + sustainable-power = <0x2ee>; + thermal-sensors = <0x83 0x00>; + phandle = <0xfd>; + + trips { + + trip-point-0 { + temperature = <0x11170>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0xfe>; + }; + + trip-point-1 { + temperature = <0x14c08>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0x84>; + }; + + soc-crit { + temperature = <0x1c138>; + hysteresis = <0x7d0>; + type = "critical"; + phandle = <0xff>; + }; + }; + + cooling-maps { + + map0 { + trip = <0x84>; + cooling-device = <0x09 0xffffffff 0xffffffff>; + contribution = <0x1000>; + }; + + map1 { + trip = <0x84>; + cooling-device = <0x85 0xffffffff 0xffffffff>; + contribution = <0x1000>; + }; + }; + }; + + gpu-thermal { + polling-delay-passive = <0x64>; + polling-delay = <0x3e8>; + thermal-sensors = <0x83 0x01>; + phandle = <0x100>; + }; + }; + + tsadc@ff280000 { + compatible = "rockchip,px30-tsadc"; + reg = <0x00 0xff280000 0x00 0x100>; + interrupts = <0x00 0x24 0x04>; + rockchip,grf = <0x2f>; + clocks = <0x02 0x2c 0x02 0x158>; + clock-names = "tsadc\0apb_pclk"; + assigned-clocks = <0x02 0x2c>; + assigned-clock-rates = <0xc350>; + resets = <0x02 0xa8>; + reset-names = "tsadc-apb"; + #thermal-sensor-cells = <0x01>; + rockchip,hw-tshut-temp = <0x1d4c0>; + status = "okay"; + pinctrl-names = "gpio\0otpout"; + pinctrl-0 = <0x86>; + pinctrl-1 = <0x87>; + phandle = <0x83>; + }; + + saradc@ff288000 { + compatible = "rockchip,px30-saradc\0rockchip,rk3399-saradc"; + reg = <0x00 0xff288000 0x00 0x100>; + interrupts = <0x00 0x54 0x04>; + #io-channel-cells = <0x01>; + clocks = <0x02 0x2d 0x02 0x157>; + clock-names = "saradc\0apb_pclk"; + resets = <0x02 0xa5>; + reset-names = "saradc-apb"; + status = "okay"; + vref-supply = <0x88>; + phandle = <0xbe>; + }; + + otp@ff290000 { + compatible = "rockchip,px30-otp"; + reg = <0x00 0xff290000 0x00 0x4000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + clocks = <0x02 0x2f 0x02 0x15a 0x02 0x161>; + clock-names = "clk_otp\0pclk_otp\0pclk_otp_phy"; + resets = <0x02 0xb4>; + reset-names = "otp_phy"; + phandle = <0x101>; + + id@7 { + reg = <0x07 0x10>; + phandle = <0x0f>; + }; + + cpu-leakage@17 { + reg = <0x17 0x01>; + phandle = <0x07>; + }; + + performance@1e { + reg = <0x1e 0x01>; + bits = <0x04 0x03>; + phandle = <0x08>; + }; + }; + + clock-controller@ff2b0000 { + compatible = "rockchip,px30-cru"; + reg = <0x00 0xff2b0000 0x00 0x1000>; + rockchip,grf = <0x2f>; + rockchip,boost = <0x89>; + #clock-cells = <0x01>; + #reset-cells = <0x01>; + assigned-clocks = <0x02 0x04>; + assigned-clock-rates = <0x3dfd2400>; + phandle = <0x02>; + }; + + cpu-boost@ff2b8000 { + compatible = "syscon"; + reg = <0x00 0xff2b8000 0x00 0x1000>; + rockchip,boost-low-con0 = <0x1032>; + rockchip,boost-low-con1 = <0x1441>; + rockchip,boost-high-con0 = <0x1036>; + rockchip,boost-high-con1 = <0x1441>; + rockchip,boost-backup-pll = <0x01>; + rockchip,boost-backup-pll-usage = <0x00>; + rockchip,boost-switch-threshold = <0x249f00>; + rockchip,boost-statis-threshold = <0x100>; + rockchip,boost-statis-enable = <0x00>; + rockchip,boost-enable = <0x00>; + phandle = <0x89>; + }; + + pmu-clock-controller@ff2bc000 { + compatible = "rockchip,px30-pmucru"; + reg = <0x00 0xff2bc000 0x00 0x1000>; + rockchip,grf = <0x2f>; + #clock-cells = <0x01>; + #reset-cells = <0x01>; + assigned-clocks = <0x2a 0x01 0x2a 0x08 0x2a 0x05 0x02 0x07 0x02 0xab 0x02 0xb0 0x02 0xf0 0x02 0xf5 0x02 0x140 0x02 0x49>; + assigned-clock-rates = <0x47868c00 0x5f5e100 0x18cba80 0x23c34600 0xbebc200 0xbebc200 0x8f0d180 0x8f0d180 0x5f5e100 0xbebc200>; + phandle = <0x2a>; + }; + + syscon@ff2c0000 { + compatible = "rockchip,px30-usb2phy-grf\0syscon\0simple-mfd"; + reg = <0x00 0xff2c0000 0x00 0x10000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0x102>; + + usb2-phy@100 { + compatible = "rockchip,px30-usb2phy\0rockchip,rk3328-usb2phy"; + reg = <0x100 0x10>; + clocks = <0x2a 0x0a>; + clock-names = "phyclk"; + #clock-cells = <0x00>; + assigned-clocks = <0x02 0x0e 0x02 0x55>; + assigned-clock-parents = <0x67 0x02 0x0e>; + clock-output-names = "usb480m_phy"; + status = "okay"; + phandle = <0x67>; + + host-port { + #phy-cells = <0x00>; + interrupts = <0x00 0x44 0x04>; + interrupt-names = "linestate"; + status = "okay"; + phandle = <0x8c>; + }; + + otg-port { + #phy-cells = <0x00>; + interrupts = <0x00 0x42 0x04 0x00 0x41 0x04 0x00 0x40 0x04>; + interrupt-names = "otg-bvalid\0otg-id\0linestate"; + status = "disabled"; + phandle = <0x8b>; + }; + }; + }; + + video-phy@ff2e0000 { + compatible = "rockchip,px30-video-phy"; + reg = <0x00 0xff2e0000 0x00 0x10000 0x00 0xff450000 0x00 0x10000>; + clocks = <0x2a 0x0b 0x02 0x145 0x02 0x144>; + clock-names = "ref\0pclk_phy\0pclk_host"; + #clock-cells = <0x00>; + resets = <0x02 0x3e>; + reset-names = "rst"; + power-domains = <0x8a 0x0c>; + #phy-cells = <0x00>; + status = "okay"; + phandle = <0x4c>; + }; + + mipi-dphy-rx0@ff2f0000 { + compatible = "rockchip,rk3326-mipi-dphy"; + reg = <0x00 0xff2f0000 0x00 0x4000>; + clocks = <0x02 0x146>; + clock-names = "dphy-ref"; + power-domains = <0x8a 0x0d>; + rockchip,grf = <0x2f>; + status = "okay"; + phandle = <0x103>; + }; + + usb@ff300000 { + compatible = "rockchip,px30-usb\0rockchip,rk3066-usb\0snps,dwc2"; + reg = <0x00 0xff300000 0x00 0x40000>; + interrupts = <0x00 0x3e 0x04>; + clocks = <0x02 0x102>; + clock-names = "otg"; + power-domains = <0x8a 0x05>; + dr_mode = "otg"; + g-np-tx-fifo-size = <0x10>; + g-rx-fifo-size = <0x118>; + g-tx-fifo-size = <0x100 0x80 0x80 0x40 0x20 0x10>; + g-use-dma; + phys = <0x8b>; + phy-names = "usb2-phy"; + status = "okay"; + phandle = <0x104>; + }; + + usb@ff340000 { + compatible = "generic-ehci"; + reg = <0x00 0xff340000 0x00 0x10000>; + interrupts = <0x00 0x3c 0x04>; + clocks = <0x02 0x103 0x67>; + clock-names = "usbhost\0utmi"; + power-domains = <0x8a 0x05>; + phys = <0x8c>; + phy-names = "usb"; + status = "disabled"; + phandle = <0x105>; + }; + + usb@ff350000 { + compatible = "generic-ohci"; + reg = <0x00 0xff350000 0x00 0x10000>; + interrupts = <0x00 0x3d 0x04>; + clocks = <0x02 0x103 0x67>; + clock-names = "usbhost\0utmi"; + power-domains = <0x8a 0x05>; + phys = <0x8c>; + phy-names = "usb"; + status = "disabled"; + phandle = <0x106>; + }; + + ethernet@ff360000 { + compatible = "rockchip,px30-gmac"; + reg = <0x00 0xff360000 0x00 0x10000>; + rockchip,grf = <0x2f>; + interrupts = <0x00 0x2b 0x04>; + interrupt-names = "macirq"; + clocks = <0x02 0x3e 0x02 0x3f 0x02 0x3f 0x02 0x40 0x02 0x41 0x02 0xb2 0x02 0x143 0x02 0x4c>; + clock-names = "stmmaceth\0mac_clk_rx\0mac_clk_tx\0clk_mac_ref\0clk_mac_refout\0aclk_mac\0pclk_mac\0clk_mac_speed"; + phy-mode = "rmii"; + pinctrl-names = "default"; + pinctrl-0 = <0x8d 0x8e>; + resets = <0x02 0x5e>; + reset-names = "stmmaceth"; + power-domains = <0x8a 0x09>; + status = "disabled"; + phandle = <0x107>; + }; + + dwmmc@ff370000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff370000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0xf7 0x02 0x3b 0x02 0x43 0x02 0x44>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x3b>; + assigned-clock-parents = <0x02 0x57>; + power-domains = <0x8a 0x07>; + fifo-depth = <0x100>; + interrupts = <0x00 0x36 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x8f 0x90 0x91 0x92>; + status = "okay"; + bus-width = <0x04>; + cap-mmc-highspeed; + cap-sd-highspeed; + supports-sd; + card-detect-delay = <0x320>; + ignore-pm-notify; + cd-gpios = <0x5c 0x03 0x01>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <0x4a>; + vmmc-supply = <0x93>; + phandle = <0x108>; + }; + + dwmmc@ff380000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff380000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0xff 0x02 0x38 0x02 0x45 0x02 0x46>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x38>; + assigned-clock-parents = <0x02 0x51>; + power-domains = <0x8a 0x0a>; + fifo-depth = <0x100>; + interrupts = <0x00 0x37 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x94 0x95 0x96>; + status = "okay"; + bus-width = <0x04>; + cap-mmc-highspeed; + cap-sd-highspeed; + supports-sd; + card-detect-delay = <0x320>; + ignore-pm-notify; + cd-gpios = <0x97 0x0e 0x01>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <0x4a>; + vmmc-supply = <0x93>; + phandle = <0x109>; + }; + + dwmmc@ff390000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff390000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0x100 0x02 0x39 0x02 0x47 0x02 0x48>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x39>; + assigned-clock-parents = <0x02 0x53>; + power-domains = <0x8a 0x0a>; + fifo-depth = <0x100>; + interrupts = <0x00 0x35 0x04>; + status = "disabled"; + phandle = <0x10a>; + }; + + nandc@ff3b0000 { + compatible = "rockchip,rk-nandc"; + reg = <0x00 0xff3b0000 0x00 0x4000>; + interrupts = <0x00 0x39 0x04>; + nandc_id = <0x00>; + clocks = <0x02 0x37 0x02 0xfe>; + clock-names = "clk_nandc\0hclk_nandc"; + assigned-clocks = <0x02 0x37>; + assigned-clock-parents = <0x02 0x4f>; + power-domains = <0x8a 0x0a>; + status = "disabled"; + phandle = <0x10b>; + }; + + sfc@ff3a0000 { + compatible = "rockchip,sfc"; + reg = <0x00 0xff3a0000 0x00 0x4000>; + interrupts = <0x00 0x38 0x04>; + clocks = <0x02 0x3a 0x02 0x101>; + clock-names = "clk_sfc\0hclk_sfc"; + assigned-clocks = <0x02 0x3a>; + assigned-clock-rates = <0x989680>; + status = "disabled"; + phandle = <0x10c>; + }; + + gpu@ff400000 { + compatible = "arm,malit602\0arm,malit60x\0arm,malit6xx\0arm,mali-midgard"; + reg = <0x00 0xff400000 0x00 0x4000>; + interrupts = <0x00 0x2d 0x04 0x00 0x2e 0x04 0x00 0x2f 0x04>; + interrupt-names = "GPU\0MMU\0JOB"; + clocks = <0x02 0x49>; + clock-names = "clk_mali"; + power-domains = <0x8a 0x0e>; + #cooling-cells = <0x02>; + operating-points-v2 = <0x98>; + status = "okay"; + mali-supply = <0x0e>; + phandle = <0x85>; + + power_model { + compatible = "arm,mali-simple-power-model"; + static-coefficient = <0x64578>; + dynamic-coefficient = <0x2dd>; + ts = <0x7d00 0x125c 0xffffffb0 0x02>; + thermal-zone = "gpu-thermal"; + }; + }; + + gpu-opp-table { + compatible = "operating-points-v2"; + rockchip,thermal-zone = "soc-thermal"; + rockchip,temp-hysteresis = <0x1388>; + rockchip,low-temp = <0x00>; + rockchip,low-temp-min-volt = <0xf4240>; + rockchip,low-temp-adjust-volt = <0x00 0x1e0 0xc350>; + rockchip,max-volt = <0x11edd8>; + rockchip,evb-irdrop = <0x61a8>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-ch = <0x00 0x00>; + phandle = <0x98>; + + opp-400000000 { + opp-hz = <0x00 0x17d78400>; + opp-microvolt = <0x100590>; + opp-microvolt-L0 = <0x100590>; + opp-microvolt-L1 = <0xfa3e8>; + opp-microvolt-L2 = <0xee098>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-480000000 { + opp-hz = <0x00 0x1c9c3800>; + opp-microvolt = <0x112a88>; + opp-microvolt-L0 = <0x112a88>; + opp-microvolt-L1 = <0x10c8e0>; + opp-microvolt-L2 = <0x100590>; + opp-microvolt-L3 = <0xf4240>; + }; + + opp-520000000 { + opp-hz = <0x00 0x1efe9200>; + opp-microvolt = <0x118c30>; + opp-microvolt-L0 = <0x118c30>; + opp-microvolt-L1 = <0x118c30>; + opp-microvolt-L2 = <0x10c8e0>; + opp-microvolt-L3 = <0x100590>; + }; + }; + + hevc_service@ff440000 { + compatible = "rockchip,hevc_sub"; + iommu_enabled = <0x01>; + reg = <0x00 0xff440000 0x00 0x400>; + interrupts = <0x00 0x31 0x04>; + interrupt-names = "irq_dec"; + dev_mode = <0x01>; + iommus = <0x99>; + allocator = <0x01>; + phandle = <0x9c>; + }; + + vpu_service@ff442000 { + compatible = "rockchip,vpu_sub"; + iommu_enabled = <0x01>; + reg = <0x00 0xff442000 0x00 0x800>; + interrupts = <0x00 0x50 0x04 0x00 0x4f 0x04>; + interrupt-names = "irq_enc\0irq_dec"; + dev_mode = <0x00>; + iommus = <0x9a>; + allocator = <0x01>; + phandle = <0x9b>; + }; + + vpu_combo { + compatible = "rockchip,vpu_combo"; + subcnt = <0x02>; + rockchip,grf = <0x2f>; + rockchip,sub = <0x9b 0x9c>; + clocks = <0x02 0xaf 0x02 0xf4 0x02 0x4b>; + clock-names = "aclk_vcodec\0hclk_vcodec\0clk_core"; + resets = <0x02 0x24 0x02 0x26 0x02 0x25 0x02 0x27 0x02 0x3f>; + reset-names = "video_a\0video_h\0niu_a\0niu_h\0video_core"; + power-domains = <0x8a 0x0b>; + mode_bit = <0x0f>; + mode_ctrl = <0x410>; + status = "okay"; + phandle = <0x10d>; + }; + + iommu@ff440440 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff440440 0x00 0x40 0x00 0xff440480 0x00 0x40>; + interrupts = <0x00 0x32 0x04>; + interrupt-names = "hevc_mmu"; + clocks = <0x02 0xaf 0x02 0xf4>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0b>; + #iommu-cells = <0x00>; + phandle = <0x99>; + }; + + iommu@ff442800 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff442800 0x00 0x100>; + interrupts = <0x00 0x51 0x04>; + interrupt-names = "vpu_mmu"; + clocks = <0x02 0xaf 0x02 0xf4>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0b>; + #iommu-cells = <0x00>; + phandle = <0x9a>; + }; + + dsi@ff450000 { + compatible = "rockchip,px30-mipi-dsi"; + reg = <0x00 0xff450000 0x00 0x10000>; + interrupts = <0x00 0x4b 0x04>; + clocks = <0x02 0x144 0x4c>; + clock-names = "pclk\0hs_clk"; + resets = <0x02 0x3d>; + reset-names = "apb"; + phys = <0x4c>; + phy-names = "mipi_dphy"; + power-domains = <0x8a 0x0c>; + rockchip,grf = <0x2f>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + phandle = <0x10e>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x13>; + status = "okay"; + phandle = <0xa2>; + }; + }; + }; + + panel@0 { + compatible = "elida,kd35t133\0simple-panel-dsi"; + reg = <0x00>; + backlight = <0x9d>; + power-supply = <0x9e>; + reset-gpios = <0x97 0x10 0x01>; + prepare-delay-ms = <0x14>; + reset-delay-ms = <0x96>; + init-delay-ms = <0x14>; + enable-delay-ms = <0x78>; + disable-delay-ms = <0x32>; + unprepare-delay-ms = <0x14>; + width-mm = <0x34>; + height-mm = <0x46>; + dsi,flags = <0xa03>; + dsi,format = <0x00>; + dsi,lanes = <0x04>; + panel-init-sequence = [15 00 02 ee 01 15 00 02 ea 07 15 00 02 eb 12 15 00 02 0a 8b 15 00 02 17 35 15 00 02 1d 33 15 00 02 21 01 15 00 02 28 1c 15 00 02 29 27 15 00 02 2a 63 15 00 02 2b b5 15 00 02 2c 00 15 00 02 2d 33 15 00 02 2f f3 15 00 02 ee 02 15 00 02 39 78 15 00 02 39 78 15 00 02 00 00 15 00 02 01 18 15 00 02 02 15 15 00 02 03 10 15 00 02 04 18 15 00 02 05 3f 15 00 02 06 11 15 00 02 07 11 15 00 02 08 11 15 00 02 09 0f 15 00 02 0a 10 15 00 02 0b 54 15 00 02 0c 14 15 00 02 0d 17 15 00 02 0e 35 15 00 02 0f 37 15 00 02 10 3f 15 00 02 20 00 15 00 02 21 18 15 00 02 22 15 15 00 02 23 10 15 00 02 24 12 15 00 02 25 37 15 00 02 26 0b 15 00 02 27 0d 15 00 02 28 0d 15 00 02 29 0b 15 00 02 2a 10 15 00 02 2b 54 15 00 02 2c 14 15 00 02 2d 17 15 00 02 2e 35 15 00 02 2f 37 15 00 02 30 3f 15 00 02 ee 04 15 00 02 00 04 15 00 02 01 01 15 00 02 02 80 15 00 02 03 04 15 00 02 04 00 15 00 02 06 16 15 00 02 07 03 15 00 02 08 13 15 00 02 09 0a 15 00 02 0a 0f 15 00 02 0b 10 15 00 02 22 80 15 00 02 24 08 15 00 02 2a 00 15 00 02 ee 05 15 00 02 00 04 15 00 02 01 08 15 00 02 02 55 15 00 02 03 05 15 00 02 04 00 15 00 02 05 04 15 00 02 06 00 15 00 02 07 13 15 00 02 08 1e 15 00 02 09 66 15 00 02 0d 22 15 00 02 10 08 15 00 02 11 0c 15 00 02 12 55 15 00 02 13 05 15 00 02 19 14 15 00 02 1a 76 15 00 02 23 00 15 00 02 43 13 15 00 02 40 44 15 00 02 41 00 15 00 02 30 01 15 00 02 31 01 15 00 02 32 00 15 00 02 33 14 15 00 02 34 14 15 00 02 35 b4 15 00 02 36 01 15 00 02 37 01 15 00 02 38 00 15 00 02 39 14 15 00 02 3a 14 15 00 02 44 01 15 00 02 45 81 15 00 02 46 05 15 00 02 ee 06 15 00 02 00 23 15 00 02 01 01 15 00 02 02 04 15 00 02 06 cd 15 00 02 08 67 15 00 02 09 45 15 00 02 0a 23 15 00 02 0b 01 15 00 02 ee 07 15 00 02 00 3c 15 00 02 01 20 15 00 02 02 20 15 00 02 03 21 15 00 02 04 21 15 00 02 05 3c 15 00 02 06 3c 15 00 02 07 04 15 00 02 08 04 15 00 02 09 0c 15 00 02 0a 0c 15 00 02 0b 01 15 00 02 0c 15 15 00 02 0d 15 15 00 02 0e 17 15 00 02 0f 17 15 00 02 10 11 15 00 02 11 11 15 00 02 12 13 15 00 02 13 13 15 00 02 14 0d 15 00 02 15 0d 15 00 02 20 3c 15 00 02 21 20 15 00 02 22 20 15 00 02 23 21 15 00 02 24 21 15 00 02 25 3c 15 00 02 26 3c 15 00 02 27 04 15 00 02 28 04 15 00 02 29 0c 15 00 02 2a 0c 15 00 02 2b 00 15 00 02 2c 14 15 00 02 2d 14 15 00 02 2e 16 15 00 02 2f 16 15 00 02 30 10 15 00 02 31 10 15 00 02 32 12 15 00 02 33 12 15 00 02 34 0d 15 00 02 35 0d 15 00 02 ee 08 15 00 02 10 00 15 00 02 12 da 15 00 02 14 10 15 00 02 22 69 15 00 02 ee 0f 15 00 02 00 01 15 00 02 01 10 15 00 02 ee 00 15 00 02 ea 00 15 00 02 eb 00 05 c8 01 11 05 14 01 29]; + panel-exit-sequence = <0x5140128 0x50a0110>; + + display-timings { + native-mode = <0x9f>; + + 60Hz { + clock-frequency = <0x3938700>; + hactive = <0x400>; + vactive = <0x300>; + hfront-porch = <0x50>; + hsync-len = <0x3c>; + hback-porch = <0x3c>; + vfront-porch = <0x10>; + vsync-len = <0x08>; + vback-porch = <0x08>; + hsync-active = <0x00>; + vsync-active = <0x00>; + de-active = <0x00>; + pixelclk-active = <0x00>; + phandle = <0x9f>; + }; + }; + }; + }; + + vop@ff460000 { + compatible = "rockchip,px30-vop-big"; + reg = <0x00 0xff460000 0x00 0x1fc 0x00 0xff460a00 0x00 0x400>; + rockchip,grf = <0x2f>; + reg-names = "regs\0gamma_lut"; + interrupts = <0x00 0x4d 0x04>; + clocks = <0x02 0xb5 0x02 0x96 0x02 0xfb>; + clock-names = "aclk_vop\0dclk_vop\0hclk_vop"; + power-domains = <0x8a 0x0c>; + iommus = <0xa0>; + status = "okay"; + phandle = <0x10f>; + + port { + #address-cells = <0x01>; + #size-cells = <0x00>; + phandle = <0x10>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0xa1>; + phandle = <0x12>; + }; + + endpoint@1 { + reg = <0x01>; + remote-endpoint = <0xa2>; + phandle = <0x13>; + }; + + endpoint@2 { + reg = <0x02>; + remote-endpoint = <0xa3>; + phandle = <0x14>; + }; + }; + }; + + iommu@ff460f00 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff460f00 0x00 0x100>; + interrupts = <0x00 0x4d 0x04>; + interrupt-names = "vopb_mmu"; + clocks = <0x02 0xb5 0x02 0xfb>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0c>; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xa0>; + }; + + rk_rga@ff480000 { + compatible = "rockchip,rga2"; + reg = <0x00 0xff480000 0x00 0x1000>; + interrupts = <0x00 0x4c 0x04>; + clocks = <0x02 0xb7 0x02 0xfd 0x02 0x35>; + clock-names = "aclk_rga\0hclk_rga\0clk_rga"; + power-domains = <0x8a 0x0c>; + dma-coherent; + status = "okay"; + phandle = <0x110>; + }; + + cif@ff490000 { + compatible = "rockchip,cif"; + reg = <0x00 0xff490000 0x00 0x200>; + interrupts = <0x00 0x45 0x04>; + clocks = <0x02 0xb3 0x02 0xf9 0x02 0x160 0x02 0x34>; + clock-names = "aclk_cif0\0hclk_cif0\0pclk_cif\0cif0_out"; + resets = <0x02 0x2c 0x02 0x2d 0x02 0x2e>; + reset-names = "rst_cif_a\0rst_cif_h\0rst_cif_pclkin"; + power-domains = <0x8a 0x0d>; + pinctrl-names = "cif_pin_all"; + pinctrl-0 = <0xa4>; + iommus = <0xa5>; + status = "disabled"; + phandle = <0x111>; + }; + + cif-new@ff490000 { + compatible = "rockchip,px30-cif"; + reg = <0x00 0xff490000 0x00 0x200>; + interrupts = <0x00 0x45 0x04>; + clocks = <0x02 0xb3 0x02 0xf9 0x02 0x160 0x02 0x34>; + clock-names = "aclk_cif\0hclk_cif\0pclk_cif\0cif_out"; + resets = <0x02 0x2c 0x02 0x2d 0x02 0x2e>; + reset-names = "rst_cif_a\0rst_cif_h\0rst_cif_pclkin"; + power-domains = <0x8a 0x0d>; + iommus = <0xa5>; + status = "disabled"; + phandle = <0x112>; + }; + + iommu@ff490800 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff490800 0x00 0x100>; + interrupts = <0x00 0x45 0x04>; + interrupt-names = "vip_mmu"; + clocks = <0x02 0xb3 0x02 0xf9>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0d>; + rk_iommu,disable_reset_quirk; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xa5>; + }; + + rk_isp@ff4a0000 { + compatible = "rockchip,px30-isp\0rockchip,isp"; + reg = <0x00 0xff4a0000 0x00 0x8000>; + interrupts = <0x00 0x46 0x04>; + clocks = <0x02 0xb4 0x02 0xfa 0x02 0x33 0x02 0x33 0x02 0x15f 0x02 0x34 0x02 0x34 0x02 0x146>; + clock-names = "aclk_isp\0hclk_isp\0clk_isp\0clk_isp_jpe\0pclkin_isp\0clk_cif_pll\0clk_cif_out\0pclk_dphyrx"; + resets = <0x02 0x2b 0x02 0x2f>; + reset-names = "rst_isp\0rst_mipicsiphy"; + power-domains = <0x8a 0x0d>; + pinctrl-names = "default\0isp_dvp8bit2\0isp_dvp10bit\0isp_dvp12bit"; + pinctrl-0 = <0xa6>; + pinctrl-1 = <0xa4>; + pinctrl-2 = <0xa4 0xa7>; + pinctrl-3 = <0xa8 0xa4 0xa7>; + rockchip,isp,mipiphy = <0x01>; + rockchip,isp,csiphy,reg = <0xff2f0000 0x4000>; + rockchip,grf = <0x2f>; + rockchip,cru = <0x02>; + rockchip,isp,iommu-enable = <0x01>; + iommus = <0xa9>; + status = "disabled"; + phandle = <0x113>; + }; + + rkisp1@ff4a0000 { + compatible = "rockchip,rk3326-rkisp1"; + reg = <0x00 0xff4a0000 0x00 0x8000>; + interrupts = <0x00 0x46 0x04 0x00 0x49 0x04 0x00 0x4a 0x04>; + interrupt-names = "isp_irq\0mi_irq\0mipi_irq"; + clocks = <0x02 0xb4 0x02 0xfa 0x02 0x33 0x02 0x15f>; + clock-names = "aclk_isp\0hclk_isp\0clk_isp\0pclk_isp"; + devfreq = <0xaa>; + power-domains = <0x8a 0x0d>; + iommus = <0xa9>; + rockchip,grf = <0x2f>; + status = "okay"; + phandle = <0x114>; + }; + + iommu@ff4a8000 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff4a8000 0x00 0x100>; + interrupts = <0x00 0x46 0x04>; + interrupt-names = "isp_mmu"; + clocks = <0x02 0xb4 0x02 0xfa>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0d>; + rk_iommu,disable_reset_quirk; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xa9>; + }; + + qos@ff518000 { + compatible = "syscon"; + reg = <0x00 0xff518000 0x00 0x20>; + phandle = <0x18>; + }; + + qos@ff520000 { + compatible = "syscon"; + reg = <0x00 0xff520000 0x00 0x20>; + phandle = <0x28>; + }; + + qos@ff52c000 { + compatible = "syscon"; + reg = <0x00 0xff52c000 0x00 0x20>; + phandle = <0x17>; + }; + + qos@ff538000 { + compatible = "syscon"; + reg = <0x00 0xff538000 0x00 0x20>; + phandle = <0x19>; + }; + + qos@ff538080 { + compatible = "syscon"; + reg = <0x00 0xff538080 0x00 0x20>; + phandle = <0x1a>; + }; + + qos@ff538100 { + compatible = "syscon"; + reg = <0x00 0xff538100 0x00 0x20>; + phandle = <0x1b>; + }; + + qos@ff538180 { + compatible = "syscon"; + reg = <0x00 0xff538180 0x00 0x20>; + phandle = <0x1c>; + }; + + qos@ff540000 { + compatible = "syscon"; + reg = <0x00 0xff540000 0x00 0x20>; + phandle = <0x15>; + }; + + qos@ff540080 { + compatible = "syscon"; + reg = <0x00 0xff540080 0x00 0x20>; + phandle = <0x16>; + }; + + qos@ff548000 { + compatible = "syscon"; + reg = <0x00 0xff548000 0x00 0x20>; + phandle = <0x23>; + }; + + qos@ff548080 { + compatible = "syscon"; + reg = <0x00 0xff548080 0x00 0x20>; + phandle = <0x24>; + }; + + qos@ff548100 { + compatible = "syscon"; + reg = <0x00 0xff548100 0x00 0x20>; + phandle = <0x25>; + }; + + qos@ff548180 { + compatible = "syscon"; + reg = <0x00 0xff548180 0x00 0x20>; + phandle = <0x26>; + }; + + qos@ff548200 { + compatible = "syscon"; + reg = <0x00 0xff548200 0x00 0x20>; + phandle = <0x27>; + }; + + qos@ff550000 { + compatible = "syscon"; + reg = <0x00 0xff550000 0x00 0x20>; + phandle = <0x1f>; + }; + + qos@ff550080 { + compatible = "syscon"; + reg = <0x00 0xff550080 0x00 0x20>; + phandle = <0x20>; + }; + + qos@ff550100 { + compatible = "syscon"; + reg = <0x00 0xff550100 0x00 0x20>; + phandle = <0x21>; + }; + + qos@ff550180 { + compatible = "syscon"; + reg = <0x00 0xff550180 0x00 0x20>; + phandle = <0x22>; + }; + + qos@ff558000 { + compatible = "syscon"; + reg = <0x00 0xff558000 0x00 0x20>; + phandle = <0x1d>; + }; + + qos@ff558080 { + compatible = "syscon"; + reg = <0x00 0xff558080 0x00 0x20>; + phandle = <0x1e>; + }; + + dfi@ff610000 { + reg = <0x00 0xff610000 0x00 0x400>; + compatible = "rockchip,px30-dfi"; + rockchip,pmugrf = <0xab>; + status = "okay"; + phandle = <0xac>; + }; + + dmc { + compatible = "rockchip,px30-dmc"; + interrupts = <0x00 0x69 0x04>; + interrupt-names = "complete_irq"; + devfreq-events = <0xac>; + clocks = <0x02 0x54>; + clock-names = "dmc_clk"; + operating-points-v2 = <0xad>; + ddr_timing = <0xae>; + upthreshold = <0x28>; + downdifferential = <0x14>; + system-status-freq = <0x01 0x80e80 0x08 0x6ddd0 0x02 0x2f5d0 0x20 0x6ddd0 0x1000 0x80e80 0x4000 0xa2990 0x2000 0xa2990>; + auto-min-freq = <0x50140>; + auto-freq-en = <0x01>; + #cooling-cells = <0x02>; + status = "okay"; + center-supply = <0x0e>; + phandle = <0xaa>; + + ddr_power_model { + compatible = "ddr_power_model"; + dynamic-power-coefficient = <0x78>; + static-power-coefficient = <0xc8>; + ts = <0x7d00 0x125c 0xffffffb0 0x02>; + thermal-zone = "soc-thermal"; + phandle = <0x115>; + }; + }; + + dmc-opp-table { + compatible = "operating-points-v2"; + rockchip,max-volt = <0x118c30>; + rockchip,evb-irdrop = <0x61a8>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-ch = <0x00 0x00>; + phandle = <0xad>; + + opp-528000000 { + opp-hz = <0x00 0x1f78a400>; + opp-microvolt = <0xee098>; + opp-microvolt-L0 = <0xee098>; + opp-microvolt-L1 = <0xee098>; + opp-microvolt-L2 = <0xe7ef0>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-666000000 { + opp-hz = <0x00 0x27b25a80>; + opp-microvolt = <0x100590>; + opp-microvolt-L0 = <0x100590>; + opp-microvolt-L1 = <0xf4240>; + opp-microvolt-L2 = <0xee098>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-786000000 { + opp-hz = <0x00 0x2ed96880>; + opp-microvolt = <0x10c8e0>; + opp-microvolt-L0 = <0x10c8e0>; + opp-microvolt-L1 = <0x100590>; + opp-microvolt-L2 = <0xfa3e8>; + opp-microvolt-L3 = <0xf4240>; + status = "okay"; + }; + }; + + rockchip-system-monitor { + compatible = "rockchip,system-monitor"; + rockchip,thermal-zone = "soc-thermal"; + rockchip,polling-delay = <0xc8>; + phandle = <0x116>; + }; + + pinctrl { + compatible = "rockchip,px30-pinctrl"; + rockchip,grf = <0x2f>; + rockchip,pmu = <0xab>; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + phandle = <0x117>; + + gpio0@ff040000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff040000 0x00 0x100>; + interrupts = <0x00 0x03 0x04>; + clocks = <0x2a 0x14>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x5c>; + }; + + gpio1@ff250000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff250000 0x00 0x100>; + interrupts = <0x00 0x04 0x04>; + clocks = <0x02 0x15c>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0xbf>; + }; + + gpio2@ff260000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff260000 0x00 0x100>; + interrupts = <0x00 0x05 0x04>; + clocks = <0x02 0x15d>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x66>; + }; + + gpio3@ff270000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff270000 0x00 0x100>; + interrupts = <0x00 0x06 0x04>; + clocks = <0x02 0x15e>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x97>; + }; + + pcfg-pull-up { + bias-pull-up; + phandle = <0xb1>; + }; + + pcfg-pull-down { + bias-pull-down; + phandle = <0xb9>; + }; + + pcfg-pull-none { + bias-disable; + phandle = <0xb0>; + }; + + pcfg-pull-none-2ma { + bias-disable; + drive-strength = <0x02>; + phandle = <0x118>; + }; + + pcfg-pull-up-2ma { + bias-pull-up; + drive-strength = <0x02>; + phandle = <0x119>; + }; + + pcfg-pull-up-4ma { + bias-pull-up; + drive-strength = <0x04>; + phandle = <0xb2>; + }; + + pcfg-pull-none-4ma { + bias-disable; + drive-strength = <0x04>; + phandle = <0x11a>; + }; + + pcfg-pull-down-4ma { + bias-pull-down; + drive-strength = <0x04>; + phandle = <0x11b>; + }; + + pcfg-pull-none-8ma { + bias-disable; + drive-strength = <0x08>; + phandle = <0xb5>; + }; + + pcfg-pull-up-8ma { + bias-pull-up; + drive-strength = <0x08>; + phandle = <0xb3>; + }; + + pcfg-pull-none-12ma { + bias-disable; + drive-strength = <0x0c>; + phandle = <0xb7>; + }; + + pcfg-pull-up-12ma { + bias-pull-up; + drive-strength = <0x0c>; + phandle = <0xb6>; + }; + + pcfg-pull-none-smt { + bias-disable; + input-schmitt-enable; + phandle = <0xaf>; + }; + + pcfg-output-high { + output-high; + phandle = <0x11c>; + }; + + pcfg-output-low { + output-low; + phandle = <0xb8>; + }; + + pcfg-input-high { + bias-pull-up; + input-enable; + phandle = <0xb4>; + }; + + pcfg-input { + input-enable; + phandle = <0x11d>; + }; + + i2c0 { + + i2c0-xfer { + rockchip,pins = <0x00 0x08 0x01 0xaf 0x00 0x09 0x01 0xaf>; + phandle = <0x5b>; + }; + }; + + i2c1 { + + i2c1-xfer { + rockchip,pins = <0x00 0x12 0x01 0xaf 0x00 0x13 0x01 0xaf>; + phandle = <0x69>; + }; + }; + + i2c2 { + + i2c2-xfer { + rockchip,pins = <0x02 0x0f 0x02 0xaf 0x02 0x10 0x02 0xaf>; + phandle = <0x6a>; + }; + }; + + i2c3 { + + i2c3-xfer { + rockchip,pins = <0x01 0x0c 0x04 0xaf 0x01 0x0d 0x04 0xaf>; + phandle = <0x6b>; + }; + }; + + tsadc { + + tsadc-otp-gpio { + rockchip,pins = <0x00 0x06 0x00 0xb0>; + phandle = <0x86>; + }; + + tsadc-otp-out { + rockchip,pins = <0x00 0x06 0x01 0xb0>; + phandle = <0x87>; + }; + }; + + uart0 { + + uart0-xfer { + rockchip,pins = <0x00 0x0a 0x01 0xb1 0x00 0x0b 0x01 0xb1>; + phandle = <0x2c>; + }; + + uart0-cts { + rockchip,pins = <0x00 0x0c 0x01 0xb0>; + phandle = <0x2d>; + }; + + uart0-rts { + rockchip,pins = <0x00 0x0d 0x01 0xb0>; + phandle = <0x2e>; + }; + + uart0-rts-gpio { + rockchip,pins = <0x00 0x0d 0x00 0xb0>; + phandle = <0x11e>; + }; + }; + + uart1 { + + uart1-xfer { + rockchip,pins = <0x01 0x11 0x01 0xb1 0x01 0x10 0x01 0xb1>; + phandle = <0x4f>; + }; + + uart1-cts { + rockchip,pins = <0x01 0x12 0x01 0xb0>; + phandle = <0x50>; + }; + + uart1-rts { + rockchip,pins = <0x01 0x13 0x01 0xb0>; + phandle = <0x11f>; + }; + + uart1-rts-gpio { + rockchip,pins = <0x01 0x13 0x00 0xb0>; + phandle = <0x120>; + }; + }; + + uart2-m0 { + + uart2m0-xfer { + rockchip,pins = <0x01 0x1a 0x02 0xb1 0x01 0x1b 0x02 0xb1>; + phandle = <0x51>; + }; + }; + + uart2-m1 { + + uart2m1-xfer { + rockchip,pins = <0x02 0x0c 0x02 0xb1 0x02 0x0e 0x02 0xb1>; + phandle = <0xba>; + }; + }; + + uart3-m0 { + + uart3m0-xfer { + rockchip,pins = <0x00 0x10 0x02 0xb1 0x00 0x11 0x02 0xb1>; + phandle = <0x121>; + }; + + uart3m0-cts { + rockchip,pins = <0x00 0x12 0x02 0xb0>; + phandle = <0x122>; + }; + + uart3m0-rts { + rockchip,pins = <0x00 0x13 0x02 0xb0>; + phandle = <0x123>; + }; + + uart3m0-rts-gpio { + rockchip,pins = <0x00 0x13 0x00 0xb0>; + phandle = <0x124>; + }; + }; + + uart3-m1 { + + uart3m1-xfer { + rockchip,pins = <0x01 0x0e 0x02 0xb1 0x01 0x0f 0x02 0xb1>; + phandle = <0x52>; + }; + + uart3m1-cts { + rockchip,pins = <0x01 0x0c 0x02 0xb0>; + phandle = <0x53>; + }; + + uart3m1-rts { + rockchip,pins = <0x01 0x0d 0x02 0xb0>; + phandle = <0x54>; + }; + + uart3m1-rts-gpio { + rockchip,pins = <0x01 0x0d 0x00 0xb0>; + phandle = <0x125>; + }; + }; + + uart4 { + + uart4-xfer { + rockchip,pins = <0x01 0x1c 0x02 0xb1 0x01 0x1d 0x02 0xb1>; + phandle = <0x55>; + }; + + uart4-cts { + rockchip,pins = <0x01 0x1e 0x02 0xb0>; + phandle = <0x56>; + }; + + uart4-rts { + rockchip,pins = <0x01 0x1f 0x02 0xb0>; + phandle = <0x57>; + }; + }; + + uart5 { + + uart5-xfer { + rockchip,pins = <0x03 0x02 0x04 0xb1 0x03 0x01 0x04 0xb1>; + phandle = <0x58>; + }; + + uart5-cts { + rockchip,pins = <0x03 0x03 0x04 0xb0>; + phandle = <0x59>; + }; + + uart5-rts { + rockchip,pins = <0x03 0x05 0x04 0xb0>; + phandle = <0x5a>; + }; + }; + + spi0 { + + spi0-clk { + rockchip,pins = <0x01 0x0f 0x03 0xb2>; + phandle = <0x6c>; + }; + + spi0-csn { + rockchip,pins = <0x01 0x0e 0x03 0xb2>; + phandle = <0x6d>; + }; + + spi0-miso { + rockchip,pins = <0x01 0x0d 0x03 0xb2>; + phandle = <0x6e>; + }; + + spi0-mosi { + rockchip,pins = <0x01 0x0c 0x03 0xb2>; + phandle = <0x6f>; + }; + + spi0-clk-hs { + rockchip,pins = <0x01 0x0f 0x03 0xb3>; + phandle = <0x70>; + }; + + spi0-miso-hs { + rockchip,pins = <0x01 0x0d 0x03 0xb3>; + phandle = <0x71>; + }; + + spi0-mosi-hs { + rockchip,pins = <0x01 0x0c 0x03 0xb3>; + phandle = <0x72>; + }; + }; + + spi1 { + + spi1-clk { + rockchip,pins = <0x03 0x0f 0x04 0xb2>; + phandle = <0x73>; + }; + + spi1-csn0 { + rockchip,pins = <0x03 0x09 0x04 0xb2>; + phandle = <0x74>; + }; + + spi1-csn1 { + rockchip,pins = <0x03 0x0a 0x02 0xb2>; + phandle = <0x75>; + }; + + spi1-miso { + rockchip,pins = <0x03 0x0e 0x04 0xb2>; + phandle = <0x76>; + }; + + spi1-mosi { + rockchip,pins = <0x03 0x0c 0x04 0xb2>; + phandle = <0x77>; + }; + + spi1-clk-hs { + rockchip,pins = <0x03 0x0f 0x04 0xb3>; + phandle = <0x78>; + }; + + spi1-miso-hs { + rockchip,pins = <0x03 0x0e 0x04 0xb3>; + phandle = <0x79>; + }; + + spi1-mosi-hs { + rockchip,pins = <0x03 0x0c 0x04 0xb3>; + phandle = <0x7a>; + }; + }; + + pdm { + + pdm-clk0m0 { + rockchip,pins = <0x03 0x16 0x02 0xb0>; + phandle = <0x44>; + }; + + pdm-clk0m1 { + rockchip,pins = <0x02 0x16 0x01 0xb0>; + phandle = <0x126>; + }; + + pdm-clk1 { + rockchip,pins = <0x03 0x17 0x02 0xb0>; + phandle = <0x45>; + }; + + pdm-sdi0m0 { + rockchip,pins = <0x03 0x1b 0x02 0xb0>; + phandle = <0x46>; + }; + + pdm-sdi0m1 { + rockchip,pins = <0x02 0x15 0x02 0xb0>; + phandle = <0x127>; + }; + + pdm-sdi1 { + rockchip,pins = <0x03 0x18 0x02 0xb0>; + phandle = <0x47>; + }; + + pdm-sdi2 { + rockchip,pins = <0x03 0x19 0x02 0xb0>; + phandle = <0x48>; + }; + + pdm-sdi3 { + rockchip,pins = <0x03 0x1a 0x02 0xb0>; + phandle = <0x49>; + }; + + pdm-clk0m0-sleep { + rockchip,pins = <0x03 0x16 0x00 0xb4>; + phandle = <0x128>; + }; + + pdm-clk0m1-sleep { + rockchip,pins = <0x02 0x16 0x00 0xb4>; + phandle = <0x129>; + }; + + pdm-clk1-sleep { + rockchip,pins = <0x03 0x17 0x00 0xb4>; + phandle = <0x12a>; + }; + + pdm-sdi0m0-sleep { + rockchip,pins = <0x03 0x1b 0x00 0xb4>; + phandle = <0x12b>; + }; + + pdm-sdi0m1-sleep { + rockchip,pins = <0x02 0x15 0x00 0xb4>; + phandle = <0x12c>; + }; + + pdm-sdi1-sleep { + rockchip,pins = <0x03 0x18 0x00 0xb4>; + phandle = <0x12d>; + }; + + pdm-sdi2-sleep { + rockchip,pins = <0x03 0x19 0x00 0xb4>; + phandle = <0x12e>; + }; + + pdm-sdi3-sleep { + rockchip,pins = <0x03 0x1a 0x00 0xb4>; + phandle = <0x12f>; + }; + }; + + i2s0 { + + i2s0-8ch-mclk { + rockchip,pins = <0x03 0x11 0x02 0xb0>; + phandle = <0x130>; + }; + + i2s0-8ch-sclktx { + rockchip,pins = <0x03 0x13 0x02 0xb0>; + phandle = <0x30>; + }; + + i2s0-8ch-sclkrx { + rockchip,pins = <0x03 0x0c 0x02 0xb0>; + phandle = <0x31>; + }; + + i2s0-8ch-lrcktx { + rockchip,pins = <0x03 0x12 0x02 0xb0>; + phandle = <0x32>; + }; + + i2s0-8ch-lrckrx { + rockchip,pins = <0x03 0x0d 0x02 0xb0>; + phandle = <0x33>; + }; + + i2s0-8ch-sdo0 { + rockchip,pins = <0x03 0x14 0x02 0xb0>; + phandle = <0x38>; + }; + + i2s0-8ch-sdo1 { + rockchip,pins = <0x03 0x10 0x02 0xb0>; + phandle = <0x39>; + }; + + i2s0-8ch-sdo2 { + rockchip,pins = <0x03 0x0f 0x02 0xb0>; + phandle = <0x3a>; + }; + + i2s0-8ch-sdo3 { + rockchip,pins = <0x03 0x0e 0x02 0xb0>; + phandle = <0x3b>; + }; + + i2s0-8ch-sdi0 { + rockchip,pins = <0x03 0x15 0x02 0xb0>; + phandle = <0x34>; + }; + + i2s0-8ch-sdi1 { + rockchip,pins = <0x03 0x0b 0x02 0xb0>; + phandle = <0x35>; + }; + + i2s0-8ch-sdi2 { + rockchip,pins = <0x03 0x09 0x02 0xb0>; + phandle = <0x36>; + }; + + i2s0-8ch-sdi3 { + rockchip,pins = <0x03 0x08 0x02 0xb0>; + phandle = <0x37>; + }; + }; + + i2s1 { + + i2s1-2ch-mclk { + rockchip,pins = <0x02 0x13 0x01 0xb0>; + phandle = <0x68>; + }; + + i2s1-2ch-sclk { + rockchip,pins = <0x02 0x12 0x01 0xb0>; + phandle = <0x3c>; + }; + + i2s1-2ch-lrck { + rockchip,pins = <0x02 0x11 0x01 0xb0>; + phandle = <0x3d>; + }; + + i2s1-2ch-sdi { + rockchip,pins = <0x02 0x15 0x01 0xb0>; + phandle = <0x3e>; + }; + + i2s1-2ch-sdo { + rockchip,pins = <0x02 0x14 0x01 0xb0>; + phandle = <0x3f>; + }; + }; + + i2s2 { + + i2s2-2ch-mclk { + rockchip,pins = <0x03 0x01 0x02 0xb0>; + phandle = <0x131>; + }; + + i2s2-2ch-sclk { + rockchip,pins = <0x03 0x02 0x02 0xb0>; + phandle = <0x40>; + }; + + i2s2-2ch-lrck { + rockchip,pins = <0x03 0x03 0x02 0xb0>; + phandle = <0x41>; + }; + + i2s2-2ch-sdi { + rockchip,pins = <0x03 0x05 0x02 0xb0>; + phandle = <0x42>; + }; + + i2s2-2ch-sdo { + rockchip,pins = <0x03 0x07 0x02 0xb0>; + phandle = <0x43>; + }; + }; + + sdmmc { + + sdmmc-clk { + rockchip,pins = <0x01 0x1e 0x01 0xb5>; + phandle = <0x8f>; + }; + + sdmmc-cmd { + rockchip,pins = <0x01 0x1f 0x01 0xb3>; + phandle = <0x90>; + }; + + sdmmc-det { + rockchip,pins = <0x00 0x03 0x01 0xb3>; + phandle = <0x91>; + }; + + sdmmc-bus1 { + rockchip,pins = <0x01 0x1a 0x01 0xb3>; + phandle = <0x132>; + }; + + sdmmc-bus4 { + rockchip,pins = <0x01 0x1a 0x01 0xb3 0x01 0x1b 0x01 0xb3 0x01 0x1c 0x01 0xb3 0x01 0x1d 0x01 0xb3>; + phandle = <0x92>; + }; + + sdmmc-gpio { + rockchip,pins = <0x01 0x1a 0x00 0xb2 0x01 0x1b 0x00 0xb2 0x01 0x1c 0x00 0xb2 0x01 0x1d 0x00 0xb2 0x01 0x1e 0x00 0xb2 0x01 0x1f 0x00 0xb2>; + phandle = <0x133>; + }; + }; + + sdio { + + sdio-clk { + rockchip,pins = <0x01 0x15 0x01 0xb0>; + phandle = <0x96>; + }; + + sdio-cmd { + rockchip,pins = <0x01 0x14 0x01 0xb1>; + phandle = <0x95>; + }; + + sdio-bus4 { + rockchip,pins = <0x01 0x16 0x01 0xb1 0x01 0x17 0x01 0xb1 0x01 0x18 0x01 0xb1 0x01 0x19 0x01 0xb1>; + phandle = <0x94>; + }; + + sdio-gpio { + rockchip,pins = <0x01 0x16 0x00 0xb1 0x01 0x17 0x00 0xb1 0x01 0x18 0x00 0xb1 0x01 0x19 0x00 0xb1 0x01 0x14 0x00 0xb1 0x01 0x15 0x00 0xb1>; + phandle = <0x134>; + }; + }; + + emmc { + + emmc-clk { + rockchip,pins = <0x01 0x09 0x02 0xb5>; + phandle = <0x135>; + }; + + emmc-cmd { + rockchip,pins = <0x01 0x0a 0x02 0xb3>; + phandle = <0x136>; + }; + + emmc-pwren { + rockchip,pins = <0x01 0x08 0x02 0xb0>; + phandle = <0x137>; + }; + + emmc-rstnout { + rockchip,pins = <0x01 0x0b 0x02 0xb0>; + phandle = <0x138>; + }; + + emmc-bus1 { + rockchip,pins = <0x01 0x00 0x02 0xb3>; + phandle = <0x139>; + }; + + emmc-bus4 { + rockchip,pins = <0x01 0x00 0x02 0xb3 0x01 0x01 0x02 0xb3 0x01 0x02 0x02 0xb3 0x01 0x03 0x02 0xb3>; + phandle = <0x13a>; + }; + + emmc-bus8 { + rockchip,pins = <0x01 0x00 0x02 0xb3 0x01 0x01 0x02 0xb3 0x01 0x02 0x02 0xb3 0x01 0x03 0x02 0xb3 0x01 0x04 0x02 0xb3 0x01 0x05 0x02 0xb3 0x01 0x06 0x02 0xb3 0x01 0x07 0x02 0xb3>; + phandle = <0x13b>; + }; + }; + + flash { + + flash-cs0 { + rockchip,pins = <0x01 0x08 0x01 0xb0>; + phandle = <0x13c>; + }; + + flash-rdy { + rockchip,pins = <0x01 0x09 0x01 0xb0>; + phandle = <0x13d>; + }; + + flash-dqs { + rockchip,pins = <0x01 0x0a 0x01 0xb0>; + phandle = <0x13e>; + }; + + flash-ale { + rockchip,pins = <0x01 0x0b 0x01 0xb0>; + phandle = <0x13f>; + }; + + flash-cle { + rockchip,pins = <0x01 0x0c 0x01 0xb0>; + phandle = <0x140>; + }; + + flash-wrn { + rockchip,pins = <0x01 0x0d 0x01 0xb0>; + phandle = <0x141>; + }; + + flash-csl { + rockchip,pins = <0x01 0x0e 0x01 0xb0>; + phandle = <0x142>; + }; + + flash-rdn { + rockchip,pins = <0x01 0x0f 0x01 0xb0>; + phandle = <0x143>; + }; + + flash-bus8 { + rockchip,pins = <0x01 0x00 0x01 0xb6 0x01 0x01 0x01 0xb6 0x01 0x02 0x01 0xb6 0x01 0x03 0x01 0xb6 0x01 0x04 0x01 0xb6 0x01 0x05 0x01 0xb6 0x01 0x06 0x01 0xb6 0x01 0x07 0x01 0xb6>; + phandle = <0x144>; + }; + }; + + lcdc { + + lcdc-m0-rgb-pins { + rockchip,pins = <0x03 0x00 0x01 0xb5 0x03 0x01 0x01 0xb5 0x03 0x02 0x01 0xb5 0x03 0x03 0x01 0xb5 0x03 0x04 0x01 0xb5 0x03 0x05 0x01 0xb5 0x03 0x06 0x01 0xb5 0x03 0x07 0x01 0xb5 0x03 0x08 0x01 0xb5 0x03 0x09 0x01 0xb5 0x03 0x0a 0x01 0xb5 0x03 0x0b 0x01 0xb5 0x03 0x0c 0x01 0xb5 0x03 0x0d 0x01 0xb5 0x03 0x0e 0x01 0xb5 0x03 0x0f 0x01 0xb5 0x03 0x10 0x01 0xb5 0x03 0x11 0x01 0xb5 0x03 0x12 0x01 0xb5 0x03 0x13 0x01 0xb5 0x03 0x14 0x01 0xb5 0x03 0x15 0x01 0xb5 0x03 0x16 0x01 0xb5 0x03 0x17 0x01 0xb5 0x03 0x18 0x01 0xb5 0x03 0x19 0x01 0xb5 0x03 0x1a 0x01 0xb5 0x03 0x1b 0x01 0xb5>; + phandle = <0x145>; + }; + + lcdc-m0-sleep-pins { + rockchip,pins = <0x03 0x00 0x00 0xb0 0x03 0x01 0x00 0xb0 0x03 0x02 0x00 0xb0 0x03 0x03 0x00 0xb0 0x03 0x04 0x00 0xb0 0x03 0x05 0x00 0xb0 0x03 0x06 0x00 0xb0 0x03 0x07 0x00 0xb0 0x03 0x08 0x00 0xb0 0x03 0x09 0x00 0xb0 0x03 0x0a 0x00 0xb0 0x03 0x0b 0x00 0xb0 0x03 0x0c 0x00 0xb0 0x03 0x0d 0x00 0xb0 0x03 0x0e 0x00 0xb0 0x03 0x0f 0x00 0xb0 0x03 0x10 0x00 0xb0 0x03 0x11 0x00 0xb0 0x03 0x12 0x00 0xb0 0x03 0x13 0x00 0xb0 0x03 0x14 0x00 0xb0 0x03 0x15 0x00 0xb0 0x03 0x16 0x00 0xb0 0x03 0x17 0x00 0xb0 0x03 0x18 0x00 0xb0 0x03 0x19 0x00 0xb0 0x03 0x1a 0x00 0xb0 0x03 0x1b 0x00 0xb0>; + phandle = <0x146>; + }; + + lcdc-m1-rgb-pins { + rockchip,pins = <0x03 0x00 0x01 0xb5 0x03 0x04 0x01 0xb5 0x03 0x06 0x01 0xb5 0x03 0x0a 0x01 0xb5 0x03 0x0b 0x01 0xb5 0x03 0x0d 0x01 0xb5 0x03 0x10 0x01 0xb5 0x03 0x11 0x01 0xb5 0x03 0x12 0x01 0xb5 0x03 0x13 0x01 0xb5 0x03 0x14 0x01 0xb5 0x03 0x15 0x01 0xb5 0x03 0x16 0x01 0xb5 0x03 0x17 0x01 0xb5 0x03 0x18 0x01 0xb5 0x03 0x19 0x01 0xb5 0x03 0x1a 0x01 0xb5 0x03 0x1b 0x01 0xb5>; + phandle = <0x4d>; + }; + + lcdc-m1-sleep-pins { + rockchip,pins = <0x03 0x00 0x00 0xb0 0x03 0x04 0x00 0xb0 0x03 0x06 0x00 0xb0 0x03 0x0a 0x00 0xb0 0x03 0x0b 0x00 0xb0 0x03 0x0d 0x00 0xb0 0x03 0x10 0x00 0xb0 0x03 0x11 0x00 0xb0 0x03 0x12 0x00 0xb0 0x03 0x13 0x00 0xb0 0x03 0x14 0x00 0xb0 0x03 0x15 0x00 0xb0 0x03 0x16 0x00 0xb0 0x03 0x17 0x00 0xb0 0x03 0x18 0x00 0xb0 0x03 0x19 0x00 0xb0 0x03 0x1a 0x00 0xb0 0x03 0x1b 0x00 0xb0>; + phandle = <0x4e>; + }; + }; + + pwm0 { + + pwm0-pin { + rockchip,pins = <0x00 0x0f 0x01 0xb0>; + phandle = <0x7b>; + }; + }; + + pwm1 { + + pwm1-pin { + rockchip,pins = <0x00 0x10 0x01 0xb0>; + phandle = <0x7c>; + }; + }; + + pwm2 { + + pwm2-pin { + rockchip,pins = <0x02 0x0d 0x01 0xb0>; + phandle = <0x7d>; + }; + }; + + pwm3 { + + pwm3-pin { + rockchip,pins = <0x00 0x11 0x01 0xb0>; + phandle = <0x7e>; + }; + }; + + pwm4 { + + pwm4-pin { + rockchip,pins = <0x03 0x12 0x03 0xb0>; + phandle = <0x7f>; + }; + }; + + pwm5 { + + pwm5-pin { + rockchip,pins = <0x03 0x13 0x03 0xb0>; + phandle = <0x80>; + }; + }; + + pwm6 { + + pwm6-pin { + rockchip,pins = <0x03 0x14 0x03 0xb0>; + phandle = <0x81>; + }; + }; + + pwm7 { + + pwm7-pin { + rockchip,pins = <0x03 0x15 0x03 0xb0>; + phandle = <0x82>; + }; + }; + + gmac { + + rmii-pins { + rockchip,pins = <0x02 0x00 0x02 0xb7 0x02 0x01 0x02 0xb7 0x02 0x02 0x02 0xb7 0x02 0x03 0x02 0xb0 0x02 0x04 0x02 0xb0 0x02 0x05 0x02 0xb0 0x02 0x06 0x02 0xb0 0x02 0x07 0x02 0xb0 0x02 0x09 0x02 0xb0>; + phandle = <0x8d>; + }; + + mac-refclk-12ma { + rockchip,pins = <0x02 0x0a 0x02 0xb7>; + phandle = <0x8e>; + }; + + mac-refclk { + rockchip,pins = <0x02 0x0a 0x02 0xb0>; + phandle = <0x147>; + }; + }; + + cif-m0 { + + cif-clkout-m0 { + rockchip,pins = <0x02 0x0b 0x01 0xb7>; + phandle = <0xa6>; + }; + + dvp-d2d9-m0 { + rockchip,pins = <0x02 0x00 0x01 0xb0 0x02 0x01 0x01 0xb0 0x02 0x02 0x01 0xb0 0x02 0x03 0x01 0xb0 0x02 0x04 0x01 0xb0 0x02 0x05 0x01 0xb0 0x02 0x06 0x01 0xb0 0x02 0x07 0x01 0xb0 0x02 0x08 0x01 0xb0 0x02 0x09 0x01 0xb0 0x02 0x0a 0x01 0xb0 0x02 0x0b 0x01 0xb0>; + phandle = <0xa4>; + }; + + dvp-d0d1-m0 { + rockchip,pins = <0x02 0x0c 0x01 0xb0 0x02 0x0e 0x01 0xb0>; + phandle = <0xa8>; + }; + + d10-d11-m0 { + rockchip,pins = <0x02 0x0f 0x01 0xb0 0x02 0x10 0x01 0xb0>; + phandle = <0xa7>; + }; + }; + + cif-m1 { + + cif-clkout-m1 { + rockchip,pins = <0x03 0x18 0x03 0xb0>; + phandle = <0x148>; + }; + + dvp-d2d9-m1 { + rockchip,pins = <0x03 0x03 0x03 0xb0 0x03 0x05 0x03 0xb0 0x03 0x07 0x03 0xb0 0x03 0x08 0x03 0xb0 0x03 0x09 0x03 0xb0 0x03 0x0c 0x03 0xb0 0x03 0x0e 0x03 0xb0 0x03 0x0f 0x03 0xb0 0x03 0x19 0x03 0xb0 0x03 0x1a 0x03 0xb0 0x03 0x1b 0x03 0xb0 0x03 0x18 0x03 0xb0>; + phandle = <0x149>; + }; + + dvp-d0d1-m1 { + rockchip,pins = <0x03 0x01 0x03 0xb0 0x03 0x02 0x03 0xb0>; + phandle = <0x14a>; + }; + + d10-d11-m1 { + rockchip,pins = <0x03 0x16 0x03 0xb0 0x03 0x17 0x03 0xb0>; + phandle = <0x14b>; + }; + }; + + isp { + + isp-prelight { + rockchip,pins = <0x03 0x19 0x04 0xb0>; + phandle = <0x14c>; + }; + }; + + pmic { + + pmic_int { + rockchip,pins = <0x00 0x0a 0x00 0xb1 0x00 0x0b 0x00 0xb0>; + phandle = <0x5d>; + }; + + soc_slppin_gpio { + rockchip,pins = <0x00 0x04 0x00 0xb8>; + phandle = <0x60>; + }; + + soc_slppin_slp { + rockchip,pins = <0x00 0x04 0x01 0xb0>; + phandle = <0x5e>; + }; + + soc_slppin_rst { + rockchip,pins = <0x00 0x04 0x02 0xb0>; + phandle = <0x62>; + }; + }; + + leds { + + led-pins { + rockchip,pins = <0x00 0x11 0x00 0xb0>; + phandle = <0xc0>; + }; + }; + + motor { + + motor-pin { + rockchip,pins = <0x02 0x15 0x00 0xb9>; + phandle = <0xc1>; + }; + }; + + btns { + + btn-pins { + rockchip,pins = <0x01 0x0c 0x00 0xb1 0x01 0x0d 0x00 0xb1 0x01 0x0e 0x00 0xb1 0x01 0x0f 0x00 0xb1 0x01 0x02 0x00 0xb1 0x01 0x05 0x00 0xb1 0x01 0x06 0x00 0xb1 0x01 0x07 0x00 0xb1 0x02 0x00 0x00 0xb1 0x02 0x01 0x00 0xb1 0x02 0x02 0x00 0xb1 0x02 0x03 0x00 0xb1 0x02 0x04 0x00 0xb1 0x02 0x05 0x00 0xb1 0x02 0x06 0x00 0xb1 0x02 0x07 0x00 0xb1 0x03 0x09 0x00 0xb1 0x03 0x0a 0x00 0xb1 0x03 0x0c 0x00 0xb1 0x03 0x0f 0x00 0xb1>; + phandle = <0xbd>; + }; + }; + }; + + chosen { + bootargs = [00]; + }; + + fiq-debugger { + compatible = "rockchip,fiq-debugger"; + rockchip,serial-id = <0x02>; + rockchip,wake-irq = <0x00>; + rockchip,irq-mode-enable = <0x00>; + rockchip,baudrate = <0x1c200>; + interrupts = <0x00 0x7f 0x08>; + pinctrl-names = "default"; + pinctrl-0 = <0xba>; + status = "okay"; + }; + + ramoops { + compatible = "ramoops"; + record-size = <0x00 0x20000>; + console-size = <0x00 0x80000>; + ftrace-size = <0x00 0x00>; + pmsg-size = <0x00 0x00>; + memory-region = <0xbb>; + }; + + reserved-memory { + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + + drm-logo@00000000 { + compatible = "rockchip,drm-logo"; + reg = <0x00 0x00 0x00 0x00>; + phandle = <0x11>; + }; + + region@110000 { + reg = <0x00 0x110000 0x00 0xf0000>; + reg-names = "ramoops_mem"; + phandle = <0xbb>; + }; + }; + + odroidgo3-keys { + compatible = "gpio-keys"; + #address-cells = <0x01>; + #size-cells = <0x00>; + autorepeat; + phandle = <0x14d>; + + button@0 { + label = "GPIO BTN-VOLUP"; + linux,code = <0x73>; + gpios = <0x66 0x00 0x01>; + }; + + button@1 { + label = "GPIO BTN-VOLDN"; + linux,code = <0x72>; + gpios = <0x66 0x01 0x01>; + }; + }; + + odroidgo3-joypad { + compatible = "odroidgo3-joypad"; + pwms = <0xbc 0x00 0xbebc200 0x00>; + pwm-names = "enable"; + rumble-boost-weak = <0x00>; + rumble-boost-strong = <0x00>; + joypad-name = "GO-Super Gamepad"; + joypad-product = <0x1100>; + joypad-revision = <0x100>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <0xbd>; + pinctrl-1 = <0x7b>; + io-channel-names = "amux_adc"; + io-channels = <0xbe 0x01>; + amux-count = <0x04>; + amux-a-gpios = <0x97 0x0b 0x01>; + amux-b-gpios = <0x97 0x08 0x01>; + amux-en-gpios = <0x97 0x0d 0x01>; + button-adc-scale = <0x02>; + button-adc-deadzone = <0x40>; + button-adc-fuzz = <0x20>; + button-adc-flat = <0x20>; + abs_x-p-tuning = <0xc8>; + abs_x-n-tuning = <0xc8>; + abs_y-p-tuning = <0xc8>; + abs_y-n-tuning = <0xc8>; + abs_rx-p-tuning = <0xc8>; + abs_rx-n-tuning = <0xc8>; + abs_ry-p-tuning = <0xc8>; + abs_ry-n-tuning = <0xc8>; + poll-interval = <0x0a>; + invert-absx; + invert-absy; + phandle = <0x14e>; + + sw1 { + gpios = <0xbf 0x0c 0x01>; + label = "GPIO DPAD-UP"; + linux,code = <0x220>; + }; + + sw2 { + gpios = <0xbf 0x0d 0x01>; + label = "GPIO DPAD-DOWN"; + linux,code = <0x221>; + }; + + sw3 { + gpios = <0xbf 0x0e 0x01>; + label = "GPIO DPAD-LEFT"; + linux,code = <0x222>; + }; + + sw4 { + gpios = <0xbf 0x0f 0x01>; + label = "GPIO DPAD-RIGHT"; + linux,code = <0x223>; + }; + + sw5 { + gpios = <0xbf 0x02 0x01>; + label = "GPIO KEY BTN-A"; + linux,code = <0x131>; + }; + + sw6 { + gpios = <0xbf 0x05 0x01>; + label = "GPIO BTN-B"; + linux,code = <0x130>; + }; + + sw7 { + gpios = <0xbf 0x06 0x01>; + label = "GPIO BTN-Y"; + linux,code = <0x134>; + }; + + sw8 { + gpios = <0xbf 0x07 0x01>; + label = "GPIO BTN-X"; + linux,code = <0x133>; + }; + + sw11 { + gpios = <0x66 0x02 0x01>; + label = "GPIO F3"; + linux,code = <0x2c2>; + }; + + sw12 { + gpios = <0x66 0x03 0x01>; + label = "GPIO F4"; + linux,code = <0x2c3>; + }; + + sw13 { + gpios = <0x66 0x04 0x01>; + label = "GPIO F5"; + linux,code = <0x2c4>; + }; + + sw15 { + gpios = <0x66 0x06 0x01>; + label = "GPIO TOP-LEFT"; + linux,code = <0x136>; + }; + + sw16 { + gpios = <0x66 0x07 0x01>; + label = "GPIO TOP-RIGHT"; + linux,code = <0x137>; + }; + + sw19 { + gpios = <0x97 0x09 0x01>; + label = "GPIO F1"; + linux,code = <0x2c0>; + }; + + sw20 { + gpios = <0x97 0x0f 0x01>; + label = "GPIO TOP-RIGHT2"; + linux,code = <0x139>; + }; + + sw21 { + gpios = <0x97 0x0a 0x01>; + label = "GPIO TOP-LEFT2"; + linux,code = <0x138>; + }; + + sw22 { + gpios = <0x97 0x0c 0x01>; + label = "GPIO F2"; + linux,code = <0x2c1>; + }; + }; + + gpio_leds { + compatible = "gpio-leds"; + pinctrl-names = "led_pins"; + pinctrl-0 = <0xc0>; + phandle = <0x14f>; + + heartbeat { + label = "blue:heartbeat"; + gpios = <0x5c 0x11 0x00>; + linux,default-trigger = "heartbeat"; + }; + }; + + motor-control { + compatible = "gpio-motor"; + motor-gpios = <0x66 0x15 0x00>; + default-state = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <0xc1>; + status = "okay"; + phandle = <0x150>; + }; + + backlight { + compatible = "pwm-backlight"; + pwms = <0xc2 0x00 0x9c40 0x00>; + brightness-levels = <0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2a 0x2b 0x2c 0x2d 0x2e 0x2f 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x3a 0x3b 0x3c 0x3d 0x3e 0x3f 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48 0x49 0x4a 0x4b 0x4c 0x4d 0x4e 0x4f 0x50 0x51 0x52 0x53 0x54 0x55 0x56 0x57 0x58 0x59 0x5a 0x5b 0x5c 0x5d 0x5e 0x5f 0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69 0x6a 0x6b 0x6c 0x6d 0x6e 0x6f 0x70 0x71 0x72 0x73 0x74 0x75 0x76 0x77 0x78 0x79 0x7a 0x7b 0x7c 0x7d 0x7e 0x7f 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90 0x91 0x92 0x93 0x94 0x95 0x96 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f 0xa0>; + default-brightness-level = <0x50>; + power-supply = <0xc3>; + phandle = <0x9d>; + }; + + rk817-sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,name = "rockchip,rk817-codec"; + simple-audio-card,mclk-fs = <0x100>; + simple-audio-card,widgets = "Microphone\0Mic Jack\0Headphone\0Headphone Jack"; + simple-audio-card,routing = "MIC_IN\0Mic Jack\0Headphone Jack\0HPOL\0Headphone Jack\0HPOR"; + simple-audio-card,hp-det-gpio = <0x66 0x16 0x01>; + simple-audio-card,codec-hp-det = <0x01>; + + simple-audio-card,cpu { + sound-dai = <0xc4>; + }; + + simple-audio-card,codec { + sound-dai = <0xc5>; + }; + }; + + vccsys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v8_sys"; + regulator-always-on; + regulator-min-microvolt = <0x39fbc0>; + regulator-max-microvolt = <0x39fbc0>; + phandle = <0x64>; + }; + + __symbols__ { + ddr_timing = "/ddr_timing"; + cpu0 = "/cpus/cpu@0"; + cpu1 = "/cpus/cpu@1"; + cpu2 = "/cpus/cpu@2"; + cpu3 = "/cpus/cpu@3"; + CPU_SLEEP = "/cpus/idle-states/cpu-sleep"; + CLUSTER_SLEEP = "/cpus/idle-states/cluster-sleep"; + cpu0_opp_table = "/cpu0-opp-table"; + bus_soc = "/bus-soc"; + bus_apll = "/bus-apll"; + bus_apll_opp_table = "/bus-apll-opp-table"; + display_subsystem = "/display-subsystem"; + route_lvds = "/display-subsystem/route/route-lvds"; + route_dsi = "/display-subsystem/route/route-dsi"; + route_rgb = "/display-subsystem/route/route-rgb"; + gmac_clkin = "/external-gmac-clock"; + rockchip_suspend = "/rockchip-suspend"; + xin24m = "/xin24m"; + xin32k = "/xin32k"; + pmu = "/power-management@ff000000"; + power = "/power-management@ff000000/power-controller"; + pmugrf = "/syscon@ff010000"; + pmu_io_domains = "/syscon@ff010000/io-domains"; + pmu_pvtm = "/syscon@ff010000/pmu-pvtm"; + uart0 = "/serial@ff030000"; + i2s0_8ch = "/i2s@ff060000"; + i2s1_2ch = "/i2s@ff070000"; + i2s2_2ch = "/i2s@ff080000"; + pdm = "/pdm@ff0a0000"; + crypto = "/crypto@ff0b0000"; + rng = "/rng@ff0b0000"; + gic = "/interrupt-controller@ff131000"; + grf = "/syscon@ff140000"; + io_domains = "/syscon@ff140000/io-domains"; + lvds = "/syscon@ff140000/lvds"; + lvds_in_vopb = "/syscon@ff140000/lvds/ports/port@0/endpoint@0"; + rgb = "/syscon@ff140000/rgb"; + rgb_in_vopb = "/syscon@ff140000/rgb/ports/port@0/endpoint@0"; + core_grf = "/syscon@ff148000"; + pvtm = "/syscon@ff148000/pvtm"; + uart1 = "/serial@ff158000"; + uart2 = "/serial@ff160000"; + uart3 = "/serial@ff168000"; + uart4 = "/serial@ff170000"; + uart5 = "/serial@ff178000"; + i2c0 = "/i2c@ff180000"; + rk817 = "/i2c@ff180000/pmic@20"; + pinctrl_rk8xx = "/i2c@ff180000/pmic@20/pinctrl_rk8xx"; + rk817_ts_gpio1 = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_ts_gpio1"; + rk817_gt_gpio2 = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_gt_gpio2"; + rk817_pin_ts = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_pin_ts"; + rk817_pin_gt = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_pin_gt"; + rk817_slppin_null = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_null"; + rk817_slppin_slp = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_slp"; + rk817_slppin_pwrdn = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_pwrdn"; + rk817_slppin_rst = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_rst"; + vdd_logic = "/i2c@ff180000/pmic@20/regulators/DCDC_REG1"; + vdd_arm = "/i2c@ff180000/pmic@20/regulators/DCDC_REG2"; + vcc_ddr = "/i2c@ff180000/pmic@20/regulators/DCDC_REG3"; + vcc_3v3 = "/i2c@ff180000/pmic@20/regulators/DCDC_REG4"; + vcc_1v0 = "/i2c@ff180000/pmic@20/regulators/LDO_REG1"; + vcc1v8_soc = "/i2c@ff180000/pmic@20/regulators/LDO_REG2"; + vdd1v0_soc = "/i2c@ff180000/pmic@20/regulators/LDO_REG3"; + vcc3v3_pmu = "/i2c@ff180000/pmic@20/regulators/LDO_REG4"; + vccio_sd = "/i2c@ff180000/pmic@20/regulators/LDO_REG5"; + vcc_sd = "/i2c@ff180000/pmic@20/regulators/LDO_REG6"; + vcc_backlight = "/i2c@ff180000/pmic@20/regulators/LDO_REG7"; + vcc_lcd = "/i2c@ff180000/pmic@20/regulators/LDO_REG8"; + dcdc_boost = "/i2c@ff180000/pmic@20/regulators/BOOST"; + otg_switch = "/i2c@ff180000/pmic@20/regulators/OTG_SWITCH"; + rk817_codec = "/i2c@ff180000/pmic@20/codec"; + i2c1 = "/i2c@ff190000"; + i2c2 = "/i2c@ff1a0000"; + i2c3 = "/i2c@ff1b0000"; + spi0 = "/spi@ff1d0000"; + spi1 = "/spi@ff1d8000"; + wdt = "/watchdog@ff1e0000"; + pwm0 = "/pwm@ff200000"; + pwm1 = "/pwm@ff200010"; + pwm2 = "/pwm@ff200020"; + pwm3 = "/pwm@ff200030"; + pwm4 = "/pwm@ff208000"; + pwm5 = "/pwm@ff208010"; + pwm6 = "/pwm@ff208020"; + pwm7 = "/pwm@ff208030"; + rktimer = "/rktimer@ff210000"; + dmac = "/amba/dmac@ff240000"; + thermal_zones = "/thermal-zones"; + soc_thermal = "/thermal-zones/soc-thermal"; + threshold = "/thermal-zones/soc-thermal/trips/trip-point-0"; + target = "/thermal-zones/soc-thermal/trips/trip-point-1"; + soc_crit = "/thermal-zones/soc-thermal/trips/soc-crit"; + gpu_thermal = "/thermal-zones/gpu-thermal"; + tsadc = "/tsadc@ff280000"; + saradc = "/saradc@ff288000"; + otp = "/otp@ff290000"; + otp_id = "/otp@ff290000/id@7"; + cpu_leakage = "/otp@ff290000/cpu-leakage@17"; + performance = "/otp@ff290000/performance@1e"; + cru = "/clock-controller@ff2b0000"; + cpu_boost = "/cpu-boost@ff2b8000"; + pmucru = "/pmu-clock-controller@ff2bc000"; + usb2phy_grf = "/syscon@ff2c0000"; + u2phy = "/syscon@ff2c0000/usb2-phy@100"; + u2phy_host = "/syscon@ff2c0000/usb2-phy@100/host-port"; + u2phy_otg = "/syscon@ff2c0000/usb2-phy@100/otg-port"; + video_phy = "/video-phy@ff2e0000"; + mipi_dphy_rx0 = "/mipi-dphy-rx0@ff2f0000"; + usb20_otg = "/usb@ff300000"; + usb_host0_ehci = "/usb@ff340000"; + usb_host0_ohci = "/usb@ff350000"; + gmac = "/ethernet@ff360000"; + sdmmc = "/dwmmc@ff370000"; + sdio = "/dwmmc@ff380000"; + emmc = "/dwmmc@ff390000"; + nandc0 = "/nandc@ff3b0000"; + sfc = "/sfc@ff3a0000"; + gpu = "/gpu@ff400000"; + gpu_opp_table = "/gpu-opp-table"; + hevc = "/hevc_service@ff440000"; + vpu = "/vpu_service@ff442000"; + vpu_combo = "/vpu_combo"; + hevc_mmu = "/iommu@ff440440"; + vpu_mmu = "/iommu@ff442800"; + dsi = "/dsi@ff450000"; + dsi_in_vopb = "/dsi@ff450000/ports/port@0/endpoint@0"; + timing0 = "/dsi@ff450000/panel@0/display-timings/60Hz"; + vopb = "/vop@ff460000"; + vopb_out = "/vop@ff460000/port"; + vopb_out_lvds = "/vop@ff460000/port/endpoint@0"; + vopb_out_dsi = "/vop@ff460000/port/endpoint@1"; + vopb_out_rgb = "/vop@ff460000/port/endpoint@2"; + vopb_mmu = "/iommu@ff460f00"; + rk_rga = "/rk_rga@ff480000"; + cif = "/cif@ff490000"; + cif_new = "/cif-new@ff490000"; + vip_mmu = "/iommu@ff490800"; + rk_isp = "/rk_isp@ff4a0000"; + rkisp1 = "/rkisp1@ff4a0000"; + isp_mmu = "/iommu@ff4a8000"; + qos_gmac = "/qos@ff518000"; + qos_gpu = "/qos@ff520000"; + qos_sdmmc = "/qos@ff52c000"; + qos_emmc = "/qos@ff538000"; + qos_nand = "/qos@ff538080"; + qos_sdio = "/qos@ff538100"; + qos_sfc = "/qos@ff538180"; + qos_usb_host = "/qos@ff540000"; + qos_usb_otg = "/qos@ff540080"; + qos_isp_128 = "/qos@ff548000"; + qos_isp_rd = "/qos@ff548080"; + qos_isp_wr = "/qos@ff548100"; + qos_isp_m1 = "/qos@ff548180"; + qos_vip = "/qos@ff548200"; + qos_rga_rd = "/qos@ff550000"; + qos_rga_wr = "/qos@ff550080"; + qos_vop_m0 = "/qos@ff550100"; + qos_vop_m1 = "/qos@ff550180"; + qos_vpu = "/qos@ff558000"; + qos_vpu_r128 = "/qos@ff558080"; + dfi = "/dfi@ff610000"; + dmc = "/dmc"; + ddr_power_model = "/dmc/ddr_power_model"; + dmc_opp_table = "/dmc-opp-table"; + rockchip_system_monitor = "/rockchip-system-monitor"; + pinctrl = "/pinctrl"; + gpio0 = "/pinctrl/gpio0@ff040000"; + gpio1 = "/pinctrl/gpio1@ff250000"; + gpio2 = "/pinctrl/gpio2@ff260000"; + gpio3 = "/pinctrl/gpio3@ff270000"; + pcfg_pull_up = "/pinctrl/pcfg-pull-up"; + pcfg_pull_down = "/pinctrl/pcfg-pull-down"; + pcfg_pull_none = "/pinctrl/pcfg-pull-none"; + pcfg_pull_none_2ma = "/pinctrl/pcfg-pull-none-2ma"; + pcfg_pull_up_2ma = "/pinctrl/pcfg-pull-up-2ma"; + pcfg_pull_up_4ma = "/pinctrl/pcfg-pull-up-4ma"; + pcfg_pull_none_4ma = "/pinctrl/pcfg-pull-none-4ma"; + pcfg_pull_down_4ma = "/pinctrl/pcfg-pull-down-4ma"; + pcfg_pull_none_8ma = "/pinctrl/pcfg-pull-none-8ma"; + pcfg_pull_up_8ma = "/pinctrl/pcfg-pull-up-8ma"; + pcfg_pull_none_12ma = "/pinctrl/pcfg-pull-none-12ma"; + pcfg_pull_up_12ma = "/pinctrl/pcfg-pull-up-12ma"; + pcfg_pull_none_smt = "/pinctrl/pcfg-pull-none-smt"; + pcfg_output_high = "/pinctrl/pcfg-output-high"; + pcfg_output_low = "/pinctrl/pcfg-output-low"; + pcfg_input_high = "/pinctrl/pcfg-input-high"; + pcfg_input = "/pinctrl/pcfg-input"; + i2c0_xfer = "/pinctrl/i2c0/i2c0-xfer"; + i2c1_xfer = "/pinctrl/i2c1/i2c1-xfer"; + i2c2_xfer = "/pinctrl/i2c2/i2c2-xfer"; + i2c3_xfer = "/pinctrl/i2c3/i2c3-xfer"; + tsadc_otp_gpio = "/pinctrl/tsadc/tsadc-otp-gpio"; + tsadc_otp_out = "/pinctrl/tsadc/tsadc-otp-out"; + uart0_xfer = "/pinctrl/uart0/uart0-xfer"; + uart0_cts = "/pinctrl/uart0/uart0-cts"; + uart0_rts = "/pinctrl/uart0/uart0-rts"; + uart0_rts_gpio = "/pinctrl/uart0/uart0-rts-gpio"; + uart1_xfer = "/pinctrl/uart1/uart1-xfer"; + uart1_cts = "/pinctrl/uart1/uart1-cts"; + uart1_rts = "/pinctrl/uart1/uart1-rts"; + uart1_rts_gpio = "/pinctrl/uart1/uart1-rts-gpio"; + uart2m0_xfer = "/pinctrl/uart2-m0/uart2m0-xfer"; + uart2m1_xfer = "/pinctrl/uart2-m1/uart2m1-xfer"; + uart3m0_xfer = "/pinctrl/uart3-m0/uart3m0-xfer"; + uart3m0_cts = "/pinctrl/uart3-m0/uart3m0-cts"; + uart3m0_rts = "/pinctrl/uart3-m0/uart3m0-rts"; + uart3m0_rts_gpio = "/pinctrl/uart3-m0/uart3m0-rts-gpio"; + uart3m1_xfer = "/pinctrl/uart3-m1/uart3m1-xfer"; + uart3m1_cts = "/pinctrl/uart3-m1/uart3m1-cts"; + uart3m1_rts = "/pinctrl/uart3-m1/uart3m1-rts"; + uart3m1_rts_gpio = "/pinctrl/uart3-m1/uart3m1-rts-gpio"; + uart4_xfer = "/pinctrl/uart4/uart4-xfer"; + uart4_cts = "/pinctrl/uart4/uart4-cts"; + uart4_rts = "/pinctrl/uart4/uart4-rts"; + uart5_xfer = "/pinctrl/uart5/uart5-xfer"; + uart5_cts = "/pinctrl/uart5/uart5-cts"; + uart5_rts = "/pinctrl/uart5/uart5-rts"; + spi0_clk = "/pinctrl/spi0/spi0-clk"; + spi0_csn = "/pinctrl/spi0/spi0-csn"; + spi0_miso = "/pinctrl/spi0/spi0-miso"; + spi0_mosi = "/pinctrl/spi0/spi0-mosi"; + spi0_clk_hs = "/pinctrl/spi0/spi0-clk-hs"; + spi0_miso_hs = "/pinctrl/spi0/spi0-miso-hs"; + spi0_mosi_hs = "/pinctrl/spi0/spi0-mosi-hs"; + spi1_clk = "/pinctrl/spi1/spi1-clk"; + spi1_csn0 = "/pinctrl/spi1/spi1-csn0"; + spi1_csn1 = "/pinctrl/spi1/spi1-csn1"; + spi1_miso = "/pinctrl/spi1/spi1-miso"; + spi1_mosi = "/pinctrl/spi1/spi1-mosi"; + spi1_clk_hs = "/pinctrl/spi1/spi1-clk-hs"; + spi1_miso_hs = "/pinctrl/spi1/spi1-miso-hs"; + spi1_mosi_hs = "/pinctrl/spi1/spi1-mosi-hs"; + pdm_clk0m0 = "/pinctrl/pdm/pdm-clk0m0"; + pdm_clk0m1 = "/pinctrl/pdm/pdm-clk0m1"; + pdm_clk1 = "/pinctrl/pdm/pdm-clk1"; + pdm_sdi0m0 = "/pinctrl/pdm/pdm-sdi0m0"; + pdm_sdi0m1 = "/pinctrl/pdm/pdm-sdi0m1"; + pdm_sdi1 = "/pinctrl/pdm/pdm-sdi1"; + pdm_sdi2 = "/pinctrl/pdm/pdm-sdi2"; + pdm_sdi3 = "/pinctrl/pdm/pdm-sdi3"; + pdm_clk0m0_sleep = "/pinctrl/pdm/pdm-clk0m0-sleep"; + pdm_clk0m_sleep1 = "/pinctrl/pdm/pdm-clk0m1-sleep"; + pdm_clk1_sleep = "/pinctrl/pdm/pdm-clk1-sleep"; + pdm_sdi0m0_sleep = "/pinctrl/pdm/pdm-sdi0m0-sleep"; + pdm_sdi0m1_sleep = "/pinctrl/pdm/pdm-sdi0m1-sleep"; + pdm_sdi1_sleep = "/pinctrl/pdm/pdm-sdi1-sleep"; + pdm_sdi2_sleep = "/pinctrl/pdm/pdm-sdi2-sleep"; + pdm_sdi3_sleep = "/pinctrl/pdm/pdm-sdi3-sleep"; + i2s0_8ch_mclk = "/pinctrl/i2s0/i2s0-8ch-mclk"; + i2s0_8ch_sclktx = "/pinctrl/i2s0/i2s0-8ch-sclktx"; + i2s0_8ch_sclkrx = "/pinctrl/i2s0/i2s0-8ch-sclkrx"; + i2s0_8ch_lrcktx = "/pinctrl/i2s0/i2s0-8ch-lrcktx"; + i2s0_8ch_lrckrx = "/pinctrl/i2s0/i2s0-8ch-lrckrx"; + i2s0_8ch_sdo0 = "/pinctrl/i2s0/i2s0-8ch-sdo0"; + i2s0_8ch_sdo1 = "/pinctrl/i2s0/i2s0-8ch-sdo1"; + i2s0_8ch_sdo2 = "/pinctrl/i2s0/i2s0-8ch-sdo2"; + i2s0_8ch_sdo3 = "/pinctrl/i2s0/i2s0-8ch-sdo3"; + i2s0_8ch_sdi0 = "/pinctrl/i2s0/i2s0-8ch-sdi0"; + i2s0_8ch_sdi1 = "/pinctrl/i2s0/i2s0-8ch-sdi1"; + i2s0_8ch_sdi2 = "/pinctrl/i2s0/i2s0-8ch-sdi2"; + i2s0_8ch_sdi3 = "/pinctrl/i2s0/i2s0-8ch-sdi3"; + i2s1_2ch_mclk = "/pinctrl/i2s1/i2s1-2ch-mclk"; + i2s1_2ch_sclk = "/pinctrl/i2s1/i2s1-2ch-sclk"; + i2s1_2ch_lrck = "/pinctrl/i2s1/i2s1-2ch-lrck"; + i2s1_2ch_sdi = "/pinctrl/i2s1/i2s1-2ch-sdi"; + i2s1_2ch_sdo = "/pinctrl/i2s1/i2s1-2ch-sdo"; + i2s2_2ch_mclk = "/pinctrl/i2s2/i2s2-2ch-mclk"; + i2s2_2ch_sclk = "/pinctrl/i2s2/i2s2-2ch-sclk"; + i2s2_2ch_lrck = "/pinctrl/i2s2/i2s2-2ch-lrck"; + i2s2_2ch_sdi = "/pinctrl/i2s2/i2s2-2ch-sdi"; + i2s2_2ch_sdo = "/pinctrl/i2s2/i2s2-2ch-sdo"; + sdmmc_clk = "/pinctrl/sdmmc/sdmmc-clk"; + sdmmc_cmd = "/pinctrl/sdmmc/sdmmc-cmd"; + sdmmc_det = "/pinctrl/sdmmc/sdmmc-det"; + sdmmc_bus1 = "/pinctrl/sdmmc/sdmmc-bus1"; + sdmmc_bus4 = "/pinctrl/sdmmc/sdmmc-bus4"; + sdmmc_gpio = "/pinctrl/sdmmc/sdmmc-gpio"; + sdio_clk = "/pinctrl/sdio/sdio-clk"; + sdio_cmd = "/pinctrl/sdio/sdio-cmd"; + sdio_bus4 = "/pinctrl/sdio/sdio-bus4"; + sdio_gpio = "/pinctrl/sdio/sdio-gpio"; + emmc_clk = "/pinctrl/emmc/emmc-clk"; + emmc_cmd = "/pinctrl/emmc/emmc-cmd"; + emmc_pwren = "/pinctrl/emmc/emmc-pwren"; + emmc_rstnout = "/pinctrl/emmc/emmc-rstnout"; + emmc_bus1 = "/pinctrl/emmc/emmc-bus1"; + emmc_bus4 = "/pinctrl/emmc/emmc-bus4"; + emmc_bus8 = "/pinctrl/emmc/emmc-bus8"; + flash_cs0 = "/pinctrl/flash/flash-cs0"; + flash_rdy = "/pinctrl/flash/flash-rdy"; + flash_dqs = "/pinctrl/flash/flash-dqs"; + flash_ale = "/pinctrl/flash/flash-ale"; + flash_cle = "/pinctrl/flash/flash-cle"; + flash_wrn = "/pinctrl/flash/flash-wrn"; + flash_csl = "/pinctrl/flash/flash-csl"; + flash_rdn = "/pinctrl/flash/flash-rdn"; + flash_bus8 = "/pinctrl/flash/flash-bus8"; + lcdc_m0_rgb_pins = "/pinctrl/lcdc/lcdc-m0-rgb-pins"; + lcdc_m0_sleep_pins = "/pinctrl/lcdc/lcdc-m0-sleep-pins"; + lcdc_m1_rgb_pins = "/pinctrl/lcdc/lcdc-m1-rgb-pins"; + lcdc_m1_sleep_pins = "/pinctrl/lcdc/lcdc-m1-sleep-pins"; + pwm0_pin = "/pinctrl/pwm0/pwm0-pin"; + pwm1_pin = "/pinctrl/pwm1/pwm1-pin"; + pwm2_pin = "/pinctrl/pwm2/pwm2-pin"; + pwm3_pin = "/pinctrl/pwm3/pwm3-pin"; + pwm4_pin = "/pinctrl/pwm4/pwm4-pin"; + pwm5_pin = "/pinctrl/pwm5/pwm5-pin"; + pwm6_pin = "/pinctrl/pwm6/pwm6-pin"; + pwm7_pin = "/pinctrl/pwm7/pwm7-pin"; + rmii_pins = "/pinctrl/gmac/rmii-pins"; + mac_refclk_12ma = "/pinctrl/gmac/mac-refclk-12ma"; + mac_refclk = "/pinctrl/gmac/mac-refclk"; + cif_clkout_m0 = "/pinctrl/cif-m0/cif-clkout-m0"; + dvp_d2d9_m0 = "/pinctrl/cif-m0/dvp-d2d9-m0"; + dvp_d0d1_m0 = "/pinctrl/cif-m0/dvp-d0d1-m0"; + dvp_d10d11_m0 = "/pinctrl/cif-m0/d10-d11-m0"; + cif_clkout_m1 = "/pinctrl/cif-m1/cif-clkout-m1"; + dvp_d2d9_m1 = "/pinctrl/cif-m1/dvp-d2d9-m1"; + dvp_d0d1_m1 = "/pinctrl/cif-m1/dvp-d0d1-m1"; + dvp_d10d11_m1 = "/pinctrl/cif-m1/d10-d11-m1"; + isp_prelight = "/pinctrl/isp/isp-prelight"; + pmic_int = "/pinctrl/pmic/pmic_int"; + soc_slppin_gpio = "/pinctrl/pmic/soc_slppin_gpio"; + soc_slppin_slp = "/pinctrl/pmic/soc_slppin_slp"; + soc_slppin_rst = "/pinctrl/pmic/soc_slppin_rst"; + led_pins = "/pinctrl/leds/led-pins"; + motor_pin = "/pinctrl/motor/motor-pin"; + btn_pins = "/pinctrl/btns/btn-pins"; + drm_logo = "/reserved-memory/drm-logo@00000000"; + ramoops_mem = "/reserved-memory/region@110000"; + gpio_keys = "/odroidgo3-keys"; + joypad = "/odroidgo3-joypad"; + leds = "/gpio_leds"; + motor = "/motor-control"; + backlight = "/backlight"; + vccsys = "/vccsys"; + }; +}; diff --git a/config/archr-dts/R36S-DTB/DTS/RGB20S.dts b/config/archr-dts/R36S-DTB/DTS/RGB20S.dts new file mode 100644 index 0000000000..053f31bcc2 --- /dev/null +++ b/config/archr-dts/R36S-DTB/DTS/RGB20S.dts @@ -0,0 +1,4053 @@ +/dts-v1/; + +/ { + compatible = "rockchip,rk3326-odroidgo3-linux\0rockchip,rk3326"; + interrupt-parent = <0x01>; + #address-cells = <0x02>; + #size-cells = <0x02>; + model = "Hardkernel ODROID-GO3"; + + ddr_timing { + compatible = "rockchip,ddr-timing"; + ddr2_speed_bin = <0x00>; + ddr3_speed_bin = <0x15>; + ddr4_speed_bin = <0x0c>; + pd_idle = <0x0d>; + sr_idle = <0x5d>; + sr_mc_gate_idle = <0x00>; + srpd_lite_idle = <0x00>; + standby_idle = <0x00>; + auto_pd_dis_freq = <0x42a>; + auto_sr_dis_freq = <0x320>; + ddr2_dll_dis_freq = <0x12c>; + ddr3_dll_dis_freq = <0x12c>; + ddr4_dll_dis_freq = <0x271>; + phy_dll_dis_freq = <0x190>; + ddr2_odt_dis_freq = <0x64>; + phy_ddr2_odt_dis_freq = <0x64>; + ddr2_drv = <0x01>; + ddr2_odt = <0x96>; + phy_ddr2_ca_drv = <0x15>; + phy_ddr2_ck_drv = <0x12>; + phy_ddr2_dq_drv = <0x15>; + phy_ddr2_odt = <0x02>; + ddr3_odt_dis_freq = <0x190>; + phy_ddr3_odt_dis_freq = <0x190>; + ddr3_drv = <0x28>; + ddr3_odt = <0x78>; + phy_ddr3_ca_drv = <0x15>; + phy_ddr3_ck_drv = <0x12>; + phy_ddr3_dq_drv = <0x15>; + phy_ddr3_odt = <0x02>; + phy_lpddr2_odt_dis_freq = <0x29a>; + lpddr2_drv = <0x28>; + phy_lpddr2_ca_drv = <0x16>; + phy_lpddr2_ck_drv = <0x13>; + phy_lpddr2_dq_drv = <0x16>; + phy_lpddr2_odt = <0x00>; + lpddr3_odt_dis_freq = <0x190>; + phy_lpddr3_odt_dis_freq = <0x190>; + lpddr3_drv = <0x28>; + lpddr3_odt = <0xf0>; + phy_lpddr3_ca_drv = <0x16>; + phy_lpddr3_ck_drv = <0x13>; + phy_lpddr3_dq_drv = <0x16>; + phy_lpddr3_odt = <0x02>; + lpddr4_odt_dis_freq = <0x320>; + phy_lpddr4_odt_dis_freq = <0x320>; + lpddr4_drv = <0x3c>; + lpddr4_dq_odt = <0x28>; + lpddr4_ca_odt = <0x28>; + phy_lpddr4_ca_drv = <0x14>; + phy_lpddr4_ck_cs_drv = <0x06>; + phy_lpddr4_dq_drv = <0x06>; + phy_lpddr4_odt = <0x10>; + ddr4_odt_dis_freq = <0x29a>; + phy_ddr4_odt_dis_freq = <0x29a>; + ddr4_drv = <0x22>; + ddr4_odt = <0xf0>; + phy_ddr4_ca_drv = <0x16>; + phy_ddr4_ck_drv = <0x13>; + phy_ddr4_dq_drv = <0x16>; + phy_ddr4_odt = <0x02>; + ddr3a1_ddr4a9_de-skew = <0x06>; + ddr3a0_ddr4a10_de-skew = <0x07>; + ddr3a3_ddr4a6_de-skew = <0x07>; + ddr3a2_ddr4a4_de-skew = <0x07>; + ddr3a5_ddr4a8_de-skew = <0x07>; + ddr3a4_ddr4a5_de-skew = <0x07>; + ddr3a7_ddr4a11_de-skew = <0x07>; + ddr3a6_ddr4a7_de-skew = <0x06>; + ddr3a9_ddr4a0_de-skew = <0x07>; + ddr3a8_ddr4a13_de-skew = <0x07>; + ddr3a11_ddr4a3_de-skew = <0x07>; + ddr3a10_ddr4cs0_de-skew = <0x07>; + ddr3a13_ddr4a2_de-skew = <0x07>; + ddr3a12_ddr4ba1_de-skew = <0x07>; + ddr3a15_ddr4odt0_de-skew = <0x07>; + ddr3a14_ddr4a1_de-skew = <0x07>; + ddr3ba1_ddr4a15_de-skew = <0x07>; + ddr3ba0_ddr4bg0_de-skew = <0x07>; + ddr3ras_ddr4cke_de-skew = <0x07>; + ddr3ba2_ddr4ba0_de-skew = <0x07>; + ddr3we_ddr4bg1_de-skew = <0x07>; + ddr3cas_ddr4a12_de-skew = <0x07>; + ddr3ckn_ddr4ckn_de-skew = <0x07>; + ddr3ckp_ddr4ckp_de-skew = <0x07>; + ddr3cke_ddr4a16_de-skew = <0x07>; + ddr3odt0_ddr4a14_de-skew = <0x07>; + ddr3cs0_ddr4act_de-skew = <0x06>; + ddr3reset_ddr4reset_de-skew = <0x07>; + ddr3cs1_ddr4cs1_de-skew = <0x06>; + ddr3odt1_ddr4odt1_de-skew = <0x07>; + cs0_dm0_rx_de-skew = <0x07>; + cs0_dm0_tx_de-skew = <0x07>; + cs0_dq0_rx_de-skew = <0x08>; + cs0_dq0_tx_de-skew = <0x08>; + cs0_dq1_rx_de-skew = <0x09>; + cs0_dq1_tx_de-skew = <0x08>; + cs0_dq2_rx_de-skew = <0x08>; + cs0_dq2_tx_de-skew = <0x08>; + cs0_dq3_rx_de-skew = <0x08>; + cs0_dq3_tx_de-skew = <0x08>; + cs0_dq4_rx_de-skew = <0x09>; + cs0_dq4_tx_de-skew = <0x08>; + cs0_dq5_rx_de-skew = <0x09>; + cs0_dq5_tx_de-skew = <0x08>; + cs0_dq6_rx_de-skew = <0x09>; + cs0_dq6_tx_de-skew = <0x08>; + cs0_dq7_rx_de-skew = <0x08>; + cs0_dq7_tx_de-skew = <0x08>; + cs0_dqs0_rx_de-skew = <0x06>; + cs0_dqs0p_tx_de-skew = <0x09>; + cs0_dqs0n_tx_de-skew = <0x09>; + cs0_dm1_rx_de-skew = <0x07>; + cs0_dm1_tx_de-skew = <0x06>; + cs0_dq8_rx_de-skew = <0x08>; + cs0_dq8_tx_de-skew = <0x07>; + cs0_dq9_rx_de-skew = <0x09>; + cs0_dq9_tx_de-skew = <0x07>; + cs0_dq10_rx_de-skew = <0x08>; + cs0_dq10_tx_de-skew = <0x08>; + cs0_dq11_rx_de-skew = <0x08>; + cs0_dq11_tx_de-skew = <0x07>; + cs0_dq12_rx_de-skew = <0x08>; + cs0_dq12_tx_de-skew = <0x08>; + cs0_dq13_rx_de-skew = <0x09>; + cs0_dq13_tx_de-skew = <0x07>; + cs0_dq14_rx_de-skew = <0x09>; + cs0_dq14_tx_de-skew = <0x08>; + cs0_dq15_rx_de-skew = <0x09>; + cs0_dq15_tx_de-skew = <0x07>; + cs0_dqs1_rx_de-skew = <0x07>; + cs0_dqs1p_tx_de-skew = <0x09>; + cs0_dqs1n_tx_de-skew = <0x09>; + cs0_dm2_rx_de-skew = <0x07>; + cs0_dm2_tx_de-skew = <0x07>; + cs0_dq16_rx_de-skew = <0x09>; + cs0_dq16_tx_de-skew = <0x09>; + cs0_dq17_rx_de-skew = <0x07>; + cs0_dq17_tx_de-skew = <0x09>; + cs0_dq18_rx_de-skew = <0x07>; + cs0_dq18_tx_de-skew = <0x08>; + cs0_dq19_rx_de-skew = <0x07>; + cs0_dq19_tx_de-skew = <0x09>; + cs0_dq20_rx_de-skew = <0x09>; + cs0_dq20_tx_de-skew = <0x09>; + cs0_dq21_rx_de-skew = <0x09>; + cs0_dq21_tx_de-skew = <0x09>; + cs0_dq22_rx_de-skew = <0x08>; + cs0_dq22_tx_de-skew = <0x09>; + cs0_dq23_rx_de-skew = <0x08>; + cs0_dq23_tx_de-skew = <0x09>; + cs0_dqs2_rx_de-skew = <0x06>; + cs0_dqs2p_tx_de-skew = <0x09>; + cs0_dqs2n_tx_de-skew = <0x09>; + cs0_dm3_rx_de-skew = <0x07>; + cs0_dm3_tx_de-skew = <0x07>; + cs0_dq24_rx_de-skew = <0x08>; + cs0_dq24_tx_de-skew = <0x08>; + cs0_dq25_rx_de-skew = <0x09>; + cs0_dq25_tx_de-skew = <0x09>; + cs0_dq26_rx_de-skew = <0x09>; + cs0_dq26_tx_de-skew = <0x08>; + cs0_dq27_rx_de-skew = <0x09>; + cs0_dq27_tx_de-skew = <0x08>; + cs0_dq28_rx_de-skew = <0x09>; + cs0_dq28_tx_de-skew = <0x09>; + cs0_dq29_rx_de-skew = <0x09>; + cs0_dq29_tx_de-skew = <0x09>; + cs0_dq30_rx_de-skew = <0x08>; + cs0_dq30_tx_de-skew = <0x08>; + cs0_dq31_rx_de-skew = <0x08>; + cs0_dq31_tx_de-skew = <0x08>; + cs0_dqs3_rx_de-skew = <0x07>; + cs0_dqs3p_tx_de-skew = <0x09>; + cs0_dqs3n_tx_de-skew = <0x09>; + cs1_dm0_rx_de-skew = <0x07>; + cs1_dm0_tx_de-skew = <0x07>; + cs1_dq0_rx_de-skew = <0x08>; + cs1_dq0_tx_de-skew = <0x08>; + cs1_dq1_rx_de-skew = <0x09>; + cs1_dq1_tx_de-skew = <0x08>; + cs1_dq2_rx_de-skew = <0x08>; + cs1_dq2_tx_de-skew = <0x08>; + cs1_dq3_rx_de-skew = <0x08>; + cs1_dq3_tx_de-skew = <0x08>; + cs1_dq4_rx_de-skew = <0x08>; + cs1_dq4_tx_de-skew = <0x08>; + cs1_dq5_rx_de-skew = <0x09>; + cs1_dq5_tx_de-skew = <0x08>; + cs1_dq6_rx_de-skew = <0x09>; + cs1_dq6_tx_de-skew = <0x08>; + cs1_dq7_rx_de-skew = <0x08>; + cs1_dq7_tx_de-skew = <0x08>; + cs1_dqs0_rx_de-skew = <0x06>; + cs1_dqs0p_tx_de-skew = <0x09>; + cs1_dqs0n_tx_de-skew = <0x09>; + cs1_dm1_rx_de-skew = <0x07>; + cs1_dm1_tx_de-skew = <0x07>; + cs1_dq8_rx_de-skew = <0x08>; + cs1_dq8_tx_de-skew = <0x08>; + cs1_dq9_rx_de-skew = <0x08>; + cs1_dq9_tx_de-skew = <0x07>; + cs1_dq10_rx_de-skew = <0x07>; + cs1_dq10_tx_de-skew = <0x08>; + cs1_dq11_rx_de-skew = <0x08>; + cs1_dq11_tx_de-skew = <0x08>; + cs1_dq12_rx_de-skew = <0x08>; + cs1_dq12_tx_de-skew = <0x07>; + cs1_dq13_rx_de-skew = <0x08>; + cs1_dq13_tx_de-skew = <0x08>; + cs1_dq14_rx_de-skew = <0x08>; + cs1_dq14_tx_de-skew = <0x08>; + cs1_dq15_rx_de-skew = <0x08>; + cs1_dq15_tx_de-skew = <0x07>; + cs1_dqs1_rx_de-skew = <0x07>; + cs1_dqs1p_tx_de-skew = <0x09>; + cs1_dqs1n_tx_de-skew = <0x09>; + cs1_dm2_rx_de-skew = <0x07>; + cs1_dm2_tx_de-skew = <0x08>; + cs1_dq16_rx_de-skew = <0x08>; + cs1_dq16_tx_de-skew = <0x09>; + cs1_dq17_rx_de-skew = <0x08>; + cs1_dq17_tx_de-skew = <0x09>; + cs1_dq18_rx_de-skew = <0x07>; + cs1_dq18_tx_de-skew = <0x08>; + cs1_dq19_rx_de-skew = <0x08>; + cs1_dq19_tx_de-skew = <0x09>; + cs1_dq20_rx_de-skew = <0x09>; + cs1_dq20_tx_de-skew = <0x09>; + cs1_dq21_rx_de-skew = <0x09>; + cs1_dq21_tx_de-skew = <0x09>; + cs1_dq22_rx_de-skew = <0x08>; + cs1_dq22_tx_de-skew = <0x09>; + cs1_dq23_rx_de-skew = <0x08>; + cs1_dq23_tx_de-skew = <0x09>; + cs1_dqs2_rx_de-skew = <0x06>; + cs1_dqs2p_tx_de-skew = <0x09>; + cs1_dqs2n_tx_de-skew = <0x09>; + cs1_dm3_rx_de-skew = <0x07>; + cs1_dm3_tx_de-skew = <0x07>; + cs1_dq24_rx_de-skew = <0x08>; + cs1_dq24_tx_de-skew = <0x09>; + cs1_dq25_rx_de-skew = <0x09>; + cs1_dq25_tx_de-skew = <0x09>; + cs1_dq26_rx_de-skew = <0x09>; + cs1_dq26_tx_de-skew = <0x08>; + cs1_dq27_rx_de-skew = <0x08>; + cs1_dq27_tx_de-skew = <0x08>; + cs1_dq28_rx_de-skew = <0x09>; + cs1_dq28_tx_de-skew = <0x09>; + cs1_dq29_rx_de-skew = <0x09>; + cs1_dq29_tx_de-skew = <0x09>; + cs1_dq30_rx_de-skew = <0x09>; + cs1_dq30_tx_de-skew = <0x08>; + cs1_dq31_rx_de-skew = <0x08>; + cs1_dq31_tx_de-skew = <0x08>; + cs1_dqs3_rx_de-skew = <0x07>; + cs1_dqs3p_tx_de-skew = <0x09>; + cs1_dqs3n_tx_de-skew = <0x09>; + phandle = <0xaf>; + }; + + aliases { + ethernet0 = "/ethernet@ff360000"; + i2c0 = "/i2c@ff180000"; + i2c1 = "/i2c@ff190000"; + i2c2 = "/i2c@ff1a0000"; + i2c3 = "/i2c@ff1b0000"; + serial0 = "/serial@ff030000"; + serial1 = "/serial@ff158000"; + serial2 = "/serial@ff160000"; + serial3 = "/serial@ff168000"; + serial4 = "/serial@ff170000"; + serial5 = "/serial@ff178000"; + spi0 = "/spi@ff1d0000"; + spi1 = "/spi@ff1d8000"; + }; + + cpus { + #address-cells = <0x02>; + #size-cells = <0x00>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x00>; + enable-method = "psci"; + clocks = <0x02 0x07>; + #cooling-cells = <0x02>; + dynamic-power-coefficient = <0x5a>; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + cpu-supply = <0x06>; + phandle = <0x09>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x01>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0a>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x02>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0b>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a35\0arm,armv8"; + reg = <0x00 0x03>; + enable-method = "psci"; + operating-points-v2 = <0x03>; + cpu-idle-states = <0x04 0x05>; + phandle = <0x0c>; + }; + + idle-states { + entry-method = "psci"; + + cpu-sleep { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x10000>; + entry-latency-us = <0x78>; + exit-latency-us = <0xfa>; + min-residency-us = <0x384>; + phandle = <0x04>; + }; + + cluster-sleep { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x1010000>; + entry-latency-us = <0x190>; + exit-latency-us = <0x1f4>; + min-residency-us = <0x7d0>; + phandle = <0x05>; + }; + }; + }; + + cpu0-opp-table { + compatible = "operating-points-v2"; + opp-shared; + rockchip,temp-hysteresis = <0x1388>; + rockchip,low-temp = <0x00>; + rockchip,low-temp-min-volt = <0xf4240>; + rockchip,low-temp-adjust-volt = <0x00 0x5e8 0xc350>; + clocks = <0x02 0x01>; + rockchip,avs-scale = <0x04>; + rockchip,max-volt = <0x149970>; + rockchip,evb-irdrop = <0x61a8>; + nvmem-cells = <0x07 0x08>; + nvmem-cell-names = "cpu_leakage\0performance"; + rockchip,bin-scaling-sel = <0x00 0x0d 0x01 0x0d>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-freq = <0x639c0>; + rockchip,pvtm-volt = <0xf4240>; + rockchip,pvtm-ch = <0x00 0x00>; + rockchip,pvtm-sample-time = <0x3e8>; + rockchip,pvtm-number = <0x0a>; + rockchip,pvtm-error = <0x3e8>; + rockchip,pvtm-ref-temp = <0x28>; + rockchip,pvtm-temp-prop = <0xffffffc8 0xffffffc8>; + rockchip,thermal-zone = "soc-thermal"; + rockchip,avs = <0x01>; + phandle = <0x03>; + + opp-1008000000 { + opp-hz = <0x00 0x3c14dc00>; + opp-microvolt = <0x11edd8 0x11edd8 0x149970>; + opp-microvolt-L0 = <0x11edd8 0x11edd8 0x149970>; + opp-microvolt-L1 = <0x112a88 0x112a88 0x149970>; + opp-microvolt-L2 = <0x112a88 0x112a88 0x149970>; + opp-microvolt-L3 = <0x100590 0x100590 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1200000000 { + opp-hz = <0x00 0x47868c00>; + opp-microvolt = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L0 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L1 = <0x137478 0x137478 0x149970>; + opp-microvolt-L2 = <0x1312d0 0x1312d0 0x149970>; + opp-microvolt-L3 = <0x124f80 0x124f80 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1248000000 { + opp-hz = <0x00 0x4a62f800>; + opp-microvolt = <0x149970 0x149970 0x149970>; + opp-microvolt-L0 = <0x149970 0x149970 0x149970>; + opp-microvolt-L1 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L2 = <0x137478 0x137478 0x149970>; + opp-microvolt-L3 = <0x12b128 0x12b128 0x149970>; + clock-latency-ns = <0x9c40>; + }; + + opp-1296000000 { + opp-hz = <0x00 0x4d3f6400>; + opp-microvolt = <0x149970 0x149970 0x149970>; + opp-microvolt-L0 = <0x149970 0x149970 0x149970>; + opp-microvolt-L1 = <0x149970 0x149970 0x149970>; + opp-microvolt-L2 = <0x13d620 0x13d620 0x149970>; + opp-microvolt-L3 = <0x1312d0 0x1312d0 0x149970>; + clock-latency-ns = <0x9c40>; + }; + }; + + arm-pmu { + compatible = "arm,cortex-a53-pmu"; + interrupts = <0x00 0x64 0x04 0x00 0x65 0x04 0x00 0x66 0x04 0x00 0x67 0x04>; + interrupt-affinity = <0x09 0x0a 0x0b 0x0c>; + }; + + bus-soc { + compatible = "rockchip,px30-bus"; + rockchip,busfreq-policy = "autocs"; + phandle = <0xc4>; + + soc-bus0 { + bus-id = <0x00>; + timer-us = <0x14>; + enable-msk = <0x40f7>; + status = "disabled"; + }; + + soc-bus1 { + bus-id = <0x01>; + timer-us = <0xc8>; + enable-msk = <0x40bf>; + status = "disabled"; + }; + + soc-bus2 { + bus-id = <0x02>; + timer-us = <0xc8>; + enable-msk = <0x4007>; + status = "disabled"; + }; + }; + + bus-apll { + compatible = "rockchip,px30-bus"; + rockchip,busfreq-policy = "clkfreq"; + clocks = <0x02 0x01>; + clock-names = "bus"; + operating-points-v2 = <0x0d>; + status = "okay"; + bus-supply = <0x0e>; + phandle = <0xc5>; + }; + + bus-apll-opp-table { + compatible = "operating-points-v2"; + opp-shared; + phandle = <0x0d>; + + opp-1512000000 { + opp-hz = <0x00 0x5a1f4a00>; + opp-microvolt = <0xf4240>; + }; + + opp-1008000000 { + opp-hz = <0x00 0x3c14dc00>; + opp-microvolt = <0xe7ef0>; + }; + }; + + cpuinfo { + compatible = "rockchip,cpuinfo"; + nvmem-cells = <0x0f>; + nvmem-cell-names = "id"; + }; + + display-subsystem { + compatible = "rockchip,display-subsystem"; + ports = <0x10>; + status = "okay"; + logo-memory-region = <0x11>; + phandle = <0xc6>; + + route { + + route-lvds { + status = "disabled"; + logo,uboot = "logo.bmp"; + logo,kernel = "logo_kernel.bmp"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x12>; + phandle = <0xc7>; + }; + + route-dsi { + status = "okay"; + logo,uboot = "logo.bmp"; + logo,kernel = "logo_kernel.bmp"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x13>; + phandle = <0xc8>; + }; + + route-rgb { + status = "disabled"; + logo,uboot = "logo.bmp"; + logo,kernel = "logo_kernel.bmp"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <0x14>; + phandle = <0xc9>; + }; + }; + }; + + firmware { + + optee { + compatible = "linaro,optee-tz"; + method = "smc"; + }; + }; + + external-gmac-clock { + compatible = "fixed-clock"; + clock-frequency = <0x2faf080>; + clock-output-names = "gmac_clkin"; + #clock-cells = <0x00>; + phandle = <0xca>; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + rockchip-suspend { + compatible = "rockchip,pm-px30"; + status = "okay"; + rockchip,sleep-debug-en = <0x01>; + rockchip,sleep-mode-config = <0x20702>; + rockchip,wakeup-config = <0x85>; + phandle = <0xcb>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <0x01 0x0d 0xf04 0x01 0x0e 0xf04 0x01 0x0b 0xf04 0x01 0x0a 0xf04>; + }; + + xin24m { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x16e3600>; + clock-output-names = "xin24m"; + phandle = <0xcc>; + }; + + xin32k { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x8000>; + clock-output-names = "xin32k"; + phandle = <0xcd>; + }; + + power-management@ff000000 { + compatible = "rockchip,px30-pmu\0syscon\0simple-mfd"; + reg = <0x00 0xff000000 0x00 0x1000>; + phandle = <0xce>; + + power-controller { + compatible = "rockchip,px30-power-controller"; + #power-domain-cells = <0x01>; + #address-cells = <0x01>; + #size-cells = <0x00>; + phandle = <0x8a>; + + pd_usb@5 { + reg = <0x05>; + clocks = <0x02 0x103 0x02 0x102 0x02 0x3c>; + pm_qos = <0x15 0x16>; + }; + + pd_sdcard@7 { + reg = <0x07>; + clocks = <0x02 0xf7 0x02 0x3b>; + pm_qos = <0x17>; + }; + + pd_gmac@9 { + reg = <0x09>; + clocks = <0x02 0xb2 0x02 0x143 0x02 0x40 0x02 0x3f>; + pm_qos = <0x18>; + }; + + pd_mmc_nand@10 { + reg = <0x0a>; + clocks = <0x02 0xfe 0x02 0x100 0x02 0xff 0x02 0x101 0x02 0x39 0x02 0x37 0x02 0x38 0x02 0x3a>; + pm_qos = <0x19 0x1a 0x1b 0x1c>; + }; + + pd_vpu@11 { + reg = <0x0b>; + clocks = <0x02 0xaf 0x02 0xf4 0x02 0x4b>; + pm_qos = <0x1d 0x1e>; + }; + + pd_vo@12 { + reg = <0x0c>; + clocks = <0x02 0xb7 0x02 0xb5 0x02 0xb6 0x02 0x96 0x02 0x97 0x02 0xfd 0x02 0xfb 0x02 0xfc 0x02 0x144 0x02 0x35 0x02 0x36>; + pm_qos = <0x1f 0x20 0x21 0x22>; + }; + + pd_vi@13 { + reg = <0x0d>; + clocks = <0x02 0xb3 0x02 0xb4 0x02 0xf9 0x02 0xfa 0x02 0x33>; + pm_qos = <0x23 0x24 0x25 0x26 0x27>; + }; + + pd_gpu@14 { + reg = <0x0e>; + clocks = <0x02 0x49>; + pm_qos = <0x28>; + }; + }; + }; + + syscon@ff010000 { + compatible = "rockchip,px30-pmugrf\0syscon\0simple-mfd"; + reg = <0x00 0xff010000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0xac>; + + io-domains { + compatible = "rockchip,px30-pmu-io-voltage-domain"; + status = "okay"; + pmuio1-supply = <0x29>; + pmuio2-supply = <0x29>; + phandle = <0xcf>; + }; + + reboot-mode { + compatible = "syscon-reboot-mode"; + offset = <0x200>; + mode-bootloader = <0x5242c301>; + mode-charge = <0x5242c30b>; + mode-fastboot = <0x5242c309>; + mode-loader = <0x5242c301>; + mode-normal = <0x5242c300>; + mode-recovery = <0x5242c303>; + mode-ums = <0x5242c30c>; + }; + + pmu-pvtm { + compatible = "rockchip,px30-pmu-pvtm"; + clocks = <0x2a 0x07>; + clock-names = "pmu"; + status = "okay"; + phandle = <0xd0>; + }; + }; + + serial@ff030000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff030000 0x00 0x100>; + interrupts = <0x00 0x0f 0x04>; + clocks = <0x2a 0x06 0x2a 0x15>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x00 0x2b 0x01>; + pinctrl-names = "default"; + pinctrl-0 = <0x2c 0x2d 0x2e>; + status = "disabled"; + phandle = <0xd1>; + }; + + i2s@ff060000 { + compatible = "rockchip,px30-i2s-tdm"; + reg = <0x00 0xff060000 0x00 0x1000>; + interrupts = <0x00 0x0c 0x04>; + clocks = <0x02 0x10 0x02 0x12 0x02 0x106>; + clock-names = "mclk_tx\0mclk_rx\0hclk"; + dmas = <0x2b 0x10 0x2b 0x11>; + dma-names = "tx\0rx"; + resets = <0x02 0x84 0x02 0xbf>; + reset-names = "tx-m\0rx-m"; + rockchip,cru = <0x02>; + rockchip,grf = <0x2f>; + pinctrl-names = "default"; + pinctrl-0 = <0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x3a 0x3b>; + status = "disabled"; + phandle = <0xd2>; + }; + + i2s@ff070000 { + compatible = "rockchip,px30-i2s\0rockchip,rk3066-i2s"; + reg = <0x00 0xff070000 0x00 0x1000>; + interrupts = <0x00 0x0d 0x04>; + clocks = <0x02 0x14 0x02 0x107>; + clock-names = "i2s_clk\0i2s_hclk"; + dmas = <0x2b 0x12 0x2b 0x13>; + dma-names = "tx\0rx"; + resets = <0x02 0x86 0x02 0x85>; + reset-names = "reset-m\0reset-h"; + pinctrl-names = "default"; + pinctrl-0 = <0x3c 0x3d 0x3e 0x3f>; + status = "okay"; + #sound-dai-cells = <0x00>; + phandle = <0xc2>; + }; + + i2s@ff080000 { + compatible = "rockchip,px30-i2s\0rockchip,rk3066-i2s"; + reg = <0x00 0xff080000 0x00 0x1000>; + interrupts = <0x00 0x0e 0x04>; + clocks = <0x02 0x16 0x02 0x108>; + clock-names = "i2s_clk\0i2s_hclk"; + dmas = <0x2b 0x14 0x2b 0x15>; + dma-names = "tx\0rx"; + resets = <0x02 0x88 0x02 0x87>; + reset-names = "reset-m\0reset-h"; + pinctrl-names = "default"; + pinctrl-0 = <0x40 0x41 0x42 0x43>; + status = "disabled"; + phandle = <0xd3>; + }; + + pdm@ff0a0000 { + compatible = "rockchip,px30-pdm\0rockchip,pdm"; + reg = <0x00 0xff0a0000 0x00 0x1000>; + clocks = <0x02 0x0f 0x02 0x105>; + clock-names = "pdm_clk\0pdm_hclk"; + dmas = <0x2b 0x18>; + dma-names = "rx"; + resets = <0x02 0x82>; + reset-names = "pdm-m"; + pinctrl-names = "default"; + pinctrl-0 = <0x44 0x45 0x46 0x47 0x48 0x49>; + status = "disabled"; + phandle = <0xd4>; + }; + + crypto@ff0b0000 { + compatible = "rockchip,px30-crypto"; + reg = <0x00 0xff0b0000 0x00 0x4000>; + interrupts = <0x00 0x52 0x04>; + clocks = <0x02 0xac 0x02 0xf1 0x02 0x30 0x02 0x31>; + clock-names = "aclk\0hclk\0sclk\0apb_pclk"; + resets = <0x02 0x74>; + reset-names = "crypto-rst"; + status = "disabled"; + phandle = <0xd5>; + }; + + rng@ff0b0000 { + compatible = "rockchip,cryptov2-rng"; + reg = <0x00 0xff0b0000 0x00 0x4000>; + clocks = <0x02 0x30 0x02 0x31 0x02 0xac 0x02 0xf1>; + clock-names = "clk_crypto\0clk_crypto_apk\0aclk_crypto\0hclk_crypto"; + assigned-clocks = <0x02 0x30 0x02 0x31 0x02 0xac 0x02 0xf1>; + assigned-clock-rates = <0x8f0d180 0x8f0d180 0xbebc200 0x5f5e100>; + resets = <0x02 0x74>; + reset-names = "reset"; + status = "okay"; + phandle = <0xd6>; + }; + + interrupt-controller@ff131000 { + compatible = "arm,gic-400"; + #interrupt-cells = <0x03>; + #address-cells = <0x00>; + interrupt-controller; + reg = <0x00 0xff131000 0x00 0x1000 0x00 0xff132000 0x00 0x2000 0x00 0xff134000 0x00 0x2000 0x00 0xff136000 0x00 0x2000>; + interrupts = <0x01 0x09 0xf04>; + phandle = <0x01>; + }; + + syscon@ff140000 { + compatible = "rockchip,px30-grf\0syscon\0simple-mfd"; + reg = <0x00 0xff140000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0x2f>; + + io-domains { + compatible = "rockchip,px30-io-voltage-domain"; + status = "okay"; + vccio1-supply = <0x4a>; + vccio2-supply = <0x4a>; + vccio3-supply = <0x4b>; + vccio4-supply = <0x4b>; + vccio5-supply = <0x4b>; + vccio6-supply = <0x4b>; + phandle = <0xd7>; + }; + + lvds { + compatible = "rockchip,px30-lvds"; + phys = <0x4c>; + phy-names = "phy"; + status = "disabled"; + phandle = <0xd8>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x12>; + phandle = <0xa2>; + }; + }; + }; + }; + + rgb { + compatible = "rockchip,px30-rgb"; + pinctrl-names = "default\0sleep"; + pinctrl-0 = <0x4d>; + pinctrl-1 = <0x4e>; + status = "disabled"; + phys = <0x4c>; + phy-names = "phy"; + phandle = <0xd9>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x14>; + phandle = <0xa4>; + }; + }; + }; + }; + }; + + syscon@ff148000 { + compatible = "syscon\0simple-mfd"; + reg = <0x00 0xff148000 0x00 0x1000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0xda>; + + pvtm { + compatible = "rockchip,px30-pvtm"; + clocks = <0x02 0x4a>; + clock-names = "core"; + status = "okay"; + phandle = <0xdb>; + }; + }; + + serial@ff158000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff158000 0x00 0x100>; + interrupts = <0x00 0x10 0x04>; + clocks = <0x02 0x18 0x02 0x149>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x02 0x2b 0x03>; + pinctrl-names = "default"; + pinctrl-0 = <0x4f 0x50>; + status = "okay"; + phandle = <0xdc>; + }; + + serial@ff160000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff160000 0x00 0x100>; + interrupts = <0x00 0x11 0x04>; + clocks = <0x02 0x19 0x02 0x14a>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x04 0x2b 0x05>; + pinctrl-names = "default"; + pinctrl-0 = <0x51>; + status = "disabled"; + phandle = <0xdd>; + }; + + serial@ff168000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff168000 0x00 0x100>; + interrupts = <0x00 0x12 0x04>; + clocks = <0x02 0x1a 0x02 0x14b>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x06 0x2b 0x07>; + pinctrl-names = "default"; + pinctrl-0 = <0x52 0x53 0x54>; + status = "disabled"; + phandle = <0xde>; + }; + + serial@ff170000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff170000 0x00 0x100>; + interrupts = <0x00 0x13 0x04>; + clocks = <0x02 0x1b 0x02 0x14c>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x08 0x2b 0x09>; + pinctrl-names = "default"; + pinctrl-0 = <0x55 0x56 0x57>; + status = "disabled"; + phandle = <0xdf>; + }; + + serial@ff178000 { + compatible = "rockchip,px30-uart\0snps,dw-apb-uart"; + reg = <0x00 0xff178000 0x00 0x100>; + interrupts = <0x00 0x14 0x04>; + clocks = <0x02 0x1c 0x02 0x14d>; + clock-names = "baudclk\0apb_pclk"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + dmas = <0x2b 0x0a 0x2b 0x0b>; + pinctrl-names = "default"; + pinctrl-0 = <0x58 0x59 0x5a>; + status = "disabled"; + phandle = <0xe0>; + }; + + i2c@ff180000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff180000 0x00 0x1000>; + clocks = <0x02 0x1d 0x02 0x14e>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x07 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x5b>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + clock-frequency = <0x61a80>; + i2c-scl-rising-time-ns = <0x118>; + i2c-scl-falling-time-ns = <0x10>; + phandle = <0xe1>; + + pmic@20 { + compatible = "rockchip,rk817"; + reg = <0x20>; + interrupt-parent = <0x5c>; + interrupts = <0x0a 0x08>; + pinctrl-names = "default\0pmic-sleep\0pmic-power-off\0pmic-reset"; + pinctrl-0 = <0x5d>; + pinctrl-1 = <0x5e 0x5f>; + pinctrl-2 = <0x60 0x61>; + pinctrl-3 = <0x62 0x63>; + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <0x01>; + clock-output-names = "rk808-clkout1\0rk808-clkout2"; + pmic-reset-func = <0x01>; + vcc1-supply = <0x64>; + vcc2-supply = <0x64>; + vcc3-supply = <0x64>; + vcc4-supply = <0x64>; + vcc5-supply = <0x64>; + vcc6-supply = <0x64>; + vcc7-supply = <0x64>; + vcc8-supply = <0x64>; + vcc9-supply = <0x65>; + phandle = <0xe2>; + + pwrkey { + status = "okay"; + }; + + pinctrl_rk8xx { + gpio-controller; + #gpio-cells = <0x02>; + phandle = <0xe3>; + + rk817_ts_gpio1 { + pins = "gpio_ts"; + function = "pin_fun1"; + phandle = <0xe4>; + }; + + rk817_gt_gpio2 { + pins = "gpio_gt"; + function = "pin_fun1"; + phandle = <0xe5>; + }; + + rk817_pin_ts { + pins = "gpio_ts"; + function = "pin_fun0"; + phandle = <0xe6>; + }; + + rk817_pin_gt { + pins = "gpio_gt"; + function = "pin_fun0"; + phandle = <0xe7>; + }; + + rk817_slppin_null { + pins = "gpio_slp"; + function = "pin_fun0"; + phandle = <0xe8>; + }; + + rk817_slppin_slp { + pins = "gpio_slp"; + function = "pin_fun1"; + phandle = <0x5f>; + }; + + rk817_slppin_pwrdn { + pins = "gpio_slp"; + function = "pin_fun2"; + phandle = <0x61>; + }; + + rk817_slppin_rst { + pins = "gpio_slp"; + function = "pin_fun3"; + phandle = <0x63>; + }; + }; + + regulators { + + DCDC_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xe7ef0>; + regulator-max-microvolt = <0x118c30>; + regulator-ramp-delay = <0x1771>; + regulator-initial-mode = <0x02>; + regulator-name = "vdd_logic"; + phandle = <0x0e>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0xe7ef0>; + }; + }; + + DCDC_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xe7ef0>; + regulator-max-microvolt = <0x149970>; + regulator-ramp-delay = <0x1771>; + regulator-initial-mode = <0x02>; + regulator-name = "vdd_arm"; + phandle = <0x06>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0xe7ef0>; + }; + }; + + DCDC_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x02>; + regulator-name = "vcc_ddr"; + phandle = <0xe9>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + DCDC_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-initial-mode = <0x02>; + regulator-name = "vcc_3v3"; + phandle = <0x4b>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG1 { + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + regulator-name = "vcc_1v0"; + phandle = <0xea>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0xf4240>; + }; + }; + + LDO_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + regulator-name = "vcc1v8_soc"; + phandle = <0x88>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x1b7740>; + }; + }; + + LDO_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xf4240>; + regulator-max-microvolt = <0xf4240>; + regulator-name = "vcc1v0_soc"; + phandle = <0xeb>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0xf4240>; + }; + }; + + LDO_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "vcc3v3_pmu"; + phandle = <0x29>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + regulator-name = "vccio_sd"; + phandle = <0x4a>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x1b7740>; + }; + }; + + LDO_REG6 { + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x2dc6c0>; + regulator-boot-on; + regulator-name = "vcc_sd"; + phandle = <0x93>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x2dc6c0>; + }; + }; + + LDO_REG7 { + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-name = "vcc_backlight"; + phandle = <0x9e>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + LDO_REG8 { + regulator-min-microvolt = <0x2ab980>; + regulator-max-microvolt = <0x2ab980>; + regulator-name = "vcc_lcd"; + phandle = <0x9f>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x2ab980>; + }; + }; + + BOOST { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x4c4b40>; + regulator-max-microvolt = <0x5265c0>; + regulator-name = "boost"; + phandle = <0x65>; + }; + + OTG_SWITCH { + regulator-boot-on; + regulator-name = "otg_switch"; + phandle = <0xec>; + }; + }; + + battery { + compatible = "rk817,battery"; + ocv_table = <0xc5d 0xc94 0xcd0 0xd02 0xd34 0xd66 0xd98 0xdca 0xdfc 0xe2e 0xe56 0xe7e 0xea6 0xece 0xef6 0xf1e 0xf46 0xf6e 0xf96 0xf9b 0xfa0>; + design_capacity = <0xd34>; + design_qmax = <0xe86>; + bat_res = <0x64>; + sleep_enter_current = <0x12c>; + sleep_exit_current = <0x12c>; + sleep_filter_current = <0x64>; + power_off_thresd = <0xbb8>; + zero_algorithm_vol = <0xf0a>; + max_soc_offset = <0x3c>; + monitor_sec = <0x05>; + virtual_power = <0x00>; + sample_res = <0x0a>; + }; + + charger { + compatible = "rk817,charger"; + min_input_voltage = <0x1194>; + max_input_current = <0x5dc>; + max_chrg_current = <0x7d0>; + max_chrg_voltage = <0x1068>; + chrg_term_mode = <0x00>; + chrg_finish_cur = <0x34>; + virtual_power = <0x00>; + sample_res = <0x0a>; + dc_det_gpio = <0x5c 0x0b 0x00>; + bat_low_gpio = <0x66 0x0d 0x00>; + extcon = <0x67>; + }; + + codec { + #sound-dai-cells = <0x00>; + compatible = "rockchip,rk817-codec"; + clocks = <0x02 0x15>; + clock-names = "mclk"; + pinctrl-names = "default"; + pinctrl-0 = <0x68>; + hp-volume = <0x14>; + spk-volume = <0x03>; + status = "okay"; + phandle = <0xc3>; + }; + }; + }; + + i2c@ff190000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff190000 0x00 0x1000>; + clocks = <0x02 0x1e 0x02 0x14f>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x08 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x69>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + clock-frequency = <0x61a80>; + phandle = <0xed>; + }; + + i2c@ff1a0000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff1a0000 0x00 0x1000>; + clocks = <0x02 0x1f 0x02 0x150>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x09 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x6a>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xee>; + }; + + i2c@ff1b0000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x00 0xff1b0000 0x00 0x1000>; + clocks = <0x02 0x20 0x02 0x151>; + clock-names = "i2c\0pclk"; + interrupts = <0x00 0x0a 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x6b>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + phandle = <0xef>; + }; + + spi@ff1d0000 { + compatible = "rockchip,px30-spi\0rockchip,rk3066-spi"; + reg = <0x00 0xff1d0000 0x00 0x1000>; + interrupts = <0x00 0x1a 0x04>; + #address-cells = <0x01>; + #size-cells = <0x00>; + clocks = <0x02 0x24 0x02 0x155>; + clock-names = "spiclk\0apb_pclk"; + dmas = <0x2b 0x0c 0x2b 0x0d>; + dma-names = "tx\0rx"; + pinctrl-names = "default\0high_speed"; + pinctrl-0 = <0x6c 0x6d 0x6e 0x6f>; + pinctrl-1 = <0x70 0x6d 0x71 0x72>; + status = "disabled"; + phandle = <0xf0>; + }; + + spi@ff1d8000 { + compatible = "rockchip,px30-spi\0rockchip,rk3066-spi"; + reg = <0x00 0xff1d8000 0x00 0x1000>; + interrupts = <0x00 0x1b 0x04>; + #address-cells = <0x01>; + #size-cells = <0x00>; + clocks = <0x02 0x25 0x02 0x156>; + clock-names = "spiclk\0apb_pclk"; + dmas = <0x2b 0x0e 0x2b 0x0f>; + dma-names = "tx\0rx"; + pinctrl-names = "default\0high_speed"; + pinctrl-0 = <0x73 0x74 0x75 0x76 0x77>; + pinctrl-1 = <0x78 0x74 0x75 0x79 0x7a>; + status = "disabled"; + phandle = <0xf1>; + }; + + watchdog@ff1e0000 { + compatible = "snps,dw-wdt"; + reg = <0x00 0xff1e0000 0x00 0x100>; + clocks = <0x02 0x15b>; + interrupts = <0x00 0x25 0x04>; + resets = <0x02 0xb5>; + reset-names = "reset"; + status = "disabled"; + phandle = <0xf2>; + }; + + pwm@ff200000 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200000 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7b>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "okay"; + phandle = <0xbc>; + }; + + pwm@ff200010 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200010 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7c>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "okay"; + phandle = <0xc1>; + }; + + pwm@ff200020 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200020 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7d>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf3>; + }; + + pwm@ff200030 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff200030 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7e>; + clocks = <0x02 0x22 0x02 0x153>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf4>; + }; + + pwm@ff208000 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208000 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x7f>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf5>; + }; + + pwm@ff208010 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208010 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x80>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf6>; + }; + + pwm@ff208020 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208020 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x81>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf7>; + }; + + pwm@ff208030 { + compatible = "rockchip,px30-pwm\0rockchip,rk3328-pwm"; + reg = <0x00 0xff208030 0x00 0x10>; + #pwm-cells = <0x03>; + pinctrl-names = "active"; + pinctrl-0 = <0x82>; + clocks = <0x02 0x23 0x02 0x154>; + clock-names = "pwm\0pclk"; + status = "disabled"; + phandle = <0xf8>; + }; + + rktimer@ff210000 { + compatible = "rockchip,rk3288-timer"; + reg = <0x00 0xff210000 0x00 0x1000>; + interrupts = <0x00 0x1e 0x04>; + clocks = <0x02 0x159 0x02 0x26>; + clock-names = "pclk\0timer"; + phandle = <0xf9>; + }; + + amba { + compatible = "simple-bus"; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + + dmac@ff240000 { + compatible = "arm,pl330\0arm,primecell"; + reg = <0x00 0xff240000 0x00 0x4000>; + interrupts = <0x00 0x01 0x04 0x00 0x02 0x04>; + clocks = <0x02 0xbb>; + clock-names = "apb_pclk"; + #dma-cells = <0x01>; + peripherals-req-type-burst; + phandle = <0x2b>; + }; + }; + + thermal-zones { + phandle = <0xfa>; + + soc-thermal { + polling-delay-passive = <0x14>; + polling-delay = <0x3e8>; + sustainable-power = <0x2ee>; + thermal-sensors = <0x83 0x00>; + phandle = <0xfb>; + + trips { + + trip-point-0 { + temperature = <0x11170>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0xfc>; + }; + + trip-point-1 { + temperature = <0x14c08>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0x84>; + }; + + soc-crit { + temperature = <0x1c138>; + hysteresis = <0x7d0>; + type = "critical"; + phandle = <0xfd>; + }; + }; + + cooling-maps { + + map0 { + trip = <0x84>; + cooling-device = <0x09 0xffffffff 0xffffffff>; + contribution = <0x1000>; + }; + + map1 { + trip = <0x84>; + cooling-device = <0x85 0xffffffff 0xffffffff>; + contribution = <0x1000>; + }; + }; + }; + + gpu-thermal { + polling-delay-passive = <0x64>; + polling-delay = <0x3e8>; + thermal-sensors = <0x83 0x01>; + phandle = <0xfe>; + }; + }; + + tsadc@ff280000 { + compatible = "rockchip,px30-tsadc"; + reg = <0x00 0xff280000 0x00 0x100>; + interrupts = <0x00 0x24 0x04>; + rockchip,grf = <0x2f>; + clocks = <0x02 0x2c 0x02 0x158>; + clock-names = "tsadc\0apb_pclk"; + assigned-clocks = <0x02 0x2c>; + assigned-clock-rates = <0xc350>; + resets = <0x02 0xa8>; + reset-names = "tsadc-apb"; + #thermal-sensor-cells = <0x01>; + rockchip,hw-tshut-temp = <0x1d4c0>; + status = "okay"; + pinctrl-names = "gpio\0otpout"; + pinctrl-0 = <0x86>; + pinctrl-1 = <0x87>; + phandle = <0x83>; + }; + + saradc@ff288000 { + compatible = "rockchip,px30-saradc\0rockchip,rk3399-saradc"; + reg = <0x00 0xff288000 0x00 0x100>; + interrupts = <0x00 0x54 0x04>; + #io-channel-cells = <0x01>; + clocks = <0x02 0x2d 0x02 0x157>; + clock-names = "saradc\0apb_pclk"; + resets = <0x02 0xa5>; + reset-names = "saradc-apb"; + status = "okay"; + vref-supply = <0x88>; + phandle = <0xbe>; + }; + + otp@ff290000 { + compatible = "rockchip,px30-otp"; + reg = <0x00 0xff290000 0x00 0x4000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + clocks = <0x02 0x2f 0x02 0x15a 0x02 0x161>; + clock-names = "clk_otp\0pclk_otp\0pclk_otp_phy"; + resets = <0x02 0xb4>; + reset-names = "otp_phy"; + phandle = <0xff>; + + id@7 { + reg = <0x07 0x10>; + phandle = <0x0f>; + }; + + cpu-leakage@17 { + reg = <0x17 0x01>; + phandle = <0x07>; + }; + + performance@1e { + reg = <0x1e 0x01>; + bits = <0x04 0x03>; + phandle = <0x08>; + }; + }; + + clock-controller@ff2b0000 { + compatible = "rockchip,px30-cru"; + reg = <0x00 0xff2b0000 0x00 0x1000>; + rockchip,grf = <0x2f>; + rockchip,boost = <0x89>; + #clock-cells = <0x01>; + #reset-cells = <0x01>; + assigned-clocks = <0x02 0x04>; + assigned-clock-rates = <0x3dfd2400>; + phandle = <0x02>; + }; + + cpu-boost@ff2b8000 { + compatible = "syscon"; + reg = <0x00 0xff2b8000 0x00 0x1000>; + rockchip,boost-low-con0 = <0x1032>; + rockchip,boost-low-con1 = <0x1441>; + rockchip,boost-high-con0 = <0x1036>; + rockchip,boost-high-con1 = <0x1441>; + rockchip,boost-backup-pll = <0x01>; + rockchip,boost-backup-pll-usage = <0x00>; + rockchip,boost-switch-threshold = <0x249f00>; + rockchip,boost-statis-threshold = <0x100>; + rockchip,boost-statis-enable = <0x00>; + rockchip,boost-enable = <0x00>; + phandle = <0x89>; + }; + + pmu-clock-controller@ff2bc000 { + compatible = "rockchip,px30-pmucru"; + reg = <0x00 0xff2bc000 0x00 0x1000>; + rockchip,grf = <0x2f>; + #clock-cells = <0x01>; + #reset-cells = <0x01>; + assigned-clocks = <0x2a 0x01 0x2a 0x08 0x2a 0x05 0x02 0x07 0x02 0xab 0x02 0xb0 0x02 0xf0 0x02 0xf5 0x02 0x140 0x02 0x49>; + assigned-clock-rates = <0x47868c00 0x5f5e100 0x18cba80 0x23c34600 0xbebc200 0xbebc200 0x8f0d180 0x8f0d180 0x5f5e100 0xbebc200>; + phandle = <0x2a>; + }; + + syscon@ff2c0000 { + compatible = "rockchip,px30-usb2phy-grf\0syscon\0simple-mfd"; + reg = <0x00 0xff2c0000 0x00 0x10000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0x100>; + + usb2-phy@100 { + compatible = "rockchip,px30-usb2phy\0rockchip,rk3328-usb2phy"; + reg = <0x100 0x10>; + clocks = <0x2a 0x0a>; + clock-names = "phyclk"; + #clock-cells = <0x00>; + assigned-clocks = <0x02 0x0e 0x02 0x55>; + assigned-clock-parents = <0x67 0x02 0x0e>; + clock-output-names = "usb480m_phy"; + status = "okay"; + phandle = <0x67>; + + host-port { + #phy-cells = <0x00>; + interrupts = <0x00 0x44 0x04>; + interrupt-names = "linestate"; + status = "okay"; + phandle = <0x8c>; + }; + + otg-port { + #phy-cells = <0x00>; + interrupts = <0x00 0x42 0x04 0x00 0x41 0x04 0x00 0x40 0x04>; + interrupt-names = "otg-bvalid\0otg-id\0linestate"; + status = "disabled"; + phandle = <0x8b>; + }; + }; + }; + + video-phy@ff2e0000 { + compatible = "rockchip,px30-video-phy"; + reg = <0x00 0xff2e0000 0x00 0x10000 0x00 0xff450000 0x00 0x10000>; + clocks = <0x2a 0x0b 0x02 0x145 0x02 0x144>; + clock-names = "ref\0pclk_phy\0pclk_host"; + #clock-cells = <0x00>; + resets = <0x02 0x3e>; + reset-names = "rst"; + power-domains = <0x8a 0x0c>; + #phy-cells = <0x00>; + status = "okay"; + phandle = <0x4c>; + }; + + mipi-dphy-rx0@ff2f0000 { + compatible = "rockchip,rk3326-mipi-dphy"; + reg = <0x00 0xff2f0000 0x00 0x4000>; + clocks = <0x02 0x146>; + clock-names = "dphy-ref"; + power-domains = <0x8a 0x0d>; + rockchip,grf = <0x2f>; + status = "okay"; + phandle = <0x101>; + }; + + usb@ff300000 { + compatible = "rockchip,px30-usb\0rockchip,rk3066-usb\0snps,dwc2"; + reg = <0x00 0xff300000 0x00 0x40000>; + interrupts = <0x00 0x3e 0x04>; + clocks = <0x02 0x102>; + clock-names = "otg"; + power-domains = <0x8a 0x05>; + dr_mode = "otg"; + g-np-tx-fifo-size = <0x10>; + g-rx-fifo-size = <0x118>; + g-tx-fifo-size = <0x100 0x80 0x80 0x40 0x20 0x10>; + g-use-dma; + phys = <0x8b>; + phy-names = "usb2-phy"; + status = "okay"; + phandle = <0x102>; + }; + + usb@ff340000 { + compatible = "generic-ehci"; + reg = <0x00 0xff340000 0x00 0x10000>; + interrupts = <0x00 0x3c 0x04>; + clocks = <0x02 0x103 0x67>; + clock-names = "usbhost\0utmi"; + power-domains = <0x8a 0x05>; + phys = <0x8c>; + phy-names = "usb"; + status = "disabled"; + phandle = <0x103>; + }; + + usb@ff350000 { + compatible = "generic-ohci"; + reg = <0x00 0xff350000 0x00 0x10000>; + interrupts = <0x00 0x3d 0x04>; + clocks = <0x02 0x103 0x67>; + clock-names = "usbhost\0utmi"; + power-domains = <0x8a 0x05>; + phys = <0x8c>; + phy-names = "usb"; + status = "disabled"; + phandle = <0x104>; + }; + + ethernet@ff360000 { + compatible = "rockchip,px30-gmac"; + reg = <0x00 0xff360000 0x00 0x10000>; + rockchip,grf = <0x2f>; + interrupts = <0x00 0x2b 0x04>; + interrupt-names = "macirq"; + clocks = <0x02 0x3e 0x02 0x3f 0x02 0x3f 0x02 0x40 0x02 0x41 0x02 0xb2 0x02 0x143 0x02 0x4c>; + clock-names = "stmmaceth\0mac_clk_rx\0mac_clk_tx\0clk_mac_ref\0clk_mac_refout\0aclk_mac\0pclk_mac\0clk_mac_speed"; + phy-mode = "rmii"; + pinctrl-names = "default"; + pinctrl-0 = <0x8d 0x8e>; + resets = <0x02 0x5e>; + reset-names = "stmmaceth"; + power-domains = <0x8a 0x09>; + status = "disabled"; + phandle = <0x105>; + }; + + dwmmc@ff370000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff370000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0xf7 0x02 0x3b 0x02 0x43 0x02 0x44>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x3b>; + assigned-clock-parents = <0x02 0x57>; + power-domains = <0x8a 0x07>; + fifo-depth = <0x100>; + interrupts = <0x00 0x36 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x8f 0x90 0x91 0x92>; + status = "okay"; + bus-width = <0x04>; + cap-mmc-highspeed; + cap-sd-highspeed; + supports-sd; + card-detect-delay = <0x320>; + ignore-pm-notify; + cd-gpios = <0x5c 0x03 0x01>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <0x4a>; + vmmc-supply = <0x93>; + phandle = <0x106>; + }; + + dwmmc@ff380000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff380000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0xff 0x02 0x38 0x02 0x45 0x02 0x46>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x38>; + assigned-clock-parents = <0x02 0x51>; + power-domains = <0x8a 0x0a>; + fifo-depth = <0x100>; + interrupts = <0x00 0x37 0x04>; + pinctrl-names = "default"; + pinctrl-0 = <0x94 0x95 0x96>; + status = "okay"; + bus-width = <0x04>; + cap-mmc-highspeed; + cap-sd-highspeed; + supports-sd; + card-detect-delay = <0x320>; + ignore-pm-notify; + cd-gpios = <0x97 0x0e 0x01>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <0x4a>; + vmmc-supply = <0x93>; + phandle = <0x107>; + }; + + dwmmc@ff390000 { + compatible = "rockchip,px30-dw-mshc\0rockchip,rk3288-dw-mshc"; + reg = <0x00 0xff390000 0x00 0x4000>; + max-frequency = <0x8f0d180>; + clocks = <0x02 0x100 0x02 0x39 0x02 0x47 0x02 0x48>; + clock-names = "biu\0ciu\0ciu-drv\0ciu-sample"; + assigned-clocks = <0x02 0x39>; + assigned-clock-parents = <0x02 0x53>; + power-domains = <0x8a 0x0a>; + fifo-depth = <0x100>; + interrupts = <0x00 0x35 0x04>; + status = "disabled"; + phandle = <0x108>; + }; + + nandc@ff3b0000 { + compatible = "rockchip,rk-nandc"; + reg = <0x00 0xff3b0000 0x00 0x4000>; + interrupts = <0x00 0x39 0x04>; + nandc_id = <0x00>; + clocks = <0x02 0x37 0x02 0xfe>; + clock-names = "clk_nandc\0hclk_nandc"; + assigned-clocks = <0x02 0x37>; + assigned-clock-parents = <0x02 0x4f>; + power-domains = <0x8a 0x0a>; + status = "disabled"; + phandle = <0x109>; + }; + + sfc@ff3a0000 { + compatible = "rockchip,sfc"; + reg = <0x00 0xff3a0000 0x00 0x4000>; + interrupts = <0x00 0x38 0x04>; + clocks = <0x02 0x3a 0x02 0x101>; + clock-names = "clk_sfc\0hclk_sfc"; + assigned-clocks = <0x02 0x3a>; + assigned-clock-rates = <0x989680>; + status = "disabled"; + phandle = <0x10a>; + }; + + gpu@ff400000 { + compatible = "arm,malit602\0arm,malit60x\0arm,malit6xx\0arm,mali-midgard"; + reg = <0x00 0xff400000 0x00 0x4000>; + interrupts = <0x00 0x2d 0x04 0x00 0x2e 0x04 0x00 0x2f 0x04>; + interrupt-names = "GPU\0MMU\0JOB"; + clocks = <0x02 0x49>; + clock-names = "clk_mali"; + power-domains = <0x8a 0x0e>; + #cooling-cells = <0x02>; + operating-points-v2 = <0x98>; + status = "okay"; + mali-supply = <0x0e>; + phandle = <0x85>; + + power_model { + compatible = "arm,mali-simple-power-model"; + static-coefficient = <0x64578>; + dynamic-coefficient = <0x2dd>; + ts = <0x7d00 0x125c 0xffffffb0 0x02>; + thermal-zone = "gpu-thermal"; + }; + }; + + gpu-opp-table { + compatible = "operating-points-v2"; + rockchip,thermal-zone = "soc-thermal"; + rockchip,temp-hysteresis = <0x1388>; + rockchip,low-temp = <0x00>; + rockchip,low-temp-min-volt = <0xf4240>; + rockchip,low-temp-adjust-volt = <0x00 0x1e0 0xc350>; + rockchip,max-volt = <0x11edd8>; + rockchip,evb-irdrop = <0x61a8>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-ch = <0x00 0x00>; + phandle = <0x98>; + + opp-400000000 { + opp-hz = <0x00 0x17d78400>; + opp-microvolt = <0x100590>; + opp-microvolt-L0 = <0x100590>; + opp-microvolt-L1 = <0xfa3e8>; + opp-microvolt-L2 = <0xee098>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-480000000 { + opp-hz = <0x00 0x1c9c3800>; + opp-microvolt = <0x112a88>; + opp-microvolt-L0 = <0x112a88>; + opp-microvolt-L1 = <0x10c8e0>; + opp-microvolt-L2 = <0x100590>; + opp-microvolt-L3 = <0xf4240>; + }; + + opp-520000000 { + opp-hz = <0x00 0x1efe9200>; + opp-microvolt = <0x118c30>; + opp-microvolt-L0 = <0x118c30>; + opp-microvolt-L1 = <0x118c30>; + opp-microvolt-L2 = <0x10c8e0>; + opp-microvolt-L3 = <0x100590>; + }; + }; + + hevc_service@ff440000 { + compatible = "rockchip,hevc_sub"; + iommu_enabled = <0x01>; + reg = <0x00 0xff440000 0x00 0x400>; + interrupts = <0x00 0x31 0x04>; + interrupt-names = "irq_dec"; + dev_mode = <0x01>; + iommus = <0x99>; + allocator = <0x01>; + phandle = <0x9c>; + }; + + vpu_service@ff442000 { + compatible = "rockchip,vpu_sub"; + iommu_enabled = <0x01>; + reg = <0x00 0xff442000 0x00 0x800>; + interrupts = <0x00 0x50 0x04 0x00 0x4f 0x04>; + interrupt-names = "irq_enc\0irq_dec"; + dev_mode = <0x00>; + iommus = <0x9a>; + allocator = <0x01>; + phandle = <0x9b>; + }; + + vpu_combo { + compatible = "rockchip,vpu_combo"; + subcnt = <0x02>; + rockchip,grf = <0x2f>; + rockchip,sub = <0x9b 0x9c>; + clocks = <0x02 0xaf 0x02 0xf4 0x02 0x4b>; + clock-names = "aclk_vcodec\0hclk_vcodec\0clk_core"; + resets = <0x02 0x24 0x02 0x26 0x02 0x25 0x02 0x27 0x02 0x3f>; + reset-names = "video_a\0video_h\0niu_a\0niu_h\0video_core"; + power-domains = <0x8a 0x0b>; + mode_bit = <0x0f>; + mode_ctrl = <0x410>; + status = "okay"; + phandle = <0x10b>; + }; + + iommu@ff440440 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff440440 0x00 0x40 0x00 0xff440480 0x00 0x40>; + interrupts = <0x00 0x32 0x04>; + interrupt-names = "hevc_mmu"; + clocks = <0x02 0xaf 0x02 0xf4>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0b>; + #iommu-cells = <0x00>; + phandle = <0x99>; + }; + + iommu@ff442800 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff442800 0x00 0x100>; + interrupts = <0x00 0x51 0x04>; + interrupt-names = "vpu_mmu"; + clocks = <0x02 0xaf 0x02 0xf4>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0b>; + #iommu-cells = <0x00>; + phandle = <0x9a>; + }; + + dsi@ff450000 { + compatible = "rockchip,px30-mipi-dsi"; + reg = <0x00 0xff450000 0x00 0x10000>; + interrupts = <0x00 0x4b 0x04>; + clocks = <0x02 0x144 0x4c>; + clock-names = "pclk\0hs_clk"; + resets = <0x02 0x3d>; + reset-names = "apb"; + phys = <0x4c>; + phy-names = "mipi_dphy"; + power-domains = <0x8a 0x0c>; + rockchip,grf = <0x2f>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + phandle = <0x10c>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + port@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0x13>; + status = "okay"; + phandle = <0xa3>; + }; + }; + }; + + panel@0 { + compatible = "elida,kd35t133\0simple-panel-dsi"; + reg = <0x00>; + backlight = <0x9d>; + backlight-supply = <0x9e>; + power-supply = <0x9f>; + reset-gpios = <0x97 0x10 0x01>; + prepare-delay-ms = <0x02>; + reset-delay-ms = <0x01>; + init-delay-ms = <0x14>; + enable-delay-ms = <0x78>; + disable-delay-ms = <0x32>; + unprepare-delay-ms = <0x14>; + width-mm = <0x34>; + height-mm = <0x46>; + dsi,flags = <0xa03>; + dsi,format = <0x00>; + dsi,lanes = <0x04>; + panel-init-sequence = <0x150002ff 0x30150002 0xff521500 0x2ff0115 0x2e300 0x15000240 0xa150002 0x3401500 0x2040015 0x20503 0x15000224 0x12150002 0x251e1500 0x2262815 0x22752 0x15000228 0x57150002 0x29011500 0x22adf15 0x2389c 0x15000239 0xa7150002 0x3a531500 0x2440015 0x2493c 0x15000259 0xfe150002 0x5c001500 0x2917715 0x29277 0x150002a0 0x55150002 0xa1501500 0x2a49c15 0x2a702 0x150002a8 0x1150002 0xa9011500 0x2aafc15 0x2ab28 0x150002ac 0x6150002 0xad061500 0x2ae0615 0x2af03 0x150002b0 0x8150002 0xb1261500 0x2b22815 0x2b328 0x150002b4 0x33150002 0xb5081500 0x2b62615 0x2b708 0x150002b8 0x26150002 0xff301500 0x2ff5215 0x2ff02 0x150002b0 0xb150002 0xb1161500 0x2b21715 0x2b32c 0x150002b4 0x32150002 0xb53b1500 0x2b62915 0x2b740 0x150002b8 0xd150002 0xb9051500 0x2ba1215 0x2bb10 0x150002bc 0x12150002 0xbd151500 0x2be1915 0x2bf0e 0x150002c0 0x16150002 0xc10a1500 0x2d00c15 0x2d117 0x150002d2 0x14150002 0xd32e1500 0x2d43215 0x2d53c 0x150002d6 0x22150002 0xd73d1500 0x2d80d15 0x2d907 0x150002da 0x13150002 0xdb131500 0x2dc1115 0x2dd15 0x150002de 0x19150002 0xdf101500 0x2e01715 0x2e10a 0x150002ff 0x30150002 0xff521500 0x2ff0315 0x2002a 0x15000201 0x2a150002 0x22a1500 0x2032a15 0x20461 0x15000205 0x80150002 0x6c71500 0x2070115 0x20882 0x15000209 0x83150002 0x302a1500 0x2312a15 0x2322a 0x15000233 0x2a150002 0x34611500 0x235c515 0x23680 0x15000237 0x23150002 0x40821500 0x2418315 0x24280 0x15000243 0x81150002 0x44111500 0x245e615 0x246e5 0x15000247 0x11150002 0x48e81500 0x249e715 0x25002 0x15000251 0x1150002 0x52041500 0x2530315 0x25411 0x15000255 0xea150002 0x56e91500 0x2571115 0x258ec 0x15000259 0xeb150002 0x7e021500 0x27f8015 0x2e05a 0x150002b1 0x150002 0xb40e1500 0x2b50f15 0x2b604 0x150002b7 0x7150002 0xb8061500 0x2b90515 0x2ba0f 0x150002c7 0x150002 0xca0e1500 0x2cb0f15 0x2cc04 0x150002cd 0x7150002 0xce061500 0x2cf0515 0x2d00f 0x15000281 0xf150002 0x840e1500 0x2850f15 0x28607 0x15000287 0x4150002 0x88051500 0x2890615 0x28a00 0x15000297 0xf150002 0x9a0e1500 0x29b0f15 0x29c07 0x1500029d 0x4150002 0x9e051500 0x29f0615 0x2a000 0x150002ff 0x30150002 0xff521500 0x2ff0215 0x20101 0x15000202 0xda150002 0x3ba1500 0x204a815 0x2059a 0x15000206 0x70150002 0x7ff1500 0x2089115 0x20990 0x1500020a 0xff150002 0xb8f1500 0x20c6015 0x20d58 0x1500020e 0x48150002 0xf381500 0x2102b15 0x2ff30 0x150002ff 0x52150002 0xff001500 0x2360215 0x23a70 0x5c80111 0x50a0129>; + panel-exit-sequence = <0x5140128 0x50a0110>; + + display-timings { + native-mode = <0xa0>; + + 60Hz { + clock-frequency = <0x192d500>; + hactive = <0x280>; + vactive = <0x1e0>; + hfront-porch = <0x77>; + hsync-len = <0x02>; + hback-porch = <0x77>; + vfront-porch = <0x0d>; + vsync-len = <0x02>; + vback-porch = <0x05>; + hsync-active = <0x00>; + vsync-active = <0x00>; + de-active = <0x00>; + pixelclk-active = <0x00>; + phandle = <0xa0>; + }; + + 50Hz { + clock-frequency = <0x192d500>; + hactive = <0x280>; + vactive = <0x1e0>; + hfront-porch = <0xcf>; + hsync-len = <0x02>; + hback-porch = <0xcf>; + vfront-porch = <0x0d>; + vsync-len = <0x02>; + vback-porch = <0x05>; + hsync-active = <0x00>; + vsync-active = <0x00>; + de-active = <0x00>; + pixelclk-active = <0x00>; + phandle = <0x10d>; + }; + + 75Hz { + clock-frequency = <0x192d500>; + hactive = <0x280>; + vactive = <0x1e0>; + hfront-porch = <0x1f>; + hsync-len = <0x02>; + hback-porch = <0x1f>; + vfront-porch = <0x0d>; + vsync-len = <0x02>; + vback-porch = <0x05>; + hsync-active = <0x00>; + vsync-active = <0x00>; + de-active = <0x00>; + pixelclk-active = <0x00>; + phandle = <0x10e>; + }; + }; + }; + }; + + vop@ff460000 { + compatible = "rockchip,px30-vop-big"; + reg = <0x00 0xff460000 0x00 0x1fc 0x00 0xff460a00 0x00 0x400>; + rockchip,grf = <0x2f>; + reg-names = "regs\0gamma_lut"; + interrupts = <0x00 0x4d 0x04>; + clocks = <0x02 0xb5 0x02 0x96 0x02 0xfb>; + clock-names = "aclk_vop\0dclk_vop\0hclk_vop"; + power-domains = <0x8a 0x0c>; + iommus = <0xa1>; + status = "okay"; + phandle = <0x10f>; + + port { + #address-cells = <0x01>; + #size-cells = <0x00>; + phandle = <0x10>; + + endpoint@0 { + reg = <0x00>; + remote-endpoint = <0xa2>; + phandle = <0x12>; + }; + + endpoint@1 { + reg = <0x01>; + remote-endpoint = <0xa3>; + phandle = <0x13>; + }; + + endpoint@2 { + reg = <0x02>; + remote-endpoint = <0xa4>; + phandle = <0x14>; + }; + }; + }; + + iommu@ff460f00 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff460f00 0x00 0x100>; + interrupts = <0x00 0x4d 0x04>; + interrupt-names = "vopb_mmu"; + clocks = <0x02 0xb5 0x02 0xfb>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0c>; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xa1>; + }; + + rk_rga@ff480000 { + compatible = "rockchip,rga2"; + reg = <0x00 0xff480000 0x00 0x1000>; + interrupts = <0x00 0x4c 0x04>; + clocks = <0x02 0xb7 0x02 0xfd 0x02 0x35>; + clock-names = "aclk_rga\0hclk_rga\0clk_rga"; + power-domains = <0x8a 0x0c>; + dma-coherent; + status = "okay"; + phandle = <0x110>; + }; + + cif@ff490000 { + compatible = "rockchip,cif"; + reg = <0x00 0xff490000 0x00 0x200>; + interrupts = <0x00 0x45 0x04>; + clocks = <0x02 0xb3 0x02 0xf9 0x02 0x160 0x02 0x34>; + clock-names = "aclk_cif0\0hclk_cif0\0pclk_cif\0cif0_out"; + resets = <0x02 0x2c 0x02 0x2d 0x02 0x2e>; + reset-names = "rst_cif_a\0rst_cif_h\0rst_cif_pclkin"; + power-domains = <0x8a 0x0d>; + pinctrl-names = "cif_pin_all"; + pinctrl-0 = <0xa5>; + iommus = <0xa6>; + status = "disabled"; + phandle = <0x111>; + }; + + cif-new@ff490000 { + compatible = "rockchip,px30-cif"; + reg = <0x00 0xff490000 0x00 0x200>; + interrupts = <0x00 0x45 0x04>; + clocks = <0x02 0xb3 0x02 0xf9 0x02 0x160 0x02 0x34>; + clock-names = "aclk_cif\0hclk_cif\0pclk_cif\0cif_out"; + resets = <0x02 0x2c 0x02 0x2d 0x02 0x2e>; + reset-names = "rst_cif_a\0rst_cif_h\0rst_cif_pclkin"; + power-domains = <0x8a 0x0d>; + iommus = <0xa6>; + status = "disabled"; + phandle = <0x112>; + }; + + iommu@ff490800 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff490800 0x00 0x100>; + interrupts = <0x00 0x45 0x04>; + interrupt-names = "vip_mmu"; + clocks = <0x02 0xb3 0x02 0xf9>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0d>; + rk_iommu,disable_reset_quirk; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xa6>; + }; + + rk_isp@ff4a0000 { + compatible = "rockchip,px30-isp\0rockchip,isp"; + reg = <0x00 0xff4a0000 0x00 0x8000>; + interrupts = <0x00 0x46 0x04>; + clocks = <0x02 0xb4 0x02 0xfa 0x02 0x33 0x02 0x33 0x02 0x15f 0x02 0x34 0x02 0x34 0x02 0x146>; + clock-names = "aclk_isp\0hclk_isp\0clk_isp\0clk_isp_jpe\0pclkin_isp\0clk_cif_pll\0clk_cif_out\0pclk_dphyrx"; + resets = <0x02 0x2b 0x02 0x2f>; + reset-names = "rst_isp\0rst_mipicsiphy"; + power-domains = <0x8a 0x0d>; + pinctrl-names = "default\0isp_dvp8bit2\0isp_dvp10bit\0isp_dvp12bit"; + pinctrl-0 = <0xa7>; + pinctrl-1 = <0xa5>; + pinctrl-2 = <0xa5 0xa8>; + pinctrl-3 = <0xa9 0xa5 0xa8>; + rockchip,isp,mipiphy = <0x01>; + rockchip,isp,csiphy,reg = <0xff2f0000 0x4000>; + rockchip,grf = <0x2f>; + rockchip,cru = <0x02>; + rockchip,isp,iommu-enable = <0x01>; + iommus = <0xaa>; + status = "disabled"; + phandle = <0x113>; + }; + + rkisp1@ff4a0000 { + compatible = "rockchip,rk3326-rkisp1"; + reg = <0x00 0xff4a0000 0x00 0x8000>; + interrupts = <0x00 0x46 0x04 0x00 0x49 0x04 0x00 0x4a 0x04>; + interrupt-names = "isp_irq\0mi_irq\0mipi_irq"; + clocks = <0x02 0xb4 0x02 0xfa 0x02 0x33 0x02 0x15f>; + clock-names = "aclk_isp\0hclk_isp\0clk_isp\0pclk_isp"; + devfreq = <0xab>; + power-domains = <0x8a 0x0d>; + iommus = <0xaa>; + rockchip,grf = <0x2f>; + status = "okay"; + phandle = <0x114>; + }; + + iommu@ff4a8000 { + compatible = "rockchip,iommu"; + reg = <0x00 0xff4a8000 0x00 0x100>; + interrupts = <0x00 0x46 0x04>; + interrupt-names = "isp_mmu"; + clocks = <0x02 0xb4 0x02 0xfa>; + clock-names = "aclk\0hclk"; + power-domains = <0x8a 0x0d>; + rk_iommu,disable_reset_quirk; + #iommu-cells = <0x00>; + status = "okay"; + phandle = <0xaa>; + }; + + qos@ff518000 { + compatible = "syscon"; + reg = <0x00 0xff518000 0x00 0x20>; + phandle = <0x18>; + }; + + qos@ff520000 { + compatible = "syscon"; + reg = <0x00 0xff520000 0x00 0x20>; + phandle = <0x28>; + }; + + qos@ff52c000 { + compatible = "syscon"; + reg = <0x00 0xff52c000 0x00 0x20>; + phandle = <0x17>; + }; + + qos@ff538000 { + compatible = "syscon"; + reg = <0x00 0xff538000 0x00 0x20>; + phandle = <0x19>; + }; + + qos@ff538080 { + compatible = "syscon"; + reg = <0x00 0xff538080 0x00 0x20>; + phandle = <0x1a>; + }; + + qos@ff538100 { + compatible = "syscon"; + reg = <0x00 0xff538100 0x00 0x20>; + phandle = <0x1b>; + }; + + qos@ff538180 { + compatible = "syscon"; + reg = <0x00 0xff538180 0x00 0x20>; + phandle = <0x1c>; + }; + + qos@ff540000 { + compatible = "syscon"; + reg = <0x00 0xff540000 0x00 0x20>; + phandle = <0x15>; + }; + + qos@ff540080 { + compatible = "syscon"; + reg = <0x00 0xff540080 0x00 0x20>; + phandle = <0x16>; + }; + + qos@ff548000 { + compatible = "syscon"; + reg = <0x00 0xff548000 0x00 0x20>; + phandle = <0x23>; + }; + + qos@ff548080 { + compatible = "syscon"; + reg = <0x00 0xff548080 0x00 0x20>; + phandle = <0x24>; + }; + + qos@ff548100 { + compatible = "syscon"; + reg = <0x00 0xff548100 0x00 0x20>; + phandle = <0x25>; + }; + + qos@ff548180 { + compatible = "syscon"; + reg = <0x00 0xff548180 0x00 0x20>; + phandle = <0x26>; + }; + + qos@ff548200 { + compatible = "syscon"; + reg = <0x00 0xff548200 0x00 0x20>; + phandle = <0x27>; + }; + + qos@ff550000 { + compatible = "syscon"; + reg = <0x00 0xff550000 0x00 0x20>; + phandle = <0x1f>; + }; + + qos@ff550080 { + compatible = "syscon"; + reg = <0x00 0xff550080 0x00 0x20>; + phandle = <0x20>; + }; + + qos@ff550100 { + compatible = "syscon"; + reg = <0x00 0xff550100 0x00 0x20>; + phandle = <0x21>; + }; + + qos@ff550180 { + compatible = "syscon"; + reg = <0x00 0xff550180 0x00 0x20>; + phandle = <0x22>; + }; + + qos@ff558000 { + compatible = "syscon"; + reg = <0x00 0xff558000 0x00 0x20>; + phandle = <0x1d>; + }; + + qos@ff558080 { + compatible = "syscon"; + reg = <0x00 0xff558080 0x00 0x20>; + phandle = <0x1e>; + }; + + dfi@ff610000 { + reg = <0x00 0xff610000 0x00 0x400>; + compatible = "rockchip,px30-dfi"; + rockchip,pmugrf = <0xac>; + status = "okay"; + phandle = <0xad>; + }; + + dmc { + compatible = "rockchip,px30-dmc"; + interrupts = <0x00 0x69 0x04>; + interrupt-names = "complete_irq"; + devfreq-events = <0xad>; + clocks = <0x02 0x54>; + clock-names = "dmc_clk"; + operating-points-v2 = <0xae>; + ddr_timing = <0xaf>; + upthreshold = <0x28>; + downdifferential = <0x14>; + system-status-freq = <0x01 0x80e80 0x08 0x6ddd0 0x02 0x2f5d0 0x20 0x6ddd0 0x1000 0x80e80 0x4000 0xa2990 0x2000 0xa2990>; + auto-min-freq = <0x50140>; + auto-freq-en = <0x01>; + #cooling-cells = <0x02>; + status = "okay"; + center-supply = <0x0e>; + phandle = <0xab>; + + ddr_power_model { + compatible = "ddr_power_model"; + dynamic-power-coefficient = <0x78>; + static-power-coefficient = <0xc8>; + ts = <0x7d00 0x125c 0xffffffb0 0x02>; + thermal-zone = "soc-thermal"; + phandle = <0x115>; + }; + }; + + dmc-opp-table { + compatible = "operating-points-v2"; + rockchip,max-volt = <0x118c30>; + rockchip,evb-irdrop = <0x61a8>; + rockchip,pvtm-voltage-sel = <0x00 0xc350 0x00 0xc351 0xd2f0 0x01 0xd2f1 0xea60 0x02 0xea61 0x1869f 0x03>; + rockchip,pvtm-ch = <0x00 0x00>; + phandle = <0xae>; + + opp-528000000 { + opp-hz = <0x00 0x1f78a400>; + opp-microvolt = <0xee098>; + opp-microvolt-L0 = <0xee098>; + opp-microvolt-L1 = <0xee098>; + opp-microvolt-L2 = <0xe7ef0>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-666000000 { + opp-hz = <0x00 0x27b25a80>; + opp-microvolt = <0x100590>; + opp-microvolt-L0 = <0x100590>; + opp-microvolt-L1 = <0xf4240>; + opp-microvolt-L2 = <0xee098>; + opp-microvolt-L3 = <0xe7ef0>; + }; + + opp-786000000 { + opp-hz = <0x00 0x2ed96880>; + opp-microvolt = <0x10c8e0>; + opp-microvolt-L0 = <0x10c8e0>; + opp-microvolt-L1 = <0x100590>; + opp-microvolt-L2 = <0xfa3e8>; + opp-microvolt-L3 = <0xf4240>; + status = "okay"; + }; + }; + + rockchip-system-monitor { + compatible = "rockchip,system-monitor"; + rockchip,thermal-zone = "soc-thermal"; + rockchip,polling-delay = <0xc8>; + phandle = <0x116>; + }; + + pinctrl { + compatible = "rockchip,px30-pinctrl"; + rockchip,grf = <0x2f>; + rockchip,pmu = <0xac>; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + phandle = <0x117>; + + gpio0@ff040000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff040000 0x00 0x100>; + interrupts = <0x00 0x03 0x04>; + clocks = <0x2a 0x14>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x5c>; + }; + + gpio1@ff250000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff250000 0x00 0x100>; + interrupts = <0x00 0x04 0x04>; + clocks = <0x02 0x15c>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0xbf>; + }; + + gpio2@ff260000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff260000 0x00 0x100>; + interrupts = <0x00 0x05 0x04>; + clocks = <0x02 0x15d>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x66>; + }; + + gpio3@ff270000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xff270000 0x00 0x100>; + interrupts = <0x00 0x06 0x04>; + clocks = <0x02 0x15e>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + phandle = <0x97>; + }; + + pcfg-pull-up { + bias-pull-up; + phandle = <0xb2>; + }; + + pcfg-pull-down { + bias-pull-down; + phandle = <0x118>; + }; + + pcfg-pull-none { + bias-disable; + phandle = <0xb1>; + }; + + pcfg-pull-none-2ma { + bias-disable; + drive-strength = <0x02>; + phandle = <0x119>; + }; + + pcfg-pull-up-2ma { + bias-pull-up; + drive-strength = <0x02>; + phandle = <0x11a>; + }; + + pcfg-pull-up-4ma { + bias-pull-up; + drive-strength = <0x04>; + phandle = <0xb3>; + }; + + pcfg-pull-none-4ma { + bias-disable; + drive-strength = <0x04>; + phandle = <0x11b>; + }; + + pcfg-pull-down-4ma { + bias-pull-down; + drive-strength = <0x04>; + phandle = <0x11c>; + }; + + pcfg-pull-none-8ma { + bias-disable; + drive-strength = <0x08>; + phandle = <0xb6>; + }; + + pcfg-pull-up-8ma { + bias-pull-up; + drive-strength = <0x08>; + phandle = <0xb4>; + }; + + pcfg-pull-none-12ma { + bias-disable; + drive-strength = <0x0c>; + phandle = <0xb8>; + }; + + pcfg-pull-up-12ma { + bias-pull-up; + drive-strength = <0x0c>; + phandle = <0xb7>; + }; + + pcfg-pull-none-smt { + bias-disable; + input-schmitt-enable; + phandle = <0xb0>; + }; + + pcfg-output-high { + output-high; + phandle = <0x11d>; + }; + + pcfg-output-low { + output-low; + phandle = <0xb9>; + }; + + pcfg-input-high { + bias-pull-up; + input-enable; + phandle = <0xb5>; + }; + + pcfg-input { + input-enable; + phandle = <0x11e>; + }; + + i2c0 { + + i2c0-xfer { + rockchip,pins = <0x00 0x08 0x01 0xb0 0x00 0x09 0x01 0xb0>; + phandle = <0x5b>; + }; + }; + + i2c1 { + + i2c1-xfer { + rockchip,pins = <0x00 0x12 0x01 0xb0 0x00 0x13 0x01 0xb0>; + phandle = <0x69>; + }; + }; + + i2c2 { + + i2c2-xfer { + rockchip,pins = <0x02 0x0f 0x02 0xb0 0x02 0x10 0x02 0xb0>; + phandle = <0x6a>; + }; + }; + + i2c3 { + + i2c3-xfer { + rockchip,pins = <0x01 0x0c 0x04 0xb0 0x01 0x0d 0x04 0xb0>; + phandle = <0x6b>; + }; + }; + + tsadc { + + tsadc-otp-gpio { + rockchip,pins = <0x00 0x06 0x00 0xb1>; + phandle = <0x86>; + }; + + tsadc-otp-out { + rockchip,pins = <0x00 0x06 0x01 0xb1>; + phandle = <0x87>; + }; + }; + + uart0 { + + uart0-xfer { + rockchip,pins = <0x00 0x0a 0x01 0xb2 0x00 0x0b 0x01 0xb2>; + phandle = <0x2c>; + }; + + uart0-cts { + rockchip,pins = <0x00 0x0c 0x01 0xb1>; + phandle = <0x2d>; + }; + + uart0-rts { + rockchip,pins = <0x00 0x0d 0x01 0xb1>; + phandle = <0x2e>; + }; + + uart0-rts-gpio { + rockchip,pins = <0x00 0x0d 0x00 0xb1>; + phandle = <0x11f>; + }; + }; + + uart1 { + + uart1-xfer { + rockchip,pins = <0x01 0x11 0x01 0xb2 0x01 0x10 0x01 0xb2>; + phandle = <0x4f>; + }; + + uart1-cts { + rockchip,pins = <0x01 0x12 0x01 0xb1>; + phandle = <0x50>; + }; + + uart1-rts { + rockchip,pins = <0x01 0x13 0x01 0xb1>; + phandle = <0x120>; + }; + + uart1-rts-gpio { + rockchip,pins = <0x01 0x13 0x00 0xb1>; + phandle = <0x121>; + }; + }; + + uart2-m0 { + + uart2m0-xfer { + rockchip,pins = <0x01 0x1a 0x02 0xb2 0x01 0x1b 0x02 0xb2>; + phandle = <0x51>; + }; + }; + + uart2-m1 { + + uart2m1-xfer { + rockchip,pins = <0x02 0x0c 0x02 0xb2 0x02 0x0e 0x02 0xb2>; + phandle = <0xba>; + }; + }; + + uart3-m0 { + + uart3m0-xfer { + rockchip,pins = <0x00 0x10 0x02 0xb2 0x00 0x11 0x02 0xb2>; + phandle = <0x122>; + }; + + uart3m0-cts { + rockchip,pins = <0x00 0x12 0x02 0xb1>; + phandle = <0x123>; + }; + + uart3m0-rts { + rockchip,pins = <0x00 0x13 0x02 0xb1>; + phandle = <0x124>; + }; + + uart3m0-rts-gpio { + rockchip,pins = <0x00 0x13 0x00 0xb1>; + phandle = <0x125>; + }; + }; + + uart3-m1 { + + uart3m1-xfer { + rockchip,pins = <0x01 0x0e 0x02 0xb2 0x01 0x0f 0x02 0xb2>; + phandle = <0x52>; + }; + + uart3m1-cts { + rockchip,pins = <0x01 0x0c 0x02 0xb1>; + phandle = <0x53>; + }; + + uart3m1-rts { + rockchip,pins = <0x01 0x0d 0x02 0xb1>; + phandle = <0x54>; + }; + + uart3m1-rts-gpio { + rockchip,pins = <0x01 0x0d 0x00 0xb1>; + phandle = <0x126>; + }; + }; + + uart4 { + + uart4-xfer { + rockchip,pins = <0x01 0x1c 0x02 0xb2 0x01 0x1d 0x02 0xb2>; + phandle = <0x55>; + }; + + uart4-cts { + rockchip,pins = <0x01 0x1e 0x02 0xb1>; + phandle = <0x56>; + }; + + uart4-rts { + rockchip,pins = <0x01 0x1f 0x02 0xb1>; + phandle = <0x57>; + }; + }; + + uart5 { + + uart5-xfer { + rockchip,pins = <0x03 0x02 0x04 0xb2 0x03 0x01 0x04 0xb2>; + phandle = <0x58>; + }; + + uart5-cts { + rockchip,pins = <0x03 0x03 0x04 0xb1>; + phandle = <0x59>; + }; + + uart5-rts { + rockchip,pins = <0x03 0x05 0x04 0xb1>; + phandle = <0x5a>; + }; + }; + + spi0 { + + spi0-clk { + rockchip,pins = <0x01 0x0f 0x03 0xb3>; + phandle = <0x6c>; + }; + + spi0-csn { + rockchip,pins = <0x01 0x0e 0x03 0xb3>; + phandle = <0x6d>; + }; + + spi0-miso { + rockchip,pins = <0x01 0x0d 0x03 0xb3>; + phandle = <0x6e>; + }; + + spi0-mosi { + rockchip,pins = <0x01 0x0c 0x03 0xb3>; + phandle = <0x6f>; + }; + + spi0-clk-hs { + rockchip,pins = <0x01 0x0f 0x03 0xb4>; + phandle = <0x70>; + }; + + spi0-miso-hs { + rockchip,pins = <0x01 0x0d 0x03 0xb4>; + phandle = <0x71>; + }; + + spi0-mosi-hs { + rockchip,pins = <0x01 0x0c 0x03 0xb4>; + phandle = <0x72>; + }; + }; + + spi1 { + + spi1-clk { + rockchip,pins = <0x03 0x0f 0x04 0xb3>; + phandle = <0x73>; + }; + + spi1-csn0 { + rockchip,pins = <0x03 0x09 0x04 0xb3>; + phandle = <0x74>; + }; + + spi1-csn1 { + rockchip,pins = <0x03 0x0a 0x02 0xb3>; + phandle = <0x75>; + }; + + spi1-miso { + rockchip,pins = <0x03 0x0e 0x04 0xb3>; + phandle = <0x76>; + }; + + spi1-mosi { + rockchip,pins = <0x03 0x0c 0x04 0xb3>; + phandle = <0x77>; + }; + + spi1-clk-hs { + rockchip,pins = <0x03 0x0f 0x04 0xb4>; + phandle = <0x78>; + }; + + spi1-miso-hs { + rockchip,pins = <0x03 0x0e 0x04 0xb4>; + phandle = <0x79>; + }; + + spi1-mosi-hs { + rockchip,pins = <0x03 0x0c 0x04 0xb4>; + phandle = <0x7a>; + }; + }; + + pdm { + + pdm-clk0m0 { + rockchip,pins = <0x03 0x16 0x02 0xb1>; + phandle = <0x44>; + }; + + pdm-clk0m1 { + rockchip,pins = <0x02 0x16 0x01 0xb1>; + phandle = <0x127>; + }; + + pdm-clk1 { + rockchip,pins = <0x03 0x17 0x02 0xb1>; + phandle = <0x45>; + }; + + pdm-sdi0m0 { + rockchip,pins = <0x03 0x1b 0x02 0xb1>; + phandle = <0x46>; + }; + + pdm-sdi0m1 { + rockchip,pins = <0x02 0x15 0x02 0xb1>; + phandle = <0x128>; + }; + + pdm-sdi1 { + rockchip,pins = <0x03 0x18 0x02 0xb1>; + phandle = <0x47>; + }; + + pdm-sdi2 { + rockchip,pins = <0x03 0x19 0x02 0xb1>; + phandle = <0x48>; + }; + + pdm-sdi3 { + rockchip,pins = <0x03 0x1a 0x02 0xb1>; + phandle = <0x49>; + }; + + pdm-clk0m0-sleep { + rockchip,pins = <0x03 0x16 0x00 0xb5>; + phandle = <0x129>; + }; + + pdm-clk0m1-sleep { + rockchip,pins = <0x02 0x16 0x00 0xb5>; + phandle = <0x12a>; + }; + + pdm-clk1-sleep { + rockchip,pins = <0x03 0x17 0x00 0xb5>; + phandle = <0x12b>; + }; + + pdm-sdi0m0-sleep { + rockchip,pins = <0x03 0x1b 0x00 0xb5>; + phandle = <0x12c>; + }; + + pdm-sdi0m1-sleep { + rockchip,pins = <0x02 0x15 0x00 0xb5>; + phandle = <0x12d>; + }; + + pdm-sdi1-sleep { + rockchip,pins = <0x03 0x18 0x00 0xb5>; + phandle = <0x12e>; + }; + + pdm-sdi2-sleep { + rockchip,pins = <0x03 0x19 0x00 0xb5>; + phandle = <0x12f>; + }; + + pdm-sdi3-sleep { + rockchip,pins = <0x03 0x1a 0x00 0xb5>; + phandle = <0x130>; + }; + }; + + i2s0 { + + i2s0-8ch-mclk { + rockchip,pins = <0x03 0x11 0x02 0xb1>; + phandle = <0x131>; + }; + + i2s0-8ch-sclktx { + rockchip,pins = <0x03 0x13 0x02 0xb1>; + phandle = <0x30>; + }; + + i2s0-8ch-sclkrx { + rockchip,pins = <0x03 0x0c 0x02 0xb1>; + phandle = <0x31>; + }; + + i2s0-8ch-lrcktx { + rockchip,pins = <0x03 0x12 0x02 0xb1>; + phandle = <0x32>; + }; + + i2s0-8ch-lrckrx { + rockchip,pins = <0x03 0x0d 0x02 0xb1>; + phandle = <0x33>; + }; + + i2s0-8ch-sdo0 { + rockchip,pins = <0x03 0x14 0x02 0xb1>; + phandle = <0x38>; + }; + + i2s0-8ch-sdo1 { + rockchip,pins = <0x03 0x10 0x02 0xb1>; + phandle = <0x39>; + }; + + i2s0-8ch-sdo2 { + rockchip,pins = <0x03 0x0f 0x02 0xb1>; + phandle = <0x3a>; + }; + + i2s0-8ch-sdo3 { + rockchip,pins = <0x03 0x0e 0x02 0xb1>; + phandle = <0x3b>; + }; + + i2s0-8ch-sdi0 { + rockchip,pins = <0x03 0x15 0x02 0xb1>; + phandle = <0x34>; + }; + + i2s0-8ch-sdi1 { + rockchip,pins = <0x03 0x0b 0x02 0xb1>; + phandle = <0x35>; + }; + + i2s0-8ch-sdi2 { + rockchip,pins = <0x03 0x09 0x02 0xb1>; + phandle = <0x36>; + }; + + i2s0-8ch-sdi3 { + rockchip,pins = <0x03 0x08 0x02 0xb1>; + phandle = <0x37>; + }; + }; + + i2s1 { + + i2s1-2ch-mclk { + rockchip,pins = <0x02 0x13 0x01 0xb1>; + phandle = <0x68>; + }; + + i2s1-2ch-sclk { + rockchip,pins = <0x02 0x12 0x01 0xb1>; + phandle = <0x3c>; + }; + + i2s1-2ch-lrck { + rockchip,pins = <0x02 0x11 0x01 0xb1>; + phandle = <0x3d>; + }; + + i2s1-2ch-sdi { + rockchip,pins = <0x02 0x15 0x01 0xb1>; + phandle = <0x3e>; + }; + + i2s1-2ch-sdo { + rockchip,pins = <0x02 0x14 0x01 0xb1>; + phandle = <0x3f>; + }; + }; + + i2s2 { + + i2s2-2ch-mclk { + rockchip,pins = <0x03 0x01 0x02 0xb1>; + phandle = <0x132>; + }; + + i2s2-2ch-sclk { + rockchip,pins = <0x03 0x02 0x02 0xb1>; + phandle = <0x40>; + }; + + i2s2-2ch-lrck { + rockchip,pins = <0x03 0x03 0x02 0xb1>; + phandle = <0x41>; + }; + + i2s2-2ch-sdi { + rockchip,pins = <0x03 0x05 0x02 0xb1>; + phandle = <0x42>; + }; + + i2s2-2ch-sdo { + rockchip,pins = <0x03 0x07 0x02 0xb1>; + phandle = <0x43>; + }; + }; + + sdmmc { + + sdmmc-clk { + rockchip,pins = <0x01 0x1e 0x01 0xb6>; + phandle = <0x8f>; + }; + + sdmmc-cmd { + rockchip,pins = <0x01 0x1f 0x01 0xb4>; + phandle = <0x90>; + }; + + sdmmc-det { + rockchip,pins = <0x00 0x03 0x01 0xb4>; + phandle = <0x91>; + }; + + sdmmc-bus1 { + rockchip,pins = <0x01 0x1a 0x01 0xb4>; + phandle = <0x133>; + }; + + sdmmc-bus4 { + rockchip,pins = <0x01 0x1a 0x01 0xb4 0x01 0x1b 0x01 0xb4 0x01 0x1c 0x01 0xb4 0x01 0x1d 0x01 0xb4>; + phandle = <0x92>; + }; + + sdmmc-gpio { + rockchip,pins = <0x01 0x1a 0x00 0xb3 0x01 0x1b 0x00 0xb3 0x01 0x1c 0x00 0xb3 0x01 0x1d 0x00 0xb3 0x01 0x1e 0x00 0xb3 0x01 0x1f 0x00 0xb3>; + phandle = <0x134>; + }; + }; + + sdio { + + sdio-clk { + rockchip,pins = <0x01 0x15 0x01 0xb1>; + phandle = <0x96>; + }; + + sdio-cmd { + rockchip,pins = <0x01 0x14 0x01 0xb2>; + phandle = <0x95>; + }; + + sdio-bus4 { + rockchip,pins = <0x01 0x16 0x01 0xb2 0x01 0x17 0x01 0xb2 0x01 0x18 0x01 0xb2 0x01 0x19 0x01 0xb2>; + phandle = <0x94>; + }; + + sdio-gpio { + rockchip,pins = <0x01 0x16 0x00 0xb2 0x01 0x17 0x00 0xb2 0x01 0x18 0x00 0xb2 0x01 0x19 0x00 0xb2 0x01 0x14 0x00 0xb2 0x01 0x15 0x00 0xb2>; + phandle = <0x135>; + }; + }; + + emmc { + + emmc-clk { + rockchip,pins = <0x01 0x09 0x02 0xb6>; + phandle = <0x136>; + }; + + emmc-cmd { + rockchip,pins = <0x01 0x0a 0x02 0xb4>; + phandle = <0x137>; + }; + + emmc-pwren { + rockchip,pins = <0x01 0x08 0x02 0xb1>; + phandle = <0x138>; + }; + + emmc-rstnout { + rockchip,pins = <0x01 0x0b 0x02 0xb1>; + phandle = <0x139>; + }; + + emmc-bus1 { + rockchip,pins = <0x01 0x00 0x02 0xb4>; + phandle = <0x13a>; + }; + + emmc-bus4 { + rockchip,pins = <0x01 0x00 0x02 0xb4 0x01 0x01 0x02 0xb4 0x01 0x02 0x02 0xb4 0x01 0x03 0x02 0xb4>; + phandle = <0x13b>; + }; + + emmc-bus8 { + rockchip,pins = <0x01 0x00 0x02 0xb4 0x01 0x01 0x02 0xb4 0x01 0x02 0x02 0xb4 0x01 0x03 0x02 0xb4 0x01 0x04 0x02 0xb4 0x01 0x05 0x02 0xb4 0x01 0x06 0x02 0xb4 0x01 0x07 0x02 0xb4>; + phandle = <0x13c>; + }; + }; + + flash { + + flash-cs0 { + rockchip,pins = <0x01 0x08 0x01 0xb1>; + phandle = <0x13d>; + }; + + flash-rdy { + rockchip,pins = <0x01 0x09 0x01 0xb1>; + phandle = <0x13e>; + }; + + flash-dqs { + rockchip,pins = <0x01 0x0a 0x01 0xb1>; + phandle = <0x13f>; + }; + + flash-ale { + rockchip,pins = <0x01 0x0b 0x01 0xb1>; + phandle = <0x140>; + }; + + flash-cle { + rockchip,pins = <0x01 0x0c 0x01 0xb1>; + phandle = <0x141>; + }; + + flash-wrn { + rockchip,pins = <0x01 0x0d 0x01 0xb1>; + phandle = <0x142>; + }; + + flash-csl { + rockchip,pins = <0x01 0x0e 0x01 0xb1>; + phandle = <0x143>; + }; + + flash-rdn { + rockchip,pins = <0x01 0x0f 0x01 0xb1>; + phandle = <0x144>; + }; + + flash-bus8 { + rockchip,pins = <0x01 0x00 0x01 0xb7 0x01 0x01 0x01 0xb7 0x01 0x02 0x01 0xb7 0x01 0x03 0x01 0xb7 0x01 0x04 0x01 0xb7 0x01 0x05 0x01 0xb7 0x01 0x06 0x01 0xb7 0x01 0x07 0x01 0xb7>; + phandle = <0x145>; + }; + }; + + lcdc { + + lcdc-m0-rgb-pins { + rockchip,pins = <0x03 0x00 0x01 0xb6 0x03 0x01 0x01 0xb6 0x03 0x02 0x01 0xb6 0x03 0x03 0x01 0xb6 0x03 0x04 0x01 0xb6 0x03 0x05 0x01 0xb6 0x03 0x06 0x01 0xb6 0x03 0x07 0x01 0xb6 0x03 0x08 0x01 0xb6 0x03 0x09 0x01 0xb6 0x03 0x0a 0x01 0xb6 0x03 0x0b 0x01 0xb6 0x03 0x0c 0x01 0xb6 0x03 0x0d 0x01 0xb6 0x03 0x0e 0x01 0xb6 0x03 0x0f 0x01 0xb6 0x03 0x10 0x01 0xb6 0x03 0x11 0x01 0xb6 0x03 0x12 0x01 0xb6 0x03 0x13 0x01 0xb6 0x03 0x14 0x01 0xb6 0x03 0x15 0x01 0xb6 0x03 0x16 0x01 0xb6 0x03 0x17 0x01 0xb6 0x03 0x18 0x01 0xb6 0x03 0x19 0x01 0xb6 0x03 0x1a 0x01 0xb6 0x03 0x1b 0x01 0xb6>; + phandle = <0x146>; + }; + + lcdc-m0-sleep-pins { + rockchip,pins = <0x03 0x00 0x00 0xb1 0x03 0x01 0x00 0xb1 0x03 0x02 0x00 0xb1 0x03 0x03 0x00 0xb1 0x03 0x04 0x00 0xb1 0x03 0x05 0x00 0xb1 0x03 0x06 0x00 0xb1 0x03 0x07 0x00 0xb1 0x03 0x08 0x00 0xb1 0x03 0x09 0x00 0xb1 0x03 0x0a 0x00 0xb1 0x03 0x0b 0x00 0xb1 0x03 0x0c 0x00 0xb1 0x03 0x0d 0x00 0xb1 0x03 0x0e 0x00 0xb1 0x03 0x0f 0x00 0xb1 0x03 0x10 0x00 0xb1 0x03 0x11 0x00 0xb1 0x03 0x12 0x00 0xb1 0x03 0x13 0x00 0xb1 0x03 0x14 0x00 0xb1 0x03 0x15 0x00 0xb1 0x03 0x16 0x00 0xb1 0x03 0x17 0x00 0xb1 0x03 0x18 0x00 0xb1 0x03 0x19 0x00 0xb1 0x03 0x1a 0x00 0xb1 0x03 0x1b 0x00 0xb1>; + phandle = <0x147>; + }; + + lcdc-m1-rgb-pins { + rockchip,pins = <0x03 0x00 0x01 0xb6 0x03 0x04 0x01 0xb6 0x03 0x06 0x01 0xb6 0x03 0x0a 0x01 0xb6 0x03 0x0b 0x01 0xb6 0x03 0x0d 0x01 0xb6 0x03 0x10 0x01 0xb6 0x03 0x11 0x01 0xb6 0x03 0x12 0x01 0xb6 0x03 0x13 0x01 0xb6 0x03 0x14 0x01 0xb6 0x03 0x15 0x01 0xb6 0x03 0x16 0x01 0xb6 0x03 0x17 0x01 0xb6 0x03 0x18 0x01 0xb6 0x03 0x19 0x01 0xb6 0x03 0x1a 0x01 0xb6 0x03 0x1b 0x01 0xb6>; + phandle = <0x4d>; + }; + + lcdc-m1-sleep-pins { + rockchip,pins = <0x03 0x00 0x00 0xb1 0x03 0x04 0x00 0xb1 0x03 0x06 0x00 0xb1 0x03 0x0a 0x00 0xb1 0x03 0x0b 0x00 0xb1 0x03 0x0d 0x00 0xb1 0x03 0x10 0x00 0xb1 0x03 0x11 0x00 0xb1 0x03 0x12 0x00 0xb1 0x03 0x13 0x00 0xb1 0x03 0x14 0x00 0xb1 0x03 0x15 0x00 0xb1 0x03 0x16 0x00 0xb1 0x03 0x17 0x00 0xb1 0x03 0x18 0x00 0xb1 0x03 0x19 0x00 0xb1 0x03 0x1a 0x00 0xb1 0x03 0x1b 0x00 0xb1>; + phandle = <0x4e>; + }; + }; + + pwm0 { + + pwm0-pin { + rockchip,pins = <0x00 0x0f 0x01 0xb1>; + phandle = <0x7b>; + }; + }; + + pwm1 { + + pwm1-pin { + rockchip,pins = <0x00 0x10 0x01 0xb1>; + phandle = <0x7c>; + }; + }; + + pwm2 { + + pwm2-pin { + rockchip,pins = <0x02 0x0d 0x01 0xb1>; + phandle = <0x7d>; + }; + }; + + pwm3 { + + pwm3-pin { + rockchip,pins = <0x00 0x11 0x01 0xb1>; + phandle = <0x7e>; + }; + }; + + pwm4 { + + pwm4-pin { + rockchip,pins = <0x03 0x12 0x03 0xb1>; + phandle = <0x7f>; + }; + }; + + pwm5 { + + pwm5-pin { + rockchip,pins = <0x03 0x13 0x03 0xb1>; + phandle = <0x80>; + }; + }; + + pwm6 { + + pwm6-pin { + rockchip,pins = <0x03 0x14 0x03 0xb1>; + phandle = <0x81>; + }; + }; + + pwm7 { + + pwm7-pin { + rockchip,pins = <0x03 0x15 0x03 0xb1>; + phandle = <0x82>; + }; + }; + + gmac { + + rmii-pins { + rockchip,pins = <0x02 0x00 0x02 0xb8 0x02 0x01 0x02 0xb8 0x02 0x02 0x02 0xb8 0x02 0x03 0x02 0xb1 0x02 0x04 0x02 0xb1 0x02 0x05 0x02 0xb1 0x02 0x06 0x02 0xb1 0x02 0x07 0x02 0xb1 0x02 0x09 0x02 0xb1>; + phandle = <0x8d>; + }; + + mac-refclk-12ma { + rockchip,pins = <0x02 0x0a 0x02 0xb8>; + phandle = <0x8e>; + }; + + mac-refclk { + rockchip,pins = <0x02 0x0a 0x02 0xb1>; + phandle = <0x148>; + }; + }; + + cif-m0 { + + cif-clkout-m0 { + rockchip,pins = <0x02 0x0b 0x01 0xb8>; + phandle = <0xa7>; + }; + + dvp-d2d9-m0 { + rockchip,pins = <0x02 0x00 0x01 0xb1 0x02 0x01 0x01 0xb1 0x02 0x02 0x01 0xb1 0x02 0x03 0x01 0xb1 0x02 0x04 0x01 0xb1 0x02 0x05 0x01 0xb1 0x02 0x06 0x01 0xb1 0x02 0x07 0x01 0xb1 0x02 0x08 0x01 0xb1 0x02 0x09 0x01 0xb1 0x02 0x0a 0x01 0xb1 0x02 0x0b 0x01 0xb1>; + phandle = <0xa5>; + }; + + dvp-d0d1-m0 { + rockchip,pins = <0x02 0x0c 0x01 0xb1 0x02 0x0e 0x01 0xb1>; + phandle = <0xa9>; + }; + + d10-d11-m0 { + rockchip,pins = <0x02 0x0f 0x01 0xb1 0x02 0x10 0x01 0xb1>; + phandle = <0xa8>; + }; + }; + + cif-m1 { + + cif-clkout-m1 { + rockchip,pins = <0x03 0x18 0x03 0xb1>; + phandle = <0x149>; + }; + + dvp-d2d9-m1 { + rockchip,pins = <0x03 0x03 0x03 0xb1 0x03 0x05 0x03 0xb1 0x03 0x07 0x03 0xb1 0x03 0x08 0x03 0xb1 0x03 0x09 0x03 0xb1 0x03 0x0c 0x03 0xb1 0x03 0x0e 0x03 0xb1 0x03 0x0f 0x03 0xb1 0x03 0x19 0x03 0xb1 0x03 0x1a 0x03 0xb1 0x03 0x1b 0x03 0xb1 0x03 0x18 0x03 0xb1>; + phandle = <0x14a>; + }; + + dvp-d0d1-m1 { + rockchip,pins = <0x03 0x01 0x03 0xb1 0x03 0x02 0x03 0xb1>; + phandle = <0x14b>; + }; + + d10-d11-m1 { + rockchip,pins = <0x03 0x16 0x03 0xb1 0x03 0x17 0x03 0xb1>; + phandle = <0x14c>; + }; + }; + + isp { + + isp-prelight { + rockchip,pins = <0x03 0x19 0x04 0xb1>; + phandle = <0x14d>; + }; + }; + + pmic { + + pmic_int { + rockchip,pins = <0x00 0x0a 0x00 0xb2 0x00 0x0b 0x00 0xb1>; + phandle = <0x5d>; + }; + + soc_slppin_gpio { + rockchip,pins = <0x00 0x04 0x00 0xb9>; + phandle = <0x60>; + }; + + soc_slppin_slp { + rockchip,pins = <0x00 0x04 0x01 0xb1>; + phandle = <0x5e>; + }; + + soc_slppin_rst { + rockchip,pins = <0x00 0x04 0x02 0xb1>; + phandle = <0x62>; + }; + }; + + leds { + + led-pins { + rockchip,pins = <0x00 0x11 0x00 0xb1>; + phandle = <0xc0>; + }; + }; + + btns { + + btn-pins { + rockchip,pins = <0x01 0x0c 0x00 0xb2 0x01 0x0d 0x00 0xb2 0x01 0x0e 0x00 0xb2 0x01 0x0f 0x00 0xb2 0x01 0x02 0x00 0xb2 0x01 0x05 0x00 0xb2 0x01 0x06 0x00 0xb2 0x01 0x07 0x00 0xb2 0x02 0x00 0x00 0xb2 0x02 0x01 0x00 0xb2 0x02 0x02 0x00 0xb2 0x02 0x03 0x00 0xb2 0x02 0x04 0x00 0xb2 0x02 0x05 0x00 0xb2 0x02 0x06 0x00 0xb2 0x02 0x07 0x00 0xb2 0x03 0x09 0x00 0xb2 0x03 0x0a 0x00 0xb2 0x03 0x0c 0x00 0xb2 0x03 0x0f 0x00 0xb2>; + phandle = <0xbd>; + }; + }; + }; + + chosen { + bootargs = [00]; + }; + + fiq-debugger { + compatible = "rockchip,fiq-debugger"; + rockchip,serial-id = <0x02>; + rockchip,wake-irq = <0x00>; + rockchip,irq-mode-enable = <0x00>; + rockchip,baudrate = <0x1c200>; + interrupts = <0x00 0x7f 0x08>; + pinctrl-names = "default"; + pinctrl-0 = <0xba>; + status = "okay"; + }; + + ramoops { + compatible = "ramoops"; + record-size = <0x00 0x20000>; + console-size = <0x00 0x80000>; + ftrace-size = <0x00 0x00>; + pmsg-size = <0x00 0x00>; + memory-region = <0xbb>; + }; + + reserved-memory { + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + + drm-logo@00000000 { + compatible = "rockchip,drm-logo"; + reg = <0x00 0x00 0x00 0x00>; + phandle = <0x11>; + }; + + region@110000 { + reg = <0x00 0x110000 0x00 0xf0000>; + reg-names = "ramoops_mem"; + phandle = <0xbb>; + }; + }; + + odroidgo3-keys { + compatible = "gpio-keys"; + #address-cells = <0x01>; + #size-cells = <0x00>; + autorepeat; + phandle = <0x14e>; + + button@0 { + label = "GPIO BTN-VOLUP"; + linux,code = <0x73>; + gpios = <0x66 0x00 0x01>; + }; + + button@1 { + label = "GPIO BTN-VOLDN"; + linux,code = <0x72>; + gpios = <0x66 0x01 0x01>; + }; + }; + + odroidgo3-joypad { + compatible = "odroidgo3-joypad"; + pwms = <0xbc 0x00 0xbebc200 0x00>; + pwm-names = "enable"; + rumble-boost-weak = <0x00>; + rumble-boost-strong = <0x00>; + joypad-name = "GO-Super Gamepad"; + joypad-product = <0x1100>; + joypad-revision = <0x100>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <0xbd>; + pinctrl-1 = <0x7b>; + io-channel-names = "amux_adc"; + io-channels = <0xbe 0x01>; + amux-count = <0x04>; + amux-a-gpios = <0x97 0x0b 0x01>; + amux-b-gpios = <0x97 0x08 0x01>; + amux-en-gpios = <0x97 0x0d 0x01>; + button-adc-scale = <0x02>; + button-adc-deadzone = <0x40>; + button-adc-fuzz = <0x20>; + button-adc-flat = <0x20>; + abs_x-p-tuning = <0xc8>; + abs_x-n-tuning = <0xc8>; + abs_y-p-tuning = <0xc8>; + abs_y-n-tuning = <0xc8>; + abs_rx-p-tuning = <0xc8>; + abs_rx-n-tuning = <0xc8>; + abs_ry-p-tuning = <0xc8>; + abs_ry-n-tuning = <0xc8>; + poll-interval = <0x0a>; + invert-absx; + invert-absy; + phandle = <0x14f>; + + sw1 { + gpios = <0xbf 0x0c 0x01>; + label = "GPIO DPAD-UP"; + linux,code = <0x220>; + }; + + sw2 { + gpios = <0xbf 0x0d 0x01>; + label = "GPIO DPAD-DOWN"; + linux,code = <0x221>; + }; + + sw3 { + gpios = <0xbf 0x0e 0x01>; + label = "GPIO DPAD-LEFT"; + linux,code = <0x222>; + }; + + sw4 { + gpios = <0xbf 0x0f 0x01>; + label = "GPIO DPAD-RIGHT"; + linux,code = <0x223>; + }; + + sw5 { + gpios = <0xbf 0x02 0x01>; + label = "GPIO KEY BTN-A"; + linux,code = <0x131>; + }; + + sw6 { + gpios = <0xbf 0x05 0x01>; + label = "GPIO BTN-B"; + linux,code = <0x130>; + }; + + sw7 { + gpios = <0xbf 0x06 0x01>; + label = "GPIO BTN-Y"; + linux,code = <0x134>; + }; + + sw8 { + gpios = <0xbf 0x07 0x01>; + label = "GPIO BTN-X"; + linux,code = <0x133>; + }; + + sw11 { + gpios = <0x66 0x02 0x01>; + label = "GPIO F3"; + linux,code = <0x2c2>; + }; + + sw12 { + gpios = <0x66 0x03 0x01>; + label = "GPIO F4"; + linux,code = <0x2c3>; + }; + + sw13 { + gpios = <0x66 0x04 0x01>; + label = "GPIO F5"; + linux,code = <0x2c4>; + }; + + sw15 { + gpios = <0x66 0x06 0x01>; + label = "GPIO TOP-LEFT"; + linux,code = <0x136>; + }; + + sw16 { + gpios = <0x66 0x07 0x01>; + label = "GPIO TOP-RIGHT"; + linux,code = <0x137>; + }; + + sw19 { + gpios = <0x97 0x09 0x01>; + label = "GPIO F1"; + linux,code = <0x2c0>; + }; + + sw20 { + gpios = <0x97 0x0f 0x01>; + label = "GPIO TOP-RIGHT2"; + linux,code = <0x139>; + }; + + sw21 { + gpios = <0x97 0x0a 0x01>; + label = "GPIO TOP-LEFT2"; + linux,code = <0x138>; + }; + + sw22 { + gpios = <0x97 0x0c 0x01>; + label = "GPIO F2"; + linux,code = <0x2c1>; + }; + }; + + gpio_leds { + compatible = "gpio-leds"; + pinctrl-names = "led_pins"; + pinctrl-0 = <0xc0>; + phandle = <0x150>; + + heartbeat { + label = "blue:heartbeat"; + gpios = <0x5c 0x11 0x00>; + linux,default-trigger = "heartbeat"; + }; + }; + + backlight { + compatible = "pwm-backlight"; + pwms = <0xc1 0x00 0x9c40 0x00>; + brightness-levels = <0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2a 0x2b 0x2c 0x2d 0x2e 0x2f 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x3a 0x3b 0x3c 0x3d 0x3e 0x3f 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48 0x49 0x4a 0x4b 0x4c 0x4d 0x4e 0x4f 0x50 0x51 0x52 0x53 0x54 0x55 0x56 0x57 0x58 0x59 0x5a 0x5b 0x5c 0x5d 0x5e 0x5f 0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69 0x6a 0x6b 0x6c 0x6d 0x6e 0x6f 0x70 0x71 0x72 0x73 0x74 0x75 0x76 0x77 0x78 0x79 0x7a 0x7b 0x7c 0x7d 0x7e 0x7f 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90 0x91 0x92 0x93 0x94 0x95 0x96 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f 0xa0>; + default-brightness-level = <0x50>; + phandle = <0x9d>; + }; + + rk817-sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,name = "rockchip,rk817-codec"; + simple-audio-card,mclk-fs = <0x100>; + simple-audio-card,widgets = "Microphone\0Mic Jack\0Headphone\0Headphone Jack"; + simple-audio-card,routing = "MIC_IN\0Mic Jack\0Headphone Jack\0HPOL\0Headphone Jack\0HPOR"; + simple-audio-card,hp-det-gpio = <0x66 0x16 0x01>; + simple-audio-card,codec-hp-det = <0x01>; + + simple-audio-card,cpu { + sound-dai = <0xc2>; + }; + + simple-audio-card,codec { + sound-dai = <0xc3>; + }; + }; + + vccsys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v8_sys"; + regulator-always-on; + regulator-min-microvolt = <0x39fbc0>; + regulator-max-microvolt = <0x39fbc0>; + phandle = <0x64>; + }; + + __symbols__ { + ddr_timing = "/ddr_timing"; + cpu0 = "/cpus/cpu@0"; + cpu1 = "/cpus/cpu@1"; + cpu2 = "/cpus/cpu@2"; + cpu3 = "/cpus/cpu@3"; + CPU_SLEEP = "/cpus/idle-states/cpu-sleep"; + CLUSTER_SLEEP = "/cpus/idle-states/cluster-sleep"; + cpu0_opp_table = "/cpu0-opp-table"; + bus_soc = "/bus-soc"; + bus_apll = "/bus-apll"; + bus_apll_opp_table = "/bus-apll-opp-table"; + display_subsystem = "/display-subsystem"; + route_lvds = "/display-subsystem/route/route-lvds"; + route_dsi = "/display-subsystem/route/route-dsi"; + route_rgb = "/display-subsystem/route/route-rgb"; + gmac_clkin = "/external-gmac-clock"; + rockchip_suspend = "/rockchip-suspend"; + xin24m = "/xin24m"; + xin32k = "/xin32k"; + pmu = "/power-management@ff000000"; + power = "/power-management@ff000000/power-controller"; + pmugrf = "/syscon@ff010000"; + pmu_io_domains = "/syscon@ff010000/io-domains"; + pmu_pvtm = "/syscon@ff010000/pmu-pvtm"; + uart0 = "/serial@ff030000"; + i2s0_8ch = "/i2s@ff060000"; + i2s1_2ch = "/i2s@ff070000"; + i2s2_2ch = "/i2s@ff080000"; + pdm = "/pdm@ff0a0000"; + crypto = "/crypto@ff0b0000"; + rng = "/rng@ff0b0000"; + gic = "/interrupt-controller@ff131000"; + grf = "/syscon@ff140000"; + io_domains = "/syscon@ff140000/io-domains"; + lvds = "/syscon@ff140000/lvds"; + lvds_in_vopb = "/syscon@ff140000/lvds/ports/port@0/endpoint@0"; + rgb = "/syscon@ff140000/rgb"; + rgb_in_vopb = "/syscon@ff140000/rgb/ports/port@0/endpoint@0"; + core_grf = "/syscon@ff148000"; + pvtm = "/syscon@ff148000/pvtm"; + uart1 = "/serial@ff158000"; + uart2 = "/serial@ff160000"; + uart3 = "/serial@ff168000"; + uart4 = "/serial@ff170000"; + uart5 = "/serial@ff178000"; + i2c0 = "/i2c@ff180000"; + rk817 = "/i2c@ff180000/pmic@20"; + pinctrl_rk8xx = "/i2c@ff180000/pmic@20/pinctrl_rk8xx"; + rk817_ts_gpio1 = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_ts_gpio1"; + rk817_gt_gpio2 = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_gt_gpio2"; + rk817_pin_ts = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_pin_ts"; + rk817_pin_gt = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_pin_gt"; + rk817_slppin_null = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_null"; + rk817_slppin_slp = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_slp"; + rk817_slppin_pwrdn = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_pwrdn"; + rk817_slppin_rst = "/i2c@ff180000/pmic@20/pinctrl_rk8xx/rk817_slppin_rst"; + vdd_logic = "/i2c@ff180000/pmic@20/regulators/DCDC_REG1"; + vdd_arm = "/i2c@ff180000/pmic@20/regulators/DCDC_REG2"; + vcc_ddr = "/i2c@ff180000/pmic@20/regulators/DCDC_REG3"; + vcc_3v3 = "/i2c@ff180000/pmic@20/regulators/DCDC_REG4"; + vcc_1v0 = "/i2c@ff180000/pmic@20/regulators/LDO_REG1"; + vcc1v8_soc = "/i2c@ff180000/pmic@20/regulators/LDO_REG2"; + vdd1v0_soc = "/i2c@ff180000/pmic@20/regulators/LDO_REG3"; + vcc3v3_pmu = "/i2c@ff180000/pmic@20/regulators/LDO_REG4"; + vccio_sd = "/i2c@ff180000/pmic@20/regulators/LDO_REG5"; + vcc_sd = "/i2c@ff180000/pmic@20/regulators/LDO_REG6"; + vcc_backlight = "/i2c@ff180000/pmic@20/regulators/LDO_REG7"; + vcc_lcd = "/i2c@ff180000/pmic@20/regulators/LDO_REG8"; + dcdc_boost = "/i2c@ff180000/pmic@20/regulators/BOOST"; + otg_switch = "/i2c@ff180000/pmic@20/regulators/OTG_SWITCH"; + rk817_codec = "/i2c@ff180000/pmic@20/codec"; + i2c1 = "/i2c@ff190000"; + i2c2 = "/i2c@ff1a0000"; + i2c3 = "/i2c@ff1b0000"; + spi0 = "/spi@ff1d0000"; + spi1 = "/spi@ff1d8000"; + wdt = "/watchdog@ff1e0000"; + pwm0 = "/pwm@ff200000"; + pwm1 = "/pwm@ff200010"; + pwm2 = "/pwm@ff200020"; + pwm3 = "/pwm@ff200030"; + pwm4 = "/pwm@ff208000"; + pwm5 = "/pwm@ff208010"; + pwm6 = "/pwm@ff208020"; + pwm7 = "/pwm@ff208030"; + rktimer = "/rktimer@ff210000"; + dmac = "/amba/dmac@ff240000"; + thermal_zones = "/thermal-zones"; + soc_thermal = "/thermal-zones/soc-thermal"; + threshold = "/thermal-zones/soc-thermal/trips/trip-point-0"; + target = "/thermal-zones/soc-thermal/trips/trip-point-1"; + soc_crit = "/thermal-zones/soc-thermal/trips/soc-crit"; + gpu_thermal = "/thermal-zones/gpu-thermal"; + tsadc = "/tsadc@ff280000"; + saradc = "/saradc@ff288000"; + otp = "/otp@ff290000"; + otp_id = "/otp@ff290000/id@7"; + cpu_leakage = "/otp@ff290000/cpu-leakage@17"; + performance = "/otp@ff290000/performance@1e"; + cru = "/clock-controller@ff2b0000"; + cpu_boost = "/cpu-boost@ff2b8000"; + pmucru = "/pmu-clock-controller@ff2bc000"; + usb2phy_grf = "/syscon@ff2c0000"; + u2phy = "/syscon@ff2c0000/usb2-phy@100"; + u2phy_host = "/syscon@ff2c0000/usb2-phy@100/host-port"; + u2phy_otg = "/syscon@ff2c0000/usb2-phy@100/otg-port"; + video_phy = "/video-phy@ff2e0000"; + mipi_dphy_rx0 = "/mipi-dphy-rx0@ff2f0000"; + usb20_otg = "/usb@ff300000"; + usb_host0_ehci = "/usb@ff340000"; + usb_host0_ohci = "/usb@ff350000"; + gmac = "/ethernet@ff360000"; + sdmmc = "/dwmmc@ff370000"; + sdio = "/dwmmc@ff380000"; + emmc = "/dwmmc@ff390000"; + nandc0 = "/nandc@ff3b0000"; + sfc = "/sfc@ff3a0000"; + gpu = "/gpu@ff400000"; + gpu_opp_table = "/gpu-opp-table"; + hevc = "/hevc_service@ff440000"; + vpu = "/vpu_service@ff442000"; + vpu_combo = "/vpu_combo"; + hevc_mmu = "/iommu@ff440440"; + vpu_mmu = "/iommu@ff442800"; + dsi = "/dsi@ff450000"; + dsi_in_vopb = "/dsi@ff450000/ports/port@0/endpoint@0"; + timing0 = "/dsi@ff450000/panel@0/display-timings/60Hz"; + timing1 = "/dsi@ff450000/panel@0/display-timings/50Hz"; + timing2 = "/dsi@ff450000/panel@0/display-timings/75Hz"; + vopb = "/vop@ff460000"; + vopb_out = "/vop@ff460000/port"; + vopb_out_lvds = "/vop@ff460000/port/endpoint@0"; + vopb_out_dsi = "/vop@ff460000/port/endpoint@1"; + vopb_out_rgb = "/vop@ff460000/port/endpoint@2"; + vopb_mmu = "/iommu@ff460f00"; + rk_rga = "/rk_rga@ff480000"; + cif = "/cif@ff490000"; + cif_new = "/cif-new@ff490000"; + vip_mmu = "/iommu@ff490800"; + rk_isp = "/rk_isp@ff4a0000"; + rkisp1 = "/rkisp1@ff4a0000"; + isp_mmu = "/iommu@ff4a8000"; + qos_gmac = "/qos@ff518000"; + qos_gpu = "/qos@ff520000"; + qos_sdmmc = "/qos@ff52c000"; + qos_emmc = "/qos@ff538000"; + qos_nand = "/qos@ff538080"; + qos_sdio = "/qos@ff538100"; + qos_sfc = "/qos@ff538180"; + qos_usb_host = "/qos@ff540000"; + qos_usb_otg = "/qos@ff540080"; + qos_isp_128 = "/qos@ff548000"; + qos_isp_rd = "/qos@ff548080"; + qos_isp_wr = "/qos@ff548100"; + qos_isp_m1 = "/qos@ff548180"; + qos_vip = "/qos@ff548200"; + qos_rga_rd = "/qos@ff550000"; + qos_rga_wr = "/qos@ff550080"; + qos_vop_m0 = "/qos@ff550100"; + qos_vop_m1 = "/qos@ff550180"; + qos_vpu = "/qos@ff558000"; + qos_vpu_r128 = "/qos@ff558080"; + dfi = "/dfi@ff610000"; + dmc = "/dmc"; + ddr_power_model = "/dmc/ddr_power_model"; + dmc_opp_table = "/dmc-opp-table"; + rockchip_system_monitor = "/rockchip-system-monitor"; + pinctrl = "/pinctrl"; + gpio0 = "/pinctrl/gpio0@ff040000"; + gpio1 = "/pinctrl/gpio1@ff250000"; + gpio2 = "/pinctrl/gpio2@ff260000"; + gpio3 = "/pinctrl/gpio3@ff270000"; + pcfg_pull_up = "/pinctrl/pcfg-pull-up"; + pcfg_pull_down = "/pinctrl/pcfg-pull-down"; + pcfg_pull_none = "/pinctrl/pcfg-pull-none"; + pcfg_pull_none_2ma = "/pinctrl/pcfg-pull-none-2ma"; + pcfg_pull_up_2ma = "/pinctrl/pcfg-pull-up-2ma"; + pcfg_pull_up_4ma = "/pinctrl/pcfg-pull-up-4ma"; + pcfg_pull_none_4ma = "/pinctrl/pcfg-pull-none-4ma"; + pcfg_pull_down_4ma = "/pinctrl/pcfg-pull-down-4ma"; + pcfg_pull_none_8ma = "/pinctrl/pcfg-pull-none-8ma"; + pcfg_pull_up_8ma = "/pinctrl/pcfg-pull-up-8ma"; + pcfg_pull_none_12ma = "/pinctrl/pcfg-pull-none-12ma"; + pcfg_pull_up_12ma = "/pinctrl/pcfg-pull-up-12ma"; + pcfg_pull_none_smt = "/pinctrl/pcfg-pull-none-smt"; + pcfg_output_high = "/pinctrl/pcfg-output-high"; + pcfg_output_low = "/pinctrl/pcfg-output-low"; + pcfg_input_high = "/pinctrl/pcfg-input-high"; + pcfg_input = "/pinctrl/pcfg-input"; + i2c0_xfer = "/pinctrl/i2c0/i2c0-xfer"; + i2c1_xfer = "/pinctrl/i2c1/i2c1-xfer"; + i2c2_xfer = "/pinctrl/i2c2/i2c2-xfer"; + i2c3_xfer = "/pinctrl/i2c3/i2c3-xfer"; + tsadc_otp_gpio = "/pinctrl/tsadc/tsadc-otp-gpio"; + tsadc_otp_out = "/pinctrl/tsadc/tsadc-otp-out"; + uart0_xfer = "/pinctrl/uart0/uart0-xfer"; + uart0_cts = "/pinctrl/uart0/uart0-cts"; + uart0_rts = "/pinctrl/uart0/uart0-rts"; + uart0_rts_gpio = "/pinctrl/uart0/uart0-rts-gpio"; + uart1_xfer = "/pinctrl/uart1/uart1-xfer"; + uart1_cts = "/pinctrl/uart1/uart1-cts"; + uart1_rts = "/pinctrl/uart1/uart1-rts"; + uart1_rts_gpio = "/pinctrl/uart1/uart1-rts-gpio"; + uart2m0_xfer = "/pinctrl/uart2-m0/uart2m0-xfer"; + uart2m1_xfer = "/pinctrl/uart2-m1/uart2m1-xfer"; + uart3m0_xfer = "/pinctrl/uart3-m0/uart3m0-xfer"; + uart3m0_cts = "/pinctrl/uart3-m0/uart3m0-cts"; + uart3m0_rts = "/pinctrl/uart3-m0/uart3m0-rts"; + uart3m0_rts_gpio = "/pinctrl/uart3-m0/uart3m0-rts-gpio"; + uart3m1_xfer = "/pinctrl/uart3-m1/uart3m1-xfer"; + uart3m1_cts = "/pinctrl/uart3-m1/uart3m1-cts"; + uart3m1_rts = "/pinctrl/uart3-m1/uart3m1-rts"; + uart3m1_rts_gpio = "/pinctrl/uart3-m1/uart3m1-rts-gpio"; + uart4_xfer = "/pinctrl/uart4/uart4-xfer"; + uart4_cts = "/pinctrl/uart4/uart4-cts"; + uart4_rts = "/pinctrl/uart4/uart4-rts"; + uart5_xfer = "/pinctrl/uart5/uart5-xfer"; + uart5_cts = "/pinctrl/uart5/uart5-cts"; + uart5_rts = "/pinctrl/uart5/uart5-rts"; + spi0_clk = "/pinctrl/spi0/spi0-clk"; + spi0_csn = "/pinctrl/spi0/spi0-csn"; + spi0_miso = "/pinctrl/spi0/spi0-miso"; + spi0_mosi = "/pinctrl/spi0/spi0-mosi"; + spi0_clk_hs = "/pinctrl/spi0/spi0-clk-hs"; + spi0_miso_hs = "/pinctrl/spi0/spi0-miso-hs"; + spi0_mosi_hs = "/pinctrl/spi0/spi0-mosi-hs"; + spi1_clk = "/pinctrl/spi1/spi1-clk"; + spi1_csn0 = "/pinctrl/spi1/spi1-csn0"; + spi1_csn1 = "/pinctrl/spi1/spi1-csn1"; + spi1_miso = "/pinctrl/spi1/spi1-miso"; + spi1_mosi = "/pinctrl/spi1/spi1-mosi"; + spi1_clk_hs = "/pinctrl/spi1/spi1-clk-hs"; + spi1_miso_hs = "/pinctrl/spi1/spi1-miso-hs"; + spi1_mosi_hs = "/pinctrl/spi1/spi1-mosi-hs"; + pdm_clk0m0 = "/pinctrl/pdm/pdm-clk0m0"; + pdm_clk0m1 = "/pinctrl/pdm/pdm-clk0m1"; + pdm_clk1 = "/pinctrl/pdm/pdm-clk1"; + pdm_sdi0m0 = "/pinctrl/pdm/pdm-sdi0m0"; + pdm_sdi0m1 = "/pinctrl/pdm/pdm-sdi0m1"; + pdm_sdi1 = "/pinctrl/pdm/pdm-sdi1"; + pdm_sdi2 = "/pinctrl/pdm/pdm-sdi2"; + pdm_sdi3 = "/pinctrl/pdm/pdm-sdi3"; + pdm_clk0m0_sleep = "/pinctrl/pdm/pdm-clk0m0-sleep"; + pdm_clk0m_sleep1 = "/pinctrl/pdm/pdm-clk0m1-sleep"; + pdm_clk1_sleep = "/pinctrl/pdm/pdm-clk1-sleep"; + pdm_sdi0m0_sleep = "/pinctrl/pdm/pdm-sdi0m0-sleep"; + pdm_sdi0m1_sleep = "/pinctrl/pdm/pdm-sdi0m1-sleep"; + pdm_sdi1_sleep = "/pinctrl/pdm/pdm-sdi1-sleep"; + pdm_sdi2_sleep = "/pinctrl/pdm/pdm-sdi2-sleep"; + pdm_sdi3_sleep = "/pinctrl/pdm/pdm-sdi3-sleep"; + i2s0_8ch_mclk = "/pinctrl/i2s0/i2s0-8ch-mclk"; + i2s0_8ch_sclktx = "/pinctrl/i2s0/i2s0-8ch-sclktx"; + i2s0_8ch_sclkrx = "/pinctrl/i2s0/i2s0-8ch-sclkrx"; + i2s0_8ch_lrcktx = "/pinctrl/i2s0/i2s0-8ch-lrcktx"; + i2s0_8ch_lrckrx = "/pinctrl/i2s0/i2s0-8ch-lrckrx"; + i2s0_8ch_sdo0 = "/pinctrl/i2s0/i2s0-8ch-sdo0"; + i2s0_8ch_sdo1 = "/pinctrl/i2s0/i2s0-8ch-sdo1"; + i2s0_8ch_sdo2 = "/pinctrl/i2s0/i2s0-8ch-sdo2"; + i2s0_8ch_sdo3 = "/pinctrl/i2s0/i2s0-8ch-sdo3"; + i2s0_8ch_sdi0 = "/pinctrl/i2s0/i2s0-8ch-sdi0"; + i2s0_8ch_sdi1 = "/pinctrl/i2s0/i2s0-8ch-sdi1"; + i2s0_8ch_sdi2 = "/pinctrl/i2s0/i2s0-8ch-sdi2"; + i2s0_8ch_sdi3 = "/pinctrl/i2s0/i2s0-8ch-sdi3"; + i2s1_2ch_mclk = "/pinctrl/i2s1/i2s1-2ch-mclk"; + i2s1_2ch_sclk = "/pinctrl/i2s1/i2s1-2ch-sclk"; + i2s1_2ch_lrck = "/pinctrl/i2s1/i2s1-2ch-lrck"; + i2s1_2ch_sdi = "/pinctrl/i2s1/i2s1-2ch-sdi"; + i2s1_2ch_sdo = "/pinctrl/i2s1/i2s1-2ch-sdo"; + i2s2_2ch_mclk = "/pinctrl/i2s2/i2s2-2ch-mclk"; + i2s2_2ch_sclk = "/pinctrl/i2s2/i2s2-2ch-sclk"; + i2s2_2ch_lrck = "/pinctrl/i2s2/i2s2-2ch-lrck"; + i2s2_2ch_sdi = "/pinctrl/i2s2/i2s2-2ch-sdi"; + i2s2_2ch_sdo = "/pinctrl/i2s2/i2s2-2ch-sdo"; + sdmmc_clk = "/pinctrl/sdmmc/sdmmc-clk"; + sdmmc_cmd = "/pinctrl/sdmmc/sdmmc-cmd"; + sdmmc_det = "/pinctrl/sdmmc/sdmmc-det"; + sdmmc_bus1 = "/pinctrl/sdmmc/sdmmc-bus1"; + sdmmc_bus4 = "/pinctrl/sdmmc/sdmmc-bus4"; + sdmmc_gpio = "/pinctrl/sdmmc/sdmmc-gpio"; + sdio_clk = "/pinctrl/sdio/sdio-clk"; + sdio_cmd = "/pinctrl/sdio/sdio-cmd"; + sdio_bus4 = "/pinctrl/sdio/sdio-bus4"; + sdio_gpio = "/pinctrl/sdio/sdio-gpio"; + emmc_clk = "/pinctrl/emmc/emmc-clk"; + emmc_cmd = "/pinctrl/emmc/emmc-cmd"; + emmc_pwren = "/pinctrl/emmc/emmc-pwren"; + emmc_rstnout = "/pinctrl/emmc/emmc-rstnout"; + emmc_bus1 = "/pinctrl/emmc/emmc-bus1"; + emmc_bus4 = "/pinctrl/emmc/emmc-bus4"; + emmc_bus8 = "/pinctrl/emmc/emmc-bus8"; + flash_cs0 = "/pinctrl/flash/flash-cs0"; + flash_rdy = "/pinctrl/flash/flash-rdy"; + flash_dqs = "/pinctrl/flash/flash-dqs"; + flash_ale = "/pinctrl/flash/flash-ale"; + flash_cle = "/pinctrl/flash/flash-cle"; + flash_wrn = "/pinctrl/flash/flash-wrn"; + flash_csl = "/pinctrl/flash/flash-csl"; + flash_rdn = "/pinctrl/flash/flash-rdn"; + flash_bus8 = "/pinctrl/flash/flash-bus8"; + lcdc_m0_rgb_pins = "/pinctrl/lcdc/lcdc-m0-rgb-pins"; + lcdc_m0_sleep_pins = "/pinctrl/lcdc/lcdc-m0-sleep-pins"; + lcdc_m1_rgb_pins = "/pinctrl/lcdc/lcdc-m1-rgb-pins"; + lcdc_m1_sleep_pins = "/pinctrl/lcdc/lcdc-m1-sleep-pins"; + pwm0_pin = "/pinctrl/pwm0/pwm0-pin"; + pwm1_pin = "/pinctrl/pwm1/pwm1-pin"; + pwm2_pin = "/pinctrl/pwm2/pwm2-pin"; + pwm3_pin = "/pinctrl/pwm3/pwm3-pin"; + pwm4_pin = "/pinctrl/pwm4/pwm4-pin"; + pwm5_pin = "/pinctrl/pwm5/pwm5-pin"; + pwm6_pin = "/pinctrl/pwm6/pwm6-pin"; + pwm7_pin = "/pinctrl/pwm7/pwm7-pin"; + rmii_pins = "/pinctrl/gmac/rmii-pins"; + mac_refclk_12ma = "/pinctrl/gmac/mac-refclk-12ma"; + mac_refclk = "/pinctrl/gmac/mac-refclk"; + cif_clkout_m0 = "/pinctrl/cif-m0/cif-clkout-m0"; + dvp_d2d9_m0 = "/pinctrl/cif-m0/dvp-d2d9-m0"; + dvp_d0d1_m0 = "/pinctrl/cif-m0/dvp-d0d1-m0"; + dvp_d10d11_m0 = "/pinctrl/cif-m0/d10-d11-m0"; + cif_clkout_m1 = "/pinctrl/cif-m1/cif-clkout-m1"; + dvp_d2d9_m1 = "/pinctrl/cif-m1/dvp-d2d9-m1"; + dvp_d0d1_m1 = "/pinctrl/cif-m1/dvp-d0d1-m1"; + dvp_d10d11_m1 = "/pinctrl/cif-m1/d10-d11-m1"; + isp_prelight = "/pinctrl/isp/isp-prelight"; + pmic_int = "/pinctrl/pmic/pmic_int"; + soc_slppin_gpio = "/pinctrl/pmic/soc_slppin_gpio"; + soc_slppin_slp = "/pinctrl/pmic/soc_slppin_slp"; + soc_slppin_rst = "/pinctrl/pmic/soc_slppin_rst"; + led_pins = "/pinctrl/leds/led-pins"; + btn_pins = "/pinctrl/btns/btn-pins"; + drm_logo = "/reserved-memory/drm-logo@00000000"; + ramoops_mem = "/reserved-memory/region@110000"; + gpio_keys = "/odroidgo3-keys"; + joypad = "/odroidgo3-joypad"; + leds = "/gpio_leds"; + backlight = "/backlight"; + vccsys = "/vccsys"; + }; +}; diff --git a/config/archr-dts/retrogame_joypad_s2_f1.dtsi b/config/archr-dts/retrogame_joypad_s2_f1.dtsi new file mode 100644 index 0000000000..7a0f231091 --- /dev/null +++ b/config/archr-dts/retrogame_joypad_s2_f1.dtsi @@ -0,0 +1,122 @@ +/* + This is a skeleton of joypad with 2 sticks and FN (MODE) button. + Fits devices with 1 stick and 2 extra face buttons too. + By including this ans setting I/O properties only, + devices should get consistent controller id and mapping + thus reusing non-game configs: + * SDL gamecontrollerdb.txt + * ES es_input.cfg + * Retroarch gamepad +*/ + +/ { + joypad: retrogame_joypad_s2_f1 { + /* These drivers emit the same button set which makes this skeleton ADC-agnostic */ + /* compatible = "archr-joypad"; */ + /* compatible = "archr-singleadc-joypad"; */ + + /* These are constants making Joystick Guid the same */ + joypad-name = "retrogame_joypad_s2_f1"; + joypad-vendor = <0x484B>; + joypad-product = <0x1121>; /* 11 inherited, 2 for number of sticks, 1 for number of FN */ + joypad-revision = <0x0100>; + + /* require explicit status = "okay"; */ + status = "disabled"; + + /* adc calculate scale */ + button-adc-scale = <2>; + + /* adc deadzone range */ + button-adc-deadzone = <64>; + + /* + specifies fuzz value that is used to filter noise from + the event stream. + */ + button-adc-fuzz = <32>; + button-adc-flat = <32>; + + /* poll device interval (ms), adc read interval */ + poll-interval = <10>; + + /* gpio button auto repeat set value : default disable */ + /* + autorepeat; + */ + + /* meaningful node names for easier use */ + up { + label = "GPIO DPAD-UP"; + linux,code = ; + }; + down { + label = "GPIO DPAD-DOWN"; + linux,code = ; + }; + left { + label = "GPIO DPAD-LEFT"; + linux,code = ; + }; + right { + label = "GPIO DPAD-RIGHT"; + linux,code = ; + }; + + a { + label = "GPIO BTN-A"; + linux,code = ; + }; + b { + label = "GPIO BTN-B"; + linux,code = ; + }; + x { + label = "GPIO BTN-X"; + linux,code = ; + }; + y { + label = "GPIO BTN-Y"; + linux,code = ; + }; + + select { + label = "GPIO BTN_SELECT"; + linux,code = ; + }; + start { + label = "GPIO BTN_START"; + linux,code = ; + }; + mode { + label = "GPIO BTN_F"; + linux,code = ; + }; + + tl { + label = "GPIO BTN_TL"; + linux,code = ; + }; + tr { + label = "GPIO BTN_TR"; + linux,code = ; + }; + tl2 { + label = "GPIO BTN_TL2"; + linux,code = ; + }; + tr2 { + label = "GPIO BTN_TR2"; + linux,code = ; + }; + + thumbl { + label = "GPIO BTN_THUMBL"; + linux,code = ; + }; + thumbr { + label = "GPIO BTN_THUMBR"; + linux,code = ; + }; + }; +}; diff --git a/config/archr-dts/rk3326-anbernic-rg351m.dts b/config/archr-dts/rk3326-anbernic-rg351m.dts new file mode 100644 index 0000000000..c12bb79944 --- /dev/null +++ b/config/archr-dts/rk3326-anbernic-rg351m.dts @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Hardkernel Co., Ltd + * Copyright (c) 2020 Theobroma Systems Design und Consulting GmbH + * Copyright (c) 2022 Maya Matuszczyk + */ + +/dts-v1/; +#include "rk3326-odroid-go.dtsi" + +/ { + model = "Anbernic RG351M"; + compatible = "anbernic,rg351m", "rockchip,rk3326"; + + battery: battery { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <3500000>; + charge-term-current-microamp = <350000>; + constant-charge-current-max-microamp = <2000000>; + constant-charge-voltage-max-microvolt = <4200000>; + factory-internal-resistance-micro-ohms = <180000>; + voltage-max-design-microvolt = <4100000>; + voltage-min-design-microvolt = <3500000>; + + ocv-capacity-celsius = <20>; + ocv-capacity-table-0 = <4046950 100>, <4001920 95>, <3967900 90>, <3919950 85>, + <3888450 80>, <3861850 75>, <3831540 70>, <3799130 65>, + <3768190 60>, <3745650 55>, <3726610 50>, <3711630 45>, + <3696720 40>, <3685660 35>, <3674950 30>, <3663050 25>, + <3649470 20>, <3635260 15>, <3616920 10>, <3592440 5>, + <3574170 0>; + }; + + vibrator { + compatible = "pwm-vibrator"; + pwms = <&pwm0 0 1000000 0>; + pwm-names = "enable"; + }; +}; + +/delete-node/ &vcc_host; /* conflicts with pwm vibration motor */ + +&internal_display { + compatible = "elida,kd35t133"; + iovcc-supply = <&vcc_lcd>; + vdd-supply = <&vcc_lcd>; + rotation = <270>; +}; + +&pwm0 { + status = "okay"; +}; + +&rk817_charger { + /* This device does not have a current sense resistor */ + //rockchip,resistor-sense-micro-ohms = <0>; + monitored-battery = <&battery>; +}; diff --git a/config/archr-dts/rk3326-anbernic-rg351m.dtsi b/config/archr-dts/rk3326-anbernic-rg351m.dtsi new file mode 100644 index 0000000000..f580df54e6 --- /dev/null +++ b/config/archr-dts/rk3326-anbernic-rg351m.dtsi @@ -0,0 +1,480 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Hardkernel Co., Ltd + * Copyright (c) 2020 Theobroma Systems Design und Consulting GmbH + * Copyright (c) 2022 Maya Matuszczyk + */ + +/dts-v1/; +#include +#include +#include +#include +#include "rk3326.dtsi" + +/ { + aliases { + mmc0 = &sdmmc; + }; + + chosen { + stdout-path = "serial2:115200n8"; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + power-supply = <&vcc_bl>; + pwms = <&pwm1 0 25000 0>; + }; + + /* + * LED is a tri-state. Driven high it is red, driven low it is + * green, and not driven at all (pin set to input) it is amber. + * Additionally, there is a 2nd LED that is not controllable + * that is on (red) when plugged in to power. + */ + gpio_led: gpio-leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&led_pin>; + + red_green_led: led-0 { + color = ; + gpios = <&gpio2 RK_PB5 GPIO_ACTIVE_HIGH>; + function = LED_FUNCTION_CHARGING; + }; + }; + + rk817-sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "rk817_int"; + simple-audio-card,format = "i2s"; + simple-audio-card,hp-det-gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Headphone", "Headphones", + "Speaker", "Speaker"; + simple-audio-card,routing = + "MICL", "Mic Jack", + "Headphones", "HPOL", + "Headphones", "HPOR", + "Speaker", "SPKO"; + + simple-audio-card,codec { + sound-dai = <&rk817>; + }; + + simple-audio-card,cpu { + sound-dai = <&i2s1_2ch>; + }; + }; + + vccsys: regulator-vccsys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v8_sys"; + regulator-always-on; + regulator-min-microvolt = <3800000>; + regulator-max-microvolt = <3800000>; + }; + + vibrator { + compatible = "pwm-vibrator"; + pwms = <&pwm0 0 1000000 0>; + pwm-names = "enable"; + }; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&cpu1 { + cpu-supply = <&vdd_arm>; +}; + +&cpu2 { + cpu-supply = <&vdd_arm>; +}; + +&cpu3 { + cpu-supply = <&vdd_arm>; +}; + +&cru { + assigned-clocks = <&cru PLL_NPLL>, + <&cru ACLK_BUS_PRE>, <&cru ACLK_PERI_PRE>, + <&cru HCLK_BUS_PRE>, <&cru HCLK_PERI_PRE>, + <&cru PCLK_BUS_PRE>, <&cru SCLK_GPU>; + + assigned-clock-rates = <1188000000>, + <200000000>, <200000000>, + <150000000>, <150000000>, + <100000000>, <200000000>; +}; + +&display_subsystem { + status = "okay"; +}; + +&dsi { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + ports { + mipi_out: port@1 { + reg = <1>; + + mipi_out_panel: endpoint { + remote-endpoint = <&mipi_in_panel>; + }; + }; + }; + + internal_display: panel@0 { + reg = <0>; + backlight = <&backlight>; + reset-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>; + + port { + mipi_in_panel: endpoint { + remote-endpoint = <&mipi_out_panel>; + }; + }; + }; +}; + +&dsi_dphy { + status = "okay"; +}; + +&gpu { + mali-supply = <&vdd_logic>; + status = "okay"; +}; + +&i2c0 { + clock-frequency = <400000>; + i2c-scl-falling-time-ns = <16>; + i2c-scl-rising-time-ns = <280>; + status = "okay"; + + rk817: pmic@20 { + compatible = "rockchip,rk817"; + reg = <0x20>; + #clock-cells = <1>; + clock-names = "mclk"; + clock-output-names = "rk808-clkout1", "xin32k"; + clocks = <&cru SCLK_I2S1_OUT>; + interrupt-parent = <&gpio0>; + interrupts = ; + pinctrl-0 = <&pmic_int>, <&i2s1_2ch_mclk>; + pinctrl-names = "default"; + #sound-dai-cells = <0>; + wakeup-source; + + vcc1-supply = <&vccsys>; + vcc2-supply = <&vccsys>; + vcc3-supply = <&vccsys>; + vcc4-supply = <&vccsys>; + vcc5-supply = <&vccsys>; + vcc6-supply = <&vccsys>; + vcc7-supply = <&vccsys>; + vcc8-supply = <&vccsys>; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1150000>; + regulator-min-microvolt = <950000>; + regulator-name = "vdd_logic"; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vdd_arm: DCDC_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1350000>; + regulator-min-microvolt = <950000>; + regulator-name = "vdd_arm"; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-name = "vcc_ddr"; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_3v3: DCDC_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "vcc_3v3"; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_1v8: LDO_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-name = "vcc_1v8"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd_1v0: LDO_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1000000>; + regulator-min-microvolt = <1000000>; + regulator-name = "vdd_1v0"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc3v3_pmu: LDO_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "vcc3v3_pmu"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vccio_sd: LDO_REG5 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <1800000>; + regulator-name = "vccio_sd"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_sd: LDO_REG6 { + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "vcc_sd"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_bl: LDO_REG7 { + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "vcc_bl"; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_lcd: LDO_REG8 { + regulator-max-microvolt = <2800000>; + regulator-min-microvolt = <2800000>; + regulator-name = "vcc_lcd"; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <2800000>; + }; + }; + + vcc_wifi: LDO_REG9 { + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "vcc_wifi"; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + usb_midu: BOOST { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <5400000>; + regulator-min-microvolt = <5000000>; + regulator-name = "usb_midu"; + }; + }; + + rk817_codec: codec { + rockchip,mic-in-differential; + }; + }; +}; + +&i2s1_2ch { + status = "okay"; +}; + +&io_domains { + vccio1-supply = <&vcc_3v3>; + vccio2-supply = <&vccio_sd>; + vccio3-supply = <&vcc_3v3>; + vccio4-supply = <&vcc_3v3>; + vccio5-supply = <&vcc_3v3>; + vccio6-supply = <&vcc_3v3>; + status = "okay"; +}; + +&pmu_io_domains { + pmuio1-supply = <&vcc3v3_pmu>; + pmuio2-supply = <&vcc3v3_pmu>; + status = "okay"; +}; + +&pwm0 { + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; + +&saradc { + vref-supply = <&vcc_1v8>; + status = "okay"; +}; + +&sdmmc { + cap-sd-highspeed; + card-detect-delay = <200>; + cd-gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_LOW>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&sfc { + #address-cells = <1>; + pinctrl-0 = <&sfc_clk &sfc_cs0 &sfc_bus2>; + pinctrl-names = "default"; + #size-cells = <0>; + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <108000000>; + spi-rx-bus-width = <2>; + spi-tx-bus-width = <1>; + }; +}; + +&tsadc { + status = "okay"; +}; + +&u2phy { + status = "okay"; + + u2phy_host: host-port { + status = "okay"; + }; + + u2phy_otg: otg-port { + status = "okay"; + }; +}; + +&usb20_otg { + status = "okay"; +}; + +&uart2 { + pinctrl-0 = <&uart2m1_xfer>; + pinctrl-names = "default"; + status = "okay"; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; + +&pinctrl { + headphone { + hp_det: hp-det { + rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; + + leds { + led_pin: led-pin { + rockchip,pins = <2 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pmic { + dc_det: dc-det { + rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + pmic_int: pmic-int { + rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + soc_slppin_gpio: soc_slppin_gpio { + rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>; + }; + + soc_slppin_rst: soc_slppin_rst { + rockchip,pins = <0 RK_PA4 2 &pcfg_pull_none>; + }; + + soc_slppin_slp: soc_slppin_slp { + rockchip,pins = <0 RK_PA4 1 &pcfg_pull_none>; + }; + }; +}; diff --git a/config/archr-dts/rk3326-anbernic-rg351v.dts b/config/archr-dts/rk3326-anbernic-rg351v.dts new file mode 100644 index 0000000000..26658a37f4 --- /dev/null +++ b/config/archr-dts/rk3326-anbernic-rg351v.dts @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Hardkernel Co., Ltd + * Copyright (c) 2020 Theobroma Systems Design und Consulting GmbH + * Copyright (c) 2022 Maya Matuszczyk + */ + +/dts-v1/; +#include "rk3326-odroid-go.dtsi" + +/ { + model = "Anbernic RG351V"; + compatible = "anbernic,rg351v", "rockchip,rk3326"; + + aliases { + mmc0 = &sdio; + mmc1 = &sdmmc; + }; + + gpio-keys-vol { + compatible = "gpio-keys"; + autorepeat; + pinctrl-0 = <&btn_pins_vol>; + pinctrl-names = "default"; + + button-vol-down { + gpios = <&gpio2 RK_PA1 GPIO_ACTIVE_LOW>; + label = "VOLUMEDOWN"; + linux,code = ; + }; + + button-volume-up { + gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; + label = "VOLUMEUP"; + linux,code = ; + }; + }; + + battery: battery { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <3500000>; + charge-term-current-microamp = <350000>; + constant-charge-current-max-microamp = <2000000>; + constant-charge-voltage-max-microvolt = <4200000>; + factory-internal-resistance-micro-ohms = <180000>; + voltage-max-design-microvolt = <4100000>; + voltage-min-design-microvolt = <3500000>; + + ocv-capacity-celsius = <20>; + ocv-capacity-table-0 = <4046950 100>, <4001920 95>, <3967900 90>, <3919950 85>, + <3888450 80>, <3861850 75>, <3831540 70>, <3799130 65>, + <3768190 60>, <3745650 55>, <3726610 50>, <3711630 45>, + <3696720 40>, <3685660 35>, <3674950 30>, <3663050 25>, + <3649470 20>, <3635260 15>, <3616920 10>, <3592440 5>, + <3574170 0>; + }; + + vibrator { + compatible = "pwm-vibrator"; + pwms = <&pwm0 0 1000000 0>; + pwm-names = "enable"; + }; +}; + +/* conflicts with pwm vibration motor */ +/delete-node/ &vcc_host; + +/* Device only has 1 LED compared to Odroid Go Advance */ +/delete-node/ &gpio_led; + +&internal_display { + compatible = "anbernic,rg351v-panel", "newvision,nv3051d"; + iovcc-supply = <&vcc_lcd>; + vdd-supply = <&vcc_lcd>; +}; + +&io_domains { + vccio1-supply = <&vccio_sd>; +}; + +/delete-node/ &pwm_led; + +&pwm0 { + status = "okay"; +}; + +/delete-node/ &pwm3; + +&rk817_charger { + /* This device does not have a current sense resistor */ + rockchip,resistor-sense-micro-ohms = <0>; + monitored-battery = <&battery>; +}; + +&sdio { + cap-sd-highspeed; + card-detect-delay = <200>; + cd-gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; /*[> CD GPIO <]*/ + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&vcc_sd { + regulator-max-microvolt = <3000000>; + regulator-min-microvolt = <1800000>; +}; + +&vccio_sd { + regulator-max-microvolt = <1800000>; +}; + +&pinctrl { + btns { + btn_pins_vol: btn-pins-vol { + rockchip,pins = <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; diff --git a/config/archr-dts/rk3326-batlexp-g350.dts b/config/archr-dts/rk3326-batlexp-g350.dts new file mode 100644 index 0000000000..9cad95fc57 --- /dev/null +++ b/config/archr-dts/rk3326-batlexp-g350.dts @@ -0,0 +1,163 @@ +/// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* +* Copyright (c) 2025 lcdyk <2670878301@qq.com> +*/ + +/dts-v1/; +#include "rk3326-gameconsole-r3xs.dtsi" +#include "retrogame_joypad_s2_f1.dtsi" + +/ { + model = "BatleXP G350"; + compatible = "batlexp,g350", "rockchip,rk3326"; +}; + +&joypad { + compatible = "archr-singleadc-joypad"; + pwms = <&pwm0 0 200000000 0>; + pwm-names = "enable"; + rumble-boost-weak = <0x0000>; + rumble-boost-strong = <0x0000>; + joypad-name = "retrogame_joypad"; + joypad-vendor = <0x484B>; + joypad-product = <0x1101>; + joypad-revision = <0x0100>; + + status = "okay"; + + /* gpio pincontrol setup */ + pinctrl-names = "default"; + pinctrl-0 = <&btn_pins>; + pinctrl-1 = <&pwm0_pin>; + + /* Analog mux define */ + io-channel-names = "amux_adc"; + io-channels = <&saradc 1>; + + /* adc mux channel count */ + amux-count = <4>; + /* non-default wiring */ + amux-channel-mapping = <2 0 1 3>; + /* adc mux enable gpio */ + amux-a-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>; + amux-b-gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_LOW>; + /* adc mux enable gpio */ + amux-en-gpios = <&gpio3 RK_PB5 GPIO_ACTIVE_LOW>; + + /* + Analog Stick data tuning value(precent) + p = positive direction, n = negative direction + report value = (real_adc_data * tuning_value) / 100 + */ + abs_x-p-tuning = <200>; + abs_x-n-tuning = <200>; + + abs_y-p-tuning = <200>; + abs_y-n-tuning = <200>; + + abs_rx-p-tuning = <200>; + abs_rx-n-tuning = <200>; + + abs_ry-p-tuning = <200>; + abs_ry-n-tuning = <200>; + + /* gpio button auto repeat set value : default disable */ + /* + autorepeat; + */ + invert-absx; + invert-absy; + invert-absrx; + + up { gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>; }; + down { gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_LOW>; }; + left { gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; }; + right { gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_LOW>; }; + a { gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>; }; + b { gpios = <&gpio1 RK_PA5 GPIO_ACTIVE_LOW>; }; + x { gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_LOW>; }; + y { gpios = <&gpio1 RK_PA6 GPIO_ACTIVE_LOW>; }; + select { gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>; }; + start { gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; }; + mode { gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_LOW>; }; + tl { gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_LOW>; }; + tr { gpios = <&gpio2 RK_PA7 GPIO_ACTIVE_LOW>; }; + tl2 { gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; }; + tr2 { gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; }; + thumbl { gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; }; + thumbr { gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; }; +}; + +&dsi { + internal_display: panel@0 { + compatible = "archr,generic-dsi"; + iovcc-supply = <&vcc_lcd>; + vcc-supply = <&vcc_lcd>; + reset-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>; + panel_description = + "G size=52,70 delays=20,150,20,120,20 format=rgb888 lanes=4 flags=0xe03", + + "M clock=50000 horizontal=640,450,70,450 vertical=480,17,5,13 default=1", + "M clock=50000 horizontal=640,450,85,450 vertical=480,17,106,13", + "M clock=50010 horizontal=640,450,127,450 vertical=480,17,90,13", + "M clock=50010 horizontal=640,450,73,450 vertical=480,17,110,13", + "M clock=50830 horizontal=640,450,85,450 vertical=480,17,34,13", + "M clock=53200 horizontal=640,450,128,450 vertical=480,17,24,13", + "M clock=50400 horizontal=640,450,77,450 vertical=480,17,10,13", + "M clock=50310 horizontal=640,450,85,450 vertical=480,17,6,13", + "M clock=54600 horizontal=640,450,94,450 vertical=480,17,46,13", + "M clock=65370 horizontal=640,450,113,450 vertical=480,17,14,13", + "M clock=76050 horizontal=640,450,85,450 vertical=480,17,10,13", + "M clock=100620 horizontal=640,450,85,450 vertical=480,17,6,13", + + "I seq=b9f11283", + "I seq=b1000000da80", + "I seq=b2001370", + "I seq=b31010282803ff00000000", + "I seq=b480", + "I seq=b50a0a", + "I seq=b67f7f", + "I seq=b82662f063", + "I seq=ba338105f90e0e2000000000000000442500900a0000014f01000037", + "I seq=bc47", + "I seq=bf021100", + "I seq=c0737350500000125000", + "I seq=c15300323277d1cccc77773333", + "I seq=c68200bfff00ff", + "I seq=c7b8000a000000", + "I seq=c810401e02", + "I seq=cc0b", + "I seq=e000070d37353f4144060c0d0f111012141a00070d37353f4144060c0d0f111012141a", + "I seq=e307070b0b0b0b00000000ff00c010", + "I seq=e9c810020000b0b11131232880b0b127080004020000000004020000008888ba60240888888888888888ba713518888888888800000001000000000000000000", + "I seq=ea970a820203070000000000008188ba17538888888888888088ba0642888888888888230000028000000000000000000000000000000000000000000000", + "I seq=efffff01", + "I seq=11 wait=200", + "I seq=29 wait=50"; + }; +}; + +&pinctrl { + btns { + btn_pins: btn-pins { + rockchip,pins = + <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; diff --git a/config/archr-dts/rk3326-device-group-r36.dtsi b/config/archr-dts/rk3326-device-group-r36.dtsi new file mode 100644 index 0000000000..bfc399984a --- /dev/null +++ b/config/archr-dts/rk3326-device-group-r36.dtsi @@ -0,0 +1,7 @@ +/ { + archr,device_switch { + r33s = "rk3326-gameconsole-r33s"; + r36s = "rk3326-gameconsole-r36s"; + rgb10x = "rk3326-powkiddy-rgb10x"; + }; +}; diff --git a/config/archr-dts/rk3326-gameconsole-eeclone.dts b/config/archr-dts/rk3326-gameconsole-eeclone.dts new file mode 100644 index 0000000000..ead32bbfe7 --- /dev/null +++ b/config/archr-dts/rk3326-gameconsole-eeclone.dts @@ -0,0 +1,960 @@ +/// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2024-present ROCKNIX (https://github.com/ROCKNIX) + * Copyright (c) 2025 Danil Zagoskin + */ + +/dts-v1/; +#include +#include +#include +#include +#include "rk3326.dtsi" + +/ { + model = "Generic EE clone"; + compatible = "gameconsole,eeclone", "rockchip,rk3326"; + + aliases { + mmc0 = &emmc; + mmc1 = &sdmmc; + mmc2 = &sdio; + serial1 = &uart2; + serial2 = &uart5; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&pwm1 0 25000 0>; + brightness-levels = < + 0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 + 24 25 26 27 28 29 30 31 + 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 + 56 57 58 59 60 61 62 63 + 64 65 66 67 68 69 70 71 + 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 + 88 89 90 91 92 93 94 95 + 96 97 98 99 100 101 102 103 + 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 + 128 129 130 131 132 133 134 135 + 136 137 138 139 140 141 142 143 + 144 145 146 147 148 149 150 151 + 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 + 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 + 184 185 186 187 188 189 190 191 + 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 + 208 209 210 211 212 213 214 215 + 216 217 218 219 220 221 222 223 + 224 225 226 227 228 229 230 231 + 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 + 248 249 250 251 252 253 254 255>; + default-brightness-level = <128>; + }; + + battery: battery { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <4000000>; + charge-term-current-microamp = <200000>; + constant-charge-current-max-microamp = <1500000>; + constant-charge-voltage-max-microvolt = <4200000>; + factory-internal-resistance-micro-ohms = <100000>; + voltage-max-design-microvolt = <4100000>; + voltage-min-design-microvolt = <3300000>; + + ocv-capacity-celsius = <20>; + ocv-capacity-table-0 = + <4046950 100>, <4001920 95>, <3967900 90>, <3940000 85>, + <3910000 80>, <3870000 75>, <3830000 70>, <3790000 65>, + <3750000 60>, <3720000 55>, <3690000 50>, <3650000 45>, + <3610000 40>, <3570000 35>, <3540000 30>, <3500000 25>, + <3460000 20>, <3420000 15>, <3380000 10>, <3340000 5>, + <3300000 0>; + }; + + adc_keys: adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 2>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + poll-interval = <100>; + + /* disabled by default, dtbo may enable it when needed */ + status = "disabled"; + + button-vol-up { + press-threshold-microvolt = <15000>; + label = "VOLUMEUP"; + linux,code = ; + }; + + button-vol-down { + press-threshold-microvolt = <300000>; + label = "VOLUMEDOWN"; + linux,code = ; + }; + }; + + joypad: joypad { + compatible = "archr-singleadc-joypad"; + + joypad-name = "r36s_Gamepad"; + joypad-product = <0x1188>; + joypad-revision = <0x0188>; + + status = "okay"; + + /* gpio pincontrol setup */ + pinctrl-names = "default"; + pinctrl-0 = <&btn_pins>; + + /* Analog mux define */ + io-channel-names = "amux_adc"; + io-channels = <&saradc 1>; + + /* adc mux channel count */ + amux-count = <4>; + /* non-default wiring */ + amux-channel-mapping = <2 3 1 0>; + /* adc mux enable gpio */ + amux-en-gpios = <&gpio2 RK_PB4 GPIO_ACTIVE_LOW>; /* rocker0-gpios */ + /* adc mux select(a,b) gpio */ + amux-a-gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_LOW>; /* rocker1-gpios */ + amux-b-gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_LOW>; /* rocker-gpios */ + + /* adc calculate scale */ + button-adc-scale = <2>; + + /* adc deadzone range */ + button-adc-deadzone = <64>; + + /* + specifies fuzz value that is used to filter noise from + the event stream. + */ + button-adc-fuzz = <32>; + button-adc-flat = <32>; + + /* + Analog Stick data tuning value(precent) + p = positive direction, n = negative direction + report value = (real_adc_data * tuning_value) / 100 + */ + abs_x-p-tuning = <200>; + abs_x-n-tuning = <200>; + + abs_y-p-tuning = <200>; + abs_y-n-tuning = <200>; + + abs_rx-p-tuning = <200>; + abs_rx-n-tuning = <200>; + + abs_ry-p-tuning = <200>; + abs_ry-n-tuning = <200>; + + /* poll device interval (ms), adc read interval */ + poll-interval = <10>; + + /* gpio button auto repeat set value : default disable */ + /* + autorepeat; + */ + + /* + joypad driver is poll-device driver. + poll-device is does not support wakeup-source. + */ + sw1 { + gpios = <&gpio3 RK_PC6 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-UP"; + linux,code = ; // 0x220 + }; + sw2 { + gpios = <&gpio3 RK_PC7 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-DOWN"; + linux,code = ; // 0x221 + }; + sw3 { + gpios = <&gpio3 RK_PC4 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-LEFT"; + linux,code = ; // 0x222 + }; + sw4 { + gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-RIGHT"; + linux,code = ; // 0x223 + }; + + sw5 { + gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>; + label = "GPIO KEY BTN-A"; + linux,code = ; // 0x131 + }; + sw6 { + gpios = <&gpio3 RK_PC1 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-B"; + linux,code = ; // 0x130 + }; + sw7 { + gpios = <&gpio3 RK_PC3 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-Y"; + linux,code = ; // 0x134 + }; + sw8 { + gpios = <&gpio3 RK_PC2 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-X"; + linux,code = ; // 0x133 + }; + + sw11 { + gpios = <&gpio2 RK_PB5 GPIO_ACTIVE_LOW>; + label = "GPIO BTN_THUMBL"; + linux,code = ; // 0x2c2 + }; + sw12 { + gpios = <&gpio2 RK_PB6 GPIO_ACTIVE_LOW>; + label = "GPIO BTN_THUMBR"; + linux,code = ; // 0x2c3 + }; + + sw13 { + gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; + label = "GPIO BTN_FN"; + linux,code = ; // 0x2c4 + }; + + sw15 { + gpios = <&gpio3 RK_PB5 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-LEFT"; + linux,code = ; // 0x02 + }; + sw16 { + gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-RIGHT"; + linux,code = ; // 0x05 + }; + sw19 { + gpios = <&gpio3 RK_PD0 GPIO_ACTIVE_LOW>; + label = "GPIO BTN_SELECT"; + linux,code = ; + }; + sw20 { + gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-RIGHT2"; + linux,code = ; + }; + sw21 { + gpios = <&gpio3 RK_PB6 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-LEFT2"; + linux,code = ; + }; + sw22 { + gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_LOW>; + label = "GPIO BTN_START"; + linux,code = ; + }; + }; + + leds: gpio-leds { + compatible = "gpio-leds"; + pinctrl-0 = <&led_pins>; + pinctrl-names = "default"; + + /* charge_red_gpio = <&gpio0 17 0>; */ + led-0 { + color = ; + default-state = "off"; + function = LED_FUNCTION_CHARGING; + linux,default-trigger = "none"; + gpios = <&gpio0 RK_PC1 GPIO_ACTIVE_HIGH>; + }; + + /* charge_blue_gpio = <&gpio0 0 0>; */ + led-1 { + color = ; + default-state = "on"; + function = LED_FUNCTION_POWER; + linux,default-trigger = "default-on"; + gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; + }; + }; + + spk_amp: audio-amplifier { + compatible = "simple-audio-amplifier"; + enable-gpios = <&gpio3 RK_PA7 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&spk_amp_enable_h>; + pinctrl-names = "default"; + sound-name-prefix = "Speaker Amp"; + }; + + rk817-sound-amplified { + compatible = "simple-audio-card"; + pinctrl-names = "default"; + pinctrl-0 = <&hp_det>; + simple-audio-card,name = "rk817_ext"; + simple-audio-card,aux-devs = <&spk_amp>; + simple-audio-card,format = "i2s"; + simple-audio-card,hp-det-gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,widgets = + "Headphone", "Headphones", + "Speaker", "Internal Speakers"; + /* despite it's just a mono speaker, we need to route both Speaker Amp channels + Otherwise, the second channel stays on and keeps amp enabled */ + simple-audio-card,routing = + "Headphones", "HPOL", + "Headphones", "HPOR", + "Internal Speakers", "Speaker Amp OUTL", + "Internal Speakers", "Speaker Amp OUTR", + "Speaker Amp INL", "HPOL", + "Speaker Amp INR", "HPOR"; + + simple-audio-card,pin-switches = "Internal Speakers"; + + status = "disabled"; + + simple-audio-card,codec { + sound-dai = <&rk817>; + }; + + simple-audio-card,cpu { + sound-dai = <&i2s1_2ch>; + }; + }; + + rk817-sound-simple { + compatible = "simple-audio-card"; + pinctrl-names = "default"; + pinctrl-0 = <&hp_det>; + simple-audio-card,name = "rk817_ext"; + simple-audio-card,format = "i2s"; + simple-audio-card,hp-det-gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,widgets = + "Headphone", "Headphones", + "Speaker", "Internal Speakers"; + simple-audio-card,routing = + "Headphones", "HPOL", + "Headphones", "HPOR", + "Internal Speakers", "SPKO"; + + status = "disabled"; + + simple-audio-card,codec { + sound-dai = <&rk817>; + }; + + simple-audio-card,cpu { + sound-dai = <&i2s1_2ch>; + }; + }; + + vccsys: vccsys { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + vcc-phy-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc_phy"; + regulator-always-on; + regulator-boot-on; + }; + + vcc18_lcd0: vcc18-lcd0 { + compatible = "regulator-fixed"; + regulator-name = "vcc18_lcd0_n"; + gpio = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>; + enable-active-high; + pinctrl-0 = <&vcc18_lcd_n>; + pinctrl-names = "default"; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_host: vcc_host { + compatible = "regulator-fixed"; + regulator-name = "vcc_host"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio3 RK_PA4 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&vcc5_usb>; + pinctrl-names = "default"; + enable-active-high; + regulator-always-on; + regulator-boot-on; + vin-supply = <&usb_midu>; + }; +}; + +&dmc { + center-supply = <&vdd_logic>; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&cpu1 { + cpu-supply = <&vdd_arm>; +}; + +&cpu2 { + cpu-supply = <&vdd_arm>; +}; + +&cpu3 { + cpu-supply = <&vdd_arm>; +}; + +&cru { + assigned-clocks = <&cru PLL_NPLL>, + <&cru ACLK_BUS_PRE>, <&cru ACLK_PERI_PRE>, + <&cru HCLK_BUS_PRE>, <&cru HCLK_PERI_PRE>, + <&cru PCLK_BUS_PRE>, <&cru SCLK_GPU>; + + assigned-clock-rates = <1188000000>, + <200000000>, <200000000>, + <150000000>, <150000000>, + <100000000>, <200000000>; +}; + +&display_subsystem { + status = "okay"; +}; + +&dsi { + status = "okay"; + + ports { + mipi_out: port@1 { + reg = <1>; + + mipi_out_panel: endpoint { + remote-endpoint = <&mipi_in_panel>; + }; + }; + }; + + internal_display: panel@0 { + compatible = "magicx,xu10-panel", "sitronix,st7703"; + iovcc-supply = <&vcc18_lcd0>; + vcc-supply = <&vcc18_lcd0>; + reg = <0>; + backlight = <&backlight>; + reset-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&lcd_rst>; + + port { + mipi_in_panel: endpoint { + remote-endpoint = <&mipi_out_panel>; + }; + }; + }; +}; + +&dsi_dphy { + status = "okay"; +}; + +&gpu { + mali-supply = <&vdd_logic>; + status = "okay"; +}; + +&i2c0 { + clock-frequency = <400000>; + i2c-scl-falling-time-ns = <16>; + i2c-scl-rising-time-ns = <280>; + status = "okay"; + + rk817: pmic@20 { + compatible = "rockchip,rk817"; + reg = <0x20>; + interrupt-parent = <&gpio0>; + interrupts = ; + clock-output-names = "rk808-clkout1", "xin32k"; + clock-names = "mclk"; + clocks = <&cru SCLK_I2S1_OUT>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int>, <&i2s1_2ch_mclk>; + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <1>; + #sound-dai-cells = <0>; + + vcc1-supply = <&vccsys>; + vcc2-supply = <&vccsys>; + vcc3-supply = <&vccsys>; + vcc4-supply = <&vccsys>; + vcc5-supply = <&vccsys>; + vcc6-supply = <&vccsys>; + vcc7-supply = <&vcc_3v0>; + vcc8-supply = <&vccsys>; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-name = "vdd_logic"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1350000>; + regulator-initial-mode = <0x02>; + regulator-ramp-delay = <6001>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vdd_arm: DCDC_REG2 { + regulator-name = "vdd_arm"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-initial-mode = <0x02>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x02>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_3v0: DCDC_REG4 { + regulator-name = "vcc_3v0"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-initial-mode = <0x02>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcc_1v0: LDO_REG1 { + regulator-name = "vcc_1v0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc1v8_soc: LDO_REG2 { + regulator-name = "vcc1v8_soc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc1v0_soc: LDO_REG3 { + regulator-name = "vcc1v0_soc"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc3v0_pmu: LDO_REG4 { + regulator-name = "vcc3v0_pmu"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vccio_sd: LDO_REG5 { + regulator-name = "vccio_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_sd: LDO_REG6 { + regulator-name = "vcc_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc2v8_dvp: LDO_REG7 { + regulator-name = "vcc2v8_dvp"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc3v0_dvp: LDO_REG8 { + regulator-name = "vcc3v0_dvp"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vdd1v5_dvp: LDO_REG9 { + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-name = "vdd1v5_dvp"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <1500000>; + }; + }; + + usb_midu: BOOST { + regulator-name = "usb_midu"; + regulator-min-microvolt = <4900000>; + regulator-max-microvolt = <5400000>; + regulator-always-on; + regulator-boot-on; + }; + + /* + otg_switch: OTG_SWITCH { + regulator-name = "otg_switch"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + */ + }; + + rk817_charger: charger { + monitored-battery = <&battery>; + rockchip,resistor-sense-micro-ohms = <10000>; + rockchip,sleep-enter-current-microamp = <300000>; + rockchip,sleep-filter-current-microamp = <100000>; + }; + + rk817_codec: codec { + rockchip,mic-in-differential; + }; + }; +}; + +/* I2S 1 Channel Used Header(P2):1(GPIO2.C3),2(.C2), 3(.C1), 4(.C5), 5(.C4) */ +&i2s1_2ch { + status = "okay"; + #sound-dai-cells = <0>; +}; + +&io_domains { + vccio1-supply = <&vcc2v8_dvp>; + vccio2-supply = <&vccio_sd>; + vccio3-supply = <&vcc1v8_soc>; + vccio4-supply = <&vcc_3v0>; + vccio5-supply = <&vcc_3v0>; + vccio6-supply = <&vcc1v8_soc>; + status = "okay"; +}; + +&isp { + status = "okay"; +}; + +&isp_mmu { + status = "okay"; +}; + +&pmu_io_domains { + pmuio1-supply = <&vcc3v0_pmu>; + pmuio2-supply = <&vcc3v0_pmu>; + status = "okay"; +}; + +&csi_dphy { + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; + +&saradc { + vref-supply = <&vcc1v8_soc>; + status = "okay"; +}; + +&sdmmc { + cap-sd-highspeed; + card-detect-delay = <800>; + cd-gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_LOW>; /*[> ff370000 PD_SDCARD CD GPIO <]*/ + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <&vccio_sd>; + vmmc-supply = <&vcc_sd>; + status = "okay"; +}; + +&sdio { + cap-sd-highspeed; + max-frequency = <100000000>; + cd-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; + card-detect-delay = <800>; + supports-sd; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <&vcc2v8_dvp>; + vmmc-supply = <&vcc3v0_dvp>; + status = "okay"; +}; + +&emmc { + status = "okay"; + no-sdio; + no-sd; + disable-wp; + non-removable; + num-slots = <1>; +}; + +&tsadc { + status = "okay"; +}; + +&u2phy { + status = "okay"; + + u2phy_host: host-port { + status = "okay"; + }; + + u2phy_otg: otg-port { + status = "okay"; + }; +}; + +&usb20_otg { + status = "okay"; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; +&pinctrl { + btns { + btn_pins: btn-pins { + rockchip,pins = + <2 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB3 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PC0 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PC1 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PC2 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PC3 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PC7 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + headphone { + hp_det: hp-det { + rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + gpio-lcd { + lcd_rst: lcd-rst { + rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + vcc18-lcd { + vcc18_lcd_n: vcc18-lcd-n { + rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + vcc5-usb { + vcc5_usb: vcc5-usb { + rockchip,pins = <3 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + gpio-led { + led_pins: led-pins { + rockchip,pins = + <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>, /* charge_blue_gpio = <&gpio0 0 0>; */ + <0 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>; /* charge_red_gpio = <&gpio0 17 0>; */ + }; + }; + + pmic { + dc_det: dc-det { + rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + pmic_int: pmic-int { + rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + soc_slppin_gpio: soc_slppin_gpio { + rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>; + }; + + soc_slppin_rst: soc_slppin_rst { + rockchip,pins = <0 RK_PA4 2 &pcfg_pull_none>; + }; + + soc_slppin_slp: soc_slppin_slp { + rockchip,pins = <0 RK_PA4 1 &pcfg_pull_none>; + }; + }; + + speaker { + spk_amp_enable_h: spk-amp-enable-h { + rockchip,pins = <3 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&uart5 { + status = "okay"; +}; +&uart2 { + status = "disabled"; +}; + + +&internal_display { + compatible = "archr,generic-dsi"; + panel_description = + "G size=153,85 delays=20,20,20,120,20 format=rgb888 lanes=4 flags=0xe03", + + "M clock=50000 horizontal=720,140,80,140 vertical=720,20,4,20 default=1", + "M clock=50000 horizontal=720,140,100,140 vertical=720,20,150,20", + "M clock=50040 horizontal=720,140,112,140 vertical=720,20,140,20", + "M clock=51400 horizontal=720,140,132,140 vertical=720,20,148,20", + "M clock=50140 horizontal=720,140,90,140 vertical=720,20,40,20", + "M clock=56900 horizontal=720,140,90,140 vertical=720,20,114,20", + "M clock=50400 horizontal=720,140,92,140 vertical=720,20,10,20", + "M clock=50220 horizontal=720,140,80,140 vertical=720,20,15,20", + "M clock=54600 horizontal=720,140,112,140 vertical=720,20,57,20", + "M clock=75450 horizontal=720,140,95,140 vertical=720,20,153,20", + "M clock=75330 horizontal=720,140,80,140 vertical=720,20,15,20", + "M clock=100440 horizontal=720,140,80,140 vertical=720,20,15,20", + + "I seq=b9f11283", + "I seq=b1000000da80", + "I seq=b23c1230", + "I seq=b31010282803ff00000000", + "I seq=b480", + "I seq=b50a0a", + "I seq=b69797", + "I seq=b82622f013", + "I seq=ba338105f90e0e2000000000000000442500900a0000014f01000037", + "I seq=bc47", + "I seq=bf021100", + "I seq=c0737350500000127000", + "I seq=c12500323277e4ffffcccc7777", + "I seq=c68200bfff00ff", + "I seq=c7b8000a000000", + "I seq=c810401e02", + "I seq=cc0b", + "I seq=e0000b102c3d3f423a070d0f131513140f16000b102c3d3f423a070d0f131513140f16", + "I seq=e307070b0b0b0b00000000ff00c010", + "I seq=e9c8100a000080811231234f86a000470800000c00000000000c00000098028baf4602888888888898138baf5713888888888800000000000000000000000000", + "I seq=ea970c090909780000000000009f318ba8317588888888889f208ba820648888888888230000027100000000000000000000000000000040808100000000", + "I seq=efffff01", + "I seq=11 wait=250", + "I seq=29 wait=50"; +}; + + diff --git a/config/archr-dts/rk3326-gameconsole-r33s.dts b/config/archr-dts/rk3326-gameconsole-r33s.dts new file mode 100644 index 0000000000..21dbab6d19 --- /dev/null +++ b/config/archr-dts/rk3326-gameconsole-r33s.dts @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * # Copyright (C) 2022-24 JELOS (https://github.com/JustEnoughLinuxOS) + */ + +/dts-v1/; +#include "rk3326-gameconsole-r3xs.dtsi" +#include "rk3326-device-group-r36.dtsi" + +/ { + model = "Game Console R33S"; + compatible = "gameconsole,r33s", "rockchip,rk3326"; + + archr,device_switch { + this = "r33s"; + }; + + builtin_gamepad: r33s_joypad { + compatible = "archr-singleadc-joypad"; + pinctrl-names = "default"; + pinctrl-0 = <&btn_pins>; + joypad-name = "r33s_joypad"; + joypad-product = <0x0AA2>; + joypad-revision = <0x0100>; + joypad-vendor = <0x0001>; + + status = "okay"; + amux-count = <0>; + /* poll device interval (ms), adc read interval */ + poll-interval = <10>; + pwms = <&pwm0 0 1000000000 0>; + pwm-names = "enable"; + rumble-boost-weak = <0x0000>; + rumble-boost-strong = <0x0000>; + + button-sw1 { + gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>; + label = "DPAD-UP"; + linux,code = ; + }; + button-sw2 { + gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_LOW>; + label = "DPAD-DOWN"; + linux,code = ; + }; + button-sw3 { + gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; + label = "DPAD-LEFT"; + linux,code = ; + }; + button-sw4 { + gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_LOW>; + label = "DPAD-RIGHT"; + linux,code = ; + }; + button-sw5 { + gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>; + label = "BTN-A"; + linux,code = ; + }; + button-sw6 { + gpios = <&gpio1 RK_PA5 GPIO_ACTIVE_LOW>; + label = "BTN-B"; + linux,code = ; + }; + button-sw7 { + gpios = <&gpio1 RK_PA6 GPIO_ACTIVE_LOW>; + label = "BTN-Y"; + linux,code = ; + }; + button-sw8 { + gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_LOW>; + label = "BTN-X"; + linux,code = ; + }; + button-sw9 { + gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_LOW>; + label = "TOP-LEFT"; + linux,code = ; + }; + button-sw10 { + gpios = <&gpio2 RK_PA7 GPIO_ACTIVE_LOW>; + label = "TOP-RIGHT"; + linux,code = ; + }; + button-sw11 { + gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>; + label = "SELECT"; + linux,code = ; + }; + button-sw12 { + gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; + label = "TOP-RIGHT 2"; + linux,code = ; + }; + button-sw13 { + gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; + label = "TOP-LEFT 2"; + linux,code = ; + }; + button-sw14 { + gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; + label = "START"; + linux,code = ; + }; + }; +}; + +&pinctrl { + btns { + btn_pins: btn-pins { + rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + }; +}; diff --git a/config/archr-dts/rk3326-gameconsole-r36max.dts b/config/archr-dts/rk3326-gameconsole-r36max.dts new file mode 100644 index 0000000000..dfc2c6e099 --- /dev/null +++ b/config/archr-dts/rk3326-gameconsole-r36max.dts @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * R36Max / K36 clone — alias for Generic EE clone board. + * + * ROCKNIX uses "r36max" for the K36 clone family. This DTS + * includes the eeclone base with a different model/compatible + * so U-Boot's fdtfile can reference either name. + * + * Copyright (c) 2024-present ROCKNIX (https://github.com/ROCKNIX) + * Copyright (c) 2025 Arch R + */ + +#include "rk3326-gameconsole-eeclone.dts" + +/ { + model = "Game Console R36Max"; + compatible = "gameconsole,r36max", "gameconsole,eeclone", "rockchip,rk3326"; +}; diff --git a/config/archr-dts/rk3326-gameconsole-r36s.dts b/config/archr-dts/rk3326-gameconsole-r36s.dts new file mode 100644 index 0000000000..5dbee3a001 --- /dev/null +++ b/config/archr-dts/rk3326-gameconsole-r36s.dts @@ -0,0 +1,234 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * # Copyright (C) 2022-24 JELOS (https://github.com/JustEnoughLinuxOS) + */ + +/dts-v1/; +#include "rk3326-gameconsole-r3xs.dtsi" +#include "rk3326-device-group-r36.dtsi" + +/ { + model = "Game Console R36S"; + compatible = "gameconsole,r35s", "gameconsole,r36s", "rockchip,rk3326"; + + archr,device_switch { + this = "r36s"; + }; + + /* R36S has an external speaker amplifier on GPIO3_PC4 */ + spk_amp: audio-amplifier { + compatible = "simple-audio-amplifier"; + enable-gpios = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&spk_amp_enable_h>; + pinctrl-names = "default"; + sound-name-prefix = "Speaker Amp"; + }; + + joypad: odroidgo3-joypad { + compatible = "odroidgo3-joypad"; + pwms = <&pwm0 0 200000000 0>; + pwm-names = "enable"; + rumble-boost-weak = <0x0000>; + rumble-boost-strong = <0x0000>; + + joypad-name = "r36s_Gamepad"; + joypad-product = <0x1188>; + joypad-revision = <0x0188>; + + status = "okay"; + + /* gpio pincontrol setup */ + pinctrl-names = "default"; + pinctrl-0 = <&btn_pins>; + pinctrl-1 = <&pwm0_pin>; + + /* Analog mux define */ + io-channel-names = "amux_adc"; + io-channels = <&saradc 1>; + + /* adc mux channel count */ + amux-count = <4>; + /* adc mux select(a,b) gpio */ + amux-a-gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_LOW>; + amux-b-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>; + /* adc mux enable gpio */ + amux-en-gpios = <&gpio3 RK_PB5 GPIO_ACTIVE_LOW>; + + /* adc calculate scale */ + button-adc-scale = <2>; + + /* adc deadzone range */ + button-adc-deadzone = <64>; + + /* + specifies fuzz value that is used to filter noise from + the event stream. + */ + button-adc-fuzz = <32>; + button-adc-flat = <32>; + + /* + Analog Stick data tuning value(precent) + p = positive direction, n = negative direction + report value = (real_adc_data * tuning_value) / 100 + */ + abs_x-p-tuning = <200>; + abs_x-n-tuning = <200>; + + abs_y-p-tuning = <200>; + abs_y-n-tuning = <200>; + + abs_rx-p-tuning = <200>; + abs_rx-n-tuning = <200>; + + abs_ry-p-tuning = <200>; + abs_ry-n-tuning = <200>; + + /* poll device interval (ms), adc read interval */ + poll-interval = <10>; + + /* required for RG36S */ + invert-absx; + invert-absy; + + /* gpio button auto repeat set value : default disable */ + /* + autorepeat; + */ + + /* + joypad driver is poll-device driver. + poll-device is does not support wakeup-source. + */ + sw1 { + gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-UP"; + linux,code = ; // 0x220 + }; + sw2 { + gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-DOWN"; + linux,code = ; // 0x221 + }; + sw3 { + gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-LEFT"; + linux,code = ; // 0x222 + }; + sw4 { + gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-RIGHT"; + linux,code = ; // 0x223 + }; + sw5 { + gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>; + label = "GPIO KEY BTN-A"; + linux,code = ; // 0x131 + }; + sw6 { + gpios = <&gpio1 RK_PA5 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-B"; + linux,code = ; // 0x130 + }; + sw7 { + gpios = <&gpio1 RK_PA6 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-Y"; + linux,code = ; // 0x134 + }; + sw8 { + gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-X"; + linux,code = ; // 0x133 + }; + sw11 { + gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; + label = "GPIO BTN_THUMBL"; + linux,code = ; // 0x2c2 + }; + sw12 { + gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; + label = "GPIO BTN_THUMBR"; + linux,code = ; // 0x2c3 + }; + sw13 { + gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_LOW>; + label = "GPIO BTN_FN"; + linux,code = ; // 0x2c4 + }; + sw15 { + gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-LEFT"; + linux,code = ; // 0x02 + }; + sw16 { + gpios = <&gpio2 RK_PA7 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-RIGHT"; + linux,code = ; // 0x05 + }; + sw19 { + gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>; + label = "GPIO BTN_SELECT"; + linux,code = ; + }; + sw20 { + gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-RIGHT2"; + linux,code = ; + }; + sw21 { + gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-LEFT2"; + linux,code = ; + }; + sw22 { + gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; + label = "GPIO BTN_START"; + linux,code = ; + }; + }; +}; + +/* Override sound card from r3xs.dtsi: add speaker amplifier */ +/ { + rk817-sound { + simple-audio-card,aux-devs = <&spk_amp>; + simple-audio-card,routing = + "MICL", "Mic Jack", + "Headphones", "HPOL", + "Headphones", "HPOR", + "Speaker Amp INL", "SPKO"; + }; +}; + +&pinctrl { + btns { + btn_pins: btn-pins { + rockchip,pins = <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>; + + }; + + }; + + speaker { + spk_amp_enable_h: spk-amp-enable-h { + rockchip,pins = <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; diff --git a/config/archr-dts/rk3326-gameconsole-r3xs.dtsi b/config/archr-dts/rk3326-gameconsole-r3xs.dtsi new file mode 100644 index 0000000000..b9f4f17ed5 --- /dev/null +++ b/config/archr-dts/rk3326-gameconsole-r3xs.dtsi @@ -0,0 +1,545 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * # Copyright (C) 2022-24 JELOS (https://github.com/JustEnoughLinuxOS) + */ + +/dts-v1/; +#include +#include +#include +#include +#include "rk3326.dtsi" + +/ { + model = "Game Console R33S"; + compatible = "gameconsolec,r33s", "rockchip,rk3326"; + + aliases { + mmc0 = &sdio; + mmc1 = &sdmmc; + }; + + chosen { + stdout-path = "serial2:115200n8"; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + power-supply = <&vcc_bl>; + pwms = <&pwm1 0 25000 0>; + brightness-levels = < + 0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 + 24 25 26 27 28 29 30 31 + 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 + 56 57 58 59 60 61 62 63 + 64 65 66 67 68 69 70 71 + 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 + 88 89 90 91 92 93 94 95 + 96 97 98 99 100 101 102 103 + 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 + 128 129 130 131 132 133 134 135 + 136 137 138 139 140 141 142 143 + 144 145 146 147 148 149 150 151 + 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 + 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 + 184 185 186 187 188 189 190 191 + 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 + 208 209 210 211 212 213 214 215 + 216 217 218 219 220 221 222 223 + 224 225 226 227 228 229 230 231 + 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 + 248 249 250 251 252 253 254 255>; + default-brightness-level = <128>; + }; + + gpio-keys-vol { + compatible = "gpio-keys"; + autorepeat; + pinctrl-0 = <&btn_pins_vol>; + pinctrl-names = "default"; + + button-vol-down { + gpios = <&gpio2 RK_PA1 GPIO_ACTIVE_LOW>; + label = "VOLUMEDOWN"; + linux,code = ; + }; + + button-volume-up { + gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; + label = "VOLUMEUP"; + linux,code = ; + }; + }; + + battery: battery { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <3200000>; + charge-term-current-microamp = <320000>; + constant-charge-current-max-microamp = <2000000>; + constant-charge-voltage-max-microvolt = <4200000>; + factory-internal-resistance-micro-ohms = <180000>; + voltage-max-design-microvolt = <4100000>; + voltage-min-design-microvolt = <3500000>; + + ocv-capacity-celsius = <20>; + ocv-capacity-table-0 = <4046950 100>, <4001920 95>, <3967900 90>, <3919950 85>, + <3888450 80>, <3861850 75>, <3831540 70>, <3799130 65>, + <3768190 60>, <3745650 55>, <3726610 50>, <3711630 45>, + <3696720 40>, <3685660 35>, <3674950 30>, <3663050 25>, + <3649470 20>, <3635260 15>, <3616920 10>, <3592440 5>, + <3574170 0>; + + }; + + rk817-sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "rk817_int"; + simple-audio-card,format = "i2s"; + simple-audio-card,hp-det-gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Headphone", "Headphones", + "Speaker", "Speaker"; + simple-audio-card,routing = + "MICL", "Mic Jack", + "Headphones", "HPOL", + "Headphones", "HPOR", + "Speaker", "SPKO"; + + simple-audio-card,codec { + sound-dai = <&rk817>; + }; + + simple-audio-card,cpu { + sound-dai = <&i2s1_2ch>; + }; + }; + + vccsys: vccsys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v8_sys"; + regulator-always-on; + regulator-min-microvolt = <3800000>; + regulator-max-microvolt = <3800000>; + }; +}; + +&dmc { + center-supply = <&vdd_logic>; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&cpu1 { + cpu-supply = <&vdd_arm>; +}; + +&cpu2 { + cpu-supply = <&vdd_arm>; +}; + +&cpu3 { + cpu-supply = <&vdd_arm>; +}; + +&cru { + assigned-clocks = <&cru PLL_NPLL>, + <&cru ACLK_BUS_PRE>, <&cru ACLK_PERI_PRE>, + <&cru HCLK_BUS_PRE>, <&cru HCLK_PERI_PRE>, + <&cru PCLK_BUS_PRE>, <&cru SCLK_GPU>; + + assigned-clock-rates = <1188000000>, + <200000000>, <200000000>, + <150000000>, <150000000>, + <100000000>, <200000000>; +}; + +&display_subsystem { + status = "okay"; +}; + +&dsi { + status = "okay"; + + ports { + mipi_out: port@1 { + reg = <1>; + + mipi_out_panel: endpoint { + remote-endpoint = <&mipi_in_panel>; + }; + }; + }; + + internal_display: panel@0 { + reg = <0>; + backlight = <&backlight>; + reset-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>; + + port { + mipi_in_panel: endpoint { + remote-endpoint = <&mipi_out_panel>; + }; + }; + }; +}; + +&dsi_dphy { + status = "okay"; +}; + +&gpu { + mali-supply = <&vdd_logic>; + status = "okay"; +}; + +&internal_display { + compatible = "gameconsole,r36s-panel", "sitronix,st7703"; + iovcc-supply = <&vcc_lcd>; + vdd-supply = <&vcc_lcd>; +}; + +&i2c0 { + clock-frequency = <400000>; + i2c-scl-falling-time-ns = <16>; + i2c-scl-rising-time-ns = <280>; + status = "okay"; + + rk817: pmic@20 { + compatible = "rockchip,rk817"; + reg = <0x20>; + interrupt-parent = <&gpio0>; + interrupts = ; + clock-output-names = "rk808-clkout1", "xin32k"; + clock-names = "mclk"; + clocks = <&cru SCLK_I2S1_OUT>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int>, <&i2s1_2ch_mclk>; + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <1>; + #sound-dai-cells = <0>; + + vcc1-supply = <&vccsys>; + vcc2-supply = <&vccsys>; + vcc3-supply = <&vccsys>; + vcc4-supply = <&vccsys>; + vcc5-supply = <&vccsys>; + vcc6-supply = <&vccsys>; + vcc7-supply = <&vccsys>; + vcc8-supply = <&vccsys>; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-name = "vdd_logic"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1150000>; + regulator-ramp-delay = <6001>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vdd_arm: DCDC_REG2 { + regulator-name = "vdd_arm"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_3v3: DCDC_REG4 { + regulator-name = "vcc_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_1v8: LDO_REG2 { + regulator-name = "vcc_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd_1v0: LDO_REG3 { + regulator-name = "vdd_1v0"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc3v3_pmu: LDO_REG4 { + regulator-name = "vcc3v3_pmu"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vccio_sd: LDO_REG5 { + regulator-name = "vccio_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc_sd: LDO_REG6 { + regulator-name = "vcc_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3000000>; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcc_bl: LDO_REG7 { + regulator-name = "vcc_bl"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_lcd: LDO_REG8 { + regulator-name = "vcc_lcd"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <2800000>; + }; + }; + + LDO_REG9 { + /* unused */ + }; + + usb_midu: BOOST { + regulator-name = "usb_midu"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5400000>; + regulator-always-on; + regulator-boot-on; + }; + }; + + rk817_charger: charger { + rockchip,resistor-sense-micro-ohms = <10000>; + rockchip,sleep-enter-current-microamp = <300000>; + rockchip,sleep-filter-current-microamp = <100000>; + }; + + rk817_codec: codec { + rockchip,mic-in-differential; + }; + }; +}; + +&i2s1_2ch { + status = "okay"; +}; + +&io_domains { + vccio1-supply = <&vccio_sd>; + vccio2-supply = <&vccio_sd>; + vccio3-supply = <&vcc_3v3>; + vccio4-supply = <&vcc_3v3>; + vccio5-supply = <&vcc_3v3>; + vccio6-supply = <&vcc_3v3>; + status = "okay"; +}; + +&pmu_io_domains { + pmuio1-supply = <&vcc3v3_pmu>; + pmuio2-supply = <&vcc3v3_pmu>; + status = "okay"; +}; + +&pwm0 { + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; + +&saradc { + vref-supply = <&vcc_1v8>; + status = "okay"; +}; + +&sdmmc { + bus-width = <4>; + cap-sd-highspeed; + card-detect-delay = <800>; + cd-gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_LOW>; /*[> CD GPIO <]*/ + disable-wp; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&sdio { + bus-width = <4>; + cap-sd-highspeed; + card-detect-delay = <800>; + cd-gpios = <&gpio3 RK_PB6 GPIO_ACTIVE_LOW>; /*[> CD GPIO <]*/ + disable-wp; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&tsadc { + status = "okay"; +}; + +&u2phy { + status = "okay"; + + u2phy_host: host-port { + status = "okay"; + }; + + u2phy_otg: otg-port { + status = "okay"; + }; +}; + +&usb20_otg { + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2m1_xfer>; + status = "okay"; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; + +&rk817_charger { + monitored-battery = <&battery>; +}; + +&pinctrl { + btns { + btn_pins_vol: btn-pins-vol { + rockchip,pins = <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + headphone { + hp_det: hp-det { + rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; + + pmic { + dc_det: dc-det { + rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + pmic_int: pmic-int { + rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + soc_slppin_gpio: soc_slppin_gpio { + rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>; + }; + + soc_slppin_rst: soc_slppin_rst { + rockchip,pins = <0 RK_PA4 2 &pcfg_pull_none>; + }; + + soc_slppin_slp: soc_slppin_slp { + rockchip,pins = <0 RK_PA4 1 &pcfg_pull_none>; + }; + }; +}; diff --git a/config/archr-dts/rk3326-gameforce-chi.dts b/config/archr-dts/rk3326-gameforce-chi.dts new file mode 100644 index 0000000000..7b47cf7017 --- /dev/null +++ b/config/archr-dts/rk3326-gameforce-chi.dts @@ -0,0 +1,811 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2024 Chris Morgan + */ + +/dts-v1/; +#include +#include +#include +#include +#include "rk3326.dtsi" + +/ { + model = "GameForce Chi"; + compatible = "gameforce,chi", "rockchip,rk3326"; + chassis-type = "handset"; + + aliases { + mmc0 = &sdmmc; + mmc1 = &sdio; + }; + + chosen { + stdout-path = "serial2:115200n8"; + }; + + adc_joystick: adc-joystick { + compatible = "adc-joystick"; + io-channels = <&saradc 0>, + <&saradc 1>; + poll-interval = <100>; + #address-cells = <1>; + #size-cells = <0>; + + axis@0 { + reg = <0>; + abs-flat = <10>; + abs-fuzz = <10>; + abs-range = <850 175>; + linux,code = ; + }; + + axis@1 { + reg = <1>; + abs-flat = <10>; + abs-fuzz = <10>; + abs-range = <800 190>; + linux,code = ; + }; + }; + + adc_keys: adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 2>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + poll-interval = <60>; + + button-1 { + label = "HAPPY1"; + linux,code = ; + press-threshold-microvolt = <15000>; + }; + + button-2 { + label = "HAPPY2"; + linux,code = ; + press-threshold-microvolt = <300000>; + }; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + power-supply = <&vcc_bl>; + pwms = <&pwm1 0 25000 0>; + }; + + battery: battery { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <3000000>; + charge-term-current-microamp = <300000>; + constant-charge-current-max-microamp = <1500000>; + constant-charge-voltage-max-microvolt = <4200000>; + factory-internal-resistance-micro-ohms = <180000>; + ocv-capacity-celsius = <20>; + ocv-capacity-table-0 = <4106000 100>, <4071000 95>, <4018000 90>, <3975000 85>, + <3946000 80>, <3908000 75>, <3877000 70>, <3853000 65>, + <3834000 60>, <3816000 55>, <3802000 50>, <3788000 45>, + <3774000 40>, <3760000 35>, <3748000 30>, <3735000 25>, + <3718000 20>, <3697000 15>, <3685000 10>, <3625000 5>, + <3400000 0>; + voltage-max-design-microvolt = <4250000>; + voltage-min-design-microvolt = <3400000>; + }; + + gpio_leds: gpio-leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&led_pins>; + + red_led: led-0 { + color = ; + gpios = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>; + }; + + green_led: led-1 { + color = ; + gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>; + }; + + blue_led: led-2 { + color = ; + gpios = <&gpio3 RK_PC6 GPIO_ACTIVE_HIGH>; + }; + + white_led: led-3 { + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_HIGH>; + }; + + chg_led: led-4 { + color = ; + function = LED_FUNCTION_CHARGING; + gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_HIGH>; + }; + + }; + + gpio_keys: gpio-keys { + compatible = "gpio-keys"; + pinctrl-0 = <&btn_pins_ctrl>; + pinctrl-names = "default"; + + button-a { + gpios = <&gpio2 RK_PB0 GPIO_ACTIVE_LOW>; + label = "EAST"; + linux,code = ; + }; + + button-b { + gpios = <&gpio2 RK_PB1 GPIO_ACTIVE_LOW>; + label = "SOUTH"; + linux,code = ; + }; + + button-down { + gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_LOW>; + label = "DPAD-DOWN"; + linux,code = ; + }; + + button-home { + gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; + label = "HOME"; + linux,code = ; + }; + + button-l1 { + gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_LOW>; + label = "TL"; + linux,code = ; + }; + + button-l2 { + gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_LOW>; + label = "TL2"; + linux,code = ; + }; + + button-left { + gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; + label = "DPAD-LEFT"; + linux,code = ; + }; + + button-r1 { + gpios = <&gpio2 RK_PA7 GPIO_ACTIVE_LOW>; + label = "TR"; + linux,code = ; + }; + + button-r2 { + gpios = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>; + label = "TR2"; + linux,code = ; + }; + + button-right { + gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_LOW>; + label = "DPAD-RIGHT"; + linux,code = ; + }; + + button-select { + gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; + label = "SELECT"; + linux,code = ; + }; + + button-start { + gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; + label = "START"; + linux,code = ; + }; + + button-up { + gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>; + label = "DPAD-UP"; + linux,code = ; + }; + + button-x { + gpios = <&gpio2 RK_PB3 GPIO_ACTIVE_LOW>; + label = "NORTH"; + linux,code = ; + }; + + button-y { + gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_LOW>; + label = "WEST"; + linux,code = ; + }; + }; + + multi-led { + compatible = "leds-group-multicolor"; + color = ; + function = LED_FUNCTION_KBD_BACKLIGHT; + leds = <&red_led>, <&green_led>, <&blue_led>; + }; + + spk_amp: audio-amplifier { + compatible = "simple-audio-amplifier"; + enable-gpios = <&gpio2 RK_PB5 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&spk_amp_enable_h>; + pinctrl-names = "default"; + sound-name-prefix = "Speaker Amp"; + }; + + sound { + compatible = "simple-audio-card"; + pinctrl-0 = <&hp_det>; + pinctrl-names = "default"; + simple-audio-card,name = "rk817_ext"; + simple-audio-card,aux-devs = <&spk_amp>; + simple-audio-card,format = "i2s"; + simple-audio-card,hp-det-gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Headphone", "Headphones", + "Speaker", "Internal Speakers"; + simple-audio-card,routing = + "MICL", "Mic Jack", + "Headphones", "HPOL", + "Headphones", "HPOR", + "Internal Speakers", "Speaker Amp OUTL", + "Internal Speakers", "Speaker Amp OUTR", + "Speaker Amp INL", "HPOL", + "Speaker Amp INR", "HPOR"; + simple-audio-card,pin-switches = "Internal Speakers"; + + simple-audio-card,codec { + sound-dai = <&rk817>; + }; + + simple-audio-card,cpu { + sound-dai = <&i2s1_2ch>; + }; + }; + + vibrator_left: pwm-vibrator-l { + compatible = "pwm-vibrator"; + pwm-names = "enable"; + pwms = <&pwm4 0 25000 0>; + }; + + vibrator_right: pwm-vibrator-r { + compatible = "pwm-vibrator"; + pwm-names = "enable"; + pwms = <&pwm5 0 25000 0>; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = <&rk817 1>; + clock-names = "ext_clock"; + pinctrl-0 = <&wifi_enable_h>; + pinctrl-names = "default"; + post-power-on-delay-ms = <200>; + reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; + }; + + vccsys: regulator-vccsys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v8_sys"; + regulator-always-on; + regulator-min-microvolt = <3800000>; + regulator-max-microvolt = <3800000>; + }; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&cpu1 { + cpu-supply = <&vdd_arm>; +}; + +&cpu2 { + cpu-supply = <&vdd_arm>; +}; + +&cpu3 { + cpu-supply = <&vdd_arm>; +}; + +&display_subsystem { + status = "okay"; +}; + +&dsi { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + internal_display: panel@0 { + reg = <0>; + compatible = "gameforce,chi-panel"; + backlight = <&backlight>; + iovcc-supply = <&vcc_lcd>; + vcc-supply = <&vcc_lcd>; + reset-gpios = <&gpio3 RK_PA0 GPIO_ACTIVE_LOW>; + + port { + mipi_in_panel: endpoint { + remote-endpoint = <&mipi_out_panel>; + }; + }; + }; + + ports { + mipi_out: port@1 { + reg = <1>; + + mipi_out_panel: endpoint { + remote-endpoint = <&mipi_in_panel>; + }; + }; + }; +}; + +&dsi_dphy { + status = "okay"; +}; + +&gpu { + mali-supply = <&vdd_logic>; + status = "okay"; +}; + +&i2c0 { + clock-frequency = <400000>; + i2c-scl-falling-time-ns = <16>; + i2c-scl-rising-time-ns = <280>; + status = "okay"; + + rk817: pmic@20 { + compatible = "rockchip,rk817"; + reg = <0x20>; + #clock-cells = <1>; + clock-names = "mclk"; + clock-output-names = "rk808-clkout1", "xin32k"; + clocks = <&cru SCLK_I2S1_OUT>; + interrupt-parent = <&gpio0>; + interrupts = ; + pinctrl-0 = <&pmic_int>, <&i2s1_2ch_mclk>; + pinctrl-names = "default"; + #sound-dai-cells = <0>; + system-power-controller; + wakeup-source; + + vcc1-supply = <&vccsys>; + vcc2-supply = <&vccsys>; + vcc3-supply = <&vccsys>; + vcc4-supply = <&vccsys>; + vcc5-supply = <&vccsys>; + vcc6-supply = <&vccsys>; + vcc7-supply = <&vcc_3v0>; + vcc8-supply = <&vccsys>; + vcc9-supply = <&dcdc_boost>; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1150000>; + regulator-min-microvolt = <950000>; + regulator-name = "vdd_logic"; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vdd_arm: DCDC_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1350000>; + regulator-min-microvolt = <950000>; + regulator-name = "vdd_arm"; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-name = "vcc_ddr"; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_3v0: DCDC_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3000000>; + regulator-min-microvolt = <3000000>; + regulator-name = "vcc_3v0"; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcc_1v8: LDO_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-name = "vcc_1v8"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd_1v0: LDO_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1000000>; + regulator-min-microvolt = <1000000>; + regulator-name = "vdd_1v0"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc_3v0_pmu: LDO_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3000000>; + regulator-min-microvolt = <3000000>; + regulator-name = "vcc_3v0_pmu"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vccio_sd: LDO_REG5 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <1800000>; + regulator-name = "vccio_sd"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_sd: LDO_REG6 { + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "vcc_sd"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_bl: LDO_REG7 { + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "vcc_bl"; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_lcd: LDO_REG8 { + regulator-max-microvolt = <2800000>; + regulator-min-microvolt = <2800000>; + regulator-name = "vcc_lcd"; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <2800000>; + }; + }; + + vcc_wifi: LDO_REG9 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "vcc_wifi"; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + dcdc_boost: BOOST { + regulator-max-microvolt = <5000000>; + regulator-min-microvolt = <5000000>; + regulator-name = "dcdc_boost"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + otg_switch: OTG_SWITCH { + regulator-name = "otg_switch"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + + rk817_charger: charger { + monitored-battery = <&battery>; + rockchip,resistor-sense-micro-ohms = <10000>; + rockchip,sleep-enter-current-microamp = <300000>; + rockchip,sleep-filter-current-microamp = <100000>; + }; + }; +}; + +&i2s1_2ch { + status = "okay"; +}; + +&io_domains { + vccio1-supply = <&vcc_3v0_pmu>; + vccio2-supply = <&vccio_sd>; + vccio3-supply = <&vcc_3v0>; + vccio4-supply = <&vcc_3v0>; + vccio5-supply = <&vcc_3v0>; + vccio6-supply = <&vcc_3v0>; + status = "okay"; +}; + +&pinctrl { + bluetooth-pins { + bt_reset: bt-reset { + rockchip,pins = + <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_down>; + }; + + bt_wake_dev: bt-wake-dev { + rockchip,pins = + <0 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + bt_wake_host: bt-wake-host { + rockchip,pins = + <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + headphone { + hp_det: hp-det { + rockchip,pins = + <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + gpio-btns { + btn_pins_ctrl: btn-pins-ctrl { + rockchip,pins = + <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PB3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + gpio-leds { + led_pins: led-pins { + rockchip,pins = + <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>, + <3 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>, + <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>, + <3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>, + <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pmic { + pmic_int: pmic-int { + rockchip,pins = + <0 RK_PC1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + soc_slppin_gpio: soc_slppin_gpio { + rockchip,pins = + <0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>; + }; + + soc_slppin_rst: soc_slppin_rst { + rockchip,pins = + <0 RK_PA4 2 &pcfg_pull_none>; + }; + + soc_slppin_slp: soc_slppin_slp { + rockchip,pins = + <0 RK_PA4 1 &pcfg_pull_none>; + }; + }; + + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = + <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + speaker { + spk_amp_enable_h: spk-amp-enable-h { + rockchip,pins = + <2 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&pmu_io_domains { + pmuio1-supply = <&vcc_1v8>; + pmuio2-supply = <&vcc_3v0_pmu>; + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; + +&pwm4 { + status = "okay"; +}; + +&pwm5 { + status = "okay"; +}; + +&saradc { + vref-supply = <&vcc_1v8>; + status = "okay"; +}; + +&sdio { + bus-width = <4>; + cap-sd-highspeed; + cap-sdio-irq; + disable-wp; + keep-power-in-suspend; + mmc-pwrseq = <&sdio_pwrseq>; + no-mmc; + no-sd; + non-removable; + sd-uhs-sdr104; + status = "okay"; +}; + +&sdmmc { + cap-mmc-highspeed; + cap-sd-highspeed; + no-sdio; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&sfc { + #address-cells = <1>; + pinctrl-0 = <&sfc_clk &sfc_cs0 &sfc_bus2>; + pinctrl-names = "default"; + #size-cells = <0>; + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <108000000>; + spi-rx-bus-width = <2>; + spi-tx-bus-width = <1>; + }; +}; + +&tsadc { + status = "okay"; +}; + +&u2phy { + status = "okay"; + + u2phy_otg: otg-port { + status = "okay"; + }; +}; + +&usb20_otg { + status = "okay"; +}; + +/* + * The right ADC joystick exists connected to an unknown ADC + * controller which can be communicated with via uart0. This ADC device + * is an 8-pin SOIC with no markings located right next to the left ADC + * joystick ribbon cable. The pinout for this ADC controller appears to + * be pin 1 - VCC (2.8v), pin 2 - 1.8v (clk maybe?), pin 3 - GPIO 10, + * pin 4 - unknown, pin 5 - unknown, pin 6 - analog in, pin 7 - analog in, + * pin 8 - ground. There is currently a userspace UART driver for this + * device but it only works with the BSP joystick driver. + */ +&uart0 { + status = "okay"; +}; + +/* + * Bluetooth was not working on BSP and is not currently working on + * mainline due to missing firmware. Bluetooth requires removal of DMA + * or else it will not probe. + */ +&uart1 { + /delete-property/ dma-names; + /delete-property/ dmas; + uart-has-rtscts; + status = "okay"; + + bluetooth: bluetooth { + compatible = "realtek,rtl8723ds-bt"; + device-wake-gpios = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>; + enable-gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; + host-wake-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&bt_reset>, <&bt_wake_dev>, <&bt_wake_host>; + pinctrl-names = "default"; + }; +}; + +&uart2 { + pinctrl-0 = <&uart2m1_xfer>; + pinctrl-names = "default"; + status = "okay"; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; diff --git a/config/archr-dts/rk3326-magicx-xu-mini-m.dts b/config/archr-dts/rk3326-magicx-xu-mini-m.dts new file mode 100644 index 0000000000..ad4841e365 --- /dev/null +++ b/config/archr-dts/rk3326-magicx-xu-mini-m.dts @@ -0,0 +1,109 @@ +/// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2024-present ROCKNIX (https://github.com/ROCKNIX) + * Copyright (c) 2024 Olivier Schonken + */ + +#include "rk3326-magicx-xu10.dts" + +/ { + model = "MagicX XU Mini M"; + compatible = "magicx,xu-mini-m", "rockchip,rk3326"; +}; + +&battery { + charge-full-design-microamp-hours = <2600000>; +}; + +&dsi { + internal_display: panel@0 { + compatible = "archr,generic-dsi"; + panel_description = + "G size=69,139 delays=5,20,20,120,20 format=rgb888 lanes=2 flags=0xe03", + + "M clock=25000 horizontal=480,60,10,54 vertical=640,20,10,20 default=1", + "M clock=25200 horizontal=480,60,22,54 vertical=640,20,139,20", + "M clock=25000 horizontal=480,60,31,54 vertical=640,20,120,20", + "M clock=25660 horizontal=480,60,22,54 vertical=640,20,153,20", + "M clock=25300 horizontal=480,60,31,54 vertical=640,20,24,20", + "M clock=28590 horizontal=480,60,15,54 vertical=640,20,106,20", + "M clock=25380 horizontal=480,60,17,54 vertical=640,20,13,20", + "M clock=25410 horizontal=480,60,11,54 vertical=640,20,20,20", + "M clock=29490 horizontal=480,60,24,54 vertical=640,20,114,20", + "M clock=33520 horizontal=480,60,36,54 vertical=640,20,25,20", + "M clock=38430 horizontal=480,60,16,54 vertical=640,20,20,20", + "M clock=50820 horizontal=480,60,11,54 vertical=640,20,20,20", + + "I seq=ff7701000013", + "I seq=ef08", + "I seq=ff7701000010", + "I seq=c04f00", "I seq=c11002", "I seq=c22002", "I seq=cc10", + "I seq=b006161e0e12060a0809230412102b311f", + "I seq=b1060f160d100704090720051210262f1f", + "I seq=ff7701000011", + "I seq=b065", "I seq=b185", "I seq=b282", "I seq=b380", "I seq=b542", "I seq=b785", + "I seq=b820", + "I seq=c178", "I seq=c278", + "I seq=d088", + "I seq=e0000002", + "I seq=e104a006a005a007a0004444", + "I seq=e2000000000000000000000000", + "I seq=e300002222", + "I seq=e44444", + "I seq=e50c90a0a00e92a0a0088ca0a00a8ea0a0", + "I seq=e600002222", + "I seq=e74444", + "I seq=e80d91a0a00f93a0a0098da0a00b8fa0a0", + "I seq=eb0000e4e4440040", + "I seq=edfff5476f0ba1abffffba1ab0f6745fff", + "I seq=ef080808403f64", + "I seq=ff7701000013", + "I seq=e6167c", "I seq=e8000e", + "I seq=e8000c wait=50", + "I seq=e80000", + "I seq=ff7701000000", + "I seq=11 wait=150", + "I seq=29 wait=120"; + rotation = <90>; + }; +}; + +&joypad { + joypad-name = "XU Mini M Gamepad"; + + invert-absrx; + /delete-property/ invert-absx; + + sw5 { + gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-B"; + }; + sw6 { + gpios = <&gpio2 RK_PA1 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-A"; + }; + sw7 { + gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-X"; + }; + sw8 { + gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-Y"; + }; + sw16 { + gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; + }; + sw17 { + gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; + }; +}; + +&pinctrl { + headphone { + hp_det: hp-det { + rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; +}; + + diff --git a/config/archr-dts/rk3326-magicx-xu10.dts b/config/archr-dts/rk3326-magicx-xu10.dts new file mode 100644 index 0000000000..91e06ffd17 --- /dev/null +++ b/config/archr-dts/rk3326-magicx-xu10.dts @@ -0,0 +1,872 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Hardkernel Co., Ltd + * Copyright (c) 2020 Theobroma Systems Design und Consulting GmbH + * Copyright (c) 2022 Maya Matuszczyk + */ + +/dts-v1/; +#include +#include +#include +#include +#include "rk3326.dtsi" + +/ { + model = "MagicX XU10"; + compatible = "magicx,xu10", "rockchip,rk3326"; + + aliases { + mmc0 = &sdio; + mmc1 = &sdmmc; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&pwm1 0 25000 0>; + brightness-levels = < + 0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 + 24 25 26 27 28 29 30 31 + 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 + 56 57 58 59 60 61 62 63 + 64 65 66 67 68 69 70 71 + 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 + 88 89 90 91 92 93 94 95 + 96 97 98 99 100 101 102 103 + 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 + 128 129 130 131 132 133 134 135 + 136 137 138 139 140 141 142 143 + 144 145 146 147 148 149 150 151 + 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 + 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 + 184 185 186 187 188 189 190 191 + 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 + 208 209 210 211 212 213 214 215 + 216 217 218 219 220 221 222 223 + 224 225 226 227 228 229 230 231 + 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 + 248 249 250 251 252 253 254 255>; + default-brightness-level = <128>; + }; + + joypad: xu10-joypad { + compatible = "xu10-joypad"; + + joypad-name = "XU10 Gamepad"; + joypad-product = <0x0200>; + joypad-revision = <0x0010>; + + status = "okay"; + /* + - xu10-joypad sysfs list - + * for poll device interval(ms) + /sys/devices/platform/odroidgo3_joypad/poll_interval [rw] + ex) echo 20 > poll_interval + * for button-adc-fuzz + /sys/devices/platform/odroidgo3_joypad/adc_fuzz [r] + * for button-adc-flat + /sys/devices/platform/odroidgo3_joypad/adc_flat [r] + + * for report control(1:enable, 0:disable) + /sys/devices/platform/odroidgo3_joypad/enable [rw] + * for adc calibration value setup(current adcs value -> cal value) + /sys/devices/platform/odroidgo3_joypad/adc_cal [rw] + ex) echo 0 > adc_cal + * for amux data debug + * Joypad driver is disabled when using this sysfs. + /sys/devices/platform/odroidgo3_joypad/amux_debug [rw] + ex) echo 0 > amux_debug --> select amux channel + ex) cat amux_debug --> get adc data of seleted channel + */ + + /* gpio pincontrol setup */ + pinctrl-names = "default"; + pinctrl-0 = <&btn_pins>; + + /* Analog mux define */ + io-channel-names = "joy_left", "joy_right"; + io-channels = <&saradc 1>, <&saradc 2>; + + /* adc mux channel count */ + amux-count = <4>; + + /* adc mux select(a,b) gpio */ + amux-a-gpios = <&gpio2 RK_PB3 GPIO_ACTIVE_LOW>; + amux-b-gpios = <&gpio2 RK_PB5 GPIO_ACTIVE_LOW>; + + /* adc mux enable gpio */ + amux-en-gpios = <&gpio1 RK_PB0 GPIO_ACTIVE_LOW>; + + /* adc calculate scale */ + button-adc-scale = <2>; + + /* adc deadzone range */ + button-adc-deadzone = <180>; + + /* + specifies fuzz value that is used to filter noise from + the event stream. + */ + button-adc-fuzz = <32>; + button-adc-flat = <32>; + + /* + Analog Stick data tuning value(precent) + p = positive direction, n = negative direction + report value = (real_adc_data * tuning_value) / 100 + */ + abs_x-p-tuning = <200>; + abs_x-n-tuning = <200>; + + abs_y-p-tuning = <200>; + abs_y-n-tuning = <200>; + + abs_rx-p-tuning = <200>; + abs_rx-n-tuning = <200>; + + abs_ry-p-tuning = <200>; + abs_ry-n-tuning = <200>; + + /* poll device interval (ms), adc read interval */ + poll-interval = <10>; + + /* required for XU10 */ + invert-absx; + invert-absy; + + /* gpio button auto repeat set value : default disable */ + /* + autorepeat; + */ + + /* + *** MagicX XU10 - layoout *** + |-------------------------------| + | sw14 sw17 sw16 sw15 | + |-----|-------------------|-----| + | | | | + |vol+ | | sw13| + |vol- | | | + | | LCD Display | | + | | | | + | | | | + | |-------------------| | + | sw9 sw10 | + | | + | sw1 sw7 | + | sw3 sw4 sw8 sw6 | + | sw2 sw5 | + | | + | sw11 sw12 | + | | + |-------|---------------|-------| + */ + + /* + joypad driver is poll-device driver. + poll-device is does not support wakeup-source. + */ + + sw1 { + gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-UP"; + linux,code = ; // 0x220 + }; + sw2 { + gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-DOWN"; + linux,code = ; // 0x221 + }; + sw3 { + gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-LEFT"; + linux,code = ; // 0x222 + }; + sw4 { + gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-RIGHT"; + linux,code = ; // 0x223 + }; + sw5 { + gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-A"; + linux,code = ; // 0x130 + }; + sw6 { + gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-B"; + linux,code = ; // 0x131 + }; + sw7 { + gpios = <&gpio2 RK_PA1 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-Y"; + linux,code = ; // 0x133 + }; + sw8 { + gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-X"; + linux,code = ; // 0x134 + }; + sw9 { + gpios = <&gpio2 RK_PB0 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-SELECT"; + linux,code = ; // 0x13a + }; + sw10 { + gpios = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-START"; + linux,code = ; // 0x13b + }; + sw11 { + gpios = <&gpio2 RK_PB1 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-THUMBL"; + linux,code = ; // 0x13d + }; + sw12 { + gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-THUMBR"; + linux,code = ; // 0x13e + }; + sw13 { + gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-G"; + linux,code = ; // 0x2c0 + }; + sw14 { + gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-LEFT"; + linux,code = ; // 0x136 + }; + sw15 { + gpios = <&gpio2 RK_PA7 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-RIGHT"; + linux,code = ; // 0x137 + }; + sw16 { + gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-RIGHT2"; + linux,code = ; // 0x139 + }; + sw17 { + gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-LEFT2"; + linux,code = ; // 0x138 + }; + }; + + battery: battery { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <3000000>; + charge-term-current-microamp = <200000>; + constant-charge-current-max-microamp = <1500000>; + constant-charge-voltage-max-microvolt = <4200000>; + factory-internal-resistance-micro-ohms = <100000>; + voltage-max-design-microvolt = <4100000>; + voltage-min-design-microvolt = <3300000>; + + ocv-capacity-celsius = <20>; + ocv-capacity-table-0 = + <4046950 100>, <4001920 95>, <3967900 90>, <3940000 85>, + <3910000 80>, <3870000 75>, <3830000 70>, <3790000 65>, + <3750000 60>, <3720000 55>, <3690000 50>, <3650000 45>, + <3610000 40>, <3570000 35>, <3540000 30>, <3500000 25>, + <3460000 20>, <3420000 15>, <3380000 10>, <3340000 5>, + <3300000 0>; + }; + + gpio-keys-vol { + compatible = "gpio-keys"; + autorepeat; + pinctrl-0 = <&btn_pins_vol>; + pinctrl-names = "default"; + + button-vol-down { + gpios = <&gpio0 RK_PC1 GPIO_ACTIVE_LOW>; + label = "VOLUMEDOWN"; + linux,code = ; + }; + + button-vol-up { + gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_LOW>; + label = "VOLUMEUP"; + linux,code = ; + }; + }; + + leds: gpio-leds { + compatible = "gpio-leds"; + pinctrl-0 = <&led_pins>; + pinctrl-names = "default"; + + led-0 { + color = ; + default-state = "off"; + function = LED_FUNCTION_CHARGING; + gpios = <&gpio0 RK_PB3 GPIO_ACTIVE_HIGH>; + }; + + led-1 { + color = ; + default-state = "off"; + function = LED_FUNCTION_STATUS; + gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>; + }; + }; + + rk817-sound { + compatible = "simple-audio-card"; + pinctrl-names = "default"; + pinctrl-0 = <&hp_det>; + simple-audio-card,name = "rk817_int"; + simple-audio-card,format = "i2s"; + simple-audio-card,hp-det-gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_LOW>; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Headphone", "Headphones", + "Speaker", "Speaker"; + simple-audio-card,routing = + "MICL", "Mic Jack", + "Headphones", "HPOL", + "Headphones", "HPOR", + "Speaker", "SPKO"; + + simple-audio-card,codec { + sound-dai = <&rk817>; + }; + + simple-audio-card,cpu { + sound-dai = <&i2s1_2ch>; + }; + }; + + vccsys: vccsys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v8_sys"; + regulator-always-on; + regulator-min-microvolt = <3800000>; + regulator-max-microvolt = <3800000>; + }; + + vcc-phy-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc_phy"; + regulator-always-on; + regulator-boot-on; + }; + + vcc18_lcd0: vcc18-lcd0 { + compatible = "regulator-fixed"; + regulator-name = "vcc18_lcd0_n"; + gpio = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>; + enable-active-high; + pinctrl-0 = <&vcc18_lcd_n>; + pinctrl-names = "default"; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_host: vcc_host { + compatible = "regulator-fixed"; + regulator-name = "vcc_host"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + vin-supply = <&usb_midu>; + }; +}; + +&dmc { + center-supply = <&vdd_logic>; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&cpu1 { + cpu-supply = <&vdd_arm>; +}; + +&cpu2 { + cpu-supply = <&vdd_arm>; +}; + +&cpu3 { + cpu-supply = <&vdd_arm>; +}; + +&cru { + assigned-clocks = <&cru PLL_NPLL>, + <&cru ACLK_BUS_PRE>, <&cru ACLK_PERI_PRE>, + <&cru HCLK_BUS_PRE>, <&cru HCLK_PERI_PRE>, + <&cru PCLK_BUS_PRE>, <&cru SCLK_GPU>; + + assigned-clock-rates = <1188000000>, + <200000000>, <200000000>, + <150000000>, <150000000>, + <100000000>, <200000000>; +}; + +&display_subsystem { + status = "okay"; +}; + +&dsi { + status = "okay"; + + ports { + mipi_out: port@1 { + reg = <1>; + + mipi_out_panel: endpoint { + remote-endpoint = <&mipi_in_panel>; + }; + }; + }; + + internal_display: panel@0 { + compatible = "magicx,xu10-panel", "sitronix,st7703"; + iovcc-supply = <&vcc18_lcd0>; + vcc-supply = <&vcc18_lcd0>; + reg = <0>; + backlight = <&backlight>; + reset-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&lcd_rst>; + + port { + mipi_in_panel: endpoint { + remote-endpoint = <&mipi_out_panel>; + }; + }; + }; +}; + +&dsi_dphy { + status = "okay"; +}; + +&gpu { + mali-supply = <&vdd_logic>; + status = "okay"; +}; + +&i2c0 { + clock-frequency = <400000>; + i2c-scl-falling-time-ns = <16>; + i2c-scl-rising-time-ns = <280>; + status = "okay"; + + rk817: pmic@20 { + compatible = "rockchip,rk817"; + reg = <0x20>; + interrupt-parent = <&gpio0>; + interrupts = ; + clock-output-names = "rk808-clkout1", "xin32k"; + clock-names = "mclk"; + clocks = <&cru SCLK_I2S1_OUT>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int>, <&i2s1_2ch_mclk>; + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <1>; + #sound-dai-cells = <0>; + + vcc1-supply = <&vccsys>; + vcc2-supply = <&vccsys>; + vcc3-supply = <&vccsys>; + vcc4-supply = <&vccsys>; + vcc5-supply = <&vccsys>; + vcc6-supply = <&vccsys>; + vcc7-supply = <&vcc_3v0>; + vcc8-supply = <&vccsys>; + vcc9-supply = <&usb_midu>; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-name = "vdd_logic"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1150000>; + regulator-ramp-delay = <6001>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vdd_arm: DCDC_REG2 { + regulator-name = "vdd_arm"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_3v0: DCDC_REG4 { + regulator-name = "vcc_3v0"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcc_1v0: LDO_REG1 { + regulator-name = "vcc_1v0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc1v8_soc: LDO_REG2 { + regulator-name = "vcc1v8_soc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc1v0_soc: LDO_REG3 { + regulator-name = "vcc1v0_soc"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc3v0_pmu: LDO_REG4 { + regulator-name = "vcc3v0_pmu"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vccio_sd: LDO_REG5 { + regulator-name = "vccio_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_sd: LDO_REG6 { + regulator-name = "vcc_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcc2v8_dvp: LDO_REG7 { + regulator-name = "vcc2v8_dvp"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <2800000>; + }; + }; + + vcc3v0_dvp: LDO_REG8 { + regulator-name = "vcc3v0_dvp"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vdd1v5_dvp: LDO_REG9 { + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-name = "vdd1v5_dvp"; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <1500000>; + }; + }; + + usb_midu: BOOST { + regulator-name = "usb_midu"; + regulator-min-microvolt = <4700000>; + regulator-max-microvolt = <5400000>; + regulator-always-on; + regulator-boot-on; + }; + + }; + + rk817_charger: charger { + monitored-battery = <&battery>; + rockchip,resistor-sense-micro-ohms = <10000>; + rockchip,sleep-enter-current-microamp = <300000>; + rockchip,sleep-filter-current-microamp = <100000>; + }; + + rk817_codec: codec { + rockchip,mic-in-differential; + }; + }; +}; + +/* I2S 1 Channel Used Header(P2):1(GPIO2.C3),2(.C2), 3(.C1), 4(.C5), 5(.C4) */ +&i2s1_2ch { + status = "okay"; + #sound-dai-cells = <0>; +}; + +&io_domains { + vccio1-supply = <&vcc1v8_soc>; + vccio2-supply = <&vccio_sd>; + vccio3-supply = <&vcc3v0_dvp>; + vccio4-supply = <&vcc_3v0>; + vccio5-supply = <&vcc_3v0>; + vccio6-supply = <&vcc_3v0>; + status = "okay"; +}; + +&isp { + status = "okay"; +}; + +&isp_mmu { + status = "okay"; +}; + +&pmu_io_domains { + pmuio1-supply = <&vcc3v0_pmu>; + pmuio2-supply = <&vcc3v0_pmu>; + status = "okay"; +}; + +&csi_dphy { + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; + +&saradc { + vref-supply = <&vcc1v8_soc>; + status = "okay"; +}; + +&sdmmc { + cap-sd-highspeed; + card-detect-delay = <200>; + cd-gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_LOW>; /*[> ff370000 PD_SDCARD CD GPIO <]*/ + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&sdio { + cap-sd-highspeed; + card-detect-delay = <200>; + cd-gpios = <&gpio3 RK_PB6 GPIO_ACTIVE_LOW>; /*[> CD GPIO <]*/ + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&tsadc { + status = "okay"; +}; + +&u2phy { + status = "okay"; + + u2phy_host: host-port { + status = "okay"; + }; + + u2phy_otg: otg-port { + status = "okay"; + }; +}; + +/* FIQ Header(P2): 2(RXD:GPIO2.B4),3(TXD:.B6) */ +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2m1_xfer>; + status = "okay"; +}; + +&usb20_otg { + status = "okay"; + dr_mode = "otg"; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; + +&pinctrl { + btns { + btn_pins: btn-pins { + rockchip,pins = <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + btn_pins_vol: btn-pins-vol { + rockchip,pins = + <0 RK_PC1 RK_FUNC_GPIO &pcfg_pull_up>, + <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + headphone { + hp_det: hp-det { + rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + gpio-lcd { + lcd_rst: lcd-rst { + rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + vcc18-lcd { + vcc18_lcd_n: vcc18-lcd-n { + rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + gpio-led { + led_pins: led-pins { + rockchip,pins = + <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>, + <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pmic { + dc_det: dc-det { + rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + pmic_int: pmic-int { + rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + soc_slppin_gpio: soc_slppin_gpio { + rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>; + }; + + soc_slppin_rst: soc_slppin_rst { + rockchip,pins = <0 RK_PA4 2 &pcfg_pull_none>; + }; + + soc_slppin_slp: soc_slppin_slp { + rockchip,pins = <0 RK_PA4 1 &pcfg_pull_none>; + }; + }; +}; diff --git a/config/archr-dts/rk3326-odroid-go.dtsi b/config/archr-dts/rk3326-odroid-go.dtsi new file mode 100644 index 0000000000..6195402b5b --- /dev/null +++ b/config/archr-dts/rk3326-odroid-go.dtsi @@ -0,0 +1,568 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Hardkernel Co., Ltd + * Copyright (c) 2020 Theobroma Systems Design und Consulting GmbH + * Copyright (c) 2022 Maya Matuszczyk + */ + +/dts-v1/; +#include +#include +#include +#include +#include "rk3326.dtsi" + +/ { + aliases { + mmc0 = &sdmmc; + }; + + chosen { + stdout-path = "serial2:115200n8"; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + power-supply = <&vcc_bl>; + pwms = <&pwm1 0 25000 0>; + brightness-levels = < + 0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 + 24 25 26 27 28 29 30 31 + 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 + 56 57 58 59 60 61 62 63 + 64 65 66 67 68 69 70 71 + 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 + 88 89 90 91 92 93 94 95 + 96 97 98 99 100 101 102 103 + 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 + 128 129 130 131 132 133 134 135 + 136 137 138 139 140 141 142 143 + 144 145 146 147 148 149 150 151 + 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 + 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 + 184 185 186 187 188 189 190 191 + 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 + 208 209 210 211 212 213 214 215 + 216 217 218 219 220 221 222 223 + 224 225 226 227 228 229 230 231 + 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 + 248 249 250 251 252 253 254 255>; + default-brightness-level = <128>; + }; + + /* led-1 is wired directly to output of always-on regulator */ + + gpio_led: gpio-leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&red_led_pin>; + + red_led: led-3 { + color = ; + gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>; + function = LED_FUNCTION_CHARGING; + }; + }; + + pwm_led: led-controller { + compatible = "pwm-leds"; + + blue_led: led-2 { + color = ; + function = LED_FUNCTION_STATUS; + linux,default-trigger = "heartbeat"; + max-brightness = <255>; + pwms = <&pwm3 0 25000 0>; + }; + }; + + rk817-sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "rk817_int"; + simple-audio-card,format = "i2s"; + simple-audio-card,hp-det-gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Headphone", "Headphones", + "Speaker", "Speaker"; + simple-audio-card,routing = + "MICL", "Mic Jack", + "Headphones", "HPOL", + "Headphones", "HPOR", + "Speaker", "SPKO"; + + simple-audio-card,codec { + sound-dai = <&rk817>; + }; + + simple-audio-card,cpu { + sound-dai = <&i2s1_2ch>; + }; + }; + + vccsys: regulator-vccsys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v8_sys"; + regulator-always-on; + regulator-min-microvolt = <3800000>; + regulator-max-microvolt = <3800000>; + }; + + vcc_host: regulator-vcc-host { + compatible = "regulator-fixed"; + regulator-name = "vcc_host"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + + gpio = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + vin-supply = <&usb_midu>; + }; +}; + +&dmc { + center-supply = <&vdd_logic>; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&cpu1 { + cpu-supply = <&vdd_arm>; +}; + +&cpu2 { + cpu-supply = <&vdd_arm>; +}; + +&cpu3 { + cpu-supply = <&vdd_arm>; +}; + +&cru { + assigned-clocks = <&cru PLL_NPLL>, + <&cru ACLK_BUS_PRE>, <&cru ACLK_PERI_PRE>, + <&cru HCLK_BUS_PRE>, <&cru HCLK_PERI_PRE>, + <&cru PCLK_BUS_PRE>, <&cru SCLK_GPU>; + + assigned-clock-rates = <1188000000>, + <200000000>, <200000000>, + <150000000>, <150000000>, + <100000000>, <200000000>; +}; + +&display_subsystem { + status = "okay"; +}; + +&dsi { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + ports { + mipi_out: port@1 { + reg = <1>; + + mipi_out_panel: endpoint { + remote-endpoint = <&mipi_in_panel>; + }; + }; + }; + + internal_display: panel@0 { + reg = <0>; + backlight = <&backlight>; + reset-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>; + + port { + mipi_in_panel: endpoint { + remote-endpoint = <&mipi_out_panel>; + }; + }; + }; +}; + +&dsi_dphy { + status = "okay"; +}; + +&gpu { + mali-supply = <&vdd_logic>; + status = "okay"; +}; + +&i2c0 { + clock-frequency = <400000>; + i2c-scl-falling-time-ns = <16>; + i2c-scl-rising-time-ns = <280>; + status = "okay"; + + rk817: pmic@20 { + compatible = "rockchip,rk817"; + reg = <0x20>; + interrupt-parent = <&gpio0>; + interrupts = ; + clock-output-names = "rk808-clkout1", "xin32k"; + clock-names = "mclk"; + clocks = <&cru SCLK_I2S1_OUT>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int>, <&i2s1_2ch_mclk>; + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <1>; + #sound-dai-cells = <0>; + + vcc1-supply = <&vccsys>; + vcc2-supply = <&vccsys>; + vcc3-supply = <&vccsys>; + vcc4-supply = <&vccsys>; + vcc5-supply = <&vccsys>; + vcc6-supply = <&vccsys>; + vcc7-supply = <&vccsys>; + vcc8-supply = <&vccsys>; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-name = "vdd_logic"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1150000>; + regulator-ramp-delay = <6001>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vdd_arm: DCDC_REG2 { + regulator-name = "vdd_arm"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_3v3: DCDC_REG4 { + regulator-name = "vcc_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_1v8: LDO_REG2 { + regulator-name = "vcc_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd_1v0: LDO_REG3 { + regulator-name = "vdd_1v0"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc3v3_pmu: LDO_REG4 { + regulator-name = "vcc3v3_pmu"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vccio_sd: LDO_REG5 { + regulator-name = "vccio_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_sd: LDO_REG6 { + regulator-name = "vcc_sd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_bl: LDO_REG7 { + regulator-name = "vcc_bl"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_lcd: LDO_REG8 { + regulator-name = "vcc_lcd"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <2800000>; + }; + }; + + LDO_REG9 { + /* unused */ + }; + + usb_midu: BOOST { + regulator-name = "usb_midu"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5400000>; + regulator-always-on; + regulator-boot-on; + }; + }; + + rk817_charger: charger { + rockchip,resistor-sense-micro-ohms = <10000>; + rockchip,sleep-enter-current-microamp = <300000>; + rockchip,sleep-filter-current-microamp = <100000>; + }; + + rk817_codec: codec { + rockchip,mic-in-differential; + }; + }; +}; + +/* EXT Header(P2): 7(SCL:GPIO0.C2), 8(SDA:GPIO0.C3) */ +&i2c1 { + clock-frequency = <400000>; + status = "okay"; +}; + +/* I2S 1 Channel Used */ +&i2s1_2ch { + status = "okay"; +}; + +&io_domains { + vccio1-supply = <&vcc_3v3>; + vccio2-supply = <&vccio_sd>; + vccio3-supply = <&vcc_3v3>; + vccio4-supply = <&vcc_3v3>; + vccio5-supply = <&vcc_3v3>; + vccio6-supply = <&vcc_3v3>; + status = "okay"; +}; + +&pmu_io_domains { + pmuio1-supply = <&vcc3v3_pmu>; + pmuio2-supply = <&vcc3v3_pmu>; + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; + +&pwm3 { + status = "okay"; +}; + +&saradc { + vref-supply = <&vcc_1v8>; + status = "okay"; +}; + +&sdmmc { + cap-sd-highspeed; + card-detect-delay = <200>; + cd-gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_LOW>; /*[> CD GPIO <]*/ + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&sfc { + pinctrl-0 = <&sfc_clk &sfc_cs0 &sfc_bus2>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <108000000>; + spi-rx-bus-width = <2>; + spi-tx-bus-width = <1>; + }; +}; + +&tsadc { + status = "okay"; +}; + +&u2phy { + status = "okay"; + + u2phy_host: host-port { + status = "okay"; + }; + + u2phy_otg: otg-port { + status = "okay"; + }; +}; + +&usb20_otg { + status = "okay"; +}; + +/* EXT Header(P2): 2(RXD:GPIO1.C0),3(TXD:.C1),4(CTS:.C2),5(RTS:.C3) */ +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_xfer &uart1_cts>; + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2m1_xfer>; + status = "okay"; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; + +&pinctrl { + btns { + btn_pins: btn-pins { + rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + headphone { + hp_det: hp-det { + rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; + + leds { + red_led_pin: red-led-pin { + rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pmic { + dc_det: dc-det { + rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + pmic_int: pmic-int { + rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + soc_slppin_gpio: soc_slppin_gpio { + rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>; + }; + + soc_slppin_rst: soc_slppin_rst { + rockchip,pins = <0 RK_PA4 2 &pcfg_pull_none>; + }; + + soc_slppin_slp: soc_slppin_slp { + rockchip,pins = <0 RK_PA4 1 &pcfg_pull_none>; + }; + }; +}; diff --git a/config/archr-dts/rk3326-odroid-go2-v11.dts b/config/archr-dts/rk3326-odroid-go2-v11.dts new file mode 100644 index 0000000000..489e0e2d0f --- /dev/null +++ b/config/archr-dts/rk3326-odroid-go2-v11.dts @@ -0,0 +1,310 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Hardkernel Co., Ltd + * Copyright (c) 2020 Theobroma Systems Design und Consulting GmbH + * Copyright (c) 2022 Maya Matuszczyk + */ + +/dts-v1/; +#include "rk3326-odroid-go.dtsi" + +/ { + model = "ODROID-GO Advance Black Edition"; + compatible = "hardkernel,rk3326-odroid-go2-v11", "rockchip,rk3326"; + + aliases { + mmc1 = &sdio; + }; + + gpio_keys: volume-keys { + compatible = "gpio-keys"; + autorepeat; + pinctrl-0 = <&btn_pins_vol>; + pinctrl-names = "default"; + + volume-up-button { + label = "VOLUMEUP"; + linux,code = ; + gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; + + }; + volume-down-button { + label = "VOLUMEDOWN"; + linux,code = ; + gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; + + }; + }; + + joypad: odroidgo2-joypad { + compatible = "odroidgo2-v11-joypad"; + + /* + - odroidgo2-joypad sysfs list - + * for poll device interval(ms) + /sys/devices/platform/odroidgo2_joypad/poll_interval [rw] + * for button-adc-fuzz + /sys/devices/platform/odroidgo2_joypad/adc_fuzz [r] + * for button-adc-flat + /sys/devices/platform/odroidgo2_joypad/adc_flat [r] + + * for report control(1:enable, 0:disable) + /sys/devices/platform/odroidgo2_joypad/enable [rw] + * for adc calibration value setup(1:current adcs value -> cal value) + /sys/devices/platform/odroidgo2_joypad/adc_cal [rw] + */ + + /* gpio pincontrol setup */ + pinctrl-names = "default"; + pinctrl-0 = <&btn_pins>; + + /* JOY_X, JOY_Y Channel define */ + io-channel-names = "joy_x", "joy_y"; + io-channels = <&saradc 1>, <&saradc 2>; + + /* adc channel count */ + button-adc-count = <2>; + + /* adc calculate scale */ + button-adc-scale = <2>; + + /* adc deadzone range */ + button-adc-deadzone = <20>; + + /* + joy-stick voltage range + /sys/devices/platform/ff288000.saradc/iio:device0 + adc-x : in_voltage1_raw + adc-y : in_voltage2_raw + + range calculate. + (adc raw max value - adc raw min value) * scale * 1.7515 + */ + button-adc-x-range = <1800>; + button-adc-y-range = <1800>; + + /* + specifies fuzz value that is used to filter noise from + the event stream. + */ + button-adc-fuzz = <32>; + button-adc-flat = <32>; + + /* poll device interval (ms), adc read interval */ + poll-interval = <10>; + + /* gpio button auto repeat set value : default disable */ + /* + autorepeat; + */ + + /* + *** ODROIDGO2-Advance Switch layoout *** + |------------------------------------------------| + | sw15 sw16 | + | sw20 sw21 | + |------------------------------------------------| + | sw1 |-------------------| sw8 | + | sw3 sw4 | | sw7 sw5 | + | sw2 | LCD Display | sw6 | + | | | | + | |-------------------| | + | sw9 sw10 vol- vol+ sw13 sw14 | + |------------------------------------------------| + */ + /* + joypad driver is poll-device driver. + poll-device is does not support wakeup-source. + */ + sw1 { + gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-UP"; + linux,code = ; // 0x220 + }; + sw2 { + gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-DOWN"; + linux,code = ; // 0x221 + }; + sw3 { + gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-LEFT"; + linux,code = ; // 0x222 + }; + sw4 { + gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-RIGHT"; + linux,code = ; // 0x223 + }; + sw5 { + gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>; + label = "GPIO KEY BTN-A"; + linux,code = ; // 0x131 + }; + sw6 { + gpios = <&gpio1 RK_PA5 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-B"; + linux,code = ; // 0x130 + }; + sw7 { + gpios = <&gpio1 RK_PA6 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-Y"; + linux,code = ; // 0x134 + }; + sw8 { + gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-X"; + linux,code = ; // 0x133 + }; + sw9 { + gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-SELECT"; + linux,code = ; // 0x2c0 + }; + sw10 { + gpios = <&gpio2 RK_PA1 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-THUMBL"; + linux,code = ; // 0x2c1 + }; + sw13 { + gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-THUMBR"; + linux,code = ; // 0x2c4 + }; + sw14 { + gpios = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-START"; + linux,code = ; // 0x13c + }; + sw15 { + gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-LEFT"; + linux,code = ; // 0x02 + }; + sw16 { + gpios = <&gpio2 RK_PA7 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-RIGHT"; + linux,code = ; // 0x05 + }; + sw20 { + gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-LEFT2"; + linux,code = ; + }; + sw21 { + gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-RIGHT2"; + linux,code = ; + }; + }; + + battery: battery { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <3000000>; + charge-term-current-microamp = <300000>; + constant-charge-current-max-microamp = <2000000>; + constant-charge-voltage-max-microvolt = <4200000>; + factory-internal-resistance-micro-ohms = <180000>; + voltage-max-design-microvolt = <4100000>; + voltage-min-design-microvolt = <3500000>; + + ocv-capacity-celsius = <20>; + ocv-capacity-table-0 = <4046950 100>, <4001920 95>, <3967900 90>, <3919950 85>, + <3888450 80>, <3861850 75>, <3831540 70>, <3799130 65>, + <3768190 60>, <3745650 55>, <3726610 50>, <3711630 45>, + <3696720 40>, <3685660 35>, <3674950 30>, <3663050 25>, + <3649470 20>, <3635260 15>, <3616920 10>, <3592440 5>, + <3574170 0>; + }; + + wifi_pwrseq: wifi-pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_pwrseq_pins>; + reset-gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>; + post-power-on-delay-ms = <300>; + power-off-delay-us = <200000>; + }; +}; + +&internal_display { + compatible = "elida,kd35t133"; + iovcc-supply = <&vcc_lcd>; + vdd-supply = <&vcc_lcd>; + rotation = <270>; +}; + +&rk817 { + regulators { + vcc_wifi: LDO_REG9 { + regulator-name = "vcc_wifi"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + }; +}; + +&rk817_charger { + monitored-battery = <&battery>; +}; + +&sdio { + #address-cells = <1>; + #size-cells = <0>; + bus-width = <4>; + cap-sd-highspeed; + cap-sdio-irq; + disable-wp; + keep-power-in-suspend; + non-removable; + vmmc-supply = <&vcc_wifi>; + mmc-pwrseq = <&wifi_pwrseq>; + status = "okay"; + + esp8089: wifi@1 { + compatible = "esp,esp8089"; + reg = <1>; + esp,crystal-26M-en = <1>; + }; +}; + +&pinctrl { + btns { + btn_pins: btn-pins { + rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + btn_pins_vol: btn-pins-vol { + rockchip,pins = <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + wifi { + wifi_pwrseq_pins: wifi-pwrseq-pins { + rockchip,pins = <3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB6 RK_FUNC_GPIO &pcfg_output_high>; + }; + }; +}; diff --git a/config/archr-dts/rk3326-odroid-go2.dts b/config/archr-dts/rk3326-odroid-go2.dts new file mode 100644 index 0000000000..f142737a01 --- /dev/null +++ b/config/archr-dts/rk3326-odroid-go2.dts @@ -0,0 +1,235 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Hardkernel Co., Ltd + * Copyright (c) 2020 Theobroma Systems Design und Consulting GmbH + * Copyright (c) 2022 Maya Matuszczyk + */ + +/dts-v1/; +#include "rk3326-odroid-go.dtsi" + +/ { + model = "ODROID-GO Advance"; + compatible = "hardkernel,rk3326-odroid-go2", "rockchip,rk3326"; + + gpio_keys: volume-keys { + compatible = "gpio-keys-polled"; + poll-interval = <5>; + autorepeat; + + volume-up-button { + label = "VOLUME-UP"; + linux,code = ; + gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; + + }; + volume-down-button { + label = "VOLUME-DOWN"; + linux,code = ; + gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; + + }; + }; + + joypad: odroidgo2-joypad { + compatible = "odroidgo2-joypad"; + + /* + - odroidgo2-joypad sysfs list - + * for poll device interval(ms) + /sys/devices/platform/odroidgo2_joypad/poll_interval [rw] + * for button-adc-fuzz + /sys/devices/platform/odroidgo2_joypad/adc_fuzz [r] + * for button-adc-flat + /sys/devices/platform/odroidgo2_joypad/adc_flat [r] + + * for report control(1:enable, 0:disable) + /sys/devices/platform/odroidgo2_joypad/enable [rw] + * for adc calibration value setup(1:current adcs value -> cal value) + /sys/devices/platform/odroidgo2_joypad/adc_cal [rw] + */ + + /* gpio pincontrol setup */ + pinctrl-names = "default"; + pinctrl-0 = <&btn_pins>; + + /* JOY_X, JOY_Y Channel define */ + io-channel-names = "joy_x", "joy_y"; + io-channels = <&saradc 1>, <&saradc 2>; + + /* adc channel count */ + button-adc-count = <2>; + + /* adc calculate scale */ + button-adc-scale = <2>; + + /* adc deadzone range */ + button-adc-deadzone = <20>; + + /* + joy-stick voltage range + /sys/devices/platform/ff288000.saradc/iio:device0 + adc-x : in_voltage1_raw + adc-y : in_voltage2_raw + + range calculate. + (adc raw max value - adc raw min value) * scale * 1.7515 + */ + button-adc-x-range = <1800>; + button-adc-y-range = <1800>; + + /* + specifies fuzz value that is used to filter noise from + the event stream. + */ + button-adc-fuzz = <32>; + button-adc-flat = <32>; + + /* poll device interval (ms), adc read interval */ + poll-interval = <10>; + + /* gpio button auto repeat set value : default disable */ + /* + autorepeat; + */ + + /* + *** ODROIDGO2-Advance Switch layoout *** + |------------------------------------------------| + | sw15 sw16 | + |------------------------------------------------| + | sw1 |-------------------| sw8 | + | sw3 sw4 | | sw7 sw5 | + | sw2 | LCD Display | sw6 | + | | | | + | |-------------------| | + | sw9 sw10 vol- vol+ sw13 sw14 | + |------------------------------------------------| + */ + /* + joypad driver is poll-device driver. + poll-device is does not support wakeup-source. + */ + sw1 { + gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-UP"; + linux,code = ; // 0x220 + }; + sw2 { + gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-DOWN"; + linux,code = ; // 0x221 + }; + sw3 { + gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-LEFT"; + linux,code = ; // 0x222 + }; + sw4 { + gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-RIGHT"; + linux,code = ; // 0x223 + }; + sw5 { + gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>; + label = "GPIO KEY BTN-A"; + linux,code = ; // 0x131 + }; + sw6 { + gpios = <&gpio1 RK_PA5 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-B"; + linux,code = ; // 0x130 + }; + sw7 { + gpios = <&gpio1 RK_PA6 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-Y"; + linux,code = ; // 0x134 + }; + sw8 { + gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-X"; + linux,code = ; // 0x133 + }; + sw9 { + gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; + label = "GPIO F1"; + linux,code = ; // 0x2c0 + }; + sw10 { + gpios = <&gpio2 RK_PA1 GPIO_ACTIVE_LOW>; + label = "GPIO F2"; + linux,code = ; // 0x2c1 + }; + sw13 { + gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_LOW>; + label = "GPIO F5"; + linux,code = ; // 0x2c4 + }; + sw14 { + gpios = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>; + label = "GPIO F6"; + linux,code = ; // 0x13c + }; + sw15 { + gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-LEFT"; + linux,code = ; // 0x02 + }; + sw16 { + gpios = <&gpio2 RK_PA7 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-RIGHT"; + linux,code = ; // 0x05 + }; + }; + + battery: battery { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <3000000>; + charge-term-current-microamp = <300000>; + constant-charge-current-max-microamp = <2000000>; + constant-charge-voltage-max-microvolt = <4200000>; + factory-internal-resistance-micro-ohms = <180000>; + voltage-max-design-microvolt = <4100000>; + voltage-min-design-microvolt = <3500000>; + + ocv-capacity-celsius = <20>; + ocv-capacity-table-0 = <4046950 100>, <4001920 95>, <3967900 90>, <3919950 85>, + <3888450 80>, <3861850 75>, <3831540 70>, <3799130 65>, + <3768190 60>, <3745650 55>, <3726610 50>, <3711630 45>, + <3696720 40>, <3685660 35>, <3674950 30>, <3663050 25>, + <3649470 20>, <3635260 15>, <3616920 10>, <3592440 5>, + <3574170 0>; + }; +}; + +&internal_display { + compatible = "elida,kd35t133"; + iovcc-supply = <&vcc_lcd>; + vdd-supply = <&vcc_lcd>; + rotation = <270>; +}; + +&rk817_charger { + monitored-battery = <&battery>; +}; + +&pinctrl { + btns { + btn_pins: btn-pins { + rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; diff --git a/config/archr-dts/rk3326-odroid-go3.dts b/config/archr-dts/rk3326-odroid-go3.dts new file mode 100644 index 0000000000..c3099f9cfe --- /dev/null +++ b/config/archr-dts/rk3326-odroid-go3.dts @@ -0,0 +1,289 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Hardkernel Co., Ltd + * Copyright (c) 2020 Theobroma Systems Design und Consulting GmbH + * Copyright (c) 2022 Maya Matuszczyk + */ + +/dts-v1/; +#include "rk3326-odroid-go.dtsi" + +/ { + model = "ODROID-GO Super"; + compatible = "hardkernel,rk3326-odroid-go3", "rockchip,rk3326"; + + joypad: odroidgo3-joypad { + compatible = "odroidgo3-joypad"; + + joypad-name = "odroidgo3_joypad"; + joypad-product = <0x0001>; + joypad-revision = <0x0101>; + + status = "okay"; + /* + - odroidgo3-joypad sysfs list - + * for poll device interval(ms) + /sys/devices/platform/odroidgo3_joypad/poll_interval [rw] + ex) echo 20 > poll_interval + * for button-adc-fuzz + /sys/devices/platform/odroidgo3_joypad/adc_fuzz [r] + * for button-adc-flat + /sys/devices/platform/odroidgo3_joypad/adc_flat [r] + + * for report control(1:enable, 0:disable) + /sys/devices/platform/odroidgo3_joypad/enable [rw] + * for adc calibration value setup(current adcs value -> cal value) + /sys/devices/platform/odroidgo3_joypad/adc_cal [rw] + ex) echo 0 > adc_cal + * for amux data debug + * Joypad driver is disabled when using this sysfs. + /sys/devices/platform/odroidgo3_joypad/amux_debug [rw] + ex) echo 0 > amux_debug --> select amux channel + ex) cat amux_debug --> get adc data of seleted channel + */ + + /* gpio pincontrol setup */ + pinctrl-names = "default"; + pinctrl-0 = <&btn_pins>; + + /* Analog mux define */ + io-channel-names = "amux_adc"; + io-channels = <&saradc 1>; + + /* adc mux channel count */ + amux-count = <4>; + /* adc mux select(a,b) gpio */ + amux-a-gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_LOW>; + amux-b-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>; + /* adc mux enable gpio */ + amux-en-gpios = <&gpio3 RK_PB5 GPIO_ACTIVE_LOW>; + + /* adc calculate scale */ + button-adc-scale = <2>; + + /* adc deadzone range */ + button-adc-deadzone = <64>; + + /* + specifies fuzz value that is used to filter noise from + the event stream. + */ + button-adc-fuzz = <32>; + button-adc-flat = <32>; + + /* + Analog Stick data tuning value(precent) + p = positive direction, n = negative direction + report value = (real_adc_data * tuning_value) / 100 + */ + abs_x-p-tuning = <180>; + abs_x-n-tuning = <180>; + + abs_y-p-tuning = <180>; + abs_y-n-tuning = <170>; + + abs_rx-p-tuning = <180>; + abs_rx-n-tuning = <180>; + + abs_ry-p-tuning = <180>; + abs_ry-n-tuning = <170>; + + /* poll device interval (ms), adc read interval */ + poll-interval = <10>; + + /* gpio button auto repeat set value : default disable */ + /* + autorepeat; + */ + + /* + *** ODROIDGO3-Advance Switch layoout *** + |------------------------------------------------| + | sw15 sw21 sw10 sw9 sw20 sw16 | + |------------------------------------------------| + | sw19 sw22 | + | |-------------------| | + | sw1 | | sw8 | + | sw3 sw4 | | sw7 sw5 | + | sw2 | LCD Display | sw6 | + | | | | + | | | | + | |-------------------| | + | sw11 sw12 | sd-slot | sw13 sw14 | + |-------------------| |------------------| + */ + /* + joypad driver is poll-device driver. + poll-device is does not support wakeup-source. + */ + sw1 { + gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-UP"; + linux,code = ; // 0x220 + }; + sw2 { + gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-DOWN"; + linux,code = ; // 0x221 + }; + sw3 { + gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-LEFT"; + linux,code = ; // 0x222 + }; + sw4 { + gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-RIGHT"; + linux,code = ; // 0x223 + }; + sw5 { + gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>; + label = "GPIO KEY BTN-A"; + linux,code = ; // 0x131 + }; + sw6 { + gpios = <&gpio1 RK_PA5 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-B"; + linux,code = ; // 0x130 + }; + sw7 { + gpios = <&gpio1 RK_PA6 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-Y"; + linux,code = ; // 0x134 + }; + sw8 { + gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-X"; + linux,code = ; // 0x133 + }; + sw11 { + gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; + label = "GPIO F3"; + linux,code = ; // 0x2c2 + }; + sw12 { + gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; + label = "GPIO F4"; + linux,code = ; // 0x2c3 + }; + sw13 { + gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_LOW>; + label = "GPIO F5"; + linux,code = ; // 0x2c4 + }; + sw14 { + gpios = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>; + label = "GPIO F6"; + linux,code = ; // 0x13c + }; + sw15 { + gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-LEFT"; + linux,code = ; // 0x02 + }; + sw16 { + gpios = <&gpio2 RK_PA7 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-RIGHT"; + linux,code = ; // 0x05 + }; + sw19 { + gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>; + label = "GPIO F1"; + linux,code = ; + }; + sw20 { + gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-RIGHT2"; + linux,code = ; + }; + sw21 { + gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-LEFT2"; + linux,code = ; + }; + sw22 { + gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; + label = "GPIO F2"; + linux,code = ; + }; + }; + + battery: battery { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <4000000>; + charge-term-current-microamp = <300000>; + constant-charge-current-max-microamp = <2000000>; + constant-charge-voltage-max-microvolt = <4200000>; + factory-internal-resistance-micro-ohms = <180000>; + voltage-max-design-microvolt = <4100000>; + voltage-min-design-microvolt = <3500000>; + + ocv-capacity-celsius = <20>; + ocv-capacity-table-0 = <4046950 100>, <4001920 95>, <3967900 90>, <3919950 85>, + <3888450 80>, <3861850 75>, <3831540 70>, <3799130 65>, + <3768190 60>, <3745650 55>, <3726610 50>, <3711630 45>, + <3696720 40>, <3685660 35>, <3674950 30>, <3663050 25>, + <3649470 20>, <3635260 15>, <3616920 10>, <3592440 5>, + <3574170 0>; + }; + + gpio-keys-vol { + compatible = "gpio-keys"; + autorepeat; + pinctrl-0 = <&btn_pins_vol>; + pinctrl-names = "default"; + + button-vol-down { + gpios = <&gpio2 RK_PA1 GPIO_ACTIVE_LOW>; + label = "VOLUMEDOWN"; + linux,code = ; + }; + + button-volume-up { + gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; + label = "VOLUMEUP"; + linux,code = ; + }; + }; +}; + +&internal_display { + compatible = "elida,kd50t048a", "sitronix,st7701"; + reset-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_HIGH>; + IOVCC-supply = <&vcc_lcd>; + VCC-supply = <&vcc_lcd>; + rotation = <270>; +}; + +&rk817_charger { + monitored-battery = <&battery>; +}; + +&pinctrl { + btns { + btn_pins: btn-pins { + rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + btn_pins_vol: btn-pins-vol { + rockchip,pins = <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; diff --git a/config/archr-dts/rk3326-powkiddy-rgb10.dts b/config/archr-dts/rk3326-powkiddy-rgb10.dts new file mode 100644 index 0000000000..de0f069fdd --- /dev/null +++ b/config/archr-dts/rk3326-powkiddy-rgb10.dts @@ -0,0 +1,282 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Hardkernel Co., Ltd + * Copyright (c) 2020 Theobroma Systems Design und Consulting GmbH + * Copyright (c) 2022 Maya Matuszczyk + */ + +/dts-v1/; +#include "rk3326-odroid-go.dtsi" + +/ { + model = "Powkiddy RGB10"; + compatible = "powkiddy,rk3326-rgb10", "rockchip,rk3326"; + + aliases { + mmc1 = &sdio; + }; + + joypad: odroidgo2-joypad { + compatible = "odroidgo2-v11-joypad"; + + /* + - odroidgo2-joypad sysfs list - + * for poll device interval(ms) + /sys/devices/platform/odroidgo2_joypad/poll_interval [rw] + * for button-adc-fuzz + /sys/devices/platform/odroidgo2_joypad/adc_fuzz [r] + * for button-adc-flat + /sys/devices/platform/odroidgo2_joypad/adc_flat [r] + + * for report control(1:enable, 0:disable) + /sys/devices/platform/odroidgo2_joypad/enable [rw] + * for adc calibration value setup(1:current adcs value -> cal value) + /sys/devices/platform/odroidgo2_joypad/adc_cal [rw] + */ + + /* gpio pincontrol setup */ + pinctrl-names = "default"; + pinctrl-0 = <&btn_pins>; + + /* JOY_X, JOY_Y Channel define */ + io-channel-names = "joy_x", "joy_y"; + io-channels = <&saradc 1>, <&saradc 2>; + + /* adc channel count */ + button-adc-count = <2>; + + /* adc calculate scale */ + button-adc-scale = <2>; + + /* adc deadzone range */ + button-adc-deadzone = <20>; + + /* + joy-stick voltage range + /sys/devices/platform/ff288000.saradc/iio:device0 + adc-x : in_voltage1_raw + adc-y : in_voltage2_raw + + range calculate. + (adc raw max value - adc raw min value) * scale * 1.7515 + */ + button-adc-x-range = <1800>; + button-adc-y-range = <1800>; + + /* + specifies fuzz value that is used to filter noise from + the event stream. + */ + button-adc-fuzz = <32>; + button-adc-flat = <32>; + + /* poll device interval (ms), adc read interval */ + poll-interval = <10>; + + /* gpio button auto repeat set value : default disable */ + /* + autorepeat; + */ + + /* + *** RGB10 Switch layoout *** + |------------------------------------------------| + | sw15 sw16 | + | sw20 sw21 | + |------------------------------------------------| + | sw1 sw10 |-------------------| sw13 sw8 | + | sw3 sw4 | | sw7 sw5 | + | sw2 | LCD Display | sw6 | + | | | | + | |-------------------| | + |------------------------------------------------| + */ + /* + joypad driver is poll-device driver. + poll-device is does not support wakeup-source. + */ + sw1 { + gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-UP"; + linux,code = ; // 0x220 + }; + sw2 { + gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-DOWN"; + linux,code = ; // 0x221 + }; + sw3 { + gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-LEFT"; + linux,code = ; // 0x222 + }; + sw4 { + gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-RIGHT"; + linux,code = ; // 0x223 + }; + sw5 { + gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>; + label = "GPIO KEY BTN-A"; + linux,code = ; // 0x131 + }; + sw6 { + gpios = <&gpio1 RK_PA5 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-B"; + linux,code = ; // 0x130 + }; + sw7 { + gpios = <&gpio1 RK_PA6 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-Y"; + linux,code = ; // 0x134 + }; + sw8 { + gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-X"; + linux,code = ; // 0x133 + }; + sw9 { + gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-SELECT"; + linux,code = ; // 0x2c0 + }; + sw10 { + gpios = <&gpio2 RK_PA1 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-THUMBL"; + linux,code = ; // 0x2c1 + }; + sw13 { + gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-THUMBR"; + linux,code = ; // 0x2c4 + }; + sw14 { + gpios = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-START"; + linux,code = ; // 0x13c + }; + sw15 { + gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-LEFT"; + linux,code = ; // 0x02 + }; + sw16 { + gpios = <&gpio2 RK_PA7 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-RIGHT"; + linux,code = ; // 0x05 + }; + sw20 { + gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-LEFT2"; + linux,code = ; + }; + sw21 { + gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-RIGHT2"; + linux,code = ; + }; + }; + + battery: battery { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <2800000>; + charge-term-current-microamp = <280000>; + constant-charge-current-max-microamp = <2000000>; + constant-charge-voltage-max-microvolt = <4200000>; + factory-internal-resistance-micro-ohms = <180000>; + voltage-max-design-microvolt = <4100000>; + voltage-min-design-microvolt = <3500000>; + + ocv-capacity-celsius = <20>; + ocv-capacity-table-0 = <4046950 100>, <4001920 95>, <3967900 90>, <3919950 85>, + <3888450 80>, <3861850 75>, <3831540 70>, <3799130 65>, + <3768190 60>, <3745650 55>, <3726610 50>, <3711630 45>, + <3696720 40>, <3685660 35>, <3674950 30>, <3663050 25>, + <3649470 20>, <3635260 15>, <3616920 10>, <3592440 5>, + <3574170 0>; + }; + + wifi_pwrseq: wifi-pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_pwrseq_pins>; + /*reset-gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>;*/ + }; +}; + +&internal_display { + compatible = "elida,kd35t133"; + iovcc-supply = <&vcc_lcd>; + vdd-supply = <&vcc_lcd>; + rotation = <270>; +}; + +&rk817 { + regulators { + vcc_wifi: LDO_REG9 { + regulator-name = "vcc_wifi"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + }; +}; + +&rk817_charger { + monitored-battery = <&battery>; +}; + +&sdio { + #address-cells = <1>; + #size-cells = <0>; + bus-width = <4>; + cap-sd-highspeed; + cap-sdio-irq; + disable-wp; + keep-power-in-suspend; + non-removable; + vmmc-supply = <&vcc_wifi>; + status = "okay"; + + esp8089: wifi@1 { + compatible = "esp,esp8089"; + reg = <1>; + esp,crystal-26M-en = <2>; + }; +}; + +&pinctrl { + btns { + btn_pins: btn-pins { + rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + wifi { + wifi_pwrseq_pins: wifi-pwrseq-pins { + rockchip,pins = /*<3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>,*/ + <3 RK_PB6 RK_FUNC_GPIO &pcfg_output_high>; + }; + }; +}; diff --git a/config/archr-dts/rk3326-powkiddy-rgb10x.dts b/config/archr-dts/rk3326-powkiddy-rgb10x.dts new file mode 100644 index 0000000000..debc628194 --- /dev/null +++ b/config/archr-dts/rk3326-powkiddy-rgb10x.dts @@ -0,0 +1,214 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2024 ROCKNIX + */ + +/dts-v1/; +#include "rk3326-odroid-go.dtsi" +#include "retrogame_joypad_s2_f1.dtsi" +#include "rk3326-device-group-r36.dtsi" + +/ { + model = "Powkiddy RGB10X"; + compatible = "powkiddy,rk3326-rgb10x", "rockchip,rk3326"; + + archr,device_switch { + this = "rgb10x"; + }; + + aliases { + mmc1 = &sdio; + }; + + battery: battery { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <2800000>; + charge-term-current-microamp = <280000>; + constant-charge-current-max-microamp = <2000000>; + constant-charge-voltage-max-microvolt = <4200000>; + factory-internal-resistance-micro-ohms = <180000>; + voltage-max-design-microvolt = <4100000>; + voltage-min-design-microvolt = <3500000>; + + ocv-capacity-celsius = <20>; + ocv-capacity-table-0 = <4046950 100>, <4001920 95>, <3967900 90>, <3919950 85>, + <3888450 80>, <3861850 75>, <3831540 70>, <3799130 65>, + <3768190 60>, <3745650 55>, <3726610 50>, <3711630 45>, + <3696720 40>, <3685660 35>, <3674950 30>, <3663050 25>, + <3649470 20>, <3635260 15>, <3616920 10>, <3592440 5>, + <3574170 0>; + }; + + gpio-keys-vol { + compatible = "gpio-keys"; + autorepeat; + pinctrl-0 = <&btn_pins_vol>; + pinctrl-names = "default"; + + button-vol-down { + gpios = <&gpio2 RK_PA1 GPIO_ACTIVE_LOW>; + label = "VOLUMEDOWN"; + linux,code = ; + }; + + button-volume-up { + gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; + label = "VOLUMEUP"; + linux,code = ; + }; + }; +}; + +&joypad { + compatible = "archr-singleadc-joypad"; + joypad-name = "retrogame_joypad_s1_f2"; /* distinct name to indicate there is 1 stick and 2 fn buttons */ + joypad-product = <0x1112>; /* 11 inherited, 1 for number of sticks, 2 for number of FN */ + status = "okay"; + + /* gpio pincontrol setup */ + pinctrl-names = "default"; + pinctrl-0 = <&btn_pins>; + + /* Analog mux define */ + io-channel-names = "amux_adc"; + io-channels = <&saradc 1>; + + /* adc mux channel count */ + /* despite there is only left stick, amux-count needs to be 4, */ + /* because amux 0 and 1 are hardcoded as RX and RY in the driver */ + amux-count = <4>; + /* adc mux select(a,b) gpio */ + amux-a-gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_LOW>; + amux-b-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>; + /* adc mux enable gpio */ + amux-en-gpios = <&gpio3 RK_PB5 GPIO_ACTIVE_LOW>; + + /* + Analog Stick data tuning value(precent) + p = positive direction, n = negative direction + report value = (real_adc_data * tuning_value) / 100 + */ + abs_x-p-tuning = <200>; + abs_x-n-tuning = <200>; + + abs_y-p-tuning = <200>; + abs_y-n-tuning = <200>; + + abs_rx-p-tuning = <200>; + abs_rx-n-tuning = <200>; + + abs_ry-p-tuning = <200>; + abs_ry-n-tuning = <200>; + + /* required for RGB10X */ + invert-absx; + invert-absy; + + /* + joypad driver is poll-device driver. + poll-device is does not support wakeup-source. + */ + up { gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>; }; + down { gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_LOW>; }; + left { gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; }; + right { gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_LOW>; }; + + a { gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>; }; + b { gpios = <&gpio1 RK_PA5 GPIO_ACTIVE_LOW>; }; + x { gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_LOW>; }; + y { gpios = <&gpio1 RK_PA6 GPIO_ACTIVE_LOW>; }; + + tl { gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_LOW>; }; + tr { gpios = <&gpio2 RK_PA7 GPIO_ACTIVE_LOW>; }; + tr2 { gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; }; + tl2 { gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; }; + + select{ gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>; }; + start { gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; }; + + thumbl{ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; }; + + /* Plus and Minus face buttons are mapped to mode and thumbr */ + mode { + gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_LOW>; + label = "GPIO MINUS"; + }; + thumbr { + gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; + label = "GPIO PLUS"; + }; +}; + +&internal_display { + compatible = "powkiddy,rk2023-panel", "newvision,nv3051d"; + vdd-supply = <&vcc_lcd>; +}; + +&io_domains { + vccio1-supply = <&vccio_sd>; +}; + +/delete-node/ &pwm3; +/delete-node/ &pwm_led; + +&red_led { + gpios = <&gpio2 RK_PB5 GPIO_ACTIVE_HIGH>; +}; + +&red_led_pin { + rockchip,pins = <2 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; +}; + +&rk817_charger { + monitored-battery = <&battery>; +}; + +&sdio { + cap-sd-highspeed; + card-detect-delay = <200>; + cd-gpios = <&gpio3 RK_PB6 GPIO_ACTIVE_LOW>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&vcc_sd { + regulator-max-microvolt = <3000000>; + regulator-min-microvolt = <1800000>; +}; + +&vccio_sd { + regulator-max-microvolt = <1800000>; +}; + +&pinctrl { + btns { + btn_pins: btn-pins { + rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + btn_pins_vol: btn-pins-vol { + rockchip,pins = <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; diff --git a/config/archr-dts/rk3326-powkiddy-rgb20s.dts b/config/archr-dts/rk3326-powkiddy-rgb20s.dts new file mode 100644 index 0000000000..93f149e62a --- /dev/null +++ b/config/archr-dts/rk3326-powkiddy-rgb20s.dts @@ -0,0 +1,375 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Hardkernel Co., Ltd + * Copyright (c) 2020 Theobroma Systems Design und Consulting GmbH + * Copyright (c) 2022 Maya Matuszczyk + */ + +/dts-v1/; +#include "rk3326-odroid-go.dtsi" + +/ { + model = "Powkiddy RGB20S"; + compatible = "powkiddy,rgb20s", "rockchip,rk3326"; + + aliases { + mmc0 = &sdio; + mmc1 = &sdmmc; + }; + + gpio-keys-vol { + compatible = "gpio-keys"; + autorepeat; + pinctrl-0 = <&btn_pins_vol>; + pinctrl-names = "default"; + + button-vol-down { + gpios = <&gpio2 RK_PA1 GPIO_ACTIVE_LOW>; + label = "VOLUMEDOWN"; + linux,code = ; + }; + + button-volume-up { + gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; + label = "VOLUMEUP"; + linux,code = ; + }; + }; + + joypad: joypad { + compatible = "archr-singleadc-joypad"; + + pwms = <&pwm0 0 200000000 0>; + pwm-names = "enable"; + rumble-boost-weak = <0x0000>; + rumble-boost-strong = <0x0000>; + + joypad-name = "r36s_Gamepad"; + joypad-product = <0x1188>; + joypad-revision = <0x0188>; + joypad-vendor = <0x0001>; + + status = "okay"; + + /* gpio pincontrol setup */ + pinctrl-names = "default"; + pinctrl-0 = <&btn_pins>; + pinctrl-1 = <&pwm0_pin>; + + /* Analog mux define */ + io-channel-names = "amux_adc"; + io-channels = <&saradc 1>; + + /* adc mux channel count */ + amux-count = <4>; + /* non-default wiring */ + amux-channel-mapping = <0 1 2 3>; + /* adc mux select(a,b) gpio */ + amux-a-gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_LOW>; + amux-b-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>; + /* adc mux enable gpio */ + amux-en-gpios = <&gpio3 RK_PB5 GPIO_ACTIVE_LOW>; + + /* adc calculate scale */ + button-adc-scale = <2>; + + /* adc deadzone range */ + button-adc-deadzone = <64>; + + /* + specifies fuzz value that is used to filter noise from + the event stream. + */ + button-adc-fuzz = <32>; + button-adc-flat = <32>; + + /* + Analog Stick data tuning value(precent) + p = positive direction, n = negative direction + report value = (real_adc_data * tuning_value) / 100 + */ + abs_x-p-tuning = <400>; + abs_x-n-tuning = <400>; + + abs_y-p-tuning = <400>; + abs_y-n-tuning = <400>; + + abs_rx-p-tuning = <400>; + abs_rx-n-tuning = <400>; + + abs_ry-p-tuning = <400>; + abs_ry-n-tuning = <400>; + + /* poll device interval (ms), adc read interval */ + poll-interval = <10>; + + /* required for RG351MP */ + invert-absx; + invert-absy; + + /* gpio button auto repeat set value : default disable */ + /* + autorepeat; + */ + + /* + joypad driver is poll-device driver. + poll-device is does not support wakeup-source. + */ + sw1 { + gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-UP"; + linux,code = ; // 0x220 + }; + sw2 { + gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-DOWN"; + linux,code = ; // 0x221 + }; + sw3 { + gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-LEFT"; + linux,code = ; // 0x222 + }; + sw4 { + gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-RIGHT"; + linux,code = ; // 0x223 + }; + sw5 { + gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>; + label = "GPIO KEY BTN-A"; + linux,code = ; // 0x131 + }; + sw6 { + gpios = <&gpio1 RK_PA5 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-B"; + linux,code = ; // 0x130 + }; + sw7 { + gpios = <&gpio1 RK_PA6 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-Y"; + linux,code = ; // 0x134 + }; + sw8 { + gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-X"; + linux,code = ; // 0x133 + }; + sw11 { + gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; + label = "GPIO BTN_THUMBL"; + linux,code = ; // 0x2c2 + }; + sw12 { + gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; + label = "GPIO BTN_THUMBR"; + linux,code = ; // 0x2c3 + }; + + sw13 { + gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_LOW>; + label = "GPIO BTN_FN"; + linux,code = ; // 0x2c4 + }; + + sw15 { + gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-LEFT"; + linux,code = ; // 0x02 + }; + sw16 { + gpios = <&gpio2 RK_PA7 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-RIGHT"; + linux,code = ; // 0x05 + }; + sw19 { + gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>; + label = "GPIO BTN_SELECT"; + linux,code = ; + }; + sw20 { + gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-RIGHT2"; + linux,code = ; + }; + sw21 { + gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-LEFT2"; + linux,code = ; + }; + sw22 { + gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; + label = "GPIO BTN_START"; + linux,code = ; + }; + }; + + battery: battery { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <3500000>; + charge-term-current-microamp = <350000>; + constant-charge-current-max-microamp = <2000000>; + constant-charge-voltage-max-microvolt = <4200000>; + factory-internal-resistance-micro-ohms = <180000>; + voltage-max-design-microvolt = <4100000>; + voltage-min-design-microvolt = <3500000>; + + ocv-capacity-celsius = <20>; + ocv-capacity-table-0 = <4046950 100>, <4001920 95>, <3967900 90>, <3919950 85>, + <3888450 80>, <3861850 75>, <3831540 70>, <3799130 65>, + <3768190 60>, <3745650 55>, <3726610 50>, <3711630 45>, + <3696720 40>, <3685660 35>, <3674950 30>, <3663050 25>, + <3649470 20>, <3635260 15>, <3616920 10>, <3592440 5>, + <3574170 0>; + }; +}; + +/* conflicts with pwm vibration motor */ +/delete-node/ &vcc_host; + +/* Device only has 1 LED compared to Odroid Go Advance */ +/delete-node/ &gpio_led; + +&internal_display { +// compatible = "anbernic,rg351v-panel", "newvision,nv3051d"; + // compatible = "powkiddy,rk2023-panel", "newvision,nv3051d"; + compatible = "archr,generic-dsi"; + iovcc-supply = <&vcc_lcd>; + vdd-supply = <&vcc_lcd>; + panel_description = + "G size=52,70 delays=2,1,20,120,20 format=rgb888 lanes=4 flags=0xe03", + + "M clock=26400 horizontal=640,119,2,119 vertical=480,13,2,5 default=1", + "M clock=27300 horizontal=640,207,24,207 vertical=480,13,9,5", + "M clock=26400 horizontal=640,207,2,207 vertical=480,13,2,5", + "M clock=27140 horizontal=640,119,45,119 vertical=480,13,90,5", + "M clock=26450 horizontal=640,119,42,119 vertical=480,13,2,5", + "M clock=28520 horizontal=640,119,3,119 vertical=480,13,44,5", + "M clock=31440 horizontal=640,119,39,119 vertical=480,13,74,5", + "M clock=26440 horizontal=640,31,30,31 vertical=480,13,103,5", + "M clock=31970 horizontal=640,31,36,31 vertical=480,13,76,5", + // "M clock=31680 horizontal=640,31,2,31 vertical=480,13,2,5", + "M clock=42240 horizontal=640,31,2,31 vertical=480,13,2,5", + + "I seq=ff30", "I seq=ff52", "I seq=ff01", + "I seq=e300", + "I seq=400a", + "I seq=0340", "I seq=0400", "I seq=0503", + "I seq=2412", "I seq=251e", "I seq=2628", "I seq=2752", + "I seq=2857", "I seq=2901", "I seq=2adf", + "I seq=389c", "I seq=39a7", "I seq=3a53", + "I seq=4400", + "I seq=493c", + "I seq=59fe", "I seq=5c00", + "I seq=9177", "I seq=9277", + "I seq=a055", "I seq=a150", "I seq=a49c", "I seq=a702", + "I seq=a801", "I seq=a901", "I seq=aafc", "I seq=ab28", "I seq=ac06", "I seq=ad06", "I seq=ae06", "I seq=af03", + "I seq=b008", "I seq=b126", "I seq=b228", "I seq=b328", "I seq=b433", "I seq=b508", "I seq=b626", "I seq=b708", + "I seq=b826", + "I seq=ff30", "I seq=ff52", "I seq=ff02", + "I seq=b00b", "I seq=b116", "I seq=b217", "I seq=b32c", "I seq=b432", "I seq=b53b", "I seq=b629", "I seq=b740", + "I seq=b80d", "I seq=b905", "I seq=ba12", "I seq=bb10", "I seq=bc12", "I seq=bd15", "I seq=be19", "I seq=bf0e", + "I seq=c016", "I seq=c10a", + "I seq=d00c", "I seq=d117", "I seq=d214", "I seq=d32e", "I seq=d432", "I seq=d53c", "I seq=d622", "I seq=d73d", + "I seq=d80d", "I seq=d907", "I seq=da13", "I seq=db13", "I seq=dc11", "I seq=dd15", "I seq=de19", "I seq=df10", + "I seq=e017", "I seq=e10a", + "I seq=ff30", "I seq=ff52", "I seq=ff03", + "I seq=002a", "I seq=012a", "I seq=022a", "I seq=032a", "I seq=0461", "I seq=0580", "I seq=06c7", "I seq=0701", + "I seq=0882", "I seq=0983", + "I seq=302a", "I seq=312a", "I seq=322a", "I seq=332a", "I seq=3461", "I seq=35c5", "I seq=3680", "I seq=3723", + "I seq=4082", "I seq=4183", "I seq=4280", "I seq=4381", "I seq=4411", "I seq=45e6", "I seq=46e5", "I seq=4711", + "I seq=48e8", "I seq=49e7", + "I seq=5002", "I seq=5101", "I seq=5204", "I seq=5303", "I seq=5411", "I seq=55ea", "I seq=56e9", "I seq=5711", + "I seq=58ec", "I seq=59eb", + "I seq=7e02", "I seq=7f80", + "I seq=e05a", + "I seq=b100", "I seq=b40e", "I seq=b50f", "I seq=b604", "I seq=b707", + "I seq=b806", "I seq=b905", "I seq=ba0f", + "I seq=c700", + "I seq=ca0e", "I seq=cb0f", "I seq=cc04", "I seq=cd07", "I seq=ce06", "I seq=cf05", + "I seq=d00f", + "I seq=810f", "I seq=840e", "I seq=850f", "I seq=8607", "I seq=8704", + "I seq=8805", "I seq=8906", "I seq=8a00", + "I seq=970f", + "I seq=9a0e", "I seq=9b0f", "I seq=9c07", "I seq=9d04", "I seq=9e05", "I seq=9f06", + "I seq=a000", + "I seq=ff30", "I seq=ff52", "I seq=ff02", + "I seq=0101", "I seq=02da", "I seq=03ba", "I seq=04a8", "I seq=059a", "I seq=0670", "I seq=07ff", + "I seq=0891", "I seq=0990", "I seq=0aff", "I seq=0b8f", "I seq=0c60", "I seq=0d58", "I seq=0e48", "I seq=0f38", + "I seq=102b", + "I seq=ff30", "I seq=ff52", "I seq=ff00", + "I seq=3602", + "I seq=3a70", + "I seq=11 wait=200", + "I seq=29 wait=10"; +}; + +&io_domains { + vccio1-supply = <&vccio_sd>; +}; + +/delete-node/ &pwm_led; + +&pwm0 { + status = "okay"; +}; + +/delete-node/ &pwm3; + +&rk817_charger { + /* This device does not have a current sense resistor */ + rockchip,resistor-sense-micro-ohms = <0>; + monitored-battery = <&battery>; +}; + +&sdio { + cap-sd-highspeed; + card-detect-delay = <200>; + cd-gpios = <&gpio3 RK_PB6 GPIO_ACTIVE_LOW>; /*[> CD GPIO <]*/ + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&vcc_sd { + regulator-max-microvolt = <3000000>; + regulator-min-microvolt = <1800000>; +}; + +&vccio_sd { + regulator-max-microvolt = <1800000>; +}; + +&pinctrl { + btns { + btn_pins_vol: btn-pins-vol { + rockchip,pins = <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + btn_pins: btn-pins { + rockchip,pins = <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; diff --git a/config/mipi-generator/archr-dtbo.py b/config/mipi-generator/archr-dtbo.py new file mode 100644 index 0000000000..0863e8d6dc --- /dev/null +++ b/config/mipi-generator/archr-dtbo.py @@ -0,0 +1,521 @@ +#!/usr/bin/env python + +# https://pypi.org/project/fdt/ +# pip install fdt + +import os, sys +import fdt +import math + + + +def prop_default(panel, prop, default): + try: + return panel.get_property(prop).value + except: + return default + +def absfrac(x): + return abs(x - round(x)) + +def panel_to_desc(panel, args): + if 'name' in args: + g_name = args['name'] + ' ' + else: + g_name = '' + comment = args.get('comment') + acc = [] + + delays = [ + prop_default(panel, "prepare-delay-ms", 50), + prop_default(panel, "reset-delay-ms", 50), + prop_default(panel, "init-delay-ms", 50), + prop_default(panel, "enable-delay-ms", 50), + 20 # ready -- no such timeout in legacy dtbs + ] + delays_str = ','.join(map(str, delays)) + + fmtprop = panel.get_property("dsi,format") + if fmtprop: + fmt = ['rgb888', 'rgb666', 'rgb666_packed', 'rgb565'] [fmtprop.value] + else: + fmt = 'rgb888' + lanes = panel.get_property("dsi,lanes").value + flags = panel.get_property("dsi,flags").value + flags |= 0x0400 + + + timings = panel.get_subnode("display-timings") + if 'Dno' in args['flags']: + # Skip original mode (it may be broken) + native = None + else: + native = timings.get_property("native-mode").value + + # Collect vendor modes + modes = {} + orig_def_fps = None + for m in timings.nodes: + clock = round(m.get_property("clock-frequency").value/1000) + hor = [ + m.get_property("hactive").value, + m.get_property("hfront-porch").value, + m.get_property("hsync-len").value, + m.get_property("hback-porch").value, + ] + ver = [ + m.get_property("vactive").value, + m.get_property("vfront-porch").value, + m.get_property("vsync-len").value, + m.get_property("vback-porch").value, + ] + + mode = {'clock': clock, 'hor': hor, 'ver': ver} + if (m.get_property("phandle").value == native): + mode['default'] = True + + htotal = sum(hor) + vtotal = sum(ver) + fps = clock*1000/(htotal*vtotal) + + if fps not in modes: + modes[fps] = mode + if (m.get_property("phandle").value == native): + modes[fps]['default'] = True + orig_def_fps = fps + + + try: + w = panel.get_property("width-mm").value + h = panel.get_property("height-mm").value + except: + if args.diagonal: + diag_mm = args.diagonal * 25.4 + else: + diag_mm = 3.5 * 2.54 + + randmode = list(modes.values())[0] + hactive = randmode['hor'][0] + vactive = randmode['ver'][0] + pxdiag = math.sqrt(hactive*hactive + vactive*vactive) + w = round(diag_mm * hactive/pxdiag) + h = round(diag_mm * vactive/pxdiag) + + # G size=52,70 delays=2,1,20,120,50,20 format=rgb888 lanes=4 flags=0xe03 + acc += [f"G {g_name}size={w},{h} delays={delays_str} format={fmt} lanes={lanes} flags=0x{flags:x}", ""] + + # Based on vendor modes construct a better set of modes + # https://tasvideos.org/PlatformFramerates + # 50, 60 -- generic + # */1.001 -- NTSC hack with 1001 divisor + # 50.0070 -- PAL NES https://www.nesdev.org/wiki/Cycle_reference_chart + # 60.0988 -- NTSC NES + # 54.8766 -- src/mame/toaplan/twincobr.cpp + # 57.5 -- src/mame/kaneko/snowbros.cpp + # 59.7275 -- https://en.wikipedia.org/wiki/Game_Boy + # 75.47 -- https://ws.nesdev.org/wiki/Display + def_fps = 60 + if orig_def_fps: + def_fps = orig_def_fps + common_fpss = [50/1.001, 50, 50.0070, 57.5, 59.7275, 60/1.001, 60, 60.0988, 75.47, 90, 120]; + common_fpss = [ fps for fps in common_fpss if fps != orig_def_fps] + for targetfps in [orig_def_fps] + common_fpss: + if not targetfps: + continue + warn = "" + # nearest fps to base on + greaterfps = [fps for fps in modes.keys() if fps >= targetfps] + if greaterfps == []: + basefps = max(modes.keys()) + basemode = modes[basefps] + clock = None + else: + # Trust original clock. If real clock differs, maybe make a whitelist or blacklist here + basefps = min(greaterfps) + basemode = modes[basefps] + clock = basemode['clock'] + hor = basemode['hor'].copy() + ver = basemode['ver'].copy() + # Assume original totals are minimal for the panel at this clock + htotal = sum(hor) + vtotal = sum(ver) + perfectclock = targetfps*htotal*vtotal/1000 + if not clock: + warn = "(CAN FAIL) " + # This may fail, but worth trying. Round up to 10kHz + clock = math.ceil(perfectclock/10)*10 + elif clock > 1.25*perfectclock: + # Too much deviation may cause no image + clock = math.ceil(perfectclock/10)*10 + + maxvtotal = round(vtotal*1.25) + # A little bruteforce to find a best totals for target fps + # TODO: maybe iterate over some clock values too + options = [(absfrac(c*1000/targetfps/vt), c, vt) + for vt in range(vtotal, maxvtotal+1) + for c in range(clock, round(1.25*perfectclock), 10) + if ((c*1000/targetfps/vt) >= htotal) and ((c*1000/targetfps/vt) < htotal*1.05) ] + if options == []: + acc += [f"# failed to find mode for fps={targetfps:.6f} c={clock} h={htotal} v={vtotal}"] + continue + (mindev, newclock, newvtotal) = min(options) + # construct a new mode with chosen vtotal + newhtotal = round(newclock*1000/targetfps/newvtotal) + addhtotal = newhtotal - htotal + addvtotal = newvtotal - vtotal + expectedfps = newclock*1000/newvtotal/newhtotal + hor[2] += addhtotal + ver[2] += addvtotal + hor_str = ','.join(map(str, hor)) + ver_str = ','.join(map(str, ver)) + maybe_default = " default=1" if targetfps == def_fps else "" + maybe_comment = f" # {warn}fps={expectedfps:.6f} (target={targetfps:.6f})" if comment else "" + acc += [f"M clock={newclock} horizontal={hor_str} vertical={ver_str}{maybe_default}{maybe_comment}"] + + acc += [""] + + iseq0 = panel.get_property("panel-init-sequence") + if (hasattr(iseq0, 'value')) and (isinstance(iseq0.value, (int))): + iseq = b''.join(map(lambda w : w.to_bytes(4, "big"), list(iseq0))) + else: + iseq = bytearray(iseq0) + + while iseq: + cmd = iseq[0] + wait = iseq[1] + datalen = iseq[2] + iseq = iseq[3:] + + data = iseq[0:datalen] + iseq = iseq[datalen:] + + maybe_wait = f" wait={wait}" if (wait) else "" + maybe_comment = f" # orig_cmd=0x{cmd:x}" if comment else "" + acc += [f"I seq={data.hex()}{maybe_wait}{maybe_comment}"] + + return acc + +def node_by_phandle(dt, phandle): + nodes = [p.parent + for p in dt.search('phandle', fdt.ItemType.PROP_WORDS) + if p.value == phandle] + return nodes[0] + +def resolve_phandle(dt, phandle): + p = node_by_phandle(dt, phandle) + return os.path.join(p.path, p.name) + +def add_overlay(overlay, path): + for f in range(100): + nodename = 'fragment@' + str(f) + if overlay.exist_node(nodename): + pass + else: + fragnode = fdt.Node(nodename) + if path[0] == '&': + fragnode.set_property('target', 0xffffffff) + overlay.set_property(path[1:], '/'+nodename+':target:0', path='/__fixups__') + else: + fragnode.set_property('target-path', path) + overlay.add_item(fragnode) + ovlnode = fdt.Node('__overlay__') + fragnode.append(ovlnode) + return ovlnode + +def add_fixup(overlay, label, fixup_path): + if overlay.exist_node('__fixups__'): + fixups = overlay.get_node('__fixups__') + else: + fixups = fdt.Node('__fixups__') + overlay.add_item(fixups) + prev_paths = fixups.get_property(label) + if prev_paths: + fixups.set_property(label, prev_paths.data + [fixup_path]) + else: + fixups.set_property(label, [fixup_path]) + +def add_local_fixup(overlay, parent_path, name): + overlay.set_property(name, 0, path='__local_fixups__'+parent_path) + +def add_gpio_vol_keys(dt, overlay, gpio_keys_ovl): + symbols = dt.get_node('__symbols__') + + keydata = dt.get_node('/play_joystick').get_property('key-gpios').data + pindata = dt.get_node('/pinctrl/buttons/gpio-key-pin').get_property('rockchip,pins').data + # extract volume keys from array + vol_up = keydata[14*3:15*3] + vol_up_pin = pindata[14*4:15*4] + vol_dn = keydata[15*3:16*3] + vol_dn_pin = pindata[15*4:16*4] + + gpio_path = resolve_phandle(dt, vol_up[0]) + gpio_sym = [p.name for p in symbols.props if p.value == gpio_path][0] + gpio_phandle = 0xffffffff + + pins_path = gpio_keys_ovl.path+'/__overlay__/pinctrl/btns/btn-pins-vol-overlay' + keys_path = gpio_keys_ovl.path+'/__overlay__/gpio-keys-overlay' + + pullup = 0xffffffff + overlay.set_property('rockchip,pins', vol_up_pin[0:3] + [pullup] + vol_dn_pin[0:3] + [pullup], path=pins_path) + pins_phandle = overlay.add_label('overlay_btns') + overlay.set_property('phandle', pins_phandle, path=pins_path) + add_fixup(overlay, 'pcfg_pull_up', pins_path+':rockchip,pins:12') + add_fixup(overlay, 'pcfg_pull_up', pins_path+':rockchip,pins:28') + + overlay.set_property('compatible', 'gpio-keys', path=keys_path) + overlay.set_property('autorepeat', None, path=keys_path) + overlay.set_property('pinctrl-0', pins_phandle, path=keys_path) + add_local_fixup(overlay, keys_path, 'pinctrl-0') + overlay.set_property('pinctrl-names', 'default', path=keys_path) + + overlay.set_property('gpios', [gpio_phandle, vol_up[1], vol_up[2]], path=keys_path+'/button-vol-up') + overlay.set_property('label', "VOLUMEUP", path=keys_path+'/button-vol-up') + overlay.set_property('linux,code', 0x73, path=keys_path+'/button-vol-up') + add_fixup(overlay, gpio_sym, keys_path+'/button-vol-up:gpios:0') + + overlay.set_property('gpios', [gpio_phandle, vol_dn[1], vol_dn[2]], path=keys_path+'/button-vol-down') + overlay.set_property('label', "VOLUMEDOWN", path=keys_path+'/button-vol-down') + overlay.set_property('linux,code', 0x72, path=keys_path+'/button-vol-down') + add_fixup(overlay, gpio_sym, keys_path+'/button-vol-down:gpios:0') + + +def switch_joypad_to_mymini(overlay, jp_ovl): + # My mini has separate ADC channels for axis, so we need another driver + jp_ovl.set_property('compatible', "rocknix-joypad") + jp_ovl.set_property('io-channel-names', ["key-RY", "key-RX", "key-LY", "key-LX"]) + jp_ovl.set_property('io-channels', [0xffffffff, 3, 0xffffffff, 3, 0xffffffff, 2, 0xffffffff, 1]) + add_fixup(overlay, 'saradc', jp_ovl.path+'/__overlay__:io-channels:0') + add_fixup(overlay, 'saradc', jp_ovl.path+'/__overlay__:io-channels:8') + add_fixup(overlay, 'saradc', jp_ovl.path+'/__overlay__:io-channels:16') + add_fixup(overlay, 'saradc', jp_ovl.path+'/__overlay__:io-channels:24') + jp_ovl.set_property('button-adc-scale', 2) + jp_ovl.set_property('button-adc-deadzone', 216) + jp_ovl.set_property('button-adc-fuzz', 54) + jp_ovl.set_property('button-adc-flat', 54) + jp_ovl.set_property('abs_x-p-tuning', 180) + jp_ovl.set_property('abs_x-n-tuning', 180) + jp_ovl.set_property('abs_y-p-tuning', 180) + jp_ovl.set_property('abs_y-n-tuning', 180) + jp_ovl.set_property('abs_rx-p-tuning', 0) + jp_ovl.set_property('abs_rx-n-tuning', 0) + jp_ovl.set_property('abs_ry-p-tuning', 0) + jp_ovl.set_property('abs_ry-n-tuning', 0) + jp_ovl.set_property('poll-interval', 10) + + +def make_dtbo(dtb_data, args): + dt = fdt.parse_dtb(dtb_data) + symbols = dt.get_node('__symbols__') + + dsipath = symbols.get_property('dsi').value + # panelpath is /dsi@ff450000/panel@0 on rk3326 and /dsi@fe060000/panel@0 on rk3566 + panelpath = dsipath + '/panel@0' + panel = dt.get_node(panelpath) + pdesc = panel_to_desc(panel, args) + + # remove empty lines as pyfdt does not like them + pdesc = [ l for l in pdesc if l != ''] + + panel_rst_gpio = panel.get_property('reset-gpios').data + gpio_sym = [p.name for p in symbols.props if p.value == resolve_phandle(dt, panel_rst_gpio[0])][0] + gpio_num = int(gpio_sym[4:]) + + # create an overlay tree + overlay = fdt.FDT() + overlay.header.version = 17 + + panel_ovl = add_overlay(overlay, '/') + panel_ovl_path = panel_ovl.path+'/__overlay__'+panelpath + overlay.set_property('compatible', 'archr,generic-dsi', path=panel_ovl_path) + overlay.set_property('panel_description', pdesc, path=panel_ovl_path) + if 'DR90' in args['flags']: + overlay.set_property('rotation', 90, path=panel_ovl_path) + elif 'DR180' in args['flags']: + overlay.set_property('rotation', 180, path=panel_ovl_path) + elif 'DR270' in args['flags']: + overlay.set_property('rotation', 270, path=panel_ovl_path) + + compat = dt.get_node('/').get_property('compatible').data[0] + args['logger'].info(f"compatible {compat}") + if 'odroidgo3' in compat: + # quick return for well supported R36s + return overlay.to_dtb() + + # copy reset config + pins_path = panel_ovl.path+'/__overlay__/pinctrl/gpio-lcd/lcd-rst' + overlay.set_property('reset-gpios', [0xffffffff, panel_rst_gpio[1], panel_rst_gpio[2]], path=panel_ovl_path) + add_fixup(overlay, gpio_sym, panel_ovl_path+':reset-gpios:0') + overlay.set_property('rockchip,pins', [gpio_num, panel_rst_gpio[1], 0, 0xffffffff], path=pins_path) + add_fixup(overlay, 'pcfg_pull_none', pins_path+':rockchip,pins:12') + # power supply gpio fetch (some trees do not have power-supply prop) + try: + panel_ps = dt.get_node(resolve_phandle(dt, panel.get_property('power-supply').value)) + panel_ps_gpio = panel_ps.get_property('gpio').data + gpio_sym = [p.name for p in symbols.props if p.value == resolve_phandle(dt, panel_ps_gpio[0])][0] + gpio_num = int(gpio_sym[4:]) + # power supply reg + panel_reg_path = panel_ovl.path+'/__overlay__/vcc18-lcd0' + overlay.set_property('gpio', [0xffffffff, panel_ps_gpio[1], panel_ps_gpio[2]], path=panel_reg_path) + add_fixup(overlay, gpio_sym, panel_reg_path+':gpio:0') + # power supply pinctrl + panel_ps_pin_path = panel_ovl.path+'/__overlay__/pinctrl/vcc18-lcd/vcc18-lcd-n' + overlay.set_property('rockchip,pins', [gpio_num, panel_ps_gpio[1], 0, 0xffffffff], path=panel_ps_pin_path) + add_fixup(overlay, 'pcfg_pull_none', panel_ps_pin_path+':rockchip,pins:12') + except: + pass + # some devices (e.g. R36s clone) have enable-gpios defined + try: + panel_en_gpio = panel.get_property('enable-gpios').data + gpio_sym = [p.name for p in symbols.props if p.value == resolve_phandle(dt, panel_en_gpio[0])][0] + overlay.set_property('enable-gpios', [0xffffffff, panel_en_gpio[1], panel_en_gpio[2]], path=panel_ovl_path) + add_fixup(overlay, gpio_sym, panel_ovl_path+':enable-gpios:0') + except: + pass + + + # If stock DTB does not have ADC keys, disable adc-keys in overlay + need_adckeys_disable = False + if not dt.exist_node('/adc-keys'): + need_adckeys_disable = True + else: + adckeys_orig = dt.get_node('/adc-keys') + adckeys_status = adckeys_orig.get_property('status') + if (adckeys_status) and (adckeys_status.value == 'disabled'): + need_adckeys_disable = True + else: + # usually we just don't have status property, so consider this valid + need_adckeys_disable = False + if need_adckeys_disable: + noadck_ovl = add_overlay(overlay, '/') + overlay.set_property('dtbo_comment', 'deliberately-disabled-adc-keys', path=noadck_ovl.path+'/__overlay__/adc-keys') + overlay.set_property('status', 'disabled', path=noadck_ovl.path+'/__overlay__/adc-keys') + args['logger'].info(f"disabled adc-keys") + # TODO: extract GPIO keys from play_joystick.key-gpios[14..15] + if dt.exist_node('/play_joystick'): + add_gpio_vol_keys(dt, overlay, noadck_ovl) + else: + adck_ovl = add_overlay(overlay, '/') + overlay.set_property('status', 'okay', path=adck_ovl.path+'/__overlay__/adc-keys') + + + # joypad overlay always present to simplify different options + jp_ovl = add_overlay(overlay, '&joypad') + + # If not explicitly specified, disabled adc-keys imply multi-adc MyMini-style joypad + if 'JPk36' in args['flags']: + pass + elif ('JPmm' in args['flags']) or (need_adckeys_disable): + args['logger'].info(f"My Mini joypad tweaks on {jp_ovl.path}") + switch_joypad_to_mymini(overlay, jp_ovl) + + # Left stick was inverted by default, so invert inversion here + if ('LSi' not in args['flags']) ^ (need_adckeys_disable): + jp_ovl.set_property('invert-absx', 1) + jp_ovl.set_property('invert-absy', 1) + args['logger'].info(f"left stick un-inverted on {jp_ovl.path}") + else: + args['logger'].info(f"left stick left inverted") + + # If needed, invert right stick + if 'RSi' in args['flags']: + jp_ovl.set_property('invert-absrx', 1) + jp_ovl.set_property('invert-absry', 1) + args['logger'].info(f"invert right stick on {jp_ovl.path}") + + + try: + snd = dt.get_node('/rk817-sound') + + # fetch raw hp-det-gpio = <0x6f 0x16 0x00>; + hpdet = snd.get_property('hp-det-gpio').data + hp_det = dt.get_node('/pinctrl/headphone/hp-det') + hp_det_pins = hp_det.get_property('rockchip,pins') + hp_det_pull_node = node_by_phandle(dt, hp_det_pins[3]) + # resolve <0x6f> into '/pinctrl/gpio2@ff260000' + hpdet_gpio_path = resolve_phandle(dt, hpdet[0]) + # find symbol 'gpio2' for path '/pinctrl/gpio2@ff260000' + gpiosyms = [p.name for p in symbols.props if p.value == hpdet_gpio_path] + gpio_sym = gpiosyms[0] + + # on success, add overlay + hpdet_ovl = add_overlay(overlay, '/') + + force_simple_audio_routing = ('SRs' in args['flags']) + + # Determine preset, configure amplifier if needed + if snd.exist_property('spk-con-gpio') and not force_simple_audio_routing: + rk817_path = hpdet_ovl.path+'/__overlay__/rk817-sound-amplified' + amp_gpio = snd.get_property('spk-con-gpio').data + amp_gpio_sym = [p.name for p in symbols.props if p.value == resolve_phandle(dt, amp_gpio[0])][0] + gpio_num = int(amp_gpio_sym[4:]) + args['logger'].info(f"spk-con-gpio {amp_gpio_sym} {amp_gpio[1]} on {hpdet_ovl.path}") + + amp_path = hpdet_ovl.path+'/__overlay__/audio-amplifier' + overlay.set_property('enable-gpios', [0xffffffff, amp_gpio[1], amp_gpio[2]], path=amp_path) + add_fixup(overlay, amp_gpio_sym, amp_path+':enable-gpios:0') + + amp_pc_path = hpdet_ovl.path+'/__overlay__/pinctrl/speaker/spk-amp-enable-h' + overlay.set_property('rockchip,pins', [gpio_num, amp_gpio[1], 0, 0xffffffff], path=amp_pc_path) + add_fixup(overlay, 'pcfg_pull_none', amp_pc_path+':rockchip,pins:12') + else: + rk817_path = hpdet_ovl.path+'/__overlay__/rk817-sound-simple' + + overlay.set_property('status', 'okay', path=rk817_path) + # for some reason hp detection polarity needs to be inverted on some devices + if 'HPi' in args['flags']: + if hpdet[2] == 0: + hpdet[2] = 1 + else: + hpdet[2] = 0 + overlay.set_property('simple-audio-card,hp-det-gpio', [0xffffffff, hpdet[1], hpdet[2]], path=rk817_path) + add_fixup(overlay, gpio_sym, rk817_path+':simple-audio-card,hp-det-gpio:0') + pins_path = hpdet_ovl.path+'/__overlay__/pinctrl/headphone/hp-det' + overlay.set_property('rockchip,pins', hp_det_pins[0:3] + [0xffffffff], path=pins_path) + # Restore bias reference + if hp_det_pull_node.exist_property('bias-pull-down'): + add_fixup(overlay, 'pcfg_pull_down', pins_path+':rockchip,pins:12') + else: + add_fixup(overlay, 'pcfg_pull_up', pins_path+':rockchip,pins:12') + args['logger'].info(f"hp-det-gpio {gpiosyms[0]} on {hpdet_ovl.path}") + + except Exception as e: + args['logger'].info(e) + + # Move fixups to the very end (if any) + if overlay.exist_node('__fixups__'): + fixups = overlay.get_node('__fixups__') + overlay.remove_node('__fixups__') + overlay.add_item(fixups) + + if overlay.exist_node('__local_fixups__'): + fixups = overlay.get_node('__local_fixups__') + overlay.remove_node('__local_fixups__') + overlay.add_item(fixups) + + # send the overlay to output + return overlay.to_dtb() + + +if __name__ == "__main__": + import argparse, logging + logging.basicConfig(level=logging.INFO) + logger = logging.getLogger("dtbo") + + parser = argparse.ArgumentParser(description="Generate a dtbo from a stock dtb") + parser.add_argument(dest="src", help="input stock dtb path", metavar="/path/to/stock.dtb") + parser.add_argument(dest="opts", help="dtbo options", nargs='?', metavar="LSi-HPi", default="") + parser.add_argument("-o", "--output", help="output (dtbo) path") + args = parser.parse_args() + + with open(args.src, 'rb') as f: + content = f.read() + + flags = args.opts.split('-') + flags = [ f for f in flags if f != ''] + dtbo = make_dtbo(content, {'flags': flags, 'logger': logger}) + + if args.output: + with open(args.output, 'wb') as f: + f.write(dtbo) + else: + sys.stdout.buffer.write(dtbo) diff --git a/config/mipi-generator/generator.sh b/config/mipi-generator/generator.sh new file mode 100644 index 0000000000..cdd4160693 --- /dev/null +++ b/config/mipi-generator/generator.sh @@ -0,0 +1,187 @@ +#!/bin/bash + +#============================================================================== +# Arch R - Generate Panel DTBO Overlays +#============================================================================== +# Generates DTBO overlay files for ALL panel variants using archr-dtbo.py +# +# Sources: +# - R36S originals: DTS in config/archr-dts/R36S-DTB/DTS/ +# - R36S clones: DTBs in config/archr-dts/R36S-Clones-DTB/ +# +# Output: +# - output/panels/original/ -> overlays for original R36S image +# - output/panels/clone/ -> overlays for clone R36S image +#============================================================================== + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ROOT_DIR="$(dirname "$(dirname "$SCRIPT_DIR")")" +DTS_DIR="${ROOT_DIR}/config/archr-dts/R36S-DTB/DTS" +CLONES_DIR="${ROOT_DIR}/config/archr-dts/R36S-Clones-DTB" +OUTPUT_ORIG="${ROOT_DIR}/config/mipi-generator/output/original" +OUTPUT_CLONE="${ROOT_DIR}/config/mipi-generator/output/clone" +DTBO_TOOL="$SCRIPT_DIR/archr-dtbo.py" + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' +log() { echo -e "${GREEN}[PANEL]${NC} $1"; } +warn() { echo -e "${YELLOW}[PANEL] WARNING:${NC} $1"; } +error() { echo -e "${RED}[PANEL] ERROR:${NC} $1"; exit 1; } + +# Check prerequisites +command -v dtc &>/dev/null || error "dtc not found" +command -v python3 &>/dev/null || error "python3 not found" +python3 -c "import fdt" 2>/dev/null || error "Python fdt package not found. Install with: pip3 install fdt" +[ -f "$DTBO_TOOL" ] || error "archr-dtbo.py not found at: $DTBO_TOOL" + +mkdir -p "$OUTPUT_ORIG" "$OUTPUT_CLONE" +TMPDIR=$(mktemp -d) +trap "rm -rf $TMPDIR" EXIT + +GENERATED=0 +FAILED=0 + +#------------------------------------------------------------------------------ +# Helper: generate overlay from DTS file (compile DTS->DTB, then run dtbo.py) +#------------------------------------------------------------------------------ +generate_from_dts() { + local dts_file="$1" + local out_file="$2" + local flags="$3" + local label="$4" + + if [ ! -f "$dts_file" ]; then + warn " DTS not found: $dts_file" + FAILED=$((FAILED + 1)) + return 1 + fi + + local tmp_dtb="$TMPDIR/$(basename "${dts_file%.dts}").dtb" + if ! dtc -I dts -O dtb -@ "$dts_file" -o "$tmp_dtb" 2>/dev/null; then + warn " Failed to compile DTS: $(basename "$dts_file")" + FAILED=$((FAILED + 1)) + return 1 + fi + + if python3 "$DTBO_TOOL" "$tmp_dtb" $flags -o "$out_file" 2>/dev/null; then + local sz=$(stat -c%s "$out_file") + log " OK: $(basename "$out_file") (${sz} bytes) [$label]" + GENERATED=$((GENERATED + 1)) + else + warn " archr-dtbo.py failed: $(basename "$out_file")" + FAILED=$((FAILED + 1)) + return 1 + fi +} + +#------------------------------------------------------------------------------ +# Helper: generate overlay from pre-compiled DTB +#------------------------------------------------------------------------------ +generate_from_dtb() { + local dtb_file="$1" + local out_file="$2" + local flags="$3" + local label="$4" + + if [ ! -f "$dtb_file" ]; then + warn " DTB not found: $dtb_file" + FAILED=$((FAILED + 1)) + return 1 + fi + + if python3 "$DTBO_TOOL" "$dtb_file" $flags -o "$out_file" 2>/dev/null; then + local sz=$(stat -c%s "$out_file") + log " OK: $(basename "$out_file") (${sz} bytes) [$label]" + GENERATED=$((GENERATED + 1)) + else + warn " archr-dtbo.py failed: $(basename "$out_file")" + FAILED=$((FAILED + 1)) + return 1 + fi +} + +#------------------------------------------------------------------------------ +# Original R36S panels (DTS files) +#------------------------------------------------------------------------------ +log "=== Original R36S Panel Overlays ===" +log "Source: $DTS_DIR" +log "Output: $OUTPUT_ORIG" +log "" + +# Panel index -> DTS filename +declare -A ORIG_PANELS=( + [panel0]="Panel0.dts" + [panel1]="Panel1.dts" + [panel2]="Panel2.dts" + [panel3]="Panel3.dts" + [panel4]="Panel4.dts" + [panel4-v22]="Panel4-V22.dts" + [panel5]="Panel5.dts" + [r35s-rumble]="R35S-Rumble.dts" + [r36s-plus]="R36S-Plus.dts" + [r46h]="R46H.dts" + [rgb20s]="RGB20S.dts" +) + +ORIG_ORDER=(panel0 panel1 panel2 panel3 panel4 panel4-v22 panel5 r35s-rumble r36s-plus r46h rgb20s) + +for key in "${ORIG_ORDER[@]}"; do + dts="${ORIG_PANELS[$key]}" + log "Original ${key}: ${dts}" + generate_from_dts "$DTS_DIR/$dts" "$OUTPUT_ORIG/${key}.dtbo" "" "$key" +done + +#------------------------------------------------------------------------------ +# Clone R36S panels (pre-compiled DTBs) +#------------------------------------------------------------------------------ +log "" +log "=== Clone R36S Panel Overlays ===" +log "Source: $CLONES_DIR" +log "Output: $OUTPUT_CLONE" +log "" + +declare -A CLONE_PANELS=( + [clone_panel_1]="Panel 1/rf3536k4ka.dtb" + [clone_panel_2]="Panel 2/rf3536k4ka.dtb" + [clone_panel_3]="Panel 3/rf3536k4ka.dtb" + [clone_panel_4]="Panel 4/rf3536k4ka.dtb" + [clone_panel_5]="Panel 5/rf3536k4ka.dtb" + [clone_panel_6]="Panel 6/rf3536k4ka.dtb" + [clone_panel_7]="Panel 7/rf3536k4ka.dtb" + [clone_panel_8]="Panel 8/rf3536k4ka.dtb" + [clone_panel_9]="Panel 9/rf3536k4ka.dtb" + [clone_panel_10]="Panel 10/rf3536k3ka.dtb" + [r36_max]="R36 Max/rf3536k4ka.dtb" + [rx6s]="RX6S/rf351g3ka.dtb" +) + +CLONE_ORDER=(clone_panel_1 clone_panel_2 clone_panel_3 clone_panel_4 clone_panel_5 + clone_panel_6 clone_panel_7 clone_panel_8 clone_panel_9 clone_panel_10 + r36_max rx6s) + +for key in "${CLONE_ORDER[@]}"; do + dtb="${CLONE_PANELS[$key]}" + log "Clone ${key}: ${dtb}" + generate_from_dtb "$CLONES_DIR/$dtb" "$OUTPUT_CLONE/${key}.dtbo" "" "$key" +done + +#------------------------------------------------------------------------------ +# Summary +#------------------------------------------------------------------------------ +log "" +log "=== Panel Generation Complete ===" +log "Generated: ${GENERATED} Failed: ${FAILED}" +log "" +log "Original overlays: $OUTPUT_ORIG/" +ls -1 "$OUTPUT_ORIG"/*.dtbo 2>/dev/null | while read f; do + log " $(basename "$f") ($(stat -c%s "$f") bytes)" +done +log "" +log "Clone overlays: $OUTPUT_CLONE/" +ls -1 "$OUTPUT_CLONE"/*.dtbo 2>/dev/null | while read f; do + log " $(basename "$f") ($(stat -c%s "$f") bytes)" +done diff --git a/config/optimize b/config/optimize index 91ce8283d4..0709178d9f 100644 --- a/config/optimize +++ b/config/optimize @@ -9,7 +9,7 @@ TARGET_LIBDIR="$SYSROOT_PREFIX/lib $SYSROOT_PREFIX/usr/lib" TARGET_INCDIR="$SYSROOT_PREFIX/include $SYSROOT_PREFIX/usr/include" HOST_CPPFLAGS="" -HOST_CFLAGS="-march=x86-64 -mtune=generic -O2 -Wall -pipe -I$TOOLCHAIN/include" +HOST_CFLAGS="-march=x86-64 -mtune=generic -O2 -Wall -pipe -std=gnu17 -I$TOOLCHAIN/include" HOST_CXXFLAGS="$HOST_CFLAGS" HOST_LDFLAGS="-Wl,-rpath,$TOOLCHAIN/lib -L$TOOLCHAIN/lib" HOST_INCDIR="$TOOLCHAIN/include /usr/include" diff --git a/config/options b/config/options index 60628772bb..a5b5cd5088 100644 --- a/config/options +++ b/config/options @@ -21,13 +21,13 @@ DISTRO_DIR="${ROOT}/distributions" PROJECT_DIR="${ROOT}/projects" # determines DISTRO, if not forced by user -DISTRO="${DISTRO:-ROCKNIX}" +DISTRO="${DISTRO:-ArchR}" # determines PROJECT, if not forced by user -export PROJECT="${PROJECT:-ROCKNIX}" +export PROJECT="${PROJECT:-ArchR}" # default to Generic device if building Generic project without device set -if [ "${PROJECT}" = "ROCKNIX" -a -z "${DEVICE}" ]; then +if [ "${PROJECT}" = "ArchR" -a -z "${DEVICE}" ]; then export DEVICE="SM8250" fi @@ -127,13 +127,13 @@ if [ -z "$ADDON_URL" ]; then fi # read local persistent options from $ROOT if available -if [ -f "${ROOT}/.rocknix/options" ]; then - . "${ROOT}/.rocknix/options" +if [ -f "${ROOT}/.archr/options" ]; then + . "${ROOT}/.archr/options" fi # read global persistent options from $HOME if available -if [ -f "${HOME}/.rocknix/options" ]; then - . "${HOME}/.rocknix/options" +if [ -f "${HOME}/.archr/options" ]; then + . "${HOME}/.archr/options" fi if [ "${LOCAL_CCACHE_SUPPORT}" = "yes" ] && [ -z "${CCACHE_DISABLE}" ]; then diff --git a/config/path b/config/path index ce559a68fe..691c8f6f94 100644 --- a/config/path +++ b/config/path @@ -14,7 +14,7 @@ set -e ADDONS=addons [ -z "${HOST_NAME}" ] && export HOST_NAME="$($LOCAL_CC -dumpmachine)" -TARGET_NAME=$TARGET_GCC_ARCH-rocknix-linux-gnu${TARGET_ABI} +TARGET_NAME=$TARGET_GCC_ARCH-${OSNAME}-linux-gnu${TARGET_ABI} BUILD=${BUILD_ROOT}/${BUILD_BASE}.${DISTRONAME}-${DEVICE:-$PROJECT}.${TARGET_ARCH} diff --git a/config/show_config b/config/show_config index 39855cbdf6..2f87747d15 100644 --- a/config/show_config +++ b/config/show_config @@ -68,12 +68,9 @@ show_config() { config_message+="\n\n Image Filesystems:" config_message+="\n ${dashes}${dashes}" - config_message+="\n - Flash Size (MiB): \t\t\t ${SYSTEM_SIZE}" + config_message+="\n - Root Size (MiB): \t\t\t ${ROOT_SIZE}" config_message+="\n - Storage Size (MiB): \t\t\t ${STORAGE_SIZE}" - config_message+="\n - SquashFS Compression Method: \t ${SQUASHFS_COMPRESSION}" - if [ -n "${SQUASHFS_COMPRESSION_OPTION}" ]; then - config_message+="\n - SquashFS Compression Options: \t ${SQUASHFS_COMPRESSION_OPTION}" - fi + config_message+="\n - Root Filesystem: \t\t\t ext4" # Misc. Filesystems diff --git a/distributions/ArchR/config/functions b/distributions/ArchR/config/functions new file mode 100644 index 0000000000..31c5f94bbe --- /dev/null +++ b/distributions/ArchR/config/functions @@ -0,0 +1,339 @@ +### Generate System Documentation + +clean_doc_cache() { + DOCTMP="${ROOT}/.doc_cache/${DEVICE}" + if [ -d "${DOCTMP}" ] + then + rm -rf "${DOCTMP}" + fi +} + +start_system_doc() { + if [ -z "${SYSDOC}" ] + then + echo "Unable to generate documentation, define SYSDOC in options." + exit 1 + fi + if [ ! -d "${SYSDOCROOT}" ] + then + mkdir ${SYSDOCROOT} + fi + if [ -e "${SYSDOC}.md" ] + then + rm -f ${SYSDOC}.md + fi + if [ -e "${ROOT}/templates/HEADER.md" ] + then + cat ${ROOT}/templates/HEADER.md >${SYSDOC}.md + fi + DOCTEMPLATE="$(basename ${SYSDOC})" + if [ -e "${ROOT}/templates/${DOCTEMPLATE}.md" ] + then + cat ${ROOT}/templates/${DOCTEMPLATE}.md >>${SYSDOC}.md + fi + cat <>${SYSDOC}.md +|Manufacturer|System|Release Date|Games Path|Supported Extensions|Emulator / Core| +|----|----|----|----|----|----| +EOF +} + +add_system_doc() { + echo -n "|${SYSTEM_MANUFACTURER}|${SYSTEM_FULLNAME} (${SYSTEM_NAME})|${SYSTEM_RELEASE}|\`$(basename ${SYSTEM_PATH})\`|${SYSTEM_EXTENSION}|" >>${DOCTMP}/${1}:system.tmp +} + +add_emu_doc() { + if [ ! -d "${DOCTMP}" ] + then + mkdir -p "${DOCTMP}" + fi + if [ "${4}" = "true" ] + then + DEFAULT=" (default)" + else + unset DEFAULT + fi + echo -n "**${2}:** ${3}${DEFAULT}
" >>${DOCTMP}/${1}:emulators.tmp +} + +mk_system_doc() { + for system in $(ls ${DOCTMP}/ | awk 'BEGIN {FS=":"} {print $1}' | sort | uniq) + do + cat ${DOCTMP}/${system}:system.tmp >>${SYSDOC}.tmp + if [ -e "${DOCTMP}/${system}:emulators.tmp" ] + then + cat ${DOCTMP}/${system}:emulators.tmp >>${SYSDOC}.tmp + fi + echo "|" >>${SYSDOC}.tmp + done + cat ${SYSDOC}.tmp | sort -f >>${SYSDOC}.md + rm -f ${SYSDOC}.tmp +} + +### Generate ES Systems + +clean_es_cache() { + ESTMP="${ROOT}/.es_cache/${DEVICE}" + if [ -d "${ESTMP}" ] + then + rm -rf "${ESTMP}" + fi +} + +add_emu_core() { + if [ ! -d "${ESTMP}" ] + then + mkdir -p "${ESTMP}" + fi + + # Schema: emulator|core|true/false + echo "${2}|${3}|${4}" >>${ESTMP}/${1}-emulators.tmp + add_emu_doc $* +} + +mk_es_systems() { + + cat <${ESTMP}/.es_systems.cfg + + +EOF + rm -f ${ESTMP}/*-emulators.tmp + for essystem in $(ls ${ESTMP}/*.tmp | sort) + do + cat ${essystem} >>${ESTMP}/.es_systems.cfg + done + cat <>${ESTMP}/.es_systems.cfg + +EOF +xmlstarlet fo -t ${ESTMP}/.es_systems.cfg >${ESTMP}/es_systems.cfg 2>/dev/null + +} + +add_system_dir() { + if [ ! -d "${ESTMP}" ] + then + mkdir -p "${ESTMP}" + fi + cat <>${ESTMP}/system-dirs.conf +d ${1} 0777 root root - - +EOF +} + +add_es_system() { + RUNCMD='/usr/bin/runemu.sh %ROM% -P%SYSTEM% --core=%CORE% --emulator=%EMULATOR% --controllers="%CONTROLLERSCONFIG%"' + if [ -e "${ROOT}/config/emulators/${1}.conf" ] + then + . ${ROOT}/config/emulators/${1}.conf + fi + + if [ ! -d "${ESTMP}" ] + then + mkdir -p "${ESTMP}" + fi + if [[ -z "${SYSTEM_COMMAND}" ]]; + then + SYSTEM_COMMAND=$RUNCMD + fi + if [ ! -e "${ESTMP}/${SYSTEM_NAME}.tmp" ] + then + cat <${ESTMP}/${SYSTEM_NAME}.tmp + + ${SYSTEM_NAME} + ${SYSTEM_FULLNAME} + ${SYSTEM_MANUFACTURER} + ${SYSTEM_RELEASE} + ${SYSTEM_HARDWARE} + ${SYSTEM_PATH} + ${SYSTEM_EXTENSION} + ${SYSTEM_COMMAND} + ${SYSTEM_PLATFORM} + ${SYSTEM_THEME} + +EOF + fi + + add_system_dir "${SYSTEM_PATH}" + + if [ -e "${ESTMP}/${SYSTEM_NAME}-emulators.tmp" ] + then + while read -r line + do + SYSTEM_EMULATOR=$(echo ${line} | awk 'BEGIN {FS="|"} {print $1}') + SYSTEM_CORE=$(echo ${line} | awk 'BEGIN {FS="|"} {print $2}') + SYSTEM_DEFAULT=$(echo ${line} | awk 'BEGIN {FS="|"} {print $3}') + + ### Check to see if we've already added an emulator key. + EMTEST=$(xmlstarlet sel -t -c "//system/emulators" ${ESTMP}/${SYSTEM_NAME}.tmp 2>/dev/null ||:) + if [ -z "${EMTEST}" ] + then + ### Add the emulator element + xmlstarlet ed --omit-decl --inplace \ + -s "//system" -t elem -n "emulators" -v "" \ + ${ESTMP}/${SYSTEM_NAME}.tmp 2>&1 >/dev/null + fi + + ### Check to see if we've already added an emulator key. + EETEST=$(xmlstarlet sel -t -c "//system/emulators/emulator[@name=\"${SYSTEM_EMULATOR}\"]" ${ESTMP}/${SYSTEM_NAME}.tmp 2>/dev/null ||:) + if [ -z "${EETEST}" ] + then + ### Add the emulator element + xmlstarlet ed --omit-decl --inplace \ + -s "//system/emulators" -t elem -n "emulator" -v "" \ + ${ESTMP}/${SYSTEM_NAME}.tmp 2>&1 >/dev/null + fi + + ### Add an attribute defining the emulator's name. + xmlstarlet ed --omit-decl --inplace \ + -s "//system/emulators/emulator[not(@name)]" -t attr -n "name" -v "${SYSTEM_EMULATOR}" \ + ${ESTMP}/${SYSTEM_NAME}.tmp 2>&1 >/dev/null + + ### Check to see if we've already added a core element. + COTEST=$(xmlstarlet sel -t -c "//system/emulators/emulator[@name=\"${SYSTEM_EMULATOR}\"]/cores/core" ${ESTMP}/${SYSTEM_NAME}.tmp 2>/dev/null ||:) + if [ -z "${COTEST}" ] + then + xmlstarlet ed --omit-decl --inplace \ + -s "//system/emulators/emulator[@name=\"${SYSTEM_EMULATOR}\"]" -t elem -n "cores" -v "" \ + ${ESTMP}/${SYSTEM_NAME}.tmp 2>&1 >/dev/null + fi + + ### Add each core. + xmlstarlet ed --omit-decl --inplace \ + -s "//system/emulators/emulator[@name=\"${SYSTEM_EMULATOR}\"]/cores" -t elem -n "core" -v "${SYSTEM_CORE}" \ + ${ESTMP}/${SYSTEM_NAME}.tmp 2>&1 >/dev/null + + if [ "${SYSTEM_DEFAULT}" = "true" ] + then + ### Add an attribute defining the default core + xmlstarlet ed --omit-decl --inplace \ + -i "//system/emulators/emulator[@name=\"${SYSTEM_EMULATOR}\"]/cores/core" -t attr -n "default" -v "true" \ + ${ESTMP}/${SYSTEM_NAME}.tmp 2>&1 >/dev/null + fi + done <${ESTMP}/${SYSTEM_NAME}-emulators.tmp + fi + add_system_doc ${SYSTEM_NAME} +} + +# config.xml parsing +CONFIGXML="${PROJECT_DIR}/${PROJECT}/config.xml" + +SUBDEVICES=$(xmlstarlet sel -t -m "//archr/${DEVICE}/*[@mkimage_options]" -v "name()" -n "${CONFIGXML}" 2>/dev/null | tr '\n' ' ') + +get_kernel_make_extracmd() { + local DTB_PREFIX + DTB_PREFIX=$(xmlstarlet sel -t -v "//archr/${DEVICE}/@dtb_prefix" "${CONFIGXML}" 2>/dev/null) + DTB_PREFIX="${DTB_PREFIX}/" + xmlstarlet sel -t -m "//archr/${DEVICE}//file" -o "${DTB_PREFIX}" -v "." -o ".dtb " "${CONFIGXML}" 2>/dev/null +} + +get_fdt() { + local FDT_FILENAME="" + + if [[ -n "${SUBDEVICE}" ]]; then + FDT_FILENAME=$(xmlstarlet sel -t -v "//archr/${DEVICE}/${SUBDEVICE}/@fdt" "${CONFIGXML}" 2>/dev/null || true) + fi + + if [[ -z "${FDT_FILENAME}" ]]; then + FDT_FILENAME=$(xmlstarlet sel -t -v "//archr/${DEVICE}/@fdt" "${CONFIGXML}" 2>/dev/null || true) + fi + + [ -n "${FDT_FILENAME}" ] && echo "${FDT_FILENAME}" || true +} + +get_fdt_type() { + local FDT_TYPE="" + + if [[ -n "${SUBDEVICE}" ]]; then + FDT_TYPE=$(xmlstarlet sel -t -v "//archr/${DEVICE}/${SUBDEVICE}/@fdt_type" "${CONFIGXML}" 2>/dev/null) + fi + + if [[ -z "${FDT_TYPE}" ]]; then + FDT_TYPE=$(xmlstarlet sel -t -v "//archr/${DEVICE}/@fdt_type" "${CONFIGXML}" 2>/dev/null) + fi + + if [[ "${FDT_TYPE}" == "fdtdir" ]]; then + echo "FDTDIR" + else + echo "FDT" + fi +} + +generate_grub_cfg_body() { + cat << EOF +insmod part_gpt +insmod part_msdos +load_env + +if [ "\${saved_entry}" ]; then + set timeout=2 + set default="\${saved_entry}" +else + set timeout=-1 +fi + +if [ x"\${feature_menuentry_id}" = xy ]; then + menuentry_id_option="--id" +else + menuentry_id_option="" +fi +export menuentry_id_option + +function savedefault { + saved_entry="\${chosen}" + save_env saved_entry +} + +set timeout_style=menu +set lang=en_US +loadfont /boot/grub/dejavu-mono.pf2 +set rotation=270 +set gfxmode=auto +insmod efi_gop +insmod gfxterm +terminal_output gfxterm +set menu_color_normal=cyan/blue +set menu_color_highlight=white/blue + +EOF + + xmlstarlet sel -t -m "//archr/${DEVICE}/file" \ + -v "concat(@short, '|', @full, '|', .)" -n "${CONFIGXML}" 2>/dev/null | while IFS='|' read -r SHORT FULL DTB; do + + cat << EOF +menuentry '${FULL}' \$menuentry_id_option '${SHORT}' { + savedefault + search --set -f /KERNEL + linux /KERNEL boot=LABEL=${DISTRO_BOOTLABEL} disk=LABEL=${DISTRO_DISKLABEL} grub_portable ${EXTRA_CMDLINE} + devicetree /boot/grub/${DTB}.dtb +} +EOF + done + + xmlstarlet sel -t -m "//archr/${DEVICE}/file" \ + -v "concat(@short, '|', @full, '|', .)" -n "${CONFIGXML}" 2>/dev/null | while IFS='|' read -r SHORT FULL DTB; do + + cat << EOF +menuentry '${FULL} RECOVERY' \$menuentry_id_option '${SHORT}-recovery' { + search --set -f /KERNEL + linux /KERNEL boot=LABEL=${DISTRO_BOOTLABEL} disk=LABEL=${DISTRO_DISKLABEL} grub_portable ${EXTRA_CMDLINE} recovery + devicetree /boot/grub/${DTB}.dtb +} +EOF + done +} + +mkimage_all() { + local OPTIONS_LIST="" + + if [[ -n "${SUBDEVICE}" ]]; then + OPTIONS_LIST=$(xmlstarlet sel -t -v "//archr/${DEVICE}/${SUBDEVICE}/@mkimage_options" "${CONFIGXML}" 2>/dev/null) + fi + + if [[ -z "${OPTIONS_LIST}" ]]; then + OPTIONS_LIST=$(xmlstarlet sel -t -v "//archr/${DEVICE}/@mkimage_options" "${CONFIGXML}" 2>/dev/null) + fi + + for step in $(echo "${OPTIONS_LIST}" | tr ',' ' '); do + local func_name="mkimage_${step}" + + "${func_name}" + done +} diff --git a/distributions/ArchR/kernel_options b/distributions/ArchR/kernel_options new file mode 100644 index 0000000000..e69de29bb2 diff --git a/distributions/ArchR/logos/archr-logo.png b/distributions/ArchR/logos/archr-logo.png new file mode 100644 index 0000000000..f85d59d604 Binary files /dev/null and b/distributions/ArchR/logos/archr-logo.png differ diff --git a/distributions/ArchR/logos/archr-logo.svg b/distributions/ArchR/logos/archr-logo.svg new file mode 100644 index 0000000000..5cd7063a7c --- /dev/null +++ b/distributions/ArchR/logos/archr-logo.svg @@ -0,0 +1,5 @@ + + + ARCHR + + diff --git a/distributions/ArchR/options b/distributions/ArchR/options new file mode 100644 index 0000000000..2257f618f6 --- /dev/null +++ b/distributions/ArchR/options @@ -0,0 +1,225 @@ +# LTO (Link Time Optimization) support + LTO_SUPPORT="yes" + +# GOLD (Google Linker) support + GOLD_SUPPORT="yes" + +# HARDENING (security relevant linker and compiler flags) support + HARDENING_SUPPORT="no" + +# The name of the parent organization for updates + GIT_ORGANIZATION="ArchR" + +# The name of the github project for updates + GIT_REPO="distribution" + +# Name of the Distro to build (full name, without special characters) + DISTRONAME="ArchR" + +# Name of the OS to build (full name, lower case, without special characters) + OSNAME="archr" + +# short project description + DESCRIPTION="Arch R - Gaming OS for R36S" + +# Distribution Home URL + HOME_URL="https://github.com/ArchR" + +# Documentation URL + WIKI_URL="https://github.com/ArchR" + +# Where to report bugs + BUG_REPORT_URL="https://github.com/ArchR" + +# Root password to integrate in the target system + ROOT_PASSWORD="archr" + +# Install glibc locales to the build (yes / no) + GLIBC_LOCALES="yes" + +# build and install pipewire support (yes / no) + PIPEWIRE_SUPPORT="yes" + +# Define package sets to clean based on the type of build being executed. +# This should be updated to be more dynamic in the future. + CLEAN_OS_BASE="emulators system-utils modules quirks autostart archr kernel-firmware" + CLEAN_NETWORK="" + CLEAN_EMU_32BIT="lib32 box86 pcsx_rearmed-lr arm" + # Sway depends on it, weston will use it if it's built but we don't want that. + CLEAN_WESTON="libdisplay-info sway" + +# build and install archr joypad driver (yes / no) + ARCHR_JOYPAD="yes" + +# additional drivers to install: +# for a list of additional drivers see packages/linux-drivers +# Space separated list is supported, +# e.g. ADDITIONAL_DRIVERS="DRIVER1 DRIVER2" + ADDITIONAL_DRIVERS="" + +# build and install driver addons (yes / no) + DRIVER_ADDONS_SUPPORT="no" + +# driver addons to install: +# for a list of additinoal drivers see packages/linux-driver-addons +# Space separated list is supported, + DRIVER_ADDONS="" + +# Disable 32BIT support + ENABLE_32BIT="${ENABLE_32BIT-true}" + +# build and install bluetooth support (yes / no) + BLUETOOTH_SUPPORT="yes" + +# build and install Avahi (Zeroconf) daemon (yes / no) + AVAHI_DAEMON="yes" + +# build with NFS support (mounting nfs shares via the OS) (yes / no) + NFS_SUPPORT="yes" + +# build with Samba Client support (mounting samba shares via the OS) (yes / no) + SAMBA_SUPPORT="no" + +# build and install Samba Server (yes / no) + SAMBA_SERVER="yes" + +# build and install SFTP Server (yes / no) + SFTP_SERVER="yes" + +# build and install Simple HTTP Server (yes / no) + SIMPLE_HTTP_SERVER="yes" + +# build and install OpenVPN support (yes / no) + OPENVPN_SUPPORT="no" + +# build and install ZeroTier support (yes / no) + ZEROTIER_SUPPORT="yes" + +# build and install WireGuard support (yes / no) + WIREGUARD_SUPPORT="yes" + +# build and install diskmounter support (udevil) +# this service provide auto mounting support for external drives in the +# mediacenter also automount internally drives at boottime via udev (yes / no) + UDEVIL="yes" + +# build and install exFAT fuse support (yes / no) + EXFAT="yes" + +# build and install NTFS-3G fuse support (yes / no) + NTFS3G="yes" + +# build and install hfs filesystem utilities (yes / no) + HFSTOOLS="no" + +# Target an emulation device + EMULATION_DEVICE="${EMULATION_DEVICE:-yes}" + +# Add support for containers + CONTAINER_SUPPORT="${CONTAINER_SUPPORT:-no}" + +# Build modules packages + MODULES_PKG="${MODULES_PKG:-yes}" + +# Support for debug tools such as strace + DEBUG_PACKAGES="${DEBUG_PACKAGES:-yes}" + +# Windowmanager to use (weston / swaywm-env / no) + WINDOWMANAGER="none" + +# Xorg Graphic drivers to use (all / i915,i965,r200,r300,r600,nvidia) +# Space separated list is supported, +# e.g. GRAPHIC_DRIVERS="i915 i965 r300 r600 radeonsi nvidia" + GRAPHIC_DRIVERS="" + +# build and install remote support (yes / no) + REMOTE_SUPPORT="yes" + +# build and install Joystick support (yes / no) + JOYSTICK_SUPPORT="yes" + +# Support for partitioning and formating disks in initramfs (yes / no) +# This adds support for parted and mkfs.ext3/4 to initramfs for OEM usage + INITRAMFS_PARTED_SUPPORT="no" + +# build with swap support (yes / no) + SWAP_SUPPORT="yes" + +# swap support enabled per default (yes / no) + SWAP_ENABLED_DEFAULT="yes" + +# swap size if SWAP_SUPPORT=yes in MB + SWAPSIZE="384" + +# swap type if SWAP_SUPPORT=yes (file / zram) + SWAP_TYPE="file" + +# Default weston terminal font size + WESTONFONTSIZE="14" + +# additional packages to install: +# Space separated list is supported, +# e.g. ADDITIONAL_PACKAGES="PACKAGE1 PACKAGE2" + +# build with installer (yes / no) + INSTALLER_SUPPORT="no" + +# Testpackages for development (yes / no) + TESTING="no" + +# OEM packages for OEM's (yes / no) + OEM_SUPPORT="no" + +# build and install nano text editor (yes / no) + NANO_EDITOR="yes" + +# cron support (yes / no) + CRON_SUPPORT="no" + +# htop tool (yes / no) + HTOP_TOOL="yes" + +# btop tool (yes / no) + BTOP_TOOL="yes" + +# Distribution Specific source location + DISTRO_MIRROR="https://github.com/ROCKNIX/distribution-sources/releases/download/sources" + +# Root filesystem type (squashfs / ext4) + ROOTFS_TYPE="ext4" + +# Boot partition size (FAT32, kernel + DTBs + bootloader), in MB + BOOT_SIZE=256 + +# Root partition size (ext4 rootfs), in MB + ROOT_SIZE=4608 + +# Default system partition offset, in sectors, eg. 2048 + SYSTEM_PART_START=32768 + +# Legacy SYSTEM_SIZE (used when ROOTFS_TYPE=squashfs, or as fallback) + SYSTEM_SIZE=${BOOT_SIZE} + +# Size of storage partition, in MB. Must be >=32 + STORAGE_SIZE=32 + +# Default supported get handlers (archive, git, file etc.) + GET_HANDLER_SUPPORT="archive git file" + +# Partition labels for USB/SD installation media + DISTRO_BOOTLABEL="ARCHR" + DISTRO_ROOTLABEL="ARCHR_ROOT" + DISTRO_DISKLABEL="STORAGE" + +# Settings package name - blank if not required + DISTRO_PKG_SETTINGS="" + +# Enable Updates + ENABLE_UPDATES="yes" + +# defines the born on date of a build + BUILD_DATE=$(date) + +# Define supported systems documentation path + SYSDOCROOT="${ROOT}/documentation/PER_DEVICE_DOCUMENTATION/${DEVICE}" + SYSDOC="${SYSDOCROOT}/SUPPORTED_EMULATORS_AND_CORES" diff --git a/distributions/ArchR/splash/boot-logo.bmp.gz b/distributions/ArchR/splash/boot-logo.bmp.gz new file mode 100644 index 0000000000..aac85ba472 Binary files /dev/null and b/distributions/ArchR/splash/boot-logo.bmp.gz differ diff --git a/distributions/ArchR/splash/splash-1080.png b/distributions/ArchR/splash/splash-1080.png new file mode 100644 index 0000000000..ae9b654877 Binary files /dev/null and b/distributions/ArchR/splash/splash-1080.png differ diff --git a/distributions/ArchR/splash/splash-1200.png b/distributions/ArchR/splash/splash-1200.png new file mode 100644 index 0000000000..5865ff0dc2 Binary files /dev/null and b/distributions/ArchR/splash/splash-1200.png differ diff --git a/distributions/ArchR/splash/splash-2160.png b/distributions/ArchR/splash/splash-2160.png new file mode 100644 index 0000000000..b576453a9c Binary files /dev/null and b/distributions/ArchR/splash/splash-2160.png differ diff --git a/distributions/ArchR/splash/splash-720.png b/distributions/ArchR/splash/splash-720.png new file mode 100644 index 0000000000..de3e1ecc9b Binary files /dev/null and b/distributions/ArchR/splash/splash-720.png differ diff --git a/distributions/ArchR/splash/splash-768.png b/distributions/ArchR/splash/splash-768.png new file mode 100644 index 0000000000..323f5e101d Binary files /dev/null and b/distributions/ArchR/splash/splash-768.png differ diff --git a/distributions/ArchR/splash/splash-base.svg b/distributions/ArchR/splash/splash-base.svg new file mode 100644 index 0000000000..f61d32630d --- /dev/null +++ b/distributions/ArchR/splash/splash-base.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + Arch R + + + + GAMING OS FOR R36S + + + + Loading... + + diff --git a/distributions/ArchR/version b/distributions/ArchR/version new file mode 100644 index 0000000000..9cfcbda200 --- /dev/null +++ b/distributions/ArchR/version @@ -0,0 +1,5 @@ +# VERSION: set full version, use "devel" for development version + DISTRO_VERSION="devel" + +# OS_VERSION: OS Version + OS_VERSION="$(date +%Y%m%d)" diff --git a/documentation/PER_DEVICE_DOCUMENTATION/RK3326/SUPPORTED_EMULATORS_AND_CORES.md b/documentation/PER_DEVICE_DOCUMENTATION/RK3326/SUPPORTED_EMULATORS_AND_CORES.md index 77fafc8230..cee044f6a5 100644 --- a/documentation/PER_DEVICE_DOCUMENTATION/RK3326/SUPPORTED_EMULATORS_AND_CORES.md +++ b/documentation/PER_DEVICE_DOCUMENTATION/RK3326/SUPPORTED_EMULATORS_AND_CORES.md @@ -8,6 +8,7 @@ | System|Tools (tools)|System|`modules`|.sh|| |Acorn|BBC Micro (bbcmicro)|1981|`bbcmicro`|.ssd .dsd|**retroarch:** b2 (default)
| |Amstrad|Amstrad CPC (amstradcpc)|1984|`amstradcpc`|.dsk .cpr .sna .tap .cdt .kcr .voc .m3u .zip .7z|**retroarch:** crocods (default)
**retroarch:** cap32
| +|Apple|iOS (ios)|2008|`ios`|.ipa .app|**touchhle:** touchhle-sa (default)
| |Apple|Macintosh (macintosh)|1984|`mac`|.dsk .img .hfv .cmd .zip|**retroarch:** minivmac (default)
| |Arcade|Arcade (arcade)|0000|`arcade`|.zip .7z|**retroarch:** mame2003_plus (default)
**retroarch:** mame2010
**retroarch:** mame2015
**retroarch:** fbneo
**retroarch:** fbalpha2012
**retroarch:** fbalpha2019
**retroarch:** mame
| |Arcade|Daphne (daphne)|1996|`daphne`|.daphne .singe|**hypseus-singe:** hypseus-singe (default)
**retroarch:** daphne
| diff --git a/packages/debug/gdb/package.mk b/packages/debug/gdb/package.mk index d50c85646c..a67b96f50d 100644 --- a/packages/debug/gdb/package.mk +++ b/packages/debug/gdb/package.mk @@ -7,7 +7,7 @@ PKG_VERSION="16.3" PKG_SHA256="bcfcd095528a987917acf9fff3f1672181694926cc18d609c99d0042c00224c5" PKG_LICENSE="GPL" PKG_SITE="https://www.gnu.org/software/gdb/" -PKG_URL="https://ftp.gnu.org/gnu/gdb/${PKG_NAME}-${PKG_VERSION}.tar.xz" +PKG_URL="https://mirrors.kernel.org/gnu/gdb/${PKG_NAME}-${PKG_VERSION}.tar.xz" PKG_DEPENDS_TARGET="toolchain expat gmp mpfr ncurses zlib" PKG_DEPENDS_HOST="toolchain:host expat:host gmp:host mpfr:host ncurses:host zlib:host" PKG_LONGDESC="GNU Project debugger, allows you to see what is going on inside another program while it executes." diff --git a/packages/devel/autoconf-archive/package.mk b/packages/devel/autoconf-archive/package.mk index b8143c79e4..9db5a7890a 100644 --- a/packages/devel/autoconf-archive/package.mk +++ b/packages/devel/autoconf-archive/package.mk @@ -7,7 +7,7 @@ PKG_VERSION="2024.10.16" PKG_SHA256="7bcd5d001916f3a50ed7436f4f700e3d2b1bade3ed803219c592d62502a57363" PKG_LICENSE="GPL" PKG_SITE="https://www.gnu.org/software/autoconf-archive/" -PKG_URL="https://ftpmirror.gnu.org/autoconf-archive/${PKG_NAME}-${PKG_VERSION}.tar.xz" +PKG_URL="https://mirrors.kernel.org/gnu/autoconf-archive/${PKG_NAME}-${PKG_VERSION}.tar.xz" PKG_DEPENDS_HOST="ccache:host" PKG_LONGDESC="autoconf-archive is an package of m4 macros" PKG_BUILD_FLAGS="-cfg-libs:host" diff --git a/packages/devel/autoconf/package.mk b/packages/devel/autoconf/package.mk index 8ec2ebc0d7..d91778d2fb 100644 --- a/packages/devel/autoconf/package.mk +++ b/packages/devel/autoconf/package.mk @@ -7,7 +7,7 @@ PKG_VERSION="2.72" PKG_SHA256="ba885c1319578d6c94d46e9b0dceb4014caafe2490e437a0dbca3f270a223f5a" PKG_LICENSE="GPL" PKG_SITE="https://www.gnu.org/software/autoconf/" -PKG_URL="https://ftpmirror.gnu.org/autoconf/${PKG_NAME}-${PKG_VERSION}.tar.xz" +PKG_URL="https://mirrors.kernel.org/gnu/autoconf/${PKG_NAME}-${PKG_VERSION}.tar.xz" PKG_DEPENDS_HOST="ccache:host m4:host gettext:host" PKG_LONGDESC="A GNU tool for automatically configuring source code." PKG_BUILD_FLAGS="-cfg-libs:host" diff --git a/packages/devel/automake/package.mk b/packages/devel/automake/package.mk index a33005d38e..688daa6019 100644 --- a/packages/devel/automake/package.mk +++ b/packages/devel/automake/package.mk @@ -6,7 +6,7 @@ PKG_VERSION="1.18.1" PKG_SHA256="168aa363278351b89af56684448f525a5bce5079d0b6842bd910fdd3f1646887" PKG_LICENSE="GPL" PKG_SITE="http://sources.redhat.com/automake/" -PKG_URL="https://ftpmirror.gnu.org/automake/${PKG_NAME}-${PKG_VERSION}.tar.xz" +PKG_URL="https://mirrors.kernel.org/gnu/automake/${PKG_NAME}-${PKG_VERSION}.tar.xz" PKG_DEPENDS_HOST="ccache:host autoconf:host" PKG_LONGDESC="A GNU tool for automatically creating Makefiles." PKG_BUILD_FLAGS="-parallel -cfg-libs:host" diff --git a/packages/devel/binutils/package.mk b/packages/devel/binutils/package.mk index dd347c2a49..c1850009c2 100644 --- a/packages/devel/binutils/package.mk +++ b/packages/devel/binutils/package.mk @@ -7,7 +7,7 @@ PKG_VERSION="2.44" PKG_SHA256="67be9198476cc37436e2801de649f4ad80bf0d02430d86aff63c6b59b6e23987" PKG_LICENSE="GPL" PKG_SITE="https://www.gnu.org/software/binutils/" -PKG_URL="https://ftp.gnu.org/gnu/binutils/${PKG_NAME}-with-gold-${PKG_VERSION}.tar.xz" +PKG_URL="https://mirrors.kernel.org/gnu/binutils/${PKG_NAME}-with-gold-${PKG_VERSION}.tar.xz" PKG_DEPENDS_HOST="ccache:host bison:host flex:host linux:host" PKG_DEPENDS_TARGET="toolchain zlib binutils:host" PKG_LONGDESC="A GNU collection of binary utilities." diff --git a/packages/devel/bison/package.mk b/packages/devel/bison/package.mk index a0fecaa15e..27c6d0dafb 100644 --- a/packages/devel/bison/package.mk +++ b/packages/devel/bison/package.mk @@ -7,7 +7,7 @@ PKG_VERSION="3.8.2" PKG_SHA256="9bba0214ccf7f1079c5d59210045227bcf619519840ebfa80cd3849cff5a5bf2" PKG_LICENSE="GPL" PKG_SITE="http://www.gnu.org/software/bison/" -PKG_URL="https://ftpmirror.gnu.org/bison/${PKG_NAME}-${PKG_VERSION}.tar.xz" +PKG_URL="https://mirrors.kernel.org/gnu/bison/${PKG_NAME}-${PKG_VERSION}.tar.xz" PKG_DEPENDS_HOST="ccache:host m4:host" PKG_LONGDESC="A general-purpose parser generator." PKG_BUILD_FLAGS="-parallel -cfg-libs:host" diff --git a/packages/devel/configtools/package.mk b/packages/devel/configtools/package.mk index a2794aacf7..7a9569baec 100644 --- a/packages/devel/configtools/package.mk +++ b/packages/devel/configtools/package.mk @@ -3,15 +3,28 @@ # Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv) PKG_NAME="configtools" -PKG_VERSION="28ea239c53a2d5d8800c472bc2452eaa16e37af2" -PKG_SHA256="6e4ebaa2a60114cf8b72d478b30e559f0c8e025d290ae3303773095104bf7bcc" +PKG_VERSION="system" PKG_LICENSE="GPL" -PKG_SITE="http://git.savannah.gnu.org/cgit/config.git" -PKG_URL="http://git.savannah.gnu.org/cgit/config.git/snapshot/config-${PKG_VERSION}.tar.gz" +PKG_SITE="https://www.gnu.org/software/config/" +PKG_URL="" PKG_DEPENDS_HOST="" -PKG_LONGDESC="configtools" +PKG_LONGDESC="GNU config.guess and config.sub from system automake" PKG_TOOLCHAIN="manual" +unpack() { + mkdir -p ${PKG_BUILD} + # Copy config.guess and config.sub from system automake + local automake_share=$(ls -d /usr/share/automake-* 2>/dev/null | head -1) + if [ -n "${automake_share}" ]; then + cp ${automake_share}/config.guess ${PKG_BUILD}/ + cp ${automake_share}/config.sub ${PKG_BUILD}/ + else + # Fallback: use the ones from /usr/share/libtool + cp /usr/share/libtool/build-aux/config.guess ${PKG_BUILD}/ 2>/dev/null || true + cp /usr/share/libtool/build-aux/config.sub ${PKG_BUILD}/ 2>/dev/null || true + fi +} + makeinstall_host() { mkdir -p ${TOOLCHAIN}/configtools cp config.* ${TOOLCHAIN}/configtools diff --git a/packages/devel/gettext/package.mk b/packages/devel/gettext/package.mk index 2d98f824a8..4f8f97944e 100644 --- a/packages/devel/gettext/package.mk +++ b/packages/devel/gettext/package.mk @@ -7,7 +7,7 @@ PKG_VERSION="0.25.1" PKG_SHA256="2c8294be238f03fb3fa65b8051057e5b68167f3e21f08008070cf40a7051ba22" PKG_LICENSE="GPL" PKG_SITE="https://www.gnu.org/s/gettext/" -PKG_URL="https://ftp.gnu.org/pub/gnu/gettext/${PKG_NAME}-${PKG_VERSION}.tar.xz" +PKG_URL="https://mirrors.kernel.org/gnu/gettext/${PKG_NAME}-${PKG_VERSION}.tar.xz" PKG_DEPENDS_HOST="make:host" PKG_DEPENDS_TARGET="autotools:host make:host gcc:host" PKG_LONGDESC="A program internationalization library and tools." diff --git a/packages/devel/glibc/package.mk b/packages/devel/glibc/package.mk index 4e76db015a..c9e80a9d03 100644 --- a/packages/devel/glibc/package.mk +++ b/packages/devel/glibc/package.mk @@ -7,7 +7,7 @@ PKG_VERSION="2.41" PKG_SHA256="a5a26b22f545d6b7d7b3dd828e11e428f24f4fac43c934fb071b6a7d0828e901" PKG_LICENSE="GPL" PKG_SITE="https://www.gnu.org/software/libc/" -PKG_URL="https://ftp.gnu.org/pub/gnu/glibc/${PKG_NAME}-${PKG_VERSION}.tar.xz" +PKG_URL="https://mirrors.kernel.org/gnu/glibc/${PKG_NAME}-${PKG_VERSION}.tar.xz" PKG_DEPENDS_TARGET="ccache:host autotools:host linux:host gcc:bootstrap Python3:host" PKG_DEPENDS_INIT="glibc" PKG_LONGDESC="The Glibc package contains the main C library." diff --git a/packages/devel/libtool/package.mk b/packages/devel/libtool/package.mk index 47d6d4a09d..45e92110d1 100644 --- a/packages/devel/libtool/package.mk +++ b/packages/devel/libtool/package.mk @@ -7,7 +7,7 @@ PKG_VERSION="2.5.4" PKG_SHA256="f81f5860666b0bc7d84baddefa60d1cb9fa6fceb2398cc3baca6afaa60266675" PKG_LICENSE="GPL" PKG_SITE="https://www.gnu.org/software/libtool/" -PKG_URL="https://ftpmirror.gnu.org/libtool/${PKG_NAME}-${PKG_VERSION}.tar.xz" +PKG_URL="https://mirrors.kernel.org/gnu/libtool/${PKG_NAME}-${PKG_VERSION}.tar.xz" PKG_DEPENDS_HOST="ccache:host autoconf:host automake:host intltool:host" PKG_DEPENDS_TARGET="toolchain" PKG_LONGDESC="A generic library support script." diff --git a/packages/devel/m4/package.mk b/packages/devel/m4/package.mk index 83f6d9a82c..a6262fc1ea 100644 --- a/packages/devel/m4/package.mk +++ b/packages/devel/m4/package.mk @@ -6,7 +6,7 @@ PKG_VERSION="1.4.20" PKG_SHA256="ac6989ee5d2aed81739780630cc2ce097e2a6546feb96a4a54db37d46a1452e4" PKG_LICENSE="GPL" PKG_SITE="http://www.gnu.org/software/m4/" -PKG_URL="https://ftpmirror.gnu.org/m4/${PKG_NAME}-${PKG_VERSION}.tar.bz2" +PKG_URL="https://mirrors.kernel.org/gnu/m4/${PKG_NAME}-${PKG_VERSION}.tar.bz2" PKG_DEPENDS_HOST="ccache:host" PKG_LONGDESC="The m4 macro processor." PKG_BUILD_FLAGS="-cfg-libs:host" diff --git a/packages/devel/make/package.mk b/packages/devel/make/package.mk index 622ad45e57..43404d9e9f 100644 --- a/packages/devel/make/package.mk +++ b/packages/devel/make/package.mk @@ -7,7 +7,7 @@ PKG_VERSION="4.4.1" PKG_SHA256="dd16fb1d67bfab79a72f5e8390735c49e3e8e70b4945a15ab1f81ddb78658fb3" PKG_LICENSE="GPLv3" PKG_SITE="https://www.gnu.org/software/make/" -PKG_URL="https://ftpmirror.gnu.org/make/${PKG_NAME}-${PKG_VERSION}.tar.gz" +PKG_URL="https://mirrors.kernel.org/gnu/make/${PKG_NAME}-${PKG_VERSION}.tar.gz" PKG_DEPENDS_HOST="" PKG_LONGDESC="Utility to maintain groups of programs." PKG_BUILD_FLAGS="+local-cc -cfg-libs:host" diff --git a/packages/devel/mpc/package.mk b/packages/devel/mpc/package.mk index a544064663..b9a078dcdd 100644 --- a/packages/devel/mpc/package.mk +++ b/packages/devel/mpc/package.mk @@ -7,7 +7,7 @@ PKG_VERSION="1.3.1" PKG_SHA256="ab642492f5cf882b74aa0cb730cd410a81edcdbec895183ce930e706c1c759b8" PKG_LICENSE="LGPL" PKG_SITE="https://www.multiprecision.org" -PKG_URL="https://ftpmirror.gnu.org/mpc/${PKG_NAME}-${PKG_VERSION}.tar.gz" +PKG_URL="https://mirrors.kernel.org/gnu/mpc/${PKG_NAME}-${PKG_VERSION}.tar.gz" PKG_DEPENDS_HOST="ccache:host gmp:host mpfr:host" PKG_LONGDESC="A C library for the arithmetic of complex numbers with arbitrarily high precision and correct rounding of the result." diff --git a/packages/devel/mpfr/package.mk b/packages/devel/mpfr/package.mk index 4855865e65..2aad45c302 100644 --- a/packages/devel/mpfr/package.mk +++ b/packages/devel/mpfr/package.mk @@ -7,7 +7,7 @@ PKG_VERSION="4.2.2" PKG_SHA256="b67ba0383ef7e8a8563734e2e889ef5ec3c3b898a01d00fa0a6869ad81c6ce01" PKG_LICENSE="LGPL" PKG_SITE="http://www.mpfr.org/" -PKG_URL="https://ftpmirror.gnu.org/mpfr/${PKG_NAME}-${PKG_VERSION}.tar.xz" +PKG_URL="https://mirrors.kernel.org/gnu/mpfr/${PKG_NAME}-${PKG_VERSION}.tar.xz" PKG_DEPENDS_HOST="ccache:host gmp:host" PKG_DEPENDS_TARGET="gmp" PKG_LONGDESC="A C library for multiple-precision floating-point computations with exact rounding." diff --git a/packages/devel/readline/package.mk b/packages/devel/readline/package.mk index f0301aff6b..6bf2b04d9c 100644 --- a/packages/devel/readline/package.mk +++ b/packages/devel/readline/package.mk @@ -7,7 +7,7 @@ PKG_VERSION="8.3" PKG_SHA256="fe5383204467828cd495ee8d1d3c037a7eba1389c22bc6a041f627976f9061cc" PKG_LICENSE="MIT" PKG_SITE="http://www.gnu.org/software/readline/" -PKG_URL="https://ftpmirror.gnu.org/readline/${PKG_NAME}-${PKG_VERSION}.tar.gz" +PKG_URL="https://mirrors.kernel.org/gnu/readline/${PKG_NAME}-${PKG_VERSION}.tar.gz" PKG_DEPENDS_TARGET="autotools:host gcc:host ncurses" PKG_LONGDESC="The GNU Readline library provides a set of functions for use by applications that allow users to edit command lines as they are typed in." PKG_BUILD_FLAGS="+pic" diff --git a/packages/lang/gcc/package.mk b/packages/lang/gcc/package.mk index 3f0f2e2b5a..ac7270b01c 100644 --- a/packages/lang/gcc/package.mk +++ b/packages/lang/gcc/package.mk @@ -7,7 +7,7 @@ PKG_VERSION="15.1.0" PKG_SHA256="e2b09ec21660f01fecffb715e0120265216943f038d0e48a9868713e54f06cea" PKG_LICENSE="GPL-2.0-or-later" PKG_SITE="https://gcc.gnu.org/" -PKG_URL="https://ftpmirror.gnu.org/gcc/${PKG_NAME}-${PKG_VERSION}/${PKG_NAME}-${PKG_VERSION}.tar.xz" +PKG_URL="https://mirrors.kernel.org/gnu/gcc/${PKG_NAME}-${PKG_VERSION}/${PKG_NAME}-${PKG_VERSION}.tar.xz" PKG_DEPENDS_BOOTSTRAP="ccache:host autoconf:host binutils:host gmp:host mpfr:host mpc:host zstd:host" PKG_DEPENDS_TARGET="toolchain" PKG_DEPENDS_HOST="ccache:host autoconf:host binutils:host gmp:host mpfr:host mpc:host zstd:host glibc libxcrypt" diff --git a/packages/mediacenter/kodi/system.d/kodi-cleanlogs.service b/packages/mediacenter/kodi/system.d/kodi-cleanlogs.service index 0b32a88742..4495f354a9 100644 --- a/packages/mediacenter/kodi/system.d/kodi-cleanlogs.service +++ b/packages/mediacenter/kodi/system.d/kodi-cleanlogs.service @@ -1,7 +1,7 @@ [Unit] Description=Kodi clean debug logs ConditionKernelCommandLine=!debugging -ConditionPathExists=!/storage/.cache/debug.libreelec +ConditionPathExists=!/storage/.cache/debug.archr Before=kodi.service [Service] diff --git a/packages/network/avahi/system.d/avahi-daemon.service b/packages/network/avahi/system.d/avahi-daemon.service index 63cd640cb8..54e2a9d046 100644 --- a/packages/network/avahi/system.d/avahi-daemon.service +++ b/packages/network/avahi/system.d/avahi-daemon.service @@ -6,7 +6,7 @@ ConditionPathExists=/storage/.cache/services/avahi.conf [Service] Restart=on-failure -EnvironmentFile=-/run/libreelec/debug/avahi.conf +EnvironmentFile=-/run/archr/debug/avahi.conf ExecStart=/usr/sbin/avahi-daemon -s $AVAHI_DEBUG ExecReload=/usr/sbin/avahi-daemon -r TimeoutStopSec=1s diff --git a/packages/network/bluez/system.d/bluetooth.service b/packages/network/bluez/system.d/bluetooth.service index f95bf377d8..171e204e02 100644 --- a/packages/network/bluez/system.d/bluetooth.service +++ b/packages/network/bluez/system.d/bluetooth.service @@ -8,7 +8,7 @@ ConditionPathExists=/storage/.cache/services/bluez.conf [Service] NotifyAccess=main EnvironmentFile=/storage/.cache/services/bluez.conf -EnvironmentFile=-/run/libreelec/debug/bluez.conf +EnvironmentFile=-/run/archr/debug/bluez.conf ExecStart=/usr/lib/bluetooth/bluetoothd $BLUEZ_ARGS $BLUEZ_DEBUG CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_FOWNER LimitNPROC=1 diff --git a/packages/network/bluez/system.d/obex.service b/packages/network/bluez/system.d/obex.service index 9ae85bfa5f..6e418d9cfe 100644 --- a/packages/network/bluez/system.d/obex.service +++ b/packages/network/bluez/system.d/obex.service @@ -8,7 +8,7 @@ ConditionPathExists=/storage/.cache/services/bluez.conf [Service] EnvironmentFile=/storage/.cache/services/obexd.conf -EnvironmentFile=-/run/libreelec/debug/obexd.conf +EnvironmentFile=-/run/archr/debug/obexd.conf ExecStartPre=/bin/sh -c 'mkdir -p $OBEXD_ROOT' ExecStart=/usr/lib/bluetooth/obexd -s -r $OBEXD_ROOT $OBEXD_DEBUG TimeoutStopSec=1s diff --git a/packages/network/connman/scripts/connman-setup b/packages/network/connman/scripts/connman-setup index da62062e02..361eb10351 100755 --- a/packages/network/connman/scripts/connman-setup +++ b/packages/network/connman/scripts/connman-setup @@ -18,8 +18,8 @@ fi # switch resolv.conf management to connman and use current contents # as a fallback -if [ -f /run/libreelec/resolv.conf ]; then - cat /run/libreelec/resolv.conf >/run/connman/resolv.conf +if [ -f /run/archr/resolv.conf ]; then + cat /run/archr/resolv.conf >/run/connman/resolv.conf fi -rm -f /run/libreelec/resolv.conf -ln -s /run/connman/resolv.conf /run/libreelec/resolv.conf +rm -f /run/archr/resolv.conf +ln -s /run/connman/resolv.conf /run/archr/resolv.conf diff --git a/packages/network/connman/system.d/connman.service b/packages/network/connman/system.d/connman.service index 7ae77172e8..702654a3fd 100644 --- a/packages/network/connman/system.d/connman.service +++ b/packages/network/connman/system.d/connman.service @@ -11,7 +11,7 @@ ConditionPathExists=!/dev/.kernel_ipconfig Type=dbus BusName=net.connman Restart=on-failure -EnvironmentFile=-/run/libreelec/debug/connman.conf +EnvironmentFile=-/run/archr/debug/connman.conf ExecStart=/bin/sh -c ". /usr/lib/connman/connman-setup; exec /usr/sbin/connmand -nr $CONNMAN_MAIN $CONNMAN_DEBUG" StandardOutput=null RestartSec=2 diff --git a/packages/network/iptables/package.mk b/packages/network/iptables/package.mk index 448497b2f7..027b1c29ca 100644 --- a/packages/network/iptables/package.mk +++ b/packages/network/iptables/package.mk @@ -23,8 +23,8 @@ post_makeinstall_target() { mkdir -p ${INSTALL}/etc/iptables/ cp -PR ${PKG_DIR}/config/* ${INSTALL}/etc/iptables/ - mkdir -p ${INSTALL}/usr/lib/libreelec - cp ${PKG_DIR}/scripts/iptables_helper ${INSTALL}/usr/lib/libreelec + mkdir -p ${INSTALL}/usr/lib/archr + cp ${PKG_DIR}/scripts/iptables_helper ${INSTALL}/usr/lib/archr } post_install() { diff --git a/packages/network/iptables/system.d/iptables.service b/packages/network/iptables/system.d/iptables.service index eacb387908..6a8c189ad1 100644 --- a/packages/network/iptables/system.d/iptables.service +++ b/packages/network/iptables/system.d/iptables.service @@ -1,6 +1,6 @@ [Unit] Description=IPTABLES Packet Filtering -ConditionPathExists=/usr/lib/libreelec/iptables_helper +ConditionPathExists=/usr/lib/archr/iptables_helper ConditionPathExists=|/storage/.cache/services/iptables.conf Before=network.target Wants=network.target @@ -8,9 +8,9 @@ Wants=network.target [Service] Type=oneshot EnvironmentFile=-/storage/.cache/services/iptables.conf -ExecStart=/usr/lib/libreelec/iptables_helper enable -ExecReload=/usr/lib/libreelec/iptables_helper enable -ExecStop=/usr/lib/libreelec/iptables_helper disable +ExecStart=/usr/lib/archr/iptables_helper enable +ExecReload=/usr/lib/archr/iptables_helper enable +ExecStop=/usr/lib/archr/iptables_helper disable RemainAfterExit=yes [Install] diff --git a/packages/security/nettle/package.mk b/packages/security/nettle/package.mk index d6e9b3828b..58bb47b28a 100644 --- a/packages/security/nettle/package.mk +++ b/packages/security/nettle/package.mk @@ -7,7 +7,7 @@ PKG_VERSION="3.10.2" PKG_SHA256="fe9ff51cb1f2abb5e65a6b8c10a92da0ab5ab6eaf26e7fc2b675c45f1fb519b5" PKG_LICENSE="GPL2" PKG_SITE="http://www.lysator.liu.se/~nisse/nettle" -PKG_URL="https://ftp.gnu.org/gnu/nettle/nettle-${PKG_VERSION}.tar.gz" +PKG_URL="https://mirrors.kernel.org/gnu/nettle/nettle-${PKG_VERSION}.tar.gz" PKG_DEPENDS_HOST="autotools:host gmp:host" PKG_DEPENDS_TARGET="autotools:host gcc:host gmp" PKG_LONGDESC="A low-level cryptographic library." diff --git a/packages/security/openssl/package.mk b/packages/security/openssl/package.mk index 824b08f7f7..63299a68b8 100644 --- a/packages/security/openssl/package.mk +++ b/packages/security/openssl/package.mk @@ -95,16 +95,16 @@ post_makeinstall_target() { # give user the chance to include their own CA mkdir -p ${INSTALL}/usr/bin cp ${PKG_DIR}/scripts/openssl-config ${INSTALL}/usr/bin - ln -sf /run/libreelec/cacert.pem ${INSTALL}/etc/ssl/cacert.pem - ln -sf /run/libreelec/cacert.pem ${INSTALL}/etc/ssl/cert.pem + ln -sf /run/archr/cacert.pem ${INSTALL}/etc/ssl/cacert.pem + ln -sf /run/archr/cacert.pem ${INSTALL}/etc/ssl/cert.pem # backwards compatibility mkdir -p ${INSTALL}/etc/pki/tls - ln -sf /run/libreelec/cacert.pem ${INSTALL}/etc/pki/tls/cacert.pem + ln -sf /run/archr/cacert.pem ${INSTALL}/etc/pki/tls/cacert.pem mkdir -p ${INSTALL}/etc/pki/tls/certs - ln -sf /run/libreelec/cacert.pem ${INSTALL}/etc/pki/tls/certs/ca-bundle.crt + ln -sf /run/archr/cacert.pem ${INSTALL}/etc/pki/tls/certs/ca-bundle.crt mkdir -p ${INSTALL}/usr/lib/ssl - ln -sf /run/libreelec/cacert.pem ${INSTALL}/usr/lib/ssl/cert.pem + ln -sf /run/archr/cacert.pem ${INSTALL}/usr/lib/ssl/cert.pem } post_install() { diff --git a/packages/security/openssl/scripts/openssl-config b/packages/security/openssl/scripts/openssl-config index fc25eded24..5c77facba6 100755 --- a/packages/security/openssl/scripts/openssl-config +++ b/packages/security/openssl/scripts/openssl-config @@ -3,8 +3,8 @@ # SPDX-License-Identifier: GPL-2.0 # Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) -cp /etc/ssl/cacert.pem.system /run/libreelec/cacert.pem +cp /etc/ssl/cacert.pem.system /run/archr/cacert.pem -[ -f /storage/.config/cacert.pem ] && cat /storage/.config/cacert.pem >>/run/libreelec/cacert.pem +[ -f /storage/.config/cacert.pem ] && cat /storage/.config/cacert.pem >>/run/archr/cacert.pem exit 0 diff --git a/packages/sysutils/busybox/config/profile b/packages/sysutils/busybox/config/profile index 79cce3c76a..faf70f625f 100644 --- a/packages/sysutils/busybox/config/profile +++ b/packages/sysutils/busybox/config/profile @@ -13,7 +13,7 @@ esac done - if [ -e /storage/.cache/debug.libreelec ] ; then + if [ -e /storage/.cache/debug.archr ] ; then export DEBUG=yes fi diff --git a/packages/sysutils/busybox/package.mk b/packages/sysutils/busybox/package.mk index fd44432bfb..bddfd0019f 100644 --- a/packages/sysutils/busybox/package.mk +++ b/packages/sysutils/busybox/package.mk @@ -124,11 +124,11 @@ makeinstall_target() { mkdir -p ${INSTALL}/usr/sbin cp ${PKG_DIR}/scripts/kernel-overlays-setup ${INSTALL}/usr/sbin - mkdir -p ${INSTALL}/usr/lib/libreelec - cp ${PKG_DIR}/scripts/functions ${INSTALL}/usr/lib/libreelec - cp ${PKG_DIR}/scripts/fs-resize ${INSTALL}/usr/lib/libreelec + mkdir -p ${INSTALL}/usr/lib/archr + cp ${PKG_DIR}/scripts/functions ${INSTALL}/usr/lib/archr + cp ${PKG_DIR}/scripts/fs-resize ${INSTALL}/usr/lib/archr sed -e "s/@DISTRONAME@/${DISTRONAME}/g" \ - -i ${INSTALL}/usr/lib/libreelec/fs-resize + -i ${INSTALL}/usr/lib/archr/fs-resize mkdir -p ${INSTALL}/usr/lib/systemd/system-generators/ cp ${PKG_DIR}/scripts/libreelec-target-generator ${INSTALL}/usr/lib/systemd/system-generators/ diff --git a/packages/sysutils/busybox/scripts/fs-resize b/packages/sysutils/busybox/scripts/fs-resize index ac03e4c430..b964bb83e1 100755 --- a/packages/sysutils/busybox/scripts/fs-resize +++ b/packages/sysutils/busybox/scripts/fs-resize @@ -11,7 +11,7 @@ StartProgressLog() { } if [ -e /storage/.please_resize_me ] ; then - . /usr/lib/libreelec/functions + . /usr/lib/archr/functions hidecursor diff --git a/packages/sysutils/busybox/scripts/init b/packages/sysutils/busybox/scripts/init index 31b455fa19..cf40b4683d 100755 --- a/packages/sysutils/busybox/scripts/init +++ b/packages/sysutils/busybox/scripts/init @@ -245,7 +245,10 @@ mount_part() { } mount_sysroot() { - if [ "$SYSTEM_TORAM" = "yes" ]; then + if [ -n "$root" ]; then + # ext4 root: mount root partition directly (read-write) + mount_part "$root" "/sysroot" "rw,noatime" + elif [ "$SYSTEM_TORAM" = "yes" ]; then cp "/flash/$IMAGE_SYSTEM" /dev/SYSTEM mount_part "/dev/SYSTEM" "/sysroot" "ro,loop" else @@ -992,6 +995,14 @@ for arg in $(cat /proc/cmdline); do ;; esac ;; + root=*) + root="${arg#*=}" + case $root in + /dev/*|LABEL=*|UUID=*) + RUN_FSCK_DISKS="$RUN_FSCK_DISKS $root" + ;; + esac + ;; wol_mac=*) wol_mac="${arg#*=}" ;; diff --git a/packages/sysutils/busybox/sleep.d.serial/99-suspend-modules.sh b/packages/sysutils/busybox/sleep.d.serial/99-suspend-modules.sh index 37545ee60a..76e7b2a8cb 100755 --- a/packages/sysutils/busybox/sleep.d.serial/99-suspend-modules.sh +++ b/packages/sysutils/busybox/sleep.d.serial/99-suspend-modules.sh @@ -51,7 +51,7 @@ modunload() _rmmod() { if modprobe -r "$1"; then - touch "/run/libreelec/suspend/module:$1" + touch "/run/archr/suspend/module:$1" return 0 else logger -t suspend-modules "# could not unload '$1', usage count was $2" @@ -61,7 +61,7 @@ _rmmod() resume_modules() { - for x in /run/libreelec/suspend/module:* ; do + for x in /run/archr/suspend/module:* ; do [ -O "${x}" ] || continue modprobe "${x##*:}" &>/dev/null && \ logger -t resume-modules "Reloaded module ${x##*:}." || \ @@ -73,8 +73,8 @@ suspend_modules() { [ -z "$SUSPEND_MODULES" ] && return 0 # clean up - rm -rf /run/libreelec/suspend - mkdir -p /run/libreelec/suspend + rm -rf /run/archr/suspend + mkdir -p /run/archr/suspend for x in $SUSPEND_MODULES ; do modunload $x && \ logger -t suspend-modules "Unloading kernel module $x: Done" || \ diff --git a/packages/sysutils/busybox/system.d/fs-resize.service b/packages/sysutils/busybox/system.d/fs-resize.service index b3a85d6460..673275f9ad 100644 --- a/packages/sysutils/busybox/system.d/fs-resize.service +++ b/packages/sysutils/busybox/system.d/fs-resize.service @@ -4,7 +4,7 @@ DefaultDependencies=no [Service] Type=idle -ExecStart=/usr/lib/libreelec/fs-resize +ExecStart=/usr/lib/archr/fs-resize StandardInput=tty-force StandardOutput=inherit StandardError=inherit diff --git a/packages/sysutils/busybox/system.d/var-log.mount b/packages/sysutils/busybox/system.d/var-log.mount index 28483c7739..a6c7ece004 100644 --- a/packages/sysutils/busybox/system.d/var-log.mount +++ b/packages/sysutils/busybox/system.d/var-log.mount @@ -6,7 +6,7 @@ After=storage-log.service DefaultDependencies=no ConditionKernelCommandLine=!installer ConditionKernelCommandLine=|debugging -ConditionPathExists=|/storage/.cache/debug.libreelec +ConditionPathExists=|/storage/.cache/debug.archr ConditionPathExists=|/storage/.cache/journald.conf.d/00_settings.conf [Mount] diff --git a/packages/sysutils/ethmactool/scripts/ethmactool-config b/packages/sysutils/ethmactool/scripts/ethmactool-config index 4db9b13087..b93546a715 100755 --- a/packages/sysutils/ethmactool/scripts/ethmactool-config +++ b/packages/sysutils/ethmactool/scripts/ethmactool-config @@ -76,7 +76,7 @@ done if validate_mac ; then MAC=$(echo "$MAC" | sed 's/\(..\)/\1:/g' | cut -b-17) - echo "MAC=${MAC}" > /run/libreelec/ethmactool-$1 + echo "MAC=${MAC}" > /run/archr/ethmactool-$1 /usr/sbin/ip link set dev $1 down /usr/sbin/ip link set dev $1 address $MAC /usr/sbin/ip link set dev $1 up diff --git a/packages/sysutils/lirc/package.mk b/packages/sysutils/lirc/package.mk index a6c36eac10..2a90cbfc91 100644 --- a/packages/sysutils/lirc/package.mk +++ b/packages/sysutils/lirc/package.mk @@ -51,9 +51,9 @@ post_makeinstall_target() { cp -r ${PKG_DIR}/config/lirc_options.conf ${INSTALL}/etc/lirc ln -s /storage/.config/lircd.conf ${INSTALL}/etc/lirc/lircd.conf - mkdir -p ${INSTALL}/usr/lib/libreelec - cp ${PKG_DIR}/scripts/lircd_helper ${INSTALL}/usr/lib/libreelec - cp ${PKG_DIR}/scripts/lircd_uinput_helper ${INSTALL}/usr/lib/libreelec + mkdir -p ${INSTALL}/usr/lib/archr + cp ${PKG_DIR}/scripts/lircd_helper ${INSTALL}/usr/lib/archr + cp ${PKG_DIR}/scripts/lircd_uinput_helper ${INSTALL}/usr/lib/archr mkdir -p ${INSTALL}/usr/share/services cp -P ${PKG_DIR}/default.d/*.conf ${INSTALL}/usr/share/services diff --git a/packages/sysutils/lirc/system.d/lircd-uinput.service b/packages/sysutils/lirc/system.d/lircd-uinput.service index f73f893e7d..cddb243d68 100644 --- a/packages/sysutils/lirc/system.d/lircd-uinput.service +++ b/packages/sysutils/lirc/system.d/lircd-uinput.service @@ -6,7 +6,7 @@ After=lircd.service [Service] Type=simple -ExecStart=/usr/lib/libreelec/lircd_uinput_helper --add-release-events +ExecStart=/usr/lib/archr/lircd_uinput_helper --add-release-events [Install] WantedBy=multi-user.target diff --git a/packages/sysutils/lirc/system.d/lircd.service b/packages/sysutils/lirc/system.d/lircd.service index 534dcf73f7..6c4ab2e4e8 100644 --- a/packages/sysutils/lirc/system.d/lircd.service +++ b/packages/sysutils/lirc/system.d/lircd.service @@ -6,7 +6,7 @@ After=network.target [Service] Type=simple -ExecStart=/usr/lib/libreelec/lircd_helper --nodaemon +ExecStart=/usr/lib/archr/lircd_helper --nodaemon [Install] WantedBy=multi-user.target diff --git a/packages/sysutils/parted/package.mk b/packages/sysutils/parted/package.mk index 8764ee1148..0218357ea5 100644 --- a/packages/sysutils/parted/package.mk +++ b/packages/sysutils/parted/package.mk @@ -7,7 +7,7 @@ PKG_VERSION="3.6" PKG_SHA256="3b43dbe33cca0f9a18601ebab56b7852b128ec1a3df3a9b30ccde5e73359e612" PKG_LICENSE="GPL" PKG_SITE="http://www.gnu.org/software/parted/" -PKG_URL="https://ftpmirror.gnu.org/parted/${PKG_NAME}-${PKG_VERSION}.tar.xz" +PKG_URL="https://mirrors.kernel.org/gnu/parted/${PKG_NAME}-${PKG_VERSION}.tar.xz" PKG_DEPENDS_HOST="autotools:host util-linux:host" PKG_DEPENDS_TARGET="autotools:host gcc:host util-linux parted:host" PKG_DEPENDS_INIT="autotools:host gcc:host util-linux:init parted" diff --git a/packages/sysutils/systemd/package.mk b/packages/sysutils/systemd/package.mk index 8728395dfb..7dc2adfffb 100644 --- a/packages/sysutils/systemd/package.mk +++ b/packages/sysutils/systemd/package.mk @@ -238,9 +238,9 @@ post_makeinstall_target() { cp ${PKG_DIR}/scripts/systemd-timesyncd-setup ${INSTALL}/usr/sbin # /etc/resolv.conf and /etc/hosts must be writable - ln -sf /run/libreelec/resolv.conf ${INSTALL}/etc/resolv.conf - ln -sf /run/libreelec/hosts ${INSTALL}/etc/hosts - ln -sf /run/libreelec/environment ${INSTALL}/etc/environment + ln -sf /run/archr/resolv.conf ${INSTALL}/etc/resolv.conf + ln -sf /run/archr/hosts ${INSTALL}/etc/hosts + ln -sf /run/archr/environment ${INSTALL}/etc/environment # provide 'halt', 'shutdown', 'reboot' & co. ln -sf /usr/bin/systemctl ${INSTALL}/usr/sbin/halt diff --git a/packages/sysutils/systemd/scripts/environment-setup b/packages/sysutils/systemd/scripts/environment-setup index eb78e067ed..ac34b30cce 100755 --- a/packages/sysutils/systemd/scripts/environment-setup +++ b/packages/sysutils/systemd/scripts/environment-setup @@ -10,7 +10,7 @@ for config in /etc/profile.d/*; do done # generate system-wide environment file -cat </run/libreelec/environment +cat </run/archr/environment PATH=${PATH} LD_LIBRARY_PATH=${LD_LIBRARY_PATH} EOF diff --git a/packages/sysutils/systemd/scripts/network-base-setup b/packages/sysutils/systemd/scripts/network-base-setup index 400084f759..f3fb864e2c 100755 --- a/packages/sysutils/systemd/scripts/network-base-setup +++ b/packages/sysutils/systemd/scripts/network-base-setup @@ -3,7 +3,7 @@ # Copyright (C) 2019-present Team LibreELEC (https://libreelec.tv) check_hosts() { - grep -v "^#" /run/libreelec/hosts | grep "${1}" + grep -v "^#" /run/archr/hosts | grep "${1}" } # setup hostname @@ -12,33 +12,33 @@ if [ -f /storage/.cache/hostname ]; then fi # setup /etc/hosts -rm -f /run/libreelec/hosts +rm -f /run/archr/hosts if [ -f /storage/.config/hosts.conf ]; then - cat /storage/.config/hosts.conf >/run/libreelec/hosts + cat /storage/.config/hosts.conf >/run/archr/hosts # add localhost to hosts if not present LOCALHOST_HOSTS=$(check_hosts "localhost") if [ -z "${LOCALHOST_HOSTS}" ]; then { echo "127.0.0.1 localhost" echo "::1 localhost ip6-localhost ip6-loopback" - } >>/run/libreelec/hosts + } >>/run/archr/hosts fi # add HOSTNAME to hosts if not present HOSTNAME=$(cat /proc/sys/kernel/hostname) HOSTNAME_HOSTS=$(check_hosts "${HOSTNAME}") if [ -z "${HOSTNAME_HOSTS}" ]; then - echo "127.0.1.1 ${HOSTNAME}" >>/run/libreelec/hosts + echo "127.0.1.1 ${HOSTNAME}" >>/run/archr/hosts fi fi # setup /etc/resolv.conf -rm -f /run/libreelec/resolv.conf +rm -f /run/archr/resolv.conf if [ -f /storage/.config/resolv.conf ]; then - cat /storage/.config/resolv.conf >/run/libreelec/resolv.conf + cat /storage/.config/resolv.conf >/run/archr/resolv.conf elif [ -f /dev/.kernel_ipconfig ] && [ -f /proc/net/pnp ]; then - cat /proc/net/pnp >/run/libreelec/resolv.conf + cat /proc/net/pnp >/run/archr/resolv.conf else - cat </run/libreelec/resolv.conf + cat </run/archr/resolv.conf nameserver 8.8.8.8 nameserver 8.8.4.4 EOF diff --git a/packages/sysutils/systemd/system.d/debugconfig.service b/packages/sysutils/systemd/system.d/debugconfig.service index 4261d0cf44..0c055fea0b 100644 --- a/packages/sysutils/systemd/system.d/debugconfig.service +++ b/packages/sysutils/systemd/system.d/debugconfig.service @@ -3,11 +3,11 @@ Description=Setup debug config DefaultDependencies=no After=systemd-tmpfiles-setup.service ConditionKernelCommandLine=|debugging -ConditionPathExists=|/storage/.cache/debug.libreelec +ConditionPathExists=|/storage/.cache/debug.archr [Service] Type=oneshot -ExecStart=/bin/sh -c 'cp /usr/share/debugconf/*.conf /run/libreelec/debug' +ExecStart=/bin/sh -c 'cp /usr/share/debugconf/*.conf /run/archr/debug' RemainAfterExit=yes [Install] diff --git a/packages/sysutils/systemd/tmpfiles.d/z_01_openelec.conf b/packages/sysutils/systemd/tmpfiles.d/z_01_openelec.conf index 07d11f550b..be15677b1f 100644 --- a/packages/sysutils/systemd/tmpfiles.d/z_01_openelec.conf +++ b/packages/sysutils/systemd/tmpfiles.d/z_01_openelec.conf @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-or-later # Copyright (C) 2009-2014 Stephan Raue (stephan@openelec.tv) -d /run/libreelec 0755 root root - - -d /run/libreelec/debug 0755 root root - - +d /run/archr 0755 root root - - +d /run/archr/debug 0755 root root - - diff --git a/packages/sysutils/util-linux/package.mk b/packages/sysutils/util-linux/package.mk index d9bf40a705..63a5ccf645 100644 --- a/packages/sysutils/util-linux/package.mk +++ b/packages/sysutils/util-linux/package.mk @@ -86,8 +86,8 @@ fi post_makeinstall_target() { if [ "${SWAP_SUPPORT}" = "yes" ]; then - mkdir -p ${INSTALL}/usr/lib/libreelec - cp -PR ${PKG_DIR}/scripts/mount-swap ${INSTALL}/usr/lib/libreelec + mkdir -p ${INSTALL}/usr/lib/archr + cp -PR ${PKG_DIR}/scripts/mount-swap ${INSTALL}/usr/lib/archr mkdir -p ${INSTALL}/etc cat ${PKG_DIR}/config/swap.conf | diff --git a/packages/sysutils/util-linux/system.d/swap.service b/packages/sysutils/util-linux/system.d/swap.service index 4bf0f8fb0b..de22a82fe4 100644 --- a/packages/sysutils/util-linux/system.d/swap.service +++ b/packages/sysutils/util-linux/system.d/swap.service @@ -13,8 +13,8 @@ ConditionKernelCommandLine=!installer [Service] Environment=HOME=/storage Type=oneshot -ExecStartPre=/usr/lib/libreelec/mount-swap create -ExecStart=/usr/lib/libreelec/mount-swap mount +ExecStartPre=/usr/lib/archr/mount-swap create +ExecStart=/usr/lib/archr/mount-swap mount RemainAfterExit=yes [Install] diff --git a/packages/textproc/libiconv/package.mk b/packages/textproc/libiconv/package.mk index a9e866c472..1cd7453dfe 100644 --- a/packages/textproc/libiconv/package.mk +++ b/packages/textproc/libiconv/package.mk @@ -6,7 +6,7 @@ PKG_VERSION="1.18" PKG_SHA256="3b08f5f4f9b4eb82f151a7040bfd6fe6c6fb922efe4b1659c66ea933276965e8" PKG_LICENSE="GPL" PKG_SITE="https://savannah.gnu.org/projects/libiconv/" -PKG_URL="https://ftp.gnu.org/pub/gnu/libiconv/${PKG_NAME}-${PKG_VERSION}.tar.gz" +PKG_URL="https://mirrors.kernel.org/gnu/libiconv/${PKG_NAME}-${PKG_VERSION}.tar.gz" PKG_DEPENDS_TARGET="toolchain" PKG_LONGDESC="A tool that converts from one character encoding to another through Unicode conversion." PKG_BUILD_FLAGS="+pic" diff --git a/packages/textproc/libidn2/package.mk b/packages/textproc/libidn2/package.mk index c6ea084983..e1b6a986da 100644 --- a/packages/textproc/libidn2/package.mk +++ b/packages/textproc/libidn2/package.mk @@ -6,7 +6,7 @@ PKG_VERSION="2.3.8" PKG_SHA256="f557911bf6171621e1f72ff35f5b1825bb35b52ed45325dcdee931e5d3c0787a" PKG_LICENSE="LGPL3" PKG_SITE="https://www.gnu.org/software/libidn/" -PKG_URL="https://ftpmirror.gnu.org/gnu/libidn/libidn2-${PKG_VERSION}.tar.gz" +PKG_URL="https://mirrors.kernel.org/gnu/gnu/libidn/libidn2-${PKG_VERSION}.tar.gz" PKG_DEPENDS_HOST="autotools:host" PKG_DEPENDS_TARGET="autotools:host gcc:host" PKG_LONGDESC="Free software implementation of IDNA2008, Punycode and TR46." diff --git a/packages/textproc/xmlstarlet/package.mk b/packages/textproc/xmlstarlet/package.mk index 6921747fe5..d311cc5d57 100644 --- a/packages/textproc/xmlstarlet/package.mk +++ b/packages/textproc/xmlstarlet/package.mk @@ -6,12 +6,16 @@ PKG_VERSION="1.6.1" PKG_SHA256="15d838c4f3375332fd95554619179b69e4ec91418a3a5296e7c631b7ed19e7ca" PKG_LICENSE="MIT" PKG_SITE="http://xmlstar.sourceforge.net" -PKG_URL="http://netcologne.dl.sourceforge.net/project/xmlstar/${PKG_NAME}/${PKG_VERSION}/${PKG_NAME}-${PKG_VERSION}.tar.gz" +PKG_URL="https://downloads.sourceforge.net/project/xmlstar/${PKG_NAME}/${PKG_VERSION}/${PKG_NAME}-${PKG_VERSION}.tar.gz" PKG_DEPENDS_HOST="libxml2:host libxslt:host" PKG_DEPENDS_TARGET="toolchain libxml2 libxslt" PKG_LONGDESC="XMLStarlet is a command-line XML utility which allows the modification and validation of XML documents." PKG_BUILD_FLAGS="-cfg-libs -cfg-libs:host" +pre_configure_host() { + export CFLAGS="${CFLAGS} -Wno-error -Wno-pointer-sign -Wno-incompatible-pointer-types" +} + PKG_CONFIGURE_OPTS_HOST=" ac_cv_func_malloc_0_nonnull=yes \ ac_cv_func_realloc_0_nonnull=yes \ LIBXML_CONFIG=${TOOLCHAIN}/bin/xml2-config \ diff --git a/packages/tools/mtools/package.mk b/packages/tools/mtools/package.mk index cc2b53c8c6..6e82bdb3d8 100644 --- a/packages/tools/mtools/package.mk +++ b/packages/tools/mtools/package.mk @@ -7,7 +7,7 @@ PKG_VERSION="4.0.49" PKG_SHA256="6fe5193583d6e7c59da75e63d7234f76c0b07caf33b103894f46f66a871ffc9f" PKG_LICENSE="GPL" PKG_SITE="http://www.gnu.org/software/mtools/" -PKG_URL="https://ftpmirror.gnu.org/${PKG_NAME}/${PKG_NAME}-${PKG_VERSION}.tar.bz2" +PKG_URL="https://mirrors.kernel.org/gnu/${PKG_NAME}/${PKG_NAME}-${PKG_VERSION}.tar.bz2" PKG_DEPENDS_HOST="autotools:host" PKG_LONGDESC="mtools: A collection of utilities to access MS-DOS disks" PKG_TOOLCHAIN="autotools" diff --git a/packages/virtual/image/package.mk b/packages/virtual/image/package.mk index 04dac096a7..5ccc0c82fc 100644 --- a/packages/virtual/image/package.mk +++ b/packages/virtual/image/package.mk @@ -4,7 +4,7 @@ PKG_NAME="image" PKG_LICENSE="GPL" PKG_SITE="https://libreelec.tv" -PKG_DEPENDS_TARGET="toolchain squashfs-tools:host pigz:host dosfstools:host fakeroot:host kmod:host mtools:host populatefs:host libc gcc linux linux-drivers linux-firmware ${BOOTLOADER} busybox util-linux corefonts network misc-packages debug exfatprogs" +PKG_DEPENDS_TARGET="toolchain squashfs-tools:host pigz:host dosfstools:host fakeroot:host kmod:host mtools:host populatefs:host libc gcc linux linux-drivers linux-firmware ${BOOTLOADER} busybox util-linux corefonts network misc-packages debug exfatprogs coreutils bash grep sed gawk findutils diffutils" PKG_SECTION="virtual" PKG_LONGDESC="Root package used to build and create complete image" diff --git a/packages/web/curl/package.mk b/packages/web/curl/package.mk index f4f34405cf..37235909d0 100644 --- a/packages/web/curl/package.mk +++ b/packages/web/curl/package.mk @@ -46,7 +46,7 @@ PKG_CMAKE_OPTS_TARGET="-DENABLE_DEBUG=OFF \ -DCURL_USE_GNUTLS=OFF \ -DCURL_ENABLE_SSL=ON \ -DCURL_USE_MBEDTLS=OFF \ - -DCURL_CA_BUNDLE=/run/libreelec/cacert.pem \ + -DCURL_CA_BUNDLE=/run/archr/cacert.pem \ -DCURL_CA_PATH=none \ -DCURL_USE_LIBPSL=OFF \ -DCURL_USE_LIBSSH2=OFF \ diff --git a/packages/web/libmicrohttpd/package.mk b/packages/web/libmicrohttpd/package.mk index c901edf174..103c994860 100644 --- a/packages/web/libmicrohttpd/package.mk +++ b/packages/web/libmicrohttpd/package.mk @@ -7,7 +7,7 @@ PKG_VERSION="1.0.1" PKG_SHA256="a89e09fc9b4de34dde19f4fcb4faaa1ce10299b9908db1132bbfa1de47882b94" PKG_LICENSE="LGPLv2.1" PKG_SITE="https://www.gnu.org/software/libmicrohttpd/" -PKG_URL="https://ftpmirror.gnu.org/libmicrohttpd/${PKG_NAME}-${PKG_VERSION}.tar.gz" +PKG_URL="https://mirrors.kernel.org/gnu/libmicrohttpd/${PKG_NAME}-${PKG_VERSION}.tar.gz" PKG_DEPENDS_TARGET="toolchain gnutls" PKG_LONGDESC="A small C library that is supposed to make it easy to run an HTTP server as part of another application." diff --git a/packages/x11/util/xorg-launch-helper/scripts/xorg-launch b/packages/x11/util/xorg-launch-helper/scripts/xorg-launch index ecb623e2e4..8ff4e9c804 100755 --- a/packages/x11/util/xorg-launch-helper/scripts/xorg-launch +++ b/packages/x11/util/xorg-launch-helper/scripts/xorg-launch @@ -5,7 +5,7 @@ # wait for xorg-configure@.service # max 10 seconds -ARGS_FILE="/run/libreelec/xorg-settings.conf" +ARGS_FILE="/run/archr/xorg-settings.conf" for i in $(seq 1 40); do if [ -e "$ARGS_FILE" ]; then break @@ -14,7 +14,7 @@ for i in $(seq 1 40); do done if [ -e "$ARGS_FILE" ]; then - . /run/libreelec/xorg-settings.conf + . /run/archr/xorg-settings.conf exec xorg-launch-helper $@ $XORG_ARGS else echo "" >/dev/tty1 diff --git a/packages/x11/xserver/xorg-server/scripts/xorg-configure b/packages/x11/xserver/xorg-server/scripts/xorg-configure index 737a1922d0..976aee67f5 100755 --- a/packages/x11/xserver/xorg-server/scripts/xorg-configure +++ b/packages/x11/xserver/xorg-server/scripts/xorg-configure @@ -86,5 +86,5 @@ fi ################################################################################ logger -t Xorg "### starting Xorg with '${DISPLAY} vt01 ${XORG_ARGS}' ###" -mkdir -p /run/libreelec -echo "XORG_ARGS=\"${XORG_ARGS}\"" >/run/libreelec/xorg-settings.conf +mkdir -p /run/archr +echo "XORG_ARGS=\"${XORG_ARGS}\"" >/run/archr/xorg-settings.conf diff --git a/packages/x11/xserver/xorg-server/system.d/xorg.service b/packages/x11/xserver/xorg-server/system.d/xorg.service index a9dbde6893..1721ed6d9c 100644 --- a/packages/x11/xserver/xorg-server/system.d/xorg.service +++ b/packages/x11/xserver/xorg-server/system.d/xorg.service @@ -6,7 +6,7 @@ ConditionKernelCommandLine=!installer [Service] Type=notify -EnvironmentFile=-/run/libreelec/debug/xorg.conf +EnvironmentFile=-/run/archr/debug/xorg.conf ExecStart=/usr/bin/xorg-launch -nolisten tcp vt01 $XORG_DEBUG Restart=always RestartSec=2 diff --git a/projects/ArchR/bootloader/mkimage b/projects/ArchR/bootloader/mkimage new file mode 100644 index 0000000000..914891d6ea --- /dev/null +++ b/projects/ArchR/bootloader/mkimage @@ -0,0 +1,114 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +. config/functions + +mkimage_uboot() { + if [ -f "${RELEASE_DIR}/3rdparty/bootloader/${SUBDEVICE}_uboot.bin" ]; then + # RK3566-Generic and RK3566-Powkiddy_x55 + echo "image: writing ${SUBDEVICE}_uboot.bin to $(basename "${DISK}")..." + dd if="${RELEASE_DIR}/3rdparty/bootloader/${SUBDEVICE}_uboot.bin" of="${DISK}" bs=512 seek=64 conv=sync,noerror,notrunc >"${SAVE_ERROR}" 2>&1 || show_error + elif [ -f "${RELEASE_DIR}/3rdparty/bootloader/uboot.bin" ]; then + echo "image: writing uboot.bin to $(basename "${DISK}")..." + dd if="${RELEASE_DIR}/3rdparty/bootloader/uboot.bin" of="${DISK}" bs=512 seek=64 conv=sync,noerror,notrunc >"${SAVE_ERROR}" 2>&1 || show_error + elif [ -f "${RELEASE_DIR}/3rdparty/bootloader/u-boot.bin" ]; then + # S922X + echo "image: writing u-boot.bin to $(basename "${DISK}")..." + dd if="${RELEASE_DIR}/3rdparty/bootloader/u-boot.bin" of="${DISK}" bs=512 seek=1 conv=sync,noerror,notrunc >"${SAVE_ERROR}" 2>&1 || show_error + elif [ -f "${RELEASE_DIR}/3rdparty/bootloader/u-boot-sunxi-with-spl.bin" ]; then + # H700 + echo "image: writing u-boot-sunxi-with-spl.bin to $(basename "${DISK}")..." + dd if="${RELEASE_DIR}/3rdparty/bootloader/u-boot-sunxi-with-spl.bin" of="${DISK}" bs=1K seek=8 conv=fsync,notrunc >"${SAVE_ERROR}" 2>&1 || show_error + elif [ -f "${RELEASE_DIR}/3rdparty/bootloader/archr-u-boot.img" ]; then + # SM8650 & SM8550 + echo "image: copying archr u-boot files..." + mcopy -o "${RELEASE_DIR}/3rdparty/bootloader/archr-u-boot.img" :: + mcopy -s -o "${RELEASE_DIR}/3rdparty/bootloader/device_trees" :: + else + echo "ERROR no u-boot file found for ${SUBDEVICE}" + fi +} + +mkimage_extlinux() { + if [ -d "${RELEASE_DIR}/3rdparty/bootloader/extlinux" ]; then + echo "image: copying custom extlinux.conf..." + mcopy -s -o "${RELEASE_DIR}/3rdparty/bootloader/extlinux" :: + else + local fdt_type + fdt_type=$(get_fdt_type) + + echo "image: set extlinux.conf to $fdt_type /$(get_fdt)..." + mkdir -p "${IMG_TMP}/extlinux" + + cat << EOF > "${IMG_TMP}/extlinux/extlinux.conf" +LABEL ${DISTRO} + LINUX /${KERNEL_NAME} + ${fdt_type} /$(get_fdt) + APPEND boot=LABEL=${DISTRO_BOOTLABEL} root=LABEL=${DISTRO_ROOTLABEL} disk=LABEL=${DISTRO_DISKLABEL} ${EXTRA_CMDLINE} +EOF + + echo "image: copying extlinux.conf..." + mcopy -s -o "${IMG_TMP}/extlinux" :: + fi +} + +mkimage_bootscr() { + if [ -f "${RELEASE_DIR}/3rdparty/bootloader/${SUBDEVICE}_boot.scr" ]; then + echo "image: copying ${SUBDEVICE}_boot.scr..." + mcopy "${RELEASE_DIR}/3rdparty/bootloader/${SUBDEVICE}_boot.scr" ::/boot.scr + else + echo "cannot find ${RELEASE_DIR}/3rdparty/bootloader/${SUBDEVICE}_boot.scr" + exit 2 + fi +} + +mkimage_dtb() { + echo "image: copying device trees..." + case "$DEVICE" in + RK3326) + mmd ::dtbs 2>/dev/null || true + mcopy "${RELEASE_DIR}/3rdparty/bootloader/device_trees/"*.dtb ::dtbs/ + mcopy "${RELEASE_DIR}/3rdparty/bootloader/stock" :: + # Copy SUBDEVICE-specific panel overlays, fallback to generic + if [ -d "${RELEASE_DIR}/3rdparty/bootloader/overlays_${SUBDEVICE}" ]; then + echo "image: copying ${SUBDEVICE} panel overlays..." + mmd ::overlays 2>/dev/null || true + mcopy "${RELEASE_DIR}/3rdparty/bootloader/overlays_${SUBDEVICE}/"*.dtbo ::overlays/ + elif [ -d "${RELEASE_DIR}/3rdparty/bootloader/overlays" ]; then + mcopy "${RELEASE_DIR}/3rdparty/bootloader/overlays" :: + fi + ;; + SM8550|SM8650|SM8250|SDM845) + mcopy -s -o "${RELEASE_DIR}/3rdparty/bootloader/boot" :: + ;; + S922X) + mcopy "${RELEASE_DIR}/3rdparty/bootloader/"*.dtb :: + ;; + *) + mcopy -s "${RELEASE_DIR}/3rdparty/bootloader/device_trees" :: + ;; + esac + + # For devices not handled above (RK3326 handles overlays in its own case) + if [ "$DEVICE" != "RK3326" ] && [ -d "${RELEASE_DIR}/3rdparty/bootloader/overlays" ]; then + echo "image: copying device tree overlays..." + mcopy -s "${RELEASE_DIR}/3rdparty/bootloader/overlays" :: + fi +} + +mkimage_gou_extras() { + echo "image: copying res..." + mcopy "${RELEASE_DIR}/3rdparty/bootloader/res" :: +} + +mkimage_grub() { + echo "image: copying grub files and dtb..." + mcopy -s -o "${RELEASE_DIR}/3rdparty/bootloader/EFI" :: +} + +mkimage_abl() { + echo "image: copying ArchR ABL..." + mcopy "${RELEASE_DIR}/3rdparty/bootloader/archr_abl" :: +} + +mkimage_all diff --git a/projects/ArchR/bootloader/release b/projects/ArchR/bootloader/release new file mode 100644 index 0000000000..4a0cb20a50 --- /dev/null +++ b/projects/ArchR/bootloader/release @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +mkdir -p ${RELEASE_DIR}/3rdparty/bootloader + cp -a ${INSTALL}/usr/share/bootloader/* ${RELEASE_DIR}/3rdparty/bootloader diff --git a/projects/ArchR/bootloader/rkhelper b/projects/ArchR/bootloader/rkhelper new file mode 100644 index 0000000000..a4f4a869f6 --- /dev/null +++ b/projects/ArchR/bootloader/rkhelper @@ -0,0 +1,60 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://arch-r.io) + +PKG_SOC="${DEVICE/RK/rk}" + +# Make idbloader.img +case "${DEVICE}" in + RK3326) + # mkimage does not support packing second level bootloader on rk3326 + ${PKG_BUILD}/tools/mkimage -n px30 -T rksd -d "${PKG_DDR_BIN}" -C bzip2 idbloader.img + cat ${PKG_MINILOADER} >> idbloader.img + ;; + RK3399|RK3566|RK3588) + [ "${PKG_SOC}" = "rk3566" ] && PKG_SOC="rk3568" + ${PKG_BUILD}/tools/mkimage -n "${PKG_SOC}" -T rksd -d "${PKG_DDR_BIN}":"${PKG_MINILOADER}" -C bzip2 idbloader.img + ;; +esac + +# Pack uboot.img +case "${DEVICE}" in + RK3326|RK3399) + ${PKG_RKBIN}/tools/loaderimage --pack --uboot u-boot-dtb.bin uboot.img 0x00200000 + ;; +esac + +# Merge trust.img +case "${DEVICE}" in + RK3326) + cat >trust.ini < + + + rk3326-gameconsole-r36s + rk3326-gameconsole-r33s + rk3326-odroid-go2 + rk3326-odroid-go2-v11 + rk3326-odroid-go3 + rk3326-anbernic-rg351m + rk3326-anbernic-rg351v + rk3326-gameforce-chi + rk3326-magicx-xu10 + rk3326-powkiddy-rgb10 + + + rk3326-gameconsole-eeclone + rk3326-powkiddy-rgb10x + rk3326-magicx-xu-mini-m + rk3326-odroid-go2 + + + diff --git a/projects/ArchR/devices/RK3326/bootloader/update.sh b/projects/ArchR/devices/RK3326/bootloader/update.sh new file mode 100755 index 0000000000..39bd5bd99a --- /dev/null +++ b/projects/ArchR/devices/RK3326/bootloader/update.sh @@ -0,0 +1,98 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-24 JELOS (https://github.com/JustEnoughLinuxOS) +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +[ -z "$SYSTEM_ROOT" ] && SYSTEM_ROOT="" +[ -z "$BOOT_ROOT" ] && BOOT_ROOT="/flash" +[ -z "$BOOT_PART" ] && BOOT_PART=$(df "$BOOT_ROOT" | tail -1 | awk {' print $1 '}) + +# mount $BOOT_ROOT rw +mount -o remount,rw $BOOT_ROOT + +# Setup logging +echo -n > $BOOT_ROOT/update.log +log() { echo $*; echo $* >> $BOOT_ROOT/update.log; } +log "Starting bootloader update" + +# identify the boot device +if [ -z "$BOOT_DISK" ]; then + case $BOOT_PART in + /dev/mmcblk*) BOOT_DISK=$(echo $BOOT_PART | sed -e "s,p[0-9]*,,g");; + esac +fi + +SUBDEVICE=$(sed -n 's|^.* uboot.hwid_adc=\([^, ]\),.*$|\1|p' /proc/cmdline) +if [ -n "$SUBDEVICE" ]; then + log "Subdevice from cmdline: $SUBDEVICE" +elif [ -f $BOOT_ROOT/boot.scr ]; then + grep -q "rk3326-anbernic-rg351m.dtb" $BOOT_ROOT/boot.scr && SUBDEVICE=a || SUBDEVICE=b + log "Subdevice from boot.scr: $SUBDEVICE" +elif [ -f $BOOT_ROOT/boot.ini ]; then + grep -q "rk3326-anbernic-rg351m.dtb" $BOOT_ROOT/boot.ini && SUBDEVICE=a || SUBDEVICE=b + log "Subdevice from boot.ini: $SUBDEVICE" +else + SUBDEVICE=a + log "Subdevice fallback: $SUBDEVICE" +fi + +log "Updating device trees..." +if [ -d "$BOOT_ROOT/device_trees" ]; then + mv $BOOT_ROOT/device_trees/*.dtb $BOOT_ROOT + rm -rf $BOOT_ROOT/device_trees +fi +cp -f $SYSTEM_ROOT/usr/share/bootloader/device_trees/* $BOOT_ROOT + +if [ -d $SYSTEM_ROOT/usr/share/bootloader/overlays ]; then + log "Updating device tree overlays..." + mkdir -p $BOOT_ROOT/overlays + cp -f $SYSTEM_ROOT/usr/share/bootloader/overlays/* $BOOT_ROOT/overlays +fi + +if [ ! -f $BOOT_ROOT/extlinux/extlinux.conf ]; then + log "Creating extlinux.conf..." + mkdir -p $BOOT_ROOT/extlinux + cp -f $SYSTEM_ROOT/usr/share/bootloader/extlinux/* $BOOT_ROOT/extlinux/ +fi + +CONSOLEDEV=$(grep -l Y /sys/devices/platform/*/*/*/tty/tty*/console | head -1 | xargs -r dirname) +if [ "${SUBDEVICE}" == "original" ]; then + log "Using legacy u-boot " + UBOOT_VARIANT="original_uboot.bin" +elif [ -z "${CONSOLEDEV}" ]; then + log "Cannot find UART console" + UBOOT_VARIANT="clone_uboot.bin" +elif grep -qi ff178000 "${CONSOLEDEV}/iomem_base"; then + log "Detected UART5 console at ${CONSOLEDEV}" + UBOOT_VARIANT="clone_uboot.bin.uart5" +else + log "Assuming default (UART2) console at ${CONSOLEDEV}" + UBOOT_VARIANT="clone_uboot.bin" +fi + +for BOOT_IMAGE in ${UBOOT_VARIANT} uboot.bin clone_uboot.bin; do + if [ -f "$SYSTEM_ROOT/usr/share/bootloader/$BOOT_IMAGE" ]; then + log "Updating $BOOT_IMAGE on $BOOT_DISK..." + # instead of using small bs, read the missing part from target and do a perfectly aligned write + { + dd if=$BOOT_DISK bs=32K count=1 + cat $SYSTEM_ROOT/usr/share/bootloader/$BOOT_IMAGE + } | dd of=$BOOT_DISK bs=4M conv=fsync &>/dev/null + break + fi +done + +log "Updating boot.scr from ${SUBDEVICE}_boot.scr..." +cp -f $SYSTEM_ROOT/usr/share/bootloader/${SUBDEVICE}_boot.scr $BOOT_ROOT/boot.scr +# prevent interference (especially with legacy u-boot) +if [ -f $BOOT_ROOT/boot.ini ]; then + mv $BOOT_ROOT/boot.ini $BOOT_ROOT/boot.ini.bak +fi + +log "Finishing bootloader update..." +# mount $BOOT_ROOT ro +sync +mount -o remount,ro $BOOT_ROOT + +echo "UPDATE" > /storage/.boot.hint +echo "DONE" diff --git a/projects/ArchR/devices/RK3326/linux/dts/rockchip/retrogame_joypad_s2_f1.dtsi b/projects/ArchR/devices/RK3326/linux/dts/rockchip/retrogame_joypad_s2_f1.dtsi new file mode 100644 index 0000000000..7a0f231091 --- /dev/null +++ b/projects/ArchR/devices/RK3326/linux/dts/rockchip/retrogame_joypad_s2_f1.dtsi @@ -0,0 +1,122 @@ +/* + This is a skeleton of joypad with 2 sticks and FN (MODE) button. + Fits devices with 1 stick and 2 extra face buttons too. + By including this ans setting I/O properties only, + devices should get consistent controller id and mapping + thus reusing non-game configs: + * SDL gamecontrollerdb.txt + * ES es_input.cfg + * Retroarch gamepad +*/ + +/ { + joypad: retrogame_joypad_s2_f1 { + /* These drivers emit the same button set which makes this skeleton ADC-agnostic */ + /* compatible = "archr-joypad"; */ + /* compatible = "archr-singleadc-joypad"; */ + + /* These are constants making Joystick Guid the same */ + joypad-name = "retrogame_joypad_s2_f1"; + joypad-vendor = <0x484B>; + joypad-product = <0x1121>; /* 11 inherited, 2 for number of sticks, 1 for number of FN */ + joypad-revision = <0x0100>; + + /* require explicit status = "okay"; */ + status = "disabled"; + + /* adc calculate scale */ + button-adc-scale = <2>; + + /* adc deadzone range */ + button-adc-deadzone = <64>; + + /* + specifies fuzz value that is used to filter noise from + the event stream. + */ + button-adc-fuzz = <32>; + button-adc-flat = <32>; + + /* poll device interval (ms), adc read interval */ + poll-interval = <10>; + + /* gpio button auto repeat set value : default disable */ + /* + autorepeat; + */ + + /* meaningful node names for easier use */ + up { + label = "GPIO DPAD-UP"; + linux,code = ; + }; + down { + label = "GPIO DPAD-DOWN"; + linux,code = ; + }; + left { + label = "GPIO DPAD-LEFT"; + linux,code = ; + }; + right { + label = "GPIO DPAD-RIGHT"; + linux,code = ; + }; + + a { + label = "GPIO BTN-A"; + linux,code = ; + }; + b { + label = "GPIO BTN-B"; + linux,code = ; + }; + x { + label = "GPIO BTN-X"; + linux,code = ; + }; + y { + label = "GPIO BTN-Y"; + linux,code = ; + }; + + select { + label = "GPIO BTN_SELECT"; + linux,code = ; + }; + start { + label = "GPIO BTN_START"; + linux,code = ; + }; + mode { + label = "GPIO BTN_F"; + linux,code = ; + }; + + tl { + label = "GPIO BTN_TL"; + linux,code = ; + }; + tr { + label = "GPIO BTN_TR"; + linux,code = ; + }; + tl2 { + label = "GPIO BTN_TL2"; + linux,code = ; + }; + tr2 { + label = "GPIO BTN_TR2"; + linux,code = ; + }; + + thumbl { + label = "GPIO BTN_THUMBL"; + linux,code = ; + }; + thumbr { + label = "GPIO BTN_THUMBR"; + linux,code = ; + }; + }; +}; diff --git a/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-anbernic-rg351m.dts b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-anbernic-rg351m.dts new file mode 100644 index 0000000000..c12bb79944 --- /dev/null +++ b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-anbernic-rg351m.dts @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Hardkernel Co., Ltd + * Copyright (c) 2020 Theobroma Systems Design und Consulting GmbH + * Copyright (c) 2022 Maya Matuszczyk + */ + +/dts-v1/; +#include "rk3326-odroid-go.dtsi" + +/ { + model = "Anbernic RG351M"; + compatible = "anbernic,rg351m", "rockchip,rk3326"; + + battery: battery { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <3500000>; + charge-term-current-microamp = <350000>; + constant-charge-current-max-microamp = <2000000>; + constant-charge-voltage-max-microvolt = <4200000>; + factory-internal-resistance-micro-ohms = <180000>; + voltage-max-design-microvolt = <4100000>; + voltage-min-design-microvolt = <3500000>; + + ocv-capacity-celsius = <20>; + ocv-capacity-table-0 = <4046950 100>, <4001920 95>, <3967900 90>, <3919950 85>, + <3888450 80>, <3861850 75>, <3831540 70>, <3799130 65>, + <3768190 60>, <3745650 55>, <3726610 50>, <3711630 45>, + <3696720 40>, <3685660 35>, <3674950 30>, <3663050 25>, + <3649470 20>, <3635260 15>, <3616920 10>, <3592440 5>, + <3574170 0>; + }; + + vibrator { + compatible = "pwm-vibrator"; + pwms = <&pwm0 0 1000000 0>; + pwm-names = "enable"; + }; +}; + +/delete-node/ &vcc_host; /* conflicts with pwm vibration motor */ + +&internal_display { + compatible = "elida,kd35t133"; + iovcc-supply = <&vcc_lcd>; + vdd-supply = <&vcc_lcd>; + rotation = <270>; +}; + +&pwm0 { + status = "okay"; +}; + +&rk817_charger { + /* This device does not have a current sense resistor */ + //rockchip,resistor-sense-micro-ohms = <0>; + monitored-battery = <&battery>; +}; diff --git a/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-anbernic-rg351m.dtsi b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-anbernic-rg351m.dtsi new file mode 100644 index 0000000000..1dadde198c --- /dev/null +++ b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-anbernic-rg351m.dtsi @@ -0,0 +1,480 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Hardkernel Co., Ltd + * Copyright (c) 2020 Theobroma Systems Design und Consulting GmbH + * Copyright (c) 2022 Maya Matuszczyk + */ + +/dts-v1/; +#include +#include +#include +#include +#include "rk3326.dtsi" + +/ { + aliases { + mmc0 = &sdmmc; + }; + + chosen { + stdout-path = "serial2:115200n8"; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + power-supply = <&vcc_bl>; + pwms = <&pwm1 0 25000 0>; + }; + + /* + * LED is a tri-state. Driven high it is red, driven low it is + * green, and not driven at all (pin set to input) it is amber. + * Additionally, there is a 2nd LED that is not controllable + * that is on (red) when plugged in to power. + */ + gpio_led: gpio-leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&led_pin>; + + red_green_led: led-0 { + color = ; + gpios = <&gpio2 RK_PB5 GPIO_ACTIVE_HIGH>; + function = LED_FUNCTION_CHARGING; + }; + }; + + rk817-sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "rk817_int"; + simple-audio-card,format = "i2s"; + simple-audio-card,hp-det-gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Headphone", "Headphones", + "Speaker", "Speaker"; + simple-audio-card,routing = + "MICL", "Mic Jack", + "Headphones", "HPOL", + "Headphones", "HPOR", + "Speaker", "SPKO"; + + simple-audio-card,codec { + sound-dai = <&rk817>; + }; + + simple-audio-card,cpu { + sound-dai = <&i2s1_2ch>; + }; + }; + + vccsys: regulator-vccsys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v8_sys"; + regulator-always-on; + regulator-min-microvolt = <3800000>; + regulator-max-microvolt = <3800000>; + }; + + vibrator { + compatible = "pwm-vibrator"; + pwms = <&pwm0 0 1000000 0>; + pwm-names = "enable"; + }; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&cpu1 { + cpu-supply = <&vdd_arm>; +}; + +&cpu2 { + cpu-supply = <&vdd_arm>; +}; + +&cpu3 { + cpu-supply = <&vdd_arm>; +}; + +&cru { + assigned-clocks = <&cru PLL_NPLL>, + <&cru ACLK_BUS_PRE>, <&cru ACLK_PERI_PRE>, + <&cru HCLK_BUS_PRE>, <&cru HCLK_PERI_PRE>, + <&cru PCLK_BUS_PRE>, <&cru SCLK_GPU>; + + assigned-clock-rates = <1188000000>, + <200000000>, <200000000>, + <150000000>, <150000000>, + <100000000>, <200000000>; +}; + +&display_subsystem { + status = "okay"; +}; + +&dsi { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + ports { + mipi_out: port@1 { + reg = <1>; + + mipi_out_panel: endpoint { + remote-endpoint = <&mipi_in_panel>; + }; + }; + }; + + internal_display: panel@0 { + reg = <0>; + backlight = <&backlight>; + reset-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>; + + port { + mipi_in_panel: endpoint { + remote-endpoint = <&mipi_out_panel>; + }; + }; + }; +}; + +&dsi_dphy { + status = "okay"; +}; + +&gpu { + mali-supply = <&vdd_logic>; + status = "okay"; +}; + +&i2c0 { + clock-frequency = <400000>; + i2c-scl-falling-time-ns = <16>; + i2c-scl-rising-time-ns = <280>; + status = "okay"; + + rk817: pmic@20 { + compatible = "rockchip,rk817"; + reg = <0x20>; + #clock-cells = <1>; + clock-names = "mclk"; + clock-output-names = "rk808-clkout1", "xin32k"; + clocks = <&cru SCLK_I2S1_OUT>; + interrupt-parent = <&gpio0>; + interrupts = ; + pinctrl-0 = <&pmic_int>, <&i2s1_2ch_mclk>; + pinctrl-names = "default"; + #sound-dai-cells = <0>; + wakeup-source; + + vcc1-supply = <&vccsys>; + vcc2-supply = <&vccsys>; + vcc3-supply = <&vccsys>; + vcc4-supply = <&vccsys>; + vcc5-supply = <&vccsys>; + vcc6-supply = <&vccsys>; + vcc7-supply = <&vccsys>; + vcc8-supply = <&vccsys>; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1150000>; + regulator-min-microvolt = <950000>; + regulator-name = "vdd_logic"; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vdd_arm: DCDC_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1350000>; + regulator-min-microvolt = <950000>; + regulator-name = "vdd_arm"; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-name = "vcc_ddr"; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_3v3: DCDC_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "vcc_3v3"; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_1v8: LDO_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-name = "vcc_1v8"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd_1v0: LDO_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1000000>; + regulator-min-microvolt = <1000000>; + regulator-name = "vdd_1v0"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc3v3_pmu: LDO_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "vcc3v3_pmu"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vccio_sd: LDO_REG5 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <1800000>; + regulator-name = "vccio_sd"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_sd: LDO_REG6 { + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "vcc_sd"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_bl: LDO_REG7 { + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "vcc_bl"; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_lcd: LDO_REG8 { + regulator-max-microvolt = <2800000>; + regulator-min-microvolt = <2800000>; + regulator-name = "vcc_lcd"; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <2800000>; + }; + }; + + vcc_wifi: LDO_REG9 { + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "vcc_wifi"; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + usb_midu: BOOST { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <5400000>; + regulator-min-microvolt = <5000000>; + regulator-name = "usb_midu"; + }; + }; + + rk817_codec: codec { + rockchip,mic-in-differential; + }; + }; +}; + +&i2s1_2ch { + status = "okay"; +}; + +&io_domains { + vccio1-supply = <&vcc_3v3>; + vccio2-supply = <&vccio_sd>; + vccio3-supply = <&vcc_3v3>; + vccio4-supply = <&vcc_3v3>; + vccio5-supply = <&vcc_3v3>; + vccio6-supply = <&vcc_3v3>; + status = "okay"; +}; + +&pmu_io_domains { + pmuio1-supply = <&vcc3v3_pmu>; + pmuio2-supply = <&vcc3v3_pmu>; + status = "okay"; +}; + +&pwm0 { + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; + +&saradc { + vref-supply = <&vcc_1v8>; + status = "okay"; +}; + +&sdmmc { + cap-sd-highspeed; + card-detect-delay = <200>; + cd-gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_LOW>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&sfc { + #address-cells = <1>; + pinctrl-0 = <&sfc_clk &sfc_cs0 &sfc_bus2>; + pinctrl-names = "default"; + #size-cells = <0>; + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <108000000>; + spi-rx-bus-width = <2>; + spi-tx-bus-width = <1>; + }; +}; + +&tsadc { + status = "okay"; +}; + +&u2phy { + status = "okay"; + + u2phy_host: host-port { + status = "okay"; + }; + + u2phy_otg: otg-port { + status = "disabled"; + }; +}; + +&usb20_otg { + status = "okay"; +}; + +&uart2 { + pinctrl-0 = <&uart2m1_xfer>; + pinctrl-names = "default"; + status = "okay"; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; + +&pinctrl { + headphone { + hp_det: hp-det { + rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; + + leds { + led_pin: led-pin { + rockchip,pins = <2 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pmic { + dc_det: dc-det { + rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + pmic_int: pmic-int { + rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + soc_slppin_gpio: soc_slppin_gpio { + rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>; + }; + + soc_slppin_rst: soc_slppin_rst { + rockchip,pins = <0 RK_PA4 2 &pcfg_pull_none>; + }; + + soc_slppin_slp: soc_slppin_slp { + rockchip,pins = <0 RK_PA4 1 &pcfg_pull_none>; + }; + }; +}; diff --git a/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-anbernic-rg351v.dts b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-anbernic-rg351v.dts new file mode 100644 index 0000000000..26658a37f4 --- /dev/null +++ b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-anbernic-rg351v.dts @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Hardkernel Co., Ltd + * Copyright (c) 2020 Theobroma Systems Design und Consulting GmbH + * Copyright (c) 2022 Maya Matuszczyk + */ + +/dts-v1/; +#include "rk3326-odroid-go.dtsi" + +/ { + model = "Anbernic RG351V"; + compatible = "anbernic,rg351v", "rockchip,rk3326"; + + aliases { + mmc0 = &sdio; + mmc1 = &sdmmc; + }; + + gpio-keys-vol { + compatible = "gpio-keys"; + autorepeat; + pinctrl-0 = <&btn_pins_vol>; + pinctrl-names = "default"; + + button-vol-down { + gpios = <&gpio2 RK_PA1 GPIO_ACTIVE_LOW>; + label = "VOLUMEDOWN"; + linux,code = ; + }; + + button-volume-up { + gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; + label = "VOLUMEUP"; + linux,code = ; + }; + }; + + battery: battery { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <3500000>; + charge-term-current-microamp = <350000>; + constant-charge-current-max-microamp = <2000000>; + constant-charge-voltage-max-microvolt = <4200000>; + factory-internal-resistance-micro-ohms = <180000>; + voltage-max-design-microvolt = <4100000>; + voltage-min-design-microvolt = <3500000>; + + ocv-capacity-celsius = <20>; + ocv-capacity-table-0 = <4046950 100>, <4001920 95>, <3967900 90>, <3919950 85>, + <3888450 80>, <3861850 75>, <3831540 70>, <3799130 65>, + <3768190 60>, <3745650 55>, <3726610 50>, <3711630 45>, + <3696720 40>, <3685660 35>, <3674950 30>, <3663050 25>, + <3649470 20>, <3635260 15>, <3616920 10>, <3592440 5>, + <3574170 0>; + }; + + vibrator { + compatible = "pwm-vibrator"; + pwms = <&pwm0 0 1000000 0>; + pwm-names = "enable"; + }; +}; + +/* conflicts with pwm vibration motor */ +/delete-node/ &vcc_host; + +/* Device only has 1 LED compared to Odroid Go Advance */ +/delete-node/ &gpio_led; + +&internal_display { + compatible = "anbernic,rg351v-panel", "newvision,nv3051d"; + iovcc-supply = <&vcc_lcd>; + vdd-supply = <&vcc_lcd>; +}; + +&io_domains { + vccio1-supply = <&vccio_sd>; +}; + +/delete-node/ &pwm_led; + +&pwm0 { + status = "okay"; +}; + +/delete-node/ &pwm3; + +&rk817_charger { + /* This device does not have a current sense resistor */ + rockchip,resistor-sense-micro-ohms = <0>; + monitored-battery = <&battery>; +}; + +&sdio { + cap-sd-highspeed; + card-detect-delay = <200>; + cd-gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; /*[> CD GPIO <]*/ + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&vcc_sd { + regulator-max-microvolt = <3000000>; + regulator-min-microvolt = <1800000>; +}; + +&vccio_sd { + regulator-max-microvolt = <1800000>; +}; + +&pinctrl { + btns { + btn_pins_vol: btn-pins-vol { + rockchip,pins = <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; diff --git a/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-batlexp-g350.dts b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-batlexp-g350.dts new file mode 100644 index 0000000000..9cad95fc57 --- /dev/null +++ b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-batlexp-g350.dts @@ -0,0 +1,163 @@ +/// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* +* Copyright (c) 2025 lcdyk <2670878301@qq.com> +*/ + +/dts-v1/; +#include "rk3326-gameconsole-r3xs.dtsi" +#include "retrogame_joypad_s2_f1.dtsi" + +/ { + model = "BatleXP G350"; + compatible = "batlexp,g350", "rockchip,rk3326"; +}; + +&joypad { + compatible = "archr-singleadc-joypad"; + pwms = <&pwm0 0 200000000 0>; + pwm-names = "enable"; + rumble-boost-weak = <0x0000>; + rumble-boost-strong = <0x0000>; + joypad-name = "retrogame_joypad"; + joypad-vendor = <0x484B>; + joypad-product = <0x1101>; + joypad-revision = <0x0100>; + + status = "okay"; + + /* gpio pincontrol setup */ + pinctrl-names = "default"; + pinctrl-0 = <&btn_pins>; + pinctrl-1 = <&pwm0_pin>; + + /* Analog mux define */ + io-channel-names = "amux_adc"; + io-channels = <&saradc 1>; + + /* adc mux channel count */ + amux-count = <4>; + /* non-default wiring */ + amux-channel-mapping = <2 0 1 3>; + /* adc mux enable gpio */ + amux-a-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>; + amux-b-gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_LOW>; + /* adc mux enable gpio */ + amux-en-gpios = <&gpio3 RK_PB5 GPIO_ACTIVE_LOW>; + + /* + Analog Stick data tuning value(precent) + p = positive direction, n = negative direction + report value = (real_adc_data * tuning_value) / 100 + */ + abs_x-p-tuning = <200>; + abs_x-n-tuning = <200>; + + abs_y-p-tuning = <200>; + abs_y-n-tuning = <200>; + + abs_rx-p-tuning = <200>; + abs_rx-n-tuning = <200>; + + abs_ry-p-tuning = <200>; + abs_ry-n-tuning = <200>; + + /* gpio button auto repeat set value : default disable */ + /* + autorepeat; + */ + invert-absx; + invert-absy; + invert-absrx; + + up { gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>; }; + down { gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_LOW>; }; + left { gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; }; + right { gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_LOW>; }; + a { gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>; }; + b { gpios = <&gpio1 RK_PA5 GPIO_ACTIVE_LOW>; }; + x { gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_LOW>; }; + y { gpios = <&gpio1 RK_PA6 GPIO_ACTIVE_LOW>; }; + select { gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>; }; + start { gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; }; + mode { gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_LOW>; }; + tl { gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_LOW>; }; + tr { gpios = <&gpio2 RK_PA7 GPIO_ACTIVE_LOW>; }; + tl2 { gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; }; + tr2 { gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; }; + thumbl { gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; }; + thumbr { gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; }; +}; + +&dsi { + internal_display: panel@0 { + compatible = "archr,generic-dsi"; + iovcc-supply = <&vcc_lcd>; + vcc-supply = <&vcc_lcd>; + reset-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>; + panel_description = + "G size=52,70 delays=20,150,20,120,20 format=rgb888 lanes=4 flags=0xe03", + + "M clock=50000 horizontal=640,450,70,450 vertical=480,17,5,13 default=1", + "M clock=50000 horizontal=640,450,85,450 vertical=480,17,106,13", + "M clock=50010 horizontal=640,450,127,450 vertical=480,17,90,13", + "M clock=50010 horizontal=640,450,73,450 vertical=480,17,110,13", + "M clock=50830 horizontal=640,450,85,450 vertical=480,17,34,13", + "M clock=53200 horizontal=640,450,128,450 vertical=480,17,24,13", + "M clock=50400 horizontal=640,450,77,450 vertical=480,17,10,13", + "M clock=50310 horizontal=640,450,85,450 vertical=480,17,6,13", + "M clock=54600 horizontal=640,450,94,450 vertical=480,17,46,13", + "M clock=65370 horizontal=640,450,113,450 vertical=480,17,14,13", + "M clock=76050 horizontal=640,450,85,450 vertical=480,17,10,13", + "M clock=100620 horizontal=640,450,85,450 vertical=480,17,6,13", + + "I seq=b9f11283", + "I seq=b1000000da80", + "I seq=b2001370", + "I seq=b31010282803ff00000000", + "I seq=b480", + "I seq=b50a0a", + "I seq=b67f7f", + "I seq=b82662f063", + "I seq=ba338105f90e0e2000000000000000442500900a0000014f01000037", + "I seq=bc47", + "I seq=bf021100", + "I seq=c0737350500000125000", + "I seq=c15300323277d1cccc77773333", + "I seq=c68200bfff00ff", + "I seq=c7b8000a000000", + "I seq=c810401e02", + "I seq=cc0b", + "I seq=e000070d37353f4144060c0d0f111012141a00070d37353f4144060c0d0f111012141a", + "I seq=e307070b0b0b0b00000000ff00c010", + "I seq=e9c810020000b0b11131232880b0b127080004020000000004020000008888ba60240888888888888888ba713518888888888800000001000000000000000000", + "I seq=ea970a820203070000000000008188ba17538888888888888088ba0642888888888888230000028000000000000000000000000000000000000000000000", + "I seq=efffff01", + "I seq=11 wait=200", + "I seq=29 wait=50"; + }; +}; + +&pinctrl { + btns { + btn_pins: btn-pins { + rockchip,pins = + <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; diff --git a/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-device-group-r36.dtsi b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-device-group-r36.dtsi new file mode 100644 index 0000000000..bfc399984a --- /dev/null +++ b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-device-group-r36.dtsi @@ -0,0 +1,7 @@ +/ { + archr,device_switch { + r33s = "rk3326-gameconsole-r33s"; + r36s = "rk3326-gameconsole-r36s"; + rgb10x = "rk3326-powkiddy-rgb10x"; + }; +}; diff --git a/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-gameconsole-eeclone.dts b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-gameconsole-eeclone.dts new file mode 100644 index 0000000000..2bd7459d6e --- /dev/null +++ b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-gameconsole-eeclone.dts @@ -0,0 +1,961 @@ +/// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2024-present ROCKNIX (https://github.com/ROCKNIX) + * Copyright (c) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + * Copyright (c) 2025 Danil Zagoskin + */ + +/dts-v1/; +#include +#include +#include +#include +#include "rk3326.dtsi" + +/ { + model = "Generic EE clone"; + compatible = "gameconsole,eeclone", "rockchip,rk3326"; + + aliases { + mmc0 = &emmc; + mmc1 = &sdmmc; + mmc2 = &sdio; + serial1 = &uart2; + serial2 = &uart5; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&pwm1 0 25000 0>; + brightness-levels = < + 0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 + 24 25 26 27 28 29 30 31 + 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 + 56 57 58 59 60 61 62 63 + 64 65 66 67 68 69 70 71 + 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 + 88 89 90 91 92 93 94 95 + 96 97 98 99 100 101 102 103 + 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 + 128 129 130 131 132 133 134 135 + 136 137 138 139 140 141 142 143 + 144 145 146 147 148 149 150 151 + 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 + 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 + 184 185 186 187 188 189 190 191 + 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 + 208 209 210 211 212 213 214 215 + 216 217 218 219 220 221 222 223 + 224 225 226 227 228 229 230 231 + 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 + 248 249 250 251 252 253 254 255>; + default-brightness-level = <128>; + }; + + battery: battery { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <4000000>; + charge-term-current-microamp = <200000>; + constant-charge-current-max-microamp = <1500000>; + constant-charge-voltage-max-microvolt = <4200000>; + factory-internal-resistance-micro-ohms = <100000>; + voltage-max-design-microvolt = <4100000>; + voltage-min-design-microvolt = <3300000>; + + ocv-capacity-celsius = <20>; + ocv-capacity-table-0 = + <4046950 100>, <4001920 95>, <3967900 90>, <3940000 85>, + <3910000 80>, <3870000 75>, <3830000 70>, <3790000 65>, + <3750000 60>, <3720000 55>, <3690000 50>, <3650000 45>, + <3610000 40>, <3570000 35>, <3540000 30>, <3500000 25>, + <3460000 20>, <3420000 15>, <3380000 10>, <3340000 5>, + <3300000 0>; + }; + + adc_keys: adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 2>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + poll-interval = <100>; + + /* disabled by default, dtbo may enable it when needed */ + status = "disabled"; + + button-vol-up { + press-threshold-microvolt = <15000>; + label = "VOLUMEUP"; + linux,code = ; + }; + + button-vol-down { + press-threshold-microvolt = <300000>; + label = "VOLUMEDOWN"; + linux,code = ; + }; + }; + + joypad: joypad { + compatible = "archr-singleadc-joypad"; + + joypad-name = "r36s_Gamepad"; + joypad-product = <0x1188>; + joypad-revision = <0x0188>; + + status = "okay"; + + /* gpio pincontrol setup */ + pinctrl-names = "default"; + pinctrl-0 = <&btn_pins>; + + /* Analog mux define */ + io-channel-names = "amux_adc"; + io-channels = <&saradc 1>; + + /* adc mux channel count */ + amux-count = <4>; + /* non-default wiring */ + amux-channel-mapping = <2 3 1 0>; + /* adc mux enable gpio */ + amux-en-gpios = <&gpio2 RK_PB4 GPIO_ACTIVE_LOW>; /* rocker0-gpios */ + /* adc mux select(a,b) gpio */ + amux-a-gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_LOW>; /* rocker1-gpios */ + amux-b-gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_LOW>; /* rocker-gpios */ + + /* adc calculate scale */ + button-adc-scale = <2>; + + /* adc deadzone range */ + button-adc-deadzone = <64>; + + /* + specifies fuzz value that is used to filter noise from + the event stream. + */ + button-adc-fuzz = <32>; + button-adc-flat = <32>; + + /* + Analog Stick data tuning value(precent) + p = positive direction, n = negative direction + report value = (real_adc_data * tuning_value) / 100 + */ + abs_x-p-tuning = <200>; + abs_x-n-tuning = <200>; + + abs_y-p-tuning = <200>; + abs_y-n-tuning = <200>; + + abs_rx-p-tuning = <200>; + abs_rx-n-tuning = <200>; + + abs_ry-p-tuning = <200>; + abs_ry-n-tuning = <200>; + + /* poll device interval (ms), adc read interval */ + poll-interval = <10>; + + /* gpio button auto repeat set value : default disable */ + /* + autorepeat; + */ + + /* + joypad driver is poll-device driver. + poll-device is does not support wakeup-source. + */ + sw1 { + gpios = <&gpio3 RK_PC6 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-UP"; + linux,code = ; // 0x220 + }; + sw2 { + gpios = <&gpio3 RK_PC7 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-DOWN"; + linux,code = ; // 0x221 + }; + sw3 { + gpios = <&gpio3 RK_PC4 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-LEFT"; + linux,code = ; // 0x222 + }; + sw4 { + gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-RIGHT"; + linux,code = ; // 0x223 + }; + + sw5 { + gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>; + label = "GPIO KEY BTN-A"; + linux,code = ; // 0x131 + }; + sw6 { + gpios = <&gpio3 RK_PC1 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-B"; + linux,code = ; // 0x130 + }; + sw7 { + gpios = <&gpio3 RK_PC3 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-Y"; + linux,code = ; // 0x134 + }; + sw8 { + gpios = <&gpio3 RK_PC2 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-X"; + linux,code = ; // 0x133 + }; + + sw11 { + gpios = <&gpio2 RK_PB5 GPIO_ACTIVE_LOW>; + label = "GPIO BTN_THUMBL"; + linux,code = ; // 0x2c2 + }; + sw12 { + gpios = <&gpio2 RK_PB6 GPIO_ACTIVE_LOW>; + label = "GPIO BTN_THUMBR"; + linux,code = ; // 0x2c3 + }; + + sw13 { + gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; + label = "GPIO BTN_FN"; + linux,code = ; // 0x2c4 + }; + + sw15 { + gpios = <&gpio3 RK_PB5 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-LEFT"; + linux,code = ; // 0x02 + }; + sw16 { + gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-RIGHT"; + linux,code = ; // 0x05 + }; + sw19 { + gpios = <&gpio3 RK_PD0 GPIO_ACTIVE_LOW>; + label = "GPIO BTN_SELECT"; + linux,code = ; + }; + sw20 { + gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-RIGHT2"; + linux,code = ; + }; + sw21 { + gpios = <&gpio3 RK_PB6 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-LEFT2"; + linux,code = ; + }; + sw22 { + gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_LOW>; + label = "GPIO BTN_START"; + linux,code = ; + }; + }; + + leds: gpio-leds { + compatible = "gpio-leds"; + pinctrl-0 = <&led_pins>; + pinctrl-names = "default"; + + /* charge_red_gpio = <&gpio0 17 0>; */ + led-0 { + color = ; + default-state = "off"; + function = LED_FUNCTION_CHARGING; + linux,default-trigger = "none"; + gpios = <&gpio0 RK_PC1 GPIO_ACTIVE_HIGH>; + }; + + /* charge_blue_gpio = <&gpio0 0 0>; */ + led-1 { + color = ; + default-state = "on"; + function = LED_FUNCTION_POWER; + linux,default-trigger = "default-on"; + gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; + }; + }; + + spk_amp: audio-amplifier { + compatible = "simple-audio-amplifier"; + enable-gpios = <&gpio3 RK_PA7 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&spk_amp_enable_h>; + pinctrl-names = "default"; + sound-name-prefix = "Speaker Amp"; + }; + + rk817-sound-amplified { + compatible = "simple-audio-card"; + pinctrl-names = "default"; + pinctrl-0 = <&hp_det>; + simple-audio-card,name = "rk817_ext"; + simple-audio-card,aux-devs = <&spk_amp>; + simple-audio-card,format = "i2s"; + simple-audio-card,hp-det-gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,widgets = + "Headphone", "Headphones", + "Speaker", "Internal Speakers"; + /* despite it's just a mono speaker, we need to route both Speaker Amp channels + Otherwise, the second channel stays on and keeps amp enabled */ + simple-audio-card,routing = + "Headphones", "HPOL", + "Headphones", "HPOR", + "Internal Speakers", "Speaker Amp OUTL", + "Internal Speakers", "Speaker Amp OUTR", + "Speaker Amp INL", "HPOL", + "Speaker Amp INR", "HPOR"; + + simple-audio-card,pin-switches = "Internal Speakers"; + + status = "disabled"; + + simple-audio-card,codec { + sound-dai = <&rk817>; + }; + + simple-audio-card,cpu { + sound-dai = <&i2s1_2ch>; + }; + }; + + rk817-sound-simple { + compatible = "simple-audio-card"; + pinctrl-names = "default"; + pinctrl-0 = <&hp_det>; + simple-audio-card,name = "rk817_ext"; + simple-audio-card,format = "i2s"; + simple-audio-card,hp-det-gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,widgets = + "Headphone", "Headphones", + "Speaker", "Internal Speakers"; + simple-audio-card,routing = + "Headphones", "HPOL", + "Headphones", "HPOR", + "Internal Speakers", "SPKO"; + + status = "disabled"; + + simple-audio-card,codec { + sound-dai = <&rk817>; + }; + + simple-audio-card,cpu { + sound-dai = <&i2s1_2ch>; + }; + }; + + vccsys: vccsys { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + vcc-phy-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc_phy"; + regulator-always-on; + regulator-boot-on; + }; + + vcc18_lcd0: vcc18-lcd0 { + compatible = "regulator-fixed"; + regulator-name = "vcc18_lcd0_n"; + gpio = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>; + enable-active-high; + pinctrl-0 = <&vcc18_lcd_n>; + pinctrl-names = "default"; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_host: vcc_host { + compatible = "regulator-fixed"; + regulator-name = "vcc_host"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio3 RK_PA4 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&vcc5_usb>; + pinctrl-names = "default"; + enable-active-high; + regulator-always-on; + regulator-boot-on; + vin-supply = <&usb_midu>; + }; +}; + +&dmc { + center-supply = <&vdd_logic>; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&cpu1 { + cpu-supply = <&vdd_arm>; +}; + +&cpu2 { + cpu-supply = <&vdd_arm>; +}; + +&cpu3 { + cpu-supply = <&vdd_arm>; +}; + +&cru { + assigned-clocks = <&cru PLL_NPLL>, + <&cru ACLK_BUS_PRE>, <&cru ACLK_PERI_PRE>, + <&cru HCLK_BUS_PRE>, <&cru HCLK_PERI_PRE>, + <&cru PCLK_BUS_PRE>, <&cru SCLK_GPU>; + + assigned-clock-rates = <1188000000>, + <200000000>, <200000000>, + <150000000>, <150000000>, + <100000000>, <200000000>; +}; + +&display_subsystem { + status = "okay"; +}; + +&dsi { + status = "okay"; + + ports { + mipi_out: port@1 { + reg = <1>; + + mipi_out_panel: endpoint { + remote-endpoint = <&mipi_in_panel>; + }; + }; + }; + + internal_display: panel@0 { + compatible = "magicx,xu10-panel", "sitronix,st7703"; + iovcc-supply = <&vcc18_lcd0>; + vcc-supply = <&vcc18_lcd0>; + reg = <0>; + backlight = <&backlight>; + reset-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&lcd_rst>; + + port { + mipi_in_panel: endpoint { + remote-endpoint = <&mipi_out_panel>; + }; + }; + }; +}; + +&dsi_dphy { + status = "okay"; +}; + +&gpu { + mali-supply = <&vdd_logic>; + status = "okay"; +}; + +&i2c0 { + clock-frequency = <400000>; + i2c-scl-falling-time-ns = <16>; + i2c-scl-rising-time-ns = <280>; + status = "okay"; + + rk817: pmic@20 { + compatible = "rockchip,rk817"; + reg = <0x20>; + interrupt-parent = <&gpio0>; + interrupts = ; + clock-output-names = "rk808-clkout1", "xin32k"; + clock-names = "mclk"; + clocks = <&cru SCLK_I2S1_OUT>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int>, <&i2s1_2ch_mclk>; + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <1>; + #sound-dai-cells = <0>; + + vcc1-supply = <&vccsys>; + vcc2-supply = <&vccsys>; + vcc3-supply = <&vccsys>; + vcc4-supply = <&vccsys>; + vcc5-supply = <&vccsys>; + vcc6-supply = <&vccsys>; + vcc7-supply = <&vcc_3v0>; + vcc8-supply = <&vccsys>; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-name = "vdd_logic"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1350000>; + regulator-initial-mode = <0x02>; + regulator-ramp-delay = <6001>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vdd_arm: DCDC_REG2 { + regulator-name = "vdd_arm"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-initial-mode = <0x02>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x02>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_3v0: DCDC_REG4 { + regulator-name = "vcc_3v0"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-initial-mode = <0x02>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcc_1v0: LDO_REG1 { + regulator-name = "vcc_1v0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc1v8_soc: LDO_REG2 { + regulator-name = "vcc1v8_soc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc1v0_soc: LDO_REG3 { + regulator-name = "vcc1v0_soc"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc3v0_pmu: LDO_REG4 { + regulator-name = "vcc3v0_pmu"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vccio_sd: LDO_REG5 { + regulator-name = "vccio_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_sd: LDO_REG6 { + regulator-name = "vcc_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc2v8_dvp: LDO_REG7 { + regulator-name = "vcc2v8_dvp"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc3v0_dvp: LDO_REG8 { + regulator-name = "vcc3v0_dvp"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vdd1v5_dvp: LDO_REG9 { + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-name = "vdd1v5_dvp"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <1500000>; + }; + }; + + usb_midu: BOOST { + regulator-name = "usb_midu"; + regulator-min-microvolt = <4900000>; + regulator-max-microvolt = <5400000>; + regulator-always-on; + regulator-boot-on; + }; + + /* + otg_switch: OTG_SWITCH { + regulator-name = "otg_switch"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + */ + }; + + rk817_charger: charger { + monitored-battery = <&battery>; + rockchip,resistor-sense-micro-ohms = <10000>; + rockchip,sleep-enter-current-microamp = <300000>; + rockchip,sleep-filter-current-microamp = <100000>; + }; + + rk817_codec: codec { + rockchip,mic-in-differential; + }; + }; +}; + +/* I2S 1 Channel Used Header(P2):1(GPIO2.C3),2(.C2), 3(.C1), 4(.C5), 5(.C4) */ +&i2s1_2ch { + status = "okay"; + #sound-dai-cells = <0>; +}; + +&io_domains { + vccio1-supply = <&vcc2v8_dvp>; + vccio2-supply = <&vccio_sd>; + vccio3-supply = <&vcc1v8_soc>; + vccio4-supply = <&vcc_3v0>; + vccio5-supply = <&vcc_3v0>; + vccio6-supply = <&vcc1v8_soc>; + status = "okay"; +}; + +&isp { + status = "okay"; +}; + +&isp_mmu { + status = "okay"; +}; + +&pmu_io_domains { + pmuio1-supply = <&vcc3v0_pmu>; + pmuio2-supply = <&vcc3v0_pmu>; + status = "okay"; +}; + +&csi_dphy { + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; + +&saradc { + vref-supply = <&vcc1v8_soc>; + status = "okay"; +}; + +&sdmmc { + cap-sd-highspeed; + card-detect-delay = <800>; + cd-gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_LOW>; /*[> ff370000 PD_SDCARD CD GPIO <]*/ + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <&vccio_sd>; + vmmc-supply = <&vcc_sd>; + status = "okay"; +}; + +&sdio { + cap-sd-highspeed; + max-frequency = <100000000>; + cd-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; + card-detect-delay = <800>; + supports-sd; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <&vcc2v8_dvp>; + vmmc-supply = <&vcc3v0_dvp>; + status = "okay"; +}; + +&emmc { + status = "okay"; + no-sdio; + no-sd; + disable-wp; + non-removable; + num-slots = <1>; +}; + +&tsadc { + status = "okay"; +}; + +&u2phy { + status = "okay"; + + u2phy_host: host-port { + status = "okay"; + }; + + u2phy_otg: otg-port { + status = "disabled"; + }; +}; + +&usb20_otg { + status = "okay"; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; +&pinctrl { + btns { + btn_pins: btn-pins { + rockchip,pins = + <2 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB3 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PC0 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PC1 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PC2 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PC3 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PC7 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + headphone { + hp_det: hp-det { + rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + gpio-lcd { + lcd_rst: lcd-rst { + rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + vcc18-lcd { + vcc18_lcd_n: vcc18-lcd-n { + rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + vcc5-usb { + vcc5_usb: vcc5-usb { + rockchip,pins = <3 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + gpio-led { + led_pins: led-pins { + rockchip,pins = + <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>, /* charge_blue_gpio = <&gpio0 0 0>; */ + <0 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>; /* charge_red_gpio = <&gpio0 17 0>; */ + }; + }; + + pmic { + dc_det: dc-det { + rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + pmic_int: pmic-int { + rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + soc_slppin_gpio: soc_slppin_gpio { + rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>; + }; + + soc_slppin_rst: soc_slppin_rst { + rockchip,pins = <0 RK_PA4 2 &pcfg_pull_none>; + }; + + soc_slppin_slp: soc_slppin_slp { + rockchip,pins = <0 RK_PA4 1 &pcfg_pull_none>; + }; + }; + + speaker { + spk_amp_enable_h: spk-amp-enable-h { + rockchip,pins = <3 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&uart5 { + status = "okay"; +}; +&uart2 { + status = "disabled"; +}; + + +&internal_display { + compatible = "archr,generic-dsi"; + panel_description = + "G size=153,85 delays=20,20,20,120,20 format=rgb888 lanes=4 flags=0xe03", + + "M clock=50000 horizontal=720,140,80,140 vertical=720,20,4,20 default=1", + "M clock=50000 horizontal=720,140,100,140 vertical=720,20,150,20", + "M clock=50040 horizontal=720,140,112,140 vertical=720,20,140,20", + "M clock=51400 horizontal=720,140,132,140 vertical=720,20,148,20", + "M clock=50140 horizontal=720,140,90,140 vertical=720,20,40,20", + "M clock=56900 horizontal=720,140,90,140 vertical=720,20,114,20", + "M clock=50400 horizontal=720,140,92,140 vertical=720,20,10,20", + "M clock=50220 horizontal=720,140,80,140 vertical=720,20,15,20", + "M clock=54600 horizontal=720,140,112,140 vertical=720,20,57,20", + "M clock=75450 horizontal=720,140,95,140 vertical=720,20,153,20", + "M clock=75330 horizontal=720,140,80,140 vertical=720,20,15,20", + "M clock=100440 horizontal=720,140,80,140 vertical=720,20,15,20", + + "I seq=b9f11283", + "I seq=b1000000da80", + "I seq=b23c1230", + "I seq=b31010282803ff00000000", + "I seq=b480", + "I seq=b50a0a", + "I seq=b69797", + "I seq=b82622f013", + "I seq=ba338105f90e0e2000000000000000442500900a0000014f01000037", + "I seq=bc47", + "I seq=bf021100", + "I seq=c0737350500000127000", + "I seq=c12500323277e4ffffcccc7777", + "I seq=c68200bfff00ff", + "I seq=c7b8000a000000", + "I seq=c810401e02", + "I seq=cc0b", + "I seq=e0000b102c3d3f423a070d0f131513140f16000b102c3d3f423a070d0f131513140f16", + "I seq=e307070b0b0b0b00000000ff00c010", + "I seq=e9c8100a000080811231234f86a000470800000c00000000000c00000098028baf4602888888888898138baf5713888888888800000000000000000000000000", + "I seq=ea970c090909780000000000009f318ba8317588888888889f208ba820648888888888230000027100000000000000000000000000000040808100000000", + "I seq=efffff01", + "I seq=11 wait=250", + "I seq=29 wait=50"; +}; + + diff --git a/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-gameconsole-r33s.dts b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-gameconsole-r33s.dts new file mode 100644 index 0000000000..21dbab6d19 --- /dev/null +++ b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-gameconsole-r33s.dts @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * # Copyright (C) 2022-24 JELOS (https://github.com/JustEnoughLinuxOS) + */ + +/dts-v1/; +#include "rk3326-gameconsole-r3xs.dtsi" +#include "rk3326-device-group-r36.dtsi" + +/ { + model = "Game Console R33S"; + compatible = "gameconsole,r33s", "rockchip,rk3326"; + + archr,device_switch { + this = "r33s"; + }; + + builtin_gamepad: r33s_joypad { + compatible = "archr-singleadc-joypad"; + pinctrl-names = "default"; + pinctrl-0 = <&btn_pins>; + joypad-name = "r33s_joypad"; + joypad-product = <0x0AA2>; + joypad-revision = <0x0100>; + joypad-vendor = <0x0001>; + + status = "okay"; + amux-count = <0>; + /* poll device interval (ms), adc read interval */ + poll-interval = <10>; + pwms = <&pwm0 0 1000000000 0>; + pwm-names = "enable"; + rumble-boost-weak = <0x0000>; + rumble-boost-strong = <0x0000>; + + button-sw1 { + gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>; + label = "DPAD-UP"; + linux,code = ; + }; + button-sw2 { + gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_LOW>; + label = "DPAD-DOWN"; + linux,code = ; + }; + button-sw3 { + gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; + label = "DPAD-LEFT"; + linux,code = ; + }; + button-sw4 { + gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_LOW>; + label = "DPAD-RIGHT"; + linux,code = ; + }; + button-sw5 { + gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>; + label = "BTN-A"; + linux,code = ; + }; + button-sw6 { + gpios = <&gpio1 RK_PA5 GPIO_ACTIVE_LOW>; + label = "BTN-B"; + linux,code = ; + }; + button-sw7 { + gpios = <&gpio1 RK_PA6 GPIO_ACTIVE_LOW>; + label = "BTN-Y"; + linux,code = ; + }; + button-sw8 { + gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_LOW>; + label = "BTN-X"; + linux,code = ; + }; + button-sw9 { + gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_LOW>; + label = "TOP-LEFT"; + linux,code = ; + }; + button-sw10 { + gpios = <&gpio2 RK_PA7 GPIO_ACTIVE_LOW>; + label = "TOP-RIGHT"; + linux,code = ; + }; + button-sw11 { + gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>; + label = "SELECT"; + linux,code = ; + }; + button-sw12 { + gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; + label = "TOP-RIGHT 2"; + linux,code = ; + }; + button-sw13 { + gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; + label = "TOP-LEFT 2"; + linux,code = ; + }; + button-sw14 { + gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; + label = "START"; + linux,code = ; + }; + }; +}; + +&pinctrl { + btns { + btn_pins: btn-pins { + rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + }; +}; diff --git a/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-gameconsole-r36s.dts b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-gameconsole-r36s.dts new file mode 100644 index 0000000000..86309e8534 --- /dev/null +++ b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-gameconsole-r36s.dts @@ -0,0 +1,207 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * # Copyright (C) 2022-24 JELOS (https://github.com/JustEnoughLinuxOS) + */ + +/dts-v1/; +#include "rk3326-gameconsole-r3xs.dtsi" +#include "rk3326-device-group-r36.dtsi" + +/ { + model = "Game Console R36S"; + compatible = "gameconsole,r35s", "gameconsole,r36s", "rockchip,rk3326"; + + archr,device_switch { + this = "r36s"; + }; + + joypad: odroidgo3-joypad { + compatible = "odroidgo3-joypad"; + pwms = <&pwm0 0 200000000 0>; + pwm-names = "enable"; + rumble-boost-weak = <0x0000>; + rumble-boost-strong = <0x0000>; + + joypad-name = "r36s_Gamepad"; + joypad-product = <0x1188>; + joypad-revision = <0x0188>; + + status = "okay"; + + /* gpio pincontrol setup */ + pinctrl-names = "default"; + pinctrl-0 = <&btn_pins>; + pinctrl-1 = <&pwm0_pin>; + + /* Analog mux define */ + io-channel-names = "amux_adc"; + io-channels = <&saradc 1>; + + /* adc mux channel count */ + amux-count = <4>; + /* adc mux select(a,b) gpio */ + amux-a-gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_LOW>; + amux-b-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>; + /* adc mux enable gpio */ + amux-en-gpios = <&gpio3 RK_PB5 GPIO_ACTIVE_LOW>; + + /* adc calculate scale */ + button-adc-scale = <2>; + + /* adc deadzone range */ + button-adc-deadzone = <64>; + + /* + specifies fuzz value that is used to filter noise from + the event stream. + */ + button-adc-fuzz = <32>; + button-adc-flat = <32>; + + /* + Analog Stick data tuning value(precent) + p = positive direction, n = negative direction + report value = (real_adc_data * tuning_value) / 100 + */ + abs_x-p-tuning = <200>; + abs_x-n-tuning = <200>; + + abs_y-p-tuning = <200>; + abs_y-n-tuning = <200>; + + abs_rx-p-tuning = <200>; + abs_rx-n-tuning = <200>; + + abs_ry-p-tuning = <200>; + abs_ry-n-tuning = <200>; + + /* poll device interval (ms), adc read interval */ + poll-interval = <10>; + + /* required for RG36S */ + invert-absx; + invert-absy; + + /* gpio button auto repeat set value : default disable */ + /* + autorepeat; + */ + + /* + joypad driver is poll-device driver. + poll-device is does not support wakeup-source. + */ + sw1 { + gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-UP"; + linux,code = ; // 0x220 + }; + sw2 { + gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-DOWN"; + linux,code = ; // 0x221 + }; + sw3 { + gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-LEFT"; + linux,code = ; // 0x222 + }; + sw4 { + gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-RIGHT"; + linux,code = ; // 0x223 + }; + sw5 { + gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>; + label = "GPIO KEY BTN-A"; + linux,code = ; // 0x131 + }; + sw6 { + gpios = <&gpio1 RK_PA5 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-B"; + linux,code = ; // 0x130 + }; + sw7 { + gpios = <&gpio1 RK_PA6 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-Y"; + linux,code = ; // 0x134 + }; + sw8 { + gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-X"; + linux,code = ; // 0x133 + }; + sw11 { + gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; + label = "GPIO BTN_THUMBL"; + linux,code = ; // 0x2c2 + }; + sw12 { + gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; + label = "GPIO BTN_THUMBR"; + linux,code = ; // 0x2c3 + }; + sw13 { + gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_LOW>; + label = "GPIO BTN_FN"; + linux,code = ; // 0x2c4 + }; + sw15 { + gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-LEFT"; + linux,code = ; // 0x02 + }; + sw16 { + gpios = <&gpio2 RK_PA7 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-RIGHT"; + linux,code = ; // 0x05 + }; + sw19 { + gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>; + label = "GPIO BTN_SELECT"; + linux,code = ; + }; + sw20 { + gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-RIGHT2"; + linux,code = ; + }; + sw21 { + gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-LEFT2"; + linux,code = ; + }; + sw22 { + gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; + label = "GPIO BTN_START"; + linux,code = ; + }; + }; +}; + +&pinctrl { + btns { + btn_pins: btn-pins { + rockchip,pins = <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>; + + }; + + }; +}; diff --git a/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-gameconsole-r3xs.dtsi b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-gameconsole-r3xs.dtsi new file mode 100644 index 0000000000..de1b0d51e2 --- /dev/null +++ b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-gameconsole-r3xs.dtsi @@ -0,0 +1,545 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * # Copyright (C) 2022-24 JELOS (https://github.com/JustEnoughLinuxOS) + */ + +/dts-v1/; +#include +#include +#include +#include +#include "rk3326.dtsi" + +/ { + model = "Game Console R33S"; + compatible = "gameconsolec,r33s", "rockchip,rk3326"; + + aliases { + mmc0 = &sdio; + mmc1 = &sdmmc; + }; + + chosen { + stdout-path = "serial2:115200n8"; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + power-supply = <&vcc_bl>; + pwms = <&pwm1 0 25000 0>; + brightness-levels = < + 0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 + 24 25 26 27 28 29 30 31 + 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 + 56 57 58 59 60 61 62 63 + 64 65 66 67 68 69 70 71 + 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 + 88 89 90 91 92 93 94 95 + 96 97 98 99 100 101 102 103 + 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 + 128 129 130 131 132 133 134 135 + 136 137 138 139 140 141 142 143 + 144 145 146 147 148 149 150 151 + 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 + 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 + 184 185 186 187 188 189 190 191 + 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 + 208 209 210 211 212 213 214 215 + 216 217 218 219 220 221 222 223 + 224 225 226 227 228 229 230 231 + 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 + 248 249 250 251 252 253 254 255>; + default-brightness-level = <128>; + }; + + gpio-keys-vol { + compatible = "gpio-keys"; + autorepeat; + pinctrl-0 = <&btn_pins_vol>; + pinctrl-names = "default"; + + button-vol-down { + gpios = <&gpio2 RK_PA1 GPIO_ACTIVE_LOW>; + label = "VOLUMEDOWN"; + linux,code = ; + }; + + button-volume-up { + gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; + label = "VOLUMEUP"; + linux,code = ; + }; + }; + + battery: battery { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <3200000>; + charge-term-current-microamp = <320000>; + constant-charge-current-max-microamp = <2000000>; + constant-charge-voltage-max-microvolt = <4200000>; + factory-internal-resistance-micro-ohms = <180000>; + voltage-max-design-microvolt = <4100000>; + voltage-min-design-microvolt = <3500000>; + + ocv-capacity-celsius = <20>; + ocv-capacity-table-0 = <4046950 100>, <4001920 95>, <3967900 90>, <3919950 85>, + <3888450 80>, <3861850 75>, <3831540 70>, <3799130 65>, + <3768190 60>, <3745650 55>, <3726610 50>, <3711630 45>, + <3696720 40>, <3685660 35>, <3674950 30>, <3663050 25>, + <3649470 20>, <3635260 15>, <3616920 10>, <3592440 5>, + <3574170 0>; + + }; + + rk817-sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "rk817_int"; + simple-audio-card,format = "i2s"; + simple-audio-card,hp-det-gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Headphone", "Headphones", + "Speaker", "Speaker"; + simple-audio-card,routing = + "MICL", "Mic Jack", + "Headphones", "HPOL", + "Headphones", "HPOR", + "Speaker", "SPKO"; + + simple-audio-card,codec { + sound-dai = <&rk817>; + }; + + simple-audio-card,cpu { + sound-dai = <&i2s1_2ch>; + }; + }; + + vccsys: vccsys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v8_sys"; + regulator-always-on; + regulator-min-microvolt = <3800000>; + regulator-max-microvolt = <3800000>; + }; +}; + +&dmc { + center-supply = <&vdd_logic>; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&cpu1 { + cpu-supply = <&vdd_arm>; +}; + +&cpu2 { + cpu-supply = <&vdd_arm>; +}; + +&cpu3 { + cpu-supply = <&vdd_arm>; +}; + +&cru { + assigned-clocks = <&cru PLL_NPLL>, + <&cru ACLK_BUS_PRE>, <&cru ACLK_PERI_PRE>, + <&cru HCLK_BUS_PRE>, <&cru HCLK_PERI_PRE>, + <&cru PCLK_BUS_PRE>, <&cru SCLK_GPU>; + + assigned-clock-rates = <1188000000>, + <200000000>, <200000000>, + <150000000>, <150000000>, + <100000000>, <200000000>; +}; + +&display_subsystem { + status = "okay"; +}; + +&dsi { + status = "okay"; + + ports { + mipi_out: port@1 { + reg = <1>; + + mipi_out_panel: endpoint { + remote-endpoint = <&mipi_in_panel>; + }; + }; + }; + + internal_display: panel@0 { + reg = <0>; + backlight = <&backlight>; + reset-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>; + + port { + mipi_in_panel: endpoint { + remote-endpoint = <&mipi_out_panel>; + }; + }; + }; +}; + +&dsi_dphy { + status = "okay"; +}; + +&gpu { + mali-supply = <&vdd_logic>; + status = "okay"; +}; + +&internal_display { + compatible = "gameconsole,r36s-panel", "sitronix,st7703"; + iovcc-supply = <&vcc_lcd>; + vdd-supply = <&vcc_lcd>; +}; + +&i2c0 { + clock-frequency = <400000>; + i2c-scl-falling-time-ns = <16>; + i2c-scl-rising-time-ns = <280>; + status = "okay"; + + rk817: pmic@20 { + compatible = "rockchip,rk817"; + reg = <0x20>; + interrupt-parent = <&gpio0>; + interrupts = ; + clock-output-names = "rk808-clkout1", "xin32k"; + clock-names = "mclk"; + clocks = <&cru SCLK_I2S1_OUT>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int>, <&i2s1_2ch_mclk>; + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <1>; + #sound-dai-cells = <0>; + + vcc1-supply = <&vccsys>; + vcc2-supply = <&vccsys>; + vcc3-supply = <&vccsys>; + vcc4-supply = <&vccsys>; + vcc5-supply = <&vccsys>; + vcc6-supply = <&vccsys>; + vcc7-supply = <&vccsys>; + vcc8-supply = <&vccsys>; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-name = "vdd_logic"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1150000>; + regulator-ramp-delay = <6001>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vdd_arm: DCDC_REG2 { + regulator-name = "vdd_arm"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_3v3: DCDC_REG4 { + regulator-name = "vcc_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_1v8: LDO_REG2 { + regulator-name = "vcc_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd_1v0: LDO_REG3 { + regulator-name = "vdd_1v0"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc3v3_pmu: LDO_REG4 { + regulator-name = "vcc3v3_pmu"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vccio_sd: LDO_REG5 { + regulator-name = "vccio_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc_sd: LDO_REG6 { + regulator-name = "vcc_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3000000>; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcc_bl: LDO_REG7 { + regulator-name = "vcc_bl"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_lcd: LDO_REG8 { + regulator-name = "vcc_lcd"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <2800000>; + }; + }; + + LDO_REG9 { + /* unused */ + }; + + usb_midu: BOOST { + regulator-name = "usb_midu"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5400000>; + regulator-always-on; + regulator-boot-on; + }; + }; + + rk817_charger: charger { + rockchip,resistor-sense-micro-ohms = <10000>; + rockchip,sleep-enter-current-microamp = <300000>; + rockchip,sleep-filter-current-microamp = <100000>; + }; + + rk817_codec: codec { + rockchip,mic-in-differential; + }; + }; +}; + +&i2s1_2ch { + status = "okay"; +}; + +&io_domains { + vccio1-supply = <&vccio_sd>; + vccio2-supply = <&vccio_sd>; + vccio3-supply = <&vcc_3v3>; + vccio4-supply = <&vcc_3v3>; + vccio5-supply = <&vcc_3v3>; + vccio6-supply = <&vcc_3v3>; + status = "okay"; +}; + +&pmu_io_domains { + pmuio1-supply = <&vcc3v3_pmu>; + pmuio2-supply = <&vcc3v3_pmu>; + status = "okay"; +}; + +&pwm0 { + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; + +&saradc { + vref-supply = <&vcc_1v8>; + status = "okay"; +}; + +&sdmmc { + bus-width = <4>; + cap-sd-highspeed; + card-detect-delay = <800>; + cd-gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_LOW>; /*[> CD GPIO <]*/ + disable-wp; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&sdio { + bus-width = <4>; + cap-sd-highspeed; + card-detect-delay = <800>; + cd-gpios = <&gpio3 RK_PB6 GPIO_ACTIVE_LOW>; /*[> CD GPIO <]*/ + disable-wp; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&tsadc { + status = "okay"; +}; + +&u2phy { + status = "okay"; + + u2phy_host: host-port { + status = "okay"; + }; + + u2phy_otg: otg-port { + status = "disabled"; + }; +}; + +&usb20_otg { + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2m1_xfer>; + status = "okay"; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; + +&rk817_charger { + monitored-battery = <&battery>; +}; + +&pinctrl { + btns { + btn_pins_vol: btn-pins-vol { + rockchip,pins = <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + headphone { + hp_det: hp-det { + rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; + + pmic { + dc_det: dc-det { + rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + pmic_int: pmic-int { + rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + soc_slppin_gpio: soc_slppin_gpio { + rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>; + }; + + soc_slppin_rst: soc_slppin_rst { + rockchip,pins = <0 RK_PA4 2 &pcfg_pull_none>; + }; + + soc_slppin_slp: soc_slppin_slp { + rockchip,pins = <0 RK_PA4 1 &pcfg_pull_none>; + }; + }; +}; diff --git a/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-gameforce-chi.dts b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-gameforce-chi.dts new file mode 100644 index 0000000000..7b47cf7017 --- /dev/null +++ b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-gameforce-chi.dts @@ -0,0 +1,811 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2024 Chris Morgan + */ + +/dts-v1/; +#include +#include +#include +#include +#include "rk3326.dtsi" + +/ { + model = "GameForce Chi"; + compatible = "gameforce,chi", "rockchip,rk3326"; + chassis-type = "handset"; + + aliases { + mmc0 = &sdmmc; + mmc1 = &sdio; + }; + + chosen { + stdout-path = "serial2:115200n8"; + }; + + adc_joystick: adc-joystick { + compatible = "adc-joystick"; + io-channels = <&saradc 0>, + <&saradc 1>; + poll-interval = <100>; + #address-cells = <1>; + #size-cells = <0>; + + axis@0 { + reg = <0>; + abs-flat = <10>; + abs-fuzz = <10>; + abs-range = <850 175>; + linux,code = ; + }; + + axis@1 { + reg = <1>; + abs-flat = <10>; + abs-fuzz = <10>; + abs-range = <800 190>; + linux,code = ; + }; + }; + + adc_keys: adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 2>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + poll-interval = <60>; + + button-1 { + label = "HAPPY1"; + linux,code = ; + press-threshold-microvolt = <15000>; + }; + + button-2 { + label = "HAPPY2"; + linux,code = ; + press-threshold-microvolt = <300000>; + }; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + power-supply = <&vcc_bl>; + pwms = <&pwm1 0 25000 0>; + }; + + battery: battery { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <3000000>; + charge-term-current-microamp = <300000>; + constant-charge-current-max-microamp = <1500000>; + constant-charge-voltage-max-microvolt = <4200000>; + factory-internal-resistance-micro-ohms = <180000>; + ocv-capacity-celsius = <20>; + ocv-capacity-table-0 = <4106000 100>, <4071000 95>, <4018000 90>, <3975000 85>, + <3946000 80>, <3908000 75>, <3877000 70>, <3853000 65>, + <3834000 60>, <3816000 55>, <3802000 50>, <3788000 45>, + <3774000 40>, <3760000 35>, <3748000 30>, <3735000 25>, + <3718000 20>, <3697000 15>, <3685000 10>, <3625000 5>, + <3400000 0>; + voltage-max-design-microvolt = <4250000>; + voltage-min-design-microvolt = <3400000>; + }; + + gpio_leds: gpio-leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&led_pins>; + + red_led: led-0 { + color = ; + gpios = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>; + }; + + green_led: led-1 { + color = ; + gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>; + }; + + blue_led: led-2 { + color = ; + gpios = <&gpio3 RK_PC6 GPIO_ACTIVE_HIGH>; + }; + + white_led: led-3 { + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_HIGH>; + }; + + chg_led: led-4 { + color = ; + function = LED_FUNCTION_CHARGING; + gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_HIGH>; + }; + + }; + + gpio_keys: gpio-keys { + compatible = "gpio-keys"; + pinctrl-0 = <&btn_pins_ctrl>; + pinctrl-names = "default"; + + button-a { + gpios = <&gpio2 RK_PB0 GPIO_ACTIVE_LOW>; + label = "EAST"; + linux,code = ; + }; + + button-b { + gpios = <&gpio2 RK_PB1 GPIO_ACTIVE_LOW>; + label = "SOUTH"; + linux,code = ; + }; + + button-down { + gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_LOW>; + label = "DPAD-DOWN"; + linux,code = ; + }; + + button-home { + gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; + label = "HOME"; + linux,code = ; + }; + + button-l1 { + gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_LOW>; + label = "TL"; + linux,code = ; + }; + + button-l2 { + gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_LOW>; + label = "TL2"; + linux,code = ; + }; + + button-left { + gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; + label = "DPAD-LEFT"; + linux,code = ; + }; + + button-r1 { + gpios = <&gpio2 RK_PA7 GPIO_ACTIVE_LOW>; + label = "TR"; + linux,code = ; + }; + + button-r2 { + gpios = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>; + label = "TR2"; + linux,code = ; + }; + + button-right { + gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_LOW>; + label = "DPAD-RIGHT"; + linux,code = ; + }; + + button-select { + gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; + label = "SELECT"; + linux,code = ; + }; + + button-start { + gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; + label = "START"; + linux,code = ; + }; + + button-up { + gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>; + label = "DPAD-UP"; + linux,code = ; + }; + + button-x { + gpios = <&gpio2 RK_PB3 GPIO_ACTIVE_LOW>; + label = "NORTH"; + linux,code = ; + }; + + button-y { + gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_LOW>; + label = "WEST"; + linux,code = ; + }; + }; + + multi-led { + compatible = "leds-group-multicolor"; + color = ; + function = LED_FUNCTION_KBD_BACKLIGHT; + leds = <&red_led>, <&green_led>, <&blue_led>; + }; + + spk_amp: audio-amplifier { + compatible = "simple-audio-amplifier"; + enable-gpios = <&gpio2 RK_PB5 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&spk_amp_enable_h>; + pinctrl-names = "default"; + sound-name-prefix = "Speaker Amp"; + }; + + sound { + compatible = "simple-audio-card"; + pinctrl-0 = <&hp_det>; + pinctrl-names = "default"; + simple-audio-card,name = "rk817_ext"; + simple-audio-card,aux-devs = <&spk_amp>; + simple-audio-card,format = "i2s"; + simple-audio-card,hp-det-gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Headphone", "Headphones", + "Speaker", "Internal Speakers"; + simple-audio-card,routing = + "MICL", "Mic Jack", + "Headphones", "HPOL", + "Headphones", "HPOR", + "Internal Speakers", "Speaker Amp OUTL", + "Internal Speakers", "Speaker Amp OUTR", + "Speaker Amp INL", "HPOL", + "Speaker Amp INR", "HPOR"; + simple-audio-card,pin-switches = "Internal Speakers"; + + simple-audio-card,codec { + sound-dai = <&rk817>; + }; + + simple-audio-card,cpu { + sound-dai = <&i2s1_2ch>; + }; + }; + + vibrator_left: pwm-vibrator-l { + compatible = "pwm-vibrator"; + pwm-names = "enable"; + pwms = <&pwm4 0 25000 0>; + }; + + vibrator_right: pwm-vibrator-r { + compatible = "pwm-vibrator"; + pwm-names = "enable"; + pwms = <&pwm5 0 25000 0>; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = <&rk817 1>; + clock-names = "ext_clock"; + pinctrl-0 = <&wifi_enable_h>; + pinctrl-names = "default"; + post-power-on-delay-ms = <200>; + reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; + }; + + vccsys: regulator-vccsys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v8_sys"; + regulator-always-on; + regulator-min-microvolt = <3800000>; + regulator-max-microvolt = <3800000>; + }; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&cpu1 { + cpu-supply = <&vdd_arm>; +}; + +&cpu2 { + cpu-supply = <&vdd_arm>; +}; + +&cpu3 { + cpu-supply = <&vdd_arm>; +}; + +&display_subsystem { + status = "okay"; +}; + +&dsi { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + internal_display: panel@0 { + reg = <0>; + compatible = "gameforce,chi-panel"; + backlight = <&backlight>; + iovcc-supply = <&vcc_lcd>; + vcc-supply = <&vcc_lcd>; + reset-gpios = <&gpio3 RK_PA0 GPIO_ACTIVE_LOW>; + + port { + mipi_in_panel: endpoint { + remote-endpoint = <&mipi_out_panel>; + }; + }; + }; + + ports { + mipi_out: port@1 { + reg = <1>; + + mipi_out_panel: endpoint { + remote-endpoint = <&mipi_in_panel>; + }; + }; + }; +}; + +&dsi_dphy { + status = "okay"; +}; + +&gpu { + mali-supply = <&vdd_logic>; + status = "okay"; +}; + +&i2c0 { + clock-frequency = <400000>; + i2c-scl-falling-time-ns = <16>; + i2c-scl-rising-time-ns = <280>; + status = "okay"; + + rk817: pmic@20 { + compatible = "rockchip,rk817"; + reg = <0x20>; + #clock-cells = <1>; + clock-names = "mclk"; + clock-output-names = "rk808-clkout1", "xin32k"; + clocks = <&cru SCLK_I2S1_OUT>; + interrupt-parent = <&gpio0>; + interrupts = ; + pinctrl-0 = <&pmic_int>, <&i2s1_2ch_mclk>; + pinctrl-names = "default"; + #sound-dai-cells = <0>; + system-power-controller; + wakeup-source; + + vcc1-supply = <&vccsys>; + vcc2-supply = <&vccsys>; + vcc3-supply = <&vccsys>; + vcc4-supply = <&vccsys>; + vcc5-supply = <&vccsys>; + vcc6-supply = <&vccsys>; + vcc7-supply = <&vcc_3v0>; + vcc8-supply = <&vccsys>; + vcc9-supply = <&dcdc_boost>; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1150000>; + regulator-min-microvolt = <950000>; + regulator-name = "vdd_logic"; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vdd_arm: DCDC_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1350000>; + regulator-min-microvolt = <950000>; + regulator-name = "vdd_arm"; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-name = "vcc_ddr"; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_3v0: DCDC_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3000000>; + regulator-min-microvolt = <3000000>; + regulator-name = "vcc_3v0"; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcc_1v8: LDO_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-name = "vcc_1v8"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd_1v0: LDO_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1000000>; + regulator-min-microvolt = <1000000>; + regulator-name = "vdd_1v0"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc_3v0_pmu: LDO_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3000000>; + regulator-min-microvolt = <3000000>; + regulator-name = "vcc_3v0_pmu"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vccio_sd: LDO_REG5 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <1800000>; + regulator-name = "vccio_sd"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_sd: LDO_REG6 { + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "vcc_sd"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_bl: LDO_REG7 { + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "vcc_bl"; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_lcd: LDO_REG8 { + regulator-max-microvolt = <2800000>; + regulator-min-microvolt = <2800000>; + regulator-name = "vcc_lcd"; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <2800000>; + }; + }; + + vcc_wifi: LDO_REG9 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "vcc_wifi"; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + dcdc_boost: BOOST { + regulator-max-microvolt = <5000000>; + regulator-min-microvolt = <5000000>; + regulator-name = "dcdc_boost"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + otg_switch: OTG_SWITCH { + regulator-name = "otg_switch"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + + rk817_charger: charger { + monitored-battery = <&battery>; + rockchip,resistor-sense-micro-ohms = <10000>; + rockchip,sleep-enter-current-microamp = <300000>; + rockchip,sleep-filter-current-microamp = <100000>; + }; + }; +}; + +&i2s1_2ch { + status = "okay"; +}; + +&io_domains { + vccio1-supply = <&vcc_3v0_pmu>; + vccio2-supply = <&vccio_sd>; + vccio3-supply = <&vcc_3v0>; + vccio4-supply = <&vcc_3v0>; + vccio5-supply = <&vcc_3v0>; + vccio6-supply = <&vcc_3v0>; + status = "okay"; +}; + +&pinctrl { + bluetooth-pins { + bt_reset: bt-reset { + rockchip,pins = + <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_down>; + }; + + bt_wake_dev: bt-wake-dev { + rockchip,pins = + <0 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + bt_wake_host: bt-wake-host { + rockchip,pins = + <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + headphone { + hp_det: hp-det { + rockchip,pins = + <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + gpio-btns { + btn_pins_ctrl: btn-pins-ctrl { + rockchip,pins = + <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PB3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + gpio-leds { + led_pins: led-pins { + rockchip,pins = + <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>, + <3 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>, + <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>, + <3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>, + <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pmic { + pmic_int: pmic-int { + rockchip,pins = + <0 RK_PC1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + soc_slppin_gpio: soc_slppin_gpio { + rockchip,pins = + <0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>; + }; + + soc_slppin_rst: soc_slppin_rst { + rockchip,pins = + <0 RK_PA4 2 &pcfg_pull_none>; + }; + + soc_slppin_slp: soc_slppin_slp { + rockchip,pins = + <0 RK_PA4 1 &pcfg_pull_none>; + }; + }; + + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = + <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + speaker { + spk_amp_enable_h: spk-amp-enable-h { + rockchip,pins = + <2 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&pmu_io_domains { + pmuio1-supply = <&vcc_1v8>; + pmuio2-supply = <&vcc_3v0_pmu>; + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; + +&pwm4 { + status = "okay"; +}; + +&pwm5 { + status = "okay"; +}; + +&saradc { + vref-supply = <&vcc_1v8>; + status = "okay"; +}; + +&sdio { + bus-width = <4>; + cap-sd-highspeed; + cap-sdio-irq; + disable-wp; + keep-power-in-suspend; + mmc-pwrseq = <&sdio_pwrseq>; + no-mmc; + no-sd; + non-removable; + sd-uhs-sdr104; + status = "okay"; +}; + +&sdmmc { + cap-mmc-highspeed; + cap-sd-highspeed; + no-sdio; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&sfc { + #address-cells = <1>; + pinctrl-0 = <&sfc_clk &sfc_cs0 &sfc_bus2>; + pinctrl-names = "default"; + #size-cells = <0>; + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <108000000>; + spi-rx-bus-width = <2>; + spi-tx-bus-width = <1>; + }; +}; + +&tsadc { + status = "okay"; +}; + +&u2phy { + status = "okay"; + + u2phy_otg: otg-port { + status = "okay"; + }; +}; + +&usb20_otg { + status = "okay"; +}; + +/* + * The right ADC joystick exists connected to an unknown ADC + * controller which can be communicated with via uart0. This ADC device + * is an 8-pin SOIC with no markings located right next to the left ADC + * joystick ribbon cable. The pinout for this ADC controller appears to + * be pin 1 - VCC (2.8v), pin 2 - 1.8v (clk maybe?), pin 3 - GPIO 10, + * pin 4 - unknown, pin 5 - unknown, pin 6 - analog in, pin 7 - analog in, + * pin 8 - ground. There is currently a userspace UART driver for this + * device but it only works with the BSP joystick driver. + */ +&uart0 { + status = "okay"; +}; + +/* + * Bluetooth was not working on BSP and is not currently working on + * mainline due to missing firmware. Bluetooth requires removal of DMA + * or else it will not probe. + */ +&uart1 { + /delete-property/ dma-names; + /delete-property/ dmas; + uart-has-rtscts; + status = "okay"; + + bluetooth: bluetooth { + compatible = "realtek,rtl8723ds-bt"; + device-wake-gpios = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>; + enable-gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; + host-wake-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&bt_reset>, <&bt_wake_dev>, <&bt_wake_host>; + pinctrl-names = "default"; + }; +}; + +&uart2 { + pinctrl-0 = <&uart2m1_xfer>; + pinctrl-names = "default"; + status = "okay"; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; diff --git a/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-magicx-xu-mini-m.dts b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-magicx-xu-mini-m.dts new file mode 100644 index 0000000000..c3a6aa31a9 --- /dev/null +++ b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-magicx-xu-mini-m.dts @@ -0,0 +1,110 @@ +/// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2024-present ROCKNIX (https://github.com/ROCKNIX) + * Copyright (c) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + * Copyright (c) 2024 Olivier Schonken + */ + +#include "rk3326-magicx-xu10.dts" + +/ { + model = "MagicX XU Mini M"; + compatible = "magicx,xu-mini-m", "rockchip,rk3326"; +}; + +&battery { + charge-full-design-microamp-hours = <2600000>; +}; + +&dsi { + internal_display: panel@0 { + compatible = "archr,generic-dsi"; + panel_description = + "G size=69,139 delays=5,20,20,120,20 format=rgb888 lanes=2 flags=0xe03", + + "M clock=25000 horizontal=480,60,10,54 vertical=640,20,10,20 default=1", + "M clock=25200 horizontal=480,60,22,54 vertical=640,20,139,20", + "M clock=25000 horizontal=480,60,31,54 vertical=640,20,120,20", + "M clock=25660 horizontal=480,60,22,54 vertical=640,20,153,20", + "M clock=25300 horizontal=480,60,31,54 vertical=640,20,24,20", + "M clock=28590 horizontal=480,60,15,54 vertical=640,20,106,20", + "M clock=25380 horizontal=480,60,17,54 vertical=640,20,13,20", + "M clock=25410 horizontal=480,60,11,54 vertical=640,20,20,20", + "M clock=29490 horizontal=480,60,24,54 vertical=640,20,114,20", + "M clock=33520 horizontal=480,60,36,54 vertical=640,20,25,20", + "M clock=38430 horizontal=480,60,16,54 vertical=640,20,20,20", + "M clock=50820 horizontal=480,60,11,54 vertical=640,20,20,20", + + "I seq=ff7701000013", + "I seq=ef08", + "I seq=ff7701000010", + "I seq=c04f00", "I seq=c11002", "I seq=c22002", "I seq=cc10", + "I seq=b006161e0e12060a0809230412102b311f", + "I seq=b1060f160d100704090720051210262f1f", + "I seq=ff7701000011", + "I seq=b065", "I seq=b185", "I seq=b282", "I seq=b380", "I seq=b542", "I seq=b785", + "I seq=b820", + "I seq=c178", "I seq=c278", + "I seq=d088", + "I seq=e0000002", + "I seq=e104a006a005a007a0004444", + "I seq=e2000000000000000000000000", + "I seq=e300002222", + "I seq=e44444", + "I seq=e50c90a0a00e92a0a0088ca0a00a8ea0a0", + "I seq=e600002222", + "I seq=e74444", + "I seq=e80d91a0a00f93a0a0098da0a00b8fa0a0", + "I seq=eb0000e4e4440040", + "I seq=edfff5476f0ba1abffffba1ab0f6745fff", + "I seq=ef080808403f64", + "I seq=ff7701000013", + "I seq=e6167c", "I seq=e8000e", + "I seq=e8000c wait=50", + "I seq=e80000", + "I seq=ff7701000000", + "I seq=11 wait=150", + "I seq=29 wait=120"; + rotation = <90>; + }; +}; + +&joypad { + joypad-name = "XU Mini M Gamepad"; + + invert-absrx; + /delete-property/ invert-absx; + + sw5 { + gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-B"; + }; + sw6 { + gpios = <&gpio2 RK_PA1 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-A"; + }; + sw7 { + gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-X"; + }; + sw8 { + gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-Y"; + }; + sw16 { + gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; + }; + sw17 { + gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; + }; +}; + +&pinctrl { + headphone { + hp_det: hp-det { + rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; +}; + + diff --git a/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-magicx-xu10.dts b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-magicx-xu10.dts new file mode 100644 index 0000000000..3fe532e06d --- /dev/null +++ b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-magicx-xu10.dts @@ -0,0 +1,872 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Hardkernel Co., Ltd + * Copyright (c) 2020 Theobroma Systems Design und Consulting GmbH + * Copyright (c) 2022 Maya Matuszczyk + */ + +/dts-v1/; +#include +#include +#include +#include +#include "rk3326.dtsi" + +/ { + model = "MagicX XU10"; + compatible = "magicx,xu10", "rockchip,rk3326"; + + aliases { + mmc0 = &sdio; + mmc1 = &sdmmc; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&pwm1 0 25000 0>; + brightness-levels = < + 0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 + 24 25 26 27 28 29 30 31 + 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 + 56 57 58 59 60 61 62 63 + 64 65 66 67 68 69 70 71 + 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 + 88 89 90 91 92 93 94 95 + 96 97 98 99 100 101 102 103 + 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 + 128 129 130 131 132 133 134 135 + 136 137 138 139 140 141 142 143 + 144 145 146 147 148 149 150 151 + 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 + 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 + 184 185 186 187 188 189 190 191 + 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 + 208 209 210 211 212 213 214 215 + 216 217 218 219 220 221 222 223 + 224 225 226 227 228 229 230 231 + 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 + 248 249 250 251 252 253 254 255>; + default-brightness-level = <128>; + }; + + joypad: xu10-joypad { + compatible = "xu10-joypad"; + + joypad-name = "XU10 Gamepad"; + joypad-product = <0x0200>; + joypad-revision = <0x0010>; + + status = "okay"; + /* + - xu10-joypad sysfs list - + * for poll device interval(ms) + /sys/devices/platform/odroidgo3_joypad/poll_interval [rw] + ex) echo 20 > poll_interval + * for button-adc-fuzz + /sys/devices/platform/odroidgo3_joypad/adc_fuzz [r] + * for button-adc-flat + /sys/devices/platform/odroidgo3_joypad/adc_flat [r] + + * for report control(1:enable, 0:disable) + /sys/devices/platform/odroidgo3_joypad/enable [rw] + * for adc calibration value setup(current adcs value -> cal value) + /sys/devices/platform/odroidgo3_joypad/adc_cal [rw] + ex) echo 0 > adc_cal + * for amux data debug + * Joypad driver is disabled when using this sysfs. + /sys/devices/platform/odroidgo3_joypad/amux_debug [rw] + ex) echo 0 > amux_debug --> select amux channel + ex) cat amux_debug --> get adc data of seleted channel + */ + + /* gpio pincontrol setup */ + pinctrl-names = "default"; + pinctrl-0 = <&btn_pins>; + + /* Analog mux define */ + io-channel-names = "joy_left", "joy_right"; + io-channels = <&saradc 1>, <&saradc 2>; + + /* adc mux channel count */ + amux-count = <4>; + + /* adc mux select(a,b) gpio */ + amux-a-gpios = <&gpio2 RK_PB3 GPIO_ACTIVE_LOW>; + amux-b-gpios = <&gpio2 RK_PB5 GPIO_ACTIVE_LOW>; + + /* adc mux enable gpio */ + amux-en-gpios = <&gpio1 RK_PB0 GPIO_ACTIVE_LOW>; + + /* adc calculate scale */ + button-adc-scale = <2>; + + /* adc deadzone range */ + button-adc-deadzone = <180>; + + /* + specifies fuzz value that is used to filter noise from + the event stream. + */ + button-adc-fuzz = <32>; + button-adc-flat = <32>; + + /* + Analog Stick data tuning value(precent) + p = positive direction, n = negative direction + report value = (real_adc_data * tuning_value) / 100 + */ + abs_x-p-tuning = <200>; + abs_x-n-tuning = <200>; + + abs_y-p-tuning = <200>; + abs_y-n-tuning = <200>; + + abs_rx-p-tuning = <200>; + abs_rx-n-tuning = <200>; + + abs_ry-p-tuning = <200>; + abs_ry-n-tuning = <200>; + + /* poll device interval (ms), adc read interval */ + poll-interval = <10>; + + /* required for XU10 */ + invert-absx; + invert-absy; + + /* gpio button auto repeat set value : default disable */ + /* + autorepeat; + */ + + /* + *** MagicX XU10 - layoout *** + |-------------------------------| + | sw14 sw17 sw16 sw15 | + |-----|-------------------|-----| + | | | | + |vol+ | | sw13| + |vol- | | | + | | LCD Display | | + | | | | + | | | | + | |-------------------| | + | sw9 sw10 | + | | + | sw1 sw7 | + | sw3 sw4 sw8 sw6 | + | sw2 sw5 | + | | + | sw11 sw12 | + | | + |-------|---------------|-------| + */ + + /* + joypad driver is poll-device driver. + poll-device is does not support wakeup-source. + */ + + sw1 { + gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-UP"; + linux,code = ; // 0x220 + }; + sw2 { + gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-DOWN"; + linux,code = ; // 0x221 + }; + sw3 { + gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-LEFT"; + linux,code = ; // 0x222 + }; + sw4 { + gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-RIGHT"; + linux,code = ; // 0x223 + }; + sw5 { + gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-A"; + linux,code = ; // 0x130 + }; + sw6 { + gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-B"; + linux,code = ; // 0x131 + }; + sw7 { + gpios = <&gpio2 RK_PA1 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-Y"; + linux,code = ; // 0x133 + }; + sw8 { + gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-X"; + linux,code = ; // 0x134 + }; + sw9 { + gpios = <&gpio2 RK_PB0 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-SELECT"; + linux,code = ; // 0x13a + }; + sw10 { + gpios = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-START"; + linux,code = ; // 0x13b + }; + sw11 { + gpios = <&gpio2 RK_PB1 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-THUMBL"; + linux,code = ; // 0x13d + }; + sw12 { + gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-THUMBR"; + linux,code = ; // 0x13e + }; + sw13 { + gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-G"; + linux,code = ; // 0x2c0 + }; + sw14 { + gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-LEFT"; + linux,code = ; // 0x136 + }; + sw15 { + gpios = <&gpio2 RK_PA7 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-RIGHT"; + linux,code = ; // 0x137 + }; + sw16 { + gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-RIGHT2"; + linux,code = ; // 0x139 + }; + sw17 { + gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-LEFT2"; + linux,code = ; // 0x138 + }; + }; + + battery: battery { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <3000000>; + charge-term-current-microamp = <200000>; + constant-charge-current-max-microamp = <1500000>; + constant-charge-voltage-max-microvolt = <4200000>; + factory-internal-resistance-micro-ohms = <100000>; + voltage-max-design-microvolt = <4100000>; + voltage-min-design-microvolt = <3300000>; + + ocv-capacity-celsius = <20>; + ocv-capacity-table-0 = + <4046950 100>, <4001920 95>, <3967900 90>, <3940000 85>, + <3910000 80>, <3870000 75>, <3830000 70>, <3790000 65>, + <3750000 60>, <3720000 55>, <3690000 50>, <3650000 45>, + <3610000 40>, <3570000 35>, <3540000 30>, <3500000 25>, + <3460000 20>, <3420000 15>, <3380000 10>, <3340000 5>, + <3300000 0>; + }; + + gpio-keys-vol { + compatible = "gpio-keys"; + autorepeat; + pinctrl-0 = <&btn_pins_vol>; + pinctrl-names = "default"; + + button-vol-down { + gpios = <&gpio0 RK_PC1 GPIO_ACTIVE_LOW>; + label = "VOLUMEDOWN"; + linux,code = ; + }; + + button-vol-up { + gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_LOW>; + label = "VOLUMEUP"; + linux,code = ; + }; + }; + + leds: gpio-leds { + compatible = "gpio-leds"; + pinctrl-0 = <&led_pins>; + pinctrl-names = "default"; + + led-0 { + color = ; + default-state = "off"; + function = LED_FUNCTION_CHARGING; + gpios = <&gpio0 RK_PB3 GPIO_ACTIVE_HIGH>; + }; + + led-1 { + color = ; + default-state = "off"; + function = LED_FUNCTION_STATUS; + gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>; + }; + }; + + rk817-sound { + compatible = "simple-audio-card"; + pinctrl-names = "default"; + pinctrl-0 = <&hp_det>; + simple-audio-card,name = "rk817_int"; + simple-audio-card,format = "i2s"; + simple-audio-card,hp-det-gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_LOW>; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Headphone", "Headphones", + "Speaker", "Speaker"; + simple-audio-card,routing = + "MICL", "Mic Jack", + "Headphones", "HPOL", + "Headphones", "HPOR", + "Speaker", "SPKO"; + + simple-audio-card,codec { + sound-dai = <&rk817>; + }; + + simple-audio-card,cpu { + sound-dai = <&i2s1_2ch>; + }; + }; + + vccsys: vccsys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v8_sys"; + regulator-always-on; + regulator-min-microvolt = <3800000>; + regulator-max-microvolt = <3800000>; + }; + + vcc-phy-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc_phy"; + regulator-always-on; + regulator-boot-on; + }; + + vcc18_lcd0: vcc18-lcd0 { + compatible = "regulator-fixed"; + regulator-name = "vcc18_lcd0_n"; + gpio = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>; + enable-active-high; + pinctrl-0 = <&vcc18_lcd_n>; + pinctrl-names = "default"; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_host: vcc_host { + compatible = "regulator-fixed"; + regulator-name = "vcc_host"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + vin-supply = <&usb_midu>; + }; +}; + +&dmc { + center-supply = <&vdd_logic>; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&cpu1 { + cpu-supply = <&vdd_arm>; +}; + +&cpu2 { + cpu-supply = <&vdd_arm>; +}; + +&cpu3 { + cpu-supply = <&vdd_arm>; +}; + +&cru { + assigned-clocks = <&cru PLL_NPLL>, + <&cru ACLK_BUS_PRE>, <&cru ACLK_PERI_PRE>, + <&cru HCLK_BUS_PRE>, <&cru HCLK_PERI_PRE>, + <&cru PCLK_BUS_PRE>, <&cru SCLK_GPU>; + + assigned-clock-rates = <1188000000>, + <200000000>, <200000000>, + <150000000>, <150000000>, + <100000000>, <200000000>; +}; + +&display_subsystem { + status = "okay"; +}; + +&dsi { + status = "okay"; + + ports { + mipi_out: port@1 { + reg = <1>; + + mipi_out_panel: endpoint { + remote-endpoint = <&mipi_in_panel>; + }; + }; + }; + + internal_display: panel@0 { + compatible = "magicx,xu10-panel", "sitronix,st7703"; + iovcc-supply = <&vcc18_lcd0>; + vcc-supply = <&vcc18_lcd0>; + reg = <0>; + backlight = <&backlight>; + reset-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&lcd_rst>; + + port { + mipi_in_panel: endpoint { + remote-endpoint = <&mipi_out_panel>; + }; + }; + }; +}; + +&dsi_dphy { + status = "okay"; +}; + +&gpu { + mali-supply = <&vdd_logic>; + status = "okay"; +}; + +&i2c0 { + clock-frequency = <400000>; + i2c-scl-falling-time-ns = <16>; + i2c-scl-rising-time-ns = <280>; + status = "okay"; + + rk817: pmic@20 { + compatible = "rockchip,rk817"; + reg = <0x20>; + interrupt-parent = <&gpio0>; + interrupts = ; + clock-output-names = "rk808-clkout1", "xin32k"; + clock-names = "mclk"; + clocks = <&cru SCLK_I2S1_OUT>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int>, <&i2s1_2ch_mclk>; + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <1>; + #sound-dai-cells = <0>; + + vcc1-supply = <&vccsys>; + vcc2-supply = <&vccsys>; + vcc3-supply = <&vccsys>; + vcc4-supply = <&vccsys>; + vcc5-supply = <&vccsys>; + vcc6-supply = <&vccsys>; + vcc7-supply = <&vcc_3v0>; + vcc8-supply = <&vccsys>; + vcc9-supply = <&usb_midu>; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-name = "vdd_logic"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1150000>; + regulator-ramp-delay = <6001>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vdd_arm: DCDC_REG2 { + regulator-name = "vdd_arm"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_3v0: DCDC_REG4 { + regulator-name = "vcc_3v0"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcc_1v0: LDO_REG1 { + regulator-name = "vcc_1v0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc1v8_soc: LDO_REG2 { + regulator-name = "vcc1v8_soc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc1v0_soc: LDO_REG3 { + regulator-name = "vcc1v0_soc"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc3v0_pmu: LDO_REG4 { + regulator-name = "vcc3v0_pmu"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vccio_sd: LDO_REG5 { + regulator-name = "vccio_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_sd: LDO_REG6 { + regulator-name = "vcc_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcc2v8_dvp: LDO_REG7 { + regulator-name = "vcc2v8_dvp"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <2800000>; + }; + }; + + vcc3v0_dvp: LDO_REG8 { + regulator-name = "vcc3v0_dvp"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vdd1v5_dvp: LDO_REG9 { + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-name = "vdd1v5_dvp"; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <1500000>; + }; + }; + + usb_midu: BOOST { + regulator-name = "usb_midu"; + regulator-min-microvolt = <4700000>; + regulator-max-microvolt = <5400000>; + regulator-always-on; + regulator-boot-on; + }; + + }; + + rk817_charger: charger { + monitored-battery = <&battery>; + rockchip,resistor-sense-micro-ohms = <10000>; + rockchip,sleep-enter-current-microamp = <300000>; + rockchip,sleep-filter-current-microamp = <100000>; + }; + + rk817_codec: codec { + rockchip,mic-in-differential; + }; + }; +}; + +/* I2S 1 Channel Used Header(P2):1(GPIO2.C3),2(.C2), 3(.C1), 4(.C5), 5(.C4) */ +&i2s1_2ch { + status = "okay"; + #sound-dai-cells = <0>; +}; + +&io_domains { + vccio1-supply = <&vcc1v8_soc>; + vccio2-supply = <&vccio_sd>; + vccio3-supply = <&vcc3v0_dvp>; + vccio4-supply = <&vcc_3v0>; + vccio5-supply = <&vcc_3v0>; + vccio6-supply = <&vcc_3v0>; + status = "okay"; +}; + +&isp { + status = "okay"; +}; + +&isp_mmu { + status = "okay"; +}; + +&pmu_io_domains { + pmuio1-supply = <&vcc3v0_pmu>; + pmuio2-supply = <&vcc3v0_pmu>; + status = "okay"; +}; + +&csi_dphy { + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; + +&saradc { + vref-supply = <&vcc1v8_soc>; + status = "okay"; +}; + +&sdmmc { + cap-sd-highspeed; + card-detect-delay = <200>; + cd-gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_LOW>; /*[> ff370000 PD_SDCARD CD GPIO <]*/ + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&sdio { + cap-sd-highspeed; + card-detect-delay = <200>; + cd-gpios = <&gpio3 RK_PB6 GPIO_ACTIVE_LOW>; /*[> CD GPIO <]*/ + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&tsadc { + status = "okay"; +}; + +&u2phy { + status = "okay"; + + u2phy_host: host-port { + status = "okay"; + }; + + u2phy_otg: otg-port { + status = "disabled"; + }; +}; + +/* FIQ Header(P2): 2(RXD:GPIO2.B4),3(TXD:.B6) */ +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2m1_xfer>; + status = "okay"; +}; + +&usb20_otg { + status = "okay"; + dr_mode = "host"; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; + +&pinctrl { + btns { + btn_pins: btn-pins { + rockchip,pins = <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + btn_pins_vol: btn-pins-vol { + rockchip,pins = + <0 RK_PC1 RK_FUNC_GPIO &pcfg_pull_up>, + <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + headphone { + hp_det: hp-det { + rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + gpio-lcd { + lcd_rst: lcd-rst { + rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + vcc18-lcd { + vcc18_lcd_n: vcc18-lcd-n { + rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + gpio-led { + led_pins: led-pins { + rockchip,pins = + <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>, + <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pmic { + dc_det: dc-det { + rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + pmic_int: pmic-int { + rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + soc_slppin_gpio: soc_slppin_gpio { + rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>; + }; + + soc_slppin_rst: soc_slppin_rst { + rockchip,pins = <0 RK_PA4 2 &pcfg_pull_none>; + }; + + soc_slppin_slp: soc_slppin_slp { + rockchip,pins = <0 RK_PA4 1 &pcfg_pull_none>; + }; + }; +}; diff --git a/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-odroid-go.dtsi b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-odroid-go.dtsi new file mode 100644 index 0000000000..b655d10598 --- /dev/null +++ b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-odroid-go.dtsi @@ -0,0 +1,568 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Hardkernel Co., Ltd + * Copyright (c) 2020 Theobroma Systems Design und Consulting GmbH + * Copyright (c) 2022 Maya Matuszczyk + */ + +/dts-v1/; +#include +#include +#include +#include +#include "rk3326.dtsi" + +/ { + aliases { + mmc0 = &sdmmc; + }; + + chosen { + stdout-path = "serial2:115200n8"; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + power-supply = <&vcc_bl>; + pwms = <&pwm1 0 25000 0>; + brightness-levels = < + 0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 + 24 25 26 27 28 29 30 31 + 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 + 56 57 58 59 60 61 62 63 + 64 65 66 67 68 69 70 71 + 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 + 88 89 90 91 92 93 94 95 + 96 97 98 99 100 101 102 103 + 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 + 128 129 130 131 132 133 134 135 + 136 137 138 139 140 141 142 143 + 144 145 146 147 148 149 150 151 + 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 + 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 + 184 185 186 187 188 189 190 191 + 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 + 208 209 210 211 212 213 214 215 + 216 217 218 219 220 221 222 223 + 224 225 226 227 228 229 230 231 + 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 + 248 249 250 251 252 253 254 255>; + default-brightness-level = <128>; + }; + + /* led-1 is wired directly to output of always-on regulator */ + + gpio_led: gpio-leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&red_led_pin>; + + red_led: led-3 { + color = ; + gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>; + function = LED_FUNCTION_CHARGING; + }; + }; + + pwm_led: led-controller { + compatible = "pwm-leds"; + + blue_led: led-2 { + color = ; + function = LED_FUNCTION_STATUS; + linux,default-trigger = "heartbeat"; + max-brightness = <255>; + pwms = <&pwm3 0 25000 0>; + }; + }; + + rk817-sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "rk817_int"; + simple-audio-card,format = "i2s"; + simple-audio-card,hp-det-gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Headphone", "Headphones", + "Speaker", "Speaker"; + simple-audio-card,routing = + "MICL", "Mic Jack", + "Headphones", "HPOL", + "Headphones", "HPOR", + "Speaker", "SPKO"; + + simple-audio-card,codec { + sound-dai = <&rk817>; + }; + + simple-audio-card,cpu { + sound-dai = <&i2s1_2ch>; + }; + }; + + vccsys: regulator-vccsys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v8_sys"; + regulator-always-on; + regulator-min-microvolt = <3800000>; + regulator-max-microvolt = <3800000>; + }; + + vcc_host: regulator-vcc-host { + compatible = "regulator-fixed"; + regulator-name = "vcc_host"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + + gpio = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + vin-supply = <&usb_midu>; + }; +}; + +&dmc { + center-supply = <&vdd_logic>; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&cpu1 { + cpu-supply = <&vdd_arm>; +}; + +&cpu2 { + cpu-supply = <&vdd_arm>; +}; + +&cpu3 { + cpu-supply = <&vdd_arm>; +}; + +&cru { + assigned-clocks = <&cru PLL_NPLL>, + <&cru ACLK_BUS_PRE>, <&cru ACLK_PERI_PRE>, + <&cru HCLK_BUS_PRE>, <&cru HCLK_PERI_PRE>, + <&cru PCLK_BUS_PRE>, <&cru SCLK_GPU>; + + assigned-clock-rates = <1188000000>, + <200000000>, <200000000>, + <150000000>, <150000000>, + <100000000>, <200000000>; +}; + +&display_subsystem { + status = "okay"; +}; + +&dsi { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + ports { + mipi_out: port@1 { + reg = <1>; + + mipi_out_panel: endpoint { + remote-endpoint = <&mipi_in_panel>; + }; + }; + }; + + internal_display: panel@0 { + reg = <0>; + backlight = <&backlight>; + reset-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>; + + port { + mipi_in_panel: endpoint { + remote-endpoint = <&mipi_out_panel>; + }; + }; + }; +}; + +&dsi_dphy { + status = "okay"; +}; + +&gpu { + mali-supply = <&vdd_logic>; + status = "okay"; +}; + +&i2c0 { + clock-frequency = <400000>; + i2c-scl-falling-time-ns = <16>; + i2c-scl-rising-time-ns = <280>; + status = "okay"; + + rk817: pmic@20 { + compatible = "rockchip,rk817"; + reg = <0x20>; + interrupt-parent = <&gpio0>; + interrupts = ; + clock-output-names = "rk808-clkout1", "xin32k"; + clock-names = "mclk"; + clocks = <&cru SCLK_I2S1_OUT>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int>, <&i2s1_2ch_mclk>; + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <1>; + #sound-dai-cells = <0>; + + vcc1-supply = <&vccsys>; + vcc2-supply = <&vccsys>; + vcc3-supply = <&vccsys>; + vcc4-supply = <&vccsys>; + vcc5-supply = <&vccsys>; + vcc6-supply = <&vccsys>; + vcc7-supply = <&vccsys>; + vcc8-supply = <&vccsys>; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-name = "vdd_logic"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1150000>; + regulator-ramp-delay = <6001>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vdd_arm: DCDC_REG2 { + regulator-name = "vdd_arm"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_3v3: DCDC_REG4 { + regulator-name = "vcc_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_1v8: LDO_REG2 { + regulator-name = "vcc_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd_1v0: LDO_REG3 { + regulator-name = "vdd_1v0"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc3v3_pmu: LDO_REG4 { + regulator-name = "vcc3v3_pmu"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vccio_sd: LDO_REG5 { + regulator-name = "vccio_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_sd: LDO_REG6 { + regulator-name = "vcc_sd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_bl: LDO_REG7 { + regulator-name = "vcc_bl"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_lcd: LDO_REG8 { + regulator-name = "vcc_lcd"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <2800000>; + }; + }; + + LDO_REG9 { + /* unused */ + }; + + usb_midu: BOOST { + regulator-name = "usb_midu"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5400000>; + regulator-always-on; + regulator-boot-on; + }; + }; + + rk817_charger: charger { + rockchip,resistor-sense-micro-ohms = <10000>; + rockchip,sleep-enter-current-microamp = <300000>; + rockchip,sleep-filter-current-microamp = <100000>; + }; + + rk817_codec: codec { + rockchip,mic-in-differential; + }; + }; +}; + +/* EXT Header(P2): 7(SCL:GPIO0.C2), 8(SDA:GPIO0.C3) */ +&i2c1 { + clock-frequency = <400000>; + status = "okay"; +}; + +/* I2S 1 Channel Used */ +&i2s1_2ch { + status = "okay"; +}; + +&io_domains { + vccio1-supply = <&vcc_3v3>; + vccio2-supply = <&vccio_sd>; + vccio3-supply = <&vcc_3v3>; + vccio4-supply = <&vcc_3v3>; + vccio5-supply = <&vcc_3v3>; + vccio6-supply = <&vcc_3v3>; + status = "okay"; +}; + +&pmu_io_domains { + pmuio1-supply = <&vcc3v3_pmu>; + pmuio2-supply = <&vcc3v3_pmu>; + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; + +&pwm3 { + status = "okay"; +}; + +&saradc { + vref-supply = <&vcc_1v8>; + status = "okay"; +}; + +&sdmmc { + cap-sd-highspeed; + card-detect-delay = <200>; + cd-gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_LOW>; /*[> CD GPIO <]*/ + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&sfc { + pinctrl-0 = <&sfc_clk &sfc_cs0 &sfc_bus2>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <108000000>; + spi-rx-bus-width = <2>; + spi-tx-bus-width = <1>; + }; +}; + +&tsadc { + status = "okay"; +}; + +&u2phy { + status = "okay"; + + u2phy_host: host-port { + status = "okay"; + }; + + u2phy_otg: otg-port { + status = "disabled"; + }; +}; + +&usb20_otg { + status = "okay"; +}; + +/* EXT Header(P2): 2(RXD:GPIO1.C0),3(TXD:.C1),4(CTS:.C2),5(RTS:.C3) */ +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_xfer &uart1_cts>; + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2m1_xfer>; + status = "okay"; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; + +&pinctrl { + btns { + btn_pins: btn-pins { + rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + headphone { + hp_det: hp-det { + rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; + + leds { + red_led_pin: red-led-pin { + rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pmic { + dc_det: dc-det { + rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + pmic_int: pmic-int { + rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + soc_slppin_gpio: soc_slppin_gpio { + rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>; + }; + + soc_slppin_rst: soc_slppin_rst { + rockchip,pins = <0 RK_PA4 2 &pcfg_pull_none>; + }; + + soc_slppin_slp: soc_slppin_slp { + rockchip,pins = <0 RK_PA4 1 &pcfg_pull_none>; + }; + }; +}; diff --git a/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-odroid-go2-v11.dts b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-odroid-go2-v11.dts new file mode 100644 index 0000000000..f96fb0645a --- /dev/null +++ b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-odroid-go2-v11.dts @@ -0,0 +1,308 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Hardkernel Co., Ltd + * Copyright (c) 2020 Theobroma Systems Design und Consulting GmbH + * Copyright (c) 2022 Maya Matuszczyk + */ + +/dts-v1/; +#include "rk3326-odroid-go.dtsi" + +/ { + model = "ODROID-GO Advance Black Edition"; + compatible = "hardkernel,rk3326-odroid-go2-v11", "rockchip,rk3326"; + + aliases { + mmc1 = &sdio; + }; + + gpio_keys: volume-keys { + compatible = "gpio-keys"; + autorepeat; + pinctrl-0 = <&btn_pins_vol>; + pinctrl-names = "default"; + + volume-up-button { + label = "VOLUMEUP"; + linux,code = ; + gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; + + }; + volume-down-button { + label = "VOLUMEDOWN"; + linux,code = ; + gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; + + }; + }; + + joypad: odroidgo2-joypad { + compatible = "odroidgo2-v11-joypad"; + + /* + - odroidgo2-joypad sysfs list - + * for poll device interval(ms) + /sys/devices/platform/odroidgo2_joypad/poll_interval [rw] + * for button-adc-fuzz + /sys/devices/platform/odroidgo2_joypad/adc_fuzz [r] + * for button-adc-flat + /sys/devices/platform/odroidgo2_joypad/adc_flat [r] + + * for report control(1:enable, 0:disable) + /sys/devices/platform/odroidgo2_joypad/enable [rw] + * for adc calibration value setup(1:current adcs value -> cal value) + /sys/devices/platform/odroidgo2_joypad/adc_cal [rw] + */ + + /* gpio pincontrol setup */ + pinctrl-names = "default"; + pinctrl-0 = <&btn_pins>; + + /* JOY_X, JOY_Y Channel define */ + io-channel-names = "joy_x", "joy_y"; + io-channels = <&saradc 1>, <&saradc 2>; + + /* adc channel count */ + button-adc-count = <2>; + + /* adc calculate scale */ + button-adc-scale = <2>; + + /* adc deadzone range */ + button-adc-deadzone = <20>; + + /* + joy-stick voltage range + /sys/devices/platform/ff288000.saradc/iio:device0 + adc-x : in_voltage1_raw + adc-y : in_voltage2_raw + + range calculate. + (adc raw max value - adc raw min value) * scale * 1.7515 + */ + button-adc-x-range = <1800>; + button-adc-y-range = <1800>; + + /* + specifies fuzz value that is used to filter noise from + the event stream. + */ + button-adc-fuzz = <32>; + button-adc-flat = <32>; + + /* poll device interval (ms), adc read interval */ + poll-interval = <10>; + + /* gpio button auto repeat set value : default disable */ + /* + autorepeat; + */ + + /* + *** ODROIDGO2-Advance Switch layoout *** + |------------------------------------------------| + | sw15 sw16 | + | sw20 sw21 | + |------------------------------------------------| + | sw1 |-------------------| sw8 | + | sw3 sw4 | | sw7 sw5 | + | sw2 | LCD Display | sw6 | + | | | | + | |-------------------| | + | sw9 sw10 vol- vol+ sw13 sw14 | + |------------------------------------------------| + */ + /* + joypad driver is poll-device driver. + poll-device is does not support wakeup-source. + */ + sw1 { + gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-UP"; + linux,code = ; // 0x220 + }; + sw2 { + gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-DOWN"; + linux,code = ; // 0x221 + }; + sw3 { + gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-LEFT"; + linux,code = ; // 0x222 + }; + sw4 { + gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-RIGHT"; + linux,code = ; // 0x223 + }; + sw5 { + gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>; + label = "GPIO KEY BTN-A"; + linux,code = ; // 0x131 + }; + sw6 { + gpios = <&gpio1 RK_PA5 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-B"; + linux,code = ; // 0x130 + }; + sw7 { + gpios = <&gpio1 RK_PA6 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-Y"; + linux,code = ; // 0x134 + }; + sw8 { + gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-X"; + linux,code = ; // 0x133 + }; + sw9 { + gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-SELECT"; + linux,code = ; // 0x2c0 + }; + sw10 { + gpios = <&gpio2 RK_PA1 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-THUMBL"; + linux,code = ; // 0x2c1 + }; + sw13 { + gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-THUMBR"; + linux,code = ; // 0x2c4 + }; + sw14 { + gpios = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-START"; + linux,code = ; // 0x13c + }; + sw15 { + gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-LEFT"; + linux,code = ; // 0x02 + }; + sw16 { + gpios = <&gpio2 RK_PA7 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-RIGHT"; + linux,code = ; // 0x05 + }; + sw20 { + gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-LEFT2"; + linux,code = ; + }; + sw21 { + gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-RIGHT2"; + linux,code = ; + }; + }; + + battery: battery { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <3000000>; + charge-term-current-microamp = <300000>; + constant-charge-current-max-microamp = <2000000>; + constant-charge-voltage-max-microvolt = <4200000>; + factory-internal-resistance-micro-ohms = <180000>; + voltage-max-design-microvolt = <4100000>; + voltage-min-design-microvolt = <3500000>; + + ocv-capacity-celsius = <20>; + ocv-capacity-table-0 = <4046950 100>, <4001920 95>, <3967900 90>, <3919950 85>, + <3888450 80>, <3861850 75>, <3831540 70>, <3799130 65>, + <3768190 60>, <3745650 55>, <3726610 50>, <3711630 45>, + <3696720 40>, <3685660 35>, <3674950 30>, <3663050 25>, + <3649470 20>, <3635260 15>, <3616920 10>, <3592440 5>, + <3574170 0>; + }; + + wifi_pwrseq: wifi-pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_pwrseq_pins>; + reset-gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>; + post-power-on-delay-ms = <300>; + power-off-delay-us = <200000>; + }; +}; + +&internal_display { + compatible = "elida,kd35t133"; + iovcc-supply = <&vcc_lcd>; + vdd-supply = <&vcc_lcd>; + rotation = <270>; +}; + +&rk817 { + regulators { + vcc_wifi: LDO_REG9 { + regulator-name = "vcc_wifi"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + }; +}; + +&rk817_charger { + monitored-battery = <&battery>; +}; + +&sdio { + bus-width = <4>; + cap-sd-highspeed; + cap-sdio-irq; + disable-wp; + keep-power-in-suspend; + non-removable; + vmmc-supply = <&vcc_wifi>; + mmc-pwrseq = <&wifi_pwrseq>; + status = "okay"; + + esp8089: wifi@1 { + compatible = "esp,esp8089"; + reg = <1>; + esp,crystal-26M-en = <1>; + }; +}; + +&pinctrl { + btns { + btn_pins: btn-pins { + rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + btn_pins_vol: btn-pins-vol { + rockchip,pins = <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + wifi { + wifi_pwrseq_pins: wifi-pwrseq-pins { + rockchip,pins = <3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB6 RK_FUNC_GPIO &pcfg_output_high>; + }; + }; +}; diff --git a/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-odroid-go2.dts b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-odroid-go2.dts new file mode 100644 index 0000000000..f142737a01 --- /dev/null +++ b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-odroid-go2.dts @@ -0,0 +1,235 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Hardkernel Co., Ltd + * Copyright (c) 2020 Theobroma Systems Design und Consulting GmbH + * Copyright (c) 2022 Maya Matuszczyk + */ + +/dts-v1/; +#include "rk3326-odroid-go.dtsi" + +/ { + model = "ODROID-GO Advance"; + compatible = "hardkernel,rk3326-odroid-go2", "rockchip,rk3326"; + + gpio_keys: volume-keys { + compatible = "gpio-keys-polled"; + poll-interval = <5>; + autorepeat; + + volume-up-button { + label = "VOLUME-UP"; + linux,code = ; + gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; + + }; + volume-down-button { + label = "VOLUME-DOWN"; + linux,code = ; + gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; + + }; + }; + + joypad: odroidgo2-joypad { + compatible = "odroidgo2-joypad"; + + /* + - odroidgo2-joypad sysfs list - + * for poll device interval(ms) + /sys/devices/platform/odroidgo2_joypad/poll_interval [rw] + * for button-adc-fuzz + /sys/devices/platform/odroidgo2_joypad/adc_fuzz [r] + * for button-adc-flat + /sys/devices/platform/odroidgo2_joypad/adc_flat [r] + + * for report control(1:enable, 0:disable) + /sys/devices/platform/odroidgo2_joypad/enable [rw] + * for adc calibration value setup(1:current adcs value -> cal value) + /sys/devices/platform/odroidgo2_joypad/adc_cal [rw] + */ + + /* gpio pincontrol setup */ + pinctrl-names = "default"; + pinctrl-0 = <&btn_pins>; + + /* JOY_X, JOY_Y Channel define */ + io-channel-names = "joy_x", "joy_y"; + io-channels = <&saradc 1>, <&saradc 2>; + + /* adc channel count */ + button-adc-count = <2>; + + /* adc calculate scale */ + button-adc-scale = <2>; + + /* adc deadzone range */ + button-adc-deadzone = <20>; + + /* + joy-stick voltage range + /sys/devices/platform/ff288000.saradc/iio:device0 + adc-x : in_voltage1_raw + adc-y : in_voltage2_raw + + range calculate. + (adc raw max value - adc raw min value) * scale * 1.7515 + */ + button-adc-x-range = <1800>; + button-adc-y-range = <1800>; + + /* + specifies fuzz value that is used to filter noise from + the event stream. + */ + button-adc-fuzz = <32>; + button-adc-flat = <32>; + + /* poll device interval (ms), adc read interval */ + poll-interval = <10>; + + /* gpio button auto repeat set value : default disable */ + /* + autorepeat; + */ + + /* + *** ODROIDGO2-Advance Switch layoout *** + |------------------------------------------------| + | sw15 sw16 | + |------------------------------------------------| + | sw1 |-------------------| sw8 | + | sw3 sw4 | | sw7 sw5 | + | sw2 | LCD Display | sw6 | + | | | | + | |-------------------| | + | sw9 sw10 vol- vol+ sw13 sw14 | + |------------------------------------------------| + */ + /* + joypad driver is poll-device driver. + poll-device is does not support wakeup-source. + */ + sw1 { + gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-UP"; + linux,code = ; // 0x220 + }; + sw2 { + gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-DOWN"; + linux,code = ; // 0x221 + }; + sw3 { + gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-LEFT"; + linux,code = ; // 0x222 + }; + sw4 { + gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-RIGHT"; + linux,code = ; // 0x223 + }; + sw5 { + gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>; + label = "GPIO KEY BTN-A"; + linux,code = ; // 0x131 + }; + sw6 { + gpios = <&gpio1 RK_PA5 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-B"; + linux,code = ; // 0x130 + }; + sw7 { + gpios = <&gpio1 RK_PA6 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-Y"; + linux,code = ; // 0x134 + }; + sw8 { + gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-X"; + linux,code = ; // 0x133 + }; + sw9 { + gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; + label = "GPIO F1"; + linux,code = ; // 0x2c0 + }; + sw10 { + gpios = <&gpio2 RK_PA1 GPIO_ACTIVE_LOW>; + label = "GPIO F2"; + linux,code = ; // 0x2c1 + }; + sw13 { + gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_LOW>; + label = "GPIO F5"; + linux,code = ; // 0x2c4 + }; + sw14 { + gpios = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>; + label = "GPIO F6"; + linux,code = ; // 0x13c + }; + sw15 { + gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-LEFT"; + linux,code = ; // 0x02 + }; + sw16 { + gpios = <&gpio2 RK_PA7 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-RIGHT"; + linux,code = ; // 0x05 + }; + }; + + battery: battery { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <3000000>; + charge-term-current-microamp = <300000>; + constant-charge-current-max-microamp = <2000000>; + constant-charge-voltage-max-microvolt = <4200000>; + factory-internal-resistance-micro-ohms = <180000>; + voltage-max-design-microvolt = <4100000>; + voltage-min-design-microvolt = <3500000>; + + ocv-capacity-celsius = <20>; + ocv-capacity-table-0 = <4046950 100>, <4001920 95>, <3967900 90>, <3919950 85>, + <3888450 80>, <3861850 75>, <3831540 70>, <3799130 65>, + <3768190 60>, <3745650 55>, <3726610 50>, <3711630 45>, + <3696720 40>, <3685660 35>, <3674950 30>, <3663050 25>, + <3649470 20>, <3635260 15>, <3616920 10>, <3592440 5>, + <3574170 0>; + }; +}; + +&internal_display { + compatible = "elida,kd35t133"; + iovcc-supply = <&vcc_lcd>; + vdd-supply = <&vcc_lcd>; + rotation = <270>; +}; + +&rk817_charger { + monitored-battery = <&battery>; +}; + +&pinctrl { + btns { + btn_pins: btn-pins { + rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; diff --git a/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-odroid-go3.dts b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-odroid-go3.dts new file mode 100644 index 0000000000..c3099f9cfe --- /dev/null +++ b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-odroid-go3.dts @@ -0,0 +1,289 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Hardkernel Co., Ltd + * Copyright (c) 2020 Theobroma Systems Design und Consulting GmbH + * Copyright (c) 2022 Maya Matuszczyk + */ + +/dts-v1/; +#include "rk3326-odroid-go.dtsi" + +/ { + model = "ODROID-GO Super"; + compatible = "hardkernel,rk3326-odroid-go3", "rockchip,rk3326"; + + joypad: odroidgo3-joypad { + compatible = "odroidgo3-joypad"; + + joypad-name = "odroidgo3_joypad"; + joypad-product = <0x0001>; + joypad-revision = <0x0101>; + + status = "okay"; + /* + - odroidgo3-joypad sysfs list - + * for poll device interval(ms) + /sys/devices/platform/odroidgo3_joypad/poll_interval [rw] + ex) echo 20 > poll_interval + * for button-adc-fuzz + /sys/devices/platform/odroidgo3_joypad/adc_fuzz [r] + * for button-adc-flat + /sys/devices/platform/odroidgo3_joypad/adc_flat [r] + + * for report control(1:enable, 0:disable) + /sys/devices/platform/odroidgo3_joypad/enable [rw] + * for adc calibration value setup(current adcs value -> cal value) + /sys/devices/platform/odroidgo3_joypad/adc_cal [rw] + ex) echo 0 > adc_cal + * for amux data debug + * Joypad driver is disabled when using this sysfs. + /sys/devices/platform/odroidgo3_joypad/amux_debug [rw] + ex) echo 0 > amux_debug --> select amux channel + ex) cat amux_debug --> get adc data of seleted channel + */ + + /* gpio pincontrol setup */ + pinctrl-names = "default"; + pinctrl-0 = <&btn_pins>; + + /* Analog mux define */ + io-channel-names = "amux_adc"; + io-channels = <&saradc 1>; + + /* adc mux channel count */ + amux-count = <4>; + /* adc mux select(a,b) gpio */ + amux-a-gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_LOW>; + amux-b-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>; + /* adc mux enable gpio */ + amux-en-gpios = <&gpio3 RK_PB5 GPIO_ACTIVE_LOW>; + + /* adc calculate scale */ + button-adc-scale = <2>; + + /* adc deadzone range */ + button-adc-deadzone = <64>; + + /* + specifies fuzz value that is used to filter noise from + the event stream. + */ + button-adc-fuzz = <32>; + button-adc-flat = <32>; + + /* + Analog Stick data tuning value(precent) + p = positive direction, n = negative direction + report value = (real_adc_data * tuning_value) / 100 + */ + abs_x-p-tuning = <180>; + abs_x-n-tuning = <180>; + + abs_y-p-tuning = <180>; + abs_y-n-tuning = <170>; + + abs_rx-p-tuning = <180>; + abs_rx-n-tuning = <180>; + + abs_ry-p-tuning = <180>; + abs_ry-n-tuning = <170>; + + /* poll device interval (ms), adc read interval */ + poll-interval = <10>; + + /* gpio button auto repeat set value : default disable */ + /* + autorepeat; + */ + + /* + *** ODROIDGO3-Advance Switch layoout *** + |------------------------------------------------| + | sw15 sw21 sw10 sw9 sw20 sw16 | + |------------------------------------------------| + | sw19 sw22 | + | |-------------------| | + | sw1 | | sw8 | + | sw3 sw4 | | sw7 sw5 | + | sw2 | LCD Display | sw6 | + | | | | + | | | | + | |-------------------| | + | sw11 sw12 | sd-slot | sw13 sw14 | + |-------------------| |------------------| + */ + /* + joypad driver is poll-device driver. + poll-device is does not support wakeup-source. + */ + sw1 { + gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-UP"; + linux,code = ; // 0x220 + }; + sw2 { + gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-DOWN"; + linux,code = ; // 0x221 + }; + sw3 { + gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-LEFT"; + linux,code = ; // 0x222 + }; + sw4 { + gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-RIGHT"; + linux,code = ; // 0x223 + }; + sw5 { + gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>; + label = "GPIO KEY BTN-A"; + linux,code = ; // 0x131 + }; + sw6 { + gpios = <&gpio1 RK_PA5 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-B"; + linux,code = ; // 0x130 + }; + sw7 { + gpios = <&gpio1 RK_PA6 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-Y"; + linux,code = ; // 0x134 + }; + sw8 { + gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-X"; + linux,code = ; // 0x133 + }; + sw11 { + gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; + label = "GPIO F3"; + linux,code = ; // 0x2c2 + }; + sw12 { + gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; + label = "GPIO F4"; + linux,code = ; // 0x2c3 + }; + sw13 { + gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_LOW>; + label = "GPIO F5"; + linux,code = ; // 0x2c4 + }; + sw14 { + gpios = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>; + label = "GPIO F6"; + linux,code = ; // 0x13c + }; + sw15 { + gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-LEFT"; + linux,code = ; // 0x02 + }; + sw16 { + gpios = <&gpio2 RK_PA7 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-RIGHT"; + linux,code = ; // 0x05 + }; + sw19 { + gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>; + label = "GPIO F1"; + linux,code = ; + }; + sw20 { + gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-RIGHT2"; + linux,code = ; + }; + sw21 { + gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-LEFT2"; + linux,code = ; + }; + sw22 { + gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; + label = "GPIO F2"; + linux,code = ; + }; + }; + + battery: battery { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <4000000>; + charge-term-current-microamp = <300000>; + constant-charge-current-max-microamp = <2000000>; + constant-charge-voltage-max-microvolt = <4200000>; + factory-internal-resistance-micro-ohms = <180000>; + voltage-max-design-microvolt = <4100000>; + voltage-min-design-microvolt = <3500000>; + + ocv-capacity-celsius = <20>; + ocv-capacity-table-0 = <4046950 100>, <4001920 95>, <3967900 90>, <3919950 85>, + <3888450 80>, <3861850 75>, <3831540 70>, <3799130 65>, + <3768190 60>, <3745650 55>, <3726610 50>, <3711630 45>, + <3696720 40>, <3685660 35>, <3674950 30>, <3663050 25>, + <3649470 20>, <3635260 15>, <3616920 10>, <3592440 5>, + <3574170 0>; + }; + + gpio-keys-vol { + compatible = "gpio-keys"; + autorepeat; + pinctrl-0 = <&btn_pins_vol>; + pinctrl-names = "default"; + + button-vol-down { + gpios = <&gpio2 RK_PA1 GPIO_ACTIVE_LOW>; + label = "VOLUMEDOWN"; + linux,code = ; + }; + + button-volume-up { + gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; + label = "VOLUMEUP"; + linux,code = ; + }; + }; +}; + +&internal_display { + compatible = "elida,kd50t048a", "sitronix,st7701"; + reset-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_HIGH>; + IOVCC-supply = <&vcc_lcd>; + VCC-supply = <&vcc_lcd>; + rotation = <270>; +}; + +&rk817_charger { + monitored-battery = <&battery>; +}; + +&pinctrl { + btns { + btn_pins: btn-pins { + rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + btn_pins_vol: btn-pins-vol { + rockchip,pins = <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; diff --git a/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-powkiddy-rgb10.dts b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-powkiddy-rgb10.dts new file mode 100644 index 0000000000..23a30542b9 --- /dev/null +++ b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-powkiddy-rgb10.dts @@ -0,0 +1,280 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Hardkernel Co., Ltd + * Copyright (c) 2020 Theobroma Systems Design und Consulting GmbH + * Copyright (c) 2022 Maya Matuszczyk + */ + +/dts-v1/; +#include "rk3326-odroid-go.dtsi" + +/ { + model = "Powkiddy RGB10"; + compatible = "powkiddy,rk3326-rgb10", "rockchip,rk3326"; + + aliases { + mmc1 = &sdio; + }; + + joypad: odroidgo2-joypad { + compatible = "odroidgo2-v11-joypad"; + + /* + - odroidgo2-joypad sysfs list - + * for poll device interval(ms) + /sys/devices/platform/odroidgo2_joypad/poll_interval [rw] + * for button-adc-fuzz + /sys/devices/platform/odroidgo2_joypad/adc_fuzz [r] + * for button-adc-flat + /sys/devices/platform/odroidgo2_joypad/adc_flat [r] + + * for report control(1:enable, 0:disable) + /sys/devices/platform/odroidgo2_joypad/enable [rw] + * for adc calibration value setup(1:current adcs value -> cal value) + /sys/devices/platform/odroidgo2_joypad/adc_cal [rw] + */ + + /* gpio pincontrol setup */ + pinctrl-names = "default"; + pinctrl-0 = <&btn_pins>; + + /* JOY_X, JOY_Y Channel define */ + io-channel-names = "joy_x", "joy_y"; + io-channels = <&saradc 1>, <&saradc 2>; + + /* adc channel count */ + button-adc-count = <2>; + + /* adc calculate scale */ + button-adc-scale = <2>; + + /* adc deadzone range */ + button-adc-deadzone = <20>; + + /* + joy-stick voltage range + /sys/devices/platform/ff288000.saradc/iio:device0 + adc-x : in_voltage1_raw + adc-y : in_voltage2_raw + + range calculate. + (adc raw max value - adc raw min value) * scale * 1.7515 + */ + button-adc-x-range = <1800>; + button-adc-y-range = <1800>; + + /* + specifies fuzz value that is used to filter noise from + the event stream. + */ + button-adc-fuzz = <32>; + button-adc-flat = <32>; + + /* poll device interval (ms), adc read interval */ + poll-interval = <10>; + + /* gpio button auto repeat set value : default disable */ + /* + autorepeat; + */ + + /* + *** RGB10 Switch layoout *** + |------------------------------------------------| + | sw15 sw16 | + | sw20 sw21 | + |------------------------------------------------| + | sw1 sw10 |-------------------| sw13 sw8 | + | sw3 sw4 | | sw7 sw5 | + | sw2 | LCD Display | sw6 | + | | | | + | |-------------------| | + |------------------------------------------------| + */ + /* + joypad driver is poll-device driver. + poll-device is does not support wakeup-source. + */ + sw1 { + gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-UP"; + linux,code = ; // 0x220 + }; + sw2 { + gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-DOWN"; + linux,code = ; // 0x221 + }; + sw3 { + gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-LEFT"; + linux,code = ; // 0x222 + }; + sw4 { + gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-RIGHT"; + linux,code = ; // 0x223 + }; + sw5 { + gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>; + label = "GPIO KEY BTN-A"; + linux,code = ; // 0x131 + }; + sw6 { + gpios = <&gpio1 RK_PA5 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-B"; + linux,code = ; // 0x130 + }; + sw7 { + gpios = <&gpio1 RK_PA6 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-Y"; + linux,code = ; // 0x134 + }; + sw8 { + gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-X"; + linux,code = ; // 0x133 + }; + sw9 { + gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-SELECT"; + linux,code = ; // 0x2c0 + }; + sw10 { + gpios = <&gpio2 RK_PA1 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-THUMBL"; + linux,code = ; // 0x2c1 + }; + sw13 { + gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-THUMBR"; + linux,code = ; // 0x2c4 + }; + sw14 { + gpios = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-START"; + linux,code = ; // 0x13c + }; + sw15 { + gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-LEFT"; + linux,code = ; // 0x02 + }; + sw16 { + gpios = <&gpio2 RK_PA7 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-RIGHT"; + linux,code = ; // 0x05 + }; + sw20 { + gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-LEFT2"; + linux,code = ; + }; + sw21 { + gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-RIGHT2"; + linux,code = ; + }; + }; + + battery: battery { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <2800000>; + charge-term-current-microamp = <280000>; + constant-charge-current-max-microamp = <2000000>; + constant-charge-voltage-max-microvolt = <4200000>; + factory-internal-resistance-micro-ohms = <180000>; + voltage-max-design-microvolt = <4100000>; + voltage-min-design-microvolt = <3500000>; + + ocv-capacity-celsius = <20>; + ocv-capacity-table-0 = <4046950 100>, <4001920 95>, <3967900 90>, <3919950 85>, + <3888450 80>, <3861850 75>, <3831540 70>, <3799130 65>, + <3768190 60>, <3745650 55>, <3726610 50>, <3711630 45>, + <3696720 40>, <3685660 35>, <3674950 30>, <3663050 25>, + <3649470 20>, <3635260 15>, <3616920 10>, <3592440 5>, + <3574170 0>; + }; + + wifi_pwrseq: wifi-pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_pwrseq_pins>; + /*reset-gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>;*/ + }; +}; + +&internal_display { + compatible = "elida,kd35t133"; + iovcc-supply = <&vcc_lcd>; + vdd-supply = <&vcc_lcd>; + rotation = <270>; +}; + +&rk817 { + regulators { + vcc_wifi: LDO_REG9 { + regulator-name = "vcc_wifi"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + }; +}; + +&rk817_charger { + monitored-battery = <&battery>; +}; + +&sdio { + bus-width = <4>; + cap-sd-highspeed; + cap-sdio-irq; + disable-wp; + keep-power-in-suspend; + non-removable; + vmmc-supply = <&vcc_wifi>; + status = "okay"; + + esp8089: wifi@1 { + compatible = "esp,esp8089"; + reg = <1>; + esp,crystal-26M-en = <2>; + }; +}; + +&pinctrl { + btns { + btn_pins: btn-pins { + rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + wifi { + wifi_pwrseq_pins: wifi-pwrseq-pins { + rockchip,pins = /*<3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>,*/ + <3 RK_PB6 RK_FUNC_GPIO &pcfg_output_high>; + }; + }; +}; diff --git a/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-powkiddy-rgb10x.dts b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-powkiddy-rgb10x.dts new file mode 100644 index 0000000000..fe5f9571d6 --- /dev/null +++ b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-powkiddy-rgb10x.dts @@ -0,0 +1,215 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2024 ROCKNIX + * Copyright (c) 2024 ArchR + */ + +/dts-v1/; +#include "rk3326-odroid-go.dtsi" +#include "retrogame_joypad_s2_f1.dtsi" +#include "rk3326-device-group-r36.dtsi" + +/ { + model = "Powkiddy RGB10X"; + compatible = "powkiddy,rk3326-rgb10x", "rockchip,rk3326"; + + archr,device_switch { + this = "rgb10x"; + }; + + aliases { + mmc1 = &sdio; + }; + + battery: battery { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <2800000>; + charge-term-current-microamp = <280000>; + constant-charge-current-max-microamp = <2000000>; + constant-charge-voltage-max-microvolt = <4200000>; + factory-internal-resistance-micro-ohms = <180000>; + voltage-max-design-microvolt = <4100000>; + voltage-min-design-microvolt = <3500000>; + + ocv-capacity-celsius = <20>; + ocv-capacity-table-0 = <4046950 100>, <4001920 95>, <3967900 90>, <3919950 85>, + <3888450 80>, <3861850 75>, <3831540 70>, <3799130 65>, + <3768190 60>, <3745650 55>, <3726610 50>, <3711630 45>, + <3696720 40>, <3685660 35>, <3674950 30>, <3663050 25>, + <3649470 20>, <3635260 15>, <3616920 10>, <3592440 5>, + <3574170 0>; + }; + + gpio-keys-vol { + compatible = "gpio-keys"; + autorepeat; + pinctrl-0 = <&btn_pins_vol>; + pinctrl-names = "default"; + + button-vol-down { + gpios = <&gpio2 RK_PA1 GPIO_ACTIVE_LOW>; + label = "VOLUMEDOWN"; + linux,code = ; + }; + + button-volume-up { + gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; + label = "VOLUMEUP"; + linux,code = ; + }; + }; +}; + +&joypad { + compatible = "archr-singleadc-joypad"; + joypad-name = "retrogame_joypad_s1_f2"; /* distinct name to indicate there is 1 stick and 2 fn buttons */ + joypad-product = <0x1112>; /* 11 inherited, 1 for number of sticks, 2 for number of FN */ + status = "okay"; + + /* gpio pincontrol setup */ + pinctrl-names = "default"; + pinctrl-0 = <&btn_pins>; + + /* Analog mux define */ + io-channel-names = "amux_adc"; + io-channels = <&saradc 1>; + + /* adc mux channel count */ + /* despite there is only left stick, amux-count needs to be 4, */ + /* because amux 0 and 1 are hardcoded as RX and RY in the driver */ + amux-count = <4>; + /* adc mux select(a,b) gpio */ + amux-a-gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_LOW>; + amux-b-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>; + /* adc mux enable gpio */ + amux-en-gpios = <&gpio3 RK_PB5 GPIO_ACTIVE_LOW>; + + /* + Analog Stick data tuning value(precent) + p = positive direction, n = negative direction + report value = (real_adc_data * tuning_value) / 100 + */ + abs_x-p-tuning = <200>; + abs_x-n-tuning = <200>; + + abs_y-p-tuning = <200>; + abs_y-n-tuning = <200>; + + abs_rx-p-tuning = <200>; + abs_rx-n-tuning = <200>; + + abs_ry-p-tuning = <200>; + abs_ry-n-tuning = <200>; + + /* required for RGB10X */ + invert-absx; + invert-absy; + + /* + joypad driver is poll-device driver. + poll-device is does not support wakeup-source. + */ + up { gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>; }; + down { gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_LOW>; }; + left { gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; }; + right { gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_LOW>; }; + + a { gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>; }; + b { gpios = <&gpio1 RK_PA5 GPIO_ACTIVE_LOW>; }; + x { gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_LOW>; }; + y { gpios = <&gpio1 RK_PA6 GPIO_ACTIVE_LOW>; }; + + tl { gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_LOW>; }; + tr { gpios = <&gpio2 RK_PA7 GPIO_ACTIVE_LOW>; }; + tr2 { gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; }; + tl2 { gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; }; + + select{ gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>; }; + start { gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; }; + + thumbl{ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; }; + + /* Plus and Minus face buttons are mapped to mode and thumbr */ + mode { + gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_LOW>; + label = "GPIO MINUS"; + }; + thumbr { + gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; + label = "GPIO PLUS"; + }; +}; + +&internal_display { + compatible = "powkiddy,rk2023-panel", "newvision,nv3051d"; + vdd-supply = <&vcc_lcd>; +}; + +&io_domains { + vccio1-supply = <&vccio_sd>; +}; + +/delete-node/ &pwm3; +/delete-node/ &pwm_led; + +&red_led { + gpios = <&gpio2 RK_PB5 GPIO_ACTIVE_HIGH>; +}; + +&red_led_pin { + rockchip,pins = <2 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; +}; + +&rk817_charger { + monitored-battery = <&battery>; +}; + +&sdio { + cap-sd-highspeed; + card-detect-delay = <200>; + cd-gpios = <&gpio3 RK_PB6 GPIO_ACTIVE_LOW>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&vcc_sd { + regulator-max-microvolt = <3000000>; + regulator-min-microvolt = <1800000>; +}; + +&vccio_sd { + regulator-max-microvolt = <1800000>; +}; + +&pinctrl { + btns { + btn_pins: btn-pins { + rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + btn_pins_vol: btn-pins-vol { + rockchip,pins = <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; diff --git a/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-powkiddy-rgb20s.dts b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-powkiddy-rgb20s.dts new file mode 100644 index 0000000000..93f149e62a --- /dev/null +++ b/projects/ArchR/devices/RK3326/linux/dts/rockchip/rk3326-powkiddy-rgb20s.dts @@ -0,0 +1,375 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Hardkernel Co., Ltd + * Copyright (c) 2020 Theobroma Systems Design und Consulting GmbH + * Copyright (c) 2022 Maya Matuszczyk + */ + +/dts-v1/; +#include "rk3326-odroid-go.dtsi" + +/ { + model = "Powkiddy RGB20S"; + compatible = "powkiddy,rgb20s", "rockchip,rk3326"; + + aliases { + mmc0 = &sdio; + mmc1 = &sdmmc; + }; + + gpio-keys-vol { + compatible = "gpio-keys"; + autorepeat; + pinctrl-0 = <&btn_pins_vol>; + pinctrl-names = "default"; + + button-vol-down { + gpios = <&gpio2 RK_PA1 GPIO_ACTIVE_LOW>; + label = "VOLUMEDOWN"; + linux,code = ; + }; + + button-volume-up { + gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; + label = "VOLUMEUP"; + linux,code = ; + }; + }; + + joypad: joypad { + compatible = "archr-singleadc-joypad"; + + pwms = <&pwm0 0 200000000 0>; + pwm-names = "enable"; + rumble-boost-weak = <0x0000>; + rumble-boost-strong = <0x0000>; + + joypad-name = "r36s_Gamepad"; + joypad-product = <0x1188>; + joypad-revision = <0x0188>; + joypad-vendor = <0x0001>; + + status = "okay"; + + /* gpio pincontrol setup */ + pinctrl-names = "default"; + pinctrl-0 = <&btn_pins>; + pinctrl-1 = <&pwm0_pin>; + + /* Analog mux define */ + io-channel-names = "amux_adc"; + io-channels = <&saradc 1>; + + /* adc mux channel count */ + amux-count = <4>; + /* non-default wiring */ + amux-channel-mapping = <0 1 2 3>; + /* adc mux select(a,b) gpio */ + amux-a-gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_LOW>; + amux-b-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>; + /* adc mux enable gpio */ + amux-en-gpios = <&gpio3 RK_PB5 GPIO_ACTIVE_LOW>; + + /* adc calculate scale */ + button-adc-scale = <2>; + + /* adc deadzone range */ + button-adc-deadzone = <64>; + + /* + specifies fuzz value that is used to filter noise from + the event stream. + */ + button-adc-fuzz = <32>; + button-adc-flat = <32>; + + /* + Analog Stick data tuning value(precent) + p = positive direction, n = negative direction + report value = (real_adc_data * tuning_value) / 100 + */ + abs_x-p-tuning = <400>; + abs_x-n-tuning = <400>; + + abs_y-p-tuning = <400>; + abs_y-n-tuning = <400>; + + abs_rx-p-tuning = <400>; + abs_rx-n-tuning = <400>; + + abs_ry-p-tuning = <400>; + abs_ry-n-tuning = <400>; + + /* poll device interval (ms), adc read interval */ + poll-interval = <10>; + + /* required for RG351MP */ + invert-absx; + invert-absy; + + /* gpio button auto repeat set value : default disable */ + /* + autorepeat; + */ + + /* + joypad driver is poll-device driver. + poll-device is does not support wakeup-source. + */ + sw1 { + gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-UP"; + linux,code = ; // 0x220 + }; + sw2 { + gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-DOWN"; + linux,code = ; // 0x221 + }; + sw3 { + gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-LEFT"; + linux,code = ; // 0x222 + }; + sw4 { + gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-RIGHT"; + linux,code = ; // 0x223 + }; + sw5 { + gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>; + label = "GPIO KEY BTN-A"; + linux,code = ; // 0x131 + }; + sw6 { + gpios = <&gpio1 RK_PA5 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-B"; + linux,code = ; // 0x130 + }; + sw7 { + gpios = <&gpio1 RK_PA6 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-Y"; + linux,code = ; // 0x134 + }; + sw8 { + gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_LOW>; + label = "GPIO BTN-X"; + linux,code = ; // 0x133 + }; + sw11 { + gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; + label = "GPIO BTN_THUMBL"; + linux,code = ; // 0x2c2 + }; + sw12 { + gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; + label = "GPIO BTN_THUMBR"; + linux,code = ; // 0x2c3 + }; + + sw13 { + gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_LOW>; + label = "GPIO BTN_FN"; + linux,code = ; // 0x2c4 + }; + + sw15 { + gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-LEFT"; + linux,code = ; // 0x02 + }; + sw16 { + gpios = <&gpio2 RK_PA7 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-RIGHT"; + linux,code = ; // 0x05 + }; + sw19 { + gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>; + label = "GPIO BTN_SELECT"; + linux,code = ; + }; + sw20 { + gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-RIGHT2"; + linux,code = ; + }; + sw21 { + gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-LEFT2"; + linux,code = ; + }; + sw22 { + gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; + label = "GPIO BTN_START"; + linux,code = ; + }; + }; + + battery: battery { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <3500000>; + charge-term-current-microamp = <350000>; + constant-charge-current-max-microamp = <2000000>; + constant-charge-voltage-max-microvolt = <4200000>; + factory-internal-resistance-micro-ohms = <180000>; + voltage-max-design-microvolt = <4100000>; + voltage-min-design-microvolt = <3500000>; + + ocv-capacity-celsius = <20>; + ocv-capacity-table-0 = <4046950 100>, <4001920 95>, <3967900 90>, <3919950 85>, + <3888450 80>, <3861850 75>, <3831540 70>, <3799130 65>, + <3768190 60>, <3745650 55>, <3726610 50>, <3711630 45>, + <3696720 40>, <3685660 35>, <3674950 30>, <3663050 25>, + <3649470 20>, <3635260 15>, <3616920 10>, <3592440 5>, + <3574170 0>; + }; +}; + +/* conflicts with pwm vibration motor */ +/delete-node/ &vcc_host; + +/* Device only has 1 LED compared to Odroid Go Advance */ +/delete-node/ &gpio_led; + +&internal_display { +// compatible = "anbernic,rg351v-panel", "newvision,nv3051d"; + // compatible = "powkiddy,rk2023-panel", "newvision,nv3051d"; + compatible = "archr,generic-dsi"; + iovcc-supply = <&vcc_lcd>; + vdd-supply = <&vcc_lcd>; + panel_description = + "G size=52,70 delays=2,1,20,120,20 format=rgb888 lanes=4 flags=0xe03", + + "M clock=26400 horizontal=640,119,2,119 vertical=480,13,2,5 default=1", + "M clock=27300 horizontal=640,207,24,207 vertical=480,13,9,5", + "M clock=26400 horizontal=640,207,2,207 vertical=480,13,2,5", + "M clock=27140 horizontal=640,119,45,119 vertical=480,13,90,5", + "M clock=26450 horizontal=640,119,42,119 vertical=480,13,2,5", + "M clock=28520 horizontal=640,119,3,119 vertical=480,13,44,5", + "M clock=31440 horizontal=640,119,39,119 vertical=480,13,74,5", + "M clock=26440 horizontal=640,31,30,31 vertical=480,13,103,5", + "M clock=31970 horizontal=640,31,36,31 vertical=480,13,76,5", + // "M clock=31680 horizontal=640,31,2,31 vertical=480,13,2,5", + "M clock=42240 horizontal=640,31,2,31 vertical=480,13,2,5", + + "I seq=ff30", "I seq=ff52", "I seq=ff01", + "I seq=e300", + "I seq=400a", + "I seq=0340", "I seq=0400", "I seq=0503", + "I seq=2412", "I seq=251e", "I seq=2628", "I seq=2752", + "I seq=2857", "I seq=2901", "I seq=2adf", + "I seq=389c", "I seq=39a7", "I seq=3a53", + "I seq=4400", + "I seq=493c", + "I seq=59fe", "I seq=5c00", + "I seq=9177", "I seq=9277", + "I seq=a055", "I seq=a150", "I seq=a49c", "I seq=a702", + "I seq=a801", "I seq=a901", "I seq=aafc", "I seq=ab28", "I seq=ac06", "I seq=ad06", "I seq=ae06", "I seq=af03", + "I seq=b008", "I seq=b126", "I seq=b228", "I seq=b328", "I seq=b433", "I seq=b508", "I seq=b626", "I seq=b708", + "I seq=b826", + "I seq=ff30", "I seq=ff52", "I seq=ff02", + "I seq=b00b", "I seq=b116", "I seq=b217", "I seq=b32c", "I seq=b432", "I seq=b53b", "I seq=b629", "I seq=b740", + "I seq=b80d", "I seq=b905", "I seq=ba12", "I seq=bb10", "I seq=bc12", "I seq=bd15", "I seq=be19", "I seq=bf0e", + "I seq=c016", "I seq=c10a", + "I seq=d00c", "I seq=d117", "I seq=d214", "I seq=d32e", "I seq=d432", "I seq=d53c", "I seq=d622", "I seq=d73d", + "I seq=d80d", "I seq=d907", "I seq=da13", "I seq=db13", "I seq=dc11", "I seq=dd15", "I seq=de19", "I seq=df10", + "I seq=e017", "I seq=e10a", + "I seq=ff30", "I seq=ff52", "I seq=ff03", + "I seq=002a", "I seq=012a", "I seq=022a", "I seq=032a", "I seq=0461", "I seq=0580", "I seq=06c7", "I seq=0701", + "I seq=0882", "I seq=0983", + "I seq=302a", "I seq=312a", "I seq=322a", "I seq=332a", "I seq=3461", "I seq=35c5", "I seq=3680", "I seq=3723", + "I seq=4082", "I seq=4183", "I seq=4280", "I seq=4381", "I seq=4411", "I seq=45e6", "I seq=46e5", "I seq=4711", + "I seq=48e8", "I seq=49e7", + "I seq=5002", "I seq=5101", "I seq=5204", "I seq=5303", "I seq=5411", "I seq=55ea", "I seq=56e9", "I seq=5711", + "I seq=58ec", "I seq=59eb", + "I seq=7e02", "I seq=7f80", + "I seq=e05a", + "I seq=b100", "I seq=b40e", "I seq=b50f", "I seq=b604", "I seq=b707", + "I seq=b806", "I seq=b905", "I seq=ba0f", + "I seq=c700", + "I seq=ca0e", "I seq=cb0f", "I seq=cc04", "I seq=cd07", "I seq=ce06", "I seq=cf05", + "I seq=d00f", + "I seq=810f", "I seq=840e", "I seq=850f", "I seq=8607", "I seq=8704", + "I seq=8805", "I seq=8906", "I seq=8a00", + "I seq=970f", + "I seq=9a0e", "I seq=9b0f", "I seq=9c07", "I seq=9d04", "I seq=9e05", "I seq=9f06", + "I seq=a000", + "I seq=ff30", "I seq=ff52", "I seq=ff02", + "I seq=0101", "I seq=02da", "I seq=03ba", "I seq=04a8", "I seq=059a", "I seq=0670", "I seq=07ff", + "I seq=0891", "I seq=0990", "I seq=0aff", "I seq=0b8f", "I seq=0c60", "I seq=0d58", "I seq=0e48", "I seq=0f38", + "I seq=102b", + "I seq=ff30", "I seq=ff52", "I seq=ff00", + "I seq=3602", + "I seq=3a70", + "I seq=11 wait=200", + "I seq=29 wait=10"; +}; + +&io_domains { + vccio1-supply = <&vccio_sd>; +}; + +/delete-node/ &pwm_led; + +&pwm0 { + status = "okay"; +}; + +/delete-node/ &pwm3; + +&rk817_charger { + /* This device does not have a current sense resistor */ + rockchip,resistor-sense-micro-ohms = <0>; + monitored-battery = <&battery>; +}; + +&sdio { + cap-sd-highspeed; + card-detect-delay = <200>; + cd-gpios = <&gpio3 RK_PB6 GPIO_ACTIVE_LOW>; /*[> CD GPIO <]*/ + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&vcc_sd { + regulator-max-microvolt = <3000000>; + regulator-min-microvolt = <1800000>; +}; + +&vccio_sd { + regulator-max-microvolt = <1800000>; +}; + +&pinctrl { + btns { + btn_pins_vol: btn-pins-vol { + rockchip,pins = <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + btn_pins: btn-pins { + rockchip,pins = <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; diff --git a/projects/ArchR/devices/RK3326/linux/linux.aarch64.conf b/projects/ArchR/devices/RK3326/linux/linux.aarch64.conf new file mode 100644 index 0000000000..2f6709d616 --- /dev/null +++ b/projects/ArchR/devices/RK3326/linux/linux.aarch64.conf @@ -0,0 +1,6918 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/arm64 6.12.61 Kernel Configuration +# +CONFIG_CC_VERSION_TEXT="aarch64-archr-linux-gnu-gcc-14.2.0 (GCC) 14.2.0" +CONFIG_CC_IS_GCC=y +CONFIG_GCC_VERSION=140200 +CONFIG_CLANG_VERSION=0 +CONFIG_AS_IS_GNU=y +CONFIG_AS_VERSION=24400 +CONFIG_LD_IS_BFD=y +CONFIG_LD_VERSION=24400 +CONFIG_LLD_VERSION=0 +CONFIG_RUSTC_VERSION=109301 +CONFIG_RUSTC_LLVM_VERSION=210108 +CONFIG_CC_CAN_LINK=y +CONFIG_CC_CAN_LINK_STATIC=y +CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y +CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT=y +CONFIG_TOOLS_SUPPORT_RELR=y +CONFIG_CC_HAS_ASM_INLINE=y +CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y +CONFIG_LD_CAN_USE_KEEP_IN_OVERLAY=y +CONFIG_RUSTC_HAS_UNNECESSARY_TRANSMUTES=y +CONFIG_PAHOLE_VERSION=0 +CONFIG_IRQ_WORK=y +CONFIG_BUILDTIME_TABLE_SORT=y +CONFIG_THREAD_INFO_IN_TASK=y + +# +# General setup +# +CONFIG_INIT_ENV_ARG_LIMIT=32 +# CONFIG_COMPILE_TEST is not set +# CONFIG_WERROR is not set +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_BUILD_SALT="" +CONFIG_DEFAULT_INIT="" +CONFIG_DEFAULT_HOSTNAME="@DEVICENAME@" +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +# CONFIG_WATCH_QUEUE is not set +CONFIG_CROSS_MEMORY_ATTACH=y +# CONFIG_USELIB is not set +# CONFIG_AUDIT is not set +CONFIG_HAVE_ARCH_AUDITSYSCALL=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_GENERIC_IRQ_MIGRATION=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_CHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_GENERIC_IRQ_IPI=y +CONFIG_GENERIC_MSI_IRQ=y +CONFIG_IRQ_MSI_IOMMU=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_SPARSE_IRQ=y +# CONFIG_GENERIC_IRQ_DEBUGFS is not set +# end of IRQ subsystem + +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_ARCH_HAS_TICK_BROADCAST=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_HAVE_POSIX_CPU_TIMERS_TASK_WORK=y +CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y +CONFIG_CONTEXT_TRACKING=y +CONFIG_CONTEXT_TRACKING_IDLE=y + +# +# Timers subsystem +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ_COMMON=y +# CONFIG_HZ_PERIODIC is not set +CONFIG_NO_HZ_IDLE=y +# CONFIG_NO_HZ_FULL is not set +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +# end of Timers subsystem + +CONFIG_BPF=y +CONFIG_HAVE_EBPF_JIT=y +CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y + +# +# BPF subsystem +# +CONFIG_BPF_SYSCALL=y +CONFIG_BPF_JIT=y +# CONFIG_BPF_JIT_ALWAYS_ON is not set +CONFIG_BPF_JIT_DEFAULT_ON=y +CONFIG_BPF_UNPRIV_DEFAULT_OFF=y +# CONFIG_BPF_PRELOAD is not set +# end of BPF subsystem + +CONFIG_PREEMPT_VOLUNTARY_BUILD=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PREEMPT is not set +# CONFIG_PREEMPT_RT is not set +# CONFIG_PREEMPT_DYNAMIC is not set + +# +# CPU/Task time and stats accounting +# +CONFIG_TICK_CPU_ACCOUNTING=y +# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set +CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_SCHED_AVG_IRQ=y +CONFIG_SCHED_HW_PRESSURE=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_PSI=y +# CONFIG_PSI_DEFAULT_DISABLED is not set +# end of CPU/Task time and stats accounting + +CONFIG_CPU_ISOLATION=y + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_RCU_EXPERT is not set +CONFIG_TREE_SRCU=y +CONFIG_TASKS_RCU_GENERIC=y +CONFIG_NEED_TASKS_RCU=y +CONFIG_TASKS_TRACE_RCU=y +CONFIG_RCU_STALL_COMMON=y +CONFIG_RCU_NEED_SEGCBLIST=y +# end of RCU Subsystem + +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +# CONFIG_IKHEADERS is not set +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 +# CONFIG_PRINTK_INDEX is not set +CONFIG_GENERIC_SCHED_CLOCK=y + +# +# Scheduler features +# +# CONFIG_UCLAMP_TASK is not set +# end of Scheduler features + +CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y +CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH=y +CONFIG_CC_HAS_INT128=y +CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" +CONFIG_GCC10_NO_ARRAY_BOUNDS=y +CONFIG_CC_NO_ARRAY_BOUNDS=y +CONFIG_GCC_NO_STRINGOP_OVERFLOW=y +CONFIG_CC_NO_STRINGOP_OVERFLOW=y +CONFIG_ARCH_SUPPORTS_INT128=y +CONFIG_SLAB_OBJ_EXT=y +CONFIG_CGROUPS=y +CONFIG_PAGE_COUNTER=y +# CONFIG_CGROUP_FAVOR_DYNMODS is not set +CONFIG_MEMCG=y +# CONFIG_MEMCG_V1 is not set +CONFIG_BLK_CGROUP=y +CONFIG_CGROUP_WRITEBACK=y +CONFIG_CGROUP_SCHED=y +CONFIG_GROUP_SCHED_WEIGHT=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_CFS_BANDWIDTH is not set +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_SCHED_MM_CID=y +CONFIG_CGROUP_PIDS=y +# CONFIG_CGROUP_RDMA is not set +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_HUGETLB=y +CONFIG_CPUSETS=y +# CONFIG_CPUSETS_V1 is not set +CONFIG_PROC_PID_CPUSET=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_PERF=y +CONFIG_CGROUP_BPF=y +# CONFIG_CGROUP_MISC is not set +# CONFIG_CGROUP_DEBUG is not set +CONFIG_SOCK_CGROUP_DATA=y +CONFIG_NAMESPACES=y +CONFIG_UTS_NS=y +CONFIG_TIME_NS=y +CONFIG_IPC_NS=y +CONFIG_USER_NS=y +CONFIG_PID_NS=y +CONFIG_NET_NS=y +# CONFIG_CHECKPOINT_RESTORE is not set +CONFIG_SCHED_AUTOGROUP=y +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="@INITRAMFS_SOURCE@" +CONFIG_INITRAMFS_ROOT_UID=0 +CONFIG_INITRAMFS_ROOT_GID=0 +# CONFIG_RD_GZIP is not set +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_XZ is not set +CONFIG_RD_LZO=y +# CONFIG_RD_LZ4 is not set +# CONFIG_RD_ZSTD is not set +CONFIG_INITRAMFS_COMPRESSION_LZO=y +# CONFIG_INITRAMFS_COMPRESSION_NONE is not set +# CONFIG_BOOT_CONFIG is not set +CONFIG_INITRAMFS_PRESERVE_MTIME=y +CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_LD_ORPHAN_WARN=y +CONFIG_LD_ORPHAN_WARN_LEVEL="warn" +CONFIG_SYSCTL=y +CONFIG_HAVE_UID16=y +CONFIG_SYSCTL_EXCEPTION_TRACE=y +CONFIG_EXPERT=y +CONFIG_UID16=y +CONFIG_MULTIUSER=y +# CONFIG_SGETMASK_SYSCALL is not set +CONFIG_SYSFS_SYSCALL=y +CONFIG_FHANDLE=y +CONFIG_POSIX_TIMERS=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +# CONFIG_BASE_SMALL is not set +CONFIG_FUTEX=y +CONFIG_FUTEX_PI=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_IO_URING=y +CONFIG_ADVISE_SYSCALLS=y +CONFIG_MEMBARRIER=y +CONFIG_KCMP=y +CONFIG_RSEQ=y +# CONFIG_DEBUG_RSEQ is not set +CONFIG_CACHESTAT_SYSCALL=y +# CONFIG_PC104 is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_SELFTEST is not set +# CONFIG_KALLSYMS_ALL is not set +CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y +CONFIG_HAVE_PERF_EVENTS=y + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +# end of Kernel Performance Events And Counters + +CONFIG_SYSTEM_DATA_VERIFICATION=y +CONFIG_PROFILING=y + +# +# Kexec and crash features +# +# CONFIG_KEXEC is not set +# CONFIG_KEXEC_FILE is not set +# end of Kexec and crash features +# end of General setup + +CONFIG_ARM64=y +CONFIG_RUSTC_SUPPORTS_ARM64=y +CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS=y +CONFIG_64BIT=y +CONFIG_MMU=y +CONFIG_ARM64_CONT_PTE_SHIFT=4 +CONFIG_ARM64_CONT_PMD_SHIFT=4 +CONFIG_ARCH_MMAP_RND_BITS_MIN=18 +CONFIG_ARCH_MMAP_RND_BITS_MAX=33 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16 +CONFIG_NO_IOPORT_MAP=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CSUM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_SMP=y +CONFIG_KERNEL_MODE_NEON=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_PGTABLE_LEVELS=4 +CONFIG_ARCH_SUPPORTS_UPROBES=y +CONFIG_ARCH_PROC_KCORE_TEXT=y +CONFIG_BUILTIN_RETURN_ADDRESS_STRIPS_PAC=y + +# +# Platform selection +# +# CONFIG_ARCH_ACTIONS is not set +# CONFIG_ARCH_AIROHA is not set +# CONFIG_ARCH_SUNXI is not set +# CONFIG_ARCH_ALPINE is not set +# CONFIG_ARCH_APPLE is not set +# CONFIG_ARCH_BCM is not set +# CONFIG_ARCH_BERLIN is not set +# CONFIG_ARCH_BITMAIN is not set +# CONFIG_ARCH_EXYNOS is not set +# CONFIG_ARCH_SPARX5 is not set +# CONFIG_ARCH_K3 is not set +# CONFIG_ARCH_LG1K is not set +# CONFIG_ARCH_HISI is not set +# CONFIG_ARCH_KEEMBAY is not set +# CONFIG_ARCH_MEDIATEK is not set +# CONFIG_ARCH_MESON is not set +# CONFIG_ARCH_MVEBU is not set +# CONFIG_ARCH_NXP is not set +# CONFIG_ARCH_MA35 is not set +# CONFIG_ARCH_NPCM is not set +# CONFIG_ARCH_PENSANDO is not set +# CONFIG_ARCH_QCOM is not set +# CONFIG_ARCH_REALTEK is not set +# CONFIG_ARCH_RENESAS is not set +CONFIG_ARCH_ROCKCHIP=y +# CONFIG_ARCH_SEATTLE is not set +# CONFIG_ARCH_INTEL_SOCFPGA is not set +# CONFIG_ARCH_STM32 is not set +# CONFIG_ARCH_SYNQUACER is not set +# CONFIG_ARCH_TEGRA is not set +# CONFIG_ARCH_SPRD is not set +# CONFIG_ARCH_THUNDER is not set +# CONFIG_ARCH_THUNDER2 is not set +# CONFIG_ARCH_UNIPHIER is not set +# CONFIG_ARCH_VEXPRESS is not set +# CONFIG_ARCH_VISCONTI is not set +# CONFIG_ARCH_XGENE is not set +# CONFIG_ARCH_ZYNQMP is not set +# end of Platform selection + +# +# Kernel Features +# + +# +# ARM errata workarounds via the alternatives framework +# +# CONFIG_AMPERE_ERRATUM_AC03_CPU_38 is not set +# CONFIG_ARM64_ERRATUM_826319 is not set +# CONFIG_ARM64_ERRATUM_827319 is not set +# CONFIG_ARM64_ERRATUM_824069 is not set +# CONFIG_ARM64_ERRATUM_819472 is not set +# CONFIG_ARM64_ERRATUM_832075 is not set +# CONFIG_ARM64_ERRATUM_1742098 is not set +# CONFIG_ARM64_ERRATUM_845719 is not set +# CONFIG_ARM64_ERRATUM_843419 is not set +CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y +# CONFIG_ARM64_ERRATUM_1024718 is not set +# CONFIG_ARM64_ERRATUM_1418040 is not set +# CONFIG_ARM64_ERRATUM_1165522 is not set +# CONFIG_ARM64_ERRATUM_1319367 is not set +# CONFIG_ARM64_ERRATUM_1530923 is not set +# CONFIG_ARM64_ERRATUM_2441007 is not set +# CONFIG_ARM64_ERRATUM_1286807 is not set +# CONFIG_ARM64_ERRATUM_1463225 is not set +# CONFIG_ARM64_ERRATUM_1542419 is not set +# CONFIG_ARM64_ERRATUM_1508412 is not set +# CONFIG_ARM64_ERRATUM_2051678 is not set +# CONFIG_ARM64_ERRATUM_2077057 is not set +# CONFIG_ARM64_ERRATUM_2658417 is not set +# CONFIG_ARM64_ERRATUM_2054223 is not set +# CONFIG_ARM64_ERRATUM_2067961 is not set +# CONFIG_ARM64_ERRATUM_2441009 is not set +# CONFIG_ARM64_ERRATUM_2645198 is not set +CONFIG_ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD=y +# CONFIG_ARM64_ERRATUM_2966298 is not set +CONFIG_ARM64_ERRATUM_3117295=y +CONFIG_ARM64_ERRATUM_3194386=y +# CONFIG_CAVIUM_ERRATUM_22375 is not set +# CONFIG_CAVIUM_ERRATUM_23154 is not set +# CONFIG_CAVIUM_ERRATUM_27456 is not set +# CONFIG_CAVIUM_ERRATUM_30115 is not set +# CONFIG_CAVIUM_TX2_ERRATUM_219 is not set +# CONFIG_FUJITSU_ERRATUM_010001 is not set +# CONFIG_HISILICON_ERRATUM_161600802 is not set +CONFIG_HISILICON_ERRATUM_162100801=y +# CONFIG_QCOM_FALKOR_ERRATUM_1003 is not set +# CONFIG_QCOM_FALKOR_ERRATUM_1009 is not set +# CONFIG_QCOM_QDF2400_ERRATUM_0065 is not set +# CONFIG_QCOM_FALKOR_ERRATUM_E1041 is not set +# CONFIG_NVIDIA_CARMEL_CNP_ERRATUM is not set +# CONFIG_ROCKCHIP_ERRATUM_3588001 is not set +# CONFIG_SOCIONEXT_SYNQUACER_PREITS is not set +# end of ARM errata workarounds via the alternatives framework + +CONFIG_ARM64_4K_PAGES=y +# CONFIG_ARM64_16K_PAGES is not set +# CONFIG_ARM64_64K_PAGES is not set +# CONFIG_ARM64_VA_BITS_39 is not set +CONFIG_ARM64_VA_BITS_48=y +# CONFIG_ARM64_VA_BITS_52 is not set +CONFIG_ARM64_VA_BITS=48 +CONFIG_ARM64_PA_BITS_48=y +CONFIG_ARM64_PA_BITS=48 +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SCHED_MC=y +# CONFIG_SCHED_CLUSTER is not set +# CONFIG_SCHED_SMT is not set +CONFIG_NR_CPUS=4 +CONFIG_HOTPLUG_CPU=y +# CONFIG_NUMA is not set +# CONFIG_HZ_100 is not set +# CONFIG_HZ_250 is not set +CONFIG_HZ_300=y +# CONFIG_HZ_1000 is not set +CONFIG_HZ=300 +CONFIG_SCHED_HRTICK=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_HW_PERF_EVENTS=y +CONFIG_CC_HAVE_SHADOW_CALL_STACK=y +# CONFIG_PARAVIRT is not set +# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set +CONFIG_ARCH_SUPPORTS_KEXEC=y +CONFIG_ARCH_SUPPORTS_KEXEC_FILE=y +CONFIG_ARCH_SUPPORTS_KEXEC_SIG=y +CONFIG_ARCH_SUPPORTS_KEXEC_IMAGE_VERIFY_SIG=y +CONFIG_ARCH_DEFAULT_KEXEC_IMAGE_VERIFY_SIG=y +CONFIG_ARCH_SUPPORTS_CRASH_DUMP=y +CONFIG_ARCH_DEFAULT_CRASH_DUMP=y +CONFIG_TRANS_TABLE=y +# CONFIG_XEN is not set +CONFIG_ARCH_FORCE_MAX_ORDER=10 +CONFIG_UNMAP_KERNEL_AT_EL0=y +# CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY is not set +CONFIG_RODATA_FULL_DEFAULT_ENABLED=y +# CONFIG_ARM64_SW_TTBR0_PAN is not set +CONFIG_ARM64_TAGGED_ADDR_ABI=y +CONFIG_COMPAT=y +CONFIG_KUSER_HELPERS=y +# CONFIG_COMPAT_ALIGNMENT_FIXUPS is not set +# CONFIG_ARMV8_DEPRECATED is not set + +# +# ARMv8.1 architectural features +# +CONFIG_ARM64_HW_AFDBM=y +CONFIG_ARM64_PAN=y +CONFIG_AS_HAS_LSE_ATOMICS=y +CONFIG_ARM64_LSE_ATOMICS=y +CONFIG_ARM64_USE_LSE_ATOMICS=y +# end of ARMv8.1 architectural features + +# +# ARMv8.2 architectural features +# +CONFIG_AS_HAS_ARMV8_2=y +CONFIG_AS_HAS_SHA3=y +# CONFIG_ARM64_PMEM is not set +# CONFIG_ARM64_RAS_EXTN is not set +# CONFIG_ARM64_CNP is not set +# end of ARMv8.2 architectural features + +# +# ARMv8.3 architectural features +# +# CONFIG_ARM64_PTR_AUTH is not set +CONFIG_CC_HAS_BRANCH_PROT_PAC_RET=y +CONFIG_CC_HAS_SIGN_RETURN_ADDRESS=y +CONFIG_AS_HAS_ARMV8_3=y +CONFIG_AS_HAS_CFI_NEGATE_RA_STATE=y +CONFIG_AS_HAS_LDAPR=y +# end of ARMv8.3 architectural features + +# +# ARMv8.4 architectural features +# +# CONFIG_ARM64_AMU_EXTN is not set +CONFIG_AS_HAS_ARMV8_4=y +# CONFIG_ARM64_TLB_RANGE is not set +# end of ARMv8.4 architectural features + +# +# ARMv8.5 architectural features +# +CONFIG_AS_HAS_ARMV8_5=y +# CONFIG_ARM64_BTI is not set +CONFIG_CC_HAS_BRANCH_PROT_PAC_RET_BTI=y +# CONFIG_ARM64_E0PD is not set +CONFIG_ARM64_AS_HAS_MTE=y +# CONFIG_ARM64_MTE is not set +# end of ARMv8.5 architectural features + +# +# ARMv8.7 architectural features +# +# CONFIG_ARM64_EPAN is not set +# end of ARMv8.7 architectural features + +# +# ARMv8.9 architectural features +# +CONFIG_ARM64_POE=y +CONFIG_ARCH_PKEY_BITS=3 +# end of ARMv8.9 architectural features + +CONFIG_ARM64_SVE=y +# CONFIG_ARM64_PSEUDO_NMI is not set +CONFIG_RELOCATABLE=y +# CONFIG_RANDOMIZE_BASE is not set +CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y +CONFIG_ARM64_CONTPTE=y +# end of Kernel Features + +# +# Boot options +# +CONFIG_CMDLINE="" +# CONFIG_EFI is not set +# CONFIG_COMPRESSED_INSTALL is not set +# end of Boot options + +# +# Power management options +# +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_SUSPEND_SKIP_SYNC is not set +CONFIG_HIBERNATE_CALLBACKS=y +CONFIG_HIBERNATION=y +# CONFIG_HIBERNATION_SNAPSHOT_DEV is not set +CONFIG_HIBERNATION_COMP_LZO=y +CONFIG_HIBERNATION_DEF_COMP="lzo" +CONFIG_PM_STD_PARTITION="" +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +# CONFIG_PM_AUTOSLEEP is not set +# CONFIG_PM_USERSPACE_AUTOSLEEP is not set +# CONFIG_PM_WAKELOCKS is not set +CONFIG_PM=y +CONFIG_PM_DEBUG=y +CONFIG_PM_ADVANCED_DEBUG=y +# CONFIG_PM_TEST_SUSPEND is not set +CONFIG_PM_SLEEP_DEBUG=y +# CONFIG_DPM_WATCHDOG is not set +CONFIG_PM_CLK=y +CONFIG_PM_GENERIC_DOMAINS=y +CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y +CONFIG_PM_GENERIC_DOMAINS_SLEEP=y +CONFIG_PM_GENERIC_DOMAINS_OF=y +CONFIG_CPU_PM=y +CONFIG_ENERGY_MODEL=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_HIBERNATION_HEADER=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +# end of Power management options + +# +# CPU Power Management +# + +# +# CPU Idle +# +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y +# CONFIG_CPU_IDLE_GOV_TEO is not set +CONFIG_DT_IDLE_STATES=y +CONFIG_DT_IDLE_GENPD=y + +# +# ARM CPU Idle Drivers +# +CONFIG_ARM_PSCI_CPUIDLE=y +CONFIG_ARM_PSCI_CPUIDLE_DOMAIN=y +# end of ARM CPU Idle Drivers +# end of CPU Idle + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_GOV_ATTR_SET=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y + +# +# CPU frequency scaling drivers +# +CONFIG_CPUFREQ_DT=y +CONFIG_CPUFREQ_DT_PLATDEV=y +CONFIG_ARM_SCPI_CPUFREQ=y +# CONFIG_ARM_SCMI_CPUFREQ is not set +# end of CPU Frequency scaling +# end of CPU Power Management + +# CONFIG_VIRTUALIZATION is not set +CONFIG_CPU_MITIGATIONS=y + +# +# General architecture-dependent options +# +CONFIG_HOTPLUG_CORE_SYNC=y +CONFIG_HOTPLUG_CORE_SYNC_DEAD=y +# CONFIG_KPROBES is not set +CONFIG_JUMP_LABEL=y +# CONFIG_STATIC_KEYS_SELFTEST is not set +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_HAVE_IOREMAP_PROT=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y +CONFIG_HAVE_FUNCTION_ERROR_INJECTION=y +CONFIG_HAVE_NMI=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_ARCH_HAS_FORTIFY_SOURCE=y +CONFIG_ARCH_HAS_KEEPINITRD=y +CONFIG_ARCH_HAS_SET_MEMORY=y +CONFIG_ARCH_HAS_SET_DIRECT_MAP=y +CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y +CONFIG_ARCH_WANTS_NO_INSTR=y +CONFIG_HAVE_ASM_MODVERSIONS=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_RSEQ=y +CONFIG_HAVE_RUST=y +CONFIG_HAVE_FUNCTION_ARG_ACCESS_API=y +CONFIG_HAVE_HW_BREAKPOINT=y +CONFIG_HAVE_PERF_REGS=y +CONFIG_HAVE_PERF_USER_STACK_DUMP=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE=y +CONFIG_MMU_GATHER_TABLE_FREE=y +CONFIG_MMU_GATHER_RCU_TABLE_FREE=y +CONFIG_MMU_LAZY_TLB_REFCOUNT=y +CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y +CONFIG_ARCH_HAS_NMI_SAFE_THIS_CPU_OPS=y +CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y +CONFIG_HAVE_CMPXCHG_LOCAL=y +CONFIG_HAVE_CMPXCHG_DOUBLE=y +CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y +CONFIG_HAVE_ARCH_SECCOMP=y +CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_SECCOMP=y +CONFIG_SECCOMP_FILTER=y +# CONFIG_SECCOMP_CACHE_DEBUG is not set +CONFIG_HAVE_ARCH_STACKLEAK=y +CONFIG_HAVE_STACKPROTECTOR=y +# CONFIG_STACKPROTECTOR is not set +CONFIG_ARCH_SUPPORTS_SHADOW_CALL_STACK=y +# CONFIG_SHADOW_CALL_STACK is not set +CONFIG_ARCH_SUPPORTS_LTO_CLANG=y +CONFIG_ARCH_SUPPORTS_LTO_CLANG_THIN=y +CONFIG_LTO_NONE=y +CONFIG_ARCH_SUPPORTS_CFI_CLANG=y +CONFIG_HAVE_CONTEXT_TRACKING_USER=y +CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y +CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_MOVE_PUD=y +CONFIG_HAVE_MOVE_PMD=y +CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y +CONFIG_HAVE_ARCH_HUGE_VMAP=y +CONFIG_HAVE_ARCH_HUGE_VMALLOC=y +CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y +CONFIG_ARCH_WANT_PMD_MKWRITE=y +CONFIG_HAVE_MOD_ARCH_SPECIFIC=y +CONFIG_MODULES_USE_ELF_RELA=y +CONFIG_ARCH_WANTS_EXECMEM_LATE=y +CONFIG_HAVE_SOFTIRQ_ON_OWN_STACK=y +CONFIG_SOFTIRQ_ON_OWN_STACK=y +CONFIG_ARCH_HAS_ELF_RANDOMIZE=y +CONFIG_HAVE_ARCH_MMAP_RND_BITS=y +CONFIG_ARCH_MMAP_RND_BITS=18 +CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS=y +CONFIG_ARCH_MMAP_RND_COMPAT_BITS=11 +CONFIG_HAVE_PAGE_SIZE_4KB=y +CONFIG_PAGE_SIZE_4KB=y +CONFIG_PAGE_SIZE_LESS_THAN_64KB=y +CONFIG_PAGE_SIZE_LESS_THAN_256KB=y +CONFIG_PAGE_SHIFT=12 +CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_COMPAT_OLD_SIGACTION=y +CONFIG_COMPAT_32BIT_TIME=y +CONFIG_ARCH_SUPPORTS_RT=y +CONFIG_HAVE_ARCH_VMAP_STACK=y +CONFIG_VMAP_STACK=y +CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET=y +CONFIG_RANDOMIZE_KSTACK_OFFSET=y +# CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT is not set +CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y +CONFIG_STRICT_KERNEL_RWX=y +CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y +CONFIG_STRICT_MODULE_RWX=y +CONFIG_HAVE_ARCH_COMPILER_H=y +CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y +# CONFIG_LOCK_EVENT_COUNTS is not set +CONFIG_ARCH_HAS_RELR=y +CONFIG_RELR=y +CONFIG_ARCH_HAS_MEM_ENCRYPT=y +CONFIG_HAVE_PREEMPT_DYNAMIC=y +CONFIG_HAVE_PREEMPT_DYNAMIC_KEY=y +CONFIG_ARCH_WANT_LD_ORPHAN_WARN=y +CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y +CONFIG_ARCH_SUPPORTS_PAGE_TABLE_CHECK=y +CONFIG_ARCH_HAVE_TRACE_MMIO_ACCESS=y +CONFIG_ARCH_HAS_HW_PTE_YOUNG=y +CONFIG_ARCH_HAS_KERNEL_FPU_SUPPORT=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y +# end of GCOV-based kernel profiling + +CONFIG_HAVE_GCC_PLUGINS=y +# CONFIG_GCC_PLUGINS is not set +CONFIG_FUNCTION_ALIGNMENT_4B=y +CONFIG_FUNCTION_ALIGNMENT=4 +CONFIG_CC_HAS_MIN_FUNCTION_ALIGNMENT=y +CONFIG_CC_HAS_SANE_FUNCTION_ALIGNMENT=y +# end of General architecture-dependent options + +CONFIG_RT_MUTEXES=y +CONFIG_MODULES=y +# CONFIG_MODULE_DEBUG is not set +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODULE_UNLOAD_TAINT_TRACKING is not set +CONFIG_MODVERSIONS=y +CONFIG_ASM_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_MODULE_SIG is not set +# CONFIG_MODULE_COMPRESS is not set +# CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS is not set +CONFIG_MODPROBE_PATH="/sbin/modprobe" +# CONFIG_TRIM_UNUSED_KSYMS is not set +CONFIG_MODULES_TREE_LOOKUP=y +CONFIG_BLOCK=y +CONFIG_BLOCK_LEGACY_AUTOLOAD=y +CONFIG_BLK_CGROUP_PUNT_BIO=y +CONFIG_BLK_DEV_BSG_COMMON=y +# CONFIG_BLK_DEV_BSGLIB is not set +# CONFIG_BLK_DEV_INTEGRITY is not set +CONFIG_BLK_DEV_WRITE_MOUNTED=y +# CONFIG_BLK_DEV_ZONED is not set +# CONFIG_BLK_DEV_THROTTLING is not set +# CONFIG_BLK_WBT is not set +# CONFIG_BLK_CGROUP_IOLATENCY is not set +# CONFIG_BLK_CGROUP_IOCOST is not set +# CONFIG_BLK_CGROUP_IOPRIO is not set +CONFIG_BLK_DEBUG_FS=y +# CONFIG_BLK_SED_OPAL is not set +# CONFIG_BLK_INLINE_ENCRYPTION is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_AIX_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +CONFIG_EFI_PARTITION=y +# CONFIG_SYSV68_PARTITION is not set +# CONFIG_CMDLINE_PARTITION is not set +# end of Partition Types + +CONFIG_BLK_PM=y + +# +# IO Schedulers +# +CONFIG_MQ_IOSCHED_DEADLINE=y +CONFIG_MQ_IOSCHED_KYBER=y +# CONFIG_IOSCHED_BFQ is not set +# end of IO Schedulers + +CONFIG_PADATA=y +CONFIG_ASN1=y +CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y +CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH=y +CONFIG_ARCH_INLINE_SPIN_LOCK=y +CONFIG_ARCH_INLINE_SPIN_LOCK_BH=y +CONFIG_ARCH_INLINE_SPIN_LOCK_IRQ=y +CONFIG_ARCH_INLINE_SPIN_LOCK_IRQSAVE=y +CONFIG_ARCH_INLINE_SPIN_UNLOCK=y +CONFIG_ARCH_INLINE_SPIN_UNLOCK_BH=y +CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQ=y +CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE=y +CONFIG_ARCH_INLINE_READ_LOCK=y +CONFIG_ARCH_INLINE_READ_LOCK_BH=y +CONFIG_ARCH_INLINE_READ_LOCK_IRQ=y +CONFIG_ARCH_INLINE_READ_LOCK_IRQSAVE=y +CONFIG_ARCH_INLINE_READ_UNLOCK=y +CONFIG_ARCH_INLINE_READ_UNLOCK_BH=y +CONFIG_ARCH_INLINE_READ_UNLOCK_IRQ=y +CONFIG_ARCH_INLINE_READ_UNLOCK_IRQRESTORE=y +CONFIG_ARCH_INLINE_WRITE_LOCK=y +CONFIG_ARCH_INLINE_WRITE_LOCK_BH=y +CONFIG_ARCH_INLINE_WRITE_LOCK_IRQ=y +CONFIG_ARCH_INLINE_WRITE_LOCK_IRQSAVE=y +CONFIG_ARCH_INLINE_WRITE_UNLOCK=y +CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH=y +CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ=y +CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE=y +CONFIG_INLINE_SPIN_TRYLOCK=y +CONFIG_INLINE_SPIN_TRYLOCK_BH=y +CONFIG_INLINE_SPIN_LOCK=y +CONFIG_INLINE_SPIN_LOCK_BH=y +CONFIG_INLINE_SPIN_LOCK_IRQ=y +CONFIG_INLINE_SPIN_LOCK_IRQSAVE=y +CONFIG_INLINE_SPIN_UNLOCK_BH=y +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE=y +CONFIG_INLINE_READ_LOCK=y +CONFIG_INLINE_READ_LOCK_BH=y +CONFIG_INLINE_READ_LOCK_IRQ=y +CONFIG_INLINE_READ_LOCK_IRQSAVE=y +CONFIG_INLINE_READ_UNLOCK=y +CONFIG_INLINE_READ_UNLOCK_BH=y +CONFIG_INLINE_READ_UNLOCK_IRQ=y +CONFIG_INLINE_READ_UNLOCK_IRQRESTORE=y +CONFIG_INLINE_WRITE_LOCK=y +CONFIG_INLINE_WRITE_LOCK_BH=y +CONFIG_INLINE_WRITE_LOCK_IRQ=y +CONFIG_INLINE_WRITE_LOCK_IRQSAVE=y +CONFIG_INLINE_WRITE_UNLOCK=y +CONFIG_INLINE_WRITE_UNLOCK_BH=y +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE=y +CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_RWSEM_SPIN_ON_OWNER=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y +CONFIG_QUEUED_SPINLOCKS=y +CONFIG_ARCH_USE_QUEUED_RWLOCKS=y +CONFIG_QUEUED_RWLOCKS=y +CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE=y +CONFIG_ARCH_HAS_SYSCALL_WRAPPER=y +CONFIG_FREEZER=y + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +CONFIG_COMPAT_BINFMT_ELF=y +CONFIG_ARCH_BINFMT_ELF_STATE=y +CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y +CONFIG_ARCH_HAVE_ELF_PROT=y +CONFIG_ARCH_USE_GNU_PROPERTY=y +CONFIG_ELFCORE=y +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y +CONFIG_BINFMT_SCRIPT=y +CONFIG_BINFMT_MISC=y +CONFIG_COREDUMP=y +# end of Executable file formats + +# +# Memory Management options +# +CONFIG_SWAP=y +# CONFIG_ZSWAP is not set +CONFIG_ZSMALLOC=m +# CONFIG_ZSMALLOC_STAT is not set +CONFIG_ZSMALLOC_CHAIN_SIZE=8 + +# +# Slab allocator options +# +CONFIG_SLUB=y +# CONFIG_SLUB_TINY is not set +CONFIG_SLAB_MERGE_DEFAULT=y +# CONFIG_SLAB_FREELIST_RANDOM is not set +# CONFIG_SLAB_FREELIST_HARDENED is not set +# CONFIG_SLAB_BUCKETS is not set +# CONFIG_SLUB_STATS is not set +CONFIG_SLUB_CPU_PARTIAL=y +# CONFIG_RANDOM_KMALLOC_CACHES is not set +# end of Slab allocator options + +# CONFIG_SHUFFLE_PAGE_ALLOCATOR is not set +# CONFIG_COMPAT_BRK is not set +CONFIG_SPARSEMEM=y +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +CONFIG_SPARSEMEM_VMEMMAP=y +CONFIG_HAVE_GUP_FAST=y +CONFIG_ARCH_KEEP_MEMBLOCK=y +CONFIG_MEMORY_ISOLATION=y +CONFIG_EXCLUSIVE_SYSTEM_RAM=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +# CONFIG_MEMORY_HOTPLUG is not set +CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y +CONFIG_SPLIT_PTE_PTLOCKS=y +CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y +CONFIG_SPLIT_PMD_PTLOCKS=y +CONFIG_COMPACTION=y +CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 +CONFIG_PAGE_REPORTING=y +CONFIG_MIGRATION=y +CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION=y +CONFIG_ARCH_ENABLE_THP_MIGRATION=y +CONFIG_CONTIG_ALLOC=y +CONFIG_PCP_BATCH_SCALE_MAX=5 +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_KSM=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y +CONFIG_MEMORY_FAILURE=y +# CONFIG_HWPOISON_INJECT is not set +CONFIG_ARCH_WANTS_THP_SWAP=y +CONFIG_TRANSPARENT_HUGEPAGE=y +# CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS is not set +CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y +# CONFIG_TRANSPARENT_HUGEPAGE_NEVER is not set +CONFIG_THP_SWAP=y +CONFIG_READ_ONLY_THP_FOR_FS=y +CONFIG_PGTABLE_HAS_HUGE_LEAVES=y +CONFIG_ARCH_SUPPORTS_HUGE_PFNMAP=y +CONFIG_ARCH_SUPPORTS_PMD_PFNMAP=y +CONFIG_CMA=y +# CONFIG_CMA_DEBUGFS is not set +# CONFIG_CMA_SYSFS is not set +CONFIG_CMA_AREAS=7 +CONFIG_GENERIC_EARLY_IOREMAP=y +# CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set +# CONFIG_IDLE_PAGE_TRACKING is not set +CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y +CONFIG_ARCH_HAS_CURRENT_STACK_POINTER=y +CONFIG_ARCH_HAS_PTE_DEVMAP=y +CONFIG_ARCH_HAS_ZONE_DMA_SET=y +CONFIG_ZONE_DMA=y +CONFIG_ZONE_DMA32=y +CONFIG_ARCH_USES_HIGH_VMA_FLAGS=y +CONFIG_ARCH_HAS_PKEYS=y +CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_PERCPU_STATS is not set +# CONFIG_GUP_TEST is not set +# CONFIG_DMAPOOL_TEST is not set +CONFIG_ARCH_HAS_PTE_SPECIAL=y +CONFIG_MEMFD_CREATE=y +CONFIG_SECRETMEM=y +# CONFIG_ANON_VMA_NAME is not set +# CONFIG_USERFAULTFD is not set +CONFIG_LRU_GEN=y +CONFIG_LRU_GEN_ENABLED=y +# CONFIG_LRU_GEN_STATS is not set +CONFIG_LRU_GEN_WALKS_MMU=y +CONFIG_ARCH_SUPPORTS_PER_VMA_LOCK=y +CONFIG_PER_VMA_LOCK=y +CONFIG_LOCK_MM_AND_FIND_VMA=y +CONFIG_EXECMEM=y + +# +# Data Access Monitoring +# +# CONFIG_DAMON is not set +# end of Data Access Monitoring +# end of Memory Management options + +CONFIG_NET=y +CONFIG_COMPAT_NETLINK_MESSAGES=y +CONFIG_NET_INGRESS=y +CONFIG_NET_EGRESS=y +CONFIG_NET_XGRESS=y +CONFIG_SKB_EXTENSIONS=y +CONFIG_NET_DEVMEM=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_DIAG is not set +CONFIG_UNIX=y +CONFIG_AF_UNIX_OOB=y +# CONFIG_UNIX_DIAG is not set +# CONFIG_TLS is not set +# CONFIG_XFRM_USER is not set +# CONFIG_NET_KEY is not set +# CONFIG_XDP_SOCKETS is not set +CONFIG_NET_HANDSHAKE=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +# CONFIG_IP_FIB_TRIE_STATS is not set +CONFIG_IP_MULTIPLE_TABLES=y +# CONFIG_IP_ROUTE_MULTIPATH is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE_DEMUX is not set +CONFIG_NET_IP_TUNNEL=m +CONFIG_IP_MROUTE_COMMON=y +CONFIG_IP_MROUTE=y +# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set +# CONFIG_IP_PIMSM_V1 is not set +# CONFIG_IP_PIMSM_V2 is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_NET_IPVTI is not set +CONFIG_NET_UDP_TUNNEL=m +CONFIG_NET_FOU=m +# CONFIG_NET_FOU_IP_TUNNELS is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +CONFIG_INET_TABLE_PERTURB_ORDER=16 +CONFIG_INET_TUNNEL=m +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_INET_UDP_DIAG is not set +# CONFIG_INET_RAW_DIAG is not set +# CONFIG_INET_DIAG_DESTROY is not set +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_HTCP=m +# CONFIG_TCP_CONG_HSTCP is not set +# CONFIG_TCP_CONG_HYBLA is not set +# CONFIG_TCP_CONG_VEGAS is not set +# CONFIG_TCP_CONG_NV is not set +# CONFIG_TCP_CONG_SCALABLE is not set +# CONFIG_TCP_CONG_LP is not set +# CONFIG_TCP_CONG_VENO is not set +# CONFIG_TCP_CONG_YEAH is not set +# CONFIG_TCP_CONG_ILLINOIS is not set +# CONFIG_TCP_CONG_DCTCP is not set +# CONFIG_TCP_CONG_CDG is not set +CONFIG_TCP_CONG_BBR=y +# CONFIG_DEFAULT_CUBIC is not set +CONFIG_DEFAULT_BBR=y +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="bbr" +# CONFIG_TCP_AO is not set +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_ILA is not set +# CONFIG_IPV6_VTI is not set +CONFIG_IPV6_SIT=m +# CONFIG_IPV6_SIT_6RD is not set +CONFIG_IPV6_NDISC_NODETYPE=y +# CONFIG_IPV6_TUNNEL is not set +CONFIG_IPV6_FOU=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_MROUTE=y +# CONFIG_IPV6_MROUTE_MULTIPLE_TABLES is not set +CONFIG_IPV6_PIMSM_V2=y +# CONFIG_IPV6_SEG6_LWTUNNEL is not set +# CONFIG_IPV6_SEG6_HMAC is not set +# CONFIG_IPV6_RPL_LWTUNNEL is not set +# CONFIG_IPV6_IOAM6_LWTUNNEL is not set +# CONFIG_NETLABEL is not set +# CONFIG_MPTCP is not set +# CONFIG_NETWORK_SECMARK is not set +CONFIG_NET_PTP_CLASSIFY=y +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +CONFIG_NETFILTER=y +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=m + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_INGRESS=y +CONFIG_NETFILTER_EGRESS=y +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_FAMILY_BRIDGE=y +CONFIG_NETFILTER_BPF_LINK=y +# CONFIG_NETFILTER_NETLINK_HOOK is not set +# CONFIG_NETFILTER_NETLINK_ACCT is not set +# CONFIG_NETFILTER_NETLINK_QUEUE is not set +# CONFIG_NETFILTER_NETLINK_LOG is not set +# CONFIG_NETFILTER_NETLINK_OSF is not set +CONFIG_NF_CONNTRACK=y +CONFIG_NF_LOG_SYSLOG=m +# CONFIG_NF_CONNTRACK_MARK is not set +# CONFIG_NF_CONNTRACK_ZONES is not set +CONFIG_NF_CONNTRACK_PROCFS=y +CONFIG_NF_CONNTRACK_EVENTS=y +# CONFIG_NF_CONNTRACK_TIMEOUT is not set +# CONFIG_NF_CONNTRACK_TIMESTAMP is not set +# CONFIG_NF_CONNTRACK_LABELS is not set +CONFIG_NF_CT_PROTO_DCCP=y +CONFIG_NF_CT_PROTO_SCTP=y +CONFIG_NF_CT_PROTO_UDPLITE=y +# CONFIG_NF_CONNTRACK_AMANDA is not set +# CONFIG_NF_CONNTRACK_FTP is not set +# CONFIG_NF_CONNTRACK_H323 is not set +# CONFIG_NF_CONNTRACK_IRC is not set +# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set +# CONFIG_NF_CONNTRACK_SNMP is not set +# CONFIG_NF_CONNTRACK_PPTP is not set +# CONFIG_NF_CONNTRACK_SANE is not set +# CONFIG_NF_CONNTRACK_SIP is not set +# CONFIG_NF_CONNTRACK_TFTP is not set +# CONFIG_NF_CT_NETLINK is not set +CONFIG_NF_NAT=y +CONFIG_NF_NAT_REDIRECT=y +CONFIG_NF_NAT_MASQUERADE=y +CONFIG_NF_TABLES=m +CONFIG_NF_TABLES_INET=y +# CONFIG_NF_TABLES_NETDEV is not set +# CONFIG_NFT_NUMGEN is not set +# CONFIG_NFT_CT is not set +# CONFIG_NFT_CONNLIMIT is not set +# CONFIG_NFT_LOG is not set +# CONFIG_NFT_LIMIT is not set +CONFIG_NFT_MASQ=m +# CONFIG_NFT_REDIR is not set +CONFIG_NFT_NAT=m +# CONFIG_NFT_TUNNEL is not set +# CONFIG_NFT_QUOTA is not set +# CONFIG_NFT_REJECT is not set +# CONFIG_NFT_COMPAT is not set +# CONFIG_NFT_HASH is not set +# CONFIG_NFT_SOCKET is not set +# CONFIG_NFT_OSF is not set +# CONFIG_NFT_TPROXY is not set +# CONFIG_NFT_SYNPROXY is not set +# CONFIG_NF_FLOW_TABLE is not set +CONFIG_NETFILTER_XTABLES=y +CONFIG_NETFILTER_XTABLES_COMPAT=y + +# +# Xtables combined modules +# +# CONFIG_NETFILTER_XT_MARK is not set +# CONFIG_NETFILTER_XT_CONNMARK is not set + +# +# Xtables targets +# +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m +# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set +# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +# CONFIG_NETFILTER_XT_TARGET_HL is not set +# CONFIG_NETFILTER_XT_TARGET_HMARK is not set +# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set +# CONFIG_NETFILTER_XT_TARGET_LED is not set +CONFIG_NETFILTER_XT_TARGET_LOG=m +# CONFIG_NETFILTER_XT_TARGET_MARK is not set +CONFIG_NETFILTER_XT_NAT=y +# CONFIG_NETFILTER_XT_TARGET_NETMAP is not set +# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set +# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set +# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set +CONFIG_NETFILTER_XT_TARGET_REDIRECT=m +CONFIG_NETFILTER_XT_TARGET_MASQUERADE=y +# CONFIG_NETFILTER_XT_TARGET_TEE is not set +# CONFIG_NETFILTER_XT_TARGET_TPROXY is not set +# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set + +# +# Xtables matches +# +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +# CONFIG_NETFILTER_XT_MATCH_BPF is not set +# CONFIG_NETFILTER_XT_MATCH_CGROUP is not set +# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set +# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set +# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set +# CONFIG_NETFILTER_XT_MATCH_CONNLABEL is not set +# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set +# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +# CONFIG_NETFILTER_XT_MATCH_CPU is not set +# CONFIG_NETFILTER_XT_MATCH_DCCP is not set +# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set +# CONFIG_NETFILTER_XT_MATCH_DSCP is not set +# CONFIG_NETFILTER_XT_MATCH_ECN is not set +# CONFIG_NETFILTER_XT_MATCH_ESP is not set +# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set +# CONFIG_NETFILTER_XT_MATCH_HELPER is not set +# CONFIG_NETFILTER_XT_MATCH_HL is not set +# CONFIG_NETFILTER_XT_MATCH_IPCOMP is not set +# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set +# CONFIG_NETFILTER_XT_MATCH_L2TP is not set +# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set +# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set +# CONFIG_NETFILTER_XT_MATCH_MAC is not set +# CONFIG_NETFILTER_XT_MATCH_MARK is not set +# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set +# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set +# CONFIG_NETFILTER_XT_MATCH_OSF is not set +# CONFIG_NETFILTER_XT_MATCH_OWNER is not set +# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set +# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set +# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set +# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set +# CONFIG_NETFILTER_XT_MATCH_REALM is not set +# CONFIG_NETFILTER_XT_MATCH_RECENT is not set +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set +# CONFIG_NETFILTER_XT_MATCH_SOCKET is not set +# CONFIG_NETFILTER_XT_MATCH_STATE is not set +# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set +# CONFIG_NETFILTER_XT_MATCH_STRING is not set +# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set +# CONFIG_NETFILTER_XT_MATCH_TIME is not set +# CONFIG_NETFILTER_XT_MATCH_U32 is not set +# end of Core Netfilter Configuration + +# CONFIG_IP_SET is not set +# CONFIG_IP_VS is not set + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=y +CONFIG_IP_NF_IPTABLES_LEGACY=y +# CONFIG_NF_SOCKET_IPV4 is not set +# CONFIG_NF_TPROXY_IPV4 is not set +CONFIG_NF_TABLES_IPV4=y +# CONFIG_NFT_DUP_IPV4 is not set +# CONFIG_NFT_FIB_IPV4 is not set +# CONFIG_NF_TABLES_ARP is not set +# CONFIG_NF_DUP_IPV4 is not set +# CONFIG_NF_LOG_ARP is not set +CONFIG_NF_LOG_IPV4=m +CONFIG_NF_REJECT_IPV4=y +CONFIG_IP_NF_IPTABLES=y +# CONFIG_IP_NF_MATCH_AH is not set +# CONFIG_IP_NF_MATCH_ECN is not set +# CONFIG_IP_NF_MATCH_RPFILTER is not set +# CONFIG_IP_NF_MATCH_TTL is not set +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +# CONFIG_IP_NF_TARGET_SYNPROXY is not set +CONFIG_IP_NF_NAT=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +# CONFIG_IP_NF_TARGET_NETMAP is not set +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_MANGLE=y +# CONFIG_IP_NF_TARGET_ECN is not set +# CONFIG_IP_NF_TARGET_TTL is not set +# CONFIG_IP_NF_RAW is not set +# CONFIG_IP_NF_SECURITY is not set +# CONFIG_IP_NF_ARPFILTER is not set +# end of IP: Netfilter Configuration + +# +# IPv6: Netfilter Configuration +# +CONFIG_IP6_NF_IPTABLES_LEGACY=m +# CONFIG_NF_SOCKET_IPV6 is not set +# CONFIG_NF_TPROXY_IPV6 is not set +CONFIG_NF_TABLES_IPV6=y +# CONFIG_NFT_DUP_IPV6 is not set +# CONFIG_NFT_FIB_IPV6 is not set +# CONFIG_NF_DUP_IPV6 is not set +CONFIG_NF_REJECT_IPV6=m +CONFIG_NF_LOG_IPV6=m +CONFIG_IP6_NF_IPTABLES=m +# CONFIG_IP6_NF_MATCH_AH is not set +# CONFIG_IP6_NF_MATCH_EUI64 is not set +# CONFIG_IP6_NF_MATCH_FRAG is not set +# CONFIG_IP6_NF_MATCH_OPTS is not set +# CONFIG_IP6_NF_MATCH_HL is not set +# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set +# CONFIG_IP6_NF_MATCH_MH is not set +# CONFIG_IP6_NF_MATCH_RPFILTER is not set +# CONFIG_IP6_NF_MATCH_RT is not set +# CONFIG_IP6_NF_MATCH_SRH is not set +# CONFIG_IP6_NF_TARGET_HL is not set +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +# CONFIG_IP6_NF_TARGET_SYNPROXY is not set +CONFIG_IP6_NF_MANGLE=m +# CONFIG_IP6_NF_RAW is not set +# CONFIG_IP6_NF_SECURITY is not set +CONFIG_IP6_NF_NAT=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +# CONFIG_IP6_NF_TARGET_NPT is not set +# end of IPv6: Netfilter Configuration + +CONFIG_NF_DEFRAG_IPV6=y +# CONFIG_NF_TABLES_BRIDGE is not set +# CONFIG_NF_CONNTRACK_BRIDGE is not set +# CONFIG_BRIDGE_NF_EBTABLES is not set +# CONFIG_IP_DCCP is not set +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_OBJCNT is not set +CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5=y +# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1 is not set +# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set +CONFIG_SCTP_COOKIE_HMAC_MD5=y +# CONFIG_SCTP_COOKIE_HMAC_SHA1 is not set +CONFIG_INET_SCTP_DIAG=m +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_L2TP is not set +CONFIG_STP=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_IGMP_SNOOPING=y +# CONFIG_BRIDGE_VLAN_FILTERING is not set +# CONFIG_BRIDGE_MRP is not set +# CONFIG_BRIDGE_CFM is not set +# CONFIG_NET_DSA is not set +CONFIG_VLAN_8021Q=m +# CONFIG_VLAN_8021Q_GVRP is not set +# CONFIG_VLAN_8021Q_MVRP is not set +CONFIG_LLC=m +# CONFIG_LLC2 is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_PHONET is not set +# CONFIG_6LOWPAN is not set +# CONFIG_IEEE802154 is not set +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +# CONFIG_NET_SCH_HTB is not set +# CONFIG_NET_SCH_HFSC is not set +# CONFIG_NET_SCH_PRIO is not set +# CONFIG_NET_SCH_MULTIQ is not set +# CONFIG_NET_SCH_RED is not set +# CONFIG_NET_SCH_SFB is not set +# CONFIG_NET_SCH_SFQ is not set +# CONFIG_NET_SCH_TEQL is not set +# CONFIG_NET_SCH_TBF is not set +# CONFIG_NET_SCH_CBS is not set +# CONFIG_NET_SCH_ETF is not set +# CONFIG_NET_SCH_TAPRIO is not set +# CONFIG_NET_SCH_GRED is not set +# CONFIG_NET_SCH_NETEM is not set +# CONFIG_NET_SCH_DRR is not set +# CONFIG_NET_SCH_MQPRIO is not set +# CONFIG_NET_SCH_SKBPRIO is not set +# CONFIG_NET_SCH_CHOKE is not set +# CONFIG_NET_SCH_QFQ is not set +# CONFIG_NET_SCH_CODEL is not set +CONFIG_NET_SCH_FQ_CODEL=y +# CONFIG_NET_SCH_CAKE is not set +# CONFIG_NET_SCH_FQ is not set +# CONFIG_NET_SCH_HHF is not set +# CONFIG_NET_SCH_PIE is not set +# CONFIG_NET_SCH_PLUG is not set +# CONFIG_NET_SCH_ETS is not set +CONFIG_NET_SCH_DEFAULT=y +CONFIG_DEFAULT_FQ_CODEL=y +# CONFIG_DEFAULT_PFIFO_FAST is not set +CONFIG_DEFAULT_NET_SCH="fq_codel" + +# +# Classification +# +# CONFIG_NET_CLS_BASIC is not set +# CONFIG_NET_CLS_ROUTE4 is not set +# CONFIG_NET_CLS_FW is not set +# CONFIG_NET_CLS_U32 is not set +# CONFIG_NET_CLS_FLOW is not set +# CONFIG_NET_CLS_CGROUP is not set +# CONFIG_NET_CLS_BPF is not set +# CONFIG_NET_CLS_FLOWER is not set +# CONFIG_NET_CLS_MATCHALL is not set +# CONFIG_NET_EMATCH is not set +# CONFIG_NET_CLS_ACT is not set +CONFIG_NET_SCH_FIFO=y +# CONFIG_DCB is not set +CONFIG_DNS_RESOLVER=y +# CONFIG_BATMAN_ADV is not set +# CONFIG_OPENVSWITCH is not set +# CONFIG_VSOCKETS is not set +# CONFIG_NETLINK_DIAG is not set +# CONFIG_MPLS is not set +# CONFIG_NET_NSH is not set +# CONFIG_HSR is not set +# CONFIG_NET_SWITCHDEV is not set +# CONFIG_NET_L3_MASTER_DEV is not set +# CONFIG_QRTR is not set +# CONFIG_NET_NCSI is not set +CONFIG_PCPU_DEV_REFCNT=y +CONFIG_MAX_SKB_FRAGS=17 +CONFIG_RPS=y +CONFIG_RFS_ACCEL=y +CONFIG_SOCK_RX_QUEUE_MAPPING=y +CONFIG_XPS=y +# CONFIG_CGROUP_NET_PRIO is not set +# CONFIG_CGROUP_NET_CLASSID is not set +CONFIG_NET_RX_BUSY_POLL=y +CONFIG_BQL=y +# CONFIG_BPF_STREAM_PARSER is not set +CONFIG_NET_FLOW_LIMIT=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# end of Network testing +# end of Networking options + +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +CONFIG_BT=m +CONFIG_BT_BREDR=y +# CONFIG_BT_RFCOMM is not set +# CONFIG_BT_BNEP is not set +CONFIG_BT_HIDP=m +# CONFIG_BT_LE is not set +CONFIG_BT_LEDS=y +# CONFIG_BT_MSFTEXT is not set +# CONFIG_BT_AOSPEXT is not set +# CONFIG_BT_DEBUGFS is not set +# CONFIG_BT_SELFTEST is not set + +# +# Bluetooth device drivers +# +CONFIG_BT_INTEL=m +CONFIG_BT_BCM=m +CONFIG_BT_RTL=m +CONFIG_BT_HCIBTUSB=m +# CONFIG_BT_HCIBTUSB_AUTOSUSPEND is not set +CONFIG_BT_HCIBTUSB_POLL_SYNC=y +CONFIG_BT_HCIBTUSB_BCM=y +# CONFIG_BT_HCIBTUSB_MTK is not set +CONFIG_BT_HCIBTUSB_RTL=y +# CONFIG_BT_HCIBTSDIO is not set +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_SERDEV=y +CONFIG_BT_HCIUART_H4=y +# CONFIG_BT_HCIUART_NOKIA is not set +# CONFIG_BT_HCIUART_BCSP is not set +# CONFIG_BT_HCIUART_ATH3K is not set +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIUART_3WIRE=y +# CONFIG_BT_HCIUART_INTEL is not set +CONFIG_BT_HCIUART_BCM=y +CONFIG_BT_HCIUART_RTL=y +# CONFIG_BT_HCIUART_QCA is not set +# CONFIG_BT_HCIUART_AG6XX is not set +# CONFIG_BT_HCIUART_MRVL is not set +# CONFIG_BT_HCIUART_AML is not set +# CONFIG_BT_HCIBCM203X is not set +# CONFIG_BT_HCIBPA10X is not set +# CONFIG_BT_HCIBFUSB is not set +# CONFIG_BT_HCIVHCI is not set +# CONFIG_BT_MRVL is not set +# CONFIG_BT_ATH3K is not set +# CONFIG_BT_MTKSDIO is not set +# CONFIG_BT_MTKUART is not set +# CONFIG_BT_NXPUART is not set +# end of Bluetooth device drivers + +# CONFIG_AF_RXRPC is not set +# CONFIG_AF_KCM is not set +# CONFIG_MCTP is not set +CONFIG_FIB_RULES=y +CONFIG_WIRELESS=y +CONFIG_WEXT_CORE=y +CONFIG_WEXT_PROC=y +CONFIG_CFG80211=y +# CONFIG_NL80211_TESTMODE is not set +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +# CONFIG_CFG80211_CERTIFICATION_ONUS is not set +CONFIG_CFG80211_REQUIRE_SIGNED_REGDB=y +CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS=y +CONFIG_CFG80211_DEFAULT_PS=y +# CONFIG_CFG80211_DEBUGFS is not set +CONFIG_CFG80211_CRDA_SUPPORT=y +CONFIG_CFG80211_WEXT=y +CONFIG_LIB80211=m +# CONFIG_LIB80211_DEBUG is not set +CONFIG_MAC80211=y +CONFIG_MAC80211_HAS_RC=y +CONFIG_MAC80211_RC_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" +# CONFIG_MAC80211_MESH is not set +CONFIG_MAC80211_LEDS=y +# CONFIG_MAC80211_DEBUG_MENU is not set +CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 +CONFIG_RFKILL=y +CONFIG_RFKILL_LEDS=y +CONFIG_RFKILL_INPUT=y +CONFIG_RFKILL_GPIO=y +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set +# CONFIG_NFC is not set +# CONFIG_PSAMPLE is not set +# CONFIG_NET_IFE is not set +# CONFIG_LWTUNNEL is not set +CONFIG_DST_CACHE=y +CONFIG_GRO_CELLS=y +CONFIG_NET_SELFTESTS=y +CONFIG_NET_SOCK_MSG=y +CONFIG_PAGE_POOL=y +# CONFIG_PAGE_POOL_STATS is not set +CONFIG_FAILOVER=y +CONFIG_ETHTOOL_NETLINK=y + +# +# Device Drivers +# +CONFIG_ARM_AMBA=y +CONFIG_HAVE_PCI=y +CONFIG_GENERIC_PCI_IOMAP=y +# CONFIG_PCI is not set +# CONFIG_PCCARD is not set + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER=y +CONFIG_UEVENT_HELPER_PATH="" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +# CONFIG_DEVTMPFS_SAFE is not set +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y + +# +# Firmware loader +# +CONFIG_FW_LOADER=y +CONFIG_FW_LOADER_DEBUG=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_FW_LOADER_USER_HELPER is not set +# CONFIG_FW_LOADER_COMPRESS is not set +CONFIG_FW_CACHE=y +# CONFIG_FW_UPLOAD is not set +# end of Firmware loader + +CONFIG_WANT_DEV_COREDUMP=y +CONFIG_ALLOW_DEV_COREDUMP=y +CONFIG_DEV_COREDUMP=y +# CONFIG_DEBUG_DRIVER is not set +CONFIG_DEBUG_DEVRES=y +# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set +# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set +CONFIG_GENERIC_CPU_DEVICES=y +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_CPU_VULNERABILITIES=y +CONFIG_SOC_BUS=y +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_SPI=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGMAP_IRQ=y +CONFIG_DMA_SHARED_BUFFER=y +# CONFIG_DMA_FENCE_TRACE is not set +CONFIG_GENERIC_ARCH_TOPOLOGY=y +# CONFIG_FW_DEVLINK_SYNC_STATE_TIMEOUT is not set +# end of Generic Driver Options + +# +# Bus devices +# +# CONFIG_MOXTET is not set +# CONFIG_VEXPRESS_CONFIG is not set +# CONFIG_MHI_BUS is not set +# CONFIG_MHI_BUS_EP is not set +# end of Bus devices + +# +# Cache Drivers +# +# end of Cache Drivers + +CONFIG_CONNECTOR=y +CONFIG_PROC_EVENTS=y + +# +# Firmware Drivers +# + +# +# ARM System Control and Management Interface Protocol +# +CONFIG_ARM_SCMI_PROTOCOL=m +# CONFIG_ARM_SCMI_RAW_MODE_SUPPORT is not set +# CONFIG_ARM_SCMI_DEBUG_COUNTERS is not set + +# +# SCMI Transport Drivers +# +CONFIG_ARM_SCMI_HAVE_TRANSPORT=y +CONFIG_ARM_SCMI_HAVE_SHMEM=y +CONFIG_ARM_SCMI_HAVE_MSG=y +CONFIG_ARM_SCMI_TRANSPORT_MAILBOX=m +CONFIG_ARM_SCMI_TRANSPORT_SMC=m +# CONFIG_ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE is not set +CONFIG_ARM_SCMI_TRANSPORT_OPTEE=m +# end of SCMI Transport Drivers + +# +# ARM SCMI NXP i.MX Vendor Protocols +# +# CONFIG_IMX_SCMI_BBM_EXT is not set +# end of ARM SCMI NXP i.MX Vendor Protocols + +# CONFIG_ARM_SCMI_POWER_CONTROL is not set +# end of ARM System Control and Management Interface Protocol + +CONFIG_ARM_SCPI_PROTOCOL=y +# CONFIG_ARM_SDE_INTERFACE is not set +# CONFIG_FIRMWARE_MEMMAP is not set +# CONFIG_ARM_FFA_TRANSPORT is not set +# CONFIG_GOOGLE_FIRMWARE is not set +CONFIG_ARM_PSCI_FW=y +# CONFIG_ARM_PSCI_CHECKER is not set + +# +# Qualcomm firmware drivers +# +# end of Qualcomm firmware drivers + +CONFIG_HAVE_ARM_SMCCC=y +CONFIG_HAVE_ARM_SMCCC_DISCOVERY=y +CONFIG_ARM_SMCCC_SOC_ID=y + +# +# Tegra firmware driver +# +# end of Tegra firmware driver +# end of Firmware Drivers + +# CONFIG_GNSS is not set +CONFIG_MTD=y +# CONFIG_MTD_TESTS is not set + +# +# Partition parsers +# +# CONFIG_MTD_CMDLINE_PARTS is not set +CONFIG_MTD_OF_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# end of Partition parsers + +# +# User Modules And Translation Layers +# +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y + +# +# Note that in some cases UBI block is preferred. See MTD_UBI_BLOCK. +# +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_SM_FTL is not set +# CONFIG_MTD_OOPS is not set +# CONFIG_MTD_SWAP is not set +# CONFIG_MTD_PARTITIONED_MASTER is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# end of RAM/ROM/Flash chip drivers + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set +# end of Mapping drivers for chip access + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_MCHP23K256 is not set +# CONFIG_MTD_MCHP48L640 is not set +# CONFIG_MTD_SST25L is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOCG3 is not set +# end of Self-contained MTD device drivers + +# +# NAND +# +# CONFIG_MTD_ONENAND is not set +# CONFIG_MTD_RAW_NAND is not set +# CONFIG_MTD_SPI_NAND is not set + +# +# ECC engine support +# +# CONFIG_MTD_NAND_ECC_SW_HAMMING is not set +# CONFIG_MTD_NAND_ECC_SW_BCH is not set +# CONFIG_MTD_NAND_ECC_MXIC is not set +# end of ECC engine support +# end of NAND + +# +# LPDDR & LPDDR2 PCM memory drivers +# +# CONFIG_MTD_LPDDR is not set +# end of LPDDR & LPDDR2 PCM memory drivers + +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y +# CONFIG_MTD_SPI_NOR_SWP_DISABLE is not set +CONFIG_MTD_SPI_NOR_SWP_DISABLE_ON_VOLATILE=y +# CONFIG_MTD_SPI_NOR_SWP_KEEP is not set +# CONFIG_MTD_UBI is not set +# CONFIG_MTD_HYPERBUS is not set +CONFIG_DTC=y +CONFIG_OF=y +# CONFIG_OF_UNITTEST is not set +CONFIG_OF_FLATTREE=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_KOBJ=y +CONFIG_OF_DYNAMIC=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_IRQ=y +CONFIG_OF_RESERVED_MEM=y +CONFIG_OF_RESOLVE=y +CONFIG_OF_OVERLAY=y +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_NULL_BLK is not set +CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +# CONFIG_ZRAM_BACKEND_DEFLATE is not set +# CONFIG_ZRAM_BACKEND_842 is not set +CONFIG_ZRAM_BACKEND_LZO=y +CONFIG_ZRAM_DEF_COMP_LZORLE=y +# CONFIG_ZRAM_DEF_COMP_LZO is not set +# CONFIG_ZRAM_DEF_COMP_LZ4 is not set +# CONFIG_ZRAM_DEF_COMP_LZ4HC is not set +# CONFIG_ZRAM_DEF_COMP_ZSTD is not set +CONFIG_ZRAM_DEF_COMP="lzo-rle" +CONFIG_ZRAM_WRITEBACK=y +# CONFIG_ZRAM_TRACK_ENTRY_ACTIME is not set +# CONFIG_ZRAM_MEMORY_TRACKING is not set +CONFIG_ZRAM_MULTI_COMP=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 +# CONFIG_BLK_DEV_DRBD is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_BLK_DEV_RBD is not set +# CONFIG_BLK_DEV_UBLK is not set + +# +# NVME Support +# +# CONFIG_NVME_FC is not set +# CONFIG_NVME_TCP is not set +# CONFIG_NVME_TARGET is not set +# end of NVME Support + +# +# Misc devices +# +# CONFIG_AD525X_DPOT is not set +# CONFIG_DUMMY_IRQ is not set +# CONFIG_RPMB is not set +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_HI6421V600_IRQ is not set +# CONFIG_APDS9802ALS is not set +# CONFIG_ISL29003 is not set +# CONFIG_ISL29020 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_BH1770 is not set +# CONFIG_SENSORS_APDS990X is not set +# CONFIG_HMC6352 is not set +# CONFIG_DS1682 is not set +# CONFIG_LATTICE_ECP3_CONFIG is not set +# CONFIG_SRAM is not set +# CONFIG_XILINX_SDFEC is not set +# CONFIG_HISI_HIKEY_USB is not set +# CONFIG_OPEN_DICE is not set +CONFIG_NTSYNC=y +# CONFIG_VCPU_STALL_DETECTOR is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +CONFIG_EEPROM_AT25=m +# CONFIG_EEPROM_MAX6875 is not set +CONFIG_EEPROM_93CX6=m +# CONFIG_EEPROM_93XX46 is not set +# CONFIG_EEPROM_IDT_89HPESX is not set +# CONFIG_EEPROM_EE1004 is not set +# end of EEPROM support + +# +# Texas Instruments shared transport line discipline +# +# CONFIG_TI_ST is not set +# end of Texas Instruments shared transport line discipline + +# CONFIG_SENSORS_LIS3_SPI is not set +# CONFIG_SENSORS_LIS3_I2C is not set +# CONFIG_ALTERA_STAPL is not set +# CONFIG_ECHO is not set +# CONFIG_MISC_RTSX_USB is not set +# CONFIG_UACCE is not set +# CONFIG_PVPANIC is not set +# end of Misc devices + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI_COMMON=y +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_PROC_FS is not set + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +CONFIG_BLK_DEV_BSG=y +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +# end of SCSI Transports + +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_ISCSI_BOOT_SYSFS is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DH is not set +# end of SCSI device support + +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_TARGET_CORE is not set +CONFIG_NETDEVICES=y +CONFIG_MII=m +CONFIG_NET_CORE=y +# CONFIG_BONDING is not set +# CONFIG_DUMMY is not set +CONFIG_WIREGUARD=m +# CONFIG_WIREGUARD_DEBUG is not set +# CONFIG_EQUALIZER is not set +# CONFIG_NET_TEAM is not set +# CONFIG_MACVLAN is not set +# CONFIG_IPVLAN is not set +# CONFIG_VXLAN is not set +# CONFIG_GENEVE is not set +# CONFIG_BAREUDP is not set +# CONFIG_GTP is not set +# CONFIG_PFCP is not set +# CONFIG_AMT is not set +# CONFIG_MACSEC is not set +CONFIG_NETCONSOLE=m +# CONFIG_NETCONSOLE_DYNAMIC is not set +# CONFIG_NETCONSOLE_EXTENDED_LOG is not set +CONFIG_NETPOLL=y +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_TUN=m +CONFIG_TUN_VNET_CROSS_LE=y +CONFIG_VETH=m +CONFIG_NLMON=m +# CONFIG_NETKIT is not set +# CONFIG_ETHERNET is not set +CONFIG_PHYLINK=m +CONFIG_PHYLIB=y +CONFIG_SWPHY=y +# CONFIG_LED_TRIGGER_PHY is not set +CONFIG_PHYLIB_LEDS=y +CONFIG_FIXED_PHY=y +# CONFIG_SFP is not set + +# +# MII PHY device drivers +# +# CONFIG_AIR_EN8811H_PHY is not set +# CONFIG_AMD_PHY is not set +# CONFIG_ADIN_PHY is not set +# CONFIG_ADIN1100_PHY is not set +# CONFIG_AQUANTIA_PHY is not set +CONFIG_AX88796B_PHY=m +# CONFIG_BROADCOM_PHY is not set +# CONFIG_BCM54140_PHY is not set +# CONFIG_BCM7XXX_PHY is not set +# CONFIG_BCM84881_PHY is not set +# CONFIG_BCM87XX_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_CORTINA_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_INTEL_XWAY_PHY is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MARVELL_PHY is not set +# CONFIG_MARVELL_10G_PHY is not set +# CONFIG_MARVELL_88Q2XXX_PHY is not set +# CONFIG_MARVELL_88X2222_PHY is not set +# CONFIG_MAXLINEAR_GPHY is not set +# CONFIG_MEDIATEK_GE_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_MICROCHIP_T1S_PHY is not set +CONFIG_MICROCHIP_PHY=m +# CONFIG_MICROCHIP_T1_PHY is not set +# CONFIG_MICROSEMI_PHY is not set +# CONFIG_MOTORCOMM_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_NXP_CBTX_PHY is not set +# CONFIG_NXP_C45_TJA11XX_PHY is not set +# CONFIG_NXP_TJA11XX_PHY is not set +# CONFIG_NCN26000_PHY is not set +# CONFIG_AT803X_PHY is not set +# CONFIG_QCA83XX_PHY is not set +# CONFIG_QCA808X_PHY is not set +# CONFIG_QCA807X_PHY is not set +# CONFIG_QSEMI_PHY is not set +CONFIG_REALTEK_PHY=y +# CONFIG_RENESAS_PHY is not set +CONFIG_ROCKCHIP_PHY=y +CONFIG_SMSC_PHY=m +# CONFIG_STE10XP is not set +# CONFIG_TERANETICS_PHY is not set +# CONFIG_DP83822_PHY is not set +# CONFIG_DP83TC811_PHY is not set +# CONFIG_DP83848_PHY is not set +# CONFIG_DP83867_PHY is not set +# CONFIG_DP83869_PHY is not set +# CONFIG_DP83TD510_PHY is not set +# CONFIG_DP83TG720_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_XILINX_GMII2RGMII is not set +# CONFIG_MICREL_KS8995MA is not set +# CONFIG_PSE_CONTROLLER is not set +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_BUS=y +CONFIG_FWNODE_MDIO=y +CONFIG_OF_MDIO=y +CONFIG_MDIO_DEVRES=y +CONFIG_MDIO_BITBANG=y +# CONFIG_MDIO_BCM_UNIMAC is not set +CONFIG_MDIO_GPIO=y +# CONFIG_MDIO_HISI_FEMAC is not set +# CONFIG_MDIO_MVUSB is not set +# CONFIG_MDIO_MSCC_MIIM is not set +# CONFIG_MDIO_OCTEON is not set +# CONFIG_MDIO_IPQ4019 is not set +# CONFIG_MDIO_IPQ8064 is not set + +# +# MDIO Multiplexers +# +CONFIG_MDIO_BUS_MUX=y +# CONFIG_MDIO_BUS_MUX_GPIO is not set +CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y +CONFIG_MDIO_BUS_MUX_MMIOREG=y + +# +# PCS device drivers +# +# CONFIG_PCS_XPCS is not set +# end of PCS device drivers + +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +CONFIG_USB_NET_DRIVERS=m +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +CONFIG_USB_RTL8150=m +CONFIG_USB_RTL8152=m +# CONFIG_USB_LAN78XX is not set +CONFIG_USB_USBNET=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_AX88179_178A=m +CONFIG_USB_NET_CDCETHER=m +# CONFIG_USB_NET_CDC_EEM is not set +CONFIG_USB_NET_CDC_NCM=m +# CONFIG_USB_NET_HUAWEI_CDC_NCM is not set +CONFIG_USB_NET_CDC_MBIM=m +# CONFIG_USB_NET_DM9601 is not set +# CONFIG_USB_NET_SR9700 is not set +# CONFIG_USB_NET_SR9800 is not set +CONFIG_USB_NET_SMSC75XX=m +CONFIG_USB_NET_SMSC95XX=m +# CONFIG_USB_NET_GL620A is not set +# CONFIG_USB_NET_NET1080 is not set +# CONFIG_USB_NET_PLUSB is not set +# CONFIG_USB_NET_MCS7830 is not set +CONFIG_USB_NET_RNDIS_HOST=m +# CONFIG_USB_NET_CDC_SUBSET is not set +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_NET_CX82310_ETH is not set +# CONFIG_USB_NET_KALMIA is not set +# CONFIG_USB_NET_QMI_WWAN is not set +# CONFIG_USB_HSO is not set +# CONFIG_USB_NET_INT51X1 is not set +# CONFIG_USB_IPHETH is not set +# CONFIG_USB_SIERRA_NET is not set +# CONFIG_USB_VL600 is not set +# CONFIG_USB_NET_CH9200 is not set +# CONFIG_USB_NET_AQC111 is not set +CONFIG_USB_RTL8153_ECM=m +CONFIG_WLAN=y +# CONFIG_WLAN_VENDOR_ADMTEK is not set +CONFIG_ATH_COMMON=m +CONFIG_WLAN_VENDOR_ATH=y +# CONFIG_ATH_DEBUG is not set +CONFIG_ATH9K_HW=m +CONFIG_ATH9K_COMMON=m +CONFIG_ATH9K_BTCOEX_SUPPORT=y +CONFIG_ATH9K=m +# CONFIG_ATH9K_AHB is not set +# CONFIG_ATH9K_DYNACK is not set +# CONFIG_ATH9K_WOW is not set +CONFIG_ATH9K_RFKILL=y +CONFIG_ATH9K_CHANNEL_CONTEXT=y +CONFIG_ATH9K_PCOEM=y +CONFIG_ATH9K_HTC=m +# CONFIG_ATH9K_HTC_DEBUGFS is not set +CONFIG_ATH9K_HWRNG=y +CONFIG_CARL9170=m +CONFIG_CARL9170_LEDS=y +CONFIG_CARL9170_WPC=y +CONFIG_CARL9170_HWRNG=y +CONFIG_ATH6KL=m +# CONFIG_ATH6KL_SDIO is not set +CONFIG_ATH6KL_USB=m +# CONFIG_ATH6KL_DEBUG is not set +CONFIG_AR5523=m +CONFIG_ATH10K=m +CONFIG_ATH10K_CE=y +# CONFIG_ATH10K_SDIO is not set +CONFIG_ATH10K_USB=m +# CONFIG_ATH10K_DEBUG is not set +# CONFIG_ATH10K_DEBUGFS is not set +CONFIG_ATH10K_LEDS=y +CONFIG_WCN36XX=m +# CONFIG_WCN36XX_DEBUGFS is not set +# CONFIG_ATH11K is not set +# CONFIG_WLAN_VENDOR_ATMEL is not set +# CONFIG_WLAN_VENDOR_BROADCOM is not set +CONFIG_WLAN_VENDOR_INTEL=y +CONFIG_WLAN_VENDOR_INTERSIL=y +CONFIG_P54_COMMON=m +CONFIG_P54_USB=m +# CONFIG_P54_SPI is not set +CONFIG_P54_LEDS=y +CONFIG_WLAN_VENDOR_MARVELL=y +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_USB=m +# CONFIG_LIBERTAS_SDIO is not set +# CONFIG_LIBERTAS_SPI is not set +# CONFIG_LIBERTAS_DEBUG is not set +# CONFIG_LIBERTAS_MESH is not set +CONFIG_LIBERTAS_THINFIRM=m +# CONFIG_LIBERTAS_THINFIRM_DEBUG is not set +CONFIG_LIBERTAS_THINFIRM_USB=m +CONFIG_MWIFIEX=m +# CONFIG_MWIFIEX_SDIO is not set +CONFIG_MWIFIEX_USB=m +CONFIG_WLAN_VENDOR_MEDIATEK=y +CONFIG_MT7601U=m +CONFIG_MT76_CORE=m +CONFIG_MT76_LEDS=y +CONFIG_MT76_USB=m +CONFIG_MT76_SDIO=m +CONFIG_MT76x02_LIB=m +CONFIG_MT76x02_USB=m +CONFIG_MT76_CONNAC_LIB=m +CONFIG_MT76x0_COMMON=m +CONFIG_MT76x0U=m +CONFIG_MT76x2_COMMON=m +CONFIG_MT76x2U=m +CONFIG_MT7615_COMMON=m +CONFIG_MT7663_USB_SDIO_COMMON=m +CONFIG_MT7663U=m +CONFIG_MT7663S=m +# CONFIG_MT7921S is not set +# CONFIG_MT7921U is not set +# CONFIG_MT7925U is not set +CONFIG_WLAN_VENDOR_MICROCHIP=y +# CONFIG_WILC1000_SDIO is not set +# CONFIG_WILC1000_SPI is not set +CONFIG_WLAN_VENDOR_PURELIFI=y +# CONFIG_PLFXLC is not set +CONFIG_WLAN_VENDOR_RALINK=y +CONFIG_RT2X00=m +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT33XX=y +CONFIG_RT2800USB_RT35XX=y +CONFIG_RT2800USB_RT3573=y +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +CONFIG_RT2800USB_UNKNOWN=y +CONFIG_RT2800_LIB=m +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_RT2X00_LIB_LEDS=y +# CONFIG_RT2X00_DEBUG is not set +CONFIG_WLAN_VENDOR_REALTEK=y +CONFIG_RTL8187=m +CONFIG_RTL8187_LEDS=y +CONFIG_RTL_CARDS=m +CONFIG_RTL8192CU=m +# CONFIG_RTL8192DU is not set +CONFIG_RTLWIFI=m +CONFIG_RTLWIFI_USB=m +# CONFIG_RTLWIFI_DEBUG is not set +CONFIG_RTL8192C_COMMON=m +CONFIG_RTL8XXXU=m +# CONFIG_RTL8XXXU_UNTESTED is not set +CONFIG_RTW88=m +CONFIG_RTW88_CORE=m +CONFIG_RTW88_SDIO=m +CONFIG_RTW88_8723X=m +CONFIG_RTW88_8723D=m +# CONFIG_RTW88_8822BS is not set +# CONFIG_RTW88_8822BU is not set +# CONFIG_RTW88_8822CS is not set +# CONFIG_RTW88_8822CU is not set +CONFIG_RTW88_8723DS=m +# CONFIG_RTW88_8723CS is not set +# CONFIG_RTW88_8723DU is not set +# CONFIG_RTW88_8821CS is not set +# CONFIG_RTW88_8821CU is not set +# CONFIG_RTW88_DEBUG is not set +# CONFIG_RTW88_DEBUGFS is not set +CONFIG_RTW89=m +CONFIG_WLAN_VENDOR_RSI=y +# CONFIG_RSI_91X is not set +CONFIG_WLAN_VENDOR_SILABS=y +# CONFIG_WFX is not set +CONFIG_WLAN_VENDOR_ST=y +# CONFIG_CW1200 is not set +CONFIG_WLAN_VENDOR_TI=y +# CONFIG_WL1251 is not set +CONFIG_WL12XX=m +CONFIG_WL18XX=m +CONFIG_WLCORE=m +# CONFIG_WLCORE_SPI is not set +# CONFIG_WLCORE_SDIO is not set +# CONFIG_WLAN_VENDOR_ZYDAS is not set +CONFIG_WLAN_VENDOR_QUANTENNA=y +CONFIG_ESP8089=m +CONFIG_ESP8089_DEBUG_FS=y +# CONFIG_MAC80211_HWSIM is not set +# CONFIG_VIRT_WIFI is not set +# CONFIG_WAN is not set + +# +# Wireless WAN +# +# CONFIG_WWAN is not set +# end of Wireless WAN + +# CONFIG_NETDEVSIM is not set +CONFIG_NET_FAILOVER=y +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_LEDS=y +CONFIG_INPUT_FF_MEMLESS=y +CONFIG_INPUT_POLLDEV=y +# CONFIG_INPUT_SPARSEKMAP is not set +CONFIG_INPUT_MATRIXKMAP=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_JOYDEV=y +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ADC=y +# CONFIG_KEYBOARD_ADP5588 is not set +# CONFIG_KEYBOARD_ADP5589 is not set +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_QT1050 is not set +# CONFIG_KEYBOARD_QT1070 is not set +# CONFIG_KEYBOARD_QT2160 is not set +# CONFIG_KEYBOARD_DLINK_DIR685 is not set +# CONFIG_KEYBOARD_LKKBD is not set +CONFIG_KEYBOARD_GPIO=y +CONFIG_KEYBOARD_GPIO_POLLED=y +# CONFIG_KEYBOARD_TCA6416 is not set +# CONFIG_KEYBOARD_TCA8418 is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_LM8333 is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_MPR121 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_PINEPHONE is not set +# CONFIG_KEYBOARD_SAMSUNG is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_OMAP4 is not set +# CONFIG_KEYBOARD_TM2_TOUCHKEY is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_CAP11XX is not set +# CONFIG_KEYBOARD_BCM is not set +# CONFIG_KEYBOARD_CYPRESS_SF is not set +CONFIG_INPUT_MOUSE=y +# CONFIG_MOUSE_PS2 is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_APPLETOUCH is not set +# CONFIG_MOUSE_BCM5974 is not set +# CONFIG_MOUSE_CYAPA is not set +# CONFIG_MOUSE_ELAN_I2C is not set +# CONFIG_MOUSE_VSXXXAA is not set +CONFIG_MOUSE_GPIO=y +# CONFIG_MOUSE_SYNAPTICS_I2C is not set +# CONFIG_MOUSE_SYNAPTICS_USB is not set +CONFIG_INPUT_JOYSTICK=y +CONFIG_JOYSTICK_ANALOG=y +# CONFIG_JOYSTICK_A3D is not set +CONFIG_JOYSTICK_ADC=y +# CONFIG_JOYSTICK_ADI is not set +# CONFIG_JOYSTICK_COBRA is not set +# CONFIG_JOYSTICK_GF2K is not set +# CONFIG_JOYSTICK_GRIP is not set +# CONFIG_JOYSTICK_GRIP_MP is not set +# CONFIG_JOYSTICK_GUILLEMOT is not set +# CONFIG_JOYSTICK_INTERACT is not set +# CONFIG_JOYSTICK_SIDEWINDER is not set +# CONFIG_JOYSTICK_TMDC is not set +# CONFIG_JOYSTICK_IFORCE is not set +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TWIDJOY is not set +# CONFIG_JOYSTICK_ZHENHUA is not set +# CONFIG_JOYSTICK_AS5011 is not set +# CONFIG_JOYSTICK_JOYDUMP is not set +# CONFIG_JOYSTICK_XPAD is not set +# CONFIG_JOYSTICK_PSXPAD_SPI is not set +# CONFIG_JOYSTICK_PXRC is not set +# CONFIG_JOYSTICK_QWIIC is not set +# CONFIG_JOYSTICK_FSIA6B is not set +CONFIG_JOYSTICK_ODROIDGO2=y +CONFIG_JOYSTICK_ODROIDGO2_V11=y +CONFIG_JOYSTICK_ODROIDGO3=y +CONFIG_JOYSTICK_RGB20S=y +CONFIG_JOYSTICK_XU10=y +# CONFIG_JOYSTICK_GAMEFORCE_CHI is not set +# CONFIG_JOYSTICK_SENSEHAT is not set +# CONFIG_JOYSTICK_SEESAW is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_ATMEL_CAPTOUCH is not set +# CONFIG_INPUT_BMA150 is not set +# CONFIG_INPUT_E3X0_BUTTON is not set +# CONFIG_INPUT_MMA8450 is not set +# CONFIG_INPUT_GPIO_BEEPER is not set +CONFIG_INPUT_GPIO_DECODER=m +CONFIG_INPUT_GPIO_VIBRA=m +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_KXTJ9 is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_INPUT_CM109 is not set +# CONFIG_INPUT_REGULATOR_HAPTIC is not set +CONFIG_INPUT_UINPUT=y +# CONFIG_INPUT_PCF8574 is not set +# CONFIG_INPUT_PWM_BEEPER is not set +CONFIG_INPUT_PWM_VIBRA=y +CONFIG_INPUT_RK805_PWRKEY=y +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +# CONFIG_INPUT_DA7280_HAPTICS is not set +# CONFIG_INPUT_ADXL34X is not set +# CONFIG_INPUT_IMS_PCU is not set +# CONFIG_INPUT_IQS269A is not set +# CONFIG_INPUT_IQS626A is not set +# CONFIG_INPUT_IQS7222 is not set +# CONFIG_INPUT_CMA3000 is not set +# CONFIG_INPUT_DRV260X_HAPTICS is not set +# CONFIG_INPUT_DRV2665_HAPTICS is not set +# CONFIG_INPUT_DRV2667_HAPTICS is not set +CONFIG_RMI4_CORE=m +# CONFIG_RMI4_I2C is not set +# CONFIG_RMI4_SPI is not set +# CONFIG_RMI4_SMB is not set +CONFIG_RMI4_F03=y +CONFIG_RMI4_F03_SERIO=m +CONFIG_RMI4_2D_SENSOR=y +CONFIG_RMI4_F11=y +CONFIG_RMI4_F12=y +CONFIG_RMI4_F30=y +# CONFIG_RMI4_F34 is not set +# CONFIG_RMI4_F3A is not set +# CONFIG_RMI4_F54 is not set +# CONFIG_RMI4_F55 is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=m +# CONFIG_SERIO_AMBAKMI is not set +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set +# CONFIG_SERIO_PS2MULT is not set +# CONFIG_SERIO_ARC_PS2 is not set +# CONFIG_SERIO_APBPS2 is not set +# CONFIG_SERIO_GPIO_PS2 is not set +# CONFIG_USERIO is not set +CONFIG_GAMEPORT=y +# end of Hardware I/O ports +# end of Input device support + +# +# Character devices +# +CONFIG_TTY=y +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_CONSOLE_SLEEP=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set +CONFIG_LEGACY_TIOCSTI=y +CONFIG_LDISC_AUTOLOAD=y + +# +# Serial drivers +# +CONFIG_SERIAL_EARLYCON=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y +# CONFIG_SERIAL_8250_16550A_VARIANTS is not set +# CONFIG_SERIAL_8250_FINTEK is not set +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_DMA=y +CONFIG_SERIAL_8250_NR_UARTS=5 +CONFIG_SERIAL_8250_RUNTIME_UARTS=5 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_RSA is not set +CONFIG_SERIAL_8250_DWLIB=y +CONFIG_SERIAL_8250_FSL=y +CONFIG_SERIAL_8250_DW=y +# CONFIG_SERIAL_8250_RT288X is not set +CONFIG_SERIAL_OF_PLATFORM=y + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +# CONFIG_SERIAL_AMBA_PL011 is not set +# CONFIG_SERIAL_EARLYCON_SEMIHOST is not set +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_MAX310X is not set +# CONFIG_SERIAL_UARTLITE is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_SIFIVE is not set +# CONFIG_SERIAL_SCCNXP is not set +# CONFIG_SERIAL_SC16IS7XX is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +CONFIG_SERIAL_XILINX_PS_UART=y +CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y +# CONFIG_SERIAL_ARC is not set +# CONFIG_SERIAL_FSL_LPUART is not set +# CONFIG_SERIAL_FSL_LINFLEXUART is not set +# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set +# CONFIG_SERIAL_SPRD is not set +# end of Serial drivers + +CONFIG_SERIAL_MCTRL_GPIO=y +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_N_GSM is not set +# CONFIG_NULL_TTY is not set +# CONFIG_HVC_DCC is not set +CONFIG_SERIAL_DEV_BUS=y +CONFIG_SERIAL_DEV_CTRL_TTYPORT=y +# CONFIG_TTY_PRINTK is not set +# CONFIG_VIRTIO_CONSOLE is not set +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=m +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +# CONFIG_HW_RANDOM_BA431 is not set +CONFIG_HW_RANDOM_OPTEE=m +# CONFIG_HW_RANDOM_CCTRNG is not set +# CONFIG_HW_RANDOM_XIPHERA is not set +CONFIG_HW_RANDOM_ARM_SMCCC_TRNG=m +CONFIG_HW_RANDOM_ROCKCHIP=m +CONFIG_DEVMEM=y +CONFIG_DEVPORT=y +# CONFIG_TCG_TPM is not set +# CONFIG_XILLYBUS is not set +# CONFIG_XILLYUSB is not set +# end of Character devices + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MUX=y + +# +# Multiplexer I2C Chip support +# +# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set +# CONFIG_I2C_MUX_GPIO is not set +# CONFIG_I2C_MUX_GPMUX is not set +# CONFIG_I2C_MUX_LTC4306 is not set +# CONFIG_I2C_MUX_PCA9541 is not set +# CONFIG_I2C_MUX_PCA954x is not set +# CONFIG_I2C_MUX_PINCTRL is not set +# CONFIG_I2C_MUX_REG is not set +# CONFIG_I2C_DEMUX_PINCTRL is not set +# CONFIG_I2C_MUX_MLXCPLD is not set +# end of Multiplexer I2C Chip support + +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=m + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_CADENCE is not set +# CONFIG_I2C_CBUS_GPIO is not set +CONFIG_I2C_DESIGNWARE_CORE=y +# CONFIG_I2C_DESIGNWARE_SLAVE is not set +CONFIG_I2C_DESIGNWARE_PLATFORM=y +# CONFIG_I2C_EMEV2 is not set +CONFIG_I2C_GPIO=m +# CONFIG_I2C_GPIO_FAULT_INJECTOR is not set +# CONFIG_I2C_HISI is not set +# CONFIG_I2C_NOMADIK is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PCA_PLATFORM is not set +CONFIG_I2C_RK3X=y +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_DIOLAN_U2C is not set +# CONFIG_I2C_CP2615 is not set +# CONFIG_I2C_ROBOTFUZZ_OSIF is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_VIRTIO is not set +# end of I2C Hardware Bus support + +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_SLAVE is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# end of I2C support + +# CONFIG_I3C is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y +CONFIG_SPI_MEM=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_ALTERA is not set +# CONFIG_SPI_AXI_SPI_ENGINE is not set +CONFIG_SPI_BITBANG=y +# CONFIG_SPI_CADENCE is not set +# CONFIG_SPI_CADENCE_QUADSPI is not set +# CONFIG_SPI_CADENCE_XSPI is not set +# CONFIG_SPI_CH341 is not set +# CONFIG_SPI_DESIGNWARE is not set +CONFIG_SPI_GPIO=y +# CONFIG_SPI_FSL_SPI is not set +# CONFIG_SPI_MICROCHIP_CORE is not set +# CONFIG_SPI_MICROCHIP_CORE_QSPI is not set +# CONFIG_SPI_OC_TINY is not set +CONFIG_SPI_PL022=y +CONFIG_SPI_ROCKCHIP=y +CONFIG_SPI_ROCKCHIP_SFC=y +# CONFIG_SPI_SC18IS602 is not set +# CONFIG_SPI_SIFIVE is not set +# CONFIG_SPI_SN_F_OSPI is not set +# CONFIG_SPI_MXIC is not set +# CONFIG_SPI_XCOMM is not set +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_ZYNQMP_GQSPI is not set +# CONFIG_SPI_AMD is not set + +# +# SPI Multiplexer support +# +# CONFIG_SPI_MUX is not set + +# +# SPI Protocol Masters +# +CONFIG_SPI_SPIDEV=m +# CONFIG_SPI_LOOPBACK_TEST is not set +# CONFIG_SPI_TLE62X0 is not set +# CONFIG_SPI_SLAVE is not set +CONFIG_SPI_DYNAMIC=y +CONFIG_SPMI=y +# CONFIG_SPMI_HISI3670 is not set +# CONFIG_HSI is not set +CONFIG_PPS=y +# CONFIG_PPS_DEBUG is not set + +# +# PPS clients support +# +# CONFIG_PPS_CLIENT_KTIMER is not set +# CONFIG_PPS_CLIENT_LDISC is not set +# CONFIG_PPS_CLIENT_GPIO is not set + +# +# PPS generators support +# + +# +# PTP clock support +# +CONFIG_PTP_1588_CLOCK=y +CONFIG_PTP_1588_CLOCK_OPTIONAL=y + +# +# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. +# +CONFIG_PTP_1588_CLOCK_KVM=y +# CONFIG_PTP_1588_CLOCK_IDT82P33 is not set +# CONFIG_PTP_1588_CLOCK_IDTCM is not set +# CONFIG_PTP_1588_CLOCK_FC3W is not set +# CONFIG_PTP_1588_CLOCK_MOCK is not set +# end of PTP clock support + +CONFIG_PINCTRL=y +CONFIG_GENERIC_PINCTRL_GROUPS=y +CONFIG_PINMUX=y +CONFIG_GENERIC_PINMUX_FUNCTIONS=y +CONFIG_PINCONF=y +CONFIG_GENERIC_PINCONF=y +# CONFIG_DEBUG_PINCTRL is not set +# CONFIG_PINCTRL_AW9523 is not set +# CONFIG_PINCTRL_CY8C95X0 is not set +CONFIG_PINCTRL_MAX77620=y +# CONFIG_PINCTRL_MCP23S08 is not set +# CONFIG_PINCTRL_MICROCHIP_SGPIO is not set +# CONFIG_PINCTRL_OCELOT is not set +CONFIG_PINCTRL_RK805=y +CONFIG_PINCTRL_ROCKCHIP=y +# CONFIG_PINCTRL_SCMI is not set +CONFIG_PINCTRL_SINGLE=y +# CONFIG_PINCTRL_STMFX is not set +# CONFIG_PINCTRL_SX150X is not set +# CONFIG_PINCTRL_IMX_SCMI is not set + +# +# Renesas pinctrl drivers +# +# end of Renesas pinctrl drivers + +CONFIG_GPIOLIB=y +CONFIG_GPIOLIB_FASTPATH_LIMIT=512 +CONFIG_OF_GPIO=y +CONFIG_GPIOLIB_IRQCHIP=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_CDEV=y +CONFIG_GPIO_CDEV_V1=y +CONFIG_GPIO_GENERIC=y + +# +# Memory mapped GPIO drivers +# +# CONFIG_GPIO_74XX_MMIO is not set +# CONFIG_GPIO_ALTERA is not set +# CONFIG_GPIO_CADENCE is not set +CONFIG_GPIO_DWAPB=y +# CONFIG_GPIO_FTGPIO010 is not set +CONFIG_GPIO_GENERIC_PLATFORM=y +# CONFIG_GPIO_GRGPIO is not set +# CONFIG_GPIO_HISI is not set +# CONFIG_GPIO_HLWD is not set +# CONFIG_GPIO_LOGICVC is not set +# CONFIG_GPIO_MB86S7X is not set +CONFIG_GPIO_PL061=y +CONFIG_GPIO_ROCKCHIP=y +# CONFIG_GPIO_SIFIVE is not set +CONFIG_GPIO_SYSCON=y +# CONFIG_GPIO_XGENE is not set +# CONFIG_GPIO_XILINX is not set +# CONFIG_GPIO_AMD_FCH is not set +# end of Memory mapped GPIO drivers + +# +# I2C GPIO expanders +# +# CONFIG_GPIO_ADNP is not set +# CONFIG_GPIO_FXL6408 is not set +# CONFIG_GPIO_DS4520 is not set +# CONFIG_GPIO_GW_PLD is not set +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +CONFIG_GPIO_PCA953X=y +CONFIG_GPIO_PCA953X_IRQ=y +# CONFIG_GPIO_PCA9570 is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_TPIC2810 is not set +# end of I2C GPIO expanders + +# +# MFD GPIO expanders +# +CONFIG_GPIO_MAX77620=y +# end of MFD GPIO expanders + +# +# SPI GPIO expanders +# +# CONFIG_GPIO_74X164 is not set +# CONFIG_GPIO_MAX3191X is not set +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MC33880 is not set +# CONFIG_GPIO_PISOSR is not set +# CONFIG_GPIO_XRA1403 is not set +# end of SPI GPIO expanders + +# +# USB GPIO expanders +# +# end of USB GPIO expanders + +# +# Virtual GPIO drivers +# +# CONFIG_GPIO_AGGREGATOR is not set +# CONFIG_GPIO_LATCH is not set +# CONFIG_GPIO_MOCKUP is not set +# CONFIG_GPIO_SIM is not set +# end of Virtual GPIO drivers + +# +# GPIO Debugging utilities +# +# CONFIG_GPIO_SLOPPY_LOGIC_ANALYZER is not set +# CONFIG_GPIO_VIRTUSER is not set +# end of GPIO Debugging utilities + +# CONFIG_W1 is not set +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_GPIO=y +CONFIG_POWER_RESET_GPIO_RESTART=y +# CONFIG_POWER_RESET_LTC2952 is not set +# CONFIG_POWER_RESET_REGULATOR is not set +# CONFIG_POWER_RESET_RESTART is not set +# CONFIG_POWER_RESET_XGENE is not set +CONFIG_POWER_RESET_SYSCON=y +CONFIG_POWER_RESET_SYSCON_POWEROFF=y +CONFIG_REBOOT_MODE=y +CONFIG_SYSCON_REBOOT_MODE=y +# CONFIG_NVMEM_REBOOT_MODE is not set +# CONFIG_POWER_SEQUENCING is not set +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +CONFIG_POWER_SUPPLY_HWMON=y +# CONFIG_GENERIC_ADC_BATTERY is not set +# CONFIG_IP5XXX_POWER is not set +# CONFIG_TEST_POWER is not set +# CONFIG_CHARGER_ADP5061 is not set +CONFIG_BATTERY_CW2015=y +# CONFIG_BATTERY_DS2780 is not set +# CONFIG_BATTERY_DS2781 is not set +# CONFIG_BATTERY_DS2782 is not set +# CONFIG_BATTERY_SAMSUNG_SDI is not set +# CONFIG_BATTERY_SBS is not set +# CONFIG_CHARGER_SBS is not set +# CONFIG_MANAGER_SBS is not set +# CONFIG_BATTERY_BQ27XXX is not set +# CONFIG_BATTERY_MAX17040 is not set +# CONFIG_BATTERY_MAX17042 is not set +# CONFIG_BATTERY_MAX1720X is not set +# CONFIG_CHARGER_ISP1704 is not set +# CONFIG_CHARGER_MAX8903 is not set +# CONFIG_CHARGER_LP8727 is not set +CONFIG_CHARGER_GPIO=m +# CONFIG_CHARGER_MANAGER is not set +# CONFIG_CHARGER_LT3651 is not set +# CONFIG_CHARGER_LTC4162L is not set +# CONFIG_CHARGER_DETECTOR_MAX14656 is not set +# CONFIG_CHARGER_MAX77976 is not set +# CONFIG_CHARGER_BQ2415X is not set +# CONFIG_CHARGER_BQ24190 is not set +# CONFIG_CHARGER_BQ24257 is not set +# CONFIG_CHARGER_BQ24735 is not set +# CONFIG_CHARGER_BQ2515X is not set +# CONFIG_CHARGER_BQ25890 is not set +# CONFIG_CHARGER_BQ25980 is not set +# CONFIG_CHARGER_BQ256XX is not set +CONFIG_CHARGER_RK817=y +# CONFIG_CHARGER_SMB347 is not set +# CONFIG_BATTERY_GAUGE_LTC2941 is not set +# CONFIG_BATTERY_GOLDFISH is not set +# CONFIG_BATTERY_RT5033 is not set +# CONFIG_CHARGER_RT9455 is not set +# CONFIG_CHARGER_RT9467 is not set +# CONFIG_CHARGER_RT9471 is not set +# CONFIG_CHARGER_UCS1002 is not set +# CONFIG_CHARGER_BD99954 is not set +# CONFIG_BATTERY_UG3105 is not set +# CONFIG_FUEL_GAUGE_MM8013 is not set +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Native drivers +# +# CONFIG_SENSORS_AD7314 is not set +# CONFIG_SENSORS_AD7414 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM1177 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7310 is not set +# CONFIG_SENSORS_ADT7410 is not set +# CONFIG_SENSORS_ADT7411 is not set +# CONFIG_SENSORS_ADT7462 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_AHT10 is not set +# CONFIG_SENSORS_AQUACOMPUTER_D5NEXT is not set +# CONFIG_SENSORS_AS370 is not set +# CONFIG_SENSORS_ASC7621 is not set +# CONFIG_SENSORS_ASUS_ROG_RYUJIN is not set +# CONFIG_SENSORS_AXI_FAN_CONTROL is not set +# CONFIG_SENSORS_ARM_SCMI is not set +# CONFIG_SENSORS_ARM_SCPI is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_CHIPCAP2 is not set +# CONFIG_SENSORS_CORSAIR_CPRO is not set +# CONFIG_SENSORS_CORSAIR_PSU is not set +# CONFIG_SENSORS_DS620 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_FTSTEUTATES is not set +# CONFIG_SENSORS_GIGABYTE_WATERFORCE is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_G760A is not set +# CONFIG_SENSORS_G762 is not set +# CONFIG_SENSORS_GPIO_FAN is not set +# CONFIG_SENSORS_HIH6130 is not set +# CONFIG_SENSORS_HS3001 is not set +# CONFIG_SENSORS_IIO_HWMON is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_JC42 is not set +# CONFIG_SENSORS_POWERZ is not set +# CONFIG_SENSORS_POWR1220 is not set +# CONFIG_SENSORS_LINEAGE is not set +# CONFIG_SENSORS_LTC2945 is not set +# CONFIG_SENSORS_LTC2947_I2C is not set +# CONFIG_SENSORS_LTC2947_SPI is not set +# CONFIG_SENSORS_LTC2990 is not set +# CONFIG_SENSORS_LTC2991 is not set +# CONFIG_SENSORS_LTC2992 is not set +# CONFIG_SENSORS_LTC4151 is not set +# CONFIG_SENSORS_LTC4215 is not set +# CONFIG_SENSORS_LTC4222 is not set +# CONFIG_SENSORS_LTC4245 is not set +# CONFIG_SENSORS_LTC4260 is not set +# CONFIG_SENSORS_LTC4261 is not set +# CONFIG_SENSORS_LTC4282 is not set +# CONFIG_SENSORS_MAX1111 is not set +# CONFIG_SENSORS_MAX127 is not set +# CONFIG_SENSORS_MAX16065 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX1668 is not set +# CONFIG_SENSORS_MAX197 is not set +# CONFIG_SENSORS_MAX31722 is not set +# CONFIG_SENSORS_MAX31730 is not set +# CONFIG_SENSORS_MAX31760 is not set +# CONFIG_MAX31827 is not set +# CONFIG_SENSORS_MAX6620 is not set +# CONFIG_SENSORS_MAX6621 is not set +# CONFIG_SENSORS_MAX6639 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_MAX6697 is not set +# CONFIG_SENSORS_MAX31790 is not set +# CONFIG_SENSORS_MC34VR500 is not set +# CONFIG_SENSORS_MCP3021 is not set +# CONFIG_SENSORS_TC654 is not set +# CONFIG_SENSORS_TPS23861 is not set +# CONFIG_SENSORS_MR75203 is not set +# CONFIG_SENSORS_ADCXX is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_LM73 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_LM95234 is not set +# CONFIG_SENSORS_LM95241 is not set +# CONFIG_SENSORS_LM95245 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_NTC_THERMISTOR is not set +# CONFIG_SENSORS_NCT6683 is not set +# CONFIG_SENSORS_NCT6775 is not set +# CONFIG_SENSORS_NCT6775_I2C is not set +# CONFIG_SENSORS_NCT7802 is not set +# CONFIG_SENSORS_NCT7904 is not set +# CONFIG_SENSORS_NPCM7XX is not set +# CONFIG_SENSORS_NZXT_KRAKEN2 is not set +# CONFIG_SENSORS_NZXT_KRAKEN3 is not set +# CONFIG_SENSORS_NZXT_SMART2 is not set +# CONFIG_SENSORS_OCC_P8_I2C is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_PMBUS is not set +# CONFIG_SENSORS_PT5161L is not set +# CONFIG_SENSORS_PWM_FAN is not set +# CONFIG_SENSORS_SBTSI is not set +# CONFIG_SENSORS_SBRMI is not set +# CONFIG_SENSORS_SHT15 is not set +# CONFIG_SENSORS_SHT21 is not set +# CONFIG_SENSORS_SHT3x is not set +# CONFIG_SENSORS_SHT4x is not set +# CONFIG_SENSORS_SHTC1 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_EMC1403 is not set +# CONFIG_SENSORS_EMC2103 is not set +# CONFIG_SENSORS_EMC2305 is not set +# CONFIG_SENSORS_EMC6W201 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SCH5627 is not set +# CONFIG_SENSORS_SCH5636 is not set +# CONFIG_SENSORS_STTS751 is not set +# CONFIG_SENSORS_ADC128D818 is not set +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_ADS7871 is not set +# CONFIG_SENSORS_AMC6821 is not set +# CONFIG_SENSORS_INA209 is not set +# CONFIG_SENSORS_INA2XX is not set +# CONFIG_SENSORS_INA238 is not set +# CONFIG_SENSORS_INA3221 is not set +# CONFIG_SENSORS_SPD5118 is not set +# CONFIG_SENSORS_TC74 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_TMP102 is not set +# CONFIG_SENSORS_TMP103 is not set +# CONFIG_SENSORS_TMP108 is not set +# CONFIG_SENSORS_TMP401 is not set +# CONFIG_SENSORS_TMP421 is not set +# CONFIG_SENSORS_TMP464 is not set +# CONFIG_SENSORS_TMP513 is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83773G is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83795 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +CONFIG_THERMAL=y +# CONFIG_THERMAL_NETLINK is not set +# CONFIG_THERMAL_STATISTICS is not set +# CONFIG_THERMAL_DEBUGFS is not set +# CONFIG_THERMAL_CORE_TESTING is not set +CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 +CONFIG_THERMAL_HWMON=y +CONFIG_THERMAL_OF=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set +# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set +# CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set +CONFIG_THERMAL_GOV_FAIR_SHARE=y +CONFIG_THERMAL_GOV_STEP_WISE=y +# CONFIG_THERMAL_GOV_BANG_BANG is not set +# CONFIG_THERMAL_GOV_USER_SPACE is not set +CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y +CONFIG_CPU_THERMAL=y +CONFIG_CPU_FREQ_THERMAL=y +CONFIG_DEVFREQ_THERMAL=y +# CONFIG_THERMAL_EMULATION is not set +# CONFIG_THERMAL_MMIO is not set +# CONFIG_MAX77620_THERMAL is not set +CONFIG_ROCKCHIP_THERMAL=y +# CONFIG_GENERIC_ADC_THERMAL is not set +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_CORE=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y +CONFIG_WATCHDOG_OPEN_TIMEOUT=0 +# CONFIG_WATCHDOG_SYSFS is not set +# CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT is not set + +# +# Watchdog Pretimeout Governors +# +# CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_GPIO_WATCHDOG is not set +# CONFIG_XILINX_WATCHDOG is not set +# CONFIG_XILINX_WINDOW_WATCHDOG is not set +# CONFIG_ZIIRAVE_WATCHDOG is not set +# CONFIG_ARM_SP805_WATCHDOG is not set +# CONFIG_ARM_SBSA_WATCHDOG is not set +# CONFIG_CADENCE_WATCHDOG is not set +CONFIG_DW_WATCHDOG=y +# CONFIG_MAX63XX_WATCHDOG is not set +# CONFIG_MAX77620_WATCHDOG is not set +# CONFIG_ARM_SMC_WATCHDOG is not set +# CONFIG_MEN_A21_WDT is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set +CONFIG_BCMA_POSSIBLE=y +# CONFIG_BCMA is not set + +# +# Multifunction device drivers +# +CONFIG_MFD_CORE=y +# CONFIG_MFD_ADP5585 is not set +# CONFIG_MFD_ACT8945A is not set +# CONFIG_MFD_AS3711 is not set +# CONFIG_MFD_SMPRO is not set +# CONFIG_MFD_AS3722 is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_AAT2870_CORE is not set +# CONFIG_MFD_ATMEL_FLEXCOM is not set +# CONFIG_MFD_ATMEL_HLCDC is not set +# CONFIG_MFD_BCM590XX is not set +# CONFIG_MFD_BD9571MWV is not set +# CONFIG_MFD_AXP20X_I2C is not set +# CONFIG_MFD_CS42L43_I2C is not set +# CONFIG_MFD_MADERA is not set +# CONFIG_MFD_MAX5970 is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_DA9052_SPI is not set +# CONFIG_MFD_DA9052_I2C is not set +# CONFIG_MFD_DA9055 is not set +# CONFIG_MFD_DA9062 is not set +# CONFIG_MFD_DA9063 is not set +# CONFIG_MFD_DA9150 is not set +# CONFIG_MFD_DLN2 is not set +# CONFIG_MFD_GATEWORKS_GSC is not set +# CONFIG_MFD_MC13XXX_SPI is not set +# CONFIG_MFD_MC13XXX_I2C is not set +# CONFIG_MFD_MP2629 is not set +# CONFIG_MFD_HI6421_PMIC is not set +# CONFIG_MFD_HI6421_SPMI is not set +# CONFIG_MFD_IQS62X is not set +# CONFIG_MFD_KEMPLD is not set +# CONFIG_MFD_88PM800 is not set +# CONFIG_MFD_88PM805 is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_88PM886_PMIC is not set +# CONFIG_MFD_MAX14577 is not set +# CONFIG_MFD_MAX77541 is not set +CONFIG_MFD_MAX77620=y +# CONFIG_MFD_MAX77650 is not set +# CONFIG_MFD_MAX77686 is not set +# CONFIG_MFD_MAX77693 is not set +# CONFIG_MFD_MAX77714 is not set +# CONFIG_MFD_MAX77843 is not set +# CONFIG_MFD_MAX8907 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_MAX8997 is not set +# CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_MT6360 is not set +# CONFIG_MFD_MT6370 is not set +# CONFIG_MFD_MT6397 is not set +# CONFIG_MFD_MENF21BMC is not set +# CONFIG_MFD_OCELOT is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MFD_CPCAP is not set +# CONFIG_MFD_VIPERBOARD is not set +# CONFIG_MFD_NTXEC is not set +# CONFIG_MFD_RETU is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_SY7636A is not set +# CONFIG_MFD_RT4831 is not set +# CONFIG_MFD_RT5033 is not set +# CONFIG_MFD_RT5120 is not set +# CONFIG_MFD_RC5T583 is not set +CONFIG_MFD_RK8XX=y +CONFIG_MFD_RK8XX_I2C=y +# CONFIG_MFD_RK8XX_SPI is not set +# CONFIG_MFD_RN5T618 is not set +CONFIG_MFD_SEC_CORE=y +# CONFIG_MFD_SI476X_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SKY81452 is not set +# CONFIG_MFD_STMPE is not set +CONFIG_MFD_SYSCON=y +# CONFIG_MFD_LP3943 is not set +# CONFIG_MFD_LP8788 is not set +# CONFIG_MFD_TI_LMU is not set +# CONFIG_MFD_PALMAS is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS65086 is not set +# CONFIG_MFD_TPS65090 is not set +# CONFIG_MFD_TPS65217 is not set +# CONFIG_MFD_TI_LP873X is not set +# CONFIG_MFD_TI_LP87565 is not set +# CONFIG_MFD_TPS65218 is not set +# CONFIG_MFD_TPS65219 is not set +# CONFIG_MFD_TPS6586X is not set +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS65912_SPI is not set +# CONFIG_MFD_TPS6594_I2C is not set +# CONFIG_MFD_TPS6594_SPI is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_TWL6040_CORE is not set +CONFIG_MFD_WL1273_CORE=m +# CONFIG_MFD_LM3533 is not set +# CONFIG_MFD_TC3589X is not set +# CONFIG_MFD_TQMX86 is not set +# CONFIG_MFD_LOCHNAGAR is not set +# CONFIG_MFD_ARIZONA_I2C is not set +# CONFIG_MFD_ARIZONA_SPI is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X_I2C is not set +# CONFIG_MFD_WM831X_SPI is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_ROHM_BD718XX is not set +# CONFIG_MFD_ROHM_BD71828 is not set +# CONFIG_MFD_ROHM_BD957XMUF is not set +# CONFIG_MFD_ROHM_BD96801 is not set +# CONFIG_MFD_STPMIC1 is not set +# CONFIG_MFD_STMFX is not set +# CONFIG_MFD_ATC260X_I2C is not set +# CONFIG_MFD_KHADAS_MCU is not set +# CONFIG_MFD_QCOM_PM8008 is not set +# CONFIG_MFD_CS40L50_I2C is not set +# CONFIG_MFD_CS40L50_SPI is not set +# CONFIG_RAVE_SP_CORE is not set +# CONFIG_MFD_INTEL_M10_BMC_SPI is not set +# CONFIG_MFD_RSMU_I2C is not set +# CONFIG_MFD_RSMU_SPI is not set +# end of Multifunction device drivers + +CONFIG_REGULATOR=y +CONFIG_REGULATOR_DEBUG=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_VIRTUAL_CONSUMER=y +CONFIG_REGULATOR_USERSPACE_CONSUMER=y +# CONFIG_REGULATOR_NETLINK_EVENTS is not set +# CONFIG_REGULATOR_88PG86X is not set +# CONFIG_REGULATOR_ACT8865 is not set +# CONFIG_REGULATOR_AD5398 is not set +# CONFIG_REGULATOR_ARM_SCMI is not set +# CONFIG_REGULATOR_AW37503 is not set +# CONFIG_REGULATOR_DA9121 is not set +# CONFIG_REGULATOR_DA9210 is not set +# CONFIG_REGULATOR_DA9211 is not set +# CONFIG_REGULATOR_FAN53555 is not set +# CONFIG_REGULATOR_FAN53880 is not set +CONFIG_REGULATOR_GPIO=y +# CONFIG_REGULATOR_ISL9305 is not set +# CONFIG_REGULATOR_ISL6271A is not set +# CONFIG_REGULATOR_LP3971 is not set +# CONFIG_REGULATOR_LP3972 is not set +# CONFIG_REGULATOR_LP872X is not set +# CONFIG_REGULATOR_LP8755 is not set +# CONFIG_REGULATOR_LTC3589 is not set +# CONFIG_REGULATOR_LTC3676 is not set +# CONFIG_REGULATOR_MAX1586 is not set +# CONFIG_REGULATOR_MAX77503 is not set +# CONFIG_REGULATOR_MAX77620 is not set +# CONFIG_REGULATOR_MAX77857 is not set +# CONFIG_REGULATOR_MAX8649 is not set +# CONFIG_REGULATOR_MAX8660 is not set +# CONFIG_REGULATOR_MAX8893 is not set +# CONFIG_REGULATOR_MAX8952 is not set +# CONFIG_REGULATOR_MAX8973 is not set +# CONFIG_REGULATOR_MAX20086 is not set +# CONFIG_REGULATOR_MAX20411 is not set +# CONFIG_REGULATOR_MAX77826 is not set +# CONFIG_REGULATOR_MCP16502 is not set +# CONFIG_REGULATOR_MP5416 is not set +# CONFIG_REGULATOR_MP8859 is not set +# CONFIG_REGULATOR_MP886X is not set +# CONFIG_REGULATOR_MPQ7920 is not set +# CONFIG_REGULATOR_MT6311 is not set +# CONFIG_REGULATOR_MT6315 is not set +# CONFIG_REGULATOR_PCA9450 is not set +# CONFIG_REGULATOR_PF8X00 is not set +# CONFIG_REGULATOR_PFUZE100 is not set +# CONFIG_REGULATOR_PV88060 is not set +# CONFIG_REGULATOR_PV88080 is not set +# CONFIG_REGULATOR_PV88090 is not set +CONFIG_REGULATOR_PWM=y +# CONFIG_REGULATOR_QCOM_SPMI is not set +# CONFIG_REGULATOR_QCOM_USB_VBUS is not set +# CONFIG_REGULATOR_RAA215300 is not set +# CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY is not set +CONFIG_REGULATOR_RK808=y +# CONFIG_REGULATOR_RT4801 is not set +# CONFIG_REGULATOR_RT4803 is not set +# CONFIG_REGULATOR_RT5190A is not set +# CONFIG_REGULATOR_RT5739 is not set +# CONFIG_REGULATOR_RT5759 is not set +# CONFIG_REGULATOR_RT6160 is not set +# CONFIG_REGULATOR_RT6190 is not set +# CONFIG_REGULATOR_RT6245 is not set +# CONFIG_REGULATOR_RTQ2134 is not set +# CONFIG_REGULATOR_RTMV20 is not set +# CONFIG_REGULATOR_RTQ6752 is not set +# CONFIG_REGULATOR_RTQ2208 is not set +# CONFIG_REGULATOR_S2MPA01 is not set +# CONFIG_REGULATOR_S2MPS11 is not set +# CONFIG_REGULATOR_S5M8767 is not set +# CONFIG_REGULATOR_SLG51000 is not set +# CONFIG_REGULATOR_SY8106A is not set +# CONFIG_REGULATOR_SY8824X is not set +# CONFIG_REGULATOR_SY8827N is not set +# CONFIG_REGULATOR_TPS51632 is not set +# CONFIG_REGULATOR_TPS62360 is not set +# CONFIG_REGULATOR_TPS6286X is not set +# CONFIG_REGULATOR_TPS6287X is not set +# CONFIG_REGULATOR_TPS65023 is not set +# CONFIG_REGULATOR_TPS6507X is not set +# CONFIG_REGULATOR_TPS65132 is not set +# CONFIG_REGULATOR_TPS6524X is not set +# CONFIG_REGULATOR_VCTRL is not set +# CONFIG_REGULATOR_QCOM_LABIBB is not set +# CONFIG_RC_CORE is not set +CONFIG_CEC_CORE=y +CONFIG_CEC_NOTIFIER=y + +# +# CEC support +# +# CONFIG_MEDIA_CEC_SUPPORT is not set +# end of CEC support + +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_SUPPORT_FILTER=y +# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set + +# +# Media device types +# +# CONFIG_MEDIA_CAMERA_SUPPORT is not set +# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set +# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set +# CONFIG_MEDIA_RADIO_SUPPORT is not set +# CONFIG_MEDIA_SDR_SUPPORT is not set +CONFIG_MEDIA_PLATFORM_SUPPORT=y +# CONFIG_MEDIA_TEST_SUPPORT is not set +# end of Media device types + +CONFIG_VIDEO_DEV=y +CONFIG_MEDIA_CONTROLLER=y + +# +# Video4Linux options +# +CONFIG_VIDEO_V4L2_I2C=y +CONFIG_VIDEO_V4L2_SUBDEV_API=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_V4L2_JPEG_HELPER=m +CONFIG_V4L2_H264=m +CONFIG_V4L2_VP9=m +CONFIG_V4L2_MEM2MEM_DEV=y +CONFIG_V4L2_FLASH_LED_CLASS=m +CONFIG_V4L2_ASYNC=m +# end of Video4Linux options + +# +# Media controller options +# +# end of Media controller options + +# +# Media drivers +# + +# +# Drivers filtered as selected at 'Filter media drivers' +# + +# +# Media drivers +# +CONFIG_MEDIA_USB_SUPPORT=y +CONFIG_MEDIA_PLATFORM_DRIVERS=y +# CONFIG_V4L_PLATFORM_DRIVERS is not set +CONFIG_V4L_MEM2MEM_DRIVERS=y +# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set + +# +# Allegro DVT media platform drivers +# + +# +# Amlogic media platform drivers +# + +# +# Amphion drivers +# + +# +# Aspeed media platform drivers +# + +# +# Atmel media platform drivers +# + +# +# Cadence media platform drivers +# +# CONFIG_VIDEO_CADENCE_CSI2RX is not set +# CONFIG_VIDEO_CADENCE_CSI2TX is not set + +# +# Chips&Media media platform drivers +# + +# +# Intel media platform drivers +# + +# +# Marvell media platform drivers +# + +# +# Mediatek media platform drivers +# + +# +# Microchip Technology, Inc. media platform drivers +# + +# +# Nuvoton media platform drivers +# + +# +# NVidia media platform drivers +# + +# +# NXP media platform drivers +# + +# +# Qualcomm media platform drivers +# + +# +# Raspberry Pi media platform drivers +# + +# +# Renesas media platform drivers +# + +# +# Rockchip media platform drivers +# +CONFIG_VIDEO_ROCKCHIP_RGA=y + +# +# Samsung media platform drivers +# + +# +# STMicroelectronics media platform drivers +# + +# +# Sunxi media platform drivers +# + +# +# Texas Instruments drivers +# + +# +# Verisilicon media platform drivers +# +CONFIG_VIDEO_HANTRO=m +# CONFIG_VIDEO_HANTRO_HEVC_RFC is not set +CONFIG_VIDEO_HANTRO_ROCKCHIP=y + +# +# VIA media platform drivers +# + +# +# Xilinx media platform drivers +# +CONFIG_VIDEOBUF2_CORE=y +CONFIG_VIDEOBUF2_V4L2=y +CONFIG_VIDEOBUF2_MEMOPS=y +CONFIG_VIDEOBUF2_DMA_CONTIG=m +CONFIG_VIDEOBUF2_VMALLOC=m +CONFIG_VIDEOBUF2_DMA_SG=y +# end of Media drivers + +# +# Media ancillary drivers +# + +# +# Audio decoders, processors and mixers +# +# CONFIG_VIDEO_CS3308 is not set +# CONFIG_VIDEO_CS5345 is not set +# CONFIG_VIDEO_CS53L32A is not set +# CONFIG_VIDEO_MSP3400 is not set +# CONFIG_VIDEO_SONY_BTF_MPX is not set +# CONFIG_VIDEO_TDA1997X is not set +# CONFIG_VIDEO_TDA7432 is not set +# CONFIG_VIDEO_TDA9840 is not set +# CONFIG_VIDEO_TEA6415C is not set +# CONFIG_VIDEO_TEA6420 is not set +# CONFIG_VIDEO_TLV320AIC23B is not set +# CONFIG_VIDEO_TVAUDIO is not set +# CONFIG_VIDEO_UDA1342 is not set +# CONFIG_VIDEO_VP27SMPX is not set +# CONFIG_VIDEO_WM8739 is not set +# CONFIG_VIDEO_WM8775 is not set +# end of Audio decoders, processors and mixers + +# +# RDS decoders +# +# CONFIG_VIDEO_SAA6588 is not set +# end of RDS decoders + +# +# Video decoders +# +# CONFIG_VIDEO_ADV7180 is not set +# CONFIG_VIDEO_ADV7183 is not set +# CONFIG_VIDEO_ADV748X is not set +# CONFIG_VIDEO_ADV7604 is not set +# CONFIG_VIDEO_ADV7842 is not set +# CONFIG_VIDEO_BT819 is not set +# CONFIG_VIDEO_BT856 is not set +# CONFIG_VIDEO_BT866 is not set +# CONFIG_VIDEO_ISL7998X is not set +# CONFIG_VIDEO_KS0127 is not set +# CONFIG_VIDEO_MAX9286 is not set +# CONFIG_VIDEO_ML86V7667 is not set +# CONFIG_VIDEO_SAA7110 is not set +# CONFIG_VIDEO_SAA711X is not set +# CONFIG_VIDEO_TC358743 is not set +# CONFIG_VIDEO_TC358746 is not set +# CONFIG_VIDEO_TVP514X is not set +# CONFIG_VIDEO_TVP5150 is not set +# CONFIG_VIDEO_TVP7002 is not set +# CONFIG_VIDEO_TW2804 is not set +# CONFIG_VIDEO_TW9900 is not set +# CONFIG_VIDEO_TW9903 is not set +# CONFIG_VIDEO_TW9906 is not set +# CONFIG_VIDEO_TW9910 is not set +# CONFIG_VIDEO_VPX3220 is not set + +# +# Video and audio decoders +# +# CONFIG_VIDEO_SAA717X is not set +# CONFIG_VIDEO_CX25840 is not set +# end of Video decoders + +# +# Video encoders +# +# CONFIG_VIDEO_ADV7170 is not set +# CONFIG_VIDEO_ADV7175 is not set +# CONFIG_VIDEO_ADV7343 is not set +# CONFIG_VIDEO_ADV7393 is not set +# CONFIG_VIDEO_ADV7511 is not set +# CONFIG_VIDEO_AK881X is not set +# CONFIG_VIDEO_SAA7127 is not set +# CONFIG_VIDEO_SAA7185 is not set +# CONFIG_VIDEO_THS8200 is not set +# end of Video encoders + +# +# Video improvement chips +# +# CONFIG_VIDEO_UPD64031A is not set +# CONFIG_VIDEO_UPD64083 is not set +# end of Video improvement chips + +# +# Audio/Video compression chips +# +# CONFIG_VIDEO_SAA6752HS is not set +# end of Audio/Video compression chips + +# +# SDR tuner chips +# +# end of SDR tuner chips + +# +# Miscellaneous helper chips +# +# CONFIG_VIDEO_I2C is not set +# CONFIG_VIDEO_M52790 is not set +# CONFIG_VIDEO_ST_MIPID02 is not set +# CONFIG_VIDEO_THS7303 is not set +# end of Miscellaneous helper chips + +# +# Video serializers and deserializers +# +# CONFIG_VIDEO_DS90UB913 is not set +# CONFIG_VIDEO_DS90UB953 is not set +# CONFIG_VIDEO_DS90UB960 is not set +# CONFIG_VIDEO_MAX96714 is not set +# CONFIG_VIDEO_MAX96717 is not set +# end of Video serializers and deserializers + +# +# Media SPI Adapters +# +# CONFIG_VIDEO_GS1662 is not set +# end of Media SPI Adapters +# end of Media ancillary drivers + +# +# Graphics support +# +CONFIG_VIDEO=y +# CONFIG_AUXDISPLAY is not set +CONFIG_DRM=y +CONFIG_DRM_MIPI_DBI=y +CONFIG_DRM_MIPI_DSI=y +# CONFIG_DRM_DEBUG_MM is not set +CONFIG_DRM_KMS_HELPER=y +# CONFIG_DRM_PANIC is not set +# CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS is not set +# CONFIG_DRM_DEBUG_MODESET_LOCK is not set +CONFIG_DRM_CLIENT_SELECTION=y +CONFIG_DRM_CLIENT_SETUP=y +CONFIG_DRM_FBDEV_EMULATION=y +CONFIG_DRM_FBDEV_OVERALLOC=200 +# CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM is not set +# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set +CONFIG_DRM_DISPLAY_HELPER=y +CONFIG_DRM_BRIDGE_CONNECTOR=y +# CONFIG_DRM_DISPLAY_DP_AUX_CEC is not set +# CONFIG_DRM_DISPLAY_DP_AUX_CHARDEV is not set +CONFIG_DRM_DISPLAY_DP_HELPER=y +CONFIG_DRM_DISPLAY_HDMI_HELPER=y +CONFIG_DRM_DISPLAY_HDMI_STATE_HELPER=y +CONFIG_DRM_GEM_DMA_HELPER=y +CONFIG_DRM_GEM_SHMEM_HELPER=m +CONFIG_DRM_SCHED=m + +# +# I2C encoder or helper chips +# +# CONFIG_DRM_I2C_CH7006 is not set +# CONFIG_DRM_I2C_SIL164 is not set +# CONFIG_DRM_I2C_NXP_TDA998X is not set +# CONFIG_DRM_I2C_NXP_TDA9950 is not set +# end of I2C encoder or helper chips + +# +# ARM devices +# +# CONFIG_DRM_HDLCD is not set +# CONFIG_DRM_MALI_DISPLAY is not set +# CONFIG_DRM_KOMEDA is not set +# end of ARM devices + +# CONFIG_DRM_VGEM is not set +# CONFIG_DRM_VKMS is not set +CONFIG_DRM_ROCKCHIP=y +CONFIG_ROCKCHIP_VOP=y +# CONFIG_ROCKCHIP_VOP2 is not set +CONFIG_ROCKCHIP_ANALOGIX_DP=y +CONFIG_ROCKCHIP_CDN_DP=y +CONFIG_ROCKCHIP_DW_HDMI=y +CONFIG_ROCKCHIP_DW_MIPI_DSI=y +CONFIG_ROCKCHIP_INNO_HDMI=y +CONFIG_ROCKCHIP_LVDS=y +CONFIG_ROCKCHIP_RGB=y +CONFIG_ROCKCHIP_RK3066_HDMI=y +# CONFIG_DRM_UDL is not set +CONFIG_DRM_PANEL=y + +# +# Display Panels +# +# CONFIG_DRM_PANEL_ABT_Y030XX067A is not set +# CONFIG_DRM_PANEL_ARM_VERSATILE is not set +# CONFIG_DRM_PANEL_ASUS_Z00T_TM5P5_NT35596 is not set +# CONFIG_DRM_PANEL_AUO_A030JTN01 is not set +# CONFIG_DRM_PANEL_BOE_BF060Y8M_AJ0 is not set +# CONFIG_DRM_PANEL_BOE_HIMAX8279D is not set +# CONFIG_DRM_PANEL_BOE_TH101MB31UIG002_28A is not set +# CONFIG_DRM_PANEL_BOE_TV101WUM_NL6 is not set +# CONFIG_DRM_PANEL_BOE_TV101WUM_LL2 is not set +# CONFIG_DRM_PANEL_EBBG_FT8719 is not set +CONFIG_DRM_PANEL_ELIDA_KD35T133=y +# CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02 is not set +# CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D is not set +# CONFIG_DRM_PANEL_DSI_CM is not set +# CONFIG_DRM_PANEL_LVDS is not set +# CONFIG_DRM_PANEL_HIMAX_HX83102 is not set +# CONFIG_DRM_PANEL_HIMAX_HX83112A is not set +# CONFIG_DRM_PANEL_HIMAX_HX8394 is not set +# CONFIG_DRM_PANEL_ILITEK_IL9322 is not set +# CONFIG_DRM_PANEL_ILITEK_ILI9341 is not set +# CONFIG_DRM_PANEL_ILITEK_ILI9805 is not set +# CONFIG_DRM_PANEL_ILITEK_ILI9806E is not set +# CONFIG_DRM_PANEL_ILITEK_ILI9881C is not set +# CONFIG_DRM_PANEL_ILITEK_ILI9882T is not set +# CONFIG_DRM_PANEL_INNOLUX_EJ030NA is not set +# CONFIG_DRM_PANEL_INNOLUX_P079ZCA is not set +# CONFIG_DRM_PANEL_JADARD_JD9365DA_H3 is not set +# CONFIG_DRM_PANEL_JDI_LPM102A188A is not set +# CONFIG_DRM_PANEL_JDI_LT070ME05000 is not set +# CONFIG_DRM_PANEL_JDI_R63452 is not set +# CONFIG_DRM_PANEL_KHADAS_TS050 is not set +# CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04 is not set +# CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W is not set +# CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829 is not set +# CONFIG_DRM_PANEL_LINCOLNTECH_LCD197 is not set +# CONFIG_DRM_PANEL_LG_LB035Q02 is not set +# CONFIG_DRM_PANEL_LG_LG4573 is not set +# CONFIG_DRM_PANEL_LG_SW43408 is not set +# CONFIG_DRM_PANEL_MAGNACHIP_D53E6EA8966 is not set +# CONFIG_DRM_PANEL_MANTIX_MLAF057WE51 is not set +# CONFIG_DRM_PANEL_NEC_NL8048HL11 is not set +CONFIG_DRM_PANEL_NEWVISION_NV3051D=y +# CONFIG_DRM_PANEL_NEWVISION_NV3052C is not set +# CONFIG_DRM_PANEL_NOVATEK_NT35510 is not set +# CONFIG_DRM_PANEL_NOVATEK_NT35560 is not set +# CONFIG_DRM_PANEL_NOVATEK_NT35950 is not set +# CONFIG_DRM_PANEL_NOVATEK_NT36523 is not set +# CONFIG_DRM_PANEL_NOVATEK_NT36672A is not set +# CONFIG_DRM_PANEL_NOVATEK_NT36672E is not set +# CONFIG_DRM_PANEL_NOVATEK_NT39016 is not set +# CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO is not set +# CONFIG_DRM_PANEL_ORISETECH_OTA5601A is not set +# CONFIG_DRM_PANEL_ORISETECH_OTM8009A is not set +# CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS is not set +# CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00 is not set +# CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN is not set +# CONFIG_DRM_PANEL_RAYDIUM_RM67191 is not set +# CONFIG_DRM_PANEL_RAYDIUM_RM68200 is not set +# CONFIG_DRM_PANEL_RAYDIUM_RM692E5 is not set +# CONFIG_DRM_PANEL_RAYDIUM_RM69380 is not set +# CONFIG_DRM_PANEL_RONBO_RB070D30 is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01 is not set +# CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20 is not set +# CONFIG_DRM_PANEL_SAMSUNG_DB7430 is not set +# CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6E3FA7 is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6D16D0 is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6D27A1 is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6D7AA0 is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2 is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03 is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6E63M0 is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set +# CONFIG_DRM_PANEL_SAMSUNG_SOFEF00 is not set +# CONFIG_DRM_PANEL_SEIKO_43WVF1G is not set +# CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 is not set +# CONFIG_DRM_PANEL_SHARP_LS037V7DW01 is not set +# CONFIG_DRM_PANEL_SHARP_LS043T1LE01 is not set +# CONFIG_DRM_PANEL_SHARP_LS060T1SX01 is not set +CONFIG_DRM_PANEL_SITRONIX_ST7701=y +CONFIG_DRM_PANEL_SITRONIX_ST7703=y +# CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set +# CONFIG_DRM_PANEL_SONY_ACX565AKM is not set +# CONFIG_DRM_PANEL_SONY_TD4353_JDI is not set +# CONFIG_DRM_PANEL_SONY_TULIP_TRULY_NT35521 is not set +# CONFIG_DRM_PANEL_STARTEK_KD070FHFID015 is not set +# CONFIG_DRM_PANEL_EDP is not set +CONFIG_DRM_PANEL_SIMPLE=y +# CONFIG_DRM_PANEL_SYNAPTICS_R63353 is not set +# CONFIG_DRM_PANEL_TDO_TL070WSH30 is not set +# CONFIG_DRM_PANEL_TPO_TD028TTEC1 is not set +# CONFIG_DRM_PANEL_TPO_TD043MTEA1 is not set +# CONFIG_DRM_PANEL_TPO_TPG110 is not set +# CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA is not set +# CONFIG_DRM_PANEL_VISIONOX_R66451 is not set +# CONFIG_DRM_PANEL_VISIONOX_RM69299 is not set +# CONFIG_DRM_PANEL_VISIONOX_VTDR6130 is not set +# CONFIG_DRM_PANEL_WIDECHIPS_WS2401 is not set +# CONFIG_DRM_PANEL_XINPENG_XPP055C272 is not set +# end of Display Panels + +CONFIG_DRM_BRIDGE=y +CONFIG_DRM_PANEL_BRIDGE=y + +# +# Display Interface Bridges +# +# CONFIG_DRM_CHIPONE_ICN6211 is not set +# CONFIG_DRM_CHRONTEL_CH7033 is not set +CONFIG_DRM_DISPLAY_CONNECTOR=m +# CONFIG_DRM_ITE_IT6505 is not set +# CONFIG_DRM_LONTIUM_LT8912B is not set +# CONFIG_DRM_LONTIUM_LT9211 is not set +# CONFIG_DRM_LONTIUM_LT9611 is not set +# CONFIG_DRM_LONTIUM_LT9611UXC is not set +# CONFIG_DRM_ITE_IT66121 is not set +# CONFIG_DRM_LVDS_CODEC is not set +# CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set +# CONFIG_DRM_NWL_MIPI_DSI is not set +# CONFIG_DRM_NXP_PTN3460 is not set +# CONFIG_DRM_PARADE_PS8622 is not set +# CONFIG_DRM_PARADE_PS8640 is not set +# CONFIG_DRM_SAMSUNG_DSIM is not set +# CONFIG_DRM_SIL_SII8620 is not set +# CONFIG_DRM_SII902X is not set +# CONFIG_DRM_SII9234 is not set +CONFIG_DRM_SIMPLE_BRIDGE=y +# CONFIG_DRM_THINE_THC63LVD1024 is not set +# CONFIG_DRM_TOSHIBA_TC358762 is not set +# CONFIG_DRM_TOSHIBA_TC358764 is not set +# CONFIG_DRM_TOSHIBA_TC358767 is not set +# CONFIG_DRM_TOSHIBA_TC358768 is not set +# CONFIG_DRM_TOSHIBA_TC358775 is not set +# CONFIG_DRM_TI_DLPC3433 is not set +# CONFIG_DRM_TI_TFP410 is not set +# CONFIG_DRM_TI_SN65DSI83 is not set +# CONFIG_DRM_TI_SN65DSI86 is not set +# CONFIG_DRM_TI_TPD12S015 is not set +# CONFIG_DRM_ANALOGIX_ANX6345 is not set +# CONFIG_DRM_ANALOGIX_ANX78XX is not set +CONFIG_DRM_ANALOGIX_DP=y +# CONFIG_DRM_ANALOGIX_ANX7625 is not set +# CONFIG_DRM_I2C_ADV7511 is not set +# CONFIG_DRM_CDNS_DSI is not set +# CONFIG_DRM_CDNS_MHDP8546 is not set +CONFIG_DRM_DW_HDMI=y +# CONFIG_DRM_DW_HDMI_AHB_AUDIO is not set +CONFIG_DRM_DW_HDMI_I2S_AUDIO=y +# CONFIG_DRM_DW_HDMI_GP_AUDIO is not set +CONFIG_DRM_DW_HDMI_CEC=y +CONFIG_DRM_DW_MIPI_DSI=y +# end of Display Interface Bridges + +# CONFIG_DRM_ETNAVIV is not set +# CONFIG_DRM_HISI_KIRIN is not set +# CONFIG_DRM_LOGICVC is not set +# CONFIG_DRM_ARCPGU is not set +# CONFIG_DRM_GM12U320 is not set +CONFIG_DRM_PANEL_MIPI_DBI=m +# CONFIG_DRM_SIMPLEDRM is not set +# CONFIG_TINYDRM_HX8357D is not set +# CONFIG_TINYDRM_ILI9163 is not set +# CONFIG_TINYDRM_ILI9225 is not set +# CONFIG_TINYDRM_ILI9341 is not set +# CONFIG_TINYDRM_ILI9486 is not set +# CONFIG_TINYDRM_MI0283QT is not set +# CONFIG_TINYDRM_REPAPER is not set +# CONFIG_TINYDRM_ST7586 is not set +# CONFIG_TINYDRM_ST7735R is not set +# CONFIG_DRM_PL111 is not set +# CONFIG_DRM_LIMA is not set +CONFIG_DRM_PANFROST=m +# CONFIG_DRM_PANTHOR is not set +# CONFIG_DRM_TIDSS is not set +# CONFIG_DRM_GUD is not set +# CONFIG_DRM_SSD130X is not set +# CONFIG_DRM_POWERVR is not set +# CONFIG_DRM_WERROR is not set +CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y + +# +# Frame buffer Devices +# +CONFIG_FB=y +# CONFIG_FB_UVESA is not set +# CONFIG_FB_OPENCORES is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_SMSCUFX is not set +# CONFIG_FB_UDL is not set +# CONFIG_FB_IBM_GXT4500 is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_SIMPLE is not set +# CONFIG_FB_SSD1307 is not set +CONFIG_FB_CORE=y +CONFIG_FB_NOTIFY=y +# CONFIG_FIRMWARE_EDID is not set +CONFIG_FB_DEVICE=y +CONFIG_FB_SYS_FILLRECT=y +CONFIG_FB_SYS_COPYAREA=y +CONFIG_FB_SYS_IMAGEBLIT=y +# CONFIG_FB_FOREIGN_ENDIAN is not set +CONFIG_FB_SYSMEM_FOPS=y +CONFIG_FB_DEFERRED_IO=y +CONFIG_FB_DMAMEM_HELPERS=y +CONFIG_FB_DMAMEM_HELPERS_DEFERRED=y +CONFIG_FB_SYSMEM_HELPERS=y +CONFIG_FB_SYSMEM_HELPERS_DEFERRED=y +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_TILEBLITTING is not set +# end of Frame buffer Devices + +# +# Backlight & LCD device support +# +# CONFIG_LCD_CLASS_DEVICE is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +# CONFIG_BACKLIGHT_KTD253 is not set +# CONFIG_BACKLIGHT_KTD2801 is not set +# CONFIG_BACKLIGHT_KTZ8866 is not set +CONFIG_BACKLIGHT_PWM=y +# CONFIG_BACKLIGHT_QCOM_WLED is not set +# CONFIG_BACKLIGHT_ADP8860 is not set +# CONFIG_BACKLIGHT_ADP8870 is not set +# CONFIG_BACKLIGHT_LM3509 is not set +# CONFIG_BACKLIGHT_LM3630A is not set +# CONFIG_BACKLIGHT_LM3639 is not set +# CONFIG_BACKLIGHT_LP855X is not set +# CONFIG_BACKLIGHT_MP3309C is not set +# CONFIG_BACKLIGHT_GPIO is not set +# CONFIG_BACKLIGHT_LV5207LP is not set +# CONFIG_BACKLIGHT_BD6107 is not set +# CONFIG_BACKLIGHT_ARCXCNN is not set +# CONFIG_BACKLIGHT_LED is not set +# end of Backlight & LCD device support + +CONFIG_VIDEOMODE_HELPERS=y +CONFIG_HDMI=y + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +CONFIG_DUMMY_CONSOLE_COLUMNS=80 +CONFIG_DUMMY_CONSOLE_ROWS=25 +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION is not set +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +# CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set +# end of Console display driver support + +# CONFIG_LOGO is not set +# end of Graphics support + +# CONFIG_DRM_ACCEL is not set +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_PCM_ELD=y +CONFIG_SND_PCM_IEC958=y +CONFIG_SND_DMAENGINE_PCM=y +CONFIG_SND_HWDEP=m +CONFIG_SND_SEQ_DEVICE=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_JACK=y +CONFIG_SND_JACK_INPUT_DEV=y +# CONFIG_SND_OSSEMUL is not set +CONFIG_SND_PCM_TIMER=y +CONFIG_SND_HRTIMER=y +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_MAX_CARDS=32 +# CONFIG_SND_SUPPORT_OLD_API is not set +CONFIG_SND_PROC_FS=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_CTL_FAST_LOOKUP is not set +# CONFIG_SND_DEBUG is not set +# CONFIG_SND_CTL_INPUT_VALIDATION is not set +# CONFIG_SND_UTIMER is not set +CONFIG_SND_SEQUENCER=m +# CONFIG_SND_SEQ_DUMMY is not set +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y +CONFIG_SND_SEQ_MIDI_EVENT=m +CONFIG_SND_SEQ_MIDI=m +# CONFIG_SND_SEQ_UMP is not set +# CONFIG_SND_DRIVERS is not set + +# +# HD-Audio +# +# end of HD-Audio + +CONFIG_SND_HDA_PREALLOC_SIZE=64 +# CONFIG_SND_SPI is not set +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=m +# CONFIG_SND_USB_AUDIO_MIDI_V2 is not set +CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER=y +# CONFIG_SND_USB_UA101 is not set +# CONFIG_SND_USB_CAIAQ is not set +# CONFIG_SND_USB_6FIRE is not set +# CONFIG_SND_USB_HIFACE is not set +# CONFIG_SND_BCD2000 is not set +# CONFIG_SND_USB_POD is not set +# CONFIG_SND_USB_PODHD is not set +# CONFIG_SND_USB_TONEPORT is not set +# CONFIG_SND_USB_VARIAX is not set +CONFIG_SND_SOC=y +CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y +# CONFIG_SND_SOC_ADI is not set +# CONFIG_SND_SOC_AMD_ACP is not set +# CONFIG_SND_AMD_ACP_CONFIG is not set +# CONFIG_SND_ATMEL_SOC is not set +# CONFIG_SND_BCM63XX_I2S_WHISTLER is not set +# CONFIG_SND_DESIGNWARE_I2S is not set + +# +# SoC Audio for Freescale CPUs +# + +# +# Common SoC Audio options for Freescale CPUs: +# +# CONFIG_SND_SOC_FSL_ASRC is not set +# CONFIG_SND_SOC_FSL_SAI is not set +# CONFIG_SND_SOC_FSL_AUDMIX is not set +# CONFIG_SND_SOC_FSL_SSI is not set +# CONFIG_SND_SOC_FSL_SPDIF is not set +# CONFIG_SND_SOC_FSL_ESAI is not set +# CONFIG_SND_SOC_FSL_MICFIL is not set +# CONFIG_SND_SOC_FSL_XCVR is not set +# CONFIG_SND_SOC_IMX_AUDMUX is not set +# end of SoC Audio for Freescale CPUs + +# CONFIG_SND_SOC_CHV3_I2S is not set +# CONFIG_SND_I2S_HI6210_I2S is not set +# CONFIG_SND_SOC_IMG is not set +# CONFIG_SND_SOC_MTK_BTCVSD is not set +CONFIG_SND_SOC_ROCKCHIP=y +CONFIG_SND_SOC_ROCKCHIP_I2S=y +# CONFIG_SND_SOC_ROCKCHIP_I2S_TDM is not set +CONFIG_SND_SOC_ROCKCHIP_PDM=m +# CONFIG_SND_SOC_ROCKCHIP_SPDIF is not set +# CONFIG_SND_SOC_ROCKCHIP_MAX98090 is not set +# CONFIG_SND_SOC_ROCKCHIP_RT5645 is not set +# CONFIG_SND_SOC_RK3288_HDMI_ANALOG is not set +# CONFIG_SND_SOC_RK3399_GRU_SOUND is not set +# CONFIG_SND_SOC_SOF_TOPLEVEL is not set + +# +# STMicroelectronics STM32 SOC audio support +# +# end of STMicroelectronics STM32 SOC audio support + +# CONFIG_SND_SOC_XILINX_I2S is not set +# CONFIG_SND_SOC_XILINX_AUDIO_FORMATTER is not set +# CONFIG_SND_SOC_XILINX_SPDIF is not set +# CONFIG_SND_SOC_XTFPGA_I2S is not set +CONFIG_SND_SOC_I2C_AND_SPI=y + +# +# CODEC drivers +# +# CONFIG_SND_SOC_AC97_CODEC is not set +# CONFIG_SND_SOC_ADAU1372_I2C is not set +# CONFIG_SND_SOC_ADAU1372_SPI is not set +# CONFIG_SND_SOC_ADAU1701 is not set +# CONFIG_SND_SOC_ADAU1761_I2C is not set +# CONFIG_SND_SOC_ADAU1761_SPI is not set +# CONFIG_SND_SOC_ADAU7002 is not set +# CONFIG_SND_SOC_ADAU7118_HW is not set +# CONFIG_SND_SOC_ADAU7118_I2C is not set +# CONFIG_SND_SOC_AK4104 is not set +# CONFIG_SND_SOC_AK4118 is not set +# CONFIG_SND_SOC_AK4375 is not set +# CONFIG_SND_SOC_AK4458 is not set +# CONFIG_SND_SOC_AK4554 is not set +CONFIG_SND_SOC_AK4613=m +# CONFIG_SND_SOC_AK4619 is not set +# CONFIG_SND_SOC_AK4642 is not set +# CONFIG_SND_SOC_AK5386 is not set +# CONFIG_SND_SOC_AK5558 is not set +# CONFIG_SND_SOC_ALC5623 is not set +# CONFIG_SND_SOC_AUDIO_IIO_AUX is not set +# CONFIG_SND_SOC_AW8738 is not set +# CONFIG_SND_SOC_AW88395 is not set +# CONFIG_SND_SOC_AW88261 is not set +# CONFIG_SND_SOC_AW87390 is not set +# CONFIG_SND_SOC_AW88399 is not set +# CONFIG_SND_SOC_BD28623 is not set +# CONFIG_SND_SOC_BT_SCO is not set +# CONFIG_SND_SOC_CHV3_CODEC is not set +# CONFIG_SND_SOC_CS35L32 is not set +# CONFIG_SND_SOC_CS35L33 is not set +# CONFIG_SND_SOC_CS35L34 is not set +# CONFIG_SND_SOC_CS35L35 is not set +# CONFIG_SND_SOC_CS35L36 is not set +# CONFIG_SND_SOC_CS35L41_SPI is not set +# CONFIG_SND_SOC_CS35L41_I2C is not set +# CONFIG_SND_SOC_CS35L45_SPI is not set +# CONFIG_SND_SOC_CS35L45_I2C is not set +# CONFIG_SND_SOC_CS35L56_I2C is not set +# CONFIG_SND_SOC_CS35L56_SPI is not set +# CONFIG_SND_SOC_CS42L42 is not set +# CONFIG_SND_SOC_CS42L51_I2C is not set +# CONFIG_SND_SOC_CS42L52 is not set +# CONFIG_SND_SOC_CS42L56 is not set +# CONFIG_SND_SOC_CS42L73 is not set +# CONFIG_SND_SOC_CS42L83 is not set +# CONFIG_SND_SOC_CS4234 is not set +# CONFIG_SND_SOC_CS4265 is not set +# CONFIG_SND_SOC_CS4270 is not set +# CONFIG_SND_SOC_CS4271_I2C is not set +# CONFIG_SND_SOC_CS4271_SPI is not set +# CONFIG_SND_SOC_CS42XX8_I2C is not set +# CONFIG_SND_SOC_CS43130 is not set +# CONFIG_SND_SOC_CS4341 is not set +# CONFIG_SND_SOC_CS4349 is not set +# CONFIG_SND_SOC_CS53L30 is not set +# CONFIG_SND_SOC_CS530X_I2C is not set +# CONFIG_SND_SOC_CX2072X is not set +# CONFIG_SND_SOC_DA7213 is not set +CONFIG_SND_SOC_DMIC=y +CONFIG_SND_SOC_HDMI_CODEC=y +# CONFIG_SND_SOC_ES7134 is not set +# CONFIG_SND_SOC_ES7241 is not set +# CONFIG_SND_SOC_ES8311 is not set +CONFIG_SND_SOC_ES8316=y +# CONFIG_SND_SOC_ES8326 is not set +CONFIG_SND_SOC_ES8328=y +CONFIG_SND_SOC_ES8328_I2C=y +CONFIG_SND_SOC_ES8328_SPI=y +# CONFIG_SND_SOC_GTM601 is not set +# CONFIG_SND_SOC_HDA is not set +# CONFIG_SND_SOC_ICS43432 is not set +# CONFIG_SND_SOC_IDT821034 is not set +# CONFIG_SND_SOC_INNO_RK3036 is not set +# CONFIG_SND_SOC_MAX98088 is not set +# CONFIG_SND_SOC_MAX98090 is not set +CONFIG_SND_SOC_MAX98357A=y +# CONFIG_SND_SOC_MAX98504 is not set +# CONFIG_SND_SOC_MAX9867 is not set +# CONFIG_SND_SOC_MAX98927 is not set +# CONFIG_SND_SOC_MAX98520 is not set +# CONFIG_SND_SOC_MAX98373_I2C is not set +# CONFIG_SND_SOC_MAX98388 is not set +# CONFIG_SND_SOC_MAX98390 is not set +# CONFIG_SND_SOC_MAX98396 is not set +# CONFIG_SND_SOC_MAX9860 is not set +# CONFIG_SND_SOC_MSM8916_WCD_ANALOG is not set +# CONFIG_SND_SOC_MSM8916_WCD_DIGITAL is not set +# CONFIG_SND_SOC_PCM1681 is not set +# CONFIG_SND_SOC_PCM1789_I2C is not set +# CONFIG_SND_SOC_PCM179X_I2C is not set +# CONFIG_SND_SOC_PCM179X_SPI is not set +# CONFIG_SND_SOC_PCM186X_I2C is not set +# CONFIG_SND_SOC_PCM186X_SPI is not set +# CONFIG_SND_SOC_PCM3060_I2C is not set +# CONFIG_SND_SOC_PCM3060_SPI is not set +# CONFIG_SND_SOC_PCM3168A_I2C is not set +# CONFIG_SND_SOC_PCM3168A_SPI is not set +# CONFIG_SND_SOC_PCM5102A is not set +# CONFIG_SND_SOC_PCM512x_I2C is not set +# CONFIG_SND_SOC_PCM512x_SPI is not set +# CONFIG_SND_SOC_PCM6240 is not set +# CONFIG_SND_SOC_PEB2466 is not set +# CONFIG_SND_SOC_RK3308 is not set +# CONFIG_SND_SOC_RK3328 is not set +CONFIG_SND_SOC_RK817=y +# CONFIG_SND_SOC_RT5616 is not set +# CONFIG_SND_SOC_RT5631 is not set +# CONFIG_SND_SOC_RT5640 is not set +# CONFIG_SND_SOC_RT5659 is not set +# CONFIG_SND_SOC_RT9120 is not set +# CONFIG_SND_SOC_RTQ9128 is not set +# CONFIG_SND_SOC_SGTL5000 is not set +CONFIG_SND_SOC_SIMPLE_AMPLIFIER=m +# CONFIG_SND_SOC_SIMPLE_MUX is not set +# CONFIG_SND_SOC_SMA1303 is not set +CONFIG_SND_SOC_SPDIF=y +# CONFIG_SND_SOC_SRC4XXX_I2C is not set +# CONFIG_SND_SOC_SSM2305 is not set +# CONFIG_SND_SOC_SSM2518 is not set +# CONFIG_SND_SOC_SSM2602_SPI is not set +# CONFIG_SND_SOC_SSM2602_I2C is not set +# CONFIG_SND_SOC_SSM3515 is not set +# CONFIG_SND_SOC_SSM4567 is not set +# CONFIG_SND_SOC_STA32X is not set +# CONFIG_SND_SOC_STA350 is not set +# CONFIG_SND_SOC_STI_SAS is not set +# CONFIG_SND_SOC_TAS2552 is not set +# CONFIG_SND_SOC_TAS2562 is not set +# CONFIG_SND_SOC_TAS2764 is not set +# CONFIG_SND_SOC_TAS2770 is not set +# CONFIG_SND_SOC_TAS2780 is not set +# CONFIG_SND_SOC_TAS2781_I2C is not set +# CONFIG_SND_SOC_TAS5086 is not set +# CONFIG_SND_SOC_TAS571X is not set +# CONFIG_SND_SOC_TAS5720 is not set +# CONFIG_SND_SOC_TAS5805M is not set +# CONFIG_SND_SOC_TAS6424 is not set +# CONFIG_SND_SOC_TDA7419 is not set +# CONFIG_SND_SOC_TFA9879 is not set +# CONFIG_SND_SOC_TFA989X is not set +# CONFIG_SND_SOC_TLV320ADC3XXX is not set +# CONFIG_SND_SOC_TLV320AIC23_I2C is not set +# CONFIG_SND_SOC_TLV320AIC23_SPI is not set +# CONFIG_SND_SOC_TLV320AIC31XX is not set +# CONFIG_SND_SOC_TLV320AIC32X4_I2C is not set +# CONFIG_SND_SOC_TLV320AIC32X4_SPI is not set +# CONFIG_SND_SOC_TLV320AIC3X_I2C is not set +# CONFIG_SND_SOC_TLV320AIC3X_SPI is not set +# CONFIG_SND_SOC_TLV320ADCX140 is not set +CONFIG_SND_SOC_TS3A227E=m +# CONFIG_SND_SOC_TSCS42XX is not set +# CONFIG_SND_SOC_TSCS454 is not set +# CONFIG_SND_SOC_UDA1334 is not set +# CONFIG_SND_SOC_WM8510 is not set +# CONFIG_SND_SOC_WM8523 is not set +# CONFIG_SND_SOC_WM8524 is not set +# CONFIG_SND_SOC_WM8580 is not set +# CONFIG_SND_SOC_WM8711 is not set +# CONFIG_SND_SOC_WM8728 is not set +# CONFIG_SND_SOC_WM8731_I2C is not set +# CONFIG_SND_SOC_WM8731_SPI is not set +# CONFIG_SND_SOC_WM8737 is not set +# CONFIG_SND_SOC_WM8741 is not set +# CONFIG_SND_SOC_WM8750 is not set +# CONFIG_SND_SOC_WM8753 is not set +# CONFIG_SND_SOC_WM8770 is not set +# CONFIG_SND_SOC_WM8776 is not set +# CONFIG_SND_SOC_WM8782 is not set +# CONFIG_SND_SOC_WM8804_I2C is not set +# CONFIG_SND_SOC_WM8804_SPI is not set +# CONFIG_SND_SOC_WM8903 is not set +# CONFIG_SND_SOC_WM8904 is not set +# CONFIG_SND_SOC_WM8940 is not set +# CONFIG_SND_SOC_WM8960 is not set +# CONFIG_SND_SOC_WM8961 is not set +# CONFIG_SND_SOC_WM8962 is not set +# CONFIG_SND_SOC_WM8974 is not set +# CONFIG_SND_SOC_WM8978 is not set +# CONFIG_SND_SOC_WM8985 is not set +# CONFIG_SND_SOC_ZL38060 is not set +# CONFIG_SND_SOC_MAX9759 is not set +# CONFIG_SND_SOC_MT6351 is not set +# CONFIG_SND_SOC_MT6357 is not set +# CONFIG_SND_SOC_MT6358 is not set +# CONFIG_SND_SOC_MT6660 is not set +# CONFIG_SND_SOC_NAU8315 is not set +# CONFIG_SND_SOC_NAU8540 is not set +# CONFIG_SND_SOC_NAU8810 is not set +# CONFIG_SND_SOC_NAU8821 is not set +# CONFIG_SND_SOC_NAU8822 is not set +# CONFIG_SND_SOC_NAU8824 is not set +# CONFIG_SND_SOC_TPA6130A2 is not set +# CONFIG_SND_SOC_LPASS_WSA_MACRO is not set +# CONFIG_SND_SOC_LPASS_VA_MACRO is not set +# CONFIG_SND_SOC_LPASS_RX_MACRO is not set +# CONFIG_SND_SOC_LPASS_TX_MACRO is not set +# end of CODEC drivers + +CONFIG_SND_SIMPLE_CARD_UTILS=y +CONFIG_SND_SIMPLE_CARD=y +# CONFIG_SND_AUDIO_GRAPH_CARD is not set +# CONFIG_SND_AUDIO_GRAPH_CARD2 is not set +# CONFIG_SND_TEST_COMPONENT is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +CONFIG_HID_BATTERY_STRENGTH=y +CONFIG_HIDRAW=y +CONFIG_UHID=y +CONFIG_HID_GENERIC=y + +# +# Special HID drivers +# +CONFIG_HID_A4TECH=m +# CONFIG_HID_ACCUTOUCH is not set +CONFIG_HID_ACRUX=m +CONFIG_HID_ACRUX_FF=y +CONFIG_HID_APPLE=m +CONFIG_HID_APPLEIR=m +# CONFIG_HID_ASUS is not set +CONFIG_HID_AUREAL=m +CONFIG_HID_BELKIN=m +CONFIG_HID_BETOP_FF=m +# CONFIG_HID_BIGBEN_FF is not set +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +CONFIG_HID_CORSAIR=m +# CONFIG_HID_COUGAR is not set +# CONFIG_HID_MACALLY is not set +CONFIG_HID_PRODIKEYS=m +# CONFIG_HID_CMEDIA is not set +# CONFIG_HID_CP2112 is not set +# CONFIG_HID_CREATIVE_SB0540 is not set +CONFIG_HID_CYPRESS=m +CONFIG_HID_DRAGONRISE=m +CONFIG_DRAGONRISE_FF=y +CONFIG_HID_EMS_FF=m +# CONFIG_HID_ELAN is not set +CONFIG_HID_ELECOM=m +CONFIG_HID_ELO=m +# CONFIG_HID_EVISION is not set +CONFIG_HID_EZKEY=m +# CONFIG_HID_FT260 is not set +CONFIG_HID_GEMBIRD=m +CONFIG_HID_GFRM=m +# CONFIG_HID_GLORIOUS is not set +CONFIG_HID_HOLTEK=m +CONFIG_HOLTEK_FF=y +# CONFIG_HID_GOODIX_SPI is not set +# CONFIG_HID_GOOGLE_STADIA_FF is not set +# CONFIG_HID_VIVALDI is not set +CONFIG_HID_GT683R=m +CONFIG_HID_KEYTOUCH=m +CONFIG_HID_KYE=m +CONFIG_HID_UCLOGIC=m +CONFIG_HID_WALTOP=m +# CONFIG_HID_VIEWSONIC is not set +# CONFIG_HID_VRC2 is not set +# CONFIG_HID_XIAOMI is not set +CONFIG_HID_GYRATION=m +CONFIG_HID_ICADE=m +# CONFIG_HID_ITE is not set +# CONFIG_HID_JABRA is not set +CONFIG_HID_TWINHAN=m +CONFIG_HID_KENSINGTON=m +CONFIG_HID_LCPOWER=m +CONFIG_HID_LED=m +CONFIG_HID_LENOVO=m +# CONFIG_HID_LETSKETCH is not set +CONFIG_HID_LOGITECH=m +# CONFIG_HID_LOGITECH_DJ is not set +CONFIG_HID_LOGITECH_HIDPP=m +CONFIG_LOGITECH_FF=y +CONFIG_LOGIRUMBLEPAD2_FF=y +CONFIG_LOGIG940_FF=y +CONFIG_LOGIWHEELS_FF=y +CONFIG_HID_MAGICMOUSE=m +# CONFIG_HID_MALTRON is not set +# CONFIG_HID_MAYFLASH is not set +# CONFIG_HID_MEGAWORLD_FF is not set +# CONFIG_HID_REDRAGON is not set +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MONTEREY=m +CONFIG_HID_MULTITOUCH=m +# CONFIG_HID_NINTENDO is not set +# CONFIG_HID_NTI is not set +CONFIG_HID_NTRIG=m +# CONFIG_HID_NVIDIA_SHIELD is not set +CONFIG_HID_ORTEK=m +CONFIG_HID_PANTHERLORD=m +CONFIG_PANTHERLORD_FF=y +CONFIG_HID_PENMOUNT=m +CONFIG_HID_PETALYNX=m +CONFIG_HID_PICOLCD=m +CONFIG_HID_PICOLCD_FB=y +CONFIG_HID_PICOLCD_BACKLIGHT=y +CONFIG_HID_PICOLCD_LEDS=y +CONFIG_HID_PLANTRONICS=m +# CONFIG_HID_PXRC is not set +# CONFIG_HID_RAZER is not set +CONFIG_HID_PRIMAX=m +# CONFIG_HID_RETRODE is not set +CONFIG_HID_ROCCAT=m +CONFIG_HID_SAITEK=m +CONFIG_HID_SAMSUNG=m +# CONFIG_HID_SEMITEK is not set +# CONFIG_HID_SIGMAMICRO is not set +CONFIG_HID_SONY=m +CONFIG_SONY_FF=y +CONFIG_HID_SPEEDLINK=m +# CONFIG_HID_STEAM is not set +CONFIG_HID_STEELSERIES=m +CONFIG_HID_SUNPLUS=m +CONFIG_HID_RMI=m +CONFIG_HID_GREENASIA=m +CONFIG_GREENASIA_FF=y +CONFIG_HID_SMARTJOYPLUS=m +CONFIG_SMARTJOYPLUS_FF=y +CONFIG_HID_TIVO=m +CONFIG_HID_TOPSEED=m +# CONFIG_HID_TOPRE is not set +CONFIG_HID_THINGM=m +CONFIG_HID_THRUSTMASTER=m +CONFIG_THRUSTMASTER_FF=y +# CONFIG_HID_UDRAW_PS3 is not set +# CONFIG_HID_U2FZERO is not set +CONFIG_HID_WACOM=m +CONFIG_HID_WIIMOTE=m +# CONFIG_HID_WINWING is not set +CONFIG_HID_XINMO=m +CONFIG_HID_ZEROPLUS=m +CONFIG_ZEROPLUS_FF=y +CONFIG_HID_ZYDACRON=m +CONFIG_HID_SENSOR_HUB=m +CONFIG_HID_SENSOR_CUSTOM_SENSOR=m +CONFIG_HID_ALPS=m +# CONFIG_HID_MCP2200 is not set +# CONFIG_HID_MCP2221 is not set +# end of Special HID drivers + +# +# HID-BPF support +# +# end of HID-BPF support + +# +# USB HID support +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +CONFIG_USB_HIDDEV=y +# end of USB HID support + +CONFIG_I2C_HID=y +CONFIG_I2C_HID_OF=y +# CONFIG_I2C_HID_OF_ELAN is not set +# CONFIG_I2C_HID_OF_GOODIX is not set +CONFIG_I2C_HID_CORE=y +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_COMMON=y +# CONFIG_USB_LED_TRIG is not set +CONFIG_USB_ULPI_BUS=y +# CONFIG_USB_CONN_GPIO is not set +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +CONFIG_USB_DEFAULT_PERSIST=y +# CONFIG_USB_FEW_INIT_RETRIES is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_OTG=y +# CONFIG_USB_OTG_PRODUCTLIST is not set +# CONFIG_USB_OTG_DISABLE_EXTERNAL_HUB is not set +# CONFIG_USB_OTG_FSM is not set +# CONFIG_USB_LEDS_TRIGGER_USBPORT is not set +CONFIG_USB_AUTOSUSPEND_DELAY=2 +CONFIG_USB_DEFAULT_AUTHORIZATION_MODE=1 +# CONFIG_USB_MON is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_XHCI_HCD is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +# CONFIG_USB_EHCI_FSL is not set +CONFIG_USB_EHCI_HCD_PLATFORM=y +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_MAX3421_HCD is not set +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HCD_TEST_MODE is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=y +# CONFIG_USB_PRINTER is not set +CONFIG_USB_WDM=m +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_REALTEK is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_STORAGE_ENE_UB6250 is not set +CONFIG_USB_UAS=y + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USBIP_CORE is not set + +# +# USB dual-mode controller drivers +# +# CONFIG_USB_CDNS_SUPPORT is not set +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_DWC3 is not set +CONFIG_USB_DWC2=y +# CONFIG_USB_DWC2_HOST is not set + +# +# Gadget/Dual-role mode requires USB Gadget support to be enabled +# +# CONFIG_USB_DWC2_PERIPHERAL is not set +CONFIG_USB_DWC2_DUAL_ROLE=y +# CONFIG_USB_DWC2_DEBUG is not set +# CONFIG_USB_DWC2_TRACK_MISSED_SOFS is not set +# CONFIG_USB_CHIPIDEA is not set +# CONFIG_USB_ISP1760 is not set + +# +# USB port drivers +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_APPLE_MFI_FASTCHARGE is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_EHSET_TEST_FIXTURE is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_YUREX is not set +# CONFIG_USB_EZUSB_FX2 is not set +# CONFIG_USB_HUB_USB251XB is not set +# CONFIG_USB_HSIC_USB3503 is not set +# CONFIG_USB_HSIC_USB4604 is not set +# CONFIG_USB_LINK_LAYER_TEST is not set +# CONFIG_USB_CHAOSKEY is not set +# CONFIG_USB_ONBOARD_DEV is not set + +# +# USB Physical Layer drivers +# +CONFIG_USB_PHY=y +CONFIG_NOP_USB_XCEIV=y +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_ISP1301 is not set +CONFIG_USB_ULPI=y +CONFIG_USB_ULPI_VIEWPORT=y +# end of USB Physical Layer drivers + +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 + +# +# USB Peripheral Controller +# +# CONFIG_USB_GR_UDC is not set +# CONFIG_USB_R8A66597 is not set +# CONFIG_USB_PXA27X is not set +# CONFIG_USB_MV_UDC is not set +# CONFIG_USB_MV_U3D is not set +# CONFIG_USB_SNP_UDC_PLAT is not set +# CONFIG_USB_M66592 is not set +# CONFIG_USB_BDC_UDC is not set +# CONFIG_USB_NET2272 is not set +# CONFIG_USB_GADGET_XILINX is not set +# CONFIG_USB_MAX3420_UDC is not set +# CONFIG_USB_DUMMY_HCD is not set +# end of USB Peripheral Controller + +CONFIG_USB_LIBCOMPOSITE=y +CONFIG_USB_U_ETHER=y +CONFIG_USB_F_NCM=y +CONFIG_USB_F_ECM=y +CONFIG_USB_F_RNDIS=y +CONFIG_USB_F_MASS_STORAGE=y +CONFIG_USB_F_FS=y +CONFIG_USB_CONFIGFS=y +# CONFIG_USB_CONFIGFS_SERIAL is not set +# CONFIG_USB_CONFIGFS_ACM is not set +# CONFIG_USB_CONFIGFS_OBEX is not set +CONFIG_USB_CONFIGFS_NCM=y +CONFIG_USB_CONFIGFS_ECM=y +# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set +CONFIG_USB_CONFIGFS_RNDIS=y +# CONFIG_USB_CONFIGFS_EEM is not set +CONFIG_USB_CONFIGFS_MASS_STORAGE=y +# CONFIG_USB_CONFIGFS_F_LB_SS is not set +CONFIG_USB_CONFIGFS_F_FS=y +# CONFIG_USB_CONFIGFS_F_UAC1 is not set +# CONFIG_USB_CONFIGFS_F_UAC1_LEGACY is not set +# CONFIG_USB_CONFIGFS_F_UAC2 is not set +# CONFIG_USB_CONFIGFS_F_MIDI is not set +# CONFIG_USB_CONFIGFS_F_MIDI2 is not set +# CONFIG_USB_CONFIGFS_F_HID is not set +# CONFIG_USB_CONFIGFS_F_UVC is not set +# CONFIG_USB_CONFIGFS_F_PRINTER is not set + +# +# USB Gadget precomposed configurations +# +# CONFIG_USB_ZERO is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_G_NCM is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FUNCTIONFS is not set +# CONFIG_USB_MASS_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_ACM_MS is not set +# CONFIG_USB_G_MULTI is not set +# CONFIG_USB_G_HID is not set +# CONFIG_USB_G_DBGP is not set +# CONFIG_USB_G_WEBCAM is not set +# CONFIG_USB_RAW_GADGET is not set +# end of USB Gadget precomposed configurations + +# CONFIG_TYPEC is not set +CONFIG_USB_ROLE_SWITCH=y +CONFIG_MMC=y +CONFIG_PWRSEQ_EMMC=y +# CONFIG_PWRSEQ_SD8787 is not set +CONFIG_PWRSEQ_SIMPLE=y +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_MINORS=32 +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_ARMMMCI=y +CONFIG_MMC_STM32_SDMMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_OF_ARASAN=y +# CONFIG_MMC_SDHCI_OF_AT91 is not set +# CONFIG_MMC_SDHCI_OF_DWCMSHC is not set +# CONFIG_MMC_SDHCI_CADENCE is not set +# CONFIG_MMC_SDHCI_F_SDH30 is not set +# CONFIG_MMC_SDHCI_MILBEAUT is not set +CONFIG_MMC_SPI=y +CONFIG_MMC_DW=y +CONFIG_MMC_DW_PLTFM=y +# CONFIG_MMC_DW_BLUEFIELD is not set +# CONFIG_MMC_DW_EXYNOS is not set +# CONFIG_MMC_DW_HI3798CV200 is not set +# CONFIG_MMC_DW_HI3798MV200 is not set +CONFIG_MMC_DW_K3=y +CONFIG_MMC_DW_ROCKCHIP=y +# CONFIG_MMC_VUB300 is not set +# CONFIG_MMC_USHC is not set +# CONFIG_MMC_USDHI6ROL0 is not set +CONFIG_MMC_CQHCI=y +# CONFIG_MMC_HSQ is not set +# CONFIG_MMC_MTK is not set +# CONFIG_MMC_SDHCI_XENON is not set +# CONFIG_SCSI_UFSHCD is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_CLASS_FLASH=m +# CONFIG_LEDS_CLASS_MULTICOLOR is not set +# CONFIG_LEDS_BRIGHTNESS_HW_CHANGED is not set + +# +# LED drivers +# +# CONFIG_LEDS_AN30259A is not set +# CONFIG_LEDS_AW200XX is not set +# CONFIG_LEDS_AW2013 is not set +# CONFIG_LEDS_BCM6328 is not set +# CONFIG_LEDS_BCM6358 is not set +# CONFIG_LEDS_CR0014114 is not set +# CONFIG_LEDS_EL15203000 is not set +# CONFIG_LEDS_LM3530 is not set +# CONFIG_LEDS_LM3532 is not set +# CONFIG_LEDS_LM3642 is not set +# CONFIG_LEDS_LM3692X is not set +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_LP3952 is not set +# CONFIG_LEDS_LP8860 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_PCA963X is not set +# CONFIG_LEDS_PCA995X is not set +# CONFIG_LEDS_DAC124S085 is not set +CONFIG_LEDS_PWM=y +# CONFIG_LEDS_REGULATOR is not set +# CONFIG_LEDS_BD2606MVV is not set +# CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_LT3593 is not set +# CONFIG_LEDS_TCA6507 is not set +# CONFIG_LEDS_TLC591XX is not set +# CONFIG_LEDS_LM355x is not set +# CONFIG_LEDS_IS31FL319X is not set +# CONFIG_LEDS_IS31FL32XX is not set + +# +# LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) +# +# CONFIG_LEDS_BLINKM is not set +CONFIG_LEDS_SYSCON=y +# CONFIG_LEDS_MLXREG is not set +# CONFIG_LEDS_USER is not set +# CONFIG_LEDS_SPI_BYTE is not set +# CONFIG_LEDS_LM3697 is not set + +# +# Flash and Torch LED drivers +# +# CONFIG_LEDS_AAT1290 is not set +# CONFIG_LEDS_AS3645A is not set +# CONFIG_LEDS_KTD2692 is not set +# CONFIG_LEDS_LM3601X is not set +# CONFIG_LEDS_RT4505 is not set +# CONFIG_LEDS_RT8515 is not set +# CONFIG_LEDS_SGM3140 is not set +# CONFIG_LEDS_SY7802 is not set + +# +# RGB LED drivers +# + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_ONESHOT=y +# CONFIG_LEDS_TRIGGER_MTD is not set +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_LEDS_TRIGGER_ACTIVITY=y +CONFIG_LEDS_TRIGGER_GPIO=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_LEDS_TRIGGER_TRANSIENT is not set +# CONFIG_LEDS_TRIGGER_CAMERA is not set +CONFIG_LEDS_TRIGGER_PANIC=y +# CONFIG_LEDS_TRIGGER_NETDEV is not set +# CONFIG_LEDS_TRIGGER_PATTERN is not set +# CONFIG_LEDS_TRIGGER_TTY is not set +# CONFIG_LEDS_TRIGGER_INPUT_EVENTS is not set + +# +# Simple LED drivers +# +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +CONFIG_EDAC_SUPPORT=y +CONFIG_EDAC=y +CONFIG_EDAC_LEGACY_SYSFS=y +# CONFIG_EDAC_DEBUG is not set +# CONFIG_EDAC_XGENE is not set +# CONFIG_EDAC_DMC520 is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_SYSTOHC=y +CONFIG_RTC_SYSTOHC_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set +CONFIG_RTC_NVMEM=y + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_ABB5ZES3 is not set +# CONFIG_RTC_DRV_ABEOZ9 is not set +# CONFIG_RTC_DRV_ABX80X is not set +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_HYM8563 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_MAX31335 is not set +CONFIG_RTC_DRV_MAX77686=y +# CONFIG_RTC_DRV_NCT3018Y is not set +CONFIG_RTC_DRV_RK808=y +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_ISL12022 is not set +# CONFIG_RTC_DRV_ISL12026 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8523 is not set +# CONFIG_RTC_DRV_PCF85063 is not set +# CONFIG_RTC_DRV_PCF85363 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8010 is not set +# CONFIG_RTC_DRV_RX8111 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set +# CONFIG_RTC_DRV_EM3027 is not set +# CONFIG_RTC_DRV_RV3028 is not set +# CONFIG_RTC_DRV_RV3032 is not set +# CONFIG_RTC_DRV_RV8803 is not set +CONFIG_RTC_DRV_S5M=y +# CONFIG_RTC_DRV_SD2405AL is not set +# CONFIG_RTC_DRV_SD3078 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T93 is not set +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1302 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1343 is not set +# CONFIG_RTC_DRV_DS1347 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6916 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RX4581 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_PCF2123 is not set +# CONFIG_RTC_DRV_MCP795 is not set +CONFIG_RTC_I2C_AND_SPI=y + +# +# SPI and I2C RTC drivers +# +CONFIG_RTC_DRV_DS3232=y +CONFIG_RTC_DRV_DS3232_HWMON=y +# CONFIG_RTC_DRV_PCF2127 is not set +# CONFIG_RTC_DRV_RV3029C2 is not set +# CONFIG_RTC_DRV_RX6110 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1685_FAMILY is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_DS2404 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_OPTEE is not set +# CONFIG_RTC_DRV_ZYNQMP is not set + +# +# on-CPU RTC drivers +# +# CONFIG_RTC_DRV_PL030 is not set +CONFIG_RTC_DRV_PL031=y +# CONFIG_RTC_DRV_CADENCE is not set +# CONFIG_RTC_DRV_FTRTC010 is not set +# CONFIG_RTC_DRV_R7301 is not set + +# +# HID Sensor RTC drivers +# +# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set +# CONFIG_RTC_DRV_GOLDFISH is not set +CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +CONFIG_DMA_ENGINE=y +CONFIG_DMA_OF=y +# CONFIG_ALTERA_MSGDMA is not set +# CONFIG_AMBA_PL08X is not set +# CONFIG_BCM_SBA_RAID is not set +# CONFIG_DW_AXI_DMAC is not set +# CONFIG_FSL_EDMA is not set +# CONFIG_FSL_QDMA is not set +# CONFIG_INTEL_IDMA64 is not set +# CONFIG_MV_XOR_V2 is not set +CONFIG_PL330_DMA=y +# CONFIG_XILINX_DMA is not set +# CONFIG_XILINX_XDMA is not set +# CONFIG_XILINX_ZYNQMP_DMA is not set +# CONFIG_XILINX_ZYNQMP_DPDMA is not set +# CONFIG_AMD_QDMA is not set +# CONFIG_QCOM_HIDMA_MGMT is not set +# CONFIG_QCOM_HIDMA is not set +# CONFIG_DW_DMAC is not set +# CONFIG_SF_PDMA is not set + +# +# DMA Clients +# +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set + +# +# DMABUF options +# +CONFIG_SYNC_FILE=y +# CONFIG_SW_SYNC is not set +# CONFIG_UDMABUF is not set +# CONFIG_DMABUF_MOVE_NOTIFY is not set +# CONFIG_DMABUF_DEBUG is not set +# CONFIG_DMABUF_SELFTESTS is not set +CONFIG_DMABUF_HEAPS=y +# CONFIG_DMABUF_SYSFS_STATS is not set +CONFIG_DMABUF_HEAPS_SYSTEM=y +CONFIG_DMABUF_HEAPS_CMA=y +# end of DMABUF options + +# CONFIG_UIO is not set +CONFIG_VFIO=y +CONFIG_VFIO_GROUP=y +CONFIG_VFIO_CONTAINER=y +CONFIG_VFIO_IOMMU_TYPE1=y +# CONFIG_VFIO_NOIOMMU is not set +# CONFIG_VFIO_DEBUGFS is not set + +# +# VFIO support for platform devices +# +# CONFIG_VFIO_PLATFORM is not set +# CONFIG_VFIO_AMBA is not set +# end of VFIO support for platform devices + +# CONFIG_VIRT_DRIVERS is not set +# CONFIG_VIRTIO_MENU is not set +# CONFIG_VDPA is not set +CONFIG_VHOST_MENU=y +# CONFIG_VHOST_NET is not set +# CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set +CONFIG_VHOST_ENABLE_FORK_OWNER_CONTROL=y + +# +# Microsoft Hyper-V guest support +# +# end of Microsoft Hyper-V guest support + +# CONFIG_GREYBUS is not set +# CONFIG_COMEDI is not set +CONFIG_STAGING=y +# CONFIG_RTLLIB is not set +CONFIG_RTL8723BS=m +# CONFIG_VT6656 is not set + +# +# IIO staging drivers +# + +# +# Accelerometers +# +# CONFIG_ADIS16203 is not set +# CONFIG_ADIS16240 is not set +# end of Accelerometers + +# +# Analog to digital converters +# +# CONFIG_AD7816 is not set +# end of Analog to digital converters + +# +# Analog digital bi-direction converters +# +# CONFIG_ADT7316 is not set +# end of Analog digital bi-direction converters + +# +# Direct Digital Synthesis +# +# CONFIG_AD9832 is not set +# CONFIG_AD9834 is not set +# end of Direct Digital Synthesis + +# +# Network Analyzer, Impedance Converters +# +# CONFIG_AD5933 is not set +# end of Network Analyzer, Impedance Converters +# end of IIO staging drivers + +CONFIG_STAGING_MEDIA=y +# CONFIG_VIDEO_MAX96712 is not set +CONFIG_VIDEO_ROCKCHIP_VDEC=m + +# +# StarFive media platform drivers +# +# CONFIG_STAGING_MEDIA_DEPRECATED is not set +# CONFIG_LTE_GDM724X is not set +# CONFIG_FB_TFT is not set +# CONFIG_XIL_AXIS_FIFO is not set +# CONFIG_FIELDBUS_DEV is not set +# CONFIG_GOLDFISH is not set +# CONFIG_CHROME_PLATFORMS is not set +# CONFIG_MELLANOX_PLATFORM is not set +# CONFIG_SURFACE_PLATFORMS is not set +CONFIG_ARM64_PLATFORM_DEVICES=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_COMMON_CLK=y + +# +# Clock driver for ARM Reference designs +# +# CONFIG_CLK_ICST is not set +# CONFIG_CLK_SP810 is not set +# end of Clock driver for ARM Reference designs + +# CONFIG_LMK04832 is not set +# CONFIG_COMMON_CLK_MAX77686 is not set +# CONFIG_COMMON_CLK_MAX9485 is not set +CONFIG_COMMON_CLK_RK808=y +# CONFIG_COMMON_CLK_SCMI is not set +CONFIG_COMMON_CLK_SCPI=y +# CONFIG_COMMON_CLK_SI5341 is not set +# CONFIG_COMMON_CLK_SI5351 is not set +# CONFIG_COMMON_CLK_SI514 is not set +# CONFIG_COMMON_CLK_SI544 is not set +# CONFIG_COMMON_CLK_SI570 is not set +# CONFIG_COMMON_CLK_CDCE706 is not set +# CONFIG_COMMON_CLK_CDCE925 is not set +CONFIG_COMMON_CLK_CS2000_CP=y +CONFIG_COMMON_CLK_S2MPS11=y +# CONFIG_COMMON_CLK_AXI_CLKGEN is not set +CONFIG_COMMON_CLK_XGENE=y +CONFIG_COMMON_CLK_PWM=y +# CONFIG_COMMON_CLK_RS9_PCIE is not set +# CONFIG_COMMON_CLK_SI521XX is not set +# CONFIG_COMMON_CLK_VC3 is not set +# CONFIG_COMMON_CLK_VC5 is not set +# CONFIG_COMMON_CLK_VC7 is not set +# CONFIG_COMMON_CLK_FIXED_MMIO is not set +CONFIG_COMMON_CLK_ROCKCHIP=y +CONFIG_CLK_PX30=y +CONFIG_CLK_RK3308=y +CONFIG_CLK_RK3328=y +CONFIG_CLK_RK3368=y +CONFIG_CLK_RK3399=y +CONFIG_CLK_RK3568=y +CONFIG_CLK_RK3576=y +CONFIG_CLK_RK3588=y +# CONFIG_XILINX_VCU is not set +# CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set +CONFIG_HWSPINLOCK=y + +# +# Clock Source drivers +# +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +CONFIG_CLKSRC_MMIO=y +CONFIG_ROCKCHIP_TIMER=y +CONFIG_ARM_ARCH_TIMER=y +CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y +CONFIG_FSL_ERRATUM_A008585=y +CONFIG_HISILICON_ERRATUM_161010101=y +CONFIG_ARM64_ERRATUM_858921=y +# CONFIG_ARM_TIMER_SP804 is not set +# end of Clock Source drivers + +CONFIG_MAILBOX=y +CONFIG_ARM_MHU=y +# CONFIG_ARM_MHU_V2 is not set +# CONFIG_ARM_MHU_V3 is not set +CONFIG_PLATFORM_MHU=y +# CONFIG_PL320_MBOX is not set +CONFIG_ROCKCHIP_MBOX=y +# CONFIG_ALTERA_MBOX is not set +# CONFIG_MAILBOX_TEST is not set +CONFIG_IOMMU_IOVA=y +CONFIG_IOMMU_API=y +CONFIG_IOMMU_SUPPORT=y + +# +# Generic IOMMU Pagetable Support +# +CONFIG_IOMMU_IO_PGTABLE=y +CONFIG_IOMMU_IO_PGTABLE_LPAE=y +# CONFIG_IOMMU_IO_PGTABLE_LPAE_SELFTEST is not set +# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set +# CONFIG_IOMMU_IO_PGTABLE_DART is not set +# end of Generic IOMMU Pagetable Support + +# CONFIG_IOMMU_DEBUGFS is not set +CONFIG_IOMMU_DEFAULT_DMA_STRICT=y +# CONFIG_IOMMU_DEFAULT_DMA_LAZY is not set +# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set +CONFIG_OF_IOMMU=y +CONFIG_IOMMU_DMA=y +# CONFIG_IOMMUFD is not set +CONFIG_ROCKCHIP_IOMMU=y +CONFIG_ARM_SMMU=y +# CONFIG_ARM_SMMU_LEGACY_DT_BINDINGS is not set +CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT=y +CONFIG_ARM_SMMU_V3=y +# CONFIG_ARM_SMMU_V3_SVA is not set + +# +# Remoteproc drivers +# +# CONFIG_REMOTEPROC is not set +# end of Remoteproc drivers + +# +# Rpmsg drivers +# +# CONFIG_RPMSG_QCOM_GLINK_RPM is not set +# CONFIG_RPMSG_VIRTIO is not set +# end of Rpmsg drivers + +# CONFIG_SOUNDWIRE is not set + +# +# SOC (System On Chip) specific Drivers +# + +# +# Amlogic SoC drivers +# +# end of Amlogic SoC drivers + +# +# Broadcom SoC drivers +# +# end of Broadcom SoC drivers + +# +# NXP/Freescale QorIQ SoC drivers +# +# CONFIG_QUICC_ENGINE is not set +# CONFIG_FSL_RCPM is not set +# end of NXP/Freescale QorIQ SoC drivers + +# +# fujitsu SoC drivers +# +# end of fujitsu SoC drivers + +# +# i.MX SoC drivers +# +# end of i.MX SoC drivers + +# +# Enable LiteX SoC Builder specific drivers +# +# CONFIG_LITEX_SOC_CONTROLLER is not set +# end of Enable LiteX SoC Builder specific drivers + +# CONFIG_WPCM450_SOC is not set + +# +# Qualcomm SoC drivers +# +# CONFIG_QCOM_PBS is not set +# end of Qualcomm SoC drivers + +CONFIG_ROCKCHIP_GRF=y +CONFIG_ROCKCHIP_IODOMAIN=y +# CONFIG_SOC_TI is not set + +# +# Xilinx SoC drivers +# +# end of Xilinx SoC drivers +# end of SOC (System On Chip) specific Drivers + +# +# PM Domains +# + +# +# Amlogic PM Domains +# +# end of Amlogic PM Domains + +CONFIG_ARM_SCMI_PERF_DOMAIN=m +CONFIG_ARM_SCMI_POWER_DOMAIN=m +CONFIG_ARM_SCPI_POWER_DOMAIN=y + +# +# Broadcom PM Domains +# +# end of Broadcom PM Domains + +# +# i.MX PM Domains +# +# end of i.MX PM Domains + +# +# Qualcomm PM Domains +# +# end of Qualcomm PM Domains + +CONFIG_ROCKCHIP_PM_DOMAINS=y +# end of PM Domains + +CONFIG_PM_DEVFREQ=y + +# +# DEVFREQ Governors +# +CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y +CONFIG_DEVFREQ_GOV_PERFORMANCE=y +CONFIG_DEVFREQ_GOV_POWERSAVE=y +CONFIG_DEVFREQ_GOV_USERSPACE=y +CONFIG_DEVFREQ_GOV_PASSIVE=y + +# +# DEVFREQ Drivers +# +CONFIG_ARM_RK3399_DMC_DEVFREQ=y +CONFIG_PM_DEVFREQ_EVENT=y +CONFIG_DEVFREQ_EVENT_ROCKCHIP_DFI=y +CONFIG_EXTCON=y + +# +# Extcon Device Drivers +# +# CONFIG_EXTCON_ADC_JACK is not set +# CONFIG_EXTCON_FSA9480 is not set +# CONFIG_EXTCON_GPIO is not set +# CONFIG_EXTCON_LC824206XA is not set +# CONFIG_EXTCON_MAX3355 is not set +# CONFIG_EXTCON_PTN5150 is not set +# CONFIG_EXTCON_RT8973A is not set +# CONFIG_EXTCON_SM5502 is not set +CONFIG_EXTCON_USB_GPIO=y +# CONFIG_MEMORY is not set +CONFIG_IIO=y +CONFIG_IIO_BUFFER=y +CONFIG_IIO_BUFFER_CB=y +# CONFIG_IIO_BUFFER_DMA is not set +# CONFIG_IIO_BUFFER_DMAENGINE is not set +# CONFIG_IIO_BUFFER_HW_CONSUMER is not set +CONFIG_IIO_KFIFO_BUF=y +CONFIG_IIO_TRIGGERED_BUFFER=y +# CONFIG_IIO_CONFIGFS is not set +CONFIG_IIO_TRIGGER=y +CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 +# CONFIG_IIO_SW_DEVICE is not set +# CONFIG_IIO_SW_TRIGGER is not set +# CONFIG_IIO_TRIGGERED_EVENT is not set + +# +# Accelerometers +# +# CONFIG_ADIS16201 is not set +# CONFIG_ADIS16209 is not set +# CONFIG_ADXL313_I2C is not set +# CONFIG_ADXL313_SPI is not set +# CONFIG_ADXL345_I2C is not set +# CONFIG_ADXL345_SPI is not set +# CONFIG_ADXL355_I2C is not set +# CONFIG_ADXL355_SPI is not set +# CONFIG_ADXL367_SPI is not set +# CONFIG_ADXL367_I2C is not set +# CONFIG_ADXL372_SPI is not set +# CONFIG_ADXL372_I2C is not set +# CONFIG_ADXL380_SPI is not set +# CONFIG_ADXL380_I2C is not set +# CONFIG_BMA180 is not set +# CONFIG_BMA220 is not set +# CONFIG_BMA400 is not set +# CONFIG_BMC150_ACCEL is not set +# CONFIG_BMI088_ACCEL is not set +# CONFIG_DA280 is not set +# CONFIG_DA311 is not set +# CONFIG_DMARD06 is not set +# CONFIG_DMARD09 is not set +# CONFIG_DMARD10 is not set +# CONFIG_FXLS8962AF_I2C is not set +# CONFIG_FXLS8962AF_SPI is not set +# CONFIG_HID_SENSOR_ACCEL_3D is not set +# CONFIG_IIO_ST_ACCEL_3AXIS is not set +# CONFIG_IIO_KX022A_SPI is not set +# CONFIG_IIO_KX022A_I2C is not set +# CONFIG_KXSD9 is not set +# CONFIG_KXCJK1013 is not set +# CONFIG_MC3230 is not set +# CONFIG_MMA7455_I2C is not set +# CONFIG_MMA7455_SPI is not set +# CONFIG_MMA7660 is not set +# CONFIG_MMA8452 is not set +# CONFIG_MMA9551 is not set +# CONFIG_MMA9553 is not set +# CONFIG_MSA311 is not set +# CONFIG_MXC4005 is not set +# CONFIG_MXC6255 is not set +# CONFIG_SCA3000 is not set +# CONFIG_SCA3300 is not set +# CONFIG_STK8312 is not set +# CONFIG_STK8BA50 is not set +# end of Accelerometers + +# +# Analog to digital converters +# +# CONFIG_AD4000 is not set +# CONFIG_AD4130 is not set +# CONFIG_AD4695 is not set +# CONFIG_AD7091R5 is not set +# CONFIG_AD7091R8 is not set +# CONFIG_AD7124 is not set +# CONFIG_AD7173 is not set +# CONFIG_AD7192 is not set +# CONFIG_AD7266 is not set +# CONFIG_AD7280 is not set +# CONFIG_AD7291 is not set +# CONFIG_AD7292 is not set +# CONFIG_AD7298 is not set +# CONFIG_AD7380 is not set +# CONFIG_AD7476 is not set +# CONFIG_AD7606_IFACE_PARALLEL is not set +# CONFIG_AD7606_IFACE_SPI is not set +# CONFIG_AD7766 is not set +# CONFIG_AD7768_1 is not set +# CONFIG_AD7780 is not set +# CONFIG_AD7791 is not set +# CONFIG_AD7793 is not set +# CONFIG_AD7887 is not set +# CONFIG_AD7923 is not set +# CONFIG_AD7944 is not set +# CONFIG_AD7949 is not set +# CONFIG_AD799X is not set +# CONFIG_AD9467 is not set +# CONFIG_CC10001_ADC is not set +# CONFIG_ENVELOPE_DETECTOR is not set +# CONFIG_HI8435 is not set +# CONFIG_HX711 is not set +# CONFIG_INA2XX_ADC is not set +# CONFIG_LTC2309 is not set +# CONFIG_LTC2471 is not set +# CONFIG_LTC2485 is not set +# CONFIG_LTC2496 is not set +# CONFIG_LTC2497 is not set +# CONFIG_MAX1027 is not set +# CONFIG_MAX11100 is not set +# CONFIG_MAX1118 is not set +# CONFIG_MAX11205 is not set +# CONFIG_MAX11410 is not set +# CONFIG_MAX1241 is not set +# CONFIG_MAX1363 is not set +# CONFIG_MAX34408 is not set +# CONFIG_MAX9611 is not set +# CONFIG_MCP320X is not set +# CONFIG_MCP3422 is not set +# CONFIG_MCP3564 is not set +# CONFIG_MCP3911 is not set +# CONFIG_NAU7802 is not set +# CONFIG_PAC1921 is not set +# CONFIG_PAC1934 is not set +# CONFIG_QCOM_SPMI_IADC is not set +# CONFIG_QCOM_SPMI_VADC is not set +# CONFIG_QCOM_SPMI_ADC5 is not set +CONFIG_ROCKCHIP_SARADC=y +# CONFIG_RICHTEK_RTQ6056 is not set +# CONFIG_SD_ADC_MODULATOR is not set +# CONFIG_TI_ADC081C is not set +# CONFIG_TI_ADC0832 is not set +# CONFIG_TI_ADC084S021 is not set +# CONFIG_TI_ADC12138 is not set +# CONFIG_TI_ADC108S102 is not set +# CONFIG_TI_ADC128S052 is not set +# CONFIG_TI_ADC161S626 is not set +# CONFIG_TI_ADS1015 is not set +# CONFIG_TI_ADS1119 is not set +# CONFIG_TI_ADS7924 is not set +# CONFIG_TI_ADS1100 is not set +# CONFIG_TI_ADS1298 is not set +# CONFIG_TI_ADS7950 is not set +# CONFIG_TI_ADS8344 is not set +# CONFIG_TI_ADS8688 is not set +# CONFIG_TI_ADS124S08 is not set +# CONFIG_TI_ADS131E08 is not set +# CONFIG_TI_LMP92064 is not set +# CONFIG_TI_TLC4541 is not set +# CONFIG_TI_TSC2046 is not set +# CONFIG_VF610_ADC is not set +# CONFIG_XILINX_XADC is not set +# end of Analog to digital converters + +# +# Analog to digital and digital to analog converters +# +# CONFIG_AD74115 is not set +# CONFIG_AD74413R is not set +# end of Analog to digital and digital to analog converters + +# +# Analog Front Ends +# +# CONFIG_IIO_RESCALE is not set +# end of Analog Front Ends + +# +# Amplifiers +# +# CONFIG_AD8366 is not set +# CONFIG_ADA4250 is not set +# CONFIG_HMC425 is not set +# end of Amplifiers + +# +# Capacitance to digital converters +# +# CONFIG_AD7150 is not set +# CONFIG_AD7746 is not set +# end of Capacitance to digital converters + +# +# Chemical Sensors +# +# CONFIG_AOSONG_AGS02MA is not set +# CONFIG_ATLAS_PH_SENSOR is not set +# CONFIG_ATLAS_EZO_SENSOR is not set +# CONFIG_BME680 is not set +# CONFIG_CCS811 is not set +# CONFIG_ENS160 is not set +# CONFIG_IAQCORE is not set +# CONFIG_PMS7003 is not set +# CONFIG_SCD30_CORE is not set +# CONFIG_SCD4X is not set +# CONFIG_SENSIRION_SGP30 is not set +# CONFIG_SENSIRION_SGP40 is not set +# CONFIG_SPS30_I2C is not set +# CONFIG_SPS30_SERIAL is not set +# CONFIG_SENSEAIR_SUNRISE_CO2 is not set +# CONFIG_VZ89X is not set +# end of Chemical Sensors + +# +# Hid Sensor IIO Common +# +# CONFIG_HID_SENSOR_IIO_COMMON is not set +# end of Hid Sensor IIO Common + +# +# IIO SCMI Sensors +# +# CONFIG_IIO_SCMI is not set +# end of IIO SCMI Sensors + +# +# SSP Sensor Common +# +# CONFIG_IIO_SSP_SENSORHUB is not set +# end of SSP Sensor Common + +# +# Digital to analog converters +# +# CONFIG_AD3552R is not set +# CONFIG_AD5064 is not set +# CONFIG_AD5360 is not set +# CONFIG_AD5380 is not set +# CONFIG_AD5421 is not set +# CONFIG_AD5446 is not set +# CONFIG_AD5449 is not set +# CONFIG_AD5592R is not set +# CONFIG_AD5593R is not set +# CONFIG_AD5504 is not set +# CONFIG_AD5624R_SPI is not set +# CONFIG_AD9739A is not set +# CONFIG_LTC2688 is not set +# CONFIG_AD5686_SPI is not set +# CONFIG_AD5696_I2C is not set +# CONFIG_AD5755 is not set +# CONFIG_AD5758 is not set +# CONFIG_AD5761 is not set +# CONFIG_AD5764 is not set +# CONFIG_AD5766 is not set +# CONFIG_AD5770R is not set +# CONFIG_AD5791 is not set +# CONFIG_AD7293 is not set +# CONFIG_AD7303 is not set +# CONFIG_AD8801 is not set +# CONFIG_DPOT_DAC is not set +# CONFIG_DS4424 is not set +# CONFIG_LTC1660 is not set +# CONFIG_LTC2632 is not set +# CONFIG_LTC2664 is not set +# CONFIG_M62332 is not set +# CONFIG_MAX517 is not set +# CONFIG_MAX5522 is not set +# CONFIG_MAX5821 is not set +# CONFIG_MCP4725 is not set +# CONFIG_MCP4728 is not set +# CONFIG_MCP4821 is not set +# CONFIG_MCP4922 is not set +# CONFIG_TI_DAC082S085 is not set +# CONFIG_TI_DAC5571 is not set +# CONFIG_TI_DAC7311 is not set +# CONFIG_TI_DAC7612 is not set +# CONFIG_VF610_DAC is not set +# end of Digital to analog converters + +# +# IIO dummy driver +# +# end of IIO dummy driver + +# +# Filters +# +# CONFIG_ADMV8818 is not set +# end of Filters + +# +# Frequency Synthesizers DDS/PLL +# + +# +# Clock Generator/Distribution +# +# CONFIG_AD9523 is not set +# end of Clock Generator/Distribution + +# +# Phase-Locked Loop (PLL) frequency synthesizers +# +# CONFIG_ADF4350 is not set +# CONFIG_ADF4371 is not set +# CONFIG_ADF4377 is not set +# CONFIG_ADMFM2000 is not set +# CONFIG_ADMV1013 is not set +# CONFIG_ADMV1014 is not set +# CONFIG_ADMV4420 is not set +# CONFIG_ADRF6780 is not set +# end of Phase-Locked Loop (PLL) frequency synthesizers +# end of Frequency Synthesizers DDS/PLL + +# +# Digital gyroscope sensors +# +# CONFIG_ADIS16080 is not set +# CONFIG_ADIS16130 is not set +# CONFIG_ADIS16136 is not set +# CONFIG_ADIS16260 is not set +# CONFIG_ADXRS290 is not set +# CONFIG_ADXRS450 is not set +# CONFIG_BMG160 is not set +# CONFIG_FXAS21002C is not set +# CONFIG_HID_SENSOR_GYRO_3D is not set +# CONFIG_MPU3050_I2C is not set +# CONFIG_IIO_ST_GYRO_3AXIS is not set +# CONFIG_ITG3200 is not set +# end of Digital gyroscope sensors + +# +# Health Sensors +# + +# +# Heart Rate Monitors +# +# CONFIG_AFE4403 is not set +# CONFIG_AFE4404 is not set +# CONFIG_MAX30100 is not set +# CONFIG_MAX30102 is not set +# end of Heart Rate Monitors +# end of Health Sensors + +# +# Humidity sensors +# +# CONFIG_AM2315 is not set +# CONFIG_DHT11 is not set +# CONFIG_ENS210 is not set +# CONFIG_HDC100X is not set +# CONFIG_HDC2010 is not set +# CONFIG_HDC3020 is not set +# CONFIG_HID_SENSOR_HUMIDITY is not set +# CONFIG_HTS221 is not set +# CONFIG_HTU21 is not set +# CONFIG_SI7005 is not set +# CONFIG_SI7020 is not set +# end of Humidity sensors + +# +# Inertial measurement units +# +# CONFIG_ADIS16400 is not set +# CONFIG_ADIS16460 is not set +# CONFIG_ADIS16475 is not set +# CONFIG_ADIS16480 is not set +# CONFIG_BMI160_I2C is not set +# CONFIG_BMI160_SPI is not set +# CONFIG_BMI323_I2C is not set +# CONFIG_BMI323_SPI is not set +# CONFIG_BOSCH_BNO055_SERIAL is not set +# CONFIG_BOSCH_BNO055_I2C is not set +# CONFIG_FXOS8700_I2C is not set +# CONFIG_FXOS8700_SPI is not set +# CONFIG_KMX61 is not set +# CONFIG_INV_ICM42600_I2C is not set +# CONFIG_INV_ICM42600_SPI is not set +# CONFIG_INV_MPU6050_I2C is not set +# CONFIG_INV_MPU6050_SPI is not set +# CONFIG_IIO_ST_LSM6DSX is not set +# CONFIG_IIO_ST_LSM9DS0 is not set +# end of Inertial measurement units + +# +# Light sensors +# +# CONFIG_ADJD_S311 is not set +# CONFIG_ADUX1020 is not set +# CONFIG_AL3010 is not set +# CONFIG_AL3320A is not set +# CONFIG_APDS9300 is not set +# CONFIG_APDS9306 is not set +# CONFIG_APDS9960 is not set +# CONFIG_AS73211 is not set +# CONFIG_BH1745 is not set +# CONFIG_BH1750 is not set +# CONFIG_BH1780 is not set +# CONFIG_CM32181 is not set +# CONFIG_CM3232 is not set +# CONFIG_CM3323 is not set +# CONFIG_CM3605 is not set +# CONFIG_CM36651 is not set +# CONFIG_GP2AP002 is not set +# CONFIG_GP2AP020A00F is not set +# CONFIG_SENSORS_ISL29018 is not set +# CONFIG_SENSORS_ISL29028 is not set +# CONFIG_ISL29125 is not set +# CONFIG_ISL76682 is not set +# CONFIG_HID_SENSOR_ALS is not set +# CONFIG_HID_SENSOR_PROX is not set +# CONFIG_JSA1212 is not set +# CONFIG_ROHM_BU27008 is not set +# CONFIG_ROHM_BU27034 is not set +# CONFIG_RPR0521 is not set +# CONFIG_LTR390 is not set +# CONFIG_LTR501 is not set +# CONFIG_LTRF216A is not set +# CONFIG_LV0104CS is not set +# CONFIG_MAX44000 is not set +# CONFIG_MAX44009 is not set +# CONFIG_NOA1305 is not set +# CONFIG_OPT3001 is not set +# CONFIG_OPT4001 is not set +# CONFIG_PA12203001 is not set +# CONFIG_SI1133 is not set +# CONFIG_SI1145 is not set +# CONFIG_STK3310 is not set +# CONFIG_ST_UVIS25 is not set +# CONFIG_TCS3414 is not set +# CONFIG_TCS3472 is not set +# CONFIG_SENSORS_TSL2563 is not set +# CONFIG_TSL2583 is not set +# CONFIG_TSL2591 is not set +# CONFIG_TSL2772 is not set +# CONFIG_TSL4531 is not set +# CONFIG_US5182D is not set +# CONFIG_VCNL4000 is not set +# CONFIG_VCNL4035 is not set +# CONFIG_VEML6030 is not set +# CONFIG_VEML6040 is not set +# CONFIG_VEML6070 is not set +# CONFIG_VEML6075 is not set +# CONFIG_VL6180 is not set +# CONFIG_ZOPT2201 is not set +# end of Light sensors + +# +# Magnetometer sensors +# +# CONFIG_AF8133J is not set +# CONFIG_AK8974 is not set +# CONFIG_AK8975 is not set +# CONFIG_AK09911 is not set +# CONFIG_BMC150_MAGN_I2C is not set +# CONFIG_BMC150_MAGN_SPI is not set +# CONFIG_MAG3110 is not set +# CONFIG_HID_SENSOR_MAGNETOMETER_3D is not set +# CONFIG_MMC35240 is not set +# CONFIG_IIO_ST_MAGN_3AXIS is not set +# CONFIG_SENSORS_HMC5843_I2C is not set +# CONFIG_SENSORS_HMC5843_SPI is not set +# CONFIG_SENSORS_RM3100_I2C is not set +# CONFIG_SENSORS_RM3100_SPI is not set +# CONFIG_TI_TMAG5273 is not set +# CONFIG_YAMAHA_YAS530 is not set +# end of Magnetometer sensors + +# +# Multiplexers +# +CONFIG_IIO_MUX=y +# end of Multiplexers + +# +# Inclinometer sensors +# +# CONFIG_HID_SENSOR_INCLINOMETER_3D is not set +# CONFIG_HID_SENSOR_DEVICE_ROTATION is not set +# end of Inclinometer sensors + +# +# Triggers - standalone +# +# CONFIG_IIO_INTERRUPT_TRIGGER is not set +# CONFIG_IIO_SYSFS_TRIGGER is not set +# end of Triggers - standalone + +# +# Linear and angular position sensors +# +# CONFIG_HID_SENSOR_CUSTOM_INTEL_HINGE is not set +# end of Linear and angular position sensors + +# +# Digital potentiometers +# +# CONFIG_AD5110 is not set +# CONFIG_AD5272 is not set +# CONFIG_DS1803 is not set +# CONFIG_MAX5432 is not set +# CONFIG_MAX5481 is not set +# CONFIG_MAX5487 is not set +# CONFIG_MCP4018 is not set +# CONFIG_MCP4131 is not set +# CONFIG_MCP4531 is not set +# CONFIG_MCP41010 is not set +# CONFIG_TPL0102 is not set +# CONFIG_X9250 is not set +# end of Digital potentiometers + +# +# Digital potentiostats +# +# CONFIG_LMP91000 is not set +# end of Digital potentiostats + +# +# Pressure sensors +# +# CONFIG_ABP060MG is not set +# CONFIG_ROHM_BM1390 is not set +# CONFIG_BMP280 is not set +# CONFIG_DLHL60D is not set +# CONFIG_DPS310 is not set +# CONFIG_HID_SENSOR_PRESS is not set +# CONFIG_HP03 is not set +# CONFIG_HSC030PA is not set +# CONFIG_ICP10100 is not set +# CONFIG_MPL115_I2C is not set +# CONFIG_MPL115_SPI is not set +# CONFIG_MPL3115 is not set +# CONFIG_MPRLS0025PA is not set +# CONFIG_MS5611 is not set +# CONFIG_MS5637 is not set +# CONFIG_SDP500 is not set +# CONFIG_IIO_ST_PRESS is not set +# CONFIG_T5403 is not set +# CONFIG_HP206C is not set +# CONFIG_ZPA2326 is not set +# end of Pressure sensors + +# +# Lightning sensors +# +# CONFIG_AS3935 is not set +# end of Lightning sensors + +# +# Proximity and distance sensors +# +# CONFIG_HX9023S is not set +# CONFIG_IRSD200 is not set +# CONFIG_ISL29501 is not set +# CONFIG_LIDAR_LITE_V2 is not set +# CONFIG_MB1232 is not set +# CONFIG_PING is not set +# CONFIG_RFD77402 is not set +# CONFIG_SRF04 is not set +# CONFIG_SX9310 is not set +# CONFIG_SX9324 is not set +# CONFIG_SX9360 is not set +# CONFIG_SX9500 is not set +# CONFIG_SRF08 is not set +# CONFIG_VCNL3020 is not set +# CONFIG_VL53L0X_I2C is not set +# CONFIG_AW96103 is not set +# end of Proximity and distance sensors + +# +# Resolver to digital converters +# +# CONFIG_AD2S90 is not set +# CONFIG_AD2S1200 is not set +# CONFIG_AD2S1210 is not set +# end of Resolver to digital converters + +# +# Temperature sensors +# +# CONFIG_LTC2983 is not set +# CONFIG_MAXIM_THERMOCOUPLE is not set +# CONFIG_HID_SENSOR_TEMP is not set +# CONFIG_MLX90614 is not set +# CONFIG_MLX90632 is not set +# CONFIG_MLX90635 is not set +# CONFIG_TMP006 is not set +# CONFIG_TMP007 is not set +# CONFIG_TMP117 is not set +# CONFIG_TSYS01 is not set +# CONFIG_TSYS02D is not set +# CONFIG_MAX30208 is not set +# CONFIG_MAX31856 is not set +# CONFIG_MAX31865 is not set +# CONFIG_MCP9600 is not set +# end of Temperature sensors + +CONFIG_PWM=y +# CONFIG_PWM_DEBUG is not set +# CONFIG_PWM_ATMEL_TCB is not set +# CONFIG_PWM_CLK is not set +# CONFIG_PWM_FSL_FTM is not set +# CONFIG_PWM_GPIO is not set +# CONFIG_PWM_PCA9685 is not set +CONFIG_PWM_ROCKCHIP=y +# CONFIG_PWM_XILINX is not set + +# +# IRQ chip support +# +CONFIG_IRQCHIP=y +CONFIG_ARM_GIC=y +CONFIG_ARM_GIC_MAX_NR=1 +CONFIG_ARM_GIC_V3=y +CONFIG_ARM_GIC_V3_ITS=y +CONFIG_IRQ_MSI_LIB=y +# CONFIG_AL_FIC is not set +# CONFIG_XILINX_INTC is not set +CONFIG_PARTITION_PERCPU=y +# end of IRQ chip support + +# CONFIG_IPACK_BUS is not set +CONFIG_ARCH_HAS_RESET_CONTROLLER=y +CONFIG_RESET_CONTROLLER=y +# CONFIG_RESET_GPIO is not set +CONFIG_RESET_SCMI=m +# CONFIG_RESET_SIMPLE is not set +# CONFIG_RESET_TI_SYSCON is not set +# CONFIG_RESET_TI_TPS380X is not set + +# +# PHY Subsystem +# +CONFIG_GENERIC_PHY=y +CONFIG_GENERIC_PHY_MIPI_DPHY=y +# CONFIG_PHY_CAN_TRANSCEIVER is not set + +# +# PHY drivers for Broadcom platforms +# +# CONFIG_BCM_KONA_USB2_PHY is not set +# end of PHY drivers for Broadcom platforms + +# CONFIG_PHY_CADENCE_TORRENT is not set +# CONFIG_PHY_CADENCE_DPHY is not set +# CONFIG_PHY_CADENCE_DPHY_RX is not set +# CONFIG_PHY_CADENCE_SIERRA is not set +# CONFIG_PHY_CADENCE_SALVO is not set +# CONFIG_PHY_PXA_28NM_HSIC is not set +# CONFIG_PHY_PXA_28NM_USB2 is not set +# CONFIG_PHY_LAN966X_SERDES is not set +# CONFIG_PHY_CPCAP_USB is not set +# CONFIG_PHY_MAPPHONE_MDM6600 is not set +# CONFIG_PHY_OCELOT_SERDES is not set +# CONFIG_PHY_QCOM_USB_HS is not set +# CONFIG_PHY_QCOM_USB_HSIC is not set +CONFIG_PHY_ROCKCHIP_DP=y +CONFIG_PHY_ROCKCHIP_DPHY_RX0=y +CONFIG_PHY_ROCKCHIP_EMMC=y +CONFIG_PHY_ROCKCHIP_INNO_HDMI=y +CONFIG_PHY_ROCKCHIP_INNO_USB2=y +# CONFIG_PHY_ROCKCHIP_INNO_CSIDPHY is not set +CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY=y +# CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY is not set +CONFIG_PHY_ROCKCHIP_PCIE=y +# CONFIG_PHY_ROCKCHIP_SAMSUNG_HDPTX is not set +# CONFIG_PHY_ROCKCHIP_SNPS_PCIE3 is not set +CONFIG_PHY_ROCKCHIP_TYPEC=y +CONFIG_PHY_ROCKCHIP_USB=y +# CONFIG_PHY_SAMSUNG_USB2 is not set +# CONFIG_PHY_TUSB1210 is not set +# end of PHY Subsystem + +# CONFIG_POWERCAP is not set +# CONFIG_MCB is not set + +# +# Performance monitor support +# +# CONFIG_ARM_CCI_PMU is not set +# CONFIG_ARM_CCN is not set +# CONFIG_ARM_CMN is not set +# CONFIG_ARM_NI is not set +CONFIG_ARM_PMU=y +# CONFIG_ARM_SMMU_V3_PMU is not set +CONFIG_ARM_PMUV3=y +# CONFIG_ARM_DSU_PMU is not set +# CONFIG_ARM_SPE_PMU is not set +# CONFIG_ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU is not set +# end of Performance monitor support + +CONFIG_RAS=y + +# +# Android +# +# CONFIG_ANDROID_BINDER_IPC is not set +# end of Android + +# CONFIG_LIBNVDIMM is not set +# CONFIG_DAX is not set +CONFIG_NVMEM=y +CONFIG_NVMEM_SYSFS=y +CONFIG_NVMEM_LAYOUTS=y + +# +# Layout Types +# +# CONFIG_NVMEM_LAYOUT_SL28_VPD is not set +# CONFIG_NVMEM_LAYOUT_ONIE_TLV is not set +# CONFIG_NVMEM_LAYOUT_U_BOOT_ENV is not set +# end of Layout Types + +# CONFIG_NVMEM_RMEM is not set +# CONFIG_NVMEM_ROCKCHIP_EFUSE is not set +CONFIG_NVMEM_ROCKCHIP_OTP=y +# CONFIG_NVMEM_SPMI_SDAM is not set +# CONFIG_NVMEM_U_BOOT_ENV is not set + +# +# HW tracing support +# +# CONFIG_STM is not set +# CONFIG_INTEL_TH is not set +# end of HW tracing support + +# CONFIG_FPGA is not set +# CONFIG_FSI is not set +CONFIG_TEE=y +CONFIG_OPTEE=m +# CONFIG_OPTEE_INSECURE_LOAD_IMAGE is not set +CONFIG_MULTIPLEXER=y + +# +# Multiplexer drivers +# +# CONFIG_MUX_ADG792A is not set +# CONFIG_MUX_ADGS1408 is not set +CONFIG_MUX_GPIO=y +CONFIG_MUX_MMIO=y +# end of Multiplexer drivers + +CONFIG_PM_OPP=y +# CONFIG_SIOX is not set +# CONFIG_SLIMBUS is not set +# CONFIG_INTERCONNECT is not set +# CONFIG_COUNTER is not set +# CONFIG_MOST is not set +# CONFIG_PECI is not set +# CONFIG_HTE is not set +# CONFIG_CDX_BUS is not set +# end of Device Drivers + +# +# File systems +# +CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_VALIDATE_FS_PARSER=y +CONFIG_FS_IOMAP=y +CONFIG_FS_STACK=y +CONFIG_BUFFER_HEAD=y +CONFIG_LEGACY_DIRECT_IO=y +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +# CONFIG_EXT4_FS_SECURITY is not set +# CONFIG_EXT4_DEBUG is not set +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +CONFIG_BTRFS_FS=y +CONFIG_BTRFS_FS_POSIX_ACL=y +# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set +# CONFIG_BTRFS_DEBUG is not set +# CONFIG_BTRFS_ASSERT is not set +# CONFIG_BTRFS_FS_REF_VERIFY is not set +# CONFIG_NILFS2_FS is not set +# CONFIG_F2FS_FS is not set +# CONFIG_BCACHEFS_FS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_EXPORTFS=y +# CONFIG_EXPORTFS_BLOCK_OPS is not set +CONFIG_FILE_LOCKING=y +# CONFIG_FS_ENCRYPTION is not set +# CONFIG_FS_VERITY is not set +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_FANOTIFY=y +CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y +CONFIG_QUOTA=y +# CONFIG_QUOTA_NETLINK_INTERFACE is not set +# CONFIG_QUOTA_DEBUG is not set +# CONFIG_QFMT_V1 is not set +# CONFIG_QFMT_V2 is not set +CONFIG_QUOTACTL=y +CONFIG_AUTOFS_FS=y +CONFIG_FUSE_FS=y +CONFIG_CUSE=m +# CONFIG_VIRTIO_FS is not set +CONFIG_FUSE_PASSTHROUGH=y +CONFIG_OVERLAY_FS=y +CONFIG_OVERLAY_FS_REDIRECT_DIR=y +CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y +# CONFIG_OVERLAY_FS_INDEX is not set +# CONFIG_OVERLAY_FS_XINO_AUTO is not set +# CONFIG_OVERLAY_FS_METACOPY is not set +# CONFIG_OVERLAY_FS_DEBUG is not set + +# +# Caches +# +# end of Caches + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +# CONFIG_UDF_FS is not set +# end of CD-ROM/DVD Filesystems + +# +# DOS/FAT/EXFAT/NT Filesystems +# +CONFIG_FAT_FS=y +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_FAT_DEFAULT_UTF8 is not set +CONFIG_EXFAT_FS=m +CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8" +CONFIG_NTFS3_FS=m +# CONFIG_NTFS3_64BIT_CLUSTER is not set +# CONFIG_NTFS3_LZX_XPRESS is not set +# CONFIG_NTFS3_FS_POSIX_ACL is not set +CONFIG_NTFS_FS=m +# end of DOS/FAT/EXFAT/NT Filesystems + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +# CONFIG_PROC_CHILDREN is not set +CONFIG_KERNFS=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMPFS_XATTR=y +# CONFIG_TMPFS_INODE64 is not set +# CONFIG_TMPFS_QUOTA is not set +CONFIG_ARCH_SUPPORTS_HUGETLBFS=y +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_HUGETLB_PMD_PAGE_TABLE_SHARING=y +CONFIG_ARCH_HAS_GIGANTIC_PAGE=y +CONFIG_CONFIGFS_FS=y +# end of Pseudo filesystems + +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ORANGEFS_FS is not set +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_ECRYPT_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_FILE_CACHE=y +# CONFIG_SQUASHFS_FILE_DIRECT is not set +CONFIG_SQUASHFS_DECOMP_SINGLE=y +# CONFIG_SQUASHFS_CHOICE_DECOMP_BY_MOUNT is not set +CONFIG_SQUASHFS_COMPILE_DECOMP_SINGLE=y +# CONFIG_SQUASHFS_COMPILE_DECOMP_MULTI is not set +# CONFIG_SQUASHFS_COMPILE_DECOMP_MULTI_PERCPU is not set +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_ZLIB=y +CONFIG_SQUASHFS_LZ4=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_SQUASHFS_ZSTD=y +CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y +CONFIG_SQUASHFS_EMBEDDED=y +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX6FS_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_PSTORE=y +CONFIG_PSTORE_DEFAULT_KMSG_BYTES=10240 +CONFIG_PSTORE_COMPRESS=y +CONFIG_PSTORE_CONSOLE=y +CONFIG_PSTORE_PMSG=y +CONFIG_PSTORE_RAM=y +# CONFIG_PSTORE_BLK is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_EROFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +# CONFIG_NFS_V2 is not set +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_SWAP is not set +# CONFIG_ROOT_NFS is not set +# CONFIG_NFS_FSCACHE is not set +CONFIG_NFS_DISABLE_UDP_SUPPORT=y +CONFIG_NFSD=m +# CONFIG_NFSD_V2 is not set +# CONFIG_NFSD_V3_ACL is not set +# CONFIG_NFSD_V4 is not set +CONFIG_GRACE_PERIOD=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +# CONFIG_NFS_LOCALIO is not set +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_SUNRPC_DEBUG is not set +# CONFIG_CEPH_FS is not set +# CONFIG_CIFS is not set +# CONFIG_SMB_SERVER is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_MAC_ROMAN is not set +# CONFIG_NLS_MAC_CELTIC is not set +# CONFIG_NLS_MAC_CENTEURO is not set +# CONFIG_NLS_MAC_CROATIAN is not set +# CONFIG_NLS_MAC_CYRILLIC is not set +# CONFIG_NLS_MAC_GAELIC is not set +# CONFIG_NLS_MAC_GREEK is not set +# CONFIG_NLS_MAC_ICELAND is not set +# CONFIG_NLS_MAC_INUIT is not set +# CONFIG_NLS_MAC_ROMANIAN is not set +# CONFIG_NLS_MAC_TURKISH is not set +CONFIG_NLS_UTF8=y +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set +CONFIG_UNICODE=y +# CONFIG_UNICODE_NORMALIZATION_SELFTEST is not set +CONFIG_IO_WQ=y +# end of File systems + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_KEYS_REQUEST_CACHE is not set +# CONFIG_PERSISTENT_KEYRINGS is not set +# CONFIG_TRUSTED_KEYS is not set +# CONFIG_ENCRYPTED_KEYS is not set +CONFIG_KEY_DH_OPERATIONS=y +# CONFIG_SECURITY_DMESG_RESTRICT is not set +CONFIG_PROC_MEM_ALWAYS_FORCE=y +# CONFIG_PROC_MEM_FORCE_PTRACE is not set +# CONFIG_PROC_MEM_NO_FORCE is not set +CONFIG_SECURITY=y +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_NETWORK is not set +# CONFIG_SECURITY_PATH is not set +# CONFIG_HARDENED_USERCOPY is not set +# CONFIG_FORTIFY_SOURCE is not set +# CONFIG_STATIC_USERMODEHELPER is not set +# CONFIG_SECURITY_SMACK is not set +# CONFIG_SECURITY_TOMOYO is not set +# CONFIG_SECURITY_APPARMOR is not set +# CONFIG_SECURITY_LOADPIN is not set +# CONFIG_SECURITY_YAMA is not set +# CONFIG_SECURITY_SAFESETID is not set +# CONFIG_SECURITY_LOCKDOWN_LSM is not set +# CONFIG_SECURITY_LANDLOCK is not set +CONFIG_INTEGRITY=y +# CONFIG_INTEGRITY_SIGNATURE is not set +# CONFIG_IMA is not set +# CONFIG_EVM is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_LSM="yama,loadpin,safesetid,integrity" + +# +# Kernel hardening options +# + +# +# Memory initialization +# +CONFIG_CC_HAS_AUTO_VAR_INIT_PATTERN=y +CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO_BARE=y +CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO=y +CONFIG_INIT_STACK_NONE=y +# CONFIG_INIT_STACK_ALL_PATTERN is not set +# CONFIG_INIT_STACK_ALL_ZERO is not set +# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set +# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set +CONFIG_CC_HAS_ZERO_CALL_USED_REGS=y +# CONFIG_ZERO_CALL_USED_REGS is not set +# end of Memory initialization + +# +# Hardening of kernel data structures +# +# CONFIG_LIST_HARDENED is not set +# CONFIG_BUG_ON_DATA_CORRUPTION is not set +# end of Hardening of kernel data structures + +CONFIG_RANDSTRUCT_NONE=y +# end of Kernel hardening options +# end of Security options + +CONFIG_XOR_BLOCKS=y +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_SIG=y +CONFIG_CRYPTO_SIG2=y +CONFIG_CRYPTO_SKCIPHER=y +CONFIG_CRYPTO_SKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=y +CONFIG_CRYPTO_AKCIPHER2=y +CONFIG_CRYPTO_AKCIPHER=y +CONFIG_CRYPTO_KPP2=y +CONFIG_CRYPTO_KPP=y +CONFIG_CRYPTO_ACOMP2=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_USER=m +CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_NULL2=y +# CONFIG_CRYPTO_PCRYPT is not set +CONFIG_CRYPTO_CRYPTD=y +CONFIG_CRYPTO_AUTHENC=m +# CONFIG_CRYPTO_TEST is not set +CONFIG_CRYPTO_ENGINE=m +# end of Crypto core or helper + +# +# Public-key cryptography +# +CONFIG_CRYPTO_RSA=y +CONFIG_CRYPTO_DH=y +# CONFIG_CRYPTO_DH_RFC7919_GROUPS is not set +CONFIG_CRYPTO_ECC=m +CONFIG_CRYPTO_ECDH=m +# CONFIG_CRYPTO_ECDSA is not set +# CONFIG_CRYPTO_ECRDSA is not set +CONFIG_CRYPTO_CURVE25519=m +# end of Public-key cryptography + +# +# Block ciphers +# +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_AES_TI is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARIA is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_SM4_GENERIC is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set +# end of Block ciphers + +# +# Length-preserving ciphers and modes +# +# CONFIG_CRYPTO_ADIANTUM is not set +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_CHACHA20=m +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CTR=y +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_HCTR2 is not set +# CONFIG_CRYPTO_KEYWRAP is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set +CONFIG_CRYPTO_NHPOLY1305=m +# end of Length-preserving ciphers and modes + +# +# AEAD (authenticated encryption with associated data) ciphers +# +# CONFIG_CRYPTO_AEGIS128 is not set +# CONFIG_CRYPTO_CHACHA20POLY1305 is not set +CONFIG_CRYPTO_CCM=y +CONFIG_CRYPTO_GCM=y +CONFIG_CRYPTO_GENIV=y +CONFIG_CRYPTO_SEQIV=m +CONFIG_CRYPTO_ECHAINIV=y +# CONFIG_CRYPTO_ESSIV is not set +# end of AEAD (authenticated encryption with associated data) ciphers + +# +# Hashes, digests, and MACs +# +CONFIG_CRYPTO_BLAKE2B=y +CONFIG_CRYPTO_CMAC=y +CONFIG_CRYPTO_GHASH=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +CONFIG_CRYPTO_POLY1305=m +# CONFIG_CRYPTO_RMD160 is not set +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_SHA3=y +# CONFIG_CRYPTO_SM3_GENERIC is not set +# CONFIG_CRYPTO_STREEBOG is not set +# CONFIG_CRYPTO_VMAC is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_XCBC is not set +CONFIG_CRYPTO_XXHASH=y +# end of Hashes, digests, and MACs + +# +# CRCs (cyclic redundancy checks) +# +CONFIG_CRYPTO_CRC32C=y +# CONFIG_CRYPTO_CRC32 is not set +# CONFIG_CRYPTO_CRCT10DIF is not set +# end of CRCs (cyclic redundancy checks) + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_LZO=y +# CONFIG_CRYPTO_842 is not set +# CONFIG_CRYPTO_LZ4 is not set +# CONFIG_CRYPTO_LZ4HC is not set +CONFIG_CRYPTO_ZSTD=y +# end of Compression + +# +# Random number generation +# +CONFIG_CRYPTO_ANSI_CPRNG=y +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_DRBG_HMAC=y +# CONFIG_CRYPTO_DRBG_HASH is not set +# CONFIG_CRYPTO_DRBG_CTR is not set +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_JITTERENTROPY=y +CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKS=64 +CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKSIZE=32 +CONFIG_CRYPTO_JITTERENTROPY_OSR=1 +CONFIG_CRYPTO_KDF800108_CTR=y +# end of Random number generation + +# +# Userspace interface +# +CONFIG_CRYPTO_USER_API=y +CONFIG_CRYPTO_USER_API_HASH=y +CONFIG_CRYPTO_USER_API_SKCIPHER=y +CONFIG_CRYPTO_USER_API_RNG=y +# CONFIG_CRYPTO_USER_API_RNG_CAVP is not set +CONFIG_CRYPTO_USER_API_AEAD=m +CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE=y +# end of Userspace interface + +CONFIG_CRYPTO_HASH_INFO=y +CONFIG_CRYPTO_NHPOLY1305_NEON=m +CONFIG_CRYPTO_CHACHA20_NEON=m + +# +# Accelerated Cryptographic Algorithms for CPU (arm64) +# +CONFIG_CRYPTO_GHASH_ARM64_CE=y +CONFIG_CRYPTO_POLY1305_NEON=m +CONFIG_CRYPTO_SHA1_ARM64_CE=y +CONFIG_CRYPTO_SHA256_ARM64=y +CONFIG_CRYPTO_SHA2_ARM64_CE=y +CONFIG_CRYPTO_SHA512_ARM64=y +CONFIG_CRYPTO_SHA512_ARM64_CE=y +# CONFIG_CRYPTO_SHA3_ARM64 is not set +# CONFIG_CRYPTO_SM3_NEON is not set +# CONFIG_CRYPTO_SM3_ARM64_CE is not set +# CONFIG_CRYPTO_POLYVAL_ARM64_CE is not set +CONFIG_CRYPTO_AES_ARM64=y +CONFIG_CRYPTO_AES_ARM64_CE=y +CONFIG_CRYPTO_AES_ARM64_CE_BLK=y +CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y +CONFIG_CRYPTO_AES_ARM64_BS=y +# CONFIG_CRYPTO_SM4_ARM64_CE is not set +# CONFIG_CRYPTO_SM4_ARM64_CE_BLK is not set +# CONFIG_CRYPTO_SM4_ARM64_NEON_BLK is not set +CONFIG_CRYPTO_AES_ARM64_CE_CCM=y +# CONFIG_CRYPTO_SM4_ARM64_CE_CCM is not set +# CONFIG_CRYPTO_SM4_ARM64_CE_GCM is not set +# end of Accelerated Cryptographic Algorithms for CPU (arm64) + +CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_ATMEL_ECC is not set +# CONFIG_CRYPTO_DEV_ATMEL_SHA204A is not set +# CONFIG_CRYPTO_DEV_CCP is not set +CONFIG_CRYPTO_DEV_ROCKCHIP=m +# CONFIG_CRYPTO_DEV_ROCKCHIP_DEBUG is not set +# CONFIG_CRYPTO_DEV_SAFEXCEL is not set +# CONFIG_CRYPTO_DEV_CCREE is not set +# CONFIG_CRYPTO_DEV_HISI_SEC is not set +# CONFIG_CRYPTO_DEV_AMLOGIC_GXL is not set +CONFIG_ASYMMETRIC_KEY_TYPE=y +CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y +CONFIG_X509_CERTIFICATE_PARSER=y +CONFIG_PKCS8_PRIVATE_KEY_PARSER=y +CONFIG_PKCS7_MESSAGE_PARSER=y +# CONFIG_PKCS7_TEST_KEY is not set +# CONFIG_SIGNED_PE_FILE_VERIFICATION is not set +# CONFIG_FIPS_SIGNATURE_SELFTEST is not set + +# +# Certificates for signature checking +# +CONFIG_SYSTEM_TRUSTED_KEYRING=y +CONFIG_SYSTEM_TRUSTED_KEYS="" +# CONFIG_SYSTEM_EXTRA_CERTIFICATE is not set +# CONFIG_SECONDARY_TRUSTED_KEYRING is not set +# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set +# end of Certificates for signature checking + +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_RAID6_PQ=y +CONFIG_RAID6_PQ_BENCHMARK=y +CONFIG_LINEAR_RANGES=y +# CONFIG_PACKING is not set +CONFIG_BITREVERSE=y +CONFIG_HAVE_ARCH_BITREVERSE=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_NET_UTILS=y +CONFIG_CORDIC=m +# CONFIG_PRIME_NUMBERS is not set +CONFIG_RATIONAL=y +CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y +CONFIG_ARCH_HAS_FAST_MULTIPLIER=y +CONFIG_ARCH_USE_SYM_ANNOTATIONS=y +# CONFIG_INDIRECT_PIO is not set + +# +# Crypto library routines +# +CONFIG_CRYPTO_LIB_UTILS=y +CONFIG_CRYPTO_LIB_AES=y +CONFIG_CRYPTO_LIB_ARC4=y +CONFIG_CRYPTO_LIB_GF128MUL=y +CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y +CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=y +CONFIG_CRYPTO_LIB_CHACHA_GENERIC=m +CONFIG_CRYPTO_LIB_CHACHA_INTERNAL=m +CONFIG_CRYPTO_LIB_CHACHA=m +CONFIG_CRYPTO_LIB_CURVE25519_GENERIC=m +CONFIG_CRYPTO_LIB_CURVE25519_INTERNAL=m +CONFIG_CRYPTO_LIB_CURVE25519=m +CONFIG_CRYPTO_LIB_DES=y +CONFIG_CRYPTO_LIB_POLY1305_RSIZE=9 +CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305=y +CONFIG_CRYPTO_LIB_POLY1305_GENERIC=m +CONFIG_CRYPTO_LIB_POLY1305_INTERNAL=m +CONFIG_CRYPTO_LIB_POLY1305=m +CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m +CONFIG_CRYPTO_LIB_SHA1=y +CONFIG_CRYPTO_LIB_SHA256=y +# end of Crypto library routines + +CONFIG_CRC_CCITT=m +CONFIG_CRC16=y +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC64_ROCKSOFT is not set +CONFIG_CRC_ITU_T=y +CONFIG_CRC32=y +# CONFIG_CRC32_SELFTEST is not set +CONFIG_CRC32_SLICEBY8=y +# CONFIG_CRC32_SLICEBY4 is not set +# CONFIG_CRC32_SARWATE is not set +# CONFIG_CRC32_BIT is not set +# CONFIG_CRC64 is not set +# CONFIG_CRC4 is not set +CONFIG_CRC7=y +CONFIG_LIBCRC32C=y +# CONFIG_CRC8 is not set +CONFIG_XXHASH=y +CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y +# CONFIG_RANDOM32_SELFTEST is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_LZ4_COMPRESS=m +CONFIG_LZ4HC_COMPRESS=m +CONFIG_LZ4_DECOMPRESS=y +CONFIG_ZSTD_COMMON=y +CONFIG_ZSTD_COMPRESS=y +CONFIG_ZSTD_DECOMPRESS=y +CONFIG_XZ_DEC=y +CONFIG_XZ_DEC_X86=y +CONFIG_XZ_DEC_POWERPC=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +CONFIG_XZ_DEC_ARM64=y +CONFIG_XZ_DEC_SPARC=y +CONFIG_XZ_DEC_RISCV=y +# CONFIG_XZ_DEC_MICROLZMA is not set +CONFIG_XZ_DEC_BCJ=y +# CONFIG_XZ_DEC_TEST is not set +CONFIG_DECOMPRESS_LZO=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_REED_SOLOMON=y +CONFIG_REED_SOLOMON_ENC8=y +CONFIG_REED_SOLOMON_DEC8=y +CONFIG_INTERVAL_TREE=y +CONFIG_XARRAY_MULTI=y +CONFIG_ASSOCIATIVE_ARRAY=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_DMA_OPS_HELPERS=y +CONFIG_NEED_SG_DMA_FLAGS=y +CONFIG_NEED_SG_DMA_LENGTH=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_ARCH_DMA_ADDR_T_64BIT=y +CONFIG_DMA_DECLARE_COHERENT=y +CONFIG_ARCH_HAS_SETUP_DMA_OPS=y +CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE=y +CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU=y +CONFIG_ARCH_HAS_DMA_PREP_COHERENT=y +CONFIG_SWIOTLB=y +# CONFIG_SWIOTLB_DYNAMIC is not set +CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC=y +CONFIG_DMA_NEED_SYNC=y +# CONFIG_DMA_RESTRICTED_POOL is not set +CONFIG_DMA_NONCOHERENT_MMAP=y +CONFIG_DMA_COHERENT_POOL=y +CONFIG_DMA_DIRECT_REMAP=y +CONFIG_DMA_CMA=y + +# +# Default contiguous memory area size: +# +CONFIG_CMA_SIZE_MBYTES=64 +CONFIG_CMA_SIZE_SEL_MBYTES=y +# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set +# CONFIG_CMA_SIZE_SEL_MIN is not set +# CONFIG_CMA_SIZE_SEL_MAX is not set +CONFIG_CMA_ALIGNMENT=8 +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_DMA_MAP_BENCHMARK is not set +CONFIG_SGL_ALLOC=y +CONFIG_CPU_RMAP=y +CONFIG_DQL=y +CONFIG_GLOB=y +# CONFIG_GLOB_SELFTEST is not set +CONFIG_NLATTR=y +CONFIG_CLZ_TAB=y +# CONFIG_IRQ_POLL is not set +CONFIG_MPILIB=y +CONFIG_DIMLIB=y +CONFIG_LIBFDT=y +CONFIG_OID_REGISTRY=y +CONFIG_HAVE_GENERIC_VDSO=y +CONFIG_GENERIC_GETTIMEOFDAY=y +CONFIG_GENERIC_VDSO_TIME_NS=y +CONFIG_VDSO_GETRANDOM=y +CONFIG_FONT_SUPPORT=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_SG_POOL=y +CONFIG_ARCH_STACKWALK=y +CONFIG_SBITMAP=y +# CONFIG_LWQ_TEST is not set +# end of Library routines + +CONFIG_GENERIC_IOREMAP=y +CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y + +# +# Kernel hacking +# + +# +# printk and dmesg options +# +CONFIG_PRINTK_TIME=y +# CONFIG_PRINTK_CALLER is not set +# CONFIG_STACKTRACE_BUILD_ID is not set +CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 +CONFIG_CONSOLE_LOGLEVEL_QUIET=4 +CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 +# CONFIG_BOOT_PRINTK_DELAY is not set +CONFIG_DYNAMIC_DEBUG=y +CONFIG_DYNAMIC_DEBUG_CORE=y +CONFIG_SYMBOLIC_ERRNAME=y +CONFIG_DEBUG_BUGVERBOSE=y +# end of printk and dmesg options + +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_MISC=y + +# +# Compile-time checks and compiler options +# +CONFIG_AS_HAS_NON_CONST_ULEB128=y +CONFIG_DEBUG_INFO_NONE=y +# CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT is not set +# CONFIG_DEBUG_INFO_DWARF4 is not set +# CONFIG_DEBUG_INFO_DWARF5 is not set +CONFIG_FRAME_WARN=2048 +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_READABLE_ASM is not set +# CONFIG_HEADERS_INSTALL is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_SECTION_MISMATCH_WARN_ONLY=y +# CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B is not set +CONFIG_ARCH_WANT_FRAME_POINTERS=y +CONFIG_FRAME_POINTER=y +# CONFIG_VMLINUX_MAP is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# end of Compile-time checks and compiler options + +# +# Generic Kernel Debugging Instruments +# +CONFIG_MAGIC_SYSRQ=y +CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 +CONFIG_MAGIC_SYSRQ_SERIAL=y +CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE="" +CONFIG_DEBUG_FS=y +CONFIG_DEBUG_FS_ALLOW_ALL=y +# CONFIG_DEBUG_FS_DISALLOW_MOUNT is not set +# CONFIG_DEBUG_FS_ALLOW_NONE is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +CONFIG_ARCH_HAS_UBSAN=y +# CONFIG_UBSAN is not set +CONFIG_HAVE_ARCH_KCSAN=y +CONFIG_HAVE_KCSAN_COMPILER=y +# CONFIG_KCSAN is not set +# end of Generic Kernel Debugging Instruments + +# +# Networking Debugging +# +# CONFIG_NET_DEV_REFCNT_TRACKER is not set +# CONFIG_NET_NS_REFCNT_TRACKER is not set +# CONFIG_DEBUG_NET is not set +# end of Networking Debugging + +# +# Memory Debugging +# +# CONFIG_PAGE_EXTENSION is not set +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_SLUB_DEBUG is not set +# CONFIG_PAGE_OWNER is not set +# CONFIG_PAGE_TABLE_CHECK is not set +# CONFIG_PAGE_POISONING is not set +# CONFIG_DEBUG_RODATA_TEST is not set +CONFIG_ARCH_HAS_DEBUG_WX=y +# CONFIG_DEBUG_WX is not set +CONFIG_GENERIC_PTDUMP=y +# CONFIG_PTDUMP_DEBUGFS is not set +CONFIG_HAVE_DEBUG_KMEMLEAK=y +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_PER_VMA_LOCK_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SHRINKER_DEBUG is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_SCHED_STACK_END_CHECK is not set +CONFIG_ARCH_HAS_DEBUG_VM_PGTABLE=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_VM_PGTABLE is not set +CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y +# CONFIG_DEBUG_VIRTUAL is not set +CONFIG_DEBUG_MEMORY_INIT=y +# CONFIG_DEBUG_PER_CPU_MAPS is not set +# CONFIG_MEM_ALLOC_PROFILING is not set +CONFIG_HAVE_ARCH_KASAN=y +CONFIG_HAVE_ARCH_KASAN_SW_TAGS=y +CONFIG_HAVE_ARCH_KASAN_VMALLOC=y +CONFIG_CC_HAS_KASAN_GENERIC=y +CONFIG_CC_HAS_KASAN_SW_TAGS=y +CONFIG_CC_HAS_WORKING_NOSANITIZE_ADDRESS=y +# CONFIG_KASAN is not set +CONFIG_HAVE_ARCH_KFENCE=y +# CONFIG_KFENCE is not set +# end of Memory Debugging + +# CONFIG_DEBUG_SHIRQ is not set + +# +# Debug Oops, Lockups and Hangs +# +# CONFIG_PANIC_ON_OOPS is not set +CONFIG_PANIC_ON_OOPS_VALUE=0 +CONFIG_PANIC_TIMEOUT=1 +# CONFIG_SOFTLOCKUP_DETECTOR is not set +CONFIG_HAVE_HARDLOCKUP_DETECTOR_BUDDY=y +# CONFIG_HARDLOCKUP_DETECTOR is not set +# CONFIG_DETECT_HUNG_TASK is not set +# CONFIG_WQ_WATCHDOG is not set +# CONFIG_WQ_CPU_INTENSIVE_REPORT is not set +# CONFIG_TEST_LOCKUP is not set +# end of Debug Oops, Lockups and Hangs + +# +# Scheduler Debugging +# +# CONFIG_SCHED_DEBUG is not set +CONFIG_SCHED_INFO=y +# CONFIG_SCHEDSTATS is not set +# end of Scheduler Debugging + +# +# Lock Debugging (spinlocks, mutexes, etc...) +# +CONFIG_LOCK_DEBUGGING_SUPPORT=y +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set +# CONFIG_DEBUG_RWSEMS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_LOCK_TORTURE_TEST is not set +# CONFIG_WW_MUTEX_SELFTEST is not set +# CONFIG_SCF_TORTURE_TEST is not set +# CONFIG_CSD_LOCK_WAIT_DEBUG is not set +# end of Lock Debugging (spinlocks, mutexes, etc...) + +# CONFIG_DEBUG_IRQFLAGS is not set +# CONFIG_STACKTRACE is not set +# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set +# CONFIG_DEBUG_KOBJECT is not set + +# +# Debug kernel data structures +# +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_PLIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_MAPLE_TREE is not set +# end of Debug kernel data structures + +# +# RCU Debugging +# +# CONFIG_RCU_SCALE_TEST is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_REF_SCALE_TEST is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=21 +CONFIG_RCU_EXP_CPU_STALL_TIMEOUT=0 +# CONFIG_RCU_CPU_STALL_CPUTIME is not set +# CONFIG_RCU_TRACE is not set +# CONFIG_RCU_EQS_DEBUG is not set +# end of RCU Debugging + +# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set +# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set +# CONFIG_LATENCYTOP is not set +CONFIG_USER_STACKTRACE_SUPPORT=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_RETVAL=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_SAMPLE_FTRACE_DIRECT=y +CONFIG_HAVE_SAMPLE_FTRACE_DIRECT_MULTI=y +CONFIG_STRICT_DEVMEM=y +# CONFIG_IO_STRICT_DEVMEM is not set + +# +# arm64 Debugging +# +# CONFIG_PID_IN_CONTEXTIDR is not set +# CONFIG_ARM64_RELOC_TEST is not set +# CONFIG_CORESIGHT is not set +# end of arm64 Debugging + +# +# Kernel Testing and Coverage +# +# CONFIG_KUNIT is not set +# CONFIG_NOTIFIER_ERROR_INJECTION is not set +# CONFIG_FAULT_INJECTION is not set +CONFIG_ARCH_HAS_KCOV=y +CONFIG_CC_HAS_SANCOV_TRACE_PC=y +# CONFIG_KCOV is not set +# CONFIG_RUNTIME_TESTING_MENU is not set +CONFIG_ARCH_USE_MEMTEST=y +CONFIG_MEMTEST=y +# end of Kernel Testing and Coverage + +# +# Rust hacking +# +# end of Rust hacking +# end of Kernel hacking diff --git a/projects/ArchR/devices/RK3326/options b/projects/ArchR/devices/RK3326/options new file mode 100644 index 0000000000..5ce4f1ec7b --- /dev/null +++ b/projects/ArchR/devices/RK3326/options @@ -0,0 +1,85 @@ +################################################################################ +# setup device defaults +################################################################################ + + # Device name for image filenames (overrides DEVICE in image name only) + DEVICE_NAME="R36S" + + # The TARGET_CPU variable controls which processor should be targeted for + # generated code. + case ${TARGET_ARCH} in + aarch64) + TARGET_KERNEL_ARCH="arm64" + TARGET_KERNEL_PATCH_ARCH="aarch64" + TARGET_CPU="cortex-a35" + TARGET_ARCH_FLAGS="+crc+fp+simd" + TARGET_FEATURES="64bit" + ;; + arm) + TARGET_KERNEL_ARCH="arm64" + TARGET_KERNEL_PATCH_ARCH="aarch64" + TARGET_FLOAT="hard" + TARGET_CPU="cortex-a35" + TARGET_ARCH_FLAGS="+crc" + TARGET_FPU="crypto-neon-fp-armv8" + TARGET_FEATURES="32bit" + ;; + esac + + PARTITION_TABLE="msdos" + HW_CPU="Rockchip RK3326" + + # Kernel target + KERNEL_TARGET="Image" + + # Kernel extra targets to build + KERNEL_MAKE_EXTRACMD=" $(get_kernel_make_extracmd)" + + # Kernel cmdline + EXTRA_CMDLINE="quiet loglevel=0 vt.global_cursor_default=0 consoleblank=0 console=ttyS2,1500000 systemd.show_status=false systemd.debug_shell=ttyS2" + + # Bootloader to use (syslinux / u-boot) + BOOTLOADER="u-boot" + + # U-Boot firmware package(s) to use + UBOOT_FIRMWARE="rkbin" + + # Mali GPU family + MALI_FAMILY="bifrost-g31" + GRAPHIC_DRIVERS="mali panfrost" + + # For maximum cross compatbility + PREFER_GLES="yes" + + # Displayserver to use (wl / no) + DISPLAYSERVER="wl" + + # Windowmanager to use (weston / swaywm-env / no) + WINDOWMANAGER="swaywm-env" + + # Additional drivers to install: + # for a list of additional drivers see packages/linux-drivers + # Space separated list is supported, + # e.g. ADDITIONAL_DRIVERS="DRIVER1 DRIVER2" + ADDITIONAL_DRIVERS="RTL8812AU RTL8814AU RTL8821AU RTL8821CU RTL88x2BU RTL8851BU mali-bifrost" + + # Additional Firmware to use ( ) + # Space separated list is supported, + # e.g. FIRMWARE="" + FIRMWARE="esp8089-firmware" + + # Additional packages to install + ADDITIONAL_PACKAGES="device-switch libmali generic-dsi" + ADDITIONAL_PACKAGES_32BIT="libmali" + + # Debug tty path + DEBUG_TTY="/dev/ttyS2" + + # ZRAM Algorithm + ZRAM_COMPRESSION_ALGO="lzo-rle" + + # ZRAM Size + ZRAM_SWAP_SIZE="0" + + # Disk Swap + SWAP_FILE_SIZE="0" diff --git a/projects/ArchR/devices/RK3326/packages/u-boot-legacy/package.mk b/projects/ArchR/devices/RK3326/packages/u-boot-legacy/package.mk new file mode 100644 index 0000000000..5ddaa4b7f6 --- /dev/null +++ b/projects/ArchR/devices/RK3326/packages/u-boot-legacy/package.mk @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="u-boot-legacy" +PKG_VERSION="2492a3e467e332e2350d987234ce6123700b3392" +PKG_LICENSE="GPL" +PKG_SITE="https://www.denx.de/wiki/U-Boot" +PKG_URL="https://github.com/archr-linux/hardkernel-uboot/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain Python3:host swig:host pyelftools:host" +PKG_LONGDESC="Das U-Boot is a cross-platform bootloader for embedded systems." +PKG_BUILD_FLAGS="-parallel" +PKG_TOOLCHAIN="manual" + +PKG_NEED_UNPACK="${PROJECT_DIR}/${PROJECT}/bootloader ${PROJECT_DIR}/${PROJECT}/devices/${DEVICE}/bootloader" +PKG_NEED_UNPACK+=" ${PROJECT_DIR}/${PROJECT}/options ${PROJECT_DIR}/${PROJECT}/devices/${DEVICE}/options" + +if [ -n "${UBOOT_FIRMWARE}" ]; then + PKG_DEPENDS_TARGET+=" ${UBOOT_FIRMWARE}" + PKG_DEPENDS_UNPACK+=" ${UBOOT_FIRMWARE}" +fi + +post_unpack() { + # Fix BSP U-Boot to load DTBs from dtbs/ subfolder and use correct DTB names + # board.c: fatload from dtbs/ instead of root + sed -i 's|fatload mmc 1:1 ${fdt_addr_r} ${dtb_name}|fatload mmc 1:1 ${fdt_addr_r} dtbs/${dtb_name}|' \ + ${PKG_BUILD}/arch/arm/mach-rockchip/board.c + + # hwrev.c: use correct DTB names matching kernel device trees + sed -i \ + -e 's|rk3326-odroidgo2-linux-v11.dtb|rk3326-odroid-go2-v11.dtb|' \ + -e 's|rk3326-odroidgo2-linux.dtb|rk3326-odroid-go2.dtb|' \ + -e 's|rk3326-odroidgo3-linux.dtb|rk3326-odroid-go3.dtb|' \ + ${PKG_BUILD}/cmd/hwrev.c +} + +pre_make_target() { + PKG_UBOOT_CONFIG="archr_rk3326_defconfig" + PKG_RKBIN="$(get_build_dir rkbin)" + PKG_MINILOADER="${PKG_RKBIN}/bin/rk33/rk3326_miniloader_v1.40.bin" + PKG_BL31="${PKG_RKBIN}/bin/rk33/rk3326_bl31_v1.34.elf" + PKG_DDR_BIN="${PKG_RKBIN}/bin/rk33/rk3326_ddr_333MHz_v2.11.bin" +} + +make_target() { + [ "${BUILD_WITH_DEBUG}" = "yes" ] && PKG_DEBUG=1 || PKG_DEBUG=0 + setup_pkg_config_host + + DEBUG=${PKG_DEBUG} CROSS_COMPILE="${TARGET_KERNEL_PREFIX}" LDFLAGS="" ARCH=arm make mrproper + DEBUG=${PKG_DEBUG} CROSS_COMPILE="${TARGET_KERNEL_PREFIX}" LDFLAGS="" ARCH=arm make ${PKG_UBOOT_CONFIG} + DEBUG=${PKG_DEBUG} CROSS_COMPILE="${TARGET_KERNEL_PREFIX}" LDFLAGS="" ARCH=arm _python_sysroot="${TOOLCHAIN}" _python_prefix=/ _python_exec_prefix=/ make HOSTCC="$HOST_CC" HOSTLDFLAGS="-L${TOOLCHAIN}/lib" HOSTSTRIP="true" CONFIG_MKIMAGE_DTC_PATH="scripts/dtc/dtc" + + find_file_path bootloader/rkhelper && . ${FOUND_PATH} +} + +makeinstall_target() { + mkdir -p $INSTALL/usr/share/bootloader + + cp -av uboot.bin $INSTALL/usr/share/bootloader/original_uboot.bin +} diff --git a/projects/ArchR/devices/RK3326/packages/u-boot-legacy/sources/configs/archr_rk3326_defconfig b/projects/ArchR/devices/RK3326/packages/u-boot-legacy/sources/configs/archr_rk3326_defconfig new file mode 100644 index 0000000000..2ddff93ae3 --- /dev/null +++ b/projects/ArchR/devices/RK3326/packages/u-boot-legacy/sources/configs/archr_rk3326_defconfig @@ -0,0 +1,1369 @@ +# +# Automatically generated file; DO NOT EDIT. +# U-Boot 2017.09 Configuration +# +CONFIG_CREATE_ARCH_SYMLINK=y +# CONFIG_ARC is not set +CONFIG_ARM=y +# CONFIG_M68K is not set +# CONFIG_MICROBLAZE is not set +# CONFIG_MIPS is not set +# CONFIG_NDS32 is not set +# CONFIG_NIOS2 is not set +# CONFIG_PPC is not set +# CONFIG_SANDBOX is not set +# CONFIG_SH is not set +# CONFIG_X86 is not set +# CONFIG_XTENSA is not set +CONFIG_SYS_ARCH="arm" +CONFIG_SYS_CPU="armv8" +CONFIG_SYS_SOC="rockchip" +CONFIG_SYS_VENDOR="rockchip" +CONFIG_SYS_BOARD="odroidgoa" +CONFIG_SYS_CONFIG_NAME="odroidgoa" + +# +# ARM architecture +# +CONFIG_ARM64=y +# CONFIG_POSITION_INDEPENDENT is not set +CONFIG_STATIC_RELA=y +CONFIG_DMA_ADDR_T_64BIT=y +CONFIG_ARM_ASM_UNIFIED=y +CONFIG_SYS_ARM_ARCH=8 +CONFIG_SYS_CACHE_SHIFT_6=y +CONFIG_SYS_CACHELINE_SIZE=64 +CONFIG_ARM_SMCCC=y +CONFIG_ARM_CPU_SUSPEND=y +# CONFIG_SEMIHOSTING is not set +# CONFIG_SYS_L2CACHE_OFF is not set +CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK=y +# CONFIG_ARM_CORTEX_CPU_IS_UP is not set +CONFIG_ARM64_SUPPORT_AARCH32=y +# CONFIG_ARCH_AT91 is not set +# CONFIG_TARGET_EDB93XX is not set +# CONFIG_TARGET_ASPENITE is not set +# CONFIG_TARGET_GPLUGD is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_KIRKWOOD is not set +# CONFIG_ARCH_MVEBU is not set +# CONFIG_TARGET_DEVKIT3250 is not set +# CONFIG_TARGET_WORK_92105 is not set +# CONFIG_TARGET_MX25PDK is not set +# CONFIG_TARGET_ZMX25 is not set +# CONFIG_TARGET_APF27 is not set +# CONFIG_TARGET_APX4DEVKIT is not set +# CONFIG_TARGET_XFI3 is not set +# CONFIG_TARGET_M28EVK is not set +# CONFIG_TARGET_MX23EVK is not set +# CONFIG_TARGET_MX28EVK is not set +# CONFIG_TARGET_MX23_OLINUXINO is not set +# CONFIG_TARGET_BG0900 is not set +# CONFIG_TARGET_SANSA_FUZE_PLUS is not set +# CONFIG_TARGET_SC_SPS_1 is not set +# CONFIG_ORION5X is not set +# CONFIG_TARGET_SPEAR300 is not set +# CONFIG_TARGET_SPEAR310 is not set +# CONFIG_TARGET_SPEAR320 is not set +# CONFIG_TARGET_SPEAR600 is not set +# CONFIG_TARGET_STV0991 is not set +# CONFIG_TARGET_X600 is not set +# CONFIG_TARGET_IMX31_PHYCORE is not set +# CONFIG_TARGET_IMX31_PHYCORE_EET is not set +# CONFIG_TARGET_MX31ADS is not set +# CONFIG_TARGET_MX31PDK is not set +# CONFIG_TARGET_WOODBURN is not set +# CONFIG_TARGET_WOODBURN_SD is not set +# CONFIG_TARGET_FLEA3 is not set +# CONFIG_TARGET_MX35PDK is not set +# CONFIG_ARCH_BCM283X is not set +# CONFIG_TARGET_VEXPRESS_CA15_TC2 is not set +# CONFIG_TARGET_VEXPRESS_CA5X2 is not set +# CONFIG_TARGET_VEXPRESS_CA9X4 is not set +# CONFIG_TARGET_BCM23550_W1D is not set +# CONFIG_TARGET_BCM28155_AP is not set +# CONFIG_TARGET_BCMCYGNUS is not set +# CONFIG_TARGET_BCMNSP is not set +# CONFIG_TARGET_BCMNS2 is not set +# CONFIG_ARCH_EXYNOS is not set +# CONFIG_ARCH_S5PC1XX is not set +# CONFIG_ARCH_HIGHBANK is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_KEYSTONE is not set +# CONFIG_ARCH_OMAP2PLUS is not set +# CONFIG_ARCH_MESON is not set +# CONFIG_ARCH_MX7ULP is not set +# CONFIG_ARCH_MX7 is not set +# CONFIG_ARCH_MX6 is not set +CONFIG_SPL_LDSCRIPT="arch/arm/cpu/armv8/u-boot-spl.lds" +# CONFIG_ARCH_MX5 is not set +# CONFIG_ARCH_RMOBILE is not set +# CONFIG_TARGET_S32V234EVB is not set +# CONFIG_ARCH_SNAPDRAGON is not set +# CONFIG_ARCH_SOCFPGA is not set +# CONFIG_ARCH_SUNXI is not set +# CONFIG_TARGET_TS4600 is not set +# CONFIG_ARCH_VF610 is not set +# CONFIG_ARCH_ZYNQ is not set +# CONFIG_ARCH_ZYNQMP is not set +# CONFIG_TEGRA is not set +# CONFIG_TARGET_VEXPRESS64_AEMV8A is not set +# CONFIG_TARGET_VEXPRESS64_BASE_FVP is not set +# CONFIG_TARGET_VEXPRESS64_BASE_FVP_DRAM is not set +# CONFIG_TARGET_VEXPRESS64_JUNO is not set +# CONFIG_TARGET_LS2080A_EMU is not set +# CONFIG_TARGET_LS2080A_SIMU is not set +# CONFIG_TARGET_LS2080AQDS is not set +# CONFIG_TARGET_LS2080ARDB is not set +# CONFIG_TARGET_LS2081ARDB is not set +# CONFIG_TARGET_HIKEY is not set +# CONFIG_TARGET_POPLAR is not set +# CONFIG_TARGET_LS1012AQDS is not set +# CONFIG_TARGET_LS1012ARDB is not set +# CONFIG_TARGET_LS1012AFRDM is not set +# CONFIG_TARGET_LS1021AQDS is not set +# CONFIG_TARGET_LS1021ATWR is not set +# CONFIG_TARGET_LS1021AIOT is not set +# CONFIG_TARGET_LS1043AQDS is not set +# CONFIG_TARGET_LS1043ARDB is not set +# CONFIG_TARGET_LS1046AQDS is not set +# CONFIG_TARGET_LS1046ARDB is not set +# CONFIG_TARGET_H2200 is not set +# CONFIG_TARGET_ZIPITZ2 is not set +# CONFIG_TARGET_COLIBRI_PXA270 is not set +# CONFIG_ARCH_UNIPHIER is not set +# CONFIG_STM32 is not set +# CONFIG_ARCH_STI is not set +CONFIG_ARCH_ROCKCHIP=y +# CONFIG_TARGET_THUNDERX_88XX is not set +# CONFIG_ARCH_ASPEED is not set +# CONFIG_SPL_GPIO_SUPPORT is not set +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_ROCKCHIP_PX30=y +CONFIG_TPL_LDSCRIPT="arch/arm/mach-rockchip/u-boot-tpl-v8.lds" +CONFIG_TPL_TEXT_BASE=0xff0e1000 +CONFIG_TPL_MAX_SIZE=10240 +CONFIG_ROCKCHIP_RK3326=y +# CONFIG_ROCKCHIP_RK3036 is not set +# CONFIG_ROCKCHIP_RK3128 is not set +# CONFIG_ROCKCHIP_RK3066 is not set +# CONFIG_ROCKCHIP_RK3188 is not set +# CONFIG_ROCKCHIP_RK322X is not set +# CONFIG_ROCKCHIP_RK3288 is not set +CONFIG_SPL_FIT_GENERATOR="arch/arm/mach-rockchip/make_fit_atf.py" +# CONFIG_ROCKCHIP_RK3308 is not set +# CONFIG_ROCKCHIP_RK3328 is not set +# CONFIG_ROCKCHIP_RK3368 is not set +# CONFIG_ROCKCHIP_RK3399 is not set +# CONFIG_ROCKCHIP_RK1808 is not set +# CONFIG_ROCKCHIP_RV1108 is not set +# CONFIG_SPL_ROCKCHIP_BACK_TO_BROM is not set +CONFIG_TPL_ROCKCHIP_BACK_TO_BROM=y +# CONFIG_ARM64_BOOT_AARCH32 is not set +CONFIG_ROCKCHIP_BOOT_MODE_REG=0xff010200 +CONFIG_ROCKCHIP_STIMER_BASE=0xff220020 +CONFIG_ROCKCHIP_IRAM_START_ADDR=0xff0e0000 +CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x0 +CONFIG_ROCKCHIP_BROM_HELPER=y +# CONFIG_SPL_ROCKCHIP_EARLYRETURN_TO_BROM is not set +# CONFIG_TPL_ROCKCHIP_EARLYRETURN_TO_BROM is not set +CONFIG_SPL_MMC_SUPPORT=y +CONFIG_RKIMG_BOOTLOADER=y +# CONFIG_RKIMG_ANDROID_BOOTMODE_LEGACY is not set +CONFIG_ROCKCHIP_RESOURCE_IMAGE=y +# CONFIG_ROCKCHIP_EARLY_DISTRO_DTB is not set +CONFIG_ROCKCHIP_VENDOR_PARTITION=y +CONFIG_USING_KERNEL_DTB=y +# CONFIG_ROCKCHIP_CRC is not set +CONFIG_ROCKCHIP_SMCCC=y +# CONFIG_ROCKCHIP_DEBUGGER is not set +# CONFIG_ROCKCHIP_CRASH_DUMP is not set +CONFIG_ROCKCHIP_PRELOADER_ATAGS=y +CONFIG_ROCKCHIP_PRELOADER_SERIAL=y +CONFIG_GICV2=y +# CONFIG_GICV3 is not set +# CONFIG_TARGET_EVB_PX30 is not set +CONFIG_PLATFORM_ODROID_GOADV=y +CONFIG_TARGET_ODROIDGOA=y +CONFIG_SPL_SERIAL_SUPPORT=y +CONFIG_BOARD_SPECIFIC_OPTIONS=y +# CONFIG_TPL_LIBCOMMON_SUPPORT is not set +# CONFIG_TPL_LIBGENERIC_SUPPORT is not set +CONFIG_SPL_DRIVERS_MISC_SUPPORT=y +CONFIG_ENV_SIZE=0x8000 +CONFIG_ENV_OFFSET=0x3f8000 +# CONFIG_SPL_LIBDISK_SUPPORT is not set +# CONFIG_SPL_NAND_SUPPORT is not set +# CONFIG_SPL_SPI_FLASH_SUPPORT is not set +# CONFIG_SPL_SPI_SUPPORT is not set +# CONFIG_SPL_WATCHDOG_SUPPORT is not set +CONFIG_IDENT_STRING="" +CONFIG_SPL_STACK_R_ADDR=0x600000 +# CONFIG_SPL_FAT_SUPPORT is not set +# CONFIG_ARMV8_MULTIENTRY is not set +# CONFIG_ARMV8_SET_SMPEN is not set + +# +# ARMv8 secure monitor firmware +# +# CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT is not set +# CONFIG_SPL_ARMV8_SEC_FIRMWARE_SUPPORT is not set +CONFIG_PSCI_RESET=y +# CONFIG_ARMV8_PSCI is not set +# CONFIG_CMD_DEKBLOB is not set +# CONFIG_CMD_HDMIDETECT is not set + +# +# ARM debug +# +CONFIG_DEFAULT_DEVICE_TREE="odroidgoa" +CONFIG_SMBIOS_PRODUCT_NAME="odroidgoa" +CONFIG_DEBUG_UART=y +# CONFIG_AHCI is not set + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_DISTRO_DEFAULTS=y +CONFIG_SYS_MALLOC_F=y +CONFIG_SPL_SYS_MALLOC_F_LEN=0x2000 +CONFIG_TPL_SYS_MALLOC_F_LEN=0x600 +CONFIG_EXPERT=y +CONFIG_SYS_MALLOC_CLEAR_ON_INIT=y +# CONFIG_TOOLS_DEBUG is not set +CONFIG_PHYS_64BIT=y + +# +# Boot images +# +# CONFIG_ANDROID_BOOT_IMAGE is not set +CONFIG_FIT=y +CONFIG_FIT_ENABLE_SHA256_SUPPORT=y +# CONFIG_FIT_SIGNATURE is not set +CONFIG_FIT_VERBOSE=y +# CONFIG_FIT_BEST_MATCH is not set +CONFIG_SPL_FIT=y +# CONFIG_SPL_FIT_SIGNATURE is not set +CONFIG_SPL_LOAD_FIT=y +# CONFIG_SPL_FIT_IMAGE_POST_PROCESS is not set +CONFIG_SPL_FIT_SOURCE="" +# CONFIG_OF_BOARD_SETUP is not set +# CONFIG_OF_SYSTEM_SETUP is not set +# CONFIG_OF_STDOUT_VIA_ALIAS is not set +CONFIG_SYS_EXTRA_OPTIONS="" +CONFIG_ARCH_FIXUP_FDT_MEMORY=y + +# +# API +# +# CONFIG_API is not set + +# +# Boot timing +# +# CONFIG_BOOTSTAGE is not set +CONFIG_BOOTSTAGE_USER_COUNT=20 +CONFIG_BOOTSTAGE_RECORD_COUNT=30 +CONFIG_BOOTSTAGE_STASH_ADDR=0 +CONFIG_BOOTSTAGE_STASH_SIZE=0x1000 +# CONFIG_BOOTSTAGE_PRINTF_TIMESTAMP is not set + +# +# Boot media +# +# CONFIG_NAND_BOOT is not set +# CONFIG_ONENAND_BOOT is not set +# CONFIG_QSPI_BOOT is not set +# CONFIG_SATA_BOOT is not set +CONFIG_SD_BOOT=y +# CONFIG_SPI_BOOT is not set +CONFIG_PASS_DEVICE_SERIAL_BY_FDT=y +CONFIG_BOOTDELAY=0 +# CONFIG_USE_BOOTARGS is not set + +# +# Console +# +CONFIG_MENU=y +# CONFIG_CONSOLE_RECORD is not set +# CONFIG_CONSOLE_DISABLE_CTRLC is not set +# CONFIG_DISABLE_CONSOLE is not set +CONFIG_LOGLEVEL=4 +CONFIG_SPL_LOGLEVEL=4 +# CONFIG_SILENT_CONSOLE is not set +# CONFIG_PRE_CONSOLE_BUFFER is not set +CONFIG_CONSOLE_MUX=y +CONFIG_SYS_CONSOLE_IS_IN_ENV=y +# CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE is not set +# CONFIG_SYS_CONSOLE_ENV_OVERWRITE is not set +# CONFIG_SYS_CONSOLE_INFO_QUIET is not set +# CONFIG_SYS_STDIO_DEREGISTER is not set + +# +# Logging +# +# CONFIG_LOG is not set +# CONFIG_SPL_LOG is not set +CONFIG_DEFAULT_FDT_FILE="" +# CONFIG_VERSION_VARIABLE is not set +CONFIG_BOARD_LATE_INIT=y +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_DISPLAY_BOARDINFO=y + +# +# Start-up hooks +# +# CONFIG_ARCH_EARLY_INIT_R is not set +# CONFIG_ARCH_MISC_INIT is not set +# CONFIG_BOARD_EARLY_INIT_F is not set +# CONFIG_BOARD_EARLY_INIT_R is not set +# CONFIG_ANDROID_AB is not set +CONFIG_ANDROID_WRITE_KEYBOX=y +# CONFIG_ANDROID_AVB is not set +CONFIG_ANDROID_KEYMASTER_CA=y +# CONFIG_SKIP_RELOCATE_UBOOT is not set + +# +# Security support +# +CONFIG_HASH=y + +# +# SPL / TPL +# +CONFIG_SUPPORT_SPL=y +CONFIG_SUPPORT_TPL=y +CONFIG_SPL=y +# CONFIG_SPL_BOARD_INIT is not set +# CONFIG_SPL_BOOTROM_SUPPORT is not set +CONFIG_SPL_RAW_IMAGE_SUPPORT=y +CONFIG_SPL_LEGACY_IMAGE_SUPPORT=y +CONFIG_SPL_SYS_MALLOC_SIMPLE=y +# CONFIG_TPL_SYS_MALLOC_SIMPLE is not set +CONFIG_SPL_STACK_R=y +CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x100000 +# CONFIG_SPL_SEPARATE_BSS is not set +# CONFIG_SPL_DISPLAY_PRINT is not set +CONFIG_SPL_SKIP_RELOCATE=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x4000 +# CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION is not set +# CONFIG_SPL_CRC32_SUPPORT is not set +# CONFIG_SPL_MD5_SUPPORT is not set +# CONFIG_SPL_SHA1_SUPPORT is not set +# CONFIG_SPL_SHA256_SUPPORT is not set +# CONFIG_SPL_FIT_IMAGE_TINY is not set +# CONFIG_SPL_CPU_SUPPORT is not set +# CONFIG_SPL_CRYPTO_SUPPORT is not set +# CONFIG_SPL_HASH_SUPPORT is not set +# CONFIG_SPL_DMA_SUPPORT is not set +# CONFIG_SPL_ENV_SUPPORT is not set +# CONFIG_SPL_EXT_SUPPORT is not set +# CONFIG_SPL_FPGA_SUPPORT is not set +# CONFIG_SPL_I2C_SUPPORT is not set +# CONFIG_SPL_MPC8XXX_INIT_DDR_SUPPORT is not set +# CONFIG_SPL_MTD_SUPPORT is not set +# CONFIG_SPL_MUSB_NEW_SUPPORT is not set +# CONFIG_SPL_NET_SUPPORT is not set +# CONFIG_SPL_NO_CPU_SUPPORT is not set +# CONFIG_SPL_NOR_SUPPORT is not set +# CONFIG_SPL_XIP_SUPPORT is not set +# CONFIG_SPL_ONENAND_SUPPORT is not set +# CONFIG_SPL_OS_BOOT is not set +# CONFIG_SPL_PCI_SUPPORT is not set +# CONFIG_SPL_PCH_SUPPORT is not set +# CONFIG_SPL_POST_MEM_SUPPORT is not set +# CONFIG_SPL_POWER_SUPPORT is not set +# CONFIG_SPL_RAM_SUPPORT is not set +# CONFIG_SPL_RTC_SUPPORT is not set +# CONFIG_SPL_SATA_SUPPORT is not set +# CONFIG_SPL_USB_HOST_SUPPORT is not set +# CONFIG_SPL_USB_GADGET_SUPPORT is not set +# CONFIG_SPL_YMODEM_SUPPORT is not set +CONFIG_SPL_ATF=y +# CONFIG_SPL_OPTEE_SUPPORT is not set +CONFIG_SPL_ATF_NO_PLATFORM_PARAM=y +# CONFIG_SPL_OPTEE is not set +# CONFIG_SPL_AB is not set +# CONFIG_SPL_LOAD_RKFW is not set +CONFIG_TPL=y +# CONFIG_TPL_BOARD_INIT is not set +# CONFIG_TPL_NEEDS_SEPARATE_TEXT_BASE is not set +# CONFIG_TPL_NEEDS_SEPARATE_STACK is not set +# CONFIG_TPL_BOOTROM_SUPPORT is not set +# CONFIG_TPL_DRIVERS_MISC_SUPPORT is not set +# CONFIG_TPL_ENV_SUPPORT is not set +# CONFIG_TPL_I2C_SUPPORT is not set +CONFIG_TPL_TINY_FRAMEWORK=y +# CONFIG_TPL_MPC8XXX_INIT_DDR_SUPPORT is not set +# CONFIG_TPL_MMC_SUPPORT is not set +# CONFIG_TPL_NAND_SUPPORT is not set +CONFIG_TPL_SERIAL_SUPPORT=y +# CONFIG_TPL_SPI_FLASH_SUPPORT is not set +# CONFIG_TPL_SPI_SUPPORT is not set + +# +# Command line interface +# +CONFIG_CMDLINE=y +CONFIG_HUSH_PARSER=y +CONFIG_SYS_PROMPT="=> " + +# +# Autoboot options +# +CONFIG_AUTOBOOT=y +# CONFIG_AUTOBOOT_KEYED is not set + +# +# FASTBOOT +# +# CONFIG_FASTBOOT is not set + +# +# Commands +# + +# +# Info commands +# +CONFIG_CMD_BDI=y +# CONFIG_CMD_CONFIG is not set +CONFIG_CMD_CONSOLE=y +# CONFIG_CMD_CPU is not set +# CONFIG_CMD_LICENSE is not set + +# +# Boot commands +# +CONFIG_CMD_BOOTD=y +CONFIG_CMD_BOOTM=y +# CONFIG_CMD_BOOTZ is not set +CONFIG_CMD_BOOTI=y +CONFIG_CMD_BOOTEFI=y +CONFIG_CMD_BOOTEFI_HELLO_COMPILE=y +# CONFIG_CMD_BOOTEFI_HELLO is not set +# CONFIG_CMD_BOOTMENU is not set +# CONFIG_CMD_DTIMG is not set +CONFIG_CMD_ELF=y +CONFIG_CMD_FDT=y +CONFIG_CMD_GO=y +CONFIG_CMD_RUN=y +CONFIG_CMD_IMI=y +# CONFIG_CMD_IMLS is not set +CONFIG_CMD_XIMG=y +CONFIG_CMD_POWEROFF=y +# CONFIG_CMD_SPL is not set +# CONFIG_CMD_THOR_DOWNLOAD is not set +# CONFIG_CMD_ZBOOT is not set + +# +# Environment commands +# +# CONFIG_CMD_ASKENV is not set +CONFIG_CMD_EXPORTENV=y +CONFIG_CMD_IMPORTENV=y +CONFIG_CMD_EDITENV=y +# CONFIG_CMD_GREPENV is not set +CONFIG_CMD_SAVEENV=y +CONFIG_CMD_ENV_EXISTS=y +# CONFIG_CMD_ENV_CALLBACK is not set +# CONFIG_CMD_ENV_FLAGS is not set + +# +# Memory commands +# +CONFIG_CMD_CRC32=y +# CONFIG_CRC32_VERIFY is not set +# CONFIG_CMD_EEPROM is not set +# CONFIG_LOOPW is not set +CONFIG_CMD_MD5SUM=y +CONFIG_MD5SUM_VERIFY=y +# CONFIG_CMD_MEMINFO is not set +CONFIG_CMD_MEMORY=y +# CONFIG_CMD_MEMTEST is not set +# CONFIG_CMD_MX_CYCLIC is not set +# CONFIG_CMD_SHA1SUM is not set +# CONFIG_CMD_STRINGS is not set + +# +# Compression commands +# +CONFIG_CMD_LZMADEC=y +CONFIG_CMD_UNZIP=y +# CONFIG_CMD_ZIP is not set + +# +# Device access commands +# +# CONFIG_CMD_ARMFLASH is not set +CONFIG_CMD_CLK=y +# CONFIG_CMD_DEMO is not set +# CONFIG_CMD_DFU is not set +CONFIG_CMD_DM=y +# CONFIG_CMD_FDC is not set +# CONFIG_CMD_FLASH is not set +# CONFIG_CMD_FPGA is not set +# CONFIG_CMD_FPGAD is not set +# CONFIG_CMD_FUSE is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_GPT=y +CONFIG_RANDOM_UUID=y +# CONFIG_CMD_GPT_RENAME is not set +# CONFIG_CMD_IDE is not set +# CONFIG_CMD_IO is not set +# CONFIG_CMD_IOTRACE is not set +CONFIG_CMD_I2C=y +CONFIG_CMD_LOADB=y +CONFIG_CMD_LOADS=y +CONFIG_CMD_BOOT_ROCKCHIP=y +CONFIG_CMD_MMC=y +# CONFIG_CMD_MTD is not set +# CONFIG_CMD_NAND is not set +# CONFIG_CMD_MMC_SPI is not set +# CONFIG_CMD_ONENAND is not set +CONFIG_CMD_PART=y +# CONFIG_CMD_PCI is not set +# CONFIG_CMD_PCMCIA is not set +# CONFIG_CMD_READ is not set +CONFIG_CMD_ROCKUSB=y +# CONFIG_CMD_RKNAND is not set +CONFIG_CMD_RKSFC=y +# CONFIG_CMD_RK_SECURE_STORAGE is not set +# CONFIG_CMD_SATA is not set +# CONFIG_CMD_SAVES is not set +# CONFIG_CMD_SDRAM is not set +CONFIG_CMD_SF=y +# CONFIG_CMD_SF_TEST is not set +CONFIG_CMD_SPI=y +# CONFIG_CMD_TSI148 is not set +# CONFIG_CMD_UNIVERSE is not set +CONFIG_CMD_USB=y +# CONFIG_CMD_USB_SDP is not set +CONFIG_CMD_USB_MASS_STORAGE=y + +# +# Shell scripting commands +# +CONFIG_CMD_ECHO=y +CONFIG_CMD_ITEST=y +CONFIG_CMD_SOURCE=y +CONFIG_CMD_SETEXPR=y + +# +# Network commands +# +CONFIG_CMD_NET=y +# CONFIG_CMD_TFTPPUT is not set +# CONFIG_CMD_TFTPSRV is not set +# CONFIG_CMD_RARP is not set +CONFIG_CMD_DHCP=y +CONFIG_CMD_PXE=y +CONFIG_CMD_NFS=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y +CONFIG_CMD_CDP=y +CONFIG_CMD_SNTP=y +CONFIG_CMD_DNS=y +CONFIG_CMD_LINK_LOCAL=y +CONFIG_CMD_ETHSW=y +CONFIG_CMD_MEMTESTER=y +# CONFIG_CMD_DDR_TEST_TOOL is not set + +# +# Misc commands +# +CONFIG_CMD_BMP=y +# CONFIG_CMD_BSP is not set +# CONFIG_CMD_BKOPS_ENABLE is not set +# CONFIG_CMD_CACHE is not set +# CONFIG_CMD_DISPLAY is not set +CONFIG_CMD_LED=y +# CONFIG_CMD_DATE is not set +# CONFIG_CMD_TIME is not set +# CONFIG_CMD_GETTIME is not set +CONFIG_CMD_MISC=y +CONFIG_CMD_TIMER=y +CONFIG_CMD_SOUND=y +# CONFIG_CMD_QFW is not set +# CONFIG_CMD_TERMINAL is not set +# CONFIG_CMD_UUID is not set + +# +# Power commands +# +CONFIG_CMD_PMIC=y +CONFIG_CMD_REGULATOR=y +CONFIG_CMD_CHARGE_DISPLAY=y + +# +# Security commands +# +# CONFIG_CMD_AES is not set +# CONFIG_CMD_BLOB is not set +# CONFIG_CMD_HASH is not set + +# +# Firmware commands +# + +# +# Filesystem commands +# +CONFIG_CMD_EXT2=y +CONFIG_CMD_EXT4=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +CONFIG_CMD_FS_UUID=y +# CONFIG_CMD_JFFS2 is not set +# CONFIG_CMD_MTDPARTS is not set +# CONFIG_CMD_MTD_BLK is not set +# CONFIG_CMD_REISER is not set +# CONFIG_CMD_SCSI is not set +# CONFIG_CMD_ZFS is not set + +# +# Debug commands +# +# CONFIG_CMD_BEDBUG is not set +# CONFIG_CMD_DIAG is not set +# CONFIG_CMD_KGDB is not set +# CONFIG_CMD_LOG is not set +# CONFIG_CMD_TRACE is not set +# CONFIG_CMD_UBI is not set + +# +# ODROID commands +# +CONFIG_CMD_ODROID_ADC=y +CONFIG_CMD_ODROID_CFGLOAD=y +CONFIG_CMD_ODROID_BATTERY=y +CONFIG_CMD_ODROID_TEST=y +CONFIG_CMD_ODROID_HWREV=y + +# +# Partition Types +# +CONFIG_PARTITIONS=y +# CONFIG_MAC_PARTITION is not set +# CONFIG_SPL_MAC_PARTITION is not set +CONFIG_DOS_PARTITION=y +CONFIG_SPL_DOS_PARTITION=y +CONFIG_ISO_PARTITION=y +CONFIG_SPL_ISO_PARTITION=y +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_SPL_AMIGA_PARTITION is not set +CONFIG_EFI_PARTITION=y +CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=128 +CONFIG_EFI_PARTITION_ENTRIES_OFF=0 +CONFIG_SPL_EFI_PARTITION=y +CONFIG_PARTITION_UUIDS=y +CONFIG_SPL_PARTITION_UUIDS=y +# CONFIG_PARTITION_TYPE_GUID is not set +CONFIG_RKPARM_PARTITION=y +# CONFIG_SPL_ROCKCHIP_PARTITION is not set +CONFIG_SUPPORT_OF_CONTROL=y +CONFIG_DTC=y + +# +# Device Tree Control +# +CONFIG_OF_CONTROL=y +# CONFIG_OF_BOARD_FIXUP is not set +CONFIG_SPL_OF_CONTROL=y +# CONFIG_TPL_OF_CONTROL is not set +CONFIG_OF_LIVE=y +CONFIG_OF_SEPARATE=y +# CONFIG_OF_EMBED is not set +# CONFIG_OF_BOARD is not set +CONFIG_OF_LIST="odroidgoa" +# CONFIG_MULTI_DTB_FIT is not set +# CONFIG_SPL_MULTI_DTB_FIT is not set +CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" +# CONFIG_SPL_OF_PLATDATA is not set +CONFIG_MKIMAGE_DTC_PATH="dtc" + +# +# Environment +# +# CONFIG_ENV_IS_NOWHERE is not set +# CONFIG_ENV_IS_IN_EEPROM is not set +# CONFIG_ENV_IS_IN_FAT is not set +# CONFIG_ENV_IS_IN_FLASH is not set +CONFIG_ENV_IS_IN_MMC=y +# CONFIG_ENV_IS_IN_NAND is not set +# CONFIG_ENV_IS_IN_NVRAM is not set +# CONFIG_ENV_IS_IN_ONENAND is not set +# CONFIG_ENV_IS_IN_REMOTE is not set +# CONFIG_ENV_IS_IN_SPI_FLASH is not set +# CONFIG_ENV_IS_IN_UBI is not set +# CONFIG_ENV_IS_IN_BLK_DEV is not set +# CONFIG_ENV_AES is not set +CONFIG_NET=y +# CONFIG_NET_RANDOM_ETHADDR is not set +# CONFIG_NETCONSOLE is not set +CONFIG_NET_TFTP_VARS=y +CONFIG_BOOTP_PXE_CLIENTARCH=0x16 +CONFIG_BOOTP_VCI_STRING="U-Boot.armv8" + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_DM=y +CONFIG_SPL_DM=y +# CONFIG_TPL_DM is not set +CONFIG_DM_WARN=y +# CONFIG_DM_DEBUG is not set +CONFIG_DM_DEVICE_REMOVE=y +CONFIG_DM_STDIO=y +CONFIG_DM_SEQ_ALIAS=y +# CONFIG_SPL_DM_SEQ_ALIAS is not set +CONFIG_REGMAP=y +CONFIG_SPL_REGMAP=y +CONFIG_SYSCON=y +CONFIG_SPL_SYSCON=y +# CONFIG_DEVRES is not set +CONFIG_SIMPLE_BUS=y +CONFIG_SPL_SIMPLE_BUS=y +CONFIG_OF_TRANSLATE=y +# CONFIG_SPL_OF_TRANSLATE is not set +CONFIG_ADC=y +# CONFIG_ADC_EXYNOS is not set +# CONFIG_ADC_SANDBOX is not set +CONFIG_SARADC_ROCKCHIP=y +# CONFIG_SATA is not set + +# +# SATA/SCSI device support +# +CONFIG_BLK=y +CONFIG_SPL_BLK=y +# CONFIG_BLOCK_CACHE is not set +# CONFIG_IDE is not set + +# +# Boot count support +# +# CONFIG_BOOTCOUNT is not set + +# +# Clock +# +CONFIG_CLK=y +CONFIG_SPL_CLK=y +# CONFIG_CLK_AT91 is not set +# CONFIG_CPU is not set +# CONFIG_AMP is not set + +# +# Hardware crypto devices +# +# CONFIG_DM_CRYPTO is not set +# CONFIG_SPL_DM_CRYPTO is not set +# CONFIG_FSL_CAAM is not set +# CONFIG_SYS_FSL_SEC_BE is not set +# CONFIG_SYS_FSL_SEC_LE is not set + +# +# Demo for driver model +# +# CONFIG_DM_DEMO is not set + +# +# DFU support +# + +# +# DMA Support +# +# CONFIG_DMA is not set +# CONFIG_TI_EDMA3 is not set +CONFIG_FIRMWARE=y +CONFIG_ARM_PSCI_FW=y + +# +# FPGA support +# +# CONFIG_FPGA_ALTERA is not set +# CONFIG_FPGA_SOCFPGA is not set +# CONFIG_FPGA_XILINX is not set + +# +# GPIO Support +# +CONFIG_DM_GPIO=y +# CONFIG_ALTERA_PIO is not set +# CONFIG_DWAPB_GPIO is not set +# CONFIG_AT91_GPIO is not set +# CONFIG_ATMEL_PIO4 is not set +# CONFIG_INTEL_BROADWELL_GPIO is not set +# CONFIG_INTEL_ICH6_GPIO is not set +# CONFIG_IMX_RGPIO2P is not set +# CONFIG_LPC32XX_GPIO is not set +# CONFIG_MSM_GPIO is not set +# CONFIG_CMD_PCA953X is not set +# CONFIG_PCF8575_GPIO is not set +CONFIG_ROCKCHIP_GPIO=y +# CONFIG_CMD_TCA642X is not set +# CONFIG_TEGRA_GPIO is not set +# CONFIG_TEGRA186_GPIO is not set +# CONFIG_VYBRID_GPIO is not set +# CONFIG_DM_74X164 is not set +# CONFIG_DM_PCA953X is not set +# CONFIG_MPC85XX_GPIO is not set + +# +# I2C support +# +CONFIG_DM_I2C=y +# CONFIG_DM_I2C_COMPAT is not set +# CONFIG_I2C_SET_DEFAULT_BUS_NUM is not set +# CONFIG_DM_I2C_GPIO is not set +# CONFIG_SYS_I2C_FSL is not set +# CONFIG_SYS_I2C_CADENCE is not set +# CONFIG_SYS_I2C_DW is not set +# CONFIG_SYS_I2C_INTEL is not set +# CONFIG_SYS_I2C_IMX_LPI2C is not set +CONFIG_SYS_I2C_ROCKCHIP=y +# CONFIG_SYS_I2C_MVTWSI is not set +# CONFIG_I2C_MUX is not set +# CONFIG_DM_KEYBOARD is not set +CONFIG_DM_KEY=y +# CONFIG_DM_RC is not set +# CONFIG_CROS_EC_KEYB is not set +CONFIG_RK8XX_PWRKEY=y +CONFIG_ADC_KEY=y +CONFIG_GPIO_KEY=y +CONFIG_RK_KEY=y +CONFIG_PWRKEY_DNL_TRIGGER_NUM=0 + +# +# LED Support +# +CONFIG_LED=y +CONFIG_LED_BLINK=y +# CONFIG_SPL_LED is not set +CONFIG_LED_GPIO=y +# CONFIG_LED_STATUS is not set + +# +# Mailbox Controller Support +# +# CONFIG_DM_MAILBOX is not set + +# +# Memory Controller drivers +# + +# +# Multifunction device drivers +# +# CONFIG_MISC is not set +# CONFIG_SPL_MISC is not set +# CONFIG_CROS_EC is not set +# CONFIG_DS4510 is not set +# CONFIG_FSL_SEC_MON is not set +# CONFIG_MXC_OCOTP is not set +# CONFIG_NUVOTON_NCT6102D is not set +# CONFIG_PWRSEQ is not set +# CONFIG_PCA9551_LED is not set +# CONFIG_WINBOND_W83627 is not set + +# +# MMC Host controller Support +# +CONFIG_MMC=y +CONFIG_DM_MMC=y +CONFIG_SPL_DM_MMC=y +# CONFIG_SPL_MMC_TINY is not set +CONFIG_MMC_DW=y +# CONFIG_MMC_DW_K3 is not set +CONFIG_MMC_DW_ROCKCHIP=y +# CONFIG_MMC_MXC is not set +# CONFIG_MMC_PCI is not set +# CONFIG_MMC_OMAP_HS is not set +# CONFIG_MMC_SDHCI is not set + +# +# MTD Support +# +# CONFIG_MTD is not set +# CONFIG_MTD_NOR_FLASH is not set +# CONFIG_MTD_DEVICE is not set +# CONFIG_FLASH_CFI_DRIVER is not set +# CONFIG_NAND is not set + +# +# SPI Flash Support +# +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH=y +CONFIG_SF_DEFAULT_BUS=0 +CONFIG_SF_DEFAULT_CS=0 +CONFIG_SF_DEFAULT_MODE=3 +CONFIG_SF_DEFAULT_SPEED=1000000 +# CONFIG_SPI_FLASH_SFDP_SUPPORT is not set +# CONFIG_SPI_FLASH_BAR is not set +# CONFIG_SF_DUAL_FLASH is not set +# CONFIG_SPI_FLASH_ATMEL is not set +# CONFIG_SPI_FLASH_EON is not set +# CONFIG_SPI_FLASH_GIGADEVICE is not set +# CONFIG_SPI_FLASH_ISSI is not set +# CONFIG_SPI_FLASH_MACRONIX is not set +# CONFIG_SPI_FLASH_SPANSION is not set +# CONFIG_SPI_FLASH_STMICRO is not set +# CONFIG_SPI_FLASH_SST is not set +# CONFIG_SPI_FLASH_WINBOND is not set +# CONFIG_SPI_FLASH_XMC is not set +CONFIG_SPI_FLASH_XTX=y +CONFIG_SPI_FLASH_USE_4K_SECTORS=y +# CONFIG_SPI_FLASH_DATAFLASH is not set +# CONFIG_SPI_FLASH_MTD is not set + +# +# UBI support +# +# CONFIG_CONFIG_UBI_SILENCE_MSG is not set +# CONFIG_MTD_UBI is not set +# CONFIG_BITBANGMII is not set +# CONFIG_MV88E6352_SWITCH is not set +# CONFIG_PHYLIB is not set +# CONFIG_DM_ETH is not set +# CONFIG_NETDEVICES is not set +# CONFIG_PCI is not set + +# +# PHY Subsystem +# +CONFIG_PHY=y +# CONFIG_SPL_PHY is not set +# CONFIG_NOP_PHY is not set +CONFIG_PHY_ROCKCHIP_INNO_USB2=y +# CONFIG_MVEBU_COMPHY_SUPPORT is not set + +# +# Pin controllers +# +CONFIG_PINCTRL=y +CONFIG_PINCTRL_FULL=y +CONFIG_PINCTRL_GENERIC=y +CONFIG_PINMUX=y +# CONFIG_PINCONF is not set +# CONFIG_SPL_PINCTRL is not set +# CONFIG_PINCTRL_AT91 is not set +# CONFIG_PINCTRL_AT91PIO4 is not set +CONFIG_PINCTRL_ROCKCHIP=y +# CONFIG_PINCTRL_SINGLE is not set +# CONFIG_PINCTRL_STM32 is not set + +# +# Power +# + +# +# Power Domain Support +# +# CONFIG_POWER_DOMAIN is not set +CONFIG_DM_FUEL_GAUGE=y +# CONFIG_POWER_FG_CW201X is not set +# CONFIG_POWER_FG_RK818 is not set +CONFIG_POWER_FG_RK817=y +# CONFIG_POWER_FG_RK816 is not set + +# +# IO Domain Support +# +# CONFIG_IO_DOMAIN is not set +CONFIG_DM_PMIC=y +CONFIG_PMIC_CHILDREN=y +CONFIG_SPL_PMIC_CHILDREN=y +# CONFIG_PMIC_ACT8846 is not set +# CONFIG_PMIC_AS3722 is not set +# CONFIG_DM_PMIC_PFUZE100 is not set +# CONFIG_DM_PMIC_MAX77686 is not set +# CONFIG_DM_PMIC_MAX8998 is not set +# CONFIG_PMIC_MAX8997 is not set +# CONFIG_PMIC_PM8916 is not set +CONFIG_PMIC_RK8XX=y +# CONFIG_PMIC_S2MPS11 is not set +# CONFIG_DM_PMIC_SANDBOX is not set +# CONFIG_PMIC_S5M8767 is not set +# CONFIG_PMIC_RN5T567 is not set +# CONFIG_PMIC_TPS65090 is not set +# CONFIG_PMIC_PALMAS is not set +# CONFIG_PMIC_LP873X is not set +# CONFIG_PMIC_LP87565 is not set +# CONFIG_POWER_MC34VR500 is not set +CONFIG_DM_REGULATOR=y +# CONFIG_SPL_DM_REGULATOR is not set +# CONFIG_REGULATOR_FAN53555 is not set +CONFIG_REGULATOR_PWM=y +CONFIG_DM_REGULATOR_FIXED=y +# CONFIG_SPL_DM_REGULATOR_FIXED is not set +# CONFIG_DM_REGULATOR_GPIO is not set +CONFIG_REGULATOR_RK8XX=y +# CONFIG_DM_DVFS is not set +# CONFIG_CHARGER_BQ25700 is not set +CONFIG_DM_CHARGE_DISPLAY=y +CONFIG_CHARGE_ANIMATION=y +CONFIG_ROCKCHIP_PM=y +CONFIG_DM_PWM=y +# CONFIG_PWM_EXYNOS is not set +CONFIG_PWM_ROCKCHIP=y +# CONFIG_PWM_SANDBOX is not set +# CONFIG_PWM_TEGRA is not set +CONFIG_RAM=y +CONFIG_SPL_RAM=y +CONFIG_TPL_RAM=y +# CONFIG_STM32_SDRAM is not set +# CONFIG_DM_RAMDISK is not set +# CONFIG_ROCKCHIP_DMC is not set +CONFIG_ROCKCHIP_SDRAM_COMMON=y +CONFIG_SDRAM_COMMON_CAP_DETECT=y +CONFIG_SDRAM_COMMON_OSREG=y +# CONFIG_SDRAM_COMMON_MSCH_RK3399 is not set +CONFIG_SDRAM_COMMON_MSCH_PX30=y + +# +# Remote Processor drivers +# + +# +# Reset Controller Support +# +CONFIG_DM_RESET=y +CONFIG_RESET_ROCKCHIP=y +CONFIG_RKNAND=y +CONFIG_ZFTL=y +CONFIG_RKFLASH=y + +# +# Rockchip Flash Devices +# +CONFIG_RKSFC_NOR=y + +# +# Real Time Clock +# +# CONFIG_DM_RTC is not set +# CONFIG_SCSI is not set +# CONFIG_DM_SCSI is not set + +# +# Serial drivers +# +CONFIG_BAUDRATE=1500000 +CONFIG_REQUIRE_SERIAL_CONSOLE=y +CONFIG_SERIAL_PRESENT=y +CONFIG_SPL_SERIAL_PRESENT=y +CONFIG_DM_SERIAL=y +# CONFIG_SERIAL_RX_BUFFER is not set +CONFIG_SPL_DM_SERIAL=y +CONFIG_TPL_DM_SERIAL=y +# CONFIG_DEBUG_UART_ALTERA_JTAGUART is not set +# CONFIG_DEBUG_UART_ALTERA_UART is not set +# CONFIG_DEBUG_UART_ATMEL is not set +CONFIG_DEBUG_UART_NS16550=y +# CONFIG_DEBUG_UART_S5P is not set +# CONFIG_DEBUG_UART_UARTLITE is not set +# CONFIG_DEBUG_UART_ARM_DCC is not set +# CONFIG_DEBUG_MVEBU_A3700_UART is not set +# CONFIG_DEBUG_UART_ZYNQ is not set +# CONFIG_DEBUG_UART_PL010 is not set +# CONFIG_DEBUG_UART_PL011 is not set +# CONFIG_DEBUG_UART_OMAP is not set +CONFIG_DEBUG_UART_BASE=0xFF160000 +CONFIG_DEBUG_UART_CLOCK=24000000 +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_DEBUG_UART_BOARD_INIT=y +# CONFIG_DEBUG_UART_ANNOUNCE is not set +# CONFIG_DEBUG_UART_SKIP_INIT is not set +# CONFIG_ALTERA_JTAG_UART is not set +# CONFIG_ALTERA_UART is not set +# CONFIG_ATMEL_USART is not set +# CONFIG_FSL_LPUART is not set +# CONFIG_MVEBU_A3700_UART is not set +CONFIG_SYS_NS16550=y +# CONFIG_MSM_SERIAL is not set +# CONFIG_PXA_SERIAL is not set + +# +# Sound support +# +CONFIG_SOUND=y +# CONFIG_I2S is not set +# CONFIG_I2S_SAMSUNG is not set +CONFIG_I2S_ROCKCHIP=y +CONFIG_SOUND_RK817=y +CONFIG_SOUND_ROCKCHIP=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_SPI_MEM=y +# CONFIG_ALTERA_SPI is not set +# CONFIG_ATCSPI200_SPI is not set +# CONFIG_ATMEL_SPI is not set +# CONFIG_CADENCE_QSPI is not set +# CONFIG_DESIGNWARE_SPI is not set +# CONFIG_EXYNOS_SPI is not set +# CONFIG_FSL_DSPI is not set +# CONFIG_ICH_SPI is not set +# CONFIG_MVEBU_A3700_SPI is not set +CONFIG_ROCKCHIP_SPI=y +# CONFIG_ROCKCHIP_SFC is not set +# CONFIG_TEGRA114_SPI is not set +# CONFIG_TEGRA20_SFLASH is not set +# CONFIG_TEGRA20_SLINK is not set +# CONFIG_TEGRA210_QSPI is not set +# CONFIG_XILINX_SPI is not set +# CONFIG_SOFT_SPI is not set +# CONFIG_CF_SPI is not set +# CONFIG_FSL_ESPI is not set +# CONFIG_FSL_QSPI is not set +# CONFIG_SH_SPI is not set +# CONFIG_SH_QSPI is not set +# CONFIG_TI_QSPI is not set +# CONFIG_KIRKWOOD_SPI is not set +# CONFIG_LPC32XX_SSP is not set +# CONFIG_MPC8XXX_SPI is not set +# CONFIG_MXC_SPI is not set +# CONFIG_MXS_SPI is not set +# CONFIG_OMAP3_SPI is not set + +# +# SPMI support +# +# CONFIG_SPMI is not set + +# +# System reset device drivers +# +CONFIG_SYSRESET=y +CONFIG_SPL_SYSRESET=y +CONFIG_SYSRESET_PSCI=y +# CONFIG_SYSRESET_SYSCON is not set +# CONFIG_SYSRESET_WATCHDOG is not set +# CONFIG_DM_THERMAL is not set + +# +# Timer Support +# +# CONFIG_TIMER is not set + +# +# TPM support +# +CONFIG_USB=y +CONFIG_DM_USB=y + +# +# USB Host Controller Drivers +# +CONFIG_USB_HOST=y +# CONFIG_USB_XHCI_HCD is not set +CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_MSM is not set +# CONFIG_USB_EHCI_PCI is not set +CONFIG_USB_EHCI_GENERIC=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_GENERIC=y +# CONFIG_USB_UHCI_HCD is not set +CONFIG_USB_DWC2=y +# CONFIG_USB_DWC3 is not set + +# +# MUSB Controller Driver +# +# CONFIG_USB_MUSB_HOST is not set +# CONFIG_USB_MUSB_GADGET is not set +# CONFIG_USB_MUSB_TI is not set + +# +# ULPI drivers +# + +# +# USB peripherals +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_KEYBOARD is not set +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_BCM_UDC_OTG_PHY is not set +CONFIG_USB_GADGET_DWC2_OTG=y +# CONFIG_USB_GADGET_DWC2_OTG_PHY_BUS_WIDTH_8 is not set +# CONFIG_CI_UDC is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_DUALSPEED=y +CONFIG_USB_GADGET_DOWNLOAD=y +# CONFIG_USB_FUNCTION_SDP is not set +CONFIG_G_DNL_MANUFACTURER="Rockchip" +CONFIG_G_DNL_VENDOR_NUM=0x2207 +CONFIG_G_DNL_PRODUCT_NUM=0x330d +CONFIG_USBNET_DEVADDR="de:ad:be:ef:00:01" +CONFIG_USB_HOST_ETHER=y +CONFIG_USB_ETHER_ASIX=y +CONFIG_USB_ETHER_ASIX88179=y +# CONFIG_USB_ETHER_LAN75XX is not set +# CONFIG_USB_ETHER_LAN78XX is not set +# CONFIG_USB_ETHER_MCS7830 is not set +CONFIG_USB_ETHER_RTL8152=y +CONFIG_USB_ETHER_SMSC95XX=y + +# +# Graphics support +# +CONFIG_DM_VIDEO=y +CONFIG_BACKLIGHT_PWM=y +# CONFIG_BACKLIGHT_GPIO is not set +CONFIG_VIDEO_BPP8=y +CONFIG_VIDEO_BPP16=y +CONFIG_VIDEO_BPP32=y +CONFIG_CONSOLE_NORMAL=y +CONFIG_CONSOLE_ROTATION=y +# CONFIG_CONSOLE_TRUETYPE is not set +CONFIG_SYS_WHITE_ON_BLACK=y + +# +# TrueType Fonts +# +# CONFIG_VIDCONSOLE_AS_LCD is not set +# CONFIG_VIDEO_VESA is not set +# CONFIG_VIDEO_LCD_ANX9804 is not set +# CONFIG_VIDEO_LCD_SSD2828 is not set +# CONFIG_VIDEO_MVEBU is not set +CONFIG_I2C_EDID=y +CONFIG_DISPLAY=y +# CONFIG_ATMEL_HLCD is not set +# CONFIG_VIDEO_ROCKCHIP is not set +CONFIG_DRM_ROCKCHIP=y +CONFIG_DRM_ROCKCHIP_PANEL=y +# CONFIG_DRM_ROCKCHIP_DW_HDMI is not set +# CONFIG_ROCKCHIP_INNO_HDMI_PHY is not set +# CONFIG_DRM_ROCKCHIP_INNO_MIPI_PHY is not set +# CONFIG_DRM_ROCKCHIP_INNO_VIDEO_PHY is not set +CONFIG_DRM_ROCKCHIP_INNO_VIDEO_COMBO_PHY=y +CONFIG_DRM_MIPI_DSI=y +CONFIG_DRM_ROCKCHIP_DW_MIPI_DSI=y +# CONFIG_DRM_ROCKCHIP_ANALOGIX_DP is not set +# CONFIG_DRM_ROCKCHIP_LVDS is not set +# CONFIG_DRM_ROCKCHIP_RGB is not set +# CONFIG_DRM_ROCKCHIP_RK618 is not set +# CONFIG_ROCKCHIP_DRM_TVE is not set +# CONFIG_VIDEO_TEGRA20 is not set +# CONFIG_VIDEO_TEGRA124 is not set +CONFIG_VIDEO_BRIDGE=y +# CONFIG_VIDEO_BRIDGE_PARADE_PS862X is not set +# CONFIG_VIDEO_BRIDGE_NXP_PTN3460 is not set +# CONFIG_VIDEO_BRIDGE_ANALOGIX_ANX6345 is not set +CONFIG_CONSOLE_SCROLL_LINES=1 +# CONFIG_LCD is not set + +# +# Watchdog Timer Support +# +# CONFIG_BCM2835_WDT is not set +# CONFIG_ULP_WATCHDOG is not set +# CONFIG_WDT is not set +CONFIG_IRQ=y +# CONFIG_PHYS_TO_BUS is not set + +# +# File systems +# +# CONFIG_FS_CBFS is not set +CONFIG_FS_FAT=y +CONFIG_FAT_WRITE=y +CONFIG_SUPPORT_VFAT=y +CONFIG_FS_FAT_MAX_CLUSTSIZE=65536 +# CONFIG_FS_JFFS2 is not set +# CONFIG_FS_CRAMFS is not set +# CONFIG_YAFFS2 is not set + +# +# Library routines +# +# CONFIG_BCH is not set +# CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED is not set +CONFIG_SYS_HZ=1000 +CONFIG_SYS_STACK_SIZE=0x200000 +CONFIG_USE_TINY_PRINTF=y +# CONFIG_PANIC_HANG is not set +CONFIG_REGEX=y +# CONFIG_LIB_RAND is not set +CONFIG_SPL_TINY_MEMSET=y +# CONFIG_TPL_TINY_MEMSET is not set +CONFIG_SYSMEM=y +CONFIG_BIDRAM=y +# CONFIG_CMD_DHRYSTONE is not set + +# +# Security support +# +# CONFIG_AES is not set +# CONFIG_RSA is not set +# CONFIG_TPM is not set + +# +# Hashing Support +# +CONFIG_SHA1=y +CONFIG_SHA256=y +# CONFIG_SHA512 is not set +# CONFIG_SHA_HW_ACCEL is not set +CONFIG_MD5=y + +# +# Compression Support +# +CONFIG_LZ4=y +CONFIG_LZMA=y +CONFIG_LZO=y +# CONFIG_SPL_LZO is not set +# CONFIG_SPL_GZIP is not set +CONFIG_ERRNO_STR=y +# CONFIG_HEXDUMP is not set +CONFIG_OF_LIBFDT=y +CONFIG_OF_LIBFDT_OVERLAY=y +CONFIG_SPL_OF_LIBFDT=y +# CONFIG_TPL_OF_LIBFDT is not set +# CONFIG_FDT_FIXUP_PARTITIONS is not set + +# +# System tables +# +CONFIG_GENERATE_SMBIOS_TABLE=y +CONFIG_SMBIOS_MANUFACTURER="rockchip" +CONFIG_EFI_LOADER=y +# CONFIG_EFI_LOADER_BOUNCE_BUFFER is not set +# CONFIG_AVB_LIBAVB is not set +# CONFIG_SPL_AVB_LIBAVB is not set +# CONFIG_TPL_AVB_LIBAVB is not set +# CONFIG_AVB_LIBAVB_AB is not set +# CONFIG_SPL_AVB_LIBAVB_AB is not set +# CONFIG_TPL_AVB_LIBAVB_AB is not set +# CONFIG_AVB_LIBAVB_ATX is not set +# CONFIG_SPL_AVB_LIBAVB_ATX is not set +# CONFIG_TPL_AVB_LIBAVB_ATX is not set +# CONFIG_AVB_LIBAVB_USER is not set +# CONFIG_SPL_AVB_LIBAVB_USER is not set +# CONFIG_TPL_AVB_LIBAVB_USER is not set +# CONFIG_RK_AVB_LIBAVB_USER is not set +# CONFIG_SPL_RK_AVB_LIBAVB_USER is not set +# CONFIG_TPL_RK_AVB_LIBAVB_USER is not set +CONFIG_OPTEE_CLIENT=y +# CONFIG_OPTEE_V1 is not set +CONFIG_OPTEE_V2=y +CONFIG_OPTEE_ALWAYS_USE_SECURITY_PARTITION=y +# CONFIG_UNIT_TEST is not set +CONFIG_TEST_ROCKCHIP=y +# CONFIG_LAVA_INFO is not set diff --git a/projects/ArchR/devices/RK3326/packages/u-boot/config/clone_boot.ini b/projects/ArchR/devices/RK3326/packages/u-boot/config/clone_boot.ini new file mode 100644 index 0000000000..f210443c5c --- /dev/null +++ b/projects/ArchR/devices/RK3326/packages/u-boot/config/clone_boot.ini @@ -0,0 +1,52 @@ +# distro_storagepart=$((${distro_bootpart} + 1)) +if test ${distro_bootpart} = '0'; then setenv distro_storagepart 1 +elif test ${distro_bootpart} = '1'; then setenv distro_storagepart 2 +elif test ${distro_bootpart} = '2'; then setenv distro_storagepart 3 +elif test ${distro_bootpart} = '3'; then setenv distro_storagepart 4 +else setenv distro_storagepart 2 +fi + +# reduce copy-paste referring to active partition +setenv thispart "${devtype} ${devnum}:${distro_bootpart}" +setenv storagepart "${devtype} ${devnum}:${distro_storagepart}" + +# Use device paths based on U-Boot mmc device number +setenv mmcdev ${devnum} +setenv partition_boot "/dev/mmcblk${mmcdev}p${distro_bootpart}" +setenv partition_root "/dev/mmcblk${mmcdev}p2" +setenv partition_storage "/dev/mmcblk${mmcdev}p3" + +# Just in case this script is executed by (patched?) hardkernel u-boot, recover adc value from hwrev +if test -n "${hwid_adc}"; then setenv adc ${hwid_adc}; echo "ADC ${hwid_adc}" # mainline u-boot, just use real value +elif test ${hwrev} = 'v10'; then setenv adc 856 # OGA +elif test ${hwrev} = 'v11'; then setenv adc 677 # OGABE +elif test ${hwrev} = 'v10-go3';then setenv adc 85 # OGS +elif test ${hwrev} = 'rg351v'; then setenv adc 515 +elif test ${hwrev} = 'r33s'; then setenv adc 165 +elif test ${hwrev} = 'xu10'; then setenv adc 1025 +elif test ${hwrev} = 'chi'; then setenv adc 475 +else setenv adc 65000 +fi + +# this will be passed to cmdline so that userspace can analyze boot criteria +if test -n "${hwid_adc}"; then setenv hwid_adc b,${hwid_adc}; +else setenv hwid_adc b,${hwrev} +fi + +# Depending on ADC value select a proper DTB +if itest.w ${adc} > 139 && itest.w ${adc} < 191; then + setenv fdtfile "rk3326-powkiddy-rgb10x.dtb" +elif itest.w ${adc} > 999 && itest.w ${adc} < 1051; then + setenv fdtfile "rk3326-magicx-xu-mini-m.dtb" +elif itest.w ${adc} > 489 && itest.w ${adc} < 541; then + setenv fdtfile "rk3326-gameconsole-eeclone.dtb" +else + echo "Unexpected ADC value ${adc}, falling back to OGA dtb" + setenv fdtfile "rk3326-odroid-go2.dtb" +fi + +# Let syslinux do the load stuff. +# User will be able to edit extlinux.conf if needed +setenv kernel_addr_r "0x09000000" +setenv fdtoverlay_addr_r "0x08000000" +sysboot ${thispart} any 0x100000 /extlinux/extlinux.conf diff --git a/projects/ArchR/devices/RK3326/packages/u-boot/config/extlinux/README.txt b/projects/ArchR/devices/RK3326/packages/u-boot/config/extlinux/README.txt new file mode 100644 index 0000000000..3430626160 --- /dev/null +++ b/projects/ArchR/devices/RK3326/packages/u-boot/config/extlinux/README.txt @@ -0,0 +1,15 @@ +extlinux.conf is a file which has a final word when describing how to boot your device. + +Usually u-boot runs boot.scr which checks some hardware stuff (ADC voltage, some GPIO levels), +chooses a dtb based on collected data and passes that to extlinux. + +Thay may fail if you have a rare device or faulty hardware or something else unexpected. +In this case you can configure extlinux.conf manually. +Main things to edit: + * APPEND -- kernel cmdline. If you have UART soldered you may want to remove 'quiet' option. + Also this parameter can modify kernel behaviour (e.g. disable or configure drivers) + * FDT -- a path to .dtb file to use. Please note that uboot's extlinux has a poor parser, + and even a space after dtb file path breaks the boot. + * FDTOVERLAYS -- dtb overlays to apply. This line can point to non-existing files, that's ok. + Overlays may be used to apply configuration specific to your device + (e.g. joystic axis inversion, display init sequence, etc.) diff --git a/projects/ArchR/devices/RK3326/packages/u-boot/config/extlinux/extlinux.conf b/projects/ArchR/devices/RK3326/packages/u-boot/config/extlinux/extlinux.conf new file mode 100644 index 0000000000..9fcca88fe9 --- /dev/null +++ b/projects/ArchR/devices/RK3326/packages/u-boot/config/extlinux/extlinux.conf @@ -0,0 +1,7 @@ +LABEL ArchR + LINUX /KERNEL + FDTDIR /dtbs/ + ## FDT: don't forget the leading slash, remove all symbols after .dtb (including whitespace) + # FDT /dtbs/your-custom-devicetree.dtb + FDTOVERLAYS /overlays/mipi-panel.dtbo + APPEND boot=${partition_boot} root=${partition_root} disk=${partition_storage} @EXTRA_CMDLINE@ uboot.hwid_adc=${hwid_adc} diff --git a/projects/ArchR/devices/RK3326/packages/u-boot/config/original_boot.ini b/projects/ArchR/devices/RK3326/packages/u-boot/config/original_boot.ini new file mode 100644 index 0000000000..182dced0a1 --- /dev/null +++ b/projects/ArchR/devices/RK3326/packages/u-boot/config/original_boot.ini @@ -0,0 +1,75 @@ +# Legacy u-boot doesn't have distro_bootpart +if test -z "${distro_bootpart}"; then + echo "No distro_bootpart; setting it to 1" + setenv distro_bootpart 1 +fi + +# distro_storagepart=$((${distro_bootpart} + 1)) +if test ${distro_bootpart} = '0'; then setenv distro_storagepart 1 +elif test ${distro_bootpart} = '1'; then setenv distro_storagepart 2 +elif test ${distro_bootpart} = '2'; then setenv distro_storagepart 3 +elif test ${distro_bootpart} = '3'; then setenv distro_storagepart 4 +else setenv distro_storagepart 2 +fi + +# reduce copy-paste referring to active partition +setenv thispart "${devtype} ${devnum}:${distro_bootpart}" +setenv storagepart "${devtype} ${devnum}:${distro_storagepart}" + +# Use device paths based on U-Boot mmc device number +# mmc 1 in U-Boot = /dev/mmcblk1 in Linux (SD card on RK3326) +setenv mmcdev ${devnum} +setenv partition_boot "/dev/mmcblk${mmcdev}p${distro_bootpart}" +setenv partition_root "/dev/mmcblk${mmcdev}p2" +setenv partition_storage "/dev/mmcblk${mmcdev}p3" + +# Just in case this script is executed by (patched?) hardkernel u-boot, recover adc value from hwrev +if test -n "${hwid_adc}"; then setenv adc ${hwid_adc}; echo "ADC ${hwid_adc}" # mainline u-boot, just use real value +elif test ${hwrev} = 'v10'; then setenv adc 856 # OGA +elif test ${hwrev} = 'v11'; then setenv adc 677 # OGABE +elif test ${hwrev} = 'v10-go3';then setenv adc 85 # OGS +elif test ${hwrev} = 'rg351v'; then setenv adc 515 +elif test ${hwrev} = 'r33s'; then setenv adc 165 +elif test ${hwrev} = 'xu10'; then setenv adc 1025 +elif test ${hwrev} = 'chi'; then setenv adc 475 +else setenv adc 65000 +fi + +# this will be passed to cmdline so that userspace can analyze boot criteria +if test -n "${hwid_adc}"; then setenv hwid_adc a,${hwid_adc}; +else setenv hwid_adc a,${hwrev} +fi + +# Depending on ADC value select a proper DTB +if itest.w ${adc} > 59 && itest.w ${adc} < 111; then + setenv fdtfile "rk3326-odroid-go3.dtb" +elif itest.w ${adc} > 139 && itest.w ${adc} < 191; then + setenv fdtfile "rk3326-gameconsole-r36s.dtb" +elif itest.w ${adc} > 449 && itest.w ${adc} < 496; then + setenv fdtfile "rk3326-gameforce-chi.dtb" +elif itest.w ${adc} < 541; then + setenv fdtfile "rk3326-anbernic-rg351v.dtb" +elif itest.w ${adc} > 651 && itest.w ${adc} < 703; then + if gpio input c22; then + if gpio input d9; then + setenv fdtfile "rk3326-powkiddy-rgb10.dtb" + else + setenv fdtfile "rk3326-odroid-go2-v11.dtb" + fi + else + setenv fdtfile "rk3326-anbernic-rg351m.dtb" + fi +elif itest.w ${adc} > 830 && itest.w ${adc} < 882; then + setenv fdtfile "rk3326-odroid-go2.dtb" +elif itest.w ${adc} > 999 && itest.w ${adc} < 1051; then + setenv fdtfile "rk3326-magicx-xu10.dtb" +else + echo "Unexpected ADC value ${adc}, falling back to OGA dtb" + setenv fdtfile "rk3326-odroid-go2.dtb" +fi + +# Let syslinux do the load stuff. +# User will be able to edit extlinux.conf if needed +setenv kernel_addr_r "0x09000000" +setenv fdtoverlay_addr_r "0x08000000" +sysboot ${thispart} any 0x100000 /extlinux/extlinux.conf diff --git a/projects/ArchR/devices/RK3326/packages/u-boot/config/overlays/README.txt b/projects/ArchR/devices/RK3326/packages/u-boot/config/overlays/README.txt new file mode 100644 index 0000000000..0360b6d208 --- /dev/null +++ b/projects/ArchR/devices/RK3326/packages/u-boot/config/overlays/README.txt @@ -0,0 +1,12 @@ +Here your device tree overlays live. +Currently only mipi-panel.dtbo is expected which is intended for display driver stuff. + +For R36s, rg351*-v2 and maybe other devices you may need to put a proper mipi-panel.dtbo +to make display work. +See https://arch-r.io/devices/unbranded/game-console-r35s-r36s/#new-displays-r36s-of-year-2024 + +Despite the name, mipi-panel.dtbo is also abused for quite a complex tuning +of EE clones of year 2025, but in this case the overlay is usually generated automatically. +In some cases (something is misdetected) you may want to replace mipi-panel.dtbo +with whatever you need. +See https://arch-r.io/devices/unbranded/EE-clones/#in-case-of-issues-with-displaysoundetc diff --git a/projects/ArchR/devices/RK3326/packages/u-boot/config/stock/README.txt b/projects/ArchR/devices/RK3326/packages/u-boot/config/stock/README.txt new file mode 100644 index 0000000000..30bddee4c1 --- /dev/null +++ b/projects/ArchR/devices/RK3326/packages/u-boot/config/stock/README.txt @@ -0,0 +1,4 @@ +On some devices (EE clones) you can put your stock .dtb file +to this dir if the wizard could not locate it automatically. + +See https://arch-r.io/devices/unbranded/EE-clones/ for info diff --git a/projects/ArchR/devices/RK3326/packages/u-boot/package.mk b/projects/ArchR/devices/RK3326/packages/u-boot/package.mk new file mode 100644 index 0000000000..a1fd13a1e5 --- /dev/null +++ b/projects/ArchR/devices/RK3326/packages/u-boot/package.mk @@ -0,0 +1,112 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="u-boot" +PKG_VERSION="v2025.10" +PKG_LICENSE="GPL" +PKG_SITE="https://www.denx.de/wiki/U-Boot" +PKG_URL="https://github.com/u-boot/u-boot/archive/refs/tags/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain Python3:host swig:host pyelftools:host u-boot-legacy" +PKG_LONGDESC="Das U-Boot is a cross-platform bootloader for embedded systems." +PKG_TOOLCHAIN="manual" + +PKG_NEED_UNPACK="${PROJECT_DIR}/${PROJECT}/bootloader ${PROJECT_DIR}/${PROJECT}/devices/${DEVICE}/bootloader" +PKG_NEED_UNPACK+=" ${PROJECT_DIR}/${PROJECT}/options ${PROJECT_DIR}/${PROJECT}/devices/${DEVICE}/options" + +if [ -n "${UBOOT_FIRMWARE}" ]; then + PKG_DEPENDS_TARGET+=" ${UBOOT_FIRMWARE}" + PKG_DEPENDS_UNPACK+=" ${UBOOT_FIRMWARE}" +fi + +pre_make_target() { + PKG_UBOOT_CONFIG="rk3326-handheld_defconfig" + PKG_RKBIN="$(get_build_dir rkbin)" + PKG_MINILOADER="${PKG_RKBIN}/bin/rk33/rk3326_miniloader_v1.40.bin" + PKG_BL31="${PKG_RKBIN}/bin/rk33/rk3326_bl31_v1.34.elf" + PKG_DDR_BIN="${PKG_RKBIN}/bin/rk33/rk3326_ddr_333MHz_v2.11.bin" + PKG_DDR_BIN_UART5="${PKG_RKBIN}/rk3326_ddr_uart5.bin" +} + +make_target() { + [ "${BUILD_WITH_DEBUG}" = "yes" ] && PKG_DEBUG=1 || PKG_DEBUG=0 + setup_pkg_config_host + + find_file_path bootloader/rkhelper || exit 4 + RKHELPER=${FOUND_PATH} + + DEBUG=${PKG_DEBUG} CROSS_COMPILE="${TARGET_KERNEL_PREFIX}" LDFLAGS="" ARCH=arm make mrproper + DEBUG=${PKG_DEBUG} CROSS_COMPILE="${TARGET_KERNEL_PREFIX}" LDFLAGS="" ARCH=arm make ${PKG_UBOOT_CONFIG} + DEBUG=${PKG_DEBUG} CROSS_COMPILE="${TARGET_KERNEL_PREFIX}" LDFLAGS="" ARCH=arm \ + _python_sysroot="${TOOLCHAIN}" _python_prefix=/ _python_exec_prefix=/ \ + make HOSTCC="${HOST_CC}" HOSTLDFLAGS="-L${TOOLCHAIN}/lib" HOSTSTRIP="true" \ + u-boot-dtb.bin + . ${RKHELPER} + mv uboot.bin uboot.bin.default + + ./scripts/config --set-val CONFIG_DEBUG_UART_BASE 0xFF178000 + ./scripts/config --set-str CONFIG_DEVICE_TREE_INCLUDES "rk3326-odroid-go2-emmc.dtsi rk3326-odroid-go2-uart5.dtsi" + DEBUG=${PKG_DEBUG} CROSS_COMPILE="${TARGET_KERNEL_PREFIX}" LDFLAGS="" ARCH=arm \ + _python_sysroot="${TOOLCHAIN}" _python_prefix=/ _python_exec_prefix=/ \ + make HOSTCC="${HOST_CC}" HOSTLDFLAGS="-L${TOOLCHAIN}/lib" HOSTSTRIP="true" \ + u-boot-dtb.bin + PKG_DDR_BIN=${PKG_DDR_BIN_UART5} . ${RKHELPER} + mv uboot.bin uboot.bin.uart5 +} + +generate_custom_extlinux_conf_files() { + INI_FILES="" + for SUBDEVICE in ${SUBDEVICES}; do + if find_file_path config/${SUBDEVICE}_boot.ini; then + INI_FILES="${INI_FILES} ${FOUND_PATH}" + fi + done + EXTLCONF0=${INSTALL}/usr/share/bootloader/extlinux/extlinux.conf + + echo "INI_FILES ${INI_FILES}" + for dtbase in $(xmlstarlet sel -t -v "//archr/${DEVICE}/*" ${CONFIGXML}); do + if ! grep -q "\<${dtbase}.dtb" ${INI_FILES}; then + EXTLCONF=${EXTLCONF0}.${dtbase##*-} + echo "Generating ${EXTLCONF} for ${dtbase}" + sed '/##/d;s|^.* FDT .*$| FDT /dtbs/'${dtbase}'.dtb|' ${EXTLCONF0} > ${EXTLCONF0}.${dtbase##*-} + fi + done +} + +makeinstall_target() { + mkdir -p $INSTALL/usr/share/bootloader + + for SUBDEVICE in ${SUBDEVICES}; do + if find_file_path config/${SUBDEVICE}_boot.ini; then + cp -av ${FOUND_PATH} . + sed -e "s/@DISTRO_BOOTLABEL@/${DISTRO_BOOTLABEL}/" \ + -e "s/@DISTRO_ROOTLABEL@/${DISTRO_ROOTLABEL}/" \ + -e "s/@DISTRO_DISKLABEL@/${DISTRO_DISKLABEL}/" \ + -e "s/@EXTRA_CMDLINE@/${EXTRA_CMDLINE}/" \ + -i "${SUBDEVICE}_boot.ini" + ./tools/mkimage -T script -d "${SUBDEVICE}_boot.ini" "${SUBDEVICE}_boot.scr" + cp -av "${SUBDEVICE}_boot.scr" "${INSTALL}/usr/share/bootloader/" + fi + done + + cp -av uboot.bin.default "${INSTALL}/usr/share/bootloader/clone_uboot.bin" + cp -av uboot.bin.uart5 "${INSTALL}/usr/share/bootloader/clone_uboot.bin.uart5" + + find_dir_path config/extlinux || exit 3 + cp -av ${FOUND_PATH} "${INSTALL}/usr/share/bootloader/" + sed -e "s/@EXTRA_CMDLINE@/${EXTRA_CMDLINE}/" \ + -i ${INSTALL}/usr/share/bootloader/extlinux/* + + generate_custom_extlinux_conf_files + + find_dir_path config/stock && cp -av ${FOUND_PATH} "${INSTALL}/usr/share/bootloader/" + + # Install per-SUBDEVICE panel overlays (original + clone) + for sd in ${SUBDEVICES}; do + if find_dir_path config/overlays_${sd}; then + mkdir -p "${INSTALL}/usr/share/bootloader/overlays_${sd}" + cp -av ${FOUND_PATH}/*.dtbo "${INSTALL}/usr/share/bootloader/overlays_${sd}/" 2>/dev/null || true + fi + done + # Also install generic overlays dir (README, fallback) + find_dir_path config/overlays && cp -av ${FOUND_PATH} "${INSTALL}/usr/share/bootloader/" +} diff --git a/projects/ArchR/devices/RK3326/packages/u-boot/patches/0001-add-support-for-k36-clone-with-emmc-rk3326.patch b/projects/ArchR/devices/RK3326/packages/u-boot/patches/0001-add-support-for-k36-clone-with-emmc-rk3326.patch new file mode 100644 index 0000000000..3d73d62fe9 --- /dev/null +++ b/projects/ArchR/devices/RK3326/packages/u-boot/patches/0001-add-support-for-k36-clone-with-emmc-rk3326.patch @@ -0,0 +1,62 @@ +From 8d4137bf6726fde54a60d84b393521a2145d349c Mon Sep 17 00:00:00 2001 +From: Danil Zagoskin +Date: Sat, 21 Jun 2025 15:38:11 +0300 +Subject: [PATCH] support for k36 clones with emmc and uart5 + +--- + board/hardkernel/odroid_go2/go2.c | 12 +- + +diff --git a/board/hardkernel/odroid_go2/go2.c b/board/hardkernel/odroid_go2/go2.c +index a0338ead3b..fe12532a5a 100644 +--- a/board/hardkernel/odroid_go2/go2.c ++++ b/board/hardkernel/odroid_go2/go2.c +@@ -23,6 +23,7 @@ enum oga_device_id { + OGA, + OGA_V11, + OGS, ++ GENERIC + }; + + /* +@@ -48,6 +49,12 @@ static const struct oga_model oga_model_details[] = { + "ODROID-GO Super", + DTB_DIR "rk3326-odroid-go3.dtb", + }, ++ [GENERIC] = { ++ 65000, ++ "rk3326-generic", ++ "UNKNOWN", ++ DTB_DIR "rk3326-generic.dtb", ++ }, + }; + + /* Detect which Odroid Go Advance device we are using so as to load the +@@ -72,15 +79,15 @@ int oga_detect_device(void) + * accounted for this with a 5% tolerance, so assume a +- value + * of 50 should be enough. + */ +- for (i = 0; i < ARRAY_SIZE(oga_model_details); i++) { ++ for (i = 0; i < ARRAY_SIZE(oga_model_details) - 1; i++) { + u32 adc_min = oga_model_details[i].adc_value - 50; + u32 adc_max = oga_model_details[i].adc_value + 50; + + if (adc_min < adc_info && adc_max > adc_info) { +- board_id = i; + break; + } + } ++ board_id = i; + + if (board_id < 0) + return board_id; +@@ -89,6 +96,7 @@ int oga_detect_device(void) + env_set("board_name", + oga_model_details[board_id].board_name); + env_set("fdtfile", oga_model_details[board_id].fdtfile); ++ env_set_ulong("hwid_adc", adc_info); + + return 0; + } +-- +2.49.0 + diff --git a/projects/ArchR/devices/RK3326/packages/u-boot/sources/arch/arm/dts/rk3326-odroid-go2-emmc.dtsi b/projects/ArchR/devices/RK3326/packages/u-boot/sources/arch/arm/dts/rk3326-odroid-go2-emmc.dtsi new file mode 100644 index 0000000000..b25e54d7bb --- /dev/null +++ b/projects/ArchR/devices/RK3326/packages/u-boot/sources/arch/arm/dts/rk3326-odroid-go2-emmc.dtsi @@ -0,0 +1,28 @@ +/* this should apply on top of rk3326-odroid-go2-u-boot.dtsi */ +/ { + chosen { + u-boot,spl-boot-order = &sdmmc, &emmc; + }; + + aliases { + mmc0 = &emmc; + mmc1 = &sdmmc; + mmc2 = &sdio; + }; +}; + +&emmc { + bootph-all; + + /* mmc to sram can't do dma, prevent aborts transferring TF-A parts */ + u-boot,spl-fifo-mode; + status = "okay"; +}; + +&sdio { + bootph-all; + + /* mmc to sram can't do dma, prevent aborts transferring TF-A parts */ + u-boot,spl-fifo-mode; + status = "okay"; +}; diff --git a/projects/ArchR/devices/RK3326/packages/u-boot/sources/arch/arm/dts/rk3326-odroid-go2-uart5.dtsi b/projects/ArchR/devices/RK3326/packages/u-boot/sources/arch/arm/dts/rk3326-odroid-go2-uart5.dtsi new file mode 100644 index 0000000000..b2bd0be717 --- /dev/null +++ b/projects/ArchR/devices/RK3326/packages/u-boot/sources/arch/arm/dts/rk3326-odroid-go2-uart5.dtsi @@ -0,0 +1,12 @@ +/ { + aliases { + serial1 = &uart1; + serial2 = &uart5; + }; +}; + +&uart5 { + clock-frequency = <24000000>; + bootph-all; + status = "okay"; +}; diff --git a/projects/ArchR/devices/RK3326/packages/u-boot/sources/configs/rk3326-handheld_defconfig b/projects/ArchR/devices/RK3326/packages/u-boot/sources/configs/rk3326-handheld_defconfig new file mode 100644 index 0000000000..72f1fb7ca9 --- /dev/null +++ b/projects/ArchR/devices/RK3326/packages/u-boot/sources/configs/rk3326-handheld_defconfig @@ -0,0 +1,127 @@ +CONFIG_ARM=y +CONFIG_SKIP_LOWLEVEL_INIT=y +CONFIG_COUNTER_FREQUENCY=24000000 +CONFIG_ARCH_ROCKCHIP=y +CONFIG_NR_DRAM_BANKS=1 +CONFIG_ENV_SIZE=0x4000 +CONFIG_ENV_OFFSET=0x4000 +CONFIG_DEFAULT_DEVICE_TREE="rockchip/rk3326-common-handheld" +CONFIG_DEVICE_TREE_INCLUDES="rk3326-odroid-go2-emmc.dtsi" +CONFIG_LAST_STAGE_INIT=y +CONFIG_DM_RESET=y +CONFIG_ROCKCHIP_PX30=y +# CONFIG_TPL_ROCKCHIP_COMMON_BOARD is not set +CONFIG_TARGET_ODROID_GO2=y +CONFIG_DEBUG_UART_CHANNEL=0 +# CONFIG_TPL_LIBCOMMON_SUPPORT is not set +CONFIG_SPL_DRIVERS_MISC=y +CONFIG_SYS_LOAD_ADDR=0x800800 +CONFIG_DEBUG_UART_BASE=0xFF160000 +CONFIG_DEBUG_UART_CLOCK=24000000 +CONFIG_DEBUG_UART=y +CONFIG_BAUDRATE=1500000 +CONFIG_BOOTDELAY=1 +CONFIG_BOOTSTD_FULL=y +CONFIG_BOOTSTD_BOOTCOMMAND=y +CONFIG_BOOTCOMMAND="bootmeth order script; bootflow scan -b" +CONFIG_DISTRO_DEFAULTS=y +# CONFIG_ANDROID_BOOT_IMAGE is not set +CONFIG_FIT=y +CONFIG_SPL_LOAD_FIT=y +CONFIG_DEFAULT_FDT_FILE="rockchip/rk3326-common-handheld.dtb" +# CONFIG_CONSOLE_MUX is not set +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_DISPLAY_BOARDINFO_LATE=y +CONFIG_BOARD_LATE_INIT=y +CONFIG_MISC_INIT_R=y +CONFIG_SPL_MAX_SIZE=0x20000 +CONFIG_SPL_PAD_TO=0x7f8000 +CONFIG_SPL_BOOTROM_SUPPORT=y +# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set +CONFIG_SPL_I2C=y +CONFIG_SPL_POWER=y +CONFIG_SPL_ATF=y +# CONFIG_TPL_FRAMEWORK is not set +# CONFIG_TPL_BANNER_PRINT is not set +# CONFIG_TPL_SYS_MALLOC_SIMPLE is not set +# CONFIG_CMD_BOOTD is not set +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_IMI is not set +# CONFIG_CMD_XIMG is not set +# CONFIG_CMD_LZMADEC is not set +# CONFIG_CMD_UNZIP is not set +CONFIG_CMD_GPT=y +# CONFIG_CMD_LOADB is not set +# CONFIG_CMD_LOADS is not set +CONFIG_CMD_MMC=y +CONFIG_CMD_USB=y +CONFIG_CMD_USB_MASS_STORAGE=y +CONFIG_CMD_ITEST=y +CONFIG_CMD_ADC=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_PMIC=y +CONFIG_CMD_REGULATOR=y +CONFIG_CMD_FS_UUID=y +# CONFIG_CMD_SLEEP is not set +# CONFIG_SPL_DOS_PARTITION is not set +# CONFIG_ISO_PARTITION is not set +CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64 +CONFIG_SPL_OF_CONTROL=y +CONFIG_OF_LIVE=y +CONFIG_OF_LIBFDT_OVERLAY=y +CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" +CONFIG_ENV_IS_IN_MMC=y +CONFIG_REGMAP=y +CONFIG_SPL_REGMAP=y +CONFIG_SYSCON=y +CONFIG_SPL_SYSCON=y +CONFIG_CLK=y +CONFIG_SPL_CLK=y +CONFIG_FASTBOOT_BUF_ADDR=0x800800 +CONFIG_FASTBOOT_BUF_SIZE=0x04000000 +CONFIG_ROCKCHIP_GPIO=y +CONFIG_SYS_I2C_ROCKCHIP=y +CONFIG_MISC=y +CONFIG_ROCKCHIP_OTP=y +CONFIG_MMC_DW=y +CONFIG_MMC_DW_ROCKCHIP=y +CONFIG_PHY_REALTEK=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_GMAC_ROCKCHIP=y +CONFIG_PINCTRL=y +CONFIG_SPL_PINCTRL=y +CONFIG_DM_PMIC=y +CONFIG_PMIC_RK8XX=y +CONFIG_ROCKCHIP_RK8XX_DISABLE_BOOT_ON_POWERON=y +CONFIG_SPL_PMIC_RK8XX=y +CONFIG_REGULATOR_PWM=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_REGULATOR_RK8XX=y +CONFIG_PWM_ROCKCHIP=y +CONFIG_RAM=y +CONFIG_SPL_RAM=y +CONFIG_TPL_RAM=y +CONFIG_ROCKCHIP_SDRAM_COMMON=y +CONFIG_RAM_ROCKCHIP_LPDDR3=y +# CONFIG_SPECIFY_CONSOLE_INDEX is not set +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_SYS_NS16550_MEM32=y +CONFIG_ROCKCHIP_SFC=y +CONFIG_SYSRESET=y +CONFIG_DM_THERMAL=y +CONFIG_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_GENERIC=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_DWC2_OTG=y +CONFIG_VIDEO=y +CONFIG_DISPLAY=y +CONFIG_SPL_TINY_MEMSET=y +CONFIG_TPL_TINY_MEMSET=y +CONFIG_LZO=y +CONFIG_ERRNO_STR=y +CONFIG_OPTEE_LIB=y +CONFIG_TOOLS_MKEFICAPSULE=n +CONFIG_EFI_LOADER=n +CONFIG_TOOLS_KWBIMAGE=n +CONFIG_TOOLS_LIBCRYPTO=n diff --git a/projects/ArchR/devices/RK3326/packages/u-boot/sources/dts/upstream/src/arm64/rockchip/rk3326-common-handheld.dts b/projects/ArchR/devices/RK3326/packages/u-boot/sources/dts/upstream/src/arm64/rockchip/rk3326-common-handheld.dts new file mode 100644 index 0000000000..c832fa8126 --- /dev/null +++ b/projects/ArchR/devices/RK3326/packages/u-boot/sources/dts/upstream/src/arm64/rockchip/rk3326-common-handheld.dts @@ -0,0 +1,398 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Hardkernel Co., Ltd + * Copyright (c) 2020 Theobroma Systems Design und Consulting GmbH + * Copyright (c) 2022 Maya Matuszczyk + * Copyright (c) 2025 ROCKNIX https://github.com/ROCKNIX + * Copyright (c) 2025 ArchR https://github.com/ArchR + */ + +/dts-v1/; +#include +#include +#include "rk3326.dtsi" + +/ { + model = "Generic RK3326 Handheld"; + compatible = "generic,rk3326-handheld", "rockchip,rk3326"; + + aliases { + mmc0 = &sdmmc; + }; + + chosen { + stdout-path = "serial2:1500000n8"; + }; + + vccsys: regulator-vccsys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v8_sys"; + regulator-always-on; + regulator-min-microvolt = <3800000>; + regulator-max-microvolt = <3800000>; + }; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&cpu1 { + cpu-supply = <&vdd_arm>; +}; + +&cpu2 { + cpu-supply = <&vdd_arm>; +}; + +&cpu3 { + cpu-supply = <&vdd_arm>; +}; + +&cru { + assigned-clocks = <&cru PLL_NPLL>, + <&cru ACLK_BUS_PRE>, <&cru ACLK_PERI_PRE>, + <&cru HCLK_BUS_PRE>, <&cru HCLK_PERI_PRE>, + <&cru PCLK_BUS_PRE>, <&cru SCLK_GPU>; + + assigned-clock-rates = <1188000000>, + <200000000>, <200000000>, + <150000000>, <150000000>, + <100000000>, <200000000>; +}; + +&display_subsystem { + status = "okay"; +}; + +&i2c0 { + clock-frequency = <400000>; + i2c-scl-falling-time-ns = <16>; + i2c-scl-rising-time-ns = <280>; + status = "okay"; + + rk817: pmic@20 { + compatible = "rockchip,rk817"; + reg = <0x20>; + interrupt-parent = <&gpio0>; + interrupts = ; + clock-output-names = "rk808-clkout1", "xin32k"; + clock-names = "mclk"; + clocks = <&cru SCLK_I2S1_OUT>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int>, <&i2s1_2ch_mclk>; + wakeup-source; + #clock-cells = <1>; + #sound-dai-cells = <0>; + + vcc1-supply = <&vccsys>; + vcc2-supply = <&vccsys>; + vcc3-supply = <&vccsys>; + vcc4-supply = <&vccsys>; + vcc5-supply = <&vccsys>; + vcc6-supply = <&vccsys>; + vcc7-supply = <&vccsys>; + vcc8-supply = <&vccsys>; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-name = "vdd_logic"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1150000>; + regulator-ramp-delay = <6001>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vdd_arm: DCDC_REG2 { + regulator-name = "vdd_arm"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_3v3: DCDC_REG4 { + regulator-name = "vcc_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_1v8: LDO_REG2 { + regulator-name = "vcc_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd_1v0: LDO_REG3 { + regulator-name = "vdd_1v0"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc3v3_pmu: LDO_REG4 { + regulator-name = "vcc3v3_pmu"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vccio_sd: LDO_REG5 { + regulator-name = "vccio_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_sd: LDO_REG6 { + regulator-name = "vcc_sd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_bl: LDO_REG7 { + regulator-name = "vcc_bl"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_lcd: LDO_REG8 { + regulator-name = "vcc_lcd"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <2800000>; + }; + }; + + LDO_REG9 { + /* unused */ + }; + + usb_midu: BOOST { + regulator-name = "usb_midu"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5400000>; + regulator-always-on; + regulator-boot-on; + }; + }; + + rk817_charger: charger { + rockchip,resistor-sense-micro-ohms = <10000>; + rockchip,sleep-enter-current-microamp = <300000>; + rockchip,sleep-filter-current-microamp = <100000>; + }; + + rk817_codec: codec { + rockchip,mic-in-differential; + }; + }; +}; + +/* EXT Header(P2): 7(SCL:GPIO0.C2), 8(SDA:GPIO0.C3) */ +&i2c1 { + clock-frequency = <400000>; + status = "okay"; +}; + +&io_domains { + vccio1-supply = <&vcc_3v3>; + vccio2-supply = <&vccio_sd>; + vccio3-supply = <&vcc_3v3>; + vccio4-supply = <&vcc_3v3>; + vccio5-supply = <&vcc_3v3>; + vccio6-supply = <&vcc_3v3>; + status = "okay"; +}; + +&pmu_io_domains { + pmuio1-supply = <&vcc3v3_pmu>; + pmuio2-supply = <&vcc3v3_pmu>; + status = "okay"; +}; + +&saradc { + vref-supply = <&vcc_1v8>; + status = "okay"; +}; + +&sdmmc { + cap-sd-highspeed; + card-detect-delay = <200>; + cd-gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_LOW>; /*[> CD GPIO <]*/ + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + + /* For some reason if u-boot tries to manage these voltages, + some (old? cheap? random?) SD cards fail to initialize. + Legacy u-boot has no supply specified, and you can see + "No vmmc supply" in debug log, and those cards work well */ + /* + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vccio_sd>; + */ + status = "okay"; +}; + +&sdio { + cap-sd-highspeed; + non-removable; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&sfc { + pinctrl-0 = <&sfc_clk &sfc_cs0 &sfc_bus2>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <108000000>; + spi-rx-bus-width = <2>; + spi-tx-bus-width = <1>; + }; +}; + +&tsadc { + status = "okay"; +}; + +&u2phy { + status = "okay"; + + u2phy_host: host-port { + status = "okay"; + }; + + u2phy_otg: otg-port { + status = "disabled"; + }; +}; + +&usb20_otg { + status = "okay"; +}; + +/* EXT Header(P2): 2(RXD:GPIO1.C0),3(TXD:.C1),4(CTS:.C2),5(RTS:.C3) */ +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_xfer &uart1_cts>; + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2m1_xfer>; + status = "okay"; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; + +&pinctrl { + pmic { + dc_det: dc-det { + rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + pmic_int: pmic-int { + rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + soc_slppin_gpio: soc_slppin_gpio { + rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>; + }; + + soc_slppin_rst: soc_slppin_rst { + rockchip,pins = <0 RK_PA4 2 &pcfg_pull_none>; + }; + + soc_slppin_slp: soc_slppin_slp { + rockchip,pins = <0 RK_PA4 1 &pcfg_pull_none>; + }; + }; +}; diff --git a/projects/ArchR/devices/RK3326/patches/linux/000-rk3326-dts.patch b/projects/ArchR/devices/RK3326/patches/linux/000-rk3326-dts.patch new file mode 100644 index 0000000000..5d3e38f1ee --- /dev/null +++ b/projects/ArchR/devices/RK3326/patches/linux/000-rk3326-dts.patch @@ -0,0 +1,135 @@ +diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/rockchip/px30.dtsi +index 9137dd76e72c..882b91d8468d 100644 +--- a/arch/arm64/boot/dts/rockchip/px30.dtsi ++++ b/arch/arm64/boot/dts/rockchip/px30.dtsi +@@ -20,6 +20,7 @@ / { + #size-cells = <2>; + + aliases { ++ ethernet0 = &gmac; + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; +@@ -113,32 +114,22 @@ cpu0_opp_table: opp-table-0 { + compatible = "operating-points-v2"; + opp-shared; + +- opp-600000000 { +- opp-hz = /bits/ 64 <600000000>; +- opp-microvolt = <950000 950000 1350000>; +- clock-latency-ns = <40000>; +- opp-suspend; +- }; +- opp-816000000 { +- opp-hz = /bits/ 64 <816000000>; +- opp-microvolt = <1050000 1050000 1350000>; +- clock-latency-ns = <40000>; +- }; + opp-1008000000 { + opp-hz = /bits/ 64 <1008000000>; + opp-microvolt = <1175000 1175000 1350000>; + clock-latency-ns = <40000>; + }; +- opp-1200000000 { +- opp-hz = /bits/ 64 <1200000000>; +- opp-microvolt = <1300000 1300000 1350000>; +- clock-latency-ns = <40000>; +- }; + opp-1296000000 { + opp-hz = /bits/ 64 <1296000000>; + opp-microvolt = <1350000 1350000 1350000>; + clock-latency-ns = <40000>; + }; ++ opp-1416000000 { ++ opp-hz = /bits/ 64 <1416000000>; ++ opp-microvolt = <1350000 1350000 1350000>; ++ clock-latency-ns = <40000>; ++ turbo-mode; ++ }; + }; + + arm-pmu { +@@ -348,6 +339,32 @@ power-domain@PX30_PD_GPU { + }; + }; + ++ dfi: dfi@ff610000 { ++ reg = <0x00 0xff610000 0x00 0x400>; ++ compatible = "rockchip,px30-dfi"; ++ rockchip,pmu = <&pmugrf>; ++ status = "okay"; ++ }; ++ ++ dmc: dmc { ++ compatible = "rockchip,px30-dmc"; ++ devfreq-events = <&dfi>; ++ clocks = <&cru SCLK_DDRCLK>; ++ clock-names = "dmc_clk"; ++ operating-points-v2 = <&dmc_opp_table>; ++ uptreshold = <40>; ++ downdifferential = <20>; ++ status = "okay"; ++ }; ++ ++ dmc_opp_table: dmc_opp_table { ++ compatible = "operating-points-v2"; ++ opp-924000000 { ++ opp-hz = /bits/ 64 <924000000>; ++ opp-microvolt = <1125000>; ++ }; ++ }; ++ + pmugrf: syscon@ff010000 { + compatible = "rockchip,px30-pmugrf", "syscon", "simple-mfd"; + reg = <0x0 0xff010000 0x0 0x1000>; +@@ -1065,21 +1082,9 @@ nfc: nand-controller@ff3b0000 { + gpu_opp_table: opp-table-1 { + compatible = "operating-points-v2"; + +- opp-200000000 { +- opp-hz = /bits/ 64 <200000000>; +- opp-microvolt = <950000>; +- }; +- opp-300000000 { +- opp-hz = /bits/ 64 <300000000>; +- opp-microvolt = <975000>; +- }; +- opp-400000000 { +- opp-hz = /bits/ 64 <400000000>; +- opp-microvolt = <1050000>; +- }; +- opp-480000000 { +- opp-hz = /bits/ 64 <480000000>; +- opp-microvolt = <1125000>; ++ opp-560000000 { ++ opp-hz = /bits/ 64 <560000000>; ++ opp-microvolt = <1150000>; + }; + }; + +@@ -1091,10 +1096,25 @@ gpu: gpu@ff400000 { + ; + interrupt-names = "job", "mmu", "gpu"; + clocks = <&cru SCLK_GPU>; ++ clock-names = "bus"; ++ resets = <&cru SRST_GPU>; + #cooling-cells = <2>; + power-domains = <&power PX30_PD_GPU>; ++ power_policy = "coarse_demand"; + operating-points-v2 = <&gpu_opp_table>; + status = "disabled"; ++ ++ power_model@0 { ++ compatible = "arm,mali-simple-power-model"; ++ static-coefficient = <100000>; ++ dynamic-coefficient = <953>; ++ ts = <(-108890) 63610 (-1355) 20>; ++ thermal-zone = "gpu-thermal"; ++ }; ++ power_model@1 { ++ compatible = "arm,mali-g31-power-model"; ++ scale = <5>; ++ }; + }; + + vpu: video-codec@ff442000 { diff --git a/projects/ArchR/devices/RK3326/patches/linux/001-panel-updates.patch b/projects/ArchR/devices/RK3326/patches/linux/001-panel-updates.patch new file mode 100644 index 0000000000..e29338fbfc --- /dev/null +++ b/projects/ArchR/devices/RK3326/patches/linux/001-panel-updates.patch @@ -0,0 +1,235 @@ +diff --git a/drivers/gpu/drm/panel/panel-newvision-nv3051d.c b/drivers/gpu/drm/panel/panel-newvision-nv3051d.c +index 5d115ecd5dd4..1b199662e7ed 100644 +--- a/drivers/gpu/drm/panel/panel-newvision-nv3051d.c ++++ b/drivers/gpu/drm/panel/panel-newvision-nv3051d.c +@@ -480,14 +480,14 @@ static const struct drm_display_mode nv3051d_rgxx3_modes[] = { + static const struct drm_display_mode nv3051d_rk2023_modes[] = { + { + .hdisplay = 640, +- .hsync_start = 640 + 40, +- .hsync_end = 640 + 40 + 2, +- .htotal = 640 + 40 + 2 + 80, ++ .hsync_start = 640 + 48, ++ .hsync_end = 640 + 48 + 2, ++ .htotal = 640 + 48 + 2 + 47, + .vdisplay = 480, +- .vsync_start = 480 + 18, +- .vsync_end = 480 + 18 + 2, +- .vtotal = 480 + 18 + 2 + 4, +- .clock = 24150, ++ .vsync_start = 480 + 2, ++ .vsync_end = 480 + 2 + 4, ++ .vtotal = 480 + 2 + 4 + 3, ++ .clock = 21600, + .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, + }, + }; +@@ -520,7 +520,8 @@ static const struct nv3051d_panel_info nv3051d_rk2023_info = { + .height_mm = 57, + .bus_flags = DRM_BUS_FLAG_DE_LOW | DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE, + .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | +- MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_NO_EOT_PACKET, ++ MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_NO_EOT_PACKET | ++ MIPI_DSI_CLOCK_NON_CONTINUOUS, + }; + + static const struct of_device_id newvision_nv3051d_of_match[] = { +diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7703.c b/drivers/gpu/drm/panel/panel-sitronix-st7703.c +index 67e8e45498cb..a9cc6c6c0fc1 100644 +--- a/drivers/gpu/drm/panel/panel-sitronix-st7703.c ++++ b/drivers/gpu/drm/panel/panel-sitronix-st7703.c +@@ -673,6 +673,182 @@ static const struct st7703_panel_desc gameforcechi_desc = { + .init_sequence = gameforcechi_init_sequence, + }; + ++static void xu10_init_sequence(struct mipi_dsi_multi_context *dsi_ctx) ++{ ++ /* ++ * Init sequence was supplied by the panel vendor. ++ */ ++ ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETEXTC, 0xf1, 0x12, 0x83); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETAPID, 0x00, 0x00, 0x00, ++ 0xda, 0x80); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETDISP, 0x00, 0x03, 0xf0); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETRGBIF, 0x10, 0x10, 0x28, ++ 0x28, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETCYC, 0x80); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETBGP, 0x0a, 0x0a); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETVCOM, 0x8e, 0x8e); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETPOWER_EXT, 0x26, 0x22, ++ 0xf0, 0x13); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETMIPI, 0x33, 0x81, 0x05, ++ 0xf9, 0x0e, 0x0e, 0x20, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x44, 0x25, 0x00, 0x90, 0x0a, ++ 0x00, 0x00, 0x01, 0x4f, 0x01, 0x00, 0x00, 0x37); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETVDC, 0x47); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_UNKNOWN_BF, 0x02, 0x11, 0x00); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETSCR, 0x73, 0x73, 0x50, 0x50, ++ 0x00, 0x00, 0x12, 0x70, 0x00); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETPOWER, 0x53, 0x00, 0x32, ++ 0x32, 0x77, 0xd1, 0xcc, 0xcc, 0x77, 0x77, 0x33, ++ 0x33); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETECO, 0x82, 0x00, 0xbf, 0xff, ++ 0x00, 0xff); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETIO, 0xb8, 0x00, 0x0a, 0x00, ++ 0x00, 0x00); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETCABC, 0x10, 0x40, 0x1e, ++ 0x02); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETPANEL, 0x0b); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETGAMMA, 0x00, 0x06, 0x0a, ++ 0x2a, 0x3d, 0x3f, 0x3b, 0x37, 0x06, 0x0b, 0x0c, ++ 0x10, 0x11, 0x10, 0x13, 0x12, 0x18, 0x00, 0x06, ++ 0x0a, 0x2a, 0x3d, 0x3f, 0x3b, 0x37, 0x06, 0x0b, ++ 0x0c, 0x10, 0x11, 0x10, 0x13, 0x12, 0x18); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETEQ, 0x07, 0x07, 0x0b, 0x0b, ++ 0x0b, 0x0b, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, ++ 0xc0, 0x10); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETGIP1, 0xc8, 0x10, 0x02, 0x00, ++ 0x00, 0xb0, 0xb1, 0x11, 0x31, 0x23, 0x28, 0x80, ++ 0xb0, 0xb1, 0x27, 0x08, 0x00, 0x04, 0x02, 0x00, ++ 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x00, ++ 0x88, 0x88, 0xba, 0x60, 0x24, 0x08, 0x88, 0x88, ++ 0x88, 0x88, 0x88, 0x88, 0x88, 0xba, 0x71, 0x35, ++ 0x18, 0x88, 0x88, 0x88, 0x88, 0x88, 0x00, 0x00, ++ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETGIP2, 0x97, 0x0a, 0x82, 0x02, ++ 0x03, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x81, 0x88, 0xba, 0x17, 0x53, 0x88, 0x88, 0x88, ++ 0x88, 0x88, 0x88, 0x80, 0x88, 0xba, 0x06, 0x42, ++ 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x23, 0x00, ++ 0x00, 0x02, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_UNKNOWN_EF, 0xff, 0xff, 0x01, 0x05, 0x96, 0x01, 0x11, 0x05, 0x78, 0x01, 0x29); ++} ++ ++static const struct drm_display_mode xu10_mode = { ++ .hdisplay = 640, ++ .hsync_start = 640 + 120, ++ .hsync_end = 640 + 120 + 10, ++ .htotal = 640 + 120 + 10 + 120, ++ .vdisplay = 480, ++ .vsync_start = 480 + 17, ++ .vsync_end = 480 + 17 + 4, ++ .vtotal = 480 + 17 + 4 + 13, ++ .clock = 30000, ++ .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, ++ .width_mm = 52, ++ .height_mm = 70, ++}; ++ ++static const struct st7703_panel_desc xu10_desc = { ++ .mode = &xu10_mode, ++ .lanes = 4, ++ .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | ++ MIPI_DSI_MODE_NO_EOT_PACKET | MIPI_DSI_MODE_LPM, ++ .format = MIPI_DSI_FMT_RGB888, ++ .init_sequence = xu10_init_sequence, ++}; ++ ++static void r36s_init_sequence(struct mipi_dsi_multi_context *dsi_ctx) ++{ ++ /* ++ * Init sequence was supplied by the panel vendor. ++ */ ++ ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETEXTC, 0xf1, 0x12, 0x83); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETAPID, 0x00, 0x00, 0x00, ++ 0xda, 0x80); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETDISP, 0x00, 0x13, 0x70); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETRGBIF, 0x10, 0x10, 0x28, ++ 0x28, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETCYC, 0x80); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETBGP, 0x0a, 0x0a); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETVCOM, 0x7f, 0x7f); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETPOWER_EXT, 0x26, 0x62, ++ 0xf0, 0x63); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETMIPI, 0x33, 0x81, 0x05, ++ 0xf9, 0x0e, 0x0e, 0x20, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x44, 0x25, 0x00, 0x90, 0x0a, ++ 0x00, 0x00, 0x01, 0x4f, 0x01, 0x00, 0x00, 0x37); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETVDC, 0x47); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_UNKNOWN_BF, 0x02, 0x11, 0x00); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETSCR, 0x73, 0x73, 0x50, 0x50, ++ 0x00, 0x00, 0x12, 0x50, 0x00); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETPOWER, 0x53, 0xc0, 0x32, ++ 0x32, 0x77, 0xe1, 0xdd, 0xdd, 0x77, 0x77, 0x33, ++ 0x33); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETECO, 0x82, 0x00, 0xbf, 0xff, ++ 0x00, 0xff); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETIO, 0xb8, 0x00, 0x0a, 0x00, ++ 0x00, 0x00); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETCABC, 0x10, 0x40, 0x1e, ++ 0x02); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETPANEL, 0x0b); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETGAMMA, 0x00, 0x07, 0x0d, ++ 0x37, 0x35, 0x3f, 0x41, 0x44, 0x06, 0x0c, 0x0d, ++ 0x0f, 0x11, 0x10, 0x12, 0x14, 0x1a, 0x00, 0x07, ++ 0x0d, 0x37, 0x35, 0x3f, 0x41, 0x44, 0x06, 0x0c, ++ 0x0d, 0x0f, 0x11, 0x10, 0x12, 0x14, 0x1a); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETEQ, 0x07, 0x07, 0x0b, 0x0b, ++ 0x0b, 0x0b, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, ++ 0xc0, 0x10); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETGIP1, 0xc8, 0x10, 0x02, 0x00, ++ 0x00, 0xb0, 0xb1, 0x11, 0x31, 0x23, 0x28, 0x80, ++ 0xb0, 0xb1, 0x27, 0x08, 0x00, 0x04, 0x02, 0x00, ++ 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x00, ++ 0x88, 0x88, 0xba, 0x60, 0x24, 0x08, 0x88, 0x88, ++ 0x88, 0x88, 0x88, 0x88, 0x88, 0xba, 0x71, 0x35, ++ 0x18, 0x88, 0x88, 0x88, 0x88, 0x88, 0x00, 0x00, ++ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_SETGIP2, 0x97, 0x0a, 0x82, 0x02, ++ 0x03, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x81, 0x88, 0xba, 0x17, 0x53, 0x88, 0x88, 0x88, ++ 0x88, 0x88, 0x88, 0x80, 0x88, 0xba, 0x06, 0x42, ++ 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x23, 0x00, ++ 0x00, 0x02, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00); ++ mipi_dsi_dcs_write_seq_multi(dsi_ctx, ST7703_CMD_UNKNOWN_EF, 0xff, 0xff, 0x01, 0x05, 0xc8, 0x01, 0x11, 0x05, 0x32, 0x01, 0x29); ++} ++ ++static const struct drm_display_mode r36s_mode = { ++ .hdisplay = 640, ++ .hsync_start = 640 + 450, ++ .hsync_end = 640 + 450 + 70, ++ .htotal = 640 + 450 + 70 + 450, ++ .vdisplay = 480, ++ .vsync_start = 480 + 17, ++ .vsync_end = 480 + 17 + 5, ++ .vtotal = 480 + 17 + 5 + 13, ++ .clock = 50000, ++ .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, ++ .width_mm = 52, ++ .height_mm = 70, ++}; ++ ++static const struct st7703_panel_desc r36s_desc = { ++ .mode = &r36s_mode, ++ .lanes = 4, ++ .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | ++ MIPI_DSI_MODE_NO_EOT_PACKET | MIPI_DSI_MODE_LPM, ++ .format = MIPI_DSI_FMT_RGB888, ++ .init_sequence = r36s_init_sequence, ++}; ++ + static int st7703_enable(struct drm_panel *panel) + { + struct st7703 *ctx = panel_to_st7703(panel); +@@ -916,8 +1092,11 @@ static void st7703_remove(struct mipi_dsi_device *dsi) + } + + static const struct of_device_id st7703_of_match[] = { ++ { .compatible = "anbernic,rg351v-panel-v2", .data = &rg353v2_desc }, + { .compatible = "anbernic,rg353v-panel-v2", .data = &rg353v2_desc }, ++ { .compatible = "gameconsole,r36s-panel", .data = &r36s_desc }, + { .compatible = "gameforce,chi-panel", .data = &gameforcechi_desc }, ++ { .compatible = "magicx,xu10-panel", .data = &xu10_desc }, + { .compatible = "powkiddy,rgb10max3-panel", .data = &rgb10max3_panel_desc }, + { .compatible = "powkiddy,rgb30-panel", .data = &rgb30panel_desc }, + { .compatible = "rocktech,jh057n00900", .data = &jh057n00900_panel_desc }, diff --git a/projects/ArchR/devices/RK3326/patches/linux/004-input-drivers.patch b/projects/ArchR/devices/RK3326/patches/linux/004-input-drivers.patch new file mode 100644 index 0000000000..0cf37d73a6 --- /dev/null +++ b/projects/ArchR/devices/RK3326/patches/linux/004-input-drivers.patch @@ -0,0 +1,6829 @@ +diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig +index 7755e5b454d2..38355e3184fc 100644 +--- a/drivers/input/joystick/Kconfig ++++ b/drivers/input/joystick/Kconfig +@@ -400,6 +400,36 @@ config JOYSTICK_N64 + Say Y here if you want enable support for the four + built-in controller ports on the Nintendo 64 console. + ++config JOYSTICK_ODROIDGO2 ++ tristate "ODROIDGO2-Advance joypad driver" ++ help ++ Made for ODROIDGO2-Advance. ++ ++config JOYSTICK_ODROIDGO2_V11 ++ tristate "ODROIDGO2-Advance joypad driver" ++ help ++ Made for ODROIDGO2-Advance. ++ ++config JOYSTICK_ODROIDGO3 ++ tristate "ODROIDGO3 joypad driver" ++ help ++ Made for ODROIDGO3. ++ ++config JOYSTICK_RGB20S ++ tristate "RGB20S joypad driver" ++ help ++ Made for RGB20S. ++ ++config JOYSTICK_XU10 ++ tristate "XU10 joypad driver" ++ help ++ Made for XU10. ++ ++config JOYSTICK_GAMEFORCE_CHI ++ tristate "gameforce joypad driver" ++ help ++ Made for Gameforce CHI. ++ + config JOYSTICK_SENSEHAT + tristate "Raspberry Pi Sense HAT joystick" + depends on INPUT && I2C +diff --git a/drivers/input/joystick/Makefile b/drivers/input/joystick/Makefile +index 9976f596a920..2a0524b63ba0 100644 +--- a/drivers/input/joystick/Makefile ++++ b/drivers/input/joystick/Makefile +@@ -15,6 +15,7 @@ obj-$(CONFIG_JOYSTICK_COBRA) += cobra.o + obj-$(CONFIG_JOYSTICK_DB9) += db9.o + obj-$(CONFIG_JOYSTICK_FSIA6B) += fsia6b.o + obj-$(CONFIG_JOYSTICK_GAMECON) += gamecon.o ++obj-$(CONFIG_JOYSTICK_GAMEFORCE_CHI) += gameforce-joypad.o + obj-$(CONFIG_JOYSTICK_GF2K) += gf2k.o + obj-$(CONFIG_JOYSTICK_GRIP) += grip.o + obj-$(CONFIG_JOYSTICK_GRIP_MP) += grip_mp.o +@@ -25,6 +26,10 @@ obj-$(CONFIG_JOYSTICK_JOYDUMP) += joydump.o + obj-$(CONFIG_JOYSTICK_MAGELLAN) += magellan.o + obj-$(CONFIG_JOYSTICK_MAPLE) += maplecontrol.o + obj-$(CONFIG_JOYSTICK_N64) += n64joy.o ++obj-$(CONFIG_JOYSTICK_ODROIDGO2) += odroidgo2-joypad.o ++obj-$(CONFIG_JOYSTICK_ODROIDGO2_V11) += odroidgo2-v11-joypad.o ++obj-$(CONFIG_JOYSTICK_ODROIDGO3) += odroidgo3-joypad.o ++obj-$(CONFIG_JOYSTICK_RGB20S) += rgb20s-joypad.o + obj-$(CONFIG_JOYSTICK_PSXPAD_SPI) += psxpad-spi.o + obj-$(CONFIG_JOYSTICK_PXRC) += pxrc.o + obj-$(CONFIG_JOYSTICK_QWIIC) += qwiic-joystick.o +@@ -40,4 +45,5 @@ obj-$(CONFIG_JOYSTICK_TWIDJOY) += twidjoy.o + obj-$(CONFIG_JOYSTICK_WARRIOR) += warrior.o + obj-$(CONFIG_JOYSTICK_WALKERA0701) += walkera0701.o + obj-$(CONFIG_JOYSTICK_XPAD) += xpad.o ++obj-$(CONFIG_JOYSTICK_XU10) += xu10-joypad.o + obj-$(CONFIG_JOYSTICK_ZHENHUA) += zhenhua.o +diff --git a/drivers/input/joystick/gameforce-joypad.c b/drivers/input/joystick/gameforce-joypad.c +new file mode 100644 +index 000000000000..e2953433b491 +--- /dev/null ++++ b/drivers/input/joystick/gameforce-joypad.c +@@ -0,0 +1,1330 @@ ++/* ++ * SARADC joystick & GPIO Button driver for Linux(Gameforce CHI) ++ */ ++/* ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * Should you need to contact me, the author, you can do so either by ++ * e-mail - mail your message to , or by paper mail: ++ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic ++ */ ++ ++/*----------------------------------------------------------------------------*/ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define RIGHT_ADC_JOYSTICK ++#define VOLUME_ADC_KEYS ++#define VIBRATORS_FF ++ ++#ifdef RIGHT_ADC_JOYSTICK ++#include ++#include "../input-compat.h" ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++#define DRV_NAME "gameforce_gamepad" ++/*----------------------------------------------------------------------------*/ ++#ifdef VOLUME_ADC_KEYS ++struct of_device_id adckeys_of_match[] = { ++ { .compatible = "volume-keys", }, ++ {}, ++}; ++#endif ++ ++#ifdef VIBRATORS_FF ++struct of_device_id vibrators_of_match[] = { ++ { .compatible = "gpio,vibrators", }, ++ {}, ++}; ++ ++ ++struct gpio_vib { ++ struct work_struct work; ++ int speed; ++ int index; ++ int last_index; ++ bool active; ++ int gpio0; ++ int gpio1; ++}; ++#endif ++ ++#ifdef VOLUME_ADC_KEYS ++struct adc_keys_button { ++ u32 voltage; ++ u32 keycode; ++}; ++ ++struct adc_keys_state { ++ struct iio_channel *channel; ++ u32 num_keys; ++ u32 last_key; ++ u32 keyup_voltage; ++ const struct adc_keys_button *map; ++}; ++#endif ++ ++struct bt_adc { ++ /* IIO ADC Channel */ ++ struct iio_channel *channel; ++ /* report value (mV) */ ++ int old_value; ++ /* report type */ ++ int report_type; ++ /* input device init value (mV) */ ++ int max, min; ++ /* calibrated adc value */ ++ int cal; ++ /* adc scale value */ ++ int scale; ++ /* invert report */ ++ bool invert; ++}; ++ ++struct bt_gpio { ++ /* GPIO Request label */ ++ const char *label; ++ /* GPIO Number */ ++ int num; ++ /* report type */ ++ int report_type; ++ /* report linux code */ ++ int linux_code; ++ /* prev button value */ ++ bool old_value; ++ /* button press level */ ++ bool active_level; ++}; ++ ++struct joypad { ++ struct device *dev; ++ int poll_interval; ++ ++ /* report enable/disable */ ++ bool enable; ++ ++ /* report reference point */ ++ bool invert_absx; ++ bool invert_absy; ++ ++ /* report interval (ms) */ ++ int bt_gpio_count; ++ struct bt_gpio *gpios; ++ /* button auto repeat */ ++ int auto_repeat; ++ ++ /* report threshold (mV) */ ++ int bt_adc_fuzz, bt_adc_flat; ++ int bt_adc_x_range, bt_adc_y_range; ++ /* adc read value scale */ ++ int bt_adc_scale; ++ /* joystick deadzone control */ ++ int bt_adc_deadzone; ++ int bt_adc_count; ++ struct bt_adc *adcs; ++#ifdef VOLUME_ADC_KEYS ++ /*adc key saradc[2]*/ ++ struct adc_keys_state *st; ++#endif ++#ifdef VIBRATORS_FF ++ /* vibrator */ ++ struct gpio_vib *vib; ++#endif ++ struct mutex lock; ++}; ++ ++#ifdef RIGHT_ADC_JOYSTICK ++struct input_dev *global_input = NULL; ++#endif ++/*----------------------------------------------------------------------------*/ ++// ++// set to the value in the boot.ini file. (if exist) ++// ++/*----------------------------------------------------------------------------*/ ++static unsigned int g_button_adc_x_range = 0; ++static unsigned int g_button_adc_y_range = 0; ++static unsigned int g_button_adc_fuzz = 0; ++static unsigned int g_button_adc_flat = 0; ++static unsigned int g_button_adc_scale = 0; ++static unsigned int g_button_adc_deadzone = 0; ++ ++static int __init button_adcx_range_setup(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ ++ g_button_adc_x_range = simple_strtoul(str, NULL, 10); ++ ++ return 0; ++} ++__setup("button-adc-x-range=", button_adcx_range_setup); ++ ++static int __init button_adcy_range_setup(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ ++ g_button_adc_y_range = simple_strtoul(str, NULL, 10); ++ ++ return 0; ++} ++__setup("button-adc-y-range=", button_adcy_range_setup); ++ ++static int button_adc_fuzz(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_fuzz = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-fuzz=", button_adc_fuzz); ++ ++static int button_adc_flat(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_flat = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-flat=", button_adc_flat); ++ ++static int button_adc_scale(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_scale = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-scale=", button_adc_scale); ++ ++static int button_adc_deadzone(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_deadzone = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-deadzone=", button_adc_deadzone); ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++static int joypad_adc_read(struct bt_adc *adc) ++{ ++ int value; ++ ++ if (iio_read_channel_processed(adc->channel, &value)) ++ return 0; ++ ++ value *= adc->scale; ++ ++ return (adc->invert ? (adc->max - value) : value); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/DRV_NAME/poll_interval [rw] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_poll_interval(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ mutex_lock(&joypad->lock); ++ joypad->poll_interval = simple_strtoul(buf, NULL, 10); ++ mutex_unlock(&joypad->lock); ++ ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_poll_interval(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->poll_interval); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(poll_interval, S_IWUSR | S_IRUGO, ++ joypad_show_poll_interval, ++ joypad_store_poll_interval); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/DRV_NAME/adc_fuzz [r] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_adc_fuzz(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->bt_adc_fuzz); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(adc_fuzz, S_IWUSR | S_IRUGO, ++ joypad_show_adc_fuzz, ++ NULL); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/DRV_NAME/adc_flat [r] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_adc_flat(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->bt_adc_flat); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(adc_flat, S_IWUSR | S_IRUGO, ++ joypad_show_adc_flat, ++ NULL); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/DRV_NAME/enable [rw] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_enable(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ mutex_lock(&joypad->lock); ++ joypad->enable = simple_strtoul(buf, NULL, 10); ++ mutex_unlock(&joypad->lock); ++ ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_enable(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->enable); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO, ++ joypad_show_enable, ++ joypad_store_enable); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/DRV_NAME/adc_cal [rw] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_adc_cal(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ bool calibration; ++ ++ calibration = simple_strtoul(buf, NULL, 10); ++ ++ if (calibration) { ++ int nbtn; ++ ++ mutex_lock(&joypad->lock); ++ for (nbtn = 0; nbtn < joypad->bt_adc_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ ++ adc->cal = joypad_adc_read(adc); ++ if (!adc->cal) { ++ dev_err(joypad->dev, "%s : saradc channels[%d]!\n", ++ __func__, nbtn); ++ continue; ++ } ++ adc->old_value = adc->cal; ++ } ++ mutex_unlock(&joypad->lock); ++ } ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_adc_cal(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ int nbtn; ++ ssize_t pos; ++ ++ for (nbtn = 0, pos = 0; nbtn < joypad->bt_adc_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ pos += sprintf(&buf[pos], "adc[%d]->cal = %d ", ++ nbtn, adc->cal); ++ } ++ pos += sprintf(&buf[pos], "\n"); ++ return pos; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(adc_cal, S_IWUSR | S_IRUGO, ++ joypad_show_adc_cal, ++ joypad_store_adc_cal); ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++static struct attribute *joypad_attrs[] = { ++ &dev_attr_poll_interval.attr, ++ &dev_attr_adc_fuzz.attr, ++ &dev_attr_adc_flat.attr, ++ &dev_attr_enable.attr, ++ &dev_attr_adc_cal.attr, ++ NULL, ++}; ++ ++static struct attribute_group joypad_attr_group = { ++ .attrs = joypad_attrs, ++}; ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++static void joypad_gpio_check(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ int nbtn, value; ++ ++ for (nbtn = 0; nbtn < joypad->bt_gpio_count; nbtn++) { ++ struct bt_gpio *gpio = &joypad->gpios[nbtn]; ++ ++ if (gpio_get_value_cansleep(gpio->num) < 0) { ++ dev_err(joypad->dev, "failed to get gpio state\n"); ++ continue; ++ } ++ value = gpio_get_value(gpio->num); ++ if (value != gpio->old_value) { ++ input_event(poll_dev->input, ++ gpio->report_type, ++ gpio->linux_code, ++ (value == gpio->active_level) ? 1 : 0); ++ gpio->old_value = value; ++ } ++ } ++ input_sync(poll_dev->input); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_adc_check(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ int nbtn, value; ++ ++ for (nbtn = 0; nbtn < joypad->bt_adc_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ ++ value = joypad_adc_read(adc); ++ if (!value) { ++ dev_err(joypad->dev, "%s : saradc channels[%d]!\n", ++ __func__, nbtn); ++ continue; ++ } ++ ++ /* Joystick Deadzone check */ ++ if (joypad->bt_adc_deadzone) { ++ if ((value < adc->cal + joypad->bt_adc_deadzone) && ++ (value > adc->cal - joypad->bt_adc_deadzone)) ++ value = adc->cal; ++ } ++ value = value - adc->cal; ++ value = value > adc->max ? adc->max : value; ++ value = value < adc->min ? adc->min : value; ++ ++ if (nbtn == 0) ++ { ++ // adc-x value is default inverted(h/w) ++ input_report_abs(poll_dev->input, ++ adc->report_type, value); ++ } ++ else ++ { ++ input_report_abs(poll_dev->input, ++ adc->report_type, value * (-1)); ++ } ++ adc->old_value = value; ++ } ++ input_sync(poll_dev->input); ++} ++ ++/*----------------------------------------------------------------------------*/ ++#ifdef VOLUME_ADC_KEYS ++static int joypad_vol_check(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ //struct adc_keys_state *st = dev->private; ++ int i, value, ret; ++ u32 diff, closest = 0xffffffff; ++ int keycode = 0; ++ ++ ret = iio_read_channel_processed(joypad->st->channel, &value); ++ if (unlikely(ret < 0)) { ++ /* Forcibly release key if any was pressed */ ++ value = joypad->st->keyup_voltage; ++ } else { ++ for (i = 0; i < joypad->st->num_keys; i++) { ++ diff = abs(joypad->st->map[i].voltage - value); ++ if (diff < closest) { ++ closest = diff; ++ keycode = joypad->st->map[i].keycode; ++ } ++ } ++ } ++ ++ if (((157 320) && (value<1700))) ++ return -1; ++ if (abs(joypad->st->keyup_voltage - value) < closest) ++ keycode = 0; ++ ++ if (joypad->st->last_key && joypad->st->last_key != keycode) ++ input_report_key(poll_dev->input, joypad->st->last_key, 0); ++ ++ if (keycode) ++ input_report_key(poll_dev->input, keycode, 1); ++ ++ input_sync(poll_dev->input); ++ joypad->st->last_key = keycode; ++ ++ return 0; ++} ++#endif ++/*----------------------------------------------------------------------------*/ ++static void joypad_poll(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ ++ if (joypad->enable) { ++ joypad_adc_check(poll_dev); ++ joypad_gpio_check(poll_dev); ++ #ifdef VOLUME_ADC_KEYS ++ joypad_vol_check(poll_dev); ++ #endif ++ } ++ if (poll_dev->poll_interval != joypad->poll_interval) { ++ mutex_lock(&joypad->lock); ++ poll_dev->poll_interval = joypad->poll_interval; ++ mutex_unlock(&joypad->lock); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_open(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ int nbtn; ++ ++ for (nbtn = 0; nbtn < joypad->bt_gpio_count; nbtn++) { ++ struct bt_gpio *gpio = &joypad->gpios[nbtn]; ++ gpio->old_value = gpio->active_level ? 0 : 1; ++ } ++ for (nbtn = 0; nbtn < joypad->bt_adc_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ ++ adc->old_value = joypad_adc_read(adc); ++ if (!adc->old_value) { ++ dev_err(joypad->dev, "%s : saradc channels[%d]!\n", ++ __func__, nbtn); ++ continue; ++ } ++ adc->cal = adc->old_value; ++ dev_info(joypad->dev, "%s : adc[%d] adc->cal = %d\n", ++ __func__, nbtn, adc->cal); ++ } ++ /* buttons status sync */ ++ joypad_adc_check(poll_dev); ++ joypad_gpio_check(poll_dev); ++ ++ /* button report enable */ ++ mutex_lock(&joypad->lock); ++ joypad->enable = true; ++ mutex_unlock(&joypad->lock); ++ ++ dev_info(joypad->dev, "%s : opened\n", __func__); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_close(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ ++ /* button report disable */ ++ mutex_lock(&joypad->lock); ++ joypad->enable = false; ++ mutex_unlock(&joypad->lock); ++ ++ dev_info(joypad->dev, "%s : closed\n", __func__); ++} ++#ifdef VIBRATORS_FF ++/** ++ * gpio_vib_set - handler to start/stop vibration ++ * @vib: pointer to vibrator structure ++ * @on: state to set ++ */ ++static int gpio_vib_set(struct gpio_vib *vib, bool on) ++{ ++ if (on) { ++ if (vib->last_index) { ++ gpio_direction_output(vib->gpio1, 1); ++ gpio_set_value(vib->gpio1, 1); ++ } else { ++ gpio_direction_output(vib->gpio0, 1); ++ gpio_set_value(vib->gpio0, 1); ++ } ++ } ++ else { ++ if (vib->last_index) { ++ gpio_direction_output(vib->gpio1, 0); ++ gpio_set_value(vib->gpio1, 0); ++ } else { ++ gpio_direction_output(vib->gpio0, 0); ++ gpio_set_value(vib->gpio0, 0); ++ } ++ } ++ ++ return 0; ++} ++ ++/** ++ * vib_work_handler - worker to set vibration level ++ * @work: pointer to work_struct ++ */ ++static void vib_work_handler(struct work_struct *work) ++{ ++ struct gpio_vib *vib = container_of(work, struct gpio_vib, work); ++ //struct joypad *joypad = container_of(vib, struct joypad, vib); ++ ++ /* ++ * pmic vibrator supports voltage ranges from 1.2 to 3.1V, so ++ * scale the level to fit into these ranges. ++ */ ++ printk("%s speed = %d\n", __func__, vib->speed); ++ if (vib->speed) { ++ vib->active = true; ++ } else { ++ vib->active = false; ++ } ++ ++ gpio_vib_set(vib, vib->active); ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_adc_setup(struct device *dev, struct joypad *joypad) ++{ ++ int nbtn = 0; ++ ++ joypad->adcs = devm_kzalloc(dev, joypad->bt_adc_count * ++ sizeof(struct bt_adc), GFP_KERNEL); ++ ++ if (!joypad->adcs) { ++ dev_err(dev, "%s devm_kzmalloc error!", __func__); ++ return -ENOMEM; ++ } ++ ++ for (nbtn = 0; nbtn < joypad->bt_adc_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ enum iio_chan_type type; ++ ++ adc->scale = joypad->bt_adc_scale; ++ if (nbtn) { ++ adc->channel = ++ devm_iio_channel_get(dev, "joy_y"); ++ adc->report_type = ABS_Y; ++ if (joypad->invert_absy) ++ adc->invert = true; ++ ++ adc->max = (joypad->bt_adc_y_range / 2) - 1; ++ adc->min = -(joypad->bt_adc_y_range / 2); ++ } ++ else { ++ adc->channel = ++ devm_iio_channel_get(dev, "joy_x"); ++ adc->report_type = ABS_X; ++ if (joypad->invert_absx) ++ adc->invert = true; ++ ++ adc->max = (joypad->bt_adc_x_range / 2) - 1; ++ adc->min = -(joypad->bt_adc_x_range / 2); ++ } ++ ++ if (IS_ERR(adc->channel)) { ++ dev_err(dev, "iio channel[%d] get error\n", nbtn); ++ return -EINVAL; ++ } ++ if (!adc->channel->indio_dev) ++ return -ENXIO; ++ ++ if (iio_get_channel_type(adc->channel, &type)) ++ return -EINVAL; ++ ++ if (type != IIO_VOLTAGE) { ++ dev_err(dev, "Incompatible channel %d type %d\n", ++ nbtn, type); ++ return -EINVAL; ++ } ++ } ++ if (nbtn == 0) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_gpio_setup(struct device *dev, struct joypad *joypad) ++{ ++ struct device_node *node, *pp; ++ int nbtn; ++ ++ node = dev->of_node; ++ if (!node) ++ return -ENODEV; ++ ++ joypad->gpios = devm_kzalloc(dev, joypad->bt_gpio_count * ++ sizeof(struct bt_gpio), GFP_KERNEL); ++ ++ if (!joypad->gpios) { ++ dev_err(dev, "%s devm_kzmalloc error!", __func__); ++ return -ENOMEM; ++ } ++ ++ nbtn = 0; ++ for_each_child_of_node(node, pp) { ++ enum of_gpio_flags flags; ++ struct bt_gpio *gpio = &joypad->gpios[nbtn++]; ++ int error; ++ ++ gpio->num = of_get_gpio_flags(pp, 0, &flags); ++ if (gpio->num < 0) { ++ error = gpio->num; ++ dev_err(dev, "Failed to get gpio flags, error: %d\n", ++ error); ++ return error; ++ } ++ ++ /* gpio active level(key press level) */ ++ gpio->active_level = (flags & OF_GPIO_ACTIVE_LOW) ? 0 : 1; ++ ++ gpio->label = of_get_property(pp, "label", NULL); ++ ++ if (gpio_is_valid(gpio->num)) { ++ error = devm_gpio_request_one(dev, gpio->num, ++ GPIOF_IN, gpio->label); ++ if (error < 0) { ++ dev_err(dev, ++ "Failed to request GPIO %d, error %d\n", ++ gpio->num, error); ++ return error; ++ } ++ } ++ if (of_property_read_u32(pp, "linux,code", &gpio->linux_code)) { ++ dev_err(dev, "Button without keycode: 0x%x\n", ++ gpio->num); ++ return -EINVAL; ++ } ++ if (of_property_read_u32(pp, "linux,input-type", ++ &gpio->report_type)) ++ gpio->report_type = EV_KEY; ++ } ++ if (nbtn == 0) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++#ifdef VOLUME_ADC_KEYS ++static int joypad_vol_setup(struct device *dev, struct joypad *joypad) ++{ ++ struct device_node *node, *pp; ++ struct adc_keys_button *map; ++ //struct device *adckey_dev; ++ enum iio_chan_type type; ++ int i; ++ int error; ++ ++ node = NULL; ++ node = of_find_matching_node(NULL, adckeys_of_match); ++ ++ if(node) { ++ ++ printk("%s into ...\n", __func__); ++ //adckey_dev = container_of(node, struct device, of_node); ++ joypad->st = devm_kzalloc(dev, sizeof(*joypad->st), GFP_KERNEL); ++ ++ joypad->st->channel = devm_iio_channel_get(dev, "volume-buttons"); ++ if (IS_ERR(joypad->st->channel)) ++ return PTR_ERR(joypad->st->channel); ++ ++ if (!joypad->st->channel->indio_dev) ++ return -ENXIO; ++ ++ error = iio_get_channel_type(joypad->st->channel, &type); ++ if (error < 0) ++ return error; ++ ++ if (type != IIO_VOLTAGE) { ++ dev_err(dev, "Incompatible channel type %d\n", type); ++ return -EINVAL; ++ } ++ ++ if (of_property_read_u32(node, "keyup-threshold-microvolt", ++ &joypad->st->keyup_voltage)) { ++ dev_err(dev, "Invalid or missing keyup voltage\n"); ++ return -EINVAL; ++ } ++ joypad->st->keyup_voltage /= 1000; ++ printk("%s : keyup_voltage = %d\n", __func__, joypad->st->keyup_voltage); ++ ++ joypad->st->num_keys = of_get_child_count(node); ++ if (joypad->st->num_keys == 0) { ++ dev_err(dev, "keymap is missing\n"); ++ return -EINVAL; ++ } ++ printk("%s : adc_keys = %d\n", __func__, joypad->st->num_keys); ++ ++ map = devm_kmalloc_array(dev, joypad->st->num_keys, sizeof(*map), GFP_KERNEL); ++ if (!map) ++ return -ENOMEM; ++ ++ i = 0; ++ for_each_child_of_node(node, pp) { ++ if (of_property_read_u32(pp, "press-threshold-microvolt", &map[i].voltage)) { ++ dev_err(dev, "Key with invalid or missing voltage\n"); ++ return -EINVAL; ++ } ++ map[i].voltage /= 1000; ++ printk("%s : key[%d] voltage = %d\n", __func__, i, map[i].voltage); ++ ++ if (of_property_read_u32(pp, "linux,code", &map[i].keycode)) { ++ dev_err(dev, "Key with invalid or missing linux,code\n"); ++ return -EINVAL; ++ } ++ printk("%s : key[%d] keycode = %d\n", __func__, i, map[i].keycode); ++ ++ i++; ++ } ++ joypad->st->map = map; ++ ++ } ++ if (i == 0) ++ return -EINVAL; ++ ++ printk("%s end ...\n", __func__); ++ return 0; ++} ++#endif ++/*----------------------------------------------------------------------------*/ ++#ifdef VIBRATORS_FF ++static int joypad_vib_setup(struct device *dev, struct joypad *joypad) ++{ ++ struct device_node *node; ++ int ret = 0; ++ ++ node = NULL; ++ node = of_find_matching_node(NULL, vibrators_of_match); ++ ++ if(node) { ++ ++ printk("%s into ... joypad = %p\n", __func__, joypad); ++ joypad->vib = devm_kzalloc(dev, sizeof(*joypad->vib), GFP_KERNEL); ++ ++ joypad->vib->gpio0 = of_get_named_gpio_flags(node, "vibrator0-gpio", 0, NULL); ++ if (!gpio_is_valid(joypad->vib->gpio0)) ++ return -1; ++ ++ printk("%s get vibrator0-gpio = %d \n", __func__, joypad->vib->gpio0); ++ ret = devm_gpio_request(dev, joypad->vib->gpio0, "vibrator0"); ++ if (ret < 0) ++ return ret; ++ ++ joypad->vib->gpio1 = of_get_named_gpio_flags(node, "vibrator1-gpio", 0, NULL); ++ if (!gpio_is_valid(joypad->vib->gpio1)) ++ return -1; ++ ++ printk("%s get vibrator1-gpio = %d \n", __func__, joypad->vib->gpio1); ++ ret = devm_gpio_request(dev, joypad->vib->gpio1, "vibrator1"); ++ if (ret < 0) ++ return ret; ++ ++ INIT_WORK(&joypad->vib->work, vib_work_handler); ++ ++ } ++ ++ printk("%s end ...\n", __func__); ++ return 0; ++} ++ ++/** ++ * gpio_vib_play_effect - function to handle vib effects. ++ * @dev: input device pointer ++ * @data: data of effect ++ * @effect: effect to play ++ * ++ * Currently this driver supports only rumble effects. ++ */ ++static int gpio_vib_play_effect(struct input_dev *dev, void *data, ++ struct ff_effect *effect) ++{ ++ __u16 strong; ++ __u16 weak; ++ //struct joypad *joypad = input_get_drvdata(dev); ++ struct joypad *joypad = data; ++ ++ printk("%s joypad gpio key count = %d\n", __func__, joypad->bt_gpio_count); ++ printk("%s joypad = %p, get vibrator0-gpio = %d \n", __func__, joypad, joypad->vib->gpio0); ++ strong = effect->u.rumble.strong_magnitude; ++ weak = effect->u.rumble.weak_magnitude; ++ ++ printk("%s strong = 0x%x, weak = 0x%x\n", __func__, strong, weak); ++ #if 1 ++ if ((strong > 1) && ((weak == 0) || (weak == 1))) { ++ joypad->vib->speed = effect->u.rumble.strong_magnitude >> 8; ++ joypad->vib->index = weak; ++ joypad->vib->last_index = joypad->vib->index; ++ } ++ else if ((strong == 0) && ((weak == 0) || (weak == 1))) { ++ joypad->vib->speed = 0; ++ } ++ else if ((weak > 0) && ((strong == 0) || (strong == 1))) { ++ joypad->vib->speed = effect->u.rumble.weak_magnitude >> 8; ++ joypad->vib->index = strong; ++ joypad->vib->last_index = joypad->vib->index; ++ } ++ else if ((weak > 0) && ((strong == 0) || (strong == 1))) { ++ joypad->vib->speed = 0; ++ } ++ ++ printk("%s speed = %d, index = %d\n", __func__, joypad->vib->speed, joypad->vib->index); ++ schedule_work(&joypad->vib->work); ++ #endif ++ return 0; ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_input_setup(struct device *dev, struct joypad *joypad) ++{ ++ struct input_polled_dev *poll_dev; ++ struct input_dev *input; ++ int nbtn, error; ++ ++ poll_dev = devm_input_allocate_polled_device(dev); ++ if (!poll_dev) { ++ dev_err(dev, "no memory for polled device\n"); ++ return -ENOMEM; ++ } ++ ++ poll_dev->private = joypad; ++ poll_dev->poll = joypad_poll; ++ poll_dev->poll_interval = joypad->poll_interval; ++ poll_dev->open = joypad_open; ++ poll_dev->close = joypad_close; ++ ++ input = poll_dev->input; ++ #ifdef RIGHT_ADC_JOYSTICK ++ global_input = poll_dev->input; ++ #endif ++ input->name = DRV_NAME; ++ input->phys = DRV_NAME"/input0"; ++ ++ input->id.bustype = BUS_HOST; ++ input->id.vendor = 0x0003; ++ input->id.product = 0x0003; ++ input->id.version = 0x0302; ++ ++ /* IIO ADC key setup (0 mv ~ 1800 mv) * adc->scale */ ++ __set_bit(EV_ABS, input->evbit); ++ for(nbtn = 0; nbtn < joypad->bt_adc_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ input_set_abs_params(input, adc->report_type, ++ adc->min, adc->max, ++ joypad->bt_adc_fuzz, ++ joypad->bt_adc_flat); ++ dev_info(dev, ++ "%s : SCALE = %d, ABS min = %d, max = %d," ++ " fuzz = %d, flat = %d, deadzone = %d\n", ++ __func__, adc->scale, adc->min, adc->max, ++ joypad->bt_adc_fuzz, joypad->bt_adc_flat, ++ joypad->bt_adc_deadzone); ++ } ++ #ifdef RIGHT_ADC_JOYSTICK ++ /* Right Analog */ ++ input_set_abs_params(input, ABS_RX, -900, 899, 32, 32); ++ input_set_abs_params(input, ABS_RY, -900, 899, 32, 32); ++ #endif ++ ++ /* GPIO key setup */ ++ __set_bit(EV_KEY, input->evbit); ++ for(nbtn = 0; nbtn < joypad->bt_gpio_count; nbtn++) { ++ struct bt_gpio *gpio = &joypad->gpios[nbtn]; ++ input_set_capability(input, gpio->report_type, ++ gpio->linux_code); ++ } ++#ifdef VOLUME_ADC_KEYS ++ /* ADC key setup */ ++ for (nbtn = 0; nbtn < joypad->st->num_keys; nbtn++) ++ __set_bit(joypad->st->map[nbtn].keycode, input->keybit); ++#endif ++ if (joypad->auto_repeat) ++ __set_bit(EV_REP, input->evbit); ++#ifdef VIBRATORS_FF ++ /* vibrator for ff */ ++ input_set_capability(input, EV_FF, FF_RUMBLE); ++ error = input_ff_create_memless(input, joypad, gpio_vib_play_effect); ++ if (error) ++ return error; ++#endif ++ joypad->dev = dev; ++ ++ error = input_register_polled_device(poll_dev); ++ if (error) { ++ dev_err(dev, "unable to register polled device, err=%d\n", ++ error); ++ return error; ++ } ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_setup_value_check(struct device *dev, struct joypad *joypad) ++{ ++ /* ++ fuzz: specifies fuzz value that is used to filter noise from ++ the event stream. ++ */ ++ if (g_button_adc_fuzz) ++ joypad->bt_adc_fuzz = g_button_adc_fuzz; ++ else ++ device_property_read_u32(dev, "button-adc-fuzz", ++ &joypad->bt_adc_fuzz); ++ /* ++ flat: values that are within this value will be discarded by ++ joydev interface and reported as 0 instead. ++ */ ++ if (g_button_adc_flat) ++ joypad->bt_adc_flat = g_button_adc_flat; ++ else ++ device_property_read_u32(dev, "button-adc-flat", ++ &joypad->bt_adc_flat); ++ ++ /* Joystick report value control */ ++ if (g_button_adc_scale) ++ joypad->bt_adc_scale = g_button_adc_scale; ++ else ++ device_property_read_u32(dev, "button-adc-scale", ++ &joypad->bt_adc_scale); ++ ++ /* Joystick deadzone value control */ ++ if (g_button_adc_deadzone) ++ joypad->bt_adc_deadzone = g_button_adc_deadzone; ++ else ++ device_property_read_u32(dev, "button-adc-deadzone", ++ &joypad->bt_adc_deadzone); ++ ++ if (g_button_adc_x_range) ++ joypad->bt_adc_x_range = g_button_adc_x_range; ++ else ++ device_property_read_u32(dev, "button-adc-x-range", ++ &joypad->bt_adc_x_range); ++ if (g_button_adc_y_range) ++ joypad->bt_adc_y_range = g_button_adc_y_range; ++ else ++ device_property_read_u32(dev, "button-adc-y-range", ++ &joypad->bt_adc_y_range); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_dt_parse(struct device *dev, struct joypad *joypad) ++{ ++ int error = 0; ++ ++ /* initialize value check from boot.ini */ ++ joypad_setup_value_check(dev, joypad); ++ ++ device_property_read_u32(dev, "button-adc-count", ++ &joypad->bt_adc_count); ++ ++ device_property_read_u32(dev, "poll-interval", ++ &joypad->poll_interval); ++ ++ joypad->auto_repeat = device_property_present(dev, "autorepeat"); ++ ++ /* change the report reference point? (ADC MAX - read value) */ ++ joypad->invert_absx = device_property_present(dev, "invert-absx"); ++ joypad->invert_absy = device_property_present(dev, "invert-absy"); ++ dev_info(dev, "%s : invert-absx = %d, inveret-absy = %d\n", ++ __func__, joypad->invert_absx, joypad->invert_absy); ++ ++ joypad->bt_gpio_count = device_get_child_node_count(dev); ++ ++ if ((joypad->bt_adc_count == 0) || (joypad->bt_gpio_count == 0)) { ++ dev_err(dev, "adc key = %d, gpio key = %d error!", ++ joypad->bt_adc_count, joypad->bt_gpio_count); ++ return -EINVAL; ++ } ++ ++ error = joypad_adc_setup(dev, joypad); ++ if (error) ++ return error; ++ ++ error = joypad_gpio_setup(dev, joypad); ++ if (error) ++ return error; ++#ifdef VOLUME_ADC_KEYS ++ error = joypad_vol_setup(dev, joypad); ++ printk("222 %s : error = %d\n", __func__, error); ++ if (error) ++ return error; ++#endif ++#ifdef VIBRATORS_FF ++ error = joypad_vib_setup(dev, joypad); ++ printk("333 %s : error = %d\n", __func__, error); ++ if (error) ++ return error; ++#endif ++ return error; ++} ++ ++#ifdef RIGHT_ADC_JOYSTICK ++static int joypad_misc_open(struct inode *inode, struct file *file) ++{ ++ printk("%s ...\n", __func__); ++ ++ //file->private_data = global_input; ++ nonseekable_open(inode, file); ++ ++ return 0; ++} ++ ++static int joypad_misc_release(struct inode *inode, struct file *file) ++{ ++ //struct input_dev *dev = file->private_data; ++ ++ //input_unregister_device(dev); ++ //kfree(dev); ++ ++ return 0; ++} ++ ++//static ssize_t joypad_inject_events(struct input_dev *dev, const char __user *buffer, size_t count ++static ssize_t joypad_inject_events(const char __user *buffer, size_t count) ++{ ++ struct input_event ev; ++ size_t bytes = 0; ++ ++ if (count != 0 && count < input_event_size()) ++ return -EINVAL; ++ ++ while (bytes + input_event_size() <= count) { ++ /* ++ * Note that even if some events were fetched successfully ++ * we are still going to return EFAULT instead of partial ++ * count to let userspace know that it got it's buffers ++ * all wrong. ++ */ ++ if (input_event_from_user(buffer + bytes, &ev)) ++ return -EFAULT; ++ ++ //input_event(dev, ev.type, ev.code, ev.value); ++ input_event(global_input, ev.type, ev.code, ev.value); ++ bytes += input_event_size(); ++ } ++ ++ return bytes; ++} ++ ++static ssize_t joypad_misc_write(struct file *file, const char __user *buffer, ++ size_t count, loff_t *ppos) ++{ ++ //struct input_dev *dev = file->private_data; ++ int retval; ++ ++ if (count == 0) ++ return 0; ++ ++ retval = mutex_lock_interruptible(&global_input->mutex); ++ if (retval) ++ return retval; ++ ++ //retval = joypad_inject_events(dev, buffer, count); ++ retval = joypad_inject_events(buffer, count); ++ ++ mutex_unlock(&global_input->mutex); ++ ++ return retval; ++} ++ ++static long joypad_misc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ int ret = 0; ++ return ret; ++} ++ ++ ++static const struct file_operations joypad_fops = { ++ .owner = THIS_MODULE, ++ .open = joypad_misc_open, ++ .release = joypad_misc_release, ++ .write = joypad_misc_write, ++ .unlocked_ioctl = joypad_misc_ioctl, ++ .llseek = no_llseek, ++ ++}; ++ ++ ++static struct miscdevice joypad_misc_dev = { ++ .minor = MISC_DYNAMIC_MINOR, ++ .name = "joypad", ++ .fops = &joypad_fops, ++}; ++#endif ++/*----------------------------------------------------------------------------*/ ++static int joypad_probe(struct platform_device *pdev) ++{ ++ struct joypad *joypad; ++ struct device *dev = &pdev->dev; ++ int error; ++ ++ joypad = devm_kzalloc(dev, sizeof(struct joypad), GFP_KERNEL); ++ if (!joypad) { ++ dev_err(dev, "joypad devm_kzmalloc error!"); ++ return -ENOMEM; ++ } ++ ++ /* device tree data parse */ ++ error = joypad_dt_parse(dev, joypad); ++ if (error) { ++ dev_err(dev, "dt parse error!(err = %d)\n", error); ++ return error; ++ } ++ ++ mutex_init(&joypad->lock); ++ platform_set_drvdata(pdev, joypad); ++ ++ error = sysfs_create_group(&pdev->dev.kobj, &joypad_attr_group); ++ if (error) { ++ dev_err(dev, "create sysfs group fail, error: %d\n", ++ error); ++ return error; ++ } ++ ++ /* poll input device setup */ ++ error = joypad_input_setup(dev, joypad); ++ if (error) { ++ dev_err(dev, "input setup failed!(err = %d)\n", error); ++ return error; ++ } ++#ifdef RIGHT_ADC_JOYSTICK ++ error = misc_register(&joypad_misc_dev); ++ if (error < 0) ++ printk("%s :fail to register misc device.\n", __func__); ++#endif ++ dev_info(dev, "%s : probe success\n", __func__); ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static const struct of_device_id joypad_of_match[] = { ++ /*{ .compatible = "odroidgo2-joypad", },*/ ++ { .compatible = "gameforce-gamepad", }, ++ {}, ++}; ++ ++MODULE_DEVICE_TABLE(of, joypad_of_match); ++ ++/*----------------------------------------------------------------------------*/ ++static struct platform_driver joypad_driver = { ++ .probe = joypad_probe, ++ .driver = { ++ .name = DRV_NAME, ++ .of_match_table = of_match_ptr(joypad_of_match), ++ }, ++}; ++ ++/*----------------------------------------------------------------------------*/ ++static int __init joypad_init(void) ++{ ++ return platform_driver_register(&joypad_driver); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void __exit joypad_exit(void) ++{ ++ platform_driver_unregister(&joypad_driver); ++} ++ ++/*----------------------------------------------------------------------------*/ ++late_initcall(joypad_init); ++module_exit(joypad_exit); ++ ++/*----------------------------------------------------------------------------*/ ++MODULE_AUTHOR("Hardkernel Co.,LTD"); ++MODULE_DESCRIPTION("Keypad driver(ADC&GPIO) for Gameforce CHI"); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:" DRV_NAME); ++ ++/*----------------------------------------------------------------------------*/ +diff --git a/drivers/input/joystick/odroidgo2-joypad.c b/drivers/input/joystick/odroidgo2-joypad.c +new file mode 100644 +index 000000000000..1382d69eec5e +--- /dev/null ++++ b/drivers/input/joystick/odroidgo2-joypad.c +@@ -0,0 +1,878 @@ ++/* ++ * SARADC joystick & GPIO Button driver for Linux(Hardkernel ODROIDGO2-Advance) ++ */ ++/* ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * Should you need to contact me, the author, you can do so either by ++ * e-mail - mail your message to , or by paper mail: ++ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic ++ */ ++ ++/*----------------------------------------------------------------------------*/ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/*----------------------------------------------------------------------------*/ ++#define DRV_NAME "odroidgo2_joypad" ++ ++/*----------------------------------------------------------------------------*/ ++struct bt_adc { ++ /* IIO ADC Channel */ ++ struct iio_channel *channel; ++ /* report value (mV) */ ++ int old_value; ++ /* report type */ ++ int report_type; ++ /* input device init value (mV) */ ++ int max, min; ++ /* calibrated adc value */ ++ int cal; ++ /* adc scale value */ ++ int scale; ++ /* invert report */ ++ bool invert; ++}; ++ ++struct bt_gpio { ++ /* GPIO Request label */ ++ const char *label; ++ /* GPIO Number */ ++ int num; ++ /* report type */ ++ int report_type; ++ /* report linux code */ ++ int linux_code; ++ /* prev button value */ ++ bool old_value; ++ /* button press level */ ++ bool active_level; ++}; ++ ++struct joypad { ++ struct device *dev; ++ int poll_interval; ++ ++ /* report enable/disable */ ++ bool enable; ++ ++ /* report reference point */ ++ bool invert_absx; ++ bool invert_absy; ++ ++ /* report interval (ms) */ ++ int bt_gpio_count; ++ struct bt_gpio *gpios; ++ /* button auto repeat */ ++ int auto_repeat; ++ ++ /* report threshold (mV) */ ++ int bt_adc_fuzz, bt_adc_flat; ++ int bt_adc_x_range, bt_adc_y_range; ++ /* adc read value scale */ ++ int bt_adc_scale; ++ /* joystick deadzone control */ ++ int bt_adc_deadzone; ++ int bt_adc_count; ++ struct bt_adc *adcs; ++ ++ struct mutex lock; ++}; ++ ++/*----------------------------------------------------------------------------*/ ++// ++// set to the value in the boot.ini file. (if exist) ++// ++/*----------------------------------------------------------------------------*/ ++static unsigned int g_button_adc_x_range = 0; ++static unsigned int g_button_adc_y_range = 0; ++static unsigned int g_button_adc_fuzz = 0; ++static unsigned int g_button_adc_flat = 0; ++static unsigned int g_button_adc_scale = 0; ++static unsigned int g_button_adc_deadzone = 0; ++ ++static int __init button_adcx_range_setup(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ ++ g_button_adc_x_range = simple_strtoul(str, NULL, 10); ++ ++ return 0; ++} ++__setup("button-adc-x-range=", button_adcx_range_setup); ++ ++static int __init button_adcy_range_setup(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ ++ g_button_adc_y_range = simple_strtoul(str, NULL, 10); ++ ++ return 0; ++} ++__setup("button-adc-y-range=", button_adcy_range_setup); ++ ++static int button_adc_fuzz(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_fuzz = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-fuzz=", button_adc_fuzz); ++ ++static int button_adc_flat(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_flat = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-flat=", button_adc_flat); ++ ++static int button_adc_scale(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_scale = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-scale=", button_adc_scale); ++ ++static int button_adc_deadzone(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_deadzone = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-deadzone=", button_adc_deadzone); ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++static int joypad_adc_read(struct bt_adc *adc) ++{ ++ int value; ++ ++ if (iio_read_channel_processed(adc->channel, &value)) ++ return 0; ++ ++ value *= adc->scale; ++ ++ return (adc->invert ? (adc->max - value) : value); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/odroidgo2_joypad/poll_interval [rw] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_poll_interval(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ mutex_lock(&joypad->lock); ++ joypad->poll_interval = simple_strtoul(buf, NULL, 10); ++ mutex_unlock(&joypad->lock); ++ ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_poll_interval(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->poll_interval); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(poll_interval, S_IWUSR | S_IRUGO, ++ joypad_show_poll_interval, ++ joypad_store_poll_interval); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/odroidgo2_joypad/adc_fuzz [r] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_adc_fuzz(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->bt_adc_fuzz); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(adc_fuzz, S_IWUSR | S_IRUGO, ++ joypad_show_adc_fuzz, ++ NULL); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/odroidgo2_joypad/adc_flat [r] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_adc_flat(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->bt_adc_flat); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(adc_flat, S_IWUSR | S_IRUGO, ++ joypad_show_adc_flat, ++ NULL); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/odroidgo2_joypad/enable [rw] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_enable(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ mutex_lock(&joypad->lock); ++ joypad->enable = simple_strtoul(buf, NULL, 10); ++ mutex_unlock(&joypad->lock); ++ ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_enable(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->enable); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO, ++ joypad_show_enable, ++ joypad_store_enable); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/odroidgo2_joypad/adc_cal [rw] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_adc_cal(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ bool calibration; ++ ++ calibration = simple_strtoul(buf, NULL, 10); ++ ++ if (calibration) { ++ int nbtn; ++ ++ mutex_lock(&joypad->lock); ++ for (nbtn = 0; nbtn < joypad->bt_adc_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ ++ adc->cal = joypad_adc_read(adc); ++ if (!adc->cal) { ++ dev_err(joypad->dev, "%s : saradc channels[%d]!\n", ++ __func__, nbtn); ++ continue; ++ } ++ adc->old_value = adc->cal; ++ } ++ mutex_unlock(&joypad->lock); ++ } ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_adc_cal(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ int nbtn; ++ ssize_t pos; ++ ++ for (nbtn = 0, pos = 0; nbtn < joypad->bt_adc_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ pos += sprintf(&buf[pos], "adc[%d]->cal = %d ", ++ nbtn, adc->cal); ++ } ++ pos += sprintf(&buf[pos], "\n"); ++ return pos; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(adc_cal, S_IWUSR | S_IRUGO, ++ joypad_show_adc_cal, ++ joypad_store_adc_cal); ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++static struct attribute *joypad_attrs[] = { ++ &dev_attr_poll_interval.attr, ++ &dev_attr_adc_fuzz.attr, ++ &dev_attr_adc_flat.attr, ++ &dev_attr_enable.attr, ++ &dev_attr_adc_cal.attr, ++ NULL, ++}; ++ ++static struct attribute_group joypad_attr_group = { ++ .attrs = joypad_attrs, ++}; ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++static void joypad_gpio_check(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ int nbtn, value; ++ ++ for (nbtn = 0; nbtn < joypad->bt_gpio_count; nbtn++) { ++ struct bt_gpio *gpio = &joypad->gpios[nbtn]; ++ ++ if (gpio_get_value_cansleep(gpio->num) < 0) { ++ dev_err(joypad->dev, "failed to get gpio state\n"); ++ continue; ++ } ++ value = gpio_get_value(gpio->num); ++ if (value != gpio->old_value) { ++ input_event(poll_dev->input, ++ gpio->report_type, ++ gpio->linux_code, ++ (value == gpio->active_level) ? 1 : 0); ++ gpio->old_value = value; ++ } ++ } ++ input_sync(poll_dev->input); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_adc_check(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ int nbtn, value; ++ ++ for (nbtn = 0; nbtn < joypad->bt_adc_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ ++ value = joypad_adc_read(adc); ++ if (!value) { ++ dev_err(joypad->dev, "%s : saradc channels[%d]!\n", ++ __func__, nbtn); ++ continue; ++ } ++ ++ /* Joystick Deadzone check */ ++ if (joypad->bt_adc_deadzone) { ++ if ((value < adc->cal + joypad->bt_adc_deadzone) && ++ (value > adc->cal - joypad->bt_adc_deadzone)) ++ value = adc->cal; ++ } ++ value = value - adc->cal; ++ value = value > adc->max ? adc->max : value; ++ value = value < adc->min ? adc->min : value; ++ ++ if (nbtn == 0) ++ { ++ // adc-x value is default inverted(h/w) ++ input_report_abs(poll_dev->input, ++ adc->report_type, value * (-1)); ++ } ++ else ++ { ++ input_report_abs(poll_dev->input, ++ adc->report_type, value); ++ } ++ adc->old_value = value; ++ } ++ input_sync(poll_dev->input); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_poll(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ ++ if (joypad->enable) { ++ joypad_adc_check(poll_dev); ++ joypad_gpio_check(poll_dev); ++ } ++ if (poll_dev->poll_interval != joypad->poll_interval) { ++ mutex_lock(&joypad->lock); ++ poll_dev->poll_interval = joypad->poll_interval; ++ mutex_unlock(&joypad->lock); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_open(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ int nbtn; ++ ++ for (nbtn = 0; nbtn < joypad->bt_gpio_count; nbtn++) { ++ struct bt_gpio *gpio = &joypad->gpios[nbtn]; ++ gpio->old_value = gpio->active_level ? 0 : 1; ++ } ++ for (nbtn = 0; nbtn < joypad->bt_adc_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ ++ adc->old_value = joypad_adc_read(adc); ++ if (!adc->old_value) { ++ dev_err(joypad->dev, "%s : saradc channels[%d]!\n", ++ __func__, nbtn); ++ continue; ++ } ++ adc->cal = adc->old_value; ++ dev_info(joypad->dev, "%s : adc[%d] adc->cal = %d\n", ++ __func__, nbtn, adc->cal); ++ } ++ /* buttons status sync */ ++ joypad_adc_check(poll_dev); ++ joypad_gpio_check(poll_dev); ++ ++ /* button report enable */ ++ mutex_lock(&joypad->lock); ++ joypad->enable = true; ++ mutex_unlock(&joypad->lock); ++ ++ dev_info(joypad->dev, "%s : opened\n", __func__); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_close(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ ++ /* button report disable */ ++ mutex_lock(&joypad->lock); ++ joypad->enable = false; ++ mutex_unlock(&joypad->lock); ++ ++ dev_info(joypad->dev, "%s : closed\n", __func__); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_adc_setup(struct device *dev, struct joypad *joypad) ++{ ++ int nbtn = 0; ++ ++ joypad->adcs = devm_kzalloc(dev, joypad->bt_adc_count * ++ sizeof(struct bt_adc), GFP_KERNEL); ++ ++ if (!joypad->adcs) { ++ dev_err(dev, "%s devm_kzmalloc error!", __func__); ++ return -ENOMEM; ++ } ++ ++ for (nbtn = 0; nbtn < joypad->bt_adc_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ enum iio_chan_type type; ++ ++ adc->scale = joypad->bt_adc_scale; ++ if (nbtn) { ++ adc->channel = ++ devm_iio_channel_get(dev, "joy_y"); ++ adc->report_type = ABS_Y; ++ if (joypad->invert_absy) ++ adc->invert = true; ++ ++ adc->max = (joypad->bt_adc_y_range / 2) - 1; ++ adc->min = -(joypad->bt_adc_y_range / 2); ++ } ++ else { ++ adc->channel = ++ devm_iio_channel_get(dev, "joy_x"); ++ adc->report_type = ABS_X; ++ if (joypad->invert_absx) ++ adc->invert = true; ++ ++ adc->max = (joypad->bt_adc_x_range / 2) - 1; ++ adc->min = -(joypad->bt_adc_x_range / 2); ++ } ++ ++ if (IS_ERR(adc->channel)) { ++ dev_err(dev, "iio channel[%d] get error\n", nbtn); ++ return -EINVAL; ++ } ++ if (!adc->channel->indio_dev) ++ return -ENXIO; ++ ++ if (iio_get_channel_type(adc->channel, &type)) ++ return -EINVAL; ++ ++ if (type != IIO_VOLTAGE) { ++ dev_err(dev, "Incompatible channel %d type %d\n", ++ nbtn, type); ++ return -EINVAL; ++ } ++ } ++ if (nbtn == 0) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_gpio_setup(struct device *dev, struct joypad *joypad) ++{ ++ struct device_node *node, *pp; ++ int nbtn; ++ ++ node = dev->of_node; ++ if (!node) ++ return -ENODEV; ++ ++ joypad->gpios = devm_kzalloc(dev, joypad->bt_gpio_count * ++ sizeof(struct bt_gpio), GFP_KERNEL); ++ ++ if (!joypad->gpios) { ++ dev_err(dev, "%s devm_kzmalloc error!", __func__); ++ return -ENOMEM; ++ } ++ ++ nbtn = 0; ++ for_each_child_of_node(node, pp) { ++ enum of_gpio_flags flags; ++ struct bt_gpio *gpio = &joypad->gpios[nbtn++]; ++ int error; ++ ++ gpio->num = of_get_gpio_flags(pp, 0, &flags); ++ if (gpio->num < 0) { ++ error = gpio->num; ++ dev_err(dev, "Failed to get gpio flags, error: %d\n", ++ error); ++ return error; ++ } ++ ++ /* gpio active level(key press level) */ ++ gpio->active_level = (flags & OF_GPIO_ACTIVE_LOW) ? 0 : 1; ++ ++ gpio->label = of_get_property(pp, "label", NULL); ++ ++ if (gpio_is_valid(gpio->num)) { ++ error = devm_gpio_request_one(dev, gpio->num, ++ GPIOF_IN, gpio->label); ++ if (error < 0) { ++ dev_err(dev, ++ "Failed to request GPIO %d, error %d\n", ++ gpio->num, error); ++ return error; ++ } ++ } ++ if (of_property_read_u32(pp, "linux,code", &gpio->linux_code)) { ++ dev_err(dev, "Button without keycode: 0x%x\n", ++ gpio->num); ++ return -EINVAL; ++ } ++ if (of_property_read_u32(pp, "linux,input-type", ++ &gpio->report_type)) ++ gpio->report_type = EV_KEY; ++ } ++ if (nbtn == 0) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_input_setup(struct device *dev, struct joypad *joypad) ++{ ++ struct input_polled_dev *poll_dev; ++ struct input_dev *input; ++ int nbtn, error; ++ ++ poll_dev = devm_input_allocate_polled_device(dev); ++ if (!poll_dev) { ++ dev_err(dev, "no memory for polled device\n"); ++ return -ENOMEM; ++ } ++ ++ poll_dev->private = joypad; ++ poll_dev->poll = joypad_poll; ++ poll_dev->poll_interval = joypad->poll_interval; ++ poll_dev->open = joypad_open; ++ poll_dev->close = joypad_close; ++ ++ input = poll_dev->input; ++ ++ input->name = DRV_NAME; ++ input->phys = DRV_NAME"/input0"; ++ ++ input->id.bustype = BUS_HOST; ++ input->id.vendor = 0x0001; ++ input->id.product = 0x0001; ++ input->id.version = 0x0101; ++ ++ /* IIO ADC key setup (0 mv ~ 1800 mv) * adc->scale */ ++ __set_bit(EV_ABS, input->evbit); ++ for(nbtn = 0; nbtn < joypad->bt_adc_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ input_set_abs_params(input, adc->report_type, ++ adc->min, adc->max, ++ joypad->bt_adc_fuzz, ++ joypad->bt_adc_flat); ++ dev_info(dev, ++ "%s : SCALE = %d, ABS min = %d, max = %d," ++ " fuzz = %d, flat = %d, deadzone = %d\n", ++ __func__, adc->scale, adc->min, adc->max, ++ joypad->bt_adc_fuzz, joypad->bt_adc_flat, ++ joypad->bt_adc_deadzone); ++ } ++ ++ /* GPIO key setup */ ++ __set_bit(EV_KEY, input->evbit); ++ for(nbtn = 0; nbtn < joypad->bt_gpio_count; nbtn++) { ++ struct bt_gpio *gpio = &joypad->gpios[nbtn]; ++ input_set_capability(input, gpio->report_type, ++ gpio->linux_code); ++ } ++ ++ if (joypad->auto_repeat) ++ __set_bit(EV_REP, input->evbit); ++ ++ joypad->dev = dev; ++ ++ error = input_register_polled_device(poll_dev); ++ if (error) { ++ dev_err(dev, "unable to register polled device, err=%d\n", ++ error); ++ return error; ++ } ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_setup_value_check(struct device *dev, struct joypad *joypad) ++{ ++ /* ++ fuzz: specifies fuzz value that is used to filter noise from ++ the event stream. ++ */ ++ if (g_button_adc_fuzz) ++ joypad->bt_adc_fuzz = g_button_adc_fuzz; ++ else ++ device_property_read_u32(dev, "button-adc-fuzz", ++ &joypad->bt_adc_fuzz); ++ /* ++ flat: values that are within this value will be discarded by ++ joydev interface and reported as 0 instead. ++ */ ++ if (g_button_adc_flat) ++ joypad->bt_adc_flat = g_button_adc_flat; ++ else ++ device_property_read_u32(dev, "button-adc-flat", ++ &joypad->bt_adc_flat); ++ ++ /* Joystick report value control */ ++ if (g_button_adc_scale) ++ joypad->bt_adc_scale = g_button_adc_scale; ++ else ++ device_property_read_u32(dev, "button-adc-scale", ++ &joypad->bt_adc_scale); ++ ++ /* Joystick deadzone value control */ ++ if (g_button_adc_deadzone) ++ joypad->bt_adc_deadzone = g_button_adc_deadzone; ++ else ++ device_property_read_u32(dev, "button-adc-deadzone", ++ &joypad->bt_adc_deadzone); ++ ++ if (g_button_adc_x_range) ++ joypad->bt_adc_x_range = g_button_adc_x_range; ++ else ++ device_property_read_u32(dev, "button-adc-x-range", ++ &joypad->bt_adc_x_range); ++ if (g_button_adc_y_range) ++ joypad->bt_adc_y_range = g_button_adc_y_range; ++ else ++ device_property_read_u32(dev, "button-adc-y-range", ++ &joypad->bt_adc_y_range); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_dt_parse(struct device *dev, struct joypad *joypad) ++{ ++ int error = 0; ++ ++ /* initialize value check from boot.ini */ ++ joypad_setup_value_check(dev, joypad); ++ ++ device_property_read_u32(dev, "button-adc-count", ++ &joypad->bt_adc_count); ++ ++ device_property_read_u32(dev, "poll-interval", ++ &joypad->poll_interval); ++ ++ joypad->auto_repeat = device_property_present(dev, "autorepeat"); ++ ++ /* change the report reference point? (ADC MAX - read value) */ ++ joypad->invert_absx = device_property_present(dev, "invert-absx"); ++ joypad->invert_absy = device_property_present(dev, "invert-absy"); ++ dev_info(dev, "%s : invert-absx = %d, inveret-absy = %d\n", ++ __func__, joypad->invert_absx, joypad->invert_absy); ++ ++ joypad->bt_gpio_count = device_get_child_node_count(dev); ++ ++ if ((joypad->bt_adc_count == 0) || (joypad->bt_gpio_count == 0)) { ++ dev_err(dev, "adc key = %d, gpio key = %d error!", ++ joypad->bt_adc_count, joypad->bt_gpio_count); ++ return -EINVAL; ++ } ++ ++ error = joypad_adc_setup(dev, joypad); ++ if (error) ++ return error; ++ ++ error = joypad_gpio_setup(dev, joypad); ++ if (error) ++ return error; ++ ++ return error; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_probe(struct platform_device *pdev) ++{ ++ struct joypad *joypad; ++ struct device *dev = &pdev->dev; ++ int error; ++ ++ joypad = devm_kzalloc(dev, sizeof(struct joypad), GFP_KERNEL); ++ if (!joypad) { ++ dev_err(dev, "joypad devm_kzmalloc error!"); ++ return -ENOMEM; ++ } ++ ++ /* device tree data parse */ ++ error = joypad_dt_parse(dev, joypad); ++ if (error) { ++ dev_err(dev, "dt parse error!(err = %d)\n", error); ++ return error; ++ } ++ ++ mutex_init(&joypad->lock); ++ platform_set_drvdata(pdev, joypad); ++ ++ error = sysfs_create_group(&pdev->dev.kobj, &joypad_attr_group); ++ if (error) { ++ dev_err(dev, "create sysfs group fail, error: %d\n", ++ error); ++ return error; ++ } ++ ++ /* poll input device setup */ ++ error = joypad_input_setup(dev, joypad); ++ if (error) { ++ dev_err(dev, "input setup failed!(err = %d)\n", error); ++ return error; ++ } ++ dev_info(dev, "%s : probe success\n", __func__); ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static const struct of_device_id joypad_of_match[] = { ++ { .compatible = "odroidgo2-joypad", }, ++ {}, ++}; ++ ++MODULE_DEVICE_TABLE(of, joypad_of_match); ++ ++/*----------------------------------------------------------------------------*/ ++static struct platform_driver joypad_driver = { ++ .probe = joypad_probe, ++ .driver = { ++ .name = DRV_NAME, ++ .of_match_table = of_match_ptr(joypad_of_match), ++ }, ++}; ++ ++/*----------------------------------------------------------------------------*/ ++static int __init joypad_init(void) ++{ ++ return platform_driver_register(&joypad_driver); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void __exit joypad_exit(void) ++{ ++ platform_driver_unregister(&joypad_driver); ++} ++ ++/*----------------------------------------------------------------------------*/ ++late_initcall(joypad_init); ++module_exit(joypad_exit); ++ ++/*----------------------------------------------------------------------------*/ ++MODULE_AUTHOR("Hardkernel Co.,LTD"); ++MODULE_DESCRIPTION("Keypad driver(ADC&GPIO) for ODROIDGO-Advance"); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:" DRV_NAME); ++ ++/*----------------------------------------------------------------------------*/ +diff --git a/drivers/input/joystick/odroidgo2-v11-joypad.c b/drivers/input/joystick/odroidgo2-v11-joypad.c +new file mode 100644 +index 000000000000..b5bd7cb40a9b +--- /dev/null ++++ b/drivers/input/joystick/odroidgo2-v11-joypad.c +@@ -0,0 +1,878 @@ ++/* ++ * SARADC joystick & GPIO Button driver for Linux(Hardkernel ODROIDGO2-Advance) ++ */ ++/* ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * Should you need to contact me, the author, you can do so either by ++ * e-mail - mail your message to , or by paper mail: ++ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic ++ */ ++ ++/*----------------------------------------------------------------------------*/ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/*----------------------------------------------------------------------------*/ ++#define DRV_NAME "odroidgo2_v11_joypad" ++ ++/*----------------------------------------------------------------------------*/ ++struct bt_adc { ++ /* IIO ADC Channel */ ++ struct iio_channel *channel; ++ /* report value (mV) */ ++ int old_value; ++ /* report type */ ++ int report_type; ++ /* input device init value (mV) */ ++ int max, min; ++ /* calibrated adc value */ ++ int cal; ++ /* adc scale value */ ++ int scale; ++ /* invert report */ ++ bool invert; ++}; ++ ++struct bt_gpio { ++ /* GPIO Request label */ ++ const char *label; ++ /* GPIO Number */ ++ int num; ++ /* report type */ ++ int report_type; ++ /* report linux code */ ++ int linux_code; ++ /* prev button value */ ++ bool old_value; ++ /* button press level */ ++ bool active_level; ++}; ++ ++struct joypad { ++ struct device *dev; ++ int poll_interval; ++ ++ /* report enable/disable */ ++ bool enable; ++ ++ /* report reference point */ ++ bool invert_absx; ++ bool invert_absy; ++ ++ /* report interval (ms) */ ++ int bt_gpio_count; ++ struct bt_gpio *gpios; ++ /* button auto repeat */ ++ int auto_repeat; ++ ++ /* report threshold (mV) */ ++ int bt_adc_fuzz, bt_adc_flat; ++ int bt_adc_x_range, bt_adc_y_range; ++ /* adc read value scale */ ++ int bt_adc_scale; ++ /* joystick deadzone control */ ++ int bt_adc_deadzone; ++ int bt_adc_count; ++ struct bt_adc *adcs; ++ ++ struct mutex lock; ++}; ++ ++/*----------------------------------------------------------------------------*/ ++// ++// set to the value in the boot.ini file. (if exist) ++// ++/*----------------------------------------------------------------------------*/ ++static unsigned int g_button_adc_x_range = 0; ++static unsigned int g_button_adc_y_range = 0; ++static unsigned int g_button_adc_fuzz = 0; ++static unsigned int g_button_adc_flat = 0; ++static unsigned int g_button_adc_scale = 0; ++static unsigned int g_button_adc_deadzone = 0; ++ ++static int __init button_adcx_range_setup(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ ++ g_button_adc_x_range = simple_strtoul(str, NULL, 10); ++ ++ return 0; ++} ++__setup("button-adc-x-range=", button_adcx_range_setup); ++ ++static int __init button_adcy_range_setup(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ ++ g_button_adc_y_range = simple_strtoul(str, NULL, 10); ++ ++ return 0; ++} ++__setup("button-adc-y-range=", button_adcy_range_setup); ++ ++static int button_adc_fuzz(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_fuzz = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-fuzz=", button_adc_fuzz); ++ ++static int button_adc_flat(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_flat = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-flat=", button_adc_flat); ++ ++static int button_adc_scale(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_scale = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-scale=", button_adc_scale); ++ ++static int button_adc_deadzone(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_deadzone = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-deadzone=", button_adc_deadzone); ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++static int joypad_adc_read(struct bt_adc *adc) ++{ ++ int value; ++ ++ if (iio_read_channel_processed(adc->channel, &value)) ++ return 0; ++ ++ value *= adc->scale; ++ ++ return (adc->invert ? (adc->max - value) : value); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/odroidgo2_joypad/poll_interval [rw] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_poll_interval(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ mutex_lock(&joypad->lock); ++ joypad->poll_interval = simple_strtoul(buf, NULL, 10); ++ mutex_unlock(&joypad->lock); ++ ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_poll_interval(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->poll_interval); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(poll_interval, S_IWUSR | S_IRUGO, ++ joypad_show_poll_interval, ++ joypad_store_poll_interval); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/odroidgo2_joypad/adc_fuzz [r] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_adc_fuzz(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->bt_adc_fuzz); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(adc_fuzz, S_IWUSR | S_IRUGO, ++ joypad_show_adc_fuzz, ++ NULL); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/odroidgo2_joypad/adc_flat [r] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_adc_flat(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->bt_adc_flat); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(adc_flat, S_IWUSR | S_IRUGO, ++ joypad_show_adc_flat, ++ NULL); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/odroidgo2_joypad/enable [rw] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_enable(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ mutex_lock(&joypad->lock); ++ joypad->enable = simple_strtoul(buf, NULL, 10); ++ mutex_unlock(&joypad->lock); ++ ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_enable(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->enable); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO, ++ joypad_show_enable, ++ joypad_store_enable); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/odroidgo2_joypad/adc_cal [rw] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_adc_cal(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ bool calibration; ++ ++ calibration = simple_strtoul(buf, NULL, 10); ++ ++ if (calibration) { ++ int nbtn; ++ ++ mutex_lock(&joypad->lock); ++ for (nbtn = 0; nbtn < joypad->bt_adc_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ ++ adc->cal = joypad_adc_read(adc); ++ if (!adc->cal) { ++ dev_err(joypad->dev, "%s : saradc channels[%d]!\n", ++ __func__, nbtn); ++ continue; ++ } ++ adc->old_value = adc->cal; ++ } ++ mutex_unlock(&joypad->lock); ++ } ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_adc_cal(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ int nbtn; ++ ssize_t pos; ++ ++ for (nbtn = 0, pos = 0; nbtn < joypad->bt_adc_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ pos += sprintf(&buf[pos], "adc[%d]->cal = %d ", ++ nbtn, adc->cal); ++ } ++ pos += sprintf(&buf[pos], "\n"); ++ return pos; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(adc_cal, S_IWUSR | S_IRUGO, ++ joypad_show_adc_cal, ++ joypad_store_adc_cal); ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++static struct attribute *joypad_attrs[] = { ++ &dev_attr_poll_interval.attr, ++ &dev_attr_adc_fuzz.attr, ++ &dev_attr_adc_flat.attr, ++ &dev_attr_enable.attr, ++ &dev_attr_adc_cal.attr, ++ NULL, ++}; ++ ++static struct attribute_group joypad_attr_group = { ++ .attrs = joypad_attrs, ++}; ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++static void joypad_gpio_check(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ int nbtn, value; ++ ++ for (nbtn = 0; nbtn < joypad->bt_gpio_count; nbtn++) { ++ struct bt_gpio *gpio = &joypad->gpios[nbtn]; ++ ++ if (gpio_get_value_cansleep(gpio->num) < 0) { ++ dev_err(joypad->dev, "failed to get gpio state\n"); ++ continue; ++ } ++ value = gpio_get_value(gpio->num); ++ if (value != gpio->old_value) { ++ input_event(poll_dev->input, ++ gpio->report_type, ++ gpio->linux_code, ++ (value == gpio->active_level) ? 1 : 0); ++ gpio->old_value = value; ++ } ++ } ++ input_sync(poll_dev->input); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_adc_check(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ int nbtn, value; ++ ++ for (nbtn = 0; nbtn < joypad->bt_adc_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ ++ value = joypad_adc_read(adc); ++ if (!value) { ++ dev_err(joypad->dev, "%s : saradc channels[%d]!\n", ++ __func__, nbtn); ++ continue; ++ } ++ ++ /* Joystick Deadzone check */ ++ if (joypad->bt_adc_deadzone) { ++ if ((value < adc->cal + joypad->bt_adc_deadzone) && ++ (value > adc->cal - joypad->bt_adc_deadzone)) ++ value = adc->cal; ++ } ++ value = value - adc->cal; ++ value = value > adc->max ? adc->max : value; ++ value = value < adc->min ? adc->min : value; ++ ++ if (nbtn == 0) ++ { ++ // adc-x value is default inverted(h/w) ++ input_report_abs(poll_dev->input, ++ adc->report_type, value * (-1)); ++ } ++ else ++ { ++ input_report_abs(poll_dev->input, ++ adc->report_type, value); ++ } ++ adc->old_value = value; ++ } ++ input_sync(poll_dev->input); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_poll(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ ++ if (joypad->enable) { ++ joypad_adc_check(poll_dev); ++ joypad_gpio_check(poll_dev); ++ } ++ if (poll_dev->poll_interval != joypad->poll_interval) { ++ mutex_lock(&joypad->lock); ++ poll_dev->poll_interval = joypad->poll_interval; ++ mutex_unlock(&joypad->lock); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_open(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ int nbtn; ++ ++ for (nbtn = 0; nbtn < joypad->bt_gpio_count; nbtn++) { ++ struct bt_gpio *gpio = &joypad->gpios[nbtn]; ++ gpio->old_value = gpio->active_level ? 0 : 1; ++ } ++ for (nbtn = 0; nbtn < joypad->bt_adc_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ ++ adc->old_value = joypad_adc_read(adc); ++ if (!adc->old_value) { ++ dev_err(joypad->dev, "%s : saradc channels[%d]!\n", ++ __func__, nbtn); ++ continue; ++ } ++ adc->cal = adc->old_value; ++ dev_info(joypad->dev, "%s : adc[%d] adc->cal = %d\n", ++ __func__, nbtn, adc->cal); ++ } ++ /* buttons status sync */ ++ joypad_adc_check(poll_dev); ++ joypad_gpio_check(poll_dev); ++ ++ /* button report enable */ ++ mutex_lock(&joypad->lock); ++ joypad->enable = true; ++ mutex_unlock(&joypad->lock); ++ ++ dev_info(joypad->dev, "%s : opened\n", __func__); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_close(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ ++ /* button report disable */ ++ mutex_lock(&joypad->lock); ++ joypad->enable = false; ++ mutex_unlock(&joypad->lock); ++ ++ dev_info(joypad->dev, "%s : closed\n", __func__); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_adc_setup(struct device *dev, struct joypad *joypad) ++{ ++ int nbtn = 0; ++ ++ joypad->adcs = devm_kzalloc(dev, joypad->bt_adc_count * ++ sizeof(struct bt_adc), GFP_KERNEL); ++ ++ if (!joypad->adcs) { ++ dev_err(dev, "%s devm_kzmalloc error!", __func__); ++ return -ENOMEM; ++ } ++ ++ for (nbtn = 0; nbtn < joypad->bt_adc_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ enum iio_chan_type type; ++ ++ adc->scale = joypad->bt_adc_scale; ++ if (nbtn) { ++ adc->channel = ++ devm_iio_channel_get(dev, "joy_y"); ++ adc->report_type = ABS_Y; ++ if (joypad->invert_absy) ++ adc->invert = true; ++ ++ adc->max = (joypad->bt_adc_y_range / 2) - 1; ++ adc->min = -(joypad->bt_adc_y_range / 2); ++ } ++ else { ++ adc->channel = ++ devm_iio_channel_get(dev, "joy_x"); ++ adc->report_type = ABS_X; ++ if (joypad->invert_absx) ++ adc->invert = true; ++ ++ adc->max = (joypad->bt_adc_x_range / 2) - 1; ++ adc->min = -(joypad->bt_adc_x_range / 2); ++ } ++ ++ if (IS_ERR(adc->channel)) { ++ dev_err(dev, "iio channel[%d] get error\n", nbtn); ++ return -EINVAL; ++ } ++ if (!adc->channel->indio_dev) ++ return -ENXIO; ++ ++ if (iio_get_channel_type(adc->channel, &type)) ++ return -EINVAL; ++ ++ if (type != IIO_VOLTAGE) { ++ dev_err(dev, "Incompatible channel %d type %d\n", ++ nbtn, type); ++ return -EINVAL; ++ } ++ } ++ if (nbtn == 0) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_gpio_setup(struct device *dev, struct joypad *joypad) ++{ ++ struct device_node *node, *pp; ++ int nbtn; ++ ++ node = dev->of_node; ++ if (!node) ++ return -ENODEV; ++ ++ joypad->gpios = devm_kzalloc(dev, joypad->bt_gpio_count * ++ sizeof(struct bt_gpio), GFP_KERNEL); ++ ++ if (!joypad->gpios) { ++ dev_err(dev, "%s devm_kzmalloc error!", __func__); ++ return -ENOMEM; ++ } ++ ++ nbtn = 0; ++ for_each_child_of_node(node, pp) { ++ enum of_gpio_flags flags; ++ struct bt_gpio *gpio = &joypad->gpios[nbtn++]; ++ int error; ++ ++ gpio->num = of_get_gpio_flags(pp, 0, &flags); ++ if (gpio->num < 0) { ++ error = gpio->num; ++ dev_err(dev, "Failed to get gpio flags, error: %d\n", ++ error); ++ return error; ++ } ++ ++ /* gpio active level(key press level) */ ++ gpio->active_level = (flags & OF_GPIO_ACTIVE_LOW) ? 0 : 1; ++ ++ gpio->label = of_get_property(pp, "label", NULL); ++ ++ if (gpio_is_valid(gpio->num)) { ++ error = devm_gpio_request_one(dev, gpio->num, ++ GPIOF_IN, gpio->label); ++ if (error < 0) { ++ dev_err(dev, ++ "Failed to request GPIO %d, error %d\n", ++ gpio->num, error); ++ return error; ++ } ++ } ++ if (of_property_read_u32(pp, "linux,code", &gpio->linux_code)) { ++ dev_err(dev, "Button without keycode: 0x%x\n", ++ gpio->num); ++ return -EINVAL; ++ } ++ if (of_property_read_u32(pp, "linux,input-type", ++ &gpio->report_type)) ++ gpio->report_type = EV_KEY; ++ } ++ if (nbtn == 0) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_input_setup(struct device *dev, struct joypad *joypad) ++{ ++ struct input_polled_dev *poll_dev; ++ struct input_dev *input; ++ int nbtn, error; ++ ++ poll_dev = devm_input_allocate_polled_device(dev); ++ if (!poll_dev) { ++ dev_err(dev, "no memory for polled device\n"); ++ return -ENOMEM; ++ } ++ ++ poll_dev->private = joypad; ++ poll_dev->poll = joypad_poll; ++ poll_dev->poll_interval = joypad->poll_interval; ++ poll_dev->open = joypad_open; ++ poll_dev->close = joypad_close; ++ ++ input = poll_dev->input; ++ ++ input->name = DRV_NAME; ++ input->phys = DRV_NAME"/input0"; ++ ++ input->id.bustype = BUS_HOST; ++ input->id.vendor = 0x0001; ++ input->id.product = 0x0002; ++ input->id.version = 0x0101; ++ ++ /* IIO ADC key setup (0 mv ~ 1800 mv) * adc->scale */ ++ __set_bit(EV_ABS, input->evbit); ++ for(nbtn = 0; nbtn < joypad->bt_adc_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ input_set_abs_params(input, adc->report_type, ++ adc->min, adc->max, ++ joypad->bt_adc_fuzz, ++ joypad->bt_adc_flat); ++ dev_info(dev, ++ "%s : SCALE = %d, ABS min = %d, max = %d," ++ " fuzz = %d, flat = %d, deadzone = %d\n", ++ __func__, adc->scale, adc->min, adc->max, ++ joypad->bt_adc_fuzz, joypad->bt_adc_flat, ++ joypad->bt_adc_deadzone); ++ } ++ ++ /* GPIO key setup */ ++ __set_bit(EV_KEY, input->evbit); ++ for(nbtn = 0; nbtn < joypad->bt_gpio_count; nbtn++) { ++ struct bt_gpio *gpio = &joypad->gpios[nbtn]; ++ input_set_capability(input, gpio->report_type, ++ gpio->linux_code); ++ } ++ ++ if (joypad->auto_repeat) ++ __set_bit(EV_REP, input->evbit); ++ ++ joypad->dev = dev; ++ ++ error = input_register_polled_device(poll_dev); ++ if (error) { ++ dev_err(dev, "unable to register polled device, err=%d\n", ++ error); ++ return error; ++ } ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_setup_value_check(struct device *dev, struct joypad *joypad) ++{ ++ /* ++ fuzz: specifies fuzz value that is used to filter noise from ++ the event stream. ++ */ ++ if (g_button_adc_fuzz) ++ joypad->bt_adc_fuzz = g_button_adc_fuzz; ++ else ++ device_property_read_u32(dev, "button-adc-fuzz", ++ &joypad->bt_adc_fuzz); ++ /* ++ flat: values that are within this value will be discarded by ++ joydev interface and reported as 0 instead. ++ */ ++ if (g_button_adc_flat) ++ joypad->bt_adc_flat = g_button_adc_flat; ++ else ++ device_property_read_u32(dev, "button-adc-flat", ++ &joypad->bt_adc_flat); ++ ++ /* Joystick report value control */ ++ if (g_button_adc_scale) ++ joypad->bt_adc_scale = g_button_adc_scale; ++ else ++ device_property_read_u32(dev, "button-adc-scale", ++ &joypad->bt_adc_scale); ++ ++ /* Joystick deadzone value control */ ++ if (g_button_adc_deadzone) ++ joypad->bt_adc_deadzone = g_button_adc_deadzone; ++ else ++ device_property_read_u32(dev, "button-adc-deadzone", ++ &joypad->bt_adc_deadzone); ++ ++ if (g_button_adc_x_range) ++ joypad->bt_adc_x_range = g_button_adc_x_range; ++ else ++ device_property_read_u32(dev, "button-adc-x-range", ++ &joypad->bt_adc_x_range); ++ if (g_button_adc_y_range) ++ joypad->bt_adc_y_range = g_button_adc_y_range; ++ else ++ device_property_read_u32(dev, "button-adc-y-range", ++ &joypad->bt_adc_y_range); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_dt_parse(struct device *dev, struct joypad *joypad) ++{ ++ int error = 0; ++ ++ /* initialize value check from boot.ini */ ++ joypad_setup_value_check(dev, joypad); ++ ++ device_property_read_u32(dev, "button-adc-count", ++ &joypad->bt_adc_count); ++ ++ device_property_read_u32(dev, "poll-interval", ++ &joypad->poll_interval); ++ ++ joypad->auto_repeat = device_property_present(dev, "autorepeat"); ++ ++ /* change the report reference point? (ADC MAX - read value) */ ++ joypad->invert_absx = device_property_present(dev, "invert-absx"); ++ joypad->invert_absy = device_property_present(dev, "invert-absy"); ++ dev_info(dev, "%s : invert-absx = %d, inveret-absy = %d\n", ++ __func__, joypad->invert_absx, joypad->invert_absy); ++ ++ joypad->bt_gpio_count = device_get_child_node_count(dev); ++ ++ if ((joypad->bt_adc_count == 0) || (joypad->bt_gpio_count == 0)) { ++ dev_err(dev, "adc key = %d, gpio key = %d error!", ++ joypad->bt_adc_count, joypad->bt_gpio_count); ++ return -EINVAL; ++ } ++ ++ error = joypad_adc_setup(dev, joypad); ++ if (error) ++ return error; ++ ++ error = joypad_gpio_setup(dev, joypad); ++ if (error) ++ return error; ++ ++ return error; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_probe(struct platform_device *pdev) ++{ ++ struct joypad *joypad; ++ struct device *dev = &pdev->dev; ++ int error; ++ ++ joypad = devm_kzalloc(dev, sizeof(struct joypad), GFP_KERNEL); ++ if (!joypad) { ++ dev_err(dev, "joypad devm_kzmalloc error!"); ++ return -ENOMEM; ++ } ++ ++ /* device tree data parse */ ++ error = joypad_dt_parse(dev, joypad); ++ if (error) { ++ dev_err(dev, "dt parse error!(err = %d)\n", error); ++ return error; ++ } ++ ++ mutex_init(&joypad->lock); ++ platform_set_drvdata(pdev, joypad); ++ ++ error = sysfs_create_group(&pdev->dev.kobj, &joypad_attr_group); ++ if (error) { ++ dev_err(dev, "create sysfs group fail, error: %d\n", ++ error); ++ return error; ++ } ++ ++ /* poll input device setup */ ++ error = joypad_input_setup(dev, joypad); ++ if (error) { ++ dev_err(dev, "input setup failed!(err = %d)\n", error); ++ return error; ++ } ++ dev_info(dev, "%s : probe success\n", __func__); ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static const struct of_device_id joypad_of_match[] = { ++ { .compatible = "odroidgo2-v11-joypad", }, ++ {}, ++}; ++ ++MODULE_DEVICE_TABLE(of, joypad_of_match); ++ ++/*----------------------------------------------------------------------------*/ ++static struct platform_driver joypad_driver = { ++ .probe = joypad_probe, ++ .driver = { ++ .name = DRV_NAME, ++ .of_match_table = of_match_ptr(joypad_of_match), ++ }, ++}; ++ ++/*----------------------------------------------------------------------------*/ ++static int __init joypad_init(void) ++{ ++ return platform_driver_register(&joypad_driver); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void __exit joypad_exit(void) ++{ ++ platform_driver_unregister(&joypad_driver); ++} ++ ++/*----------------------------------------------------------------------------*/ ++late_initcall(joypad_init); ++module_exit(joypad_exit); ++ ++/*----------------------------------------------------------------------------*/ ++MODULE_AUTHOR("Hardkernel Co.,LTD"); ++MODULE_DESCRIPTION("Keypad driver(ADC&GPIO) for ODROIDGO-Advance"); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:" DRV_NAME); ++ ++/*----------------------------------------------------------------------------*/ +diff --git a/drivers/input/joystick/odroidgo3-joypad.c b/drivers/input/joystick/odroidgo3-joypad.c +new file mode 100644 +index 000000000000..34f182175bcd +--- /dev/null ++++ b/drivers/input/joystick/odroidgo3-joypad.c +@@ -0,0 +1,1112 @@ ++/* ++ * SARADC joystick & GPIO Button driver for Linux(Hardkernel ODROIDGO2-Advance) ++ */ ++/* ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * Should you need to contact me, the author, you can do so either by ++ * e-mail - mail your message to , or by paper mail: ++ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic ++ */ ++ ++/*----------------------------------------------------------------------------*/ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/*----------------------------------------------------------------------------*/ ++#define DRV_NAME "odroidgo3_joypad" ++ ++/*----------------------------------------------------------------------------*/ ++#define ADC_MAX_VOLTAGE 1800 ++#define ADC_DATA_TUNING(x, p) ((x * p) / 100) ++#define ADC_TUNING_DEFAULT 180 ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ +--------------------------------+ ++ | IIO Channel : ADC_IN1 | ++ +--------------+-----------------+-----------------+--------+---------+ ++ | EN(GPIO3.B5) | SEL_A(GPIO3.B3) | SEL_B(GPIO3.B0) | SELECT | EVENT | ++ +--------------+-----------------+-----------------+--------+---------+ ++ | 0 | 0 | 0 | R-Y | ABS_RY | ++ +--------------+-----------------+-----------------+--------+---------+ ++ | 0 | 0 | 1 | R-X | ABS_RX | ++ +--------------+-----------------+-----------------+--------+---------+ ++ | 0 | 1 | 0 | L-Y | ABS_Y | ++ +--------------+-----------------+-----------------+--------+---------+ ++ | 0 | 1 | 1 | L-X | ABS_X | ++ +--------------+-----------------+-----------------+--------+---------+ ++ | 1 | X | X | XXXX | ++ +--------------+-----------------+-----------------+--------+ ++*/ ++/*----------------------------------------------------------------------------*/ ++struct bt_adc { ++ /* report value (mV) */ ++ int value; ++ /* report type */ ++ int report_type; ++ /* input device init value (mV) */ ++ int max, min; ++ /* calibrated adc value */ ++ int cal; ++ /* adc scale value */ ++ int scale; ++ /* invert report */ ++ bool invert; ++ /* amux channel */ ++ int amux_ch; ++ /* adc data tuning value([percent), p = positive, n = negative */ ++ int tuning_p, tuning_n; ++}; ++ ++struct analog_mux { ++ /* IIO ADC Channel : amux connect channel */ ++ struct iio_channel *iio_ch; ++ /* analog mux select(a,b) gpio */ ++ int sel_a_gpio, sel_b_gpio; ++ /* analog mux enable gpio */ ++ int en_gpio; ++}; ++ ++struct bt_gpio { ++ /* GPIO Request label */ ++ const char *label; ++ /* GPIO Number */ ++ int num; ++ /* report type */ ++ int report_type; ++ /* report linux code */ ++ int linux_code; ++ /* prev button value */ ++ bool old_value; ++ /* button press level */ ++ bool active_level; ++}; ++ ++struct joypad { ++ struct device *dev; ++ int poll_interval; ++ ++ /* report enable/disable */ ++ bool enable; ++ ++ /* analog mux & joystick control */ ++ struct analog_mux *amux; ++ /* analog mux max count */ ++ int amux_count; ++ /* analog button */ ++ struct bt_adc *adcs; ++ ++ /* report reference point */ ++ bool invert_absx; ++ bool invert_absy; ++ bool invert_absrx; ++ bool invert_absry; ++ ++ /* report interval (ms) */ ++ int bt_gpio_count; ++ struct bt_gpio *gpios; ++ ++ /* button auto repeat */ ++ int auto_repeat; ++ ++ /* report threshold (mV) */ ++ int bt_adc_fuzz, bt_adc_flat; ++ /* adc read value scale */ ++ int bt_adc_scale; ++ /* joystick deadzone control */ ++ int bt_adc_deadzone; ++ ++ struct mutex lock; ++ ++ /* amux debug channel */ ++ int debug_ch; ++}; ++ ++/*----------------------------------------------------------------------------*/ ++// ++// set to the value in the boot.ini file. (if exist) ++// ++/*----------------------------------------------------------------------------*/ ++static unsigned int g_button_adc_fuzz = 0; ++static unsigned int g_button_adc_flat = 0; ++static unsigned int g_button_adc_scale = 0; ++static unsigned int g_button_adc_deadzone = 0; ++ ++static int button_adc_fuzz(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_fuzz = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-fuzz=", button_adc_fuzz); ++ ++static int button_adc_flat(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_flat = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-flat=", button_adc_flat); ++ ++static int button_adc_scale(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_scale = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-scale=", button_adc_scale); ++ ++static int button_adc_deadzone(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_deadzone = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-deadzone=", button_adc_deadzone); ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++static int joypad_amux_select(struct analog_mux *amux, int channel) ++{ ++ /* select mux channel */ ++ gpio_set_value(amux->en_gpio, 0); ++ ++ switch(channel) { ++ case 0: /* EVENT (ABS_RY) */ ++ gpio_set_value(amux->sel_a_gpio, 0); ++ gpio_set_value(amux->sel_b_gpio, 0); ++ break; ++ case 1: /* EVENT (ABS_RX) */ ++ gpio_set_value(amux->sel_a_gpio, 0); ++ gpio_set_value(amux->sel_b_gpio, 1); ++ break; ++ case 2: /* EVENT (ABS_Y) */ ++ gpio_set_value(amux->sel_a_gpio, 1); ++ gpio_set_value(amux->sel_b_gpio, 0); ++ break; ++ case 3: /* EVENT (ABS_X) */ ++ gpio_set_value(amux->sel_a_gpio, 1); ++ gpio_set_value(amux->sel_b_gpio, 1); ++ break; ++ default: ++ /* amux disanle */ ++ gpio_set_value(amux->en_gpio, 1); ++ return -1; ++ } ++ /* mux swtiching speed : 35ns(on) / 9ns(off) */ ++ usleep_range(1, 2); ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_adc_read(struct analog_mux *amux, struct bt_adc *adc) ++{ ++ int value; ++ ++ if (joypad_amux_select(amux, adc->amux_ch)) ++ return 0; ++ ++ if (iio_read_channel_processed(amux->iio_ch, &value)) ++ return 0; ++ ++ value *= adc->scale; ++ ++ return value; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/odroidgo2_joypad/poll_interval [rw] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_poll_interval(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ mutex_lock(&joypad->lock); ++ joypad->poll_interval = simple_strtoul(buf, NULL, 10); ++ mutex_unlock(&joypad->lock); ++ ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_poll_interval(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->poll_interval); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(poll_interval, S_IWUSR | S_IRUGO, ++ joypad_show_poll_interval, ++ joypad_store_poll_interval); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/odroidgo2_joypad/adc_fuzz [r] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_adc_fuzz(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->bt_adc_fuzz); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(adc_fuzz, S_IWUSR | S_IRUGO, ++ joypad_show_adc_fuzz, ++ NULL); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/odroidgo2_joypad/adc_flat [r] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_adc_flat(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->bt_adc_flat); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(adc_flat, S_IWUSR | S_IRUGO, ++ joypad_show_adc_flat, ++ NULL); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/odroidgo2_joypad/enable [rw] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_enable(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ mutex_lock(&joypad->lock); ++ joypad->enable = simple_strtoul(buf, NULL, 10); ++ mutex_unlock(&joypad->lock); ++ ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_enable(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->enable); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO, ++ joypad_show_enable, ++ joypad_store_enable); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/odroidgo2_joypad/adc_cal [rw] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_adc_cal(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ bool calibration; ++ ++ calibration = simple_strtoul(buf, NULL, 10); ++ ++ if (calibration) { ++ int nbtn; ++ ++ mutex_lock(&joypad->lock); ++ for (nbtn = 0; nbtn < joypad->amux_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ ++ adc->value = joypad_adc_read(joypad->amux, adc); ++ if (!adc->value) { ++ dev_err(joypad->dev, "%s : saradc channels[%d]!\n", ++ __func__, nbtn); ++ continue; ++ } ++ adc->cal = adc->value; ++ } ++ mutex_unlock(&joypad->lock); ++ } ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_adc_cal(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ int nbtn; ++ ssize_t pos; ++ ++ for (nbtn = 0, pos = 0; nbtn < joypad->amux_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ pos += sprintf(&buf[pos], "adc[%d]->cal = %d\n", ++ nbtn, adc->cal); ++ } ++ pos += sprintf(&buf[pos], "adc scale = %d\n", joypad->bt_adc_scale); ++ return pos; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(adc_cal, S_IWUSR | S_IRUGO, ++ joypad_show_adc_cal, ++ joypad_store_adc_cal); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/odroidgo2_joypad/amux_debug [rw] ++ * ++ * echo [debug channel] > amux_debug ++ * cat amux_debug : debug channel mux set & adc read ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_amux_debug(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ joypad->debug_ch = simple_strtoul(buf, NULL, 10); ++ ++ /* if error than default setting(debug_ch = 0) */ ++ if (joypad->debug_ch > joypad->amux_count) ++ joypad->debug_ch = 0; ++ ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_amux_debug(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ struct analog_mux *amux = joypad->amux; ++ ssize_t pos; ++ int value; ++ ++ mutex_lock(&joypad->lock); ++ ++ /* disable poll driver */ ++ if (joypad->enable) ++ joypad->enable = false; ++ ++ if (joypad_amux_select(amux, joypad->debug_ch)) ++ goto err_out; ++ ++ if (iio_read_channel_processed(amux->iio_ch, &value)) ++ goto err_out; ++ ++ pos = sprintf(buf, "amux ch[%d], adc scale = %d, adc value = %d\n", ++ joypad->debug_ch, joypad->bt_adc_scale, ++ value * joypad->bt_adc_scale); ++ goto out; ++ ++err_out: ++ pos = sprintf(buf, "error : amux setup & adc read!\n"); ++out: ++ mutex_unlock(&joypad->lock); ++ return pos; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(amux_debug, S_IWUSR | S_IRUGO, ++ joypad_show_amux_debug, ++ joypad_store_amux_debug); ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++static struct attribute *joypad_attrs[] = { ++ &dev_attr_poll_interval.attr, ++ &dev_attr_adc_fuzz.attr, ++ &dev_attr_adc_flat.attr, ++ &dev_attr_enable.attr, ++ &dev_attr_adc_cal.attr, ++ &dev_attr_amux_debug.attr, ++ NULL, ++}; ++ ++static struct attribute_group joypad_attr_group = { ++ .attrs = joypad_attrs, ++}; ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++static void joypad_gpio_check(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ int nbtn, value; ++ ++ for (nbtn = 0; nbtn < joypad->bt_gpio_count; nbtn++) { ++ struct bt_gpio *gpio = &joypad->gpios[nbtn]; ++ ++ if (gpio_get_value_cansleep(gpio->num) < 0) { ++ dev_err(joypad->dev, "failed to get gpio state\n"); ++ continue; ++ } ++ value = gpio_get_value(gpio->num); ++ if (value != gpio->old_value) { ++ input_event(poll_dev->input, ++ gpio->report_type, ++ gpio->linux_code, ++ (value == gpio->active_level) ? 1 : 0); ++ gpio->old_value = value; ++ } ++ } ++ input_sync(poll_dev->input); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_adc_check(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ int nbtn; ++ ++ for (nbtn = 0; nbtn < joypad->amux_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ ++ adc->value = joypad_adc_read(joypad->amux, adc); ++ if (!adc->value) { ++ dev_err(joypad->dev, "%s : saradc channels[%d]!\n", ++ __func__, nbtn); ++ continue; ++ } ++ adc->value = adc->value - adc->cal; ++ ++ /* Joystick Deadzone check */ ++ if (joypad->bt_adc_deadzone) { ++ if (abs(adc->value) < joypad->bt_adc_deadzone) ++ adc->value = 0; ++ } ++ ++ /* adc data tuning */ ++ if (adc->tuning_n && adc->value < 0) ++ adc->value = ADC_DATA_TUNING(adc->value, adc->tuning_n); ++ if (adc->tuning_p && adc->value > 0) ++ adc->value = ADC_DATA_TUNING(adc->value, adc->tuning_p); ++ ++ adc->value = adc->value > adc->max ? adc->max : adc->value; ++ adc->value = adc->value < adc->min ? adc->min : adc->value; ++ ++ input_report_abs(poll_dev->input, ++ adc->report_type, ++ adc->invert ? adc->value * (-1) : adc->value); ++ } ++ input_sync(poll_dev->input); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_poll(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ ++ if (joypad->enable) { ++ joypad_adc_check(poll_dev); ++ joypad_gpio_check(poll_dev); ++ } ++ if (poll_dev->poll_interval != joypad->poll_interval) { ++ mutex_lock(&joypad->lock); ++ poll_dev->poll_interval = joypad->poll_interval; ++ mutex_unlock(&joypad->lock); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_open(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ int nbtn; ++ ++ for (nbtn = 0; nbtn < joypad->bt_gpio_count; nbtn++) { ++ struct bt_gpio *gpio = &joypad->gpios[nbtn]; ++ gpio->old_value = gpio->active_level ? 0 : 1; ++ } ++ for (nbtn = 0; nbtn < joypad->amux_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ ++ adc->value = joypad_adc_read(joypad->amux, adc); ++ if (!adc->value) { ++ dev_err(joypad->dev, "%s : saradc channels[%d]!\n", ++ __func__, nbtn); ++ continue; ++ } ++ adc->cal = adc->value; ++ dev_info(joypad->dev, "%s : adc[%d] adc->cal = %d\n", ++ __func__, nbtn, adc->cal); ++ } ++ /* buttons status sync */ ++ joypad_adc_check(poll_dev); ++ joypad_gpio_check(poll_dev); ++ ++ /* button report enable */ ++ mutex_lock(&joypad->lock); ++ joypad->enable = true; ++ mutex_unlock(&joypad->lock); ++ ++ dev_info(joypad->dev, "%s : opened\n", __func__); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_close(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ ++ /* button report disable */ ++ mutex_lock(&joypad->lock); ++ joypad->enable = false; ++ mutex_unlock(&joypad->lock); ++ ++ dev_info(joypad->dev, "%s : closed\n", __func__); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_amux_setup(struct device *dev, struct joypad *joypad) ++{ ++ struct analog_mux *amux; ++ enum iio_chan_type type; ++ enum of_gpio_flags flags; ++ int ret; ++ ++ /* analog mux control struct init */ ++ joypad->amux = devm_kzalloc(dev, sizeof(struct analog_mux), ++ GFP_KERNEL); ++ if (!joypad->amux) { ++ dev_err(dev, "%s amux devm_kzmalloc error!", __func__); ++ return -ENOMEM; ++ } ++ amux = joypad->amux; ++ amux->iio_ch = devm_iio_channel_get(dev, "amux_adc"); ++ if (IS_ERR(amux->iio_ch)) { ++ dev_err(dev, "iio channel get error\n"); ++ return -EINVAL; ++ } ++ if (!amux->iio_ch->indio_dev) ++ return -ENXIO; ++ ++ if (iio_get_channel_type(amux->iio_ch, &type)) ++ return -EINVAL; ++ ++ if (type != IIO_VOLTAGE) { ++ dev_err(dev, "Incompatible channel type %d\n", type); ++ return -EINVAL; ++ } ++ ++ amux->sel_a_gpio = of_get_named_gpio_flags(dev->of_node, ++ "amux-a-gpios", 0, &flags); ++ if (gpio_is_valid(amux->sel_a_gpio)) { ++ ret = devm_gpio_request(dev, amux->sel_a_gpio, "amux-sel-a"); ++ if (ret < 0) { ++ dev_err(dev, "%s : failed to request amux-sel-a %d\n", ++ __func__, amux->sel_a_gpio); ++ goto err_out; ++ } ++ ret = gpio_direction_output(amux->sel_a_gpio, 0); ++ if (ret < 0) ++ goto err_out; ++ } ++ ++ amux->sel_b_gpio = of_get_named_gpio_flags(dev->of_node, ++ "amux-b-gpios", 0, &flags); ++ if (gpio_is_valid(amux->sel_b_gpio)) { ++ ret = devm_gpio_request(dev, amux->sel_b_gpio, "amux-sel-b"); ++ if (ret < 0) { ++ dev_err(dev, "%s : failed to request amux-sel-b %d\n", ++ __func__, amux->sel_b_gpio); ++ goto err_out; ++ } ++ ret = gpio_direction_output(amux->sel_b_gpio, 0); ++ if (ret < 0) ++ goto err_out; ++ } ++ ++ amux->en_gpio = of_get_named_gpio_flags(dev->of_node, ++ "amux-en-gpios", 0, &flags); ++ if (gpio_is_valid(amux->en_gpio)) { ++ ret = devm_gpio_request(dev, amux->en_gpio, "amux-en"); ++ if (ret < 0) { ++ dev_err(dev, "%s : failed to request amux-en %d\n", ++ __func__, amux->en_gpio); ++ goto err_out; ++ } ++ ret = gpio_direction_output(amux->en_gpio, 0); ++ if (ret < 0) ++ goto err_out; ++ } ++ return 0; ++err_out: ++ return ret; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_adc_setup(struct device *dev, struct joypad *joypad) ++{ ++ int nbtn; ++ ++ /* adc button struct init */ ++ joypad->adcs = devm_kzalloc(dev, joypad->amux_count * ++ sizeof(struct bt_adc), GFP_KERNEL); ++ if (!joypad->adcs) { ++ dev_err(dev, "%s devm_kzmalloc error!", __func__); ++ return -ENOMEM; ++ } ++ ++ for (nbtn = 0; nbtn < joypad->amux_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ ++ adc->scale = joypad->bt_adc_scale; ++ ++ adc->max = (ADC_MAX_VOLTAGE / 2); ++ adc->min = (ADC_MAX_VOLTAGE / 2) * (-1); ++ if (adc->scale) { ++ adc->max *= adc->scale; ++ adc->min *= adc->scale; ++ } ++ adc->amux_ch = nbtn; ++ adc->invert = false; ++ ++ switch (nbtn) { ++ case 0: ++ if (joypad->invert_absry) ++ adc->invert = true; ++ adc->report_type = ABS_RY; ++ if (device_property_read_u32(dev, ++ "abs_ry-p-tuning", ++ &adc->tuning_p)) ++ adc->tuning_p = ADC_TUNING_DEFAULT; ++ if (device_property_read_u32(dev, ++ "abs_ry-n-tuning", ++ &adc->tuning_n)) ++ adc->tuning_n = ADC_TUNING_DEFAULT; ++ break; ++ case 1: ++ if (joypad->invert_absrx) ++ adc->invert = true; ++ adc->report_type = ABS_RX; ++ if (device_property_read_u32(dev, ++ "abs_rx-p-tuning", ++ &adc->tuning_p)) ++ adc->tuning_p = ADC_TUNING_DEFAULT; ++ if (device_property_read_u32(dev, ++ "abs_rx-n-tuning", ++ &adc->tuning_n)) ++ adc->tuning_n = ADC_TUNING_DEFAULT; ++ break; ++ case 2: ++ if (joypad->invert_absy) ++ adc->invert = true; ++ adc->report_type = ABS_Y; ++ if (device_property_read_u32(dev, ++ "abs_y-p-tuning", ++ &adc->tuning_p)) ++ adc->tuning_p = ADC_TUNING_DEFAULT; ++ if (device_property_read_u32(dev, ++ "abs_y-n-tuning", ++ &adc->tuning_n)) ++ adc->tuning_n = ADC_TUNING_DEFAULT; ++ break; ++ case 3: ++ if (joypad->invert_absx) ++ adc->invert = true; ++ adc->report_type = ABS_X; ++ if (device_property_read_u32(dev, ++ "abs_x-p-tuning", ++ &adc->tuning_p)) ++ adc->tuning_p = ADC_TUNING_DEFAULT; ++ if (device_property_read_u32(dev, ++ "abs_x-n-tuning", ++ &adc->tuning_n)) ++ adc->tuning_n = ADC_TUNING_DEFAULT; ++ break; ++ default : ++ dev_err(dev, "%s amux count(%d) error!", ++ __func__, nbtn); ++ return -EINVAL; ++ } ++ } ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_gpio_setup(struct device *dev, struct joypad *joypad) ++{ ++ struct device_node *node, *pp; ++ int nbtn; ++ ++ node = dev->of_node; ++ if (!node) ++ return -ENODEV; ++ ++ joypad->gpios = devm_kzalloc(dev, joypad->bt_gpio_count * ++ sizeof(struct bt_gpio), GFP_KERNEL); ++ ++ if (!joypad->gpios) { ++ dev_err(dev, "%s devm_kzmalloc error!", __func__); ++ return -ENOMEM; ++ } ++ ++ nbtn = 0; ++ for_each_child_of_node(node, pp) { ++ enum of_gpio_flags flags; ++ struct bt_gpio *gpio = &joypad->gpios[nbtn++]; ++ int error; ++ ++ gpio->num = of_get_gpio_flags(pp, 0, &flags); ++ if (gpio->num < 0) { ++ error = gpio->num; ++ dev_err(dev, "Failed to get gpio flags, error: %d\n", ++ error); ++ return error; ++ } ++ ++ /* gpio active level(key press level) */ ++ gpio->active_level = (flags & OF_GPIO_ACTIVE_LOW) ? 0 : 1; ++ ++ gpio->label = of_get_property(pp, "label", NULL); ++ ++ if (gpio_is_valid(gpio->num)) { ++ error = devm_gpio_request_one(dev, gpio->num, ++ GPIOF_IN, gpio->label); ++ if (error < 0) { ++ dev_err(dev, ++ "Failed to request GPIO %d, error %d\n", ++ gpio->num, error); ++ return error; ++ } ++ } ++ if (of_property_read_u32(pp, "linux,code", &gpio->linux_code)) { ++ dev_err(dev, "Button without keycode: 0x%x\n", ++ gpio->num); ++ return -EINVAL; ++ } ++ if (of_property_read_u32(pp, "linux,input-type", ++ &gpio->report_type)) ++ gpio->report_type = EV_KEY; ++ } ++ if (nbtn == 0) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_input_setup(struct device *dev, struct joypad *joypad) ++{ ++ struct input_polled_dev *poll_dev; ++ struct input_dev *input; ++ int nbtn, error; ++ u32 joypad_revision = 0; ++ u32 joypad_product = 0; ++ ++ poll_dev = devm_input_allocate_polled_device(dev); ++ if (!poll_dev) { ++ dev_err(dev, "no memory for polled device\n"); ++ return -ENOMEM; ++ } ++ ++ poll_dev->private = joypad; ++ poll_dev->poll = joypad_poll; ++ poll_dev->poll_interval = joypad->poll_interval; ++ poll_dev->open = joypad_open; ++ poll_dev->close = joypad_close; ++ ++ input = poll_dev->input; ++ ++ device_property_read_string(dev, "joypad-name", &input->name); ++ input->phys = DRV_NAME"/input0"; ++ ++ device_property_read_u32(dev, "joypad-revision", &joypad_revision); ++ device_property_read_u32(dev, "joypad-product", &joypad_product); ++ input->id.bustype = BUS_HOST; ++ input->id.vendor = 0x0001; ++ input->id.product = (u16)joypad_product; ++ input->id.version = (u16)joypad_revision; ++ ++ /* IIO ADC key setup (0 mv ~ 1800 mv) * adc->scale */ ++ __set_bit(EV_ABS, input->evbit); ++ for(nbtn = 0; nbtn < joypad->amux_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ input_set_abs_params(input, adc->report_type, ++ adc->min, adc->max, ++ joypad->bt_adc_fuzz, ++ joypad->bt_adc_flat); ++ dev_info(dev, ++ "%s : SCALE = %d, ABS min = %d, max = %d," ++ " fuzz = %d, flat = %d, deadzone = %d\n", ++ __func__, adc->scale, adc->min, adc->max, ++ joypad->bt_adc_fuzz, joypad->bt_adc_flat, ++ joypad->bt_adc_deadzone); ++ dev_info(dev, ++ "%s : adc tuning_p = %d, adc_tuning_n = %d\n\n", ++ __func__, adc->tuning_p, adc->tuning_n); ++ } ++ ++ /* GPIO key setup */ ++ __set_bit(EV_KEY, input->evbit); ++ for(nbtn = 0; nbtn < joypad->bt_gpio_count; nbtn++) { ++ struct bt_gpio *gpio = &joypad->gpios[nbtn]; ++ input_set_capability(input, gpio->report_type, ++ gpio->linux_code); ++ } ++ ++ if (joypad->auto_repeat) ++ __set_bit(EV_REP, input->evbit); ++ ++ joypad->dev = dev; ++ ++ error = input_register_polled_device(poll_dev); ++ if (error) { ++ dev_err(dev, "unable to register polled device, err=%d\n", ++ error); ++ return error; ++ } ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_setup_value_check(struct device *dev, struct joypad *joypad) ++{ ++ /* ++ fuzz: specifies fuzz value that is used to filter noise from ++ the event stream. ++ */ ++ if (g_button_adc_fuzz) ++ joypad->bt_adc_fuzz = g_button_adc_fuzz; ++ else ++ device_property_read_u32(dev, "button-adc-fuzz", ++ &joypad->bt_adc_fuzz); ++ /* ++ flat: values that are within this value will be discarded by ++ joydev interface and reported as 0 instead. ++ */ ++ if (g_button_adc_flat) ++ joypad->bt_adc_flat = g_button_adc_flat; ++ else ++ device_property_read_u32(dev, "button-adc-flat", ++ &joypad->bt_adc_flat); ++ ++ /* Joystick report value control */ ++ if (g_button_adc_scale) ++ joypad->bt_adc_scale = g_button_adc_scale; ++ else ++ device_property_read_u32(dev, "button-adc-scale", ++ &joypad->bt_adc_scale); ++ ++ /* Joystick deadzone value control */ ++ if (g_button_adc_deadzone) ++ joypad->bt_adc_deadzone = g_button_adc_deadzone; ++ else ++ device_property_read_u32(dev, "button-adc-deadzone", ++ &joypad->bt_adc_deadzone); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_dt_parse(struct device *dev, struct joypad *joypad) ++{ ++ int error = 0; ++ ++ /* initialize value check from boot.ini */ ++ joypad_setup_value_check(dev, joypad); ++ ++ device_property_read_u32(dev, "amux-count", ++ &joypad->amux_count); ++ ++ device_property_read_u32(dev, "poll-interval", ++ &joypad->poll_interval); ++ ++ joypad->auto_repeat = device_property_present(dev, "autorepeat"); ++ ++ /* change the report reference point? (read value * -1) */ ++ joypad->invert_absx = device_property_present(dev, "invert-absx"); ++ joypad->invert_absy = device_property_present(dev, "invert-absy"); ++ joypad->invert_absrx = device_property_present(dev, "invert-absrx"); ++ joypad->invert_absry = device_property_present(dev, "invert-absry"); ++ dev_info(dev, "%s : invert-absx = %d, inveret-absy = %d, invert-absrx = %d, invert-absry = %d\n", ++ __func__, joypad->invert_absx, joypad->invert_absy, joypad->invert_absrx, joypad->invert_absry); ++ ++ joypad->bt_gpio_count = device_get_child_node_count(dev); ++ ++ if ((joypad->amux_count == 0) || (joypad->bt_gpio_count == 0)) { ++ dev_err(dev, "adc key = %d, gpio key = %d error!", ++ joypad->amux_count, joypad->bt_gpio_count); ++ return -EINVAL; ++ } ++ ++ error = joypad_adc_setup(dev, joypad); ++ if (error) ++ return error; ++ ++ error = joypad_amux_setup(dev, joypad); ++ if (error) ++ return error; ++ ++ error = joypad_gpio_setup(dev, joypad); ++ if (error) ++ return error; ++ ++ dev_info(dev, "%s : adc key cnt = %d, gpio key cnt = %d\n", ++ __func__, joypad->amux_count, joypad->bt_gpio_count); ++ ++ return error; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_probe(struct platform_device *pdev) ++{ ++ struct joypad *joypad; ++ struct device *dev = &pdev->dev; ++ int error; ++ ++ joypad = devm_kzalloc(dev, sizeof(struct joypad), GFP_KERNEL); ++ if (!joypad) { ++ dev_err(dev, "joypad devm_kzmalloc error!"); ++ return -ENOMEM; ++ } ++ ++ /* device tree data parse */ ++ error = joypad_dt_parse(dev, joypad); ++ if (error) { ++ dev_err(dev, "dt parse error!(err = %d)\n", error); ++ return error; ++ } ++ ++ mutex_init(&joypad->lock); ++ platform_set_drvdata(pdev, joypad); ++ ++ error = sysfs_create_group(&pdev->dev.kobj, &joypad_attr_group); ++ if (error) { ++ dev_err(dev, "create sysfs group fail, error: %d\n", ++ error); ++ return error; ++ } ++ ++ /* poll input device setup */ ++ error = joypad_input_setup(dev, joypad); ++ if (error) { ++ dev_err(dev, "input setup failed!(err = %d)\n", error); ++ return error; ++ } ++ dev_info(dev, "%s : probe success\n", __func__); ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static const struct of_device_id joypad_of_match[] = { ++ { .compatible = "odroidgo3-joypad", }, ++ {}, ++}; ++ ++MODULE_DEVICE_TABLE(of, joypad_of_match); ++ ++/*----------------------------------------------------------------------------*/ ++static struct platform_driver joypad_driver = { ++ .probe = joypad_probe, ++ .driver = { ++ .name = DRV_NAME, ++ .of_match_table = of_match_ptr(joypad_of_match), ++ }, ++}; ++ ++/*----------------------------------------------------------------------------*/ ++static int __init joypad_init(void) ++{ ++ return platform_driver_register(&joypad_driver); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void __exit joypad_exit(void) ++{ ++ platform_driver_unregister(&joypad_driver); ++} ++ ++/*----------------------------------------------------------------------------*/ ++late_initcall(joypad_init); ++module_exit(joypad_exit); ++ ++/*----------------------------------------------------------------------------*/ ++MODULE_AUTHOR("Hardkernel Co.,LTD"); ++MODULE_DESCRIPTION("Keypad driver(ADC&GPIO) for ODROIDGO-Advance"); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:" DRV_NAME); ++ ++/*----------------------------------------------------------------------------*/ +diff --git a/drivers/input/joystick/rgb20s-joypad.c b/drivers/input/joystick/rgb20s-joypad.c +new file mode 100644 +index 000000000000..a52981eee9fb +--- /dev/null ++++ b/drivers/input/joystick/rgb20s-joypad.c +@@ -0,0 +1,1373 @@ ++/* ++ * SARADC joystick & GPIO Button driver for Linux(Powkiddy RGB20S) ++ */ ++/* ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * Should you need to contact me, the author, you can do so either by ++ * e-mail - mail your message to , or by paper mail: ++ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic ++ */ ++ ++/*----------------------------------------------------------------------------*/ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/*----------------------------------------------------------------------------*/ ++#define DRV_NAME "rgb20s_joypad" ++ ++/*----------------------------------------------------------------------------*/ ++#define ADC_MAX_VOLTAGE 1800 ++#define ADC_DATA_TUNING(x, p) ((x * p) / 100) ++#define ADC_TUNING_DEFAULT 180 ++#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ +--------------------------------+ ++ | IIO Channel : ADC_IN1 | ++ +--------------+-----------------+-----------------+--------+---------+ ++ | EN(GPIO3.B5) | SEL_A(GPIO3.B3) | SEL_B(GPIO3.B0) | SELECT | EVENT | ++ +--------------+-----------------+-----------------+--------+---------+ ++ | 0 | 0 | 0 | R-Y | ABS_RY | ++ +--------------+-----------------+-----------------+--------+---------+ ++ | 0 | 0 | 1 | R-X | ABS_RX | ++ +--------------+-----------------+-----------------+--------+---------+ ++ | 0 | 1 | 0 | L-Y | ABS_Y | ++ +--------------+-----------------+-----------------+--------+---------+ ++ | 0 | 1 | 1 | L-X | ABS_X | ++ +--------------+-----------------+-----------------+--------+---------+ ++ | 1 | X | X | XXXX | ++ +--------------+-----------------+-----------------+--------+ ++*/ ++/*----------------------------------------------------------------------------*/ ++struct bt_adc { ++ /* report value (mV) */ ++ int value; ++ /* report type */ ++ int report_type; ++ /* input device init value (mV) */ ++ int max, min; ++ /* calibrated adc value */ ++ int cal; ++ /* adc scale value */ ++ int scale; ++ /* invert report */ ++ bool invert; ++ /* amux channel */ ++ int amux_ch; ++ /* adc data tuning value([percent), p = positive, n = negative */ ++ int tuning_p, tuning_n; ++}; ++ ++struct analog_mux { ++ /* IIO ADC Channel : amux connect channel */ ++ struct iio_channel *iio_ch; ++ /* analog mux select(a,b) gpio */ ++ int sel_a_gpio, sel_b_gpio; ++ /* analog mux enable gpio */ ++ int en_gpio; ++}; ++ ++struct bt_gpio { ++ /* GPIO Request label */ ++ const char *label; ++ /* GPIO Number */ ++ int num; ++ /* report type */ ++ int report_type; ++ /* report linux code */ ++ int linux_code; ++ /* prev button value */ ++ bool old_value; ++ /* button press level */ ++ bool active_level; ++}; ++ ++struct joypad { ++ struct device *dev; ++ int poll_interval; ++ ++ /* report enable/disable */ ++ bool enable; ++ ++ /* analog mux & joystick control */ ++ struct analog_mux *amux; ++ /* analog mux max count */ ++ int amux_count; ++ /* analog button */ ++ struct bt_adc *adcs; ++ ++ /* report reference point */ ++ bool invert_absx; ++ bool invert_absy; ++ bool invert_absrx; ++ bool invert_absry; ++ ++ /* report interval (ms) */ ++ int bt_gpio_count; ++ struct bt_gpio *gpios; ++ ++ /* button auto repeat */ ++ int auto_repeat; ++ ++ /* report threshold (mV) */ ++ int bt_adc_fuzz, bt_adc_flat; ++ /* adc read value scale */ ++ int bt_adc_scale; ++ /* joystick deadzone control */ ++ int bt_adc_deadzone; ++ ++ struct mutex lock; ++ ++ /* amux debug channel */ ++ int debug_ch; ++ ++ /* pwm device for rumble*/ ++ struct input_dev *input; ++ struct pwm_device *pwm; ++ struct work_struct play_work; ++ u16 level; ++ u16 boost_weak; ++ u16 boost_strong; ++}; ++ ++static int pwm_vibrator_start(struct joypad *joypad) ++{ ++ struct device *pdev = joypad->input->dev.parent; ++ struct pwm_state state; ++ int err; ++ ++ pwm_get_state(joypad->pwm, &state); ++ pwm_set_relative_duty_cycle(&state, joypad->level, 0xffff); ++ state.enabled = true; ++ ++ err = pwm_apply_might_sleep(joypad->pwm, &state); ++ if (err) { ++ dev_err(pdev, "failed to apply pwm state: %d", err); ++ return err; ++ } ++ ++ return 0; ++} ++ ++static void pwm_vibrator_stop(struct joypad *joypad) ++{ ++ pwm_disable(joypad->pwm); ++} ++ ++static void pwm_vibrator_play_work(struct work_struct *work) ++{ ++ struct joypad *joypad = container_of(work, ++ struct joypad, play_work); ++ ++ if (joypad->level) ++ pwm_vibrator_start(joypad); ++ else ++ pwm_vibrator_stop(joypad); ++} ++ ++ ++/*----------------------------------------------------------------------------*/ ++// ++// set to the value in the boot.ini file. (if exist) ++// ++/*----------------------------------------------------------------------------*/ ++static unsigned int g_button_adc_fuzz = 0; ++static unsigned int g_button_adc_flat = 0; ++static unsigned int g_button_adc_scale = 0; ++static unsigned int g_button_adc_deadzone = 0; ++ ++static int button_adc_fuzz(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_fuzz = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-fuzz=", button_adc_fuzz); ++ ++static int button_adc_flat(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_flat = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-flat=", button_adc_flat); ++ ++static int button_adc_scale(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_scale = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-scale=", button_adc_scale); ++ ++static int button_adc_deadzone(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_deadzone = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-deadzone=", button_adc_deadzone); ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++static int joypad_amux_select(struct analog_mux *amux, int channel) ++{ ++ /* select mux channel */ ++ gpio_set_value(amux->en_gpio, 0); ++ ++ switch(channel) { ++ case 0: /* EVENT (ABS_RY) */ ++ gpio_set_value(amux->sel_a_gpio, 0); ++ gpio_set_value(amux->sel_b_gpio, 0); ++ break; ++ case 1: /* EVENT (ABS_RX) */ ++ gpio_set_value(amux->sel_a_gpio, 0); ++ gpio_set_value(amux->sel_b_gpio, 1); ++ break; ++ case 2: /* EVENT (ABS_Y) */ ++ gpio_set_value(amux->sel_a_gpio, 1); ++ gpio_set_value(amux->sel_b_gpio, 0); ++ break; ++ case 3: /* EVENT (ABS_X) */ ++ gpio_set_value(amux->sel_a_gpio, 1); ++ gpio_set_value(amux->sel_b_gpio, 1); ++ break; ++ default: ++ /* amux disanle */ ++ gpio_set_value(amux->en_gpio, 1); ++ return -1; ++ } ++ /* mux swtiching speed : 35ns(on) / 9ns(off) */ ++ usleep_range(1, 2); ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_adc_read(struct analog_mux *amux, struct bt_adc *adc) ++{ ++ int value; ++ ++ if (joypad_amux_select(amux, adc->amux_ch)) ++ return 0; ++ ++ if (iio_read_channel_processed(amux->iio_ch, &value)) ++ return 0; ++ ++ value *= adc->scale; ++ ++ return value; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/rgb20s_joypad/poll_interval [rw] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_poll_interval(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ mutex_lock(&joypad->lock); ++ joypad->poll_interval = simple_strtoul(buf, NULL, 10); ++ mutex_unlock(&joypad->lock); ++ ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_poll_interval(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->poll_interval); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(poll_interval, S_IWUSR | S_IRUGO, ++ joypad_show_poll_interval, ++ joypad_store_poll_interval); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/rgb20s_joypad/adc_fuzz [r] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_adc_fuzz(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->bt_adc_fuzz); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(adc_fuzz, S_IWUSR | S_IRUGO, ++ joypad_show_adc_fuzz, ++ NULL); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/rgb20s_joypad/adc_flat [r] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_adc_flat(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->bt_adc_flat); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(adc_flat, S_IWUSR | S_IRUGO, ++ joypad_show_adc_flat, ++ NULL); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/rgb20s_joypad/enable [rw] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_enable(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ mutex_lock(&joypad->lock); ++ joypad->enable = simple_strtoul(buf, NULL, 10); ++ mutex_unlock(&joypad->lock); ++ ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_enable(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->enable); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO, ++ joypad_show_enable, ++ joypad_store_enable); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/rgb20s_joypad/adc_cal [rw] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_adc_cal(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ bool calibration; ++ ++ calibration = simple_strtoul(buf, NULL, 10); ++ ++ if (calibration) { ++ int nbtn; ++ ++ mutex_lock(&joypad->lock); ++ for (nbtn = 0; nbtn < joypad->amux_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ ++ adc->value = joypad_adc_read(joypad->amux, adc); ++ if (!adc->value) { ++ dev_err(joypad->dev, "%s : saradc channels[%d]!\n", ++ __func__, nbtn); ++ continue; ++ } ++ adc->cal = adc->value; ++ } ++ mutex_unlock(&joypad->lock); ++ } ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_adc_cal(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ int nbtn; ++ ssize_t pos; ++ ++ for (nbtn = 0, pos = 0; nbtn < joypad->amux_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ pos += sprintf(&buf[pos], "adc[%d]->cal = %d\n", ++ nbtn, adc->cal); ++ } ++ pos += sprintf(&buf[pos], "adc scale = %d\n", joypad->bt_adc_scale); ++ return pos; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(adc_cal, S_IWUSR | S_IRUGO, ++ joypad_show_adc_cal, ++ joypad_store_adc_cal); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/rgb20s_joypad/amux_debug [rw] ++ * ++ * echo [debug channel] > amux_debug ++ * cat amux_debug : debug channel mux set & adc read ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_amux_debug(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ joypad->debug_ch = simple_strtoul(buf, NULL, 10); ++ ++ /* if error than default setting(debug_ch = 0) */ ++ if (joypad->debug_ch > joypad->amux_count) ++ joypad->debug_ch = 0; ++ ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_amux_debug(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ struct analog_mux *amux = joypad->amux; ++ ssize_t pos; ++ int value; ++ ++ mutex_lock(&joypad->lock); ++ ++ /* disable poll driver */ ++ if (joypad->enable) ++ joypad->enable = false; ++ ++ if (joypad_amux_select(amux, joypad->debug_ch)) ++ goto err_out; ++ ++ if (iio_read_channel_processed(amux->iio_ch, &value)) ++ goto err_out; ++ ++ pos = sprintf(buf, "amux ch[%d], adc scale = %d, adc value = %d\n", ++ joypad->debug_ch, joypad->bt_adc_scale, ++ value * joypad->bt_adc_scale); ++ goto out; ++ ++err_out: ++ pos = sprintf(buf, "error : amux setup & adc read!\n"); ++out: ++ mutex_unlock(&joypad->lock); ++ return pos; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(amux_debug, S_IWUSR | S_IRUGO, ++ joypad_show_amux_debug, ++ joypad_store_amux_debug); ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/rgb20s_joypad/rumble_period [rw] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_period(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ mutex_lock(&joypad->lock); ++ pwm_set_period(joypad->pwm, simple_strtoul(buf, NULL, 21)); ++ mutex_unlock(&joypad->lock); ++ ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_period(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", pwm_get_period(joypad->pwm)); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(rumble_period, S_IWUSR | S_IRUGO, ++ joypad_show_period, ++ joypad_store_period); ++ ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/rgb20s_joypad/rumble_boost_strong [rw] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_boost_strong(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ mutex_lock(&joypad->lock); ++ joypad->boost_strong = simple_strtoul(buf, NULL, 10); ++ mutex_unlock(&joypad->lock); ++ ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_boost_strong(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->boost_strong); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(rumble_boost_strong, S_IWUSR | S_IRUGO, ++ joypad_show_boost_strong, ++ joypad_store_boost_strong); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/rgb20s_joypad/rumble_boost_weak [rw] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_boost_weak(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ mutex_lock(&joypad->lock); ++ joypad->boost_weak = simple_strtoul(buf, NULL, 10); ++ mutex_unlock(&joypad->lock); ++ ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_boost_weak(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->boost_weak); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(rumble_boost_weak, S_IWUSR | S_IRUGO, ++ joypad_show_boost_weak, ++ joypad_store_boost_weak); ++ ++static struct attribute *joypad_attrs[] = { ++ &dev_attr_poll_interval.attr, ++ &dev_attr_adc_fuzz.attr, ++ &dev_attr_adc_flat.attr, ++ &dev_attr_enable.attr, ++ &dev_attr_adc_cal.attr, ++ &dev_attr_amux_debug.attr, ++ &dev_attr_rumble_period.attr, ++ &dev_attr_rumble_boost_strong.attr, ++ &dev_attr_rumble_boost_weak.attr, ++ NULL, ++}; ++ ++static struct attribute_group joypad_attr_group = { ++ .attrs = joypad_attrs, ++}; ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++static void joypad_gpio_check(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ int nbtn, value; ++ ++ for (nbtn = 0; nbtn < joypad->bt_gpio_count; nbtn++) { ++ struct bt_gpio *gpio = &joypad->gpios[nbtn]; ++ ++ if (gpio_get_value_cansleep(gpio->num) < 0) { ++ dev_err(joypad->dev, "failed to get gpio state\n"); ++ continue; ++ } ++ value = gpio_get_value(gpio->num); ++ if (value != gpio->old_value) { ++ input_event(poll_dev->input, ++ gpio->report_type, ++ gpio->linux_code, ++ (value == gpio->active_level) ? 1 : 0); ++ gpio->old_value = value; ++ } ++ } ++ input_sync(poll_dev->input); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_adc_check(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ int nbtn; ++ ++ for (nbtn = 0; nbtn < joypad->amux_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ ++ adc->value = joypad_adc_read(joypad->amux, adc); ++ if (!adc->value) { ++ dev_err(joypad->dev, "%s : saradc channels[%d]!\n", ++ __func__, nbtn); ++ continue; ++ } ++ adc->value = adc->value - adc->cal; ++ ++ /* Joystick Deadzone check */ ++ if (joypad->bt_adc_deadzone) { ++ if (abs(adc->value) < joypad->bt_adc_deadzone) ++ adc->value = 0; ++ } ++ ++ /* adc data tuning */ ++ if (adc->tuning_n && adc->value < 0) ++ adc->value = ADC_DATA_TUNING(adc->value, adc->tuning_n); ++ if (adc->tuning_p && adc->value > 0) ++ adc->value = ADC_DATA_TUNING(adc->value, adc->tuning_p); ++ ++ adc->value = adc->value > adc->max ? adc->max : adc->value; ++ adc->value = adc->value < adc->min ? adc->min : adc->value; ++ ++ input_report_abs(poll_dev->input, ++ adc->report_type, ++ adc->invert ? adc->value * (-1) : adc->value); ++ } ++ input_sync(poll_dev->input); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_poll(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ ++ if (joypad->enable) { ++ joypad_adc_check(poll_dev); ++ joypad_gpio_check(poll_dev); ++ } ++ if (poll_dev->poll_interval != joypad->poll_interval) { ++ mutex_lock(&joypad->lock); ++ poll_dev->poll_interval = joypad->poll_interval; ++ mutex_unlock(&joypad->lock); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_open(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ int nbtn; ++ ++ for (nbtn = 0; nbtn < joypad->bt_gpio_count; nbtn++) { ++ struct bt_gpio *gpio = &joypad->gpios[nbtn]; ++ gpio->old_value = gpio->active_level ? 0 : 1; ++ } ++ for (nbtn = 0; nbtn < joypad->amux_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ ++ adc->value = joypad_adc_read(joypad->amux, adc); ++ if (!adc->value) { ++ dev_err(joypad->dev, "%s : saradc channels[%d]!\n", ++ __func__, nbtn); ++ continue; ++ } ++ adc->cal = adc->value; ++ dev_info(joypad->dev, "%s : adc[%d] adc->cal = %d\n", ++ __func__, nbtn, adc->cal); ++ } ++ /* buttons status sync */ ++ joypad_adc_check(poll_dev); ++ joypad_gpio_check(poll_dev); ++ ++ /* button report enable */ ++ mutex_lock(&joypad->lock); ++ joypad->enable = true; ++ mutex_unlock(&joypad->lock); ++ ++ dev_info(joypad->dev, "%s : opened\n", __func__); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_close(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ ++ /* button report disable */ ++ mutex_lock(&joypad->lock); ++ joypad->enable = false; ++ mutex_unlock(&joypad->lock); ++ ++ cancel_work_sync(&joypad->play_work); ++ pwm_vibrator_stop(joypad); ++ ++ dev_info(joypad->dev, "%s : closed\n", __func__); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_amux_setup(struct device *dev, struct joypad *joypad) ++{ ++ struct analog_mux *amux; ++ enum iio_chan_type type; ++ enum of_gpio_flags flags; ++ int ret; ++ ++ /* analog mux control struct init */ ++ joypad->amux = devm_kzalloc(dev, sizeof(struct analog_mux), ++ GFP_KERNEL); ++ if (!joypad->amux) { ++ dev_err(dev, "%s amux devm_kzmalloc error!", __func__); ++ return -ENOMEM; ++ } ++ amux = joypad->amux; ++ amux->iio_ch = devm_iio_channel_get(dev, "amux_adc"); ++ if (IS_ERR(amux->iio_ch)) { ++ dev_err(dev, "iio channel get error\n"); ++ return -EINVAL; ++ } ++ if (!amux->iio_ch->indio_dev) ++ return -ENXIO; ++ ++ if (iio_get_channel_type(amux->iio_ch, &type)) ++ return -EINVAL; ++ ++ if (type != IIO_VOLTAGE) { ++ dev_err(dev, "Incompatible channel type %d\n", type); ++ return -EINVAL; ++ } ++ ++ amux->sel_a_gpio = of_get_named_gpio_flags(dev->of_node, ++ "amux-a-gpios", 0, &flags); ++ if (gpio_is_valid(amux->sel_a_gpio)) { ++ ret = devm_gpio_request(dev, amux->sel_a_gpio, "amux-sel-a"); ++ if (ret < 0) { ++ dev_err(dev, "%s : failed to request amux-sel-a %d\n", ++ __func__, amux->sel_a_gpio); ++ goto err_out; ++ } ++ ret = gpio_direction_output(amux->sel_a_gpio, 0); ++ if (ret < 0) ++ goto err_out; ++ } ++ ++ amux->sel_b_gpio = of_get_named_gpio_flags(dev->of_node, ++ "amux-b-gpios", 0, &flags); ++ if (gpio_is_valid(amux->sel_b_gpio)) { ++ ret = devm_gpio_request(dev, amux->sel_b_gpio, "amux-sel-b"); ++ if (ret < 0) { ++ dev_err(dev, "%s : failed to request amux-sel-b %d\n", ++ __func__, amux->sel_b_gpio); ++ goto err_out; ++ } ++ ret = gpio_direction_output(amux->sel_b_gpio, 0); ++ if (ret < 0) ++ goto err_out; ++ } ++ ++ amux->en_gpio = of_get_named_gpio_flags(dev->of_node, ++ "amux-en-gpios", 0, &flags); ++ if (gpio_is_valid(amux->en_gpio)) { ++ ret = devm_gpio_request(dev, amux->en_gpio, "amux-en"); ++ if (ret < 0) { ++ dev_err(dev, "%s : failed to request amux-en %d\n", ++ __func__, amux->en_gpio); ++ goto err_out; ++ } ++ ret = gpio_direction_output(amux->en_gpio, 0); ++ if (ret < 0) ++ goto err_out; ++ } ++ return 0; ++err_out: ++ return ret; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_adc_setup(struct device *dev, struct joypad *joypad) ++{ ++ int nbtn; ++ ++ /* adc button struct init */ ++ joypad->adcs = devm_kzalloc(dev, joypad->amux_count * ++ sizeof(struct bt_adc), GFP_KERNEL); ++ if (!joypad->adcs) { ++ dev_err(dev, "%s devm_kzmalloc error!", __func__); ++ return -ENOMEM; ++ } ++ ++ for (nbtn = 0; nbtn < joypad->amux_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ ++ adc->scale = joypad->bt_adc_scale; ++ ++ adc->max = (ADC_MAX_VOLTAGE / 2); ++ adc->min = (ADC_MAX_VOLTAGE / 2) * (-1); ++ if (adc->scale) { ++ adc->max *= adc->scale; ++ adc->min *= adc->scale; ++ } ++ adc->amux_ch = nbtn; ++ adc->invert = false; ++ ++ switch (nbtn) { ++ case 0: ++ if (joypad->invert_absry) ++ adc->invert = true; ++ adc->report_type = ABS_RY; ++ if (device_property_read_u32(dev, ++ "abs_ry-p-tuning", ++ &adc->tuning_p)) ++ adc->tuning_p = ADC_TUNING_DEFAULT; ++ if (device_property_read_u32(dev, ++ "abs_ry-n-tuning", ++ &adc->tuning_n)) ++ adc->tuning_n = ADC_TUNING_DEFAULT; ++ break; ++ case 1: ++ if (joypad->invert_absrx) ++ adc->invert = true; ++ adc->report_type = ABS_RX; ++ if (device_property_read_u32(dev, ++ "abs_rx-p-tuning", ++ &adc->tuning_p)) ++ adc->tuning_p = ADC_TUNING_DEFAULT; ++ if (device_property_read_u32(dev, ++ "abs_rx-n-tuning", ++ &adc->tuning_n)) ++ adc->tuning_n = ADC_TUNING_DEFAULT; ++ break; ++ case 2: ++ if (joypad->invert_absy) ++ adc->invert = true; ++ adc->report_type = ABS_Y; ++ if (device_property_read_u32(dev, ++ "abs_y-p-tuning", ++ &adc->tuning_p)) ++ adc->tuning_p = ADC_TUNING_DEFAULT; ++ if (device_property_read_u32(dev, ++ "abs_y-n-tuning", ++ &adc->tuning_n)) ++ adc->tuning_n = ADC_TUNING_DEFAULT; ++ break; ++ case 3: ++ if (joypad->invert_absx) ++ adc->invert = true; ++ adc->report_type = ABS_X; ++ if (device_property_read_u32(dev, ++ "abs_x-p-tuning", ++ &adc->tuning_p)) ++ adc->tuning_p = ADC_TUNING_DEFAULT; ++ if (device_property_read_u32(dev, ++ "abs_x-n-tuning", ++ &adc->tuning_n)) ++ adc->tuning_n = ADC_TUNING_DEFAULT; ++ break; ++ default : ++ dev_err(dev, "%s amux count(%d) error!", ++ __func__, nbtn); ++ return -EINVAL; ++ } ++ } ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_gpio_setup(struct device *dev, struct joypad *joypad) ++{ ++ struct device_node *node, *pp; ++ int nbtn; ++ ++ node = dev->of_node; ++ if (!node) ++ return -ENODEV; ++ ++ joypad->gpios = devm_kzalloc(dev, joypad->bt_gpio_count * ++ sizeof(struct bt_gpio), GFP_KERNEL); ++ ++ if (!joypad->gpios) { ++ dev_err(dev, "%s devm_kzmalloc error!", __func__); ++ return -ENOMEM; ++ } ++ ++ nbtn = 0; ++ for_each_child_of_node(node, pp) { ++ enum of_gpio_flags flags; ++ struct bt_gpio *gpio = &joypad->gpios[nbtn++]; ++ int error; ++ ++ gpio->num = of_get_gpio_flags(pp, 0, &flags); ++ if (gpio->num < 0) { ++ error = gpio->num; ++ dev_err(dev, "Failed to get gpio flags, error: %d\n", ++ error); ++ return error; ++ } ++ ++ /* gpio active level(key press level) */ ++ gpio->active_level = (flags & OF_GPIO_ACTIVE_LOW) ? 0 : 1; ++ ++ gpio->label = of_get_property(pp, "label", NULL); ++ ++ if (gpio_is_valid(gpio->num)) { ++ error = devm_gpio_request_one(dev, gpio->num, ++ GPIOF_IN, gpio->label); ++ if (error < 0) { ++ dev_err(dev, ++ "Failed to request GPIO %d, error %d\n", ++ gpio->num, error); ++ return error; ++ } ++ } ++ if (of_property_read_u32(pp, "linux,code", &gpio->linux_code)) { ++ dev_err(dev, "Button without keycode: 0x%x\n", ++ gpio->num); ++ return -EINVAL; ++ } ++ if (of_property_read_u32(pp, "linux,input-type", ++ &gpio->report_type)) ++ gpio->report_type = EV_KEY; ++ } ++ if (nbtn == 0) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++static int rumble_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect) ++{ ++ struct joypad *joypad = data; ++ u32 boosted_level; ++ if (effect->type != FF_RUMBLE) ++ return 0; ++ ++ if (effect->u.rumble.strong_magnitude) ++ boosted_level = effect->u.rumble.strong_magnitude + joypad->boost_strong; ++ else ++ boosted_level = effect->u.rumble.weak_magnitude + joypad->boost_weak; ++ ++ joypad->level = (u16)CLAMP(boosted_level, 0, 0xffff); ++ ++ dev_info(joypad->dev,"joypad->level = %d", joypad->level); ++ schedule_work(&joypad->play_work); ++ return 0; ++} ++/*----------------------------------------------------------------------------*/ ++static int joypad_rumble_setup(struct device *dev, struct joypad *joypad) ++{ ++ int err; ++ struct pwm_state state; ++ ++ joypad->pwm = devm_pwm_get(dev, "enable"); ++ if (IS_ERR(joypad->pwm)) ++ { ++ dev_err(dev, "rumble get error\n"); ++ return -EINVAL; ++ } ++ ++ INIT_WORK(&joypad->play_work, pwm_vibrator_play_work); ++ ++ /* Sync up PWM state and ensure it is off. */ ++ pwm_init_state(joypad->pwm, &state); ++ state.enabled = false; ++ err = pwm_apply_might_sleep(joypad->pwm, &state); ++ if (err) { ++ dev_err(dev, "failed to apply initial PWM state: %d", ++ err); ++ return err; ++ } ++ dev_info(dev, "rumble setup success!\n"); ++ return 0; ++} ++static int joypad_input_setup(struct device *dev, struct joypad *joypad) ++{ ++ struct input_polled_dev *poll_dev; ++ struct input_dev *input; ++ int nbtn, error; ++ u32 joypad_revision = 0; ++ u32 joypad_product = 0; ++ u32 boost_weak = 0; ++ u32 boost_strong = 0; ++ poll_dev = devm_input_allocate_polled_device(dev); ++ if (!poll_dev) { ++ dev_err(dev, "no memory for polled device\n"); ++ return -ENOMEM; ++ } ++ ++ poll_dev->private = joypad; ++ poll_dev->poll = joypad_poll; ++ poll_dev->poll_interval = joypad->poll_interval; ++ poll_dev->open = joypad_open; ++ poll_dev->close = joypad_close; ++ ++ input = poll_dev->input; ++ joypad->input = poll_dev->input; ++ ++ device_property_read_string(dev, "joypad-name", &input->name); ++ input->phys = DRV_NAME"/input0"; ++ ++ device_property_read_u32(dev, "joypad-revision", &joypad_revision); ++ device_property_read_u32(dev, "joypad-product", &joypad_product); ++ input->id.bustype = BUS_HOST; ++ input->id.vendor = 0x484B; ++ input->id.product = (u16)joypad_product; ++ input->id.version = (u16)joypad_revision; ++ ++ /* IIO ADC key setup (0 mv ~ 1800 mv) * adc->scale */ ++ __set_bit(EV_ABS, input->evbit); ++ for(nbtn = 0; nbtn < joypad->amux_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ input_set_abs_params(input, adc->report_type, ++ adc->min, adc->max, ++ joypad->bt_adc_fuzz, ++ joypad->bt_adc_flat); ++ dev_info(dev, ++ "%s : SCALE = %d, ABS min = %d, max = %d," ++ " fuzz = %d, flat = %d, deadzone = %d\n", ++ __func__, adc->scale, adc->min, adc->max, ++ joypad->bt_adc_fuzz, joypad->bt_adc_flat, ++ joypad->bt_adc_deadzone); ++ dev_info(dev, ++ "%s : adc tuning_p = %d, adc_tuning_n = %d\n\n", ++ __func__, adc->tuning_p, adc->tuning_n); ++ } ++ ++ /* Rumble setip*/ ++ device_property_read_u32(dev, "rumble-boost-weak", &boost_weak); ++ device_property_read_u32(dev, "rumble-boost-strong", &boost_strong); ++ joypad->boost_weak = boost_weak; ++ joypad->boost_strong = boost_strong; ++ dev_info(dev, "Boost = %d, %d",boost_weak, boost_strong); ++ input_set_capability(input, EV_FF, FF_RUMBLE); ++ error = input_ff_create_memless(input, joypad, rumble_play_effect); ++ if (error) { ++ dev_err(dev, "unable to register rumble, err=%d\n", ++ error); ++ return error; ++ } ++ ++ /* GPIO key setup */ ++ __set_bit(EV_KEY, input->evbit); ++ for(nbtn = 0; nbtn < joypad->bt_gpio_count; nbtn++) { ++ struct bt_gpio *gpio = &joypad->gpios[nbtn]; ++ input_set_capability(input, gpio->report_type, ++ gpio->linux_code); ++ } ++ ++ if (joypad->auto_repeat) ++ __set_bit(EV_REP, input->evbit); ++ ++ joypad->dev = dev; ++ ++ error = input_register_polled_device(poll_dev); ++ if (error) { ++ dev_err(dev, "unable to register polled device, err=%d\n", ++ error); ++ return error; ++ } ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_setup_value_check(struct device *dev, struct joypad *joypad) ++{ ++ /* ++ fuzz: specifies fuzz value that is used to filter noise from ++ the event stream. ++ */ ++ if (g_button_adc_fuzz) ++ joypad->bt_adc_fuzz = g_button_adc_fuzz; ++ else ++ device_property_read_u32(dev, "button-adc-fuzz", ++ &joypad->bt_adc_fuzz); ++ /* ++ flat: values that are within this value will be discarded by ++ joydev interface and reported as 0 instead. ++ */ ++ if (g_button_adc_flat) ++ joypad->bt_adc_flat = g_button_adc_flat; ++ else ++ device_property_read_u32(dev, "button-adc-flat", ++ &joypad->bt_adc_flat); ++ ++ /* Joystick report value control */ ++ if (g_button_adc_scale) ++ joypad->bt_adc_scale = g_button_adc_scale; ++ else ++ device_property_read_u32(dev, "button-adc-scale", ++ &joypad->bt_adc_scale); ++ ++ /* Joystick deadzone value control */ ++ if (g_button_adc_deadzone) ++ joypad->bt_adc_deadzone = g_button_adc_deadzone; ++ else ++ device_property_read_u32(dev, "button-adc-deadzone", ++ &joypad->bt_adc_deadzone); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_dt_parse(struct device *dev, struct joypad *joypad) ++{ ++ int error = 0; ++ ++ /* initialize value check from boot.ini */ ++ joypad_setup_value_check(dev, joypad); ++ ++ device_property_read_u32(dev, "amux-count", ++ &joypad->amux_count); ++ ++ device_property_read_u32(dev, "poll-interval", ++ &joypad->poll_interval); ++ ++ joypad->auto_repeat = device_property_present(dev, "autorepeat"); ++ ++ /* change the report reference point? (ADC MAX - read value) */ ++ joypad->invert_absx = device_property_present(dev, "invert-absx"); ++ joypad->invert_absy = device_property_present(dev, "invert-absy"); ++ joypad->invert_absrx = device_property_present(dev, "invert-absrx"); ++ joypad->invert_absry = device_property_present(dev, "invert-absry"); ++ dev_info(dev, "%s : invert-absx = %d, inveret-absy = %d, invert-absrx = %d, inveret-absry = %d\n", ++ __func__, joypad->invert_absx, joypad->invert_absy, joypad->invert_absrx, joypad->invert_absry); ++ ++ joypad->bt_gpio_count = device_get_child_node_count(dev); ++ ++ if ((joypad->amux_count == 0) || (joypad->bt_gpio_count == 0)) { ++ dev_err(dev, "adc key = %d, gpio key = %d error!", ++ joypad->amux_count, joypad->bt_gpio_count); ++ return -EINVAL; ++ } ++ ++ error = joypad_adc_setup(dev, joypad); ++ if (error) ++ return error; ++ ++ error = joypad_amux_setup(dev, joypad); ++ if (error) ++ return error; ++ ++ error = joypad_gpio_setup(dev, joypad); ++ if (error) ++ return error; ++ ++ dev_info(dev, "%s : adc key cnt = %d, gpio key cnt = %d\n", ++ __func__, joypad->amux_count, joypad->bt_gpio_count); ++ ++ return error; ++} ++ ++static int __maybe_unused joypad_suspend(struct device *dev) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ cancel_work_sync(&joypad->play_work); ++ if (joypad->level) ++ pwm_vibrator_stop(joypad); ++ ++ return 0; ++} ++ ++static int __maybe_unused joypad_resume(struct device *dev) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ if (joypad->level) ++ pwm_vibrator_start(joypad); ++ ++ return 0; ++} ++ ++static SIMPLE_DEV_PM_OPS(joypad_pm_ops, ++ joypad_suspend, joypad_resume); ++/*----------------------------------------------------------------------------*/ ++static int joypad_probe(struct platform_device *pdev) ++{ ++ struct joypad *joypad; ++ struct device *dev = &pdev->dev; ++ int error; ++ ++ joypad = devm_kzalloc(dev, sizeof(struct joypad), GFP_KERNEL); ++ if (!joypad) { ++ dev_err(dev, "joypad devm_kzmalloc error!"); ++ return -ENOMEM; ++ } ++ ++ /* device tree data parse */ ++ error = joypad_dt_parse(dev, joypad); ++ if (error) { ++ dev_err(dev, "dt parse error!(err = %d)\n", error); ++ return error; ++ } ++ ++ mutex_init(&joypad->lock); ++ platform_set_drvdata(pdev, joypad); ++ ++ error = sysfs_create_group(&pdev->dev.kobj, &joypad_attr_group); ++ if (error) { ++ dev_err(dev, "create sysfs group fail, error: %d\n", ++ error); ++ return error; ++ } ++ ++ /* poll input device setup */ ++ error = joypad_input_setup(dev, joypad); ++ if (error) { ++ dev_err(dev, "input setup failed!(err = %d)\n", error); ++ return error; ++ } ++ ++ /* rumble setup */ ++ error = joypad_rumble_setup(dev, joypad); ++ if (error) { ++ dev_err(dev, "rumble setup failed!(err = %d)\n", error); ++ return error; ++ } ++ ++ dev_info(dev, "%s : probe success\n", __func__); ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static const struct of_device_id joypad_of_match[] = { ++ { .compatible = "rgb20s-joypad", }, ++ {}, ++}; ++ ++MODULE_DEVICE_TABLE(of, joypad_of_match); ++ ++/*----------------------------------------------------------------------------*/ ++static struct platform_driver joypad_driver = { ++ .probe = joypad_probe, ++ .driver = { ++ .name = DRV_NAME, ++ .pm = &joypad_pm_ops, ++ .of_match_table = of_match_ptr(joypad_of_match), ++ }, ++}; ++ ++/*----------------------------------------------------------------------------*/ ++static int __init joypad_init(void) ++{ ++ return platform_driver_register(&joypad_driver); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void __exit joypad_exit(void) ++{ ++ platform_driver_unregister(&joypad_driver); ++} ++ ++/*----------------------------------------------------------------------------*/ ++late_initcall(joypad_init); ++module_exit(joypad_exit); ++ ++/*----------------------------------------------------------------------------*/ ++MODULE_AUTHOR("Hardkernel Co.,LTD"); ++MODULE_DESCRIPTION("Keypad driver(ADC&GPIO) for Powkiddy RGB20S"); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:" DRV_NAME); ++ ++/*----------------------------------------------------------------------------*/ +diff --git a/drivers/input/joystick/xu10-joypad.c b/drivers/input/joystick/xu10-joypad.c +new file mode 100644 +index 000000000000..f7832a8158d4 +--- /dev/null ++++ b/drivers/input/joystick/xu10-joypad.c +@@ -0,0 +1,1139 @@ ++/* ++ * SARADC joystick & GPIO Button driver for Linux(Hardkernel MagicX-XU10) ++ */ ++/* ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * Should you need to contact me, the author, you can do so either by ++ * e-mail - mail your message to , or by paper mail: ++ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic ++ */ ++ ++/*----------------------------------------------------------------------------*/ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/*----------------------------------------------------------------------------*/ ++#define DRV_NAME "xu10_joypad" ++ ++/*----------------------------------------------------------------------------*/ ++#define ADC_MAX_VOLTAGE 1800 ++#define ADC_DATA_TUNING(x, p) ((x * p) / 100) ++#define ADC_TUNING_DEFAULT 180 ++ ++ ++/*----------------------------------------------------------------------------*/ ++struct bt_adc { ++ /* report value (mV) */ ++ int value; ++ /* report type */ ++ int report_type; ++ /* input device init value (mV) */ ++ int max, min; ++ /* calibrated adc value */ ++ int cal; ++ /* adc scale value */ ++ int scale; ++ /* invert report */ ++ bool invert; ++ /* amux channel */ ++ int amux_ch; ++ /* adc data tuning value([percent), p = positive, n = negative */ ++ int tuning_p, tuning_n; ++}; ++ ++struct analog_mux { ++ /* IIO ADC Channel : amux connect channel */ ++ struct iio_channel *iio_ch; ++ struct iio_channel *iio_ch_r; ++ /* analog mux select(a,b) gpio */ ++ int sel_a_gpio, sel_b_gpio; ++ /* analog mux enable gpio */ ++ int en_gpio; ++}; ++ ++struct bt_gpio { ++ /* GPIO Request label */ ++ const char *label; ++ /* GPIO Number */ ++ int num; ++ /* report type */ ++ int report_type; ++ /* report linux code */ ++ int linux_code; ++ /* prev button value */ ++ bool old_value; ++ /* button press level */ ++ bool active_level; ++}; ++ ++struct joypad { ++ struct device *dev; ++ int poll_interval; ++ ++ /* report enable/disable */ ++ bool enable; ++ ++ /* analog mux & joystick control */ ++ struct analog_mux *amux; ++ /* analog mux max count */ ++ int amux_count; ++ /* analog button */ ++ struct bt_adc *adcs; ++ ++ /* report reference point */ ++ bool invert_absx; ++ bool invert_absy; ++ bool invert_absrx; ++ bool invert_absry; ++ ++ /* report interval (ms) */ ++ int bt_gpio_count; ++ struct bt_gpio *gpios; ++ ++ /* button auto repeat */ ++ int auto_repeat; ++ ++ /* report threshold (mV) */ ++ int bt_adc_fuzz, bt_adc_flat; ++ /* adc read value scale */ ++ int bt_adc_scale; ++ /* joystick deadzone control */ ++ int bt_adc_deadzone; ++ ++ struct mutex lock; ++ ++ /* amux debug channel */ ++ int debug_ch; ++}; ++ ++/*----------------------------------------------------------------------------*/ ++// ++// set to the value in the boot.ini file. (if exist) ++// ++/*----------------------------------------------------------------------------*/ ++static unsigned int g_button_adc_fuzz = 0; ++static unsigned int g_button_adc_flat = 0; ++static unsigned int g_button_adc_scale = 0; ++static unsigned int g_button_adc_deadzone = 0; ++ ++static int button_adc_fuzz(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_fuzz = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-fuzz=", button_adc_fuzz); ++ ++static int button_adc_flat(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_flat = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-flat=", button_adc_flat); ++ ++static int button_adc_scale(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_scale = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-scale=", button_adc_scale); ++ ++static int button_adc_deadzone(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_deadzone = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-deadzone=", button_adc_deadzone); ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++static int joypad_amux_select(struct analog_mux *amux, int channel) ++{ ++ /* select mux channel */ ++ gpio_set_value(amux->en_gpio, 0); ++ ++ switch(channel) { ++ case 0: /* EVENT (ABS_RY) */ ++ gpio_set_value(amux->sel_a_gpio, 0); ++ gpio_set_value(amux->sel_b_gpio, 0); ++ break; ++ case 1: /* EVENT (ABS_RX) */ ++ gpio_set_value(amux->sel_a_gpio, 1); ++ gpio_set_value(amux->sel_b_gpio, 1); ++ break; ++ case 2: /* EVENT (ABS_Y) */ ++ gpio_set_value(amux->sel_a_gpio, 0); ++ gpio_set_value(amux->sel_b_gpio, 0); ++ break; ++ case 3: /* EVENT (ABS_X) */ ++ gpio_set_value(amux->sel_a_gpio, 1); ++ gpio_set_value(amux->sel_b_gpio, 1); ++ break; ++ default: ++ /* amux disable */ ++ gpio_set_value(amux->en_gpio, 1); ++ return -1; ++ } ++ /* mux swtiching speed : 35ns(on) / 9ns(off) */ ++ usleep_range(1, 2); ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_adc_read(struct analog_mux *amux, struct bt_adc *adc) ++{ ++ int value; ++ int res; ++ ++ if (joypad_amux_select(amux, adc->amux_ch)) ++ return 0; ++ ++ switch(adc->amux_ch) { ++ case 0: ++ case 1: ++ res = iio_read_channel_processed(amux->iio_ch_r, &value); ++ break; ++ case 2: ++ case 3: ++ default: ++ res = iio_read_channel_processed(amux->iio_ch, &value); ++ break; ++ } ++ ++ if (res) ++ return 0; ++ ++ value *= adc->scale; ++ ++ return value; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/odroidgo2_joypad/poll_interval [rw] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_poll_interval(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ mutex_lock(&joypad->lock); ++ joypad->poll_interval = simple_strtoul(buf, NULL, 10); ++ mutex_unlock(&joypad->lock); ++ ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_poll_interval(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->poll_interval); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(poll_interval, S_IWUSR | S_IRUGO, ++ joypad_show_poll_interval, ++ joypad_store_poll_interval); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/odroidgo2_joypad/adc_fuzz [r] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_adc_fuzz(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->bt_adc_fuzz); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(adc_fuzz, S_IWUSR | S_IRUGO, ++ joypad_show_adc_fuzz, ++ NULL); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/odroidgo2_joypad/adc_flat [r] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_adc_flat(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->bt_adc_flat); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(adc_flat, S_IWUSR | S_IRUGO, ++ joypad_show_adc_flat, ++ NULL); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/odroidgo2_joypad/enable [rw] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_enable(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ mutex_lock(&joypad->lock); ++ joypad->enable = simple_strtoul(buf, NULL, 10); ++ mutex_unlock(&joypad->lock); ++ ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_enable(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->enable); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO, ++ joypad_show_enable, ++ joypad_store_enable); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/odroidgo2_joypad/adc_cal [rw] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_adc_cal(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ bool calibration; ++ ++ calibration = simple_strtoul(buf, NULL, 10); ++ ++ if (calibration) { ++ int nbtn; ++ ++ mutex_lock(&joypad->lock); ++ for (nbtn = 0; nbtn < joypad->amux_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ ++ adc->value = joypad_adc_read(joypad->amux, adc); ++ if (!adc->value) { ++ dev_err(joypad->dev, "%s : saradc channels[%d]!\n", ++ __func__, nbtn); ++ continue; ++ } ++ adc->cal = adc->value; ++ } ++ mutex_unlock(&joypad->lock); ++ } ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_adc_cal(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ int nbtn; ++ ssize_t pos; ++ ++ for (nbtn = 0, pos = 0; nbtn < joypad->amux_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ pos += sprintf(&buf[pos], "adc[%d]->cal = %d\n", ++ nbtn, adc->cal); ++ } ++ pos += sprintf(&buf[pos], "adc scale = %d\n", joypad->bt_adc_scale); ++ return pos; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(adc_cal, S_IWUSR | S_IRUGO, ++ joypad_show_adc_cal, ++ joypad_store_adc_cal); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/odroidgo2_joypad/amux_debug [rw] ++ * ++ * echo [debug channel] > amux_debug ++ * cat amux_debug : debug channel mux set & adc read ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_amux_debug(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ joypad->debug_ch = simple_strtoul(buf, NULL, 10); ++ ++ /* if error than default setting(debug_ch = 0) */ ++ if (joypad->debug_ch > joypad->amux_count) ++ joypad->debug_ch = 0; ++ ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_amux_debug(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ struct analog_mux *amux = joypad->amux; ++ ssize_t pos; ++ int value; ++ int res; ++ ++ mutex_lock(&joypad->lock); ++ ++ /* disable poll driver */ ++ if (joypad->enable) ++ joypad->enable = false; ++ ++ if (joypad_amux_select(amux, joypad->debug_ch)) ++ goto err_out; ++ ++ switch(joypad->debug_ch) { ++ case 0: ++ case 1: ++ res = iio_read_channel_processed(amux->iio_ch_r, &value); ++ break; ++ case 2: ++ case 3: ++ default: ++ res = iio_read_channel_processed(amux->iio_ch, &value); ++ break; ++ } ++ ++ if (res) ++ goto err_out; ++ ++ pos = sprintf(buf, "amux ch[%d], adc scale = %d, adc value = %d\n", ++ joypad->debug_ch, joypad->bt_adc_scale, ++ value * joypad->bt_adc_scale); ++ goto out; ++ ++err_out: ++ pos = sprintf(buf, "error : amux setup & adc read!\n"); ++out: ++ mutex_unlock(&joypad->lock); ++ return pos; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(amux_debug, S_IWUSR | S_IRUGO, ++ joypad_show_amux_debug, ++ joypad_store_amux_debug); ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++static struct attribute *joypad_attrs[] = { ++ &dev_attr_poll_interval.attr, ++ &dev_attr_adc_fuzz.attr, ++ &dev_attr_adc_flat.attr, ++ &dev_attr_enable.attr, ++ &dev_attr_adc_cal.attr, ++ &dev_attr_amux_debug.attr, ++ NULL, ++}; ++ ++static struct attribute_group joypad_attr_group = { ++ .attrs = joypad_attrs, ++}; ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++static void joypad_gpio_check(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ int nbtn, value; ++ ++ for (nbtn = 0; nbtn < joypad->bt_gpio_count; nbtn++) { ++ struct bt_gpio *gpio = &joypad->gpios[nbtn]; ++ ++ if (gpio_get_value_cansleep(gpio->num) < 0) { ++ dev_err(joypad->dev, "failed to get gpio state\n"); ++ continue; ++ } ++ value = gpio_get_value(gpio->num); ++ if (value != gpio->old_value) { ++ input_event(poll_dev->input, ++ gpio->report_type, ++ gpio->linux_code, ++ (value == gpio->active_level) ? 1 : 0); ++ gpio->old_value = value; ++ } ++ } ++ input_sync(poll_dev->input); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_adc_check(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ int nbtn; ++ ++ for (nbtn = 0; nbtn < joypad->amux_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ ++ adc->value = joypad_adc_read(joypad->amux, adc); ++ if (!adc->value) { ++ dev_err(joypad->dev, "%s : saradc channels[%d]!\n", ++ __func__, nbtn); ++ continue; ++ } ++ adc->value = adc->value - adc->cal; ++ ++ /* Joystick Deadzone check */ ++ if (joypad->bt_adc_deadzone) { ++ if (abs(adc->value) < joypad->bt_adc_deadzone) ++ adc->value = 0; ++ } ++ ++ /* adc data tuning */ ++ if (adc->tuning_n && adc->value < 0) ++ adc->value = ADC_DATA_TUNING(adc->value, adc->tuning_n); ++ if (adc->tuning_p && adc->value > 0) ++ adc->value = ADC_DATA_TUNING(adc->value, adc->tuning_p); ++ ++ adc->value = adc->value > adc->max ? adc->max : adc->value; ++ adc->value = adc->value < adc->min ? adc->min : adc->value; ++ ++ input_report_abs(poll_dev->input, ++ adc->report_type, ++ adc->invert ? adc->value * (-1) : adc->value); ++ } ++ input_sync(poll_dev->input); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_poll(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ ++ if (joypad->enable) { ++ joypad_adc_check(poll_dev); ++ joypad_gpio_check(poll_dev); ++ } ++ if (poll_dev->poll_interval != joypad->poll_interval) { ++ mutex_lock(&joypad->lock); ++ poll_dev->poll_interval = joypad->poll_interval; ++ mutex_unlock(&joypad->lock); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_open(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ int nbtn; ++ ++ for (nbtn = 0; nbtn < joypad->bt_gpio_count; nbtn++) { ++ struct bt_gpio *gpio = &joypad->gpios[nbtn]; ++ gpio->old_value = gpio->active_level ? 0 : 1; ++ } ++ for (nbtn = 0; nbtn < joypad->amux_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ ++ adc->value = joypad_adc_read(joypad->amux, adc); ++ if (!adc->value) { ++ dev_err(joypad->dev, "%s : saradc channels[%d]!\n", ++ __func__, nbtn); ++ continue; ++ } ++ adc->cal = adc->value; ++ dev_info(joypad->dev, "%s : adc[%d] adc->cal = %d\n", ++ __func__, nbtn, adc->cal); ++ } ++ /* buttons status sync */ ++ joypad_adc_check(poll_dev); ++ joypad_gpio_check(poll_dev); ++ ++ /* button report enable */ ++ mutex_lock(&joypad->lock); ++ joypad->enable = true; ++ mutex_unlock(&joypad->lock); ++ ++ dev_info(joypad->dev, "%s : opened\n", __func__); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_close(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ ++ /* button report disable */ ++ mutex_lock(&joypad->lock); ++ joypad->enable = false; ++ mutex_unlock(&joypad->lock); ++ ++ dev_info(joypad->dev, "%s : closed\n", __func__); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_amux_setup(struct device *dev, struct joypad *joypad) ++{ ++ struct analog_mux *amux; ++ enum iio_chan_type type; ++ enum of_gpio_flags flags; ++ int ret; ++ ++ /* analog mux control struct init */ ++ joypad->amux = devm_kzalloc(dev, sizeof(struct analog_mux), ++ GFP_KERNEL); ++ if (!joypad->amux) { ++ dev_err(dev, "%s amux devm_kzmalloc error!", __func__); ++ return -ENOMEM; ++ } ++ amux = joypad->amux; ++ amux->iio_ch = devm_iio_channel_get(dev, "joy_left"); ++ amux->iio_ch_r = devm_iio_channel_get(dev, "joy_right"); ++ ++ if (IS_ERR(amux->iio_ch)) { ++ dev_err(dev, "iio channel get error\n"); ++ return -EINVAL; ++ } ++ ++ if (IS_ERR(amux->iio_ch_r)) { ++ dev_err(dev, "iio channel right get error\n"); ++ return -EINVAL; ++ } ++ ++ if (!amux->iio_ch->indio_dev || !amux->iio_ch_r->indio_dev) ++ return -ENXIO; ++ ++ if (iio_get_channel_type(amux->iio_ch, &type)) ++ return -EINVAL; ++ ++ if (type != IIO_VOLTAGE) { ++ dev_err(dev, "Incompatible channel type %d\n", type); ++ return -EINVAL; ++ } ++ ++ if (iio_get_channel_type(amux->iio_ch_r, &type)) ++ return -EINVAL; ++ ++ if (type != IIO_VOLTAGE) { ++ dev_err(dev, "Incompatible channel type %d\n", type); ++ return -EINVAL; ++ } ++ ++ amux->sel_a_gpio = of_get_named_gpio_flags(dev->of_node, ++ "amux-a-gpios", 0, &flags); ++ if (gpio_is_valid(amux->sel_a_gpio)) { ++ ret = devm_gpio_request(dev, amux->sel_a_gpio, "amux-sel-a"); ++ if (ret < 0) { ++ dev_err(dev, "%s : failed to request amux-sel-a %d\n", ++ __func__, amux->sel_a_gpio); ++ goto err_out; ++ } ++ ret = gpio_direction_output(amux->sel_a_gpio, 0); ++ if (ret < 0) ++ goto err_out; ++ } ++ ++ amux->sel_b_gpio = of_get_named_gpio_flags(dev->of_node, ++ "amux-b-gpios", 0, &flags); ++ if (gpio_is_valid(amux->sel_b_gpio)) { ++ ret = devm_gpio_request(dev, amux->sel_b_gpio, "amux-sel-b"); ++ if (ret < 0) { ++ dev_err(dev, "%s : failed to request amux-sel-b %d\n", ++ __func__, amux->sel_b_gpio); ++ goto err_out; ++ } ++ ret = gpio_direction_output(amux->sel_b_gpio, 0); ++ if (ret < 0) ++ goto err_out; ++ } ++ ++ amux->en_gpio = of_get_named_gpio_flags(dev->of_node, ++ "amux-en-gpios", 0, &flags); ++ if (gpio_is_valid(amux->en_gpio)) { ++ ret = devm_gpio_request(dev, amux->en_gpio, "amux-en"); ++ if (ret < 0) { ++ dev_err(dev, "%s : failed to request amux-en %d\n", ++ __func__, amux->en_gpio); ++ goto err_out; ++ } ++ ret = gpio_direction_output(amux->en_gpio, 0); ++ if (ret < 0) ++ goto err_out; ++ } ++ return 0; ++err_out: ++ return ret; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_adc_setup(struct device *dev, struct joypad *joypad) ++{ ++ int nbtn; ++ ++ /* adc button struct init */ ++ joypad->adcs = devm_kzalloc(dev, joypad->amux_count * ++ sizeof(struct bt_adc), GFP_KERNEL); ++ if (!joypad->adcs) { ++ dev_err(dev, "%s devm_kzmalloc error!", __func__); ++ return -ENOMEM; ++ } ++ ++ for (nbtn = 0; nbtn < joypad->amux_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ ++ adc->scale = joypad->bt_adc_scale; ++ ++ adc->max = (ADC_MAX_VOLTAGE / 2); ++ adc->min = (ADC_MAX_VOLTAGE / 2) * (-1); ++ if (adc->scale) { ++ adc->max *= adc->scale; ++ adc->min *= adc->scale; ++ } ++ adc->amux_ch = nbtn; ++ adc->invert = false; ++ ++ switch (nbtn) { ++ case 0: ++ if (joypad->invert_absry) ++ adc->invert = true; ++ adc->report_type = ABS_RY; ++ if (device_property_read_u32(dev, ++ "abs_ry-p-tuning", ++ &adc->tuning_p)) ++ adc->tuning_p = ADC_TUNING_DEFAULT; ++ if (device_property_read_u32(dev, ++ "abs_ry-n-tuning", ++ &adc->tuning_n)) ++ adc->tuning_n = ADC_TUNING_DEFAULT; ++ break; ++ case 1: ++ if (joypad->invert_absrx) ++ adc->invert = true; ++ adc->report_type = ABS_RX; ++ if (device_property_read_u32(dev, ++ "abs_rx-p-tuning", ++ &adc->tuning_p)) ++ adc->tuning_p = ADC_TUNING_DEFAULT; ++ if (device_property_read_u32(dev, ++ "abs_rx-n-tuning", ++ &adc->tuning_n)) ++ adc->tuning_n = ADC_TUNING_DEFAULT; ++ break; ++ case 2: ++ if (joypad->invert_absy) ++ adc->invert = true; ++ adc->report_type = ABS_Y; ++ if (device_property_read_u32(dev, ++ "abs_y-p-tuning", ++ &adc->tuning_p)) ++ adc->tuning_p = ADC_TUNING_DEFAULT; ++ if (device_property_read_u32(dev, ++ "abs_y-n-tuning", ++ &adc->tuning_n)) ++ adc->tuning_n = ADC_TUNING_DEFAULT; ++ break; ++ case 3: ++ if (joypad->invert_absx) ++ adc->invert = true; ++ adc->report_type = ABS_X; ++ if (device_property_read_u32(dev, ++ "abs_x-p-tuning", ++ &adc->tuning_p)) ++ adc->tuning_p = ADC_TUNING_DEFAULT; ++ if (device_property_read_u32(dev, ++ "abs_x-n-tuning", ++ &adc->tuning_n)) ++ adc->tuning_n = ADC_TUNING_DEFAULT; ++ break; ++ default : ++ dev_err(dev, "%s amux count(%d) error!", ++ __func__, nbtn); ++ return -EINVAL; ++ } ++ } ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_gpio_setup(struct device *dev, struct joypad *joypad) ++{ ++ struct device_node *node, *pp; ++ int nbtn; ++ ++ node = dev->of_node; ++ if (!node) ++ return -ENODEV; ++ ++ joypad->gpios = devm_kzalloc(dev, joypad->bt_gpio_count * ++ sizeof(struct bt_gpio), GFP_KERNEL); ++ ++ if (!joypad->gpios) { ++ dev_err(dev, "%s devm_kzmalloc error!", __func__); ++ return -ENOMEM; ++ } ++ ++ nbtn = 0; ++ for_each_child_of_node(node, pp) { ++ enum of_gpio_flags flags; ++ struct bt_gpio *gpio = &joypad->gpios[nbtn++]; ++ int error; ++ ++ gpio->num = of_get_gpio_flags(pp, 0, &flags); ++ if (gpio->num < 0) { ++ error = gpio->num; ++ dev_err(dev, "Failed to get gpio flags, error: %d\n", ++ error); ++ return error; ++ } ++ ++ /* gpio active level(key press level) */ ++ gpio->active_level = (flags & OF_GPIO_ACTIVE_LOW) ? 0 : 1; ++ ++ gpio->label = of_get_property(pp, "label", NULL); ++ ++ if (gpio_is_valid(gpio->num)) { ++ error = devm_gpio_request_one(dev, gpio->num, ++ GPIOF_IN, gpio->label); ++ if (error < 0) { ++ dev_err(dev, ++ "Failed to request GPIO %d, error %d\n", ++ gpio->num, error); ++ return error; ++ } ++ } ++ if (of_property_read_u32(pp, "linux,code", &gpio->linux_code)) { ++ dev_err(dev, "Button without keycode: 0x%x\n", ++ gpio->num); ++ return -EINVAL; ++ } ++ if (of_property_read_u32(pp, "linux,input-type", ++ &gpio->report_type)) ++ gpio->report_type = EV_KEY; ++ } ++ if (nbtn == 0) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_input_setup(struct device *dev, struct joypad *joypad) ++{ ++ struct input_polled_dev *poll_dev; ++ struct input_dev *input; ++ int nbtn, error; ++ u32 joypad_product = 0; ++ u32 joypad_revision = 0; ++ ++ poll_dev = devm_input_allocate_polled_device(dev); ++ if (!poll_dev) { ++ dev_err(dev, "no memory for polled device\n"); ++ return -ENOMEM; ++ } ++ ++ poll_dev->private = joypad; ++ poll_dev->poll = joypad_poll; ++ poll_dev->poll_interval = joypad->poll_interval; ++ poll_dev->open = joypad_open; ++ poll_dev->close = joypad_close; ++ ++ input = poll_dev->input; ++ ++ device_property_read_string(dev, "joypad-name", &input->name); ++ input->phys = DRV_NAME"/input0"; ++ ++ device_property_read_u32(dev, "joypad-product", &joypad_product); ++ device_property_read_u32(dev, "joypad-revision", &joypad_revision); ++ ++ input->id.bustype = BUS_HOST; ++ input->id.vendor = 0xC3B0; ++ input->id.product = (u16)joypad_product; ++ input->id.version = (u16)joypad_revision; ++ ++ /* IIO ADC key setup (0 mv ~ 1800 mv) * adc->scale */ ++ __set_bit(EV_ABS, input->evbit); ++ for(nbtn = 0; nbtn < joypad->amux_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ input_set_abs_params(input, adc->report_type, ++ adc->min, adc->max, ++ joypad->bt_adc_fuzz, ++ joypad->bt_adc_flat); ++ dev_info(dev, ++ "%s : SCALE = %d, ABS min = %d, max = %d," ++ " fuzz = %d, flat = %d, deadzone = %d\n", ++ __func__, adc->scale, adc->min, adc->max, ++ joypad->bt_adc_fuzz, joypad->bt_adc_flat, ++ joypad->bt_adc_deadzone); ++ dev_info(dev, ++ "%s : adc tuning_p = %d, adc_tuning_n = %d\n\n", ++ __func__, adc->tuning_p, adc->tuning_n); ++ } ++ ++ /* GPIO key setup */ ++ __set_bit(EV_KEY, input->evbit); ++ for(nbtn = 0; nbtn < joypad->bt_gpio_count; nbtn++) { ++ struct bt_gpio *gpio = &joypad->gpios[nbtn]; ++ input_set_capability(input, gpio->report_type, ++ gpio->linux_code); ++ } ++ ++ if (joypad->auto_repeat) ++ __set_bit(EV_REP, input->evbit); ++ ++ joypad->dev = dev; ++ ++ error = input_register_polled_device(poll_dev); ++ if (error) { ++ dev_err(dev, "unable to register polled device, err=%d\n", ++ error); ++ return error; ++ } ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_setup_value_check(struct device *dev, struct joypad *joypad) ++{ ++ /* ++ fuzz: specifies fuzz value that is used to filter noise from ++ the event stream. ++ */ ++ if (g_button_adc_fuzz) ++ joypad->bt_adc_fuzz = g_button_adc_fuzz; ++ else ++ device_property_read_u32(dev, "button-adc-fuzz", ++ &joypad->bt_adc_fuzz); ++ /* ++ flat: values that are within this value will be discarded by ++ joydev interface and reported as 0 instead. ++ */ ++ if (g_button_adc_flat) ++ joypad->bt_adc_flat = g_button_adc_flat; ++ else ++ device_property_read_u32(dev, "button-adc-flat", ++ &joypad->bt_adc_flat); ++ ++ /* Joystick report value control */ ++ if (g_button_adc_scale) ++ joypad->bt_adc_scale = g_button_adc_scale; ++ else ++ device_property_read_u32(dev, "button-adc-scale", ++ &joypad->bt_adc_scale); ++ ++ /* Joystick deadzone value control */ ++ if (g_button_adc_deadzone) ++ joypad->bt_adc_deadzone = g_button_adc_deadzone; ++ else ++ device_property_read_u32(dev, "button-adc-deadzone", ++ &joypad->bt_adc_deadzone); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_dt_parse(struct device *dev, struct joypad *joypad) ++{ ++ int error = 0; ++ ++ /* initialize value check from boot.ini */ ++ joypad_setup_value_check(dev, joypad); ++ ++ device_property_read_u32(dev, "amux-count", ++ &joypad->amux_count); ++ ++ device_property_read_u32(dev, "poll-interval", ++ &joypad->poll_interval); ++ ++ joypad->auto_repeat = device_property_present(dev, "autorepeat"); ++ ++ /* change the report reference point? (read value * -1) */ ++ joypad->invert_absx = device_property_present(dev, "invert-absx"); ++ joypad->invert_absy = device_property_present(dev, "invert-absy"); ++ joypad->invert_absrx = device_property_present(dev, "invert-absrx"); ++ joypad->invert_absry = device_property_present(dev, "invert-absry"); ++ dev_info(dev, "%s : invert-absx = %d, inveret-absy = %d, invert-absrx = %d, invert-absry = %d\n", ++ __func__, joypad->invert_absx, joypad->invert_absy, joypad->invert_absrx, joypad->invert_absry); ++ ++ joypad->bt_gpio_count = device_get_child_node_count(dev); ++ ++ if ((joypad->amux_count == 0) || (joypad->bt_gpio_count == 0)) { ++ dev_err(dev, "adc key = %d, gpio key = %d error!", ++ joypad->amux_count, joypad->bt_gpio_count); ++ return -EINVAL; ++ } ++ ++ error = joypad_adc_setup(dev, joypad); ++ if (error) ++ return error; ++ ++ error = joypad_amux_setup(dev, joypad); ++ if (error) ++ return error; ++ ++ error = joypad_gpio_setup(dev, joypad); ++ if (error) ++ return error; ++ ++ dev_info(dev, "%s : adc key cnt = %d, gpio key cnt = %d\n", ++ __func__, joypad->amux_count, joypad->bt_gpio_count); ++ ++ return error; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_probe(struct platform_device *pdev) ++{ ++ struct joypad *joypad; ++ struct device *dev = &pdev->dev; ++ int error; ++ ++ joypad = devm_kzalloc(dev, sizeof(struct joypad), GFP_KERNEL); ++ if (!joypad) { ++ dev_err(dev, "joypad devm_kzmalloc error!"); ++ return -ENOMEM; ++ } ++ ++ /* device tree data parse */ ++ error = joypad_dt_parse(dev, joypad); ++ if (error) { ++ dev_err(dev, "dt parse error!(err = %d)\n", error); ++ return error; ++ } ++ ++ mutex_init(&joypad->lock); ++ platform_set_drvdata(pdev, joypad); ++ ++ error = sysfs_create_group(&pdev->dev.kobj, &joypad_attr_group); ++ if (error) { ++ dev_err(dev, "create sysfs group fail, error: %d\n", ++ error); ++ return error; ++ } ++ ++ /* poll input device setup */ ++ error = joypad_input_setup(dev, joypad); ++ if (error) { ++ dev_err(dev, "input setup failed!(err = %d)\n", error); ++ return error; ++ } ++ dev_info(dev, "%s : probe success\n", __func__); ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static const struct of_device_id joypad_of_match[] = { ++ { .compatible = "xu10-joypad", }, ++ {}, ++}; ++ ++MODULE_DEVICE_TABLE(of, joypad_of_match); ++ ++/*----------------------------------------------------------------------------*/ ++static struct platform_driver joypad_driver = { ++ .probe = joypad_probe, ++ .driver = { ++ .name = DRV_NAME, ++ .of_match_table = of_match_ptr(joypad_of_match), ++ }, ++}; ++ ++/*----------------------------------------------------------------------------*/ ++static int __init joypad_init(void) ++{ ++ return platform_driver_register(&joypad_driver); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void __exit joypad_exit(void) ++{ ++ platform_driver_unregister(&joypad_driver); ++} ++ ++/*----------------------------------------------------------------------------*/ ++late_initcall(joypad_init); ++module_exit(joypad_exit); ++ ++/*----------------------------------------------------------------------------*/ ++MODULE_AUTHOR("Hardkernel Co.,LTD"); ++MODULE_DESCRIPTION("Keypad driver(ADC&GPIO) for MagicX-XU10"); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:" DRV_NAME); ++ ++/*----------------------------------------------------------------------------*/ +diff --git a/drivers/power/supply/rk817_charger.c b/drivers/power/supply/rk817_charger.c +index 7ca91739c6cc..a2a6d8093206 100644 +--- a/drivers/power/supply/rk817_charger.c ++++ b/drivers/power/supply/rk817_charger.c +@@ -679,7 +679,7 @@ static enum power_supply_usb_type rk817_usb_type[] = { + }; + + static const struct power_supply_desc rk817_bat_desc = { +- .name = "rk817-battery", ++ .name = "battery", + .type = POWER_SUPPLY_TYPE_BATTERY, + .properties = rk817_bat_props, + .num_properties = ARRAY_SIZE(rk817_bat_props), diff --git a/projects/ArchR/devices/RK3326/patches/linux/005-unigue-gpio-guid.patch b/projects/ArchR/devices/RK3326/patches/linux/005-unigue-gpio-guid.patch new file mode 100644 index 0000000000..92cce0e352 --- /dev/null +++ b/projects/ArchR/devices/RK3326/patches/linux/005-unigue-gpio-guid.patch @@ -0,0 +1,14 @@ +diff -rupN linux.orig/drivers/input/keyboard/gpio_keys.c linux/drivers/input/keyboard/gpio_keys.c +--- linux.orig/drivers/input/keyboard/gpio_keys.c 2024-01-25 20:47:47.094097973 +0000 ++++ linux/drivers/input/keyboard/gpio_keys.c 2024-01-26 04:17:54.663672057 +0000 +@@ -847,8 +847,8 @@ static int gpio_keys_probe(struct platfo + + input->id.bustype = BUS_HOST; + input->id.vendor = 0x0001; +- input->id.product = 0x0001; +- input->id.version = 0x0100; ++ input->id.product = 0x7891; ++ input->id.version = 0x0500; + + input->keycode = ddata->keymap; + input->keycodesize = sizeof(ddata->keymap[0]); diff --git a/projects/ArchR/devices/RK3326/patches/linux/007-ogs-panel-timings.patch b/projects/ArchR/devices/RK3326/patches/linux/007-ogs-panel-timings.patch new file mode 100644 index 0000000000..c440a804de --- /dev/null +++ b/projects/ArchR/devices/RK3326/patches/linux/007-ogs-panel-timings.patch @@ -0,0 +1,32 @@ +diff -rupbN linux.orig/drivers/gpu/drm/panel/panel-sitronix-st7701.c linux/drivers/gpu/drm/panel/panel-sitronix-st7701.c +--- linux.orig/drivers/gpu/drm/panel/panel-sitronix-st7701.c 2025-01-09 12:33:55.000000000 +0000 ++++ linux/drivers/gpu/drm/panel/panel-sitronix-st7701.c 2025-01-15 14:14:08.794990319 +0000 +@@ -838,20 +838,20 @@ static const struct st7701_panel_desc dm + }; + + static const struct drm_display_mode kd50t048a_mode = { +- .clock = 27500, ++ .clock = 29170, + + .hdisplay = 480, +- .hsync_start = 480 + 2, +- .hsync_end = 480 + 2 + 10, +- .htotal = 480 + 2 + 10 + 2, ++ .hsync_start = 480 + 12, ++ .hsync_end = 480 + 12 + 12, ++ .htotal = 480 + 12 + 12 + 38, + + .vdisplay = 854, + .vsync_start = 854 + 2, +- .vsync_end = 854 + 2 + 2, +- .vtotal = 854 + 2 + 2 + 17, ++ .vsync_end = 854 + 2 + 19, ++ .vtotal = 854 + 2 + 19 + 22, + +- .width_mm = 69, +- .height_mm = 139, ++ .width_mm = 70, ++ .height_mm = 140, + + .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, + }; diff --git a/projects/ArchR/devices/RK3326/patches/linux/008-esp-8089-wifi.patch b/projects/ArchR/devices/RK3326/patches/linux/008-esp-8089-wifi.patch new file mode 100644 index 0000000000..1ca6266df0 --- /dev/null +++ b/projects/ArchR/devices/RK3326/patches/linux/008-esp-8089-wifi.patch @@ -0,0 +1,10933 @@ +From 2d6165af6e9d5ed5026cdf250536c0a00d84fd75 Mon Sep 17 00:00:00 2001 +From: Paolo Sabatino +Date: Sat, 1 Oct 2022 12:43:53 +0000 +Subject: [PATCH] add esp8089 kernel driver + +--- + drivers/net/wireless/Kconfig | 1 + + drivers/net/wireless/Makefile | 1 + + drivers/net/wireless/esp8089/.gitignore | 7 + + drivers/net/wireless/esp8089/Kconfig | 13 + + drivers/net/wireless/esp8089/LICENSE | 340 +++ + drivers/net/wireless/esp8089/Makefile | 7 + + drivers/net/wireless/esp8089/Makefile.old | 99 + + drivers/net/wireless/esp8089/README.md | 31 + + drivers/net/wireless/esp8089/esp_ctrl.c | 801 ++++++ + drivers/net/wireless/esp8089/esp_ctrl.h | 58 + + drivers/net/wireless/esp8089/esp_debug.c | 297 ++ + drivers/net/wireless/esp8089/esp_debug.h | 101 + + drivers/net/wireless/esp8089/esp_ext.c | 542 ++++ + drivers/net/wireless/esp8089/esp_ext.h | 100 + + drivers/net/wireless/esp8089/esp_file.c | 258 ++ + drivers/net/wireless/esp8089/esp_file.h | 43 + + drivers/net/wireless/esp8089/esp_init_data.h | 7 + + drivers/net/wireless/esp8089/esp_io.c | 639 +++++ + drivers/net/wireless/esp8089/esp_mac80211.c | 1727 ++++++++++++ + drivers/net/wireless/esp8089/esp_mac80211.h | 38 + + drivers/net/wireless/esp8089/esp_main.c | 263 ++ + drivers/net/wireless/esp8089/esp_path.h | 6 + + drivers/net/wireless/esp8089/esp_pub.h | 222 ++ + drivers/net/wireless/esp8089/esp_sif.h | 207 ++ + drivers/net/wireless/esp8089/esp_sip.c | 2418 +++++++++++++++++ + drivers/net/wireless/esp8089/esp_sip.h | 171 ++ + drivers/net/wireless/esp8089/esp_utils.c | 262 ++ + drivers/net/wireless/esp8089/esp_utils.h | 41 + + drivers/net/wireless/esp8089/esp_version.h | 1 + + drivers/net/wireless/esp8089/esp_wl.h | 63 + + drivers/net/wireless/esp8089/esp_wmac.h | 92 + + .../wireless/esp8089/firmware/LICENSE-2.0.txt | 203 ++ + drivers/net/wireless/esp8089/sdio_sif_esp.c | 811 ++++++ + drivers/net/wireless/esp8089/sip2_common.h | 475 ++++ + .../net/wireless/esp8089/slc_host_register.h | 271 ++ + 35 files changed, 10616 insertions(+) + create mode 100644 drivers/net/wireless/esp8089/.gitignore + create mode 100644 drivers/net/wireless/esp8089/Kconfig + create mode 100644 drivers/net/wireless/esp8089/LICENSE + create mode 100644 drivers/net/wireless/esp8089/Makefile + create mode 100644 drivers/net/wireless/esp8089/Makefile.old + create mode 100644 drivers/net/wireless/esp8089/README.md + create mode 100644 drivers/net/wireless/esp8089/esp_ctrl.c + create mode 100644 drivers/net/wireless/esp8089/esp_ctrl.h + create mode 100644 drivers/net/wireless/esp8089/esp_debug.c + create mode 100644 drivers/net/wireless/esp8089/esp_debug.h + create mode 100644 drivers/net/wireless/esp8089/esp_ext.c + create mode 100644 drivers/net/wireless/esp8089/esp_ext.h + create mode 100644 drivers/net/wireless/esp8089/esp_file.c + create mode 100644 drivers/net/wireless/esp8089/esp_file.h + create mode 100644 drivers/net/wireless/esp8089/esp_init_data.h + create mode 100644 drivers/net/wireless/esp8089/esp_io.c + create mode 100644 drivers/net/wireless/esp8089/esp_mac80211.c + create mode 100644 drivers/net/wireless/esp8089/esp_mac80211.h + create mode 100644 drivers/net/wireless/esp8089/esp_main.c + create mode 100644 drivers/net/wireless/esp8089/esp_path.h + create mode 100644 drivers/net/wireless/esp8089/esp_pub.h + create mode 100644 drivers/net/wireless/esp8089/esp_sif.h + create mode 100644 drivers/net/wireless/esp8089/esp_sip.c + create mode 100644 drivers/net/wireless/esp8089/esp_sip.h + create mode 100644 drivers/net/wireless/esp8089/esp_utils.c + create mode 100644 drivers/net/wireless/esp8089/esp_utils.h + create mode 100644 drivers/net/wireless/esp8089/esp_version.h + create mode 100644 drivers/net/wireless/esp8089/esp_wl.h + create mode 100644 drivers/net/wireless/esp8089/esp_wmac.h + create mode 100644 drivers/net/wireless/esp8089/firmware/LICENSE-2.0.txt + create mode 100644 drivers/net/wireless/esp8089/sdio_sif_esp.c + create mode 100644 drivers/net/wireless/esp8089/sip2_common.h + create mode 100644 drivers/net/wireless/esp8089/slc_host_register.h + +diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig +index cb1c15012dd0..de5e37846397 100644 +--- a/drivers/net/wireless/Kconfig ++++ b/drivers/net/wireless/Kconfig +@@ -37,6 +37,7 @@ source "drivers/net/wireless/st/Kconfig" + source "drivers/net/wireless/ti/Kconfig" + source "drivers/net/wireless/zydas/Kconfig" + source "drivers/net/wireless/quantenna/Kconfig" ++source "drivers/net/wireless/esp8089/Kconfig" + + config PCMCIA_RAYCS + tristate "Aviator/Raytheon 2.4GHz wireless support" +diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile +index a61cf6c90343..92ffd2cef51c 100644 +--- a/drivers/net/wireless/Makefile ++++ b/drivers/net/wireless/Makefile +@@ -22,6 +22,7 @@ obj-$(CONFIG_WLAN_VENDOR_SILABS) += silabs/ + obj-$(CONFIG_WLAN_VENDOR_ST) += st/ + obj-$(CONFIG_WLAN_VENDOR_TI) += ti/ + obj-$(CONFIG_WLAN_VENDOR_ZYDAS) += zydas/ ++obj-$(CONFIG_ESP8089) += esp8089/ + + # 16-bit wireless PCMCIA client drivers + obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o +diff --git a/drivers/net/wireless/esp8089/.gitignore b/drivers/net/wireless/esp8089/.gitignore +new file mode 100644 +index 000000000000..eae6529085d0 +--- /dev/null ++++ b/drivers/net/wireless/esp8089/.gitignore +@@ -0,0 +1,7 @@ ++*.cmd ++*.o ++Module.symvers ++modules.order ++.tmp_versions ++*.ko ++*.mod.c +diff --git a/drivers/net/wireless/esp8089/Kconfig b/drivers/net/wireless/esp8089/Kconfig +new file mode 100644 +index 000000000000..8db1fc54712d +--- /dev/null ++++ b/drivers/net/wireless/esp8089/Kconfig +@@ -0,0 +1,13 @@ ++config ESP8089 ++ tristate "Espressif ESP8089 SDIO WiFi" ++ depends on MAC80211 ++ help ++ ESP8089 is a low-budget 2.4GHz WiFi chip by Espressif, used in many ++ cheap tablets with Allwinner or Rockchip SoC ++ ++config ESP8089_DEBUG_FS ++ bool "Enable DebugFS support for ESP8089" ++ depends on ESP8089 ++ default y ++ help ++ DebugFS support for ESP8089 +diff --git a/drivers/net/wireless/esp8089/LICENSE b/drivers/net/wireless/esp8089/LICENSE +new file mode 100644 +index 000000000000..d6a93266f748 +--- /dev/null ++++ b/drivers/net/wireless/esp8089/LICENSE +@@ -0,0 +1,340 @@ ++GNU GENERAL PUBLIC LICENSE ++ Version 2, June 1991 ++ ++ Copyright (C) 1989, 1991 Free Software Foundation, Inc., ++ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ Everyone is permitted to copy and distribute verbatim copies ++ of this license document, but changing it is not allowed. ++ ++ Preamble ++ ++ The licenses for most software are designed to take away your ++freedom to share and change it. By contrast, the GNU General Public ++License is intended to guarantee your freedom to share and change free ++software--to make sure the software is free for all its users. This ++General Public License applies to most of the Free Software ++Foundation's software and to any other program whose authors commit to ++using it. (Some other Free Software Foundation software is covered by ++the GNU Lesser General Public License instead.) You can apply it to ++your programs, too. ++ ++ When we speak of free software, we are referring to freedom, not ++price. Our General Public Licenses are designed to make sure that you ++have the freedom to distribute copies of free software (and charge for ++this service if you wish), that you receive source code or can get it ++if you want it, that you can change the software or use pieces of it ++in new free programs; and that you know you can do these things. ++ ++ To protect your rights, we need to make restrictions that forbid ++anyone to deny you these rights or to ask you to surrender the rights. ++These restrictions translate to certain responsibilities for you if you ++distribute copies of the software, or if you modify it. ++ ++ For example, if you distribute copies of such a program, whether ++gratis or for a fee, you must give the recipients all the rights that ++you have. You must make sure that they, too, receive or can get the ++source code. And you must show them these terms so they know their ++rights. ++ ++ We protect your rights with two steps: (1) copyright the software, and ++(2) offer you this license which gives you legal permission to copy, ++distribute and/or modify the software. ++ ++ Also, for each author's protection and ours, we want to make certain ++that everyone understands that there is no warranty for this free ++software. If the software is modified by someone else and passed on, we ++want its recipients to know that what they have is not the original, so ++that any problems introduced by others will not reflect on the original ++authors' reputations. ++ ++ Finally, any free program is threatened constantly by software ++patents. We wish to avoid the danger that redistributors of a free ++program will individually obtain patent licenses, in effect making the ++program proprietary. To prevent this, we have made it clear that any ++patent must be licensed for everyone's free use or not licensed at all. ++ ++ The precise terms and conditions for copying, distribution and ++modification follow. ++ ++ GNU GENERAL PUBLIC LICENSE ++ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION ++ ++ 0. This License applies to any program or other work which contains ++a notice placed by the copyright holder saying it may be distributed ++under the terms of this General Public License. The "Program", below, ++refers to any such program or work, and a "work based on the Program" ++means either the Program or any derivative work under copyright law: ++that is to say, a work containing the Program or a portion of it, ++either verbatim or with modifications and/or translated into another ++language. (Hereinafter, translation is included without limitation in ++the term "modification".) Each licensee is addressed as "you". ++ ++Activities other than copying, distribution and modification are not ++covered by this License; they are outside its scope. The act of ++running the Program is not restricted, and the output from the Program ++is covered only if its contents constitute a work based on the ++Program (independent of having been made by running the Program). ++Whether that is true depends on what the Program does. ++ ++ 1. You may copy and distribute verbatim copies of the Program's ++source code as you receive it, in any medium, provided that you ++conspicuously and appropriately publish on each copy an appropriate ++copyright notice and disclaimer of warranty; keep intact all the ++notices that refer to this License and to the absence of any warranty; ++and give any other recipients of the Program a copy of this License ++along with the Program. ++ ++You may charge a fee for the physical act of transferring a copy, and ++you may at your option offer warranty protection in exchange for a fee. ++ ++ 2. You may modify your copy or copies of the Program or any portion ++of it, thus forming a work based on the Program, and copy and ++distribute such modifications or work under the terms of Section 1 ++above, provided that you also meet all of these conditions: ++ ++ a) You must cause the modified files to carry prominent notices ++ stating that you changed the files and the date of any change. ++ ++ b) You must cause any work that you distribute or publish, that in ++ whole or in part contains or is derived from the Program or any ++ part thereof, to be licensed as a whole at no charge to all third ++ parties under the terms of this License. ++ ++ c) If the modified program normally reads commands interactively ++ when run, you must cause it, when started running for such ++ interactive use in the most ordinary way, to print or display an ++ announcement including an appropriate copyright notice and a ++ notice that there is no warranty (or else, saying that you provide ++ a warranty) and that users may redistribute the program under ++ these conditions, and telling the user how to view a copy of this ++ License. (Exception: if the Program itself is interactive but ++ does not normally print such an announcement, your work based on ++ the Program is not required to print an announcement.) ++ ++These requirements apply to the modified work as a whole. If ++identifiable sections of that work are not derived from the Program, ++and can be reasonably considered independent and separate works in ++themselves, then this License, and its terms, do not apply to those ++sections when you distribute them as separate works. But when you ++distribute the same sections as part of a whole which is a work based ++on the Program, the distribution of the whole must be on the terms of ++this License, whose permissions for other licensees extend to the ++entire whole, and thus to each and every part regardless of who wrote it. ++ ++Thus, it is not the intent of this section to claim rights or contest ++your rights to work written entirely by you; rather, the intent is to ++exercise the right to control the distribution of derivative or ++collective works based on the Program. ++ ++In addition, mere aggregation of another work not based on the Program ++with the Program (or with a work based on the Program) on a volume of ++a storage or distribution medium does not bring the other work under ++the scope of this License. ++ ++ 3. You may copy and distribute the Program (or a work based on it, ++under Section 2) in object code or executable form under the terms of ++Sections 1 and 2 above provided that you also do one of the following: ++ ++ a) Accompany it with the complete corresponding machine-readable ++ source code, which must be distributed under the terms of Sections ++ 1 and 2 above on a medium customarily used for software interchange; or, ++ ++ b) Accompany it with a written offer, valid for at least three ++ years, to give any third party, for a charge no more than your ++ cost of physically performing source distribution, a complete ++ machine-readable copy of the corresponding source code, to be ++ distributed under the terms of Sections 1 and 2 above on a medium ++ customarily used for software interchange; or, ++ ++ c) Accompany it with the information you received as to the offer ++ to distribute corresponding source code. (This alternative is ++ allowed only for noncommercial distribution and only if you ++ received the program in object code or executable form with such ++ an offer, in accord with Subsection b above.) ++ ++The source code for a work means the preferred form of the work for ++making modifications to it. For an executable work, complete source ++code means all the source code for all modules it contains, plus any ++associated interface definition files, plus the scripts used to ++control compilation and installation of the executable. However, as a ++special exception, the source code distributed need not include ++anything that is normally distributed (in either source or binary ++form) with the major components (compiler, kernel, and so on) of the ++operating system on which the executable runs, unless that component ++itself accompanies the executable. ++ ++If distribution of executable or object code is made by offering ++access to copy from a designated place, then offering equivalent ++access to copy the source code from the same place counts as ++distribution of the source code, even though third parties are not ++compelled to copy the source along with the object code. ++ ++ 4. You may not copy, modify, sublicense, or distribute the Program ++except as expressly provided under this License. Any attempt ++otherwise to copy, modify, sublicense or distribute the Program is ++void, and will automatically terminate your rights under this License. ++However, parties who have received copies, or rights, from you under ++this License will not have their licenses terminated so long as such ++parties remain in full compliance. ++ ++ 5. You are not required to accept this License, since you have not ++signed it. However, nothing else grants you permission to modify or ++distribute the Program or its derivative works. These actions are ++prohibited by law if you do not accept this License. Therefore, by ++modifying or distributing the Program (or any work based on the ++Program), you indicate your acceptance of this License to do so, and ++all its terms and conditions for copying, distributing or modifying ++the Program or works based on it. ++ ++ 6. Each time you redistribute the Program (or any work based on the ++Program), the recipient automatically receives a license from the ++original licensor to copy, distribute or modify the Program subject to ++these terms and conditions. You may not impose any further ++restrictions on the recipients' exercise of the rights granted herein. ++You are not responsible for enforcing compliance by third parties to ++this License. ++ ++ 7. If, as a consequence of a court judgment or allegation of patent ++infringement or for any other reason (not limited to patent issues), ++conditions are imposed on you (whether by court order, agreement or ++otherwise) that contradict the conditions of this License, they do not ++excuse you from the conditions of this License. If you cannot ++distribute so as to satisfy simultaneously your obligations under this ++License and any other pertinent obligations, then as a consequence you ++may not distribute the Program at all. For example, if a patent ++license would not permit royalty-free redistribution of the Program by ++all those who receive copies directly or indirectly through you, then ++the only way you could satisfy both it and this License would be to ++refrain entirely from distribution of the Program. ++ ++If any portion of this section is held invalid or unenforceable under ++any particular circumstance, the balance of the section is intended to ++apply and the section as a whole is intended to apply in other ++circumstances. ++ ++It is not the purpose of this section to induce you to infringe any ++patents or other property right claims or to contest validity of any ++such claims; this section has the sole purpose of protecting the ++integrity of the free software distribution system, which is ++implemented by public license practices. Many people have made ++generous contributions to the wide range of software distributed ++through that system in reliance on consistent application of that ++system; it is up to the author/donor to decide if he or she is willing ++to distribute software through any other system and a licensee cannot ++impose that choice. ++ ++This section is intended to make thoroughly clear what is believed to ++be a consequence of the rest of this License. ++ ++ 8. If the distribution and/or use of the Program is restricted in ++certain countries either by patents or by copyrighted interfaces, the ++original copyright holder who places the Program under this License ++may add an explicit geographical distribution limitation excluding ++those countries, so that distribution is permitted only in or among ++countries not thus excluded. In such case, this License incorporates ++the limitation as if written in the body of this License. ++ ++ 9. The Free Software Foundation may publish revised and/or new versions ++of the General Public License from time to time. Such new versions will ++be similar in spirit to the present version, but may differ in detail to ++address new problems or concerns. ++ ++Each version is given a distinguishing version number. If the Program ++specifies a version number of this License which applies to it and "any ++later version", you have the option of following the terms and conditions ++either of that version or of any later version published by the Free ++Software Foundation. If the Program does not specify a version number of ++this License, you may choose any version ever published by the Free Software ++Foundation. ++ ++ 10. If you wish to incorporate parts of the Program into other free ++programs whose distribution conditions are different, write to the author ++to ask for permission. For software which is copyrighted by the Free ++Software Foundation, write to the Free Software Foundation; we sometimes ++make exceptions for this. Our decision will be guided by the two goals ++of preserving the free status of all derivatives of our free software and ++of promoting the sharing and reuse of software generally. ++ ++ NO WARRANTY ++ ++ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY ++FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN ++OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES ++PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED ++OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS ++TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE ++PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, ++REPAIR OR CORRECTION. ++ ++ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING ++WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR ++REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, ++INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING ++OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED ++TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY ++YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER ++PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE ++POSSIBILITY OF SUCH DAMAGES. ++ ++ END OF TERMS AND CONDITIONS ++ ++ How to Apply These Terms to Your New Programs ++ ++ If you develop a new program, and you want it to be of the greatest ++possible use to the public, the best way to achieve this is to make it ++free software which everyone can redistribute and change under these terms. ++ ++ To do so, attach the following notices to the program. It is safest ++to attach them to the start of each source file to most effectively ++convey the exclusion of warranty; and each file should have at least ++the "copyright" line and a pointer to where the full notice is found. ++ ++ {description} ++ Copyright (C) {year} {fullname} ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License along ++ with this program; if not, write to the Free Software Foundation, Inc., ++ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ ++Also add information on how to contact you by electronic and paper mail. ++ ++If the program is interactive, make it output a short notice like this ++when it starts in an interactive mode: ++ ++ Gnomovision version 69, Copyright (C) year name of author ++ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. ++ This is free software, and you are welcome to redistribute it ++ under certain conditions; type `show c' for details. ++ ++The hypothetical commands `show w' and `show c' should show the appropriate ++parts of the General Public License. Of course, the commands you use may ++be called something other than `show w' and `show c'; they could even be ++mouse-clicks or menu items--whatever suits your program. ++ ++You should also get your employer (if you work as a programmer) or your ++school, if any, to sign a "copyright disclaimer" for the program, if ++necessary. Here is a sample; alter the names: ++ ++ Yoyodyne, Inc., hereby disclaims all copyright interest in the program ++ `Gnomovision' (which makes passes at compilers) written by James Hacker. ++ ++ {signature of Ty Coon}, 1 April 1989 ++ Ty Coon, President of Vice ++ ++This General Public License does not permit incorporating your program into ++proprietary programs. If your program is a subroutine library, you may ++consider it more useful to permit linking proprietary applications with the ++library. If this is what you want to do, use the GNU Lesser General ++Public License instead of this License. ++ +diff --git a/drivers/net/wireless/esp8089/Makefile b/drivers/net/wireless/esp8089/Makefile +new file mode 100644 +index 000000000000..36decfd20ecd +--- /dev/null ++++ b/drivers/net/wireless/esp8089/Makefile +@@ -0,0 +1,7 @@ ++MODULE_NAME = esp8089 ++ ++$(MODULE_NAME)-y := esp_debug.o sdio_sif_esp.o esp_io.o \ ++ esp_file.o esp_main.o esp_sip.o esp_ext.o esp_ctrl.o \ ++ esp_mac80211.o esp_debug.o esp_utils.o ++ ++obj-$(CONFIG_ESP8089) := esp8089.o +diff --git a/drivers/net/wireless/esp8089/Makefile.old b/drivers/net/wireless/esp8089/Makefile.old +new file mode 100644 +index 000000000000..b7b1a47b159c +--- /dev/null ++++ b/drivers/net/wireless/esp8089/Makefile.old +@@ -0,0 +1,99 @@ ++MODNAME = esp8089 ++ ++# By default, we try to compile the modules for the currently running ++# kernel. But it's the first approximation, as we will re-read the ++# version from the kernel sources. ++KVERS_UNAME ?= $(shell uname -r) ++ ++# KBUILD is the path to the Linux kernel build tree. It is usually the ++# same as the kernel source tree, except when the kernel was compiled in ++# a separate directory. ++KBUILD ?= $(shell readlink -f /lib/modules/$(KVERS_UNAME)/build) ++ ++ifeq (,$(KBUILD)) ++$(error Kernel build tree not found - please set KBUILD to configured kernel) ++endif ++ ++KCONFIG := $(KBUILD)/.config ++ifeq (,$(wildcard $(KCONFIG))) ++$(error No .config found in $(KBUILD), please set KBUILD to configured kernel) ++endif ++ ++ifneq (,$(wildcard $(KBUILD)/include/linux/version.h)) ++ifneq (,$(wildcard $(KBUILD)/include/generated/uapi/linux/version.h)) ++$(error Multiple copies of version.h found, please clean your build tree) ++endif ++endif ++ ++# Kernel Makefile doesn't always know the exact kernel version, so we ++# get it from the kernel headers instead and pass it to make. ++VERSION_H := $(KBUILD)/include/generated/utsrelease.h ++ifeq (,$(wildcard $(VERSION_H))) ++VERSION_H := $(KBUILD)/include/linux/utsrelease.h ++endif ++ifeq (,$(wildcard $(VERSION_H))) ++VERSION_H := $(KBUILD)/include/linux/version.h ++endif ++ifeq (,$(wildcard $(VERSION_H))) ++$(error Please run 'make modules_prepare' in $(KBUILD)) ++endif ++ ++KVERS := $(shell sed -ne 's/"//g;s/^\#define UTS_RELEASE //p' $(VERSION_H)) ++ ++ifeq (,$(KVERS)) ++$(error Cannot find UTS_RELEASE in $(VERSION_H), please report) ++endif ++ ++INST_DIR = /lib/modules/$(KVERS)/misc ++ ++SRC_DIR=$(shell pwd) ++ ++include $(KCONFIG) ++ ++EXTRA_CFLAGS += -DCONFIG_ESP8089_DEBUG_FS ++ ++OBJS = esp_debug.o sdio_sif_esp.o esp_io.o \ ++ esp_file.o esp_main.o esp_sip.o esp_ext.o esp_ctrl.o \ ++ esp_mac80211.o esp_debug.o esp_utils.o esp_pm.o ++ ++all: config_check modules ++ ++MODULE := $(MODNAME).ko ++obj-m := $(MODNAME).o ++ ++$(MODNAME)-objs := $(OBJS) ++ ++config_check: ++ @if [ -z "$(CONFIG_WIRELESS_EXT)$(CONFIG_NET_RADIO)" ]; then \ ++ echo; echo; \ ++ echo "*** WARNING: This kernel lacks wireless extensions."; \ ++ echo "Wireless drivers will not work properly."; \ ++ echo; echo; \ ++ fi ++ ++modules: ++ $(MAKE) -C $(KBUILD) M=$(SRC_DIR) ++ ++$(MODULE): ++ $(MAKE) modules ++ ++clean: ++ rm -f *.o *.ko .*.cmd *.mod.c *.symvers modules.order ++ rm -rf .tmp_versions ++ ++install: config_check $(MODULE) ++ @/sbin/modinfo $(MODULE) | grep -q "^vermagic: *$(KVERS) " || \ ++ { echo "$(MODULE)" is not for Linux $(KVERS); exit 1; } ++ mkdir -p -m 755 $(DESTDIR)$(INST_DIR) ++ install -m 0644 $(MODULE) $(DESTDIR)$(INST_DIR) ++ifndef DESTDIR ++ -/sbin/depmod -a $(KVERS) ++endif ++ ++uninstall: ++ rm -f $(DESTDIR)$(INST_DIR)/$(MODULE) ++ifndef DESTDIR ++ -/sbin/depmod -a $(KVERS) ++endif ++ ++.PHONY: all modules clean install config_check +diff --git a/drivers/net/wireless/esp8089/README.md b/drivers/net/wireless/esp8089/README.md +new file mode 100644 +index 000000000000..56b40db272f3 +--- /dev/null ++++ b/drivers/net/wireless/esp8089/README.md +@@ -0,0 +1,31 @@ ++esp8089 ++====== ++ ++ESP8089 Linux driver ++ ++v1.9 imported from the Rockchip Linux kernel github repo ++ ++Modified to build as a standalone module for SDIO devices. ++ ++ ++ ++ ++Building: ++ ++ make ++ ++Using: ++ ++Must load mac80211.ko first if not baked in. ++ ++ sudo modprobe esp8089.ko ++ ++If you get a wlan interface, but scanning shows no networks try using: ++ ++ sudo modprobe esp8089.ko config=crystal_26M_en=1 ++ ++or: ++ ++ sudo modprobe esp8089.ko config=crystal_26M_en=2 ++ ++To load the module. +diff --git a/drivers/net/wireless/esp8089/esp_ctrl.c b/drivers/net/wireless/esp8089/esp_ctrl.c +new file mode 100644 +index 000000000000..a19d2437dd82 +--- /dev/null ++++ b/drivers/net/wireless/esp8089/esp_ctrl.c +@@ -0,0 +1,801 @@ ++/* ++ * Copyright (c) 2009 - 2014 Espressif System. ++ * ++ * SIP ctrl packet parse and pack ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "esp_pub.h" ++#include "esp_sip.h" ++#include "esp_ctrl.h" ++#include "esp_sif.h" ++#include "esp_debug.h" ++#include "esp_wmac.h" ++#include "esp_utils.h" ++#include "esp_wl.h" ++#include "esp_file.h" ++#include "esp_path.h" ++#ifdef TEST_MODE ++#include "testmode.h" ++#endif /* TEST_MODE */ ++#include "esp_version.h" ++ ++extern struct completion *gl_bootup_cplx; ++ ++static void esp_tx_ba_session_op(struct esp_sip *sip, ++ struct esp_node *node, ++ trc_ampdu_state_t state, u8 tid) ++{ ++ struct esp_tx_tid *txtid; ++ ++ txtid = &node->tid[tid]; ++ if (state == TRC_TX_AMPDU_STOPPED) { ++ if (txtid->state == ESP_TID_STATE_OPERATIONAL) { ++ esp_dbg(ESP_DBG_TXAMPDU, ++ "%s tid %d TXAMPDU GOT STOP EVT\n", ++ __func__, tid); ++ ++ spin_lock_bh(&sip->epub->tx_ampdu_lock); ++ txtid->state = ESP_TID_STATE_WAIT_STOP; ++ spin_unlock_bh(&sip->epub->tx_ampdu_lock); ++ ieee80211_stop_tx_ba_session(node->sta, (u16) tid); ++ } else { ++ esp_dbg(ESP_DBG_TXAMPDU, ++ "%s tid %d TXAMPDU GOT STOP EVT IN WRONG STATE %d\n", ++ __func__, tid, txtid->state); ++ } ++ } else if (state == TRC_TX_AMPDU_OPERATIONAL) { ++ if (txtid->state == ESP_TID_STATE_STOP) { ++ esp_dbg(ESP_DBG_TXAMPDU, ++ "%s tid %d TXAMPDU GOT OPERATIONAL\n", ++ __func__, tid); ++ ++ spin_lock_bh(&sip->epub->tx_ampdu_lock); ++ txtid->state = ESP_TID_STATE_TRIGGER; ++ spin_unlock_bh(&sip->epub->tx_ampdu_lock); ++ ieee80211_start_tx_ba_session(node->sta, (u16) tid, ++ 0); ++ ++ } else if (txtid->state == ESP_TID_STATE_OPERATIONAL) { ++ sip_send_ampdu_action(sip->epub, ++ SIP_AMPDU_TX_OPERATIONAL, ++ node->sta->addr, tid, ++ node->ifidx, 0); ++ } else { ++ esp_dbg(ESP_DBG_TXAMPDU, ++ "%s tid %d TXAMPDU GOT OPERATIONAL EVT IN WRONG STATE %d\n", ++ __func__, tid, txtid->state); ++ } ++ } ++} ++ ++int sip_parse_events(struct esp_sip *sip, u8 * buf) ++{ ++ struct sip_hdr *hdr = (struct sip_hdr *) buf; ++ ++ switch (hdr->c_evtid) { ++ case SIP_EVT_TARGET_ON:{ ++ /* use rx work queue to send... */ ++ if (atomic_read(&sip->state) == SIP_PREPARE_BOOT ++ || atomic_read(&sip->state) == SIP_BOOT) { ++ atomic_set(&sip->state, SIP_SEND_INIT); ++ queue_work(sip->epub->esp_wkq, ++ &sip->rx_process_work); ++ } else { ++ esp_dbg(ESP_DBG_ERROR, ++ "%s boot during wrong state %d\n", ++ __func__, ++ atomic_read(&sip->state)); ++ } ++ break; ++ } ++ ++ case SIP_EVT_BOOTUP:{ ++ struct sip_evt_bootup2 *bootup_evt = ++ (struct sip_evt_bootup2 *) (buf + ++ SIP_CTRL_HDR_LEN); ++ if (sip->rawbuf) ++ kfree(sip->rawbuf); ++ ++ sip_post_init(sip, bootup_evt); ++ ++ if (gl_bootup_cplx) ++ complete(gl_bootup_cplx); ++ ++ break; ++ } ++ case SIP_EVT_RESETTING:{ ++ sip->epub->wait_reset = 1; ++ if (gl_bootup_cplx) ++ complete(gl_bootup_cplx); ++ break; ++ } ++ case SIP_EVT_SLEEP:{ ++ //atomic_set(&sip->epub->ps.state, ESP_PM_ON); ++ break; ++ } ++ case SIP_EVT_TXIDLE:{ ++ //struct sip_evt_txidle *txidle = (struct sip_evt_txidle *)(buf + SIP_CTRL_HDR_LEN); ++ //sip_txdone_clear(sip, txidle->last_seq); ++ break; ++ } ++ ++ case SIP_EVT_SCAN_RESULT:{ ++ struct sip_evt_scan_report *report = ++ (struct sip_evt_scan_report *) (buf + ++ SIP_CTRL_HDR_LEN); ++ if (atomic_read(&sip->epub->wl.off)) { ++ esp_dbg(ESP_DBG_ERROR, ++ "%s scan result while wlan off\n", ++ __func__); ++ return 0; ++ } ++ sip_scandone_process(sip, report); ++ ++ break; ++ } ++ ++ case SIP_EVT_ROC:{ ++ struct sip_evt_roc *report = ++ (struct sip_evt_roc *) (buf + ++ SIP_CTRL_HDR_LEN); ++ esp_rocdone_process(sip->epub->hw, report); ++ break; ++ } ++ ++ ++#ifdef ESP_RX_COPYBACK_TEST ++ ++ case SIP_EVT_COPYBACK:{ ++ u32 len = hdr->len - SIP_CTRL_HDR_LEN; ++ ++ esp_dbg(ESP_DBG_TRACE, ++ "%s copyback len %d seq %u\n", __func__, ++ len, hdr->seq); ++ ++ memcpy(copyback_buf + copyback_offset, ++ pkt->buf + SIP_CTRL_HDR_LEN, len); ++ copyback_offset += len; ++ ++ //show_buf(pkt->buf, 256); ++ ++ //how about totlen % 256 == 0?? ++ if (hdr->hdr.len < 256) { ++ kfree(copyback_buf); ++ } ++ } ++ break; ++#endif /* ESP_RX_COPYBACK_TEST */ ++ case SIP_EVT_CREDIT_RPT: ++ break; ++ ++#ifdef TEST_MODE ++ case SIP_EVT_WAKEUP:{ ++ u8 check_str[12]; ++ struct sip_evt_wakeup *wakeup_evt = ++ (struct sip_evt_wakeup *) (buf + ++ SIP_CTRL_HDR_LEN); ++ sprintf((char *) &check_str, "%d", ++ wakeup_evt->check_data); ++ esp_test_cmd_event(TEST_CMD_WAKEUP, ++ (char *) &check_str); ++ break; ++ } ++ ++ case SIP_EVT_DEBUG:{ ++ u8 check_str[640]; ++ sip_parse_event_debug(sip->epub, buf, check_str); ++ esp_dbg(ESP_DBG_TRACE, "%s", check_str); ++ esp_test_cmd_event(TEST_CMD_DEBUG, ++ (char *) &check_str); ++ break; ++ } ++ ++ case SIP_EVT_LOOPBACK:{ ++ u8 check_str[12]; ++ struct sip_evt_loopback *loopback_evt = ++ (struct sip_evt_loopback *) (buf + ++ SIP_CTRL_HDR_LEN); ++ esp_dbg(ESP_DBG_LOG, "%s loopback len %d seq %u\n", ++ __func__, hdr->len, hdr->seq); ++ ++ if (loopback_evt->pack_id != get_loopback_id()) { ++ sprintf((char *) &check_str, ++ "seq id error %d, expect %d", ++ loopback_evt->pack_id, ++ get_loopback_id()); ++ esp_test_cmd_event(TEST_CMD_LOOPBACK, ++ (char *) &check_str); ++ } ++ ++ if ((loopback_evt->pack_id + 1) < ++ get_loopback_num()) { ++ inc_loopback_id(); ++ sip_send_loopback_mblk(sip, ++ loopback_evt->txlen, ++ loopback_evt->rxlen, ++ get_loopback_id()); ++ } else { ++ sprintf((char *) &check_str, "test over!"); ++ esp_test_cmd_event(TEST_CMD_LOOPBACK, ++ (char *) &check_str); ++ } ++ break; ++ } ++#endif /*TEST_MODE */ ++ ++ case SIP_EVT_SNPRINTF_TO_HOST:{ ++ u8 *p = ++ (buf + sizeof(struct sip_hdr) + sizeof(u16)); ++ u16 *len = (u16 *) (buf + sizeof(struct sip_hdr)); ++ char test_res_str[560]; ++ sprintf(test_res_str, ++ "esp_host:%llx\nesp_target: %.*s", ++ DRIVER_VER, *len, p); ++ ++ esp_dbg(ESP_DBG_TRACE, "%s\n", test_res_str); ++ if (*len ++ && sip->epub->sdio_state == ++ ESP_SDIO_STATE_FIRST_INIT) { ++ char filename[256]; ++ if (mod_eagle_path_get() == NULL) ++ sprintf(filename, "%s/%s", FWPATH, ++ "test_results"); ++ else ++ sprintf(filename, "%s/%s", ++ mod_eagle_path_get(), ++ "test_results"); ++ esp_dbg(ESP_DBG_TRACE, ++ "SNPRINTF TO HOST: %s\n", ++ test_res_str); ++ } ++ break; ++ } ++ case SIP_EVT_TRC_AMPDU:{ ++ struct sip_evt_trc_ampdu *ep = ++ (struct sip_evt_trc_ampdu *) (buf + ++ SIP_CTRL_HDR_LEN); ++ struct esp_node *node = NULL; ++ int i = 0; ++ ++ if (atomic_read(&sip->epub->wl.off)) { ++ esp_dbg(ESP_DBG_ERROR, ++ "%s scan result while wlan off\n", ++ __func__); ++ return 0; ++ } ++ ++ node = esp_get_node_by_addr(sip->epub, ep->addr); ++ if (node == NULL) ++ break; ++ for (i = 0; i < 8; i++) { ++ if (ep->tid & (1 << i)) { ++ esp_tx_ba_session_op(sip, node, ++ ep->state, i); ++ } ++ } ++ break; ++ } ++ ++#ifdef TEST_MODE ++ case SIP_EVT_EP:{ ++ char *ep = (char *) (buf + SIP_CTRL_HDR_LEN); ++ static int counter = 0; ++ ++ esp_dbg(ESP_ATE, "%s EVT_EP \n\n", __func__); ++ if (counter++ < 2) { ++ esp_dbg(ESP_ATE, "ATE: %s \n", ep); ++ } ++ ++ esp_test_ate_done_cb(ep); ++ ++ break; ++ } ++#endif /*TEST_MODE */ ++ ++ case SIP_EVT_INIT_EP:{ ++ char *ep = (char *) (buf + SIP_CTRL_HDR_LEN); ++ esp_dbg(ESP_ATE, "Phy Init: %s \n", ep); ++ break; ++ } ++ ++ case SIP_EVT_NOISEFLOOR:{ ++ struct sip_evt_noisefloor *ep = ++ (struct sip_evt_noisefloor *) (buf + ++ SIP_CTRL_HDR_LEN); ++ atomic_set(&sip->noise_floor, ep->noise_floor); ++ break; ++ } ++ default: ++ break; ++ } ++ ++ return 0; ++} ++ ++#include "esp_init_data.h" ++ ++void sip_send_chip_init(struct esp_sip *sip) ++{ ++ size_t size = 0; ++ size = sizeof(esp_init_data); ++ ++ esp_conf_upload_second(esp_init_data, size); ++ ++ atomic_sub(1, &sip->tx_credits); ++ ++ sip_send_cmd(sip, SIP_CMD_INIT, size, (void *) esp_init_data); ++ ++} ++ ++int sip_send_config(struct esp_pub *epub, struct ieee80211_conf *conf) ++{ ++ struct sk_buff *skb = NULL; ++ struct sip_cmd_config *configcmd; ++ ++ skb = ++ sip_alloc_ctrl_skbuf(epub->sip, ++ sizeof(struct sip_cmd_config) + ++ sizeof(struct sip_hdr), SIP_CMD_CONFIG); ++ if (!skb) ++ return -EINVAL; ++ esp_dbg(ESP_DBG_TRACE, "%s config center freq %d\n", __func__, ++ conf->chandef.chan->center_freq); ++ configcmd = ++ (struct sip_cmd_config *) (skb->data + sizeof(struct sip_hdr)); ++ configcmd->center_freq = conf->chandef.chan->center_freq; ++ configcmd->duration = 0; ++ return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL); ++} ++ ++int sip_send_bss_info_update(struct esp_pub *epub, struct esp_vif *evif, ++ u8 * bssid, int assoc) ++{ ++ struct sk_buff *skb = NULL; ++ struct sip_cmd_bss_info_update *bsscmd; ++ ++ skb = ++ sip_alloc_ctrl_skbuf(epub->sip, ++ sizeof(struct sip_cmd_bss_info_update) + ++ sizeof(struct sip_hdr), ++ SIP_CMD_BSS_INFO_UPDATE); ++ if (!skb) ++ return -EINVAL; ++ ++ bsscmd = ++ (struct sip_cmd_bss_info_update *) (skb->data + ++ sizeof(struct sip_hdr)); ++ if (assoc == 2) { //hack for softAP mode ++ bsscmd->beacon_int = evif->beacon_interval; ++ } else if (assoc == 1) { ++ set_bit(ESP_WL_FLAG_CONNECT, &epub->wl.flags); ++ } else { ++ clear_bit(ESP_WL_FLAG_CONNECT, &epub->wl.flags); ++ } ++ bsscmd->bssid_no = evif->index; ++ bsscmd->isassoc = assoc; ++ bsscmd->beacon_int = evif->beacon_interval; ++ memcpy(bsscmd->bssid, bssid, ETH_ALEN); ++ return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL); ++} ++ ++int sip_send_wmm_params(struct esp_pub *epub, u8 aci, ++ const struct ieee80211_tx_queue_params *params) ++{ ++ struct sk_buff *skb = NULL; ++ struct sip_cmd_set_wmm_params *bsscmd; ++ skb = ++ sip_alloc_ctrl_skbuf(epub->sip, ++ sizeof(struct sip_cmd_set_wmm_params) + ++ sizeof(struct sip_hdr), ++ SIP_CMD_SET_WMM_PARAM); ++ if (!skb) ++ return -EINVAL; ++ ++ bsscmd = ++ (struct sip_cmd_set_wmm_params *) (skb->data + ++ sizeof(struct sip_hdr)); ++ bsscmd->aci = aci; ++ bsscmd->aifs = params->aifs; ++ bsscmd->txop_us = params->txop * 32; ++ ++ bsscmd->ecw_min = 32 - __builtin_clz(params->cw_min); ++ bsscmd->ecw_max = 32 - __builtin_clz(params->cw_max); ++ ++ return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL); ++} ++ ++int sip_send_ampdu_action(struct esp_pub *epub, u8 action_num, ++ const u8 * addr, u16 tid, u16 ssn, u8 buf_size) ++{ ++ int index = 0; ++ struct sk_buff *skb = NULL; ++ struct sip_cmd_ampdu_action *action; ++ if (action_num == SIP_AMPDU_RX_START) { ++ index = esp_get_empty_rxampdu(epub, addr, tid); ++ } else if (action_num == SIP_AMPDU_RX_STOP) { ++ index = esp_get_exist_rxampdu(epub, addr, tid); ++ } ++ if (index < 0) ++ return -EACCES; ++ skb = ++ sip_alloc_ctrl_skbuf(epub->sip, ++ sizeof(struct sip_cmd_ampdu_action) + ++ sizeof(struct sip_hdr), ++ SIP_CMD_AMPDU_ACTION); ++ if (!skb) ++ return -EINVAL; ++ ++ action = ++ (struct sip_cmd_ampdu_action *) (skb->data + ++ sizeof(struct sip_hdr)); ++ action->action = action_num; ++ //for TX, it means interface index ++ action->index = ssn; ++ ++ switch (action_num) { ++ case SIP_AMPDU_RX_START: ++ action->ssn = ssn; ++ // fall through ++ case SIP_AMPDU_RX_STOP: ++ action->index = index; ++ // fall through ++ case SIP_AMPDU_TX_OPERATIONAL: ++ case SIP_AMPDU_TX_STOP: ++ action->win_size = buf_size; ++ action->tid = tid; ++ memcpy(action->addr, addr, ETH_ALEN); ++ break; ++ } ++ ++ return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL); ++} ++ ++#ifdef HW_SCAN ++/*send cmd to target, if aborted is true, inform target stop scan, report scan complete imediately ++ return 1: complete over, 0: success, still have next scan, -1: hardware failure ++ */ ++int sip_send_scan(struct esp_pub *epub) ++{ ++ struct cfg80211_scan_request *scan_req = epub->wl.scan_req; ++ struct sk_buff *skb = NULL; ++ struct sip_cmd_scan *scancmd; ++ u8 *ptr = NULL; ++ int i; ++ u8 append_len, ssid_len; ++ ++ ESSERT(scan_req != NULL); ++ ssid_len = scan_req->n_ssids == 0 ? 0 : ++ (scan_req->n_ssids == ++ 1 ? scan_req->ssids->ssid_len : scan_req->ssids->ssid_len + ++ (scan_req->ssids + 1)->ssid_len); ++ append_len = ssid_len + scan_req->n_channels + scan_req->ie_len; ++ ++ skb = ++ sip_alloc_ctrl_skbuf(epub->sip, ++ sizeof(struct sip_cmd_scan) + ++ sizeof(struct sip_hdr) + append_len, ++ SIP_CMD_SCAN); ++ ++ if (!skb) ++ return -EINVAL; ++ ++ ptr = skb->data; ++ scancmd = (struct sip_cmd_scan *) (ptr + sizeof(struct sip_hdr)); ++ ptr += sizeof(struct sip_hdr); ++ ++ scancmd->aborted = false; ++ ++ if (scancmd->aborted == false) { ++ ptr += sizeof(struct sip_cmd_scan); ++ if (scan_req->n_ssids <= 0 ++ || (scan_req->n_ssids == 1 && ssid_len == 0)) { ++ scancmd->ssid_len = 0; ++ } else { ++ scancmd->ssid_len = ssid_len; ++ if (scan_req->ssids->ssid_len == ssid_len) ++ memcpy(ptr, scan_req->ssids->ssid, ++ scancmd->ssid_len); ++ else ++ memcpy(ptr, (scan_req->ssids + 1)->ssid, ++ scancmd->ssid_len); ++ } ++ ++ ptr += scancmd->ssid_len; ++ scancmd->n_channels = scan_req->n_channels; ++ for (i = 0; i < scan_req->n_channels; i++) ++ ptr[i] = scan_req->channels[i]->hw_value; ++ ++ ptr += scancmd->n_channels; ++ if (scan_req->ie_len && scan_req->ie != NULL) { ++ scancmd->ie_len = scan_req->ie_len; ++ memcpy(ptr, scan_req->ie, scan_req->ie_len); ++ } else { ++ scancmd->ie_len = 0; ++ } ++ //add a flag that support two ssids, ++ if (scan_req->n_ssids > 1) ++ scancmd->ssid_len |= 0x80; ++ ++ } ++ ++ return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL); ++} ++#endif ++ ++int sip_send_suspend_config(struct esp_pub *epub, u8 suspend) ++{ ++ struct sip_cmd_suspend *cmd = NULL; ++ struct sk_buff *skb = NULL; ++ ++ skb = ++ sip_alloc_ctrl_skbuf(epub->sip, ++ sizeof(struct sip_cmd_suspend) + ++ sizeof(struct sip_hdr), SIP_CMD_SUSPEND); ++ ++ if (!skb) ++ return -EINVAL; ++ ++ cmd = ++ (struct sip_cmd_suspend *) (skb->data + ++ sizeof(struct sip_hdr)); ++ cmd->suspend = suspend; ++ return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL); ++} ++ ++int sip_send_ps_config(struct esp_pub *epub, struct esp_ps *ps) ++{ ++ struct sip_cmd_ps *pscmd = NULL; ++ struct sk_buff *skb = NULL; ++ struct sip_hdr *shdr = NULL; ++ ++ skb = ++ sip_alloc_ctrl_skbuf(epub->sip, ++ sizeof(struct sip_cmd_ps) + ++ sizeof(struct sip_hdr), SIP_CMD_PS); ++ ++ if (!skb) ++ return -EINVAL; ++ ++ ++ shdr = (struct sip_hdr *) skb->data; ++ pscmd = (struct sip_cmd_ps *) (skb->data + sizeof(struct sip_hdr)); ++ ++ pscmd->dtim_period = ps->dtim_period; ++ pscmd->max_sleep_period = ps->max_sleep_period; ++ ++ return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL); ++} ++ ++void sip_scandone_process(struct esp_sip *sip, ++ struct sip_evt_scan_report *scan_report) ++{ ++ struct esp_pub *epub = sip->epub; ++ ++ esp_dbg(ESP_DBG_TRACE, "eagle hw scan report\n"); ++ ++ if (epub->wl.scan_req) { ++ hw_scan_done(epub, scan_report->aborted); ++ epub->wl.scan_req = NULL; ++ } ++} ++ ++int sip_send_setkey(struct esp_pub *epub, u8 bssid_no, u8 * peer_addr, ++ struct ieee80211_key_conf *key, u8 isvalid) ++{ ++ struct sip_cmd_setkey *setkeycmd; ++ struct sk_buff *skb = NULL; ++ ++ skb = ++ sip_alloc_ctrl_skbuf(epub->sip, ++ sizeof(struct sip_cmd_setkey) + ++ sizeof(struct sip_hdr), SIP_CMD_SETKEY); ++ ++ if (!skb) ++ return -EINVAL; ++ ++ setkeycmd = ++ (struct sip_cmd_setkey *) (skb->data + sizeof(struct sip_hdr)); ++ ++ if (peer_addr) { ++ memcpy(setkeycmd->addr, peer_addr, ETH_ALEN); ++ } else { ++ memset(setkeycmd->addr, 0, ETH_ALEN); ++ } ++ ++ setkeycmd->bssid_no = bssid_no; ++ setkeycmd->hw_key_idx = key->hw_key_idx; ++ ++ if (isvalid) { ++ setkeycmd->alg = esp_cipher2alg(key->cipher); ++ setkeycmd->keyidx = key->keyidx; ++ setkeycmd->keylen = key->keylen; ++ if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { ++ memcpy(setkeycmd->key, key->key, 16); ++ memcpy(setkeycmd->key + 16, key->key + 24, 8); ++ memcpy(setkeycmd->key + 24, key->key + 16, 8); ++ } else { ++ memcpy(setkeycmd->key, key->key, key->keylen); ++ } ++ ++ setkeycmd->flags = 1; ++ } else { ++ setkeycmd->flags = 0; ++ } ++ return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL); ++} ++ ++#ifdef FPGA_LOOPBACK ++#define LOOPBACK_PKT_LEN 200 ++int sip_send_loopback_cmd_mblk(struct esp_sip *sip) ++{ ++ int cnt, ret; ++ ++ for (cnt = 0; cnt < 4; cnt++) { ++ if (0 != ++ (ret = ++ sip_send_loopback_mblk(sip, LOOPBACK_PKT_LEN, ++ LOOPBACK_PKT_LEN, 0))) ++ return ret; ++ } ++ return 0; ++} ++#endif /* FPGA_LOOPBACK */ ++ ++int sip_send_loopback_mblk(struct esp_sip *sip, int txpacket_len, ++ int rxpacket_len, int packet_id) ++{ ++ struct sk_buff *skb = NULL; ++ struct sip_cmd_loopback *cmd; ++ u8 *ptr = NULL; ++ int i, ret; ++ ++ //send 100 loopback pkt ++ if (txpacket_len) ++ skb = ++ sip_alloc_ctrl_skbuf(sip, ++ sizeof(struct sip_cmd_loopback) + ++ sizeof(struct sip_hdr) + ++ txpacket_len, SIP_CMD_LOOPBACK); ++ else ++ skb = ++ sip_alloc_ctrl_skbuf(sip, ++ sizeof(struct sip_cmd_loopback) + ++ sizeof(struct sip_hdr), ++ SIP_CMD_LOOPBACK); ++ ++ if (!skb) ++ return -ENOMEM; ++ ++ ptr = skb->data; ++ cmd = (struct sip_cmd_loopback *) (ptr + sizeof(struct sip_hdr)); ++ ptr += sizeof(struct sip_hdr); ++ cmd->txlen = txpacket_len; ++ cmd->rxlen = rxpacket_len; ++ cmd->pack_id = packet_id; ++ ++ if (txpacket_len) { ++ ptr += sizeof(struct sip_cmd_loopback); ++ /* fill up pkt payload */ ++ for (i = 0; i < txpacket_len; i++) { ++ ptr[i] = i; ++ } ++ } ++ ++ ret = sip_cmd_enqueue(sip, skb, ENQUEUE_PRIOR_TAIL); ++ if (ret < 0) ++ return ret; ++ ++ return 0; ++} ++ ++//remain_on_channel ++int sip_send_roc(struct esp_pub *epub, u16 center_freq, u16 duration) ++{ ++ struct sk_buff *skb = NULL; ++ struct sip_cmd_config *configcmd; ++ ++ skb = ++ sip_alloc_ctrl_skbuf(epub->sip, ++ sizeof(struct sip_cmd_config) + ++ sizeof(struct sip_hdr), SIP_CMD_CONFIG); ++ if (!skb) ++ return -EINVAL; ++ ++ configcmd = ++ (struct sip_cmd_config *) (skb->data + sizeof(struct sip_hdr)); ++ configcmd->center_freq = center_freq; ++ configcmd->duration = duration; ++ return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL); ++} ++ ++int sip_send_set_sta(struct esp_pub *epub, u8 ifidx, u8 set, ++ struct ieee80211_sta *sta, struct ieee80211_vif *vif, ++ u8 index) ++{ ++ struct sk_buff *skb = NULL; ++ struct sip_cmd_setsta *setstacmd; ++ skb = ++ sip_alloc_ctrl_skbuf(epub->sip, ++ sizeof(struct sip_cmd_setsta) + ++ sizeof(struct sip_hdr), SIP_CMD_SETSTA); ++ if (!skb) ++ return -EINVAL; ++ ++ setstacmd = ++ (struct sip_cmd_setsta *) (skb->data + sizeof(struct sip_hdr)); ++ setstacmd->ifidx = ifidx; ++ setstacmd->index = index; ++ setstacmd->set = set; ++ if (sta->aid == 0) ++ setstacmd->aid = vif->cfg.aid; ++ else ++ setstacmd->aid = sta->aid; ++ memcpy(setstacmd->mac, sta->addr, ETH_ALEN); ++ if (set) { ++ if (sta->deflink.ht_cap.ht_supported) { ++ if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ++ setstacmd->phymode = ++ ESP_IEEE80211_T_HT20_S; ++ else ++ setstacmd->phymode = ++ ESP_IEEE80211_T_HT20_L; ++ setstacmd->ampdu_factor = sta->deflink.ht_cap.ampdu_factor; ++ setstacmd->ampdu_density = ++ sta->deflink.ht_cap.ampdu_density; ++ } else { ++ if (sta->deflink.supp_rates[NL80211_BAND_2GHZ] & (~(u32) ++ CONF_HW_BIT_RATE_11B_MASK)) ++ { ++ setstacmd->phymode = ESP_IEEE80211_T_OFDM; ++ } else { ++ setstacmd->phymode = ESP_IEEE80211_T_CCK; ++ } ++ } ++ } ++ return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL); ++} ++ ++int sip_send_recalc_credit(struct esp_pub *epub) ++{ ++ struct sk_buff *skb = NULL; ++ ++ skb = ++ sip_alloc_ctrl_skbuf(epub->sip, 0 + sizeof(struct sip_hdr), ++ SIP_CMD_RECALC_CREDIT); ++ if (!skb) ++ return -ENOMEM; ++ ++ return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_HEAD); ++} ++ ++int sip_cmd(struct esp_pub *epub, enum sip_cmd_id cmd_id, u8 * cmd_buf, ++ u8 cmd_len) ++{ ++ struct sk_buff *skb = NULL; ++ ++ skb = ++ sip_alloc_ctrl_skbuf(epub->sip, ++ cmd_len + sizeof(struct sip_hdr), cmd_id); ++ if (!skb) ++ return -ENOMEM; ++ ++ memcpy(skb->data + sizeof(struct sip_hdr), cmd_buf, cmd_len); ++ ++ return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL); ++} +diff --git a/drivers/net/wireless/esp8089/esp_ctrl.h b/drivers/net/wireless/esp8089/esp_ctrl.h +new file mode 100644 +index 000000000000..29c18caa9ede +--- /dev/null ++++ b/drivers/net/wireless/esp8089/esp_ctrl.h +@@ -0,0 +1,58 @@ ++/* ++ * Copyright (c) 2009- 2014 Espressif System. ++ * ++ * SIP ctrl packet parse and pack ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++#ifndef _ESP_CTRL_H_ ++#define _ESP_CTRL_H_ ++ ++int sip_send_loopback_mblk(struct esp_sip *sip, int txpacket_len, ++ int rxpacket_len, int packet_id); ++ ++int sip_send_config(struct esp_pub *epub, struct ieee80211_conf *conf); ++ ++int sip_send_setkey(struct esp_pub *epub, u8 bssid_no, u8 * peer_addr, ++ struct ieee80211_key_conf *key, u8 isvalid); ++ ++int sip_send_scan(struct esp_pub *epub); ++ ++void sip_scandone_process(struct esp_sip *sip, ++ struct sip_evt_scan_report *scan_report); ++ ++int sip_send_bss_info_update(struct esp_pub *epub, struct esp_vif *evif, ++ u8 * bssid, int assoc); ++ ++int sip_send_wmm_params(struct esp_pub *epub, u8 aci, ++ const struct ieee80211_tx_queue_params *params); ++ ++int sip_send_ampdu_action(struct esp_pub *epub, u8 action_num, ++ const u8 * addr, u16 tid, u16 ssn, u8 buf_size); ++ ++int sip_send_roc(struct esp_pub *epub, u16 center_freq, u16 duration); ++ ++int sip_send_set_sta(struct esp_pub *epub, u8 ifidx, u8 set, ++ struct ieee80211_sta *sta, struct ieee80211_vif *vif, ++ u8 index); ++ ++int sip_send_suspend_config(struct esp_pub *epub, u8 suspend); ++ ++int sip_send_ps_config(struct esp_pub *epub, struct esp_ps *ps); ++ ++int sip_parse_events(struct esp_sip *sip, u8 * buf); ++ ++int sip_send_recalc_credit(struct esp_pub *epub); ++ ++int sip_cmd(struct esp_pub *epub, enum sip_cmd_id cmd_id, u8 * cmd_buf, ++ u8 cmd_len); ++ ++#endif /* _ESP_CTRL_H_ */ +diff --git a/drivers/net/wireless/esp8089/esp_debug.c b/drivers/net/wireless/esp8089/esp_debug.c +new file mode 100644 +index 000000000000..5ce8fd2ebd6b +--- /dev/null ++++ b/drivers/net/wireless/esp8089/esp_debug.c +@@ -0,0 +1,297 @@ ++/* ++ * Copyright (c) 2011-2014 Espressif System. ++ * ++ * esp debug interface ++ * - debugfs ++ * - debug level control ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++ ++#include ++#include "sip2_common.h" ++ ++#include "esp_debug.h" ++ ++#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_ESP8089_DEBUG_FS) ++ ++static struct dentry *esp_debugfs_root = NULL; ++ ++static int esp_debugfs_open(struct inode *inode, struct file *filp) ++{ ++ filp->private_data = inode->i_private; ++ return 0; ++} ++ ++static ssize_t esp_debugfs_read(struct file *filp, char __user * buffer, ++ size_t count, loff_t * ppos) ++{ ++ if (*ppos >= 32) ++ return 0; ++ if (*ppos + count > 32) ++ count = 32 - *ppos; ++ ++ if (copy_to_user(buffer, filp->private_data + *ppos, count)) ++ return -EFAULT; ++ ++ *ppos += count; ++ ++ return count; ++} ++ ++static ssize_t esp_debugfs_write(struct file *filp, ++ const char __user * buffer, size_t count, ++ loff_t * ppos) ++{ ++ if (*ppos >= 32) ++ return 0; ++ if (*ppos + count > 32) ++ count = 32 - *ppos; ++ ++ if (copy_from_user(filp->private_data + *ppos, buffer, count)) ++ return -EFAULT; ++ ++ *ppos += count; ++ ++ return count; ++} ++ ++struct file_operations esp_debugfs_fops = { ++ .owner = THIS_MODULE, ++ .open = esp_debugfs_open, ++ .read = esp_debugfs_read, ++ .write = esp_debugfs_write, ++}; ++ ++ ++void esp_dump_var(const char *name, struct dentry *parent, ++ void *value, esp_type type) ++{ ++ umode_t mode = 0644; ++ ++ if (!esp_debugfs_root) ++ return; ++ ++ if (!parent) ++ parent = esp_debugfs_root; ++ ++ switch (type) { ++ case ESP_U8: ++ debugfs_create_u8(name, mode, parent, (u8 *) value); ++ break; ++ case ESP_U16: ++ debugfs_create_u16(name, mode, parent, (u16 *) value); ++ break; ++ case ESP_U32: ++ debugfs_create_u32(name, mode, parent, (u32 *) value); ++ break; ++ case ESP_U64: ++ debugfs_create_u64(name, mode, parent, (u64 *) value); ++ break; ++ case ESP_BOOL: ++ debugfs_create_bool(name, mode, parent, ++ (bool *) value); ++ break; ++ default: //32 ++ debugfs_create_u32(name, mode, parent, (u32 *) value); ++ } ++ ++ return; ++ ++} ++ ++void esp_dump_array(const char *name, struct dentry *parent, ++ struct debugfs_blob_wrapper *blob) ++{ ++ umode_t mode = 0644; ++ ++ if (!esp_debugfs_root) ++ return; ++ ++ if (!parent) ++ parent = esp_debugfs_root; ++ ++ debugfs_create_blob(name, mode, parent, blob); ++ ++} ++ ++void esp_dump(const char *name, struct dentry *parent, ++ void *data, int size) ++{ ++ umode_t mode = 0644; ++ ++ if (!esp_debugfs_root) ++ return; ++ ++ if (!parent) ++ parent = esp_debugfs_root; ++ ++ debugfs_create_file(name, mode, parent, data, ++ &esp_debugfs_fops); ++ ++} ++ ++struct dentry *esp_debugfs_add_sub_dir(const char *name) ++{ ++ struct dentry *sub_dir = NULL; ++ ++ sub_dir = debugfs_create_dir(name, esp_debugfs_root); ++ ++ if (!sub_dir) ++ goto Fail; ++ ++ return sub_dir; ++ ++ Fail: ++ debugfs_remove_recursive(esp_debugfs_root); ++ esp_debugfs_root = NULL; ++ esp_dbg(ESP_DBG_ERROR, ++ "%s failed, debugfs root removed; dir name: %s\n", ++ __FUNCTION__, name); ++ return NULL; ++ ++} ++ ++int esp_debugfs_init(void) ++{ ++ esp_dbg(ESP_DBG, "esp debugfs init\n"); ++ esp_debugfs_root = debugfs_create_dir("esp_debug", NULL); ++ ++ if (!esp_debugfs_root || IS_ERR_OR_NULL(esp_debugfs_root)) { ++ return -ENOENT; ++ } ++ ++ return 0; ++} ++ ++void esp_debugfs_exit(void) ++{ ++ esp_dbg(ESP_DBG, "esp debugfs exit"); ++ ++ debugfs_remove_recursive(esp_debugfs_root); ++ ++ return; ++} ++ ++#else ++ ++inline struct dentry *esp_dump_var(const char *name, struct dentry *parent, ++ void *value, esp_type type) ++{ ++ return NULL; ++} ++ ++inline struct dentry *esp_dump_array(const char *name, ++ struct dentry *parent, ++ struct debugfs_blob_wrapper *blob) ++{ ++ return NULL; ++} ++ ++inline struct dentry *esp_dump(const char *name, struct dentry *parent, ++ void *data, int size) ++{ ++ return NULL; ++} ++ ++struct dentry *esp_debugfs_add_sub_dir(const char *name) ++{ ++ return NULL; ++} ++ ++inline int esp_debugfs_init(void) ++{ ++ return -EPERM; ++} ++ ++inline void esp_debugfs_exit(void) ++{ ++ ++} ++ ++#endif ++ ++ ++void show_buf(u8 * buf, u32 len) ++{ ++// print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 1, buf, len, true); ++#if 1 ++ int i = 0, j; ++ ++ printk(KERN_INFO "\n++++++++++++++++show rbuf+++++++++++++++\n"); ++ for (i = 0; i < (len / 16); i++) { ++ j = i * 16; ++ printk(KERN_INFO ++ "0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x \n", ++ buf[j], buf[j + 1], buf[j + 2], buf[j + 3], ++ buf[j + 4], buf[j + 5], buf[j + 6], buf[j + 7], ++ buf[j + 8], buf[j + 9], buf[j + 10], buf[j + 11], ++ buf[j + 12], buf[j + 13], buf[j + 14], buf[j + 15]); ++ } ++ printk(KERN_INFO "\n++++++++++++++++++++++++++++++++++++++++\n"); ++#endif //0000 ++} ++ ++#ifdef HOST_RC ++static u8 get_cnt(u32 cnt_store, int idx) ++{ ++ int shift = idx << 2; ++ ++ return (u8) ((cnt_store >> shift) & 0xf); ++} ++ ++void esp_show_rcstatus(struct sip_rc_status *rcstatus) ++{ ++ int i; ++ char msg[82]; ++ char rcstr[16]; ++ u32 cnt_store = rcstatus->rc_cnt_store; ++ ++ memset(msg, 0, sizeof(msg)); ++ memset(rcstr, 0, sizeof(rcstr)); ++ ++ printk(KERN_INFO "rcstatus map 0x%08x cntStore 0x%08x\n", ++ rcstatus->rc_map, rcstatus->rc_cnt_store); ++ ++ for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { ++ if (rcstatus->rc_map & BIT(i)) { ++ sprintf(rcstr, "rcIdx %d, cnt %d ", i, ++ get_cnt(cnt_store, i)); ++ strcat(msg, rcstr); ++ } ++ } ++ printk(KERN_INFO "%s \n", msg); ++} ++ ++void esp_show_tx_rates(struct ieee80211_tx_rate *rates) ++{ ++ int i; ++ char msg[128]; ++ char rcstr[32]; ++ ++ memset(msg, 0, sizeof(msg)); ++ memset(rcstr, 0, sizeof(rcstr)); ++ ++ for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { ++ if (rates->idx != -1) { ++ sprintf(rcstr, "Idx %d, cnt %d, flag %02x ", ++ rates->idx, rates->count, rates->flags); ++ strcat(msg, rcstr); ++ } ++ rates++; ++ } ++ strcat(msg, "\n"); ++ printk(KERN_INFO "%s \n", msg); ++} ++#endif /* HOST_RC */ +diff --git a/drivers/net/wireless/esp8089/esp_debug.h b/drivers/net/wireless/esp8089/esp_debug.h +new file mode 100644 +index 000000000000..bab695d34bfb +--- /dev/null ++++ b/drivers/net/wireless/esp8089/esp_debug.h +@@ -0,0 +1,101 @@ ++/* ++ * Copyright (c) 2011-2014 Espressif System. ++ * ++ * esp debug ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _DEBUG_H_ ++ ++#ifdef ASSERT_PANIC ++#define ESSERT(v) BUG_ON(!(v)) ++#else ++#define ESSERT(v) if(!(v)) printk("ESSERT:%s %d\n", __FILE__, __LINE__) ++#endif ++ ++ ++#include ++#include ++#include ++ ++typedef enum esp_type { ++ ESP_BOOL, ++ ESP_U8, ++ ESP_U16, ++ ESP_U32, ++ ESP_U64 ++} esp_type; ++ ++void esp_dump_var(const char *name, struct dentry *parent, ++ void *value, esp_type type); ++ ++void esp_dump_array(const char *name, struct dentry *parent, ++ struct debugfs_blob_wrapper *blob); ++ ++void esp_dump(const char *name, struct dentry *parent, ++ void *data, int size); ++ ++struct dentry *esp_debugfs_add_sub_dir(const char *name); ++ ++int esp_debugfs_init(void); ++ ++void esp_debugfs_exit(void); ++ ++enum { ++ ESP_DBG_ERROR = BIT(0), ++ ESP_DBG_TRACE = BIT(1), ++ ESP_DBG_LOG = BIT(2), ++ ESP_DBG = BIT(3), ++ ESP_SHOW = BIT(4), ++ ESP_DBG_TXAMPDU = BIT(5), ++ ESP_DBG_OP = BIT(6), ++ ESP_DBG_PS = BIT(7), ++ ESP_ATE = BIT(8), ++ ESP_DBG_ALL = 0xffffffff ++}; ++ ++extern unsigned int esp_msg_level; ++ ++#ifdef ESP_ANDROID_LOGGER ++extern bool log_off; ++#endif /* ESP_ANDROID_LOGGER */ ++ ++#ifdef ESP_ANDROID_LOGGER ++#include "esp_file.h" ++#define esp_dbg(mask, fmt, args...) do { \ ++ if (esp_msg_level & mask) \ ++ { \ ++ if (log_off) \ ++ printk(fmt, ##args); \ ++ else \ ++ logger_write(4, "esp_wifi", fmt, ##args); \ ++ } \ ++ } while (0) ++#else ++#define esp_dbg(mask, fmt, args...) do { \ ++ if (esp_msg_level & mask) \ ++ printk("esp8089: " fmt, ##args); \ ++ } while (0) ++#endif /* ESP_ANDROID_LOGGER */ ++ ++void show_buf(u8 * buf, u32 len); ++ ++#ifdef HOST_RC ++struct sip_rc_status; ++struct ieee80211_tx_rate; ++ ++void esp_show_rcstatus(struct sip_rc_status *rcstatus); ++ ++void esp_show_tx_rates(struct ieee80211_tx_rate *rates); ++#endif /* HOST_RC */ ++ ++#endif /* _DEBUG_H_ */ +diff --git a/drivers/net/wireless/esp8089/esp_ext.c b/drivers/net/wireless/esp8089/esp_ext.c +new file mode 100644 +index 000000000000..541f27a6853f +--- /dev/null ++++ b/drivers/net/wireless/esp8089/esp_ext.c +@@ -0,0 +1,542 @@ ++/* ++ * Copyright (c) 2010 -2013 Espressif System. ++ * ++ * extended gpio ++ * - interface for other driver or kernel ++ * - gpio control ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifdef USE_EXT_GPIO ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "esp_ext.h" ++#include "esp_debug.h" ++#include "esp_sip.h" ++#include "esp_sif.h" ++ ++#ifdef EXT_GPIO_OPS ++extern void register_ext_gpio_ops(struct esp_ext_gpio_ops *ops); ++extern void unregister_ext_gpio_ops(void); ++ ++static struct esp_ext_gpio_ops ext_gpio_ops = { ++ .gpio_request = ext_gpio_request, /* gpio_request gpio_no from 0x0 to 0xf */ ++ .gpio_release = ext_gpio_release, /* gpio_release */ ++ .gpio_set_mode = ext_gpio_set_mode, /* gpio_set_mode, data is irq_func of irq_mode , default level of output_mode */ ++ .gpio_get_mode = ext_gpio_get_mode, /* gpio_get_mode, current mode */ ++ .gpio_set_state = ext_gpio_set_output_state, /* only output state, high level or low level */ ++ .gpio_get_state = ext_gpio_get_state, /* current state */ ++ .irq_ack = ext_irq_ack, /* ack interrupt */ ++}; ++ ++ ++#endif ++ ++static struct esp_pub *ext_epub = NULL; ++ ++static u16 intr_mask_reg = 0x0000; ++struct workqueue_struct *ext_irq_wkq = NULL; ++struct work_struct ext_irq_work; ++static struct mutex ext_mutex_lock; ++ ++static struct ext_gpio_info gpio_list[EXT_GPIO_MAX_NUM] = { ++ {0, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, ++ {1, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, ++ {2, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, ++ {3, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, ++ {4, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, ++ {5, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, ++ {6, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, ++ {7, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, ++ {8, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, ++ {9, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, ++ {10, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, ++ {11, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, ++ {12, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, ++ {13, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, ++ {14, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, ++ {15, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, ++}; ++ ++static struct pending_intr_list_info esp_pending_intr_list = { ++ .start_pos = 0, ++ .end_pos = 0, ++ .curr_num = 0, ++}; ++ ++u16 ext_gpio_get_int_mask_reg(void) ++{ ++ return intr_mask_reg; ++} ++ ++int ext_gpio_request(int gpio_no) ++{ ++ if (ext_epub == NULL || ext_epub->sip == NULL || ++ atomic_read(&ext_epub->sip->state) != SIP_RUN) { ++ esp_dbg(ESP_DBG_ERROR, "%s esp state is not ok\n", ++ __func__); ++ return -ENOTRECOVERABLE; ++ } ++ ++ mutex_lock(&ext_mutex_lock); ++ ++ if (gpio_no >= EXT_GPIO_MAX_NUM || gpio_no < 0) { ++ mutex_unlock(&ext_mutex_lock); ++ esp_dbg(ESP_DBG_ERROR, "%s unkown gpio num\n", __func__); ++ return -ERANGE; ++ } ++ ++ if (gpio_list[gpio_no].gpio_mode != EXT_GPIO_MODE_DISABLE) { ++ mutex_unlock(&ext_mutex_lock); ++ esp_dbg(ESP_DBG_ERROR, ++ "%s gpio is already in used by other\n", __func__); ++ return -EPERM; ++ } else { ++ gpio_list[gpio_no].gpio_mode = EXT_GPIO_MODE_MAX; ++ mutex_unlock(&ext_mutex_lock); ++ return 0; ++ } ++} ++ ++EXPORT_SYMBOL(ext_gpio_request); ++ ++int ext_gpio_release(int gpio_no) ++{ ++ int ret; ++ ++ if (ext_epub == NULL || ext_epub->sip == NULL || ++ atomic_read(&ext_epub->sip->state) != SIP_RUN) { ++ esp_dbg(ESP_DBG_ERROR, "%s esp state is not ok\n", ++ __func__); ++ return -ENOTRECOVERABLE; ++ } ++ ++ mutex_lock(&ext_mutex_lock); ++ ++ if (gpio_no >= EXT_GPIO_MAX_NUM || gpio_no < 0) { ++ mutex_unlock(&ext_mutex_lock); ++ esp_dbg(ESP_DBG_ERROR, "%s unkown gpio num\n", __func__); ++ return -ERANGE; ++ } ++ sif_lock_bus(ext_epub); ++ ret = ++ sif_config_gpio_mode(ext_epub, (u8) gpio_no, ++ EXT_GPIO_MODE_DISABLE); ++ sif_unlock_bus(ext_epub); ++ if (ret) { ++ esp_dbg(ESP_DBG_ERROR, "%s gpio release error\n", ++ __func__); ++ mutex_unlock(&ext_mutex_lock); ++ return ret; ++ } ++ ++ gpio_list[gpio_no].gpio_mode = EXT_GPIO_MODE_DISABLE; ++ gpio_list[gpio_no].gpio_state = EXT_GPIO_STATE_IDLE; ++ gpio_list[gpio_no].irq_handler = NULL; ++ intr_mask_reg &= ~(1 << gpio_no); ++ ++ mutex_unlock(&ext_mutex_lock); ++ ++ return 0; ++} ++ ++EXPORT_SYMBOL(ext_gpio_release); ++ ++int ext_gpio_set_mode(int gpio_no, int mode, void *data) ++{ ++ u8 gpio_mode; ++ int ret; ++ struct ext_gpio_info backup_info; ++ ++ if (ext_epub == NULL || ext_epub->sip == NULL || ++ atomic_read(&ext_epub->sip->state) != SIP_RUN) { ++ esp_dbg(ESP_DBG_LOG, "%s esp state is not ok\n", __func__); ++ return -ENOTRECOVERABLE; ++ } ++ ++ mutex_lock(&ext_mutex_lock); ++ ++ if (gpio_no >= EXT_GPIO_MAX_NUM || gpio_no < 0) { ++ mutex_unlock(&ext_mutex_lock); ++ esp_dbg(ESP_DBG_ERROR, "%s unkown gpio num\n", __func__); ++ return -ERANGE; ++ } ++ ++ if (gpio_list[gpio_no].gpio_mode == EXT_GPIO_MODE_DISABLE) { ++ mutex_unlock(&ext_mutex_lock); ++ esp_dbg(ESP_DBG_ERROR, ++ "%s gpio is not in occupy, please request gpio\n", ++ __func__); ++ return -ENOTRECOVERABLE; ++ } ++ ++ if (mode <= EXT_GPIO_MODE_OOB || mode >= EXT_GPIO_MODE_MAX) { ++ mutex_unlock(&ext_mutex_lock); ++ esp_dbg(ESP_DBG_ERROR, "%s gpio mode unknown\n", __func__); ++ return -EOPNOTSUPP; ++ } ++ ++ memcpy(&backup_info, &gpio_list[gpio_no], ++ sizeof(struct ext_gpio_info)); ++ ++ gpio_list[gpio_no].gpio_mode = mode; ++ gpio_mode = (u8) mode; ++ ++ switch (mode) { ++ case EXT_GPIO_MODE_INTR_POSEDGE: ++ case EXT_GPIO_MODE_INTR_NEGEDGE: ++ case EXT_GPIO_MODE_INTR_LOLEVEL: ++ case EXT_GPIO_MODE_INTR_HILEVEL: ++ if (!data) { ++ memcpy(&gpio_list[gpio_no], &backup_info, ++ sizeof(struct ext_gpio_info)); ++ esp_dbg(ESP_DBG_ERROR, "%s irq_handler is NULL\n", ++ __func__); ++ mutex_unlock(&ext_mutex_lock); ++ return -EINVAL; ++ } ++ gpio_list[gpio_no].irq_handler = (ext_irq_handler_t) data; ++ intr_mask_reg |= (1 << gpio_no); ++ break; ++ case EXT_GPIO_MODE_OUTPUT: ++ if (!data) { ++ memcpy(&gpio_list[gpio_no], &backup_info, ++ sizeof(struct ext_gpio_info)); ++ esp_dbg(ESP_DBG_ERROR, ++ "%s output default value is NULL\n", ++ __func__); ++ mutex_unlock(&ext_mutex_lock); ++ return -EINVAL; ++ } ++ *(int *) data = (*(int *) data == 0 ? 0 : 1); ++ gpio_mode = (u8) (((*(int *) data) << 4) | gpio_mode); ++ default: ++ gpio_list[gpio_no].irq_handler = NULL; ++ intr_mask_reg &= ~(1 << gpio_no); ++ break; ++ } ++ ++ sif_lock_bus(ext_epub); ++ ret = sif_config_gpio_mode(ext_epub, (u8) gpio_no, gpio_mode); ++ sif_unlock_bus(ext_epub); ++ if (ret) { ++ memcpy(&gpio_list[gpio_no], &backup_info, ++ sizeof(struct ext_gpio_info)); ++ esp_dbg(ESP_DBG_ERROR, "%s gpio set error\n", __func__); ++ mutex_unlock(&ext_mutex_lock); ++ return ret; ++ } ++ ++ mutex_unlock(&ext_mutex_lock); ++ return 0; ++} ++ ++EXPORT_SYMBOL(ext_gpio_set_mode); ++ ++int ext_gpio_get_mode(int gpio_no) ++{ ++ int gpio_mode; ++ ++ if (ext_epub == NULL || ext_epub->sip == NULL || ++ atomic_read(&ext_epub->sip->state) != SIP_RUN) { ++ esp_dbg(ESP_DBG_LOG, "%s esp state is not ok\n", __func__); ++ return -ENOTRECOVERABLE; ++ } ++ ++ mutex_lock(&ext_mutex_lock); ++ ++ if (gpio_no >= EXT_GPIO_MAX_NUM || gpio_no < 0) { ++ esp_dbg(ESP_DBG_ERROR, "%s unkown gpio num\n", __func__); ++ mutex_unlock(&ext_mutex_lock); ++ return -ERANGE; ++ } ++ ++ gpio_mode = gpio_list[gpio_no].gpio_mode; ++ ++ mutex_unlock(&ext_mutex_lock); ++ ++ return gpio_mode; ++} ++ ++EXPORT_SYMBOL(ext_gpio_get_mode); ++ ++ ++int ext_gpio_set_output_state(int gpio_no, int state) ++{ ++ int ret; ++ ++ if (ext_epub == NULL || ext_epub->sip == NULL || ++ atomic_read(&ext_epub->sip->state) != SIP_RUN) { ++ esp_dbg(ESP_DBG_LOG, "%s esp state is not ok\n", __func__); ++ return -ENOTRECOVERABLE; ++ } ++ ++ mutex_lock(&ext_mutex_lock); ++ ++ if (gpio_no >= EXT_GPIO_MAX_NUM || gpio_no < 0) { ++ mutex_unlock(&ext_mutex_lock); ++ esp_dbg(ESP_DBG_ERROR, "%s unkown gpio num\n", __func__); ++ return -ERANGE; ++ } ++ ++ if (gpio_list[gpio_no].gpio_mode != EXT_GPIO_MODE_OUTPUT) { ++ mutex_unlock(&ext_mutex_lock); ++ esp_dbg(ESP_DBG_ERROR, ++ "%s gpio is not in output state, please request gpio or set output state\n", ++ __func__); ++ return -EOPNOTSUPP; ++ } ++ ++ if (state != EXT_GPIO_STATE_LOW && state != EXT_GPIO_STATE_HIGH) { ++ mutex_unlock(&ext_mutex_lock); ++ esp_dbg(ESP_DBG_ERROR, "%s gpio state unknown\n", ++ __func__); ++ return -ENOTRECOVERABLE; ++ } ++ ++ sif_lock_bus(ext_epub); ++ ret = ++ sif_set_gpio_output(ext_epub, 1 << gpio_no, state << gpio_no); ++ sif_unlock_bus(ext_epub); ++ if (ret) { ++ esp_dbg(ESP_DBG_ERROR, "%s gpio state set error\n", ++ __func__); ++ mutex_unlock(&ext_mutex_lock); ++ return ret; ++ } ++ gpio_list[gpio_no].gpio_state = state; ++ ++ mutex_unlock(&ext_mutex_lock); ++ ++ return 0; ++} ++ ++EXPORT_SYMBOL(ext_gpio_set_output_state); ++ ++int ext_gpio_get_state(int gpio_no) ++{ ++ int ret; ++ u16 state; ++ u16 mask; ++ ++ if (ext_epub == NULL || ext_epub->sip == NULL || ++ atomic_read(&ext_epub->sip->state) != SIP_RUN) { ++ esp_dbg(ESP_DBG_LOG, "%s esp state is not ok\n", __func__); ++ return -ENOTRECOVERABLE; ++ } ++ ++ mutex_lock(&ext_mutex_lock); ++ ++ if (gpio_no >= EXT_GPIO_MAX_NUM || gpio_no < 0) { ++ esp_dbg(ESP_DBG_ERROR, "%s unkown gpio num\n", __func__); ++ mutex_unlock(&ext_mutex_lock); ++ return -ERANGE; ++ } ++ ++ if (gpio_list[gpio_no].gpio_mode == EXT_GPIO_MODE_OUTPUT) { ++ state = gpio_list[gpio_no].gpio_state; ++ } else if (gpio_list[gpio_no].gpio_mode == EXT_GPIO_MODE_INPUT) { ++ sif_lock_bus(ext_epub); ++ ret = sif_get_gpio_input(ext_epub, &mask, &state); ++ sif_unlock_bus(ext_epub); ++ if (ret) { ++ esp_dbg(ESP_DBG_ERROR, ++ "%s get gpio_input state error\n", ++ __func__); ++ mutex_unlock(&ext_mutex_lock); ++ return ret; ++ } ++ } else { ++ esp_dbg(ESP_DBG_ERROR, ++ "%s gpio_state is not input or output\n", ++ __func__); ++ mutex_unlock(&ext_mutex_lock); ++ return -EOPNOTSUPP; ++ } ++ mutex_unlock(&ext_mutex_lock); ++ ++ return (state & (1 << gpio_no)) ? 1 : 0; ++} ++ ++EXPORT_SYMBOL(ext_gpio_get_state); ++ ++int ext_irq_ack(int gpio_no) ++{ ++ int ret; ++ ++ if (ext_epub == NULL || ext_epub->sip == NULL || ++ atomic_read(&ext_epub->sip->state) != SIP_RUN) { ++ esp_dbg(ESP_DBG_LOG, "%s esp state is not ok\n", __func__); ++ return -ENOTRECOVERABLE; ++ } ++ ++ mutex_lock(&ext_mutex_lock); ++ if (gpio_no >= EXT_GPIO_MAX_NUM || gpio_no < 0) { ++ esp_dbg(ESP_DBG_ERROR, "%s unkown gpio num\n", __func__); ++ mutex_unlock(&ext_mutex_lock); ++ return -ERANGE; ++ } ++ ++ if (gpio_list[gpio_no].gpio_mode != EXT_GPIO_MODE_INTR_POSEDGE ++ && gpio_list[gpio_no].gpio_mode != EXT_GPIO_MODE_INTR_NEGEDGE ++ && gpio_list[gpio_no].gpio_mode != EXT_GPIO_MODE_INTR_LOLEVEL ++ && gpio_list[gpio_no].gpio_mode != ++ EXT_GPIO_MODE_INTR_HILEVEL) { ++ esp_dbg(ESP_DBG_ERROR, "%s gpio mode is not intr mode\n", ++ __func__); ++ mutex_unlock(&ext_mutex_lock); ++ return -ENOTRECOVERABLE; ++ } ++ ++ sif_lock_bus(ext_epub); ++ ret = sif_set_gpio_output(ext_epub, 0x00, 1 << gpio_no); ++ sif_unlock_bus(ext_epub); ++ if (ret) { ++ esp_dbg(ESP_DBG_ERROR, "%s gpio intr ack error\n", ++ __func__); ++ mutex_unlock(&ext_mutex_lock); ++ return ret; ++ } ++ ++ mutex_unlock(&ext_mutex_lock); ++ return 0; ++} ++ ++EXPORT_SYMBOL(ext_irq_ack); ++ ++void show_status(void) ++{ ++ int i = 0; ++ for (i = 0; i < MAX_PENDING_INTR_LIST; i++) ++ esp_dbg(ESP_DBG_ERROR, "status[%d] = [0x%04x]\n", i, ++ esp_pending_intr_list.pending_intr_list[i]); ++ ++ esp_dbg(ESP_DBG_ERROR, "start_pos[%d]\n", ++ esp_pending_intr_list.start_pos); ++ esp_dbg(ESP_DBG_ERROR, "end_pos[%d]\n", ++ esp_pending_intr_list.end_pos); ++ esp_dbg(ESP_DBG_ERROR, "curr_num[%d]\n", ++ esp_pending_intr_list.curr_num); ++ ++} ++void esp_tx_work(struct work_struct *work) ++{ ++ int i; ++ u16 tmp_intr_status_reg; ++ ++ esp_dbg(ESP_DBG_TRACE, "%s enter\n", __func__); ++ ++ spin_lock(&esp_pending_intr_list.spin_lock); ++ ++ tmp_intr_status_reg = ++ esp_pending_intr_list.pending_intr_list[esp_pending_intr_list. ++ start_pos]; ++ ++ esp_pending_intr_list.pending_intr_list[esp_pending_intr_list. ++ start_pos] = 0x0000; ++ esp_pending_intr_list.start_pos = ++ (esp_pending_intr_list.start_pos + 1) % MAX_PENDING_INTR_LIST; ++ esp_pending_intr_list.curr_num--; ++ ++ spin_unlock(&esp_pending_intr_list.spin_lock); ++ ++ for (i = 0; i < EXT_GPIO_MAX_NUM; i++) { ++ if (tmp_intr_status_reg & (1 << i) ++ && (gpio_list[i].irq_handler)) ++ gpio_list[i].irq_handler(); ++ } ++ ++ spin_lock(&esp_pending_intr_list.spin_lock); ++ if (esp_pending_intr_list.curr_num > 0) ++ queue_work(ext_irq_wkq, &ext_irq_work); ++ spin_unlock(&esp_pending_intr_list.spin_lock); ++} ++ ++void ext_gpio_int_process(u16 value) ++{ ++ if (value == 0x00) ++ return; ++ ++ esp_dbg(ESP_DBG_TRACE, "%s enter\n", __func__); ++ ++ /* intr cycle queue is full, wait */ ++ while (esp_pending_intr_list.curr_num >= MAX_PENDING_INTR_LIST) { ++ udelay(1); ++ } ++ ++ spin_lock(&esp_pending_intr_list.spin_lock); ++ ++ esp_pending_intr_list.pending_intr_list[esp_pending_intr_list. ++ end_pos] = value; ++ esp_pending_intr_list.end_pos = ++ (esp_pending_intr_list.end_pos + 1) % MAX_PENDING_INTR_LIST; ++ esp_pending_intr_list.curr_num++; ++ ++ queue_work(ext_irq_wkq, &ext_irq_work); ++ ++ spin_unlock(&esp_pending_intr_list.spin_lock); ++} ++ ++int ext_gpio_init(struct esp_pub *epub) ++{ ++ esp_dbg(ESP_DBG_ERROR, "%s enter\n", __func__); ++ ++ ext_irq_wkq = create_singlethread_workqueue("esp_ext_irq_wkq"); ++ if (ext_irq_wkq == NULL) { ++ esp_dbg(ESP_DBG_ERROR, "%s create workqueue error\n", ++ __func__); ++ return -EACCES; ++ } ++ ++ INIT_WORK(&ext_irq_work, esp_tx_work); ++ mutex_init(&ext_mutex_lock); ++ ++ ext_epub = epub; ++ ++ if (ext_epub == NULL) ++ return -EINVAL; ++ ++#ifdef EXT_GPIO_OPS ++ register_ext_gpio_ops(&ext_gpio_ops); ++#endif ++ ++ return 0; ++} ++ ++void ext_gpio_deinit(void) ++{ ++ esp_dbg(ESP_DBG_ERROR, "%s enter\n", __func__); ++ ++#ifdef EXT_GPIO_OPS ++ unregister_ext_gpio_ops(); ++#endif ++ ext_epub = NULL; ++ cancel_work_sync(&ext_irq_work); ++ ++ if (ext_irq_wkq) ++ destroy_workqueue(ext_irq_wkq); ++ ++} ++ ++#endif /* USE_EXT_GPIO */ +diff --git a/drivers/net/wireless/esp8089/esp_ext.h b/drivers/net/wireless/esp8089/esp_ext.h +new file mode 100644 +index 000000000000..0eeba4d22111 +--- /dev/null ++++ b/drivers/net/wireless/esp8089/esp_ext.h +@@ -0,0 +1,100 @@ ++#ifdef USE_EXT_GPIO ++ ++#ifndef _ESP_EXT_H_ ++#define _ESP_EXT_H_ ++ ++#include ++#include ++#include "esp_sip.h" ++ ++#define MAX_PENDING_INTR_LIST 16 ++ ++#ifdef EXT_GPIO_OPS ++typedef struct esp_ext_gpio_ops { ++ int (*gpio_request) (int gpio_no); /* gpio_request gpio_no from 0x0 to 0xf */ ++ int (*gpio_release) (int gpio_no); /* gpio_release */ ++ int (*gpio_set_mode) (int gpio_no, int mode, void *data); /* gpio_set_mode, data is irq_func of irq_mode , default level of output_mode */ ++ int (*gpio_get_mode) (int gpio_no); /* gpio_get_mode, current mode */ ++ int (*gpio_set_state) (int gpio_no, int state); /* only output state, high level or low level */ ++ int (*gpio_get_state) (int gpio_no); /* current state */ ++ int (*irq_ack) (int gpio_no); /* ack interrupt */ ++} esp_ext_gpio_ops_t; ++#endif ++ ++typedef enum EXT_GPIO_NO { ++ EXT_GPIO_GPIO0 = 0, ++ EXT_GPIO_U0TXD, ++ EXT_GPIO_GPIO2, ++ EXT_GPIO_U0RXD, ++ EXT_GPIO_GPIO4, ++ EXT_GPIO_GPIO5, ++ EXT_GPIO_SD_CLK, ++ EXT_GPIO_SD_DATA0, ++ EXT_GPIO_SD_DATA1, ++ EXT_GPIO_SD_DATA2, ++ EXT_GPIO_SD_DATA3, ++ EXT_GPIO_SD_CMD, ++ EXT_GPIO_MTDI, ++ EXT_GPIO_MTCK, ++ EXT_GPIO_MTMS, ++ EXT_GPIO_MTDO, ++ EXT_GPIO_MAX_NUM ++} EXT_GPIO_NO_T; ++ ++typedef enum EXT_GPIO_MODE { //dir def pullup mode wake ++ EXT_GPIO_MODE_OOB = 0, //output 1 0 n/a n/a ++ EXT_GPIO_MODE_OUTPUT, //output / 0 n/a n/a ++ EXT_GPIO_MODE_DISABLE, //input n/a 0 DIS n/a ++ EXT_GPIO_MODE_INTR_POSEDGE, //input n/a 0 POS 1 ++ EXT_GPIO_MODE_INTR_NEGEDGE, //input n/a 1 NEG 1 ++ EXT_GPIO_MODE_INPUT, //input n/a 0 ANY 1 ++ EXT_GPIO_MODE_INTR_LOLEVEL, //input n/a 1 LOW 1 ++ EXT_GPIO_MODE_INTR_HILEVEL, //input n/a 0 HIGH 1 ++ EXT_GPIO_MODE_MAX, ++} EXT_GPIO_MODE_T; ++ ++typedef enum EXT_GPIO_STATE { ++ EXT_GPIO_STATE_LOW, ++ EXT_GPIO_STATE_HIGH, ++ EXT_GPIO_STATE_IDLE ++} EXT_GPIO_STATE_T; ++ ++typedef irqreturn_t(*ext_irq_handler_t) (void); ++ ++struct ext_gpio_info { ++ int gpio_no; ++ int gpio_mode; ++ int gpio_state; ++ ext_irq_handler_t irq_handler; ++}; ++ ++struct pending_intr_list_info { ++ u16 pending_intr_list[MAX_PENDING_INTR_LIST]; ++ int start_pos; ++ int end_pos; ++ int curr_num; ++ spinlock_t spin_lock; ++}; ++ ++u16 ext_gpio_get_int_mask_reg(void); ++ ++/* for extern user start */ ++int ext_gpio_request(int gpio_no); ++int ext_gpio_release(int gpio_no); ++ ++int ext_gpio_set_mode(int gpio_no, int mode, void *data); ++int ext_gpio_get_mode(int gpio_no); ++ ++int ext_gpio_set_output_state(int gpio_no, int state); ++int ext_gpio_get_state(int gpio_no); ++ ++int ext_irq_ack(int gpio_no); ++/* for extern user end */ ++ ++void ext_gpio_int_process(u16 value); ++ ++int ext_gpio_init(struct esp_pub *epub); ++void ext_gpio_deinit(void); ++#endif /* _ESP_EXT_H_ */ ++ ++#endif /* USE_EXT_GPIO */ +diff --git a/drivers/net/wireless/esp8089/esp_file.c b/drivers/net/wireless/esp8089/esp_file.c +new file mode 100644 +index 000000000000..ea702f010eec +--- /dev/null ++++ b/drivers/net/wireless/esp8089/esp_file.c +@@ -0,0 +1,258 @@ ++/* ++ * Copyright (c) 2010 -2014 Espressif System. ++ * ++ * file operation in kernel space ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "esp_file.h" ++#include "esp_debug.h" ++#include "esp_sif.h" ++ ++static int mod_parm_crystal = -1; ++module_param_named(crystal, mod_parm_crystal, int, 0444); ++MODULE_PARM_DESC(crystal, "crystal frequency: 0=40MHz, 1=26MHz, 2=24MHz"); ++ ++struct esp_init_table_elem esp_init_table[MAX_ATTR_NUM] = { ++ /* ++ * Crystal type: ++ * 0: 40MHz (default) ++ * 1: 26MHz (ESP8266 ESP-12F) ++ * 2: 24MHz ++ */ ++ {"crystal_26M_en", 48, 0}, ++ /* ++ * Output crystal clock to pin: ++ * 0: None ++ * 1: GPIO1 ++ * 2: URXD0 ++ */ ++ {"test_xtal", 49, 0}, ++ /* ++ * Host SDIO mode: ++ * 0: Auto by pin strapping ++ * 1: SDIO data output on negative edges (SDIO v1.1) ++ * 2: SDIO data output on positive edges (SDIO v2.0) ++ */ ++ {"sdio_configure", 50, 2}, ++ /* ++ * WiFi/Bluetooth co-existence with BK3515A BT chip ++ * 0: None ++ * 1: GPIO0->WLAN_ACTIVE, MTMS->BT_ACTIVE, MTDI->BT_PRIORITY, ++ * U0TXD->ANT_SEL_BT, U0RXD->ANT_SEL_WIFI ++ */ ++ {"bt_configure", 51, 0}, ++ /* ++ * Antenna selection: ++ * 0: Antenna is for WiFi ++ * 1: Antenna is for Bluetooth ++ */ ++ {"bt_protocol", 52, 0}, ++ /* ++ * Dual antenna configuration mode: ++ * 0: None ++ * 1: U0RXD + XPD_DCDC ++ * 2: U0RXD + GPIO0 ++ * 3: U0RXD + U0TXD ++ */ ++ {"dual_ant_configure", 53, 0}, ++ /* ++ * Firmware debugging output pin: ++ * 0: None ++ * 1: UART TX on GPIO2 ++ * 2: UART TX on U0TXD ++ */ ++ {"test_uart_configure", 54, 2}, ++ /* ++ * Whether to share crystal clock with BT (in sleep mode): ++ * 0: no ++ * 1: always on ++ * 2: automatically on according to XPD_DCDC ++ */ ++ {"share_xtal", 55, 0}, ++ /* ++ * Allow chip to be woken up during sleep on pin: ++ * 0: None ++ * 1: XPD_DCDC ++ * 2: GPIO0 ++ * 3: Both XPD_DCDC and GPIO0 ++ */ ++ {"gpio_wake", 56, 0}, ++ {"no_auto_sleep", 57, 0}, ++ {"speed_suspend", 58, 0}, ++ {"attr11", -1, -1}, ++ {"attr12", -1, -1}, ++ {"attr13", -1, -1}, ++ {"attr14", -1, -1}, ++ {"attr15", -1, -1}, ++ //attr that is not send to target ++ /* ++ * Allow chip to be reset by GPIO pin: ++ * 0: no ++ * 1: yes ++ */ ++ {"ext_rst", -1, 0}, ++ {"wakeup_gpio", -1, 12}, ++ {"ate_test", -1, 0}, ++ {"attr19", -1, -1}, ++ {"attr20", -1, -1}, ++ {"attr21", -1, -1}, ++ {"attr22", -1, -1}, ++ {"attr23", -1, -1}, ++}; ++ ++/* ++ * Export part of the configuration related to first initiliazition to the esp8089 ++ */ ++void esp_conf_upload_first(void) ++{ ++ int i; ++ ++ for (i = 0; i < MAX_ATTR_NUM; i++) { ++ if (esp_init_table[i].value < 0) ++ continue; ++ ++ if (!strcmp(esp_init_table[i].attr, "share_xtal")) ++ sif_record_bt_config(esp_init_table[i].value); ++ else if (!strcmp(esp_init_table[i].attr, "ext_rst")) ++ sif_record_rst_config(esp_init_table[i].value); ++ else if (!strcmp(esp_init_table[i].attr, "wakeup_gpio")) ++ sif_record_wakeup_gpio_config(esp_init_table[i].value); ++ else if (!strcmp(esp_init_table[i].attr, "ate_test")) ++ sif_record_ate_config(esp_init_table[i].value); ++ } ++} ++ ++/* ++ * Export part of the configuration related to second initiliazition ++ */ ++void esp_conf_upload_second(u8 * init_data_buf, int buf_size) ++{ ++ int i; ++ ++ for (i = 0; i < MAX_FIX_ATTR_NUM; i++) { ++ if (esp_init_table[i].offset > -1 ++ && esp_init_table[i].offset < buf_size ++ && esp_init_table[i].value > -1) { ++ *(u8 *) (init_data_buf + ++ esp_init_table[i].offset) = ++ esp_init_table[i].value; ++ } else if (esp_init_table[i].offset > buf_size) { ++ esp_dbg(ESP_DBG_ERROR, ++ "%s: offset[%d] longer than init_data_buf len[%d] Ignore\n", ++ __FUNCTION__, esp_init_table[i].offset, ++ buf_size); ++ } ++ } ++ ++} ++ ++ ++void esp_conf_init(struct device *dev) ++{ ++ ++ struct device_node *np = dev->of_node; ++ ++ if (np) { ++ ++ u32 value; ++ ++ if (!of_property_read_u32(np, "esp,crystal-26M-en", &value)) ++ esp_conf_set_attr("crystal_26M_en", value); ++ ++ if (!of_property_read_u32(np, "esp,sdio-configure", &value)) ++ esp_conf_set_attr("sdio_configure", value); ++ ++ if (of_property_read_bool(np, "esp,shared-xtal")) ++ esp_conf_set_attr("share_xtal", 1); ++ ++ if (!of_property_read_u32(np, "esp,gpio-wake", &value)) ++ esp_conf_set_attr("gpio_wake", value); ++ ++ if (!of_property_read_u32(np, "esp,wakeup-gpio", &value)) ++ esp_conf_set_attr("wakeup_gpio", value); ++ ++ if (of_property_read_bool(np, "esp,configure-dual-antenna")) ++ esp_conf_set_attr("dual_ant_configure", 1); ++ ++ if (of_property_read_bool(np, "esp,no-auto-sleep")) ++ esp_conf_set_attr("no_auto_sleep", 1); ++ ++ if (of_property_read_bool(np, "esp,test-xtal")) ++ esp_conf_set_attr("test_xtal", 1); ++ ++ if (of_property_read_bool(np, "esp,bt-configure")) ++ esp_conf_set_attr("bt_configure", 1); ++ ++ if (!of_property_read_u32(np, "esp,bt-protocol", &value)) ++ esp_conf_set_attr("bt_protocol", value); ++ ++ if (of_property_read_bool(np, "esp,test-uart-configure")) ++ esp_conf_set_attr("test_uart_configure", 1); ++ ++ if (of_property_read_bool(np, "esp,speed-suspend")) ++ esp_conf_set_attr("speed_suspend", 1); ++ ++ if (of_property_read_bool(np, "esp,ate-test")) ++ esp_conf_set_attr("ate_test", 1); ++ ++ if (!of_property_read_u32(np, "esp,ext-rst", &value)) ++ esp_conf_set_attr("ext_rst", value); ++ ++ } ++ ++ if (mod_parm_crystal >= 0 && mod_parm_crystal <= 2) ++ esp_conf_set_attr("crystal_26M_en", mod_parm_crystal); ++ ++ ++ esp_conf_show_attrs(); ++ ++} ++ ++int esp_conf_set_attr(char *name, u8 value) { ++ ++ int i; ++ ++ for (i = 0; i < MAX_ATTR_NUM; i++) { ++ ++ if (strcmp(esp_init_table[i].attr, name) == 0) { ++ esp_dbg(ESP_DBG, "set config: %s value: %d", name, value); ++ esp_init_table[i].value = value; ++ return 0; ++ } ++ ++ } ++ ++ return -1; ++ ++} ++ ++void esp_conf_show_attrs(void) ++{ ++ int i; ++ for (i = 0; i < MAX_ATTR_NUM; i++) ++ if (esp_init_table[i].offset > -1) ++ esp_dbg(ESP_SHOW, "config parm:%s (id:%d), value: %d\n", ++ esp_init_table[i].attr, ++ esp_init_table[i].offset, ++ esp_init_table[i].value); ++} +diff --git a/drivers/net/wireless/esp8089/esp_file.h b/drivers/net/wireless/esp8089/esp_file.h +new file mode 100644 +index 000000000000..5ba39c626baa +--- /dev/null ++++ b/drivers/net/wireless/esp8089/esp_file.h +@@ -0,0 +1,43 @@ ++/* ++ * Copyright (c) 2010 -2014 Espressif System. ++ * ++ * file operation in kernel space ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _ESP_FILE_H_ ++#define _ESP_FILE_H_ ++ ++#include ++#include ++ ++#define E_ROUND_UP(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) ++ ++#define CONF_ATTR_LEN 24 ++#define CONF_VAL_LEN 3 ++#define MAX_ATTR_NUM 24 ++#define MAX_FIX_ATTR_NUM 16 ++#define MAX_BUF_LEN ((CONF_ATTR_LEN + CONF_VAL_LEN + 2) * MAX_ATTR_NUM + 2) ++ ++struct esp_init_table_elem { ++ char attr[CONF_ATTR_LEN]; ++ int offset; ++ short value; ++}; ++ ++void esp_conf_init(struct device *dev); ++void esp_conf_upload_first(void); ++void esp_conf_upload_second(u8 * init_data_buf, int buf_size); ++int esp_conf_set_attr(char *name, u8 value); ++void esp_conf_show_attrs(void); ++ ++#endif /* _ESP_FILE_H_ */ +diff --git a/drivers/net/wireless/esp8089/esp_init_data.h b/drivers/net/wireless/esp8089/esp_init_data.h +new file mode 100644 +index 000000000000..16f451affd1e +--- /dev/null ++++ b/drivers/net/wireless/esp8089/esp_init_data.h +@@ -0,0 +1,7 @@ ++static char esp_init_data[] = ++ { 0x5, 0x0, 4, 2, 5, 5, 5, 2, 5, 0, 4, 5, 5, 4, 5, 5, 4, -2, -3, -1, ++-16, -16, -16, -32, -32, -32, 204, 1, 0xff, 0xff, 0, 0, 0, 0, 82, 78, 74, 68, 64, 56, 0, ++0, 1, 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 10, 0x0, 0x0, ++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 }; +diff --git a/drivers/net/wireless/esp8089/esp_io.c b/drivers/net/wireless/esp8089/esp_io.c +new file mode 100644 +index 000000000000..6c5c01aad4e5 +--- /dev/null ++++ b/drivers/net/wireless/esp8089/esp_io.c +@@ -0,0 +1,639 @@ ++/* ++ * Copyright (c) 2009 - 2014 Espressif System. ++ * IO interface ++ * - sdio/spi common i/f driver ++ * - target sdio hal ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include "esp_sif.h" ++#include "slc_host_register.h" ++#include "esp_debug.h" ++ ++#ifdef SIF_DEBUG_DSR_DUMP_REG ++static void dump_slc_regs(struct slc_host_regs *regs); ++#endif /* SIF_DEBUG_DSR_DUMP_REG */ ++ ++int esp_common_read(struct esp_pub *epub, u8 * buf, u32 len, int sync, ++ bool noround) ++{ ++ if (sync) { ++ return sif_lldesc_read_sync(epub, buf, len); ++ } else { ++ return sif_lldesc_read_raw(epub, buf, len, noround); ++ } ++} ++ ++ ++int esp_common_write(struct esp_pub *epub, u8 * buf, u32 len, int sync) ++{ ++ if (sync) { ++ return sif_lldesc_write_sync(epub, buf, len); ++ } else { ++ return sif_lldesc_write_raw(epub, buf, len); ++ } ++} ++ ++ ++int esp_common_read_with_addr(struct esp_pub *epub, u32 addr, u8 * buf, ++ u32 len, int sync) ++{ ++ if (sync) { ++ return sif_io_sync(epub, addr, buf, len, ++ SIF_FROM_DEVICE | SIF_SYNC | ++ SIF_BYTE_BASIS | SIF_INC_ADDR); ++ } else { ++ return sif_io_raw(epub, addr, buf, len, ++ SIF_FROM_DEVICE | SIF_BYTE_BASIS | ++ SIF_INC_ADDR); ++ } ++ ++} ++ ++ ++int esp_common_write_with_addr(struct esp_pub *epub, u32 addr, u8 * buf, ++ u32 len, int sync) ++{ ++ if (sync) { ++ return sif_io_sync(epub, addr, buf, len, ++ SIF_TO_DEVICE | SIF_SYNC | ++ SIF_BYTE_BASIS | SIF_INC_ADDR); ++ } else { ++ return sif_io_raw(epub, addr, buf, len, ++ SIF_TO_DEVICE | SIF_BYTE_BASIS | ++ SIF_INC_ADDR); ++ } ++} ++ ++int esp_common_readbyte_with_addr(struct esp_pub *epub, u32 addr, u8 * buf, ++ int sync) ++{ ++ if (sync) { ++ int res; ++ sif_lock_bus(epub); ++ *buf = sdio_io_readb(epub, addr, &res); ++ sif_unlock_bus(epub); ++ return res; ++ } else { ++ int res; ++ *buf = sdio_io_readb(epub, addr, &res); ++ return res; ++ } ++ ++} ++ ++ ++ ++int esp_common_writebyte_with_addr(struct esp_pub *epub, u32 addr, u8 buf, ++ int sync) ++{ ++ if (sync) { ++ int res; ++ sif_lock_bus(epub); ++ sdio_io_writeb(epub, buf, addr, &res); ++ sif_unlock_bus(epub); ++ return res; ++ } else { ++ int res; ++ sdio_io_writeb(epub, buf, addr, &res); ++ return res; ++ } ++} ++ ++int sif_read_reg_window(struct esp_pub *epub, unsigned int reg_addr, ++ u8 * value) ++{ ++ u8 *p_tbuf = NULL; ++ int ret = 0; ++ int retry = 20; ++ ++ reg_addr >>= 2; ++ if (reg_addr > 0x1f) ++ return -1; ++ ++ p_tbuf = kzalloc(4, GFP_KERNEL); ++ if (p_tbuf == NULL) ++ return -ENOMEM; ++ ++ p_tbuf[0] = 0x80 | (reg_addr & 0x1f); ++ ++ ret = ++ esp_common_write_with_addr(epub, SLC_HOST_WIN_CMD, p_tbuf, 1, ++ ESP_SIF_NOSYNC); ++ ++ if (ret == 0) { ++ do { ++ if (retry < 20) ++ mdelay(10); ++ retry--; ++ ret = ++ esp_common_read_with_addr(epub, ++ SLC_HOST_STATE_W0, ++ p_tbuf, 4, ++ ESP_SIF_NOSYNC); ++ } while (retry > 0 && ret != 0); ++ } ++ ++ if (ret == 0) ++ memcpy(value, p_tbuf, 4); ++ ++ kfree(p_tbuf); ++ return ret; ++} ++ ++int sif_write_reg_window(struct esp_pub *epub, unsigned int reg_addr, ++ u8 * value) ++{ ++ u8 *p_tbuf = NULL; ++ int ret = 0; ++ ++ reg_addr >>= 2; ++ if (reg_addr > 0x1f) ++ return -1; ++ ++ p_tbuf = kzalloc(8, GFP_KERNEL); ++ if (p_tbuf == NULL) ++ return -ENOMEM; ++ memcpy(p_tbuf, value, 4); ++ p_tbuf[4] = 0xc0 | (reg_addr & 0x1f); ++ ++ ret = ++ esp_common_write_with_addr(epub, SLC_HOST_CONF_W5, p_tbuf, 5, ++ ESP_SIF_NOSYNC); ++ ++ kfree(p_tbuf); ++ return ret; ++} ++ ++int sif_ack_target_read_err(struct esp_pub *epub) ++{ ++ u32 value[1]; ++ int ret; ++ ++ ret = sif_read_reg_window(epub, SLC_RX_LINK, (u8 *) value); ++ if (ret) ++ return ret; ++ value[0] |= SLC_RXLINK_START; ++ ret = sif_write_reg_window(epub, SLC_RX_LINK, (u8 *) value); ++ return ret; ++} ++ ++int sif_had_io_enable(struct esp_pub *epub) ++{ ++ u32 *p_tbuf = NULL; ++ int ret; ++ ++ p_tbuf = kzalloc(sizeof(u32), GFP_KERNEL); ++ if (p_tbuf == NULL) ++ return -ENOMEM; ++ ++ *p_tbuf = ++ SLC_TXEOF_ENA | (0x4 << SLC_FIFO_MAP_ENA_S) | SLC_TX_DUMMY_MODE ++ | SLC_HDA_MAP_128K | (0xFE << SLC_TX_PUSH_IDLE_NUM_S); ++ ret = sif_write_reg_window(epub, SLC_BRIDGE_CONF, (u8 *) p_tbuf); ++ ++ if (ret) ++ goto _err; ++ ++ *p_tbuf = 0x30; ++ ret = ++ esp_common_write_with_addr((epub), SLC_HOST_CONF_W4 + 1, ++ (u8 *) p_tbuf, 1, ESP_SIF_NOSYNC); ++ ++ if (ret) ++ goto _err; ++ //set w3 0 ++ *p_tbuf = 0x1; ++ ret = ++ esp_common_write_with_addr((epub), SLC_HOST_CONF_W3, ++ (u8 *) p_tbuf, 1, ESP_SIF_NOSYNC); ++ ++ _err: ++ kfree(p_tbuf); ++ return ret; ++} ++ ++typedef enum _SDIO_INTR_MODE { ++ SDIO_INTR_IB = 0, ++ SDIO_INTR_OOB_TOGGLE, ++ SDIO_INTR_OOB_HIGH_LEVEL, ++ SDIO_INTR_OOB_LOW_LEVEL, ++} SDIO_INTR_MODE; ++ ++#define GEN_GPIO_SEL(_gpio_num, _sel_func, _intr_mode, _offset) (((_offset)<< 9 ) |((_intr_mode) << 7)|((_sel_func) << 4)|(_gpio_num)) ++//bit[3:0] = gpio num, 2 ++//bit[6:4] = gpio sel func, 0 ++//bit[8:7] = gpio intr mode, SDIO_INTR_OOB_TOGGLE ++//bit[15:9] = register offset, 0x38 ++ ++u16 gpio_sel_sets[17] = { ++ GEN_GPIO_SEL(0, 0, SDIO_INTR_OOB_TOGGLE, 0x34), //GPIO0 ++ GEN_GPIO_SEL(1, 3, SDIO_INTR_OOB_TOGGLE, 0x18), //U0TXD ++ GEN_GPIO_SEL(2, 0, SDIO_INTR_OOB_TOGGLE, 0x38), //GPIO2 ++ GEN_GPIO_SEL(3, 3, SDIO_INTR_OOB_TOGGLE, 0x14), //U0RXD ++ GEN_GPIO_SEL(4, 0, SDIO_INTR_OOB_TOGGLE, 0x3C), //GPIO4 ++ GEN_GPIO_SEL(5, 0, SDIO_INTR_OOB_TOGGLE, 0x40), //GPIO5 ++ GEN_GPIO_SEL(6, 3, SDIO_INTR_OOB_TOGGLE, 0x1C), //SD_CLK ++ GEN_GPIO_SEL(7, 3, SDIO_INTR_OOB_TOGGLE, 0x20), //SD_DATA0 ++ GEN_GPIO_SEL(8, 3, SDIO_INTR_OOB_TOGGLE, 0x24), //SD_DATA1 ++ GEN_GPIO_SEL(9, 3, SDIO_INTR_OOB_TOGGLE, 0x28), //SD_DATA2 ++ GEN_GPIO_SEL(10, 3, SDIO_INTR_OOB_TOGGLE, 0x2C), //SD_DATA3 ++ GEN_GPIO_SEL(11, 3, SDIO_INTR_OOB_TOGGLE, 0x30), //SD_CMD ++ GEN_GPIO_SEL(12, 3, SDIO_INTR_OOB_TOGGLE, 0x04), //MTDI ++ GEN_GPIO_SEL(13, 3, SDIO_INTR_OOB_TOGGLE, 0x08), //MTCK ++ GEN_GPIO_SEL(14, 3, SDIO_INTR_OOB_TOGGLE, 0x0C), //MTMS ++ GEN_GPIO_SEL(15, 3, SDIO_INTR_OOB_TOGGLE, 0x10), //MTDO ++ //pls do not change sel before, if you want to change intr mode,change the one blow ++ //GEN_GPIO_SEL(2, 0, SDIO_INTR_OOB_TOGGLE, 0x38) ++ GEN_GPIO_SEL(2, 0, SDIO_INTR_OOB_LOW_LEVEL, 0x38) ++}; ++ ++#if defined(USE_EXT_GPIO) ++u16 gpio_forbidden = 0; ++#endif ++ ++int sif_interrupt_target(struct esp_pub *epub, u8 index) ++{ ++ u8 low_byte = BIT(index); ++ return esp_common_writebyte_with_addr(epub, SLC_HOST_CONF_W4 + 2, ++ low_byte, ESP_SIF_NOSYNC); ++ ++} ++ ++#ifdef USE_EXT_GPIO ++int sif_config_gpio_mode(struct esp_pub *epub, u8 gpio_num, u8 gpio_mode) ++{ ++ u32 *p_tbuf = NULL; ++ int err; ++ ++ if ((BIT(gpio_num) & gpio_forbidden) || gpio_num > 15) ++ return -EINVAL; ++ ++ p_tbuf = kzalloc(sizeof(u32), GFP_KERNEL); ++ if (p_tbuf == NULL) ++ return -ENOMEM; ++ *p_tbuf = (gpio_mode << 16) | gpio_sel_sets[gpio_num]; ++ err = ++ esp_common_write_with_addr(epub, SLC_HOST_CONF_W1, ++ (u8 *) p_tbuf, sizeof(u32), ++ ESP_SIF_NOSYNC); ++ kfree(p_tbuf); ++ if (err) ++ return err; ++ ++ return sif_interrupt_target(epub, 4); ++} ++ ++int sif_set_gpio_output(struct esp_pub *epub, u16 mask, u16 value) ++{ ++ u32 *p_tbuf = NULL; ++ int err; ++ ++ mask &= ~gpio_forbidden; ++ p_tbuf = kzalloc(sizeof(u32), GFP_KERNEL); ++ if (p_tbuf == NULL) ++ return -ENOMEM; ++ *p_tbuf = (mask << 16) | value; ++ err = ++ esp_common_write_with_addr(epub, SLC_HOST_CONF_W2, ++ (u8 *) p_tbuf, sizeof(u32), ++ ESP_SIF_NOSYNC); ++ kfree(p_tbuf); ++ if (err) ++ return err; ++ ++ return sif_interrupt_target(epub, 5); ++} ++ ++int sif_get_gpio_intr(struct esp_pub *epub, u16 intr_mask, u16 * value) ++{ ++ u32 *p_tbuf = NULL; ++ int err; ++ ++ p_tbuf = kzalloc(sizeof(u32), GFP_KERNEL); ++ if (p_tbuf == NULL) ++ return -ENOMEM; ++ *p_tbuf = 0; ++ err = ++ esp_common_read_with_addr(epub, SLC_HOST_CONF_W3, ++ (u8 *) p_tbuf, sizeof(u32), ++ ESP_SIF_NOSYNC); ++ if (err) { ++ kfree(p_tbuf); ++ return err; ++ } ++ ++ *value = *p_tbuf & intr_mask; ++ kfree(p_tbuf); ++ if (*value == 0) ++ return 0; ++ return sif_interrupt_target(epub, 6); ++} ++ ++int sif_get_gpio_input(struct esp_pub *epub, u16 * mask, u16 * value) ++{ ++ u32 *p_tbuf = NULL; ++ int err; ++ ++ err = sif_interrupt_target(epub, 3); ++ if (err) ++ return err; ++ ++ udelay(20); ++ p_tbuf = kzalloc(sizeof(u32), GFP_KERNEL); ++ if (p_tbuf == NULL) ++ return -ENOMEM; ++ *p_tbuf = 0; ++ err = ++ esp_common_read_with_addr(epub, SLC_HOST_CONF_W3, ++ (u8 *) p_tbuf, sizeof(u32), ++ ESP_SIF_NOSYNC); ++ if (err) { ++ kfree(p_tbuf); ++ return err; ++ } ++ ++ *mask = *p_tbuf >> 16; ++ *value = *p_tbuf & *mask; ++ kfree(p_tbuf); ++ ++ return 0; ++} ++#endif ++ ++void check_target_id(struct esp_pub *epub) ++{ ++ u32 date; ++ int err = 0; ++ int i; ++ ++ EPUB_CTRL_CHECK(epub, _err); ++ ++ sif_lock_bus(epub); ++ ++ for (i = 0; i < 4; i++) { ++ err = ++ esp_common_readbyte_with_addr(epub, SLC_HOST_DATE + i, ++ (u8 *) & date + i, ++ ESP_SIF_NOSYNC); ++ err = ++ esp_common_readbyte_with_addr(epub, SLC_HOST_ID + i, ++ (u8 *) & ++ EPUB_TO_CTRL(epub)-> ++ target_id + i, ++ ESP_SIF_NOSYNC); ++ } ++ ++ sif_unlock_bus(epub); ++ ++ esp_dbg(ESP_DBG_LOG, "\n\n \t\t SLC data 0x%08x, ID 0x%08x\n\n", ++ date, EPUB_TO_CTRL(epub)->target_id); ++ ++ switch (EPUB_TO_CTRL(epub)->target_id) { ++ case 0x100: ++ EPUB_TO_CTRL(epub)->slc_window_end_addr = 0x20000; ++ break; ++ case 0x600: ++ EPUB_TO_CTRL(epub)->slc_window_end_addr = 0x20000 - 0x800; ++ ++ do { ++ u16 gpio_sel; ++ u8 low_byte = 0; ++ u8 high_byte = 0; ++ u8 byte2 = 0; ++ u8 byte3 = 0; ++#ifdef USE_OOB_INTR ++ gpio_sel = gpio_sel_sets[16]; ++ low_byte = gpio_sel; ++ high_byte = gpio_sel >> 8; ++#ifdef USE_EXT_GPIO ++ gpio_forbidden |= BIT(gpio_sel & 0xf); ++#endif /* USE_EXT_GPIO */ ++#endif /* USE_OOB_INTR */ ++ ++ if (sif_get_bt_config() == 1 ++ && sif_get_rst_config() != 1) { ++ u8 gpio_num = sif_get_wakeup_gpio_config(); ++ gpio_sel = gpio_sel_sets[gpio_num]; ++ byte2 = gpio_sel; ++ byte3 = gpio_sel >> 8; ++#ifdef USE_EXT_GPIO ++ gpio_forbidden |= BIT(gpio_num); ++#endif ++ } ++ sif_lock_bus(epub); ++ err = ++ esp_common_writebyte_with_addr(epub, ++ SLC_HOST_CONF_W1, ++ low_byte, ++ ESP_SIF_NOSYNC); ++ err = ++ esp_common_writebyte_with_addr(epub, ++ SLC_HOST_CONF_W1 ++ + 1, high_byte, ++ ESP_SIF_NOSYNC); ++ err = ++ esp_common_writebyte_with_addr(epub, ++ SLC_HOST_CONF_W1 ++ + 2, byte2, ++ ESP_SIF_NOSYNC); ++ err = ++ esp_common_writebyte_with_addr(epub, ++ SLC_HOST_CONF_W1 ++ + 3, byte3, ++ ESP_SIF_NOSYNC); ++ sif_unlock_bus(epub); ++ } while (0); ++ break; ++ default: ++ EPUB_TO_CTRL(epub)->slc_window_end_addr = 0x20000; ++ break; ++ } ++ _err: ++ return; ++} ++ ++u32 sif_get_blksz(struct esp_pub * epub) ++{ ++ EPUB_CTRL_CHECK(epub, _err); ++ ++ return EPUB_TO_CTRL(epub)->slc_blk_sz; ++ _err: ++ return 512; ++} ++ ++u32 sif_get_target_id(struct esp_pub * epub) ++{ ++ EPUB_CTRL_CHECK(epub, _err); ++ ++ return EPUB_TO_CTRL(epub)->target_id; ++ _err: ++ return 0x600; ++} ++ ++void sif_dsr(struct sdio_func *func) ++{ ++ struct esp_sdio_ctrl *sctrl = sdio_get_drvdata(func); ++ static int dsr_cnt = 0, real_intr_cnt = 0, bogus_intr_cnt = 0; ++ struct slc_host_regs *regs = &(sctrl->slc_regs); ++ esp_dbg(ESP_DBG_TRACE, " %s enter %d \n", __func__, dsr_cnt++); ++ ++ sdio_release_host(sctrl->func); ++ ++ ++ sif_lock_bus(sctrl->epub); ++ ++ ++ do { ++ int ret = 0; ++ ++ memset(regs, 0x0, sizeof(struct slc_host_regs)); ++ ++ ret = ++ esp_common_read_with_addr(sctrl->epub, ++ REG_SLC_HOST_BASE + 8, ++ (u8 *) regs, ++ sizeof(struct slc_host_regs), ++ ESP_SIF_NOSYNC); ++ ++ if ((regs->intr_raw & SLC_HOST_RX_ST) && (ret == 0)) { ++ esp_dbg(ESP_DBG_TRACE, "%s eal intr cnt: %d", ++ __func__, ++real_intr_cnt); ++ ++ esp_dsr(sctrl->epub); ++ ++ } else { ++ sif_unlock_bus(sctrl->epub); ++ ++ esp_dbg(ESP_DBG_TRACE, "%s bogus_intr_cnt %d\n", ++ __func__, ++bogus_intr_cnt); ++ } ++ ++#ifdef SIF_DEBUG_DSR_DUMP_REG ++ dump_slc_regs(regs); ++#endif /* SIF_DEBUG_DUMP_DSR */ ++ ++ } while (0); ++ ++ sdio_claim_host(func); ++ ++ atomic_set(&sctrl->irq_handling, 0); ++} ++ ++ ++struct slc_host_regs *sif_get_regs(struct esp_pub *epub) ++{ ++ EPUB_CTRL_CHECK(epub, _err); ++ ++ return &EPUB_TO_CTRL(epub)->slc_regs; ++ _err: ++ return NULL; ++} ++ ++void sif_disable_target_interrupt(struct esp_pub *epub) ++{ ++ EPUB_FUNC_CHECK(epub, _exit); ++ sif_lock_bus(epub); ++#ifdef HOST_RESET_BUG ++ mdelay(10); ++#endif ++ memset(EPUB_TO_CTRL(epub)->dma_buffer, 0x00, sizeof(u32)); ++ esp_common_write_with_addr(epub, SLC_HOST_INT_ENA, ++ EPUB_TO_CTRL(epub)->dma_buffer, ++ sizeof(u32), ESP_SIF_NOSYNC); ++#ifdef HOST_RESET_BUG ++ mdelay(10); ++#endif ++ ++ sif_unlock_bus(epub); ++ ++ mdelay(1); ++ ++ sif_lock_bus(epub); ++ sif_interrupt_target(epub, 7); ++ sif_unlock_bus(epub); ++ _exit: ++ return; ++} ++ ++#ifdef SIF_DEBUG_DSR_DUMP_REG ++static void dump_slc_regs(struct slc_host_regs *regs) ++{ ++ esp_dbg(ESP_DBG_TRACE, "\n\n ------- %s --------------\n", ++ __func__); ++ ++ esp_dbg(ESP_DBG_TRACE, " \ ++ intr_raw 0x%08X \t \n \ ++ state_w0 0x%08X \t state_w1 0x%08X \n \ ++ config_w0 0x%08X \t config_w1 0x%08X \n \ ++ intr_status 0x%08X \t config_w2 0x%08X \n \ ++ config_w3 0x%08X \t config_w4 0x%08X \n \ ++ token_wdata 0x%08X \t intr_clear 0x%08X \n \ ++ intr_enable 0x%08X \n\n", regs->intr_raw, regs->state_w0, regs->state_w1, regs->config_w0, regs->config_w1, regs->intr_status, regs->config_w2, regs->config_w3, regs->config_w4, regs->token_wdata, regs->intr_clear, regs->intr_enable); ++} ++#endif /* SIF_DEBUG_DSR_DUMP_REG */ ++ ++static int bt_config = 0; ++void sif_record_bt_config(int value) ++{ ++ bt_config = value; ++} ++ ++int sif_get_bt_config(void) ++{ ++ return bt_config; ++} ++ ++static int rst_config = 0; ++void sif_record_rst_config(int value) ++{ ++ rst_config = value; ++} ++ ++int sif_get_rst_config(void) ++{ ++ return rst_config; ++} ++ ++static int ate_test = 0; ++void sif_record_ate_config(int value) ++{ ++ ate_test = value; ++} ++ ++int sif_get_ate_config(void) ++{ ++ return ate_test; ++} ++ ++static int retry_reset = 0; ++void sif_record_retry_config(void) ++{ ++ retry_reset = 1; ++} ++ ++int sif_get_retry_config(void) ++{ ++ return retry_reset; ++} ++ ++static int wakeup_gpio = 12; ++void sif_record_wakeup_gpio_config(int value) ++{ ++ wakeup_gpio = value; ++} ++ ++int sif_get_wakeup_gpio_config(void) ++{ ++ return wakeup_gpio; ++} +diff --git a/drivers/net/wireless/esp8089/esp_mac80211.c b/drivers/net/wireless/esp8089/esp_mac80211.c +new file mode 100644 +index 000000000000..14186365fdd4 +--- /dev/null ++++ b/drivers/net/wireless/esp8089/esp_mac80211.c +@@ -0,0 +1,1731 @@ ++/* ++ * Copyright (c) 2011-2014 Espressif System. ++ * ++ * MAC80211 support module ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "esp_pub.h" ++#include "esp_sip.h" ++#include "esp_ctrl.h" ++#include "esp_sif.h" ++#include "esp_debug.h" ++#include "esp_wl.h" ++#include "esp_utils.h" ++ ++#define ESP_IEEE80211_DBG esp_dbg ++ ++#define GET_NEXT_SEQ(seq) (((seq) +1) & 0x0fff) ++ ++static u8 esp_mac_addr[ETH_ALEN * 2]; ++static u8 getaddr_index(u8 * addr, struct esp_pub *epub); ++ ++static ++void ++esp_op_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, ++ struct sk_buff *skb) ++{ ++ struct esp_pub *epub = (struct esp_pub *) hw->priv; ++ ++ ESP_IEEE80211_DBG(ESP_DBG_LOG, "%s enter\n", __func__); ++ if (!mod_support_no_txampdu() && ++ cfg80211_get_chandef_type(&epub->hw->conf.chandef) != ++ NL80211_CHAN_NO_HT) { ++ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); ++ struct ieee80211_hdr *wh = ++ (struct ieee80211_hdr *) skb->data; ++ if (ieee80211_is_data_qos(wh->frame_control)) { ++ if (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) { ++ u8 tidno = ++ ieee80211_get_qos_ctl(wh)[0] & ++ IEEE80211_QOS_CTL_TID_MASK; ++ struct esp_node *node = ++ esp_get_node_by_addr(epub, wh->addr1); ++ { ++ struct esp_tx_tid *tid = ++ &node->tid[tidno]; ++ //record ssn ++ spin_lock_bh(&epub->tx_ampdu_lock); ++ tid->ssn = ++ GET_NEXT_SEQ(le16_to_cpu ++ (wh-> ++ seq_ctrl) >> 4); ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, ++ "tidno:%u,ssn:%u\n", ++ tidno, tid->ssn); ++ spin_unlock_bh(&epub-> ++ tx_ampdu_lock); ++ } ++ } else { ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, ++ "tx ampdu pkt, sn:%u, %u\n", ++ le16_to_cpu(wh-> ++ seq_ctrl) >> ++ 4, skb->len); ++ } ++ } ++ } ++#ifdef GEN_ERR_CHECKSUM ++ esp_gen_err_checksum(skb); ++#endif ++ ++ sip_tx_data_pkt_enqueue(epub, skb); ++ if (epub) ++ ieee80211_queue_work(hw, &epub->tx_work); ++} ++ ++static int esp_op_start(struct ieee80211_hw *hw) ++{ ++ struct esp_pub *epub; ++ ++ ESP_IEEE80211_DBG(ESP_DBG_OP, "%s\n", __func__); ++ ++ if (!hw) { ++ ESP_IEEE80211_DBG(ESP_DBG_ERROR, "%s no hw!\n", __func__); ++ return -EINVAL; ++ } ++ ++ epub = (struct esp_pub *) hw->priv; ++ ++ if (!epub) { ++ ESP_IEEE80211_DBG(ESP_DBG_ERROR, "%s no epub!\n", ++ __func__); ++ return EINVAL; ++ } ++ /*add rfkill poll function */ ++ ++ atomic_set(&epub->wl.off, 0); ++ wiphy_rfkill_start_polling(hw->wiphy); ++ return 0; ++} ++ ++static void esp_op_stop(struct ieee80211_hw *hw, bool flag) ++{ ++ struct esp_pub *epub; ++ ++ ESP_IEEE80211_DBG(ESP_DBG_OP, "%s\n", __func__); ++ ++ if (!hw) { ++ ESP_IEEE80211_DBG(ESP_DBG_ERROR, "%s no hw!\n", __func__); ++ return; ++ } ++ ++ epub = (struct esp_pub *) hw->priv; ++ ++ if (!epub) { ++ ESP_IEEE80211_DBG(ESP_DBG_ERROR, "%s no epub!\n", ++ __func__); ++ return; ++ } ++ ++ atomic_set(&epub->wl.off, 1); ++ ++#ifdef HOST_RESET_BUG ++ mdelay(200); ++#endif ++ ++ if (epub->wl.scan_req) { ++ hw_scan_done(epub, true); ++ epub->wl.scan_req = NULL; ++ //msleep(2); ++ } ++} ++ ++#ifdef CONFIG_PM ++static int esp_op_suspend(struct ieee80211_hw *hw, ++ struct cfg80211_wowlan *wowlan) ++{ ++ esp_dbg(ESP_DBG_OP, "%s\n", __func__); ++ ++ return 0; ++} ++ ++static int esp_op_resume(struct ieee80211_hw *hw) ++{ ++ esp_dbg(ESP_DBG_OP, "%s\n", __func__); ++ ++ return 0; ++} ++#endif //CONFIG_PM ++ ++static int esp_op_add_interface(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif) ++{ ++ struct esp_pub *epub = (struct esp_pub *) hw->priv; ++ struct esp_vif *evif = (struct esp_vif *) vif->drv_priv; ++ struct sip_cmd_setvif svif; ++ ++ ESP_IEEE80211_DBG(ESP_DBG_OP, "%s enter: type %d, addr %pM\n", ++ __func__, vif->type, vif->addr); ++ ++ memset(&svif, 0, sizeof(struct sip_cmd_setvif)); ++ memcpy(svif.mac, vif->addr, ETH_ALEN); ++ evif->index = svif.index = getaddr_index(vif->addr, epub); ++ evif->epub = epub; ++ epub->vif = vif; ++ svif.set = 1; ++ if ((1 << svif.index) & epub->vif_slot) { ++ ESP_IEEE80211_DBG(ESP_DBG_ERROR, ++ "%s interface %d already used\n", ++ __func__, svif.index); ++ return -EOPNOTSUPP; ++ } ++ epub->vif_slot |= 1 << svif.index; ++ ++ if (svif.index == ESP_PUB_MAX_VIF) { ++ ESP_IEEE80211_DBG(ESP_DBG_ERROR, ++ "%s only support MAX %d interface\n", ++ __func__, ESP_PUB_MAX_VIF); ++ return -EOPNOTSUPP; ++ } ++ ++ switch (vif->type) { ++ case NL80211_IFTYPE_STATION: ++ //if (svif.index == 1) ++ // vif->type = NL80211_IFTYPE_UNSPECIFIED; ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s STA \n", __func__); ++ svif.op_mode = 0; ++ svif.is_p2p = 0; ++ break; ++ case NL80211_IFTYPE_AP: ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s AP \n", __func__); ++ svif.op_mode = 1; ++ svif.is_p2p = 0; ++ break; ++ case NL80211_IFTYPE_P2P_CLIENT: ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s P2P_CLIENT \n", __func__); ++ svif.op_mode = 0; ++ svif.is_p2p = 1; ++ break; ++ case NL80211_IFTYPE_P2P_GO: ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s P2P_GO \n", __func__); ++ svif.op_mode = 1; ++ svif.is_p2p = 1; ++ break; ++ case NL80211_IFTYPE_UNSPECIFIED: ++ case NL80211_IFTYPE_ADHOC: ++ case NL80211_IFTYPE_AP_VLAN: ++ case NL80211_IFTYPE_WDS: ++ case NL80211_IFTYPE_MONITOR: ++ default: ++ ESP_IEEE80211_DBG(ESP_DBG_ERROR, ++ "%s does NOT support type %d\n", ++ __func__, vif->type); ++ return -EOPNOTSUPP; ++ } ++ ++ sip_cmd(epub, SIP_CMD_SETVIF, (u8 *) & svif, ++ sizeof(struct sip_cmd_setvif)); ++ return 0; ++} ++ ++static int esp_op_change_interface(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ enum nl80211_iftype new_type, bool p2p) ++{ ++ struct esp_pub *epub = (struct esp_pub *) hw->priv; ++ struct esp_vif *evif = (struct esp_vif *) vif->drv_priv; ++ struct sip_cmd_setvif svif; ++ ESP_IEEE80211_DBG(ESP_DBG_OP, "%s enter,change to if:%d \n", ++ __func__, new_type); ++ ++ if (new_type == NL80211_IFTYPE_AP) { ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter,change to AP \n", ++ __func__); ++ } ++ ++ if (vif->type != new_type) { ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s type from %d to %d\n", ++ __func__, vif->type, new_type); ++ } ++ ++ memset(&svif, 0, sizeof(struct sip_cmd_setvif)); ++ memcpy(svif.mac, vif->addr, ETH_ALEN); ++ svif.index = evif->index; ++ svif.set = 2; ++ ++ switch (new_type) { ++ case NL80211_IFTYPE_STATION: ++ svif.op_mode = 0; ++ svif.is_p2p = p2p; ++ break; ++ case NL80211_IFTYPE_AP: ++ svif.op_mode = 1; ++ svif.is_p2p = p2p; ++ break; ++ case NL80211_IFTYPE_P2P_CLIENT: ++ svif.op_mode = 0; ++ svif.is_p2p = 1; ++ break; ++ case NL80211_IFTYPE_P2P_GO: ++ svif.op_mode = 1; ++ svif.is_p2p = 1; ++ break; ++ case NL80211_IFTYPE_UNSPECIFIED: ++ case NL80211_IFTYPE_ADHOC: ++ case NL80211_IFTYPE_AP_VLAN: ++ case NL80211_IFTYPE_WDS: ++ case NL80211_IFTYPE_MONITOR: ++ default: ++ ESP_IEEE80211_DBG(ESP_DBG_ERROR, ++ "%s does NOT support type %d\n", ++ __func__, vif->type); ++ return -EOPNOTSUPP; ++ } ++ sip_cmd(epub, SIP_CMD_SETVIF, (u8 *) & svif, ++ sizeof(struct sip_cmd_setvif)); ++ return 0; ++} ++ ++static void esp_op_remove_interface(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif) ++{ ++ struct esp_pub *epub = (struct esp_pub *) hw->priv; ++ struct esp_vif *evif = (struct esp_vif *) vif->drv_priv; ++ struct sip_cmd_setvif svif; ++ ++ ESP_IEEE80211_DBG(ESP_DBG_OP, ++ "%s enter, vif addr %pM, beacon enable %x\n", ++ __func__, vif->addr, ++ vif->bss_conf.enable_beacon); ++ ++ memset(&svif, 0, sizeof(struct sip_cmd_setvif)); ++ svif.index = evif->index; ++ epub->vif_slot &= ~(1 << svif.index); ++ ++ if (evif->ap_up) { ++ evif->beacon_interval = 0; ++ del_timer_sync(&evif->beacon_timer); ++ evif->ap_up = false; ++ } ++ epub->vif = NULL; ++ evif->epub = NULL; ++ ++ sip_cmd(epub, SIP_CMD_SETVIF, (u8 *) & svif, ++ sizeof(struct sip_cmd_setvif)); ++ ++ /* clean up tx/rx queue */ ++ ++} ++ ++#define BEACON_TIM_SAVE_MAX 20 ++u8 beacon_tim_saved[BEACON_TIM_SAVE_MAX]; ++int beacon_tim_count; ++static void beacon_tim_init(void) ++{ ++ memset(beacon_tim_saved, 0, BEACON_TIM_SAVE_MAX); ++ beacon_tim_count = 0; ++} ++ ++static u8 beacon_tim_save(u8 this_tim) ++{ ++ u8 all_tim = 0; ++ int i; ++ beacon_tim_saved[beacon_tim_count] = this_tim; ++ if (++beacon_tim_count >= BEACON_TIM_SAVE_MAX) ++ beacon_tim_count = 0; ++ for (i = 0; i < BEACON_TIM_SAVE_MAX; i++) ++ all_tim |= beacon_tim_saved[i]; ++ return all_tim; ++} ++ ++static bool beacon_tim_alter(struct sk_buff *beacon) ++{ ++ u8 *p, *tim_end; ++ u8 tim_count; ++ int len; ++ int remain_len; ++ struct ieee80211_mgmt *mgmt; ++ ++ if (beacon == NULL) ++ return false; ++ ++ mgmt = (struct ieee80211_mgmt *) ((u8 *) beacon->data); ++ ++ remain_len = ++ beacon->len - ((u8 *) mgmt->u.beacon.variable - (u8 *) mgmt + ++ 12); ++ p = mgmt->u.beacon.variable; ++ ++ while (remain_len > 0) { ++ len = *(++p); ++ if (*p == WLAN_EID_TIM) { // tim field ++ tim_end = p + len; ++ tim_count = *(++p); ++ p += 2; ++ //multicast ++ if (tim_count == 0) ++ *p |= 0x1; ++ if ((*p & 0xfe) == 0 && tim_end >= p + 1) { // we only support 8 sta in this case ++ p++; ++ *p = beacon_tim_save(*p); ++ } ++ return tim_count == 0; ++ } ++ p += (len + 1); ++ remain_len -= (2 + len); ++ } ++ ++ return false; ++} ++ ++unsigned long init_jiffies; ++unsigned long cycle_beacon_count; ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) ++static void drv_handle_beacon(struct timer_list *t) ++#else ++static void drv_handle_beacon(unsigned long data) ++#endif ++{ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) ++ struct esp_vif *evif = from_timer(evif, t, beacon_timer); ++ struct ieee80211_vif *vif = evif->epub->vif; ++#else ++ struct ieee80211_vif *vif = (struct ieee80211_vif *) data; ++ struct esp_vif *evif = (struct esp_vif *) vif->drv_priv; ++#endif ++ struct sk_buff *beacon; ++ struct sk_buff *skb; ++ static int dbgcnt = 0; ++ bool tim_reach = false; ++ ++ if (evif->epub == NULL) ++ return; ++ ++ mdelay(2400 * (cycle_beacon_count % 25) % 10000 / 1000); ++ ++ beacon = ieee80211_beacon_get(evif->epub->hw, vif, 0); ++ ++ tim_reach = beacon_tim_alter(beacon); ++ ++ if (beacon && !(dbgcnt++ % 600)) { ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, " beacon length:%d,fc:0x%x\n", ++ beacon->len, ++ ((struct ieee80211_mgmt *) (beacon-> ++ data))-> ++ frame_control); ++ ++ } ++ ++ if (beacon) ++ sip_tx_data_pkt_enqueue(evif->epub, beacon); ++ ++ if (cycle_beacon_count++ == 100) { ++ init_jiffies = jiffies; ++ cycle_beacon_count -= 100; ++ } ++ mod_timer(&evif->beacon_timer, ++ init_jiffies + ++ msecs_to_jiffies(cycle_beacon_count * ++ vif->bss_conf.beacon_int * 1024 / ++ 1000)); ++ //FIXME:the packets must be sent at home channel ++ //send buffer mcast frames ++ if (tim_reach) { ++ skb = ieee80211_get_buffered_bc(evif->epub->hw, vif); ++ while (skb) { ++ sip_tx_data_pkt_enqueue(evif->epub, skb); ++ skb = ++ ieee80211_get_buffered_bc(evif->epub->hw, vif); ++ } ++ } ++} ++ ++static void init_beacon_timer(struct ieee80211_vif *vif) ++{ ++ struct esp_vif *evif = (struct esp_vif *) vif->drv_priv; ++ ++ ESP_IEEE80211_DBG(ESP_DBG_OP, " %s enter: beacon interval %x\n", ++ __func__, evif->beacon_interval); ++ ++ beacon_tim_init(); ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) ++ timer_setup(&evif->beacon_timer, drv_handle_beacon, 0); ++#else ++ init_timer(&evif->beacon_timer); //TBD, not init here... ++ evif->beacon_timer.data = (unsigned long) vif; ++ evif->beacon_timer.function = drv_handle_beacon; ++#endif ++ cycle_beacon_count = 1; ++ init_jiffies = jiffies; ++ evif->beacon_timer.expires = ++ init_jiffies + ++ msecs_to_jiffies(cycle_beacon_count * ++ vif->bss_conf.beacon_int * 1024 / 1000); ++ add_timer(&evif->beacon_timer); ++} ++ ++static int esp_op_config(struct ieee80211_hw *hw, u32 changed) ++{ ++ //struct ieee80211_conf *conf = &hw->conf; ++ ++ struct esp_pub *epub = (struct esp_pub *) hw->priv; ++ ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter 0x%08x\n", __func__, ++ changed); ++ ++ if (changed & ++ (IEEE80211_CONF_CHANGE_CHANNEL | IEEE80211_CONF_CHANGE_IDLE)) { ++ sip_send_config(epub, &hw->conf); ++ } ++ ++ return 0; ++} ++ ++static void esp_op_bss_info_changed(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ struct ieee80211_bss_conf *info, ++ u64 changed) ++{ ++ struct esp_pub *epub = (struct esp_pub *) hw->priv; ++ struct esp_vif *evif = (struct esp_vif *) vif->drv_priv; ++ ++ // ieee80211_bss_conf(include/net/mac80211.h) is included in ieee80211_sub_if_data(net/mac80211/ieee80211_i.h) , does bssid=ieee80211_if_ap's ssid ? ++ // in 2.6.27, ieee80211_sub_if_data has ieee80211_bss_conf while in 2.6.32 ieee80211_sub_if_data don't have ieee80211_bss_conf ++ // in 2.6.27, ieee80211_bss_conf->enable_beacon don't exist, does it mean it support beacon always? ++ // ESP_IEEE80211_DBG(ESP_DBG_OP, " %s enter: vif addr %pM, changed %x, assoc %x, bssid %pM\n", __func__, vif->addr, changed, vif->cfg.assoc, info->bssid); ++ // sdata->u.sta.bssid ++ ++ ESP_IEEE80211_DBG(ESP_DBG_OP, ++ " %s enter: changed %llx, assoc %x, bssid %pM\n", ++ __func__, changed, vif->cfg.assoc, info->bssid); ++ ++ if (vif->type == NL80211_IFTYPE_STATION) { ++ if ((changed & BSS_CHANGED_BSSID) || ++ ((changed & BSS_CHANGED_ASSOC) && (vif->cfg.assoc))) { ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, ++ " %s STA change bssid or assoc\n", ++ __func__); ++ evif->beacon_interval = vif->cfg.aid; ++ memcpy(epub->wl.bssid, (u8 *) info->bssid, ++ ETH_ALEN); ++ sip_send_bss_info_update(epub, evif, ++ (u8 *) info->bssid, ++ vif->cfg.assoc); ++ } else if ((changed & BSS_CHANGED_ASSOC) && (!vif->cfg.assoc)) { ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, ++ " %s STA change disassoc\n", ++ __func__); ++ evif->beacon_interval = 0; ++ memset(epub->wl.bssid, 0, ETH_ALEN); ++ sip_send_bss_info_update(epub, evif, ++ (u8 *) info->bssid, ++ vif->cfg.assoc); ++ } else { ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, ++ "%s wrong mode of STA mode\n", ++ __func__); ++ } ++ } else if (vif->type == NL80211_IFTYPE_AP) { ++ if ((changed & BSS_CHANGED_BEACON_ENABLED) || ++ (changed & BSS_CHANGED_BEACON_INT)) { ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, ++ " %s AP change enable %d, interval is %d, bssid %pM\n", ++ __func__, info->enable_beacon, ++ info->beacon_int, info->bssid); ++ if (info->enable_beacon && evif->ap_up != true) { ++ evif->beacon_interval = info->beacon_int; ++ init_beacon_timer(vif); ++ sip_send_bss_info_update(epub, evif, ++ (u8 *) info-> ++ bssid, 2); ++ evif->ap_up = true; ++ } else if (!info->enable_beacon && evif->ap_up && ++ !(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) ++ ) { ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, ++ " %s AP disable beacon, interval is %d\n", ++ __func__, ++ info->beacon_int); ++ evif->beacon_interval = 0; ++ del_timer_sync(&evif->beacon_timer); ++ sip_send_bss_info_update(epub, evif, ++ (u8 *) info-> ++ bssid, 2); ++ evif->ap_up = false; ++ } ++ } ++ } else { ++ ESP_IEEE80211_DBG(ESP_DBG_ERROR, ++ "%s op mode unspecified\n", __func__); ++ } ++} ++ ++ ++static u64 esp_op_prepare_multicast(struct ieee80211_hw *hw, ++ struct netdev_hw_addr_list *mc_list) ++{ ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter \n", __func__); ++ ++ return 0; ++} ++ ++static void esp_op_configure_filter(struct ieee80211_hw *hw, ++ unsigned int changed_flags, ++ unsigned int *total_flags, ++ u64 multicast) ++{ ++ struct esp_pub *epub = (struct esp_pub *) hw->priv; ++ ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter \n", __func__); ++ ++ epub->rx_filter = 0; ++ ++ if (*total_flags & FIF_ALLMULTI) ++ epub->rx_filter |= FIF_ALLMULTI; ++ ++ *total_flags = epub->rx_filter; ++} ++ ++static int esp_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta, ++ struct ieee80211_key_conf *key) ++{ ++ u8 i; ++ int ret; ++ struct esp_pub *epub = (struct esp_pub *) hw->priv; ++ struct esp_vif *evif = (struct esp_vif *) vif->drv_priv; ++ u8 ifidx = evif->index; ++ u8 *peer_addr, isvalid; ++ ++ ESP_IEEE80211_DBG(ESP_DBG_OP, ++ "%s enter, flags = %x keyindx = %x cmd = %x mac = %pM cipher = %x\n", ++ __func__, key->flags, key->keyidx, cmd, ++ vif->addr, key->cipher); ++ ++ key->flags = key->flags | IEEE80211_KEY_FLAG_GENERATE_IV; ++ ++ if (sta) { ++ if (memcmp(sta->addr, epub->wl.bssid, ETH_ALEN)) ++ peer_addr = sta->addr; ++ else ++ peer_addr = epub->wl.bssid; ++ } else { ++ peer_addr = epub->wl.bssid; ++ } ++ isvalid = (cmd == SET_KEY) ? 1 : 0; ++ ++ if ((key->flags & IEEE80211_KEY_FLAG_PAIRWISE) ++ || (key->cipher == WLAN_CIPHER_SUITE_WEP40 ++ || key->cipher == WLAN_CIPHER_SUITE_WEP104)) { ++ if (isvalid) { ++ for (i = 0; i < 19; i++) { ++ if (epub->hi_map[i].flag == 0) { ++ epub->hi_map[i].flag = 1; ++ key->hw_key_idx = i + 6; ++ memcpy(epub->hi_map[i].mac, ++ peer_addr, ETH_ALEN); ++ break; ++ } ++ } ++ } else { ++ u8 index = key->hw_key_idx - 6; ++ epub->hi_map[index].flag = 0; ++ memset(epub->hi_map[index].mac, 0, ETH_ALEN); ++ } ++ } else { ++ if (isvalid) { ++ for (i = 0; i < 2; i++) ++ if (epub->low_map[ifidx][i].flag == 0) { ++ epub->low_map[ifidx][i].flag = 1; ++ key->hw_key_idx = ++ i + ifidx * 2 + 2; ++ memcpy(epub->low_map[ifidx][i].mac, ++ peer_addr, ETH_ALEN); ++ break; ++ } ++ } else { ++ u8 index = key->hw_key_idx - 2 - ifidx * 2; ++ epub->low_map[ifidx][index].flag = 0; ++ memset(epub->low_map[ifidx][index].mac, 0, ++ ETH_ALEN); ++ } ++ //key->hw_key_idx = key->keyidx + ifidx * 2 + 1; ++ } ++ ++ if (key->hw_key_idx >= 6) { ++ /*send sub_scan task to target */ ++ //epub->wl.ptk = (cmd==SET_KEY) ? key : NULL; ++ if (isvalid) ++ atomic_inc(&epub->wl.ptk_cnt); ++ else ++ atomic_dec(&epub->wl.ptk_cnt); ++ if (key->cipher == WLAN_CIPHER_SUITE_WEP40 ++ || key->cipher == WLAN_CIPHER_SUITE_WEP104) { ++ if (isvalid) ++ atomic_inc(&epub->wl.gtk_cnt); ++ else ++ atomic_dec(&epub->wl.gtk_cnt); ++ } ++ } else { ++ /*send sub_scan task to target */ ++ if (isvalid) ++ atomic_inc(&epub->wl.gtk_cnt); ++ else ++ atomic_dec(&epub->wl.gtk_cnt); ++ ++ if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 ++ || key->cipher == WLAN_CIPHER_SUITE_WEP104)) { ++ if (isvalid) ++ atomic_inc(&epub->wl.ptk_cnt); ++ else ++ atomic_dec(&epub->wl.ptk_cnt); ++ //epub->wl.ptk = (cmd==SET_KEY) ? key : NULL; ++ } ++ } ++ ++ ret = sip_send_setkey(epub, ifidx, peer_addr, key, isvalid); ++ ++ if ((key->cipher == WLAN_CIPHER_SUITE_TKIP ++ || key->cipher == WLAN_CIPHER_SUITE_TKIP)) { ++ if (ret == 0) ++ atomic_set(&epub->wl.tkip_key_set, 1); ++ } ++ ++ ESP_IEEE80211_DBG(ESP_DBG_OP, "%s exit\n", __func__); ++ return ret; ++} ++ ++static void esp_op_update_tkip_key(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ struct ieee80211_key_conf *conf, ++ struct ieee80211_sta *sta, ++ u32 iv32, u16 * phase1key) ++{ ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter \n", __func__); ++ ++} ++ ++void hw_scan_done(struct esp_pub *epub, bool aborted) ++{ ++ cancel_delayed_work_sync(&epub->scan_timeout_work); ++ ++ ESSERT(epub->wl.scan_req != NULL); ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)) ++ { ++ struct cfg80211_scan_info info = { ++ .aborted = aborted, ++ }; ++ ++ ieee80211_scan_completed(epub->hw, &info); ++ } ++#else ++ ieee80211_scan_completed(epub->hw, aborted); ++#endif ++ if (test_and_clear_bit(ESP_WL_FLAG_STOP_TXQ, &epub->wl.flags)) { ++ sip_trigger_txq_process(epub->sip); ++ } ++} ++ ++static void hw_scan_timeout_report(struct work_struct *work) ++{ ++ struct esp_pub *epub = ++ container_of(work, struct esp_pub, scan_timeout_work.work); ++ bool aborted; ++ ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, "eagle hw scan done\n"); ++ ++ if (test_and_clear_bit(ESP_WL_FLAG_STOP_TXQ, &epub->wl.flags)) { ++ sip_trigger_txq_process(epub->sip); ++ } ++ /*check if normally complete or aborted like timeout/hw error */ ++ aborted = (epub->wl.scan_req) ? true : false; ++ ++ if (aborted == true) { ++ epub->wl.scan_req = NULL; ++ } ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)) ++ { ++ struct cfg80211_scan_info info = { ++ .aborted = aborted, ++ }; ++ ++ ieee80211_scan_completed(epub->hw, &info); ++ } ++#else ++ ieee80211_scan_completed(epub->hw, aborted); ++#endif ++} ++ ++static int esp_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value) ++{ ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter \n", __func__); ++ ++ return 0; ++} ++ ++static int esp_node_attach(struct ieee80211_hw *hw, u8 ifidx, ++ struct ieee80211_sta *sta) ++{ ++ struct esp_pub *epub = (struct esp_pub *) hw->priv; ++ struct esp_node *node; ++ u8 tidno; ++ struct esp_tx_tid *tid; ++ int i; ++ ++ spin_lock_bh(&epub->tx_ampdu_lock); ++ ++ if (hweight32(epub->enodes_maps[ifidx]) < ESP_PUB_MAX_STA ++ && (i = ffz(epub->enodes_map)) < ESP_PUB_MAX_STA + 1) { ++ epub->enodes_map |= (1 << i); ++ epub->enodes_maps[ifidx] |= (1 << i); ++ node = (struct esp_node *) sta->drv_priv; ++ epub->enodes[i] = node; ++ node->sta = sta; ++ node->ifidx = ifidx; ++ node->index = i; ++ ++ for (tidno = 0, tid = &node->tid[tidno]; ++ tidno < WME_NUM_TID; tidno++) { ++ tid->ssn = 0; ++ tid->cnt = 0; ++ tid->state = ESP_TID_STATE_INIT; ++ } ++ ++ ++ } else { ++ i = -1; ++ } ++ ++ spin_unlock_bh(&epub->tx_ampdu_lock); ++ return i; ++} ++ ++static int esp_node_detach(struct ieee80211_hw *hw, u8 ifidx, ++ struct ieee80211_sta *sta) ++{ ++ struct esp_pub *epub = (struct esp_pub *) hw->priv; ++ u32 map; ++ int i; ++ struct esp_node *node = NULL; ++ ++ spin_lock_bh(&epub->tx_ampdu_lock); ++ map = epub->enodes_maps[ifidx]; ++ while (map != 0) { ++ i = ffs(map) - 1; ++ if (epub->enodes[i]->sta == sta) { ++ epub->enodes[i]->sta = NULL; ++ node = epub->enodes[i]; ++ epub->enodes[i] = NULL; ++ epub->enodes_map &= ~(1 << i); ++ epub->enodes_maps[ifidx] &= ~(1 << i); ++ ++ spin_unlock_bh(&epub->tx_ampdu_lock); ++ return i; ++ } ++ map &= ~(1 << i); ++ } ++ ++ spin_unlock_bh(&epub->tx_ampdu_lock); ++ return -1; ++} ++ ++struct esp_node *esp_get_node_by_addr(struct esp_pub *epub, ++ const u8 * addr) ++{ ++ int i; ++ u32 map; ++ struct esp_node *node = NULL; ++ if (addr == NULL) ++ return NULL; ++ spin_lock_bh(&epub->tx_ampdu_lock); ++ map = epub->enodes_map; ++ while (map != 0) { ++ i = ffs(map) - 1; ++ if (i < 0) { ++ spin_unlock_bh(&epub->tx_ampdu_lock); ++ return NULL; ++ } ++ map &= ~(1 << i); ++ if (memcmp(epub->enodes[i]->sta->addr, addr, ETH_ALEN) == ++ 0) { ++ node = epub->enodes[i]; ++ break; ++ } ++ } ++ ++ spin_unlock_bh(&epub->tx_ampdu_lock); ++ return node; ++} ++ ++struct esp_node *esp_get_node_by_index(struct esp_pub *epub, u8 index) ++{ ++ u32 map; ++ struct esp_node *node = NULL; ++ ++ if (epub == NULL) ++ return NULL; ++ ++ spin_lock_bh(&epub->tx_ampdu_lock); ++ map = epub->enodes_map; ++ if (map & BIT(index)) { ++ node = epub->enodes[index]; ++ } else { ++ spin_unlock_bh(&epub->tx_ampdu_lock); ++ return NULL; ++ } ++ ++ spin_unlock_bh(&epub->tx_ampdu_lock); ++ return node; ++} ++ ++int esp_get_empty_rxampdu(struct esp_pub *epub, const u8 * addr, u8 tid) ++{ ++ int index = -1; ++ if (addr == NULL) ++ return index; ++ spin_lock_bh(&epub->rx_ampdu_lock); ++ if ((index = ffz(epub->rxampdu_map)) < ESP_PUB_MAX_RXAMPDU) { ++ epub->rxampdu_map |= BIT(index); ++ epub->rxampdu_node[index] = ++ esp_get_node_by_addr(epub, addr); ++ epub->rxampdu_tid[index] = tid; ++ } else { ++ index = -1; ++ } ++ spin_unlock_bh(&epub->rx_ampdu_lock); ++ return index; ++} ++ ++int esp_get_exist_rxampdu(struct esp_pub *epub, const u8 * addr, u8 tid) ++{ ++ u8 map; ++ int index = -1; ++ int i; ++ if (addr == NULL) ++ return index; ++ spin_lock_bh(&epub->rx_ampdu_lock); ++ map = epub->rxampdu_map; ++ while (map != 0) { ++ i = ffs(map) - 1; ++ if (i < 0) { ++ spin_unlock_bh(&epub->rx_ampdu_lock); ++ return index; ++ } ++ map &= ~BIT(i); ++ if (epub->rxampdu_tid[i] == tid && ++ memcmp(epub->rxampdu_node[i]->sta->addr, addr, ++ ETH_ALEN) == 0) { ++ index = i; ++ break; ++ } ++ } ++ ++ epub->rxampdu_map &= ~BIT(index); ++ spin_unlock_bh(&epub->rx_ampdu_lock); ++ return index; ++ ++} ++ ++static int esp_op_sta_add(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta) ++{ ++ struct esp_pub *epub = (struct esp_pub *) hw->priv; ++ struct esp_vif *evif = (struct esp_vif *) vif->drv_priv; ++ int index; ++ ESP_IEEE80211_DBG(ESP_DBG_OP, ++ "%s enter, vif addr %pM, sta addr %pM\n", ++ __func__, vif->addr, sta->addr); ++ index = esp_node_attach(hw, evif->index, sta); ++ ++ if (index < 0) ++ return -1; ++ sip_send_set_sta(epub, evif->index, 1, sta, vif, (u8) index); ++ return 0; ++} ++ ++static int esp_op_sta_remove(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta) ++{ ++ struct esp_pub *epub = (struct esp_pub *) hw->priv; ++ struct esp_vif *evif = (struct esp_vif *) vif->drv_priv; ++ int index; ++ ++ ESP_IEEE80211_DBG(ESP_DBG_OP, ++ "%s enter, vif addr %pM, sta addr %pM\n", ++ __func__, vif->addr, sta->addr); ++ ++ //remove a connect in target ++ index = esp_node_detach(hw, evif->index, sta); ++ sip_send_set_sta(epub, evif->index, 0, sta, vif, (u8) index); ++ ++ return 0; ++} ++ ++ ++static void esp_op_sta_notify(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ enum sta_notify_cmd cmd, ++ struct ieee80211_sta *sta) ++{ ++ ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter \n", __func__); ++ ++ switch (cmd) { ++ case STA_NOTIFY_SLEEP: ++ break; ++ ++ case STA_NOTIFY_AWAKE: ++ break; ++ ++ default: ++ break; ++ } ++} ++ ++ ++static int esp_op_conf_tx(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ u32 link_id, u16 queue, ++ const struct ieee80211_tx_queue_params *params) ++{ ++ struct esp_pub *epub = (struct esp_pub *) hw->priv; ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter \n", __func__); ++ return sip_send_wmm_params(epub, queue, params); ++} ++ ++static u64 esp_op_get_tsf(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif) ++{ ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter \n", __func__); ++ ++ return 0; ++} ++ ++static void esp_op_set_tsf(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, u64 tsf) ++{ ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter \n", __func__); ++} ++ ++static void esp_op_reset_tsf(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif) ++{ ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter \n", __func__); ++ ++} ++ ++static void esp_op_rfkill_poll(struct ieee80211_hw *hw) ++{ ++ struct esp_pub *epub = (struct esp_pub *) hw->priv; ++ ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter \n", __func__); ++ ++ wiphy_rfkill_set_hw_state(hw->wiphy, ++ test_bit(ESP_WL_FLAG_RFKILL, ++ &epub->wl. ++ flags) ? true : false); ++} ++ ++#ifdef HW_SCAN ++static int esp_op_hw_scan(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ struct cfg80211_scan_request *req) ++{ ++ struct esp_pub *epub = (struct esp_pub *) hw->priv; ++ int i, ret; ++ bool scan_often = true; ++ ++ ESP_IEEE80211_DBG(ESP_DBG_OP, "%s\n", __func__); ++ ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, "scan, %d\n", req->n_ssids); ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, "scan, len 1:%d,ssid 1:%s\n", ++ req->ssids->ssid_len, ++ req->ssids->ssid_len == ++ 0 ? "" : (char *) req->ssids->ssid); ++ if (req->n_ssids > 1) ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, ++ "scan, len 2:%d,ssid 2:%s\n", ++ (req->ssids + 1)->ssid_len, ++ (req->ssids + 1)->ssid_len == ++ 0 ? "" : (char *) (req->ssids + ++ 1)->ssid); ++ ++ /*scan_request is keep allocate untill scan_done,record it ++ to split request into multi sdio_cmd */ ++ if (atomic_read(&epub->wl.off)) { ++ esp_dbg(ESP_DBG_ERROR, "%s scan but wl off \n", __func__); ++ return -EPERM; ++ } ++ ++ if (req->n_ssids > 1) { ++ struct cfg80211_ssid *ssid2 = req->ssids + 1; ++ if ((req->ssids->ssid_len > 0 && ssid2->ssid_len > 0) ++ || req->n_ssids > 2) { ++ ESP_IEEE80211_DBG(ESP_DBG_ERROR, ++ "scan ssid num: %d, ssid1:%s, ssid2:%s,not support\n", ++ req->n_ssids, ++ req->ssids->ssid_len == ++ 0 ? "" : (char *) req->ssids-> ++ ssid, ++ ssid2->ssid_len == ++ 0 ? "" : (char *) ssid2->ssid); ++ return -EINVAL; ++ } ++ } ++ ++ epub->wl.scan_req = req; ++ ++ for (i = 0; i < req->n_channels; i++) ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, "eagle hw_scan freq %d\n", ++ req->channels[i]->center_freq); ++#if 0 ++ for (i = 0; i < req->n_ssids; i++) { ++ if (req->ssids->ssid_len > 0) { ++ req->ssids->ssid[req->ssids->ssid_len] = '\0'; ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, ++ "scan_ssid %d:%s\n", i, ++ req->ssids->ssid); ++ } ++ } ++#endif ++ ++ /*in connect state, suspend tx data */ ++ if (epub->sip->support_bgscan && ++ test_bit(ESP_WL_FLAG_CONNECT, &epub->wl.flags) && ++ req->n_channels > 0) { ++ ++ scan_often = epub->scan_permit_valid ++ && time_before(jiffies, epub->scan_permit); ++ epub->scan_permit_valid = true; ++ ++ if (!scan_often) { ++/* epub->scan_permit = jiffies + msecs_to_jiffies(900); ++ set_bit(ESP_WL_FLAG_STOP_TXQ, &epub->wl.flags); ++ if (atomic_read(&epub->txq_stopped) == false) { ++ atomic_set(&epub->txq_stopped, true); ++ ieee80211_stop_queues(hw); ++ } ++*/ ++ } else { ++ ESP_IEEE80211_DBG(ESP_DBG_LOG, "scan too often\n"); ++ return -EACCES; ++ } ++ } else { ++ scan_often = false; ++ } ++ ++ /*send sub_scan task to target */ ++ ret = sip_send_scan(epub); ++ ++ if (ret) { ++ ESP_IEEE80211_DBG(ESP_DBG_ERROR, ++ "fail to send scan_cmd\n"); ++ return ret; ++ } else { ++ if (!scan_often) { ++ epub->scan_permit = ++ jiffies + msecs_to_jiffies(900); ++ set_bit(ESP_WL_FLAG_STOP_TXQ, &epub->wl.flags); ++ if (atomic_read(&epub->txq_stopped) == false) { ++ atomic_set(&epub->txq_stopped, true); ++ ieee80211_stop_queues(hw); ++ } ++ /*force scan complete in case target fail to report in time */ ++ ieee80211_queue_delayed_work(hw, ++ &epub-> ++ scan_timeout_work, ++ req->n_channels * HZ / ++ 4); ++ } ++ } ++ ++ return 0; ++} ++ ++static int esp_op_remain_on_channel(struct ieee80211_hw *hw, ++ struct ieee80211_channel *chan, ++ enum nl80211_channel_type channel_type, ++ int duration) ++{ ++ struct esp_pub *epub = (struct esp_pub *) hw->priv; ++ ++ ESP_IEEE80211_DBG(ESP_DBG_OP, ++ "%s enter, center_freq = %d duration = %d\n", ++ __func__, chan->center_freq, duration); ++ sip_send_roc(epub, chan->center_freq, duration); ++ return 0; ++} ++ ++static int esp_op_cancel_remain_on_channel(struct ieee80211_hw *hw) ++{ ++ struct esp_pub *epub = (struct esp_pub *) hw->priv; ++ ++ ESP_IEEE80211_DBG(ESP_DBG_OP, "%s enter \n", __func__); ++ epub->roc_flags = 0; // to disable roc state ++ sip_send_roc(epub, 0, 0); ++ return 0; ++} ++#endif ++ ++void esp_rocdone_process(struct ieee80211_hw *hw, ++ struct sip_evt_roc *report) ++{ ++ struct esp_pub *epub = (struct esp_pub *) hw->priv; ++ ++ ESP_IEEE80211_DBG(ESP_DBG_OP, "%s enter, state = %d is_ok = %d\n", ++ __func__, report->state, report->is_ok); ++ ++ //roc process begin ++ if ((report->state == 1) && (report->is_ok == 1)) { ++ epub->roc_flags = 1; //flags in roc state, to fix channel, not change ++ ieee80211_ready_on_channel(hw); ++ } else if ((report->state == 0) && (report->is_ok == 1)) //roc process timeout ++ { ++ epub->roc_flags = 0; // to disable roc state ++ ieee80211_remain_on_channel_expired(hw); ++ } ++} ++ ++static int esp_op_set_bitrate_mask(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ const struct cfg80211_bitrate_mask ++ *mask) ++{ ++ ESP_IEEE80211_DBG(ESP_DBG_OP, "%s enter \n", __func__); ++ ESP_IEEE80211_DBG(ESP_DBG_OP, "%s vif->macaddr[%pM], mask[%d]\n", ++ __func__, vif->addr, mask->control[0].legacy); ++ ++ return 0; ++} ++ ++static void esp_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, ++ u32 queues, bool drop) ++{ ++ ++ ESP_IEEE80211_DBG(ESP_DBG_OP, "%s enter \n", __func__); ++ do { ++ ++ struct esp_pub *epub = (struct esp_pub *) hw->priv; ++ unsigned long time = jiffies + msecs_to_jiffies(15); ++ while (atomic_read(&epub->sip->tx_data_pkt_queued)) { ++ if (!time_before(jiffies, time)) { ++ break; ++ } ++ if (sif_get_ate_config() == 0) { ++ ieee80211_queue_work(epub->hw, ++ &epub->tx_work); ++ } else { ++ queue_work(epub->esp_wkq, &epub->tx_work); ++ } ++ //sip_txq_process(epub); ++ } ++ mdelay(10); ++ ++ } while (0); ++} ++ ++static int esp_op_ampdu_action(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ struct ieee80211_ampdu_params *params) ++{ ++ int ret = -EOPNOTSUPP; ++ enum ieee80211_ampdu_mlme_action action = params->action; ++ struct ieee80211_sta *sta = params->sta; ++ u16 tid = params->tid; ++ u16 *ssn = ¶ms->ssn; ++ u8 buf_size = params->buf_size; ++ struct esp_pub *epub = (struct esp_pub *) hw->priv; ++ struct esp_node *node = (struct esp_node *) sta->drv_priv; ++ struct esp_tx_tid *tid_info = &node->tid[tid]; ++ ++ ESP_IEEE80211_DBG(ESP_DBG_OP, "%s enter \n", __func__); ++ switch (action) { ++ case IEEE80211_AMPDU_TX_START: ++ if (mod_support_no_txampdu() || ++ cfg80211_get_chandef_type(&epub->hw->conf.chandef) == ++ NL80211_CHAN_NO_HT || !sta->deflink.ht_cap.ht_supported) ++ return ret; ++ ++ //if (vif->p2p || vif->type != NL80211_IFTYPE_STATION) ++ // return ret; ++ ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, ++ "%s TX START, addr:%pM,tid:%u,state:%d\n", ++ __func__, sta->addr, tid, ++ tid_info->state); ++ spin_lock_bh(&epub->tx_ampdu_lock); ++ ESSERT(tid_info->state == ESP_TID_STATE_TRIGGER); ++ *ssn = tid_info->ssn; ++ tid_info->state = ESP_TID_STATE_PROGRESS; ++ ++ ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); ++ spin_unlock_bh(&epub->tx_ampdu_lock); ++ ret = 0; ++ break; ++ case IEEE80211_AMPDU_TX_STOP_CONT: ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, ++ "%s TX STOP, addr:%pM,tid:%u,state:%d\n", ++ __func__, sta->addr, tid, ++ tid_info->state); ++ spin_lock_bh(&epub->tx_ampdu_lock); ++ if (tid_info->state == ESP_TID_STATE_WAIT_STOP) ++ tid_info->state = ESP_TID_STATE_STOP; ++ else ++ tid_info->state = ESP_TID_STATE_INIT; ++ ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); ++ spin_unlock_bh(&epub->tx_ampdu_lock); ++ ret = ++ sip_send_ampdu_action(epub, SIP_AMPDU_TX_STOP, ++ sta->addr, tid, node->ifidx, 0); ++ break; ++ case IEEE80211_AMPDU_TX_STOP_FLUSH: ++ case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: ++ if (tid_info->state == ESP_TID_STATE_WAIT_STOP) ++ tid_info->state = ESP_TID_STATE_STOP; ++ else ++ tid_info->state = ESP_TID_STATE_INIT; ++ ret = ++ sip_send_ampdu_action(epub, SIP_AMPDU_TX_STOP, ++ sta->addr, tid, node->ifidx, 0); ++ break; ++ case IEEE80211_AMPDU_TX_OPERATIONAL: ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, ++ "%s TX OPERATION, addr:%pM,tid:%u,state:%d\n", ++ __func__, sta->addr, tid, ++ tid_info->state); ++ spin_lock_bh(&epub->tx_ampdu_lock); ++ ++ if (tid_info->state != ESP_TID_STATE_PROGRESS) { ++ if (tid_info->state == ESP_TID_STATE_INIT) { ++ printk(KERN_ERR "%s WIFI RESET, IGNORE\n", ++ __func__); ++ spin_unlock_bh(&epub->tx_ampdu_lock); ++ return -ENETRESET; ++ } else { ++ ESSERT(0); ++ } ++ } ++ ++ tid_info->state = ESP_TID_STATE_OPERATIONAL; ++ spin_unlock_bh(&epub->tx_ampdu_lock); ++ ret = ++ sip_send_ampdu_action(epub, SIP_AMPDU_TX_OPERATIONAL, ++ sta->addr, tid, node->ifidx, ++ buf_size); ++ break; ++ case IEEE80211_AMPDU_RX_START: ++ if (mod_support_no_rxampdu() || ++ cfg80211_get_chandef_type(&epub->hw->conf.chandef) == ++ NL80211_CHAN_NO_HT || !sta->deflink.ht_cap.ht_supported) ++ return ret; ++ ++ if ((vif->p2p && false) ++ || (vif->type != NL80211_IFTYPE_STATION && false) ++ ) ++ return ret; ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, ++ "%s RX START %pM tid %u %u\n", __func__, ++ sta->addr, tid, *ssn); ++ ret = ++ sip_send_ampdu_action(epub, SIP_AMPDU_RX_START, ++ sta->addr, tid, *ssn, 64); ++ break; ++ case IEEE80211_AMPDU_RX_STOP: ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s RX STOP %pM tid %u\n", ++ __func__, sta->addr, tid); ++ ret = ++ sip_send_ampdu_action(epub, SIP_AMPDU_RX_STOP, ++ sta->addr, tid, 0, 0); ++ break; ++ default: ++ break; ++ } ++ return ret; ++} ++ ++static void esp_tx_work(struct work_struct *work) ++{ ++ struct esp_pub *epub = container_of(work, struct esp_pub, tx_work); ++ ++ mutex_lock(&epub->tx_mtx); ++ sip_txq_process(epub); ++ mutex_unlock(&epub->tx_mtx); ++} ++ ++static const struct ieee80211_ops esp_mac80211_ops = { ++ .tx = esp_op_tx, ++ .start = esp_op_start, ++ .stop = esp_op_stop, ++#ifdef CONFIG_PM ++ .suspend = esp_op_suspend, ++ .resume = esp_op_resume, ++#endif ++ .add_interface = esp_op_add_interface, ++ .remove_interface = esp_op_remove_interface, ++ .config = esp_op_config, ++ ++ .bss_info_changed = esp_op_bss_info_changed, ++ .prepare_multicast = esp_op_prepare_multicast, ++ .configure_filter = esp_op_configure_filter, ++ .set_key = esp_op_set_key, ++ .update_tkip_key = esp_op_update_tkip_key, ++ //.sched_scan_start = esp_op_sched_scan_start, ++ //.sched_scan_stop = esp_op_sched_scan_stop, ++ .set_rts_threshold = esp_op_set_rts_threshold, ++ .sta_notify = esp_op_sta_notify, ++ .conf_tx = esp_op_conf_tx, ++ .change_interface = esp_op_change_interface, ++ .get_tsf = esp_op_get_tsf, ++ .set_tsf = esp_op_set_tsf, ++ .reset_tsf = esp_op_reset_tsf, ++ .rfkill_poll = esp_op_rfkill_poll, ++ .add_chanctx = ieee80211_emulate_add_chanctx, ++ .remove_chanctx = ieee80211_emulate_remove_chanctx, ++ .change_chanctx = ieee80211_emulate_change_chanctx, ++#ifdef HW_SCAN ++ .hw_scan = esp_op_hw_scan, ++ .remain_on_channel = esp_op_remain_on_channel, ++ .cancel_remain_on_channel = esp_op_cancel_remain_on_channel, ++#endif ++ .ampdu_action = esp_op_ampdu_action, ++ //.get_survey = esp_op_get_survey, ++ .sta_add = esp_op_sta_add, ++ .sta_remove = esp_op_sta_remove, ++#ifdef CONFIG_NL80211_TESTMODE ++ //CFG80211_TESTMODE_CMD(esp_op_tm_cmd) ++#endif ++ .set_bitrate_mask = esp_op_set_bitrate_mask, ++ .flush = esp_op_flush, ++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, ++}; ++ ++struct esp_pub *esp_pub_alloc_mac80211(struct device *dev) ++{ ++ struct ieee80211_hw *hw; ++ struct esp_pub *epub; ++ int ret = 0; ++ ++ hw = ieee80211_alloc_hw(sizeof(struct esp_pub), &esp_mac80211_ops); ++ ++ if (hw == NULL) { ++ esp_dbg(ESP_DBG_ERROR, "ieee80211 can't alloc hw!\n"); ++ ret = -ENOMEM; ++ return ERR_PTR(ret); ++ } ++ hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; ++ ++ epub = hw->priv; ++ memset(epub, 0, sizeof(*epub)); ++ epub->hw = hw; ++ SET_IEEE80211_DEV(hw, dev); ++ epub->dev = dev; ++ ++ skb_queue_head_init(&epub->txq); ++ skb_queue_head_init(&epub->txdoneq); ++ skb_queue_head_init(&epub->rxq); ++ ++ spin_lock_init(&epub->tx_ampdu_lock); ++ spin_lock_init(&epub->rx_ampdu_lock); ++ spin_lock_init(&epub->tx_lock); ++ mutex_init(&epub->tx_mtx); ++ spin_lock_init(&epub->rx_lock); ++ ++ INIT_WORK(&epub->tx_work, esp_tx_work); ++ ++ //epub->esp_wkq = create_freezable_workqueue("esp_wkq"); ++ epub->esp_wkq = create_singlethread_workqueue("esp_wkq"); ++ ++ if (epub->esp_wkq == NULL) { ++ ret = -ENOMEM; ++ return ERR_PTR(ret); ++ } ++ epub->scan_permit_valid = false; ++ INIT_DELAYED_WORK(&epub->scan_timeout_work, ++ hw_scan_timeout_report); ++ ++ return epub; ++} ++ ++ ++int esp_pub_dealloc_mac80211(struct esp_pub *epub) ++{ ++ set_bit(ESP_WL_FLAG_RFKILL, &epub->wl.flags); ++ ++ destroy_workqueue(epub->esp_wkq); ++ mutex_destroy(&epub->tx_mtx); ++ ++#ifdef ESP_NO_MAC80211 ++ free_netdev(epub->net_dev); ++ wiphy_free(epub->wdev->wiphy); ++ kfree(epub->wdev); ++#else ++ if (epub->hw) { ++ ieee80211_free_hw(epub->hw); ++ } ++#endif ++ ++ return 0; ++} ++ ++#if 0 ++static int esp_reg_notifier(struct wiphy *wiphy, ++ struct regulatory_request *request) ++{ ++ struct ieee80211_supported_band *sband; ++ struct ieee80211_channel *ch; ++ int i; ++ ++ ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter %d\n", __func__, ++ request->initiator); ++ ++ //TBD ++} ++#endif ++ ++/* 2G band channels */ ++static struct ieee80211_channel esp_channels_2ghz[] = { ++ {.hw_value = 1,.center_freq = 2412,.max_power = 25}, ++ {.hw_value = 2,.center_freq = 2417,.max_power = 25}, ++ {.hw_value = 3,.center_freq = 2422,.max_power = 25}, ++ {.hw_value = 4,.center_freq = 2427,.max_power = 25}, ++ {.hw_value = 5,.center_freq = 2432,.max_power = 25}, ++ {.hw_value = 6,.center_freq = 2437,.max_power = 25}, ++ {.hw_value = 7,.center_freq = 2442,.max_power = 25}, ++ {.hw_value = 8,.center_freq = 2447,.max_power = 25}, ++ {.hw_value = 9,.center_freq = 2452,.max_power = 25}, ++ {.hw_value = 10,.center_freq = 2457,.max_power = 25}, ++ {.hw_value = 11,.center_freq = 2462,.max_power = 25}, ++ {.hw_value = 12,.center_freq = 2467,.max_power = 25}, ++ {.hw_value = 13,.center_freq = 2472,.max_power = 25}, ++ //{ .hw_value = 14, .center_freq = 2484, .max_power = 25 }, ++}; ++ ++/* 11G rate */ ++static struct ieee80211_rate esp_rates_2ghz[] = { ++ { ++ .bitrate = 10, ++ .hw_value = CONF_HW_BIT_RATE_1MBPS, ++ .hw_value_short = CONF_HW_BIT_RATE_1MBPS, ++ }, ++ { ++ .bitrate = 20, ++ .hw_value = CONF_HW_BIT_RATE_2MBPS, ++ .hw_value_short = CONF_HW_BIT_RATE_2MBPS, ++ .flags = IEEE80211_RATE_SHORT_PREAMBLE}, ++ { ++ .bitrate = 55, ++ .hw_value = CONF_HW_BIT_RATE_5_5MBPS, ++ .hw_value_short = CONF_HW_BIT_RATE_5_5MBPS, ++ .flags = IEEE80211_RATE_SHORT_PREAMBLE}, ++ { ++ .bitrate = 110, ++ .hw_value = CONF_HW_BIT_RATE_11MBPS, ++ .hw_value_short = CONF_HW_BIT_RATE_11MBPS, ++ .flags = IEEE80211_RATE_SHORT_PREAMBLE}, ++ { ++ .bitrate = 60, ++ .hw_value = CONF_HW_BIT_RATE_6MBPS, ++ .hw_value_short = CONF_HW_BIT_RATE_6MBPS, ++ }, ++ { ++ .bitrate = 90, ++ .hw_value = CONF_HW_BIT_RATE_9MBPS, ++ .hw_value_short = CONF_HW_BIT_RATE_9MBPS, ++ }, ++ { ++ .bitrate = 120, ++ .hw_value = CONF_HW_BIT_RATE_12MBPS, ++ .hw_value_short = CONF_HW_BIT_RATE_12MBPS, ++ }, ++ { ++ .bitrate = 180, ++ .hw_value = CONF_HW_BIT_RATE_18MBPS, ++ .hw_value_short = CONF_HW_BIT_RATE_18MBPS, ++ }, ++ { ++ .bitrate = 240, ++ .hw_value = CONF_HW_BIT_RATE_24MBPS, ++ .hw_value_short = CONF_HW_BIT_RATE_24MBPS, ++ }, ++ { ++ .bitrate = 360, ++ .hw_value = CONF_HW_BIT_RATE_36MBPS, ++ .hw_value_short = CONF_HW_BIT_RATE_36MBPS, ++ }, ++ { ++ .bitrate = 480, ++ .hw_value = CONF_HW_BIT_RATE_48MBPS, ++ .hw_value_short = CONF_HW_BIT_RATE_48MBPS, ++ }, ++ { ++ .bitrate = 540, ++ .hw_value = CONF_HW_BIT_RATE_54MBPS, ++ .hw_value_short = CONF_HW_BIT_RATE_54MBPS, ++ }, ++}; ++ ++static void esp_pub_init_mac80211(struct esp_pub *epub) ++{ ++ struct ieee80211_hw *hw = epub->hw; ++ ++ static const u32 cipher_suites[] = { ++ WLAN_CIPHER_SUITE_WEP40, ++ WLAN_CIPHER_SUITE_WEP104, ++ WLAN_CIPHER_SUITE_TKIP, ++ WLAN_CIPHER_SUITE_CCMP, ++ }; ++ ++ hw->max_listen_interval = 10; ++ ++ ieee80211_hw_set(hw, SIGNAL_DBM); ++ ieee80211_hw_set(hw, HAS_RATE_CONTROL); ++ ieee80211_hw_set(hw, SUPPORTS_PS); ++ ieee80211_hw_set(hw, AMPDU_AGGREGATION); ++ ieee80211_hw_set(hw, HOST_BROADCAST_PS_BUFFERING); ++ //IEEE80211_HW_PS_NULLFUNC_STACK | ++ //IEEE80211_HW_CONNECTION_MONITOR | ++ //IEEE80211_HW_BEACON_FILTER | ++ //IEEE80211_HW_AMPDU_AGGREGATION | ++ //IEEE80211_HW_REPORTS_TX_ACK_STATUS; ++ hw->max_rx_aggregation_subframes = 0x40; ++ hw->max_tx_aggregation_subframes = 0x40; ++ ++ hw->wiphy->cipher_suites = cipher_suites; ++ hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); ++ hw->wiphy->max_scan_ie_len = ++ epub->sip->tx_blksz - sizeof(struct sip_hdr) - ++ sizeof(struct sip_cmd_scan); ++ ++ /* ONLY station for now, support P2P soon... */ ++ hw->wiphy->interface_modes = ++ BIT(NL80211_IFTYPE_P2P_GO) | ++ BIT(NL80211_IFTYPE_P2P_CLIENT) | ++ BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP); ++ ++ hw->wiphy->max_scan_ssids = 2; ++ //hw->wiphy->max_sched_scan_ssids = 16; ++ //hw->wiphy->max_match_sets = 16; ++ ++ hw->wiphy->max_remain_on_channel_duration = 5000; ++ ++ atomic_set(&epub->wl.off, 1); ++ ++ epub->wl.sbands[NL80211_BAND_2GHZ].band = NL80211_BAND_2GHZ; ++ epub->wl.sbands[NL80211_BAND_2GHZ].channels = esp_channels_2ghz; ++ epub->wl.sbands[NL80211_BAND_2GHZ].bitrates = esp_rates_2ghz; ++ epub->wl.sbands[NL80211_BAND_2GHZ].n_channels = ++ ARRAY_SIZE(esp_channels_2ghz); ++ epub->wl.sbands[NL80211_BAND_2GHZ].n_bitrates = ++ ARRAY_SIZE(esp_rates_2ghz); ++ /*add to support 11n */ ++ epub->wl.sbands[NL80211_BAND_2GHZ].ht_cap.ht_supported = true; ++ epub->wl.sbands[NL80211_BAND_2GHZ].ht_cap.cap = 0x116C; //IEEE80211_HT_CAP_RX_STBC; //IEEE80211_HT_CAP_SGI_20; ++ epub->wl.sbands[NL80211_BAND_2GHZ].ht_cap.ampdu_factor = ++ IEEE80211_HT_MAX_AMPDU_16K; ++ epub->wl.sbands[NL80211_BAND_2GHZ].ht_cap.ampdu_density = ++ IEEE80211_HT_MPDU_DENSITY_NONE; ++ memset(&epub->wl.sbands[NL80211_BAND_2GHZ].ht_cap.mcs, 0, ++ sizeof(epub->wl.sbands[NL80211_BAND_2GHZ].ht_cap.mcs)); ++ epub->wl.sbands[NL80211_BAND_2GHZ].ht_cap.mcs.rx_mask[0] = 0xff; ++ //epub->wl.sbands[NL80211_BAND_2GHZ].ht_cap.mcs.rx_highest = 7; ++ //epub->wl.sbands[NL80211_BAND_2GHZ].ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; ++ ++ /* BAND_5GHZ TBD */ ++ ++ hw->wiphy->bands[NL80211_BAND_2GHZ] = ++ &epub->wl.sbands[NL80211_BAND_2GHZ]; ++ /* BAND_5GHZ TBD */ ++ ++ /*no fragment */ ++ hw->wiphy->frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD; ++ ++ /* handle AC queue in f/w */ ++ hw->queues = 4; ++ hw->max_rates = 4; ++ //hw->wiphy->reg_notifier = esp_reg_notify; ++ ++ hw->vif_data_size = sizeof(struct esp_vif); ++ hw->sta_data_size = sizeof(struct esp_node); ++ ++ //hw->max_rx_aggregation_subframes = 8; ++} ++ ++int esp_register_mac80211(struct esp_pub *epub) ++{ ++ int ret = 0; ++ u8 *wlan_addr; ++ u8 *p2p_addr; ++ int idx; ++ ++ esp_pub_init_mac80211(epub); ++ ++ epub->hw->wiphy->addresses = (struct mac_address *) esp_mac_addr; ++ memcpy(&epub->hw->wiphy->addresses[0], epub->mac_addr, ETH_ALEN); ++ memcpy(&epub->hw->wiphy->addresses[1], epub->mac_addr, ETH_ALEN); ++ wlan_addr = (u8 *) & epub->hw->wiphy->addresses[0]; ++ p2p_addr = (u8 *) & epub->hw->wiphy->addresses[1]; ++ ++ for (idx = 0; idx < 64; idx++) { ++ p2p_addr[0] = wlan_addr[0] | 0x02; ++ p2p_addr[0] ^= idx << 2; ++ if (strncmp(p2p_addr, wlan_addr, 6) != 0) ++ break; ++ } ++ ++ epub->hw->wiphy->n_addresses = 2; ++ ++ ret = ieee80211_register_hw(epub->hw); ++ ++ if (ret < 0) { ++ ESP_IEEE80211_DBG(ESP_DBG_ERROR, ++ "unable to register mac80211 hw: %d\n", ++ ret); ++ return ret; ++ } else { ++#ifdef MAC80211_NO_CHANGE ++ rtnl_lock(); ++ if (epub->hw->wiphy->interface_modes & ++ (BIT(NL80211_IFTYPE_P2P_GO) | ++ BIT(NL80211_IFTYPE_P2P_CLIENT))) { ++ ret = ++ ieee80211_if_add(hw_to_local(epub->hw), ++ "p2p%d", NULL, ++ NL80211_IFTYPE_STATION, NULL); ++ if (ret) ++ wiphy_warn(epub->hw->wiphy, ++ "Failed to add default virtual iface\n"); ++ } ++ ++ rtnl_unlock(); ++#endif ++ } ++ ++ set_bit(ESP_WL_FLAG_HW_REGISTERED, &epub->wl.flags); ++ ++ return ret; ++} ++ ++static u8 getaddr_index(u8 * addr, struct esp_pub *epub) ++{ ++ int i; ++ for (i = 0; i < ESP_PUB_MAX_VIF; i++) ++ if (memcmp ++ (addr, (u8 *) & epub->hw->wiphy->addresses[i], ++ ETH_ALEN) == 0) ++ return i; ++ return ESP_PUB_MAX_VIF; ++} +diff --git a/drivers/net/wireless/esp8089/esp_mac80211.h b/drivers/net/wireless/esp8089/esp_mac80211.h +new file mode 100644 +index 000000000000..699b27dcadd1 +--- /dev/null ++++ b/drivers/net/wireless/esp8089/esp_mac80211.h +@@ -0,0 +1,38 @@ ++/* ++ * Copyright (c) 2011-2014 Espressif System. ++ * ++ * MAC80211 support module ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++#ifndef _ESP_MAC80211_H_ ++#define _ESP_MAC80211_H_ ++ ++struct esp_80211_wmm_ac_param { ++ u8 aci_aifsn; /* AIFSN, ACM, ACI */ ++ u8 cw; /* ECWmin, ECWmax (CW = 2^ECW - 1) */ ++ u16 txop_limit; ++}; ++ ++struct esp_80211_wmm_param_element { ++ /* Element ID: 221 (0xdd); length: 24 */ ++ /* required fields for WMM version 1 */ ++ u8 oui[3]; /* 00:50:f2 */ ++ u8 oui_type; /* 2 */ ++ u8 oui_subtype; /* 1 */ ++ u8 version; /* 1 for WMM version 1.0 */ ++ u8 qos_info; /* AP/STA specif QoS info */ ++ u8 reserved; /* 0 */ ++ struct esp_80211_wmm_ac_param ac[4]; /* AC_BE, AC_BK, AC_VI, AC_VO */ ++}; ++ ++ ++#endif /* _ESP_MAC80211_H_ */ +diff --git a/drivers/net/wireless/esp8089/esp_main.c b/drivers/net/wireless/esp8089/esp_main.c +new file mode 100644 +index 000000000000..404e0d7a6f54 +--- /dev/null ++++ b/drivers/net/wireless/esp8089/esp_main.c +@@ -0,0 +1,263 @@ ++/* ++ * Copyright (c) 2010 - 2014 Espressif System. ++ * ++ * main routine ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "esp_pub.h" ++#include "esp_sip.h" ++#include "esp_sif.h" ++#include "esp_debug.h" ++#include "esp_file.h" ++#include "esp_wl.h" ++ ++struct completion *gl_bootup_cplx = NULL; ++ ++#ifndef FPGA_DEBUG ++static int esp_download_fw(struct esp_pub *epub); ++#endif /* !FGPA_DEBUG */ ++ ++static int modparam_no_txampdu = 0; ++static int modparam_no_rxampdu = 0; ++module_param_named(no_txampdu, modparam_no_txampdu, int, 0444); ++MODULE_PARM_DESC(no_txampdu, "Disable tx ampdu."); ++module_param_named(no_rxampdu, modparam_no_rxampdu, int, 0444); ++MODULE_PARM_DESC(no_rxampdu, "Disable rx ampdu."); ++ ++static char *modparam_eagle_path = "/lib/firmware"; ++module_param_named(eagle_path, modparam_eagle_path, charp, 0444); ++MODULE_PARM_DESC(eagle_path, "eagle path"); ++ ++bool mod_support_no_txampdu() ++{ ++ return modparam_no_txampdu; ++} ++ ++bool mod_support_no_rxampdu() ++{ ++ return modparam_no_rxampdu; ++} ++ ++void mod_support_no_txampdu_set(bool value) ++{ ++ modparam_no_txampdu = value; ++} ++ ++char *mod_eagle_path_get(void) ++{ ++ if (modparam_eagle_path[0] == '\0') ++ return NULL; ++ ++ return modparam_eagle_path; ++} ++ ++int esp_pub_init_all(struct esp_pub *epub) ++{ ++ int ret = 0; ++ ++ /* completion for bootup event poll */ ++ DECLARE_COMPLETION_ONSTACK(complete); ++ atomic_set(&epub->ps.state, ESP_PM_OFF); ++ if (epub->sdio_state == ESP_SDIO_STATE_FIRST_INIT) { ++ epub->sip = sip_attach(epub); ++ if (epub->sip == NULL) { ++ printk(KERN_ERR "%s sip alloc failed\n", __func__); ++ return -ENOMEM; ++ } ++ ++ esp_dump_var("esp_msg_level", NULL, &esp_msg_level, ++ ESP_U32); ++ ++#ifdef ESP_ANDROID_LOGGER ++ esp_dump_var("log_off", NULL, &log_off, ESP_U32); ++#endif /* ESP_ANDROID_LOGGER */ ++ } else { ++ atomic_set(&epub->sip->state, SIP_PREPARE_BOOT); ++ atomic_set(&epub->sip->tx_credits, 0); ++ } ++ ++ epub->sip->to_host_seq = 0; ++ ++#ifdef TEST_MODE ++ if (sif_get_ate_config() != 0 && sif_get_ate_config() != 1 ++ && sif_get_ate_config() != 6) { ++ esp_test_init(epub); ++ return -1; ++ } ++#endif ++ ++#ifndef FPGA_DEBUG ++ ret = esp_download_fw(epub); ++#ifdef TEST_MODE ++ if (sif_get_ate_config() == 6) { ++ sif_enable_irq(epub); ++ mdelay(500); ++ sif_disable_irq(epub); ++ mdelay(1000); ++ esp_test_init(epub); ++ return -1; ++ } ++#endif ++ if (ret) { ++ esp_dbg(ESP_DBG_ERROR, "download firmware failed\n"); ++ return ret; ++ } ++ ++ esp_dbg(ESP_DBG_TRACE, "download firmware OK \n"); ++#else ++ sip_send_bootup(epub->sip); ++#endif /* FPGA_DEBUG */ ++ ++ gl_bootup_cplx = &complete; ++ epub->wait_reset = 0; ++ sif_enable_irq(epub); ++ ++ if (epub->sdio_state == ESP_SDIO_STATE_SECOND_INIT ++ || sif_get_ate_config() == 1) { ++ ret = sip_poll_bootup_event(epub->sip); ++ } else { ++ ret = sip_poll_resetting_event(epub->sip); ++ if (ret == 0) { ++ sif_lock_bus(epub); ++ sif_interrupt_target(epub, 7); ++ sif_unlock_bus(epub); ++ } ++ ++ } ++ ++ gl_bootup_cplx = NULL; ++ ++ if (sif_get_ate_config() == 1) ++ ret = -EOPNOTSUPP; ++ ++ return ret; ++} ++ ++void esp_dsr(struct esp_pub *epub) ++{ ++ sip_rx(epub); ++} ++ ++ ++struct esp_fw_hdr { ++ u8 magic; ++ u8 blocks; ++ u8 pad[2]; ++ u32 entry_addr; ++} __packed; ++ ++struct esp_fw_blk_hdr { ++ u32 load_addr; ++ u32 data_len; ++} __packed; ++ ++#define ESP_FW_NAME1 "eagle_fw_ate_config_v19.bin" ++#define ESP_FW_NAME2 "eagle_fw_first_init_v19.bin" ++#define ESP_FW_NAME3 "eagle_fw_second_init_v19.bin" ++ ++#ifndef FPGA_DEBUG ++static int esp_download_fw(struct esp_pub *epub) ++{ ++ const struct firmware *fw_entry; ++ u8 *fw_buf = NULL; ++ u32 offset = 0; ++ int ret = 0; ++ u8 blocks; ++ struct esp_fw_hdr *fhdr; ++ struct esp_fw_blk_hdr *bhdr = NULL; ++ struct sip_cmd_bootup bootcmd; ++ char *esp_fw_name; ++ ++ if (sif_get_ate_config() == 1) { ++ esp_fw_name = ESP_FW_NAME3; ++ } else { ++ esp_fw_name = ++ epub->sdio_state == ++ ESP_SDIO_STATE_FIRST_INIT ? ESP_FW_NAME1 : ++ ESP_FW_NAME2; ++ } ++ ret = request_firmware(&fw_entry, esp_fw_name, epub->dev); ++ ++ if (ret) ++ return ret; ++ ++ fw_buf = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL); ++ ++ release_firmware(fw_entry); ++ ++ if (fw_buf == NULL) { ++ return -ENOMEM; ++ } ++ ++ fhdr = (struct esp_fw_hdr *) fw_buf; ++ ++ if (fhdr->magic != 0xE9) { ++ esp_dbg(ESP_DBG_ERROR, "%s wrong magic! \n", __func__); ++ goto _err; ++ } ++ ++ blocks = fhdr->blocks; ++ offset += sizeof(struct esp_fw_hdr); ++ ++ while (blocks) { ++ ++ bhdr = (struct esp_fw_blk_hdr *) (&fw_buf[offset]); ++ offset += sizeof(struct esp_fw_blk_hdr); ++ ++ ret = ++ sip_write_memory(epub->sip, bhdr->load_addr, ++ &fw_buf[offset], bhdr->data_len); ++ ++ if (ret) { ++ esp_dbg(ESP_DBG_ERROR, ++ "%s Failed to write fw, err: %d\n", ++ __func__, ret); ++ goto _err; ++ } ++ ++ blocks--; ++ offset += bhdr->data_len; ++ } ++ ++ /* TODO: last byte should be the checksum and skip checksum for now */ ++ ++ bootcmd.boot_addr = fhdr->entry_addr; ++ ret = ++ sip_send_cmd(epub->sip, SIP_CMD_BOOTUP, ++ sizeof(struct sip_cmd_bootup), &bootcmd); ++ ++ if (ret) ++ goto _err; ++ ++ _err: ++ kfree(fw_buf); ++ ++ return ret; ++ ++} ++ ++MODULE_FIRMWARE(ESP_FW_NAME1); ++MODULE_FIRMWARE(ESP_FW_NAME2); ++MODULE_FIRMWARE(ESP_FW_NAME3); ++#endif /* !FPGA_DEBUG */ +diff --git a/drivers/net/wireless/esp8089/esp_path.h b/drivers/net/wireless/esp8089/esp_path.h +new file mode 100644 +index 000000000000..1ceb14bc3b15 +--- /dev/null ++++ b/drivers/net/wireless/esp8089/esp_path.h +@@ -0,0 +1,6 @@ ++#ifndef _ESP_PATH_H_ ++#define _ESP_PATH_H_ ++#define FWPATH "/lib/firmware" ++//module_param_string(fwpath, fwpath, sizeof(fwpath), 0644); ++ ++#endif /* _ESP_PATH_H_ */ +diff --git a/drivers/net/wireless/esp8089/esp_pub.h b/drivers/net/wireless/esp8089/esp_pub.h +new file mode 100644 +index 000000000000..0d3ad3655cf4 +--- /dev/null ++++ b/drivers/net/wireless/esp8089/esp_pub.h +@@ -0,0 +1,222 @@ ++/* ++ * Copyright (c) 2011-2014 Espressif System. ++ * ++ * wlan device header file ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _ESP_PUB_H_ ++#define _ESP_PUB_H_ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "sip2_common.h" ++ ++enum esp_sdio_state { ++ ESP_SDIO_STATE_FIRST_INIT, ++ ESP_SDIO_STATE_FIRST_NORMAL_EXIT, ++ ESP_SDIO_STATE_FIRST_ERROR_EXIT, ++ ESP_SDIO_STATE_SECOND_INIT, ++ ESP_SDIO_STATE_SECOND_ERROR_EXIT, ++}; ++ ++enum esp_tid_state { ++ ESP_TID_STATE_INIT, ++ ESP_TID_STATE_TRIGGER, ++ ESP_TID_STATE_PROGRESS, ++ ESP_TID_STATE_OPERATIONAL, ++ ESP_TID_STATE_WAIT_STOP, ++ ESP_TID_STATE_STOP, ++}; ++ ++struct esp_tx_tid { ++ u8 state; ++ u8 cnt; ++ u16 ssn; ++}; ++ ++#define WME_NUM_TID 16 ++struct esp_node { ++ struct esp_tx_tid tid[WME_NUM_TID]; ++ struct ieee80211_sta *sta; ++ u8 ifidx; ++ u8 index; ++}; ++ ++#define WME_AC_BE 2 ++#define WME_AC_BK 3 ++#define WME_AC_VI 1 ++#define WME_AC_VO 0 ++ ++struct llc_snap_hdr { ++ u8 dsap; ++ u8 ssap; ++ u8 cntl; ++ u8 org_code[3]; ++ __be16 eth_type; ++} __packed; ++ ++struct esp_vif { ++ struct esp_pub *epub; ++ u8 index; ++ u32 beacon_interval; ++ bool ap_up; ++ struct timer_list beacon_timer; ++}; ++ ++/* WLAN related, mostly... */ ++/*struct hw_scan_timeout { ++ struct delayed_work w; ++ struct ieee80211_hw *hw; ++};*/ ++ ++typedef struct esp_wl { ++ u8 bssid[ETH_ALEN]; ++ u8 req_bssid[ETH_ALEN]; ++ ++ //struct hw_scan_timeout *hsd; ++ struct cfg80211_scan_request *scan_req; ++ atomic_t ptk_cnt; ++ atomic_t gtk_cnt; ++ atomic_t tkip_key_set; ++ ++ /* so far only 2G band */ ++ struct ieee80211_supported_band sbands[NUM_NL80211_BANDS]; ++ ++ unsigned long flags; ++ atomic_t off; ++} esp_wl_t; ++ ++typedef struct esp_hw_idx_map { ++ u8 mac[ETH_ALEN]; ++ u8 flag; ++} esp_hw_idx_map_t; ++ ++#define ESP_WL_FLAG_RFKILL BIT(0) ++#define ESP_WL_FLAG_HW_REGISTERED BIT(1) ++#define ESP_WL_FLAG_CONNECT BIT(2) ++#define ESP_WL_FLAG_STOP_TXQ BIT(3) ++ ++#define ESP_PUB_MAX_VIF 2 ++#define ESP_PUB_MAX_STA 16 //for one interface ++#define ESP_PUB_MAX_RXAMPDU 8 //for all interfaces ++ ++enum { ++ ESP_PM_OFF = 0, ++ ESP_PM_TURNING_ON, ++ ESP_PM_ON, ++ ESP_PM_TURNING_OFF, /* Do NOT change the order */ ++}; ++ ++struct esp_ps { ++ u32 dtim_period; ++ u32 max_sleep_period; ++ unsigned long last_config_time; ++ atomic_t state; ++ bool nulldata_pm_on; ++}; ++ ++struct esp_mac_prefix { ++ u8 mac_index; ++ u8 mac_addr_prefix[3]; ++}; ++ ++struct esp_pub { ++ struct device *dev; ++#ifdef ESP_NO_MAC80211 ++ struct net_device *net_dev; ++ struct wireless_dev *wdev; ++ struct net_device_stats *net_stats; ++#else ++ struct ieee80211_hw *hw; ++ struct ieee80211_vif *vif; ++ u8 vif_slot; ++#endif /* ESP_MAC80211 */ ++ ++ void *sif; /* serial interface control block, e.g. sdio */ ++ enum esp_sdio_state sdio_state; ++ struct esp_sip *sip; ++ struct esp_wl wl; ++ struct esp_hw_idx_map hi_map[19]; ++ struct esp_hw_idx_map low_map[ESP_PUB_MAX_VIF][2]; ++ //u32 flags; //flags to represent rfkill switch,start ++ u8 roc_flags; //0: not in remain on channel state, 1: in roc state ++ ++ struct work_struct tx_work; /* attach to ieee80211 workqueue */ ++ /* latest mac80211 has multiple tx queue, but we stick with single queue now */ ++ spinlock_t rx_lock; ++ spinlock_t tx_ampdu_lock; ++ spinlock_t rx_ampdu_lock; ++ spinlock_t tx_lock; ++ struct mutex tx_mtx; ++ struct sk_buff_head txq; ++ atomic_t txq_stopped; ++ ++ struct work_struct sendup_work; /* attach to ieee80211 workqueue */ ++ struct sk_buff_head txdoneq; ++ struct sk_buff_head rxq; ++ ++ struct workqueue_struct *esp_wkq; ++ ++ //u8 bssid[ETH_ALEN]; ++ u8 mac_addr[ETH_ALEN]; ++ ++ u32 rx_filter; ++ unsigned long scan_permit; ++ bool scan_permit_valid; ++ struct delayed_work scan_timeout_work; ++ u32 enodes_map; ++ u8 rxampdu_map; ++ u32 enodes_maps[ESP_PUB_MAX_VIF]; ++ struct esp_node *enodes[ESP_PUB_MAX_STA + 1]; ++ struct esp_node *rxampdu_node[ESP_PUB_MAX_RXAMPDU]; ++ u8 rxampdu_tid[ESP_PUB_MAX_RXAMPDU]; ++ struct esp_ps ps; ++ int enable_int; ++ int wait_reset; ++}; ++ ++typedef struct esp_pub esp_pub_t; ++ ++struct esp_pub *esp_pub_alloc_mac80211(struct device *dev); ++int esp_pub_dealloc_mac80211(struct esp_pub *epub); ++int esp_register_mac80211(struct esp_pub *epub); ++ ++int esp_pub_init_all(struct esp_pub *epub); ++ ++char *mod_eagle_path_get(void); ++ ++void esp_dsr(struct esp_pub *epub); ++void hw_scan_done(struct esp_pub *epub, bool aborted); ++void esp_rocdone_process(struct ieee80211_hw *hw, ++ struct sip_evt_roc *report); ++ ++void esp_ps_config(struct esp_pub *epub, struct esp_ps *ps, bool on); ++ ++struct esp_node *esp_get_node_by_addr(struct esp_pub *epub, ++ const u8 * addr); ++struct esp_node *esp_get_node_by_index(struct esp_pub *epub, u8 index); ++int esp_get_empty_rxampdu(struct esp_pub *epub, const u8 * addr, u8 tid); ++int esp_get_exist_rxampdu(struct esp_pub *epub, const u8 * addr, u8 tid); ++ ++#ifdef TEST_MODE ++int test_init_netlink(struct esp_sip *sip); ++void test_exit_netlink(void); ++void esp_test_cmd_event(u32 cmd_type, char *reply_info); ++void esp_test_init(struct esp_pub *epub); ++#endif ++#endif /* _ESP_PUB_H_ */ +diff --git a/drivers/net/wireless/esp8089/esp_sif.h b/drivers/net/wireless/esp8089/esp_sif.h +new file mode 100644 +index 000000000000..2d49f2bc8035 +--- /dev/null ++++ b/drivers/net/wireless/esp8089/esp_sif.h +@@ -0,0 +1,207 @@ ++/* ++ * Copyright (c) 2011 - 2014 Espressif System. ++ * ++ * Serial I/F wrapper layer for eagle WLAN device, ++ * abstraction of buses like SDIO/SIP, and provides ++ * flow control for tx/rx layer ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _ESP_SIF_H_ ++#define _ESP_SIF_H_ ++ ++#include "esp_pub.h" ++#include ++#include ++ ++/* ++ * H/W SLC module definitions ++ */ ++ ++#define SIF_SLC_BLOCK_SIZE 512 ++ ++ ++/* S/W struct mapping to slc registers */ ++typedef struct slc_host_regs { ++ /* do NOT read token_rdata ++ * ++ u32 pf_data; ++ u32 token_rdata; ++ */ ++ u32 intr_raw; ++ u32 state_w0; ++ u32 state_w1; ++ u32 config_w0; ++ u32 config_w1; ++ u32 intr_status; ++ u32 config_w2; ++ u32 config_w3; ++ u32 config_w4; ++ u32 token_wdata; ++ u32 intr_clear; ++ u32 intr_enable; ++} sif_slc_reg_t; ++ ++ ++enum io_sync_type { ++ ESP_SIF_NOSYNC = 0, ++ ESP_SIF_SYNC, ++}; ++ ++typedef struct esp_sdio_ctrl { ++ struct sdio_func *func; ++ struct esp_pub *epub; ++ ++ ++ struct list_head free_req; ++ ++ u8 *dma_buffer; ++ ++ spinlock_t scat_lock; ++ struct list_head scat_req; ++ ++ bool off; ++ atomic_t irq_handling; ++ const struct sdio_device_id *id; ++ u32 slc_blk_sz; ++ u32 target_id; ++ u32 slc_window_end_addr; ++ ++ struct slc_host_regs slc_regs; ++ atomic_t irq_installed; ++ ++} esp_sdio_ctrl_t; ++ ++#define SIF_TO_DEVICE 0x1 ++#define SIF_FROM_DEVICE 0x2 ++ ++#define SIF_SYNC 0x00000010 ++#define SIF_ASYNC 0x00000020 ++ ++#define SIF_BYTE_BASIS 0x00000040 ++#define SIF_BLOCK_BASIS 0x00000080 ++ ++#define SIF_FIXED_ADDR 0x00000100 ++#define SIF_INC_ADDR 0x00000200 ++ ++#define EPUB_CTRL_CHECK(_epub, _go_err) do{\ ++ if (_epub == NULL) {\ ++ ESSERT(0);\ ++ goto _go_err;\ ++ }\ ++ if ((_epub)->sif == NULL) {\ ++ ESSERT(0);\ ++ goto _go_err;\ ++ }\ ++}while(0) ++ ++#define EPUB_FUNC_CHECK(_epub, _go_err) do{\ ++ if (_epub == NULL) {\ ++ ESSERT(0);\ ++ goto _go_err;\ ++ }\ ++ if ((_epub)->sif == NULL) {\ ++ ESSERT(0);\ ++ goto _go_err;\ ++ }\ ++ if (((struct esp_sdio_ctrl *)(_epub)->sif)->func == NULL) {\ ++ ESSERT(0);\ ++ goto _go_err;\ ++ }\ ++}while(0) ++ ++#define EPUB_TO_CTRL(_epub) (((struct esp_sdio_ctrl *)(_epub)->sif)) ++ ++#define EPUB_TO_FUNC(_epub) (((struct esp_sdio_ctrl *)(_epub)->sif)->func) ++ ++void sdio_io_writeb(struct esp_pub *epub, u8 value, int addr, int *res); ++u8 sdio_io_readb(struct esp_pub *epub, int addr, int *res); ++ ++ ++void sif_enable_irq(struct esp_pub *epub); ++void sif_disable_irq(struct esp_pub *epub); ++void sif_disable_target_interrupt(struct esp_pub *epub); ++ ++u32 sif_get_blksz(struct esp_pub *epub); ++u32 sif_get_target_id(struct esp_pub *epub); ++ ++void sif_dsr(struct sdio_func *func); ++int sif_io_raw(struct esp_pub *epub, u32 addr, u8 * buf, u32 len, ++ u32 flag); ++int sif_io_sync(struct esp_pub *epub, u32 addr, u8 * buf, u32 len, ++ u32 flag); ++int sif_io_async(struct esp_pub *epub, u32 addr, u8 * buf, u32 len, ++ u32 flag, void *context); ++int sif_lldesc_read_sync(struct esp_pub *epub, u8 * buf, u32 len); ++int sif_lldesc_write_sync(struct esp_pub *epub, u8 * buf, u32 len); ++int sif_lldesc_read_raw(struct esp_pub *epub, u8 * buf, u32 len, ++ bool noround); ++int sif_lldesc_write_raw(struct esp_pub *epub, u8 * buf, u32 len); ++ ++int sif_platform_get_irq_no(void); ++int sif_platform_is_irq_occur(void); ++void sif_platform_irq_clear(void); ++void sif_platform_irq_mask(int enable_mask); ++int sif_platform_irq_init(void); ++void sif_platform_irq_deinit(void); ++ ++int esp_common_read(struct esp_pub *epub, u8 * buf, u32 len, int sync, ++ bool noround); ++int esp_common_write(struct esp_pub *epub, u8 * buf, u32 len, int sync); ++int esp_common_read_with_addr(struct esp_pub *epub, u32 addr, u8 * buf, ++ u32 len, int sync); ++int esp_common_write_with_addr(struct esp_pub *epub, u32 addr, u8 * buf, ++ u32 len, int sync); ++ ++int esp_common_readbyte_with_addr(struct esp_pub *epub, u32 addr, u8 * buf, ++ int sync); ++int esp_common_writebyte_with_addr(struct esp_pub *epub, u32 addr, u8 buf, ++ int sync); ++ ++int sif_read_reg_window(struct esp_pub *epub, unsigned int reg_addr, ++ unsigned char *value); ++int sif_write_reg_window(struct esp_pub *epub, unsigned int reg_addr, ++ unsigned char *value); ++int sif_ack_target_read_err(struct esp_pub *epub); ++int sif_had_io_enable(struct esp_pub *epub); ++ ++struct slc_host_regs *sif_get_regs(struct esp_pub *epub); ++ ++void sif_lock_bus(struct esp_pub *epub); ++void sif_unlock_bus(struct esp_pub *epub); ++ ++int sif_interrupt_target(struct esp_pub *epub, u8 index); ++#ifdef USE_EXT_GPIO ++int sif_config_gpio_mode(struct esp_pub *epub, u8 gpio_num, u8 gpio_mode); ++int sif_set_gpio_output(struct esp_pub *epub, u16 mask, u16 value); ++int sif_get_gpio_intr(struct esp_pub *epub, u16 intr_mask, u16 * value); ++int sif_get_gpio_input(struct esp_pub *epub, u16 * mask, u16 * value); ++#endif ++ ++void check_target_id(struct esp_pub *epub); ++ ++void sif_record_bt_config(int value); ++int sif_get_bt_config(void); ++void sif_record_rst_config(int value); ++int sif_get_rst_config(void); ++void sif_record_ate_config(int value); ++int sif_get_ate_config(void); ++void sif_record_retry_config(void); ++int sif_get_retry_config(void); ++void sif_record_wakeup_gpio_config(int value); ++int sif_get_wakeup_gpio_config(void); ++ ++#define sif_reg_read_sync(epub, addr, buf, len) sif_io_sync((epub), (addr), (buf), (len), SIF_FROM_DEVICE | SIF_BYTE_BASIS | SIF_INC_ADDR) ++ ++#define sif_reg_write_sync(epub, addr, buf, len) sif_io_sync((epub), (addr), (buf), (len), SIF_TO_DEVICE | SIF_BYTE_BASIS | SIF_INC_ADDR) ++ ++#endif /* _ESP_SIF_H_ */ +diff --git a/drivers/net/wireless/esp8089/esp_sip.c b/drivers/net/wireless/esp8089/esp_sip.c +new file mode 100644 +index 000000000000..6602a1e22ab1 +--- /dev/null ++++ b/drivers/net/wireless/esp8089/esp_sip.c +@@ -0,0 +1,2420 @@ ++/* ++ * Copyright (c) 2009 - 2014 Espressif System. ++ * ++ * Serial Interconnctor Protocol ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "esp_mac80211.h" ++#include "esp_pub.h" ++#include "esp_sip.h" ++#include "esp_ctrl.h" ++#include "esp_sif.h" ++#include "esp_debug.h" ++#include "slc_host_register.h" ++#include "esp_wmac.h" ++#include "esp_utils.h" ++ ++#ifdef USE_EXT_GPIO ++#include "esp_ext.h" ++#endif /* USE_EXT_GPIO */ ++ ++extern struct completion *gl_bootup_cplx; ++ ++static int old_signal = -35; ++static int avg_signal = 0; ++static int signal_loop = 0; ++ ++struct esp_mac_prefix esp_mac_prefix_table[] = { ++ {0, {0x18, 0xfe, 0x34}}, ++ {1, {0xac, 0xd0, 0x74}}, ++ {255, {0x18, 0xfe, 0x34}}, ++}; ++ ++#define SIGNAL_COUNT 300 ++ ++#define TID_TO_AC(_tid) ((_tid)== 0||((_tid)==3)?WME_AC_BE:((_tid)<3)?WME_AC_BK:((_tid)<6)?WME_AC_VI:WME_AC_VO) ++ ++#ifdef SIP_DEBUG ++#define esp_sip_dbg esp_dbg ++struct sip_trace { ++ u32 tx_data; ++ u32 tx_cmd; ++ u32 rx_data; ++ u32 rx_evt; ++ u32 rx_tx_status; ++ u32 tx_out_of_credit; ++ u32 tx_one_shot_overflow; ++}; ++static struct sip_trace str; ++#define STRACE_TX_DATA_INC() (str.tx_data++) ++#define STRACE_TX_CMD_INC() (str.tx_cmd++) ++#define STRACE_RX_DATA_INC() (str.rx_data++) ++#define STRACE_RX_EVENT_INC() (str.rx_evt++) ++#define STRACE_RX_TXSTATUS_INC() (str.rx_tx_status++) ++#define STRACE_TX_OUT_OF_CREDIT_INC() (str.tx_out_of_credit++) ++#define STRACE_TX_ONE_SHOT_INC() (str.tx_one_shot_overflow++) ++#define STRACE_SHOW(sip) ++#else ++#define esp_sip_dbg(...) ++#define STRACE_TX_DATA_INC() ++#define STRACE_TX_CMD_INC() ++#define STRACE_RX_DATA_INC() ++#define STRACE_RX_EVENT_INC() ++#define STRACE_RX_TXSTATUS_INC() ++#define STRACE_TX_OUT_OF_CREDIT_INC() ++#define STRACE_TX_ONE_SHOT_INC() ++#define STRACE_SHOW(sip) ++#endif /* SIP_DEBUG */ ++ ++#define SIP_STOP_QUEUE_THRESHOLD 48 ++#define SIP_RESUME_QUEUE_THRESHOLD 12 ++ ++#define SIP_MIN_DATA_PKT_LEN (sizeof(struct esp_mac_rx_ctrl) + 24) //24 is min 80211hdr ++ ++#ifdef ESP_PREALLOC ++extern struct sk_buff *esp_get_sip_skb(int size); ++extern void esp_put_sip_skb(struct sk_buff **skb); ++ ++extern u8 *esp_get_tx_aggr_buf(void); ++extern void esp_put_tx_aggr_buf(u8 ** p); ++ ++#endif ++ ++static void sip_recalc_credit_init(struct esp_sip *sip); ++ ++static int sip_recalc_credit_claim(struct esp_sip *sip, int force); ++ ++static void sip_recalc_credit_release(struct esp_sip *sip); ++ ++static struct sip_pkt *sip_get_ctrl_buf(struct esp_sip *sip, ++ SIP_BUF_TYPE bftype); ++ ++static void sip_reclaim_ctrl_buf(struct esp_sip *sip, struct sip_pkt *pkt, ++ SIP_BUF_TYPE bftype); ++ ++static void sip_free_init_ctrl_buf(struct esp_sip *sip); ++ ++static int sip_pack_pkt(struct esp_sip *sip, struct sk_buff *skb, ++ int *pm_state); ++ ++static struct esp_mac_rx_ctrl *sip_parse_normal_mac_ctrl(struct sk_buff ++ *skb, ++ int *pkt_len_enc, ++ int *buf_len, ++ int *pulled_len); ++ ++static struct sk_buff *sip_parse_data_rx_info(struct esp_sip *sip, ++ struct sk_buff *skb, ++ int pkt_len_enc, int buf_len, ++ struct esp_mac_rx_ctrl ++ *mac_ctrl, int *pulled_len); ++ ++static inline void sip_rx_pkt_enqueue(struct esp_sip *sip, ++ struct sk_buff *skb); ++ ++static void sip_after_write_pkts(struct esp_sip *sip); ++ ++static void sip_update_tx_credits(struct esp_sip *sip, ++ u16 recycled_credits); ++ ++//static void sip_trigger_txq_process(struct esp_sip *sip); ++ ++static bool sip_rx_pkt_process(struct esp_sip *sip, struct sk_buff *skb); ++ ++static void sip_tx_status_report(struct esp_sip *sip, struct sk_buff *skb, ++ struct ieee80211_tx_info *tx_info, ++ bool success); ++ ++#ifdef FPGA_TXDATA ++int sip_send_tx_data(struct esp_sip *sip); ++#endif /* FPGA_TXDATA */ ++ ++#ifdef FPGA_LOOPBACK ++int sip_send_loopback_cmd_mblk(struct esp_sip *sip); ++#endif /* FPGA_LOOPBACK */ ++ ++static bool check_ac_tid(u8 * pkt, u8 ac, u8 tid) ++{ ++ struct ieee80211_hdr *wh = (struct ieee80211_hdr *) pkt; ++#ifdef TID_DEBUG ++ u16 real_tid = 0; ++#endif //TID_DEBUG ++ ++ if (ieee80211_is_data_qos(wh->frame_control)) { ++#ifdef TID_DEBUG ++ real_tid = ++ *ieee80211_get_qos_ctl(wh) & ++ IEEE80211_QOS_CTL_TID_MASK; ++ ++ esp_sip_dbg(ESP_SHOW, "ac:%u, tid:%u, tid in pkt:%u\n", ac, ++ tid, real_tid); ++ if (tid != real_tid) { ++ esp_sip_dbg(ESP_DBG_ERROR, ++ "111 ac:%u, tid:%u, tid in pkt:%u\n", ++ ac, tid, real_tid); ++ } ++ if (TID_TO_AC(tid) != ac) { ++ esp_sip_dbg(ESP_DBG_ERROR, ++ "222 ac:%u, tid:%u, tid in pkt:%u\n", ++ ac, tid, real_tid); ++ } ++#endif /* TID_DEBUG */ ++ } else if (ieee80211_is_mgmt(wh->frame_control)) { ++#ifdef TID_DEBUG ++ esp_sip_dbg(ESP_SHOW, "ac:%u, tid:%u\n", ac, tid); ++ if (tid != 7 || ac != WME_AC_VO) { ++ esp_sip_dbg(ESP_DBG_ERROR, "333 ac:%u, tid:%u\n", ++ ac, tid); ++ } ++#endif /* TID_DEBUG */ ++ } else { ++ if (ieee80211_is_ctl(wh->frame_control)) { ++#ifdef TID_DEBUG ++ esp_sip_dbg(ESP_SHOW, ++ "%s is ctrl pkt fc 0x%04x ac:%u, tid:%u, tid in pkt:%u\n", ++ __func__, wh->frame_control, ac, tid, ++ real_tid); ++#endif /* TID_DEBUG */ ++ } else { ++ if (tid != 0 || ac != WME_AC_BE) { ++ //show_buf(pkt, 24); ++ esp_sip_dbg(ESP_DBG_LOG, ++ "444 ac:%u, tid:%u \n", ac, ++ tid); ++ if (tid == 7 && ac == WME_AC_VO) ++ return false; ++ } ++ return true; //hack to modify non-qos null data. ++ ++ } ++ } ++ ++ return false; ++} ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) ++static void sip_recalc_credit_timeout(struct timer_list *t) ++#else ++static void sip_recalc_credit_timeout(unsigned long data) ++#endif ++{ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) ++ struct esp_sip *sip = from_timer(sip, t, credit_timer); ++#else ++ struct esp_sip *sip = (struct esp_sip *) data; ++#endif ++ ++ esp_dbg(ESP_DBG_ERROR, "rct"); ++ ++ sip_recalc_credit_claim(sip, 1); /* recalc again */ ++} ++ ++static void sip_recalc_credit_init(struct esp_sip *sip) ++{ ++ atomic_set(&sip->credit_status, RECALC_CREDIT_DISABLE); //set it disable ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) ++ timer_setup(&sip->credit_timer, sip_recalc_credit_timeout, 0); ++#else ++ init_timer(&sip->credit_timer); ++ sip->credit_timer.data = (unsigned long) sip; ++ sip->credit_timer.function = sip_recalc_credit_timeout; ++#endif ++} ++ ++static int sip_recalc_credit_claim(struct esp_sip *sip, int force) ++{ ++ int ret; ++ ++ if (atomic_read(&sip->credit_status) == RECALC_CREDIT_ENABLE ++ && force == 0) ++ return 1; ++ ++ atomic_set(&sip->credit_status, RECALC_CREDIT_ENABLE); ++ ret = sip_send_recalc_credit(sip->epub); ++ if (ret) { ++ esp_dbg(ESP_DBG_ERROR, "%s error %d", __func__, ret); ++ return ret; ++ } ++ /*setup a timer for handle the abs_credit not receive */ ++ mod_timer(&sip->credit_timer, jiffies + msecs_to_jiffies(2000)); ++ ++ esp_dbg(ESP_SHOW, "rcc"); ++ ++ return ret; ++} ++ ++static void sip_recalc_credit_release(struct esp_sip *sip) ++{ ++ esp_dbg(ESP_SHOW, "rcr"); ++ ++ if (atomic_read(&sip->credit_status) == RECALC_CREDIT_ENABLE) { ++ atomic_set(&sip->credit_status, RECALC_CREDIT_DISABLE); ++ del_timer_sync(&sip->credit_timer); ++ } else ++ esp_dbg(ESP_SHOW, "maybe bogus credit"); ++} ++ ++static void sip_update_tx_credits(struct esp_sip *sip, ++ u16 recycled_credits) ++{ ++ esp_sip_dbg(ESP_DBG_TRACE, "%s:before add, credits is %d\n", ++ __func__, atomic_read(&sip->tx_credits)); ++ ++ if (recycled_credits & 0x800) { ++ atomic_set(&sip->tx_credits, (recycled_credits & 0x7ff)); ++ sip_recalc_credit_release(sip); ++ } else ++ atomic_add(recycled_credits, &sip->tx_credits); ++ ++ esp_sip_dbg(ESP_DBG_TRACE, "%s:after add %d, credits is %d\n", ++ __func__, recycled_credits, ++ atomic_read(&sip->tx_credits)); ++} ++ ++void sip_trigger_txq_process(struct esp_sip *sip) ++{ ++ if (atomic_read(&sip->tx_credits) <= sip->credit_to_reserve + SIP_CTRL_CREDIT_RESERVE //no credits, do nothing ++ || atomic_read(&sip->credit_status) == RECALC_CREDIT_ENABLE) ++ return; ++ ++ if (sip_queue_may_resume(sip)) { ++ /* wakeup upper queue only if we have sufficient credits */ ++ esp_sip_dbg(ESP_DBG_TRACE, "%s wakeup ieee80211 txq \n", ++ __func__); ++ atomic_set(&sip->epub->txq_stopped, false); ++ ieee80211_wake_queues(sip->epub->hw); ++ } else if (atomic_read(&sip->epub->txq_stopped)) { ++ esp_sip_dbg(ESP_DBG_TRACE, ++ "%s can't wake txq, credits: %d \n", __func__, ++ atomic_read(&sip->tx_credits)); ++ } ++ ++ if (!skb_queue_empty(&sip->epub->txq)) { ++ /* try to send out pkt already in sip queue once we have credits */ ++ esp_sip_dbg(ESP_DBG_TRACE, "%s resume sip txq \n", ++ __func__); ++ ++#if !defined(FPGA_TXDATA) ++ if (sif_get_ate_config() == 0) { ++ ieee80211_queue_work(sip->epub->hw, ++ &sip->epub->tx_work); ++ } else { ++ queue_work(sip->epub->esp_wkq, ++ &sip->epub->tx_work); ++ } ++#else ++ queue_work(sip->epub->esp_wkq, &sip->epub->tx_work); ++#endif ++ } ++} ++ ++static bool sip_ampdu_occupy_buf(struct esp_sip *sip, ++ struct esp_rx_ampdu_len *ampdu_len) ++{ ++ return (ampdu_len->substate == 0 ++ || esp_wmac_rxsec_error(ampdu_len->substate) ++ || (sip->dump_rpbm_err ++ && ampdu_len->substate == RX_RPBM_ERR)); ++} ++ ++static bool sip_rx_pkt_process(struct esp_sip *sip, struct sk_buff *skb) ++{ ++#define DO_NOT_COPY false ++#define DO_COPY true ++ ++ struct sip_hdr *hdr = NULL; ++ struct sk_buff *rskb = NULL; ++ int remains_len = 0; ++ int first_pkt_len = 0; ++ u8 *bufptr = NULL; ++ int ret = 0; ++ bool trigger_rxq = false; ++ ++ if (skb == NULL) { ++ esp_sip_dbg(ESP_DBG_ERROR, "%s NULL SKB!!!!!!!! \n", ++ __func__); ++ return trigger_rxq; ++ } ++ ++ hdr = (struct sip_hdr *) skb->data; ++ bufptr = skb->data; ++ ++ ++ esp_sip_dbg(ESP_DBG_TRACE, "%s Hcredits 0x%08x, realCredits %d\n", ++ __func__, hdr->h_credits, ++ hdr->h_credits & SIP_CREDITS_MASK); ++ if (hdr->h_credits & SIP_CREDITS_MASK) { ++ sip_update_tx_credits(sip, ++ hdr->h_credits & SIP_CREDITS_MASK); ++ } ++ ++ hdr->h_credits &= ~SIP_CREDITS_MASK; /* clean credits in sip_hdr, prevent over-add */ ++ ++ esp_sip_dbg(ESP_DBG_TRACE, "%s credits %d\n", __func__, ++ hdr->h_credits); ++ ++ /* ++ * first pkt's length is stored in recycled_credits first 20 bits ++ * config w3 [31:12] ++ * repair hdr->len of first pkt ++ */ ++ remains_len = hdr->len; ++ first_pkt_len = hdr->h_credits >> 12; ++ hdr->len = first_pkt_len; ++ ++ esp_dbg(ESP_DBG_TRACE, "%s first_pkt_len %d, whole pkt len %d \n", ++ __func__, first_pkt_len, remains_len); ++ if (first_pkt_len > remains_len) { ++ sip_recalc_credit_claim(sip, 0); ++ esp_dbg(ESP_DBG_ERROR, ++ "first_pkt_len %d, whole pkt len %d\n", ++ first_pkt_len, remains_len); ++ show_buf((u8 *) hdr, first_pkt_len); ++ ESSERT(0); ++ goto _exit; ++ } ++ ++ /* ++ * pkts handling, including the first pkt, should alloc new skb for each data pkt. ++ * free the original whole skb after parsing is done. ++ */ ++ while (remains_len) { ++ if (remains_len < sizeof(struct sip_hdr)) { ++ sip_recalc_credit_claim(sip, 0); ++ ESSERT(0); ++ show_buf((u8 *) hdr, 512); ++ goto _exit; ++ } ++ ++ hdr = (struct sip_hdr *) bufptr; ++ if (hdr->len <= 0) { ++ sip_recalc_credit_claim(sip, 0); ++ show_buf((u8 *) hdr, 512); ++ ESSERT(0); ++ goto _exit; ++ } ++ ++ if ((hdr->len & 3) != 0) { ++ sip_recalc_credit_claim(sip, 0); ++ show_buf((u8 *) hdr, 512); ++ ESSERT(0); ++ goto _exit; ++ } ++ if (unlikely(hdr->seq != sip->rxseq++)) { ++ sip_recalc_credit_claim(sip, 0); ++ esp_dbg(ESP_DBG_ERROR, ++ "%s seq mismatch! got %u, expect %u\n", ++ __func__, hdr->seq, sip->rxseq - 1); ++ sip->rxseq = hdr->seq + 1; ++ show_buf(bufptr, 32); ++ ESSERT(0); ++ } ++ ++ if (SIP_HDR_IS_CTRL(hdr)) { ++ STRACE_RX_EVENT_INC(); ++ esp_sip_dbg(ESP_DBG_TRACE, "seq %u \n", hdr->seq); ++ ++ ret = sip_parse_events(sip, bufptr); ++ ++ skb_pull(skb, hdr->len); ++ ++ } else if (SIP_HDR_IS_DATA(hdr)) { ++ struct esp_mac_rx_ctrl *mac_ctrl = NULL; ++ int pkt_len_enc = 0, buf_len = 0, pulled_len = 0; ++ ++ STRACE_RX_DATA_INC(); ++ esp_sip_dbg(ESP_DBG_TRACE, "seq %u \n", hdr->seq); ++ mac_ctrl = ++ sip_parse_normal_mac_ctrl(skb, &pkt_len_enc, ++ &buf_len, ++ &pulled_len); ++ rskb = ++ sip_parse_data_rx_info(sip, skb, pkt_len_enc, ++ buf_len, mac_ctrl, ++ &pulled_len); ++ ++ if (rskb == NULL) ++ goto _move_on; ++ ++ if (likely(atomic_read(&sip->epub->wl.off) == 0)) { ++#ifdef RX_CHECKSUM_TEST ++ esp_rx_checksum_test(rskb); ++#endif ++ local_bh_disable(); ++ ieee80211_rx(sip->epub->hw, rskb); ++ local_bh_enable(); ++ } else { ++ /* still need go thro parsing as skb_pull should invoke */ ++ kfree_skb(rskb); ++ } ++ } else if (SIP_HDR_IS_AMPDU(hdr)) { ++ struct esp_mac_rx_ctrl *mac_ctrl = NULL; ++ struct esp_mac_rx_ctrl new_mac_ctrl; ++ struct esp_rx_ampdu_len *ampdu_len; ++ int pkt_num; ++ int pulled_len = 0; ++ static int pkt_dropped = 0; ++ static int pkt_total = 0; ++ bool have_rxabort = false; ++ bool have_goodpkt = false; ++ static u8 frame_head[16]; ++ static u8 frame_buf_ttl = 0; ++ ++ ampdu_len = ++ (struct esp_rx_ampdu_len *) (skb->data + ++ hdr->len / ++ sip->rx_blksz * ++ sip->rx_blksz); ++ esp_sip_dbg(ESP_DBG_TRACE, ++ "%s rx ampdu total len %u\n", __func__, ++ hdr->len); ++ if (skb->data != (u8 *) hdr) { ++ printk("%p %p\n", skb->data, hdr); ++ show_buf(skb->data, 512); ++ show_buf((u8 *) hdr, 512); ++ ESSERT(0); ++ goto _exit; ++ } ++ mac_ctrl = ++ sip_parse_normal_mac_ctrl(skb, NULL, NULL, ++ &pulled_len); ++ memcpy(&new_mac_ctrl, mac_ctrl, ++ sizeof(struct esp_mac_rx_ctrl)); ++ mac_ctrl = &new_mac_ctrl; ++ pkt_num = mac_ctrl->ampdu_cnt; ++ esp_sip_dbg(ESP_DBG_TRACE, ++ "%s %d rx ampdu %u pkts, %d pkts dumped, first len %u\n", ++ __func__, __LINE__, ++ (unsigned ++ int) ((hdr->len % sip->rx_blksz) / ++ sizeof(struct ++ esp_rx_ampdu_len)), ++ pkt_num, ++ (unsigned int) ampdu_len->sublen); ++ ++ pkt_total += mac_ctrl->ampdu_cnt; ++ //esp_sip_dbg(ESP_DBG_ERROR, "%s ampdu dropped %d/%d\n", __func__, pkt_dropped, pkt_total); ++ while (pkt_num > 0) { ++ esp_sip_dbg(ESP_DBG_TRACE, ++ "%s %d ampdu sub state %02x,\n", ++ __func__, __LINE__, ++ ampdu_len->substate); ++ ++ if (sip_ampdu_occupy_buf(sip, ampdu_len)) { //pkt is dumped ++ ++ rskb = ++ sip_parse_data_rx_info(sip, ++ skb, ++ ampdu_len-> ++ sublen - ++ FCS_LEN, ++ 0, ++ mac_ctrl, ++ &pulled_len); ++ if (!rskb) { ++ ESSERT(0); ++ goto _exit; ++ } ++ ++ if (likely ++ (atomic_read ++ (&sip->epub->wl.off) == 0) ++ && (ampdu_len->substate == 0 ++ || ampdu_len->substate == ++ RX_TKIPMIC_ERR ++ || (sip->sendup_rpbm_pkt ++ && ampdu_len-> ++ substate == ++ RX_RPBM_ERR)) ++ && (sip->rxabort_fixed ++ || !have_rxabort)) { ++ if (!have_goodpkt) { ++ have_goodpkt = ++ true; ++ memcpy(frame_head, ++ rskb->data, ++ 16); ++ frame_head[1] &= ++ ~0x80; ++ frame_buf_ttl = 3; ++ } ++#ifdef RX_CHECKSUM_TEST ++ esp_rx_checksum_test(rskb); ++#endif ++ local_bh_disable(); ++ ieee80211_rx(sip->epub->hw, ++ rskb); ++ local_bh_enable(); ++ ++ } else { ++ kfree_skb(rskb); ++ } ++ } else { ++ if (ampdu_len->substate == ++ RX_ABORT) { ++ u8 *a; ++ have_rxabort = true; ++ esp_sip_dbg(ESP_DBG_TRACE, ++ "rx abort %d %d\n", ++ frame_buf_ttl, ++ pkt_num); ++ if (frame_buf_ttl ++ && !sip-> ++ rxabort_fixed) { ++ struct ++ esp_rx_ampdu_len ++ *next_good_ampdu_len ++ = ++ ampdu_len + 1; ++ a = frame_head; ++ esp_sip_dbg ++ (ESP_DBG_TRACE, ++ "frame:%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", ++ a[0], a[1], ++ a[2], a[3], ++ a[4], a[5], ++ a[6], a[7], ++ a[8], a[9], ++ a[10], a[11], ++ a[12], a[13], ++ a[14], a[15]); ++ while ++ (!sip_ampdu_occupy_buf ++ (sip, ++ next_good_ampdu_len)) ++ { ++ if (next_good_ampdu_len > ampdu_len + pkt_num - 1) ++ break; ++ next_good_ampdu_len++; ++ ++ } ++ if (next_good_ampdu_len <= ampdu_len + pkt_num - 1) { ++ bool b0, ++ b10, ++ b11; ++ a = skb-> ++ data; ++ esp_sip_dbg ++ (ESP_DBG_TRACE, ++ "buf:%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", ++ a[0], ++ a[1], ++ a[2], ++ a[3], ++ a[4], ++ a[5], ++ a[6], ++ a[7], ++ a[8], ++ a[9], ++ a[10], ++ a[11], ++ a[12], ++ a[13], ++ a[14], ++ a ++ [15]); ++ b0 = memcmp ++ (frame_head ++ + 4, ++ skb-> ++ data + ++ 4, ++ 12) == ++ 0; ++ b10 = ++ memcmp ++ (frame_head ++ + 10, ++ skb-> ++ data, ++ 6) == ++ 0; ++ b11 = ++ memcpy ++ (frame_head ++ + 11, ++ skb-> ++ data, ++ 5) == ++ 0; ++ esp_sip_dbg ++ (ESP_DBG_TRACE, ++ "com %d %d %d\n", ++ b0, ++ b10, ++ b11); ++ if (b0 ++ && !b10 ++ && ++ !b11) { ++ have_rxabort ++ = ++ false; ++ esp_sip_dbg ++ (ESP_DBG_TRACE, ++ "repair 0\n"); ++ } else ++ if (!b0 ++ && ++ b10 ++ && ++ !b11) ++ { ++ skb_push ++ (skb, ++ 10); ++ memcpy ++ (skb-> ++ data, ++ frame_head, ++ 10); ++ have_rxabort ++ = ++ false; ++ pulled_len ++ -= ++ 10; ++ esp_sip_dbg ++ (ESP_DBG_TRACE, ++ "repair 10\n"); ++ } else ++ if (!b0 ++ && ++ !b10 ++ && ++ b11) ++ { ++ skb_push ++ (skb, ++ 11); ++ memcpy ++ (skb-> ++ data, ++ frame_head, ++ 11); ++ have_rxabort ++ = ++ false; ++ pulled_len ++ -= ++ 11; ++ esp_sip_dbg ++ (ESP_DBG_TRACE, ++ "repair 11\n"); ++ } ++ } ++ } ++ } ++ pkt_dropped++; ++ esp_sip_dbg(ESP_DBG_LOG, ++ "%s ampdu dropped %d/%d\n", ++ __func__, pkt_dropped, ++ pkt_total); ++ } ++ pkt_num--; ++ ampdu_len++; ++ } ++ if (frame_buf_ttl) ++ frame_buf_ttl--; ++ skb_pull(skb, hdr->len - pulled_len); ++ } else { ++ esp_sip_dbg(ESP_DBG_ERROR, "%s %d unknown type\n", ++ __func__, __LINE__); ++ } ++ ++ _move_on: ++ if (hdr->len < remains_len) { ++ remains_len -= hdr->len; ++ } else { ++ break; ++ } ++ bufptr += hdr->len; ++ } ++ ++ _exit: ++#ifdef ESP_PREALLOC ++ esp_put_sip_skb(&skb); ++#else ++ kfree_skb(skb); ++#endif ++ ++ return trigger_rxq; ++ ++#undef DO_NOT_COPY ++#undef DO_COPY ++} ++ ++static void _sip_rxq_process(struct esp_sip *sip) ++{ ++ struct sk_buff *skb = NULL; ++ bool sendup = false; ++ ++ while ((skb = skb_dequeue(&sip->rxq))) { ++ if (sip_rx_pkt_process(sip, skb)) ++ sendup = true; ++ } ++ if (sendup) { ++ queue_work(sip->epub->esp_wkq, &sip->epub->sendup_work); ++ } ++ ++ /* probably tx_credit is updated, try txq */ ++ sip_trigger_txq_process(sip); ++} ++ ++static void sip_rxq_process(struct work_struct *work) ++{ ++ struct esp_sip *sip = ++ container_of(work, struct esp_sip, rx_process_work); ++ if (sip == NULL) { ++ ESSERT(0); ++ return; ++ } ++ ++ if (unlikely(atomic_read(&sip->state) == SIP_SEND_INIT)) { ++ sip_send_chip_init(sip); ++ atomic_set(&sip->state, SIP_WAIT_BOOTUP); ++ return; ++ } ++ ++ mutex_lock(&sip->rx_mtx); ++ _sip_rxq_process(sip); ++ mutex_unlock(&sip->rx_mtx); ++} ++ ++static inline void sip_rx_pkt_enqueue(struct esp_sip *sip, ++ struct sk_buff *skb) ++{ ++ skb_queue_tail(&sip->rxq, skb); ++} ++ ++static inline struct sk_buff *sip_rx_pkt_dequeue(struct esp_sip *sip) ++{ ++ return skb_dequeue(&sip->rxq); ++} ++ ++static u32 sip_rx_count = 0; ++void sip_debug_show(struct esp_sip *sip) ++{ ++ esp_sip_dbg(ESP_DBG_ERROR, "txq left %d %d\n", ++ skb_queue_len(&sip->epub->txq), ++ atomic_read(&sip->tx_data_pkt_queued)); ++ esp_sip_dbg(ESP_DBG_ERROR, "tx queues stop ? %d\n", ++ atomic_read(&sip->epub->txq_stopped)); ++ esp_sip_dbg(ESP_DBG_ERROR, "txq stop? %d\n", ++ test_bit(ESP_WL_FLAG_STOP_TXQ, &sip->epub->wl.flags)); ++ esp_sip_dbg(ESP_DBG_ERROR, "tx credit %d\n", ++ atomic_read(&sip->tx_credits)); ++ esp_sip_dbg(ESP_DBG_ERROR, "rx collect %d\n", sip_rx_count); ++ sip_rx_count = 0; ++} ++ ++int sip_rx(struct esp_pub *epub) ++{ ++ struct sip_hdr *shdr = NULL; ++ struct esp_sip *sip = epub->sip; ++ int err = 0; ++ struct sk_buff *first_skb = NULL; ++ u8 *rx_buf = NULL; ++ u32 rx_blksz; ++ struct sk_buff *rx_skb = NULL; ++ ++ u32 first_sz; ++ ++ first_sz = sif_get_regs(epub)->config_w0; ++ ++ if (likely(sif_get_ate_config() != 1)) { ++ do { ++ u8 raw_seq = sif_get_regs(epub)->intr_raw & 0xff; ++ ++ if (raw_seq != sip->to_host_seq) { ++ if (raw_seq == sip->to_host_seq + 1) { /* when last read pkt crc err, this situation may occur, but raw_seq mustn't < to_host_Seq */ ++ sip->to_host_seq = raw_seq; ++ esp_dbg(ESP_DBG_TRACE, ++ "warn: to_host_seq reg 0x%02x, seq 0x%02x", ++ raw_seq, sip->to_host_seq); ++ break; ++ } ++ esp_dbg(ESP_DBG_ERROR, ++ "err: to_host_seq reg 0x%02x, seq 0x%02x", ++ raw_seq, sip->to_host_seq); ++ goto _err; ++ } ++ } while (0); ++ } ++ esp_sip_dbg(ESP_DBG_LOG, "%s enter\n", __func__); ++ ++ ++ /* first read one block out, if we luck enough, that's it ++ * ++ * To make design as simple as possible, we allocate skb(s) ++ * separately for each sif read operation to avoid global ++ * read_buf_pointe access. It coule be optimized late. ++ */ ++ rx_blksz = sif_get_blksz(epub); ++#ifdef ESP_PREALLOC ++ first_skb = esp_get_sip_skb(roundup(first_sz, rx_blksz)); ++#else ++ first_skb = ++ __dev_alloc_skb(roundup(first_sz, rx_blksz), GFP_KERNEL); ++#endif /* ESP_PREALLOC */ ++ ++ if (first_skb == NULL) { ++ sif_unlock_bus(epub); ++ esp_sip_dbg(ESP_DBG_ERROR, "%s first no memory \n", ++ __func__); ++ goto _err; ++ } ++ ++ rx_buf = skb_put(first_skb, first_sz); ++ esp_sip_dbg(ESP_DBG_LOG, "%s rx_buf ptr %p, first_sz %d\n", ++ __func__, rx_buf, first_sz); ++ ++ ++#ifdef USE_EXT_GPIO ++ do { ++ int err2 = 0; ++ u16 value = 0; ++ u16 intr_mask = ext_gpio_get_int_mask_reg(); ++ if (!intr_mask) ++ break; ++ value = sif_get_regs(epub)->config_w3 & intr_mask; ++ if (value) { ++ err2 = sif_interrupt_target(epub, 6); ++ esp_sip_dbg(ESP_DBG, "write gpio\n"); ++ } ++ ++ if (!err2 && value) { ++ esp_sip_dbg(ESP_DBG_TRACE, ++ "%s intr_mask[0x%04x] value[0x%04x]\n", ++ __func__, intr_mask, value); ++ ext_gpio_int_process(value); ++ } ++ } while (0); ++#endif ++ ++ err = ++ esp_common_read(epub, rx_buf, first_sz, ESP_SIF_NOSYNC, false); ++ sip_rx_count++; ++ if (unlikely(err)) { ++ esp_dbg(ESP_DBG_ERROR, " %s first read err %d %d\n", ++ __func__, err, sif_get_regs(epub)->config_w0); ++#ifdef ESP_PREALLOC ++ esp_put_sip_skb(&first_skb); ++#else ++ kfree_skb(first_skb); ++#endif /* ESP_PREALLOC */ ++ sif_unlock_bus(epub); ++ goto _err; ++ } ++ ++ shdr = (struct sip_hdr *) rx_buf; ++ if (SIP_HDR_IS_CTRL(shdr) && (shdr->c_evtid == SIP_EVT_SLEEP)) { ++ atomic_set(&sip->epub->ps.state, ESP_PM_ON); ++ esp_dbg(ESP_DBG_TRACE, "s\n"); ++ } ++ ++ if (likely(sif_get_ate_config() != 1)) { ++ sip->to_host_seq++; ++ } ++ ++ if ((shdr->len & 3) != 0) { ++ esp_sip_dbg(ESP_DBG_ERROR, "%s shdr->len[%d] error\n", ++ __func__, shdr->len); ++#ifdef ESP_PREALLOC ++ esp_put_sip_skb(&first_skb); ++#else ++ kfree_skb(first_skb); ++#endif /* ESP_PREALLOC */ ++ sif_unlock_bus(epub); ++ err = -EIO; ++ goto _err; ++ } ++ if (shdr->len != first_sz) { ++ esp_sip_dbg(ESP_DBG_ERROR, ++ "%s shdr->len[%d] first_size[%d] error\n", ++ __func__, shdr->len, first_sz); ++#ifdef ESP_PREALLOC ++ esp_put_sip_skb(&first_skb); ++#else ++ kfree_skb(first_skb); ++#endif /* ESP_PREALLOC */ ++ sif_unlock_bus(epub); ++ err = -EIO; ++ goto _err; ++ } else { ++ sif_unlock_bus(epub); ++ skb_trim(first_skb, shdr->len); ++ esp_dbg(ESP_DBG_TRACE, " %s first_skb only\n", __func__); ++ ++ rx_skb = first_skb; ++ } ++ ++ if (atomic_read(&sip->state) == SIP_STOP) { ++#ifdef ESP_PREALLOC ++ esp_put_sip_skb(&rx_skb); ++#else ++ kfree_skb(rx_skb); ++#endif /* ESP_PREALLOC */ ++ esp_sip_dbg(ESP_DBG_ERROR, "%s when sip stopped\n", ++ __func__); ++ return 0; ++ } ++ ++ sip_rx_pkt_enqueue(sip, rx_skb); ++ queue_work(sip->epub->esp_wkq, &sip->rx_process_work); ++ ++ _err: ++ return err; ++} ++ ++int sip_post_init(struct esp_sip *sip, struct sip_evt_bootup2 *bevt) ++{ ++ struct esp_pub *epub; ++ ++ u8 mac_id = bevt->mac_addr[0]; ++ int mac_index = 0; ++ int i = 0; ++ ++ if (sip == NULL) { ++ ESSERT(0); ++ return -EINVAL; ++ } ++ ++ epub = sip->epub; ++ ++ ++ sip->tx_aggr_write_ptr = sip->tx_aggr_buf; ++ ++ sip->tx_blksz = bevt->tx_blksz; ++ sip->rx_blksz = bevt->rx_blksz; ++ sip->credit_to_reserve = bevt->credit_to_reserve; ++ ++ sip->dump_rpbm_err = (bevt->options & SIP_DUMP_RPBM_ERR); ++ sip->rxabort_fixed = (bevt->options & SIP_RXABORT_FIXED); ++ sip->support_bgscan = (bevt->options & SIP_SUPPORT_BGSCAN); ++ ++ sip->sendup_rpbm_pkt = sip->dump_rpbm_err && false; ++ ++ /* print out MAC addr... */ ++ memcpy(epub->mac_addr, bevt->mac_addr, ETH_ALEN); ++ for (i = 0; ++ i < ++ sizeof(esp_mac_prefix_table) / sizeof(struct esp_mac_prefix); ++ i++) { ++ if (esp_mac_prefix_table[i].mac_index == mac_id) { ++ mac_index = i; ++ break; ++ } ++ } ++ ++ epub->mac_addr[0] = ++ esp_mac_prefix_table[mac_index].mac_addr_prefix[0]; ++ epub->mac_addr[1] = ++ esp_mac_prefix_table[mac_index].mac_addr_prefix[1]; ++ epub->mac_addr[2] = ++ esp_mac_prefix_table[mac_index].mac_addr_prefix[2]; ++ ++#ifdef SELF_MAC ++ epub->mac_addr[0] = 0xff; ++ epub->mac_addr[1] = 0xff; ++ epub->mac_addr[2] = 0xff; ++#endif ++ atomic_set(&sip->noise_floor, bevt->noise_floor); ++ ++ sip_recalc_credit_init(sip); ++ ++ esp_sip_dbg(ESP_DBG_TRACE, ++ "%s tx_blksz %d rx_blksz %d mac addr %pM\n", __func__, ++ sip->tx_blksz, sip->rx_blksz, epub->mac_addr); ++ ++ return 0; ++} ++ ++/* write pkts in aggr buf to target memory */ ++static void sip_write_pkts(struct esp_sip *sip, int pm_state) ++{ ++ int tx_aggr_len = 0; ++ struct sip_hdr *first_shdr = NULL; ++ int err = 0; ++ ++ tx_aggr_len = sip->tx_aggr_write_ptr - sip->tx_aggr_buf; ++ if (tx_aggr_len < sizeof(struct sip_hdr)) { ++ printk("%s tx_aggr_len %d \n", __func__, tx_aggr_len); ++ ESSERT(0); ++ return; ++ } ++ if ((tx_aggr_len & 0x3) != 0) { ++ ESSERT(0); ++ return; ++ } ++ ++ first_shdr = (struct sip_hdr *) sip->tx_aggr_buf; ++ ++ if (atomic_read(&sip->tx_credits) <= SIP_CREDITS_LOW_THRESHOLD) { ++ first_shdr->fc[1] |= SIP_HDR_F_NEED_CRDT_RPT; ++ } ++ ++ /* still use lock bus instead of sif_lldesc_write_sync since we want to protect several global varibles assignments */ ++ sif_lock_bus(sip->epub); ++ ++ err = ++ esp_common_write(sip->epub, sip->tx_aggr_buf, tx_aggr_len, ++ ESP_SIF_NOSYNC); ++ ++ sip->tx_aggr_write_ptr = sip->tx_aggr_buf; ++ sip->tx_tot_len = 0; ++ ++ sif_unlock_bus(sip->epub); ++ ++ if (err) ++ esp_sip_dbg(ESP_DBG_ERROR, "func %s err!!!!!!!!!: %d\n", ++ __func__, err); ++ ++} ++ ++/* setup sip header and tx info, copy pkt into aggr buf */ ++static int sip_pack_pkt(struct esp_sip *sip, struct sk_buff *skb, ++ int *pm_state) ++{ ++ struct ieee80211_tx_info *itx_info; ++ struct sip_hdr *shdr; ++ u32 tx_len = 0, offset = 0; ++ bool is_data = true; ++ ++ itx_info = IEEE80211_SKB_CB(skb); ++ ++ if (itx_info->flags == 0xffffffff) { ++ shdr = (struct sip_hdr *) skb->data; ++ is_data = false; ++ tx_len = skb->len; ++ } else { ++ struct ieee80211_hdr *wh = ++ (struct ieee80211_hdr *) skb->data; ++ struct esp_vif *evif = ++ (struct esp_vif *) itx_info->control.vif->drv_priv; ++ u8 sta_index; ++ struct esp_node *node; ++ /* update sip header */ ++ shdr = (struct sip_hdr *) sip->tx_aggr_write_ptr; ++ ++ shdr->fc[0] = 0; ++ shdr->fc[1] = 0; ++ ++ if ((itx_info->flags & IEEE80211_TX_CTL_AMPDU) ++ && (true || esp_is_ip_pkt(skb))) ++ SIP_HDR_SET_TYPE(shdr->fc[0], SIP_DATA_AMPDU); ++ else ++ SIP_HDR_SET_TYPE(shdr->fc[0], SIP_DATA); ++ ++ if (evif->epub == NULL) { ++ sip_tx_status_report(sip, skb, itx_info, false); ++ atomic_dec(&sip->tx_data_pkt_queued); ++ return -EINVAL; ++ } ++ ++ /* make room for encrypted pkt */ ++ if (itx_info->control.hw_key) { ++ int alg = ++ esp_cipher2alg(itx_info->control.hw_key-> ++ cipher); ++ if (unlikely(alg == -1)) { ++ sip_tx_status_report(sip, skb, itx_info, ++ false); ++ atomic_dec(&sip->tx_data_pkt_queued); ++ return -1; ++ } else { ++ shdr->d_enc_flag = alg + 1; ++ } ++ ++ shdr->d_hw_kid = ++ itx_info->control.hw_key->hw_key_idx | (evif-> ++ index ++ << 7); ++ } else { ++ shdr->d_enc_flag = 0; ++ shdr->d_hw_kid = (evif->index << 7 | evif->index); ++ } ++ ++ /* update sip tx info */ ++ node = esp_get_node_by_addr(sip->epub, wh->addr1); ++ if (node != NULL) ++ sta_index = node->index; ++ else ++ sta_index = ESP_PUB_MAX_STA + 1; ++ SIP_HDR_SET_IFIDX(shdr->fc[0], ++ evif->index << 3 | sta_index); ++ shdr->d_p2p = itx_info->control.vif->p2p; ++ if (evif->index == 1) ++ shdr->d_p2p = 1; ++ shdr->d_ac = skb_get_queue_mapping(skb); ++ shdr->d_tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; ++ wh = (struct ieee80211_hdr *) skb->data; ++ if (ieee80211_is_mgmt(wh->frame_control)) { ++ /* addba/delba/bar may use different tid/ac */ ++ if (shdr->d_ac == WME_AC_VO) { ++ shdr->d_tid = 7; ++ } ++ if (ieee80211_is_beacon(wh->frame_control)) { ++ shdr->d_tid = 8; ++ shdr->d_ac = 4; ++ } ++ } ++ if (check_ac_tid(skb->data, shdr->d_ac, shdr->d_tid)) { ++ shdr->d_ac = WME_AC_BE; ++ shdr->d_tid = 0; ++ } ++ ++ ++ /* make sure data is start at 4 bytes aligned addr. */ ++ offset = roundup(sizeof(struct sip_hdr), 4); ++ ++#ifdef HOST_RC ++ esp_sip_dbg(ESP_DBG_TRACE, "%s offset0 %d \n", __func__, ++ offset); ++ memcpy(sip->tx_aggr_write_ptr + offset, ++ (void *) &itx_info->control, ++ sizeof(struct sip_tx_rc)); ++ ++ offset += roundup(sizeof(struct sip_tx_rc), 4); ++ esp_show_tx_rates(&itx_info->control.rates[0]); ++ ++#endif /* HOST_RC */ ++ ++ if (SIP_HDR_IS_AMPDU(shdr)) { ++ memset(sip->tx_aggr_write_ptr + offset, 0, ++ sizeof(struct esp_tx_ampdu_entry)); ++ offset += ++ roundup(sizeof(struct esp_tx_ampdu_entry), 4); ++ } ++ ++ tx_len = offset + skb->len; ++ shdr->len = tx_len; /* actual len */ ++ ++ esp_sip_dbg(ESP_DBG_TRACE, ++ "%s offset %d skblen %d txlen %d\n", __func__, ++ offset, skb->len, tx_len); ++ ++ } ++ ++ shdr->seq = sip->txseq++; ++ //esp_sip_dbg(ESP_DBG_ERROR, "%s seq %u, %u %u\n", __func__, shdr->seq, SIP_HDR_GET_TYPE(shdr->fc[0]),shdr->c_cmdid); ++ ++ /* copy skb to aggr buf */ ++ memcpy(sip->tx_aggr_write_ptr + offset, skb->data, skb->len); ++ ++ if (is_data) { ++ spin_lock_bh(&sip->epub->tx_lock); ++ sip->txdataseq = shdr->seq; ++ spin_unlock_bh(&sip->epub->tx_lock); ++ /* fake a tx_status and report to mac80211 stack to speed up tx, may affect ++ * 1) rate control (now it's all in target, so should be OK) ++ * 2) ps mode, mac80211 want to check ACK of ps/nulldata to see if AP is awake ++ * 3) BAR, mac80211 do BAR by checking ACK ++ */ ++ /* ++ * XXX: need to adjust for 11n, e.g. report tx_status according to BA received in target ++ * ++ */ ++ sip_tx_status_report(sip, skb, itx_info, true); ++ atomic_dec(&sip->tx_data_pkt_queued); ++ ++ STRACE_TX_DATA_INC(); ++ } else { ++ /* check pm state here */ ++ ++ /* no need to hold ctrl skb */ ++ sip_free_ctrl_skbuff(sip, skb); ++ STRACE_TX_CMD_INC(); ++ } ++ ++ /* TBD: roundup here or whole aggr-buf */ ++ tx_len = roundup(tx_len, sip->tx_blksz); ++ ++ sip->tx_aggr_write_ptr += tx_len; ++ sip->tx_tot_len += tx_len; ++ ++ return 0; ++} ++ ++#ifdef HOST_RC ++static void sip_set_tx_rate_status(struct sip_rc_status *rcstatus, ++ struct ieee80211_tx_rate *irates) ++{ ++ int i; ++ u8 shift = 0; ++ u32 cnt = 0; ++ ++ for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { ++ if (rcstatus->rc_map & BIT(i)) { ++ shift = i << 2; ++ cnt = ++ (rcstatus-> ++ rc_cnt_store >> shift) & RC_CNT_MASK; ++ irates[i].idx = i; ++ irates[i].count = (u8) cnt; ++ } else { ++ irates[i].idx = -1; ++ irates[i].count = 0; ++ } ++ } ++ ++ esp_show_rcstatus(rcstatus); ++ esp_show_tx_rates(irates); ++} ++#endif /* HOST_RC */ ++ ++static void sip_tx_status_report(struct esp_sip *sip, struct sk_buff *skb, ++ struct ieee80211_tx_info *tx_info, ++ bool success) ++{ ++ if (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) { ++ if (likely(success)) ++ tx_info->flags |= IEEE80211_TX_STAT_ACK; ++ else ++ tx_info->flags &= ~IEEE80211_TX_STAT_ACK; ++ ++ /* manipulate rate status... */ ++ tx_info->status.rates[0].idx = 11; ++ tx_info->status.rates[0].count = 1; ++ tx_info->status.rates[0].flags = 0; ++ tx_info->status.rates[1].idx = -1; ++ ++ } else { ++ tx_info->flags |= ++ IEEE80211_TX_STAT_AMPDU | IEEE80211_TX_STAT_ACK; ++ tx_info->status.ampdu_len = 1; ++ tx_info->status.ampdu_ack_len = 1; ++ ++ /* manipulate rate status... */ ++ tx_info->status.rates[0].idx = 7; ++ tx_info->status.rates[0].count = 1; ++ tx_info->status.rates[0].flags = ++ IEEE80211_TX_RC_MCS | IEEE80211_TX_RC_SHORT_GI; ++ tx_info->status.rates[1].idx = -1; ++ ++ } ++ ++ if (tx_info->flags & IEEE80211_TX_STAT_AMPDU) ++ esp_sip_dbg(ESP_DBG_TRACE, "%s ampdu status! \n", ++ __func__); ++ ++ if (!mod_support_no_txampdu() && ++ cfg80211_get_chandef_type(&sip->epub->hw->conf.chandef) != ++ NL80211_CHAN_NO_HT) { ++ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); ++ struct ieee80211_hdr *wh = ++ (struct ieee80211_hdr *) skb->data; ++ if (ieee80211_is_data_qos(wh->frame_control)) { ++ if (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) { ++ u8 tidno = ++ ieee80211_get_qos_ctl(wh)[0] & ++ IEEE80211_QOS_CTL_TID_MASK; ++ struct esp_node *node; ++ struct esp_tx_tid *tid; ++ struct ieee80211_sta *sta; ++ ++ node = ++ esp_get_node_by_addr(sip->epub, ++ wh->addr1); ++ if (node == NULL) ++ goto _exit; ++ if (node->sta == NULL) ++ goto _exit; ++ sta = node->sta; ++ tid = &node->tid[tidno]; ++ spin_lock_bh(&sip->epub->tx_ampdu_lock); ++ //start session ++ if (tid == NULL) { ++ spin_unlock_bh(&sip->epub-> ++ tx_ampdu_lock); ++ ESSERT(0); ++ goto _exit; ++ } ++ if ((tid->state == ESP_TID_STATE_INIT) && ++ (TID_TO_AC(tidno) != WME_AC_VO) ++ && tid->cnt >= 10) { ++ tid->state = ESP_TID_STATE_TRIGGER; ++ esp_sip_dbg(ESP_DBG_ERROR, ++ "start tx ba session,addr:%pM,tid:%u\n", ++ wh->addr1, tidno); ++ spin_unlock_bh(&sip->epub-> ++ tx_ampdu_lock); ++ ieee80211_start_tx_ba_session(sta, ++ tidno, ++ 0); ++ } else { ++ if (tid->state == ++ ESP_TID_STATE_INIT) ++ tid->cnt++; ++ else ++ tid->cnt = 0; ++ spin_unlock_bh(&sip->epub-> ++ tx_ampdu_lock); ++ } ++ } ++ } ++ } ++ _exit: ++ ieee80211_tx_status_skb(sip->epub->hw, skb); ++} ++ ++/* ++ * NB: this routine should be locked when calling ++ */ ++void sip_txq_process(struct esp_pub *epub) ++{ ++ struct sk_buff *skb; ++ struct esp_sip *sip = epub->sip; ++ u32 pkt_len = 0, tx_len = 0; ++ int blknum = 0; ++ bool queued_back = false; ++ bool out_of_credits = false; ++ struct ieee80211_tx_info *itx_info; ++ int pm_state = 0; ++ ++ while ((skb = skb_dequeue(&epub->txq))) { ++ ++ /* cmd skb->len does not include sip_hdr too */ ++ pkt_len = skb->len; ++ itx_info = IEEE80211_SKB_CB(skb); ++ if (itx_info->flags != 0xffffffff) { ++ pkt_len += roundup(sizeof(struct sip_hdr), 4); ++ if ((itx_info->flags & IEEE80211_TX_CTL_AMPDU) ++ && (true || esp_is_ip_pkt(skb))) ++ pkt_len += ++ roundup(sizeof ++ (struct esp_tx_ampdu_entry), ++ 4); ++ } ++ ++ /* current design simply requires every sip_hdr must be at the begin of mblk, that definitely ++ * need to be optimized, e.g. calulate remain length in the previous mblk, if it larger than ++ * certain threshold (e.g, whole pkt or > 50% of pkt or 2 x sizeof(struct sip_hdr), append pkt ++ * to the previous mblk. This might be done in sip_pack_pkt() ++ */ ++ pkt_len = roundup(pkt_len, sip->tx_blksz); ++ blknum = pkt_len / sip->tx_blksz; ++ esp_dbg(ESP_DBG_TRACE, ++ "%s skb_len %d pkt_len %d blknum %d\n", __func__, ++ skb->len, pkt_len, blknum); ++ ++ if (unlikely(atomic_read(&sip->credit_status) == RECALC_CREDIT_ENABLE)) { /* need recalc credit */ ++ struct sip_hdr *hdr = (struct sip_hdr *) skb->data; ++ itx_info = IEEE80211_SKB_CB(skb); ++ if (!(itx_info->flags == 0xffffffff && SIP_HDR_GET_TYPE(hdr->fc[0]) == SIP_CTRL && hdr->c_cmdid == SIP_CMD_RECALC_CREDIT && blknum <= atomic_read(&sip->tx_credits) - sip->credit_to_reserve)) { /* except cmd recalc credit */ ++ esp_dbg(ESP_DBG_ERROR, ++ "%s recalc credits!\n", __func__); ++ STRACE_TX_OUT_OF_CREDIT_INC(); ++ queued_back = true; ++ out_of_credits = true; ++ break; ++ } ++ } else { /* normal situation */ ++ if (unlikely ++ (blknum > ++ (atomic_read(&sip->tx_credits) - ++ sip->credit_to_reserve - ++ SIP_CTRL_CREDIT_RESERVE))) { ++ itx_info = IEEE80211_SKB_CB(skb); ++ if (itx_info->flags == 0xffffffff) { /* priv ctrl pkt */ ++ if (blknum > ++ atomic_read(&sip->tx_credits) - ++ sip->credit_to_reserve) { ++ esp_dbg(ESP_DBG_TRACE, ++ "%s cmd pkt out of credits!\n", ++ __func__); ++ STRACE_TX_OUT_OF_CREDIT_INC ++ (); ++ queued_back = true; ++ out_of_credits = true; ++ break; ++ } ++ } else { ++ esp_dbg(ESP_DBG_TRACE, ++ "%s out of credits!\n", ++ __func__); ++ STRACE_TX_OUT_OF_CREDIT_INC(); ++ queued_back = true; ++ out_of_credits = true; ++ break; ++ } ++ } ++ } ++ tx_len += pkt_len; ++ if (tx_len >= SIP_TX_AGGR_BUF_SIZE) { ++ /* do we need to have limitation likemax 8 pkts in a row? */ ++ esp_dbg(ESP_DBG_TRACE, ++ "%s too much pkts in one shot!\n", ++ __func__); ++ STRACE_TX_ONE_SHOT_INC(); ++ tx_len -= pkt_len; ++ queued_back = true; ++ break; ++ } ++ ++ if (sip_pack_pkt(sip, skb, &pm_state) != 0) { ++ /* wrong pkt, won't send to target */ ++ tx_len -= pkt_len; ++ continue; ++ } ++ ++ esp_sip_dbg(ESP_DBG_TRACE, ++ "%s:before sub, credits is %d\n", __func__, ++ atomic_read(&sip->tx_credits)); ++ atomic_sub(blknum, &sip->tx_credits); ++ esp_sip_dbg(ESP_DBG_TRACE, ++ "%s:after sub %d,credits remains %d\n", ++ __func__, blknum, ++ atomic_read(&sip->tx_credits)); ++ ++ } ++ ++ if (queued_back) { ++ skb_queue_head(&epub->txq, skb); ++ } ++ ++ if (atomic_read(&sip->state) == SIP_STOP ++#ifdef HOST_RESET_BUG ++ || atomic_read(&epub->wl.off) == 1 ++#endif ++ ) { ++ queued_back = 1; ++ tx_len = 0; ++ sip_after_write_pkts(sip); ++ } ++ ++ if (tx_len) { ++ ++ sip_write_pkts(sip, pm_state); ++ ++ sip_after_write_pkts(sip); ++ } ++ ++ if (queued_back && !out_of_credits) { ++ ++ /* skb pending, do async process again */ ++ sip_trigger_txq_process(sip); ++ } ++} ++ ++static void sip_after_write_pkts(struct esp_sip *sip) ++{ ++ ++} ++ ++#ifndef NO_WMM_DUMMY ++static struct esp_80211_wmm_param_element esp_wmm_param = { ++ .oui = {0x00, 0x50, 0xf2}, ++ .oui_type = 0x02, ++ .oui_subtype = 0x01, ++ .version = 0x01, ++ .qos_info = 0x00, ++ .reserved = 0x00, ++ .ac = { ++ { ++ .aci_aifsn = 0x03, ++ .cw = 0xa4, ++ .txop_limit = 0x0000, ++ }, ++ { ++ .aci_aifsn = 0x27, ++ .cw = 0xa4, ++ .txop_limit = 0x0000, ++ }, ++ { ++ .aci_aifsn = 0x42, ++ .cw = 0x43, ++ .txop_limit = 0x005e, ++ }, ++ { ++ .aci_aifsn = 0x62, ++ .cw = 0x32, ++ .txop_limit = 0x002f, ++ }, ++ }, ++}; ++ ++static int esp_add_wmm(struct sk_buff *skb) ++{ ++ u8 *p; ++ int flag = 0; ++ int remain_len; ++ int base_len; ++ int len; ++ struct ieee80211_mgmt *mgmt; ++ struct ieee80211_hdr *wh; ++ ++ if (!skb) ++ return -1; ++ ++ wh = (struct ieee80211_hdr *) skb->data; ++ mgmt = (struct ieee80211_mgmt *) ((u8 *) skb->data); ++ ++ if (ieee80211_is_assoc_resp(wh->frame_control)) { ++ p = mgmt->u.assoc_resp.variable; ++ base_len = ++ (u8 *) mgmt->u.assoc_resp.variable - (u8 *) mgmt; ++ } else if (ieee80211_is_reassoc_resp(wh->frame_control)) { ++ p = mgmt->u.reassoc_resp.variable; ++ base_len = ++ (u8 *) mgmt->u.reassoc_resp.variable - (u8 *) mgmt; ++ } else if (ieee80211_is_probe_resp(wh->frame_control)) { ++ p = mgmt->u.probe_resp.variable; ++ base_len = ++ (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; ++ } else if (ieee80211_is_beacon(wh->frame_control)) { ++ p = mgmt->u.beacon.variable; ++ base_len = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; ++ } else ++ return 1; ++ ++ ++ remain_len = skb->len - base_len; ++ ++ while (remain_len > 0) { ++ if (*p == 0xdd && *(p + 5) == 0x02) //wmm type ++ return 0; ++ else if (*p == 0x2d) //has ht cap ++ flag = 1; ++ ++ len = *(++p); ++ p += (len + 1); ++ remain_len -= (len + 2); ++ } ++ ++ if (remain_len < 0) { ++ esp_dbg(ESP_DBG_TRACE, ++ "%s remain_len %d, skb->len %d, base_len %d, flag %d", ++ __func__, remain_len, skb->len, base_len, flag); ++ return -2; ++ } ++ ++ if (flag == 1) { ++ skb_put(skb, 2 + sizeof(esp_wmm_param)); ++ ++ memset(p, 0xdd, sizeof(u8)); ++ memset(p + 1, sizeof(esp_wmm_param), sizeof(u8)); ++ memcpy(p + 2, &esp_wmm_param, sizeof(esp_wmm_param)); ++ ++ esp_dbg(ESP_DBG_TRACE, "esp_wmm_param"); ++ } ++ ++ return 0; ++} ++#endif /* NO_WMM_DUMMY */ ++ ++/* parse mac_rx_ctrl and return length */ ++static int sip_parse_mac_rx_info(struct esp_sip *sip, ++ struct esp_mac_rx_ctrl *mac_ctrl, ++ struct sk_buff *skb) ++{ ++ struct ieee80211_rx_status *rx_status = NULL; ++ struct ieee80211_hdr *hdr; ++ ++ rx_status = IEEE80211_SKB_RXCB(skb); ++ rx_status->freq = esp_ieee2mhz(mac_ctrl->channel); ++ ++ rx_status->signal = mac_ctrl->rssi + mac_ctrl->noise_floor; /* snr actually, need to offset noise floor e.g. -85 */ ++ ++ hdr = (struct ieee80211_hdr *) skb->data; ++ if (mac_ctrl->damatch0 == 1 && mac_ctrl->bssidmatch0 == 1 /*match bssid and da, but beacon package contain other bssid */ ++ && strncmp(hdr->addr2, sip->epub->wl.bssid, ETH_ALEN) == 0) { /* force match addr2 */ ++ if (++signal_loop >= SIGNAL_COUNT) { ++ avg_signal += rx_status->signal; ++ avg_signal /= SIGNAL_COUNT; ++ old_signal = rx_status->signal = (avg_signal + 5); ++ signal_loop = 0; ++ avg_signal = 0; ++ } else { ++ avg_signal += rx_status->signal; ++ rx_status->signal = old_signal; ++ } ++ } ++ ++ rx_status->antenna = 0; /* one antenna for now */ ++ rx_status->band = NL80211_BAND_2GHZ; ++ rx_status->flag = RX_FLAG_DECRYPTED | RX_FLAG_MMIC_STRIPPED; ++ if (mac_ctrl->sig_mode) { ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)) ++ rx_status->encoding = RX_ENC_HT; ++#else ++ rx_status->flag |= RX_FLAG_HT; ++#endif ++ rx_status->rate_idx = mac_ctrl->MCS; ++ if (mac_ctrl->SGI) ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)) ++ rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI; ++#else ++ rx_status->flag |= RX_FLAG_SHORT_GI; ++#endif ++ } else { ++ rx_status->rate_idx = esp_wmac_rate2idx(mac_ctrl->rate); ++ } ++ if (mac_ctrl->rxend_state == RX_FCS_ERR) ++ rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; ++ ++ /* Mic error frame flag */ ++ if (mac_ctrl->rxend_state == RX_TKIPMIC_ERR ++ || mac_ctrl->rxend_state == RX_CCMPMIC_ERR) { ++ if (atomic_read(&sip->epub->wl.tkip_key_set) == 1) { ++ rx_status->flag |= RX_FLAG_MMIC_ERROR; ++ atomic_set(&sip->epub->wl.tkip_key_set, 0); ++ printk("mic err\n"); ++ } else { ++ printk("mic err discard\n"); ++ } ++ } ++ //esp_dbg(ESP_DBG_LOG, "%s freq: %u; signal: %d; rate_idx %d; flag: %d \n", __func__, rx_status->freq, rx_status->signal, rx_status->rate_idx, rx_status->flag); ++ ++ do { ++ struct ieee80211_hdr *wh = ++ (struct ieee80211_hdr *) ((u8 *) skb->data); ++ ++#ifndef NO_WMM_DUMMY ++ if (ieee80211_is_mgmt(wh->frame_control)) ++ esp_add_wmm(skb); ++#endif ++ ++ /* some kernel e.g. 3.0.8 wrongly handles non-encrypted pkt like eapol */ ++ if (ieee80211_is_data(wh->frame_control)) { ++ if (!ieee80211_has_protected(wh->frame_control)) { ++ esp_sip_dbg(ESP_DBG_TRACE, ++ "%s kiv_war, add iv_stripped flag \n", ++ __func__); ++ rx_status->flag |= RX_FLAG_IV_STRIPPED; ++ } else { ++ if ((atomic_read(&sip->epub->wl.ptk_cnt) == ++ 0 && !(wh->addr1[0] & 0x1)) ++ || (atomic_read(&sip->epub->wl.gtk_cnt) ++ == 0 && (wh->addr1[0] & 0x1))) { ++ esp_dbg(ESP_DBG_TRACE, ++ "%s ==kiv_war, got bogus enc pkt==\n", ++ __func__); ++ rx_status->flag |= ++ RX_FLAG_IV_STRIPPED; ++ //show_buf(skb->data, 32); ++ } ++ ++ esp_sip_dbg(ESP_DBG_TRACE, ++ "%s kiv_war, got enc pkt \n", ++ __func__); ++ } ++ } ++ } while (0); ++ ++ return 0; ++} ++ ++static struct esp_mac_rx_ctrl *sip_parse_normal_mac_ctrl(struct sk_buff ++ *skb, ++ int *pkt_len_enc, ++ int *buf_len, ++ int *pulled_len) ++{ ++ struct esp_mac_rx_ctrl *mac_ctrl = NULL; ++ struct sip_hdr *hdr = (struct sip_hdr *) skb->data; ++ int len_in_hdr = hdr->len; ++ ++ ESSERT(skb != NULL); ++ ESSERT(skb->len > SIP_MIN_DATA_PKT_LEN); ++ ++ skb_pull(skb, sizeof(struct sip_hdr)); ++ *pulled_len += sizeof(struct sip_hdr); ++ mac_ctrl = (struct esp_mac_rx_ctrl *) skb->data; ++ if (!mac_ctrl->Aggregation) { ++ ESSERT(pkt_len_enc != NULL); ++ ESSERT(buf_len != NULL); ++ *pkt_len_enc = ++ (mac_ctrl->sig_mode ? mac_ctrl->HT_length : mac_ctrl-> ++ legacy_length) - FCS_LEN; ++ *buf_len = ++ len_in_hdr - sizeof(struct sip_hdr) - ++ sizeof(struct esp_mac_rx_ctrl); ++ } ++ skb_pull(skb, sizeof(struct esp_mac_rx_ctrl)); ++ *pulled_len += sizeof(struct esp_mac_rx_ctrl); ++ ++ return mac_ctrl; ++} ++ ++/* ++ * for one MPDU (including subframe in AMPDU) ++ * ++ */ ++static struct sk_buff *sip_parse_data_rx_info(struct esp_sip *sip, ++ struct sk_buff *skb, ++ int pkt_len_enc, int buf_len, ++ struct esp_mac_rx_ctrl ++ *mac_ctrl, int *pulled_len) ++{ ++ /* ++ * | mac_rx_ctrl | real_data_payload | ampdu_entries | ++ */ ++ //without enc ++ int pkt_len = 0; ++ struct sk_buff *rskb = NULL; ++ int ret; ++ ++ if (mac_ctrl->Aggregation) { ++ struct ieee80211_hdr *wh = ++ (struct ieee80211_hdr *) skb->data; ++ pkt_len = pkt_len_enc; ++ if (ieee80211_has_protected(wh->frame_control)) //ampdu, it is CCMP enc ++ pkt_len -= 8; ++ buf_len = roundup(pkt_len, 4); ++ } else ++ pkt_len = buf_len - 3 + ((pkt_len_enc - 1) & 0x3); ++ esp_dbg(ESP_DBG_TRACE, ++ "%s pkt_len %u, pkt_len_enc %u!, delta %d \n", __func__, ++ pkt_len, pkt_len_enc, pkt_len_enc - pkt_len); ++ do { ++#ifndef NO_WMM_DUMMY ++ rskb = ++ __dev_alloc_skb(pkt_len_enc + sizeof(esp_wmm_param) + ++ 2, GFP_ATOMIC); ++#else ++ rskb = __dev_alloc_skb(pkt_len_enc, GFP_ATOMIC); ++#endif /* NO_WMM_DUMMY */ ++ if (unlikely(rskb == NULL)) { ++ esp_sip_dbg(ESP_DBG_ERROR, "%s no mem for rskb\n", ++ __func__); ++ return NULL; ++ } ++ skb_put(rskb, pkt_len_enc); ++ } while (0); ++ ++ do { ++ memcpy(rskb->data, skb->data, pkt_len); ++ if (pkt_len_enc > pkt_len) { ++ memset(rskb->data + pkt_len, 0, ++ pkt_len_enc - pkt_len); ++ } ++ /* strip out current pkt, move to the next one */ ++ skb_pull(skb, buf_len); ++ *pulled_len += buf_len; ++ } while (0); ++ ++ ret = sip_parse_mac_rx_info(sip, mac_ctrl, rskb); ++ if (ret == -1 && !mac_ctrl->Aggregation) { ++ kfree_skb(rskb); ++ return NULL; ++ } ++ ++ esp_dbg(ESP_DBG_LOG, ++ "%s after pull headers, skb->len %d rskb->len %d \n", ++ __func__, skb->len, rskb->len); ++ ++ return rskb; ++} ++ ++struct esp_sip *sip_attach(struct esp_pub *epub) ++{ ++ struct esp_sip *sip = NULL; ++ struct sip_pkt *pkt = NULL; ++ int i; ++#ifndef ESP_PREALLOC ++ int po = 0; ++#endif ++ ++ sip = kzalloc(sizeof(struct esp_sip), GFP_KERNEL); ++ if (sip == NULL) { ++ esp_dbg(ESP_DBG_ERROR, "no mem for sip! \n"); ++ goto _err_sip; ++ } ++#ifdef ESP_PREALLOC ++ sip->tx_aggr_buf = (u8 *) esp_get_tx_aggr_buf(); ++#else ++ po = get_order(SIP_TX_AGGR_BUF_SIZE); ++ sip->tx_aggr_buf = (u8 *) __get_free_pages(GFP_ATOMIC, po); ++#endif ++ if (sip->tx_aggr_buf == NULL) { ++ esp_dbg(ESP_DBG_ERROR, "no mem for tx_aggr_buf! \n"); ++ goto _err_aggr; ++ } ++ ++ spin_lock_init(&sip->lock); ++ ++ INIT_LIST_HEAD(&sip->free_ctrl_txbuf); ++ INIT_LIST_HEAD(&sip->free_ctrl_rxbuf); ++ ++ for (i = 0; i < SIP_CTRL_BUF_N; i++) { ++ pkt = kzalloc(sizeof(struct sip_pkt), GFP_KERNEL); ++ ++ if (!pkt) ++ goto _err_pkt; ++ ++ pkt->buf_begin = kzalloc(SIP_CTRL_BUF_SZ, GFP_KERNEL); ++ ++ if (pkt->buf_begin == NULL) { ++ kfree(pkt); ++ pkt = NULL; ++ goto _err_pkt; ++ } ++ ++ pkt->buf_len = SIP_CTRL_BUF_SZ; ++ pkt->buf = pkt->buf_begin; ++ ++ if (i < SIP_CTRL_TXBUF_N) { ++ list_add_tail(&pkt->list, &sip->free_ctrl_txbuf); ++ } else { ++ list_add_tail(&pkt->list, &sip->free_ctrl_rxbuf); ++ } ++ } ++ ++ mutex_init(&sip->rx_mtx); ++ skb_queue_head_init(&sip->rxq); ++ INIT_WORK(&sip->rx_process_work, sip_rxq_process); ++ ++ sip->epub = epub; ++ atomic_set(&sip->noise_floor, -96); ++ ++ atomic_set(&sip->state, SIP_INIT); ++ atomic_set(&sip->tx_credits, 0); ++ ++ if (sip->rawbuf == NULL) { ++ sip->rawbuf = kzalloc(SIP_BOOT_BUF_SIZE, GFP_KERNEL); ++ if (sip->rawbuf == NULL) { ++ esp_dbg(ESP_DBG_ERROR, "no mem for rawbuf! \n"); ++ goto _err_pkt; ++ } ++ } ++ ++ atomic_set(&sip->state, SIP_PREPARE_BOOT); ++ ++ return sip; ++ ++ _err_pkt: ++ sip_free_init_ctrl_buf(sip); ++ ++ if (sip->tx_aggr_buf) { ++#ifdef ESP_PREALLOC ++ esp_put_tx_aggr_buf(&sip->tx_aggr_buf); ++#else ++ po = get_order(SIP_TX_AGGR_BUF_SIZE); ++ free_pages((unsigned long) sip->tx_aggr_buf, po); ++ sip->tx_aggr_buf = NULL; ++#endif ++ } ++ _err_aggr: ++ if (sip) { ++ kfree(sip); ++ sip = NULL; ++ } ++ _err_sip: ++ return NULL; ++ ++} ++ ++static void sip_free_init_ctrl_buf(struct esp_sip *sip) ++{ ++ struct sip_pkt *pkt, *tpkt; ++ ++ list_for_each_entry_safe(pkt, tpkt, &sip->free_ctrl_txbuf, list) { ++ list_del(&pkt->list); ++ kfree(pkt->buf_begin); ++ kfree(pkt); ++ } ++ ++ list_for_each_entry_safe(pkt, tpkt, &sip->free_ctrl_rxbuf, list) { ++ list_del(&pkt->list); ++ kfree(pkt->buf_begin); ++ kfree(pkt); ++ } ++} ++ ++void sip_detach(struct esp_sip *sip) ++{ ++#ifndef ESP_PREALLOC ++ int po; ++#endif ++ if (sip == NULL) ++ return; ++ ++ esp_dbg(ESP_DBG_TRACE, "sip_detach: sip_free_init_ctrl_buf()"); ++ sip_free_init_ctrl_buf(sip); ++ ++ if (atomic_read(&sip->state) == SIP_RUN) { ++ ++ sif_disable_target_interrupt(sip->epub); ++ ++ atomic_set(&sip->state, SIP_STOP); ++ ++ /* disable irq here */ ++ sif_disable_irq(sip->epub); ++ cancel_work_sync(&sip->rx_process_work); ++ ++ skb_queue_purge(&sip->rxq); ++ mutex_destroy(&sip->rx_mtx); ++ cancel_work(&sip->epub->sendup_work); // Must be non-sync ++ skb_queue_purge(&sip->epub->rxq); ++ ++#ifdef ESP_NO_MAC80211 ++ unregister_netdev(sip->epub->net_dev); ++ wiphy_unregister(sip->epub->wdev->wiphy); ++#else ++ if (test_and_clear_bit ++ (ESP_WL_FLAG_HW_REGISTERED, &sip->epub->wl.flags)) { ++ ieee80211_unregister_hw(sip->epub->hw); ++ } ++#endif ++ ++ /* cancel all worker/timer */ ++ cancel_work_sync(&sip->epub->tx_work); ++ skb_queue_purge(&sip->epub->txq); ++ skb_queue_purge(&sip->epub->txdoneq); ++ ++#ifdef ESP_PREALLOC ++ esp_put_tx_aggr_buf(&sip->tx_aggr_buf); ++#else ++ po = get_order(SIP_TX_AGGR_BUF_SIZE); ++ free_pages((unsigned long) sip->tx_aggr_buf, po); ++ sip->tx_aggr_buf = NULL; ++#endif ++ ++ atomic_set(&sip->state, SIP_INIT); ++ } else if (atomic_read(&sip->state) >= SIP_BOOT ++ && atomic_read(&sip->state) <= SIP_WAIT_BOOTUP) { ++ ++ sif_disable_target_interrupt(sip->epub); ++ atomic_set(&sip->state, SIP_STOP); ++ ++ sif_disable_irq(sip->epub); ++ ++ if (sip->rawbuf) ++ kfree(sip->rawbuf); ++ ++ if (atomic_read(&sip->state) == SIP_SEND_INIT) { ++ cancel_work_sync(&sip->rx_process_work); ++ skb_queue_purge(&sip->rxq); ++ mutex_destroy(&sip->rx_mtx); ++ cancel_work_sync(&sip->epub->sendup_work); ++ skb_queue_purge(&sip->epub->rxq); ++ } ++#ifdef ESP_NO_MAC80211 ++ unregister_netdev(sip->epub->net_dev); ++ wiphy_unregister(sip->epub->wdev->wiphy); ++#else ++ if (test_and_clear_bit ++ (ESP_WL_FLAG_HW_REGISTERED, &sip->epub->wl.flags)) { ++ ieee80211_unregister_hw(sip->epub->hw); ++ } ++#endif ++ atomic_set(&sip->state, SIP_INIT); ++ } else ++ esp_dbg(ESP_DBG_ERROR, "%s wrong state %d\n", __func__, ++ atomic_read(&sip->state)); ++ ++ kfree(sip); ++} ++ ++int sip_write_memory(struct esp_sip *sip, u32 addr, u8 * buf, u16 len) ++{ ++ struct sip_cmd_write_memory *cmd; ++ struct sip_hdr *chdr; ++ u16 remains, hdrs, bufsize; ++ u32 loadaddr; ++ u8 *src; ++ int err = 0; ++ u32 *t = NULL; ++ ++ if (sip == NULL || sip->rawbuf == NULL) { ++ ESSERT(sip != NULL); ++ ESSERT(sip->rawbuf != NULL); ++ return -EINVAL; ++ } ++ ++ memset(sip->rawbuf, 0, SIP_BOOT_BUF_SIZE); ++ ++ chdr = (struct sip_hdr *) sip->rawbuf; ++ SIP_HDR_SET_TYPE(chdr->fc[0], SIP_CTRL); ++ chdr->c_cmdid = SIP_CMD_WRITE_MEMORY; ++ ++ remains = len; ++ hdrs = ++ sizeof(struct sip_hdr) + sizeof(struct sip_cmd_write_memory); ++ ++ while (remains) { ++ src = &buf[len - remains]; ++ loadaddr = addr + (len - remains); ++ ++ if (remains < (SIP_BOOT_BUF_SIZE - hdrs)) { ++ /* aligned with 4 bytes */ ++ bufsize = roundup(remains, 4); ++ memset(sip->rawbuf + hdrs, 0, bufsize); ++ remains = 0; ++ } else { ++ bufsize = SIP_BOOT_BUF_SIZE - hdrs; ++ remains -= bufsize; ++ } ++ ++ chdr->len = bufsize + hdrs; ++ chdr->seq = sip->txseq++; ++ cmd = ++ (struct sip_cmd_write_memory *) (sip->rawbuf + ++ SIP_CTRL_HDR_LEN); ++ cmd->len = bufsize; ++ cmd->addr = loadaddr; ++ memcpy(sip->rawbuf + hdrs, src, bufsize); ++ ++ t = (u32 *) sip->rawbuf; ++ esp_dbg(ESP_DBG_TRACE, ++ "%s t0: 0x%08x t1: 0x%08x t2:0x%08x loadaddr 0x%08x \n", ++ __func__, t[0], t[1], t[2], loadaddr); ++ ++ err = ++ esp_common_write(sip->epub, sip->rawbuf, chdr->len, ++ ESP_SIF_SYNC); ++ ++ if (err) { ++ esp_dbg(ESP_DBG_ERROR, "%s send buffer failed\n", ++ __func__); ++ return err; ++ } ++ // 1ms is enough, in fact on dell-d430, need not delay at all. ++ mdelay(1); ++ ++ } ++ ++ return err; ++} ++ ++int sip_send_cmd(struct esp_sip *sip, int cid, u32 cmdlen, void *cmd) ++{ ++ struct sip_hdr *chdr; ++ struct sip_pkt *pkt = NULL; ++ int ret = 0; ++ ++ pkt = sip_get_ctrl_buf(sip, SIP_TX_CTRL_BUF); ++ ++ if (pkt == NULL) ++ return -ENOMEM; ++ ++ chdr = (struct sip_hdr *) pkt->buf_begin; ++ chdr->len = SIP_CTRL_HDR_LEN + cmdlen; ++ chdr->seq = sip->txseq++; ++ chdr->c_cmdid = cid; ++ ++ ++ if (cmd) { ++ memset(pkt->buf, 0, cmdlen); ++ memcpy(pkt->buf, (u8 *) cmd, cmdlen); ++ } ++ ++ esp_dbg(ESP_DBG_TRACE, "cid %d, len %u, seq %u \n", chdr->c_cmdid, ++ chdr->len, chdr->seq); ++ ++ esp_dbg(ESP_DBG_TRACE, "c1 0x%08x c2 0x%08x\n", ++ *(u32 *) & pkt->buf[0], *(u32 *) & pkt->buf[4]); ++ ++ ret = ++ esp_common_write(sip->epub, pkt->buf_begin, chdr->len, ++ ESP_SIF_SYNC); ++ ++ if (ret) ++ esp_dbg(ESP_DBG_ERROR, "%s send cmd %d failed \n", ++ __func__, cid); ++ ++ sip_reclaim_ctrl_buf(sip, pkt, SIP_TX_CTRL_BUF); ++ ++ /* ++ * Hack here: reset tx/rx seq before target ram code is up... ++ */ ++ if (cid == SIP_CMD_BOOTUP) { ++ sip->rxseq = 0; ++ sip->txseq = 0; ++ sip->txdataseq = 0; ++ } ++ ++ return ret; ++} ++ ++struct sk_buff *sip_alloc_ctrl_skbuf(struct esp_sip *sip, u16 len, u32 cid) ++{ ++ struct sip_hdr *si = NULL; ++ struct ieee80211_tx_info *ti = NULL; ++ struct sk_buff *skb = NULL; ++ ++ ESSERT(len <= sip->tx_blksz); ++ ++ /* no need to reserve space for net stack */ ++ skb = __dev_alloc_skb(len, GFP_KERNEL); ++ ++ if (skb == NULL) { ++ esp_dbg(ESP_DBG_ERROR, "no skb for ctrl !\n"); ++ return NULL; ++ } ++ ++ skb->len = len; ++ ++ ti = IEEE80211_SKB_CB(skb); ++ /* set tx_info flags to 0xffffffff to indicate sip_ctrl pkt */ ++ ti->flags = 0xffffffff; ++ si = (struct sip_hdr *) skb->data; ++ memset(si, 0, sizeof(struct sip_hdr)); ++ SIP_HDR_SET_TYPE(si->fc[0], SIP_CTRL); ++ si->len = len; ++ si->c_cmdid = cid; ++ ++ return skb; ++} ++ ++void sip_free_ctrl_skbuff(struct esp_sip *sip, struct sk_buff *skb) ++{ ++ memset(IEEE80211_SKB_CB(skb), 0, sizeof(struct ieee80211_tx_info)); ++ kfree_skb(skb); ++} ++ ++static struct sip_pkt *sip_get_ctrl_buf(struct esp_sip *sip, ++ SIP_BUF_TYPE bftype) ++{ ++ struct sip_pkt *pkt = NULL; ++ struct list_head *bflist; ++ struct sip_hdr *chdr; ++ ++ bflist = ++ (bftype == ++ SIP_TX_CTRL_BUF) ? &sip->free_ctrl_txbuf : &sip-> ++ free_ctrl_rxbuf; ++ ++ spin_lock_bh(&sip->lock); ++ ++ if (list_empty(bflist)) { ++ spin_unlock_bh(&sip->lock); ++ return NULL; ++ } ++ ++ pkt = list_first_entry(bflist, struct sip_pkt, list); ++ list_del(&pkt->list); ++ spin_unlock_bh(&sip->lock); ++ ++ if (bftype == SIP_TX_CTRL_BUF) { ++ chdr = (struct sip_hdr *) pkt->buf_begin; ++ SIP_HDR_SET_TYPE(chdr->fc[0], SIP_CTRL); ++ pkt->buf = pkt->buf_begin + SIP_CTRL_HDR_LEN; ++ } else { ++ pkt->buf = pkt->buf_begin; ++ } ++ ++ return pkt; ++} ++ ++static void ++sip_reclaim_ctrl_buf(struct esp_sip *sip, struct sip_pkt *pkt, ++ SIP_BUF_TYPE bftype) ++{ ++ struct list_head *bflist = NULL; ++ ++ if (bftype == SIP_TX_CTRL_BUF) ++ bflist = &sip->free_ctrl_txbuf; ++ else if (bftype == SIP_RX_CTRL_BUF) ++ bflist = &sip->free_ctrl_rxbuf; ++ else ++ return; ++ ++ pkt->buf = pkt->buf_begin; ++ ++ spin_lock_bh(&sip->lock); ++ list_add_tail(&pkt->list, bflist); ++ spin_unlock_bh(&sip->lock); ++} ++ ++int sip_poll_bootup_event(struct esp_sip *sip) ++{ ++ int ret = 0; ++ ++ esp_dbg(ESP_DBG_TRACE, "polling bootup event... \n"); ++ ++ if (gl_bootup_cplx) ++ ret = wait_for_completion_timeout(gl_bootup_cplx, 2 * HZ); ++ ++ esp_dbg(ESP_DBG_TRACE, "******time remain****** = [%d]\n", ret); ++ if (ret <= 0) { ++ esp_dbg(ESP_DBG_ERROR, "bootup event timeout\n"); ++ return -ETIMEDOUT; ++ } ++ ++ if (sif_get_ate_config() == 0) { ++ ret = esp_register_mac80211(sip->epub); ++ } ++#ifdef TEST_MODE ++ ret = test_init_netlink(sip); ++ if (ret < 0) { ++ esp_sip_dbg(ESP_DBG_TRACE, ++ "esp_sdio: failed initializing netlink\n"); ++ return ret; ++ } ++#endif ++ ++ atomic_set(&sip->state, SIP_RUN); ++ esp_dbg(ESP_DBG_TRACE, "target booted up\n"); ++ ++ return ret; ++} ++ ++int sip_poll_resetting_event(struct esp_sip *sip) ++{ ++ int ret = 0; ++ ++ esp_dbg(ESP_DBG_TRACE, "polling resetting event... \n"); ++ ++ if (gl_bootup_cplx) ++ ret = wait_for_completion_timeout(gl_bootup_cplx, 10 * HZ); ++ ++ esp_dbg(ESP_DBG_TRACE, "******time remain****** = [%d]\n", ret); ++ if (ret <= 0) { ++ esp_dbg(ESP_DBG_ERROR, "resetting event timeout\n"); ++ return -ETIMEDOUT; ++ } ++ ++ esp_dbg(ESP_DBG_TRACE, "target resetting %d %p\n", ret, ++ gl_bootup_cplx); ++ ++ return 0; ++} ++ ++ ++#ifdef FPGA_DEBUG ++ ++/* bogus bootup cmd for FPGA debugging */ ++int sip_send_bootup(struct esp_sip *sip) ++{ ++ int ret; ++ struct sip_cmd_bootup bootcmd; ++ ++ esp_dbg(ESP_DBG_LOG, "sending bootup\n"); ++ ++ bootcmd.boot_addr = 0; ++ ret = ++ sip_send_cmd(sip, SIP_CMD_BOOTUP, ++ sizeof(struct sip_cmd_bootup), &bootcmd); ++ ++ return ret; ++} ++ ++#endif /* FPGA_DEBUG */ ++ ++bool sip_queue_need_stop(struct esp_sip * sip) ++{ ++ return atomic_read(&sip->tx_data_pkt_queued) >= ++ SIP_STOP_QUEUE_THRESHOLD || (atomic_read(&sip->tx_credits) < 8 ++ && atomic_read(&sip-> ++ tx_data_pkt_queued) ++ >= ++ SIP_STOP_QUEUE_THRESHOLD / 4 * 3); ++} ++ ++bool sip_queue_may_resume(struct esp_sip * sip) ++{ ++ return atomic_read(&sip->epub->txq_stopped) ++ && !test_bit(ESP_WL_FLAG_STOP_TXQ, &sip->epub->wl.flags) ++ && ((atomic_read(&sip->tx_credits) >= 16 ++ && atomic_read(&sip->tx_data_pkt_queued) < ++ SIP_RESUME_QUEUE_THRESHOLD * 2) ++ || atomic_read(&sip->tx_data_pkt_queued) < ++ SIP_RESUME_QUEUE_THRESHOLD); ++} ++ ++int sip_cmd_enqueue(struct esp_sip *sip, struct sk_buff *skb, int prior) ++{ ++ if (!sip || !sip->epub) { ++ esp_dbg(ESP_DBG_ERROR, "func %s, sip->epub->txq is NULL\n", ++ __func__); ++ return -EINVAL; ++ } ++ ++ if (!skb) { ++ esp_dbg(ESP_DBG_ERROR, "func %s, skb is NULL\n", __func__); ++ return -EINVAL; ++ } ++ ++ if (prior == ENQUEUE_PRIOR_HEAD) ++ skb_queue_head(&sip->epub->txq, skb); ++ else ++ skb_queue_tail(&sip->epub->txq, skb); ++ ++ if (sif_get_ate_config() == 0) { ++ ieee80211_queue_work(sip->epub->hw, &sip->epub->tx_work); ++ } else { ++ queue_work(sip->epub->esp_wkq, &sip->epub->tx_work); ++ } ++ return 0; ++} ++ ++void sip_tx_data_pkt_enqueue(struct esp_pub *epub, struct sk_buff *skb) ++{ ++ if (!epub || !epub->sip) { ++ if (!epub) ++ esp_dbg(ESP_DBG_ERROR, "func %s, epub is NULL\n", ++ __func__); ++ else ++ esp_dbg(ESP_DBG_ERROR, ++ "func %s, epub->sip is NULL\n", __func__); ++ ++ return; ++ } ++ if (!skb) { ++ esp_dbg(ESP_DBG_ERROR, "func %s, skb is NULL\n", __func__); ++ return; ++ } ++ skb_queue_tail(&epub->txq, skb); ++ atomic_inc(&epub->sip->tx_data_pkt_queued); ++ if (sip_queue_need_stop(epub->sip)) { ++ if (epub->hw) { ++ ieee80211_stop_queues(epub->hw); ++ atomic_set(&epub->txq_stopped, true); ++ } ++ ++ } ++} ++ ++#ifdef FPGA_TXDATA ++int sip_send_tx_data(struct esp_sip *sip) ++{ ++ struct sk_buff *skb = NULL; ++ struct sip_cmd_bss_info_update *bsscmd; ++ ++ skb = ++ sip_alloc_ctrl_skbuf(epub->sip, ++ sizeof(struct sip_cmd_bss_info_update), ++ SIP_CMD_BSS_INFO_UPDATE); ++ if (!skb) ++ return -EINVAL; ++ ++ bsscmd = ++ (struct sip_cmd_bss_info_update *) (skb->data + ++ sizeof(struct ++ sip_tx_info)); ++ bsscmd->isassoc = (assoc == true) ? 1 : 0; ++ memcpy(bsscmd->bssid, bssid, ETH_ALEN); ++ STRACE_SHOW(epub->sip); ++ return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL); ++} ++#endif /* FPGA_TXDATA */ +diff --git a/drivers/net/wireless/esp8089/esp_sip.h b/drivers/net/wireless/esp8089/esp_sip.h +new file mode 100644 +index 000000000000..95cc42989b2c +--- /dev/null ++++ b/drivers/net/wireless/esp8089/esp_sip.h +@@ -0,0 +1,171 @@ ++/* ++ * Copyright (c) 2009- 2014 Espressif System. ++ * ++ * Serial Interconnctor Protocol ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _ESP_SIP_H ++#define _ESP_SIP_H ++ ++#include "sip2_common.h" ++ ++#define SIP_CTRL_CREDIT_RESERVE 2 ++ ++#define SIP_PKT_MAX_LEN (1024*16) ++ ++/* 16KB on normal X86 system, should check before porting to orhters */ ++ ++#define SIP_TX_AGGR_BUF_SIZE (4 * PAGE_SIZE) ++#define SIP_RX_AGGR_BUF_SIZE (4 * PAGE_SIZE) ++ ++struct sk_buff; ++ ++struct sip_pkt { ++ struct list_head list; ++ ++ u8 *buf_begin; ++ u32 buf_len; ++ u8 *buf; ++}; ++ ++typedef enum RECALC_CREDIT_STATE { ++ RECALC_CREDIT_DISABLE = 0, ++ RECALC_CREDIT_ENABLE = 1, ++} RECALC_CREDIT_STATE; ++ ++typedef enum ENQUEUE_PRIOR { ++ ENQUEUE_PRIOR_TAIL = 0, ++ ENQUEUE_PRIOR_HEAD, ++} ENQUEUE_PRIOR; ++ ++typedef enum SIP_STATE { ++ SIP_INIT = 0, ++ SIP_PREPARE_BOOT, ++ SIP_BOOT, ++ SIP_SEND_INIT, ++ SIP_WAIT_BOOTUP, ++ SIP_RUN, ++ SIP_SUSPEND, ++ SIP_STOP ++} SIP_STATE; ++ ++enum sip_notifier { ++ SIP_TX_DONE = 1, ++ SIP_RX_DONE = 2, ++}; ++ ++#define SIP_CREDITS_LOW_THRESHOLD 64 //i.e. 4k ++ ++struct esp_sip { ++ struct list_head free_ctrl_txbuf; ++ struct list_head free_ctrl_rxbuf; ++ ++ u32 rxseq; /* sip pkt seq, should match target side */ ++ u32 txseq; ++ u32 txdataseq; ++ ++ u8 to_host_seq; ++ ++ atomic_t state; ++ spinlock_t lock; ++ atomic_t tx_credits; ++ ++ atomic_t tx_ask_credit_update; ++ ++ u8 *rawbuf; /* used in boot stage, free once chip is fully up */ ++ u8 *tx_aggr_buf; ++ u8 *tx_aggr_write_ptr; /* update after insertion of each pkt */ ++ u8 *tx_aggr_lastpkt_ptr; ++ ++ struct mutex rx_mtx; ++ struct sk_buff_head rxq; ++ struct work_struct rx_process_work; ++ ++ u16 tx_blksz; ++ u16 rx_blksz; ++ ++ bool dump_rpbm_err; ++ bool sendup_rpbm_pkt; ++ bool rxabort_fixed; ++ bool support_bgscan; ++ u8 credit_to_reserve; ++ ++ atomic_t credit_status; ++ struct timer_list credit_timer; ++ ++ atomic_t noise_floor; ++ ++ u32 tx_tot_len; /* total len for one transaction */ ++ u32 rx_tot_len; ++ ++ atomic_t rx_handling; ++ atomic_t tx_data_pkt_queued; ++ ++ atomic_t data_tx_stopped; ++ atomic_t tx_stopped; ++ ++ struct esp_pub *epub; ++}; ++ ++int sip_rx(struct esp_pub *epub); ++//int sip_download_fw(struct esp_sip *sip, u32 load_addr, u32 boot_addr); ++ ++ ++int sip_write_memory(struct esp_sip *, u32 addr, u8 * buf, u16 len); ++ ++void sip_credit_process(struct esp_pub *, u8 credits); ++ ++int sip_send_cmd(struct esp_sip *sip, int cid, u32 cmdlen, void *cmd); ++ ++struct esp_sip *sip_attach(struct esp_pub *); ++ ++int sip_post_init(struct esp_sip *sip, struct sip_evt_bootup2 *bevt); ++ ++void sip_detach(struct esp_sip *sip); ++ ++void sip_txq_process(struct esp_pub *epub); ++ ++struct sk_buff *sip_alloc_ctrl_skbuf(struct esp_sip *sip, u16 len, ++ u32 cid); ++ ++void sip_free_ctrl_skbuff(struct esp_sip *sip, struct sk_buff *skb); ++ ++bool sip_queue_need_stop(struct esp_sip *sip); ++bool sip_queue_may_resume(struct esp_sip *sip); ++bool sip_tx_data_need_stop(struct esp_sip *sip); ++bool sip_tx_data_may_resume(struct esp_sip *sip); ++ ++void sip_tx_data_pkt_enqueue(struct esp_pub *epub, struct sk_buff *skb); ++void sip_rx_data_pkt_enqueue(struct esp_pub *epub, struct sk_buff *skb); ++ ++int sip_cmd_enqueue(struct esp_sip *sip, struct sk_buff *skb, int prior); ++ ++int sip_poll_bootup_event(struct esp_sip *sip); ++ ++int sip_poll_resetting_event(struct esp_sip *sip); ++ ++void sip_trigger_txq_process(struct esp_sip *sip); ++ ++void sip_send_chip_init(struct esp_sip *sip); ++ ++bool mod_support_no_txampdu(void); ++ ++bool mod_support_no_rxampdu(void); ++ ++void mod_support_no_txampdu_set(bool value); ++ ++#ifdef FPGA_DEBUG ++int sip_send_bootup(struct esp_sip *sip); ++#endif /* FPGA_DEBUG */ ++void sip_debug_show(struct esp_sip *sip); ++#endif +diff --git a/drivers/net/wireless/esp8089/esp_utils.c b/drivers/net/wireless/esp8089/esp_utils.c +new file mode 100644 +index 000000000000..8b188de79b2c +--- /dev/null ++++ b/drivers/net/wireless/esp8089/esp_utils.c +@@ -0,0 +1,262 @@ ++/* ++ * Copyright (c) 2009 - 2014 Espressif System. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include "linux/types.h" ++#include "linux/kernel.h" ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include "esp_pub.h" ++#include "esp_utils.h" ++#include "esp_wmac.h" ++#include "esp_debug.h" ++ ++/* ++ * Convert IEEE channel number to MHz frequency. ++ */ ++u32 esp_ieee2mhz(u8 chan) ++{ ++ if (chan == 14) ++ return 2484; ++ ++ if (chan < 14) ++ return 2407 + chan * 5; ++ else ++ return 2512 + ((chan - 15) * 20); ++ //TODO, add 5GHz ++} ++ ++enum { ++ ESP_RATE_1_LONG = 0x0, ++ ESP_RATE_2_LONG = 0x1, ++ ESP_RATE_2_SHORT = 0x5, ++ ESP_RATE_5_SHORT = 0x6, ++ ESP_RATE_5_LONG = 0x2, ++ ESP_RATE_11_SHORT = 0x7, ++ ESP_RATE_11_LONG = 0x3, ++ ESP_RATE_6 = 0xb, ++ ESP_RATE_9 = 0xf, ++ ESP_RATE_12 = 0xa, ++ ESP_RATE_18 = 0xe, ++ ESP_RATE_24 = 0x9, ++ ESP_RATE_36 = 0xd, ++ ESP_RATE_48 = 0x8, ++ ESP_RATE_54 = 0xc, ++ /* ESP_RATE_MCS0 =0x10, ++ ESP_RATE_MCS1 =0x11, ++ ESP_RATE_MCS2 =0x12, ++ ESP_RATE_MCS3 =0x13, ++ ESP_RATE_MCS4 =0x14, ++ ESP_RATE_MCS5 =0x15, ++ ESP_RATE_MCS6 =0x16, ++ ESP_RATE_MCS7 =0x17, ++ */ ++}; ++ ++static u8 esp_rate_table[20] = { ++ ESP_RATE_1_LONG, ++ ESP_RATE_2_SHORT, ++ ESP_RATE_5_SHORT, ++ ESP_RATE_11_SHORT, ++ ESP_RATE_6, ++ ESP_RATE_9, ++ ESP_RATE_12, ++ ESP_RATE_18, ++ ESP_RATE_24, ++ ESP_RATE_36, ++ ESP_RATE_48, ++ ESP_RATE_54, ++ /* ESP_RATE_MCS0, ++ ESP_RATE_MCS1, ++ ESP_RATE_MCS2, ++ ESP_RATE_MCS3, ++ ESP_RATE_MCS4, ++ ESP_RATE_MCS5, ++ ESP_RATE_MCS6, ++ ESP_RATE_MCS7, ++ */ ++}; ++ ++s8 esp_wmac_rate2idx(u8 rate) ++{ ++ int i; ++ ++ if (rate == ESP_RATE_2_LONG) ++ return 1; ++ if (rate == ESP_RATE_5_LONG) ++ return 2; ++ if (rate == ESP_RATE_11_LONG) ++ return 3; ++ ++ for (i = 0; i < 20; i++) { ++ if (rate == esp_rate_table[i]) ++ return i; ++ } ++ ++ esp_dbg(ESP_DBG_ERROR, "%s unknown rate 0x%02x \n", __func__, ++ rate); ++ ++ return 0; ++} ++ ++bool esp_wmac_rxsec_error(u8 error) ++{ ++ return (error >= RX_SECOV_ERR && error <= RX_SECFIFO_TIMEOUT) ++ || (error >= RX_WEPICV_ERR && error <= RX_WAPIMIC_ERR); ++} ++ ++int esp_cipher2alg(int cipher) ++{ ++ if (cipher == WLAN_CIPHER_SUITE_TKIP) ++ return ALG_TKIP; ++ ++ if (cipher == WLAN_CIPHER_SUITE_CCMP) ++ return ALG_CCMP; ++ ++ if (cipher == WLAN_CIPHER_SUITE_WEP40 ++ || cipher == WLAN_CIPHER_SUITE_WEP104) ++ return ALG_WEP; ++ ++ if (cipher == WLAN_CIPHER_SUITE_AES_CMAC) ++ return ALG_AES_CMAC; ++ ++ //printk("%s wrong cipher 0x%x!\n",__func__,cipher); ++ ++ return -1; ++} ++ ++#ifdef RX_CHECKSUM_TEST ++atomic_t g_iv_len; ++void esp_rx_checksum_test(struct sk_buff *skb) ++{ ++ static u32 ip_err = 0; ++ static u32 tcp_err = 0; ++ struct ieee80211_hdr *pwh = (struct ieee80211_hdr *) skb->data; ++ int hdrlen = ieee80211_hdrlen(pwh->frame_control); ++ ++ if (ieee80211_has_protected(pwh->frame_control)) ++ hdrlen += atomic_read(&g_iv_len); ++ ++ if (ieee80211_is_data(pwh->frame_control)) { ++ struct llc_snap_hdr *llc = ++ (struct llc_snap_hdr *) (skb->data + hdrlen); ++ if (ntohs(llc->eth_type) == ETH_P_IP) { ++ int llclen = sizeof(struct llc_snap_hdr); ++ struct iphdr *iph = ++ (struct iphdr *) (skb->data + hdrlen + llclen); ++ __sum16 csum_bak = iph->check; ++ ++ iph->check = 0; ++ iph->check = ip_fast_csum(iph, iph->ihl); ++ if (iph->check != csum_bak) { ++ esp_dbg(ESP_DBG_ERROR, ++ "total ip checksum error %d\n", ++ ++ip_err); ++ } ++ iph->check = csum_bak; ++ ++ if (iph->protocol == 0x06) { ++ struct tcphdr *tcph = ++ (struct tcphdr *) (skb->data + hdrlen + ++ llclen + ++ iph->ihl * 4); ++ int datalen = ++ skb->len - (hdrlen + llclen + ++ iph->ihl * 4); ++ csum_bak = tcph->check; ++ ++ tcph->check = 0; ++ tcph->check = ++ tcp_v4_check(datalen, iph->saddr, ++ iph->daddr, ++ csum_partial((char *) ++ tcph, ++ datalen, 0)); ++ if (tcph->check != csum_bak) { ++ esp_dbg(ESP_DBG_ERROR, ++ "total tcp checksum error %d\n", ++ ++tcp_err); ++ } ++ tcph->check = csum_bak; ++ } ++ } ++ } ++} ++ ++#endif ++ ++#ifdef GEN_ERR_CHECKSUM ++ ++void esp_gen_err_checksum(struct sk_buff *skb) ++{ ++ static u32 tx_seq = 0; ++ if ((tx_seq++ % 16) == 0) { ++ struct ieee80211_hdr *hdr = ++ (struct ieee80211_hdr *) skb->data; ++ int hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ ++ if (ieee80211_has_protected(pwh->frame_control)) ++ hdrlen += ++ IEEE80211_SKB_CB(skb)->control.hw_key->iv_len; ++ ++ struct llc_snap_hdr *llc = ++ (struct llc_snap_hdr *) (skb->data + hdrlen); ++ if (ntohs(llc->eth_type) == ETH_P_IP) { ++ int llclen = sizeof(struct llc_snap_hdr); ++ struct iphdr *iph = ++ (struct iphdr *) (skb->data + hdrlen + llclen); ++ ++ iph->check = ~iph->check; ++ ++ if (iph->protocol == 0x06) { ++ struct tcphdr *tcph = ++ (struct tcphdr *) (skb->data + hdrlen + ++ llclen + ++ iph->ihl * 4); ++ tcph->check = ~tcph->check; ++ } ++ } ++ } ++} ++#endif ++ ++bool esp_is_ip_pkt(struct sk_buff *skb) ++{ ++ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; ++ int hdrlen; ++ struct llc_snap_hdr *llc; ++ ++ if (!ieee80211_is_data(hdr->frame_control)) ++ return false; ++ ++ hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ if (ieee80211_has_protected(hdr->frame_control)) ++ hdrlen += IEEE80211_SKB_CB(skb)->control.hw_key->iv_len; ++#ifdef RX_CHECKSUM_TEST ++ atomic_set(&g_iv_len, ++ IEEE80211_SKB_CB(skb)->control.hw_key->iv_len); ++#endif ++ if (skb->len < hdrlen + sizeof(struct llc_snap_hdr)) ++ return false; ++ llc = (struct llc_snap_hdr *) (skb->data + hdrlen); ++ if (ntohs(llc->eth_type) != ETH_P_IP) ++ return false; ++ else ++ return true; ++} +diff --git a/drivers/net/wireless/esp8089/esp_utils.h b/drivers/net/wireless/esp8089/esp_utils.h +new file mode 100644 +index 000000000000..ed16d9ca0a65 +--- /dev/null ++++ b/drivers/net/wireless/esp8089/esp_utils.h +@@ -0,0 +1,41 @@ ++/* ++ * Copyright (c) 2011-2012 Espressif System. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _ESP_UTILS_H_ ++#define _ESP_UTILS_H_ ++ ++#include "linux/types.h" ++#include ++ ++#ifndef BIT ++#define BIT(x) (0x1 << (x)) ++#endif ++ ++u32 esp_ieee2mhz(u8 chan); ++ ++enum ieee80211_key_alg { ++ ALG_WEP, ++ ALG_TKIP, ++ ALG_CCMP, ++ ALG_AES_CMAC ++}; ++ ++int esp_cipher2alg(int cipher); ++ ++void esp_rx_checksum_test(struct sk_buff *skb); ++void esp_gen_err_checksum(struct sk_buff *skb); ++ ++bool esp_is_ip_pkt(struct sk_buff *skb); ++ ++#endif +diff --git a/drivers/net/wireless/esp8089/esp_version.h b/drivers/net/wireless/esp8089/esp_version.h +new file mode 100644 +index 000000000000..481d98841fc2 +--- /dev/null ++++ b/drivers/net/wireless/esp8089/esp_version.h +@@ -0,0 +1 @@ ++#define DRIVER_VER 0xbdf5087c3debll +diff --git a/drivers/net/wireless/esp8089/esp_wl.h b/drivers/net/wireless/esp8089/esp_wl.h +new file mode 100644 +index 000000000000..e3e62a83d505 +--- /dev/null ++++ b/drivers/net/wireless/esp8089/esp_wl.h +@@ -0,0 +1,63 @@ ++#ifndef _ESP_WL_H_ ++#define _ESP_WL_H_ ++ ++//#define MAX_PROBED_SSID_INDEX 9 ++ ++ ++enum { ++ CONF_HW_BIT_RATE_1MBPS = BIT(0), ++ CONF_HW_BIT_RATE_2MBPS = BIT(1), ++ CONF_HW_BIT_RATE_5_5MBPS = BIT(2), ++ CONF_HW_BIT_RATE_11MBPS = BIT(3), ++ CONF_HW_BIT_RATE_6MBPS = BIT(4), ++ CONF_HW_BIT_RATE_9MBPS = BIT(5), ++ CONF_HW_BIT_RATE_12MBPS = BIT(6), ++ CONF_HW_BIT_RATE_18MBPS = BIT(7), ++ CONF_HW_BIT_RATE_22MBPS = BIT(8), ++ CONF_HW_BIT_RATE_24MBPS = BIT(9), ++ CONF_HW_BIT_RATE_36MBPS = BIT(10), ++ CONF_HW_BIT_RATE_48MBPS = BIT(11), ++ CONF_HW_BIT_RATE_54MBPS = BIT(12), ++ CONF_HW_BIT_RATE_11B_MASK = ++ (CONF_HW_BIT_RATE_1MBPS | CONF_HW_BIT_RATE_2MBPS | ++ CONF_HW_BIT_RATE_5_5MBPS | CONF_HW_BIT_RATE_11MBPS), ++}; ++ ++#if 0 ++enum { ++ CONF_HW_RATE_INDEX_1MBPS = 0, ++ CONF_HW_RATE_INDEX_2MBPS = 1, ++ CONF_HW_RATE_INDEX_5_5MBPS = 2, ++ CONF_HW_RATE_INDEX_6MBPS = 3, ++ CONF_HW_RATE_INDEX_9MBPS = 4, ++ CONF_HW_RATE_INDEX_11MBPS = 5, ++ CONF_HW_RATE_INDEX_12MBPS = 6, ++ CONF_HW_RATE_INDEX_18MBPS = 7, ++ CONF_HW_RATE_INDEX_22MBPS = 8, ++ CONF_HW_RATE_INDEX_24MBPS = 9, ++ CONF_HW_RATE_INDEX_36MBPS = 10, ++ CONF_HW_RATE_INDEX_48MBPS = 11, ++ CONF_HW_RATE_INDEX_54MBPS = 12, ++ CONF_HW_RATE_INDEX_MAX, ++}; ++ ++enum { ++ CONF_HW_RXTX_RATE_54 = 0, ++ CONF_HW_RXTX_RATE_48, ++ CONF_HW_RXTX_RATE_36, ++ CONF_HW_RXTX_RATE_24, ++ CONF_HW_RXTX_RATE_22, ++ CONF_HW_RXTX_RATE_18, ++ CONF_HW_RXTX_RATE_12, ++ CONF_HW_RXTX_RATE_11, ++ CONF_HW_RXTX_RATE_9, ++ CONF_HW_RXTX_RATE_6, ++ CONF_HW_RXTX_RATE_5_5, ++ CONF_HW_RXTX_RATE_2, ++ CONF_HW_RXTX_RATE_1, ++ CONF_HW_RXTX_RATE_MAX, ++ CONF_HW_RXTX_RATE_UNSUPPORTED = 0xff ++}; ++#endif ++ ++#endif /* _ESP_WL_H_ */ +diff --git a/drivers/net/wireless/esp8089/esp_wmac.h b/drivers/net/wireless/esp8089/esp_wmac.h +new file mode 100644 +index 000000000000..72d13cbfc0e5 +--- /dev/null ++++ b/drivers/net/wireless/esp8089/esp_wmac.h +@@ -0,0 +1,92 @@ ++/* ++ * Copyright (c) 2011-2012 Espressif System. ++ * ++ * MAC header ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _ESP_WMAC_H_ ++#define _ESP_WMAC_H_ ++ ++struct esp_mac_rx_ctrl { ++ signed rssi:8; ++ unsigned rate:4; ++ unsigned is_group:1; ++ unsigned:1; ++ unsigned sig_mode:2; ++ unsigned legacy_length:12; ++ unsigned damatch0:1; ++ unsigned damatch1:1; ++ unsigned bssidmatch0:1; ++ unsigned bssidmatch1:1; ++ unsigned MCS:7; ++ unsigned CWB:1; ++ unsigned HT_length:16; ++ unsigned Smoothing:1; ++ unsigned Not_Sounding:1; ++ unsigned:1; ++ unsigned Aggregation:1; ++ unsigned STBC:2; ++ unsigned FEC_CODING:1; ++ unsigned SGI:1; ++ unsigned rxend_state:8; ++ unsigned ampdu_cnt:8; ++ unsigned channel:4; ++ unsigned:4; ++ signed noise_floor:8; ++}; ++ ++struct esp_rx_ampdu_len { ++ unsigned substate:8; ++ unsigned sublen:12; ++ unsigned:12; ++}; ++ ++struct esp_tx_ampdu_entry { ++ u32 sub_len:12, dili_num:7,:1, null_byte:2, data:1, enc:1, seq:8; ++}; ++ ++//rxend_state flags ++#define RX_PYH_ERR_MIN 0x42 ++#define RX_AGC_ERR_MIN 0x42 ++#define RX_AGC_ERR_MAX 0x47 ++#define RX_OFDM_ERR_MIN 0x50 ++#define RX_OFDM_ERR_MAX 0x58 ++#define RX_CCK_ERR_MIN 0x59 ++#define RX_CCK_ERR_MAX 0x5F ++#define RX_ABORT 0x80 ++#define RX_SF_ERR 0x40 ++#define RX_FCS_ERR 0x41 ++#define RX_AHBOV_ERR 0xC0 ++#define RX_BUFOV_ERR 0xC1 ++#define RX_BUFINV_ERR 0xC2 ++#define RX_AMPDUSF_ERR 0xC3 ++#define RX_AMPDUBUFOV_ERR 0xC4 ++#define RX_MACBBFIFOOV_ERR 0xC5 ++#define RX_RPBM_ERR 0xC6 ++#define RX_BTFORCE_ERR 0xC7 ++#define RX_SECOV_ERR 0xE1 ++#define RX_SECPROT_ERR0 0xE2 ++#define RX_SECPROT_ERR1 0xE3 ++#define RX_SECKEY_ERR 0xE4 ++#define RX_SECCRLEN_ERR 0xE5 ++#define RX_SECFIFO_TIMEOUT 0xE6 ++#define RX_WEPICV_ERR 0xF0 ++#define RX_TKIPICV_ERR 0xF4 ++#define RX_TKIPMIC_ERR 0xF5 ++#define RX_CCMPMIC_ERR 0xF8 ++#define RX_WAPIMIC_ERR 0xFC ++ ++s8 esp_wmac_rate2idx(u8 rate); ++bool esp_wmac_rxsec_error(u8 error); ++ ++#endif /* _ESP_WMAC_H_ */ +diff --git a/drivers/net/wireless/esp8089/firmware/LICENSE-2.0.txt b/drivers/net/wireless/esp8089/firmware/LICENSE-2.0.txt +new file mode 100644 +index 000000000000..0dd35c82a001 +--- /dev/null ++++ b/drivers/net/wireless/esp8089/firmware/LICENSE-2.0.txt +@@ -0,0 +1,203 @@ ++The esp8089 firmware files are licensed under the Apache License, Version 2.0: ++ ++ 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. +diff --git a/drivers/net/wireless/esp8089/sdio_sif_esp.c b/drivers/net/wireless/esp8089/sdio_sif_esp.c +new file mode 100644 +index 000000000000..2bd2c63f5388 +--- /dev/null ++++ b/drivers/net/wireless/esp8089/sdio_sif_esp.c +@@ -0,0 +1,824 @@ ++/* ++ * Copyright (c) 2010 -2013 Espressif System. ++ * ++ * sdio serial i/f driver ++ * - sdio device control routines ++ * - sync/async DMA/PIO read/write ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "esp_pub.h" ++#include "esp_sif.h" ++#include "esp_sip.h" ++#include "esp_debug.h" ++#include "slc_host_register.h" ++#include "esp_version.h" ++#include "esp_ctrl.h" ++#include "esp_file.h" ++#ifdef USE_EXT_GPIO ++#include "esp_ext.h" ++#endif /* USE_EXT_GPIO */ ++ ++#define MANUFACTURER_ID_EAGLE_BASE 0x1110 ++#define MANUFACTURER_ID_EAGLE_BASE_MASK 0xFF00 ++#define MANUFACTURER_CODE 0x6666 ++ ++static const struct sdio_device_id esp_sdio_devices[] = { ++ {SDIO_DEVICE ++ (MANUFACTURER_CODE, (MANUFACTURER_ID_EAGLE_BASE | 0x1))}, ++ {}, ++}; ++ ++static const struct of_device_id esp_of_match_table[] = { ++ { .compatible = "esp,esp8089", .data = NULL}, ++ { } ++}; ++ ++static int /*__init*/ esp_sdio_init(void); ++static void /*__exit*/ esp_sdio_exit(void); ++ ++ ++#define ESP_DMA_IBUFSZ 2048 ++ ++//unsigned int esp_msg_level = 0; ++unsigned int esp_msg_level = ESP_DBG_ERROR | ESP_SHOW; ++ ++struct esp_sdio_ctrl *sif_sctrl = NULL; ++ ++#ifdef ESP_ANDROID_LOGGER ++bool log_off = false; ++#endif /* ESP_ANDROID_LOGGER */ ++ ++static int esdio_power_off(struct esp_sdio_ctrl *sctrl); ++static int esdio_power_on(struct esp_sdio_ctrl *sctrl); ++ ++void sif_set_clock(struct sdio_func *func, int clk); ++ ++void sif_lock_bus(struct esp_pub *epub) ++{ ++ EPUB_FUNC_CHECK(epub, _exit); ++ ++ sdio_claim_host(EPUB_TO_FUNC(epub)); ++ _exit: ++ return; ++} ++ ++void sif_unlock_bus(struct esp_pub *epub) ++{ ++ EPUB_FUNC_CHECK(epub, _exit); ++ ++ sdio_release_host(EPUB_TO_FUNC(epub)); ++ _exit: ++ return; ++} ++ ++static inline bool bad_buf(u8 * buf) ++{ ++ return ((unsigned long) buf & 0x3) || !virt_addr_valid(buf); ++} ++ ++u8 sdio_io_readb(struct esp_pub *epub, int addr, int *res) ++{ ++ struct esp_sdio_ctrl *sctrl = NULL; ++ struct sdio_func *func = NULL; ++ sctrl = (struct esp_sdio_ctrl *) epub->sif; ++ func = sctrl->func; ++ ++ if (func->num == 0) ++ return sdio_f0_readb(func, addr, res); ++ else ++ return sdio_readb(func, addr, res); ++} ++ ++void sdio_io_writeb(struct esp_pub *epub, u8 value, int addr, int *res) ++{ ++ struct esp_sdio_ctrl *sctrl = NULL; ++ struct sdio_func *func = NULL; ++ sctrl = (struct esp_sdio_ctrl *) epub->sif; ++ func = sctrl->func; ++ ++ if (func->num == 0) ++ sdio_f0_writeb(func, value, addr, res); ++ else ++ sdio_writeb(func, value, addr, res); ++} ++ ++int sif_io_raw(struct esp_pub *epub, u32 addr, u8 * buf, u32 len, u32 flag) ++{ ++ int err = 0; ++ u8 *ibuf = NULL; ++ bool need_ibuf = false; ++ struct esp_sdio_ctrl *sctrl = NULL; ++ struct sdio_func *func = NULL; ++ ++ if (epub == NULL || buf == NULL) { ++ ESSERT(0); ++ err = -EINVAL; ++ goto _exit; ++ } ++ ++ sctrl = (struct esp_sdio_ctrl *) epub->sif; ++ func = sctrl->func; ++ if (func == NULL) { ++ ESSERT(0); ++ err = -EINVAL; ++ goto _exit; ++ } ++ ++ if (bad_buf(buf)) { ++ esp_dbg(ESP_DBG_TRACE, "%s dst 0x%08x, len %d badbuf\n", ++ __func__, addr, len); ++ need_ibuf = true; ++ ibuf = sctrl->dma_buffer; ++ } else { ++ ibuf = buf; ++ } ++ ++ if (flag & SIF_BLOCK_BASIS) { ++ /* round up for block data transcation */ ++ } ++ ++ if (flag & SIF_TO_DEVICE) { ++ ++ if (need_ibuf) ++ memcpy(ibuf, buf, len); ++ ++ if (flag & SIF_FIXED_ADDR) ++ err = sdio_writesb(func, addr, ibuf, len); ++ else if (flag & SIF_INC_ADDR) { ++ err = sdio_memcpy_toio(func, addr, ibuf, len); ++ } ++ } else if (flag & SIF_FROM_DEVICE) { ++ ++ if (flag & SIF_FIXED_ADDR) ++ err = sdio_readsb(func, ibuf, addr, len); ++ else if (flag & SIF_INC_ADDR) { ++ err = sdio_memcpy_fromio(func, ibuf, addr, len); ++ } ++ ++ ++ if (!err && need_ibuf) ++ memcpy(buf, ibuf, len); ++ } ++ ++ _exit: ++ return err; ++} ++ ++int sif_io_sync(struct esp_pub *epub, u32 addr, u8 * buf, u32 len, ++ u32 flag) ++{ ++ int err = 0; ++ u8 *ibuf = NULL; ++ bool need_ibuf = false; ++ struct esp_sdio_ctrl *sctrl = NULL; ++ struct sdio_func *func = NULL; ++ ++ if (epub == NULL || buf == NULL) { ++ ESSERT(0); ++ err = -EINVAL; ++ goto _exit; ++ } ++ ++ sctrl = (struct esp_sdio_ctrl *) epub->sif; ++ func = sctrl->func; ++ if (func == NULL) { ++ ESSERT(0); ++ err = -EINVAL; ++ goto _exit; ++ } ++ ++ if (bad_buf(buf)) { ++ esp_dbg(ESP_DBG_TRACE, "%s dst 0x%08x, len %d badbuf\n", ++ __func__, addr, len); ++ need_ibuf = true; ++ ibuf = sctrl->dma_buffer; ++ } else { ++ ibuf = buf; ++ } ++ ++ if (flag & SIF_BLOCK_BASIS) { ++ /* round up for block data transcation */ ++ } ++ ++ if (flag & SIF_TO_DEVICE) { ++ ++ esp_dbg(ESP_DBG_TRACE, "%s to addr 0x%08x, len %d \n", ++ __func__, addr, len); ++ if (need_ibuf) ++ memcpy(ibuf, buf, len); ++ ++ sdio_claim_host(func); ++ ++ if (flag & SIF_FIXED_ADDR) ++ err = sdio_writesb(func, addr, ibuf, len); ++ else if (flag & SIF_INC_ADDR) { ++ err = sdio_memcpy_toio(func, addr, ibuf, len); ++ } ++ sdio_release_host(func); ++ } else if (flag & SIF_FROM_DEVICE) { ++ ++ esp_dbg(ESP_DBG_TRACE, "%s from addr 0x%08x, len %d \n", ++ __func__, addr, len); ++ ++ sdio_claim_host(func); ++ ++ if (flag & SIF_FIXED_ADDR) ++ err = sdio_readsb(func, ibuf, addr, len); ++ else if (flag & SIF_INC_ADDR) { ++ err = sdio_memcpy_fromio(func, ibuf, addr, len); ++ } ++ ++ sdio_release_host(func); ++ ++ if (!err && need_ibuf) ++ memcpy(buf, ibuf, len); ++ } ++ ++ _exit: ++ return err; ++} ++ ++int sif_lldesc_read_sync(struct esp_pub *epub, u8 * buf, u32 len) ++{ ++ struct esp_sdio_ctrl *sctrl = NULL; ++ u32 read_len; ++ ++ if (epub == NULL || buf == NULL) { ++ ESSERT(0); ++ return -EINVAL; ++ } ++ ++ sctrl = (struct esp_sdio_ctrl *) epub->sif; ++ ++ switch (sctrl->target_id) { ++ case 0x100: ++ read_len = len; ++ break; ++ case 0x600: ++ read_len = roundup(len, sctrl->slc_blk_sz); ++ break; ++ default: ++ read_len = len; ++ break; ++ } ++ ++ return sif_io_sync((epub), ++ (sctrl->slc_window_end_addr - 2 - (len)), (buf), ++ (read_len), ++ SIF_FROM_DEVICE | SIF_BYTE_BASIS | ++ SIF_INC_ADDR); ++} ++ ++int sif_lldesc_write_sync(struct esp_pub *epub, u8 * buf, u32 len) ++{ ++ struct esp_sdio_ctrl *sctrl = NULL; ++ u32 write_len; ++ ++ if (epub == NULL || buf == NULL) { ++ ESSERT(0); ++ return -EINVAL; ++ } ++ ++ sctrl = (struct esp_sdio_ctrl *) epub->sif; ++ ++ switch (sctrl->target_id) { ++ case 0x100: ++ write_len = len; ++ break; ++ case 0x600: ++ write_len = roundup(len, sctrl->slc_blk_sz); ++ break; ++ default: ++ write_len = len; ++ break; ++ } ++ ++ return sif_io_sync((epub), (sctrl->slc_window_end_addr - (len)), ++ (buf), (write_len), ++ SIF_TO_DEVICE | SIF_BYTE_BASIS | SIF_INC_ADDR); ++} ++ ++int sif_lldesc_read_raw(struct esp_pub *epub, u8 * buf, u32 len, ++ bool noround) ++{ ++ struct esp_sdio_ctrl *sctrl = NULL; ++ u32 read_len; ++ ++ if (epub == NULL || buf == NULL) { ++ ESSERT(0); ++ return -EINVAL; ++ } ++ ++ sctrl = (struct esp_sdio_ctrl *) epub->sif; ++ ++ switch (sctrl->target_id) { ++ case 0x100: ++ read_len = len; ++ break; ++ case 0x600: ++ if (!noround) ++ read_len = roundup(len, sctrl->slc_blk_sz); ++ else ++ read_len = len; ++ break; ++ default: ++ read_len = len; ++ break; ++ } ++ ++ return sif_io_raw((epub), (sctrl->slc_window_end_addr - 2 - (len)), ++ (buf), (read_len), ++ SIF_FROM_DEVICE | SIF_BYTE_BASIS | SIF_INC_ADDR); ++} ++ ++int sif_lldesc_write_raw(struct esp_pub *epub, u8 * buf, u32 len) ++{ ++ struct esp_sdio_ctrl *sctrl = NULL; ++ u32 write_len; ++ ++ if (epub == NULL || buf == NULL) { ++ ESSERT(0); ++ return -EINVAL; ++ } ++ ++ sctrl = (struct esp_sdio_ctrl *) epub->sif; ++ ++ switch (sctrl->target_id) { ++ case 0x100: ++ write_len = len; ++ break; ++ case 0x600: ++ write_len = roundup(len, sctrl->slc_blk_sz); ++ break; ++ default: ++ write_len = len; ++ break; ++ } ++ return sif_io_raw((epub), (sctrl->slc_window_end_addr - (len)), ++ (buf), (write_len), ++ SIF_TO_DEVICE | SIF_BYTE_BASIS | SIF_INC_ADDR); ++ ++} ++ ++static int esdio_power_on(struct esp_sdio_ctrl *sctrl) ++{ ++ int err = 0; ++ ++ if (sctrl->off == false) ++ return err; ++ ++ sdio_claim_host(sctrl->func); ++ err = sdio_enable_func(sctrl->func); ++ ++ if (err) { ++ esp_dbg(ESP_DBG_ERROR, "Unable to enable sdio func: %d\n", ++ err); ++ sdio_release_host(sctrl->func); ++ return err; ++ } ++ ++ sdio_release_host(sctrl->func); ++ ++ /* ensure device is up */ ++ msleep(5); ++ ++ sctrl->off = false; ++ ++ return err; ++} ++ ++static int esdio_power_off(struct esp_sdio_ctrl *sctrl) ++{ ++ int err; ++ ++ if (sctrl->off) ++ return 0; ++ ++ sdio_claim_host(sctrl->func); ++ err = sdio_disable_func(sctrl->func); ++ sdio_release_host(sctrl->func); ++ ++ if (err) ++ return err; ++ ++ sctrl->off = true; ++ ++ return err; ++} ++ ++void sif_enable_irq(struct esp_pub *epub) ++{ ++ int err; ++ struct esp_sdio_ctrl *sctrl = NULL; ++ ++ sctrl = (struct esp_sdio_ctrl *) epub->sif; ++ ++ sdio_claim_host(sctrl->func); ++ ++ err = sdio_claim_irq(sctrl->func, sif_dsr); ++ ++ if (err) ++ esp_dbg(ESP_DBG_ERROR, "sif %s failed\n", __func__); ++ ++ atomic_set(&epub->sip->state, SIP_BOOT); ++ ++ atomic_set(&sctrl->irq_installed, 1); ++ ++ sdio_release_host(sctrl->func); ++} ++ ++void sif_disable_irq(struct esp_pub *epub) ++{ ++ struct esp_sdio_ctrl *sctrl = (struct esp_sdio_ctrl *) epub->sif; ++ int i = 0; ++ ++ if (atomic_read(&sctrl->irq_installed) == 0) ++ return; ++ ++ sdio_claim_host(sctrl->func); ++ ++ while (atomic_read(&sctrl->irq_handling)) { ++ sdio_release_host(sctrl->func); ++ schedule_timeout(HZ / 100); ++ sdio_claim_host(sctrl->func); ++ if (i++ >= 400) { ++ esp_dbg(ESP_DBG_ERROR, "%s force to stop irq\n", ++ __func__); ++ break; ++ } ++ } ++ ++ /* Ignore errors, we don't always use an irq. */ ++ sdio_release_irq(sctrl->func); ++ ++ atomic_set(&sctrl->irq_installed, 0); ++ ++ sdio_release_host(sctrl->func); ++ ++} ++ ++void sif_set_clock(struct sdio_func *func, int clk) ++{ ++ struct mmc_host *host = NULL; ++ struct mmc_card *card = NULL; ++ ++ card = func->card; ++ host = card->host; ++ ++ sdio_claim_host(func); ++ ++ //currently only set clock ++ host->ios.clock = clk * 1000000; ++ ++ esp_dbg(ESP_SHOW, "%s clock is %u\n", __func__, host->ios.clock); ++ if (host->ios.clock > host->f_max) { ++ host->ios.clock = host->f_max; ++ } ++ host->ops->set_ios(host, &host->ios); ++ ++ mdelay(2); ++ ++ sdio_release_host(func); ++} ++ ++static int esp_sdio_probe(struct sdio_func *func, ++ const struct sdio_device_id *id); ++static void esp_sdio_remove(struct sdio_func *func); ++ ++static int esp_sdio_probe(struct sdio_func *func, ++ const struct sdio_device_id *id) ++{ ++ int err = 0; ++ struct esp_pub *epub = NULL; ++ struct esp_sdio_ctrl *sctrl; ++ ++ esp_dbg(ESP_DBG_TRACE, ++ "sdio_func_num: 0x%X, vendor id: 0x%X, dev id: 0x%X, block size: 0x%X/0x%X\n", ++ func->num, func->vendor, func->device, func->max_blksize, ++ func->cur_blksize); ++ ++ if (sif_sctrl == NULL) { ++ ++ esp_conf_init(&func->dev); ++ ++ esp_conf_upload_first(); ++ ++ sctrl = kzalloc(sizeof(struct esp_sdio_ctrl), GFP_KERNEL); ++ ++ if (sctrl == NULL) { ++ return -ENOMEM; ++ } ++ ++ /* temp buffer reserved for un-dma-able request */ ++ sctrl->dma_buffer = kzalloc(ESP_DMA_IBUFSZ, GFP_KERNEL); ++ ++ if (sctrl->dma_buffer == NULL) { ++ err = -ENOMEM; ++ goto _err_last; ++ } ++ sif_sctrl = sctrl; ++ sctrl->slc_blk_sz = SIF_SLC_BLOCK_SIZE; ++ ++ epub = esp_pub_alloc_mac80211(&func->dev); ++ ++ if (epub == NULL) { ++ esp_dbg(ESP_DBG_ERROR, "no mem for epub \n"); ++ err = -ENOMEM; ++ goto _err_dma; ++ } ++ epub->sif = (void *) sctrl; ++ epub->sdio_state = ESP_SDIO_STATE_FIRST_INIT; ++ sctrl->epub = epub; ++ ++#ifdef USE_EXT_GPIO ++ if (sif_get_ate_config() == 0) { ++ err = ext_gpio_init(epub); ++ if (err) { ++ esp_dbg(ESP_DBG_ERROR, ++ "ext_irq_work_init failed %d\n", ++ err); ++ goto _err_epub; ++ } ++ } ++#endif ++ ++ } else { ++ sctrl = sif_sctrl; ++ sif_sctrl = NULL; ++ epub = sctrl->epub; ++ epub->sdio_state = ESP_SDIO_STATE_SECOND_INIT; ++ SET_IEEE80211_DEV(epub->hw, &func->dev); ++ epub->dev = &func->dev; ++ } ++ ++ sctrl->func = func; ++ sdio_set_drvdata(func, sctrl); ++ ++ sctrl->id = id; ++ sctrl->off = true; ++ ++ /* give us some time to enable, in ms */ ++ func->enable_timeout = 100; ++ ++ err = esdio_power_on(sctrl); ++ esp_dbg(ESP_DBG_TRACE, " %s >> power_on err %d \n", __func__, err); ++ ++ if (err) { ++ if (epub->sdio_state == ESP_SDIO_STATE_FIRST_INIT) ++ goto _err_ext_gpio; ++ else ++ goto _err_second_init; ++ } ++ check_target_id(epub); ++ ++ sdio_claim_host(func); ++ ++ err = sdio_set_block_size(func, sctrl->slc_blk_sz); ++ ++ if (err) { ++ esp_dbg(ESP_DBG_ERROR, ++ "Set sdio block size %d failed: %d)\n", ++ sctrl->slc_blk_sz, err); ++ sdio_release_host(func); ++ if (epub->sdio_state == ESP_SDIO_STATE_FIRST_INIT) ++ goto _err_off; ++ else ++ goto _err_second_init; ++ } ++ ++ sdio_release_host(func); ++ ++#ifdef LOWER_CLK ++ /* fix clock for dongle */ ++ sif_set_clock(func, 23); ++#endif //LOWER_CLK ++ ++ err = esp_pub_init_all(epub); ++ ++ if (err) { ++ esp_dbg(ESP_DBG_ERROR, "esp_init_all failed: %d\n", err); ++ if (epub->sdio_state == ESP_SDIO_STATE_FIRST_INIT) { ++ err = 0; ++ goto _err_first_init; ++ } ++ if (epub->sdio_state == ESP_SDIO_STATE_SECOND_INIT) ++ goto _err_second_init; ++ } ++ ++ esp_dbg(ESP_DBG_TRACE, " %s return %d\n", __func__, err); ++ if (epub->sdio_state == ESP_SDIO_STATE_FIRST_INIT) { ++ esp_dbg(ESP_DBG_TRACE, "first normal exit\n"); ++ epub->sdio_state = ESP_SDIO_STATE_FIRST_NORMAL_EXIT; ++ /* Rescan the esp8089 after loading the initial firmware */ ++ sdio_claim_host(func); ++ mmc_sw_reset(func->card); ++ sdio_release_host(func); ++ msleep(10); ++ } ++ ++ return err; ++ ++ _err_off: ++ esdio_power_off(sctrl); ++ _err_ext_gpio: ++#ifdef USE_EXT_GPIO ++ if (sif_get_ate_config() == 0) ++ ext_gpio_deinit(); ++ _err_epub: ++#endif ++ esp_pub_dealloc_mac80211(epub); ++ _err_dma: ++ kfree(sctrl->dma_buffer); ++ _err_last: ++ kfree(sctrl); ++ _err_first_init: ++ if (epub && epub->sdio_state == ESP_SDIO_STATE_FIRST_INIT) { ++ esp_dbg(ESP_DBG_ERROR, "first error exit\n"); ++ epub->sdio_state = ESP_SDIO_STATE_FIRST_ERROR_EXIT; ++ } ++ return err; ++ _err_second_init: ++ epub->sdio_state = ESP_SDIO_STATE_SECOND_ERROR_EXIT; ++ esp_sdio_remove(func); ++ return err; ++} ++ ++static void esp_sdio_remove(struct sdio_func *func) ++{ ++ struct esp_sdio_ctrl *sctrl = NULL; ++ struct esp_pub *epub = NULL; ++ ++ esp_dbg(ESP_DBG_TRACE, "%s enter\n", __func__); ++ ++ sctrl = sdio_get_drvdata(func); ++ ++ if (sctrl == NULL) { ++ esp_dbg(ESP_DBG_ERROR, "%s no sctrl\n", __func__); ++ return; ++ } ++ ++ do { ++ epub = sctrl->epub; ++ if (epub == NULL) { ++ esp_dbg(ESP_DBG_ERROR, "%s epub null\n", __func__); ++ break; ++ } ++ if (epub->sdio_state != ESP_SDIO_STATE_FIRST_NORMAL_EXIT) { ++ if (epub->sip) { ++ sip_detach(epub->sip); ++ epub->sip = NULL; ++ esp_dbg(ESP_DBG_TRACE, ++ "%s sip detached \n", __func__); ++ } ++#ifdef USE_EXT_GPIO ++ if (sif_get_ate_config() == 0) ++ ext_gpio_deinit(); ++#endif ++ } else { ++ //sif_disable_target_interrupt(epub); ++ atomic_set(&epub->sip->state, SIP_STOP); ++ sif_disable_irq(epub); ++ } ++ ++ if (epub->sdio_state != ESP_SDIO_STATE_FIRST_NORMAL_EXIT) { ++ esp_pub_dealloc_mac80211(epub); ++ esp_dbg(ESP_DBG_TRACE, "%s dealloc mac80211 \n", ++ __func__); ++ ++ if (sctrl->dma_buffer) { ++ kfree(sctrl->dma_buffer); ++ sctrl->dma_buffer = NULL; ++ esp_dbg(ESP_DBG_TRACE, ++ "%s free dma_buffer \n", __func__); ++ } ++ ++ kfree(sctrl); ++ } ++ ++ } while (0); ++ ++ sdio_set_drvdata(func, NULL); ++ ++ /* ++ * Reset on sdio remove to leave the hardware in cold state, ++ * so a new module insertion will be possible ++ */ ++ if (epub->sdio_state == ESP_SDIO_STATE_SECOND_INIT) { ++ sdio_claim_host(func); ++ mmc_hw_reset(func->card); ++ sdio_release_host(func); ++ mdelay(10); ++ } ++ ++ esp_dbg(ESP_DBG_TRACE, "eagle sdio remove complete\n"); ++} ++ ++static int esp_sdio_suspend(struct device *dev) ++{ ++ struct sdio_func *func = dev_to_sdio_func(dev); ++ struct esp_sdio_ctrl *sctrl = sdio_get_drvdata(func); ++ struct esp_pub *epub = sctrl->epub; ++ ++ printk("%s", __func__); ++ atomic_set(&epub->ps.state, ESP_PM_ON); ++ ++ do { ++ u32 sdio_flags = 0; ++ int ret = 0; ++ sdio_flags = sdio_get_host_pm_caps(func); ++ ++ if (!(sdio_flags & MMC_PM_KEEP_POWER)) { ++ printk ++ ("%s can't keep power while host is suspended\n", ++ __func__); ++ } ++ ++ /* keep power while host suspended */ ++ ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); ++ if (ret) { ++ printk("%s error while trying to keep power\n", ++ __func__); ++ } ++ } while (0); ++ ++ ++ return 0; ++ ++} ++ ++static int esp_sdio_resume(struct device *dev) ++{ ++ esp_dbg(ESP_DBG_ERROR, "%s", __func__); ++ ++ return 0; ++} ++ ++static const struct dev_pm_ops esp_sdio_pm_ops = { ++ .suspend = esp_sdio_suspend, ++ .resume = esp_sdio_resume, ++}; ++ ++static struct sdio_driver esp_sdio_driver = { ++ .name = "eagle_sdio", ++ .id_table = esp_sdio_devices, ++ .probe = esp_sdio_probe, ++ .remove = esp_sdio_remove, ++ .drv = { ++ .pm = &esp_sdio_pm_ops, ++ .of_match_table = esp_of_match_table, ++ }, ++}; ++ ++static int /*__init*/ esp_sdio_init(void) ++{ ++ ++ esp_debugfs_init(); ++ sdio_register_driver(&esp_sdio_driver); ++ ++ msleep(1000); ++ ++ sdio_unregister_driver(&esp_sdio_driver); ++ msleep(100); ++ sdio_register_driver(&esp_sdio_driver); ++ ++ return 0; ++} ++ ++static void /*__exit*/ esp_sdio_exit(void) ++{ ++ sdio_unregister_driver(&esp_sdio_driver); ++ esp_debugfs_exit(); ++} ++ ++MODULE_DEVICE_TABLE(sdio, esp_sdio_devices); ++MODULE_DEVICE_TABLE(of, esp_of_match_table); ++MODULE_AUTHOR("Espressif System"); ++MODULE_DESCRIPTION ++ ("Driver for SDIO interconnected eagle low-power WLAN devices"); ++MODULE_LICENSE("GPL"); ++ ++module_init(esp_sdio_init); ++module_exit(esp_sdio_exit); +diff --git a/drivers/net/wireless/esp8089/sip2_common.h b/drivers/net/wireless/esp8089/sip2_common.h +new file mode 100644 +index 000000000000..d46e87589b0b +--- /dev/null ++++ b/drivers/net/wireless/esp8089/sip2_common.h +@@ -0,0 +1,475 @@ ++/* ++ * Copyright (c) 2010 - 2014 Espressif System. ++ * ++ * Common definitions of Serial Interconnctor Protocol ++ * ++ * little endian ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _SIP2_COMMON_H ++#define _SIP2_COMMON_H ++ ++#ifdef __ets__ ++#include "utils.h" ++#endif /*__ets__*/ ++ ++/* max 16 types */ ++typedef enum { ++ SIP_CTRL = 0, ++ SIP_DATA, ++ SIP_DATA_AMPDU ++} SIP_TYPE; ++ ++typedef enum { ++ SIP_TX_CTRL_BUF = 0, /* from host */ ++ SIP_RX_CTRL_BUF, /* to host */ ++ SIP_TX_DATA_BUF, /* from host */ ++ SIP_RX_DATA_BUF /* to host */ ++} SIP_BUF_TYPE; ++ ++enum sip_cmd_id { ++ SIP_CMD_GET_VER = 0, ++ SIP_CMD_WRITE_MEMORY, //1 ROM code ++ SIP_CMD_READ_MEMORY, //2 ++ SIP_CMD_WRITE_REG, //3 ROM code ++ SIP_CMD_READ_REG, //4 ++ SIP_CMD_BOOTUP, //5 ROM code ++ SIP_CMD_COPYBACK, //6 ++ SIP_CMD_INIT, //7 ++ SIP_CMD_SCAN, //8 ++ SIP_CMD_SETKEY, //9 ++ SIP_CMD_CONFIG, //10 ++ SIP_CMD_BSS_INFO_UPDATE, //11 ++ SIP_CMD_LOOPBACK, //12 ROM code ++ //do not add cmd before this line ++ SIP_CMD_SET_WMM_PARAM, ++ SIP_CMD_AMPDU_ACTION, ++ SIP_CMD_HB_REQ, //15 ++ SIP_CMD_RESET_MAC, //16 ++ SIP_CMD_PRE_DOWN, //17 ++ SIP_CMD_SLEEP, /* for sleep testing */ ++ SIP_CMD_WAKEUP, /* for sleep testing */ ++ SIP_CMD_DEBUG, /* for general testing */ ++ SIP_CMD_GET_FW_VER, /* get fw rev. */ ++ SIP_CMD_SETVIF, ++ SIP_CMD_SETSTA, ++ SIP_CMD_PS, ++ SIP_CMD_ATE, ++ SIP_CMD_SUSPEND, ++ SIP_CMD_RECALC_CREDIT, ++ SIP_CMD_MAX, ++}; ++ ++enum { ++ SIP_EVT_TARGET_ON = 0, // ++ SIP_EVT_BOOTUP, //1 in ROM code ++ SIP_EVT_COPYBACK, //2 ++ SIP_EVT_SCAN_RESULT, //3 ++ SIP_EVT_TX_STATUS, //4 ++ SIP_EVT_CREDIT_RPT, //5, in ROM code ++ SIP_EVT_ERROR, //6 ++ SIP_EVT_LOOPBACK, //7, in ROM code ++ SIP_EVT_SNPRINTF_TO_HOST, //8 in ROM code ++ //do not add evt before this line ++ SIP_EVT_HB_ACK, //9 ++ SIP_EVT_RESET_MAC_ACK, //10 ++ SIP_EVT_WAKEUP, //11 /* for sleep testing */ ++ SIP_EVT_DEBUG, //12 /* for general testing */ ++ SIP_EVT_PRINT_TO_HOST, //13 ++ SIP_EVT_TRC_AMPDU, //14 ++ SIP_EVT_ROC, //15 ++ SIP_EVT_RESETTING, ++ SIP_EVT_ATE, ++ SIP_EVT_EP, ++ SIP_EVT_INIT_EP, ++ SIP_EVT_SLEEP, ++ SIP_EVT_TXIDLE, ++ SIP_EVT_NOISEFLOOR, ++ SIP_EVT_MAX ++}; ++ ++#define SIP_IFIDX_MASK 0xf0 ++#define SIP_IFIDX_S 4 ++#define SIP_TYPE_MASK 0x0f ++#define SIP_TYPE_S 0 ++ ++#define SIP_HDR_GET_IFIDX(fc0) (((fc0) & SIP_IFIDX_MASK) >> SIP_IFIDX_S) ++#define SIP_HDR_SET_IFIDX(fc0, ifidx) ( (fc0) = ((fc0) & ~SIP_IFIDX_MASK) | ((ifidx) << SIP_IFIDX_S & SIP_IFIDX_MASK) ) ++#define SIP_HDR_GET_TYPE(fc0) ((fc0) & SIP_TYPE_MASK ) ++/* assume type field is cleared */ ++#define SIP_HDR_SET_TYPE(fc0, type) ((fc0) = ((fc0) & ~ SIP_TYPE_MASK) | ((type) & SIP_TYPE_MASK)) ++ ++/* sip 2.0, not hybrid header so far */ ++#define SIP_HDR_IS_CTRL(hdr) (SIP_HDR_GET_TYPE((hdr)->fc[0]) == SIP_CTRL) ++#define SIP_HDR_IS_DATA(hdr) (SIP_HDR_GET_TYPE((hdr)->fc[0]) == SIP_DATA) ++#define SIP_HDR_IS_AMPDU(hdr) (SIP_HDR_GET_TYPE((hdr)->fc[0]) == SIP_DATA_AMPDU) ++ ++/* fc[1] flags, only for data pkt. Ctrl pkts use fc[1] as eventID */ ++#define SIP_HDR_SET_FLAGS(hdr, flags) ((hdr)->fc[1] |= (flags)) ++#define SIP_HDR_F_MORE_PKT 0x1 ++#define SIP_HDR_F_NEED_CRDT_RPT 0x2 ++#define SIP_HDR_F_SYNC 0x4 ++#define SIP_HDR_F_SYNC_RESET 0x8 ++#define SIP_HDR_F_PM_TURNING_ON 0x10 ++#define SIP_HDR_F_PM_TURNING_OFF 0x20 ++ ++#define SIP_HDR_NEED_CREDIT_UPDATE(hdr) ((hdr)->fc[1] & SIP_HDR_F_NEED_CRDT_RPT) ++#define SIP_HDR_IS_MORE_PKT(hdr) ((hdr)->fc[1] & SIP_HDR_F_MORE_PKT) ++#define SIP_HDR_IS_CRDT_RPT(hdr) ((hdr)->fc[1] & SIP_HDR_F_CRDT_RPT) ++#define SIP_HDR_IS_SYNC(hdr) ((hdr)->fc[1] & SIP_HDR_F_SYNC) ++#define SIP_HDR_IS_SYNC_RESET(hdr) ((hdr)->fc[1] & SIP_HDR_F_SYNC_RESET) ++#define SIP_HDR_IS_SYNC_PKT(hdr) (SIP_HDR_IS_SYNC(hdr) | SIP_HDR_IS_SYNC_RESET(hdr)) ++#define SIP_HDR_SET_SYNC(hdr) SIP_HDR_SET_FLAGS((hdr), SIP_HDR_F_SYNC) ++#define SIP_HDR_SET_SYNC_RESET(hdr) SIP_HDR_SET_FLAGS((hdr), SIP_HDR_F_SYNC_RESET) ++#define SIP_HDR_SET_MORE_PKT(hdr) SIP_HDR_SET_FLAGS((hdr), SIP_HDR_F_MORE_PKT) ++#define SIP_HDR_SET_PM_TURNING_ON(hdr) SIP_HDR_SET_FLAGS((hdr), SIP_HDR_F_PM_TURNING_ON) ++#define SIP_HDR_IS_PM_TURNING_ON(hdr) ((hdr)->fc[1] & SIP_HDR_F_PM_TURNING_ON) ++#define SIP_HDR_SET_PM_TURNING_OFF(hdr) SIP_HDR_SET_FLAGS((hdr), SIP_HDR_F_PM_TURNING_OFF) ++#define SIP_HDR_IS_PM_TURNING_OFF(hdr) ((hdr)->fc[1] & SIP_HDR_F_PM_TURNING_OFF) ++ ++/* ++ * fc[0]: first 4bit: ifidx; last 4bit: type ++ * fc[1]: flags ++ * ++ * Don't touch the header definitons ++ */ ++struct sip_hdr_min { ++ u8 fc[2]; ++ __le16 len; ++} __packed; ++ ++/* not more than 4byte long */ ++struct sip_tx_data_info { ++ u8 tid; ++ u8 ac; ++ u8 p2p:1, enc_flag:7; ++ u8 hw_kid; ++} __packed; ++ ++/* NB: this structure should be not more than 4byte !! */ ++struct sip_tx_info { ++ union { ++ u32 cmdid; ++ struct sip_tx_data_info dinfo; ++ } u; ++} __packed; ++ ++struct sip_hdr { ++ u8 fc[2]; //fc[0]: type and ifidx ; fc[1] is eventID if the first ctrl pkt in the chain. data pkt still can use fc[1] to set flag ++ __le16 len; ++ union { ++ volatile u32 recycled_credits; /* last 12bits is credits, first 20 bits is actual length of the first pkt in the chain */ ++ struct sip_tx_info tx_info; ++ } u; ++ u32 seq; ++} __packed; ++ ++#define h_credits u.recycled_credits ++#define c_evtid fc[1] ++#define c_cmdid u.tx_info.u.cmdid ++#define d_ac u.tx_info.u.dinfo.ac ++#define d_tid u.tx_info.u.dinfo.tid ++#define d_p2p u.tx_info.u.dinfo.p2p ++#define d_enc_flag u.tx_info.u.dinfo.enc_flag ++#define d_hw_kid u.tx_info.u.dinfo.hw_kid ++ ++#define SIP_CREDITS_MASK 0xfff /* last 12 bits */ ++ ++#ifdef HOST_RC ++ ++#define RC_CNT_MASK 0xf ++ ++struct sip_rc_status { ++ u32 rc_map; ++ union { ++ u32 rc_cnt1:4, rc_cnt2:4, rc_cnt3:4, rc_cnt4:4, rc_cnt5:4; ++ ++ u32 rc_cnt_store; ++ }; ++}; ++ ++/* copy from mac80211.h */ ++struct sip_tx_rc { ++ struct ieee80211_tx_rate rates[IEEE80211_TX_MAX_RATES]; ++ s8 rts_cts_rate_idx; ++}; ++#endif /* HOST_RC */ ++ ++#define SIP_HDR_MIN_LEN 4 ++#define SIP_HDR_LEN sizeof(struct sip_hdr) ++#define SIP_CTRL_HDR_LEN SIP_HDR_LEN /* same as sip_hdr in sip2 design */ ++#define SIP_BOOT_BUF_SIZE 256 ++#define SIP_CTRL_BUF_SZ 256 /* too much?? */ ++#define SIP_CTRL_BUF_N 6 ++#define SIP_CTRL_TXBUF_N 2 ++#define SIP_CTRL_RXBUF_N 4 ++ ++/* WAR for mblk */ ++#define SIP_RX_ADDR_PREFIX_MASK 0xfc000000 ++#define SIP_RX_ADDR_SHIFT 6 /* [31:5], shift 6 bits */ ++ ++struct sip_cmd_write_memory { ++ u32 addr; ++ u32 len; ++} __packed; ++ ++struct sip_cmd_read_memory { ++ u32 addr; ++ u32 len; ++} __packed; ++ ++struct sip_cmd_write_reg { ++ u32 addr; ++ u32 val; ++} __packed; ++ ++struct sip_cmd_bootup { ++ u32 boot_addr; ++} __packed; ++ ++struct sip_cmd_loopback { ++ u32 txlen; //host to target packet len, 0 means no txpacket ++ u32 rxlen; //target to host packet len, 0 means no rxpacket ++ u32 pack_id; //sequence of packet ++} __packed; ++ ++struct sip_evt_loopback { ++ u32 txlen; //host to target packet len, 0 means no txpacket ++ u32 rxlen; //target to host packet len, 0 means no rxpacket ++ u32 pack_id; //sequence of packet ++} __packed; ++ ++struct sip_cmd_copyback { ++ u32 addr; ++ u32 len; ++} __packed; ++ ++struct sip_cmd_scan { ++// u8 ssid[32]; ++ u8 ssid_len; ++// u8 hw_channel[14]; ++ u8 n_channels; ++ u8 ie_len; ++ u8 aborted; ++} __packed; // ie[] append at the end ++ ++ ++#ifndef ETH_ALEN ++#define ETH_ALEN 6 ++#endif /* ETH_ALEN */ ++ ++struct sip_cmd_setkey { ++ u8 bssid_no; ++ u8 addr[ETH_ALEN]; ++ u8 alg; ++ u8 keyidx; ++ u8 hw_key_idx; ++ u8 flags; ++ u8 keylen; ++ u8 key[32]; ++} __packed; ++ ++struct sip_cmd_config { ++ u16 center_freq; ++ u16 duration; ++} __packed; ++ ++struct sip_cmd_bss_info_update { ++ u8 bssid[ETH_ALEN]; ++ u16 isassoc; ++ u32 beacon_int; ++ u8 bssid_no; ++} __packed; ++ ++struct sip_evt_bootup { ++ u16 tx_blksz; ++ u8 mac_addr[ETH_ALEN]; ++ /* anything else ? */ ++} __packed; ++ ++struct sip_cmd_setvif { ++ u8 index; ++ u8 mac[ETH_ALEN]; ++ u8 set; ++ u8 op_mode; ++ u8 is_p2p; ++} __packed; ++ ++enum esp_ieee80211_phytype { ++ ESP_IEEE80211_T_CCK = 0, ++ ESP_IEEE80211_T_OFDM = 1, ++ ESP_IEEE80211_T_HT20_L = 2, ++ ESP_IEEE80211_T_HT20_S = 3, ++}; ++ ++struct sip_cmd_setsta { ++ u8 ifidx; ++ u8 index; ++ u8 set; ++ u8 phymode; ++ u8 mac[ETH_ALEN]; ++ u16 aid; ++ u8 ampdu_factor; ++ u8 ampdu_density; ++ u16 resv; ++} __packed; ++ ++struct sip_cmd_ps { ++ u8 dtim_period; ++ u8 max_sleep_period; ++ u8 on; ++ u8 resv; ++} __packed; ++ ++struct sip_cmd_suspend { ++ u8 suspend; ++ u8 resv[3]; ++} __packed; ++ ++#define SIP_DUMP_RPBM_ERR BIT(0) ++#define SIP_RXABORT_FIXED BIT(1) ++#define SIP_SUPPORT_BGSCAN BIT(2) ++struct sip_evt_bootup2 { ++ u16 tx_blksz; ++ u8 mac_addr[ETH_ALEN]; ++ u16 rx_blksz; ++ u8 credit_to_reserve; ++ u8 options; ++ s16 noise_floor; ++ u8 resv[2]; ++ /* anything else ? */ ++} __packed; ++ ++typedef enum { ++ TRC_TX_AMPDU_STOPPED = 1, ++ TRC_TX_AMPDU_OPERATIONAL, ++ TRC_TX_AMPDU_WAIT_STOP, ++ TRC_TX_AMPDU_WAIT_OPERATIONAL, ++ TRC_TX_AMPDU_START, ++} trc_ampdu_state_t; ++ ++struct sip_evt_trc_ampdu { ++ u8 state; ++ u8 tid; ++ u8 addr[ETH_ALEN]; ++} __packed; ++ ++struct sip_cmd_set_wmm_params { ++ u8 aci; ++ u8 aifs; ++ u8 ecw_min; ++ u8 ecw_max; ++ u16 txop_us; ++} __packed; ++ ++#define SIP_AMPDU_RX_START 0 ++#define SIP_AMPDU_RX_STOP 1 ++#define SIP_AMPDU_TX_OPERATIONAL 2 ++#define SIP_AMPDU_TX_STOP 3 ++struct sip_cmd_ampdu_action { ++ u8 action; ++ u8 index; ++ u8 tid; ++ u8 win_size; ++ u16 ssn; ++ u8 addr[ETH_ALEN]; ++} __packed; ++ ++#define SIP_TX_ST_OK 0 ++#define SIP_TX_ST_NOEB 1 ++#define SIP_TX_ST_ACKTO 2 ++#define SIP_TX_ST_ENCERR 3 ++ ++//NB: sip_tx_status must be 4 bytes aligned ++struct sip_tx_status { ++ u32 sip_seq; ++#ifdef HOST_RC ++ struct sip_rc_status rcstatus; ++#endif /* HOST_RC */ ++ u8 errno; /* success or failure code */ ++ u8 rate_index; ++ char ack_signal; ++ u8 pad; ++} __packed; ++ ++struct sip_evt_tx_report { ++ u32 pkts; ++ struct sip_tx_status status[0]; ++} __packed; ++ ++struct sip_evt_tx_mblk { ++ u32 mblk_map; ++} __packed; ++ ++struct sip_evt_scan_report { ++ u16 scan_id; ++ u16 aborted; ++} __packed; ++ ++struct sip_evt_roc { ++ u16 state; //start:1, end :0 ++ u16 is_ok; ++} __packed; ++ ++struct sip_evt_txidle { ++ u32 last_seq; ++} __packed; ++ ++struct sip_evt_noisefloor { ++ s16 noise_floor; ++ u16 pad; ++} __packed; ++/* ++ * for mblk direct memory access, no need for sip_hdr. tx: first 2k for contrl msg, ++ * rest of 14k for data. rx, same. ++ */ ++#ifdef TEST_MODE ++ ++struct sip_cmd_sleep { ++ u32 sleep_mode; ++ u32 sleep_tm_ms; ++ u32 wakeup_tm_ms; //zero: after receive bcn, then sleep, nozero: delay nozero ms to sleep ++ u32 sleep_times; //zero: always sleep, nozero: after nozero number sleep/wakeup, then end up sleep ++} __packed; ++ ++struct sip_cmd_wakeup { ++ u32 check_data; //0:copy to event ++} __packed; ++ ++struct sip_evt_wakeup { ++ u32 check_data; ++} __packed; ++ ++//general debug command ++struct sip_cmd_debug { ++ u32 cmd_type; ++ u32 para_num; ++ u32 para[10]; ++} __packed; ++ ++struct sip_evt_debug { ++ u16 len; ++ u32 results[12]; ++ u16 pad; ++} __packed; ++ ++struct sip_cmd_ate { ++ //u8 len; ++ u8 cmdstr[0]; ++} __packed; ++ ++ ++ ++#endif //ifdef TEST_MODE ++ ++#endif /* _SIP_COMMON_H_ */ +diff --git a/drivers/net/wireless/esp8089/slc_host_register.h b/drivers/net/wireless/esp8089/slc_host_register.h +new file mode 100644 +index 000000000000..2cdb2c856d15 +--- /dev/null ++++ b/drivers/net/wireless/esp8089/slc_host_register.h +@@ -0,0 +1,271 @@ ++//Generated at 2012-10-23 20:11:08 ++/* ++ * Copyright (c) 2011 Espressif System ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef SLC_HOST_REGISTER_H_INCLUDED ++#define SLC_HOST_REGISTER_H_INCLUDED ++ ++/* #define REG_SLC_HOST_BASE 0x00000000 */ ++/* skip the token1, since reading it will clean the credit */ ++#define REG_SLC_HOST_BASE 0x00000000 ++#define REG_SLC_BASE 0x00000000 ++ ++ ++#define SLC_HOST_PF (REG_SLC_HOST_BASE + 0x0) ++#define SLC_HOST_TOKEN_RDATA (REG_SLC_HOST_BASE + 0x4) ++#define SLC_HOST_RX_PF_EOF 0x0000000F ++#define SLC_HOST_RX_PF_EOF_S 28 ++#define SLC_HOST_TOKEN1 0x00000FFF ++#define SLC_HOST_TOKEN1_S 16 ++#define SLC_HOST_RX_PF_VALID (BIT(15)) ++#define SLC_HOST_TOKEN0 0x00000FFF ++#define SLC_HOST_TOKEN0_S 0 ++ ++#define SLC_HOST_TOKEN0_MASK SLC_HOST_TOKEN0 ++ ++#define SLC_HOST_INT_RAW (REG_SLC_HOST_BASE + 0x8) ++#define SLC_HOST_EXT_BIT3_INT_RAW (BIT(22)) ++#define SLC_HOST_EXT_BIT2_INT_RAW (BIT(21)) ++#define SLC_HOST_EXT_BIT1_INT_RAW (BIT(20)) ++#define SLC_HOST_RXFIFO_NOT_EMPTY_INT_RAW (BIT(19)) ++#define SLC_HOST_RX_PF_VALID_INT_RAW (BIT(18)) ++#define SLC_HOST_TX_OVF_INT_RAW (BIT(17)) ++#define SLC_HOST_RX_UDF_INT_RAW (BIT(16)) ++#define SLC_HOST_TX_START_INT_RAW (BIT(15)) ++#define SLC_HOST_RX_START_INT_RAW (BIT(14)) ++#define SLC_HOST_RX_EOF_INT_RAW (BIT(13)) ++#define SLC_HOST_RX_SOF_INT_RAW (BIT(12)) ++#define SLC_HOST_TOKEN1_0TO1_INT_RAW (BIT(11)) ++#define SLC_HOST_TOKEN0_0TO1_INT_RAW (BIT(10)) ++#define SLC_HOST_TOKEN1_1TO0_INT_RAW (BIT(9)) ++#define SLC_HOST_TOKEN0_1TO0_INT_RAW (BIT(8)) ++#define SLC_HOST_TOHOST_BIT7_INT_RAW (BIT(7)) ++#define SLC_HOST_TOHOST_BIT6_INT_RAW (BIT(6)) ++#define SLC_HOST_TOHOST_BIT5_INT_RAW (BIT(5)) ++#define SLC_HOST_TOHOST_BIT4_INT_RAW (BIT(4)) ++#define SLC_HOST_TOHOST_BIT3_INT_RAW (BIT(3)) ++#define SLC_HOST_TOHOST_BIT2_INT_RAW (BIT(2)) ++#define SLC_HOST_TOHOST_BIT1_INT_RAW (BIT(1)) ++#define SLC_HOST_TOHOST_BIT0_INT_RAW (BIT(0)) ++ ++#define SLC_HOST_STATE_W0 (REG_SLC_HOST_BASE + 0xC) ++#define SLC_HOST_STATE3 0x000000FF ++#define SLC_HOST_STATE3_S 24 ++#define SLC_HOST_STATE2 0x000000FF ++#define SLC_HOST_STATE2_S 16 ++#define SLC_HOST_STATE1 0x000000FF ++#define SLC_HOST_STATE1_S 8 ++#define SLC_HOST_STATE0 0x000000FF ++#define SLC_HOST_STATE0_S 0 ++ ++#define SLC_HOST_STATE_W1 (REG_SLC_HOST_BASE + 0x10) ++#define SLC_HOST_STATE7 0x000000FF ++#define SLC_HOST_STATE7_S 24 ++#define SLC_HOST_STATE6 0x000000FF ++#define SLC_HOST_STATE6_S 16 ++#define SLC_HOST_STATE5 0x000000FF ++#define SLC_HOST_STATE5_S 8 ++#define SLC_HOST_STATE4 0x000000FF ++#define SLC_HOST_STATE4_S 0 ++ ++#define SLC_HOST_CONF_W0 (REG_SLC_HOST_BASE + 0x14) ++#define SLC_HOST_CONF3 0x000000FF ++#define SLC_HOST_CONF3_S 24 ++#define SLC_HOST_CONF2 0x000000FF ++#define SLC_HOST_CONF2_S 16 ++#define SLC_HOST_CONF1 0x000000FF ++#define SLC_HOST_CONF1_S 8 ++#define SLC_HOST_CONF0 0x000000FF ++#define SLC_HOST_CONF0_S 0 ++ ++#define SLC_HOST_CONF_W1 (REG_SLC_HOST_BASE + 0x18) ++#define SLC_HOST_CONF7 0x000000FF ++#define SLC_HOST_CONF7_S 24 ++#define SLC_HOST_CONF6 0x000000FF ++#define SLC_HOST_CONF6_S 16 ++#define SLC_HOST_CONF5 0x000000FF ++#define SLC_HOST_CONF5_S 8 ++#define SLC_HOST_CONF4 0x000000FF ++#define SLC_HOST_CONF4_S 0 ++ ++#define SLC_HOST_INT_ST (REG_SLC_HOST_BASE + 0x1C) ++#define SLC_HOST_RX_ST (BIT(23)) ++#define SLC_HOST_EXT_BIT3_INT_ST (BIT(22)) ++#define SLC_HOST_EXT_BIT2_INT_ST (BIT(21)) ++#define SLC_HOST_EXT_BIT1_INT_ST (BIT(20)) ++#define SLC_HOST_RXFIFO_NOT_EMPTY_INT_ST (BIT(19)) ++#define SLC_HOST_RX_PF_VALID_INT_ST (BIT(18)) ++#define SLC_HOST_TX_OVF_INT_ST (BIT(17)) ++#define SLC_HOST_RX_UDF_INT_ST (BIT(16)) ++#define SLC_HOST_TX_START_INT_ST (BIT(15)) ++#define SLC_HOST_RX_START_INT_ST (BIT(14)) ++#define SLC_HOST_RX_EOF_INT_ST (BIT(13)) ++#define SLC_HOST_RX_SOF_INT_ST (BIT(12)) ++#define SLC_HOST_TOKEN1_0TO1_INT_ST (BIT(11)) ++#define SLC_HOST_TOKEN0_0TO1_INT_ST (BIT(10)) ++#define SLC_HOST_TOKEN1_1TO0_INT_ST (BIT(9)) ++#define SLC_HOST_TOKEN0_1TO0_INT_ST (BIT(8)) ++#define SLC_HOST_TOHOST_BIT7_INT_ST (BIT(7)) ++#define SLC_HOST_TOHOST_BIT6_INT_ST (BIT(6)) ++#define SLC_HOST_TOHOST_BIT5_INT_ST (BIT(5)) ++#define SLC_HOST_TOHOST_BIT4_INT_ST (BIT(4)) ++#define SLC_HOST_TOHOST_BIT3_INT_ST (BIT(3)) ++#define SLC_HOST_TOHOST_BIT2_INT_ST (BIT(2)) ++#define SLC_HOST_TOHOST_BIT1_INT_ST (BIT(1)) ++#define SLC_HOST_TOHOST_BIT0_INT_ST (BIT(0)) ++ ++#define SLC_HOST_CONF_W2 (REG_SLC_HOST_BASE + 0x20) ++#define SLC_HOST_CONF11 0x000000FF ++#define SLC_HOST_CONF11_S 24 ++#define SLC_HOST_CONF10 0x000000FF ++#define SLC_HOST_CONF10_S 16 ++#define SLC_HOST_CONF9 0x000000FF ++#define SLC_HOST_CONF9_S 8 ++#define SLC_HOST_CONF8 0x000000FF ++#define SLC_HOST_CONF8_S 0 ++ ++#define SLC_HOST_CONF_W3 (REG_SLC_HOST_BASE + 0x24) ++#define SLC_HOST_CONF15 0x000000FF ++#define SLC_HOST_CONF15_S 24 ++#define SLC_HOST_CONF14 0x000000FF ++#define SLC_HOST_CONF14_S 16 ++#define SLC_HOST_CONF13 0x000000FF ++#define SLC_HOST_CONF13_S 8 ++#define SLC_HOST_CONF12 0x000000FF ++#define SLC_HOST_CONF12_S 0 ++ ++#define SLC_HOST_GEN_TXDONE_INT BIT(16) ++#define SLC_HOST_GEN_RXDONE_INT BIT(17) ++ ++#define SLC_HOST_CONF_W4 (REG_SLC_HOST_BASE + 0x28) ++#define SLC_HOST_CONF19 0x000000FF ++#define SLC_HOST_CONF19_S 24 ++#define SLC_HOST_CONF18 0x000000FF ++#define SLC_HOST_CONF18_S 16 ++#define SLC_HOST_CONF17 0x000000FF ++#define SLC_HOST_CONF17_S 8 ++#define SLC_HOST_CONF16 0x000000FF ++#define SLC_HOST_CONF16_S 0 ++ ++#define SLC_HOST_TOKEN_WDATA (REG_SLC_HOST_BASE + 0x2C) ++#define SLC_HOST_TOKEN1_WD 0x00000FFF ++#define SLC_HOST_TOKEN1_WD_S 16 ++#define SLC_HOST_TOKEN0_WD 0x00000FFF ++#define SLC_HOST_TOKEN0_WD_S 0 ++ ++#define SLC_HOST_INT_CLR (REG_SLC_HOST_BASE + 0x30) ++#define SLC_HOST_TOKEN1_WR (BIT(31)) ++#define SLC_HOST_TOKEN0_WR (BIT(30)) ++#define SLC_HOST_TOKEN1_DEC (BIT(29)) ++#define SLC_HOST_TOKEN0_DEC (BIT(28)) ++#define SLC_HOST_EXT_BIT3_INT_CLR (BIT(22)) ++#define SLC_HOST_EXT_BIT2_INT_CLR (BIT(21)) ++#define SLC_HOST_EXT_BIT1_INT_CLR (BIT(20)) ++#define SLC_HOST_EXT_BIT0_INT_CLR (BIT(19)) ++#define SLC_HOST_RX_PF_VALID_INT_CLR (BIT(18)) ++#define SLC_HOST_TX_OVF_INT_CLR (BIT(17)) ++#define SLC_HOST_RX_UDF_INT_CLR (BIT(16)) ++#define SLC_HOST_TX_START_INT_CLR (BIT(15)) ++#define SLC_HOST_RX_START_INT_CLR (BIT(14)) ++#define SLC_HOST_RX_EOF_INT_CLR (BIT(13)) ++#define SLC_HOST_RX_SOF_INT_CLR (BIT(12)) ++#define SLC_HOST_TOKEN1_0TO1_INT_CLR (BIT(11)) ++#define SLC_HOST_TOKEN0_0TO1_INT_CLR (BIT(10)) ++#define SLC_HOST_TOKEN1_1TO0_INT_CLR (BIT(9)) ++#define SLC_HOST_TOKEN0_1TO0_INT_CLR (BIT(8)) ++#define SLC_HOST_TOHOST_BIT7_INT_CLR (BIT(7)) ++#define SLC_HOST_TOHOST_BIT6_INT_CLR (BIT(6)) ++#define SLC_HOST_TOHOST_BIT5_INT_CLR (BIT(5)) ++#define SLC_HOST_TOHOST_BIT4_INT_CLR (BIT(4)) ++#define SLC_HOST_TOHOST_BIT3_INT_CLR (BIT(3)) ++#define SLC_HOST_TOHOST_BIT2_INT_CLR (BIT(2)) ++#define SLC_HOST_TOHOST_BIT1_INT_CLR (BIT(1)) ++#define SLC_HOST_TOHOST_BIT0_INT_CLR (BIT(0)) ++ ++#define SLC_HOST_INT_ENA (REG_SLC_HOST_BASE + 0x34) ++#define SLC_HOST_EXT_BIT3_INT_ENA (BIT(22)) ++#define SLC_HOST_EXT_BIT2_INT_ENA (BIT(21)) ++#define SLC_HOST_EXT_BIT1_INT_ENA (BIT(20)) ++#define SLC_HOST_EXT_BIT0_INT_ENA (BIT(19)) ++#define SLC_HOST_RX_PF_VALID_INT_ENA (BIT(18)) ++#define SLC_HOST_TX_OVF_INT_ENA (BIT(17)) ++#define SLC_HOST_RX_UDF_INT_ENA (BIT(16)) ++#define SLC_HOST_TX_START_INT_ENA (BIT(15)) ++#define SLC_HOST_RX_START_INT_ENA (BIT(14)) ++#define SLC_HOST_RX_EOF_INT_ENA (BIT(13)) ++#define SLC_HOST_RX_SOF_INT_ENA (BIT(12)) ++#define SLC_HOST_TOKEN1_0TO1_INT_ENA (BIT(11)) ++#define SLC_HOST_TOKEN0_0TO1_INT_ENA (BIT(10)) ++#define SLC_HOST_TOKEN1_1TO0_INT_ENA (BIT(9)) ++#define SLC_HOST_TOKEN0_1TO0_INT_ENA (BIT(8)) ++#define SLC_HOST_TOHOST_BIT7_INT_ENA (BIT(7)) ++#define SLC_HOST_TOHOST_BIT6_INT_ENA (BIT(6)) ++#define SLC_HOST_TOHOST_BIT5_INT_ENA (BIT(5)) ++#define SLC_HOST_TOHOST_BIT4_INT_ENA (BIT(4)) ++#define SLC_HOST_TOHOST_BIT3_INT_ENA (BIT(3)) ++#define SLC_HOST_TOHOST_BIT2_INT_ENA (BIT(2)) ++#define SLC_HOST_TOHOST_BIT1_INT_ENA (BIT(1)) ++#define SLC_HOST_TOHOST_BIT0_INT_ENA (BIT(0)) ++ ++#define SLC_HOST_CONF_W5 (REG_SLC_HOST_BASE + 0x3C) ++#define SLC_HOST_CONF23 0x000000FF ++#define SLC_HOST_CONF23_S 24 ++#define SLC_HOST_CONF22 0x000000FF ++#define SLC_HOST_CONF22_S 16 ++#define SLC_HOST_CONF21 0x000000FF ++#define SLC_HOST_CONF21_S 8 ++#define SLC_HOST_CONF20 0x000000FF ++#define SLC_HOST_CONF20_S 0 ++ ++#define SLC_HOST_WIN_CMD (REG_SLC_HOST_BASE + 0x40) ++ ++ ++#define SLC_HOST_DATE (REG_SLC_HOST_BASE + 0x78) ++#define SLC_HOST_ID (REG_SLC_HOST_BASE + 0x7C) ++ ++#define SLC_ADDR_WINDOW_CLEAR_MASK (~(0xf<<12)) ++#define SLC_FROM_HOST_ADDR_WINDOW (0x1<<12) ++#define SLC_TO_HOST_ADDR_WINDOW (0x3<<12) ++ ++#define SLC_SET_FROM_HOST_ADDR_WINDOW(v) do { \ ++ (v) &= 0xffff; \ ++ (v) &= SLC_ADDR_WINDOW_CLEAR_MASK; \ ++ (v) |= SLC_FROM_HOST_ADDR_WINDOW; \ ++} while (0); ++ ++#define SLC_SET_TO_HOST_ADDR_WINDOW(v) do { \ ++ (v) &= 0xffff; \ ++ (v) &= SLC_ADDR_WINDOW_CLEAR_MASK; \ ++ (v) |= SLC_TO_HOST_ADDR_WINDOW; \ ++} while (0); ++ ++#define SLC_INT_ENA (REG_SLC_BASE + 0xC) ++#define SLC_RX_EOF_INT_ENA BIT(17) ++#define SLC_FRHOST_BIT2_INT_ENA BIT(2) ++ ++#define SLC_RX_LINK (REG_SLC_BASE + 0x24) ++#define SLC_RXLINK_START BIT(29) ++ ++#define SLC_BRIDGE_CONF (REG_SLC_BASE + 0x44) ++#define SLC_TX_PUSH_IDLE_NUM 0xFFFF ++#define SLC_TX_PUSH_IDLE_NUM_S 16 ++#define SLC_HDA_MAP_128K BIT(13) ++#define SLC_TX_DUMMY_MODE BIT(12) ++#define SLC_FIFO_MAP_ENA 0x0000000F ++#define SLC_FIFO_MAP_ENA_S 8 ++#define SLC_TXEOF_ENA 0x0000003F ++#define SLC_TXEOF_ENA_S ++ ++ ++#endif // SLC_HOST_REGISTER_H_INCLUDED +-- +2.34.1 diff --git a/projects/ArchR/devices/RK3326/patches/linux/020-elida-refresh-rates.patch b/projects/ArchR/devices/RK3326/patches/linux/020-elida-refresh-rates.patch new file mode 100644 index 0000000000..b96e429792 --- /dev/null +++ b/projects/ArchR/devices/RK3326/patches/linux/020-elida-refresh-rates.patch @@ -0,0 +1,79 @@ +diff --git a/drivers/gpu/drm/panel/panel-elida-kd35t133.c b/drivers/gpu/drm/panel/panel-elida-kd35t133.c +index b904d5437444..abbeb18eb6b4 100644 +--- a/drivers/gpu/drm/panel/panel-elida-kd35t133.c ++++ b/drivers/gpu/drm/panel/panel-elida-kd35t133.c +@@ -148,7 +148,8 @@ static int kd35t133_prepare(struct drm_panel *panel) + return dsi_ctx.accum_err; + } + +-static const struct drm_display_mode default_mode = { ++/* drm_display_mode template without clock as it is variable */ ++static const struct drm_display_mode mode_template = { + .hdisplay = 320, + .hsync_start = 320 + 130, + .hsync_end = 320 + 130 + 4, +@@ -157,33 +158,49 @@ static const struct drm_display_mode default_mode = { + .vsync_start = 480 + 2, + .vsync_end = 480 + 2 + 1, + .vtotal = 480 + 2 + 1 + 2, +- .clock = 17000, + .width_mm = 42, + .height_mm = 82, + }; + ++static const int pixel_clocks[] = { ++ 14118, /* 49.84 Hz PAL everything */ ++ 15545, /* 54.88 Hz Arcade: Midway, Toaplan, R-Type */ ++ 16300, /* 57.50 Hz Arcade: Toaplan, more? */ ++ 16900, /* 59.7 Hz GB/GBC/GBA */ ++ 17000, /* 60 Hz everything */ ++ 21375, /* 75.47 Hz Wonderswan(Color) */ ++}; ++ + static int kd35t133_get_modes(struct drm_panel *panel, + struct drm_connector *connector) + { + struct kd35t133 *ctx = panel_to_kd35t133(panel); ++ struct drm_display_mode mode_tmp; + struct drm_display_mode *mode; + +- mode = drm_mode_duplicate(connector->dev, &default_mode); +- if (!mode) { +- dev_err(ctx->dev, "Failed to add mode %ux%u@%u\n", +- default_mode.hdisplay, default_mode.vdisplay, +- drm_mode_vrefresh(&default_mode)); +- return -ENOMEM; ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(pixel_clocks); i++) { ++ mode_tmp = mode_template; ++ mode_tmp.clock = pixel_clocks[i]; ++ mode = drm_mode_duplicate(connector->dev, &mode_tmp); ++ if (!mode) { ++ dev_err(ctx->dev, "Failed to add mode %u\n", ++ drm_mode_vrefresh(mode)); ++ return -ENOMEM; ++ } ++ drm_mode_set_name(mode); ++ ++ mode->type = DRM_MODE_TYPE_DRIVER; ++ if (i == 4) ++ mode->type |= DRM_MODE_TYPE_PREFERRED; ++ ++ drm_mode_probed_add(connector, mode); ++ connector->display_info.width_mm = mode->width_mm; ++ connector->display_info.height_mm = mode->height_mm; + } + +- drm_mode_set_name(mode); +- +- mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; +- connector->display_info.width_mm = mode->width_mm; +- connector->display_info.height_mm = mode->height_mm; +- drm_mode_probed_add(connector, mode); +- +- return 1; ++ return ARRAY_SIZE(pixel_clocks); + } + + static enum drm_panel_orientation kd35t133_get_orientation(struct drm_panel *panel) diff --git a/projects/ArchR/devices/RK3326/patches/linux/022-usb-role-switch.patch b/projects/ArchR/devices/RK3326/patches/linux/022-usb-role-switch.patch new file mode 100644 index 0000000000..2231cc94ed --- /dev/null +++ b/projects/ArchR/devices/RK3326/patches/linux/022-usb-role-switch.patch @@ -0,0 +1,11 @@ +--- linux-6.11.9/arch/arm64/boot/dts/rockchip/px30.dtsi.orig 2024-11-29 21:08:01.000962112 +0000 ++++ linux-6.11.9/arch/arm64/boot/dts/rockchip/px30.dtsi 2024-11-29 20:20:01.012069647 +0000 +@@ -950,6 +950,8 @@ + clocks = <&cru HCLK_OTG>; + clock-names = "otg"; + dr_mode = "otg"; ++ usb-role-switch; ++ role-switch-default-mode = "host"; + g-np-tx-fifo-size = <16>; + g-rx-fifo-size = <280>; + g-tx-fifo-size = <256 128 128 64 32 16>; diff --git a/projects/ArchR/devices/RK3326/patches/mali-bifrost/001-single-regulator.patch b/projects/ArchR/devices/RK3326/patches/mali-bifrost/001-single-regulator.patch new file mode 100644 index 0000000000..0ebd0b68a5 --- /dev/null +++ b/projects/ArchR/devices/RK3326/patches/mali-bifrost/001-single-regulator.patch @@ -0,0 +1,31 @@ +--- a/product/kernel/drivers/gpu/arm/midgard/mali_kbase_defs.h 2024-02-19 17:24:21.000000000 +0300 ++++ b/product/kernel/drivers/gpu/arm/midgard/mali_kbase_defs.h 2024-03-18 23:51:35.201950500 +0300 +@@ -141,7 +141,7 @@ + * This is dependent on support for of_property_read_u64_array() in the + * kernel. + */ +-#define BASE_MAX_NR_CLOCKS_REGULATORS (2) ++#define BASE_MAX_NR_CLOCKS_REGULATORS (1) + + /* Forward declarations */ + struct kbase_context; +--- a/product/kernel/drivers/gpu/arm/midgard/mali_kbase_core_linux.c 2024-03-19 00:26:38.775395807 +0300 ++++ b/product/kernel/drivers/gpu/arm/midgard/mali_kbase_core_linux.c 2024-03-19 00:23:39.644058337 +0300 +@@ -4725,7 +4725,7 @@ + int err = 0; + unsigned int i; + #if defined(CONFIG_REGULATOR) +- static const char *const regulator_names[] = { "mali", "shadercores" }; ++ static const char *const regulator_names[] = { "mali", NULL }; + BUILD_BUG_ON(ARRAY_SIZE(regulator_names) < BASE_MAX_NR_CLOCKS_REGULATORS); + #endif /* CONFIG_REGULATOR */ + +@@ -4771,7 +4771,7 @@ + * operating with a partial initialization of clocks. + */ + for (i = 0; i < BASE_MAX_NR_CLOCKS_REGULATORS; i++) { +- kbdev->clocks[i] = of_clk_get(kbdev->dev->of_node, (int)i); ++ kbdev->clocks[i] = of_clk_get_by_name(kbdev->dev->of_node, "bus"); + if (IS_ERR(kbdev->clocks[i])) { + err = PTR_ERR(kbdev->clocks[i]); + kbdev->clocks[i] = NULL; diff --git a/projects/ArchR/devices/RK3326/patches/mali-bifrost/002-lowercase-interrupts-first.patch b/projects/ArchR/devices/RK3326/patches/mali-bifrost/002-lowercase-interrupts-first.patch new file mode 100644 index 0000000000..1360d86fcb --- /dev/null +++ b/projects/ArchR/devices/RK3326/patches/mali-bifrost/002-lowercase-interrupts-first.patch @@ -0,0 +1,30 @@ +diff -ur build.ArchR-RK3566.aarch64/mali-bifrost-r48p0-01eac0.orig/product/kernel/drivers/gpu/arm/midgard/mali_kbase_core_linux.c build.ArchR-RK3566.aarch64/mali-bifrost-r48p0-01eac0/product/kernel/drivers/gpu/arm/midgard/mali_kbase_core_linux.c +--- mali-bifrost-r48p0-01eac0.orig/product/kernel/drivers/gpu/arm/midgard/mali_kbase_core_linux.c 2024-04-10 00:29:25.679588022 +0300 ++++ mali-bifrost-r48p0-01eac0/product/kernel/drivers/gpu/arm/midgard/mali_kbase_core_linux.c 2024-04-10 00:33:32.693922486 +0300 +@@ -548,9 +548,9 @@ + static int get_irqs(struct kbase_device *kbdev, struct platform_device *pdev) + { + int i; +- static const char *const irq_names_caps[] = { "JOB", "MMU", "GPU" }; ++ static const char *const irq_names[] = { "job", "mmu", "gpu" }; + +- for (i = 0; i < ARRAY_SIZE(irq_names_caps); i++) { ++ for (i = 0; i < ARRAY_SIZE(irq_names); i++) { + struct irq_data *irqdata; + int irq; + +@@ -560,11 +560,11 @@ + * first then try using Lower case names. If both attempts fail then + * we assume there is no IRQ resource specified for the GPU. + */ +- irq = platform_get_irq_byname(pdev, irq_names_caps[i]); ++ irq = platform_get_irq_byname(pdev, irq_names[i]); + if (irq < 0) { +- static const char *const irq_names[] = { "job", "mmu", "gpu" }; ++ static const char *const irq_names_caps[] = { "JOB", "MMU", "GPU" }; + +- irq = platform_get_irq_byname(pdev, irq_names[i]); ++ irq = platform_get_irq_byname(pdev, irq_names_caps[i]); + } + + if (irq < 0) diff --git a/projects/ArchR/devices/RK3326/patches/mali-bifrost/003-midgard-refactor-power-init-and-fixed-unbalanced-run.patch b/projects/ArchR/devices/RK3326/patches/mali-bifrost/003-midgard-refactor-power-init-and-fixed-unbalanced-run.patch new file mode 100644 index 0000000000..125dc12649 --- /dev/null +++ b/projects/ArchR/devices/RK3326/patches/mali-bifrost/003-midgard-refactor-power-init-and-fixed-unbalanced-run.patch @@ -0,0 +1,199 @@ +From 5b1c50b3e181a57f5ce0a7d8c50f0f0823ac1609 Mon Sep 17 00:00:00 2001 +From: Paul Reioux +Date: Wed, 12 Jun 2024 07:36:52 -0700 +Subject: [PATCH] midgard: refactor power init and fixed unbalanced runtime PM + calls + +Signed-off-by: Paul Reioux +--- + .../gpu/arm/midgard/mali_kbase_core_linux.c | 124 ++++++++++++------ + .../platform/meson/mali_kbase_runtime_pm.c | 11 +- + 2 files changed, 88 insertions(+), 47 deletions(-) + +diff --git a/product/kernel/drivers/gpu/arm/midgard/mali_kbase_core_linux.c b/product/kernel/drivers/gpu/arm/midgard/mali_kbase_core_linux.c +index 0ad8a70..8db0c13 100644 +--- a/product/kernel/drivers/gpu/arm/midgard/mali_kbase_core_linux.c ++++ b/product/kernel/drivers/gpu/arm/midgard/mali_kbase_core_linux.c +@@ -4507,31 +4507,44 @@ int power_control_init(struct kbase_device *kbdev) + + pdev = to_platform_device(kbdev->dev); + +-#if defined(CONFIG_REGULATOR) +- /* Since the error code EPROBE_DEFER causes the entire probing +- * procedure to be restarted from scratch at a later time, +- * all regulators will be released before returning. +- * +- * Any other error is ignored and the driver will continue +- * operating with a partial initialization of regulators. +- */ +- for (i = 0; i < BASE_MAX_NR_CLOCKS_REGULATORS; i++) { +- kbdev->regulators[i] = regulator_get_optional(kbdev->dev, regulator_names[i]); +- if (IS_ERR(kbdev->regulators[i])) { +- err = PTR_ERR(kbdev->regulators[i]); +- kbdev->regulators[i] = NULL; +- break; +- } +- } +- if (err == -EPROBE_DEFER) { +- while (i > 0) +- regulator_put(kbdev->regulators[--i]); +- return err; ++// #if defined(CONFIG_REGULATOR) ++// /* Since the error code EPROBE_DEFER causes the entire probing ++// * procedure to be restarted from scratch at a later time, ++// * all regulators will be released before returning. ++// * ++// * Any other error is ignored and the driver will continue ++// * operating with a partial initialization of regulators. ++// */ ++// for (i = 0; i < BASE_MAX_NR_CLOCKS_REGULATORS; i++) { ++// kbdev->regulators[i] = regulator_get_optional(kbdev->dev, regulator_names[i]); ++// if (IS_ERR(kbdev->regulators[i])) { ++// err = PTR_ERR(kbdev->regulators[i]); ++// kbdev->regulators[i] = NULL; ++// break; ++// } ++// } ++// if (err == -EPROBE_DEFER) { ++// while (i > 0) ++// regulator_put(kbdev->regulators[--i]); ++// return err; ++// } ++ kbdev->regulators[0] = devm_regulator_get_optional(kbdev->dev, regulator_names[0]); ++ ++ if (IS_ERR(kbdev->regulators[0])) { ++ err = PTR_ERR(kbdev->regulators[0]); ++ kbdev->regulators[0] = NULL; ++ kbdev->nr_regulators = 0; ++ } else { ++ kbdev->nr_regulators = 1; ++ ++ err = regulator_enable(kbdev->regulators[0]); ++ if (err) ++ dev_dbg(&pdev->dev, "regulator_enable failed\n"); + } + +- kbdev->nr_regulators = i; + dev_dbg(&pdev->dev, "Regulators probed: %u\n", kbdev->nr_regulators); +-#endif ++ ++// #endif + + /* Having more clocks than regulators is acceptable, while the + * opposite shall not happen. +@@ -4543,30 +4556,55 @@ int power_control_init(struct kbase_device *kbdev) + * Any other error is ignored and the driver will continue + * operating with a partial initialization of clocks. + */ +- for (i = 0; i < BASE_MAX_NR_CLOCKS_REGULATORS; i++) { +- kbdev->clocks[i] = of_clk_get_by_name(kbdev->dev->of_node, "bus"); +- if (IS_ERR(kbdev->clocks[i])) { +- err = PTR_ERR(kbdev->clocks[i]); +- kbdev->clocks[i] = NULL; +- break; +- } + +- err = clk_prepare_enable(kbdev->clocks[i]); +- if (err) { +- dev_err(kbdev->dev, "Failed to prepare and enable clock (%d)\n", err); +- clk_put(kbdev->clocks[i]); +- break; +- } +- } +- if (err == -EPROBE_DEFER) { +- while (i > 0) { +- clk_disable_unprepare(kbdev->clocks[--i]); +- clk_put(kbdev->clocks[i]); +- } +- goto clocks_probe_defer; ++ kbdev->clocks[0] = devm_clk_get_optional(kbdev->dev, NULL); ++ if (!IS_ERR(kbdev->clocks[0])) ++ dev_dbg(kbdev->dev, "clk_get: %s\n", __clk_get_name(kbdev->clocks[0])); ++ else ++ dev_err(kbdev->dev, "clk_get: is NULL"); ++ ++ /* if platform device is enabled, disable it now */ ++ //if (__clk_is_enabled(kbdev->clocks[0])) { ++ // clk_disable(kbdev->clocks[0]); ++ //} ++ /* delete from clk tree */ ++ //clk_unprepare(kbdev->clocks[0]); ++ //clk_put(kbdev->clocks[0]); ++ ++ /* now grab the gpu clock node from device tree definition */ ++ //kbdev->clocks[0] = of_clk_get_by_name(kbdev->dev->of_node, "gpu"); ++ ++ /* we are kinda commited here.. if this fails, the system will lock up */ ++ err = clk_prepare_enable(kbdev->clocks[0]); ++ if (err) { ++ dev_err(kbdev->dev, "Failed to prepare and enable clock (%d)\n", err); ++ clk_put(kbdev->clocks[0]); + } + +- kbdev->nr_clocks = i; ++ // for (i = 0; i < BASE_MAX_NR_CLOCKS_REGULATORS; i++) { ++ // kbdev->clocks[i] = of_clk_get(kbdev->dev->of_node, (int)i); ++ // if (IS_ERR(kbdev->clocks[i])) { ++ // err = PTR_ERR(kbdev->clocks[i]); ++ // kbdev->clocks[i] = NULL; ++ // break; ++ // } ++ ++ // err = clk_prepare_enable(kbdev->clocks[i]); ++ // if (err) { ++ // dev_err(kbdev->dev, "Failed to prepare and enable clock (%d)\n", err); ++ // clk_put(kbdev->clocks[i]); ++ // break; ++ // } ++ // } ++ // if (err == -EPROBE_DEFER) { ++ // while (i > 0) { ++ // clk_disable_unprepare(kbdev->clocks[--i]); ++ // clk_put(kbdev->clocks[i]); ++ // } ++ // goto clocks_probe_defer; ++ // } ++ ++ kbdev->nr_clocks = 1; + dev_dbg(&pdev->dev, "Clocks probed: %u\n", kbdev->nr_clocks); + + /* Any error in parsing the OPP table from the device file +diff --git a/product/kernel/drivers/gpu/arm/midgard/platform/meson/mali_kbase_runtime_pm.c b/product/kernel/drivers/gpu/arm/midgard/platform/meson/mali_kbase_runtime_pm.c +index bd3b4b5..33a24bb 100644 +--- a/product/kernel/drivers/gpu/arm/midgard/platform/meson/mali_kbase_runtime_pm.c ++++ b/product/kernel/drivers/gpu/arm/midgard/platform/meson/mali_kbase_runtime_pm.c +@@ -113,7 +113,8 @@ static void enable_gpu_power_control(struct kbase_device *kbdev) + if (WARN_ON(kbdev->clocks[i] == NULL)) + ; + else if (!__clk_is_enabled(kbdev->clocks[i])) +- WARN_ON(clk_prepare_enable(kbdev->clocks[i])); ++ //WARN_ON(clk_prepare_enable(kbdev->clocks[i])); ++ ; + } + } + +@@ -125,8 +126,9 @@ static void disable_gpu_power_control(struct kbase_device *kbdev) + if (WARN_ON(kbdev->clocks[i] == NULL)) + ; + else if (__clk_is_enabled(kbdev->clocks[i])) { +- clk_disable_unprepare(kbdev->clocks[i]); +- WARN_ON(__clk_is_enabled(kbdev->clocks[i])); ++ //clk_disable_unprepare(kbdev->clocks[i]); ++ //WARN_ON(__clk_is_enabled(kbdev->clocks[i])); ++ ; + } + } + +@@ -135,7 +137,8 @@ static void disable_gpu_power_control(struct kbase_device *kbdev) + if (WARN_ON(kbdev->regulators[i] == NULL)) + ; + else if (regulator_is_enabled(kbdev->regulators[i])) +- WARN_ON(regulator_disable(kbdev->regulators[i])); ++ //WARN_ON(regulator_disable(kbdev->regulators[i])); ++ ; + } + #endif + } +-- +2.34.1 + diff --git a/projects/ArchR/options b/projects/ArchR/options new file mode 100644 index 0000000000..63fa8cefd5 --- /dev/null +++ b/projects/ArchR/options @@ -0,0 +1,44 @@ +################################################################################ +# setup build defaults +################################################################################ + + # Project FLAGS + PROJECT_CFLAGS="" + + # Root filesystem type (ext4 for ArchR, squashfs for legacy) + ROOTFS_TYPE="ext4" + + # SquashFS compression method (gzip / lzo / xz) - only used when ROOTFS_TYPE=squashfs + SQUASHFS_COMPRESSION="lzo" + +################################################################################ +# setup project defaults +################################################################################ + + # OpenGL(X) implementation to use (no / mesa) + OPENGL="mesa" + + # OpenGL-ES implementation to use (no / mesa) + OPENGLES="mesa" + + # Displayserver to use (no / wl) + DISPLAYSERVER="no" + + # Windowmanager to use (none / weston) + WINDOWMANAGER="none" + + # Xorg Graphic drivers to use (all / i915,i965,r200,r300,r600,nvidia) + # Space separated list is supported, + # e.g. GRAPHIC_DRIVERS="i915 i965 r300 r600 radeonsi nvidia" + GRAPHIC_DRIVERS="" + + # Additional Firmware to use ( ) + # Space separated list is supported, + # e.g. FIRMWARE="" + FIRMWARE="" + + # Additional packages to install + ADDITIONAL_PACKAGES="" + + # Satisfy legacy build dependencies + SWAP_SUPPORT="yes" diff --git a/projects/ArchR/packages/apps/archr-hotkey/package.mk b/projects/ArchR/packages/apps/archr-hotkey/package.mk new file mode 100644 index 0000000000..661919e50b --- /dev/null +++ b/projects/ArchR/packages/apps/archr-hotkey/package.mk @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2021-present Shanti Gilbert (https://github.com/shantigilbert) + +PKG_NAME="archr-hotkey" +PKG_VERSION="cc3a863199a71a350db05e9d0d0e646a8411332c" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/archr-linux/archr-hotkey" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain libevdev SDL2 control-gen" +PKG_TOOLCHAIN="make" +GET_HANDLER_SUPPORT="git" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp ${PKG_BUILD}/gptokeyb ${INSTALL}/usr/bin + + mkdir -p ${INSTALL}/usr/lib + cp ${PKG_BUILD}/inputfilter.so ${INSTALL}/usr/lib + + mkdir -p ${INSTALL}/usr/config/gptokeyb/ + cp ${PKG_BUILD}/configs/default.gptk ${INSTALL}/usr/config/gptokeyb/ +} diff --git a/projects/ArchR/packages/apps/archr-screenshot/package.mk b/projects/ArchR/packages/apps/archr-screenshot/package.mk new file mode 100644 index 0000000000..416d418242 --- /dev/null +++ b/projects/ArchR/packages/apps/archr-screenshot/package.mk @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="archr-screenshot" +PKG_VERSION="1.0" +PKG_LICENSE="GPLv2" +PKG_SITE="" +PKG_URL="" +PKG_DEPENDS_TARGET="toolchain grim jq sway" +PKG_LONGDESC="ArchR screenshot utility" +PKG_TOOLCHAIN="manual" + +make_target() { + : +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp -rf ${PKG_DIR}/sources/archr-screenshot ${INSTALL}/usr/bin + chmod +x ${INSTALL}/usr/bin/archr-screenshot +} diff --git a/projects/ArchR/packages/apps/archr-screenshot/sources/archr-screenshot b/projects/ArchR/packages/apps/archr-screenshot/sources/archr-screenshot new file mode 100644 index 0000000000..8186047981 --- /dev/null +++ b/projects/ArchR/packages/apps/archr-screenshot/sources/archr-screenshot @@ -0,0 +1,48 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025-present ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile + +# Enable / Disable archr screenshot +ArchR_SCREENSHOT=$(get_setting "archr.screenshot.enabled") +if [ ! -n "${ArchR_SCREENSHOT}" ]; then + set_setting "archr.screenshot.enabled" "0" +fi + +if [ "${ArchR_SCREENSHOT}" == "1" ]; then + # Disable archr-screenshot while retroarch is running + if pgrep -f "retroarch" > /dev/null; then + echo "RetroArch is running, skipping screenshot." + # 'failure' (screenshot not taken) exit code + exit 1 + fi + + # Folder to save screenshots + SAVE_DIR="/storage/roms/screenshots" + + # Create the folder if it doesn't exist + mkdir -p "$SAVE_DIR" + + # Generate a timestamped filename + FILENAME="$(date +'%Y-%m-%d-%H%M%S').png" + FULL_PATH="${SAVE_DIR}/${FILENAME}" + + # Get focused window geometry + GEOMETRY=$(swaymsg -t get_tree | jq -r ' + .. + | select(.type? == "con" and .focused == true) + | "\(.rect.x),\(.rect.y) \(.rect.width)x\(.rect.height)"' + ) + + # Take screenshot of the focused window + grim -g "$GEOMETRY" "$FULL_PATH" + + # 'success' (screenshot taken) exit code + exit 0 +else + echo "archr-screenshot is not enabled, skipping screenshot." + # 'failure' (screenshot not taken) exit code + exit 1 +fi diff --git a/projects/ArchR/packages/apps/archr-touchscreen-keyboard/package.mk b/projects/ArchR/packages/apps/archr-touchscreen-keyboard/package.mk new file mode 100644 index 0000000000..4e75e73fa4 --- /dev/null +++ b/projects/ArchR/packages/apps/archr-touchscreen-keyboard/package.mk @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2025-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="archr-touchscreen-keyboard" +PKG_VERSION="v0.17" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/jjsullivan5196/wvkbd" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_LONGDESC="wvkbd - On-screen keyboard for wlroots that sucks less" +PKG_DEPENDS_TARGET="toolchain wayland sway pango libxkbcommon cairo" +PKG_TOOLCHAIN="make" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp -rf ${PKG_BUILD}/wvkbd-mobintl ${INSTALL}/usr/bin + cp -rf ${PKG_DIR}/sources/* ${INSTALL}/usr/bin + chmod 0755 ${INSTALL}/usr/bin/* +} + +post_install() { + enable_service touchkeyboard.service +} diff --git a/projects/ArchR/packages/apps/archr-touchscreen-keyboard/patches/000-remove-scdoc-dependency.patch b/projects/ArchR/packages/apps/archr-touchscreen-keyboard/patches/000-remove-scdoc-dependency.patch new file mode 100644 index 0000000000..d69c2fd02e --- /dev/null +++ b/projects/ArchR/packages/apps/archr-touchscreen-keyboard/patches/000-remove-scdoc-dependency.patch @@ -0,0 +1,46 @@ +diff --git a/Makefile b/Makefile +index db17991..bbdc67e 100644 +--- a/Makefile ++++ b/Makefile +@@ -3,7 +3,6 @@ include config.mk + NAME=wvkbd + BIN=${NAME}-${LAYOUT} + SRC=. +-MAN1 = ${NAME}.1 + + PKGS = wayland-client xkbcommon pangocairo + +@@ -21,12 +20,9 @@ HDRS = $(WAYLAND_HEADERS:.xml=-client-protocol.h) + WAYLAND_SRC = $(HDRS:.h=.c) + SOURCES = $(WVKBD_SOURCES) $(WAYLAND_SRC) + +-SCDOC=scdoc +-DOCS = wvkbd.1 +- + OBJECTS = $(SOURCES:.c=.o) + +-all: ${BIN} ${DOCS} ++all: ${BIN} + + config.h: + cp config.def.h config.h +@@ -43,18 +39,12 @@ wvkbd-${LAYOUT}: config.h $(OBJECTS) layout.${LAYOUT}.h + $(CC) -o wvkbd-${LAYOUT} $(OBJECTS) $(LDFLAGS) + + clean: +- rm -f $(OBJECTS) $(HDRS) $(WAYLAND_SRC) ${BIN} ${DOCS} ++ rm -f $(OBJECTS) $(HDRS) $(WAYLAND_SRC) ${BIN} + + format: + clang-format -i $(WVKBD_SOURCES) $(WVKBD_HEADERS) + +-%: %.scd +- $(SCDOC) < $< > $@ +- + install: all + mkdir -p ${DESTDIR}${PREFIX}/bin + cp -f ${NAME}-${LAYOUT} ${DESTDIR}${PREFIX}/bin + chmod 755 ${DESTDIR}${PREFIX}/bin/${NAME}-${LAYOUT} +- mkdir -p "${DESTDIR}${MANPREFIX}/man1" +- sed "s/VERSION/${VERSION}/g" < ${MAN1} > ${DESTDIR}${MANPREFIX}/man1/${MAN1} +- chmod 644 ${DESTDIR}${MANPREFIX}/man1/${MAN1} diff --git a/projects/ArchR/packages/apps/archr-touchscreen-keyboard/patches/001-fix-special-chars.patch b/projects/ArchR/packages/apps/archr-touchscreen-keyboard/patches/001-fix-special-chars.patch new file mode 100644 index 0000000000..eb8e387c8f --- /dev/null +++ b/projects/ArchR/packages/apps/archr-touchscreen-keyboard/patches/001-fix-special-chars.patch @@ -0,0 +1,897 @@ +diff --git a/layout.mobintl.h b/layout.mobintl.h +index 913f392..6200c6e 100644 +--- a/layout.mobintl.h ++++ b/layout.mobintl.h +@@ -22,7 +22,6 @@ enum layout_id { + Greek, + Georgian, + Hebrew, +- Emoji, + Nav, + Landscape, + LandscapeSpecial, +@@ -51,6 +50,7 @@ enum layout_id { + ComposeB, + ComposeN, + ComposeM, ++ ComposeQ, + ComposeMath, + ComposePunctuation, + ComposeBracket, +@@ -70,13 +70,13 @@ enum layout_id { + + static struct key keys_full[], keys_full_wide[], keys_special[], keys_specialpad[], keys_simple[], + keys_cyrillic[], keys_arabic[], keys_persian[], keys_georgian[], keys_greek[], keys_hebrew[], +- keys_emoji[], keys_nav[], keys_landscape[], keys_landscape_special[], keys_compose_a[], ++ keys_nav[], keys_landscape[], keys_landscape_special[], keys_compose_a[], + keys_compose_e[], keys_compose_y[], keys_compose_u[], keys_compose_i[], + keys_compose_o[], keys_compose_w[], keys_compose_r[], keys_compose_t[], + keys_compose_p[], keys_compose_s[], keys_compose_d[], keys_compose_f[], + keys_compose_g[], keys_compose_h[], keys_compose_j[], keys_compose_k[], + keys_compose_l[], keys_compose_z[], keys_compose_x[], keys_compose_c[], +- keys_compose_v[], keys_compose_b[], keys_compose_n[], keys_compose_m[], ++ keys_compose_v[], keys_compose_b[], keys_compose_n[], keys_compose_m[], keys_compose_q[], + keys_compose_math[], keys_compose_punctuation[], keys_compose_bracket[], + keys_compose_cyr_i[], keys_compose_cyr_j[], keys_compose_cyr_e[], + keys_compose_cyr_u[], keys_compose_cyr_l[], keys_compose_cyr_n[], +@@ -98,7 +98,6 @@ static struct layout layouts[NumLayouts] = { + [Greek] = {keys_greek, "greek", "greek", true}, + [Georgian] = {keys_georgian, "georgian", "georgian", true}, + [Hebrew] = {keys_hebrew, "hebrew", "hebrew", true}, +- [Emoji] = {keys_emoji, "latin", "emoji", false}, + [Nav] = {keys_nav, "latin", "nav", false}, + [Landscape] = {keys_landscape, "latin", "landscape", true}, + [LandscapeSpecial] = {keys_landscape_special, "latin", "landscapespecial", true}, +@@ -127,6 +126,7 @@ static struct layout layouts[NumLayouts] = { + [ComposeB] = {keys_compose_b, "latin"}, + [ComposeN] = {keys_compose_n, "latin"}, + [ComposeM] = {keys_compose_m, "latin"}, ++ [ComposeQ] = {keys_compose_q, "latin"}, + [ComposeMath] = {keys_compose_math, "latin"}, + [ComposePunctuation] = {keys_compose_punctuation, "latin"}, + [ComposeBracket] = {keys_compose_bracket, "latin"}, +@@ -197,7 +197,7 @@ static struct key keys_full[] = { + {"0", ")", 1.0, Code, KEY_0, &layouts[ComposeBracket]}, + {"", "", 0.0, EndRow}, + +- {"q", "Q", 1.0, Code, KEY_Q, &layouts[Emoji]}, ++ {"q", "Q", 1.0, Code, KEY_Q, &layouts[ComposeQ]}, + {"w", "W", 1.0, Code, KEY_W, &layouts[ComposeW]}, + {"e", "E", 1.0, Code, KEY_E, &layouts[ComposeE]}, + {"r", "R", 1.0, Code, KEY_R, &layouts[ComposeR]}, +@@ -222,7 +222,7 @@ static struct key keys_full[] = { + {"", "", 0.5, Pad}, + {"", "", 0.0, EndRow}, + +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"z", "Z", 1.0, Code, KEY_Z, &layouts[ComposeZ]}, + {"x", "X", 1.0, Code, KEY_X, &layouts[ComposeX]}, + {"c", "C", 1.0, Code, KEY_C, &layouts[ComposeC]}, +@@ -230,10 +230,10 @@ static struct key keys_full[] = { + {"b", "B", 1.0, Code, KEY_B, &layouts[ComposeB]}, + {"n", "N", 1.0, Code, KEY_N, &layouts[ComposeN]}, + {"m", "M", 1.0, Code, KEY_M, &layouts[ComposeM]}, +- {"⌫", "⌫", 1.5, Code, KEY_BACKSPACE, .scheme = 1}, ++ {"Back", "Back", 1.5, Code, KEY_BACKSPACE, .scheme = 1}, + {"", "", 0.0, EndRow}, + +- {"⌨͕", "⌨͔", 1.5, NextLayer, .scheme = 1}, ++ {"123", "123", 1.5, NextLayer, .scheme = 1}, + {"Cmp", "Cmp", 1.0, Compose, .scheme = 1}, + {",", "'", 1.0, Code, KEY_COMMA, &layouts[ComposeMath]}, + {"", "Tab", 4.0, Code, KEY_SPACE}, +@@ -271,7 +271,7 @@ static struct key keys_full_wide[] = { + {"=", "+", 1.0, Code, KEY_EQUAL, &layouts[ComposeMath] }, + {"", "", 0.0, EndRow}, + +- {"q", "Q", 1.0, Code, KEY_Q, &layouts[Emoji]}, ++ {"q", "Q", 1.0, Code, KEY_Q, &layouts[ComposeQ]}, + {"w", "W", 1.0, Code, KEY_W, &layouts[ComposeW]}, + {"e", "E", 1.0, Code, KEY_E, &layouts[ComposeE]}, + {"r", "R", 1.0, Code, KEY_R, &layouts[ComposeR]}, +@@ -296,7 +296,7 @@ static struct key keys_full_wide[] = { + {"", "", 0.5, Pad}, + {"", "", 0.0, EndRow}, + +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"z", "Z", 1.0, Code, KEY_Z, &layouts[ComposeZ]}, + {"x", "X", 1.0, Code, KEY_X, &layouts[ComposeX]}, + {"c", "C", 1.0, Code, KEY_C, &layouts[ComposeC]}, +@@ -304,10 +304,10 @@ static struct key keys_full_wide[] = { + {"b", "B", 1.0, Code, KEY_B, &layouts[ComposeB]}, + {"n", "N", 1.0, Code, KEY_N, &layouts[ComposeN]}, + {"m", "M", 1.0, Code, KEY_M, &layouts[ComposeM]}, +- {"⌫", "⌫", 1.5, Code, KEY_BACKSPACE, .scheme = 1}, ++ {"Back", "Back", 1.5, Code, KEY_BACKSPACE, .scheme = 1}, + {"", "", 0.0, EndRow}, + +- {"⌨͕", "⌨͔", 1.5, NextLayer, .scheme = 1}, ++ {"123", "123", 1.5, NextLayer, .scheme = 1}, + {"Cmp", "Cmp", 1.0, Compose, .scheme = 1}, + {",", "'", 1.0, Code, KEY_COMMA, &layouts[ComposeMath]}, + {"", "Tab", 4.0, Code, KEY_SPACE}, +@@ -325,10 +325,10 @@ static struct key keys_special[] = { + {"↓", "↓", 1.0, Code, KEY_DOWN, .scheme = 1}, + {"←", "←", 1.0, Code, KEY_LEFT, .scheme = 1}, + {"→", "→", 1.0, Code, KEY_RIGHT, .scheme = 1}, +- {"⇈", "⇈", 1.0, Code, KEY_PAGEUP, .scheme = 1}, +- {"⇊", "⇊", 1.0, Code, KEY_PAGEDOWN, .scheme = 1}, +- {"⇤", "⇤", 1.0, Code, KEY_HOME, .scheme = 1}, +- {"⇥", "⇥", 1.0, Code, KEY_END, .scheme = 1}, ++ {"Up", "Up", 1.0, Code, KEY_PAGEUP, .scheme = 1}, ++ {"Down", "Down", 1.0, Code, KEY_PAGEDOWN, .scheme = 1}, ++ {"Home", "Home", 1.0, Code, KEY_HOME, .scheme = 1}, ++ {"End", "End", 1.0, Code, KEY_END, .scheme = 1}, + {"", "", 0.0, EndRow}, + + {"1", "!", 1.0, Code, KEY_1}, +@@ -355,19 +355,18 @@ static struct key keys_special[] = { + {"Del", "Del", 1.0, Code, KEY_DELETE, .scheme = 1}, + {"", "", 0.0, EndRow}, + +- {"⇧", "⇫", 2.0, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 2.0, Mod, Shift, .scheme = 1}, + {";", ":", 1.0, Code, KEY_SEMICOLON}, + {"/", ">", 1.0, Code, KEY_SLASH}, + {"<", "«", 1.0, Code, KEY_COMMA, 0, AltGr}, + {">", "»", 1.0, Code, KEY_DOT, 0, AltGr}, + {"¡", "¿", 1.0, Code, KEY_MENU}, +- {"🙂", "🙂", 1.0, Layout, 0, &layouts[Emoji]}, + {"AGr", "AGr", 1.0, Mod, AltGr, .scheme = 1}, +- {"⌫", "⌫", 1.0, Code, KEY_BACKSPACE, .scheme = 1}, ++ {"Back", "Back", 1.0, Code, KEY_BACKSPACE, .scheme = 1}, + {"", "", 0.0, EndRow}, + + {"Abc", "Abc", 1.0, BackLayer, .scheme = 1}, +- {"⌨͕", "⌨͔", 1.0, NextLayer, .scheme = 1}, ++ {"123", "123", 1.0, NextLayer, .scheme = 1}, + {",", "'", 1.0, Code, KEY_COMMA, &layouts[ComposeMath]}, + {"", "Tab", 4.0, Code, KEY_SPACE}, + {".", "?", 1.0, Code, KEY_DOT, &layouts[ComposePunctuation]}, +@@ -378,20 +377,20 @@ static struct key keys_special[] = { + }; + + static struct key keys_specialpad[] = { +- {"⎋", "⎋", 1.0, Code, KEY_ESC, .scheme = 1}, ++ {"Esc", "Esc", 1.0, Code, KEY_ESC, .scheme = 1}, + {"↑", "↑", 1.0, Code, KEY_UP, .scheme = 1}, +- {"⇈", "⇈", 1.0, Code, KEY_PAGEUP, .scheme = 1}, ++ {"Up", "Up", 1.0, Code, KEY_PAGEUP, .scheme = 1}, + {"`", "~", 1.0, Code, KEY_GRAVE}, + {"\\", "|", 1.0, Code, KEY_BACKSLASH}, + {"/", ">", 1.0, Code, KEY_SLASH}, + {"1", "!", 1.0, Code, KEY_1}, + {"2", "@", 1.0, Code, KEY_2}, + {"3", "#", 1.0, Code, KEY_3}, +- {"⌦", "⌦", 1.0, Code, KEY_DELETE, .scheme = 1}, ++ {"Del", "Del", 1.0, Code, KEY_DELETE, .scheme = 1}, + {"", "", 0.0, EndRow}, + //{"Tab", "Tab", 1.0, Code, KEY_TAB, .scheme = 1}, + {"←", "←", 1.0, Code, KEY_LEFT, .scheme = 1}, +- {"", "↹", 1.0, Code, KEY_SPACE}, ++ {"", "Space", 1.0, Code, KEY_SPACE}, + {"→", "→", 1.0, Code, KEY_RIGHT, .scheme = 1}, + {".", "?", 1.0, Code, KEY_DOT}, + {"[", "{", 1.0, Code, KEY_LEFTBRACE}, +@@ -401,25 +400,25 @@ static struct key keys_specialpad[] = { + {"6", "^", 1.0, Code, KEY_6}, + {"'", "\"", 1.0, Code, KEY_APOSTROPHE}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.0, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.0, Mod, Shift, .scheme = 1}, + {"↓", "↓", 1.0, Code, KEY_DOWN, .scheme = 1}, +- {"⇊", "⇊", 1.0, Code, KEY_PAGEDOWN, .scheme = 1}, ++ {"Down", "Down", 1.0, Code, KEY_PAGEDOWN, .scheme = 1}, + {";", ":", 1.0, Code, KEY_SEMICOLON}, + {"<", "«", 1.0, Code, KEY_COMMA, 0, AltGr}, + {">", "»", 1.0, Code, KEY_DOT, 0, AltGr}, + {"7", "&", 1.0, Code, KEY_7}, + {"8", "*", 1.0, Code, KEY_8}, + {"9", "(", 1.0, Code, KEY_9}, +- {"⌫", "⌫", 1.0, Code, KEY_BACKSPACE, .scheme = 1}, ++ {"Back", "Back", 1.0, Code, KEY_BACKSPACE, .scheme = 1}, + {"", "", 0.0, EndRow}, + +- {"⌨͕", "⌨͔", 1.0, NextLayer, .scheme = 1}, ++ {"123", "123", 1.0, NextLayer, .scheme = 1}, + {"Ctr", "Ctr", 1.0, Mod, Ctrl, .scheme = 1}, + {"Alt", "Alt", 1.0, Mod, Alt, .scheme = 1}, + {"Sup", "Sup", 1.0, Mod, Super, .scheme = 1}, + +- {"⇤", "⇤", 1.0, Code, KEY_HOME, .scheme = 1}, +- {"⇥", "⇥", 1.0, Code, KEY_END, .scheme = 1}, ++ {"Home", "Home", 1.0, Code, KEY_HOME, .scheme = 1}, ++ {"End", "End", 1.0, Code, KEY_END, .scheme = 1}, + {"-", "_", 1.0, Code, KEY_MINUS}, + {"0", ")", 1.0, Code, KEY_0}, + {"=", "+", 1.0, Code, KEY_EQUAL}, +@@ -430,7 +429,7 @@ static struct key keys_specialpad[] = { + }; + + static struct key keys_simple[] = { +- {"q", "Q", 1.0, Code, KEY_Q, &layouts[Emoji]}, ++ {"q", "Q", 1.0, Code, KEY_Q, &layouts[ComposeQ]}, + {"w", "W", 1.0, Code, KEY_W, &layouts[ComposeW]}, + {"e", "E", 1.0, Code, KEY_E, &layouts[ComposeE]}, + {"r", "R", 1.0, Code, KEY_R, &layouts[ComposeR]}, +@@ -455,7 +454,7 @@ static struct key keys_simple[] = { + {"", "", 0.5, Pad}, + {"", "", 0.0, EndRow}, + +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"z", "Z", 1.0, Code, KEY_Z, &layouts[ComposeZ]}, + {"x", "X", 1.0, Code, KEY_X, &layouts[ComposeX]}, + {"c", "C", 1.0, Code, KEY_C, &layouts[ComposeC]}, +@@ -463,10 +462,10 @@ static struct key keys_simple[] = { + {"b", "B", 1.0, Code, KEY_B, &layouts[ComposeB]}, + {"n", "N", 1.0, Code, KEY_N, &layouts[ComposeN]}, + {"m", "M", 1.0, Code, KEY_M, &layouts[ComposeM]}, +- {"⌫", "⌫", 1.5, Code, KEY_BACKSPACE, .scheme = 1}, ++ {"Back", "Back", 1.5, Code, KEY_BACKSPACE, .scheme = 1}, + {"", "", 0.0, EndRow}, + +- {"⌨͕", "⌨͔", 1.0, NextLayer, .scheme = 1}, ++ {"123", "123", 1.0, NextLayer, .scheme = 1}, + {"Cmp", "Cmp", 1.0, Compose, .scheme = 1}, + {"Ctr", "Ctr", 1.0, Mod, Ctrl, .scheme = 1}, + {"-", "_", 0.75, Code, KEY_MINUS, &layouts[ComposeMath]}, +@@ -482,7 +481,7 @@ static struct key keys_simple[] = { + static struct key keys_dialer[] = { + {"Esc", "Esc", 1.0, Code, KEY_ESC}, + {"+","+", 1.0, Code, KEY_KPPLUS}, +- {"⌫", "⌫", 1.0, Code, KEY_BACKSPACE}, ++ {"Back", "Back", 1.0, Code, KEY_BACKSPACE}, + {"", "", 0.0, EndRow}, + {"1", "1", 1.0, Code, KEY_1}, + {"2", "2", 1.0, Code, KEY_2}, +@@ -500,7 +499,7 @@ static struct key keys_dialer[] = { + {"0", "0", 1.0, Code, KEY_0}, + {"#", "#", 1.0, Code, KEY_3, 0, Shift}, + {"", "", 0.0, EndRow}, +- {"⌨͕", "⌨͔", 1.0, NextLayer, .scheme = 1}, ++ {"123", "123", 1.0, NextLayer, .scheme = 1}, + {"Enter", "Enter", 2.0, Code, KEY_ENTER, .scheme = 1}, + + /* end of layout */ +@@ -549,7 +548,7 @@ static struct key keys_cyrillic[] = { + {"ж", "Ж", 1.0, Code, KEY_SEMICOLON}, + {"", "", 0.0, EndRow}, + +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"я", "Я", 1.0, Code, KEY_Z}, + {"ч", "Ч", 1.0, Code, KEY_X, &layouts[ComposeCyrChe]}, + {"c", "С", 1.0, Code, KEY_C}, +@@ -558,11 +557,11 @@ static struct key keys_cyrillic[] = { + {"т", "Т", 1.0, Code, KEY_N}, + {"ь", "Ь", 1.0, Code, KEY_M}, + {"б", "Б", 1.0, Code, KEY_COMMA}, +- {"⌫", "⌫", 1.5, Code, KEY_BACKSPACE, .scheme = 1}, ++ {"Back", "Back", 1.5, Code, KEY_BACKSPACE, .scheme = 1}, + + {"", "", 0.0, EndRow}, + +- {"⌨͕", "⌨͔", 1.0, NextLayer, .scheme = 1}, ++ {"123", "123", 1.0, NextLayer, .scheme = 1}, + {"Cmp", "Cmp", 1.0, Compose, .scheme = 1}, + {",", "'", 1.0, Code, KEY_EQUAL, &layouts[ComposeMath]}, + {"", "Tab", 4.0, Code, KEY_SPACE}, +@@ -586,7 +585,6 @@ static struct key keys_arabic[] = { + {"٠", ")", 1.0, Code, KEY_0, &layouts[ComposeBracket]}, + {"", "", 0.0, EndRow}, + +- {"ض", "ـَ", 1.0, Code, KEY_Q, &layouts[Emoji]}, + {"ص", "ـً", 1.0, Code, KEY_W}, + {"ث", "ـُ", 1.0, Code, KEY_E}, + {"ق", "ـٌ", 1.0, Code, KEY_R}, +@@ -622,12 +620,12 @@ static struct key keys_arabic[] = { + {"ز", "؟", 1.0, Code, KEY_COMMA}, + {"ظ", ".", 1.0, Code, KEY_DOT}, + {"د", ">", 1.0, Code, KEY_RIGHTBRACE}, +- {"⌫", "⌫", 1.0, Code, KEY_BACKSPACE, .scheme = 1}, ++ {"Back", "Back", 1.0, Code, KEY_BACKSPACE, .scheme = 1}, + + {"", "", 0.0, EndRow}, + +- {"⌨͕", "⌨͔", 1.0, NextLayer, .scheme = 1}, +- {"⇧", "⇫", 1.0, Mod, Shift, .scheme = 1}, ++ {"123", "123", 1.0, NextLayer, .scheme = 1}, ++ {"Shift", "Shift", 1.0, Mod, Shift, .scheme = 1}, + {"Cmp", "Cmp", 1.0, Compose, .scheme = 1}, + {"", "Tab", 5.0, Code, KEY_SPACE}, + {"Enter", "Enter", 2.0, Code, KEY_ENTER, .scheme = 1}, +@@ -682,12 +680,12 @@ static struct key keys_georgian[] = { + {"მ", "M", 1.0, Code, KEY_M}, + {",", "<", 1.0, Code, KEY_COMMA, &layouts[ComposeMath]}, + {".", ">", 1.0, Code, KEY_DOT, &layouts[ComposePunctuation]}, +- {"⌫", "⌫", 1.0, Code, KEY_BACKSPACE, .scheme = 1}, ++ {"Back", "Back", 1.0, Code, KEY_BACKSPACE, .scheme = 1}, + + {"", "", 0.0, EndRow}, + +- {"⌨͕", "⌨͔", 1.0, NextLayer, .scheme = 1}, +- {"⇧", "⇫", 1.0, Mod, Shift, .scheme = 1}, ++ {"123", "123", 1.0, NextLayer, .scheme = 1}, ++ {"Shift", "Shift", 1.0, Mod, Shift, .scheme = 1}, + {"Cmp", "Cmp", 1.0, Compose, .scheme = 1}, + {"", "Tab", 5.0, Code, KEY_SPACE}, + {"Enter", "Enter", 2.0, Code, KEY_ENTER, .scheme = 1}, +@@ -738,7 +736,7 @@ static struct key keys_persian[] = { + {"گ", "؛", 1.0, Code, KEY_APOSTROPHE}, + {"", "", 0.0, EndRow}, + +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"ظ", "ك", 1.0, Code, KEY_Z}, + {"ط", "ـٓ", 1.0, Code, KEY_X}, + {"ژ", ">", 1.0, Code, KEY_BACKSLASH}, +@@ -748,14 +746,14 @@ static struct key keys_persian[] = { + {"د", "ـٔ", 1.0, Code, KEY_N}, + {"پ", "ء", 1.0, Code, KEY_M}, + {"و", "\\", 1.0, Code, KEY_COMMA}, +- {"⌫", "⌫", 1.5, Code, KEY_BACKSPACE, .scheme = 1}, ++ {"Back", "Back", 1.5, Code, KEY_BACKSPACE, .scheme = 1}, + {"", "", 0.0, EndRow}, + +- {"⌨͕", "⌨͔", 1.0, NextLayer, .scheme = 1}, ++ {"123", "123", 1.0, NextLayer, .scheme = 1}, + {"Cmp", "Cmp", 1.0, Compose, .scheme = 1}, + {".", "،", 1.0, Code, KEY_DOT, &layouts[ComposePunctuation]}, + {"", "Tab", 4.0, Code, KEY_SPACE}, +- {"⥣", "↥", 1.0, Code, KEY_GRAVE}, ++ {"`", "~", 1.0, Code, KEY_GRAVE}, + {"؟", "!", 1.0, Code, KEY_SLASH, &layouts[ComposePunctuation]}, + {"Enter", "Enter", 2.0, Code, KEY_ENTER, .scheme = 1}, + +@@ -802,7 +800,7 @@ static struct key keys_greek[] = { + {"΄", "¨", 1.0, Code, KEY_SEMICOLON, &layouts[ComposeBracket]}, + {"", "", 0.0, EndRow}, + +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"ζ", "Ζ", 1.0, Code, KEY_Z}, + {"χ", "Χ", 1.0, Code, KEY_X}, + {"ψ", "Ψ", 1.0, Code, KEY_C}, +@@ -811,10 +809,10 @@ static struct key keys_greek[] = { + {"ν", "Ν", 1.0, Code, KEY_N}, + {"μ", "Μ", 1.0, Code, KEY_M}, + {"/", "\\", 1.0, Code, KEY_SLASH}, +- {"⌫", "⌫", 1.5, Code, KEY_BACKSPACE, .scheme = 1}, ++ {"Back", "Back", 1.5, Code, KEY_BACKSPACE, .scheme = 1}, + {"", "", 0.0, EndRow}, + +- {"⌨͕", "⌨͔", 1.5, NextLayer, .scheme = 1}, ++ {"123", "123", 1.5, NextLayer, .scheme = 1}, + {",", "'", 1.0, Code, KEY_COMMA, &layouts[ComposeMath]}, + {"", "Tab", 5, Code, KEY_SPACE}, + {".", "\"", 1.0, Code, KEY_DOT, &layouts[ComposePunctuation]}, +@@ -858,11 +856,11 @@ static struct key keys_hebrew[] = { + {"צ", "צ", 1.0, Code, KEY_M}, + {"ת", "ת", 1.0, Code, KEY_COMMA}, + {"ץ", "ץ", 1.0, Code, KEY_DOT}, +- {"⌫", "⌫", 1.0, Code, KEY_BACKSPACE, .scheme = 1}, ++ {"Back", "Back", 1.0, Code, KEY_BACKSPACE, .scheme = 1}, + + {"", "", 0.0, EndRow}, + +- {"⌨͕", "⌨͔", 1.0, NextLayer, .scheme = 1}, ++ {"123", "123", 1.0, NextLayer, .scheme = 1}, + {"Cmp", "Cmp", 1.0, Compose, .scheme = 1}, + {",", "\"", 1.0, Code, KEY_APOSTROPHE, &layouts[ComposeMath]}, + {"", "Tab", 3.5, Code, KEY_SPACE}, +@@ -889,7 +887,7 @@ static struct key keys_compose_a[] = { + {"α", "Α", 1.0, Copy, 0x03B1, 0, 0x0391}, + {"", "", 9.0, Pad}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Abc", "Abc", 1.0, BackLayer, .scheme = 1}, +@@ -913,7 +911,7 @@ static struct key keys_compose_e[] = { + {"ǝ", "Ə", 1.0, Copy, 0x0259, 0, 0x018F}, + {"", "", 8.0, Pad}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Abc", "Abc", 1.0, BackLayer, .scheme = 1}, +@@ -930,7 +928,7 @@ static struct key keys_compose_y[] = { + {"υ", "Υ", 1.0, Copy, 0x03C5, 0, 0x03A5}, + {"", "", 9.0, Pad}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Abc", "Abc", 1.0, BackLayer, .scheme = 1}, +@@ -953,7 +951,7 @@ static struct key keys_compose_u[] = { + {"υ", "Υ", 1.0, Copy, 0x03C5, 0, 0x03A5}, + {"", "", 9.0, Pad}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Abc", "Abc", 1.0, BackLayer, .scheme = 1}, +@@ -977,7 +975,7 @@ static struct key keys_compose_o[] = { + {"ω", "Ο", 1.0, Copy, 0x03C9, 0, 0x03A9}, + {"", "", 8.0, Pad}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Abc", "Abc", 1.0, BackLayer, .scheme = 1}, +@@ -1001,7 +999,7 @@ static struct key keys_compose_i[] = { + {"η", "Η", 1.0, Copy, 0x03B7, 0, 0x0397}, + {"", "", 8.0, Pad}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Abc", "Abc", 1.0, BackLayer, .scheme = 1}, +@@ -1009,58 +1007,11 @@ static struct key keys_compose_i[] = { + {"", "", 0.0, Last}, + }; + +-static struct key keys_emoji[] = { +- {"🙂", "🙏", 1.0, Copy, 0x1f642, 0, 0x1f64f}, // Emojis +- {"😀", "🙋", 1.0, Copy, 0x1f600, 0, 0x1f64b}, +- {"😁", "✋", 1.0, Copy, 0x1f601, 0, 0x270B}, +- {"😂", "🙇", 1.0, Copy, 0x1f602, 0, 0x1f647}, +- {"😃", "👨", 1.0, Copy, 0x1f603, 0, 0x1f468}, +- {"😄", "👩", 1.0, Copy, 0x1f604, 0, 0x1f469}, +- {"😅", "👶", 1.0, Copy, 0x1f605, 0, 0x1f476}, +- {"😆", "👻", 1.0, Copy, 0x1f606, 0, 0x1f47b}, +- {"😇", "✨", 1.0, Copy, 0x1f607, 0, 0x2728}, +- {"🤣", "💰", 1.0, Copy, 0x1f923, 0, 0x1f4b0}, +- {"", "", 0.0, EndRow}, +- {"😉", "🐕", 1.0, Copy, 0x1f609, 0, 0x1f415}, +- {"😊", "🐈", 1.0, Copy, 0x1f60a, 0, 0x1f408}, +- {"😋", "🐧", 1.0, Copy, 0x1f60b, 0, 0x1f427}, +- {"😌", "🐇", 1.0, Copy, 0x1f60c, 0, 0x1f407}, +- {"😍", "💔", 1.0, Copy, 0x1f60d, 0, 0x1f494}, +- {"😘", "💕", 1.0, Copy, 0x1f618, 0, 0x1f495}, +- {"😎", "❤", 1.0, Copy, 0x1f60e, 0, 0x2764}, +- {"😐", "😏", 1.0, Copy, 0x1f610, 0, 0x1f60f}, +- {"😒", "👀", 1.0, Copy, 0x1f612, 0, 0x1f440}, +- {"😓", "💀", 1.0, Copy, 0x1f613, 0, 0x1f480}, +- {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.0, Mod, Shift, .scheme = 1}, +- {"😛", "😜", 1.0, Copy, 0x1f61b, 0, 0x1f61c}, +- {"😮", "😝", 1.0, Copy, 0x1f62e, 0, 0x1f61d}, +- {"😟", "😞", 1.0, Copy, 0x1f61f, 0, 0x1f61e}, +- {"😠", "🥺", 1.0, Copy, 0x1f620, 0, 0x1f97a}, +- {"😢", "👿", 1.0, Copy, 0x1f622, 0, 0x1f47f}, +- {"😭", "😯", 1.0, Copy, 0x1f62d, 0, 0x1f62f}, +- {"😳", "😕", 1.0, Copy, 0x1f633, 0, 0x1f615}, +- {"😴", "😵", 1.0, Copy, 0x1f634, 0, 0x1f635}, +- {"⌫", "⌫", 1.0, Code, KEY_BACKSPACE, .scheme = 1}, +- {"", "", 0.0, EndRow}, +- {"Abc", "Abc", 1.0, BackLayer, .scheme = 1}, +- {"⌨͕", "⌨͔", 1.0, NextLayer, .scheme = 1}, +- {"👆", "👊", 1.0, Copy, 0x1f446, 0, 0x1f44a}, +- {"👇", "👌", 1.0, Copy, 0x1f447, 0, 0x1f44c}, +- {"👈", "👏", 1.0, Copy, 0x1f448, 0, 0x1f44f}, +- {"👉", "👐", 1.0, Copy, 0x1f449, 0, 0x1f450}, +- {"👋", "🙌", 1.0, Copy, 0x1f44b, 0, 0x1f64c}, +- {"👍", "✅", 1.0, Copy, 0x1f44d, 0, 0x2705}, +- {"👎", "💪", 1.0, Copy, 0x1f44e, 0, 0x1f4aa}, +- {"Enter", "Enter", 1.0, Code, KEY_ENTER, .scheme = 1}, +- {"", "", 0.0, Last}, +-}; +- + static struct key keys_nav[] = { + {"Esc", "Esc", 1.0, Code, KEY_ESC, .scheme = 1}, +- {"⌫", "⌫", 1.0, Code, KEY_BACKSPACE, .scheme = 1}, ++ {"Back", "Back", 1.0, Code, KEY_BACKSPACE, .scheme = 1}, + {"↑", "↑", 1.0, Code, KEY_UP, .scheme = 1}, +- {"⇈", "⇈", 1.0, Code, KEY_PAGEUP, .scheme = 1}, ++ {"Up", "Up", 1.0, Code, KEY_PAGEUP, .scheme = 1}, + {"", "", 0.0, EndRow}, + + {"q", "q", 1.0, Code, KEY_Q, .scheme = 1}, +@@ -1069,10 +1020,10 @@ static struct key keys_nav[] = { + {"→", "→", 1.0, Code, KEY_RIGHT, .scheme = 1}, + {"", "", 0.0, EndRow}, + +- {"⌨͕", "⌨͔", 1.0, NextLayer, .scheme = 1}, +- {"", "↹", 1.0, Code, KEY_SPACE, .scheme = 1}, ++ {"123", "123", 1.0, NextLayer, .scheme = 1}, ++ {"", "Space", 1.0, Code, KEY_SPACE, .scheme = 1}, + {"↓", "↓", 1.0, Code, KEY_DOWN, .scheme = 1}, +- {"⇊", "⇊", 1.0, Code, KEY_PAGEDOWN, .scheme = 1}, ++ {"Down", "Down", 1.0, Code, KEY_PAGEDOWN, .scheme = 1}, + {"", "", 0.0, Last}, + }; + +@@ -1089,7 +1040,6 @@ static struct key keys_index[] = { + {"Pad", "Pad", 1.0, Layout, 0, &layouts[SpecialPad]}, + {"Nav", "Nav", 1.0, Layout, 0, &layouts[Nav], .scheme = 1}, + {"123", "123", 1.0, Layout, 0, &layouts[Dialer], .scheme = 1}, +- {"🙂", "🙂", 1.0, Layout, 0, &layouts[Emoji], .scheme = 1}, + {"", "", 0.0, EndRow}, + + {"Абв", "Абв", 1.0, Layout, 0, &layouts[Cyrillic], .scheme = 1}, +@@ -1104,7 +1054,7 @@ static struct key keys_index[] = { + static struct key keys_landscape[] = { + {"Esc", "Esc", 1.0, Code, KEY_ESC, .scheme = 1}, + {"", "", 0.5, Pad, .scheme = 1}, +- {"q", "Q", 1.0, Code, KEY_Q, &layouts[Emoji]}, ++ {"q", "Q", 1.0, Code, KEY_Q, &layouts[ComposeQ]}, + {"w", "W", 1.0, Code, KEY_W, &layouts[ComposeW]}, + {"e", "E", 1.0, Code, KEY_E, &layouts[ComposeE]}, + {"r", "R", 1.0, Code, KEY_R, &layouts[ComposeR]}, +@@ -1136,7 +1086,7 @@ static struct key keys_landscape[] = { + + {"←", "←", 0.75, Code, KEY_LEFT, .scheme = 1}, + {"→", "→", 0.75, Code, KEY_RIGHT, .scheme = 1}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"z", "Z", 1.0, Code, KEY_Z, &layouts[ComposeZ]}, + {"x", "X", 1.0, Code, KEY_X, &layouts[ComposeX]}, + {"c", "C", 1.0, Code, KEY_C, &layouts[ComposeC]}, +@@ -1146,10 +1096,10 @@ static struct key keys_landscape[] = { + {"m", "M", 1.0, Code, KEY_M, &layouts[ComposeM]}, + {"", "", 0.5, Pad, .scheme = 1}, + {"-", "_", 1.0, Code, KEY_MINUS, &layouts[ComposeBracket]}, +- {"⌫", "⌫", 1.5, Code, KEY_BACKSPACE, .scheme = 1}, ++ {"Back", "Back", 1.5, Code, KEY_BACKSPACE, .scheme = 1}, + {"", "", 0.0, EndRow}, + +- {"⌨͕", "⌨͔", 1.0, NextLayer, .scheme = 1}, ++ {"123", "123", 1.0, NextLayer, .scheme = 1}, + {"Cmp", "Cmp", 1.0, Compose, .scheme = 1}, + {"Ctr", "Ctr", 1.0, Mod, Ctrl, .scheme = 1}, + {",", "'", 1.0, Code, KEY_COMMA, &layouts[ComposeMath]}, +@@ -1178,10 +1128,9 @@ static struct key keys_landscape_special[] = { + {"Tab", "Tab", 1.0, Code, KEY_TAB, .scheme = 1}, + {"", "", 0.0, EndRow}, + +- {"⇈", "⇈", 1.0, Code, KEY_PAGEUP, .scheme = 1}, +- {"⇊", "⇊", 1.0, Code, KEY_PAGEDOWN, .scheme = 1}, ++ {"Up", "Up", 1.0, Code, KEY_PAGEUP, .scheme = 1}, ++ {"Down", "Down", 1.0, Code, KEY_PAGEDOWN, .scheme = 1}, + {"CpL", "CpL", 1.0, Mod, CapsLock, .scheme = 1}, +- {"🙂", "🙂", 1.0, Layout, 0, &layouts[Emoji]}, + {"`", "~", 1.0, Code, KEY_GRAVE}, + {"'", "\"", 1.0, Code, KEY_APOSTROPHE}, + {"-", "_", 1.0, Code, KEY_MINUS}, +@@ -1193,9 +1142,9 @@ static struct key keys_landscape_special[] = { + {"Del", "Del", 1.0, Code, KEY_DELETE, .scheme = 1}, + {"", "", 0.0, EndRow}, + +- {"⇤", "⇤", 1.0, Code, KEY_HOME, .scheme = 1}, +- {"⇥", "⇥", 1.0, Code, KEY_END, .scheme = 1}, +- {"⇧", "⇫", 2.0, Mod, Shift, .scheme = 1}, ++ {"Home", "Home", 1.0, Code, KEY_HOME, .scheme = 1}, ++ {"End", "End", 1.0, Code, KEY_END, .scheme = 1}, ++ {"Shift", "Shift", 2.0, Mod, Shift, .scheme = 1}, + {";", ":", 1.0, Code, KEY_SEMICOLON}, + {"<", "«", 1.0, Code, KEY_COMMA, 0, AltGr}, + {">", "»", 1.0, Code, KEY_DOT, 0, AltGr}, +@@ -1204,11 +1153,11 @@ static struct key keys_landscape_special[] = { + {".", "?", 1.0, Code, KEY_DOT, &layouts[ComposePunctuation]}, + {"/", ">", 1.0, Code, KEY_SLASH}, + {"", "", 0.5, Pad, .scheme = 1}, +- {"⌫", "⌫", 1.5, Code, KEY_BACKSPACE, .scheme = 1}, ++ {"Back", "Back", 1.5, Code, KEY_BACKSPACE, .scheme = 1}, + {"", "", 0.0, EndRow}, + + {"Abc", "Abc", 1.0, BackLayer, .scheme = 1}, +- {"⌨͕", "⌨͔", 1.0, NextLayer, .scheme = 1}, ++ {"123", "123", 1.0, NextLayer, .scheme = 1}, + {"Ctr", "Ctr", 1.0, Mod, Ctrl, .scheme = 1}, + {"Sup", "Sup", 1.0, Mod, Super, .scheme = 1}, + {"", "Tab", 5.0, Code, KEY_SPACE}, +@@ -1225,7 +1174,7 @@ static struct key keys_compose_w[] = { + {"", "", 9.0, Pad}, + {"", "", 0.0, EndRow}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Abc", "Abc", 1.0, BackLayer, .scheme = 1}, +@@ -1242,7 +1191,7 @@ static struct key keys_compose_r[] = { + {"ρ", "Ρ", 1.0, Copy, 0x03C1, 0, 0x03A1}, + {"", "", 9.0, Pad}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Abc", "Abc", 1.0, BackLayer, .scheme = 1}, +@@ -1261,7 +1210,7 @@ static struct key keys_compose_t[] = { + {"θ", "Θ", 1.0, Copy, 0x03B8, 0, 0x0398}, + {"", "", 8.0, Pad}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Abc", "Abc", 1.0, BackLayer, .scheme = 1}, +@@ -1274,7 +1223,7 @@ static struct key keys_compose_p[] = { + {"", "", 9.0, Pad}, + {"", "", 0.0, EndRow}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Abc", "Abc", 1.0, BackLayer, .scheme = 1}, +@@ -1294,7 +1243,7 @@ static struct key keys_compose_s[] = { + {"ς", "Σ", 1.0, Copy, 0x03C2, 0, 0x03A3}, + {"", "", 9.0, Pad}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Abc", "Abc", 1.0, BackLayer, .scheme = 1}, +@@ -1311,7 +1260,7 @@ static struct key keys_compose_d[] = { + {"δ", "Δ", 1.0, Copy, 0x03B4, 0, 0x0394}, + {"", "", 9.0, Pad}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Abc", "Abc", 1.0, BackLayer, .scheme = 1}, +@@ -1324,7 +1273,7 @@ static struct key keys_compose_f[] = { + {"", "", 9.0, Pad}, + {"", "", 0.0, EndRow}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Abc", "Abc", 1.0, BackLayer, .scheme = 1}, +@@ -1340,7 +1289,7 @@ static struct key keys_compose_g[] = { + {"γ", "Γ", 1.0, Copy, 0x03B3, 0, 0x0393}, + {"", "", 9.0, Pad}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Abc", "Abc", 1.0, BackLayer, .scheme = 1}, +@@ -1356,7 +1305,7 @@ static struct key keys_compose_h[] = { + {"η", "Η", 1.0, Copy, 0x03B7, 0, 0x0397}, + {"", "", 9.0, Pad}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Abc", "Abc", 1.0, BackLayer, .scheme = 1}, +@@ -1370,7 +1319,7 @@ static struct key keys_compose_j[] = { + {"", "", 0.0, EndRow}, + {"", "", 10.0, Pad}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Abc", "Abc", 1.0, BackLayer, .scheme = 1}, +@@ -1386,7 +1335,7 @@ static struct key keys_compose_k[] = { + {"κ", "Κ", 1.0, Copy, 0x03BA, 0, 0x039A}, + {"", "", 9.0, Pad}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Abc", "Abc", 1.0, BackLayer, .scheme = 1}, +@@ -1403,7 +1352,7 @@ static struct key keys_compose_l[] = { + {"λ", "Λ", 1.0, Copy, 0x03BB, 0, 0x039B}, + {"", "", 9.0, Pad}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Abc", "Abc", 1.0, BackLayer, .scheme = 1}, +@@ -1420,7 +1369,7 @@ static struct key keys_compose_z[] = { + {"ζ", "Ζ", 1.0, Copy, 0x03B6, 0, 0x0396}, + {"", "", 9.0, Pad}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Abc", "Abc", 1.0, BackLayer, .scheme = 1}, +@@ -1434,7 +1383,7 @@ static struct key keys_compose_x[] = { + {"", "", 9.0, Pad}, + {"", "", 0.0, EndRow}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Abc", "Abc", 1.0, BackLayer, .scheme = 1}, +@@ -1453,7 +1402,7 @@ static struct key keys_compose_c[] = { + {"χ", "Χ", 1.0, Copy, 0x03C7, 0, 0x03A7}, + {"", "", 9.0, Pad}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Abc", "Abc", 1.0, BackLayer, .scheme = 1}, +@@ -1464,7 +1413,7 @@ static struct key keys_compose_c[] = { + static struct key keys_compose_v[] = { + {"", "", 0.0, EndRow}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Abc", "Abc", 1.0, BackLayer, .scheme = 1}, +@@ -1477,7 +1426,7 @@ static struct key keys_compose_b[] = { + {"", "", 9.0, Pad}, + {"", "", 0.0, EndRow}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Abc", "Abc", 1.0, BackLayer, .scheme = 1}, +@@ -1496,7 +1445,7 @@ static struct key keys_compose_n[] = { + {"ν", "Ν", 1.0, Copy, 0x03BD, 0, 0x039D}, + {"", "", 9.0, Pad}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Abc", "Abc", 1.0, BackLayer, .scheme = 1}, +@@ -1509,7 +1458,20 @@ static struct key keys_compose_m[] = { + {"", "", 9.0, Pad}, + {"", "", 0.0, EndRow}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, ++ {"", "", 8.5, Pad}, ++ {"", "", 0.0, EndRow}, ++ {"Abc", "Abc", 1.0, BackLayer, .scheme = 1}, ++ {"", "", 9, Pad}, ++ {"", "", 0.0, Last}, ++}; ++ ++static struct key keys_compose_q[] = { ++ {"q", "Q", 1.0, Copy, 0x0071, 0, 0x0051}, ++ {"", "", 9.0, Pad}, ++ {"", "", 0.0, EndRow}, ++ {"", "", 0.0, EndRow}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Abc", "Abc", 1.0, BackLayer, .scheme = 1}, +@@ -1523,7 +1485,7 @@ static struct key keys_compose_cyr_i[] = { + {"", "", 8.0, Pad}, + {"", "", 0.0, EndRow}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Абв", "Абв", 1.0, BackLayer, .scheme = 1}, +@@ -1536,7 +1498,7 @@ static struct key keys_compose_cyr_j[] = { + {"", "", 9.0, Pad}, + {"", "", 0.0, EndRow}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Абв", "Абв", 1.0, BackLayer, .scheme = 1}, +@@ -1549,7 +1511,7 @@ static struct key keys_compose_cyr_e[] = { + {"", "", 9.0, Pad}, + {"", "", 0.0, EndRow}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Абв", "Абв", 1.0, BackLayer, .scheme = 1}, +@@ -1562,7 +1524,7 @@ static struct key keys_compose_cyr_u[] = { + {"", "", 9.0, Pad}, + {"", "", 0.0, EndRow}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Абв", "Абв", 1.0, BackLayer, .scheme = 1}, +@@ -1575,7 +1537,7 @@ static struct key keys_compose_cyr_l[] = { + {"", "", 9.0, Pad}, + {"", "", 0.0, EndRow}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Абв", "Абв", 1.0, BackLayer, .scheme = 1}, +@@ -1588,7 +1550,7 @@ static struct key keys_compose_cyr_n[] = { + {"", "", 9.0, Pad}, + {"", "", 0.0, EndRow}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Абв", "Абв", 1.0, BackLayer, .scheme = 1}, +@@ -1602,7 +1564,7 @@ static struct key keys_compose_cyr_che[] = { + {"", "", 8.0, Pad}, + {"", "", 0.0, EndRow}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Абв", "Абв", 1.0, BackLayer, .scheme = 1}, +@@ -1616,7 +1578,7 @@ static struct key keys_compose_cyr_tse[] = { + {"", "", 8.0, Pad}, + {"", "", 0.0, EndRow}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Абв", "Абв", 1.0, BackLayer, .scheme = 1}, +@@ -1630,7 +1592,7 @@ static struct key keys_compose_cyr_g[] = { + {"", "", 8.0, Pad}, + {"", "", 0.0, EndRow}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Абв", "Абв", 1.0, BackLayer, .scheme = 1}, +@@ -1643,7 +1605,7 @@ static struct key keys_compose_cyr_k[] = { + {"", "", 9.0, Pad}, + {"", "", 0.0, EndRow}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 8.5, Pad}, + {"", "", 0.0, EndRow}, + {"Абв", "Абв", 1.0, BackLayer, .scheme = 1}, +@@ -1654,7 +1616,7 @@ static struct key keys_compose_cyr_k[] = { + static struct key keys_compose_math[] = { + {"", "", 0.0, EndRow}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"+", "+", 1, Code, KEY_EQUAL, 0, Shift}, + {"/", "/", 1, Code, KEY_SLASH}, + {"*", "*", 1, Code, KEY_8, 0, Shift}, +@@ -1679,7 +1641,7 @@ static struct key keys_compose_punctuation[] = { + {"⍽", "⍽", 1, Copy, 0x202F, 0, 0x00A0}, + {"", "", 0.5, Pad}, + {"", "", 0.0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"", "", 3, Pad}, + {"!", "!", 1, Code, KEY_1, 0, Shift}, + {"?", "?", 1, Code, KEY_DOT, 0, Shift}, +@@ -1701,10 +1663,10 @@ static struct key keys_compose_bracket[] = { + {"]", "]", 1, Code, KEY_RIGHTBRACE}, + {"", "", 4.5, Pad}, + {"", "", 0, EndRow}, +- {"⇧", "⇫", 1.5, Mod, Shift, .scheme = 1}, ++ {"Shift", "Shift", 1.5, Mod, Shift, .scheme = 1}, + {"<", "<", 1, Code, KEY_COMMA, 0, AltGr}, + {">", ">", 1, Code, KEY_SLASH, 0, Shift}, +- {"`", "`", 1, Code, KEY_GRAVE}, ++ {"`", "~", 1, Code, KEY_GRAVE}, + {"\"", "\"", 1, Code, KEY_APOSTROPHE, 0, Shift}, + {"'", "'", 1, Code, KEY_APOSTROPHE}, + {"", "", 3.5, Pad}, diff --git a/projects/ArchR/packages/apps/archr-touchscreen-keyboard/patches/002-Add-pin-keyboard-to-specific-output.patch b/projects/ArchR/packages/apps/archr-touchscreen-keyboard/patches/002-Add-pin-keyboard-to-specific-output.patch new file mode 100644 index 0000000000..b7df551866 --- /dev/null +++ b/projects/ArchR/packages/apps/archr-touchscreen-keyboard/patches/002-Add-pin-keyboard-to-specific-output.patch @@ -0,0 +1,407 @@ +From 6d897e736916d1e34dac1474225e81d84e7edb64 Mon Sep 17 00:00:00 2001 +From: tiopex +Date: Sun, 9 Nov 2025 22:47:57 +0100 +Subject: [PATCH] Add pin keyboard to specific output + +--- + main.c | 83 +++++++++++- + proto/xdg-output-unstable-v1.xml | 222 +++++++++++++++++++++++++++++++ + 2 files changed, 303 insertions(+), 2 deletions(-) + create mode 100644 proto/xdg-output-unstable-v1.xml + +diff --git a/main.c b/main.c +index 502d2f5..e85174e 100644 +--- a/main.c ++++ b/main.c +@@ -3,6 +3,7 @@ + #include "proto/xdg-shell-client-protocol.h" + #include "proto/fractional-scale-v1-client-protocol.h" + #include "proto/viewporter-client-protocol.h" ++#include "proto/xdg-output-unstable-v1-client-protocol.h" + #include + #include + #include +@@ -47,7 +48,7 @@ static struct wp_fractional_scale_manager_v1 *wfs_mgr; + static struct wp_viewport *draw_surf_viewport, *popup_draw_surf_viewport; + static struct wp_viewporter *viewporter; + static bool popup_xdg_surface_configured; +- ++static struct wl_output *preferred_output = NULL; + struct Output { + uint32_t name; + uint32_t w, h; +@@ -55,6 +56,9 @@ struct Output { + struct wl_output *data; + }; + static struct Output *current_output; ++struct zxdg_output_manager_v1 *xdg_output_manager = NULL; ++static char preferred_output_name[64] = {0}; ++static bool preferred_output_set = false; + + #define WL_OUTPUTS_LIMIT 8 + static struct Output wl_outputs[WL_OUTPUTS_LIMIT]; +@@ -135,6 +139,24 @@ static void layer_surface_closed(void *data, + static void flip_landscape(); + static void show(); + ++static void xdg_output_done(void *data, struct zxdg_output_v1 *xdg_output); ++ ++static void xdg_output_name(void *data, ++ struct zxdg_output_v1 *xdg_output, ++ const char *name); ++ ++static void xdg_output_logical_position(void *data, ++ struct zxdg_output_v1 *xdg_output, ++ int32_t x, int32_t y); ++ ++static void xdg_output_logical_size(void *data, ++ struct zxdg_output_v1 *xdg_output, ++ int32_t width, int32_t height); ++ ++static void xdg_output_description(void *data, ++ struct zxdg_output_v1 *xdg_output, ++ const char *desc); ++ + /* event handlers */ + static const struct wl_pointer_listener pointer_listener = { + .enter = wl_pointer_enter, +@@ -174,6 +196,14 @@ static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { + .closed = layer_surface_closed, + }; + ++static const struct zxdg_output_v1_listener xdg_output_listener = { ++ .name = xdg_output_name, ++ .done = xdg_output_done, ++ .logical_position = xdg_output_logical_position, ++ .logical_size = xdg_output_logical_size, ++ .description = xdg_output_description, ++}; ++ + /* configuration, allows nested code to access above variables */ + + char * +@@ -438,6 +468,33 @@ display_handle_mode(void *data, struct wl_output *wl_output, uint32_t flags, + { + } + ++static void xdg_output_done(void *data, struct zxdg_output_v1 *xdg_output) ++{ ++} ++ ++static void xdg_output_name(void *data, ++ struct zxdg_output_v1 *xdg_output, ++ const char *name) ++{ ++ struct Output *out = data; ++ if (preferred_output_set && strcmp(name, preferred_output_name) == 0) { ++ preferred_output = out->data; ++ fprintf(stderr, "wvkbd: assigned preferred output to: %s\n", name); ++ } ++} ++ ++static void xdg_output_logical_position(void *data, ++ struct zxdg_output_v1 *xdg_output, ++ int32_t x, int32_t y) {} ++ ++static void xdg_output_logical_size(void *data, ++ struct zxdg_output_v1 *xdg_output, ++ int32_t width, int32_t height) {} ++ ++static void xdg_output_description(void *data, ++ struct zxdg_output_v1 *xdg_output, ++ const char *desc) {} ++ + static const struct wl_output_listener output_listener = { + .geometry = display_handle_geometry, + .mode = display_handle_mode, +@@ -461,6 +518,9 @@ handle_global(void *data, struct wl_registry *registry, uint32_t name, + if (strcmp(interface, wl_compositor_interface.name) == 0) { + compositor = + wl_registry_bind(registry, name, &wl_compositor_interface, 3); ++ } else if (strcmp(interface, zxdg_output_manager_v1_interface.name) == 0) { ++ xdg_output_manager = wl_registry_bind( ++ registry, name, &zxdg_output_manager_v1_interface, 3); + } else if (strcmp(interface, wl_shm_interface.name) == 0) { + draw_ctx.shm = wl_registry_bind(registry, name, &wl_shm_interface, 1); + } else if (strcmp(interface, wl_output_interface.name) == 0) { +@@ -471,6 +531,12 @@ handle_global(void *data, struct wl_registry *registry, uint32_t name, + output->name = name; + output->scale = 1; + wl_output_add_listener(output->data, &output_listener, output); ++ wl_display_roundtrip(display); ++ if (xdg_output_manager) { ++ struct zxdg_output_v1 *xdg_output = ++ zxdg_output_manager_v1_get_xdg_output(xdg_output_manager, output->data); ++ zxdg_output_v1_add_listener(xdg_output, &xdg_output_listener, output); ++ } + wl_outputs_size += 1; + } + } else if (strcmp(interface, wl_seat_interface.name) == 0) { +@@ -716,6 +782,8 @@ usage(char *argv0) + " -l - Comma separated list of layers\n"); + fprintf(stderr, " --landscape-layers - Comma separated list of " + "landscape layers\n"); ++ fprintf(stderr, ++ " --output [name] - Pin keyboard to specific output (e.g. DSI-1, HDMI-A-1)\n"); + } + + void +@@ -777,8 +845,9 @@ show() + if (current_output) + current_output_data = current_output->data; + ++ struct wl_output *target_output = preferred_output ? preferred_output : current_output_data; + layer_surface = zwlr_layer_shell_v1_get_layer_surface( +- layer_shell, draw_surf.surf, current_output_data, layer, namespace); ++ layer_shell, draw_surf.surf, target_output, layer, namespace); + + zwlr_layer_surface_v1_set_size(layer_surface, 0, height); + zwlr_layer_surface_v1_set_anchor(layer_surface, anchor); +@@ -986,6 +1055,16 @@ main(int argc, char **argv) + (!strcmp(argv[i], "--list-layers"))) { + list_layers(); + exit(0); ++ } else if ((!strcmp(argv[i], "-output")) ++ || (!strcmp(argv[i], "--output"))) { ++ if (i >= argc - 1) { ++ usage(argv[0]); ++ exit(1); ++ } ++ strncpy(preferred_output_name, argv[++i], sizeof(preferred_output_name) - 1); ++ preferred_output_name[sizeof(preferred_output_name) - 1] = '\0'; ++ preferred_output_set = true; ++ fprintf(stderr, "wvkbd: preferred output set to: \"%s\"\n", preferred_output_name); + } else { + fprintf(stderr, "Invalid argument: %s\n", argv[i]); + usage(argv[0]); +diff --git a/proto/xdg-output-unstable-v1.xml b/proto/xdg-output-unstable-v1.xml +new file mode 100644 +index 0000000..a7306e4 +--- /dev/null ++++ b/proto/xdg-output-unstable-v1.xml +@@ -0,0 +1,222 @@ ++ ++ ++ ++ ++ Copyright © 2017 Red Hat Inc. ++ ++ 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 (including the next ++ paragraph) 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. ++ ++ ++ ++ This protocol aims at describing outputs in a way which is more in line ++ with the concept of an output on desktop oriented systems. ++ ++ Some information are more specific to the concept of an output for ++ a desktop oriented system and may not make sense in other applications, ++ such as IVI systems for example. ++ ++ Typically, the global compositor space on a desktop system is made of ++ a contiguous or overlapping set of rectangular regions. ++ ++ The logical_position and logical_size events defined in this protocol ++ might provide information identical to their counterparts already ++ available from wl_output, in which case the information provided by this ++ protocol should be preferred to their equivalent in wl_output. The goal is ++ to move the desktop specific concepts (such as output location within the ++ global compositor space, etc.) out of the core wl_output protocol. ++ ++ Warning! The protocol described in this file is experimental and ++ backward incompatible changes may be made. Backward compatible ++ changes may be added together with the corresponding interface ++ version bump. ++ Backward incompatible changes are done by bumping the version ++ number in the protocol and interface names and resetting the ++ interface version. Once the protocol is to be declared stable, ++ the 'z' prefix and the version number in the protocol and ++ interface names are removed and the interface version number is ++ reset. ++ ++ ++ ++ ++ A global factory interface for xdg_output objects. ++ ++ ++ ++ ++ Using this request a client can tell the server that it is not ++ going to use the xdg_output_manager object anymore. ++ ++ Any objects already created through this instance are not affected. ++ ++ ++ ++ ++ ++ This creates a new xdg_output object for the given wl_output. ++ ++ ++ ++ ++ ++ ++ ++ ++ An xdg_output describes part of the compositor geometry. ++ ++ This typically corresponds to a monitor that displays part of the ++ compositor space. ++ ++ For objects version 3 onwards, after all xdg_output properties have been ++ sent (when the object is created and when properties are updated), a ++ wl_output.done event is sent. This allows changes to the output ++ properties to be seen as atomic, even if they happen via multiple events. ++ ++ ++ ++ ++ Using this request a client can tell the server that it is not ++ going to use the xdg_output object anymore. ++ ++ ++ ++ ++ ++ The position event describes the location of the wl_output within ++ the global compositor space. ++ ++ The logical_position event is sent after creating an xdg_output ++ (see xdg_output_manager.get_xdg_output) and whenever the location ++ of the output changes within the global compositor space. ++ ++ ++ ++ ++ ++ ++ ++ The logical_size event describes the size of the output in the ++ global compositor space. ++ ++ Most regular Wayland clients should not pay attention to the ++ logical size and would rather rely on xdg_shell interfaces. ++ ++ Some clients such as Xwayland, however, need this to configure ++ their surfaces in the global compositor space as the compositor ++ may apply a different scale from what is advertised by the output ++ scaling property (to achieve fractional scaling, for example). ++ ++ For example, for a wl_output mode 3840×2160 and a scale factor 2: ++ ++ - A compositor not scaling the monitor viewport in its compositing space ++ will advertise a logical size of 3840×2160, ++ ++ - A compositor scaling the monitor viewport with scale factor 2 will ++ advertise a logical size of 1920×1080, ++ ++ - A compositor scaling the monitor viewport using a fractional scale of ++ 1.5 will advertise a logical size of 2560×1440. ++ ++ For example, for a wl_output mode 1920×1080 and a 90 degree rotation, ++ the compositor will advertise a logical size of 1080x1920. ++ ++ The logical_size event is sent after creating an xdg_output ++ (see xdg_output_manager.get_xdg_output) and whenever the logical ++ size of the output changes, either as a result of a change in the ++ applied scale or because of a change in the corresponding output ++ mode(see wl_output.mode) or transform (see wl_output.transform). ++ ++ ++ ++ ++ ++ ++ ++ This event is sent after all other properties of an xdg_output ++ have been sent. ++ ++ This allows changes to the xdg_output properties to be seen as ++ atomic, even if they happen via multiple events. ++ ++ For objects version 3 onwards, this event is deprecated. Compositors ++ are not required to send it anymore and must send wl_output.done ++ instead. ++ ++ ++ ++ ++ ++ ++ ++ Many compositors will assign names to their outputs, show them to the ++ user, allow them to be configured by name, etc. The client may wish to ++ know this name as well to offer the user similar behaviors. ++ ++ The naming convention is compositor defined, but limited to ++ alphanumeric characters and dashes (-). Each name is unique among all ++ wl_output globals, but if a wl_output global is destroyed the same name ++ may be reused later. The names will also remain consistent across ++ sessions with the same hardware and software configuration. ++ ++ Examples of names include 'HDMI-A-1', 'WL-1', 'X11-1', etc. However, do ++ not assume that the name is a reflection of an underlying DRM ++ connector, X11 connection, etc. ++ ++ The name event is sent after creating an xdg_output (see ++ xdg_output_manager.get_xdg_output). This event is only sent once per ++ xdg_output, and the name does not change over the lifetime of the ++ wl_output global. ++ ++ This event is deprecated, instead clients should use wl_output.name. ++ Compositors must still support this event. ++ ++ ++ ++ ++ ++ ++ Many compositors can produce human-readable descriptions of their ++ outputs. The client may wish to know this description as well, to ++ communicate the user for various purposes. ++ ++ The description is a UTF-8 string with no convention defined for its ++ contents. Examples might include 'Foocorp 11" Display' or 'Virtual X11 ++ output via :1'. ++ ++ The description event is sent after creating an xdg_output (see ++ xdg_output_manager.get_xdg_output) and whenever the description ++ changes. The description is optional, and may not be sent at all. ++ ++ For objects of version 2 and lower, this event is only sent once per ++ xdg_output, and the description does not change over the lifetime of ++ the wl_output global. ++ ++ This event is deprecated, instead clients should use ++ wl_output.description. Compositors must still support this event. ++ ++ ++ ++ ++ ++ +-- +2.43.0 + diff --git a/projects/ArchR/packages/apps/archr-touchscreen-keyboard/sources/archr-touchscreen-keyboard b/projects/ArchR/packages/apps/archr-touchscreen-keyboard/sources/archr-touchscreen-keyboard new file mode 100644 index 0000000000..a5cee42355 --- /dev/null +++ b/projects/ArchR/packages/apps/archr-touchscreen-keyboard/sources/archr-touchscreen-keyboard @@ -0,0 +1,39 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025-present ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile + +TSKEY=$(get_setting "archr.touchscreen-keyboard.enabled") +if [ ! -n "${TSKEY}" ]; then + if [ "$DEVICE_HAS_TOUCHSCREEN" == "true" ]; then + set_setting "archr.touchscreen-keyboard.enabled" "1" + else + set_setting "archr.touchscreen-keyboard.enabled" "0" + fi +fi + + +while true; do + TSKEY=$(get_setting "archr.touchscreen-keyboard.enabled") + if [[ "${DEVICE_HAS_TOUCHSCREEN}" == "true" ]] && [[ "${TSKEY}" == "1" ]]; then + PID="$(pidof wvkbd-mobintl)" + if [ "$PID" != "" ]; then + killall wvkbd-mobintl + elif [[ "${DEVICE_HAS_DUAL_SCREEN}" == "true" ]]; then + secondary_output=$(swaymsg -t get_outputs -r | jq -r '.[] | select(.focused == false) | .name') + swaymsg output ${secondary_output} power on + if [[ ! "${QUIRK_DEVICE}" == "Anbernic RG DS" ]]; then + tskb_height=720 + tskb_legend_size=35 + else + tskb_height=350 + tskb_legend_size=18 + fi + /usr/bin/wvkbd-mobintl -L ${tskb_height} -fg 6b6b75 -fg-sp 6b6b75 -bg 1d1d1d --text ffffff --text-sp ffffff -fn ${tskb_legend_size} -l simple --hidden --output ${secondary_output} + else + /usr/bin/wvkbd-mobintl -L 350 -fg 6b6b75 -fg-sp 6b6b75 -bg 1d1d1d --text ffffff --text-sp ffffff -fn 50 -l simple --hidden + fi + fi + sleep 5 +done diff --git a/projects/ArchR/packages/apps/archr-touchscreen-keyboard/system.d/touchkeyboard.service b/projects/ArchR/packages/apps/archr-touchscreen-keyboard/system.d/touchkeyboard.service new file mode 100644 index 0000000000..59275d005c --- /dev/null +++ b/projects/ArchR/packages/apps/archr-touchscreen-keyboard/system.d/touchkeyboard.service @@ -0,0 +1,15 @@ +[Unit] +Description=touchscreen keyboard service +After=input.service +RequiresMountsFor=/storage +Before=archr.target +StartLimitIntervalSec=0 + +[Service] +Environment=HOME=/storage +ExecStart=/usr/bin/archr-touchscreen-keyboard +Restart=always +RestartSec=1 + +[Install] +WantedBy=multi-user.target diff --git a/projects/ArchR/packages/apps/commander/package.mk b/projects/ArchR/packages/apps/commander/package.mk new file mode 100644 index 0000000000..200669d0ea --- /dev/null +++ b/projects/ArchR/packages/apps/commander/package.mk @@ -0,0 +1,31 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2025-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="commander" +PKG_VERSION="a6ef30eb3bd6ef80a031744aae0f5b9cd974c182" +PKG_LICENSE="MIT" +PKG_SITE="https://github.com/od-contrib/commander" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain SDL2 SDL2_image SDL2_gfx SDL2_ttf dejavu" +PKG_LONGDESC="A minimal SDL2 file manager for embedded Linux devices." +PKG_TOOLCHAIN="cmake" + +PKG_CMAKE_OPTS_TARGET+=" -DCMAKE_BUILD_TYPE=Release \ + -DWITH_SYSTEM_SDL_TTF=ON \ + -DWITH_SYSTEM_SDL_GFX=ON \ + -DAUTOSCALE=0 \ + -DAUTOSCALE_DPI=0 \ + -DPPU_X=2 \ + -DPPU_Y=2 \ + -DCMDR_GAMEPAD_OPEN=ControllerButton::A \ + -DCMDR_GAMEPAD_PARENT=ControllerButton::B" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + mkdir -p ${INSTALL}/usr/share/commander + + cp -rf ${PKG_BUILD}/.${TARGET_NAME}/commander ${INSTALL}/usr/bin/ + cp -rf ${PKG_BUILD}/res ${INSTALL}/usr/share/commander/res + + chmod 0755 ${INSTALL}/usr/bin/commander +} diff --git a/projects/ArchR/packages/apps/commander/patches/000-dark-theme.patch b/projects/ArchR/packages/apps/commander/patches/000-dark-theme.patch new file mode 100644 index 0000000000..4561001d0a --- /dev/null +++ b/projects/ArchR/packages/apps/commander/patches/000-dark-theme.patch @@ -0,0 +1,34 @@ +diff --git a/def.h b/def.h +index 231e052..05de582 100755 +--- a/def.h ++++ b/def.h +@@ -36,17 +36,17 @@ + #define DIALOG_BORDER 2 + #define DIALOG_PADDING 8 + // Colors +-#define COLOR_TITLE_BG 102, 85, 74 +-#define COLOR_KEY 255, 0, 255 +-#define COLOR_TEXT_NORMAL 70, 27, 10 +-#define COLOR_TEXT_TITLE 233, 229, 227 +-#define COLOR_TEXT_DIR 75, 70, 164 +-#define COLOR_TEXT_SELECTED 255, 0, 0 +-#define COLOR_CURSOR_1 232, 152, 80 +-#define COLOR_CURSOR_2 232, 201, 173 +-#define COLOR_BG_1 255, 255, 255 +-#define COLOR_BG_2 232, 228, 224 +-#define COLOR_BORDER 102, 85, 74 +-#define COLOR_BORDER_ERROR 128, 55, 55 ++#define COLOR_TITLE_BG 40, 44, 52 // Dark slate gray ++#define COLOR_KEY 198, 120, 221 // Soft purple ++#define COLOR_TEXT_NORMAL 171, 178, 191 // Light gray-blue ++#define COLOR_TEXT_TITLE 255, 255, 255 // White ++#define COLOR_TEXT_DIR 97, 175, 239 // Soft blue ++#define COLOR_TEXT_SELECTED 224, 108, 117 // Soft red ++#define COLOR_CURSOR_1 80, 80, 80 // Charcoal gray ++#define COLOR_CURSOR_2 100, 100, 100 // Slightly lighter gray ++#define COLOR_BG_1 30, 34, 40 // Main dark background ++#define COLOR_BG_2 36, 40, 48 // Slightly lighter background ++#define COLOR_BORDER 56, 60, 72 // Subtle borders ++#define COLOR_BORDER_ERROR 191, 97, 106 // Muted red + + #endif // _DEF_H_ diff --git a/projects/ArchR/packages/apps/commander/patches/001-default-paths.patch b/projects/ArchR/packages/apps/commander/patches/001-default-paths.patch new file mode 100644 index 0000000000..bb79afc2be --- /dev/null +++ b/projects/ArchR/packages/apps/commander/patches/001-default-paths.patch @@ -0,0 +1,18 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 1a36617..b716c6a 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -25,10 +25,10 @@ option(USE_SDL2 "Use SDL2 instead of SDL1" ON) + option(WITH_SYSTEM_SDL_GFX "Use system SDL_gfx library" OFF) + option(WITH_SYSTEM_SDL_TTF "Use system SDL_ttf library" OFF) + +-set(RES_DIR \"res/\" CACHE STRING "Resources directory") ++set(RES_DIR \"/usr/share/commander/res/\" CACHE STRING "Resources directory") + set(FILE_SYSTEM \"/dev/mmcblk1p1\" CACHE STRING "Default filesystem (for Disk info)") +-set(PATH_DEFAULT "" CACHE STRING "Default path for the left pane (default: getenv(\"PWD\")") +-set(PATH_DEFAULT_RIGHT "" CACHE STRING "Default path for the right pane (default: getenv(\"HOME\")") ++set(PATH_DEFAULT \"/storage/.config/\" CACHE STRING "Default path for the left pane (default: getenv(\"HOME\")") ++set(PATH_DEFAULT_RIGHT \"/storage/.config/\" CACHE STRING "Default path for the right pane (default: getenv(\"HOME\")") + set(AUTOSCALE 1 CACHE STRING "Auto-detect resolution (maximize on startup if there is a windowing system)") + set(AUTOSCALE_DPI 1 CACHE STRING "Auto-detect DPI scaling factors") + set(WITH_SYSTEM_SDL_TTF OFF CACHE BOOL "Use system sdl_ttf") diff --git a/projects/ArchR/packages/apps/commander/patches/002-build-fix.patch b/projects/ArchR/packages/apps/commander/patches/002-build-fix.patch new file mode 100644 index 0000000000..ca5b5caf18 --- /dev/null +++ b/projects/ArchR/packages/apps/commander/patches/002-build-fix.patch @@ -0,0 +1,13 @@ +diff --git a/image_viewer.cpp b/image_viewer.cpp +index f636344..39d9c87 100644 +--- a/image_viewer.cpp ++++ b/image_viewer.cpp +@@ -213,7 +213,7 @@ bool ImageViewer::keyHold() + } + + #if SDL_VERSION_ATLEAST(2, 0, 0) +-bool CCommander::gamepadHold(SDL_GameController *controller) ++bool ImageViewer::gamepadHold(SDL_GameController *controller) + { + const auto &c = config(); + if (tick(controller, c.gamepad_up) || tick(controller, c.gamepad_left)) return actionUp(); diff --git a/projects/ArchR/packages/apps/control-gen/Makefile b/projects/ArchR/packages/apps/control-gen/Makefile new file mode 100644 index 0000000000..2cbe7e5c77 --- /dev/null +++ b/projects/ArchR/packages/apps/control-gen/Makefile @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +CXX ?= gcc +CCFLAGS = -W -Wall -std=c++11 `sdl2-config --cflags` + +BINARY = control-gen +LIBRARIES = -lSDL2 +SOURCES = "control-gen.cpp" + +all: + $(CXX) $(CFLAGS) $(SOURCES) -o $(BINARY) $(LIBRARIES) + +clean: + rm -f $(BINARY) diff --git a/projects/ArchR/packages/apps/control-gen/control-gen.cpp b/projects/ArchR/packages/apps/control-gen/control-gen.cpp new file mode 100644 index 0000000000..3c06b15215 --- /dev/null +++ b/projects/ArchR/packages/apps/control-gen/control-gen.cpp @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +#include +#include +#include + +int main() +{ + + SDL_GameControllerAddMappingsFromFile("/storage/.config/SDL-GameControllerDB/gamecontrollerdb.txt"); + SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER); + atexit(SDL_Quit); + + int num_joysticks = SDL_NumJoysticks(); + int i; + for(i = 0; i < num_joysticks; ++i) + { + SDL_Joystick* js = SDL_JoystickOpen(i); + if (js) + { + SDL_JoystickGUID guid = SDL_JoystickGetGUID(js); + bool is_controller = SDL_IsGameController(i); + + char guid_str[1024]; + SDL_JoystickGetGUIDString(guid, guid_str, sizeof(guid_str)); + if (is_controller) + { + const char* name = SDL_JoystickName(js); + + printf("controlfolder=\"/storage/.config/gptokeyb\"\nESUDO=\"sudo\"\nESUDOKILL=\"-sudokill\"\nexport SDL_GAMECONTROLLERCONFIG_FILE=\"$controlfolder/gamecontrollerdb.txt\"\nSDLDBFILE=\"${SDL_GAMECONTROLLERCONFIG_FILE}\"\n[ -z \"${SDLDBFILE}\" ] && SDLDBFILE=\"${controlfolder}/gamecontrollerdb.txt\"\nSDLDBUSERFILE=\"/storage/.config/SDL-GameControllerDB/gamecontrollerdb.txt\"\nget_controls() {\nANALOGSTICKS=\"2\"\nDEVICE=\"%s\"\nparam_device=\"%s\"\n}\nGPTOKEYB=\"$controlfolder/gptokeyb $ESUDOKILL\"", + guid_str, name); + } + SDL_JoystickClose(js); + } + } + + return 0; +} diff --git a/projects/ArchR/packages/apps/control-gen/package.mk b/projects/ArchR/packages/apps/control-gen/package.mk new file mode 100644 index 0000000000..99adf811b8 --- /dev/null +++ b/projects/ArchR/packages/apps/control-gen/package.mk @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="control-gen" +PKG_VERSION="ea44ab254d09d2d86eeb70289673418df2beee75" +PKG_LICENSE="GPLv2" +PKG_DEPENDS_TARGET="toolchain SDL2" +PKG_LONGDESC="Generates control.txt for gptokeyb" +PKG_TOOLCHAIN="make" + +pre_make_target() { + cp -f ${PKG_DIR}/Makefile ${PKG_BUILD} + cp -f ${PKG_DIR}/control-gen.cpp ${PKG_BUILD} + CFLAGS+=" -I$(get_build_dir SDL2)/include -D_REENTRANT" +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp ${PKG_BUILD}/control-gen ${INSTALL}/usr/bin + cp -rf ${PKG_DIR}/scripts/* ${INSTALL}/usr/bin + chmod 0755 ${INSTALL}/usr/bin/* +} diff --git a/projects/ArchR/packages/apps/control-gen/scripts/control-gen_init.sh b/projects/ArchR/packages/apps/control-gen/scripts/control-gen_init.sh new file mode 100644 index 0000000000..318bbe196b --- /dev/null +++ b/projects/ArchR/packages/apps/control-gen/scripts/control-gen_init.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +#Check if gptokeyb exists in .config +if [ ! -d "/storage/.config/gptokeyb" ]; then + mkdir -p "/storage/.config/gptokeyb" +fi + +#Link gamecontrollerdb.txt +ln -sf /usr/config/SDL-GameControllerDB/gamecontrollerdb.txt /storage/.config/gptokeyb/gamecontrollerdb.txt + +#Link gptokeyb +ln -sf /usr/bin/gptokeyb /storage/.config/gptokeyb/gptokeyb + +#Run control-gen +/usr/bin/control-gen > /storage/.config/gptokeyb/control.ini diff --git a/projects/ArchR/packages/apps/device-switch/package.mk b/projects/ArchR/packages/apps/device-switch/package.mk new file mode 100644 index 0000000000..a51c4678c9 --- /dev/null +++ b/projects/ArchR/packages/apps/device-switch/package.mk @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="device-switch" +PKG_VERSION="" +PKG_LICENSE="mix" +PKG_DEPENDS_TARGET="toolchain" +PKG_SITE="" +PKG_URL="" +PKG_LONGDESC="Support script for switching device dtbs" +PKG_TOOLCHAIN="manual" + +makeinstall_target() { + + mkdir -p ${INSTALL}/usr/bin + cp ${PKG_DIR}/scripts/${DEVICE}/device-switch ${INSTALL}/usr/bin + chmod 0755 ${INSTALL}/usr/bin/* +} diff --git a/projects/ArchR/packages/apps/device-switch/scripts/RK3326/device-switch b/projects/ArchR/packages/apps/device-switch/scripts/RK3326/device-switch new file mode 100644 index 0000000000..fbc708ec31 --- /dev/null +++ b/projects/ArchR/packages/apps/device-switch/scripts/RK3326/device-switch @@ -0,0 +1,35 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +EXTLCONF=/flash/extlinux/extlinux.conf +EXTLCONFBAK=${EXTLCONF}.orig + +case "$1" in + "") + echo $(cat /sys/firmware/devicetree/base/archr,device_switch/this | tr -d '\0') + ;; + "--options") + echo $(ls /sys/firmware/devicetree/base/archr,device_switch/ | grep -Ev '^(name|this)$') + ;; + *) + DTB=$(cat /sys/firmware/devicetree/base/archr,device_switch/$1 | tr -d '\0').dtb + [[ $? -eq 0 ]] || { echo "Cannot resolve dtb name for $1" >&2; exit 2; } + [ -f "/flash/${DTB}" ] || { echo "dtb not found: /flash/${DTB}"; exit 3; } + + mount -o remount,rw /flash + + [ -f ${EXTLCONFBAK} ] || cp ${EXTLCONF} ${EXTLCONFBAK} + grep -q '^ *FDT ' ${EXTLCONF} || sed -i 's|^\(.* FDTDIR .*$\)|\1\n FDT todo.dtb|' ${EXTLCONF} + sed -i "s|^ *FDT .*$| FDT /${DTB}|" ${EXTLCONF} + + echo $1 > /flash/device.name + rm -r /storage/remappings/* + + sync + mount -o remount,ro /flash + ;; +esac + diff --git a/projects/ArchR/packages/apps/device-switch/scripts/RK3326/device-switch.save b/projects/ArchR/packages/apps/device-switch/scripts/RK3326/device-switch.save new file mode 100644 index 0000000000..afb5b818b1 --- /dev/null +++ b/projects/ArchR/packages/apps/device-switch/scripts/RK3326/device-switch.save @@ -0,0 +1,20 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +mount -o remount,rw /flash +case $1 in + R33S) + sed -i "s#rk3566-rg353v-linux.dtb#rk3566-rg353p-linux.dtb#g" /flash/extlinux/extlinux.conf + ;; + R36S) + sed -i "s#rk3566-rg353p-linux.dtb#rk3566-rg353v-linux.dtb#g" /flash/extlinux/extlinux.conf + ;; +esac + +set_setting system.hostname ${1} + +sync +reboot diff --git a/projects/ArchR/packages/apps/fileman/package.mk b/projects/ArchR/packages/apps/fileman/package.mk new file mode 100644 index 0000000000..f47e9397f1 --- /dev/null +++ b/projects/ArchR/packages/apps/fileman/package.mk @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2021-present 351ELEC (https://github.com/351elec) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="fileman" +PKG_VERSION="6be2347233dc331dfd4eb57ea36289036933fe64" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/archr-linux/fileman" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain SDL2 SDL2_image SDL2_gfx SDL2_ttf" +PKG_LONGDESC="A Single panel file Manager." + +make_target() { + MAKEDEVICE=$(echo ${DEVICE^^} | sed "s#-#_##g") + make DEVICE=${MAKEDEVICE^^} RES_PATH=/usr/share/fileman/res START_PATH=/storage/roms SDL2_CONFIG=${SYSROOT_PREFIX}/usr/bin/sdl2-config CC=${CXX} +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + mkdir -p ${INSTALL}/usr/share/fileman + cp fileman ${INSTALL}/usr/bin/ + cp -rf res ${INSTALL}/usr/share/fileman/ + chmod 0755 ${INSTALL}/usr/bin/fileman +} diff --git a/projects/ArchR/packages/apps/gamecontrollerdb/config/gamecontrollerdb.txt b/projects/ArchR/packages/apps/gamecontrollerdb/config/gamecontrollerdb.txt new file mode 100644 index 0000000000..c629c6258e --- /dev/null +++ b/projects/ArchR/packages/apps/gamecontrollerdb/config/gamecontrollerdb.txt @@ -0,0 +1,26 @@ +1900fcf27a65645f6a6f797374696300,zed_joystick,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b8,start:b9,dpleft:b15,dpdown:b14,dpright:b16,dpup:b13,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a2,righty:a3, +03002758091200000031000011010000,OpenSimHardware OSH PB Controller,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b7,start:b6,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b10,rightshoulder:b5,righttrigger:b11,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3, +19000226010000000100000001010000,odroidgo2_joypad,platform:Linux,x:b2,a:b1,b:b0,y:b3,back:b10,start:b13,dpleft:b8,dpdown:b7,dpright:b9,dpup:b6,leftshoulder:b4,lefttrigger:b11,rightshoulder:b5,righttrigger:b12,leftx:a0,lefty:a1, +1900dea8010000000200000001010000,odroidgo2_v11_joypad,platform:Linux,x:b2,a:b1,b:b0,y:b3,back:b8,start:b9,dpleft:b14,dpdown:b13,dpright:b15,dpup:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1, +03009b4d4b4800000111000000010000,retrogame_joypad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b8,start:b9,dpleft:b15,dpdown:b14,dpright:b16,dpup:b13,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a2,righty:a3, +19009b4d4b4800000111000000010000,retrogame_joypad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b8,guide:b10,start:b9,dpleft:b15,dpdown:b14,dpright:b16,dpup:b13,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a2,righty:a3, +1900adda4b4800001211000000010000,retrogame_joypad_s1_f2,platform:Linux,x:b2,a:b1,b:b0,y:b3,back:b8,guide:b10,start:b9,dpleft:b15,dpdown:b14,dpright:b16,dpup:b13,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a2,righty:a3, +19009321b0c300000002000010000000,XU10 Gamepad,platform:Linux,x:b3,a:b2,b:b1,y:b0,back:b8,guide:b16,start:b9,dpleft:b14,dpdown:b13,dpright:b15,dpup:b12,leftshoulder:b4,lefttrigger:b7,rightshoulder:b5,righttrigger:b6,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3, +190014b301000000a20a000000010000,r33s_joypad,platform:Linux,x:b2,a:b1,b:b0,y:b3,back:b8,start:b9,dpleft:b12,dpdown:b11,dpright:b13,dpup:b10,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7, +1900e5914b4800007711000077010000,RGB20S Gamepad,platform:Linux,x:b2,a:b1,b:b0,y:b3,back:b12,start:b13,dpleft:b10,dpdown:b9,dpright:b11,dpup:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b14,rightstick:b15,leftx:a0,lefty:a1,rightx:a2,righty:a3, +1900e7444b4800000111000034020000,rg552_joypad,platform:Linux,x:b2,a:b1,b:b0,y:b3,back:b8,start:b9,dpleft:b15,dpdown:b14,dpright:b16,dpup:b13,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a2,righty:a3, +03001a3447616d65466f726365204100,GameForce ACE Gamepad,a:b1,b:b0,dpdown:b13,dpleft:b14,lefty:a1,leftx:a0,leftshoulder:b5,leftstick:b10,lefttrigger:-a2,dpright:b15,+righty:+a4,-rightx:-a3,+rightx:+a3,-righty:-a4,rightshoulder:b6,rightstick:b11,righttrigger:-a5,back:b7,guide:b9,start:b8,dpup:b12,x:b3,y:b4,platform:Linux, +1900c3ea010000000100000001010000,odroidgo3_joypad,a:b1,b:b0,dpdown:b13,dpleft:b14,+lefty:+a1,-leftx:-a0,+leftx:+a0,-lefty:-a1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,dpright:b15,+righty:+a3,-rightx:-a2,+rightx:+a2,-righty:-a3,rightshoulder:b5,rightstick:b11,righttrigger:b7,back:b8,start:b9,dpup:b12,x:b2,y:b3,platform:Linux, +03001354474f2d556c74726120476100,GO-Ultra Gamepad,platform:Linux,a:b1,b:b0,dpdown:b15,dpleft:b16,guide:b11,+lefty:+a1,-leftx:-a0,+leftx:+a0,-lefty:-a1,leftshoulder:b5,leftstick:b12,lefttrigger:b7,dpright:b17,+righty:+a3,-rightx:-a2,+rightx:+a2,-righty:-a3,rightshoulder:b6,rightstick:b13,righttrigger:b8,back:b9,start:b10,dpup:b14,x:b3,y:b4, +1900d632010000002c0a000000010000,rg_arc_joypad,platform:Linux,x:b4,a:b0,b:b1,y:b3,back:b10,start:b11,dpleft:b14,dpdown:b13,dpright:b15,dpup:b12,leftshoulder:b6,lefttrigger:b8,rightshoulder:b7,righttrigger:b9,rightstick:b2,leftstick:b5,platform:Linux, +0300879bfeca00000550000011010000,CM5 Gamepad,platform:Linux,a:b0,b:b1,x:b2,y:b3,back:b5,guide:b14,start:b4,leftstick:b12,rightstick:b13,leftshoulder:b11,rightshoulder:b10,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7, +1900c3bbb0c300000002000010000000,XU Mini M Gamepad,platform:Linux,x:b2,a:b1,b:b0,y:b3,back:b8,guide:b16,start:b9,dpleft:b14,dpdown:b13,dpright:b15,dpup:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3, +0300f353202000000130000001000000,Retroid Pocket Gamepad,platform:Linux,x:b2,a:b1,b:b0,y:b3,back:b6,guide:b8,start:b7,dpleft:b13,dpdown:b12,dpright:b14,dpup:b11,leftshoulder:b4,lefttrigger:a6,rightshoulder:b5,righttrigger:a7,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,misc1:b15, +19003982010000008811000088010000,r36s_Gamepad,platform:Linux,a:b1,b:b0,dpdown:b14,dpleft:b15,+lefty:+a1,-leftx:-a0,+leftx:+a0,-lefty:-a1,leftshoulder:b4,leftstick:b11,lefttrigger:b6,dpright:b16,+righty:+a3,-rightx:-a2,+rightx:+a2,-righty:-a3,rightshoulder:b5,rightstick:b12,righttrigger:b7,back:b8,start:b9,dpup:b13,x:b2,y:b3, +1900f6a24b480000df14000000010000,H700 Gamepad,platform:Linux,x:b3,a:b1,b:b0,y:b2,back:b8,guide:b10,start:b9,dpleft:b15,dpdown:b14,dpright:b16,dpup:b13,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a2,righty:a3, +0300b605202000000130000001000000,AYN Odin2 Gamepad,platform:Linux,x:b2,a:b1,b:b0,y:b3,back:b6,guide:b8,start:b7,dpleft:b13,dpdown:b12,dpright:b14,dpup:b11,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4, +1900365541594e204f64696e20476100,AYN Odin Gamepad,platform:Linux,x:b2,a:b1,b:b0,y:b3,back:b8,guide:b10,start:b9,dpleft:b15,dpdown:b14,dpright:b16,dpup:b13,leftshoulder:b4,lefttrigger:a5,rightshoulder:b5,righttrigger:a4,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a2,righty:a3, +030081b85e0400008e02000000020000,Xbox 360 Controller,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4, + +#InputPlumber Controller +0300f5a35e040000120b000001000000,InputPlumber GameController,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,misc1:b15,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4, diff --git a/projects/ArchR/packages/apps/gamecontrollerdb/package.mk b/projects/ArchR/packages/apps/gamecontrollerdb/package.mk new file mode 100644 index 0000000000..18793bf68a --- /dev/null +++ b/projects/ArchR/packages/apps/gamecontrollerdb/package.mk @@ -0,0 +1,19 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="gamecontrollerdb" +PKG_VERSION="e1efb4bad8730b2c0c6316617cbd06b9def1192e" +PKG_LICENSE="GPL" +PKG_DEPENDS_TARGET="toolchain SDL2" +PKG_SITE="https://github.com/gabomdq/SDL_GameControllerDB" +PKG_URL="${PKG_SITE}.git" +PKG_LONGDESC="SDL Game Controller DB" +PKG_TOOLCHAIN="manual" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/config/SDL-GameControllerDB + if [ -f "${PKG_DIR}/config/gamecontrollerdb.txt" ]; then + cat ${PKG_DIR}/config/gamecontrollerdb.txt >${INSTALL}/usr/config/SDL-GameControllerDB/gamecontrollerdb.txt + fi + cat ${PKG_BUILD}/gamecontrollerdb.txt >>${INSTALL}/usr/config/SDL-GameControllerDB/gamecontrollerdb.txt +} diff --git a/projects/ArchR/packages/apps/gamepadtester/package.mk b/projects/ArchR/packages/apps/gamepadtester/package.mk new file mode 100644 index 0000000000..8c6cc7f39d --- /dev/null +++ b/projects/ArchR/packages/apps/gamepadtester/package.mk @@ -0,0 +1,31 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="gamepadtester" +PKG_VERSION="6ac49e67aa98fe3dd5c27f73306d65d4b7a82daa" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/timre13/GamepadTester" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain SDL2 SDL2_gfx gamecontrollerdb" +PKG_LONGDESC="A simple SDL GUI Gamepad tester" +PKG_TOOLCHAIN="cmake" +PKG_PATCH_DIRS+="${DEVICE}" + +case ${DEVICE} in + SM8650|SM8550) + PKG_PATCH_DIRS+=" xbox" + ;; + *) + PKG_PATCH_DIRS+=" legacy" + ;; +esac + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp -rf ${PKG_BUILD}/.${TARGET_NAME}/gamepad_test ${INSTALL}/usr/bin/gamepad-tester + chmod 0755 ${INSTALL}/usr/bin/gamepad-tester + + mkdir -p ${INSTALL}/usr/config/modules + cp -rf ${PKG_DIR}/scripts/* ${INSTALL}/usr/config/modules + chmod 0755 ${INSTALL}/usr/config/modules/* +} diff --git a/projects/ArchR/packages/apps/gamepadtester/patches/RK3399/000-set-resolution.patch b/projects/ArchR/packages/apps/gamepadtester/patches/RK3399/000-set-resolution.patch new file mode 100644 index 0000000000..8c6ffab599 --- /dev/null +++ b/projects/ArchR/packages/apps/gamepadtester/patches/RK3399/000-set-resolution.patch @@ -0,0 +1,14 @@ +diff -rupN GamepadTester.orig/src/main.cpp GamepadTester/src/main.cpp +--- GamepadTester.orig/src/main.cpp 2024-04-26 21:31:53.731460755 +0000 ++++ GamepadTester/src/main.cpp 2024-04-26 22:29:53.239175112 +0000 +@@ -5,8 +5,8 @@ + #include + + #define STICK_MAX_VAL (float(0x7fff)) +-#define WIN_W 1100 +-#define WIN_H 800 ++#define WIN_W 1920 ++#define WIN_H 1152 + + std::string cStringToStdString(const char* str, const std::string& or_="N/A") + { diff --git a/projects/ArchR/packages/apps/gamepadtester/patches/RK3588/000-set-resolution.patch b/projects/ArchR/packages/apps/gamepadtester/patches/RK3588/000-set-resolution.patch new file mode 100644 index 0000000000..6ca1fc8f89 --- /dev/null +++ b/projects/ArchR/packages/apps/gamepadtester/patches/RK3588/000-set-resolution.patch @@ -0,0 +1,14 @@ +diff -rupN GamepadTester.orig/src/main.cpp GamepadTester/src/main.cpp +--- GamepadTester.orig/src/main.cpp 2024-04-26 21:31:53.731460755 +0000 ++++ GamepadTester/src/main.cpp 2024-04-26 22:30:25.679908246 +0000 +@@ -5,8 +5,8 @@ + #include + + #define STICK_MAX_VAL (float(0x7fff)) +-#define WIN_W 1100 +-#define WIN_H 800 ++#define WIN_W 1920 ++#define WIN_H 1080 + + std::string cStringToStdString(const char* str, const std::string& or_="N/A") + { diff --git a/projects/ArchR/packages/apps/gamepadtester/patches/legacy/000-gamepad-tester.patch b/projects/ArchR/packages/apps/gamepadtester/patches/legacy/000-gamepad-tester.patch new file mode 100644 index 0000000000..1f1fe71582 --- /dev/null +++ b/projects/ArchR/packages/apps/gamepadtester/patches/legacy/000-gamepad-tester.patch @@ -0,0 +1,118 @@ +diff -rupN GamepadTester.orig/CMakeLists.txt GamepadTester/CMakeLists.txt +--- GamepadTester.orig/CMakeLists.txt 2024-04-26 21:31:53.727460671 +0000 ++++ GamepadTester/CMakeLists.txt 2024-04-26 21:30:53.862216932 +0000 +@@ -6,7 +6,6 @@ set(CMAKE_CXX_STANDARD_REQUIRED TRUE) + project(gamepad_test VERSION 1.0) + + link_libraries(SDL2 SDL2_gfx) +-include_directories(/usr/include/SDL2) + + set(CMAKE_CXX_FLAGS "\ + -D_REENTRANT\ +diff -rupN GamepadTester.orig/src/main.cpp GamepadTester/src/main.cpp +--- GamepadTester.orig/src/main.cpp 2024-04-26 21:31:53.731460755 +0000 ++++ GamepadTester/src/main.cpp 2024-04-26 22:27:08.203425064 +0000 +@@ -38,7 +38,7 @@ int main() + SDL_Renderer* rend = SDL_CreateRenderer(window, 0, 0); + gfxPrimitivesSetFont(gfxPrimitivesFontdata, 8, 8); + +- SDL_GameControllerAddMappingsFromFile("../gamecontrollerdb.txt"); ++ SDL_GameControllerAddMappingsFromFile("/storage/.config/SDL-GameControllerDB/gamecontrollerdb.txt"); + + SDL_GameController* gcont = nullptr; + StickState leftStickState{}; +@@ -74,7 +74,6 @@ int main() + + case SDL_CONTROLLERBUTTONDOWN: + std::cout << "Controller button down: " << +event.cbutton.button << '\n'; +- SDL_GameControllerRumble(gcont, 0, 0xffff/2, 200); + buttonStates[event.cbutton.button] = true; + break; + +@@ -83,16 +82,6 @@ int main() + buttonStates[event.cbutton.button] = false; + break; + +- case SDL_JOYBUTTONDOWN: +- if (event.jbutton.button == 8) +- buttonStates[SDL_CONTROLLER_BUTTON_GUIDE] = true; +- break; +- +- case SDL_JOYBUTTONUP: +- if (event.jbutton.button == 8) +- buttonStates[SDL_CONTROLLER_BUTTON_GUIDE] = false; +- break; +- + case SDL_CONTROLLERAXISMOTION: + std::cout << "Controller axis movement\n"; + std::cout << "\tAxis: " << +event.caxis.axis << '\n'; +@@ -153,45 +142,57 @@ int main() + filledCircleColor(rend, WIN_W-300+rightStickState.x*30, WIN_H-300+rightStickState.y*30, 30, + (buttonStates[SDL_CONTROLLER_BUTTON_RIGHTSTICK] ? 0xffffffff : 0)); + +- // Y button ++ // X button + aacircleRGBA(rend, WIN_W-300, 300-40, 20, 255, 255, 0, 255); +- if (buttonStates[SDL_CONTROLLER_BUTTON_Y]) ++ if (buttonStates[SDL_CONTROLLER_BUTTON_X]) + filledCircleRGBA(rend, WIN_W-300, 300-40, 20, 255, 255, 0, 255); + +- // X button ++ // Y button + aacircleRGBA(rend, WIN_W-300-40, 300+40-40, 20, 100, 100, 255, 255); +- if (buttonStates[SDL_CONTROLLER_BUTTON_X]) ++ if (buttonStates[SDL_CONTROLLER_BUTTON_Y]) + filledCircleRGBA(rend, WIN_W-300-40, 300+40-40, 20, 100, 100, 255, 255); + +- // B button ++ // A button + aacircleRGBA(rend, WIN_W-300+40, 300+40-40, 20, 255, 0, 0, 255); +- if (buttonStates[SDL_CONTROLLER_BUTTON_B]) ++ if (buttonStates[SDL_CONTROLLER_BUTTON_A]) + filledCircleRGBA(rend, WIN_W-300+40, 300+40-40, 20, 255, 0, 0, 255); + +- // A button ++ // B button + aacircleRGBA(rend, WIN_W-300, 300+80-40, 20, 0, 255, 0, 255); +- if (buttonStates[SDL_CONTROLLER_BUTTON_A]) ++ if (buttonStates[SDL_CONTROLLER_BUTTON_B]) + filledCircleRGBA(rend, WIN_W-300, 300+80-40, 20, 0, 255, 0, 255); + + // D-pad up + aatrigonRGBA(rend, 300, WIN_H-360, 280, WIN_H-320, 320, WIN_H-320, 255, 255, 255, 255); +- if (dpadState & SDL_HAT_UP) ++ if (dpadState & SDL_HAT_UP) { ++ filledTrigonRGBA(rend, 300, WIN_H-360, 280, WIN_H-320, 320, WIN_H-320, 255, 255, 255, 255); ++ } else if (buttonStates[SDL_CONTROLLER_BUTTON_DPAD_UP]) { + filledTrigonRGBA(rend, 300, WIN_H-360, 280, WIN_H-320, 320, WIN_H-320, 255, 255, 255, 255); ++ } + + // D-pad down + aatrigonRGBA(rend, 300, WIN_H-240, 280, WIN_H-280, 320, WIN_H-280, 255, 255, 255, 255); +- if (dpadState & SDL_HAT_DOWN) ++ if (dpadState & SDL_HAT_DOWN) { + filledTrigonRGBA(rend, 300, WIN_H-240, 280, WIN_H-280, 320, WIN_H-280, 255, 255, 255, 255); ++ } else if (buttonStates[SDL_CONTROLLER_BUTTON_DPAD_DOWN]) { ++ filledTrigonRGBA(rend, 300, WIN_H-240, 280, WIN_H-280, 320, WIN_H-280, 255, 255, 255, 255); ++ } + + // D-pad left + aatrigonRGBA(rend, 240, WIN_H-300, 280, WIN_H-320, 280, WIN_H-280, 255, 255, 255, 255); +- if (dpadState & SDL_HAT_LEFT) ++ if (dpadState & SDL_HAT_LEFT) { ++ filledTrigonRGBA(rend, 240, WIN_H-300, 280, WIN_H-320, 280, WIN_H-280, 255, 255, 255, 255); ++ } else if (buttonStates[SDL_CONTROLLER_BUTTON_DPAD_LEFT]) { + filledTrigonRGBA(rend, 240, WIN_H-300, 280, WIN_H-320, 280, WIN_H-280, 255, 255, 255, 255); ++ } + + // D-pad right + aatrigonRGBA(rend, 360, WIN_H-300, 320, WIN_H-320, 320, WIN_H-280, 255, 255, 255, 255); +- if (dpadState & SDL_HAT_RIGHT) ++ if (dpadState & SDL_HAT_RIGHT) { ++ filledTrigonRGBA(rend, 360, WIN_H-300, 320, WIN_H-320, 320, WIN_H-280, 255, 255, 255, 255); ++ } else if (buttonStates[SDL_CONTROLLER_BUTTON_DPAD_RIGHT]) { + filledTrigonRGBA(rend, 360, WIN_H-300, 320, WIN_H-320, 320, WIN_H-280, 255, 255, 255, 255); ++ } + + // Left bumper + rectangleColor(rend, 300-50, 300-150-20, 300+50, 300-150+20, 0xffffffff); diff --git a/projects/ArchR/packages/apps/gamepadtester/patches/xbox/000-gamepad-tester.patch b/projects/ArchR/packages/apps/gamepadtester/patches/xbox/000-gamepad-tester.patch new file mode 100644 index 0000000000..a303cc4f92 --- /dev/null +++ b/projects/ArchR/packages/apps/gamepadtester/patches/xbox/000-gamepad-tester.patch @@ -0,0 +1,102 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 2df8fda..4ae98f1 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -6,7 +6,6 @@ set(CMAKE_CXX_STANDARD_REQUIRED TRUE) + project(gamepad_test VERSION 1.0) + + link_libraries(SDL2 SDL2_gfx) +-include_directories(/usr/include/SDL2) + + set(CMAKE_CXX_FLAGS "\ + -D_REENTRANT\ +diff --git a/src/main.cpp b/src/main.cpp +index 7381b9b..eb25c84 100644 +--- a/src/main.cpp ++++ b/src/main.cpp +@@ -38,7 +38,7 @@ int main() + SDL_Renderer* rend = SDL_CreateRenderer(window, 0, 0); + gfxPrimitivesSetFont(gfxPrimitivesFontdata, 8, 8); + +- SDL_GameControllerAddMappingsFromFile("../gamecontrollerdb.txt"); ++ SDL_GameControllerAddMappingsFromFile("/storage/.config/SDL-GameControllerDB/gamecontrollerdb.txt"); + + SDL_GameController* gcont = nullptr; + StickState leftStickState{}; +@@ -74,7 +74,6 @@ int main() + + case SDL_CONTROLLERBUTTONDOWN: + std::cout << "Controller button down: " << +event.cbutton.button << '\n'; +- SDL_GameControllerRumble(gcont, 0, 0xffff/2, 200); + buttonStates[event.cbutton.button] = true; + break; + +@@ -83,16 +82,6 @@ int main() + buttonStates[event.cbutton.button] = false; + break; + +- case SDL_JOYBUTTONDOWN: +- if (event.jbutton.button == 8) +- buttonStates[SDL_CONTROLLER_BUTTON_GUIDE] = true; +- break; +- +- case SDL_JOYBUTTONUP: +- if (event.jbutton.button == 8) +- buttonStates[SDL_CONTROLLER_BUTTON_GUIDE] = false; +- break; +- + case SDL_CONTROLLERAXISMOTION: + std::cout << "Controller axis movement\n"; + std::cout << "\tAxis: " << +event.caxis.axis << '\n'; +@@ -175,23 +164,35 @@ int main() + + // D-pad up + aatrigonRGBA(rend, 300, WIN_H-360, 280, WIN_H-320, 320, WIN_H-320, 255, 255, 255, 255); +- if (dpadState & SDL_HAT_UP) ++ if (dpadState & SDL_HAT_UP) { ++ filledTrigonRGBA(rend, 300, WIN_H-360, 280, WIN_H-320, 320, WIN_H-320, 255, 255, 255, 255); ++ } else if (buttonStates[SDL_CONTROLLER_BUTTON_DPAD_UP]) { + filledTrigonRGBA(rend, 300, WIN_H-360, 280, WIN_H-320, 320, WIN_H-320, 255, 255, 255, 255); ++ } + + // D-pad down + aatrigonRGBA(rend, 300, WIN_H-240, 280, WIN_H-280, 320, WIN_H-280, 255, 255, 255, 255); +- if (dpadState & SDL_HAT_DOWN) ++ if (dpadState & SDL_HAT_DOWN) { + filledTrigonRGBA(rend, 300, WIN_H-240, 280, WIN_H-280, 320, WIN_H-280, 255, 255, 255, 255); ++ } else if (buttonStates[SDL_CONTROLLER_BUTTON_DPAD_DOWN]) { ++ filledTrigonRGBA(rend, 300, WIN_H-240, 280, WIN_H-280, 320, WIN_H-280, 255, 255, 255, 255); ++ } + + // D-pad left + aatrigonRGBA(rend, 240, WIN_H-300, 280, WIN_H-320, 280, WIN_H-280, 255, 255, 255, 255); +- if (dpadState & SDL_HAT_LEFT) ++ if (dpadState & SDL_HAT_LEFT) { ++ filledTrigonRGBA(rend, 240, WIN_H-300, 280, WIN_H-320, 280, WIN_H-280, 255, 255, 255, 255); ++ } else if (buttonStates[SDL_CONTROLLER_BUTTON_DPAD_LEFT]) { + filledTrigonRGBA(rend, 240, WIN_H-300, 280, WIN_H-320, 280, WIN_H-280, 255, 255, 255, 255); ++ } + + // D-pad right + aatrigonRGBA(rend, 360, WIN_H-300, 320, WIN_H-320, 320, WIN_H-280, 255, 255, 255, 255); +- if (dpadState & SDL_HAT_RIGHT) ++ if (dpadState & SDL_HAT_RIGHT) { + filledTrigonRGBA(rend, 360, WIN_H-300, 320, WIN_H-320, 320, WIN_H-280, 255, 255, 255, 255); ++ } else if (buttonStates[SDL_CONTROLLER_BUTTON_DPAD_RIGHT]) { ++ filledTrigonRGBA(rend, 360, WIN_H-300, 320, WIN_H-320, 320, WIN_H-280, 255, 255, 255, 255); ++ } + + // Left bumper + rectangleColor(rend, 300-50, 300-150-20, 300+50, 300-150+20, 0xffffffff); +@@ -221,6 +222,11 @@ int main() + if (buttonStates[SDL_CONTROLLER_BUTTON_START]) + filledCircleColor(rend, WIN_W/2+40, WIN_H/2, 20, 0xffffffff); + ++ // Misc1 button (Share) ++ aacircleColor(rend, WIN_W/2, WIN_H/2 + 50, 18, 0xffffffff); ++ if (buttonStates[SDL_CONTROLLER_BUTTON_MISC1]) ++ filledCircleColor(rend, WIN_W/2, WIN_H/2 + 50, 18, 0xffffffff); ++ + // Guide button + aacircleColor(rend, WIN_W/2, WIN_H/2-60, 30, 0xffffffff); + if (buttonStates[SDL_CONTROLLER_BUTTON_GUIDE]) diff --git a/projects/ArchR/packages/apps/gamepadtester/scripts/Test Gamepad.sh b/projects/ArchR/packages/apps/gamepadtester/scripts/Test Gamepad.sh new file mode 100644 index 0000000000..9b2f768013 --- /dev/null +++ b/projects/ArchR/packages/apps/gamepadtester/scripts/Test Gamepad.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +source /etc/profile + +set_kill set "gamepad-tester" + +sway_fullscreen "gamepad-tester" & + +/usr/bin/gamepad-tester diff --git a/projects/ArchR/packages/apps/jstest-sdl/package.mk b/projects/ArchR/packages/apps/jstest-sdl/package.mk new file mode 100644 index 0000000000..75a868e383 --- /dev/null +++ b/projects/ArchR/packages/apps/jstest-sdl/package.mk @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2021-present Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="jstest-sdl" +PKG_VERSION="f4fdf6daae687d19b303d8ba8809ff5a68bc33a4" +PKG_LICENSE="MIT" +PKG_SITE="https://github.com/archr-linux/jstest-sdl" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain SDL2 ncurses" +PKG_LONGDESC="Simple SDL joystick test application for the console" +PKG_TOOLCHAIN="make" +GET_HANDLER_SUPPORT="git" + +pre_configure_target() { + sed -i "s|sdl2-config|${SYSROOT_PREFIX}/usr/bin/sdl2-config|g" Makefile +} + +makeinstall_target(){ + mkdir -p ${INSTALL}/usr/bin + cp jstest-sdl ${INSTALL}/usr/bin +} diff --git a/projects/ArchR/packages/apps/jstest-sdl/patches/001-fix-building-with-gcc15.patch b/projects/ArchR/packages/apps/jstest-sdl/patches/001-fix-building-with-gcc15.patch new file mode 100644 index 0000000000..b2ae8cf390 --- /dev/null +++ b/projects/ArchR/packages/apps/jstest-sdl/patches/001-fix-building-with-gcc15.patch @@ -0,0 +1,24 @@ +From a621a74a5099612fbd4a0689aca4dc6ee7b4080f Mon Sep 17 00:00:00 2001 +From: spycat88 +Date: Sun, 16 Nov 2025 15:40:43 +0000 +Subject: [PATCH] fix building with gcc15 + +--- + jstest-sdl.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/jstest-sdl.c b/jstest-sdl.c +index d576029..b76ed08 100644 +--- a/jstest-sdl.c ++++ b/jstest-sdl.c +@@ -44,6 +44,7 @@ + #include + #include + #include ++#include + #include + #include + +-- +2.34.1 + diff --git a/projects/ArchR/packages/apps/list-guid/Makefile b/projects/ArchR/packages/apps/list-guid/Makefile new file mode 100644 index 0000000000..1388448f7c --- /dev/null +++ b/projects/ArchR/packages/apps/list-guid/Makefile @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +CXX ?= gcc +CCFLAGS = -W -Wall -std=c++11 `sdl2-config --cflags` + +BINARY = list-guid +LIBRARIES = -lSDL2 +SOURCES = "list-guid.cpp" + +all: + $(CXX) $(CFLAGS) $(SOURCES) -o $(BINARY) $(LIBRARIES) + +clean: + rm -f $(BINARY) diff --git a/projects/ArchR/packages/apps/list-guid/list-guid.cpp b/projects/ArchR/packages/apps/list-guid/list-guid.cpp new file mode 100644 index 0000000000..5a15f5d5de --- /dev/null +++ b/projects/ArchR/packages/apps/list-guid/list-guid.cpp @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +#include +#include +#include + +int main() +{ + + SDL_GameControllerAddMappingsFromFile("/storage/.config/SDL-GameControllerDB/gamecontrollerdb.txt"); + SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER); + atexit(SDL_Quit); + + int num_joysticks = SDL_NumJoysticks(); + int i; + for(i = 0; i < num_joysticks; ++i) + { + SDL_Joystick* js = SDL_JoystickOpen(i); + if (js) + { + SDL_JoystickGUID guid = SDL_JoystickGetGUID(js); + bool is_controller = SDL_IsGameController(i); + + char guid_str[1024]; + SDL_JoystickGetGUIDString(guid, guid_str, sizeof(guid_str)); + if (is_controller) + { + printf("%s\n", + guid_str); + } + SDL_JoystickClose(js); + } + } + + return 0; +} diff --git a/projects/ArchR/packages/apps/list-guid/package.mk b/projects/ArchR/packages/apps/list-guid/package.mk new file mode 100644 index 0000000000..1c88983718 --- /dev/null +++ b/projects/ArchR/packages/apps/list-guid/package.mk @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="list-guid" +PKG_VERSION="ea44ab254d09d2d86eeb70289673418df2beee75" +PKG_LICENSE="GPLv2" +PKG_DEPENDS_TARGET="toolchain SDL2" +PKG_LONGDESC="Simple SDL tool to create a list off GUIDs for all connected gamepads." +PKG_TOOLCHAIN="make" + +pre_make_target() { + cp -f ${PKG_DIR}/Makefile ${PKG_BUILD} + cp -f ${PKG_DIR}/list-guid.cpp ${PKG_BUILD} + CFLAGS+=" -I$(get_build_dir SDL2)/include -D_REENTRANT" +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp ${PKG_BUILD}/list-guid ${INSTALL}/usr/bin + chmod 0755 ${INSTALL}/usr/bin/* +} diff --git a/projects/ArchR/packages/apps/m8c/config/H700/Anbernic RG CubeXX.ini b/projects/ArchR/packages/apps/m8c/config/H700/Anbernic RG CubeXX.ini new file mode 100644 index 0000000000..dd125a307a --- /dev/null +++ b/projects/ArchR/packages/apps/m8c/config/H700/Anbernic RG CubeXX.ini @@ -0,0 +1,50 @@ +[graphics] +fullscreen=false +use_gpu=true +idle_ms=10 +wait_for_device=true +wait_packets=1024 +[audio] +audio_enabled=false +audio_buffer_size=1024 +audio_device_name=Default +[keyboard] +;Ref: https://wiki.libsdl.org/SDL2/SDL_Scancode +key_up=82 +key_left=80 +key_down=81 +key_right=79 +key_select=225 +key_select_alt=29 +key_start=44 +key_start_alt=27 +key_opt=226 +key_opt_alt=4 +key_edit=224 +key_edit_alt=22 +key_delete=76 +key_reset=21 +key_jazz_inc_octave=85 +key_jazz_dec_octave=84 +key_jazz_inc_velocity=86 +key_jazz_dec_velocity=69 +key_toggle_audio=69 +[gamepad] +gamepad_up=11 +gamepad_left=13 +gamepad_down=12 +gamepad_right=14 +gamepad_select=9 ; L1 +gamepad_start=10 ; R1 +gamepad_opt=0 ; B +gamepad_edit=1 ; A +gamepad_quit=5 ; Menu/Guide +gamepad_reset=7 ; R2 +gamepad_analog_threshold=30000 +gamepad_analog_invert=false +gamepad_analog_axis_updown=1 +gamepad_analog_axis_leftright=0 +gamepad_analog_axis_select=4 +gamepad_analog_axis_start=5 +gamepad_analog_axis_opt=-1 +gamepad_analog_axis_edit=-1 diff --git a/projects/ArchR/packages/apps/m8c/config/H700/Anbernic RG34XX.ini b/projects/ArchR/packages/apps/m8c/config/H700/Anbernic RG34XX.ini new file mode 120000 index 0000000000..4c7e7a42fa --- /dev/null +++ b/projects/ArchR/packages/apps/m8c/config/H700/Anbernic RG34XX.ini @@ -0,0 +1 @@ +Anbernic RG CubeXX.ini \ No newline at end of file diff --git a/projects/ArchR/packages/apps/m8c/config/H700/Anbernic RG40XX H.ini b/projects/ArchR/packages/apps/m8c/config/H700/Anbernic RG40XX H.ini new file mode 120000 index 0000000000..4c7e7a42fa --- /dev/null +++ b/projects/ArchR/packages/apps/m8c/config/H700/Anbernic RG40XX H.ini @@ -0,0 +1 @@ +Anbernic RG CubeXX.ini \ No newline at end of file diff --git a/projects/ArchR/packages/apps/m8c/config/H700/config.ini b/projects/ArchR/packages/apps/m8c/config/H700/config.ini new file mode 100644 index 0000000000..7879affca9 --- /dev/null +++ b/projects/ArchR/packages/apps/m8c/config/H700/config.ini @@ -0,0 +1,50 @@ +[graphics] +fullscreen=false +use_gpu=true +idle_ms=10 +wait_for_device=true +wait_packets=1024 +[audio] +audio_enabled=false +audio_buffer_size=1024 +audio_device_name=Default +[keyboard] +;Ref: https://wiki.libsdl.org/SDL2/SDL_Scancode +key_up=82 +key_left=80 +key_down=81 +key_right=79 +key_select=225 +key_select_alt=29 +key_start=44 +key_start_alt=27 +key_opt=226 +key_opt_alt=4 +key_edit=224 +key_edit_alt=22 +key_delete=76 +key_reset=21 +key_jazz_inc_octave=85 +key_jazz_dec_octave=84 +key_jazz_inc_velocity=86 +key_jazz_dec_velocity=69 +key_toggle_audio=69 +[gamepad] +gamepad_up=11 +gamepad_left=13 +gamepad_down=12 +gamepad_right=14 +gamepad_select=4 ; Select +gamepad_start=6 ; Start +gamepad_opt=0 ; B +gamepad_edit=1 ; A +gamepad_quit=5 ; Menu/Guide +gamepad_reset=7 ; R2 +gamepad_analog_threshold=30000 +gamepad_analog_invert=false +gamepad_analog_axis_updown=1 +gamepad_analog_axis_leftright=0 +gamepad_analog_axis_select=4 +gamepad_analog_axis_start=5 +gamepad_analog_axis_opt=-1 +gamepad_analog_axis_edit=-1 diff --git a/projects/ArchR/packages/apps/m8c/package.mk b/projects/ArchR/packages/apps/m8c/package.mk new file mode 100644 index 0000000000..356ba412ba --- /dev/null +++ b/projects/ArchR/packages/apps/m8c/package.mk @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="m8c" +PKG_VERSION="v1.7.10" +PKG_LICENSE="MIT" +PKG_SITE="https://github.com/laamaa/m8c" +PKG_URL="${PKG_SITE}/archive/refs/tags/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain SDL2 libserialport" +PKG_LONGDESC="Cross-platform M8 tracker headless client" +PKG_TOOLCHAIN="cmake" + +makeinstall_target(){ + # Create directories + mkdir -p ${INSTALL}/usr/bin + mkdir -p ${INSTALL}/usr/config/m8c + mkdir -p ${INSTALL}/usr/config/modules + + cp -f m8c ${INSTALL}/usr/bin + chmod 0755 ${INSTALL}/usr/bin/m8c + + cp -rf ${PKG_DIR}/scripts/* ${INSTALL}/usr/config/modules + chmod 0755 ${INSTALL}/usr/config/modules/* + + if [ -d ${PKG_DIR}/config/${DEVICE} ] + then + cp -ra ${PKG_DIR}/config/${DEVICE}/* ${INSTALL}/usr/config/m8c/ + fi +} diff --git a/projects/ArchR/packages/apps/m8c/patches/0001-update-defaults-config.patch b/projects/ArchR/packages/apps/m8c/patches/0001-update-defaults-config.patch new file mode 100644 index 0000000000..f192924821 --- /dev/null +++ b/projects/ArchR/packages/apps/m8c/patches/0001-update-defaults-config.patch @@ -0,0 +1,32 @@ +From c2b17d28cf8800f3011c3c13492fa836d8c773f3 Mon Sep 17 00:00:00 2001 +From: Philippe Simons +Date: Sat, 28 Dec 2024 10:55:19 +0100 +Subject: [PATCH] update defaults config + +--- + src/config.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/config.c b/src/config.c +index 50848a9..95a36ba 100644 +--- a/src/config.c ++++ b/src/config.c +@@ -23,13 +23,13 @@ config_params_s init_config() { + + c.filename = "config.ini"; // default config file to load + +- c.init_fullscreen = 0; // default fullscreen state at load ++ c.init_fullscreen = 1; // default fullscreen state at load + c.init_use_gpu = 1; // default to use hardware acceleration + c.idle_ms = 10; // default to high performance + c.wait_for_device = 1; // default to exit if device disconnected + c.wait_packets = 1024; // default zero-byte attempts to disconnect (about 2 + // sec for default idle_ms) +- c.audio_enabled = 0; // route M8 audio to default output ++ c.audio_enabled = 1; // route M8 audio to default output + c.audio_buffer_size = 1024; // requested audio buffer size in samples + c.audio_device_name = NULL; // Use this device, leave NULL to use the default output device + +-- +2.47.1 + diff --git a/projects/ArchR/packages/apps/m8c/patches/0002-fix-building-with-gcc15.patch b/projects/ArchR/packages/apps/m8c/patches/0002-fix-building-with-gcc15.patch new file mode 100644 index 0000000000..1a5918406f --- /dev/null +++ b/projects/ArchR/packages/apps/m8c/patches/0002-fix-building-with-gcc15.patch @@ -0,0 +1,42 @@ +From 8e268b3e6501eb9dee62ae7a5d3982210ccd4212 Mon Sep 17 00:00:00 2001 +From: spycat88 +Date: Sun, 16 Nov 2025 15:19:10 +0000 +Subject: [PATCH] fix building with gcc15 + +--- + src/config.h | 2 +- + src/main.c | 5 ++++- + 2 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/src/config.h b/src/config.h +index 0a65907..caa90d5 100644 +--- a/src/config.h ++++ b/src/config.h +@@ -60,7 +60,7 @@ typedef struct config_params_s { + } config_params_s; + + +-config_params_s init_config(); ++config_params_s init_config(char *filename); + void read_config(config_params_s *conf); + void read_audio_config(const ini_t *ini, config_params_s *conf); + void read_graphics_config(const ini_t *ini, config_params_s *conf); +diff --git a/src/main.c b/src/main.c +index d7d60db..09cbd38 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -24,7 +24,10 @@ enum state run = WAIT_FOR_DEVICE; + uint8_t need_display_reset = 0; + + // Handles CTRL+C / SIGINT +-void intHandler() { run = QUIT; } ++void intHandler(int sig) { ++ (void)sig; ++ run = QUIT; ++} + + void close_serial_port() { disconnect(); } + +-- +2.34.1 + diff --git a/projects/ArchR/packages/apps/m8c/scripts/Start M8C.sh b/projects/ArchR/packages/apps/m8c/scripts/Start M8C.sh new file mode 100755 index 0000000000..8e789bd80f --- /dev/null +++ b/projects/ArchR/packages/apps/m8c/scripts/Start M8C.sh @@ -0,0 +1,109 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2021-present 351ELEC + +source /etc/profile + +set_kill set "-9 m8c" + +M8C_DIR="/storage/.local/share/m8c" +M8C_CONF_DIR="/usr/config/m8c" + +if [ ! -d ${M8C_DIR} ]; then + mkdir -p ${M8C_DIR} +fi + +if [ ! -f "${M8C_DIR}/config.ini" ]; then + if [ -f "${M8C_CONF_DIR}/${QUIRK_DEVICE}.ini" ]; then + cp "${M8C_CONF_DIR}/${QUIRK_DEVICE}.ini" "${M8C_DIR}/config.ini" + else + if [ -f "${M8C_CONF_DIR}/config.ini" ]; then + cp "${M8C_CONF_DIR}/config.ini" "${M8C_DIR}/config.ini" + fi + fi +fi + +modprobe cdc-acm +modprobe snd-hwdep +modprobe snd-usbmidi-lib +modprobe snd-usb-audio + +# Arrays to store connections for cleanup +MIDI_CONNECTIONS=() + +#Connect all MIDI ports to Dirtywave in both directions +M8_ID=$(aconnect -iol | awk '/client [0-9]+: .*M8/ {print $2}' | tr -d ':') +M8_PORT="$M8_ID:0" + +DEVICE_IDS=$(aconnect -iol | awk '/client [0-9]+:/ {print $2}' | tr -d ':' | grep -vE "^(0|$M8_ID)$") + +for DEVICE_ID in $DEVICE_IDS; do + DEVICE_PORT="$DEVICE_ID:0" + # Store connections for later cleanup + MIDI_CONNECTIONS+=("$DEVICE_PORT:$M8_PORT") + MIDI_CONNECTIONS+=("$M8_PORT:$DEVICE_PORT") + aconnect "$DEVICE_PORT" "$M8_PORT" + aconnect "$M8_PORT" "$DEVICE_PORT" +done + +#Capture M8 USB Source and Play it out the default audio sink +M8_AUDIO_SOURCE=$(pactl list sources | awk '/Name: alsa_input\.usb-DirtyWave/{print $2}') +pw-loopback -C $M8_AUDIO_SOURCE & + +#Connect each BT Source and Play it to the M8 Sink +BT_SOURCES=$(pactl list | awk -F. '/Name: bluez_card/{print $2}') +M8_AUDIO_SINK=$(pactl list sinks | awk '/Name: alsa_output\.usb-DirtyWave/{print $2}') +for BT_SOURCE in $BT_SOURCES; do + pw-loopback -C bluez_input.$BT_SOURCE.2 -P $M8_AUDIO_SINK & +done + +# Connect each audio source to the M8 Sink, excluding the M8 device itself + +# Get the M8 Audio Sink (your specific USB sink) +M8_AUDIO_SINK=$(pactl list sinks short | awk '/alsa_output\.usb-DirtyWave/{print $2}') + +# List all audio sources, excluding monitor sources +ALL_SOURCES=$(pactl list sources short | awk '$2 !~ /\.monitor/ {print $2}') + +# Loop over each source and connect it to the sink, but skip the M8 device's own source +for SRC in $ALL_SOURCES; do + if [[ "$SRC" == *"usb-DirtyWave"* ]]; then + continue + fi + pw-loopback -C "$SRC" -P "$M8_AUDIO_SINK" & +done + +# Function to cleanup MIDI connections and audio routing +cleanup() { + echo "Cleaning up MIDI connections and audio routing..." + + # Kill all pw-loopback processes + echo "Terminating PipeWire loopback processes..." + kill $(jobs -p) 2>/dev/null + + # Wait a moment for processes to terminate + sleep 1 + + # Force kill any remaining pw-loopback processes + pkill -f pw-loopback 2>/dev/null + + # Disconnect MIDI connections + echo "Disconnecting MIDI connections..." + for connection in "${MIDI_CONNECTIONS[@]}"; do + if [[ "$connection" == *":"* ]]; then + src_port="${connection%:*}" + dst_port="${connection#*:}" + aconnect -d "$src_port" "$dst_port" 2>/dev/null || true + fi + done + + echo "Cleanup completed." +} + +# Set up trap to cleanup on script exit +trap cleanup EXIT + +sway_fullscreen "m8c" & + +/usr/bin/m8c diff --git a/projects/ArchR/packages/apps/mako-osd/mako-notify/Makefile b/projects/ArchR/packages/apps/mako-osd/mako-notify/Makefile new file mode 100644 index 0000000000..c30404b6c4 --- /dev/null +++ b/projects/ArchR/packages/apps/mako-osd/mako-notify/Makefile @@ -0,0 +1,11 @@ +CXX ?= g++ +CCFLAGS = -W -Wall -std=c++11 `pkg-config --cflags dbus-1` +BINARY := mako-notify +LIBRARIES = `pkg-config --libs dbus-1` +SOURCES := mako-notify.cpp + +all: + $(CXX) $(CCFLAGS) $(SOURCES) -o $(BINARY) $(LIBRARIES) + +clean: + rm -f $(BINARY) diff --git a/projects/ArchR/packages/apps/mako-osd/mako-notify/mako-notify.cpp b/projects/ArchR/packages/apps/mako-osd/mako-notify/mako-notify.cpp new file mode 100644 index 0000000000..b25ccdaef0 --- /dev/null +++ b/projects/ArchR/packages/apps/mako-osd/mako-notify/mako-notify.cpp @@ -0,0 +1,174 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2026-present ArchR (https://github.com/archr-linux/Arch-R) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const std::string CONFIG_DIR = "/storage/.config/mako"; +const std::string CONFIG_FILE = CONFIG_DIR + "/config"; + +void ensure_mako_config() { + // Check if directory exists + struct stat st{}; + if (stat(CONFIG_DIR.c_str(), &st) != 0) { + // Directory does not exist, create it + if (mkdir(CONFIG_DIR.c_str(), 0755) != 0) { + perror("Failed to create config directory"); + return; + } + } + + // Check if file exists + if (stat(CONFIG_FILE.c_str(), &st) != 0) { + // File does not exist, create it with default contents + std::ofstream ofs(CONFIG_FILE); + if (!ofs) { + std::cerr << "Failed to create config file at " << CONFIG_FILE << std::endl; + return; + } + + ofs << +"max-visible=1\n" +"layer=overlay\n" +"font=monospace 30\n" +"text-color=#ffffff\n" +"text-alignment=center\n" +"background-color=#000000\n" +"border-size=0\n" +"border-radius=10\n" +"default-timeout=1500\n" +"anchor=top-center\n" +"width=500\n"; + + ofs.close(); + } +} + +// Check focused app function +std::string get_focused_app() { + std::string result; + std::array buffer; + std::unique_ptr pipe( + popen("swaymsg -t get_tree | jq -r '.. | select(.focused?) | .app_id'", "r"), + [](FILE* f){ if(f) pclose(f); } + ); + if (!pipe) return ""; + while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) { + result += buffer.data(); + } + if (!result.empty() && result.back() == '\n') result.pop_back(); + return result; +} + +int main(int argc, char* argv[]) { + if (argc < 2) { + std::cerr << "Usage: " << argv[0] << " " << std::endl; + std::cerr << "Example: " << argv[0] << " \"Hello World\"" << std::endl; + return 1; + } + + // check for -no-es / -no-ra option + bool no_es_flag = false; + bool no_ra_flag = false; + for (int i = 2; i < argc; ++i) { + if (std::string(argv[i]) == "-no-es") { + no_es_flag = true; + } + if (std::string(argv[i]) == "-no-ra") { + no_ra_flag = true; + } + } + + if (no_es_flag || no_ra_flag) { + std::string focused_app = get_focused_app(); + // skip notification if -no-es and EmulationStation focused + if (no_es_flag && focused_app == "emulationstation") { + return 0; + } + // skip notification if -no-ra and Retorarch focused + if (no_ra_flag && focused_app == "com.libretro.RetroArch") { + return 0; + } + } + + // Ensure the Mako config exists + ensure_mako_config(); + + DBusError err; + dbus_error_init(&err); + + // Connect to the session bus + DBusConnection* conn = dbus_bus_get(DBUS_BUS_SESSION, &err); + if (dbus_error_is_set(&err)) { + std::cerr << "Connection Error: " << err.message << std::endl; + dbus_error_free(&err); + return 1; + } + if (!conn) return 1; + + // Create a method call + DBusMessage* msg = dbus_message_new_method_call( + "org.freedesktop.Notifications", // destination + "/org/freedesktop/Notifications", // object path + "org.freedesktop.Notifications", // interface + "Notify" // method + ); + + if (!msg) { + std::cerr << "Message Null" << std::endl; + return 1; + } + + // Build arguments + DBusMessageIter args; + dbus_message_iter_init_append(msg, &args); + + const char* app_name = "mako-notify"; + uint32_t replaces_id = 0; + const char* icon = ""; + const char* summary = argv[1]; + const char* body = argv[1]; + int32_t timeout = 2000; + + dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &app_name); + dbus_message_iter_append_basic(&args, DBUS_TYPE_UINT32, &replaces_id); + dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &icon); + dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &summary); + dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &body); + + // empty array of actions + DBusMessageIter array_iter; + dbus_message_iter_open_container(&args, DBUS_TYPE_ARRAY, "s", &array_iter); + dbus_message_iter_close_container(&args, &array_iter); + + // empty dictionary for hints + DBusMessageIter dict_iter; + dbus_message_iter_open_container(&args, DBUS_TYPE_ARRAY, "{sv}", &dict_iter); + dbus_message_iter_close_container(&args, &dict_iter); + + dbus_message_iter_append_basic(&args, DBUS_TYPE_INT32, &timeout); + + // Send message + DBusPendingCall* pending = nullptr; + if (!dbus_connection_send_with_reply(conn, msg, &pending, -1)) { + std::cerr << "Failed to send message" << std::endl; + return 1; + } + + dbus_connection_flush(conn); + dbus_message_unref(msg); + + // Wait for reply + if (pending) dbus_pending_call_block(pending); + if (pending) dbus_pending_call_unref(pending); + + return 0; +} diff --git a/projects/ArchR/packages/apps/mako-osd/mako-notify/package.mk b/projects/ArchR/packages/apps/mako-osd/mako-notify/package.mk new file mode 100644 index 0000000000..20ed24065a --- /dev/null +++ b/projects/ArchR/packages/apps/mako-osd/mako-notify/package.mk @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2026-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="mako-notify" +PKG_VERSION="v1.0" +PKG_LICENSE="GPLv2" +PKG_DEPENDS_TARGET="toolchain dbus" +PKG_LONGDESC="Tool to show onscreen messages in sway, via the mako-osd tool" +PKG_TOOLCHAIN="make" + +pre_make_target() { + cp -f ${PKG_DIR}/Makefile ${PKG_BUILD} + cp -f ${PKG_DIR}/mako-notify.cpp ${PKG_BUILD} + CFLAGS+=" -D_REENTRANT" +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp -r ${PKG_BUILD}/mako-notify ${INSTALL}/usr/bin + chmod +x ${INSTALL}/usr/bin +} diff --git a/projects/ArchR/packages/apps/mako-osd/package.mk b/projects/ArchR/packages/apps/mako-osd/package.mk new file mode 100644 index 0000000000..555a535b8f --- /dev/null +++ b/projects/ArchR/packages/apps/mako-osd/package.mk @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2026-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="mako-osd" +PKG_VERSION="b131bc143f6b0f24d650f16bb88a11c7cb011c20" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/emersion/mako" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain cairo wayland sway pango glib mako-notify" +PKG_LONGDESC="Meso - A lightweight notification daemon for Wayland. Works on Sway." +PKG_TOOLCHAIN="meson" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp -r ${PKG_BUILD}/.${TARGET_NAME}/mako ${INSTALL}/usr/bin + cp -r ${PKG_BUILD}/.${TARGET_NAME}/makoctl ${INSTALL}/usr/bin + chmod +x ${INSTALL}/usr/bin +} diff --git a/projects/ArchR/packages/apps/mako-osd/patches/000-disable-placeholder-text.patch b/projects/ArchR/packages/apps/mako-osd/patches/000-disable-placeholder-text.patch new file mode 100644 index 0000000000..f1497c2341 --- /dev/null +++ b/projects/ArchR/packages/apps/mako-osd/patches/000-disable-placeholder-text.patch @@ -0,0 +1,22 @@ +diff --git a/render.c b/render.c +index 8fed6d8..b157323 100644 +--- a/render.c ++++ b/render.c +@@ -438,7 +438,7 @@ void render(struct mako_surface *surface, struct pool_buffer *buffer, int scale, + ++visible_count; + } + } +- ++/* + if (hidden_count > 0) { + struct mako_notification *hidden_notif = create_notification(state); + hidden_notif->surface = surface; +@@ -478,7 +478,7 @@ void render(struct mako_surface *surface, struct pool_buffer *buffer, int scale, + } + destroy_notification(hidden_notif); + } +- ++*/ + *rendered_width = max_width; + *rendered_height = total_height; + } diff --git a/projects/ArchR/packages/apps/mangohud/config/MangoHud.conf b/projects/ArchR/packages/apps/mangohud/config/MangoHud.conf new file mode 100644 index 0000000000..4acbedd055 --- /dev/null +++ b/projects/ArchR/packages/apps/mangohud/config/MangoHud.conf @@ -0,0 +1,409 @@ +### MangoHud configuration file +### Uncomment any options you wish to enable. Default options are left uncommented +### Use some_parameter=0 to disable a parameter (only works with on/off parameters) +### Everything below can be used / overridden with the environment variable MANGOHUD_CONFIG instead + +################ INFORMATIONAL ################# +## prints possible options on stdout +# help + +################ PERFORMANCE ################# + +### Limit the application FPS. Comma-separated list of one or more FPS values (e.g. 0,30,60). 0 means unlimited (unless VSynced) +# fps_limit=0 + +### early = wait before present, late = wait after present +# fps_limit_method= + +### VSync [0-3] 0 = adaptive; 1 = off; 2 = mailbox; 3 = on +# vsync=-1 + +### OpenGL VSync [0-N] 0 = off; >=1 = wait for N v-blanks, N > 1 acts as a FPS limiter (FPS = display refresh rate / N) +# gl_vsync=-2 + +### Mip-map LoD bias. Negative values will increase texture sharpness (and aliasing) +## Positive values will increase texture blurriness (-16 to 16) +# picmip=-17 + +### Anisotropic filtering level. Improves sharpness of textures viewed at an angle (0 to 16) +# af=-1 + +### Force bicubic filtering +# bicubic + +### Force trilinear filtering +# trilinear + +### Disable linear texture filtering. Makes textures look blocky +# retro + +################### VISUAL ################### + +### Legacy layout +# legacy_layout=0 + +### pre defined presets +# -1 = default +# 0 = no display +# 1 = fps only +# 2 = horizontal view +# 3 = extended +# 4 = high detailed information +# preset=-1 + +### Enable most of the toggleable parameters (currently excludes `histogram`) +# full + +### Show FPS only. ***Not meant to be used with other display params*** +# fps_only + +### Display custom centered text, useful for a header +# custom_text_center= + +### Display the current system time +# time +## removes the time label +# time_no_label + +### Time formatting examples +## %H:%M +## [ %T %F ] +## %X # locally formatted time, because of limited glyph range, missing characters may show as '?' (e.g. Japanese) +# time_format="%T" + +### Display MangoHud version +# version + +### Display the current GPU information +## Note: gpu_mem_clock and gpu_mem_temp also need "vram" to be enabled +# gpu_stats +gpu_temp +# gpu_junction_temp +gpu_core_clock +# gpu_mem_temp +# gpu_mem_clock +# gpu_power +# gpu_power_limit +# gpu_text= +# gpu_load_change +# gpu_load_value=60,90 +# gpu_load_color=39F900,FDFD09,B22222 +## GPU fan in rpm on AMD, FAN in percent on NVIDIA +# gpu_fan +## gpu_voltage only works on AMD GPUs +# gpu_voltage +## Select list of GPUs to display +# gpu_list=0,1 +# gpu_efficiency + +### Display the current CPU information +# cpu_stats +cpu_temp +# cpu_power +# cpu_text= +cpu_mhz +# cpu_load_change +# cpu_load_value=60,90 +# cpu_load_color=39F900,FDFD09,B22222 +# cpu_efficiency + +### Display the current CPU load & frequency for each core +# core_load +# core_load_change +# core_bars +# core_type + +### Display IO read and write for the app (not system) +# io_read +# io_write + +### Display system vram / ram / swap space usage +# vram +# ram +# swap + +### Display per process memory usage +## Show resident memory and other types, if enabled +procmem +# procmem_shared +# procmem_virt +# proc_vram + +### Display battery information +battery +# battery_icon +# device_battery=gamepad,mouse +# device_battery_icon +battery_watt +# battery_time + +### Display FPS and frametime +fps +# fps_sampling_period=500 +# fps_color_change +# fps_value=30,60 +# fps_color=B22222,FDFD09,39F900 +# fps_text="" +frametime +# frame_count +## fps_metrics takes a list of decimal values or the value avg +# fps_metrics=avg,0.01 + +### Display GPU throttling status based on Power, current, temp or "other" +## Only shows if throttling is currently happening +throttling_status +## Same as throttling_status but displays throttling on the frametime graph +#throttling_status_graph + +### Display miscellaneous information +# engine_version +# engine_short_names +# gpu_name +# vulkan_driver +# wine +# exec_name +# winesync +# present_mode + +### Display loaded MangoHud architecture +# arch + +### Display the frametime line graph +frame_timing +# frame_timing_detailed +# dynamic_frame_timing +# histogram + +### Display GameMode / vkBasalt running status +# gamemode +# vkbasalt + +### Gamescope related options +## Display the status of FSR (only works in gamescope) +# fsr +## Hides the sharpness info for the `fsr` option (only available in gamescope) +# hide_fsr_sharpness +## Shows the graph of gamescope app frametimes and latency (only on gamescope obviously) +# debug +## Display the status of HDR (only works in gamescope) +# hdr +## Display the current refresh rate (only works in gamescope) +# refresh_rate + + +### graphs displays one or more graphs that you chose +## separated by ",", available graphs are +## gpu_load,cpu_load,gpu_core_clock,gpu_mem_clock,vram,ram,cpu_temp,gpu_temp +# graphs= + +### mangoapp related options +## Enables mangoapp to be displayed above the Steam UI +# mangoapp_steam + +### Steam Deck options +## Shows the Steam Deck fan rpm +# fan + +### Display current FPS limit +# show_fps_limit + +### Display the current resolution +# resolution + +### Display current display session +# display_server + +### Display temperature in fahrenheit +# temp_fahrenheit + +## Display efficiency in joules per frame +# flip_efficiency + +### Display custom text +# custom_text= +### Display output of Bash command in next column +# exec= + +### Display media player metadata +# media_player +## for example spotify +# media_player_name= +## Format metadata, lines are delimited by ; (wip) +## example: {title};{artist};{album} +## example: Track:;{title};By:;{artist};From:;{album} +# media_player_format=title,artist,album + +### Network interface throughput +# network +## Network can take arguments but it's not required. +## without arguments it shows all interfaces +## arguments set which interfaces will be displayed +# network=eth0,wlo1 + + +### Change the hud font size +font_size=@FONT_SIZE@ +# font_scale=1.0 +# font_size_text=24 +# font_scale_media_player=0.55 +# no_small_font + +### Change default font (set location to TTF/OTF file) +## Set font for the whole hud +# font_file= + +## Set font only for text like media player metadata +# font_file_text= + +## Set font glyph ranges. Defaults to Latin-only. Don't forget to set font_file/font_file_text to font that supports these +## Probably don't enable all at once because of memory usage and hardware limits concerns +## If you experience crashes or text is just squares, reduce glyph range or reduce font size +# font_glyph_ranges=korean,chinese,chinese_simplified,japanese,cyrillic,thai,vietnamese,latin_ext_a,latin_ext_b + +### Outline text +text_outline +# text_outline_color = 000000 +# text_outline_thickness = 1.5 + +### Change the hud position +# position=top-left + +### Change the corner roundness +# round_corners=0 + +### Remove margins around MangoHud +# hud_no_margin + +### Display compact version of MangoHud +# hud_compact + +### Display MangoHud in a horizontal position +# horizontal +# horizontal_stretch + +### Disable / hide the hud by default +# no_display + +### Show FEX-Emu statistics +## Only useful for Arm64 devices running applications under emulation +# fex_stats + +### Hud position offset +# offset_x=0 +# offset_y=0 + +### Hud dimensions +# width=0 +# height=140 +# table_columns=3 +# cellpadding_y=-0.085 + +### Hud transparency / alpha +# background_alpha=0.5 +# alpha=1.0 + +### FCAT overlay +### This enables an FCAT overlay to perform frametime analysis on the final image stream. +### Enable the overlay +# fcat +### Set the width of the FCAT overlay. +### 24 is a performance optimization on AMD GPUs that should not have adverse effects on nVidia GPUs. +### A minimum of 20 pixels is recommended by nVidia. +# fcat_overlay_width=24 +### Set the screen edge, this can be useful for special displays that don't update from top edge to bottom. This goes from 0 (left side) to 3 (top edge), counter-clockwise. +# fcat_screen_edge=0 + +### Color customization +# text_color=FFFFFF +# gpu_color=2E9762 +# cpu_color=2E97CB +# vram_color=AD64C1 +# ram_color=C26693 +# engine_color=EB5B5B +# io_color=A491D3 +# frametime_color=00FF00 +# background_color=020202 +# media_player_color=FFFFFF +# wine_color=EB5B5B +# battery_color=FF9078 +# network_color=E07B85 +# horizontal_separator_color=AD64C1 + +### Specify GPU with PCI bus ID +### Set to 'domain:bus:slot.function' +### Example: +### $ lspci | grep A770 +### 03:00.0 VGA compatible controller: Intel Corporation DG2 [Arc A770] (rev 08) +# pci_dev=0000:03:00.0 + +### Blacklist +# blacklist= + +### Control over socket +### Enable and set socket name, '%p' is replaced with process id +## example: mangohud +## example: mangohud-%p +# control = -1 + +### ftrace tracepoint display +## Enable display of tracepoint information gathered from ftrace. MangoHud will parse +## out the necessary data from the ftrace pipe, ftrace itself still has to be configured +## manually (enabling the desired event, applying any filtering etc.). The user running +## MangoHud will require permission to access the default-mounted tracefs (expected at +## /sys/kernel/tracing/). +## +## When parsing ftrace output, currently only the `key=value` format for event fields is +## expected. This is the most common format used in events, but it's not standardized. +## +## Three types of display are available: +## - `histogram/drm_vblank_event`, a histogram of event occurrence +## - `linegraph/devfreq_monitor/freq`, a line graph of an event field's numerical value +## - `label/devfreq_frequency/dev_name`, a textual presentation of an event field's value +## +## The displays are set through the `ftrace` option. Multiple displays can be specified. +# ftrace=histogram/drm_vblank_event+linegraph/devfreq_monitor/freq + +################ WORKAROUNDS ################# +### Options starting with "gl_*" are for OpenGL +### Specify what to use for getting display size. Options are "viewport", "scissorbox" or disabled. Defaults to using glXQueryDrawable +# gl_size_query=viewport + +### (Re)bind given framebuffer before MangoHud gets drawn. Helps with Crusader Kings III +# gl_bind_framebuffer=0 + +### Don't swap origin if using GL_UPPER_LEFT. Helps with Ryujinx +# gl_dont_flip=1 + +################ INTERACTION ################# + +### Change toggle keybinds for the hud & logging +# toggle_hud=Shift_R+F12 +# toggle_hud_position=Shift_R+F11 +# toggle_preset=Shift_R+F10 +# toggle_fps_limit=Shift_L+F1 +# toggle_logging=Shift_L+F2 +# reload_cfg=Shift_L+F4 +# upload_log=Shift_L+F3 +# reset_fps_metrics=Shift_R+f9 + +#################### LOG ##################### +### Automatically start the log after X seconds +# autostart_log= +### Set amount of time in seconds that the logging will run for +# log_duration= +### Change the default log interval, 0 is default +# log_interval=0 +### Set location of the output files (required for logging) +# output_folder=/home//mangologs +### Permit uploading logs directly to FlightlessMango.com +## set to 1 to enable +# permit_upload=0 +### Define a '+'-separated list of percentiles shown in the benchmark results +### Use "AVG" to get a mean average. Default percentiles are 97+AVG+1+0.1 +## example: ['97', 'AVG', '1', '0.1'] +# benchmark_percentiles=97,AVG +## Adds more headers and information such as versioning to the log. This format is not supported on flightlessmango.com (yet) +# log_versioning +## Enable automatic uploads of logs to flightlessmango.com +# upload_logs +# output_file="" diff --git a/projects/ArchR/packages/apps/mangohud/meson-patches/imgui_patch_1.91.6-3.zip b/projects/ArchR/packages/apps/mangohud/meson-patches/imgui_patch_1.91.6-3.zip new file mode 100644 index 0000000000..353decf906 Binary files /dev/null and b/projects/ArchR/packages/apps/mangohud/meson-patches/imgui_patch_1.91.6-3.zip differ diff --git a/projects/ArchR/packages/apps/mangohud/meson-patches/implot_patch_0.16-1.zip b/projects/ArchR/packages/apps/mangohud/meson-patches/implot_patch_0.16-1.zip new file mode 100644 index 0000000000..6c64983d09 Binary files /dev/null and b/projects/ArchR/packages/apps/mangohud/meson-patches/implot_patch_0.16-1.zip differ diff --git a/projects/ArchR/packages/apps/mangohud/meson-patches/spdlog_patch_1.14.1-1.zip b/projects/ArchR/packages/apps/mangohud/meson-patches/spdlog_patch_1.14.1-1.zip new file mode 100644 index 0000000000..dd82a146ac Binary files /dev/null and b/projects/ArchR/packages/apps/mangohud/meson-patches/spdlog_patch_1.14.1-1.zip differ diff --git a/projects/ArchR/packages/apps/mangohud/meson-patches/vulkan-headers_patch_1.3.283-1.zip b/projects/ArchR/packages/apps/mangohud/meson-patches/vulkan-headers_patch_1.3.283-1.zip new file mode 100644 index 0000000000..677ba45978 Binary files /dev/null and b/projects/ArchR/packages/apps/mangohud/meson-patches/vulkan-headers_patch_1.3.283-1.zip differ diff --git a/projects/ArchR/packages/apps/mangohud/package.mk b/projects/ArchR/packages/apps/mangohud/package.mk new file mode 100644 index 0000000000..8880ee4730 --- /dev/null +++ b/projects/ArchR/packages/apps/mangohud/package.mk @@ -0,0 +1,91 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2025-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="mangohud" +PKG_VERSION="d7654ebcefb3bdb106d581c937417aa2007eaeeb" # v0.8.3-rc1 + a few fixes +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/flightlessmango/MangoHud" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain glslang mesa Python3 wayland libxcb dbus" +PKG_LONGDESC="A Vulkan and OpenGL overlay for monitoring FPS, temperatures, CPU/GPU load and more." +PKG_PATCH_DIRS+="${DEVICE}" + +if [ "${OPENGL_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL}" +fi + +if [ "${VULKAN_SUPPORT}" = "yes" ] +then + PKG_DEPENDS_TARGET+=" ${VULKAN}" +fi + +pre_configure_target() { + PKG_MESON_OPTS_TARGET+=" -Dwith_xnvctrl=disabled \ + -Dwith_x11=enabled \ + -Dmangoplot=disabled \ + -Dwith_wayland=enabled" + + # Download Sub Modules + mkdir -p ${PKG_BUILD}/subprojects/ + + ### vulkan-headers + curl -Lo ${PKG_BUILD}/subprojects/vulkan-headers.tar.gz https://github.com/KhronosGroup/Vulkan-Headers/archive/v1.3.283.tar.gz + tar -xvf ${PKG_BUILD}/subprojects/vulkan-headers.tar.gz -C ${PKG_BUILD}/subprojects/ + #curl -Lo ${PKG_BUILD}/subprojects/vulkan-headers_patch_1.3.283-1.zip https://wrapdb.mesonbuild.com/v2/vulkan-headers_1.3.283-1/get_patch + #unzip -o ${PKG_BUILD}/subprojects/vulkan-headers_patch_1.3.283-1.zip -d ${PKG_BUILD}/subprojects + unzip -o ${PKG_DIR}/meson-patches/vulkan-headers_patch_1.3.283-1.zip -d ${PKG_BUILD}/subprojects + rm -rf ${PKG_BUILD}/subprojects/vulkan-headers.tar.gz + rm -rf ${PKG_BUILD}/subprojects/vulkan-headers_patch_1.3.283-1.zip + + ### imgui + curl -Lo ${PKG_BUILD}/subprojects/imgui.tar.gz https://github.com/ocornut/imgui/archive/refs/tags/v1.91.6.tar.gz + tar -xvf ${PKG_BUILD}/subprojects/imgui.tar.gz -C ${PKG_BUILD}/subprojects/ + #curl -Lo ${PKG_BUILD}/subprojects/imgui_patch_1.91.6-3.zip https://wrapdb.mesonbuild.com/v2/imgui_1.91.6-3/get_patch + #unzip -o ${PKG_BUILD}/subprojects/imgui_patch_1.91.6-3.zip -d ${PKG_BUILD}/subprojects + unzip -o ${PKG_DIR}/meson-patches/imgui_patch_1.91.6-3.zip -d ${PKG_BUILD}/subprojects + rm -rf ${PKG_BUILD}/subprojects/imgui.tar.gz + rm -rf ${PKG_BUILD}/subprojects/imgui_patch_1.91.6-3.zip + + ### implot + curl -Lo ${PKG_BUILD}/subprojects/implot.zip https://github.com/epezent/implot/archive/refs/tags/v0.16.zip + unzip -o ${PKG_BUILD}/subprojects/implot.zip -d ${PKG_BUILD}/subprojects + #curl -Lo ${PKG_BUILD}/subprojects/implot_patch_0.16-1.zip https://wrapdb.mesonbuild.com/v2/implot_0.16-1/get_patch + #unzip -o ${PKG_BUILD}/subprojects/implot_patch_0.16-1.zip -d ${PKG_BUILD}/subprojects + unzip -o ${PKG_DIR}/meson-patches/implot_patch_0.16-1.zip -d ${PKG_BUILD}/subprojects + rm -rf ${PKG_BUILD}/subprojects/implot.zip + rm -rf ${PKG_BUILD}/subprojects/implot_patch_0.16-1.zip + + ### spdlog + curl -Lo ${PKG_BUILD}/subprojects/spdlog.tar.gz https://github.com/gabime/spdlog/archive/refs/tags/v1.14.1.tar.gz + tar -xvf ${PKG_BUILD}/subprojects/spdlog.tar.gz -C ${PKG_BUILD}/subprojects/ + #curl -Lo ${PKG_BUILD}/subprojects/spdlog_patch_1.14.1-1.zip https://wrapdb.mesonbuild.com/v2/spdlog_1.14.1-1/get_patch + #unzip -o ${PKG_BUILD}/subprojects/spdlog_patch_1.14.1-1.zip -d ${PKG_BUILD}/subprojects + unzip -o ${PKG_DIR}/meson-patches/spdlog_patch_1.14.1-1.zip -d ${PKG_BUILD}/subprojects + rm -rf ${PKG_BUILD}/subprojects/spdlog.tar.gz + rm -rf ${PKG_BUILD}/subprojects/spdlog_patch_1.14.1-1.zip +} + +post_makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp -rf ${PKG_DIR}/sources/* ${INSTALL}/usr/bin + chmod +x ${INSTALL}/usr/bin/* + + mkdir -p ${INSTALL}/usr/config/MangoHud + cp -rf ${PKG_DIR}/config/* ${INSTALL}/usr/config/MangoHud + + # Customize config per platform, eg set font size for display resolution + case ${DEVICE} in + RK3326) + sed -e "s/@FONT_SIZE@/30/g" -i ${INSTALL}/usr/config/MangoHud/MangoHud.conf + ;; + S922X) + sed -e "s/@FONT_SIZE@/30/g" -i ${INSTALL}/usr/config/MangoHud/MangoHud.conf + + # No GPU temperature sensor available + sed -i 's/^gpu_temp/\# gpu_temp/g' ${INSTALL}/usr/config/MangoHud/MangoHud.conf + ;; + *) + sed -e "s/@FONT_SIZE@/40/g" -i ${INSTALL}/usr/config/MangoHud/MangoHud.conf + ;; + esac +} diff --git a/projects/ArchR/packages/apps/mangohud/patches/0001-No-static-lib.patch b/projects/ArchR/packages/apps/mangohud/patches/0001-No-static-lib.patch new file mode 100644 index 0000000000..2c20c13641 --- /dev/null +++ b/projects/ArchR/packages/apps/mangohud/patches/0001-No-static-lib.patch @@ -0,0 +1,25 @@ +From 5911b0ea29e64c289cf8582c55d8892687149602 Mon Sep 17 00:00:00 2001 +From: John Williams +Date: Wed, 14 Jan 2026 22:18:16 +1100 +Subject: [PATCH 1/3] No static lib + +--- + src/meson.build | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/meson.build b/src/meson.build +index e500c0c..9ca3f5b 100644 +--- a/src/meson.build ++++ b/src/meson.build +@@ -176,7 +176,7 @@ if is_unixy + endif + endif + +-link_args = cc.get_supported_link_arguments(['-Wl,-Bsymbolic-functions', '-Wl,-z,relro', '-Wl,--exclude-libs,ALL', '-lGL', '-static-libstdc++']) ++link_args = cc.get_supported_link_arguments(['-Wl,-Bsymbolic-functions', '-Wl,-z,relro', '-Wl,--exclude-libs,ALL', '-lGL']) + # meson fails to check version-script so just force add + link_args += '-Wl,--version-script,@0@'.format(join_paths(meson.current_source_dir(), 'mangohud.version')) + +-- +2.47.3 + diff --git a/projects/ArchR/packages/apps/mangohud/patches/0002-Battery-name.patch b/projects/ArchR/packages/apps/mangohud/patches/0002-Battery-name.patch new file mode 100644 index 0000000000..a5a114428e --- /dev/null +++ b/projects/ArchR/packages/apps/mangohud/patches/0002-Battery-name.patch @@ -0,0 +1,25 @@ +From aed0afd4578c66194b85587f6904ee6457487d74 Mon Sep 17 00:00:00 2001 +From: John Williams +Date: Wed, 14 Jan 2026 22:18:41 +1100 +Subject: [PATCH 2/3] Battery name + +--- + src/battery.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/battery.cpp b/src/battery.cpp +index e5d311b..9cf8e5b 100644 +--- a/src/battery.cpp ++++ b/src/battery.cpp +@@ -13,7 +13,7 @@ void BatteryStats::numBattery() { + fs::path path("/sys/class/power_supply/"); + for (auto& p : fs::directory_iterator(path)) { + string fileName = p.path().filename(); +- if (fileName.find("BAT") != std::string::npos) { ++ if (fileName.find("battery") != std::string::npos) { + battPath[batteryCount] = p.path(); + batteryCount += 1; + } +-- +2.47.3 + diff --git a/projects/ArchR/packages/apps/mangohud/patches/0003-RAM-name.patch b/projects/ArchR/packages/apps/mangohud/patches/0003-RAM-name.patch new file mode 100644 index 0000000000..fd5449291b --- /dev/null +++ b/projects/ArchR/packages/apps/mangohud/patches/0003-RAM-name.patch @@ -0,0 +1,25 @@ +From d0ce0d7ed5d7b6122057976627f6761d70f1c59c Mon Sep 17 00:00:00 2001 +From: John Williams +Date: Wed, 14 Jan 2026 22:19:09 +1100 +Subject: [PATCH 3/3] RAM name + +--- + src/hud_elements.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/hud_elements.cpp b/src/hud_elements.cpp +index 3cac5af..86d5002 100644 +--- a/src/hud_elements.cpp ++++ b/src/hud_elements.cpp +@@ -804,7 +804,7 @@ void HudElements::procmem() + return; + + ImguiNextColumnFirstItem(); +- HUDElements.TextColored(HUDElements.colors.ram, "PMEM"); ++ HUDElements.TextColored(HUDElements.colors.ram, "RAM"); + ImguiNextColumnOrNewRow(); + right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%.1f", format_units(proc_mem_resident, unit)); + ImGui::SameLine(0, 1.0f); +-- +2.47.3 + diff --git a/projects/ArchR/packages/apps/mangohud/patches/RK3326/0001-RK3326-soc_thermal.patch b/projects/ArchR/packages/apps/mangohud/patches/RK3326/0001-RK3326-soc_thermal.patch new file mode 100644 index 0000000000..4029824991 --- /dev/null +++ b/projects/ArchR/packages/apps/mangohud/patches/RK3326/0001-RK3326-soc_thermal.patch @@ -0,0 +1,26 @@ +From 0e3eb106c43c640ddb3cc9863297153215913c15 Mon Sep 17 00:00:00 2001 +From: John Williams +Date: Sun, 11 Jan 2026 21:42:52 +1100 +Subject: [PATCH 1/2] RK3326 soc_thermal + +--- + src/cpu.cpp | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/cpu.cpp b/src/cpu.cpp +index f46faba..621e03e 100644 +--- a/src/cpu.cpp ++++ b/src/cpu.cpp +@@ -615,6 +615,9 @@ bool CPUStats::GetCpuFile() { + } else if (name == "apm_xgene") { + find_input(path, "temp", input, "SoC Temperature"); + break; ++ } else if (name == "soc_thermal") { ++ find_fallback_input(path, "temp1", input); ++ break; + } else { + path.clear(); + } +-- +2.47.3 + diff --git a/projects/ArchR/packages/apps/mangohud/patches/RK3326/0002-RK3326-battery_watt.patch b/projects/ArchR/packages/apps/mangohud/patches/RK3326/0002-RK3326-battery_watt.patch new file mode 100644 index 0000000000..060253aacf --- /dev/null +++ b/projects/ArchR/packages/apps/mangohud/patches/RK3326/0002-RK3326-battery_watt.patch @@ -0,0 +1,27 @@ +From 0941b7be6555286d60f3a551d100597d9b9640c9 Mon Sep 17 00:00:00 2001 +From: John Williams +Date: Mon, 19 Jan 2026 21:25:05 +1100 +Subject: [PATCH 2/2] RK3326 battery_watt + +--- + src/battery.cpp | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/battery.cpp b/src/battery.cpp +index 9cf8e5b..8a39d24 100644 +--- a/src/battery.cpp ++++ b/src/battery.cpp +@@ -92,8 +92,8 @@ float BatteryStats::getPower() { + float voltage = 0; + for(int i = 0; i < batt_count; i++) { + string syspath = battPath[i]; +- string current_power = syspath + "/current_now"; +- string current_voltage = syspath + "/voltage_now"; ++ string current_power = syspath + "/current_avg"; ++ string current_voltage = syspath + "/voltage_avg"; + string power_now = syspath + "/power_now"; + string status = syspath + "/status"; + +-- +2.47.3 + diff --git a/projects/ArchR/packages/apps/mangohud/patches/SM8250/0001-SM8250-GPU.patch b/projects/ArchR/packages/apps/mangohud/patches/SM8250/0001-SM8250-GPU.patch new file mode 100644 index 0000000000..1e25e165c3 --- /dev/null +++ b/projects/ArchR/packages/apps/mangohud/patches/SM8250/0001-SM8250-GPU.patch @@ -0,0 +1,162 @@ +From fd8d0808a5a7133aea277156065c8b9dd5277861 Mon Sep 17 00:00:00 2001 +From: John Williams +Date: Wed, 14 Jan 2026 21:18:03 +1100 +Subject: [PATCH 1/2] SM8250 GPU + +--- + src/gpu_fdinfo.cpp | 68 ++++++++++++++++++++++++++++++++++------------ + src/gpu_fdinfo.h | 2 ++ + 2 files changed, 53 insertions(+), 17 deletions(-) + +diff --git a/src/gpu_fdinfo.cpp b/src/gpu_fdinfo.cpp +index 0fdd99e..14445be 100644 +--- a/src/gpu_fdinfo.cpp ++++ b/src/gpu_fdinfo.cpp +@@ -55,7 +55,7 @@ void GPU_fdinfo::find_fd() + client_id = val; + } + +- if (!driver.empty() && driver == module) { ++ if ((module == "msm_dpu" || module == "msm_drm") && driver == "msm") { + total++; + SPDLOG_TRACE( + "driver = \"{}\", pdev = \"{}\", " +@@ -63,14 +63,30 @@ void GPU_fdinfo::find_fd() + driver, pdev, + client_id, client_ids.find(client_id) != client_ids.end() + ); +- } + +- if ( +- driver.empty() || client_id.empty() || +- driver != module || pdev != pci_dev || +- client_ids.find(client_id) != client_ids.end() +- ) +- continue; ++ if ( ++ driver.empty() || client_id.empty() || ++ client_ids.find(client_id) != client_ids.end() ++ ) ++ continue; ++ } else { ++ if (!driver.empty() && driver == module) { ++ total++; ++ SPDLOG_TRACE( ++ "driver = \"{}\", pdev = \"{}\", " ++ "client_id = \"{}\", client_id_exists = \"{}\"", ++ driver, pdev, ++ client_id, client_ids.find(client_id) != client_ids.end() ++ ); ++ } ++ ++ if ( ++ driver.empty() || client_id.empty() || ++ driver != module || pdev != pci_dev || ++ client_ids.find(client_id) != client_ids.end() ++ ) ++ continue; ++ } + + client_ids.insert(client_id); + open_fdinfo_fd(fd_path); +@@ -175,8 +191,9 @@ void GPU_fdinfo::find_hwmon_sensors() + { + std::string hwmon; + +- if (module == "msm") +- hwmon = find_hwmon_sensor_dir("gpu"); ++ if (module == "msm_drm" || module == "msm_dpu" ) ++ // gpuss_0_thermal, gpuss_1_thermal and gpuss_2_thermal are all candidates ++ hwmon = find_hwmon_sensor_dir("gpu_top_thermal"); + else if (module == "panfrost" || module == "panthor") + hwmon = find_hwmon_sensor_dir("gpu_thermal"); + else +@@ -538,6 +555,8 @@ int GPU_fdinfo::get_gpu_clock() + { + if (module == "panfrost" || module == "panthor") + return get_gpu_clock_mali(); ++ else if (module == "msm_dpu") ++ return get_kgsl_clock(); + + if (!gpu_clock_stream.is_open()) + return 0; +@@ -637,7 +656,7 @@ float GPU_fdinfo::amdgpu_helper_get_proc_vram() { + } + + void GPU_fdinfo::init_kgsl() { +- const std::string sys_path = "/sys/class/kgsl/kgsl-3d0"; ++ const std::string sys_path = "/sys/class/devfreq/3d00000.gpu"; + + try { + if (!fs::exists(sys_path)) { +@@ -649,7 +668,8 @@ void GPU_fdinfo::init_kgsl() { + return; + } + +- for (std::string metric : {"gpu_busy_percentage", "temp", "clock_mhz" }) { ++ // Only GPU clocks accessible ++ for (std::string metric : {"cur_freq" }) { + std::string p = sys_path + "/" + metric; + + if (!fs::exists(p)) { +@@ -658,11 +678,7 @@ void GPU_fdinfo::init_kgsl() { + } + + SPDLOG_DEBUG("kgsl: {} found", p); +- +- if (metric == "clock_mhz") +- gpu_clock_stream.open(p); +- else +- kgsl_streams[metric].open(p); ++ kgsl_streams[metric].open(p); + } + } + +@@ -702,6 +718,24 @@ int GPU_fdinfo::get_kgsl_temp() { + return std::round(std::stoi(temp_str) / 1'000.f); + } + ++int GPU_fdinfo::get_kgsl_clock() { ++ std::ifstream* s = &kgsl_streams["cur_freq"]; ++ ++ if (!s->is_open()) ++ return 0; ++ ++ std::string freq_str; ++ ++ s->seekg(0); ++ ++ std::getline(*s, freq_str); ++ ++ if (freq_str.empty()) ++ return 0; ++ ++ return std::round(std::stoi(freq_str) / 1'000'000.f); ++} ++ + void GPU_fdinfo::main_thread() + { + while (!stop_thread) { +diff --git a/src/gpu_fdinfo.h b/src/gpu_fdinfo.h +index 97e62e5..a5b1d9e 100644 +--- a/src/gpu_fdinfo.h ++++ b/src/gpu_fdinfo.h +@@ -119,6 +119,7 @@ private: + void init_kgsl(); + int get_kgsl_load(); + int get_kgsl_temp(); ++ int get_kgsl_clock(); + + public: + GPU_fdinfo( +@@ -146,6 +147,7 @@ public: + } else if (module == "msm_dpu") { + // msm driver does not report vram usage + drm_engine_type = "drm-engine-gpu"; ++ init_kgsl(); + } else if (module == "msm_drm") { + init_kgsl(); + } else if (module == "panfrost") { +-- +2.47.3 + diff --git a/projects/ArchR/packages/apps/mangohud/patches/SM8250/0002-SM8250-big-core.patch b/projects/ArchR/packages/apps/mangohud/patches/SM8250/0002-SM8250-big-core.patch new file mode 100644 index 0000000000..b834d2af1c --- /dev/null +++ b/projects/ArchR/packages/apps/mangohud/patches/SM8250/0002-SM8250-big-core.patch @@ -0,0 +1,28 @@ +From 60731bb7fd6002649580ab9c63f7f43159ecac10 Mon Sep 17 00:00:00 2001 +From: John Williams +Date: Wed, 14 Jan 2026 21:18:18 +1100 +Subject: [PATCH 2/2] SM8250 big core + +--- + src/cpu.cpp | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/cpu.cpp b/src/cpu.cpp +index f46faba..5174c75 100644 +--- a/src/cpu.cpp ++++ b/src/cpu.cpp +@@ -236,6 +236,11 @@ bool CPUStats::UpdateCPUData() + + m_cpuPeriod = (double)m_cpuData[0].totalPeriod / m_cpuData.size(); + m_updatedCPUs = true; ++ ++ if (m_cpuData.size() > 7) { ++ m_cpuDataTotal.percent = m_cpuData[7].percent; ++ } ++ + return ret; + } + +-- +2.47.3 + diff --git a/projects/ArchR/packages/apps/mangohud/patches/SM8550/0001-SM8550-GPU.patch b/projects/ArchR/packages/apps/mangohud/patches/SM8550/0001-SM8550-GPU.patch new file mode 100644 index 0000000000..05243ea567 --- /dev/null +++ b/projects/ArchR/packages/apps/mangohud/patches/SM8550/0001-SM8550-GPU.patch @@ -0,0 +1,162 @@ +From 8abf317204f876b19238c21f045b1d54fc77cd80 Mon Sep 17 00:00:00 2001 +From: John Williams +Date: Tue, 13 Jan 2026 21:46:12 +1100 +Subject: [PATCH 1/2] SM8550 GPU + +--- + src/gpu_fdinfo.cpp | 68 ++++++++++++++++++++++++++++++++++------------ + src/gpu_fdinfo.h | 2 ++ + 2 files changed, 53 insertions(+), 17 deletions(-) + +diff --git a/src/gpu_fdinfo.cpp b/src/gpu_fdinfo.cpp +index 0fdd99e..23cf6a2 100644 +--- a/src/gpu_fdinfo.cpp ++++ b/src/gpu_fdinfo.cpp +@@ -55,7 +55,7 @@ void GPU_fdinfo::find_fd() + client_id = val; + } + +- if (!driver.empty() && driver == module) { ++ if ((module == "msm_dpu" || module == "msm_drm") && driver == "msm") { + total++; + SPDLOG_TRACE( + "driver = \"{}\", pdev = \"{}\", " +@@ -63,14 +63,30 @@ void GPU_fdinfo::find_fd() + driver, pdev, + client_id, client_ids.find(client_id) != client_ids.end() + ); +- } + +- if ( +- driver.empty() || client_id.empty() || +- driver != module || pdev != pci_dev || +- client_ids.find(client_id) != client_ids.end() +- ) +- continue; ++ if ( ++ driver.empty() || client_id.empty() || ++ client_ids.find(client_id) != client_ids.end() ++ ) ++ continue; ++ } else { ++ if (!driver.empty() && driver == module) { ++ total++; ++ SPDLOG_TRACE( ++ "driver = \"{}\", pdev = \"{}\", " ++ "client_id = \"{}\", client_id_exists = \"{}\"", ++ driver, pdev, ++ client_id, client_ids.find(client_id) != client_ids.end() ++ ); ++ } ++ ++ if ( ++ driver.empty() || client_id.empty() || ++ driver != module || pdev != pci_dev || ++ client_ids.find(client_id) != client_ids.end() ++ ) ++ continue; ++ } + + client_ids.insert(client_id); + open_fdinfo_fd(fd_path); +@@ -175,8 +191,9 @@ void GPU_fdinfo::find_hwmon_sensors() + { + std::string hwmon; + +- if (module == "msm") +- hwmon = find_hwmon_sensor_dir("gpu"); ++ if (module == "msm_drm" || module == "msm_dpu" ) ++ // gpuss_0_thermal, gpuss_1_thermal and gpuss_2_thermal are all candidates ++ hwmon = find_hwmon_sensor_dir("gpuss_0_thermal"); + else if (module == "panfrost" || module == "panthor") + hwmon = find_hwmon_sensor_dir("gpu_thermal"); + else +@@ -538,6 +555,8 @@ int GPU_fdinfo::get_gpu_clock() + { + if (module == "panfrost" || module == "panthor") + return get_gpu_clock_mali(); ++ else if (module == "msm_dpu") ++ return get_kgsl_clock(); + + if (!gpu_clock_stream.is_open()) + return 0; +@@ -637,7 +656,7 @@ float GPU_fdinfo::amdgpu_helper_get_proc_vram() { + } + + void GPU_fdinfo::init_kgsl() { +- const std::string sys_path = "/sys/class/kgsl/kgsl-3d0"; ++ const std::string sys_path = "/sys/class/devfreq/3d00000.gpu"; + + try { + if (!fs::exists(sys_path)) { +@@ -649,7 +668,8 @@ void GPU_fdinfo::init_kgsl() { + return; + } + +- for (std::string metric : {"gpu_busy_percentage", "temp", "clock_mhz" }) { ++ // Only GPU clocks accessible ++ for (std::string metric : {"cur_freq" }) { + std::string p = sys_path + "/" + metric; + + if (!fs::exists(p)) { +@@ -658,11 +678,7 @@ void GPU_fdinfo::init_kgsl() { + } + + SPDLOG_DEBUG("kgsl: {} found", p); +- +- if (metric == "clock_mhz") +- gpu_clock_stream.open(p); +- else +- kgsl_streams[metric].open(p); ++ kgsl_streams[metric].open(p); + } + } + +@@ -702,6 +718,24 @@ int GPU_fdinfo::get_kgsl_temp() { + return std::round(std::stoi(temp_str) / 1'000.f); + } + ++int GPU_fdinfo::get_kgsl_clock() { ++ std::ifstream* s = &kgsl_streams["cur_freq"]; ++ ++ if (!s->is_open()) ++ return 0; ++ ++ std::string freq_str; ++ ++ s->seekg(0); ++ ++ std::getline(*s, freq_str); ++ ++ if (freq_str.empty()) ++ return 0; ++ ++ return std::round(std::stoi(freq_str) / 1'000'000.f); ++} ++ + void GPU_fdinfo::main_thread() + { + while (!stop_thread) { +diff --git a/src/gpu_fdinfo.h b/src/gpu_fdinfo.h +index 97e62e5..a5b1d9e 100644 +--- a/src/gpu_fdinfo.h ++++ b/src/gpu_fdinfo.h +@@ -119,6 +119,7 @@ private: + void init_kgsl(); + int get_kgsl_load(); + int get_kgsl_temp(); ++ int get_kgsl_clock(); + + public: + GPU_fdinfo( +@@ -146,6 +147,7 @@ public: + } else if (module == "msm_dpu") { + // msm driver does not report vram usage + drm_engine_type = "drm-engine-gpu"; ++ init_kgsl(); + } else if (module == "msm_drm") { + init_kgsl(); + } else if (module == "panfrost") { +-- +2.47.3 + diff --git a/projects/ArchR/packages/apps/mangohud/sources/mangohud_set b/projects/ArchR/packages/apps/mangohud/sources/mangohud_set new file mode 100644 index 0000000000..0975b07576 --- /dev/null +++ b/projects/ArchR/packages/apps/mangohud/sources/mangohud_set @@ -0,0 +1,85 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025-present ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile + +MHUD_SET=${1} + +### Enable logging +case $(get_setting system.loglevel) in + verbose) + DEBUG=true + ;; + *) + DEBUG=false + ;; +esac + +### Confirm MangoHud dir exists +if [ ! -d "/storage/.config/MangoHud" ]; then + cp -r "/usr/config/MangoHud" "/storage/.config/" +fi + +### Confirm MangoHud conf exists +if [ ! -f "/storage/.config/MangoHud/MangoHud.conf" ]; then + cp -r "/usr/config/MangoHud/MangoHud.conf" "/storage/.config/MangoHud" +fi + +# Enable MangoHud support +MANGOHUD_INIT_STATE=$(get_setting "archr.mangohud.state") +if [ ! -n "${MANGOHUD_INIT_STATE}" ]; then + MANGOHUD_INIT_STATE="off" + set_setting "archr.mangohud.state" "${MANGOHUD_INIT_STATE}" +fi + +### Check if a value was sent to mangohud_set +if [ ! -n "${MHUD_SET}" ]; then + MHUD_SET="NULL" +fi + +### Check that the value sent to manghud_set is a valid selection +if [[ "${MHUD_SET}" != "on" && "$MHUD_SET" != "off" && "${MHUD_SET}" != "toggle" && "$MHUD_SET" != "enable" && "$MHUD_SET" != "disable" ]]; then + ${DEBUG} && log $0 "$MHUD_SET is not a valid choice, valid options are on | off | toggle, setting MangoHud to off." + set_setting "archr.mangohud.state" "off" + MHUD_SET="off" +fi + +CONF_DIR="/storage/.config/MangoHud" +MANGOHUD_CONF="MangoHud.conf" + +case $MHUD_SET in + "disable") + set_setting "archr.mangohud.enabled" "0" + ${DEBUG} && log $0 "Disabling MangoHud." + ;; + "enable") + set_setting "archr.mangohud.enabled" "1" + ${DEBUG} && log $0 "Enabling MangoHud." + ;; + "off") + sed -i '/no_display/c\no_display' ${CONF_DIR}/${MANGOHUD_CONF} + set_setting "archr.mangohud.state" "off" + ${DEBUG} && log $0 "Turning MangoHud off." + ;; + "on") + sed -i '/no_display/c\# no_display' ${CONF_DIR}/${MANGOHUD_CONF} + set_setting "archr.mangohud.state" "on" + ${DEBUG} && log $0 "Turning MangoHud on." + ;; + "toggle") + MHUD_STATE=$(get_setting "archr.mangohud.state") + case ${MHUD_STATE} in + "on") + sed -i '/no_display/c\no_display' ${CONF_DIR}/${MANGOHUD_CONF} + set_setting "archr.mangohud.state" "off" + ${DEBUG} && log $0 "Toggle MangoHud, turning MangoHud off." + ;; + "off") + sed -i '/no_display/c\# no_display' ${CONF_DIR}/${MANGOHUD_CONF} + set_setting "archr.mangohud.state" "on" + ${DEBUG} && log $0 "Toggle MangoHud, turning MangoHud on." + ;; + esac + ;; +esac diff --git a/projects/ArchR/packages/apps/moonlight/autostart/010-moonlight b/projects/ArchR/packages/apps/moonlight/autostart/010-moonlight new file mode 100755 index 0000000000..1b30ba5547 --- /dev/null +++ b/projects/ArchR/packages/apps/moonlight/autostart/010-moonlight @@ -0,0 +1,15 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +if [ ! -f "/storage/.config/moonlight/moonlight.conf" ] +then + mkdir -p /storage/.config/moonlight + cp /usr/config/moonlight/moonlight.conf /storage/.config/moonlight/moonlight.conf +fi + +sed -i "s#@MWIDTH@#$(fbwidth)#g; + s#@MHEIGHT@#$(fbheight)#g" /storage/.config/moonlight/moonlight.conf diff --git a/projects/ArchR/packages/apps/moonlight/package.mk b/projects/ArchR/packages/apps/moonlight/package.mk new file mode 100644 index 0000000000..a4d9259e37 --- /dev/null +++ b/projects/ArchR/packages/apps/moonlight/package.mk @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="moonlight" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/moonlight-stream/moonlight-" +PKG_DEPENDS_TARGET="toolchain opus SDL2 libevdev alsa curl enet avahi libvdpau ffmpeg" +PKG_LONGDESC="Moonlight is an open source implementation of NVIDIA's GameStream, as used by the NVIDIA Shield, but built for Linux." +GET_HANDLER_SUPPORT="git" +PKG_PATCH_DIRS+="${DEVICE}" + +if [ "${TARGET_ARCH}" = "null" ] +then + PKG_SITE+="qt" + PKG_URL="${PKG_SITE}.git" + PKG_VERSION="8a87a09947f27dd2fe4bee7ae9faabe86873a5c4" + PKG_DEPENDS_TARGET+=" qt6" + PKG_TOOLCHAIN="manual" + make_target() { + qmake6 "CONFIG+=embedded" moonlight-qt.pro + make release + } + post_makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + mkdir -p ${INSTALL}/usr/config/modules + cp ${PKG_BUILD}/app/moonlight ${INSTALL}/usr/bin/ + cp ${PKG_BUILD}/start_moonlight.sh ${INSTALL}/usr/bin/ + chmod +x ${INSTALL}/usr/bin/* + mv ${INSTALL}/usr/bin/start_moonlight.sh ${INSTALL}/usr/config/modules/Start\ Moonlight.sh + } +else + PKG_SITE+="embedded" + PKG_URL="${PKG_SITE}.git" + PKG_VERSION="a6bf7154a743d4f74a1b377e730f188352a1b80c" + PKG_TOOLCHAIN="cmake" + + PKG_CMAKE_OPTS_TARGET+=" -DENABLE_CEC=OFF" + + post_makeinstall_target() { + mkdir -p ${INSTALL}/usr/config/moonlight + cp -R ${PKG_BUILD}/moonlight.conf ${INSTALL}/usr/config/moonlight + rm ${INSTALL}/usr/etc/moonlight.conf + rm ${INSTALL}/usr/share/moonlight/gamecontrollerdb.txt + } +fi + +if [[ "${DEVICE}" == RK* ]] +then + PKG_DEPENDS_TARGET+=" librga rkmpp" +fi + +if [ ! "${OPENGL}" = "no" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" +fi + +if [ "${OPENGLES_SUPPORT}" = yes ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" +fi + +if [ "${VULKAN_SUPPORT}" = "yes" ] + then + PKG_DEPENDS_TARGET+=" ${VULKAN}" +fi diff --git a/projects/ArchR/packages/apps/moonlight/sources/moonlight.conf b/projects/ArchR/packages/apps/moonlight/sources/moonlight.conf new file mode 100644 index 0000000000..e766d0c615 --- /dev/null +++ b/projects/ArchR/packages/apps/moonlight/sources/moonlight.conf @@ -0,0 +1,82 @@ +## Hostname or IP-address of host to connect to +## By default host is autodiscovered using mDNS +#address = 1.2.3.4 + +## Video streaming configuration +width = @MWIDTH@ +height = @MHEIGHT@ +fps = 60 + +## Output rotation (independent of xrandr or framebuffer settings!) +## Allowed values: 0, 90, 180, 270 +#rotation = 0 + +## Bitrate depends by default on resolution and fps +## Set to -1 to enable default +## 20Mbps (20000) for 1080p (60 fps) +## 10Mbps (10000) for 1080p or 60 fps +## 5Mbps (5000) for lower resolution or fps +bitrate = 15000 + +## Size of network packets should be lower than MTU +## If streaming with WAN optimizations, this will be capped at 1024. +#packetsize = 1392 + +## Select video codec (auto/h264/h265) +codec = h264 + +## Default started application on host +#app = Steam + +## Default used mapping for streaming +## Searched for in $XDG_DATA_DIRS/moonlight or /usr/share/moonlight and /usr/local/share/moonlight +## Mapping can also be user overrided in $XDG_CONFIG_DIR/moonlight or ~/.config/moonlight or current directory +#mapping = gamecontrollerdb.txt + +## Enable selected input devices +## By default all available input devices should be used +## Only evdev devices /dev/input/event* are allowed +## To use a different mapping then default another mapping should be declared above the input +#input = /dev/input/event1 + +## Enable GFE for changing graphical game settings for optimal performance and quality +#sops = true + +## Play audio on host instead of streaming to client +#localaudio = false + +## Send quit app request to remote after quitting session +quitappafter = true + +## Disable all input processing (view-only mode) +#viewonly = false + +## Select audio device to play sound on +#audio = sysdefault + +## Select the audio and video decoder to use +## default - autodetect +## aml - hardware video decoder for ODROID-C1/C2 +## rk - hardware video decoder for ODROID-N1 Rockchip +## omx - hardware video decoder for Raspberry Pi +## imx - hardware video decoder for i.MX6 devices +## x11 - software decoder +## sdl - software decoder with SDL input and audio +## fake - no audio and video +platform = sdl + +## Directory to store encryption keys +## By default keys are stored in $XDG_CACHE_DIR/moonlight or ~/.cache/moonlight +#keydir = /dir/to/keys + +## Enable QOS settings to optimize for internet or local network +## yes - optimize for WAN streaming +## no - optimize for LAN streaming +## auto (default) - decide automatically based on target IP address +#remote = auto + +## Enable 5.1/7.1 surround sound +#surround = 5.1 + +## Load additional configuration files +#config = /path/to/config diff --git a/projects/ArchR/packages/apps/moonlight/sources/start_moonlight.sh b/projects/ArchR/packages/apps/moonlight/sources/start_moonlight.sh new file mode 100644 index 0000000000..515cb099c7 --- /dev/null +++ b/projects/ArchR/packages/apps/moonlight/sources/start_moonlight.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +. /etc/profile +set_kill set "moonlight" +QT_QPA_PLATFORM=wayland moonlight diff --git a/projects/ArchR/packages/apps/oga_controls/Makefile b/projects/ArchR/packages/apps/oga_controls/Makefile new file mode 100644 index 0000000000..8f3a37c82f --- /dev/null +++ b/projects/ArchR/packages/apps/oga_controls/Makefile @@ -0,0 +1,12 @@ +cc = gcc +CFLAGS += -W -Wall + +BINARY = oga_controls +LIBRARIES = -levdev -lSDL2 +SOURCES = "main.c" + +all: + $(CC) $(CFLAGS) $(SOURCES) -o $(BINARY) $(LIBRARIES) + +clean: + rm -f $(BINARY) diff --git a/projects/ArchR/packages/apps/oga_controls/package.mk b/projects/ArchR/packages/apps/oga_controls/package.mk new file mode 100644 index 0000000000..e1f9e9e28a --- /dev/null +++ b/projects/ArchR/packages/apps/oga_controls/package.mk @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="oga_controls" +PKG_VERSION="1604ee24150c1c5bb7c66bc4670919c2ad8f0064" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/christianhaitian/oga_controls" +PKG_URL="${PKG_SITE}.git" +PKG_GIT_CLONE_BRANCH="universal" +PKG_DEPENDS_TARGET="toolchain libevdev SDL2" +PKG_LONGDESC="Emulated keyboard / mouse / joystick for the RGB10/OGA 1.1 (BE), RG351 P/M/V, RK2020/OGA 1.0, OGS, and the Chi" +PKG_TOOLCHAIN="make" +GET_HANDLER_SUPPORT="git" +PKG_PATCH_DIRS+="${DEVICE}" + +pre_make_target() { + cp -f ${PKG_DIR}/Makefile ${PKG_BUILD} + CFLAGS+=" -I$(get_build_dir SDL2)/include -D_REENTRANT" + CFLAGS+=" -I$(get_build_dir libevdev)" +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp ${PKG_BUILD}/oga_controls* ${INSTALL}/usr/bin +} diff --git a/projects/ArchR/packages/apps/oga_controls/patches/000-fix-libevdev.patch b/projects/ArchR/packages/apps/oga_controls/patches/000-fix-libevdev.patch new file mode 100644 index 0000000000..d719f6acb4 --- /dev/null +++ b/projects/ArchR/packages/apps/oga_controls/patches/000-fix-libevdev.patch @@ -0,0 +1,15 @@ +diff --git a/main.c b/main.c +index 2e43de7..80999b8 100644 +--- a/main.c ++++ b/main.c +@@ -30,8 +30,8 @@ + #include + #include + +-#include +-#include ++#include ++#include + + #include "parser.h" + diff --git a/projects/ArchR/packages/apps/oga_controls/patches/RK3326/000-platform.patch b/projects/ArchR/packages/apps/oga_controls/patches/RK3326/000-platform.patch new file mode 100644 index 0000000000..70dee864a0 --- /dev/null +++ b/projects/ArchR/packages/apps/oga_controls/patches/RK3326/000-platform.patch @@ -0,0 +1,33 @@ +diff --git a/main.c b/main.c +index 2e43de7..27cbd65 100644 +--- a/main.c ++++ b/main.c +@@ -1455,7 +1455,7 @@ void handle_event_ogx(int type, int code, int value) { + } + } + +-void handle_event_rk2020(int type, int code, int value) { ++void handle_event_oga(int type, int code, int value) { + if (type == 1) { + if (code == back_key && value == 1) { + hold = 1; +@@ -2215,7 +2215,7 @@ int main(int argc, char* argv[]) { + deadzone_x = -300; + strcpy(inputstr, "/dev/input/by-path/platform-odroidgo2-joypad-event-joystick"); + } +- else if (strcmp(argv[2], "rk2020") == 0) { ++ else if (strcmp(argv[2], "oga") == 0) { + back_key = 704; + start_key = 709; + a_key = 305; +@@ -2456,8 +2456,8 @@ int main(int argc, char* argv[]) { + if (strcmp(argv[2], "anbernic") == 0) { + handle_event_anbernic(ev_joypad.type, ev_joypad.code, ev_joypad.value); + } +- else if (strcmp(argv[2], "rk2020") == 0) { +- handle_event_rk2020(ev_joypad.type, ev_joypad.code, ev_joypad.value); ++ else if (strcmp(argv[2], "oga") == 0) { ++ handle_event_oga(ev_joypad.type, ev_joypad.code, ev_joypad.value); + } + else if (strcmp(argv[2], "chi") == 0) { + handle_event_chi(ev_joypad.type, ev_joypad.code, ev_joypad.value); diff --git a/projects/ArchR/packages/apps/oga_controls/patches/S922X/000-platform.patch b/projects/ArchR/packages/apps/oga_controls/patches/S922X/000-platform.patch new file mode 100644 index 0000000000..54eff6a259 --- /dev/null +++ b/projects/ArchR/packages/apps/oga_controls/patches/S922X/000-platform.patch @@ -0,0 +1,42 @@ +diff --git a/main.c b/main.c +index 2e43de7..8ef2b8b 100644 +--- a/main.c ++++ b/main.c +@@ -113,7 +113,7 @@ void emit(int type, int code, int val) { + write(uinp_fd, &ev, sizeof(ev)); + } + +-void handle_event_rg552(int type, int code, int value) { ++void handle_event_s922x(int type, int code, int value) { + if (type == 1) { + if (code == back_key && value == 1) { + emit(EV_KEY, back, 1); +@@ -2276,7 +2276,7 @@ int main(int argc, char* argv[]) { + deadzone_x = -300; + strcpy(inputstr, "/dev/input/by-path/platform-gameforce-gamepad-event-joystick"); + } +- else if (strcmp(argv[2], "rg552") == 0) { ++ else if (strcmp(argv[2], "s922x") == 0) { + back_key = 314; + start_key = 315; + a_key = 305; +@@ -2295,7 +2295,7 @@ int main(int argc, char* argv[]) { + r3_key = 318; + deadzone_y = 300; + deadzone_x = -300; +- strcpy(inputstr, "/dev/input/by-path/platform-singleadc-joypad-event-joystick"); ++ strcpy(inputstr, "/dev/input/by-path/platform-platform-gou_joypad-event-joystick"); + } + else { + printf("Error launching, unrecognised parameters\n"); +@@ -2465,8 +2465,8 @@ int main(int argc, char* argv[]) { + else if (strcmp(argv[2], "ogs") == 0) { + handle_event_ogs(ev_joypad.type, ev_joypad.code, ev_joypad.value); + } +- else if (strcmp(argv[2], "rg552") == 0) { +- handle_event_rg552(ev_joypad.type, ev_joypad.code, ev_joypad.value); ++ else if (strcmp(argv[2], "s922x") == 0) { ++ handle_event_s922x(ev_joypad.type, ev_joypad.code, ev_joypad.value); + } + else { + handle_event_ogx(ev_joypad.type, ev_joypad.code, ev_joypad.value); diff --git a/projects/ArchR/packages/apps/portmaster/package.mk b/projects/ArchR/packages/apps/portmaster/package.mk new file mode 100644 index 0000000000..e2cf1bc25c --- /dev/null +++ b/projects/ArchR/packages/apps/portmaster/package.mk @@ -0,0 +1,31 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="portmaster" +PKG_VERSION="2025.12.07-0332" +PKG_ARCH="arm aarch64" +PKG_LICENSE="MIT" +PKG_SITE="https://github.com/PortsMaster/PortMaster-GUI" +PKG_URL="https://github.com/PortsMaster/PortMaster-GUI/releases/download/${PKG_VERSION}/PortMaster.zip" +PKG_DEPENDS_TARGET="toolchain archr-hotkey gamecontrollerdb oga_controls control-gen xmlstarlet list-guid gst-plugins-base" +PKG_LONGDESC="Portmaster - a simple tool that allows you to download various game ports" +PKG_TOOLCHAIN="manual" + +COMPAT_URL="https://github.com/archr-linux/packages/raw/main/compat.zip" + +makeinstall_target() { + export STRIP=true + + mkdir -p ${INSTALL}/usr/config/PortMaster + cp -a ${PKG_DIR}/sources/* ${INSTALL}/usr/config/PortMaster + + mkdir -p ${INSTALL}/usr/bin + cp -a ${PKG_DIR}/scripts/* ${INSTALL}/usr/bin + + mkdir -p ${INSTALL}/usr/config/PortMaster/release + curl -Lo ${INSTALL}/usr/config/PortMaster/release/PortMaster.zip ${PKG_URL} + + mkdir -p ${INSTALL}/usr/lib/compat + curl -Lo ${PKG_BUILD}/compat.zip ${COMPAT_URL} + unzip -qq ${PKG_BUILD}/compat.zip -d ${INSTALL}/usr/lib/compat +} diff --git a/projects/ArchR/packages/apps/portmaster/scripts/portmaster_sway_fullscreen.sh b/projects/ArchR/packages/apps/portmaster/scripts/portmaster_sway_fullscreen.sh new file mode 100755 index 0000000000..ab734f4626 --- /dev/null +++ b/projects/ArchR/packages/apps/portmaster/scripts/portmaster_sway_fullscreen.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# Will be called by PortMaster mod_ArchR.txt + +. /etc/profile + +if echo "${UI_SERVICE}" | grep -q "sway"; then + # Call the function to fullscreen the window for app_id asynchronously + sway_fullscreen "${1}" & + + # Create a virtual touch keyboard device if there are two displays + if [[ "${DEVICE_HAS_DUAL_SCREEN}" == "true" ]]; then + TSKEY=$(get_setting "archr.touchscreen-keyboard.enabled") + if [[ "${TSKEY}" == "1" ]]; then + swaymsg 'output DSI-1 power on' + ( + sleep 2 + swaymsg 'seat seat1 fallback yes' + ) & + fi + fi +fi diff --git a/projects/ArchR/packages/apps/portmaster/scripts/start_portmaster.sh b/projects/ArchR/packages/apps/portmaster/scripts/start_portmaster.sh new file mode 100755 index 0000000000..d3472c7537 --- /dev/null +++ b/projects/ArchR/packages/apps/portmaster/scripts/start_portmaster.sh @@ -0,0 +1,75 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile +. /etc/os-release +set_kill set "PortMaster" + +#Make sure PortMaster exists in .config/PortMaster +if [ ! -d "/storage/.config/PortMaster" ]; then + mkdir -p "/storage/.config/PortMaster" + cp -r "/usr/config/PortMaster" "/storage/.config/" +fi + +cd /storage/.config/PortMaster + +#Grab the latest control.txt & mapper.txt, then set correct permissions +cp /usr/config/PortMaster/control.txt control.txt +chmod +x /storage/.config/PortMaster/control.txt +cp /usr/config/PortMaster/mapper.txt mapper.txt +chmod +x /storage/.config/PortMaster/mapper.txt + + +#Use our gamecontrollerdb.txt +rm -r gamecontrollerdb.txt +ln -sf /usr/config/SDL-GameControllerDB/gamecontrollerdb.txt gamecontrollerdb.txt + +#Delete old PortMaster fold first (we can probably remove this later) +if [ ! -f "/storage/roms/ports/PortMaster/pugwash" ]; then + rm -r /storage/roms/ports/PortMaster +fi + +#Make sure roms/ports/PortMaster folder exists +if [ ! -d "/storage/roms/ports/PortMaster" ]; then + unzip /usr/config/PortMaster/release/PortMaster.zip -d /storage/roms/ports/ + chmod +x /storage/roms/ports/PortMaster/PortMaster.sh +fi + +#We dont use tasksetter, delete it +if [ -f /storage/roms/ports/PortMaster/tasksetter ]; then + rm -r /storage/roms/ports/PortMaster/tasksetter +fi + +#Use PortMasters gptokeyb +rm gptokeyb +cp /storage/roms/ports/PortMaster/gptokeyb gptokeyb + +#Copy over required files for ports +cp /storage/.config/PortMaster/control.txt /storage/roms/ports/PortMaster/control.txt +cp /storage/.config/PortMaster/mapper.txt /storage/roms/ports/PortMaster/mapper.txt +cp /storage/.config/PortMaster/gamecontrollerdb.txt /storage/roms/ports/PortMaster/gamecontrollerdb.txt +cp /usr/bin/oga_controls* /storage/roms/ports/PortMaster/ + +#Hide PortMaster folder in ports +if [ ! -f /storage/roms/ports/gamelist.xml ]; then +echo " + + ./PortMaster + PortMaster + true + +" > /storage/roms/ports/gamelist.xml +else + xmlstarlet ed --inplace -d "/gameList/folder[name='PortMaster']" /storage/roms/ports/gamelist.xml + xmlstarlet ed --inplace -d "/gameList/game[name='PortMaster']" /storage/roms/ports/gamelist.xml + xmlstarlet ed --inplace --subnode "/gameList" --type elem -n folder -v "" /storage/roms/ports/gamelist.xml + xmlstarlet ed --inplace --subnode "/gameList/folder[last()]" --type elem -n path -v "./PortMaster" /storage/roms/ports/gamelist.xml + xmlstarlet ed --inplace --subnode "/gameList/folder[last()]" --type elem -n name -v "PortMaster" /storage/roms/ports/gamelist.xml + xmlstarlet ed --inplace --subnode "/gameList/folder[last()]" --type elem -n hidden -v "true" /storage/roms/ports/gamelist.xml +fi + +#Start PortMaster +cd /storage/roms/ports/PortMaster +./PortMaster.sh 2>/dev/null diff --git a/projects/ArchR/packages/apps/portmaster/sources/control.txt b/projects/ArchR/packages/apps/portmaster/sources/control.txt new file mode 100644 index 0000000000..5028fc9a81 --- /dev/null +++ b/projects/ArchR/packages/apps/portmaster/sources/control.txt @@ -0,0 +1,105 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +# This file can and should be sourced by ports for various parameters to +# minimize script customizations and allow for easier future updates +# like adding additional supported devices. +# Thanks to JohnnyonFlame, dhwz, romadu, and shantigilbert for the +# suggestion and assistance with this. +# Source used for gptokeyb available at +# https://github.com/christianhaitian/gptokeyb +# Source used for oga_controls available at +# https://github.com/christianhaitian/oga_controls + +. /etc/profile + +directory="roms" +controlfolder="/$directory/ports/PortMaster" +ESUDO="" +ESUDOKILL="-1" +ESUDOKILL2="-1" +SDLDBUSERFILE="/storage/.config/SDL-GameControllerDB/gamecontrollerdb.txt" +clibs="/usr/lib/compat/" +raloc="/usr/bin" +raconf="--config /storage/.config/retroarch/retroarch.cfg" + +[[ -f "$controlfolder/device_info.txt" ]] && source $controlfolder/device_info.txt +[[ -f "$controlfolder/funcs.txt" ]] && source $controlfolder/funcs.txt + +# $param_device / $LOWRES / $ANALOG_STICKS (also set by device_info.txt) are used in port launch scripts +case "${QUIRK_DEVICE}" in + "Anbernic RG552") + param_device="rg552" + LOWRES="N" + ANALOG_STICKS="2" + ;; + "Hardkernel ODROID-GO-Ultra"|"Powkiddy RGB10 MAX 3 Pro") + param_device="s922x" + LOWRES="N" + ANALOG_STICKS="2" + ;; + "Powkiddy x55") + param_device="x55" + LOWRES="N" + ANALOG_STICKS="2" + ;; + "Anbernic RG351M") + param_device="anbernic" + LOWRES="Y" + ANALOG_STICKS="2" + ;; + "Anbernic RG351V") + param_device="anbernic" + LOWRES="N" + ANALOG_STICKS="1" + ;; + "ODROID-GO Advance*"|"Powkiddy RGB10") + param_device="oga" + LOWRES="Y" + ANALOG_STICKS="1" + ;; + "ODROID-GO Super") + param_device="ogs" + LOWRES="N" + ANALOG_STICKS="2" + ;; + "Anbernic RG35XX H"|"Anbernic RG40XX H"|"Anbernic RG CubeXX") + param_device="anbernic" + LOWRES="N" + ANALOG_STICKS="2" + ;; + "Anbernic RG40XX V") + param_device="anbernic" + LOWRES="N" + ANALOG_STICKS="1" + ;; + "Anbernic RG35XX Plus"|"Anbernic RG35XX 2024"|"Anbernic RG28XX") + param_device="anbernic" + LOWRES="N" + ANALOG_STICKS="0" + ;; + *) + param_device="rg552" + LOWRES="N" + ANALOG_STICKS="2" + ;; +esac + +get_controls() { + # Set controller file to be generated + export SDL_GAMECONTROLLERCONFIG_FILE="/tmp/gamecontrollerdb.txt" + + # Generate controller file for controllers mapped in emulationstation + /storage/.config/PortMaster/mapper.txt ${SDL_GAMECONTROLLERCONFIG_FILE} ${controlfolder} + + # Set compatability libs + export LD_LIBRARY_PATH=${clibs} + + # Some ports want sdl_controllerconfig (to set SDL_GAMECONTROLLERCONFIG), so let's fill it in + sdl_controllerconfig="$(< "${SDL_GAMECONTROLLERCONFIG_FILE}")" +} + +GPTOKEYB2="$ESUDO env LD_PRELOAD=$controlfolder/libinterpose.${DEVICE_ARCH}.so $controlfolder/gptokeyb2 $ESUDOKILL" +GPTOKEYB="$ESUDO $controlfolder/gptokeyb $ESUDOKILL" diff --git a/projects/ArchR/packages/apps/portmaster/sources/mapper.txt b/projects/ArchR/packages/apps/portmaster/sources/mapper.txt new file mode 100644 index 0000000000..c88f4fe746 --- /dev/null +++ b/projects/ArchR/packages/apps/portmaster/sources/mapper.txt @@ -0,0 +1,53 @@ +#!/bin/bash + +. /etc/profile.d/001-functions +. /etc/profile.d/100-gamecontroller-functions + +# -- Config & Setup -- +# Destination file +if [[ -z "$1" ]] && [[ -z "$2" ]]; then + echo "Usage: mapper.txt [gamecontrollerdb.txt] [controlfolder]" + exit -1 +fi + +CONTROLLER_DB="$1" +controlfolder="$2" + +#Scrub the CONTROLLER_DB file +echo "" > ${CONTROLLER_DB} + +# Where the emulationstation configuration file is +ES_CONFIG="/tmp/es_input.cfg" + +#Set layout via Emulation Station +ACTIVE_GAME="" +ACTIVE_PLATFORM="" +GAME="${ACTIVE_GAME##*/}" +PLATFORM="${ACTIVE_PLATFORM##*/}" +CONTROLLER_LAYOUT=$(get_setting controller_layout "${PLATFORM}" "${GAME}") + +#Default to nintendo if no value assigned +if [ ! -n "${CONTROLLER_LAYOUT}" ]; then + CONTROLLER_LAYOUT="nintendo" +fi + +scriptdir="controller_layout" + +if [ ! -d "${controlfolder}/${scriptdir}" ]; then + mkdir -p "${controlfolder}/${scriptdir}" +fi + +echo -e "# Xbox Layout\nABUT=\"b\"\nBBUT=\"a\"\nXBUT=\"y\"\nYBUT=\"x\"" > "${controlfolder}/${scriptdir}/xbox_layout.txt" +echo -e "# Nintendo Layout\nABUT=\"a\"\nBBUT=\"b\"\nXBUT=\"x\"\nYBUT=\"y\"" > "${controlfolder}/${scriptdir}/nintendo_layout.txt" +if [[ ! -e "${controlfolder}/${scriptdir}/custom_layout.txt" ]]; then + echo -e "# Custom Layout\nABUT=\"a\"\nBBUT=\"b\"\nXBUT=\"x\"\nYBUT=\"y\"" > "${controlfolder}/${scriptdir}/custom_layout.txt" +fi + +source "${controlfolder}/${scriptdir}/${CONTROLLER_LAYOUT}_layout.txt" + +# Call function to create controller db from ES input config file for only connected devices +create_controller_db ${CONTROLLER_LAYOUT} ${ES_CONFIG} ${CONTROLLER_DB} + +#Reset file for next run +sed -i '/^ACTIVE_GAME=/c\ACTIVE_GAME=""' /storage/.config/PortMaster/mapper.txt +sed -i '/^ACTIVE_PLATFORM=/c\ACTIVE_PLATFORM=""' /storage/.config/PortMaster/mapper.txt diff --git a/projects/ArchR/packages/apps/qterminal/layer-shell-qt/package.mk b/projects/ArchR/packages/apps/qterminal/layer-shell-qt/package.mk new file mode 100644 index 0000000000..a035f70c3b --- /dev/null +++ b/projects/ArchR/packages/apps/qterminal/layer-shell-qt/package.mk @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2025-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="layer-shell-qt" +PKG_VERSION="v6.4.3" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/KDE/layer-shell-qt" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_LONGDESC="Layer-Shell-QT is meant for applications to be able to easily use clients based on wlr-layer-shell." +PKG_DEPENDS_TARGET="toolchain qt6 ecm" +PKG_TOOLCHAIN="cmake" + +post_makeinstall_target() { + rm -rf ${INSTALL}/usr + mkdir -p ${INSTALL}/usr/lib + cp -rf ${PKG_BUILD}/.${TARGET_NAME}/bin/libLayerShellQtInterface.so* ${INSTALL}/usr/lib +} diff --git a/projects/ArchR/packages/apps/qterminal/lxqt-build-tools/package.mk b/projects/ArchR/packages/apps/qterminal/lxqt-build-tools/package.mk new file mode 100644 index 0000000000..b9785f917a --- /dev/null +++ b/projects/ArchR/packages/apps/qterminal/lxqt-build-tools/package.mk @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2025-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="lxqt-build-tools" +PKG_VERSION="2.2.0" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/lxqt/lxqt-build-tools" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_LONGDESC="Several tools needed to build LXQt itself as well as other components maintained by the LXQt project." +PKG_DEPENDS_TARGET="toolchain qt6" +PKG_TOOLCHAIN="cmake" + +post_makeinstall_target() { + rm -rf ${INSTALL}/usr +} diff --git a/projects/ArchR/packages/apps/qterminal/lxqt-build-tools/patches/000-fix-build.patch b/projects/ArchR/packages/apps/qterminal/lxqt-build-tools/patches/000-fix-build.patch new file mode 100644 index 0000000000..2d6de3c8d6 --- /dev/null +++ b/projects/ArchR/packages/apps/qterminal/lxqt-build-tools/patches/000-fix-build.patch @@ -0,0 +1,13 @@ +diff --git a/cmake/FindInstallConfigPath.cmake b/cmake/FindInstallConfigPath.cmake +index 4ea6552..fbbf5ed 100644 +--- a/cmake/FindInstallConfigPath.cmake ++++ b/cmake/FindInstallConfigPath.cmake +@@ -6,7 +6,7 @@ + # + + find_package(Qt6 ${LXQTBT_QT_MINIMUM_VERSION} REQUIRED) +-find_package(Qt6CoreTools ${LXQTBT_QT_MINIMUM_VERSION} REQUIRED) ++#find_package(Qt6CoreTools ${LXQTBT_QT_MINIMUM_VERSION} REQUIRED) + + macro(print_set_lxqt_etc_xdg_dir_info) + message(STATUS "You can set it manually with -DLXQT_ETC_XDG_DIR=") diff --git a/projects/ArchR/packages/apps/qterminal/package.mk b/projects/ArchR/packages/apps/qterminal/package.mk new file mode 100644 index 0000000000..e5ccafedf4 --- /dev/null +++ b/projects/ArchR/packages/apps/qterminal/package.mk @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2025-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="qterminal" +PKG_VERSION="2.2.1" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/lxqt/qterminal" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_LONGDESC="QTerminal is a lightweight Qt terminal emulator based on QTermWidget." +PKG_DEPENDS_TARGET="toolchain qt6 qtermwidget lxqt-build-tools layer-shell-qt" +PKG_TOOLCHAIN="cmake" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp -rf ${PKG_BUILD}/.${TARGET_NAME}/qterminal ${INSTALL}/usr/bin + chmod 0755 ${INSTALL}/usr/bin/qterminal + + mkdir -p ${INSTALL}/usr/config/modules + cp -rf ${PKG_DIR}/scripts/* ${INSTALL}/usr/config/modules + chmod 0755 ${INSTALL}/usr/config/modules/* +} diff --git a/projects/ArchR/packages/apps/qterminal/patches/000-build-fixes.patch b/projects/ArchR/packages/apps/qterminal/patches/000-build-fixes.patch new file mode 100644 index 0000000000..2744c1230d --- /dev/null +++ b/projects/ArchR/packages/apps/qterminal/patches/000-build-fixes.patch @@ -0,0 +1,13 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 0a431b7..683dc03 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -29,7 +29,7 @@ set(SHELLQT_MINIMUM_VERSION "6.0.0") + + find_package(Qt6Core ${QT_MINIMUM_VERSION} REQUIRED) + find_package(Qt6Gui ${QT_MINIMUM_VERSION} REQUIRED) +-find_package(Qt6LinguistTools ${QT_MINIMUM_VERSION} REQUIRED) ++find_package(Qt6Tools ${QT_MINIMUM_VERSION} REQUIRED) + find_package(Qt6Widgets ${QT_MINIMUM_VERSION} REQUIRED) + find_package(LayerShellQt ${SHELLQT_MINIMUM_VERSION} REQUIRED) + if(UNIX) diff --git a/projects/ArchR/packages/apps/qterminal/patches/001-fullscreen.patch b/projects/ArchR/packages/apps/qterminal/patches/001-fullscreen.patch new file mode 100644 index 0000000000..e3e1d00ffe --- /dev/null +++ b/projects/ArchR/packages/apps/qterminal/patches/001-fullscreen.patch @@ -0,0 +1,22 @@ +diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp +index d5163c8..c327bc9 100644 +--- a/src/mainwindow.cpp ++++ b/src/mainwindow.cpp +@@ -589,7 +589,7 @@ void MainWindow::toggleBorderless() + + void MainWindow::toggleMenu() + { +- m_menuBar->setVisible(!m_menuBar->isVisible()); ++ m_menuBar->setVisible(false); + Properties::Instance()->menuVisible = m_menuBar->isVisible(); + } + +@@ -748,7 +748,7 @@ void MainWindow::propertiesChanged() + } + } + +- m_menuBar->setVisible(Properties::Instance()->menuVisible); ++ m_menuBar->setVisible(false); + + m_bookmarksDock->setVisible(Properties::Instance()->useBookmarks + && Properties::Instance()->bookmarksVisible); diff --git a/projects/ArchR/packages/apps/qterminal/patches/002-font-and-theme.patch b/projects/ArchR/packages/apps/qterminal/patches/002-font-and-theme.patch new file mode 100644 index 0000000000..69956f0b68 --- /dev/null +++ b/projects/ArchR/packages/apps/qterminal/patches/002-font-and-theme.patch @@ -0,0 +1,31 @@ +diff --git a/src/properties.cpp b/src/properties.cpp +index 78cba0b..8201dfc 100644 +--- a/src/properties.cpp ++++ b/src/properties.cpp +@@ -69,7 +69,7 @@ QFont Properties::defaultFont() + { + QFont default_font = QApplication::font(); + default_font.setFamily(QLatin1String(DEFAULT_FONT)); +- default_font.setPointSize(12); ++ default_font.setPointSize(20); + default_font.setStyleHint(QFont::TypeWriter); + return default_font; + } +@@ -80,7 +80,7 @@ void Properties::loadSettings() + if (!guiStyle.isNull()) + QApplication::setStyle(guiStyle); + +- colorScheme = m_settings->value(QLatin1String("colorScheme"), QLatin1String("Linux")).toString(); ++ colorScheme = m_settings->value(QLatin1String("colorScheme"), QLatin1String("WhiteOnBlack")).toString(); + + highlightCurrentTerminal = m_settings->value(QLatin1String("highlightCurrentTerminal"), true).toBool(); + focusOnMoueOver = m_settings->value(QLatin1String("focusOnMoueOver"), false).toBool(); +@@ -126,7 +126,7 @@ void Properties::loadSettings() + /* default to BlockCursor */ + keyboardCursorShape = m_settings->value(QLatin1String("KeyboardCursorShape"), 0).toInt(); + keyboardCursorBlink = m_settings->value(QLatin1String("KeyboardCursorBlink"), false).toBool(); +- hideTabBarWithOneTab = m_settings->value(QLatin1String("HideTabBarWithOneTab"), false).toBool(); ++ hideTabBarWithOneTab = m_settings->value(QLatin1String("HideTabBarWithOneTab"), true).toBool(); + // For "Motion after paste", 2 (scrolling to bottom) makes more sense + m_motionAfterPaste = m_settings->value(QLatin1String("MotionAfterPaste"), 2).toInt(); + m_disableBracketedPasteMode = m_settings->value(QLatin1String("DisableBracketedPasteMode"), false).toBool(); diff --git a/projects/ArchR/packages/apps/qterminal/qtermwidget/package.mk b/projects/ArchR/packages/apps/qterminal/qtermwidget/package.mk new file mode 100644 index 0000000000..27ac3ca663 --- /dev/null +++ b/projects/ArchR/packages/apps/qterminal/qtermwidget/package.mk @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2025-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="qtermwidget" +PKG_VERSION="2.2.0" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/lxqt/qtermwidget" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_LONGDESC="A terminal emulator widget for Qt 6." +PKG_DEPENDS_TARGET="toolchain qt6 lxqt-build-tools" +PKG_TOOLCHAIN="cmake" + +post_makeinstall_target() { + rm -rf ${INSTALL}/usr + + mkdir -p ${INSTALL}/usr/lib + cp -rf ${PKG_BUILD}/.${TARGET_NAME}/libqtermwidget6.so* ${INSTALL}/usr/lib + + mkdir -p ${INSTALL}/usr/config/qterminal.org/color-schemes + cp -rf ${PKG_BUILD}/lib/color-schemes/*.colorscheme ${INSTALL}/usr/config/qterminal.org/color-schemes/ +} diff --git a/projects/ArchR/packages/apps/qterminal/qtermwidget/patches/000-fix-build.patch b/projects/ArchR/packages/apps/qterminal/qtermwidget/patches/000-fix-build.patch new file mode 100644 index 0000000000..44c5817d93 --- /dev/null +++ b/projects/ArchR/packages/apps/qterminal/qtermwidget/patches/000-fix-build.patch @@ -0,0 +1,13 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index bf7aa04..bc7df47 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -36,7 +36,7 @@ set(QT_MINIMUM_VERSION "6.6.0") + set(LXQTBT_MINIMUM_VERSION "2.2.0") + + find_package(Qt6Widgets "${QT_MINIMUM_VERSION}" REQUIRED) +-find_package(Qt6LinguistTools "${QT_MINIMUM_VERSION}" REQUIRED) ++find_package(Qt6Tools "${QT_MINIMUM_VERSION}" REQUIRED) + find_package(lxqt2-build-tools ${LXQTBT_MINIMUM_VERSION} REQUIRED) + + if(USE_UTF8PROC) diff --git a/projects/ArchR/packages/apps/qterminal/scripts/qterminal.sh b/projects/ArchR/packages/apps/qterminal/scripts/qterminal.sh new file mode 100644 index 0000000000..e3d84f2584 --- /dev/null +++ b/projects/ArchR/packages/apps/qterminal/scripts/qterminal.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile +set_kill set "qterminal" + +if [ ! -d "/storage/.config/qterminal.org" ]; then + cp -r "/usr/config/qterminal.org" "/storage/.config/" +fi + +sway_fullscreen "qterminal" & + +cd ~/ +/usr/bin/qterminal diff --git a/projects/ArchR/packages/apps/screen-switch/package.mk b/projects/ArchR/packages/apps/screen-switch/package.mk new file mode 100644 index 0000000000..48fe274118 --- /dev/null +++ b/projects/ArchR/packages/apps/screen-switch/package.mk @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="screen-switch" +PKG_VERSION="1.0" +PKG_LICENSE="GPLv3" +PKG_DEPENDS_TARGET="toolchain sway" +PKG_LONGDESC="A simple script to swap sway output screens" +PKG_TOOLCHAIN="manual" +PKG_PATCH_DIRS+="${DEVICE}" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp -rf ${PKG_DIR}/scripts/screen_switch ${INSTALL}/usr/bin + chmod 0755 ${INSTALL}/usr/bin/* +} diff --git a/projects/ArchR/packages/apps/screen-switch/scripts/screen_switch b/projects/ArchR/packages/apps/screen-switch/scripts/screen_switch new file mode 100644 index 0000000000..dc2568228a --- /dev/null +++ b/projects/ArchR/packages/apps/screen-switch/scripts/screen_switch @@ -0,0 +1,51 @@ +#!/bin/bash + +source /etc/profile + +ACTIVE_APPID=$(swaymsg -t get_tree | awk ' + /"focused": true/ {focused=1} + focused && /"app_id":/ { + gsub(/.*"app_id": *"/,""); gsub(/".*/,""); print; exit + } +') + +if [[ -n "$ACTIVE_APPID" && "$ACTIVE_APPID" = "emulationstation" ]]; then + exit 0 +fi + +OUTPUTS=$(swaymsg -t get_outputs -r | jq -r '.[] | select(.active==true) | .name') + +if [ "$(echo "$OUTPUTS" | wc -l)" -lt 2 ]; then + exit 0 +fi + +BUSY_COUNT=$(swaymsg -t get_tree -r | jq '[.. | select(.type? == "output" and .name != "__i3") + | select([.. | select(.app_id? or .window_properties?) | .name] | length > 0) + | .name] | length') + +TOTAL_OUTPUTS=$(echo "$OUTPUTS" | wc -l) + +if [ "$BUSY_COUNT" -ge "$TOTAL_OUTPUTS" ]; then + exit 0 +fi + +OUT1=$(echo "$OUTPUTS" | sed -n '1p') +OUT2=$(echo "$OUTPUTS" | sed -n '2p') +CURRENT_WORKSPACE=$(swaymsg -t get_tree -r | jq -r ' + [ .nodes[] + | select(.type == "output" and .name != "__i3") + | .nodes[] # workspace...y + | select(.type == "workspace" and .name != "__i3_scratch") + | select(.. | select(.app_id? or .window_properties?) | length > 0) + | .name + ][0] +') + +CURRENT_OUTPUT=$(swaymsg -t get_workspaces -r | jq -r --arg ws "$CURRENT_WORKSPACE" '.[] | select(.name==$ws) | .output') + +if [ "$CURRENT_OUTPUT" = "$OUT1" ]; then + swaymsg workspace ${CURRENT_WORKSPACE}, move workspace to output "$OUT2" + swaymsg focus output "$OUT1" +else + swaymsg workspace ${CURRENT_WORKSPACE}, move workspace to output "$OUT1" +fi diff --git a/projects/ArchR/packages/apps/sdl2text/Makefile b/projects/ArchR/packages/apps/sdl2text/Makefile new file mode 100644 index 0000000000..1108d71a28 --- /dev/null +++ b/projects/ArchR/packages/apps/sdl2text/Makefile @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2025-present ArchR (https://github.com/archr-linux/Arch-R) + +CXX ?= gcc +CCFLAGS = -W -Wall -std=c++11 `sdl2-config --cflags` + +BINARY = sdl2text +LIBRARIES = -lSDL2 -lSDL2_ttf +SOURCES = "sdl2text.cpp" + +all: + $(CXX) $(CFLAGS) $(SOURCES) -o $(BINARY) $(LIBRARIES) + +clean: + rm -f $(BINARY) diff --git a/projects/ArchR/packages/apps/sdl2text/package.mk b/projects/ArchR/packages/apps/sdl2text/package.mk new file mode 100644 index 0000000000..f21ff781d7 --- /dev/null +++ b/projects/ArchR/packages/apps/sdl2text/package.mk @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="sdl2text" +PKG_VERSION="v1.0" +PKG_LICENSE="GPLv2" +PKG_DEPENDS_TARGET="toolchain SDL2 SDL2_ttf" +PKG_LONGDESC="SDL2 text reader with gamepad controls" +PKG_TOOLCHAIN="make" + +pre_make_target() { + cp -f ${PKG_DIR}/Makefile ${PKG_BUILD} + cp -f ${PKG_DIR}/sdl2text.cpp ${PKG_BUILD} + CFLAGS+=" -I$(get_build_dir SDL2)/include -D_REENTRANT" +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp ${PKG_BUILD}/sdl2text ${INSTALL}/usr/bin + cp -rf ${PKG_DIR}/scripts/* ${INSTALL}/usr/bin + chmod 0755 ${INSTALL}/usr/bin/* +} diff --git a/projects/ArchR/packages/apps/sdl2text/scripts/game-guides-tool b/projects/ArchR/packages/apps/sdl2text/scripts/game-guides-tool new file mode 100644 index 0000000000..94a1d321f1 --- /dev/null +++ b/projects/ArchR/packages/apps/sdl2text/scripts/game-guides-tool @@ -0,0 +1,32 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2025-present ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile + +if [ -n "${1}" ]; then + # Make sure sdl2text dir exists + if [ ! -d "/storage/.config/sdl2text" ]; then + mkdir -p "/storage/.config/sdl2text" + fi + + # Check if guide exists for this game and output to temp path + GAME_GUIDE_CHECK="${1%.*}.txt" + + if [ -f "${GAME_GUIDE_CHECK}" ]; then +cat </storage/.config/sdl2text/game_guide.path +${GAME_GUIDE_CHECK} +EOF + else + rm -r "/storage/.config/sdl2text/game_guide.path" + fi +else + # Show game guide if exists + if [ -f "/storage/.config/sdl2text/game_guide.path" ]; then + GAME_GUIDE_PATH="$(cat /storage/.config/sdl2text/game_guide.path)" + /usr/bin/sdl2text "${GAME_GUIDE_PATH}" + else + exit 1 + fi +fi diff --git a/projects/ArchR/packages/apps/sdl2text/sdl2text.cpp b/projects/ArchR/packages/apps/sdl2text/sdl2text.cpp new file mode 100644 index 0000000000..4bc205f19b --- /dev/null +++ b/projects/ArchR/packages/apps/sdl2text/sdl2text.cpp @@ -0,0 +1,398 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2025-present ArchR (https://github.com/archr-linux/Arch-R) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// -------------------- Config Helpers -------------------- +std::filesystem::path get_config_file() { + std::filesystem::path cfgDir = std::filesystem::path(std::getenv("HOME")) / ".config" / "sdl2text"; + std::filesystem::create_directories(cfgDir); + return cfgDir / "sdl2text.conf"; +} + +struct FileConfig { int scroll = 0; int fontSize = 40; }; // default font size 40 + +std::map load_config() { + std::map cfg; + std::ifstream f(get_config_file()); + if(!f.is_open()) return cfg; + std::string line; + while(std::getline(f,line)) { + size_t sep = line.find('='); + if(sep != std::string::npos) { + std::string key = line.substr(0,sep); + std::string val = line.substr(sep+1); + size_t comma = val.find(','); + int scroll = 0; + int font = 40; + if(comma != std::string::npos) { + try { + scroll = std::stoi(val.substr(0,comma)); + font = std::stoi(val.substr(comma+1)); + } catch(...) { } + } + cfg[key] = {scroll,font}; + } + } + return cfg; +} + +void save_config(const std::map& cfg) { + std::ofstream f(get_config_file()); + if(!f.is_open()) return; + for(const auto& [k,v]: cfg) { + f << k << "=" << v.scroll << "," << v.fontSize << "\n"; + } +} + +// -------------------- File & Font Helpers -------------------- +std::vector load_file_lines(const std::string& path) { + std::vector lines; + std::ifstream file(path); + std::string line; + while (std::getline(file, line)) lines.push_back(line); + return lines; +} + +std::string find_any_ttf_font() { + const char* dirs[] = { + "/usr/share/fonts/truetype/", + "/usr/share/fonts/truetype/dejavu/", + "/usr/share/fonts/", + "/usr/local/share/fonts/", + "/system/fonts/" + }; + for (auto dir : dirs) { + DIR* d = opendir(dir); + if (!d) continue; + struct dirent* ent; + while ((ent = readdir(d)) != nullptr) { + std::string name = ent->d_name; + if (name.size() > 4 && name.substr(name.size()-4) == ".ttf") { + closedir(d); + return std::string(dir) + name; + } + } + closedir(d); + } + return ""; +} + +// -------------------- UTF-8 safe filtering -------------------- +static bool font_can_render_codepoint(TTF_Font* font, uint32_t cp) { + if (cp <= 0xFFFF) return TTF_GlyphIsProvided(font, static_cast(cp)) != 0; + return false; +} + +std::string filter_invalid_chars(const std::string& s, TTF_Font* font) { + std::string out; + size_t i = 0; + while (i < s.size()) { + unsigned char c = static_cast(s[i]); + if (c < 0x80) { if (font_can_render_codepoint(font, c)) out.push_back(static_cast(c)); ++i; continue; } + uint32_t cp = 0; size_t seqLen = 0; + + if ((c & 0xE0) == 0xC0) { if (i+1 >= s.size()) { ++i; continue; } unsigned char c1 = s[i+1]; if ((c1 & 0xC0) != 0x80) { ++i; continue; } cp = ((c & 0x1F)<<6)|(c1&0x3F); seqLen=2; if(cp<0x80){i+=2;continue;} } + else if ((c & 0xF0) == 0xE0) { if(i+2>=s.size()){++i;continue;} unsigned char c1=s[i+1],c2=s[i+2]; if((c1&0xC0)!=0x80||(c2&0xC0)!=0x80){++i;continue;} cp=((c&0x0F)<<12)|((c1&0x3F)<<6)|(c2&0x3F); seqLen=3; } + else if ((c & 0xF8) == 0xF0) { if(i+3>=s.size()){++i;continue;} unsigned char c1=s[i+1],c2=s[i+2],c3=s[i+3]; if((c1&0xC0)!=0x80||(c2&0xC0)!=0x80||(c3&0xC0)!=0x80){++i;continue;} cp=((c&0x07)<<18)|((c1&0x3F)<<12)|((c2&0x3F)<<6)|(c3&0x3F); seqLen=4; } + else { ++i; continue; } + + if(seqLen==0){++i;continue;} + if(font_can_render_codepoint(font,cp)) out.append(s.substr(i,seqLen)); + i+=seqLen; + } + return out; +} + +// -------------------- Line wrapping -------------------- +std::vector wrap_line(const std::string& line, TTF_Font* font, int maxWidth) { + std::vector result; + size_t start=0,len=line.length(); + while(startmaxWidth) hi=mid-1; + else { best=mid; lo=mid+1; } + } + std::string chunk=line.substr(start,best); + if(chunk.empty()) chunk=line.substr(start,1); + result.push_back(chunk); + start+=chunk.length(); + } + return result; +} + +// -------------------- Pre-render textures -------------------- +struct LineTexture { SDL_Texture* tex; int w,h; }; + +std::vector create_textures(SDL_Renderer* ren, TTF_Font* font, const std::vector& wrapped, SDL_Color color) { + std::vector textures; + for(auto &line:wrapped) { + SDL_Surface* surf=TTF_RenderUTF8_Blended(font,line.c_str(),color); + if(!surf) continue; + SDL_Texture* tex=SDL_CreateTextureFromSurface(ren,surf); + textures.push_back({tex,surf->w,surf->h}); + SDL_FreeSurface(surf); + } + return textures; +} + +// -------------------- Main -------------------- +int main(int argc,char* argv[]) { + if(argc<2) { std::cout << "Usage: " << argv[0] << " \n"; return 1; } + { + std::filesystem::path cfgDir = + std::filesystem::path(std::getenv("HOME")) / ".config" / "sdl2text"; + std::filesystem::create_directories(cfgDir); + } + + std::filesystem::path textFilePath=std::filesystem::absolute(argv[1]); + std::string textFile=textFilePath.string(); + auto lines=load_file_lines(textFile); + if(lines.empty()) { std::cout << "Failed to load file\n"; return 1; } + + if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_GAMECONTROLLER)!=0) { std::cerr << "SDL_Init error\n"; return 1; } + if(TTF_Init()!=0) { std::cerr << "TTF_Init error\n"; SDL_Quit(); return 1; } + + std::string fontPath=find_any_ttf_font(); + if(fontPath.empty()) { std::cout<<"No TTF font found\n"; TTF_Quit(); SDL_Quit(); return 1; } + + auto cfg=load_config(); + FileConfig fcfg=cfg[textFile]; + int fontSize=fcfg.fontSize; + auto loadFont=[&](int size)->TTF_Font* { TTF_Font* f=TTF_OpenFont(fontPath.c_str(),size); if(!f) std::cout<<"Failed to load font size "< wrapped; + for(auto &line:lines) { + std::string clean=filter_invalid_chars(line,font); + auto chunks=wrap_line(clean,font,WINDOW_W-20); + wrapped.insert(wrapped.end(),chunks.begin(),chunks.end()); + } + auto textures=create_textures(ren,font,wrapped,white); + + bool upPressed=false,downPressed=false,l1Pressed=false,r1Pressed=false,startPressed=false; + bool running=true,showHelp=false; + SDL_Event e; + bool touchActive=false; + float lastTouchY=0.0f; + const float TOUCH_MULTIPLIER=1.75f; + SDL_Color helpColor={255,255,255,255}, boxColor={0,0,0,200}; + + while(running) { + while(SDL_PollEvent(&e)) { + if(e.type==SDL_QUIT) { running=false; break; } + + if(e.type==SDL_CONTROLLERBUTTONDOWN) { + switch(e.cbutton.button) { + case SDL_CONTROLLER_BUTTON_DPAD_UP: upPressed=true; break; + case SDL_CONTROLLER_BUTTON_DPAD_DOWN: downPressed=true; break; + case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: l1Pressed=true; break; + case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: r1Pressed=true; break; + case SDL_CONTROLLER_BUTTON_START: startPressed=true; break; + case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: + fontSize+=2; TTF_CloseFont(font); font=loadFont(fontSize); if(!font){fontSize-=2; font=loadFont(fontSize);} + wrapped.clear(); + for(auto &line:lines) { std::string clean=filter_invalid_chars(line,font); auto chunks=wrap_line(clean,font,WINDOW_W-20); wrapped.insert(wrapped.end(),chunks.begin(),chunks.end()); } + for(auto <:textures) if(lt.tex) SDL_DestroyTexture(lt.tex); + textures=create_textures(ren,font,wrapped,white); lineHeight=TTF_FontHeight(font); break; + case SDL_CONTROLLER_BUTTON_DPAD_LEFT: + fontSize-=2; if(fontSize<8) fontSize=8; TTF_CloseFont(font); font=loadFont(fontSize); if(!font){fontSize+=2; font=loadFont(fontSize);} + wrapped.clear(); + for(auto &line:lines) { std::string clean=filter_invalid_chars(line,font); auto chunks=wrap_line(clean,font,WINDOW_W-20); wrapped.insert(wrapped.end(),chunks.begin(),chunks.end()); } + for(auto <:textures) if(lt.tex) SDL_DestroyTexture(lt.tex); + textures=create_textures(ren,font,wrapped,white); lineHeight=TTF_FontHeight(font); break; + case SDL_CONTROLLER_BUTTON_B: running=false; break; + case SDL_CONTROLLER_BUTTON_BACK: showHelp=!showHelp; break; + } + } + + if(e.type==SDL_CONTROLLERBUTTONUP) { + switch(e.cbutton.button) { + case SDL_CONTROLLER_BUTTON_DPAD_UP: upPressed=false; break; + case SDL_CONTROLLER_BUTTON_DPAD_DOWN: downPressed=false; break; + case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: l1Pressed=false; break; + case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: r1Pressed=false; break; + case SDL_CONTROLLER_BUTTON_START: startPressed=false; break; + } + } + + if(e.type==SDL_FINGERDOWN) { touchActive=true; lastTouchY=e.tfinger.y; } + if(e.type==SDL_FINGERMOTION && touchActive) { float y=e.tfinger.y; float dy_norm=y-lastTouchY; lastTouchY=y; scroll_y+=(int)(-dy_norm*WINDOW_H*TOUCH_MULTIPLIER); } + if(e.type==SDL_FINGERUP) touchActive=false; + } + + // Controller continuous scrolling + if(upPressed) scroll_y-=SCROLL_SPEED; + if(downPressed) scroll_y+=SCROLL_SPEED; + if(l1Pressed) scroll_y-=SKIP_LINES*lineHeight; + if(r1Pressed) scroll_y+=SKIP_LINES*lineHeight; + + // Secret kill combo: L1 + START + SELECT + if(l1Pressed && startPressed && SDL_GameControllerGetButton(pad, SDL_CONTROLLER_BUTTON_BACK)) running=false; + + // Clamp + int total_height=(int)textures.size()*lineHeight; + if(total_heighttotal_height-WINDOW_H) scroll_y=total_height-WINDOW_H; + + // Render + SDL_SetRenderDrawColor(ren,0,0,0,255); SDL_RenderClear(ren); + int firstLine=scroll_y/lineHeight, offsetY=-(scroll_y%lineHeight); + for(size_t i=firstLine;i helpLines={ + "CONTROLS:", + "SELECT - Toggle This Help", + "DPAD UP/DOWN - Scroll Up / Down", + "L1/R1 - Skip Up / Down", + "DPAD LEFT/RIGHT - Dec / Inc Font Size", + "Touch Drag - Scroll Up / Down", + "B - Exit" + }; + + // Calculate box height based on content + int lineHeight=TTF_FontLineSkip(font); // Get typical line height + int boxH=40+(helpLines.size()*(lineHeight+8)); // Top margin + all lines with spacing + int boxW=WINDOW_W/2; + int boxX=(WINDOW_W-boxW)/2, boxY=(WINDOW_H-boxH)/2; + + SDL_Rect helpBox={boxX,boxY,boxW,boxH}; + SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawColor(ren, boxColor.r, boxColor.g, boxColor.b, boxColor.a); + SDL_RenderFillRect(ren,&helpBox); + + int ty=boxY+20; + int columnSplit=375; + + for(auto &line:helpLines) { + size_t dashPos=line.find(" - "); + if(dashPos!=std::string::npos) { + std::string leftPart=line.substr(0,dashPos); + std::string rightPart=line.substr(dashPos); + + SDL_Surface* surf1=TTF_RenderUTF8_Blended(font,leftPart.c_str(),helpColor); + if(surf1) { + SDL_Texture* tex1=SDL_CreateTextureFromSurface(ren,surf1); + SDL_Rect dst1={boxX+20,ty,surf1->w,surf1->h}; + SDL_RenderCopy(ren,tex1,nullptr,&dst1); + int lineHeight=surf1->h; + SDL_DestroyTexture(tex1); + SDL_FreeSurface(surf1); + + SDL_Surface* surf2=TTF_RenderUTF8_Blended(font,rightPart.c_str(),helpColor); + if(surf2) { + SDL_Texture* tex2=SDL_CreateTextureFromSurface(ren,surf2); + SDL_Rect dst2={boxX+20+columnSplit,ty,surf2->w,surf2->h}; + SDL_RenderCopy(ren,tex2,nullptr,&dst2); + SDL_DestroyTexture(tex2); + SDL_FreeSurface(surf2); + } + ty+=lineHeight+8; + } + } else { + SDL_Surface* surf=TTF_RenderUTF8_Blended(font,line.c_str(),helpColor); + if(surf) { + SDL_Texture* tex=SDL_CreateTextureFromSurface(ren,surf); + SDL_Rect dst={boxX+20,ty,surf->w,surf->h}; + SDL_RenderCopy(ren,tex,nullptr,&dst); + ty+=surf->h+8; + SDL_DestroyTexture(tex); + SDL_FreeSurface(surf); + } + } + } + } + + // ---- Line Counter (bottom-right) ---- + { + int currentLine = scroll_y / lineHeight + 1; + int totalLines = (int)textures.size(); + + if (currentLine < 1) currentLine = 1; + if (currentLine > totalLines) currentLine = totalLines; + + std::string lcText = std::to_string(currentLine) + "/" + std::to_string(totalLines); + + SDL_Color lcColor = {255,255,255,255}; + + SDL_Surface* lcSurf = TTF_RenderUTF8_Blended(font, lcText.c_str(), lcColor); + if (lcSurf) { + SDL_Texture* lcTex = SDL_CreateTextureFromSurface(ren, lcSurf); + if (lcTex) { + SDL_Rect textRect; + textRect.w = lcSurf->w; + textRect.h = lcSurf->h; + textRect.x = WINDOW_W - textRect.w - 15; + textRect.y = WINDOW_H - textRect.h - 10; + + // transparent background box + SDL_Rect bgRect; + bgRect.x = textRect.x - 8; + bgRect.y = textRect.y - 4; + bgRect.w = textRect.w + 16; + bgRect.h = textRect.h + 8; + + SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawColor(ren, 0, 0, 0, 200); + SDL_RenderFillRect(ren, &bgRect); + + SDL_RenderCopy(ren, lcTex, nullptr, &textRect); + + SDL_DestroyTexture(lcTex); + } + SDL_FreeSurface(lcSurf); + } + } + + SDL_RenderPresent(ren); + SDL_Delay(16); + } + + // Save config + cfg[textFile]={scroll_y,fontSize}; + save_config(cfg); + + for(auto <:textures) if(lt.tex) SDL_DestroyTexture(lt.tex); + if(pad) SDL_GameControllerClose(pad); + if(font) TTF_CloseFont(font); + if(ren) SDL_DestroyRenderer(ren); + if(win) SDL_DestroyWindow(win); + TTF_Quit(); + SDL_Quit(); + return 0; +} diff --git a/projects/ArchR/packages/apps/sdljoytest/package.mk b/projects/ArchR/packages/apps/sdljoytest/package.mk new file mode 100644 index 0000000000..f6eb15778b --- /dev/null +++ b/projects/ArchR/packages/apps/sdljoytest/package.mk @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2020-present Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="sdljoytest" +PKG_VERSION="811d9875e0c13e0c87d93351e69169bf74d28270" +PKG_LICENSE="OSS" +PKG_SITE="https://github.com/Wintermute0110/sdljoytest" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain SDL2" +PKG_LONGDESC="Test joystick with SDL2 in Linux" +PKG_TOOLCHAIN="make" + +pre_configure_target() { +sed -i "s|gcc|${CC}|" Makefile +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp -rf test_gamepad_SDL2 ${INSTALL}/usr/bin + ln -s test_gamepad_SDL2 ${INSTALL}/usr/bin/sdljoytest + cp -rf map_gamepad_SDL2 ${INSTALL}/usr/bin + ln -s map_gamepad_SDL2 ${INSTALL}/usr/bin/sdljoymap +} diff --git a/projects/ArchR/packages/apps/sdltouchtest/package.mk b/projects/ArchR/packages/apps/sdltouchtest/package.mk new file mode 100644 index 0000000000..f49e5114ed --- /dev/null +++ b/projects/ArchR/packages/apps/sdltouchtest/package.mk @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="sdltouchtest" +PKG_VERSION="b62dae0d6233869a4c70a9472bc1e93dec391f94" +PKG_LICENSE="MIT" +PKG_SITE="https://github.com/realchonk/sdl2-touch-test" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain SDL2" +PKG_LONGDESC="SDL2 touchscreen tester" +PKG_TOOLCHAIN="make" + +pre_configure_target() { + sed -i "s|gcc|${CC}|" Makefile +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp ${PKG_BUILD}/test ${INSTALL}/usr/bin/sdltouchtest + chmod 0755 ${INSTALL}/usr/bin/* + +case ${DEVICE} in + RK3399|RK35*|SM8250|SM8550|SDM845) + mkdir -p ${INSTALL}/usr/config/modules + cp -rf ${PKG_DIR}/scripts/* ${INSTALL}/usr/config/modules + chmod 0755 ${INSTALL}/usr/config/modules/* + ;; +esac +} diff --git a/projects/ArchR/packages/apps/sdltouchtest/patches/000-sdltouchtest.patch b/projects/ArchR/packages/apps/sdltouchtest/patches/000-sdltouchtest.patch new file mode 100644 index 0000000000..19f125800d --- /dev/null +++ b/projects/ArchR/packages/apps/sdltouchtest/patches/000-sdltouchtest.patch @@ -0,0 +1,264 @@ +diff --git a/test.c b/test.c +index 8ff9eb3..9ec3be2 100644 +--- a/test.c ++++ b/test.c +@@ -3,105 +3,164 @@ + #include + #include + +-#define stop_timer(tid) \ +-do { \ +- if (tid) { \ +- SDL_RemoveTimer (tid); \ +- tid = 0; \ +- } \ ++#define MAX_FINGERS 10 ++ ++// Stop timer macro definition ++#define stop_timer(tid) \ ++do { \ ++ if (tid) { \ ++ SDL_RemoveTimer(tid); \ ++ tid = 0; \ ++ } \ + } while (0) + +- +-static Uint32 cb_haptic (Uint32 interval, void *arg) { +- SDL_Haptic *haptic = arg; +- +- if (haptic) { +- SDL_HapticRumblePlay (haptic, 0.5f, 250); +- } ++// Define a custom structure to store finger information ++typedef struct { ++ int touchId; ++ float x, y; ++} Finger; ++ ++// Haptic callback function ++static Uint32 cb_haptic(Uint32 interval, void *arg) { ++ SDL_Haptic *haptic = arg; ++ if (haptic) { ++ SDL_HapticRumblePlay(haptic, 0.5f, 250); // Trigger a short rumble ++ } ++ return 0; // No need to repeat + } + +-int main (void) { +- SDL_Init (SDL_INIT_EVERYTHING); +- SDL_Window *window = SDL_CreateWindow ( +- "Test", +- SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, +- 720, 1440, +- SDL_WINDOW_SHOWN +- ); +- if (!window) +- return 1; +- +- SDL_Renderer *renderer = SDL_CreateRenderer (window, -1, SDL_RENDERER_ACCELERATED); +- if (!renderer) +- return 1; +- +- SDL_Haptic *haptic = SDL_HapticOpen (0); +- if (haptic) { +- SDL_HapticRumbleInit (haptic); +- } else { +- +- printf ("No haptic device found.\n"); +- } +- +- int ww, wh, num_fingers = 0; +- SDL_GetWindowSize (window, &ww, &wh); +- float x = 0.0f, y = 0.0f; +- float scale = 50.0f; +- SDL_TimerID timerID = 0; +- +- while (1) { +- SDL_Event e; +- while (SDL_PollEvent (&e)) { +- switch (e.type) { +- case SDL_QUIT: +- goto end; +- +- case SDL_MULTIGESTURE: +- if (e.mgesture.numFingers == 2) { +- stop_timer (timerID); +- scale *= 1.0f + e.mgesture.dDist * 5.0f; +- } +- /*printf ("touchId = %u\n", (unsigned)e.mgesture.touchId); +- printf ("dTheta = %f\n", e.mgesture.dTheta); +- printf ("dDist = %f\n", e.mgesture.dDist); +- printf ("x = %f\n", e.mgesture.x); +- printf ("y = %f\n", e.mgesture.y); +- printf ("num_fingers = %u\n", (unsigned)e.mgesture.numFingers);*/ +- break; +- case SDL_FINGERDOWN: +- if (!timerID && num_fingers == 0) +- timerID = SDL_AddTimer (500, &cb_haptic, haptic); +- +- ++num_fingers; +- break; +- case SDL_FINGERUP: +- stop_timer (timerID); +- --num_fingers; +- break; +- case SDL_FINGERMOTION: +- if (num_fingers == 1) { +- stop_timer (timerID); +- x += e.tfinger.dx; +- y += e.tfinger.dy; +- } +- break; +- } +- } +- SDL_SetRenderDrawColor (renderer, 255, 255, 255, 255); +- SDL_RenderClear (renderer); +- +- const SDL_Rect rect = { x * ww, y * wh, scale, scale }; +- SDL_SetRenderDrawColor (renderer, 0, 0, 0, 255); +- SDL_RenderFillRect (renderer, &rect); +- +- SDL_RenderPresent (renderer); +- } ++int main() { ++ if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { ++ printf("SDL_Init Error: %s\n", SDL_GetError()); ++ return 1; ++ } ++ ++ // Get the current screen resolution ++ SDL_DisplayMode mode; ++ if (SDL_GetDesktopDisplayMode(0, &mode) != 0) { ++ printf("SDL_GetDesktopDisplayMode Error: %s\n", SDL_GetError()); ++ return 1; ++ } ++ int screen_width = mode.w; ++ int screen_height = mode.h; ++ ++ // Create a fullscreen window ++ SDL_Window *window = SDL_CreateWindow( ++ "Test", ++ SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, ++ screen_width, screen_height, ++ SDL_WINDOW_FULLSCREEN ++ ); ++ ++ if (!window) { ++ printf("SDL_CreateWindow Error: %s\n", SDL_GetError()); ++ return 1; ++ } ++ ++ // Create the renderer ++ SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); ++ if (!renderer) { ++ printf("SDL_CreateRenderer Error: %s\n", SDL_GetError()); ++ return 1; ++ } ++ ++ // Check for haptic support ++ SDL_Haptic *haptic = SDL_HapticOpen(0); ++ if (haptic) { ++ SDL_HapticRumbleInit(haptic); ++ } else { ++ printf("No haptic device found.\n"); ++ } ++ ++ // Initialize variables ++ int ww, wh, num_fingers = 0; ++ SDL_GetWindowSize(window, &ww, &wh); ++ float scale = 50.0f; ++ SDL_TimerID timerID = 0; ++ ++ // Store positions of active fingers (custom structure) ++ Finger fingers[MAX_FINGERS]; ++ for (int i = 0; i < MAX_FINGERS; ++i) { ++ fingers[i].touchId = -1; // Mark all touchIds as unused initially ++ } ++ ++ // Variables for tracking the position of the square ++ float square_x = 0.0f, square_y = 0.0f; // To track the movement of the square ++ ++ // Main loop ++ while (1) { ++ SDL_Event e; ++ while (SDL_PollEvent(&e)) { ++ switch (e.type) { ++ case SDL_QUIT: ++ goto end; ++ ++ case SDL_FINGERDOWN: ++ // Ensure that we don't exceed MAX_FINGERS ++ if (num_fingers < MAX_FINGERS) { ++ if (!timerID && num_fingers == 0) ++ timerID = SDL_AddTimer(500, &cb_haptic, haptic); ++ ++ // Find an empty slot for the new finger ++ for (int i = 0; i < MAX_FINGERS; ++i) { ++ if (fingers[i].touchId == -1) { ++ fingers[i].touchId = e.tfinger.touchId; ++ fingers[i].x = e.tfinger.x; ++ fingers[i].y = e.tfinger.y; ++ ++num_fingers; ++ break; ++ } ++ } ++ } ++ break; ++ ++ case SDL_FINGERUP: ++ stop_timer(timerID); ++ ++ // Remove the finger from tracking ++ for (int i = 0; i < MAX_FINGERS; ++i) { ++ if (fingers[i].touchId == e.tfinger.touchId) { ++ fingers[i].touchId = -1; ++ --num_fingers; ++ break; ++ } ++ } ++ break; ++ ++ case SDL_FINGERMOTION: ++ // Handle finger motion for moving the square ++ for (int i = 0; i < MAX_FINGERS; ++i) { ++ if (fingers[i].touchId == e.tfinger.touchId) { ++ // Update the square position based on this finger ++ square_x = e.tfinger.x * ww; // Convert normalized X to pixel ++ square_y = e.tfinger.y * wh; // Convert normalized Y to pixel ++ break; ++ } ++ } ++ break; ++ } ++ } ++ ++ // Render ++ SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); ++ SDL_RenderClear(renderer); ++ ++ // Calculate the new position and scale of the square ++ const SDL_Rect rect = {(int)(square_x - scale / 2), (int)(square_y - scale / 2), (int)(scale), (int)(scale)}; ++ SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); ++ SDL_RenderFillRect(renderer, &rect); ++ ++ SDL_RenderPresent(renderer); ++ } + + end: +- if (haptic) +- SDL_HapticClose (haptic); +- SDL_DestroyRenderer (renderer); +- SDL_DestroyWindow (window); +- SDL_Quit (); ++ // Cleanup ++ if (haptic) { ++ SDL_HapticClose(haptic); ++ } ++ SDL_DestroyRenderer(renderer); ++ SDL_DestroyWindow(window); ++ SDL_Quit(); ++ ++ return 0; + } +- diff --git a/projects/ArchR/packages/apps/sdltouchtest/scripts/Test Touchscreen.sh b/projects/ArchR/packages/apps/sdltouchtest/scripts/Test Touchscreen.sh new file mode 100644 index 0000000000..493bf5d5fe --- /dev/null +++ b/projects/ArchR/packages/apps/sdltouchtest/scripts/Test Touchscreen.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +source /etc/profile + +set_kill set "-9 sdltouchtest" + +/usr/bin/sdltouchtest diff --git a/projects/ArchR/packages/archr/autostart/001-setup b/projects/ArchR/packages/archr/autostart/001-setup new file mode 100755 index 0000000000..a33b74e984 --- /dev/null +++ b/projects/ArchR/packages/archr/autostart/001-setup @@ -0,0 +1,42 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +if [ -d "/storage/cache/.cores" ] +then + rm -rf /storage/cache/.cores +fi + +if [ ! -d "/tmp/cache" ] +then + mkdir -p /tmp/cache +fi + +ln -sf /tmp/cache /storage/cache/.cores + +if [ ! -d "/storage/.config/profile.d" ] +then + mkdir -p /storage/.config/profile.d +fi + +### Inspect the system config and revert +### to last known good state if corrupt. +/usr/bin/chksysconfig verify + +### Clean up settings +sort_settings + +### We do not want to mount the cloud drive on startup +### so we'll reset the mount option to 0. +set_setting clouddrive.mounted 0 + +### Set up the runtime directory. +if [ ! -d "/var/run/0-runtime-dir" ] +then + mkdir -p /var/run/0-runtime-dir +fi + +chmod 0700 /var/run/0-runtime-dir diff --git a/projects/ArchR/packages/archr/autostart/003-upgrade b/projects/ArchR/packages/archr/autostart/003-upgrade new file mode 100755 index 0000000000..5021e7c280 --- /dev/null +++ b/projects/ArchR/packages/archr/autostart/003-upgrade @@ -0,0 +1,18 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +if [ "$(cat /storage/.boot.hint 2>/dev/null)" = "UPDATE" ] +then + if [ -e "/usr/share/post-update" ] + then + tocon "Performing post-update configuration..." + /usr/share/post-update >/var/log/upgrade.log 2>&1 + fi + rm /storage/.boot.hint +else + echo "No update hint found." >/var/log/upgrade.log 2>&1 +fi diff --git a/projects/ArchR/packages/archr/autostart/006-display b/projects/ArchR/packages/archr/autostart/006-display new file mode 100755 index 0000000000..339d96d19b --- /dev/null +++ b/projects/ArchR/packages/archr/autostart/006-display @@ -0,0 +1,29 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-24 JELOS (https://github.com/JustEnoughLinuxOS) +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +tocon "Configuring display..." + +BRIGHTNESS_1=$(get_setting display.brightness) +DEFAULT_BRIGHTNESS="10" +MIN_BRIGHTNESS="5" + +if [ -z "${BRIGHTNESS_1}" ] || [ "${BRIGHTNESS_1}" -lt "${MIN_BRIGHTNESS}" ]; then + BRIGHTNESS_1="${DEFAULT_BRIGHTNESS}" +fi + +brightness set "${BRIGHTNESS_1}" + +BRIGHTNESS_2=$(get_setting display.brightness2) + +if [ -n "${BRIGHTNESS_2}" ]; then + if [ "${BRIGHTNESS_2}" -lt "${MIN_BRIGHTNESS}" ]; then + BRIGHTNESS_2="${DEFAULT_BRIGHTNESS}" + fi + + brightness set 2 "${BRIGHTNESS_2}" +fi diff --git a/projects/ArchR/packages/archr/autostart/007-rootpw b/projects/ArchR/packages/archr/autostart/007-rootpw new file mode 100755 index 0000000000..7dea564e5c --- /dev/null +++ b/projects/ArchR/packages/archr/autostart/007-rootpw @@ -0,0 +1,17 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +tocon "Setting root password..." + +if [ ! -d "/storage/.cache/samba" ] +then + mkdir -p /storage/.cache/samba + touch /storage/.cache/samba/smbpasswd +fi + +ROOTPASS=$(get_setting root.password) +setrootpass "${ROOTPASS}" diff --git a/projects/ArchR/packages/archr/autostart/008-perfmode b/projects/ArchR/packages/archr/autostart/008-perfmode new file mode 100755 index 0000000000..5b1cab804e --- /dev/null +++ b/projects/ArchR/packages/archr/autostart/008-perfmode @@ -0,0 +1,37 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-24 JELOS (https://github.com/JustEnoughLinuxOS) +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions +. /etc/profile.d/099-freqfunctions + +tocon "Setting performance mode..." + +### Enable the desired number of threads. +tocon "Restoring cpu threads..." +NUMTHREADS=$(get_setting "system.threads") +if [ -n "${NUMTHREADS}" ]; then + onlinethreads ${NUMTHREADS} 0 +else + onlinethreads all 1 +fi + +### If we don't have a default governor set, set it +### to ondemand if the device supports it, otherwise +### set to performance, but don't enable it. +if [ -z "$(get_setting system.cpugovernor)" ]; then + GOVTEST="$(awk '/ondemand/ {print $1}' /sys/devices/system/cpu/cpufreq/policy0/scaling_available_governors)" + if [ -n "${GOVTEST}" ]; then + set_setting system.cpugovernor ondemand + else + set_setting system.cpugovernor performance + fi +fi + +### Set the default GPU performance mode +GPUPERF=$(get_setting system.gpuperf) +if [ -n "${GPUPERF}" ]; then + gpu_performance_level ${GPUPERF} +fi diff --git a/projects/ArchR/packages/archr/autostart/009-sleepmode b/projects/ArchR/packages/archr/autostart/009-sleepmode new file mode 100755 index 0000000000..74482f941c --- /dev/null +++ b/projects/ArchR/packages/archr/autostart/009-sleepmode @@ -0,0 +1,17 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +tocon "Configure suspend mode..." + +### Configure suspend mode. +MYSLEEPMODE=$(get_setting system.suspendmode) +if [ -n "${MYSLEEPMODE}" ] +then + /usr/bin/suspendmode ${MYSLEEPMODE} +else + /usr/bin/suspendmode mem +fi diff --git a/projects/ArchR/packages/archr/autostart/010-uimode b/projects/ArchR/packages/archr/autostart/010-uimode new file mode 100755 index 0000000000..9e9187d676 --- /dev/null +++ b/projects/ArchR/packages/archr/autostart/010-uimode @@ -0,0 +1,26 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +tocon "Configuring user interface..." + +UIMODE=$(get_setting desktop.enabled) +if [ "${UIMODE}" = "1" ] || \ + [ ! -e "/usr/bin/emulationstation" ] +then + cp -f /usr/share/weston/weston.ini /storage/.config/weston.ini +else + cp -f /usr/share/weston/kiosk.ini /storage/.config/weston.ini +fi + +STARTUP=$(get_setting weston.startup) +if [ -z "${STARTUP}" ] && \ + [ -e "/usr/bin/emulationstation" ] +then + STARTUP="/usr/bin/start_es.sh" + set_setting weston.startup "${STARTUP}" +fi +sed -i "s#@STARTUP@#${STARTUP}#g" /storage/.config/weston.ini diff --git a/projects/ArchR/packages/archr/autostart/050-audio b/projects/ArchR/packages/archr/autostart/050-audio new file mode 100755 index 0000000000..48c94cd3f5 --- /dev/null +++ b/projects/ArchR/packages/archr/autostart/050-audio @@ -0,0 +1,51 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +tocon "Configuring Audio..." + +STATE=$(systemctl is-active pipewire-pulse) +if [ "${STATE}" = "inactive" ] +then + systemctl start pipewire-pulse +fi + +### Auto switch between internal and bluetooth devices +pactl load-module module-switch-on-connect blocklist="DirtyWave_M8|hdmi" 2>/dev/null + +### Set up audio routing (Internal or HDMI) +/usr/bin/hdmi_sense 2>/dev/null + +### Set the default audio path, needed for some devices +if [ ! -z "${DEVICE_PLAYBACK_PATH_SPK}" ] +then + if [ -z "${DEVICE_PLAYBACK_PATH}" ] + then + export DEVICE_PLAYBACK_PATH="Playback Path" + fi + amixer -c ${ALSA_PRIMARY_CARD:-0} cset name="${DEVICE_PLAYBACK_PATH}" ${DEVICE_PLAYBACK_PATH_SPK} 2>/dev/null +fi + +VOLUME=$(get_setting audio.volume) +if [ -z ${VOLUME} ] +then + VOLUME="60" +elif [ -n "${DEVICE_VOLUME}" ] +then + VOLUME="${DEVICE_VOLUME}" +fi + +### Set the primary card volume to 100% +### to eliminate low audio on some devices. + amixer -c ${ALSA_PRIMARY_CARD:-0} -q sset "Master" 100% + +### Now set the pipewire mixer volume +/usr/bin/volume ${VOLUME} + +### Run quantum audio hack if exists +if [ -n "/usr/sbin/quantum" ]; then + /usr/sbin/quantum +fi diff --git a/projects/ArchR/packages/archr/autostart/055-hdmi-check b/projects/ArchR/packages/archr/autostart/055-hdmi-check new file mode 100755 index 0000000000..9bb3362b54 --- /dev/null +++ b/projects/ArchR/packages/archr/autostart/055-hdmi-check @@ -0,0 +1,29 @@ +#!/bin/bash +# SPDX-License-Identifier: MIT +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) +# Copyright (C) 2023-present christianhaitian (https://github.com/christianhaitian) +# Copyright (C) 2023-present Rocky5 (https://github.com/rocky5) + +# The purpose of this script is to permanently set the resolution +# output for hdmi when connected. + +xres="$(cat /sys/class/graphics/fb0/modes | grep -o -P '(?<=:).*(?=p-)' | cut -dx -f1)" + +# drm_tool source available at https://github.com/christianhaitian/drm_tool.git + +mode="$(/usr/bin/drm_tool list | awk '/1280x720.*60/ {print substr($2,1,length($2)-1); exit}')" +mode2="$(/usr/bin/drm_tool list | awk '/1920x1080.*60/ {print substr($2,1,length($2)-1); exit}')" + +# Now we tell drm what the hdmi mode is by writing to /var/run/drmMode +# This will get picked up by SDL2 as long as it's been patched with the batocera +# drm resolution patch. This patch can be found at +# https://github.com/christianhaitian/rk3566_core_builds/raw/master/patches/sdl2-patch-0003-drm-resolution.patch + +if [ $xres -eq "1280" ]; then + echo $mode | tee /var/run/drmMode +elif [ $xres -eq "1920" ]; then + echo $mode2 | tee /var/run/drmConn +else + echo 0 | tee /var/run/drmMode + echo 1 | tee /var/run/drmConn +fi diff --git a/projects/ArchR/packages/archr/autostart/081-usbgadget b/projects/ArchR/packages/archr/autostart/081-usbgadget new file mode 100755 index 0000000000..3943419f94 --- /dev/null +++ b/projects/ArchR/packages/archr/autostart/081-usbgadget @@ -0,0 +1,5 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +/usr/bin/usbgadget --start diff --git a/projects/ArchR/packages/archr/autostart/099-networkservices b/projects/ArchR/packages/archr/autostart/099-networkservices new file mode 100755 index 0000000000..7b605c6496 --- /dev/null +++ b/projects/ArchR/packages/archr/autostart/099-networkservices @@ -0,0 +1,42 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +tocon "Starting services..." + +for SERVICE in /usr/lib/autostart/daemons/* +do + source ${SERVICE} + + + if [ ! -d "/storage/.cache/services" ] + then + mkdir -p "/storage/.cache/services" + fi + + if [ -n "${CONF}" ] && \ + [ -e "/storage/.cache/services/${CONF}" ] + then + rm -f "/storage/.cache/services/${CONF}" + fi + + statemgr() { + for daemon in ${DAEMONS[@]} + do + nohup systemctl ${1} ${daemon} & + done + } + + case "$STATE" in + "1") + touch "/storage/.cache/services/${CONF}" + statemgr start + ;; + *) + statemgr stop + ;; + esac +done diff --git a/projects/ArchR/packages/archr/config/system/configs/system.cfg b/projects/ArchR/packages/archr/config/system/configs/system.cfg new file mode 100644 index 0000000000..dca536fdf0 --- /dev/null +++ b/projects/ArchR/packages/archr/config/system/configs/system.cfg @@ -0,0 +1,218 @@ +3do.integerscale=0 +3do.ratio=4/3 +advmame_auto_gamepad=0 +amigacd32.integerscale=0 +amigacd32.ratio=4/3 +amiga.integerscale=0 +amiga.ratio=4/3 +amstradcpc.integerscale=0 +arcade.autosave=0 +atari2600.integerscale=0 +atari5200.integerscale=0 +atari7800.integerscale=0 +atari800.integerscale=0 +atarilynx.integerscale=0 +atarilynx.ratio=core +atarist.integerscale=0 +atomiswave.integerscale=0 +atomiswave.ratio=4/3 +audio.bgmusic=1 +audio.device=headphone +audio.display_titles=1 +audio.persystem=0 +audio.preamp=50 +audio.volume=60 +boot=Emulationstation +c128.integerscale=0 +c16.integerscale=0 +c64.integerscale=0 +cdi.integerscale=0 +cdi.ratio=4/3 +chip-8.integerscale=0 +cloud.backup=0 +colecovision.integerscale=0 +colecovision.ratio=4/3 +controllers.bluetooth.enabled=0 +cooling.profile=quiet +cps1.integerscale=0 +cps2.integerscale=0 +cps3.integerscale=0 +daphne.integerscale=0 +daphne.ratio=4/3 +desktop.enabled=0 +display.brightness=50 +display.contrast=50 +display.hue=50 +display.saturation=50 +dreamcast.integerscale=0 +dreamcast.ratio=4/3 +easyrpg.integerscale=0 +famicom.integerscale=0 +famicom.ratio=4/3 +fbn.integerscale=0 +fbn.ratio=core +fds.integerscale=0 +fds.ratio=4/3 +fstrim.enabled=0 +gamegear.integerscale=0 +gbah.ratio=3/2 +gba.ratio=3/2 +gbch.integerscale=0 +gbc.integerscale=0 +gbh.integerscale=0 +gb.integerscale=0 +genesis.integerscale=0 +genesis.ratio=4/3 +genh.integerscale=0 +genh.ratio=4/3 +ggh.integerscale=0 +global.analogue=1 +global.autosave=1 +global.bezel=thebezelproject +global.savestates=1 +global.incrementalsavestates=0 +global.netplay=0 +global.netplay.port=55435 +global.netplay.relay=none +global.ratio=core +global.retroachievements=0 +global.retroachievements.challengeindicators=0 +global.retroachievements.hardcore=0 +global.retroachievements.leaderboards=disabled +global.retroachievements.password= +global.retroachievements.richpresence=0 +global.retroachievements.screenshot=0 +global.retroachievements.soundenable=0 +global.retroachievements.testunofficial=0 +global.retroachievements.username= +global.retroachievements.verbose=0 +global.retroarch.menu_driver=ozone +global.rewind=0 +global.runahead=0 +global.secondinstance=0 +intellivision.integerscale=0 +intellivision.ratio=4/3 +mame.autosave=0 +mame.integerscale=0 +mastersystem.integerscale=0 +megacd.integerscale=0 +megacd.ratio=4/3 +megadrive.integerscale=0 +megadrive-japan.integerscale=0 +megadrive-japan.ratio=4/3 +megadrive.ratio=4/3 +megaduck.integerscale=0 +moto.integerscale=0 +moto.ratio=4/3 +msx2.integerscale=0 +msx2.ratio=4/3 +msx.integerscale=0 +msx.ratio=4/3 +mu.integerscale=0 +n64.controller_pak=2 +n64.game_aspect_ratio=4:3 +n64.input_configuration=zlswap +n64.integerscale=0 +n64.internal_resolution=1 +n64.parallel_n64_gamespeed=fullspeed +n64.parallel_n64_gfx_accuracy=medium +n64.parallel_n64_internal_resolution=480p +n64.parallel_n64_video_core=glide64 +n64.ratio=4/3 +n64.rsp_plugin=hle +n64.show_fps=0 +naomi.integerscale=0 +naomi.ratio=4/3 +neocd.integerscale=0 +neocd.ratio=core +neogeo.integerscale=0 +neogeo.ratio=core +nesh.integerscale=0 +nesh.ratio=4/3 +nes.integerscale=0 +nes.ratio=4/3 +ngpc.intergerscale=1 +ngp.integerscale=0 +odyssey2.integerscale=0 +odyssey2.ratio=4/3 +pc-9800.integerscale=0 +pc-9800.ratio=4/3 +pcenginecd.integerscale=0 +pcenginecd.ratio=4/3 +pcengine.integerscale=0 +pcengine.ratio=4/3 +pcfx.integerscale=0 +pcfx.ratio=4/3 +pc.integerscale=0 +pc.ratio=4/3 +pet.ratio=4/3 +pokemini.ratio=3/2 +psx.integerscale=0 +psx.ratio=4/3 +root.password=archr +samba.enabled=0 +saturn.integerscale=0 +saturn.ratio=4/3 +scv.integerscale=0 +scv.ratio=4/3 +sega32x.integerscale=0 +sega32x.ratio=4/3 +segacd.integerscale=0 +segacd.ratio=4/3 +sfc.integerscale=0 +sfc.ratio=4/3 +sg-1000.integerscale=0 +simplehttp.enabled=0 +snesh.integerscale=0 +snesh.ratio=4/3 +snes.integerscale=0 +snesmsu1.integerscale=0 +snesmsu1.ratio=4/3 +snes.ratio=4/3 +splash.enabled=0 +ssh.enabled=0 +supergrafx.integerscale=0 +supergrafx.ratio=4/3 +supervision.integerscale=0 +syncthing.enabled=0 +system.autohotkeys=1 +system.automount=1 +system.battery.warning=0 +system.battery.warning_threshold=25 +system.hostname=@DEVICENAME@ +system.language=en_US +system.loglevel=none +system.merged.storage=0 +system.shutdown_delay=0 +system.shutdown_delay_running_game=900 +system.suspend.park_cores=1 +system.suspend.dpms=1 +system.timezone=America/Sao_Paulo +tg16cd.integerscale=0 +tg16cd.ratio=4/3 +tg16.integerscale=0 +tg16.ratio=4/3 +updates.branch=auto +updates.enabled=1 +updates.force=0 +uzebox.integerscale=0 +uzebox.integerscale=0 +vectrex.integerscale=0 +vectrex.ratio=3/4 +vic20.integerscale=0 +vic20.ratio=4/3 +videopac.integerscale=0 +videopac.ratio=4/3 +vircon32.integerscale=0 +virtualboy.integerscale=0 +weston.startup=/usr/bin/start_es.sh +wifi.enabled=0 +wonderswancolor.integerscale=0 +wonderswan.integerscale=0 +wts.enabled=1 +x68000.integerscale=0 +x68000.ratio=4/3 +zx81.integerscale=0 +zx81.ratio=4/3 +zxspectrum.integerscale=0 +zxspectrum.ratio=4/3 diff --git a/projects/ArchR/packages/archr/config/system/configs/tz b/projects/ArchR/packages/archr/config/system/configs/tz new file mode 100644 index 0000000000..fe39d982cc --- /dev/null +++ b/projects/ArchR/packages/archr/config/system/configs/tz @@ -0,0 +1,593 @@ +Africa/Abidjan +Africa/Accra +Africa/Addis_Ababa +Africa/Algiers +Africa/Asmara +Africa/Asmera +Africa/Bamako +Africa/Bangui +Africa/Banjul +Africa/Bissau +Africa/Blantyre +Africa/Brazzaville +Africa/Bujumbura +Africa/Cairo +Africa/Casablanca +Africa/Ceuta +Africa/Conakry +Africa/Dakar +Africa/Dar_es_Salaam +Africa/Djibouti +Africa/Douala +Africa/El_Aaiun +Africa/Freetown +Africa/Gaborone +Africa/Harare +Africa/Johannesburg +Africa/Juba +Africa/Kampala +Africa/Khartoum +Africa/Kigali +Africa/Kinshasa +Africa/Lagos +Africa/Libreville +Africa/Lome +Africa/Luanda +Africa/Lubumbashi +Africa/Lusaka +Africa/Malabo +Africa/Maputo +Africa/Maseru +Africa/Mbabane +Africa/Mogadishu +Africa/Monrovia +Africa/Nairobi +Africa/Ndjamena +Africa/Niamey +Africa/Nouakchott +Africa/Ouagadougou +Africa/Porto-Novo +Africa/Sao_Tome +Africa/Timbuktu +Africa/Tripoli +Africa/Tunis +Africa/Windhoek +America/Adak +America/Anchorage +America/Anguilla +America/Antigua +America/Araguaina +America/Argentina/Buenos_Aires +America/Argentina/Catamarca +America/Argentina/ComodRivadavia +America/Argentina/Cordoba +America/Argentina/Jujuy +America/Argentina/La_Rioja +America/Argentina/Mendoza +America/Argentina/Rio_Gallegos +America/Argentina/Salta +America/Argentina/San_Juan +America/Argentina/San_Luis +America/Argentina/Tucuman +America/Argentina/Ushuaia +America/Aruba +America/Asuncion +America/Atikokan +America/Atka +America/Bahia +America/Bahia_Banderas +America/Barbados +America/Belem +America/Belize +America/Blanc-Sablon +America/Boa_Vista +America/Bogota +America/Boise +America/Buenos_Aires +America/Cambridge_Bay +America/Campo_Grande +America/Cancun +America/Caracas +America/Catamarca +America/Cayenne +America/Cayman +America/Chicago +America/Chihuahua +America/Coral_Harbour +America/Cordoba +America/Costa_Rica +America/Creston +America/Cuiaba +America/Curacao +America/Danmarkshavn +America/Dawson +America/Dawson_Creek +America/Denver +America/Detroit +America/Dominica +America/Edmonton +America/Eirunepe +America/El_Salvador +America/Ensenada +America/Fort_Nelson +America/Fort_Wayne +America/Fortaleza +America/Glace_Bay +America/Godthab +America/Goose_Bay +America/Grand_Turk +America/Grenada +America/Guadeloupe +America/Guatemala +America/Guayaquil +America/Guyana +America/Halifax +America/Havana +America/Hermosillo +America/Indiana/Indianapolis +America/Indiana/Knox +America/Indiana/Marengo +America/Indiana/Petersburg +America/Indiana/Tell_City +America/Indiana/Vevay +America/Indiana/Vincennes +America/Indiana/Winamac +America/Indianapolis +America/Inuvik +America/Iqaluit +America/Jamaica +America/Jujuy +America/Juneau +America/Kentucky/Louisville +America/Kentucky/Monticello +America/Knox_IN +America/Kralendijk +America/La_Paz +America/Lima +America/Los_Angeles +America/Louisville +America/Lower_Princes +America/Maceio +America/Managua +America/Manaus +America/Marigot +America/Martinique +America/Matamoros +America/Mazatlan +America/Mendoza +America/Menominee +America/Merida +America/Metlakatla +America/Mexico_City +America/Miquelon +America/Moncton +America/Monterrey +America/Montevideo +America/Montreal +America/Montserrat +America/Nassau +America/New_York +America/Nipigon +America/Nome +America/Noronha +America/North_Dakota/Beulah +America/North_Dakota/Center +America/North_Dakota/New_Salem +America/Ojinaga +America/Panama +America/Pangnirtung +America/Paramaribo +America/Phoenix +America/Port-au-Prince +America/Port_of_Spain +America/Porto_Acre +America/Porto_Velho +America/Puerto_Rico +America/Punta_Arenas +America/Rainy_River +America/Rankin_Inlet +America/Recife +America/Regina +America/Resolute +America/Rio_Branco +America/Rosario +America/Santa_Isabel +America/Santarem +America/Santiago +America/Santo_Domingo +America/Sao_Paulo +America/Scoresbysund +America/Shiprock +America/Sitka +America/St_Barthelemy +America/St_Johns +America/St_Kitts +America/St_Lucia +America/St_Thomas +America/St_Vincent +America/Swift_Current +America/Tegucigalpa +America/Thule +America/Thunder_Bay +America/Tijuana +America/Toronto +America/Tortola +America/Vancouver +America/Virgin +America/Whitehorse +America/Winnipeg +America/Yakutat +America/Yellowknife +Antarctica/Casey +Antarctica/Davis +Antarctica/DumontDUrville +Antarctica/Macquarie +Antarctica/Mawson +Antarctica/McMurdo +Antarctica/Palmer +Antarctica/Rothera +Antarctica/South_Pole +Antarctica/Syowa +Antarctica/Troll +Antarctica/Vostok +Arctic/Longyearbyen +Asia/Aden +Asia/Almaty +Asia/Amman +Asia/Anadyr +Asia/Aqtau +Asia/Aqtobe +Asia/Ashgabat +Asia/Ashkhabad +Asia/Atyrau +Asia/Baghdad +Asia/Bahrain +Asia/Baku +Asia/Bangkok +Asia/Barnaul +Asia/Beirut +Asia/Bishkek +Asia/Brunei +Asia/Calcutta +Asia/Chita +Asia/Choibalsan +Asia/Chongqing +Asia/Chungking +Asia/Colombo +Asia/Dacca +Asia/Damascus +Asia/Dhaka +Asia/Dili +Asia/Dubai +Asia/Dushanbe +Asia/Famagusta +Asia/Gaza +Asia/Harbin +Asia/Hebron +Asia/Ho_Chi_Minh +Asia/Hong_Kong +Asia/Hovd +Asia/Irkutsk +Asia/Istanbul +Asia/Jakarta +Asia/Jayapura +Asia/Jerusalem +Asia/Kabul +Asia/Kamchatka +Asia/Karachi +Asia/Kashgar +Asia/Kathmandu +Asia/Katmandu +Asia/Khandyga +Asia/Kolkata +Asia/Krasnoyarsk +Asia/Kuala_Lumpur +Asia/Kuching +Asia/Kuwait +Asia/Macao +Asia/Macau +Asia/Magadan +Asia/Makassar +Asia/Manila +Asia/Muscat +Asia/Nicosia +Asia/Novokuznetsk +Asia/Novosibirsk +Asia/Omsk +Asia/Oral +Asia/Phnom_Penh +Asia/Pontianak +Asia/Pyongyang +Asia/Qatar +Asia/Qostanay +Asia/Qyzylorda +Asia/Rangoon +Asia/Riyadh +Asia/Saigon +Asia/Sakhalin +Asia/Samarkand +Asia/Seoul +Asia/Shanghai +Asia/Singapore +Asia/Srednekolymsk +Asia/Taipei +Asia/Tashkent +Asia/Tbilisi +Asia/Tehran +Asia/Tel_Aviv +Asia/Thimbu +Asia/Thimphu +Asia/Tokyo +Asia/Tomsk +Asia/Ujung_Pandang +Asia/Ulaanbaatar +Asia/Ulan_Bator +Asia/Urumqi +Asia/Ust-Nera +Asia/Vientiane +Asia/Vladivostok +Asia/Yakutsk +Asia/Yangon +Asia/Yekaterinburg +Asia/Yerevan +Atlantic/Azores +Atlantic/Bermuda +Atlantic/Canary +Atlantic/Cape_Verde +Atlantic/Faeroe +Atlantic/Faroe +Atlantic/Jan_Mayen +Atlantic/Madeira +Atlantic/Reykjavik +Atlantic/South_Georgia +Atlantic/St_Helena +Atlantic/Stanley +Australia/ACT +Australia/Adelaide +Australia/Brisbane +Australia/Broken_Hill +Australia/Canberra +Australia/Currie +Australia/Darwin +Australia/Eucla +Australia/Hobart +Australia/LHI +Australia/Lindeman +Australia/Lord_Howe +Australia/Melbourne +Australia/NSW +Australia/North +Australia/Perth +Australia/Queensland +Australia/South +Australia/Sydney +Australia/Tasmania +Australia/Victoria +Australia/West +Australia/Yancowinna +Brazil/Acre +Brazil/DeNoronha +Brazil/East +Brazil/West +CET +CST6CDT +Canada/Atlantic +Canada/Central +Canada/Eastern +Canada/Mountain +Canada/Newfoundland +Canada/Pacific +Canada/Saskatchewan +Canada/Yukon +Chile/Continental +Chile/EasterIsland +Cuba +EET +EST +EST5EDT +Egypt +Eire +Etc/GMT +Etc/GMT+0 +Etc/GMT+1 +Etc/GMT+10 +Etc/GMT+11 +Etc/GMT+12 +Etc/GMT+2 +Etc/GMT+3 +Etc/GMT+4 +Etc/GMT+5 +Etc/GMT+6 +Etc/GMT+7 +Etc/GMT+8 +Etc/GMT+9 +Etc/GMT-0 +Etc/GMT-1 +Etc/GMT-10 +Etc/GMT-11 +Etc/GMT-12 +Etc/GMT-13 +Etc/GMT-14 +Etc/GMT-2 +Etc/GMT-3 +Etc/GMT-4 +Etc/GMT-5 +Etc/GMT-6 +Etc/GMT-7 +Etc/GMT-8 +Etc/GMT-9 +Etc/GMT0 +Etc/Greenwich +Etc/UCT +Etc/UTC +Etc/Universal +Etc/Zulu +Europe/Amsterdam +Europe/Andorra +Europe/Astrakhan +Europe/Athens +Europe/Belfast +Europe/Belgrade +Europe/Berlin +Europe/Bratislava +Europe/Brussels +Europe/Bucharest +Europe/Budapest +Europe/Busingen +Europe/Chisinau +Europe/Copenhagen +Europe/Dublin +Europe/Gibraltar +Europe/Guernsey +Europe/Helsinki +Europe/Isle_of_Man +Europe/Istanbul +Europe/Jersey +Europe/Kaliningrad +Europe/Kiev +Europe/Kirov +Europe/Lisbon +Europe/Ljubljana +Europe/London +Europe/Luxembourg +Europe/Madrid +Europe/Malta +Europe/Mariehamn +Europe/Minsk +Europe/Monaco +Europe/Moscow +Europe/Nicosia +Europe/Oslo +Europe/Paris +Europe/Podgorica +Europe/Prague +Europe/Riga +Europe/Rome +Europe/Samara +Europe/San_Marino +Europe/Sarajevo +Europe/Saratov +Europe/Simferopol +Europe/Skopje +Europe/Sofia +Europe/Stockholm +Europe/Tallinn +Europe/Tirane +Europe/Tiraspol +Europe/Ulyanovsk +Europe/Uzhgorod +Europe/Vaduz +Europe/Vatican +Europe/Vienna +Europe/Vilnius +Europe/Volgograd +Europe/Warsaw +Europe/Zagreb +Europe/Zaporozhye +Europe/Zurich +GB +GB-Eire +GMT +GMT+0 +GMT-0 +GMT0 +Greenwich +HST +Hongkong +Iceland +Indian/Antananarivo +Indian/Chagos +Indian/Christmas +Indian/Cocos +Indian/Comoro +Indian/Kerguelen +Indian/Mahe +Indian/Maldives +Indian/Mauritius +Indian/Mayotte +Indian/Reunion +Iran +Israel +Jamaica +Japan +Kwajalein +Libya +MET +MST +MST7MDT +Mexico/BajaNorte +Mexico/BajaSur +Mexico/General +NZ +NZ-CHAT +Navajo +PRC +PST8PDT +Pacific/Apia +Pacific/Auckland +Pacific/Bougainville +Pacific/Chatham +Pacific/Chuuk +Pacific/Easter +Pacific/Efate +Pacific/Enderbury +Pacific/Fakaofo +Pacific/Fiji +Pacific/Funafuti +Pacific/Galapagos +Pacific/Gambier +Pacific/Guadalcanal +Pacific/Guam +Pacific/Honolulu +Pacific/Johnston +Pacific/Kiritimati +Pacific/Kosrae +Pacific/Kwajalein +Pacific/Majuro +Pacific/Marquesas +Pacific/Midway +Pacific/Nauru +Pacific/Niue +Pacific/Norfolk +Pacific/Noumea +Pacific/Pago_Pago +Pacific/Palau +Pacific/Pitcairn +Pacific/Pohnpei +Pacific/Ponape +Pacific/Port_Moresby +Pacific/Rarotonga +Pacific/Saipan +Pacific/Samoa +Pacific/Tahiti +Pacific/Tarawa +Pacific/Tongatapu +Pacific/Truk +Pacific/Wake +Pacific/Wallis +Pacific/Yap +Poland +Portugal +ROC +ROK +Singapore +Turkey +UCT +US/Alaska +US/Aleutian +US/Arizona +US/Central +US/East-Indiana +US/Eastern +US/Hawaii +US/Indiana-Starke +US/Michigan +US/Mountain +US/Pacific +US/Pacific-New +US/Samoa +UTC +Universal +W-SU +WET +Zulu diff --git a/projects/ArchR/packages/archr/package.mk b/projects/ArchR/packages/archr/package.mk new file mode 100644 index 0000000000..0f6c3e3de5 --- /dev/null +++ b/projects/ArchR/packages/archr/package.mk @@ -0,0 +1,95 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) +# Copyright (C) 2024-present Arch R + +PKG_NAME="archr" +PKG_VERSION="" +PKG_LICENSE="GPLv2" +PKG_SITE="" +PKG_URL="" +PKG_DEPENDS_TARGET="toolchain autostart" +PKG_LONGDESC="Arch R Meta Package" +PKG_TOOLCHAIN="make" + +make_target() { + : +} + +makeinstall_target() { + + mkdir -p ${INSTALL}/usr/config/ + rsync -av ${PKG_DIR}/config/* ${INSTALL}/usr/config/ + ln -sf /storage/.config/system ${INSTALL}/system + find ${INSTALL}/usr/config/system/ -type f -exec chmod o+x {} \; + + mkdir -p ${INSTALL}/usr/bin/ + + ### Compatibility links for ports + ln -s /storage/roms ${INSTALL}/roms + + ### Add some quality of life customizations for hardworking devs. + if [ -n "${LOCAL_SSH_KEYS_FILE}" ] + then + mkdir -p ${INSTALL}/usr/config/ssh + cp ${LOCAL_SSH_KEYS_FILE} ${INSTALL}/usr/config/ssh/authorized_keys + fi + + if [ -n "${LOCAL_WIFI_SSID}" ] + then + sed -i "s#wifi.enabled=0#wifi.enabled=1#g" ${INSTALL}/usr/config/system/configs/system.cfg + mkdir -p ${INSTALL}/usr/config/iwd + cat <> ${INSTALL}/usr/config/iwd/${LOCAL_WIFI_SSID}.psk +[Security] +Passphrase=${LOCAL_WIFI_KEY} +EOF + fi + # Always install the update script + mkdir -p $INSTALL/usr/share/bootloader + find_file_path bootloader/update.sh && cp -av ${FOUND_PATH} ${INSTALL}/usr/share/bootloader +} + +post_install() { + ln -sf archr.target ${INSTALL}/usr/lib/systemd/system/default.target + + if [ ! -d "${INSTALL}/usr/share" ] + then + mkdir "${INSTALL}/usr/share" + fi + cp ${PKG_DIR}/sources/post-update ${INSTALL}/usr/share + chmod 755 ${INSTALL}/usr/share/post-update + + # Issue banner (no ASCII art - archr-splash handles the graphical logo) + cat <> ${INSTALL}/etc/issue + +... Version: ${OS_VERSION} (${OS_BUILD}) +... Built: ${BUILD_DATE} + +EOF + cp ${PKG_DIR}/sources/motd ${INSTALL}/etc + cat ${INSTALL}/etc/issue >> ${INSTALL}/etc/motd + + cp ${PKG_DIR}/sources/scripts/* ${INSTALL}/usr/bin + chmod 0755 ${INSTALL}/usr/bin/* 2>/dev/null ||: + + ### Fix and migrate to autostart package + enable_service archr-autostart.service + + ### ZRAM/Swap and Memory Manager Service + enable_service archr-memory-manager.service + + ### Take a backup of the system configuration on shutdown + enable_service save-sysconfig.service + + sed -i "s#@DEVICENAME@#${DEVICE}#g" ${INSTALL}/usr/config/system/configs/system.cfg + + ### Defaults for non-main builds. + BUILD_BRANCH="$(git branch --show-current)" + if [ ! "${BUILD_BRANCH}" = "main" ] + then + sed -i "s#samba.enabled=0#samba.enabled=1#g" ${INSTALL}/usr/config/system/configs/system.cfg + sed -i "s#ssh.enabled=0#ssh.enabled=1#g" ${INSTALL}/usr/config/system/configs/system.cfg + sed -i "s#wifi.enabled=0#wifi.enabled=1#g" ${INSTALL}/usr/config/system/configs/system.cfg + sed -i "s#system.loglevel=none#system.loglevel=verbose#g" ${INSTALL}/usr/config/system/configs/system.cfg + fi + +} diff --git a/projects/ArchR/packages/archr/profile.d/001-functions b/projects/ArchR/packages/archr/profile.d/001-functions new file mode 100644 index 0000000000..b34003bf99 --- /dev/null +++ b/projects/ArchR/packages/archr/profile.d/001-functions @@ -0,0 +1,236 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2019-present Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/os-release + +export XDG_RUNTIME_DIR=/var/run/0-runtime-dir +export PATH="/usr/bin:/usr/local/bin:/storage/bin:${PATH}" +export SDL_GAMECONTROLLERCONFIG_FILE="/storage/.config/SDL-GameControllerDB/gamecontrollerdb.txt" + +J_DIR="/storage/.config/system" +J_CONF="${J_DIR}/configs/system.cfg" +J_CONF_LOCK="/tmp/.system.cfg.lock" +ES_CONF="/storage/.emulationstation/es_settings.cfg" + +function tocon() { + echo -ne "\033[1000H\033[2K==> ${*}" >/dev/console +} + +function log() { + SOURCE=${1//\/*\//} + MESSAGE=${*#${1}} + MESSAGE=${MESSAGE# } + logger -t ${SOURCE} "${MESSAGE}" + echo "$(date) ${SOURCE}: ${MESSAGE}" >>/var/log/messages +} + +function get_setting() { + if [ -n "${3}" ] + then + ### Test to see if we have a game setting. + VAR="$2\[\"$(echo ${3} | sed -E "s~'~\\\x27~g"';s~[()&]~\\&~g')\"\]\.$1" + OUTPUT=$(awk 'BEGIN {FS="="} /^'"${VAR}"'/ {print $NF}' ${J_CONF}) + if [ ! -z "${OUTPUT}" ] + then + echo ${OUTPUT} + return + else + ### If not, check to see if we have a system setting. + LOCAL=$(awk -F: '/^'"${2}.${1}"'=/ { st = index($0,"=");print substr($0,st+1);exit}' ${J_CONF}) + if [ ! -z "${LOCAL}" ] + then + echo ${LOCAL} + return + fi + fi + fi + + if [ -z "${3}" ] && [ -n "${2}" ] + then + ### Check to see if we have a global setting. + LOCAL=$(awk -F: '/^'"${2}.${1}"'=/ { st = index($0,"=");print substr($0,st+1);exit}' ${J_CONF}) + if [ ! -z "${LOCAL}" ] + then + echo ${LOCAL} + return + fi + fi + + ### Check to see if we have a "system." global setting. + SYSTEM=$(awk -F: '/^system.'"${1}"='/ { st = index($0,"=");print substr($0,st+1);exit}' ${J_CONF}) + if [ -n "${SYSTEM}" ] + then + echo ${SYSTEM} + return + fi + + ### Check to see if we have a "global." global setting." + LOCAL=$(awk -F: '/^'"${1}"='/ { st = index($0,"=");print substr($0,st+1);exit}' ${J_CONF}) + if [ -z "${LOCAL}" ] + then + awk -F: '/^global.'"${1}"='/ { st = index($0,"=");print substr($0,st+1);exit}' ${J_CONF} + return + else + echo ${LOCAL} + fi + return +} + +function wait_lock() { + while true + do + if (set -o noclobber; echo "$$" > "${J_CONF_LOCK}") 2>/dev/null + then + trap 'rm -f "$lockfile"; exit $?' INT TERM EXIT + break + else + sleep 1 + fi + done +} + +function del_setting() { + wait_lock + if [[ "${1}" =~ ^[[:alnum:]] ]] + then + sed -i "/^${1}=/d" "${J_CONF}" + fi + rm -f "${J_CONF_LOCK}" +} + +function sort_settings() { + wait_lock + cat "${J_CONF}" | grep ^[a-z0-9] | sort >"${J_CONF}.tmp" + mv "${J_CONF}.tmp" "${J_CONF}" + rm -f "${J_CONF_LOCK}" +} + +function set_kill() { + if [ "${1}" = "set" ] + then + cat </tmp/.process-kill-data +${2} +EOF + elif [ "${1}" = "stop" ] + then + if [ -e "/tmp/.process-kill-data" ] + then + rm -f "/tmp/.process-kill-data" + fi + fi +} + +function set_setting() { + + if [ ! -d "/storage/.config/system/configs" ] + then + mkdir -p /storage/.config/system/configs + fi + if [ ! -e "/storage/.config/system/configs/system.cfg" ] + then + cp -f /usr/config/system/configs/system.cfg /storage/.config/system/configs/system.cfg + fi + + if [[ "${1}" =~ ^[[:alnum:]] ]] + then + del_setting "${1}" + if [ ! "${2}" = "default" ] + then + wait_lock + echo "${1}=${2}" >> "${J_CONF}" + rm -f "${J_CONF_LOCK}" + fi + fi +} + +function battery_percent() { + awk 'BEGIN {FS="="} /POWER_SUPPLY_CAPACITY=/ {print $2}' /sys/class/power_supply/[Bb][Aa][Tt]*/uevent 2>/dev/null +} + +function get_es_setting() { + echo $(sed -n "s|\s*<${1} name=\"${2}\" value=\"\(.*\)\" />|\1|p" ${ES_CONF}) +} + +function fbwidth() { + local ORIENTATION=$(/dev/null 2>&1 + done + + for thread in $(seq ${THREADS} 1 ${AVAILABLE_THREADS}); do + echo ${MODE} | tee /sys/devices/system/cpu/cpu${thread}/online >/dev/null 2>&1 + done +} + +set_cpu_gov() { + for POLICY in $(ls /sys/devices/system/cpu/cpufreq 2>/dev/null | grep policy[0-9]); do + if [ -e "/sys/devices/system/cpu/cpufreq/${POLICY}/scaling_governor" ]; then + echo $1 >/sys/devices/system/cpu/cpufreq/${POLICY}/scaling_governor 2>/dev/null + fi + done +} + +set_dmc_gov() { + if [ -e "${DMC_FREQ}/governor" ]; then + for governor in $1 dmc_$1 simple_$1; do + echo ${governor} >${DMC_FREQ}/governor 2>/dev/null + if [ "$?" = 0 ]; then + return + fi + done + fi +} + +set_gpu_gov() { + if [ -e "${GPU_FREQ}/governor" ]; then + for governor in $1 dmc_$1 simple_$1; do + echo ${governor} >${GPU_FREQ}/governor 2>/dev/null + if [ "$?" = 0 ]; then + return + fi + done + fi +} + +onlinethreads() { + set_online_threads ${1} ${2} +} + +performance() { + set_cpu_gov performance + set_dmc_gov performance +} + +ondemand() { + set_cpu_gov ondemand + set_dmc_gov ondemand +} + +schedutil() { + set_cpu_gov schedutil + set_dmc_gov ondemand +} + +powersave() { + set_cpu_gov powersave + set_dmc_gov powersave +} + +get_gpu_performance_level() { + get_setting system.gpuperf +} + +gpu_performance_level() { + case ${1} in + profile_peak) + set_gpu_gov performance + ;; + auto|profile_standard) + set_gpu_gov ondemand + ;; + low) + set_gpu_gov powersave + ;; + esac +} diff --git a/projects/ArchR/packages/archr/profile.d/100-gamecontroller-functions b/projects/ArchR/packages/archr/profile.d/100-gamecontroller-functions new file mode 100644 index 0000000000..09667a2aed --- /dev/null +++ b/projects/ArchR/packages/archr/profile.d/100-gamecontroller-functions @@ -0,0 +1,157 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +# -- Helper functions -- +# Map the actual button/hat/axis - defaults to Nintendo layout mapping +function map_input_control { + local INPUT_NAME=$1 + local TYPE=$2 + local ID=$3 + local VALUE=$4 + + map_x_result="" + case "${INPUT_NAME}" in + "a") TR_NAME="${ABUT:-a}";; + "b") TR_NAME="${BBUT:-b}";; + "x") TR_NAME="${XBUT:-x}";; + "y") TR_NAME="${YBUT:-y}";; + "hotkeyenable") TR_NAME="guide";; + "up") TR_NAME="dpup";; + "down") TR_NAME="dpdown";; + "left") TR_NAME="dpleft";; + "right") TR_NAME="dpright";; + "leftshoulder") TR_NAME="${LEFTSHOULDER:-leftshoulder}";; + "leftthumb") TR_NAME="leftstick";; + "lefttrigger") TR_NAME="${LEFTTRIGGER:-lefttrigger}";; + "rightshoulder") TR_NAME="${RIGHTSHOULDER:-rightshoulder}";; + "rightthumb") TR_NAME="rightstick";; + "righttrigger") TR_NAME="${RIGHTTRIGGER:-righttrigger}";; + "select") TR_NAME="back";; + "start") TR_NAME="start";; + "leftanalogup") TR_NAME="-lefty";; + "leftanalogleft") TR_NAME="-leftx";; + "leftanalogdown") TR_NAME="+lefty";; + "leftanalogright") TR_NAME="+leftx";; + "rightanalogup") TR_NAME="-righty";; + "rightanalogleft") TR_NAME="-rightx";; + "rightanalogdown") TR_NAME="+righty";; + "rightanalogright") TR_NAME="+rightx";; + *) + return + ;; + esac + + case "${TYPE}" in + "axis") + if (( $VALUE < 0 )); then + map_x_result="${TR_NAME}:${map_x_result}-a${ID}," + else + # Most (save for a few misbehaved children...) triggers are [0, 1] instead of [-1, 1] + # Shitty workaround for an emulationstation issue + if [[ $INPUT_NAME =~ .*"trigger" ]]; then + map_x_result="${TR_NAME}:${map_x_result}a${ID}," + else + map_x_result="${TR_NAME}:${map_x_result}+a${ID}," + fi + fi + ;; + "button") + map_x_result="${TR_NAME}:${map_x_result}b${ID}," + ;; + "hat") + map_x_result="${TR_NAME}:${map_x_result}h${ID}.${VALUE}," + ;; + *) + echo "Invalid entry ${TYPE}" + ;; + esac +} + +function get_map_suffix { + map_suffix="platform:Linux," +} + +function get_map_prefix { + map_prefix="${GUID},${NAME}," +} + +function build_connected_devices_es_input { + local ES_CONFIG=${1} + # Clean up any old files + rm -rf /tmp/es_input + rm -rf "${ES_CONFIG}" + + # Dump connected device GUIDs + /usr/bin/list-guid > /tmp/list-guid + + # Loop through connected device and extract ES xml mapping + mkdir /tmp/es_input + while read DGUID; do + if [ ! -z "$(cat /storage/.config/emulationstation/es_input.cfg | grep ${DGUID})" ]; then + cp -r /storage/.config/emulationstation/es_input.cfg /tmp/es_input/${DGUID}.xml + xmlstarlet ed --inplace -d "inputList/inputConfig[@deviceGUID!='${DGUID}']" /tmp/es_input/${DGUID}.xml + fi + done ' > "${ES_CONFIG}" + grep -vh '>\|> "${ES_CONFIG}" + echo '' >> "${ES_CONFIG}" +} + +# Create a controller DB file for connected controllers witih mappings for desired layout +function create_controller_db { + local CONTROLLER_LAYOUT="${1}" + local ES_CONFIG="${2}" + local CONTROLLER_DB="${3}"; + + # Create an ES input config file containing only connected controllers + build_connected_devices_es_input ${ES_CONFIG} + + # Query controllers mapped in emulationstation, ignore devices without a GUID + local ES_QUERY="$(xmlstarlet sel -T -t -m "inputList/inputConfig[@deviceGUID!='']" -n -v "concat(@deviceName,';',@deviceGUID)" $ES_CONFIG)" + printf "# ${CONTROLLER_LAYOUT} layout\n" >> "${CONTROLLER_DB}" + + echo "## ES Dev Mapper ##" + while IFS=";" read -r NAME GUID; do + echo "$NAME :: $GUID" + # Ignore keyboards + if [[ "${GUID}" == -1 ]]; then + continue + fi + + # Query this specific GUID on the mappings + local MAPPING_CFG=$(xmlstarlet sel -T -t -m "//inputConfig[@deviceGUID = '${GUID}']/input" -n -v "concat(@name,';',@type,';',@id,';',@value)" $ES_CONFIG) + + # Grab the 'hotkeyenable' and 'select' button mappings to use later + unset HOTKEYENABLE_BUTTON + unset SELECT_BUTTON + + while IFS=";" read -r -e INPUT_NAME TYPE ID VALUE; do + [ ${INPUT_NAME} == "hotkeyenable" ] && HOTKEYENABLE_BUTTON="${ID}" + [ ${INPUT_NAME} == "select" ] && SELECT_BUTTON="${ID}" + done <<< ${MAPPING_CFG:1} + + local MAPPING="" + while IFS=";" read -r -e INPUT_NAME TYPE ID VALUE; do + # Map the controller - skip 'hotkeyenable' if it is the same as 'select' + if [ ${INPUT_NAME} == "hotkeyenable" -a ${HOTKEYENABLE_BUTTON} == ${SELECT_BUTTON} ]; then + echo "Skipping 'hotkeyenable', same mapping as 'select'" + else + map_input_control "${INPUT_NAME}" "${TYPE}" "${ID}" "${VALUE}" + + # Only concatenate valid mappings + if [[ ! -z ${map_x_result} ]]; then + MAPPING="${MAPPING}${map_x_result}" + fi + fi + done <<< ${MAPPING_CFG:1} + + get_map_prefix + get_map_suffix + if [[ ! -z "${MAPPING}" ]]; then + echo "${map_prefix}${MAPPING}${map_suffix}" >> "${CONTROLLER_DB}" + fi + done <<< ${ES_QUERY:1} +} \ No newline at end of file diff --git a/projects/ArchR/packages/archr/profile.d/101-gpu-functions b/projects/ArchR/packages/archr/profile.d/101-gpu-functions new file mode 100644 index 0000000000..1c81913f22 --- /dev/null +++ b/projects/ArchR/packages/archr/profile.d/101-gpu-functions @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2026-present ArchR (https://github.com/archr-linux/Arch-R) + +function gpu_profiling() { + local sysfs_node + local profiling_state=${1} + + case "${HW_DEVICE}" in + S922X|RK3326) + # Enable Panfrost profiling - see https://docs.kernel.org/gpu/panfrost.html + if [[ -e "/sys/bus/platform/drivers/panfrost" ]]; then + case "${profiling_state}" in + "on") + echo 1 > /sys/bus/platform/drivers/panfrost/[a-f0-9]*.gpu/profiling + ;; + "off") + echo 0 > /sys/bus/platform/drivers/panfrost/[a-f0-9]*.gpu/profiling + ;; + esac + fi + ;; + esac +} \ No newline at end of file diff --git a/projects/ArchR/packages/archr/sources/motd b/projects/ArchR/packages/archr/sources/motd new file mode 100644 index 0000000000..85461ff637 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/motd @@ -0,0 +1,9 @@ + +[1;34m _ _ [1;37m ____ +[1;34m / \ _ __ ___ | |__ [1;37m| _ \ +[1;34m/ _ \ | '__/ __|| '_ \ [1;37m| |_) | +[1;34m/ ___ \| | | (__ | | | | [1;37m| _ < +[1;34m/_/ \_\_| \___||_| |_| [1;37m|_| \_\[0;m + +[0;36mGaming OS for R36S[0;m + diff --git a/projects/ArchR/packages/archr/sources/post-update b/projects/ArchR/packages/archr/sources/post-update new file mode 100644 index 0000000000..3f841811c7 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/post-update @@ -0,0 +1,295 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +LOG="/var/log/boot.log" + +### This script contains items that we only want to execute after a ArchR upgrade, +### or after a fresh installation. + +### Items in this block should always run after updates. +################################################################################ + +echo "Rebuild library cache..." >>${LOG} +tocon "Rebuilding library cache..." +### Rebuild the library cache +rm -f /storage/.cache/ld.so.cache +ldconfig -X + +echo "Sync configuration files..." >>${LOG} +tocon "Re-sync configuration files..." +### Sync configurations +if [ -d "/storage/.config/system/configs" ] +then + EXCLUDE="--exclude=configs" +fi + +### Remove and link es configs so they are managed with OS updates. +for es_cfg in es_features.cfg es_systems.cfg +do + mv /storage/.config/emulationstation/${es_cfg} /storage/.config/emulationstation/last_${es_cfg} >/dev/null 2>&1 + ln -s /usr/config/emulationstation/${es_cfg} /storage/.config/emulationstation/${es_cfg} >/dev/null 2>&1 +done + +rsync -a --delete ${EXCLUDE} /usr/config/system/ /storage/.config/system/ +rsync -a --ignore-existing /usr/config/game /storage/.config/ +rsync -a /usr/config/modules /storage/.config/ + +if [ -f "/storage/.config/emulationstation/resources/logo.png" ] +then + rm -f /storage/.config/emulationstation/resources/logo.png +fi + +echo "Sync modules..." >>${LOG} +tocon "Update tool modules..." +rsync -a /usr/config/modules/* /storage/.config/modules/ +cp -f /usr/config/retroarch/retroarch-core-options.cfg /storage/.config/retroarch/retroarch-core-options.cfg + +### Apply developer ssh keys if they exist +echo "Apply dev keys if available..." >>${LOG} +if [ -e /usr/config/ssh/authorized_keys ] +then + tocon "Update developer keys..." + cp /usr/config/ssh/authorized_keys /storage/.ssh +fi + +### Apply developer wifi config if they exist +echo "Apply dev wifi config if available..." >>${LOG} +if [ -d /usr/config/iwd ] +then + tocon "Update developer wifi config..." + cp /usr/config/iwd/* /storage/.cache/iwd/ +fi + +### Sync rsync configs +echo "Update rsync configuration files..." >>${LOG} +rsync --ignore-existing /usr/config/rsync-rules.conf /storage/.config/ +rsync --ignore-existing /usr/config/rsync.conf /storage/.config/ + +### Add cloud sync-related files if missing +echo "Update cloud sync files..." >>${LOG} +if [ -x "/usr/bin/cloud_sync_helper" ]; then + # Use the helper script to properly merge configurations + tocon "Updating cloud sync configuration..." + /usr/bin/cloud_sync_helper ${LOG} +else + # Fall back to the simple copy if helper is not available + tocon "Updating cloud sync files..." + # Copy default cloud sync files if they don't exist + for config_file in cloud_sync-rules.txt.defaults cloud_sync.conf.defaults; do + if [ -f "/usr/config/${config_file}" ]; then + rsync --ignore-existing /usr/config/${config_file} /storage/.config/ + fi + done + # Also copy the main config file if it doesn't exist + if [ -f "/usr/config/cloud_sync.conf" ]; then + rsync --ignore-existing /usr/config/cloud_sync.conf /storage/.config/ + # Always update defaults file to ensure latest version + rsync /usr/config/cloud_sync.conf.defaults /storage/.config/ + fi +fi + +### Sync locale data +tocon "Re-sync locale data..." +rsync -a --delete /usr/config/locale/* /storage/.config/locale/ >>/var/log/configure.log 2>&1 +rm -rf /storage/.config/emulationstation/locale >>/var/log/configure.log 2>&1 ||: +ln -sf /usr/share/locale /storage/.config/emulationstation/locale >>/var/log/configure.log 2>&1 ||: + +### Handle assets folder for ppsspp v1.20+ upgrade +if [ ! -d "/storage/.config/ppsspp/assets/ui_images" ] +then + rsync -a --delete /usr/config/ppsspp/assets/* /storage/.config/ppsspp/assets/ +fi + +### Fix Japanese language bug +if [ ! -e "/storage/.config/ppsspp/assets/NotoSansJP-Regular.ttf" ] +then + cd /storage/.config/ppsspp/assets + cp /usr/config/ppsspp/assets/NotoSansJP-Regular.ttf . + ln -s NotoSansJP-Regular.ttf Roboto-Condensed.ttf + cd - +fi + +### Add items below this line that are safe to remove after a period of time. +################################################################################ + +if echo ${HW_DEVICE} | grep -E 'H700'; then + rsync -a /usr/config/ppsspp /storage/.config/ + rsync -a /usr/config/flycast /storage/.config/ +fi + +# SM8250 / SM8550 - disable RA threaded video +if echo ${HW_DEVICE} | grep -E 'SM8250|SM8550'; then + sed -i '/video_threaded =/c\video_threaded = "false"' /storage/.config/retroarch/retroarch.cfg +fi + +# run the idtech script on update if folder does not exist +if [ ! -d "/storage/.config/idtech" ]; then + /usr/bin/generate-idtech.sh +fi + +# Clean up Dolphin +rm -r /storage/.config/dolphin-emu/GC +cp -rf /usr/config/dolphin-emu /storage/.config/ + +# Remove gamepad overlays +rm -r /tmp/overlays/gamepads + +# Clean hypseus/daphne mapping so the correct gets applied +if echo ${QUIRK_DEVICE} | grep ARC; then + rm /storage/.config/game/configs/hypseus/hypinput.ini +fi + +# Clean old dtb-overlays, they have been renamed to dtbo +if [ "${HW_DEVICE}" = "RK3566" ] && \ + [ $(ls -1 /flash/overlays/rk3566-undervolt-cpu*.dtb | wc -l) != 0 ]; then + mount -o remount,rw /flash + rm /flash/overlays/rk3566-undervolt-cpu*.dtb + sed -i '/FDTOVERLAYS/s/.dtb/.dtbo/g' /flash/extlinux/extlinux.conf + sed -i '/FDTOVERLAYS/s/.dtboo/.dtbo/g' /flash/extlinux/extlinux.conf + mount -o remount,ro /flash +fi + +if [ "$(uname -m)" = "aarch64" ] && \ + [ ! -d "/storage/roms/savestates/saturn/yabasanshiro" ]; then + mkdir "/storage/roms/savestates/saturn/yabasanshiro" + cp /storage/.config/yabasanshiro/*.yss /storage/roms/savestates/saturn/yabasanshiro/ + cp /storage/.config/yabasanshiro/*.png /storage/roms/savestates/saturn/yabasanshiro/ +fi + +# Rename network.enabled to wifi.enabled +sed -i 's/network.enabled/wifi.enabled/g' /storage/.config/system/configs/system.cfg + +# Add skip IPL/bios option tol dolphin config +DINI=/storage/.config/dolphin-emu/Dolphin.ini +grep -q "SkipIPL" "$DINI" +if [ $? -ne 0 ]; then + sed -i "/\[Core\]/a SkipIPL = True" $DINI +fi + +# Fix GUID Arc +if echo ${QUIRK_DEVICE} | grep ARC; then + for file in "\ + /storage/.config/emulationstation/es_input.cfg \ + /storage/.config/SDL-GameControllerDB/gamecontrollerdb.txt \ + /storage/.config/yabasanshiro/input.cfg \ + /storage/.config/yabasanshiro/keymapv2.json \ + yabasanshiro/devices/keymapv2_rg_arc_joypad.json"; do + sed -i "s/1900d632010000000100000000010000/1900d632010000002c0a000000010000/g" $file + done +fi + +# Fix GUID R33s +if echo ${QUIRK_DEVICE} | grep R33S; then + for file in "\ + /storage/.config/emulationstation/es_input.cfg \ + /storage/.config/SDL-GameControllerDB/gamecontrollerdb.txt \ + /storage/.config/yabasanshiro/input.cfg \ + /storage/.config/yabasanshiro/keymapv2.json \ + yabasanshiro/devices/keymapv2_rg_arc_joypad.json"; do + sed -i "s/190014b3010000009178000000050000/190014b301000000a20a000000010000/g" $file + done +fi + +# set the default global.bezel if it doesn't already exist +grep -q "^global\.bezel=" /storage/.config/system/configs/system.cfg || + sed -i '$ a\global.bezel=thebezelproject' /storage/.config/system/configs/system.cfg + +# set the default suspend shutdown delays if they doesn't already exist +grep -q "^system\.shutdown_delay=" /storage/.config/system/configs/system.cfg || + sed -i '$ a\system.shutdown_delay=0' /storage/.config/system/configs/system.cfg + +grep -q "^system\.shutdown_delay_running_game=" /storage/.config/system/configs/system.cfg || + sed -i '$ a\system.shutdown_delay_running_game=900' /storage/.config/system/configs/system.cfg + +# Set the flag to park cores on fake suspend if it doesn't already exist +grep -q "^system\.suspend\.park_cores=" /storage/.config/system/configs/system.cfg || + sed -i '$ a\system.suspend.park_cores=1' /storage/.config/system/configs/system.cfg + +# Set the flag to use DPMS on fake suspend if it doesn't already exist +grep -q "^system\.suspend\.dpms=" /storage/.config/system/configs/system.cfg || + sed -i '$ a\system.suspend.dpms=1' /storage/.config/system/configs/system.cfg + +# Wipe azahar gptokeyb mappings as they have changed +rm -rf /storage/.config/azahar/*.gptk + +# Clean RGB10X mupen64plus-sa config +if echo ${QUIRK_DEVICE} | grep RGB10X; then + rm -rf /storage/.config/mupen64plus +fi + +if [ ! -d "/storage/.config/mednafen/mednafen.cfg" ]; then + # Don't load cd images to RAM, doesn't work with CHD or is at least very slow on rk3566 + sed -i "s/cd.image_memcache 1/cd.image_memcache 0/" /storage/.config/mednafen/mednafen.cfg +fi + +# Clean melonds-sa Gallium HUD config +sed -i '/nds.show_fps=/d' /storage/.config/system/configs/system.cfg + +# Clean S922X melonds-sa config +if [[ "${HW_DEVICE}" == "S922X" ]]; then + rm -f /storage/.config/melonDS/melonDS.gptk + rm -f /storage/.config/melonDS/melonDS.ini +fi + +# S922X - by default, disable MangoHud for systems with problematic emulators +# (flycast-sa, dolphin-sa and ppsspp-sa) +if [[ "${HW_DEVICE}" == "S922X" ]]; then + grep -q "^dreamcast\.archr\.mangohud\.enabled=" /storage/.config/system/configs/system.cfg || + sed -i '$ a\dreamcast.archr.mangohud.enabled=0' /storage/.config/system/configs/system.cfg + + grep -q "^gamecube\.archr\.mangohud\.enabled=" /storage/.config/system/configs/system.cfg || + sed -i '$ a\gamecube.archr.mangohud.enabled=0' /storage/.config/system/configs/system.cfg + + grep -q "^psp\.archr\.mangohud\.enabled=" /storage/.config/system/configs/system.cfg || + sed -i '$ a\psp.archr.mangohud.enabled=0' /storage/.config/system/configs/system.cfg +fi + +# S922X - disable fake suspend DPMS as it causes crash / reboot on resume +[[ "${HW_DEVICE}" == "S922X" ]] && sed -i '/system.suspend.dpms/c\system.suspend.dpms=0' /storage/.config/system/configs/system.cfg + +# Make sure we are using the latest gamecontrollerdb file +cp -r "/usr/config/SDL-GameControllerDB/gamecontrollerdb.txt" "/storage/.config/SDL-GameControllerDB/gamecontrollerdb.txt" + +# Delete existing swap file - disabled by default on all platforms in https://github.com/archr-linux/Arch-R/pull/2223 +rm -f /storage/.cache/swapfile + +# Move existing azahar save states to /roms/savestates/3ds +if [[ -d "/storage/.config/azahar/states" && ! -d "/storage/roms/savestates/3ds" ]]; then + mkdir -p /storage/roms/savestates/3ds + cp -rf /storage/.config/azahar/states/* /storage/roms/savestates/3ds/ +fi + +# Clean input config for platforms migrated to inputplumber, with migration flag check +if [[ "${HW_DEVICE}" =~ SM8550|SM8650 && ! -e "/storage/.inputplumber_migration_complete" ]]; then + # Reset ES input / RA config + cp -f /usr/config/emulationstation/es_input.cfg /storage/.config/emulationstation/ + cp -f /usr/config/retroarch/retroarch.cfg /storage/.config/retroarch/ + + # Wipe standalone emulator config - it will be recreated from /usr/config on emulator launch + rm -rf /storage/.config/aethersx2 + rm -rf /storage/.config/dolphin-emu + rm -rf /storage/.config/azahar + rm -rf /storage/.config/duckstation + rm -rf /storage/.config/flycast + rm -rf /storage/.config/ppsspp + rm -rf /storage/.config/rpcs3 + rm -rf /storage/.config/Cemu + rm -rf /storage/.config/melonDS + rm -rf /storage/.config/mupen64plus + rm -rf /storage/.config/yabasanshiro + + # Mark migration as complete + touch /storage/.inputplumber_migration_complete +fi + +# Duckstation Qt +if [ -e "/storage/.config/duckstation/settings.ini" ]; then + # don't ask to create a desktop shortcut + grep -q "^NoDesktopFile =" /storage/.config/duckstation/settings.ini || + sed -i '/\[Main\]/a\NoDesktopFile = true' /storage/.config/duckstation/settings.ini + # no confirmation popup + sed -i 's/ConfirmPowerOff = true/ConfirmPowerOff = false/' /storage/.config/duckstation/settings.ini +fi diff --git a/projects/ArchR/packages/archr/sources/scripts/amionline b/projects/ArchR/packages/archr/sources/scripts/amionline new file mode 100755 index 0000000000..3551d04787 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/amionline @@ -0,0 +1,20 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +ip route | awk '/default/ {print $3}' >/dev/null 2>&1 +if [ ! $? = 0 ] +then + echo false + exit 1 +else + ping www.google.com -c1 -w1 >/dev/null 2>&1 + if [ ! $? = 0 ] + then + echo false + exit 1 + else + echo true + exit 0 + fi +fi diff --git a/projects/ArchR/packages/archr/sources/scripts/archr-bluetooth b/projects/ArchR/packages/archr/sources/scripts/archr-bluetooth new file mode 100755 index 0000000000..e9d25a1900 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/archr-bluetooth @@ -0,0 +1,371 @@ +#!/bin/sh + +# Source system-wide profile +. /etc/profile + +# Global variables +STORAGE_PATH="/storage" +CACHE_PATH="${STORAGE_PATH}/.cache" +BACKUP_DIR="${STORAGE_PATH}/roms/backups" +BACKUP_FILE="${BACKUP_DIR}/bluetooth.tar" +BT_DEVICE_FILE="/run/bt_device" +BT_LISTING_FILE="/run/bt_listing" +BT_LISTING_PID_FILE="/run/bt_listing.pid" +BT_CONTROL_FILE="/run/bt_discovery_control" +BT_AGENT_STATUS_FILE="/run/bt_agent_status" +BT_STATUS_FILE="/run/bt_status" + +# Action from command line +ACTION=$1 + +# Logging functions +log_error() { + echo "ERROR: $1" >&2 +} + +log_info() { + echo "INFO: $1" +} + +# Helper function to check MAC address format +validate_mac_address() { + echo "$1" | grep -qE "^([0-9A-F]{2}:){5}[0-9A-F]{2}$" + return $? +} + +# Display help information +do_help() { + cat >&2 < [options] + +Commands: + list - List trusted bluetooth devices + trust - Trust a specific device + trust input - Enter trust input mode + remove - Remove a device + save - Backup bluetooth configuration + restore - Restore bluetooth configuration + start_live_devices - Start monitoring devices + stop_live_devices - Stop monitoring devices + enable - Enable bluetooth + disable - Disable bluetooth + connect - Connect to a device + disconnect - Disconnect from a device +EOF +} + +# Check if bluetooth agent is running +check_agent_status() { + if [ ! -f "${BT_AGENT_STATUS_FILE}" ]; then + return 1 + fi + + local pid + pid=$(cat "${BT_AGENT_STATUS_FILE}") + if ! kill -0 "${pid}" 2>/dev/null; then + return 1 + fi + + return 0 +} + +# Backup bluetooth configuration +do_save() { + mkdir -p "${BACKUP_DIR}" + if (cd "${CACHE_PATH}" && tar cf "${BACKUP_FILE}" bluetooth); then + log_info "Bluetooth configuration backed up to ${BACKUP_FILE}" + return 0 + else + log_error "Failed to backup bluetooth configuration" + return 1 + fi +} + +# Restore bluetooth configuration +do_restore() { + if [ ! -f "${BACKUP_FILE}" ]; then + log_error "Backup file ${BACKUP_FILE} not found" + return 1 + fi + + if (cd "${CACHE_PATH}" && tar xf "${BACKUP_FILE}"); then + log_info "Bluetooth configuration restored from ${BACKUP_FILE}" + return 0 + else + log_error "Failed to restore bluetooth configuration" + return 1 + fi +} + +# List paired devices +do_list() { + find "${CACHE_PATH}/bluetooth" -type f -name info | while read -r FILE; do + if grep -qE '^Trusted=true$' "${FILE}"; then + DEVNAME=$(grep -E '^Name=' "${FILE}" | sed -e s+"^Name="++) + DEVCLASS=$(grep -E '^Class=' "${FILE}" | sed -e s+"^Class="++) + DEVADDR=$(basename "$(dirname "${FILE}")") + + DEVTYPE="" + case "${DEVCLASS}" in + "0x002508"|"0x000508") DEVTYPE="joystick" ;; + esac + + # Check connection status + if bluetoothctl -- info "${DEVADDR}" | grep -q "Connected: yes"; then + CONNECTED="yes" + else + CONNECTED="no" + fi + + echo "" + fi + done +} + +# Clean up device listing resources +cleanup_devlist() { + local tail_pid + + # Stop the tail process if running + if [ -f "${BT_LISTING_PID_FILE}" ]; then + tail_pid=$(cat "${BT_LISTING_PID_FILE}") + if [ -n "${tail_pid}" ]; then + kill -15 "${tail_pid}" 2>/dev/null + fi + rm -f "${BT_LISTING_PID_FILE}" + fi + + # Signal stop via control file + echo "stop" > "${BT_CONTROL_FILE}" + + # Clean up files + rm -f "${BT_LISTING_FILE}" "${BT_DEVICE_FILE}" +} + +# Start device listing +do_devlist() { + # Check if agent is running + if ! check_agent_status; then + log_error "Bluetooth agent is not running" + return 1 + fi + + # Initialize files + if ! > "${BT_DEVICE_FILE}"; then + log_error "Cannot create device file" + return 1 + fi + + if ! > "${BT_LISTING_FILE}"; then + log_error "Cannot create listing file" + return 1 + fi + + # Signal start via control file + echo "start" > "${BT_CONTROL_FILE}" + + # Start monitoring in background + tail -f "${BT_LISTING_FILE}" & + echo $! > "${BT_LISTING_PID_FILE}" + + # Set up cleanup on script exit + trap cleanup_devlist EXIT INT TERM + + # Wait for the tail process + wait $(cat "${BT_LISTING_PID_FILE}") +} + +# Stop device listing +do_stopdevlist() { + cleanup_devlist +} + +# Remove a device +do_remove() { + local DEV="$1" + + if ! validate_mac_address "${DEV}"; then + log_error "Invalid device address format" + return 1 + fi + + # Remove device using bluetoothctl + (echo "untrust ${DEV}"; echo "remove ${DEV}") | bluetoothctl >/dev/null 2>&1 + + # Remove device files + find "${CACHE_PATH}/bluetooth" -name "${DEV}" -exec rm -rf {} + + + # Backup new configuration + do_save + log_info "Device ${DEV} removed successfully" +} + +# Trust a device +do_trust() { + local TRUSTDEV="$1" + + # Check if agent is running + if ! check_agent_status; then + log_error "Bluetooth agent is not running" + return 1 + fi # This was the problem - had } instead of fi + + # Validate input for device address + if [ "${TRUSTDEV}" != "input" ]; then + if ! validate_mac_address "${TRUSTDEV}"; then + log_error "Invalid device address format" + return 1 + fi + fi + + # Write device to control file + echo "${TRUSTDEV}" > "${BT_DEVICE_FILE}" || return 1 + + local LAST_MSG="" + local NEW_MSG="" + local N=60 + + while [ $N -gt 0 ]; do + if [ -f "${BT_STATUS_FILE}" ]; then + NEW_MSG=$(cat "${BT_STATUS_FILE}") + if [ "${LAST_MSG}" != "${NEW_MSG}" ]; then + LAST_MSG="${NEW_MSG}" + echo "${NEW_MSG}" + fi + fi + + if [ "${TRUSTDEV}" != "input" ]; then + if do_list | grep -q "id=\"${TRUSTDEV}\""; then + break + fi + fi + + sleep 1 + N=$((N-1)) + done + + do_save +} + +# Enable bluetooth +do_enable() { + set_setting controllers.bluetooth.enabled 1 + systemctl start bluetooth + systemctl start bluetooth-agent + + # Wait for agent to start (up to 5 seconds) + local n=0 + while [ $n -lt 10 ]; do + if check_agent_status; then + log_info "Bluetooth agent started successfully" + return 0 + fi + sleep 0.5 + n=$((n + 1)) + done + + log_error "Failed to start bluetooth agent" + return 1 +} + +# Disable bluetooth +do_disable() { + set_setting controllers.bluetooth.enabled 0 + systemctl stop bluetooth-agent + systemctl stop bluetooth + log_info "Bluetooth disabled" +} + +# Connect to a device +do_connect() { + local DEV="$1" + + if ! validate_mac_address "${DEV}"; then + log_error "Invalid device address format" + return 1 + fi + + if bluetoothctl -- info "${DEV}" | grep -q "Connected: yes"; then + log_info "Device ${DEV} is already connected" + return 0 + fi + + log_info "Attempting to connect to device ${DEV}..." + if bluetoothctl -- connect "${DEV}"; then + log_info "Successfully connected to device ${DEV}" + return 0 + else + log_error "Failed to connect to device ${DEV}" + return 1 + fi +} + +# Disconnect from a device +do_disconnect() { + local DEV="$1" + + if ! validate_mac_address "${DEV}"; then + log_error "Invalid device address format" + return 1 + fi + + if ! bluetoothctl -- info "${DEV}" | grep -q "Connected: yes"; then + log_error "Device ${DEV} is not connected" + return 1 + fi + + if bluetoothctl -- disconnect "${DEV}"; then + log_info "Successfully disconnected device ${DEV}" + return 0 + else + log_error "Failed to disconnect device ${DEV}" + return 1 + fi +} + +# Main command processing +case "${ACTION}" in + "list") + do_list + ;; + "trust") + [ -z "$2" ] && { do_help "${0}"; exit 1; } + do_trust "$2" + ;; + "remove") + [ -z "$2" ] && { do_help "${0}"; exit 1; } + do_remove "$2" + ;; + "save") + do_save + ;; + "restore") + do_restore + ;; + "start_live_devices"|"live_devices") + do_devlist + ;; + "stop_live_devices") + do_stopdevlist + ;; + "enable") + do_enable + ;; + "disable") + do_disable + ;; + "connect") + [ -z "$2" ] && { do_help "${0}"; exit 1; } + do_connect "$2" + ;; + "disconnect") + [ -z "$2" ] && { do_help "${0}"; exit 1; } + do_disconnect "$2" + ;; + *) + do_help "${0}" + exit 1 + ;; +esac + +exit 0 diff --git a/projects/ArchR/packages/archr/sources/scripts/archr-bluetooth-agent b/projects/ArchR/packages/archr/sources/scripts/archr-bluetooth-agent new file mode 100755 index 0000000000..6bbe081806 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/archr-bluetooth-agent @@ -0,0 +1,570 @@ +#!/usr/bin/python + +from __future__ import absolute_import, print_function + +from optparse import OptionParser, make_option +import asyncio +import dbussy as dbus +import ravel +import time +import os +import logging +import signal +import atexit + +# Constants and global variables +AGENT_INTERFACE = 'org.bluez.Agent1' +CONTROL_FILE = "/run/bt_discovery_control" +AGENT_STATUS_FILE = "/run/bt_agent_status" +LOG_FILE = "/var/log/bluetooth-agent.log" + +gadapter = None +gdiscovering = False +gdevices = {} +glisting_mode = False +glisting_devs = {} +gbus = None +g_shutdown_future = None + +# Configure logging +logging.basicConfig( + filename=LOG_FILE, + level=logging.DEBUG, + format='%(asctime)s [%(levelname)s] %(message)s', + datefmt='%Y-%m-%d %H:%M:%S' +) + +def bool2str(val, valiftrue, valiffalse): + return valiftrue if val else valiffalse + +def logging_status(msg): + try: + with open("/run/bt_status", "w") as file: + file.write(msg + "\n") + except Exception as e: + logging.error(f"Failed to write status: {e}") + +def prop2str(p): + val = p + if isinstance(p, (tuple, list)) and len(p) == 2 and isinstance(p[0], dbus.DBUS.Signature): + val = p[1] + + if isinstance(val, bytes): + return val.decode('UTF-8', 'replace') + + return val + +def getDevName(properties): + if "Name" in properties and "Address" in properties and "Icon" in properties: + return f"{prop2str(properties['Name'])} ({prop2str(properties['Address'])}, {prop2str(properties['Icon'])})" + if "Name" in properties and "Address" in properties: + return f"{prop2str(properties['Name'])} ({prop2str(properties['Address'])})" + if "Name" in properties: + return prop2str(properties["Name"]) + if "Address" in properties: + return prop2str(properties["Address"]) + return "unknown" + +def getShortDevName(properties): + if "Name" in properties: + return prop2str(properties["Name"]) + if "Address" in properties: + return prop2str(properties["Address"]) + return "unknown" + +def propertiesToStr(properties): + result = "" + for p in properties: + if p not in ["ServiceData", "RSSI", "UUIDs", "Adapter", "AddressType", + "Alias", "Bonded", "ServicesResolved", "ManufacturerData", + "AdvertisingFlags"]: + if result != "": + result = result + ", " + + val = prop2str(properties[p]) + + result = result + "{}={}".format(p, str(val)) + return result + +def getDevAddressNameType(properties): + if "Address" not in properties: + return None, None, None + + vaddr = prop2str(properties["Address"]) + vname = prop2str(properties["Name"]) if "Name" in properties else None + vtype = prop2str(properties["Icon"]) if "Icon" in properties else None + + return vaddr, vname, vtype + +def listing_dev_event(path, properties, adding): + global glisting_devs + + if (path in glisting_devs and adding) or (path not in glisting_devs and not adding): + return + + if adding: + glisting_devs[path] = True + else: + del glisting_devs[path] + + try: + devaddress, devname, devtype = getDevAddressNameType(properties) + + # Skip writing to file if the device address is None + if devaddress is None: + logging.debug(f"Skipping device with None address at path: {path}") + return + + with open("/run/bt_listing", "a") as file: + file.write(f'\n') + except Exception as e: + logging.error(f"Failed to write listing event: {e}") + +def icon2basicname(icon): + if icon is None: + return "unknown" + if icon == "input-gaming": + return "joystick" + if icon.startswith("audio-"): + return "audio" + return icon + +# Define the DBus signal handlers +async def interfaces_added(path, interfaces): + global gdevices + global glisting_mode + + if "org.bluez.Device1" not in interfaces: + return + if not interfaces["org.bluez.Device1"]: + return + + properties = interfaces["org.bluez.Device1"] + + if path in gdevices: + gdevices[path] = merge2dicts(gdevices[path], properties) + else: + gdevices[path] = properties + + logging.info("Interface added: {}".format(propertiesToStr(properties))) + + if glisting_mode: + listing_dev_event(path, gdevices[path], True) + + if "Address" in gdevices[path]: + await connect_device(path, prop2str(properties["Address"]), gdevices[path], False, getBluetoothWantedAddr()) + else: + logging.info("No address. skip.") + +def interfaces_removed(path, interfaces): + global gdevices + + if "org.bluez.Device1" not in interfaces: + return + + if path in gdevices: + listing_dev_event(path, gdevices[path], False) + del gdevices[path] + +async def properties_changed(interface, changed, invalidated, path): + global gdevices + global glisting_mode + + if interface != "org.bluez.Device1": + return + + if path in gdevices: + gdevices[path] = merge2dicts(gdevices[path], changed) + else: + gdevices[path] = changed + + if glisting_mode: + listing_dev_event(path, gdevices[path], True) + + propstr = propertiesToStr(changed) + if propstr != "": + logging.info("Properties changed: {}".format(propstr)) + + if "Paired" in changed and changed["Paired"] == True: + await connect_device(path, gdevices[path]["Address"], gdevices[path], True, getBluetoothWantedAddr()) + return + + if "Connected" in changed: + if changed["Connected"] == True: + return + if changed["Connected"] == False: + logging.info("Skipping (property Connected changed to False)") + return + + if "Address" in gdevices[path]: + await connect_device(path, prop2str(gdevices[path]["Address"]), gdevices[path], False, getBluetoothWantedAddr()) + +def merge2dicts(d1, d2): + res = d1.copy() + res.update(d2) + return res + +def getBluetoothWantedAddr(): + addrDevice = None + if os.path.isfile("/run/bt_device"): + with open("/run/bt_device", "r") as file: + addrDevice = file.read().strip() + if addrDevice == "": + addrDevice = None + logging.info("bt_dev: {}".format(addrDevice)) + return addrDevice + +async def connect_device(path, address, properties, forceConnect, filter): + global gdiscovering + global gadapter + + if not filter: + logging.info(f"skipping {address}. No filter.") + return + + if "Trusted" not in properties or "Connected" not in properties: + logging.info(f"skipping {address}. Missing required properties.") + return + + trusted = prop2str(properties["Trusted"]) + paired = prop2str(properties["Paired"]) + devName = getDevName(properties) + shortDevName = getShortDevName(properties) + connected = prop2str(properties["Connected"]) + + if "Icon" not in properties: + logging.info(f"Skipping device {devName} (no type)") + return + + if not (filter == prop2str(properties["Address"]) or + (filter == "input" and prop2str(properties["Icon"]).startswith("input"))): + logging.info(f"Skipping device {devName} (not {filter})") + return + + logging.info(f"Event for {devName} (paired={bool2str(paired, 'paired', 'not paired')}, " + f"trusted={bool2str(trusted, 'trusted', 'untrusted')}, " + f"connected={bool2str(connected, 'connected', 'disconnected')})") + + if paired and trusted and connected: + logging.info(f"Skipping already connected device {devName}") + return + + if not paired and not connected and gdiscovering: + await doPairing(path, devName, shortDevName) + + if not trusted and (gdiscovering or forceConnect): + await doTrusting(path, devName, shortDevName) + + if not connected or forceConnect: + await doConnect(path, devName, shortDevName) + +async def check_discovery_control(): + try: + if os.path.exists(CONTROL_FILE): + with open(CONTROL_FILE, "r") as f: + command = f.read().strip() + + try: + os.remove(CONTROL_FILE) + except Exception as e: + logging.error(f"Failed to remove control file: {e}") + + if command == "start": + await handle_start_discovery() + elif command == "stop": + await handle_stop_discovery() + except Exception as e: + logging.error(f"Error in check_discovery_control: {e}") + return True + +async def handle_start_discovery(): + global gdiscovering, gadapter, glisting_mode, glisting_devs, gdevices + + if os.path.isfile("/run/bt_listing"): + glisting_mode = True + logging.info("Listing mode enabled") + glisting_devs = {} + for path in gdevices: + listing_dev_event(path, gdevices[path], True) + + try: + if not gdiscovering: + gdiscovering = True + logging.info("Starting discovery") + await gadapter.StartDiscovery() + except Exception as e: + logging.error(f"Failed to start discovery: {e}") + +async def handle_stop_discovery(): + global gdiscovering, gadapter, glisting_mode + + if glisting_mode: + logging.info("Listing mode disabled") + glisting_mode = False + + try: + if gdiscovering: + gdiscovering = False + logging.info("Stopping discovery") + await gadapter.StopDiscovery() + except Exception as e: + logging.error(f"Failed to stop discovery: {e}") + +async def doPairing(path, devName, shortDevName): + global gbus + logging.info(f"Pairing... ({devName})") + logging_status(f"Pairing {shortDevName}...") + try: + device_obj = gbus.get_proxy_object("org.bluez", path) + device_iface = await device_obj.get_async_interface("org.bluez.Device1") + await device_iface.Pair() + except Exception as e: + logging.error(f"Pairing failed ({devName}): {e}") + logging_status(f"Pairing failed ({shortDevName})") + +async def doTrusting(path, devName, shortDevName): + global gbus + logging.info(f"Trusting ({devName})") + logging_status(f"Trusting {shortDevName}...") + try: + device_obj = gbus.get_proxy_object("org.bluez", path) + device_iface = await device_obj.get_async_interface("org.bluez.Device1") + device_iface.Trusted = True + await ravel.set_prop_flush(device_iface) + except Exception as e: + logging.error(f"Trusting failed ({devName}): {e}") + logging_status(f"Trusting failed ({shortDevName})") + +async def doConnect(path, devName, shortDevName): + global gadapter, gdiscovering, gbus + + try: + if gdiscovering: + logging.info("Stopping discovery for connection") + await gadapter.StopDiscovery() + + device_obj = gbus.get_proxy_object("org.bluez", path) + device_iface = await device_obj.get_async_interface("org.bluez.Device1") + + for attempt in range(5): + try: + logging.info(f"Connecting... ({devName}) attempt {attempt + 1}") + logging_status(f"Connecting {shortDevName}...") + await device_iface.Connect() + logging.info(f"Connected successfully ({devName})") + logging_status(f"Connected successfully ({shortDevName})") + break + except Exception as e: + logging.error(f"Connection attempt {attempt + 1} failed: {e}") + if attempt < 4: + await asyncio.sleep(1) + else: + logging_status(f"Connection failed. Giving up. ({shortDevName})") + finally: + if gdiscovering: + logging.info("Restarting discovery") + try: + await gadapter.StartDiscovery() + except Exception as e: + logging.error(f"Failed to restart discovery: {e}") + +@ravel.interface(ravel.INTERFACE.SERVER, name=AGENT_INTERFACE) +class Agent: + def __init__(self): + self.exit_on_release = True + + def set_exit_on_release(self, exit_on_release): + self.exit_on_release = exit_on_release + + @ravel.method(in_signature="", out_signature="") + def Release(self): + global g_shutdown_future + logging.info("Agent Release") + if self.exit_on_release and g_shutdown_future: + g_shutdown_future.set_result(None) + + @ravel.method(in_signature="os", out_signature="") + def AuthorizeService(self, device, uuid): + logging.info("Agent AuthorizeService") + + @ravel.method(in_signature="o", out_signature="s") + def RequestPinCode(self, device): + logging.info(f"RequestPinCode ({device})") + return "0000" + + @ravel.method(in_signature="o", out_signature="u") + def RequestPasskey(self, device): + logging.info(f"RequestPasskey ({device})") + return 0 + + @ravel.method(in_signature="ouq", out_signature="") + def DisplayPasskey(self, device, passkey, entered): + logging.info(f"DisplayPasskey ({device}, {passkey:06d} entered {entered})") + + @ravel.method(in_signature="os", out_signature="") + def DisplayPinCode(self, device, pincode): + logging.info(f"DisplayPinCode ({device}, {pincode})") + + @ravel.method(in_signature="ou", out_signature="") + def RequestConfirmation(self, device, passkey): + logging.info("Agent RequestConfirmation") + return + + @ravel.method(in_signature="o", out_signature="") + def RequestAuthorization(self, device): + logging.info("Agent RequestAuthorization") + return + + @ravel.method(in_signature="", out_signature="") + def Cancel(self): + logging.info("Agent Cancel") + +def cleanup(): + try: + if os.path.exists(AGENT_STATUS_FILE): + os.remove(AGENT_STATUS_FILE) + except Exception as e: + logging.error(f"Cleanup failed: {e}") + +def write_status(): + try: + with open(AGENT_STATUS_FILE, "w") as f: + f.write(str(os.getpid())) + except Exception as e: + logging.error(f"Failed to write status file: {e}") + return False + return True + +async def find_adapter(bus, dev_id=None): + adapter_path = None + if dev_id: + adapter_path = f"/org/bluez/{dev_id}" + else: + try: + obj_manager_proxy = bus.get_proxy_object("org.bluez", "/") + obj_manager_iface = await obj_manager_proxy.get_async_interface(dbus.DBUSX.INTERFACE_OBJECT_MANAGER) + managed_objects = await obj_manager_iface.GetManagedObjects() + + for path, interfaces in managed_objects[0].items(): + if "org.bluez.Adapter1" in interfaces: + adapter_path = path + break + except Exception as e: + logging.error(f"Failed to find adapter via ObjectManager: {e}") + return None + + if not adapter_path: + return None + + logging.info(f"Using adapter at {adapter_path}") + adapter_obj = bus.get_proxy_object("org.bluez", adapter_path) + return await adapter_obj.get_async_interface("org.bluez.Adapter1") + +async def discovery_control_loop(): + """ Replaces GLib.timeout_add(500, check_discovery_control) """ + while True: + try: + await check_discovery_control() + except Exception as e: + logging.error(f"Error in discovery_control_loop: {e}") + await asyncio.sleep(0.5) + +@ravel.signal(in_signature="oa{sa{sv}}") +async def interfaces_added_wrapper(path, interfaces_and_properties, bus=None): + """ Wrapper to call the original async handler """ + try: + await interfaces_added(path, interfaces_and_properties) + except Exception as e: + logging.error(f"Error in interfaces_added_wrapper: {e}") + +@ravel.signal(in_signature="oas") +def interfaces_removed_wrapper(path, interfaces, bus=None): + """ Wrapper to call the original handler """ + try: + interfaces_removed(path, interfaces) + except Exception as e: + logging.error(f"Error in interfaces_removed_wrapper: {e}") + +@ravel.signal(in_signature="sa{sv}as", message_keyword="message") +async def properties_changed_wrapper(interface_name, changed_properties, invalidated_properties, message=None): + """ Wrapper to filter for Device1 and call the original async handler """ + if interface_name == "org.bluez.Device1": + try: + await properties_changed(interface_name, changed_properties, invalidated_properties, message.path) + except Exception as e: + logging.error(f"Error in properties_changed_wrapper: {e}") + + +async def main(): + global gbus, gadapter, g_shutdown_future + + atexit.register(cleanup) + + option_list = [ + make_option("-i", "--device", action="store", type="string", dest="dev_id") + ] + parser = OptionParser(option_list=option_list) + options, args = parser.parse_args() + + gbus = await ravel.system_bus_async() + + gbus.listen_objects_added(interfaces_added_wrapper) + gbus.listen_objects_removed(interfaces_removed_wrapper) + + gbus.listen_propchanged( + path="/", + fallback=True, + interface="org.bluez.Device1", + func=properties_changed_wrapper + ) + + agentpath = "/archr/agent" + agent = Agent() + gbus.register(path=agentpath, interface=agent, fallback=False) + + try: + agent_manager_obj = gbus.get_proxy_object("org.bluez", "/org/bluez") + manager = await agent_manager_obj.get_async_interface("org.bluez.AgentManager1") + await manager.RegisterAgent(agentpath, "NoInputNoOutput") + await manager.RequestDefaultAgent(agentpath) + logging.info("Agent registered") + except Exception as e: + logging.error(f"Failed to register agent: {e}") + raise + + if not write_status(): + raise Exception("Failed to write status file") + + logging.info("Waiting for Bluetooth adapter...") + await asyncio.sleep(5) + gadapter = await find_adapter(gbus, options.dev_id) + + if not gadapter: + raise Exception("No bluetooth adapter found") + + logging.info("Adapter initialized") + + discovery_task = asyncio.create_task(discovery_control_loop()) + + g_shutdown_future = asyncio.Future() + await g_shutdown_future + + discovery_task.cancel() + try: + await discovery_task + except asyncio.CancelledError: + pass + + logging.info("Shutdown future triggered, main loop terminating.") + + +if __name__ == '__main__': + try: + asyncio.run(main()) + except Exception as e: + logging.error(f"Fatal error: {e}", exc_info=True) + finally: + logging.error("Agent terminated") + cleanup() diff --git a/projects/ArchR/packages/archr/sources/scripts/archr-config b/projects/ArchR/packages/archr/sources/scripts/archr-config new file mode 100755 index 0000000000..3bb1e58ea6 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/archr-config @@ -0,0 +1,296 @@ +#!/bin/bash + +. /etc/profile +. /etc/os-release + +if [ ! "$1" ];then + echo -e "usage : archr-config [command] [args]\nWith command in\n\toverscan [enable|disable]\n\tlsaudio\n\tgetaudio\n\taudio [hdmi|jack|auto|custom|x,y]\n\tcanupdate\n\tupdate\n\twifi [enable|disable] ssid key\n\tstorage [current|list|INTERNAL|ANYEXTERNAL|RAM|DEV UUID]\n\tsetRootPassword [password]\n\tgetRootPassword\n\ttz [|tz]" + exit 1 +fi +configFile="/storage/.config/system/configs/config.txt" +storageFile="/storage/.config/system/configs/archr-boot.conf" +command="$1" +mode="$2" +extra1="$3" +extra2="$4" +extra3="$5" +extra4="$6" +arch=${HW_DEVICE} + +updateurl="https://127.0.0.1" + +preBootConfig() { + mount -o remount,rw /boot +} + +postBootConfig() { + mount -o remount,ro /boot +} + +bato_config_set_value () { + key=$1 + value=$2 + [ -z "$value" ] && value=0 + cat "$configFile" | grep "$key" + valPresent=$? + if [ "$valPresent" != "0" ];then + echo "$key=$value" >> "$configFile" + else + sed -i "s/#\?$key=.*/$key=$value/g" "$configFile" + fi +} + +#log=/userdata/system/logs/archr.log +#systemsetting="python /usr/lib/python2.7/site-packages/configgen/settings/archrSettings.py" + +log=/var/log/systemsettings.log +systemsetting="/usr/bin/archr-settings" + + +echo "----config ----" >> $log + +if [ "$command" == "getRootPassword" ]; then + # security disabled, force the default one without changing boot configuration + securityenabled="`$systemsetting -command load -key system.security.enabled`" + if [ "$securityenabled" != "1" ];then + echo "linux" + exit 0 + fi + + ENCPASSWD=$(grep -E '^[ \t]*rootshadowpassword[ \t]*=' "${storageFile}" | sed -e s+'^[ \t]*rootshadowpassword[ \t]*='++) + if test -z "${ENCPASSWD}" + then + exit 1 + fi + if ! archr-encode decode "${ENCPASSWD}" + then + exit 1 + fi + exit 0 +fi + +if [ "$command" == "setRootPassword" ]; then + PASSWD=${2} + + # security disabled, don't change + securityenabled="`$systemsetting -command load -key system.security.enabled`" + if [ "$securityenabled" != "1" ];then + exit 0 + fi + + # if no password if provided, generate one + if test -z "${PASSWD}" + then + PASSWD=$(tr -cd _A-Z-a-z-0-9 < /dev/urandom | fold -w8 | head -n1) + fi + PASSWDENC=$(archr-encode encode "${PASSWD}") + + preBootConfig + if grep -qE '^[ \t]*rootshadowpassword[ \t]*=' "${storageFile}" + then + # update it + if ! sed -i -e s@'^[ \t]*rootshadowpassword[ \t]*=.*$'@"rootshadowpassword=${PASSWDENC}"@ "${storageFile}" + then + postBootConfig + exit 1 + fi + postBootConfig + exit 0 + else + # create it + if ! echo "rootshadowpassword=${PASSWDENC}" >> "${storageFile}" + then + postBootConfig + exit 1 + fi + postBootConfig + exit 0 + fi +fi + +if [ "$command" == "overscan" ]; then +if [ "$mode" == "set" ];then +# set will set overscan values abd also enable this mode + if [ -z "$extra1" ] || [ -z "$extra2" ] || [ -z "$extra3" ] || [ -z "$extra4" ]; then + echo "$0 $command $mode needs 4 arguments:" + echo "$0 $command $mode overscan_left overscan_right overscan_top overscan_bottom" + exit 2 + fi + preBootConfig + [ -f "$configFile" ] || touch "$configFile" + + echo "setting overscan values $extra1 $extra2 $extra3 $extra4 " >> $log + bato_config_set_value disable_overscan 0 + bato_config_set_value overscan_scale 1 + bato_config_set_value overscan_left "$extra1" + bato_config_set_value overscan_right "$extra2" + bato_config_set_value overscan_top "$extra3" + bato_config_set_value overscan_bottom "$extra4" + + postBootConfig + exit 0 + +fi +if [ -f "$configFile" ];then + preBootConfig + if [ "$mode" == "enable" ];then + echo "enabling overscan" >> $log + bato_config_set_value disable_overscan 0 + bato_config_set_value overscan_scale 1 + elif [ "$mode" == "disable" ];then + echo "disabling overscan" >> $log + bato_config_set_value disable_overscan 1 + bato_config_set_value overscan_scale 0 + else + postBootConfig + exit 1 + fi + postBootConfig + exit 0 +else + exit 2 +fi +fi + +if [ "$command" == "lsoutputs" ] +then + echo "auto" + archr-resolution listOutputs +fi + +if [ "$command" == "lsaudio" ];then + if [[ "${arch}" =~ "rpi" ]] + then + echo "hdmi" + echo "jack" + echo "auto" + elif [[ "${arch}" =~ "x86" ]];then + echo "auto" + echo "custom" + LANG=C aplay -l | grep -E '^card [0-9]*:' | sed -e s+'^card \([0-9]*\): \([^,]*\), device \([0-9]*\): [^\[]* \[\([^]]*\)].*$'+'\1,\3 \4 \2'+ + else + echo "auto" + fi +fi + +if [ "$command" == "getaudio" ];then + $systemsetting -command load -key audio.device + exit 0 +fi + +if [ "$command" == "audio" ];then + # this code is specific to the rpi + # don't set it on other boards + # find a more generic way would be nice + if [[ "${arch}" =~ "rpi" ]] + then + # this is specific to the rpi + cmdVal="0" + if [ "$mode" == "hdmi" ];then + cmdVal="2" + elif [ "$mode" == "jack" ];then + cmdVal="1" + fi + echo "setting audio output mode : $mode" >> $log + amixer -c 0 -M cset numid=3 $cmdVal || exit 1 + elif [[ "${arch}" =~ "x86" ]] + then + # auto: no .asoundrc file + # custom: don't touch the .asoundrc file + # any other, create the .asoundrd file + if [ "$mode" == "auto" ];then + rm -rf /userdata/system/.asoundrc || exit 1 + elif [ "$mode" != "custom" ];then + if echo "${mode}" | grep -qE '^[0-9]*,[0-9]* ' + then + cardnb=$(echo "${mode}" | sed -e s+'^\([0-9]*\),.*$'+'\1'+) + devicenb=$(echo "${mode}" | sed -e s+'^[0-9]*,\([0-9]*\) .*$'+'\1'+) + cat > /userdata/system/.asoundrc <> $log + + # on my pc, the master is turned off at boot + # i don't know what are the rules to set here. + amixer -c 0 -M set ${DEVICE_AUDIO_MIXER} unmute || exit 1 + amixer -c 0 -M set ${DEVICE_AUDIO_MIXER} -- ${mode}% || exit 1 + + # maximize the sound to be sure it's not 0, allow errors + amixer -c 0 -M set PCM -- 100% #|| exit 1 + amixer -c 0 -M set Headphone -- 100% #|| exit 1 + exit 0 + fi + exit 12 +fi + +if [ "$command" == "gpiocontrollers" ];then + command="module" + mode="load" + extra1="mk_arcade_joystick_rpi" + extra2="map=1,2" +fi + +if [ "$command" == "module" ];then + modulename="$extra1" + map="$extra2" + # remove in all cases + rmmod /lib/modules/`uname -r`/extra/${modulename}.ko >> $log + + if [ "$mode" == "load" ];then + echo "loading module $modulename args = $map" >> $log + insmod /lib/modules/`uname -r`/extra/${modulename}.ko $map >> $log + [ "$?" ] || exit 1 + fi + exit 0 +fi + +if [ "$command" == "canupdate" ];then + available=$(updatecheck canupdate) + echo "$available" + if [[ "$available" != "no" ]]; then + exit 0 + fi + exit 12 +fi + +if [ "$command" == "update" ];then + system-upgrade + exit $? +fi + +if [[ "$command" == "storage" ]]; then + exit 0; +fi + +if [[ "$command" == "forgetBT" ]]; then + systemctl stop bluetooth bluetooth-agent + rm -rf /storage/.cache/bluetooth/* /storage/roms/backups/bluetooth.tar + systemctl start bluetooth bluetooth-agent + exit 0 +fi + +if [ "$command" == "tz" ];then + if test "$mode" == "" + then + cat /storage/.config/system/configs/tz + else + if test -f "/usr/share/zoneinfo/${mode}" + then + echo "TIMEZONE=${mode}" > /storage/.cache/timezone + systemctl restart tz-data.service + fi + fi + exit $? +fi + +exit 10 diff --git a/projects/ArchR/packages/archr/sources/scripts/archr-es-thebezelproject b/projects/ArchR/packages/archr/sources/scripts/archr-es-thebezelproject new file mode 100755 index 0000000000..d4537ef83e --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/archr-es-thebezelproject @@ -0,0 +1,641 @@ +#! /bin/bash +# +# Download and install The Bezel Project for Batocera +# +# @evoflash and @lbrpdx on Batocera Forums and Discord +# +# Usage: +# batocera-es-thebezelproject 'list', 'install or remove ' +# +# 20190801 Initial release +# 20191120 Rewite all script for incremential runtime +# 20200410 Fix : Support for daphne did not work +# 20200708 Fix : Default bezel was never copied +# 20200709 Add : Progress count (started from Terminal/SSH vs ES) +# 20210130 Add : Take bezels by systems from TheBezelProjet Github (Batocera 30+) +# 20211010 Fix : Recursive search in roms directory +# 20220524 Fix : Properly URL encode bezel file names +# 20220524 Add : Support symlinks to roms directories and roms themselves +# 20220524 Add : Output unmatched ROMs when requested +# 20220606 Add : Support installing all available systems +# + +readonly VERSION="20220606" +readonly TITLE="the BezelProject for ArchR" +readonly LOGS_DIR="/var/log" +readonly DECORATION_DIR="/storage/roms/bezels" +readonly ROMS_DIR="/storage/roms" +readonly BEZELPROJECT_DIR="thebezelproject" +readonly BEZELPROJECT_GAMES_DIR="$BEZELPROJECT_DIR/games" +readonly BEZELPROJECT_SYSTEMS_DIR="$BEZELPROJECT_DIR/systems" +readonly DEFAULT_BEZEL_URL="https://updates.batocera.org/thebezelproject" +readonly SYSTEMS_LIST="https://updates.batocera.org/tbp_systems.txt" +readonly LOCAL_SYSTEMS_LIST="/storage/.config/system/tbp_systems.txt" +readonly INDEX_LIST="https://updates.batocera.org/thebezelproject/tbp_" +readonly LOCAL_INDEX_LIST="/storage/.config/system/thebezelproject/tbp_" +readonly TMP_SYSTEMS_LIST=`mktemp` +readonly TMP_INDEX_LIST=`mktemp` +readonly TMP_PROGRESS_COUNT=`mktemp` +readonly MAX_NB_WARNING=10 +readonly _BADEXT=(jpg jpeg png bmp psd tga gif hdr pic ppm pgm mkv pdf mp4 avi cbz) +readonly BADEXT="$( IFS="|" ; echo "${_BADEXT[*]}" | sed 's/|/\\|/g' )" +NB_WARNING=0 + +# tbp_systems.txt must be a plain text file with the format +# 'system github_repository bezels_path system_bezel_file' (spaces or tabs) +# Example of tbp_systems.txt file: +# fbneo https://github.com/thebezelproject/bezelproject-MAME MAME MAME-Horizontal.cfg +# snes https://github.com/thebezelproject/bezelproject-SNES SNES Super-Nintendo-Entertainment-System.png + +# tbp_.txt is a plain text file with the format +# 'md5 rom_name' for each rom_name.png (spaces or tabs) +# An external script generates this file for each Batocera system +# available in the BezelProject (with monthly update, i hope) +# Example of tbp_snes.txt file: +# 29aa1cf6a91c472fd0e2db50ebf38 2020 Super Baseball (USA).png + +############################### +# +function usage() { + record "Showing usage for '$TITLE'" + record "$(basename $0) - downloads and installs $TITLE" "2" + record " " "2" + record "It accepts three modes: 'list', 'install' and 'remove' '" "2" + record "- 'list' to list systems installed locally, which are available within TheBezelProject:" "2" + record " [A]vailable to install, [I]nstalled or [?]unknown." "2" + record "- 'install [--show-unmatched]' to install the bezels for this ." "2" + record "- 'install all [--show-unmatched]' to install the bezels for all locally installed supported systems." "2" + record "- 'remove ' to remove the bezels for this ." "2" + record "- 'remove all' to remove all the bezels from TheBezelProject." "2" + record " " "2" + record "If you have a local system list $LOCAL_SYSTEMS_LIST file" "2" + record "and the corresponding index files $LOCAL_INDEX_LIST*.txt" "2" + record "they will override those hosted on Batocera website." "2" + return 1 +} + +############################### +# Cleanup process for exiting +function do_clean() { + record "* Cleanup and exiting" + + # kill job process + if [ -n "$PID" ]; then + record "Killing process: $PID" + kill -9 "$PID" + fi + + # remove temporary files + if [ -f "$TMP_SYSTEMS_LIST" ]; then + record "Removing systems list: $TMP_SYSTEMS_LIST" + rm "$TMP_SYSTEMS_LIST" + fi + + if [ -f "$TMP_INDEX_LIST" ]; then + record "Removing index list: $TMP_INDEX_LIST" + rm "$TMP_INDEX_LIST" + fi + + if [ -f "$TMP_PROGRESS_COUNT" ]; then + record "Removing progress count: $TMP_PROGRESS_COUNT" + rm "$TMP_PROGRESS_COUNT" + fi +} + +############################### +# log messages for debugging +function get_per() { + local system_name=$1 + local roms_filescount=$2 + while true + do + curval=$(cat "$TMP_PROGRESS_COUNT") + local per=$(expr "$curval" '*' 100 / "$roms_filescount") + record "[$system_name] Installing bezels >>> $per%" "2" + sleep 1 + done +} + +############################### +# log messages for debugging +function record() { + local STAMP_TIME="$(date "+%Y-%m-%d %T")" + local backup="$LOGS_DIR"/thebezelproject.log + local message="$1" + local show_msg="$2" + # 0 disables stdout output and enables log + # 1 enables stdout output and enables log + # 2 enables stdout output only + # -1 left empty nothing happens + [[ $show_msg -lt 0 ]] && return + [[ $show_msg -lt 2 ]] && echo "$STAMP_TIME $1" >> "$backup" + [[ $show_msg -gt 0 ]] && echo "$1" +} + +############################### +# check if url format is valid +function check_url() { + [[ "$1" =~ ^(https?|ftp)://.*$ ]] && echo "[A]" || echo "[?]" +} + +############################### +# +function url_encode() { + # Properly escape all URL special characters + local url=$(printf %s "$1" | jq -s -R -r @uri) + echo "$url" +} + +############################### +# return the git name +function git_name() { + echo "$1" | sed "s,.*/\(.*\),\1," +} + +############################### +# return the number of files in a directory +function files_count() { + # we want only files and not those starting with '.' or '_' or "gamelist*" + # support for daphne : there is a sub-folder called roms we want to parse + [[ $(grep "daphne" <<< "$1") && -d "$1"/roms ]] && echo `find "$1"/roms \( -type f -or -type l \) -iname "[!._]*" | wc -l` || echo `find "$1" \( -type f -or -type l \) -iname "[!._]*" -and ! -iname "gamelist*" -and ! -regex ".*\.\($BADEXT\)" | wc -l` +} + +############################### +# +function list() { + local systems_count=0 + local systems_available=0 + local roms_filescount + local system_name + local url + local path + local file + local dir + + record "* List" + record "Path to games bezels $DECORATION_DIR/$BEZELPROJECT_GAMES_DIR" + record "Path to systems bezels $DECORATION_DIR/$BEZELPROJECT_SYSTEMS_DIR" + + # create temporary file for systems list + if [ -f $LOCAL_SYSTEMS_LIST ]; then + record "File for local systems list $LOCAL_SYSTEMS_LIST" + cp -f "$LOCAL_SYSTEMS_LIST" "$TMP_SYSTEMS_LIST" + else + record "File for systems list $SYSTEMS_LIST" + url2="$SYSTEMS_LIST" + # check header only for HTTP 200 (OK) + if [[ $(curl -sIL "$url2" | head -n 1 | grep "200") ]]; then + curl -sfL "$url2" -o "$TMP_SYSTEMS_LIST" + else + record "Error : file $(basename $url2) could not be downloaded from $(dirname $url2)" "1" + return 1 + fi + fi + + # read systems list from configuration file + while IFS=$' \t' read system_name url path file; do + [ -z "$system_name" ] && continue + # Is this line a comment ? + [ "$system_name" = "#" ] && continue + # check if roms/ directory exists + dir=$(readlink -f "$ROMS_DIR/$system_name") + if [ ! -d "$dir" ]; then continue; fi + let systems_count+=1 + record "System #$systems_count $system_name" + # there is at least one ROM in the roms/ directory + roms_filescount=$(files_count "$dir") + if [ "$roms_filescount" -eq 0 ]; then continue; fi + let systems_available+=1 + # check if url is valid and returns [A] or [?] + ia=$(check_url "$url") + # if games/ directory exists, then we assume the bezels are already installed + if [ -d "$DECORATION_DIR/$BEZELPROJECT_GAMES_DIR/$system_name" ]; then ia="[I]"; fi + record "$ia $system_name - $url" "2" + record "$ia $system_name - $url - $path - $file" + done < "$TMP_SYSTEMS_LIST" + record "There are $systems_count systems ($systems_available availables)" + rm "$TMP_SYSTEMS_LIST" +} + +############################### +# +function install() { + local roms_filescount + local roms_count=0 + local systems_count=0 + local system_found=0 + local bezels_installed=0 + local matching_rom + local system_to_install="$1" + local daphne="" + local OS + local TERMINAL + + local git_name + local file_name + local rom_name + local bezel_md5 + + local rom_no_ext + local rom_no_brkts + + local index_ext + local index_no_ext + local index_no_brkts + + local index_bezel_name + local formated_index_bezel_name + local index_bezel_md5 + + local system_name + local url + local url2 + local path + local git_path + local file + + local show_unmatched="$2" + local unmatched=() + local unmatched_count + + record "* Install" + record "Path to games bezels $DECORATION_DIR/$BEZELPROJECT_GAMES_DIR" + record "Path to systems bezels $DECORATION_DIR/$BEZELPROJECT_SYSTEMS_DIR" + + # started from Terminal/SSH or from ES ? + [ -t 1 ] && TERMINAL=1 || TERMINAL=0 + + # create temporary file for systems list + if [ -f $LOCAL_SYSTEMS_LIST ]; then + record "File for local systems list $LOCAL_SYSTEMS_LIST" + cp -f "$LOCAL_SYSTEMS_LIST" "$TMP_SYSTEMS_LIST" + else + record "File for systems list $SYSTEMS_LIST" + url2="$SYSTEMS_LIST" + # check header only for HTTP 200 (OK) + if [[ $(curl -sIL "$url2" | head -n 1 | grep "200") ]]; then + curl -sfL "$url2" -o "$TMP_SYSTEMS_LIST" + else + record "Error : file $(basename $url2) could not be downloaded from $(dirname $url2)" "1" + return 1 + fi + fi + + # read systems list from configuration file + while IFS=$' \t' read system_name url path file; do + [ -z "$system_name" ] && continue + # Is this line a comment ? + [ "$system_name" = "#" ] && continue + let systems_count+=1 + # have we found the system we want to install ? + [ "$system_name" != "$system_to_install" ] && continue + # check if url is valid and return [A] else [?] + ia=$(check_url "$url") + if [ "$ia" != "[A]" ]; then + record "Error : invalid bezels URL $url" "1" + return 1 + else + record "Found system #$systems_count $system_name" + system_found=1 + break + fi + done < "$TMP_SYSTEMS_LIST" + rm "$TMP_SYSTEMS_LIST" + + # In case TheBezelProject doesn't provide the system we want to install + if [ "$system_found" -eq 0 ]; then + record "Error : system $system_to_install could not be found" "1" + return 1 + fi + + # check if roms/ directory exists + dir=$(readlink -f "$ROMS_DIR/$system_to_install") + if [ ! -d "$dir" ]; then + record "Error : ROMs directory for system $system_to_install could not be found" "1" + return 1 + fi + + # check that there is at least one ROM in roms/ directory + roms_filescount=$(files_count "$dir") + record "Found $roms_filescount ROMs in $ROMS_DIR/$system_to_install" + if [ "$roms_filescount" -eq 0 ]; then + record "Error : ROMs directory for system $system_to_install is empty" "1" + return 1 + fi + + # if it doesn't already exist, create the games bezels directory + if [ ! -d "$DECORATION_DIR/$BEZELPROJECT_GAMES_DIR/$system_to_install" ]; then + record "Creating $DECORATION_DIR/$BEZELPROJECT_GAMES_DIR/$system_to_install" + mkdir -p "$DECORATION_DIR/$BEZELPROJECT_GAMES_DIR/$system_to_install" + else + record "Directory $DECORATION_DIR/$BEZELPROJECT_GAMES_DIR/$system_to_install already exist" + fi + + # if it doesn't already exist, create the systems bezels directory + if [ ! -d "$DECORATION_DIR/$BEZELPROJECT_SYSTEMS_DIR" ]; then + record "Creating $DECORATION_DIR/$BEZELPROJECT_SYSTEMS_DIR" + mkdir -p "$DECORATION_DIR/$BEZELPROJECT_SYSTEMS_DIR" + else + record "Directory $DECORATION_DIR/$BEZELPROJECT_SYSTEMS_DIR already exist" + fi + + # create temporary file for index list + if [ -f "$LOCAL_INDEX_LIST$system_to_install.txt" ]; then + record "File for local index list $LOCAL_INDEX_LIST$system_to_install.txt" + cp -f "$LOCAL_INDEX_LIST$system_to_install.txt" "$TMP_INDEX_LIST" + else + record "File for index list $INDEX_LIST$system_to_install.txt" + url2="$INDEX_LIST$system_to_install.txt" + # check header only for HTTP 200 (OK) + if [[ $(curl -sIL "$url2" | head -n 1 | grep "200") ]]; then + curl -sfL "$url2" -o "$TMP_INDEX_LIST" + else + record "Error : file $(basename $url2) could not be downloaded from $(dirname $url2)" "1" + return 1 + fi + fi + + # does the path contains arcade bezels ? + if [ "$path" = "ArcadeBezels" ]; then + git_path="/raw/master/retroarch/overlay/ArcadeBezels/" + else + git_path="/raw/master/retroarch/overlay/GameBezels/$path/" + fi + + # extract git_name from the url + git_name=$(git_name "$url") + record "URL : $url" + record "Git repository : $git_name" + record "Git bezels path : $git_path" + record "Git default bezel file : $file" + record "[$system_to_install] $roms_filescount ROMs found" "1" + + # support for daphne : there is a sub-folder called roms we want to parse + [[ $(grep "daphne" <<< "$system_to_install") && -d "$dir/roms" ]] && daphne="/roms" + + # debug purpose (started from Terminal/SSH vs ES) + #TERMINAL=0 + + if [ "$TERMINAL" -eq 0 ]; then + # start job process (for background refresh) + echo "0" > "$TMP_PROGRESS_COUNT" + PID= + get_per "$system_to_install" "$roms_filescount" & + PID=$! + fi + + # check if running on a Mac or on Busybox + # (Mac for debug purposes, Batocera runs on Linux) + OS=`uname` + + # ******************************************* + # parse ROMs files in system_to_install + while read file_name; do + rom_name=$(basename "$file_name") + rom_no_ext="${rom_name%.*}" + rom_no_brkts="${rom_no_ext%% [*}" + rom_no_brkts="${rom_no_brkts%% (*}" + [ -z "$rom_name" ] && continue + let roms_count+=1 + echo $roms_count > "$TMP_PROGRESS_COUNT" + record "ROM: #$roms_count $rom_name" + + # ********************************************* + # parse index file for maching rom_name + matching_rom=0 + while IFS=$' \t' read index_bezel_md5 index_bezel_name; do + [ -z "$index_bezel_name" ] && continue + index_ext="${index_bezel_name##*.}" + index_no_ext="${index_bezel_name%.*}" + index_no_brkts="${index_no_ext%% [*}" + index_no_brkts="${index_no_brkts%% (*}" + + # ********************* + # is there a match ? + if [ "$rom_no_brkts" = "$index_no_brkts" ]; then + matching_rom=1 + + # ************************************************* + # does the bezel for this game already exist ? + if [ -f "$DECORATION_DIR/$BEZELPROJECT_GAMES_DIR/$system_to_install/$rom_no_ext.$index_ext" ]; then + + # ******************************************************************** + # Check MD5, in case the bezel has been modified/updated ? + if [ $OS = "Darwin" ]; then + # MacOS X version + bezel_md5=$(md5 -q "$DECORATION_DIR/$BEZELPROJECT_GAMES_DIR/$system_to_install/$rom_no_ext.$index_ext") + else + # Busybox version + bezel_md5=$(md5sum "$DECORATION_DIR/$BEZELPROJECT_GAMES_DIR/$system_to_install/$rom_no_ext.$index_ext" | cut -d ' ' -f 1) + fi + + if [ "$bezel_md5" != "$index_bezel_md5" ]; then + # MODIFIED (updated) + record "MODIFIED : $index_bezel_name" + # Clean up the URL for the bezel name + formated_index_bezel_name=$(url_encode "$index_bezel_name") + let bezels_installed+=1 + curl -sfL "$url$git_path$formated_index_bezel_name" -o "$DECORATION_DIR/$BEZELPROJECT_GAMES_DIR/$system_to_install/$rom_no_ext.$index_ext" + if [ "$?" -ne 0 ]; then + record "Warning : file $index_bezel_name could not be downloaded from $url" + let NB_WARNING+=1 + fi + else + # SKIPPED + record "SKIPPED : $index_bezel_name" + fi + + else + # COPIED + record "COPIED : $index_bezel_name" + # Clean up the URL for the bezel name + formated_index_bezel_name=$(url_encode "$index_bezel_name") + let bezels_installed+=1 + curl -sfL "$url$git_path$formated_index_bezel_name" -o "$DECORATION_DIR/$BEZELPROJECT_GAMES_DIR/$system_to_install/$rom_no_ext.$index_ext" + if [ "$?" -ne 0 ]; then + record "Warning : file $index_bezel_name could not be downloaded from $url" + let NB_WARNING+=1 + fi + fi + + # break loop from index (we found a match, go to next ROM) + break + + fi + + done < "$TMP_INDEX_LIST" + + # NOT MATCHING + if [ "$matching_rom" -eq 0 ]; then + record "NOT MATCHING : $rom_name" + [[ -n "$show_unmatched" ]] && unmatched+=("$rom_name") + fi + + # is there too many warning ? + if [ "$NB_WARNING" -gt "$MAX_NB_WARNING" ]; then + record "Error : too many warning ("$MAX_NB_WARNING") while downloading files, exiting..." "1" + break + fi + + # show one line progress count on Terminal/SSH only + if [ "$TERMINAL" -ne 0 ]; then + echo -ne "[$system_to_install] Installing bezel $roms_count / $roms_filescount\r" + fi + + done < <(find "$dir$daphne" \( -type f -or -type l \) -iname "[!._]*" -and ! -iname "gamelist*" -and ! -regex ".*\.\($BADEXT\)") + rm "$TMP_INDEX_LIST" + + if [ "$TERMINAL" -eq 0 ]; then + # kill job process + kill -9 "$PID" + PID= + fi + + if [ "$NB_WARNING" -gt "$MAX_NB_WARNING" ]; then + # sync disk + sync + return 1 + fi + + # summary (only show on stdout if started from Terminal/SSH) + record "[$system_to_install] $bezels_installed bezels ($roms_count ROMs) were installed/modified" "$TERMINAL" + + # install system bezel (i.e. system bezel from TheBezelProject) + record "[$system_to_install] Installing system bezel" "1" + if [ -d "$DECORATION_DIR/$BEZELPROJECT_SYSTEMS_DIR" ]; then + git_path="/raw/master/retroarch/overlay/" + curl -sfL "$url$git_path$file" -o "$DECORATION_DIR/$BEZELPROJECT_SYSTEMS_DIR/$system_to_install.png" + if [ "$?" -ne 0 ]; then + record "Warning : file $file could not be downloaded from $url" + fi + fi + + # install default bezel (i.e default bezel from BATOCERA website) + record "[$system_to_install] Installing default bezel" "1" + if [ -d "$DECORATION_DIR/$BEZELPROJECT_DIR" ]; then + url2="$DEFAULT_BEZEL_URL/default.png" + # check header only for HTTP 200 (OK) + if [[ $(curl -sIL "$url2" | head -n 1 | grep "200") ]]; then + curl -sfL "$url2" -o "$DECORATION_DIR/$BEZELPROJECT_DIR/default.png" + else + record "Warning : file $(basename $url2) could not be downloaded from $(dirname $url2)" + fi + url2="$DEFAULT_BEZEL_URL/default.info" + # check header only for HTTP 200 (OK) + if [[ $(curl -sIL "$url2" | head -n 1 | grep "200") ]]; then + curl -sfL "$url2" -o "$DECORATION_DIR/$BEZELPROJECT_DIR/default.info" + else + record "Warning : file $(basename $url2) could not be downloaded from $(dirname $url2)" + fi + fi + + # If requested (and any roms couldn't be matched), the output the list for easy lookup (only show on stdout if started from Terminal/SSH) + unmatched_count=${#unmatched[@]} + if [[ $unmatched_count != 0 ]]; then + local sorted=() + record "[$system_to_install] $unmatched_count unmatched ROM(s) (check $url$git_path to see if the bezel exists)" "$TERMINAL" + readarray -t sorted < <(for a in "${unmatched[@]}"; do echo "$a"; done | sort) + for (( i=0; i< "$unmatched_count"; i++ )); do + record "$(($i + 1)). ${sorted[$i]}" "$TERMINAL" + done + fi + + # sync disk + sync + + return 0 +} + +############################### +# +function install_all() { + local show_unmatched="$1" + local system + local systems=() + + # List returns the status of each local system one per line + readarray -t systems < <(list) + + record "${#systems[@]} local system(s) found." "2" + + for system_status in "${systems[@]}"; do + system=($system_status) + # The column for the system is the second one + install "${system[1]}" "$show_unmatched" + done +} + +############################### +# +function remove() { + local system_name="$1" + + # do you want to remove all bezels from TheBezelProject ? + record "* Remove" + if [ "$system_name" = "all" ]; then + if [ -d "$DECORATION_DIR/$BEZELPROJECT_DIR" ]; then + read -p "Do you wish to remove all bezels from TheBezelProject ? " yn + if [[ "$yn" = "y" || "$yn" = "Y" ]]; then + # all TheBezelProject sub-directories + rm -rf "$DECORATION_DIR/$BEZELPROJECT_DIR" + record "Deleting directory : $DECORATION_DIR/$BEZELPROJECT_DIR" + fi + else + record "Error : bezels directory $DECORATION_DIR/$BEZELPROJECT_DIR is not valid" "1" + return 1 + fi + else + # check if games/ directory exists + if [ ! -d "$DECORATION_DIR/$BEZELPROJECT_GAMES_DIR/$system_name" ]; then + record "Error : bezels for system $system_name could not be found" "1" + return 1 + else + # games bezels + rm -rf "$DECORATION_DIR/$BEZELPROJECT_GAMES_DIR/$system_name" + record "Deleting directory : $DECORATION_DIR/$BEZELPROJECT_GAMES_DIR/$system_name" + # system bezels + rm -f "$DECORATION_DIR/$BEZELPROJECT_SYSTEMS_DIR/$system_name.png" + record "Deleting file : $DECORATION_DIR/$BEZELPROJECT_SYSTEMS_DIR/$system_name.png" + # default bezel + rm -f "$DECORATION_DIR/$BEZELPROJECT_DIR/default.*" + record "Deleting files : $DECORATION_DIR/$BEZELPROJECT_DIR/default.*" + fi + fi + + # sync disk + sync + + return 0 +} + +############################### +#### Main loop +# +command="$1" +system="$2" + +trap do_clean EXIT +record "Starting script v$VERSION" + +if [ ! -d "$DECORATION_DIR" ]; then + record "Error : decorations directory $DECORATION_DIR is not valid" "1" + exit 1 +fi + +if [[ "$command" = "list" ]]; then + list +elif [[ "$command" = "install" && -n "$system" ]]; then + if [[ -n "$3" && "$3" != "--show-unmatched" ]]; then + record "Error : unknown argument for install: $3" "1" + record "" "1" + usage + elif [[ "$system" = "all" ]]; then + install_all "$3" + else + install "$system" "$3" + fi +elif [[ "$command" = "remove" && -n "$system" ]]; then + remove "$system" +else + usage +fi diff --git a/projects/ArchR/packages/archr/sources/scripts/archr-fake-suspend b/projects/ArchR/packages/archr/sources/scripts/archr-fake-suspend new file mode 100755 index 0000000000..137499c147 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/archr-fake-suspend @@ -0,0 +1,434 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025-present ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile + +### Enable logging +case $(get_setting system.loglevel) in +verbose) + DEBUG=true + ;; +*) + DEBUG=false + ;; +esac + +check_hardware_suspend_enabled() { + local SUSPEND_MODE="$(get_setting system.suspendmode)" + + if [[ "${SUSPEND_MODE}" != "off" ]]; then + return 0 + else + return 1 + fi +} + +check_hdmi_connected() { + for status_file in /sys/class/drm/card*-HDMI-A-[0-9]/status; do + if [[ -f "$status_file" ]]; then + local HDMI_STATUS=$(cat "$status_file") + if [[ "${HDMI_STATUS}" = "connected" ]]; then + return 0 + fi + fi + done + + return 1 +} + +check_charging() { + local CHARGE_STATUS=$(cat /sys/class/power_supply/battery/status) + + if [[ "${CHARGE_STATUS}" = "Charging" ]]; then + return 0 + else + return 1 + fi +} + +check_es_running_game() { + local HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:1234/runningGame") + ${DEBUG} && log $0 "ES runningGame HTTP_STATUS - ${HTTP_STATUS}" + test $? != 0 && return 1 # call failed, assume no game running + test "${HTTP_STATUS}" = 201 && return 1 # 201 when no game running + test "${HTTP_STATUS}" = 200 && return 0 # 200 when game running +} + +display_off() { + if [[ "${ENABLE_DPMS}" == "1" ]]; then + # DPMS enabled, use it to turn off the display + ${DEBUG} && log $0 "DPMS - display off" + + if echo "${UI_SERVICE}" | grep "sway"; then + ${DEBUG} && log $0 "Display power off" + swaymsg "output * power off" + elif echo "${UI_SERVICE}" | grep "weston"; then + weston-dpms -m off + fi + else + # DPMS disabled, just turn off the backlight + ${DEBUG} && log $0 "Backlight off" + + for BL_POWER_DEVICE in "${BL_POWER_DEVICES[@]}"; do + echo 4 > "${BL_POWER_DEVICE}" + done + fi +} + +display_on() { + if [[ "${ENABLE_DPMS}" == "1" ]]; then + # DPMS enabled, use it to turn on the display + ${DEBUG} && log $0 "DPMS - display on" + + if echo "${UI_SERVICE}" | grep "sway"; then + ${DEBUG} && log $0 "Display power on" + swaymsg "output * power on" + elif echo "${UI_SERVICE}" | grep "weston"; then + weston-dpms -m on + fi + else + # DPMS disabled, just turn on the backlight + ${DEBUG} && log $0 "Backlight on" + + for BL_POWER_DEVICE in "${BL_POWER_DEVICES[@]}"; do + echo 0 > "${BL_POWER_DEVICE}" + done + fi +} + +mute_audio() { + ${DEBUG} && log $0 "Mute audio" + pactl set-sink-mute @DEFAULT_SINK@ true +} + +unmute_audio() { + ${DEBUG} && log $0 "Unmute audio" + pactl set-sink-mute @DEFAULT_SINK@ false +} + +disable_leds() { + ${DEBUG} && log $0 "disable leds" + /usr/bin/ledcontrol poweroff +} + +enable_leds() { + ${DEBUG} && log $0 "restore leds" + LED_STATE=$(get_setting "led.color") + /usr/bin/ledcontrol ${LED_STATE} +} + +powersave_governors() { + ${DEBUG} && log $0 "Set CPU/GPU governors to powersave" + + # Get the current cpu and gpu governor, save for restoration on resume + local CURR_CPU_GOVERNOR="$(cat ${CPU_FREQ}/scaling_governor)" + local CURR_GPU_GOVERNOR="$(cat ${GPU_FREQ}/governor)" + + set_setting sleep.cpugovernor "${CURR_CPU_GOVERNOR}" + set_setting sleep.gpugovernor "${CURR_GPU_GOVERNOR}" + + # Set all governors to powersave + set_cpu_gov powersave + set_gpu_gov powersave +} + +restore_governors() { + ${DEBUG} && log $0 "Restore CPU/GPU governors" + + # Grab the old governors + local PRE_SUSPEND_CPU_GOVERNOR=$(get_setting "sleep.cpugovernor") + [[ -z "${PRE_SUSPEND_CPU_GOVERNOR}" ]] && PRE_SUSPEND_CPU_GOVERNOR="ondemand" + + local PRE_SUSPEND_GPU_GOVERNOR=$(get_setting "sleep.gpugovernor") + [[ -z "${PRE_SUSPEND_GPU_GOVERNOR}" ]] && PRE_SUSPEND_GPU_GOVERNOR="simple_ondemand" + + # Restore old governors + set_cpu_gov "${PRE_SUSPEND_CPU_GOVERNOR}" + set_gpu_gov "${PRE_SUSPEND_GPU_GOVERNOR}" + + # Clean up + del_setting "sleep.cpugovernor" + del_setting "sleep.gpugovernor" +} + +park_cores() { + ${DEBUG} && log $0 "CPU core parking" + for x in /sys/devices/system/cpu/cpu*/online; do + if [[ ! $(echo "${x}" | grep "cpu0") ]]; then + echo 0 > "${x}" + fi + done +} + +unpark_cores() { + ${DEBUG} && log $0 "Undo CPU core parking" + for x in /sys/devices/system/cpu/cpu*/online; do + echo 1 > "${x}" + done +} + +block_input() { + for x in /dev/input/event*; do + local EVENT_INPUT=$(echo ${x} | awk 'BEGIN{FS="/"} {print $NF}') + local DEVICE_NAME=$(cat /sys/class/input/$EVENT_INPUT/device/name) + + # If device is not in whitelist, block input + local FOUND=0 + for WHITELIST_DEVICE in "${INPUT_WHITELIST[@]}"; do + if [[ "${WHITELIST_DEVICE}" = "${DEVICE_NAME}" ]]; then + FOUND=1 + break + fi + done + + if (( ! ${FOUND})); then + ${DEBUG} && log $0 "Blocking input for ${x} - ${DEVICE_NAME}" + /usr/bin/evtest --grab ${x} > /dev/null & + fi + done +} + +unblock_input() { + ${DEBUG} && log $0 "Unblocking input" + for x in $(pgrep -f "evtest --grab"); do + kill -9 ${x} + done +} + +do_suspend_actions() { + # Turn off display + display_off + + # Mute audio + mute_audio + + # Set CPU / GPU governors + powersave_governors + + # CPU core parking (if enabled) + [[ "${ENABLE_CORE_PARKING}" == "1" ]] && park_cores + + # Block input + block_input + + # Disable LEDs + disable_leds +} + +do_resume_actions() { + # Turn on display + display_on + + # Unmute audio + unmute_audio + + # Restore CPU / GPU governors + restore_governors + + # Undo CPU core parking (if enabled) + [[ "${ENABLE_CORE_PARKING}" == "1" ]] && unpark_cores + + # Unblock input + unblock_input + + # Restore LEDs + enable_leds +} + +do_shutdown() { + # Check if HDMI has been connected while suspended + check_hdmi_connected + local HDMI_CONNECTED=$? + + if [[ $HDMI_CONNECTED -eq 0 ]]; then + ${DEBUG} && log $0 "HDMI connected, not shutting down" + return 0 + fi + + # Check if charger has been connected while suspended + check_charging + local CHARGING=$? + + if [[ $CHARGING -eq 0 ]]; then + ${DEBUG} && log $0 "Charging, not shutting down" + return 0 + fi + + # Unmute audio - otherwise wireplumber will keep it muted on next boot + unmute_audio + + # Check whether a game is running + check_es_running_game + local RUNNING_GAME=$? + + if [[ $RUNNING_GAME -eq 0 ]]; then + # ES shutdown API won't work if a game is running + ${DEBUG} && log $0 "Shutting down now" + shutdown now + else + # Use ES shutdown API so metadata is saved + ${DEBUG} && log $0 "Shutting down via ES API" + curl "http://localhost:1234/shutdown" + fi +} + +suspend() { + # Create delay flag file + ${DEBUG} && log $0 "Creating ${DELAY_FLAG_FILE}" + touch "${DELAY_FLAG_FILE}" + + check_es_running_game + local RUNNING_GAME=$? + + check_charging + local CHARGING=$? + + # Determine shutdown delay + local DELAY=${SHUTDOWN_DELAY} + [[ $RUNNING_GAME -eq 0 ]] && DELAY=${SHUTDOWN_DELAY_RUNNING_GAME} + ${DEBUG} && log $0 "Shutdown delay - ${DELAY} seconds" + [[ ${CHARGING} -eq 0 ]] && ${DEBUG} && log $0 "Charging ..." + + if [[ "${DELAY}" -gt 0 || ${CHARGING} -eq 0 ]]; then + do_suspend_actions + fi + + # Delay shutdown + sleep ${DELAY} + + # Delay has completed - check whether the flag file is still present + if [[ -f "${DELAY_FLAG_FILE}" ]]; then + ${DEBUG} && log $0 "Delay expired, flag file found" + # Flag present - shutdown + do_shutdown + else + ${DEBUG} && log $0 "Delay expired, flag file not found" + fi +} + +resume() { + # Resume event - remove all flag files and kill processes + ${DEBUG} && log $0 "Removing flags" + rm -f "${DELAY_FLAG_FILE_PATTERN}".* + rm -f "${POWER_SUSPEND_ACTIVE_FLAG_FILE}" + rm -f "${LID_CLOSED_FLAG_FILE}" + + # Do resume actions + do_resume_actions + + ${DEBUG} && log $0 "Resume - killing ${TO_KILL} processes" + killall ${TO_KILL} +} + +# Main logic +# Only do something when hardware suspend is disabled +check_hardware_suspend_enabled +HW_SUSPEND_ENABLED=$? + +if [[ $HW_SUSPEND_ENABLED -eq 0 ]]; then + ${DEBUG} && log $0 "Hardware suspend enabled, exiting" + exit 0 +fi + +# If a game is not running, by default shutdown immediately +SHUTDOWN_DELAY="$(get_setting system.shutdown_delay)" +[[ "${SHUTDOWN_DELAY}" = "" ]] && SHUTDOWN_DELAY=0 + +# If a game is running, by default delay the shutdown for 15 minutes +SHUTDOWN_DELAY_RUNNING_GAME="$(get_setting system.shutdown_delay_running_game)" +[[ "${SHUTDOWN_DELAY_RUNNING_GAME}" = "" ]] && SHUTDOWN_DELAY_RUNNING_GAME=900 + +# On suspend, should CPU cores be parked +ENABLE_CORE_PARKING="$(get_setting system.suspend.park_cores)" +[[ "${ENABLE_CORE_PARKING}" = "" ]] && ENABLE_CORE_PARKING="1" + +# On suspend, should DPMS be used +ENABLE_DPMS="$(get_setting system.suspend.dpms)" +[[ "${ENABLE_DPMS}" = "" ]] && ENABLE_DPMS="1" + +# flag files +PID=$$ +DELAY_FLAG_FILE_PATTERN="/var/run/shutdown-delay.flag" +DELAY_FLAG_FILE="${DELAY_FLAG_FILE_PATTERN}.${PID}" +POWER_SUSPEND_ACTIVE_FLAG_FILE="/var/run/power-fake-suspend-active.flag" +LID_CLOSED_FLAG_FILE="/var/run/lid-closed.flag" + +# Process to kill +TO_KILL="archr-fake-suspend" + +# Lid / power button - event input device whitelist +INPUT_WHITELIST=( + # H700 + "axp20x-pek" \ + "gpio-keys-lid" \ + # S922X + "rk805 pwrkey" \ + # SM8550 + "pmic_pwrkey" +) + +# Ayn Thor gpio-keys contains lid events +[[ "${QUIRK_DEVICE}" == "AYN Thor" ]] && INPUT_WHITELIST+=("gpio-keys") + +# Backlight power devices +declare -a BL_POWER_DEVICES=() +while IFS= read -r line; do + BL_POWER_DEVICES+=("$line") +done < <(find /sys/class/backlight/*/ -name bl_power 2>/dev/null) + +# Source = power / lid +SOURCE=$1 + +# Action = open / close +ACTION=$2 + +# Check if HDMI is connected +check_hdmi_connected +HDMI_CONNECTED=$? + +# Handle event +if [[ "${SOURCE}" = "power" ]]; then + ${DEBUG} && log $0 "Power button pressed ..." + + if [[ -f "${LID_CLOSED_FLAG_FILE}" ]]; then + ${DEBUG} && log $0 "Lid closed - no action" + elif [[ -f "${POWER_SUSPEND_ACTIVE_FLAG_FILE}" ]]; then + # In a 'suspend' state from power button, 'resume' + ${DEBUG} && log $0 "Power suspend active - resuming" + resume + else + if [[ $HDMI_CONNECTED -eq 0 ]]; then + ${DEBUG} && log $0 "HDMI connected, not suspending" + else + # Create flag file and suspend + ${DEBUG} && log $0 "Suspending" + touch ${POWER_SUSPEND_ACTIVE_FLAG_FILE} + suspend + fi + fi +elif [[ "${SOURCE}" = "lid" && "${ACTION}" = "close" ]]; then + ${DEBUG} && log $0 "Lid closed ..." + touch ${LID_CLOSED_FLAG_FILE} + + if [[ -f "${POWER_SUSPEND_ACTIVE_FLAG_FILE}" ]]; then + # In a 'suspend' state from power button, do nothing + ${DEBUG} && log $0 "Power suspend active - no action" + else + if [[ $HDMI_CONNECTED -eq 0 ]]; then + ${DEBUG} && log $0 "HDMI connected, not suspending" + else + # Suspend + ${DEBUG} && log $0 "Suspending" + suspend + fi + fi +elif [[ "${SOURCE}" = "lid" && "${ACTION}" = "open" ]]; then + rm -f "${LID_CLOSED_FLAG_FILE}" + + # Always resume on lid open - regardless of suspend source + ${DEBUG} && log $0 "Lid opened - resuming" + resume +fi + +exit 0 \ No newline at end of file diff --git a/projects/ArchR/packages/archr/sources/scripts/archr-info b/projects/ArchR/packages/archr/sources/scripts/archr-info new file mode 100755 index 0000000000..53fe4eae64 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/archr-info @@ -0,0 +1,187 @@ +#!/bin/bash + +source /etc/profile + +### Apply device quirks +if [ -e "/sys/firmware/devicetree/base/model" ] +then + export QUIRK_DEVICE="$(tr -d '\0' /dev/null)" +else + export QUIRK_DEVICE="$(tr -d '\0' /dev/null) $(tr -d '\0' /dev/null)" +fi +export QUIRK_DEVICE="$(echo ${QUIRK_DEVICE} | sed -e "s#[/]#-#g")" + +info_quirks() { + for QUIRK in /usr/lib/autostart/quirks/platforms/"${HW_DEVICE}"/info.d/${1}/* \ + /usr/lib/autostart/quirks/devices/"${QUIRK_DEVICE}"/info.d/${1}/* + do + "${QUIRK}" 2>/dev/null + done +} + +### short version (for osd) +if test "$1" = "--short" +then + BATT=$(awk 'BEGIN {FS="="} /POWER_SUPPLY_CAPACITY=/ {print $2; exit}' /sys/class/power_supply/[Bb][Aa][Tt]*/uevent 2>/dev/null) + DT=$(date +%H:%M) + if test -n "${BATT}" + then + echo "Battery: ${BATT}% - ${DT}" + else + echo "${DT}" + fi + exit 0 +fi +### + +V_CPUNB=$(grep -E $'^processor\t:' /proc/cpuinfo | wc -l) +V_CPUMODEL1=$(grep -E $'^model name\t:' /proc/cpuinfo | head -1 | sed -e s+'^model name\t: '++) +V_SYSTEM=$(uname -rs) +V_ARCH=$(uname -m) + +[[ "$V_CPUMODEL1" ]] || V_CPUMODEL1="${HW_CPU}" + +# network +ip=$(ip -4 addr show dev eth0 2>/dev/null | grep inet | awk '{print $2}' | cut -d/ -f1) +if [ -z "$ip" ]; then + WIFI_DEV="$({ ls /sys/class/net; echo wlan0; } | grep -m1 ^wlan)" + ip=$(ip -4 addr show dev ${WIFI_DEV} 2>/dev/null | grep inet | awk '{print $2}' | cut -d/ -f1) +fi +if [ -z "$ip" ]; then + ip="Offline" +fi + +host=$(hostname) + +# gpu +CUR_FREQ=$(cat "$GPU_FREQ/cur_freq") +MAX_FREQ=$(cat "$GPU_FREQ/max_freq") +GPUCUR=$((CUR_FREQ / 1000000)) +GPUMAX=$((MAX_FREQ / 1000000)) + +# ram +MEMT=$(grep MemTotal /proc/meminfo | sed 's/[^0-9]*//g') +MEMT=$((${MEMT} / 1000)) +MEMAV=$(grep MemAvailable /proc/meminfo | sed 's/[^0-9]*//g') +MEMAV=$((${MEMAV} / 1000)) + +# battery +BATT=$(awk 'BEGIN {FS="="} /POWER_SUPPLY_CAPACITY=/ {print $2; exit}' /sys/class/power_supply/[Bb][Aa][Tt]*/uevent 2>/dev/null) + +case ${HW_ARCH} in + aarch64) + declare -a CF MF + + CNTR=0 + for CPUFREQ in /sys/devices/system/cpu/cpufreq/* + do + if [[ "${CPUFREQ}" =~ boost ]] + then + continue + fi + if [ "${CNTR}" -eq 0 ] + then + CF+=("CURRENT FREQUENCY:") + MF+=("MAXIMUM FREQUENCY:") + fi + RELCPUS=$(cat ${CPUFREQ}/related_cpus 2>/dev/null) + if [ "${#RELCPUS}" -gt 1 ] + then + FIELD="$(cat ${CPUFREQ}/related_cpus 2>/dev/null | awk '{print $1"-"$NF}')" + else + FIELD="$(cat ${CPUFREQ}/related_cpus 2>/dev/null)" + fi + if [ -e "${CPUFREQ}/scaling_cur_freq" ]; then + CF+=("THREADS ${FIELD}: $(( $(cat ${CPUFREQ}/scaling_cur_freq 2>/dev/null | sort | tail -n 1) / 1000))MHz") + fi + if [ -e "${CPUFREQ}/scaling_max_freq" ]; then + MF+=("THREADS ${FIELD}: $(( $(cat ${CPUFREQ}/scaling_max_freq 2>/dev/null | sort | tail -n 1) / 1000))MHz") + fi + CNTR=$(( CNTR + 1 )) + done + ;; +esac + +echo "SYSTEM INFORMATION:" +echo "DEVICE: ${QUIRK_DEVICE}" +echo "OPERATING SYSTEM: ${OS_NAME}" +echo "VERSION: ${OS_VERSION} (${OS_BUILD})" +echo "BUILD ID: ${BUILD_ID:0:7} (${BUILD_BRANCH})" +echo "KERNEL: ${V_SYSTEM} ($(uname -m))" +echo "NETWORK INFORMATION:" +echo "HOST NAME: ${host}" +echo "IP ADDRESS: ${ip}" +echo "DISK SPACE:" +echo "/storage/games-internal: $(df -h /storage/games-internal | awk '/dev/ {print $3"/"$2" ("$5")"}')" +echo "/storage/games-external: $(df -h /storage/games-external | awk '/dev/ {print $3"/"$2" ("$5")"}')" + +if test -n "${BATT}" +then + echo "BATTERY INFORMATION:" + echo "BATTERY REMAINING: ${BATT}%" + BAT_HEALTH=$(cat /sys/class/power_supply/[Bb][Aa][Tt]*/health 2>/dev/null) + if [ -n "${BAT_HEALTH}" ] + then + echo "BATTERY HEALTH: ${BAT_HEALTH}" + fi + BAT_STATUS=$(cat /sys/class/power_supply/[Bb][Aa][Tt]*/status 2>/dev/null) + if [ -n "${BAT_STATUS}" ] + then + echo "BATTERY STATE: ${BAT_STATUS}" + fi +fi +echo "CPU INFORMATION:" +echo "CPU: ${V_CPUMODEL1} (${V_CPUNB} Cores)" + +# temperature +# Unit: millidegree Celsius +if [ -n "${DEVICE_TEMP_SENSOR}" ] +then + TEMPE=$(awk '{total += $1; count++} END {printf "%d", total/count/1000}' ${DEVICE_TEMP_SENSOR}) + if [ -n "${TEMPE}" ] + then + echo "CPU TEMPERATURE: ${TEMPE}°" + fi +fi + +if [ "${DEVICE_HAS_FAN}" = "true" ] +then + FANSPEED=$(cat ${DEVICE_FAN_INPUT} 2>/dev/null) + if [ "${FANSPEED}" = "0" ] + then + FANSPEED="OFF" + else + FANSPEED="${FANSPEED} RPM" + fi + echo "CPU FAN: ${FANSPEED}" +fi +case ${HW_ARCH} in + aarch64) + for C in "${CF[@]}" + do + echo ${C} + done + for M in "${MF[@]}" + do + echo ${M} + done + ;; +esac +if [ -n "$GPUCUR" ]; then + echo "GPU INFORMATION:" +# GPU temperature +# Unit: millidegree Celsius + if [ -n "${DEVICE_GPU_TEMP_SENSOR}" ]; then + GTEMPE=$(awk '{total += $1; count++} END {printf "%d", total/count/1000}' ${DEVICE_GPU_TEMP_SENSOR}) + if [ -n "${GTEMPE}" ]; then + echo "GPU TEMPERATURE: ${GTEMPE}°" + fi +fi + echo "GPU CURRENT FREQUENCY: ${GPUCUR} MHz" + echo "GPU MAXIMUM FREQUENCY: ${GPUMAX} MHz" +fi +echo "RAM INFORMATION:" +echo "RAM AVAILABLE: ${MEMAV} MB" +echo "RAM CAPACITY: ${MEMT} MB" + +info_quirks diff --git a/projects/ArchR/packages/archr/sources/scripts/archr-keyboard b/projects/ArchR/packages/archr/sources/scripts/archr-keyboard new file mode 100755 index 0000000000..fef3f314cd --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/archr-keyboard @@ -0,0 +1,97 @@ +#!/bin/bash + +. /etc/profile.d/001-functions + +RULES_FILE="/usr/share/X11/xkb/rules/base.lst" +CONF_KEY_LAYOUT="system.kblayout" +CONF_KEY_VARIANT="system.kbvariant" + +# Check to make sure the rules file exists +if [ ! -f "$RULES_FILE" ]; then + echo "Error: $RULES_FILE not found" >&2 + exit 1 +fi + +function get_current_layout() { + local val=$(get_setting "$CONF_KEY_LAYOUT") + if [ -z "$val" ]; then echo "us"; else echo "$val"; fi +} + +function get_current_variant() { + local val=$(get_setting "$CONF_KEY_VARIANT") + if [ -z "$val" ] || [ "$val" == "none" ]; then echo ""; else echo "$val"; fi +} + +function list_layouts() { + awk ' + BEGIN { in_section=0 } + /^! layout/ { in_section=1; next } + /^!/ { in_section=0 } + in_section && NF > 0 { + code=$1; + $1=""; + sub(/^ */, "", $0); + print code " " $0 + } + ' "$RULES_FILE" | sort -k2 +} + +function list_variants() { + local layout="$1" + + # If no argument, get from config + if [ -z "$layout" ]; then + layout=$(get_current_layout) + fi + + if [ -z "$layout" ]; then return; fi + + awk -v layout="$layout" ' + BEGIN { in_section=0 } + /^! variant/ { in_section=1; next } + /^!/ { in_section=0 } + in_section && NF > 0 { + if ($2 == layout":") { + code=$1; + $1=""; $2=""; + sub(/^ */, "", $0); + print code " " $0 + } + } + ' "$RULES_FILE" | sort -k2 +} + +case "$1" in + list-layouts) + list_layouts + ;; + list-variants) + list_variants "$2" + ;; + get) + L=$(get_current_layout) + V=$(get_current_variant) + echo "$L $V" + ;; + set) + LAYOUT="$2" + VARIANT="$3" + + if [ -z "$LAYOUT" ]; then LAYOUT="us"; fi + if [ "$VARIANT" == "none" ] || [ -z "$VARIANT" ]; then VARIANT=""; fi + + set_setting "$CONF_KEY_LAYOUT" "$LAYOUT" + set_setting "$CONF_KEY_VARIANT" "$VARIANT" + + # Try to apply immediately (Runtime) + # We check if setxkbmap exists. This works for X11. + if command -v setxkbmap > /dev/null; then + setxkbmap -layout "$LAYOUT" -variant "$VARIANT" 2>/dev/null || true + fi + + ;; + *) + echo "Usage: $0 {list-layouts|list-variants [layout]|get|set }" + exit 1 + ;; +esac diff --git a/projects/ArchR/packages/archr/sources/scripts/archr-memory-manager b/projects/ArchR/packages/archr/sources/scripts/archr-memory-manager new file mode 100755 index 0000000000..a569ed5734 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/archr-memory-manager @@ -0,0 +1,598 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2026-present Joel Wirāmu Pauling +# Copyright (C) 2026-present ArchR (https://arch-r.io) + +# ArchR Memory Manager +# Logic: 0/Empty = Off, "Auto" = Smart Calculation, "Resume" = Hibernation Sizing. + +# --- 1. CONFIGURATION CASCADE --- + +# A. Internal Safe Defaults (Hardcoded Fallback) +DEFAULT_ZRAM_SIZE="0" +DEFAULT_ZRAM_ALGO="zstd" +DEFAULT_SWAP_FILE_SIZE="0" +DEFAULT_SWAP_PRIORITY="auto" +DEFAULT_VM_WATERMARK_FACTOR="auto" +DEFAULT_VM_COMPACTION="auto" +DEFAULT_KSM_ENABLE="auto" + +# B. Load System Defaults (Distro Config) +if [ -f /etc/swap.conf ]; then + . /etc/swap.conf +fi + +# C. Load User Overrides (Partial Config Support) +if [ -f /storage/.config/swap.conf ]; then + . /storage/.config/swap.conf +fi + +# D. Variable Finalization +ZRAM_SIZE="${ZRAM_SIZE:-$DEFAULT_ZRAM_SIZE}" +ZRAM_ALGO="${ZRAM_ALGO:-$DEFAULT_ZRAM_ALGO}" +SWAP_FILE_SIZE="${SWAP_FILE_SIZE:-$DEFAULT_SWAP_FILE_SIZE}" +SWAP_PRIORITY="${SWAP_PRIORITY:-$DEFAULT_SWAP_PRIORITY}" +VM_WATERMARK_FACTOR="${VM_WATERMARK_FACTOR:-$DEFAULT_VM_WATERMARK_FACTOR}" +VM_COMPACTION="${VM_COMPACTION:-$DEFAULT_VM_COMPACTION}" +KSM_ENABLE="${KSM_ENABLE:-$DEFAULT_KSM_ENABLE}" + +# --- 2. ENVIRONMENT & TIER DETECTION --- + +# Source environment to ensure HW_DEVICE is available +if [ -f /etc/profile ]; then + . /etc/profile +fi + +# Global RAM calc (MB) +TOTAL_MEM_KB=$(awk '/MemTotal/ {print $2}' /proc/meminfo) +TOTAL_MEM_MB=$((TOTAL_MEM_KB / 1024)) + +# RAM Tiers +IS_LOW_RAM=false +IS_MID_RAM=false +IS_HIGH_RAM=false + +if [ "$TOTAL_MEM_MB" -lt 2048 ]; then + IS_LOW_RAM=true +elif [ "$TOTAL_MEM_MB" -le 8192 ]; then + IS_MID_RAM=true +else + IS_HIGH_RAM=true +fi + +# SoC Capability Tiers +# Detect High Performance SoCs that can handle aggressive background ops (KSM/Compaction) +# even with lower RAM. +IS_HIGH_PERF_SOC=false + +if [[ "${HW_DEVICE,,}" =~ rk3588|sm8|s922x|g12b|rk3399 ]]; then + IS_HIGH_PERF_SOC=true +fi + +# Basic mount check +if ! mountpoint -q /storage; then + if [[ "$*" != *"--help"* ]]; then + logger -t memory-manager "Error: /storage is not mounted." + exit 1 + fi +fi + +# --- 3. HELPER FUNCTIONS --- + +update_config() { + local key="$1" + local val="$2" + local file="/storage/.config/swap.conf" + + if [ ! -d "$(dirname "$file")" ]; then mkdir -p "$(dirname "$file")"; fi + if [ ! -f "$file" ]; then touch "$file"; fi + + if grep -q "^${key}=" "$file"; then + sed -i "s|^${key}=.*|${key}=\"${val}\"|" "$file" + else + echo "${key}=\"${val}\"" >> "$file" + fi + eval "${key}=\"${val}\"" +} + +show_status_json() { + # Generate machine-readable status + local ksm_status="false" + local ksm_saved=0 + if [ -f /sys/kernel/mm/ksm/run ] && [ "$(cat /sys/kernel/mm/ksm/run)" -eq 1 ]; then + ksm_status="true" + local sharing=$(cat /sys/kernel/mm/ksm/pages_sharing 2>/dev/null || echo 0) + ksm_saved=$(( (sharing * 4096) / 1024 / 1024 )) + fi + + local zram_enabled="false" + local zram_compr=0 + if [ -d /sys/block/zram0 ]; then + zram_enabled="true" + local stat=($(cat /sys/block/zram0/mm_stat 2>/dev/null)) + if [ ${#stat[@]} -ge 3 ]; then + zram_compr=$((stat[1] / 1024 / 1024)) + fi + fi + + local ram_tier="high" + [ "$IS_LOW_RAM" = true ] && ram_tier="low" + [ "$IS_MID_RAM" = true ] && ram_tier="mid" + + echo "{" + echo " \"ram_total_mb\": $TOTAL_MEM_MB," + echo " \"tier_ram\": \"$ram_tier\"," + echo " \"tier_soc\": \"$([ "$IS_HIGH_PERF_SOC" = true ] && echo "high" || echo "standard")\"," + echo " \"zram\": {" + echo " \"enabled\": $zram_enabled," + echo " \"size_mb\": $ZRAM_SIZE_VAL," + echo " \"algo\": \"$ZRAM_ALGO\"," + echo " \"compressed_size_mb\": $zram_compr" + echo " }," + echo " \"swap\": {" + echo " \"size_mb\": $SWAP_SIZE_VAL," + echo " \"priority\": \"$SWAP_PRIORITY\"" + echo " }," + echo " \"ksm\": {" + echo " \"enabled\": $ksm_status," + echo " \"saved_mb\": $ksm_saved" + echo " }" + echo "}" +} + +show_status() { + echo "--- ArchR Memory Manager Status ---" + printf "System RAM: %s MB\n" "$TOTAL_MEM_MB" + printf "RAM Tier: %s\n" "$([ "$IS_LOW_RAM" = true ] && echo "Low" || ([ "$IS_MID_RAM" = true ] && echo "Mid" || echo "High"))" + printf "SoC Tier: %s\n" "$([ "$IS_HIGH_PERF_SOC" = true ] && echo "High Performance" || echo "Standard")" + printf "ZRAM Config: %s [%s]\n" "$ZRAM_STATUS" "$ZRAM_ALGO" + printf "Swap Config: %s [Mode: %s]\n" "$SWAP_STATUS" "$SWAP_PRIORITY" + echo "" + echo "[ Tier 1: ZRAM Statistics ]" + if [ -d /sys/block/zram0 ]; then + local stat=($(cat /sys/block/zram0/mm_stat 2>/dev/null)) + if [ ${#stat[@]} -ge 3 ]; then + local orig=$((stat[0] / 1024 / 1024)) + local compr=$((stat[1] / 1024 / 1024)) + local total=$((stat[2] / 1024 / 1024)) + printf " Original Data: %s MB\n" "$orig" + printf " Compressed: %s MB\n" "$compr" + printf " Memory Used: %s MB\n" "$total" + [ "$compr" -gt 0 ] && printf " Ratio: %.2f:1\n" "$(echo "scale=2; $orig / $compr" | bc)" + fi + [ -f /sys/block/zram0/comp_algorithm ] && printf " Algorithms: %s\n" "$(cat /sys/block/zram0/comp_algorithm)" + else + echo " ZRAM device not initialized." + fi + echo "" + echo "[ Tier 2: Physical Swap ]" + swapon --show | grep -v "NAME" || echo " No physical swap active." + echo "" + echo "[ Memory Subsystem ]" + # KSM + if [ -f /sys/kernel/mm/ksm/run ]; then + local ksm_run=$(cat /sys/kernel/mm/ksm/run) + local ksm_status="Stopped" + [ "$ksm_run" -eq 1 ] && ksm_status="Running" + if [ "$ksm_run" -eq 1 ]; then + local sharing=$(cat /sys/kernel/mm/ksm/pages_sharing 2>/dev/null || echo 0) + local saved=$(( (sharing * 4096) / 1024 / 1024 )) + printf " KSM Status: %s (Saved: %s MB)\n" "$ksm_status" "$saved" + printf " KSM Setting: %s\n" "$KSM_ENABLE" + else + printf " KSM Status: %s\n" "$ksm_status" + fi + else + echo " KSM Status: Absent" + fi + + # MGLRU + if [ -f /sys/kernel/mm/lru_gen/enabled ]; then + printf " MGLRU: Enabled [0x%s]\n" "$(cat /sys/kernel/mm/lru_gen/enabled)" + else + printf " MGLRU: Absent\n" + fi + + # THP + if [ -f /sys/kernel/mm/transparent_hugepage/enabled ]; then + local thp=$(grep -o '\[.*\]' /sys/kernel/mm/transparent_hugepage/enabled | tr -d '[]') + local defrag=$(grep -o '\[.*\]' /sys/kernel/mm/transparent_hugepage/defrag | tr -d '[]') + printf " Huge Pages: %s (Defrag: %s)\n" "$thp" "$defrag" + else + printf " Huge Pages: Absent\n" + fi + + echo "" + echo "[ Advanced Tuning ]" + sysctl vm.swappiness \ + vm.page-cluster \ + vm.vfs_cache_pressure \ + vm.dirty_ratio \ + vm.dirty_background_ratio \ + vm.watermark_scale_factor \ + vm.compaction_proactiveness \ + 2>/dev/null | sed 's/^/ /' +} + +check_safety() { + local mem_avail_kb=$(awk '/MemAvailable/ {print $2}' /proc/meminfo) + local swap_total_kb=$(awk '/SwapTotal/ {print $2}' /proc/meminfo) + local swap_free_kb=$(awk '/SwapFree/ {print $2}' /proc/meminfo) + local swap_used_kb=$((swap_total_kb - swap_free_kb)) + + if [ "$swap_used_kb" -gt "$((mem_avail_kb - 51200))" ]; then + logger -t memory-manager "CRITICAL: Reload aborted. Active swap usage ($swap_used_kb kB) exceeds available RAM ($mem_avail_kb kB)." + return 1 + fi + return 0 +} + +stop_zram() { + if grep -q "/dev/zram0" /proc/swaps; then + swapoff /dev/zram0 || return 1 + fi + if [ -b /dev/zram0 ]; then + echo 1 > /sys/block/zram0/reset 2>/dev/null + fi +} + +stop_swapfile() { + TARGET_SWAP="${SWAPFILE:-/storage/.cache/swapfile}" + if grep -q "$TARGET_SWAP" /proc/swaps; then + swapoff "$TARGET_SWAP" || return 1 + fi +} + +setup_ksm() { + if [ -f /sys/kernel/mm/ksm/run ]; then + local should_run=0 + + if [[ "${KSM_ENABLE,,}" == "auto" ]]; then + should_run=1 + elif [[ "${KSM_ENABLE,,}" == "enable" || "$KSM_ENABLE" == "1" ]]; then + should_run=1 + fi + + if [ "$should_run" -eq 1 ]; then + echo 1 > /sys/kernel/mm/ksm/run + + # Smart Tuning: RAM Tier + SoC Capabilities + if [ "$IS_LOW_RAM" = true ]; then + if [ "$IS_HIGH_PERF_SOC" = true ]; then + # Low RAM but Strong CPU (e.g. S922X 2GB). + # Run KSM aggressively to maximize RAM availability. + echo 200 > /sys/kernel/mm/ksm/sleep_millisecs + echo 200 > /sys/kernel/mm/ksm/pages_to_scan + else + # Low RAM and Weak CPU (e.g. RK3326). + # Conservative to avoid CPU stutter. + echo 500 > /sys/kernel/mm/ksm/sleep_millisecs + echo 100 > /sys/kernel/mm/ksm/pages_to_scan + fi + elif [ "$IS_MID_RAM" = true ]; then + # Mid Range: Slower scan rate + echo 1000 > /sys/kernel/mm/ksm/sleep_millisecs + echo 100 > /sys/kernel/mm/ksm/pages_to_scan + else + # High End: Very lazy scan + echo 3000 > /sys/kernel/mm/ksm/sleep_millisecs + echo 100 > /sys/kernel/mm/ksm/pages_to_scan + fi + else + echo 0 > /sys/kernel/mm/ksm/run + fi + fi +} + +apply_vm_tuning() { + # 1. Watermark Scale Factor + local watermark_factor=10 + if [[ "${VM_WATERMARK_FACTOR,,}" == "auto" ]]; then + if [ "$IS_LOW_RAM" = true ]; then + watermark_factor=10 + else + watermark_factor=100 + fi + elif [[ "$VM_WATERMARK_FACTOR" =~ ^[0-9]+$ ]]; then + watermark_factor=$VM_WATERMARK_FACTOR + fi + if [ -f /proc/sys/vm/watermark_scale_factor ]; then + sysctl -w vm.watermark_scale_factor=$watermark_factor >/dev/null + fi + + # 2. Compaction Proactiveness + local compaction_val=20 + if [[ "${VM_COMPACTION,,}" == "auto" ]]; then + if [ "$IS_HIGH_PERF_SOC" = true ]; then + # High-end chips can afford background cleanup to keep THP ready. + compaction_val=40 + elif [ "$IS_LOW_RAM" = true ]; then + # Save CPU cycles on budget targets. + compaction_val=10 + else + compaction_val=20 + fi + elif [[ "$VM_COMPACTION" =~ ^[0-9]+$ ]]; then + compaction_val=$VM_COMPACTION + fi + if [ -f /proc/sys/vm/compaction_proactiveness ]; then + sysctl -w vm.compaction_proactiveness=$compaction_val >/dev/null + fi + + # 3. Transparent Huge Pages + # Tiered THP Logic (FS MADVISE Synergy) + if [ -f /sys/kernel/mm/transparent_hugepage/enabled ]; then + # Default to madvise for all to prevent bloat + echo madvise > /sys/kernel/mm/transparent_hugepage/enabled + + # Enable for Shared Memory (Crucial for Vulkan/Wayland textures) + if [ -f /sys/kernel/mm/transparent_hugepage/shmem_enabled ]; then + echo advise > /sys/kernel/mm/transparent_hugepage/shmem_enabled + fi + + # Budget vs Flagship Defrag Logic + # On Budget devices (e.g. H700, RK3326), we use 'defer' so the system + # never stalls while trying to find a contiguous 2MB block. + if [ "$IS_LOW_RAM" = true ] && [ "$IS_HIGH_PERF_SOC" = false ]; then + echo defer > /sys/kernel/mm/transparent_hugepage/defrag + logger -t memory-manager "THP: Budget mode enabled (defrag=defer)" + else + # Flagship (RK3588, SM8x) or powerful Mid-range (RK3399) + # Use defer+madvise to allow some synchronous compaction for + # applications that explicitly think it is worth the performance. + echo "defer+madvise" > /sys/kernel/mm/transparent_hugepage/defrag + logger -t memory-manager "THP: Flagship mode enabled (defrag=defer+madvise)" + fi + fi +} + +apply_tuning() { + sysctl -w vm.vfs_cache_pressure=100 >/dev/null + sysctl -w vm.dirty_ratio=10 >/dev/null + sysctl -w vm.dirty_background_ratio=5 >/dev/null + + apply_vm_tuning + setup_ksm + + if [ "$ZRAM_SIZE_VAL" -gt 0 ]; then + # With ZRAM + MGLRU + THP, high swappiness ensures the system swaps + # anonymous memory into compressed RAM, keeping physical RAM "unfragmented" + # for Huge Page allocations. + sysctl -w vm.swappiness=100 >/dev/null + sysctl -w vm.page-cluster=0 >/dev/null + + if [ -n "$SECONDARY_ALGO" ] && [ -f /sys/block/zram0/recompress ]; then + if grep -q "$SECONDARY_ALGO" /sys/block/zram0/comp_algorithm; then + echo "algo=$SECONDARY_ALGO priority=1" > /sys/block/zram0/recompress 2>/dev/null + fi + fi + elif [ "$SWAP_SIZE_VAL" -gt 0 ]; then + sysctl -w vm.swappiness=60 >/dev/null + sysctl -w vm.page-cluster=3 >/dev/null + fi +} + +perform_optimization() { + # Proactive Maintenance Logic + # 1. ZRAM Recompression (if Hybrid Tiering is active) + if [ "$ZRAM_SIZE_VAL" -gt 0 ] && [ -n "$SECONDARY_ALGO" ] && [ -f /sys/block/zram0/recompress ]; then + logger -t memory-manager "Optimizing: Triggering ZRAM recompression ($SECONDARY_ALGO)..." + if grep -q "$SECONDARY_ALGO" /sys/block/zram0/comp_algorithm; then + # Recompress huge/idle pages to secondary algo + echo "algo=$SECONDARY_ALGO type=huge_idle" > /sys/block/zram0/recompress 2>/dev/null + fi + fi + + # 2. Memory Compaction (if Fragmentation is high) + if [ -f /proc/sys/vm/compact_memory ]; then + logger -t memory-manager "Optimizing: Triggering Memory Compaction..." + echo 1 > /proc/sys/vm/compact_memory + fi +} + +setup_zram() { + [ "$ZRAM_SIZE_VAL" -le 0 ] && return + + modprobe zsmalloc 2>/dev/null + modprobe zram num_devices=1 2>/dev/null + + local timeout=0 + while [ ! -b /dev/zram0 ] && [ $timeout -lt 5 ]; do + sleep 0.1 + ((timeout++)) + done + + if [ ! -b /dev/zram0 ]; then + logger -t memory-manager "Error: ZRAM device node /dev/zram0 did not appear." + return + fi + + grep -q "zram0" /proc/swaps && return + + local algo_path="/sys/block/zram0/comp_algorithm" + [ -f "$algo_path" ] && echo "$PRIMARY_ALGO" > "$algo_path" 2>/dev/null + + echo $((ZRAM_SIZE_VAL * 1024 * 1024)) > /sys/block/zram0/disksize + mkswap /dev/zram0 >/dev/null + swapon -p 100 /dev/zram0 +} + +setup_swapfile() { + [ "$SWAP_SIZE_VAL" -le 0 ] && return + TARGET_SWAP="${SWAPFILE:-/storage/.cache/swapfile}" + mkdir -p "$(dirname "$TARGET_SWAP")" 2>/dev/null + local cur=0 + [ -f "$TARGET_SWAP" ] && cur=$(du -m "$TARGET_SWAP" | cut -f1) + + if [ "$cur" -ne "$SWAP_SIZE_VAL" ]; then + [ -f "$TARGET_SWAP" ] && swapoff "$TARGET_SWAP" 2>/dev/null && rm "$TARGET_SWAP" + fallocate -l ${SWAP_SIZE_VAL}M "$TARGET_SWAP" 2>/dev/null || \ + dd if=/dev/zero of="$TARGET_SWAP" bs=1M count=$SWAP_SIZE_VAL status=none + chmod 0600 "$TARGET_SWAP" + mkswap "$TARGET_SWAP" >/dev/null + fi + + local prio=-2 + if [[ "${SWAP_PRIORITY,,}" == "stripe" ]]; then + prio=100 + elif [[ "${SWAP_PRIORITY,,}" == "auto" ]]; then + if [ "$ZRAM_SIZE_VAL" -gt 0 ]; then + prio=-10 + else + prio=-2 + fi + elif [[ "$SWAP_PRIORITY" =~ ^-?[0-9]+$ ]]; then + prio=$SWAP_PRIORITY + fi + + swapon -p $prio "$TARGET_SWAP" 2>/dev/null +} + +drop_caches() { + sync + echo 3 > /proc/sys/vm/drop_caches + logger -t memory-manager "Caches dropped." + echo "Caches dropped." +} + +# --- 4. LOGIC RESOLUTION & ARG PARSING --- + +ACTION="" + +while [[ $# -gt 0 ]]; do + case "$1" in + --zram-size) update_config "ZRAM_SIZE" "$2"; shift 2 ;; + --zram-algo) update_config "ZRAM_ALGO" "$2"; shift 2 ;; + --swap-size) update_config "SWAP_FILE_SIZE" "$2"; shift 2 ;; + --swap-priority) update_config "SWAP_PRIORITY" "$2"; shift 2 ;; + --vm-watermark) update_config "VM_WATERMARK_FACTOR" "$2"; shift 2 ;; + --vm-compaction) update_config "VM_COMPACTION" "$2"; shift 2 ;; + --ksm) update_config "KSM_ENABLE" "$2"; shift 2 ;; + --setup) ACTION="setup"; shift ;; + --stop) ACTION="stop"; shift ;; + --reload) ACTION="reload"; shift ;; + --drop-caches) ACTION="drop-caches"; shift ;; + --optimize) ACTION="optimize"; shift ;; + --status) ACTION="status"; shift ;; + --json) ACTION="json"; shift ;; + --help|-h) + echo "Usage: archr-memory-manager [OPTIONS] [ACTION]" + echo "Config Options (Writes to .config/swap.conf):" + echo " --zram-size [0|Auto|MB] Set ZRAM size" + echo " --zram-algo [zstd|lzo|lz4] Set ZRAM compression" + echo " --swap-size [0|Auto|Resume] Set Disk Swap size" + echo " --swap-priority [Auto|Stripe] Set Swap priority" + echo " --vm-watermark [Auto|Val] Set VM watermark scale factor" + echo " --vm-compaction [Auto|Val] Set VM compaction proactiveness" + echo " --ksm [Auto|Enable|Disable] Set Kernel Samepage Merging" + echo "Actions:" + echo " --setup Initial setup" + echo " --reload Safe reload (teardown -> setup)" + echo " --optimize Run runtime optimizations (Recompress/Compact)" + echo " --status Show status (default interactive)" + echo " --json Show status in JSON" + exit 0 + ;; + *) if [ -z "$ACTION" ]; then ACTION="setup"; fi; shift ;; + esac +done + +if [ -z "$ACTION" ]; then + if [ -t 0 ]; then ACTION="status"; else ACTION="setup"; fi +fi + +# --- 5. RE-EVALUATE LOGIC WITH NEW CONFIGS --- + +# Calculate ZRAM Size +ZRAM_SIZE_VAL=0 +ZRAM_STATUS="Off" +if [[ "${ZRAM_SIZE,,}" == "auto" ]]; then + if [ "$IS_LOW_RAM" = true ]; then + ZRAM_SIZE_VAL=$((TOTAL_MEM_MB * 3 / 4)) + elif [ "$IS_MID_RAM" = true ]; then + ZRAM_SIZE_VAL=$((TOTAL_MEM_MB / 2)) + else + ZRAM_SIZE_VAL=6144 + fi + ZRAM_STATUS="Auto (${ZRAM_SIZE_VAL}MB)" +elif [[ "$ZRAM_SIZE" =~ ^[0-9]+$ ]] && [ "$ZRAM_SIZE" -gt 0 ]; then + ZRAM_SIZE_VAL=$ZRAM_SIZE + ZRAM_STATUS="${ZRAM_SIZE_VAL}MB" +fi + +# Calculate Swap File Size +SWAP_SIZE_VAL=0 +SWAP_STATUS="Off" +if [[ "${SWAP_FILE_SIZE,,}" == "auto" ]]; then + SWAP_SIZE_VAL=$TOTAL_MEM_MB + [ "$SWAP_SIZE_VAL" -gt 2048 ] && SWAP_SIZE_VAL=2048 + SWAP_STATUS="Auto (${SWAP_SIZE_VAL}MB)" +elif [[ "${SWAP_FILE_SIZE,,}" == "resume" ]]; then + SWAP_SIZE_VAL=$((TOTAL_MEM_MB + 512)) + SWAP_STATUS="Resume Target (${SWAP_SIZE_VAL}MB)" +elif [[ "$SWAP_FILE_SIZE" =~ ^[0-9]+$ ]] && [ "$SWAP_FILE_SIZE" -gt 0 ]; then + SWAP_SIZE_VAL=$SWAP_FILE_SIZE + SWAP_STATUS="${SWAP_SIZE_VAL}MB" +fi + +# Determine Algorithms +if [[ "$ZRAM_ALGO" == "@ZRAM_COMPRESSION_ALGO@" ]]; then + ZRAM_ALGO="zstd" +fi + +PRIMARY_ALGO="$ZRAM_ALGO" +SECONDARY_ALGO="" + +if [[ "$ZRAM_ALGO" == "zstd" ]]; then + PRIMARY_ALGO="lzo-rle" + SECONDARY_ALGO="zstd" +fi + +# Safety check for algorithm +if [ -e /sys/block/zram0/comp_algorithm ] && ! grep -q "$PRIMARY_ALGO" /sys/block/zram0/comp_algorithm 2>/dev/null; then + if grep -q "lzo-rle" /sys/block/zram0/comp_algorithm 2>/dev/null; then + PRIMARY_ALGO="lzo-rle" + else + PRIMARY_ALGO=$(awk '{print $1}' /sys/block/zram0/comp_algorithm | tr -d '[]') + fi +fi + +# --- 6. PERFORM ACTION --- + +case "$ACTION" in + setup) + exec 1> >(logger -s -t memory-manager) 2>&1 + apply_tuning + setup_zram + setup_swapfile + ;; + stop) + exec 1> >(logger -s -t memory-manager) 2>&1 + stop_zram + stop_swapfile + ;; + reload) + exec 1> >(logger -s -t memory-manager) 2>&1 + logger "Reloading memory configuration..." + if ! check_safety; then exit 1; fi + stop_swapfile + stop_zram + apply_tuning + setup_zram + setup_swapfile + ;; + optimize) + exec 1> >(logger -s -t memory-manager) 2>&1 + perform_optimization + ;; + drop-caches) + drop_caches + ;; + status) + show_status + ;; + json) + show_status_json + ;; +esac +exit 0 diff --git a/projects/ArchR/packages/archr/sources/scripts/archr-report-stats b/projects/ArchR/packages/archr/sources/scripts/archr-report-stats new file mode 100755 index 0000000000..438ef2d15d --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/archr-report-stats @@ -0,0 +1,48 @@ +#!/bin/sh +# This script reports non personally identifiable information to ArchR so that we can +# see active user statistics. + +. /etc/profile + +MACHINEIDFILE=/storage/.cache/systemd-machine-id +USERID=$(cat ${MACHINEIDFILE}) + +ENDPOINT_URL="https://stats.archr.org" +MAX_RETRIES=5 +RETRY_DELAY=60 + +send_stats() { + curl -s -S -X POST \ + -F "ArchR_UID=${USERID:(-12)}" \ + -F "ArchR_VERSION=${OS_VERSION}" \ + -F "ArchR_BUILD=${OS_BUILD}" \ + -F "ArchR_SOC=${HW_DEVICE}" \ + -F "ArchR_DEV=${QUIRK_DEVICE}" \ + $ENDPOINT_URL + return $? +} + +# Try to send stats with retries +retry_count=0 +while [ $retry_count -lt $MAX_RETRIES ]; do + # Check network connectivity first (ping DNS server) + if ping -c 1 8.8.8.8 >/dev/null 2>&1; then + send_stats + exit_code=$? + + if [ $exit_code -eq 0 ]; then + echo "Statistics reported successfully." + exit 0 + else + echo "Failed to send statistics (HTTP error). Retrying in $RETRY_DELAY seconds..." + fi + else + echo "Network connection unavailable. Retrying in $RETRY_DELAY seconds..." + fi + + sleep $RETRY_DELAY + retry_count=$((retry_count + 1)) +done + +echo "Maximum retry attempts reached. Failed to report statistics." +exit 1 diff --git a/projects/ArchR/packages/archr/sources/scripts/archr-retroachievements-info b/projects/ArchR/packages/archr/sources/scripts/archr-retroachievements-info new file mode 100755 index 0000000000..623eb37ee9 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/archr-retroachievements-info @@ -0,0 +1,104 @@ +#!/bin/bash +# +# Get RetroAchievements information for ArchR +# +# @lbrpdx on Batocera Forums and Discord +# +# 20191124 - v2 with now outputs in XML format (for Batocera 5.25+) +# 20200113 - updated for retroachievements.org HTML changes +# 20200124 - added badges for each game played +# 20200304 - fixed a bug in rare cases where a RA game has no success icons +# 20200410 - updated for retroachievements.org HTML changes, again +# 20200625 - retroachievements.org HTML changes, again +# 20201104 - retroachievements.org HTML changes, again, again +# +# Usage: +# archr-retroachievements-info +# +CONFIGFILE="/storage/.config/system/configs/system.cfg" +TIMEOUT=4 # seconds before timeout (>2 sec) +USER="" + +############################### +# +function usage() { + echo "$0 username" + echo " - where username is the RetroAchievements username you want to check out" + exit 1 +} + +############################### +# +function process() { + fn=$(date +"%s") + tmpfile=/tmp/ra_$fn + curl -H 'Cache-Control: no-cache' -m "$TIMEOUT" -o $tmpfile https://retroachievements.org/user/$USER 2>/dev/null + if [ x"$?" != x0 ]; then + echo "" + echo "" + echo " $fn" + echo " RetroAchievements website is too slow to respond" + echo "" + exit 1; + fi + cat "$tmpfile" | awk -v FS="(
|
)" '{print $2}' | uniq > "$tmpfile"_2 + idcard=$(cat "$tmpfile" | sed -e "/^[[:blank:]]*$/d" | awk -v FS="(

Member Since: |
Account Type:)" '{print $2}' | uniq) + parsedid=$(echo "$idcard" | sed -e "/^[[:blank:]]*$/d" | sed -e "s;\(.*\)
Last Activity: \(.*\);\1@\2;") + avcompletion=$(cat "$tmpfile" | sed -e "/^[[:blank:]]*$/d" | awk -v FS="(
Average Completion: |
Site Rank:)" '{print $2}' | sed -e "/^[[:blank:]]*$/d" | uniq) + points=$(cat "$tmpfile"_2 | sed -e "/^[[:blank:]]*$/d" | awk -v FS="( |)" '{print $2}' | sed -e "s;(\([0-9]*\) points);\1;") + if [ x"$points" != x ] && [ "$points" -ge 1 ]; then + rank=$(cat "$tmpfile"_2 | sed -e "/^[[:blank:]]*$/d" | awk -v FS="(globalRanking.php|

)" '{print $3}' | sed -e "s/\?[a-zA-Z0-9=&;']*>//" -e "s;;;" -e "s;%).*;%);") + ## For future use: UserPic is RetroAchievements' user avatar - however the S3 bucket is protected. + # UserPic=$(cat $tmpfile | grep 'meta property=.og:image. content=' | cut -d= -f3 | awk -F\' '{print $2}') + # Workaround: use the line below + UserPic="https://retroachievements.org/UserPic/$USER".png + pic="" + curl -H 'Cache-Control: no-cache' -m "$TIMEOUT" -f -s "$UserPic" >/dev/null 2>/dev/null + if [ x"$?" == x0 ]; then + pic=" $UserPic\n" + fi + echo "" + echo "" + echo " $fn" + echo " $USER" + echo " $points" + echo " $rank" + echo " $avcompletion" + echo -ne "$pic" + echo "$parsedid" | sed -e "s;\(.*\)@\(.*\); \1\n \2;" + xmllint --html "$tmpfile" 2>/dev/null | grep '.*points.' | sed -e "/^[[:blank:]]*$/d" | sed -e 's:\(.*\)points\.
:\1points\@\\\n:g;' > "$tmpfile"_2 + cat "$tmpfile"_2 | awk -v FS="(href=\"/[gG]ame/[0-9]*\">|@)" '{print $2}' | sed -e "s;

\(Last played[ 0-9:-]*\)
\(.*\);@\2@\1;" | sed -e "s;achievements, ;achievements@;" | sed -e "s;Earned ;;" | sed -e "/^[[:blank:]]*$/d" > "$tmpfile"_st + cat "$tmpfile"_2 | grep -e 'div class="bb_inline" onmouseover' -e '^$' | sed "s:.*src=\"\(.*/Badge/.*\.png\)\".*:\1:" | sed "s;^$;https://batocera.org/favicon-64.png;" > "$tmpfile"_ba + i=0 + if [ $(cat "$tmpfile"_ba | wc -l) -eq $(cat "$tmpfile"_st | wc -l) ]; then + while IFS= read -r line || [[ -n "$line" ]]; do + i=$((i+1)) + echo "$line" | sed -e "s;\(.*\)@\(.*\) achievements@\(.*\) points@Last played \(.*\); \n \1\n \2\n \3\n \4;" + cat "$tmpfile"_ba | head -n "$i" | tail -n 1 | sed "s:^: :;s:$::" + echo " " + done < "$tmpfile"_st + else + echo "$res" | sed -e "s;\(.*\)@\(.*\) achievements@\(.*\) points@Last played \(.*\); \n \1\n \2\n \3\n \4\n ;" + fi + echo "
" + else + echo "" + echo "" + echo " $fn" + echo " Player $USER hasn't unlocked any RetroAchievement yet" + echo "" + fi + rm "$tmpfile" "$tmpfile"_2 "$tmpfile"_st "$tmpfile"_ba 2>/dev/null +} + +#### Main loop +# +if [ $# -lt 1 ]; then + [ -f "$CONFIGFILE" ] && USER=$(grep -E "^[ \t]*global.retroachievements.username=" "$CONFIGFILE" | cut -d= -f2 | uniq) +else + tmp="$1" + [ x"${tmp::1}" == "x-" ] && usage || USER="$1" +fi + +[ x"$USER" == x ] && usage || process + diff --git a/projects/ArchR/packages/archr/sources/scripts/archr-scraper b/projects/ArchR/packages/archr/sources/scripts/archr-scraper new file mode 100755 index 0000000000..5d03e3cf5e --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/archr-scraper @@ -0,0 +1,79 @@ +#!/bin/bash + +systemsetting="/usr/bin/archr-settings" +syslang=$($systemsetting -command load -key system.language) +IMGSTYLE=$($systemsetting -command load -key scrapper.style) + +if test $# = 1 +then + DOSYS=$1 +fi + +# supported languages : en, fr, es, de, pt +case "${syslang}" in + fr_FR) + sslang=fr,en + ;; + es_ES) + sslang=es,en + ;; + de_DE) + sslang=de,en + ;; + pt_PT) + sslang=pt,en + ;; + pt_BR) + sslang=pt,en + ;; + *) + sslang=en +esac + +if test -z "${IMGSTYLE}" +then + IMGSTYLE="b,f,a,l,3b,s" +fi + +do_scrap() { + LRDIR=$1 + NF=$(ls "${LRDIR}" | grep -vE '\.txt$|\.xml$' | wc -l) + if test "${NF}" -gt 0 + then + BASEDIR=$(basename "${LRDIR}") + echo "GAME: system ${BASEDIR}" + EXTRAOPT= + + for x in "mame" "fba" "fba_libretro" "neogeo" + do + test "${LRDIR}" = "/storage/roms/${x}" && EXTRAOPT="-mame" + done + + (cd "${LRDIR}" && sselph-scraper -console_src ss,gdb,ovgdb -lang "${sslang}" -console_img "${IMGSTYLE}" -download_videos -workers 5 ${EXTRAOPT}) 2>&1 + fi +} + +# find system to scrape +(if test -n "${DOSYS}" + then + test -d "/storage/roms/${DOSYS}" && echo "/storage/roms/${DOSYS}" + else + find /storage/roms -maxdepth 1 -mindepth 1 -type d + fi) | + while read RDIR1 + do + # read the 2 next dir + read RDIR2 + read RDIR3 + read RDIR4 + + do_scrap "${RDIR1}" & + test -n "${RDIR2}" && do_scrap "${RDIR2}" & + test -n "${RDIR3}" && do_scrap "${RDIR3}" & + test -n "${RDIR4}" && do_scrap "${RDIR4}" & + wait + + done + +# synchronize to not make the usb/sdcard slowing down once finnished +sync diff --git a/projects/ArchR/packages/archr/sources/scripts/archr-settings b/projects/ArchR/packages/archr/sources/scripts/archr-settings new file mode 100755 index 0000000000..c9d32e9b54 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/archr-settings @@ -0,0 +1,267 @@ +#!/bin/bash + +# archr-settings can mimic archrSettings.py +# goal: abolish this python script, it's useless for the sake of the load feature only +# get a more user friendly environment for setting, getting and saving keys +# +# Usage of BASE COMMAND: +# longform: --command --key --value +# +# shortform: +# +# --command load write enable disable status +# --key any key in system.cfg (kodi.enabled...) +# --value any alphanumerical string +# use quotation marks to avoid globbing use slashes escape special characters + +# This script reads only 1st occurrence if string and writes only to this first hit +# +# This script uses #-Character to comment values +# +# If there is a boolean value (0,1) then then enable and disable command will set the corresponding +# boolean value. + +# Examples: +# 'archr-settings --command load --key wifi.enabled' will print out 0 or 1 +# 'archr-settings --command write --key wifi.ssid -value "This is my NET"' will set 'wlan.ssid=This is my NET' +# 'archr-settings enable wifi.ssid' will remove # from configfile (activate) +# 'archr-settings disable wifi.enabled' will set key wifi.enabled=0 +# 'archr-settings /myown/config.file --command status --key my.key' will output status of own config.file and my.key + +# by cyperghost - 2019/12/30 + +##### INITS ##### +ArchR_CONFIGFILE="/storage/.config/system/configs/system.cfg" +COMMENT_CHAR_SEARCH="[#|;]" +COMMENT_CHAR="#" +##### INITS ##### + +##### Function Calls ##### + +function get_config() { + #Will search for key.value and #key.value for only one occurrence + #If the character is the COMMENT CHAR then set value to it + #Otherwise strip till the equal-char to obtain value + local val + local ret + val="$(grep -E -m1 "^\s*$1\s*=" $ArchR_CONFIGFILE)" + ret=$? + if [[ $ret -eq 1 ]]; then + val="$(grep -E -m1 "^$COMMENT_CHAR_SEARCH\s*$1\s*=" $ArchR_CONFIGFILE)" + ret=$? + [[ $ret -eq 0 ]] && val=$COMMENT_CHAR + else + #Maybe here some finetuning to catch key.value = ENTRY without blanks + val="${val#*=}" + fi + echo "$val" + return $ret +} + +function set_config() { + #Will search for first key.name at beginning of line and write value to it + sed -i "1,/^\(\s*$1\s*=\).*/s//\1$2/" "$ArchR_CONFIGFILE" +} + +function uncomment_config() { + #Will search for first Comment Char at beginning of line and remove it + sed -i "1,/^$COMMENT_CHAR_SEARCH\(\s*$1\)/s//\1/" "$ArchR_CONFIGFILE" +} + +function comment_config() { + #Will search for first key.name at beginning of line and add a comment char to it + sed -i "1,/^\(\s*$1\)/s//$COMMENT_CHAR\1/" "$ArchR_CONFIGFILE" +} + +function check_argument() { + # This method does not accept arguments starting with '-'. + if [[ -z "$2" || "$2" =~ ^- ]]; then + echo >&2 + echo "ERROR: '$1' is missing an argument." >&2 + echo >&2 + echo "Just type '$0' to see usage page." >&2 + echo >&2 + return 1 + fi +} + +function dash_style() { + #This function is needed to "simulate" the python script with single dash + #commands. It will also accept the more common posix double dashes + #Accept dashes and double dashes and build new array ii with parameter set + #The else-branch can be used for the shortform + + for i in --command --key --value; do + if [[ -z "$1" ]]; then + continue + elif [[ "$i" =~ ^-{0,1}"${1,,}" ]]; then + check_argument $1 $2 + [[ $? -eq 0 ]] || exit 1 + ii+=("$2") + shift 2 + else + ii+=("$1") + shift 1 + fi + done +} + + +function usage() { +val=" Usage of BASE COMMAND: + + --command --key --value + + shortform: + + --command load write enable disable status + --key any key in system.cfg (kodi.enabled...) + --value any alphanumerical string + use quotation marks to avoid globbing + + For write command --value must be provided + + exit codes: exit 0 = value is available, proper exit + exit 1 = general error + exit 2 = file error + exit 10 = value found, but empty + exit 11 = value found, but not activated + exit 12 = value not found + + If you don't set a filename then default is '~/storage/.config/system.cfg'" + +echo "$val" + +} +##### Function Calls ##### + +##### MAIN FUNCTION ##### +function main() { + + #Filename parsed? + if [[ -f "$1" ]]; then + ArchR_CONFIGFILE="$1" + shift + else + [[ -f "$ArchR_CONFIGFILE" ]] || { echo "not found: $ArchR_CONFIGFILE" >&2; exit 2; } + fi + + #How much arguments are parsed, up to 6 then it is the long format + #up to 3 then it is the short format + if [[ ${#@} -eq 0 || ${#@} -gt 6 ]]; then + usage + exit 1 + else + dash_style "$@" + command="${ii[0]}" + keyvalue="${ii[1]}" + newvalue="${ii[2]}" + unset ii + fi + + [[ -z $keyvalue ]] && { echo "error: Please provide a proper keyvalue" >&2; exit 1; } + + # value processing, switch case + case "${command,,}" in + + "read"|"get"|"load") + val="$(get_config $keyvalue)" + ret=$? + [[ "$val" == "$COMMENT_CHAR" ]] && exit 11 + [[ -z "$val" && $ret -eq 0 ]] && exit 10 + [[ -z "$val" && $ret -eq 1 ]] && exit 12 + [[ -n "$val" ]] && echo "$val" && exit 0 + ;; + + "stat"|"status") + val="$(get_config $keyvalue)" + ret=$? + [[ -f "$ArchR_CONFIGFILE" ]] && echo "ok: found '$ArchR_CONFIGFILE'" >&2 || echo "error: not found '$ArchR_CONFIGFILE'" >&2 + [[ -w "$ArchR_CONFIGFILE" ]] && echo "ok: r/w file '$ArchR_CONFIGFILE'" >&2 || echo "error: r/o file '$ArchR_CONFIGFILE'" >&2 + [[ -z "$val" && $ret -eq 1 ]] && echo "error: '$keyvalue' not found!" >&2 + [[ -z "$val" && $ret -eq 0 ]] && echo "error: '$keyvalue' is empty - use 'comment' command to retrieve" >&2 + [[ "$val" == "$COMMENT_CHAR" ]] && echo "error: '$keyvalue' is commented $COMMENT_CHAR!" >&2 && val= + [[ -n "$val" ]] && echo "ok: '$keyvalue' $val" + exit 0 + ;; + + "set"|"write"|"save") + #Is file write protected? + [[ -w "$ArchR_CONFIGFILE" ]] || { echo "r/o file: $ArchR_CONFIGFILE" >&2; exit 2; } + #We can comment line above to erase keys, it's much saver to check if a value is setted + [[ -z "$newvalue" ]] && echo "error: '$keyvalue' needs value to be setted" >&2 && exit 1 + + val="$(get_config $keyvalue)" + ret=$? + if [[ "$val" == "$COMMENT_CHAR" ]]; then + echo "$keyvalue: hashed out!" >&2 + uncomment_config "$keyvalue" + set_config "$keyvalue" "$newvalue" + echo "$keyvalue: set from '$val' to '$newvalue'" >&2 + exit 0 + elif [[ -z "$val" && $ret -eq 1 ]]; then + echo "$keyvalue: not found!" >&2 + exit 12 + elif [[ "$val" != "$newvalue" ]]; then + set_config "$keyvalue" "$newvalue" + exit 0 + fi + ;; + + "uncomment"|"enable"|"activate") + val="$(get_config $keyvalue)" + ret=$? + # Boolean + if [[ "$val" == "$COMMENT_CHAR" ]]; then + uncomment_config "$keyvalue" + echo "$keyvalue: removed '$COMMENT_CHAR', key is active" >&2 + elif [[ "$val" == "0" ]]; then + set_config "$keyvalue" "1" + echo "$keyvalue: boolean set '1'" >&2 + elif [[ -z "$val" && $ret -eq 1 ]]; then + echo "$keyvalue: not found!" && exit 2 + fi + ;; + + "comment"|"disable"|"remark") + val="$(get_config $keyvalue)" + ret=$? + # Boolean + [[ "$val" == "$COMMENT_CHAR" || "$val" == "0" ]] && exit 0 + if [[ -z "$val" && $ret -eq 1 ]]; then + echo "$keyvalue: not found!" >&2 && exit 12 + elif [[ "$val" == "1" ]]; then + set_config "$keyvalue" "0" + echo "$keyvalue: boolean set to '0'" >&2 + else + comment_config "$keyvalue" + echo "$keyvalue: added '$COMMENT_CHAR', key is not active" >&2 + fi + ;; + + *) + echo "ERROR: invalid command '$command'" >&2 + exit 1 + ;; + esac +} +##### MAIN FUNCTION ##### + +##### MAIN CALL ##### + +# Prepare arrays from fob python script +# Keyword for python call is mimic_python +# Attention the unset is needed to eliminate first argument (python basefile) + +if [[ "${#@}" -eq 1 && "$1" =~ "mimic_python" ]]; then + #archrSettings.py fob + readarray -t arr <<< "$1" + unset arr[0] +else + #regular call by shell + arr=("$@") +fi + +main "${arr[@]}" + +##### MAIN CALL ##### diff --git a/projects/ArchR/packages/archr/sources/scripts/archr-systems b/projects/ArchR/packages/archr/sources/scripts/archr-systems new file mode 100755 index 0000000000..ca4d00a3ae --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/archr-systems @@ -0,0 +1,971 @@ +#!/usr/bin/env python + +from __future__ import print_function + +from hashlib import md5 +from os.path import isfile +from collections import OrderedDict +import sys +import zipfile +import xml.etree.ElementTree as elementTree + +systems = { + + # ---------- Atari ---------- # + # https://docs.libretro.com/library/atari800/#bios + "atari800": { "name": "Atari 800", "biosFiles": [ { "md5": "eb1f32f5d9f382db1bbfb8d7f9cb343a", "file": "bios/ATARIOSA.ROM"}, + { "md5": "4177f386a3bac989a981d3fe3388cb6c", "file": "bios/ATARIOSB.ROM"}, + { "md5": "06daac977823773a3eea3422fd26a703", "file": "bios/ATARIXL.ROM" }, + # The BASIC cart came with all Atari computers. On the XL and XE, it was built-in, so it's required by those models. + { "md5": "0bac0c6a50104045d902df4503a4c30b", "file": "bios/ATARIBAS.ROM"} ] }, + + "atari5200": { "name": "Atari 5200", "biosFiles": [ { "md5": "281f20ea4320404ec820fb7ec0693b38", "file": "bios/5200.rom" } ] }, + + # https://github.com/libretro/libretro-super/blob/master/dist/info/hatari_libretro.info + "atarist": { "name": "Atari ST", "biosFiles": [ { "md5": "c1c57ce48e8ee4135885cee9e63a68a2", "file": "bios/tos.img"}, # TOS 1.02 US + # Atari ST / STf / STfm + { "md5": "25789a649faff0a1176dc7d9b98105c0", "file": "bios/tos100fr.img"}, + { "md5": "c87a52c277f7952b41c639fc7bf0a43b", "file": "bios/tos100uk.img"}, + { "md5": "d0f682ee6237497004339fb02172638b", "file": "bios/tos100us.img"}, + + { "md5": "a622cc35d8d78703905592dfaa4d2ccb", "file": "bios/tos102de.img"}, + { "md5": "d6521785627d20c51edc566808a6bf28", "file": "bios/tos102fr.img"}, + { "md5": "b2a8570de2e850c5acf81cb80512d9f6", "file": "bios/tos102uk.img"}, + #{ "md5": "c1c57ce48e8ee4135885cee9e63a68a2", "file": "bios/tos102us.img"}, + + { "md5": "41b7dae4e24735f330b63ad923a0bfbc", "file": "bios/tos104de.img"}, + { "md5": "143343f7b8e0b1162af206fe8f46b002", "file": "bios/tos104es.img"}, + { "md5": "0087e2707c57efa2106a0aa7576655c0", "file": "bios/tos104fr.img"}, + #{ "md5": "52248cc70ae48b3050e197e270917130", "file": "bios/tos104nl.img"}, + #{ "md5": "7c040857bdcfcd7d748ca82205463efa", "file": "bios/tos104se.img"}, + { "md5": "036c5ae4f885cbf62c9bed651c6c58a8", "file": "bios/tos104uk.img"}, + { "md5": "736adb2dc835df4d323191fdc8926cc9", "file": "bios/tos104us.img"}, + + # Atari STe + { "md5": "992bac38e01633a529121a2a65f0779e", "file": "bios/tos106de.img"}, + { "md5": "30f69d70fe7c210300ed83f991b12de9", "file": "bios/tos106es.img"}, + { "md5": "bc7b224d0dc3f0cc14c8897db89c5787", "file": "bios/tos106fr.img"}, + { "md5": "6033f2b9364edfed321c6931a8181fd2", "file": "bios/tos106uk.img"}, + { "md5": "a0982e760f9807d82667ff5a69e78f6b", "file": "bios/tos106us.img"}, + + { "md5": "94a75c1c65408d9f974b0463e15a3b11", "file": "bios/tos162de.img"}, + { "md5": "ed5fbaabe0219092df74c6c14cea3f8e", "file": "bios/tos162fr.img"}, + #{ "md5": "6f9471098a521214fad1e2c6f2dd3d08", "file": "bios/tos162se.img"}, + { "md5": "1cbc4f55295e469fc8cd72b7efdea1da", "file": "bios/tos162uk.img"}, + { "md5": "febb00ba8784798293a7ae709a1dafcb", "file": "bios/tos162us.img"}, + + # Atari Mega STe + { "md5": "7aeabdc25f8134590e25643a405210ca", "file": "bios/tos205de.img"}, + { "md5": "7449b131681f1dfe62ebed1392847057", "file": "bios/tos205es.img"}, + { "md5": "61b620ad951815a25cb37895c81a947c", "file": "bios/tos205fr.img"}, + { "md5": "7e87d8fe7e24e0b4c55ad1b7955beae3", "file": "bios/tos205it.img"}, + #{ "md5": "1c92855316a33faee602b8007f22d2cb", "file": "bios/tos205se.img"}, + { "md5": "7cdd45b6aac66a21bfb357d9334e46db", "file": "bios/tos205us.img"}, + + { "md5": "0604dbb85928f0598d04144a8b554bbe", "file": "bios/tos206de.img"}, + { "md5": "b2873004a408b8db36321f98daafa251", "file": "bios/tos206fr.img"}, + { "md5": "4a0d4f282c3f2a0196681adf88862dd4", "file": "bios/tos206.img"}, + #{ "md5": "332fe3803a7e20cd625b27a69f07ae69", "file": "bios/tos206ru.img"}, + #{ "md5": "a7dc40dc5c1086bce1a8f3d44fd29051", "file": "bios/tos206se.img"}, + { "md5": "e690bec90d902024beed549d22150755", "file": "bios/tos206uk.img"}, + { "md5": "c9093f27159e7d13ac0d1501a95e53d4", "file": "bios/tos206us.img"}, + + # Atari TT + { "md5": "066f39a7ea5789d5afd59dd7b3104fa6", "file": "bios/tos306de.img"}, + { "md5": "dd1010ec566efbd71047d6c4919feba5", "file": "bios/tos306uk.img"}, + + # Atari Falcon + { "md5": "ed2647936ce4bd283c4d7dfd7ae09d1c", "file": "bios/tos400.img"}, + { "md5": "9e880168d0a004f7f5e852be758f39e4", "file": "bios/tos402.img"}, + { "md5": "e5ea0f216fb446f1c4a4f476bc5f03d4", "file": "bios/tos404.img"} ] }, + + # https://docs.libretro.com/library/beetle_handy/#bios + "lynx": { "name": "Lynx", "biosFiles": [ { "md5": "fcd403db69f54290b51035d82f835e7b", "file": "bios/lynxboot.img"} ] }, + + # ---------- Magnavox and Philips ---------- # + # https://docs.libretro.com/library/o2em/#bios + "o2em": { "name": "Odyssey 2", "biosFiles": [ { "md5": "562d5ebf9e030a40d6fabfc2f33139fd", "file": "bios/o2rom.bin" }, + { "md5": "f1071cdb0b6b10dde94d3bc8a6146387", "file": "bios/c52.bin" } ] }, + + "videopacplus": { "name": "Videopac+ G7400", "biosFiles": [ { "md5": "c500ff71236068e0dc0d0603d265ae76", "file": "bios/g7400.bin" }, + { "md5": "279008e4a0db2dc5f1c048853b033828", "file": "bios/jopac.bin" } ] }, + + # ---------- Mattel ---------- # + # https://docs.libretro.com/library/freeintv/#bios + "intellivision": { "name": "Mattel Intellivision", "biosFiles": [ { "md5": "62e761035cb657903761800f4437b8af", "file": "bios/exec.bin" }, + { "md5": "0cd5946c6473e42e8e4c2137785e427f", "file": "bios/grom.bin" } ] }, + + # ---------- NEC ---------- # + # https://docs.libretro.com/library/beetle_pce_fast/#bios + "pcengine": { "name": "PC Engine", "biosFiles": [ { "md5": "38179df8f4ac870017db21ebcbf53114", "file": "bios/syscard3.pce" } ] }, + + # https://docs.libretro.com/library/beetle_pc_fx/#bios + "pcfx": { "name": "PC-FX", "biosFiles": [ { "md5": "08e36edbea28a017f79f8d4f7ff9b6d7", "file": "bios/pcfx.rom" } ] }, + + # https://docs.libretro.com/library/beetle_pce_fast/#bios + "supergrafx": { "name": "Supergrafx", "biosFiles": [ { "md5": "38179df8f4ac870017db21ebcbf53114", "file": "bios/syscard3.pce" } ] }, + + # ---------- SNK ----------# + "neogeo": { "name": "NeoGeo", "biosFiles": [ { "md5": "dffb72f116d36d025068b23970a4f6df", "file": "bios/neogeo.zip" } ] }, + "neogeocd": { "name": "NeoGeo CD", "biosFiles": [ { "md5": "8834880c33164ccbe6476b559f3e37de", "file": "bios/neocd/neocd_f.rom" }, + { "md5": "043d76d5f0ef836500700c34faef774d", "file": "bios/neocd/neocd_sf.rom" }, + { "md5": "de3cf45d227ad44645b22aa83b49f450", "file": "bios/neocd/neocd_t.rom" }, + { "md5": "f6325a33c6d63ea4b9162a3fa8c32727", "file": "bios/neocd/neocd_st.rom" }, + { "md5": "11526d58d4c524daef7d5d677dc6b004", "file": "bios/neocd/neocd_z.rom" }, + { "md5": "971ee8a36fb72da57aed01758f0a37f5", "file": "bios/neocd/neocd_sz.rom" }, + { "md5": "5c2366f25ff92d71788468ca492ebeca", "file": "bios/neocd/front-sp1.bin" }, + { "md5": "122aee210324c72e8a11116e6ef9c0d0", "file": "bios/neocd/top-sp1.bin" }, + { "md5": "f39572af7584cb5b3f70ae8cc848aba2", "file": "bios/neocd/neocd.bin"}, + { "md5": "08ca8b2dba6662e8024f9e789711c6fc", "file": "bios/neocd/uni-bioscd.rom"} ] }, + + # ---------- Sharp ---------- # + # https://github.com/libretro/libretro-super/blob/master/dist/info/px68k_libretro.info + "x68000": { "name": "Sharp x68000", "biosFiles": [ { "md5": "7fd4caabac1d9169e289f0f7bbf71d8e", "file": "bios/keropi/iplrom.dat" }, + { "md5": "cb0a5cfcf7247a7eab74bb2716260269", "file": "bios/keropi/cgrom.dat" } ] }, + + # ---------- Panasonic, Sanyo and Goldstar ---------- # + # https://github.com/libretro/libretro-super/blob/master/dist/info/opera_libretro.info + "3do": { "name": "3DO", "biosFiles": [ { "md5": "f47264dd47fe30f73ab3c010015c155b", "file": "bios/panafz1.bin" }, + { "md5": "51f2f43ae2f3508a14d9f56597e2d3ce", "file": "bios/panafz10.bin"}, + { "md5": "8639fd5e549bd6238cfee79e3e749114", "file": "bios/goldstar.bin"} ] }, + + # ---------- Sega ---------- # + # https://docs.libretro.com/library/flycast/#bios + "dreamcast": { "name": "Dreamcast", "biosFiles": [ { "md5": "e10c53c2f8b90bab96ead2d368858623", "file": "bios/dc_boot.bin" }, + { "md5": "0a93f7940c455905bea6e392dfde92a4", "file": "bios/dc_flash.bin" } ] }, + + # https://github.com/libretro/libretro-super/blob/master/dist/info/flycast_libretro.info + "naomi": { "name": "Naomi", "biosFiles": [ { "md5": "eb4099aeb42ef089cfe94f8fe95e51f6", "file": "bios/dc/naomi.zip" } ] }, + + "atomiswave": { "name": "Atomiswave", "biosFiles": [ { "md5": "85254fbe320ca82a768ec2c26bb08def", "file": "bios/dc/awbios.zip" } ] }, + + "segacd": { "name": "Sega CD", "biosFiles": [ { "md5": "e66fa1dc5820d254611fdcdba0662372", "file": "bios/bios_CD_E.bin" }, + { "md5": "854b9150240a198070150e4566ae1290", "file": "bios/bios_CD_U.bin" }, + { "md5": "278a9397d192149e84e820ac621a8edd", "file": "bios/bios_CD_J.bin" } ] }, + + # https://docs.libretro.com/library/genesis_plus_gx/#bios + "msu-md": { "name": "MSU-MD", "biosFiles": [ { "md5": "e66fa1dc5820d254611fdcdba0662372", "file": "bios/bios_CD_E.bin" }, + { "md5": "854b9150240a198070150e4566ae1290", "file": "bios/bios_CD_U.bin" }, + { "md5": "278a9397d192149e84e820ac621a8edd", "file": "bios/bios_CD_J.bin" } ] }, + + # https://docs.libretro.com/library/beetle_saturn/#bios + # https://github.com/libretro/libretro-super/blob/master/dist/info/yabasanshiro_libretro.info + "saturn": { "name": "Sega Saturn", "biosFiles": [ { "md5": "85ec9ca47d8f6807718151cbcca8b964", "file": "bios/sega_101.bin" }, + { "md5": "3240872c70984b6cbfda1586cab68dbe", "file": "bios/mpr-17933.bin" }, + { "md5": "255113ba943c92a54facd25a10fd780c", "file": "bios/mpr-18811-mx.ic1" }, + { "md5": "1cd19988d1d72a3e7caa0b73234c96b4", "file": "bios/mpr-19367-mx.ic1" }, + { "md5": "af5828fdff51384f99b3c4926be27762", "file": "bios/saturn_bios.bin" } ] }, + + # ---------- Sony Computer Entertainment ---------- # + # https://docs.libretro.com/library/pcsx_rearmed/#bios + "psx": { "name": "PSX", "biosFiles": [ { "md5": "c53ca5908936d412331790f4426c6c33", "file": "bios/psxonpsp660.bin" }, + { "md5": "6e3735ff4c7dc899ee98981385f6f3d0", "file": "bios/scph101.bin" }, + { "md5": "dc2b9bf8da62ec93e868cfd29f0d067d", "file": "bios/scph1001.bin" }, + { "md5": "8dd7d5296a650fac7319bce665a6a53c", "file": "bios/scph5500.bin" }, + { "md5": "490f666e1afb15b7362b406ed1cea246", "file": "bios/scph5501.bin" }, + { "md5": "32736f17079d0b2b7024407c39bd3050", "file": "bios/scph5502.bin" }, + { "md5": "1e68c231d0896b7eadcad1d7d8e76129", "file": "bios/scph7001.bin" } ] }, + + # https://pcsx2.net/config-guide/official-english-pcsx2-configuration-guide.html#Bios + # use the last USA bios which can run NTSC and PAL games + "ps2": { "name": "PS2", "biosFiles": [ { "md5": "21038400dc633070a78ad53090c53017", "file": "bios/ps2/ps2-0230a-20080220.bin" } ] }, + + # https://www.playstation.com/en-us/support/system-updates/ps3/ + "ps3": { "name": "PS3", "biosFiles": [ { "md5": "05fe32f5dc8c78acbcd84d36ee7fdc5b", "file": "bios/PS3UPDAT.PUP" } ] }, + + # ---------- Nintendo ---------- # + # https://docs.libretro.com/library/fceumm/#bios + "fds": { "name": "Nintendo Family Computer Disk System", "biosFiles": [ { "md5": "ca30b50f880eb660a320674ed365ef7a", "file": "bios/disksys.rom" } ] }, + + # https://docs.libretro.com/library/melonds/#bios + "nds": { "name": "Nintendo DS", "biosFiles": [ { "md5": "", "file": "bios/firmware.bin" }, # ideally - 94bc5094607c5e6598d50472c52f27f2 + { "md5": "df692a80a5b1bc90728bc3dfc76cd948", "file": "bios/bios7.bin" }, + { "md5": "a392174eb3e572fed6447e956bde4b25", "file": "bios/bios9.bin" }, + { "md5": "559dae4ea78eb9d67702c56c1d791e81", "file": "bios/dsi_bios7.bin" }, + { "md5": "87b665fce118f76251271c3732532777", "file": "bios/dsi_bios9.bin" }, + { "md5": "", "file": "bios/dsi_firmware.bin" }, # ideally - 74f23348012d7b3e1cc216c47192ffeb + { "md5": "", "file": "bios/dsi_nand.bin" } # ideally - d71edf897ddd06bf335feeb68edeb272 + ] }, + + # https://docs.libretro.com/library/mgba/#bios + "gba": { "name": "Nintendo Gameboy Advance", "biosFiles": [ { "md5": "a860e8c0b6d573d191e4ec7db1b1e4f6", "file": "bios/gba_bios.bin" }, + { "md5": "32fbbd84168d3482956eb3c5051637f5", "file": "bios/gb_bios.bin" }, # Optional + { "md5": "dbfce9db9deaa2567f6a84fde55f9680", "file": "bios/gbc_bios.bin" }, # Optional + { "md5": "d574d4f9c12f305074798f54c091a8b4", "file": "bios/sgb_bios.bin" } ] }, # Optional + + # https://docs.libretro.com/library/snes9x/#bios + "satellaview": { "name": "Satellaview", "biosFiles": [ { "md5": "96cf17bf589fcbfa6f8de2dc84f19fa2", "file": "bios/BS-X.bin" } ] }, + "sufami": { "name": "Sufami", "biosFiles": [ { "md5": "d3a44ba7d42a74d3ac58cb9c14c6a5ca", "file": "bios/STBIOS.bin" } ] }, + + # https://docs.libretro.com/library/mesen-s/#bios + "sgb": { "name": "Super Game Boy", "biosFiles": [ { "md5": "d574d4f9c12f305074798f54c091a8b4", "file": "bios/sgb_boot.bin" }, + { "md5": "e0430bca9925fb9882148fd2dc2418c1", "file": "bios/sgb2_boot.bin" }, + { "md5": "b15ddb15721c657d82c5bab6db982ee9", "file": "bios/SGB1.sfc" }, + { "md5": "8ecd73eb4edf7ed7e81aef1be80031d5", "file": "bios/SGB2.sfc" } ] }, + # ---------- Microsoft ---------- # + # https://docs.libretro.com/library/fmsx/#bios + "msx": { "name": "MSX", "biosFiles": [ { "md5": "364a1a579fe5cb8dba54519bcfcdac0d", "file": "bios/MSX.ROM" } ] }, + + "msx2": { "name": "MSX2", "biosFiles": [ { "md5": "ec3a01c91f24fbddcbcab0ad301bc9ef", "file": "bios/MSX2.ROM" }, + { "md5": "2183c2aff17cf4297bdb496de78c2e8a", "file": "bios/MSX2EXT.ROM" } ] }, + + "msx2+": { "name": "MSX2+", "biosFiles": [ { "md5": "847cc025ffae665487940ff2639540e5", "file": "bios/MSX2P.ROM" }, + { "md5": "7c8243c71d8f143b2531f01afa6a05dc", "file": "bios/MSX2PEXT.ROM" } ] }, + + "xbox": { "name": "Xbox", "biosFiles": [{ "md5": "d49c52a4102f6df7bcf8d0617ac475ed", "file": "bios/mcpx_1.0.bin" }, + { "md5": "39cee882148a87f93cb440b99dde3ceb", "file": "bios/Complex_4627.bin" }] }, + + # ---------- Commodore ---------- # + # https://github.com/libretro/libretro-super/blob/master/dist/info/puae_libretro.info + # https://github.com/midwan/amiberry/wiki/Kickstart-ROMs-(BIOS) + # https://fs-uae.net/docs/kickstarts + "amiga500": { "name": "Amiga 500", "biosFiles": [ { "md5": "85ad74194e87c08904327de1a9443b7a", "file": "bios/amiga/kick33180.A500" }, + { "md5": "dc10d7bdd1b6f450773dfb558477c230", "file": "bios/amiga/kick37175.A500" }, + { "md5": "82a21c1890cae844b3df741f2762d48d", "file": "bios/amiga/kick34005.A500" }, + # Amiga 600 kickstart. Not really needed but maybe someone out there will want to switch their model to Amiga 600. + { "md5": "465646c9b6729f77eea5314d1f057951", "file": "bios/amiga/kick37350.A600" }, + { "md5": "e40a5dfb3d017ba8779faba30cbd1c8e", "file": "bios/amiga/kick40063.A600" }, + # The Amiga Forever equivalents. Really are these actually needed? Just so people don't have to rename their stuff? + { "md5": "85ad74194e87c08904327de1a9443b7a", "file": "bios/amiga/amiga-os-120.rom" }, + { "md5": "82a21c1890cae844b3df741f2762d48d", "file": "bios/amiga/amiga-os-130.rom" }, + { "md5": "dc10d7bdd1b6f450773dfb558477c230", "file": "bios/amiga/amiga-os-204.rom" }, + { "md5": "465646c9b6729f77eea5314d1f057951", "file": "bios/amiga/amiga-os-205.rom" }, + { "md5": "e40a5dfb3d017ba8779faba30cbd1c8e", "file": "bios/amiga/amiga-os-310-a600.rom" }] }, + + "amigacdtv": { "name": "Amiga CDTV", "biosFiles": [ { "md5": "82a21c1890cae844b3df741f2762d48d", "file": "bios/amiga/kick34005.A500" }, + { "md5": "89da1838a24460e4b93f4f0c5d92d48d", "file": "bios/amiga/kick34005.CDTV" }, + # CDTV requires both the Amiga 500 kickstart and its own extended kickstart. + { "md5": "82a21c1890cae844b3df741f2762d48d", "file": "bios/amiga/amiga-os-130.rom" }, + { "md5": "89da1838a24460e4b93f4f0c5d92d48d", "file": "bios/amiga/amiga-ext-130-cdtv.rom" }] }, + + "amiga1200": { "name": "Amiga 1200", "biosFiles": [ { "md5": "b7cc148386aa631136f510cd29e42fc3", "file": "bios/amiga/kick39106.A1200" }, + { "md5": "646773759326fbac3b2311fd8c8793ee", "file": "bios/amiga/kick40068.A1200" }, + { "md5": "9bdedde6a4f33555b4a270c8ca53297d", "file": "bios/amiga/kick40068.A4000" }, + # The Amiga Forever equivalents. a3000 seems to not have a kickstart equivalent. amiga-os-310.rom doesn't match libretro's docs. + { "md5": "b7cc148386aa631136f510cd29e42fc3", "file": "bios/amiga/amiga-os-300-a1200.rom" }, + { "md5": "646773759326fbac3b2311fd8c8793ee", "file": "bios/amiga/amiga-os-310-a1200.rom" }, + { "md5": "413590e50098a056cfec418d3df0212d", "file": "bios/amiga/amiga-os-310-a3000.rom" }, + { "md5": "9bdedde6a4f33555b4a270c8ca53297d", "file": "bios/amiga/amiga-os-310-a4000.rom" }, + { "md5": "730888fb1bd9a3606d51f772ed136528", "file": "bios/amiga/amiga-os-310.rom" }] }, + + "amigacd32": { "name": "Amiga CD32", "biosFiles": [ { "md5": "5f8924d013dd57a89cf349f4cdedc6b1", "file": "bios/amiga/kick40060.CD32" }, + { "md5": "bb72565701b1b6faece07d68ea5da639", "file": "bios/amiga/kick40060.CD32.ext" }, + # Unlike the CDTV, CD32 does not need the Amiga 1200 kickstart. + # But, it has its own unique "base" anyway, which is required in addition to its extended. + { "md5": "5f8924d013dd57a89cf349f4cdedc6b1", "file": "bios/amiga/amiga-os-310-cd32.rom" }, + { "md5": "bb72565701b1b6faece07d68ea5da639", "file": "bios/amiga/amiga-ext-310-cd32.rom" }] }, + + # ---------- NEC PC-8800 ---------- # + # https://github.com/RetroPie/RetroPie-Setup/wiki/PC-8800 + "pc88": { "name": "NEC PC-8800", "biosFiles": [ { "md5": "4f984e04a99d56c4cfe36115415d6eb8", "file": "bios/quasi88/N88.ROM" }, + { "md5": "793f86784e5608352a5d7f03f03e0858", "file": "bios/quasi88/N88SUB.ROM" }, + { "md5": "2ff07b8769367321128e03924af668a0", "file": "bios/quasi88/N88N.ROM" }, + { "md5": "d81c6d5d7ad1a4bbbd6ae22a01257603", "file": "bios/quasi88/N88KNJ1.ROM" }, + { "md5": "d675a2ca186c6efcd6277b835de4c7e5", "file": "bios/quasi88/N88EXT0.ROM" }, + { "md5": "e844534dfe5744b381444dbe61ef1b66", "file": "bios/quasi88/N88EXT1.ROM" }, + { "md5": "6548fa45061274dee1ea8ae1e9e93910", "file": "bios/quasi88/N88EXT2.ROM" }, + { "md5": "fc4b76a402ba501e6ba6de4b3e8b4273", "file": "bios/quasi88/N88EXT3.ROM" } ] }, + + # ---------- NEC PC-9800 ---------- # + # https://github.com/RetroPie/RetroPie-Setup/wiki/PC-9800#bios + "pc98": { "name": "NEC PC-9800", "biosFiles": [ { "md5": "e246140dec5124c5e404869a84caefce", "file": "bios/np2kai/BIOS.ROM" }, + { "md5": "2af6179d7de4893ea0b705c00e9a98d6", "file": "bios/np2kai/FONT.ROM" }, + { "md5": "caf90f22197aed6f14c471c21e64658d", "file": "bios/np2kai/SOUND.ROM"}, + { "md5": "e9fc3890963b12cf15d0a2eea5815b72", "file": "bios/np2kai/ITF.ROM" }, + { "md5": "7da1e5b7c482d4108d22a5b09631d967", "file": "bios/np2kai/font.bmp" } ] }, + # ---------- Fairchild ChannelF ---------- # + # https://github.com/libretro/FreeChaF/blob/master/README.md#bios + "channelf": { "name": "Fairchild ChannelF", "biosFiles": [ { "md5": "ac9804d4c0e9d07e33472e3726ed15c3", "file": "bios/sl31253.bin" }, + { "md5": "da98f4bb3242ab80d76629021bb27585", "file": "bios/sl31254.bin" }, + { "md5": "95d339631d867c8f1d15a5f2ec26069d", "file": "bios/sl90025.bin" } ] }, + # ---------- Sharp X1 ---------- # + # https://github.com/libretro/xmil-libretro/blob/master/README.MD + "x1": { "name": "Sharp X1", "biosFiles": [ { "md5": "eeeea1cd29c6e0e8b094790ae969bfa7", "file": "bios/xmil/IPLROM.X1" }, + { "md5": "56c28adcf1f3a2f87cf3d57c378013f5", "file": "bios/xmil/iplrom.x1t" } ] }, + + # ---------- Fujistu FM-Towns ---------- # + # https://github.com/captainys/TOWNSEMU + "fmtowns": { "name": "Fujistu FM-Towns", "biosFiles": [ { "md5": "8fa4e553f28cfc0c30a0a1e589799942", "file": "bios/fmtowns/FMT_DIC.ROM" }, + { "md5": "0585b19930d4a7f4c71bcc8a33746588", "file": "bios/fmtowns/FMT_DOS.ROM" }, + { "md5": "ac0c7021e9bf48ca84b51ab651169a88", "file": "bios/fmtowns/FMT_F20.ROM" }, + { "md5": "b91300e55b70227ce98b59c5f02fa8dd", "file": "bios/fmtowns/FMT_FNT.ROM" }, + { "md5": "86fb6f7280689259f0ca839dd3dd6cde", "file": "bios/fmtowns/FMT_SYS.ROM" }, + { "md5": "", "file": "bios/fmtmarty.zip" }, + { "md5": "6618519b2c104cf9b7e71a48381b44a9", "zippedFile": "mrom.m36", "file": "bios/fmtmarty.zip"}, + { "md5": "75a5c7afb4bc8221bab8cf24db417950", "zippedFile": "mrom.m37", "file": "bios/fmtmarty.zip"}, + { "md5": "", "file": "bios/fmtowns.zip" }, + { "md5": "34847786d7de94b5d1133c956ab1d75d", "zippedFile": "fmt_dic.rom", "file": "bios/fmtowns.zip"}, + { "md5": "0585b19930d4a7f4c71bcc8a33746588", "zippedFile": "fmt_dos.rom", "file": "bios/fmtowns.zip"}, + { "md5": "eb44f2093f51eb7159f03e170b13af76", "zippedFile": "fmt_fnt.rom", "file": "bios/fmtowns.zip"}, + { "md5": "feaf8c5675151e00cfe3ad27673bff29", "zippedFile": "fmt_sys.rom", "file": "bios/fmtowns.zip"}, + { "md5": "", "file": "bios/fmtownsux.zip" }, + { "md5": "8fa4e553f28cfc0c30a0a1e589799942", "zippedFile": "fmt_dic.rom", "file": "bios/fmtownsux.zip"}, + { "md5": "03c8fac9a5f5f5f35fb5de5a5d0d018f", "zippedFile": "fmt_dos_a.rom", "file": "bios/fmtownsux.zip"}, + { "md5": "b91300e55b70227ce98b59c5f02fa8dd", "zippedFile": "fmt_fnt.rom", "file": "bios/fmtownsux.zip"}, + { "md5": "90b5e01d42aaa93e8f4503a5e94e120b", "zippedFile": "fmt_sys_a.rom", "file": "bios/fmtownsux.zip"}, + { "md5": "1a15f6c1b58ec7e5f850118610a787a7", "zippedFile": "mytownsux.rom", "file": "bios/fmtownsux.zip"} ] }, + + # ---------- GamePark GP32 ---------- # + "gp32": { "name": "GamePark GP32", "biosFiles": [ { "md5": "", "file": "bios/gp32.zip" }, + { "md5": "e64ad881b5e1d86547f2edc3034946d9", "zippedFile": "x2c32.jed", "file": "bios/gp32.zip"}, + { "md5": "f78092f15f6ffe15975901ee4e92c680", "zippedFile": "gp32166m.bin", "file": "bios/gp32.zip"}, + { "md5": "19021cc891119c0872d46e87fc0ffe35", "zippedFile": "gp32157e.bin", "file": "bios/gp32.zip"}, + { "md5": "1e4d3216719acea231b81dfcf6069aef", "zippedFile": "gp32156k.bin", "file": "bios/gp32.zip"}, + { "md5": "cac4b56c0db80922cae75403faef40af", "zippedFile": "gp32100k.bin", "file": "bios/gp32.zip"}, + { "md5": "d4af2bc352bdaf4972ea40902feda114", "zippedFile": "gp32mfv2.bin", "file": "bios/gp32.zip"} ] }, + + # ---------- VTech Laser 310 ---------- # + "laser310": { "name": "VTech Laser 310", "biosFiles": [ { "md5": "", "file": "bios/laser310.zip" }, + { "md5": "42c8f9e6c2133ae0e953b89ccbbdb7e2", "zippedFile": "vtechv20.u12", "file": "bios/laser310.zip"}, + { "md5": "f7e5d9a3eb2b57bf5f4e2a4565318a8f", "zippedFile": "vtechv21.u12", "file": "bios/laser310.zip"} ] }, + + + # ---------- Future Pinball ---------- # + "fpinball": { "name": "Future Pinball", "biosFiles": [ { "md5": "65a8ebf870420316a939ac44fd4c731d", "file": "bios/wsh57/scripten.exe" } ] }, + + # ---------- Super Cassette Vision ---------- # + "scv": { "name": "Super Cassette Vision", "biosFiles": [ { "md5": "635a978fd40db9a18ee44eff449fc126", "file": "bios/upd7801g.s01" } ] }, + + # ---------- Apple 2 GS ---------- # + "gsplus": { "name": "Apple 2 GS", "biosFiles": [ { "md5": "20a0334c447cb069a040ae5be1d938df", "file": "bios/ROM1" } ] }, + + # ---------- Zelda Classic ---------- # + "zc210": { "name": "Zelda Classic", "biosFiles": [ { "md5": "033d7392985841027909c4c32b9f2076", "file": "bios/zc210/zcdata.dat" }, + { "md5": "39e5bc84ce9aac3a2d297d8aeb2a0d05", "file": "bios/zc210/sf2/default.sf2" }, + { "md5": "e0ba7a8634b12cfee4b6760a6f89051a", "file": "bios/zc210/sf2/custom0.sf2" }, + { "md5": "c1dc781c34cff8f9a023c0192754dc6c", "file": "bios/zc210/sf2/custom1.sf2" }, + { "md5": "144fcdbb6a30f1f916f6963006c2da97", "file": "bios/zc210/sf2/custom2.sf2" }, + { "md5": "134d217fb99c3be1e89cfaf8f28280d8", "file": "bios/zc210/sf2/custom3.sf2" }, + { "md5": "b37366199c6df9ee5316f031755aa821", "file": "bios/zc210/sf2/custom4.sf2" }, + { "md5": "64068b84eb88dc85b75148bbe9b393fb", "file": "bios/zc210/sf2/custom5.sf2" }, + { "md5": "1241986de5b1d00b02d34f1e6651a1d1", "file": "bios/zc210/sf2/custom6.sf2" }, + { "md5": "386db0d538f372a9f1af622d1e934abf", "file": "bios/zc210/sf2/custom7.sf2" }, + { "md5": "6f68e4baf89c8ee4623c19617319184b", "file": "bios/zc210/sf2/custom8.sf2" }, + { "md5": "2010e5b85f9e1d60685ccb3d84a17115", "file": "bios/zc210/sf2/custom9.sf2" }, + { "md5": "e0ba7a8634b12cfee4b6760a6f89051a", "file": "bios/zcsf.sf2" } ] }, + # ---------- Apple Mac ---------- # + "macintosh": { "name": "Apple Macintosh", "biosFiles": [ { "md5": "66223be1497460f1e60885eeb35e03cc", "file": "bios/MacII.ROM", "emulator": "libretro", "core": "minivmac" }, + { "md5": "2a8a4c7f2a38e0ab0771f59a9a0f1ee4", "file": "bios/MacIIx.ROM", "emulator": "libretro", "core": "minivmac" }, + { "md5": "", "file": "bios/mac128k.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "bc04a4252ee96826c1f41f927c145225", "zippedFile": "342-0220-a.u6d", "file": "bios/mac128k.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "409d8b9a04db15b7bfbbd5fcb931bf2e", "zippedFile": "342-0221-a.u8d", "file": "bios/mac128k.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "", "file": "bios/mackbd_m0110.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "9d09a9a51c9ef3ea5719e19db22e7901", "zippedFile": "ip8021h_2173.bin", "file": "bios/mackbd_m0110.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "", "file": "bios/mackbd_m0120.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "9d09a9a51c9ef3ea5719e19db22e7901", "zippedFile": "ip8021h_2173.bin", "file": "bios/mackbd_m0120.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "", "file": "bios/mac512k.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "b4118b89fa68a913a225f0cf9a751fae", "zippedFile": "342-0220-b.u6d", "file": "bios/mac512k.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "ab4e461833e98ef7106f24455a07769d", "zippedFile": "342-0221-b.u8d", "file": "bios/mac512k.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "", "file": "bios/macplus.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "1467a42dee57ac265d063b3f351189fc", "zippedFile": "342-0341-a.u6d", "file": "bios/macplus.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "25b1bf85b3b072d957499cef4d7e313f", "zippedFile": "342-0341-b.u6d", "file": "bios/macplus.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "cf7c3259844245a8967556fa40d81243", "zippedFile": "342-0341-c.u6d", "file": "bios/macplus.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "d5584762b43a9b1cb24a981f9b9b4198", "zippedFile": "342-0342-a.u8d", "file": "bios/macplus.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "f83069fd7ff1fb011958f819cbff4c88", "zippedFile": "342-0342-b.u8d", "file": "bios/macplus.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "875919e2544644cd628f44b5c11db036", "zippedFile": "modplus-harp2.bin", "file": "bios/macplus.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "efcefe8f11c10541a503d48a07878201", "zippedFile": "rominator-20150225-hi.bin", "file": "bios/macplus.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "f4b06da98500df0747a764dfbf1862b9", "zippedFile": "rominator-20150225-lo.bin", "file": "bios/macplus.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "", "file": "bios/macse.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "9fb38bdcc0d53d9d380897ee53dc1322", "zippedFile": "macse.rom", "file": "bios/macse.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "", "file": "bios/macclasc.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "c229bb677cb41b84b780c9e38a09173e", "zippedFile": "341-0813__=c=1983-90_apple__japan__910d_d.27c4096_be.ue1", "file": "bios/macclasc.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "", "file": "bios/mac2fdhd.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "2a8a4c7f2a38e0ab0771f59a9a0f1ee4", "zippedFile": "97221136.rom", "file": "bios/mac2fdhd.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "", "file": "bios/nb_mdc824.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "7500a6a958247ee6e092f08715f2fff8", "zippedFile": "3410868.bin", "file": "bios/nb_mdc824.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "", "file": "bios/maciix.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "2a8a4c7f2a38e0ab0771f59a9a0f1ee4", "zippedFile": "97221136.rom", "file": "bios/maciix.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "", "file": "bios/maclc3.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "fa16d49527c4e6e9c0d9e46904133d39", "zippedFile": "ecbbc41c.rom", "file": "bios/maclc3.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "", "file": "bios/mackbd_m0110a.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "9e8ea1552153c5e0f895e247e7d3ec1c", "zippedFile": "341-0332-a.bin", "file": "bios/mackbd_m0110a.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "", "file": "bios/nb_image.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "93155ac7bad0fec36837252bb1e408f2", "zippedFile": "nb_fake.bin", "file": "bios/nb_image.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "", "file": "bios/egret.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "96665499f5cf2bb5b4aae6fdaf0a9fb5", "zippedFile": "341s0850.bin", "file": "bios/egret.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "b955ecbdf6d2f979f3683dd1d6884643", "zippedFile": "341s0851.bin", "file": "bios/egret.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "5035d321c5d5fa1eab5ce6bf986676e4", "zippedFile": "344s0100.bin", "file": "bios/egret.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "", "file": "bios/adbmodem.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "862b8598cecdbc934658c4cb599a8142", "zippedFile": "342s0440-b.bin", "file": "bios/adbmodem.zip", "emulator": "libretro", "core": "mame" }, + { "md5": "", "file": "bios/macos3.img", "emulator": "libretro", "core": "mame" }, + { "md5": "", "file": "bios/macos608.img", "emulator": "libretro", "core": "mame" }, + { "md5": "", "file": "bios/macos701.img", "emulator": "libretro", "core": "mame" }, + { "md5": "", "file": "bios/macos75.img", "emulator": "libretro", "core": "mame" }, + { "md5": "", "file": "bios/mac608.chd", "emulator": "libretro", "core": "mame" }, + { "md5": "", "file": "bios/mac701.chd", "emulator": "libretro", "core": "mame" }, + { "md5": "", "file": "bios/mac755.chd", "emulator": "libretro", "core": "mame" } ] }, + + # ---------- Tandy Color Conputer ---------- # + "coco": { "name": "Tandy Color Computer", "biosFiles": [ { "md5": "", "file": "bios/coco.zip" }, + { "md5": "a74f3d95b395dad7cdca19d560eeea74", "zippedFile": "bas10.rom", "file": "bios/coco.zip"}, + { "md5": "", "file": "bios/coco2.zip" }, + { "md5": "c933316c7d939532a13648850c1c2aa6", "zippedFile": "bas12.rom", "file": "bios/coco2.zip"}, + { "md5": "21070aa0496142b886c562bf76d7c113", "zippedFile": "extbas11.rom", "file": "bios/coco2.zip"}, + { "md5": "", "file": "bios/coco2b.zip" }, + { "md5": "c2fc43556eb6b7b25bdf5955bd9df825", "zippedFile": "bas13.rom", "file": "bios/coco2b.zip"}, + { "md5": "21070aa0496142b886c562bf76d7c113", "zippedFile": "extbas11.rom", "file": "bios/coco2.zip"}, + { "md5": "", "file": "bios/coco3.zip" }, + { "md5": "7233c6c429f3ce1c7392f28a933e0b6f", "zippedFile": "coco3.rom", "file": "bios/coco3.zip"}, + { "md5": "", "file": "bios/coco3p.zip" }, + { "md5": "4ae57e5a8e7494e5485446fefedb580b", "zippedFile": "coco3p.rom", "file": "bios/coco3p.zip"}, + { "md5": "", "file": "bios/coco_fdc_v11.zip" }, + { "md5": "8cab28f4b7311b8df63c07bb3b59bfd5", "zippedFile": "disk11.rom", "file": "bios/coco_fdc_v11.zip"} ] }, + + # ---------- Tomy Tutor ---------- # + "tutor": { "name": "Tomy Tutor", "biosFiles": [ { "md5": "", "file": "bios/tutor.zip" }, + { "md5": "196ba41dd1184fe754390534cc273116", "zippedFile": "tutor1.bin", "file": "bios/tutor.zip"}, + { "md5": "5770834c10946ac2c3617504ba530884", "zippedFile": "tutor2.bin", "file": "bios/tutor.zip"} ] }, + + # ---------- TI-99 ---------- # + "ti99": { "name": "Texas Instruments TI-99", "biosFiles": [ { "md5": "", "file": "bios/ti99_4a.zip" }, + { "md5": "9bb51dfab49b9a7cf832cc1fb6f203e6", "zippedFile": "994a_grom0.u500", "file": "bios/ti99_4a.zip"}, + { "md5": "7f1864c3dac31c86e2ae6ce43ccead07", "zippedFile": "994a_grom1.u501", "file": "bios/ti99_4a.zip"}, + { "md5": "a1f77a07243a334e13509a89bff944f2", "zippedFile": "994a_grom2.u502", "file": "bios/ti99_4a.zip"}, + { "md5": "6f495eef767b3f2821a2ec32d0047891", "zippedFile": "994a_rom_hb.u610", "file": "bios/ti99_4a.zip"}, + { "md5": "0dcb961cf84c69b2171a565427c7c6c7", "zippedFile": "994a_rom_lb.u611", "file": "bios/ti99_4a.zip"}, + { "md5": "", "file": "bios/ti99_speech.zip" }, + { "md5": "491c1195f6345cb6b725096b69d81ec9", "zippedFile": "cd2325a.u2a", "file": "bios/ti99_speech.zip"}, + { "md5": "206daf498ac5d0141de1d47d38afd899", "zippedFile": "cd2326a.u2b", "file": "bios/ti99_speech.zip"} ] }, + + # ---------- Bally Astrocade ---------- # + "astrocde": { "name": "Bally Astrocade", "biosFiles": [ { "md5": "", "file": "bios/astrocde.zip" }, + { "md5": "7d25a26e5c4841b364cfe6b1735eaf03", "zippedFile": "astro.bin", "file": "bios/astrocde.zip"}, ] }, + + # ---------- Game Master ---------- # + "gmaster": { "name": "Hartung Game Master", "biosFiles": [ { "md5": "", "file": "bios/gmaster.zip" }, + { "md5": "6bff08b5e5f96de405cd56d5f04a08f8", "zippedFile": "d78c11agf_e19.u1", "file": "bios/gmaster.zip"}, ] }, + + # ---------- Coleco Adam ---------- # + "adam": { "name": "Coleco Adam", "biosFiles": [ { "md5": "", "file": "bios/adam.zip" }, + { "md5": "01bba3bcd46d8a586dd6ec555accc133", "zippedFile": "alf @1 rev 57 e3d5.u8", "file": "bios/adam.zip"}, + { "md5": "feabe33e8f2dab88da1458b4d27f3faa", "zippedFile": "alf @2 rev 57 ae6a.u20", "file": "bios/adam.zip"}, + { "md5": "a720bc872a772ed471fac14e36ec8bcb", "zippedFile": "alf @3 rev 57 8534.u21", "file": "bios/adam.zip"}, + { "md5": "cf10b154f2e006a9740d7653cfc47cab", "zippedFile": "eos 6 rev 57 08dd.u22", "file": "bios/adam.zip"}, + { "md5": "7916bb9635d502366326ec39aea5fc89", "zippedFile": "master rev a 174b.u6", "file": "bios/adam.zip"}, + { "md5": "2c66f5911e5b42b8ebe113403548eee7", "zippedFile": "os7.u2", "file": "bios/adam.zip"}, + { "md5": "4fe4f6800076ea3d897d4285653447bd", "zippedFile": "wp_r80.rom", "file": "bios/adam.zip"}, + { "md5": "", "file": "bios/adam_ddp.zip" }, + { "md5": "0423e9e9bf5036aa1e9d656b6a1f842c", "zippedFile": "tape rev a 8865.u24", "file": "bios/adam_ddp.zip"}, + { "md5": "", "file": "bios/adam_fdc.zip" }, + { "md5": "ae12d0b83832b059cb6cb43029bbfdb3", "zippedFile": "1440k micro innovations hd-dd.u10", "file": "bios/adam_fdc.zip"}, + { "md5": "4c38a7df1e645c8d9f417bf7165c46d0", "zippedFile": "320ta.u10", "file": "bios/adam_fdc.zip"}, + { "md5": "afea14c826f3cfbc89b76725a4a41951", "zippedFile": "a720dipi 7607 mmsg =c= 1988.u10", "file": "bios/adam_fdc.zip"}, + { "md5": "976d2a7d85319d9104bc9ec176fbfa9c", "zippedFile": "adam disk u10 ad 31 rev a 09-27-84.u10", "file": "bios/adam_fdc.zip"}, + { "md5": "29569dc029e95e48907b3c81d636987f", "zippedFile": "dbl2-4.u10", "file": "bios/adam_fdc.zip"}, + { "md5": "a121855c20a638429bbfcf0448349515", "zippedFile": "doug.u10", "file": "bios/adam_fdc.zip"}, + { "md5": "e05ababa16e2d5cb92b678cb6e6e2004", "zippedFile": "fastpack 720a,t.u10", "file": "bios/adam_fdc.zip"}, + { "md5": "a1a2a353dea4b8769a2da733822abfdc", "zippedFile": "pmhdfdc.u10", "file": "bios/adam_fdc.zip"}, + { "md5": "", "file": "bios/adam_kb.zip" }, + { "md5": "d81e0b2bb6b98999541c5f40b489e88f", "zippedFile": "keyboard.u2", "file": "bios/adam_kb.zip"}, + { "md5": "", "file": "bios/adam_prn.zip" }, + { "md5": "3cdf2fe48ac4224b56f26c03f6c68982", "zippedFile": "printer.u2", "file": "bios/adam_prn.zip"}, ] }, + + # ---------- BBC Micro ---------- # + "bbc": { "name": "BBC Micro", "biosFiles": [ { "md5": "", "file": "bios/bbcb.zip" }, + { "md5": "521a197d3623682825f1042c1350feb4", "zippedFile": "basic1.rom", "file": "bios/bbcb.zip"}, + { "md5": "2cc67be4624df4dc66617742571a8e3d", "zippedFile": "basic2.rom", "file": "bios/bbcb.zip"}, + { "md5": "0cad3d0cf0d111aca2b158b9b605913f", "zippedFile": "os01.rom", "file": "bios/bbcb.zip"}, + { "md5": "46f920a170e88bab7faa96cf80b84324", "zippedFile": "os092.rom", "file": "bios/bbcb.zip"}, + { "md5": "0199bac73f1dbca291582834a3e61122", "zippedFile": "os10.rom", "file": "bios/bbcb.zip"}, + { "md5": "0a59a5ba15fe8557b5f7fee32bbd393a", "zippedFile": "os12.rom", "file": "bios/bbcb.zip"}, + { "md5": "35e9ab10bcf016bd24b4c716add009b9", "zippedFile": "phroma.bin", "file": "bios/bbcb.zip"}, + { "md5": "", "file": "bios/bbc_acorn8271.zip" }, + { "md5": "803530149c274994fabc6d28cbe03679", "zippedFile": "dfs090.rom", "file": "bios/bbc_acorn8271.zip"}, + { "md5": "5a3ddfae96178e025f27bf1f69bfa629", "zippedFile": "dfs098.rom", "file": "bios/bbc_acorn8271.zip"}, + { "md5": "d636ffb7a80fc29b133d32e4250fbab6", "zippedFile": "dnfs100.rom", "file": "bios/bbc_acorn8271.zip"}, + { "md5": "5daed103918277e2065dd7e8d23e57a5", "zippedFile": "dnfs120.rom", "file": "bios/bbc_acorn8271.zip"}, + { "md5": "79b31feacab0b1ccddf358be5dfb6241", "zippedFile": "wedfs130.rom", "file": "bios/bbc_acorn8271.zip"}, + { "md5": "24458ace9566a01d255bca16b46a960d", "zippedFile": "wedfs141.rom", "file": "bios/bbc_acorn8271.zip"}, + { "md5": "6e9356d0a5e7fbabb386824ec370d6f3", "zippedFile": "wedfs142.rom", "file": "bios/bbc_acorn8271.zip"}, + { "md5": "990b8a9755af25452c85f23ceb344be4", "zippedFile": "wedfs143.rom", "file": "bios/bbc_acorn8271.zip"}, + { "md5": "1d250b0242e447e9106e8bfd1f27ea84", "zippedFile": "wedfs144.rom", "file": "bios/bbc_acorn8271.zip"}, + { "md5": "", "file": "bios/saa5050.zip" }, + { "md5": "8b3c10a2317808ed94d6c6073b5b3327", "zippedFile": "saa5050", "file": "bios/saa5050.zip"}, + { "md5": "", "file": "bios/bbc_tube_80186.zip" }, + { "md5": "33d097349f12526584fcac21eccf3012", "zippedFile": "m512_hi_ic32.rom", "file": "bios/bbc_tube_80186.zip"}, + { "md5": "e6e84221c29b5d31d07055039583c8e7", "zippedFile": "m512_lo_ic31.rom", "file": "bios/bbc_tube_80186.zip"}, + { "md5": "", "file": "bios/bbcm.zip" }, + { "md5": "b159012f9f301bab33316fd3bf55db79", "zippedFile": "mos320.cmos", "file": "bios/bbcm.zip"}, + { "md5": "fed079c5e2c595b354529a8ea703b5fb", "zippedFile": "mos320.ic24", "file": "bios/bbcm.zip"}, + { "md5": "ca0527f13f83bc95ef4b6833ee440afa", "zippedFile": "mos329.ic24", "file": "bios/bbcm.zip"}, + { "md5": "ee9fc46252b7d7fe341b9c7f92575099", "zippedFile": "mos350.cmos", "file": "bios/bbcm.zip"}, + { "md5": "3f3dd4614db30f6e383794731272076a", "zippedFile": "mos350.ic24", "file": "bios/bbcm.zip"}, + { "md5": "", "file": "bios/bbcmc.zip" }, + { "md5": "55586a88477505d8fd28edfae646e2e3", "zippedFile": "mos500.ic49", "file": "bios/bbcmc.zip"}, + { "md5": "956bf71da840943050836ade2474ef7b", "zippedFile": "mos510.ic49", "file": "bios/bbcmc.zip"}, + { "md5": "", "file": "bios/bbc_bitstik1.zip" }, + { "md5": "baf5cb5564ff6e6b4400243e7612f323", "zippedFile": "bitstik1.rom", "file": "bios/bbc_bitstik1.zip"}, + { "md5": "", "file": "bios/bbc_bitstik2.zip" }, + { "md5": "c196c145b3de630f85f625ca762e5504", "zippedFile": "bitstik2.rom", "file": "bios/bbc_bitstik2.zip"}, + { "md5": "", "file": "bios/mame/samples/bbc.zip" }, + { "md5": "", "zippedFile": "motoroff.wav", "file": "bios/mame/samples/bbc.zip"}, + { "md5": "", "zippedFile": "motoron.wav", "file": "bios/mame/samples/bbc.zip"} ] }, + + # ---------- APF M-1000 ---------- # + "apfm1000": { "name": "APF M-1000", "biosFiles": [ { "md5": "", "file": "bios/apfm1000.zip" }, + { "md5": "1f4a976350202ee1e32c2b0477c3fc1b", "zippedFile": "apf_4000.rom", "file": "bios/apfm1000.zip"}, + { "md5": "b325543b36d37edf3fc20761f00c7a37", "zippedFile": "mod_bios.bin", "file": "bios/apfm1000.zip"}, + { "md5": "89a7cfa5469ce24773721d65b28f8544", "zippedFile": "trash-ii.bin", "file": "bios/apfm1000.zip"} ] }, + + # ---------- Fujitsu FM-7 ---------- # + "fm7": { "name": "Fujitsu FM-7", "biosFiles": [ { "md5": "", "file": "bios/fm7.zip" }, + { "md5": "9f9b7d5615ecdbde2cd26e9306ffef13", "zippedFile": "boot_bas.rom", "file": "bios/fm7.zip"}, + { "md5": "18a461ccaf7ef4e8ecad58cecd3a24b3", "zippedFile": "boot_dos_a.rom", "file": "bios/fm7.zip"}, + { "md5": "6a5da0404b7ee338df9002cdcabc3068", "zippedFile": "fbasic300.rom", "file": "bios/fm7.zip"}, + { "md5": "a330817f8f7ced752a7bcc8dfba8fd2e", "zippedFile": "kanji.rom", "file": "bios/fm7.zip"}, + { "md5": "d19ed5923aaae2ec43dffe7a0daa80cb", "zippedFile": "subsys_c.rom", "file": "bios/fm7.zip"}, + { "md5": "", "file": "bios/fm77av.zip" }, + { "md5": "71c96a45b78e88a39cb94c1aabd23d8a", "zippedFile": "fbasic30.rom", "file": "bios/fm77av.zip"}, + { "md5": "e0f4c0ebee60aee83e863826e59ae1de", "zippedFile": "initiate.rom", "file": "bios/fm77av.zip"}, + { "md5": "ae945a6dfb642b0a5d0529737e8ee5cd", "zippedFile": "subsys_a.rom", "file": "bios/fm77av.zip"}, + { "md5": "fb83a1a9725c8432acef0c3ce89492e3", "zippedFile": "subsys_b.rom", "file": "bios/fm77av.zip"}, + { "md5": "7db27dede3e358017d518101850bccfa", "zippedFile": "subsyscg.rom", "file": "bios/fm77av.zip"} ] }, + + # ---------- Acorn Archimedes ---------- # + "archimedes": { "name": "Acorn Archimedes", "biosFiles": [ { "md5": "", "file": "bios/aa310.zip" }, + { "md5": "374e4bcaa04cb98aad3b64a1555c3930", "zippedFile": "0270,251-01.rom", "file": "bios/aa310.zip"}, + { "md5": "b0b6a83029b6f85bb044bfc46bf3f0f6", "zippedFile": "0270,252-01.rom", "file": "bios/aa310.zip"}, + { "md5": "bf35bb799aa0278b7ee7719dd32f26bc", "zippedFile": "0270,253-01.rom", "file": "bios/aa310.zip"}, + { "md5": "e41af081535aae930d68ee4cbd672513", "zippedFile": "0270,254-01.rom", "file": "bios/aa310.zip"}, + { "md5": "7ecdccd760557ab0711edb37773faeb6", "zippedFile": "0270,601-01.rom", "file": "bios/aa310.zip"}, + { "md5": "c43bad04862ea03146ff5bf7441a1a24", "zippedFile": "0270,602-01.rom", "file": "bios/aa310.zip"}, + { "md5": "454c1977ad70a206f4f3a0bdca294d85", "zippedFile": "0270,603-01.rom", "file": "bios/aa310.zip"}, + { "md5": "6850da7a70b198eaf6fde5be503fa5cd", "zippedFile": "0270,604-01.rom", "file": "bios/aa310.zip"}, + { "md5": "84d305e248dab48a3a110af161dfb005", "zippedFile": "0276,146-01.rom", "file": "bios/aa310.zip"}, + { "md5": "64d7f085e6afb149ebc2e7f919429a19", "zippedFile": "0276,147-01.rom", "file": "bios/aa310.zip"}, + { "md5": "f7d0a9a4d1dae8eee057aa626b87715f", "zippedFile": "0276,148-01.rom", "file": "bios/aa310.zip"}, + { "md5": "763b015d85c7d9d17e06d5babc0a9d32", "zippedFile": "0276,149-01.rom", "file": "bios/aa310.zip"}, + { "md5": "b8fcd63c6a28d0c7034af2e6c5aff9a8", "zippedFile": "0276,322-01.rom", "file": "bios/aa310.zip"}, + { "md5": "6265551c5d6336f7ddd9f3fc78ceba93", "zippedFile": "0276,323-01.rom", "file": "bios/aa310.zip"}, + { "md5": "ca4379aeab4f7c7640c8ad34b27a9db6", "zippedFile": "0276,324-01.rom", "file": "bios/aa310.zip"}, + { "md5": "358d3c9d2685c076f6a141c26d45520c", "zippedFile": "0276,325-01.rom", "file": "bios/aa310.zip"}, + { "md5": "4ae429fbf23f8aa64ce2002cfb14c527", "zippedFile": "0277,022-02.rom", "file": "bios/aa310.zip"}, + { "md5": "83d0f0738468fdf9f23c13eef22dbeea", "zippedFile": "0277,023-02.rom", "file": "bios/aa310.zip"}, + { "md5": "636e4072c392916d2bf00865fee40984", "zippedFile": "0277,024-02.rom", "file": "bios/aa310.zip"}, + { "md5": "252b1993fdb66cac522a0edbeffc3407", "zippedFile": "0277,025-02.rom", "file": "bios/aa310.zip"}, + { "md5": "591f3bdd0f20a0a3d03c8748f2f75754", "zippedFile": "0283,022-01.rom", "file": "bios/aa310.zip"}, + { "md5": "f77f4a409c78c8495fc3876cd4e7d97c", "zippedFile": "0283,023-01.rom", "file": "bios/aa310.zip"}, + { "md5": "57d3a349407916f55129d6c8c0f56395", "zippedFile": "0283,024-01.rom", "file": "bios/aa310.zip"}, + { "md5": "ee4aa1ea0eebf88c5f6cae6315ed11a1", "zippedFile": "0283,025-01.rom", "file": "bios/aa310.zip"}, + { "md5": "a057124502e533ccd8865dc970cf7017", "zippedFile": "0296,041-01.rom", "file": "bios/aa310.zip"}, + { "md5": "3c40d2821595a7334a46ea3b46a5421d", "zippedFile": "0296,041-02.rom", "file": "bios/aa310.zip"}, + { "md5": "d1d51b8f603bba476d1f63bc5980040e", "zippedFile": "0296,042-01.rom", "file": "bios/aa310.zip"}, + { "md5": "7b096a93cc5ada80bcfb5249bca33768", "zippedFile": "0296,042-02.rom", "file": "bios/aa310.zip"}, + { "md5": "744e80abe4c6a845412f63a0f0b14e48", "zippedFile": "0296,043-01.rom", "file": "bios/aa310.zip"}, + { "md5": "9dac78cba6034c427d00f78fa94ab63d", "zippedFile": "0296,043-02.rom", "file": "bios/aa310.zip"}, + { "md5": "4c0b2e1fb29c8acd84e94d25c953173c", "zippedFile": "0296,044-01.rom", "file": "bios/aa310.zip"}, + { "md5": "f6bf5f8908a19a9aacf733633b1cd5cf", "zippedFile": "0296,044-02.rom", "file": "bios/aa310.zip"}, + { "md5": "eec46f5bd4cdb456b760b3cddf16a33c", "zippedFile": "0296,241-01.rom", "file": "bios/aa310.zip"}, + { "md5": "980e3be0c851a59d0f4602f4a94b2eef", "zippedFile": "0296,242-01.rom", "file": "bios/aa310.zip"}, + { "md5": "971a49d5c2dbb3fc01c17d1d5615781a", "zippedFile": "0296,243-01.rom", "file": "bios/aa310.zip"}, + { "md5": "9ce06a4d2a8331bc5b7fadb967d74f4f", "zippedFile": "0296,244-01.rom", "file": "bios/aa310.zip"}, + { "md5": "c74763f720c98e16dc3c6c421db21485", "zippedFile": "cmos_arthur.bin", "file": "bios/aa310.zip"}, + { "md5": "6f564c8917f04594bda7385f6de61061", "zippedFile": "cmos_riscos2.bin", "file": "bios/aa310.zip"}, + { "md5": "232a302efe19278d9df6ecbc8ea3dc6c", "zippedFile": "cmos_riscos3.bin", "file": "bios/aa310.zip"}, + { "md5": "", "file": "bios/archimedes_keyboard.zip" }, + { "md5": "1a8617c1abe3e0729d20ce844e1e12a8", "zippedFile": "acorn_0280,022-01_philips_8051ah-2.bin", "file": "bios/archimedes_keyboard.zip"} ] }, + + # ---------- Acorn Atom ---------- # + "atom": { "name": "Acorn Atom", "biosFiles": [ { "md5": "", "file": "bios/atom.zip" }, + { "md5": "b7b7f8a608339fa39d44a3bcfa2cc3f0", "zippedFile": "abasic.ic20", "file": "bios/atom.zip"}, + { "md5": "baa26f458acf5745388177ffc7368124", "zippedFile": "afloat.ic21", "file": "bios/atom.zip"}, + { "md5": "9627dfb5f8302db8dd5702dbf7c09f72", "zippedFile": "dosrom.u15", "file": "bios/atom.zip"} ] }, + + # ---------- Acorn Electron ---------- # + "electron": { "name": "Acorn Electron", "biosFiles": [ { "md5": "", "file": "bios/electron.zip" }, + { "md5": "4688a93aa298b9431c1788c9b90378c8", "zippedFile": "os_basic.ic2", "file": "bios/electron.zip"}, + { "md5": "", "file": "bios/electron64.zip" }, + { "md5": "2cc67be4624df4dc66617742571a8e3d", "zippedFile": "basic.rom", "file": "bios/electron64.zip"}, + { "md5": "df01cfe5894276de96bbd1c45b7e834c", "zippedFile": "os_300.rom", "file": "bios/electron64.zip"}, + { "md5": "", "file": "bios/electron_plus1.zip" }, + { "md5": "f3a39227b401a2ce8cdc7e4b7a860aaf", "zippedFile": "plus1.rom", "file": "bios/electron_plus1.zip"}, + { "md5": "", "file": "bios/electron_plus3.zip" }, + { "md5": "9aa334b4e8f6d7565e6323e0f77110de", "zippedFile": "acp_dfs1770_200.rom", "file": "bios/electron_plus3.zip"}, + { "md5": "83e15ca501899b0d5b2ce3f5ef696069", "zippedFile": "acp_dfs1770_210.rom", "file": "bios/electron_plus3.zip"}, + { "md5": "b60ee811f4b805638478acd5297b16e0", "zippedFile": "adfs.rom", "file": "bios/electron_plus3.zip"}, + { "md5": "62f5e1d3dae3a68d8fe4406a6f603dc3", "zippedFile": "pres_adfs_113.rom", "file": "bios/electron_plus3.zip"}, + { "md5": "5c39baa89fe8a40a5167a53cc5ae7791", "zippedFile": "pres_adfs_115.rom", "file": "bios/electron_plus3.zip"} ] }, + + # ---------- Apple ][ ---------- # + "apple2": { "name": "Apple II", "emulator": "libretro", "core": "mame", "biosFiles": [ { "md5": "", "file": "bios/apple2e.zip" }, + { "md5": "4431aea380185e3f509285540d7cb418", "zippedFile": "342-0132-c.e12", "file": "bios/apple2e.zip"}, + { "md5": "e6d453d8738e6df4f73df8c8051df3e8", "zippedFile": "342-0133-a.chr", "file": "bios/apple2e.zip"}, + { "md5": "72924019cf1719765e4fde35e59c1c7d", "zippedFile": "342-0134-a.64", "file": "bios/apple2e.zip"}, + { "md5": "0b150f4bfa090770a866cc5d214703f4", "zippedFile": "342-0135-b.64", "file": "bios/apple2e.zip"}, + { "md5": "", "file": "bios/apple2ee.zip" }, + { "md5": "b956c537e7b6b85ffa5c3493b1490d8a", "zippedFile": "341-0132-d.e12", "file": "bios/apple2ee.zip"}, + { "md5": "9123fff3442c0e688cc6816be88dd4ab", "zippedFile": "342-0265-a.chr", "file": "bios/apple2ee.zip"}, + { "md5": "6ac9338f6972eea01604f90d9a581f18", "zippedFile": "342-0303-a.e8", "file": "bios/apple2ee.zip"}, + { "md5": "6b11018a14668a7e3904319d2097dddc", "zippedFile": "342-0304-a.e10", "file": "bios/apple2ee.zip"}, + { "md5": "", "file": "bios/apple2p.zip" }, + { "md5": "89ca5cd551ffad9a557652a97dcb6627", "zippedFile": "341-0011.d0", "file": "bios/apple2p.zip"}, + { "md5": "42333f24cd6e70696b212b042f3166aa", "zippedFile": "341-0012.d8", "file": "bios/apple2p.zip"}, + { "md5": "5de50bebc41e59ae4eb27be4c24b6814", "zippedFile": "341-0013.e0", "file": "bios/apple2p.zip"}, + { "md5": "56d9bb6730735a3b2bbcc75d1da7a8de", "zippedFile": "341-0014.e8", "file": "bios/apple2p.zip"}, + { "md5": "cb63c41c5e72b5fda54feb5490efdefb", "zippedFile": "341-0015.f0", "file": "bios/apple2p.zip"}, + { "md5": "8925b695ae0177dd3919dbea2f2f202b", "zippedFile": "341-0020-00.f8", "file": "bios/apple2p.zip"}, + { "md5": "9ac0dc8c4d0002eb45b0b84be0bde5ec", "zippedFile": "341-0036.chr", "file": "bios/apple2p.zip"}, + { "md5": "", "file": "bios/a2diskiing.zip" }, + { "md5": "2020aa1413ff77fe29353f3ee72dc295", "zippedFile": "341-0027-a.p5", "file": "bios/a2diskiing.zip"}, + { "md5": "", "file": "bios/a2cffa02.zip" }, + { "md5": "80adbc2d79f347ec63f4b771ea32984d", "zippedFile": "cffa20ee02.bin", "file": "bios/a2cffa02.zip"}, + { "md5": "", "file": "bios/votrsc01.zip" }, + { "md5": "8ccf35a06f5e9a2131b0f42380ee5c15", "zippedFile": "sc01.bin", "file": "bios/votrsc01.zip"}, + { "md5": "", "file": "bios/votrsc01a.zip" }, + { "md5": "95b91e4a2fe7d6f13d353ba1827d37f9", "zippedFile": "sc01a.bin", "file": "bios/votrsc01a.zip"}, + { "md5": "", "file": "bios/d2fdc.zip" }, + { "md5": "5f1be0c1cdff26f5956eef9643911886", "zippedFile": "341-0028-a.rom", "file": "bios/d2fdc.zip"} ] }, + + # ---------- Apple IIgs ---------- # + "apple2gs": { "name": "Apple IIgs", "biosFiles": [ { "md5": "", "file": "bios/apple2gs.zip" }, + { "md5": "b956c537e7b6b85ffa5c3493b1490d8a", "zippedFile": "341-0132-d.e12", "file": "bios/apple2gs.zip"}, + { "md5": "b9f94f5d1be27dafcb8fe619ca3f4d15", "zippedFile": "341-0728", "file": "bios/apple2gs.zip"}, + { "md5": "e8e632aa592a61ef373b38af10ed54e1", "zippedFile": "341-0748", "file": "bios/apple2gs.zip"}, + { "md5": "c9e0e059faec0393fc429131a3af4ee9", "zippedFile": "341s0632-2.bin", "file": "bios/apple2gs.zip"}, + { "md5": "68ff96a624237d233e8d4c701f660dd1", "zippedFile": "apple2gs.chr", "file": "bios/apple2gs.zip"} ] }, + + # ---------- Camputers Lynx ---------- # + "camplynx": { "name": "Camputers Lynx", "biosFiles": [ { "md5": "", "file": "bios/lynx48k.zip" }, + { "md5": "b0ad5bf3070aea27b637e1998c81fa8c", "zippedFile": "lynx48-1.ic46", "file": "bios/lynx48k.zip"}, + { "md5": "b665e10211bbdbfaf2defb32d5580892", "zippedFile": "lynx48-2.ic45", "file": "bios/lynx48k.zip"}, + { "md5": "bc0760d8bf61c9683270266d259cd2ae", "zippedFile": "lynx4811.ic46", "file": "bios/lynx48k.zip"}, + { "md5": "dde90a794e5324002a9fd7f79cec3172", "zippedFile": "lynx4812.ic45", "file": "bios/lynx48k.zip"}, + { "md5": "", "file": "bios/lynx96k.zip" }, + { "md5": "a0a8f136f69b5891d33993627a185697", "zippedFile": "danish96k3.ic44", "file": "bios/lynx96k.zip"}, + { "md5": "fcb706b3ba2ba61f6f7af1c28f420f94", "zippedFile": "dosrom.rom", "file": "bios/lynx96k.zip"}, + { "md5": "815afa653b61cbe70936b01aff700912", "zippedFile": "lynx9644.ic44", "file": "bios/lynx96k.zip"}, + { "md5": "3ccdb9dfe6018892383fcbb1a9167d76", "zippedFile": "lynx9645.ic45", "file": "bios/lynx96k.zip"}, + { "md5": "01a9770efdab17f089bbbbe53f5d69fa", "zippedFile": "lynx9646.ic46", "file": "bios/lynx96k.zip"}, + { "md5": "89ba52f683cd79638646874e965476b6", "zippedFile": "skorprom.ic44", "file": "bios/lynx96k.zip"}, + { "md5": "", "file": "bios/lynx128k.zip" }, + { "md5": "fcb706b3ba2ba61f6f7af1c28f420f94", "zippedFile": "dosrom.rom", "file": "bios/lynx128k.zip"}, + { "md5": "5017fe3a2ea47038ae61e2aeb4f43d65", "zippedFile": "lynx128-1.ic1", "file": "bios/lynx128k.zip"}, + { "md5": "bf69d9538192f65571dbed43dc4a99bb", "zippedFile": "lynx128-2.ic2", "file": "bios/lynx128k.zip"}, + { "md5": "f9f54913cdedb22bb8f0c549ad121379", "zippedFile": "lynx128-3.ic3", "file": "bios/lynx128k.zip"} ] }, + + # ---------- Video Game Music Player ---------- # + "vgmplay": { "name": "Video Game Music Player", "biosFiles": [ { "md5": "", "file": "bios/qsound.zip" }, + { "md5": "108b113a596e800a02fece73f784eeb0", "zippedFile": "dl-1425.bin", "file": "bios/qsound.zip"}, + { "md5": "", "file": "bios/ym2413.zip" }, + { "md5": "96c11a92992bdff7f7e9d98a52621e1f", "zippedFile": "ym2413_instruments.bin", "file": "bios/ym2413.zip"}, + { "md5": "", "file": "bios/ym2608.zip" }, + { "md5": "8740932cda05e518a9955f1d08d6786f", "zippedFile": "ym2608_adpcm_rom.bin", "file": "bios/ym2608.zip"} ] }, + + # ---------- Epoch Game Pocket Computer ---------- # + "gamepock": { "name": "Epoch Game Pocket Computer", "biosFiles": [ { "md5": "", "file": "bios/gamepock.zip" }, + { "md5": "a0dd595eafb407a6a4b4ed800005a394", "zippedFile": "egpcboot.bin", "file": "bios/gamepock.zip"} ] }, + + # ---------- Tiger Game.com ---------- # + "gamecom": { "name": "Tiger Game.com", "biosFiles": [ { "md5": "", "file": "bios/gamecom.zip" }, + { "md5": "813364d4863b1d7b7b8fd6a97a416bcf", "zippedFile": "external.bin", "file": "bios/gamecom.zip"}, + { "md5": "f7bcefb6daf923c8e5ea2eb69f619efe", "zippedFile": "internal.bin", "file": "bios/gamecom.zip"} ] }, + + # ---------- Atari XEGS ---------- # + "xegs": { "name": "Atari XE Game System", "biosFiles": [ { "md5": "", "file": "bios/xegs.zip" }, + { "md5": "42cbd989802c17d0ac3731d33270d835", "zippedFile": "c101687.rom", "file": "bios/xegs.zip"} ] }, + + # ---------- VTech CreatiVision ---------- # + "crvision": { "name": "VTech CreatiVision", "biosFiles": [ { "md5": "", "file": "bios/crvision.zip" }, + { "md5": "3b1ef759d8e3fb4071582efd33dd05f9", "zippedFile": "crvision.u20", "file": "bios/crvision.zip"} ] }, + + # ---------- VTech V.Smile ---------- # + "vsmile": { "name": "VTech V.Smile", "biosFiles": [ { "md5": "", "file": "bios/vsmile.zip" }, + { "md5": "851ff77a89ec3f4f2793eb4aede30e5f", "zippedFile": "vsmile_v100.bin", "file": "bios/vsmile.zip"}, + { "md5": "f41fcc19ebe1e90fa359cd0df6293fab", "zippedFile": "vsmile_v102.bin", "file": "bios/vsmile.zip"}, + { "md5": "11e59253c578c8f16ea2375ec398e4e9", "zippedFile": "vsmile_v103.bin", "file": "bios/vsmile.zip"} ] }, + + # ---------- VTech Socrates ---------- # + "socrates": { "name": "VTech Socrates", "biosFiles": [ { "md5": "", "file": "bios/socrates.zip" }, + { "md5": "0efac0c2cc168c0d495e1c4e04ea9f5a", "zippedFile": "27-00817-000-000.u1", "file": "bios/socrates.zip"}, + { "md5": "99af124aa300ecd44f5dc9d5a2599778", "zippedFile": "speech_eng_internal.bin", "file": "bios/socrates.zip"}, + { "md5": "7046c2b27f51c9a5d33b4d6103f29acf", "zippedFile": "speech_eng_vsm1.bin", "file": "bios/socrates.zip"}, + { "md5": "6878302c362321eeee7e40d285cf7d30", "zippedFile": "speech_eng_vsm2.bin", "file": "bios/socrates.zip"}, + { "md5": "31c29c57e3d3e6788ba5817eaaa8b17a", "zippedFile": "speech_eng_vsm3.bin", "file": "bios/socrates.zip"} ] }, + + # ---------- Entex Aventure Vision ---------- # + "advision": { "name": "Entex Adventure Vision", "biosFiles": [ { "md5": "", "file": "bios/advision.zip" }, + { "md5": "5729638bd856c475678467a353bd921c", "zippedFile": "b225__ins8048-11kdp_n.u5", "file": "bios/advision.zip"}, + { "md5": "fc5e71445e4947a9d00eedbc66b13a8f", "zippedFile": "b8223__cop411l-kcn_n.u8", "file": "bios/advision.zip"} ] }, + + # ---------- Bitcorp Gamate ---------- # + "gamate": { "name": "Bitcorp Gamate", "biosFiles": [ { "md5": "", "file": "bios/gamate.zip" }, + { "md5": "b411167df6dd563111729296f4c547f6", "zippedFile": "gamate_bios_bit.bin", "file": "bios/gamate.zip"}, + { "md5": "ef67993a94503c4b7798b5901c7dda52", "zippedFile": "gamate_bios_umc.bin", "file": "bios/gamate.zip"} ] }, + + # ---------- Phillips CD-i ---------- # + "cdi": { "name": "Phillips CD-i", "biosFiles": [ { "md5": "", "file": "bios/cdimono1.zip" }, + { "md5": "2969341396aa61e0143dc2351aaa6ef6", "zippedFile": "cdi200.rom", "file": "bios/cdimono1.zip"}, + { "md5": "ac80a92c988ce07fbd6a8f21ded34cf1", "zippedFile": "cdi220.rom", "file": "bios/cdimono1.zip"}, + { "md5": "ac0d468be366779c9df633be98da250a", "zippedFile": "cdi220b.rom", "file": "bios/cdimono1.zip"}, + { "md5": "3e59b8a9a423d3ecd612a32fe4e2d748", "zippedFile": "zx405037p__cdi_servo_2.1__b43t__llek9215.mc68hc705c8a_withtestrom.7201", "file": "bios/cdimono1.zip"}, + { "md5": "3d20cf7550f1b723158b42a1fd5bac62", "zippedFile": "zx405042p__cdi_slave_2.0__b43t__zzmk9213.mc68hc705c8a_withtestrom.7206", "file": "bios/cdimono1.zip"} ] }, + + # ---------- Naomi 2 ---------- # + "naomi2": { "name": "Naomi 2", "biosFiles": [ { "md5": "", "file": "bios/dc/naomi2.zip" }, + { "md5": "728bfe038ce280872057e365ebfc0fee", "zippedFile": "315-6146.bin", "file": "bios/dc/naomi2.zip"}, + { "md5": "baf83367044924067e09856ba164aa6f", "zippedFile": "315-6215.bin", "file": "bios/dc/naomi2.zip"}, + { "md5": "6f8ad6e3ab04c8ae1cbcaa652b91cf4e", "zippedFile": "epr-23605.ic27", "file": "bios/dc/naomi2.zip"}, + { "md5": "f3f39513484df216d9979f6ae7577942", "zippedFile": "epr-23605a.ic27", "file": "bios/dc/naomi2.zip"}, + { "md5": "ab046e62c51d67fb89eade2b8d5f6a8d", "zippedFile": "epr-23605b.ic27", "file": "bios/dc/naomi2.zip"}, + { "md5": "096a5217ff6e6c6cafe65a03336760ab", "zippedFile": "epr-23605c.ic27", "file": "bios/dc/naomi2.zip"}, + { "md5": "659d579ba9aef5b025d87323044e83f4", "zippedFile": "epr-23605c_multi.ic27", "file": "bios/dc/naomi2.zip"}, + { "md5": "cbe0984d03d73869c23da5a3dd2ce207", "zippedFile": "epr-23607.ic27", "file": "bios/dc/naomi2.zip"}, + { "md5": "b624ec7b3b90fdf3be103cdfb1679d1d", "zippedFile": "epr-23607b.ic27", "file": "bios/dc/naomi2.zip"}, + { "md5": "a9d82db14b823a5a57885bea1a998eb7", "zippedFile": "epr-23607c.ic27", "file": "bios/dc/naomi2.zip"}, + { "md5": "3b1315be24dc8d17f4fa18f3bfc5fe5c", "zippedFile": "epr-23608.ic27", "file": "bios/dc/naomi2.zip"}, + { "md5": "0143cf852cb2a8a41f217bc688f62105", "zippedFile": "epr-23608a.ic27", "file": "bios/dc/naomi2.zip"}, + { "md5": "8b88c1f5a06e9b560e887c3b9f879237", "zippedFile": "epr-23608b.ic27", "file": "bios/dc/naomi2.zip"}, + { "md5": "b49702e4fadb3b5f9143a3d20afd04b5", "zippedFile": "epr-23608c.ic27", "file": "bios/dc/naomi2.zip"}, + { "md5": "ecadb008179ca1e6f4fe3fa091ab5df2", "zippedFile": "epr-23609b.ic27", "file": "bios/dc/naomi2.zip"}, + { "md5": "edeed38a9795e062a9af28c3eba22040", "zippedFile": "main_eeprom.bin", "file": "bios/dc/naomi2.zip"}, + { "md5": "14e6bffff0d4dff6a5a547e7c43680ff", "zippedFile": "sp5001.bin", "file": "bios/dc/naomi2.zip"}, + { "md5": "689d2228b00fb59781f82af6e8ecdb78", "zippedFile": "sp5001-a.bin", "file": "bios/dc/naomi2.zip"}, + { "md5": "8373a11106c1c2fc21ac839f75ea488f", "zippedFile": "sp5001-b.bin", "file": "bios/dc/naomi2.zip"}, + { "md5": "7eecfb8e8f82b47ffab92a0c5528100e", "zippedFile": "sp5002-a.bin", "file": "bios/dc/naomi2.zip"}, + { "md5": "960ece0dc22a7c5ff81c812a2993e7cc", "zippedFile": "x76f100_eeprom.bin", "file": "bios/dc/naomi2.zip"} ] }, + + # ---------- Hikaru ---------- # + "hikaru": { "name": "Hikaru", "biosFiles": [ { "md5": "aac601811a25d7b31a3d5f3f1f82f338", "file": "bios/hikaru.zip" }, + { "md5": "e95415b161121bef35ade12367138c63", "file": "bios/mie.zip"} ] }, + + # ---------- Playstation Vita ---------- # + # https://www.playstation.com/en-us/support/hardware/psvita/system-software/ + # http://dus01.psp2.update.playstation.net/update/psp2/image/2022_0209/sd_59dcf059d3328fb67be7e51f8aa33418/PSP2UPDAT.PUP?dest=us + "psvita": { "name": "PS Vita", "biosFiles": [ { "md5": "59dcf059d3328fb67be7e51f8aa33418", "file": "bios/psvita/PSP2UPDAT.PUP" }, + { "md5": "f2c7b12fe85496ec88a0391b514d6e3b", "file": "bios/psvita/PSVUPDAT.PUP"} ] }, + + # ---------- GCE Vectrex ---------- # + # Not required for libretro-vecx, the default emulator + "vectrex": { "name": "GCE Vectrex", "emulator": "libretro", "core": "mame", "biosFiles": [ { "md5": "", "file": "bios/vectrex.zip" }, + { "md5": "ab082fa8c8e632dd68589a8c7741388f", "zippedFile": "exec_rom.bin", "file": "bios/vectrex.zip"}, + { "md5": "a9c238473229912eb757ff3dfe6f4631", "zippedFile": "exec_rom_intl_284001-1.bin", "file": "bios/vectrex.zip"} ] }, + + # ---------- ScummVM ---------- # + "scummvm": { "name": "ScummVM", "biosFiles": [ { "md5": "89e42e386e82e0cacb4a2704a03706ca", "file": "bios/scummvm/extra/MT32_PCM.ROM" }, + { "md5": "5626206284b22c2734f3e9efefcd2675", "file": "bios/scummvm/extra/MT32_CONTROL.ROM" } ] }, + + # ---------- MSX1/MSX2 ---------- # + #https://github.com/openMSX/openMSX/blob/master/share/machines/Boosted_MSX2_EN.txt + "msx1": { "name": "MSX1/MS2", "biosFiles": [ { "md5": "01dd1d72ed9bb6afe8a9b441c198a1cd", "file": "bios/openmsx/nms8250_disk.rom" }, + { "md5": "ec3a01c91f24fbddcbcab0ad301bc9ef", "file": "bios/openmsx/nms8250_basic-bios2.rom" }, + { "md5": "2183c2aff17cf4297bdb496de78c2e8a", "file": "bios/openmsx/nms8250_msx2sub.rom" }, + { "md5": "6f69cc8b5ed761b03afd78000dfb0e19", "file": "bios/openmsx/fmpac.rom" }, + { "md5": "2ce20986da024e9a0e271961c6bc9f01", "file": "bios/openmsx/phc-70fd2_basickun.rom" }, + { "md5": "42af93619160ef2116416f74a6cb12f2", "file": "bios/openmsx/yrw801.rom" } ] }, + + # ---------- MSX LaserDisc ---------- # + #https://github.com/openMSX/openMSX/blob/master/share/machines/Pioneer_PX-7.xml + "msx1": { "name": "MSX LaserDisc", "biosFiles": [ { "md5": "281809cafe63437fc4bffb3033fbd0db", "file": "bios/openmsx/px-7_pbasic.rom" }, + { "md5": "9218f6dd89f7ba01e3090d44721b4260", "file": "bios/openmsx/px-7_basic-bios1.rom" } ] }, + + # ---------- MSX2+ ---------- # + #https://github.com/openMSX/openMSX/blob/master/share/machines/Boosted_MSX2+_JP.txt + "msx2+": { "name": "MSX2+", "biosFiles": [ { "md5": "acf53887c2d2783dc059a9b442c86b90", "file": "bios/openmsx/fs-a1wsx_kanjifont.rom" }, + { "md5": "c5c26c3e8bc6c485424818057f0507b9", "file": "bios/openmsx/fs-a1wsx_basic-bios2p.rom" }, + { "md5": "0c40e7db1c1fcc2405e4d0cdd215adb4", "file": "bios/openmsx/fs-a1wsx_fmbasic.rom" }, + { "md5": "7c8243c71d8f143b2531f01afa6a05dc", "file": "bios/openmsx/fs-a1wsx_msx2psub.rom" }, + { "md5": "9dfdebfaa6b547222a40aab8bb2e29f8", "file": "bios/openmsx/fs-a1wsx_kanjibasic.rom" }, + { "md5": "00aa02b6077de40a0b51d71a3c3e1d5f", "file": "bios/openmsx/fs-a1wsx_disk.rom" }, + { "md5": "fa8e7d4b999af058fe2864a5f2e014ec", "file": "bios/openmsx/fs-a1wsx_firmware.rom" }, + { "md5": "2ce20986da024e9a0e271961c6bc9f01", "file": "bios/openmsx/phc-70fd2_basickun.rom" }, + { "md5": "42af93619160ef2116416f74a6cb12f2", "file": "bios/openmsx/yrw801.rom" } ] }, + + # ---------- MSX-Turbo ---------- # + #https://github.com/openMSX/openMSX/blob/master/share/machines/Panasonic_FS-A1GT.xml + "msxturbor": { "name": "MSX-Turbo", "biosFiles": [ { "md5": "af17a344bcc177b97a4888c4c559f3ae", "file": "bios/openmsx/fs-a1gt_firmware.rom" }, + { "md5": "acf53887c2d2783dc059a9b442c86b90", "file": "bios/openmsx/fs-a1gt_kanjifont.rom" }, + { "md5": "afa4b5f2944334f84971af814a24bd5a", "file": "bios/openmsx/ide250.zip" }, + { "md5": "2ce20986da024e9a0e271961c6bc9f01", "file": "bios/openmsx/phc-70fd2_basickun.rom" }, + { "md5": "42af93619160ef2116416f74a6cb12f2", "file": "bios/openmsx/yrw801.rom" } ] }, + + # ---------- Supr'A'can ---------- # + "supracan": { "name": "Supr'A'can", "biosFiles": [ { "md5": "", "file": "bios/supracan.zip" }, + { "md5": "53c4343e062bb3b337370bbb58e64d16", "zippedFile": "internal_68k.bin", "file": "bios/supracan.zip" } ] }, + + # ---------- Tandy VIS ---------- # + "vis": { "name": "Tandy Video Information System", "biosFiles": [ { "md5": "", "file": "bios/vis.zip" }, + { "md5": "ebf432d3b09f694db1c62018eb2ab471", "zippedFile": "p513bk0b.bin", "file": "bios/vis.zip"}, + { "md5": "758f8fec271fbf526bb22b36e88f154b", "zippedFile": "p513bk1b.bin", "file": "bios/vis.zip"} ] }, + + # ---------- GameCube ---------- # + "n64dd": { "name": "Nintendo 64DD", "biosFiles": [ { "md5": "8d3d9f294b6e174bc7b1d2fd1c727530", "file": "bios/64DD_IPL.bin" } ] }, + + # ---------- GameCube ---------- # + "gamecube": { "name": "Nintendo GameCube", "biosFiles": [ { "md5": "db92574caab77a7ec99d4605fd6f2450", "file": "bios/GC/EUR/IPL.bin" }, + { "md5": "b17148254a5799684c7d783206504926", "file": "bios/GC/JAP/IPL.bin" }, + { "md5": "b17148254a5799684c7d783206504926", "file": "bios/GC/USA/IPL.bin" } ] }, + + # ---------- Sega Chihiro ---------- # + "chihiro": { "name": "Sega Chihiro", "biosFiles": [{ "md5": "d49c52a4102f6df7bcf8d0617ac475ed", "file": "bios/mcpx_1.0.bin" }, + { "md5": "f23d7e00ae8fbf88908ed1f9165f35eb", "file": "bios/cerbios.bin" }] }, +} + +class BiosStatus: + MISSING = "MISSING" + UNTESTED = "UNTESTED" + +def md5sum(filename, blocksize=65536): + hash = md5() + with open(filename, "rb") as f: + for block in iter(lambda: f.read(blocksize), b""): + hash.update(block) + return hash.hexdigest() + +def checkInsideZip(container, fileName, md5sum): + # Check inside Zip files + try: + archive = zipfile.ZipFile(container) + except Exception as e: + print ('Error opening file {}: {}.'.format(container, e)) + return False + blocksize = 1024**2 #1M chunks + for fname in archive.namelist(): + # Only check if the file matches + if fname.casefold() == fileName.casefold(): + if md5sum == "": + return True + archive = zipfile.ZipFile(container) + blocksize = 1024**2 #1M chunks + for fname in archive.namelist(): + if fname == fileName: + entry = archive.open(fname) + zippedHash = md5() + while True: + block = entry.read(blocksize) + if not block: + break + zippedHash.update(block) + if zippedHash.hexdigest() == md5sum: + return True + else: + print('Mismatch inside .zip: File {} in {} has MD5 {} (expected {})'.format(fileName, container, zippedHash.hexdigest(), md5sum)) + return False + # File was not found in zip. + print('Missing file inside .zip: File {} not found in {}'.format(fileName, container)) + return False + +def coreExists(checkMe, emuDict): + if "emulator" in checkMe: + if checkMe["emulator"] in emuDict.keys(): + hasEmu = True + else: + hasEmu = False + else: + # Emulator not defined, check BIOS + hasEmu = True + if hasEmu and "core" in checkMe: + if checkMe["core"] in emuDict[checkMe["emulator"]]: + hasCore = True + else: + hasCore = False + else: + # Either core is undefined or emulator is not installed. + # Set core presence to emulator presence, we'll assume there's only one core or it applies to all. + hasCore = hasEmu + return hasCore + +def checkBios(systems, prefix, filterROMs): + systemDict = {} + emuDict = {} + systemName = "" + configFile = "/storage/.config/emulationstation/es_systems.cfg" + configData = elementTree.parse(configFile) + configRoot = configData.getroot() + + if filterROMs: + # Load systems & emulators from es_systems.cfg + # System full name stored but not currently used, may be useful for the readme function. + for activeSystem in configRoot: + for systemTag in activeSystem: + if systemTag.tag == "fullname": + systemName = systemTag.text + elif systemTag.tag == "name": + systemDict[systemTag.text] = systemName + systemName = "" + elif systemTag.tag == "emulators": + for emulatorTag in systemTag: + emulatorName = emulatorTag.attrib['name'] + for coreTag in emulatorTag[0]: + if emulatorName in emuDict.keys(): + if not coreTag.text in emuDict[emulatorName]: + emuDict[emulatorName].append(coreTag.text) + else: + emuDict[emulatorName] = [coreTag.text] + else: + for system in systems.keys(): + systemDict[system] = systems[system]['name'] + + missingBios = {} + for system in systems.keys(): + if system in systemDict.keys(): + if coreExists(systems[system], emuDict) or filterROMs == False: + for file in systems[system]["biosFiles"]: + if coreExists(file, emuDict) or filterROMs == False: + filepath = prefix + "/" + file["file"] + if isfile(filepath): + if not "zippedFile" in file: + md5 = md5sum(filepath) + if md5 != file["md5"] and file["md5"] != "": + if system not in missingBios: + missingBios[system] = {} + missingBios[system][file["file"]] = { "status": BiosStatus.UNTESTED, "md5": file["md5"], "file": file["file"] } + else: + if 'altmd5' in file: + if not checkInsideZip(filepath, file["zippedFile"], file["md5"], file["altmd5"]): + if system not in missingBios: + missingBios[system] = {} + missingBios[system][file["file"]] = { "status": BiosStatus.UNTESTED, "md5": file["md5"], "file": file["file"] } + else: + if not checkInsideZip(filepath, file["zippedFile"], file["md5"]): + if system not in missingBios: + missingBios[system] = {} + missingBios[system][file["file"]] = { "status": BiosStatus.UNTESTED, "md5": file["md5"], "file": file["file"] } + else: + if system not in missingBios: + missingBios[system] = {} + missingBios[system][file["file"]] = { "status": BiosStatus.MISSING, "md5": file["md5"], "file": file["file"] } + return missingBios + +def displayMissingBios(systems, missingBios): + sortedMissingBios = OrderedDict(sorted(missingBios.items())) + if sortedMissingBios: + for system in sortedMissingBios: + print("> {}".format(system)) + for file in sortedMissingBios[system].keys(): + md5str = "-" + if sortedMissingBios[system][file]["md5"] != "": + md5str = sortedMissingBios[system][file]["md5"] + print("{} {} {}".format(sortedMissingBios[system][file]["status"], md5str, sortedMissingBios[system][file]["file"])) + else: + print("No missing bios") + +def createReadme(systems): + for system in sorted(systems): + print("{}:".format(systems[system]["name"])) + for bios in systems[system]["biosFiles"]: + print("{} {}".format(bios["md5"], bios["file"])) + print("") + +if __name__ == '__main__': + if len(sys.argv) == 1: + prefix = "/storage/roms" + displayMissingBios(systems, checkBios(systems, prefix, True)) + elif sys.argv[1] == "--noFilter": + prefix = "/storage/roms" + displayMissingBios(systems, checkBios(systems, prefix, False)) + elif sys.argv[1] == "--createReadme": + createReadme(systems) + elif len(sys.argv) == 3 and sys.argv[1] == "--filter": + prefix = "/storage/roms" + lowered_name = sys.argv[2].lower() + + filtered_systems = {} + for system in systems: + if lowered_name in system.lower() or lowered_name in systems[system]['name'].lower(): + filtered_systems[system] = systems[system] + + if len(filtered_systems) == 0: + print("No system named {} found".format(sys.argv[2])) + exit(1) + + displayMissingBios(filtered_systems, checkBios(filtered_systems, prefix, True)) diff --git a/projects/ArchR/packages/archr/sources/scripts/archr-update b/projects/ArchR/packages/archr/sources/scripts/archr-update new file mode 100755 index 0000000000..be03ce6cd8 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/archr-update @@ -0,0 +1,188 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile + +BRANCH="$(get_setting updates.branch)" +FORCE="$(get_setting updates.force)" + +ENDPOINT_URL="https://update.archr.org" + +MACHINEIDFILE=/storage/.cache/systemd-machine-id +USERID=$(cat ${MACHINEIDFILE}) + +# Function to check for an update. It returns a URL if an update is available. +check_update() { + custom_force="${1:-$FORCE}" + + update_url=$(curl -s -S -X POST \ + -F "OS=${OS_NAME}" \ + -F "ARCH=${HW_ARCH}" \ + -F "SOC=${HW_DEVICE}" \ + -F "VERSION=${OS_VERSION}" \ + -F "UID=${USERID:(-12)}" \ + -F "BUILD=${OS_BUILD}" \ + -F "DEV=${QUIRK_DEVICE}" \ + -F "FORCE=${custom_force}" \ + -F "BRANCH=${BRANCH}" \ + "$ENDPOINT_URL") + echo "$update_url" + return $? +} + +# Function to get list of releases +get_releases() { + releases=$(curl -s -S -X POST \ + -F "OS=${OS_NAME}" \ + -F "ARCH=${HW_ARCH}" \ + -F "SOC=${HW_DEVICE}" \ + -F "BRANCH=${BRANCH}" \ + -F "LIST=1" \ + "$ENDPOINT_URL") + echo "$releases" + return $? +} + +# Returns 0 if there is enough available free space at target_path in megabytes. +check_disk_space() { + target_path=$1 + required_mB=$2 + available_mB=$(df -m "$target_path" | awk 'NR==2 {print $4}') + if [ "$available_mB" -ge "$required_mB" ]; then + return 0 + else + return 1 + fi +} + +# Download a file from url to destination and show progress. +download_file() { + url=$1 + destination=$2 + curl --progress-bar -S -L "$url" -o "$destination" + return $? +} + +# Main update logic. +main_update() { + custom_force="${1:-$FORCE}" + update_url=$(check_update "$custom_force") + + # Check if the returned update_url looks like a URL (e.g., starts with http) + case "$update_url" in + http://*|https://*) + echo "Update available at: $update_url" ;; + *) + echo "No update available or invalid update URL." + exit 1 + ;; + esac + + # Check that there is at least 2GB of available free space on /storage. + if ! check_disk_space "/storage" "2048"; then + echo "Not enough free space on /storage (need at least 2GB)." + exit 1 + fi + + # Ensure that the /storage/.update folder exists. + if [ ! -d "/storage/.update" ]; then + mkdir -p /storage/.update || { echo "Failed to create /storage/.update directory."; exit 1; } + fi + + # Extract the file name from the update URL. + filename=$(basename "$update_url") + + # Define download destinations inside /storage/.update folder using the original file names. + update_file="/storage/.update/${filename}" + checksum_file="/storage/.update/${filename}.sha256" + + # Download the update file. + echo "Downloading update file..." + download_file "$update_url" "$update_file" + if [ $? -ne 0 ]; then + echo "Failed to download update file." + exit 1 + fi + + # Download the checksum file (append .sha256 to the update URL). + checksum_url="${update_url}.sha256" + echo "Downloading checksum file..." + download_file "$checksum_url" "$checksum_file" + if [ $? -ne 0 ]; then + echo "Failed to download checksum file." + rm -f "$update_file" + exit 1 + fi + + # Verify checksum. + echo "Verifying the downloaded update..." + expected_checksum=$(awk '{print $1}' "$checksum_file") + actual_checksum=$(sha256sum "$update_file" | awk '{print $1}') + if [ "$expected_checksum" = "$actual_checksum" ]; then + echo "Checksum verified successfully. Reboot to apply the update." + set_setting updates.force 0 + sync + else + echo "Checksum verification failed. Removing downloaded files." + rm -f "$update_file" "$checksum_file" + exit 1 + fi +} + +# Check network connectivity (ping DNS server) +if ! ping -c 1 8.8.8.8 >/dev/null 2>&1; then + echo "Network connection unavailable." + exit 1 +fi + +# Read the first argument to determine the mode. +mode=$1 + +# Check if the mode is a number (e.g., 20250101), which indicates forcing a specific version +if echo "$mode" | grep -q '^[0-9]\{8\}$'; then + # If mode is a date (8 digits), treat it as a forced version + echo "Forcing update to version $mode..." + main_update "$mode" + exit 0 +fi + +case "$mode" in + check) + update_url=$(check_update) + case "$update_url" in + http://*|https://*) + # Extract the filename from the URL. + filename=$(basename "$update_url") + # Use shell parameter expansion to remove everything up to the last dash, then remove the .tar suffix. + version=${filename##*-} + version=${version%.tar} + echo "$version" + exit 0 + ;; + *) + echo "No update available." + exit 1 + ;; + esac + ;; + releases) + # Get the list of available releases + echo "Checking available releases..." + releases=$(get_releases) + echo "$releases" + exit 0 + ;; + update|"") + # If mode is "update" or no argument is provided, proceed with the update. + main_update + ;; + *) + echo "Usage: $0 [check|update|releases|]" + echo " check - Check for available updates and print version" + echo " update - Update to the latest version" + echo " releases - Show available releases" + echo " - Force update to specific version (e.g., 20250101)" + exit 1 + ;; +esac diff --git a/projects/ArchR/packages/archr/sources/scripts/automount b/projects/ArchR/packages/archr/sources/scripts/automount new file mode 100755 index 0000000000..6cc9f3f60e --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/automount @@ -0,0 +1,243 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile +. /etc/os-release + +### Vars +UPDATE_ROOT="/storage/.update" +MOUNT_GAMES=$(get_setting system.automount) +GAMES_DEVICE=$(get_setting system.gamesdevice) +MS_PATH="/storage/roms" + +function unmount() { + log $0 "Unmount ${1}." + umount -f "${1}" 2>/dev/null ||: +} + +function start_ms() { + ### Entrypoint will be either games card found (external), or not found (internal). + MOUNT_PATH="/storage/games-${1}" + + MS_DEVICE=$(get_setting system.merged.device) + ### If the merge target isn't defined and we have an external microsd, we should use the external card by default. + if [ -z "${MS_DEVICE}" ] && \ + [ "${1}" = "external" ] + then + set_setting system.merged.device external + fi + + ### Determine if internal or external is the primary target by configuration. + case ${MS_DEVICE} in + internal) + LOWER="external" + UPPER="internal" + ;; + *) + LOWER="internal" + UPPER="external" + ;; + esac + + for GAME_PATH in internal external + do + if [ ! -d "/storage/games-${GAME_PATH}/roms" ] + then + log $0 "Create /storage/games-${GAME_PATH}/roms." + mkdir -p "/storage/games-${GAME_PATH}/roms" + fi + done + + MS_ENABLED=$(get_setting system.merged.storage) + if [ -e "/storage/.ms_unsupported" ] || \ + [ ! "${MS_ENABLED}" = 1 ] + then + log $0 "Executing bind mount of ${MOUNT_PATH} to ${MS_PATH}" + mount --bind ${MOUNT_PATH}/roms ${MS_PATH} + else + log $0 "Enabling merged storage of /storage/games-${LOWER} and /storage/games-${UPPER} to ${MS_PATH}." + + for DIR in /storage/games-${UPPER}/.tmp/games-workdir /storage/games-${LOWER}/roms /storage/games-${UPPER}/roms + do + if [ ! -d "${DIR}" ] + then + mkdir -p "${DIR}" + fi + done + mount overlay -t overlay -o lowerdir=/storage/games-${LOWER}/roms,upperdir=/storage/games-${UPPER}/roms,workdir=/storage/games-${UPPER}/.tmp/games-workdir ${MS_PATH} + fi +} + +start_overlay() { + if [ -e "/storage/.overlay_unsupported" ] + then + # If we're not using the overlay, bind mount the external storage path + # so we don't need to change any configs. + grep ${MOUNT_PATH} /proc/mounts >/dev/null 2>&1 + if [ ! $? = 0 ] + then + MOUNT_PATH="/storage/games-internal" + fi + log $0 "Executing bind mount of ${MOUNT_PATH} to ${OVERLAY_PATH}" + mount --bind ${MOUNT_PATH} ${OVERLAY_PATH} + exit 0 + else + log $0 "Enabling overlay." + systemctl enable storage-roms.mount >/dev/null 2>&1 + systemctl start storage-roms.mount >/dev/null 2>&1 + fi +} + +if [[ ! "${MOUNT_GAMES}" =~ [0-9] ]] +then + set_setting system.automount 1 +elif [[ "${MOUNT_GAMES}" == "0" ]] +then + start_ms internal + exit 0 +fi + +function create_game_dirs() { + ### We don't want systemd to manage this or the directories could be created in the wrong location. + if [ -e "/usr/config/system-dirs.conf" ] + then + log $0 "Creating game directories." + systemd-tmpfiles --create /usr/config/system-dirs.conf >/dev/null 2>&1 ||: + fi +} + +function load_modules() { + for MODULE in exfat vfat ntfs ntfs3 + do + lsmod | grep ${MODULE} >/dev/null 2>&1 + if [ ! $? = 0 ] + then + log $0 "Loading ${MODULE}." + modprobe ${MODULE} >/dev/null 2>&1 + fi + done +} + +function mount_games() { + MOUNT_PATH="/storage/games-external" + FSTYPE=$(blkid -o export ${1} | awk 'BEGIN {FS="="} /TYPE/ {print $2}') + case ${FSTYPE} in + ext4 | btrfs) + log $0 "Found supported partition for overlayfs." + if [ -e "/storage/.ms_unsupported" ] + then + rm -f /storage/.ms_unsupported + fi + touch /storage/.ms_supported + ;; + *) + log $0 "Partition does not support overlayfs, disabling." + if [ -e "/storage/.ms_supported" ] + then + rm -f /storage/.ms_supported + fi + touch /storage/.ms_unsupported + ;; + esac + + # busybox has some weird behaviour with helpers. + # Despite mount.ntfs is present, it is not used, so just a stupid rewrite to use newer kernel ntfs3 driver + case ${FSTYPE} in + ntfs) MOUNT_ARGS="-t ntfs3" ;; + *) true ;; + esac + + if [ ! -d "${MOUNT_PATH}" ] + then + log $0 "Create directory ${MOUNT_PATH}" + /usr/bin/busybox mkdir -p ${MOUNT_PATH} >/dev/null 2>&1 + fi + + NULL=$(cat /proc/mounts | grep -v -e "/var/media" 2>/dev/null | grep ${1}) + if [ ! "$?" = "0" ] && \ + [ -e "${1}" ] && \ + [ ! -e "/storage/.please_resize_me" ] + then + + ### Udevil shouldn't mount it this early, but just in-case. + umount /var/media/* 2>/dev/null + + log $0 "Mounting ${1} on ${MOUNT_PATH}" + /usr/bin/busybox mount ${MOUNT_ARGS} ${1} ${MOUNT_PATH} >/dev/null 2>&1 + + log $0 "Checking filesystem ${1}." + if ! touch "${MOUNT_PATH}/.tmp-archr"; then + log $0 "Fixing filesystem ${1}." + /usr/bin/busybox umount ${1} >/dev/null 2>&1 + /usr/sbin/fsck -Mly ${1} >/dev/null 2>&1 + /usr/bin/busybox mount ${MOUNT_ARGS} ${1} ${MOUNT_PATH} >/dev/null 2>&1 + else + rm "${MOUNT_PATH}/.tmp-archr" + fi + fi + start_ms external + create_game_dirs + exit 0 +} + +function find_games() { + if /usr/bin/busybox mountpoint -q /storage + then + for DEV in $(for dev in mmcblk[0-9] sd[a-z] nvme[0-9]n[0-9]; do blkid | grep ${dev} | awk 'BEGIN {FS=":"}; /ext4/ || /btrfs/ || /fat/ || /ntfs/ {print $1}' | sort -r; done) + do + ROOTDEV=$(echo ${DEV} | sed -e "s#^/.*/##g" -e "s#p[0-9].*\$##g") + log $0 "Inspecting ${DEV}." + SIZE=$(awk '/'${ROOTDEV}'$/ {print $3}' /proc/partitions) + if (( ${SIZE} <= 8388608 )) + then + log $0 "Device ${ROOTDEV} is too small, ignoring." + # We don't want to mount partitions smaller than ~8GB. + continue + fi + if [ -L "/sys/class/block/${ROOTDEV}boot0" ] + then + log $0 "Device ${ROOTDEV} might be Android, ignoring." + # Assume this is an android boot device and ignore it. + continue + fi + ISMOUNTED="$(grep "${DEV}" /proc/mounts) >/dev/null 2>&1" + if [ ! "$?" = 0 ] && \ + [ -e "${DEV}" ] && \ + [ ! -e "/storage/.please_resize_me" ] + then + GAMES_DEVICE=${DEV} + log $0 "Found ${DEV} available to mount." + mount_games "${DEV}" + else + log $0 "${DEV} not available." + fi + done + log $0 "Could not find external card to mount, assume internal." + + MS_DEVICE=$(get_setting system.merged.device) + ### If the merge target isn't defined and we do not have an external microsd, we should use the internal card by default. + if [ -z "${MS_DEVICE}" ] + then + set_setting system.merged.device internal + fi + start_ms internal + create_game_dirs + exit 0 + fi +} + +## Main.. + +load_modules + +### Unmount any existing storage before beginning operations. +unmount /storage/games-external +unmount /storage/roms + +if [ -e "${GAMES_DEVICE}" ] +then + mount_games ${GAMES_DEVICE} +else + find_games +fi diff --git a/projects/ArchR/packages/archr/sources/scripts/backuptool b/projects/ArchR/packages/archr/sources/scripts/backuptool new file mode 100755 index 0000000000..805c960cf0 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/backuptool @@ -0,0 +1,69 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2020-present Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +# NOTE: to customize your backups, create a backuptool.conf file in +# /storage/.config like this: + +# LOCATIONS=( +# /storage/.config/retroarch/* +# /storage/roms/savestates/* +# /some/other/folder/file.name* +# ) + +BACKUPFOLDER="/storage/roms/backup" +BACKUPFILE="${BACKUPFOLDER}/${OS_NAME}_BACKUP.zip" +mkdir -p ${BACKUPFOLDER} + +DEFAULT=( + /storage/.config/fancontrol.conf + /storage/.config/backuptool.conf + /storage/.cache/bluetooth/* + /storage/.cache/connman* + /storage/.config/system/configs/system.cfg + /storage/.config/ppsspp/* + /storage/.config/retroarch/* + /storage/.config/moonlight/* + /storage/.config/game/* + /storage/.emulationstation/es_*.cfg + /storage/.emulationstation/scripts/* + /storage/.emulationstation/themesettings/* + $(find /storage/.emulationstation/themes/* -type d -maxdepth 0 -not -path "*es-theme-art-book-next" -not -path "*system-theme") +) + +if [ -e "/storage/.config/backuptool.conf" ] +then + source /storage/.config/backuptool.conf + if [ ! $? = 0 ] + then + WARN="Error loading custom backuptool configs. Using defaults." + ${DEBUG} && echo "${WARN}" + logger -t backuptool "${WARN}" + COMPRESSLOCATIONS=(${DEFAULT[@]}) + else + COMPRESSLOCATIONS=(${LOCATIONS[@]}) + fi +else + COMPRESSLOCATIONS=(${DEFAULT[@]}) +fi + +case "${1}" in + "restore") + unzip -o ${BACKUPFILE} -d / + ;; + "backup") + if [ -f ${BACKUPFILE} ] + then + TODAY=`date +%y-%m-%d_%H_%M_%S` + ARCHIVEFILENAME="ARCHIVED_${OS_NAME}_BACKUP-${TODAY}.zip" + mv ${BACKUPFILE} "${BACKUPFOLDER}/${ARCHIVEFILENAME}" + fi + [ -f "${BACKUPFILE}" ] && rm "${BACKUPFILE}" + zip -9 -r ${BACKUPFILE} \ + ${COMPRESSLOCATIONS[@]} + ;; +esac diff --git a/projects/ArchR/packages/archr/sources/scripts/bezels.sh b/projects/ArchR/packages/archr/sources/scripts/bezels.sh new file mode 100755 index 0000000000..283e47415c --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/bezels.sh @@ -0,0 +1,217 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2019-present SumavisionQ5 (https://github.com/SumavisionQ5) +# Modifications by Shanti Gilbert (https://github.com/shantigilbert) + +PLATFORM="$1" + +ROMNAME=$(basename "${2%.*}") +RACONFIG="/storage/.config/retroarch/retroarch.cfg" +OPACITY="1.000000" +AR_INDEX="23" +BEZELDIR="/storage/roms/bezels" +INIFILE="/storage/.config/system/bezels/settings.ini" +DEFAULT_BEZEL="false" + +case $PLATFORM in + "arcade"|"fba"|"fbn"|"neogeo"|"mame"|cps*) + PLATFORM="ARCADE" + ;; + "default") + if [ -f "/storage/.config/bezels_enabled" ]; then + clear_bezel + sed -i '/input_overlay = "/d' $RACONFIG + rm "/storage/.config/bezels_enabled" + fi + exit 0 + ;; + "RETROPIE") + # fbterm does not need bezels + exit 0 + ;; +esac + + if [ ! -f "/storage/.config/bezels_enabled" ]; then + touch /storage/.config/bezels_enabled + fi + +# we make sure the platform is all lowercase +PLATFORM=${PLATFORM,,} + +# if a backup does not exists make a copy of retroarch.cfg so we can return to it when we disable bezels + # for future use...maybe + #if [ ! -f "$RACONFIG.org" ]; then + # cp "$RACONFIG" "$RACONFIG.org" + #fi + +# bezelmap.cfg in $BEZELDIR/ is to share bezels between arcade clones and parent. +BEZELMAP="/storage/.config/system/bezels/arcademap.cfg" +BZLNAME=$(sed -n "/"$PLATFORM"_"$ROMNAME" = /p" "$BEZELMAP") +BZLNAME="${BZLNAME#*\"}" +BZLNAME="${BZLNAME%\"*}" +OVERLAYDIR1=$(find $BEZELDIR/$PLATFORM -maxdepth 1 -iname "$ROMNAME*.cfg" | sort -V | head -n 1) +[ ! -z "$BZLNAME" ] && OVERLAYDIR2=$(find $BEZELDIR/$PLATFORM -maxdepth 1 -iname "$BZLNAME*.cfg" | sort -V | head -n 1) +OVERLAYDIR3="$BEZELDIR/$PLATFORM/default.cfg" + +clear_bezel() { + sed -i '/aspect_ratio_index = "/d' $RACONFIG + sed -i '/custom_viewport_width = "/d' $RACONFIG + sed -i '/custom_viewport_height = "/d' $RACONFIG + sed -i '/custom_viewport_x = "/d' $RACONFIG + sed -i '/custom_viewport_y = "/d' $RACONFIG + sed -i '/video_scale_integer = "/d' $RACONFIG + sed -i '/input_overlay_opacity = "/d' $RACONFIG + echo 'video_scale_integer = "false"' >> $RACONFIG + echo 'input_overlay_opacity = "0.150000"' >> $RACONFIG + } + +set_bezel() { +# $OPACITY: input_overlay_opacity +# ${AR}_INDEX: aspect_ratio_index +# $1: custom_viewport_width +# $2: custom_viewport_height +# $3: ustom_viewport_x +# $4: custom_viewport_y +# $5: video_scale_integer +# $6: video_scale + + clear_bezel + sed -i '/input_overlay_opacity = "/d' $RACONFIG + sed -i "1i input_overlay_opacity = \"$OPACITY\"" $RACONFIG + sed -i "2i aspect_ratio_index = \"${AR}_INDEX\"" $RACONFIG + sed -i "3i custom_viewport_width = \"$1\"" $RACONFIG + sed -i "4i custom_viewport_height = \"$2\"" $RACONFIG + sed -i "5i custom_viewport_x = \"$3\"" $RACONFIG + sed -i "6i custom_viewport_y = \"$4\"" $RACONFIG + sed -i "7i video_scale_integer = \"$5\"" $RACONFIG + } + +check_overlay_dir() { + +# The bezel will be searched and used in following order: +# 1.$OVERLAYDIR1 will be used, if it does not exist, then +# 2.$OVERLAYDIR2 will be used, if it does not exist, then +# 3.$OVERLAYDIR2 platform default bezel as "$BEZELDIR/"$PLATFORM"/default.cfg\" will be used. +# 4.Default bezel at "$BEZELDIR/default.cfg\" will be used. + + sed -i '/input_overlay = "/d' $RACONFIG + + if [ -f "$OVERLAYDIR1" ]; then + echo -e "input_overlay = \""$OVERLAYDIR1"\"\n" >> $RACONFIG + elif [ -f "$OVERLAYDIR2" ]; then + echo -e "input_overlay = \""$OVERLAYDIR2"\"\n" >> $RACONFIG + elif [ -f "$OVERLAYDIR3" ]; then + echo -e "input_overlay = \""$OVERLAYDIR3"\"\n" >> $RACONFIG + else + echo -e "input_overlay = \"$BEZELDIR/default.cfg\"\n" >> $RACONFIG + DEFAULT_BEZEL="true" + fi +} + +# Only 720P and 1080P can use bezels. For 480p/i and 576p/i we just delete bezel config. +hdmimode=$(cat /sys/class/display/mode) + +case $hdmimode in + 480*) + sed -i '/input_overlay = "/d' $RACONFIG + clear_bezel + ;; + 576*) + sed -i '/input_overlay = "/d' $RACONFIG + clear_bezel + ;; + 720p*) + + check_overlay_dir "$PLATFORM" + case "$PLATFORM" in + "gba") + set_bezel "467" "316" "405" "190" "false" + ;; + "gamegear") + set_bezel "780" "580" "245" "70" "false" + ;; + "gb") + set_bezel "429" "380" "420" "155" "false" + ;; + "gbc") + set_bezel "430" "380" "425" "155" "false" + ;; + "ngp") + set_bezel "461" "428" "407" "145" "false" + ;; + "ngpc") + set_bezel "460" "428" "407" "145" "false" + ;; + "wonderswan") + set_bezel "645" "407" "325" "150" "false" + ;; + "wonderswancolor") + set_bezel "643" "405" "325" "150" "false" + ;; + *) + # delete aspect_ratio_index to make sure video is expanded fullscreen. Only certain AMD64 platforms need custom_viewport. + clear_bezel + sed -i '/input_overlay_opacity = "/d' $RACONFIG + sed -i "1i input_overlay_opacity = \"$OPACITY\"" $RACONFIG + ;; + esac + ;; + # For Amlogic TV box, the following resolution is 1080p/i. + 1080*) + check_overlay_dir "$PLATFORM" + case "$1" in + "gba") + set_bezel "698" "472" "609" "288" "false" + ;; + "gamegear") + set_bezel "1160" "850" "380" "120" "false" + ;; + "gb") + set_bezel "625" "565" "645" "235" "false" + ;; + "gbc") + set_bezel "625" "565" "645" "235" "false" + ;; + "ngp") + set_bezel "700" "635" "610" "220" "false" + ;; + "ngpc") + set_bezel "700" "640" "610" "215" "false" + ;; + "wonderswan") + set_bezel "950" "605" "490" "225" "false" + ;; + "wonderswancolor") + set_bezel "950" "605" "490" "225" "false" + ;; + *) + clear_bezel + sed -i '/input_overlay_opacity = "/d' $RACONFIG + sed -i "1i input_overlay_opacity = \"$OPACITY\"" $RACONFIG + ;; + esac + ;; +esac + + if [ "$DEFAULT_BEZEL" = "true" ]; then + set_bezel "1427" "1070" "247" "10" "false" + fi + +# If we disable bezel in setting.ini for certain platform, we just delete bezel config. +Bezel=$(sed -n "/"$PLATFORM"_Bezel = /p" $INIFILE) +Bezel="${Bezel#*\"}" +Bezel="${Bezel%\"*}" +if [ "$Bezel" = "OFF" ]; then +sed -i '/input_overlay = "/d' $RACONFIG +fi + +# Note: +# 1. Different AMD64 platforms have different bezels, they may need different viewport value even for same platform. +# So, I think this script should be stored in $BEZELDIR/ or some place wich can be modified by users. +# 2. For Arcade games, I created a bezelmap.cfg in $BEZELDIR/ in order to share bezels between arcade clones and parent. +# In fact, ROMs of other platforms can share certain bezel if you write mapping relationship in bezelmap.cfg. +# 3. I modified es_systems.cfg to set $1 as platfrom for all platfrom. +# For some libretro core such as /usr/bin/sx05reRunEmu.sh LIBRETRO scummvm %ROM%, $1 not right platform value, +# you may need some tunings on them. +# 4. I am a Linux noob, so the codes are a mess. Sorry for that:) diff --git a/projects/ArchR/packages/archr/sources/scripts/brightness b/projects/ArchR/packages/archr/sources/scripts/brightness new file mode 100755 index 0000000000..cb41a5fa0c --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/brightness @@ -0,0 +1,224 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-24 JELOS (https://github.com/JustEnoughLinuxOS) +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +## Load minimal distribution settings to improve +## performance. +. /etc/profile.d/001-functions + +declare -a BRIGHTNESS_DEVS=() +while IFS= read -r line; do + BRIGHTNESS_DEVS+=("$line") +done < <(find /sys/class/backlight/*/ -name brightness 2>/dev/null) + +NUM_DEVS="${#BRIGHTNESS_DEVS[@]}" + +if [ "${NUM_DEVS}" -eq 0 ]; then + echo "ERROR: No backlight devices found in /sys/class/backlight/." >&2 + exit 1 +fi + +declare -a MAX_VALUES=() +for dev_path in "${BRIGHTNESS_DEVS[@]}"; do + DIR="$(dirname "${dev_path}")" + MAX_FILE="${DIR}/max_brightness" + if [ -f "${MAX_FILE}" ]; then + MAX_VALUES+=("$(<"${MAX_FILE}")") + else + MAX_VALUES+=(100) + fi +done + +CURRENT_DEV_PATH="" +CURRENT_MAX=0 +CURRENT_SETTING_KEY="" +SCREEN_INPUT=1 + +_compute_raw() { + local percent="${1}" + local max_val="${2}" + echo "(${percent} / 100 * ${max_val})" | bc -l | cut -f1 -d. +} + +_resolve_config() { + SCREEN_INPUT="${1}" + + if ! [[ "${SCREEN_INPUT}" =~ ^[1-9][0-9]*$ ]]; then + echo "ERROR: Screen number must be a positive integer." >&2 + return 1 + fi + + local dev_index=$((SCREEN_INPUT - 1)) + + if [ "${dev_index}" -lt 0 ] || [ "${dev_index}" -ge "${NUM_DEVS}" ]; then + echo "ERROR: Screen number ${SCREEN_INPUT} is out of range (1-${NUM_DEVS})." >&2 + return 1 + fi + + CURRENT_DEV_PATH="${BRIGHTNESS_DEVS[dev_index]}" + CURRENT_MAX="${MAX_VALUES[dev_index]}" + + if [ "${SCREEN_INPUT}" -eq 1 ]; then + CURRENT_SETTING_KEY="display.brightness" + else + CURRENT_SETTING_KEY="display.brightness${SCREEN_INPUT}" + fi + + return 0 +} + +_write_brightness() { + local raw_value="${1}" + local percentage="${2}" + + echo "${raw_value}" > "${CURRENT_DEV_PATH}" + set_setting "${CURRENT_SETTING_KEY}" "${percentage}" +} + +stepUp() { + local current_percent + current_percent="$(get_setting "${CURRENT_SETTING_KEY}")" + + local next_percent=$((current_percent + 5)) + if (("${next_percent}" > 100)); then + next_percent=100 + fi + + if (("${current_percent}" < 5)) && (("${next_percent}" < 5)); then + next_percent=5 + fi + + local raw_value + raw_value="$(_compute_raw "${next_percent}" "${CURRENT_MAX}")" + + if (("${raw_value}" > "${CURRENT_MAX}")); then + raw_value="${CURRENT_MAX}" + fi + + _write_brightness "${raw_value}" "${next_percent}" + getBrightnessValue +} + +stepDown() { + local current_percent + current_percent="$(get_setting "${CURRENT_SETTING_KEY}")" + + local next_percent=$((current_percent - 5)) + + if (("${next_percent}" < 5)); then + next_percent=5 + fi + + local raw_value + raw_value="$(_compute_raw "${next_percent}" "${CURRENT_MAX}")" + + _write_brightness "${raw_value}" "${next_percent}" + getBrightnessValue +} + +setBrightnessValue() { + local percent="${1}" + + if ! [[ "${percent}" =~ ^[0-9]+$ ]] || (("${percent}" < 0)) || (("${percent}" > 100)); then + echo "ERROR: Invalid percentage value provided: ${percent}. Must be 0-100." >&2 + return 1 + fi + + if (("${percent}" < 5)); then + percent=5 + fi + + local raw_value + raw_value="$(_compute_raw "${percent}" "${CURRENT_MAX}")" + + _write_brightness "${raw_value}" "${percent}" +} + +getBrightnessValue() { + cat "${CURRENT_DEV_PATH}" +} + +# Helper: apply an action to all detected screens +_apply_all() { + local action="$1" + local value="$2" # only used for "set" + + for ((i=0; i" >&2 + echo "Example: $0 set 50 or $0 set 2 50" >&2 + exit 1 + fi + + if [ "${screen_num_val}" = "all" ]; then + _apply_all "set" "${percentage_val}" + else + if ! _resolve_config "${screen_num_val}"; then exit 1; fi + setBrightnessValue "${percentage_val}" + fi + getBrightnessValue + ;; + + "") + ;& + *) + screen_to_get="" + if [ -z "${ACTION}" ] || { [ "${ACTION}" != "up" ] && [ "${ACTION}" != "down" ] && [ "${ACTION}" != "set" ]; }; then + if [ -n "${1}" ] && [[ "${1}" =~ ^[0-9]+$ ]]; then + screen_to_get="${1}" + else + screen_to_get="1" + fi + + if ! _resolve_config "${screen_to_get}"; then exit 1; fi + getBrightnessValue + exit 0 + fi + + echo "Usage: $0 {up|down|set} [screen_num|all] [percentage]" >&2 + echo "Example 1: $0 up (Increase brightness on all screens)" >&2 + echo "Example 2: $0 down 2 (Decrease brightness on screen 2)" >&2 + echo "Example 3: $0 set all 75 (Set brightness on all to 75%)" >&2 + exit 1 + ;; +esac diff --git a/projects/ArchR/packages/archr/sources/scripts/chksysconfig b/projects/ArchR/packages/archr/sources/scripts/chksysconfig new file mode 100755 index 0000000000..682ec7db6d --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/chksysconfig @@ -0,0 +1,45 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +CFG_PATH="/storage/.config/system/configs" + +backup() { + TYPE=$(grep a ${CFG_PATH}/system.cfg 2>&1) + if [[ ! "${TYPE}" =~ binary ]] + then + cp ${CFG_PATH}/system.cfg ${CFG_PATH}/system.cfg.backup + fi +} + +restore() { + cp ${CFG_PATH}/system.cfg.backup ${CFG_PATH}/system.cfg +} + +verify() { + TYPE=$(grep a ${CFG_PATH}/system.cfg 2>&1) + if [[ "${TYPE}" =~ binary ]]; then + restore + fi + + # Check if any configs are missing and restore everything if they are + if [ ! -s /storage/.config/retroarch/retroarch-core-options.cfg ] || \ + [ ! -s /storage/.config/retroarch/retroarch.cfg ] || \ + ! grep -q system.hostname /storage/.config/system/configs/system.cfg; then + rsync -a /usr/config/ /storage/.config + fi +} + +case ${1} in + verify) + verify + ;; + backup) + backup + ;; + restore) + restore + ;; +esac diff --git a/projects/ArchR/packages/archr/sources/scripts/controller-layout b/projects/ArchR/packages/archr/sources/scripts/controller-layout new file mode 100644 index 0000000000..0d63ffc56e --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/controller-layout @@ -0,0 +1,60 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile.d/001-functions +. /etc/profile.d/100-gamecontroller-functions + +# -- Config & Setup -- +# Destination file +if [[ -z "$1" ]] && [[ -z "$2" ]] && [[ -z "$3" ]]; then + echo "Usage: controller-layout [platform] [game] [gamecontrollerdb.txt]" + exit -1 +fi + +PLATFORM="$1" +GAME="$2" +CONTROLLER_DB="$3" + +# Where the emulationstation configuration file is +ES_CONFIG="/tmp/es_input.cfg" + +# Scrub the CONTROLLER_DB file +echo "" > ${CONTROLLER_DB} + +# Set layout via EmulationStation +CONTROLLER_LAYOUT=$(get_setting controller_layout "${PLATFORM}" "${GAME}") + +if [ "${CONTROLLER_LAYOUT}" = "xbox" ]; then + # xbox layout + ABUT="b" + BBUT="a" + XBUT="y" + YBUT="x" + unset LEFTSHOULDER + unset LEFTTRIGGER + unset RIGHTSHOULDER + unset RIGHTTRIGGER +elif [ "${CONTROLLER_LAYOUT}" = "xbox_swap_shoulders_triggers" ]; then + # xbox layout - with shoulders and triggers swapped + ABUT="b" + BBUT="a" + XBUT="y" + YBUT="x" + LEFTSHOULDER="lefttrigger" + LEFTTRIGGER="leftshoulder" + RIGHTSHOULDER="righttrigger" + RIGHTTRIGGER="rightshoulder" +else + # nintendo layout + unset ABUT + unset BBUT + unset XBUT + unset YBUT + unset LEFTSHOULDER + unset LEFTTRIGGER + unset RIGHTSHOULDER + unset RIGHTTRIGGER +fi + +# Call function to create controller db from ES input config file for only connected devices +create_controller_db ${CONTROLLER_LAYOUT} ${ES_CONFIG} ${CONTROLLER_DB} \ No newline at end of file diff --git a/projects/ArchR/packages/archr/sources/scripts/error.sh b/projects/ArchR/packages/archr/sources/scripts/error.sh new file mode 100755 index 0000000000..db010efe2b --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/error.sh @@ -0,0 +1,19 @@ +#!/usr/bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2021-present 351ELEC + +. /etc/profile + +clear +if [ -n "$1" ] +then + text_viewer -w -e -t "BIOS ERROR" -m "$*" +else + ERROR=$(tail -n 25 /var/log/es_launch_stderr.log) + if [ !-z "${ERROR}" ]; + then + text_viewer -w -e -t ERROR -m "${ERROR}" + fi +fi + +clear diff --git a/projects/ArchR/packages/archr/sources/scripts/factoryreset b/projects/ArchR/packages/archr/sources/scripts/factoryreset new file mode 100755 index 0000000000..2f7851a382 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/factoryreset @@ -0,0 +1,86 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2020-present Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +case "${1}" in + "retroarch") + rm -f /storage/.config/retroarch/retroarch.cfg + cp -rf /usr/config/retroarch/retroarch.cfg /storage/.config/retroarch/retroarch.cfg + ;; + "retroarch-full") + rm -rf /storage/.config/retroarch + cp -rf /usr/config/retroarch /storage/.config/ + ;; + "mednafen") + rm -f /storage/.config/mednafen/mednafen.cfg + ;; + "standalone") + rm -rf /storage/.config/aethersx2 + cp -rf /usr/config/aethersx2 /storage/.config/ + + rm -rf /storage/.config/amiberry + cp -rf /usr/config/amiberry /storage/.config/ + + rm -rf /storage/.config/dolphin-emu + cp -rf /usr/config/dolphin-emu /storage/.config/ + + rm -rf /storage/.config/drastic + cp -rf /usr/config/drastic /storage/.config/ + + rm -rf /storage/.config/duckstation + cp -rf /usr/config/duckstation /storage/.config/ + + rm -rf /storage/.config/flycast + cp -rf /usr/config/flycast /storage/.config/ + + rm -rf /storage/.config/gzdoom + cp -rf /usr/config/gzdoom /storage/.config/ + + rm -rf /storage/.config/hatari + cp -rf /usr/config/hatari /storage/.config/ + + rm -rf /storage/.config/melonDS + cp -rf /usr/config/melonDS /storage/.config/ + + rm -rf /storage/.config/openbor + cp -rf /usr/config/openbor /storage/.config/ + + rm -rf /storage/.config/ppsspp + cp -rf /usr/config/ppsspp /storage/.config/ + + rm -rf /storage/.config/azahar + cp -rf /usr/config/azahar /storage/.config/ + + rm -rf /storage/.config/rpcs3 + cp -rf /usr/config/rpcs3 /storage/.config/ + ;; + "portmaster") + rm -rf /storage/.config/PortMaster + cp -rf /usr/config/PortMaster /storage/.config/ + rm -rf /storage/roms/ports/PortMaster + unzip /usr/config/PortMaster/release/PortMaster.zip -d /storage/roms/ports/ + chmod +x /storage/roms/ports/PortMaster/PortMaster.sh + ;; + "overlays") + rm -rf $(cat /usr/lib/systemd/system/tmp-*.mount | grep -Eo 'upperdir=.*,' | sed -e 's~upperdir=~~g; s~,~~g') + sync + systemctl reboot + ;; + "audio") + systemctl stop pipewire-pulse pipewire-pulse.socket pipewire pipewire.socket wireplumber + rm -rf /storage/.local/state /storage/.config/pulse /storage/asound* + systemctl reboot + ;; + "ALL") + swapoff -a 2>/dev/null + umount /storage/roms 2>/dev/null ||: + umount /storage/games-external 2>/dev/null ||: + cd / + find /storage -mindepth 1 \( ! -regex '^/storage/.update.*' -a ! -regex '^/storage/roms.*' -a ! -regex '^/storage/games-.*' \) -delete 2>/dev/null + mkdir /storage/.config/ + sync 2>/dev/null + systemctl reboot + ;; +esac diff --git a/projects/ArchR/packages/archr/sources/scripts/find.sh b/projects/ArchR/packages/archr/sources/scripts/find.sh new file mode 100755 index 0000000000..d363e3b2ed --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/find.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2019-present Shanti Gilbert (https://github.com/shantigilbert) + +find / -type d \( -path /var/media -o -path /storage/roms \) -prune -o -iname *${1}* -print diff --git a/projects/ArchR/packages/archr/sources/scripts/getfilters b/projects/ArchR/packages/archr/sources/scripts/getfilters new file mode 100755 index 0000000000..1298d5637e --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/getfilters @@ -0,0 +1,11 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2020-present Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +find /usr/share/retroarch/filters/64bit/video/ -name '*.filt' -print0 | + while IFS= read -r -d '' line; do + echo ${line#/usr/share/retroarch/filters/64bit/video/}, +done | sort + diff --git a/projects/ArchR/packages/archr/sources/scripts/getoverlays b/projects/ArchR/packages/archr/sources/scripts/getoverlays new file mode 100755 index 0000000000..96f73aff92 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/getoverlays @@ -0,0 +1,12 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2020-present Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + + +find /storage/overlays/ -name '*.cfg' -print0 | + while IFS= read -r -d '' line; do + echo ${line#/storage/overlays/}, +done | sort + diff --git a/projects/ArchR/packages/archr/sources/scripts/getshaders b/projects/ArchR/packages/archr/sources/scripts/getshaders new file mode 100755 index 0000000000..318fa59080 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/getshaders @@ -0,0 +1,23 @@ +#!/bin/bash + +. /etc/profile + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2020-present Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +if [ -z "$UI_SHADER" ]; then + option=".*\.\(glslp\|slangp\)$" +else + option=".*\.\($UI_SHADER\)$" +fi + +for dir in /tmp/shaders +do + if [ -d "${dir}" ]; then + find ${dir} -regex "${option}" -print0 | + while IFS= read -r -d '' line; do + echo ${line#${dir}/}, + done | sort + fi +done diff --git a/projects/ArchR/packages/archr/sources/scripts/handle-hdmi-hotplug b/projects/ArchR/packages/archr/sources/scripts/handle-hdmi-hotplug new file mode 100755 index 0000000000..8bfba3b350 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/handle-hdmi-hotplug @@ -0,0 +1,48 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile +if ! pgrep -x emulationstation > /dev/null; then + exit 0 +fi + +HDMI_OUTPUT=$(wlr-randr | awk '/^(HDMI-A|DP|DisplayPort)-[0-9]*/ {print $1}') +DSI_OUTPUT=$(wlr-randr | awk '/^DSI-[0-9]/ {print $1}') + +HDMI_STATE=$(cat /run/hdmi-status.last 2>/dev/null) + +case "${HDMI_STATE}" in + connected) + + # Stop USB gadget only if using USB-C (DisplayPort) video, as it conflicts with USB data lanes on some SoCs (e.g. RK3588/SM8250) + # Standard HDMI ports are unaffected. + if cat /sys/class/drm/card*-DP*/status /sys/class/drm/card*-DisplayPort*/status 2>/dev/null | grep -q "^connected"; then + if systemctl is-active --quiet usbgadget; then + systemctl stop usbgadget + fi + fi + if [ -n "${HDMI_OUTPUT}" ]; then + wlr-randr --output "${HDMI_OUTPUT}" --preferred --on + fi + if [ -n "${DSI_OUTPUT}" ]; then + wlr-randr --output "${DSI_OUTPUT}" --off + fi + killall emulationstation + ;; + disconnected) + + # Stop USB gadget only if using USB-C (DisplayPort) video, as it conflicts with USB data lanes on some SoCs (e.g. RK3588/SM8250) + # Standard HDMI ports are unaffected. + if cat /sys/class/drm/card*-DP*/status /sys/class/drm/card*-DisplayPort*/status 2>/dev/null | grep -q "^connected"; then + if systemctl is-active --quiet usbgadget; then + systemctl stop usbgadget + fi + fi + if [ -n "${DSI_OUTPUT}" ]; then + wlr-randr --output "${DSI_OUTPUT}" --preferred --on + fi + killall emulationstation + ;; +esac + diff --git a/projects/ArchR/packages/archr/sources/scripts/installtointernal b/projects/ArchR/packages/archr/sources/scripts/installtointernal new file mode 100755 index 0000000000..3c301b6c95 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/installtointernal @@ -0,0 +1,212 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) +# +# This script will resize the Android userdata partition and install +# ArchR to the internal UFS. + +set -euo pipefail + +case "$HW_DEVICE" in + SM8250|SM8550|SM8650) + ;; + *) + echo "This script is not compatible with this device!" + exit 1 + ;; +esac + +DEVICE=/dev/sda +FLASH_DIR=/flash +OLD_STORAGE=/storage +TMP_ArchR=/tmp/archr +TMP_STORAGE=/tmp/storage + +# Helper: report a device's size in GiB +get_gb() { + local dev=$1 bytes + if bytes=$(blockdev --getsize64 "$dev" 2>/dev/null); then + echo $(( bytes / 1024**3 )) + else + echo "N/A" + fi +} + +# Helper: calculate storage size excluding specific folders +get_storage_size_kb() { + local storage_path="$1" + local total_kb=0 + local excluded_folders=("roms" "games-internal" "games-external" ".cache/cores") + + # Get total size first + total_kb=$(du -ks "$storage_path" | awk '{print $1}') + + # Subtract excluded folders if they exist + for folder in "${excluded_folders[@]}"; do + if [[ -d "$storage_path/$folder" ]]; then + local folder_kb=$(du -ks "$storage_path/$folder" | awk '{print $1}') + total_kb=$((total_kb - folder_kb)) + fi + done + + echo "$total_kb" +} + +# 1) Check for existing ArchR or STORAGE partitions +mapfile -t part_names < <(parted -m -s "$DEVICE" print | tail -n +2 | cut -d: -f6) +for name in "${part_names[@]}"; do + if [[ "$name" == "ArchR" || "$name" == "STORAGE" ]]; then + echo "An installation already exists (found partition named '$name'). Exiting." + exit 0 + fi +done + +# 2) Warn user +read -rp "WARNING: This will wipe Android userdata on ${DEVICE}. Proceed? [y/N]: " confirm +if [[ ! $confirm =~ ^[Yy]$ ]]; then + echo "Aborted by user." + exit 0 +fi + +# 3) Find current Android userdata partition +mapfile -t ud_line < <(parted -m -s "$DEVICE" unit B print | grep ':userdata:') +if [[ ${#ud_line[@]} -ne 1 ]]; then + echo "ERROR: Could not uniquely find a Android userdata partition labeled 'userdata'." + exit 1 +fi +IFS=':' read -r UD_NUM UD_STARTB UD_ENDB _ <<< "${ud_line[0]}" +UD_START=${UD_STARTB%B} +UD_END=${UD_ENDB%B} + +# Compute MiB-aligned boundaries for Android userdata +UD_START_MB=$(( (UD_START + 1048575) / 1048576 )) # round up to MiB +UD_END_MB=$(( UD_END / 1048576 )) # round down to MiB +ORIG_SIZE=$(( (UD_END_MB - UD_START_MB) * 1024**2 )) # bytes +MIN_SIZE=$((1 * 1024**3)) +RESERVE=$((8 * 1024**3)) +MAX_SIZE=$(( ORIG_SIZE - RESERVE )) +if (( MAX_SIZE < MIN_SIZE )); then + echo "ERROR: Not enough space to shrink by 8GB. Aborting." + exit 1 +fi + +# 4) Ask desired Android userdata size in GB +echo "Current Android userdata size: $((ORIG_SIZE / 1024**3)) GB" +echo "You may choose between 1 GB and $((MAX_SIZE / 1024**3)) GB" +while :; do + read -rp "Enter new Android userdata size in GB: " ud_gb + if ! [[ $ud_gb =~ ^[0-9]+$ ]]; then + echo "Please enter an integer." + continue + fi + ud_bytes=$(( ud_gb * 1024**3 )) + if (( ud_bytes < MIN_SIZE || ud_bytes > MAX_SIZE )); then + echo "Value out of range. Must be between 1 and $((MAX_SIZE / 1024**3)) GB." + continue + fi + break +done +NEW_UD_END_MB=$(( UD_START_MB + (ud_bytes / 1024**2) )) + +# 5) Delete and recreate Android userdata partition +echo "Deleting Android userdata partition #$UD_NUM..." +parted -s "$DEVICE" rm "$UD_NUM" +echo "Creating Android userdata partition #$UD_NUM (${UD_START_MB}MiB–${NEW_UD_END_MB}MiB)..." +parted -a optimal -s "$DEVICE" \ + mkpart primary ext4 "${UD_START_MB}MiB" "${NEW_UD_END_MB}MiB" +parted -s "$DEVICE" name "$UD_NUM" userdata + +# 5b) Wipe first 8 MiB of the new Android userdata partition +echo "Zeroing first 8 MiB of ${DEVICE}${UD_NUM}..." +dd if=/dev/zero of="${DEVICE}${UD_NUM}" bs=1M count=8 &>/dev/null + +# 6) Create ArchR partition +RK_NUM=$(( UD_NUM + 1 )) +RK_START_MB=$NEW_UD_END_MB +RK_END_MB=$(( RK_START_MB + 2048 )) # 2 GiB +echo "Creating ArchR partition #$RK_NUM (${RK_START_MB}MiB–${RK_END_MB}MiB)..." +parted -a optimal -s "$DEVICE" \ + mkpart primary fat32 "${RK_START_MB}MiB" "${RK_END_MB}MiB" +parted -s "$DEVICE" name "$RK_NUM" ArchR +parted -s "$DEVICE" set "$RK_NUM" msftdata on +parted -s "$DEVICE" set "$RK_NUM" boot on + +# 7) Format ArchR partition +if mount | grep -q "^${DEVICE}${RK_NUM} "; then + echo "Auto-unmounting ${DEVICE}${RK_NUM}..." + umount "${DEVICE}${RK_NUM}" +fi +mkfs.vfat -F 32 -S 4096 -s 4 -n ArchR "${DEVICE}${RK_NUM}" &>/dev/null + +# 8) Create STORAGE partition +ST_NUM=$(( UD_NUM + 2 )) +echo "Creating STORAGE partition #$ST_NUM (from ${RK_END_MB}MiB to end)..." +parted -a optimal -s "$DEVICE" \ + mkpart primary ext4 "${RK_END_MB}MiB" 100% +parted -s "$DEVICE" name "$ST_NUM" STORAGE + +# 9) Format STORAGE +if mount | grep -q "^${DEVICE}${ST_NUM} "; then + echo "Auto-unmounting ${DEVICE}${ST_NUM}..." + umount "${DEVICE}${ST_NUM}" +fi +mkfs.ext4 -F -q -L STORAGE -T ext4 -O ^orphan_file -m 0 "${DEVICE}${ST_NUM}" &>/dev/null + +# 10) Final mounts: unmount any auto-mounted, then mount fresh +for dev in "${DEVICE}${RK_NUM}" "${DEVICE}${ST_NUM}"; do + if mount | grep -q "^$dev "; then + echo "Auto-unmounting $dev..." + umount "$dev" + fi +done +mkdir -p "$TMP_ArchR" "$TMP_STORAGE" +mount "${DEVICE}${RK_NUM}" "$TMP_ArchR" +mount "${DEVICE}${ST_NUM}" "$TMP_STORAGE" + +# 11) Copy files to ArchR partition, then sync +echo "Copying flash files to ArchR..." +cp -a "$FLASH_DIR"/. "$TMP_ArchR"/ +sync + +# 12) Optionally copy /storage to STORAGE partition, then sync +read -rp "Copy existing /storage to new STORAGE? [y/N]: " copy_ans +if [[ $copy_ans =~ ^[Yy]$ ]]; then + avail_kb=$(df -k "$TMP_STORAGE" | awk 'NR==2 {print $4}') + used_kb=$(get_storage_size_kb "$OLD_STORAGE") + if (( used_kb <= avail_kb )); then + echo "Copying /storage to new STORAGE (excluding roms)..." + + # Copy everything except the excluded folders + find "$OLD_STORAGE" -mindepth 1 -maxdepth 1 \ + ! -name "roms" \ + ! -name "games-internal" \ + ! -name "games-external" \ + -exec cp -a {} "$TMP_STORAGE"/ \; + + sync + else + echo "Skipping copy: not enough free space ($((avail_kb*1024)) bytes available, $((used_kb*1024)) bytes needed)." + fi +fi + +# 13) Final sync +echo "Syncing final data to disk..." +sync + +# 14) Cleanup mounts +echo "Cleaning up..." +umount "$TMP_ArchR" +umount "$TMP_STORAGE" +rmdir "$TMP_ArchR" "$TMP_STORAGE" + +# 15) Final summary with sizes +ud_sz=$(get_gb "${DEVICE}${UD_NUM}") +rk_sz=$(get_gb "${DEVICE}${RK_NUM}") +st_sz=$(get_gb "${DEVICE}${ST_NUM}") + +echo "Done. New partitions:" +echo " Android userdata: ${DEVICE}${UD_NUM} (${ud_sz} GB)" +echo " ArchR : ${DEVICE}${RK_NUM} (${rk_sz} GB)" +echo " STORAGE : ${DEVICE}${ST_NUM} (${st_sz} GB)" +echo +echo "ArchR Installation to internal UFS was successful. You can now reboot and remove your SD card." diff --git a/projects/ArchR/packages/archr/sources/scripts/led_flash b/projects/ArchR/packages/archr/sources/scripts/led_flash new file mode 100755 index 0000000000..660e200013 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/led_flash @@ -0,0 +1,42 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +COLOR=$(get_setting led.color) +BRI=$(get_setting led.brightness) + +if [ -z "${COLOR}" ] || \ + [ "${COLOR}" = "off" ] || \ + [ -n "${DEVICE_LED_CHARGING}" ] +then + FLASH_COLOR="red" +else + FLASH_COLOR="${COLOR}" +fi + +if [ "${DEVICE_LED_BRIGHTNESS}" = "true" ] +then + ledcontrol brightness mid +fi + +for i in $(seq 1 1 3) +do + ledcontrol ${FLASH_COLOR} + sleep .5 + ledcontrol poweroff + sleep .5 +done + +if [ -n "${COLOR}" ] +then + ledcontrol ${COLOR} +else + ledcontrol default +fi + +if [ "${DEVICE_LED_BRIGHTNESS}" = "true" ] +then + ledcontrol brightness ${BRI} +fi diff --git a/projects/ArchR/packages/archr/sources/scripts/migrate_roms b/projects/ArchR/packages/archr/sources/scripts/migrate_roms new file mode 100644 index 0000000000..b3ab9abbfe --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/migrate_roms @@ -0,0 +1,36 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +LOGFILE="/var/log/migrate.log" + +read -p "WARNING: This tool can cause data loss... Make sure you have a backup before proceeding... Press control-c now to cancel, or any other key to continue..." + +for GAMES in /storage/games-internal /storage/games-external +do + echo "Working on ${GAMES}..." + if [ ! -d "${GAMES}/roms" ] + then + echo "Making ${GAMES}/roms..." + mkdir -p "${GAMES}/roms" >>${LOGFILE} 2>&1 1|>>${LOGFILE} + fi + for DIR in $(find "${GAMES}/" -type d -maxdepth 1 -mindepth 1 2>/dev/null) + do + TARGET_DIR=$(basename ${DIR}) + echo "Working on ${DIR}..." + if [[ "${DIR}" =~ roms$ ]] + then + continue + fi + if [ ! -d "${GAMES}/roms/${TARGET_DIR}" ] + then + echo "Making ${GAMES}/roms/${TARGET_DIR}..." + mkdir -p "${GAMES}/roms/${TARGET_DIR}" >>${LOGFILE} 2>&1 + fi + mv "${DIR}"/* "${GAMES}/roms/${TARGET_DIR}" >>${LOGFILE} 2>&1 + rsync -av --remove-source-files "${DIR}"/* "${GAMES}/roms/${TARGET_DIR}" >>${LOGFILE} 2>&1 + done + echo "Clean empties in ${GAMES}..." + find "${GAMES}" -type d -empty -delete >>${LOGFILE} 2>&1 1|>>${LOGFILE} + echo "Your games have been migrated, however you will need to manually clean up stale directories. Please reboot your system now by running the `reboot` command." +done diff --git a/projects/ArchR/packages/archr/sources/scripts/paneladj b/projects/ArchR/packages/archr/sources/scripts/paneladj new file mode 100755 index 0000000000..2f25badde5 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/paneladj @@ -0,0 +1,104 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +# ARGS: +# +# 1 - property to adjust (gamma (brightness)/contrast/saturation/hue) +# 2 - up/down or a defined value + +PROPERTY=${1} +NEWVAL=${2} + +# Command usage: +# drm_tool set /dev/dri/card0 133 saturation value + +# Define the basics +MIN=1 +MAX=100 +STEP=1 + +if [ ! -e /dev/dri/card0 ] +then + echo "ERROR: No display found." + exit 1 +fi + +log() { + $DEBUG && echo "Info: ${*}" >>/var/log/display.log +} + +getValue() { + MYVAL=$(get_setting display.${1}) + if [ -n "${MYVAL}" ] + then + if [ "${MYVAL}" > "${MAX}" ] + then + MYVAL=${MAX} + elif [ "${MYVAL}" < "${MIN}" ] + then + MYVAL=${MIN} + fi + echo ${MYVAL} + else + echo $(drm_tool list 2>/dev/null | sed -n '/Connector: '${CONNECTOR}'/,$p' | awk '/'${1}'/ {print $5}') + fi +} + +setValue() { + log "Set (${1}: ${2})" + drm_tool set /dev/dri/card0 ${CONNECTOR} ${1} ${2} 2>/dev/null + if [ $? = 0 ] + then + set_setting display.${1} ${2} + fi +} + +stepUp() { + LASTVAL=$(getValue ${PROPERTY}) + NEWVAL=$(expr ${LASTVAL} + 1) + log "Step up (${PROPERTY}: ${NEWVAL})" + setValue ${PROPERTY} ${NEWVAL} +} + +stepDown() { + LASTVAL=$(getValue ${PROPERTY}) + NEWVAL=$(expr ${LASTVAL} - 1) + log "Step down (${PROPERTY}: ${NEWVAL})" + setValue ${PROPERTY} ${NEWVAL} +} + +restoreSettings() { + for PROPERTY in brightness contrast saturation hue + do + RESTVAL=$(getValue ${PROPERTY}) + setValue ${PROPERTY} ${RESTVAL} + done +} + +CONNECTOR=$(drm_tool list | grep -B1 "mode.*:" | awk '/Connector/ {print $2}') + +case ${NEWVAL} in + "up") + stepUp + ;; + "down") + stepDown + ;; + "restore") + restoreSettings + ;; + *) + if [[ "${NEWVAL}" =~ ^[0-9] ]] && \ + [ "${NEWVAL}" -le "${MAX}" ] && \ + [ "${NEWVAL}" -ge "${MIN}" ] + then + setValue ${PROPERTY} ${NEWVAL} + else + echo "Error: Invalid value." + exit 1 + fi + ;; +esac diff --git a/projects/ArchR/packages/archr/sources/scripts/run b/projects/ArchR/packages/archr/sources/scripts/run new file mode 100755 index 0000000000..136d1c3eb2 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/run @@ -0,0 +1,42 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +ui_state() { + clear >/dev/console + systemctl ${1} ${UI_SERVICE} +} + +if [ "${UI_SERVICE}" = "weston.service" ] +then + if [ -f "${*}" ] + then + RUN=$(echo ${*} | sed 's# #\\ #g') + weston-terminal --command="${RUN}" + else + weston-terminal --command="${*}" + fi +elif echo "${UI_SERVICE}" | grep "sway"; then + if [ -f "${*}" ] + then + foot -F "${*}" + else + foot -F ${*} + fi +else + ui_state stop + clear >/dev/console + $* >/dev/console + if [ "$?" == 0 ] + then + ui_state start + exit 0 + else + "$*" >/dev/console + ui_state start + exit 0 + fi +fi + diff --git a/projects/ArchR/packages/archr/sources/scripts/runemu.sh b/projects/ArchR/packages/archr/sources/scripts/runemu.sh new file mode 100755 index 0000000000..8a22a1d6e4 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/runemu.sh @@ -0,0 +1,484 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2019-present Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Source predefined functions and variables +. /etc/profile +. /etc/os-release + +### Switch to performance mode early to speed up configuration and reduce time it takes to get into games. +performance + +# Command line schema +# $1 = Game/Port +# $2 = Platform +# $3 = Core +# $4 = Emulator + +ARGUMENTS="$@" +PLATFORM="${ARGUMENTS##*-P}" # read from -P onwards +PLATFORM="${PLATFORM%% *}" # until a space is found +CORE="${ARGUMENTS##*--core=}" # read from --core= onwards +CORE="${CORE%% *}" # until a space is found +EMULATOR="${ARGUMENTS##*--emulator=}" # read from --emulator= onwards +EMULATOR="${EMULATOR%% *}" # until a space is found +ROMNAME="$1" +BASEROMNAME=${ROMNAME##*/} +GAMEFOLDER="${ROMNAME//${BASEROMNAME}}" + +### Define the variables used throughout the script +BLUETOOTH_STATE=$(get_setting controllers.bluetooth.enabled) +ES_CONFIG="/storage/.emulationstation/es_settings.cfg" +VERBOSE=false +LOG_DIRECTORY="/var/log" +LOG_FILE="exec.log" +RUN_SHELL="/usr/bin/bash" +RETROARCH_TEMP_CONFIG="/storage/.config/retroarch/retroarch.cfg" +RETROARCH_APPEND_CONFIG="/tmp/.retroarch.cfg" +NETWORK_PLAY="No" +SET_SETTINGS_TMP="/tmp/shader" +OUTPUT_LOG="${LOG_DIRECTORY}/${LOG_FILE}" +SCRIPT_NAME=$(basename "$0") + +### Export Game Guide Path +GAME_GUIDE_PATH_CHECK="${1%.*}.txt" +if [ ! -f "${GAME_GUIDE_PATH_CHECK}" ]; then + GAME_GUIDE_PATH_CHECK="No Game Guide Found" +fi + /usr/bin/game-guides-tool "${1}" + +### Function Library +function log() { + if [ ${LOG} == true ] + then + if [[ ! -d "$LOG_DIRECTORY" ]] + then + mkdir -p "$LOG_DIRECTORY" + fi + echo "${SCRIPT_NAME}: $*" 2>&1 | tee -a ${LOG_DIRECTORY}/${LOG_FILE} + else + echo "${SCRIPT_NAME}: $*" + fi +} + +function loginit() { + if [ ${LOG} == true ] + then + if [ -e ${LOG_DIRECTORY}/${LOG_FILE} ] + then + rm -f ${LOG_DIRECTORY}/${LOG_FILE} + fi + cat <${LOG_DIRECTORY}/${LOG_FILE} +Emulation Run Log - Started at $(date) + +ARG1: $1 +ARG2: $2 +ARG3: $3 +ARG4: $4 +ARGS: $* +EMULATOR: ${EMULATOR} +PLATFORM: ${PLATFORM} +CORE: ${CORE} +ROM NAME: ${ROMNAME} +BASE ROM NAME: ${ROMNAME##*/} +USING CONFIG: ${RETROARCH_TEMP_CONFIG} +USING APPENDCONFIG : ${RETROARCH_APPEND_CONFIG} +GAME GUIDE PATH: ${GAME_GUIDE_PATH_CHECK} + +EOF + else + log $0 "Emulation Run Log - Started at $(date)" + fi +} + +function quit() { + ${VERBOSE} && log $0 "Cleaning up and exiting" + bluetooth enable + set_kill set "emulationstation" + clear_screen + DEVICE_CPU_GOVERNOR=$(get_setting system.cpugovernor) + ${DEVICE_CPU_GOVERNOR} + exit $1 +} + +function clear_screen() { + ${VERBOSE} && log $0 "Clearing screen" + clear +} + +function bluetooth() { + if [ "$1" == "disable" ] + then + ${VERBOSE} && log $0 "Disabling BT" + if [[ "${BLUETOOTH_STATE}" == "1" ]] + then + NPID=$(pgrep -f archr-bluetooth-agent) + if [[ ! -z "$NPID" ]]; then + kill "$NPID" + fi + fi + elif [ "$1" == "enable" ] + then + ${VERBOSE} && log $0 "Enabling BT" + if [[ "${BLUETOOTH_STATE}" == "1" ]] + then + systemd-run archr-bluetooth-agent + fi + fi +} + +### Enable logging +case $(get_setting system.loglevel) in + off|none) + LOG=false + ;; + verbose) + LOG=true + VERBOSE=true + ;; + *) + LOG=true + ;; +esac + +### Prepare to load our emulator and game. +loginit "$1" "$2" "$3" "$4" +clear_screen +bluetooth disable +set_kill stop + +### Determine which emulator we're launching and make appropriate adjustments before launching. +${VERBOSE} && log $0 "Configuring for ${EMULATOR}" +case ${EMULATOR} in + mednafen) + set_kill set "-9 mednafen" + RUNTHIS='${RUN_SHELL} /usr/bin/start_mednafen.sh "${ROMNAME}" "${CORE}" "${PLATFORM}"' + ;; + retroarch) + # Make sure NETWORK_PLAY isn't defined before we start our tests/configuration. + del_setting netplay.mode + + case ${ARGUMENTS} in + *"--host"*) + ${VERBOSE} && log $0 "Setup netplay host." + NETWORK_PLAY="${ARGUMENTS##*--host}" # read from --host onwards + NETWORK_PLAY="${NETWORK_PLAY%%--nick*}" # until --nick is found + NETWORK_PLAY="--host ${NETWORK_PLAY} --nick" + set_setting netplay.mode "host" + ;; + *"--connect"*) + ${VERBOSE} && log $0 "Setup netplay client." + NETWORK_PLAY="${ARGUMENTS##*--connect}" # read from --connect onwards + NETWORK_PLAY="${NETWORK_PLAY%%--nick*}" # until --nick is found + NETWORK_PLAY="--connect ${NETWORK_PLAY} --nick" + set_setting netplay.mode "client" + ;; + *"--netplaymode spectator"*) + ${VERBOSE} && log $0 "Setup netplay spectator." + set_setting "netplay.mode" "spectator" + ;; + esac + + ### Set set_kill to kill the appropriate retroarch + set_kill set "retroarch retroarch32" + + ### Assume we're running 64bit Retroarch + RABIN="retroarch" + + case ${HW_ARCH} in + aarch64) + if [[ "${CORE}" =~ pcsx_rearmed32 ]] || \ + [[ "${CORE}" =~ gpsp ]] || \ + [[ "${CORE}" =~ desmume ]] + then + ### Configure for 32bit Retroarch + ${VERBOSE} && log $0 "Configuring for 32bit cores." + export RABIN="retroarch32" + fi + ;; + esac + + + ### Configure specific emulator requirements + case ${CORE} in + freej2me*) + ${VERBOSE} && log $0 "Setup freej2me requirements." + /usr/bin/freej2me.sh + JAVA_HOME='/storage/jdk' + export JAVA_HOME + PATH="$JAVA_HOME/bin:$PATH" + export PATH + export _JAVA_OPTIONS="-Djava.awt.headless=true" + ;; + easyrpg*) + # easyrpg needs runtime files to be downloaded on the first run + ${VERBOSE} && log $0 "Setup easyrpg requirements." + /usr/bin/easyrpg.sh + ;; + esac + + + RUNTHIS='${EMUPERF} /usr/bin/${RABIN} -L /tmp/cores/${CORE}_libretro.so --config ${RETROARCH_TEMP_CONFIG} --appendconfig ${RETROARCH_APPEND_CONFIG} "${ROMNAME}"' + + CONTROLLERCONFIG="${ARGUMENTS#*--controllers=*}" + + if [[ "${ARGUMENTS}" == *"-state_slot"* ]] + then + CONTROLLERCONFIG="${CONTROLLERCONFIG%% -state_slot*}" # until -state is found + SNAPSHOT="${ARGUMENTS#*-state_slot *}" # -state_slot x + SNAPSHOT="${SNAPSHOT%% -*}" + if [[ "${ARGUMENTS}" == *"-autosave"* ]]; then + CONTROLLERCONFIG="${CONTROLLERCONFIG%% -autosave*}" # until -autosave is found + AUTOSAVE="${ARGUMENTS#*-autosave *}" # -autosave x + AUTOSAVE="${AUTOSAVE%% -*}" + else + AUTOSAVE="" + fi + else + CONTROLLERCONFIG="${CONTROLLERCONFIG%% --*}" # until a -- is found + SNAPSHOT="" + AUTOSAVE="" + fi + + # Configure platform specific requirements + case ${PLATFORM} in + "atomiswave") + rm ${ROMNAME}.nvmem* + ;; + "scummvm") + GAMEDIR=$(cat "${ROMNAME}" | awk 'BEGIN {FS="\""}; {print $2}') + cd "${GAMEDIR}" + RUNTHIS='${RUN_SHELL} /usr/bin/start_scummvm.sh libretro .' + ;; + esac + + ### Configure retroarch + if [ -e "${SET_SETTINGS_TMP}" ] + then + rm -f "${SET_SETTINGS_TMP}" + fi + ${VERBOSE} && log $0 "Execute setsettings (${PLATFORM} ${ROMNAME} ${CORE} --controllers=${CONTROLLERCONFIG} --autosave=${AUTOSAVE} --snapshot=${SNAPSHOT})" + (/usr/bin/setsettings.sh "${PLATFORM}" "${ROMNAME}" "${CORE}" --controllers="${CONTROLLERCONFIG}" --autosave="${AUTOSAVE}" --snapshot="${SNAPSHOT}" >${SET_SETTINGS_TMP}) + + ### If setsettings wrote data in the background, grab it and assign it to EXTRAOPTS + if [ -e "${SET_SETTINGS_TMP}" ] + then + EXTRAOPTS=$(cat ${SET_SETTINGS_TMP}) + rm -f ${SET_SETTINGS_TMP} + ${VERBOSE} && log $0 "Extra Options: ${EXTRAOPTS}" + fi + + if [[ ${EXTRAOPTS} != 0 ]]; then + RUNTHIS=$(echo ${RUNTHIS} | sed "s|--config|${EXTRAOPTS} --config|") + fi + ;; + *) + case ${PLATFORM} in + "setup") + RUNTHIS='${RUN_SHELL} "${ROMNAME}"' + ;; + "gamecube"|"triforce") + RUNTHIS='${RUN_SHELL} /usr/bin/start_dolphin_gc.sh "${ROMNAME}" "${PLATFORM}" "${CORE}"' + ;; + "wii"|"wiiware") + RUNTHIS='${RUN_SHELL} /usr/bin/start_dolphin_wii.sh "${ROMNAME}" "${PLATFORM}" "${CORE}"' + ;; + "ports") + RUNTHIS='${EMUPERF} ${RUN_SHELL} "${ROMNAME}"' + sed -i "/^ACTIVE_GAME=/c\ACTIVE_GAME=\"${ROMNAME}\"" /storage/.config/PortMaster/mapper.txt + sed -i "/^ACTIVE_PLATFORM=/c\ACTIVE_PLATFORM=\"${PLATFORM}\"" /storage/.config/PortMaster/mapper.txt + ;; + "windows") + RUNTHIS='${EMUPERF} ${RUN_SHELL} "${ROMNAME}"' + # Hook into Portmaster control mapping + sed -i "/^ACTIVE_GAME=/c\ACTIVE_GAME=\"${ROMNAME}\"" /storage/.config/PortMaster/mapper.txt + sed -i "/^ACTIVE_PLATFORM=/c\ACTIVE_PLATFORM=\"${PLATFORM}\"" /storage/.config/PortMaster/mapper.txt + ;; + "shell") + RUNTHIS='${RUN_SHELL} "${ROMNAME}"' + ;; + *) + RUNTHIS='${RUN_SHELL} "/usr/bin/start_${CORE%-*}.sh" "${ROMNAME}" "${PLATFORM}"' + ;; + esac + ;; +esac + +### Execution time. +clear_screen +${VERBOSE} && log $0 "executing game: ${ROMNAME}" +${VERBOSE} && log $0 "script to execute: ${RUNTHIS}" + +### Set the cores to use +CORES=$(get_setting "cores" "${PLATFORM}" "${ROMNAME##*/}") +${VERBOSE} && log $0 "Configure big.little (${CORES})" +case ${CORES} in + little) + EMUPERF="${SLOW_CORES}" + ;; + big) + EMUPERF="${FAST_CORES}" + ;; + *) + unset EMUPERF + ;; +esac + +### We need the original system cooling profile later so get it now! +COOLINGPROFILE=$(get_setting cooling.profile) + +### Configure GPU performance mode +GPUPERF=$(get_setting "gpuperf" "${PLATFORM}" "${ROMNAME##*/}") +if [ ! -z ${GPUPERF} ] +then + ${VERBOSE} && log $0 "Set GPU performance to (${GPUPERF})" + gpu_performance_level ${GPUPERF} + get_gpu_performance_level >/tmp/.gpu_performance_level +fi + +if [ "${DEVICE_HAS_FAN}" = "true" ] +then + ### Set any custom fan profile (make this better!) + GAMEFAN=$(get_setting "cooling.profile" "${PLATFORM}" "${ROMNAME##*/}") + if [ ! -z "${GAMEFAN}" ] + then + ${VERBOSE} && log $0 "Set fan profile to (${GAMEFAN})" + set_setting cooling.profile ${GAMEFAN} + systemctl restart fancontrol + fi +fi + +### Display mode for emulation +DISPLAY_MODE=$(get_setting "display_mode" "${PLATFORM}" "${ROMNAME##*/}") +if [ ! -z "${DISPLAY_MODE}" ] && [ "${DISPLAY_MODE}" != "default" ] +then + set_refresh_rate "${DISPLAY_MODE}" +fi + +FORCEPACK=$(get_setting "forcepack" "${PLATFORM}" "${ROMNAME##*/}") +if [ ! -z "${FORCEPACK}" ] && [ "${FORCEPACK}" = "On" ] +then + ${VERBOSE} && log $0 "Enabling panfrost forcepack" + export PAN_MESA_DEBUG=forcepack +fi + +### Offline all but the number of threads we need for this game if configured. +NUMTHREADS=$(get_setting "threads" "${PLATFORM}" "${ROMNAME##*/}") +if [ -n "${NUMTHREADS}" ] && + [ ! ${NUMTHREADS} = "default" ] +then + ${VERBOSE} && log $0 "Configure active cores (${NUMTHREADS})" + onlinethreads ${NUMTHREADS} 0 +fi + +### Set the governor mode for emulation +CPU_GOVERNOR=$(get_setting "cpugovernor" "${PLATFORM}" "${ROMNAME##*/}") +${VERBOSE} && log $0 "Set emulation performance mode to (${CPU_GOVERNOR})" +${CPU_GOVERNOR} + +### Check whether MangoHud is supported and enabled +if [ "${DEVICE_MANGOHUD_SUPPORT}" == "true" ]; then + MANGOHUD_ENABLED=$(get_setting "archr.mangohud.enabled" "${PLATFORM}" "${ROMNAME##*/}") + if [ "${MANGOHUD_ENABLED}" = "1" ]; then + # Enable GPU profiling and MangoHud + gpu_profiling "on" + RUNTHIS="/usr/bin/mangohud ${RUNTHIS}" + ${VERBOSE} && log $0 "Enabling MangoHud" + fi +fi + +# If the rom is a shell script just execute it, useful for DOSBOX and ScummVM scan scripts +if [[ "${ROMNAME}" == *".sh" ]] && [ ! "${PLATFORM}" = "ports" ] && [ ! "${PLATFORM}" = "windows" ]; then + ${VERBOSE} && log $0 "Executing shell script ${ROMNAME}" + "${ROMNAME}" &>>${OUTPUT_LOG} + ret_error=$? +else + ${VERBOSE} && log $0 "Executing $(eval echo ${RUNTHIS})" + eval ${RUNTHIS} &>>${OUTPUT_LOG} + ret_error=$? +fi + +### Switch back to performance mode to clean up +performance + +clear_screen + +### Disable touch on the secondary screen for dual screen devices +if [[ "${DEVICE_HAS_DUAL_SCREEN}" == "true" ]]; then + # Disable touch events for Retroid Pocket devices to prevent focus loss + if [[ "${QUIRK_DEVICE}" == "Retroid Pocket 5" || "${QUIRK_DEVICE}" == "Retroid Pocket Flip2" || "${QUIRK_DEVICE}" == "Retroid Pocket Mini" || "${QUIRK_DEVICE}" == "Retroid Pocket Mini V2" ]]; then + swaymsg input "0:0:generic_ft5x06_(a0)" events disabled + swaymsg input "0:0:generic_ft5x06_(8d)" events disabled + fi +fi + +### Go back to system display mode , if we had specialized mode defined +DISPLAY_MODE=$(get_setting "display_mode" "${PLATFORM}" "${ROMNAME##*/}") +if [ ! -z "${DISPLAY_MODE}" ] && [ "${DISPLAY_MODE}" != "default" ] +then + DISPLAY_MODE=$(get_setting "system.display_mode") + DISPLAY_OUTPUT=$(/usr/bin/wlr-randr | awk 'NR==1{print $1;}') + if [ -z "${DISPLAY_MODE}" ]; then + # if we have no system mode use the displays preferred mode + /usr/bin/wlr-randr --output ${DISPLAY_OUTPUT} --preferred + else + # If we have user specifed system mode set that + set_refresh_rate "${DISPLAY_MODE}" + fi +fi + +### Restore cooling profile. +if [ "${DEVICE_HAS_FAN}" = "true" ] +then + ${VERBOSE} && log $0 "Restore system cooling profile (${COOLINGPROFILE})" + set_setting cooling.profile ${COOLINGPROFILE} + systemctl restart fancontrol & +fi + +### Restore system GPU performance mode +GPUPERF=$(get_setting "system.gpuperf") +if [ ! -z ${GPUPERF} ] +then + ${VERBOSE} && log $0 "Restore system GPU performance mode (${GPUPERF})" + gpu_performance_level ${GPUPERF} & +else + ${VERBOSE} && log $0 "Restore system GPU performance mode (auto)" + gpu_performance_level auto & +fi +rm -f /tmp/.gpu_performance_level 2>/dev/null + +### Reset the number of cores to use. +NUMTHREADS=$(get_setting "system.threads") +${VERBOSE} && log $0 "Restore active threads (${NUMTHREADS})" +if [ -n "${NUMTHREADS}" ] +then + onlinethreads ${NUMTHREADS} 0 & +else + onlinethreads all 1 & +fi + +### Disable GPU profiling +gpu_profiling "off" + +### Backup save games +CLOUD_BACKUP=$(get_setting "cloud.backup") +if [ "${CLOUD_BACKUP}" = "1" ] +then + INETUP=$(/usr/bin/amionline >/dev/null 2>&1) + if [ $? == 0 ] + then + log $0 "backup saves to the cloud." + /usr/bin/run /usr/bin/cloud_backup + fi +fi + +${VERBOSE} && log $0 "Checking errors: ${ret_error} " +if [ "${ret_error}" == "0" ] +then + quit 0 +else + log $0 "exiting with ${ret_error}" + quit 1 +fi diff --git a/projects/ArchR/packages/archr/sources/scripts/say b/projects/ArchR/packages/archr/sources/scripts/say new file mode 100755 index 0000000000..9e4a0a6416 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/say @@ -0,0 +1,22 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +AUDIOTEST=$(ps -ef | grep [p]ipewire) +if [ ! $? = 0 ] +then + PLAYCMD="aplay -q" +else + PLAYCMD="paplay" +fi + +case $1 in + -b) + espeak --stdout "$(battery_percent)%" | ${PLAYCMD} + ;; + *) + espeak --stdout "$*" | ${PLAYCMD} + ;; +esac diff --git a/projects/ArchR/packages/archr/sources/scripts/setemu.sh b/projects/ArchR/packages/archr/sources/scripts/setemu.sh new file mode 100755 index 0000000000..405aad50b9 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/setemu.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2019-present Shanti Gilbert (https://github.com/shantigilbert) + +## workaround for ES performance with big conf files +## This is no longer in use! + +EE_CONF="/storage/.config/system/configs/emuoptions.conf" + +[ ! -f ${EE_CONF} ] && touch ${EE_CONF} + +case "$1" in +"set") + PAT=$(echo "$2" | sed -e 's|\"|\\"|g' | sed -e 's|\[|\\\[|g' | sed -e 's|\]|\\\]|g') + sed -i "/$PAT/d" "${EE_CONF}" + S2=${2} + S3=${3} + shift 2 + if [ "${S3}" != "auto" ]; then + [ ${S3} == "disable" ] && echo "#${S2}=" >> "${EE_CONF}" || echo "${S2}=${@}" >> "${EE_CONF}" + fi + ;; +"get") + PAT=$(echo ${2} | sed -e 's|\"|\\"|g' | sed -e 's|\[|\\\[|g' | sed -e 's|\]|\\\]|g' | sed -e 's|(|\\\(|g' | sed -e 's|)|\\\)|g') + PAT="^${PAT}=(.*)" + EES=$(cat "${EE_CONF}" | grep -oE "${PAT}") + echo "${EES##*=}" + ;; +esac diff --git a/projects/ArchR/packages/archr/sources/scripts/setrootpass b/projects/ArchR/packages/archr/sources/scripts/setrootpass new file mode 100755 index 0000000000..9f063a3462 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/setrootpass @@ -0,0 +1,44 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +ROOTPASS="$1" + +LPC=$(awk -F: '/^root/{print $3}' /storage/.cache/shadow) +CURRENT=$(awk -F: '/^root/{print $2}' /storage/.cache/shadow) + +# Turn it into a usable hash +NEW=$(cryptpw -m sha512 "${ROOTPASS}" 2>/dev/null) + +# Set the root password. +sed -i "s#root:${CURRENT}:${LPC}::::::#root:${NEW}:${LPC}::::::#g" /storage/.cache/shadow 2>/dev/null + +# Create a root user and set the password. +echo -ne "${ROOTPASS}\n${ROOTPASS}\n" | smbpasswd -sa root 2>/dev/null + +# Set the root user and password for SyncThing +syncthing generate --gui-user "root" --gui-password "${ROOTPASS}" >/dev/null 2>&1 + +# Save the password so we can display it in ES +set_setting root.password "${ROOTPASS}" + +# Restart syncthing if it was enabled. +SYNCSTATUS=$(get_setting syncthing.enabled) +SYNCACTIVE=$(systemctl status syncthing | awk '/active/ {print $2}') +if [ "${SYNCSTATUS}" = "1" ] && + [ "${SYNCACTIVE}" = "active" ] +then + systemctl restart syncthing >/dev/null 2>&1 +fi + +# Restart simple-http-server if it is enabled +SIMPLESTATUS=$(get_setting simplehttp.enabled) +SIMPLEACTIVE=$(systemctl status simple-http-server | awk '/active/ {print $2}') +if [ "${SIMPLESTATUS}" = "1" ] && + [ "${SIMPLEACTIVE}" = "active" ] +then + systemctl restart simple-http-server >/dev/null 2>&1 +fi + diff --git a/projects/ArchR/packages/archr/sources/scripts/setsettings.sh b/projects/ArchR/packages/archr/sources/scripts/setsettings.sh new file mode 100755 index 0000000000..3425b997e1 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/setsettings.sh @@ -0,0 +1,1297 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +### +### System configuration variables +### + +SYSTEM_CONFIG="/storage/.config/system/configs/system.cfg" +RETROARCH_PATH="/storage/.config/retroarch" +RETROARCH_CONFIG="${RETROARCH_PATH}/retroarch.cfg" +RETROARCH_TEMPLATE="/usr/config/retroarch/retroarch.cfg" + +ROMS_DIR="/storage/roms" +SNAPSHOTS="${ROMS_DIR}/savestates" +BEZEL_DIR="/storage/roms/bezels" + +TMP_CONFIG="/tmp/.retroarch.cfg" +LOG_DIR="/var/log" +LOG_FILE="exec.log" +LOCK_FILE="/tmp/.retroarch.lock" + +### +### Variables parsed from the command line +### + +PLATFORM=${1,,} +ROM="${2##*/}" +CORE=${3,,} + + +#Autosave +AUTOSAVE="$@" +AUTOSAVE="${AUTOSAVE#*-autosave=*}" +AUTOSAVE="${AUTOSAVE% --*}" + +#Snapshot +SNAPSHOT="$@" +SNAPSHOT="${SNAPSHOT#*--snapshot=*}" + +#Controllers +CONTROLLERS="$@" +CONTROLLERS="${CONTROLLERS#*--controllers=*}" + +### +### Arrays containing various supported/non-supported attributes. +### + +declare -a HAS_CHEEVOS=( arcade + arduboy + atari2600 + atari7800 + atarilynx + cdi + colecovision + cps1 + cps2 + cps3 + dreamcast + famicom + fbn + fds + gamegear + gb + gbh + gba + gbah + gbav + gbc + gbch + gbh + genesis + genh + ggh + intellivision + mastersystem + megacd + megadrive + megadrive-japan + msx + msx2 + n64 + nds + neogeo + neogeocd + nes + nesh + ngp + ngpc + odyssey2 + 3do + pcengine + pcenginecd + pcfx + pokemini + psp + psx + ps2 + saturn + sega32x + segacd + sfc + sg-1000 + snes + snesh + snesmsu1 + supergrafx + supervision + tg16 + tg16cd + vectrex + virtualboy + wonderswan + wonderswancolor +) + +declare -a NO_REWIND=( atomiswave + dreamcast + mame + n64 + naomi + neogeocd + odyssey2 + psp + pspminis + saturn + sega32x + zxspectrum +) + +declare -a NO_RUNAHEAD=( atomiswave + dreamcast + n64 + naomi + neogeocd + psp + saturn + sega32x +) + +declare -a NO_ANALOG=( dreamcast + gc + n64 + nds + ps2 + psp + pspminis + psx + wii + wonderswan + wonderswancolor +) + +declare -a IS_32BIT=( gpsp + pcsx_rearmed +) + +declare -a CORE_RATIOS=( 4/3 + 16/9 + 16/10 + 16/15 + 21/9 + 1/1 + 2/1 + 3/2 + 3/4 + 4/1 + 9/16 + 5/4 + 6/5 + 7/9 + 8/3 + 8/7 + 19/12 + 19/14 + 30/17 + 32/9 + config + squarepixel + core + custom + full +) + +declare -a LANG_CODES=( ["false"]="0" + ["En"]="1" + ["Fr"]="3" + ["Pt"]="49" + ["De"]="5" + ["El"]="30" + ["Es"]="2" + ["Cs"]="8" + ["Da"]="9" + ["Hr"]="11" + ["Hu"]="35" + ["It"]="4" + ["Ja"]="6" + ["Ko"]="12" + ["Nl"]="7" + ["Nn"]="46" + ["Po"]="48" + ["Ro"]="50" + ["Ru"]="51" + ["Sv"]="10" + ["Tr"]="59" + ["Zh"]="13" +) + +### +### Fetch common settings +### + +LOGGING=$(get_setting system.loglevel) +if [ -z "${LOGGING}" ] +then + LOGGING="none" +fi + +### +### Set up +### + +### Create log directory if it doesn't exist +if [ ! -d "${LOG_DIR}" ] +then + mkdir -p ${LOG_DIR} +fi + +if [ -e "${LOCK_FILE}" ] +then + rm -f "${LOCK_FILE}" +fi + +### Clean up temp files +for FILE in ${TMP_CONFIG} ${TMP_CONFIG}.sed +do + if [ -f "${FILE}" ] + then + rm -f "${FILE}" + fi +done + +### +### Core functions +### + +function log() { + if [ ${LOGGING} = "verbose" ] + then + echo "$(printf '%(%c)T\n' -1): setsettings: $*" >> ${LOG_DIR}/${LOG_FILE} 2>&1 + fi +} + +function cleanup() { + log "Work complete" + sync + exit +} + +function game_setting() { + if [ -n "${1}" ] + then + SETTING=$(get_setting "${1}" "${PLATFORM}" "${ROM}") + log "Fetch \"${1}\" \"${PLATFORM}\" \"${ROM}\"] (${SETTING})" + echo ${SETTING} + fi +} + +function clear_setting() { + log "Remove setting [${1}]" + if [ ! -f "${TMP_CONFIG}.sed" ] + then + echo -n 'sed -i "/^'${1}'/d;' >${TMP_CONFIG}.sed + else + echo -n ' /^'${1}'/d;' >>${TMP_CONFIG}.sed + fi +} + +function flush_settings() { + echo -n '" '${RETROARCH_CONFIG}' >/dev/null 2>&1' >>${TMP_CONFIG}.sed + chmod 0755 ${TMP_CONFIG}.sed + ${TMP_CONFIG}.sed >/dev/null 2>&1 ||: + rm -f ${TMP_CONFIG}.sed +} + +function add_setting() { + if [ ! "${1}" = "none" ] + then + local OS_SETTING="$(game_setting ${1})" + fi + local RETROARCH_KEY="${2}" + local RETROARCH_VALUE="${3}" + if [ -z "${RETROARCH_VALUE}" ]& \ + [ ! "${1}" = "none" ] + then + RETROARCH_VALUE="${OS_SETTING}" + fi + clear_setting "${RETROARCH_KEY}" + echo "${RETROARCH_KEY} = \"${RETROARCH_VALUE}\"" >>${TMP_CONFIG} + log "Added setting: ${RETROARCH_KEY} = \"${RETROARCH_VALUE}\"" +} + +function match() { + local seek="${1}" + shift + local myarray=(${@}) + if [[ "${myarray[*]}" =~ ${seek} ]] + then + local MATCH="1" + else + local MATCH="0" + fi + log "Match: [${seek}] [${MATCH}] (${myarray[*]})" + echo ${MATCH} +} + +### +### Game data functions +### + +### Configure retroarch paths +function set_retroarch_paths() { + for RPATH in assets_directory cache_directory \ + cheat_database_path content_database_path \ + content_database_path joypad_autoconfig_dir \ + libretro_directory libretro_info_path \ + overlay_directory video_shader_dir + do + clear_setting "${RPATH}" + done + flush_settings + cat <>${RETROARCH_CONFIG} +assets_directory = "/tmp/assets" +cache_directory = "/tmp/cache" +cheat_database_path = "/tmp/database/cht" +content_database_path = "/tmp/database/rdb" +joypad_autoconfig_dir = "/tmp/joypads" +libretro_directory = "/tmp/cores" +libretro_info_path = "/tmp/cores" +overlay_directory = "/tmp/overlays" +video_shader_dir = "/tmp/shaders" +EOF +} + +### Configure retroarch hotkeys +function configure_hotkeys() { + log "Configure hotkeys..." + local MY_CONTROLLER + if grep -q "js0" /proc/bus/input/devices; then + MY_CONTROLLER=$(grep -b4 js0 /proc/bus/input/devices | awk 'BEGIN {FS="\""}; /Name/ {printf $2}') + else + MY_CONTROLLER=$(grep -b4 joypad /proc/bus/input/devices | awk 'BEGIN {FS="\""}; /Name/ {printf $2}') + fi + + ### Remove any input settings retroarch may have added. + sed -i '/input_player[0-9]/d' ${RETROARCH_CONFIG} + + if [ "$(get_setting system.autohotkeys)" == "1" ] + then + if [ -e "/tmp/joypads/${MY_CONTROLLER}.cfg" ] + then + cp /tmp/joypads/"${MY_CONTROLLER}.cfg" /tmp + sed -i "s# = #=#g" /tmp/"${MY_CONTROLLER}.cfg" + source /tmp/"${MY_CONTROLLER}.cfg" + for HKEYSETTING in input_enable_hotkey_btn input_bind_hold \ + input_exit_emulator_btn input_fps_toggle_btn \ + input_menu_toggle_btn input_save_state_btn \ + input_load_state_btn input_toggle_fast_forward_btn \ + input_toggle_fast_forward_axis input_rewind_axis \ + input_rewind_btn + do + clear_setting "${HKEYSETTING}" + done + flush_settings + if [ -z ${input_enable_hotkey_btn+x} ] + then + echo 'input_enable_hotkey_btn = '\"${input_select_btn}\" >>${RETROARCH_CONFIG} + else + echo 'input_enable_hotkey_btn = '\"${input_enable_hotkey_btn}\" >>${RETROARCH_CONFIG} + fi + cat <>${RETROARCH_CONFIG} +input_bind_hold = "${input_select_btn}" +input_exit_emulator_btn = "${input_start_btn}" +input_fps_toggle_btn = "${input_y_btn}" +input_menu_toggle_btn = "${input_x_btn}" +input_save_state_btn = "${input_r_btn}" +input_load_state_btn = "${input_l_btn}" +EOF + if [ -n "${input_r2_btn}" ] && \ + [ -n "${input_l2_btn}" ] + then + cat <>${RETROARCH_CONFIG} +input_toggle_fast_forward_axis = "nul" +input_toggle_fast_forward_btn = "${input_r2_btn}" +input_rewind_axis = "nul" +input_rewind_btn = "${input_l2_btn}" +EOF + elif [ -n "${input_r2_axis}" ] && \ + [ -n "${input_l2_axis}" ] + then + cat <>${RETROARCH_CONFIG} +input_toggle_fast_forward_axis = "${input_r2_axis}" +input_toggle_fast_forward_btn = "nul" +input_rewind_axis = "${input_l2_axis}" +input_rewind_btn = "nul" +EOF + fi + rm -f /tmp/"${MY_CONTROLLER}.cfg" + fi + fi +} + +function set_ra_menudriver() { + add_setting "retroarch.menu_driver" "menu_driver" + local MENU_DRIVER=$(game_setting retroarch.menu_driver) + case ${MENU_DRIVER} in + rgui) + add_setting "none" "menu_linear_filter" "true" + ;; + esac +} + +function set_fps() { + add_setting "showFPS" "fps_show" +} + +function set_config_save() { + add_setting "config_save_on_exit" "false" +} + +function set_cheevos() { + local USE_CHEEVOS=$(game_setting "retroachievements") + local CHECK_CHEEVOS="$(match "${PLATFORM}" "${HAS_CHEEVOS[@]}")" + if [ "${USE_CHEEVOS}" = 1 ] && \ + [ "${CHECK_CHEEVOS}" = 1 ] + then + add_setting "none" "cheevos_enable" "true" + add_setting "retroachievements.username" "cheevos_username" + add_setting "retroachievements.password" "cheevos_password" + add_setting "none" "cheevos_cmd" "/usr/share/libretro/call_achievements_hooks.sh" + add_setting "retroachievements.hardcore" "cheevos_hardcore_mode_enable" + add_setting "retroachievements.leaderboards" "cheevos_leaderboards_enable" + add_setting "retroachievements.verbose" "cheevos_verbose_enable" + add_setting "retroachievements.screenshot" "cheevos_auto_screenshot" + add_setting "retroachievements.richpresence" "cheevos_richpresence_enable" + add_setting "retroachievements.challengeindicators" "cheevos_challenge_indicators" + add_setting "retroachievements.testunofficial" "cheevos_test_unofficial" + add_setting "retroachievements.badges" "cheevos_badges_enable" + add_setting "retroachievements.active" "cheevos_start_active" + local CHEEVOS_SOUND_ENABLE=$(game_setting "retroachievements.sound") + if [ "${CHEEVOS_SOUND_ENABLE}" != "none" ]; then + add_setting "none" "cheevos_unlock_sound_enable" "true" + add_setting "retroachievements.sound" "cheevos_unlock_sound" + else + add_setting "none" "cheevos_unlock_sound_enable" "false" + fi + else + add_setting "none" "cheevos_enable" "false" + fi +} + +function set_netplay() { + USE_NETPLAY=$(game_setting "netplay") + if [ "${USE_NETPLAY}" = 1 ] + then + add_setting "none" "savestate_auto_load" "false" + add_setting "none" "savestate_auto_save" "false" + add_setting "retroachievements.hardcore" "cheevos_hardcore_mode_enable" "false" + add_setting "global.netplay.nickname" "netplay_nickname" + add_setting "global.netplay.password" "netplay_password" + add_setting "netplay_public_announce" "netplay_public_announce" + local NETPLAY_MODE=$(game_setting "netplay.mode") + local NETPLAY_PORT=$(game_setting "global.netplay.port") + case ${NETPLAY_MODE} in + host) + add_setting "none" "netplay_mode" "false" + add_setting "none" "netplay_client_swap_input" "false" + add_setting "global.netplay.port" "netplay_ip_port" "${NETPLAY_PORT}" + case ${CORE} in + gambatte) + log "Configuring gameboy link server." + if [ ! -d "${RETROARCH_PATH}/config/Gambatte" ] + then + mkdir -p "${RETROARCH_PATH}/config/Gambatte" + fi + local GAMBATTE_CONF="${RETROARCH_PATH}/config/Gambatte/Gambatte.opt" + ### Rework this to use add_setting and be configurable in ES. + sed -i '/gambatte_gb_link_mode/d; \ + /gambatte_gb_link_network_port/d' ${GAMBATTE_CONF} + cat <>${GAMBATTE_CONF} +gambatte_gb_link_mode = "Network Server" +gambatte_gb_link_network_port = "$(( ${NETPLAY_PORT} + 1 ))" +EOF + ;; + tgbdual) + log "Configuring tgbdual for network play" + if [ ! -d "${RETROARCH_PATH}/config/TGB Dual" ] + then + mkdir -p "${RETROARCH_PATH}/config/TGB Dual" + fi + local TGBDUAL_CONF="${RETROARCH_PATH}/config/TGB Dual/TGB Dual.opt" + sed -i '/tgbdual_gblink_enable/d; \ + /tgbdual_single_screen_mp/d; \ + /tgbdual_switch_screens/d; \ + /tgbdual_audio_output/d' "${TGBDUAL_CONF}" + cat <>"${TGBDUAL_CONF}" +tgbdual_gblink_enable = "enabled" +tgbdual_single_screen_mp = "player 1 only" +tgbdual_switch_screens = "normal" +tgbdual_audio_output = "Game Boy #1" +EOF + echo -n " --host" + ;; + genesis_plus_gx) + log "Configure genesis_plus_gx 4 way play." + add_setting "none" "input_libretro_device_p2" "1025" + echo -n " --host" + ;; + + snes9x) + log "Configure snes9x multitap." + add_setting "none" "input_libretro_device_p2" "257" + echo -n " --host" + ;; + *) + echo -n " --host" + ;; + esac + ;; + client) + local NETPLAY_HOST_IP=$(get_setting global.netplay.host) + add_setting "global.netplay.port" "${NETPLAY_PORT}" + if [ ! -z "${NETPLAY_HOST_IP}" ] + then + add_setting "none" "netplay_ip_address" "${NETPLAY_HOST_IP}" + case ${CORE} in + gambatte) + log "Configuring gameboy link client." + if [ ! -d "${RETROARCH_PATH}/config/Gambatte" ] + then + mkdir -p "${RETROARCH_PATH}/config/Gambatte" + fi + add_setting "none" "netplay_mode" "false" + add_setting "none" "netplay_client_swap_input" "false" + local GAMBATTE_CONF="${RETROARCH_PATH}/config/Gambatte/Gambatte.opt" + sed -i '/gambatte_gb_link_mode/d; \ + /gambatte_gb_link_network_port/d' ${GAMBATTE_CONF} + cat <>${GAMBATTE_CONF} +gambatte_gb_link_mode = "Network Client" +gambatte_gb_link_network_port = "$(( ${NETPLAY_PORT} + 1 ))" +EOF + + sed -i '/gambatte_gb_link_network_server_ip_/d' ${GAMBATTE_CONF} + + local IPARRAY=(${NETPLAY_HOST_IP//./ }) + for ELEM in ${IPARRAY[*]} + do + ADDR="${ADDR}$(printf "%03d" "${ELEM}")" + done + + local COUNT=1 + for (( i=0; i<${#ADDR}; i++ )); + do + cat <>${GAMBATTE_CONF} +gambatte_gb_link_network_server_ip_${COUNT} = "${ADDR:$i:1}" +EOF + COUNT=$(( ${COUNT} + 1 )) + done + ;; + tgbdual) + log "Configuring tgbdual for network play" + if [ ! -d "${RETROARCH_PATH}/config/TGB Dual" ] + then + mkdir -p "${RETROARCH_PATH}/config/TGB Dual" + fi + local TGBDUAL_CONF="${RETROARCH_PATH}/config/TGB Dual/TGB Dual.opt" + local PLAYER=$(get_setting wifi.adhoc.id) + if [ -z "${PLAYER}" ] + then + PLAYER=2 + fi + sed -i '/tgbdual_gblink_enable/d; \ + /tgbdual_single_screen_mp/d; \ + /tgbdual_switch_screens/d; \ + /tgbdual_audio_output/d' "${TGBDUAL_CONF}" + cat <"${TGBDUAL_CONF}" +tgbdual_gblink_enable = "enabled" +tgbdual_single_screen_mp = "player ${PLAYER} only" +tgbdual_switch_screens = "normal" +tgbdual_audio_output = "Game Boy #${PLAYER}" +EOF + add_setting "none" "netplay_mode" "true" + add_setting "none" "netplay_client_swap_input" "true" + echo -n " --connect ${NETPLAY_HOST_IP}" + ;; + *) + add_setting "none" "netplay_mode" "true" + add_setting "none" "netplay_client_swap_input" "true" + echo -n " --connect ${NETPLAY_HOST_IP}" + ;; + esac + fi + ;; + esac + local NETPLAY_RELAY=$(game_setting global.netplay.relay) + if [ -n "${NETPLAY_RELAY}" ] + then + case ${NETPLAY_RELAY} in + none|false|0) + add_setting "none" "netplay_use_mitm_server" "false" + ;; + custom) + add_setting "none" "netplay_use_mitm_server" "true" + add_setting "none" "netplay_mitm_server" "${NETPLAY_RELAY}" + add_setting "global.netplay.customserver" "netplay_custom_mitm_server" + ;; + *) + add_setting "none" "netplay_use_mitm_server" "true" + add_setting "none" "netplay_mitm_server" "${NETPLAY_RELAY}" + ;; + esac + else + add_setting "none" "netplay_use_mitm_server" "false" + fi + else + add_setting "none" "netplay" "false" + fi +} + +function set_translation() { + local USE_AI_SERVICE="$(game_setting ai_service_enabled)" + case ${USE_AI_SERVICE} in + 0|false|none) + add_setting "none" "ai_service_enable" "false" + ;; + *) + add_setting "none" "ai_service_enable" "true" + local AI_LANG="$(game_setting ai_target_lang)" + local AI_URL="$(game_setting ai_service_url)" + case ${AI_URL} in + 0|false|none) + add_setting "none" "ai_service_url" "http://ztranslate.net/service?api_key=BATOCERA&mode=Fast&output=png&target_lang=${AI_LANG}" + ;; + *) + add_setting "none" "ai_service_url" "${AI_URL}&mode=Fast&output=png&target_lang=${AI_LANG}" + ;; + esac + ;; + esac +} + +function set_aspectratio() { + local ASPECT_RATIO="$(game_setting ratio)" + case ${ASPECT_RATIO} in + 0|false|none) + add_setting "none" "aspect_ratio_index" "22" + ;; + *) + for AR in ${!CORE_RATIOS[@]} + do + if [ "${CORE_RATIOS[${AR}]}" = "${ASPECT_RATIO}" ] + then + add_setting "none" "aspect_ratio_index" "${AR}" + break + fi + done + ;; + esac +# add_setting "positionx" "custom_viewport_x" +# add_setting "positiony" "custom_viewport_y" +# add_setting "width" "custom_viewport_width" +# add_setting "height" "custom_viewport_height" + add_setting "rotation" "video_rotation" +} + +function set_filtering() { + add_setting "smooth" "video_smooth" +} + +function set_integerscale() { + add_setting "integerscale" "video_scale_integer" + add_setting "integerscaleoverscale" "video_scale_integer_overscale" +} + +function set_rgascale() { + add_setting "rgascale" "video_ctx_scaling" +} + +function set_shader() { + local SHADER="$(game_setting shaderset)" + case ${SHADER} in + 0|false|none) + add_setting "none" "video_shader_enable" "false" + ;; + *) + add_setting "none" "video_shader_enable" "true" + add_setting "none" "video_shader" "${SHADER}" + echo -n " --set-shader /tmp/shaders/${SHADER}" + ;; + esac +} + +function set_filter() { + local FILTER="$(game_setting videofilter)" + case ${FILTER} in + 0|false|none) + add_setting "none" "video_filter" "" + ;; + *) + local FILTER_PATH="/usr/share/retroarch/filters" + add_setting "none" "video_ctx_scaling" "false" + local CHECK_BITNESS="$(match ${CORE} ${IS_32BIT[@]})" + if [ "${CHECK_BITNESS}" = 1 ] + then + BITS="32" + else + BITS="64" + fi + add_setting "none" "video_filter" "${FILTER_PATH}/${BITS}bit/video/${FILTER}" + add_setting "none" "video_filter_dir" "${FILTER_PATH}/${BITS}bit/video/" + add_setting "none" "audio_filter_dir" "${FILTER_PATH}/${BITS}bit/audio" + ;; + esac +} + +function set_overlay() { + local BEZEL="$(game_setting bezel)" + case ${BEZEL} in + 0|false|none) + ;; + *) + write_bezel_config + exit 0 + ;; + esac + + local OVERLAY="$(game_setting overlayset)" + case ${OVERLAY} in + 0|false|none) + add_setting "none" "input_overlay_enable" "false" + add_setting "none" "input_overlay" "" + ;; + *) + local OVERLAY_PATH="/storage/overlays" + add_setting "none" "input_overlay_enable" "true" + add_setting "none" "input_overlay" "${OVERLAY_PATH}/${OVERLAY}" + ;; + esac +} + +function set_rewind() { + local REWIND="$(game_setting rewind)" + case ${REWIND} in + 1) + case $(match ${PLATFORM} ${NO_REWIND[@]}) in + 0) + add_setting "none" "rewind_enable" "true" + ;; + *) + add_setting "none" "rewind_enable" "false" + ;; + esac + ;; + *) + add_setting "none" "rewind_enable" "false" + ;; + esac +} + +function set_savestates() { + local SAVESTATES="$(game_setting incrementalsavestates)" + local MAXINCREMENTALSAVES="$(game_setting maxincrementalsaves)" + case ${SAVESTATES} in + 0|false|none) + add_setting "none" "savestate_auto_index" "false" + ;; + *) + add_setting "none" "savestate_auto_index" "true" + ;; + esac + add_setting "none" "savestate_max_keep" "${MAXINCREMENTALSAVES}" +} + +function set_autosave() { + local SETAUTOSAVE=false + + # argument overrides user setting + case ${AUTOSAVE} in + 0) + SETAUTOSAVE=false + ;; + 1) + SETAUTOSAVE=true + ;; + *) + local AUTOSAVE_SETTING="$(game_setting autosave)" + case ${AUTOSAVE_SETTING} in + [1-3]) + SETAUTOSAVE=true + ;; + esac + ;; + esac + + add_setting "none" "savestate_directory" "${SNAPSHOTS}/${PLATFORM}" + if [ ! -d "${SNAPSHOTS}/${PLATFORM}" ] + then + mkdir "${SNAPSHOTS}/${PLATFORM}" + fi + + if [ ! -z "${SNAPSHOT}" ] + then + add_setting "none" "state_slot" "${SNAPSHOT}" + fi + + add_setting "none" "savestate_auto_load" "${SETAUTOSAVE}" + add_setting "none" "savestate_auto_save" "${SETAUTOSAVE}" +} + +function set_runahead() { + local RUNAHEAD="$(game_setting runahead)" + local HAS_RUNAHEAD="$(match ${PLATFORM} ${NO_RUNAHEAD[@]})" + case ${HAS_RUNAHEAD} in + 1) + add_setting "none" "run_ahead_enabled" "false" + add_setting "none" "run_ahead_frames" "0" + ;; + *) + if [ "${RUNAHEAD}" -gt 0 ] + then + add_setting "none" "run_ahead_enabled" "true" + add_setting "none" "run_ahead_frames" "${RUNAHEAD}" + add_setting "secondinstance" "run_ahead_secondary_instance" + else + add_setting "none" "run_ahead_enabled" "false" + add_setting "none" "run_ahead_frames" "0" + fi + ;; + esac +} + +function set_audiolatency() { + add_setting "audiolatency" "audio_latency" +} + +function set_analogsupport() { + local HAS_ANALOG="$(match ${PLATFORM} ${NO_ANALOG[@]})" + case ${HAS_ANALOG} in + 1) + add_setting "none" "input_player1_analog_dpad_mode" "0" + ;; + *) + add_setting "analogue" "input_player1_analog_dpad_mode" "1" + ;; + esac +} + +function set_tatemode() { + log "Setup tate mode..." + if [ "${CORE}" = "mame2003_plus" ] + then + local TATEMODE="$(game_setting tatemode)" + local MAME2003DIR="${RETROARCH_PATH}/config/MAME 2003-Plus" + local MAME2003REMAPDIR="/storage/remappings/MAME 2003-Plus" + if [ ! -d "${MAME2003DIR}" ] + then + mkdir -p "${MAME2003DIR}" + fi + if [ ! -d "${MAME2003REMAPDIR}" ] + then + mkdir -p "${MAME2003REMAPDIR}" + fi + case ${TATEMODE} in + 1|true) + cp "/usr/config/retroarch/TATE-MAME 2003-Plus.rmp" "${MAME2003REMAPDIR}/MAME 2003-Plus.rmp" + if [ "$(grep mame2003-plus_tate_mode "${MAME2003DIR}/MAME 2003-Plus.opt" > /dev/null 2>&1)" ] + then + sed -i 's#mame2003-plus_tate_mode.*$#mame2003-plus_tate_mode = "enabled"#' "${MAME2003DIR}/MAME 2003-Plus.opt" 2>/dev/null + else + echo 'mame2003-plus_tate_mode = "enabled"' > "${MAME2003DIR}/MAME 2003-Plus.opt" + fi + ;; + *) + if [ -e "${MAME2003DIR}/MAME 2003-Plus.opt" ] + then + sed -i 's#mame2003-plus_tate_mode.*$#mame2003-plus_tate_mode = "disabled"#' "${MAME2003DIR}/MAME 2003-Plus.opt" 2>/dev/null + fi + if [ -e "${MAME2003REMAPDIR}/MAME 2003-Plus.rmp" ] + then + rm -f "${MAME2003REMAPDIR}/MAME 2003-Plus.rmp" + fi + ;; + esac + fi +} + +function set_n64opts() { + log "Set up N64..." + if [ "${CORE}" = "parallel_n64" ] + then + local PARALLELN64DIR="${RETROARCH_PATH}/config/ParaLLEl N64" + if [ ! -d "${PARALLELN64DIR}" ] + then + mkdir -p "${PARALLELN64DIR}" + fi + + if [ ! -f "${PARALLELN64DIR}/ParaLLEl N64.opt" ] + then + cp "/usr/config/retroarch/ParaLLEl N64.opt" "${PARALLELN64DIR}/ParaLLEl N64.opt" + fi + local VIDEO_CORE="$(game_setting parallel_n64_video_core)" + sed -i '/parallel-n64-gfxplugin = /c\parallel-n64-gfxplugin = "'${VIDEO_CORE}'"' "${PARALLELN64DIR}/ParaLLEl N64.opt" + local SCREENSIZE="$(game_setting parallel_n64_internal_resolution)" + sed -i '/parallel-n64-screensize = /c\parallel-n64-screensize = "'${SCREENSIZE}'"' "${PARALLELN64DIR}/ParaLLEl N64.opt" + local GAMESPEED="$(game_setting parallel_n64_gamespeed)" + sed -i '/parallel-n64-framerate = /c\parallel-n64-framerate = "'${GAMESPEED}'"' "${PARALLELN64DIR}/ParaLLEl N64.opt" + local ACCURACY="$(game_setting parallel_n64_gfx_accuracy)" + sed -i '/parallel-n64-gfxplugin-accuracy = /c\parallel-n64-gfxplugin-accuracy = "'${ACCURACY}'"' "${PARALLELN64DIR}/ParaLLEl N64.opt" + local CONTROLLERPAK="$(game_setting parallel_n64_controller_pak)" + sed -i '/parallel-n64-pak1 = /c\parallel-n64-pak1 = "'${CONTROLLERPAK}'"' "${PARALLELN64DIR}/ParaLLEl N64.opt" + fi +} + +function set_saturnopts() { + log "Set up Saturn..." + if [ "${CORE}" = "kronos" ] + then + log "Set up Kronos..." + local KRONOSDIR="${RETROARCH_PATH}/Kronos/config/Kronos" + if [ ! -d "${KRONOSDIR}" ] + then + mkdir -p "${KRONOSDIR}" + fi + + if [ ! -f "${KRONOSDIR}/Kronos.opt" ] + then + cp "/usr/config/retroarch/Kronos.opt" "${KRONOSDIR}/Kronos.opt" + fi + local KRONOSOPT="${KRONOSDIR}/Kronos.opt" + local HLE_BIOS="$(game_setting force_hle_bios)" + sed -i '/kronos_force_hle_bios = /c\kronos_force_hle_bios = "'${HLE_BIOS}'"' "${KRONOSOPT}" + local ADDON_CART="$(game_setting addon_cartridge)" + sed -i '/kronos_addon_cartridge = /c\kronos_addon_cartridge = "'${ADDON_CART}'"' "${KRONOSOPT}" + local TESSELATION="$(game_setting tesselation)" + sed -i '/kronos_polygon_mode = /c\kronos_polygon_mode = "'${TESSELATION}'"' "${KRONOSOPT}" + local RESOLUTION="$(game_setting resolution)" + sed -i '/kronos_resolution_mode = /c\kronos_resolution_mode = "'${RESOLUTION}'"' "${KRONOSOPT}" + local COMPUTE_SHADER="$(game_setting compute_shader)" + sed -i '/kronos_use_cs = /c\kronos_use_cs = "'${COMPUTE_SHADER}'"' "${KRONOSOPT}" + local TRANSPARENCY="$(game_setting transparency)" + sed -i '/kronos_mesh_mode = /c\kronos_mesh_mode = "'${TRANSPARENCY}'"' "${KRONOSOPT}" + fi +} + +function set_snesopts() { + log "Set up SNES..." + if [ "${CORE}" = "beetle_supafaust" ] + then + log "Set up beetle_supafaust" + local FAUSTDIR="${RETROARCH_PATH}/config/Supafaust" + if [ ! -d "${FAUSTDIR}" ] + then + mkdir -p "${FAUSTDIR}" + fi + if [ ! -f "${FAUSTDIR}/Supafaust.opt" ] + then + cp "/usr/config/retroarch/Supafaust.opt" "${FAUSTDIR}/Supafaust.opt" + fi + fi +} + +function set_dreamcastopts() { + log "Set up Dreamcast..." + if [ "${CORE}" = "flycast" ] + then + local FLYCASTDIR="${RETROARCH_PATH}/config/Flycast" + if [ ! -d "${FLYCASTDIR}" ] + then + mkdir -p "${FLYCASTDIR}" + fi + + if [ ! -f "${FLYCASTDIR}/Flycast.opt" ] + then + cp "/usr/config/retroarch/Flycast.opt" "${FLYCASTDIR}/Flycast.opt" + fi + local FRAME_SKIP="$(game_setting frame_skip)" + sed -i '/flycast_auto_skip_frame = /c\flycast_auto_skip_frame = "'${FRAME_SKIP}'"' "${FLYCASTDIR}/Flycast.opt" + fi +} + +function set_melondsdsopts() { + log "Set up melonDS DS..." + if [ "${CORE}" = "melondsds" ] + then + local MELONDSDSDIR="${RETROARCH_PATH}/config/melonDS DS" + if [ ! -d "${MELONDSDSDIR}" ] + then + mkdir -p "${MELONDSDSDIR}" + fi + + if [ ! -f "${MELONDSDSDIR}/melonDS DS.opt" ] + then + cat <"${MELONDSDSDIR}/melonDS DS.opt" +melonds_boot_mode = "direct" +melonds_console_mode = "ds" +melonds_show_cursor = "timeout" +melonds_touch_mode = "auto" +EOF + fi + + if [ "${PLATFORM}" = "ndsiware" ] + then + sed -i '/melonds_console_mode = /c\melonds_console_mode = "dsi"' "${MELONDSDSDIR}/melonDS DS.opt" + else + sed -i '/melonds_console_mode = /c\melonds_console_mode = "ds"' "${MELONDSDSDIR}/melonDS DS.opt" + fi + + if [ "${DEVICE_HAS_TOUCHSCREEN}" = "true" ] + then + sed -i '/melonds_show_cursor = /c\melonds_show_cursor = "disabled"' "${MELONDSDSDIR}/melonDS DS.opt" + sed -i '/melonds_touch_mode = /c\melonds_touch_mode = "touch"' "${MELONDSDSDIR}/melonDS DS.opt" + fi + fi +} + +function set_atari() { + log "Set up Atari (FIXME)..." + if [ "${CORE}" = "atari800" ] + then + ATARICONF="/storage/.config/system/configs/atari800.cfg" + ATARI800CONF="${RETROARCH_PATH}/config/Atari800/Atari800.opt" + if [ ! -f "$ATARI800CONF" ] + then + touch "$ATARI800CONF" + fi + sed -i "/RAM_SIZE=/d" ${ATARICONF} + sed -i "/STEREO_POKEY=/d" ${ATARICONF} + sed -i "/BUILTIN_BASIC=/d" ${ATARICONF} + sed -i "/atari800_system =/d" ${ATARI800CONF} + + if [ "${PLATFORM}" == "atari5200" ]; then + add_setting "none" "atari800_system" "5200" + echo "atari800_system = \"5200\"" >> ${ATARI800CONF} + echo "RAM_SIZE=16" >> ${ATARICONF} + echo "STEREO_POKEY=0" >> ${ATARICONF} + echo "BUILTIN_BASIC=0" >> ${ATARICONF} + else + add_setting "none" "atari800_system" "800XL (64K)" + echo "atari800_system = \"800XL (64K)\"" >> ${ATARI800CONF} + echo "RAM_SIZE=64" >> ${ATARICONF} + echo "STEREO_POKEY=1" >> ${ATARICONF} + echo "BUILTIN_BASIC=1" >> ${ATARICONF} + fi + flush_settings + fi +} + +function set_gambatte() { + log "Set up Gambatte..." + if [ "${CORE}" = "gambatte" ] + then + GAMBATTECONF="${RETROARCH_PATH}/config/Gambatte/Gambatte.opt" + if [ ! -f "GAMBATTECONF" ] + then + echo 'gambatte_gbc_color_correction = "disabled"' > ${GAMBATTECONF} + else + sed -i "/gambatte_gb_colorization =/d" ${GAMBATTECONF} + sed -i "/gambatte_gb_internal_palette =/d" ${GAMBATTECONF} + fi + local COLORIZATION=$(game_setting renderer.colorization) + local TWB1_COLORIZATION=$(game_setting renderer.twb1_colorization) + local TWB2_COLORIZATION=$(game_setting renderer.twb2_colorization) + local TWB3_COLORIZATION=$(game_setting renderer.twb3_colorization) + local PIXELSHIFT1_COLORIZATION=$(game_setting renderer.pixelshift1_colorization) + + if [ -n "${COLORIZATION}" ] + then + case ${COLORIZATION} in + 0|false|none) + echo 'gambatte_gb_colorization = "disabled"' >> ${GAMBATTECONF} + ;; + "Best Guess") + echo 'gambatte_gb_colorization = "auto"' >> ${GAMBATTECONF} + ;; + GBC|SGB) + echo 'gambatte_gb_colorization = "'${COLORIZATION}'"' >> ${GAMBATTECONF} + ;; + *) + echo 'gambatte_gb_colorization = "internal"' >> ${GAMBATTECONF} + echo 'gambatte_gb_internal_palette = "'${COLORIZATION}'"' >> ${GAMBATTECONF} + echo 'gambatte_gb_palette_twb64_1 = "'${TWB1_COLORIZATION}'"' >> ${GAMBATTECONF} + echo 'gambatte_gb_palette_twb64_2 = "'${TWB2_COLORIZATION}'"' >> ${GAMBATTECONF} + echo 'gambatte_gb_palette_twb64_3 = "'${TWB3_COLORIZATION}'"' >> ${GAMBATTECONF} + echo 'gambatte_gb_palette_pixelshift_1 = "'${PIXELSHIFT1_COLORIZATION}'"' >> ${GAMBATTECONF} + ;; + esac + fi + fi +} + +function setup_controllers() { + for i in $(seq 1 1 5) + do + log "Controller setup (${i})" + if [[ "$CONTROLLERS" == *p${i}* ]] + then + PINDEX="${CONTROLLERS#*-p${i}index }" + PINDEX="${PINDEX%% -p${i}guid*}" + log "Set up controller ($i) (${PINDEX})" + add_setting "none" "input_player${i}_joypad_index" "${PINDEX}" + case ${PLATFORM} in + atari5200) + add_setting "none" "input_libretro_device_p${i}" "513" + ;; + esac + fi + done + flush_settings +} + +# Function to write bezel configuration +write_bezel_config() { + RETROARCH_OVERLAY_CONFIG="/tmp/.overlay.cfg" + + local json_output + json_output=$(get_bezel_infos "${ROM}" "${BEZEL}" "${PLATFORM}" "retroarch") + + if [ $? -eq 0 ] && [ -n "$json_output" ]; then + local bezel_png + bezel_png=$(echo "$json_output" | jq -r '.png') + + if [ -n "$bezel_png" ] && [ -f "$bezel_png" ]; then + cat > "$RETROARCH_OVERLAY_CONFIG" << EOF +overlays = 1 +overlay0_overlay = "$bezel_png" +overlay0_full_screen = true +overlay0_descs = 0 +EOF + + add_setting "none" "input_overlay_enable" "true" + add_setting "none" "input_overlay" "${RETROARCH_OVERLAY_CONFIG}" + return 0 + fi + fi + + return 1 +} + +# Function to check bezel file existence +check_bezel_file() { + local base_path="$1" + local file_name="$2" + + if [ -f "${base_path}/${file_name}.png" ]; then + bezel_png="${base_path}/${file_name}.png" + if [ -f "${base_path}/${file_name}.info" ]; then + bezel_info="${base_path}/${file_name}.info" + elif [ -f "${base_path}/default.info" ]; then + bezel_info="${base_path}/default.info" + else + bezel_info="${bezel_png}" + fi + return 0 + fi + return 1 +} + +# Function to check decorations in a directory +check_decorations() { + local base_path="$1" + local system_name="$2" + local rom_name="$3" + + if [ -d "${base_path}/games/${system_name}" ]; then + if check_bezel_file "${base_path}/games/${system_name}" "${rom_name}"; then + specific_to_game="true" + return 0 + fi + fi + + if [ -d "${base_path}/systems" ]; then + if check_bezel_file "${base_path}/systems" "${system_name}"; then + return 0 + fi + fi + + if check_bezel_file "${base_path}" "default"; then + return 0 + fi + + return 1 +} + +# Function to get bezel information +get_bezel_infos() { + local rom="$1" + local bezel="$2" + local system="$3" + local target="$4" + + # Initialize variables + local bezel_info="" + local bezel_png="" + local layout_file="" + local mame_zip="" + local specific_to_game="false" + + # Check parameters + if [ -z "$rom" ] || [ -z "$system" ] || [ -z "$target" ]; then + return 1 + fi + + # Get ROM name without extension + local rom_name=$(basename "${rom}") + rom_name="${rom_name%.*}" + + # Check if bezel parameter is provided + if [ -n "$bezel" ]; then + local bezel_base_path="${BEZEL_DIR}/${bezel}" + + if check_decorations "${bezel_base_path}" "${system}" "${rom_name}"; then + cat << EOF +{ + "png": "$bezel_png", + "info": "${bezel_info}", + "layout": "${layout_file:-null}", + "mamezip": "${mame_zip:-null}", + "specific_to_game": $specific_to_game +} +EOF + return 0 + fi + fi + + return 1 +} + +### +### Execute functions +### + +### +### Functions that must be run without parallelization. +### + +set_retroarch_paths +setup_controllers +configure_hotkeys + +### +### Game specific functions +### + +set_atari & +set_gambatte & + +wait +flush_settings + +### +### Functions that can execute in parallel. +### + +set_ra_menudriver & +set_config_save & +set_fps & +set_cheevos & +set_translation & +set_aspectratio & +set_filtering & +set_integerscale & +set_rgascale & +set_shader & +set_filter & +set_overlay & +set_rewind & +set_savestates & +set_autosave & +set_netplay & +set_runahead & +set_audiolatency & +set_analogsupport & +set_tatemode & +set_n64opts & +set_saturnopts & +set_snesopts & +set_dreamcastopts & +set_melondsdsopts & + +### Sed operations are expensive, so they are staged and executed as +### a single process when all forks complete. +wait +flush_settings + +cleanup diff --git a/projects/ArchR/packages/archr/sources/scripts/show_changelog b/projects/ArchR/packages/archr/sources/scripts/show_changelog new file mode 100755 index 0000000000..98f2598faf --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/show_changelog @@ -0,0 +1,32 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +CHANGELOG="/storage/.cache/changelog" + +if [ ! -e "${CHANGELOG}" ] +then + exit 0 +fi + +WIDTH=$(fbwidth) + +if [ "${WIDTH}" -le "480" ] +then + FONTSIZE=8 +elif [ "${WIDTH}" -gt "480" ] && [ "${WIDTH}" -le "640" ] +then + FONTSIZE=12 +elif [ "${WIDTH}" -gt "640" ] && [ "${WIDTH}" -le "720" ] +then + FONTSIZE=14 +elif [ "${WIDTH}" -gt "720" ] && [ "${WIDTH}" -lt "1080" ] +then + FONTSIZE=20 +else + FONTSIZE=24 +fi + +/usr/bin/text_viewer -f ${FONTSIZE} ${CHANGELOG} diff --git a/projects/ArchR/packages/archr/sources/scripts/suspendmode b/projects/ArchR/packages/archr/sources/scripts/suspendmode new file mode 100755 index 0000000000..9fba960b99 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/suspendmode @@ -0,0 +1,55 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile + +REQUESTED_MODE="${*}" +SUSPEND_MODE=$(get_setting system.suspendmode) + +if [ ! "${REQUESTED_MODE}" = "${SUSPEND_MODE}" ]; then + cat </storage/.config/sleep.conf.d/sleep.conf +[Sleep] +EOF + case ${REQUESTED_MODE} in + off) + cat <>/storage/.config/sleep.conf.d/sleep.conf +AllowSuspend=no +EOF + ;; + freeze) + cat <>/storage/.config/sleep.conf.d/sleep.conf +AllowSuspend=yes +SuspendState=freeze standby mem +EOF + ;; + standby) + cat <>/storage/.config/sleep.conf.d/sleep.conf +AllowSuspend=yes +SuspendState=standby mem freeze +EOF + ;; + mem) + cat <>/storage/.config/sleep.conf.d/sleep.conf +AllowSuspend=yes +SuspendState=mem standby freeze +EOF + ;; + default) + del_setting system.suspendmode + if [ -e "/usr/lib/autostart/quirks/devices/${QUIRK_DEVICE}/030-suspend_mode" ]; then + "/usr/lib/autostart/quirks/devices/${QUIRK_DEVICE}/030-suspend_mode" + elif [ -e "/usr/lib/autostart/quirks/platforms/${HW_DEVICE}/030-suspend_mode" ]; then + "/usr/lib/autostart/quirks/platforms/${HW_DEVICE}/030-suspend_mode" + fi + ;; + *) + cat <>/storage/.config/sleep.conf.d/sleep.conf +AllowSuspend=yes +SuspendState=${REQUESTED_MODE} +EOF + ;; + esac + set_setting system.suspendmode ${1} + systemctl restart systemd-logind +fi diff --git a/projects/ArchR/packages/archr/sources/scripts/timeinfo b/projects/ArchR/packages/archr/sources/scripts/timeinfo new file mode 100755 index 0000000000..8b43dbe090 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/timeinfo @@ -0,0 +1,22 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2020-2022 Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +function get_timezone() { + readlink -f /etc/localtime | sed 's;/usr/share/zoneinfo/;;' +} + +function list_timezones() { + cat /usr/share/zoneinfo/zone1970.tab | grep -v "^#" | awk '{ print $3"," }' | sort -u +} + +case "${1}" in + "current_timezone") + get_timezone + ;; + "timezones") + list_timezones + ;; +esac diff --git a/projects/ArchR/packages/archr/sources/scripts/updateabl b/projects/ArchR/packages/archr/sources/scripts/updateabl new file mode 100755 index 0000000000..691398e31d --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/updateabl @@ -0,0 +1,46 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) +# +# This script will update the ABL on the internal eMMC/UFS. + +. $SYSTEM_ROOT/etc/os-release + +case "$HW_DEVICE" in + SM6115|SM8250|SM8550|SM8650) + ;; + *) + echo "This script is not compatible with this device!" + exit 1 + ;; +esac + +# ---- Sanity checks ---- +ELF="$SYSTEM_ROOT/usr/share/bootloader/archr_abl/abl_signed-${HW_DEVICE}.elf" +if [ ! -f "${ELF}" ]; then + echo "Error: ABL update not found" + exit 1 +fi + +ABL_A="$($SYSTEM_ROOT/usr/sbin/blkid -t PARTLABEL=abl_a -o device)" +ABL_B="$($SYSTEM_ROOT/usr/sbin/blkid -t PARTLABEL=abl_b -o device)" +if [ ! -b "${ABL_A}" ] || [ ! -b "${ABL_B}" ]; then + echo "Error: ABL partitions not found" + exit 1 +fi + +# ---- Get sector size ---- +SS="$($SYSTEM_ROOT/usr/sbin/blockdev --getss "${ABL_A}")" +if [ -z "${SS}" ]; then + echo "Error: failed to get sector size" + exit 1 +fi + +# ---- Flash ---- +echo "Updating ABL partitions..." +dd if="${ELF}" of="${ABL_A}" bs="${SS}" conv=fsync,notrunc status=none +dd if="${ELF}" of="${ABL_B}" bs="${SS}" conv=fsync,notrunc status=none + +sync + +echo "ABL update completed successfully..." diff --git a/projects/ArchR/packages/archr/sources/scripts/usbgadget b/projects/ArchR/packages/archr/sources/scripts/usbgadget new file mode 100755 index 0000000000..5061598517 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/usbgadget @@ -0,0 +1,504 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# gadget setup functions (prepare_usb_network and cleanup_usb_network) are derived from code from +# * https://pastebin.com/VtAusEmf (author unknown) +# * David Lechner https://github.com/ev3dev/ev3-systemd/blob/ev3dev-buster/scripts/ev3-usb.sh +# * rundekugel @github https://github.com/rundekugel/USBGadgetNetwork/blob/main/create-dual-rndis-and-cdcecm.sh + +# For implementation benchmark results, see the end of this file + +. /etc/os-release + +MACHINEIDFILE=/storage/.cache/systemd-machine-id +SERIAL=$(cat ${MACHINEIDFILE}) + +CACHEDIR=/storage/.cache/usbgadget +GADGETCONF=${CACHEDIR}/usbgadget.conf +GADGETNETCONF=${CACHEDIR}/network.conf +UDHCPCONF=/var/run/udhcpd.conf +UDHCPPIDFILE=/var/run/udhcpd.pid + +for mod in usb_f_ncm usb_f_fs; do + modprobe -q ${mod} +done + +mkdir -p ${CACHEDIR} + +if [ -r ${GADGETCONF} ] ; then + . ${GADGETCONF} +fi + +UDC_NAME=$(ls -1 /sys/class/udc |head -n1) +CURRENT_MODE=$(cat /sys/class/udc/${UDC_NAME}/function) +[ -z ${CURRENT_MODE} ] && CURRENT_MODE=disabled + + +usb_disable() { + echo "USB_MODE=disabled" > ${GADGETCONF} + if [[ "${CURRENT_MODE}" == "disabled" ]]; then return; fi + echo "" > /sys/kernel/config/usb_gadget/${CURRENT_MODE}/UDC + CURRENT_MODE=disabled +} + + +is_cable_connected() { + # https://developerhelp.microchip.com/xwiki/bin/view/applications/usb/power-delivery/battery-charging/ + PHY_NAME=$(ls -d /sys/devices/platform/${UDC_NAME}/supplier:platform:*usb2phy | sed 's|^.*:platform:||') + for cable in /sys/devices/platform/${PHY_NAME}/extcon/*/cable.*; do + cable_name="$(cat ${cable}/name)" + case "${cable_name}" in + SDP|CDP) + # Standard Downstream Port and Charging Downstream Port carry data + # these are different types of hub ports, okay for transfer + if grep -q 1 ${cable}/state; then + return 0 + fi + ;; + *) + # Dedicated Charging Port or anything else (derived), + # these do not (reliably) indicate data transfer capability + true + ;; + esac + done + return 1 +} + + +# This function issues soft disconnect and then connect on RK3566 devices +# If gadget is activated with cable unplugged, RK3566 prints 'dwc3 fcc00000.usb: failed to enable ep0out' +# and then host cannot enumerate the gadget. +# Always activating the gadget allows simple setup logic (e.g. start udhcpd immediately), +# and few seconds to soft-disconnect should be OK when done in background +# When cable is plugged, udev calls this function again, and the gadget is soft-connected. +usb_trigger() { + if [[ "${HW_DEVICE}" != "RK3566" ]]; then + return + fi + # do the weird stuff only when ep0 failed + grep -q 'control' /sys/kernel/debug/usb/${UDC_NAME}/ep0out/transfer_type && return + + # initial disconnect takes few seconds, but later it's fast. + # After successful connect, ep0out/transfer_type is control, and we stop doing this stuff + if is_cable_connected; then + CONNECT_CMD=connect + else + CONNECT_CMD=disconnect + fi + if [ "$verbose" -gt "0" ]; then echo "quirk: $1 soft ${CONNECT_CMD} ${UDC_NAME}"; fi + if [[ "$1" == "async" ]]; then + echo ${CONNECT_CMD} > /sys/class/udc/${UDC_NAME}/soft_connect & + else + echo ${CONNECT_CMD} > /sys/class/udc/${UDC_NAME}/soft_connect + fi +} + +############################################# +# code below (prepare_usb_network and cleanup_usb_network) is derived from +# https://github.com/rundekugel/USBGadgetNetwork +# and adapted for ArchR +############################################# +g_cdc="/sys/kernel/config/usb_gadget/cdc" +verbose=${verbose:-0} +devversion=0x$(echo $OS_VERSION | cut -b 3-6) # 0xYYMM; 20241025 -> 0x2410 + +prepare_usb_network() { + set -e + usb_ver="0x0200" # USB 2.0 + dev_class="2" # Communications + attr="0xC0" # Self powered + pwr="0xfe" # + cfg1="CDC" + ms_vendor_code="0xcd" # Microsoft + ms_qw_sign="MSFT100" # also Microsoft (if you couldn't tell) + + if [ -d ${g_cdc} ]; then + if [ "$(cat ${g_cdc}/UDC)" != "" ]; then + if [ "$verbose" -gt "0" ];then echo "Gadget is already up."; fi + exit 1 + fi + if [ "$verbose" -gt "0" ];then echo "Cleaning up old directory..."; fi + cleanup_usb_network + fi + if [ "$verbose" -gt "0" ];then echo "Setting up gadget..."; fi + + # Create a new gadget + + mkdir ${g_cdc} + echo "${usb_ver}" > ${g_cdc}/bcdUSB + echo "${dev_class}" > ${g_cdc}/bDeviceClass + echo "0x1d6b" > ${g_cdc}/idVendor + echo "0x0104" > ${g_cdc}/idProduct + echo "${devversion}" > ${g_cdc}/bcdDevice + mkdir ${g_cdc}/strings/0x409 + echo "${OS_NAME}" > ${g_cdc}/strings/0x409/manufacturer + echo "${QUIRK_DEVICE}" > ${g_cdc}/strings/0x409/product + echo "${SERIAL}" > ${g_cdc}/strings/0x409/serialnumber + + # config 1 is for CDC + + mkdir ${g_cdc}/configs/c.1 + echo "${attr}" > ${g_cdc}/configs/c.1/bmAttributes + echo "${pwr}" > ${g_cdc}/configs/c.1/MaxPower + mkdir ${g_cdc}/configs/c.1/strings/0x409 + echo "${cfg1}" > ${g_cdc}/configs/c.1/strings/0x409/configuration + + # Create the CDC function + + mkdir ${g_cdc}/functions/ncm.usb0 + echo "WINNCM" > ${g_cdc}/functions/ncm.usb0/os_desc/interface.ncm/compatible_id + + echo "1" > ${g_cdc}/os_desc/use + echo "${ms_vendor_code}" > ${g_cdc}/os_desc/b_vendor_code + echo "${ms_qw_sign}" > ${g_cdc}/os_desc/qw_sign + + + smac=$(echo ${SERIAL} | cut -b 1-12) + # Change the first number for each MAC address - the second digit of 2 indicates + # that these are "locally assigned (b2=1), unicast (b1=0)" addresses. This is + # so that they don't conflict with any existing vendors. Care should be taken + # not to change these two bits. + dev_mac="82ba1c9278b1" # Static to make all devices the same network for Windows, switch to "Private" once for all + host_mac="12$(echo ${smac} | cut -b 3-)" + + echo "${dev_mac}" > ${g_cdc}/functions/ncm.usb0/dev_addr + echo "${host_mac}" > ${g_cdc}/functions/ncm.usb0/host_addr + # max_segment_size allows higher MTUs which lead to higher transfer rates and lower CPU usage. + # However it needs some more work to be done as host needs to set high MTU as well + #echo "8000" > ${g_cdc}/functions/ncm.usb0/max_segment_size # f_ncm.c: #define MAX_DATAGRAM_SIZE 8000 + + # Make NCM the first configuration + ln -s ${g_cdc}/functions/ncm.usb0 ${g_cdc}/configs/c.1 + + if [ -n "$verbose" ]; then echo "Done."; fi +} + +configure_iface() { + # Hope udev rule works well, and device gets the name 'gadget' + udevadm wait --timeout=5 --settle /sys/class/net/gadget + IFACE_NAME=$(cat "${g_cdc}/functions/ncm.usb0/ifname") + + OLDIPADDRFILE=${CACHEDIR}/ip_address.conf + if [ ! -f ${GADGETNETCONF} ] ; then + NETMASK="255.255.0.0" + # Migrate old configs + if [ -f "${OLDIPADDRFILE}" ] ; then + IP=$(cat "${OLDIPADDRFILE}") + # if IP has last octed modified, fall back to large netmask + [[ "${IP##*.}" == "2" ]] || NETMASK="255.255.255.0" + fi + [ -z "$IP" ] && IP="169.254.170.2" + + cat < ${GADGETNETCONF} +IP=${IP} +NETMASK=${NETMASK} +# Stupid calculator just subtracting 1 from last octet. +# Combined with /30 subnet only (4*N+2) numbers are valid in last octet +HOSTIP=\${IP%.*}.\$((\${IP##*.}-1)) +EOF + fi + rm -f ${OLDIPADDRFILE} ${CACHEDIR}/udhcpd.conf + + . ${GADGETNETCONF} + + + ip address add ${IP}/${NETMASK} dev ${IFACE_NAME} 2>/dev/null + ip -6 address add fe80::2/64 dev ${IFACE_NAME} scope link 2>/dev/null + ip link set ${IFACE_NAME} up + + cat < ${UDHCPCONF} +interface ${IFACE_NAME} +start ${HOSTIP} +end ${HOSTIP} +opt subnet ${NETMASK} + +# Windows needs some route to "indentify" network, this allows to make connection "private" and accept samba announces +option msstaticroutes 0.0.0.0/32 ${IP} + +opt lease 86400 +max_leases 1 +lease_file /dev/null +pidfile ${UDHCPPIDFILE} +remaining no +EOF + /usr/sbin/udhcpd -S ${UDHCPCONF} +} + + +cleanup_usb_network() { + if [ ! -d ${g_cdc} ]; then + if [ "$verbose" -gt "0" ];then echo "Gadget is already down."; fi + exit 1 + fi + if [ "$verbose" -gt "0" ];then echo "Taking down gadget..."; fi + + # Have to unlink and remove directories in reverse order. + # Checks allow to finish takedown after error. + + if [ "$(cat ${g_cdc}/UDC)" != "" ]; then + echo "" > ${g_cdc}/UDC + fi + rm -f ${g_cdc}/configs/c.1/ncm.usb0 + [ -d ${g_cdc}/functions/ncm.usb0 ] && rmdir ${g_cdc}/functions/ncm.usb0 + [ -d ${g_cdc}/configs/c.1/strings/0x409 ] && rmdir ${g_cdc}/configs/c.1/strings/0x409 + [ -d ${g_cdc}/configs/c.1 ] && rmdir ${g_cdc}/configs/c.1 + [ -d ${g_cdc}/strings/0x409 ] && rmdir ${g_cdc}/strings/0x409 + rmdir ${g_cdc} + + rm -f ${UDHCPCONF} + + if [ -n "$verbose" ]; then echo "Done."; fi +} + + + +g_mtp="/sys/kernel/config/usb_gadget/mtp" + +prepare_usb_mtp() { + usb_ver="0x0200" # USB 2.0 + dev_class="2" # Communications + attr="0xC0" # Self powered + pwr="0xfe" # + + mkdir ${g_mtp} + echo "${usb_ver}" > ${g_mtp}/bcdUSB + echo "${dev_class}" > ${g_mtp}/bDeviceClass + echo "0x1d6b" > ${g_mtp}/idVendor + echo "0x0104" > ${g_mtp}/idProduct + echo "${devversion}" > ${g_mtp}/bcdDevice + mkdir ${g_mtp}/strings/0x409 + echo "${OS_NAME}" > ${g_mtp}/strings/0x409/manufacturer + echo "${QUIRK_DEVICE}" > ${g_mtp}/strings/0x409/product + echo "${SERIAL}" > ${g_mtp}/strings/0x409/serialnumber + + # config 1 for MTP + mkdir ${g_mtp}/configs/c.1 + echo "${attr}" > ${g_mtp}/configs/c.1/bmAttributes + echo "${pwr}" > ${g_mtp}/configs/c.1/MaxPower + mkdir ${g_mtp}/configs/c.1/strings/0x409 + echo mtp > ${g_mtp}/configs/c.1/strings/0x409/configuration + + mkdir ${g_mtp}/functions/ffs.mtp + ln -s ${g_mtp}/functions/ffs.mtp ${g_mtp}/configs/c.1 +} + +cleanup_usb_mtp() { + rm -f \ + ${g_mtp}/configs/c.1/ffs.mtp + + rmdir \ + ${g_mtp}/configs/c.1/strings/0x409 \ + ${g_mtp}/configs/c.1 \ + ${g_mtp}/functions/ffs.mtp \ + ${g_mtp}/strings/0x409 \ + ${g_mtp} +} + +set_role() { + for sw in $(ls -1 /sys/class/udc/${UDC_NAME}/device/usb_role/*/role 2>/dev/null); do + if [ "$verbose" -gt "0" ]; then echo "swithing usb role to $1: $sw"; fi + echo $1 > $sw + done +} + +# USB_MODE is how the gadget was last configured (got from state file) +# CURRENT_MODE is USB gadget subsystem state -- which gadget has UDC +# $1 is desired mode, passed by caller +usb_start() { + if [ "$verbose" -gt "0" ];then echo "STORED=${USB_MODE}, CURRENT=${CURRENT_MODE}, DESIRED=$1"; fi + + # Exit with error if this UDC has a downstream device. Applies to RK3326 where we use a single port + # Switching to device mode in this case would break USB Wifi and USB gamepad + grep -q configured /sys/class/udc/${UDC_NAME}/device/usb1/1-0\:1.0/usb1-port1/state 2>/dev/null && exit 3 + + # with no argument setup previous mode + [[ -n "$1" ]] && USB_MODE=$1 + + # Avoid double start + if [ "${CURRENT_MODE}" == "${USB_MODE}" ]; then + if [ "$verbose" -gt "0" ]; then echo "Already in target mode: ${CURRENT_MODE}; skip"; fi + return + fi + + # This will reset both UDC and userspace when needed + if [ "${CURRENT_MODE}" != "disabled" ]; then + if [ "$verbose" -gt "0" ]; then echo "Stopping previous mode: ${CURRENT_MODE}"; fi + usb_stop + fi + + if [ "${USB_MODE}" == "disabled" ]; then + usb_disable + set_role host + return + else + set_role device + fi + + if [ "${USB_MODE}" = mtp ] ; then + if [ ! -d "${g_mtp}" ]; then + echo "MTP gadget not configured. Run '$0 prepare' first!" >&2 + exit 3 + fi + + mkdir /dev/ffs-umtp + mount mtp -t functionfs /dev/ffs-umtp + /usr/sbin/umtprd & + sleep 1 + + elif [ "${USB_MODE}" = cdc ] ; then + if [ ! -d "${g_cdc}" ]; then + echo "CDC gadget not configured. Run '$0 prepare' first!" >&2 + exit 3 + fi + else + exit 0 + fi + + # Enable selected mode + echo "${UDC_NAME}" > /sys/kernel/config/usb_gadget/${USB_MODE}/UDC + echo "USB_MODE=${USB_MODE}" > ${GADGETCONF} + + [[ "${USB_MODE}" == "cdc" ]] && configure_iface + + # For RK3566 we need to perform a soft disconnect when cable is not plugged + # This leaves network interface available for configuration, and will be re-connected later by udev + usb_trigger async +} + +usb_stop() { + # If there is a role switch, switch to host mode + set_role host + + ( + if [ -f ${UDHCPPIDFILE} ] ; then + cat ${UDHCPPIDFILE} | xargs -r -n 1 kill + fi + + usb_disable + + if [ -d /dev/ffs-umtp ] ; then + umount /dev/ffs-umtp + rmdir /dev/ffs-umtp + + killall umtprd + fi + ) >/dev/null 2>&1 +} + +set_usb_mode() { + case "${1}" in + cdc|mtp) + usb_start "${1}" + ;; + *) + usb_stop + ;; + esac +} + +case "$1" in + prepare) + prepare_usb_network + prepare_usb_mtp + ;; + cleanup) + cleanup_usb_network + cleanup_usb_mtp + ;; + start) + usb_start $2 + ;; + stop) + usb_stop + ;; + trigger) + usb_trigger + ;; + restart) + usb_stop + usb_start $2 + ;; + is_cable_connected) + is_cable_connected + ;; + + # + # API inspired by gpudriver + # + "--options") + echo "disabled network file_transfer" + ;; + "--start") + prepare_usb_network + prepare_usb_mtp + set_usb_mode "${USB_MODE}" + ;; + "") + case ${CURRENT_MODE} in + "cdc") echo "network"; ;; + "mtp") echo "file_transfer"; ;; + *) echo "disabled"; ;; + esac + ;; + "disabled") + usb_stop + ;; + "network") + usb_start cdc + ;; + "file_transfer") + usb_start mtp + ;; + "address") + . ${GADGETNETCONF} + echo ${IP} + ;; + *) + echo "Usage:" + echo "$0 --options List available modes" + echo "$0 --start Restore previously chosen mode" + echo "$0 Show current mode" + echo "$0 disabled Disable USB gadget" + echo "$0 Activate specified mode" + echo "$0 address Show network gadget IP address" + + echo "Deprecated usage: usbgadget [prepare|start|trigger|stop|restart|cleanup|address]" + ;; +esac + + + +# Benchmarks performed by @stolen with RK3326 Linux 6.11.9 as gadget and Linux 6.8.0 as host: +# +# Conditions: +# * performance governor: `echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor` +# * server on gadget: `socat -b 4194304 /dev/null,ignoreeof tcp-listen:2003,fork,reuseaddr` +# * client on host: `dd if=/dev/urandom bs=1M status=progress | nc 10.1.1.2 2003` +# * switch NCM to direct mode: `brctl delif usbnet usb0; ip ad de 10.1.1.2/24 dev usbnet; ip ad ad 10.1.1.2/24 dev usb0` +# * back to bridge mode (restart): `usbgadget cleanup; usbgadget prepare; usbgadget start cdc` +# * switch to rndis: `sudo usb_modeswitch -v 1d6b -p 0104 -u 2` +# * top delay 10 seconds +# +# Measurements: +# * speed: as reported by dd after 90 seconds +# * socat: socat '%CPU' as reported by top +# * idle: total idle as reported by top in '%Cpu(s):' line +# * utilization (after '->'): `(100 - idle) * 4` +# * hidden: `utilization - socat` +# +# Results: +# * NCM direct: speed 30.3, socat 30.8%, idle 77.7% (x4) -> 89.2% (58.4% hidden) +# * NCM bridge: speed 30.4, socat 34.1%, idle 75.5% (x4) -> 98.0% (63.9% hidden) +# * RNDIS direct: speed 35.0, socat 80.3%, idle 55.7% (x4) -> 177.2% (96.9% hidden) +# * RNDIS bridge: speed 34.9, socat 80.2%, idle 54.9% (x4) -> 180.4% (100.2% hidden) +# +# With extra actions to increase MTU (9000 for RNDIS, 7986 for NCM): +# * NCM bridge : speed 35.7, socat 18.7%, idle 82.0% (x4) -> 72.0% (53.3% hidden) +# * NCM direct : speed 36.0, socat 17.5%, idle 83.1% (x4) -> 67.6% (50.1% hidden) +# * RNDIS direct: speed 36.0, socat 25.1%, idle 83.4% (x4) -> 66.4% (41.3% hidden) +# +# High MTU needs more research to announce, so host side sets it on connect without user intervention (via DHCP?) +# See `max_segment_size` for increasing possible MTU on NCM link diff --git a/projects/ArchR/packages/archr/sources/scripts/vertical-check b/projects/ArchR/packages/archr/sources/scripts/vertical-check new file mode 100644 index 0000000000..14f4175576 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/vertical-check @@ -0,0 +1,84 @@ +#!/bin/sh + +. /etc/profile + +ARCADEROMS_XML="/usr/config/emulationstation/resources/arcaderoms.xml" + +RUNEMU_LINE=$(ps aux | grep '[r]unemu.sh' | head -n 1) +CURRENT_CORE=$(echo "${RUNEMU_LINE}" | sed -n 's/.*--core=\([^ ]*\).*/\1/p') +ROM_PATH=$(echo "${RUNEMU_LINE}" | sed -n 's|.*runemu\.sh \([^ ]*\).*|\1|p') + +if [ -z "${CURRENT_CORE}" ] || [ -z "${ROM_PATH}" ]; then + exit 0 +fi + +ROM_NAME=$(basename "${ROM_PATH}" | sed 's/\.[^.]*$//') +IS_VERTICAL=false + +case "${CURRENT_CORE}" in + # Unconditionally vertical + melonds*|desmume|vecx) + IS_VERTICAL=true + ;; + # Might not be vertical + mame*|fbneo|fbalpha*) + if grep -q "id=\"${ROM_NAME}\"[^>]*vert=\"true\"" "${ARCADEROMS_XML}" 2>/dev/null; then + IS_VERTICAL=true + fi + ;; +esac + +case "${ROM_NAME}" in + # Also check for some specific roms that aren't marked vert + punchout*|spnchout*|pc_*|mp_*) + IS_VERTICAL=true + ;; +esac + +if [ "${IS_VERTICAL}" = "true" ]; then + if [ "${QUIRK_DEVICE}" = "AYN Thor" ]; then + # Needs two separate swaymsg calls. Screen cannot move and have windows moved to it in the same line. + swaymsg '[title="RetroArch.*"] output DSI-2 pos 0 0, output DSI-1 pos 340 1080' + swaymsg '[title="RetroArch.*"] floating enable, fullscreen disable, resize set 1240 2160, move to output DSI-2, move absolute position 340 0' + # Additionally fix touch mapping for vertical stack. + swaymsg input "0:0:generic_ft5x06_(8d)" map_to_output DSI-1 + swaymsg -- input "0:0:generic_ft5x06_(8d)" calibration_matrix 0 -1 1 1 0 0 + elif [ "${QUIRK_DEVICE}" = "Anbernic RG DS" ]; then + # Same notes from above apply here. + swaymsg '[title="RetroArch.*"] output DSI-2 pos 0 0, output DSI-1 power on pos 0 480' + swaymsg '[title="RetroArch.*"] floating enable, fullscreen disable, resize set 640 960, move to output DSI-2, move absolute position 0 0' + swaymsg 'input "1046:911:Goodix_Capacitive_TouchScreen" calibration_matrix 1 0 0 0 0.5 0.5' + elif [ "${QUIRK_DEVICE}" = "AYANEO Pocket DS" ]; then + swaymsg output DSI-1 scale 1.40 + swaymsg output DSI-2 transform 270 + swaymsg '[title="RetroArch.*"] output DSI-1 pos 0 0, output DSI-2 power on pos 160 776' + swaymsg '[title="RetroArch.*"] floating enable, fullscreen disable, resize set 1024 1544, move to output DSI-1, move absolute position 160 0' + elif [[ "${QUIRK_DEVICE}" == "Retroid Pocket 5" || "${QUIRK_DEVICE}" == "Retroid Pocket Flip2" || "${QUIRK_DEVICE}" == "Retroid Pocket Mini" || "${QUIRK_DEVICE}" == "Retroid Pocket Mini V2" ]]; then + case "${QUIRK_DEVICE}" in + "Retroid Pocket 5" | "Retroid Pocket Flip2") + DSI_X="0" + RA_WIDTH="1920" + RA_HEIGHT="2160" # 1080 + 1080 + ;; + "Retroid Pocket Mini") + DSI_X="340" + RA_WIDTH="1240" + RA_HEIGHT="2010" # 1080 + 930 + ;; + "Retroid Pocket Mini V2") + DSI_X="340" + RA_WIDTH="1240" + RA_HEIGHT="2160" # 1080 + 1080 + ;; + esac + + # Setup vertical stack using external DP-1 as the top screen. + swaymsg "[title=\"RetroArch.*\"] output DP-1 pos 0 0, output DSI-1 pos ${DSI_X} 1080" + swaymsg "[title=\"RetroArch.*\"] floating enable, fullscreen disable, resize set ${RA_WIDTH} ${RA_HEIGHT}, move to output DP-1, move absolute position ${DSI_X} 0" + + swaymsg input "0:0:generic_ft5x06_(a0)" map_to_output DSI-1 + swaymsg input "0:0:generic_ft5x06_(a0)" events enabled + swaymsg input "0:0:generic_ft5x06_(8d)" map_to_output DSI-1 + swaymsg input "0:0:generic_ft5x06_(8d)" events enabled + fi +fi \ No newline at end of file diff --git a/projects/ArchR/packages/archr/sources/scripts/volume b/projects/ArchR/packages/archr/sources/scripts/volume new file mode 100755 index 0000000000..5a7bd9c708 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/volume @@ -0,0 +1,43 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + + +# Source minimal predefined functions and variables +# to ensure as much performance as possible. +. /etc/profile.d/001-functions + +VOLUME=$(get_setting "audio.volume") +MAX_VOLUME=100 +MIN_VOLUME=0 +STEP=5 + +case ${1} in + "+"|"up") + VOLUME=$(( ${VOLUME} + ${STEP} )) + ;; + "-"|"down") + VOLUME=$(( ${VOLUME} - ${STEP} )) + ;; + "restore") + true + ;; + *) + VOLUME=${1} + ;; +esac + +if (( ${VOLUME} < ${MIN_VOLUME} )) +then + VOLUME=${MIN_VOLUME} +elif (( ${VOLUME} > ${MAX_VOLUME} )) +then + VOLUME=${MAX_VOLUME} +elif [ -z "${VOLUME}" ] +then + VOLUME=50 +fi + +pactl -- set-sink-volume @DEFAULT_SINK@ ${VOLUME}% +set_setting "audio.volume" ${VOLUME} diff --git a/projects/ArchR/packages/archr/sources/scripts/wifictl b/projects/ArchR/packages/archr/sources/scripts/wifictl new file mode 100755 index 0000000000..e04a0886a0 --- /dev/null +++ b/projects/ArchR/packages/archr/sources/scripts/wifictl @@ -0,0 +1,154 @@ +#!/bin/bash +# SPDX-License-Identifier: Apache-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) +# Copyright (C) 2022 kkoshelev (https://github.com/kkoshelev) +# Refactored for iwd (including AP mode) +# Symlink management added for read-only root filesystems. + +. /etc/profile + +### +### Basic WIFI properties used across the tool. +### +### Usage: +### wifictl command [ssid] [psk] +### + +IWD_AP_CFG_DIR="/storage/.cache/iwd/ap" +WIFI_TYPE=$(get_setting wifi.adhoc.enabled) +NETWORK_ADDRESS="192.168.80" +ADHOC_CLIENT_ID=$(get_setting wifi.adhoc.id) +WIFI_DEV="$(ls /sys/class/net | grep -m1 ^wlan)" +DEFAULT_CHAN="6" + +# Exit the script if the WiFi device isn't available +[ -z "${WIFI_DEV}" ] && exit 0 +[ ! -d "/sys/class/net/${WIFI_DEV}" ] && exit 0 + +SSID="${2:-$(get_setting wifi.ssid 2>/dev/null)}" +PSK="${3:-$(get_setting wifi.key 2>/dev/null)}" +COUNTRY="${4:-$(get_setting wifi.country | tr -d '[:space:]' 2>/dev/null)}" + +if [ "${WIFI_TYPE}" = "1" ]; then + SSID="NETPLAY_AP" + PSK="deadbeef" +fi + +ADHOC_CHAN=$(get_setting wifi.adhoc.channel) +if [ -z "${ADHOC_CHAN}" ]; then + ADHOC_CHAN="${DEFAULT_CHAN}" + set_setting wifi.adhoc.channel ${DEFAULT_CHAN} +fi + +### +### Functions... +### + +# Wait for iwd to start and have a device available +wait_for_wifi() { + for i in $(seq 1 5); do + iwctl device list | grep -q "${WIFI_DEV}" && break + sleep 1 + done + [ -n "${COUNTRY}" ] && iw reg set "${COUNTRY}" +} + +# lists all wifi networks +list_wifi() { + wait_for_wifi + /usr/bin/iwd_get-networks +} + +connect_wifi() { + wait_for_wifi + + iwctl device ${WIFI_DEV} set-property Mode station + # Connect to the network. + iwctl --passphrase "${PSK}" station ${WIFI_DEV} connect "${SSID}" 2>/dev/null +} + +create_adhoc() { + wait_for_wifi + + # Create an iwd AP profile file + cat <"${IWD_AP_CFG_DIR}/${SSID}.ap" +[General] +Channel=${ADHOC_CHAN} +DisableHT=true + +[Security] +Passphrase=${PSK} + +[IPv4] +Address=${NETWORK_ADDRESS}.${ADHOC_CLIENT_ID} +Netmask=255.255.255.0 +Gateway=${NETWORK_ADDRESS}.${ADHOC_CLIENT_ID} +EOF + + iwctl device ${WIFI_DEV} set-property Mode ap + # Start the AP profile + iwctl ap ${WIFI_DEV} start-profile "${SSID}" 2>/dev/null +} + +destroy_adhoc() { + iwctl ap ${WIFI_DEV} stop 2>/dev/null + rm -f "${IWD_AP_CFG_DIR}/${SSID}.ap" 2>/dev/null +} + +has_ap_mode() { + wait_for_wifi + + PHY=$(basename "$(readlink /sys/class/net/${WIFI_DEV}/phy80211)") + if iwctl adapter "$PHY" show | grep -q 'SupportedModes.*ap'; then + exit 0 + else + exit 1 + fi +} + +case "${1}" in + enable) + rfkill unblock wifi + ;; + disable) + rfkill block wifi + ;; + connect) + if [ "${WIFI_TYPE}" = "1" ] && \ + [ "${ADHOC_CLIENT_ID}" = "1" ]; then + create_adhoc >/dev/null 2>&1 + else + destroy_adhoc >/dev/null 2>&1 + connect_wifi >/dev/null 2>&1 + fi + ;; + disconnect) + if [ "${WIFI_TYPE}" = "1" ]; then + destroy_adhoc >/dev/null 2>&1 + iwctl ap ${WIFI_DEV} stop 2>/dev/null + else + iwctl station ${WIFI_DEV} disconnect 2>/dev/null + fi + ;; + reconnect) + /usr/bin/wifictl disconnect + /usr/bin/wifictl connect + ;; + list) + list_wifi + ;; + channels) + iw list | awk '/[0-9] MHz \[/ && ! /disabled|radar|no IR/ { gsub(/^.*\[/,""); gsub(/\].*$/,""); print}' + ;; + has_ap_mode) + has_ap_mode + ;; + scan) + iwctl station ${WIFI_DEV} scan 2>/dev/null + ;; + scanlist) + iwctl station ${WIFI_DEV} scan 2>/dev/null + sleep 2 + list_wifi + ;; +esac diff --git a/projects/ArchR/packages/archr/system.d/archr-automount.service b/projects/ArchR/packages/archr/system.d/archr-automount.service new file mode 100644 index 0000000000..9e1df19286 --- /dev/null +++ b/projects/ArchR/packages/archr/system.d/archr-automount.service @@ -0,0 +1,15 @@ +[Unit] +Description=ArchR user autostart script +Before=autostart.service +After=systemd-tmpfiles-setup.service +RequiresMountsFor=/storage + +[Service] +Type=oneshot +Environment=HOME=/storage +EnvironmentFile=/etc/profile +ExecStart=/usr/bin/automount +RemainAfterExit=yes + +[Install] +WantedBy=archr.target diff --git a/projects/ArchR/packages/archr/system.d/archr-memory-manager.service b/projects/ArchR/packages/archr/system.d/archr-memory-manager.service new file mode 100644 index 0000000000..e8a38f66e2 --- /dev/null +++ b/projects/ArchR/packages/archr/system.d/archr-memory-manager.service @@ -0,0 +1,17 @@ +[Unit] +Description=ArchR Memory Manager +After=local-fs.target +DefaultDependencies=no +Conflicts=shutdown.target +Before=shutdown.target + +[Service] +Environment=HOME=/storage +Type=oneshot +ExecStart=/usr/bin/archr-memory-manager --setup +ExecReload=/usr/bin/archr-memory-manager --reload +ExecStop=/usr/bin/archr-memory-manager --stop +RemainAfterExit=yes + +[Install] +WantedBy=basic.target diff --git a/projects/ArchR/packages/archr/system.d/archr-report-stats.service b/projects/ArchR/packages/archr/system.d/archr-report-stats.service new file mode 100644 index 0000000000..b11faf971b --- /dev/null +++ b/projects/ArchR/packages/archr/system.d/archr-report-stats.service @@ -0,0 +1,9 @@ +[Unit] +Description=Report anonymous ArchR install statistics + +[Service] +Type=oneshot +ExecStart=/usr/bin/archr-report-stats + +[Install] +WantedBy=multi-user.target diff --git a/projects/ArchR/packages/archr/system.d/archr-report-stats.timer b/projects/ArchR/packages/archr/system.d/archr-report-stats.timer new file mode 100644 index 0000000000..b99a16d0de --- /dev/null +++ b/projects/ArchR/packages/archr/system.d/archr-report-stats.timer @@ -0,0 +1,8 @@ +[Unit] +Description=Timer to report anonymous ArchR install statistics + +[Timer] +OnBootSec=5min + +[Install] +WantedBy=timers.target diff --git a/projects/ArchR/packages/archr/system.d/archr.target b/projects/ArchR/packages/archr/system.d/archr.target new file mode 100644 index 0000000000..faa1c1d603 --- /dev/null +++ b/projects/ArchR/packages/archr/system.d/archr.target @@ -0,0 +1,9 @@ +[Unit] +Description=archr +Requires=multi-user.target graphical.target +After=graphical.target +Conflicts=rescue.target +AllowIsolate=yes + +[Install] +Alias=default.target diff --git a/projects/ArchR/packages/archr/system.d/bluetooth-agent.service b/projects/ArchR/packages/archr/system.d/bluetooth-agent.service new file mode 100644 index 0000000000..1405e50c2b --- /dev/null +++ b/projects/ArchR/packages/archr/system.d/bluetooth-agent.service @@ -0,0 +1,13 @@ +[Unit] +Description=Start bluetooth agent +After=bluetooth.service +PartOf=bluetooth.service + +[Service] +Type=simple +ExecStart=/usr/bin/archr-bluetooth-agent +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=bluetooth.service diff --git a/projects/ArchR/packages/archr/system.d/hdmi-hotplug.path b/projects/ArchR/packages/archr/system.d/hdmi-hotplug.path new file mode 100644 index 0000000000..183229ed26 --- /dev/null +++ b/projects/ArchR/packages/archr/system.d/hdmi-hotplug.path @@ -0,0 +1,8 @@ +[Unit] +Description=Monitor HDMI status + +[Path] +PathModified=/run/hdmi-status.last + +[Install] +WantedBy=multi-user.target diff --git a/projects/ArchR/packages/archr/system.d/hdmi-hotplug.service b/projects/ArchR/packages/archr/system.d/hdmi-hotplug.service new file mode 100644 index 0000000000..e9a7c32eaa --- /dev/null +++ b/projects/ArchR/packages/archr/system.d/hdmi-hotplug.service @@ -0,0 +1,6 @@ +[Unit] +Description=Handle HDMI hotplug +[Service] +ExecStartPre=/bin/sleep 1 +ExecStart=/usr/bin/handle-hdmi-hotplug +Type=oneshot diff --git a/projects/ArchR/packages/archr/system.d/save-sysconfig.service b/projects/ArchR/packages/archr/system.d/save-sysconfig.service new file mode 100644 index 0000000000..6c27eca17e --- /dev/null +++ b/projects/ArchR/packages/archr/system.d/save-sysconfig.service @@ -0,0 +1,13 @@ +[Unit] +Description=Back up the system config before shutting down +RequiresMountsFor=/storage +DefaultDependencies=no +Before=shutdown.target + +[Service] +Type=oneshot +ExecStart=/usr/bin/chksysconfig backup +TimeoutStartSec=0 + +[Install] +WantedBy=shutdown.target diff --git a/projects/ArchR/packages/archr/system.d/timers.target.wants/rocknix-report-stats.timer b/projects/ArchR/packages/archr/system.d/timers.target.wants/rocknix-report-stats.timer new file mode 120000 index 0000000000..4ae66d6f74 --- /dev/null +++ b/projects/ArchR/packages/archr/system.d/timers.target.wants/rocknix-report-stats.timer @@ -0,0 +1 @@ +../rocknix-report-stats.timer \ No newline at end of file diff --git a/projects/ArchR/packages/archr/udev.d/80-usbgadget.rules b/projects/ArchR/packages/archr/udev.d/80-usbgadget.rules new file mode 100644 index 0000000000..f9e5505bf1 --- /dev/null +++ b/projects/ArchR/packages/archr/udev.d/80-usbgadget.rules @@ -0,0 +1,4 @@ +# trigger for activating gadget after cable is plugged +SUBSYSTEMS=="extcon", ACTION=="change", RUN+="/usr/bin/usbgadget trigger" +# rename gadget interface to avoid ES displaying connected state +ACTION=="add", SUBSYSTEM=="net", ENV{DEVTYPE}=="gadget", NAME="gadget" diff --git a/projects/ArchR/packages/audio/SDL2_mixer/package.mk b/projects/ArchR/packages/audio/SDL2_mixer/package.mk new file mode 100644 index 0000000000..ff0b651519 --- /dev/null +++ b/projects/ArchR/packages/audio/SDL2_mixer/package.mk @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="SDL2_mixer" +PKG_VERSION="2.8.0" +PKG_LICENSE="GPLv3" +PKG_SITE="http://www.libsdl.org/projects/SDL_mixer/release" +PKG_URL="${PKG_SITE}/${PKG_NAME}-${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain fluidsynth opusfile alsa-lib SDL2 libogg libvorbis flac mpg123 libmodplug wavpack libxmp" +PKG_LONGDESC="SDL2 mixer" + +pre_configure_target() { + PKG_CONFIGURE_OPTS_TARGET="${PKG_CONFIGURE_OPTS_TARGET} --enable-music-mp3" +} diff --git a/projects/ArchR/packages/audio/alsa-lib/modprobe.d/alsa-base.conf b/projects/ArchR/packages/audio/alsa-lib/modprobe.d/alsa-base.conf new file mode 100644 index 0000000000..ee4bf79015 --- /dev/null +++ b/projects/ArchR/packages/audio/alsa-lib/modprobe.d/alsa-base.conf @@ -0,0 +1,25 @@ +############################# +# ALSA drivers load options # +############################# + +options snd cards_limit=3 + +# Prevent abnormal drivers from grabbing index 0 +options snd-hda-intel index=1 + +options snd-bt87x index=-2 +options cx88-alsa index=-2 +options saa7134-alsa index=-2 +options snd-atiixp-modem index=-2 +options snd-intel8x0m index=-2 +options snd-via82xx-modem index=-2 +options snd-usb-usx2y index=-2 +options snd-usb-caiaq index=-2 +options snd-cmipci mpu_port=0x330 fm_port=0x388 + +options snd-hda-codec-realtek index=-2 +options snd-hda-codec-hdmi index=-2 + +# fix some Audio Problems with HDMI on ION based Hardware +# see: http://xbmc.org/forum/showthread.php?t=69479 +alias snd-card-0 snd-hda-codec-nvhdmi diff --git a/projects/ArchR/packages/audio/alsa-lib/modprobe.d/intel-audio.conf b/projects/ArchR/packages/audio/alsa-lib/modprobe.d/intel-audio.conf new file mode 100644 index 0000000000..d3198ed205 --- /dev/null +++ b/projects/ArchR/packages/audio/alsa-lib/modprobe.d/intel-audio.conf @@ -0,0 +1,2 @@ +# use legacy hda-intel driver even if a DSP is present +options snd_intel_dspcfg dsp_driver=1 diff --git a/projects/ArchR/packages/audio/alsa-lib/package.mk b/projects/ArchR/packages/audio/alsa-lib/package.mk new file mode 100644 index 0000000000..7649fd03ee --- /dev/null +++ b/projects/ArchR/packages/audio/alsa-lib/package.mk @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="alsa-lib" +PKG_VERSION="1.2.14" +PKG_LICENSE="GPL" +PKG_SITE="http://www.alsa-project.org/" +PKG_URL="https://www.alsa-project.org/files/pub/lib/alsa-lib-${PKG_VERSION}.tar.bz2" +PKG_DEPENDS_TARGET="toolchain alsa-ucm-conf alsa-topology-conf" +PKG_LONGDESC="ALSA (Advanced Linux Sound Architecture) is the next generation Linux Sound API." +PKG_TOOLCHAIN="autotools" +PKG_BUILD_FLAGS="+pic" +PKG_PATCH_DIRS+=" ${DEVICE}" + +if build_with_debug; then + PKG_ALSA_DEBUG=--with-debug +else + PKG_ALSA_DEBUG=--without-debug +fi + +PKG_CONFIGURE_OPTS_TARGET+="${PKG_ALSA_DEBUG} \ + --disable-dependency-tracking \ + --with-plugindir=/usr/lib/alsa \ + --disable-python" + +post_configure_target() { + sed -i 's/.*PKGLIBDIR.*/#define PKGLIBDIR ""/' include/config.h +} + diff --git a/projects/ArchR/packages/audio/alsa-lib/patches/001-silence-underruns.patch b/projects/ArchR/packages/audio/alsa-lib/patches/001-silence-underruns.patch new file mode 100644 index 0000000000..bf4253550c --- /dev/null +++ b/projects/ArchR/packages/audio/alsa-lib/patches/001-silence-underruns.patch @@ -0,0 +1,14 @@ +diff -rupN alsa-lib-1.2.8.orig/src/pcm/pcm.c alsa-lib-1.2.8/src/pcm/pcm.c +--- alsa-lib-1.2.8.orig/src/pcm/pcm.c 2023-02-08 15:16:54.463152310 -0500 ++++ alsa-lib-1.2.8/src/pcm/pcm.c 2023-02-08 15:17:08.347091741 -0500 +@@ -8566,8 +8566,8 @@ int snd_pcm_recover(snd_pcm_t *pcm, int + s = "underrun"; + else + s = "overrun"; +- if (!silent) +- SNDERR("%s occurred", s); ++ //if (!silent) ++ // SNDERR("%s occurred", s); + err = snd_pcm_prepare(pcm); + if (err < 0) { + SNDERR("cannot recovery from %s, prepare failed: %s", s, snd_strerror(err)); diff --git a/projects/ArchR/packages/audio/alsa-lib/patches/SM8250/0001-Enabled-extended-namehints-in-alsa.conf.patch b/projects/ArchR/packages/audio/alsa-lib/patches/SM8250/0001-Enabled-extended-namehints-in-alsa.conf.patch new file mode 100644 index 0000000000..aeba6d016f --- /dev/null +++ b/projects/ArchR/packages/audio/alsa-lib/patches/SM8250/0001-Enabled-extended-namehints-in-alsa.conf.patch @@ -0,0 +1,27 @@ +From 80965d8afd3241017b7dde8dcbd56ab2fd879973 Mon Sep 17 00:00:00 2001 +From: Elimar Riesebieter +Date: Wed, 11 Jan 2017 16:16:14 +0100 +Subject: [PATCH] Enabled extended namehints in alsa.conf + +--- + src/conf/alsa.conf | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +Index: alsa-lib/src/conf/alsa.conf +=================================================================== +--- alsa-lib.orig/src/conf/alsa.conf ++++ alsa-lib/src/conf/alsa.conf +@@ -53,11 +53,11 @@ cards.@hooks [ + # + + # show all name hints also for definitions without hint {} section +-defaults.namehint.showall off ++defaults.namehint.showall on + # show just basic name hints + defaults.namehint.basic on + # show extended name hints +-defaults.namehint.extended off ++defaults.namehint.extended on + # + defaults.ctl.card 0 + defaults.pcm.card 0 diff --git a/projects/ArchR/packages/audio/alsa-lib/patches/SM8550/0001-Enabled-extended-namehints-in-alsa.conf.patch b/projects/ArchR/packages/audio/alsa-lib/patches/SM8550/0001-Enabled-extended-namehints-in-alsa.conf.patch new file mode 100644 index 0000000000..aeba6d016f --- /dev/null +++ b/projects/ArchR/packages/audio/alsa-lib/patches/SM8550/0001-Enabled-extended-namehints-in-alsa.conf.patch @@ -0,0 +1,27 @@ +From 80965d8afd3241017b7dde8dcbd56ab2fd879973 Mon Sep 17 00:00:00 2001 +From: Elimar Riesebieter +Date: Wed, 11 Jan 2017 16:16:14 +0100 +Subject: [PATCH] Enabled extended namehints in alsa.conf + +--- + src/conf/alsa.conf | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +Index: alsa-lib/src/conf/alsa.conf +=================================================================== +--- alsa-lib.orig/src/conf/alsa.conf ++++ alsa-lib/src/conf/alsa.conf +@@ -53,11 +53,11 @@ cards.@hooks [ + # + + # show all name hints also for definitions without hint {} section +-defaults.namehint.showall off ++defaults.namehint.showall on + # show just basic name hints + defaults.namehint.basic on + # show extended name hints +-defaults.namehint.extended off ++defaults.namehint.extended on + # + defaults.ctl.card 0 + defaults.pcm.card 0 diff --git a/projects/ArchR/packages/audio/alsa-lib/patches/alsa-lib-asound.conf_configdir.patch b/projects/ArchR/packages/audio/alsa-lib/patches/alsa-lib-asound.conf_configdir.patch new file mode 100644 index 0000000000..efe2f1ae7c --- /dev/null +++ b/projects/ArchR/packages/audio/alsa-lib/patches/alsa-lib-asound.conf_configdir.patch @@ -0,0 +1,14 @@ +diff --git a/src/conf/alsa.conf b/src/conf/alsa.conf +index a04173a0..1f13fd84 100644 +--- a/src/conf/alsa.conf ++++ b/src/conf/alsa.conf +@@ -11,7 +11,8 @@ + "/usr/etc/alsa/conf.d" + "/etc/alsa/conf.d" + "/etc/asound.conf|||/usr/etc/asound.conf" +- "~/.asoundrc" ++ "/run/asound.conf" ++ "/storage/.config/asound.conf" + { + @func concat + strings [ diff --git a/projects/ArchR/packages/audio/alsa-ucm-conf/package.mk b/projects/ArchR/packages/audio/alsa-ucm-conf/package.mk new file mode 100644 index 0000000000..8f571a1dcc --- /dev/null +++ b/projects/ArchR/packages/audio/alsa-ucm-conf/package.mk @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2020-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="alsa-ucm-conf" +PKG_VERSION="1.2.13" +PKG_LICENSE="BSD-3c" +PKG_SITE="http://www.alsa-project.org/" +PKG_URL="https://www.alsa-project.org/files/pub/lib/alsa-ucm-conf-${PKG_VERSION}.tar.bz2" +PKG_LONGDESC="ALSA Use Case Manager configuration (and topologies)" +PKG_TOOLCHAIN="manual" +PKG_PATCH_DIRS+=" ${DEVICE}" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/share/alsa/ + cp -PR ${PKG_BUILD}/ucm2 ${INSTALL}/usr/share/alsa/ + # work around scripts/build removing empty directories, this leads to errors in ucm + touch ${INSTALL}/usr/share/alsa/ucm2/conf.virt.d/.dont_remove_this_dir +} diff --git a/projects/ArchR/packages/audio/alsa-ucm-conf/patches/001-steamdeck.patch b/projects/ArchR/packages/audio/alsa-ucm-conf/patches/001-steamdeck.patch new file mode 100644 index 0000000000..1f232c2d06 --- /dev/null +++ b/projects/ArchR/packages/audio/alsa-ucm-conf/patches/001-steamdeck.patch @@ -0,0 +1,299 @@ +diff -rupN alsa-ucm-conf.orig/ucm2/conf.d/acp5x/acp5x.conf alsa-ucm-conf/ucm2/conf.d/acp5x/acp5x.conf +--- alsa-ucm-conf.orig/ucm2/conf.d/acp5x/acp5x.conf 1969-12-31 19:00:00.000000000 -0500 ++++ alsa-ucm-conf/ucm2/conf.d/acp5x/acp5x.conf 2023-01-15 22:05:57.605619272 -0500 +@@ -0,0 +1,17 @@ ++Syntax 2 ++ ++Comment "Vangogh internal card" ++ ++SectionUseCase."HiFi" { ++ If.upstream { ++ Condition { ++ Type ControlExists ++ Control "name='Left Analog PCM Volume'" ++ } ++ True.File "HiFi-upstream.conf" ++ False.File "HiFi.conf" ++ } ++ ++ Comment "Default" ++} ++ +diff -rupN alsa-ucm-conf.orig/ucm2/conf.d/acp5x/HiFi.conf alsa-ucm-conf/ucm2/conf.d/acp5x/HiFi.conf +--- alsa-ucm-conf.orig/ucm2/conf.d/acp5x/HiFi.conf 1969-12-31 19:00:00.000000000 -0500 ++++ alsa-ucm-conf/ucm2/conf.d/acp5x/HiFi.conf 2023-01-15 22:05:57.609619224 -0500 +@@ -0,0 +1,140 @@ ++SectionVerb { ++ Value { ++ FullySpecifiedUCM "1" ++ } ++ EnableSequence [ ++ cdev "hw:acp5x" ++ ++ exec "echo Main Verb Config EnableSequence" ++ ++ cset "name='Left DSP Booted' 0" ++ cset "name='Right DSP Booted' 0" ++ cset "name='Left DSP1 Preload Switch' 0" ++ cset "name='Right DSP1 Preload Switch' 0" ++ cset "name='Headphone Volume' 0" ++ cset "name='Digital Playback Volume' 207" ++ cset "name='Frontend PGA Volume' 27" ++ cset "name='ADC Phase Switch' 1" ++ cset "name='BIQ Coefficients' 0x03,0x5a,0x00,0x06,0xfc,0xac,0x00,0x00,0xfe,0x58,0x00,0x00,0x03,0x50,0x00,0x06,0xfe,0x58,0x00,0x08" ++ cset "name='Left AMP PCM Gain' 17" ++ cset "name='Right AMP PCM Gain' 17" ++ cset "name='Left Digital PCM Volume' 817" ++ cset "name='Right Digital PCM Volume' 817" ++ cset "name='Left ASPRX1 Slot Position' 0" ++ cset "name='Left ASPRX2 Slot Position' 1" ++ cset "name='Left DSP RX1 Source' ASPRX1" ++ cset "name='Left DSP RX2 Source' ASPRX1" ++ cset "name='Right ASPRX1 Slot Position' 0" ++ cset "name='Right ASPRX2 Slot Position' 1" ++ cset "name='Right DSP RX1 Source' ASPRX2" ++ cset "name='Right DSP RX2 Source' ASPRX2" ++ ++ cset "name='Left Boost Converter Enable' 2" ++ cset "name='Right DSP RX1 Source' 2" ++ cset "name='Left DSP RX2 Source' 1" ++ ] ++ DisableSequence [ ++ cdev "hw:acp5x" ++ ++ exec "echo Main Verb Config DisableSequence" ++ cset "name='Left DSP Booted' 0" ++ cset "name='Right DSP Booted' 0" ++ cset "name='Left DSP1 Preload Switch' 0" ++ cset "name='Right DSP1 Preload Switch' 0" ++ ] ++} ++ ++SectionDevice."Headphones".0 { ++ Comment "Headphones" ++ ++ Value { ++ PlaybackPriority 200 ++ PlaybackPCM "hw:acp5x,0" ++ JackControl "Headphone Jack" ++ } ++ ConflictingDevice [ ++ ] ++ EnableSequence [ ++ cdev "hw:acp5x" ++ exec "echo Headphones EnableSequence" ++ cset "name='Headphone Switch' on" ++ ] ++ DisableSequence [ ++ cdev "hw:acp5x" ++ exec "echo Headphones DisableSequence" ++ cset "name='Headphone Switch' off" ++ ] ++} ++ ++SectionDevice."Speaker".0 { ++ Comment "Speaker" ++ ++ Value { ++ PlaybackPriority 100 ++ PlaybackPCM "hw:acp5x,1" ++ } ++ ConflictingDevice [ ++ ] ++ EnableSequence [ ++ cdev "hw:acp5x" ++ exec "echo Speaker EnableSequence" ++ cset "name='Left DSP1 Preload Switch' 1" ++ cset "name='Right DSP1 Preload Switch' 1" ++ cset "name='Left AMP Enable Switch' on" ++ cset "name='Right AMP Enable Switch' on" ++ cset "name='Left PCM Source' DSP" ++ cset "name='Right PCM Source' DSP" ++ ] ++ DisableSequence [ ++ cdev "hw:acp5x" ++ exec "echo Speaker DisableSequence" ++ cset "name='Left AMP Enable Switch' off" ++ cset "name='Right AMP Enable Switch' off" ++ ] ++} ++ ++SectionDevice."Internal Mic".0 { ++ Comment "Internal Microphone" ++ ++ Value { ++ CapturePriority 200 ++ CapturePCM "hw:acp5x,0" ++ } ++ ConflictingDevice [ ++ "Headset" ++ ] ++ EnableSequence [ ++ cdev "hw:acp5x" ++ cset "name='Int Mic Switch' on" ++ cset "name='DMIC Enable Switch' on" ++ cset "name='Mic Volume' 252" ++ ] ++ DisableSequence [ ++ cdev "hw:acp5x" ++ cset "name='Int Mic Switch' off" ++ cset "name='DMIC Enable Switch' off" ++ ] ++} ++ ++SectionDevice."Headset" { ++ Comment "Headset Microphone" ++ ++ Value { ++ CapturePriority 300 ++ CapturePCM "hw:acp5x,0" ++ JackControl "Headset Mic Jack" ++ } ++ ConflictingDevice [ ++ "Internal Mic" ++ ] ++ EnableSequence [ ++ cdev "hw:acp5x" ++ cset "name='Headset Mic Switch' on" ++ cset "name='Mic Volume' 200" ++ ] ++ DisableSequence [ ++ cdev "hw:acp5x" ++ cset "name='Headset Mic Switch' off" ++ ] ++} ++ +diff -rupN alsa-ucm-conf.orig/ucm2/conf.d/acp5x/HiFi-upstream.conf alsa-ucm-conf/ucm2/conf.d/acp5x/HiFi-upstream.conf +--- alsa-ucm-conf.orig/ucm2/conf.d/acp5x/HiFi-upstream.conf 1969-12-31 19:00:00.000000000 -0500 ++++ alsa-ucm-conf/ucm2/conf.d/acp5x/HiFi-upstream.conf 2023-01-15 22:05:57.609619224 -0500 +@@ -0,0 +1,130 @@ ++SectionVerb { ++ Value { ++ FullySpecifiedUCM "1" ++ } ++ EnableSequence [ ++ cdev "hw:acp5x" ++ ++ exec "echo Main Verb Config EnableSequence" ++ ++ cset "name='Left DSP1 Preload Switch' 0" ++ cset "name='Right DSP1 Preload Switch' 0" ++ cset "name='Digital Playback Volume' 207" ++ cset "name='Headphone Volume' 0" ++ cset "name='Frontend PGA Volume' 27" ++ cset "name='ADC Phase Switch' 1" ++ cset "name='BIQ Coefficients' 0x03,0x5a,0x00,0x06,0xfc,0xac,0x00,0x00,0xfe,0x58,0x00,0x00,0x03,0x50,0x00,0x06,0xfe,0x58,0x00,0x08" ++ cset "name='Left Analog PCM Volume' 17" ++ cset "name='Right Analog PCM Volume' 17" ++ cset "name='Left Digital PCM Volume' 817" ++ cset "name='Right Digital PCM Volume' 817" ++ cset "name='Left DSP RX1 Source' ASPRX1" ++ cset "name='Left DSP RX2 Source' ASPRX1" ++ cset "name='Right DSP RX1 Source' ASPRX2" ++ cset "name='Right DSP RX2 Source' ASPRX2" ++ ++ cset "name='Right DSP RX1 Source' 2" ++ cset "name='Left DSP RX2 Source' 1" ++ ] ++ DisableSequence [ ++ cdev "hw:acp5x" ++ ++ exec "echo Main Verb Config DisableSequence" ++ cset "name='Left DSP Booted' 0" ++ cset "name='Right DSP Booted' 0" ++ cset "name='Left DSP1 Preload Switch' 0" ++ cset "name='Right DSP1 Preload Switch' 0" ++ ] ++} ++ ++SectionDevice."Headphones".0 { ++ Comment "Headphones" ++ ++ Value { ++ PlaybackPriority 200 ++ PlaybackPCM "hw:acp5x,0" ++ JackControl "Headphone Jack" ++ } ++ ConflictingDevice [ ++ ] ++ EnableSequence [ ++ cdev "hw:acp5x" ++ exec "echo Headphones EnableSequence" ++ cset "name='Headphone Switch' on" ++ ] ++ DisableSequence [ ++ cdev "hw:acp5x" ++ exec "echo Headphones DisableSequence" ++ cset "name='Headphone Switch' off" ++ ] ++} ++ ++SectionDevice."Speaker".0 { ++ Comment "Speaker" ++ ++ Value { ++ PlaybackPriority 100 ++ PlaybackPCM "hw:acp5x,1" ++ } ++ ConflictingDevice [ ++ ] ++ EnableSequence [ ++ cdev "hw:acp5x" ++ exec "echo Speaker EnableSequence" ++ cset "name='Left DSP1 Preload Switch' 1" ++ cset "name='Right DSP1 Preload Switch' 1" ++ cset "name='Left PCM Source' DSP" ++ cset "name='Right PCM Source' DSP" ++ ] ++ DisableSequence [ ++ cdev "hw:acp5x" ++ exec "echo Speaker DisableSequence" ++ cset "name='Left AMP Enable Switch' off" ++ cset "name='Right AMP Enable Switch' off" ++ ] ++} ++ ++SectionDevice."Internal Mic".0 { ++ Comment "Internal Microphone" ++ ++ Value { ++ CapturePriority 200 ++ CapturePCM "hw:acp5x,0" ++ } ++ ConflictingDevice [ ++ "Headset" ++ ] ++ EnableSequence [ ++ cdev "hw:acp5x" ++ cset "name='Int Mic Switch' on" ++ cset "name='DMIC Enable Switch' on" ++ cset "name='Mic Volume' 252" ++ ] ++ DisableSequence [ ++ cdev "hw:acp5x" ++ cset "name='Int Mic Switch' off" ++ cset "name='DMIC Enable Switch' off" ++ ] ++} ++ ++SectionDevice."Headset" { ++ Comment "Headset Microphone" ++ ++ Value { ++ CapturePriority 300 ++ CapturePCM "hw:acp5x,0" ++ JackControl "Headset Mic Jack" ++ } ++ ConflictingDevice [ ++ "Internal Mic" ++ ] ++ EnableSequence [ ++ cdev "hw:acp5x" ++ cset "name='Headset Mic Switch' on" ++ cset "name='Mic Volume' 200" ++ ] ++ DisableSequence [ ++ cdev "hw:acp5x" ++ cset "name='Headset Mic Switch' off" ++ ] ++} diff --git a/projects/ArchR/packages/audio/alsa-ucm-conf/patches/H700/0002_Add-Allwinner-H616-configuration.patch b/projects/ArchR/packages/audio/alsa-ucm-conf/patches/H700/0002_Add-Allwinner-H616-configuration.patch new file mode 100644 index 0000000000..f6b824464e --- /dev/null +++ b/projects/ArchR/packages/audio/alsa-ucm-conf/patches/H700/0002_Add-Allwinner-H616-configuration.patch @@ -0,0 +1,85 @@ +From eccc3536e12a86434ced1529fcad5bbbb280ffeb Mon Sep 17 00:00:00 2001 +From: Ryan Walklin +Date: Sat, 21 Dec 2024 23:01:14 +1300 +Subject: [PATCH] sun4i-codec: add routing for headphones and internal speaker + +The sun4i-codec kernel driver covers a large number of Allwinner SoCs. +The H616 codec has a single line-out route, which is used in concert +with a Toshiba mux chip to send audio to either an internal speaker or +headphone jack on a number of Anbernic handheld gaming devices. + +Add a UCM configuration to allow enabling/disabling the speaker amp +depending on whether headphones are in use or not. + +Signed-off-by: Ryan Walklin +--- + ucm2/Allwinner/sun4i-h616/HiFi.conf | 35 +++++++++++++++++++ + ucm2/conf.d/sun4i-codec/h616-audio-codec.conf | 8 +++++ + 2 files changed, 43 insertions(+) + create mode 100644 ucm2/Allwinner/sun4i-h616/HiFi.conf + create mode 100644 ucm2/conf.d/sun4i-codec/h616-audio-codec.conf + +diff --git a/ucm2/Allwinner/sun4i-h616/HiFi.conf b/ucm2/Allwinner/sun4i-h616/HiFi.conf +new file mode 100644 +index 00000000..2cb9a31f +--- /dev/null ++++ b/ucm2/Allwinner/sun4i-h616/HiFi.conf +@@ -0,0 +1,40 @@ ++SectionDevice."Speaker" { ++ Comment "Internal Speaker" ++ ++ EnableSequence [ ++ cset "name='DAC Playback Volume' 63" ++ cset "name='Speaker Switch' on" ++ ] ++ ++ Value { ++ PlaybackMixerElem "Line Out" ++ PlaybackPCM "hw:${CardId},0" ++ } ++ ++ DisableSequence [ ++ cset "name='Speaker Switch' off" ++ ] ++ ++ ConflictingDevice [ ++ "Headphones" ++ ] ++} ++ ++ ++SectionDevice."Headphones" { ++ Comment "Headphones" ++ ++ EnableSequence [ ++ cset "name='DAC Playback Volume' 63" ++ ] ++ ++ Value { ++ PlaybackMixerElem "Line Out" ++ PlaybackPCM "hw:${CardId},0" ++ JackControl "Headphone Jack" ++ } ++ ++ ConflictingDevice [ ++ "Speaker" ++ ] ++} +diff --git a/ucm2/conf.d/sun4i-codec/h616-audio-codec.conf b/ucm2/conf.d/sun4i-codec/h616-audio-codec.conf +new file mode 100644 +index 00000000..240f41ab +--- /dev/null ++++ b/ucm2/conf.d/sun4i-codec/h616-audio-codec.conf +@@ -0,0 +1,12 @@ ++# UCM for Allwinner H616 Codec ++ ++Syntax 3 ++ ++SectionUseCase."HiFi" { ++ File "/Allwinner/sun4i-h616/HiFi.conf" ++ Comment "Play HiFi quality Music" ++} ++ ++FixedBootSequence [ ++ cset "name='DAC Playback Switch' on" ++] diff --git a/projects/ArchR/packages/audio/alsa-ucm-conf/patches/RK3326/0001_fix_speaker_when_booting_with_headphones.patch b/projects/ArchR/packages/audio/alsa-ucm-conf/patches/RK3326/0001_fix_speaker_when_booting_with_headphones.patch new file mode 100644 index 0000000000..c163d7dc1c --- /dev/null +++ b/projects/ArchR/packages/audio/alsa-ucm-conf/patches/RK3326/0001_fix_speaker_when_booting_with_headphones.patch @@ -0,0 +1,13 @@ +--- a/ucm2/Rockchip/rk817-sound/HiFi.conf.orig 2025-12-16 23:07:38.584854260 +0000 ++++ b/ucm2/Rockchip/rk817-sound/HiFi.conf 2025-12-16 23:08:28.880964760 +0000 +@@ -15,6 +15,10 @@ + SectionDevice."Speaker".DisableSequence [ + cset "name='Internal Speakers Switch' off" + ] ++ ++ SectionDevice."Headphones".EnableSequence [ ++ cset "name='Internal Speakers Switch' off" ++ ] + } + } + diff --git a/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SDM845/0001-Add-Odin-configuration.patch b/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SDM845/0001-Add-Odin-configuration.patch new file mode 100755 index 0000000000..9184102e1e --- /dev/null +++ b/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SDM845/0001-Add-Odin-configuration.patch @@ -0,0 +1,142 @@ +From 1839c307004f9608fa47bc305a524964a03bfaaa Mon Sep 17 00:00:00 2001 +From: Teguh Sobirin +Date: Thu, 30 Jun 2022 22:23:34 +0700 +Subject: [PATCH] Add Odin configuration + +--- + ucm2/Odin/HiFi.conf | 82 +++++++++++++++++++ + ucm2/Odin/Odin.conf | 6 ++ + .../AYNTechnologiesCo.Ltd.-OdinBase-odin.conf | 1 + + .../AYNTechnologiesCo.Ltd.-OdinPro-odin.conf | 1 + + 4 files changed, 90 insertions(+) + create mode 100644 ucm2/Odin/HiFi.conf + create mode 100644 ucm2/Odin/Odin.conf + create mode 120000 ucm2/conf.d/sdm845/AYNTechnologiesCo.Ltd.-OdinBase-odin.conf + create mode 120000 ucm2/conf.d/sdm845/AYNTechnologiesCo.Ltd.-OdinPro-odin.conf + +diff --git a/ucm2/Odin/HiFi.conf b/ucm2/Odin/HiFi.conf +new file mode 100644 +index 0000000..6e432c1 +--- /dev/null ++++ b/ucm2/Odin/HiFi.conf +@@ -0,0 +1,82 @@ ++SectionVerb { ++ ++ EnableSequence [ ++ cset "name='SLIMBUS_0_RX Audio Mixer MultiMedia1' 1" ++ cset "name='SLIM RX1 MUX' AIF1_PB" ++ cset "name='SLIM RX2 MUX' AIF1_PB" ++ cset "name='SLIM RX6 MUX' ZERO" ++ cset "name='SLIM RX7 MUX' ZERO" ++ cset "name='SLIM RX3 MUX' ZERO" ++ cset "name='SLIM RX4 MUX' ZERO" ++ cset "name='SLIM RX5 MUX' ZERO" ++ cset "name='AIF1_CAP Mixer SLIM TX0' 1" ++ cset "name='RX INT7_1 MIX1 INP0' RX1" ++ cset "name='RX INT8_1 MIX1 INP0' RX2" ++ cset "name='RX INT1_2 MUX' RX1" ++ cset "name='RX INT2_2 MUX' RX2" ++ cset "name='CDC_IF TX0 MUX' DEC0" ++ cset "name='SpkrLeft COMP Switch' 1" ++ cset "name='SpkrLeft BOOST Switch' 1" ++ cset "name='SpkrLeft DAC Switch' 1" ++ cset "name='SpkrLeft VISENSE Switch' 0" ++ cset "name='SpkrRight COMP Switch' 1" ++ cset "name='SpkrRight BOOST Switch' 1" ++ cset "name='SpkrRight DAC Switch' 1" ++ cset "name='SpkrRight VISENSE Switch' 0" ++ ] ++ ++ DisableSequence [ ++ cset "name='RX INT7_1 MIX1 INP0' ZERO" ++ cset "name='RX INT8_1 MIX1 INP0' ZERO" ++ cset "name='RX INT1_2 MUX' ZERO" ++ cset "name='RX INT2_2 MUX' ZERO" ++ cset "name='CDC_IF TX0 MUX' ZERO" ++ cset "name='SLIMBUS_0_RX Audio Mixer MultiMedia1' 0" ++ ] ++ ++ Value { ++ TQ "HiFi" ++ } ++} ++ ++SectionDevice."Speaker" { ++ Comment "Speaker playback" ++ ++ EnableSequence [ ++ cset "name='COMP7 Switch' 1" ++ cset "name='COMP8 Switch' 1" ++ cset "name='RX7 Digital Volume' 120" ++ cset "name='RX8 Digital Volume' 120" ++ cset "name='SpkrLeft COMP Switch' 1" ++ cset "name='SpkrLeft BOOST Switch' 1" ++ cset "name='SpkrLeft DAC Switch' 1" ++ cset "name='SpkrLeft VISENSE Switch' 0" ++ cset "name='SpkrLeft PA Volume' 5" ++ cset "name='SpkrRight COMP Switch' 1" ++ cset "name='SpkrRight BOOST Switch' 1" ++ cset "name='SpkrRight DAC Switch' 1" ++ cset "name='SpkrRight VISENSE Switch' 0" ++ cset "name='SpkrRight PA Volume' 5" ++ ] ++ ++ DisableSequence [ ++ cset "name='SpkrLeft COMP Switch' 0" ++ cset "name='SpkrLeft BOOST Switch' 0" ++ cset "name='SpkrLeft DAC Switch' 0" ++ cset "name='SpkrLeft VISENSE Switch' 0" ++ cset "name='SpkrRight COMP Switch' 0" ++ cset "name='SpkrRight BOOST Switch' 0" ++ cset "name='SpkrRight DAC Switch' 0" ++ cset "name='SpkrRight VISENSE Switch' 0" ++ cset "name='RX7 Digital Volume' 0" ++ cset "name='RX8 Digital Volume' 0" ++ cset "name='COMP7 Switch' 0" ++ cset "name='COMP8 Switch' 0" ++ ] ++ ++ Value { ++ PlaybackPriority 100 ++ PlaybackPCM "hw:${CardId},0" ++ PlaybackChannels 2 ++ } ++} +diff --git a/ucm2/Odin/Odin.conf b/ucm2/Odin/Odin.conf +new file mode 100644 +index 0000000..ceba910 +--- /dev/null ++++ b/ucm2/Odin/Odin.conf +@@ -0,0 +1,6 @@ ++Syntax 3 ++ ++SectionUseCase."HiFi" { ++ File "/Odin/HiFi.conf" ++ Comment "HiFi quality Music." ++} +diff --git a/ucm2/conf.d/sdm845/AYNTechnologiesCo.Ltd.-OdinBase-odin.conf b/ucm2/conf.d/sdm845/AYNTechnologiesCo.Ltd.-OdinBase-odin.conf +new file mode 120000 +index 0000000..1a8d968 +--- /dev/null ++++ b/ucm2/conf.d/sdm845/AYNTechnologiesCo.Ltd.-OdinBase-odin.conf +@@ -0,0 +1 @@ ++../../Odin/Odin.conf +\ No newline at end of file +diff --git a/ucm2/conf.d/sdm845/AYNTechnologiesCo.Ltd.-OdinPro-odin.conf b/ucm2/conf.d/sdm845/AYNTechnologiesCo.Ltd.-OdinPro-odin.conf +new file mode 120000 +index 0000000..1a8d968 +--- /dev/null ++++ b/ucm2/conf.d/sdm845/AYNTechnologiesCo.Ltd.-OdinPro-odin.conf +@@ -0,0 +1 @@ ++../../Odin/Odin.conf +\ No newline at end of file +diff --git a/ucm2/conf.d/sdm845/ayn-AYNOdin-.conf b/ucm2/conf.d/sdm845/ayn-AYNOdin-.conf +new file mode 120000 +index 0000000..1a8d968 +--- /dev/null ++++ b/ucm2/conf.d/sdm845/ayn-AYNOdin-.conf +@@ -0,0 +1 @@ ++../../Odin/Odin.conf +\ No newline at end of file +-- +2.34.1 diff --git a/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8250/0002_Add-Retroid-Pocket-SM8250-configuration.patch b/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8250/0002_Add-Retroid-Pocket-SM8250-configuration.patch new file mode 100755 index 0000000000..77f4674a93 --- /dev/null +++ b/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8250/0002_Add-Retroid-Pocket-SM8250-configuration.patch @@ -0,0 +1,184 @@ +From eae9ef3f5aed6679ac743e1a7314a7ff1d10f815 Mon Sep 17 00:00:00 2001 +From: Teguh Sobirin +Date: Wed, 9 Oct 2024 18:21:07 +0800 +Subject: [PATCH] Add Retroid Pocket SM8250 configuration + +--- + ucm2/Qualcomm/sm8250/HiFi-RP.conf | 67 +++++++++++++++++++ + ucm2/Qualcomm/sm8250/RetroidPocket.conf | 22 ++++++ + ucm2/codecs/wsa881x/init.conf | 12 ++++ + ucm2/conf.d/sm8250/RetroidPocket.conf | 1 + + .../sm8250/retroidpocket-RetroidPocket5-.conf | 1 + + .../retroidpocket-RetroidPocketFlip2-.conf | 1 + + .../retroidpocket-RetroidPocketMini-.conf | 1 + + .../retroidpocket-RetroidPocketMiniV2-.conf | 1 + + 8 files changed, 106 insertions(+) + create mode 100644 ucm2/Qualcomm/sm8250/HiFi-RP.conf + create mode 100644 ucm2/Qualcomm/sm8250/RetroidPocket.conf + create mode 100644 ucm2/codecs/wsa881x/init.conf + create mode 120000 ucm2/conf.d/sm8250/RetroidPocket.conf + create mode 120000 ucm2/conf.d/sm8250/retroidpocket-RetroidPocket5-.conf + create mode 120000 ucm2/conf.d/sm8250/retroidpocket-RetroidPocketFlip2-.conf + create mode 120000 ucm2/conf.d/sm8250/retroidpocket-RetroidPocketMini-.conf + create mode 120000 ucm2/conf.d/sm8250/retroidpocket-RetroidPocketMiniV2-.conf + +diff --git a/ucm2/Qualcomm/sm8250/HiFi-RP.conf b/ucm2/Qualcomm/sm8250/HiFi-RP.conf +new file mode 100644 +index 0000000..4a6c0a7 +--- /dev/null ++++ b/ucm2/Qualcomm/sm8250/HiFi-RP.conf +@@ -0,0 +1,65 @@ ++# Use case configuration for RetroidPocket 5 and Mini. ++# Author: Teguh Sobirin ++ ++SectionVerb { ++ ++ EnableSequence [ ++ cset "name='RX_CODEC_DMA_RX_0 Audio Mixer MultiMedia1' 1" ++ cset "name='WSA_CODEC_DMA_RX_0 Audio Mixer MultiMedia2' 1" ++ cset "name='MultiMedia3 Mixer TX_CODEC_DMA_TX_3' 1" ++ ] ++ ++ Value { ++ TQ "HiFi" ++ } ++} ++ ++SectionDevice."Headphones" { ++ Comment "Headphones Playback" ++ ++ Include.wcdhpe.File "/codecs/wcd938x/HeadphoneEnableSeq.conf" ++ Include.wcdhpd.File "/codecs/wcd938x/HeadphoneDisableSeq.conf" ++ Include.rxmhpe.File "/codecs/qcom-lpass/rx-macro/HeadphoneEnableSeq.conf" ++ Include.rxmhpd.File "/codecs/qcom-lpass/rx-macro/HeadphoneDisableSeq.conf" ++ ++ Value { ++ PlaybackPriority 200 ++ PlaybackPCM "hw:${CardId},0" ++ PlaybackMixer "default:${CardId}" ++ PlaybackMixerElem "HP" ++ JackControl "Headphone Jack" ++ JackHWMute "Speaker" ++ } ++} ++ ++SectionDevice."Speaker" { ++ Comment "Speaker Playback" ++ ++ Include.wsamspke.File "/codecs/qcom-lpass/wsa-macro/SpeakerEnableSeq.conf" ++ Include.wsamspkd.File "/codecs/qcom-lpass/wsa-macro/SpeakerDisableSeq.conf" ++ Include.wsaspke.File "/codecs/wsa881x/SpeakerEnableSeq.conf" ++ Include.wsaspkd.File "/codecs/wsa881x/SpeakerDisableSeq.conf" ++ ++ Value { ++ PlaybackPriority 100 ++ PlaybackPCM "hw:${CardId},1" ++ PlaybackMixer "default:${CardId}" ++ PlaybackMixerElem "Speakers" ++ } ++} ++ ++SectionDevice."Headset" { ++ Comment "Headphone Microphone" ++ ++ Include.wcdmice.File "/codecs/wcd938x/HeadphoneMicEnableSeq.conf" ++ Include.wcdmicd.File "/codecs/wcd938x/HeadphoneMicDisableSeq.conf" ++ Include.txmhpe.File "/codecs/qcom-lpass/tx-macro/HeadphoneMicEnableSeq.conf" ++ Include.txmhpd.File "/codecs/qcom-lpass/tx-macro/HeadphoneMicDisableSeq.conf" ++ ++ Value { ++ CapturePriority 100 ++ CapturePCM "hw:${CardId},2" ++ CaptureMixerElem "ADC2" ++ JackControl "Mic Jack" ++ } ++} +diff --git a/ucm2/Qualcomm/sm8250/RetroidPocket.conf b/ucm2/Qualcomm/sm8250/RetroidPocket.conf +new file mode 100644 +index 0000000..387d5a5 +--- /dev/null ++++ b/ucm2/Qualcomm/sm8250/RetroidPocket.conf +@@ -0,0 +1,22 @@ ++Syntax 4 ++ ++SectionUseCase."HiFi" { ++ File "/Qualcomm/sm8250/HiFi-RP.conf" ++ Comment "HiFi quality Music." ++} ++ ++BootSequence [ ++ cset "name='WSA_RX0 Digital Volume' 120" ++ cset "name='WSA_RX1 Digital Volume' 120" ++ cset "name='SpkrLeft PA Volume' 12" ++ cset "name='SpkrRight PA Volume' 12" ++ cset "name='HPHL Volume' 20" ++ cset "name='HPHR Volume' 20" ++ cset "name='ADC2 Volume' 10" ++] ++ ++Include.card-init.File "/lib/card-init.conf" ++Include.ctl-remap.File "/lib/ctl-remap.conf" ++Include.wcd-init.File "/codecs/wcd938x/init.conf" ++Include.wsa-init.File "/codecs/wsa881x/init.conf" ++Include.rxm-init.File "/codecs/qcom-lpass/rx-macro/init.conf" +diff --git a/ucm2/codecs/wsa881x/init.conf b/ucm2/codecs/wsa881x/init.conf +new file mode 100644 +index 0000000..fcb8988 +--- /dev/null ++++ b/ucm2/codecs/wsa881x/init.conf +@@ -0,0 +1,12 @@ ++# WSA881x specific volume control settings ++LibraryConfig.remap.Config { ++ ++ ctl.default.map { ++ # Merge two mono controls into one stereo ++ "name='Speakers Volume'" { ++ "name='SpkrLeft PA Volume'".vindex.0 0 ++ "name='SpkrRight PA Volume'".vindex.1 0 ++ } ++ } ++} ++ +diff --git a/ucm2/conf.d/sm8250/RetroidPocket.conf b/ucm2/conf.d/sm8250/RetroidPocket.conf +new file mode 120000 +index 0000000..8598750 +--- /dev/null ++++ b/ucm2/conf.d/sm8250/RetroidPocket.conf +@@ -0,0 +1 @@ ++../../Qualcomm/sm8250/RetroidPocket.conf +\ No newline at end of file +diff --git a/ucm2/conf.d/sm8250/retroidpocket-RetroidPocket5-.conf b/ucm2/conf.d/sm8250/retroidpocket-RetroidPocket5-.conf +new file mode 120000 +index 0000000..8598750 +--- /dev/null ++++ b/ucm2/conf.d/sm8250/retroidpocket-RetroidPocket5-.conf +@@ -0,0 +1 @@ ++../../Qualcomm/sm8250/RetroidPocket.conf +\ No newline at end of file +diff --git a/ucm2/conf.d/sm8250/retroidpocket-RetroidPocketFlip2-.conf b/ucm2/conf.d/sm8250/retroidpocket-RetroidPocketFlip2-.conf +new file mode 120000 +index 0000000..8598750 +--- /dev/null ++++ b/ucm2/conf.d/sm8250/retroidpocket-RetroidPocketFlip2-.conf +@@ -0,0 +1 @@ ++../../Qualcomm/sm8250/RetroidPocket.conf +\ No newline at end of file +diff --git a/ucm2/conf.d/sm8250/retroidpocket-RetroidPocketMini-.conf b/ucm2/conf.d/sm8250/retroidpocket-RetroidPocketMini-.conf +new file mode 120000 +index 0000000..8598750 +--- /dev/null ++++ b/ucm2/conf.d/sm8250/retroidpocket-RetroidPocketMini-.conf +@@ -0,0 +1 @@ ++../../Qualcomm/sm8250/RetroidPocket.conf +\ No newline at end of file +diff --git a/ucm2/conf.d/sm8250/retroidpocket-RetroidPocketMiniV2-.conf b/ucm2/conf.d/sm8250/retroidpocket-RetroidPocketMiniV2-.conf +new file mode 120000 +index 0000000..8598750 +--- /dev/null ++++ b/ucm2/conf.d/sm8250/retroidpocket-RetroidPocketMiniV2-.conf +@@ -0,0 +1 @@ ++../../Qualcomm/sm8250/RetroidPocket.conf +\ No newline at end of file +-- +2.34.1 + diff --git a/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8250/0003_Maintain-compatibility-with-old-loader-u-boot.patch b/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8250/0003_Maintain-compatibility-with-old-loader-u-boot.patch new file mode 100644 index 0000000000..f33d3cb801 --- /dev/null +++ b/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8250/0003_Maintain-compatibility-with-old-loader-u-boot.patch @@ -0,0 +1,30 @@ +From 39caffb11de21215c9ae2d651c43869a73d04654 Mon Sep 17 00:00:00 2001 +From: Teguh Sobirin +Date: Sat, 12 Oct 2024 03:42:09 +0800 +Subject: [PATCH] Maintain compatibility with old loader (u-boot) + +--- + ucm2/conf.d/sm8250/retroid-RetroidPocket5-conf | 1 + + ucm2/conf.d/sm8250/retroid-RetroidPocketMini-.conf | 1 + + 2 files changed, 2 insertions(+) + create mode 120000 ucm2/conf.d/sm8250/retroid-RetroidPocket5-conf + create mode 120000 ucm2/conf.d/sm8250/retroid-RetroidPocketMini-.conf + +diff --git a/ucm2/conf.d/sm8250/retroid-RetroidPocket5-conf b/ucm2/conf.d/sm8250/retroid-RetroidPocket5-conf +new file mode 120000 +index 0000000..8598750 +--- /dev/null ++++ b/ucm2/conf.d/sm8250/retroid-RetroidPocket5-conf +@@ -0,0 +1 @@ ++../../Qualcomm/sm8250/RetroidPocket.conf +\ No newline at end of file +diff --git a/ucm2/conf.d/sm8250/retroid-RetroidPocketMini-.conf b/ucm2/conf.d/sm8250/retroid-RetroidPocketMini-.conf +new file mode 120000 +index 0000000..8598750 +--- /dev/null ++++ b/ucm2/conf.d/sm8250/retroid-RetroidPocketMini-.conf +@@ -0,0 +1 @@ ++../../Qualcomm/sm8250/RetroidPocket.conf +\ No newline at end of file +-- +2.34.1 diff --git a/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8550/0001_Add-AYN-Odin2.patch b/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8550/0001_Add-AYN-Odin2.patch new file mode 100644 index 0000000000..4c3b6b7549 --- /dev/null +++ b/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8550/0001_Add-AYN-Odin2.patch @@ -0,0 +1,160 @@ +From d33738b93e9560e8d9e08a024cc84c8055bb7eb9 Mon Sep 17 00:00:00 2001 +From: Teguh Sobirin +Date: Mon, 24 Feb 2025 17:19:57 +0800 +Subject: [PATCH] Add AYN Odin2 + +Signed-off-by: Teguh Sobirin +--- + ucm2/AYN/Odin2/AYN-Odin2.conf | 31 +++++++++++ + ucm2/AYN/Odin2/HiFi.conf | 91 +++++++++++++++++++++++++++++++ + ucm2/conf.d/sm8550/AYN-Odin2.conf | 1 + + 3 files changed, 123 insertions(+) + create mode 100644 ucm2/AYN/Odin2/AYN-Odin2.conf + create mode 100644 ucm2/AYN/Odin2/HiFi.conf + create mode 120000 ucm2/conf.d/sm8550/AYN-Odin2.conf + +diff --git a/ucm2/AYN/Odin2/AYN-Odin2.conf b/ucm2/AYN/Odin2/AYN-Odin2.conf +new file mode 100644 +index 0000000..e4054ba +--- /dev/null ++++ b/ucm2/AYN/Odin2/AYN-Odin2.conf +@@ -0,0 +1,31 @@ ++# Use case configuration for AYN Odin2 ++# Author: Teguh Sobirin ++ ++Syntax 4 ++ ++SectionUseCase."HiFi" { ++ File "/AYN/Odin2/HiFi.conf" ++ Comment "HiFi quality Music." ++} ++ ++BootSequence [ ++ cset "name='RX_RX0 Digital Volume' 84" ++ cset "name='RX_RX1 Digital Volume' 84" ++ cset "name='HPHL Volume' 20" ++ cset "name='HPHR Volume' 20" ++ cset "name='ADC2 Volume' 10" ++] ++ ++LibraryConfig.remap.Config { ++ ++ ctl.default.map { ++ "name='HP Volume'" { ++ "name='HPHL Volume'".vindex.0 0 ++ "name='HPHR Volume'".vindex.1 0 ++ } ++ } ++} ++ ++Include.card-init.File "/lib/card-init.conf" ++Include.ctl-remap.File "/lib/ctl-remap.conf" ++Include.wcd-init.File "/codecs/wcd938x/init.conf" +diff --git a/ucm2/AYN/Odin2/HiFi.conf b/ucm2/AYN/Odin2/HiFi.conf +new file mode 100644 +index 0000000..dc5211e +--- /dev/null ++++ b/ucm2/AYN/Odin2/HiFi.conf +@@ -0,0 +1,91 @@ ++# Use case configuration for AYN Odin2 ++# Author: Teguh Sobirin ++ ++SectionVerb { ++ EnableSequence [ ++ cset "name='PRIMARY_MI2S_RX Audio Mixer MultiMedia1' 1" ++ cset "name='RX_CODEC_DMA_RX_0 Audio Mixer MultiMedia2' 1" ++ cset "name='DISPLAY_PORT_RX_0 Audio Mixer MultiMedia2' 0" ++ cset "name='MultiMedia3 Mixer TX_CODEC_DMA_TX_3' 1" ++ ] ++ ++ DisableSequence [ ++ cset "name='PRIMARY_MI2S_RX Audio Mixer MultiMedia1' 0" ++ cset "name='RX_CODEC_DMA_RX_0 Audio Mixer MultiMedia2' 0" ++ cset "name='DISPLAY_PORT_RX_0 Audio Mixer MultiMedia2' 0" ++ cset "name='MultiMedia3 Mixer TX_CODEC_DMA_TX_3' 0" ++ ] ++ ++ Value { ++ TQ "HiFi" ++ } ++} ++ ++SectionDevice."Speaker" { ++ Comment "Speaker playback" ++ ++ Value { ++ PlaybackPriority 150 ++ PlaybackPCM "hw:${CardId},0" ++ PlaybackChannels 2 ++ } ++} ++ ++SectionDevice."Headphones" { ++ Comment "Headphones Playback" ++ ++ Include.wcdhpe.File "/codecs/wcd938x/HeadphoneEnableSeq.conf" ++ Include.wcdhpd.File "/codecs/wcd938x/HeadphoneDisableSeq.conf" ++ Include.rxmhpe.File "/codecs/qcom-lpass/rx-macro/HeadphoneEnableSeq.conf" ++ Include.rxmhpd.File "/codecs/qcom-lpass/rx-macro/HeadphoneDisableSeq.conf" ++ ++ Value { ++ PlaybackPriority 200 ++ PlaybackPCM "hw:${CardId},1" ++ PlaybackMixer "default:${CardId}" ++ PlaybackMixerElem "HP" ++ PlaybackChannels 2 ++ JackControl "Headphone Jack" ++ JackHWMute "Speaker" ++ } ++} ++ ++#SectionDevice."Headset" { ++# Comment "Headphone Microphone" ++# ++# Include.wcdmice.File "/codecs/wcd938x/HeadphoneMicEnableSeq.conf" ++# Include.wcdmicd.File "/codecs/wcd938x/HeadphoneMicDisableSeq.conf" ++# Include.txmhpe.File "/codecs/qcom-lpass/tx-macro/SoundwireMic1EnableSeq.conf" ++# Include.txmhpd.File "/codecs/qcom-lpass/tx-macro/HeadphoneMicDisableSeq.conf" ++# ++# Value { ++# CapturePriority 200 ++# CapturePCM "hw:${CardId},2" ++# CaptureMixerElem "ADC2" ++# CaptureChannels 1 ++# JackControl "Mic Jack" ++# } ++#} ++ ++SectionDevice."DisplayPort" { ++ Comment "DisplayPort playback" ++ ++ EnableSequence [ ++ cset "name='PRIMARY_MI2S_RX Audio Mixer MultiMedia1' 0" ++ cset "name='RX_CODEC_DMA_RX_0 Audio Mixer MultiMedia2' 0" ++ cset "name='DISPLAY_PORT_RX_0 Audio Mixer MultiMedia2' 1" ++ ] ++ ++ DisableSequence [ ++ cset "name='PRIMARY_MI2S_RX Audio Mixer MultiMedia1' 1" ++ cset "name='DISPLAY_PORT_RX_0 Audio Mixer MultiMedia2' 0" ++ cset "name='RX_CODEC_DMA_RX_0 Audio Mixer MultiMedia2' 1" ++ ] ++ ++ Value { ++ PlaybackPriority 100 ++ PlaybackPCM "hw:${CardId},1" ++ JackControl "DP0 Jack" ++ JackHWMute "Speaker" ++ } ++} +diff --git a/ucm2/conf.d/sm8550/AYN-Odin2.conf b/ucm2/conf.d/sm8550/AYN-Odin2.conf +new file mode 120000 +index 0000000..414976a +--- /dev/null ++++ b/ucm2/conf.d/sm8550/AYN-Odin2.conf +@@ -0,0 +1 @@ ++../../AYN/Odin2/AYN-Odin2.conf +\ No newline at end of file +-- +2.34.1 + diff --git a/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8550/0002_AYN-Odin2---Add-EFI-boot-compatibility.patch b/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8550/0002_AYN-Odin2---Add-EFI-boot-compatibility.patch new file mode 100644 index 0000000000..7b5f549c08 --- /dev/null +++ b/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8550/0002_AYN-Odin2---Add-EFI-boot-compatibility.patch @@ -0,0 +1,22 @@ +From 39a2034f56bc990059cf20d3d6ef3e85fdb0e924 Mon Sep 17 00:00:00 2001 +From: Teguh Sobirin +Date: Mon, 24 Feb 2025 17:20:50 +0800 +Subject: [PATCH] AYN Odin2 : Add EFI boot compatibility + +Signed-off-by: Teguh Sobirin +--- + ucm2/conf.d/sm8550/ayn-AYNOdin2-.conf | 1 + + 1 file changed, 1 insertion(+) + create mode 120000 ucm2/conf.d/sm8550/ayn-AYNOdin2-.conf + +diff --git a/ucm2/conf.d/sm8550/ayn-AYNOdin2-.conf b/ucm2/conf.d/sm8550/ayn-AYNOdin2-.conf +new file mode 120000 +index 0000000..414976a +--- /dev/null ++++ b/ucm2/conf.d/sm8550/ayn-AYNOdin2-.conf +@@ -0,0 +1 @@ ++../../AYN/Odin2/AYN-Odin2.conf +\ No newline at end of file +-- +2.34.1 + diff --git a/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8550/0003_Add-AYANEO-Pocket-ACE.patch b/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8550/0003_Add-AYANEO-Pocket-ACE.patch new file mode 100644 index 0000000000..1200a01542 --- /dev/null +++ b/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8550/0003_Add-AYANEO-Pocket-ACE.patch @@ -0,0 +1,87 @@ +diff --git a/ucm2/AYANEO/Pocket/AYANEO-Pocket.conf b/ucm2/AYANEO/Pocket/AYANEO-Pocket.conf +new file mode 100644 +index 0000000..e4054ba +--- /dev/null ++++ b/ucm2/AYANEO/Pocket/AYANEO-Pocket.conf +@@ -0,0 +1,11 @@ ++Syntax 4 ++ ++SectionUseCase."HiFi" { ++ File "/AYANEO/Pocket/HiFi.conf" ++ Comment "HiFi quality Music." ++} ++ ++Include.card-init.File "/lib/card-init.conf" ++Include.ctl-remap.File "/lib/ctl-remap.conf" ++Include.wsa-init.File "/codecs/wsa884x/two-speakers/init.conf" ++Include.wsam-init.File "/codecs/qcom-lpass/wsa-macro/init.conf" +diff --git a/ucm2/AYANEO/Pocket/HiFi.conf b/ucm2/AYANEO/Pocket/HiFi.conf +new file mode 100644 +index 0000000..dc5211e +--- /dev/null ++++ b/ucm2/AYANEO/Pocket/HiFi.conf +@@ -0,0 +1,56 @@ ++SectionVerb { ++ EnableSequence [ ++ cset "name='WSA_CODEC_DMA_RX_0 Audio Mixer MultiMedia2' 1" ++ cset "name='MultiMedia3 Mixer VA_CODEC_DMA_TX_0' 1" ++ ] ++ ++ Include.wsae.File "/codecs/wsa884x/two-speakers/DefaultEnableSeq.conf" ++ ++ Value { ++ TQ "HiFi" ++ } ++} ++ ++SectionDevice."Speaker" { ++ Comment "Speaker playback" ++ ++ Include.wsmspk1e.File "/codecs/qcom-lpass/wsa-macro/SpeakerEnableSeq.conf" ++ Include.wsmspk1d.File "/codecs/qcom-lpass/wsa-macro/SpeakerDisableSeq.conf" ++ Include.wsaspkd.File "/codecs/wsa884x/two-speakers/SpeakerSeq.conf" ++ ++ Value { ++ PlaybackChannels 2 ++ PlaybackPriority 100 ++ PlaybackPCM "hw:${CardId},1" ++ PlaybackMixer "default:${CardId}" ++ PlaybackMixerElem "Speakers" ++ } ++} ++ ++SectionDevice."Mic1" { ++ Comment "Top microphones" ++ ++ Include.vadm0e.File "/codecs/qcom-lpass/va-macro/DMIC0EnableSeq.conf" ++ Include.vadm0d.File "/codecs/qcom-lpass/va-macro/DMIC0DisableSeq.conf" ++ Include.vadm1e.File "/codecs/qcom-lpass/va-macro/DMIC1EnableSeq.conf" ++ Include.vadm1d.File "/codecs/qcom-lpass/va-macro/DMIC1DisableSeq.conf" ++ ++ Value { ++ CapturePriority 100 ++ CapturePCM "hw:${CardId},2" ++ } ++} ++ ++#SectionDevice."Mic2" { ++# Comment "Bottom microphones" ++# ++# Include.vadm2e.File "/codecs/qcom-lpass/va-macro/DMIC2EnableSeq.conf" ++# Include.vadm2d.File "/codecs/qcom-lpass/va-macro/DMIC2DisableSeq.conf" ++# Include.vadm3e.File "/codecs/qcom-lpass/va-macro/DMIC3EnableSeq.conf" ++# Include.vadm3d.File "/codecs/qcom-lpass/va-macro/DMIC3DisableSeq.conf" ++# ++# Value { ++# CapturePriority 100 ++# CapturePCM "hw:${CardId},4" ++# } ++#} +diff --git a/ucm2/conf.d/sm8550/SM8550-APS.conf b/ucm2/conf.d/sm8550/SM8550-APS.conf +new file mode 120000 +index 0000000..414976a +--- /dev/null ++++ b/ucm2/conf.d/sm8550/SM8550-APS.conf +@@ -0,0 +1 @@ ++../../AYANEO/Pocket/AYANEO-Pocket.conf +\ No newline at end of file diff --git a/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8550/0004_AYANEO-Pocket-ACE---Add-EFI-boot-compatibility.patch b/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8550/0004_AYANEO-Pocket-ACE---Add-EFI-boot-compatibility.patch new file mode 100644 index 0000000000..344f64107e --- /dev/null +++ b/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8550/0004_AYANEO-Pocket-ACE---Add-EFI-boot-compatibility.patch @@ -0,0 +1,8 @@ +diff --git a/ucm2/conf.d/sm8550/ayaneo-AYANEOPocketACE-.conf b/ucm2/conf.d/sm8550/ayaneo-AYANEOPocketACE-.conf +new file mode 120000 +index 0000000..414976a +--- /dev/null ++++ b/ucm2/conf.d/sm8550/ayaneo-AYANEOPocketACE-.conf +@@ -0,0 +1 @@ ++../../AYANEO/Pocket/AYANEO-Pocket.conf +\ No newline at end of file diff --git a/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8550/0004_AYANEO-Pocket-DMG---Add-EFI-boot-compatibility.patch b/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8550/0004_AYANEO-Pocket-DMG---Add-EFI-boot-compatibility.patch new file mode 100644 index 0000000000..962bf8c556 --- /dev/null +++ b/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8550/0004_AYANEO-Pocket-DMG---Add-EFI-boot-compatibility.patch @@ -0,0 +1,8 @@ +diff --git a/ucm2/conf.d/sm8550/ayaneo-AYANEOPocketDMG-.conf b/ucm2/conf.d/sm8550/ayaneo-AYANEOPocketDMG-.conf +new file mode 120000 +index 0000000..414976a +--- /dev/null ++++ b/ucm2/conf.d/sm8550/ayaneo-AYANEOPocketDMG-.conf +@@ -0,0 +1 @@ ++../../AYANEO/Pocket/AYANEO-Pocket.conf +\ No newline at end of file diff --git a/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8550/0004_AYANEO-Pocket-DS---Add-EFI-boot-compatibility.patch b/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8550/0004_AYANEO-Pocket-DS---Add-EFI-boot-compatibility.patch new file mode 100644 index 0000000000..54b574b125 --- /dev/null +++ b/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8550/0004_AYANEO-Pocket-DS---Add-EFI-boot-compatibility.patch @@ -0,0 +1,8 @@ +diff --git a/ucm2/conf.d/sm8550/ayaneo-AYANEOPocketDS-.conf b/ucm2/conf.d/sm8550/ayaneo-AYANEOPocketDS-.conf +new file mode 120000 +index 0000000..414976a +--- /dev/null ++++ b/ucm2/conf.d/sm8550/ayaneo-AYANEOPocketDS-.conf +@@ -0,0 +1 @@ ++../../AYANEO/Pocket/AYANEO-Pocket.conf +\ No newline at end of file diff --git a/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8550/0004_AYANEO-Pocket-EVO---Add-EFI-boot-compatibility.patch b/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8550/0004_AYANEO-Pocket-EVO---Add-EFI-boot-compatibility.patch new file mode 100644 index 0000000000..d3173ebcdb --- /dev/null +++ b/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8550/0004_AYANEO-Pocket-EVO---Add-EFI-boot-compatibility.patch @@ -0,0 +1,8 @@ +diff --git a/ucm2/conf.d/sm8550/ayaneo-AYANEOPocketEVO-.conf b/ucm2/conf.d/sm8550/ayaneo-AYANEOPocketEVO-.conf +new file mode 120000 +index 0000000..414976a +--- /dev/null ++++ b/ucm2/conf.d/sm8550/ayaneo-AYANEOPocketEVO-.conf +@@ -0,0 +1 @@ ++../../AYANEO/Pocket/AYANEO-Pocket.conf +\ No newline at end of file diff --git a/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8650/0001-AYANEO-Pocket-S2.patch b/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8650/0001-AYANEO-Pocket-S2.patch new file mode 100644 index 0000000000..7125c09b4d --- /dev/null +++ b/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8650/0001-AYANEO-Pocket-S2.patch @@ -0,0 +1,145 @@ +diff --git a/ucm2/Qualcomm/sm8650/APS2/SM8650-APS2.conf b/ucm2/Qualcomm/sm8650/APS2/SM8650-APS2.conf +new file mode 100644 +index 0000000..e4054ba +--- /dev/null ++++ b/ucm2/Qualcomm/sm8650/APS2/SM8650-APS2.conf +@@ -0,0 +1,13 @@ ++Syntax 4 ++ ++SectionUseCase."HiFi" { ++ File "/Qualcomm/sm8650/APS2/HiFi.conf" ++ Comment "HiFi quality Music." ++} ++ ++Include.card-init.File "/lib/card-init.conf" ++Include.ctl-remap.File "/lib/ctl-remap.conf" ++Include.wcd-init.File "/codecs/wcd939x/init.conf" ++Include.wsam-init.File "/codecs/qcom-lpass/wsa-macro/init.conf" ++Include.rxm-init.File "/codecs/qcom-lpass/rx-macro/init.conf" ++Include.wsa-init.File "/codecs/wsa884x/two-speakers/init.conf" +diff --git a/ucm2/Qualcomm/sm8650/APS2/HiFi.conf b/ucm2/Qualcomm/sm8650/APS2/HiFi.conf +new file mode 100644 +index 0000000..dc5211e +--- /dev/null ++++ b/ucm2/Qualcomm/sm8650/APS2/HiFi.conf +@@ -0,0 +1,112 @@ ++SectionVerb { ++ EnableSequence [ ++ cset "name='DISPLAY_PORT_RX_0 Audio Mixer MultiMedia1' 0" ++ cset "name='RX_CODEC_DMA_RX_0 Audio Mixer MultiMedia1' 1" ++ cset "name='WSA_CODEC_DMA_RX_0 Audio Mixer MultiMedia2' 1" ++ cset "name='MultiMedia3 Mixer TX_CODEC_DMA_TX_3' 1" ++ cset "name='MultiMedia4 Mixer VA_CODEC_DMA_TX_0' 1" ++ ] ++ ++ Include.wcde.File "/codecs/wcd939x/DefaultEnableSeq.conf" ++ Include.wsae.File "/codecs/wsa884x/two-speakers/DefaultEnableSeq.conf" ++ ++ Value { ++ TQ "HiFi" ++ } ++} ++ ++SectionDevice."Speaker" { ++ Comment "Speaker playback" ++ ++ Include.wcdspk1e.File "/codecs/qcom-lpass/wsa-macro/SpeakerEnableSeq.conf" ++ Include.wcdspk1d.File "/codecs/qcom-lpass/wsa-macro/SpeakerDisableSeq.conf" ++ Include.wsaspkd.File "/codecs/wsa884x/two-speakers/SpeakerSeq.conf" ++ ++ Value { ++ PlaybackChannels 2 ++ PlaybackPriority 100 ++ PlaybackPCM "hw:${CardId},1" ++ PlaybackMixer "default:${CardId}" ++ PlaybackMixerElem "Speakers" ++ } ++} ++ ++SectionDevice."Headphones" { ++ Comment "Headphones playback" ++ ++ EnableSequence [ ++ cset "name='RX_CODEC_DMA_RX_0 Audio Mixer MultiMedia1' 1" ++ cset "name='DISPLAY_PORT_RX_0 Audio Mixer MultiMedia1' 0" ++ ] ++ ++ Include.wcdhpe.File "/codecs/wcd939x/HeadphoneEnableSeq.conf" ++ Include.wcdhpd.File "/codecs/wcd939x/HeadphoneDisableSeq.conf" ++ Include.rxmhpe.File "/codecs/qcom-lpass/rx-macro/HeadphoneEnableSeq.conf" ++ Include.rxmhpd.File "/codecs/qcom-lpass/rx-macro/HeadphoneDisableSeq.conf" ++ ++ Value { ++ PlaybackPriority 200 ++ PlaybackPCM "hw:${CardId},0" ++ PlaybackMixer "default:${CardId}" ++ PlaybackMixerElem "HP" ++ JackControl "Headset Jack" ++ JackHWMute "Speaker" ++ } ++} ++ ++#SectionDevice."Headset" { ++# Comment "Headset microphone" ++# ++# #ConflictingDevice [ ++# # "Mic" ++# #] ++# ++# Include.wcdmice.File "/codecs/wcd939x/HeadphoneMicEnableSeq.conf" ++# Include.wcdmicd.File "/codecs/wcd939x/HeadphoneMicDisableSeq.conf" ++# Include.txmhpe.File "/codecs/qcom-lpass/tx-macro/SoundwireMic1EnableSeq.conf" ++# Include.txmhpd.File "/codecs/qcom-lpass/tx-macro/SoundwireMicDisableSeq.conf" ++# ++# Value { ++# CaptureChannels 1 ++# CapturePriority 200 ++# CapturePCM "hw:${CardId},2" ++# CaptureMixerElem "ADC2" ++# JackControl "Headset Jack" ++# } ++#} ++ ++#SectionDevice."Mic" { ++# Comment "Bottom Microphone" ++# ++# Include.txmhpe.File "/codecs/qcom-lpass/tx-macro/SoundwireMic8EnableSeq.conf" ++# Include.txmhpd.File "/codecs/qcom-lpass/tx-macro/SoundwireMicDisableSeq.conf" ++# ++# Value { ++# CaptureChannels 1 ++# CapturePriority 100 ++# CapturePCM "hw:${CardId},3" ++# CaptureMixerElem "SMIC8" ++# } ++#} ++ ++SectionDevice."HDMI0" { ++ Comment "DisplayPort 0 playback" ++ ++ ConflictingDevice [ ++ "Headphones" ++ ] ++ ++ EnableSequence [ ++ cset "name='DISPLAY_PORT_RX_0 Audio Mixer MultiMedia1' 1" ++ ] ++ ++ DisableSequence [ ++ cset "name='DISPLAY_PORT_RX_0 Audio Mixer MultiMedia1' 0" ++ ] ++ ++ Value { ++ PlaybackPriority 200 ++ PlaybackPCM "hw:${CardId},0" ++ JackControl "DP0 Jack" ++ } ++} +diff --git a/ucm2/conf.d/sm8650/SM8650-APS2.conf b/ucm2/conf.d/sm8650/SM8650-APS2.conf +new file mode 120000 +index 0000000..414976a +--- /dev/null ++++ b/ucm2/conf.d/sm8650/SM8650-APS2.conf +@@ -0,0 +1 @@ ++../../Qualcomm/sm8650/APS2/SM8650-APS2.conf +\ No newline at end of file diff --git a/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8650/0002_AYANEO-Pocket-S2---Add-EFI-boot-compatibility.patch b/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8650/0002_AYANEO-Pocket-S2---Add-EFI-boot-compatibility.patch new file mode 100644 index 0000000000..76ad34fd63 --- /dev/null +++ b/projects/ArchR/packages/audio/alsa-ucm-conf/patches/SM8650/0002_AYANEO-Pocket-S2---Add-EFI-boot-compatibility.patch @@ -0,0 +1,8 @@ +diff --git a/ucm2/conf.d/sm8650/ayaneo-AYANEOPocketS2-.conf b/ucm2/conf.d/sm8650/ayaneo-AYANEOPocketS2-.conf +new file mode 120000 +index 0000000..414976a +--- /dev/null ++++ b/ucm2/conf.d/sm8650/ayaneo-AYANEOPocketS2-.conf +@@ -0,0 +1 @@ ++../../Qualcomm/sm8650/APS2/SM8650-APS2.conf +\ No newline at end of file diff --git a/projects/ArchR/packages/audio/alsa-utils/package.mk b/projects/ArchR/packages/audio/alsa-utils/package.mk new file mode 100644 index 0000000000..e576cff430 --- /dev/null +++ b/projects/ArchR/packages/audio/alsa-utils/package.mk @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="alsa-utils" +PKG_VERSION="1.2.14" +PKG_LICENSE="GPL" +PKG_SITE="http://www.alsa-project.org/" +PKG_URL="https://www.alsa-project.org/files/pub/utils/alsa-utils-${PKG_VERSION}.tar.bz2" +PKG_DEPENDS_TARGET="toolchain alsa-lib ncurses systemd alsa-ucm-conf" +PKG_LONGDESC="This package includes the utilities for ALSA, like alsamixer, aplay, arecord, alsactl, iecset and speaker-test." +PKG_TOOLCHAIN="autotools" + +PKG_CONFIGURE_OPTS_TARGET="--disable-alsaconf \ + --disable-alsaloop \ + --enable-alsatest \ + --disable-bat \ + --disable-dependency-tracking \ + --disable-nls \ + --disable-rst2man \ + --disable-xmlto" + +post_makeinstall_target() { + rm -rf ${INSTALL}/lib ${INSTALL}/var + rm -rf ${INSTALL}/usr/share/alsa/speaker-test + rm -rf ${INSTALL}/usr/share/sounds + rm -rf ${INSTALL}/usr/lib/systemd/system +} diff --git a/projects/ArchR/packages/audio/espeak/package.mk b/projects/ArchR/packages/audio/espeak/package.mk new file mode 100644 index 0000000000..6b20b6f07d --- /dev/null +++ b/projects/ArchR/packages/audio/espeak/package.mk @@ -0,0 +1,31 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="espeak" +PKG_VERSION="1.48.04-source" +PKG_SHA256="bf9a17673adffcc28ff7ea18764f06136547e97bbd9edf2ec612f09b207f0659" +PKG_LICENSE="GPL" +PKG_SITE="http://espeak.sourceforge.net/" +PKG_URL="http://sourceforge.net/projects/espeak/files/espeak/espeak-1.48/${PKG_NAME}-${PKG_VERSION}.zip" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Text to Speech engine for English, with support for other languages" +PKG_TOOLCHAIN="manual" + +pre_make_target() { + cp src/portaudio19.h src/portaudio.h +} + +make_target() { + make -C src \ + CXXFLAGS="${CXXFLAGS}" \ + LDFLAGS="${LDFLAGS}" \ + AUDIO="" +} + +makeinstall_target() { + make -C src \ + CXXFLAGS="${CXXFLAGS}" \ + LDFLAGS="${LDFLAGS}" \ + AUDIO="" \ + DESTDIR=${INSTALL} install +} diff --git a/projects/ArchR/packages/audio/espeak/patches/espeak-1.47-ftbs-ld-libm.patch b/projects/ArchR/packages/audio/espeak/patches/espeak-1.47-ftbs-ld-libm.patch new file mode 100644 index 0000000000..446493fb40 --- /dev/null +++ b/projects/ArchR/packages/audio/espeak/patches/espeak-1.47-ftbs-ld-libm.patch @@ -0,0 +1,23 @@ +diff --git a/src/Makefile b/src/Makefile +index f04b4c4..b8d4b19 100644 +--- a/src/Makefile ++++ b/src/Makefile +@@ -83,15 +83,15 @@ libespeak_SOURCES = speak_lib.cpp compiledict.cpp dictionary.cpp intonation.cpp + + SRCS1=$(speak_SOURCES) + OBJS1=$(patsubst %.cpp,%.o,$(SRCS1)) +-LIBS1=-lstdc++ $(LIB_AUDIO) -lpthread $(EXTRA_LIBS) ++LIBS1=-lstdc++ -lm $(LIB_AUDIO) -lpthread $(EXTRA_LIBS) + + SRCS2=$(libespeak_SOURCES) + OBJS2=$(patsubst %.cpp,x_%.o,$(SRCS2)) +-LIBS2=-lstdc++ $(LIB_AUDIO) -lpthread ++LIBS2=-lstdc++ -lm $(LIB_AUDIO) -lpthread + + SRCS3 = espeak.cpp + OBJS3=$(patsubst %.cpp,%.o,$(SRCS3)) +-LIBS3=-lstdc++ -L . -lespeak ++LIBS3=-lstdc++ -lm -L . -lespeak + + CXXFLAGS=-O2 + diff --git a/projects/ArchR/packages/audio/espeak/patches/espeak-1.47-wav-close.patch b/projects/ArchR/packages/audio/espeak/patches/espeak-1.47-wav-close.patch new file mode 100644 index 0000000000..d0550d9458 --- /dev/null +++ b/projects/ArchR/packages/audio/espeak/patches/espeak-1.47-wav-close.patch @@ -0,0 +1,23 @@ +diff --git a/src/espeak.cpp b/src/espeak.cpp +index 00f93c1..4ad42e8 100644 +--- a/src/espeak.cpp ++++ b/src/espeak.cpp +@@ -281,10 +281,7 @@ static int SynthCallback(short *wav, int numsamples, espeak_EVENT *events) + if(quiet) return(0); // -q quiet mode + + if(wav == NULL) +- { +- CloseWavFile(); + return(0); +- } + + while(events->type != 0) + { +@@ -805,5 +802,7 @@ int main (int argc, char **argv) + + if(f_phonemes_out != stdout) + fclose(f_phonemes_out); // needed for WinCE ++ CloseWavFile(); ++ espeak_Terminate(); + return(0); + } diff --git a/projects/ArchR/packages/audio/espeak/patches/espeak-1.48-gcc-6-fix.patch b/projects/ArchR/packages/audio/espeak/patches/espeak-1.48-gcc-6-fix.patch new file mode 100644 index 0000000000..6e59c7892f --- /dev/null +++ b/projects/ArchR/packages/audio/espeak/patches/espeak-1.48-gcc-6-fix.patch @@ -0,0 +1,12 @@ +diff --git a/src/tr_languages.cpp b/src/tr_languages.cpp +--- a/src/tr_languages.cpp ++++ b/src/tr_languages.cpp +@@ -198,7 +198,7 @@ static const unsigned short chars_ignore_zwnj_hyphen[] = { + 0x200d, 1, // zero width joiner + 0, 0 }; + +-const char string_ordinal[] = {0xc2,0xba,0}; // masculine ordinal character, UTF-8 ++const char string_ordinal[] = {'\xc2','\xba',0}; // masculine ordinal character, UTF-8 + + + static Translator* NewTranslator(void) diff --git a/projects/ArchR/packages/audio/fluidsynth/package.mk b/projects/ArchR/packages/audio/fluidsynth/package.mk new file mode 100644 index 0000000000..e45943a6cb --- /dev/null +++ b/projects/ArchR/packages/audio/fluidsynth/package.mk @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +. ${ROOT}/packages/audio/fluidsynth/package.mk + +PKG_CMAKE_OPTS_TARGET="-DBUILD_SHARED_LIBS=1 \ + -DLIB_SUFFIX= \ + -Denable-libsndfile=1 \ + -Denable-pkgconfig=1 \ + -Denable-pipewire=1 \ + -Denable-pulseaudio=1 \ + -Denable-systemd=1 \ + -Denable-readline=0" diff --git a/projects/ArchR/packages/audio/fluidsynth/system.d/fluidsynth.service b/projects/ArchR/packages/audio/fluidsynth/system.d/fluidsynth.service new file mode 100644 index 0000000000..8f865ec372 --- /dev/null +++ b/projects/ArchR/packages/audio/fluidsynth/system.d/fluidsynth.service @@ -0,0 +1,26 @@ +[Unit] +Description=FluidSynth Daemon +Documentation=man:fluidsynth(1) +After=sound.target +After=pipewire.service + +[Service] +# added automatically, for details please see +# https://en.opensuse.org/openSUSE:Security_Features#Systemd_hardening_effort +ProtectSystem=full +ProtectHome=read-only +ProtectHostname=true +ProtectKernelTunables=true +ProtectKernelModules=true +ProtectKernelLogs=true +ProtectControlGroups=true +# end of automatic additions +# required in order for the above sandboxing options to work on a user unit +PrivateUsers=yes +Type=simple +NotifyAccess=main +EnvironmentFile=-%h/.config/fluidsynth +ExecStart=/usr/bin/fluidsynth -is -a sdl2 /usr/share/soundfonts/GeneralUser.sf2 + +[Install] +WantedBy=default.target diff --git a/projects/ArchR/packages/audio/ldacBT/package.mk b/projects/ArchR/packages/audio/ldacBT/package.mk new file mode 100644 index 0000000000..a0f95227d7 --- /dev/null +++ b/projects/ArchR/packages/audio/ldacBT/package.mk @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +. ${ROOT}/packages/audio/ldacBT/package.mk + +PKG_CMAKE_OPTS_TARGET="-DCMAKE_POLICY_VERSION_MINIMUM=3.5 \ + -DLDAC_SOFT_FLOAT=OFF" diff --git a/projects/ArchR/packages/audio/libao/package.mk b/projects/ArchR/packages/audio/libao/package.mk new file mode 100644 index 0000000000..7bda398b96 --- /dev/null +++ b/projects/ArchR/packages/audio/libao/package.mk @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="libao" +PKG_VERSION="1.2.0" +PKG_LICENSE="GPLv2" +PKG_SITE="https://xiph.org/ao/" +PKG_URL="http://downloads.xiph.org/releases/ao/${PKG_NAME}-${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain alsa-lib pulseaudio" +PKG_LONGDESC="Libao is a cross-platform audio library that allows programs to output +audio using a simple API on a wide variety of platforms." +PKG_BUILD_FLAGS="+pic" + +pre_configure_target() { +export CFLAGS="${CFLAGS} -Wno-implicit-function-declaration" +} diff --git a/projects/ArchR/packages/audio/libfreeaptx/package.mk b/projects/ArchR/packages/audio/libfreeaptx/package.mk new file mode 100644 index 0000000000..5a5f3dbdd3 --- /dev/null +++ b/projects/ArchR/packages/audio/libfreeaptx/package.mk @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +. ${ROOT}/packages/audio/libfreeaptx/package.mk + +PKG_SHA256="5ab5ebddf3f2eb7ce47a505b87460b00fc1ede99c70010796d3575ab31ea80bf" diff --git a/projects/ArchR/packages/audio/libogg/package.mk b/projects/ArchR/packages/audio/libogg/package.mk new file mode 100644 index 0000000000..01052294e8 --- /dev/null +++ b/projects/ArchR/packages/audio/libogg/package.mk @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +. ${ROOT}/packages/audio/libogg/package.mk + +PKG_CMAKE_OPTS_TARGET="-DBUILD_SHARED_LIBS=ON \ + -DINSTALL_DOCS=OFF" diff --git a/projects/ArchR/packages/audio/libsndfile/package.mk b/projects/ArchR/packages/audio/libsndfile/package.mk new file mode 100644 index 0000000000..4fd0f4aeae --- /dev/null +++ b/projects/ArchR/packages/audio/libsndfile/package.mk @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2021-present Team LibreELEC (https://libreelec.tv) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="libsndfile" +PKG_VERSION="e486f20" +PKG_LICENSE="LGPL-2.1-or-later" +PKG_SITE="https://libsndfile.github.io/libsndfile/" +PKG_URL="https://github.com/libsndfile/libsndfile/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain alsa-lib flac libogg libvorbis opus" +PKG_LONGDESC="A C library for reading and writing sound files containing sampled audio data." +PKG_BUILD_FLAGS="+pic" + +PKG_CMAKE_OPTS_TARGET="-DBUILD_PROGRAMS=OFF \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_REGTEST=OFF \ + -DBUILD_TESTING=OFF \ + -DENABLE_EXTERNAL_LIBS=ON \ + -DBUILD_SHARED_LIBS=ON + -DINSTALL_MANPAGES=OFF \ + -DINSTALL_PKGCONFIG_MODULE=ON" diff --git a/projects/ArchR/packages/audio/libsndfile/patches/libsndfile-add-required-static-libraries-to-pkg-config.patch b/projects/ArchR/packages/audio/libsndfile/patches/libsndfile-add-required-static-libraries-to-pkg-config.patch new file mode 100644 index 0000000000..e5220c098d --- /dev/null +++ b/projects/ArchR/packages/audio/libsndfile/patches/libsndfile-add-required-static-libraries-to-pkg-config.patch @@ -0,0 +1,10 @@ +--- a/sndfile.pc.in 2021-01-24 23:22:23.000000000 +1100 ++++ b/sndfile.pc.in 2021-09-12 14:30:47.763655089 +1000 +@@ -8,6 +8,6 @@ + Requires: + Requires.private: @EXTERNAL_XIPH_REQUIRE@ @EXTERNAL_MPEG_REQUIRE@ + Version: @VERSION@ +-Libs: -L${libdir} -lsndfile ++Libs: -L${libdir} -lsndfile -lFLAC -lvorbis -logg -lvorbisenc -lopus + Libs.private: @EXTERNAL_MPEG_LIBS@ + Cflags: -I${includedir} diff --git a/projects/ArchR/packages/audio/libvorbis/package.mk b/projects/ArchR/packages/audio/libvorbis/package.mk new file mode 100644 index 0000000000..3ea1e65d24 --- /dev/null +++ b/projects/ArchR/packages/audio/libvorbis/package.mk @@ -0,0 +1,19 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="libvorbis" +PKG_VERSION="1.3.7" +PKG_SHA256="b33cc4934322bcbf6efcbacf49e3ca01aadbea4114ec9589d1b1e9d20f72954b" +PKG_LICENSE="BSD" +PKG_SITE="http://www.vorbis.com/" +PKG_URL="http://downloads.xiph.org/releases/vorbis/libvorbis-${PKG_VERSION}.tar.xz" +PKG_DEPENDS_TARGET="toolchain libogg" +PKG_LONGDESC="Lossless audio compression tools using the ogg-vorbis algorithms." +PKG_TOOLCHAIN="autotools" +PKG_BUILD_FLAGS="+pic" + +PKG_CONFIGURE_OPTS_TARGET="--with-ogg=${SYSROOT_PREFIX}/usr \ + --disable-docs \ + --disable-examples \ + --disable-oggtest" diff --git a/projects/ArchR/packages/audio/libxmp/package.mk b/projects/ArchR/packages/audio/libxmp/package.mk new file mode 100644 index 0000000000..ddf4b979b3 --- /dev/null +++ b/projects/ArchR/packages/audio/libxmp/package.mk @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="libxmp" +PKG_VERSION="8201d26cf933688a8be64292457c429fd8e654ab" #v4.6.0 +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/libxmp/libxmp" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Libxmp is a library that renders module files to PCM data." +PKG_TOOLCHAIN="cmake" + +PKG_CMAKE_OPTS_TARGET="-DCMAKE_POLICY_VERSION_MINIMUM=3.5" diff --git a/projects/ArchR/packages/audio/pipewire/package.mk b/projects/ArchR/packages/audio/pipewire/package.mk new file mode 100644 index 0000000000..1088e87635 --- /dev/null +++ b/projects/ArchR/packages/audio/pipewire/package.mk @@ -0,0 +1,98 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2021-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="pipewire" +PKG_VERSION="1.2.6" +PKG_LICENSE="LGPL" +PKG_SITE="https://pipewire.org" +PKG_URL="https://github.com/PipeWire/pipewire/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain libpthread-stubs dbus ncurses alsa-lib pulseaudio systemd libsndfile libusb" +PKG_LONGDESC="PipeWire is a server and user space API to deal with multimedia pipeline" +PKG_PATCH_DIRS+=" ${DEVICE}" + +if [ "${BLUETOOTH_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" bluez sbc ldacBT libfreeaptx fdk-aac" + PKG_PIPEWIRE_BLUETOOTH="-Dbluez5=enabled \ + -Dbluez5-backend-hsp-native=disabled \ + -Dbluez5-backend-hfp-native=disabled \ + -Dbluez5-backend-ofono=disabled \ + -Dbluez5-backend-hsphfpd=disabled \ + -Dbluez5-codec-aptx=enabled \ + -Dbluez5-codec-lc3plus=disabled \ + -Dbluez5-codec-ldac=enabled \ + -Dbluez5-codec-aac=enabled" +else + PKG_PIPEWIRE_BLUETOOTH="-Dbluez5=disabled" +fi + +if [ "${VULKAN_SUPPORT}" = "yes" ]; then + PKG_PIPEWIRE_VULKAN+="-Dvulkan=enabled \ + -Dx11=disabled \ + -Dx11-xfixes=disabled" +fi + +PKG_MESON_OPTS_TARGET="-Ddocs=disabled \ + -Dexamples=disabled \ + -Dman=disabled \ + -Dtests=disabled \ + -Dinstalled_tests=disabled \ + -Dgstreamer=disabled \ + -Dgstreamer-device-provider=disabled \ + -Dsystemd=enabled \ + -Dsystemd-system-service=enabled \ + -Dsystemd-user-service=disabled \ + -Dpipewire-alsa=enabled \ + -Dpipewire-jack=disabled \ + -Dpipewire-v4l2=disabled \ + -Djack-devel=false + -Dspa-plugins=enabled \ + -Dalsa=enabled \ + -Daudiomixer=enabled \ + -Daudioconvert=enabled \ + ${PKG_PIPEWIRE_BLUETOOTH} \ + -Dcontrol=enabled \ + -Daudiotestsrc=disabled \ + -Dffmpeg=disabled \ + -Djack=disabled \ + -Dsupport=enabled \ + -Devl=disabled \ + -Dtest=disabled \ + -Dv4l2=disabled \ + -Ddbus=enabled \ + -Dlibcamera=disabled \ + -Dvideoconvert=disabled \ + -Dvideotestsrc=disabled \ + -Dvolume=enabled \ + ${PKG_PIPEWIRE_VULKAN} \ + -Dpw-cat=enabled \ + -Dudev=enabled \ + -Dudevrulesdir=/usr/lib/udev/rules.d \ + -Dsdl2=disabled \ + -Dsndfile=enabled \ + -Dlibpulse=enabled \ + -Droc=disabled \ + -Davahi=disabled \ + -Decho-cancel-webrtc=disabled \ + -Dlibusb=enabled \ + -Dsession-managers=[] \ + -Draop=disabled \ + -Dlv2=disabled \ + -Dlibcanberra=disabled \ + -Dlegacy-rtkit=false" + +pre_configure_target() { + export TARGET_CFLAGS="${TARGET_CFLAGS} -Wno-error=float-conversion" + export TARGET_LDFLAGS="${TARGET_LDFLAGS} -lncursesw -ltinfow" +} + +post_install() { + add_user pipewire x 982 980 "pipewire-daemon" "/var/run/pipewire" "/bin/sh" + add_group pipewire 980 + mkdir -p ${INSTALL}/etc/alsa/conf.d + ln -sf /usr/share/alsa/alsa.conf.d/50-pipewire.conf ${INSTALL}/etc/alsa/conf.d/50-pipewire.conf + ln -sf /usr/share/alsa/alsa.conf.d/99-pipewire-default.conf ${INSTALL}/etc/alsa/conf.d/99-pipewire-default.conf + enable_service pipewire.socket + enable_service pipewire.service + enable_service pipewire-pulse.socket + enable_service pipewire-pulse.service +} diff --git a/projects/ArchR/packages/audio/pipewire/patches/001-pipewire-pulse.patch b/projects/ArchR/packages/audio/pipewire/patches/001-pipewire-pulse.patch new file mode 100644 index 0000000000..bb7a5af626 --- /dev/null +++ b/projects/ArchR/packages/audio/pipewire/patches/001-pipewire-pulse.patch @@ -0,0 +1,66 @@ +diff -rupN pipewire-1.0.0.orig/src/daemon/pipewire-pulse.conf.in pipewire-1.0.0/src/daemon/pipewire-pulse.conf.in +--- pipewire-1.0.0.orig/src/daemon/pipewire-pulse.conf.in 2023-12-29 13:41:35.329947857 +0000 ++++ pipewire-1.0.0/src/daemon/pipewire-pulse.conf.in 2023-12-29 13:41:46.850669838 +0000 +@@ -92,11 +92,11 @@ pulse.properties = { + #"tcp:[::]:9999" # IPv6 on all addresses + #"tcp:127.0.0.1:8888" # IPv4 on a single address + # +- #{ address = "tcp:4713" # address +- # max-clients = 64 # maximum number of clients +- # listen-backlog = 32 # backlog in the server listen queue +- # client.access = "restricted" # permissions for clients +- #} ++ { address = "tcp:127.0.0.1:4713" # address ++ max-clients = 64 # maximum number of clients ++ listen-backlog = 32 # backlog in the server listen queue ++ client.access = "allowed" # permissions for clients ++ } + ] + #server.dbus-name = "org.pulseaudio.Server" + #pulse.min.req = 128/48000 # 2.7ms +diff -rupN pipewire-1.0.0.orig/src/daemon/systemd/system/pipewire.service.in pipewire-1.0.0/src/daemon/systemd/system/pipewire.service.in +--- pipewire-1.0.0.orig/src/daemon/systemd/system/pipewire.service.in 2023-12-29 13:41:35.329947857 +0000 ++++ pipewire-1.0.0/src/daemon/systemd/system/pipewire.service.in 2023-12-29 13:43:32.217227049 +0000 +@@ -21,15 +21,25 @@ NoNewPrivileges=yes + RestrictNamespaces=yes + SystemCallArchitectures=native + SystemCallFilter=@system-service ++Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/dbus/system_bus_socket ++User=root + Type=simple + AmbientCapabilities=CAP_SYS_NICE +-ExecStart=@PW_BINARY@ ++ExecStart=/usr/bin/pipewire + Restart=on-failure + RuntimeDirectory=pipewire + RuntimeDirectoryPreserve=yes +-User=pipewire + Environment=PIPEWIRE_RUNTIME_DIR=%t/pipewire ++# Add if you need debugging ++# Environment=PIPEWIRE_DEBUG=4 ++ ++# These hardcoded runtime and dbus paths must stay this way for a system service ++# as the User= is not resolved here 8( ++## NOTE we do not change PIPEWIRE_RUNTIME_DIR as this is the system socket dir... ++Environment=XDG_RUNTIME_DIR=/var/run/0-runtime-dir ++Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/dbus/system_bus_socket ++Environment=HOME=/storage + + [Install] +-Also=pipewire.socket pipewire-manager.socket ++Also=pipewire.socket pipewire-pulse.socket pipewire-manager.socket + WantedBy=default.target +diff -rupN pipewire-1.0.0.orig/src/daemon/systemd/system/pipewire.socket pipewire-1.0.0/src/daemon/systemd/system/pipewire.socket +--- pipewire-1.0.0.orig/src/daemon/systemd/system/pipewire.socket 2023-12-29 13:41:35.329947857 +0000 ++++ pipewire-1.0.0/src/daemon/systemd/system/pipewire.socket 2023-12-29 13:44:04.291208172 +0000 +@@ -4,8 +4,8 @@ Description=PipeWire Multimedia System S + [Socket] + Priority=6 + ListenStream=%t/pipewire/pipewire-0 +-SocketUser=pipewire +-SocketGroup=pipewire ++SocketUser=root ++SocketGroup=root + SocketMode=0660 + + [Install] diff --git a/projects/ArchR/packages/audio/pipewire/patches/SDM845/001-increase-pulse-buffer-size.patch b/projects/ArchR/packages/audio/pipewire/patches/SDM845/001-increase-pulse-buffer-size.patch new file mode 100644 index 0000000000..e4c8cdb343 --- /dev/null +++ b/projects/ArchR/packages/audio/pipewire/patches/SDM845/001-increase-pulse-buffer-size.patch @@ -0,0 +1,20 @@ +diff --git a/src/daemon/pipewire-pulse.conf.in b/src/daemon/pipewire-pulse.conf.in +index 0d54cf9b90..bdea2ca072 100644 +--- a/src/daemon/pipewire-pulse.conf.in ++++ b/src/daemon/pipewire-pulse.conf.in +@@ -102,12 +102,12 @@ pulse.properties = { + ] + #server.dbus-name = "org.pulseaudio.Server" + #pulse.allow-module-loading = true +- #pulse.min.req = 128/48000 # 2.7ms ++ pulse.min.req = 960/48000 # 20ms + #pulse.default.req = 960/48000 # 20 milliseconds +- #pulse.min.frag = 128/48000 # 2.7ms ++ pulse.min.frag = 960/48000 # 20ms + #pulse.default.frag = 96000/48000 # 2 seconds + #pulse.default.tlength = 96000/48000 # 2 seconds +- #pulse.min.quantum = 128/48000 # 2.7ms ++ pulse.min.quantum = 960/48000 # 20ms + #pulse.idle.timeout = 0 # don't pause after underruns + #pulse.default.format = F32 + #pulse.default.position = [ FL FR ] diff --git a/projects/ArchR/packages/audio/pipewire/patches/SM8250/000-increase-buffer.patch b/projects/ArchR/packages/audio/pipewire/patches/SM8250/000-increase-buffer.patch new file mode 100644 index 0000000000..74d57d7292 --- /dev/null +++ b/projects/ArchR/packages/audio/pipewire/patches/SM8250/000-increase-buffer.patch @@ -0,0 +1,28 @@ +diff -rupbN pipewire.orig/src/daemon/pipewire-pulse.conf.in pipewire/src/daemon/pipewire-pulse.conf.in +--- pipewire.orig/src/daemon/pipewire-pulse.conf.in 2024-10-08 04:01:35.119453036 +0000 ++++ pipewire/src/daemon/pipewire-pulse.conf.in 2024-10-08 04:03:35.898636383 +0000 +@@ -27,7 +27,7 @@ context.modules = [ + { name = libpipewire-module-rt + args = { + nice.level = -11 +- #rt.prio = @rtprio_client@ ++ rt.prio = 99 + #rt.time.soft = -1 + #rt.time.hard = -1 + #uclamp.min = 0 +@@ -102,12 +102,12 @@ pulse.properties = { + ] + #server.dbus-name = "org.pulseaudio.Server" + #pulse.allow-module-loading = true +- #pulse.min.req = 128/48000 # 2.7ms ++ pulse.min.req = 1024/48000 # 2.7ms + #pulse.default.req = 960/48000 # 20 milliseconds +- #pulse.min.frag = 128/48000 # 2.7ms ++ pulse.min.frag = 1024/48000 # 2.7ms + #pulse.default.frag = 96000/48000 # 2 seconds + #pulse.default.tlength = 96000/48000 # 2 seconds +- #pulse.min.quantum = 128/48000 # 2.7ms ++ pulse.min.quantum = 1024/48000 # 2.7ms + #pulse.idle.timeout = 0 # don't pause after underruns + #pulse.default.format = F32 + #pulse.default.position = [ FL FR ] diff --git a/projects/ArchR/packages/audio/pipewire/patches/SM8550/001-increase-pulse-buffer-size.patch b/projects/ArchR/packages/audio/pipewire/patches/SM8550/001-increase-pulse-buffer-size.patch new file mode 100644 index 0000000000..e4c8cdb343 --- /dev/null +++ b/projects/ArchR/packages/audio/pipewire/patches/SM8550/001-increase-pulse-buffer-size.patch @@ -0,0 +1,20 @@ +diff --git a/src/daemon/pipewire-pulse.conf.in b/src/daemon/pipewire-pulse.conf.in +index 0d54cf9b90..bdea2ca072 100644 +--- a/src/daemon/pipewire-pulse.conf.in ++++ b/src/daemon/pipewire-pulse.conf.in +@@ -102,12 +102,12 @@ pulse.properties = { + ] + #server.dbus-name = "org.pulseaudio.Server" + #pulse.allow-module-loading = true +- #pulse.min.req = 128/48000 # 2.7ms ++ pulse.min.req = 960/48000 # 20ms + #pulse.default.req = 960/48000 # 20 milliseconds +- #pulse.min.frag = 128/48000 # 2.7ms ++ pulse.min.frag = 960/48000 # 20ms + #pulse.default.frag = 96000/48000 # 2 seconds + #pulse.default.tlength = 96000/48000 # 2 seconds +- #pulse.min.quantum = 128/48000 # 2.7ms ++ pulse.min.quantum = 960/48000 # 20ms + #pulse.idle.timeout = 0 # don't pause after underruns + #pulse.default.format = F32 + #pulse.default.position = [ FL FR ] diff --git a/projects/ArchR/packages/audio/pipewire/patches/SM8550/002-increase-pipewire-buffer-size.patch b/projects/ArchR/packages/audio/pipewire/patches/SM8550/002-increase-pipewire-buffer-size.patch new file mode 100644 index 0000000000..cb77ba5f20 --- /dev/null +++ b/projects/ArchR/packages/audio/pipewire/patches/SM8550/002-increase-pipewire-buffer-size.patch @@ -0,0 +1,13 @@ +diff --git a/src/daemon/pipewire.conf.in b/src/daemon/pipewire.conf.in +index 0d54cf9b90..bdea2ca072 100644 +--- a/src/daemon/pipewire.conf.in ++++ b/src/daemon/pipewire.conf.in +@@ -43,7 +43,7 @@ context.properties = { + #default.clock.rate = 48000 + #default.clock.allowed-rates = [ 48000 ] + #default.clock.quantum = 1024 +- #default.clock.min-quantum = 32 ++ default.clock.min-quantum = 960 + #default.clock.max-quantum = 2048 + #default.clock.quantum-limit = 8192 + #default.clock.quantum-floor = 4 diff --git a/projects/ArchR/packages/audio/pipewire/patches/SM8650/001-increase-pulse-buffer-size.patch b/projects/ArchR/packages/audio/pipewire/patches/SM8650/001-increase-pulse-buffer-size.patch new file mode 100644 index 0000000000..e4c8cdb343 --- /dev/null +++ b/projects/ArchR/packages/audio/pipewire/patches/SM8650/001-increase-pulse-buffer-size.patch @@ -0,0 +1,20 @@ +diff --git a/src/daemon/pipewire-pulse.conf.in b/src/daemon/pipewire-pulse.conf.in +index 0d54cf9b90..bdea2ca072 100644 +--- a/src/daemon/pipewire-pulse.conf.in ++++ b/src/daemon/pipewire-pulse.conf.in +@@ -102,12 +102,12 @@ pulse.properties = { + ] + #server.dbus-name = "org.pulseaudio.Server" + #pulse.allow-module-loading = true +- #pulse.min.req = 128/48000 # 2.7ms ++ pulse.min.req = 960/48000 # 20ms + #pulse.default.req = 960/48000 # 20 milliseconds +- #pulse.min.frag = 128/48000 # 2.7ms ++ pulse.min.frag = 960/48000 # 20ms + #pulse.default.frag = 96000/48000 # 2 seconds + #pulse.default.tlength = 96000/48000 # 2 seconds +- #pulse.min.quantum = 128/48000 # 2.7ms ++ pulse.min.quantum = 960/48000 # 20ms + #pulse.idle.timeout = 0 # don't pause after underruns + #pulse.default.format = F32 + #pulse.default.position = [ FL FR ] diff --git a/projects/ArchR/packages/audio/pipewire/patches/SM8650/002-increase-pipewire-buffer-size.patch b/projects/ArchR/packages/audio/pipewire/patches/SM8650/002-increase-pipewire-buffer-size.patch new file mode 100644 index 0000000000..cb77ba5f20 --- /dev/null +++ b/projects/ArchR/packages/audio/pipewire/patches/SM8650/002-increase-pipewire-buffer-size.patch @@ -0,0 +1,13 @@ +diff --git a/src/daemon/pipewire.conf.in b/src/daemon/pipewire.conf.in +index 0d54cf9b90..bdea2ca072 100644 +--- a/src/daemon/pipewire.conf.in ++++ b/src/daemon/pipewire.conf.in +@@ -43,7 +43,7 @@ context.properties = { + #default.clock.rate = 48000 + #default.clock.allowed-rates = [ 48000 ] + #default.clock.quantum = 1024 +- #default.clock.min-quantum = 32 ++ default.clock.min-quantum = 960 + #default.clock.max-quantum = 2048 + #default.clock.quantum-limit = 8192 + #default.clock.quantum-floor = 4 diff --git a/projects/ArchR/packages/audio/pipewire/system.d/pipewire-pulse.service b/projects/ArchR/packages/audio/pipewire/system.d/pipewire-pulse.service new file mode 100644 index 0000000000..29e21a8c92 --- /dev/null +++ b/projects/ArchR/packages/audio/pipewire/system.d/pipewire-pulse.service @@ -0,0 +1,23 @@ +[Unit] +Description=PipeWire PulseAudio Service +Requires=pipewire-pulse.socket +After=pipewire.service wireplumber.service +RequiresMountsFor=/storage + +[Service] +User=root +Type=simple +ExecStart=/usr/bin/pipewire-pulse +Restart=on-failure +RuntimeDirectory=pipewire +RuntimeDirectoryPreserve=yes +ExecStartPre=/bin/mkdir -p /var/run/0-runtime-dir/pulse +Environment=PIPEWIRE_RUNTIME_DIR=%t/pipewire +Environment=XDG_RUNTIME_DIR=/var/run/0-runtime-dir +Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/dbus/system_bus_socket +Environment=HOME=/storage +# Environment=PIPEWIRE_DEBUG=4 + +[Install] +Also=pipewire-pulse.socket +WantedBy=default.target diff --git a/projects/ArchR/packages/audio/pipewire/system.d/pipewire-pulse.socket b/projects/ArchR/packages/audio/pipewire/system.d/pipewire-pulse.socket new file mode 100644 index 0000000000..d27fb0e261 --- /dev/null +++ b/projects/ArchR/packages/audio/pipewire/system.d/pipewire-pulse.socket @@ -0,0 +1,10 @@ +[Unit] +Description=PipeWire PulseAudio +Conflicts=pulseaudio.socket + +[Socket] +Priority=6 +ListenStream=%t/pulse/native + +[Install] +WantedBy=sockets.target diff --git a/projects/ArchR/packages/audio/pulseaudio/config/pulse-daemon.conf.d/README b/projects/ArchR/packages/audio/pulseaudio/config/pulse-daemon.conf.d/README new file mode 100644 index 0000000000..350761ed58 --- /dev/null +++ b/projects/ArchR/packages/audio/pulseaudio/config/pulse-daemon.conf.d/README @@ -0,0 +1,5 @@ +Files have to have the .conf file name extension, but otherwise the file names can be +chosen freely. The files under pulse-daemon.conf.d are processed in alphabetical order. +In case the same option is set in multiple files, the last file to set an option +overrides earlier files. The main daemon.conf file is processed first, so +options set in files under pulse-daemon.conf.d override the main file. diff --git a/projects/ArchR/packages/audio/pulseaudio/config/system.pa b/projects/ArchR/packages/audio/pulseaudio/config/system.pa new file mode 100644 index 0000000000..653361e807 --- /dev/null +++ b/projects/ArchR/packages/audio/pulseaudio/config/system.pa @@ -0,0 +1,59 @@ +#!/usr/bin/pulseaudio -nF +# +# This file is part of PulseAudio. +# +# PulseAudio is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# PulseAudio is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with PulseAudio; if not, see . + +# This startup script is used only if PulseAudio is started in system +# mode. + +### Load several protocols +load-module module-native-protocol-unix + +### Automatically restore the volume of streams and devices +load-module module-stream-restore +load-module module-device-restore +load-module module-card-restore + +### Automatically restore the default sink/source when changed by the user +### during runtime +### NOTE: This should be loaded as early as possible so that subsequent modules +### that look up the default sink/source get the right value +load-module module-default-device-restore + +### Make sure we always have a sink around, even if it is a null sink. +load-module module-always-sink + +### Automatically suspend sinks/sources that become idle for too long +load-module module-suspend-on-idle + +### Automatically load modules for dbus +.ifexists module-dbus-protocol.so + load-module module-dbus-protocol +.endif + +### Automatically load modules for bluetooth +.ifexists module-bluetooth-policy.so + load-module module-bluetooth-policy +.endif + +.ifexists module-bluetooth-discover.so + load-module module-bluetooth-discover +.endif + +.ifexists module-zeroconf-publish.so + load-module module-zeroconf-publish +.endif + +load-module module-switch-on-connect diff --git a/projects/ArchR/packages/audio/pulseaudio/package.mk b/projects/ArchR/packages/audio/pulseaudio/package.mk new file mode 100644 index 0000000000..738045dc51 --- /dev/null +++ b/projects/ArchR/packages/audio/pulseaudio/package.mk @@ -0,0 +1,90 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="pulseaudio" +PKG_VERSION="17.0" +PKG_LICENSE="GPL" +PKG_SITE="http://pulseaudio.org/" +PKG_URL="http://www.freedesktop.org/software/pulseaudio/releases/${PKG_NAME}-${PKG_VERSION}.tar.xz" +PKG_DEPENDS_TARGET="toolchain libcap libsndfile libtool soxr speexdsp glib:host glib" +PKG_LONGDESC="PulseAudio is a sound system for POSIX OSes, meaning that it is a proxy for your sound applications." + +if [ "${AVAHI_DAEMON}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" avahi" + PKG_PULSEAUDIO_AVAHI="-Davahi=enabled" +else + PKG_PULSEAUDIO_AVAHI="-Davahi=disabled" +fi + +PKG_MESON_OPTS_TARGET="-Ddaemon=false \ + -Ddoxygen=false \ + -Dgcov=false \ + -Dman=false \ + -Dtests=false \ + -Dsystem_user=root \ + -Dsystem_group=root \ + -Daccess_group=root \ + -Ddatabase=simple \ + -Dlegacy-database-entry-format=false \ + -Dstream-restore-clear-old-devices=false \ + -Drunning-from-build-tree=false \ + -Datomic-arm-linux-helpers=true \ + -Datomic-arm-memory-barrier=false \ + -Dmodlibexecdir=/usr/lib/pulse \ + -Dudevrulesdir=/usr/lib/udev/rules.d \ + -Dalsa=disabled \ + -Dasyncns=disabled \ + ${PKG_PULSEAUDIO_AVAHI} \ + -Dbluez5=disabled + -Dbluez5-gstreamer=disabled \ + -Ddbus=disabled \ + -Delogind=disabled \ + -Dfftw=disabled \ + -Dglib=enabled \ + -Dgsettings=disabled \ + -Dgstreamer=disabled \ + -Dgtk=disabled \ + -Dhal-compat=false \ + -Dipv6=true \ + -Djack=disabled \ + -Dlirc=disabled \ + -Dopenssl=disabled \ + -Dorc=disabled \ + -Doss-output=disabled \ + -Dsamplerate=disabled \ + -Dsoxr=enabled \ + -Dspeex=enabled \ + -Dsystemd=disabled \ + -Dtcpwrap=disabled \ + -Dudev=disabled \ + -Dvalgrind=disabled \ + -Dx11=disabled \ + -Dadrian-aec=true \ + -Dwebrtc-aec=disabled" + +pre_configure_target() { + sed -e 's|; remixing-use-all-sink-channels = yes|; remixing-use-all-sink-channels = no|' \ + -i ${PKG_BUILD}/src/daemon/daemon.conf.in +} + +post_makeinstall_target() { + safe_remove ${INSTALL}/usr/include + safe_remove ${INSTALL}/usr/lib/cmake + safe_remove ${INSTALL}/usr/lib/pkgconfig + safe_remove ${INSTALL}/usr/share/vala + safe_remove ${INSTALL}/usr/share/zsh + safe_remove ${INSTALL}/usr/share/bash-completion + + cp ${PKG_DIR}/config/system.pa ${INSTALL}/etc/pulse/ + + # Sometimes apps cannot load `libpulsecommon`. It is located in ${libdir}/pulseaudio and is not intended to be loaded directly. + # Application loads `libpulse.so.0`, `libpulse` has `libpulsecommon` as a dep and RPATH set to ${libdir}/pulseaudio + # So, if there is error loading `libpulsecommon`, check RPATH of `libpulse` and `libpulse-simple` + # Adding pulseaudio subdir to `/etc/ld.so.conf.d/*.conf` may be a working hack for that, but please check/fix RPATH first +} + +# Deprecated by pipewire +#post_install() { +# enable_service pulseaudio.service +#} diff --git a/projects/ArchR/packages/audio/pulseaudio/patches/pulseaudio-100.01-never-append-dirty-to-server-module-version.patch b/projects/ArchR/packages/audio/pulseaudio/patches/pulseaudio-100.01-never-append-dirty-to-server-module-version.patch new file mode 100644 index 0000000000..8bea8d95fb --- /dev/null +++ b/projects/ArchR/packages/audio/pulseaudio/patches/pulseaudio-100.01-never-append-dirty-to-server-module-version.patch @@ -0,0 +1,24 @@ +From c9d7dcaa87f9ada49d75483a7c604dba27a0d71a Mon Sep 17 00:00:00 2001 +From: Stefan Saraev +Date: Tue, 7 Jan 2014 13:22:48 +0200 +Subject: [PATCH] never append -dirty to server/module version + +--- + git-version-gen | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +diff --git a/git-version-gen b/git-version-gen +index 9d65b80..fcf11fd 100755 +--- a/git-version-gen ++++ b/git-version-gen +@@ -152,6 +152,7 @@ v=`echo "$v" |sed 's/^v//'` + git status > /dev/null 2>&1 + + dirty=`sh -c 'git diff-index --name-only HEAD' 2>/dev/null` || dirty= ++dirty= + case "$dirty" in + '') ;; + *) # Append the suffix only if there isn't one already. +-- +1.7.2.5 + diff --git a/projects/ArchR/packages/audio/pulseaudio/patches/pulseaudio-100.02-check_uid.patch b/projects/ArchR/packages/audio/pulseaudio/patches/pulseaudio-100.02-check_uid.patch new file mode 100644 index 0000000000..df92750890 --- /dev/null +++ b/projects/ArchR/packages/audio/pulseaudio/patches/pulseaudio-100.02-check_uid.patch @@ -0,0 +1,13 @@ +--- pulseaudio-4.0.orig/src/pulsecore/core-util.c 2014-01-12 23:31:26.281525000 -0800 ++++ pulseaudio-4.0/src/pulsecore/core-util.c 2014-01-12 23:32:32.977118803 -0800 +@@ -1447,10 +1447,6 @@ + if (stat(p, &st) < 0) + return -errno; + +-#ifdef HAVE_GETUID +- if (st.st_uid != getuid() && st.st_uid != 0) +- return -EACCES; +-#endif + + return 0; + } diff --git a/projects/ArchR/packages/audio/sndio/package.mk b/projects/ArchR/packages/audio/sndio/package.mk new file mode 100644 index 0000000000..673f7226dd --- /dev/null +++ b/projects/ArchR/packages/audio/sndio/package.mk @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2026-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="sndio" +PKG_VERSION="1.10.0" +PKG_LICENSE="GPLv3" +PKG_SITE="https://sndio.org/" +PKG_URL="${PKG_SITE}/${PKG_NAME}-${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain alsa-lib" +PKG_LONGDESC="Sndio is a small audio and MIDI framework" +PKG_BUILD_FLAGS="+pic" +PKG_TOOLCHAIN="configure" + +configure_target() { + cd ${PKG_BUILD} + ./configure \ + --prefix=/usr \ + --enable-static +} + +make_target() { + make +} + +makeinstall_target() { + make DESTDIR=${SYSROOT_PREFIX} install +} diff --git a/projects/ArchR/packages/audio/wavpack/package.mk b/projects/ArchR/packages/audio/wavpack/package.mk new file mode 100644 index 0000000000..cea5cde12e --- /dev/null +++ b/projects/ArchR/packages/audio/wavpack/package.mk @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +. ${ROOT}/packages/audio/wavpack/package.mk + +PKG_CMAKE_OPTS_TARGET+=" -DBUILD_SHARED_LIBS=ON" diff --git a/projects/ArchR/packages/audio/wireplumber/package.mk b/projects/ArchR/packages/audio/wireplumber/package.mk new file mode 100644 index 0000000000..c6a4cc7360 --- /dev/null +++ b/projects/ArchR/packages/audio/wireplumber/package.mk @@ -0,0 +1,97 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="wireplumber" +PKG_VERSION="0.5.7" +PKG_LICENSE="MIT" +PKG_SITE="https://gitlab.freedesktop.org/pipewire/wireplumber" +PKG_URL="https://gitlab.freedesktop.org/pipewire/wireplumber/-/archive/${PKG_VERSION}/${PKG_NAME}-${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="pipewire glib lua54 glib:host" +PKG_LONGDESC="Session / policy manager implementation for PipeWire" + +PKG_MESON_OPTS_TARGET="-Dintrospection=disabled \ + -Ddoc=disabled \ + -Dsystem-lua=true \ + -Delogind=disabled \ + -Dsystemd=enabled \ + -Dsystemd-system-service=true \ + -Dsystemd-user-service=false \ + -Dsystemd-system-unit-dir=/usr/lib/systemd/system \ + -Dtests=false" + +post_makeinstall_target() { + # connect to the system bus + sed '/^\[Service\]/a Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/dbus/system_bus_socket' -i ${INSTALL}/usr/lib/systemd/system/wireplumber.service + + # ref https://gitlab.freedesktop.org/pipewire/wireplumber/-/commit/0da29f38181e391160fa8702623050b8544ec775 + # ref https://github.com/PipeWire/wireplumber/blob/master/docs/rst/daemon/configuration/migration.rst + # ref https://github.com/PipeWire/wireplumber/blob/master/docs/rst/daemon/configuration/features.rst + cat >${INSTALL}/usr/share/wireplumber/wireplumber.conf.d/89-disable-session-dbus-dependent-features.conf <${INSTALL}/usr/share/wireplumber/wireplumber.conf.d/89-disable-v4l2.conf <${INSTALL}/usr/share/wireplumber/wireplumber.conf.d/89-disable-bluez-hfphsp-backend.conf < ${INSTALL}/usr/share/wireplumber/wireplumber.conf.d/89-disable-libcamera.conf << EOF +wireplumber.profiles = { + main = { + monitor.libcamera = disabled + } +} +EOF + + cat >${INSTALL}/usr/share/wireplumber/wireplumber.conf.d/89-bluez-auto-connect.conf </dev/null 2>&1 + rsync -al ${LIBROOT}/usr/lib32/* ${INSTALL}/usr/lib32 >/dev/null 2>&1 + mkdir -p ${INSTALL}/usr/lib + ln -s /usr/lib32/${LDSO} ${INSTALL}/usr/lib/${LDSO} + + mkdir -p "${INSTALL}/etc/ld.so.conf.d" + echo "/usr/lib32" > "${INSTALL}/etc/ld.so.conf.d/${LIBARCH}-lib32.conf" + + mkdir -p ${INSTALL}/usr/bin + cp ${LIBROOT}/usr/bin/ldd ${INSTALL}/usr/bin/ldd32 +} diff --git a/projects/ArchR/packages/compat/wine/package.mk b/projects/ArchR/packages/compat/wine/package.mk new file mode 100644 index 0000000000..e62e8bd152 --- /dev/null +++ b/projects/ArchR/packages/compat/wine/package.mk @@ -0,0 +1,33 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="wine" +PKG_VERSION="11.0" +PKG_LICENSE="MIT" +PKG_SITE="https://github.com/Kron4ek/Wine-Builds" +PKG_URL="${PKG_SITE}/releases/download/${PKG_VERSION}/wine-${PKG_VERSION}-amd64.tar.xz" + +PKG_DEPENDS_TARGET="toolchain libXcomposite libXdmcp cups" +PKG_LONGDESC="Wine is a compatibility layer capable of running Windows applications" +PKG_TOOLCHAIN="manual" +PKG_WINE_TRICKS="https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks" + +unpack() { + mkdir -p ${PKG_BUILD} + tar --strip-components=1 -xf ${SOURCES}/${PKG_NAME}/${PKG_NAME}-${PKG_VERSION}.tar.xz -C ${PKG_BUILD} +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp -rf ${PKG_BUILD}/bin/* ${INSTALL}/usr/bin + + mkdir -p ${INSTALL}/usr/lib + cp -rf ${PKG_BUILD}/lib/* ${INSTALL}/usr/lib + + mkdir -p ${INSTALL}/usr/share + cp -rf ${PKG_BUILD}/share/* ${INSTALL}/usr/share + + curl -Lo ${INSTALL}/usr/bin/winetricks ${PKG_WINE_TRICKS} + + chmod +x ${INSTALL}/usr/bin/* +} diff --git a/projects/ArchR/packages/compress/cabextract/package.mk b/projects/ArchR/packages/compress/cabextract/package.mk new file mode 100644 index 0000000000..7a56ce59c7 --- /dev/null +++ b/projects/ArchR/packages/compress/cabextract/package.mk @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="cabextract" +PKG_VERSION="1.11" +PKG_LICENSE="GPLv3" +PKG_SITE="https://www.cabextract.org.uk" +PKG_URL="https://github.com/archr-linux/packages/raw/main/cabextract.tar.xz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="cabextract is Free Software for extracting Microsoft cabinet file" +PKG_TOOLCHAIN="make" + +make_target() { + : +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + mkdir -p ${INSTALL}/usr/lib + + cp -rf ${PKG_BUILD}/usr/bin/* ${INSTALL}/usr/bin + cp -rf ${PKG_BUILD}/usr/lib/* ${INSTALL}/usr/lib + + chmod +x ${INSTALL}/usr/bin/* +} diff --git a/projects/ArchR/packages/compress/gzip/package.mk b/projects/ArchR/packages/compress/gzip/package.mk new file mode 100644 index 0000000000..6e0bced369 --- /dev/null +++ b/projects/ArchR/packages/compress/gzip/package.mk @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="gzip" +PKG_VERSION="1.13" +PKG_LICENSE="GPL" +PKG_SITE="https://mirrors.kernel.org/gnu/gzip" +PKG_URL="https://mirrors.kernel.org/gnu/gzip/${PKG_NAME}-${PKG_VERSION}.tar.xz" +PKG_DEPENDS_HOST="ccache:host" +PKG_DEPENDS_TARGET="gcc:host" +PKG_LONGDESC="GNU Gzip is a popular data compression program originally written by Jean-loup Gailly for the GNU project." + +# For some weird reason gzip wrappers default to /bin/dash which we don't have +CONFIG_SHELL=/bin/bash +PKG_CONFIGURE_OPTS_TARGET=" CONFIG_SHELL=/bin/bash" diff --git a/projects/ArchR/packages/compress/libarchive/package.mk b/projects/ArchR/packages/compress/libarchive/package.mk new file mode 100644 index 0000000000..3961a47084 --- /dev/null +++ b/projects/ArchR/packages/compress/libarchive/package.mk @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +. ${ROOT}/packages/compress/libarchive/package.mk + +PKG_CMAKE_OPTS_TARGET="${PKG_CMAKE_OPTS_TARGET/-DBUILD_SHARED_LIBS=OFF/-DBUILD_SHARED_LIBS=ON}" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib + cp -rf libarchive/libarchive.so* ${INSTALL}/usr/lib + + mkdir -p ${SYSROOT_PREFIX}/usr/lib + cp -rf libarchive/libarchive.so* ${SYSROOT_PREFIX}/usr/lib + + mkdir -p ${SYSROOT_PREFIX}/usr/lib/pkgconfig + cp build/pkgconfig/libarchive.pc ${SYSROOT_PREFIX}/usr/lib/pkgconfig + + mkdir -p ${SYSROOT_PREFIX}/usr/include + cp ${PKG_BUILD}/libarchive/{archive.h,archive_entry.h} ${SYSROOT_PREFIX}/usr/include +} diff --git a/projects/ArchR/packages/compress/libzip/package.mk b/projects/ArchR/packages/compress/libzip/package.mk new file mode 100644 index 0000000000..7fe44ce691 --- /dev/null +++ b/projects/ArchR/packages/compress/libzip/package.mk @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2019-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="libzip" +PKG_VERSION="1.11.1" +PKG_LICENSE="GPL" +PKG_SITE="https://libzip.org/download" +PKG_URL="${PKG_SITE}/${PKG_NAME}-${PKG_VERSION}.tar.xz" +PKG_DEPENDS_TARGET="toolchain zlib gnutls openssl" +PKG_LONGDESC="A C library for reading, creating, and modifying zip archives." diff --git a/projects/ArchR/packages/compress/p7zip/package.mk b/projects/ArchR/packages/compress/p7zip/package.mk new file mode 100644 index 0000000000..cabab8410b --- /dev/null +++ b/projects/ArchR/packages/compress/p7zip/package.mk @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="p7zip" +PKG_VERSION="16.02" +PKG_SHA256="5eb20ac0e2944f6cb9c2d51dd6c4518941c185347d4089ea89087ffdd6e2341f" +PKG_LICENSE="GPL" +PKG_SITE="http://p7zip.sourceforge.net/" +PKG_URL="http://downloads.sourceforge.net/project/p7zip/p7zip/${PKG_VERSION}/p7zip_${PKG_VERSION}_src_all.tar.bz2" +PKG_DEPENDS_HOST="ccache:host" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="p7zip is a port of 7za.exe for POSIX systems like Unix." +PKG_TOOLCHAIN="manual" + +pre_build_host() { + rm -fr ${PKG_BUILD}/.${HOST_NAME} + mkdir -p ${PKG_BUILD}/.${HOST_NAME} + cp -RP ${PKG_BUILD}/* ${PKG_BUILD}/.${HOST_NAME} +} + +make_host() { + make CXX=${CXX} CC=${CC} -C ${PKG_BUILD}/.${HOST_NAME} 7za +} + +makeinstall_host() { + mkdir -p ${TOOLCHAIN}/bin + cp ${PKG_BUILD}/.${HOST_NAME}/bin/7za ${TOOLCHAIN}/bin +} + +pre_build_target() { + rm -fr ${PKG_BUILD}/.${TARGET_NAME} + mkdir -p ${PKG_BUILD}/.${TARGET_NAME} + cp -RP ${PKG_BUILD}/* ${PKG_BUILD}/.${TARGET_NAME} +} + +make_target() { + make CXX=${CXX} CC=${CC} -C ${PKG_BUILD}/.${TARGET_NAME} all3 +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp -pr ${PKG_BUILD}/.${TARGET_NAME}/bin/Codecs ${INSTALL}/usr/bin + cp -p ${PKG_BUILD}/.${TARGET_NAME}/bin/7z* ${INSTALL}/usr/bin +} diff --git a/projects/ArchR/packages/compress/p7zip/patches/p7zip-0100-CVE-2016-9296.patch b/projects/ArchR/packages/compress/p7zip/patches/p7zip-0100-CVE-2016-9296.patch new file mode 100644 index 0000000000..773f92a46e --- /dev/null +++ b/projects/ArchR/packages/compress/p7zip/patches/p7zip-0100-CVE-2016-9296.patch @@ -0,0 +1,12 @@ +--- ./CPP/7zip/Archive/7z/7zIn.cpp.orig 2016-11-21 01:42:29.460901230 +0000 ++++ ./CPP/7zip/Archive/7z/7zIn.cpp 2016-11-21 01:42:57.481197725 +0000 +@@ -1097,7 +1097,8 @@ HRESULT CInArchive::ReadAndDecodePackedS + if (CrcCalc(data, unpackSize) != folders.FolderCRCs.Vals[i]) + ThrowIncorrect(); + } +- HeadersSize += folders.PackPositions[folders.NumPackStreams]; ++ if (folders.PackPositions) ++ HeadersSize += folders.PackPositions[folders.NumPackStreams]; + return S_OK; + } + diff --git a/projects/ArchR/packages/compress/p7zip/patches/p7zip-0200-CVE-2017-17969.patch b/projects/ArchR/packages/compress/p7zip/patches/p7zip-0200-CVE-2017-17969.patch new file mode 100644 index 0000000000..ebc0ac93ef --- /dev/null +++ b/projects/ArchR/packages/compress/p7zip/patches/p7zip-0200-CVE-2017-17969.patch @@ -0,0 +1,26 @@ +From 79bca880ce7bcf07216c45f93afea545e0344418 Mon Sep 17 00:00:00 2001 +From: aone +Date: Mon, 5 Feb 2018 13:01:09 +0100 +Subject: [PATCH] Security fix CVE-2017-17969 + +--- + CPP/7zip/Compress/ShrinkDecoder.cpp | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/CPP/7zip/Compress/ShrinkDecoder.cpp b/CPP/7zip/Compress/ShrinkDecoder.cpp +index 80b7e67..5bb0559 100644 +--- a/CPP/7zip/Compress/ShrinkDecoder.cpp ++++ b/CPP/7zip/Compress/ShrinkDecoder.cpp +@@ -121,7 +121,12 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * + { + _stack[i++] = _suffixes[cur]; + cur = _parents[cur]; ++ if (cur >= kNumItems || i >= kNumItems) ++ break; + } ++ ++ if (cur >= kNumItems || i >= kNumItems) ++ break; + + _stack[i++] = (Byte)cur; + lastChar2 = (Byte)cur; diff --git a/projects/ArchR/packages/compress/p7zip/patches/p7zip-0300-CVE-2018-5996.patch b/projects/ArchR/packages/compress/p7zip/patches/p7zip-0300-CVE-2018-5996.patch new file mode 100644 index 0000000000..6733bff918 --- /dev/null +++ b/projects/ArchR/packages/compress/p7zip/patches/p7zip-0300-CVE-2018-5996.patch @@ -0,0 +1,221 @@ +From: Robert Luberda +Date: Sun, 28 Jan 2018 23:47:40 +0100 +Subject: CVE-2018-5996 + +Hopefully fix Memory Corruptions via RAR PPMd (CVE-2018-5996) by +applying a few changes from 7Zip 18.00-beta. + +Bug-Debian: https://bugs.debian.org/#888314 +--- + CPP/7zip/Compress/Rar1Decoder.cpp | 13 +++++++++---- + CPP/7zip/Compress/Rar1Decoder.h | 1 + + CPP/7zip/Compress/Rar2Decoder.cpp | 10 +++++++++- + CPP/7zip/Compress/Rar2Decoder.h | 1 + + CPP/7zip/Compress/Rar3Decoder.cpp | 23 ++++++++++++++++++++--- + CPP/7zip/Compress/Rar3Decoder.h | 2 ++ + 6 files changed, 42 insertions(+), 8 deletions(-) + +diff --git a/CPP/7zip/Compress/Rar1Decoder.cpp b/CPP/7zip/Compress/Rar1Decoder.cpp +index 1aaedcc..68030c7 100644 +--- a/CPP/7zip/Compress/Rar1Decoder.cpp ++++ b/CPP/7zip/Compress/Rar1Decoder.cpp +@@ -29,7 +29,7 @@ public: + }; + */ + +-CDecoder::CDecoder(): m_IsSolid(false) { } ++CDecoder::CDecoder(): m_IsSolid(false), _errorMode(false) { } + + void CDecoder::InitStructures() + { +@@ -406,9 +406,14 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * + InitData(); + if (!m_IsSolid) + { ++ _errorMode = false; + InitStructures(); + InitHuff(); + } ++ ++ if (_errorMode) ++ return S_FALSE; ++ + if (m_UnpackSize > 0) + { + GetFlagsBuf(); +@@ -477,9 +482,9 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) + { + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } +- catch(const CInBufferException &e) { return e.ErrorCode; } +- catch(const CLzOutWindowException &e) { return e.ErrorCode; } +- catch(...) { return S_FALSE; } ++ catch(const CInBufferException &e) { _errorMode = true; return e.ErrorCode; } ++ catch(const CLzOutWindowException &e) { _errorMode = true; return e.ErrorCode; } ++ catch(...) { _errorMode = true; return S_FALSE; } + } + + STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) +diff --git a/CPP/7zip/Compress/Rar1Decoder.h b/CPP/7zip/Compress/Rar1Decoder.h +index 630f089..01b606b 100644 +--- a/CPP/7zip/Compress/Rar1Decoder.h ++++ b/CPP/7zip/Compress/Rar1Decoder.h +@@ -39,6 +39,7 @@ public: + + Int64 m_UnpackSize; + bool m_IsSolid; ++ bool _errorMode; + + UInt32 ReadBits(int numBits); + HRESULT CopyBlock(UInt32 distance, UInt32 len); +diff --git a/CPP/7zip/Compress/Rar2Decoder.cpp b/CPP/7zip/Compress/Rar2Decoder.cpp +index b3f2b4b..0580c8d 100644 +--- a/CPP/7zip/Compress/Rar2Decoder.cpp ++++ b/CPP/7zip/Compress/Rar2Decoder.cpp +@@ -80,7 +80,8 @@ static const UInt32 kHistorySize = 1 << 20; + static const UInt32 kWindowReservSize = (1 << 22) + 256; + + CDecoder::CDecoder(): +- m_IsSolid(false) ++ m_IsSolid(false), ++ m_TablesOK(false) + { + } + +@@ -100,6 +101,8 @@ UInt32 CDecoder::ReadBits(unsigned numBits) { return m_InBitStream.ReadBits(numB + + bool CDecoder::ReadTables(void) + { ++ m_TablesOK = false; ++ + Byte levelLevels[kLevelTableSize]; + Byte newLevels[kMaxTableSize]; + m_AudioMode = (ReadBits(1) == 1); +@@ -170,6 +173,8 @@ bool CDecoder::ReadTables(void) + } + + memcpy(m_LastLevels, newLevels, kMaxTableSize); ++ m_TablesOK = true; ++ + return true; + } + +@@ -344,6 +349,9 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * + return S_FALSE; + } + ++ if (!m_TablesOK) ++ return S_FALSE; ++ + UInt64 startPos = m_OutWindowStream.GetProcessedSize(); + while (pos < unPackSize) + { +diff --git a/CPP/7zip/Compress/Rar2Decoder.h b/CPP/7zip/Compress/Rar2Decoder.h +index 3a0535c..0e9005f 100644 +--- a/CPP/7zip/Compress/Rar2Decoder.h ++++ b/CPP/7zip/Compress/Rar2Decoder.h +@@ -139,6 +139,7 @@ class CDecoder : + + UInt64 m_PackSize; + bool m_IsSolid; ++ bool m_TablesOK; + + void InitStructures(); + UInt32 ReadBits(unsigned numBits); +diff --git a/CPP/7zip/Compress/Rar3Decoder.cpp b/CPP/7zip/Compress/Rar3Decoder.cpp +index 3bf2513..6cb8a6a 100644 +--- a/CPP/7zip/Compress/Rar3Decoder.cpp ++++ b/CPP/7zip/Compress/Rar3Decoder.cpp +@@ -92,7 +92,8 @@ CDecoder::CDecoder(): + _writtenFileSize(0), + _vmData(0), + _vmCode(0), +- m_IsSolid(false) ++ m_IsSolid(false), ++ _errorMode(false) + { + Ppmd7_Construct(&_ppmd); + } +@@ -545,6 +546,9 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing) + return InitPPM(); + } + ++ TablesRead = false; ++ TablesOK = false; ++ + _lzMode = true; + PrevAlignBits = 0; + PrevAlignCount = 0; +@@ -606,6 +610,9 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing) + } + } + } ++ if (InputEofError()) ++ return S_FALSE; ++ + TablesRead = true; + + // original code has check here: +@@ -623,6 +630,9 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing) + RIF(m_LenDecoder.Build(&newLevels[kMainTableSize + kDistTableSize + kAlignTableSize])); + + memcpy(m_LastLevels, newLevels, kTablesSizesSum); ++ ++ TablesOK = true; ++ + return S_OK; + } + +@@ -824,7 +834,12 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress) + PpmEscChar = 2; + PpmError = true; + InitFilters(); ++ _errorMode = false; + } ++ ++ if (_errorMode) ++ return S_FALSE; ++ + if (!m_IsSolid || !TablesRead) + { + bool keepDecompressing; +@@ -838,6 +853,8 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress) + bool keepDecompressing; + if (_lzMode) + { ++ if (!TablesOK) ++ return S_FALSE; + RINOK(DecodeLZ(keepDecompressing)) + } + else +@@ -901,8 +918,8 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream + _unpackSize = outSize ? *outSize : (UInt64)(Int64)-1; + return CodeReal(progress); + } +- catch(const CInBufferException &e) { return e.ErrorCode; } +- catch(...) { return S_FALSE; } ++ catch(const CInBufferException &e) { _errorMode = true; return e.ErrorCode; } ++ catch(...) { _errorMode = true; return S_FALSE; } + // CNewException is possible here. But probably CNewException is caused + // by error in data stream. + } +diff --git a/CPP/7zip/Compress/Rar3Decoder.h b/CPP/7zip/Compress/Rar3Decoder.h +index c130cec..2f72d7d 100644 +--- a/CPP/7zip/Compress/Rar3Decoder.h ++++ b/CPP/7zip/Compress/Rar3Decoder.h +@@ -192,6 +192,7 @@ class CDecoder: + UInt32 _lastFilter; + + bool m_IsSolid; ++ bool _errorMode; + + bool _lzMode; + bool _unsupportedFilter; +@@ -200,6 +201,7 @@ class CDecoder: + UInt32 PrevAlignCount; + + bool TablesRead; ++ bool TablesOK; + + CPpmd7 _ppmd; + int PpmEscChar; diff --git a/projects/ArchR/packages/compress/p7zip/patches/p7zip-0400-CVE-2018-10115.patch b/projects/ArchR/packages/compress/p7zip/patches/p7zip-0400-CVE-2018-10115.patch new file mode 100644 index 0000000000..7d9c4bf81f --- /dev/null +++ b/projects/ArchR/packages/compress/p7zip/patches/p7zip-0400-CVE-2018-10115.patch @@ -0,0 +1,311 @@ +From: Robert Luberda +Date: Tue, 29 May 2018 23:59:09 +0200 +Subject: Fix CVE-2018-10115 + +Apply "patch" taken from https://landave.io/files/patch_7zip_CVE-2018-10115.txt + + +Bugs-Debian: https://bugs.debian.org/897674 +--- + CPP/7zip/Compress/Rar1Decoder.cpp | 16 +++++++++++----- + CPP/7zip/Compress/Rar1Decoder.h | 3 ++- + CPP/7zip/Compress/Rar2Decoder.cpp | 17 +++++++++++++---- + CPP/7zip/Compress/Rar2Decoder.h | 3 ++- + CPP/7zip/Compress/Rar3Decoder.cpp | 19 +++++++++++++++---- + CPP/7zip/Compress/Rar3Decoder.h | 3 ++- + CPP/7zip/Compress/Rar5Decoder.cpp | 8 ++++++++ + CPP/7zip/Compress/Rar5Decoder.h | 1 + + 8 files changed, 54 insertions(+), 16 deletions(-) + +diff --git a/CPP/7zip/Compress/Rar1Decoder.cpp b/CPP/7zip/Compress/Rar1Decoder.cpp +index 68030c7..8c890c8 100644 +--- a/CPP/7zip/Compress/Rar1Decoder.cpp ++++ b/CPP/7zip/Compress/Rar1Decoder.cpp +@@ -29,7 +29,7 @@ public: + }; + */ + +-CDecoder::CDecoder(): m_IsSolid(false), _errorMode(false) { } ++CDecoder::CDecoder(): _isSolid(false), _solidAllowed(false), _errorMode(false) { } + + void CDecoder::InitStructures() + { +@@ -345,7 +345,7 @@ void CDecoder::GetFlagsBuf() + + void CDecoder::InitData() + { +- if (!m_IsSolid) ++ if (!_isSolid) + { + AvrPlcB = AvrLn1 = AvrLn2 = AvrLn3 = NumHuf = Buf60 = 0; + AvrPlc = 0x3500; +@@ -391,6 +391,11 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * + if (inSize == NULL || outSize == NULL) + return E_INVALIDARG; + ++ if (_isSolid && !_solidAllowed) ++ return S_FALSE; ++ ++ _solidAllowed = false; ++ + if (!m_OutWindowStream.Create(kHistorySize)) + return E_OUTOFMEMORY; + if (!m_InBitStream.Create(1 << 20)) +@@ -398,13 +403,13 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * + + m_UnpackSize = (Int64)*outSize; + m_OutWindowStream.SetStream(outStream); +- m_OutWindowStream.Init(m_IsSolid); ++ m_OutWindowStream.Init(_isSolid); + m_InBitStream.SetStream(inStream); + m_InBitStream.Init(); + + // CCoderReleaser coderReleaser(this); + InitData(); +- if (!m_IsSolid) ++ if (!_isSolid) + { + _errorMode = false; + InitStructures(); +@@ -475,6 +480,7 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * + } + if (m_UnpackSize < 0) + return S_FALSE; ++ _solidAllowed = true; + return m_OutWindowStream.Flush(); + } + +@@ -491,7 +497,7 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) + { + if (size < 1) + return E_INVALIDARG; +- m_IsSolid = ((data[0] & 1) != 0); ++ _isSolid = ((data[0] & 1) != 0); + return S_OK; + } + +diff --git a/CPP/7zip/Compress/Rar1Decoder.h b/CPP/7zip/Compress/Rar1Decoder.h +index 01b606b..8abb3a3 100644 +--- a/CPP/7zip/Compress/Rar1Decoder.h ++++ b/CPP/7zip/Compress/Rar1Decoder.h +@@ -38,7 +38,8 @@ public: + UInt32 LastLength; + + Int64 m_UnpackSize; +- bool m_IsSolid; ++ bool _isSolid; ++ bool _solidAllowed; + bool _errorMode; + + UInt32 ReadBits(int numBits); +diff --git a/CPP/7zip/Compress/Rar2Decoder.cpp b/CPP/7zip/Compress/Rar2Decoder.cpp +index 0580c8d..be8d842 100644 +--- a/CPP/7zip/Compress/Rar2Decoder.cpp ++++ b/CPP/7zip/Compress/Rar2Decoder.cpp +@@ -80,7 +80,8 @@ static const UInt32 kHistorySize = 1 << 20; + static const UInt32 kWindowReservSize = (1 << 22) + 256; + + CDecoder::CDecoder(): +- m_IsSolid(false), ++ _isSolid(false), ++ _solidAllowed(false), + m_TablesOK(false) + { + } +@@ -320,6 +321,10 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * + if (inSize == NULL || outSize == NULL) + return E_INVALIDARG; + ++ if (_isSolid && !_solidAllowed) ++ return S_FALSE; ++ _solidAllowed = false; ++ + if (!m_OutWindowStream.Create(kHistorySize)) + return E_OUTOFMEMORY; + if (!m_InBitStream.Create(1 << 20)) +@@ -330,12 +335,12 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * + UInt64 pos = 0, unPackSize = *outSize; + + m_OutWindowStream.SetStream(outStream); +- m_OutWindowStream.Init(m_IsSolid); ++ m_OutWindowStream.Init(_isSolid); + m_InBitStream.SetStream(inStream); + m_InBitStream.Init(); + + // CCoderReleaser coderReleaser(this); +- if (!m_IsSolid) ++ if (!_isSolid) + { + InitStructures(); + if (unPackSize == 0) +@@ -343,6 +348,7 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * + if (m_InBitStream.GetProcessedSize() + 2 <= m_PackSize) // test it: probably incorrect; + if (!ReadTables()) + return S_FALSE; ++ _solidAllowed = true; + return S_OK; + } + if (!ReadTables()) +@@ -386,6 +392,9 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * + + if (!ReadLastTables()) + return S_FALSE; ++ ++ _solidAllowed = true; ++ + return m_OutWindowStream.Flush(); + } + +@@ -402,7 +411,7 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) + { + if (size < 1) + return E_INVALIDARG; +- m_IsSolid = ((data[0] & 1) != 0); ++ _isSolid = ((data[0] & 1) != 0); + return S_OK; + } + +diff --git a/CPP/7zip/Compress/Rar2Decoder.h b/CPP/7zip/Compress/Rar2Decoder.h +index 0e9005f..370bce2 100644 +--- a/CPP/7zip/Compress/Rar2Decoder.h ++++ b/CPP/7zip/Compress/Rar2Decoder.h +@@ -138,7 +138,8 @@ class CDecoder : + Byte m_LastLevels[kMaxTableSize]; + + UInt64 m_PackSize; +- bool m_IsSolid; ++ bool _isSolid; ++ bool _solidAllowed; + bool m_TablesOK; + + void InitStructures(); +diff --git a/CPP/7zip/Compress/Rar3Decoder.cpp b/CPP/7zip/Compress/Rar3Decoder.cpp +index 6cb8a6a..7b85833 100644 +--- a/CPP/7zip/Compress/Rar3Decoder.cpp ++++ b/CPP/7zip/Compress/Rar3Decoder.cpp +@@ -92,7 +92,8 @@ CDecoder::CDecoder(): + _writtenFileSize(0), + _vmData(0), + _vmCode(0), +- m_IsSolid(false), ++ _isSolid(false), ++ _solidAllowed(false), + _errorMode(false) + { + Ppmd7_Construct(&_ppmd); +@@ -821,7 +822,7 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress) + { + _writtenFileSize = 0; + _unsupportedFilter = false; +- if (!m_IsSolid) ++ if (!_isSolid) + { + _lzSize = 0; + _winPos = 0; +@@ -840,12 +841,15 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress) + if (_errorMode) + return S_FALSE; + +- if (!m_IsSolid || !TablesRead) ++ if (!_isSolid || !TablesRead) + { + bool keepDecompressing; + RINOK(ReadTables(keepDecompressing)); + if (!keepDecompressing) ++ { ++ _solidAllowed = true; + return S_OK; ++ } + } + + for (;;) +@@ -870,6 +874,9 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress) + if (!keepDecompressing) + break; + } ++ ++ _solidAllowed = true; ++ + RINOK(WriteBuf()); + UInt64 packSize = m_InBitStream.BitDecoder.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &_writtenFileSize)); +@@ -890,6 +897,10 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream + if (!inSize) + return E_INVALIDARG; + ++ if (_isSolid && !_solidAllowed) ++ return S_FALSE; ++ _solidAllowed = false; ++ + if (!_vmData) + { + _vmData = (Byte *)::MidAlloc(kVmDataSizeMax + kVmCodeSizeMax); +@@ -928,7 +939,7 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) + { + if (size < 1) + return E_INVALIDARG; +- m_IsSolid = ((data[0] & 1) != 0); ++ _isSolid = ((data[0] & 1) != 0); + return S_OK; + } + +diff --git a/CPP/7zip/Compress/Rar3Decoder.h b/CPP/7zip/Compress/Rar3Decoder.h +index 2f72d7d..32c8943 100644 +--- a/CPP/7zip/Compress/Rar3Decoder.h ++++ b/CPP/7zip/Compress/Rar3Decoder.h +@@ -191,7 +191,8 @@ class CDecoder: + CRecordVector _tempFilters; + UInt32 _lastFilter; + +- bool m_IsSolid; ++ bool _isSolid; ++ bool _solidAllowed; + bool _errorMode; + + bool _lzMode; +diff --git a/CPP/7zip/Compress/Rar5Decoder.cpp b/CPP/7zip/Compress/Rar5Decoder.cpp +index dc8830f..a826d5a 100644 +--- a/CPP/7zip/Compress/Rar5Decoder.cpp ++++ b/CPP/7zip/Compress/Rar5Decoder.cpp +@@ -72,6 +72,7 @@ CDecoder::CDecoder(): + _writtenFileSize(0), + _dictSizeLog(0), + _isSolid(false), ++ _solidAllowed(false), + _wasInit(false), + _inputBuf(NULL) + { +@@ -801,7 +802,10 @@ HRESULT CDecoder::CodeReal() + */ + + if (res == S_OK) ++ { ++ _solidAllowed = true; + res = res2; ++ } + + if (res == S_OK && _unpackSize_Defined && _writtenFileSize != _unpackSize) + return S_FALSE; +@@ -821,6 +825,10 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream + { + try + { ++ if (_isSolid && !_solidAllowed) ++ return S_FALSE; ++ _solidAllowed = false; ++ + if (_dictSizeLog >= sizeof(size_t) * 8) + return E_NOTIMPL; + +diff --git a/CPP/7zip/Compress/Rar5Decoder.h b/CPP/7zip/Compress/Rar5Decoder.h +index b0a4dd1..3db5018 100644 +--- a/CPP/7zip/Compress/Rar5Decoder.h ++++ b/CPP/7zip/Compress/Rar5Decoder.h +@@ -271,6 +271,7 @@ class CDecoder: + Byte _dictSizeLog; + bool _tableWasFilled; + bool _isSolid; ++ bool _solidAllowed; + bool _wasInit; + + UInt32 _reps[kNumReps]; diff --git a/projects/ArchR/packages/compress/p7zip/patches/p7zip-0500-gcc10-build-fix.patch b/projects/ArchR/packages/compress/p7zip/patches/p7zip-0500-gcc10-build-fix.patch new file mode 100644 index 0000000000..45f9f84af4 --- /dev/null +++ b/projects/ArchR/packages/compress/p7zip/patches/p7zip-0500-gcc10-build-fix.patch @@ -0,0 +1,26 @@ +diff -Nrup a/CPP/Windows/ErrorMsg.cpp b/CPP/Windows/ErrorMsg.cpp +--- a/CPP/Windows/ErrorMsg.cpp 2015-01-18 11:20:28.000000000 -0700 ++++ b/CPP/Windows/ErrorMsg.cpp 2019-09-24 13:01:18.887289152 -0600 +@@ -14,14 +14,14 @@ UString MyFormatMessage(DWORD errorCode) + AString msg; + + switch(errorCode) { +- case ERROR_NO_MORE_FILES : txt = "No more files"; break ; +- case E_NOTIMPL : txt = "E_NOTIMPL"; break ; +- case E_NOINTERFACE : txt = "E_NOINTERFACE"; break ; +- case E_ABORT : txt = "E_ABORT"; break ; +- case E_FAIL : txt = "E_FAIL"; break ; +- case STG_E_INVALIDFUNCTION : txt = "STG_E_INVALIDFUNCTION"; break ; +- case E_OUTOFMEMORY : txt = "E_OUTOFMEMORY"; break ; +- case E_INVALIDARG : txt = "E_INVALIDARG"; break ; ++ case unsigned (ERROR_NO_MORE_FILES) : txt = "No more files"; break ; ++ case unsigned (E_NOTIMPL) : txt = "E_NOTIMPL"; break ; ++ case unsigned (E_NOINTERFACE) : txt = "E_NOINTERFACE"; break ; ++ case unsigned (E_ABORT) : txt = "E_ABORT"; break ; ++ case unsigned (E_FAIL) : txt = "E_FAIL"; break ; ++ case unsigned (STG_E_INVALIDFUNCTION) : txt = "STG_E_INVALIDFUNCTION"; break ; ++ case unsigned (E_OUTOFMEMORY) : txt = "E_OUTOFMEMORY"; break ; ++ case unsigned (E_INVALIDARG) : txt = "E_INVALIDARG"; break ; + case ERROR_DIRECTORY : txt = "Error Directory"; break ; + default: + txt = strerror(errorCode); diff --git a/projects/ArchR/packages/compress/p7zip/patches/p7zip-0501-change-numMethods-from-bool-to-unsigned.patch b/projects/ArchR/packages/compress/p7zip/patches/p7zip-0501-change-numMethods-from-bool-to-unsigned.patch new file mode 100644 index 0000000000..93eb0588c0 --- /dev/null +++ b/projects/ArchR/packages/compress/p7zip/patches/p7zip-0501-change-numMethods-from-bool-to-unsigned.patch @@ -0,0 +1,34 @@ +From 0820ef4b9238c1e39ae5bda32cc08cce3fd3ce89 Mon Sep 17 00:00:00 2001 +From: Nisha Parrakat +Date: Wed, 26 May 2021 19:59:28 +0000 +Subject: [PATCH] fixes the below error + +| ../../../../CPP/7zip/Archive/Wim/WimHandler.cpp: In member function 'virtual LONG NArchive::NWim::CHandler::GetArchiveProperty(PROPID, PROPVARIANT*)': +| ../../../../CPP/7zip/Archive/Wim/WimHandler.cpp:308:11: error: use of an operand of type 'bool' in 'operator++' is forbidden in C++17 +| 308 | numMethods++; +| | ^~~~~~~~~~ +| ../../../../CPP/7zip/Archive/Wim/WimHandler.cpp:318:9: error: use of an operand of type 'bool' in 'operator++' is forbidden in C++17 +| 318 | numMethods++; + +use unsigned instead of bool +Signed-off-by: Nisha Parrakat + +Upstream-Status: Pending + +--- + CPP/7zip/Archive/Wim/WimHandler.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/CPP/7zip/Archive/Wim/WimHandler.cpp b/CPP/7zip/Archive/Wim/WimHandler.cpp +index 27d3298..4ff5cfe 100644 +--- a/CPP/7zip/Archive/Wim/WimHandler.cpp ++++ b/CPP/7zip/Archive/Wim/WimHandler.cpp +@@ -298,7 +298,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) + + AString res; + +- bool numMethods = 0; ++ unsigned numMethods = 0; + for (unsigned i = 0; i < ARRAY_SIZE(k_Methods); i++) + { + if (methodMask & ((UInt32)1 << i)) diff --git a/projects/ArchR/packages/compress/xz/package.mk b/projects/ArchR/packages/compress/xz/package.mk new file mode 100644 index 0000000000..f156fe0f74 --- /dev/null +++ b/projects/ArchR/packages/compress/xz/package.mk @@ -0,0 +1,34 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="xz" +PKG_VERSION="5.8.1" +PKG_SHA256="0b54f79df85912504de0b14aec7971e3f964491af1812d83447005807513cd9e" +PKG_LICENSE="GPL" +PKG_SITE="https://tukaani.org/xz/" +PKG_URL="https://github.com/tukaani-project/xz/releases/download/v${PKG_VERSION}/${PKG_NAME}-${PKG_VERSION}.tar.xz" +PKG_DEPENDS_HOST="ccache:host" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="A free general-purpose data compression software with high compression ratio." +PKG_BUILD_FLAGS="+pic +pic:host" +PKG_TOOLCHAIN="configure" + +# never build shared or k0p happens when building +# on fedora due to host selinux/liblzma +PKG_CONFIGURE_OPTS_HOST="--disable-shared --enable-static \ + --disable-lzmadec \ + --disable-lzmainfo \ + --enable-lzma-links \ + --disable-nls \ + --disable-scripts \ + --enable-symbol-versions=no" + +PKG_CONFIGURE_OPTS_TARGET="--enable-shared \ + --disable-static \ + --enable-symbol-versions=yes" + +post_makeinstall_target() { + rm -rf ${INSTALL}/usr/bin +} diff --git a/projects/ArchR/packages/compress/xz/patches/xz-01-init-uninitialized-variables.patch b/projects/ArchR/packages/compress/xz/patches/xz-01-init-uninitialized-variables.patch new file mode 100644 index 0000000000..0d88880702 --- /dev/null +++ b/projects/ArchR/packages/compress/xz/patches/xz-01-init-uninitialized-variables.patch @@ -0,0 +1,27 @@ +From 5cd389f1fe1fe095cdf555194df875ee3ab445cf Mon Sep 17 00:00:00 2001 +From: MilhouseVH +Date: Sun, 26 Nov 2017 22:21:15 +0000 +Subject: [PATCH] uninitialized variables build error + +--- + src/liblzma/lzma/lzma_encoder.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/liblzma/lzma/lzma_encoder.c b/src/liblzma/lzma/lzma_encoder.c +index ba9ce69..08e8c87 100644 +--- a/src/liblzma/lzma/lzma_encoder.c ++++ b/src/liblzma/lzma/lzma_encoder.c +@@ -359,8 +359,8 @@ lzma_lzma_encode(lzma_lzma1_encoder *restrict coder, lzma_mf *restrict mf, + // - UINT32_MAX: not a match but a literal + // Value ranges for len: + // - [MATCH_LEN_MIN, MATCH_LEN_MAX] +- uint32_t len; +- uint32_t back; ++ uint32_t len = 0; ++ uint32_t back = 0; + + if (coder->fast_mode) + lzma_lzma_optimum_fast(coder, mf, &back, &len); +-- +2.14.1 + diff --git a/projects/ArchR/packages/debug/apitrace/package.mk b/projects/ArchR/packages/debug/apitrace/package.mk new file mode 100644 index 0000000000..5c27d518d1 --- /dev/null +++ b/projects/ArchR/packages/debug/apitrace/package.mk @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="apitrace" +PKG_VERSION="45a005875d348b055d5b88dca285c109dee90457" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/apitrace/apitrace" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain waffle Python3:host" +PKG_LONGDESC="A set of tools to trace, replay, and inspect OpenGL calls" +GET_HANDLER_SUPPORT="git" + +PKG_CMAKE_OPTS_TARGET=" -DENABLE_GUI=OFF -DENABLE_EGL=ON -DENABLE_WAFFLE=ON " diff --git a/projects/ArchR/packages/debug/strace/package.mk b/projects/ArchR/packages/debug/strace/package.mk new file mode 100644 index 0000000000..4cfffdaae6 --- /dev/null +++ b/projects/ArchR/packages/debug/strace/package.mk @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="strace" +PKG_LICENSE="BSD" +PKG_SITE="https://strace.io/" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="strace is a diagnostic, debugging and instructional userspace utility" +PKG_TOOLCHAIN="autotools" +PKG_BUILD_FLAGS="-cfg-libs" + +case "${DEVICE}" in + SM8650|SM8550|SM8250|H700) + PKG_VERSION="6.19" + PKG_SHA256="e076c851eec0972486ec842164fdc54547f9d17abd3d1449de8b120f5d299143" + ;; + RK3399|S922X|RK3566) + PKG_VERSION="6.18" + PKG_SHA256="0ad5dcba973a69e779650ef1cb335b12ee60716fc7326609895bd33e6d2a7325" + ;; + *) + PKG_VERSION="6.17" + PKG_SHA256="0a7c7bedc7efc076f3242a0310af2ae63c292a36dd4236f079e88a93e98cb9c0" + ;; +esac +PKG_URL="https://strace.io/files/${PKG_VERSION}/strace-${PKG_VERSION}.tar.xz" + +if [ "${TARGET_ARCH}" = x86_64 -o "${TARGET_ARCH}" = "aarch64" ]; then + PKG_CONFIGURE_OPTS_TARGET="--enable-mpers=no" +fi diff --git a/projects/ArchR/packages/debug/strace/patches/strace-0001-autoreconf.patch b/projects/ArchR/packages/debug/strace/patches/strace-0001-autoreconf.patch new file mode 100644 index 0000000000..41dd01be4b --- /dev/null +++ b/projects/ArchR/packages/debug/strace/patches/strace-0001-autoreconf.patch @@ -0,0 +1,17 @@ +diff --git a/configure.ac b/configure.ac +index 4e7bc2a89..3b762c94c 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -11,11 +11,7 @@ + # SPDX-License-Identifier: LGPL-2.1-or-later + + AC_PREREQ(2.57) +-AC_INIT([strace], +- st_esyscmd_s([./build-aux/git-version-gen .tarball-version]), +- [strace-devel@lists.strace.io], +- [strace], +- [https://strace.io]) ++AC_INIT([strace],[5.11]) + m4_define([copyright_year], st_esyscmd_s([./build-aux/copyright-year-gen .year])) + m4_define([manpage_date], st_esyscmd_s([./build-aux/file-date-gen doc/strace.1.in])) + AC_COPYRIGHT([Copyright (c) 1999-]copyright_year[ The strace developers.]) diff --git a/projects/ArchR/packages/debug/strace/patches/strace-0002-fix-autoconf-archive.patch b/projects/ArchR/packages/debug/strace/patches/strace-0002-fix-autoconf-archive.patch new file mode 100644 index 0000000000..4e0927da66 --- /dev/null +++ b/projects/ArchR/packages/debug/strace/patches/strace-0002-fix-autoconf-archive.patch @@ -0,0 +1,39 @@ +From ba71a5f3778df1bb19ba593f6a5550c01f5349ad Mon Sep 17 00:00:00 2001 +From: MilhouseVH +Date: Tue, 28 Jan 2020 03:17:14 +0000 +Subject: [PATCH] fix API change since autoconf-archive-2019.01.06 + +--- + Makefile.am | 2 +- + Makefile.in | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index 723460f2e..a6a0f5f9c 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -408,7 +408,7 @@ strace_LDADD += $(libiberty_LIBS) + endif + endif + +-@CODE_COVERAGE_RULES@ ++include $(top_srcdir)/aminclude_static.am + CODE_COVERAGE_BRANCH_COVERAGE = 1 + CODE_COVERAGE_GENHTML_OPTIONS = $(CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT) \ + --prefix $(shell cd $(abs_top_srcdir)/.. && pwd || echo .) +diff --git a/Makefile.in b/Makefile.in +index b0ec9f686..9b4b93d8b 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -10351,7 +10351,7 @@ $(top_srcdir)/xlat/xfs_dqblk_flags.h: $(top_srcdir)/xlat/xfs_dqblk_flags.in $(to + $(top_srcdir)/xlat/xfs_quota_flags.h: $(top_srcdir)/xlat/xfs_quota_flags.in $(top_srcdir)/xlat/gen.sh + $(AM_V_GEN)$(top_srcdir)/xlat/gen.sh $< $@ + +-@CODE_COVERAGE_RULES@ ++include $(top_srcdir)/aminclude_static.am + + .PHONY: check-valgrind-local + check-valgrind-local: +-- +2.7.4 + diff --git a/projects/ArchR/packages/devel/SDL2_gfx/package.mk b/projects/ArchR/packages/devel/SDL2_gfx/package.mk new file mode 100644 index 0000000000..ab59b3b893 --- /dev/null +++ b/projects/ArchR/packages/devel/SDL2_gfx/package.mk @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2020-present Shanti Gilbert (https://github.com/shantigilbert) + +PKG_NAME="SDL2_gfx" +PKG_VERSION="29927b3" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/jjYBdx4IL/SDL2_gfx" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain SDL2" +PKG_LONGDESC="SDL_image is an image file loading library. " +PKG_TOOLCHAIN="configure" + +PKG_CONFIGURE_OPTS_TARGET=" --disable-mmx" + +pre_configure_target() { + export CC=${CC} +} + diff --git a/projects/ArchR/packages/devel/SDL2_image/package.mk b/projects/ArchR/packages/devel/SDL2_image/package.mk new file mode 100644 index 0000000000..bbb1fbda64 --- /dev/null +++ b/projects/ArchR/packages/devel/SDL2_image/package.mk @@ -0,0 +1,31 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 0riginally created by Escalade (https://github.com/escalade) +# Copyright (C) 2018-present 5schatten (https://github.com/5schatten) + +PKG_NAME="SDL2_image" +PKG_VERSION="2.8.2" +PKG_LICENSE="GPL" +PKG_SITE="http://www.libsdl.org/" +PKG_URL="https://github.com/libsdl-org/SDL_image/releases/download/release-${PKG_VERSION}/${PKG_NAME}-${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain SDL2 libjpeg-turbo libpng" +PKG_LONGDESC="SDL_image is an image file loading library. " +PKG_TOOLCHAIN="configure" + +PKG_CONFIGURE_OPTS_TARGET="--disable-sdltest \ + --enable-bmp \ + --enable-gif \ + --enable-jpg \ + --enable-lbm \ + --enable-pcx \ + --enable-png \ + --enable-pnm \ + --enable-tga \ + --enable-tif \ + --enable-xcf \ + --enable-xpm \ + --enable-xv \ + + --enable-webp" +pre_configure_target() { + export LDFLAGS="${LDFLAGS} -ljpeg -lz -lm" +} diff --git a/projects/ArchR/packages/devel/SDL2_net/package.mk b/projects/ArchR/packages/devel/SDL2_net/package.mk new file mode 100644 index 0000000000..2bc303387b --- /dev/null +++ b/projects/ArchR/packages/devel/SDL2_net/package.mk @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 0riginally created by Escalade (https://github.com/escalade) +# Copyright (C) 2018-present 5schatten (https://github.com/5schatten) + +PKG_NAME="SDL2_net" +PKG_VERSION="2.2.0" +PKG_LICENSE="GPL" +PKG_SITE="https://www.libsdl.org/projects/SDL_net/" +PKG_URL="https://github.com/libsdl-org/SDL_net/releases/download/release-${PKG_VERSION}/${PKG_NAME}-${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain SDL2" +PKG_LONGDESC="SDL2_net: network library" +PKG_TOOLCHAIN="autotools" diff --git a/projects/ArchR/packages/devel/SDL2_ttf/package.mk b/projects/ArchR/packages/devel/SDL2_ttf/package.mk new file mode 100644 index 0000000000..a45b8353bd --- /dev/null +++ b/projects/ArchR/packages/devel/SDL2_ttf/package.mk @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 0riginally created by Escalade (https://github.com/escalade) +# Copyright (C) 2018-present 5schatten (https://github.com/5schatten) + +PKG_NAME="SDL2_ttf" +PKG_VERSION="2.20.2" +PKG_LICENSE="GPL" +PKG_SITE="http://www.libsdl.org/" +PKG_URL="https://github.com/libsdl-org/SDL_ttf/releases/download/release-${PKG_VERSION}/${PKG_NAME}-${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain SDL2 freetype" +PKG_LONGDESC="This is a sample library which allows you to use TrueType fonts in your SDL applications" +PKG_TOOLCHAIN="cmake" + +PKG_CMAKE_OPTS_TARGET="-DFREETYPE_INCLUDE_DIRS=${SYSROOT_PREFIX}/usr" diff --git a/projects/ArchR/packages/devel/binutils/package.mk b/projects/ArchR/packages/devel/binutils/package.mk new file mode 100644 index 0000000000..bac890a6d7 --- /dev/null +++ b/projects/ArchR/packages/devel/binutils/package.mk @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +. ${ROOT}/packages/devel/binutils/package.mk + +# gprofng fails to build with GCC 15 / glibc _Generic conflict +PKG_CONFIGURE_OPTS_HOST="${PKG_CONFIGURE_OPTS_HOST} --disable-gprofng" diff --git a/projects/ArchR/packages/devel/boost/package.mk b/projects/ArchR/packages/devel/boost/package.mk new file mode 100644 index 0000000000..8a6c26a17b --- /dev/null +++ b/projects/ArchR/packages/devel/boost/package.mk @@ -0,0 +1,68 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2019-present Team LibreELEC (https://libreelec.tv) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="boost" +PKG_VERSION="1.86.0" +PKG_LICENSE="OSS" +PKG_SITE="http://www.boost.org/" +PKG_URL="https://archives.boost.io/release/${PKG_VERSION}/source/${PKG_NAME}_${PKG_VERSION//./_}.tar.bz2" +PKG_DEPENDS_HOST="toolchain:host" +PKG_DEPENDS_TARGET="toolchain boost:host Python3 zlib bzip2" +PKG_LONGDESC="boost: Peer-reviewed STL style libraries for C++" +PKG_TOOLCHAIN="manual" +PKG_BUILD_FLAGS="+pic" +PKG_B2_PARAM=" binary-format=elf link=static threading=multi toolset=gcc " +if [ "${TARGET_ARCH}" = "aarch64" ]; then + PKG_B2_PARAM+=" abi=aapcs address-model=64 architecture=arm " +fi + +make_host() { + cd tools/build/src/engine + sh build.sh +} + +makeinstall_host() { + mkdir -p ${TOOLCHAIN}/bin + cp b2 ${TOOLCHAIN}/bin +} + +pre_configure_target() { + export CFLAGS="${CFLAGS} -I${SYSROOT_PREFIX}/usr/include/${PKG_PYTHON_VERSION}" + export CXXFLAGS="${CXXFLAGS} -I${SYSROOT_PREFIX}/usr/include/${PKG_PYTHON_VERSION}" +} + +configure_target() { + sh bootstrap.sh --prefix=/usr \ + --with-bjam=${TOOLCHAIN}/bin/b2 \ + --with-python=${TOOLCHAIN}/bin/python \ + --with-python-root=${SYSROOT_PREFIX}/usr + + echo "using gcc : $(${CC} -v 2>&1 | tail -n 1 |awk '{print $3}') : ${CXX} : \"${CFLAGS}\" \"${LDFLAGS}\" ;" \ + > tools/build/src/user-config.jam + echo "using python : ${PKG_PYTHON_VERSION/#python} : ${TOOLCHAIN} : ${SYSROOT_PREFIX}/usr/include : ${SYSROOT_PREFIX}/usr/lib ;" \ + >> tools/build/src/user-config.jam +} +makeinstall_target() { + ln -sf ${TOOLCHAIN}/bin/b2 ${TOOLCHAIN}/bin/bjam + ${TOOLCHAIN}/bin/bjam -d2 --ignore-site-config \ + ${PKG_B2_PARAM} \ + --layout=system \ + --prefix=${SYSROOT_PREFIX}/usr \ + --with-chrono \ + --with-date_time \ + --with-filesystem \ + --with-iostreams \ + --with-program_options \ + --with-python \ + --with-locale \ + --with-random \ + --with-regex -sICU_PATH="${SYSROOT_PREFIX}/usr" \ + --with-serialization \ + --with-system \ + --with-thread \ + --with-nowide \ + --with-context \ + install +} diff --git a/projects/ArchR/packages/devel/cmake/package.mk b/projects/ArchR/packages/devel/cmake/package.mk new file mode 100644 index 0000000000..888bae585c --- /dev/null +++ b/projects/ArchR/packages/devel/cmake/package.mk @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="cmake" +PKG_VERSION="3.30.3" +PKG_LICENSE="BSD" +PKG_SITE="https://cmake.org/" +PKG_URL="https://cmake.org/files/v$(get_pkg_version_maj_min)/cmake-${PKG_VERSION}.tar.gz" +PKG_DEPENDS_HOST="pkg-config:host openssl:host" +PKG_LONGDESC="A cross-platform, open-source make system." +PKG_TOOLCHAIN="configure" +PKG_BUILD_FLAGS="+local-cc" + +configure_host() { + ../configure --prefix=${TOOLCHAIN} \ + --no-qt-gui --no-system-libs \ + -- \ + -DCMAKE_C_FLAGS="-O2 -Wall -pipe -Wno-format-security" \ + -DCMAKE_CXX_FLAGS="-O2 -Wall -pipe -Wno-format-security" \ + -DCMAKE_EXE_LINKER_FLAGS="${HOST_LDFLAGS}" \ + -DCMAKE_USE_OPENSSL=ON \ + -DBUILD_CursesDialog=0 +} diff --git a/projects/ArchR/packages/devel/cmake/patches/cmake-001-disable-free-comp-methods.patch b/projects/ArchR/packages/devel/cmake/patches/cmake-001-disable-free-comp-methods.patch new file mode 100644 index 0000000000..79c961baf7 --- /dev/null +++ b/projects/ArchR/packages/devel/cmake/patches/cmake-001-disable-free-comp-methods.patch @@ -0,0 +1,14 @@ +--- a/Utilities/cmcurl/lib/vtls/openssl.c.orig 2016-10-19 19:17:49.615923691 +0200 ++++ b/Utilities/cmcurl/lib/vtls/openssl.c 2016-10-19 19:22:50.849565684 +0200 +@@ -134,6 +134,11 @@ + #define HAVE_SSL_COMP_FREE_COMPRESSION_METHODS 1 + #endif + ++#if !defined(OPENSSL_NO_COMP) || \ ++ OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0+ has no free compression methods */ ++#undef HAVE_SSL_COMP_FREE_COMPRESSION_METHODS /* undef */ ++#endif ++ + #if (OPENSSL_VERSION_NUMBER < 0x0090808fL) + /* not present in older OpenSSL */ + #define OPENSSL_load_builtin_modules(x) diff --git a/projects/ArchR/packages/devel/ecm/package.mk b/projects/ArchR/packages/devel/ecm/package.mk new file mode 100644 index 0000000000..460e73c750 --- /dev/null +++ b/projects/ArchR/packages/devel/ecm/package.mk @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="ecm" +PKG_VERSION="v6.16.0" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/KDE/extra-cmake-modules" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_LONGDESC="KDE Extra CMake Modules" +PKG_DEPENDS_TARGET="toolchain" +PKG_TOOLCHAIN="cmake" + +PKG_CMAKE_OPTS_TARGET+=" -DBUILD_TESTING=OFF -DBUILD_HTML_DOCS=OFF -DBUILD_MAN_DOCS=OFF -DBUILD_QTHELP_DOCS=OFF" diff --git a/projects/ArchR/packages/devel/elfutils/package.mk b/projects/ArchR/packages/devel/elfutils/package.mk new file mode 100644 index 0000000000..6b461a347a --- /dev/null +++ b/projects/ArchR/packages/devel/elfutils/package.mk @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +. ${ROOT}/packages/devel/elfutils/package.mk + +pre_configure_host() { + # GCC 15 treats discarded-qualifiers as error with -Werror + export CFLAGS="${CFLAGS} -Wno-error=discarded-qualifiers" + # Fix -std=gnu17 invalid for C++ and same warning for C++ files + export CXXFLAGS="${CXXFLAGS//-std=gnu17/-std=gnu++17} -Wno-error=discarded-qualifiers" +} diff --git a/projects/ArchR/packages/devel/glib/package.mk b/projects/ArchR/packages/devel/glib/package.mk new file mode 100644 index 0000000000..173f5fe4cc --- /dev/null +++ b/projects/ArchR/packages/devel/glib/package.mk @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +. ${ROOT}/packages/devel/glib/package.mk + +PKG_MESON_OPTS_HOST="-Ddefault_library=shared \ + -Dinstalled_tests=false \ + -Dlibmount=disabled \ + -Dintrospection=disabled \ + -Dtests=false" diff --git a/projects/ArchR/packages/devel/glib/patches/001-frexpl.patch b/projects/ArchR/packages/devel/glib/patches/001-frexpl.patch new file mode 100644 index 0000000000..bee2df918a --- /dev/null +++ b/projects/ArchR/packages/devel/glib/patches/001-frexpl.patch @@ -0,0 +1,23 @@ +diff --git a/glib/gnulib/meson.build b/glib/gnulib/meson.build +index 38b530aa0..4408a3dc6 100644 +--- a/glib/gnulib/meson.build ++++ b/glib/gnulib/meson.build +@@ -302,12 +302,12 @@ else + gl_cv_func_frexpl_broken_beyond_repair = true + endif + +-if not gl_cv_func_frexp_works and gl_cv_func_frexp_broken_beyond_repair +- error ('frexp() is missing or broken beyond repair, and we have nothing to replace it with') +-endif +-if not gl_cv_func_frexpl_works and gl_cv_func_frexpl_broken_beyond_repair +- error ('frexpl() is missing or broken beyond repair, and we have nothing to replace it with') +-endif ++#if not gl_cv_func_frexp_works and gl_cv_func_frexp_broken_beyond_repair ++# error ('frexp() is missing or broken beyond repair, and we have nothing to replace it with') ++#endif ++#if not gl_cv_func_frexpl_works and gl_cv_func_frexpl_broken_beyond_repair ++# error ('frexpl() is missing or broken beyond repair, and we have nothing to replace it with') ++#endif + + math_h_config.set ('REPLACE_FREXP', gl_cv_func_frexp_works ? 0 : 1) + math_h_config.set ('REPLACE_FREXPL', gl_cv_func_frexpl_works ? 0 : 1) diff --git a/projects/ArchR/packages/devel/glibc/config/gai.conf b/projects/ArchR/packages/devel/glibc/config/gai.conf new file mode 100644 index 0000000000..4616ed005b --- /dev/null +++ b/projects/ArchR/packages/devel/glibc/config/gai.conf @@ -0,0 +1,65 @@ +# Configuration for getaddrinfo(3). +# +# So far only configuration for the destination address sorting is needed. +# RFC 3484 governs the sorting. But the RFC also says that system +# administrators should be able to overwrite the defaults. This can be +# achieved here. +# +# All lines have an initial identifier specifying the option followed by +# up to two values. Information specified in this file replaces the +# default information. Complete absence of data of one kind causes the +# appropriate default information to be used. The supported commands include: +# +# reload +# If set to yes, each getaddrinfo(3) call will check whether this file +# changed and if necessary reload. This option should not really be +# used. There are possible runtime problems. The default is no. +# +# label +# Add another rule to the RFC 3484 label table. See section 2.1 in +# RFC 3484. The default is: +# +#label ::1/128 0 +#label ::/0 1 +#label 2002::/16 2 +#label ::/96 3 +#label ::ffff:0:0/96 4 +#label fec0::/10 5 +#label fc00::/7 6 +#label 2001:0::/32 7 +# +# This default differs from the tables given in RFC 3484 by handling +# (now obsolete) site-local IPv6 addresses and Unique Local Addresses. +# The reason for this difference is that these addresses are never +# NATed while IPv4 site-local addresses most probably are. Given +# the precedence of IPv6 over IPv4 (see below) on machines having only +# site-local IPv4 and IPv6 addresses a lookup for a global address would +# see the IPv6 be preferred. The result is a long delay because the +# site-local IPv6 addresses cannot be used while the IPv4 address is +# (at least for the foreseeable future) NATed. We also treat Teredo +# tunnels special. +# +# precedence +# Add another rule to the RFC 3484 precedence table. See section 2.1 +# and 10.3 in RFC 3484. The default is: +# +#precedence ::1/128 50 +#precedence ::/0 40 +#precedence 2002::/16 30 +#precedence ::/96 20 +#precedence ::ffff:0:0/96 10 +# +# For sites which prefer IPv4 connections change the last line to +# +#precedence ::ffff:0:0/96 100 + +# +# scopev4 +# Add another rule to the RFC 6724 scope table for IPv4 addresses. +# By default the scope IDs described in section 3.2 in RFC 6724 are +# used. Changing these defaults should hardly ever be necessary. +# The defaults are equivalent to: +# +#scopev4 ::ffff:169.254.0.0/112 2 +#scopev4 ::ffff:127.0.0.0/104 2 +#scopev4 ::ffff:0.0.0.0/96 14 diff --git a/projects/ArchR/packages/devel/glibc/config/host.conf b/projects/ArchR/packages/devel/glibc/config/host.conf new file mode 100644 index 0000000000..d1a59f73a9 --- /dev/null +++ b/projects/ArchR/packages/devel/glibc/config/host.conf @@ -0,0 +1 @@ +multi on diff --git a/projects/ArchR/packages/devel/glibc/config/ld.so.conf b/projects/ArchR/packages/devel/glibc/config/ld.so.conf new file mode 100644 index 0000000000..83327c01bf --- /dev/null +++ b/projects/ArchR/packages/devel/glibc/config/ld.so.conf @@ -0,0 +1 @@ +include /etc/ld.so.conf.d/*.conf diff --git a/projects/ArchR/packages/devel/glibc/config/nsswitch-init.conf b/projects/ArchR/packages/devel/glibc/config/nsswitch-init.conf new file mode 100644 index 0000000000..eba159e8fc --- /dev/null +++ b/projects/ArchR/packages/devel/glibc/config/nsswitch-init.conf @@ -0,0 +1,3 @@ +# This is just enough to get DNS resolution working in the initramfs + +hosts: dns diff --git a/projects/ArchR/packages/devel/glibc/config/nsswitch-target.conf b/projects/ArchR/packages/devel/glibc/config/nsswitch-target.conf new file mode 100644 index 0000000000..4391cdd21e --- /dev/null +++ b/projects/ArchR/packages/devel/glibc/config/nsswitch-target.conf @@ -0,0 +1,19 @@ +# /etc/nsswitch.conf +# +# Example configuration of GNU Name Service Switch functionality. +# + +passwd: files +group: files +shadow: files +gshadow: files + +hosts: files dns +networks: files dns + +protocols: files +services: files +ethers: files +rpc: files + +netgroup: files diff --git a/projects/ArchR/packages/devel/glibc/package.mk b/projects/ArchR/packages/devel/glibc/package.mk new file mode 100644 index 0000000000..2e68c82032 --- /dev/null +++ b/projects/ArchR/packages/devel/glibc/package.mk @@ -0,0 +1,161 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="glibc" +PKG_VERSION="2.40" +PKG_LICENSE="GPL" +PKG_SITE="https://www.gnu.org/software/libc/" +PKG_URL="https://mirrors.kernel.org/gnu/glibc/${PKG_NAME}-${PKG_VERSION}.tar.xz" +PKG_DEPENDS_TARGET="ccache:host autotools:host linux:host gcc:bootstrap pigz:host Python3:host" +PKG_DEPENDS_INIT="glibc" +PKG_LONGDESC="The Glibc package contains the main C library." +PKG_BUILD_FLAGS="+bfd -gold" + +case "${DEVICE}" in + RK3588*) + OPT_ENABLE_KERNEL=6.1.0 + ;; + SDM845) + OPT_ENABLE_KERNEL=5.18.0 + ;; + *) + OPT_ENABLE_KERNEL=6.10.0 + ;; +esac + +case ${TARGET_ARCH} in + arm|aarch64) + PKG_PATCH_DIRS="widevine-arm" + ;; +esac + +PKG_CONFIGURE_OPTS_TARGET="BASH_SHELL=/bin/sh \ + ac_cv_path_PERL=no \ + ac_cv_prog_MAKEINFO= \ + --libexecdir=/usr/lib/glibc \ + --cache-file=config.cache \ + --disable-profile \ + --disable-sanity-checks \ + --enable-add-ons \ + --enable-bind-now \ + --with-elf \ + --with-tls \ + --with-__thread \ + --with-binutils=${BUILD}/toolchain/bin \ + --with-headers=${SYSROOT_PREFIX}/usr/include \ + --enable-kernel=${OPT_ENABLE_KERNEL} \ + --without-cvs \ + --without-gd \ + --disable-build-nscd \ + --disable-nscd \ + --disable-timezone-tools" + +if build_with_debug; then + PKG_CONFIGURE_OPTS_TARGET+=" --enable-debug" +else + PKG_CONFIGURE_OPTS_TARGET+=" --disable-debug" +fi + +post_unpack() { + find "${PKG_BUILD}" -type f -name '*.py' -exec sed -e '1s,^#![[:space:]]*/usr/bin/python.*,#!/usr/bin/env python3,' -i {} \; +} + +pre_configure_target() { +# Filter out some problematic *FLAGS + export CFLAGS=$(echo ${CFLAGS} | sed -e "s|-O.|-O3|g") + + export CFLAGS=$(echo ${CFLAGS} | sed -e "s|-Wunused-but-set-variable||g") + export CFLAGS="${CFLAGS} -Wno-unused-variable" + + if [ -n "${PROJECT_CFLAGS}" ]; then + export CFLAGS=$(echo ${CFLAGS} | sed -e "s|${PROJECT_CFLAGS}||g") + fi + + export LDFLAGS=$(echo ${LDFLAGS} | sed -e "s|-O.|-O3|g") + + export LDFLAGS=$(echo ${LDFLAGS} | sed -e "s|-Wl,--as-needed||") + + unset LD_LIBRARY_PATH + + # set some CFLAGS we need + export CFLAGS="${CFLAGS} -g -fno-stack-protector" + + export BUILD_CC=${HOST_CC} + export OBJDUMP_FOR_HOST=objdump + + cat >config.cache <configparms </maps +Next message (by thread): [RFC PATCH] arm64/math-vec.h: guard off the vector types with CPP constants +Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] +When implementing a C parser, it's apparently common to use GCC as +preprocessor. However, those programs don't necessarily define the SIMD +intrinsic types exposed by GCC, resulting in failed compilations. + +This patch adds a way for those users to bypass entirely the vector +types, as they usually aren't interested in libmvec anyway. They can +just add -D__ARM_VEC_MATH_DISABLED=1 to the CPP_FLAGS they pass on to +GCC. + +Fixes: BZ #25422 + +Signed-off-by: Simon Chopin +--- + sysdeps/aarch64/fpu/bits/math-vector.h | 32 ++++++++++++++------------ + 1 file changed, 17 insertions(+), 15 deletions(-) + +diff --git a/sysdeps/aarch64/fpu/bits/math-vector.h b/sysdeps/aarch64/fpu/bits/math-vector.h +index 7c200599c1..c739e6bc5d 100644 +--- a/sysdeps/aarch64/fpu/bits/math-vector.h ++++ b/sysdeps/aarch64/fpu/bits/math-vector.h +@@ -25,29 +25,30 @@ + /* Get default empty definitions for simd declarations. */ + #include + +-#if __GNUC_PREREQ(9, 0) +-# define __ADVSIMD_VEC_MATH_SUPPORTED ++#if defined __ARM_ARCH_8A && !defined __ARM_VEC_MATH_DISABLED ++# if __GNUC_PREREQ(9, 0) ++# define __ADVSIMD_VEC_MATH_SUPPORTED + typedef __Float32x4_t __f32x4_t; + typedef __Float64x2_t __f64x2_t; +-#elif __glibc_clang_prereq(8, 0) +-# define __ADVSIMD_VEC_MATH_SUPPORTED ++# elif __glibc_clang_prereq(8, 0) ++# define __ADVSIMD_VEC_MATH_SUPPORTED + typedef __attribute__ ((__neon_vector_type__ (4))) float __f32x4_t; + typedef __attribute__ ((__neon_vector_type__ (2))) double __f64x2_t; +-#endif ++# endif + +-#if __GNUC_PREREQ(10, 0) || __glibc_clang_prereq(11, 0) +-# define __SVE_VEC_MATH_SUPPORTED ++# if __GNUC_PREREQ(10, 0) || __glibc_clang_prereq(11, 0) ++# define __SVE_VEC_MATH_SUPPORTED + typedef __SVFloat32_t __sv_f32_t; + typedef __SVFloat64_t __sv_f64_t; + typedef __SVBool_t __sv_bool_t; +-#endif ++# endif + + /* If vector types and vector PCS are unsupported in the working + compiler, no choice but to omit vector math declarations. */ + +-#ifdef __ADVSIMD_VEC_MATH_SUPPORTED ++# ifdef __ADVSIMD_VEC_MATH_SUPPORTED + +-# define __vpcs __attribute__ ((__aarch64_vector_pcs__)) ++# define __vpcs __attribute__ ((__aarch64_vector_pcs__)) + + __vpcs __f32x4_t _ZGVnN4v_cosf (__f32x4_t); + __vpcs __f32x4_t _ZGVnN4v_expf (__f32x4_t); +@@ -59,10 +60,10 @@ __vpcs __f64x2_t _ZGVnN2v_exp (__f64x2_t); + __vpcs __f64x2_t _ZGVnN2v_log (__f64x2_t); + __vpcs __f64x2_t _ZGVnN2v_sin (__f64x2_t); + +-# undef __ADVSIMD_VEC_MATH_SUPPORTED +-#endif /* __ADVSIMD_VEC_MATH_SUPPORTED */ ++# undef __ADVSIMD_VEC_MATH_SUPPORTED ++# endif /* __ADVSIMD_VEC_MATH_SUPPORTED */ + +-#ifdef __SVE_VEC_MATH_SUPPORTED ++# ifdef __SVE_VEC_MATH_SUPPORTED + + __sv_f32_t _ZGVsMxv_cosf (__sv_f32_t, __sv_bool_t); + __sv_f32_t _ZGVsMxv_expf (__sv_f32_t, __sv_bool_t); +@@ -74,5 +75,6 @@ __sv_f64_t _ZGVsMxv_exp (__sv_f64_t, __sv_bool_t); + __sv_f64_t _ZGVsMxv_log (__sv_f64_t, __sv_bool_t); + __sv_f64_t _ZGVsMxv_sin (__sv_f64_t, __sv_bool_t); + +-# undef __SVE_VEC_MATH_SUPPORTED +-#endif /* __SVE_VEC_MATH_SUPPORTED */ ++# undef __SVE_VEC_MATH_SUPPORTED ++# endif /* __SVE_VEC_MATH_SUPPORTED */ ++#endif /* _ARM_ARCH_8A && !__ARM_VEC_MATH_DISABLED */ + +base-commit: 64b1a44183a3094672ed304532bedb9acc707554 +-- +2.40.1 diff --git a/projects/ArchR/packages/devel/glibc/patches/glibc-fix-dns-with-broken-routers.patch b/projects/ArchR/packages/devel/glibc/patches/glibc-fix-dns-with-broken-routers.patch new file mode 100644 index 0000000000..d2ac670853 --- /dev/null +++ b/projects/ArchR/packages/devel/glibc/patches/glibc-fix-dns-with-broken-routers.patch @@ -0,0 +1,107 @@ +commit 45918e237cd32bb3d9a5fde83f81f83b52584771 +Author: Stefan Saraev +Date: Tue Oct 1 12:09:07 2013 +0300 + + fix dns with broken routers + + ref: https://fedoraproject.org/wiki/Networking/NameResolution/ADDRCONFIG + +--- a/nss/getaddrinfo.c ++++ b/nss/getaddrinfo.c +@@ -730,6 +730,38 @@ gaih_inet (const char *name, const struc + if (res_ctx == NULL) + no_more = 1; + ++ /* AI_ADDRCONFIG determines whether or not we should suppress any ++ * hostname lookups. If the local host has only IPv4 interfaces, ++ * then suppress lookups for IPv6 addresses, and vice versa; if ++ * the local host has only IPv6 interfaces, suppress any lookups ++ * for IPv4 addresses.. ++ * ++ * Link-local IPv6 addresses and loopback addresses of either ++ * family are ignored when determining whether or not the host has ++ * an interface of the given address family, cf. __check_pf(). ++ * ++ * This logic is only applied for AF_UNSPEC. If the caller ++ * explicitly requested an address family, give him what he asked ++ * for. ++ * ++ * If we didn't find any interfaces of either address family, ++ * we ignore AI_ADDRCONFIG and return all available resutlts. */ ++ int suppress_af = 0; ++ if (req->ai_family == AF_UNSPEC) ++ { ++ struct in6addrinfo *in6ai = NULL; ++ size_t in6ailen = 0; ++ bool seen_ipv4 = false; ++ bool seen_ipv6 = false; ++ __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen); ++ __free_in6ai (in6ai); ++ ++ if(seen_ipv4 && !seen_ipv6) ++ suppress_af = AF_INET6; ++ else if(seen_ipv6 && !seen_ipv4) ++ suppress_af = AF_INET; ++ } ++ + while (!no_more) + { + no_data = 0; +@@ -737,7 +769,7 @@ gaih_inet (const char *name, const struc + + /* gethostbyname4_r sends out parallel A and AAAA queries and + is thus only suitable for PF_UNSPEC. */ +- if (req->ai_family == PF_UNSPEC) ++ if (req->ai_family == PF_UNSPEC && !suppress_af) + fct4 = __nss_lookup_function (nip, "gethostbyname4_r"); + + if (fct4 != NULL) +@@ -826,25 +858,27 @@ gaih_inet (const char *name, const struc + + if (fct != NULL) + { +- if (req->ai_family == AF_INET6 +- || req->ai_family == AF_UNSPEC) ++ if ((req->ai_family == AF_INET6 ++ || req->ai_family == AF_UNSPEC) ++ && suppress_af != AF_INET6) + { + if ((result = gethosts (fct, AF_INET6, name, req, tmpbuf, + res, &status, &no_data)) != 0) + { + __resolv_context_put (res_ctx); + goto out; + } + no_inet6_data = no_data; + inet6_status = status; + } +- if (req->ai_family == AF_INET +- || req->ai_family == AF_UNSPEC +- || (req->ai_family == AF_INET6 +- && (req->ai_flags & AI_V4MAPPED) +- /* Avoid generating the mapped addresses if we +- know we are not going to need them. */ +- && ((req->ai_flags & AI_ALL) || !res->got_ipv6))) ++ if ((req->ai_family == AF_INET ++ || req->ai_family == AF_UNSPEC ++ || (req->ai_family == AF_INET6 ++ && (req->ai_flags & AI_V4MAPPED) ++ /* Avoid generating the mapped addresses if we ++ know we are not going to need them. */ ++ && ((req->ai_flags & AI_ALL) || !res->got_ipv6))) ++ && suppress_af != AF_INET) + { + if ((result = gethosts (fct, AF_INET, name, req, tmpbuf, + res, &status, &no_data)) != 0) +--- a/sysdeps/unix/sysv/linux/check_pf.c ++++ b/sysdeps/unix/sysv/linux/check_pf.c +@@ -224,7 +224,8 @@ make_request (int fd, pid_t pid) + } + else + { +- if (!IN6_IS_ADDR_LOOPBACK (address)) ++ if (!IN6_IS_ADDR_LOOPBACK (address) && ++ !IN6_IS_ADDR_LINKLOCAL (address)) + seen_ipv6 = true; + } + } diff --git a/projects/ArchR/packages/devel/glibc/patches/glibc-ld.so.cache-to-writable-cache.patch b/projects/ArchR/packages/devel/glibc/patches/glibc-ld.so.cache-to-writable-cache.patch new file mode 100644 index 0000000000..1f38ff8849 --- /dev/null +++ b/projects/ArchR/packages/devel/glibc/patches/glibc-ld.so.cache-to-writable-cache.patch @@ -0,0 +1,25 @@ +From bfdcab6e5f8352d5a1ee9724244d98cfd1d1d309 Mon Sep 17 00:00:00 2001 +From: 7Ji +Date: Fri, 15 Jul 2022 11:30:30 +0800 +Subject: [PATCH] glibc: ld.so.cache to .cache + +--- + sysdeps/generic/dl-cache.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sysdeps/generic/dl-cache.h b/sysdeps/generic/dl-cache.h +index 93d4bea930..34aa313cf0 100644 +--- a/sysdeps/generic/dl-cache.h ++++ b/sysdeps/generic/dl-cache.h +@@ -35,7 +35,7 @@ + #endif + + #ifndef LD_SO_CACHE +-# define LD_SO_CACHE SYSCONFDIR "/ld.so.cache" ++# define LD_SO_CACHE "/storage/.cache/ld.so.cache" + #endif + + #ifndef add_system_dir +-- +2.37.1 + diff --git a/projects/ArchR/packages/devel/gnulib/package.mk b/projects/ArchR/packages/devel/gnulib/package.mk new file mode 100644 index 0000000000..8e4d3337d0 --- /dev/null +++ b/projects/ArchR/packages/devel/gnulib/package.mk @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2019-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="gnulib" +# Match version with GNULIB_REVISION in grub bootstrap.conf +PKG_VERSION="9f48fb992a3d7e96610c4ce8be969cff2d61a01b" +PKG_LICENSE="GPL" +PKG_SITE="https://savannah.gnu.org/git/?group=gnulib" +PKG_URL="http://git.savannah.gnu.org/gitweb/?p=${PKG_NAME}.git;a=snapshot;h=${PKG_VERSION};sf=tgz" +PKG_SOURCE_NAME="${PKG_NAME}-${PKG_VERSION}.tar.gz" +PKG_LONGDESC="GNU portability library" +PKG_TOOLCHAIN="manual" diff --git a/projects/ArchR/packages/devel/json-glib/package.mk b/projects/ArchR/packages/devel/json-glib/package.mk new file mode 100644 index 0000000000..698d5bbebc --- /dev/null +++ b/projects/ArchR/packages/devel/json-glib/package.mk @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2021-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="json-glib" +PKG_VERSION="1.10.0" +PKG_LICENSE="LGPL-2.1" +PKG_SITE="https://github.com/GNOME/json-glib" +PKG_URL="https://github.com/GNOME/json-glib/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain glib glib:host" +PKG_LONGDESC="JSON-GLib implements a full suite of JSON-related tools using GLib and GObject." + +PKG_MESON_OPTS_TARGET="-Dintrospection=disabled \ + -Dgtk_doc=disabled \ + -Dman=false \ + -Dtests=false" diff --git a/projects/ArchR/packages/devel/libaio/package.mk b/projects/ArchR/packages/devel/libaio/package.mk new file mode 100644 index 0000000000..254deb2329 --- /dev/null +++ b/projects/ArchR/packages/devel/libaio/package.mk @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2017 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2019-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="libaio" +PKG_VERSION="0.3.113" +PKG_SHA256="716c7059703247344eb066b54ecbc3ca2134f0103307192e6c2b7dab5f9528ab" +PKG_LICENSE="GPL" +PKG_SITE="https://pagure.io/libaio" +PKG_URL="https://pagure.io/${PKG_NAME}/archive/${PKG_NAME}-${PKG_VERSION}/${PKG_NAME}-${PKG_NAME}-${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Kernel Asynchronous I/O (AIO) Support for Linux." +PKG_BUILD_FLAGS="-lto" + +make_target() { + make -C src +} diff --git a/projects/ArchR/packages/devel/libclc/package.mk b/projects/ArchR/packages/devel/libclc/package.mk new file mode 100644 index 0000000000..fd187b4318 --- /dev/null +++ b/projects/ArchR/packages/devel/libclc/package.mk @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (C) 2024-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="libclc" +PKG_VERSION="$(get_pkg_version llvm)" +PKG_LICENSE="Apache-2.0" +PKG_URL="" +PKG_DEPENDS_HOST="toolchain:host llvm:host spirv-tools spirv-tools:host spirv-llvm-translator:host" +PKG_LONGDESC="Low-Level Virtual Machine (LLVM) is a compiler infrastructure." +PKG_DEPENDS_UNPACK+=" llvm" +PKG_PATCH_DIRS+=" $(get_pkg_directory llvm)/patches" +PKG_TOOLCHAIN="cmake" + +unpack() { + mkdir -p ${PKG_BUILD} + tar --strip-components=1 -xf ${SOURCES}/llvm/llvm-${PKG_VERSION}.tar.xz -C ${PKG_BUILD} +} + +pre_configure() { + PKG_CMAKE_SCRIPT="${PKG_BUILD}/libclc/CMakeLists.txt" +} + +pre_configure_host() { + LIBCLC_TARGETS_TO_BUILD="spirv64-mesa3d-;spirv-mesa3d-" + + mkdir -p "${PKG_BUILD}/.${HOST_NAME}" + cd ${PKG_BUILD}/.${HOST_NAME} + PKG_CMAKE_OPTS_HOST="-DLIBCLC_TARGETS_TO_BUILD=${LIBCLC_TARGETS_TO_BUILD}" +} diff --git a/projects/ArchR/packages/devel/libcom-err/package.mk b/projects/ArchR/packages/devel/libcom-err/package.mk new file mode 100644 index 0000000000..d21e9c7633 --- /dev/null +++ b/projects/ArchR/packages/devel/libcom-err/package.mk @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="libcom-err" +PKG_VERSION="$(get_pkg_version e2fsprogs)" +PKG_LICENSE="GPL" +PKG_SITE="http://e2fsprogs.sourceforge.net/" +PKG_URL="https://www.kernel.org/pub/linux/kernel/people/tytso/e2fsprogs/v${PKG_VERSION}/e2fsprogs-${PKG_VERSION}.tar.xz" +PKG_DEPENDS_TARGET="autotools:host gcc:host" +PKG_LONGDESC="The filesystem utilities for the EXT2 filesystem, including e2fsck, mke2fs, dumpe2fs, fsck, and others." + +pre_configure() { + PKG_CONFIGURE_OPTS_TARGET="BUILD_CC=${HOST_CC} \ + --with-udev-rules-dir=no \ + --with-crond-dir=no \ + --with-systemd-unit-dir=no \ + --enable-verbose-makecmds \ + --disable-subset \ + --enable-elf-shlibs \ + --disable-bsd-shlibs \ + --disable-profile \ + --disable-jbd-debug \ + --disable-blkid-debug \ + --disable-testio-debug \ + --enable-libuuid \ + --enable-libblkid \ + --disable-debugfs \ + --disable-imager \ + --disable-resizer \ + --disable-fsck \ + --disable-e2initrd-helper \ + --disable-tls \ + --disable-uuidd \ + --disable-nls \ + --disable-rpath \ + --disable-fuse2fs \ + --with-gnu-ld" +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib + cp -rf ${PKG_BUILD}/.${TARGET_NAME}/lib/libcom_err.so* ${INSTALL}/usr/lib +} diff --git a/projects/ArchR/packages/devel/libdatrie/package.mk b/projects/ArchR/packages/devel/libdatrie/package.mk new file mode 100644 index 0000000000..28467ec975 --- /dev/null +++ b/projects/ArchR/packages/devel/libdatrie/package.mk @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="libdatrie" +PKG_VERSION="0.2.13" +PKG_LICENSE="LGPLv2" +PKG_SITE="https://github.com/tlwg/libdatrie" +PKG_URL="${PKG_SITE}/releases/download/v${PKG_VERSION}/libdatrie-${PKG_VERSION}.tar.xz" +PKG_DEPENDS_TARGET="toolchain libtool" +PKG_BUILD_FLAGS="+pic" +PKG_TOOLCHAIN="configure" + diff --git a/projects/ArchR/packages/devel/libfmt/package.mk b/projects/ArchR/packages/devel/libfmt/package.mk new file mode 100644 index 0000000000..8e7f85262e --- /dev/null +++ b/projects/ArchR/packages/devel/libfmt/package.mk @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +. ${ROOT}/packages/devel/libfmt/package.mk + +case ${DEVICE} in + SM8250|SM8550|SDM845) + ;; + *) + PKG_VERSION="9.1.0" + PKG_SHA256="" + PKG_URL="https://github.com/fmtlib/fmt/archive/${PKG_VERSION}.tar.gz" + ;; +esac diff --git a/projects/ArchR/packages/devel/libpthread-stubs/package.mk b/projects/ArchR/packages/devel/libpthread-stubs/package.mk new file mode 100644 index 0000000000..61575af746 --- /dev/null +++ b/projects/ArchR/packages/devel/libpthread-stubs/package.mk @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) + +PKG_NAME="libpthread-stubs" +PKG_VERSION="0.5" +PKG_LICENSE="OSS" +PKG_SITE="http://xcb.freedesktop.org/" +PKG_URL="http://xcb.freedesktop.org/dist/${PKG_NAME}-${PKG_VERSION}.tar.gz" +PKG_DEPENDS_HOST="toolchain" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="A library providing weak aliases for pthread functions." diff --git a/projects/ArchR/packages/devel/libserialport/package.mk b/projects/ArchR/packages/devel/libserialport/package.mk new file mode 100644 index 0000000000..adc4e7d857 --- /dev/null +++ b/projects/ArchR/packages/devel/libserialport/package.mk @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: GPL-2.0 + +PKG_NAME="libserialport" +PKG_VERSION="fd20b0fc5a34cd7f776e4af6c763f59041de223b" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/sigrokproject/libserialport" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="A minimal, cross-platform shared library written in C that is intended to take care of the OS-specific details when writing software that uses serial ports." +PKG_TOOLCHAIN="make" + +make_target() { + cd ${PKG_BUILD} + + ./autogen.sh + ./configure --host=${TARGET_NAME} --with-sysroot=${SYSROOT_PREFIX} --prefix=/usr +} diff --git a/projects/ArchR/packages/devel/libthai/package.mk b/projects/ArchR/packages/devel/libthai/package.mk new file mode 100644 index 0000000000..fe52fd44eb --- /dev/null +++ b/projects/ArchR/packages/devel/libthai/package.mk @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="libthai" +PKG_VERSION="0.1.29" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/tlwg/libthai" +PKG_URL="${PKG_SITE}/releases/download/v${PKG_VERSION}/libthai-${PKG_VERSION}.tar.xz" +PKG_DEPENDS_TARGET="toolchain libtool libdatrie" +PKG_BUILD_FLAGS="+pic" +PKG_TOOLCHAIN="configure" + +PKG_CONFIGURE_OPTS_TARGET=" --disable-dict --disable-doxygen-doc" + diff --git a/projects/ArchR/packages/devel/make/package.mk b/projects/ArchR/packages/devel/make/package.mk new file mode 100644 index 0000000000..467ccda2f0 --- /dev/null +++ b/projects/ArchR/packages/devel/make/package.mk @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="make" +PKG_VERSION="4.4.1" +PKG_SHA256="dd16fb1d67bfab79a72f5e8390735c49e3e8e70b4945a15ab1f81ddb78658fb3" +PKG_LICENSE="GPLv3" +PKG_SITE="https://www.gnu.org/software/make/" +PKG_URL="https://mirrors.kernel.org/gnu/make/${PKG_NAME}-${PKG_VERSION}.tar.gz" +PKG_DEPENDS_HOST="" +PKG_DEPENDS_TARGET="toolchain:host" +PKG_LONGDESC="Utility to maintain groups of programs." +PKG_BUILD_FLAGS="+local-cc -cfg-libs:host" + +post_makeinstall_host() { + ln -sf make ${TOOLCHAIN}/bin/gmake +} diff --git a/projects/ArchR/packages/devel/make/patches/make-02-fix-large-command-line-on-POSIX-systems.patch b/projects/ArchR/packages/devel/make/patches/make-02-fix-large-command-line-on-POSIX-systems.patch new file mode 100644 index 0000000000..12ac8b767a --- /dev/null +++ b/projects/ArchR/packages/devel/make/patches/make-02-fix-large-command-line-on-POSIX-systems.patch @@ -0,0 +1,170 @@ +From e249c43741779ae7dd6834f6840384257d4c3dd8 Mon Sep 17 00:00:00 2001 +From: Mike Crowe +Date: Fri, 6 Nov 2020 15:22:37 +0000 +Subject: [PATCH] [SV 45763] Fix large command line on POSIX systems + +When presented with a very long command line (as is common when linking +a large number of files with absolute paths in a deep subdirectory), +make fails to execute the command as it doesn't split the command line +to fit within the limits. + +This is based on a fix for Debian bug 688601[1] by Adam Conrad applied +by Manoj Srivastava originally applied for Debian make-dfsg 4.0-5 in +2014 but dropped in 2018 (it seems under the incorrect assumption that +it had been accepted upstream.) + +I've tweaked Adam's original patch so that it compiles successfully with +-Werror on top of current master. This required: + +* moving the eval_line declaration to the top of the block, so I moved + the macros too +* using a const variable when iterating over the shell +* adding a cast to avoid a signed/unsigned mismatch. + +As suggested in the Savannah bug report[2], I've added a test case that +fails without the rest of the patch. I'm not sure what the consequences +of running the test on non-POSIX targets would be and whether it needs +marking as an expected failure. + +* src/job.c (construct_command_argv_internal): support running commands +longer than MAX_ARG_STRLEN +* tests/scripts/features/long_command_line: add test for such a command +* configure.ac: check for now-required sys/user.h and linux/binfmts.h +headers + +[1] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=688601 +[2] https://savannah.gnu.org/bugs/?45763#comment2 +--- + src/job.c | 52 +++++++++++++++++++++++- + tests/scripts/features/long_command_line | 30 ++++++++++++++ + 2 files changed, 81 insertions(+), 1 deletions(-) + create mode 100644 tests/scripts/features/long_command_line + +diff --git a/src/job.c b/src/job.c +index 3bcec38..734c591 100644 +--- a/src/job.c ++++ b/src/job.c +@@ -26,6 +26,12 @@ this program. If not, see . */ + #include "variable.h" + #include "os.h" + ++#include ++#include ++#ifndef PAGE_SIZE ++# define PAGE_SIZE (sysconf(_SC_PAGESIZE)) ++#endif ++ + /* Default shell to use. */ + #ifdef WINDOWS32 + # ifdef HAVE_STRINGS_H +@@ -3228,6 +3236,15 @@ construct_command_argv_internal (char *line, char **restp, const char *shell, + size_t sflags_len = shellflags ? strlen (shellflags) : 0; + #ifdef WINDOWS32 + char *command_ptr = NULL; /* used for batch_mode_shell mode */ ++#endif ++ char *args_ptr; ++#ifdef MAX_ARG_STRLEN ++ static char eval_line[] = "eval\\ \\\"set\\ x\\;\\ shift\\;\\ "; ++#define ARG_NUMBER_DIGITS 5 ++#define EVAL_LEN (sizeof(eval_line)-1 + shell_len + 4 \ ++ + (7 + ARG_NUMBER_DIGITS) * 2 * line_len / (MAX_ARG_STRLEN - 2)) ++#else ++#define EVAL_LEN 0 + #endif + + # ifdef __EMX__ /* is this necessary? */ +@@ -3395,7 +3412,7 @@ construct_command_argv_internal (char *line, char **restp, const char *shell, + } + + new_line = xmalloc ((shell_len*2) + 1 + sflags_len + 1 +- + (line_len*2) + 1); ++ + (line_len*2) + 1 + EVAL_LEN); + ap = new_line; + /* Copy SHELL, escaping any characters special to the shell. If + we don't escape them, construct_command_argv_internal will +@@ -3415,6 +3432,31 @@ construct_command_argv_internal (char *line, char **restp, const char *shell, + #ifdef WINDOWS32 + command_ptr = ap; + #endif ++ ++#if !defined (WINDOWS32) && defined (MAX_ARG_STRLEN) ++ if (unixy_shell && line_len > MAX_ARG_STRLEN) ++ { ++ const char *q; ++ unsigned j; ++ memcpy (ap, eval_line, sizeof (eval_line) - 1); ++ ap += sizeof (eval_line) - 1; ++ for (j = 1; j <= 2 * line_len / (MAX_ARG_STRLEN - 2); j++) ++ ap += sprintf (ap, "\\$\\{%u\\}", j); ++ *ap++ = '\\'; ++ *ap++ = '"'; ++ *ap++ = ' '; ++ /* Copy only the first word of SHELL to $0. */ ++ for (q = shell; *q != '\0'; ++q) ++ { ++ if (isspace ((unsigned char)*q)) ++ break; ++ *ap++ = *q; ++ } ++ *ap++ = ' '; ++ } ++#endif ++ args_ptr = ap; ++ + for (p = line; *p != '\0'; ++p) + { + if (restp != NULL && *p == '\n') +@@ -3462,6 +3504,14 @@ construct_command_argv_internal (char *line, char **restp, const char *shell, + } + #endif + *ap++ = *p; ++#if !defined (WINDOWS32) && defined (MAX_ARG_STRLEN) ++ if (unixy_shell && line_len > MAX_ARG_STRLEN ++ && (ap - args_ptr > (long)(MAX_ARG_STRLEN - 2))) ++ { ++ *ap++ = ' '; ++ args_ptr = ap; ++ } ++#endif + } + if (ap == new_line + shell_len + sflags_len + 2) + { +diff --git a/tests/scripts/features/long_command_line b/tests/scripts/features/long_command_line +new file mode 100644 +index 0000000..3899ac8 +--- /dev/null ++++ b/tests/scripts/features/long_command_line +@@ -0,0 +1,30 @@ ++# -*-perl-*- ++$description = "Test long command line."; ++ ++$details = ""; ++ ++# Variable names containing UTF8 characters ++run_make_test(q! ++# 49 characters ++ARGS:=one two three four five six seven eight niner ten ++# 49*4+3 = 199 characters ++ARGS:=$(ARGS) $(ARGS) $(ARGS) $(ARGS) ++# 199*4+3 = 799 characters ++ARGS:=$(ARGS) $(ARGS) $(ARGS) $(ARGS) ++# 799*4+3 = 3199 characters ++ARGS:=$(ARGS) $(ARGS) $(ARGS) $(ARGS) ++# 3199*4+3 = 12799 characters ++ARGS:=$(ARGS) $(ARGS) $(ARGS) $(ARGS) ++# 12799*4+3 = 51199 characters ++ARGS:=$(ARGS) $(ARGS) $(ARGS) $(ARGS) ++# 51199*4+3 = 204799 characters ++ARGS:=$(ARGS) $(ARGS) $(ARGS) $(ARGS) ++# 24799*2+1 = 409599 characters ++#ARGS:=$(ARGS) $(ARGS) ++ ++test: ++ @: $(ARGS) ++!, ++ '', ""); ++ ++1; +-- +2.20.1 + diff --git a/projects/ArchR/packages/devel/ncurses/package.mk b/projects/ArchR/packages/devel/ncurses/package.mk new file mode 100644 index 0000000000..8daf772e58 --- /dev/null +++ b/projects/ArchR/packages/devel/ncurses/package.mk @@ -0,0 +1,95 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="ncurses" +PKG_VERSION="6.4" +PKG_LICENSE="MIT" +PKG_SITE="http://www.gnu.org/software/ncurses/" +PKG_URL="http://invisible-island.net/archives/ncurses/ncurses-${PKG_VERSION}.tar.gz" +PKG_DEPENDS_HOST="ccache:host" +PKG_DEPENDS_TARGET="toolchain zlib ncurses:host" +PKG_LONGDESC="A library is a free software emulation of curses in System V Release 4.0, and more." +PKG_BUILD_FLAGS="+pic +pic:host" +PKG_TOOLCHAIN="auto" + +PKG_CONFIGURE_OPTS_TARGET=" + --without-ada \ + --without-cxx \ + --without-cxx-binding \ + --disable-db-install \ + --without-manpages \ + --without-progs \ + --without-tests \ + --with-shared \ + --with-normal \ + --without-debug \ + --without-profile \ + --with-termlib \ + --without-ticlib \ + --without-gpm \ + --without-dbmalloc \ + --without-dmalloc \ + --disable-rpath \ + --disable-database \ + --with-fallbacks=linux,screen,xterm,xterm-color,dumb,st-256color \ + --with-termpath=/storage/.config/termcap \ + --disable-big-core \ + --enable-termcap \ + --enable-getcap \ + --disable-getcap-cache \ + --enable-symlinks \ + --disable-bsdpad \ + --without-rcs-ids \ + --enable-ext-funcs \ + --disable-const \ + --enable-no-padding \ + --disable-sigwinch \ + --enable-pc-files \ + --with-pkg-config-libdir=/usr/lib/pkgconfig \ + --enable-tcap-names \ + --without-develop \ + --disable-hard-tabs \ + --disable-xmc-glitch \ + --disable-hashmap \ + --disable-safe-sprintf \ + --disable-scroll-hints \ + --enable-widec \ + --disable-echo \ + --disable-warnings \ + --enable-home-terminfo \ + --enable-lib-suffixes \ + --disable-assertions" + +PKG_CONFIGURE_OPTS_HOST=" + --without-cxx-binding \ + --enable-termcap \ + --with-termlib \ + --without-shared \ + --enable-pc-files \ + --without-tests \ + --without-manpages" + +post_makeinstall_target() { + local f + cp misc/ncurses-config ${TOOLCHAIN}/bin + chmod +x ${TOOLCHAIN}/bin/ncurses-config + sed -e "s:\(['=\" ]\)/usr:\\1${PKG_ORIG_SYSROOT_PREFIX}/usr:g" -i ${TOOLCHAIN}/bin/ncurses-config + rm -f ${TOOLCHAIN}/bin/ncurses6-config + rm -rf ${INSTALL}/usr/bin + # create links to be compatible with any ncurses include path and lib names + ln -sf . ${SYSROOT_PREFIX}/usr/include/ncursesw + ln -sf . ${SYSROOT_PREFIX}/usr/include/ncurses + for f in form menu ncurses panel tinfo; do + ln -sf lib${f}w.a ${SYSROOT_PREFIX}/usr/lib/lib${f}.a + ln -sf ${f}w.pc ${SYSROOT_PREFIX}/usr/lib/pkgconfig/${f}.pc + done + cd ${INSTALL}/usr/lib + for LIB in *w*.so* + do + NOWLIB=$(echo ${LIB} | sed "s#w##g") + ln -sf ${LIB} ${INSTALL}/usr/lib/${NOWLIB} + done + cd - +} diff --git a/projects/ArchR/packages/devel/ncurses/patches/ncurses-001-terminfo-xterm.patch b/projects/ArchR/packages/devel/ncurses/patches/ncurses-001-terminfo-xterm.patch new file mode 100644 index 0000000000..3c2a9d0f0c --- /dev/null +++ b/projects/ArchR/packages/devel/ncurses/patches/ncurses-001-terminfo-xterm.patch @@ -0,0 +1,16 @@ + +Remove recent xterm terminfo features to be compatible with other emulations + +--- a/misc/terminfo.src 2021-03-20 22:45:39.000000000 +0100 ++++ b/misc/terminfo.src 2021-06-01 23:53:10.335516419 +0200 +@@ -4808,8 +4808,8 @@ xterm-xfree86|xterm terminal emulator (X + xterm+nofkeys|building block for xterm fkey-variants, + npc, + kcbt=\E[Z, kent=\EOM, nel=\EE, use=ecma+index, +- use=ansi+rep, use=ecma+strikeout, use=vt420+lrmm, +- use=xterm+sm+1006, use=xterm+tmux, use=ecma+italics, ++ use=ecma+strikeout, use=vt420+lrmm, ++ use=xterm+sm+1005, use=xterm+tmux, use=ecma+italics, + use=xterm+keypad, use=xterm-basic, + + # This version reflects the current xterm features. diff --git a/projects/ArchR/packages/devel/ncurses/patches/ncurses-002-alloc-fallbacks.patch b/projects/ArchR/packages/devel/ncurses/patches/ncurses-002-alloc-fallbacks.patch new file mode 100644 index 0000000000..eaf093adb5 --- /dev/null +++ b/projects/ArchR/packages/devel/ncurses/patches/ncurses-002-alloc-fallbacks.patch @@ -0,0 +1,13 @@ +Fix freeing not allocated fallback entries by allocating a copy. + +--- a/ncurses/tinfo/tinfo_driver.c 2018-11-24 23:17:03.000000000 +0100 ++++ b/ncurses/tinfo/tinfo_driver.c 2018-12-29 10:27:19.000000000 +0100 +@@ -180,6 +180,8 @@ drv_CanHandle(TERMINAL_CONTROL_BLOCK * T + if (status != TGETENT_YES) { + const TERMTYPE2 *fallback = _nc_fallback2(tname); + ++ if (fallback) ++ fallback = _nc_copy_entry(fallback); + if (fallback) { + T(("found fallback entry")); + TerminalType(termp) = *fallback; diff --git a/projects/ArchR/packages/devel/ncurses/patches/ncurses-003-fix_hints.patch b/projects/ArchR/packages/devel/ncurses/patches/ncurses-003-fix_hints.patch new file mode 100644 index 0000000000..8462304867 --- /dev/null +++ b/projects/ArchR/packages/devel/ncurses/patches/ncurses-003-fix_hints.patch @@ -0,0 +1,18 @@ +Fix USE_SCROLL_HINTS/USE_HASHMAP logic + +--- a/ncurses/curses.priv.h 2018-12-16 02:16:58.000000000 +0100 ++++ a/ncurses/curses.priv.h 2021-05-30 00:12:14.086528124 +0200 +@@ -258,10 +258,9 @@ extern NCURSES_EXPORT(void *) _nc_memmov + /* + * Scroll hints are useless when hashmap is used + */ +-#if !USE_SCROLL_HINTS +-#if !USE_HASHMAP +-#define USE_SCROLL_HINTS 1 +-#else ++#if USE_SCROLL_HINTS ++#if USE_HASHMAP ++#undef USE_SCROLL_HINTS + #define USE_SCROLL_HINTS 0 + #endif + #endif diff --git a/projects/ArchR/packages/devel/ncurses/patches/ncurses-004-fix_configure_pkgconfig.patch b/projects/ArchR/packages/devel/ncurses/patches/ncurses-004-fix_configure_pkgconfig.patch new file mode 100644 index 0000000000..171145cd09 --- /dev/null +++ b/projects/ArchR/packages/devel/ncurses/patches/ncurses-004-fix_configure_pkgconfig.patch @@ -0,0 +1,12 @@ +diff -rupN ncurses-6.4.orig/configure ncurses-6.4/configure +--- ncurses-6.4.orig/configure 2022-11-05 21:13:26.000000000 +0000 ++++ ncurses-6.4/configure 2023-05-09 11:21:38.765534941 +0000 +@@ -4236,7 +4236,7 @@ echo $ECHO_N "checking for first directo + cf_pkg_config_path=none + for cf_config in $cf_search_path + do +- if test -d "$cf_config" ++ if test -n "$cf_config" + then + cf_pkg_config_path=$cf_config + break diff --git a/projects/ArchR/packages/devel/patchelf/package.mk b/projects/ArchR/packages/devel/patchelf/package.mk new file mode 100644 index 0000000000..5205689e11 --- /dev/null +++ b/projects/ArchR/packages/devel/patchelf/package.mk @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (C) 2023-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="patchelf" +PKG_VERSION="0.18.0" +PKG_SHA256="1952b2a782ba576279c211ee942e341748fdb44997f704dd53def46cd055470b" +PKG_LICENSE="GPL-3.0-or-later" +PKG_SITE="https://github.com/NixOS/patchelf" +PKG_URL="https://github.com/NixOS/patchelf/releases/download/${PKG_VERSION}/patchelf-${PKG_VERSION}.tar.bz2" +PKG_DEPENDS_HOST="autotools:host" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="A small utility to modify the dynamic linker and RPATH of ELF executables" +PKG_TOOLCHAIN="autotools" +PKG_BUILD_FLAGS="-cfg-libs:host" diff --git a/projects/ArchR/packages/devel/readline/package.mk b/projects/ArchR/packages/devel/readline/package.mk new file mode 100644 index 0000000000..796ca3679f --- /dev/null +++ b/projects/ArchR/packages/devel/readline/package.mk @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +. ${ROOT}/packages/devel/readline/package.mk + +PKG_CONFIGURE_OPTS_TARGET="bash_cv_wcwidth_broken=no \ + --enable-shared \ + --disable-static \ + --with-curses" + +# Ensure shared libreadline.so links against ncurses (provides termcap symbols: BC, UP, tputs, etc.) +PKG_MAKE_OPTS_TARGET="SHLIB_LIBS=-lncursesw" +PKG_MAKEINSTALL_OPTS_TARGET="SHLIB_LIBS=-lncursesw" + +pre_configure_target() { + export LDFLAGS="${LDFLAGS} -lncursesw" +} diff --git a/projects/ArchR/packages/devel/readline/patches/01-fix-iwd.patch b/projects/ArchR/packages/devel/readline/patches/01-fix-iwd.patch new file mode 100644 index 0000000000..7458dd4545 --- /dev/null +++ b/projects/ArchR/packages/devel/readline/patches/01-fix-iwd.patch @@ -0,0 +1,15 @@ +*** a/display.c +--- b/display.c +*************** +*** 784,788 **** + /* Useful shorthand used by rl_redisplay, update_line, rl_move_cursor_relative */ + #define INVIS_FIRST() (local_prompt_invis_chars[0]) +! #define WRAP_OFFSET(line, offset) ((line <= prompt_last_screen_line) ? local_prompt_invis_chars[line] : 0) + + #define W_OFFSET(line, offset) ((line) == 0 ? offset : 0) +--- 784,788 ---- + /* Useful shorthand used by rl_redisplay, update_line, rl_move_cursor_relative */ + #define INVIS_FIRST() (local_prompt_invis_chars[0]) +! #define WRAP_OFFSET(line, offset) ((line <= prompt_last_screen_line && local_prompt_invis_chars) ? local_prompt_invis_chars[line] : 0) + + #define W_OFFSET(line, offset) ((line) == 0 ? offset : 0) diff --git a/projects/ArchR/packages/devel/shared-mime-info/package.mk b/projects/ArchR/packages/devel/shared-mime-info/package.mk new file mode 100644 index 0000000000..d0abba6de2 --- /dev/null +++ b/projects/ArchR/packages/devel/shared-mime-info/package.mk @@ -0,0 +1,32 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="shared-mime-info" +PKG_VERSION="2.4" +PKG_LICENSE="GPL-2.0-only" +PKG_SITE="https://freedesktop.org/wiki/Software/shared-mime-info/" +PKG_URL="https://gitlab.freedesktop.org/xdg/${PKG_NAME}/-/archive/${PKG_VERSION}/${PKG_NAME}-${PKG_VERSION}.tar.bz2" +PKG_DEPENDS_HOST="toolchain:host glib:host libxml2:host gettext:host itstool:host" +PKG_DEPENDS_TARGET="toolchain glib libxml2 gettext shared-mime-info:host" +PKG_LONGDESC="The shared-mime-info package contains the core database of common types." +PKG_BUILD_FLAGS="-parallel" + +configure_package() { + # Sway Support + if [ ! "${WINDOWMANAGER}" = "sway" ]; then + PKG_BUILD_FLAGS+=" -sysroot" + fi +} + +PKG_MESON_OPTS_HOST="-Dupdate-mimedb=false" +PKG_MESON_OPTS_TARGET="-Dupdate-mimedb=false" + +post_makeinstall_target() { + mkdir -p ${SYSROOT_PREFIX}/usr/lib/pkgconfig + cp shared-mime-info.pc ${SYSROOT_PREFIX}/usr/lib/pkgconfig + + # Create /usr/share/mime/mime.cache + if [ "${WINDOWMANAGER}" = "sway" ]; then + ${TOOLCHAIN}/bin/update-mime-database ${INSTALL}/usr/share/mime + fi +} diff --git a/projects/ArchR/packages/devel/swig/package.mk b/projects/ArchR/packages/devel/swig/package.mk new file mode 100644 index 0000000000..829c79652d --- /dev/null +++ b/projects/ArchR/packages/devel/swig/package.mk @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2019-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="swig" +PKG_VERSION="4.1.1" +PKG_SHA256="2af08aced8fcd65cdb5cc62426768914bedc735b1c250325203716f78e39ac9b" +PKG_LICENSE="GPL" +PKG_SITE="http://www.swig.org" +PKG_URL="${SOURCEFORGE_SRC}/swig/${PKG_NAME}-${PKG_VERSION}.tar.gz" +PKG_DEPENDS_HOST="ccache:host" +PKG_LONGDESC="SWIG is a software development tool that connects programs written in C and C++ with a variety of high-level programming languages." +PKG_TOOLCHAIN="configure" + +PKG_CONFIGURE_OPTS_HOST="--program-suffix=4.0 \ + --with-pcre-prefix=${TOOLCHAIN} \ + --with-boost=no \ + --without-pcre \ + --without-x \ + --without-tcl \ + --without-python \ + --without-python3 \ + --without-perl5 \ + --without-octave \ + --without-java \ + --without-gcj \ + --without-android \ + --without-guile \ + --without-mzscheme \ + --without-ruby \ + --without-php \ + --without-ocaml \ + --without-pike \ + --without-chicken \ + --without-csharp \ + --without-lua \ + --without-allegrocl \ + --without-clisp \ + --without-r \ + --without-go \ + --without-d" + +post_makeinstall_host() { + ln -sf swig4.0 ${TOOLCHAIN}/bin/swig +} diff --git a/projects/ArchR/packages/devel/xa/package.mk b/projects/ArchR/packages/devel/xa/package.mk new file mode 100644 index 0000000000..df960f1750 --- /dev/null +++ b/projects/ArchR/packages/devel/xa/package.mk @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="xa" +PKG_VERSION="2.4.1" +PKG_LICENSE="GPL" +PKG_SITE="http://tinycorelinux.net" +PKG_URL="${PKG_SITE}/15.x/x86/tcz/src/xa/xa-${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_DEPENDS_HOST="ccache:host" +PKG_LONGDESC="xa is a high-speed, two-pass portable cross-assembler." + +makeinstall_host() { + mkdir -p ${TOOLCHAIN}/bin + cp -f file65 ldo65 mkrom.sh printcbm reloc65 uncpk xa ${TOOLCHAIN}/bin +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp -f file65 ldo65 mkrom.sh printcbm reloc65 uncpk xa ${INSTALL}/usr/bin +} diff --git a/projects/ArchR/packages/emulators/libretro/81-lr/package.mk b/projects/ArchR/packages/emulators/libretro/81-lr/package.mk new file mode 100644 index 0000000000..4040f6d0a4 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/81-lr/package.mk @@ -0,0 +1,38 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="81-lr" +PKG_VERSION="ffc99f27f092addc9ddd34dd0e3a3d4d1c053cbf" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/libretro/81-libretro" +PKG_URL="https://github.com/libretro/81-libretro/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="A port of the EightyOne ZX81 Emulator to libretro" + +PKG_TOOLCHAIN="make" + +make_target() { + make -f Makefile.libretro +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp 81_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/a5200-lr/package.mk b/projects/ArchR/packages/emulators/libretro/a5200-lr/package.mk new file mode 100644 index 0000000000..e5a111bea2 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/a5200-lr/package.mk @@ -0,0 +1,36 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="a5200-lr" +PKG_VERSION="526404072821bb2021fab16f8c5dbbca300512c8" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/libretro/a5200" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Atari 5200 libretro core" +PKG_TOOLCHAIN="auto" +GET_HANDLER_SUPPORT="git" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp a5200_libretro.so ${INSTALL}/usr/lib/libretro/ +} + diff --git a/projects/ArchR/packages/emulators/libretro/arduous-lr/package.mk b/projects/ArchR/packages/emulators/libretro/arduous-lr/package.mk new file mode 100644 index 0000000000..18b5197914 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/arduous-lr/package.mk @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="arduous-lr" +PKG_VERSION="50c1e48084f003dee582ed5f4f5c0f59eb30bc4c" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/libretro/arduous" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="A Libretro emulator core for the Arduboy" + +PKG_CMAKE_OPTS_TARGET="-DCMAKE_POLICY_VERSION_MINIMUM=3.5" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp arduous_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/atari800-lr/package.mk b/projects/ArchR/packages/emulators/libretro/atari800-lr/package.mk new file mode 100644 index 0000000000..0985b7fee3 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/atari800-lr/package.mk @@ -0,0 +1,35 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="atari800-lr" +PKG_VERSION="6a18cb23cc4a7cecabd9b16143d2d7332ae8d44b" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/libretro/libretro-atari800" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="atari800 3.1.0 for libretro/libco WIP" +PKG_TOOLCHAIN="auto" +GET_HANDLER_SUPPORT="git" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp atari800_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/b2-lr/package.mk b/projects/ArchR/packages/emulators/libretro/b2-lr/package.mk new file mode 100644 index 0000000000..a97cf28ae9 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/b2-lr/package.mk @@ -0,0 +1,40 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="b2-lr" +PKG_VERSION="ffcfcddc5ba05a97e04372672879bc25284ff653" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/zoltanvb/b2-libretro" +PKG_URL="https://github.com/zoltanvb/b2-libretro/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Adaptation of Tom Seddon's b2 emulator for BBC Micro" + +PKG_TOOLCHAIN="make" + +make_target() { + cd ${PKG_BUILD}/src/libretro + make -j$(getconf _NPROCESSORS_ONLN) clean + make -j$(getconf _NPROCESSORS_ONLN) +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp b2_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/b2-lr/patches/01-fix-gcc14.patch b/projects/ArchR/packages/emulators/libretro/b2-lr/patches/01-fix-gcc14.patch new file mode 100644 index 0000000000..843c8592a8 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/b2-lr/patches/01-fix-gcc14.patch @@ -0,0 +1,17 @@ +diff --git a/src/shared/h/shared/system.h b/src/shared/h/shared/system.h +index f5f38b34..2d765a07 100644 +--- a/src/shared/h/shared/system.h ++++ b/src/shared/h/shared/system.h +@@ -289,7 +289,11 @@ int vasprintf(char **buf, const char *fmt, va_list v); + // + // See https://lwn.net/Articles/612244/ + #ifndef HAVE_STRLCPY ++#if __GNUC__ >= 14 ++extern "C" size_t strlcpy(char *dest, const char *src, size_t size) noexcept; ++#else + size_t strlcpy(char *dest, const char *src, size_t size); ++#endif + #endif // HAVE_STRLCPY + #endif + + diff --git a/projects/ArchR/packages/emulators/libretro/beetle-gba-lr/package.mk b/projects/ArchR/packages/emulators/libretro/beetle-gba-lr/package.mk new file mode 100644 index 0000000000..3f5b322e09 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/beetle-gba-lr/package.mk @@ -0,0 +1,35 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="beetle-gba-lr" +PKG_VERSION="6cee80685f735ea6c2373db2622a1f1ee9f39d39" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/beetle-gba-libretro" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="libretro implementation of Mednafen VBA/GBA. (Game Boy Advance)" + +PKG_TOOLCHAIN="make" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp mednafen_gba_libretro.so ${INSTALL}/usr/lib/libretro/beetle_gba_libretro.so +} diff --git a/projects/ArchR/packages/emulators/libretro/beetle-lynx-lr/package.mk b/projects/ArchR/packages/emulators/libretro/beetle-lynx-lr/package.mk new file mode 100644 index 0000000000..6d29e845a8 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/beetle-lynx-lr/package.mk @@ -0,0 +1,35 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="beetle-lynx-lr" +PKG_VERSION="efd1797c7aa5a83c354507b1b61ac24222ebaa58" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/beetle-lynx-libretro" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="libretro implementation of Mednafen Lynx" + +PKG_TOOLCHAIN="make" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp mednafen_lynx_libretro.so ${INSTALL}/usr/lib/libretro/beetle_lynx_libretro.so +} diff --git a/projects/ArchR/packages/emulators/libretro/beetle-ngp-lr/package.mk b/projects/ArchR/packages/emulators/libretro/beetle-ngp-lr/package.mk new file mode 100644 index 0000000000..2b5f17ecd8 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/beetle-ngp-lr/package.mk @@ -0,0 +1,35 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="beetle-ngp-lr" +PKG_VERSION="139fe34c8dfc5585d6ee1793a7902bca79d544de" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/beetle-ngp-libretro" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="libretro implementation of Mednafen Neo Geo Pocket." + +PKG_TOOLCHAIN="make" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp mednafen_ngp_libretro.so ${INSTALL}/usr/lib/libretro/beetle_ngp_libretro.so +} diff --git a/projects/ArchR/packages/emulators/libretro/beetle-pce-fast-lr/package.mk b/projects/ArchR/packages/emulators/libretro/beetle-pce-fast-lr/package.mk new file mode 100644 index 0000000000..f3f14b2474 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/beetle-pce-fast-lr/package.mk @@ -0,0 +1,35 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="beetle-pce-fast-lr" +PKG_VERSION="7e9b257b8a591cb7e00f9e55371edba19db9799c" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/beetle-pce-fast-libretro" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Standalone port of Mednafen PCE Fast to libretro." + +PKG_TOOLCHAIN="make" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp mednafen_pce_fast_libretro.so ${INSTALL}/usr/lib/libretro/beetle_pce_fast_libretro.so +} diff --git a/projects/ArchR/packages/emulators/libretro/beetle-pce-lr/package.mk b/projects/ArchR/packages/emulators/libretro/beetle-pce-lr/package.mk new file mode 100644 index 0000000000..6bb8ea70e9 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/beetle-pce-lr/package.mk @@ -0,0 +1,35 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="beetle-pce-lr" +PKG_VERSION="9a301c0773c53702a882bbaa42ee9cbc6d523787" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/beetle-pce-libretro" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Standalone port of Mednafen PCE to libretro." + +PKG_TOOLCHAIN="make" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp mednafen_pce_libretro.so ${INSTALL}/usr/lib/libretro/beetle_pce_libretro.so +} diff --git a/projects/ArchR/packages/emulators/libretro/beetle-pcfx-lr/package.mk b/projects/ArchR/packages/emulators/libretro/beetle-pcfx-lr/package.mk new file mode 100644 index 0000000000..4a28c1a536 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/beetle-pcfx-lr/package.mk @@ -0,0 +1,43 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="beetle-pcfx-lr" +PKG_VERSION="dd04cef9355286488a1d78ff18c4c848a1575540" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/beetle-pcfx-libretro" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="libretro implementation of Mednafen PC-FX." + +PKG_TOOLCHAIN="make" + +make_target() { + if [ "${ARCH}" == "i386" -o "${ARCH}" == "x86_64" ]; then + make platform=unix CC=${CC} CXX=${CXX} AR=${AR} + else + make platform=armv CC=${CC} CXX=${CXX} AR=${AR} + fi +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp mednafen_pcfx_libretro.so ${INSTALL}/usr/lib/libretro/beetle_pcfx_libretro.so +} diff --git a/projects/ArchR/packages/emulators/libretro/beetle-psx-lr/package.mk b/projects/ArchR/packages/emulators/libretro/beetle-psx-lr/package.mk new file mode 100644 index 0000000000..37542bc144 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/beetle-psx-lr/package.mk @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="beetle-psx-lr" +PKG_VERSION="4e0cb4ddf0c52ef802cd4f7f2b7d3a187ab9962d" +PKG_LICENSE="GPLv2" +PKG_SITE="https://git.libretro.com/libretro/beetle-psx-libretro" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Fork of Mednafen PSX" +PKG_TOOLCHAIN="make" + +if [ ! "${OPENGL}" = "no" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" +fi + +if [ "${OPENGLES_SUPPORT}" = yes ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" +fi + +if [ "${VULKAN_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${VULKAN}" +fi + +PKG_MAKE_OPTS_TARGET+=" LINK_STATIC_LIBCPLUSPLUS=0" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp mednafen_psx_libretro.so ${INSTALL}/usr/lib/libretro/beetle_psx_libretro.so +} diff --git a/projects/ArchR/packages/emulators/libretro/beetle-saturn-lr/package.mk b/projects/ArchR/packages/emulators/libretro/beetle-saturn-lr/package.mk new file mode 100644 index 0000000000..fb6f6c7fdd --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/beetle-saturn-lr/package.mk @@ -0,0 +1,32 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="beetle-saturn-lr" +PKG_VERSION="06c9daa7ff6de42955437d29a80d8fc4ececc8d3" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/beetle-saturn-libretro" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Beetle Saturn libretro, a fork from mednafen" +PKG_TOOLCHAIN="make" + +if [ ! "${OPENGL}" = "no" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" +fi + +if [ "${OPENGLES_SUPPORT}" = yes ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" +fi + +make_target() { + if [ "${ARCH}" == "i386" -o "${ARCH}" == "x86_64" ]; then + make platform=unix CC=${CC} CXX=${CXX} AR=${AR} + else + make platform=armv CC=${CC} CXX=${CXX} AR=${AR} + fi +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp mednafen_saturn_libretro.so ${INSTALL}/usr/lib/libretro/beetle_saturn_libretro.so +} diff --git a/projects/ArchR/packages/emulators/libretro/beetle-supafaust-lr/config/Supafaust.opt b/projects/ArchR/packages/emulators/libretro/beetle-supafaust-lr/config/Supafaust.opt new file mode 100644 index 0000000000..5c73e159c8 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/beetle-supafaust-lr/config/Supafaust.opt @@ -0,0 +1,19 @@ +supafaust_audio_rate = "disabled" +supafaust_correct_aspect = "enabled" +supafaust_cx4_clock_rate = "100" +supafaust_deinterlacer = "bob_offset" +supafaust_frame_begin_vblank = "enabled" +supafaust_h_filter = "phr256blend_auto512" +supafaust_multitap = "disabled" +supafaust_pixel_format = "rgb565" +supafaust_region = "auto" +supafaust_renderer = "mt" +supafaust_run_ahead = "disabled" +supafaust_slend = "223" +supafaust_slendp = "238" +supafaust_slstart = "0" +supafaust_slstartp = "0" +supafaust_superfx_clock_rate = "100" +supafaust_superfx_icache = "disabled" +supafaust_thread_affinity_emu = "0x3" +supafaust_thread_affinity_ppu = "0xc" diff --git a/projects/ArchR/packages/emulators/libretro/beetle-supafaust-lr/package.mk b/projects/ArchR/packages/emulators/libretro/beetle-supafaust-lr/package.mk new file mode 100644 index 0000000000..26abdf1c98 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/beetle-supafaust-lr/package.mk @@ -0,0 +1,40 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="beetle-supafaust-lr" +PKG_VERSION="e25f66765938d33f9ad5850e8d6cd597e55b7299" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/supafaust" +PKG_URL="${PKG_SITE}.git" +#PKG_GIT_CLONE_BRANCH="hd" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Super Nintendo (Super Famicom) emulator" +GET_HANDLER_SUPPORT="git" +PKG_TOOLCHAIN="make" + + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp ${PKG_BUILD}/mednafen_supafaust_libretro.so ${INSTALL}/usr/lib/libretro/beetle_supafaust_libretro.so + + mkdir -p ${INSTALL}/usr/config/retroarch + cp -rf ${PKG_DIR}/config/* ${INSTALL}/usr/config/retroarch/ +} diff --git a/projects/ArchR/packages/emulators/libretro/beetle-supergrafx-lr/package.mk b/projects/ArchR/packages/emulators/libretro/beetle-supergrafx-lr/package.mk new file mode 100644 index 0000000000..9d6d69037a --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/beetle-supergrafx-lr/package.mk @@ -0,0 +1,35 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="beetle-supergrafx-lr" +PKG_VERSION="a776133c34ae8da5daf7d9ccb43e3e292e2b07b0" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/beetle-supergrafx-libretro" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Standalone port of Mednafen PCE Fast to libretro." + +PKG_TOOLCHAIN="make" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp mednafen_supergrafx_libretro.so ${INSTALL}/usr/lib/libretro/beetle_supergrafx_libretro.so +} diff --git a/projects/ArchR/packages/emulators/libretro/beetle-vb-lr/package.mk b/projects/ArchR/packages/emulators/libretro/beetle-vb-lr/package.mk new file mode 100644 index 0000000000..9924eefd6f --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/beetle-vb-lr/package.mk @@ -0,0 +1,35 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="beetle-vb-lr" +PKG_VERSION="8f837ebc077afdd6652efb2827fd8308a07113ca" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/beetle-vb-libretro" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="libretro implementation of Mednafen VB. (VirtualBoy)" + +PKG_TOOLCHAIN="make" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp mednafen_vb_libretro.so ${INSTALL}/usr/lib/libretro/beetle_vb_libretro.so +} diff --git a/projects/ArchR/packages/emulators/libretro/beetle-wswan-lr/package.mk b/projects/ArchR/packages/emulators/libretro/beetle-wswan-lr/package.mk new file mode 100644 index 0000000000..83b4176936 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/beetle-wswan-lr/package.mk @@ -0,0 +1,35 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="beetle-wswan-lr" +PKG_VERSION="2aeb47d3a58bf0360c686f842d9bb5bd201306fe" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/beetle-wswan-libretro" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="libretro implementation of Mednafen wswan" + +PKG_TOOLCHAIN="make" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp mednafen_wswan_libretro.so ${INSTALL}/usr/lib/libretro/beetle_wswan_libretro.so +} diff --git a/projects/ArchR/packages/emulators/libretro/bluemsx-lr/package.mk b/projects/ArchR/packages/emulators/libretro/bluemsx-lr/package.mk new file mode 100644 index 0000000000..008b5ca8e3 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/bluemsx-lr/package.mk @@ -0,0 +1,39 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="bluemsx-lr" +PKG_VERSION="036376d6679c9e153712dbbb3fdca774afc49706" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/blueMSX-libretro" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Port of blueMSX to the libretro API." + +PKG_TOOLCHAIN="make" + +make_target() { + make -f Makefile.libretro +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp bluemsx_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/boom3-lr/package.mk b/projects/ArchR/packages/emulators/libretro/boom3-lr/package.mk new file mode 100644 index 0000000000..d235d93512 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/boom3-lr/package.mk @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="boom3-lr" +PKG_VERSION="0bea79abf5ec8262dfe9af73cb8c54ea6e2aeb98" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/libretro/boom3" +PKG_URL="https://github.com/libretro/boom3/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Doom3 - dhewm3 port to libretro." +PKG_TOOLCHAIN="make" + +if [ "${OPENGL_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL}" +elif [ "${OPENGLES_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" +fi + +make_target() { + make -C neo BASE=1 + make -C neo D3XP=1 +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp -v ${PKG_BUILD}/neo/boom3_libretro.so ${INSTALL}/usr/lib/libretro/ + cp -v ${PKG_BUILD}/neo/boom3_xp_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/bsnes-hd-lr/package.mk b/projects/ArchR/packages/emulators/libretro/bsnes-hd-lr/package.mk new file mode 100644 index 0000000000..199267b926 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/bsnes-hd-lr/package.mk @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (C) 2023-present Daedalia (https://github.com/daedalia) + +PKG_NAME="bsnes-hd-lr" +PKG_VERSION="0bb7b8645e22ea2476cabd58f32e987b14686601" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/DerKoun/bsnes-hd" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="bsnes-hd is a fork of bsnes that adds HD video features such as widescreen, HD Mode 7 and true color" + +PKG_TOOLCHAIN="make" + +PKG_MAKE_OPTS_TARGET+=" -C bsnes target=libretro compiler=${TARGET_NAME}-g++" + +pre_configure_target() { + sed -i 's/\-O[23]/-Ofast/' ${PKG_BUILD}/bsnes/GNUmakefile +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp bsnes/out/bsnes_hd_beta_libretro.so ${INSTALL}/usr/lib/libretro/ +} + diff --git a/projects/ArchR/packages/emulators/libretro/bsnes-hd-lr/patches/makefile-remove-build-flags.patch b/projects/ArchR/packages/emulators/libretro/bsnes-hd-lr/patches/makefile-remove-build-flags.patch new file mode 100644 index 0000000000..95a6901487 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/bsnes-hd-lr/patches/makefile-remove-build-flags.patch @@ -0,0 +1,12 @@ +diff --git a/bsnes/GNUmakefile b/bsnes/GNUmakefile +index 58466fb..578a916 100644 +--- a/bsnes/GNUmakefile ++++ b/bsnes/GNUmakefile +@@ -37,7 +37,6 @@ else ifeq ($(platform),macos) + else ifneq ($(filter $(platform),linux bsd),) + ifeq ($(binary),application) + options += -Wl,-export-dynamic +- options += -lX11 -lXext + else ifeq ($(binary),library) + flags += -fPIC + options += -shared diff --git a/projects/ArchR/packages/emulators/libretro/bsnes-lr/package.mk b/projects/ArchR/packages/emulators/libretro/bsnes-lr/package.mk new file mode 100644 index 0000000000..2945641f4a --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/bsnes-lr/package.mk @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="bsnes-lr" +PKG_VERSION="b102d6d5817b25aa059b573cd3b7675f2e375fa4" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/bsnes-libretro" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="BSNES Super Nintendo Libretro Core" +PKG_TOOLCHAIN="make" + +if [ ! "${OPENGL}" = "no" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" +fi + +if [ "${OPENGLES_SUPPORT}" = yes ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" +fi + +pre_configure_target() { + sed -i 's/\-O[23]/-Ofast/' ${PKG_BUILD}/Makefile +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp bsnes_libretro.so ${INSTALL}/usr/lib/libretro/ +} + diff --git a/projects/ArchR/packages/emulators/libretro/bsnes-mercury-accuracy-lr/package.mk b/projects/ArchR/packages/emulators/libretro/bsnes-mercury-accuracy-lr/package.mk new file mode 100644 index 0000000000..168de285c5 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/bsnes-mercury-accuracy-lr/package.mk @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="bsnes-mercury-accuracy-lr" +PKG_VERSION="0f35d044bf2f2b879018a0500e676447e93a1db1" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/bsnes-mercury" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="BSNES Super Nintendo Libretro Core" +PKG_TOOLCHAIN="make" + +pre_configure_target() { + sed -i 's/\-O[23]/-Ofast/' ${PKG_BUILD}/Makefile +} + +pre_make_target() { + PKG_MAKE_OPTS_TARGET+=" platform=${DEVICE}" +} + +make_target() { + make PROFILE=accuracy +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp bsnes_mercury_accuracy_libretro.so ${INSTALL}/usr/lib/libretro/ +} + diff --git a/projects/ArchR/packages/emulators/libretro/bsnes-mercury-balanced-lr/package.mk b/projects/ArchR/packages/emulators/libretro/bsnes-mercury-balanced-lr/package.mk new file mode 100644 index 0000000000..4e3422d8bd --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/bsnes-mercury-balanced-lr/package.mk @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="bsnes-mercury-balanced-lr" +PKG_VERSION="0f35d044bf2f2b879018a0500e676447e93a1db1" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/bsnes-mercury" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="BSNES Super Nintendo Libretro Core" +PKG_TOOLCHAIN="make" + +pre_configure_target() { + sed -i 's/\-O[23]/-Ofast/' ${PKG_BUILD}/Makefile +} + +pre_make_target() { + PKG_MAKE_OPTS_TARGET+=" platform=${DEVICE}" +} + +make_target() { + make PROFILE=balanced +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp bsnes_mercury_balanced_libretro.so ${INSTALL}/usr/lib/libretro/ +} + diff --git a/projects/ArchR/packages/emulators/libretro/bsnes-mercury-performance-lr/package.mk b/projects/ArchR/packages/emulators/libretro/bsnes-mercury-performance-lr/package.mk new file mode 100644 index 0000000000..4a85b567b9 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/bsnes-mercury-performance-lr/package.mk @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="bsnes-mercury-performance-lr" +PKG_VERSION="0f35d044bf2f2b879018a0500e676447e93a1db1" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/bsnes-mercury" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="BSNES Super Nintendo Libretro Core" +PKG_TOOLCHAIN="make" + +pre_configure_target() { + sed -i 's/\-O[23]/-Ofast/' ${PKG_BUILD}/Makefile +} + +pre_make_target() { + PKG_MAKE_OPTS_TARGET+=" platform=${DEVICE}" +} + +make_target() { + make PROFILE=performance +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp bsnes_mercury_performance_libretro.so ${INSTALL}/usr/lib/libretro/ +} + diff --git a/projects/ArchR/packages/emulators/libretro/cap32-lr/package.mk b/projects/ArchR/packages/emulators/libretro/cap32-lr/package.mk new file mode 100644 index 0000000000..3aea395765 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/cap32-lr/package.mk @@ -0,0 +1,35 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="cap32-lr" +PKG_VERSION="a5d96c5ebbda3bc89a3bd1c1691a20f5eacc232d" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/libretro-cap32" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="caprice32 4.2.0 libretro" + +PKG_TOOLCHAIN="make" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp cap32_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/common-shaders/package.mk b/projects/ArchR/packages/emulators/libretro/common-shaders/package.mk new file mode 100644 index 0000000000..cc9c4e3432 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/common-shaders/package.mk @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="common-shaders" +PKG_VERSION="86cfa146a8dfddf6377ddb5dbcff552feae2e5bf" +PKG_ARCH="aarch64" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/libretro/common-shaders" +PKG_URL="https://github.com/libretro/common-shaders/archive/${PKG_VERSION}.tar.gz" +PKG_LONGDESC="Libretro common shaders" +PKG_TOOLCHAIN="manual" + +make_target() { + : +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/share/common-shaders + cp -PR ${PKG_BUILD}/* ${INSTALL}/usr/share/common-shaders + rm -f ${INSTALL}/usr/share/common-shaders/{Makefile,configure} +} diff --git a/projects/ArchR/packages/emulators/libretro/core-info/package.mk b/projects/ArchR/packages/emulators/libretro/core-info/package.mk new file mode 100644 index 0000000000..577419bc1d --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/core-info/package.mk @@ -0,0 +1,37 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="core-info" +PKG_VERSION="20e7d555f911f5aa6712d5937f7b9b834015d88d" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/libretro/libretro-core-info" +PKG_URL="https://github.com/libretro/libretro-core-info/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Mirror of libretro's core info files" +PKG_TOOLCHAIN="manual" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + ${TOOLCHAIN}/bin/rename -v mednafen beetle ${PKG_BUILD}/*.info + cp ${PKG_BUILD}/*.info ${INSTALL}/usr/lib/libretro/ + cp ${PKG_BUILD}/pcsx_rearmed_libretro.info ${INSTALL}/usr/lib/libretro/pcsx_rearmed32_libretro.info + cp ${PKG_BUILD}/flycast_libretro.info ${INSTALL}/usr/lib/libretro/flycast2021_libretro.info +} diff --git a/projects/ArchR/packages/emulators/libretro/crocods-lr/package.mk b/projects/ArchR/packages/emulators/libretro/crocods-lr/package.mk new file mode 100644 index 0000000000..1fbafdac93 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/crocods-lr/package.mk @@ -0,0 +1,35 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="crocods-lr" +PKG_VERSION="a320f6e38af49af84a63f81329a1bdb9322022b4" +PKG_LICENSE="MIT" +PKG_SITE="https://github.com/libretro/libretro-crocods" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Amstrad CPC emulator" + +PKG_TOOLCHAIN="make" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp crocods_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/crocods-lr/patches/001-keyboard.patch b/projects/ArchR/packages/emulators/libretro/crocods-lr/patches/001-keyboard.patch new file mode 100644 index 0000000000..aad705c424 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/crocods-lr/patches/001-keyboard.patch @@ -0,0 +1,22 @@ +From 997a1f4851c53eca18c17ef753e284b3420ff871 Mon Sep 17 00:00:00 2001 +From: christianhaitian +Date: Tue, 26 Jan 2021 14:10:15 -0500 +Subject: [PATCH] Change keyboard mapping from French to US + +--- + libretro.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libretro.c b/libretro.c +index ef4b250..b18e01e 100644 +--- a/libretro.c ++++ b/libretro.c +@@ -125,7 +125,7 @@ void retro_init(void) + + // Get map layout + +- gb.keyboardLayout = 1; // French ++ gb.keyboardLayout = 0; // English + + for (i = 0; i < RETROK_LAST; i++) { + KeySymToCPCKey[i] = CPC_NIL; diff --git a/projects/ArchR/packages/emulators/libretro/daphne-lr/package.mk b/projects/ArchR/packages/emulators/libretro/daphne-lr/package.mk new file mode 100644 index 0000000000..7af8d89a25 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/daphne-lr/package.mk @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2019-present Shanti Gilbert (https://github.com/shantigilbert) + +PKG_NAME="daphne-lr" +PKG_VERSION="b5481bab34a51369b6749cd95f5f889e43aaa23f" +PKG_LICENSE="GPLv2+" +PKG_SITE="https://github.com/libretro/daphne" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="This is a Daphne core" +PKG_TOOLCHAIN="make" + +pre_configure_target() { + export CFLAGS="${CFLAGS} -Wno-use-after-free -Wno-unused-function -Wno-maybe-uninitialized -Wno-unused-variable -Wno-implicit-function-declaration -Wno-builtin-declaration-mismatch -Wno-unknown-pragmas -Wno-pointer-to-int-cast -Wno-pedantic -Wno-error=incompatible-pointer-types" +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp daphne_libretro.so ${INSTALL}/usr/lib/libretro/ +} + diff --git a/projects/ArchR/packages/emulators/libretro/desmume-lr/package.mk b/projects/ArchR/packages/emulators/libretro/desmume-lr/package.mk new file mode 100644 index 0000000000..36bbbf44f5 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/desmume-lr/package.mk @@ -0,0 +1,50 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="desmume-lr" +PKG_VERSION="7f05a8d447b00acd9e0798aee97b4f72eb505ef9" +PKG_LICENSE="GPLv2" +PKG_SITE="https://git.libretro.com/libretro/desmume" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain libpcap" +PKG_LONGDESC="DeSmuME - Nintendo DS libretro" +PKG_TOOLCHAIN="make" + +if [ "${OPENGL_SUPPORT}" = "yes" ] && [ ! "${PREFER_GLES}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" + +elif [ "${OPENGLES_SUPPORT}" = yes ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" + PKG_PATCH_DIRS+=" gles" +fi + + +pre_configure_target() { + cd ${PKG_BUILD}/desmume/src/frontend/libretro +} + +if [ "${ARCH}" = "arm" ] +then + make_target() { + make CC=${CC} platform=armv-unix-${TARGET_FLOAT}float-${TARGET_CPU} + } +elif [ "${ARCH}" = "x86_64" ] +then + make_target() { + make CC=${CC} platform=unix + } +else + make_target() { + : + } +fi + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + if [ "${ARCH}" = "aarch64" ] + then + cp -vP ${ROOT}/build.${DISTRO}-${DEVICE}.arm/install_pkg/desmume-*/usr/lib/libretro/desmume_libretro.so ${INSTALL}/usr/lib/libretro/ + else + cp desmume_libretro.so ${INSTALL}/usr/lib/libretro/ + fi +} diff --git a/projects/ArchR/packages/emulators/libretro/desmume-lr/patches/gles/000-enable-gles.patch b/projects/ArchR/packages/emulators/libretro/desmume-lr/patches/gles/000-enable-gles.patch new file mode 100644 index 0000000000..1cef5bf6df --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/desmume-lr/patches/gles/000-enable-gles.patch @@ -0,0 +1,26 @@ +From 89112d650a16787a7b27fd176b976a67bf10f96d Mon Sep 17 00:00:00 2001 +From: SupervisedThinking +Date: Thu, 20 May 2021 15:57:36 +0200 +Subject: [PATCH] Makefile.libretro: disable OpenGL + +--- + desmume/src/frontend/libretro/Makefile.libretro | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +--- a/desmume/src/frontend/libretro/Makefile.libretro ++++ b/desmume/src/frontend/libretro/Makefile.libretro +@@ -75,10 +75,10 @@ ifneq (,$(findstring unix,$(platform))) + CXX = g++-x86 + endif + else +- LIBS := -lpthread -lGL -lpcap +- CXXFLAGS += -DHAVE_OPENGL -std=gnu++11 +- DESMUME_OPENGL = 1 +- DESMUME_OPENGL_CORE = 1 ++ LIBS := -lpthread -lpcap ++ CXXFLAGS += -std=gnu++11 ++ DESMUME_OPENGL = 0 ++ DESMUME_OPENGL_CORE = 0 + endif + + ifneq (,$(findstring clang,$(platform))) diff --git a/projects/ArchR/packages/emulators/libretro/dolphin-lr/package.mk b/projects/ArchR/packages/emulators/libretro/dolphin-lr/package.mk new file mode 100644 index 0000000000..bb805513c7 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/dolphin-lr/package.mk @@ -0,0 +1,65 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="dolphin-lr" +PKG_VERSION="89a4df725d4eb24537728f7d655cddb1add25c18" +PKG_LICENSE="GPLv2" +PKG_DEPENDS_TARGET="toolchain libevdev libdrm ffmpeg zlib libpng lzo libusb" +PKG_SITE="https://github.com/libretro/dolphin" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Dolphin Libretro, a Gamecube & Wii emulator core for Retroarch" +PKG_TOOLCHAIN="cmake" + +if [ ! "${OPENGL}" = "no" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" + PKG_CMAKE_OPTS_TARGET+=" -DENABLE_X11=OFF \ + -DENABLE_EGL=ON" +fi + +if [ "${OPENGLES_SUPPORT}" = yes ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" + PKG_CMAKE_OPTS_TARGET+=" -DENABLE_X11=OFF \ + -DENABLE_EGL=ON" +fi + +if [ "${DISPLAYSERVER}" = "wl" ]; then + PKG_DEPENDS_TARGET+=" wayland ${WINDOWMANAGER} xwayland xrandr libXi" + PKG_CMAKE_OPTS_TARGET+=" -DENABLE_X11=ON \ + -DENABLE_EGL=ON" +fi + +if [ "${VULKAN_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${VULKAN}" + PKG_CMAKE_OPTS_TARGET+=" -DENABLE_VULKAN=ON" +fi + +PKG_CMAKE_OPTS_TARGET+=" -DENABLE_EGL=ON \ + -DUSE_SHARED_ENET=OFF \ + -DUSE_UPNP=ON \ + -DENABLE_NOGUI=ON \ + -DENABLE_QT=OFF \ + -DENABLE_LTO=ON \ + -DENABLE_GENERIC=OFF \ + -DENABLE_HEADLESS=ON \ + -DENABLE_ALSA=ALSA \ + -DENABLE_PULSEAUDIO=ON \ + -DENABLE_LLVM=OFF \ + -DENABLE_TESTS=OFF \ + -DUSE_DISCORD_PRESENCE=OFF \ + -DLIBRETRO=ON \ + -DCMAKE_POLICY_VERSION_MINIMUM=3.5" + +pre_configure_target() { + if [ "${ARCH}" = "aarch64" ]; then + # This is only needed for armv8.2-a targets where we don't use this flag + # as it prohibits the use of LSE-instructions, this is a package bug most likely + export CFLAGS="${CFLAGS} -mno-outline-atomics" + export CXXFLAGS="${CXXFLAGS} -mno-outline-atomics" + fi +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp ${PKG_BUILD}/.${TARGET_NAME}/dolphin_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/dolphin-lr/patches/fix-gcc14.patch b/projects/ArchR/packages/emulators/libretro/dolphin-lr/patches/fix-gcc14.patch new file mode 100644 index 0000000000..8d01e20b15 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/dolphin-lr/patches/fix-gcc14.patch @@ -0,0 +1,27 @@ +From b6c97e3158554f29c1467011e8d50ad2b2350bc1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Piotr=20Pawe=C5=82=20Stefaniak?= + <3462925+pstef@users.noreply.github.com> +Date: Sat, 11 May 2024 19:12:53 +0200 +Subject: [PATCH] Fix build on some systems +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The complaint was: error: ‘reverse’ is not a member of ‘std’ +--- + Source/Core/Core/Debugger/PPCDebugInterface.cpp | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Source/Core/Core/Debugger/PPCDebugInterface.cpp b/Source/Core/Core/Debugger/PPCDebugInterface.cpp +index f44c20d7f28c..1ebd0f8d5b48 100644 +--- a/Source/Core/Core/Debugger/PPCDebugInterface.cpp ++++ b/Source/Core/Core/Debugger/PPCDebugInterface.cpp +@@ -4,6 +4,7 @@ + + #include "Core/Debugger/PPCDebugInterface.h" + ++#include + #include + #include + #include + diff --git a/projects/ArchR/packages/emulators/libretro/dolphin-lr/patches/fmt-10.patch b/projects/ArchR/packages/emulators/libretro/dolphin-lr/patches/fmt-10.patch new file mode 100644 index 0000000000..98419eea65 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/dolphin-lr/patches/fmt-10.patch @@ -0,0 +1,13 @@ +diff --git a/Source/Core/Core/IOS/FS/FileSystemProxy.cpp b/Source/Core/Core/IOS/FS/FileSystemProxy.cpp +index 181a739748..a8d8ba280c 100644 +--- a/Source/Core/Core/IOS/FS/FileSystemProxy.cpp ++++ b/Source/Core/Core/IOS/FS/FileSystemProxy.cpp +@@ -272,7 +272,7 @@ IPCCommandResult FS::Seek(const SeekRequest& request) + + const Result result = + m_ios.GetFS()->SeekFile(handle.fs_fd, request.offset, IOS::HLE::FS::SeekMode(request.mode)); +- LogResult(result, "Seek({}, 0x{:08x}, {})", handle.name.data(), request.offset, request.mode); ++ LogResult(result, "Seek({}, 0x{:08x}, {})", handle.name.data(), request.offset, static_cast(request.mode)); + if (!result) + return GetFSReply(ConvertResult(result.Error())); + return GetFSReply(*result); diff --git a/projects/ArchR/packages/emulators/libretro/dosbox-core-lr/package.mk b/projects/ArchR/packages/emulators/libretro/dosbox-core-lr/package.mk new file mode 100644 index 0000000000..7a02c63124 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/dosbox-core-lr/package.mk @@ -0,0 +1,44 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="dosbox-core-lr" +PKG_VERSION="7bcf083e8309660e2c598d6f7d5982d3851f2178" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/realnc/dosbox-core" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_GIT_CLONE_BRANCH="libretro" +PKG_DEPENDS_TARGET="toolchain SDL2" +PKG_LONGDESC="Upstream port of DOSBox to libretro" +PKG_BUILD_FLAGS="-lto" +PKG_TOOLCHAIN="make" + +make_target() { + #export PKG_CONFIG_DEBUG_SPEW=1 + make -C libretro target=arm64 platform=unix WITH_FAKE_SDL=1 STATIC_LIBCXX=0 \ + WITH_DYNAREC=arm64 WITH_FLUIDSYNTH=0 BUNDLED_AUDIO_CODECS=0 BUNDLED_GLIB=0 \ + BUNDLED_LIBSNDFILE=0 WITH_PINHACK=0 WITH_VOODOO=0 WITH_BASSMIDI=0 +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp ${PKG_BUILD}/libretro/dosbox_core_libretro.so ${INSTALL}/usr/lib/libretro +} diff --git a/projects/ArchR/packages/emulators/libretro/dosbox-core-lr/patches/001-fix-pkgconfig-abuse-issue.patch b/projects/ArchR/packages/emulators/libretro/dosbox-core-lr/patches/001-fix-pkgconfig-abuse-issue.patch new file mode 100644 index 0000000000..5e58080837 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/dosbox-core-lr/patches/001-fix-pkgconfig-abuse-issue.patch @@ -0,0 +1,15 @@ +--- a/libretro/Makefile.common 2025-06-11 13:20:35.626175688 +0000 ++++ b/libretro/Makefile.common 2025-06-11 13:26:33.757777680 +0000 +@@ -20,8 +20,12 @@ + -I$(CORE_DIR)/libretro/src \ + -I$(CORE_DIR)/libretro/src/virtual_keyboard \ + -I$(CORE_DIR)/src \ ++ -I$(CORE_DIR)/libretro/deps_bin/include \ + -I$(LIBRETRO_COMM_DIR)/include + ++LDFLAGS += \ ++ -L$(CORE_DIR)/libretro/deps_bin/lib ++ + # common files + SOURCES_CXX += \ + $(CORE_DIR)/libretro/src/CoreOptionCategory.cpp \ diff --git a/projects/ArchR/packages/emulators/libretro/dosbox-core-lr/patches/002-fix-cmake-build.patch b/projects/ArchR/packages/emulators/libretro/dosbox-core-lr/patches/002-fix-cmake-build.patch new file mode 100644 index 0000000000..ee51233868 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/dosbox-core-lr/patches/002-fix-cmake-build.patch @@ -0,0 +1,8 @@ +--- a/libretro/deps/munt/mt32emu/CMakeLists.txt ++++ b/libretro/deps/munt/mt32emu/CMakeLists.txt +@@ -1,4 +1,4 @@ +-cmake_minimum_required(VERSION 2.8.12) ++cmake_minimum_required(VERSION 3.5) + + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") + diff --git a/projects/ArchR/packages/emulators/libretro/dosbox-pure-lr/package.mk b/projects/ArchR/packages/emulators/libretro/dosbox-pure-lr/package.mk new file mode 100644 index 0000000000..23855364ae --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/dosbox-pure-lr/package.mk @@ -0,0 +1,36 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="dosbox-pure-lr" +PKG_VERSION="b9f8bc681c55301b7430070b1c2057b3744ad480" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/schellingb/dosbox-pure" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="A port of DOSBox to libretro" +GET_HANDLER_SUPPORT="git" +PKG_TOOLCHAIN="make" +PKG_PATCH_DIRS+="${DEVICE}" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + ${STRIP} --strip-debug dosbox_pure_libretro.so + cp dosbox_pure_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/doublecherrygb-lr/package.mk b/projects/ArchR/packages/emulators/libretro/doublecherrygb-lr/package.mk new file mode 100644 index 0000000000..5f474fc1bf --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/doublecherrygb-lr/package.mk @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="doublecherrygb-lr" +PKG_VERSION="f6ffb9ae6230e6614066b887c7b269d44a00cab7" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/TimOelrichs/doublecherryGB-libretro" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="DoubleCherryGB is an open source (GPLv2) GB/GBC emulator." +PKG_TOOLCHAIN="make" + +if [ "${OPENGL_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" +fi + +if [ "${OPENGLES_SUPPORT}" = yes ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" +fi + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp ${PKG_BUILD}/DoubleCherryGB_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/easyrpg-lr/easyrpg.sh b/projects/ArchR/packages/emulators/libretro/easyrpg-lr/easyrpg.sh new file mode 100644 index 0000000000..22e08951a4 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/easyrpg-lr/easyrpg.sh @@ -0,0 +1,67 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2021-present 351ELEC (https://github.com/351ELEC) + +. /etc/profile + +clear > /dev/console + +DEST="/storage/roms/bios/rtp" + +SHASUMS="ddd519b50a22a2a95beeb831d29f7d7d92ae6263f953491163b446b808b66863 rpg2003_rtp_installer.zip#ec82b92da65ca6fdb2d3df25dfbcd7f2bb716e4fe63a079e8e5e396e91fa5e29 rpg2000_rtp_installer.exe" + +install_bios() { + BIOS="$1" + BIOSPATH="$2" + if [ -d "${INSTALLPATH}/${BIOSPATH}" ] + then + rm -rf "${INSTALLPATH}/${BIOSPATH}" + fi + mkdir -p "${INSTALLPATH}/${BIOSPATH}" + cd "${INSTALLPATH}/${BIOSPATH}" + curl -Lo "${BIOS}" "${PKG_URL}/${BIOS}" + BINSUM=$(sha256sum "${BIOS}" | awk '{print $1}') + SHASUM=$(echo $SHASUMS | tr '#' '\n' | awk '/'${BIOS}'/ {print $1}') + if [ ! "${SHASUM}" == "${BINSUM}" ] + then + echo "Checksum mismatch, please update the package." + exit 1 + fi + if [[ "${BIOS}" =~ .zip$ ]] + then + /usr/bin/7z x "${BIOS}" + rm "${BIOS}" + BIOS="$(echo ${BIOS} | sed "s#.zip#.exe#")" + fi + /usr/bin/7z x "${BIOS}" + rm "${BIOS}" + cd ${SOURCEPATH} +} + +INSTALLPATH="/storage/roms/bios" +SOURCEPATH="$(pwd)" +PKG_NAME="rpgmaker" +PKG_VERSION="1.0.0" +PKG_URL="https://dl.degica.com/rpgmakerweb/run-time-packages" + +# Check if the easyrpg runtime files are already available +[ "$(ls -A ${DEST})" ] && JDKINSTALLED="yes" || JDKINSTALLED="no" + +if [ ${JDKINSTALLED} == "no" ]; then + mkdir -p ${DEST} + echo -e "GET http://google.com HTTP/1.0\n\n" | nc google.com 80 > /dev/null 2>&1 + if [ $? -ne 0 ]; then + text_viewer -e -w -t "No Internet!" -m "You need to be connected to the internet to download the easyrpg runtime files."; + exit 1 + fi + echo "Downloading easyrpg runtime files please be patient..." > /dev/console + + install_bios rpg2000_rtp_installer.exe rtp/2000 + install_bios rpg2003_rtp_installer.zip rtp/2003 + + echo "Done! loading core!" > /dev/console +fi + +clear > /dev/console < /dev/null 2>&1 +exit 0 diff --git a/projects/ArchR/packages/emulators/libretro/easyrpg-lr/liblcf/package.mk b/projects/ArchR/packages/emulators/libretro/easyrpg-lr/liblcf/package.mk new file mode 100644 index 0000000000..0d5535ce0c --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/easyrpg-lr/liblcf/package.mk @@ -0,0 +1,34 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) +# +# OpenELEC is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# OpenELEC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC. If not, see . +################################################################################ + +PKG_NAME="liblcf" +PKG_VERSION="92c4450a1bc1acb58bd02bbb99b57e5036919cdf" +PKG_LICENSE="MIT" +PKG_SITE="https://github.com/EasyRPG/liblcf" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain expat icu inih" +PKG_LONGDESC="Library to handle RPG Maker 2000/2003 and EasyRPG projects" +GET_HANDLER_SUPPORT="git" + +PKG_CMAKE_OPTS_TARGET="-DCMAKE_BUILD_TYPE=Release" + +pre_make_target() { + find ${PKG_BUILD} -name flags.make -exec sed -i "s:isystem :I:g" \{} \; + find ${PKG_BUILD} -name build.ninja -exec sed -i "s:isystem :I:g" \{} \; +} diff --git a/projects/ArchR/packages/emulators/libretro/easyrpg-lr/libspeexdsp/package.mk b/projects/ArchR/packages/emulators/libretro/easyrpg-lr/libspeexdsp/package.mk new file mode 100644 index 0000000000..44be0c1e1d --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/easyrpg-lr/libspeexdsp/package.mk @@ -0,0 +1,28 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="libspeexdsp" +PKG_VERSION="738e17905e1ca2a1fa932ddd9c2a85d089f4e845" +PKG_SITE="https://github.com/xiph/speexdsp" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Speex audio processing library" +GET_HANDLER_SUPPORT="git" +PKG_TOOLCHAIN="autotools" diff --git a/projects/ArchR/packages/emulators/libretro/easyrpg-lr/libxmp-lite/package.mk b/projects/ArchR/packages/emulators/libretro/easyrpg-lr/libxmp-lite/package.mk new file mode 100644 index 0000000000..6fcc3b972e --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/easyrpg-lr/libxmp-lite/package.mk @@ -0,0 +1,35 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="libxmp-lite" +PKG_VERSION="4.5.0" +PKG_SITE="http://sourceforge.net/projects/xmp" +PKG_URL="${PKG_SITE}/files/libxmp/${PKG_VERSION}/libxmp-lite-${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Libxmp is a library that renders module files to PCM data." + + +PKG_TOOLCHAIN="configure" + +pre_configure_target() { + cd ${PKG_BUILD} +} + + diff --git a/projects/ArchR/packages/emulators/libretro/easyrpg-lr/libxmp-lite/sources/CMakeLists.txt b/projects/ArchR/packages/emulators/libretro/easyrpg-lr/libxmp-lite/sources/CMakeLists.txt new file mode 100644 index 0000000000..01033a2075 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/easyrpg-lr/libxmp-lite/sources/CMakeLists.txt @@ -0,0 +1,65 @@ +cmake_minimum_required(VERSION 3.7) + +project(xmp-lite VERSION 4.5.0 LANGUAGES C) + +add_library(xmp-lite + include/libxmp-lite/xmp.h + src/virtual.c + src/format.c + src/period.c + src/player.c + src/read_event.c + src/dataio.c + src/lfo.c + src/scan.c + src/control.c + src/filter.c + src/effects.c + src/mixer.c + src/mix_all.c + src/load_helpers.c + src/load.c + src/hio.c + src/smix.c + src/memio.c + src/md5.c + src/misc.c + src/loaders/common.c + src/loaders/itsex.c + src/loaders/sample.c + src/loaders/xm_load.c + src/loaders/mod_load.c + src/loaders/s3m_load.c + src/loaders/it_load.c) + +target_include_directories(xmp-lite PUBLIC + $ + $) + +target_compile_definitions(xmp-lite PRIVATE + LIBXMP_CORE_PLAYER=1 + LIBXMP_NO_DEPACKERS=1) + +# pkg-config +set(PACKAGE_TARNAME ${PROJECT_NAME}) +set(prefix "${CMAKE_INSTALL_PREFIX}") +set(exec_prefix "\${prefix}") +set(libdir "\${exec_prefix}/lib") +set(includedir "\${prefix}/include") +configure_file(lib${PROJECT_NAME}.pc.in libxmp.pc @ONLY) + +# install +install( + TARGETS xmp-lite + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin) + +install( + FILES include/libxmp-lite/xmp.h + DESTINATION include/libxmp-lite) + +install( + FILES ${CMAKE_CURRENT_BINARY_DIR}/libxmp.pc + DESTINATION lib/pkgconfig +) diff --git a/projects/ArchR/packages/emulators/libretro/easyrpg-lr/package.mk b/projects/ArchR/packages/emulators/libretro/easyrpg-lr/package.mk new file mode 100644 index 0000000000..eb68fa7e6f --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/easyrpg-lr/package.mk @@ -0,0 +1,50 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="easyrpg-lr" +PKG_VERSION="31de2a75e2187360bc55b1b43f9524779485fe8a" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/easyrpg/player" +PKG_URL="${PKG_SITE}.git" +PKG_GIT_CLONE_BRANCH="0-8-0-stable" +PKG_DEPENDS_TARGET="toolchain zlib libfmt liblcf icu pixman libspeexdsp mpg123 libsndfile libvorbis opusfile wildmidi libxmp-lite fluidsynth harfbuzz libpng retroarch inih" +PKG_LONGDESC="An unofficial libretro port of the EasyRPG/Player." +GET_HANDLER_SUPPORT="git" +PKG_BUILD_FLAGS="+pic" + + +PKG_CMAKE_OPTS_TARGET="-DPLAYER_TARGET_PLATFORM=libretro \ + -DBUILD_SHARED_LIBS=ON \ + -DCMAKE_BUILD_TYPE=Release" + +pre_make_target() { + find ${PKG_BUILD} -name flags.make -exec sed -i "s:isystem :I:g" \{} \; + find ${PKG_BUILD} -name build.ninja -exec sed -i "s:isystem :I:g" \{} \; +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp ${PKG_BUILD}/.${TARGET_NAME}/easyrpg_libretro.so ${INSTALL}/usr/lib/libretro/ + + mkdir -p ${INSTALL}/usr/bin + cp ${PKG_DIR}/easyrpg.sh ${INSTALL}/usr/bin + chmod 0755 ${INSTALL}/usr/bin/easyrpg.sh +} diff --git a/projects/ArchR/packages/emulators/libretro/easyrpg-lr/wildmidi/package.mk b/projects/ArchR/packages/emulators/libretro/easyrpg-lr/wildmidi/package.mk new file mode 100644 index 0000000000..cf2b3a9d85 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/easyrpg-lr/wildmidi/package.mk @@ -0,0 +1,30 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="wildmidi" +PKG_VERSION="405ca73" +PKG_SITE="https://github.com/Mindwerks/wildmidi" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="WildMIDI is a simple software midi player which has a core softsynth library that can be used with other applications." + +PKG_TOOLCHAIN="cmake" + +PKG_CMAKE_OPTS_TARGET="WANT_PLAYER=OFF -DWANT_ALSA=ON" diff --git a/projects/ArchR/packages/emulators/libretro/easyrpg-lr/wildmidi/sources/CMakeLists.txt b/projects/ArchR/packages/emulators/libretro/easyrpg-lr/wildmidi/sources/CMakeLists.txt new file mode 100644 index 0000000000..86687abca2 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/easyrpg-lr/wildmidi/sources/CMakeLists.txt @@ -0,0 +1,303 @@ +# ########## Project setup ########## +PROJECT(wildmidi C) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) + +# WildMIDI Version +SET(VERSION_MAJOR 0) +SET(VERSION_MINOR 4) +SET(VERSION_RELEASE 3) +SET(WILDMIDI_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_RELEASE}") + +# Lib Versions +SET(SOVERSION 2) +SET(VERSION 2.1.0) + +# Find Macros +SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) + +INCLUDE(CMakeDependentOption) +INCLUDE(CheckCCompilerFlag) +INCLUDE(CheckCSourceCompiles) +INCLUDE(CheckIncludeFile) +INCLUDE(TestBigEndian) + +# Set a default build type if none was specified +IF (NOT DEFINED CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "") + MESSAGE(STATUS "Setting build type to 'Debug' as none was specified.") + SET(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE) + # Set the possible values of build type for cmake-gui + SET_PROPERTY(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") +ENDIF () +SET(CMAKE_CONFIGURATION_TYPES "${CMAKE_BUILD_TYPE}") +MESSAGE(STATUS "Build Type: ${CMAKE_BUILD_TYPE}") + +# Set our options +OPTION(BUILD_SHARED_LIBS "Build a dynamic wildmidi library" ON) +OPTION(WANT_PLAYER "Build WildMIDI player in addition to the libraries" ON) +OPTION(WANT_STATIC "Build static library in addition to dynamic library" OFF) +CMAKE_DEPENDENT_OPTION(WANT_PLAYERSTATIC "Build a statically linked WildMIDI player" ON "WANT_STATIC;WANT_PLAYER" OFF) +OPTION(WANT_ALSA "Include ALSA (Advanced Linux Sound Architecture) support" OFF) +OPTION(WANT_OSS "Include OSS (Open Sound System) support" OFF) +OPTION(WANT_OPENAL "Include OpenAL (Cross Platform) support" OFF) +OPTION(WANT_DEVTEST "Build WildMIDI DevTest file to check files" OFF) +OPTION(WANT_OSX_DEPLOYMENT "OSX Deployment" OFF) +IF (WIN32 AND MSVC) + OPTION(WANT_MP_BUILD "Build with Multiple Processes (/MP)" OFF) +ENDIF () +IF (UNIX AND NOT APPLE AND NOT RISCOS) + SET(WILDMIDI_CFG "/etc/wildmidi/wildmidi.cfg" CACHE STRING "default config location") +ELSE () + SET(WILDMIDI_CFG "wildmidi.cfg" CACHE STRING "default config location") +ENDIF () + +IF ((NOT BUILD_SHARED_LIBS) AND (NOT WANT_STATIC)) + MESSAGE(FATAL_ERROR "Neither dynamic nor static library build is selected.") +ENDIF () + + +# Platform specific defines +IF (UNIX) + # allow 'large' files in 32 bit builds + ADD_DEFINITIONS( + -D_LARGEFILE_SOURCE + -D_FILE_OFFSET_BITS=64 + -D_LARGE_FILES + ) +ENDIF (UNIX) + +# Usage of RPATH for macOS is enabled by default; this just suppresses the CMP0042 warning +# when building libwildmidi_dynamic. +IF (POLICY CMP0042) + CMAKE_POLICY(SET CMP0042 NEW) +ENDIF () + +IF (OPENBSD) # Set RPATH for OpenBSD so WildMIDI can find libWildMidi.so + # use, i.e. don't skip the full RPATH for the build tree + SET(CMAKE_SKIP_BUILD_RPATH FALSE) + + # when building, don't use the install RPATH already + # (but later on when installing) + SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) + + SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") + + # add the automatically determined parts of the RPATH + # which point to directories outside the build tree to the install RPATH + SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) + + # the RPATH to be used when installing, but only if it's not a system directory + LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir) + IF ("${isSystemDir}" STREQUAL "-1") + SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") + ENDIF () +ENDIF (OPENBSD) + +IF (WIN32) + ADD_DEFINITIONS( + -DNOMINMAX + -DWIN32_LEAN_AND_MEAN + -D_CRT_SECURE_NO_WARNINGS + ) +ENDIF (WIN32) + +# Compiler specific settings +IF (CMAKE_COMPILER_IS_GNUCC OR (CMAKE_C_COMPILER_ID MATCHES "Clang")) + ADD_DEFINITIONS( + -Wall -W + -fno-common + ) + + IF (NOT WIN32 AND NOT CYGWIN) + SET(OLD_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + SET(CMAKE_REQUIRED_FLAGS "${OLD_REQUIRED_FLAGS} -Werror") + CHECK_C_SOURCE_COMPILES("int foo(void) __attribute__((visibility(\"default\"))); + int main(void) {return 0;}" HAVE_VISIBILITY_DEFAULT) + IF (HAVE_VISIBILITY_DEFAULT) + CHECK_C_COMPILER_FLAG(-fvisibility=hidden HAVE_VISIBILITY_HIDDEN) + ENDIF () + SET(CMAKE_REQUIRED_FLAGS "${OLD_REQUIRED_FLAGS}") + ENDIF () + + IF (CMAKE_BUILD_TYPE STREQUAL "Debug") + ADD_DEFINITIONS(-ggdb3 -O0) + ELSEIF (CMAKE_BUILD_TYPE STREQUAL "Release") + ADD_DEFINITIONS(-O3) + ENDIF (CMAKE_BUILD_TYPE STREQUAL "Debug") +ENDIF () + +IF (CMAKE_C_COMPILER_ID MATCHES "SunPro") + SET(OLD_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + SET(CMAKE_REQUIRED_FLAGS "${OLD_REQUIRED_FLAGS} -xldscope=hidden") + # __SUNPRO_C >= 0x590 + # CHECK_C_SOURCE_COMPILES("int foo(void) __attribute__((visibility(\"default\"))); + # int main(void) {return 0;}" HAVE_VISIBILITY_DEFAULT) + # __SUNPRO_C >= 0x550 + CHECK_C_SOURCE_COMPILES("__global int foo(void); + int main(void) {return 0;}" HAVE_LDSCOPE_GLOBAL) + IF (HAVE_LDSCOPE_GLOBAL)# OR HAVE_VISIBILITY_DEFAULT + SET(HAVE_LDSCOPE_HIDDEN 1) + ENDIF () + SET(CMAKE_REQUIRED_FLAGS "${OLD_REQUIRED_FLAGS}") +ENDIF () + +CHECK_C_SOURCE_COMPILES("int main(void) {__builtin_expect(0,0); return 0;}" HAVE___BUILTIN_EXPECT) + +CHECK_C_SOURCE_COMPILES("static inline int static_foo() {return 0;} + int main(void) {return 0;}" HAVE_C_INLINE) +CHECK_C_SOURCE_COMPILES("static __inline__ int static_foo() {return 0;} + int main(void) {return 0;}" HAVE_C___INLINE__) +CHECK_C_SOURCE_COMPILES("static __inline int static_foo() {return 0;} + int main(void) {return 0;}" HAVE_C___INLINE) + +# we must not have any unresolved symbols: +if (APPLE) + SET(EXTRA_LDFLAGS "-Wl,-undefined,error") +ELSE() + SET(OLD_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + SET(CMAKE_REQUIRED_FLAGS "${OLD_REQUIRED_FLAGS} -Wl,--no-undefined") + CHECK_C_COMPILER_FLAG("" HAVE_NO_UNDEFINED) + SET(CMAKE_REQUIRED_FLAGS "${OLD_REQUIRED_FLAGS}") + IF (HAVE_NO_UNDEFINED) + SET(EXTRA_LDFLAGS "-Wl,--no-undefined -lm") + ELSE() + SET(EXTRA_LDFLAGS "") + ENDIF() +ENDIF() + +CHECK_INCLUDE_FILE(stdint.h HAVE_STDINT_H) +CHECK_INCLUDE_FILE(inttypes.h HAVE_INTTYPES_H) + +TEST_BIG_ENDIAN(WORDS_BIGENDIAN) + +SET(AUDIODRV_ALSA) +SET(AUDIODRV_OSS) +SET(AUDIODRV_OPENAL) + +# UNIX-like environments +IF (UNIX AND NOT APPLE) + + # Go looking for available sound packages for WildMIDI player + IF (WANT_PLAYER) + FIND_PACKAGE(ALSA) + FIND_PACKAGE(OpenAL) + FIND_PACKAGE(OSS) + + # Set preferred output + IF (WANT_ALSA) + IF (NOT ALSA_FOUND) + MESSAGE(FATAL_ERROR "ALSA required but not found.") + ENDIF () + SET(AUDIODRV_ALSA 1) + SET(AUDIO_LIBRARY ${ALSA_LIBRARY}) + + ELSEIF (WANT_OSS) + IF (NOT OSS_FOUND) + MESSAGE(FATAL_ERROR "OSS required but not found.") + ENDIF () + # no special header paths + SET(AUDIODRV_OSS 1) + SET(AUDIO_LIBRARY ${OSS_LIBRARY}) + + ELSEIF (WANT_OPENAL) + IF (NOT OPENAL_FOUND) + MESSAGE(FATAL_ERROR "OpenAL required but not found.") + ENDIF () + SET(AUDIODRV_OPENAL 1) + SET(AUDIO_LIBRARY ${OPENAL_LIBRARY}) + + ELSE () # Try to auto-detect + + IF (ALSA_FOUND) + SET(AUDIO_LIBRARY ${ALSA_LIBRARY}) + SET(AUDIODRV_ALSA 1) + + ELSEIF (OSS_FOUND) + # no special header paths + SET(AUDIO_LIBRARY ${OSS_LIBRARY}) + SET(AUDIODRV_OSS 1) + + ELSEIF (OPENAL_FOUND) + SET(AUDIO_LIBRARY ${OPENAL_LIBRARY}) + SET(AUDIODRV_OPENAL 1) + + ELSE () + MESSAGE(WARNING "Could not find an audio sub-system!") + SET(AUDIO_LIBRARY "") + ENDIF () + + ENDIF () + ENDIF () + + # find our math lib + FIND_LIBRARY(M_LIBRARY m) + MESSAGE(STATUS "M_LIBRARY: ${M_LIBRARY}") + IF (NOT M_LIBRARY) + SET(M_LIBRARY "") + ENDIF () + + ## Debian and non debian Linux building + IF (DPKG_PROGRAM) + ## Debian specific + ELSE () + ## Non debian specific + ENDIF () +ENDIF (UNIX AND NOT APPLE) + +IF (APPLE AND WANT_PLAYER) + FIND_PACKAGE(OpenAL) + + IF (WANT_OPENAL) + IF (NOT OPENAL_FOUND) + MESSAGE(FATAL_ERROR "OpenAL required but not found.") + ENDIF () + SET(AUDIO_LIBRARY ${OPENAL_LIBRARY}) + + ELSE () + IF (OPENAL_FOUND) + SET(AUDIO_LIBRARY ${OPENAL_LIBRARY}) + SET(AUDIODRV_OPENAL 1) + + ELSE () + MESSAGE(WARNING "Could not find an audio sub-system!") + SET(AUDIO_LIBRARY "") + ENDIF () + + ENDIF () +ENDIF () + +IF (WIN32) + IF (WANT_PLAYER) + LINK_LIBRARIES(winmm) + ENDIF () +ENDIF (WIN32) + +# ######### General setup ########## +INCLUDE_DIRECTORIES(BEFORE "${CMAKE_SOURCE_DIR}/include") +FILE(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/include") +INCLUDE_DIRECTORIES(BEFORE "${CMAKE_BINARY_DIR}/include") +IF (NOT HAVE_STDINT_H) # AND NOT HAVE_INTTYPES_H + INCLUDE_DIRECTORIES(BEFORE "${CMAKE_SOURCE_DIR}/include/stdint") +ENDIF () + +IF (AMIGA OR AROS) + SET(WILDMIDI_AMIGA 1) +ENDIF () + +IF (APPLE) + SET(APP_BUNDLE_NAME "${CMAKE_PROJECT_NAME}.app") + SET(APP_BUNDLE_DIR "${wildmidi_BINARY_DIR}/${APP_BUNDLE_NAME}") + IF (WANT_OSX_DEPLOYMENT) + SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) + ENDIF () +ENDIF (APPLE) + +IF (APPLE) + SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${APP_BUNDLE_DIR}/Contents/MacOS") +ELSE (APPLE) + SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${wildmidi_BINARY_DIR}") +ENDIF (APPLE) + +# Setup up our config file +CONFIGURE_FILE("${CMAKE_SOURCE_DIR}/include/config.h.cmake" "${CMAKE_BINARY_DIR}/include/config.h") + +ADD_SUBDIRECTORY(src) diff --git a/projects/ArchR/packages/emulators/libretro/ecwolf-lr/package.mk b/projects/ArchR/packages/emulators/libretro/ecwolf-lr/package.mk new file mode 100644 index 0000000000..70629e0766 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/ecwolf-lr/package.mk @@ -0,0 +1,36 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="ecwolf-lr" +PKG_VERSION="5ddc1d0000df81a92378da2514da91e06de67922" +PKG_LICENSE="GPLv2" +# TODO revert PKG_SITE once https://github.com/libretro/ecwolf/pull/102 is merged +#PKG_SITE="https://github.com/libretro/ecwolf" +PKG_SITE="https://github.com/porschemad911/ecwolf" +PKG_URL="${PKG_SITE}.git" +# TODO remove PKG_GIT_CLONE_BRANCH once https://github.com/libretro/ecwolf/pull/102 is merged +PKG_GIT_CLONE_BRANCH="sdl-submodule-url" +PKG_DEPENDS_TARGET="toolchain SDL2 SDL2_mixer SDL2_net libjpeg-turbo bzip2" +PKG_LONGDESC="ECWolf is a port of the Wolfenstein 3D engine based of Wolf4SDL." +PKG_TOOLCHAIN="make" + +if [ "${OPENGL_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL}" +elif [ "${OPENGLES_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" +fi + +PKG_MAKE_OPTS_TARGET="-C src/libretro" + +pre_configure_target() { + CXXFLAGS="${CXXFLAGS} -Wno-error=int-conversion" +} + +pre_make_target() { + cd ${PKG_BUILD} +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp src/libretro/ecwolf_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/emuscv-lr/package.mk b/projects/ArchR/packages/emulators/libretro/emuscv-lr/package.mk new file mode 100644 index 0000000000..8fc9b23e0a --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/emuscv-lr/package.mk @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present AmberELEC (https://github.com/AmberELEC) + +PKG_NAME="emuscv-lr" +PKG_VERSION="dfce10df090ce3f5eb23bdbee289702ec1478246" +#PKG_ARCH="aarch64" +PKG_SITE="https://gitlab.com/MaaaX-EmuSCV/libretro-emuscv" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain bin2c:host SDL2" +PKG_LONGDESC="An EPOCH/YENO Super Cassette Vision (1984) home video game emulator for Libretro" +PKG_TOOLCHAIN="make" + +PKG_MAKE_OPTS_TARGET="-C . platform=unix" + +pre_configure_target() { + export TERM=xterm + CXXFLAGS+=" -I$(get_build_dir glibc)/sysdeps/unix/sysv/linux/x86" + sed -i 's~tools/bin2c/~'${TOOLCHAIN}'/usr/bin/~g' Makefile.libretro +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp ${PKG_BUILD}/emuscv_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/emuscv-lr/patches/emuscv_platform.patch b/projects/ArchR/packages/emulators/libretro/emuscv-lr/patches/emuscv_platform.patch new file mode 100644 index 0000000000..96cac8656d --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/emuscv-lr/patches/emuscv_platform.patch @@ -0,0 +1,16 @@ +diff --git a/Makefile.libretro b/Makefile.libretro +index e1df23a..0392c0c 100644 +--- a/Makefile.libretro ++++ b/Makefile.libretro +@@ -70,11 +70,6 @@ ifneq (,$(findstring unix,$(platform))) + ifneq (,$(findstring Haiku,$(shell uname -s))) + LDFLAGS += -lnetwork -lroot + endif +- CC = gcc +- CXX = gcc +- LDFLAGS += -I/usr/include/SDL2 -L/usr/lib/x86_64-linux-gnu -lSDL2 +- CFLAGS += -I/usr/include/SDL2 `sdl2-config --cflags` +- CXXFLAGS += -I/usr/include/SDL2 `sdl2-config --cflags` + + # Raspberry Pi + ifneq (,$(findstring rpi,$(platform))) diff --git a/projects/ArchR/packages/emulators/libretro/fake08-lr/package.mk b/projects/ArchR/packages/emulators/libretro/fake08-lr/package.mk new file mode 100644 index 0000000000..a98e84d746 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/fake08-lr/package.mk @@ -0,0 +1,19 @@ + +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present Lakka (https://www.lakka.tv) + +PKG_NAME="fake08-lr" +PKG_VERSION="0d26fd59103941e5f95e0ee665c6e0fb8c6b6f03" +PKG_LICENSE="MIT" +PKG_SITE="https://github.com/jtothebell/fake-08" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="A Pico-8 player/emulator for console homebrew" +PKG_TOOLCHAIN="make" + +PKG_MAKE_OPTS_TARGET="-C platform/libretro" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp -v platform/libretro/fake08_libretro.{so,info} ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/fbalpha2012-lr/package.mk b/projects/ArchR/packages/emulators/libretro/fbalpha2012-lr/package.mk new file mode 100644 index 0000000000..5dadaeb4c1 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/fbalpha2012-lr/package.mk @@ -0,0 +1,43 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="fbalpha2012-lr" +PKG_VERSION="77167cea72e808384c136c8c163a6b4975ce7a84" +PKG_LICENSE="Non-commercial" +PKG_SITE="https://github.com/libretro/fbalpha2012" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Port of Final Burn Alpha 2012 to Libretro" +PKG_TOOLCHAIN="make" + +pre_configure_target() { +export CFLAGS="${CFLAGS} -Wno-maybe-uninitialized -Wno-unused-function -Wno-error=incompatible-pointer-types" +} + +make_target() { + cd svn-current/trunk + make -f makefile.libretro +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp fbalpha2012_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/fbalpha2019-lr/fbalpha2019_libretro.info b/projects/ArchR/packages/emulators/libretro/fbalpha2019-lr/fbalpha2019_libretro.info new file mode 100644 index 0000000000..5a605e4845 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/fbalpha2019-lr/fbalpha2019_libretro.info @@ -0,0 +1,20 @@ +# Software Information +display_name = "Arcade (FB Alpha 2019)" +authors = "Team FB Alpha" +supported_extensions = "iso|zip|7z" +corename = "FB Alpha 2019" +license = "Non-commercial" +permissions = "" +display_version = "v0.2.97.44" +categories = "Emulator" + +# Hardware Information +manufacturer = "Various" +systemname = "Arcade (various)" +systemid = "fb_alpha" + +# Libretro Features +supports_no_game = "false" +notes = "(!) The BIOS files must be inside the ROM directory." + +description = "Based on a snapshot of the Final Burn Alpha codebase from circa 2019, 'FB Alpha 2019' is compatible with FB Alpha v0.2.97.44 ROM sets. Most users should use up-to-date FBNeo instead and should only fall back to this core if their device is not capable of running that core." diff --git a/projects/ArchR/packages/emulators/libretro/fbalpha2019-lr/package.mk b/projects/ArchR/packages/emulators/libretro/fbalpha2019-lr/package.mk new file mode 100644 index 0000000000..d5297e3217 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/fbalpha2019-lr/package.mk @@ -0,0 +1,39 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="fbalpha2019-lr" +PKG_VERSION="0581797db6fdffd826086b053ced4b6b29bb6678" +PKG_LICENSE="Non-commercial" +PKG_SITE="https://github.com/libretro/fbalpha" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Port of Final Burn Alpha to Libretro (v0.2.97.44)." +PKG_TOOLCHAIN="make" + +make_target() { + make -f makefile.libretro +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp ${PKG_DIR}/fbalpha2019_libretro.info ${INSTALL}/usr/lib/libretro/ + cp fbalpha_libretro.so ${INSTALL}/usr/lib/libretro/fbalpha2019_libretro.so +} diff --git a/projects/ArchR/packages/emulators/libretro/fbneo-lr/package.mk b/projects/ArchR/packages/emulators/libretro/fbneo-lr/package.mk new file mode 100644 index 0000000000..599ba5890e --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/fbneo-lr/package.mk @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2019-present Shanti Gilbert (https://github.com/shantigilbert) +# Maintenance 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="fbneo-lr" +PKG_VERSION="012dbe9dc11fd5fd765ef92e0ad4c08583862f69" +PKG_LICENSE="Non-commercial" +PKG_SITE="https://github.com/libretro/FBNeo" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Port of Final Burn Neo to Libretro (v0.2.97.38)." +PKG_TOOLCHAIN="make" + + +pre_configure_target() { +sed -i "s|LDFLAGS += -static-libgcc -static-libstdc++|LDFLAGS += -static-libgcc|" ./src/burner/libretro/Makefile + +PKG_MAKE_OPTS_TARGET=" -C ./src/burner/libretro USE_CYCLONE=0 profile=performance" + +if [[ "${TARGET_FPU}" =~ "neon" ]]; then + PKG_MAKE_OPTS_TARGET+=" HAVE_NEON=1" +fi + +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp ${PKG_BUILD}/src/burner/libretro/fbneo_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/fceumm-lr/package.mk b/projects/ArchR/packages/emulators/libretro/fceumm-lr/package.mk new file mode 100644 index 0000000000..e0d116753f --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/fceumm-lr/package.mk @@ -0,0 +1,39 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="fceumm-lr" +PKG_VERSION="5cd4a43e16a7f3cd35628d481c347a0a98cfdfa2" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/libretro-fceumm" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Port of FCEUmm / FCEUX to Libretro." + +PKG_TOOLCHAIN="make" + +make_target() { + make -f Makefile.libretro +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp fceumm_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/flycast-lr/config/Flycast.opt b/projects/ArchR/packages/emulators/libretro/flycast-lr/config/Flycast.opt new file mode 100644 index 0000000000..ac207c51ac --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/flycast-lr/config/Flycast.opt @@ -0,0 +1,74 @@ +flycast_allow_service_buttons = "disabled" +flycast_alpha_sorting = "per-strip (fast, least accurate)" +flycast_analog_stick_deadzone = "15%" +flycast_anisotropic_filtering = "off" +flycast_auto_skip_frame = "disabled" +flycast_boot_to_bios = "disabled" +flycast_broadcast = "NTSC" +flycast_cable_type = "TV (Composite)" +flycast_custom_textures = "disabled" +flycast_delay_frame_swapping = "disabled" +flycast_detect_vsync_swap_interval = "disabled" +flycast_digital_triggers = "disabled" +flycast_dump_textures = "disabled" +flycast_emulate_bba = "disabled" +flycast_emulate_framebuffer = "disabled" +flycast_enable_dsp = "disabled" +flycast_enable_purupuru = "enabled" +flycast_enable_rttb = "disabled" +flycast_fog = "enabled" +flycast_force_freeplay = "enabled" +flycast_force_wince = "disabled" +flycast_frame_skipping = "disabled" +flycast_gdrom_fast_loading = "disabled" +flycast_hle_bios = "disabled" +flycast_internal_resolution = "640x480" +flycast_language = "English" +flycast_lightgun1_crosshair = "disabled" +flycast_lightgun2_crosshair = "disabled" +flycast_lightgun3_crosshair = "disabled" +flycast_lightgun4_crosshair = "disabled" +flycast_mipmapping = "enabled" +flycast_native_depth_interpolation = "disabled" +flycast_network_output = "disabled" +flycast_per_content_vmus = "disabled" +flycast_pvr2_filtering = "disabled" +flycast_region = "USA" +flycast_screen_rotation = "horizontal" +flycast_sh4clock = "200" +flycast_show_lightgun_settings = "disabled" +flycast_show_vmu_screen_settings = "disabled" +flycast_texture_filtering = "0" +flycast_texupscale = "1" +flycast_texupscale_max_filtered_texture_size = "256" +flycast_threaded_rendering = "enabled" +flycast_trigger_deadzone = "0%" +flycast_upnp = "enabled" +flycast_vmu1_pixel_off_color = "DEFAULT_OFF 01" +flycast_vmu1_pixel_on_color = "DEFAULT_ON 00" +flycast_vmu1_screen_display = "disabled" +flycast_vmu1_screen_opacity = "100%" +flycast_vmu1_screen_position = "Upper Left" +flycast_vmu1_screen_size_mult = "1x" +flycast_vmu2_pixel_off_color = "DEFAULT_OFF 01" +flycast_vmu2_pixel_on_color = "DEFAULT_ON 00" +flycast_vmu2_screen_display = "disabled" +flycast_vmu2_screen_opacity = "100%" +flycast_vmu2_screen_position = "Upper Left" +flycast_vmu2_screen_size_mult = "1x" +flycast_vmu3_pixel_off_color = "DEFAULT_OFF 01" +flycast_vmu3_pixel_on_color = "DEFAULT_ON 00" +flycast_vmu3_screen_display = "disabled" +flycast_vmu3_screen_opacity = "100%" +flycast_vmu3_screen_position = "Upper Left" +flycast_vmu3_screen_size_mult = "1x" +flycast_vmu4_pixel_off_color = "DEFAULT_OFF 01" +flycast_vmu4_pixel_on_color = "DEFAULT_ON 00" +flycast_vmu4_screen_display = "disabled" +flycast_vmu4_screen_opacity = "100%" +flycast_vmu4_screen_position = "Upper Left" +flycast_vmu4_screen_size_mult = "1x" +flycast_vmu_sound = "disabled" +flycast_volume_modifier_enable = "enabled" +flycast_widescreen_cheats = "disabled" +flycast_widescreen_hack = "disabled" diff --git a/projects/ArchR/packages/emulators/libretro/flycast-lr/package.mk b/projects/ArchR/packages/emulators/libretro/flycast-lr/package.mk new file mode 100644 index 0000000000..9cee9234c7 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/flycast-lr/package.mk @@ -0,0 +1,54 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present AmberELEC (https://github.com/AmberELEC) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="flycast-lr" +PKG_VERSION="c57b2e1aa775c21f6ddcd090607f4b3ba1a1baa1" +PKG_SITE="https://github.com/flyinghead/flycast" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain zlib libzip" +PKG_LONGDESC="Flycast is a multi-platform Sega Dreamcast, Naomi and Atomiswave emulator" +PKG_TOOLCHAIN="cmake" +PKG_PATCH_DIRS+=" ${DEVICE}" +PKG_BUILD_FLAGS="-parallel" + +if [ "${OPENGL_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" + PKG_CMAKE_OPTS_TARGET+=" -DUSE_OPENGL=ON" +else + PKG_CMAKE_OPTS_TARGET+=" -DUSE_OPENGL=OFF" +fi + +if [ "${OPENGLES_SUPPORT}" = yes ] && \ + [ "${PREFER_GLES}" = "yes" ] +then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" + ### Will fail to compile if USE_OPENGL=OFF and USE_GLES=ON as both options are required. + PKG_CMAKE_OPTS_TARGET+=" -DUSE_OPENGL=ON -DUSE_GLES=ON" +else + PKG_CMAKE_OPTS_TARGET+=" -DUSE_GLES=OFF" +fi + +if [ "${VULKAN_SUPPORT}" = "yes" ] +then + PKG_DEPENDS_TARGET+=" ${VULKAN}" + PKG_CMAKE_OPTS_TARGET+=" -DUSE_VULKAN=ON" +else + PKG_CMAKE_OPTS_TARGET+=" -DUSE_VULKAN=OFF" +fi + +pre_configure_target() { + sed -i 's/"reicast"/"flycast"/g' ${PKG_BUILD}/shell/libretro/libretro_core_option_defines.h + sed -i 's/\-O[23]/-Ofast/' ${PKG_BUILD}/CMakeLists.txt + PKG_CMAKE_OPTS_TARGET="${PKG_CMAKE_OPTS_TARGET} \ + -Wno-dev -DLIBRETRO=ON \ + -DWITH_SYSTEM_ZLIB=ON \ + -DUSE_OPENMP=ON" +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp flycast_libretro.so ${INSTALL}/usr/lib/libretro/flycast_libretro.so + mkdir -p ${INSTALL}/usr/config/retroarch + cp -rf ${PKG_DIR}/config/* ${INSTALL}/usr/config/retroarch/ +} diff --git a/projects/ArchR/packages/emulators/libretro/flycast-lr/patches/001-fix-building-with-gcc15.patch b/projects/ArchR/packages/emulators/libretro/flycast-lr/patches/001-fix-building-with-gcc15.patch new file mode 100644 index 0000000000..84157201e5 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/flycast-lr/patches/001-fix-building-with-gcc15.patch @@ -0,0 +1,10 @@ +--- a/core/deps/glslang/SPIRV/SpvBuilder.h ++++ b/core/deps/glslang/SPIRV/SpvBuilder.h +@@ -63,6 +63,7 @@ + #include + #include + #include ++#include + + namespace spv { + diff --git a/projects/ArchR/packages/emulators/libretro/flycast2021-lr/package.mk b/projects/ArchR/packages/emulators/libretro/flycast2021-lr/package.mk new file mode 100644 index 0000000000..0628a5da4e --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/flycast2021-lr/package.mk @@ -0,0 +1,65 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="flycast2021-lr" +PKG_VERSION="603814c9f73b773c455d9a497f389d2f93a257fd" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/metallic77/flycast" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Flycast is a multiplatform Sega Dreamcast emulator " +PKG_TOOLCHAIN="make" +PKG_BUILD_FLAGS="-gold" +PKG_PATCH_DIRS+="${DEVICE}" + +if [ "${OPENGL_SUPPORT}" = "yes" ] && [ ! "${PREFER_GLES}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" + PKG_MAKE_OPTS_TARGET+=" FORCE_GLES=0" +elif [ "${OPENGLES_SUPPORT}" = yes ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" + PKG_MAKE_OPTS_TARGET+=" FORCE_GLES=1" +fi + +if [ "${VULKAN_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${VULKAN}" + PKG_MAKE_OPTS_TARGET+=" HAVE_VULKAN=1" +fi + +pre_configure_target() { + export CXXFLAGS="${CXXFLAGS} -Wno-implicit-function-declaration" + sed -i 's/define CORE_OPTION_NAME "reicast"/define CORE_OPTION_NAME "flycast2021"/g' core/libretro/libretro_core_option_defines.h + sed -i 's/\-O[23]/-Ofast/' ${PKG_BUILD}/Makefile + PKG_MAKE_OPTS_TARGET="${PKG_MAKE_OPTS_TARGET} ARCH=${TARGET_ARCH} HAVE_OPENMP=0 GIT_VERSION=${PKG_VERSION:0:7} HAVE_LTCG=0" +} + +pre_make_target() { + export BUILD_SYSROOT=${SYSROOT_PREFIX} + case ${ARCH} in + aarch64) + PKG_MAKE_OPTS_TARGET+=" platform=${DEVICE}" + ;; + esac +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp flycast_libretro.so ${INSTALL}/usr/lib/libretro/flycast2021_libretro.so +} diff --git a/projects/ArchR/packages/emulators/libretro/flycast2021-lr/patches/01-fix-gcc14.patch b/projects/ArchR/packages/emulators/libretro/flycast2021-lr/patches/01-fix-gcc14.patch new file mode 100644 index 0000000000..6b5bf785ae --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/flycast2021-lr/patches/01-fix-gcc14.patch @@ -0,0 +1,28 @@ +diff --git a/core/deps/libzip/mkstemp.c b/core/deps/libzip/mkstemp.c +index 353f3f7..3776f91 100644 +--- a/core/deps/libzip/mkstemp.c ++++ b/core/deps/libzip/mkstemp.c +@@ -43,9 +43,7 @@ + #include + #include + +-#ifdef __APPLE__ + #include +-#endif + + #ifndef O_BINARY + #define O_BINARY 0 +diff --git a/core/deps/libzip/zip_close.c b/core/deps/libzip/zip_close.c +index 88265a0..89bb26d 100644 +--- a/core/deps/libzip/zip_close.c ++++ b/core/deps/libzip/zip_close.c +@@ -42,9 +42,7 @@ + + #include "zipint.h" + +-#ifdef __APPLE__ + #include +-#endif + + static int add_data(struct zip *, struct zip_source *, struct zip_dirent *, + FILE *); diff --git a/projects/ArchR/packages/emulators/libretro/flycast2021-lr/patches/aarch64/000-platform.patch b/projects/ArchR/packages/emulators/libretro/flycast2021-lr/patches/aarch64/000-platform.patch new file mode 100644 index 0000000000..8c1319c053 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/flycast2021-lr/patches/aarch64/000-platform.patch @@ -0,0 +1,54 @@ +diff --git a/Makefile b/Makefile +index 01d99c3..0b80603 100644 +--- a/Makefile ++++ b/Makefile +@@ -45,12 +45,9 @@ + + MFLAGS := + ASFLAGS := +-LDFLAGS := + LDFLAGS_END := + INCFLAGS := + LIBS := +-CFLAGS := +-CXXFLAGS := + + GIT_VERSION := " $(shell git rev-parse --short HEAD || echo unknown)" + ifneq ($(GIT_VERSION)," unknown") +@@ -403,25 +400,27 @@ else ifeq ($(platform), arm64_cortex_a53_gles2) + + ####################################### + +-# ARM64 SM1 Odroid C4 +-else ifeq ($(platform), odroidc4) ++# ArchR device ++else ifeq ($(platform), @DEVICE@) + EXT ?= so + TARGET := $(TARGET_NAME)_libretro.$(EXT) + SHARED += -shared -Wl,--version-script=link.T +- LDFLAGS += -Wl,--no-undefined + fpic = -fPIC + LIBS += -lrt + ARM_FLOAT_ABI_HARD = 0 +- FORCE_GLES = 1 + SINGLE_PREC_FLAGS = 1 ++ HAVE_OPENMP = 0 +- CPUFLAGS += -DHOST_CPU=0x20000006 -DTARGET_LINUX_ARMv8 -frename-registers +- CFLAGS += -mcpu=cortex-a55 -mtune=cortex-a55 $(CPUFLAGS) +- CXXFLAGS += -mcpu=cortex-a55 -mtune=cortex-a55 $(CPUFLAGS) +- ASFLAGS += $(CFLAGS) -c -frename-registers -fno-strict-aliasing -ffast-math -ftree-vectorize ++ CFLAGS += -Ofast \ ++ -fuse-linker-plugin \ ++ -fno-stack-protector -fno-ident -fomit-frame-pointer \ ++ -fmerge-all-constants -ffast-math -funroll-all-loops \ ++ -mno-outline-atomics -DTARGET_LINUX_ARMv8 -DNOSSE -D__NEON_OPT ++ CXXFLAGS += $(CFLAGS) ++ LDFLAGS += -Ofast -flto -fuse-linker-plugin + PLATFORM_EXT := unix ++ CORE_DEFINES += -DLOW_END -DLOW_RES + WITH_DYNAREC=arm64 + HAVE_GENERIC_JIT = 0 +- HAVE_VULKAN = 0 + HAVE_LTCG = 0 + + ####################################### diff --git a/projects/ArchR/packages/emulators/libretro/fmsx-lr/package.mk b/projects/ArchR/packages/emulators/libretro/fmsx-lr/package.mk new file mode 100644 index 0000000000..521c8aec09 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/fmsx-lr/package.mk @@ -0,0 +1,39 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="fmsx-lr" +PKG_VERSION="fbe4dfc4c3e3f7eb27089def3d663a905b181845" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/fmsx-libretro" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Port of fMSX 4.9 to the libretro API." + +PKG_TOOLCHAIN="make" + +make_target() { + make +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp fmsx_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/freechaf-lr/package.mk b/projects/ArchR/packages/emulators/libretro/freechaf-lr/package.mk new file mode 100644 index 0000000000..6e06639fb3 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/freechaf-lr/package.mk @@ -0,0 +1,18 @@ +PKG_NAME="freechaf-lr" +PKG_VERSION="cdb8ad6fcecb276761b193650f5ce9ae8b878067" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/FreeChaF" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="FreeChaF is a libretro emulation core for the Fairchild ChannelF / Video Entertainment System designed to be compatible with joypads from the SNES era forward." +PKG_TOOLCHAIN="make" +GET_HANDLER_SUPPORT="git" + +make_target() { + make +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp freechaf_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/freeintv-lr/package.mk b/projects/ArchR/packages/emulators/libretro/freeintv-lr/package.mk new file mode 100644 index 0000000000..f6a49931df --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/freeintv-lr/package.mk @@ -0,0 +1,35 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="freeintv-lr" +PKG_VERSION="1b51f41238ef9691d9fe16722f7d093bb6a6e379" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/libretro/FreeIntv" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="FreeIntv is a libretro emulation core for the Mattel Intellivision." + +PKG_TOOLCHAIN="make" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp freeintv_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/freej2me-lr/freej2me.sh b/projects/ArchR/packages/emulators/libretro/freej2me-lr/freej2me.sh new file mode 100644 index 0000000000..66d9115f3e --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/freej2me-lr/freej2me.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2021-present Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2021-present 351ELEC (https://github.com/351ELEC) + +. /etc/profile + +clear > /dev/console + +if [ ! -f "/storage/roms/bios/freej2me-lr.jar" ]; then + cp /usr/config/game/freej2me/freej2me-lr.jar /storage/roms/bios +fi + +JDKDEST="/storage/jdk" +JDKNAME="zulu11.48.21-ca-jdk11.0.11" + +mkdir -p ${JDKDEST} + +# Check if the jdk does not already exists +[ "$(ls -A ${JDKDEST})" ] && JDKINSTALLED="yes" || JDKINSTALLED="no" + +if [ ${JDKINSTALLED} == "no" ]; then + echo -e "GET http://google.com HTTP/1.0\n\n" | nc google.com 80 > /dev/null 2>&1 + if [ $? -ne 0 ]; then + text_viewer -e -w -t "No Internet!" -m "You need to be connected to the internet to download the JDK."; + exit 1 + fi + echo "Downloading JDK please be patient..." > /dev/console + cd ${JDKDEST}/.. + wget "https://cdn.azul.com/zulu-embedded/bin/${JDKNAME}-linux_aarch64.tar.gz" > /dev/console 2>&1 + echo "Inflating JDK please be patient..." > /dev/console + tar xvfz ${JDKNAME}-linux_aarch64.tar.gz ${JDKNAME}-linux_aarch64/lib > /dev/console 2>&1 + tar xvfz ${JDKNAME}-linux_aarch64.tar.gz ${JDKNAME}-linux_aarch64/bin > /dev/console 2>&1 + tar xvfz ${JDKNAME}-linux_aarch64.tar.gz ${JDKNAME}-linux_aarch64/conf > /dev/console 2>&1 + rm ${JDKNAME}-linux_aarch64/lib/*.zip + mv ${JDKNAME}-linux_aarch64/* jdk + rm -rf ${JDKNAME}-linux_aarch64* + + for del in jmods include demo legal man DISCLAIMER LICENSE readme.txt release Welcome.html; do + rm -rf ${JDKDEST}/${del} + done + echo "JDK done! loading core!" > /dev/console + cp -rf /usr/config/game/freej2me/freej2me-lr.jar /storage/roms/bios +fi + +clear > /dev/console < /dev/null 2>&1 +exit 0 diff --git a/projects/ArchR/packages/emulators/libretro/freej2me-lr/package.mk b/projects/ArchR/packages/emulators/libretro/freej2me-lr/package.mk new file mode 100644 index 0000000000..c5ea9ac973 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/freej2me-lr/package.mk @@ -0,0 +1,36 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2021-present 351ELEC (https://github.com/351ELEC) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="freej2me-lr" +PKG_VERSION="1.52" +PKG_SITE="https://github.com/TASEmulators/freej2me-plus" +PKG_URL="${PKG_SITE}/archive/refs/tags/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain apache-ant:host libXtst" +PKG_LONGDESC="J2ME emulator with libretro and AWT frontends, it aims to run on basically anything that can run a Java VM." +PKG_TOOLCHAIN="make" + +post_unpack() { + # Java 25 no longer supports source/target 1.6, upgrade to 1.8 + sed -i 's/value="1\.6"/value="1.8"/g' ${PKG_BUILD}/build.xml +} + +pre_configure_target() { + ${TOOLCHAIN}/bin/ant +} + +make_target() { + make -C ${PKG_BUILD}/src/libretro +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp ${PKG_BUILD}/src/libretro/freej2me_libretro.so ${INSTALL}/usr/lib/libretro/ + + mkdir -p ${INSTALL}/usr/config/game/freej2me + cp ${PKG_BUILD}/build/freej2me-lr.jar ${INSTALL}/usr/config/game/freej2me + + mkdir -p ${INSTALL}/usr/bin + cp ${PKG_DIR}/freej2me.sh ${INSTALL}/usr/bin + chmod 0755 ${INSTALL}/usr/bin/freej2me.sh +} diff --git a/projects/ArchR/packages/emulators/libretro/fuse-lr/package.mk b/projects/ArchR/packages/emulators/libretro/fuse-lr/package.mk new file mode 100644 index 0000000000..31558f9364 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/fuse-lr/package.mk @@ -0,0 +1,39 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="fuse-lr" +PKG_VERSION="cad85b7b1b864c65734f71aa4a510b6f6536881c" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/libretro/fuse-libretro" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="A port of the Fuse Unix Spectrum Emulator to libretro " + +PKG_TOOLCHAIN="make" + +make_target() { + make -f Makefile.libretro +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp fuse_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/gambatte-lr/package.mk b/projects/ArchR/packages/emulators/libretro/gambatte-lr/package.mk new file mode 100644 index 0000000000..53e73457cf --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/gambatte-lr/package.mk @@ -0,0 +1,40 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="gambatte-lr" +PKG_VERSION="6924c76ba03dadddc6e97fa3660f3d3bc08faa94" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/gambatte-libretro" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="libretro implementation of libgambatte" + +PKG_TOOLCHAIN="make" +PKG_PATCH_DIRS+="${DEVICE}" + +make_target() { + make -f Makefile.libretro +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp gambatte_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/gearboy-lr/package.mk b/projects/ArchR/packages/emulators/libretro/gearboy-lr/package.mk new file mode 100644 index 0000000000..4fa55188bf --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/gearboy-lr/package.mk @@ -0,0 +1,34 @@ +################################################################################ +# +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +################################################################################ + +PKG_NAME="gearboy-lr" +PKG_VERSION="37c21f776a54a7bfac2b2135b1b776d2e31fa93d" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/drhelius/Gearboy" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Game Boy / Gameboy Color emulator for iOS, Mac, Raspberry Pi, Windows and Linux" + +PKG_TOOLCHAIN="make" + +make_target() { + make -C platforms/libretro/ +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp platforms/libretro/gearboy_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/gearcoleco-lr/package.mk b/projects/ArchR/packages/emulators/libretro/gearcoleco-lr/package.mk new file mode 100644 index 0000000000..0602ffde12 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/gearcoleco-lr/package.mk @@ -0,0 +1,34 @@ +################################################################################ +# +# Copyright (C) 2021 351ELEC team (https://github.com/351ELEC/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +################################################################################ + +PKG_NAME="gearcoleco-lr" +PKG_VERSION="f3e3e1812a3421bf24fca26ff257fb36842d33a9" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/drhelius/Gearcoleco" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Gearcoleco is a very accurate cross-platform ColecoVision emulator written in C++ that runs on Windows, macOS, Linux, BSD, Raspberry Pi and RetroArch." + +PKG_TOOLCHAIN="make" + +make_target() { + make -C platforms/libretro/ +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp platforms/libretro/gearcoleco_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/gearsystem-lr/package.mk b/projects/ArchR/packages/emulators/libretro/gearsystem-lr/package.mk new file mode 100644 index 0000000000..4cac87ecae --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/gearsystem-lr/package.mk @@ -0,0 +1,40 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="gearsystem-lr" +PKG_VERSION="af2652e4082ef23f6826b5acf8338900d08cab2a" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/drhelius/Gearsystem" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Gearsystem is a Sega Master System / Game Gear / SG-1000 emulator written in C++" +PKG_TOOLCHAIN="make" +GET_HANDLER_SUPPORT="git" + +make_target() { + make -C platforms/libretro/ +} + + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp platforms/libretro/gearsystem_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/genesis-plus-gx-lr/package.mk b/projects/ArchR/packages/emulators/libretro/genesis-plus-gx-lr/package.mk new file mode 100644 index 0000000000..9eb30154ee --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/genesis-plus-gx-lr/package.mk @@ -0,0 +1,43 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="genesis-plus-gx-lr" +PKG_VERSION="e48a37173350b5aec2a6431add7c1a625d1f28bf" +PKG_LICENSE="Non-commercial" +PKG_SITE="https://github.com/libretro/Genesis-Plus-GX" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="An enhanced port of Genesis Plus for Gamecube/Wii" + +PKG_TOOLCHAIN="make" + +make_target() { + if [ "${ARCH}" == "arm" ]; then + CFLAGS="${CFLAGS} -DALIGN_LONG" + fi + make -f Makefile.libretro +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp genesis_plus_gx_libretro.so ${INSTALL}/usr/lib/libretro/genesis_plus_gx_libretro.so +} diff --git a/projects/ArchR/packages/emulators/libretro/genesis-plus-gx-wide-lr/package.mk b/projects/ArchR/packages/emulators/libretro/genesis-plus-gx-wide-lr/package.mk new file mode 100644 index 0000000000..3f059024d8 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/genesis-plus-gx-wide-lr/package.mk @@ -0,0 +1,42 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="genesis-plus-gx-wide-lr" +PKG_VERSION="b7d314220d755537aebb7bc1750ac21f764365c4" +PKG_LICENSE="Non-commercial" +PKG_SITE="https://github.com/libretro/Genesis-Plus-GX-Wide" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="An enhanced port of Genesis Plus for Gamecube/Wii" + +PKG_TOOLCHAIN="make" + +make_target() { + if [ "${ARCH}" == "arm" ]; then + CFLAGS="${CFLAGS} -DALIGN_LONG" + fi + make -f Makefile.libretro +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp genesis_plus_gx_wide_libretro.so ${INSTALL}/usr/lib/libretro/genesis_plus_gx_wide_libretro.so +} diff --git a/projects/ArchR/packages/emulators/libretro/geolith-lr/package.mk b/projects/ArchR/packages/emulators/libretro/geolith-lr/package.mk new file mode 100644 index 0000000000..785ee6e8e3 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/geolith-lr/package.mk @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="geolith-lr" +PKG_VERSION="1391cef3d373cd2aaf4f8a0478b9d6f831c7dfac" +PKG_ARCH="aarch64" +PKG_LICENSE="BSD" +PKG_SITE="https://github.com/libretro/geolith-libretro" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Geolith is a highly accurate emulator for the Neo Geo AES and MVS." +PKG_TOOLCHAIN="make" + +make_target() { +cd libretro + make -f ./Makefile platform=${DEVICE} +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp geolith_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/geolith-lr/patches/000-platform.patch b/projects/ArchR/packages/emulators/libretro/geolith-lr/patches/000-platform.patch new file mode 100644 index 0000000000..367b6d29c4 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/geolith-lr/patches/000-platform.patch @@ -0,0 +1,19 @@ +diff -rupN geolith-libretro.orig/libretro/Makefile geolith-libretro/libretro/Makefile +--- geolith-libretro.orig/libretro/Makefile 2024-04-18 21:11:00.166799951 +0000 ++++ geolith-libretro/libretro/Makefile 2024-04-18 22:08:26.503486311 +0000 +@@ -375,6 +375,15 @@ else ifeq ($(platform), rpi4) + FLAGS += -mcpu=cortex-a72 -mtune=cortex-a72 + FLAGS += -fomit-frame-pointer -ffast-math + ++# @DEVICE@ ++else ifeq ($(platform), @DEVICE@) ++ TARGET := $(TARGET_NAME)_libretro.so ++ fpic := -fPIC ++ SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T ++ CFLAGS += -fsigned-char ++ FLAGS += -DARM ++ FLAGS += -fomit-frame-pointer -ffast-math ++ + else ifeq ($(platform), emscripten) + TARGET := $(TARGET_NAME)_libretro_$(platform).bc + STATIC_LINKING = 1 diff --git a/projects/ArchR/packages/emulators/libretro/glsl-shaders/package.mk b/projects/ArchR/packages/emulators/libretro/glsl-shaders/package.mk new file mode 100644 index 0000000000..34c225851e --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/glsl-shaders/package.mk @@ -0,0 +1,41 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="glsl-shaders" +PKG_VERSION="7e1617b722f85466ad7dd4ddb4ac241fd02dc8d0" +PKG_ARCH="aarch64" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/libretro/glsl-shaders" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Common GSLS shaders for RetroArch" + +PKG_TOOLCHAIN="make" + +configure_target() { + cd ${PKG_BUILD} +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/share/glsl-shaders + make install INSTALLDIR="${INSTALL}/usr/share/glsl-shaders" +} diff --git a/projects/ArchR/packages/emulators/libretro/gpsp-lr/package.mk b/projects/ArchR/packages/emulators/libretro/gpsp-lr/package.mk new file mode 100644 index 0000000000..548c34a081 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/gpsp-lr/package.mk @@ -0,0 +1,53 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="gpsp-lr" +PKG_VERSION="b0d5d27ae51c23f514974ddffa5760f1e1d05d9b" +PKG_ARCH="arm aarch64" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/gpsp" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="gameplaySP is a Gameboy Advance emulator for Playstation Portable" +PKG_PATCH_DIRS+="${DEVICE}" +PKG_TOOLCHAIN="make" + +if [ "${ARCH}" = "arm" ] +then + make_target() { + make CC=${CC} platform=${DEVICE} + } +else + make_target() { + : + } +fi + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + if [ "${ARCH}" = "aarch64" ] + then + cp -vP ${ROOT}/build.${DISTRO}-${DEVICE}.arm/install_pkg/gpsp-*/usr/lib/libretro/gpsp_libretro.so ${INSTALL}/usr/lib/libretro/ + else + cp ${PKG_BUILD}/gpsp_libretro.so ${INSTALL}/usr/lib/libretro/ + fi +} diff --git a/projects/ArchR/packages/emulators/libretro/gpsp-lr/patches/000-platform.patch b/projects/ArchR/packages/emulators/libretro/gpsp-lr/patches/000-platform.patch new file mode 100644 index 0000000000..47e5d2cd35 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/gpsp-lr/patches/000-platform.patch @@ -0,0 +1,29 @@ +diff --git a/Makefile b/Makefile +index c52b50b..5e7f2ec 100644 +--- a/Makefile ++++ b/Makefile +@@ -67,7 +67,6 @@ + endif + LIBM := -lm + CORE_DIR := . +-LDFLAGS := + + # Unix + ifeq ($(platform), unix) +@@ -289,6 +288,16 @@ else ifeq ($(platform), rpi1) + MMAP_JIT_CACHE = 1 + HAVE_DYNAREC = 1 + ++# @DEVICE@ ++else ifeq ($(platform), @DEVICE@) ++ CFLAGS += -marm -flto -fpic -ffast-math -fno-rtti -fno-exceptions ++ TARGET := $(TARGET_NAME)_libretro.so ++ fpic := -fPIC ++ SHARED := -shared -Wl,--version-script=link.T -Wl,--no-undefined ++ CPU_ARCH := arm ++ MMAP_JIT_CACHE = 1 ++ HAVE_DYNAREC = 1 ++ + # Classic Platforms #################### + # Platform affix = classic__<µARCH> + # Help at https://modmyclassic.com/comp diff --git a/projects/ArchR/packages/emulators/libretro/gw-lr/package.mk b/projects/ArchR/packages/emulators/libretro/gw-lr/package.mk new file mode 100644 index 0000000000..52171ad51c --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/gw-lr/package.mk @@ -0,0 +1,39 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="gw-lr" +PKG_VERSION="435e5cfd4bf6aea03a84259e9b8dba3daf3ff5bd" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/libretro/gw-libretro" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="A libretro core for Game & Watch simulators " + +PKG_TOOLCHAIN="make" + +make_target() { + make -f Makefile.libretro +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp gw_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/handy-lr/package.mk b/projects/ArchR/packages/emulators/libretro/handy-lr/package.mk new file mode 100644 index 0000000000..cd2095e23e --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/handy-lr/package.mk @@ -0,0 +1,43 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="handy-lr" +PKG_VERSION="fca239207e9c111da3e85d2faf0b1b9d7524e498" +PKG_LICENSE="Zlib" +PKG_SITE="https://github.com/libretro/libretro-handy" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="K. Wilkins' Atari Lynx emulator Handy for libretro" +PKG_TOOLCHAIN="make" + +case ${ARCH} in + aarch64) + PKG_MAKE_OPTS_TARGET=" platform=emuelec" + ;; + arm) + PKG_MAKE_OPTS_TARGET=" platform=classic_armv8_a35" + ;; +esac + + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp handy_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/handy-lr/patches/aarch64/handy-01-add-emuelec.patch b/projects/ArchR/packages/emulators/libretro/handy-lr/patches/aarch64/handy-01-add-emuelec.patch new file mode 100644 index 0000000000..e1975cbc69 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/handy-lr/patches/aarch64/handy-01-add-emuelec.patch @@ -0,0 +1,24 @@ +--- a/Makefile ++++ b/Makefile +@@ -245,7 +245,7 @@ + + # (armv8 a35, hard point, neon based) ### + # Playstation Classic +-else ifeq ($(platform), classic_armv8_a35) ++else ifeq ($(platform), emuelec) + TARGET := $(TARGET_NAME)_libretro.so + fpic := -fPIC + SHARED := -shared -Wl,-version-script=$(LIBRETRO_DIR)/link.T -Wl,-no-undefined +@@ -256,10 +256,9 @@ + -fno-stack-protector -fno-ident -fomit-frame-pointer \ + -falign-functions=1 -falign-jumps=1 -falign-loops=1 \ + -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-unroll-loops \ +- -fmerge-all-constants -fno-math-errno \ +- -marm -mtune=cortex-a35 -mfpu=neon-fp-armv8 -mfloat-abi=hard ++ -fmerge-all-constants -fno-math-errno + HAVE_NEON = 1 +- ARCH = arm ++ ARCH = aarch64 + ifeq ($(shell echo `$(CC) -dumpversion` "< 4.9" | bc -l), 1) + CFLAGS += -march=armv8-a + else diff --git a/projects/ArchR/packages/emulators/libretro/hatari-lr/config/conf/Atari-ST-default.cfg b/projects/ArchR/packages/emulators/libretro/hatari-lr/config/conf/Atari-ST-default.cfg new file mode 100644 index 0000000000..f242a8e4aa --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/hatari-lr/config/conf/Atari-ST-default.cfg @@ -0,0 +1,252 @@ +[Log] +sLogFileName = stderr +sTraceFileName = stderr +nTextLogLevel = 3 +nAlertDlgLogLevel = 1 +bConfirmQuit = FALSE +bNatFeats = FALSE +bConsoleWindow = FALSE + +[Debugger] +nNumberBase = 10 +nSymbolLines = -1 +nMemdumpLines = -1 +nDisasmLines = -1 +nExceptionDebugMask = 515 +nDisasmOptions = 15 +bDisasmUAE = FALSE +bSymbolsResident = FALSE +bMatchAllSymbols = FALSE + +[Screen] +nMonitorType = 1 +nFrameSkips = 5 +bFullScreen = TRUE +bKeepResolution = TRUE +bResizable = TRUE +bAllowOverscan = TRUE +nSpec512Threshold = 1 +nForceBpp = 0 +bAspectCorrect = TRUE +bUseExtVdiResolutions = FALSE +nVdiWidth = 640 +nVdiHeight = 480 +nVdiColors = 2 +bMouseWarp = TRUE +bShowStatusbar = FALSE +bShowDriveLed = FALSE +bCrop = FALSE +bForceMax = FALSE +nMaxWidth = 832 +nMaxHeight = 588 +bUseSdlRenderer = TRUE +nRenderScaleQuality = 0 +bUseVsync = TRUE + +[Joystick0] +nJoystickMode = 0 +bEnableAutoFire = FALSE +bEnableJumpOnFire2 = FALSE +nJoyId = 0 +kUp = Up +kDown = Down +kLeft = Left +kRight = Right +kFire = Right Ctrl + +[Joystick1] +nJoystickMode = 1 +bEnableAutoFire = FALSE +bEnableJumpOnFire2 = FALSE +nJoyId = 0 +kUp = Up +kDown = Down +kLeft = Left +kRight = Right +kFire = Right Ctrl + +[Joystick2] +nJoystickMode = 0 +bEnableAutoFire = FALSE +bEnableJumpOnFire2 = FALSE +nJoyId = 0 +kUp = Up +kDown = Down +kLeft = Left +kRight = Right +kFire = Right Ctrl + +[Joystick3] +nJoystickMode = 0 +bEnableAutoFire = FALSE +bEnableJumpOnFire2 = FALSE +nJoyId = 0 +kUp = Up +kDown = Down +kLeft = Left +kRight = Right +kFire = Right Ctrl + +[Joystick4] +nJoystickMode = 0 +bEnableAutoFire = FALSE +bEnableJumpOnFire2 = FALSE +nJoyId = 0 +kUp = Up +kDown = Down +kLeft = Left +kRight = Right +kFire = Right Ctrl + +[Joystick5] +nJoystickMode = 0 +bEnableAutoFire = FALSE +bEnableJumpOnFire2 = FALSE +nJoyId = 0 +kUp = Up +kDown = Down +kLeft = Left +kRight = Right +kFire = Right Ctrl + +[Keyboard] +bDisableKeyRepeat = FALSE +nKeymapType = 0 +szMappingFileName = + +[KeyShortcutsWithMod] +kOptions = O +kFullScreen = F +kBorders = B +kMouseMode = M +kColdReset = C +kWarmReset = R +kScreenShot = G +kBossKey = I +kCursorEmu = J +kFastForward = X +kRecAnim = A +kRecSound = Y +kSound = S +kPause = +kDebugger = Pause +kQuit = Q +kLoadMem = L +kSaveMem = K +kInsertDiskA = D +kSwitchJoy0 = F1 +kSwitchJoy1 = F2 +kSwitchPadA = F3 +kSwitchPadB = F4 + +[KeyShortcutsWithoutMod] +kOptions = F12 +kFullScreen = F11 +kBorders = +kMouseMode = +kColdReset = +kWarmReset = +kScreenShot = +kBossKey = +kCursorEmu = +kFastForward = +kRecAnim = +kRecSound = +kSound = +kPause = Pause +kDebugger = +kQuit = +kLoadMem = +kSaveMem = +kInsertDiskA = +kSwitchJoy0 = +kSwitchJoy1 = +kSwitchPadA = +kSwitchPadB = + +[Sound] +bEnableMicrophone = TRUE +bEnableSound = TRUE +bEnableSoundSync = FALSE +nPlaybackFreq = 44100 +nSdlAudioBufferSize = 0 +szYMCaptureFileName = /storage/.hatari/hatari.wav +YmVolumeMixing = 2 + +[Memory] +nMemorySize = 1024 +nTTRamSize = 0 +bAutoSave = FALSE +szMemoryCaptureFileName = /storage/.config/hatari/hatari.sav +szAutoSaveFileName = /storage/.config/hatari/auto.sav + +[HardDisk] +nGemdosDrive = 0 +bBootFromHardDisk = FALSE +bUseHardDiskDirectory = FALSE +szHardDiskDirectory = /storage/.hatari +nGemdosCase = 0 +nWriteProtection = 0 +bFilenameConversion = FALSE +bGemdosHostTime = FALSE +bUseHardDiskImage = FALSE +szHardDiskImage = /storage/.hatari +bUseIdeMasterHardDiskImage = FALSE +bUseIdeSlaveHardDiskImage = FALSE +szIdeMasterHardDiskImage = /storage/.hatari +szIdeSlaveHardDiskImage = /storage/.hatari + +[ROM] +szTosImageFileName = /storage/roms/bios/tos.img +bPatchTos = TRUE +szCartridgeImageFileName = + +[RS232] +bEnableRS232 = FALSE +szOutFileName = /dev/modem +szInFileName = /dev/modem + +[Printer] +bEnablePrinting = FALSE +szPrintToFileName = /storage/.config/hatari/hatari.prn + +[Midi] +bEnableMidi = FALSE +sMidiInFileName = /dev/snd/midiC1D0 +sMidiOutFileName = /dev/snd/midiC1D0 +sMidiInPortName = Off +sMidiOutPortName = Off + +[System] +nCpuLevel = 0 +nCpuFreq = 8 +bCompatibleCpu = TRUE +nModelType = 0 +bBlitter = FALSE +nDSPType = 0 +bPatchTimerD = FALSE +bFastBoot = FALSE +bFastForward = FALSE +bAddressSpace24 = TRUE +bCycleExactCpu = TRUE +n_FPUType = 0 +bSoftFloatFPU = FALSE +bMMU = FALSE +VideoTiming = 3 + +[Video] +AviRecordVcodec = 2 +AviRecordFps = 0 +AviRecordFile = /storage/.hatari/hatari.avi + +[Floppy] +bAutoInsertDiskB = TRUE +FastFloppy = TRUE +EnableDriveA = TRUE +DriveA_NumberOfHeads = 2 +EnableDriveB = TRUE +DriveB_NumberOfHeads = 2 +nWriteProtection = 0 +szDiskImageDirectory = /storage/roms/atarist +szDiskAZipPath = +szDiskBZipPath = diff --git a/projects/ArchR/packages/emulators/libretro/hatari-lr/config/hatari.nvram b/projects/ArchR/packages/emulators/libretro/hatari-lr/config/hatari.nvram new file mode 100644 index 0000000000..e69de29bb2 diff --git a/projects/ArchR/packages/emulators/libretro/hatari-lr/package.mk b/projects/ArchR/packages/emulators/libretro/hatari-lr/package.mk new file mode 100644 index 0000000000..6b0e1dc9ad --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/hatari-lr/package.mk @@ -0,0 +1,46 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="hatari-lr" +PKG_VERSION="7008194d3f951a157997f67a820578f56f7feee0" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/hatari" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain capsimg" +PKG_LONGDESC="New rebasing of Hatari based on Mercurial upstream. Tries to be a shallow fork for easy upstreaming later on." + +PKG_TOOLCHAIN="make" +PKG_USE_CMAKE="no" + +configure_target() { + : +} + +make_target() { + make -C .. -f Makefile.libretro +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + mkdir -p ${INSTALL}/usr/config/game/configs/hatari + cp ../hatari_libretro.so ${INSTALL}/usr/lib/libretro/ + cp -rf ${PKG_DIR}/config/* ${INSTALL}/usr/config/game/configs/hatari/ +} diff --git a/projects/ArchR/packages/emulators/libretro/idtech-lr/package.mk b/projects/ArchR/packages/emulators/libretro/idtech-lr/package.mk new file mode 100644 index 0000000000..53c765b5cb --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/idtech-lr/package.mk @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="idtech-lr" +PKG_LICENSE="Apache-2.0" +PKG_SITE="https://arch-r.io" +PKG_LONGDESC="Package for all iD Software game engines." +PKG_TOOLCHAIN="manual" +PKG_DOOM_SHAREWARE="https://github.com/archr-linux/packages/raw/main/doom.tar.gz" + +if [ "${OPENGLES_SUPPORT}" = yes ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" + PKG_DEPENDS_TARGET+=" ecwolf-lr prboom-lr tyrquake-lr vitaquake2-lr" +fi + +if [ "${TARGET_ARCH}" = "x86_64" ]; then + PKG_DEPENDS_TARGET+=" vitaquake3-lr boom3-lr" +fi + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/config/idtech + mkdir -p ${INSTALL}/usr/bin + cp -rf ${PKG_DIR}/scripts/* ${INSTALL}/usr/bin + chmod +x ${INSTALL}/usr/bin/* + + mkdir -p ${INSTALL}/usr/share/idtech + cp -rf ${PKG_DIR}/sources/* ${INSTALL}/usr/share/idtech/ + curl -Lo ${INSTALL}/usr/share/idtech/doom.tar.gz ${PKG_DOOM_SHAREWARE} +} + +post_install() { + case ${TARGET_ARCH} in + aarch64) + sed -i '/doom3/d' ${INSTALL}/usr/share/idtech/idtech_dirs + sed -i '/quake3/d' ${INSTALL}/usr/share/idtech/idtech_dirs + ;; + esac +} diff --git a/projects/ArchR/packages/emulators/libretro/idtech-lr/scripts/generate-idtech.sh b/projects/ArchR/packages/emulators/libretro/idtech-lr/scripts/generate-idtech.sh new file mode 100644 index 0000000000..6568cc28ba --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/idtech-lr/scripts/generate-idtech.sh @@ -0,0 +1,229 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + + +# This scripts scans the /storage/roms/idtech folder for idtech game files +# and creates the necessary idtech launcher scripts + +# Source predefined variables +. /etc/os-release + +RA_BIN="/usr/bin/retroarch" +RA_DIR="/usr/lib/libretro" +SCRIPT_DIR="/storage/.config/idtech" +GAME_DIR="/storage/roms/idtech" + +### create .config/idtech if does not exist +if [ ! -d ${SCRIPT_DIR} ]; then + mkdir -p ${SCRIPT_DIR} +fi + +### Create game directories +while read IDTECH_DIR; do + if [ ! -d "${GAME_DIR}/${IDTECH_DIR}" ]; then + mkdir -p ${GAME_DIR}/${IDTECH_DIR} + fi +done ${SCRIPT_DIR}/Doom.sh +#!/bin/bash + +${RA_BIN} -L ${RA_DIR}/prboom_libretro.so ${GAME_DIR}/doom/doom/doom.wad +EOF +fi + +### The Ultimate Doom +if [[ -f "${GAME_DIR}/doom/doomu/doomu.wad" ]] && [[ ! -f ${SCRIPT_DIR}/The\ Ultimate\ Doom.sh ]]; then +cat <${SCRIPT_DIR}/The\ Ultimate\ Doom.sh +#!/bin/bash + +${RA_BIN} -L ${RA_DIR}/prboom_libretro.so ${GAME_DIR}/doom/doomu/doomu.wad +EOF +fi + +### Doom 2 +if [[ -f "${GAME_DIR}/doom/doom2/doom2.wad" ]] && [[ ! -f ${SCRIPT_DIR}/Doom\ II.sh ]]; then +cat <${SCRIPT_DIR}/Doom\ II.sh +#!/bin/bash + +${RA_BIN} -L ${RA_DIR}/prboom_libretro.so ${GAME_DIR}/doom/doom2/doom2.wad +EOF +fi + +### The Plutonia Experiment +if [[ -f "${GAME_DIR}/doom/plutonia/plutonia.wad" ]] && [[ ! -f ${SCRIPT_DIR}/The\ Plutonia\ Experiment.sh ]]; then +cat <${SCRIPT_DIR}/The\ Plutonia\ Experiment.sh +#!/bin/bash + +${RA_BIN} -L ${RA_DIR}/prboom_libretro.so ${GAME_DIR}/doom/plutonia/plutonia.wad +EOF +fi + +### TNT Evilution +if [[ -f "${GAME_DIR}/doom/tnt/tnt.wad" ]] && [[ ! -f ${SCRIPT_DIR}/TNT\ Evilution.sh ]]; then +cat <${SCRIPT_DIR}/TNT\ Evilution.sh +#!/bin/bash + +${RA_BIN} -L ${RA_DIR}/prboom_libretro.so ${GAME_DIR}/doom/tnt/tnt.wad +EOF +fi + +### SIGIL +if [[ -f "${GAME_DIR}/doom/sigil/sigil.wad" ]] && [[ ! -f ${SCRIPT_DIR}/Sigil.sh ]]; then +cat <${SCRIPT_DIR}/Sigil.sh +#!/bin/bash + +${RA_BIN} -L ${RA_DIR}/prboom_libretro.so ${GAME_DIR}/doom/sigil/sigil.wad +EOF +fi + +### SIGIL II +if [[ -f "${GAME_DIR}/doom/sigil2/sigil2.wad" ]] && [[ ! -f ${SCRIPT_DIR}/Sigil\ II.sh ]]; then +cat <${SCRIPT_DIR}/Sigil\ II.sh +#!/bin/bash + +${RA_BIN} -L ${RA_DIR}/prboom_libretro.so ${GAME_DIR}/doom/sigil2/sigil2.wad +EOF +fi + +### Doom 3 +if [[ ${HW_ARCH} = "x86_64" ]] && [[ -f "${GAME_DIR}/doom3/base/pak000.pk4" ]] && [[ ! -f ${SCRIPT_DIR}/Doom\ 3.sh ]]; then +cat <${SCRIPT_DIR}/Doom\ 3.sh +#!/bin/bash + +${RA_BIN} -L ${RA_DIR}/boom3_libretro.so ${GAME_DIR}/doom3/base/* +EOF +fi + +### Doom 3 - Resurrection of Evil +if [[ ${HW_ARCH} = "x86_64" ]] && [[ -f "${GAME_DIR}/doom3/d3xp/pak000.pk4" ]] && [[ ! -f ${SCRIPT_DIR}/Doom\ 3\ -\ Resurrection\ of\ Evil.sh ]]; then +cat <${SCRIPT_DIR}/Doom\ 3\ -\ Resurrection\ of\ Evil.sh +#!/bin/bash + +${RA_BIN} -L ${RA_DIR}/boom3_xp_libretro.so ${GAME_DIR}/doom3/d3xp/* +EOF +fi + +### Quake +if [[ -f "${GAME_DIR}/quake/id1/pak0.pak" ]] && [[ ! -f ${SCRIPT_DIR}/Quake.sh ]]; then +cat <${SCRIPT_DIR}/Quake.sh +#!/bin/bash + +${RA_BIN} -L ${RA_DIR}/tyrquake_libretro.so ${GAME_DIR}/quake/id1/pak0.pak +EOF +fi + +### Quake - Scourge of Armagon +if [[ -f "${GAME_DIR}/quake/hipnotic/pak0.pak" ]] && [[ ! -f ${SCRIPT_DIR}/Quake\ -\ Scourge\ of\ Armagon.sh ]]; then +cat <${SCRIPT_DIR}/Quake\ -\ Scourge\ of\ Armagon.sh +#!/bin/bash + +${RA_BIN} -L ${RA_DIR}/tyrquake_libretro.so ${GAME_DIR}/quake/hipnotic/pak0.pak +EOF +fi + +### Quake - Dissolution of Eternity +if [[ -f "${GAME_DIR}/quake/rogue/pak0.pak" ]] && [[ ! -f ${SCRIPT_DIR}/Quake\ -\ Dissolution\ of\ Eternity.sh ]]; then +cat <${SCRIPT_DIR}/Quake\ -\ Dissolution\ of\ Eternity.sh +#!/bin/bash + +${RA_BIN} -L ${RA_DIR}/tyrquake_libretro.so ${GAME_DIR}/quake/rogue/pak0.pak +EOF +fi + +### Quake - Dimension of the Past +if [[ -f "${GAME_DIR}/quake/dopa/pak0.pak" ]] && [[ ! -f ${SCRIPT_DIR}/Quake\ -\ Dimension\ of\ the\ Past.sh ]]; then +cat <${SCRIPT_DIR}/Quake\ -\ Dimension\ of\ the\ Past.sh +#!/bin/bash + +${RA_BIN} -L ${RA_DIR}/tyrquake_libretro.so ${GAME_DIR}/quake/dopa/pak0.pak +EOF +fi + +### Malice +if [[ -f "${GAME_DIR}/quake/malice/pak0.pak" ]] && [[ ! -f ${SCRIPT_DIR}/Malice.sh ]]; then +cat <${SCRIPT_DIR}/Malice.sh +#!/bin/bash + +${RA_BIN} -L ${RA_DIR}/tyrquake_libretro.so ${GAME_DIR}/quake/malice/pak0.pak +EOF +fi + +### Quake 2 +if [[ -f "${GAME_DIR}/quake2/baseq2/pak0.pak" ]] && [[ ! -f ${SCRIPT_DIR}/Quake\ II.sh ]]; then +cat <${SCRIPT_DIR}/Quake\ II.sh +#!/bin/bash + +${RA_BIN} -L ${RA_DIR}/vitaquake2_libretro.so ${GAME_DIR}/quake2/baseq2/* +EOF +fi + +### Quake 2 - The Reckoning +if [[ -f "${GAME_DIR}/quake2/xatrix/pak0.pak" ]] && [[ ! -f ${SCRIPT_DIR}/Quake\ II\ -\ The\ Reckoning.sh ]]; then +cat <${SCRIPT_DIR}/Quake\ II\ -\ The\ Reckoning.sh +#!/bin/bash + +${RA_BIN} -L ${RA_DIR}/vitaquake2-xatrix_libretro.so ${GAME_DIR}/quake2/xatrix/* +EOF +fi + +### Quake 2 - Ground Zero +if [[ -f "${GAME_DIR}/quake2/rogue/pak0.pak" ]] && [[ ! -f ${SCRIPT_DIR}/Quake\ II\ -\ Ground\ Zero.sh ]]; then +cat <${SCRIPT_DIR}/Quake\ II\ -\ Ground\ Zero.sh +#!/bin/bash + +${RA_BIN} -L ${RA_DIR}/vitaquake2-rogue_libretro.so ${GAME_DIR}/quake2/rogue/* +EOF +fi + +### Quake 2 - Zaero +if [[ -f "${GAME_DIR}/quake2/zaero/pak0.pak" ]] && [[ ! -f ${SCRIPT_DIR}/Quake\ II\ -\ Zaero.sh ]]; then +cat <${SCRIPT_DIR}/Quake\ II\ -\ Zaero.sh +#!/bin/bash + +${RA_BIN} -L ${RA_DIR}/vitaquake2-zaero_libretro.so ${GAME_DIR}/quake2/zaero/* +EOF +fi + +### Quake 3 +if [[ ${HW_ARCH} = "x86_64" ]] && [[ -f "${GAME_DIR}/quake3/baseq3/pak0.pk3" ]] && [[ ! -f ${SCRIPT_DIR}/Quake\ III.sh ]]; then +cat <${SCRIPT_DIR}/Quake\ III.sh +#!/bin/bash + +${RA_BIN} -L ${RA_DIR}/vitaquake3_libretro.so ${GAME_DIR}/quake3/baseq3/* +EOF +fi + +### Wolfenstein 3D +if [[ -f "${GAME_DIR}/wolf3d/wolf3d/VSWAP.WL6" ]] && [[ ! -f ${SCRIPT_DIR}/Wolfenstein\ 3D.sh ]]; then +cat <${SCRIPT_DIR}/Wolfenstein\ 3D.sh +#!/bin/bash + +${RA_BIN} -L ${RA_DIR}/ecwolf_libretro.so ${GAME_DIR}/wolf3d/wolf3d/* +EOF +fi + +### Wolfenstein 3D - Spear of Destiny +if [[ -f "${GAME_DIR}/wolf3d/sod/VSWAP.SOD" ]] && [[ ! -f ${SCRIPT_DIR}/Wolfenstein\ 3D\ -\ Spear\ of\ Destiny.sh ]]; then +cat <${SCRIPT_DIR}/Wolfenstein\ 3D\ -\ Spear\ of\ Destiny.sh +#!/bin/bash + +${RA_BIN} -L ${RA_DIR}/ecwolf_libretro.so ${GAME_DIR}/wolf3d/sod/* +EOF +fi + +### Set all launcher scripts to be executable ### +chmod +x ${SCRIPT_DIR}/* + +#Restart ES so games are displayed +systemctl restart ${UI_SERVICE} diff --git a/projects/ArchR/packages/emulators/libretro/idtech-lr/sources/idtech_dirs b/projects/ArchR/packages/emulators/libretro/idtech-lr/sources/idtech_dirs new file mode 100644 index 0000000000..1bf88d991e --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/idtech-lr/sources/idtech_dirs @@ -0,0 +1,21 @@ +doom/doom +doom/doomu +doom/doom2 +doom/plutonia +doom/tnt +doom/sigil +doom/sigil2 +doom3/base +doom3/d3xp +quake/id1 +quake/dopa +quake/hipnotic +quake/rogue +quake/malice +quake2/baseq2 +quake2/rogue +quake2/xatrix +quake2/zaero +quake3/baseq3 +wolf3d/wolf3d +wolf3d/sod diff --git a/projects/ArchR/packages/emulators/libretro/jaxe-lr/package.mk b/projects/ArchR/packages/emulators/libretro/jaxe-lr/package.mk new file mode 100644 index 0000000000..6a017231bc --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/jaxe-lr/package.mk @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present AmberELEC (https://github.com/AmberELEC) + +PKG_NAME="jaxe-lr" +PKG_VERSION="4825aad24716f67924cd949354aae490a14b4d2d" +PKG_ARCH="aarch64" +PKG_SITE="https://github.com/kurtjd/jaxe" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="A fully-featured, cross platform XO-CHIP/S-CHIP/CHIP-8 emulator written in C and SDL" +PKG_TOOLCHAIN="make" + +make_target() { + cd ${PKG_BUILD} + make -f Makefile.libretro +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp ${PKG_BUILD}/jaxe_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/libretro-database/package.mk b/projects/ArchR/packages/emulators/libretro/libretro-database/package.mk new file mode 100644 index 0000000000..82d69642f2 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/libretro-database/package.mk @@ -0,0 +1,19 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="libretro-database" +PKG_VERSION="fbcc8c1c24d8b20b6aaca95b4da6a2f39ad85f05" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/libretro/libretro-database" +PKG_URL="https://github.com/libretro/libretro-database/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="" +PKG_LONGDESC="Repository containing cheatcode files, content data files, etc." +PKG_TOOLCHAIN="manual" + +post_unpack() { + sed -i '/cp -ar -t .* cht cursors/s/ rdb//' ${PKG_BUILD}/Makefile +} + +makeinstall_target() { + make install INSTALLDIR="${INSTALL}/usr/share/libretro-database" -C "${PKG_BUILD}" +} diff --git a/projects/ArchR/packages/emulators/libretro/mame-lr/package.mk b/projects/ArchR/packages/emulators/libretro/mame-lr/package.mk new file mode 100644 index 0000000000..7f2837163e --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/mame-lr/package.mk @@ -0,0 +1,69 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2019 Trond Haugland (trondah@gmail.com) + +PKG_NAME="mame-lr" +PKG_VERSION="a90e86e100f79533f257ac2b30ccefe26a76daad" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/mame" +PKG_URL="https://github.com/libretro/mame/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain zlib flac sqlite expat" +PKG_LONGDESC="MAME - Multiple Arcade Machine Emulator" +PKG_TOOLCHAIN="make" +PKG_BUILD_FLAGS="-lto +pic" + +case ${TARGET_ARCH} in + arm|aarch64) + MAME_PLATFORM="PLATFORM=arm64" + CROSS_BUILD="1" + PTR64=0 + ;; + *) + CROSS_BUILD="0" + PTR64=1 + ;; +esac + +PKG_MAKE_OPTS_TARGET="REGENIE=1 \ + VERBOSE=1 \ + NOWERROR=1 \ + OPENMP=1 \ + CROSS_BUILD=${CROSS_BUILD} \ + TOOLS=0 \ + RETRO=1 \ + PTR64=${PTR64} \ + NOASM=0 \ + PYTHON_EXECUTABLE=python3 \ + CONFIG=libretro \ + LIBRETRO_OS=unix \ + LIBRETRO_CPU= \ + ${MAME_PLATFORM} \ + ARCH= \ + TARGET=mame \ + SUBTARGET=mame \ + OSD=retro \ + USE_SYSTEM_LIB_EXPAT=1 \ + USE_SYSTEM_LIB_ZLIB=1 \ + USE_SYSTEM_LIB_FLAC=1 \ + USE_SYSTEM_LIB_SQLITE3=1" + +pre_configure_target() { + sed -i "s/-static-libstdc++//g" scripts/genie.lua +} + +make_target() { + unset ARCH + unset DISTRO + unset PROJECT + if [ "${PLATFORM}" = "arm64" ] + then + export ARCHOPTS="-D__aarch64__ -DASMJIT_BUILD_X86" + fi + make ${PKG_MAKE_OPTS_TARGET} OVERRIDE_CC=${CC} OVERRIDE_CXX=${CXX} OVERRIDE_LD=$LD AR=${AR} ${MAKEFLAGS} +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp *.so ${INSTALL}/usr/lib/libretro/mame_libretro.so + mkdir -p ${INSTALL}/usr/config/retroarch/savefiles/mame/hi + cp plugins/hiscore/hiscore.dat ${INSTALL}/usr/config/retroarch/savefiles/mame/hi +} diff --git a/projects/ArchR/packages/emulators/libretro/mame-lr/patches/mame-crosscompile.patch b/projects/ArchR/packages/emulators/libretro/mame-lr/patches/mame-crosscompile.patch new file mode 100644 index 0000000000..c100e31b27 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/mame-lr/patches/mame-crosscompile.patch @@ -0,0 +1,54 @@ +--- a/3rdparty/genie/build/gmake.linux/genie.make 2018-08-11 00:17:44.000000000 +0200 ++++ b/3rdparty/genie/build/gmake.linux/genie.make 2019-04-03 11:57:27.671223016 +0200 +@@ -28,8 +28,8 @@ + RM = $(SILENT) del /F "$(subst /,\\,$(1))" 2> nul || exit 0 + endif + +-CC = gcc +-CXX = g++ ++CC = $(HOST_CC) ++CXX = $(HOST_CXX) + AR = ar + + ifndef RESCOMP +@@ -50,12 +50,12 @@ + INCLUDES += -I"../../src/host/lua-5.3.0/src" + ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP -MP $(DEFINES) $(INCLUDES) + ALL_ASMFLAGS += $(ASMFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Wall -Wextra -Os $(MPARAM) -Wno-implicit-fallthrough +- ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Wall -Wextra -Os $(MPARAM) -Wno-implicit-fallthrough +- ALL_CXXFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Wall -Wextra -Os $(MPARAM) -Wno-implicit-fallthrough +- ALL_OBJCFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Wall -Wextra -Os $(MPARAM) -Wno-implicit-fallthrough +- ALL_OBJCPPFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Wall -Wextra -Os $(MPARAM) -Wno-implicit-fallthrough ++ ALL_CFLAGS += $(ALL_CPPFLAGS) $(ARCH) -Wall -Wextra -Os $(MPARAM) -Wno-implicit-fallthrough ++ ALL_CXXFLAGS += $(ALL_CPPFLAGS) $(ARCH) -Wall -Wextra -Os $(MPARAM) -Wno-implicit-fallthrough ++ ALL_OBJCFLAGS += $(ALL_CPPFLAGS) $(ARCH) -Wall -Wextra -Os $(MPARAM) -Wno-implicit-fallthrough ++ ALL_OBJCPPFLAGS += $(ALL_CPPFLAGS) $(ARCH) -Wall -Wextra -Os $(MPARAM) -Wno-implicit-fallthrough + ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES) +- ALL_LDFLAGS += $(LDFLAGS) -L"." -s -rdynamic ++ ALL_LDFLAGS += -L"." -s -rdynamic + LIBDEPS += + LDDEPS += + LDRESP = +--- a/3rdparty/genie/src/host/scripts.c 2025-01-04 19:13:10.550615500 +0100 ++++ b/3rdparty/genie/src/host/scripts.c 2025-01-04 21:29:13.629791709 +0100 +@@ -149,7 +149,7 @@ + + /* tools/gcc.lua */ + "premake.gcc = { }\npremake.gcc.cc = \"gcc\"\npremake.gcc.cxx = \"g++\"\npremake.gcc.ar = \"ar\"\npremake.gcc.rc = \"windres\"\npremake.gcc.llvm = false\nlocal cflags =\n{\nEnableSSE = \"-msse\",\nEnableSSE2 = \"-msse2\",\nEnableAVX = \"-mavx\",\nEnableAVX2 = \"-mavx2\",\nPedanticWarnings = \"-Wall -Wextra -pedantic\",\nExtraWarnings = \"-Wall -Wextra\",\nFatalWarnings = \"-Werror\",\nFloatFast = \"-ffast-math\",\nFloatStrict = \"-ffloat-store\",\nNoFramePointer = \"-fomit-frame-pointer\",\nOptimize = \"-O2\",\nOptimizeSize = \"-Os\",\nOptimizeSpeed = \"-O3\",\nSymbols = \"-g\",\n}\nlocal cxxflags =\n{\nCpp11 = \"-std=c++11\",\nCpp14 = \"-std=c++14\",\nCpp17 = \"-std=c++17\",\nCpp20 = \"-std=c++20\",\nCppLatest = \"-std=c++2b\",\nNoExceptions = \"-fno-exceptions\",\nNoRTTI = \"-fno-rtti\",\nUnsignedChar = \"-funsigned-char\",\n}\nlocal objcflags =\n{\nObjcARC = \"-fobjc-arc\",\n}\npremake." +- "gcc.platforms =\n{\nNative = {\ncppflags = \"-MMD -MP\",\n},\nx32 = {\ncppflags = \"-MMD -MP\",\nflags = \"-m32\",\n},\nx64 = {\ncppflags = \"-MMD -MP\",\nflags = \"-m64\",\n},\nUniversal = {\nar = \"libtool\",\ncppflags = \"-MMD -MP\",\nflags = \"-arch i386 -arch x86_64 -arch ppc -arch ppc64\",\n},\nUniversal32 = {\nar = \"libtool\",\ncppflags = \"-MMD -MP\",\nflags = \"-arch i386 -arch ppc\",\n},\nUniversal64 = {\nar = \"libtool\",\ncppflags = \"-MMD -MP\",\nflags = \"-arch x86_64 -arch ppc64\",\n},\nPS3 = {\ncc = \"ppu-lv2-g++\",\ncxx = \"ppu-lv2-g++\",\nar = \"ppu-lv2-ar\",\ncppflags = \"-MMD -MP\",\n},\nWiiDev = {\ncppflags = \"-MMD -MP -I$(LIBOGC_INC) $(MACHDEP)\",\nldflags= \"-L$(LIBOGC_LIB) $(MACHDEP)\",\ncfgsettings = [[\n ifeq ($(strip $(DEVKITPPC)),)\n $(error \"DEVKITPPC environment variable is not set\")'\n endif\n include $(DEVKITPPC)/wii_rules']],\n},\nOrbis = {\ncc = \"orbis-clang\",\ncxx = \"orbis-clang++\",\nar " ++ "gcc.platforms =\n{\nNative = {\ncppflags = \"-MMD -MP\",\n},\nx32 = {\ncppflags = \"-MMD -MP\"\n},\nx64 = {\ncppflags = \"-MMD -MP\",\nflags = \"-m64\",\n},\nUniversal = {\nar = \"libtool\",\ncppflags = \"-MMD -MP\",\nflags = \"-arch i386 -arch x86_64 -arch ppc -arch ppc64\",\n},\nUniversal32 = {\nar = \"libtool\",\ncppflags = \"-MMD -MP\",\nflags = \"-arch i386 -arch ppc\",\n},\nUniversal64 = {\nar = \"libtool\",\ncppflags = \"-MMD -MP\",\nflags = \"-arch x86_64 -arch ppc64\",\n},\nPS3 = {\ncc = \"ppu-lv2-g++\",\ncxx = \"ppu-lv2-g++\",\nar = \"ppu-lv2-ar\",\ncppflags = \"-MMD -MP\",\n},\nWiiDev = {\ncppflags = \"-MMD -MP -I$(LIBOGC_INC) $(MACHDEP)\",\nldflags= \"-L$(LIBOGC_LIB) $(MACHDEP)\",\ncfgsettings = [[\n ifeq ($(strip $(DEVKITPPC)),)\n $(error \"DEVKITPPC environment variable is not set\")'\n endif\n include $(DEVKITPPC)/wii_rules']],\n},\nOrbis = {\ncc = \"orbis-clang\",\ncxx = \"orbis-clang++\",\nar " + " = \"orbis-ar\",\ncppflags = \"-MMD -MP\",\n},\nEmscripten = {\ncc = \"$(EMSCRIPTEN)/emcc\",\ncxx = \"$(EMSCRIPTEN)/em++\",\nar = \"$(EMSCRIPTEN)/emar\",\ncppflags = \"-MMD -MP\",\n},\nNX32 = {\ncc = \"clang\",\ncxx = \"clang++\",\nar = \"armv7l-nintendo-nx-eabihf-ar\",\ncppflags = \"-MMD -MP\",\nflags = \"-march=armv7l\",\n},\nNX64 = {\ncc = \"clang\",\ncxx = \"clang++\",\nar = \"aarch64-nintendo-nx-elf-ar\",\ncppflags = \"-MMD -MP\",\nflags = \"-march=aarch64\",\n},\n}\nlocal platforms = premake.gcc.platforms\nfunction premake.gcc.getcppflags(cfg)\nlocal flags = { }\ntable.insert(flags, platforms[cfg.platform].cppflags)\nif flags[1]:startswith(\"-MMD\") then\ntable.insert(flags, \"-MP\")\nend\nreturn flags\nend\nfunction premake.gcc.getcflags(cfg)\nlocal result = table.translate(cfg.flags, cflags)\ntable.insert(result, platforms[cfg.platform].flags)\nif cfg.system ~= \"windows\" and cfg.kind == \"SharedLib\" then\nt" + "able.insert(result, \"-fPIC\")\nend\nreturn result\nend\nfunction premake.gcc.getcxxflags(cfg)\nlocal result = table.translate(cfg.flags, cxxflags)\nreturn result\nend\nfunction premake.gcc.getobjcflags(cfg)\nreturn table.translate(cfg.flags, objcflags)\nend\nfunction premake.gcc.getldflags(cfg)\nlocal result = { }\nif not cfg.flags.Symbols then\nif cfg.system == \"macosx\" then\nelse\ntable.insert(result, \"-s\")\nend\nend\nif cfg.kind == \"Bundle\" then\ntable.insert(result, \"-bundle\")\nend\nif cfg.kind == \"SharedLib\" then\nif cfg.system == \"macosx\" then\ntable.insert(result, \"-dynamiclib\")\nelse\ntable.insert(result, \"-shared\")\nend\nif cfg.system == \"windows\" and not cfg.flags.NoImportLib then\ntable.insert(result, '-Wl,--out-implib=\"' .. cfg.linktarget.fullpath .. '\"')\nend\nend\nif cfg.kind == \"WindowedApp\" and cfg.system == \"windows\" then\ntable.insert(result, \"-mwindows\")\nend\nlocal platform = platforms[cfg.platform]\ntable.insert(result, platform.flags)\ntable.insert(result, platf" + "orm.ldflags)\nreturn result\nend\nfunction premake.gcc.getlibdirflags(cfg)\nlocal result = { }\nfor _, value in ipairs(premake.getlinks(cfg, \"all\", \"directory\")) do\ntable.insert(result, '-L\\\"' .. value .. '\\\"')\nend\nreturn result\nend\nfunction premake.gcc.islibfile(p)\nif path.getextension(p) == \".a\" then\nreturn true\nend\nreturn false\nend\nfunction premake.gcc.getlibfiles(cfg)\nlocal result = {}\nfor _, value in ipairs(premake.getlinks(cfg, \"system\", \"fullpath\")) do\nif premake.gcc.islibfile(value) then\ntable.insert(result, _MAKE.esc(value))\nend\nend\nreturn result\nend\nfunction premake.gcc.getlinkflags(cfg)\nlocal result = {}\nfor _, value in ipairs(premake.getlinks(cfg, \"system\", \"fullpath\")) do\nif premake.gcc.islibfile(value) then\nvalue = path.rebase(value, cfg.project.location, cfg.location)\ntable.insert(result, _MAKE.esc(value))\nelseif path.getextension(value) == \".framework\" then\ntable.insert(result, '-framework ' .. _MAKE.esc(path.getbasename(value)))\nelse\ntable.inser" +--- a/scripts/toolchain.lua 2019-04-30 15:47:21.000000000 +0200 ++++ b/scripts/toolchain.lua 2019-05-21 22:51:48.116148725 +0200 +@@ -698,9 +698,6 @@ + + configuration { "linux-gcc", "x32" } + objdir (_buildDir .. "linux_gcc" .. "/obj") +- buildoptions { +- "-m32", +- } + + configuration { "linux-gcc", "x32", "Release" } + targetdir (_buildDir .. "linux_gcc" .. "/bin/x32/Release") diff --git a/projects/ArchR/packages/emulators/libretro/mame2003-lr/package.mk b/projects/ArchR/packages/emulators/libretro/mame2003-lr/package.mk new file mode 100644 index 0000000000..e85d88ee18 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/mame2003-lr/package.mk @@ -0,0 +1,40 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="mame2003-lr" +PKG_VERSION="c079e586e5ef54e084622863816f4f0439fdb870" +PKG_SHA256="a23579c5df4cadcf57740a4d64e10eff0e26805e304261902a4d891fd2a2662a" +PKG_LICENSE="MAME" +PKG_SITE="https://github.com/libretro/mame2003-libretro" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="MAME - Multiple Arcade Machine Emulator" + +PKG_TOOLCHAIN="make" + +make_target() { + make ARCH="" CC="${CC}" NATIVE_CC="${CC}" LD="${CC}" +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp mame2003_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/mame2003-plus-lr/package.mk b/projects/ArchR/packages/emulators/libretro/mame2003-plus-lr/package.mk new file mode 100644 index 0000000000..44ee40229c --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/mame2003-plus-lr/package.mk @@ -0,0 +1,40 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="mame2003-plus-lr" +PKG_VERSION="62c7089644966f6ac5fc79fe03592603579a409d" +PKG_LICENSE="MAME" +PKG_SITE="https://github.com/libretro/mame2003-plus-libretro" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="MAME - Multiple Arcade Machine Emulator" + +PKG_TOOLCHAIN="make" + +make_target() { + make ARCH="" CC="${CC}" NATIVE_CC="${CC}" LD="${CC}" +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp mame2003_plus_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/mame2010-lr/package.mk b/projects/ArchR/packages/emulators/libretro/mame2010-lr/package.mk new file mode 100644 index 0000000000..c65cdf5faf --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/mame2010-lr/package.mk @@ -0,0 +1,47 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="mame2010-lr" +PKG_VERSION="c5b413b71e0a290c57fc351562cd47ba75bac105" +PKG_LICENSE="MAME" +PKG_SITE="https://github.com/libretro/mame2010-libretro" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Late 2010 version of MAME (0.139) for libretro. Compatible with MAME 0.139 romsets." +PKG_BUILD_FLAGS="-parallel" +PKG_TOOLCHAIN="make" + +make_target() { + if [ "${ARCH}" == "arm" ]; then + make CC="${CC}" LD="${CC}" PLATCFLAGS="${CFLAGS}" PTR64=0 ARM_ENABLED=1 LCPU=arm + elif [ "${ARCH}" == "i386" ]; then + make CC="${CC}" LD="${CC}" PLATCFLAGS="${CFLAGS}" PTR64=0 ARM_ENABLED=0 LCPU=x86 + elif [ "${ARCH}" == "x86_64" ]; then + make CC="${CC}" LD="${CC}" PLATCFLAGS="${CFLAGS}" PTR64=1 ARM_ENABLED=0 LCPU=x86_64 + elif [ "${ARCH}" == "aarch64" ]; then + make CC="${CC}" LD="${CC}" PLATCFLAGS="${CFLAGS}" PTR64=1 ARM_ENABLED=1 LCPU=arm64 + fi +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp mame2010_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/mame2015-lr/package.mk b/projects/ArchR/packages/emulators/libretro/mame2015-lr/package.mk new file mode 100644 index 0000000000..7abcf4354d --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/mame2015-lr/package.mk @@ -0,0 +1,49 @@ +################################################################################ +# This file is part of LibreELEC - http://www.libreelec.tv +# Copyright (C) 2016 Team LibreELEC +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# LibreELEC is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# LibreELEC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with LibreELEC. If not, see . +################################################################################ + +PKG_NAME="mame2015-lr" +PKG_VERSION="316cd06349f2b34b4719f04f7c0d07569a74c764" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/mame2015-libretro" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Late 2014/Early 2015 version of MAME (0.160-ish) for libretro. Compatible with MAME 0.160 romsets." +PKG_TOOLCHAIN="make" +PKG_BUILD_FLAGS="-lto -parallel" + +pre_make_target() { + export REALCC=${CC} + export CC=${CXX} + export LD=${CXX} +} + +pre_configure_target() { + case ${ARCH} in + arm|aarch64) + PKG_MAKE_OPTS_TARGET=" platform=armv8-neon-hardfloat-cortex-a53" + sed -i 's/LDFLAGS += -Wl,--fix-cortex-a8 -Wl,--no-as-needed//g' Makefile + sed -i 's/CCOMFLAGS += -mstructure-size-boundary=32//g' Makefile + ;; + esac +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp mame*_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/mame2015-lr/patches/001-python-3.11.patch b/projects/ArchR/packages/emulators/libretro/mame2015-lr/patches/001-python-3.11.patch new file mode 100644 index 0000000000..eb6df27b31 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/mame2015-lr/patches/001-python-3.11.patch @@ -0,0 +1,57 @@ +diff -rupN mame2015.orig/src/emu/cpu/m6502/m6502make.py mame2015/src/emu/cpu/m6502/m6502make.py +--- mame2015.orig/src/emu/cpu/m6502/m6502make.py 2022-12-06 11:09:35.970767689 -0500 ++++ mame2015/src/emu/cpu/m6502/m6502make.py 2022-12-06 11:10:17.918361583 -0500 +@@ -16,7 +16,7 @@ def load_opcodes(fname): + opcodes = [] + logging.info("load_opcodes: %s", fname) + try: +- f = open(fname, "rU") ++ f = open(fname, "r") + except Exception: + err = sys.exc_info()[1] + logging.error("cannot read opcodes file %s [%s]", fname, err) +@@ -39,7 +39,7 @@ def load_disp(fname): + logging.info("load_disp: %s", fname) + states = [] + try: +- f = open(fname, "rU") ++ f = open(fname, "r") + except Exception: + err = sys.exc_info()[1] + logging.error("cannot read display file %s [%s]", fname, err) +diff -rupN mame2015.orig/src/emu/cpu/m6809/m6809make.py mame2015/src/emu/cpu/m6809/m6809make.py +--- mame2015.orig/src/emu/cpu/m6809/m6809make.py 2022-12-06 11:09:35.974767650 -0500 ++++ mame2015/src/emu/cpu/m6809/m6809make.py 2022-12-06 11:10:02.046515086 -0500 +@@ -14,7 +14,7 @@ def load_file(fname, lines): + if path != "": + path += '/' + try: +- f = open(fname, "rU") ++ f = open(fname, "r") + except Exception: + err = sys.exc_info()[1] + sys.stderr.write("Cannot read opcodes file %s [%s]\n" % (fname, err)) +diff -rupN mame2015.orig/src/emu/cpu/mcs96/mcs96make.py mame2015/src/emu/cpu/mcs96/mcs96make.py +--- mame2015.orig/src/emu/cpu/mcs96/mcs96make.py 2022-12-06 11:09:35.974767650 -0500 ++++ mame2015/src/emu/cpu/mcs96/mcs96make.py 2022-12-06 11:10:07.230464929 -0500 +@@ -71,7 +71,7 @@ class OpcodeList: + self.ea = {} + self.macros = {} + try: +- f = open(fname, "rU") ++ f = open(fname, "r") + except Exception: + err = sys.exc_info()[1] + sys.stderr.write("Cannot read opcodes file %s [%s]\n" % (fname, err)) +diff -rupN mame2015.orig/src/emu/cpu/tms57002/tmsmake.py mame2015/src/emu/cpu/tms57002/tmsmake.py +--- mame2015.orig/src/emu/cpu/tms57002/tmsmake.py 2022-12-06 11:09:35.982767573 -0500 ++++ mame2015/src/emu/cpu/tms57002/tmsmake.py 2022-12-06 11:10:24.850294595 -0500 +@@ -326,7 +326,7 @@ def ins_cmp_dasm(a, b): + def LoadLst(filename): + instructions = [] + ins = None +- for n, line in enumerate(open(filename, "rU")): ++ for n, line in enumerate(open(filename, "r")): + line = line.rstrip() + if not line and ins: + # new lines separate intructions diff --git a/projects/ArchR/packages/emulators/libretro/melonds-ds-lr/package.mk b/projects/ArchR/packages/emulators/libretro/melonds-ds-lr/package.mk new file mode 100644 index 0000000000..61bd81ea73 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/melonds-ds-lr/package.mk @@ -0,0 +1,26 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="melonds-ds-lr" +PKG_VERSION="86986bfd82fb130d4d4739d93159acd986921808" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/JesseTG/melonds-ds" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_SHORTDESC="An enhanced remake of the melonDS core for libretro that prioritizes standalone parity, reliability, and usability." +PKG_TOOLCHAIN="cmake-make" + +PKG_CMAKE_OPTS_TARGET=" -DENABLE_OPENGL=ON" + +if [ "${OPENGL_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL}" + PKG_CMAKE_OPTS_TARGET+=" -DDEFAULT_OPENGL_PROFILE=OpenGL" +elif [ "${OPENGLES_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" + PKG_CMAKE_OPTS_TARGET+=" -DDEFAULT_OPENGL_PROFILE=OpenGLES2" +fi + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp ${PKG_BUILD}/.${TARGET_NAME}/src/libretro/melondsds_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/melonds-lr/package.mk b/projects/ArchR/packages/emulators/libretro/melonds-lr/package.mk new file mode 100644 index 0000000000..1feeaa9fa3 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/melonds-lr/package.mk @@ -0,0 +1,33 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="melonds-lr" +PKG_VERSION="7a3c11ff970cd36ca806961fae6db94b30dd5401" +PKG_LICENSE="GPLv3" +PKG_SITE="https://git.libretro.com/libretro/melonDS" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="MelonDS - Nintendo DS emulator for libretro" +PKG_TOOLCHAIN="make" + +if [ ! "${OPENGL}" = "no" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" +fi + +if [ "${OPENGLES_SUPPORT}" = yes ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" +fi + +pre_make_target() { + + cd ${PKG_BUILD} + if [ -e "CMakeLists.txt" ] + then + rm CMakeLists.txt + fi +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp melonds_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/mesen-lr/package.mk b/projects/ArchR/packages/emulators/libretro/mesen-lr/package.mk new file mode 100644 index 0000000000..5fcd8da085 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/mesen-lr/package.mk @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="mesen-lr" +PKG_VERSION="791c5e8153ee6e29691d45b5df2cf1151ff416f9" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/libretro/Mesen" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Mesen is a cross-platform NES/Famicom emulator for Windows & Linux built in C++ and C#." +PKG_TOOLCHAIN="make" + +make_target() { + make -C Libretro/ +} + + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp Libretro/mesen_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/mgba-lr/package.mk b/projects/ArchR/packages/emulators/libretro/mgba-lr/package.mk new file mode 100644 index 0000000000..97eec4c5a4 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/mgba-lr/package.mk @@ -0,0 +1,51 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="mgba-lr" +PKG_VERSION="c758314a639aa0066e7b65a8341448181b73c804" +PKG_LICENSE="MPLv2.0" +PKG_SITE="https://github.com/libretro/mgba" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="mGBA Game Boy Advance Emulator" +PKG_PATCH_DIRS+="${DEVICE}" + +PKG_TOOLCHAIN="make" +PKG_USE_CMAKE="no" + +make_target() { + cd ${PKG_BUILD} + case ${ARCH} in + arm) + make -f Makefile.libretro platform=unix-armv HAVE_NEON=1 + ;; + aarch64) + make -f Makefile.libretro platform=goadvance + ;; + *) + make -f Makefile.libretro + ;; + esac +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp mgba_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/minivmac-lr/package.mk b/projects/ArchR/packages/emulators/libretro/minivmac-lr/package.mk new file mode 100644 index 0000000000..2e97c8ef7a --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/minivmac-lr/package.mk @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="minivmac-lr" +PKG_VERSION="6b468a9610aa422fe1b01bf56d73b636976d2b97" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/libretro-minivmac" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Virtual Macintosh" +PKG_TOOLCHAIN="make" + + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp ${PKG_BUILD}/minivmac_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/mojozork-lr/package.mk b/projects/ArchR/packages/emulators/libretro/mojozork-lr/package.mk new file mode 100644 index 0000000000..fc667b78a7 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/mojozork-lr/package.mk @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present AmberELEC (https://github.com/AmberELEC) + +PKG_NAME="mojozork-lr" +PKG_VERSION="5c8d81f8db53c206ace6952472e7a7e68bd8e752" +PKG_SITE="https://github.com/icculus/mojozork" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain sqlite" +PKG_LONGDESC="A simple Z-Machine implementation in a single C file" +PKG_TOOLCHAIN="cmake" + +PKG_CMAKE_OPTS_TARGET="-DMOJOZORK_LIBRETRO=ON \ + -DMOJOZORK_STANDALONE_DEFAULT=OFF \ + -DMOJOZORK_MULTIZORK_DEFAULT=OFF \ + -DCMAKE_POLICY_VERSION_MINIMUM=3.5" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp ${PKG_BUILD}/.${TARGET_NAME}/mojozork_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/mu-lr/package.mk b/projects/ArchR/packages/emulators/libretro/mu-lr/package.mk new file mode 100644 index 0000000000..3953573e41 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/mu-lr/package.mk @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="mu-lr" +PKG_VERSION="865acf3a2889dfe02863bbfb9c5b3cfee8620c22" +PKG_LICENSE="CC BY-NC 3.0 US" +PKG_SITE="https://git.libretro.com/libretro/Mu" +PKG_URL="${PKG_SITE}/-/archive/${PKG_VERSION}/Mu-${PKG_VERSION}.tar.gz" +PKG_GIT_CLONE_BRANCH="buildbot" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="An emulator for the Palm m515 OS ported to libretro." + +PKG_TOOLCHAIN="make" + +make_target() { + make -C ${PKG_BUILD}/libretroBuildSystem/ +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp ${PKG_BUILD}/libretroBuildSystem/mu_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/mupen64plus-lr/package.mk b/projects/ArchR/packages/emulators/libretro/mupen64plus-lr/package.mk new file mode 100644 index 0000000000..125a83648f --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/mupen64plus-lr/package.mk @@ -0,0 +1,56 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="mupen64plus-lr" +PKG_VERSION="ab8134ac90a567581df6de4fc427dd67bfad1b17" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/mupen64plus-libretro" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain nasm:host" +PKG_LONGDESC="mupen64plus + RSP-HLE + GLideN64 + libretro" +PKG_TOOLCHAIN="make" +PKG_BUILD_FLAGS="-lto" +PKG_PATCH_DIRS+=" ${DEVICE}" + +if [ "${OPENGL}" = "yes" ] && [ ! "${PREFER_GLES}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL} glu" + PKG_MAKE_OPTS_TARGET+=" GLES=0 GL_LIB=\"-lGL\"" +elif [ "${OPENGLES_SUPPORT}" = yes ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" + PKG_MAKE_OPTS_TARGET+=" GLES=1 GL_LIB=\"-lGLESv2\"" +fi + +pre_configure_target() { + export CFLAGS="${CFLAGS} -fcommon -Wno-error=incompatible-pointer-types -std=gnu17" + + case ${ARCH} in + aarch64) + PKG_MAKE_OPTS_TARGET+=" OS_LINUX=1 platform=${DEVICE}" + ;; + esac + + sed -i 's/\-O[23]/-Ofast/' ${PKG_BUILD}/Makefile +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp mupen64plus_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/mupen64plus-lr/patches/aarch64/001-optimizations.patch b/projects/ArchR/packages/emulators/libretro/mupen64plus-lr/patches/aarch64/001-optimizations.patch new file mode 100644 index 0000000000..f8afa9d651 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/mupen64plus-lr/patches/aarch64/001-optimizations.patch @@ -0,0 +1,20 @@ +diff -rupN mupen64plus.orig/Makefile mupen64plus/Makefile +--- mupen64plus.orig/Makefile 2022-02-27 09:19:06.080700288 -0500 ++++ mupen64plus/Makefile 2022-02-27 13:27:51.390268523 -0500 +@@ -238,6 +238,16 @@ else ifneq (,$(findstring osx,$(platform + + COREFLAGS += -DOS_LINUX + ASFLAGS = -f elf -d ELF_TYPE ++ ++# @DEVICE@ ++else ifneq (,$(findstring @DEVICE@,$(platform))) ++ TARGET := $(TARGET_NAME)_libretro.so ++ LDFLAGS += -shared -Wl,--version-script=$(LIBRETRO_DIR)/link.T -Wl,--no-undefined -ldl ++ COREFLAGS += -DOS_LINUX ++ HAVE_NEON = 0 ++ WITH_DYNAREC := aarch64 ++ ASFLAGS = -f elf -d ELF_TYPE ++ + # iOS + else ifneq (,$(findstring ios,$(platform))) + ifeq ($(IOSSDK),) diff --git a/projects/ArchR/packages/emulators/libretro/mupen64plus-lr/patches/mupen64plus-fixdouble.patch b/projects/ArchR/packages/emulators/libretro/mupen64plus-lr/patches/mupen64plus-fixdouble.patch new file mode 100644 index 0000000000..64070b5d25 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/mupen64plus-lr/patches/mupen64plus-fixdouble.patch @@ -0,0 +1,12 @@ +diff --git a/libretro-common/include/glsym/rglgen_headers.h b/libretro-common/include/glsym/rglgen_headers.h +index 766efb63..3de538d6 100644 +--- a/libretro-common/include/glsym/rglgen_headers.h ++++ b/libretro-common/include/glsym/rglgen_headers.h +@@ -53,6 +53,7 @@ + #include + #elif defined(HAVE_OPENGLES2) + #include ++#define GL_NV_path_rendering + #include + #elif defined(HAVE_OPENGLES1) + #include diff --git a/projects/ArchR/packages/emulators/libretro/mupen64plus-lr/patches/mupen64plus-inc-string.patch b/projects/ArchR/packages/emulators/libretro/mupen64plus-lr/patches/mupen64plus-inc-string.patch new file mode 100644 index 0000000000..5c85488abe --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/mupen64plus-lr/patches/mupen64plus-inc-string.patch @@ -0,0 +1,11 @@ +diff -rupN mupen64plus-libretro.orig/GLideN64/src/ShaderUtils.h mupen64plus-libretro.new/GLideN64/src/ShaderUtils.h +--- mupen64plus-libretro.orig/GLideN64/src/ShaderUtils.h 2021-01-27 17:21:42.177358627 -0500 ++++ mupen64plus-libretro.new/GLideN64/src/ShaderUtils.h 2021-01-27 17:22:02.081763415 -0500 +@@ -1,6 +1,7 @@ + #ifndef SHADER_UTILS_H + #define SHADER_UTILS_H + ++#include + #include "OpenGL.h" + #include "Combiner.h" + diff --git a/projects/ArchR/packages/emulators/libretro/mupen64plus-nx-lr/package.mk b/projects/ArchR/packages/emulators/libretro/mupen64plus-nx-lr/package.mk new file mode 100755 index 0000000000..7be058f83d --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/mupen64plus-nx-lr/package.mk @@ -0,0 +1,53 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="mupen64plus-nx-lr" +PKG_VERSION="7c7f11061f29b2ccd5d0952e2373ae5b55cfea8f" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/mupen64plus-libretro-nx" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain nasm:host" +PKG_LONGDESC="mupen64plus NX" +PKG_TOOLCHAIN="make" +PKG_BUILD_FLAGS="-lto" + +if [ "${OPENGL_SUPPORT}" = "yes" ] && [ ! "${PREFER_GLES}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" + PKG_MAKE_OPTS_TARGET+=" GL_LIB=\"-lGL\" GLES3=0" +elif [ "${OPENGLES_SUPPORT}" = yes ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" + PKG_MAKE_OPTS_TARGET+=" GL_LIB=\"-lGLESv2\" GLES3=1" +fi + +if [ "${VULKAN_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${VULKAN}" + PKG_MAKE_OPTS_TARGET+=" HAVE_PARALLEL_RSP=1 HAVE_PARALLEL_RDP=1" +fi + +echo PKG_DEPENDS_TARGET ${PKG_DEPENDS_TARGET} + +pre_configure_target() { + export CFLAGS="${CFLAGS} -DHAVE_UNISTD_H -Wno-error=incompatible-pointer-types" + if [ "${ARCH}" = "aarch64" ]; then + # This is only needed for armv8.2-a targets where we don't use this flag + # as it prohibits the use of LSE-instructions, this is a package bug most likely + export CXXFLAGS="${CXXFLAGS} -mno-outline-atomics" + fi + for SOURCE in ${PKG_BUILD}/mupen64plus-rsp-paraLLEl/rsp_disasm.cpp ${PKG_BUILD}/mupen64plus-rsp-paraLLEl/rsp_disasm.hpp + do + sed -i '/include /a #include ' ${SOURCE} + done + sed -e "s|^GIT_VERSION ?.*$|GIT_VERSION := \" ${PKG_VERSION:0:7}\"|" -i Makefile + sed -i 's/\-O[23]/-Ofast/' ${PKG_BUILD}/Makefile + + case ${ARCH} in + aarch64) + PKG_MAKE_OPTS_TARGET+=" platform=${DEVICE}" + ;; + esac +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp mupen64plus_next_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/mupen64plus-nx-lr/patches/000-platform.patch b/projects/ArchR/packages/emulators/libretro/mupen64plus-nx-lr/patches/000-platform.patch new file mode 100644 index 0000000000..2e7a4489f3 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/mupen64plus-nx-lr/patches/000-platform.patch @@ -0,0 +1,44 @@ +diff --git a/Makefile b/Makefile +index 481e8b9..2a4e365 100644 +--- a/Makefile ++++ b/Makefile +@@ -366,34 +366,13 @@ else ifneq (,$(findstring arm64_cortex_a53_gles3,$(platform))) + COREFLAGS += -DOS_LINUX + ASFLAGS = -f elf64 -d ELF_TYPE + +-# Rockchip RK3288 e.g. Asus Tinker Board / RK3328 e.g. PINE64 Rock64 / RK3399 e.g. PINE64 RockPro64 - 32-bit userspace +-else ifneq (,$(findstring RK,$(platform))) ++# ArchR DEVICE ++else ifneq (,$(findstring @DEVICE@,$(platform))) + TARGET := $(TARGET_NAME)_libretro.so + LDFLAGS += -shared -Wl,--version-script=$(LIBRETRO_DIR)/link.T -Wl,--no-undefined -ldl +- +- ifneq (,$(findstring RK33,$(platform))) +- CPUFLAGS += -march=armv8-a+crc -mfloat-abi=hard -mfpu=neon-fp-armv8 +- ifneq (,$(findstring RK3399,$(platform))) +- CPUFLAGS += -mtune=cortex-a72.cortex-a53 +- GLES3 = 1 +- else ifneq (,$(findstring RK3328,$(platform))) +- CPUFLAGS += -mtune=cortex-a53 +- GLES = 1 +- endif +- else ifneq (,$(findstring RK3288,$(platform))) +- CPUFLAGS += -march=armv7ve -mtune=cortex-a17 -mfloat-abi=hard -mfpu=neon-vfpv4 +- GLES3 = 1 +- endif +- +- ifneq (,$(findstring mesa,$(platform))) +- COREFLAGS += -DEGL_NO_X11 +- endif +- +- GL_LIB := -lGLESv2 +- HAVE_NEON = 1 +- WITH_DYNAREC=arm +- COREFLAGS += -DUSE_GENERIC_GLESV2 -DOS_LINUX +- ASFLAGS = -f elf -d ELF_TYPE ++ WITH_DYNAREC := aarch64 ++ COREFLAGS += -DOS_LINUX ++ ASFLAGS = -f elf64 -d ELF_TYPE + + # OS X + else ifneq (,$(findstring osx,$(platform))) diff --git a/projects/ArchR/packages/emulators/libretro/mupen64plus-nx-lr/patches/001-fix-building-with-gcc15.patch b/projects/ArchR/packages/emulators/libretro/mupen64plus-nx-lr/patches/001-fix-building-with-gcc15.patch new file mode 100644 index 0000000000..12ba64fbb3 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/mupen64plus-nx-lr/patches/001-fix-building-with-gcc15.patch @@ -0,0 +1,19 @@ +--- a/GLideN64/src/GLideNHQ/TxHiResLoader.h ++++ b/GLideN64/src/GLideNHQ/TxHiResLoader.h +@@ -1,6 +1,8 @@ + #ifndef TXHIRESLOADER_H + #define TXHIRESLOADER_H + ++#include ++ + /* support hires textures + * 0: disable + * 1: enable +--- a/GLideN64/src/GLideNHQ/TxHiResLoader.cpp ++++ b/GLideN64/src/GLideNHQ/TxHiResLoader.cpp +@@ -1,3 +1,5 @@ ++#include ++ + #include "TxHiResLoader.h" + #include "TxDbg.h" + #include "TxDbg.h" diff --git a/projects/ArchR/packages/emulators/libretro/neocd_lr/package.mk b/projects/ArchR/packages/emulators/libretro/neocd_lr/package.mk new file mode 100644 index 0000000000..6265b5599b --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/neocd_lr/package.mk @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2019-present Team CoreELEC (https://coreelec.org) + +PKG_NAME="neocd_lr" +PKG_VERSION="5eca2c8fd567b5261251c65ecafa8cf5b179d1d2" +PKG_LICENSE="LGPLv3.0" +PKG_SITE="https://github.com/libretro/neocd_libretro" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain flac libogg libvorbis" +PKG_LONGDESC="Neo Geo CD emulator for libretro " +PKG_TOOLCHAIN="make" +GET_HANDLER_SUPPORT="git" + +make_target() { +cd ${PKG_BUILD} +CFLAGS=${CFLAGS} CXXFLAGS="${CXXFLAGS}" CXX="${CXX}" CC="${CC}" LD="$LD" RANLIB="$RANLIB" AR="${AR}" make +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp ${PKG_BUILD}/neocd_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/nestopia-lr/package.mk b/projects/ArchR/packages/emulators/libretro/nestopia-lr/package.mk new file mode 100644 index 0000000000..298350f2d7 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/nestopia-lr/package.mk @@ -0,0 +1,40 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="nestopia-lr" +PKG_VERSION="5deada54077fae87e2873f5ad9ef77e3ab7af5e1" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/nestopia" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Libretro implementation of NEStopia. (Nintendo Entertainment System)" + +PKG_TOOLCHAIN="make" +PKG_USE_CMAKE="no" + +make_target() { + cd ${PKG_BUILD} + make -C libretro +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp libretro/nestopia_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/np2kai-lr/package.mk b/projects/ArchR/packages/emulators/libretro/np2kai-lr/package.mk new file mode 100644 index 0000000000..8074ff0f12 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/np2kai-lr/package.mk @@ -0,0 +1,43 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="np2kai-lr" +PKG_VERSION="c2ca4046860264cb307e768f529f180caee5e224" +PKG_LICENSE="MIT" +PKG_SITE="https://github.com/AZO234/NP2kai" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Neko Project II kai" +PKG_TOOLCHAIN="make" + +pre_configure_target() { +export CFLAGS="${CFLAGS} -Wno-error=incompatible-pointer-types -Wno-int-conversion" +} + +make_target() { + VERSION="${PKG_VERSION:0:7}" + cd ${PKG_BUILD}/sdl + make NP2KAI_VERSION=$VERSION NP2KAI_HASH=$VERSION +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp ${PKG_BUILD}/sdl/np2kai_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/o2em-lr/package.mk b/projects/ArchR/packages/emulators/libretro/o2em-lr/package.mk new file mode 100644 index 0000000000..6f0b972f21 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/o2em-lr/package.mk @@ -0,0 +1,34 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="o2em-lr" +PKG_VERSION="3ba4231c1dc8dcdf487428712856b790d2e4b8f3" +PKG_LICENSE="Artistic License" +PKG_SITE="https://github.com/libretro/libretro-o2em" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Port of O2EM to the libretro API, an Odyssey 2 / VideoPac emulator." + +PKG_TOOLCHAIN="make" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp o2em_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/opera-lr/package.mk b/projects/ArchR/packages/emulators/libretro/opera-lr/package.mk new file mode 100644 index 0000000000..245501d306 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/opera-lr/package.mk @@ -0,0 +1,38 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="opera-lr" +PKG_VERSION="67a29e60a4d194b675c9272b21b61eaa022f3ba3" +PKG_LICENSE="LGPL with additional notes" +PKG_SITE="https://github.com/libretro/opera-libretro" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Port of 4DO/libfreedo to libretro." +PKG_TOOLCHAIN="make" + + +make_target() { + make CC=${CC} CXX=${CXX} AR=${AR} +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp opera_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/panda3ds-lr/package.mk b/projects/ArchR/packages/emulators/libretro/panda3ds-lr/package.mk new file mode 100644 index 0000000000..4890db074e --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/panda3ds-lr/package.mk @@ -0,0 +1,34 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="panda3ds-lr" +PKG_VERSION="5591606177d7d595e19a18b3fdd33b8ffbbc1449" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/wheremyfoodat/Panda3DS" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Panda3DS is an HLE, red-panda-themed Nintendo 3DS emulator" +PKG_TOOLCHAIN="cmake" + +if [ "${OPENGL_SUPPORT}" = "yes" ] && [ ! "${PREFER_GLES}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL}" + PKG_CMAKE_OPTS_TARGET+=" -DOPENGL_PROFILE=OpenGL" +elif [ "${OPENGLES_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" + PKG_PATCH_DIRS+=" gles" + PKG_CMAKE_OPTS_TARGET+=" -DOPENGL_PROFILE=OpenGLES" +fi + +PKG_CMAKE_OPTS_TARGET+=" -DBUILD_LIBRETRO_CORE=ON \ + -DENABLE_USER_BUILD=ON \ + -DENABLE_DISCORD_RPC=OFF \ + -DENABLE_LUAJIT=OFF \ + -DSDL_VIDEO=OFF \ + -DSDL_AUDIO=OFF \ + -DENABLE_VULKAN=OFF \ + -DCMAKE_BUILD_TYPE=Release" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp -v ${PKG_BUILD}/.${TARGET_NAME}/panda3ds_libretro.so ${INSTALL}/usr/lib/libretro/panda3ds_libretro.so +} diff --git a/projects/ArchR/packages/emulators/libretro/panda3ds-lr/patches/gles/000-enable-gles.patch b/projects/ArchR/packages/emulators/libretro/panda3ds-lr/patches/gles/000-enable-gles.patch new file mode 100644 index 0000000000..c9de55daa6 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/panda3ds-lr/patches/gles/000-enable-gles.patch @@ -0,0 +1,270 @@ +diff -rupbN panda3ds.orig/src/host_shaders/opengl_display.frag panda3ds/src/host_shaders/opengl_display.frag +--- panda3ds.orig/src/host_shaders/opengl_display.frag 2024-08-28 21:01:16.674631846 +0000 ++++ panda3ds/src/host_shaders/opengl_display.frag 2024-08-28 22:09:19.387098916 +0000 +@@ -1,4 +1,5 @@ +-#version 410 core ++#version 320 es ++precision mediump float; + in vec2 UV; + out vec4 FragColor; + +diff -rupbN panda3ds.orig/src/host_shaders/opengl_display.vert panda3ds/src/host_shaders/opengl_display.vert +--- panda3ds.orig/src/host_shaders/opengl_display.vert 2024-08-28 21:01:16.674631846 +0000 ++++ panda3ds/src/host_shaders/opengl_display.vert 2024-08-28 22:09:19.387098916 +0000 +@@ -1,4 +1,5 @@ +-#version 410 core ++#version 320 es ++precision mediump float; + out vec2 UV; + + void main() { +diff -rupbN panda3ds.orig/src/host_shaders/opengl_fragment_shader.frag panda3ds/src/host_shaders/opengl_fragment_shader.frag +--- panda3ds.orig/src/host_shaders/opengl_fragment_shader.frag 2024-08-28 21:01:16.674631846 +0000 ++++ panda3ds/src/host_shaders/opengl_fragment_shader.frag 2024-08-28 22:09:19.387098916 +0000 +@@ -1,4 +1,5 @@ +-#version 410 core ++#version 320 es ++precision mediump float; + + in vec4 v_quaternion; + in vec4 v_colour; +@@ -41,8 +42,8 @@ vec3 normal; + const uint samplerEnabledBitfields[2] = uint[2](0x7170e645u, 0x7f013fefu); + + bool isSamplerEnabled(uint environment_id, uint lut_id) { +- uint index = 7 * environment_id + lut_id; +- uint arrayIndex = (index >> 5); ++ uint index = 7u * environment_id + lut_id; ++ uint arrayIndex = (index >> 5u); + return (samplerEnabledBitfields[arrayIndex] & (1u << (index & 31u))) != 0u; + } + +@@ -166,11 +167,17 @@ float lutLookup(uint lut, int index) { + return texelFetch(u_tex_luts, ivec2(index, int(lut)), 0).r; + } + ++// some gles versions have bitfieldExtractCompat and complain if you redefine it, some don't and compile error, using this instead ++uint bitfieldExtractCompat(uint val, int off, int size) { ++ uint mask = uint((1 << size) - 1); ++ return uint(val >> off) & mask; ++} ++ + vec3 regToColor(uint reg) { + // Normalization scale to convert from [0...255] to [0.0...1.0] + const float scale = 1.0 / 255.0; + +- return scale * vec3(float(bitfieldExtract(reg, 20, 8)), float(bitfieldExtract(reg, 10, 8)), float(bitfieldExtract(reg, 00, 8))); ++ return scale * vec3(float(bitfieldExtractCompat(reg, 20, 8)), float(bitfieldExtractCompat(reg, 10, 8)), float(bitfieldExtractCompat(reg, 00, 8))); + } + + // Convert an arbitrary-width floating point literal to an f32 +@@ -201,7 +208,7 @@ float lightLutLookup(uint environment_id + // These are the spotlight attenuation LUTs + bit_in_config1 = 8 + int(light_id & 7u); + lut_index = 8u + light_id; +- } else if (lut_id <= 6) { ++ } else if (lut_id <= 6u) { + bit_in_config1 = 16 + int(lut_id); + lut_index = lut_id; + } else { +@@ -210,16 +217,16 @@ float lightLutLookup(uint environment_id + + bool current_sampler_enabled = isSamplerEnabled(environment_id, lut_id); // 7 luts per environment + +- if (!current_sampler_enabled || (bitfieldExtract(GPUREG_LIGHTING_CONFIG1, bit_in_config1, 1) != 0u)) { ++ if (!current_sampler_enabled || (bitfieldExtractCompat(GPUREG_LIGHTING_CONFIG1, bit_in_config1, 1) != 0u)) { + return 1.0; + } + +- uint scale_id = bitfieldExtract(GPUREG_LIGHTING_LUTINPUT_SCALE, int(lut_id) << 2, 3); ++ uint scale_id = bitfieldExtractCompat(GPUREG_LIGHTING_LUTINPUT_SCALE, int(lut_id) << 2, 3); + float scale = float(1u << scale_id); + if (scale_id >= 6u) scale /= 256.0; + + float delta = 1.0; +- uint input_id = bitfieldExtract(GPUREG_LIGHTING_LUTINPUT_SELECT, int(lut_id) << 2, 3); ++ uint input_id = bitfieldExtractCompat(GPUREG_LIGHTING_LUTINPUT_SELECT, int(lut_id) << 2, 3); + switch (input_id) { + case 0u: { + delta = dot(normal, normalize(half_vector)); +@@ -243,9 +250,9 @@ float lightLutLookup(uint environment_id + + // Sign extend them. Normally bitfieldExtract would do that but it's missing on some versions + // of GLSL so we do it manually +- int se_x = bitfieldExtract(GPUREG_LIGHTi_SPOTDIR_LOW, 0, 13); +- int se_y = bitfieldExtract(GPUREG_LIGHTi_SPOTDIR_LOW, 16, 13); +- int se_z = bitfieldExtract(GPUREG_LIGHTi_SPOTDIR_HIGH, 0, 13); ++ int se_x = int(bitfieldExtractCompat(uint(GPUREG_LIGHTi_SPOTDIR_LOW), 0, 13)); ++ int se_y = int(bitfieldExtractCompat(uint(GPUREG_LIGHTi_SPOTDIR_LOW), 16, 13)); ++ int se_z = int(bitfieldExtractCompat(uint(GPUREG_LIGHTi_SPOTDIR_HIGH), 0, 13)); + + if ((se_x & 0x1000) == 0x1000) se_x |= 0xffffe000; + if ((se_y & 0x1000) == 0x1000) se_y |= 0xffffe000; +@@ -272,9 +279,9 @@ float lightLutLookup(uint environment_id + } + + // 0 = enabled +- if (bitfieldExtract(GPUREG_LIGHTING_LUTINPUT_ABS, 1 + (int(lut_id) << 2), 1) == 0u) { ++ if (bitfieldExtractCompat(GPUREG_LIGHTING_LUTINPUT_ABS, 1 + (int(lut_id) << 2), 1) == 0u) { + // Two sided diffuse +- if (bitfieldExtract(GPUREG_LIGHTi_CONFIG, 1, 1) == 0u) { ++ if (bitfieldExtractCompat(GPUREG_LIGHTi_CONFIG, 1, 1) == 0u) { + delta = max(delta, 0.0); + } else { + delta = abs(delta); +@@ -298,7 +305,7 @@ vec3 rotateVec3ByQuaternion(vec3 v, vec4 + // Implements the following algorthm: https://mathb.in/26766 + void calcLighting(out vec4 primary_color, out vec4 secondary_color) { + uint GPUREG_LIGHTING_ENABLE = readPicaReg(0x008Fu); +- if (bitfieldExtract(GPUREG_LIGHTING_ENABLE, 0, 1) == 0u) { ++ if (bitfieldExtractCompat(GPUREG_LIGHTING_ENABLE, 0, 1) == 0u) { + primary_color = secondary_color = vec4(0.0); + return; + } +@@ -315,7 +322,7 @@ void calcLighting(out vec4 primary_color + GPUREG_LIGHTING_LUTINPUT_ABS = readPicaReg(0x01D0u); + GPUREG_LIGHTING_LUTINPUT_SELECT = readPicaReg(0x01D1u); + +- uint bump_mode = bitfieldExtract(GPUREG_LIGHTING_CONFIG0, 28, 2); ++ uint bump_mode = bitfieldExtractCompat(GPUREG_LIGHTING_CONFIG0, 28, 2); + + // Bump mode is ignored for now because it breaks some games ie. Toad Treasure Tracker + switch (bump_mode) { +@@ -328,15 +335,15 @@ void calcLighting(out vec4 primary_color + vec4 diffuse_sum = vec4(0.0, 0.0, 0.0, 1.0); + vec4 specular_sum = vec4(0.0, 0.0, 0.0, 1.0); + +- uint environment_id = bitfieldExtract(GPUREG_LIGHTING_CONFIG0, 4, 4); +- bool clamp_highlights = bitfieldExtract(GPUREG_LIGHTING_CONFIG0, 27, 1) == 1u; ++ uint environment_id = bitfieldExtractCompat(GPUREG_LIGHTING_CONFIG0, 4, 4); ++ bool clamp_highlights = bitfieldExtractCompat(GPUREG_LIGHTING_CONFIG0, 27, 1) == 1u; + + uint light_id; + vec3 light_vector; + vec3 half_vector; + + for (uint i = 0u; i < GPUREG_LIGHTING_NUM_LIGHTS; i++) { +- light_id = bitfieldExtract(GPUREG_LIGHTING_LIGHT_PERMUTATION, int(i) << 2, 3); ++ light_id = bitfieldExtractCompat(GPUREG_LIGHTING_LIGHT_PERMUTATION, int(i) << 2, 3); + + uint GPUREG_LIGHTi_SPECULAR0 = readPicaReg(0x0140u + (light_id << 4u)); + uint GPUREG_LIGHTi_SPECULAR1 = readPicaReg(0x0141u + (light_id << 4u)); +@@ -348,12 +355,12 @@ void calcLighting(out vec4 primary_color + + float light_distance; + vec3 light_position = vec3( +- decodeFP(bitfieldExtract(GPUREG_LIGHTi_VECTOR_LOW, 0, 16), 5u, 10u), decodeFP(bitfieldExtract(GPUREG_LIGHTi_VECTOR_LOW, 16, 16), 5u, 10u), +- decodeFP(bitfieldExtract(GPUREG_LIGHTi_VECTOR_HIGH, 0, 16), 5u, 10u) ++ decodeFP(bitfieldExtractCompat(GPUREG_LIGHTi_VECTOR_LOW, 0, 16), 5u, 10u), decodeFP(bitfieldExtractCompat(GPUREG_LIGHTi_VECTOR_LOW, 16, 16), 5u, 10u), ++ decodeFP(bitfieldExtractCompat(GPUREG_LIGHTi_VECTOR_HIGH, 0, 16), 5u, 10u) + ); + + // Positional Light +- if (bitfieldExtract(GPUREG_LIGHTi_CONFIG, 0, 1) == 0u) { ++ if (bitfieldExtractCompat(GPUREG_LIGHTi_CONFIG, 0, 1) == 0u) { + light_vector = light_position + v_view; + } + +@@ -369,23 +376,23 @@ void calcLighting(out vec4 primary_color + float NdotL = dot(normal, light_vector); // N dot Li + + // Two sided diffuse +- if (bitfieldExtract(GPUREG_LIGHTi_CONFIG, 1, 1) == 0u) ++ if (bitfieldExtractCompat(GPUREG_LIGHTi_CONFIG, 1, 1) == 0u) + NdotL = max(0.0, NdotL); + else + NdotL = abs(NdotL); + + float geometric_factor; +- bool use_geo_0 = bitfieldExtract(GPUREG_LIGHTi_CONFIG, 2, 1) == 1u; +- bool use_geo_1 = bitfieldExtract(GPUREG_LIGHTi_CONFIG, 3, 1) == 1u; ++ bool use_geo_0 = bitfieldExtractCompat(GPUREG_LIGHTi_CONFIG, 2, 1) == 1u; ++ bool use_geo_1 = bitfieldExtractCompat(GPUREG_LIGHTi_CONFIG, 3, 1) == 1u; + if (use_geo_0 || use_geo_1) { + geometric_factor = dot(half_vector, half_vector); + geometric_factor = geometric_factor == 0.0 ? 0.0 : min(NdotL / geometric_factor, 1.0); + } + + float distance_attenuation = 1.0; +- if (bitfieldExtract(GPUREG_LIGHTING_CONFIG1, 24 + int(light_id), 1) == 0u) { +- uint GPUREG_LIGHTi_ATTENUATION_BIAS = bitfieldExtract(readPicaReg(0x014Au + (light_id << 4u)), 0, 20); +- uint GPUREG_LIGHTi_ATTENUATION_SCALE = bitfieldExtract(readPicaReg(0x014Bu + (light_id << 4u)), 0, 20); ++ if (bitfieldExtractCompat(GPUREG_LIGHTING_CONFIG1, 24 + int(light_id), 1) == 0u) { ++ uint GPUREG_LIGHTi_ATTENUATION_BIAS = bitfieldExtractCompat(readPicaReg(0x014Au + (light_id << 4u)), 0, 20); ++ uint GPUREG_LIGHTi_ATTENUATION_SCALE = bitfieldExtractCompat(readPicaReg(0x014Bu + (light_id << 4u)), 0, 20); + + float distance_attenuation_bias = decodeFP(GPUREG_LIGHTi_ATTENUATION_BIAS, 7u, 12u); + float distance_attenuation_scale = decodeFP(GPUREG_LIGHTi_ATTENUATION_SCALE, 7u, 12u); +@@ -430,8 +437,8 @@ void calcLighting(out vec4 primary_color + specular_sum.rgb += light_factor * clamp_factor * (specular0 + specular1); + } + +- uint fresnel_output1 = bitfieldExtract(GPUREG_LIGHTING_CONFIG0, 2, 1); +- uint fresnel_output2 = bitfieldExtract(GPUREG_LIGHTING_CONFIG0, 3, 1); ++ uint fresnel_output1 = bitfieldExtractCompat(GPUREG_LIGHTING_CONFIG0, 2, 1); ++ uint fresnel_output2 = bitfieldExtractCompat(GPUREG_LIGHTING_CONFIG0, 3, 1); + // Uses parameters from the last light as Fresnel is only applied to the last light + float fresnel_factor; + +diff -rupbN panda3ds.orig/src/host_shaders/opengl_vertex_shader.vert panda3ds/src/host_shaders/opengl_vertex_shader.vert +--- panda3ds.orig/src/host_shaders/opengl_vertex_shader.vert 2024-08-28 21:01:16.674631846 +0000 ++++ panda3ds/src/host_shaders/opengl_vertex_shader.vert 2024-08-28 22:09:19.387098916 +0000 +@@ -1,4 +1,6 @@ +-#version 410 core ++#version 320 es ++precision mediump float; ++precision mediump int; + + layout(location = 0) in vec4 a_coords; + layout(location = 1) in vec4 a_quaternion; +@@ -18,7 +20,7 @@ out vec2 v_texcoord2; + flat out vec4 v_textureEnvColor[6]; + flat out vec4 v_textureEnvBufferColor; + +-out float gl_ClipDistance[2]; ++// out float gl_ClipDistance[2]; + + // TEV uniforms + uniform uint u_textureEnvColor[6]; +@@ -81,8 +83,8 @@ void main() { + ); + + // There's also another, always-on clipping plane based on vertex z +- gl_ClipDistance[0] = -a_coords.z; +- gl_ClipDistance[1] = dot(clipData, a_coords); ++ // gl_ClipDistance[0] = -a_coords.z; ++ // gl_ClipDistance[1] = dot(clipData, a_coords); + + v_quaternion = a_quaternion; + } +diff -rupbN panda3ds.orig/third_party/opengl/opengl.hpp panda3ds/third_party/opengl/opengl.hpp +--- panda3ds.orig/third_party/opengl/opengl.hpp 2024-08-28 21:01:16.706632561 +0000 ++++ panda3ds/third_party/opengl/opengl.hpp 2024-08-28 22:09:19.387098916 +0000 +@@ -602,22 +602,22 @@ namespace OpenGL { + static void disableScissor() { glDisable(GL_SCISSOR_TEST); } + static void enableBlend() { glEnable(GL_BLEND); } + static void disableBlend() { glDisable(GL_BLEND); } +- static void enableLogicOp() { glEnable(GL_COLOR_LOGIC_OP); } +- static void disableLogicOp() { glDisable(GL_COLOR_LOGIC_OP); } ++ static void enableLogicOp() { /* glEnable(GL_COLOR_LOGIC_OP); */ } ++ static void disableLogicOp() { /* glDisable(GL_COLOR_LOGIC_OP); */ } + static void enableDepth() { glEnable(GL_DEPTH_TEST); } + static void disableDepth() { glDisable(GL_DEPTH_TEST); } + static void enableStencil() { glEnable(GL_STENCIL_TEST); } + static void disableStencil() { glDisable(GL_STENCIL_TEST); } + +- static void enableClipPlane(GLuint index) { glEnable(GL_CLIP_DISTANCE0 + index); } +- static void disableClipPlane(GLuint index) { glDisable(GL_CLIP_DISTANCE0 + index); } ++ static void enableClipPlane(GLuint index) { /* glEnable(GL_CLIP_DISTANCE0 + index); */ } ++ static void disableClipPlane(GLuint index) { /* glDisable(GL_CLIP_DISTANCE0 + index); */ } + + static void setDepthFunc(DepthFunc func) { glDepthFunc(static_cast(func)); } + static void setColourMask(GLboolean r, GLboolean g, GLboolean b, GLboolean a) { glColorMask(r, g, b, a); } + static void setDepthMask(GLboolean mask) { glDepthMask(mask); } + + // TODO: Add a proper enum for this +- static void setLogicOp(GLenum op) { glLogicOp(op); } ++ static void setLogicOp(GLenum op) { /* glLogicOp(op); */ } + + enum Primitives { + Triangle = GL_TRIANGLES, diff --git a/projects/ArchR/packages/emulators/libretro/parallel-n64-lr/config/ParaLLEl N64.opt b/projects/ArchR/packages/emulators/libretro/parallel-n64-lr/config/ParaLLEl N64.opt new file mode 100644 index 0000000000..6b9c6179b2 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/parallel-n64-lr/config/ParaLLEl N64.opt @@ -0,0 +1,30 @@ +parallel-n64-64dd-hardware = "disabled" +parallel-n64-alt-map = "disabled" +parallel-n64-angrylion-multithread = "all threads" +parallel-n64-angrylion-overscan = "disabled" +parallel-n64-angrylion-sync = "Low" +parallel-n64-angrylion-vioverlay = "Filtered" +parallel-n64-aspectratiohint = "normal" +parallel-n64-astick-deadzone = "15" +parallel-n64-astick-sensitivity = "100" +parallel-n64-audio-buffer-size = "2048" +parallel-n64-boot-device = "Default" +parallel-n64-bufferswap = "disabled" +parallel-n64-cpucore = "dynamic_recompiler" +parallel-n64-disable_expmem = "enabled" +parallel-n64-dithering = "enabled" +parallel-n64-filtering = "automatic" +parallel-n64-framerate = "original" +parallel-n64-gfxplugin = "auto" +parallel-n64-gfxplugin-accuracy = "low" +parallel-n64-pak1 = "none" +parallel-n64-pak2 = "none" +parallel-n64-pak3 = "none" +parallel-n64-pak4 = "none" +parallel-n64-polyoffset-factor = "-3.0" +parallel-n64-polyoffset-units = "-3.0" +parallel-n64-rspplugin = "auto" +parallel-n64-screensize = "640x480" +parallel-n64-send_allist_to_hle_rsp = "disabled" +parallel-n64-vcache-vbo = "disabled" +parallel-n64-virefresh = "auto" diff --git a/projects/ArchR/packages/emulators/libretro/parallel-n64-lr/package.mk b/projects/ArchR/packages/emulators/libretro/parallel-n64-lr/package.mk new file mode 100644 index 0000000000..e9fc63cbde --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/parallel-n64-lr/package.mk @@ -0,0 +1,39 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="parallel-n64-lr" +PKG_VERSION="f8605345e13c018a30c8f4ed03c05d8fc8f70be8" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/parallel-n64" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain core-info" +PKG_LONGDESC="Optimized/rewritten Nintendo 64 emulator made specifically for Libretro. Originally based on Mupen64 Plus." +PKG_TOOLCHAIN="make" +PKG_BUILD_FLAGS="-lto" + +if [ "${OPENGL_SUPPORT}" = "yes" ] && [ ! "${PREFER_GLES}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" + PKG_MAKE_OPTS_TARGET+=" GLES=0 GL_LIB=\"-lGL\"" +elif [ "${OPENGLES_SUPPORT}" = yes ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" + PKG_MAKE_OPTS_TARGET+=" GLES=1 GL_LIB=\"-lGLESv2\"" +fi + +pre_configure_target() { + if [ "${ARCH}" = "aarch64" ]; then + # This is only needed for armv8.2-a targets where we don't use this flag + # as it prohibits the use of LSE-instructions, this is a package bug most likely + export CFLAGS="${CFLAGS} -mno-outline-atomics -std=gnu17" + export CXXFLAGS="${CXXFLAGS} -mno-outline-atomics" + PKG_MAKE_OPTS_TARGET+=" platform=${DEVICE}" + fi +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp parallel_n64_libretro.so ${INSTALL}/usr/lib/libretro/ + + mkdir -p ${INSTALL}/usr/config/retroarch + cp -rf ${PKG_DIR}/config/* ${INSTALL}/usr/config/retroarch/ +} + diff --git a/projects/ArchR/packages/emulators/libretro/parallel-n64-lr/patches/001-gcc-13.patch b/projects/ArchR/packages/emulators/libretro/parallel-n64-lr/patches/001-gcc-13.patch new file mode 100644 index 0000000000..1e6045345f --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/parallel-n64-lr/patches/001-gcc-13.patch @@ -0,0 +1,32 @@ +diff --git a/mupen64plus-core/src/r4300/r4300.c b/mupen64plus-core/src/r4300/r4300.c +index 744198d6..73cb1f27 100644 +--- a/mupen64plus-core/src/r4300/r4300.c ++++ b/mupen64plus-core/src/r4300/r4300.c +@@ -50,8 +50,8 @@ + unsigned int r4300emu = 0; + unsigned int count_per_op = COUNT_PER_OP_DEFAULT; + unsigned int llbit; +-int stop; + #if NEW_DYNAREC < NEW_DYNAREC_ARM ++int stop; + int64_t reg[32], hi, lo; + uint32_t next_interrupt; + struct precomp_instr *PC; +diff --git a/mupen64plus-rsp-paraLLEl/rsp_disasm.cpp b/mupen64plus-rsp-paraLLEl/rsp_disasm.cpp +index 9b1f6eda..bbb84e74 100644 +--- a/mupen64plus-rsp-paraLLEl/rsp_disasm.cpp ++++ b/mupen64plus-rsp-paraLLEl/rsp_disasm.cpp +@@ -1,5 +1,6 @@ + #include "rsp_disasm.hpp" + #include ++#include + + namespace RSP + { +@@ -582,4 +583,4 @@ std::string disassemble(uint32_t pc, uint32_t instr) + + return "???"; + } +-} +\ No newline at end of file ++} diff --git a/projects/ArchR/packages/emulators/libretro/parallel-n64-lr/patches/002-rk3588-make.patch b/projects/ArchR/packages/emulators/libretro/parallel-n64-lr/patches/002-rk3588-make.patch new file mode 100644 index 0000000000..f459bac308 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/parallel-n64-lr/patches/002-rk3588-make.patch @@ -0,0 +1,27 @@ +diff --git a/Makefile b/Makefile +index 8a719d55..0872e619 100644 +--- a/Makefile ++++ b/Makefile +@@ -60,6 +60,8 @@ else ifneq (,$(findstring rpi,$(platform))) + override platform += unix + else ifneq (,$(findstring odroid,$(platform))) + override platform += unix ++else ifneq (,$(findstring @DEVICE@,$(platform))) ++ override platform += unix + endif + + # system platform +@@ -171,6 +173,13 @@ ifneq (,$(findstring unix,$(platform))) + + endif + ++ #@DEVICE@ ++ ifneq (,$(findstring @DEVICE@,$(platform))) ++ TARGET := $(TARGET_NAME)_libretro.so ++ CPUFLAGS += -DARM_FIX -DCLASSIC -DARM64 ++ WITH_DYNAREC = aarch64 ++ endif ++ + # ODROIDs + ifneq (,$(findstring odroid,$(platform))) + BOARD ?= $(shell cat /proc/cpuinfo | grep -i odroid | awk '{print $$3}') diff --git a/projects/ArchR/packages/emulators/libretro/parallel-n64-lr/patches/003-libretro-cleanup.patch b/projects/ArchR/packages/emulators/libretro/parallel-n64-lr/patches/003-libretro-cleanup.patch new file mode 100644 index 0000000000..f02b641b54 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/parallel-n64-lr/patches/003-libretro-cleanup.patch @@ -0,0 +1,56 @@ +diff --git a/libretro/libretro.c b/libretro/libretro.c +index 16525703..0922084c 100644 +--- a/libretro/libretro.c ++++ b/libretro/libretro.c +@@ -406,10 +406,10 @@ static void setup_variables(void) + "Send audio lists to HLE RSP; disabled|enabled" }, + { "parallel-n64-gfxplugin", + "GFX Plugin; auto" +-#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) + "|glide64|gln64|rice" +-#endif ++#ifdef HAVE_THR_AL + "|angrylion" ++#endif + #ifdef HAVE_PARALLEL + "|parallel" + #endif +@@ -424,26 +424,23 @@ static void setup_variables(void) + "|parallel" + #endif + }, +-#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) || defined(HAVE_PARALLEL) + { "parallel-n64-screensize", +-#ifdef CLASSIC +- "Resolution (restart); 320x240|640x480|960x720|1280x960|1440x1080|1600x1200|1920x1440|2240x1680|2880x2160|5760x4320" }, +-#else +- "Resolution (restart); 640x480|960x720|1280x960|1440x1080|1600x1200|1920x1440|2240x1680|2880x2160|5760x4320|320x240" }, +-#endif ++ "Resolution (restart); 320x240|640x480|960x720|1440x1080" }, + { "parallel-n64-aspectratiohint", + "Aspect ratio hint (reinit); normal|widescreen" }, + { "parallel-n64-filtering", + "(Glide64) Texture Filtering; automatic|N64 3-point|bilinear|nearest" }, ++#ifdef HAVE_THR_AL + { "parallel-n64-dithering", + "(Angrylion) Dithering; enabled|disabled" }, ++#endif + { "parallel-n64-polyoffset-factor", + "(Glide64) Polygon Offset Factor; -3.0|-2.5|-2.0|-1.5|-1.0|-0.5|0.0|0.5|1.0|1.5|2.0|2.5|3.0|3.5|4.0|4.5|5.0|-3.5|-4.0|-4.5|-5.0" + }, + { "parallel-n64-polyoffset-units", + "(Glide64) Polygon Offset Units; -3.0|-2.5|-2.0|-1.5|-1.0|-0.5|0.0|0.5|1.0|1.5|2.0|2.5|3.0|3.5|4.0|4.5|5.0|-3.5|-4.0|-4.5|-5.0" + }, +-#endif ++#ifdef HAVE_THR_AL + { "parallel-n64-angrylion-vioverlay", + "(Angrylion) VI Overlay; Filtered|AA+Blur|AA+Dedither|AA only|Unfiltered|Depth|Coverage" + }, +@@ -454,6 +451,7 @@ static void setup_variables(void) + "(Angrylion) Multi-threading; all threads|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33|34|35|36|37|38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|56|57|58|59|60|61|62|63" }, + { "parallel-n64-angrylion-overscan", + "(Angrylion) Hide overscan; disabled|enabled" }, ++#endif + { "parallel-n64-virefresh", + "VI Refresh (Overclock); auto|1500|2200" }, + { "parallel-n64-bufferswap", diff --git a/projects/ArchR/packages/emulators/libretro/pcsx_rearmed-lr/package.mk b/projects/ArchR/packages/emulators/libretro/pcsx_rearmed-lr/package.mk new file mode 100644 index 0000000000..0ff8bdec57 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/pcsx_rearmed-lr/package.mk @@ -0,0 +1,46 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2020 Trond Haugland (trondah@gmail.com) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="pcsx_rearmed-lr" +PKG_VERSION="228c14e10e9a8fae0ead8adf30daad2cdd8655b9" +PKG_ARCH="arm aarch64" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/pcsx_rearmed" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="ARM optimized PCSX fork" +PKG_TOOLCHAIN="manual" + +pre_configure_target() { + sed -i 's/\-O[23]/-Ofast/' ${PKG_BUILD}/Makefile + export CFLAGS="${CFLAGS} -flto -fipa-pta" + export CXXFLAGS="${CXXFLAGS} -flto -fipa-pta" + export LDFLAGS="${LDFLAGS} -flto -fipa-pta" +} + +make_target() { + cd ${PKG_BUILD} + make -f Makefile.libretro GIT_VERSION=${PKG_VERSION} platform=${DEVICE} +} + +makeinstall_target32() { + case ${ARCH} in + aarch64) + if [ "${ENABLE_32BIT}" == "true" ] + then + cp -vP ${ROOT}/build.${DISTRO}-${DEVICE}.arm/install_pkg/${PKG_NAME}-*/usr/lib/libretro/${1}_libretro.so ${INSTALL}/usr/lib/libretro/${1}32_libretro.so + fi + ;; + esac +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp pcsx_rearmed_libretro.so ${INSTALL}/usr/lib/libretro/ + case ${TARGET_ARCH} in + aarch64) + makeinstall_target32 pcsx_rearmed + ;; + esac +} diff --git a/projects/ArchR/packages/emulators/libretro/pcsx_rearmed-lr/patches/aarch64/pcsx_rearmed-add_platform.patch b/projects/ArchR/packages/emulators/libretro/pcsx_rearmed-lr/patches/aarch64/pcsx_rearmed-add_platform.patch new file mode 100644 index 0000000000..e14f8bcf3c --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/pcsx_rearmed-lr/patches/aarch64/pcsx_rearmed-add_platform.patch @@ -0,0 +1,19 @@ +diff -rupN pcsx_rearmed.orig/Makefile.libretro pcsx_rearmed/Makefile.libretro +--- pcsx_rearmed.orig/Makefile.libretro 2022-08-16 15:19:42.928678600 +0200 ++++ pcsx_rearmed/Makefile.libretro 2022-08-17 18:08:41.346728698 +0200 +@@ -385,6 +385,15 @@ else ifeq ($(platform), rpi4_64) + fpic := -fPIC + CFLAGS += -march=armv8-a+crc+simd -mtune=cortex-a72 -ftree-vectorize + ++else ifeq ($(platform), @DEVICE@) ++ TARGET := $(TARGET_NAME)_libretro.so ++ fpic := -fPIC ++ ARCH = arm64 ++ DYNAREC = ari64 ++ BUILTIN_GPU = neon ++ HAVE_NEON = 1 ++ CFLAGS += -ftree-vectorize ++ + # Classic Platforms #################### + # Platform affix = classic__<µARCH> + # Help at https://modmyclassic.com/comp diff --git a/projects/ArchR/packages/emulators/libretro/pcsx_rearmed-lr/patches/aarch64/pcsx_rearmed-patch-enable-threaded-rendering.patch b/projects/ArchR/packages/emulators/libretro/pcsx_rearmed-lr/patches/aarch64/pcsx_rearmed-patch-enable-threaded-rendering.patch new file mode 100644 index 0000000000..d69f1c880a --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/pcsx_rearmed-lr/patches/aarch64/pcsx_rearmed-patch-enable-threaded-rendering.patch @@ -0,0 +1,13 @@ +diff --git a/frontend/libretro_core_options.h b/frontend/libretro_core_options.h +index 3e1daf2..06702a1 100644 +--- a/frontend/libretro_core_options.h ++++ b/frontend/libretro_core_options.h +@@ -848,7 +848,7 @@ struct retro_core_option_definition option_defs_us[] = { + { "async", NULL }, + { NULL, NULL}, + }, +- "disabled", ++ "sync", + }, + #endif + diff --git a/projects/ArchR/packages/emulators/libretro/pcsx_rearmed-lr/patches/arm/pcsx_rearmed-add_platform.patch b/projects/ArchR/packages/emulators/libretro/pcsx_rearmed-lr/patches/arm/pcsx_rearmed-add_platform.patch new file mode 100644 index 0000000000..524aca8bab --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/pcsx_rearmed-lr/patches/arm/pcsx_rearmed-add_platform.patch @@ -0,0 +1,20 @@ +diff -rupN pcsx_rearmed.orig/Makefile.libretro pcsx_rearmed/Makefile.libretro +--- pcsx_rearmed.orig/Makefile.libretro 2022-08-16 15:19:42.928678600 +0200 ++++ pcsx_rearmed/Makefile.libretro 2022-08-17 17:51:57.256712172 +0200 +@@ -385,6 +385,16 @@ else ifeq ($(platform), rpi4_64) + fpic := -fPIC + CFLAGS += -march=armv8-a+crc+simd -mtune=cortex-a72 -ftree-vectorize + ++else ifeq ($(platform), @DEVICE@) ++ TARGET := $(TARGET_NAME)_libretro.so ++ fpic := -fPIC ++ CFLAGS += -marm ++ HAVE_NEON = 1 ++ HAVE_NEON_ASM = 1 ++ ARCH = arm ++ BUILTIN_GPU = neon ++ DYNAREC = ari64 ++ + # Classic Platforms #################### + # Platform affix = classic__<µARCH> + # Help at https://modmyclassic.com/comp diff --git a/projects/ArchR/packages/emulators/libretro/pcsx_rearmed-lr/patches/arm/pcsx_rearmed-patch-enable-threaded-rendering.patch b/projects/ArchR/packages/emulators/libretro/pcsx_rearmed-lr/patches/arm/pcsx_rearmed-patch-enable-threaded-rendering.patch new file mode 100644 index 0000000000..d69f1c880a --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/pcsx_rearmed-lr/patches/arm/pcsx_rearmed-patch-enable-threaded-rendering.patch @@ -0,0 +1,13 @@ +diff --git a/frontend/libretro_core_options.h b/frontend/libretro_core_options.h +index 3e1daf2..06702a1 100644 +--- a/frontend/libretro_core_options.h ++++ b/frontend/libretro_core_options.h +@@ -848,7 +848,7 @@ struct retro_core_option_definition option_defs_us[] = { + { "async", NULL }, + { NULL, NULL}, + }, +- "disabled", ++ "sync", + }, + #endif + diff --git a/projects/ArchR/packages/emulators/libretro/picodrive-lr/package.mk b/projects/ArchR/packages/emulators/libretro/picodrive-lr/package.mk new file mode 100644 index 0000000000..f96f3a1f9b --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/picodrive-lr/package.mk @@ -0,0 +1,31 @@ +PKG_NAME="picodrive-lr" +PKG_VERSION="c4332d608c1005a46ce51236ade9894e0d32e52b" +PKG_LICENSE="MAME" +PKG_SITE="https://github.com/libretro/picodrive" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Libretro implementation of PicoDrive. (Sega Megadrive/Genesis/Sega Master System/Sega GameGear/Sega CD/32X)" +GET_HANDLER_SUPPORT="git" +PKG_BUILD_FLAGS="-gold" +PKG_TOOLCHAIN="make" + +PKG_PATCH_DIRS="${PROJECT}" + +pre_configure_target() { +export CFLAGS="${CFLAGS} -Wno-error=incompatible-pointer-types" +} + +configure_target() { + : +} + +make_target() { + cd ${PKG_BUILD} +# ${PKG_BUILD}/configure --platform=generic + make -f Makefile.libretro +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp ${PKG_BUILD}/picodrive_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/play-lr/package.mk b/projects/ArchR/packages/emulators/libretro/play-lr/package.mk new file mode 100644 index 0000000000..11d90b151e --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/play-lr/package.mk @@ -0,0 +1,43 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="play-lr" +PKG_VERSION="b3be9d4840ab947448aedf2228496510257726ac" +PKG_LICENSE="BSDv2" +PKG_SITE="https://github.com/jpd002/Play-" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain libevdev zstd" +PKG_LONGDESC="Play! is an attempt to create a PlayStation 2 emulator for Windows, macOS, UNIX, Android & iOS platforms." +PKG_TOOLCHAIN="cmake" + +if [ "${OPENGL_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL} glu" +fi + +if [ "${OPENGLES_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" +fi + +case ${TARGET_ARCH} in + aarch64) + PKG_CMAKE_OPTS_TARGET+=" -DUSE_GLEW=off \ + -DUSE_GLES=on + -DTARGET_PLATFORM_UNIX_AARCH64=yes" + ;; +esac + +PKG_CMAKE_OPTS_TARGET+=" -DBUILD_LIBRETRO_CORE=yes \ + -DBUILD_PLAY=off \ + -DBUILD_TESTS=no \ + -DENABLE_AMAZON_S3=no \ + -DCMAKE_BUILD_TYPE=Release" + +pre_make_target() { + find ${PKG_BUILD} -name flags.make -exec sed -i "s:isystem :I:g" \{} \; + find ${PKG_BUILD} -name build.ninja -exec sed -i "s:isystem :I:g" \{} \; +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp ${PKG_BUILD}/.${TARGET_NAME}/Source/ui_libretro/play_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/play-lr/patches/000-fix-build.patch b/projects/ArchR/packages/emulators/libretro/play-lr/patches/000-fix-build.patch new file mode 100644 index 0000000000..b51e897223 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/play-lr/patches/000-fix-build.patch @@ -0,0 +1,13 @@ +diff --git a/Source/ui_libretro/CMakeLists.txt b/Source/ui_libretro/CMakeLists.txt +index cc195c1a..cf1acb44 100644 +--- a/Source/ui_libretro/CMakeLists.txt ++++ b/Source/ui_libretro/CMakeLists.txt +@@ -50,7 +50,7 @@ elseif(TARGET_PLATFORM_IOS) + list(APPEND PROJECT_LIBS "-ObjC -lsqlite3 -framework OpenGLES") + elseif(TARGET_PLATFORM_UNIX) + list(APPEND PROJECT_LIBS "-static-libgcc") +- list(APPEND PROJECT_LIBS "-static-libstdc++") ++# list(APPEND PROJECT_LIBS "-static-libstdc++") + endif() + + if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 8 AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9) diff --git a/projects/ArchR/packages/emulators/libretro/pokemini-lr/package.mk b/projects/ArchR/packages/emulators/libretro/pokemini-lr/package.mk new file mode 100644 index 0000000000..b17c8cf38a --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/pokemini-lr/package.mk @@ -0,0 +1,35 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="pokemini-lr" +PKG_VERSION="19095803f1434eb980db6e4004187a4b786e20b6" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/libretro/pokemini" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Obscure nintendo AMD64 emulator (functional,no color files or savestates currently)" + +PKG_TOOLCHAIN="make" +PKG_PATCH_DIRS+="${DEVICE}" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp pokemini_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/potator-lr/package.mk b/projects/ArchR/packages/emulators/libretro/potator-lr/package.mk new file mode 100644 index 0000000000..be78651482 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/potator-lr/package.mk @@ -0,0 +1,18 @@ +PKG_NAME="potator-lr" +PKG_VERSION="ad87bc6068ef126e48339b440465fb0bf5a2794f" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/potator" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="A Watara Supervision Emulator based on Normmatt version." +PKG_TOOLCHAIN="make" + + +make_target() { + make -C platform/libretro/ platform=aarch64 +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp platform/libretro/potator_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/ppsspp-lr/package.mk b/projects/ArchR/packages/emulators/libretro/ppsspp-lr/package.mk new file mode 100644 index 0000000000..3727578367 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/ppsspp-lr/package.mk @@ -0,0 +1,108 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="ppsspp-lr" +PKG_VERSION="e49c0bd8836a8a8f678565357773386f1174d3f5" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/hrydgard/ppsspp" +PKG_URL="https://github.com/hrydgard/ppsspp.git" +PKG_DEPENDS_TARGET="toolchain SDL2 libzip zstd" +PKG_LONGDESC="A PSP emulator for Android, Windows, Mac, Linux and Blackberry 10, written in C++." +GET_HANDLER_SUPPORT="git" + + +pre_configure_target() { + PKG_LIBNAME="ppsspp_libretro.so" + PKG_LIBPATH="lib/${PKG_LIBNAME}" + + + if [ ! "${OPENGL}" = "no" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd glew glslang" + PKG_CMAKE_OPTS_TARGET+=" -DUSING_FBDEV=OFF \ + -DUSING_GLES2=OFF" + fi + + if [ "${OPENGLES_SUPPORT}" = yes ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" + PKG_CMAKE_OPTS_TARGET+=" -DUSING_FBDEV=ON \ + -DUSING_EGL=OFF \ + -DUSING_GLES2=ON \ + -DVULKAN=OFF \ + -DUSE_VULKAN_DISPLAY_KHR=OFF\ + -DUSING_X11_VULKAN=OFF" + fi + + if [ "${VULKAN_SUPPORT}" = "yes" ] + then + PKG_DEPENDS_TARGET+=" ${VULKAN}" + PKG_CMAKE_OPTS_TARGET+=" -DUSE_VULKAN_DISPLAY_KHR=ON \ + -DVULKAN=ON \ + -DEGL_NO_X11=1 \ + -DMESA_EGL_NO_X11_HEADERS=1" + else + PKG_CMAKE_OPTS_TARGET+=" -DVULKAN=OFF" + fi + + if [ "${DISPLAYSERVER}" = "wl" ]; then + PKG_DEPENDS_TARGET+=" wayland ${WINDOWMANAGER}" + PKG_CMAKE_OPTS_TARGET+=" -DUSE_WAYLAND_WSI=ON" + else + PKG_CMAKE_OPTS_TARGET+=" -DUSE_WAYLAND_WSI=OFF" + fi + + case ${TARGET_ARCH} in + aarch64) + PKG_CMAKE_OPTS_TARGET+=" -DFORCED_CPU=aarch64" + ;; + esac + + PKG_CMAKE_OPTS_TARGET+=" -DUSE_SYSTEM_FFMPEG=OFF \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_SYSTEM_NAME=Linux \ + -DBUILD_SHARED_LIBS=OFF \ + -DANDROID=OFF \ + -DWIN32=OFF \ + -DAPPLE=OFF \ + -DLIBRETRO=ON \ + -DCMAKE_CROSSCOMPILING=ON \ + -DUSING_QT_UI=OFF \ + -DUNITTEST=OFF \ + -DSIMULATOR=OFF \ + -DHEADLESS=OFF \ + -DUSE_DISCORD=OFF" +} + +pre_make_target() { + # This script should work on any board that has issues with system ffmpeg in ppsspp + if [ "${TARGET_ARCH}" = "aarch64" ]; then + sed -i "s|aarch64-linux-gnu-|${TARGET_PREFIX}|g" ${PKG_BUILD}/ffmpeg/linux_arm64.sh + (cd ${PKG_BUILD}/ffmpeg && ./linux_arm64.sh) + fi + + # fix cross compiling + find ${PKG_BUILD} -name flags.make -exec sed -i "s:isystem :I:g" \{} \; + find ${PKG_BUILD} -name build.ninja -exec sed -i "s:isystem :I:g" \{} \; +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp ${PKG_LIBPATH} ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/ppsspp-lr/patches/000-armv8-build-fix.patch b/projects/ArchR/packages/emulators/libretro/ppsspp-lr/patches/000-armv8-build-fix.patch new file mode 100644 index 0000000000..f59ce50a92 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/ppsspp-lr/patches/000-armv8-build-fix.patch @@ -0,0 +1,33 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 90cd57ace..2ace6b70a 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -58,6 +58,10 @@ if(CMAKE_SYSTEM_PROCESSOR) + set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -target armv7a-none-linux-android") + endif() + endif() ++ if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^armv8") ++ add_compile_options(-march=armv8-a+crc -mtune=cortex-a53 -mfloat-abi=hard -mfpu=neon-fp-armv8 -fomit-frame-pointer) ++ add_definitions(-DPPSSPP_ARCH_ARM_NEON=1 -DPPSSPP_ARCH_ARMV8=1) ++ endif() + elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^amd64" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "^x86_64" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "^AMD64") + set(X86_DEVICE ON) + set(X86_64_DEVICE ON) +diff --git a/Common/ArmCPUDetect.cpp b/Common/ArmCPUDetect.cpp +index 437bd3158..d46cf19db 100644 +--- a/Common/ArmCPUDetect.cpp ++++ b/Common/ArmCPUDetect.cpp +@@ -337,6 +337,13 @@ void CPUInfo::Detect() + bNEON = true; + bASIMD = true; + #endif ++ ++#if PPSSPP_ARCH(ARMV8) ++ bNEON = true; ++ bASIMD = true; ++ bFP = true; ++#endif ++ + } + + // Turn the cpu info into a string we can show diff --git a/projects/ArchR/packages/emulators/libretro/ppsspp-lr/patches/001-x86_64-build-fix.patch b/projects/ArchR/packages/emulators/libretro/ppsspp-lr/patches/001-x86_64-build-fix.patch new file mode 100644 index 0000000000..e4aec51bab --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/ppsspp-lr/patches/001-x86_64-build-fix.patch @@ -0,0 +1,12 @@ +diff -Naur ppsspp-00051fd/ext/glew/glew.c ppsspp-00051fd.patch/ext/glew/glew.c +--- ppsspp-00051fd/ext/glew/glew.c 2018-12-24 10:48:13.869315087 +0100 ++++ ppsspp-00051fd.patch/ext/glew/glew.c 2018-12-24 10:50:23.969537401 +0100 +@@ -20872,8 +20872,6 @@ + return r; + #elif defined(_WIN32) + return wglewInit(); +-#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) /* _UNIX */ +- return glxewInit(); + #else + return r; + #endif /* _WIN32 */ diff --git a/projects/ArchR/packages/emulators/libretro/ppsspp-lr/patches/002-psp-path.patch b/projects/ArchR/packages/emulators/libretro/ppsspp-lr/patches/002-psp-path.patch new file mode 100644 index 0000000000..f9ce20c81c --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/ppsspp-lr/patches/002-psp-path.patch @@ -0,0 +1,18 @@ +diff --git a/Core/System.cpp b/Core/System.cpp +index cb6fc34fa..829a5795a 100644 +--- a/Core/System.cpp ++++ b/Core/System.cpp +@@ -619,12 +619,7 @@ std::string PSP_GetLoading() { + Path GetSysDirectory(PSPDirectories directoryType) { + const Path &memStickDirectory = g_Config.memStickDirectory; + Path pspDirectory; +- if (!strcasecmp(memStickDirectory.GetFilename().c_str(), "PSP")) { +- // Let's strip this off, to easily allow choosing a root directory named "PSP" on Android. +- pspDirectory = memStickDirectory; +- } else { +- pspDirectory = memStickDirectory / "PSP"; +- } ++ pspDirectory = memStickDirectory / "PSP"; + + switch (directoryType) { + case DIRECTORY_PSP: diff --git a/projects/ArchR/packages/emulators/libretro/ppsspp-lr/patches/004-build-flags.patch b/projects/ArchR/packages/emulators/libretro/ppsspp-lr/patches/004-build-flags.patch new file mode 100644 index 0000000000..2daa6ced77 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/ppsspp-lr/patches/004-build-flags.patch @@ -0,0 +1,10 @@ +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -395,6 +395,7 @@ + # NEON optimizations in libpng17 seem to cause PNG load errors, see #14485. + add_compile_definitions(PNG_ARM_NEON_OPT=0) + ++ add_compile_options(-Ofast -fno-tree-slp-vectorize) + add_compile_options(-Wall -Werror=return-type -Wno-unused-function -Wno-sign-compare -Wno-unused-but-set-variable "$<$:-Wno-reorder>" -Wno-unknown-pragmas -Wno-unused-value -Wno-unused-variable) + if(NOT CLANG) + # This one is very useful but has many false positives. diff --git a/projects/ArchR/packages/emulators/libretro/ppsspp-lr/patches/005-fix-atomics-arm64.patch b/projects/ArchR/packages/emulators/libretro/ppsspp-lr/patches/005-fix-atomics-arm64.patch new file mode 100644 index 0000000000..397f36496b --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/ppsspp-lr/patches/005-fix-atomics-arm64.patch @@ -0,0 +1,10 @@ +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -396,6 +396,7 @@ + add_compile_definitions(PNG_ARM_NEON_OPT=0) + + add_compile_options(-Ofast -fno-tree-slp-vectorize) ++ add_compile_options(-mno-outline-atomics) + add_compile_options(-Wall -Werror=return-type -Wno-unused-function -Wno-sign-compare -Wno-unused-but-set-variable "$<$:-Wno-reorder>" -Wno-unknown-pragmas -Wno-unused-value -Wno-unused-variable) + if(NOT CLANG) + # This one is very useful but has many false positives. diff --git a/projects/ArchR/packages/emulators/libretro/ppsspp-lr/patches/006-fix-ffmpeg-atomics.patch b/projects/ArchR/packages/emulators/libretro/ppsspp-lr/patches/006-fix-ffmpeg-atomics.patch new file mode 100644 index 0000000000..e5577de6e2 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/ppsspp-lr/patches/006-fix-ffmpeg-atomics.patch @@ -0,0 +1,11 @@ +--- a/ffmpeg/linux_arm64.sh ++++ b/ffmpeg/linux_arm64.sh +@@ -86,7 +86,7 @@ + ./configure --target-os=linux \ + --prefix=./linux/aarch64 \ + ${GENERAL} \ +- --extra-cflags=" -O3 -fasm -Wno-psabi -fno-short-enums -fno-strict-aliasing -finline-limit=300 " \ ++ --extra-cflags=" -O3 -fasm -Wno-psabi -mno-outline-atomics -fno-short-enums -fno-strict-aliasing -finline-limit=300 " \ + --disable-shared \ + --enable-static \ + --enable-zlib \ diff --git a/projects/ArchR/packages/emulators/libretro/prboom-lr/package.mk b/projects/ArchR/packages/emulators/libretro/prboom-lr/package.mk new file mode 100644 index 0000000000..ae22be85cc --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/prboom-lr/package.mk @@ -0,0 +1,32 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="prboom-lr" +PKG_VERSION="9d412db570d3291829b308e6d1ac17f04acdda17" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/libretro-prboom" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="libretro implementation of Doom" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp prboom_libretro.so ${INSTALL}/usr/lib/libretro/prboom_libretro.so +} diff --git a/projects/ArchR/packages/emulators/libretro/prosystem-lr/package.mk b/projects/ArchR/packages/emulators/libretro/prosystem-lr/package.mk new file mode 100644 index 0000000000..6dea030719 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/prosystem-lr/package.mk @@ -0,0 +1,34 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="prosystem-lr" +PKG_VERSION="acae250da8d98b8b9707cd499e2a0bf6d8500652" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/prosystem-libretro" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Port of ProSystem to libretro." + +PKG_TOOLCHAIN="make" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp prosystem_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/puae-lr/package.mk b/projects/ArchR/packages/emulators/libretro/puae-lr/package.mk new file mode 100644 index 0000000000..3c9f9d8f7f --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/puae-lr/package.mk @@ -0,0 +1,41 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="puae-lr" +PKG_VERSION="0043cf9c061bd9b81dbc1869c2761017139cfc63" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/libretro/libretro-uae" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="WIP libretro port of UAE (P-UAE and libco) Expect bugs" +PKG_TOOLCHAIN="make" + +pre_configure_target() { + if [ "${ARCH}" == "arm" ]; then + CFLAGS="${CFLAGS} -DARM -marm" + fi +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp puae_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/puae2021-lr/package.mk b/projects/ArchR/packages/emulators/libretro/puae2021-lr/package.mk new file mode 100644 index 0000000000..1882554baa --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/puae2021-lr/package.mk @@ -0,0 +1,42 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# Copyright (C) 2023-present Ilmenit +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="puae2021-lr" +PKG_VERSION="87cbcb27809c2800418bf81da21a766de28029a0" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/libretro/libretro-uae" +PKG_URL="${PKG_SITE}.git" +PKG_GIT_CLONE_BRANCH="2.6.1" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="PUAE 2021 libretro port of UAE" +PKG_TOOLCHAIN="make" + +pre_configure_target() { + if [ "${ARCH}" == "arm" ]; then + CFLAGS="${CFLAGS} -DARM -marm" + fi +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp puae2021_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/px68k-lr/package.mk b/projects/ArchR/packages/emulators/libretro/px68k-lr/package.mk new file mode 100644 index 0000000000..b57f2ff7d6 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/px68k-lr/package.mk @@ -0,0 +1,35 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="px68k-lr" +PKG_VERSION="9dfa6abc25ddd6e597790f7a535cd0a1d7f9c385" +PKG_LICENSE="Unknown" +PKG_SITE="https://github.com/libretro/px68k-libretro" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Portable SHARP X68000 Emulator for PSP, Android and other platforms" +PKG_PATCH_DIRS+="${DEVICE}" + +PKG_TOOLCHAIN="make" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp px68k_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/quasi88-lr/package.mk b/projects/ArchR/packages/emulators/libretro/quasi88-lr/package.mk new file mode 100644 index 0000000000..0093af8787 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/quasi88-lr/package.mk @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2019-present asakous (https://github.com/asakous) + +PKG_NAME="quasi88-lr" +PKG_VERSION="42be798db5585f62b4bd34ce49dd1e8063c9d7c1" +PKG_LICENSE="BSD3" +PKG_SITE="https://github.com/libretro/quasi88-libretro" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="A port of QUASI88, a PC-8800 series emulator by Showzoh Fukunaga, to the libretro API" +PKG_TOOLCHAIN="make" +GET_HANDLER_SUPPORT="git" + +pre_configure_target() { + CFLAGS="${CFLAGS} -std=gnu17" +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp quasi88_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/quicknes-lr/package.mk b/projects/ArchR/packages/emulators/libretro/quicknes-lr/package.mk new file mode 100644 index 0000000000..283f555044 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/quicknes-lr/package.mk @@ -0,0 +1,42 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="quicknes-lr" +PKG_VERSION="dbf19f73e3eb9701d1c7f5898f57c097e05c9fbd" +PKG_LICENSE="LGPLv2.1+" +PKG_SITE="https://github.com/libretro/QuickNES_Core" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="The QuickNES core library, originally by Shay Green, heavily modified" +PKG_BUILD_FLAGS="-gold" + +PKG_TOOLCHAIN="make" + +make_target() { + VERSION='GIT_VERSION ?= ' + VERSION+=${PKG_VERSION:0:7} + sed -i "s/GIT_VERSION ?= \" \$(shell git describe --dirty --always --tags)\"/${VERSION}/g" ${PKG_BUILD}/Makefile + make +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp quicknes_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/race-lr/package.mk b/projects/ArchR/packages/emulators/libretro/race-lr/package.mk new file mode 100644 index 0000000000..141a5fa8a7 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/race-lr/package.mk @@ -0,0 +1,34 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="race-lr" +PKG_VERSION="171950ea64c96ead503340ed60fa7ba18f56325c" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/RACE" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="This is the RACE NGPC emulator modified by theelf to run on the PSP." +PKG_TOOLCHAIN="make" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp race_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/autostart/003-logging b/projects/ArchR/packages/emulators/libretro/retroarch/autostart/003-logging new file mode 100755 index 0000000000..cfa5b7e723 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/autostart/003-logging @@ -0,0 +1,20 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +tocon "Configuring logging..." + +if [ ! -d "/var/log/retroarch" ] +then + mkdir /var/log/retroarch +fi + +if [ -d "/storage/.config/retroarch/logs" ] +then + rm -rf /storage/.config/retroarch/logs +fi + +ln -s /var/log/retroarch /storage/.config/retroarch/logs diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/modprobe.d/usbhid.conf b/projects/ArchR/packages/emulators/libretro/retroarch/modprobe.d/usbhid.conf new file mode 100644 index 0000000000..a93b4222fe --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/modprobe.d/usbhid.conf @@ -0,0 +1,51 @@ +# Juyao +options usbhid quirks=0x0314:0x0326:0x040 +options usbhid quirks=0x0314:0x0328:0x040 + +# 4NES4SNES +options usbhid quirks=0x1781:0x0A9D:0x040 + +# Retrolink SNES +options usbhid quirks=0x1292:0x5346:0x040 +options usbhid quirks=0x1292:0x5366:0x040 + +# Retrobit Atari to USB Driver +options usbhid quirks=0x1292:0x4154:0x040 + +# Retrobit Genesis to PC USB Adapter +options usbhid quirks=0x1292:0x4745:0x040 + +# Retrode +options usbhid quirks=0x0403:0x97c1:0x040 + +# HuiJia USB GamePad Mayflash Sega Saturn +options usbhid quirks=0x0e8f:0x3010:0x040 + +# HuiJia USB GamePad Mayflash NES SNES +options usbhid quirks=0x0079:0x1804:0x040 + +# Mayflash Dreamcast +options usbhid quirks=0x0xe8f:0x3013:0x040 + +# Xin-Mo 2players 20pins +options usbhid quirks=0x16c0:0x75e1:0x040 + +# Xinmo 18 pins USB THT 2P arcade controller THT 2P arcade controller +options usbhid quirks=0x16c0:0x05e1:0x040 + +# USB PS2 Adapter GreenAsia Electronics +options usbhid quirks=0xe8f:0x1013:0x040 + +# HuiJia USB GamePad Mayflash N64 - need test +options usbhid quirks=0xe8f:0x3013:0x040 + +# XCSOURCE 2 Encoder USB - Twin USB Gamepad +options usbhid quirks=0x810:0xe001:0x040 + +# 3H Dual Arcade 2Players +options usbhid quirks=0x16c0:0x05e0:0x040 + +#ShanWan Twin USB Joystick +options usbhid quirks=0x2563:0x555:0x040 + + diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/package.mk b/projects/ArchR/packages/emulators/libretro/retroarch/package.mk new file mode 100644 index 0000000000..12a727b466 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/package.mk @@ -0,0 +1,166 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2021-present 351ELEC (https://github.com/351ELEC) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="retroarch" +PKG_VERSION="fae7468de15b32a0e105e45325e5ca85e62ea7d4" # v1.22.2 + fixes +PKG_SITE="https://github.com/libretro/RetroArch" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_LICENSE="GPLv3" +PKG_DEPENDS_TARGET="toolchain SDL2 alsa-lib libass openssl freetype zlib retroarch-assets core-info ffmpeg libass joyutils nss-mdns openal-soft libogg libvorbisidec libvorbis libvpx libpng libdrm pulseaudio miniupnpc flac xz" +PKG_LONGDESC="Reference frontend for the libretro API." + +if [ "${PIPEWIRE_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" pipewire" +fi + +case ${ARCH} in + arm) + true + ;; + *) + PKG_DEPENDS_TARGET+=" empty" + ;; +esac + +PKG_PATCH_DIRS+=" ${DEVICE}" + +PKG_CONFIGURE_OPTS_TARGET=" --disable-qt \ + --enable-alsa \ + --enable-udev \ + --disable-opengl1 \ + --disable-x11 \ + --enable-zlib \ + --enable-freetype \ + --disable-discord \ + --disable-vg \ + --disable-sdl \ + --enable-sdl2 \ + --enable-kms \ + --enable-ffmpeg" + +case ${ARCH} in + arm) + PKG_CONFIGURE_OPTS_TARGET+=" --enable-neon" + ;; + aarch64) + PKG_CONFIGURE_OPTS_TARGET+=" --disable-neon" + ;; +esac + +case ${DEVICE} in + RK*) + PKG_DEPENDS_TARGET+=" librga" + ;; +esac + +if [ "${DISPLAYSERVER}" = "wl" ]; then + PKG_DEPENDS_TARGET+=" wayland" + PKG_CONFIGURE_OPTS_TARGET+=" --enable-wayland" + case ${ARCH} in + arm) + true + ;; + *) + PKG_DEPENDS_TARGET+=" ${WINDOWMANAGER}" + ;; + esac +else + PKG_CONFIGURE_OPTS_TARGET+=" --disable-wayland" +fi + +if [ "${OPENGLES_SUPPORT}" = "yes" ] && \ + [ "${PREFER_GLES}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" + # --enable-opengles3 required for glcore, --enable-opengles3_1 doesn't auto-select it + PKG_CONFIGURE_OPTS_TARGET+=" --enable-opengles --enable-opengles3 --enable-opengles3_1" + PKG_CONFIGURE_OPTS_TARGET+=" --disable-opengl" +else + # Full OpenGL + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" + PKG_CONFIGURE_OPTS_TARGET+=" --enable-opengl" + PKG_CONFIGURE_OPTS_TARGET+=" --disable-opengles --disable-opengles3 --disable-opengles3_1 --disable-opengles3_2" +fi + +if [ "${VULKAN_SUPPORT}" = "yes" ] +then + PKG_DEPENDS_TARGET+=" ${VULKAN}" + PKG_CONFIGURE_OPTS_TARGET+=" --enable-vulkan --enable-vulkan_display" +else + PKG_CONFIGURE_OPTS_TARGET+=" --disable-vulkan" +fi + +pre_configure_target() { + CFLAGS+=" -DUDEV_TOUCH_SUPPORT" + CXXFLAGS+=" -DUDEV_TOUCH_SUPPORT" + TARGET_CONFIGURE_OPTS="" + + cd ${PKG_BUILD} +} + +make_target() { + make HAVE_UPDATE_ASSETS=0 HAVE_LIBRETRODB=1 HAVE_BLUETOOTH=0 HAVE_NETWORKING=1 HAVE_ZARCH=1 HAVE_QT=0 HAVE_LANGEXTRA=1 + [ $? -eq 0 ] && echo "(retroarch ok)" || { echo "(retroarch failed)" ; exit 1 ; } + make -C gfx/video_filters compiler=$CC extra_flags="$CFLAGS" + [ $? -eq 0 ] && echo "(video filters ok)" || { echo "(video filters failed)" ; exit 1 ; } + make -C libretro-common/audio/dsp_filters compiler=$CC extra_flags="$CFLAGS" + [ $? -eq 0 ] && echo "(audio filters ok)" || { echo "(audio filters failed)" ; exit 1 ; } +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp ${PKG_BUILD}/retroarch ${INSTALL}/usr/bin + mkdir -p ${INSTALL}/usr/share/retroarch/filters + + case ${ARCH} in + aarch64) + if [ -f ${ROOT}/build.${DISTRO}-${DEVICE}.arm/install_pkg/retroarch-*/usr/bin/retroarch ]; then + cp -vP ${ROOT}/build.${DISTRO}-${DEVICE}.arm/install_pkg/retroarch-*/usr/bin/retroarch ${INSTALL}/usr/bin/retroarch32 + mkdir -p ${INSTALL}/usr/share/retroarch/filters/32bit/ + cp -rvP ${ROOT}/build.${DISTRO}-${DEVICE}.arm/install_pkg/retroarch-*/usr/share/retroarch/filters/64bit/* ${INSTALL}/usr/share/retroarch/filters/32bit/ + fi + ;; + esac + + mkdir -p ${INSTALL}/etc + cp ${PKG_BUILD}/retroarch.cfg ${INSTALL}/etc + + mkdir -p ${INSTALL}/usr/share/retroarch/filters/64bit/video + cp ${PKG_BUILD}/gfx/video_filters/*.so ${INSTALL}/usr/share/retroarch/filters/64bit/video + cp ${PKG_BUILD}/gfx/video_filters/*.filt ${INSTALL}/usr/share/retroarch/filters/64bit/video + + mkdir -p ${INSTALL}/usr/share/retroarch/filters/64bit/audio + cp ${PKG_BUILD}/libretro-common/audio/dsp_filters/*.so ${INSTALL}/usr/share/retroarch/filters/64bit/audio + cp ${PKG_BUILD}/libretro-common/audio/dsp_filters/*.dsp ${INSTALL}/usr/share/retroarch/filters/64bit/audio + + # General configuration + mkdir -p ${INSTALL}/usr/config/retroarch/ + if [ -d "${PKG_DIR}/sources/${DEVICE}" ]; then + cp -rf ${PKG_DIR}/sources/${DEVICE}/* ${INSTALL}/usr/config/retroarch/ + else + echo "Configure retroarch for ${DEVICE}" + exit 1 + fi + + # Make sure the shader directories exist for overlayfs. + for dir in common-shaders glsl-shaders slang-shaders + do + mkdir -p ${INSTALL}/usr/share/${dir} + touch ${INSTALL}/usr/share/${dir}/.overlay + done + + # Copy achievment sounds + mkdir -p ${INSTALL}/usr/share/libretro + cp -R ${PKG_DIR}/sounds ${INSTALL}/usr/share/libretro + + # Copy achievements hooks script + cp ${PKG_DIR}/scripts/call_achievements_hooks.sh ${INSTALL}/usr/share/libretro +} + +post_install() { + enable_service tmp-cores.mount + enable_service tmp-database.mount + enable_service tmp-assets.mount + enable_service tmp-shaders.mount + enable_service tmp-overlays.mount +} diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/patches/0001-Increase-glui-size.patch b/projects/ArchR/packages/emulators/libretro/retroarch/patches/0001-Increase-glui-size.patch new file mode 100644 index 0000000000..d62d7d4465 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/patches/0001-Increase-glui-size.patch @@ -0,0 +1,22 @@ +diff --git a/menu/drivers/materialui.c b/menu/drivers/materialui.c +index d3ae5ec997..5ff5405b2a 100644 +--- a/menu/drivers/materialui.c ++++ b/menu/drivers/materialui.c +@@ -3591,7 +3591,7 @@ static void materialui_render(void *data, + /* Check whether screen dimensions, menu scale + * factor or layout optimisation settings have changed */ + scale_factor = gfx_display_get_dpi_scale(p_disp, settings, +- width, height, false, false); ++ width, height, false, false) * 2.000f; + + if ( (scale_factor != mui->last_scale_factor) + || (width != mui->last_width) +@@ -8133,7 +8133,7 @@ static void *materialui_init(void **userdata, bool video_is_threaded) + mui->last_height = height; + mui->last_scale_factor = gfx_display_get_dpi_scale( + p_disp, settings, width, height, +- false, false); ++ false, false) * 2.000f; + mui->dip_base_unit_size = mui->last_scale_factor + * MUI_DIP_BASE_UNIT_SIZE; + mui->flags = 0; diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/patches/0001-Increase-ozone-size.patch b/projects/ArchR/packages/emulators/libretro/retroarch/patches/0001-Increase-ozone-size.patch new file mode 100644 index 0000000000..cc13c3f934 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/patches/0001-Increase-ozone-size.patch @@ -0,0 +1,22 @@ +diff --git a/menu/drivers/ozone.c b/menu/drivers/ozone.c +index 23a2d13245..45db0d5bf8 100644 +--- a/menu/drivers/ozone.c ++++ b/menu/drivers/ozone.c +@@ -9103,7 +9103,7 @@ static void *ozone_init(void **userdata, bool video_is_threaded) + ozone->last_width = width; + ozone->last_height = height; + ozone->last_scale_factor = gfx_display_get_dpi_scale(p_disp, +- settings, width, height, false, false); ++ settings, width, height, false, false) * 2.000f; + ozone->last_thumbnail_scale_factor = settings->floats.ozone_thumbnail_scale_factor; + + ozone->selection_buf_old.list = NULL; +@@ -10256,7 +10256,7 @@ static void ozone_render(void *data, + /* Check whether screen dimensions or menu scale + * factor have changed */ + scale_factor = gfx_display_get_dpi_scale(p_disp, settings, +- width, height, false, false); ++ width, height, false, false) * 2.000f; + thumbnail_scale_factor = settings->floats.ozone_thumbnail_scale_factor; + padding_factor = settings->floats.ozone_padding_factor; + font_scale_factor_global = (font_scale == 1) ? (settings->floats.ozone_font_scale_factor_global) : 1.0f; diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/patches/0001-Increase-ozone-widget_size.patch b/projects/ArchR/packages/emulators/libretro/retroarch/patches/0001-Increase-ozone-widget_size.patch new file mode 100644 index 0000000000..3dd774b0ba --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/patches/0001-Increase-ozone-widget_size.patch @@ -0,0 +1,14 @@ +diff --git a/gfx/gfx_widgets.c b/gfx/gfx_widgets.c +index 29e956763e..3caec1f48d 100644 +--- a/gfx/gfx_widgets.c ++++ b/gfx/gfx_widgets.c +@@ -931,6 +931,9 @@ void gfx_widgets_iterate( + p_disp, + settings, width, height, fullscreen, true); + ++ if (p_disp->menu_driver_id == MENU_DRIVER_ID_OZONE) ++ scale_factor = scale_factor * 1.500f; ++ + /* Check whether screen dimensions or menu scale + * factor have changed */ + if ((scale_factor != p_dispwidget->last_scale_factor) || diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/patches/0002-quit-not-restart.patch b/projects/ArchR/packages/emulators/libretro/retroarch/patches/0002-quit-not-restart.patch new file mode 100644 index 0000000000..76ea4041aa --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/patches/0002-quit-not-restart.patch @@ -0,0 +1,12 @@ +diff -rupN retroarch.orig/menu/menu_setting.c retroarch/menu/menu_setting.c +--- retroarch.orig/menu/menu_setting.c 2022-03-05 15:34:24.206615672 -0500 ++++ retroarch/menu/menu_setting.c 2022-03-05 20:09:51.435336191 -0500 +@@ -9321,7 +9321,7 @@ static bool setting_append_list( + CONFIG_ACTION( + list, list_info, + MENU_ENUM_LABEL_QUIT_RETROARCH, +- MENU_ENUM_LABEL_VALUE_RESTART_RETROARCH, ++ MENU_ENUM_LABEL_VALUE_QUIT_RETROARCH, + &group_info, + &subgroup_info, + parent_group); diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/patches/0003-fix-oga-no-preferred.patch b/projects/ArchR/packages/emulators/libretro/retroarch/patches/0003-fix-oga-no-preferred.patch new file mode 100644 index 0000000000..e5a77fe1d6 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/patches/0003-fix-oga-no-preferred.patch @@ -0,0 +1,54 @@ +diff --git a/deps/libgo2/src/display.c b/deps/libgo2/src/display.c +index b91cf0624b..e1d10593ba 100644 +--- a/deps/libgo2/src/display.c ++++ b/deps/libgo2/src/display.c +@@ -151,6 +151,7 @@ go2_display_t* go2_display_create() + + // Find prefered mode + drmModeModeInfo* mode; ++ mode = &connector->modes[0]; + for (i = 0; i < connector->count_modes; i++) + { + drmModeModeInfo *current_mode = &connector->modes[i]; +@@ -159,14 +160,6 @@ go2_display_t* go2_display_create() + mode = current_mode; + break; + } +- +- mode = NULL; +- } +- +- if (!mode) +- { +- printf("DRM_MODE_TYPE_PREFERRED not found.\n"); +- goto err_03; + } + + result->mode = *mode; +diff --git a/gfx/drivers/oga_gfx.c b/gfx/drivers/oga_gfx.c +index 69fa7a75bb..28c1b0f1fc 100644 +--- a/gfx/drivers/oga_gfx.c ++++ b/gfx/drivers/oga_gfx.c +@@ -142,6 +142,7 @@ static bool oga_create_display(oga_video_t* vid) + vid->connector_id = connector->connector_id; + + /* Find preferred mode */ ++ mode = &connector->modes[0]; + for (i = 0; i < connector->count_modes; i++) + { + drmModeModeInfo *current_mode = &connector->modes[i]; +@@ -150,14 +151,6 @@ static bool oga_create_display(oga_video_t* vid) + mode = current_mode; + break; + } +- +- mode = NULL; +- } +- +- if (!mode) +- { +- RARCH_ERR("DRM_MODE_TYPE_PREFERRED not found.\n"); +- goto err_03; + } + + vid->mode = *mode; diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/patches/0004-drm-resolution.patch b/projects/ArchR/packages/emulators/libretro/retroarch/patches/0004-drm-resolution.patch new file mode 100644 index 0000000000..369b26729e --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/patches/0004-drm-resolution.patch @@ -0,0 +1,27 @@ +diff --git a/gfx/common/drm_common.c b/gfx/common/drm_common.c +index a1bede5..8bc674a 100644 +--- a/gfx/common/drm_common.c ++++ b/gfx/common/drm_common.c +@@ -156,6 +156,22 @@ bool drm_get_encoder(int fd) + g_drm_connector->modes[i].vrefresh); + } + ++ // batocera - set resolution ++ FILE* fdDrmMode; ++ int drmMode; ++ if((fdDrmMode = fopen("/var/run/drmMode", "r")) != NULL) { ++ if(fscanf(fdDrmMode, "%i", &drmMode) == 1) { ++ if(drmMode>=0 && drmModecount_modes) { ++ drmModeCrtc *pcrtc = drmModeGetCrtc(fd, g_drm_encoder->crtc_id); ++ if(pcrtc != NULL) { ++ drmModeSetCrtc(fd, pcrtc->crtc_id, pcrtc->buffer_id, 0, 0, &g_drm_connector->connector_id, 1, &g_drm_connector->modes[drmMode]); ++ } ++ } ++ } ++ fclose(fdDrmMode); ++ } ++ // ++ + return true; + } + diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/patches/0006-no-screen-brightness.patch b/projects/ArchR/packages/emulators/libretro/retroarch/patches/0006-no-screen-brightness.patch new file mode 100644 index 0000000000..9f88f70e6f --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/patches/0006-no-screen-brightness.patch @@ -0,0 +1,29 @@ +diff -rupN retroarch.orig/frontend/drivers/platform_unix.c retroarch/frontend/drivers/platform_unix.c +--- retroarch.orig/frontend/drivers/platform_unix.c 2022-02-05 19:38:43.852018492 -0500 ++++ retroarch/frontend/drivers/platform_unix.c 2022-02-05 20:10:30.735583922 -0500 +@@ -2048,12 +2048,6 @@ static void frontend_unix_deinit(void *d + android_app_destroy(android_app); + #endif + +-#ifdef HAVE_LAKKA +- /* Reset brightness to maximum */ +- if (settings->uints.screen_brightness != DEFAULT_SCREEN_BRIGHTNESS) +- frontend_unix_set_screen_brightness(DEFAULT_SCREEN_BRIGHTNESS); +-#endif +- + frontend_unix_set_gamemode(false); + } + +@@ -2885,11 +2879,7 @@ frontend_ctx_driver_t frontend_ctx_unix + #else + NULL, /* get_lakka_version */ + #endif +-#if defined(HAVE_LAKKA_SWITCH) || (defined(HAVE_LAKKA) && defined(HAVE_ODROIDGO2)) +- frontend_unix_set_screen_brightness,/* set_screen_brightness */ +-#else +- NULL, /* set_screen_brightness */ +-#endif ++ NULL, /* set_screen_brightness? No. */ + frontend_unix_watch_path_for_changes, + frontend_unix_check_for_path_changes, + frontend_unix_set_sustained_performance_mode, diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/patches/0008-disable_search.patch b/projects/ArchR/packages/emulators/libretro/retroarch/patches/0008-disable_search.patch new file mode 100644 index 0000000000..c15a8979ab --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/patches/0008-disable_search.patch @@ -0,0 +1,13 @@ +diff --git a/menu/menu_driver.c b/menu/menu_driver.c +index cf2c30f7c7..e04ab9702b 100644 +--- a/menu/menu_driver.c ++++ b/menu/menu_driver.c +@@ -7617,7 +7617,7 @@ int generic_menu_entry_action( + entry->label, entry->type, i, entry->entry_idx); + break; + case MENU_ACTION_SEARCH: +- menu_input_dialog_start_search(); ++ //menu_input_dialog_start_search(); + break; + case MENU_ACTION_SCAN: + if (cbs && cbs->action_scan) diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/patches/0009-hide-wayland-checkerboard.patch b/projects/ArchR/packages/emulators/libretro/retroarch/patches/0009-hide-wayland-checkerboard.patch new file mode 100644 index 0000000000..6c03def537 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/patches/0009-hide-wayland-checkerboard.patch @@ -0,0 +1,27 @@ +diff --git a/gfx/drivers/vulkan.c b/gfx/drivers/vulkan.c +index d04a24172c..806e336ba2 100644 +--- a/gfx/drivers/vulkan.c ++++ b/gfx/drivers/vulkan.c +@@ -3313,14 +3313,14 @@ static uintptr_t vulkan_load_texture(void *video_data, void *data, + { + /* Create a dummy texture instead. */ + static const uint32_t checkerboard[] = { +- VK_T0, VK_T1, VK_T0, VK_T1, VK_T0, VK_T1, VK_T0, VK_T1, +- VK_T1, VK_T0, VK_T1, VK_T0, VK_T1, VK_T0, VK_T1, VK_T0, +- VK_T0, VK_T1, VK_T0, VK_T1, VK_T0, VK_T1, VK_T0, VK_T1, +- VK_T1, VK_T0, VK_T1, VK_T0, VK_T1, VK_T0, VK_T1, VK_T0, +- VK_T0, VK_T1, VK_T0, VK_T1, VK_T0, VK_T1, VK_T0, VK_T1, +- VK_T1, VK_T0, VK_T1, VK_T0, VK_T1, VK_T0, VK_T1, VK_T0, +- VK_T0, VK_T1, VK_T0, VK_T1, VK_T0, VK_T1, VK_T0, VK_T1, +- VK_T1, VK_T0, VK_T1, VK_T0, VK_T1, VK_T0, VK_T1, VK_T0, ++ VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, ++ VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, ++ VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, ++ VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, ++ VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, ++ VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, ++ VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, ++ VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, VK_T0, + }; + *texture = vulkan_create_texture(vk, NULL, + 8, 8, VK_FORMAT_B8G8R8A8_UNORM, diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/patches/0010-paths.patch b/projects/ArchR/packages/emulators/libretro/retroarch/patches/0010-paths.patch new file mode 100644 index 0000000000..75595787dc --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/patches/0010-paths.patch @@ -0,0 +1,51 @@ +diff --git a/frontend/drivers/platform_unix.c b/frontend/drivers/platform_unix.c +index e1db1da096..7baf8a5f21 100644 +--- a/frontend/drivers/platform_unix.c ++++ b/frontend/drivers/platform_unix.c +@@ -1812,7 +1812,7 @@ static void frontend_unix_get_env(int *argc, + "/usr/share/games/retroarch", + "assets", sizeof(g_defaults.dirs[DEFAULT_DIR_ASSETS])); + else +- fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_ASSETS], base_path, ++ fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_ASSETS], "/tmp/", + "assets", sizeof(g_defaults.dirs[DEFAULT_DIR_ASSETS])); + + #if defined(DINGUX) +@@ -1885,7 +1885,7 @@ static void frontend_unix_get_env(int *argc, + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_REMAP], + g_defaults.dirs[DEFAULT_DIR_MENU_CONFIG], + "remaps", sizeof(g_defaults.dirs[DEFAULT_DIR_REMAP])); +- fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_PLAYLIST], base_path, ++ fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_PLAYLIST], "/tmp/", + "playlists", sizeof(g_defaults.dirs[DEFAULT_DIR_PLAYLIST])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_RECORD_CONFIG], base_path, + "records_config", sizeof(g_defaults.dirs[DEFAULT_DIR_RECORD_CONFIG])); +@@ -1896,14 +1896,14 @@ static void frontend_unix_get_env(int *argc, + libretro_database_directory, + sizeof(g_defaults.dirs[DEFAULT_DIR_DATABASE])); + else +- fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_DATABASE], base_path, ++ fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_DATABASE], "/tmp/", + "database/rdb", sizeof(g_defaults.dirs[DEFAULT_DIR_DATABASE])); + if (!string_is_empty(libretro_video_shader_directory)) + strlcpy(g_defaults.dirs[DEFAULT_DIR_SHADER], + libretro_video_shader_directory, + sizeof(g_defaults.dirs[DEFAULT_DIR_SHADER])); + else +- fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SHADER], base_path, ++ fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SHADER], "/tmp/", + "shaders", sizeof(g_defaults.dirs[DEFAULT_DIR_SHADER])); + if (!string_is_empty(libretro_cheats_directory)) + strlcpy(g_defaults.dirs[DEFAULT_DIR_CHEATS], +@@ -1912,9 +1912,9 @@ static void frontend_unix_get_env(int *argc, + else + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CHEATS], base_path, + "cheats", sizeof(g_defaults.dirs[DEFAULT_DIR_CHEATS])); +- fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_OVERLAY], base_path, ++ fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_OVERLAY], "/tmp/", + "overlays", sizeof(g_defaults.dirs[DEFAULT_DIR_OVERLAY])); +- fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_OSK_OVERLAY], base_path, ++ fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_OSK_OVERLAY], "/tmp/", + "overlays/keyboards", sizeof(g_defaults.dirs[DEFAULT_DIR_OSK_OVERLAY])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS], base_path, + "downloads", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS])); diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/patches/0011-cheevos-sounds.patch b/projects/ArchR/packages/emulators/libretro/retroarch/patches/0011-cheevos-sounds.patch new file mode 100644 index 0000000000..b5e8662091 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/patches/0011-cheevos-sounds.patch @@ -0,0 +1,83 @@ +diff --git a/audio/audio_driver.c b/audio/audio_driver.c +index 01a727eb95..fc43700d22 100644 +--- a/audio/audio_driver.c ++++ b/audio/audio_driver.c +@@ -1339,8 +1339,8 @@ static void audio_driver_load_menu_bgm_callback(retro_task_t *task, + void audio_driver_load_system_sounds(void) + { + char basename_noext[NAME_MAX_LENGTH]; +- char sounds_path[PATH_MAX_LENGTH]; +- char sounds_fallback_path[PATH_MAX_LENGTH]; ++ char* sounds_path = "/usr/share/libretro/sounds"; ++ char* sounds_fallback_path = "/storage/roms/music/retroachievements"; + settings_t *settings = config_get_ptr(); + const char *dir_assets = settings->paths.directory_assets; + const bool audio_enable_menu = settings->bools.audio_enable_menu; +@@ -1365,19 +1365,6 @@ void audio_driver_load_system_sounds(void) + if (!audio_enable_menu && !audio_enable_cheevo_unlock) + goto end; + +- sounds_path[0] = basename_noext[0] ='\0'; +- +- fill_pathname_join_special( +- sounds_fallback_path, +- dir_assets, +- "sounds", +- sizeof(sounds_fallback_path)); +- +- fill_pathname_application_special( +- sounds_path, +- sizeof(sounds_path), +- APPLICATION_SPECIAL_DIRECTORY_ASSETS_SOUNDS); +- + list = dir_list_new(sounds_path, MENU_SOUND_FORMATS, false, false, false, false); + list_fallback = dir_list_new(sounds_fallback_path, MENU_SOUND_FORMATS, false, false, false, false); + +@@ -1423,8 +1410,13 @@ void audio_driver_load_system_sounds(void) + path_notice_back = path; + else if (string_is_equal_noncase(basename_noext, "bgm")) + path_bgm = path; +- else if (string_is_equal_noncase(basename_noext, "unlock")) +- path_cheevo_unlock = path; ++ else if(string_is_empty(settings->arrays.cheevos_unlock_sound) == false) { ++ if (string_is_equal_noncase(basename_noext, "unlock")) ++ path_cheevo_unlock = path; ++ else ++ if (string_is_equal_noncase(basename_noext, settings->arrays.cheevos_unlock_sound)) ++ path_cheevo_unlock = path; ++ } + else if (string_is_equal_noncase(basename_noext, "up")) + path_up = path; + else if (string_is_equal_noncase(basename_noext, "down")) +diff --git a/configuration.c b/configuration.c +index 6b202341b0..ef831dc1fb 100644 +--- a/configuration.c ++++ b/configuration.c +@@ -1568,6 +1568,7 @@ static struct config_array_setting *populate_settings_array( + SETTING_ARRAY("cheevos_username", settings->arrays.cheevos_username, false, NULL, true); + SETTING_ARRAY("cheevos_password", settings->arrays.cheevos_password, false, NULL, true); + SETTING_ARRAY("cheevos_token", settings->arrays.cheevos_token, false, NULL, true); ++ SETTING_ARRAY("cheevos_unlock_sound", settings->arrays.cheevos_unlock_sound, false, NULL, true); + SETTING_ARRAY("cheevos_leaderboards_enable", settings->arrays.cheevos_leaderboards_enable, true, "", true); /* deprecated */ + #endif + +@@ -2957,6 +2958,7 @@ void config_set_defaults(void *data) + #ifdef HAVE_CHEEVOS + *settings->arrays.cheevos_username = '\0'; + *settings->arrays.cheevos_password = '\0'; ++ *settings->arrays.cheevos_unlock_sound = '\0'; + *settings->arrays.cheevos_token = '\0'; + #endif + +diff --git a/configuration.h b/configuration.h +index 611678c510..e87f2f6318 100644 +--- a/configuration.h ++++ b/configuration.h +@@ -467,6 +467,7 @@ typedef struct settings + char cloud_sync_driver[32]; + char menu_driver[32]; + char cheevos_username[32]; ++ char cheevos_unlock_sound[128]; + char cheevos_token[32]; + char cheevos_leaderboards_enable[32]; + char video_context_driver[32]; diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/patches/0012-cheevos-cmd.patch b/projects/ArchR/packages/emulators/libretro/retroarch/patches/0012-cheevos-cmd.patch new file mode 100644 index 0000000000..1d94a25bab --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/patches/0012-cheevos-cmd.patch @@ -0,0 +1,42 @@ +diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c +index d8fc40c..aed6de4 100644 +--- a/cheevos/cheevos.c ++++ b/cheevos/cheevos.c +@@ -470,6 +470,13 @@ static void rcheevos_award_achievement(const rc_client_achievement_t* cheevo) + } + } + ++ const char* cheevos_cmd = settings->arrays.cheevos_cmd; ++ if (cheevos_cmd[0]) { ++ char cmdargs[256]; ++ snprintf(cmdargs, sizeof(cmdargs), "%s %u \"%s\" \"%s\" > /dev/null 2>/dev/null", cheevos_cmd, cheevo->id, cheevo->title, cheevo->description); ++ system(cmdargs); ++ } ++ + #ifdef HAVE_AUDIOMIXER + /* Play the unlock sound */ + if (settings->bools.cheevos_unlock_sound_enable) +diff --git a/configuration.c b/configuration.c +index 0458404..3119b97 100644 +--- a/configuration.c ++++ b/configuration.c +@@ -1523,6 +1523,7 @@ static struct config_array_setting *populate_settings_array( + + #ifdef HAVE_CHEEVOS + SETTING_ARRAY("cheevos_custom_host", settings->arrays.cheevos_custom_host, false, NULL, true); ++ SETTING_ARRAY("cheevos_cmd", settings->arrays.cheevos_cmd, false, NULL, true); + SETTING_ARRAY("cheevos_username", settings->arrays.cheevos_username, false, NULL, true); + SETTING_ARRAY("cheevos_password", settings->arrays.cheevos_password, false, NULL, true); + SETTING_ARRAY("cheevos_token", settings->arrays.cheevos_token, false, NULL, true); +diff --git a/configuration.h b/configuration.h +index a7eae74..47a8376 100644 +--- a/configuration.h ++++ b/configuration.h +@@ -471,6 +471,7 @@ typedef struct settings + char cheevos_unlock_sound[128]; + char cheevos_token[32]; + char cheevos_leaderboards_enable[32]; ++ char cheevos_cmd[256]; + char video_context_driver[32]; + char audio_driver[32]; + char audio_resampler[32]; diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-assets/package.mk b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-assets/package.mk new file mode 100644 index 0000000000..99eb903150 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-assets/package.mk @@ -0,0 +1,26 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="retroarch-assets" +PKG_VERSION="76cc6cf03507429c5a136cb50d83a14e05430fcd" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/libretro/retroarch-assets" +PKG_URL="https://github.com/libretro/retroarch-assets/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="make:host" +PKG_LONGDESC="RetroArch assets. Background and icon themes for the menu drivers." +PKG_TOOLCHAIN="manual" + +pre_configure_target() { + cd ../ + rm -rf .${TARGET_NAME} +} + +makeinstall_target() { + make install INSTALLDIR="${INSTALL}/usr/share/retroarch-assets" +} + +post_makeinstall_target() { + # Remove unnecesary Retroarch Assets and overlays + rm -rf ${INSTALL}/usr/share/retroarch-assets/{branding,nxrgui,pkg,scripts,switch,wallpapers} + rm -rf ${INSTALL}/usr/share/retroarch-assets/xmb/{automatic,dot-art,flatui,pixel,retrosystem,systematic} +} diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/ THEC64 Joystick THEC64 Joystick .cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/ THEC64 Joystick THEC64 Joystick .cfg new file mode 100644 index 0000000000..0ec40c3ec9 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/ THEC64 Joystick THEC64 Joystick .cfg @@ -0,0 +1,16 @@ +input_driver = "udev" +input_device = " THEC64 Joystick THEC64 Joystick " +input_vendor_id = "7257" +input_product_id = "36" +input_b_btn = "1" +input_y_btn = "4" +input_select_btn = "2" +input_start_btn = "3" +input_up_axis = "-1" +input_down_axis = "+1" +input_left_axis = "-0" +input_right_axis = "+0" +input_a_btn = "0" +input_x_btn = "7" +input_l_btn = "5" +input_r_btn = "6" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/8Bitdo SF30 Pro 8Bitdo SN30 Pro.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/8Bitdo SF30 Pro 8Bitdo SN30 Pro.cfg new file mode 100644 index 0000000000..5d4714bb32 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/8Bitdo SF30 Pro 8Bitdo SN30 Pro.cfg @@ -0,0 +1,29 @@ +input_driver = "udev" +input_device = "8Bitdo SF30 Pro 8Bitdo SN30 Pro" +input_vendor_id = "11720" +input_product_id = "24577" +input_gun_trigger_mbtn = "1" +input_b_btn = "1" +input_y_btn = "4" +input_select_btn = "10" +input_start_btn = "11" +input_up_btn = "h0up" +input_down_btn = "h0down" +input_left_btn = "h0left" +input_right_btn = "h0right" +input_a_btn = "0" +input_x_btn = "3" +input_l_btn = "6" +input_r_btn = "7" +input_l2_btn = "8" +input_r2_btn = "9" +input_l3_btn = "13" +input_r3_btn = "14" +input_l_x_plus_axis = "+0" +input_l_x_minus_axis = "-0" +input_l_y_plus_axis = "+1" +input_l_y_minus_axis = "-1" +input_r_x_plus_axis = "+2" +input_r_x_minus_axis = "-2" +input_r_y_plus_axis = "+3" +input_r_y_minus_axis = "-3" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/AYN Odin Gamepad.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/AYN Odin Gamepad.cfg new file mode 100644 index 0000000000..d8ed6f5fab --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/AYN Odin Gamepad.cfg @@ -0,0 +1,42 @@ +fast_forwardinput_driver = "udev" +input_device = "AYN Odin Gamepad" + +input_a_btn = "0" +input_b_btn = "1" +input_x_btn = "2" +input_y_btn = "3" +input_select_btn = "4" +input_start_btn = "6" +input_up_btn = "11" +input_down_btn = "12" +input_left_btn = "13" +input_right_btn = "14" +input_l_btn = "9" +input_r_btn = "10" +input_l2_axis = "+2" +input_r2_axis = "+5" +input_l3_btn = "7" +input_r3_btn = "8" +input_l_x_plus_axis = "+0" +input_l_x_minus_axis = "-0" +input_l_y_plus_axis = "+1" +input_l_y_minus_axis = "-1" +input_r_x_plus_axis = "+2" +input_r_x_minus_axis = "-2" +input_r_y_plus_axis = "+3" +input_r_y_minus_axis = "-3" + +# Hotkeys +input_enable_hotkey_btn = "5" +input_exit_emulator_btn = "6" + +input_screenshot_btn = "0" +input_reset_btn = "1" +input_menu_toggle_btn = "2" +input_fps_toggle_btn = "3" + +input_load_state_btn = "9" +input_save_state_btn = "10" + +input_rewind_axis = "+2" +input_toggle_fast_forward_axis = "+5" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/AYN Odin2 Gamepad.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/AYN Odin2 Gamepad.cfg new file mode 100644 index 0000000000..4f6ca212a7 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/AYN Odin2 Gamepad.cfg @@ -0,0 +1,42 @@ +input_driver = "udev" +input_device = "AYN Odin2 Gamepad" + +input_b_btn = "1" +input_y_btn = "3" +input_select_btn = "4" +input_start_btn = "6" +input_up_btn = "11" +input_down_btn = "12" +input_left_btn = "13" +input_right_btn = "14" +input_a_btn = "0" +input_x_btn = "2" +input_l_btn = "9" +input_r_btn = "10" +input_l2_axis = "+4" +input_r2_axis = "+5" +input_l3_btn = "7" +input_r3_btn = "8" +input_l_x_plus_axis = "+0" +input_l_x_minus_axis = "-0" +input_l_y_plus_axis = "+1" +input_l_y_minus_axis = "-1" +input_r_x_plus_axis = "+2" +input_r_x_minus_axis = "-2" +input_r_y_plus_axis = "+3" +input_r_y_minus_axis = "-3" + +# Hotkeys +input_enable_hotkey_btn = "5" +input_exit_emulator_btn = "6" + +input_menu_toggle_btn = "2" +input_fps_toggle_btn = "3" +input_screenshot_btn = "0" +input_reset_btn = "1" + +input_load_state_btn = "9" +input_save_state_btn = "10" + +input_rewind_axis = "+4" +input_toggle_fast_forward_axis = "+5" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/Atari Classic Controller.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/Atari Classic Controller.cfg new file mode 100644 index 0000000000..a4815613a0 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/Atari Classic Controller.cfg @@ -0,0 +1,14 @@ +input_driver = "udev" +input_device = "Atari Classic Controller" +input_vendor_id = "12880" +input_product_id = "4098" +input_b_btn = "2" +input_select_btn = "4" +input_start_btn = "3" +input_up_btn = "h0up" +input_down_btn = "h0down" +input_left_btn = "h0left" +input_right_btn = "h0right" +input_a_btn = "1" +input_x_btn = "5" +input_gun_trigger_mbtn = "1" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/Atari Game Controller.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/Atari Game Controller.cfg new file mode 100644 index 0000000000..5459ea22bc --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/Atari Game Controller.cfg @@ -0,0 +1,29 @@ +input_driver = "udev" +input_device = "Atari Game Controller" +input_vendor_id = "12880" +input_product_id = "4098" +input_b_btn = "1" +input_y_btn = "3" +input_select_btn = "10" +input_start_btn = "9" +input_up_btn = "h0up" +input_down_btn = "h0down" +input_left_btn = "h0left" +input_right_btn = "h0right" +input_a_btn = "2" +input_x_btn = "4" +input_l_btn = "5" +input_r_btn = "6" +input_l2_axis = "+5" +input_r2_axis = "+4" +input_l3_btn = "7" +input_r3_btn = "8" +input_l_x_plus_axis = "+0" +input_l_x_minus_axis = "-0" +input_l_y_plus_axis = "+1" +input_l_y_minus_axis = "-1" +input_r_x_plus_axis = "+2" +input_r_x_minus_axis = "-2" +input_r_y_plus_axis = "+3" +input_r_y_minus_axis = "-3" +input_gun_trigger_mbtn = "1" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/Core (Plus) Wired Controller.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/Core (Plus) Wired Controller.cfg new file mode 100644 index 0000000000..345a0c5e62 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/Core (Plus) Wired Controller.cfg @@ -0,0 +1,29 @@ +input_driver = "udev" +input_device = "Core (Plus) Wired Controller" +input_vendor_id = "8406" +input_product_id = "42769" +input_b_btn = "1" +input_y_btn = "0" +input_select_btn = "8" +input_start_btn = "9" +input_up_btn = "h0up" +input_down_btn = "h0down" +input_left_btn = "h0left" +input_right_btn = "h0right" +input_a_btn = "2" +input_x_btn = "3" +input_l_btn = "4" +input_r_btn = "5" +input_l2_btn = "6" +input_r2_btn = "7" +input_l3_btn = "10" +input_r3_btn = "11" +input_l_x_plus_axis = "+0" +input_l_x_minus_axis = "-0" +input_l_y_plus_axis = "+1" +input_l_y_minus_axis = "-1" +input_r_x_plus_axis = "+2" +input_r_x_minus_axis = "-2" +input_r_y_plus_axis = "+3" +input_r_y_minus_axis = "-3" +input_gun_trigger_mbtn = "1" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/GO-Super Gamepad.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/GO-Super Gamepad.cfg new file mode 100644 index 0000000000..d30e378aae --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/GO-Super Gamepad.cfg @@ -0,0 +1,53 @@ +input_device = "GO-Super Gamepad" +input_driver = "udev" +input_vendor_id = "484B" +input_product_id = "1100" + +input_b_btn = "0" +input_a_btn = "1" +input_x_btn = "2" +input_y_btn = "3" +input_l_btn = "4" +input_r_btn = "5" +input_l2_btn = "6" +input_r2_btn = "7" + +input_up_btn = "8" +input_down_btn = "9" +input_left_btn = "10" +input_right_btn = "11" + +input_select_btn = "12" +input_start_btn = "13" + +input_l3_btn = "14" +input_r3_btn = "15" + +input_l_x_plus_axis = "+0" +input_l_x_minus_axis = "-0" +input_l_y_plus_axis = "+1" +input_l_y_minus_axis = "-1" + +input_r_x_plus_axis = "+2" +input_r_x_minus_axis = "-2" +input_r_y_plus_axis = "+3" +input_r_y_minus_axis = "-3" + + +# Hotkeys +input_enable_hotkey_btn = "12" +input_exit_emulator_btn = "13" + +input_screenshot_btn = "0" +input_pause_toggle_btn = "1" +input_menu_toggle_btn = "2" +input_fps_toggle_btn = "3" + +input_state_slot_increase_btn = "8" +input_state_slot_decrease_btn = "9" + +input_load_state_btn = "4" +input_save_state_btn = "5" + +input_rewind_btn = "6" +input_toggle_fast_forward_btn = "7" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/GO-Ultra Gamepad.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/GO-Ultra Gamepad.cfg new file mode 100644 index 0000000000..5bc2e5d0fe --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/GO-Ultra Gamepad.cfg @@ -0,0 +1,51 @@ +input_device = "GO-Ultra Gamepad" +input_driver = "udev" + +input_b_btn = "0" +input_a_btn = "1" +input_x_btn = "3" +input_y_btn = "4" +input_l_btn = "5" +input_r_btn = "6" +input_l2_btn = "7" +input_r2_btn = "8" + +input_up_btn = "14" +input_down_btn = "15" +input_left_btn = "16" +input_right_btn = "17" + +input_select_btn = "9" +input_start_btn = "10" + +input_l3_btn = "12" +input_r3_btn = "13" + +input_l_x_plus_axis = "+0" +input_l_x_minus_axis = "-0" +input_l_y_plus_axis = "+1" +input_l_y_minus_axis = "-1" + +input_r_x_plus_axis = "+2" +input_r_x_minus_axis = "-2" +input_r_y_plus_axis = "+3" +input_r_y_minus_axis = "-3" + + +# Hotkeys +input_enable_hotkey_btn = "11" +input_exit_emulator_btn = "10" + +input_screenshot_btn = "0" +input_pause_toggle_btn = "1" +input_menu_toggle_btn = "3" +input_fps_toggle_btn = "4" + +input_state_slot_increase_btn = "14" +input_state_slot_decrease_btn = "15" + +input_load_state_btn = "5" +input_save_state_btn = "6" + +input_rewind_btn = "7" +input_toggle_fast_forward_btn = "8" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/Game Controller.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/Game Controller.cfg new file mode 100644 index 0000000000..835197fe99 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/Game Controller.cfg @@ -0,0 +1,29 @@ +input_driver = "udev" +input_device = "Game Controller" +input_vendor_id = "12880" +input_product_id = "4098" +input_b_btn = "1" +input_y_btn = "3" +input_select_btn = "10" +input_start_btn = "9" +input_up_btn = "h0up" +input_down_btn = "h0down" +input_left_btn = "h0left" +input_right_btn = "h0right" +input_a_btn = "2" +input_x_btn = "4" +input_l_btn = "5" +input_r_btn = "6" +input_l2_axis = "+5" +input_r2_axis = "+4" +input_l3_btn = "7" +input_r3_btn = "8" +input_l_x_plus_axis = "+0" +input_l_x_minus_axis = "-0" +input_l_y_plus_axis = "+1" +input_l_y_minus_axis = "-1" +input_r_x_plus_axis = "+2" +input_r_x_minus_axis = "-2" +input_r_y_plus_axis = "+3" +input_r_y_minus_axis = "-3" +input_gun_trigger_mbtn = "1" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/GameForce ACE Gamepad.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/GameForce ACE Gamepad.cfg new file mode 100644 index 0000000000..69a36664ed --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/GameForce ACE Gamepad.cfg @@ -0,0 +1,27 @@ +input_driver = "udev" +input_device = "GameForce ACE Gamepad" +input_b_btn = "0" +input_y_btn = "4" +input_select_btn = "7" +input_start_btn = "8" +input_up_btn = "12" +input_down_btn = "13" +input_left_btn = "14" +input_right_btn = "15" +input_a_btn = "1" +input_x_btn = "3" +input_l_btn = "5" +input_r_btn = "6" +input_l2_axis = "-2" +input_r2_axis = "-5" +input_l3_btn = "10" +input_r3_btn = "11" +input_l_x_plus_axis = "+0" +input_l_x_minus_axis = "-0" +input_l_y_plus_axis = "+1" +input_l_y_minus_axis = "-1" +input_r_x_plus_axis = "+3" +input_r_x_minus_axis = "-3" +input_r_y_plus_axis = "+4" +input_r_y_minus_axis = "-4" +input_enable_hotkey_btn = "9" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/H700 Gamepad.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/H700 Gamepad.cfg new file mode 100644 index 0000000000..f07001abd1 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/H700 Gamepad.cfg @@ -0,0 +1,52 @@ +input_driver = "udev" +input_device = "H700 Gamepad" +input_device_display_name = "Anbernic RG35XX Gamepad" +input_vendor_id = "18507" +input_product_id = "5343" + +input_b_btn = "0" +input_a_btn = "1" +input_y_btn = "2" +input_x_btn = "3" +input_l_btn = "4" +input_r_btn = "5" +input_l2_btn = "6" +input_r2_btn = "7" + +input_select_btn = "8" +input_start_btn = "9" + +input_l3_btn = "11" +input_r3_btn = "12" + +input_up_btn = "13" +input_down_btn = "14" +input_left_btn = "15" +input_right_btn = "16" + +input_enable_hotkey_btn = "10" +input_exit_emulator_btn = "9" + +input_pause_toggle_btn = "1" +input_menu_toggle_btn = "3" +input_fps_toggle_btn = "2" +input_screenshot_btn = "nul" +input_load_state_btn = "4" +input_save_state_btn = "5" +input_toggle_fast_forward_btn = "7" +input_rewind_btn = "6" + +input_analog_dpad_mode = "0" +input_gun_trigger_mbtn = "1" +input_joypad_index = "0" +input_l_x_minus_axis = "-0" +input_l_x_plus_axis = "+0" +input_l_y_minus_axis = "-1" +input_l_y_plus_axis = "+1" +input_mouse_index = "0" +input_r_x_minus_axis = "-2" +input_r_x_plus_axis = "+2" +input_r_y_minus_axis = "-3" +input_r_y_plus_axis = "+3" +input_state_slot_increase_btn = "nul" +input_state_slot_decrease_btn = "nul" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/Microsoft X-Box 360 pad.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/Microsoft X-Box 360 pad.cfg new file mode 100644 index 0000000000..07aed81e42 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/Microsoft X-Box 360 pad.cfg @@ -0,0 +1,28 @@ +input_driver = "udev" +input_device = "Microsoft X-Box 360 pad" +input_vendor_id = "1118" +input_product_id = "654" +input_b_btn = "0" +input_y_btn = "2" +input_select_btn = "6" +input_start_btn = "7" +input_up_btn = "h0up" +input_down_btn = "h0down" +input_left_btn = "h0left" +input_right_btn = "h0right" +input_a_btn = "1" +input_x_btn = "3" +input_l_btn = "4" +input_r_btn = "5" +input_l2_axis = "+2" +input_r2_axis = "+5" +input_l3_btn = "9" +input_r3_btn = "10" +input_l_x_plus_axis = "+0" +input_l_x_minus_axis = "-0" +input_l_y_plus_axis = "+1" +input_l_y_minus_axis = "-1" +input_r_x_plus_axis = "+3" +input_r_x_minus_axis = "-3" +input_r_y_plus_axis = "+4" +input_r_y_minus_axis = "-4" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/Microsoft Xbox Series S_X Controller.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/Microsoft Xbox Series S_X Controller.cfg new file mode 100644 index 0000000000..4b96332b91 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/Microsoft Xbox Series S_X Controller.cfg @@ -0,0 +1,44 @@ +input_driver = "udev" +input_device = "Microsoft Xbox Series S|X Controller" +input_vendor_id = "1118" +input_product_id = "2834" + +input_b_btn = "0" +input_a_btn = "1" +input_y_btn = "2" +input_x_btn = "3" +input_l_btn = "4" +input_r_btn = "5" + +input_select_btn = "6" +input_start_btn = "7" + +input_up_btn = "h0up" +input_down_btn = "h0down" +input_left_btn = "h0left" +input_right_btn = "h0right" + +input_l2_axis = "+2" +input_r2_axis = "+5" +input_l3_btn = "9" +input_r3_btn = "10" + +input_l_x_plus_axis = "+0" +input_l_x_minus_axis = "-0" +input_l_y_plus_axis = "+1" +input_l_y_minus_axis = "-1" +input_r_x_plus_axis = "+3" +input_r_x_minus_axis = "-3" +input_r_y_plus_axis = "+4" +input_r_y_minus_axis = "-4" + +input_enable_hotkey_btn = "8" +input_exit_emulator_btn = "7" +input_menu_toggle_btn = "3" +input_pause_toggle_btn = "1" +input_fps_toggle_btn = "0" +input_screenshot_btn = "2" +input_load_state_btn = "4" +input_save_state_btn = "5" +input_rewind_axis = "+2" +input_hold_fast_forward_axis = "+5" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/OpenSimHardware OSH PB Controller.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/OpenSimHardware OSH PB Controller.cfg new file mode 100755 index 0000000000..6edd2a183a --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/OpenSimHardware OSH PB Controller.cfg @@ -0,0 +1,44 @@ +input_device = "OpenSimHardware OSH PB Controller" +input_driver = "udev" +input_vendor_id = "4617" +input_product_id = "12544" + +input_b_btn = "1" +input_a_btn = "0" +input_x_btn = "2" +input_y_btn = "3" +input_l_btn = "4" +input_r_btn = "5" +input_l2_btn = "10" +input_r2_btn = "11" + +input_select_btn = "7" +input_start_btn = "6" + +input_l3_btn = "8" +input_r3_btn = "9" + +input_up_btn = "h0up" +input_down_btn = "h0down" +input_left_btn = "h0left" +input_right_btn = "h0right" + +input_l_x_plus_axis = "-0" +input_l_x_minus_axis = "+0" +input_l_y_plus_axis = "-1" +input_l_y_minus_axis = "+1" + +input_r_x_plus_axis = "+2" +input_r_x_minus_axis = "-2" +input_r_y_plus_axis = "+3" +input_r_y_minus_axis = "-3" + +input_enable_hotkey_btn = "7" +input_exit_emulator_btn = "6" + +input_menu_toggle_btn = "2" +input_fps_toggle_btn = "3" + +input_load_state_btn = "4" +input_save_state_btn = "5" + diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/OpenSimHardware OSH PB Controller_SDL.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/OpenSimHardware OSH PB Controller_SDL.cfg new file mode 100644 index 0000000000..f9905f2781 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/OpenSimHardware OSH PB Controller_SDL.cfg @@ -0,0 +1,41 @@ +input_device = "OpenSimHardware OSH PB Controller" +input_driver = "udev" +input_vendor_id = "4617" +input_product_id = "12544" +input_r_y_plus_axis = "+3" +input_l3_btn = "8" +input_r_x_minus_axis = "-2" +input_l_btn = "4" +input_load_state_btn = "4" +input_start_btn = "6" +input_exit_emulator_btn = "6" +input_l_y_minus_axis = "-1" +input_up_btn = "h0up" +input_volume_up_btn = "h0up" +input_r_y_minus_axis = "-3" +input_a_btn = "0" +input_b_btn = "1" +input_screenshot_btn = "16" +input_enable_hotkey_btn = "7" +input_down_btn = "h0down" +input_volume_down_btn = "h0down" +input_l_x_plus_axis = "+0" +input_l_y_plus_axis = "+1" +input_r_btn = "5" +input_save_state_btn = "5" +input_r2_btn = "11" +input_hold_fast_forward_btn = "11" +input_r3_btn = "9" +input_fps_toggle_btn = "9" +input_right_btn = "h0right" +input_state_slot_increase_btn = "h0right" +input_x_btn = "2" +input_menu_toggle_btn = "2" +input_select_btn = "7" +input_l_x_minus_axis = "-0" +input_y_btn = "3" +input_left_btn = "h0left" +input_state_slot_decrease_btn = "h0left" +input_r_x_plus_axis = "+2" +input_l2_btn = "10" +input_rewind_btn = "10" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/RGB20S Gamepad.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/RGB20S Gamepad.cfg new file mode 100644 index 0000000000..3b09cd61f7 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/RGB20S Gamepad.cfg @@ -0,0 +1,44 @@ +input_driver = "udev" +input_device = "RGB20S Gamepad" +input_device_display_name = "RGB20S Gamepad" + +input_b_btn = "0" +input_y_btn = "3" +input_select_btn = "12" +input_start_btn = "13" +input_a_btn = "1" +input_x_btn = "2" +input_l_btn = "4" +input_r_btn = "5" +input_l2_btn = "6" +input_r2_btn = "7" +input_l3_btn = "14" +input_r3_btn = "15" + +input_up_btn = "8" +input_down_btn = "9" +input_left_btn = "10" +input_right_btn = "11" + +input_l_x_plus_axis = "+0" +input_l_x_minus_axis = "-0" +input_l_y_plus_axis = "+1" +input_l_y_minus_axis = "-1" + +input_r_x_plus_axis = "+2" +input_r_x_minus_axis = "-2" +input_r_y_plus_axis = "+3" +input_r_y_minus_axis = "-3" + +# Hotkeys +input_enable_hotkey_btn = "12" +input_exit_emulator_btn = "13" + +input_menu_toggle_btn = "2" +input_fps_toggle_btn = "3" + +input_load_state_btn = "4" +input_save_state_btn = "5" + +input_rewind_btn = "6" +input_toggle_fast_forward_btn = "7" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/ROCKNIX Gamepad.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/ROCKNIX Gamepad.cfg new file mode 100644 index 0000000000..542b465936 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/ROCKNIX Gamepad.cfg @@ -0,0 +1,29 @@ +input_driver = "udev" +input_device = "ArchR Gamepad" +input_vendor_id = "4660" +input_product_id = "22136" +input_b_btn = "0" +input_y_btn = "3" +input_select_btn = "8" +input_start_btn = "9" +input_up_btn = "13" +input_down_btn = "14" +input_left_btn = "15" +input_right_btn = "16" +input_a_btn = "1" +input_x_btn = "2" +input_l_btn = "4" +input_r_btn = "5" +input_l2_btn = "6" +input_r2_btn = "7" +input_l3_btn = "11" +input_r3_btn = "12" +input_l_x_plus_axis = "+0" +input_l_x_minus_axis = "-0" +input_l_y_plus_axis = "-1" +input_l_y_minus_axis = "+1" +input_r_x_plus_axis = "+3" +input_r_x_minus_axis = "-3" +input_r_y_plus_axis = "+4" +input_r_y_minus_axis = "-4" +input_gun_trigger_mbtn = "1" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/Retro Lite CM5 Gamepad.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/Retro Lite CM5 Gamepad.cfg new file mode 100644 index 0000000000..e85b5142bc --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/Retro Lite CM5 Gamepad.cfg @@ -0,0 +1,27 @@ +input_driver = "udev" +input_device = "Retro Lite CM5 Gamepad" +input_b_btn = "0" +input_y_btn = "2" +input_select_btn = "5" +input_start_btn = "4" +input_up_btn = "h0up" +input_down_btn = "h0down" +input_left_btn = "h0left" +input_right_btn = "h0right" +input_a_btn = "1" +input_x_btn = "3" +input_l_btn = "11" +input_r_btn = "10" +input_l2_btn = "6" +input_r2_btn = "7" +input_l3_btn = "12" +input_r3_btn = "13" +input_l_x_plus_axis = "+0" +input_l_x_minus_axis = "-0" +input_l_y_plus_axis = "+1" +input_l_y_minus_axis = "-1" +input_r_x_plus_axis = "+2" +input_r_x_minus_axis = "-2" +input_r_y_plus_axis = "+3" +input_r_y_minus_axis = "-3" +input_enable_hotkey_btn = "14" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/Retroid Pocket Gamepad.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/Retroid Pocket Gamepad.cfg new file mode 100644 index 0000000000..17fb8356af --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/Retroid Pocket Gamepad.cfg @@ -0,0 +1,42 @@ +input_driver = "udev" +input_device = "Retroid Pocket Gamepad" + +input_b_btn = "1" +input_y_btn = "3" +input_select_btn = "4" +input_start_btn = "6" +input_up_btn = "11" +input_down_btn = "12" +input_left_btn = "13" +input_right_btn = "14" +input_a_btn = "0" +input_x_btn = "2" +input_l_btn = "9" +input_r_btn = "10" +input_l2_axis = "+4" +input_r2_axis = "+5" +input_l3_btn = "7" +input_r3_btn = "8" +input_l_x_plus_axis = "+0" +input_l_x_minus_axis = "-0" +input_l_y_plus_axis = "+1" +input_l_y_minus_axis = "-1" +input_r_x_plus_axis = "+2" +input_r_x_minus_axis = "-2" +input_r_y_plus_axis = "+3" +input_r_y_minus_axis = "-3" + +# Hotkeys +input_enable_hotkey_btn = "5" +input_exit_emulator_btn = "6" + +input_menu_toggle_btn = "2" +input_fps_toggle_btn = "3" +input_screenshot_btn = "0" +input_reset_btn = "1" + +input_load_state_btn = "9" +input_save_state_btn = "10" + +input_rewind_axis = "+4" +input_toggle_fast_forward_axis = "+5" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/Steam Controller.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/Steam Controller.cfg new file mode 100644 index 0000000000..8331e7cbac --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/Steam Controller.cfg @@ -0,0 +1,32 @@ +input_driver = "udev" +input_device = "Steam Controller" +input_vendor_id = "10462" +input_product_id = "4613" +input_b_btn = "5" +input_y_btn = "7" +input_select_btn = "13" +input_start_btn = "14" +input_up_btn = "20" +input_down_btn = "21" +input_left_btn = "22" +input_right_btn = "23" +input_a_btn = "6" +input_x_btn = "8" +input_l_btn = "9" +input_r_btn = "10" +input_l2_btn = "11" +input_r2_btn = "2" +input_l3_btn = "16" +input_r3_axis = "-1" +input_l_x_plus_axis = "+0" +input_l_x_minus_axis = "-0" +input_l_y_plus_axis = "+1" +input_l_y_minus_axis = "-1" +input_r_x_plus_axis = "+3" +input_r_x_minus_axis = "-3" +input_r_y_plus_axis = "+4" +input_r_y_minus_axis = "-4" +input_l2_axis = "+4" +input_r2_axis = "+2" +input_r3_btn = "17" +input_gun_trigger_mbtn = "1" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/XU Mini M Gamepad.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/XU Mini M Gamepad.cfg new file mode 100644 index 0000000000..b32cd84915 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/XU Mini M Gamepad.cfg @@ -0,0 +1,35 @@ +input_driver = "udev" +input_device = "XU Mini M Gamepad" +input_device_display_name = "MagicX XU Mini M Gamepad" +input_b_btn = "0" +input_y_btn = "3" +input_select_btn = "8" +input_start_btn = "9" +input_up_btn = "12" +input_down_btn = "13" +input_left_btn = "14" +input_right_btn = "15" +input_a_btn = "1" +input_x_btn = "2" +input_l_btn = "4" +input_r_btn = "5" +input_l2_btn = "6" +input_r2_btn = "7" +input_l3_btn = "10" +input_r3_btn = "11" +input_l_x_plus_axis = "+1" +input_l_x_minus_axis = "-1" +input_l_y_plus_axis = "-0" +input_l_y_minus_axis = "+0" +input_r_x_plus_axis = "+3" +input_r_x_minus_axis = "-3" +input_r_y_plus_axis = "-2" +input_r_y_minus_axis = "+2" +input_enable_hotkey_btn = "16" +input_exit_emulator_btn = "9" +input_menu_toggle_btn = "2" +input_fps_toggle_btn = "3" +input_load_state_btn = "4" +input_save_state_btn = "5" +input_rewind_btn = "6" +input_toggle_fast_forward_btn = "7" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/XU10 Gamepad.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/XU10 Gamepad.cfg new file mode 100644 index 0000000000..ba2d42a8d5 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/XU10 Gamepad.cfg @@ -0,0 +1,52 @@ +input_device = "XU10 Gamepad" +input_driver = "udev" +input_device_display_name = "MagicX XU10 Gamepad" + +input_b_btn = "1" +input_a_btn = "2" +input_x_btn = "3" +input_y_btn = "0" +input_l_btn = "4" +input_r_btn = "5" +input_l2_btn = "7" +input_r2_btn = "6" + +input_up_btn = "12" +input_down_btn = "13" +input_left_btn = "14" +input_right_btn = "15" + +input_select_btn = "8" +input_start_btn = "9" + +input_l3_btn = "10" +input_r3_btn = "11" + +input_l_x_plus_axis = "+0" +input_l_x_minus_axis = "-0" +input_l_y_plus_axis = "+1" +input_l_y_minus_axis = "-1" + +input_r_x_plus_axis = "+2" +input_r_x_minus_axis = "-2" +input_r_y_plus_axis = "+3" +input_r_y_minus_axis = "-3" + + +# Hotkeys +input_enable_hotkey_btn = "16" +input_exit_emulator_btn = "9" + +input_screenshot_btn = "0" +input_pause_toggle_btn = "1" +input_menu_toggle_btn = "2" +input_fps_toggle_btn = "3" + +input_state_slot_increase_btn = "7" +input_state_slot_decrease_btn = "6" + +input_load_state_btn = "4" +input_save_state_btn = "5" + +input_rewind_btn = "10" +input_toggle_fast_forward_btn = "11" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/Xbox 360 Controller.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/Xbox 360 Controller.cfg new file mode 100644 index 0000000000..788729c2d4 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/Xbox 360 Controller.cfg @@ -0,0 +1,42 @@ +input_driver = "udev" +input_device = "Xbox 360 Controller" +input_vendor_id = "1118" +input_product_id = "654" + +input_b_btn = "1" +input_a_btn = "0" +input_y_btn = "3" +input_x_btn = "2" +input_l_btn = "9" +input_r_btn = "10" + +input_select_btn = "4" +input_start_btn = "6" +input_up_btn = "11" +input_down_btn = "12" +input_left_btn = "13" +input_right_btn = "14" +input_l2_axis = "+4" +input_r2_axis = "+5" +input_l3_btn = "7" +input_r3_btn = "8" +input_l_x_plus_axis = "+0" +input_l_x_minus_axis = "-0" +input_l_y_plus_axis = "+1" +input_l_y_minus_axis = "-1" +input_r_x_plus_axis = "+2" +input_r_x_minus_axis = "-2" +input_r_y_plus_axis = "+3" +input_r_y_minus_axis = "-3" + +input_enable_hotkey_btn = "5" +input_exit_emulator_btn = "6" +input_menu_toggle_btn = "2" +input_pause_toggle_btn = "0" +input_fps_toggle_btn = "3" +input_screenshot_btn = "nul" +input_load_state_btn = "9" +input_save_state_btn = "10" +input_state_slot_increase_btn = "nul" +input_state_slot_decrease_btn = "nul" +input_menu_toggle_gamepad_combo = "nul" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/odroidgo2_joypad.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/odroidgo2_joypad.cfg new file mode 100644 index 0000000000..489d064618 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/odroidgo2_joypad.cfg @@ -0,0 +1,37 @@ +input_driver = "udev" +input_device = "odroidgo2_joypad" +input_device_display_name = "Odroid GO Advance Joypad" + +input_b_btn = "0" +input_y_btn = "3" +input_select_btn = "10" +input_start_btn = "13" +input_a_btn = "1" +input_x_btn = "2" +input_l_btn = "4" +input_r_btn = "5" +input_l2_btn = "11" +input_r2_btn = "12" + +input_up_btn = "6" +input_down_btn = "7" +input_left_btn = "8" +input_right_btn = "9" + +input_l_x_plus_axis = "+0" +input_l_x_minus_axis = "-0" +input_l_y_plus_axis = "+1" +input_l_y_minus_axis = "-1" + +# Hotkeys +input_enable_hotkey_btn = "10" +input_exit_emulator_btn = "13" + +input_menu_toggle_btn = "2" +input_fps_toggle_btn = "3" + +input_load_state_btn = "4" +input_save_state_btn = "5" + +input_rewind_btn = "11" +input_toggle_fast_forward_btn = "12" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/odroidgo2_v11_joypad.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/odroidgo2_v11_joypad.cfg new file mode 100644 index 0000000000..ec35a92031 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/odroidgo2_v11_joypad.cfg @@ -0,0 +1,39 @@ +input_driver = "udev" +input_device = "odroidgo2_v11_joypad" +input_device_display_name = "Odroid GO Advance Joypad v1.1" + +input_b_btn = "0" +input_y_btn = "3" +input_select_btn = "8" +input_start_btn = "9" +input_a_btn = "1" +input_x_btn = "2" +input_l_btn = "4" +input_r_btn = "5" +input_l2_btn = "6" +input_r2_btn = "7" +input_l3_btn = "10" +input_r3_btn = "11" + +input_up_btn = "12" +input_down_btn = "13" +input_left_btn = "14" +input_right_btn = "15" + +input_l_x_plus_axis = "+0" +input_l_x_minus_axis = "-0" +input_l_y_plus_axis = "+1" +input_l_y_minus_axis = "-1" + +# Hotkeys +input_enable_hotkey_btn = "8" +input_exit_emulator_btn = "9" + +input_menu_toggle_btn = "2" +input_fps_toggle_btn = "3" + +input_load_state_btn = "4" +input_save_state_btn = "5" + +input_rewind_btn = "6" +input_toggle_fast_forward_btn = "7" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/odroidgo3_joypad.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/odroidgo3_joypad.cfg new file mode 100644 index 0000000000..8904a82396 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/odroidgo3_joypad.cfg @@ -0,0 +1,44 @@ +input_driver = "udev" +input_device = "odroidgo3_joypad" +input_device_display_name = "Odroid GO Super" + +input_b_btn = "0" +input_y_btn = "3" +input_select_btn = "8" +input_start_btn = "9" +input_a_btn = "1" +input_x_btn = "2" +input_l_btn = "4" +input_r_btn = "5" +input_l2_btn = "6" +input_r2_btn = "7" +input_l3_btn = "10" +input_r3_btn = "11" + +input_up_btn = "12" +input_down_btn = "13" +input_left_btn = "14" +input_right_btn = "15" + +input_l_x_plus_axis = "+0" +input_l_x_minus_axis = "-0" +input_l_y_plus_axis = "+1" +input_l_y_minus_axis = "-1" + +input_r_x_plus_axis = "+2" +input_r_x_minus_axis = "-2" +input_r_y_plus_axis = "+3" +input_r_y_minus_axis = "-3" + +# Hotkeys +input_enable_hotkey_btn = "8" +input_exit_emulator_btn = "9" + +input_menu_toggle_btn = "2" +input_fps_toggle_btn = "3" + +input_load_state_btn = "4" +input_save_state_btn = "5" + +input_rewind_btn = "6" +input_toggle_fast_forward_btn = "7" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/r33s_joypad.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/r33s_joypad.cfg new file mode 100644 index 0000000000..1067ae2c4a --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/r33s_joypad.cfg @@ -0,0 +1,32 @@ +input_driver = "udev" +input_device = "r33s_joypad" +input_device_display_name = "R33S Joypad" + +input_b_btn = "0" +input_y_btn = "3" +input_select_btn = "8" +input_start_btn = "9" +input_a_btn = "1" +input_x_btn = "2" +input_l_btn = "4" +input_r_btn = "5" +input_l2_btn = "6" +input_r2_btn = "7" + +input_up_btn = "10" +input_down_btn = 11" +input_left_btn = "12" +input_right_btn = "13" + +# Hotkeys +input_enable_hotkey_btn = "8" +input_exit_emulator_btn = "9" + +input_menu_toggle_btn = "2" +input_fps_toggle_btn = "3" + +input_load_state_btn = "4" +input_save_state_btn = "5" + +input_rewind_btn = "6" +input_toggle_fast_forward_btn = "7" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/r36s_Gamepad.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/r36s_Gamepad.cfg new file mode 100644 index 0000000000..aab534b319 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/r36s_Gamepad.cfg @@ -0,0 +1,35 @@ +input_driver = "udev" +input_device = "r36s_Gamepad" +input_device_display_name = "R36S" +input_b_btn = "0" +input_y_btn = "3" +input_select_btn = "8" +input_start_btn = "9" +input_a_btn = "1" +input_x_btn = "2" +input_l_btn = "4" +input_r_btn = "5" +input_l2_btn = "6" +input_r2_btn = "7" +input_l3_btn = "11" +input_r3_btn = "12" +input_up_btn = "13" +input_down_btn = "14" +input_left_btn = "15" +input_right_btn = "16" +input_l_x_plus_axis = "+0" +input_l_x_minus_axis = "-0" +input_l_y_plus_axis = "+1" +input_l_y_minus_axis = "-1" +input_r_x_plus_axis = "+2" +input_r_x_minus_axis = "-2" +input_r_y_plus_axis = "+3" +input_r_y_minus_axis = "-3" +input_enable_hotkey_btn = "8" +input_exit_emulator_btn = "9" +input_menu_toggle_btn = "2" +input_fps_toggle_btn = "3" +input_load_state_btn = "4" +input_save_state_btn = "5" +input_rewind_btn = "6" +input_toggle_fast_forward_btn = "7" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/retrogame_joypad.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/retrogame_joypad.cfg new file mode 100644 index 0000000000..b6a11487b4 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/retrogame_joypad.cfg @@ -0,0 +1,56 @@ +input_driver = "udev" +input_device = "retrogame_joypad" +input_vendor_id = "18507" +input_product_id = "4353" +input_a = "x" +input_a_btn = "1" +input_analog_dpad_mode = "0" +input_b = "z" +input_b_btn = "0" +input_down = "down" +input_down_btn = "14" +input_gun_trigger_mbtn = "1" +input_joypad_index = "0" +input_l = "q" +input_l2_btn = "6" +input_l3_btn = "11" +input_l_btn = "4" +input_l_x_minus_axis = "-0" +input_l_x_plus_axis = "+0" +input_l_y_minus_axis = "-1" +input_l_y_plus_axis = "+1" +input_left = "left" +input_left_btn = "15" +input_mouse_index = "0" +input_r = "w" +input_r2_btn = "7" +input_r3_btn = "12" +input_r_btn = "5" +input_r_x_minus_axis = "-2" +input_r_x_plus_axis = "+2" +input_r_y_minus_axis = "-3" +input_r_y_plus_axis = "+3" +input_right = "right" +input_right_btn = "16" +input_select = "rshift" +input_select_btn = "8" +input_start = "enter" +input_start_btn = "9" +input_up = "up" +input_up_btn = "13" +input_x = "s" +input_x_btn = "2" +input_y = "a" +input_y_btn = "3" +input_enable_hotkey_btn = "8" +input_exit_emulator_btn = "9" +input_screenshot_btn = "nul" +input_pause_toggle_btn = "nul" +input_menu_toggle_btn = "2" +input_fps_toggle_btn = "3" +input_state_slot_increase_btn = "nul" +input_state_slot_decrease_btn = "nul" +input_load_state_btn = "4" +input_save_state_btn = "5" +input_rewind_btn = "6" +input_toggle_fast_forward_btn = "7" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/retrogame_joypad_s1_f2.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/retrogame_joypad_s1_f2.cfg new file mode 100644 index 0000000000..d1d51e107f --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/retrogame_joypad_s1_f2.cfg @@ -0,0 +1,31 @@ +input_driver = "udev" +input_device = "retrogame_joypad_s1_f2" +input_device_display_name = "Retro console gamepad" +input_b_btn = "0" +input_y_btn = "3" +input_select_btn = "8" +input_start_btn = "9" +input_up_btn = "13" +input_down_btn = "14" +input_left_btn = "15" +input_right_btn = "16" +input_a_btn = "1" +input_x_btn = "2" +input_l_btn = "4" +input_r_btn = "5" +input_l2_btn = "6" +input_r2_btn = "7" +input_l3_btn = "11" +input_r3_btn = "12" +input_l_x_plus_axis = "+0" +input_l_x_minus_axis = "-0" +input_l_y_plus_axis = "+1" +input_l_y_minus_axis = "-1" +input_enable_hotkey_btn = "10" +input_exit_emulator_btn = "9" +input_menu_toggle_btn = "2" +input_fps_toggle_btn = "3" +input_load_state_btn = "4" +input_save_state_btn = "5" +input_rewind_btn = "6" +input_toggle_fast_forward_btn = "7" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/rg552_joypad.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/rg552_joypad.cfg new file mode 100644 index 0000000000..5d15bc8847 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/rg552_joypad.cfg @@ -0,0 +1,47 @@ +input_driver = "udev" +input_device = "rg552_joypad" +input_device_display_name = "Anbernic RG552 Joypad" + +input_b_btn = "0" +input_a_btn = "1" +input_x_btn = "2" +input_y_btn = "3" + +input_select_btn = "8" +input_start_btn = "9" + + +input_l_btn = "4" +input_r_btn = "5" +input_l2_btn = "6" +input_r2_btn = "7" +input_l3_btn = "11" +input_r3_btn = "12" + +input_up_btn = "13" +input_down_btn = "14" +input_left_btn = "15" +input_right_btn = "16" + +input_l_x_minus_axis = "-0" +input_l_x_plus_axis = "+0" +input_l_y_minus_axis = "-1" +input_l_y_plus_axis = "+1" + +input_r_x_minus_axis = "-2" +input_r_x_plus_axis = "+2" +input_r_y_minus_axis = "-3" +input_r_y_plus_axis = "+3" + +# Hotkeys +input_enable_hotkey_btn = "8" +input_exit_emulator_btn = "9" + +input_menu_toggle_btn = "2" +input_fps_toggle_btn = "3" + +input_load_state_btn = "4" +input_save_state_btn = "5" + +input_rewind_btn = "11" +input_toggle_fast_forward_btn = "12" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/rg_arc_joypad.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/rg_arc_joypad.cfg new file mode 100644 index 0000000000..8850d7c3fa --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/rg_arc_joypad.cfg @@ -0,0 +1,41 @@ +input_driver = "udev" +input_device = "rg_arc_joypad" +input_device_display_name = "Anbernic RG ARC" + + +input_b_btn = "1" +input_b_btn_label = "A" +input_y_btn = "3" +input_y_btn_label = "X" +input_select_btn = "10" +input_start_btn = "11" +input_a_btn = "0" +input_a_btn_label = "B" +input_x_btn = "4" +input_x_btn_label = "Y" +input_l_btn = "6" +input_r_btn = "7" +input_l2_btn = "8" +input_r2_btn = "9" + +input_up_btn = "12" +input_down_btn = 13" +input_left_btn = "14" +input_right_btn = "15" + +input_l3_btn = "5" +input_l3_btn_label = "Z" +input_r3_btn = "2" +input_r3_btn_label = "C" +# Hotkeys +input_enable_hotkey_btn = "10" +input_exit_emulator_btn = "11" + +input_menu_toggle_btn = "4" +input_fps_toggle_btn = "3" + +input_load_state_btn = "6" +input_save_state_btn = "7" + +input_rewind_btn = "8" +input_toggle_fast_forward_btn = "9" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/zed_joystick.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/zed_joystick.cfg new file mode 100644 index 0000000000..1a48b91395 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/gamepads/zed_joystick.cfg @@ -0,0 +1,39 @@ +input_driver = "udev" +input_device = "zed_joystick" +input_b_btn = "1" +input_y_btn = "3" +input_select_btn = "8" +input_start_btn = "9" +input_up_btn = "13" +input_down_btn = "14" +input_left_btn = "15" +input_right_btn = "16" +input_a_btn = "0" +input_x_btn = "2" +input_l_btn = "4" +input_r_btn = "5" +input_l2_btn = "6" +input_r2_btn = "7" +input_l3_btn = "11" +input_r3_btn = "12" +input_l_x_plus_axis = "+0" +input_l_x_minus_axis = "-0" +input_l_y_plus_axis = "+1" +input_l_y_minus_axis = "-1" +input_r_x_plus_axis = "+2" +input_r_x_minus_axis = "-2" +input_r_y_plus_axis = "+3" +input_r_y_minus_axis = "-3" +input_gun_trigger_mbtn = "1" +input_enable_hotkey_btn = "8" +input_exit_emulator_btn = "9" +input_screenshot_btn = "nul" +input_pause_toggle_btn = "nul" +input_menu_toggle_btn = "2" +input_fps_toggle_btn = "3" +input_state_slot_increase_btn = "nul" +input_state_slot_decrease_btn = "nul" +input_load_state_btn = "4" +input_save_state_btn = "5" +input_rewind_btn = "6" +input_toggle_fast_forward_btn = "7" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/package.mk b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/package.mk new file mode 100644 index 0000000000..124360b9ea --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/package.mk @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="retroarch-joypads" +PKG_VERSION="38cf938bba0adbde375972053068f10d955a9d14" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/libretro/retroarch-joypad-autoconfig" +PKG_URL="https://github.com/libretro/retroarch-joypad-autoconfig/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="" +PKG_LONGDESC="RetroArch joypad autoconfigs." +PKG_TOOLCHAIN="manual" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/share/libretro/autoconfig + cp -an ${PKG_BUILD}/{linuxraw,sdl2,udev,x,xinput}/*.cfg ${INSTALL}/usr/share/libretro/autoconfig + cp -a ${PKG_DIR}/gamepads/* ${INSTALL}/usr/share/libretro/autoconfig +} + +post_install() { + enable_service tmp-joypads.mount +} diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/system.d/tmp-joypads.mount b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/system.d/tmp-joypads.mount new file mode 100644 index 0000000000..c038bee1bf --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-joypads/system.d/tmp-joypads.mount @@ -0,0 +1,14 @@ +[Unit] +Description=Joypad configs directory +After=systemd-tmpfiles-setup.service +RequiresMountsFor=/storage +DefaultDependencies=no + +[Mount] +What=none +Where=/tmp/joypads +Type=overlay +Options=lowerdir=/usr/share/libretro/autoconfig,upperdir=/storage/joypads,workdir=/storage/.tmp/joypads-workdir + +[Install] +WantedBy=archr.target diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-overlays/package.mk b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-overlays/package.mk new file mode 100644 index 0000000000..df0f501e4b --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/retroarch-overlays/package.mk @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="retroarch-overlays" +PKG_VERSION="ea3f2bf187ae814fdd90431cf796dfe1438cf98c" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/libretro/common-overlays" +PKG_URL="https://github.com/libretro/common-overlays/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="" +PKG_LONGDESC="Collection of overlay files for use with libretro frontends, such as RetroArch." +PKG_TOOLCHAIN="manual" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/share/retroarch-overlays + cp -a ${PKG_BUILD}/{borders,ctr,effects,keyboards,misc} ${INSTALL}/usr/share/retroarch-overlays +} diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/scripts/call_achievements_hooks.sh b/projects/ArchR/packages/emulators/libretro/retroarch/scripts/call_achievements_hooks.sh new file mode 100755 index 0000000000..47fc59ffa8 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/scripts/call_achievements_hooks.sh @@ -0,0 +1,19 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile.d/001-functions + +# Get Cheevos LED state +CHEEVOS_LED=$(get_setting "global.retroachievements.leds") +if [ ! -n "${CHEEVOS_LED}" ]; then + set_setting "global.retroachievements.leds" "0" +fi + +if [ "${CHEEVOS_LED}" == "1" ]; then + if [ -f "/usr/lib/autostart/quirks/devices/${QUIRK_DEVICE}/bin/achievements" ]; then + "/usr/lib/autostart/quirks/devices/${QUIRK_DEVICE}/bin/achievements" $* & + elif [ -f "/usr/lib/autostart/quirks/platforms/${HW_DEVICE}/bin/achievements" ]; then + "/usr/lib/autostart/quirks/platforms/${HW_DEVICE}/bin/achievements" $* & + fi +fi diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sounds/ff-victory-orchestra.ogg b/projects/ArchR/packages/emulators/libretro/retroarch/sounds/ff-victory-orchestra.ogg new file mode 100644 index 0000000000..251334118c Binary files /dev/null and b/projects/ArchR/packages/emulators/libretro/retroarch/sounds/ff-victory-orchestra.ogg differ diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sounds/mario-1up.ogg b/projects/ArchR/packages/emulators/libretro/retroarch/sounds/mario-1up.ogg new file mode 100644 index 0000000000..0d5131e566 Binary files /dev/null and b/projects/ArchR/packages/emulators/libretro/retroarch/sounds/mario-1up.ogg differ diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sounds/mario-mushroom.ogg b/projects/ArchR/packages/emulators/libretro/retroarch/sounds/mario-mushroom.ogg new file mode 100644 index 0000000000..97d3bb1c2b Binary files /dev/null and b/projects/ArchR/packages/emulators/libretro/retroarch/sounds/mario-mushroom.ogg differ diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sounds/mgs-alert.ogg b/projects/ArchR/packages/emulators/libretro/retroarch/sounds/mgs-alert.ogg new file mode 100644 index 0000000000..c281e19b1f Binary files /dev/null and b/projects/ArchR/packages/emulators/libretro/retroarch/sounds/mgs-alert.ogg differ diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sounds/ps3-trophy.ogg b/projects/ArchR/packages/emulators/libretro/retroarch/sounds/ps3-trophy.ogg new file mode 100644 index 0000000000..c1e1a5c93c Binary files /dev/null and b/projects/ArchR/packages/emulators/libretro/retroarch/sounds/ps3-trophy.ogg differ diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sounds/sonic-ring.ogg b/projects/ArchR/packages/emulators/libretro/retroarch/sounds/sonic-ring.ogg new file mode 100644 index 0000000000..471434cf50 Binary files /dev/null and b/projects/ArchR/packages/emulators/libretro/retroarch/sounds/sonic-ring.ogg differ diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sounds/xbox360-achievement.ogg b/projects/ArchR/packages/emulators/libretro/retroarch/sounds/xbox360-achievement.ogg new file mode 100644 index 0000000000..35265e4d53 Binary files /dev/null and b/projects/ArchR/packages/emulators/libretro/retroarch/sounds/xbox360-achievement.ogg differ diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sounds/zelda-secret.ogg b/projects/ArchR/packages/emulators/libretro/retroarch/sounds/zelda-secret.ogg new file mode 100644 index 0000000000..afce6a046c Binary files /dev/null and b/projects/ArchR/packages/emulators/libretro/retroarch/sounds/zelda-secret.ogg differ diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/H700/TATE-MAME 2003-Plus.rmp b/projects/ArchR/packages/emulators/libretro/retroarch/sources/H700/TATE-MAME 2003-Plus.rmp new file mode 100755 index 0000000000..366e47afad --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/H700/TATE-MAME 2003-Plus.rmp @@ -0,0 +1,27 @@ +input_libretro_device_p1 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_player1_analog_dpad_mode = "1" +input_player1_btn_down = "6" +input_player1_btn_left = "4" +input_player1_btn_right = "5" +input_player1_btn_up = "7" +input_player1_stk_l_x+ = "5" +input_player1_stk_l_x- = "4" +input_player1_stk_l_y+ = "6" +input_player1_stk_l_y- = "7" +input_player1_stk_r_x+ = "5" +input_player1_stk_r_x- = "4" +input_player1_stk_r_y+ = "6" +input_player1_stk_r_y- = "7" +input_player2_analog_dpad_mode = "0" +input_player3_analog_dpad_mode = "0" +input_player4_analog_dpad_mode = "0" +input_player5_analog_dpad_mode = "0" +input_remap_port_p1 = "0" +input_remap_port_p2 = "1" +input_remap_port_p3 = "2" +input_remap_port_p4 = "3" +input_remap_port_p5 = "4" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/H700/retroarch-core-options.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/H700/retroarch-core-options.cfg new file mode 100755 index 0000000000..8ccae69cf1 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/H700/retroarch-core-options.cfg @@ -0,0 +1,153 @@ +mupen64plus-alt-map = "False" +mupen64plus-aspect = "4:3" +mupen64plus-astick-deadzone = "15" +mupen64plus-astick-sensitivity = "100" +mupen64plus-BackgroundMode = "Stripped" +mupen64plus-BilinearMode = "standard" +mupen64plus-CorrectTexrectCoords = "Auto" +mupen64plus-CountPerOp = "0" +mupen64plus-CountPerOpDenomPot = "0" +mupen64plus-cpucore = "dynamic_recompiler" +mupen64plus-d-cbutton = "C3" +mupen64plus-DitheringPattern = "True" +mupen64plus-DitheringQuantization = "True" +mupen64plus-EnableCopyAuxToRDRAM = "True" +mupen64plus-EnableCopyColorToRDRAM = "Async" +mupen64plus-EnableCopyDepthToRDRAM = "Software" +mupen64plus-EnableEnhancedHighResStorage = "False" +mupen64plus-EnableEnhancedTextureStorage = "False" +mupen64plus-EnableFBEmulation = "True" +mupen64plus-EnableFragmentDepthWrite = "False" +mupen64plus-EnableHiResAltCRC = "False" +mupen64plus-EnableHWLighting = "True" +mupen64plus-EnableInaccurateTextureCoordinates = "False" +mupen64plus-EnableLegacyBlending = "False" +mupen64plus-EnableLODEmulation = "True" +mupen64plus-EnableNativeResFactor = "1" +mupen64plus-EnableNativeResTexrects = "Optimized" +mupen64plus-EnableOverscan = "Enabled" +mupen64plus-EnableTexCoordBounds = "False" +mupen64plus-EnableTextureCache = "True" +mupen64plus-ForceDisableExtraMem = "False" +mupen64plus-FrameDuping = "True" +mupen64plus-Framerate = "Original" +mupen64plus-FXAA = "0" +mupen64plus-GLideN64IniBehaviour = "late" +mupen64plus-HybridFilter = "True" +mupen64plus-IgnoreTLBExceptions = "False" +mupen64plus-l-cbutton = "C2" +mupen64plus-MaxHiResTxVramLimit = "0" +mupen64plus-MaxTxCacheSize = "8000" +mupen64plus-MultiSampling = "0" +mupen64plus-OverscanBottom = "0" +mupen64plus-OverscanLeft = "0" +mupen64plus-OverscanRight = "0" +mupen64plus-OverscanTop = "0" +mupen64plus-pak1 = "memory" +mupen64plus-pak2 = "none" +mupen64plus-pak3 = "none" +mupen64plus-pak4 = "none" +mupen64plus-r-cbutton = "C1" +mupen64plus-rdp-plugin = "gliden64" +mupen64plus-RDRAMImageDitheringMode = "BlueNoise" +mupen64plus-rsp-plugin = "hle" +mupen64plus-ThreadedRenderer = "True" +mupen64plus-txCacheCompression = "True" +mupen64plus-txEnhancementMode = "None" +mupen64plus-txFilterIgnoreBG = "True" +mupen64plus-txFilterMode = "None" +mupen64plus-txHiresEnable = "False" +mupen64plus-txHiresFullAlphaChannel = "False" +mupen64plus-u-cbutton = "C4" +mupen64plus-virefresh = "Auto" +pcsx_rearmed_analog_axis_modifier = "circle" +pcsx_rearmed_async_cd = "sync" +pcsx_rearmed_bios = "auto" +pcsx_rearmed_display_internal_fps = "disabled" +pcsx_rearmed_dithering = "enabled" +pcsx_rearmed_drc = "enabled" +pcsx_rearmed_duping_enable = "enabled" +pcsx_rearmed_frameskip_type = "disabled" +pcsx_rearmed_gteregsunneeded = "disabled" +pcsx_rearmed_gunconadjustratiox = "1" +pcsx_rearmed_gunconadjustratioy = "1" +pcsx_rearmed_gunconadjustx = "0" +pcsx_rearmed_gunconadjusty = "0" +pcsx_rearmed_idiablofix = "disabled" +pcsx_rearmed_input_sensitivity = "1.00" +pcsx_rearmed_inuyasha_fix = "disabled" +pcsx_rearmed_memcard2 = "disabled" +pcsx_rearmed_multitap1 = "auto" +pcsx_rearmed_multitap2 = "auto" +pcsx_rearmed_negcon_deadzone = "0" +pcsx_rearmed_negcon_response = "linear" +pcsx_rearmed_neon_enhancement_enable = "disabled" +pcsx_rearmed_neon_enhancement_no_main = "disabled" +pcsx_rearmed_neon_interlace_enable = "disabled" +pcsx_rearmed_nocdaudio = "enabled" +pcsx_rearmed_nogteflags = "disabled" +pcsx_rearmed_nosmccheck = "disabled" +pcsx_rearmed_noxadecoding = "enabled" +pcsx_rearmed_pad1type = "standard" +pcsx_rearmed_pad2type = "standard" +pcsx_rearmed_pad3type = "none" +pcsx_rearmed_pad4type = "none" +pcsx_rearmed_pad5type = "none" +pcsx_rearmed_pad6type = "none" +pcsx_rearmed_pad7type = "none" +pcsx_rearmed_pad8type = "none" +pcsx_rearmed_pe2_fix = "disabled" +pcsx_rearmed_psxclock = "57" +pcsx_rearmed_region = "auto" +pcsx_rearmed_show_bios_bootlogo = "disabled" +pcsx_rearmed_show_other_input_settings = "disabled" +pcsx_rearmed_spu_interpolation = "simple" +pcsx_rearmed_spu_reverb = "enabled" +pcsx_rearmed_spuirq = "disabled" +pcsx_rearmed_vibration = "enabled" +gambatte_gb_colorization = "disabled" +gambatte_gb_internal_palette = "" +mame2003-plus_analog = "digital" +mame2003-plus_art_resolution = "1" +mame2003-plus_brightness = "1.0" +mame2003-plus_cheat_input_ports = "disabled" +mame2003-plus_core_save_subfolder = "enabled" +mame2003-plus_core_sys_subfolder = "enabled" +mame2003-plus_dcs_speedhack = "enabled" +mame2003-plus_deadzone = "20" +mame2003-plus_digital_joy_centering = "enabled" +mame2003-plus_display_artwork = "enabled" +mame2003-plus_display_setup = "disabled" +mame2003-plus_four_way_emulation = "disabled" +mame2003-plus_frameskip = "0" +mame2003-plus_gamma = "1.0" +mame2003-plus_input_interface = "retropad" +mame2003-plus_machine_timing = "enabled" +mame2003-plus_mame_remapping = "enabled" +mame2003-plus_mouse_device = "mouse" +mame2003-plus_sample_rate = "48000" +mame2003-plus_skip_disclaimer = "disabled" +mame2003-plus_skip_warnings = "disabled" +flycast_internal_resolution = "640x480" +flycast_alpha_sorting = "per-strip (fast, least accurate)" +flycast_enable_dsp = "disabled" +flycast_threaded_rendering = "enabled" +flycast_anisotropic_filtering = "off" +flycast_synchronous_rendering = "enabled" +flycast_enable_rtt = "disabled" +flycast_enable_rttb = "disabled" +flycast_delay_frame_swapping = "disabled" +flycast_div_matching = "auto" +flycast_texupscale = "off" +flycast_auto_skip_frame = "normal" +opera_swi_hle = "enabled" +opera_dsp_threaded = "enabled" +opera_madam_matrix_engine = "software" +puae_deadzone = "25" +melonds_screen_layout = "Left/Right" +melonds_swapscreen_mode = "Toggle" +melonds_threaded_renderer = "enabled" +melonds_touch_mode = "Joystick" +virtualjaguar_bios = "enabled" +virtualjaguar_usefastblitter = "enabled" +swanstation_GPU_Renderer = "Software" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/H700/retroarch.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/H700/retroarch.cfg new file mode 100755 index 0000000000..a893ac85ab --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/H700/retroarch.cfg @@ -0,0 +1,817 @@ +accessibility_enable = "false" +accessibility_narrator_speech_speed = "5" +ai_service_enable = "true" +ai_service_mode = "1" +ai_service_pause = "false" +ai_service_source_lang = "0" +ai_service_target_lang = "0" +ai_service_url = "http://localhost:4404/" +all_users_control_menu = "true" +apply_cheats_after_load = "false" +apply_cheats_after_toggle = "false" +aspect_ratio_index = "22" +assets_directory = "/tmp/assets" +audio_block_frames = "0" +audio_device = "" +audio_driver = "alsathread" +audio_dsp_plugin = "" +audio_enable_menu_bgm = "false" +audio_enable_menu_cancel = "false" +audio_enable_menu = "false" +audio_enable_menu_notice = "false" +audio_enable_menu_ok = "false" +audio_enable = "true" +audio_fastforward_mute = "false" +audio_filter_dir = "~/.config/retroarch/filters/audio" +audio_max_timing_skew = "0.049999" +audio_mixer_mute_enable = "false" +audio_mixer_volume = "0.000000" +audio_mute_enable = "false" +audio_out_rate = "44100" +audio_rate_control_delta = "0.004999" +audio_rate_control = "true" +audio_resampler_quality = "2" +audio_resampler = "sinc" +audio_sync = "true" +audio_volume = "0.000000" +auto_overrides_enable = "true" +auto_remaps_enable = "true" +autosave_interval = "10" +auto_screenshot_filename = "true" +auto_shaders_enable = "true" +block_sram_overwrite = "false" +bluetooth_driver = "null" +builtin_imageviewer_enable = "false" +builtin_mediaplayer_enable = "true" +bundle_assets_dst_path = "" +bundle_assets_dst_path_subdir = "" +bundle_assets_extract_enable = "false" +bundle_assets_extract_last_version = "0" +bundle_assets_extract_version_current = "0" +bundle_assets_src_path = "" +cache_directory = "/tmp/cache" +camera_allow = "false" +camera_device = "" +camera_driver = "null" +cheat_database_path = "/tmp/database/cht" +check_firmware_before_loading = "false" +cheevos_auto_screenshot = "false" +cheevos_badges_enable = "false" +cheevos_challenge_indicators = "true" +cheevos_enable = "false" +cheevos_hardcore_mode_enable = "false" +cheevos_leaderboards_enable = "" +cheevos_password = "" +cheevos_richpresence_enable = "true" +cheevos_start_active = "false" +cheevos_test_unofficial = "false" +cheevos_token = "" +cheevos_unlock_sound_enable = "false" +cheevos_username = "" +cheevos_verbose_enable = "false" +config_save_on_exit = "false" +content_database_path = "/tmp/database/rdb" +content_favorites_directory = "default" +content_favorites_path = "~/.config/retroarch/content_favorites.lpl" +content_favorites_size = "200" +content_history_dir = "" +content_history_directory = "default" +content_history_path = "~/.config/retroarch/content_history.lpl" +content_history_size = "200" +content_image_history_directory = "default" +content_image_history_path = "~/.config/retroarch/content_image_history.lpl" +content_music_history_directory = "default" +content_music_history_path = "~/.config/retroarch/content_music_history.lpl" +content_runtime_log_aggregate = "false" +content_runtime_log = "true" +content_show_add_entry = "2" +content_show_add = "true" +content_show_explore = "true" +content_show_favorites = "true" +content_show_history = "true" +content_show_images = "false" +content_show_music = "false" +content_show_netplay = "true" +content_show_playlists = "true" +content_show_settings_password = "" +content_show_settings = "true" +content_show_video = "false" +content_video_directory = "default" +content_video_history_path = "~/.config/retroarch/content_video_history.lpl" +core_assets_directory = "~/roms/downloads" +core_info_cache_enable = "true" +core_option_category_enable = "true" +core_options_path = "" +core_set_supports_no_game_enable = "true" +core_updater_auto_backup = "false" +core_updater_auto_backup_history_size = "1" +core_updater_auto_extract_archive = "true" +core_updater_buildbot_assets_url = "http://buildbot.libretro.com/assets/" +core_updater_buildbot_cores_url = "" +core_updater_buildbot_url = "http://buildbot.libretro.com/nightly/linux/armhf/latest/" +core_updater_show_experimental_cores = "false" +cpu_main_gov = "performance" +cpu_max_freq = "-1" +cpu_menu_gov = "powersave" +cpu_min_freq = "1" +cpu_scaling_mode = "0" +crt_switch_center_adjust = "0" +crt_switch_hires_menu = "false" +crt_switch_porch_adjust = "0" +crt_switch_resolution = "0" +crt_switch_resolution_super = "2560" +crt_switch_resolution_use_custom_refresh_rate = "false" +crt_switch_timings = "" +crt_video_refresh_rate = "60.000000" +current_resolution_id = "0" +cursor_directory = "~/.config/retroarch/database/cursors" +desktop_menu_enable = "true" +discord_allow = "false" +discord_app_id = "475456035851599874" +driver_switch_enable = "true" +dynamic_wallpapers_directory = "default" +emuelec_exit_to_kodi = "false" +enable_device_vibration = "true" +facebook_stream_key = "" +fastforward_ratio = "0.000000" +filter_by_current_core = "false" +flicker_filter_enable = "false" +flicker_filter_index = "0" +fps_show = "false" +fps_update_interval = "256" +framecount_show = "false" +frame_time_counter_reset_after_fastforwarding = "false" +frame_time_counter_reset_after_load_state = "false" +frame_time_counter_reset_after_save_state = "false" +frontend_log_level = "1" +game_specific_options = "true" +gamma_correction = "0" +global_core_options = "false" +history_list_enable = "true" +input_ai_service_axis = "nul" +input_ai_service_btn = "nul" +input_ai_service_mbtn = "nul" +input_ai_service = "nul" +input_analog_deadzone = "0.000000" +input_analog_sensitivity = "1.500000" +input_audio_mute_axis = "nul" +input_audio_mute_btn = "nul" +input_audio_mute = "f9" +input_audio_mute_mbtn = "nul" +input_autodetect_enable = "true" +input_auto_game_focus = "0" +input_auto_mouse_grab = "false" +input_axis_threshold = "0.500000" +input_bind_hold = "2" +input_bind_timeout = "5" +input_cheat_index_minus_axis = "nul" +input_cheat_index_minus_btn = "nul" +input_cheat_index_minus_mbtn = "nul" +input_cheat_index_minus = "t" +input_cheat_index_plus_axis = "nul" +input_cheat_index_plus_btn = "nul" +input_cheat_index_plus_mbtn = "nul" +input_cheat_index_plus = "y" +input_cheat_toggle_axis = "nul" +input_cheat_toggle_btn = "nul" +input_cheat_toggle_mbtn = "nul" +input_cheat_toggle = "u" +input_close_content_axis = "nul" +input_close_content_btn = "nul" +input_close_content_mbtn = "nul" +input_close_content = "nul" +input_descriptor_hide_unbound = "false" +input_descriptor_label_show = "true" +input_desktop_menu_toggle_axis = "nul" +input_desktop_menu_toggle_btn = "nul" +input_desktop_menu_toggle = "f5" +input_desktop_menu_toggle_mbtn = "nul" +input_device_p1 = "0" +input_device_p10 = "0" +input_device_p11 = "0" +input_device_p12 = "0" +input_device_p13 = "0" +input_device_p14 = "0" +input_device_p15 = "0" +input_device_p16 = "0" +input_device_p2 = "0" +input_device_p3 = "0" +input_device_p4 = "0" +input_device_p5 = "0" +input_device_p6 = "0" +input_device_p7 = "0" +input_device_p8 = "0" +input_device_p9 = "0" +input_disk_eject_toggle_axis = "nul" +input_disk_eject_toggle_btn = "nul" +input_disk_eject_toggle_mbtn = "nul" +input_disk_eject_toggle = "nul" +input_disk_next_axis = "nul" +input_disk_next_btn = "nul" +input_disk_next_mbtn = "nul" +input_disk_next = "nul" +input_disk_prev_axis = "nul" +input_disk_prev_btn = "nul" +input_disk_prev_mbtn = "nul" +input_disk_prev = "nul" +input_driver = "udev" +input_duty_cycle = "3" +input_enable_hotkey_axis = "nul" +input_enable_hotkey_mbtn = "nul" +input_enable_hotkey = "nul" +input_exit_emulator_axis = "nul" +input_exit_emulator_btn = "9" +input_exit_emulator = "escape" +input_exit_emulator_mbtn = "nul" +input_fps_toggle_axis = "nul" +input_fps_toggle = "f3" +input_fps_toggle_mbtn = "nul" +input_frame_advance_axis = "nul" +input_frame_advance_btn = "nul" +input_frame_advance = "k" +input_frame_advance_mbtn = "nul" +input_game_focus_toggle_axis = "nul" +input_game_focus_toggle_btn = "nul" +input_game_focus_toggle_mbtn = "nul" +input_game_focus_toggle = "scroll_lock" +input_grab_mouse_toggle_axis = "nul" +input_grab_mouse_toggle_btn = "nul" +input_grab_mouse_toggle = "f11" +input_grab_mouse_toggle_mbtn = "nul" +input_hold_fast_forward_axis = "nul" +input_hold_fast_forward_btn = "nul" +input_hold_fast_forward = "l" +input_hold_fast_forward_mbtn = "nul" +input_hold_slowmotion_axis = "nul" +input_hold_slowmotion_btn = "nul" +input_hold_slowmotion = "e" +input_hold_slowmotion_mbtn = "nul" +input_hotkey_block_delay = "5" +input_joypad_driver = "udev" +input_keyboard_layout = "" +input_libretro_device_p10 = "1" +input_libretro_device_p1 = "1" +input_libretro_device_p11 = "1" +input_libretro_device_p12 = "1" +input_libretro_device_p13 = "1" +input_libretro_device_p14 = "1" +input_libretro_device_p15 = "1" +input_libretro_device_p16 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_libretro_device_p6 = "1" +input_libretro_device_p7 = "1" +input_libretro_device_p8 = "1" +input_libretro_device_p9 = "1" +input_load_state_axis = "nul" +input_load_state_btn = "4" +input_load_state = "f4" +input_load_state_mbtn = "nul" +input_max_users = "5" +input_menu_toggle_axis = "nul" +input_menu_toggle = "f1" +input_menu_toggle_gamepad_combo = "0" +input_menu_toggle_mbtn = "nul" +input_movie_record_toggle_axis = "nul" +input_movie_record_toggle_btn = "nul" +input_movie_record_toggle_mbtn = "nul" +input_movie_record_toggle = "o" +input_netplay_game_watch_axis = "nul" +input_netplay_game_watch_btn = "nul" +input_netplay_game_watch = "i" +input_netplay_game_watch_mbtn = "nul" +input_netplay_host_toggle_axis = "nul" +input_netplay_host_toggle_btn = "nul" +input_netplay_host_toggle_mbtn = "nul" +input_netplay_host_toggle = "nul" +input_nowinkey_enable = "false" +input_osk_toggle_axis = "nul" +input_osk_toggle_btn = "nul" +input_osk_toggle = "f12" +input_osk_toggle_mbtn = "nul" +input_overlay = "" +input_overlay_aspect_adjust_landscape = "0.000000" +input_overlay_aspect_adjust_portrait = "0.000000" +input_overlay_auto_rotate = "false" +input_overlay_auto_scale = "false" +input_overlay_enable_autopreferred = "true" +input_overlay_enable = "false" +input_overlay_hide_in_menu = "true" +input_overlay_hide_when_gamepad_connected = "false" +input_overlay_next_axis = "nul" +input_overlay_next_btn = "nul" +input_overlay_next_mbtn = "nul" +input_overlay_next = "nul" +input_overlay_opacity = "0.700000" +input_overlay_scale_landscape = "1.000000" +input_overlay_scale_portrait = "1.000000" +input_overlay_show_inputs = "2" +input_overlay_show_inputs_port = "0" +input_overlay_show_mouse_cursor = "true" +input_overlay_x_offset_landscape = "0.000000" +input_overlay_x_offset_portrait = "0.000000" +input_overlay_x_separation_landscape = "0.000000" +input_overlay_x_separation_portrait = "0.000000" +input_overlay_y_offset_landscape = "0.000000" +input_overlay_y_offset_portrait = "0.000000" +input_overlay_y_separation_landscape = "0.000000" +input_overlay_y_separation_portrait = "0.000000" +input_pause_toggle_axis = "nul" +input_pause_toggle_btn = "nul" +input_pause_toggle_mbtn = "nul" +input_pause_toggle = "p" +input_poll_type_behavior = "2" +input_quit_gamepad_combo = "0" +input_recording_toggle_axis = "nul" +input_recording_toggle_btn = "nul" +input_recording_toggle_mbtn = "nul" +input_recording_toggle = "nul" +input_remap_binds_enable = "true" +input_remapping_directory = "~/remappings" +input_reset_axis = "nul" +input_reset_btn = "nul" +input_reset = "h" +input_reset_mbtn = "nul" +input_rewind_axis = "nul" +input_rewind_btn = "6" +input_rewind_mbtn = "nul" +input_rewind = "r" +input_rumble_gain = "100" +input_runahead_toggle_axis = "nul" +input_runahead_toggle_btn = "nul" +input_runahead_toggle_mbtn = "nul" +input_runahead_toggle = "nul" +input_save_state_axis = "nul" +input_save_state_btn = "5" +input_save_state = "f2" +input_save_state_mbtn = "nul" +input_screenshot_axis = "nul" +input_screenshot_btn = "nul" +input_screenshot = "f8" +input_screenshot_mbtn = "nul" +input_send_debug_info_axis = "nul" +input_send_debug_info_btn = "nul" +input_send_debug_info = "f10" +input_send_debug_info_mbtn = "nul" +input_sensors_enable = "true" +input_shader_next_axis = "nul" +input_shader_next_btn = "nul" +input_shader_next = "m" +input_shader_next_mbtn = "nul" +input_shader_prev_axis = "nul" +input_shader_prev_btn = "nul" +input_shader_prev_mbtn = "nul" +input_shader_prev = "n" +input_state_slot_decrease_axis = "nul" +input_state_slot_decrease_btn = "nul" +input_state_slot_decrease = "f6" +input_state_slot_decrease_mbtn = "nul" +input_state_slot_increase_axis = "nul" +input_state_slot_increase_btn = "nul" +input_state_slot_increase = "f7" +input_state_slot_increase_mbtn = "nul" +input_streaming_toggle_axis = "nul" +input_streaming_toggle_btn = "nul" +input_streaming_toggle_mbtn = "nul" +input_streaming_toggle = "nul" +input_toggle_fast_forward_axis = "nul" +input_toggle_fast_forward_btn = "7" +input_toggle_fast_forward_mbtn = "nul" +input_toggle_fast_forward = "space" +input_toggle_fullscreen_axis = "nul" +input_toggle_fullscreen_btn = "nul" +input_toggle_fullscreen = "f" +input_toggle_fullscreen_mbtn = "nul" +input_toggle_slowmotion_axis = "nul" +input_toggle_slowmotion_btn = "nul" +input_toggle_slowmotion_mbtn = "nul" +input_toggle_slowmotion = "nul" +input_touch_scale = "1" +input_turbo_default_button = "0" +input_turbo_mode = "0" +input_turbo_period = "6" +input_volume_down_axis = "nul" +input_volume_down_btn = "nul" +input_volume_down_mbtn = "nul" +input_volume_down = "subtract" +input_volume_up = "add" +input_volume_up_axis = "nul" +input_volume_up_btn = "nul" +input_volume_up_mbtn = "nul" +joypad_autoconfig_dir = "/tmp/joypads" +keyboard_gamepad_enable = "true" +keyboard_gamepad_mapping_type = "1" +kiosk_mode_enable = "false" +kiosk_mode_password = "" +led_driver = "null" +libretro_directory = "/tmp/cores" +libretro_info_path = "/tmp/cores" +libretro_log_level = "1" +load_dummy_on_core_shutdown = "true" +location_allow = "false" +location_driver = "null" +log_dir = "~/.config/retroarch/logs" +log_to_file = "false" +log_to_file_timestamp = "false" +log_verbosity = "true" +materialui_auto_rotate_nav_bar = "true" +materialui_dual_thumbnail_list_view_enable = "true" +materialui_icons_enable = "true" +materialui_landscape_layout_optimization = "1" +materialui_menu_color_theme = "9" +materialui_menu_transition_animation = "0" +materialui_playlist_icons_enable = "true" +materialui_show_nav_bar = "true" +materialui_thumbnail_background_enable = "true" +materialui_thumbnail_view_landscape = "2" +materialui_thumbnail_view_portrait = "1" +memory_show = "false" +memory_update_interval = "256" +menu_battery_level_enable = "true" +menu_core_enable = "true" +menu_dynamic_wallpaper_enable = "false" +menu_enable_widgets = "true" +menu_font_color_blue = "255" +menu_font_color_green = "255" +menu_font_color_red = "255" +menu_footer_opacity = "1.000000" +menu_framebuffer_opacity = "0.899999" +menu_header_opacity = "1.000000" +menu_horizontal_animation = "true" +menu_insert_disk_resume = "true" +menu_left_thumbnails = "0" +menu_linear_filter = "false" +menu_mouse_enable = "false" +menu_navigation_browser_filter_supported_extensions_enable = "true" +menu_navigation_wraparound_enable = "true" +menu_pause_libretro = "true" +menu_pointer_enable = "false" +menu_rgui_full_width_layout = "true" +menu_rgui_shadows = "false" +menu_rgui_transparency = "true" +menu_savestate_resume = "true" +menu_scale_factor = "0.300000" +menu_screensaver_animation = "0" +menu_screensaver_animation_speed = "1.000000" +menu_screensaver_timeout = "0" +menu_scroll_delay = "256" +menu_scroll_fast = "false" +menu_shader_pipeline = "2" +menu_show_advanced_settings = "true" +menu_show_configurations = "true" +menu_show_core_updater = "false" +menu_show_dump_disc = "true" +menu_show_help = "true" +menu_show_information = "true" +menu_show_latency = "true" +menu_show_legacy_thumbnail_updater = "false" +menu_show_load_content_animation = "false" +menu_show_load_content = "true" +menu_show_load_core = "true" +menu_show_load_disc = "true" +menu_show_online_updater = "true" +menu_show_overlays = "true" +menu_show_quit_retroarch = "true" +menu_show_reboot = "false" +menu_show_restart_retroarch = "true" +menu_show_rewind = "true" +menu_show_shutdown = "false" +menu_show_sublabels = "true" +menu_show_video_layout = "true" +menu_swap_ok_cancel_buttons = "false" +menu_throttle_framerate = "true" +menu_thumbnails = "3" +menu_thumbnail_upscale_threshold = "0" +menu_ticker_smooth = "true" +menu_ticker_speed = "2.000000" +menu_ticker_type = "1" +menu_timedate_date_separator = "0" +menu_timedate_enable = "true" +menu_timedate_style = "11" +menu_unified_controls = "false" +menu_use_preferred_system_color_theme = "false" +menu_wallpaper = "" +menu_wallpaper_opacity = "1.000000" +menu_widget_scale_auto = "false" +menu_widget_scale_factor = "0.400000" +menu_widget_scale_factor_windowed = "1.000000" +menu_xmb_animation_horizontal_highlight = "0" +menu_xmb_animation_move_up_down = "0" +menu_xmb_animation_opening_main_menu = "0" +menu_xmb_thumbnail_scale_factor = "100" +midi_driver = "alsa" +midi_input = "Off" +midi_output = "Off" +midi_volume = "100" +netplay_allow_slaves = "true" +netplay_check_frames = "600" +netplay_input_latency_frames_min = "0" +netplay_input_latency_frames_range = "0" +netplay_ip_address = "" +netplay_ip_port = "55435" +netplay_max_connections = "3" +netplay_mitm_server = "nyc" +netplay_nat_traversal = "true" +netplay_nickname = "" +netplay_password = "" +netplay_public_announce = "true" +netplay_request_device_p10 = "false" +netplay_request_device_p11 = "false" +netplay_request_device_p12 = "false" +netplay_request_device_p13 = "false" +netplay_request_device_p14 = "false" +netplay_request_device_p15 = "false" +netplay_request_device_p16 = "false" +netplay_request_device_p1 = "false" +netplay_request_device_p2 = "false" +netplay_request_device_p3 = "false" +netplay_request_device_p4 = "false" +netplay_request_device_p5 = "false" +netplay_request_device_p6 = "false" +netplay_request_device_p7 = "false" +netplay_request_device_p8 = "false" +netplay_request_device_p9 = "false" +netplay_require_slaves = "false" +netplay_share_analog = "1" +netplay_share_digital = "1" +netplay_spectate_password = "" +netplay_start_as_spectator = "false" +netplay_stateless_mode = "false" +netplay_use_mitm_server = "false" +network_cmd_enable = "false" +network_cmd_port = "55355" +network_on_demand_thumbnails = "false" +network_remote_base_port = "55400" +network_remote_enable = "false" +network_remote_enable_user_p10 = "false" +network_remote_enable_user_p11 = "false" +network_remote_enable_user_p12 = "false" +network_remote_enable_user_p13 = "false" +network_remote_enable_user_p14 = "false" +network_remote_enable_user_p15 = "false" +network_remote_enable_user_p16 = "false" +network_remote_enable_user_p1 = "false" +network_remote_enable_user_p2 = "false" +network_remote_enable_user_p3 = "false" +network_remote_enable_user_p4 = "false" +network_remote_enable_user_p5 = "false" +network_remote_enable_user_p6 = "false" +network_remote_enable_user_p7 = "false" +network_remote_enable_user_p8 = "false" +network_remote_enable_user_p9 = "false" +notification_show_autoconfig = "false" +notification_show_cheats_applied = "true" +notification_show_config_override_load = "false" +notification_show_fast_forward = "true" +notification_show_netplay_extra = "false" +notification_show_patch_applied = "true" +notification_show_refresh_rate = "true" +notification_show_remap_load = "false" +notification_show_screenshot_duration = "2" +notification_show_screenshot = "false" +notification_show_screenshot_flash = "1" +notification_show_set_initial_disk = "true" +overlay_directory = "/tmp/overlays" +ozone_collapse_sidebar = "false" +ozone_menu_color_theme = "1" +ozone_scroll_content_metadata = "false" +ozone_sort_after_truncate_playlist_name = "true" +ozone_truncate_playlist_name = "true" +pause_nonactive = "true" +perfcnt_enable = "false" +playlist_compression = "false" +playlist_cores = "" +playlist_directory = "~/playlists" +playlist_entry_remove_enable = "1" +playlist_entry_remove = "false" +playlist_entry_rename = "false" +playlist_fuzzy_archive_match = "false" +playlist_names = "" +playlist_portable_paths = "false" +playlist_show_entry_idx = "true" +playlist_show_inline_core_name = "0" +playlist_show_sublabels = "true" +playlist_sort_alphabetical = "true" +playlist_sublabel_last_played_style = "0" +playlist_sublabel_runtime_type = "0" +playlist_use_old_format = "false" +quick_menu_show_add_to_favorites = "true" +quick_menu_show_cheats = "true" +quick_menu_show_close_content = "true" +quick_menu_show_controls = "true" +quick_menu_show_core_options_flush = "false" +quick_menu_show_download_thumbnails = "true" +quick_menu_show_information = "true" +quick_menu_show_options = "true" +quick_menu_show_recording = "true" +quick_menu_show_reset_core_association = "true" +quick_menu_show_restart_content = "true" +quick_menu_show_resume_content = "true" +quick_menu_show_save_content_dir_overrides = "true" +quick_menu_show_save_core_overrides = "false" +quick_menu_show_save_game_overrides = "false" +quick_menu_show_save_load_state = "true" +quick_menu_show_set_core_association = "true" +quick_menu_show_shaders = "true" +quick_menu_show_start_recording = "true" +quick_menu_show_start_streaming = "true" +quick_menu_show_streaming = "true" +quick_menu_show_take_screenshot = "true" +quick_menu_show_undo_save_load_state = "false" +quit_on_close_content = "0" +quit_press_twice = "true" +record_driver = "null" +recording_config_directory = "" +recording_output_directory = "~/roms/screenshots" +resampler_directory = "" +rewind_buffer_size = "20971520" +rewind_buffer_size_step = "10" +rewind_enable = "false" +rewind_granularity = "1" +rgui_aspect_ratio = "0" +rgui_aspect_ratio_lock = "0" +rgui_background_filler_thickness_enable = "true" +rgui_border_filler_enable = "true" +rgui_border_filler_thickness_enable = "true" +rgui_browser_directory = "~/roms" +rgui_config_directory = "~/.config/retroarch/config" +rgui_extended_ascii = "false" +rgui_inline_thumbnails = "false" +rgui_internal_upscale_level = "0" +rgui_menu_color_theme = "4" +rgui_menu_theme_preset = "" +rgui_particle_effect = "0" +rgui_particle_effect_screensaver = "true" +rgui_particle_effect_speed = "1.000000" +rgui_show_start_screen = "false" +rgui_swap_thumbnails = "false" +rgui_switch_icons = "true" +rgui_thumbnail_delay = "0" +rgui_thumbnail_downscaler = "0" +run_ahead_enabled = "false" +run_ahead_frames = "1" +run_ahead_hide_warnings = "false" +run_ahead_secondary_instance = "true" +runtime_log_directory = "default" +save_file_compression = "false" +savefile_directory = "~/.config/retroarch/saves" +savefiles_in_content_dir = "true" +savestate_auto_index = "false" +savestate_auto_load = "false" +savestate_auto_save = "false" +savestate_directory = "~/.config/retroarch/states" +savestate_file_compression = "true" +savestate_max_keep = "0" +savestates_in_content_dir = "false" +savestate_thumbnail_enable = "true" +scan_without_core_match = "false" +screen_brightness = "100" +screen_orientation = "0" +screenshot_directory = "~/roms/screenshots" +screenshots_in_content_dir = "false" +settings_show_accessibility = "true" +settings_show_achievements = "true" +settings_show_ai_service = "true" +settings_show_audio = "true" +settings_show_configuration = "true" +settings_show_core = "true" +settings_show_directory = "true" +settings_show_drivers = "true" +settings_show_file_browser = "true" +settings_show_frame_throttle = "true" +settings_show_input = "true" +settings_show_latency = "true" +settings_show_logging = "true" +settings_show_network = "true" +settings_show_onscreen_display = "true" +settings_show_playlists = "true" +settings_show_power_management = "true" +settings_show_recording = "true" +settings_show_saving = "true" +settings_show_user_interface = "true" +settings_show_user = "true" +settings_show_video = "true" +show_hidden_files = "false" +slowmotion_ratio = "3.000000" +soft_filter_enable = "false" +soft_filter_index = "0" +sort_savefiles_by_content_enable = "false" +sort_savefiles_enable = "false" +sort_savestates_by_content_enable = "false" +sort_savestates_enable = "false" +sort_screenshots_by_content_enable = "false" +state_slot = "0" +statistics_show = "false" +stdin_cmd_enable = "false" +streaming_mode = "0" +suspend_screensaver_enable = "true" +sustained_performance_mode = "false" +system_directory = "~/roms/bios" +systemfiles_in_content_dir = "false" +threaded_data_runloop_enable = "true" +thumbnails_directory = "~/thumbnails" +twitch_stream_key = "" +ui_companion_enable = "false" +ui_companion_start_on_boot = "true" +ui_companion_toggle = "false" +ui_menubar_enable = "true" +use_last_start_directory = "false" +user_language = "0" +vibrate_on_keypress = "true" +video_adaptive_vsync = "false" +video_allow_rotate = "true" +video_aspect_ratio = "-1.000000" +video_aspect_ratio_auto = "true" +video_black_frame_insertion = "0" +video_context_driver = "" +video_crop_overscan = "true" +video_ctx_scaling = "false" +video_disable_composition = "false" +video_driver = "glcore" +video_filter = "" +video_filter_dir = "~/.config/retroarch/filters/video" +video_font_enable = "true" +video_font_path = "/usr/share/retroarch-assets/xmb/monochrome/font.ttf" +video_font_size = "32.000000" +video_force_aspect = "true" +video_force_srgb_disable = "false" +video_frame_delay = "0" +video_frame_delay_auto = "false" +video_fullscreen = "true" +video_fullscreen_x = "640" +video_fullscreen_y = "480" +video_gpu_record = "false" +video_gpu_screenshot = "false" +video_hard_sync = "false" +video_hard_sync_frames = "0" +video_hdr_display_contrast = "5.000000" +video_hdr_enable = "false" +video_hdr_expand_gamut = "true" +video_hdr_max_nits = "1000.000000" +video_hdr_paper_white_nits = "200.000000" +video_layout_directory = "~/.config/retroarch/layouts" +video_layout_enable = "true" +video_layout_path = "" +video_layout_selected_view = "0" +video_max_swapchain_images = "3" +video_message_color = "ffff00" +video_message_pos_x = "0.049999" +video_message_pos_y = "0.049999" +video_monitor_index = "0" +video_msg_bgcolor_blue = "0" +video_msg_bgcolor_enable = "false" +video_msg_bgcolor_green = "0" +video_msg_bgcolor_opacity = "1.000000" +video_msg_bgcolor_red = "0" +video_notch_write_over_enable = "false" +video_oga_vertical_enable = "false" +video_post_filter_record = "false" +video_record_config = "" +video_record_quality = "4" +video_record_scale_factor = "1" +video_record_threads = "2" +video_refresh_rate = "60.000000" +video_rotation = "0" +video_scale = "3.000000" +video_scale_integer = "false" +video_scale_integer_overscale = "false" +video_shader_delay = "0" +video_shader_dir = "/tmp/shaders" +video_shader_enable = "false" +video_shader_preset_save_reference_enable = "true" +video_shader_remember_last_dir = "false" +video_shader_watch_files = "false" +video_shared_context = "false" +video_smooth = "false" +video_stream_config = "" +video_stream_port = "56400" +video_stream_quality = "10" +video_stream_scale_factor = "1" +video_stream_url = "" +video_swap_interval = "1" +video_threaded = "true" +video_vsync = "true" +video_window_auto_height_max = "480" +video_window_auto_width_max = "640" +video_window_custom_size_enable = "false" +video_windowed_fullscreen = "false" +video_windowed_position_height = "720" +video_windowed_position_width = "1280" +video_windowed_position_x = "0" +video_windowed_position_y = "0" +video_window_opacity = "100" +video_window_save_positions = "false" +video_window_show_decorations = "true" +vrr_runloop_enable = "false" +wifi_driver = "null" +wifi_enabled = "true" +xmb_alpha_factor = "75" +xmb_font = "/usr/share/retroarch-assets/xmb/monochrome/font.ttf" +xmb_layout = "2" +xmb_menu_color_theme = "4" +xmb_shadows_enable = "true" +xmb_theme = "0" +xmb_vertical_thumbnails = "false" +youtube_stream_key = "" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/H700/retroarch32bit-append.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/H700/retroarch32bit-append.cfg new file mode 100755 index 0000000000..343124c254 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/H700/retroarch32bit-append.cfg @@ -0,0 +1,3 @@ +audio_filter_dir = "/usr/share/retroarch/filters/32bit/audio" +video_filter_dir = "/usr/share/retroarch/filters/32bit/video" +libretro_directory = /usr/lib32/libretro diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/H700/retroarch64bit-append.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/H700/retroarch64bit-append.cfg new file mode 100755 index 0000000000..b6cbf68312 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/H700/retroarch64bit-append.cfg @@ -0,0 +1,2 @@ +audio_filter_dir = "/usr/share/retroarch/filters/64bit/audio" +video_filter_dir = "/usr/share/retroarch/filters/64bit/video" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3326/TATE-MAME 2003-Plus.rmp b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3326/TATE-MAME 2003-Plus.rmp new file mode 100755 index 0000000000..366e47afad --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3326/TATE-MAME 2003-Plus.rmp @@ -0,0 +1,27 @@ +input_libretro_device_p1 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_player1_analog_dpad_mode = "1" +input_player1_btn_down = "6" +input_player1_btn_left = "4" +input_player1_btn_right = "5" +input_player1_btn_up = "7" +input_player1_stk_l_x+ = "5" +input_player1_stk_l_x- = "4" +input_player1_stk_l_y+ = "6" +input_player1_stk_l_y- = "7" +input_player1_stk_r_x+ = "5" +input_player1_stk_r_x- = "4" +input_player1_stk_r_y+ = "6" +input_player1_stk_r_y- = "7" +input_player2_analog_dpad_mode = "0" +input_player3_analog_dpad_mode = "0" +input_player4_analog_dpad_mode = "0" +input_player5_analog_dpad_mode = "0" +input_remap_port_p1 = "0" +input_remap_port_p2 = "1" +input_remap_port_p3 = "2" +input_remap_port_p4 = "3" +input_remap_port_p5 = "4" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3326/retroarch-core-options.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3326/retroarch-core-options.cfg new file mode 100755 index 0000000000..0bcbaa2661 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3326/retroarch-core-options.cfg @@ -0,0 +1,152 @@ +mupen64plus-alt-map = "False" +mupen64plus-aspect = "4:3" +mupen64plus-astick-deadzone = "15" +mupen64plus-astick-sensitivity = "100" +mupen64plus-BackgroundMode = "Stripped" +mupen64plus-BilinearMode = "standard" +mupen64plus-CorrectTexrectCoords = "Auto" +mupen64plus-CountPerOp = "0" +mupen64plus-CountPerOpDenomPot = "0" +mupen64plus-cpucore = "dynamic_recompiler" +mupen64plus-d-cbutton = "C3" +mupen64plus-DitheringPattern = "True" +mupen64plus-DitheringQuantization = "True" +mupen64plus-EnableCopyAuxToRDRAM = "True" +mupen64plus-EnableCopyColorToRDRAM = "Async" +mupen64plus-EnableCopyDepthToRDRAM = "Software" +mupen64plus-EnableEnhancedHighResStorage = "False" +mupen64plus-EnableEnhancedTextureStorage = "False" +mupen64plus-EnableFBEmulation = "True" +mupen64plus-EnableFragmentDepthWrite = "False" +mupen64plus-EnableHiResAltCRC = "False" +mupen64plus-EnableHWLighting = "True" +mupen64plus-EnableInaccurateTextureCoordinates = "False" +mupen64plus-EnableLegacyBlending = "False" +mupen64plus-EnableLODEmulation = "True" +mupen64plus-EnableNativeResFactor = "1" +mupen64plus-EnableNativeResTexrects = "Optimized" +mupen64plus-EnableOverscan = "Enabled" +mupen64plus-EnableTexCoordBounds = "False" +mupen64plus-EnableTextureCache = "True" +mupen64plus-ForceDisableExtraMem = "False" +mupen64plus-FrameDuping = "True" +mupen64plus-Framerate = "Original" +mupen64plus-FXAA = "0" +mupen64plus-GLideN64IniBehaviour = "late" +mupen64plus-HybridFilter = "True" +mupen64plus-IgnoreTLBExceptions = "False" +mupen64plus-l-cbutton = "C2" +mupen64plus-MaxHiResTxVramLimit = "0" +mupen64plus-MaxTxCacheSize = "8000" +mupen64plus-MultiSampling = "0" +mupen64plus-OverscanBottom = "0" +mupen64plus-OverscanLeft = "0" +mupen64plus-OverscanRight = "0" +mupen64plus-OverscanTop = "0" +mupen64plus-pak1 = "memory" +mupen64plus-pak2 = "none" +mupen64plus-pak3 = "none" +mupen64plus-pak4 = "none" +mupen64plus-r-cbutton = "C1" +mupen64plus-rdp-plugin = "gliden64" +mupen64plus-RDRAMImageDitheringMode = "BlueNoise" +mupen64plus-rsp-plugin = "hle" +mupen64plus-ThreadedRenderer = "True" +mupen64plus-txCacheCompression = "True" +mupen64plus-txEnhancementMode = "None" +mupen64plus-txFilterIgnoreBG = "True" +mupen64plus-txFilterMode = "None" +mupen64plus-txHiresEnable = "False" +mupen64plus-txHiresFullAlphaChannel = "False" +mupen64plus-u-cbutton = "C4" +mupen64plus-virefresh = "Auto" +pcsx_rearmed_analog_axis_modifier = "circle" +pcsx_rearmed_async_cd = "sync" +pcsx_rearmed_bios = "auto" +pcsx_rearmed_display_internal_fps = "disabled" +pcsx_rearmed_dithering = "enabled" +pcsx_rearmed_drc = "enabled" +pcsx_rearmed_duping_enable = "enabled" +pcsx_rearmed_frameskip_type = "disabled" +pcsx_rearmed_gteregsunneeded = "disabled" +pcsx_rearmed_gunconadjustratiox = "1" +pcsx_rearmed_gunconadjustratioy = "1" +pcsx_rearmed_gunconadjustx = "0" +pcsx_rearmed_gunconadjusty = "0" +pcsx_rearmed_idiablofix = "disabled" +pcsx_rearmed_input_sensitivity = "1.00" +pcsx_rearmed_inuyasha_fix = "disabled" +pcsx_rearmed_memcard2 = "disabled" +pcsx_rearmed_multitap1 = "auto" +pcsx_rearmed_multitap2 = "auto" +pcsx_rearmed_negcon_deadzone = "0" +pcsx_rearmed_negcon_response = "linear" +pcsx_rearmed_neon_enhancement_enable = "disabled" +pcsx_rearmed_neon_enhancement_no_main = "disabled" +pcsx_rearmed_neon_interlace_enable = "disabled" +pcsx_rearmed_nocdaudio = "enabled" +pcsx_rearmed_nogteflags = "disabled" +pcsx_rearmed_nosmccheck = "disabled" +pcsx_rearmed_noxadecoding = "enabled" +pcsx_rearmed_pad1type = "standard" +pcsx_rearmed_pad2type = "standard" +pcsx_rearmed_pad3type = "none" +pcsx_rearmed_pad4type = "none" +pcsx_rearmed_pad5type = "none" +pcsx_rearmed_pad6type = "none" +pcsx_rearmed_pad7type = "none" +pcsx_rearmed_pad8type = "none" +pcsx_rearmed_pe2_fix = "disabled" +pcsx_rearmed_psxclock = "57" +pcsx_rearmed_region = "auto" +pcsx_rearmed_show_bios_bootlogo = "disabled" +pcsx_rearmed_show_other_input_settings = "disabled" +pcsx_rearmed_spu_interpolation = "simple" +pcsx_rearmed_spu_reverb = "enabled" +pcsx_rearmed_spuirq = "disabled" +pcsx_rearmed_vibration = "enabled" +gambatte_gb_colorization = "disabled" +gambatte_gb_internal_palette = "" +mame2003-plus_analog = "digital" +mame2003-plus_art_resolution = "1" +mame2003-plus_brightness = "1.0" +mame2003-plus_cheat_input_ports = "disabled" +mame2003-plus_core_save_subfolder = "enabled" +mame2003-plus_core_sys_subfolder = "enabled" +mame2003-plus_dcs_speedhack = "enabled" +mame2003-plus_deadzone = "20" +mame2003-plus_digital_joy_centering = "enabled" +mame2003-plus_display_artwork = "enabled" +mame2003-plus_display_setup = "disabled" +mame2003-plus_four_way_emulation = "disabled" +mame2003-plus_frameskip = "0" +mame2003-plus_gamma = "1.0" +mame2003-plus_input_interface = "retropad" +mame2003-plus_machine_timing = "enabled" +mame2003-plus_mame_remapping = "enabled" +mame2003-plus_mouse_device = "mouse" +mame2003-plus_sample_rate = "48000" +mame2003-plus_skip_disclaimer = "disabled" +mame2003-plus_skip_warnings = "disabled" +flycast_internal_resolution = "640x480" +flycast_alpha_sorting = "per-strip (fast, least accurate)" +flycast_enable_dsp = "disabled" +flycast_threaded_rendering = "enabled" +flycast_anisotropic_filtering = "off" +flycast_synchronous_rendering = "enabled" +flycast_enable_rtt = "disabled" +flycast_enable_rttb = "disabled" +flycast_delay_frame_swapping = "disabled" +flycast_div_matching = "auto" +flycast_texupscale = "off" +flycast_auto_skip_frame = "normal" +opera_swi_hle = "enabled" +opera_dsp_threaded = "enabled" +opera_madam_matrix_engine = "software" +puae_deadzone = "25" +melonds_screen_layout = "Left/Right" +melonds_swapscreen_mode = "Toggle" +melonds_threaded_renderer = "enabled" +melonds_touch_mode = "Joystick" +virtualjaguar_bios = "enabled" +virtualjaguar_usefastblitter = "enabled" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3326/retroarch.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3326/retroarch.cfg new file mode 100755 index 0000000000..099eec8426 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3326/retroarch.cfg @@ -0,0 +1,822 @@ +accessibility_enable = "false" +accessibility_narrator_speech_speed = "5" +ai_service_enable = "true" +ai_service_mode = "1" +ai_service_pause = "false" +ai_service_source_lang = "0" +ai_service_target_lang = "0" +ai_service_url = "http://localhost:4404/" +all_users_control_menu = "true" +apply_cheats_after_load = "false" +apply_cheats_after_toggle = "false" +aspect_ratio_index = "22" +assets_directory = "/tmp/assets" +audio_block_frames = "0" +audio_device = "" +audio_driver = "alsathread" +audio_dsp_plugin = "" +audio_enable_menu_bgm = "false" +audio_enable_menu_cancel = "false" +audio_enable_menu = "false" +audio_enable_menu_notice = "false" +audio_enable_menu_ok = "false" +audio_enable = "true" +audio_fastforward_mute = "false" +audio_filter_dir = "~/.config/retroarch/filters/audio" +audio_latency = "32" +audio_max_timing_skew = "0.049999" +audio_mixer_mute_enable = "false" +audio_mixer_volume = "0.000000" +audio_mute_enable = "false" +audio_out_rate = "48000" +audio_rate_control_delta = "0.004999" +audio_rate_control = "true" +audio_resampler_quality = "2" +audio_resampler = "sinc" +audio_sync = "true" +audio_volume = "0.000000" +auto_overrides_enable = "true" +auto_remaps_enable = "true" +autosave_interval = "10" +auto_screenshot_filename = "true" +auto_shaders_enable = "true" +block_sram_overwrite = "false" +bluetooth_driver = "null" +builtin_imageviewer_enable = "false" +builtin_mediaplayer_enable = "true" +bundle_assets_dst_path = "" +bundle_assets_dst_path_subdir = "" +bundle_assets_extract_enable = "false" +bundle_assets_extract_last_version = "0" +bundle_assets_extract_version_current = "0" +bundle_assets_src_path = "" +cache_directory = "/tmp/cache" +camera_allow = "false" +camera_device = "" +camera_driver = "null" +cheat_database_path = "/tmp/database/cht" +check_firmware_before_loading = "false" +cheevos_auto_screenshot = "false" +cheevos_badges_enable = "false" +cheevos_challenge_indicators = "true" +cheevos_enable = "false" +cheevos_hardcore_mode_enable = "false" +cheevos_leaderboards_enable = "" +cheevos_password = "" +cheevos_richpresence_enable = "true" +cheevos_start_active = "false" +cheevos_test_unofficial = "false" +cheevos_token = "" +cheevos_unlock_sound_enable = "false" +cheevos_username = "" +cheevos_verbose_enable = "false" +config_save_on_exit = "false" +content_database_path = "/tmp/database/rdb" +content_favorites_directory = "default" +content_favorites_path = "~/.config/retroarch/content_favorites.lpl" +content_favorites_size = "200" +content_history_dir = "" +content_history_directory = "default" +content_history_path = "~/.config/retroarch/content_history.lpl" +content_history_size = "200" +content_image_history_directory = "default" +content_image_history_path = "~/.config/retroarch/content_image_history.lpl" +content_music_history_directory = "default" +content_music_history_path = "~/.config/retroarch/content_music_history.lpl" +content_runtime_log_aggregate = "false" +content_runtime_log = "true" +content_show_add_entry = "2" +content_show_add = "true" +content_show_explore = "true" +content_show_favorites = "true" +content_show_history = "true" +content_show_images = "false" +content_show_music = "false" +content_show_netplay = "true" +content_show_playlists = "true" +content_show_settings_password = "" +content_show_settings = "true" +content_show_video = "false" +content_video_directory = "default" +content_video_history_path = "~/.config/retroarch/content_video_history.lpl" +core_assets_directory = "~/roms/downloads" +core_info_cache_enable = "true" +core_option_category_enable = "true" +core_options_path = "" +core_set_supports_no_game_enable = "true" +core_updater_auto_backup = "false" +core_updater_auto_backup_history_size = "1" +core_updater_auto_extract_archive = "true" +core_updater_buildbot_assets_url = "http://buildbot.libretro.com/assets/" +core_updater_buildbot_cores_url = "" +core_updater_buildbot_url = "http://buildbot.libretro.com/nightly/linux/armhf/latest/" +core_updater_show_experimental_cores = "false" +cpu_main_gov = "performance" +cpu_max_freq = "-1" +cpu_menu_gov = "interactive" +cpu_min_freq = "1" +cpu_scaling_mode = "0" +crt_switch_center_adjust = "0" +crt_switch_hires_menu = "false" +crt_switch_porch_adjust = "0" +crt_switch_resolution = "0" +crt_switch_resolution_super = "2560" +crt_switch_resolution_use_custom_refresh_rate = "false" +crt_switch_timings = "" +crt_video_refresh_rate = "60.000000" +current_resolution_id = "0" +cursor_directory = "~/.config/retroarch/database/cursors" +desktop_menu_enable = "true" +discord_allow = "false" +discord_app_id = "475456035851599874" +driver_switch_enable = "true" +dynamic_wallpapers_directory = "default" +emuelec_exit_to_kodi = "false" +enable_device_vibration = "true" +facebook_stream_key = "" +fastforward_ratio = "0.000000" +filter_by_current_core = "false" +flicker_filter_enable = "false" +flicker_filter_index = "0" +fps_show = "false" +fps_update_interval = "256" +framecount_show = "false" +frame_time_counter_reset_after_fastforwarding = "false" +frame_time_counter_reset_after_load_state = "false" +frame_time_counter_reset_after_save_state = "false" +frontend_log_level = "1" +game_specific_options = "true" +gamma_correction = "0" +global_core_options = "false" +history_list_enable = "true" +input_ai_service_axis = "nul" +input_ai_service_btn = "nul" +input_ai_service_mbtn = "nul" +input_ai_service = "nul" +input_analog_deadzone = "0.000000" +input_analog_sensitivity = "1.500000" +input_audio_mute_axis = "nul" +input_audio_mute_btn = "nul" +input_audio_mute = "f9" +input_audio_mute_mbtn = "nul" +input_autodetect_enable = "true" +input_auto_game_focus = "0" +input_auto_mouse_grab = "false" +input_axis_threshold = "0.500000" +input_bind_hold = "2" +input_bind_timeout = "5" +input_cheat_index_minus_axis = "nul" +input_cheat_index_minus_btn = "nul" +input_cheat_index_minus_mbtn = "nul" +input_cheat_index_minus = "t" +input_cheat_index_plus_axis = "nul" +input_cheat_index_plus_btn = "nul" +input_cheat_index_plus_mbtn = "nul" +input_cheat_index_plus = "y" +input_cheat_toggle_axis = "nul" +input_cheat_toggle_btn = "nul" +input_cheat_toggle_mbtn = "nul" +input_cheat_toggle = "u" +input_close_content_axis = "nul" +input_close_content_btn = "nul" +input_close_content_mbtn = "nul" +input_close_content = "nul" +input_descriptor_hide_unbound = "false" +input_descriptor_label_show = "true" +input_desktop_menu_toggle_axis = "nul" +input_desktop_menu_toggle_btn = "nul" +input_desktop_menu_toggle = "f5" +input_desktop_menu_toggle_mbtn = "nul" +input_device_p1 = "0" +input_device_p10 = "0" +input_device_p11 = "0" +input_device_p12 = "0" +input_device_p13 = "0" +input_device_p14 = "0" +input_device_p15 = "0" +input_device_p16 = "0" +input_device_p2 = "0" +input_device_p3 = "0" +input_device_p4 = "0" +input_device_p5 = "0" +input_device_p6 = "0" +input_device_p7 = "0" +input_device_p8 = "0" +input_device_p9 = "0" +input_disk_eject_toggle_axis = "nul" +input_disk_eject_toggle_btn = "nul" +input_disk_eject_toggle_mbtn = "nul" +input_disk_eject_toggle = "nul" +input_disk_next_axis = "nul" +input_disk_next_btn = "nul" +input_disk_next_mbtn = "nul" +input_disk_next = "nul" +input_disk_prev_axis = "nul" +input_disk_prev_btn = "nul" +input_disk_prev_mbtn = "nul" +input_disk_prev = "nul" +input_driver = "udev" +input_duty_cycle = "3" +input_enable_hotkey_axis = "nul" +input_enable_hotkey_btn = "8" +input_enable_hotkey_mbtn = "nul" +input_enable_hotkey = "nul" +input_exit_emulator_axis = "nul" +input_exit_emulator_btn = "9" +input_exit_emulator = "escape" +input_exit_emulator_mbtn = "nul" +input_fps_toggle_axis = "nul" +input_fps_toggle_btn = "3" +input_fps_toggle = "f3" +input_fps_toggle_mbtn = "nul" +input_frame_advance_axis = "nul" +input_frame_advance_btn = "nul" +input_frame_advance = "k" +input_frame_advance_mbtn = "nul" +input_game_focus_toggle_axis = "nul" +input_game_focus_toggle_btn = "nul" +input_game_focus_toggle_mbtn = "nul" +input_game_focus_toggle = "scroll_lock" +input_grab_mouse_toggle_axis = "nul" +input_grab_mouse_toggle_btn = "nul" +input_grab_mouse_toggle = "f11" +input_grab_mouse_toggle_mbtn = "nul" +input_hold_fast_forward_axis = "nul" +input_hold_fast_forward_btn = "nul" +input_hold_fast_forward = "l" +input_hold_fast_forward_mbtn = "nul" +input_hold_slowmotion_axis = "nul" +input_hold_slowmotion_btn = "nul" +input_hold_slowmotion = "e" +input_hold_slowmotion_mbtn = "nul" +input_hotkey_block_delay = "5" +input_joypad_driver = "udev" +input_keyboard_layout = "" +input_libretro_device_p10 = "1" +input_libretro_device_p1 = "1" +input_libretro_device_p11 = "1" +input_libretro_device_p12 = "1" +input_libretro_device_p13 = "1" +input_libretro_device_p14 = "1" +input_libretro_device_p15 = "1" +input_libretro_device_p16 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_libretro_device_p6 = "1" +input_libretro_device_p7 = "1" +input_libretro_device_p8 = "1" +input_libretro_device_p9 = "1" +input_load_state_axis = "nul" +input_load_state_btn = "4" +input_load_state = "f4" +input_load_state_mbtn = "nul" +input_max_users = "5" +input_menu_toggle_axis = "nul" +input_menu_toggle_btn = "2" +input_menu_toggle = "f1" +input_menu_toggle_gamepad_combo = "2" +input_menu_toggle_mbtn = "nul" +input_movie_record_toggle_axis = "nul" +input_movie_record_toggle_btn = "nul" +input_movie_record_toggle_mbtn = "nul" +input_movie_record_toggle = "o" +input_netplay_game_watch_axis = "nul" +input_netplay_game_watch_btn = "nul" +input_netplay_game_watch = "i" +input_netplay_game_watch_mbtn = "nul" +input_netplay_host_toggle_axis = "nul" +input_netplay_host_toggle_btn = "nul" +input_netplay_host_toggle_mbtn = "nul" +input_netplay_host_toggle = "nul" +input_nowinkey_enable = "false" +input_osk_toggle_axis = "nul" +input_osk_toggle_btn = "nul" +input_osk_toggle = "f12" +input_osk_toggle_mbtn = "nul" +input_overlay = "" +input_overlay_aspect_adjust_landscape = "0.000000" +input_overlay_aspect_adjust_portrait = "0.000000" +input_overlay_auto_rotate = "false" +input_overlay_auto_scale = "false" +input_overlay_enable_autopreferred = "true" +input_overlay_enable = "false" +input_overlay_hide_in_menu = "true" +input_overlay_hide_when_gamepad_connected = "false" +input_overlay_next_axis = "nul" +input_overlay_next_btn = "nul" +input_overlay_next_mbtn = "nul" +input_overlay_next = "nul" +input_overlay_opacity = "0.700000" +input_overlay_scale_landscape = "1.000000" +input_overlay_scale_portrait = "1.000000" +input_overlay_show_inputs = "2" +input_overlay_show_inputs_port = "0" +input_overlay_show_mouse_cursor = "true" +input_overlay_x_offset_landscape = "0.000000" +input_overlay_x_offset_portrait = "0.000000" +input_overlay_x_separation_landscape = "0.000000" +input_overlay_x_separation_portrait = "0.000000" +input_overlay_y_offset_landscape = "0.000000" +input_overlay_y_offset_portrait = "0.000000" +input_overlay_y_separation_landscape = "0.000000" +input_overlay_y_separation_portrait = "0.000000" +input_pause_toggle_axis = "nul" +input_pause_toggle_btn = "nul" +input_pause_toggle_mbtn = "nul" +input_pause_toggle = "p" +input_poll_type_behavior = "2" +input_quit_gamepad_combo = "0" +input_recording_toggle_axis = "nul" +input_recording_toggle_btn = "nul" +input_recording_toggle_mbtn = "nul" +input_recording_toggle = "nul" +input_remap_binds_enable = "true" +input_remapping_directory = "~/remappings" +input_reset_axis = "nul" +input_reset_btn = "nul" +input_reset = "h" +input_reset_mbtn = "nul" +input_rewind_axis = "nul" +input_rewind_btn = "6" +input_rewind_mbtn = "nul" +input_rewind = "r" +input_rumble_gain = "100" +input_runahead_toggle_axis = "nul" +input_runahead_toggle_btn = "nul" +input_runahead_toggle_mbtn = "nul" +input_runahead_toggle = "nul" +input_save_state_axis = "nul" +input_save_state_btn = "5" +input_save_state = "f2" +input_save_state_mbtn = "nul" +input_screenshot_axis = "nul" +input_screenshot_btn = "nul" +input_screenshot = "f8" +input_screenshot_mbtn = "nul" +input_send_debug_info_axis = "nul" +input_send_debug_info_btn = "nul" +input_send_debug_info = "f10" +input_send_debug_info_mbtn = "nul" +input_sensors_enable = "true" +input_shader_next_axis = "nul" +input_shader_next_btn = "nul" +input_shader_next = "m" +input_shader_next_mbtn = "nul" +input_shader_prev_axis = "nul" +input_shader_prev_btn = "nul" +input_shader_prev_mbtn = "nul" +input_shader_prev = "n" +input_state_slot_decrease_axis = "nul" +input_state_slot_decrease_btn = "nul" +input_state_slot_decrease = "f6" +input_state_slot_decrease_mbtn = "nul" +input_state_slot_increase_axis = "nul" +input_state_slot_increase_btn = "nul" +input_state_slot_increase = "f7" +input_state_slot_increase_mbtn = "nul" +input_streaming_toggle_axis = "nul" +input_streaming_toggle_btn = "nul" +input_streaming_toggle_mbtn = "nul" +input_streaming_toggle = "nul" +input_toggle_fast_forward_axis = "nul" +input_toggle_fast_forward_btn = "7" +input_toggle_fast_forward_mbtn = "nul" +input_toggle_fast_forward = "space" +input_toggle_fullscreen_axis = "nul" +input_toggle_fullscreen_btn = "nul" +input_toggle_fullscreen = "f" +input_toggle_fullscreen_mbtn = "nul" +input_toggle_slowmotion_axis = "nul" +input_toggle_slowmotion_btn = "nul" +input_toggle_slowmotion_mbtn = "nul" +input_toggle_slowmotion = "nul" +input_touch_scale = "1" +input_turbo_default_button = "0" +input_turbo_mode = "0" +input_turbo_period = "6" +input_volume_down_axis = "nul" +input_volume_down_btn = "nul" +input_volume_down_mbtn = "nul" +input_volume_down = "subtract" +input_volume_up = "add" +input_volume_up_axis = "nul" +input_volume_up_btn = "nul" +input_volume_up_mbtn = "nul" +joypad_autoconfig_dir = "/tmp/joypads" +keyboard_gamepad_enable = "true" +keyboard_gamepad_mapping_type = "1" +kiosk_mode_enable = "false" +kiosk_mode_password = "" +led_driver = "null" +libretro_directory = "/tmp/cores" +libretro_info_path = "/tmp/cores" +libretro_log_level = "1" +load_dummy_on_core_shutdown = "true" +location_allow = "false" +location_driver = "null" +log_dir = "~/.config/retroarch/logs" +log_to_file = "false" +log_to_file_timestamp = "false" +log_verbosity = "true" +materialui_auto_rotate_nav_bar = "true" +materialui_dual_thumbnail_list_view_enable = "true" +materialui_icons_enable = "true" +materialui_landscape_layout_optimization = "1" +materialui_menu_color_theme = "9" +materialui_menu_transition_animation = "0" +materialui_playlist_icons_enable = "true" +materialui_show_nav_bar = "true" +materialui_thumbnail_background_enable = "true" +materialui_thumbnail_view_landscape = "2" +materialui_thumbnail_view_portrait = "1" +memory_show = "false" +memory_update_interval = "256" +menu_battery_level_enable = "true" +menu_core_enable = "true" +menu_driver = "xmb" +menu_dynamic_wallpaper_enable = "false" +menu_enable_widgets = "true" +menu_font_color_blue = "255" +menu_font_color_green = "255" +menu_font_color_red = "255" +menu_footer_opacity = "1.000000" +menu_framebuffer_opacity = "0.899999" +menu_header_opacity = "1.000000" +menu_horizontal_animation = "true" +menu_insert_disk_resume = "true" +menu_left_thumbnails = "0" +menu_linear_filter = "false" +menu_mouse_enable = "false" +menu_navigation_browser_filter_supported_extensions_enable = "true" +menu_navigation_wraparound_enable = "true" +menu_pause_libretro = "true" +menu_pointer_enable = "false" +menu_rgui_full_width_layout = "true" +menu_rgui_shadows = "false" +menu_rgui_transparency = "true" +menu_savestate_resume = "true" +menu_scale_factor = "0.300000" +menu_screensaver_animation = "0" +menu_screensaver_animation_speed = "1.000000" +menu_screensaver_timeout = "0" +menu_scroll_delay = "256" +menu_scroll_fast = "false" +menu_shader_pipeline = "2" +menu_show_advanced_settings = "true" +menu_show_configurations = "true" +menu_show_core_updater = "false" +menu_show_dump_disc = "true" +menu_show_help = "true" +menu_show_information = "true" +menu_show_latency = "true" +menu_show_legacy_thumbnail_updater = "false" +menu_show_load_content_animation = "false" +menu_show_load_content = "true" +menu_show_load_core = "true" +menu_show_load_disc = "true" +menu_show_online_updater = "true" +menu_show_overlays = "true" +menu_show_quit_retroarch = "true" +menu_show_reboot = "false" +menu_show_restart_retroarch = "true" +menu_show_rewind = "true" +menu_show_shutdown = "false" +menu_show_sublabels = "true" +menu_show_video_layout = "true" +menu_swap_ok_cancel_buttons = "false" +menu_throttle_framerate = "true" +menu_thumbnails = "3" +menu_thumbnail_upscale_threshold = "0" +menu_ticker_smooth = "true" +menu_ticker_speed = "2.000000" +menu_ticker_type = "1" +menu_timedate_date_separator = "0" +menu_timedate_enable = "true" +menu_timedate_style = "11" +menu_unified_controls = "false" +menu_use_preferred_system_color_theme = "false" +menu_wallpaper = "" +menu_wallpaper_opacity = "1.000000" +menu_widget_scale_auto = "false" +menu_widget_scale_factor = "0.350000" +menu_widget_scale_factor_windowed = "1.000000" +menu_xmb_animation_horizontal_highlight = "0" +menu_xmb_animation_move_up_down = "0" +menu_xmb_animation_opening_main_menu = "0" +menu_xmb_thumbnail_scale_factor = "100" +midi_driver = "alsa" +midi_input = "Off" +midi_output = "Off" +midi_volume = "100" +netplay_allow_slaves = "true" +netplay_check_frames = "600" +netplay_input_latency_frames_min = "0" +netplay_input_latency_frames_range = "0" +netplay_ip_address = "" +netplay_ip_port = "55435" +netplay_max_connections = "3" +netplay_mitm_server = "nyc" +netplay_nat_traversal = "true" +netplay_nickname = "" +netplay_password = "" +netplay_public_announce = "true" +netplay_request_device_p10 = "false" +netplay_request_device_p11 = "false" +netplay_request_device_p12 = "false" +netplay_request_device_p13 = "false" +netplay_request_device_p14 = "false" +netplay_request_device_p15 = "false" +netplay_request_device_p16 = "false" +netplay_request_device_p1 = "false" +netplay_request_device_p2 = "false" +netplay_request_device_p3 = "false" +netplay_request_device_p4 = "false" +netplay_request_device_p5 = "false" +netplay_request_device_p6 = "false" +netplay_request_device_p7 = "false" +netplay_request_device_p8 = "false" +netplay_request_device_p9 = "false" +netplay_require_slaves = "false" +netplay_share_analog = "1" +netplay_share_digital = "1" +netplay_spectate_password = "" +netplay_start_as_spectator = "false" +netplay_stateless_mode = "false" +netplay_use_mitm_server = "false" +network_cmd_enable = "false" +network_cmd_port = "55355" +network_on_demand_thumbnails = "false" +network_remote_base_port = "55400" +network_remote_enable = "false" +network_remote_enable_user_p10 = "false" +network_remote_enable_user_p11 = "false" +network_remote_enable_user_p12 = "false" +network_remote_enable_user_p13 = "false" +network_remote_enable_user_p14 = "false" +network_remote_enable_user_p15 = "false" +network_remote_enable_user_p16 = "false" +network_remote_enable_user_p1 = "false" +network_remote_enable_user_p2 = "false" +network_remote_enable_user_p3 = "false" +network_remote_enable_user_p4 = "false" +network_remote_enable_user_p5 = "false" +network_remote_enable_user_p6 = "false" +network_remote_enable_user_p7 = "false" +network_remote_enable_user_p8 = "false" +network_remote_enable_user_p9 = "false" +notification_show_autoconfig = "false" +notification_show_cheats_applied = "true" +notification_show_config_override_load = "false" +notification_show_fast_forward = "true" +notification_show_netplay_extra = "false" +notification_show_patch_applied = "true" +notification_show_refresh_rate = "true" +notification_show_remap_load = "false" +notification_show_screenshot_duration = "2" +notification_show_screenshot = "false" +notification_show_screenshot_flash = "1" +notification_show_set_initial_disk = "true" +overlay_directory = "/tmp/overlays" +ozone_collapse_sidebar = "false" +ozone_menu_color_theme = "1" +ozone_scroll_content_metadata = "false" +ozone_sort_after_truncate_playlist_name = "true" +ozone_truncate_playlist_name = "true" +pause_nonactive = "true" +perfcnt_enable = "false" +playlist_compression = "false" +playlist_cores = "" +playlist_directory = "~/playlists" +playlist_entry_remove_enable = "1" +playlist_entry_remove = "false" +playlist_entry_rename = "false" +playlist_fuzzy_archive_match = "false" +playlist_names = "" +playlist_portable_paths = "false" +playlist_show_entry_idx = "true" +playlist_show_inline_core_name = "0" +playlist_show_sublabels = "true" +playlist_sort_alphabetical = "true" +playlist_sublabel_last_played_style = "0" +playlist_sublabel_runtime_type = "0" +playlist_use_old_format = "false" +quick_menu_show_add_to_favorites = "true" +quick_menu_show_cheats = "true" +quick_menu_show_close_content = "true" +quick_menu_show_controls = "true" +quick_menu_show_core_options_flush = "false" +quick_menu_show_download_thumbnails = "true" +quick_menu_show_information = "true" +quick_menu_show_options = "true" +quick_menu_show_recording = "true" +quick_menu_show_reset_core_association = "true" +quick_menu_show_restart_content = "true" +quick_menu_show_resume_content = "true" +quick_menu_show_save_content_dir_overrides = "true" +quick_menu_show_save_core_overrides = "false" +quick_menu_show_save_game_overrides = "false" +quick_menu_show_save_load_state = "true" +quick_menu_show_set_core_association = "true" +quick_menu_show_shaders = "true" +quick_menu_show_start_recording = "true" +quick_menu_show_start_streaming = "true" +quick_menu_show_streaming = "true" +quick_menu_show_take_screenshot = "true" +quick_menu_show_undo_save_load_state = "false" +quit_on_close_content = "0" +quit_press_twice = "true" +record_driver = "null" +recording_config_directory = "" +recording_output_directory = "~/roms/screenshots" +resampler_directory = "" +rewind_buffer_size = "20971520" +rewind_buffer_size_step = "10" +rewind_enable = "false" +rewind_granularity = "1" +rgui_aspect_ratio = "0" +rgui_aspect_ratio_lock = "0" +rgui_background_filler_thickness_enable = "true" +rgui_border_filler_enable = "true" +rgui_border_filler_thickness_enable = "true" +rgui_browser_directory = "~/roms" +rgui_config_directory = "~/.config/retroarch/config" +rgui_extended_ascii = "false" +rgui_inline_thumbnails = "false" +rgui_internal_upscale_level = "0" +rgui_menu_color_theme = "4" +rgui_menu_theme_preset = "" +rgui_particle_effect = "0" +rgui_particle_effect_screensaver = "true" +rgui_particle_effect_speed = "1.000000" +rgui_show_start_screen = "false" +rgui_swap_thumbnails = "false" +rgui_switch_icons = "true" +rgui_thumbnail_delay = "0" +rgui_thumbnail_downscaler = "0" +run_ahead_enabled = "false" +run_ahead_frames = "1" +run_ahead_hide_warnings = "false" +run_ahead_secondary_instance = "true" +runtime_log_directory = "default" +save_file_compression = "false" +savefile_directory = "~/.config/retroarch/saves" +savefiles_in_content_dir = "true" +savestate_auto_index = "false" +savestate_auto_load = "false" +savestate_auto_save = "false" +savestate_directory = "~/.config/retroarch/states" +savestate_file_compression = "true" +savestate_max_keep = "0" +savestates_in_content_dir = "false" +savestate_thumbnail_enable = "true" +scan_without_core_match = "false" +screen_brightness = "100" +screen_orientation = "0" +screenshot_directory = "~/roms/screenshots" +screenshots_in_content_dir = "false" +settings_show_accessibility = "true" +settings_show_achievements = "true" +settings_show_ai_service = "true" +settings_show_audio = "true" +settings_show_configuration = "true" +settings_show_core = "true" +settings_show_directory = "true" +settings_show_drivers = "true" +settings_show_file_browser = "true" +settings_show_frame_throttle = "true" +settings_show_input = "true" +settings_show_latency = "true" +settings_show_logging = "true" +settings_show_network = "true" +settings_show_onscreen_display = "true" +settings_show_playlists = "true" +settings_show_power_management = "true" +settings_show_recording = "true" +settings_show_saving = "true" +settings_show_user_interface = "true" +settings_show_user = "true" +settings_show_video = "true" +show_hidden_files = "false" +slowmotion_ratio = "3.000000" +soft_filter_enable = "false" +soft_filter_index = "0" +sort_savefiles_by_content_enable = "false" +sort_savefiles_enable = "false" +sort_savestates_by_content_enable = "false" +sort_savestates_enable = "false" +sort_screenshots_by_content_enable = "false" +state_slot = "0" +statistics_show = "false" +stdin_cmd_enable = "false" +streaming_mode = "0" +suspend_screensaver_enable = "true" +sustained_performance_mode = "false" +system_directory = "~/roms/bios" +systemfiles_in_content_dir = "false" +threaded_data_runloop_enable = "true" +thumbnails_directory = "~/thumbnails" +twitch_stream_key = "" +ui_companion_enable = "false" +ui_companion_start_on_boot = "true" +ui_companion_toggle = "false" +ui_menubar_enable = "true" +use_last_start_directory = "false" +user_language = "0" +vibrate_on_keypress = "true" +video_adaptive_vsync = "false" +video_allow_rotate = "true" +video_aspect_ratio = "-1.000000" +video_aspect_ratio_auto = "true" +video_black_frame_insertion = "0" +video_context_driver = "" +video_crop_overscan = "true" +video_ctx_scaling = "false" +video_disable_composition = "false" +video_driver = "gl" +video_filter = "" +video_filter_dir = "~/.config/retroarch/filters/video" +video_font_enable = "true" +video_font_path = "/usr/share/retroarch-assets/xmb/monochrome/font.ttf" +video_font_size = "32.000000" +video_force_aspect = "true" +video_force_srgb_disable = "false" +video_frame_delay = "0" +video_frame_delay_auto = "false" +video_fullscreen = "true" +video_fullscreen_x = "480" +video_fullscreen_y = "320" +video_gpu_record = "false" +video_gpu_screenshot = "false" +video_hard_sync = "false" +video_hard_sync_frames = "0" +video_hdr_display_contrast = "5.000000" +video_hdr_enable = "false" +video_hdr_expand_gamut = "true" +video_hdr_max_nits = "1000.000000" +video_hdr_paper_white_nits = "200.000000" +video_layout_directory = "~/.config/retroarch/layouts" +video_layout_enable = "true" +video_layout_path = "" +video_layout_selected_view = "0" +video_max_swapchain_images = "3" +video_message_color = "ffff00" +video_message_pos_x = "0.049999" +video_message_pos_y = "0.049999" +video_monitor_index = "0" +video_msg_bgcolor_blue = "0" +video_msg_bgcolor_enable = "false" +video_msg_bgcolor_green = "0" +video_msg_bgcolor_opacity = "1.000000" +video_msg_bgcolor_red = "0" +video_notch_write_over_enable = "false" +video_oga_vertical_enable = "false" +video_post_filter_record = "false" +video_record_config = "" +video_record_quality = "4" +video_record_scale_factor = "1" +video_record_threads = "2" +video_refresh_rate = "60.000000" +video_rotation = "0" +video_scale = "3.000000" +video_scale_integer = "false" +video_scale_integer_overscale = "false" +video_shader_delay = "0" +video_shader_dir = "/tmp/shaders" +video_shader_enable = "false" +video_shader_preset_save_reference_enable = "true" +video_shader_remember_last_dir = "false" +video_shader_watch_files = "false" +video_shared_context = "false" +video_smooth = "false" +video_stream_config = "" +video_stream_port = "56400" +video_stream_quality = "10" +video_stream_scale_factor = "1" +video_stream_url = "" +video_swap_interval = "1" +video_threaded = "true" +video_vsync = "true" +video_window_auto_height_max = "320" +video_window_auto_width_max = "480" +video_window_custom_size_enable = "false" +video_windowed_fullscreen = "false" +video_windowed_position_height = "720" +video_windowed_position_width = "1280" +video_windowed_position_x = "0" +video_windowed_position_y = "0" +video_window_opacity = "100" +video_window_save_positions = "false" +video_window_show_decorations = "true" +vrr_runloop_enable = "false" +wifi_driver = "null" +wifi_enabled = "true" +xmb_alpha_factor = "75" +xmb_font = "/usr/share/retroarch-assets/xmb/monochrome/font.ttf" +xmb_layout = "2" +xmb_menu_color_theme = "4" +xmb_shadows_enable = "true" +xmb_theme = "0" +xmb_vertical_thumbnails = "false" +youtube_stream_key = "" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3326/retroarch32bit-append.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3326/retroarch32bit-append.cfg new file mode 100755 index 0000000000..343124c254 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3326/retroarch32bit-append.cfg @@ -0,0 +1,3 @@ +audio_filter_dir = "/usr/share/retroarch/filters/32bit/audio" +video_filter_dir = "/usr/share/retroarch/filters/32bit/video" +libretro_directory = /usr/lib32/libretro diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3326/retroarch64bit-append.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3326/retroarch64bit-append.cfg new file mode 100755 index 0000000000..b6cbf68312 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3326/retroarch64bit-append.cfg @@ -0,0 +1,2 @@ +audio_filter_dir = "/usr/share/retroarch/filters/64bit/audio" +video_filter_dir = "/usr/share/retroarch/filters/64bit/video" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3399/TATE-MAME 2003-Plus.rmp b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3399/TATE-MAME 2003-Plus.rmp new file mode 100755 index 0000000000..366e47afad --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3399/TATE-MAME 2003-Plus.rmp @@ -0,0 +1,27 @@ +input_libretro_device_p1 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_player1_analog_dpad_mode = "1" +input_player1_btn_down = "6" +input_player1_btn_left = "4" +input_player1_btn_right = "5" +input_player1_btn_up = "7" +input_player1_stk_l_x+ = "5" +input_player1_stk_l_x- = "4" +input_player1_stk_l_y+ = "6" +input_player1_stk_l_y- = "7" +input_player1_stk_r_x+ = "5" +input_player1_stk_r_x- = "4" +input_player1_stk_r_y+ = "6" +input_player1_stk_r_y- = "7" +input_player2_analog_dpad_mode = "0" +input_player3_analog_dpad_mode = "0" +input_player4_analog_dpad_mode = "0" +input_player5_analog_dpad_mode = "0" +input_remap_port_p1 = "0" +input_remap_port_p2 = "1" +input_remap_port_p3 = "2" +input_remap_port_p4 = "3" +input_remap_port_p5 = "4" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3399/retroarch-core-options.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3399/retroarch-core-options.cfg new file mode 100755 index 0000000000..0bcbaa2661 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3399/retroarch-core-options.cfg @@ -0,0 +1,152 @@ +mupen64plus-alt-map = "False" +mupen64plus-aspect = "4:3" +mupen64plus-astick-deadzone = "15" +mupen64plus-astick-sensitivity = "100" +mupen64plus-BackgroundMode = "Stripped" +mupen64plus-BilinearMode = "standard" +mupen64plus-CorrectTexrectCoords = "Auto" +mupen64plus-CountPerOp = "0" +mupen64plus-CountPerOpDenomPot = "0" +mupen64plus-cpucore = "dynamic_recompiler" +mupen64plus-d-cbutton = "C3" +mupen64plus-DitheringPattern = "True" +mupen64plus-DitheringQuantization = "True" +mupen64plus-EnableCopyAuxToRDRAM = "True" +mupen64plus-EnableCopyColorToRDRAM = "Async" +mupen64plus-EnableCopyDepthToRDRAM = "Software" +mupen64plus-EnableEnhancedHighResStorage = "False" +mupen64plus-EnableEnhancedTextureStorage = "False" +mupen64plus-EnableFBEmulation = "True" +mupen64plus-EnableFragmentDepthWrite = "False" +mupen64plus-EnableHiResAltCRC = "False" +mupen64plus-EnableHWLighting = "True" +mupen64plus-EnableInaccurateTextureCoordinates = "False" +mupen64plus-EnableLegacyBlending = "False" +mupen64plus-EnableLODEmulation = "True" +mupen64plus-EnableNativeResFactor = "1" +mupen64plus-EnableNativeResTexrects = "Optimized" +mupen64plus-EnableOverscan = "Enabled" +mupen64plus-EnableTexCoordBounds = "False" +mupen64plus-EnableTextureCache = "True" +mupen64plus-ForceDisableExtraMem = "False" +mupen64plus-FrameDuping = "True" +mupen64plus-Framerate = "Original" +mupen64plus-FXAA = "0" +mupen64plus-GLideN64IniBehaviour = "late" +mupen64plus-HybridFilter = "True" +mupen64plus-IgnoreTLBExceptions = "False" +mupen64plus-l-cbutton = "C2" +mupen64plus-MaxHiResTxVramLimit = "0" +mupen64plus-MaxTxCacheSize = "8000" +mupen64plus-MultiSampling = "0" +mupen64plus-OverscanBottom = "0" +mupen64plus-OverscanLeft = "0" +mupen64plus-OverscanRight = "0" +mupen64plus-OverscanTop = "0" +mupen64plus-pak1 = "memory" +mupen64plus-pak2 = "none" +mupen64plus-pak3 = "none" +mupen64plus-pak4 = "none" +mupen64plus-r-cbutton = "C1" +mupen64plus-rdp-plugin = "gliden64" +mupen64plus-RDRAMImageDitheringMode = "BlueNoise" +mupen64plus-rsp-plugin = "hle" +mupen64plus-ThreadedRenderer = "True" +mupen64plus-txCacheCompression = "True" +mupen64plus-txEnhancementMode = "None" +mupen64plus-txFilterIgnoreBG = "True" +mupen64plus-txFilterMode = "None" +mupen64plus-txHiresEnable = "False" +mupen64plus-txHiresFullAlphaChannel = "False" +mupen64plus-u-cbutton = "C4" +mupen64plus-virefresh = "Auto" +pcsx_rearmed_analog_axis_modifier = "circle" +pcsx_rearmed_async_cd = "sync" +pcsx_rearmed_bios = "auto" +pcsx_rearmed_display_internal_fps = "disabled" +pcsx_rearmed_dithering = "enabled" +pcsx_rearmed_drc = "enabled" +pcsx_rearmed_duping_enable = "enabled" +pcsx_rearmed_frameskip_type = "disabled" +pcsx_rearmed_gteregsunneeded = "disabled" +pcsx_rearmed_gunconadjustratiox = "1" +pcsx_rearmed_gunconadjustratioy = "1" +pcsx_rearmed_gunconadjustx = "0" +pcsx_rearmed_gunconadjusty = "0" +pcsx_rearmed_idiablofix = "disabled" +pcsx_rearmed_input_sensitivity = "1.00" +pcsx_rearmed_inuyasha_fix = "disabled" +pcsx_rearmed_memcard2 = "disabled" +pcsx_rearmed_multitap1 = "auto" +pcsx_rearmed_multitap2 = "auto" +pcsx_rearmed_negcon_deadzone = "0" +pcsx_rearmed_negcon_response = "linear" +pcsx_rearmed_neon_enhancement_enable = "disabled" +pcsx_rearmed_neon_enhancement_no_main = "disabled" +pcsx_rearmed_neon_interlace_enable = "disabled" +pcsx_rearmed_nocdaudio = "enabled" +pcsx_rearmed_nogteflags = "disabled" +pcsx_rearmed_nosmccheck = "disabled" +pcsx_rearmed_noxadecoding = "enabled" +pcsx_rearmed_pad1type = "standard" +pcsx_rearmed_pad2type = "standard" +pcsx_rearmed_pad3type = "none" +pcsx_rearmed_pad4type = "none" +pcsx_rearmed_pad5type = "none" +pcsx_rearmed_pad6type = "none" +pcsx_rearmed_pad7type = "none" +pcsx_rearmed_pad8type = "none" +pcsx_rearmed_pe2_fix = "disabled" +pcsx_rearmed_psxclock = "57" +pcsx_rearmed_region = "auto" +pcsx_rearmed_show_bios_bootlogo = "disabled" +pcsx_rearmed_show_other_input_settings = "disabled" +pcsx_rearmed_spu_interpolation = "simple" +pcsx_rearmed_spu_reverb = "enabled" +pcsx_rearmed_spuirq = "disabled" +pcsx_rearmed_vibration = "enabled" +gambatte_gb_colorization = "disabled" +gambatte_gb_internal_palette = "" +mame2003-plus_analog = "digital" +mame2003-plus_art_resolution = "1" +mame2003-plus_brightness = "1.0" +mame2003-plus_cheat_input_ports = "disabled" +mame2003-plus_core_save_subfolder = "enabled" +mame2003-plus_core_sys_subfolder = "enabled" +mame2003-plus_dcs_speedhack = "enabled" +mame2003-plus_deadzone = "20" +mame2003-plus_digital_joy_centering = "enabled" +mame2003-plus_display_artwork = "enabled" +mame2003-plus_display_setup = "disabled" +mame2003-plus_four_way_emulation = "disabled" +mame2003-plus_frameskip = "0" +mame2003-plus_gamma = "1.0" +mame2003-plus_input_interface = "retropad" +mame2003-plus_machine_timing = "enabled" +mame2003-plus_mame_remapping = "enabled" +mame2003-plus_mouse_device = "mouse" +mame2003-plus_sample_rate = "48000" +mame2003-plus_skip_disclaimer = "disabled" +mame2003-plus_skip_warnings = "disabled" +flycast_internal_resolution = "640x480" +flycast_alpha_sorting = "per-strip (fast, least accurate)" +flycast_enable_dsp = "disabled" +flycast_threaded_rendering = "enabled" +flycast_anisotropic_filtering = "off" +flycast_synchronous_rendering = "enabled" +flycast_enable_rtt = "disabled" +flycast_enable_rttb = "disabled" +flycast_delay_frame_swapping = "disabled" +flycast_div_matching = "auto" +flycast_texupscale = "off" +flycast_auto_skip_frame = "normal" +opera_swi_hle = "enabled" +opera_dsp_threaded = "enabled" +opera_madam_matrix_engine = "software" +puae_deadzone = "25" +melonds_screen_layout = "Left/Right" +melonds_swapscreen_mode = "Toggle" +melonds_threaded_renderer = "enabled" +melonds_touch_mode = "Joystick" +virtualjaguar_bios = "enabled" +virtualjaguar_usefastblitter = "enabled" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3399/retroarch.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3399/retroarch.cfg new file mode 100644 index 0000000000..5ceb294e90 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3399/retroarch.cfg @@ -0,0 +1,826 @@ +accessibility_enable = "false" +accessibility_narrator_speech_speed = "5" +ai_service_enable = "true" +ai_service_mode = "1" +ai_service_pause = "false" +ai_service_source_lang = "0" +ai_service_target_lang = "0" +ai_service_url = "http://localhost:4404/" +all_users_control_menu = "true" +apply_cheats_after_load = "false" +apply_cheats_after_toggle = "false" +aspect_ratio_index = "22" +assets_directory = "/tmp/assets" +audio_block_frames = "0" +audio_device = "" +audio_driver = "alsathread" +audio_dsp_plugin = "" +audio_enable_menu_bgm = "false" +audio_enable_menu_cancel = "false" +audio_enable_menu = "false" +audio_enable_menu_notice = "false" +audio_enable_menu_ok = "false" +audio_enable = "true" +audio_fastforward_mute = "false" +audio_filter_dir = "~/.config/retroarch/filters/audio" +audio_latency = "32" +audio_max_timing_skew = "0.049999" +audio_mixer_mute_enable = "false" +audio_mixer_volume = "0.000000" +audio_mute_enable = "false" +audio_out_rate = "48000" +audio_rate_control_delta = "0.004999" +audio_rate_control = "true" +audio_resampler_quality = "2" +audio_resampler = "sinc" +audio_sync = "true" +audio_volume = "0.000000" +auto_overrides_enable = "true" +auto_remaps_enable = "true" +autosave_interval = "10" +auto_screenshot_filename = "true" +auto_shaders_enable = "true" +block_sram_overwrite = "false" +bluetooth_driver = "null" +builtin_imageviewer_enable = "false" +builtin_mediaplayer_enable = "true" +bundle_assets_dst_path = "" +bundle_assets_dst_path_subdir = "" +bundle_assets_extract_enable = "false" +bundle_assets_extract_last_version = "0" +bundle_assets_extract_version_current = "0" +bundle_assets_src_path = "" +cache_directory = "/tmp/cache" +camera_allow = "false" +camera_device = "" +camera_driver = "null" +cheat_database_path = "/tmp/database/cht" +check_firmware_before_loading = "false" +cheevos_auto_screenshot = "false" +cheevos_badges_enable = "false" +cheevos_challenge_indicators = "true" +cheevos_enable = "false" +cheevos_hardcore_mode_enable = "false" +cheevos_leaderboards_enable = "" +cheevos_password = "" +cheevos_richpresence_enable = "true" +cheevos_start_active = "false" +cheevos_test_unofficial = "false" +cheevos_token = "" +cheevos_unlock_sound_enable = "false" +cheevos_username = "" +cheevos_verbose_enable = "false" +config_save_on_exit = "false" +content_database_path = "/tmp/database/rdb" +content_favorites_directory = "default" +content_favorites_path = "~/.config/retroarch/content_favorites.lpl" +content_favorites_size = "200" +content_history_dir = "" +content_history_directory = "default" +content_history_path = "~/.config/retroarch/content_history.lpl" +content_history_size = "200" +content_image_history_directory = "default" +content_image_history_path = "~/.config/retroarch/content_image_history.lpl" +content_music_history_directory = "default" +content_music_history_path = "~/.config/retroarch/content_music_history.lpl" +content_runtime_log_aggregate = "false" +content_runtime_log = "true" +content_show_add_entry = "2" +content_show_add = "true" +content_show_explore = "true" +content_show_favorites = "true" +content_show_history = "true" +content_show_images = "false" +content_show_music = "false" +content_show_netplay = "true" +content_show_playlists = "true" +content_show_settings_password = "" +content_show_settings = "true" +content_show_video = "false" +content_video_directory = "default" +content_video_history_path = "~/.config/retroarch/content_video_history.lpl" +core_assets_directory = "~/roms/downloads" +core_info_cache_enable = "true" +core_option_category_enable = "true" +core_options_path = "" +core_set_supports_no_game_enable = "true" +core_updater_auto_backup = "false" +core_updater_auto_backup_history_size = "1" +core_updater_auto_extract_archive = "true" +core_updater_buildbot_assets_url = "http://buildbot.libretro.com/assets/" +core_updater_buildbot_cores_url = "" +core_updater_buildbot_url = "http://buildbot.libretro.com/nightly/linux/armhf/latest/" +core_updater_show_experimental_cores = "false" +cpu_main_gov = "performance" +cpu_max_freq = "-1" +cpu_menu_gov = "interactive" +cpu_min_freq = "1" +cpu_scaling_mode = "0" +crt_switch_center_adjust = "0" +crt_switch_hires_menu = "false" +crt_switch_porch_adjust = "0" +crt_switch_resolution = "0" +crt_switch_resolution_super = "2560" +crt_switch_resolution_use_custom_refresh_rate = "false" +crt_switch_timings = "" +crt_video_refresh_rate = "60.000000" +current_resolution_id = "0" +cursor_directory = "~/.config/retroarch/database/cursors" +custom_viewport_height = "1152" +custom_viewport_width = "1920" +custom_viewport_x = "0" +custom_viewport_y = "0" +desktop_menu_enable = "true" +discord_allow = "false" +discord_app_id = "475456035851599874" +driver_switch_enable = "true" +dynamic_wallpapers_directory = "default" +emuelec_exit_to_kodi = "false" +enable_device_vibration = "true" +facebook_stream_key = "" +fastforward_ratio = "0.000000" +filter_by_current_core = "false" +flicker_filter_enable = "false" +flicker_filter_index = "0" +fps_show = "false" +fps_update_interval = "256" +framecount_show = "false" +frame_time_counter_reset_after_fastforwarding = "false" +frame_time_counter_reset_after_load_state = "false" +frame_time_counter_reset_after_save_state = "false" +frontend_log_level = "1" +game_specific_options = "true" +gamma_correction = "0" +global_core_options = "false" +history_list_enable = "true" +input_ai_service_axis = "nul" +input_ai_service_btn = "nul" +input_ai_service_mbtn = "nul" +input_ai_service = "nul" +input_analog_deadzone = "0.000000" +input_analog_sensitivity = "1.500000" +input_audio_mute_axis = "nul" +input_audio_mute_btn = "nul" +input_audio_mute = "f9" +input_audio_mute_mbtn = "nul" +input_autodetect_enable = "true" +input_auto_game_focus = "0" +input_auto_mouse_grab = "false" +input_axis_threshold = "0.500000" +input_bind_hold = "2" +input_bind_timeout = "5" +input_cheat_index_minus_axis = "nul" +input_cheat_index_minus_btn = "nul" +input_cheat_index_minus_mbtn = "nul" +input_cheat_index_minus = "t" +input_cheat_index_plus_axis = "nul" +input_cheat_index_plus_btn = "nul" +input_cheat_index_plus_mbtn = "nul" +input_cheat_index_plus = "y" +input_cheat_toggle_axis = "nul" +input_cheat_toggle_btn = "nul" +input_cheat_toggle_mbtn = "nul" +input_cheat_toggle = "u" +input_close_content_axis = "nul" +input_close_content_btn = "nul" +input_close_content_mbtn = "nul" +input_close_content = "nul" +input_descriptor_hide_unbound = "false" +input_descriptor_label_show = "true" +input_desktop_menu_toggle_axis = "nul" +input_desktop_menu_toggle_btn = "nul" +input_desktop_menu_toggle = "f5" +input_desktop_menu_toggle_mbtn = "nul" +input_device_p1 = "0" +input_device_p10 = "0" +input_device_p11 = "0" +input_device_p12 = "0" +input_device_p13 = "0" +input_device_p14 = "0" +input_device_p15 = "0" +input_device_p16 = "0" +input_device_p2 = "0" +input_device_p3 = "0" +input_device_p4 = "0" +input_device_p5 = "0" +input_device_p6 = "0" +input_device_p7 = "0" +input_device_p8 = "0" +input_device_p9 = "0" +input_disk_eject_toggle_axis = "nul" +input_disk_eject_toggle_btn = "nul" +input_disk_eject_toggle_mbtn = "nul" +input_disk_eject_toggle = "nul" +input_disk_next_axis = "nul" +input_disk_next_btn = "nul" +input_disk_next_mbtn = "nul" +input_disk_next = "nul" +input_disk_prev_axis = "nul" +input_disk_prev_btn = "nul" +input_disk_prev_mbtn = "nul" +input_disk_prev = "nul" +input_driver = "udev" +input_duty_cycle = "3" +input_enable_hotkey_axis = "nul" +input_enable_hotkey_btn = "8" +input_enable_hotkey_mbtn = "nul" +input_enable_hotkey = "nul" +input_exit_emulator_axis = "nul" +input_exit_emulator_btn = "9" +input_exit_emulator = "escape" +input_exit_emulator_mbtn = "nul" +input_fps_toggle_axis = "nul" +input_fps_toggle_btn = "3" +input_fps_toggle = "f3" +input_fps_toggle_mbtn = "nul" +input_frame_advance_axis = "nul" +input_frame_advance_btn = "nul" +input_frame_advance = "k" +input_frame_advance_mbtn = "nul" +input_game_focus_toggle_axis = "nul" +input_game_focus_toggle_btn = "nul" +input_game_focus_toggle_mbtn = "nul" +input_game_focus_toggle = "scroll_lock" +input_grab_mouse_toggle_axis = "nul" +input_grab_mouse_toggle_btn = "nul" +input_grab_mouse_toggle = "f11" +input_grab_mouse_toggle_mbtn = "nul" +input_hold_fast_forward_axis = "nul" +input_hold_fast_forward_btn = "nul" +input_hold_fast_forward = "l" +input_hold_fast_forward_mbtn = "nul" +input_hold_slowmotion_axis = "nul" +input_hold_slowmotion_btn = "nul" +input_hold_slowmotion = "e" +input_hold_slowmotion_mbtn = "nul" +input_hotkey_block_delay = "5" +input_joypad_driver = "udev" +input_keyboard_layout = "" +input_libretro_device_p10 = "1" +input_libretro_device_p1 = "1" +input_libretro_device_p11 = "1" +input_libretro_device_p12 = "1" +input_libretro_device_p13 = "1" +input_libretro_device_p14 = "1" +input_libretro_device_p15 = "1" +input_libretro_device_p16 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_libretro_device_p6 = "1" +input_libretro_device_p7 = "1" +input_libretro_device_p8 = "1" +input_libretro_device_p9 = "1" +input_load_state_axis = "nul" +input_load_state_btn = "4" +input_load_state = "f4" +input_load_state_mbtn = "nul" +input_max_users = "5" +input_menu_toggle_axis = "nul" +input_menu_toggle_btn = "2" +input_menu_toggle = "f1" +input_menu_toggle_gamepad_combo = "2" +input_menu_toggle_mbtn = "nul" +input_movie_record_toggle_axis = "nul" +input_movie_record_toggle_btn = "nul" +input_movie_record_toggle_mbtn = "nul" +input_movie_record_toggle = "o" +input_netplay_game_watch_axis = "nul" +input_netplay_game_watch_btn = "nul" +input_netplay_game_watch = "i" +input_netplay_game_watch_mbtn = "nul" +input_netplay_host_toggle_axis = "nul" +input_netplay_host_toggle_btn = "nul" +input_netplay_host_toggle_mbtn = "nul" +input_netplay_host_toggle = "nul" +input_nowinkey_enable = "false" +input_osk_toggle_axis = "nul" +input_osk_toggle_btn = "nul" +input_osk_toggle = "f12" +input_osk_toggle_mbtn = "nul" +input_overlay = "" +input_overlay_aspect_adjust_landscape = "0.000000" +input_overlay_aspect_adjust_portrait = "0.000000" +input_overlay_auto_rotate = "false" +input_overlay_auto_scale = "false" +input_overlay_enable_autopreferred = "true" +input_overlay_enable = "false" +input_overlay_hide_in_menu = "true" +input_overlay_hide_when_gamepad_connected = "false" +input_overlay_next_axis = "nul" +input_overlay_next_btn = "nul" +input_overlay_next_mbtn = "nul" +input_overlay_next = "nul" +input_overlay_opacity = "0.700000" +input_overlay_scale_landscape = "1.000000" +input_overlay_scale_portrait = "1.000000" +input_overlay_show_inputs = "2" +input_overlay_show_inputs_port = "0" +input_overlay_show_mouse_cursor = "true" +input_overlay_x_offset_landscape = "0.000000" +input_overlay_x_offset_portrait = "0.000000" +input_overlay_x_separation_landscape = "0.000000" +input_overlay_x_separation_portrait = "0.000000" +input_overlay_y_offset_landscape = "0.000000" +input_overlay_y_offset_portrait = "0.000000" +input_overlay_y_separation_landscape = "0.000000" +input_overlay_y_separation_portrait = "0.000000" +input_pause_toggle_axis = "nul" +input_pause_toggle_btn = "nul" +input_pause_toggle_mbtn = "nul" +input_pause_toggle = "p" +input_poll_type_behavior = "2" +input_quit_gamepad_combo = "0" +input_recording_toggle_axis = "nul" +input_recording_toggle_btn = "nul" +input_recording_toggle_mbtn = "nul" +input_recording_toggle = "nul" +input_remap_binds_enable = "true" +input_remapping_directory = "~/remappings" +input_reset_axis = "nul" +input_reset_btn = "nul" +input_reset = "h" +input_reset_mbtn = "nul" +input_rewind_axis = "nul" +input_rewind_btn = "6" +input_rewind_mbtn = "nul" +input_rewind = "r" +input_rumble_gain = "25" +input_runahead_toggle_axis = "nul" +input_runahead_toggle_btn = "nul" +input_runahead_toggle_mbtn = "nul" +input_runahead_toggle = "nul" +input_save_state_axis = "nul" +input_save_state_btn = "5" +input_save_state = "f2" +input_save_state_mbtn = "nul" +input_screenshot_axis = "nul" +input_screenshot_btn = "nul" +input_screenshot = "f8" +input_screenshot_mbtn = "nul" +input_send_debug_info_axis = "nul" +input_send_debug_info_btn = "nul" +input_send_debug_info = "f10" +input_send_debug_info_mbtn = "nul" +input_sensors_enable = "true" +input_shader_next_axis = "nul" +input_shader_next_btn = "nul" +input_shader_next = "m" +input_shader_next_mbtn = "nul" +input_shader_prev_axis = "nul" +input_shader_prev_btn = "nul" +input_shader_prev_mbtn = "nul" +input_shader_prev = "n" +input_state_slot_decrease_axis = "nul" +input_state_slot_decrease_btn = "nul" +input_state_slot_decrease = "f6" +input_state_slot_decrease_mbtn = "nul" +input_state_slot_increase_axis = "nul" +input_state_slot_increase_btn = "nul" +input_state_slot_increase = "f7" +input_state_slot_increase_mbtn = "nul" +input_streaming_toggle_axis = "nul" +input_streaming_toggle_btn = "nul" +input_streaming_toggle_mbtn = "nul" +input_streaming_toggle = "nul" +input_toggle_fast_forward_axis = "nul" +input_toggle_fast_forward_btn = "7" +input_toggle_fast_forward_mbtn = "nul" +input_toggle_fast_forward = "space" +input_toggle_fullscreen_axis = "nul" +input_toggle_fullscreen_btn = "nul" +input_toggle_fullscreen = "f" +input_toggle_fullscreen_mbtn = "nul" +input_toggle_slowmotion_axis = "nul" +input_toggle_slowmotion_btn = "nul" +input_toggle_slowmotion_mbtn = "nul" +input_toggle_slowmotion = "nul" +input_touch_scale = "1" +input_turbo_default_button = "0" +input_turbo_mode = "0" +input_turbo_period = "6" +input_volume_down_axis = "nul" +input_volume_down_btn = "nul" +input_volume_down_mbtn = "nul" +input_volume_down = "subtract" +input_volume_up = "add" +input_volume_up_axis = "nul" +input_volume_up_btn = "nul" +input_volume_up_mbtn = "nul" +joypad_autoconfig_dir = "/tmp/joypads" +keyboard_gamepad_enable = "true" +keyboard_gamepad_mapping_type = "1" +kiosk_mode_enable = "false" +kiosk_mode_password = "" +led_driver = "null" +libretro_directory = "/tmp/cores" +libretro_info_path = "/tmp/cores" +libretro_log_level = "1" +load_dummy_on_core_shutdown = "true" +location_allow = "false" +location_driver = "null" +log_dir = "~/.config/retroarch/logs" +log_to_file = "false" +log_to_file_timestamp = "false" +log_verbosity = "true" +materialui_auto_rotate_nav_bar = "true" +materialui_dual_thumbnail_list_view_enable = "true" +materialui_icons_enable = "true" +materialui_landscape_layout_optimization = "1" +materialui_menu_color_theme = "9" +materialui_menu_transition_animation = "0" +materialui_playlist_icons_enable = "true" +materialui_show_nav_bar = "true" +materialui_thumbnail_background_enable = "true" +materialui_thumbnail_view_landscape = "2" +materialui_thumbnail_view_portrait = "1" +memory_show = "false" +memory_update_interval = "256" +menu_battery_level_enable = "true" +menu_core_enable = "true" +menu_driver = "xmb" +menu_dynamic_wallpaper_enable = "false" +menu_enable_widgets = "true" +menu_font_color_blue = "255" +menu_font_color_green = "255" +menu_font_color_red = "255" +menu_footer_opacity = "1.000000" +menu_framebuffer_opacity = "0.899999" +menu_header_opacity = "1.000000" +menu_horizontal_animation = "true" +menu_insert_disk_resume = "true" +menu_left_thumbnails = "0" +menu_linear_filter = "false" +menu_mouse_enable = "false" +menu_navigation_browser_filter_supported_extensions_enable = "true" +menu_navigation_wraparound_enable = "true" +menu_pause_libretro = "true" +menu_pointer_enable = "true" +menu_rgui_full_width_layout = "true" +menu_rgui_shadows = "false" +menu_rgui_transparency = "true" +menu_savestate_resume = "true" +menu_scale_factor = "0.300000" +menu_screensaver_animation = "0" +menu_screensaver_animation_speed = "1.000000" +menu_screensaver_timeout = "0" +menu_scroll_delay = "256" +menu_scroll_fast = "false" +menu_shader_pipeline = "2" +menu_show_advanced_settings = "true" +menu_show_configurations = "true" +menu_show_core_updater = "false" +menu_show_dump_disc = "true" +menu_show_help = "true" +menu_show_information = "true" +menu_show_latency = "true" +menu_show_legacy_thumbnail_updater = "false" +menu_show_load_content_animation = "false" +menu_show_load_content = "true" +menu_show_load_core = "true" +menu_show_load_disc = "true" +menu_show_online_updater = "true" +menu_show_overlays = "true" +menu_show_quit_retroarch = "true" +menu_show_reboot = "false" +menu_show_restart_retroarch = "true" +menu_show_rewind = "true" +menu_show_shutdown = "false" +menu_show_sublabels = "true" +menu_show_video_layout = "true" +menu_swap_ok_cancel_buttons = "false" +menu_throttle_framerate = "true" +menu_thumbnails = "3" +menu_thumbnail_upscale_threshold = "0" +menu_ticker_smooth = "true" +menu_ticker_speed = "2.000000" +menu_ticker_type = "1" +menu_timedate_date_separator = "0" +menu_timedate_enable = "true" +menu_timedate_style = "11" +menu_unified_controls = "false" +menu_use_preferred_system_color_theme = "false" +menu_wallpaper = "" +menu_wallpaper_opacity = "1.000000" +menu_widget_scale_auto = "false" +menu_widget_scale_factor = "0.350000" +menu_widget_scale_factor_windowed = "1.000000" +menu_xmb_animation_horizontal_highlight = "0" +menu_xmb_animation_move_up_down = "0" +menu_xmb_animation_opening_main_menu = "0" +menu_xmb_thumbnail_scale_factor = "100" +midi_driver = "alsa" +midi_input = "Off" +midi_output = "Off" +midi_volume = "100" +netplay_allow_slaves = "true" +netplay_check_frames = "600" +netplay_input_latency_frames_min = "0" +netplay_input_latency_frames_range = "0" +netplay_ip_address = "" +netplay_ip_port = "55435" +netplay_max_connections = "3" +netplay_mitm_server = "nyc" +netplay_nat_traversal = "true" +netplay_nickname = "" +netplay_password = "" +netplay_public_announce = "true" +netplay_request_device_p10 = "false" +netplay_request_device_p11 = "false" +netplay_request_device_p12 = "false" +netplay_request_device_p13 = "false" +netplay_request_device_p14 = "false" +netplay_request_device_p15 = "false" +netplay_request_device_p16 = "false" +netplay_request_device_p1 = "false" +netplay_request_device_p2 = "false" +netplay_request_device_p3 = "false" +netplay_request_device_p4 = "false" +netplay_request_device_p5 = "false" +netplay_request_device_p6 = "false" +netplay_request_device_p7 = "false" +netplay_request_device_p8 = "false" +netplay_request_device_p9 = "false" +netplay_require_slaves = "false" +netplay_share_analog = "1" +netplay_share_digital = "1" +netplay_spectate_password = "" +netplay_start_as_spectator = "false" +netplay_stateless_mode = "false" +netplay_use_mitm_server = "false" +network_cmd_enable = "false" +network_cmd_port = "55355" +network_on_demand_thumbnails = "false" +network_remote_base_port = "55400" +network_remote_enable = "false" +network_remote_enable_user_p10 = "false" +network_remote_enable_user_p11 = "false" +network_remote_enable_user_p12 = "false" +network_remote_enable_user_p13 = "false" +network_remote_enable_user_p14 = "false" +network_remote_enable_user_p15 = "false" +network_remote_enable_user_p16 = "false" +network_remote_enable_user_p1 = "false" +network_remote_enable_user_p2 = "false" +network_remote_enable_user_p3 = "false" +network_remote_enable_user_p4 = "false" +network_remote_enable_user_p5 = "false" +network_remote_enable_user_p6 = "false" +network_remote_enable_user_p7 = "false" +network_remote_enable_user_p8 = "false" +network_remote_enable_user_p9 = "false" +notification_show_autoconfig = "false" +notification_show_cheats_applied = "true" +notification_show_config_override_load = "false" +notification_show_fast_forward = "true" +notification_show_netplay_extra = "false" +notification_show_patch_applied = "true" +notification_show_refresh_rate = "true" +notification_show_remap_load = "false" +notification_show_screenshot_duration = "2" +notification_show_screenshot = "false" +notification_show_screenshot_flash = "1" +notification_show_set_initial_disk = "true" +overlay_directory = "/tmp/overlays" +ozone_collapse_sidebar = "false" +ozone_menu_color_theme = "1" +ozone_scroll_content_metadata = "false" +ozone_sort_after_truncate_playlist_name = "true" +ozone_truncate_playlist_name = "true" +pause_nonactive = "true" +perfcnt_enable = "false" +playlist_compression = "false" +playlist_cores = "" +playlist_directory = "~/playlists" +playlist_entry_remove_enable = "1" +playlist_entry_remove = "false" +playlist_entry_rename = "false" +playlist_fuzzy_archive_match = "false" +playlist_names = "" +playlist_portable_paths = "false" +playlist_show_entry_idx = "true" +playlist_show_inline_core_name = "0" +playlist_show_sublabels = "true" +playlist_sort_alphabetical = "true" +playlist_sublabel_last_played_style = "0" +playlist_sublabel_runtime_type = "0" +playlist_use_old_format = "false" +quick_menu_show_add_to_favorites = "true" +quick_menu_show_cheats = "true" +quick_menu_show_close_content = "true" +quick_menu_show_controls = "true" +quick_menu_show_core_options_flush = "false" +quick_menu_show_download_thumbnails = "true" +quick_menu_show_information = "true" +quick_menu_show_options = "true" +quick_menu_show_recording = "true" +quick_menu_show_reset_core_association = "true" +quick_menu_show_restart_content = "true" +quick_menu_show_resume_content = "true" +quick_menu_show_save_content_dir_overrides = "true" +quick_menu_show_save_core_overrides = "false" +quick_menu_show_save_game_overrides = "false" +quick_menu_show_save_load_state = "true" +quick_menu_show_set_core_association = "true" +quick_menu_show_shaders = "true" +quick_menu_show_start_recording = "true" +quick_menu_show_start_streaming = "true" +quick_menu_show_streaming = "true" +quick_menu_show_take_screenshot = "true" +quick_menu_show_undo_save_load_state = "false" +quit_on_close_content = "0" +quit_press_twice = "true" +record_driver = "null" +recording_config_directory = "" +recording_output_directory = "~/roms/screenshots" +resampler_directory = "" +rewind_buffer_size = "20971520" +rewind_buffer_size_step = "10" +rewind_enable = "false" +rewind_granularity = "1" +rgui_aspect_ratio = "0" +rgui_aspect_ratio_lock = "0" +rgui_background_filler_thickness_enable = "true" +rgui_border_filler_enable = "true" +rgui_border_filler_thickness_enable = "true" +rgui_browser_directory = "~/roms" +rgui_config_directory = "~/.config/retroarch/config" +rgui_extended_ascii = "false" +rgui_inline_thumbnails = "false" +rgui_internal_upscale_level = "0" +rgui_menu_color_theme = "4" +rgui_menu_theme_preset = "" +rgui_particle_effect = "0" +rgui_particle_effect_screensaver = "true" +rgui_particle_effect_speed = "1.000000" +rgui_show_start_screen = "false" +rgui_swap_thumbnails = "false" +rgui_switch_icons = "true" +rgui_thumbnail_delay = "0" +rgui_thumbnail_downscaler = "0" +run_ahead_enabled = "false" +run_ahead_frames = "1" +run_ahead_hide_warnings = "false" +run_ahead_secondary_instance = "true" +runtime_log_directory = "default" +save_file_compression = "false" +savefile_directory = "~/.config/retroarch/saves" +savefiles_in_content_dir = "true" +savestate_auto_index = "false" +savestate_auto_load = "false" +savestate_auto_save = "false" +savestate_directory = "~/.config/retroarch/states" +savestate_file_compression = "true" +savestate_max_keep = "0" +savestates_in_content_dir = "false" +savestate_thumbnail_enable = "true" +scan_without_core_match = "false" +screen_brightness = "100" +screen_orientation = "0" +screenshot_directory = "~/roms/screenshots" +screenshots_in_content_dir = "false" +settings_show_accessibility = "true" +settings_show_achievements = "true" +settings_show_ai_service = "true" +settings_show_audio = "true" +settings_show_configuration = "true" +settings_show_core = "true" +settings_show_directory = "true" +settings_show_drivers = "true" +settings_show_file_browser = "true" +settings_show_frame_throttle = "true" +settings_show_input = "true" +settings_show_latency = "true" +settings_show_logging = "true" +settings_show_network = "true" +settings_show_onscreen_display = "true" +settings_show_playlists = "true" +settings_show_power_management = "true" +settings_show_recording = "true" +settings_show_saving = "true" +settings_show_user_interface = "true" +settings_show_user = "true" +settings_show_video = "true" +show_hidden_files = "false" +slowmotion_ratio = "3.000000" +soft_filter_enable = "false" +soft_filter_index = "0" +sort_savefiles_by_content_enable = "false" +sort_savefiles_enable = "false" +sort_savestates_by_content_enable = "false" +sort_savestates_enable = "false" +sort_screenshots_by_content_enable = "false" +state_slot = "0" +statistics_show = "false" +stdin_cmd_enable = "false" +streaming_mode = "0" +suspend_screensaver_enable = "true" +sustained_performance_mode = "false" +system_directory = "~/roms/bios" +systemfiles_in_content_dir = "false" +threaded_data_runloop_enable = "true" +thumbnails_directory = "~/thumbnails" +twitch_stream_key = "" +ui_companion_enable = "false" +ui_companion_start_on_boot = "true" +ui_companion_toggle = "false" +ui_menubar_enable = "true" +use_last_start_directory = "false" +user_language = "0" +vibrate_on_keypress = "true" +video_adaptive_vsync = "false" +video_allow_rotate = "true" +video_aspect_ratio = "-1.000000" +video_aspect_ratio_auto = "true" +video_black_frame_insertion = "0" +video_context_driver = "" +video_crop_overscan = "true" +video_ctx_scaling = "false" +video_disable_composition = "false" +video_driver = "glcore" +video_filter = "" +video_filter_dir = "~/.config/retroarch/filters/video" +video_font_enable = "true" +video_font_path = "/usr/share/retroarch-assets/xmb/monochrome/font.ttf" +video_font_size = "32.000000" +video_force_aspect = "true" +video_force_srgb_disable = "false" +video_frame_delay = "0" +video_frame_delay_auto = "false" +video_fullscreen = "true" +video_fullscreen_x = "1920" +video_fullscreen_y = "1152" +video_gpu_record = "false" +video_gpu_screenshot = "false" +video_hard_sync = "false" +video_hard_sync_frames = "0" +video_hdr_display_contrast = "5.000000" +video_hdr_enable = "false" +video_hdr_expand_gamut = "true" +video_hdr_max_nits = "1000.000000" +video_hdr_paper_white_nits = "200.000000" +video_layout_directory = "~/.config/retroarch/layouts" +video_layout_enable = "true" +video_layout_path = "" +video_layout_selected_view = "0" +video_max_swapchain_images = "3" +video_message_color = "ffff00" +video_message_pos_x = "0.049999" +video_message_pos_y = "0.049999" +video_monitor_index = "0" +video_msg_bgcolor_blue = "0" +video_msg_bgcolor_enable = "false" +video_msg_bgcolor_green = "0" +video_msg_bgcolor_opacity = "1.000000" +video_msg_bgcolor_red = "0" +video_notch_write_over_enable = "false" +video_oga_vertical_enable = "false" +video_post_filter_record = "false" +video_record_config = "" +video_record_quality = "4" +video_record_scale_factor = "1" +video_record_threads = "2" +video_refresh_rate = "60.000000" +video_rotation = "0" +video_scale = "3.000000" +video_scale_integer = "false" +video_scale_integer_overscale = "false" +video_shader_delay = "0" +video_shader_dir = "/tmp/shaders" +video_shader_enable = "false" +video_shader_preset_save_reference_enable = "true" +video_shader_remember_last_dir = "false" +video_shader_watch_files = "false" +video_shared_context = "false" +video_smooth = "false" +video_stream_config = "" +video_stream_port = "56400" +video_stream_quality = "10" +video_stream_scale_factor = "1" +video_stream_url = "" +video_swap_interval = "1" +video_threaded = "true" +video_vsync = "true" +video_window_auto_height_max = "1152" +video_window_auto_width_max = "1920" +video_window_custom_size_enable = "false" +video_windowed_fullscreen = "false" +video_windowed_position_height = "720" +video_windowed_position_width = "1280" +video_windowed_position_x = "0" +video_windowed_position_y = "0" +video_window_opacity = "100" +video_window_save_positions = "false" +video_window_show_decorations = "true" +vrr_runloop_enable = "false" +wifi_driver = "null" +wifi_enabled = "true" +xmb_alpha_factor = "75" +xmb_font = "/usr/share/retroarch-assets/xmb/monochrome/font.ttf" +xmb_layout = "2" +xmb_menu_color_theme = "4" +xmb_shadows_enable = "true" +xmb_theme = "0" +xmb_vertical_thumbnails = "false" +youtube_stream_key = "" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3399/retroarch32bit-append.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3399/retroarch32bit-append.cfg new file mode 100755 index 0000000000..343124c254 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3399/retroarch32bit-append.cfg @@ -0,0 +1,3 @@ +audio_filter_dir = "/usr/share/retroarch/filters/32bit/audio" +video_filter_dir = "/usr/share/retroarch/filters/32bit/video" +libretro_directory = /usr/lib32/libretro diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3399/retroarch64bit-append.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3399/retroarch64bit-append.cfg new file mode 100755 index 0000000000..b6cbf68312 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3399/retroarch64bit-append.cfg @@ -0,0 +1,2 @@ +audio_filter_dir = "/usr/share/retroarch/filters/64bit/audio" +video_filter_dir = "/usr/share/retroarch/filters/64bit/video" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3566/TATE-MAME 2003-Plus.rmp b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3566/TATE-MAME 2003-Plus.rmp new file mode 100644 index 0000000000..366e47afad --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3566/TATE-MAME 2003-Plus.rmp @@ -0,0 +1,27 @@ +input_libretro_device_p1 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_player1_analog_dpad_mode = "1" +input_player1_btn_down = "6" +input_player1_btn_left = "4" +input_player1_btn_right = "5" +input_player1_btn_up = "7" +input_player1_stk_l_x+ = "5" +input_player1_stk_l_x- = "4" +input_player1_stk_l_y+ = "6" +input_player1_stk_l_y- = "7" +input_player1_stk_r_x+ = "5" +input_player1_stk_r_x- = "4" +input_player1_stk_r_y+ = "6" +input_player1_stk_r_y- = "7" +input_player2_analog_dpad_mode = "0" +input_player3_analog_dpad_mode = "0" +input_player4_analog_dpad_mode = "0" +input_player5_analog_dpad_mode = "0" +input_remap_port_p1 = "0" +input_remap_port_p2 = "1" +input_remap_port_p3 = "2" +input_remap_port_p4 = "3" +input_remap_port_p5 = "4" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3566/retroarch-core-options.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3566/retroarch-core-options.cfg new file mode 100644 index 0000000000..59b65f5bfb --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3566/retroarch-core-options.cfg @@ -0,0 +1,152 @@ +mupen64plus-alt-map = "False" +mupen64plus-aspect = "4:3" +mupen64plus-astick-deadzone = "15" +mupen64plus-astick-sensitivity = "100" +mupen64plus-BackgroundMode = "Stripped" +mupen64plus-BilinearMode = "standard" +mupen64plus-CorrectTexrectCoords = "Auto" +mupen64plus-CountPerOp = "0" +mupen64plus-CountPerOpDenomPot = "0" +mupen64plus-cpucore = "dynamic_recompiler" +mupen64plus-d-cbutton = "C3" +mupen64plus-DitheringPattern = "True" +mupen64plus-DitheringQuantization = "True" +mupen64plus-EnableCopyAuxToRDRAM = "True" +mupen64plus-EnableCopyColorToRDRAM = "Async" +mupen64plus-EnableCopyDepthToRDRAM = "Software" +mupen64plus-EnableEnhancedHighResStorage = "False" +mupen64plus-EnableEnhancedTextureStorage = "False" +mupen64plus-EnableFBEmulation = "True" +mupen64plus-EnableFragmentDepthWrite = "True" +mupen64plus-EnableHiResAltCRC = "False" +mupen64plus-EnableHWLighting = "False" +mupen64plus-EnableInaccurateTextureCoordinates = "False" +mupen64plus-EnableLegacyBlending = "False" +mupen64plus-EnableLODEmulation = "True" +mupen64plus-EnableNativeResFactor = "1" +mupen64plus-EnableNativeResTexrects = "Optimized" +mupen64plus-EnableOverscan = "Enabled" +mupen64plus-EnableTexCoordBounds = "False" +mupen64plus-EnableTextureCache = "True" +mupen64plus-ForceDisableExtraMem = "False" +mupen64plus-FrameDuping = "True" +mupen64plus-Framerate = "Original" +mupen64plus-FXAA = "0" +mupen64plus-GLideN64IniBehaviour = "late" +mupen64plus-HybridFilter = "True" +mupen64plus-IgnoreTLBExceptions = "False" +mupen64plus-l-cbutton = "C2" +mupen64plus-MaxHiResTxVramLimit = "0" +mupen64plus-MaxTxCacheSize = "8000" +mupen64plus-MultiSampling = "0" +mupen64plus-OverscanBottom = "0" +mupen64plus-OverscanLeft = "0" +mupen64plus-OverscanRight = "0" +mupen64plus-OverscanTop = "0" +mupen64plus-pak1 = "memory" +mupen64plus-pak2 = "none" +mupen64plus-pak3 = "none" +mupen64plus-pak4 = "none" +mupen64plus-r-cbutton = "C1" +mupen64plus-rdp-plugin = "gliden64" +mupen64plus-RDRAMImageDitheringMode = "BlueNoise" +mupen64plus-rsp-plugin = "hle" +mupen64plus-ThreadedRenderer = "True" +mupen64plus-txCacheCompression = "True" +mupen64plus-txEnhancementMode = "None" +mupen64plus-txFilterIgnoreBG = "True" +mupen64plus-txFilterMode = "None" +mupen64plus-txHiresEnable = "False" +mupen64plus-txHiresFullAlphaChannel = "False" +mupen64plus-u-cbutton = "C4" +mupen64plus-virefresh = "Auto" +pcsx_rearmed_analog_axis_modifier = "circle" +pcsx_rearmed_async_cd = "sync" +pcsx_rearmed_bios = "auto" +pcsx_rearmed_display_internal_fps = "disabled" +pcsx_rearmed_dithering = "enabled" +pcsx_rearmed_drc = "enabled" +pcsx_rearmed_duping_enable = "enabled" +pcsx_rearmed_frameskip_type = "disabled" +pcsx_rearmed_gteregsunneeded = "disabled" +pcsx_rearmed_gunconadjustratiox = "1" +pcsx_rearmed_gunconadjustratioy = "1" +pcsx_rearmed_gunconadjustx = "0" +pcsx_rearmed_gunconadjusty = "0" +pcsx_rearmed_idiablofix = "disabled" +pcsx_rearmed_input_sensitivity = "1.00" +pcsx_rearmed_inuyasha_fix = "disabled" +pcsx_rearmed_memcard2 = "disabled" +pcsx_rearmed_multitap1 = "auto" +pcsx_rearmed_multitap2 = "auto" +pcsx_rearmed_negcon_deadzone = "0" +pcsx_rearmed_negcon_response = "linear" +pcsx_rearmed_neon_enhancement_enable = "disabled" +pcsx_rearmed_neon_enhancement_no_main = "disabled" +pcsx_rearmed_neon_interlace_enable = "disabled" +pcsx_rearmed_nocdaudio = "enabled" +pcsx_rearmed_nogteflags = "disabled" +pcsx_rearmed_nosmccheck = "disabled" +pcsx_rearmed_noxadecoding = "enabled" +pcsx_rearmed_pad1type = "standard" +pcsx_rearmed_pad2type = "standard" +pcsx_rearmed_pad3type = "none" +pcsx_rearmed_pad4type = "none" +pcsx_rearmed_pad5type = "none" +pcsx_rearmed_pad6type = "none" +pcsx_rearmed_pad7type = "none" +pcsx_rearmed_pad8type = "none" +pcsx_rearmed_pe2_fix = "disabled" +pcsx_rearmed_psxclock = "57" +pcsx_rearmed_region = "auto" +pcsx_rearmed_show_bios_bootlogo = "disabled" +pcsx_rearmed_show_other_input_settings = "disabled" +pcsx_rearmed_spu_interpolation = "simple" +pcsx_rearmed_spu_reverb = "enabled" +pcsx_rearmed_spuirq = "disabled" +pcsx_rearmed_vibration = "enabled" +gambatte_gb_colorization = "disabled" +gambatte_gb_internal_palette = "" +mame2003-plus_analog = "digital" +mame2003-plus_art_resolution = "1" +mame2003-plus_brightness = "1.0" +mame2003-plus_cheat_input_ports = "disabled" +mame2003-plus_core_save_subfolder = "enabled" +mame2003-plus_core_sys_subfolder = "enabled" +mame2003-plus_dcs_speedhack = "enabled" +mame2003-plus_deadzone = "20" +mame2003-plus_digital_joy_centering = "enabled" +mame2003-plus_display_artwork = "enabled" +mame2003-plus_display_setup = "disabled" +mame2003-plus_four_way_emulation = "disabled" +mame2003-plus_frameskip = "0" +mame2003-plus_gamma = "1.0" +mame2003-plus_input_interface = "retropad" +mame2003-plus_machine_timing = "enabled" +mame2003-plus_mame_remapping = "enabled" +mame2003-plus_mouse_device = "mouse" +mame2003-plus_sample_rate = "48000" +mame2003-plus_skip_disclaimer = "disabled" +mame2003-plus_skip_warnings = "disabled" +flycast_internal_resolution = "640x480" +flycast_alpha_sorting = "per-strip (fast, least accurate)" +flycast_enable_dsp = "disabled" +flycast_threaded_rendering = "enabled" +flycast_anisotropic_filtering = "off" +flycast_synchronous_rendering = "enabled" +flycast_enable_rtt = "disabled" +flycast_enable_rttb = "disabled" +flycast_delay_frame_swapping = "disabled" +flycast_div_matching = "auto" +flycast_texupscale = "off" +flycast_auto_skip_frame = "normal" +opera_swi_hle = "enabled" +opera_dsp_threaded = "enabled" +opera_madam_matrix_engine = "software" +puae_deadzone = "25" +melonds_screen_layout = "Left/Right" +melonds_swapscreen_mode = "Toggle" +melonds_threaded_renderer = "enabled" +melonds_touch_mode = "Joystick" +virtualjaguar_bios = "enabled" +virtualjaguar_usefastblitter = "enabled" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3566/retroarch.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3566/retroarch.cfg new file mode 100644 index 0000000000..f95b391016 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3566/retroarch.cfg @@ -0,0 +1,822 @@ +accessibility_enable = "false" +accessibility_narrator_speech_speed = "5" +ai_service_enable = "true" +ai_service_mode = "1" +ai_service_pause = "false" +ai_service_source_lang = "0" +ai_service_target_lang = "0" +ai_service_url = "http://localhost:4404/" +all_users_control_menu = "true" +apply_cheats_after_load = "false" +apply_cheats_after_toggle = "false" +aspect_ratio_index = "22" +assets_directory = "/tmp/assets" +audio_block_frames = "0" +audio_device = "" +audio_driver = "alsathread" +audio_dsp_plugin = "" +audio_enable_menu_bgm = "false" +audio_enable_menu_cancel = "false" +audio_enable_menu = "false" +audio_enable_menu_notice = "false" +audio_enable_menu_ok = "false" +audio_enable = "true" +audio_fastforward_mute = "false" +audio_filter_dir = "~/.config/retroarch/filters/audio" +audio_latency = "32" +audio_max_timing_skew = "0.049999" +audio_mixer_mute_enable = "false" +audio_mixer_volume = "0.000000" +audio_mute_enable = "false" +audio_out_rate = "48000" +audio_rate_control_delta = "0.004999" +audio_rate_control = "true" +audio_resampler_quality = "2" +audio_resampler = "sinc" +audio_sync = "true" +audio_volume = "0.000000" +auto_overrides_enable = "true" +auto_remaps_enable = "true" +autosave_interval = "10" +auto_screenshot_filename = "true" +auto_shaders_enable = "true" +block_sram_overwrite = "false" +bluetooth_driver = "null" +builtin_imageviewer_enable = "false" +builtin_mediaplayer_enable = "true" +bundle_assets_dst_path = "" +bundle_assets_dst_path_subdir = "" +bundle_assets_extract_enable = "false" +bundle_assets_extract_last_version = "0" +bundle_assets_extract_version_current = "0" +bundle_assets_src_path = "" +cache_directory = "/tmp/cache" +camera_allow = "false" +camera_device = "" +camera_driver = "null" +cheat_database_path = "/tmp/database/cht" +check_firmware_before_loading = "false" +cheevos_auto_screenshot = "false" +cheevos_badges_enable = "false" +cheevos_challenge_indicators = "true" +cheevos_enable = "false" +cheevos_hardcore_mode_enable = "false" +cheevos_leaderboards_enable = "" +cheevos_password = "" +cheevos_richpresence_enable = "true" +cheevos_start_active = "false" +cheevos_test_unofficial = "false" +cheevos_token = "" +cheevos_unlock_sound_enable = "false" +cheevos_username = "" +cheevos_verbose_enable = "false" +config_save_on_exit = "false" +content_database_path = "/tmp/database/rdb" +content_favorites_directory = "default" +content_favorites_path = "~/.config/retroarch/content_favorites.lpl" +content_favorites_size = "200" +content_history_dir = "" +content_history_directory = "default" +content_history_path = "~/.config/retroarch/content_history.lpl" +content_history_size = "200" +content_image_history_directory = "default" +content_image_history_path = "~/.config/retroarch/content_image_history.lpl" +content_music_history_directory = "default" +content_music_history_path = "~/.config/retroarch/content_music_history.lpl" +content_runtime_log_aggregate = "false" +content_runtime_log = "true" +content_show_add_entry = "2" +content_show_add = "true" +content_show_explore = "true" +content_show_favorites = "true" +content_show_history = "true" +content_show_images = "false" +content_show_music = "false" +content_show_netplay = "true" +content_show_playlists = "true" +content_show_settings_password = "" +content_show_settings = "true" +content_show_video = "false" +content_video_directory = "default" +content_video_history_path = "~/.config/retroarch/content_video_history.lpl" +core_assets_directory = "~/roms/downloads" +core_info_cache_enable = "true" +core_option_category_enable = "true" +core_options_path = "" +core_set_supports_no_game_enable = "true" +core_updater_auto_backup = "false" +core_updater_auto_backup_history_size = "1" +core_updater_auto_extract_archive = "true" +core_updater_buildbot_assets_url = "http://buildbot.libretro.com/assets/" +core_updater_buildbot_cores_url = "" +core_updater_buildbot_url = "http://buildbot.libretro.com/nightly/linux/armhf/latest/" +core_updater_show_experimental_cores = "false" +cpu_main_gov = "performance" +cpu_max_freq = "-1" +cpu_menu_gov = "interactive" +cpu_min_freq = "1" +cpu_scaling_mode = "0" +crt_switch_center_adjust = "0" +crt_switch_hires_menu = "false" +crt_switch_porch_adjust = "0" +crt_switch_resolution = "0" +crt_switch_resolution_super = "2560" +crt_switch_resolution_use_custom_refresh_rate = "false" +crt_switch_timings = "" +crt_video_refresh_rate = "60.000000" +current_resolution_id = "0" +cursor_directory = "~/.config/retroarch/database/cursors" +desktop_menu_enable = "true" +discord_allow = "false" +discord_app_id = "475456035851599874" +driver_switch_enable = "true" +dynamic_wallpapers_directory = "default" +emuelec_exit_to_kodi = "false" +enable_device_vibration = "true" +facebook_stream_key = "" +fastforward_ratio = "0.000000" +filter_by_current_core = "false" +flicker_filter_enable = "false" +flicker_filter_index = "0" +fps_show = "false" +fps_update_interval = "256" +framecount_show = "false" +frame_time_counter_reset_after_fastforwarding = "false" +frame_time_counter_reset_after_load_state = "false" +frame_time_counter_reset_after_save_state = "false" +frontend_log_level = "1" +game_specific_options = "true" +gamma_correction = "0" +global_core_options = "false" +history_list_enable = "true" +input_ai_service_axis = "nul" +input_ai_service_btn = "nul" +input_ai_service_mbtn = "nul" +input_ai_service = "nul" +input_analog_deadzone = "0.000000" +input_analog_sensitivity = "1.500000" +input_audio_mute_axis = "nul" +input_audio_mute_btn = "nul" +input_audio_mute = "f9" +input_audio_mute_mbtn = "nul" +input_autodetect_enable = "true" +input_auto_game_focus = "0" +input_auto_mouse_grab = "false" +input_axis_threshold = "0.500000" +input_bind_hold = "2" +input_bind_timeout = "5" +input_cheat_index_minus_axis = "nul" +input_cheat_index_minus_btn = "nul" +input_cheat_index_minus_mbtn = "nul" +input_cheat_index_minus = "t" +input_cheat_index_plus_axis = "nul" +input_cheat_index_plus_btn = "nul" +input_cheat_index_plus_mbtn = "nul" +input_cheat_index_plus = "y" +input_cheat_toggle_axis = "nul" +input_cheat_toggle_btn = "nul" +input_cheat_toggle_mbtn = "nul" +input_cheat_toggle = "u" +input_close_content_axis = "nul" +input_close_content_btn = "nul" +input_close_content_mbtn = "nul" +input_close_content = "nul" +input_descriptor_hide_unbound = "false" +input_descriptor_label_show = "true" +input_desktop_menu_toggle_axis = "nul" +input_desktop_menu_toggle_btn = "nul" +input_desktop_menu_toggle = "f5" +input_desktop_menu_toggle_mbtn = "nul" +input_device_p1 = "0" +input_device_p10 = "0" +input_device_p11 = "0" +input_device_p12 = "0" +input_device_p13 = "0" +input_device_p14 = "0" +input_device_p15 = "0" +input_device_p16 = "0" +input_device_p2 = "0" +input_device_p3 = "0" +input_device_p4 = "0" +input_device_p5 = "0" +input_device_p6 = "0" +input_device_p7 = "0" +input_device_p8 = "0" +input_device_p9 = "0" +input_disk_eject_toggle_axis = "nul" +input_disk_eject_toggle_btn = "nul" +input_disk_eject_toggle_mbtn = "nul" +input_disk_eject_toggle = "nul" +input_disk_next_axis = "nul" +input_disk_next_btn = "nul" +input_disk_next_mbtn = "nul" +input_disk_next = "nul" +input_disk_prev_axis = "nul" +input_disk_prev_btn = "nul" +input_disk_prev_mbtn = "nul" +input_disk_prev = "nul" +input_driver = "udev" +input_duty_cycle = "3" +input_enable_hotkey_axis = "nul" +input_enable_hotkey_btn = "8" +input_enable_hotkey_mbtn = "nul" +input_enable_hotkey = "nul" +input_exit_emulator_axis = "nul" +input_exit_emulator_btn = "9" +input_exit_emulator = "escape" +input_exit_emulator_mbtn = "nul" +input_fps_toggle_axis = "nul" +input_fps_toggle_btn = "3" +input_fps_toggle = "f3" +input_fps_toggle_mbtn = "nul" +input_frame_advance_axis = "nul" +input_frame_advance_btn = "nul" +input_frame_advance = "k" +input_frame_advance_mbtn = "nul" +input_game_focus_toggle_axis = "nul" +input_game_focus_toggle_btn = "nul" +input_game_focus_toggle_mbtn = "nul" +input_game_focus_toggle = "scroll_lock" +input_grab_mouse_toggle_axis = "nul" +input_grab_mouse_toggle_btn = "nul" +input_grab_mouse_toggle = "f11" +input_grab_mouse_toggle_mbtn = "nul" +input_hold_fast_forward_axis = "nul" +input_hold_fast_forward_btn = "nul" +input_hold_fast_forward = "l" +input_hold_fast_forward_mbtn = "nul" +input_hold_slowmotion_axis = "nul" +input_hold_slowmotion_btn = "nul" +input_hold_slowmotion = "e" +input_hold_slowmotion_mbtn = "nul" +input_hotkey_block_delay = "5" +input_joypad_driver = "udev" +input_keyboard_layout = "" +input_libretro_device_p10 = "1" +input_libretro_device_p1 = "1" +input_libretro_device_p11 = "1" +input_libretro_device_p12 = "1" +input_libretro_device_p13 = "1" +input_libretro_device_p14 = "1" +input_libretro_device_p15 = "1" +input_libretro_device_p16 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_libretro_device_p6 = "1" +input_libretro_device_p7 = "1" +input_libretro_device_p8 = "1" +input_libretro_device_p9 = "1" +input_load_state_axis = "nul" +input_load_state_btn = "4" +input_load_state = "f4" +input_load_state_mbtn = "nul" +input_max_users = "5" +input_menu_toggle_axis = "nul" +input_menu_toggle_btn = "2" +input_menu_toggle = "f1" +input_menu_toggle_gamepad_combo = "9" +input_menu_toggle_mbtn = "nul" +input_movie_record_toggle_axis = "nul" +input_movie_record_toggle_btn = "nul" +input_movie_record_toggle_mbtn = "nul" +input_movie_record_toggle = "o" +input_netplay_game_watch_axis = "nul" +input_netplay_game_watch_btn = "nul" +input_netplay_game_watch = "i" +input_netplay_game_watch_mbtn = "nul" +input_netplay_host_toggle_axis = "nul" +input_netplay_host_toggle_btn = "nul" +input_netplay_host_toggle_mbtn = "nul" +input_netplay_host_toggle = "nul" +input_nowinkey_enable = "false" +input_osk_toggle_axis = "nul" +input_osk_toggle_btn = "nul" +input_osk_toggle = "f12" +input_osk_toggle_mbtn = "nul" +input_overlay = "" +input_overlay_aspect_adjust_landscape = "0.000000" +input_overlay_aspect_adjust_portrait = "0.000000" +input_overlay_auto_rotate = "false" +input_overlay_auto_scale = "false" +input_overlay_enable_autopreferred = "true" +input_overlay_enable = "false" +input_overlay_hide_in_menu = "true" +input_overlay_hide_when_gamepad_connected = "false" +input_overlay_next_axis = "nul" +input_overlay_next_btn = "nul" +input_overlay_next_mbtn = "nul" +input_overlay_next = "nul" +input_overlay_opacity = "0.700000" +input_overlay_scale_landscape = "1.000000" +input_overlay_scale_portrait = "1.000000" +input_overlay_show_inputs = "2" +input_overlay_show_inputs_port = "0" +input_overlay_show_mouse_cursor = "true" +input_overlay_x_offset_landscape = "0.000000" +input_overlay_x_offset_portrait = "0.000000" +input_overlay_x_separation_landscape = "0.000000" +input_overlay_x_separation_portrait = "0.000000" +input_overlay_y_offset_landscape = "0.000000" +input_overlay_y_offset_portrait = "0.000000" +input_overlay_y_separation_landscape = "0.000000" +input_overlay_y_separation_portrait = "0.000000" +input_pause_toggle_axis = "nul" +input_pause_toggle_btn = "nul" +input_pause_toggle_mbtn = "nul" +input_pause_toggle = "p" +input_poll_type_behavior = "2" +input_quit_gamepad_combo = "0" +input_recording_toggle_axis = "nul" +input_recording_toggle_btn = "nul" +input_recording_toggle_mbtn = "nul" +input_recording_toggle = "nul" +input_remap_binds_enable = "true" +input_remapping_directory = "~/remappings" +input_reset_axis = "nul" +input_reset_btn = "nul" +input_reset = "h" +input_reset_mbtn = "nul" +input_rewind_axis = "nul" +input_rewind_btn = "6" +input_rewind_mbtn = "nul" +input_rewind = "r" +input_rumble_gain = "100" +input_runahead_toggle_axis = "nul" +input_runahead_toggle_btn = "nul" +input_runahead_toggle_mbtn = "nul" +input_runahead_toggle = "nul" +input_save_state_axis = "nul" +input_save_state_btn = "5" +input_save_state = "f2" +input_save_state_mbtn = "nul" +input_screenshot_axis = "nul" +input_screenshot_btn = "nul" +input_screenshot = "f8" +input_screenshot_mbtn = "nul" +input_send_debug_info_axis = "nul" +input_send_debug_info_btn = "nul" +input_send_debug_info = "f10" +input_send_debug_info_mbtn = "nul" +input_sensors_enable = "true" +input_shader_next_axis = "nul" +input_shader_next_btn = "nul" +input_shader_next = "m" +input_shader_next_mbtn = "nul" +input_shader_prev_axis = "nul" +input_shader_prev_btn = "nul" +input_shader_prev_mbtn = "nul" +input_shader_prev = "n" +input_state_slot_decrease_axis = "nul" +input_state_slot_decrease_btn = "nul" +input_state_slot_decrease = "f6" +input_state_slot_decrease_mbtn = "nul" +input_state_slot_increase_axis = "nul" +input_state_slot_increase_btn = "nul" +input_state_slot_increase = "f7" +input_state_slot_increase_mbtn = "nul" +input_streaming_toggle_axis = "nul" +input_streaming_toggle_btn = "nul" +input_streaming_toggle_mbtn = "nul" +input_streaming_toggle = "nul" +input_toggle_fast_forward_axis = "nul" +input_toggle_fast_forward_btn = "7" +input_toggle_fast_forward_mbtn = "nul" +input_toggle_fast_forward = "space" +input_toggle_fullscreen_axis = "nul" +input_toggle_fullscreen_btn = "nul" +input_toggle_fullscreen = "f" +input_toggle_fullscreen_mbtn = "nul" +input_toggle_slowmotion_axis = "nul" +input_toggle_slowmotion_btn = "nul" +input_toggle_slowmotion_mbtn = "nul" +input_toggle_slowmotion = "nul" +input_touch_scale = "1" +input_turbo_default_button = "0" +input_turbo_mode = "0" +input_turbo_period = "6" +input_volume_down_axis = "nul" +input_volume_down_btn = "nul" +input_volume_down_mbtn = "nul" +input_volume_down = "subtract" +input_volume_up = "add" +input_volume_up_axis = "nul" +input_volume_up_btn = "nul" +input_volume_up_mbtn = "nul" +joypad_autoconfig_dir = "/tmp/joypads" +keyboard_gamepad_enable = "true" +keyboard_gamepad_mapping_type = "1" +kiosk_mode_enable = "false" +kiosk_mode_password = "" +led_driver = "null" +libretro_directory = "/tmp/cores" +libretro_info_path = "/tmp/cores" +libretro_log_level = "1" +load_dummy_on_core_shutdown = "true" +location_allow = "false" +location_driver = "null" +log_dir = "~/.config/retroarch/logs" +log_to_file = "false" +log_to_file_timestamp = "false" +log_verbosity = "true" +materialui_auto_rotate_nav_bar = "true" +materialui_dual_thumbnail_list_view_enable = "true" +materialui_icons_enable = "true" +materialui_landscape_layout_optimization = "1" +materialui_menu_color_theme = "9" +materialui_menu_transition_animation = "0" +materialui_playlist_icons_enable = "true" +materialui_show_nav_bar = "true" +materialui_thumbnail_background_enable = "true" +materialui_thumbnail_view_landscape = "2" +materialui_thumbnail_view_portrait = "1" +memory_show = "false" +memory_update_interval = "256" +menu_battery_level_enable = "true" +menu_core_enable = "true" +menu_driver = "xmb" +menu_dynamic_wallpaper_enable = "false" +menu_enable_widgets = "true" +menu_font_color_blue = "255" +menu_font_color_green = "255" +menu_font_color_red = "255" +menu_footer_opacity = "1.000000" +menu_framebuffer_opacity = "0.899999" +menu_header_opacity = "1.000000" +menu_horizontal_animation = "true" +menu_insert_disk_resume = "true" +menu_left_thumbnails = "0" +menu_linear_filter = "false" +menu_mouse_enable = "false" +menu_navigation_browser_filter_supported_extensions_enable = "true" +menu_navigation_wraparound_enable = "true" +menu_pause_libretro = "true" +menu_pointer_enable = "true" +menu_rgui_full_width_layout = "true" +menu_rgui_shadows = "false" +menu_rgui_transparency = "true" +menu_savestate_resume = "true" +menu_scale_factor = "0.350000" +menu_screensaver_animation = "0" +menu_screensaver_animation_speed = "1.000000" +menu_screensaver_timeout = "0" +menu_scroll_delay = "256" +menu_scroll_fast = "false" +menu_shader_pipeline = "2" +menu_show_advanced_settings = "true" +menu_show_configurations = "true" +menu_show_core_updater = "false" +menu_show_dump_disc = "true" +menu_show_help = "true" +menu_show_information = "true" +menu_show_latency = "true" +menu_show_legacy_thumbnail_updater = "false" +menu_show_load_content_animation = "false" +menu_show_load_content = "true" +menu_show_load_core = "true" +menu_show_load_disc = "true" +menu_show_online_updater = "true" +menu_show_overlays = "true" +menu_show_quit_retroarch = "true" +menu_show_reboot = "false" +menu_show_restart_retroarch = "true" +menu_show_rewind = "true" +menu_show_shutdown = "false" +menu_show_sublabels = "true" +menu_show_video_layout = "true" +menu_swap_ok_cancel_buttons = "false" +menu_throttle_framerate = "true" +menu_thumbnails = "3" +menu_thumbnail_upscale_threshold = "0" +menu_ticker_smooth = "true" +menu_ticker_speed = "2.000000" +menu_ticker_type = "1" +menu_timedate_date_separator = "0" +menu_timedate_enable = "true" +menu_timedate_style = "11" +menu_unified_controls = "false" +menu_use_preferred_system_color_theme = "false" +menu_wallpaper = "" +menu_wallpaper_opacity = "1.000000" +menu_widget_scale_auto = "false" +menu_widget_scale_factor = "0.350000" +menu_widget_scale_factor_windowed = "1.000000" +menu_xmb_animation_horizontal_highlight = "0" +menu_xmb_animation_move_up_down = "0" +menu_xmb_animation_opening_main_menu = "0" +menu_xmb_thumbnail_scale_factor = "100" +midi_driver = "alsa" +midi_input = "Off" +midi_output = "Off" +midi_volume = "100" +netplay_allow_slaves = "true" +netplay_check_frames = "600" +netplay_input_latency_frames_min = "0" +netplay_input_latency_frames_range = "0" +netplay_ip_address = "" +netplay_ip_port = "55435" +netplay_max_connections = "3" +netplay_mitm_server = "nyc" +netplay_nat_traversal = "true" +netplay_nickname = "" +netplay_password = "" +netplay_public_announce = "true" +netplay_request_device_p10 = "false" +netplay_request_device_p11 = "false" +netplay_request_device_p12 = "false" +netplay_request_device_p13 = "false" +netplay_request_device_p14 = "false" +netplay_request_device_p15 = "false" +netplay_request_device_p16 = "false" +netplay_request_device_p1 = "false" +netplay_request_device_p2 = "false" +netplay_request_device_p3 = "false" +netplay_request_device_p4 = "false" +netplay_request_device_p5 = "false" +netplay_request_device_p6 = "false" +netplay_request_device_p7 = "false" +netplay_request_device_p8 = "false" +netplay_request_device_p9 = "false" +netplay_require_slaves = "false" +netplay_share_analog = "1" +netplay_share_digital = "1" +netplay_spectate_password = "" +netplay_start_as_spectator = "false" +netplay_stateless_mode = "false" +netplay_use_mitm_server = "false" +network_cmd_enable = "false" +network_cmd_port = "55355" +network_on_demand_thumbnails = "false" +network_remote_base_port = "55400" +network_remote_enable = "false" +network_remote_enable_user_p10 = "false" +network_remote_enable_user_p11 = "false" +network_remote_enable_user_p12 = "false" +network_remote_enable_user_p13 = "false" +network_remote_enable_user_p14 = "false" +network_remote_enable_user_p15 = "false" +network_remote_enable_user_p16 = "false" +network_remote_enable_user_p1 = "false" +network_remote_enable_user_p2 = "false" +network_remote_enable_user_p3 = "false" +network_remote_enable_user_p4 = "false" +network_remote_enable_user_p5 = "false" +network_remote_enable_user_p6 = "false" +network_remote_enable_user_p7 = "false" +network_remote_enable_user_p8 = "false" +network_remote_enable_user_p9 = "false" +notification_show_autoconfig = "false" +notification_show_cheats_applied = "true" +notification_show_config_override_load = "false" +notification_show_fast_forward = "true" +notification_show_netplay_extra = "false" +notification_show_patch_applied = "true" +notification_show_refresh_rate = "true" +notification_show_remap_load = "false" +notification_show_screenshot_duration = "2" +notification_show_screenshot = "false" +notification_show_screenshot_flash = "1" +notification_show_set_initial_disk = "true" +overlay_directory = "/tmp/overlays" +ozone_collapse_sidebar = "false" +ozone_menu_color_theme = "1" +ozone_scroll_content_metadata = "false" +ozone_sort_after_truncate_playlist_name = "true" +ozone_truncate_playlist_name = "true" +pause_nonactive = "true" +perfcnt_enable = "false" +playlist_compression = "false" +playlist_cores = "" +playlist_directory = "~/playlists" +playlist_entry_remove_enable = "1" +playlist_entry_remove = "false" +playlist_entry_rename = "false" +playlist_fuzzy_archive_match = "false" +playlist_names = "" +playlist_portable_paths = "false" +playlist_show_entry_idx = "true" +playlist_show_inline_core_name = "0" +playlist_show_sublabels = "true" +playlist_sort_alphabetical = "true" +playlist_sublabel_last_played_style = "0" +playlist_sublabel_runtime_type = "0" +playlist_use_old_format = "false" +quick_menu_show_add_to_favorites = "true" +quick_menu_show_cheats = "true" +quick_menu_show_close_content = "true" +quick_menu_show_controls = "true" +quick_menu_show_core_options_flush = "false" +quick_menu_show_download_thumbnails = "true" +quick_menu_show_information = "true" +quick_menu_show_options = "true" +quick_menu_show_recording = "true" +quick_menu_show_reset_core_association = "true" +quick_menu_show_restart_content = "true" +quick_menu_show_resume_content = "true" +quick_menu_show_save_content_dir_overrides = "true" +quick_menu_show_save_core_overrides = "false" +quick_menu_show_save_game_overrides = "false" +quick_menu_show_save_load_state = "true" +quick_menu_show_set_core_association = "true" +quick_menu_show_shaders = "true" +quick_menu_show_start_recording = "true" +quick_menu_show_start_streaming = "true" +quick_menu_show_streaming = "true" +quick_menu_show_take_screenshot = "true" +quick_menu_show_undo_save_load_state = "false" +quit_on_close_content = "0" +quit_press_twice = "true" +record_driver = "null" +recording_config_directory = "" +recording_output_directory = "~/roms/screenshots" +resampler_directory = "" +rewind_buffer_size = "20971520" +rewind_buffer_size_step = "10" +rewind_enable = "false" +rewind_granularity = "1" +rgui_aspect_ratio = "0" +rgui_aspect_ratio_lock = "0" +rgui_background_filler_thickness_enable = "true" +rgui_border_filler_enable = "true" +rgui_border_filler_thickness_enable = "true" +rgui_browser_directory = "~/roms" +rgui_config_directory = "~/.config/retroarch/config" +rgui_extended_ascii = "false" +rgui_inline_thumbnails = "false" +rgui_internal_upscale_level = "0" +rgui_menu_color_theme = "4" +rgui_menu_theme_preset = "" +rgui_particle_effect = "0" +rgui_particle_effect_screensaver = "true" +rgui_particle_effect_speed = "1.000000" +rgui_show_start_screen = "false" +rgui_swap_thumbnails = "false" +rgui_switch_icons = "true" +rgui_thumbnail_delay = "0" +rgui_thumbnail_downscaler = "0" +run_ahead_enabled = "false" +run_ahead_frames = "1" +run_ahead_hide_warnings = "false" +run_ahead_secondary_instance = "true" +runtime_log_directory = "default" +save_file_compression = "false" +savefile_directory = "~/.config/retroarch/saves" +savefiles_in_content_dir = "true" +savestate_auto_index = "false" +savestate_auto_load = "false" +savestate_auto_save = "false" +savestate_directory = "~/.config/retroarch/states" +savestate_file_compression = "true" +savestate_max_keep = "0" +savestates_in_content_dir = "false" +savestate_thumbnail_enable = "true" +scan_without_core_match = "false" +screen_brightness = "100" +screen_orientation = "0" +screenshot_directory = "~/roms/screenshots" +screenshots_in_content_dir = "false" +settings_show_accessibility = "true" +settings_show_achievements = "true" +settings_show_ai_service = "true" +settings_show_audio = "true" +settings_show_configuration = "true" +settings_show_core = "true" +settings_show_directory = "true" +settings_show_drivers = "true" +settings_show_file_browser = "true" +settings_show_frame_throttle = "true" +settings_show_input = "true" +settings_show_latency = "true" +settings_show_logging = "true" +settings_show_network = "true" +settings_show_onscreen_display = "true" +settings_show_playlists = "true" +settings_show_power_management = "true" +settings_show_recording = "true" +settings_show_saving = "true" +settings_show_user_interface = "true" +settings_show_user = "true" +settings_show_video = "true" +show_hidden_files = "false" +slowmotion_ratio = "3.000000" +soft_filter_enable = "false" +soft_filter_index = "0" +sort_savefiles_by_content_enable = "false" +sort_savefiles_enable = "false" +sort_savestates_by_content_enable = "false" +sort_savestates_enable = "false" +sort_screenshots_by_content_enable = "false" +state_slot = "0" +statistics_show = "false" +stdin_cmd_enable = "false" +streaming_mode = "0" +suspend_screensaver_enable = "true" +sustained_performance_mode = "false" +system_directory = "~/roms/bios" +systemfiles_in_content_dir = "false" +threaded_data_runloop_enable = "true" +thumbnails_directory = "~/thumbnails" +twitch_stream_key = "" +ui_companion_enable = "false" +ui_companion_start_on_boot = "true" +ui_companion_toggle = "false" +ui_menubar_enable = "true" +use_last_start_directory = "false" +user_language = "0" +vibrate_on_keypress = "true" +video_adaptive_vsync = "false" +video_allow_rotate = "true" +video_aspect_ratio = "-1.000000" +video_aspect_ratio_auto = "true" +video_black_frame_insertion = "0" +video_context_driver = "" +video_crop_overscan = "true" +video_ctx_scaling = "false" +video_disable_composition = "false" +video_driver = "gl" +video_filter = "" +video_filter_dir = "~/.config/retroarch/filters/video" +video_font_enable = "true" +video_font_path = "/usr/share/retroarch-assets/xmb/monochrome/font.ttf" +video_font_size = "32.000000" +video_force_aspect = "true" +video_force_srgb_disable = "false" +video_frame_delay = "0" +video_frame_delay_auto = "false" +video_fullscreen = "true" +video_fullscreen_x = "0" +video_fullscreen_y = "0" +video_gpu_record = "false" +video_gpu_screenshot = "false" +video_hard_sync = "false" +video_hard_sync_frames = "0" +video_hdr_display_contrast = "5.000000" +video_hdr_enable = "false" +video_hdr_expand_gamut = "true" +video_hdr_max_nits = "1000.000000" +video_hdr_paper_white_nits = "200.000000" +video_layout_directory = "~/.config/retroarch/layouts" +video_layout_enable = "true" +video_layout_path = "" +video_layout_selected_view = "0" +video_max_swapchain_images = "3" +video_message_color = "ffff00" +video_message_pos_x = "0.049999" +video_message_pos_y = "0.049999" +video_monitor_index = "0" +video_msg_bgcolor_blue = "0" +video_msg_bgcolor_enable = "false" +video_msg_bgcolor_green = "0" +video_msg_bgcolor_opacity = "1.000000" +video_msg_bgcolor_red = "0" +video_notch_write_over_enable = "false" +video_oga_vertical_enable = "false" +video_post_filter_record = "false" +video_record_config = "" +video_record_quality = "4" +video_record_scale_factor = "1" +video_record_threads = "2" +video_refresh_rate = "60.000000" +video_rotation = "0" +video_scale = "3.000000" +video_scale_integer = "false" +video_scale_integer_overscale = "false" +video_shader_delay = "0" +video_shader_dir = "/tmp/shaders" +video_shader_enable = "false" +video_shader_preset_save_reference_enable = "true" +video_shader_remember_last_dir = "false" +video_shader_watch_files = "false" +video_shared_context = "false" +video_smooth = "false" +video_stream_config = "" +video_stream_port = "56400" +video_stream_quality = "10" +video_stream_scale_factor = "1" +video_stream_url = "" +video_swap_interval = "1" +video_threaded = "true" +video_vsync = "true" +video_window_auto_height_max = "1080" +video_window_auto_width_max = "1920" +video_window_custom_size_enable = "false" +video_windowed_fullscreen = "false" +video_windowed_position_height = "720" +video_windowed_position_width = "1280" +video_windowed_position_x = "0" +video_windowed_position_y = "0" +video_window_opacity = "100" +video_window_save_positions = "false" +video_window_show_decorations = "true" +vrr_runloop_enable = "false" +wifi_driver = "null" +wifi_enabled = "true" +xmb_alpha_factor = "75" +xmb_font = "/usr/share/retroarch-assets/xmb/monochrome/font.ttf" +xmb_layout = "2" +xmb_menu_color_theme = "4" +xmb_shadows_enable = "true" +xmb_theme = "0" +xmb_vertical_thumbnails = "false" +youtube_stream_key = "" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3566/retroarch32bit-append.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3566/retroarch32bit-append.cfg new file mode 100644 index 0000000000..343124c254 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3566/retroarch32bit-append.cfg @@ -0,0 +1,3 @@ +audio_filter_dir = "/usr/share/retroarch/filters/32bit/audio" +video_filter_dir = "/usr/share/retroarch/filters/32bit/video" +libretro_directory = /usr/lib32/libretro diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3566/retroarch64bit-append.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3566/retroarch64bit-append.cfg new file mode 100644 index 0000000000..b6cbf68312 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3566/retroarch64bit-append.cfg @@ -0,0 +1,2 @@ +audio_filter_dir = "/usr/share/retroarch/filters/64bit/audio" +video_filter_dir = "/usr/share/retroarch/filters/64bit/video" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3588/TATE-MAME 2003-Plus.rmp b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3588/TATE-MAME 2003-Plus.rmp new file mode 100755 index 0000000000..366e47afad --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3588/TATE-MAME 2003-Plus.rmp @@ -0,0 +1,27 @@ +input_libretro_device_p1 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_player1_analog_dpad_mode = "1" +input_player1_btn_down = "6" +input_player1_btn_left = "4" +input_player1_btn_right = "5" +input_player1_btn_up = "7" +input_player1_stk_l_x+ = "5" +input_player1_stk_l_x- = "4" +input_player1_stk_l_y+ = "6" +input_player1_stk_l_y- = "7" +input_player1_stk_r_x+ = "5" +input_player1_stk_r_x- = "4" +input_player1_stk_r_y+ = "6" +input_player1_stk_r_y- = "7" +input_player2_analog_dpad_mode = "0" +input_player3_analog_dpad_mode = "0" +input_player4_analog_dpad_mode = "0" +input_player5_analog_dpad_mode = "0" +input_remap_port_p1 = "0" +input_remap_port_p2 = "1" +input_remap_port_p3 = "2" +input_remap_port_p4 = "3" +input_remap_port_p5 = "4" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3588/retroarch-core-options.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3588/retroarch-core-options.cfg new file mode 100755 index 0000000000..0bcbaa2661 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3588/retroarch-core-options.cfg @@ -0,0 +1,152 @@ +mupen64plus-alt-map = "False" +mupen64plus-aspect = "4:3" +mupen64plus-astick-deadzone = "15" +mupen64plus-astick-sensitivity = "100" +mupen64plus-BackgroundMode = "Stripped" +mupen64plus-BilinearMode = "standard" +mupen64plus-CorrectTexrectCoords = "Auto" +mupen64plus-CountPerOp = "0" +mupen64plus-CountPerOpDenomPot = "0" +mupen64plus-cpucore = "dynamic_recompiler" +mupen64plus-d-cbutton = "C3" +mupen64plus-DitheringPattern = "True" +mupen64plus-DitheringQuantization = "True" +mupen64plus-EnableCopyAuxToRDRAM = "True" +mupen64plus-EnableCopyColorToRDRAM = "Async" +mupen64plus-EnableCopyDepthToRDRAM = "Software" +mupen64plus-EnableEnhancedHighResStorage = "False" +mupen64plus-EnableEnhancedTextureStorage = "False" +mupen64plus-EnableFBEmulation = "True" +mupen64plus-EnableFragmentDepthWrite = "False" +mupen64plus-EnableHiResAltCRC = "False" +mupen64plus-EnableHWLighting = "True" +mupen64plus-EnableInaccurateTextureCoordinates = "False" +mupen64plus-EnableLegacyBlending = "False" +mupen64plus-EnableLODEmulation = "True" +mupen64plus-EnableNativeResFactor = "1" +mupen64plus-EnableNativeResTexrects = "Optimized" +mupen64plus-EnableOverscan = "Enabled" +mupen64plus-EnableTexCoordBounds = "False" +mupen64plus-EnableTextureCache = "True" +mupen64plus-ForceDisableExtraMem = "False" +mupen64plus-FrameDuping = "True" +mupen64plus-Framerate = "Original" +mupen64plus-FXAA = "0" +mupen64plus-GLideN64IniBehaviour = "late" +mupen64plus-HybridFilter = "True" +mupen64plus-IgnoreTLBExceptions = "False" +mupen64plus-l-cbutton = "C2" +mupen64plus-MaxHiResTxVramLimit = "0" +mupen64plus-MaxTxCacheSize = "8000" +mupen64plus-MultiSampling = "0" +mupen64plus-OverscanBottom = "0" +mupen64plus-OverscanLeft = "0" +mupen64plus-OverscanRight = "0" +mupen64plus-OverscanTop = "0" +mupen64plus-pak1 = "memory" +mupen64plus-pak2 = "none" +mupen64plus-pak3 = "none" +mupen64plus-pak4 = "none" +mupen64plus-r-cbutton = "C1" +mupen64plus-rdp-plugin = "gliden64" +mupen64plus-RDRAMImageDitheringMode = "BlueNoise" +mupen64plus-rsp-plugin = "hle" +mupen64plus-ThreadedRenderer = "True" +mupen64plus-txCacheCompression = "True" +mupen64plus-txEnhancementMode = "None" +mupen64plus-txFilterIgnoreBG = "True" +mupen64plus-txFilterMode = "None" +mupen64plus-txHiresEnable = "False" +mupen64plus-txHiresFullAlphaChannel = "False" +mupen64plus-u-cbutton = "C4" +mupen64plus-virefresh = "Auto" +pcsx_rearmed_analog_axis_modifier = "circle" +pcsx_rearmed_async_cd = "sync" +pcsx_rearmed_bios = "auto" +pcsx_rearmed_display_internal_fps = "disabled" +pcsx_rearmed_dithering = "enabled" +pcsx_rearmed_drc = "enabled" +pcsx_rearmed_duping_enable = "enabled" +pcsx_rearmed_frameskip_type = "disabled" +pcsx_rearmed_gteregsunneeded = "disabled" +pcsx_rearmed_gunconadjustratiox = "1" +pcsx_rearmed_gunconadjustratioy = "1" +pcsx_rearmed_gunconadjustx = "0" +pcsx_rearmed_gunconadjusty = "0" +pcsx_rearmed_idiablofix = "disabled" +pcsx_rearmed_input_sensitivity = "1.00" +pcsx_rearmed_inuyasha_fix = "disabled" +pcsx_rearmed_memcard2 = "disabled" +pcsx_rearmed_multitap1 = "auto" +pcsx_rearmed_multitap2 = "auto" +pcsx_rearmed_negcon_deadzone = "0" +pcsx_rearmed_negcon_response = "linear" +pcsx_rearmed_neon_enhancement_enable = "disabled" +pcsx_rearmed_neon_enhancement_no_main = "disabled" +pcsx_rearmed_neon_interlace_enable = "disabled" +pcsx_rearmed_nocdaudio = "enabled" +pcsx_rearmed_nogteflags = "disabled" +pcsx_rearmed_nosmccheck = "disabled" +pcsx_rearmed_noxadecoding = "enabled" +pcsx_rearmed_pad1type = "standard" +pcsx_rearmed_pad2type = "standard" +pcsx_rearmed_pad3type = "none" +pcsx_rearmed_pad4type = "none" +pcsx_rearmed_pad5type = "none" +pcsx_rearmed_pad6type = "none" +pcsx_rearmed_pad7type = "none" +pcsx_rearmed_pad8type = "none" +pcsx_rearmed_pe2_fix = "disabled" +pcsx_rearmed_psxclock = "57" +pcsx_rearmed_region = "auto" +pcsx_rearmed_show_bios_bootlogo = "disabled" +pcsx_rearmed_show_other_input_settings = "disabled" +pcsx_rearmed_spu_interpolation = "simple" +pcsx_rearmed_spu_reverb = "enabled" +pcsx_rearmed_spuirq = "disabled" +pcsx_rearmed_vibration = "enabled" +gambatte_gb_colorization = "disabled" +gambatte_gb_internal_palette = "" +mame2003-plus_analog = "digital" +mame2003-plus_art_resolution = "1" +mame2003-plus_brightness = "1.0" +mame2003-plus_cheat_input_ports = "disabled" +mame2003-plus_core_save_subfolder = "enabled" +mame2003-plus_core_sys_subfolder = "enabled" +mame2003-plus_dcs_speedhack = "enabled" +mame2003-plus_deadzone = "20" +mame2003-plus_digital_joy_centering = "enabled" +mame2003-plus_display_artwork = "enabled" +mame2003-plus_display_setup = "disabled" +mame2003-plus_four_way_emulation = "disabled" +mame2003-plus_frameskip = "0" +mame2003-plus_gamma = "1.0" +mame2003-plus_input_interface = "retropad" +mame2003-plus_machine_timing = "enabled" +mame2003-plus_mame_remapping = "enabled" +mame2003-plus_mouse_device = "mouse" +mame2003-plus_sample_rate = "48000" +mame2003-plus_skip_disclaimer = "disabled" +mame2003-plus_skip_warnings = "disabled" +flycast_internal_resolution = "640x480" +flycast_alpha_sorting = "per-strip (fast, least accurate)" +flycast_enable_dsp = "disabled" +flycast_threaded_rendering = "enabled" +flycast_anisotropic_filtering = "off" +flycast_synchronous_rendering = "enabled" +flycast_enable_rtt = "disabled" +flycast_enable_rttb = "disabled" +flycast_delay_frame_swapping = "disabled" +flycast_div_matching = "auto" +flycast_texupscale = "off" +flycast_auto_skip_frame = "normal" +opera_swi_hle = "enabled" +opera_dsp_threaded = "enabled" +opera_madam_matrix_engine = "software" +puae_deadzone = "25" +melonds_screen_layout = "Left/Right" +melonds_swapscreen_mode = "Toggle" +melonds_threaded_renderer = "enabled" +melonds_touch_mode = "Joystick" +virtualjaguar_bios = "enabled" +virtualjaguar_usefastblitter = "enabled" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3588/retroarch.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3588/retroarch.cfg new file mode 100755 index 0000000000..46991fdc90 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3588/retroarch.cfg @@ -0,0 +1,822 @@ +accessibility_enable = "false" +accessibility_narrator_speech_speed = "5" +ai_service_enable = "true" +ai_service_mode = "1" +ai_service_pause = "false" +ai_service_source_lang = "0" +ai_service_target_lang = "0" +ai_service_url = "http://localhost:4404/" +all_users_control_menu = "true" +apply_cheats_after_load = "false" +apply_cheats_after_toggle = "false" +aspect_ratio_index = "22" +assets_directory = "/tmp/assets" +audio_block_frames = "0" +audio_device = "" +audio_driver = "alsathread" +audio_dsp_plugin = "" +audio_enable_menu_bgm = "false" +audio_enable_menu_cancel = "false" +audio_enable_menu = "false" +audio_enable_menu_notice = "false" +audio_enable_menu_ok = "false" +audio_enable = "true" +audio_fastforward_mute = "false" +audio_filter_dir = "~/.config/retroarch/filters/audio" +audio_latency = "32" +audio_max_timing_skew = "0.049999" +audio_mixer_mute_enable = "false" +audio_mixer_volume = "0.000000" +audio_mute_enable = "false" +audio_out_rate = "48000" +audio_rate_control_delta = "0.004999" +audio_rate_control = "true" +audio_resampler_quality = "2" +audio_resampler = "sinc" +audio_sync = "true" +audio_volume = "0.000000" +auto_overrides_enable = "true" +auto_remaps_enable = "true" +autosave_interval = "10" +auto_screenshot_filename = "true" +auto_shaders_enable = "true" +block_sram_overwrite = "false" +bluetooth_driver = "null" +builtin_imageviewer_enable = "false" +builtin_mediaplayer_enable = "true" +bundle_assets_dst_path = "" +bundle_assets_dst_path_subdir = "" +bundle_assets_extract_enable = "false" +bundle_assets_extract_last_version = "0" +bundle_assets_extract_version_current = "0" +bundle_assets_src_path = "" +cache_directory = "/tmp/cache" +camera_allow = "false" +camera_device = "" +camera_driver = "null" +cheat_database_path = "/tmp/database/cht" +check_firmware_before_loading = "false" +cheevos_auto_screenshot = "false" +cheevos_badges_enable = "false" +cheevos_challenge_indicators = "true" +cheevos_enable = "false" +cheevos_hardcore_mode_enable = "false" +cheevos_leaderboards_enable = "" +cheevos_password = "" +cheevos_richpresence_enable = "true" +cheevos_start_active = "false" +cheevos_test_unofficial = "false" +cheevos_token = "" +cheevos_unlock_sound_enable = "false" +cheevos_username = "" +cheevos_verbose_enable = "false" +config_save_on_exit = "false" +content_database_path = "/tmp/database/rdb" +content_favorites_directory = "default" +content_favorites_path = "~/.config/retroarch/content_favorites.lpl" +content_favorites_size = "200" +content_history_dir = "" +content_history_directory = "default" +content_history_path = "~/.config/retroarch/content_history.lpl" +content_history_size = "200" +content_image_history_directory = "default" +content_image_history_path = "~/.config/retroarch/content_image_history.lpl" +content_music_history_directory = "default" +content_music_history_path = "~/.config/retroarch/content_music_history.lpl" +content_runtime_log_aggregate = "false" +content_runtime_log = "true" +content_show_add_entry = "2" +content_show_add = "true" +content_show_explore = "true" +content_show_favorites = "true" +content_show_history = "true" +content_show_images = "false" +content_show_music = "false" +content_show_netplay = "true" +content_show_playlists = "true" +content_show_settings_password = "" +content_show_settings = "true" +content_show_video = "false" +content_video_directory = "default" +content_video_history_path = "~/.config/retroarch/content_video_history.lpl" +core_assets_directory = "~/roms/downloads" +core_info_cache_enable = "true" +core_option_category_enable = "true" +core_options_path = "" +core_set_supports_no_game_enable = "true" +core_updater_auto_backup = "false" +core_updater_auto_backup_history_size = "1" +core_updater_auto_extract_archive = "true" +core_updater_buildbot_assets_url = "http://buildbot.libretro.com/assets/" +core_updater_buildbot_cores_url = "" +core_updater_buildbot_url = "http://buildbot.libretro.com/nightly/linux/armhf/latest/" +core_updater_show_experimental_cores = "false" +cpu_main_gov = "performance" +cpu_max_freq = "-1" +cpu_menu_gov = "interactive" +cpu_min_freq = "1" +cpu_scaling_mode = "0" +crt_switch_center_adjust = "0" +crt_switch_hires_menu = "false" +crt_switch_porch_adjust = "0" +crt_switch_resolution = "0" +crt_switch_resolution_super = "2560" +crt_switch_resolution_use_custom_refresh_rate = "false" +crt_switch_timings = "" +crt_video_refresh_rate = "60.000000" +current_resolution_id = "0" +cursor_directory = "~/.config/retroarch/database/cursors" +desktop_menu_enable = "true" +discord_allow = "false" +discord_app_id = "475456035851599874" +driver_switch_enable = "true" +dynamic_wallpapers_directory = "default" +emuelec_exit_to_kodi = "false" +enable_device_vibration = "true" +facebook_stream_key = "" +fastforward_ratio = "0.000000" +filter_by_current_core = "false" +flicker_filter_enable = "false" +flicker_filter_index = "0" +fps_show = "false" +fps_update_interval = "256" +framecount_show = "false" +frame_time_counter_reset_after_fastforwarding = "false" +frame_time_counter_reset_after_load_state = "false" +frame_time_counter_reset_after_save_state = "false" +frontend_log_level = "1" +game_specific_options = "true" +gamma_correction = "0" +global_core_options = "false" +history_list_enable = "true" +input_ai_service_axis = "nul" +input_ai_service_btn = "nul" +input_ai_service_mbtn = "nul" +input_ai_service = "nul" +input_analog_deadzone = "0.000000" +input_analog_sensitivity = "1.500000" +input_audio_mute_axis = "nul" +input_audio_mute_btn = "nul" +input_audio_mute = "f9" +input_audio_mute_mbtn = "nul" +input_autodetect_enable = "true" +input_auto_game_focus = "0" +input_auto_mouse_grab = "false" +input_axis_threshold = "0.500000" +input_bind_hold = "2" +input_bind_timeout = "5" +input_cheat_index_minus_axis = "nul" +input_cheat_index_minus_btn = "nul" +input_cheat_index_minus_mbtn = "nul" +input_cheat_index_minus = "t" +input_cheat_index_plus_axis = "nul" +input_cheat_index_plus_btn = "nul" +input_cheat_index_plus_mbtn = "nul" +input_cheat_index_plus = "y" +input_cheat_toggle_axis = "nul" +input_cheat_toggle_btn = "nul" +input_cheat_toggle_mbtn = "nul" +input_cheat_toggle = "u" +input_close_content_axis = "nul" +input_close_content_btn = "nul" +input_close_content_mbtn = "nul" +input_close_content = "nul" +input_descriptor_hide_unbound = "false" +input_descriptor_label_show = "true" +input_desktop_menu_toggle_axis = "nul" +input_desktop_menu_toggle_btn = "nul" +input_desktop_menu_toggle = "f5" +input_desktop_menu_toggle_mbtn = "nul" +input_device_p1 = "0" +input_device_p10 = "0" +input_device_p11 = "0" +input_device_p12 = "0" +input_device_p13 = "0" +input_device_p14 = "0" +input_device_p15 = "0" +input_device_p16 = "0" +input_device_p2 = "0" +input_device_p3 = "0" +input_device_p4 = "0" +input_device_p5 = "0" +input_device_p6 = "0" +input_device_p7 = "0" +input_device_p8 = "0" +input_device_p9 = "0" +input_disk_eject_toggle_axis = "nul" +input_disk_eject_toggle_btn = "nul" +input_disk_eject_toggle_mbtn = "nul" +input_disk_eject_toggle = "nul" +input_disk_next_axis = "nul" +input_disk_next_btn = "nul" +input_disk_next_mbtn = "nul" +input_disk_next = "nul" +input_disk_prev_axis = "nul" +input_disk_prev_btn = "nul" +input_disk_prev_mbtn = "nul" +input_disk_prev = "nul" +input_driver = "udev" +input_duty_cycle = "3" +input_enable_hotkey_axis = "nul" +input_enable_hotkey_btn = "8" +input_enable_hotkey_mbtn = "nul" +input_enable_hotkey = "nul" +input_exit_emulator_axis = "nul" +input_exit_emulator_btn = "9" +input_exit_emulator = "escape" +input_exit_emulator_mbtn = "nul" +input_fps_toggle_axis = "nul" +input_fps_toggle_btn = "3" +input_fps_toggle = "f3" +input_fps_toggle_mbtn = "nul" +input_frame_advance_axis = "nul" +input_frame_advance_btn = "nul" +input_frame_advance = "k" +input_frame_advance_mbtn = "nul" +input_game_focus_toggle_axis = "nul" +input_game_focus_toggle_btn = "nul" +input_game_focus_toggle_mbtn = "nul" +input_game_focus_toggle = "scroll_lock" +input_grab_mouse_toggle_axis = "nul" +input_grab_mouse_toggle_btn = "nul" +input_grab_mouse_toggle = "f11" +input_grab_mouse_toggle_mbtn = "nul" +input_hold_fast_forward_axis = "nul" +input_hold_fast_forward_btn = "nul" +input_hold_fast_forward = "l" +input_hold_fast_forward_mbtn = "nul" +input_hold_slowmotion_axis = "nul" +input_hold_slowmotion_btn = "nul" +input_hold_slowmotion = "e" +input_hold_slowmotion_mbtn = "nul" +input_hotkey_block_delay = "5" +input_joypad_driver = "udev" +input_keyboard_layout = "" +input_libretro_device_p10 = "1" +input_libretro_device_p1 = "1" +input_libretro_device_p11 = "1" +input_libretro_device_p12 = "1" +input_libretro_device_p13 = "1" +input_libretro_device_p14 = "1" +input_libretro_device_p15 = "1" +input_libretro_device_p16 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_libretro_device_p6 = "1" +input_libretro_device_p7 = "1" +input_libretro_device_p8 = "1" +input_libretro_device_p9 = "1" +input_load_state_axis = "nul" +input_load_state_btn = "4" +input_load_state = "f4" +input_load_state_mbtn = "nul" +input_max_users = "5" +input_menu_toggle_axis = "nul" +input_menu_toggle_btn = "2" +input_menu_toggle = "f1" +input_menu_toggle_gamepad_combo = "2" +input_menu_toggle_mbtn = "nul" +input_movie_record_toggle_axis = "nul" +input_movie_record_toggle_btn = "nul" +input_movie_record_toggle_mbtn = "nul" +input_movie_record_toggle = "o" +input_netplay_game_watch_axis = "nul" +input_netplay_game_watch_btn = "nul" +input_netplay_game_watch = "i" +input_netplay_game_watch_mbtn = "nul" +input_netplay_host_toggle_axis = "nul" +input_netplay_host_toggle_btn = "nul" +input_netplay_host_toggle_mbtn = "nul" +input_netplay_host_toggle = "nul" +input_nowinkey_enable = "false" +input_osk_toggle_axis = "nul" +input_osk_toggle_btn = "nul" +input_osk_toggle = "f12" +input_osk_toggle_mbtn = "nul" +input_overlay = "" +input_overlay_aspect_adjust_landscape = "0.000000" +input_overlay_aspect_adjust_portrait = "0.000000" +input_overlay_auto_rotate = "false" +input_overlay_auto_scale = "false" +input_overlay_enable_autopreferred = "true" +input_overlay_enable = "false" +input_overlay_hide_in_menu = "true" +input_overlay_hide_when_gamepad_connected = "false" +input_overlay_next_axis = "nul" +input_overlay_next_btn = "nul" +input_overlay_next_mbtn = "nul" +input_overlay_next = "nul" +input_overlay_opacity = "0.700000" +input_overlay_scale_landscape = "1.000000" +input_overlay_scale_portrait = "1.000000" +input_overlay_show_inputs = "2" +input_overlay_show_inputs_port = "0" +input_overlay_show_mouse_cursor = "true" +input_overlay_x_offset_landscape = "0.000000" +input_overlay_x_offset_portrait = "0.000000" +input_overlay_x_separation_landscape = "0.000000" +input_overlay_x_separation_portrait = "0.000000" +input_overlay_y_offset_landscape = "0.000000" +input_overlay_y_offset_portrait = "0.000000" +input_overlay_y_separation_landscape = "0.000000" +input_overlay_y_separation_portrait = "0.000000" +input_pause_toggle_axis = "nul" +input_pause_toggle_btn = "nul" +input_pause_toggle_mbtn = "nul" +input_pause_toggle = "p" +input_poll_type_behavior = "2" +input_quit_gamepad_combo = "0" +input_recording_toggle_axis = "nul" +input_recording_toggle_btn = "nul" +input_recording_toggle_mbtn = "nul" +input_recording_toggle = "nul" +input_remap_binds_enable = "true" +input_remapping_directory = "~/remappings" +input_reset_axis = "nul" +input_reset_btn = "nul" +input_reset = "h" +input_reset_mbtn = "nul" +input_rewind_axis = "nul" +input_rewind_btn = "6" +input_rewind_mbtn = "nul" +input_rewind = "r" +input_rumble_gain = "100" +input_runahead_toggle_axis = "nul" +input_runahead_toggle_btn = "nul" +input_runahead_toggle_mbtn = "nul" +input_runahead_toggle = "nul" +input_save_state_axis = "nul" +input_save_state_btn = "5" +input_save_state = "f2" +input_save_state_mbtn = "nul" +input_screenshot_axis = "nul" +input_screenshot_btn = "nul" +input_screenshot = "f8" +input_screenshot_mbtn = "nul" +input_send_debug_info_axis = "nul" +input_send_debug_info_btn = "nul" +input_send_debug_info = "f10" +input_send_debug_info_mbtn = "nul" +input_sensors_enable = "true" +input_shader_next_axis = "nul" +input_shader_next_btn = "nul" +input_shader_next = "m" +input_shader_next_mbtn = "nul" +input_shader_prev_axis = "nul" +input_shader_prev_btn = "nul" +input_shader_prev_mbtn = "nul" +input_shader_prev = "n" +input_state_slot_decrease_axis = "nul" +input_state_slot_decrease_btn = "nul" +input_state_slot_decrease = "f6" +input_state_slot_decrease_mbtn = "nul" +input_state_slot_increase_axis = "nul" +input_state_slot_increase_btn = "nul" +input_state_slot_increase = "f7" +input_state_slot_increase_mbtn = "nul" +input_streaming_toggle_axis = "nul" +input_streaming_toggle_btn = "nul" +input_streaming_toggle_mbtn = "nul" +input_streaming_toggle = "nul" +input_toggle_fast_forward_axis = "nul" +input_toggle_fast_forward_btn = "7" +input_toggle_fast_forward_mbtn = "nul" +input_toggle_fast_forward = "space" +input_toggle_fullscreen_axis = "nul" +input_toggle_fullscreen_btn = "nul" +input_toggle_fullscreen = "f" +input_toggle_fullscreen_mbtn = "nul" +input_toggle_slowmotion_axis = "nul" +input_toggle_slowmotion_btn = "nul" +input_toggle_slowmotion_mbtn = "nul" +input_toggle_slowmotion = "nul" +input_touch_scale = "1" +input_turbo_default_button = "0" +input_turbo_mode = "0" +input_turbo_period = "6" +input_volume_down_axis = "nul" +input_volume_down_btn = "nul" +input_volume_down_mbtn = "nul" +input_volume_down = "subtract" +input_volume_up = "add" +input_volume_up_axis = "nul" +input_volume_up_btn = "nul" +input_volume_up_mbtn = "nul" +joypad_autoconfig_dir = "/tmp/joypads" +keyboard_gamepad_enable = "true" +keyboard_gamepad_mapping_type = "1" +kiosk_mode_enable = "false" +kiosk_mode_password = "" +led_driver = "null" +libretro_directory = "/tmp/cores" +libretro_info_path = "/tmp/cores" +libretro_log_level = "1" +load_dummy_on_core_shutdown = "true" +location_allow = "false" +location_driver = "null" +log_dir = "~/.config/retroarch/logs" +log_to_file = "false" +log_to_file_timestamp = "false" +log_verbosity = "true" +materialui_auto_rotate_nav_bar = "true" +materialui_dual_thumbnail_list_view_enable = "true" +materialui_icons_enable = "true" +materialui_landscape_layout_optimization = "1" +materialui_menu_color_theme = "9" +materialui_menu_transition_animation = "0" +materialui_playlist_icons_enable = "true" +materialui_show_nav_bar = "true" +materialui_thumbnail_background_enable = "true" +materialui_thumbnail_view_landscape = "2" +materialui_thumbnail_view_portrait = "1" +memory_show = "false" +memory_update_interval = "256" +menu_battery_level_enable = "true" +menu_core_enable = "true" +menu_driver = "xmb" +menu_dynamic_wallpaper_enable = "false" +menu_enable_widgets = "true" +menu_font_color_blue = "255" +menu_font_color_green = "255" +menu_font_color_red = "255" +menu_footer_opacity = "1.000000" +menu_framebuffer_opacity = "0.899999" +menu_header_opacity = "1.000000" +menu_horizontal_animation = "true" +menu_insert_disk_resume = "true" +menu_left_thumbnails = "0" +menu_linear_filter = "false" +menu_mouse_enable = "false" +menu_navigation_browser_filter_supported_extensions_enable = "true" +menu_navigation_wraparound_enable = "true" +menu_pause_libretro = "true" +menu_pointer_enable = "false" +menu_rgui_full_width_layout = "true" +menu_rgui_shadows = "false" +menu_rgui_transparency = "true" +menu_savestate_resume = "true" +menu_scale_factor = "0.300000" +menu_screensaver_animation = "0" +menu_screensaver_animation_speed = "1.000000" +menu_screensaver_timeout = "0" +menu_scroll_delay = "256" +menu_scroll_fast = "false" +menu_shader_pipeline = "2" +menu_show_advanced_settings = "true" +menu_show_configurations = "true" +menu_show_core_updater = "false" +menu_show_dump_disc = "true" +menu_show_help = "true" +menu_show_information = "true" +menu_show_latency = "true" +menu_show_legacy_thumbnail_updater = "false" +menu_show_load_content_animation = "false" +menu_show_load_content = "true" +menu_show_load_core = "true" +menu_show_load_disc = "true" +menu_show_online_updater = "true" +menu_show_overlays = "true" +menu_show_quit_retroarch = "true" +menu_show_reboot = "false" +menu_show_restart_retroarch = "true" +menu_show_rewind = "true" +menu_show_shutdown = "false" +menu_show_sublabels = "true" +menu_show_video_layout = "true" +menu_swap_ok_cancel_buttons = "false" +menu_throttle_framerate = "true" +menu_thumbnails = "3" +menu_thumbnail_upscale_threshold = "0" +menu_ticker_smooth = "true" +menu_ticker_speed = "2.000000" +menu_ticker_type = "1" +menu_timedate_date_separator = "0" +menu_timedate_enable = "true" +menu_timedate_style = "11" +menu_unified_controls = "false" +menu_use_preferred_system_color_theme = "false" +menu_wallpaper = "" +menu_wallpaper_opacity = "1.000000" +menu_widget_scale_auto = "false" +menu_widget_scale_factor = "0.350000" +menu_widget_scale_factor_windowed = "1.000000" +menu_xmb_animation_horizontal_highlight = "0" +menu_xmb_animation_move_up_down = "0" +menu_xmb_animation_opening_main_menu = "0" +menu_xmb_thumbnail_scale_factor = "100" +midi_driver = "alsa" +midi_input = "Off" +midi_output = "Off" +midi_volume = "100" +netplay_allow_slaves = "true" +netplay_check_frames = "600" +netplay_input_latency_frames_min = "0" +netplay_input_latency_frames_range = "0" +netplay_ip_address = "" +netplay_ip_port = "55435" +netplay_max_connections = "3" +netplay_mitm_server = "nyc" +netplay_nat_traversal = "true" +netplay_nickname = "" +netplay_password = "" +netplay_public_announce = "true" +netplay_request_device_p10 = "false" +netplay_request_device_p11 = "false" +netplay_request_device_p12 = "false" +netplay_request_device_p13 = "false" +netplay_request_device_p14 = "false" +netplay_request_device_p15 = "false" +netplay_request_device_p16 = "false" +netplay_request_device_p1 = "false" +netplay_request_device_p2 = "false" +netplay_request_device_p3 = "false" +netplay_request_device_p4 = "false" +netplay_request_device_p5 = "false" +netplay_request_device_p6 = "false" +netplay_request_device_p7 = "false" +netplay_request_device_p8 = "false" +netplay_request_device_p9 = "false" +netplay_require_slaves = "false" +netplay_share_analog = "1" +netplay_share_digital = "1" +netplay_spectate_password = "" +netplay_start_as_spectator = "false" +netplay_stateless_mode = "false" +netplay_use_mitm_server = "false" +network_cmd_enable = "false" +network_cmd_port = "55355" +network_on_demand_thumbnails = "false" +network_remote_base_port = "55400" +network_remote_enable = "false" +network_remote_enable_user_p10 = "false" +network_remote_enable_user_p11 = "false" +network_remote_enable_user_p12 = "false" +network_remote_enable_user_p13 = "false" +network_remote_enable_user_p14 = "false" +network_remote_enable_user_p15 = "false" +network_remote_enable_user_p16 = "false" +network_remote_enable_user_p1 = "false" +network_remote_enable_user_p2 = "false" +network_remote_enable_user_p3 = "false" +network_remote_enable_user_p4 = "false" +network_remote_enable_user_p5 = "false" +network_remote_enable_user_p6 = "false" +network_remote_enable_user_p7 = "false" +network_remote_enable_user_p8 = "false" +network_remote_enable_user_p9 = "false" +notification_show_autoconfig = "false" +notification_show_cheats_applied = "true" +notification_show_config_override_load = "false" +notification_show_fast_forward = "true" +notification_show_netplay_extra = "false" +notification_show_patch_applied = "true" +notification_show_refresh_rate = "true" +notification_show_remap_load = "false" +notification_show_screenshot_duration = "2" +notification_show_screenshot = "false" +notification_show_screenshot_flash = "1" +notification_show_set_initial_disk = "true" +overlay_directory = "/tmp/overlays" +ozone_collapse_sidebar = "false" +ozone_menu_color_theme = "1" +ozone_scroll_content_metadata = "false" +ozone_sort_after_truncate_playlist_name = "true" +ozone_truncate_playlist_name = "true" +pause_nonactive = "true" +perfcnt_enable = "false" +playlist_compression = "false" +playlist_cores = "" +playlist_directory = "~/playlists" +playlist_entry_remove_enable = "1" +playlist_entry_remove = "false" +playlist_entry_rename = "false" +playlist_fuzzy_archive_match = "false" +playlist_names = "" +playlist_portable_paths = "false" +playlist_show_entry_idx = "true" +playlist_show_inline_core_name = "0" +playlist_show_sublabels = "true" +playlist_sort_alphabetical = "true" +playlist_sublabel_last_played_style = "0" +playlist_sublabel_runtime_type = "0" +playlist_use_old_format = "false" +quick_menu_show_add_to_favorites = "true" +quick_menu_show_cheats = "true" +quick_menu_show_close_content = "true" +quick_menu_show_controls = "true" +quick_menu_show_core_options_flush = "false" +quick_menu_show_download_thumbnails = "true" +quick_menu_show_information = "true" +quick_menu_show_options = "true" +quick_menu_show_recording = "true" +quick_menu_show_reset_core_association = "true" +quick_menu_show_restart_content = "true" +quick_menu_show_resume_content = "true" +quick_menu_show_save_content_dir_overrides = "true" +quick_menu_show_save_core_overrides = "false" +quick_menu_show_save_game_overrides = "false" +quick_menu_show_save_load_state = "true" +quick_menu_show_set_core_association = "true" +quick_menu_show_shaders = "true" +quick_menu_show_start_recording = "true" +quick_menu_show_start_streaming = "true" +quick_menu_show_streaming = "true" +quick_menu_show_take_screenshot = "true" +quick_menu_show_undo_save_load_state = "false" +quit_on_close_content = "0" +quit_press_twice = "true" +record_driver = "null" +recording_config_directory = "" +recording_output_directory = "~/roms/screenshots" +resampler_directory = "" +rewind_buffer_size = "20971520" +rewind_buffer_size_step = "10" +rewind_enable = "false" +rewind_granularity = "1" +rgui_aspect_ratio = "0" +rgui_aspect_ratio_lock = "0" +rgui_background_filler_thickness_enable = "true" +rgui_border_filler_enable = "true" +rgui_border_filler_thickness_enable = "true" +rgui_browser_directory = "~/roms" +rgui_config_directory = "~/.config/retroarch/config" +rgui_extended_ascii = "false" +rgui_inline_thumbnails = "false" +rgui_internal_upscale_level = "0" +rgui_menu_color_theme = "4" +rgui_menu_theme_preset = "" +rgui_particle_effect = "0" +rgui_particle_effect_screensaver = "true" +rgui_particle_effect_speed = "1.000000" +rgui_show_start_screen = "false" +rgui_swap_thumbnails = "false" +rgui_switch_icons = "true" +rgui_thumbnail_delay = "0" +rgui_thumbnail_downscaler = "0" +run_ahead_enabled = "false" +run_ahead_frames = "1" +run_ahead_hide_warnings = "false" +run_ahead_secondary_instance = "true" +runtime_log_directory = "default" +save_file_compression = "false" +savefile_directory = "~/.config/retroarch/saves" +savefiles_in_content_dir = "true" +savestate_auto_index = "false" +savestate_auto_load = "false" +savestate_auto_save = "false" +savestate_directory = "~/.config/retroarch/states" +savestate_file_compression = "true" +savestate_max_keep = "0" +savestates_in_content_dir = "false" +savestate_thumbnail_enable = "true" +scan_without_core_match = "false" +screen_brightness = "100" +screen_orientation = "0" +screenshot_directory = "~/roms/screenshots" +screenshots_in_content_dir = "false" +settings_show_accessibility = "true" +settings_show_achievements = "true" +settings_show_ai_service = "true" +settings_show_audio = "true" +settings_show_configuration = "true" +settings_show_core = "true" +settings_show_directory = "true" +settings_show_drivers = "true" +settings_show_file_browser = "true" +settings_show_frame_throttle = "true" +settings_show_input = "true" +settings_show_latency = "true" +settings_show_logging = "true" +settings_show_network = "true" +settings_show_onscreen_display = "true" +settings_show_playlists = "true" +settings_show_power_management = "true" +settings_show_recording = "true" +settings_show_saving = "true" +settings_show_user_interface = "true" +settings_show_user = "true" +settings_show_video = "true" +show_hidden_files = "false" +slowmotion_ratio = "3.000000" +soft_filter_enable = "false" +soft_filter_index = "0" +sort_savefiles_by_content_enable = "false" +sort_savefiles_enable = "false" +sort_savestates_by_content_enable = "false" +sort_savestates_enable = "false" +sort_screenshots_by_content_enable = "false" +state_slot = "0" +statistics_show = "false" +stdin_cmd_enable = "false" +streaming_mode = "0" +suspend_screensaver_enable = "true" +sustained_performance_mode = "false" +system_directory = "~/roms/bios" +systemfiles_in_content_dir = "false" +threaded_data_runloop_enable = "true" +thumbnails_directory = "~/thumbnails" +twitch_stream_key = "" +ui_companion_enable = "false" +ui_companion_start_on_boot = "true" +ui_companion_toggle = "false" +ui_menubar_enable = "true" +use_last_start_directory = "false" +user_language = "0" +vibrate_on_keypress = "true" +video_adaptive_vsync = "false" +video_allow_rotate = "true" +video_aspect_ratio = "-1.000000" +video_aspect_ratio_auto = "true" +video_black_frame_insertion = "0" +video_context_driver = "" +video_crop_overscan = "true" +video_ctx_scaling = "false" +video_disable_composition = "false" +video_driver = "gl" +video_filter = "" +video_filter_dir = "~/.config/retroarch/filters/video" +video_font_enable = "true" +video_font_path = "/usr/share/retroarch-assets/xmb/monochrome/font.ttf" +video_font_size = "32.000000" +video_force_aspect = "true" +video_force_srgb_disable = "false" +video_frame_delay = "0" +video_frame_delay_auto = "false" +video_fullscreen = "true" +video_fullscreen_x = "1920" +video_fullscreen_y = "1080" +video_gpu_record = "false" +video_gpu_screenshot = "false" +video_hard_sync = "false" +video_hard_sync_frames = "0" +video_hdr_display_contrast = "5.000000" +video_hdr_enable = "false" +video_hdr_expand_gamut = "true" +video_hdr_max_nits = "1000.000000" +video_hdr_paper_white_nits = "200.000000" +video_layout_directory = "~/.config/retroarch/layouts" +video_layout_enable = "true" +video_layout_path = "" +video_layout_selected_view = "0" +video_max_swapchain_images = "3" +video_message_color = "ffff00" +video_message_pos_x = "0.049999" +video_message_pos_y = "0.049999" +video_monitor_index = "0" +video_msg_bgcolor_blue = "0" +video_msg_bgcolor_enable = "false" +video_msg_bgcolor_green = "0" +video_msg_bgcolor_opacity = "1.000000" +video_msg_bgcolor_red = "0" +video_notch_write_over_enable = "false" +video_oga_vertical_enable = "false" +video_post_filter_record = "false" +video_record_config = "" +video_record_quality = "4" +video_record_scale_factor = "1" +video_record_threads = "2" +video_refresh_rate = "60.000000" +video_rotation = "0" +video_scale = "3.000000" +video_scale_integer = "false" +video_scale_integer_overscale = "false" +video_shader_delay = "0" +video_shader_dir = "/tmp/shaders" +video_shader_enable = "false" +video_shader_preset_save_reference_enable = "true" +video_shader_remember_last_dir = "false" +video_shader_watch_files = "false" +video_shared_context = "false" +video_smooth = "false" +video_stream_config = "" +video_stream_port = "56400" +video_stream_quality = "10" +video_stream_scale_factor = "1" +video_stream_url = "" +video_swap_interval = "1" +video_threaded = "true" +video_vsync = "true" +video_window_auto_height_max = "1080" +video_window_auto_width_max = "1920" +video_window_custom_size_enable = "false" +video_windowed_fullscreen = "false" +video_windowed_position_height = "720" +video_windowed_position_width = "1280" +video_windowed_position_x = "0" +video_windowed_position_y = "0" +video_window_opacity = "100" +video_window_save_positions = "false" +video_window_show_decorations = "true" +vrr_runloop_enable = "false" +wifi_driver = "null" +wifi_enabled = "true" +xmb_alpha_factor = "75" +xmb_font = "/usr/share/retroarch-assets/xmb/monochrome/font.ttf" +xmb_layout = "2" +xmb_menu_color_theme = "4" +xmb_shadows_enable = "true" +xmb_theme = "0" +xmb_vertical_thumbnails = "false" +youtube_stream_key = "" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3588/retroarch32bit-append.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3588/retroarch32bit-append.cfg new file mode 100755 index 0000000000..343124c254 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3588/retroarch32bit-append.cfg @@ -0,0 +1,3 @@ +audio_filter_dir = "/usr/share/retroarch/filters/32bit/audio" +video_filter_dir = "/usr/share/retroarch/filters/32bit/video" +libretro_directory = /usr/lib32/libretro diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3588/retroarch64bit-append.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3588/retroarch64bit-append.cfg new file mode 100755 index 0000000000..b6cbf68312 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/RK3588/retroarch64bit-append.cfg @@ -0,0 +1,2 @@ +audio_filter_dir = "/usr/share/retroarch/filters/64bit/audio" +video_filter_dir = "/usr/share/retroarch/filters/64bit/video" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/S922X/TATE-MAME 2003-Plus.rmp b/projects/ArchR/packages/emulators/libretro/retroarch/sources/S922X/TATE-MAME 2003-Plus.rmp new file mode 100644 index 0000000000..366e47afad --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/S922X/TATE-MAME 2003-Plus.rmp @@ -0,0 +1,27 @@ +input_libretro_device_p1 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_player1_analog_dpad_mode = "1" +input_player1_btn_down = "6" +input_player1_btn_left = "4" +input_player1_btn_right = "5" +input_player1_btn_up = "7" +input_player1_stk_l_x+ = "5" +input_player1_stk_l_x- = "4" +input_player1_stk_l_y+ = "6" +input_player1_stk_l_y- = "7" +input_player1_stk_r_x+ = "5" +input_player1_stk_r_x- = "4" +input_player1_stk_r_y+ = "6" +input_player1_stk_r_y- = "7" +input_player2_analog_dpad_mode = "0" +input_player3_analog_dpad_mode = "0" +input_player4_analog_dpad_mode = "0" +input_player5_analog_dpad_mode = "0" +input_remap_port_p1 = "0" +input_remap_port_p2 = "1" +input_remap_port_p3 = "2" +input_remap_port_p4 = "3" +input_remap_port_p5 = "4" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/S922X/retroarch-core-options.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/S922X/retroarch-core-options.cfg new file mode 100644 index 0000000000..3f1cc2ca9e --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/S922X/retroarch-core-options.cfg @@ -0,0 +1,153 @@ +mupen64plus-alt-map = "False" +mupen64plus-aspect = "4:3" +mupen64plus-astick-deadzone = "15" +mupen64plus-astick-sensitivity = "100" +mupen64plus-BackgroundMode = "Stripped" +mupen64plus-BilinearMode = "standard" +mupen64plus-CorrectTexrectCoords = "Auto" +mupen64plus-CountPerOp = "0" +mupen64plus-CountPerOpDenomPot = "0" +mupen64plus-cpucore = "dynamic_recompiler" +mupen64plus-d-cbutton = "C3" +mupen64plus-DitheringPattern = "True" +mupen64plus-DitheringQuantization = "True" +mupen64plus-EnableCopyAuxToRDRAM = "True" +mupen64plus-EnableCopyColorToRDRAM = "Async" +mupen64plus-EnableCopyDepthToRDRAM = "Software" +mupen64plus-EnableEnhancedHighResStorage = "False" +mupen64plus-EnableEnhancedTextureStorage = "False" +mupen64plus-EnableFBEmulation = "True" +mupen64plus-EnableFragmentDepthWrite = "True" +mupen64plus-EnableHiResAltCRC = "False" +mupen64plus-EnableHWLighting = "False" +mupen64plus-EnableInaccurateTextureCoordinates = "False" +mupen64plus-EnableLegacyBlending = "False" +mupen64plus-EnableLODEmulation = "True" +mupen64plus-EnableNativeResFactor = "1" +mupen64plus-EnableNativeResTexrects = "Optimized" +mupen64plus-EnableOverscan = "Enabled" +mupen64plus-EnableTexCoordBounds = "False" +mupen64plus-EnableTextureCache = "True" +mupen64plus-ForceDisableExtraMem = "False" +mupen64plus-FrameDuping = "True" +mupen64plus-Framerate = "Original" +mupen64plus-FXAA = "0" +mupen64plus-GLideN64IniBehaviour = "late" +mupen64plus-HybridFilter = "True" +mupen64plus-IgnoreTLBExceptions = "False" +mupen64plus-l-cbutton = "C2" +mupen64plus-MaxHiResTxVramLimit = "0" +mupen64plus-MaxTxCacheSize = "8000" +mupen64plus-MultiSampling = "0" +mupen64plus-OverscanBottom = "0" +mupen64plus-OverscanLeft = "0" +mupen64plus-OverscanRight = "0" +mupen64plus-OverscanTop = "0" +mupen64plus-pak1 = "memory" +mupen64plus-pak2 = "none" +mupen64plus-pak3 = "none" +mupen64plus-pak4 = "none" +mupen64plus-r-cbutton = "C1" +mupen64plus-rdp-plugin = "gliden64" +mupen64plus-RDRAMImageDitheringMode = "BlueNoise" +mupen64plus-rsp-plugin = "hle" +mupen64plus-ThreadedRenderer = "True" +mupen64plus-txCacheCompression = "True" +mupen64plus-txEnhancementMode = "None" +mupen64plus-txFilterIgnoreBG = "True" +mupen64plus-txFilterMode = "None" +mupen64plus-txHiresEnable = "False" +mupen64plus-txHiresFullAlphaChannel = "False" +mupen64plus-u-cbutton = "C4" +mupen64plus-virefresh = "Auto" +pcsx_rearmed_analog_axis_modifier = "circle" +pcsx_rearmed_async_cd = "sync" +pcsx_rearmed_bios = "auto" +pcsx_rearmed_display_internal_fps = "disabled" +pcsx_rearmed_dithering = "enabled" +pcsx_rearmed_drc = "enabled" +pcsx_rearmed_duping_enable = "enabled" +pcsx_rearmed_frameskip_type = "disabled" +pcsx_rearmed_gteregsunneeded = "disabled" +pcsx_rearmed_gunconadjustratiox = "1" +pcsx_rearmed_gunconadjustratioy = "1" +pcsx_rearmed_gunconadjustx = "0" +pcsx_rearmed_gunconadjusty = "0" +pcsx_rearmed_idiablofix = "disabled" +pcsx_rearmed_input_sensitivity = "1.00" +pcsx_rearmed_inuyasha_fix = "disabled" +pcsx_rearmed_memcard2 = "disabled" +pcsx_rearmed_multitap1 = "auto" +pcsx_rearmed_multitap2 = "auto" +pcsx_rearmed_negcon_deadzone = "0" +pcsx_rearmed_negcon_response = "linear" +pcsx_rearmed_neon_enhancement_enable = "disabled" +pcsx_rearmed_neon_enhancement_no_main = "disabled" +pcsx_rearmed_neon_interlace_enable = "disabled" +pcsx_rearmed_nocdaudio = "enabled" +pcsx_rearmed_nogteflags = "disabled" +pcsx_rearmed_nosmccheck = "disabled" +pcsx_rearmed_noxadecoding = "enabled" +pcsx_rearmed_pad1type = "standard" +pcsx_rearmed_pad2type = "standard" +pcsx_rearmed_pad3type = "none" +pcsx_rearmed_pad4type = "none" +pcsx_rearmed_pad5type = "none" +pcsx_rearmed_pad6type = "none" +pcsx_rearmed_pad7type = "none" +pcsx_rearmed_pad8type = "none" +pcsx_rearmed_pe2_fix = "disabled" +pcsx_rearmed_psxclock = "57" +pcsx_rearmed_region = "auto" +pcsx_rearmed_show_bios_bootlogo = "disabled" +pcsx_rearmed_show_other_input_settings = "disabled" +pcsx_rearmed_spu_interpolation = "simple" +pcsx_rearmed_spu_reverb = "enabled" +pcsx_rearmed_spuirq = "disabled" +pcsx_rearmed_vibration = "enabled" +gambatte_gb_colorization = "disabled" +gambatte_gb_internal_palette = "" +mame2003-plus_analog = "digital" +mame2003-plus_art_resolution = "1" +mame2003-plus_brightness = "1.0" +mame2003-plus_cheat_input_ports = "disabled" +mame2003-plus_core_save_subfolder = "enabled" +mame2003-plus_core_sys_subfolder = "enabled" +mame2003-plus_dcs_speedhack = "enabled" +mame2003-plus_deadzone = "20" +mame2003-plus_digital_joy_centering = "enabled" +mame2003-plus_display_artwork = "enabled" +mame2003-plus_display_setup = "disabled" +mame2003-plus_four_way_emulation = "disabled" +mame2003-plus_frameskip = "0" +mame2003-plus_gamma = "1.0" +mame2003-plus_input_interface = "retropad" +mame2003-plus_machine_timing = "enabled" +mame2003-plus_mame_remapping = "enabled" +mame2003-plus_mouse_device = "mouse" +mame2003-plus_sample_rate = "48000" +mame2003-plus_skip_disclaimer = "disabled" +mame2003-plus_skip_warnings = "disabled" +flycast_internal_resolution = "640x480" +flycast_alpha_sorting = "per-strip (fast, least accurate)" +flycast_enable_dsp = "disabled" +flycast_threaded_rendering = "enabled" +flycast_anisotropic_filtering = "off" +flycast_synchronous_rendering = "enabled" +flycast_enable_rtt = "disabled" +flycast_enable_rttb = "disabled" +flycast_delay_frame_swapping = "disabled" +flycast_div_matching = "auto" +flycast_texupscale = "off" +flycast_auto_skip_frame = "normal" +opera_swi_hle = "enabled" +opera_dsp_threaded = "enabled" +opera_madam_matrix_engine = "software" +puae_deadzone = "25" +melonds_screen_layout = "Left/Right" +melonds_swapscreen_mode = "Toggle" +melonds_threaded_renderer = "enabled" +melonds_touch_mode = "Joystick" +virtualjaguar_bios = "enabled" +virtualjaguar_usefastblitter = "enabled" +desmume_screens_layout = "left/right" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/S922X/retroarch.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/S922X/retroarch.cfg new file mode 100644 index 0000000000..792bc4834a --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/S922X/retroarch.cfg @@ -0,0 +1,821 @@ +accessibility_enable = "false" +accessibility_narrator_speech_speed = "5" +ai_service_enable = "true" +ai_service_mode = "1" +ai_service_pause = "false" +ai_service_source_lang = "0" +ai_service_target_lang = "0" +ai_service_url = "http://localhost:4404/" +all_users_control_menu = "true" +apply_cheats_after_load = "false" +apply_cheats_after_toggle = "false" +aspect_ratio_index = "22" +assets_directory = "/tmp/assets" +audio_block_frames = "0" +audio_device = "" +audio_driver = "alsathread" +audio_dsp_plugin = "" +audio_enable_menu_bgm = "false" +audio_enable_menu_cancel = "false" +audio_enable_menu = "false" +audio_enable_menu_notice = "false" +audio_enable_menu_ok = "false" +audio_enable = "true" +audio_fastforward_mute = "false" +audio_filter_dir = "~/.config/retroarch/filters/audio" +audio_latency = "32" +audio_max_timing_skew = "0.049999" +audio_mixer_mute_enable = "false" +audio_mixer_volume = "0.000000" +audio_mute_enable = "false" +audio_out_rate = "48000" +audio_rate_control_delta = "0.004999" +audio_rate_control = "true" +audio_resampler_quality = "2" +audio_resampler = "sinc" +audio_sync = "true" +audio_volume = "0.000000" +auto_overrides_enable = "true" +auto_remaps_enable = "true" +autosave_interval = "10" +auto_screenshot_filename = "true" +auto_shaders_enable = "true" +block_sram_overwrite = "false" +bluetooth_driver = "null" +builtin_imageviewer_enable = "false" +builtin_mediaplayer_enable = "true" +bundle_assets_dst_path = "" +bundle_assets_dst_path_subdir = "" +bundle_assets_extract_enable = "false" +bundle_assets_extract_last_version = "0" +bundle_assets_extract_version_current = "0" +bundle_assets_src_path = "" +cache_directory = "/tmp/cache" +camera_allow = "false" +camera_device = "" +camera_driver = "null" +cheat_database_path = "/tmp/database/cht" +check_firmware_before_loading = "false" +cheevos_auto_screenshot = "false" +cheevos_badges_enable = "false" +cheevos_challenge_indicators = "true" +cheevos_enable = "false" +cheevos_hardcore_mode_enable = "false" +cheevos_leaderboards_enable = "" +cheevos_password = "" +cheevos_richpresence_enable = "true" +cheevos_start_active = "false" +cheevos_test_unofficial = "false" +cheevos_token = "" +cheevos_unlock_sound_enable = "false" +cheevos_username = "" +cheevos_verbose_enable = "false" +config_save_on_exit = "false" +content_database_path = "/tmp/database/rdb" +content_favorites_directory = "default" +content_favorites_path = "~/.config/retroarch/content_favorites.lpl" +content_favorites_size = "200" +content_history_dir = "" +content_history_directory = "default" +content_history_path = "~/.config/retroarch/content_history.lpl" +content_history_size = "200" +content_image_history_directory = "default" +content_image_history_path = "~/.config/retroarch/content_image_history.lpl" +content_music_history_directory = "default" +content_music_history_path = "~/.config/retroarch/content_music_history.lpl" +content_runtime_log_aggregate = "false" +content_runtime_log = "true" +content_show_add_entry = "2" +content_show_add = "true" +content_show_explore = "true" +content_show_favorites = "true" +content_show_history = "true" +content_show_images = "false" +content_show_music = "false" +content_show_netplay = "true" +content_show_playlists = "true" +content_show_settings_password = "" +content_show_settings = "true" +content_show_video = "false" +content_video_directory = "default" +content_video_history_path = "~/.config/retroarch/content_video_history.lpl" +core_assets_directory = "~/roms/downloads" +core_info_cache_enable = "true" +core_option_category_enable = "true" +core_options_path = "" +core_set_supports_no_game_enable = "true" +core_updater_auto_backup = "false" +core_updater_auto_backup_history_size = "1" +core_updater_auto_extract_archive = "true" +core_updater_buildbot_assets_url = "http://buildbot.libretro.com/assets/" +core_updater_buildbot_cores_url = "" +core_updater_buildbot_url = "http://buildbot.libretro.com/nightly/linux/armhf/latest/" +core_updater_show_experimental_cores = "false" +cpu_main_gov = "performance" +cpu_max_freq = "-1" +cpu_menu_gov = "interactive" +cpu_min_freq = "1" +cpu_scaling_mode = "0" +crt_switch_center_adjust = "0" +crt_switch_hires_menu = "false" +crt_switch_porch_adjust = "0" +crt_switch_resolution = "0" +crt_switch_resolution_super = "2560" +crt_switch_resolution_use_custom_refresh_rate = "false" +crt_switch_timings = "" +crt_video_refresh_rate = "60.000000" +current_resolution_id = "0" +cursor_directory = "~/.config/retroarch/database/cursors" +desktop_menu_enable = "true" +discord_allow = "false" +discord_app_id = "475456035851599874" +driver_switch_enable = "true" +dynamic_wallpapers_directory = "default" +emuelec_exit_to_kodi = "false" +enable_device_vibration = "true" +facebook_stream_key = "" +fastforward_ratio = "0.000000" +filter_by_current_core = "false" +flicker_filter_enable = "false" +flicker_filter_index = "0" +fps_show = "false" +fps_update_interval = "256" +framecount_show = "false" +frame_time_counter_reset_after_fastforwarding = "false" +frame_time_counter_reset_after_load_state = "false" +frame_time_counter_reset_after_save_state = "false" +frontend_log_level = "1" +game_specific_options = "true" +gamma_correction = "0" +global_core_options = "false" +history_list_enable = "true" +input_ai_service_axis = "nul" +input_ai_service_btn = "nul" +input_ai_service_mbtn = "nul" +input_ai_service = "nul" +input_analog_deadzone = "0.000000" +input_analog_sensitivity = "1.500000" +input_audio_mute_axis = "nul" +input_audio_mute_btn = "nul" +input_audio_mute = "f9" +input_audio_mute_mbtn = "nul" +input_autodetect_enable = "true" +input_auto_game_focus = "0" +input_auto_mouse_grab = "false" +input_axis_threshold = "0.500000" +input_bind_hold = "2" +input_bind_timeout = "5" +input_cheat_index_minus_axis = "nul" +input_cheat_index_minus_btn = "nul" +input_cheat_index_minus_mbtn = "nul" +input_cheat_index_minus = "t" +input_cheat_index_plus_axis = "nul" +input_cheat_index_plus_btn = "nul" +input_cheat_index_plus_mbtn = "nul" +input_cheat_index_plus = "y" +input_cheat_toggle_axis = "nul" +input_cheat_toggle_btn = "nul" +input_cheat_toggle_mbtn = "nul" +input_cheat_toggle = "u" +input_close_content_axis = "nul" +input_close_content_btn = "nul" +input_close_content_mbtn = "nul" +input_close_content = "nul" +input_descriptor_hide_unbound = "false" +input_descriptor_label_show = "true" +input_desktop_menu_toggle_axis = "nul" +input_desktop_menu_toggle_btn = "nul" +input_desktop_menu_toggle = "f5" +input_desktop_menu_toggle_mbtn = "nul" +input_device_p1 = "0" +input_device_p10 = "0" +input_device_p11 = "0" +input_device_p12 = "0" +input_device_p13 = "0" +input_device_p14 = "0" +input_device_p15 = "0" +input_device_p16 = "0" +input_device_p2 = "0" +input_device_p3 = "0" +input_device_p4 = "0" +input_device_p5 = "0" +input_device_p6 = "0" +input_device_p7 = "0" +input_device_p8 = "0" +input_device_p9 = "0" +input_disk_eject_toggle_axis = "nul" +input_disk_eject_toggle_btn = "nul" +input_disk_eject_toggle_mbtn = "nul" +input_disk_eject_toggle = "nul" +input_disk_next_axis = "nul" +input_disk_next_btn = "nul" +input_disk_next_mbtn = "nul" +input_disk_next = "nul" +input_disk_prev_axis = "nul" +input_disk_prev_btn = "nul" +input_disk_prev_mbtn = "nul" +input_disk_prev = "nul" +input_driver = "udev" +input_duty_cycle = "3" +input_enable_hotkey_axis = "nul" +input_enable_hotkey_btn = "13" +input_enable_hotkey_mbtn = "nul" +input_enable_hotkey = "nul" +input_exit_emulator_axis = "nul" +input_exit_emulator_btn = "9" +input_exit_emulator = "escape" +input_exit_emulator_mbtn = "nul" +input_fps_toggle_axis = "nul" +input_fps_toggle_btn = "3" +input_fps_toggle = "f3" +input_fps_toggle_mbtn = "nul" +input_frame_advance_axis = "nul" +input_frame_advance_btn = "nul" +input_frame_advance = "k" +input_frame_advance_mbtn = "nul" +input_game_focus_toggle_axis = "nul" +input_game_focus_toggle_btn = "nul" +input_game_focus_toggle_mbtn = "nul" +input_game_focus_toggle = "scroll_lock" +input_grab_mouse_toggle_axis = "nul" +input_grab_mouse_toggle_btn = "nul" +input_grab_mouse_toggle = "f11" +input_grab_mouse_toggle_mbtn = "nul" +input_hold_fast_forward_axis = "nul" +input_hold_fast_forward_btn = "nul" +input_hold_fast_forward = "l" +input_hold_fast_forward_mbtn = "nul" +input_hold_slowmotion_axis = "nul" +input_hold_slowmotion_btn = "nul" +input_hold_slowmotion = "e" +input_hold_slowmotion_mbtn = "nul" +input_hotkey_block_delay = "5" +input_joypad_driver = "udev" +input_keyboard_layout = "" +input_libretro_device_p10 = "1" +input_libretro_device_p1 = "1" +input_libretro_device_p11 = "1" +input_libretro_device_p12 = "1" +input_libretro_device_p13 = "1" +input_libretro_device_p14 = "1" +input_libretro_device_p15 = "1" +input_libretro_device_p16 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_libretro_device_p6 = "1" +input_libretro_device_p7 = "1" +input_libretro_device_p8 = "1" +input_libretro_device_p9 = "1" +input_load_state_axis = "nul" +input_load_state_btn = "4" +input_load_state = "f4" +input_load_state_mbtn = "nul" +input_max_users = "5" +input_menu_toggle_axis = "nul" +input_menu_toggle_btn = "2" +input_menu_toggle = "f1" +input_menu_toggle_gamepad_combo = "2" +input_menu_toggle_mbtn = "nul" +input_movie_record_toggle_axis = "nul" +input_movie_record_toggle_btn = "nul" +input_movie_record_toggle_mbtn = "nul" +input_movie_record_toggle = "o" +input_netplay_game_watch_axis = "nul" +input_netplay_game_watch_btn = "nul" +input_netplay_game_watch = "i" +input_netplay_game_watch_mbtn = "nul" +input_netplay_host_toggle_axis = "nul" +input_netplay_host_toggle_btn = "nul" +input_netplay_host_toggle_mbtn = "nul" +input_netplay_host_toggle = "nul" +input_nowinkey_enable = "false" +input_osk_toggle_axis = "nul" +input_osk_toggle_btn = "nul" +input_osk_toggle = "f12" +input_osk_toggle_mbtn = "nul" +input_overlay = "" +input_overlay_aspect_adjust_landscape = "0.000000" +input_overlay_aspect_adjust_portrait = "0.000000" +input_overlay_auto_rotate = "false" +input_overlay_auto_scale = "false" +input_overlay_enable_autopreferred = "true" +input_overlay_enable = "false" +input_overlay_hide_in_menu = "true" +input_overlay_hide_when_gamepad_connected = "false" +input_overlay_next_axis = "nul" +input_overlay_next_btn = "nul" +input_overlay_next_mbtn = "nul" +input_overlay_next = "nul" +input_overlay_opacity = "0.700000" +input_overlay_scale_landscape = "1.000000" +input_overlay_scale_portrait = "1.000000" +input_overlay_show_inputs = "2" +input_overlay_show_inputs_port = "0" +input_overlay_show_mouse_cursor = "true" +input_overlay_x_offset_landscape = "0.000000" +input_overlay_x_offset_portrait = "0.000000" +input_overlay_x_separation_landscape = "0.000000" +input_overlay_x_separation_portrait = "0.000000" +input_overlay_y_offset_landscape = "0.000000" +input_overlay_y_offset_portrait = "0.000000" +input_overlay_y_separation_landscape = "0.000000" +input_overlay_y_separation_portrait = "0.000000" +input_pause_toggle_axis = "nul" +input_pause_toggle_btn = "nul" +input_pause_toggle_mbtn = "nul" +input_pause_toggle = "p" +input_poll_type_behavior = "2" +input_quit_gamepad_combo = "0" +input_recording_toggle_axis = "nul" +input_recording_toggle_btn = "nul" +input_recording_toggle_mbtn = "nul" +input_recording_toggle = "nul" +input_remap_binds_enable = "true" +input_remapping_directory = "~/remappings" +input_reset_axis = "nul" +input_reset_btn = "nul" +input_reset = "h" +input_reset_mbtn = "nul" +input_rewind_axis = "nul" +input_rewind_btn = "6" +input_rewind_mbtn = "nul" +input_rewind = "r" +input_rumble_gain = "100" +input_runahead_toggle_axis = "nul" +input_runahead_toggle_btn = "nul" +input_runahead_toggle_mbtn = "nul" +input_runahead_toggle = "nul" +input_save_state_axis = "nul" +input_save_state_btn = "5" +input_save_state = "f2" +input_save_state_mbtn = "nul" +input_screenshot_axis = "nul" +input_screenshot_btn = "nul" +input_screenshot = "f8" +input_screenshot_mbtn = "nul" +input_send_debug_info_axis = "nul" +input_send_debug_info_btn = "nul" +input_send_debug_info = "f10" +input_send_debug_info_mbtn = "nul" +input_sensors_enable = "true" +input_shader_next_axis = "nul" +input_shader_next_btn = "nul" +input_shader_next = "m" +input_shader_next_mbtn = "nul" +input_shader_prev_axis = "nul" +input_shader_prev_btn = "nul" +input_shader_prev_mbtn = "nul" +input_shader_prev = "n" +input_state_slot_decrease_axis = "nul" +input_state_slot_decrease_btn = "nul" +input_state_slot_decrease = "f6" +input_state_slot_decrease_mbtn = "nul" +input_state_slot_increase_axis = "nul" +input_state_slot_increase_btn = "nul" +input_state_slot_increase = "f7" +input_state_slot_increase_mbtn = "nul" +input_streaming_toggle_axis = "nul" +input_streaming_toggle_btn = "nul" +input_streaming_toggle_mbtn = "nul" +input_streaming_toggle = "nul" +input_toggle_fast_forward_axis = "nul" +input_toggle_fast_forward_btn = "7" +input_toggle_fast_forward_mbtn = "nul" +input_toggle_fast_forward = "space" +input_toggle_fullscreen_axis = "nul" +input_toggle_fullscreen_btn = "nul" +input_toggle_fullscreen = "f" +input_toggle_fullscreen_mbtn = "nul" +input_toggle_slowmotion_axis = "nul" +input_toggle_slowmotion_btn = "nul" +input_toggle_slowmotion_mbtn = "nul" +input_toggle_slowmotion = "nul" +input_touch_scale = "1" +input_turbo_default_button = "0" +input_turbo_mode = "0" +input_turbo_period = "6" +input_volume_down_axis = "nul" +input_volume_down_btn = "nul" +input_volume_down_mbtn = "nul" +input_volume_down = "subtract" +input_volume_up = "add" +input_volume_up_axis = "nul" +input_volume_up_btn = "nul" +input_volume_up_mbtn = "nul" +joypad_autoconfig_dir = "/tmp/joypads" +keyboard_gamepad_enable = "true" +keyboard_gamepad_mapping_type = "1" +kiosk_mode_enable = "false" +kiosk_mode_password = "" +led_driver = "null" +libretro_directory = "/tmp/cores" +libretro_info_path = "/tmp/cores" +libretro_log_level = "1" +load_dummy_on_core_shutdown = "true" +location_allow = "false" +location_driver = "null" +log_dir = "~/.config/retroarch/logs" +log_to_file = "false" +log_to_file_timestamp = "false" +log_verbosity = "true" +materialui_auto_rotate_nav_bar = "true" +materialui_dual_thumbnail_list_view_enable = "true" +materialui_icons_enable = "true" +materialui_landscape_layout_optimization = "1" +materialui_menu_color_theme = "9" +materialui_menu_transition_animation = "0" +materialui_playlist_icons_enable = "true" +materialui_show_nav_bar = "true" +materialui_thumbnail_background_enable = "true" +materialui_thumbnail_view_landscape = "2" +materialui_thumbnail_view_portrait = "1" +memory_show = "false" +memory_update_interval = "256" +menu_battery_level_enable = "true" +menu_core_enable = "true" +menu_dynamic_wallpaper_enable = "false" +menu_enable_widgets = "true" +menu_font_color_blue = "255" +menu_font_color_green = "255" +menu_font_color_red = "255" +menu_footer_opacity = "1.000000" +menu_framebuffer_opacity = "0.899999" +menu_header_opacity = "1.000000" +menu_horizontal_animation = "true" +menu_insert_disk_resume = "true" +menu_left_thumbnails = "0" +menu_mouse_enable = "false" +menu_navigation_browser_filter_supported_extensions_enable = "true" +menu_navigation_wraparound_enable = "true" +menu_pause_libretro = "true" +menu_pointer_enable = "false" +menu_rgui_full_width_layout = "true" +menu_rgui_shadows = "false" +menu_rgui_transparency = "true" +menu_savestate_resume = "true" +menu_scale_factor = "0.300000" +menu_screensaver_animation = "0" +menu_screensaver_animation_speed = "1.000000" +menu_screensaver_timeout = "0" +menu_scroll_delay = "256" +menu_scroll_fast = "false" +menu_shader_pipeline = "2" +menu_show_advanced_settings = "true" +menu_show_configurations = "true" +menu_show_core_updater = "false" +menu_show_dump_disc = "true" +menu_show_help = "true" +menu_show_information = "true" +menu_show_latency = "true" +menu_show_legacy_thumbnail_updater = "false" +menu_show_load_content_animation = "false" +menu_show_load_content = "true" +menu_show_load_core = "true" +menu_show_load_disc = "true" +menu_show_online_updater = "true" +menu_show_overlays = "true" +menu_show_quit_retroarch = "true" +menu_show_reboot = "false" +menu_show_restart_retroarch = "true" +menu_show_rewind = "true" +menu_show_shutdown = "false" +menu_show_sublabels = "true" +menu_show_video_layout = "true" +menu_swap_ok_cancel_buttons = "false" +menu_throttle_framerate = "true" +menu_thumbnails = "3" +menu_thumbnail_upscale_threshold = "0" +menu_ticker_smooth = "true" +menu_ticker_speed = "2.000000" +menu_ticker_type = "1" +menu_timedate_date_separator = "0" +menu_timedate_enable = "true" +menu_timedate_style = "11" +menu_unified_controls = "false" +menu_use_preferred_system_color_theme = "false" +menu_wallpaper = "" +menu_wallpaper_opacity = "1.000000" +menu_widget_scale_auto = "false" +menu_widget_scale_factor = "0.350000" +menu_widget_scale_factor_windowed = "1.000000" +menu_xmb_animation_horizontal_highlight = "0" +menu_xmb_animation_move_up_down = "0" +menu_xmb_animation_opening_main_menu = "0" +menu_xmb_thumbnail_scale_factor = "100" +midi_driver = "alsa" +midi_input = "Off" +midi_output = "Off" +midi_volume = "100" +netplay_allow_slaves = "true" +netplay_check_frames = "600" +netplay_input_latency_frames_min = "0" +netplay_input_latency_frames_range = "0" +netplay_ip_address = "" +netplay_ip_port = "55435" +netplay_max_connections = "3" +netplay_mitm_server = "nyc" +netplay_nat_traversal = "true" +netplay_nickname = "" +netplay_password = "" +netplay_public_announce = "true" +netplay_request_device_p10 = "false" +netplay_request_device_p11 = "false" +netplay_request_device_p12 = "false" +netplay_request_device_p13 = "false" +netplay_request_device_p14 = "false" +netplay_request_device_p15 = "false" +netplay_request_device_p16 = "false" +netplay_request_device_p1 = "false" +netplay_request_device_p2 = "false" +netplay_request_device_p3 = "false" +netplay_request_device_p4 = "false" +netplay_request_device_p5 = "false" +netplay_request_device_p6 = "false" +netplay_request_device_p7 = "false" +netplay_request_device_p8 = "false" +netplay_request_device_p9 = "false" +netplay_require_slaves = "false" +netplay_share_analog = "1" +netplay_share_digital = "1" +netplay_spectate_password = "" +netplay_start_as_spectator = "false" +netplay_stateless_mode = "false" +netplay_use_mitm_server = "false" +network_cmd_enable = "false" +network_cmd_port = "55355" +network_on_demand_thumbnails = "false" +network_remote_base_port = "55400" +network_remote_enable = "false" +network_remote_enable_user_p10 = "false" +network_remote_enable_user_p11 = "false" +network_remote_enable_user_p12 = "false" +network_remote_enable_user_p13 = "false" +network_remote_enable_user_p14 = "false" +network_remote_enable_user_p15 = "false" +network_remote_enable_user_p16 = "false" +network_remote_enable_user_p1 = "false" +network_remote_enable_user_p2 = "false" +network_remote_enable_user_p3 = "false" +network_remote_enable_user_p4 = "false" +network_remote_enable_user_p5 = "false" +network_remote_enable_user_p6 = "false" +network_remote_enable_user_p7 = "false" +network_remote_enable_user_p8 = "false" +network_remote_enable_user_p9 = "false" +notification_show_autoconfig = "false" +notification_show_cheats_applied = "true" +notification_show_config_override_load = "false" +notification_show_fast_forward = "true" +notification_show_netplay_extra = "false" +notification_show_patch_applied = "true" +notification_show_refresh_rate = "true" +notification_show_remap_load = "false" +notification_show_screenshot_duration = "2" +notification_show_screenshot = "false" +notification_show_screenshot_flash = "1" +notification_show_set_initial_disk = "true" +overlay_directory = "/tmp/overlays" +ozone_collapse_sidebar = "false" +ozone_menu_color_theme = "1" +ozone_scroll_content_metadata = "false" +ozone_sort_after_truncate_playlist_name = "true" +ozone_truncate_playlist_name = "true" +pause_nonactive = "true" +perfcnt_enable = "false" +playlist_compression = "false" +playlist_cores = "" +playlist_directory = "~/playlists" +playlist_entry_remove_enable = "1" +playlist_entry_remove = "false" +playlist_entry_rename = "false" +playlist_fuzzy_archive_match = "false" +playlist_names = "" +playlist_portable_paths = "false" +playlist_show_entry_idx = "true" +playlist_show_inline_core_name = "0" +playlist_show_sublabels = "true" +playlist_sort_alphabetical = "true" +playlist_sublabel_last_played_style = "0" +playlist_sublabel_runtime_type = "0" +playlist_use_old_format = "false" +quick_menu_show_add_to_favorites = "true" +quick_menu_show_cheats = "true" +quick_menu_show_close_content = "true" +quick_menu_show_controls = "true" +quick_menu_show_core_options_flush = "false" +quick_menu_show_download_thumbnails = "true" +quick_menu_show_information = "true" +quick_menu_show_options = "true" +quick_menu_show_recording = "true" +quick_menu_show_reset_core_association = "true" +quick_menu_show_restart_content = "true" +quick_menu_show_resume_content = "true" +quick_menu_show_save_content_dir_overrides = "true" +quick_menu_show_save_core_overrides = "false" +quick_menu_show_save_game_overrides = "false" +quick_menu_show_save_load_state = "true" +quick_menu_show_set_core_association = "true" +quick_menu_show_shaders = "true" +quick_menu_show_start_recording = "true" +quick_menu_show_start_streaming = "true" +quick_menu_show_streaming = "true" +quick_menu_show_take_screenshot = "true" +quick_menu_show_undo_save_load_state = "false" +quit_on_close_content = "0" +quit_press_twice = "true" +record_driver = "null" +recording_config_directory = "" +recording_output_directory = "~/roms/screenshots" +resampler_directory = "" +rewind_buffer_size = "20971520" +rewind_buffer_size_step = "10" +rewind_enable = "false" +rewind_granularity = "1" +rgui_aspect_ratio = "0" +rgui_aspect_ratio_lock = "0" +rgui_background_filler_thickness_enable = "true" +rgui_border_filler_enable = "true" +rgui_border_filler_thickness_enable = "true" +rgui_browser_directory = "~/roms" +rgui_config_directory = "~/.config/retroarch/config" +rgui_extended_ascii = "false" +rgui_inline_thumbnails = "false" +rgui_internal_upscale_level = "0" +rgui_menu_color_theme = "4" +rgui_menu_theme_preset = "" +rgui_particle_effect = "0" +rgui_particle_effect_screensaver = "true" +rgui_particle_effect_speed = "1.000000" +rgui_show_start_screen = "false" +rgui_swap_thumbnails = "false" +rgui_switch_icons = "true" +rgui_thumbnail_delay = "0" +rgui_thumbnail_downscaler = "0" +run_ahead_enabled = "false" +run_ahead_frames = "1" +run_ahead_hide_warnings = "false" +run_ahead_secondary_instance = "true" +runtime_log_directory = "default" +save_file_compression = "false" +savefile_directory = "~/.config/retroarch/saves" +savefiles_in_content_dir = "true" +savestate_auto_index = "false" +savestate_auto_load = "false" +savestate_auto_save = "false" +savestate_directory = "~/.config/retroarch/states" +savestate_file_compression = "true" +savestate_max_keep = "0" +savestates_in_content_dir = "false" +savestate_thumbnail_enable = "true" +scan_without_core_match = "false" +screen_brightness = "100" +screen_orientation = "0" +screenshot_directory = "~/roms/screenshots" +screenshots_in_content_dir = "false" +settings_show_accessibility = "true" +settings_show_achievements = "true" +settings_show_ai_service = "true" +settings_show_audio = "true" +settings_show_configuration = "true" +settings_show_core = "true" +settings_show_directory = "true" +settings_show_drivers = "true" +settings_show_file_browser = "true" +settings_show_frame_throttle = "true" +settings_show_input = "true" +settings_show_latency = "true" +settings_show_logging = "true" +settings_show_network = "true" +settings_show_onscreen_display = "true" +settings_show_playlists = "true" +settings_show_power_management = "true" +settings_show_recording = "true" +settings_show_saving = "true" +settings_show_user_interface = "true" +settings_show_user = "true" +settings_show_video = "true" +show_hidden_files = "false" +slowmotion_ratio = "3.000000" +soft_filter_enable = "false" +soft_filter_index = "0" +sort_savefiles_by_content_enable = "false" +sort_savefiles_enable = "false" +sort_savestates_by_content_enable = "false" +sort_savestates_enable = "false" +sort_screenshots_by_content_enable = "false" +state_slot = "0" +statistics_show = "false" +stdin_cmd_enable = "false" +streaming_mode = "0" +suspend_screensaver_enable = "true" +sustained_performance_mode = "false" +system_directory = "~/roms/bios" +systemfiles_in_content_dir = "false" +threaded_data_runloop_enable = "true" +thumbnails_directory = "~/thumbnails" +twitch_stream_key = "" +ui_companion_enable = "false" +ui_companion_start_on_boot = "true" +ui_companion_toggle = "false" +ui_menubar_enable = "true" +use_last_start_directory = "false" +user_language = "0" +vibrate_on_keypress = "true" +video_adaptive_vsync = "false" +video_allow_rotate = "true" +video_aspect_ratio = "-1.000000" +video_aspect_ratio_auto = "true" +video_black_frame_insertion = "0" +video_context_driver = "" +video_crop_overscan = "true" +video_ctx_scaling = "false" +video_disable_composition = "false" +video_driver = "gl" +video_filter = "" +video_filter_dir = "~/.config/retroarch/filters/video" +video_font_enable = "true" +video_font_path = "/usr/share/retroarch-assets/xmb/monochrome/font.ttf" +video_font_size = "32.000000" +video_force_aspect = "true" +video_force_srgb_disable = "false" +video_frame_delay = "0" +video_frame_delay_auto = "false" +video_fullscreen = "true" +video_fullscreen_x = "854" +video_fullscreen_y = "480" +video_gpu_record = "false" +video_gpu_screenshot = "false" +video_hard_sync = "false" +video_hard_sync_frames = "0" +video_hdr_display_contrast = "5.000000" +video_hdr_enable = "false" +video_hdr_expand_gamut = "true" +video_hdr_max_nits = "1000.000000" +video_hdr_paper_white_nits = "200.000000" +video_layout_directory = "~/.config/retroarch/layouts" +video_layout_enable = "true" +video_layout_path = "" +video_layout_selected_view = "0" +video_max_swapchain_images = "3" +video_message_color = "ffff00" +video_message_pos_x = "0.049999" +video_message_pos_y = "0.049999" +video_monitor_index = "0" +video_msg_bgcolor_blue = "0" +video_msg_bgcolor_enable = "false" +video_msg_bgcolor_green = "0" +video_msg_bgcolor_opacity = "1.000000" +video_msg_bgcolor_red = "0" +video_notch_write_over_enable = "false" +video_oga_vertical_enable = "false" +video_post_filter_record = "false" +video_record_config = "" +video_record_quality = "4" +video_record_scale_factor = "1" +video_record_threads = "2" +video_refresh_rate = "60.000000" +video_rotation = "0" +video_scale = "3.000000" +video_scale_integer = "false" +video_scale_integer_overscale = "false" +video_shader_delay = "0" +video_shader_dir = "/tmp/shaders" +video_shader_enable = "false" +video_shader_preset_save_reference_enable = "true" +video_shader_remember_last_dir = "false" +video_shader_watch_files = "false" +video_shared_context = "false" +video_smooth = "false" +video_stream_config = "" +video_stream_port = "56400" +video_stream_quality = "10" +video_stream_scale_factor = "1" +video_stream_url = "" +video_swap_interval = "1" +video_threaded = "true" +video_vsync = "true" +video_window_auto_height_max = "480" +video_window_auto_width_max = "854" +video_window_custom_size_enable = "false" +video_windowed_fullscreen = "false" +video_windowed_position_height = "720" +video_windowed_position_width = "1280" +video_windowed_position_x = "0" +video_windowed_position_y = "0" +video_window_opacity = "100" +video_window_save_positions = "false" +video_window_show_decorations = "true" +vrr_runloop_enable = "false" +wifi_driver = "null" +wifi_enabled = "true" +xmb_alpha_factor = "75" +xmb_font = "/usr/share/retroarch-assets/xmb/monochrome/font.ttf" +xmb_layout = "2" +xmb_menu_color_theme = "4" +xmb_shadows_enable = "true" +xmb_theme = "0" +xmb_vertical_thumbnails = "false" +youtube_stream_key = "" +menu_driver = "ozone" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/S922X/retroarch32bit-append.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/S922X/retroarch32bit-append.cfg new file mode 100644 index 0000000000..343124c254 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/S922X/retroarch32bit-append.cfg @@ -0,0 +1,3 @@ +audio_filter_dir = "/usr/share/retroarch/filters/32bit/audio" +video_filter_dir = "/usr/share/retroarch/filters/32bit/video" +libretro_directory = /usr/lib32/libretro diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/S922X/retroarch64bit-append.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/S922X/retroarch64bit-append.cfg new file mode 100644 index 0000000000..b6cbf68312 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/S922X/retroarch64bit-append.cfg @@ -0,0 +1,2 @@ +audio_filter_dir = "/usr/share/retroarch/filters/64bit/audio" +video_filter_dir = "/usr/share/retroarch/filters/64bit/video" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/SDM845/TATE-MAME 2003-Plus.rmp b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SDM845/TATE-MAME 2003-Plus.rmp new file mode 100755 index 0000000000..366e47afad --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SDM845/TATE-MAME 2003-Plus.rmp @@ -0,0 +1,27 @@ +input_libretro_device_p1 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_player1_analog_dpad_mode = "1" +input_player1_btn_down = "6" +input_player1_btn_left = "4" +input_player1_btn_right = "5" +input_player1_btn_up = "7" +input_player1_stk_l_x+ = "5" +input_player1_stk_l_x- = "4" +input_player1_stk_l_y+ = "6" +input_player1_stk_l_y- = "7" +input_player1_stk_r_x+ = "5" +input_player1_stk_r_x- = "4" +input_player1_stk_r_y+ = "6" +input_player1_stk_r_y- = "7" +input_player2_analog_dpad_mode = "0" +input_player3_analog_dpad_mode = "0" +input_player4_analog_dpad_mode = "0" +input_player5_analog_dpad_mode = "0" +input_remap_port_p1 = "0" +input_remap_port_p2 = "1" +input_remap_port_p3 = "2" +input_remap_port_p4 = "3" +input_remap_port_p5 = "4" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/SDM845/retroarch-core-options.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SDM845/retroarch-core-options.cfg new file mode 100755 index 0000000000..0bcbaa2661 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SDM845/retroarch-core-options.cfg @@ -0,0 +1,152 @@ +mupen64plus-alt-map = "False" +mupen64plus-aspect = "4:3" +mupen64plus-astick-deadzone = "15" +mupen64plus-astick-sensitivity = "100" +mupen64plus-BackgroundMode = "Stripped" +mupen64plus-BilinearMode = "standard" +mupen64plus-CorrectTexrectCoords = "Auto" +mupen64plus-CountPerOp = "0" +mupen64plus-CountPerOpDenomPot = "0" +mupen64plus-cpucore = "dynamic_recompiler" +mupen64plus-d-cbutton = "C3" +mupen64plus-DitheringPattern = "True" +mupen64plus-DitheringQuantization = "True" +mupen64plus-EnableCopyAuxToRDRAM = "True" +mupen64plus-EnableCopyColorToRDRAM = "Async" +mupen64plus-EnableCopyDepthToRDRAM = "Software" +mupen64plus-EnableEnhancedHighResStorage = "False" +mupen64plus-EnableEnhancedTextureStorage = "False" +mupen64plus-EnableFBEmulation = "True" +mupen64plus-EnableFragmentDepthWrite = "False" +mupen64plus-EnableHiResAltCRC = "False" +mupen64plus-EnableHWLighting = "True" +mupen64plus-EnableInaccurateTextureCoordinates = "False" +mupen64plus-EnableLegacyBlending = "False" +mupen64plus-EnableLODEmulation = "True" +mupen64plus-EnableNativeResFactor = "1" +mupen64plus-EnableNativeResTexrects = "Optimized" +mupen64plus-EnableOverscan = "Enabled" +mupen64plus-EnableTexCoordBounds = "False" +mupen64plus-EnableTextureCache = "True" +mupen64plus-ForceDisableExtraMem = "False" +mupen64plus-FrameDuping = "True" +mupen64plus-Framerate = "Original" +mupen64plus-FXAA = "0" +mupen64plus-GLideN64IniBehaviour = "late" +mupen64plus-HybridFilter = "True" +mupen64plus-IgnoreTLBExceptions = "False" +mupen64plus-l-cbutton = "C2" +mupen64plus-MaxHiResTxVramLimit = "0" +mupen64plus-MaxTxCacheSize = "8000" +mupen64plus-MultiSampling = "0" +mupen64plus-OverscanBottom = "0" +mupen64plus-OverscanLeft = "0" +mupen64plus-OverscanRight = "0" +mupen64plus-OverscanTop = "0" +mupen64plus-pak1 = "memory" +mupen64plus-pak2 = "none" +mupen64plus-pak3 = "none" +mupen64plus-pak4 = "none" +mupen64plus-r-cbutton = "C1" +mupen64plus-rdp-plugin = "gliden64" +mupen64plus-RDRAMImageDitheringMode = "BlueNoise" +mupen64plus-rsp-plugin = "hle" +mupen64plus-ThreadedRenderer = "True" +mupen64plus-txCacheCompression = "True" +mupen64plus-txEnhancementMode = "None" +mupen64plus-txFilterIgnoreBG = "True" +mupen64plus-txFilterMode = "None" +mupen64plus-txHiresEnable = "False" +mupen64plus-txHiresFullAlphaChannel = "False" +mupen64plus-u-cbutton = "C4" +mupen64plus-virefresh = "Auto" +pcsx_rearmed_analog_axis_modifier = "circle" +pcsx_rearmed_async_cd = "sync" +pcsx_rearmed_bios = "auto" +pcsx_rearmed_display_internal_fps = "disabled" +pcsx_rearmed_dithering = "enabled" +pcsx_rearmed_drc = "enabled" +pcsx_rearmed_duping_enable = "enabled" +pcsx_rearmed_frameskip_type = "disabled" +pcsx_rearmed_gteregsunneeded = "disabled" +pcsx_rearmed_gunconadjustratiox = "1" +pcsx_rearmed_gunconadjustratioy = "1" +pcsx_rearmed_gunconadjustx = "0" +pcsx_rearmed_gunconadjusty = "0" +pcsx_rearmed_idiablofix = "disabled" +pcsx_rearmed_input_sensitivity = "1.00" +pcsx_rearmed_inuyasha_fix = "disabled" +pcsx_rearmed_memcard2 = "disabled" +pcsx_rearmed_multitap1 = "auto" +pcsx_rearmed_multitap2 = "auto" +pcsx_rearmed_negcon_deadzone = "0" +pcsx_rearmed_negcon_response = "linear" +pcsx_rearmed_neon_enhancement_enable = "disabled" +pcsx_rearmed_neon_enhancement_no_main = "disabled" +pcsx_rearmed_neon_interlace_enable = "disabled" +pcsx_rearmed_nocdaudio = "enabled" +pcsx_rearmed_nogteflags = "disabled" +pcsx_rearmed_nosmccheck = "disabled" +pcsx_rearmed_noxadecoding = "enabled" +pcsx_rearmed_pad1type = "standard" +pcsx_rearmed_pad2type = "standard" +pcsx_rearmed_pad3type = "none" +pcsx_rearmed_pad4type = "none" +pcsx_rearmed_pad5type = "none" +pcsx_rearmed_pad6type = "none" +pcsx_rearmed_pad7type = "none" +pcsx_rearmed_pad8type = "none" +pcsx_rearmed_pe2_fix = "disabled" +pcsx_rearmed_psxclock = "57" +pcsx_rearmed_region = "auto" +pcsx_rearmed_show_bios_bootlogo = "disabled" +pcsx_rearmed_show_other_input_settings = "disabled" +pcsx_rearmed_spu_interpolation = "simple" +pcsx_rearmed_spu_reverb = "enabled" +pcsx_rearmed_spuirq = "disabled" +pcsx_rearmed_vibration = "enabled" +gambatte_gb_colorization = "disabled" +gambatte_gb_internal_palette = "" +mame2003-plus_analog = "digital" +mame2003-plus_art_resolution = "1" +mame2003-plus_brightness = "1.0" +mame2003-plus_cheat_input_ports = "disabled" +mame2003-plus_core_save_subfolder = "enabled" +mame2003-plus_core_sys_subfolder = "enabled" +mame2003-plus_dcs_speedhack = "enabled" +mame2003-plus_deadzone = "20" +mame2003-plus_digital_joy_centering = "enabled" +mame2003-plus_display_artwork = "enabled" +mame2003-plus_display_setup = "disabled" +mame2003-plus_four_way_emulation = "disabled" +mame2003-plus_frameskip = "0" +mame2003-plus_gamma = "1.0" +mame2003-plus_input_interface = "retropad" +mame2003-plus_machine_timing = "enabled" +mame2003-plus_mame_remapping = "enabled" +mame2003-plus_mouse_device = "mouse" +mame2003-plus_sample_rate = "48000" +mame2003-plus_skip_disclaimer = "disabled" +mame2003-plus_skip_warnings = "disabled" +flycast_internal_resolution = "640x480" +flycast_alpha_sorting = "per-strip (fast, least accurate)" +flycast_enable_dsp = "disabled" +flycast_threaded_rendering = "enabled" +flycast_anisotropic_filtering = "off" +flycast_synchronous_rendering = "enabled" +flycast_enable_rtt = "disabled" +flycast_enable_rttb = "disabled" +flycast_delay_frame_swapping = "disabled" +flycast_div_matching = "auto" +flycast_texupscale = "off" +flycast_auto_skip_frame = "normal" +opera_swi_hle = "enabled" +opera_dsp_threaded = "enabled" +opera_madam_matrix_engine = "software" +puae_deadzone = "25" +melonds_screen_layout = "Left/Right" +melonds_swapscreen_mode = "Toggle" +melonds_threaded_renderer = "enabled" +melonds_touch_mode = "Joystick" +virtualjaguar_bios = "enabled" +virtualjaguar_usefastblitter = "enabled" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/SDM845/retroarch.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SDM845/retroarch.cfg new file mode 100644 index 0000000000..d387d760d7 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SDM845/retroarch.cfg @@ -0,0 +1,894 @@ +accessibility_enable = "false" +accessibility_narrator_speech_speed = "5" +ai_service_mode = "1" +ai_service_pause = "false" +ai_service_source_lang = "0" +ai_service_target_lang = "0" +all_users_control_menu = "true" +app_icon = "default" +apply_cheats_after_load = "false" +apply_cheats_after_toggle = "false" +audio_block_frames = "0" +audio_device = "" +audio_driver = "alsathread" +audio_dsp_plugin = "" +audio_enable = "true" +audio_enable_menu = "false" +audio_enable_menu_bgm = "false" +audio_enable_menu_cancel = "false" +audio_enable_menu_notice = "false" +audio_enable_menu_ok = "false" +audio_enable_menu_scroll = "false" +audio_fastforward_mute = "false" +audio_fastforward_speedup = "false" +audio_max_timing_skew = "0.049999" +audio_mixer_mute_enable = "false" +audio_mixer_volume = "0.000000" +audio_mute_enable = "false" +audio_out_rate = "48000" +audio_rate_control = "true" +audio_rate_control_delta = "0.004999" +audio_resampler = "sinc" +audio_resampler_quality = "2" +audio_sync = "true" +audio_volume = "0.000000" +auto_overrides_enable = "true" +auto_remaps_enable = "true" +auto_screenshot_filename = "true" +auto_shaders_enable = "true" +autosave_interval = "10" +block_sram_overwrite = "false" +bluetooth_driver = "null" +builtin_imageviewer_enable = "false" +builtin_mediaplayer_enable = "true" +bundle_assets_dst_path = "" +bundle_assets_dst_path_subdir = "" +bundle_assets_extract_enable = "false" +bundle_assets_extract_last_version = "0" +bundle_assets_extract_version_current = "0" +bundle_assets_src_path = "" +camera_allow = "false" +camera_device = "" +camera_driver = "null" +check_firmware_before_loading = "false" +cheevos_appearance_anchor = "0" +cheevos_appearance_padding_auto = "true" +cheevos_appearance_padding_h = "0.000000" +cheevos_appearance_padding_v = "0.000000" +cheevos_auto_screenshot = "false" +cheevos_badges_enable = "false" +cheevos_challenge_indicators = "true" +cheevos_custom_host = "" +cheevos_hardcore_mode_enable = "false" +cheevos_leaderboards_enable = "" +cheevos_password = "" +cheevos_richpresence_enable = "true" +cheevos_start_active = "false" +cheevos_test_unofficial = "false" +cheevos_token = "" +cheevos_unlock_sound_enable = "false" +cheevos_username = "" +cheevos_verbose_enable = "false" +cheevos_visibility_account = "true" +cheevos_visibility_lboard_cancel = "true" +cheevos_visibility_lboard_start = "true" +cheevos_visibility_lboard_submit = "true" +cheevos_visibility_lboard_trackers = "true" +cheevos_visibility_mastery = "true" +cheevos_visibility_progress_tracker = "true" +cheevos_visibility_summary = "1" +cheevos_visibility_unlock = "true" +cloud_sync_destructive = "false" +cloud_sync_driver = "" +cloud_sync_enable = "false" +config_save_on_exit = "false" +content_favorites_directory = "default" +content_favorites_path = "~/.config/retroarch/content_favorites.lpl" +content_favorites_size = "200" +content_history_dir = "" +content_history_directory = "default" +content_history_path = "~/.config/retroarch/content_history.lpl" +content_history_size = "200" +content_image_history_directory = "default" +content_image_history_path = "~/.config/retroarch/content_image_history.lpl" +content_music_history_directory = "default" +content_music_history_path = "~/.config/retroarch/content_music_history.lpl" +content_runtime_log = "true" +content_runtime_log_aggregate = "false" +content_show_add = "true" +content_show_add_entry = "2" +content_show_contentless_cores = "2" +content_show_explore = "true" +content_show_favorites = "true" +content_show_history = "true" +content_show_images = "false" +content_show_music = "false" +content_show_netplay = "true" +content_show_playlists = "true" +content_show_settings = "true" +content_show_settings_password = "" +content_show_video = "false" +content_video_directory = "default" +content_video_history_path = "~/.config/retroarch/content_video_history.lpl" +core_assets_directory = "~/roms/downloads" +core_info_cache_enable = "true" +core_info_savestate_bypass = "false" +core_option_category_enable = "true" +core_options_path = "" +core_set_supports_no_game_enable = "true" +core_updater_auto_backup = "false" +core_updater_auto_backup_history_size = "1" +core_updater_auto_extract_archive = "true" +core_updater_buildbot_assets_url = "http://buildbot.libretro.com/assets/" +core_updater_buildbot_cores_url = "" +core_updater_buildbot_url = "http://buildbot.libretro.com/nightly/linux/armhf/latest/" +core_updater_show_experimental_cores = "false" +cpu_main_gov = "performance" +cpu_max_freq = "-1" +cpu_menu_gov = "interactive" +cpu_min_freq = "1" +cpu_scaling_mode = "0" +crt_switch_center_adjust = "0" +crt_switch_hires_menu = "false" +crt_switch_porch_adjust = "0" +crt_switch_resolution = "0" +crt_switch_resolution_super = "2560" +crt_switch_resolution_use_custom_refresh_rate = "false" +crt_switch_timings = "" +crt_video_refresh_rate = "60.000000" +current_resolution_id = "0" +cursor_directory = "~/.config/retroarch/database/cursors" +custom_viewport_height = "1080" +custom_viewport_width = "1920" +custom_viewport_x = "0" +custom_viewport_y = "0" +desktop_menu_enable = "true" +discord_allow = "false" +discord_app_id = "475456035851599874" +driver_switch_enable = "true" +dynamic_wallpapers_directory = "default" +emuelec_exit_to_kodi = "false" +enable_device_vibration = "true" +facebook_stream_key = "" +fastforward_frameskip = "true" +fastforward_ratio = "0.000000" +filter_by_current_core = "false" +flicker_filter_enable = "false" +flicker_filter_index = "0" +fps_update_interval = "256" +frame_time_counter_reset_after_fastforwarding = "false" +frame_time_counter_reset_after_load_state = "false" +frame_time_counter_reset_after_save_state = "false" +framecount_show = "false" +frontend_log_level = "1" +game_specific_options = "true" +gamemode_enable = "false" +gamma_correction = "0" +global_core_options = "false" +history_list_enable = "true" +initial_disk_change_enable = "true" +input_ai_service = "nul" +input_ai_service_axis = "nul" +input_ai_service_btn = "nul" +input_ai_service_mbtn = "nul" +input_allow_turbo_dpad = "false" +input_analog_deadzone = "0.100000" +input_analog_sensitivity = "1.500000" +input_audio_mute = "nul" +input_audio_mute_axis = "nul" +input_audio_mute_btn = "nul" +input_audio_mute_mbtn = "nul" +input_auto_game_focus = "0" +input_auto_mouse_grab = "false" +input_autodetect_enable = "true" +input_axis_threshold = "0.500000" +input_bind_hold = "2" +input_bind_timeout = "5" +input_cheat_index_minus = "nul" +input_cheat_index_minus_axis = "nul" +input_cheat_index_minus_btn = "nul" +input_cheat_index_minus_mbtn = "nul" +input_cheat_index_plus = "nul" +input_cheat_index_plus_axis = "nul" +input_cheat_index_plus_btn = "nul" +input_cheat_index_plus_mbtn = "nul" +input_cheat_toggle = "nul" +input_cheat_toggle_axis = "nul" +input_cheat_toggle_btn = "nul" +input_cheat_toggle_mbtn = "nul" +input_close_content = "nul" +input_close_content_axis = "nul" +input_close_content_btn = "nul" +input_close_content_mbtn = "nul" +input_descriptor_hide_unbound = "false" +input_descriptor_label_show = "true" +input_desktop_menu_toggle = "nul" +input_desktop_menu_toggle_axis = "nul" +input_desktop_menu_toggle_btn = "nul" +input_desktop_menu_toggle_mbtn = "nul" +input_device_p1 = "0" +input_device_p10 = "0" +input_device_p11 = "0" +input_device_p12 = "0" +input_device_p13 = "0" +input_device_p14 = "0" +input_device_p15 = "0" +input_device_p16 = "0" +input_device_p2 = "0" +input_device_p3 = "0" +input_device_p4 = "0" +input_device_p5 = "0" +input_device_p6 = "0" +input_device_p7 = "0" +input_device_p8 = "0" +input_device_p9 = "0" +input_disk_eject_toggle = "nul" +input_disk_eject_toggle_axis = "nul" +input_disk_eject_toggle_btn = "nul" +input_disk_eject_toggle_mbtn = "nul" +input_disk_next = "nul" +input_disk_next_axis = "nul" +input_disk_next_btn = "nul" +input_disk_next_mbtn = "nul" +input_disk_prev = "nul" +input_disk_prev_axis = "nul" +input_disk_prev_btn = "nul" +input_disk_prev_mbtn = "nul" +input_driver = "udev" +input_duty_cycle = "3" +input_enable_hotkey = "nul" +input_enable_hotkey_axis = "nul" +input_enable_hotkey_btn = "nul" +input_enable_hotkey_mbtn = "nul" +input_exit_emulator = "nul" +input_exit_emulator_axis = "nul" +input_exit_emulator_btn = "nul" +input_exit_emulator_mbtn = "nul" +input_fps_toggle = "nul" +input_fps_toggle_axis = "nul" +input_fps_toggle_btn = "nul" +input_fps_toggle_mbtn = "nul" +input_frame_advance = "nul" +input_frame_advance_axis = "nul" +input_frame_advance_btn = "nul" +input_frame_advance_mbtn = "nul" +input_game_focus_toggle = "nul" +input_game_focus_toggle_axis = "nul" +input_game_focus_toggle_btn = "nul" +input_game_focus_toggle_mbtn = "nul" +input_grab_mouse_toggle = "nul" +input_grab_mouse_toggle_axis = "nul" +input_grab_mouse_toggle_btn = "nul" +input_grab_mouse_toggle_mbtn = "nul" +input_halt_replay = "nul" +input_halt_replay_axis = "nul" +input_halt_replay_btn = "nul" +input_halt_replay_mbtn = "nul" +input_hold_fast_forward = "nul" +input_hold_fast_forward_axis = "nul" +input_hold_fast_forward_btn = "nul" +input_hold_fast_forward_mbtn = "nul" +input_hold_slowmotion = "nul" +input_hold_slowmotion_axis = "nul" +input_hold_slowmotion_btn = "nul" +input_hold_slowmotion_mbtn = "nul" +input_hotkey_block_delay = "5" +input_hotkey_device_merge = "false" +input_joypad_driver = "sdl2" +input_keyboard_layout = "" +input_libretro_device_p1 = "1" +input_libretro_device_p10 = "1" +input_libretro_device_p11 = "1" +input_libretro_device_p12 = "1" +input_libretro_device_p13 = "1" +input_libretro_device_p14 = "1" +input_libretro_device_p15 = "1" +input_libretro_device_p16 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_libretro_device_p6 = "1" +input_libretro_device_p7 = "1" +input_libretro_device_p8 = "1" +input_libretro_device_p9 = "1" +input_load_state = "nul" +input_load_state_axis = "nul" +input_load_state_btn = "nul" +input_load_state_mbtn = "nul" +input_max_users = "5" +input_menu_toggle = "nul" +input_menu_toggle_axis = "nul" +input_menu_toggle_btn = "nul" +input_menu_toggle_gamepad_combo = "nul" +input_menu_toggle_mbtn = "nul" +input_movie_record_toggle = "o" +input_movie_record_toggle_axis = "nul" +input_movie_record_toggle_btn = "nul" +input_movie_record_toggle_mbtn = "nul" +input_netplay_fade_chat_toggle = "nul" +input_netplay_fade_chat_toggle_axis = "nul" +input_netplay_fade_chat_toggle_btn = "nul" +input_netplay_fade_chat_toggle_mbtn = "nul" +input_netplay_game_watch = "nul" +input_netplay_game_watch_axis = "nul" +input_netplay_game_watch_btn = "nul" +input_netplay_game_watch_mbtn = "nul" +input_netplay_host_toggle = "nul" +input_netplay_host_toggle_axis = "nul" +input_netplay_host_toggle_btn = "nul" +input_netplay_host_toggle_mbtn = "nul" +input_netplay_ping_toggle = "nul" +input_netplay_ping_toggle_axis = "nul" +input_netplay_ping_toggle_btn = "nul" +input_netplay_ping_toggle_mbtn = "nul" +input_netplay_player_chat = "nul" +input_netplay_player_chat_axis = "nul" +input_netplay_player_chat_btn = "nul" +input_netplay_player_chat_mbtn = "nul" +input_nowinkey_enable = "false" +input_osk_overlay = "" +input_osk_overlay_auto_scale = "false" +input_osk_overlay_opacity = "0.700000" +input_osk_toggle = "nul" +input_osk_toggle_axis = "nul" +input_osk_toggle_btn = "nul" +input_osk_toggle_mbtn = "nul" +input_overlay = "" +input_overlay_aspect_adjust_landscape = "0.000000" +input_overlay_aspect_adjust_portrait = "0.000000" +input_overlay_auto_rotate = "false" +input_overlay_auto_scale = "false" +input_overlay_enable_autopreferred = "true" +input_overlay_enable = "false" +input_overlay_hide_in_menu = "true" +input_overlay_hide_when_gamepad_connected = "false" +input_overlay_next_axis = "nul" +input_overlay_next_btn = "nul" +input_overlay_next_mbtn = "nul" +input_overlay_next = "nul" +input_overlay_opacity = "0.700000" +input_overlay_scale_landscape = "1.000000" +input_overlay_scale_portrait = "1.000000" +input_overlay_show_inputs = "2" +input_overlay_show_inputs_port = "0" +input_overlay_show_mouse_cursor = "true" +input_overlay_x_offset_landscape = "0.000000" +input_overlay_x_offset_portrait = "0.000000" +input_overlay_x_separation_landscape = "0.000000" +input_overlay_x_separation_portrait = "0.000000" +input_overlay_y_offset_landscape = "0.000000" +input_overlay_y_offset_portrait = "0.000000" +input_overlay_y_separation_landscape = "0.000000" +input_overlay_y_separation_portrait = "0.000000" +input_pause_toggle = "nul" +input_pause_toggle_axis = "nul" +input_pause_toggle_btn = "nul" +input_pause_toggle_mbtn = "nul" +input_play_replay = "nul" +input_play_replay_axis = "nul" +input_play_replay_btn = "nul" +input_play_replay_mbtn = "nul" +input_poll_type_behavior = "2" +input_preempt_toggle = "nul" +input_preempt_toggle_axis = "nul" +input_preempt_toggle_btn = "nul" +input_preempt_toggle_mbtn = "nul" +input_quit_gamepad_combo = "0" +input_record_replay = "nul" +input_record_replay_axis = "nul" +input_record_replay_btn = "nul" +input_record_replay_mbtn = "nul" +input_recording_toggle = "nul" +input_recording_toggle_axis = "nul" +input_recording_toggle_btn = "nul" +input_recording_toggle_mbtn = "nul" +input_remap_binds_enable = "true" +input_remapping_directory = "~/remappings" +input_replay_slot_decrease = "nul" +input_replay_slot_decrease_axis = "nul" +input_replay_slot_decrease_btn = "nul" +input_replay_slot_decrease_mbtn = "nul" +input_replay_slot_increase = "nul" +input_replay_slot_increase_axis = "nul" +input_replay_slot_increase_btn = "nul" +input_replay_slot_increase_mbtn = "nul" +input_reset = "nul" +input_reset_axis = "nul" +input_reset_btn = "nul" +input_reset_mbtn = "nul" +input_rewind = "nul" +input_rewind_axis = "nul" +input_rewind_btn = "nul" +input_rewind_mbtn = "nul" +input_rumble_gain = "25" +input_runahead_toggle = "nul" +input_runahead_toggle_axis = "nul" +input_runahead_toggle_btn = "nul" +input_runahead_toggle_mbtn = "nul" +input_save_state = "nul" +input_save_state_axis = "nul" +input_save_state_btn = "nul" +input_save_state_mbtn = "nul" +input_screenshot = "nul" +input_screenshot_axis = "nul" +input_screenshot_btn = "nul" +input_screenshot_mbtn = "nul" +input_send_debug_info = "nul" +input_send_debug_info_axis = "nul" +input_send_debug_info_btn = "nul" +input_send_debug_info_mbtn = "nul" +input_sensors_enable = "true" +input_shader_next = "nul" +input_shader_next_axis = "nul" +input_shader_next_btn = "nul" +input_shader_next_mbtn = "nul" +input_shader_prev = "nul" +input_shader_prev_axis = "nul" +input_shader_prev_btn = "nul" +input_shader_prev_mbtn = "nul" +input_shader_toggle = "nul" +input_shader_toggle_axis = "nul" +input_shader_toggle_btn = "nul" +input_shader_toggle_mbtn = "nul" +input_state_slot_decrease = "nul" +input_state_slot_decrease_axis = "nul" +input_state_slot_decrease_btn = "nul" +input_state_slot_decrease_mbtn = "nul" +input_state_slot_increase = "nul" +input_state_slot_increase_axis = "nul" +input_state_slot_increase_btn = "nul" +input_state_slot_increase_mbtn = "nul" +input_streaming_toggle = "nul" +input_streaming_toggle_axis = "nul" +input_streaming_toggle_btn = "nul" +input_streaming_toggle_mbtn = "nul" +input_toggle_fast_forward = "nul" +input_toggle_fast_forward_axis = "nul" +input_toggle_fast_forward_btn = "nul" +input_toggle_fast_forward_mbtn = "nul" +input_toggle_fullscreen = "nul" +input_toggle_fullscreen_axis = "nul" +input_toggle_fullscreen_btn = "nul" +input_toggle_fullscreen_mbtn = "nul" +input_toggle_slowmotion = "nul" +input_toggle_slowmotion_axis = "nul" +input_toggle_slowmotion_btn = "nul" +input_toggle_slowmotion_mbtn = "nul" +input_toggle_statistics = "nul" +input_toggle_statistics_axis = "nul" +input_toggle_statistics_btn = "nul" +input_toggle_statistics_mbtn = "nul" +input_toggle_vrr_runloop = "nul" +input_toggle_vrr_runloop_axis = "nul" +input_toggle_vrr_runloop_btn = "nul" +input_toggle_vrr_runloop_mbtn = "nul" +input_touch_scale = "1" +input_touch_vmouse_gesture = "true" +input_touch_vmouse_mouse = "true" +input_touch_vmouse_pointer = "true" +input_touch_vmouse_touchpad = "true" +input_touch_vmouse_trackball = "false" +input_turbo_default_button = "0" +input_turbo_mode = "0" +input_turbo_period = "6" +input_volume_down = "nul" +input_volume_down_axis = "nul" +input_volume_down_btn = "nul" +input_volume_down_mbtn = "nul" +input_volume_up = "nul" +input_volume_up_axis = "nul" +input_volume_up_btn = "nul" +input_volume_up_mbtn = "nul" +keyboard_gamepad_enable = "true" +keyboard_gamepad_mapping_type = "1" +kiosk_mode_enable = "false" +kiosk_mode_password = "" +led_driver = "null" +libretro_log_level = "1" +load_dummy_on_core_shutdown = "true" +location_allow = "false" +location_driver = "null" +log_dir = "~/.config/retroarch/logs" +log_to_file = "true" +log_to_file_timestamp = "false" +log_verbosity = "true" +materialui_auto_rotate_nav_bar = "true" +materialui_dual_thumbnail_list_view_enable = "true" +materialui_icons_enable = "true" +materialui_landscape_layout_optimization = "1" +materialui_menu_color_theme = "9" +materialui_menu_transition_animation = "0" +materialui_playlist_icons_enable = "true" +materialui_show_nav_bar = "true" +materialui_switch_icons = "true" +materialui_thumbnail_background_enable = "true" +materialui_thumbnail_view_landscape = "2" +materialui_thumbnail_view_portrait = "1" +memory_show = "false" +memory_update_interval = "256" +menu_battery_level_enable = "true" +menu_core_enable = "true" +menu_disable_info_button = "false" +menu_disable_search_button = "false" +menu_driver = "ozone" +menu_dynamic_wallpaper_enable = "false" +menu_enable_widgets = "true" +menu_font_color_blue = "255" +menu_font_color_green = "255" +menu_font_color_red = "255" +menu_footer_opacity = "1.000000" +menu_framebuffer_opacity = "0.899999" +menu_header_opacity = "1.000000" +menu_horizontal_animation = "true" +menu_insert_disk_resume = "true" +menu_left_thumbnails = "0" +menu_linear_filter = "false" +menu_mouse_enable = "false" +menu_navigation_browser_filter_supported_extensions_enable = "true" +menu_navigation_wraparound_enable = "true" +menu_pause_libretro = "true" +menu_pointer_enable = "true" +menu_remember_selection = "1" +menu_rgui_full_width_layout = "true" +menu_rgui_shadows = "false" +menu_rgui_transparency = "true" +menu_savestate_resume = "true" +menu_scale_factor = "0.300000" +menu_screensaver_animation = "0" +menu_screensaver_animation_speed = "1.000000" +menu_screensaver_timeout = "0" +menu_scroll_delay = "256" +menu_scroll_fast = "false" +menu_shader_pipeline = "2" +menu_show_advanced_settings = "true" +menu_show_configurations = "true" +menu_show_core_updater = "false" +menu_show_dump_disc = "true" +menu_show_help = "true" +menu_show_information = "true" +menu_show_latency = "true" +menu_show_legacy_thumbnail_updater = "false" +menu_show_load_content = "true" +menu_show_load_content_animation = "false" +menu_show_load_core = "true" +menu_show_load_disc = "true" +menu_show_online_updater = "true" +menu_show_overlays = "true" +menu_show_quit_retroarch = "true" +menu_show_reboot = "false" +menu_show_restart_retroarch = "true" +menu_show_rewind = "true" +menu_show_shutdown = "false" +menu_show_sublabels = "true" +menu_show_video_layout = "true" +menu_swap_ok_cancel_buttons = "false" +menu_swap_scroll_buttons = "false" +menu_throttle_framerate = "true" +menu_thumbnail_upscale_threshold = "0" +menu_thumbnails = "3" +menu_ticker_smooth = "true" +menu_ticker_speed = "2.000000" +menu_ticker_type = "1" +menu_timedate_date_separator = "0" +menu_timedate_enable = "true" +menu_timedate_style = "11" +menu_unified_controls = "false" +menu_use_preferred_system_color_theme = "false" +menu_wallpaper = "" +menu_wallpaper_opacity = "1.000000" +menu_widget_scale_auto = "false" +menu_widget_scale_factor = "0.350000" +menu_widget_scale_factor_windowed = "1.000000" +menu_xmb_animation_horizontal_highlight = "0" +menu_xmb_animation_move_up_down = "0" +menu_xmb_animation_opening_main_menu = "0" +menu_xmb_show_title_header = "true" +menu_xmb_thumbnail_scale_factor = "100" +menu_xmb_title_margin = "5" +menu_xmb_title_margin_horizontal_offset = "0" +menu_xmb_vertical_fade_factor = "100" +microphone_block_frames = "0" +microphone_device = "" +microphone_driver = "alsathread" +microphone_enable = "true" +microphone_latency = "64" +microphone_rate = "48000" +microphone_resampler = "sinc" +microphone_resampler_quality = "3" +midi_driver = "alsa" +midi_input = "OFF" +midi_output = "OFF" +midi_volume = "100" +network_cmd_enable = "false" +network_cmd_port = "55355" +network_on_demand_thumbnails = "false" +network_remote_base_port = "55400" +network_remote_enable = "false" +network_remote_enable_user_p1 = "false" +network_remote_enable_user_p10 = "false" +network_remote_enable_user_p11 = "false" +network_remote_enable_user_p12 = "false" +network_remote_enable_user_p13 = "false" +network_remote_enable_user_p14 = "false" +network_remote_enable_user_p15 = "false" +network_remote_enable_user_p16 = "false" +network_remote_enable_user_p2 = "false" +network_remote_enable_user_p3 = "false" +network_remote_enable_user_p4 = "false" +network_remote_enable_user_p5 = "false" +network_remote_enable_user_p6 = "false" +network_remote_enable_user_p7 = "false" +network_remote_enable_user_p8 = "false" +network_remote_enable_user_p9 = "false" +notification_show_autoconfig = "false" +notification_show_cheats_applied = "true" +notification_show_config_override_load = "false" +notification_show_disk_control = "true" +notification_show_fast_forward = "true" +notification_show_netplay_extra = "false" +notification_show_patch_applied = "true" +notification_show_refresh_rate = "true" +notification_show_remap_load = "false" +notification_show_save_state = "true" +notification_show_screenshot = "false" +notification_show_screenshot_duration = "2" +notification_show_screenshot_flash = "1" +notification_show_set_initial_disk = "true" +notification_show_when_menu_is_alive = "false" +osk_overlay_directory = "/tmp/overlays/keyboards" +ozone_collapse_sidebar = "false" +ozone_menu_color_theme = "1" +ozone_scroll_content_metadata = "false" +ozone_sort_after_truncate_playlist_name = "true" +ozone_thumbnail_scale_factor = "1.000000" +ozone_truncate_playlist_name = "true" +pause_nonactive = "true" +pause_on_disconnect = "false" +perfcnt_enable = "false" +playlist_compression = "false" +playlist_cores = "" +playlist_directory = "~/playlists" +playlist_entry_remove = "false" +playlist_entry_remove_enable = "1" +playlist_entry_rename = "false" +playlist_fuzzy_archive_match = "false" +playlist_names = "" +playlist_portable_paths = "false" +playlist_show_entry_idx = "true" +playlist_show_history_icons = "1" +playlist_show_inline_core_name = "0" +playlist_show_sublabels = "true" +playlist_sort_alphabetical = "true" +playlist_sublabel_last_played_style = "0" +playlist_sublabel_runtime_type = "0" +playlist_use_filename = "false" +playlist_use_old_format = "false" +preemptive_frames_enable = "false" +preemptive_frames_hide_warnings = "false" +quick_menu_show_add_to_favorites = "true" +quick_menu_show_add_to_playlist = "false" +quick_menu_show_cheats = "true" +quick_menu_show_close_content = "true" +quick_menu_show_controls = "true" +quick_menu_show_core_options_flush = "false" +quick_menu_show_download_thumbnails = "true" +quick_menu_show_information = "true" +quick_menu_show_options = "true" +quick_menu_show_recording = "true" +quick_menu_show_replay = "false" +quick_menu_show_reset_core_association = "true" +quick_menu_show_restart_content = "true" +quick_menu_show_resume_content = "true" +quick_menu_show_save_content_dir_overrides = "true" +quick_menu_show_save_core_overrides = "false" +quick_menu_show_save_game_overrides = "false" +quick_menu_show_save_load_state = "true" +quick_menu_show_savestate_submenu = "true" +quick_menu_show_set_core_association = "true" +quick_menu_show_shaders = "true" +quick_menu_show_start_recording = "true" +quick_menu_show_start_streaming = "true" +quick_menu_show_streaming = "true" +quick_menu_show_take_screenshot = "true" +quick_menu_show_undo_save_load_state = "false" +quit_on_close_content = "0" +quit_press_twice = "true" +record_driver = "null" +recording_config_directory = "" +recording_output_directory = "~/roms/screenshots" +remap_save_on_exit = "true" +replay_auto_index = "true" +replay_checkpoint_interval = "0" +replay_max_keep = "0" +replay_slot = "0" +resampler_directory = "" +rewind_buffer_size = "20971520" +rewind_buffer_size_step = "10" +rewind_granularity = "1" +rgui_aspect_ratio = "0" +rgui_aspect_ratio_lock = "0" +rgui_background_filler_thickness_enable = "true" +rgui_border_filler_enable = "true" +rgui_border_filler_thickness_enable = "true" +rgui_browser_directory = "~/roms" +rgui_config_directory = "~/.config/retroarch/config" +rgui_extended_ascii = "false" +rgui_inline_thumbnails = "false" +rgui_internal_upscale_level = "0" +rgui_menu_color_theme = "4" +rgui_menu_theme_preset = "" +rgui_particle_effect = "0" +rgui_particle_effect_screensaver = "true" +rgui_particle_effect_speed = "1.000000" +rgui_show_start_screen = "false" +rgui_swap_thumbnails = "false" +rgui_switch_icons = "true" +rgui_thumbnail_delay = "0" +rgui_thumbnail_downscaler = "0" +run_ahead_hide_warnings = "false" +run_ahead_secondary_instance = "true" +runtime_log_directory = "default" +save_file_compression = "false" +savefile_directory = "~/.config/retroarch/saves" +savefiles_in_content_dir = "true" +savestate_file_compression = "true" +savestate_thumbnail_enable = "true" +savestates_in_content_dir = "false" +scan_serial_and_crc = "false" +scan_without_core_match = "false" +screen_brightness = "100" +screen_orientation = "0" +screenshot_directory = "~/roms/screenshots" +screenshots_in_content_dir = "false" +settings_show_accessibility = "true" +settings_show_achievements = "true" +settings_show_ai_service = "true" +settings_show_audio = "true" +settings_show_configuration = "true" +settings_show_core = "true" +settings_show_directory = "true" +settings_show_drivers = "true" +settings_show_file_browser = "true" +settings_show_frame_throttle = "true" +settings_show_input = "true" +settings_show_latency = "true" +settings_show_logging = "true" +settings_show_network = "true" +settings_show_onscreen_display = "true" +settings_show_playlists = "true" +settings_show_power_management = "true" +settings_show_recording = "true" +settings_show_saving = "true" +settings_show_user = "true" +settings_show_user_interface = "true" +settings_show_video = "true" +show_hidden_files = "false" +slowmotion_ratio = "3.000000" +soft_filter_enable = "false" +soft_filter_index = "0" +sort_savefiles_by_content_enable = "false" +sort_savefiles_enable = "false" +sort_savestates_by_content_enable = "false" +sort_savestates_enable = "false" +sort_screenshots_by_content_enable = "false" +statistics_show = "false" +stdin_cmd_enable = "false" +streaming_mode = "0" +suspend_screensaver_enable = "true" +sustained_performance_mode = "false" +system_directory = "~/roms/bios" +systemfiles_in_content_dir = "false" +test_input_file_joypad = "" +threaded_data_runloop_enable = "true" +thumbnails_directory = "~/thumbnails" +twitch_stream_key = "" +ui_companion_enable = "false" +ui_companion_start_on_boot = "true" +ui_companion_toggle = "false" +ui_menubar_enable = "true" +use_last_start_directory = "false" +user_language = "0" +vibrate_on_keypress = "true" +video_adaptive_vsync = "false" +video_allow_rotate = "true" +video_aspect_ratio = "-1.000000" +video_aspect_ratio_auto = "true" +video_autoswitch_pal_threshold = "54.500000" +video_autoswitch_refresh_rate = "0" +video_bfi_dark_frames = "1" +video_black_frame_insertion = "0" +video_context_driver = "" +video_crop_overscan = "true" +video_disable_composition = "false" +video_driver = "glcore" +video_font_enable = "true" +video_font_path = "/usr/share/retroarch-assets/xmb/monochrome/font.ttf" +video_font_size = "32.000000" +video_force_aspect = "true" +video_force_srgb_disable = "false" +video_frame_delay = "0" +video_frame_delay_auto = "false" +video_frame_rest = "false" +video_fullscreen = "true" +video_fullscreen_x = "1920" +video_fullscreen_y = "1080" +video_gpu_record = "false" +video_gpu_screenshot = "false" +video_hard_sync = "false" +video_hard_sync_frames = "0" +video_hdr_display_contrast = "5.000000" +video_hdr_enable = "false" +video_hdr_expand_gamut = "true" +video_hdr_max_nits = "1000.000000" +video_hdr_paper_white_nits = "200.000000" +video_layout_directory = "~/.config/retroarch/layouts" +video_layout_enable = "true" +video_layout_path = "" +video_layout_selected_view = "0" +video_max_frame_latency = "1" +video_max_swapchain_images = "3" +video_message_color = "ffff00" +video_message_pos_x = "0.049999" +video_message_pos_y = "0.049999" +video_monitor_index = "0" +video_msg_bgcolor_blue = "0" +video_msg_bgcolor_enable = "false" +video_msg_bgcolor_green = "0" +video_msg_bgcolor_opacity = "1.000000" +video_msg_bgcolor_red = "0" +video_notch_write_over_enable = "false" +video_oga_vertical_enable = "false" +video_post_filter_record = "false" +video_record_config = "" +video_record_quality = "4" +video_record_scale_factor = "1" +video_record_threads = "2" +video_refresh_rate = "60.000000" +video_scale = "3" +video_scan_subframes = "false" +video_shared_context = "false" +video_stream_config = "" +video_stream_port = "56400" +video_stream_quality = "10" +video_stream_scale_factor = "1" +video_stream_url = "" +video_swap_interval = "1" +video_threaded = "false" +video_vsync = "true" +video_waitable_swapchains = "true" +video_window_auto_height_max = "1080" +video_window_auto_width_max = "1920" +video_window_custom_size_enable = "false" +video_window_opacity = "100" +video_window_save_positions = "false" +video_window_show_decorations = "true" +video_windowed_fullscreen = "false" +video_windowed_position_height = "720" +video_windowed_position_width = "1280" +video_windowed_position_x = "0" +video_windowed_position_y = "0" +vrr_runloop_enable = "false" +vulkan_gpu_index = "0" +webdav_password = "" +webdav_url = "" +webdav_username = "" +wifi_driver = "null" +wifi_enabled = "true" +xmb_alpha_factor = "75" +xmb_font = "/usr/share/retroarch-assets/xmb/monochrome/font.ttf" +xmb_layout = "2" +xmb_menu_color_theme = "4" +xmb_shadows_enable = "true" +xmb_switch_icons = "true" +xmb_theme = "0" +xmb_vertical_thumbnails = "false" +youtube_stream_key = "" +assets_directory = "/tmp/assets" +cache_directory = "/tmp/cache" +cheat_database_path = "/tmp/database/cht" +content_database_path = "/tmp/database/rdb" +joypad_autoconfig_dir = "/tmp/joypads" +libretro_directory = "/tmp/cores" +libretro_info_path = "/tmp/cores" +overlay_directory = "/tmp/overlays" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/SDM845/retroarch32bit-append.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SDM845/retroarch32bit-append.cfg new file mode 100755 index 0000000000..343124c254 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SDM845/retroarch32bit-append.cfg @@ -0,0 +1,3 @@ +audio_filter_dir = "/usr/share/retroarch/filters/32bit/audio" +video_filter_dir = "/usr/share/retroarch/filters/32bit/video" +libretro_directory = /usr/lib32/libretro diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/SDM845/retroarch64bit-append.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SDM845/retroarch64bit-append.cfg new file mode 100755 index 0000000000..b6cbf68312 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SDM845/retroarch64bit-append.cfg @@ -0,0 +1,2 @@ +audio_filter_dir = "/usr/share/retroarch/filters/64bit/audio" +video_filter_dir = "/usr/share/retroarch/filters/64bit/video" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8250/TATE-MAME 2003-Plus.rmp b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8250/TATE-MAME 2003-Plus.rmp new file mode 100755 index 0000000000..366e47afad --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8250/TATE-MAME 2003-Plus.rmp @@ -0,0 +1,27 @@ +input_libretro_device_p1 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_player1_analog_dpad_mode = "1" +input_player1_btn_down = "6" +input_player1_btn_left = "4" +input_player1_btn_right = "5" +input_player1_btn_up = "7" +input_player1_stk_l_x+ = "5" +input_player1_stk_l_x- = "4" +input_player1_stk_l_y+ = "6" +input_player1_stk_l_y- = "7" +input_player1_stk_r_x+ = "5" +input_player1_stk_r_x- = "4" +input_player1_stk_r_y+ = "6" +input_player1_stk_r_y- = "7" +input_player2_analog_dpad_mode = "0" +input_player3_analog_dpad_mode = "0" +input_player4_analog_dpad_mode = "0" +input_player5_analog_dpad_mode = "0" +input_remap_port_p1 = "0" +input_remap_port_p2 = "1" +input_remap_port_p3 = "2" +input_remap_port_p4 = "3" +input_remap_port_p5 = "4" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8250/retroarch-core-options.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8250/retroarch-core-options.cfg new file mode 100755 index 0000000000..0bcbaa2661 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8250/retroarch-core-options.cfg @@ -0,0 +1,152 @@ +mupen64plus-alt-map = "False" +mupen64plus-aspect = "4:3" +mupen64plus-astick-deadzone = "15" +mupen64plus-astick-sensitivity = "100" +mupen64plus-BackgroundMode = "Stripped" +mupen64plus-BilinearMode = "standard" +mupen64plus-CorrectTexrectCoords = "Auto" +mupen64plus-CountPerOp = "0" +mupen64plus-CountPerOpDenomPot = "0" +mupen64plus-cpucore = "dynamic_recompiler" +mupen64plus-d-cbutton = "C3" +mupen64plus-DitheringPattern = "True" +mupen64plus-DitheringQuantization = "True" +mupen64plus-EnableCopyAuxToRDRAM = "True" +mupen64plus-EnableCopyColorToRDRAM = "Async" +mupen64plus-EnableCopyDepthToRDRAM = "Software" +mupen64plus-EnableEnhancedHighResStorage = "False" +mupen64plus-EnableEnhancedTextureStorage = "False" +mupen64plus-EnableFBEmulation = "True" +mupen64plus-EnableFragmentDepthWrite = "False" +mupen64plus-EnableHiResAltCRC = "False" +mupen64plus-EnableHWLighting = "True" +mupen64plus-EnableInaccurateTextureCoordinates = "False" +mupen64plus-EnableLegacyBlending = "False" +mupen64plus-EnableLODEmulation = "True" +mupen64plus-EnableNativeResFactor = "1" +mupen64plus-EnableNativeResTexrects = "Optimized" +mupen64plus-EnableOverscan = "Enabled" +mupen64plus-EnableTexCoordBounds = "False" +mupen64plus-EnableTextureCache = "True" +mupen64plus-ForceDisableExtraMem = "False" +mupen64plus-FrameDuping = "True" +mupen64plus-Framerate = "Original" +mupen64plus-FXAA = "0" +mupen64plus-GLideN64IniBehaviour = "late" +mupen64plus-HybridFilter = "True" +mupen64plus-IgnoreTLBExceptions = "False" +mupen64plus-l-cbutton = "C2" +mupen64plus-MaxHiResTxVramLimit = "0" +mupen64plus-MaxTxCacheSize = "8000" +mupen64plus-MultiSampling = "0" +mupen64plus-OverscanBottom = "0" +mupen64plus-OverscanLeft = "0" +mupen64plus-OverscanRight = "0" +mupen64plus-OverscanTop = "0" +mupen64plus-pak1 = "memory" +mupen64plus-pak2 = "none" +mupen64plus-pak3 = "none" +mupen64plus-pak4 = "none" +mupen64plus-r-cbutton = "C1" +mupen64plus-rdp-plugin = "gliden64" +mupen64plus-RDRAMImageDitheringMode = "BlueNoise" +mupen64plus-rsp-plugin = "hle" +mupen64plus-ThreadedRenderer = "True" +mupen64plus-txCacheCompression = "True" +mupen64plus-txEnhancementMode = "None" +mupen64plus-txFilterIgnoreBG = "True" +mupen64plus-txFilterMode = "None" +mupen64plus-txHiresEnable = "False" +mupen64plus-txHiresFullAlphaChannel = "False" +mupen64plus-u-cbutton = "C4" +mupen64plus-virefresh = "Auto" +pcsx_rearmed_analog_axis_modifier = "circle" +pcsx_rearmed_async_cd = "sync" +pcsx_rearmed_bios = "auto" +pcsx_rearmed_display_internal_fps = "disabled" +pcsx_rearmed_dithering = "enabled" +pcsx_rearmed_drc = "enabled" +pcsx_rearmed_duping_enable = "enabled" +pcsx_rearmed_frameskip_type = "disabled" +pcsx_rearmed_gteregsunneeded = "disabled" +pcsx_rearmed_gunconadjustratiox = "1" +pcsx_rearmed_gunconadjustratioy = "1" +pcsx_rearmed_gunconadjustx = "0" +pcsx_rearmed_gunconadjusty = "0" +pcsx_rearmed_idiablofix = "disabled" +pcsx_rearmed_input_sensitivity = "1.00" +pcsx_rearmed_inuyasha_fix = "disabled" +pcsx_rearmed_memcard2 = "disabled" +pcsx_rearmed_multitap1 = "auto" +pcsx_rearmed_multitap2 = "auto" +pcsx_rearmed_negcon_deadzone = "0" +pcsx_rearmed_negcon_response = "linear" +pcsx_rearmed_neon_enhancement_enable = "disabled" +pcsx_rearmed_neon_enhancement_no_main = "disabled" +pcsx_rearmed_neon_interlace_enable = "disabled" +pcsx_rearmed_nocdaudio = "enabled" +pcsx_rearmed_nogteflags = "disabled" +pcsx_rearmed_nosmccheck = "disabled" +pcsx_rearmed_noxadecoding = "enabled" +pcsx_rearmed_pad1type = "standard" +pcsx_rearmed_pad2type = "standard" +pcsx_rearmed_pad3type = "none" +pcsx_rearmed_pad4type = "none" +pcsx_rearmed_pad5type = "none" +pcsx_rearmed_pad6type = "none" +pcsx_rearmed_pad7type = "none" +pcsx_rearmed_pad8type = "none" +pcsx_rearmed_pe2_fix = "disabled" +pcsx_rearmed_psxclock = "57" +pcsx_rearmed_region = "auto" +pcsx_rearmed_show_bios_bootlogo = "disabled" +pcsx_rearmed_show_other_input_settings = "disabled" +pcsx_rearmed_spu_interpolation = "simple" +pcsx_rearmed_spu_reverb = "enabled" +pcsx_rearmed_spuirq = "disabled" +pcsx_rearmed_vibration = "enabled" +gambatte_gb_colorization = "disabled" +gambatte_gb_internal_palette = "" +mame2003-plus_analog = "digital" +mame2003-plus_art_resolution = "1" +mame2003-plus_brightness = "1.0" +mame2003-plus_cheat_input_ports = "disabled" +mame2003-plus_core_save_subfolder = "enabled" +mame2003-plus_core_sys_subfolder = "enabled" +mame2003-plus_dcs_speedhack = "enabled" +mame2003-plus_deadzone = "20" +mame2003-plus_digital_joy_centering = "enabled" +mame2003-plus_display_artwork = "enabled" +mame2003-plus_display_setup = "disabled" +mame2003-plus_four_way_emulation = "disabled" +mame2003-plus_frameskip = "0" +mame2003-plus_gamma = "1.0" +mame2003-plus_input_interface = "retropad" +mame2003-plus_machine_timing = "enabled" +mame2003-plus_mame_remapping = "enabled" +mame2003-plus_mouse_device = "mouse" +mame2003-plus_sample_rate = "48000" +mame2003-plus_skip_disclaimer = "disabled" +mame2003-plus_skip_warnings = "disabled" +flycast_internal_resolution = "640x480" +flycast_alpha_sorting = "per-strip (fast, least accurate)" +flycast_enable_dsp = "disabled" +flycast_threaded_rendering = "enabled" +flycast_anisotropic_filtering = "off" +flycast_synchronous_rendering = "enabled" +flycast_enable_rtt = "disabled" +flycast_enable_rttb = "disabled" +flycast_delay_frame_swapping = "disabled" +flycast_div_matching = "auto" +flycast_texupscale = "off" +flycast_auto_skip_frame = "normal" +opera_swi_hle = "enabled" +opera_dsp_threaded = "enabled" +opera_madam_matrix_engine = "software" +puae_deadzone = "25" +melonds_screen_layout = "Left/Right" +melonds_swapscreen_mode = "Toggle" +melonds_threaded_renderer = "enabled" +melonds_touch_mode = "Joystick" +virtualjaguar_bios = "enabled" +virtualjaguar_usefastblitter = "enabled" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8250/retroarch.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8250/retroarch.cfg new file mode 100644 index 0000000000..25942da255 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8250/retroarch.cfg @@ -0,0 +1,894 @@ +accessibility_enable = "false" +accessibility_narrator_speech_speed = "5" +ai_service_mode = "1" +ai_service_pause = "false" +ai_service_source_lang = "0" +ai_service_target_lang = "0" +all_users_control_menu = "true" +app_icon = "default" +apply_cheats_after_load = "false" +apply_cheats_after_toggle = "false" +audio_block_frames = "0" +audio_device = "" +audio_driver = "alsathread" +audio_dsp_plugin = "" +audio_enable = "true" +audio_enable_menu = "false" +audio_enable_menu_bgm = "false" +audio_enable_menu_cancel = "false" +audio_enable_menu_notice = "false" +audio_enable_menu_ok = "false" +audio_enable_menu_scroll = "false" +audio_fastforward_mute = "false" +audio_fastforward_speedup = "false" +audio_max_timing_skew = "0.049999" +audio_mixer_mute_enable = "false" +audio_mixer_volume = "0.000000" +audio_mute_enable = "false" +audio_out_rate = "48000" +audio_rate_control = "true" +audio_rate_control_delta = "0.004999" +audio_resampler = "sinc" +audio_resampler_quality = "2" +audio_sync = "true" +audio_volume = "0.000000" +auto_overrides_enable = "true" +auto_remaps_enable = "true" +auto_screenshot_filename = "true" +auto_shaders_enable = "true" +autosave_interval = "10" +block_sram_overwrite = "false" +bluetooth_driver = "null" +builtin_imageviewer_enable = "false" +builtin_mediaplayer_enable = "true" +bundle_assets_dst_path = "" +bundle_assets_dst_path_subdir = "" +bundle_assets_extract_enable = "false" +bundle_assets_extract_last_version = "0" +bundle_assets_extract_version_current = "0" +bundle_assets_src_path = "" +camera_allow = "false" +camera_device = "" +camera_driver = "null" +check_firmware_before_loading = "false" +cheevos_appearance_anchor = "0" +cheevos_appearance_padding_auto = "true" +cheevos_appearance_padding_h = "0.000000" +cheevos_appearance_padding_v = "0.000000" +cheevos_auto_screenshot = "false" +cheevos_badges_enable = "false" +cheevos_challenge_indicators = "true" +cheevos_custom_host = "" +cheevos_hardcore_mode_enable = "false" +cheevos_leaderboards_enable = "" +cheevos_password = "" +cheevos_richpresence_enable = "true" +cheevos_start_active = "false" +cheevos_test_unofficial = "false" +cheevos_token = "" +cheevos_unlock_sound_enable = "false" +cheevos_username = "" +cheevos_verbose_enable = "false" +cheevos_visibility_account = "true" +cheevos_visibility_lboard_cancel = "true" +cheevos_visibility_lboard_start = "true" +cheevos_visibility_lboard_submit = "true" +cheevos_visibility_lboard_trackers = "true" +cheevos_visibility_mastery = "true" +cheevos_visibility_progress_tracker = "true" +cheevos_visibility_summary = "1" +cheevos_visibility_unlock = "true" +cloud_sync_destructive = "false" +cloud_sync_driver = "" +cloud_sync_enable = "false" +config_save_on_exit = "false" +content_favorites_directory = "default" +content_favorites_path = "~/.config/retroarch/content_favorites.lpl" +content_favorites_size = "200" +content_history_dir = "" +content_history_directory = "default" +content_history_path = "~/.config/retroarch/content_history.lpl" +content_history_size = "200" +content_image_history_directory = "default" +content_image_history_path = "~/.config/retroarch/content_image_history.lpl" +content_music_history_directory = "default" +content_music_history_path = "~/.config/retroarch/content_music_history.lpl" +content_runtime_log = "true" +content_runtime_log_aggregate = "false" +content_show_add = "true" +content_show_add_entry = "2" +content_show_contentless_cores = "2" +content_show_explore = "true" +content_show_favorites = "true" +content_show_history = "true" +content_show_images = "false" +content_show_music = "false" +content_show_netplay = "true" +content_show_playlists = "true" +content_show_settings = "true" +content_show_settings_password = "" +content_show_video = "false" +content_video_directory = "default" +content_video_history_path = "~/.config/retroarch/content_video_history.lpl" +core_assets_directory = "~/roms/downloads" +core_info_cache_enable = "true" +core_info_savestate_bypass = "false" +core_option_category_enable = "true" +core_options_path = "" +core_set_supports_no_game_enable = "true" +core_updater_auto_backup = "false" +core_updater_auto_backup_history_size = "1" +core_updater_auto_extract_archive = "true" +core_updater_buildbot_assets_url = "http://buildbot.libretro.com/assets/" +core_updater_buildbot_cores_url = "" +core_updater_buildbot_url = "http://buildbot.libretro.com/nightly/linux/armhf/latest/" +core_updater_show_experimental_cores = "false" +cpu_main_gov = "performance" +cpu_max_freq = "-1" +cpu_menu_gov = "interactive" +cpu_min_freq = "1" +cpu_scaling_mode = "0" +crt_switch_center_adjust = "0" +crt_switch_hires_menu = "false" +crt_switch_porch_adjust = "0" +crt_switch_resolution = "0" +crt_switch_resolution_super = "2560" +crt_switch_resolution_use_custom_refresh_rate = "false" +crt_switch_timings = "" +crt_video_refresh_rate = "60.000000" +current_resolution_id = "0" +cursor_directory = "~/.config/retroarch/database/cursors" +custom_viewport_height = "1080" +custom_viewport_width = "1920" +custom_viewport_x = "0" +custom_viewport_y = "0" +desktop_menu_enable = "true" +discord_allow = "false" +discord_app_id = "475456035851599874" +driver_switch_enable = "true" +dynamic_wallpapers_directory = "default" +emuelec_exit_to_kodi = "false" +enable_device_vibration = "true" +facebook_stream_key = "" +fastforward_frameskip = "true" +fastforward_ratio = "0.000000" +filter_by_current_core = "false" +flicker_filter_enable = "false" +flicker_filter_index = "0" +fps_update_interval = "256" +frame_time_counter_reset_after_fastforwarding = "false" +frame_time_counter_reset_after_load_state = "false" +frame_time_counter_reset_after_save_state = "false" +framecount_show = "false" +frontend_log_level = "1" +game_specific_options = "true" +gamemode_enable = "false" +gamma_correction = "0" +global_core_options = "false" +history_list_enable = "true" +initial_disk_change_enable = "true" +input_ai_service = "nul" +input_ai_service_axis = "nul" +input_ai_service_btn = "nul" +input_ai_service_mbtn = "nul" +input_allow_turbo_dpad = "false" +input_analog_deadzone = "0.100000" +input_analog_sensitivity = "1.500000" +input_audio_mute = "nul" +input_audio_mute_axis = "nul" +input_audio_mute_btn = "nul" +input_audio_mute_mbtn = "nul" +input_auto_game_focus = "0" +input_auto_mouse_grab = "false" +input_autodetect_enable = "true" +input_axis_threshold = "0.500000" +input_bind_hold = "2" +input_bind_timeout = "5" +input_cheat_index_minus = "nul" +input_cheat_index_minus_axis = "nul" +input_cheat_index_minus_btn = "nul" +input_cheat_index_minus_mbtn = "nul" +input_cheat_index_plus = "nul" +input_cheat_index_plus_axis = "nul" +input_cheat_index_plus_btn = "nul" +input_cheat_index_plus_mbtn = "nul" +input_cheat_toggle = "nul" +input_cheat_toggle_axis = "nul" +input_cheat_toggle_btn = "nul" +input_cheat_toggle_mbtn = "nul" +input_close_content = "nul" +input_close_content_axis = "nul" +input_close_content_btn = "nul" +input_close_content_mbtn = "nul" +input_descriptor_hide_unbound = "false" +input_descriptor_label_show = "true" +input_desktop_menu_toggle = "f5" +input_desktop_menu_toggle_axis = "nul" +input_desktop_menu_toggle_btn = "nul" +input_desktop_menu_toggle_mbtn = "nul" +input_device_p1 = "0" +input_device_p10 = "0" +input_device_p11 = "0" +input_device_p12 = "0" +input_device_p13 = "0" +input_device_p14 = "0" +input_device_p15 = "0" +input_device_p16 = "0" +input_device_p2 = "0" +input_device_p3 = "0" +input_device_p4 = "0" +input_device_p5 = "0" +input_device_p6 = "0" +input_device_p7 = "0" +input_device_p8 = "0" +input_device_p9 = "0" +input_disk_eject_toggle = "nul" +input_disk_eject_toggle_axis = "nul" +input_disk_eject_toggle_btn = "nul" +input_disk_eject_toggle_mbtn = "nul" +input_disk_next = "nul" +input_disk_next_axis = "nul" +input_disk_next_btn = "nul" +input_disk_next_mbtn = "nul" +input_disk_prev = "nul" +input_disk_prev_axis = "nul" +input_disk_prev_btn = "nul" +input_disk_prev_mbtn = "nul" +input_driver = "udev" +input_duty_cycle = "3" +input_enable_hotkey = "nul" +input_enable_hotkey_axis = "nul" +input_enable_hotkey_btn = "5" +input_enable_hotkey_mbtn = "nul" +input_exit_emulator = "nul" +input_exit_emulator_axis = "nul" +input_exit_emulator_btn = "6" +input_exit_emulator_mbtn = "nul" +input_fps_toggle = "nul" +input_fps_toggle_axis = "nul" +input_fps_toggle_btn = "3" +input_fps_toggle_mbtn = "nul" +input_frame_advance = "nul" +input_frame_advance_axis = "nul" +input_frame_advance_btn = "nul" +input_frame_advance_mbtn = "nul" +input_game_focus_toggle = "nul" +input_game_focus_toggle_axis = "nul" +input_game_focus_toggle_btn = "nul" +input_game_focus_toggle_mbtn = "nul" +input_grab_mouse_toggle = "nul" +input_grab_mouse_toggle_axis = "nul" +input_grab_mouse_toggle_btn = "nul" +input_grab_mouse_toggle_mbtn = "nul" +input_halt_replay = "nul" +input_halt_replay_axis = "nul" +input_halt_replay_btn = "nul" +input_halt_replay_mbtn = "nul" +input_hold_fast_forward = "nul" +input_hold_fast_forward_axis = "+5" +input_hold_fast_forward_btn = "nul" +input_hold_fast_forward_mbtn = "nul" +input_hold_slowmotion = "nul" +input_hold_slowmotion_axis = "nul" +input_hold_slowmotion_btn = "nul" +input_hold_slowmotion_mbtn = "nul" +input_hotkey_block_delay = "5" +input_hotkey_device_merge = "false" +input_joypad_driver = "sdl2" +input_keyboard_layout = "" +input_libretro_device_p1 = "1" +input_libretro_device_p10 = "1" +input_libretro_device_p11 = "1" +input_libretro_device_p12 = "1" +input_libretro_device_p13 = "1" +input_libretro_device_p14 = "1" +input_libretro_device_p15 = "1" +input_libretro_device_p16 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_libretro_device_p6 = "1" +input_libretro_device_p7 = "1" +input_libretro_device_p8 = "1" +input_libretro_device_p9 = "1" +input_load_state = "nul" +input_load_state_axis = "nul" +input_load_state_btn = "9" +input_load_state_mbtn = "nul" +input_max_users = "5" +input_menu_toggle = "nul" +input_menu_toggle_axis = "nul" +input_menu_toggle_btn = "2" +input_menu_toggle_gamepad_combo = "2" +input_menu_toggle_mbtn = "nul" +input_movie_record_toggle = "o" +input_movie_record_toggle_axis = "nul" +input_movie_record_toggle_btn = "nul" +input_movie_record_toggle_mbtn = "nul" +input_netplay_fade_chat_toggle = "nul" +input_netplay_fade_chat_toggle_axis = "nul" +input_netplay_fade_chat_toggle_btn = "nul" +input_netplay_fade_chat_toggle_mbtn = "nul" +input_netplay_game_watch = "nul" +input_netplay_game_watch_axis = "nul" +input_netplay_game_watch_btn = "nul" +input_netplay_game_watch_mbtn = "nul" +input_netplay_host_toggle = "nul" +input_netplay_host_toggle_axis = "nul" +input_netplay_host_toggle_btn = "nul" +input_netplay_host_toggle_mbtn = "nul" +input_netplay_ping_toggle = "nul" +input_netplay_ping_toggle_axis = "nul" +input_netplay_ping_toggle_btn = "nul" +input_netplay_ping_toggle_mbtn = "nul" +input_netplay_player_chat = "nul" +input_netplay_player_chat_axis = "nul" +input_netplay_player_chat_btn = "nul" +input_netplay_player_chat_mbtn = "nul" +input_nowinkey_enable = "false" +input_osk_overlay = "" +input_osk_overlay_auto_scale = "false" +input_osk_overlay_opacity = "0.700000" +input_osk_toggle = "nul" +input_osk_toggle_axis = "nul" +input_osk_toggle_btn = "nul" +input_osk_toggle_mbtn = "nul" +input_overlay = "" +input_overlay_aspect_adjust_landscape = "0.000000" +input_overlay_aspect_adjust_portrait = "0.000000" +input_overlay_auto_rotate = "false" +input_overlay_auto_scale = "false" +input_overlay_enable_autopreferred = "true" +input_overlay_enable = "false" +input_overlay_hide_in_menu = "true" +input_overlay_hide_when_gamepad_connected = "false" +input_overlay_next_axis = "nul" +input_overlay_next_btn = "nul" +input_overlay_next_mbtn = "nul" +input_overlay_next = "nul" +input_overlay_opacity = "0.700000" +input_overlay_scale_landscape = "1.000000" +input_overlay_scale_portrait = "1.000000" +input_overlay_show_inputs = "2" +input_overlay_show_inputs_port = "0" +input_overlay_show_mouse_cursor = "true" +input_overlay_x_offset_landscape = "0.000000" +input_overlay_x_offset_portrait = "0.000000" +input_overlay_x_separation_landscape = "0.000000" +input_overlay_x_separation_portrait = "0.000000" +input_overlay_y_offset_landscape = "0.000000" +input_overlay_y_offset_portrait = "0.000000" +input_overlay_y_separation_landscape = "0.000000" +input_overlay_y_separation_portrait = "0.000000" +input_pause_toggle = "nul" +input_pause_toggle_axis = "nul" +input_pause_toggle_btn = "nul" +input_pause_toggle_mbtn = "nul" +input_play_replay = "nul" +input_play_replay_axis = "nul" +input_play_replay_btn = "nul" +input_play_replay_mbtn = "nul" +input_poll_type_behavior = "2" +input_preempt_toggle = "nul" +input_preempt_toggle_axis = "nul" +input_preempt_toggle_btn = "nul" +input_preempt_toggle_mbtn = "nul" +input_quit_gamepad_combo = "0" +input_record_replay = "nul" +input_record_replay_axis = "nul" +input_record_replay_btn = "nul" +input_record_replay_mbtn = "nul" +input_recording_toggle = "nul" +input_recording_toggle_axis = "nul" +input_recording_toggle_btn = "nul" +input_recording_toggle_mbtn = "nul" +input_remap_binds_enable = "true" +input_remapping_directory = "~/remappings" +input_replay_slot_decrease = "nul" +input_replay_slot_decrease_axis = "nul" +input_replay_slot_decrease_btn = "nul" +input_replay_slot_decrease_mbtn = "nul" +input_replay_slot_increase = "nul" +input_replay_slot_increase_axis = "nul" +input_replay_slot_increase_btn = "nul" +input_replay_slot_increase_mbtn = "nul" +input_reset = "nul" +input_reset_axis = "nul" +input_reset_btn = "nul" +input_reset_mbtn = "nul" +input_rewind = "nul" +input_rewind_axis = "+4" +input_rewind_btn = "nul" +input_rewind_mbtn = "nul" +input_rumble_gain = "25" +input_runahead_toggle = "nul" +input_runahead_toggle_axis = "nul" +input_runahead_toggle_btn = "nul" +input_runahead_toggle_mbtn = "nul" +input_save_state = "nul" +input_save_state_axis = "nul" +input_save_state_btn = "10" +input_save_state_mbtn = "nul" +input_screenshot = "nul" +input_screenshot_axis = "nul" +input_screenshot_btn = "nul" +input_screenshot_mbtn = "nul" +input_send_debug_info = "f10" +input_send_debug_info_axis = "nul" +input_send_debug_info_btn = "nul" +input_send_debug_info_mbtn = "nul" +input_sensors_enable = "true" +input_shader_next = "nul" +input_shader_next_axis = "nul" +input_shader_next_btn = "nul" +input_shader_next_mbtn = "nul" +input_shader_prev = "nul" +input_shader_prev_axis = "nul" +input_shader_prev_btn = "nul" +input_shader_prev_mbtn = "nul" +input_shader_toggle = "nul" +input_shader_toggle_axis = "nul" +input_shader_toggle_btn = "nul" +input_shader_toggle_mbtn = "nul" +input_state_slot_decrease = "nul" +input_state_slot_decrease_axis = "nul" +input_state_slot_decrease_btn = "nul" +input_state_slot_decrease_mbtn = "nul" +input_state_slot_increase = "nul" +input_state_slot_increase_axis = "nul" +input_state_slot_increase_btn = "nul" +input_state_slot_increase_mbtn = "nul" +input_streaming_toggle = "nul" +input_streaming_toggle_axis = "nul" +input_streaming_toggle_btn = "nul" +input_streaming_toggle_mbtn = "nul" +input_toggle_fast_forward = "nul" +input_toggle_fast_forward_axis = "nul" +input_toggle_fast_forward_btn = "nul" +input_toggle_fast_forward_mbtn = "nul" +input_toggle_fullscreen = "nul" +input_toggle_fullscreen_axis = "nul" +input_toggle_fullscreen_btn = "nul" +input_toggle_fullscreen_mbtn = "nul" +input_toggle_slowmotion = "nul" +input_toggle_slowmotion_axis = "nul" +input_toggle_slowmotion_btn = "nul" +input_toggle_slowmotion_mbtn = "nul" +input_toggle_statistics = "nul" +input_toggle_statistics_axis = "nul" +input_toggle_statistics_btn = "nul" +input_toggle_statistics_mbtn = "nul" +input_toggle_vrr_runloop = "nul" +input_toggle_vrr_runloop_axis = "nul" +input_toggle_vrr_runloop_btn = "nul" +input_toggle_vrr_runloop_mbtn = "nul" +input_touch_scale = "1" +input_touch_vmouse_gesture = "true" +input_touch_vmouse_mouse = "true" +input_touch_vmouse_pointer = "true" +input_touch_vmouse_touchpad = "true" +input_touch_vmouse_trackball = "false" +input_turbo_default_button = "0" +input_turbo_mode = "0" +input_turbo_period = "6" +input_volume_down = "nul" +input_volume_down_axis = "nul" +input_volume_down_btn = "nul" +input_volume_down_mbtn = "nul" +input_volume_up = "nul" +input_volume_up_axis = "nul" +input_volume_up_btn = "nul" +input_volume_up_mbtn = "nul" +keyboard_gamepad_enable = "true" +keyboard_gamepad_mapping_type = "1" +kiosk_mode_enable = "false" +kiosk_mode_password = "" +led_driver = "null" +libretro_log_level = "1" +load_dummy_on_core_shutdown = "true" +location_allow = "false" +location_driver = "null" +log_dir = "~/.config/retroarch/logs" +log_to_file = "true" +log_to_file_timestamp = "false" +log_verbosity = "true" +materialui_auto_rotate_nav_bar = "true" +materialui_dual_thumbnail_list_view_enable = "true" +materialui_icons_enable = "true" +materialui_landscape_layout_optimization = "1" +materialui_menu_color_theme = "9" +materialui_menu_transition_animation = "0" +materialui_playlist_icons_enable = "true" +materialui_show_nav_bar = "true" +materialui_switch_icons = "true" +materialui_thumbnail_background_enable = "true" +materialui_thumbnail_view_landscape = "2" +materialui_thumbnail_view_portrait = "1" +memory_show = "false" +memory_update_interval = "256" +menu_battery_level_enable = "true" +menu_core_enable = "true" +menu_disable_info_button = "false" +menu_disable_search_button = "false" +menu_driver = "ozone" +menu_dynamic_wallpaper_enable = "false" +menu_enable_widgets = "true" +menu_font_color_blue = "255" +menu_font_color_green = "255" +menu_font_color_red = "255" +menu_footer_opacity = "1.000000" +menu_framebuffer_opacity = "0.899999" +menu_header_opacity = "1.000000" +menu_horizontal_animation = "true" +menu_insert_disk_resume = "true" +menu_left_thumbnails = "0" +menu_linear_filter = "false" +menu_mouse_enable = "false" +menu_navigation_browser_filter_supported_extensions_enable = "true" +menu_navigation_wraparound_enable = "true" +menu_pause_libretro = "true" +menu_pointer_enable = "true" +menu_remember_selection = "1" +menu_rgui_full_width_layout = "true" +menu_rgui_shadows = "false" +menu_rgui_transparency = "true" +menu_savestate_resume = "true" +menu_scale_factor = "0.300000" +menu_screensaver_animation = "0" +menu_screensaver_animation_speed = "1.000000" +menu_screensaver_timeout = "0" +menu_scroll_delay = "256" +menu_scroll_fast = "false" +menu_shader_pipeline = "2" +menu_show_advanced_settings = "true" +menu_show_configurations = "true" +menu_show_core_updater = "false" +menu_show_dump_disc = "true" +menu_show_help = "true" +menu_show_information = "true" +menu_show_latency = "true" +menu_show_legacy_thumbnail_updater = "false" +menu_show_load_content = "true" +menu_show_load_content_animation = "false" +menu_show_load_core = "true" +menu_show_load_disc = "true" +menu_show_online_updater = "true" +menu_show_overlays = "true" +menu_show_quit_retroarch = "true" +menu_show_reboot = "false" +menu_show_restart_retroarch = "true" +menu_show_rewind = "true" +menu_show_shutdown = "false" +menu_show_sublabels = "true" +menu_show_video_layout = "true" +menu_swap_ok_cancel_buttons = "false" +menu_swap_scroll_buttons = "false" +menu_throttle_framerate = "true" +menu_thumbnail_upscale_threshold = "0" +menu_thumbnails = "3" +menu_ticker_smooth = "true" +menu_ticker_speed = "2.000000" +menu_ticker_type = "1" +menu_timedate_date_separator = "0" +menu_timedate_enable = "true" +menu_timedate_style = "11" +menu_unified_controls = "false" +menu_use_preferred_system_color_theme = "false" +menu_wallpaper = "" +menu_wallpaper_opacity = "1.000000" +menu_widget_scale_auto = "false" +menu_widget_scale_factor = "0.350000" +menu_widget_scale_factor_windowed = "1.000000" +menu_xmb_animation_horizontal_highlight = "0" +menu_xmb_animation_move_up_down = "0" +menu_xmb_animation_opening_main_menu = "0" +menu_xmb_show_title_header = "true" +menu_xmb_thumbnail_scale_factor = "100" +menu_xmb_title_margin = "5" +menu_xmb_title_margin_horizontal_offset = "0" +menu_xmb_vertical_fade_factor = "100" +microphone_block_frames = "0" +microphone_device = "" +microphone_driver = "alsathread" +microphone_enable = "true" +microphone_latency = "64" +microphone_rate = "48000" +microphone_resampler = "sinc" +microphone_resampler_quality = "3" +midi_driver = "alsa" +midi_input = "OFF" +midi_output = "OFF" +midi_volume = "100" +network_cmd_enable = "false" +network_cmd_port = "55355" +network_on_demand_thumbnails = "false" +network_remote_base_port = "55400" +network_remote_enable = "false" +network_remote_enable_user_p1 = "false" +network_remote_enable_user_p10 = "false" +network_remote_enable_user_p11 = "false" +network_remote_enable_user_p12 = "false" +network_remote_enable_user_p13 = "false" +network_remote_enable_user_p14 = "false" +network_remote_enable_user_p15 = "false" +network_remote_enable_user_p16 = "false" +network_remote_enable_user_p2 = "false" +network_remote_enable_user_p3 = "false" +network_remote_enable_user_p4 = "false" +network_remote_enable_user_p5 = "false" +network_remote_enable_user_p6 = "false" +network_remote_enable_user_p7 = "false" +network_remote_enable_user_p8 = "false" +network_remote_enable_user_p9 = "false" +notification_show_autoconfig = "false" +notification_show_cheats_applied = "true" +notification_show_config_override_load = "false" +notification_show_disk_control = "true" +notification_show_fast_forward = "true" +notification_show_netplay_extra = "false" +notification_show_patch_applied = "true" +notification_show_refresh_rate = "true" +notification_show_remap_load = "false" +notification_show_save_state = "true" +notification_show_screenshot = "false" +notification_show_screenshot_duration = "2" +notification_show_screenshot_flash = "1" +notification_show_set_initial_disk = "true" +notification_show_when_menu_is_alive = "false" +osk_overlay_directory = "/tmp/overlays/keyboards" +ozone_collapse_sidebar = "false" +ozone_menu_color_theme = "1" +ozone_scroll_content_metadata = "false" +ozone_sort_after_truncate_playlist_name = "true" +ozone_thumbnail_scale_factor = "1.000000" +ozone_truncate_playlist_name = "true" +pause_nonactive = "true" +pause_on_disconnect = "false" +perfcnt_enable = "false" +playlist_compression = "false" +playlist_cores = "" +playlist_directory = "~/playlists" +playlist_entry_remove = "false" +playlist_entry_remove_enable = "1" +playlist_entry_rename = "false" +playlist_fuzzy_archive_match = "false" +playlist_names = "" +playlist_portable_paths = "false" +playlist_show_entry_idx = "true" +playlist_show_history_icons = "1" +playlist_show_inline_core_name = "0" +playlist_show_sublabels = "true" +playlist_sort_alphabetical = "true" +playlist_sublabel_last_played_style = "0" +playlist_sublabel_runtime_type = "0" +playlist_use_filename = "false" +playlist_use_old_format = "false" +preemptive_frames_enable = "false" +preemptive_frames_hide_warnings = "false" +quick_menu_show_add_to_favorites = "true" +quick_menu_show_add_to_playlist = "false" +quick_menu_show_cheats = "true" +quick_menu_show_close_content = "true" +quick_menu_show_controls = "true" +quick_menu_show_core_options_flush = "false" +quick_menu_show_download_thumbnails = "true" +quick_menu_show_information = "true" +quick_menu_show_options = "true" +quick_menu_show_recording = "true" +quick_menu_show_replay = "false" +quick_menu_show_reset_core_association = "true" +quick_menu_show_restart_content = "true" +quick_menu_show_resume_content = "true" +quick_menu_show_save_content_dir_overrides = "true" +quick_menu_show_save_core_overrides = "false" +quick_menu_show_save_game_overrides = "false" +quick_menu_show_save_load_state = "true" +quick_menu_show_savestate_submenu = "true" +quick_menu_show_set_core_association = "true" +quick_menu_show_shaders = "true" +quick_menu_show_start_recording = "true" +quick_menu_show_start_streaming = "true" +quick_menu_show_streaming = "true" +quick_menu_show_take_screenshot = "true" +quick_menu_show_undo_save_load_state = "false" +quit_on_close_content = "0" +quit_press_twice = "true" +record_driver = "null" +recording_config_directory = "" +recording_output_directory = "~/roms/screenshots" +remap_save_on_exit = "true" +replay_auto_index = "true" +replay_checkpoint_interval = "0" +replay_max_keep = "0" +replay_slot = "0" +resampler_directory = "" +rewind_buffer_size = "20971520" +rewind_buffer_size_step = "10" +rewind_granularity = "1" +rgui_aspect_ratio = "0" +rgui_aspect_ratio_lock = "0" +rgui_background_filler_thickness_enable = "true" +rgui_border_filler_enable = "true" +rgui_border_filler_thickness_enable = "true" +rgui_browser_directory = "~/roms" +rgui_config_directory = "~/.config/retroarch/config" +rgui_extended_ascii = "false" +rgui_inline_thumbnails = "false" +rgui_internal_upscale_level = "0" +rgui_menu_color_theme = "4" +rgui_menu_theme_preset = "" +rgui_particle_effect = "0" +rgui_particle_effect_screensaver = "true" +rgui_particle_effect_speed = "1.000000" +rgui_show_start_screen = "false" +rgui_swap_thumbnails = "false" +rgui_switch_icons = "true" +rgui_thumbnail_delay = "0" +rgui_thumbnail_downscaler = "0" +run_ahead_hide_warnings = "false" +run_ahead_secondary_instance = "true" +runtime_log_directory = "default" +save_file_compression = "false" +savefile_directory = "~/.config/retroarch/saves" +savefiles_in_content_dir = "true" +savestate_file_compression = "true" +savestate_thumbnail_enable = "true" +savestates_in_content_dir = "false" +scan_serial_and_crc = "false" +scan_without_core_match = "false" +screen_brightness = "100" +screen_orientation = "0" +screenshot_directory = "~/roms/screenshots" +screenshots_in_content_dir = "false" +settings_show_accessibility = "true" +settings_show_achievements = "true" +settings_show_ai_service = "true" +settings_show_audio = "true" +settings_show_configuration = "true" +settings_show_core = "true" +settings_show_directory = "true" +settings_show_drivers = "true" +settings_show_file_browser = "true" +settings_show_frame_throttle = "true" +settings_show_input = "true" +settings_show_latency = "true" +settings_show_logging = "true" +settings_show_network = "true" +settings_show_onscreen_display = "true" +settings_show_playlists = "true" +settings_show_power_management = "true" +settings_show_recording = "true" +settings_show_saving = "true" +settings_show_user = "true" +settings_show_user_interface = "true" +settings_show_video = "true" +show_hidden_files = "false" +slowmotion_ratio = "3.000000" +soft_filter_enable = "false" +soft_filter_index = "0" +sort_savefiles_by_content_enable = "false" +sort_savefiles_enable = "false" +sort_savestates_by_content_enable = "false" +sort_savestates_enable = "false" +sort_screenshots_by_content_enable = "false" +statistics_show = "false" +stdin_cmd_enable = "false" +streaming_mode = "0" +suspend_screensaver_enable = "true" +sustained_performance_mode = "false" +system_directory = "~/roms/bios" +systemfiles_in_content_dir = "false" +test_input_file_joypad = "" +threaded_data_runloop_enable = "true" +thumbnails_directory = "~/thumbnails" +twitch_stream_key = "" +ui_companion_enable = "false" +ui_companion_start_on_boot = "true" +ui_companion_toggle = "false" +ui_menubar_enable = "true" +use_last_start_directory = "false" +user_language = "0" +vibrate_on_keypress = "true" +video_adaptive_vsync = "false" +video_allow_rotate = "true" +video_aspect_ratio = "-1.000000" +video_aspect_ratio_auto = "true" +video_autoswitch_pal_threshold = "54.500000" +video_autoswitch_refresh_rate = "0" +video_bfi_dark_frames = "1" +video_black_frame_insertion = "0" +video_context_driver = "" +video_crop_overscan = "true" +video_disable_composition = "false" +video_driver = "glcore" +video_font_enable = "true" +video_font_path = "/usr/share/retroarch-assets/xmb/monochrome/font.ttf" +video_font_size = "32.000000" +video_force_aspect = "true" +video_force_srgb_disable = "false" +video_frame_delay = "0" +video_frame_delay_auto = "false" +video_frame_rest = "false" +video_fullscreen = "true" +video_fullscreen_x = "1920" +video_fullscreen_y = "1080" +video_gpu_record = "false" +video_gpu_screenshot = "false" +video_hard_sync = "false" +video_hard_sync_frames = "0" +video_hdr_display_contrast = "5.000000" +video_hdr_enable = "false" +video_hdr_expand_gamut = "true" +video_hdr_max_nits = "1000.000000" +video_hdr_paper_white_nits = "200.000000" +video_layout_directory = "~/.config/retroarch/layouts" +video_layout_enable = "true" +video_layout_path = "" +video_layout_selected_view = "0" +video_max_frame_latency = "1" +video_max_swapchain_images = "3" +video_message_color = "ffff00" +video_message_pos_x = "0.049999" +video_message_pos_y = "0.049999" +video_monitor_index = "0" +video_msg_bgcolor_blue = "0" +video_msg_bgcolor_enable = "false" +video_msg_bgcolor_green = "0" +video_msg_bgcolor_opacity = "1.000000" +video_msg_bgcolor_red = "0" +video_notch_write_over_enable = "false" +video_oga_vertical_enable = "false" +video_post_filter_record = "false" +video_record_config = "" +video_record_quality = "4" +video_record_scale_factor = "1" +video_record_threads = "2" +video_refresh_rate = "60.000000" +video_scale = "3" +video_scan_subframes = "false" +video_shared_context = "false" +video_stream_config = "" +video_stream_port = "56400" +video_stream_quality = "10" +video_stream_scale_factor = "1" +video_stream_url = "" +video_swap_interval = "1" +video_threaded = "false" +video_vsync = "true" +video_waitable_swapchains = "true" +video_window_auto_height_max = "1080" +video_window_auto_width_max = "1920" +video_window_custom_size_enable = "false" +video_window_opacity = "100" +video_window_save_positions = "false" +video_window_show_decorations = "true" +video_windowed_fullscreen = "false" +video_windowed_position_height = "720" +video_windowed_position_width = "1280" +video_windowed_position_x = "0" +video_windowed_position_y = "0" +vrr_runloop_enable = "false" +vulkan_gpu_index = "0" +webdav_password = "" +webdav_url = "" +webdav_username = "" +wifi_driver = "null" +wifi_enabled = "true" +xmb_alpha_factor = "75" +xmb_font = "/usr/share/retroarch-assets/xmb/monochrome/font.ttf" +xmb_layout = "2" +xmb_menu_color_theme = "4" +xmb_shadows_enable = "true" +xmb_switch_icons = "true" +xmb_theme = "0" +xmb_vertical_thumbnails = "false" +youtube_stream_key = "" +assets_directory = "/tmp/assets" +cache_directory = "/tmp/cache" +cheat_database_path = "/tmp/database/cht" +content_database_path = "/tmp/database/rdb" +joypad_autoconfig_dir = "/tmp/joypads" +libretro_directory = "/tmp/cores" +libretro_info_path = "/tmp/cores" +overlay_directory = "/tmp/overlays" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8250/retroarch32bit-append.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8250/retroarch32bit-append.cfg new file mode 100755 index 0000000000..343124c254 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8250/retroarch32bit-append.cfg @@ -0,0 +1,3 @@ +audio_filter_dir = "/usr/share/retroarch/filters/32bit/audio" +video_filter_dir = "/usr/share/retroarch/filters/32bit/video" +libretro_directory = /usr/lib32/libretro diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8250/retroarch64bit-append.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8250/retroarch64bit-append.cfg new file mode 100755 index 0000000000..b6cbf68312 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8250/retroarch64bit-append.cfg @@ -0,0 +1,2 @@ +audio_filter_dir = "/usr/share/retroarch/filters/64bit/audio" +video_filter_dir = "/usr/share/retroarch/filters/64bit/video" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8550/TATE-MAME 2003-Plus.rmp b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8550/TATE-MAME 2003-Plus.rmp new file mode 100755 index 0000000000..366e47afad --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8550/TATE-MAME 2003-Plus.rmp @@ -0,0 +1,27 @@ +input_libretro_device_p1 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_player1_analog_dpad_mode = "1" +input_player1_btn_down = "6" +input_player1_btn_left = "4" +input_player1_btn_right = "5" +input_player1_btn_up = "7" +input_player1_stk_l_x+ = "5" +input_player1_stk_l_x- = "4" +input_player1_stk_l_y+ = "6" +input_player1_stk_l_y- = "7" +input_player1_stk_r_x+ = "5" +input_player1_stk_r_x- = "4" +input_player1_stk_r_y+ = "6" +input_player1_stk_r_y- = "7" +input_player2_analog_dpad_mode = "0" +input_player3_analog_dpad_mode = "0" +input_player4_analog_dpad_mode = "0" +input_player5_analog_dpad_mode = "0" +input_remap_port_p1 = "0" +input_remap_port_p2 = "1" +input_remap_port_p3 = "2" +input_remap_port_p4 = "3" +input_remap_port_p5 = "4" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8550/retroarch-core-options.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8550/retroarch-core-options.cfg new file mode 100755 index 0000000000..0bcbaa2661 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8550/retroarch-core-options.cfg @@ -0,0 +1,152 @@ +mupen64plus-alt-map = "False" +mupen64plus-aspect = "4:3" +mupen64plus-astick-deadzone = "15" +mupen64plus-astick-sensitivity = "100" +mupen64plus-BackgroundMode = "Stripped" +mupen64plus-BilinearMode = "standard" +mupen64plus-CorrectTexrectCoords = "Auto" +mupen64plus-CountPerOp = "0" +mupen64plus-CountPerOpDenomPot = "0" +mupen64plus-cpucore = "dynamic_recompiler" +mupen64plus-d-cbutton = "C3" +mupen64plus-DitheringPattern = "True" +mupen64plus-DitheringQuantization = "True" +mupen64plus-EnableCopyAuxToRDRAM = "True" +mupen64plus-EnableCopyColorToRDRAM = "Async" +mupen64plus-EnableCopyDepthToRDRAM = "Software" +mupen64plus-EnableEnhancedHighResStorage = "False" +mupen64plus-EnableEnhancedTextureStorage = "False" +mupen64plus-EnableFBEmulation = "True" +mupen64plus-EnableFragmentDepthWrite = "False" +mupen64plus-EnableHiResAltCRC = "False" +mupen64plus-EnableHWLighting = "True" +mupen64plus-EnableInaccurateTextureCoordinates = "False" +mupen64plus-EnableLegacyBlending = "False" +mupen64plus-EnableLODEmulation = "True" +mupen64plus-EnableNativeResFactor = "1" +mupen64plus-EnableNativeResTexrects = "Optimized" +mupen64plus-EnableOverscan = "Enabled" +mupen64plus-EnableTexCoordBounds = "False" +mupen64plus-EnableTextureCache = "True" +mupen64plus-ForceDisableExtraMem = "False" +mupen64plus-FrameDuping = "True" +mupen64plus-Framerate = "Original" +mupen64plus-FXAA = "0" +mupen64plus-GLideN64IniBehaviour = "late" +mupen64plus-HybridFilter = "True" +mupen64plus-IgnoreTLBExceptions = "False" +mupen64plus-l-cbutton = "C2" +mupen64plus-MaxHiResTxVramLimit = "0" +mupen64plus-MaxTxCacheSize = "8000" +mupen64plus-MultiSampling = "0" +mupen64plus-OverscanBottom = "0" +mupen64plus-OverscanLeft = "0" +mupen64plus-OverscanRight = "0" +mupen64plus-OverscanTop = "0" +mupen64plus-pak1 = "memory" +mupen64plus-pak2 = "none" +mupen64plus-pak3 = "none" +mupen64plus-pak4 = "none" +mupen64plus-r-cbutton = "C1" +mupen64plus-rdp-plugin = "gliden64" +mupen64plus-RDRAMImageDitheringMode = "BlueNoise" +mupen64plus-rsp-plugin = "hle" +mupen64plus-ThreadedRenderer = "True" +mupen64plus-txCacheCompression = "True" +mupen64plus-txEnhancementMode = "None" +mupen64plus-txFilterIgnoreBG = "True" +mupen64plus-txFilterMode = "None" +mupen64plus-txHiresEnable = "False" +mupen64plus-txHiresFullAlphaChannel = "False" +mupen64plus-u-cbutton = "C4" +mupen64plus-virefresh = "Auto" +pcsx_rearmed_analog_axis_modifier = "circle" +pcsx_rearmed_async_cd = "sync" +pcsx_rearmed_bios = "auto" +pcsx_rearmed_display_internal_fps = "disabled" +pcsx_rearmed_dithering = "enabled" +pcsx_rearmed_drc = "enabled" +pcsx_rearmed_duping_enable = "enabled" +pcsx_rearmed_frameskip_type = "disabled" +pcsx_rearmed_gteregsunneeded = "disabled" +pcsx_rearmed_gunconadjustratiox = "1" +pcsx_rearmed_gunconadjustratioy = "1" +pcsx_rearmed_gunconadjustx = "0" +pcsx_rearmed_gunconadjusty = "0" +pcsx_rearmed_idiablofix = "disabled" +pcsx_rearmed_input_sensitivity = "1.00" +pcsx_rearmed_inuyasha_fix = "disabled" +pcsx_rearmed_memcard2 = "disabled" +pcsx_rearmed_multitap1 = "auto" +pcsx_rearmed_multitap2 = "auto" +pcsx_rearmed_negcon_deadzone = "0" +pcsx_rearmed_negcon_response = "linear" +pcsx_rearmed_neon_enhancement_enable = "disabled" +pcsx_rearmed_neon_enhancement_no_main = "disabled" +pcsx_rearmed_neon_interlace_enable = "disabled" +pcsx_rearmed_nocdaudio = "enabled" +pcsx_rearmed_nogteflags = "disabled" +pcsx_rearmed_nosmccheck = "disabled" +pcsx_rearmed_noxadecoding = "enabled" +pcsx_rearmed_pad1type = "standard" +pcsx_rearmed_pad2type = "standard" +pcsx_rearmed_pad3type = "none" +pcsx_rearmed_pad4type = "none" +pcsx_rearmed_pad5type = "none" +pcsx_rearmed_pad6type = "none" +pcsx_rearmed_pad7type = "none" +pcsx_rearmed_pad8type = "none" +pcsx_rearmed_pe2_fix = "disabled" +pcsx_rearmed_psxclock = "57" +pcsx_rearmed_region = "auto" +pcsx_rearmed_show_bios_bootlogo = "disabled" +pcsx_rearmed_show_other_input_settings = "disabled" +pcsx_rearmed_spu_interpolation = "simple" +pcsx_rearmed_spu_reverb = "enabled" +pcsx_rearmed_spuirq = "disabled" +pcsx_rearmed_vibration = "enabled" +gambatte_gb_colorization = "disabled" +gambatte_gb_internal_palette = "" +mame2003-plus_analog = "digital" +mame2003-plus_art_resolution = "1" +mame2003-plus_brightness = "1.0" +mame2003-plus_cheat_input_ports = "disabled" +mame2003-plus_core_save_subfolder = "enabled" +mame2003-plus_core_sys_subfolder = "enabled" +mame2003-plus_dcs_speedhack = "enabled" +mame2003-plus_deadzone = "20" +mame2003-plus_digital_joy_centering = "enabled" +mame2003-plus_display_artwork = "enabled" +mame2003-plus_display_setup = "disabled" +mame2003-plus_four_way_emulation = "disabled" +mame2003-plus_frameskip = "0" +mame2003-plus_gamma = "1.0" +mame2003-plus_input_interface = "retropad" +mame2003-plus_machine_timing = "enabled" +mame2003-plus_mame_remapping = "enabled" +mame2003-plus_mouse_device = "mouse" +mame2003-plus_sample_rate = "48000" +mame2003-plus_skip_disclaimer = "disabled" +mame2003-plus_skip_warnings = "disabled" +flycast_internal_resolution = "640x480" +flycast_alpha_sorting = "per-strip (fast, least accurate)" +flycast_enable_dsp = "disabled" +flycast_threaded_rendering = "enabled" +flycast_anisotropic_filtering = "off" +flycast_synchronous_rendering = "enabled" +flycast_enable_rtt = "disabled" +flycast_enable_rttb = "disabled" +flycast_delay_frame_swapping = "disabled" +flycast_div_matching = "auto" +flycast_texupscale = "off" +flycast_auto_skip_frame = "normal" +opera_swi_hle = "enabled" +opera_dsp_threaded = "enabled" +opera_madam_matrix_engine = "software" +puae_deadzone = "25" +melonds_screen_layout = "Left/Right" +melonds_swapscreen_mode = "Toggle" +melonds_threaded_renderer = "enabled" +melonds_touch_mode = "Joystick" +virtualjaguar_bios = "enabled" +virtualjaguar_usefastblitter = "enabled" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8550/retroarch.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8550/retroarch.cfg new file mode 100644 index 0000000000..8eb383db75 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8550/retroarch.cfg @@ -0,0 +1,894 @@ +accessibility_enable = "false" +accessibility_narrator_speech_speed = "5" +ai_service_mode = "1" +ai_service_pause = "false" +ai_service_source_lang = "0" +ai_service_target_lang = "0" +all_users_control_menu = "true" +app_icon = "default" +apply_cheats_after_load = "false" +apply_cheats_after_toggle = "false" +audio_block_frames = "0" +audio_device = "" +audio_driver = "alsathread" +audio_dsp_plugin = "" +audio_enable = "true" +audio_enable_menu = "false" +audio_enable_menu_bgm = "false" +audio_enable_menu_cancel = "false" +audio_enable_menu_notice = "false" +audio_enable_menu_ok = "false" +audio_enable_menu_scroll = "false" +audio_fastforward_mute = "false" +audio_fastforward_speedup = "false" +audio_max_timing_skew = "0.049999" +audio_mixer_mute_enable = "false" +audio_mixer_volume = "0.000000" +audio_mute_enable = "false" +audio_out_rate = "48000" +audio_rate_control = "true" +audio_rate_control_delta = "0.004999" +audio_resampler = "sinc" +audio_resampler_quality = "2" +audio_sync = "true" +audio_volume = "0.000000" +auto_overrides_enable = "true" +auto_remaps_enable = "true" +auto_screenshot_filename = "true" +auto_shaders_enable = "true" +autosave_interval = "10" +block_sram_overwrite = "false" +bluetooth_driver = "null" +builtin_imageviewer_enable = "false" +builtin_mediaplayer_enable = "true" +bundle_assets_dst_path = "" +bundle_assets_dst_path_subdir = "" +bundle_assets_extract_enable = "false" +bundle_assets_extract_last_version = "0" +bundle_assets_extract_version_current = "0" +bundle_assets_src_path = "" +camera_allow = "false" +camera_device = "" +camera_driver = "null" +check_firmware_before_loading = "false" +cheevos_appearance_anchor = "0" +cheevos_appearance_padding_auto = "true" +cheevos_appearance_padding_h = "0.000000" +cheevos_appearance_padding_v = "0.000000" +cheevos_auto_screenshot = "false" +cheevos_badges_enable = "false" +cheevos_challenge_indicators = "true" +cheevos_custom_host = "" +cheevos_hardcore_mode_enable = "false" +cheevos_leaderboards_enable = "" +cheevos_password = "" +cheevos_richpresence_enable = "true" +cheevos_start_active = "false" +cheevos_test_unofficial = "false" +cheevos_token = "" +cheevos_unlock_sound_enable = "false" +cheevos_username = "" +cheevos_verbose_enable = "false" +cheevos_visibility_account = "true" +cheevos_visibility_lboard_cancel = "true" +cheevos_visibility_lboard_start = "true" +cheevos_visibility_lboard_submit = "true" +cheevos_visibility_lboard_trackers = "true" +cheevos_visibility_mastery = "true" +cheevos_visibility_progress_tracker = "true" +cheevos_visibility_summary = "1" +cheevos_visibility_unlock = "true" +cloud_sync_destructive = "false" +cloud_sync_driver = "" +cloud_sync_enable = "false" +config_save_on_exit = "false" +content_favorites_directory = "default" +content_favorites_path = "~/.config/retroarch/content_favorites.lpl" +content_favorites_size = "200" +content_history_dir = "" +content_history_directory = "default" +content_history_path = "~/.config/retroarch/content_history.lpl" +content_history_size = "200" +content_image_history_directory = "default" +content_image_history_path = "~/.config/retroarch/content_image_history.lpl" +content_music_history_directory = "default" +content_music_history_path = "~/.config/retroarch/content_music_history.lpl" +content_runtime_log = "true" +content_runtime_log_aggregate = "false" +content_show_add = "true" +content_show_add_entry = "2" +content_show_contentless_cores = "2" +content_show_explore = "true" +content_show_favorites = "true" +content_show_history = "true" +content_show_images = "false" +content_show_music = "false" +content_show_netplay = "true" +content_show_playlists = "true" +content_show_settings = "true" +content_show_settings_password = "" +content_show_video = "false" +content_video_directory = "default" +content_video_history_path = "~/.config/retroarch/content_video_history.lpl" +core_assets_directory = "~/roms/downloads" +core_info_cache_enable = "true" +core_info_savestate_bypass = "false" +core_option_category_enable = "true" +core_options_path = "" +core_set_supports_no_game_enable = "true" +core_updater_auto_backup = "false" +core_updater_auto_backup_history_size = "1" +core_updater_auto_extract_archive = "true" +core_updater_buildbot_assets_url = "http://buildbot.libretro.com/assets/" +core_updater_buildbot_cores_url = "" +core_updater_buildbot_url = "http://buildbot.libretro.com/nightly/linux/armhf/latest/" +core_updater_show_experimental_cores = "false" +cpu_main_gov = "performance" +cpu_max_freq = "-1" +cpu_menu_gov = "interactive" +cpu_min_freq = "1" +cpu_scaling_mode = "0" +crt_switch_center_adjust = "0" +crt_switch_hires_menu = "false" +crt_switch_porch_adjust = "0" +crt_switch_resolution = "0" +crt_switch_resolution_super = "2560" +crt_switch_resolution_use_custom_refresh_rate = "false" +crt_switch_timings = "" +crt_video_refresh_rate = "60.000000" +current_resolution_id = "0" +cursor_directory = "~/.config/retroarch/database/cursors" +custom_viewport_height = "1080" +custom_viewport_width = "1920" +custom_viewport_x = "0" +custom_viewport_y = "0" +desktop_menu_enable = "true" +discord_allow = "false" +discord_app_id = "475456035851599874" +driver_switch_enable = "true" +dynamic_wallpapers_directory = "default" +emuelec_exit_to_kodi = "false" +enable_device_vibration = "true" +facebook_stream_key = "" +fastforward_frameskip = "true" +fastforward_ratio = "0.000000" +filter_by_current_core = "false" +flicker_filter_enable = "false" +flicker_filter_index = "0" +fps_update_interval = "256" +frame_time_counter_reset_after_fastforwarding = "false" +frame_time_counter_reset_after_load_state = "false" +frame_time_counter_reset_after_save_state = "false" +framecount_show = "false" +frontend_log_level = "1" +game_specific_options = "true" +gamemode_enable = "false" +gamma_correction = "0" +global_core_options = "false" +history_list_enable = "true" +initial_disk_change_enable = "true" +input_ai_service = "nul" +input_ai_service_axis = "nul" +input_ai_service_btn = "nul" +input_ai_service_mbtn = "nul" +input_allow_turbo_dpad = "false" +input_analog_deadzone = "0.100000" +input_analog_sensitivity = "1.500000" +input_audio_mute = "nul" +input_audio_mute_axis = "nul" +input_audio_mute_btn = "nul" +input_audio_mute_mbtn = "nul" +input_auto_game_focus = "0" +input_auto_mouse_grab = "false" +input_autodetect_enable = "true" +input_axis_threshold = "0.500000" +input_bind_hold = "2" +input_bind_timeout = "5" +input_cheat_index_minus = "nul" +input_cheat_index_minus_axis = "nul" +input_cheat_index_minus_btn = "nul" +input_cheat_index_minus_mbtn = "nul" +input_cheat_index_plus = "nul" +input_cheat_index_plus_axis = "nul" +input_cheat_index_plus_btn = "nul" +input_cheat_index_plus_mbtn = "nul" +input_cheat_toggle = "nul" +input_cheat_toggle_axis = "nul" +input_cheat_toggle_btn = "nul" +input_cheat_toggle_mbtn = "nul" +input_close_content = "nul" +input_close_content_axis = "nul" +input_close_content_btn = "nul" +input_close_content_mbtn = "nul" +input_descriptor_hide_unbound = "false" +input_descriptor_label_show = "true" +input_desktop_menu_toggle = "f5" +input_desktop_menu_toggle_axis = "nul" +input_desktop_menu_toggle_btn = "nul" +input_desktop_menu_toggle_mbtn = "nul" +input_device_p1 = "0" +input_device_p10 = "0" +input_device_p11 = "0" +input_device_p12 = "0" +input_device_p13 = "0" +input_device_p14 = "0" +input_device_p15 = "0" +input_device_p16 = "0" +input_device_p2 = "0" +input_device_p3 = "0" +input_device_p4 = "0" +input_device_p5 = "0" +input_device_p6 = "0" +input_device_p7 = "0" +input_device_p8 = "0" +input_device_p9 = "0" +input_disk_eject_toggle = "nul" +input_disk_eject_toggle_axis = "nul" +input_disk_eject_toggle_btn = "nul" +input_disk_eject_toggle_mbtn = "nul" +input_disk_next = "nul" +input_disk_next_axis = "nul" +input_disk_next_btn = "nul" +input_disk_next_mbtn = "nul" +input_disk_prev = "nul" +input_disk_prev_axis = "nul" +input_disk_prev_btn = "nul" +input_disk_prev_mbtn = "nul" +input_driver = "udev" +input_duty_cycle = "3" +input_enable_hotkey = "nul" +input_enable_hotkey_axis = "nul" +input_enable_hotkey_btn = "nul" +input_enable_hotkey_mbtn = "nul" +input_exit_emulator = "nul" +input_exit_emulator_axis = "nul" +input_exit_emulator_btn = "nul" +input_exit_emulator_mbtn = "nul" +input_fps_toggle = "nul" +input_fps_toggle_axis = "nul" +input_fps_toggle_btn = "nul" +input_fps_toggle_mbtn = "nul" +input_frame_advance = "nul" +input_frame_advance_axis = "nul" +input_frame_advance_btn = "nul" +input_frame_advance_mbtn = "nul" +input_game_focus_toggle = "nul" +input_game_focus_toggle_axis = "nul" +input_game_focus_toggle_btn = "nul" +input_game_focus_toggle_mbtn = "nul" +input_grab_mouse_toggle = "nul" +input_grab_mouse_toggle_axis = "nul" +input_grab_mouse_toggle_btn = "nul" +input_grab_mouse_toggle_mbtn = "nul" +input_halt_replay = "nul" +input_halt_replay_axis = "nul" +input_halt_replay_btn = "nul" +input_halt_replay_mbtn = "nul" +input_hold_fast_forward = "nul" +input_hold_fast_forward_axis = "nul" +input_hold_fast_forward_btn = "nul" +input_hold_fast_forward_mbtn = "nul" +input_hold_slowmotion = "nul" +input_hold_slowmotion_axis = "nul" +input_hold_slowmotion_btn = "nul" +input_hold_slowmotion_mbtn = "nul" +input_hotkey_block_delay = "5" +input_hotkey_device_merge = "false" +input_joypad_driver = "udev" +input_keyboard_layout = "" +input_libretro_device_p1 = "1" +input_libretro_device_p10 = "1" +input_libretro_device_p11 = "1" +input_libretro_device_p12 = "1" +input_libretro_device_p13 = "1" +input_libretro_device_p14 = "1" +input_libretro_device_p15 = "1" +input_libretro_device_p16 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_libretro_device_p6 = "1" +input_libretro_device_p7 = "1" +input_libretro_device_p8 = "1" +input_libretro_device_p9 = "1" +input_load_state = "nul" +input_load_state_axis = "nul" +input_load_state_btn = "nul" +input_load_state_mbtn = "nul" +input_max_users = "5" +input_menu_toggle = "nul" +input_menu_toggle_axis = "nul" +input_menu_toggle_btn = "nul" +input_menu_toggle_gamepad_combo = "nul" +input_menu_toggle_mbtn = "nul" +input_movie_record_toggle = "o" +input_movie_record_toggle_axis = "nul" +input_movie_record_toggle_btn = "nul" +input_movie_record_toggle_mbtn = "nul" +input_netplay_fade_chat_toggle = "nul" +input_netplay_fade_chat_toggle_axis = "nul" +input_netplay_fade_chat_toggle_btn = "nul" +input_netplay_fade_chat_toggle_mbtn = "nul" +input_netplay_game_watch = "nul" +input_netplay_game_watch_axis = "nul" +input_netplay_game_watch_btn = "nul" +input_netplay_game_watch_mbtn = "nul" +input_netplay_host_toggle = "nul" +input_netplay_host_toggle_axis = "nul" +input_netplay_host_toggle_btn = "nul" +input_netplay_host_toggle_mbtn = "nul" +input_netplay_ping_toggle = "nul" +input_netplay_ping_toggle_axis = "nul" +input_netplay_ping_toggle_btn = "nul" +input_netplay_ping_toggle_mbtn = "nul" +input_netplay_player_chat = "nul" +input_netplay_player_chat_axis = "nul" +input_netplay_player_chat_btn = "nul" +input_netplay_player_chat_mbtn = "nul" +input_nowinkey_enable = "false" +input_osk_overlay = "" +input_osk_overlay_auto_scale = "false" +input_osk_overlay_opacity = "0.700000" +input_osk_toggle = "nul" +input_osk_toggle_axis = "nul" +input_osk_toggle_btn = "nul" +input_osk_toggle_mbtn = "nul" +input_overlay = "" +input_overlay_aspect_adjust_landscape = "0.000000" +input_overlay_aspect_adjust_portrait = "0.000000" +input_overlay_auto_rotate = "false" +input_overlay_auto_scale = "false" +input_overlay_enable_autopreferred = "true" +input_overlay_enable = "false" +input_overlay_hide_in_menu = "true" +input_overlay_hide_when_gamepad_connected = "false" +input_overlay_next_axis = "nul" +input_overlay_next_btn = "nul" +input_overlay_next_mbtn = "nul" +input_overlay_next = "nul" +input_overlay_opacity = "0.700000" +input_overlay_scale_landscape = "1.000000" +input_overlay_scale_portrait = "1.000000" +input_overlay_show_inputs = "2" +input_overlay_show_inputs_port = "0" +input_overlay_show_mouse_cursor = "true" +input_overlay_x_offset_landscape = "0.000000" +input_overlay_x_offset_portrait = "0.000000" +input_overlay_x_separation_landscape = "0.000000" +input_overlay_x_separation_portrait = "0.000000" +input_overlay_y_offset_landscape = "0.000000" +input_overlay_y_offset_portrait = "0.000000" +input_overlay_y_separation_landscape = "0.000000" +input_overlay_y_separation_portrait = "0.000000" +input_pause_toggle = "nul" +input_pause_toggle_axis = "nul" +input_pause_toggle_btn = "nul" +input_pause_toggle_mbtn = "nul" +input_play_replay = "nul" +input_play_replay_axis = "nul" +input_play_replay_btn = "nul" +input_play_replay_mbtn = "nul" +input_poll_type_behavior = "2" +input_preempt_toggle = "nul" +input_preempt_toggle_axis = "nul" +input_preempt_toggle_btn = "nul" +input_preempt_toggle_mbtn = "nul" +input_quit_gamepad_combo = "0" +input_record_replay = "nul" +input_record_replay_axis = "nul" +input_record_replay_btn = "nul" +input_record_replay_mbtn = "nul" +input_recording_toggle = "nul" +input_recording_toggle_axis = "nul" +input_recording_toggle_btn = "nul" +input_recording_toggle_mbtn = "nul" +input_remap_binds_enable = "true" +input_remapping_directory = "~/remappings" +input_replay_slot_decrease = "nul" +input_replay_slot_decrease_axis = "nul" +input_replay_slot_decrease_btn = "nul" +input_replay_slot_decrease_mbtn = "nul" +input_replay_slot_increase = "nul" +input_replay_slot_increase_axis = "nul" +input_replay_slot_increase_btn = "nul" +input_replay_slot_increase_mbtn = "nul" +input_reset = "nul" +input_reset_axis = "nul" +input_reset_btn = "nul" +input_reset_mbtn = "nul" +input_rewind = "nul" +input_rewind_axis = "nul" +input_rewind_btn = "nul" +input_rewind_mbtn = "nul" +input_rumble_gain = "25" +input_runahead_toggle = "nul" +input_runahead_toggle_axis = "nul" +input_runahead_toggle_btn = "nul" +input_runahead_toggle_mbtn = "nul" +input_save_state = "nul" +input_save_state_axis = "nul" +input_save_state_btn = "nul" +input_save_state_mbtn = "nul" +input_screenshot = "nul" +input_screenshot_axis = "nul" +input_screenshot_btn = "nul" +input_screenshot_mbtn = "nul" +input_send_debug_info = "f10" +input_send_debug_info_axis = "nul" +input_send_debug_info_btn = "nul" +input_send_debug_info_mbtn = "nul" +input_sensors_enable = "true" +input_shader_next = "nul" +input_shader_next_axis = "nul" +input_shader_next_btn = "nul" +input_shader_next_mbtn = "nul" +input_shader_prev = "nul" +input_shader_prev_axis = "nul" +input_shader_prev_btn = "nul" +input_shader_prev_mbtn = "nul" +input_shader_toggle = "nul" +input_shader_toggle_axis = "nul" +input_shader_toggle_btn = "nul" +input_shader_toggle_mbtn = "nul" +input_state_slot_decrease = "nul" +input_state_slot_decrease_axis = "nul" +input_state_slot_decrease_btn = "nul" +input_state_slot_decrease_mbtn = "nul" +input_state_slot_increase = "nul" +input_state_slot_increase_axis = "nul" +input_state_slot_increase_btn = "nul" +input_state_slot_increase_mbtn = "nul" +input_streaming_toggle = "nul" +input_streaming_toggle_axis = "nul" +input_streaming_toggle_btn = "nul" +input_streaming_toggle_mbtn = "nul" +input_toggle_fast_forward = "nul" +input_toggle_fast_forward_axis = "nul" +input_toggle_fast_forward_btn = "nul" +input_toggle_fast_forward_mbtn = "nul" +input_toggle_fullscreen = "nul" +input_toggle_fullscreen_axis = "nul" +input_toggle_fullscreen_btn = "nul" +input_toggle_fullscreen_mbtn = "nul" +input_toggle_slowmotion = "nul" +input_toggle_slowmotion_axis = "nul" +input_toggle_slowmotion_btn = "nul" +input_toggle_slowmotion_mbtn = "nul" +input_toggle_statistics = "nul" +input_toggle_statistics_axis = "nul" +input_toggle_statistics_btn = "nul" +input_toggle_statistics_mbtn = "nul" +input_toggle_vrr_runloop = "nul" +input_toggle_vrr_runloop_axis = "nul" +input_toggle_vrr_runloop_btn = "nul" +input_toggle_vrr_runloop_mbtn = "nul" +input_touch_scale = "1" +input_touch_vmouse_gesture = "true" +input_touch_vmouse_mouse = "true" +input_touch_vmouse_pointer = "true" +input_touch_vmouse_touchpad = "true" +input_touch_vmouse_trackball = "false" +input_turbo_default_button = "0" +input_turbo_mode = "0" +input_turbo_period = "6" +input_volume_down = "nul" +input_volume_down_axis = "nul" +input_volume_down_btn = "nul" +input_volume_down_mbtn = "nul" +input_volume_up = "nul" +input_volume_up_axis = "nul" +input_volume_up_btn = "nul" +input_volume_up_mbtn = "nul" +keyboard_gamepad_enable = "true" +keyboard_gamepad_mapping_type = "1" +kiosk_mode_enable = "false" +kiosk_mode_password = "" +led_driver = "null" +libretro_log_level = "1" +load_dummy_on_core_shutdown = "true" +location_allow = "false" +location_driver = "null" +log_dir = "~/.config/retroarch/logs" +log_to_file = "true" +log_to_file_timestamp = "false" +log_verbosity = "true" +materialui_auto_rotate_nav_bar = "true" +materialui_dual_thumbnail_list_view_enable = "true" +materialui_icons_enable = "true" +materialui_landscape_layout_optimization = "1" +materialui_menu_color_theme = "9" +materialui_menu_transition_animation = "0" +materialui_playlist_icons_enable = "true" +materialui_show_nav_bar = "true" +materialui_switch_icons = "true" +materialui_thumbnail_background_enable = "true" +materialui_thumbnail_view_landscape = "2" +materialui_thumbnail_view_portrait = "1" +memory_show = "false" +memory_update_interval = "256" +menu_battery_level_enable = "true" +menu_core_enable = "true" +menu_disable_info_button = "false" +menu_disable_search_button = "false" +menu_driver = "ozone" +menu_dynamic_wallpaper_enable = "false" +menu_enable_widgets = "true" +menu_font_color_blue = "255" +menu_font_color_green = "255" +menu_font_color_red = "255" +menu_footer_opacity = "1.000000" +menu_framebuffer_opacity = "0.899999" +menu_header_opacity = "1.000000" +menu_horizontal_animation = "true" +menu_insert_disk_resume = "true" +menu_left_thumbnails = "0" +menu_linear_filter = "false" +menu_mouse_enable = "false" +menu_navigation_browser_filter_supported_extensions_enable = "true" +menu_navigation_wraparound_enable = "true" +menu_pause_libretro = "true" +menu_pointer_enable = "true" +menu_remember_selection = "1" +menu_rgui_full_width_layout = "true" +menu_rgui_shadows = "false" +menu_rgui_transparency = "true" +menu_savestate_resume = "true" +menu_scale_factor = "0.300000" +menu_screensaver_animation = "0" +menu_screensaver_animation_speed = "1.000000" +menu_screensaver_timeout = "0" +menu_scroll_delay = "256" +menu_scroll_fast = "false" +menu_shader_pipeline = "2" +menu_show_advanced_settings = "true" +menu_show_configurations = "true" +menu_show_core_updater = "false" +menu_show_dump_disc = "true" +menu_show_help = "true" +menu_show_information = "true" +menu_show_latency = "true" +menu_show_legacy_thumbnail_updater = "false" +menu_show_load_content = "true" +menu_show_load_content_animation = "false" +menu_show_load_core = "true" +menu_show_load_disc = "true" +menu_show_online_updater = "true" +menu_show_overlays = "true" +menu_show_quit_retroarch = "true" +menu_show_reboot = "false" +menu_show_restart_retroarch = "true" +menu_show_rewind = "true" +menu_show_shutdown = "false" +menu_show_sublabels = "true" +menu_show_video_layout = "true" +menu_swap_ok_cancel_buttons = "false" +menu_swap_scroll_buttons = "false" +menu_throttle_framerate = "true" +menu_thumbnail_upscale_threshold = "0" +menu_thumbnails = "3" +menu_ticker_smooth = "true" +menu_ticker_speed = "2.000000" +menu_ticker_type = "1" +menu_timedate_date_separator = "0" +menu_timedate_enable = "true" +menu_timedate_style = "11" +menu_unified_controls = "false" +menu_use_preferred_system_color_theme = "false" +menu_wallpaper = "" +menu_wallpaper_opacity = "1.000000" +menu_widget_scale_auto = "false" +menu_widget_scale_factor = "0.350000" +menu_widget_scale_factor_windowed = "1.000000" +menu_xmb_animation_horizontal_highlight = "0" +menu_xmb_animation_move_up_down = "0" +menu_xmb_animation_opening_main_menu = "0" +menu_xmb_show_title_header = "true" +menu_xmb_thumbnail_scale_factor = "100" +menu_xmb_title_margin = "5" +menu_xmb_title_margin_horizontal_offset = "0" +menu_xmb_vertical_fade_factor = "100" +microphone_block_frames = "0" +microphone_device = "" +microphone_driver = "alsathread" +microphone_enable = "true" +microphone_latency = "64" +microphone_rate = "48000" +microphone_resampler = "sinc" +microphone_resampler_quality = "3" +midi_driver = "alsa" +midi_input = "OFF" +midi_output = "OFF" +midi_volume = "100" +network_cmd_enable = "false" +network_cmd_port = "55355" +network_on_demand_thumbnails = "false" +network_remote_base_port = "55400" +network_remote_enable = "false" +network_remote_enable_user_p1 = "false" +network_remote_enable_user_p10 = "false" +network_remote_enable_user_p11 = "false" +network_remote_enable_user_p12 = "false" +network_remote_enable_user_p13 = "false" +network_remote_enable_user_p14 = "false" +network_remote_enable_user_p15 = "false" +network_remote_enable_user_p16 = "false" +network_remote_enable_user_p2 = "false" +network_remote_enable_user_p3 = "false" +network_remote_enable_user_p4 = "false" +network_remote_enable_user_p5 = "false" +network_remote_enable_user_p6 = "false" +network_remote_enable_user_p7 = "false" +network_remote_enable_user_p8 = "false" +network_remote_enable_user_p9 = "false" +notification_show_autoconfig = "false" +notification_show_cheats_applied = "true" +notification_show_config_override_load = "false" +notification_show_disk_control = "true" +notification_show_fast_forward = "true" +notification_show_netplay_extra = "false" +notification_show_patch_applied = "true" +notification_show_refresh_rate = "true" +notification_show_remap_load = "false" +notification_show_save_state = "true" +notification_show_screenshot = "false" +notification_show_screenshot_duration = "2" +notification_show_screenshot_flash = "1" +notification_show_set_initial_disk = "true" +notification_show_when_menu_is_alive = "false" +osk_overlay_directory = "/tmp/overlays/keyboards" +ozone_collapse_sidebar = "false" +ozone_menu_color_theme = "1" +ozone_scroll_content_metadata = "false" +ozone_sort_after_truncate_playlist_name = "true" +ozone_thumbnail_scale_factor = "1.000000" +ozone_truncate_playlist_name = "true" +pause_nonactive = "true" +pause_on_disconnect = "false" +perfcnt_enable = "false" +playlist_compression = "false" +playlist_cores = "" +playlist_directory = "~/playlists" +playlist_entry_remove = "false" +playlist_entry_remove_enable = "1" +playlist_entry_rename = "false" +playlist_fuzzy_archive_match = "false" +playlist_names = "" +playlist_portable_paths = "false" +playlist_show_entry_idx = "true" +playlist_show_history_icons = "1" +playlist_show_inline_core_name = "0" +playlist_show_sublabels = "true" +playlist_sort_alphabetical = "true" +playlist_sublabel_last_played_style = "0" +playlist_sublabel_runtime_type = "0" +playlist_use_filename = "false" +playlist_use_old_format = "false" +preemptive_frames_enable = "false" +preemptive_frames_hide_warnings = "false" +quick_menu_show_add_to_favorites = "true" +quick_menu_show_add_to_playlist = "false" +quick_menu_show_cheats = "true" +quick_menu_show_close_content = "true" +quick_menu_show_controls = "true" +quick_menu_show_core_options_flush = "false" +quick_menu_show_download_thumbnails = "true" +quick_menu_show_information = "true" +quick_menu_show_options = "true" +quick_menu_show_recording = "true" +quick_menu_show_replay = "false" +quick_menu_show_reset_core_association = "true" +quick_menu_show_restart_content = "true" +quick_menu_show_resume_content = "true" +quick_menu_show_save_content_dir_overrides = "true" +quick_menu_show_save_core_overrides = "false" +quick_menu_show_save_game_overrides = "false" +quick_menu_show_save_load_state = "true" +quick_menu_show_savestate_submenu = "true" +quick_menu_show_set_core_association = "true" +quick_menu_show_shaders = "true" +quick_menu_show_start_recording = "true" +quick_menu_show_start_streaming = "true" +quick_menu_show_streaming = "true" +quick_menu_show_take_screenshot = "true" +quick_menu_show_undo_save_load_state = "false" +quit_on_close_content = "0" +quit_press_twice = "true" +record_driver = "null" +recording_config_directory = "" +recording_output_directory = "~/roms/screenshots" +remap_save_on_exit = "true" +replay_auto_index = "true" +replay_checkpoint_interval = "0" +replay_max_keep = "0" +replay_slot = "0" +resampler_directory = "" +rewind_buffer_size = "20971520" +rewind_buffer_size_step = "10" +rewind_granularity = "1" +rgui_aspect_ratio = "0" +rgui_aspect_ratio_lock = "0" +rgui_background_filler_thickness_enable = "true" +rgui_border_filler_enable = "true" +rgui_border_filler_thickness_enable = "true" +rgui_browser_directory = "~/roms" +rgui_config_directory = "~/.config/retroarch/config" +rgui_extended_ascii = "false" +rgui_inline_thumbnails = "false" +rgui_internal_upscale_level = "0" +rgui_menu_color_theme = "4" +rgui_menu_theme_preset = "" +rgui_particle_effect = "0" +rgui_particle_effect_screensaver = "true" +rgui_particle_effect_speed = "1.000000" +rgui_show_start_screen = "false" +rgui_swap_thumbnails = "false" +rgui_switch_icons = "true" +rgui_thumbnail_delay = "0" +rgui_thumbnail_downscaler = "0" +run_ahead_hide_warnings = "false" +run_ahead_secondary_instance = "true" +runtime_log_directory = "default" +save_file_compression = "false" +savefile_directory = "~/.config/retroarch/saves" +savefiles_in_content_dir = "true" +savestate_file_compression = "true" +savestate_thumbnail_enable = "true" +savestates_in_content_dir = "false" +scan_serial_and_crc = "false" +scan_without_core_match = "false" +screen_brightness = "100" +screen_orientation = "0" +screenshot_directory = "~/roms/screenshots" +screenshots_in_content_dir = "false" +settings_show_accessibility = "true" +settings_show_achievements = "true" +settings_show_ai_service = "true" +settings_show_audio = "true" +settings_show_configuration = "true" +settings_show_core = "true" +settings_show_directory = "true" +settings_show_drivers = "true" +settings_show_file_browser = "true" +settings_show_frame_throttle = "true" +settings_show_input = "true" +settings_show_latency = "true" +settings_show_logging = "true" +settings_show_network = "true" +settings_show_onscreen_display = "true" +settings_show_playlists = "true" +settings_show_power_management = "true" +settings_show_recording = "true" +settings_show_saving = "true" +settings_show_user = "true" +settings_show_user_interface = "true" +settings_show_video = "true" +show_hidden_files = "false" +slowmotion_ratio = "3.000000" +soft_filter_enable = "false" +soft_filter_index = "0" +sort_savefiles_by_content_enable = "false" +sort_savefiles_enable = "false" +sort_savestates_by_content_enable = "false" +sort_savestates_enable = "false" +sort_screenshots_by_content_enable = "false" +statistics_show = "false" +stdin_cmd_enable = "false" +streaming_mode = "0" +suspend_screensaver_enable = "true" +sustained_performance_mode = "false" +system_directory = "~/roms/bios" +systemfiles_in_content_dir = "false" +test_input_file_joypad = "" +threaded_data_runloop_enable = "true" +thumbnails_directory = "~/thumbnails" +twitch_stream_key = "" +ui_companion_enable = "false" +ui_companion_start_on_boot = "true" +ui_companion_toggle = "false" +ui_menubar_enable = "true" +use_last_start_directory = "false" +user_language = "0" +vibrate_on_keypress = "true" +video_adaptive_vsync = "false" +video_allow_rotate = "true" +video_aspect_ratio = "-1.000000" +video_aspect_ratio_auto = "true" +video_autoswitch_pal_threshold = "54.500000" +video_autoswitch_refresh_rate = "0" +video_bfi_dark_frames = "1" +video_black_frame_insertion = "0" +video_context_driver = "" +video_crop_overscan = "true" +video_disable_composition = "false" +video_driver = "glcore" +video_font_enable = "true" +video_font_path = "/usr/share/retroarch-assets/xmb/monochrome/font.ttf" +video_font_size = "32.000000" +video_force_aspect = "true" +video_force_srgb_disable = "false" +video_frame_delay = "0" +video_frame_delay_auto = "false" +video_frame_rest = "false" +video_fullscreen = "true" +video_fullscreen_x = "1920" +video_fullscreen_y = "1080" +video_gpu_record = "false" +video_gpu_screenshot = "false" +video_hard_sync = "false" +video_hard_sync_frames = "0" +video_hdr_display_contrast = "5.000000" +video_hdr_enable = "false" +video_hdr_expand_gamut = "true" +video_hdr_max_nits = "1000.000000" +video_hdr_paper_white_nits = "200.000000" +video_layout_directory = "~/.config/retroarch/layouts" +video_layout_enable = "true" +video_layout_path = "" +video_layout_selected_view = "0" +video_max_frame_latency = "1" +video_max_swapchain_images = "3" +video_message_color = "ffff00" +video_message_pos_x = "0.049999" +video_message_pos_y = "0.049999" +video_monitor_index = "0" +video_msg_bgcolor_blue = "0" +video_msg_bgcolor_enable = "false" +video_msg_bgcolor_green = "0" +video_msg_bgcolor_opacity = "1.000000" +video_msg_bgcolor_red = "0" +video_notch_write_over_enable = "false" +video_oga_vertical_enable = "false" +video_post_filter_record = "false" +video_record_config = "" +video_record_quality = "4" +video_record_scale_factor = "1" +video_record_threads = "2" +video_refresh_rate = "60.000000" +video_scale = "3" +video_scan_subframes = "false" +video_shared_context = "false" +video_stream_config = "" +video_stream_port = "56400" +video_stream_quality = "10" +video_stream_scale_factor = "1" +video_stream_url = "" +video_swap_interval = "1" +video_threaded = "false" +video_vsync = "true" +video_waitable_swapchains = "true" +video_window_auto_height_max = "1080" +video_window_auto_width_max = "1920" +video_window_custom_size_enable = "false" +video_window_opacity = "100" +video_window_save_positions = "false" +video_window_show_decorations = "true" +video_windowed_fullscreen = "false" +video_windowed_position_height = "720" +video_windowed_position_width = "1280" +video_windowed_position_x = "0" +video_windowed_position_y = "0" +vrr_runloop_enable = "false" +vulkan_gpu_index = "0" +webdav_password = "" +webdav_url = "" +webdav_username = "" +wifi_driver = "null" +wifi_enabled = "true" +xmb_alpha_factor = "75" +xmb_font = "/usr/share/retroarch-assets/xmb/monochrome/font.ttf" +xmb_layout = "2" +xmb_menu_color_theme = "4" +xmb_shadows_enable = "true" +xmb_switch_icons = "true" +xmb_theme = "0" +xmb_vertical_thumbnails = "false" +youtube_stream_key = "" +assets_directory = "/tmp/assets" +cache_directory = "/tmp/cache" +cheat_database_path = "/tmp/database/cht" +content_database_path = "/tmp/database/rdb" +joypad_autoconfig_dir = "/tmp/joypads" +libretro_directory = "/tmp/cores" +libretro_info_path = "/tmp/cores" +overlay_directory = "/tmp/overlays" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8550/retroarch32bit-append.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8550/retroarch32bit-append.cfg new file mode 100755 index 0000000000..343124c254 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8550/retroarch32bit-append.cfg @@ -0,0 +1,3 @@ +audio_filter_dir = "/usr/share/retroarch/filters/32bit/audio" +video_filter_dir = "/usr/share/retroarch/filters/32bit/video" +libretro_directory = /usr/lib32/libretro diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8550/retroarch64bit-append.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8550/retroarch64bit-append.cfg new file mode 100755 index 0000000000..b6cbf68312 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8550/retroarch64bit-append.cfg @@ -0,0 +1,2 @@ +audio_filter_dir = "/usr/share/retroarch/filters/64bit/audio" +video_filter_dir = "/usr/share/retroarch/filters/64bit/video" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8650/TATE-MAME 2003-Plus.rmp b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8650/TATE-MAME 2003-Plus.rmp new file mode 100755 index 0000000000..366e47afad --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8650/TATE-MAME 2003-Plus.rmp @@ -0,0 +1,27 @@ +input_libretro_device_p1 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_player1_analog_dpad_mode = "1" +input_player1_btn_down = "6" +input_player1_btn_left = "4" +input_player1_btn_right = "5" +input_player1_btn_up = "7" +input_player1_stk_l_x+ = "5" +input_player1_stk_l_x- = "4" +input_player1_stk_l_y+ = "6" +input_player1_stk_l_y- = "7" +input_player1_stk_r_x+ = "5" +input_player1_stk_r_x- = "4" +input_player1_stk_r_y+ = "6" +input_player1_stk_r_y- = "7" +input_player2_analog_dpad_mode = "0" +input_player3_analog_dpad_mode = "0" +input_player4_analog_dpad_mode = "0" +input_player5_analog_dpad_mode = "0" +input_remap_port_p1 = "0" +input_remap_port_p2 = "1" +input_remap_port_p3 = "2" +input_remap_port_p4 = "3" +input_remap_port_p5 = "4" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8650/retroarch-core-options.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8650/retroarch-core-options.cfg new file mode 100755 index 0000000000..f0f3122721 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8650/retroarch-core-options.cfg @@ -0,0 +1,153 @@ +mupen64plus-alt-map = "False" +mupen64plus-aspect = "4:3" +mupen64plus-astick-deadzone = "15" +mupen64plus-astick-sensitivity = "100" +mupen64plus-BackgroundMode = "Stripped" +mupen64plus-BilinearMode = "standard" +mupen64plus-CorrectTexrectCoords = "Auto" +mupen64plus-CountPerOp = "0" +mupen64plus-CountPerOpDenomPot = "0" +mupen64plus-cpucore = "dynamic_recompiler" +mupen64plus-d-cbutton = "C3" +mupen64plus-DitheringPattern = "True" +mupen64plus-DitheringQuantization = "True" +mupen64plus-EnableCopyAuxToRDRAM = "True" +mupen64plus-EnableCopyColorToRDRAM = "Async" +mupen64plus-EnableCopyDepthToRDRAM = "Software" +mupen64plus-EnableEnhancedHighResStorage = "False" +mupen64plus-EnableEnhancedTextureStorage = "False" +mupen64plus-EnableFBEmulation = "True" +mupen64plus-EnableFragmentDepthWrite = "False" +mupen64plus-EnableHiResAltCRC = "False" +mupen64plus-EnableHWLighting = "True" +mupen64plus-EnableInaccurateTextureCoordinates = "False" +mupen64plus-EnableLegacyBlending = "False" +mupen64plus-EnableLODEmulation = "True" +mupen64plus-EnableNativeResFactor = "1" +mupen64plus-EnableNativeResTexrects = "Optimized" +mupen64plus-EnableOverscan = "Enabled" +mupen64plus-EnableTexCoordBounds = "False" +mupen64plus-EnableTextureCache = "True" +mupen64plus-ForceDisableExtraMem = "False" +mupen64plus-FrameDuping = "True" +mupen64plus-Framerate = "Original" +mupen64plus-FXAA = "0" +mupen64plus-GLideN64IniBehaviour = "late" +mupen64plus-HybridFilter = "True" +mupen64plus-IgnoreTLBExceptions = "False" +mupen64plus-l-cbutton = "C2" +mupen64plus-MaxHiResTxVramLimit = "0" +mupen64plus-MaxTxCacheSize = "8000" +mupen64plus-MultiSampling = "0" +mupen64plus-OverscanBottom = "0" +mupen64plus-OverscanLeft = "0" +mupen64plus-OverscanRight = "0" +mupen64plus-OverscanTop = "0" +mupen64plus-pak1 = "memory" +mupen64plus-pak2 = "none" +mupen64plus-pak3 = "none" +mupen64plus-pak4 = "none" +mupen64plus-r-cbutton = "C1" +mupen64plus-rdp-plugin = "gliden64" +mupen64plus-RDRAMImageDitheringMode = "BlueNoise" +mupen64plus-rsp-plugin = "hle" +mupen64plus-ThreadedRenderer = "True" +mupen64plus-txCacheCompression = "True" +mupen64plus-txEnhancementMode = "None" +mupen64plus-txFilterIgnoreBG = "True" +mupen64plus-txFilterMode = "None" +mupen64plus-txHiresEnable = "False" +mupen64plus-txHiresFullAlphaChannel = "False" +mupen64plus-u-cbutton = "C4" +mupen64plus-virefresh = "Auto" +pcsx_rearmed_analog_axis_modifier = "circle" +pcsx_rearmed_async_cd = "sync" +pcsx_rearmed_bios = "auto" +pcsx_rearmed_display_internal_fps = "disabled" +pcsx_rearmed_dithering = "enabled" +pcsx_rearmed_drc = "enabled" +pcsx_rearmed_duping_enable = "enabled" +pcsx_rearmed_frameskip_type = "disabled" +pcsx_rearmed_gteregsunneeded = "disabled" +pcsx_rearmed_gunconadjustratiox = "1" +pcsx_rearmed_gunconadjustratioy = "1" +pcsx_rearmed_gunconadjustx = "0" +pcsx_rearmed_gunconadjusty = "0" +pcsx_rearmed_idiablofix = "disabled" +pcsx_rearmed_input_sensitivity = "1.00" +pcsx_rearmed_inuyasha_fix = "disabled" +pcsx_rearmed_memcard2 = "disabled" +pcsx_rearmed_multitap1 = "auto" +pcsx_rearmed_multitap2 = "auto" +pcsx_rearmed_negcon_deadzone = "0" +pcsx_rearmed_negcon_response = "linear" +pcsx_rearmed_neon_enhancement_enable = "disabled" +pcsx_rearmed_neon_enhancement_no_main = "disabled" +pcsx_rearmed_neon_interlace_enable = "disabled" +pcsx_rearmed_nocdaudio = "enabled" +pcsx_rearmed_nogteflags = "disabled" +pcsx_rearmed_nosmccheck = "disabled" +pcsx_rearmed_noxadecoding = "enabled" +pcsx_rearmed_pad1type = "standard" +pcsx_rearmed_pad2type = "standard" +pcsx_rearmed_pad3type = "none" +pcsx_rearmed_pad4type = "none" +pcsx_rearmed_pad5type = "none" +pcsx_rearmed_pad6type = "none" +pcsx_rearmed_pad7type = "none" +pcsx_rearmed_pad8type = "none" +pcsx_rearmed_pe2_fix = "disabled" +pcsx_rearmed_psxclock = "57" +pcsx_rearmed_region = "auto" +pcsx_rearmed_show_bios_bootlogo = "disabled" +pcsx_rearmed_show_other_input_settings = "disabled" +pcsx_rearmed_spu_interpolation = "simple" +pcsx_rearmed_spu_reverb = "enabled" +pcsx_rearmed_spuirq = "disabled" +pcsx_rearmed_vibration = "enabled" +gambatte_gb_colorization = "disabled" +gambatte_gb_internal_palette = "" +mame2003-plus_analog = "digital" +mame2003-plus_art_resolution = "1" +mame2003-plus_brightness = "1.0" +mame2003-plus_cheat_input_ports = "disabled" +mame2003-plus_core_save_subfolder = "enabled" +mame2003-plus_core_sys_subfolder = "enabled" +mame2003-plus_dcs_speedhack = "enabled" +mame2003-plus_deadzone = "20" +mame2003-plus_digital_joy_centering = "enabled" +mame2003-plus_display_artwork = "enabled" +mame2003-plus_display_setup = "disabled" +mame2003-plus_four_way_emulation = "disabled" +mame2003-plus_frameskip = "0" +mame2003-plus_gamma = "1.0" +mame2003-plus_input_interface = "retropad" +mame2003-plus_machine_timing = "enabled" +mame2003-plus_mame_remapping = "enabled" +mame2003-plus_mouse_device = "mouse" +mame2003-plus_sample_rate = "48000" +mame2003-plus_skip_disclaimer = "disabled" +mame2003-plus_skip_warnings = "disabled" +flycast_internal_resolution = "640x480" +flycast_alpha_sorting = "per-strip (fast, least accurate)" +flycast_enable_dsp = "disabled" +flycast_threaded_rendering = "enabled" +flycast_anisotropic_filtering = "off" +flycast_synchronous_rendering = "enabled" +flycast_enable_rtt = "disabled" +flycast_enable_rttb = "disabled" +flycast_delay_frame_swapping = "disabled" +flycast_div_matching = "auto" +flycast_texupscale = "off" +flycast_auto_skip_frame = "normal" +opera_swi_hle = "enabled" +opera_dsp_threaded = "enabled" +opera_madam_matrix_engine = "software" +puae_deadzone = "25" +melonds_screen_layout = "Left/Right" +melonds_swapscreen_mode = "Toggle" +melonds_threaded_renderer = "enabled" +melonds_touch_mode = "Joystick" +duckstation_GPU.Renderer = "Software" +virtualjaguar_bios = "enabled" +virtualjaguar_usefastblitter = "enabled" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8650/retroarch.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8650/retroarch.cfg new file mode 100644 index 0000000000..8eb383db75 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8650/retroarch.cfg @@ -0,0 +1,894 @@ +accessibility_enable = "false" +accessibility_narrator_speech_speed = "5" +ai_service_mode = "1" +ai_service_pause = "false" +ai_service_source_lang = "0" +ai_service_target_lang = "0" +all_users_control_menu = "true" +app_icon = "default" +apply_cheats_after_load = "false" +apply_cheats_after_toggle = "false" +audio_block_frames = "0" +audio_device = "" +audio_driver = "alsathread" +audio_dsp_plugin = "" +audio_enable = "true" +audio_enable_menu = "false" +audio_enable_menu_bgm = "false" +audio_enable_menu_cancel = "false" +audio_enable_menu_notice = "false" +audio_enable_menu_ok = "false" +audio_enable_menu_scroll = "false" +audio_fastforward_mute = "false" +audio_fastforward_speedup = "false" +audio_max_timing_skew = "0.049999" +audio_mixer_mute_enable = "false" +audio_mixer_volume = "0.000000" +audio_mute_enable = "false" +audio_out_rate = "48000" +audio_rate_control = "true" +audio_rate_control_delta = "0.004999" +audio_resampler = "sinc" +audio_resampler_quality = "2" +audio_sync = "true" +audio_volume = "0.000000" +auto_overrides_enable = "true" +auto_remaps_enable = "true" +auto_screenshot_filename = "true" +auto_shaders_enable = "true" +autosave_interval = "10" +block_sram_overwrite = "false" +bluetooth_driver = "null" +builtin_imageviewer_enable = "false" +builtin_mediaplayer_enable = "true" +bundle_assets_dst_path = "" +bundle_assets_dst_path_subdir = "" +bundle_assets_extract_enable = "false" +bundle_assets_extract_last_version = "0" +bundle_assets_extract_version_current = "0" +bundle_assets_src_path = "" +camera_allow = "false" +camera_device = "" +camera_driver = "null" +check_firmware_before_loading = "false" +cheevos_appearance_anchor = "0" +cheevos_appearance_padding_auto = "true" +cheevos_appearance_padding_h = "0.000000" +cheevos_appearance_padding_v = "0.000000" +cheevos_auto_screenshot = "false" +cheevos_badges_enable = "false" +cheevos_challenge_indicators = "true" +cheevos_custom_host = "" +cheevos_hardcore_mode_enable = "false" +cheevos_leaderboards_enable = "" +cheevos_password = "" +cheevos_richpresence_enable = "true" +cheevos_start_active = "false" +cheevos_test_unofficial = "false" +cheevos_token = "" +cheevos_unlock_sound_enable = "false" +cheevos_username = "" +cheevos_verbose_enable = "false" +cheevos_visibility_account = "true" +cheevos_visibility_lboard_cancel = "true" +cheevos_visibility_lboard_start = "true" +cheevos_visibility_lboard_submit = "true" +cheevos_visibility_lboard_trackers = "true" +cheevos_visibility_mastery = "true" +cheevos_visibility_progress_tracker = "true" +cheevos_visibility_summary = "1" +cheevos_visibility_unlock = "true" +cloud_sync_destructive = "false" +cloud_sync_driver = "" +cloud_sync_enable = "false" +config_save_on_exit = "false" +content_favorites_directory = "default" +content_favorites_path = "~/.config/retroarch/content_favorites.lpl" +content_favorites_size = "200" +content_history_dir = "" +content_history_directory = "default" +content_history_path = "~/.config/retroarch/content_history.lpl" +content_history_size = "200" +content_image_history_directory = "default" +content_image_history_path = "~/.config/retroarch/content_image_history.lpl" +content_music_history_directory = "default" +content_music_history_path = "~/.config/retroarch/content_music_history.lpl" +content_runtime_log = "true" +content_runtime_log_aggregate = "false" +content_show_add = "true" +content_show_add_entry = "2" +content_show_contentless_cores = "2" +content_show_explore = "true" +content_show_favorites = "true" +content_show_history = "true" +content_show_images = "false" +content_show_music = "false" +content_show_netplay = "true" +content_show_playlists = "true" +content_show_settings = "true" +content_show_settings_password = "" +content_show_video = "false" +content_video_directory = "default" +content_video_history_path = "~/.config/retroarch/content_video_history.lpl" +core_assets_directory = "~/roms/downloads" +core_info_cache_enable = "true" +core_info_savestate_bypass = "false" +core_option_category_enable = "true" +core_options_path = "" +core_set_supports_no_game_enable = "true" +core_updater_auto_backup = "false" +core_updater_auto_backup_history_size = "1" +core_updater_auto_extract_archive = "true" +core_updater_buildbot_assets_url = "http://buildbot.libretro.com/assets/" +core_updater_buildbot_cores_url = "" +core_updater_buildbot_url = "http://buildbot.libretro.com/nightly/linux/armhf/latest/" +core_updater_show_experimental_cores = "false" +cpu_main_gov = "performance" +cpu_max_freq = "-1" +cpu_menu_gov = "interactive" +cpu_min_freq = "1" +cpu_scaling_mode = "0" +crt_switch_center_adjust = "0" +crt_switch_hires_menu = "false" +crt_switch_porch_adjust = "0" +crt_switch_resolution = "0" +crt_switch_resolution_super = "2560" +crt_switch_resolution_use_custom_refresh_rate = "false" +crt_switch_timings = "" +crt_video_refresh_rate = "60.000000" +current_resolution_id = "0" +cursor_directory = "~/.config/retroarch/database/cursors" +custom_viewport_height = "1080" +custom_viewport_width = "1920" +custom_viewport_x = "0" +custom_viewport_y = "0" +desktop_menu_enable = "true" +discord_allow = "false" +discord_app_id = "475456035851599874" +driver_switch_enable = "true" +dynamic_wallpapers_directory = "default" +emuelec_exit_to_kodi = "false" +enable_device_vibration = "true" +facebook_stream_key = "" +fastforward_frameskip = "true" +fastforward_ratio = "0.000000" +filter_by_current_core = "false" +flicker_filter_enable = "false" +flicker_filter_index = "0" +fps_update_interval = "256" +frame_time_counter_reset_after_fastforwarding = "false" +frame_time_counter_reset_after_load_state = "false" +frame_time_counter_reset_after_save_state = "false" +framecount_show = "false" +frontend_log_level = "1" +game_specific_options = "true" +gamemode_enable = "false" +gamma_correction = "0" +global_core_options = "false" +history_list_enable = "true" +initial_disk_change_enable = "true" +input_ai_service = "nul" +input_ai_service_axis = "nul" +input_ai_service_btn = "nul" +input_ai_service_mbtn = "nul" +input_allow_turbo_dpad = "false" +input_analog_deadzone = "0.100000" +input_analog_sensitivity = "1.500000" +input_audio_mute = "nul" +input_audio_mute_axis = "nul" +input_audio_mute_btn = "nul" +input_audio_mute_mbtn = "nul" +input_auto_game_focus = "0" +input_auto_mouse_grab = "false" +input_autodetect_enable = "true" +input_axis_threshold = "0.500000" +input_bind_hold = "2" +input_bind_timeout = "5" +input_cheat_index_minus = "nul" +input_cheat_index_minus_axis = "nul" +input_cheat_index_minus_btn = "nul" +input_cheat_index_minus_mbtn = "nul" +input_cheat_index_plus = "nul" +input_cheat_index_plus_axis = "nul" +input_cheat_index_plus_btn = "nul" +input_cheat_index_plus_mbtn = "nul" +input_cheat_toggle = "nul" +input_cheat_toggle_axis = "nul" +input_cheat_toggle_btn = "nul" +input_cheat_toggle_mbtn = "nul" +input_close_content = "nul" +input_close_content_axis = "nul" +input_close_content_btn = "nul" +input_close_content_mbtn = "nul" +input_descriptor_hide_unbound = "false" +input_descriptor_label_show = "true" +input_desktop_menu_toggle = "f5" +input_desktop_menu_toggle_axis = "nul" +input_desktop_menu_toggle_btn = "nul" +input_desktop_menu_toggle_mbtn = "nul" +input_device_p1 = "0" +input_device_p10 = "0" +input_device_p11 = "0" +input_device_p12 = "0" +input_device_p13 = "0" +input_device_p14 = "0" +input_device_p15 = "0" +input_device_p16 = "0" +input_device_p2 = "0" +input_device_p3 = "0" +input_device_p4 = "0" +input_device_p5 = "0" +input_device_p6 = "0" +input_device_p7 = "0" +input_device_p8 = "0" +input_device_p9 = "0" +input_disk_eject_toggle = "nul" +input_disk_eject_toggle_axis = "nul" +input_disk_eject_toggle_btn = "nul" +input_disk_eject_toggle_mbtn = "nul" +input_disk_next = "nul" +input_disk_next_axis = "nul" +input_disk_next_btn = "nul" +input_disk_next_mbtn = "nul" +input_disk_prev = "nul" +input_disk_prev_axis = "nul" +input_disk_prev_btn = "nul" +input_disk_prev_mbtn = "nul" +input_driver = "udev" +input_duty_cycle = "3" +input_enable_hotkey = "nul" +input_enable_hotkey_axis = "nul" +input_enable_hotkey_btn = "nul" +input_enable_hotkey_mbtn = "nul" +input_exit_emulator = "nul" +input_exit_emulator_axis = "nul" +input_exit_emulator_btn = "nul" +input_exit_emulator_mbtn = "nul" +input_fps_toggle = "nul" +input_fps_toggle_axis = "nul" +input_fps_toggle_btn = "nul" +input_fps_toggle_mbtn = "nul" +input_frame_advance = "nul" +input_frame_advance_axis = "nul" +input_frame_advance_btn = "nul" +input_frame_advance_mbtn = "nul" +input_game_focus_toggle = "nul" +input_game_focus_toggle_axis = "nul" +input_game_focus_toggle_btn = "nul" +input_game_focus_toggle_mbtn = "nul" +input_grab_mouse_toggle = "nul" +input_grab_mouse_toggle_axis = "nul" +input_grab_mouse_toggle_btn = "nul" +input_grab_mouse_toggle_mbtn = "nul" +input_halt_replay = "nul" +input_halt_replay_axis = "nul" +input_halt_replay_btn = "nul" +input_halt_replay_mbtn = "nul" +input_hold_fast_forward = "nul" +input_hold_fast_forward_axis = "nul" +input_hold_fast_forward_btn = "nul" +input_hold_fast_forward_mbtn = "nul" +input_hold_slowmotion = "nul" +input_hold_slowmotion_axis = "nul" +input_hold_slowmotion_btn = "nul" +input_hold_slowmotion_mbtn = "nul" +input_hotkey_block_delay = "5" +input_hotkey_device_merge = "false" +input_joypad_driver = "udev" +input_keyboard_layout = "" +input_libretro_device_p1 = "1" +input_libretro_device_p10 = "1" +input_libretro_device_p11 = "1" +input_libretro_device_p12 = "1" +input_libretro_device_p13 = "1" +input_libretro_device_p14 = "1" +input_libretro_device_p15 = "1" +input_libretro_device_p16 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_libretro_device_p6 = "1" +input_libretro_device_p7 = "1" +input_libretro_device_p8 = "1" +input_libretro_device_p9 = "1" +input_load_state = "nul" +input_load_state_axis = "nul" +input_load_state_btn = "nul" +input_load_state_mbtn = "nul" +input_max_users = "5" +input_menu_toggle = "nul" +input_menu_toggle_axis = "nul" +input_menu_toggle_btn = "nul" +input_menu_toggle_gamepad_combo = "nul" +input_menu_toggle_mbtn = "nul" +input_movie_record_toggle = "o" +input_movie_record_toggle_axis = "nul" +input_movie_record_toggle_btn = "nul" +input_movie_record_toggle_mbtn = "nul" +input_netplay_fade_chat_toggle = "nul" +input_netplay_fade_chat_toggle_axis = "nul" +input_netplay_fade_chat_toggle_btn = "nul" +input_netplay_fade_chat_toggle_mbtn = "nul" +input_netplay_game_watch = "nul" +input_netplay_game_watch_axis = "nul" +input_netplay_game_watch_btn = "nul" +input_netplay_game_watch_mbtn = "nul" +input_netplay_host_toggle = "nul" +input_netplay_host_toggle_axis = "nul" +input_netplay_host_toggle_btn = "nul" +input_netplay_host_toggle_mbtn = "nul" +input_netplay_ping_toggle = "nul" +input_netplay_ping_toggle_axis = "nul" +input_netplay_ping_toggle_btn = "nul" +input_netplay_ping_toggle_mbtn = "nul" +input_netplay_player_chat = "nul" +input_netplay_player_chat_axis = "nul" +input_netplay_player_chat_btn = "nul" +input_netplay_player_chat_mbtn = "nul" +input_nowinkey_enable = "false" +input_osk_overlay = "" +input_osk_overlay_auto_scale = "false" +input_osk_overlay_opacity = "0.700000" +input_osk_toggle = "nul" +input_osk_toggle_axis = "nul" +input_osk_toggle_btn = "nul" +input_osk_toggle_mbtn = "nul" +input_overlay = "" +input_overlay_aspect_adjust_landscape = "0.000000" +input_overlay_aspect_adjust_portrait = "0.000000" +input_overlay_auto_rotate = "false" +input_overlay_auto_scale = "false" +input_overlay_enable_autopreferred = "true" +input_overlay_enable = "false" +input_overlay_hide_in_menu = "true" +input_overlay_hide_when_gamepad_connected = "false" +input_overlay_next_axis = "nul" +input_overlay_next_btn = "nul" +input_overlay_next_mbtn = "nul" +input_overlay_next = "nul" +input_overlay_opacity = "0.700000" +input_overlay_scale_landscape = "1.000000" +input_overlay_scale_portrait = "1.000000" +input_overlay_show_inputs = "2" +input_overlay_show_inputs_port = "0" +input_overlay_show_mouse_cursor = "true" +input_overlay_x_offset_landscape = "0.000000" +input_overlay_x_offset_portrait = "0.000000" +input_overlay_x_separation_landscape = "0.000000" +input_overlay_x_separation_portrait = "0.000000" +input_overlay_y_offset_landscape = "0.000000" +input_overlay_y_offset_portrait = "0.000000" +input_overlay_y_separation_landscape = "0.000000" +input_overlay_y_separation_portrait = "0.000000" +input_pause_toggle = "nul" +input_pause_toggle_axis = "nul" +input_pause_toggle_btn = "nul" +input_pause_toggle_mbtn = "nul" +input_play_replay = "nul" +input_play_replay_axis = "nul" +input_play_replay_btn = "nul" +input_play_replay_mbtn = "nul" +input_poll_type_behavior = "2" +input_preempt_toggle = "nul" +input_preempt_toggle_axis = "nul" +input_preempt_toggle_btn = "nul" +input_preempt_toggle_mbtn = "nul" +input_quit_gamepad_combo = "0" +input_record_replay = "nul" +input_record_replay_axis = "nul" +input_record_replay_btn = "nul" +input_record_replay_mbtn = "nul" +input_recording_toggle = "nul" +input_recording_toggle_axis = "nul" +input_recording_toggle_btn = "nul" +input_recording_toggle_mbtn = "nul" +input_remap_binds_enable = "true" +input_remapping_directory = "~/remappings" +input_replay_slot_decrease = "nul" +input_replay_slot_decrease_axis = "nul" +input_replay_slot_decrease_btn = "nul" +input_replay_slot_decrease_mbtn = "nul" +input_replay_slot_increase = "nul" +input_replay_slot_increase_axis = "nul" +input_replay_slot_increase_btn = "nul" +input_replay_slot_increase_mbtn = "nul" +input_reset = "nul" +input_reset_axis = "nul" +input_reset_btn = "nul" +input_reset_mbtn = "nul" +input_rewind = "nul" +input_rewind_axis = "nul" +input_rewind_btn = "nul" +input_rewind_mbtn = "nul" +input_rumble_gain = "25" +input_runahead_toggle = "nul" +input_runahead_toggle_axis = "nul" +input_runahead_toggle_btn = "nul" +input_runahead_toggle_mbtn = "nul" +input_save_state = "nul" +input_save_state_axis = "nul" +input_save_state_btn = "nul" +input_save_state_mbtn = "nul" +input_screenshot = "nul" +input_screenshot_axis = "nul" +input_screenshot_btn = "nul" +input_screenshot_mbtn = "nul" +input_send_debug_info = "f10" +input_send_debug_info_axis = "nul" +input_send_debug_info_btn = "nul" +input_send_debug_info_mbtn = "nul" +input_sensors_enable = "true" +input_shader_next = "nul" +input_shader_next_axis = "nul" +input_shader_next_btn = "nul" +input_shader_next_mbtn = "nul" +input_shader_prev = "nul" +input_shader_prev_axis = "nul" +input_shader_prev_btn = "nul" +input_shader_prev_mbtn = "nul" +input_shader_toggle = "nul" +input_shader_toggle_axis = "nul" +input_shader_toggle_btn = "nul" +input_shader_toggle_mbtn = "nul" +input_state_slot_decrease = "nul" +input_state_slot_decrease_axis = "nul" +input_state_slot_decrease_btn = "nul" +input_state_slot_decrease_mbtn = "nul" +input_state_slot_increase = "nul" +input_state_slot_increase_axis = "nul" +input_state_slot_increase_btn = "nul" +input_state_slot_increase_mbtn = "nul" +input_streaming_toggle = "nul" +input_streaming_toggle_axis = "nul" +input_streaming_toggle_btn = "nul" +input_streaming_toggle_mbtn = "nul" +input_toggle_fast_forward = "nul" +input_toggle_fast_forward_axis = "nul" +input_toggle_fast_forward_btn = "nul" +input_toggle_fast_forward_mbtn = "nul" +input_toggle_fullscreen = "nul" +input_toggle_fullscreen_axis = "nul" +input_toggle_fullscreen_btn = "nul" +input_toggle_fullscreen_mbtn = "nul" +input_toggle_slowmotion = "nul" +input_toggle_slowmotion_axis = "nul" +input_toggle_slowmotion_btn = "nul" +input_toggle_slowmotion_mbtn = "nul" +input_toggle_statistics = "nul" +input_toggle_statistics_axis = "nul" +input_toggle_statistics_btn = "nul" +input_toggle_statistics_mbtn = "nul" +input_toggle_vrr_runloop = "nul" +input_toggle_vrr_runloop_axis = "nul" +input_toggle_vrr_runloop_btn = "nul" +input_toggle_vrr_runloop_mbtn = "nul" +input_touch_scale = "1" +input_touch_vmouse_gesture = "true" +input_touch_vmouse_mouse = "true" +input_touch_vmouse_pointer = "true" +input_touch_vmouse_touchpad = "true" +input_touch_vmouse_trackball = "false" +input_turbo_default_button = "0" +input_turbo_mode = "0" +input_turbo_period = "6" +input_volume_down = "nul" +input_volume_down_axis = "nul" +input_volume_down_btn = "nul" +input_volume_down_mbtn = "nul" +input_volume_up = "nul" +input_volume_up_axis = "nul" +input_volume_up_btn = "nul" +input_volume_up_mbtn = "nul" +keyboard_gamepad_enable = "true" +keyboard_gamepad_mapping_type = "1" +kiosk_mode_enable = "false" +kiosk_mode_password = "" +led_driver = "null" +libretro_log_level = "1" +load_dummy_on_core_shutdown = "true" +location_allow = "false" +location_driver = "null" +log_dir = "~/.config/retroarch/logs" +log_to_file = "true" +log_to_file_timestamp = "false" +log_verbosity = "true" +materialui_auto_rotate_nav_bar = "true" +materialui_dual_thumbnail_list_view_enable = "true" +materialui_icons_enable = "true" +materialui_landscape_layout_optimization = "1" +materialui_menu_color_theme = "9" +materialui_menu_transition_animation = "0" +materialui_playlist_icons_enable = "true" +materialui_show_nav_bar = "true" +materialui_switch_icons = "true" +materialui_thumbnail_background_enable = "true" +materialui_thumbnail_view_landscape = "2" +materialui_thumbnail_view_portrait = "1" +memory_show = "false" +memory_update_interval = "256" +menu_battery_level_enable = "true" +menu_core_enable = "true" +menu_disable_info_button = "false" +menu_disable_search_button = "false" +menu_driver = "ozone" +menu_dynamic_wallpaper_enable = "false" +menu_enable_widgets = "true" +menu_font_color_blue = "255" +menu_font_color_green = "255" +menu_font_color_red = "255" +menu_footer_opacity = "1.000000" +menu_framebuffer_opacity = "0.899999" +menu_header_opacity = "1.000000" +menu_horizontal_animation = "true" +menu_insert_disk_resume = "true" +menu_left_thumbnails = "0" +menu_linear_filter = "false" +menu_mouse_enable = "false" +menu_navigation_browser_filter_supported_extensions_enable = "true" +menu_navigation_wraparound_enable = "true" +menu_pause_libretro = "true" +menu_pointer_enable = "true" +menu_remember_selection = "1" +menu_rgui_full_width_layout = "true" +menu_rgui_shadows = "false" +menu_rgui_transparency = "true" +menu_savestate_resume = "true" +menu_scale_factor = "0.300000" +menu_screensaver_animation = "0" +menu_screensaver_animation_speed = "1.000000" +menu_screensaver_timeout = "0" +menu_scroll_delay = "256" +menu_scroll_fast = "false" +menu_shader_pipeline = "2" +menu_show_advanced_settings = "true" +menu_show_configurations = "true" +menu_show_core_updater = "false" +menu_show_dump_disc = "true" +menu_show_help = "true" +menu_show_information = "true" +menu_show_latency = "true" +menu_show_legacy_thumbnail_updater = "false" +menu_show_load_content = "true" +menu_show_load_content_animation = "false" +menu_show_load_core = "true" +menu_show_load_disc = "true" +menu_show_online_updater = "true" +menu_show_overlays = "true" +menu_show_quit_retroarch = "true" +menu_show_reboot = "false" +menu_show_restart_retroarch = "true" +menu_show_rewind = "true" +menu_show_shutdown = "false" +menu_show_sublabels = "true" +menu_show_video_layout = "true" +menu_swap_ok_cancel_buttons = "false" +menu_swap_scroll_buttons = "false" +menu_throttle_framerate = "true" +menu_thumbnail_upscale_threshold = "0" +menu_thumbnails = "3" +menu_ticker_smooth = "true" +menu_ticker_speed = "2.000000" +menu_ticker_type = "1" +menu_timedate_date_separator = "0" +menu_timedate_enable = "true" +menu_timedate_style = "11" +menu_unified_controls = "false" +menu_use_preferred_system_color_theme = "false" +menu_wallpaper = "" +menu_wallpaper_opacity = "1.000000" +menu_widget_scale_auto = "false" +menu_widget_scale_factor = "0.350000" +menu_widget_scale_factor_windowed = "1.000000" +menu_xmb_animation_horizontal_highlight = "0" +menu_xmb_animation_move_up_down = "0" +menu_xmb_animation_opening_main_menu = "0" +menu_xmb_show_title_header = "true" +menu_xmb_thumbnail_scale_factor = "100" +menu_xmb_title_margin = "5" +menu_xmb_title_margin_horizontal_offset = "0" +menu_xmb_vertical_fade_factor = "100" +microphone_block_frames = "0" +microphone_device = "" +microphone_driver = "alsathread" +microphone_enable = "true" +microphone_latency = "64" +microphone_rate = "48000" +microphone_resampler = "sinc" +microphone_resampler_quality = "3" +midi_driver = "alsa" +midi_input = "OFF" +midi_output = "OFF" +midi_volume = "100" +network_cmd_enable = "false" +network_cmd_port = "55355" +network_on_demand_thumbnails = "false" +network_remote_base_port = "55400" +network_remote_enable = "false" +network_remote_enable_user_p1 = "false" +network_remote_enable_user_p10 = "false" +network_remote_enable_user_p11 = "false" +network_remote_enable_user_p12 = "false" +network_remote_enable_user_p13 = "false" +network_remote_enable_user_p14 = "false" +network_remote_enable_user_p15 = "false" +network_remote_enable_user_p16 = "false" +network_remote_enable_user_p2 = "false" +network_remote_enable_user_p3 = "false" +network_remote_enable_user_p4 = "false" +network_remote_enable_user_p5 = "false" +network_remote_enable_user_p6 = "false" +network_remote_enable_user_p7 = "false" +network_remote_enable_user_p8 = "false" +network_remote_enable_user_p9 = "false" +notification_show_autoconfig = "false" +notification_show_cheats_applied = "true" +notification_show_config_override_load = "false" +notification_show_disk_control = "true" +notification_show_fast_forward = "true" +notification_show_netplay_extra = "false" +notification_show_patch_applied = "true" +notification_show_refresh_rate = "true" +notification_show_remap_load = "false" +notification_show_save_state = "true" +notification_show_screenshot = "false" +notification_show_screenshot_duration = "2" +notification_show_screenshot_flash = "1" +notification_show_set_initial_disk = "true" +notification_show_when_menu_is_alive = "false" +osk_overlay_directory = "/tmp/overlays/keyboards" +ozone_collapse_sidebar = "false" +ozone_menu_color_theme = "1" +ozone_scroll_content_metadata = "false" +ozone_sort_after_truncate_playlist_name = "true" +ozone_thumbnail_scale_factor = "1.000000" +ozone_truncate_playlist_name = "true" +pause_nonactive = "true" +pause_on_disconnect = "false" +perfcnt_enable = "false" +playlist_compression = "false" +playlist_cores = "" +playlist_directory = "~/playlists" +playlist_entry_remove = "false" +playlist_entry_remove_enable = "1" +playlist_entry_rename = "false" +playlist_fuzzy_archive_match = "false" +playlist_names = "" +playlist_portable_paths = "false" +playlist_show_entry_idx = "true" +playlist_show_history_icons = "1" +playlist_show_inline_core_name = "0" +playlist_show_sublabels = "true" +playlist_sort_alphabetical = "true" +playlist_sublabel_last_played_style = "0" +playlist_sublabel_runtime_type = "0" +playlist_use_filename = "false" +playlist_use_old_format = "false" +preemptive_frames_enable = "false" +preemptive_frames_hide_warnings = "false" +quick_menu_show_add_to_favorites = "true" +quick_menu_show_add_to_playlist = "false" +quick_menu_show_cheats = "true" +quick_menu_show_close_content = "true" +quick_menu_show_controls = "true" +quick_menu_show_core_options_flush = "false" +quick_menu_show_download_thumbnails = "true" +quick_menu_show_information = "true" +quick_menu_show_options = "true" +quick_menu_show_recording = "true" +quick_menu_show_replay = "false" +quick_menu_show_reset_core_association = "true" +quick_menu_show_restart_content = "true" +quick_menu_show_resume_content = "true" +quick_menu_show_save_content_dir_overrides = "true" +quick_menu_show_save_core_overrides = "false" +quick_menu_show_save_game_overrides = "false" +quick_menu_show_save_load_state = "true" +quick_menu_show_savestate_submenu = "true" +quick_menu_show_set_core_association = "true" +quick_menu_show_shaders = "true" +quick_menu_show_start_recording = "true" +quick_menu_show_start_streaming = "true" +quick_menu_show_streaming = "true" +quick_menu_show_take_screenshot = "true" +quick_menu_show_undo_save_load_state = "false" +quit_on_close_content = "0" +quit_press_twice = "true" +record_driver = "null" +recording_config_directory = "" +recording_output_directory = "~/roms/screenshots" +remap_save_on_exit = "true" +replay_auto_index = "true" +replay_checkpoint_interval = "0" +replay_max_keep = "0" +replay_slot = "0" +resampler_directory = "" +rewind_buffer_size = "20971520" +rewind_buffer_size_step = "10" +rewind_granularity = "1" +rgui_aspect_ratio = "0" +rgui_aspect_ratio_lock = "0" +rgui_background_filler_thickness_enable = "true" +rgui_border_filler_enable = "true" +rgui_border_filler_thickness_enable = "true" +rgui_browser_directory = "~/roms" +rgui_config_directory = "~/.config/retroarch/config" +rgui_extended_ascii = "false" +rgui_inline_thumbnails = "false" +rgui_internal_upscale_level = "0" +rgui_menu_color_theme = "4" +rgui_menu_theme_preset = "" +rgui_particle_effect = "0" +rgui_particle_effect_screensaver = "true" +rgui_particle_effect_speed = "1.000000" +rgui_show_start_screen = "false" +rgui_swap_thumbnails = "false" +rgui_switch_icons = "true" +rgui_thumbnail_delay = "0" +rgui_thumbnail_downscaler = "0" +run_ahead_hide_warnings = "false" +run_ahead_secondary_instance = "true" +runtime_log_directory = "default" +save_file_compression = "false" +savefile_directory = "~/.config/retroarch/saves" +savefiles_in_content_dir = "true" +savestate_file_compression = "true" +savestate_thumbnail_enable = "true" +savestates_in_content_dir = "false" +scan_serial_and_crc = "false" +scan_without_core_match = "false" +screen_brightness = "100" +screen_orientation = "0" +screenshot_directory = "~/roms/screenshots" +screenshots_in_content_dir = "false" +settings_show_accessibility = "true" +settings_show_achievements = "true" +settings_show_ai_service = "true" +settings_show_audio = "true" +settings_show_configuration = "true" +settings_show_core = "true" +settings_show_directory = "true" +settings_show_drivers = "true" +settings_show_file_browser = "true" +settings_show_frame_throttle = "true" +settings_show_input = "true" +settings_show_latency = "true" +settings_show_logging = "true" +settings_show_network = "true" +settings_show_onscreen_display = "true" +settings_show_playlists = "true" +settings_show_power_management = "true" +settings_show_recording = "true" +settings_show_saving = "true" +settings_show_user = "true" +settings_show_user_interface = "true" +settings_show_video = "true" +show_hidden_files = "false" +slowmotion_ratio = "3.000000" +soft_filter_enable = "false" +soft_filter_index = "0" +sort_savefiles_by_content_enable = "false" +sort_savefiles_enable = "false" +sort_savestates_by_content_enable = "false" +sort_savestates_enable = "false" +sort_screenshots_by_content_enable = "false" +statistics_show = "false" +stdin_cmd_enable = "false" +streaming_mode = "0" +suspend_screensaver_enable = "true" +sustained_performance_mode = "false" +system_directory = "~/roms/bios" +systemfiles_in_content_dir = "false" +test_input_file_joypad = "" +threaded_data_runloop_enable = "true" +thumbnails_directory = "~/thumbnails" +twitch_stream_key = "" +ui_companion_enable = "false" +ui_companion_start_on_boot = "true" +ui_companion_toggle = "false" +ui_menubar_enable = "true" +use_last_start_directory = "false" +user_language = "0" +vibrate_on_keypress = "true" +video_adaptive_vsync = "false" +video_allow_rotate = "true" +video_aspect_ratio = "-1.000000" +video_aspect_ratio_auto = "true" +video_autoswitch_pal_threshold = "54.500000" +video_autoswitch_refresh_rate = "0" +video_bfi_dark_frames = "1" +video_black_frame_insertion = "0" +video_context_driver = "" +video_crop_overscan = "true" +video_disable_composition = "false" +video_driver = "glcore" +video_font_enable = "true" +video_font_path = "/usr/share/retroarch-assets/xmb/monochrome/font.ttf" +video_font_size = "32.000000" +video_force_aspect = "true" +video_force_srgb_disable = "false" +video_frame_delay = "0" +video_frame_delay_auto = "false" +video_frame_rest = "false" +video_fullscreen = "true" +video_fullscreen_x = "1920" +video_fullscreen_y = "1080" +video_gpu_record = "false" +video_gpu_screenshot = "false" +video_hard_sync = "false" +video_hard_sync_frames = "0" +video_hdr_display_contrast = "5.000000" +video_hdr_enable = "false" +video_hdr_expand_gamut = "true" +video_hdr_max_nits = "1000.000000" +video_hdr_paper_white_nits = "200.000000" +video_layout_directory = "~/.config/retroarch/layouts" +video_layout_enable = "true" +video_layout_path = "" +video_layout_selected_view = "0" +video_max_frame_latency = "1" +video_max_swapchain_images = "3" +video_message_color = "ffff00" +video_message_pos_x = "0.049999" +video_message_pos_y = "0.049999" +video_monitor_index = "0" +video_msg_bgcolor_blue = "0" +video_msg_bgcolor_enable = "false" +video_msg_bgcolor_green = "0" +video_msg_bgcolor_opacity = "1.000000" +video_msg_bgcolor_red = "0" +video_notch_write_over_enable = "false" +video_oga_vertical_enable = "false" +video_post_filter_record = "false" +video_record_config = "" +video_record_quality = "4" +video_record_scale_factor = "1" +video_record_threads = "2" +video_refresh_rate = "60.000000" +video_scale = "3" +video_scan_subframes = "false" +video_shared_context = "false" +video_stream_config = "" +video_stream_port = "56400" +video_stream_quality = "10" +video_stream_scale_factor = "1" +video_stream_url = "" +video_swap_interval = "1" +video_threaded = "false" +video_vsync = "true" +video_waitable_swapchains = "true" +video_window_auto_height_max = "1080" +video_window_auto_width_max = "1920" +video_window_custom_size_enable = "false" +video_window_opacity = "100" +video_window_save_positions = "false" +video_window_show_decorations = "true" +video_windowed_fullscreen = "false" +video_windowed_position_height = "720" +video_windowed_position_width = "1280" +video_windowed_position_x = "0" +video_windowed_position_y = "0" +vrr_runloop_enable = "false" +vulkan_gpu_index = "0" +webdav_password = "" +webdav_url = "" +webdav_username = "" +wifi_driver = "null" +wifi_enabled = "true" +xmb_alpha_factor = "75" +xmb_font = "/usr/share/retroarch-assets/xmb/monochrome/font.ttf" +xmb_layout = "2" +xmb_menu_color_theme = "4" +xmb_shadows_enable = "true" +xmb_switch_icons = "true" +xmb_theme = "0" +xmb_vertical_thumbnails = "false" +youtube_stream_key = "" +assets_directory = "/tmp/assets" +cache_directory = "/tmp/cache" +cheat_database_path = "/tmp/database/cht" +content_database_path = "/tmp/database/rdb" +joypad_autoconfig_dir = "/tmp/joypads" +libretro_directory = "/tmp/cores" +libretro_info_path = "/tmp/cores" +overlay_directory = "/tmp/overlays" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8650/retroarch32bit-append.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8650/retroarch32bit-append.cfg new file mode 100755 index 0000000000..343124c254 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8650/retroarch32bit-append.cfg @@ -0,0 +1,3 @@ +audio_filter_dir = "/usr/share/retroarch/filters/32bit/audio" +video_filter_dir = "/usr/share/retroarch/filters/32bit/video" +libretro_directory = /usr/lib32/libretro diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8650/retroarch64bit-append.cfg b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8650/retroarch64bit-append.cfg new file mode 100755 index 0000000000..b6cbf68312 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/sources/SM8650/retroarch64bit-append.cfg @@ -0,0 +1,2 @@ +audio_filter_dir = "/usr/share/retroarch/filters/64bit/audio" +video_filter_dir = "/usr/share/retroarch/filters/64bit/video" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/system.d/tmp-assets.mount b/projects/ArchR/packages/emulators/libretro/retroarch/system.d/tmp-assets.mount new file mode 100644 index 0000000000..25628de694 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/system.d/tmp-assets.mount @@ -0,0 +1,14 @@ +[Unit] +Description=Assets directory +After=systemd-tmpfiles-setup.service +RequiresMountsFor=/storage +DefaultDependencies=no + +[Mount] +What=none +Where=/tmp/assets +Type=overlay +Options=lowerdir=/usr/share/retroarch-assets,upperdir=/storage/assets,workdir=/storage/.tmp/assets-workdir + +[Install] +WantedBy=archr.target diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/system.d/tmp-cores.mount b/projects/ArchR/packages/emulators/libretro/retroarch/system.d/tmp-cores.mount new file mode 100644 index 0000000000..f819867a3a --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/system.d/tmp-cores.mount @@ -0,0 +1,14 @@ +[Unit] +Description=Cores directory +After=systemd-tmpfiles-setup.service +RequiresMountsFor=/storage +DefaultDependencies=no + +[Mount] +What=none +Where=/tmp/cores +Type=overlay +Options=lowerdir=/usr/lib/libretro,upperdir=/storage/cores,workdir=/storage/.tmp/cores-workdir + +[Install] +WantedBy=archr.target diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/system.d/tmp-database.mount b/projects/ArchR/packages/emulators/libretro/retroarch/system.d/tmp-database.mount new file mode 100644 index 0000000000..3ca7aa6242 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/system.d/tmp-database.mount @@ -0,0 +1,14 @@ +[Unit] +Description=Database directory +After=systemd-tmpfiles-setup.service +RequiresMountsFor=/storage +DefaultDependencies=no + +[Mount] +What=none +Where=/tmp/database +Type=overlay +Options=lowerdir=/usr/share/libretro-database,upperdir=/storage/database,workdir=/storage/.tmp/database-workdir + +[Install] +WantedBy=archr.target diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/system.d/tmp-overlays.mount b/projects/ArchR/packages/emulators/libretro/retroarch/system.d/tmp-overlays.mount new file mode 100644 index 0000000000..11ed4f6e3b --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/system.d/tmp-overlays.mount @@ -0,0 +1,14 @@ +[Unit] +Description=Overlays directory +After=systemd-tmpfiles-setup.service +RequiresMountsFor=/storage +DefaultDependencies=no + +[Mount] +What=none +Where=/tmp/overlays +Type=overlay +Options=lowerdir=/usr/share/retroarch-overlays,upperdir=/storage/overlays,workdir=/storage/.tmp/overlays-workdir + +[Install] +WantedBy=archr.target diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/system.d/tmp-shaders.mount b/projects/ArchR/packages/emulators/libretro/retroarch/system.d/tmp-shaders.mount new file mode 100644 index 0000000000..9a32142a60 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/system.d/tmp-shaders.mount @@ -0,0 +1,14 @@ +[Unit] +Description=Shaders directory RetroArch +After=systemd-tmpfiles-setup.service +RequiresMountsFor=/storage +DefaultDependencies=no + +[Mount] +What=none +Where=/tmp/shaders +Type=overlay +Options=lowerdir=/usr/share/common-shaders:/usr/share/glsl-shaders:/usr/share/slang-shaders,upperdir=/storage/shaders,workdir=/storage/.tmp/shaders-workdir + +[Install] +WantedBy=archr.target diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/tmpfiles.d/retroarch-userdirs.conf b/projects/ArchR/packages/emulators/libretro/retroarch/tmpfiles.d/retroarch-userdirs.conf new file mode 100644 index 0000000000..1a40a9ea2f --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/tmpfiles.d/retroarch-userdirs.conf @@ -0,0 +1,32 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2014 Stephan Raue (stephan@openelec.tv) +# +# OpenELEC is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# OpenELEC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC. If not, see . +################################################################################ + +d /storage/assets 0777 root root - - +d /storage/cores 0777 root root - - +d /storage/database 0777 root root - - +d /storage/joypads 0777 root root - - +d /storage/overlays 0777 root root - - +d /storage/remappings 0777 root root - - +d /storage/shaders 0777 root root - - + +d /storage/.tmp/cores-workdir 0777 root root - - +d /storage/.tmp/joypads-workdir 0777 root root - - +d /storage/.tmp/database-workdir 0777 root root - - +d /storage/.tmp/assets-workdir 0777 root root - - +d /storage/.tmp/overlays-workdir 0777 root root - - +d /storage/.tmp/shaders-workdir 0777 root root - - diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/udev.d/99-8bitdo-bluetooth-controllers.rules b/projects/ArchR/packages/emulators/libretro/retroarch/udev.d/99-8bitdo-bluetooth-controllers.rules new file mode 100644 index 0000000000..b6abb22f60 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/udev.d/99-8bitdo-bluetooth-controllers.rules @@ -0,0 +1,49 @@ +# Add the ID_INPUT_JOYSTICK attribute to the device so SDL picks up on it + +# 8Bitdo FC30 1P GamePad Bluetooth mode(START) mode(START+R) +SUBSYSTEM=="input", ATTRS{name}=="8Bitdo FC30 GamePad", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1" + +# 8Bitdo FC30 2P GamePad Bluetooth mode(START) +SUBSYSTEM=="input", ATTRS{name}=="8Bitdo FC30 II", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1" + +# 8Bitdo FC30 2P GamePad Bluetooth mode(START+R) +SUBSYSTEM=="input", ATTRS{name}=="8Bitdo FC30 II Joystick", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1" + +# 8Bitdo SFC30 GamePad Bluetooth mode(START) +SUBSYSTEM=="input", ATTRS{name}=="8Bitdo SFC30 GamePad", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1" + +# 8Bitdo SFC30 GamePad Bluetooth mode(START+R) +SUBSYSTEM=="input", ATTRS{name}=="8Bitdo SFC30 GamePad Joystick", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1" + +# 8Bitdo NES30 GamePad Bluetooth mode(START) +SUBSYSTEM=="input", ATTRS{name}=="8Bitdo NES30 GamePad", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1" + +# 8Bitdo NES30 GamePad Bluetooth mode(START+R) +SUBSYSTEM=="input", ATTRS{name}=="8Bitdo NES30 GamePad Joystick", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1" + +# 8Bitdo SNES30 GamePad Bluetooth mode(START) +SUBSYSTEM=="input", ATTRS{name}=="8Bitdo SNES30 GamePad", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1" + +# 8Bitdo SNES30 GamePad Bluetooth mode(START+R) +SUBSYSTEM=="input", ATTRS{name}=="8Bitdo SNES30 GamePad Joystick", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1" + +# 8Bitdo FC30 Pro GamePad Bluetooth mode(POWER) mode(POWER+R1) +SUBSYSTEM=="input", ATTRS{name}=="8Bitdo FC30 Pro", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1" + +# 8Bitdo NES30 Pro GamePad Bluetooth mode(POWER) +SUBSYSTEM=="input", ATTRS{name}=="8Bitdo NES30 Pro", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1" + +# 8Bitdo NES30 Pro GamePad Bluetooth mode(POWER+R1) +SUBSYSTEM=="input", ATTRS{name}=="8Bitdo NES30 Pro Joystick", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1" + +# 8Bitdo FC30 Arcade Joystick Bluetooth mode(HOME) +SUBSYSTEM=="input", ATTRS{name}=="8Bitdo Joy", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1" + +# 8Bitdo Zero GamePad Bluetooth mode(START) mode(START+R) +SUBSYSTEM=="input", ATTRS{name}=="8Bitdo Zero GamePad", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1" + +# 8Bitdo 2.4ghz ultimate +ACTION=="add", ATTRS{idVendor}=="2dc8", ATTRS{idProduct}=="3106", RUN+="/usr/sbin/modprobe xpad", RUN+="/bin/sh -c 'echo 2dc8 3106 > /sys/bus/usb/drivers/xpad/new_id'" + +# 8Bitdo M30 +ACTION=="add", ATTRS{idVendor}=="2dc8", ATTRS{idProduct}=="6002", RUN+="/usr/sbin/modprobe xpad", RUN+="/bin/sh -c 'echo 2dc8 6002 > /sys/bus/usb/drivers/xpad/new_id'" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/udev.d/99-ION-iCade-bluetooth.rules b/projects/ArchR/packages/emulators/libretro/retroarch/udev.d/99-ION-iCade-bluetooth.rules new file mode 100644 index 0000000000..a25b646dc1 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/udev.d/99-ION-iCade-bluetooth.rules @@ -0,0 +1 @@ +SUBSYSTEM=="input", ATTRS{name}=="ION iCade", KERNEL=="event*", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/udev.d/99-gen-game-s3-controller.rules b/projects/ArchR/packages/emulators/libretro/retroarch/udev.d/99-gen-game-s3-controller.rules new file mode 100644 index 0000000000..66b6a0ac6c --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/udev.d/99-gen-game-s3-controller.rules @@ -0,0 +1 @@ +SUBSYSTEM=="input", ATTRS{name}=="GEN GAME S3", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1", ENV{ID_INPUT_MOUSE}="", ENV{ID_INPUT_KEYBOARD}="" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/udev.d/99-nintendo-wii-remote.rules b/projects/ArchR/packages/emulators/libretro/retroarch/udev.d/99-nintendo-wii-remote.rules new file mode 100644 index 0000000000..f07b272009 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/udev.d/99-nintendo-wii-remote.rules @@ -0,0 +1,2 @@ +SUBSYSTEM=="input", ATTRS{name}=="Nintendo Wii Remote", MODE="666", ENV{ID_INPUT_JOYSTICK}="1" +SUBSYSTEM=="input", ATTRS{name}=="Nintendo Wii Remote Classic Controller", MODE="666", ENV{ID_INPUT_JOYSTICK}="1" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/udev.d/99-ninteno-wii-remote.rules b/projects/ArchR/packages/emulators/libretro/retroarch/udev.d/99-ninteno-wii-remote.rules new file mode 100644 index 0000000000..f07b272009 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/udev.d/99-ninteno-wii-remote.rules @@ -0,0 +1,2 @@ +SUBSYSTEM=="input", ATTRS{name}=="Nintendo Wii Remote", MODE="666", ENV{ID_INPUT_JOYSTICK}="1" +SUBSYSTEM=="input", ATTRS{name}=="Nintendo Wii Remote Classic Controller", MODE="666", ENV{ID_INPUT_JOYSTICK}="1" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/udev.d/99-nv-shield-controller.rules b/projects/ArchR/packages/emulators/libretro/retroarch/udev.d/99-nv-shield-controller.rules new file mode 100644 index 0000000000..f5b679f7b0 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/udev.d/99-nv-shield-controller.rules @@ -0,0 +1 @@ +SUBSYSTEM=="input", ATTRS{idVendor}=="0955", ATTRS{idProduct}=="7210", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1", ENV{ID_INPUT_MOUSE}="" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/udev.d/99-ouya-controller.rules b/projects/ArchR/packages/emulators/libretro/retroarch/udev.d/99-ouya-controller.rules new file mode 100644 index 0000000000..55a0949d9f --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/udev.d/99-ouya-controller.rules @@ -0,0 +1 @@ +SUBSYSTEM=="input", ATTRS{name}=="OUYA Game Controller", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1", ENV{ID_INPUT_MOUSE}="" diff --git a/projects/ArchR/packages/emulators/libretro/retroarch/udev.d/99-terios-t3.rules b/projects/ArchR/packages/emulators/libretro/retroarch/udev.d/99-terios-t3.rules new file mode 100644 index 0000000000..32d1692892 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retroarch/udev.d/99-terios-t3.rules @@ -0,0 +1,2 @@ +# Needed for device Terios T3 (1949:0402) +SUBSYSTEM=="input", ATTRS{name}=="Gamepad", KERNEL=="event*", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1" diff --git a/projects/ArchR/packages/emulators/libretro/retropie-shaders/package.mk b/projects/ArchR/packages/emulators/libretro/retropie-shaders/package.mk new file mode 100644 index 0000000000..eeba4b444f --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/retropie-shaders/package.mk @@ -0,0 +1,44 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="retropie-shaders" +PKG_VERSION="43eaf9b91857eb8515310c74ae750895d77b20f8" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/RetroPie/common-shaders" +PKG_URL="${PKG_SITE}.git" +PKG_GIT_CLONE_BRANCH="rpi" +PKG_DEPENDS_TARGET="toolchain glsl-shaders" +PKG_LONGDESC="Libretro common shaders from retropie" +PKG_TOOLCHAIN="manual" + +make_target() { + : +} + +makeinstall_target() { + if [ ! -d "${INSTALL}/usr/share/common-shaders" ] + then + mkdir -p ${INSTALL}/usr/share/common-shaders + fi + rsync -a ${PKG_BUILD}/* ${INSTALL}/usr/share/common-shaders/ + rm -f ${INSTALL}/usr/share/common-shaders/{Makefile,configure} +} diff --git a/projects/ArchR/packages/emulators/libretro/same_cdi-lr/package.mk b/projects/ArchR/packages/emulators/libretro/same_cdi-lr/package.mk new file mode 100644 index 0000000000..b54aa2e16a --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/same_cdi-lr/package.mk @@ -0,0 +1,50 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present AmberELEC (https://github.com/AmberELEC) + +PKG_NAME="same_cdi-lr" +PKG_VERSION="7ee1d8e9cb4307b7cd44ee1dd757e9b3f48f41d5" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/libretro/same_cdi" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain expat zlib flac sqlite" +PKG_LONGDESC="SAME_CDI is a Single Arcade/Machine Emulator for libretro" +PKG_TOOLCHAIN="make" + +PKG_MAKE_OPTS_TARGET="REGENIE=1 \ + VERBOSE=1 \ + NOWERROR=1 \ + OPENMP=1 \ + CROSS_BUILD=1 \ + TOOLS=0 \ + RETRO=1 \ + PTR64=0 \ + NOASM=0 \ + PYTHON_EXECUTABLE=python3 \ + CONFIG=libretro \ + LIBRETRO_OS=unix \ + LIBRETRO_CPU= \ + PLATFORM=arm64 \ + ARCH= \ + TARGET=mame \ + OSD=retro \ + USE_SYSTEM_LIB_EXPAT=1 \ + USE_SYSTEM_LIB_ZLIB=1 \ + USE_SYSTEM_LIB_FLAC=1 \ + USE_SYSTEM_LIB_SQLITE3=1" + +pre_configure_target() { + sed -i "s/-static-libstdc++//g" scripts/genie.lua +} + +make_target() { + unset ARCH + unset DISTRO + unset PROJECT + export ARCHOPTS="-D__aarch64__ -DASMJIT_BUILD_X86" + make -f Makefile.libretro ${PKG_MAKE_OPTS_TARGET} OVERRIDE_CC=${CC} OVERRIDE_CXX=${CXX} OVERRIDE_LD=${LD} AR=${AR} ${MAKEFLAGS} +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp same_cdi_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/same_cdi-lr/patches/001-gcc13-fix.patch b/projects/ArchR/packages/emulators/libretro/same_cdi-lr/patches/001-gcc13-fix.patch new file mode 100644 index 0000000000..d2a6c8c43f --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/same_cdi-lr/patches/001-gcc13-fix.patch @@ -0,0 +1,12 @@ +diff --git a/src/osd/modules/lib/osdlib.h b/src/osd/modules/lib/osdlib.h +index 4a06b705..506ba834 100644 +--- a/src/osd/modules/lib/osdlib.h ++++ b/src/osd/modules/lib/osdlib.h +@@ -18,6 +18,7 @@ + + #include + #include ++#include + #include + #include + #include diff --git a/projects/ArchR/packages/emulators/libretro/same_cdi-lr/patches/002-fix-building-with-gcc15.patch b/projects/ArchR/packages/emulators/libretro/same_cdi-lr/patches/002-fix-building-with-gcc15.patch new file mode 100644 index 0000000000..3894a8a80e --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/same_cdi-lr/patches/002-fix-building-with-gcc15.patch @@ -0,0 +1,22 @@ +--- a/src/lib/util/corestr.h ++++ b/src/lib/util/corestr.h +@@ -17,6 +17,7 @@ + #include + + #include ++#include + + + /*************************************************************************** +--- a/3rdparty/sol2/sol/sol.hpp ++++ b/3rdparty/sol2/sol/sol.hpp +@@ -6056,7 +6056,8 @@ + static_assert(std::is_constructible::value, "T must be constructible with Args"); + + *this = nullopt; +- this->construct(std::forward(args)...); ++ m_value = std::addressof(std::forward(args)...); ++ return *m_value; + } + + /// Swaps this optional with the other. diff --git a/projects/ArchR/packages/emulators/libretro/same_cdi-lr/patches/mame-crosscompile.patch b/projects/ArchR/packages/emulators/libretro/same_cdi-lr/patches/mame-crosscompile.patch new file mode 100644 index 0000000000..49f1ff3763 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/same_cdi-lr/patches/mame-crosscompile.patch @@ -0,0 +1,54 @@ +--- a/3rdparty/genie/build/gmake.linux/genie.make 2018-08-11 00:17:44.000000000 +0200 ++++ b/3rdparty/genie/build/gmake.linux/genie.make 2019-04-03 11:57:27.671223016 +0200 +@@ -28,8 +28,8 @@ + RM = $(SILENT) del /F "$(subst /,\\,$(1))" 2> nul || exit 0 + endif + +-CC = gcc +-CXX = g++ ++CC = $(HOST_CC) ++CXX = $(HOST_CXX) + AR = ar + + ifndef RESCOMP +@@ -50,12 +50,12 @@ + INCLUDES += -I"../../src/host/lua-5.3.0/src" + ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP -MP $(DEFINES) $(INCLUDES) + ALL_ASMFLAGS += $(ASMFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Wall -Wextra -Os $(MPARAM) -Wno-implicit-fallthrough +- ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Wall -Wextra -Os $(MPARAM) -Wno-implicit-fallthrough +- ALL_CXXFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Wall -Wextra -Os $(MPARAM) -Wno-implicit-fallthrough +- ALL_OBJCFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Wall -Wextra -Os $(MPARAM) -Wno-implicit-fallthrough +- ALL_OBJCPPFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Wall -Wextra -Os $(MPARAM) -Wno-implicit-fallthrough ++ ALL_CFLAGS += $(ALL_CPPFLAGS) $(ARCH) -Wall -Wextra -Os $(MPARAM) -Wno-implicit-fallthrough ++ ALL_CXXFLAGS += $(ALL_CPPFLAGS) $(ARCH) -Wall -Wextra -Os $(MPARAM) -Wno-implicit-fallthrough ++ ALL_OBJCFLAGS += $(ALL_CPPFLAGS) $(ARCH) -Wall -Wextra -Os $(MPARAM) -Wno-implicit-fallthrough ++ ALL_OBJCPPFLAGS += $(ALL_CPPFLAGS) $(ARCH) -Wall -Wextra -Os $(MPARAM) -Wno-implicit-fallthrough + ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES) +- ALL_LDFLAGS += $(LDFLAGS) -L"." -s -rdynamic ++ ALL_LDFLAGS += -L"." -s -rdynamic + LIBDEPS += + LDDEPS += + LDRESP = +--- a/3rdparty/genie/src/host/scripts.c 2019-05-21 22:41:14.207745861 +0200 ++++ b/3rdparty/genie/src/host/scripts.c 2019-05-21 22:42:43.159893481 +0200 +@@ -147,7 +147,7 @@ + + /* tools/gcc.lua */ + "premake.gcc = { }\npremake.gcc.cc = \"gcc\"\npremake.gcc.cxx = \"g++\"\npremake.gcc.ar = \"ar\"\npremake.gcc.rc = \"windres\"\npremake.gcc.llvm = false\nlocal cflags =\n{\nEnableSSE = \"-msse\",\nEnableSSE2 = \"-msse2\",\nEnableAVX = \"-mavx\",\nEnableAVX2 = \"-mavx2\",\nPedanticWarnings = \"-Wall -Wextra -pedantic\",\nExtraWarnings = \"-Wall -Wextra\",\nFatalWarnings = \"-Werror\",\nFloatFast = \"-ffast-math\",\nFloatStrict = \"-ffloat-store\",\nNoFramePointer = \"-fomit-frame-pointer\",\nOptimize = \"-O2\",\nOptimizeSize = \"-Os\",\nOptimizeSpeed = \"-O3\",\nSymbols = \"-g\",\n}\nlocal cxxflags =\n{\nCpp11 = \"-std=c++11\",\nCpp14 = \"-std=c++14\",\nCpp17 = \"-std=c++17\",\nCppLatest = \"-std=c++2a\",\nNoExceptions = \"-fno-exceptions\",\nNoRTTI = \"-fno-rtti\",\nUnsignedChar = \"-funsigned-char\",\n}\nlocal objcflags =\n{\nObjcARC = \"-fobjc-arc\",\n}\npremake.gcc.platforms =\n{\nNative = {\n" +- "cppflags = \"-MMD -MP\",\n},\nx32 = {\ncppflags = \"-MMD -MP\",\nflags = \"-m32\",\n},\nx64 = {\ncppflags = \"-MMD -MP\",\nflags = \"-m64\",\n},\nUniversal = {\nar = \"libtool\",\ncppflags = \"-MMD -MP\",\nflags = \"-arch i386 -arch x86_64 -arch ppc -arch ppc64\",\n},\nUniversal32 = {\nar = \"libtool\",\ncppflags = \"-MMD -MP\",\nflags = \"-arch i386 -arch ppc\",\n},\nUniversal64 = {\nar = \"libtool\",\ncppflags = \"-MMD -MP\",\nflags = \"-arch x86_64 -arch ppc64\",\n},\nPS3 = {\ncc = \"ppu-lv2-g++\",\ncxx = \"ppu-lv2-g++\",\nar = \"ppu-lv2-ar\",\ncppflags = \"-MMD -MP\",\n},\nWiiDev = {\ncppflags = \"-MMD -MP -I$(LIBOGC_INC) $(MACHDEP)\",\nldflags= \"-L$(LIBOGC_LIB) $(MACHDEP)\",\ncfgsettings = [[\n ifeq ($(strip $(DEVKITPPC)),)\n $(error \"DEVKITPPC environment variable is not set\")'\n endif\n include $(DEVKITPPC)/wii_rules']],\n},\nOrbis = {\ncc = \"orbis-clang\",\ncxx = \"orbis-clang++\",\nar = \"orbis-ar\",\ncppflag" ++ "cppflags = \"-MMD -MP\",\n},\nx32 = {\ncppflags = \"-MMD -MP\"\n},\nx64 = {\ncppflags = \"-MMD -MP\",\nflags = \"-m64\",\n},\nUniversal = {\nar = \"libtool\",\ncppflags = \"-MMD -MP\",\nflags = \"-arch i386 -arch x86_64 -arch ppc -arch ppc64\",\n},\nUniversal32 = {\nar = \"libtool\",\ncppflags = \"-MMD -MP\",\nflags = \"-arch i386 -arch ppc\",\n},\nUniversal64 = {\nar = \"libtool\",\ncppflags = \"-MMD -MP\",\nflags = \"-arch x86_64 -arch ppc64\",\n},\nPS3 = {\ncc = \"ppu-lv2-g++\",\ncxx = \"ppu-lv2-g++\",\nar = \"ppu-lv2-ar\",\ncppflags = \"-MMD -MP\",\n},\nWiiDev = {\ncppflags = \"-MMD -MP -I$(LIBOGC_INC) $(MACHDEP)\",\nldflags= \"-L$(LIBOGC_LIB) $(MACHDEP)\",\ncfgsettings = [[\n ifeq ($(strip $(DEVKITPPC)),)\n $(error \"DEVKITPPC environment variable is not set\")'\n endif\n include $(DEVKITPPC)/wii_rules']],\n},\nOrbis = {\ncc = \"orbis-clang\",\ncxx = \"orbis-clang++\",\nar = \"orbis-ar\",\ncppflag" + "s = \"-MMD -MP\",\n},\nEmscripten = {\ncc = \"$(EMSCRIPTEN)/emcc\",\ncxx = \"$(EMSCRIPTEN)/em++\",\nar = \"$(EMSCRIPTEN)/emar\",\ncppflags = \"-MMD -MP\",\n}\n}\nlocal platforms = premake.gcc.platforms\nfunction premake.gcc.getcppflags(cfg)\nlocal flags = { }\ntable.insert(flags, platforms[cfg.platform].cppflags)\nif flags[1]:startswith(\"-MMD\") then\ntable.insert(flags, \"-MP\")\nend\nreturn flags\nend\nfunction premake.gcc.getcflags(cfg)\nlocal result = table.translate(cfg.flags, cflags)\ntable.insert(result, platforms[cfg.platform].flags)\nif cfg.system ~= \"windows\" and cfg.kind == \"SharedLib\" then\ntable.insert(result, \"-fPIC\")\nend\nreturn result\nend\nfunction premake.gcc.getcxxflags(cfg)\nlocal result = table.translate(cfg.flags, cxxflags)\nreturn result\nend\nfunction premake.gcc.getobjcflags(cfg)\nreturn table.translate(cfg.flags, objcflags)\nend\nfunction premake.gcc.getldflags(cfg)\nlocal result = { }\nif not cfg.flags.Symbols then\nif cfg.system == \"macosx\" then" + "\nelse\ntable.insert(result, \"-s\")\nend\nend\nif cfg.kind == \"Bundle\" then\ntable.insert(result, \"-bundle\")\nend\nif cfg.kind == \"SharedLib\" then\nif cfg.system == \"macosx\" then\ntable.insert(result, \"-dynamiclib\")\nelse\ntable.insert(result, \"-shared\")\nend\nif cfg.system == \"windows\" and not cfg.flags.NoImportLib then\ntable.insert(result, '-Wl,--out-implib=\"' .. cfg.linktarget.fullpath .. '\"')\nend\nend\nif cfg.kind == \"WindowedApp\" and cfg.system == \"windows\" then\ntable.insert(result, \"-mwindows\")\nend\nlocal platform = platforms[cfg.platform]\ntable.insert(result, platform.flags)\ntable.insert(result, platform.ldflags)\nreturn result\nend\nfunction premake.gcc.getlibdirflags(cfg)\nlocal result = { }\nfor _, value in ipairs(premake.getlinks(cfg, \"all\", \"directory\")) do\ntable.insert(result, '-L\\\"' .. value .. '\\\"')\nend\nreturn result\nend\nfunction premake.gcc.islibfile(p)\nif path.getextension(p) == \".a\" then\nreturn true\nend\nreturn false\nend\nfunction premake.gcc.ge" + "tlibfiles(cfg)\nlocal result = {}\nfor _, value in ipairs(premake.getlinks(cfg, \"system\", \"fullpath\")) do\nif premake.gcc.islibfile(value) then\ntable.insert(result, _MAKE.esc(value))\nend\nend\nreturn result\nend\nfunction premake.gcc.getlinkflags(cfg)\nlocal result = {}\nfor _, value in ipairs(premake.getlinks(cfg, \"system\", \"fullpath\")) do\nif premake.gcc.islibfile(value) then\nvalue = path.rebase(value, cfg.project.location, cfg.location)\ntable.insert(result, _MAKE.esc(value))\nelseif path.getextension(value) == \".framework\" then\ntable.insert(result, '-framework ' .. _MAKE.esc(path.getbasename(value)))\nelse\ntable.insert(result, '-l' .. _MAKE.esc(path.getname(value)))\nend\nend\nreturn result\nend\nfunction premake.gcc.wholearchive(lib)\nif premake.gcc.llvm then\nreturn {\"-force_load\", lib}\nelse\nreturn {\"-Wl,--whole-archive\", lib, \"-Wl,--no-whole-archive\"}\nend\nend\nfunction premake.gcc.getarchiveflags(prj, cfg, ndx)\nlocal result = {}\nif cfg.platform:startswith(\"Universal\") then\n" +--- a/scripts/toolchain.lua 2019-04-30 15:47:21.000000000 +0200 ++++ b/scripts/toolchain.lua 2019-05-21 22:51:48.116148725 +0200 +@@ -698,9 +698,6 @@ + + configuration { "linux-gcc", "x32" } + objdir (_buildDir .. "linux_gcc" .. "/obj") +- buildoptions { +- "-m32", +- } + + configuration { "linux-gcc", "x32", "Release" } + targetdir (_buildDir .. "linux_gcc" .. "/bin/x32/Release") diff --git a/projects/ArchR/packages/emulators/libretro/sameboy-lr/package.mk b/projects/ArchR/packages/emulators/libretro/sameboy-lr/package.mk new file mode 100644 index 0000000000..30a6e63503 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/sameboy-lr/package.mk @@ -0,0 +1,39 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="sameboy-lr" +PKG_VERSION="2d29ece3b8e7ec44347c9daad0fabb84912ed44f" +PKG_LICENSE="MIT" +PKG_SITE="https://git.libretro.com/libretro/SameBoy" +PKG_URL="${PKG_SITE}/-/archive/${PKG_VERSION}/SameBoy-${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain util-linux:host" +PKG_LONGDESC="Gameboy and Gameboy Color emulator written in C" + +PKG_TOOLCHAIN="make" + +make_target() { + make -C libretro BOOTROMS_DIR=${PKG_BUILD}/BootROMs/prebuilt +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp ${PKG_BUILD}/sameboy_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/sameduck-lr/package.mk b/projects/ArchR/packages/emulators/libretro/sameduck-lr/package.mk new file mode 100644 index 0000000000..6e07913912 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/sameduck-lr/package.mk @@ -0,0 +1,40 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="sameduck-lr" +PKG_VERSION="5619abdb01cee6bedb47599cdb5532c318443b52" +PKG_LICENSE="MIT" +PKG_SITE="https://github.com/LIJI32/SameBoy" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_GIT_CLONE_BRANCH="SameDuck" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Mega Duck/Cougar Boy emulator written in C" + +PKG_TOOLCHAIN="make" + +make_target() { + make -C libretro +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp build/bin/sameduck_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/scummvm-lr/package.mk b/projects/ArchR/packages/emulators/libretro/scummvm-lr/package.mk new file mode 100644 index 0000000000..10aad938e2 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/scummvm-lr/package.mk @@ -0,0 +1,41 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="scummvm-lr" +PKG_VERSION="9d31b31c179fd4a43f7cfc383a3435a9070c6aa8" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/scummvm" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="ScummVM with libretro backend." + +PKG_TOOLCHAIN="make" +PKG_BUILD_FLAGS="-lto" + +pre_make_target() { + CXXFLAGS+=" -DHAVE_POSIX_MEMALIGN=1" + cd ${PKG_BUILD}/backends/platform/libretro +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp scummvm_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/scummvm-lr/patches/001-fix-building-with-gcc15.patch b/projects/ArchR/packages/emulators/libretro/scummvm-lr/patches/001-fix-building-with-gcc15.patch new file mode 100644 index 0000000000..8447e5ef4d --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/scummvm-lr/patches/001-fix-building-with-gcc15.patch @@ -0,0 +1,14 @@ +--- a/backends/platform/libretro/scripts/configure_submodules.sh ++++ b/backends/platform/libretro/scripts/configure_submodules.sh +@@ -72,5 +72,11 @@ + cd $SUBMODULE_FOLDER + [ $reset -eq 1 ] && git reset --hard > /dev/null 2>&1 + ++# dirty hack to fix gcc15 build issue ++[ -f libfaad/libfaad/common.h ] && sed -i -e '/# define strchr index/d' \ ++ -e '/\# define strrchr rindex/d' \ ++ -e '/char \*strchr(), \*strrchr();/d' \ ++ libfaad/libfaad/common.h ++ + # Success + echo 0 diff --git a/projects/ArchR/packages/emulators/libretro/slang-shaders/package.mk b/projects/ArchR/packages/emulators/libretro/slang-shaders/package.mk new file mode 100644 index 0000000000..801da2ca21 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/slang-shaders/package.mk @@ -0,0 +1,39 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="slang-shaders" +PKG_VERSION="a2ac00bcd5a44982ecaa6ba6e5b8cc9a9608b1d6" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/libretro/slang-shaders" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Common SLANG shaders for RetroArch" + +PKG_TOOLCHAIN="make" + +configure_target() { + cd ${PKG_BUILD} +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/share/slang-shaders + make install INSTALLDIR="${INSTALL}/usr/share/slang-shaders" +} diff --git a/projects/ArchR/packages/emulators/libretro/smsplus-gx-lr/package.mk b/projects/ArchR/packages/emulators/libretro/smsplus-gx-lr/package.mk new file mode 100644 index 0000000000..7f4af3451c --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/smsplus-gx-lr/package.mk @@ -0,0 +1,42 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="smsplus-gx-lr" +PKG_VERSION="c642bbd0680b5959180a420036108893d0aec961" +PKG_LICENSE="Non-commercial" +PKG_SITE="https://github.com/libretro/smsplus-gx" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="SMS Plus GX is an enhanced version" + +PKG_TOOLCHAIN="make" + +make_target() { + if [ "${ARCH}" == "arm" ]; then + CFLAGS="${CFLAGS} -DALIGN_LONG" + fi + make -f Makefile.libretro +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp smsplus_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/snes9x-lr/package.mk b/projects/ArchR/packages/emulators/libretro/snes9x-lr/package.mk new file mode 100644 index 0000000000..2468246b8f --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/snes9x-lr/package.mk @@ -0,0 +1,43 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="snes9x-lr" +PKG_VERSION="5a40cd5514e63e691e39141d64267798357a1424" +PKG_LICENSE="Non-commercial" +PKG_SITE="https://github.com/libretro/snes9x" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Snes9x - Portable Super Nintendo Entertainment System (TM) emulator" + +PKG_TOOLCHAIN="make" + +make_target() { + if [ "${ARCH}" == "arm" ]; then + CXXFLAGS="${CXXFLAGS} -DARM" + fi + + make -C libretro +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp libretro/snes9x_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/snes9x2002-lr/package.mk b/projects/ArchR/packages/emulators/libretro/snes9x2002-lr/package.mk new file mode 100644 index 0000000000..199b72fa73 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/snes9x2002-lr/package.mk @@ -0,0 +1,34 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="snes9x2002-lr" +PKG_VERSION="a0709ec7dcd6de2fbebb43106bd757b649e3b7cf" +PKG_LICENSE="Non-commercial" +PKG_SITE="https://github.com/libretro/snes9x2002" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Snes9x 2002." + +PKG_TOOLCHAIN="make" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp snes9x2002_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/snes9x2005_plus-lr/package.mk b/projects/ArchR/packages/emulators/libretro/snes9x2005_plus-lr/package.mk new file mode 100644 index 0000000000..44febaaf54 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/snes9x2005_plus-lr/package.mk @@ -0,0 +1,35 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="snes9x2005_plus-lr" +PKG_VERSION="74d871db9b4dba6dbe6c5ecebc88cbf255be5349" +PKG_LICENSE="Non-commercial" +PKG_SITE="https://github.com/libretro/snes9x2005" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Snes9x 2005 Plus." +PKG_TOOLCHAIN="make" + +PKG_MAKE_OPTS_TARGET="USE_BLARGG_APU=1 platform=armv8-hardfloat-neon" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp snes9x2005_plus_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/snes9x2005_plus-lr/patches/01-snes9x2005_plux-01-fix-fpic.patch b/projects/ArchR/packages/emulators/libretro/snes9x2005_plus-lr/patches/01-snes9x2005_plux-01-fix-fpic.patch new file mode 100644 index 0000000000..3868c0280e --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/snes9x2005_plus-lr/patches/01-snes9x2005_plux-01-fix-fpic.patch @@ -0,0 +1,26 @@ +--- a/Makefile ++++ b/Makefile +@@ -74,9 +74,10 @@ + else ifneq (,$(findstring armv,$(platform))) + TARGET := $(TARGET_NAME)_libretro.so + fpic := -fPIC ++ FLAGS += $(fpic) + SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T +- CC = gcc +- CXX = g++ ++ #CC = gcc ++ #CXX = g++ + PLATFORM_DEFINES += -marm + ifneq (,$(findstring softfloat,$(platform))) + PLATFORM_DEFINES += -mfloat-abi=softfp +@@ -84,8 +85,8 @@ + PLATFORM_DEFINES += -mfloat-abi=hard + endif + ifneq (,$(findstring neon,$(platform))) +- FLAGS += -mfpu=neon +- ASFLAGS += -mfpu=neon ++ #FLAGS += -mfpu=neon ++ #ASFLAGS += -mfpu=neon + HAVE_NEON = 1 + endif + PLATFORM_DEFINES += -DARM diff --git a/projects/ArchR/packages/emulators/libretro/snes9x2010-lr/package.mk b/projects/ArchR/packages/emulators/libretro/snes9x2010-lr/package.mk new file mode 100644 index 0000000000..8ba4761916 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/snes9x2010-lr/package.mk @@ -0,0 +1,38 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="snes9x2010-lr" +PKG_VERSION="f9ae8fd28b13070a945a829ccf41cbf90a21d0f7" +PKG_LICENSE="Non-commercial" +PKG_SITE="https://github.com/libretro/snes9x2010" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Snes9x 2010." + +PKG_TOOLCHAIN="make" + +make_target() { + make -f Makefile.libretro +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp snes9x2010_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/snes9x2010-lr/patches/snes9x2010-add-oga.patch b/projects/ArchR/packages/emulators/libretro/snes9x2010-lr/patches/snes9x2010-add-oga.patch new file mode 100644 index 0000000000..dff83e8770 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/snes9x2010-lr/patches/snes9x2010-add-oga.patch @@ -0,0 +1,32 @@ +--- a/Makefile.libretro ++++ b/Makefile.libretro +@@ -344,6 +344,29 @@ + endif + ####################################### + ++ ++######################################### ++# (armv8 a35, hard point, neon based) ### ++# Odroid Go Advance ++else ifeq ($(platform), goa_armv8_a35) ++TARGET := $(TARGET_NAME)_libretro.so ++ fpic := -fPIC ++ SHARED := -shared -Wl,--version-script=libretro/link.T -Wl,--no-undefined ++ CFLAGS += -Ofast \ ++ -flto=4 -fuse-linker-plugin \ ++ -fdata-sections -ffunction-sections -Wl,--gc-sections \ ++ -fno-stack-protector -fno-ident -fomit-frame-pointer \ ++ -falign-functions=1 -falign-jumps=1 -falign-loops=1 \ ++ -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-unroll-loops \ ++ -fmerge-all-constants -fno-math-errno \ ++ -marm ++ CXXFLAGS += $(CFLAGS) ++ CPPFLAGS += $(CFLAGS) ++ ASFLAGS += $(CFLAGS) ++ HAVE_NEON = 1 ++ ARCH = arm ++ BUILTIN_GPU = neon ++ USE_DYNAREC = 1 + # Xbox 360 + else ifeq ($(platform), xenon) + EXT=a diff --git a/projects/ArchR/packages/emulators/libretro/stella-lr/package.mk b/projects/ArchR/packages/emulators/libretro/stella-lr/package.mk new file mode 100644 index 0000000000..1cc05badd6 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/stella-lr/package.mk @@ -0,0 +1,46 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="stella-lr" +PKG_VERSION="5d737b2e54717753be235c4fd2cd172e307da623" +PKG_LICENSE="GPL2" +PKG_SITE="https://github.com/stella-emu/stella" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Port of Stella to libretro." +PKG_TOOLCHAIN="make" + +pre_configure_target() { + case ${TARGET_ARCH} in + aarch64) + PKG_MAKE_OPTS_TARGET=" -C ${PKG_BUILD}/src/os/libretro -f Makefile platform=aarch64" + ;; + *) + PKG_MAKE_OPTS_TARGET=" -C ${PKG_BUILD}/src/os/libretro -f Makefile" + ;; + esac +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp ${PKG_BUILD}/src/os/libretro/stella_libretro.so ${INSTALL}/usr/lib/libretro/ +} + diff --git a/projects/ArchR/packages/emulators/libretro/stella-lr/patches/001-aarch64.patch b/projects/ArchR/packages/emulators/libretro/stella-lr/patches/001-aarch64.patch new file mode 100644 index 0000000000..f4cabd3119 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/stella-lr/patches/001-aarch64.patch @@ -0,0 +1,20 @@ +diff -rupN stella.orig/src/os/libretro/Makefile stella/src/os/libretro/Makefile +--- stella.orig/src/os/libretro/Makefile 2022-10-02 14:39:47.954719313 -0400 ++++ stella/src/os/libretro/Makefile 2022-10-03 19:19:12.544824555 -0400 +@@ -114,6 +114,16 @@ else ifeq ($(platform), osx) + CXXFLAGS += $(ARCHFLAGS) + LDFLAGS += $(ARCHFLAGS) + ++else ifeq ($(platform), aarch64) ++ TARGET := $(TARGET_NAME)_libretro.so ++ fpic := -fPIC ++ SHARED := -shared -Wl,--version-script=link.T -Wl,--no-undefined ++ CXXFLAGS += -lpthread -DARM64 ++ LDFLAGS += -lpthread -static-libgcc -lstdc++ ++ ARCH = arm64 ++ USE_DYNAREC = 1 ++ ++ + # iOS + else ifneq (,$(findstring ios,$(platform))) + CXXFLAGS += $(LTO) -stdlib=libc++ diff --git a/projects/ArchR/packages/emulators/libretro/swanstation-lr/package.mk b/projects/ArchR/packages/emulators/libretro/swanstation-lr/package.mk new file mode 100644 index 0000000000..a77a11a223 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/swanstation-lr/package.mk @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2020-present Shanti Gilbert (https://github.com/shantigilbert) +# Maintenance 2020 351ELEC team (https://github.com/fewtarius/351ELEC) + +PKG_NAME="swanstation-lr" +PKG_VERSION="4d309c05fd7bdc503d91d267bd542edb8d192b09" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/libretro/swanstation" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain nasm:host" +PKG_LONGDESC="SwanStation - PlayStation 1, aka. PSX Emulator" +PKG_TOOLCHAIN="cmake" +PKG_BUILD_FLAGS="-lto" + +if [ ! "${OPENGL}" = "no" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" +fi + +if [ "${OPENGLES_SUPPORT}" = yes ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" +fi + +pre_configure_target() { + PKG_CMAKE_OPTS_TARGET+=" -DCMAKE_BUILD_TYPE=Release -DBUILD_LIBRETRO_CORE=ON " +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp ${PKG_BUILD}/.${TARGET_NAME}/swanstation_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/tgbdual-lr/package.mk b/projects/ArchR/packages/emulators/libretro/tgbdual-lr/package.mk new file mode 100644 index 0000000000..a9b11fc692 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/tgbdual-lr/package.mk @@ -0,0 +1,35 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="tgbdual-lr" +PKG_VERSION="933707c0ba8f12360f6d79712f735a917713709a" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/tgbdual-libretro" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="libretro port of TGB Dual" + +PKG_TOOLCHAIN="make" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp tgbdual_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/theodore-lr/package.mk b/projects/ArchR/packages/emulators/libretro/theodore-lr/package.mk new file mode 100644 index 0000000000..1a84175ae1 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/theodore-lr/package.mk @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="theodore-lr" +PKG_VERSION="242e932d838284a61b81aa7641c60d813934025e" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/Zlika/theodore" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="A port of the Theodore emulator for the Thomson MO/TO system--a family of French 8-bit home computers--to libretro. This core emulates all of the main models of the MO/TO family, including the TO7, TO7/70, TO8, TO8D, TO9, TO9+, MO5 and MO6 models, as well as the Olivetti Prodest PC128, which is a rebranded MO6 that was released in the Italian market. The core includes an onscreen keyboard, which can be toggled with retropad-select and navigated using the d-pad and retropad-B to press the selected key." +PKG_TOOLCHAIN="make" + +PKG_MAKE_OPTS_TARGET="-C . platform=unix" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp ${PKG_BUILD}/theodore_libretro.so ${INSTALL}/usr/lib/libretro +} diff --git a/projects/ArchR/packages/emulators/libretro/tic80-lr/package.mk b/projects/ArchR/packages/emulators/libretro/tic80-lr/package.mk new file mode 100644 index 0000000000..c053eff4e2 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/tic80-lr/package.mk @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="tic80-lr" +PKG_VERSION="7020500a6e88f6ee91301933bb77f082a10e10f5" +PKG_LICENSE="MIT" +PKG_SITE="https://github.com/nesbox/TIC-80" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="TIC-80 is a fantasy computer for making, playing and sharing tiny games." +GET_HANDLER_SUPPORT="git" + +PKG_CMAKE_OPTS_TARGET="-DBUILD_DEMO_CARTS=OFF \ + -DBUILD_EDITORS=OFF \ + -DBUILD_LIBRETRO=ON \ + -DBUILD_PLAYER=OFF \ + -DBUILD_PRO=OFF \ + -DBUILD_SDL=OFF \ + -DBUILD_SDLGPU=OFF \ + -DBUILD_SOKOL=OFF \ + -DBUILD_STATIC=ON \ + -DBUILD_TOOLS=OFF \ + -DBUILD_TOUCH_INPUT=ON \ + -DBUILD_WITH_ALL=OFF \ + -DBUILD_WITH_FENNEL=ON \ + -DBUILD_WITH_JANET=OFF \ + -DBUILD_WITH_LUA=ON \ + -DBUILD_WITH_MRUBY=OFF \ + -DBUILD_WITH_POCKETPY=OFF \ + -DBUILD_WITH_QUICKJS=OFF \ + -DBUILD_WITH_SCHEME=OFF \ + -DBUILD_WITH_SQUIRREL=OFF \ + -DBUILD_WITH_WASM=OFF \ + -DBUILD_WITH_WREN=ON \ + -DBUILD_WITH_ZLIB=ON \ + -DCMAKE_BUILD_TYPE=Release" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp ${PKG_BUILD}/.${TARGET_NAME}/bin/tic80_libretro.so ${INSTALL}/usr/lib/libretro/tic80_libretro.so +} diff --git a/projects/ArchR/packages/emulators/libretro/tyrquake-lr/package.mk b/projects/ArchR/packages/emulators/libretro/tyrquake-lr/package.mk new file mode 100644 index 0000000000..bae39ad327 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/tyrquake-lr/package.mk @@ -0,0 +1,42 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="tyrquake-lr" +PKG_VERSION="77217664a09afe893a06be8e3e8f9611184636f8" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/tyrquake" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Libretro port of Tyrquake (Quake 1 engine)" +PKG_PATCH_DIRS+="${DEVICE}" + +PKG_TOOLCHAIN="make" + +pre_configure_target() { + if [ "${ARCH}" == "arm" ]; then + CFLAGS="${CFLAGS} -DARM -marm" + fi + CFLAGS="${CFLAGS} -std=gnu17" +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp tyrquake_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/uae4arm/package.mk b/projects/ArchR/packages/emulators/libretro/uae4arm/package.mk new file mode 100644 index 0000000000..1cd42273f4 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/uae4arm/package.mk @@ -0,0 +1,39 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="uae4arm" +PKG_VERSION="177c2f0e892adf2603ada9b150e31beffe0f76c3" +PKG_ARCH="arm aarch64" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/Chips-fr/uae4arm-rpi" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain flac mpg123" +PKG_LONGDESC="Port of uae4arm for libretro (rpi/android)" + +PKG_TOOLCHAIN="make" + +make_target() { + make -f Makefile.libretro platform=unix_aarch64 "CPU_FLAGS=-mcpu=${TARGET_CPU}" +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp uae4arm_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/uzem-lr/package.mk b/projects/ArchR/packages/emulators/libretro/uzem-lr/package.mk new file mode 100644 index 0000000000..8726607911 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/uzem-lr/package.mk @@ -0,0 +1,35 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="uzem-lr" +PKG_VERSION="cd6004ea143435cfdb6b12e7c6779dab499f7829" +PKG_LICENSE="MIT" +PKG_SITE="https://github.com/libretro/libretro-uzem" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_PATCH_DIRS="libretro" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="A retro-minimalist game console engine for the ATMega644" + +PKG_TOOLCHAIN="make" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp uzem_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/vba-next-lr/package.mk b/projects/ArchR/packages/emulators/libretro/vba-next-lr/package.mk new file mode 100644 index 0000000000..cda0c6330c --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/vba-next-lr/package.mk @@ -0,0 +1,39 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="vba-next-lr" +PKG_VERSION="d0ec7f3e209a91b903bb9d2c2397fef2bb3cca32" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/libretro/vba-next" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Optimized port of VBA-M to Libretro." + +PKG_TOOLCHAIN="make" + +make_target() { + make -f Makefile.libretro +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp vba_next_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/vbam-lr/package.mk b/projects/ArchR/packages/emulators/libretro/vbam-lr/package.mk new file mode 100644 index 0000000000..c5132744c0 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/vbam-lr/package.mk @@ -0,0 +1,40 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="vbam-lr" +PKG_VERSION="d0787aee43d260675da203c2f85ba9fa226c0c66" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/vbam-libretro" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="A fork of VBA-M with libretro integration" + +PKG_TOOLCHAIN="make" +PKG_USE_CMAKE="no" + +make_target() { + make -C ../src/libretro -f Makefile +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp ../src/libretro/vbam_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/vecx-lr/package.mk b/projects/ArchR/packages/emulators/libretro/vecx-lr/package.mk new file mode 100644 index 0000000000..e9bc17d076 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/vecx-lr/package.mk @@ -0,0 +1,38 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="vecx-lr" +PKG_VERSION="841229a6a81a0461d08af6488f252dcec5266c6a" +PKG_LICENSE="GPLv2|LGPLv2.1" +PKG_SITE="https://github.com/libretro/libretro-vecx" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="libretro adaptation of vecx" + +PKG_TOOLCHAIN="make" + +make_target() { + make -f Makefile.libretro HAS_GPU=1 HAS_GLES=1 +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp vecx_libretro.so ${INSTALL}/usr/lib/libretro/vecx_libretro.so +} diff --git a/projects/ArchR/packages/emulators/libretro/vice-lr/package.mk b/projects/ArchR/packages/emulators/libretro/vice-lr/package.mk new file mode 100644 index 0000000000..8f32781e9c --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/vice-lr/package.mk @@ -0,0 +1,52 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020 351ELEC team (https://github.com/fewtarius/351ELEC) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="vice-lr" +PKG_VERSION="91d0d4d884acd44b5240dfcdbd8bdc2f0f757dfd" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/vice-libretro" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Versatile Commodore 8-bit Emulator version 3.0" +PKG_TOOLCHAIN="make" + +make_target() { + if [ ! -d "built" ] + then + mkdir built + fi + for EMUTYPE in x128 x64sc x64dtv xscpu64 xplus4 xvic xcbm5x0 xcbm2 xpet x64 + do + make clean + make EMUTYPE=${EMUTYPE} + mv vice_*_libretro.so built + done +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp built/vice_x128_libretro.so ${INSTALL}/usr/lib/libretro/ + cp built/vice_x64_libretro.so ${INSTALL}/usr/lib/libretro/ + cp built/vice_xplus4_libretro.so ${INSTALL}/usr/lib/libretro/ + cp built/vice_xvic_libretro.so ${INSTALL}/usr/lib/libretro/ + cp built/vice_xpet_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/vice-lr/patches/001-revert-makefile.patch b/projects/ArchR/packages/emulators/libretro/vice-lr/patches/001-revert-makefile.patch new file mode 100644 index 0000000000..855ea82355 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/vice-lr/patches/001-revert-makefile.patch @@ -0,0 +1,31 @@ +diff -rupN vice.orig/Makefile vice/Makefile +--- vice.orig/Makefile 2023-09-10 22:23:12.000000000 +0000 ++++ vice/Makefile 2023-09-16 12:43:09.816419382 +0000 +@@ -416,7 +416,6 @@ COMMONFLAGS += -DCORE_NAME=\"$(EMUTYPE)\ + include Makefile.common + + OBJECTS += $(patsubst %.cpp,%.o,$(SOURCES_CXX:.cc=.o)) $(SOURCES_C:.c=.o) +-PLATFLAGS := $(CFLAGS) + CXXFLAGS += $(fpic) $(INCFLAGS) $(COMMONFLAGS) + CFLAGS += $(fpic) $(INCFLAGS) $(COMMONFLAGS) + LDFLAGS += -lm $(fpic) +@@ -437,12 +436,6 @@ ifeq ($(platform), theos_ios) + ${LIBRARY_NAME}_FILES = $(SOURCES_CXX) $(SOURCES_C) + include $(THEOS_MAKE_PATH)/library.mk + else +- +-default: +- $(info CFLAGS: $(PLATFLAGS) $(COMMONFLAGS)) +- $(info -------) +- $(MAKE) $(TARGET) +- + all: $(TARGET) + + -include $(OBJECTS:.o=.d)) +@@ -490,5 +483,5 @@ objectclean: + targetclean: + rm -f $(TARGET) + +-.PHONY: all clean objectclean targetclean ++.PHONY: clean + endif diff --git a/projects/ArchR/packages/emulators/libretro/vircon32-lr/package.mk b/projects/ArchR/packages/emulators/libretro/vircon32-lr/package.mk new file mode 100644 index 0000000000..a5dd329a4b --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/vircon32-lr/package.mk @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present AmberELEC (https://github.com/AmberELEC) + +PKG_NAME="vircon32-lr" +PKG_VERSION="d8a92430e887286b4e5351916ef0bd35d8cb40e8" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/vircon32/vircon32-libretro" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain ${OPENGLES}" +PKG_LONGDESC="Vircon32 32-bit Virtual Console" +PKG_TOOLCHAIN="cmake-make" + +pre_configure_target() { + PKG_CMAKE_OPTS_TARGET="-DPLATFORM=EMUELEC \ + -DOPENGL_INCLUDE_DIR=${SYSROOT_PREFIX}/usr/include \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_RULE_MESSAGES=OFF \ + -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON" + + if [ "${PREFER_GLES}" = "yes" ]; then + PKG_CMAKE_OPTS_TARGET+=" -DENABLE_OPENGLES2=1" + fi +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp -f vircon32_libretro.so ${INSTALL}/usr/lib/libretro +} diff --git a/projects/ArchR/packages/emulators/libretro/vircon32-lr/patches/0000-fix-opengl.patch b/projects/ArchR/packages/emulators/libretro/vircon32-lr/patches/0000-fix-opengl.patch new file mode 100644 index 0000000000..fd717489b6 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/vircon32-lr/patches/0000-fix-opengl.patch @@ -0,0 +1,22 @@ +diff --git a/VideoOutput.cpp b/VideoOutput.cpp +index 4109192..9dc1bca 100644 +--- a/VideoOutput.cpp ++++ b/VideoOutput.cpp +@@ -324,7 +324,7 @@ void VideoOutput::InitRendering() + + // on a core OpenGL profile, we need this since + // the default VAO is not valid! +- #if defined(EMUELEC) || defined(HAVE_OPENGLES2) ++ #if defined(HAVE_OPENGLES2) + glGenVertexArraysOES( 1, &VAO ); + glBindVertexArrayOES( VAO ); + #else +@@ -473,7 +473,7 @@ void VideoOutput::Destroy() + VBOVertexInfo = VBOIndices = 0; + + LOG( "Destroying OpenGL vertex arrays" ); +- #if defined(EMUELEC) || defined(HAVE_OPENGLES2) ++ #if defined(HAVE_OPENGLES2) + glDeleteVertexArraysOES( 1, &VAO ); + #else + glDeleteVertexArrays( 1, &VAO ); diff --git a/projects/ArchR/packages/emulators/libretro/virtualjaguar-lr/package.mk b/projects/ArchR/packages/emulators/libretro/virtualjaguar-lr/package.mk new file mode 100644 index 0000000000..a7649d3b98 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/virtualjaguar-lr/package.mk @@ -0,0 +1,34 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="virtualjaguar-lr" +PKG_VERSION="48096c1f6f8b98cfff048a5cb4e6a86686631072" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/libretro/virtualjaguar-libretro" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Port of Virtual Jaguar to Libretro" + +PKG_TOOLCHAIN="make" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp virtualjaguar_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/package.mk b/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/package.mk new file mode 100644 index 0000000000..724f018102 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/package.mk @@ -0,0 +1,31 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="vitaquake2-lr" +PKG_VERSION="69e56a470638ca8ed15b53212923220360a69f97" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/vitaquake2" +PKG_URL="$PKG_SITE/archive/$PKG_VERSION.tar.gz" +PKG_DEPENDS_TARGET="toolchain vitaquake2-rogue-lr vitaquake2-xatrix-lr vitaquake2-zaero-lr" +PKG_LONGDESC="Libretro port of VitaQuakeII (Quake 2 engine)" + +if [ "${OPENGL_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL}" +elif [ "${OPENGLES_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" +fi + +pre_make_target() { + export BUILD_SYSROOT=${SYSROOT_PREFIX} + + case ${TARGET_ARCH} in + aarch64) + PKG_MAKE_OPTS_TARGET+=" platform=${DEVICE}_archr" + ;; + esac +} + +makeinstall_target() { + mkdir -p $INSTALL/usr/lib/libretro + cp vitaquake2_libretro.so $INSTALL/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/patches/aarch64/001-set-platform.patch b/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/patches/aarch64/001-set-platform.patch new file mode 100644 index 0000000000..800fed1e1e --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/patches/aarch64/001-set-platform.patch @@ -0,0 +1,19 @@ +diff -rupN vitaquake2.orig/Makefile vitaquake2/Makefile +--- vitaquake2.orig/Makefile 2023-09-15 16:57:45.991890996 +0000 ++++ vitaquake2/Makefile 2023-09-15 20:08:45.856895708 +0000 +@@ -76,6 +76,15 @@ else ifeq ($(platform), linux-portable) + SHARED := -shared -Wl,--version-script=$(CORE_DIR)/link.T + LIBM := + ++else ifeq ($(platform), @DEVICE@_archr) ++ TARGET := $(TARGET_NAME)_libretro.so ++ fpic := -fPIC ++ SHARED := -shared -Wl,--version-script=$(CORE_DIR)/link.T -Wl,--no-undefined ++ CFLAGS += -ffast-math -DARM ++ CFLAGS += -D_POSIX_C_SOURCE=200809L -D_DEFAULT_SOURCE ++ GLES := 1 ++ GLES31 := 1 ++ + else ifneq (,$(findstring rockchip,$(platform))) + EXT ?= so + TARGET := $(TARGET_NAME)_libretro.$(EXT) diff --git a/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/patches/x86_64/001-set-platform.patch b/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/patches/x86_64/001-set-platform.patch new file mode 100644 index 0000000000..fdb106c448 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/patches/x86_64/001-set-platform.patch @@ -0,0 +1,18 @@ +diff -rupN vitaquake2.orig/Makefile vitaquake2/Makefile +--- vitaquake2.orig/Makefile 2023-09-15 16:57:45.991890996 +0000 ++++ vitaquake2/Makefile 2023-09-15 20:08:45.856895708 +0000 +@@ -76,6 +76,14 @@ else ifeq ($(platform), linux-portable) + SHARED := -shared -Wl,--version-script=$(CORE_DIR)/link.T + LIBM := + ++else ifeq ($(platform), @DEVICE@) ++ TARGET := $(TARGET_NAME)_libretro.so ++ fpic := -fPIC ++ SHARED := -shared -Wl,--version-script=$(CORE_DIR)/link.T -Wl,--no-undefined ++ CFLAGS += -D_POSIX_C_SOURCE=199309L ++ GLES := 1 ++ GLES31 := 1 ++ + else ifneq (,$(findstring rockchip,$(platform))) + EXT ?= so + TARGET := $(TARGET_NAME)_libretro.$(EXT) diff --git a/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/vitaquake2-rogue-lr/package.mk b/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/vitaquake2-rogue-lr/package.mk new file mode 100644 index 0000000000..4adc23ff90 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/vitaquake2-rogue-lr/package.mk @@ -0,0 +1,33 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="vitaquake2-rogue-lr" +PKG_VERSION="$(get_pkg_version vitaquake2-lr)" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/vitaquake2" +PKG_URL="$PKG_SITE/archive/$PKG_VERSION.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Libretro port of VitaQuakeII (Quake 2 engine)" + +if [ "${OPENGL_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL}" +elif [ "${OPENGLES_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" +fi + +pre_make_target() { + export BUILD_SYSROOT=${SYSROOT_PREFIX} + + PKG_MAKE_OPTS_TARGET+=" basegame=rogue" + + case ${TARGET_ARCH} in + aarch64) + PKG_MAKE_OPTS_TARGET+=" platform=${DEVICE}_archr" + ;; + esac +} + +makeinstall_target() { + mkdir -p $INSTALL/usr/lib/libretro + cp vitaquake2-rogue_libretro.so $INSTALL/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/vitaquake2-rogue-lr/patches/aarch64/001-set-platform.patch b/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/vitaquake2-rogue-lr/patches/aarch64/001-set-platform.patch new file mode 120000 index 0000000000..77bcdfd104 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/vitaquake2-rogue-lr/patches/aarch64/001-set-platform.patch @@ -0,0 +1 @@ +../../../patches/aarch64/001-set-platform.patch \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/vitaquake2-rogue-lr/patches/x86_64/001-set-platform.patch b/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/vitaquake2-rogue-lr/patches/x86_64/001-set-platform.patch new file mode 100644 index 0000000000..fdb106c448 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/vitaquake2-rogue-lr/patches/x86_64/001-set-platform.patch @@ -0,0 +1,18 @@ +diff -rupN vitaquake2.orig/Makefile vitaquake2/Makefile +--- vitaquake2.orig/Makefile 2023-09-15 16:57:45.991890996 +0000 ++++ vitaquake2/Makefile 2023-09-15 20:08:45.856895708 +0000 +@@ -76,6 +76,14 @@ else ifeq ($(platform), linux-portable) + SHARED := -shared -Wl,--version-script=$(CORE_DIR)/link.T + LIBM := + ++else ifeq ($(platform), @DEVICE@) ++ TARGET := $(TARGET_NAME)_libretro.so ++ fpic := -fPIC ++ SHARED := -shared -Wl,--version-script=$(CORE_DIR)/link.T -Wl,--no-undefined ++ CFLAGS += -D_POSIX_C_SOURCE=199309L ++ GLES := 1 ++ GLES31 := 1 ++ + else ifneq (,$(findstring rockchip,$(platform))) + EXT ?= so + TARGET := $(TARGET_NAME)_libretro.$(EXT) diff --git a/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/vitaquake2-xatrix-lr/package.mk b/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/vitaquake2-xatrix-lr/package.mk new file mode 100644 index 0000000000..e98f560878 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/vitaquake2-xatrix-lr/package.mk @@ -0,0 +1,33 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="vitaquake2-xatrix-lr" +PKG_VERSION="$(get_pkg_version vitaquake2-lr)" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/vitaquake2" +PKG_URL="$PKG_SITE/archive/$PKG_VERSION.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Libretro port of VitaQuakeII (Quake 2 engine)" + +if [ "${OPENGL_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL}" +elif [ "${OPENGLES_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" +fi + +pre_make_target() { + export BUILD_SYSROOT=${SYSROOT_PREFIX} + + PKG_MAKE_OPTS_TARGET+=" basegame=xatrix" + + case ${TARGET_ARCH} in + aarch64) + PKG_MAKE_OPTS_TARGET+=" platform=${DEVICE}_archr" + ;; + esac +} + +makeinstall_target() { + mkdir -p $INSTALL/usr/lib/libretro + cp vitaquake2-xatrix_libretro.so $INSTALL/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/vitaquake2-xatrix-lr/patches/aarch64/001-set-platform.patch b/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/vitaquake2-xatrix-lr/patches/aarch64/001-set-platform.patch new file mode 120000 index 0000000000..77bcdfd104 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/vitaquake2-xatrix-lr/patches/aarch64/001-set-platform.patch @@ -0,0 +1 @@ +../../../patches/aarch64/001-set-platform.patch \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/vitaquake2-xatrix-lr/patches/x86_64/001-set-platform.patch b/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/vitaquake2-xatrix-lr/patches/x86_64/001-set-platform.patch new file mode 100644 index 0000000000..fdb106c448 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/vitaquake2-xatrix-lr/patches/x86_64/001-set-platform.patch @@ -0,0 +1,18 @@ +diff -rupN vitaquake2.orig/Makefile vitaquake2/Makefile +--- vitaquake2.orig/Makefile 2023-09-15 16:57:45.991890996 +0000 ++++ vitaquake2/Makefile 2023-09-15 20:08:45.856895708 +0000 +@@ -76,6 +76,14 @@ else ifeq ($(platform), linux-portable) + SHARED := -shared -Wl,--version-script=$(CORE_DIR)/link.T + LIBM := + ++else ifeq ($(platform), @DEVICE@) ++ TARGET := $(TARGET_NAME)_libretro.so ++ fpic := -fPIC ++ SHARED := -shared -Wl,--version-script=$(CORE_DIR)/link.T -Wl,--no-undefined ++ CFLAGS += -D_POSIX_C_SOURCE=199309L ++ GLES := 1 ++ GLES31 := 1 ++ + else ifneq (,$(findstring rockchip,$(platform))) + EXT ?= so + TARGET := $(TARGET_NAME)_libretro.$(EXT) diff --git a/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/vitaquake2-zaero-lr/package.mk b/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/vitaquake2-zaero-lr/package.mk new file mode 100644 index 0000000000..090bc1d08f --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/vitaquake2-zaero-lr/package.mk @@ -0,0 +1,33 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="vitaquake2-zaero-lr" +PKG_VERSION="$(get_pkg_version vitaquake2-lr)" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/vitaquake2" +PKG_URL="$PKG_SITE/archive/$PKG_VERSION.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Libretro port of VitaQuakeII (Quake 2 engine)" + +if [ "${OPENGL_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL}" +elif [ "${OPENGLES_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" +fi + +pre_make_target() { + export BUILD_SYSROOT=${SYSROOT_PREFIX} + + PKG_MAKE_OPTS_TARGET+=" basegame=zaero" + + case ${TARGET_ARCH} in + aarch64) + PKG_MAKE_OPTS_TARGET+=" platform=${DEVICE}_archr" + ;; + esac +} + +makeinstall_target() { + mkdir -p $INSTALL/usr/lib/libretro + cp vitaquake2-zaero_libretro.so $INSTALL/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/vitaquake2-zaero-lr/patches/aarch64/001-set-platform.patch b/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/vitaquake2-zaero-lr/patches/aarch64/001-set-platform.patch new file mode 120000 index 0000000000..77bcdfd104 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/vitaquake2-zaero-lr/patches/aarch64/001-set-platform.patch @@ -0,0 +1 @@ +../../../patches/aarch64/001-set-platform.patch \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/vitaquake2-zaero-lr/patches/x86_64/001-set-platform.patch b/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/vitaquake2-zaero-lr/patches/x86_64/001-set-platform.patch new file mode 100644 index 0000000000..fdb106c448 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/vitaquake2-lr/vitaquake2-zaero-lr/patches/x86_64/001-set-platform.patch @@ -0,0 +1,18 @@ +diff -rupN vitaquake2.orig/Makefile vitaquake2/Makefile +--- vitaquake2.orig/Makefile 2023-09-15 16:57:45.991890996 +0000 ++++ vitaquake2/Makefile 2023-09-15 20:08:45.856895708 +0000 +@@ -76,6 +76,14 @@ else ifeq ($(platform), linux-portable) + SHARED := -shared -Wl,--version-script=$(CORE_DIR)/link.T + LIBM := + ++else ifeq ($(platform), @DEVICE@) ++ TARGET := $(TARGET_NAME)_libretro.so ++ fpic := -fPIC ++ SHARED := -shared -Wl,--version-script=$(CORE_DIR)/link.T -Wl,--no-undefined ++ CFLAGS += -D_POSIX_C_SOURCE=199309L ++ GLES := 1 ++ GLES31 := 1 ++ + else ifneq (,$(findstring rockchip,$(platform))) + EXT ?= so + TARGET := $(TARGET_NAME)_libretro.$(EXT) diff --git a/projects/ArchR/packages/emulators/libretro/vitaquake3-lr/package.mk b/projects/ArchR/packages/emulators/libretro/vitaquake3-lr/package.mk new file mode 100644 index 0000000000..829423e057 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/vitaquake3-lr/package.mk @@ -0,0 +1,26 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="vitaquake3-lr" +PKG_VERSION="7a633867cf0a35c71701aef6fc9dd9dfab9c33a9" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/vitaquake3" +PKG_URL="https://github.com/libretro/vitaquake3/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Quake III - ioquake3 port for libretro" +PKG_TOOLCHAIN="make" + +if [ "${OPENGL_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL}" +elif [ "${OPENGLES_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" +fi + +pre_configure_target() { + export CFLAGS="${CFLAGS} -Wno-implicit-function-declaration -Wno-incompatible-pointer-types -Wno-implicit-int" +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp vitaquake3_libretro.so $INSTALL/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/wasm4-lr/package.mk b/projects/ArchR/packages/emulators/libretro/wasm4-lr/package.mk new file mode 100644 index 0000000000..18ed257d1e --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/wasm4-lr/package.mk @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + + +PKG_NAME="wasm4-lr" +PKG_VERSION="68cbe429fcbab3e80537282d2c21566f5ea216ea" +PKG_LICENSE="ISC" +PKG_SITE="https://github.com/aduros/wasm4" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="WASM-4 is a low-level fantasy game console for building small games with WebAssembly. Game cartridges (ROMs) are small, self-contained .wasm files that can be built with any programming language that compiles to WebAssembly." +GET_HANDLER_SUPPORT="git" +PKG_TOOLCHAIN='manual' + +make_target() { + cd ${PKG_BUILD}/runtimes/native + cmake -B build \ + -DBUILD_TARGET=wasm4_libretro \ + -DCMAKE_BUILD_TYPE=Release + cmake --build build --target wasm4_libretro +} + + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp ${PKG_BUILD}/runtimes/native/build/wasm4_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/xmil-lr/package.mk b/projects/ArchR/packages/emulators/libretro/xmil-lr/package.mk new file mode 100644 index 0000000000..0ffcb46c66 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/xmil-lr/package.mk @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2019-present asakous (https://github.com/asakous) + +PKG_NAME="xmil-lr" +PKG_VERSION="6a52dc21a5ff106137670bb600ab2ce3fcebeb1b" +PKG_LICENSE="Unknown" +PKG_SITE="https://github.com/libretro/xmil-libretro" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Libretro port of X Millennium Sharp X1 emulator" +PKG_TOOLCHAIN="make" +GET_HANDLER_SUPPORT="git" + +make_target() { + cd ${PKG_BUILD} + make -C libretro +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp ${PKG_BUILD}/libretro/x1_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/yabasanshiro-lr/package.mk b/projects/ArchR/packages/emulators/libretro/yabasanshiro-lr/package.mk new file mode 100644 index 0000000000..16e9628e52 --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/yabasanshiro-lr/package.mk @@ -0,0 +1,63 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="yabasanshiro-lr" +PKG_VERSION="39535a6abcad5abf9f71c8b2a7975f005ee12ed6" +PKG_GIT_CLONE_BRANCH="yabasanshiro" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/libretro/yabause" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Port of YabaSanshiro to libretro." +PKG_TOOLCHAIN="make" +GET_HANDLER_SUPPORT="git" + +PKG_MAKE_OPTS_TARGET+=" -C yabause/src/libretro" +if [ "${OPENGL_SUPPORT}" = "yes" ] && [ ! "${PREFER_GLES}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" + PKG_MAKE_OPTS_TARGET+=" FORCE_GLES=0" +elif [ "${OPENGLES_SUPPORT}" = yes ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" + PKG_MAKE_OPTS_TARGET+=" FORCE_GLES=1" +fi + +pre_configure_target() { + export CFLAGS="${CFLAGS} -Wno-implicit-function-declaration" + sed -i 's/\-O[23]/-Ofast -ffast-math/' ${PKG_BUILD}/yabause/src/libretro/Makefile + + case ${ARCH} in + aarch64) + PKG_MAKE_OPTS_TARGET+=" platform=rockpro64 HAVE_NEON=0" + # no-outline-atomics is only needed for armv8.2-a targets where we don't use this flag + # as it prohibits the use of LSE-instructions, this is a package bug most likely + export CFLAGS="${CFLAGS} -flto -fipa-pta -mno-outline-atomics" + export CXXFLAGS="${CXXFLAGS} -flto -fipa-pta -mno-outline-atomics" + export LDFLAGS="${CXXFLAGS} -flto -fipa-pta" + ;; + x86_64) + PKG_MAKE_OPTS_TARGET+=" USE_X86_DRC=1 FASTMATH=1" + ;; + esac +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp yabause/src/libretro/yabasanshiro_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/projects/ArchR/packages/emulators/libretro/yabasanshiro-lr/patches/aarch64/01-optimization.patch b/projects/ArchR/packages/emulators/libretro/yabasanshiro-lr/patches/aarch64/01-optimization.patch new file mode 100644 index 0000000000..bae9d1126e --- /dev/null +++ b/projects/ArchR/packages/emulators/libretro/yabasanshiro-lr/patches/aarch64/01-optimization.patch @@ -0,0 +1,17 @@ +diff -rupN yabasanshiro.orig/yabause/src/libretro/Makefile yabasanshiro/yabause/src/libretro/Makefile +--- yabasanshiro.orig/yabause/src/libretro/Makefile 2022-02-27 14:51:53.958685169 -0500 ++++ yabasanshiro/yabause/src/libretro/Makefile 2022-02-27 14:57:08.993824415 -0500 +@@ -155,11 +155,11 @@ else ifneq (,$(findstring rockpro64,$(pl + SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T + LDFLAGS += -lpthread + ARCH_IS_LINUX = 1 ++ FLAGS += -DAARCH64 + HAVE_SSE = 0 + FORCE_GLES = 1 +- USE_ARM_DRC = 1 ++ USE_AARCH64_DRC = 1 + DYNAREC_DEVMIYAX = 1 +- FLAGS += -march=armv8-a+crc -mcpu=cortex-a72 -mtune=cortex-a72.cortex-a53 -mfloat-abi=hard -mfpu=neon-vfpv4 -mvectorize-with-neon-quad + + # Rpi4 (64-bit) + else ifeq ($(platform), rpi4) diff --git a/projects/ArchR/packages/emulators/standalone/amiberry/config/conf/AmigaA1200-default.uae b/projects/ArchR/packages/emulators/standalone/amiberry/config/conf/AmigaA1200-default.uae new file mode 100644 index 0000000000..c81d2999d3 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/amiberry/config/conf/AmigaA1200-default.uae @@ -0,0 +1,197 @@ +config_description=UAE Amiga 1200 default configuration +config_hardware=true +config_host=true +config_version=3.6.0 +rtg_nocustom=true +a1000ram=false +synchronize_clock=yes +sound_auto=yes +pandora.jump=-1 +pandora.autofire_button=3 +pandora.button2=1 +pandora.button1=2 +pandora.move_y=0 +pandora.move_x=0 +pandora.custom_r=0 +pandora.custom_l=0 +pandora.custom_y=0 +pandora.custom_x=0 +pandora.custom_b=0 +pandora.custom_a=0 +pandora.custom_right=0 +pandora.custom_left=0 +pandora.custom_down=0 +pandora.custom_up=0 +pandora.custom_dpad=0 +pandora.custom_controls=0 +pandora.tap_delay=10 +pandora.stylus_offset=0 +pandora.joy_port=0 +pandora.joy_conf=0 +pandora.cpu_speed=600 +pandora.hardfile_path=/storage/.config/amiberry/ +pandora.floppy_path=/storage/.config/amiberry/disks/ +pandora.rom_path=/storage/.config/amiberry/kickstarts/ +amiberry.rom_path=/storage/.config/amiberry/kickstarts/ +amiberry.floppy_path=/storage/.config/amiberry/disks/ +amiberry.hardfile_path=/storage/.config/amiberry/ +amiberry.cd_path=/storage/.config/amiberry/cd32/ +; +; +config_path=/storage/.config/amiberry/conf +controllers_path=/usr/config/SDL-GameControllerDB +retroarch_config=/storage/.config/retroarch/retroarch.cfg +; +; *** Controller/Input Configuration +; +joyport0=mouse +joyport0_autofire=none +joyport0_friendlyname=Mouse +joyport0_name=MOUSE0 +; +joyport1=joy0 +joyport1_autofire=normal +joyport1_friendlyname=Retrogame Joypad +joyport1_name=JOY0 +; +; +joyport1_amiberry_custom_none_a=Joy1 Fire/Mouse1 Left Button +joyport1_amiberry_custom_none_b=Swap joystick ports +joyport1_amiberry_custom_none_x=Joy1 2nd Button/Mouse1 Right Button +joyport1_amiberry_custom_none_y=Toggle Virtual Keyboard +joyport1_amiberry_custom_none_start=Pause emulation +joyport1_amiberry_custom_none_leftshoulder=Quick restore state +joyport1_amiberry_custom_none_rightshoulder=Quick save state +joyport1_amiberry_custom_none_dpup=Joy1 Up +joyport1_amiberry_custom_none_dpdown=Joy2 Down +joyport1_amiberry_custom_none_dpleft=Joy2 Left +joyport1_amiberry_custom_none_dpright=Joy2 Right +joyport1_amiberry_custom_axis_none_leftx=Joy1 Horizontal +joyport1_amiberry_custom_axis_none_lefty=Joy1 Vertical +joyport1_amiberry_custom_axis_none_rightx=Mouse1 Horizontal +joyport1_amiberry_custom_axis_none_righty=Mouse1 Vertical +; +; +input.joymouse_speed_analog=2 +input.joymouse_speed_digital=10 +input.joymouse_deadzone=33 +input.joystick_deadzone=33 +input.analog_joystick_multiplier=15 +input.analog_joystick_offset=-1 +input.mouse_speed=100 +input.autofire_speed=2496 +kbd_lang=us +; +; *** Host-Specific +; +amiberry.vertical_offset=0 +amiberry.hide_idle_led=0 +amiberry.gfx_correct_aspect=1 +amiberry.kbd_led_num=-1 +amiberry.kbd_led_scr=-1 +amiberry.scaling_method=-1 +amiberry.use_analogue_remap=false +amiberry.use_retroarch_quit=true +amiberry.use_retroarch_menu=true +amiberry.use_retroarch_reset=false +default_retroarch_vkbd=yes +default_vkbd_exit=yes +default_vkbd_hires=yes +default_vkbd_enabled=yes +vkbd_style=Original +vkbd_language=US +vkbd_transparency=0 +vkbd_exit=true +vkbd_hires=true +amiberry.use_retroarch_vkbd=true +amiberry.vkbd_enabled=true +amiberry.vkbd_hires=true +amiberry.vkbd_exit=true +; +; *** Common / Paths +; +use_gui=no +kickstart_rom_file=@BIOS_PATH@/kick40068.A1200.rom +kickstart_ext_rom_file= +ide_mb_rom_file=:ENABLED +flash_file= +cart_file= +; +; *** Floppy Drives +; +;floppy0= +;floppy1= +;floppy2= +;floppy3= +nr_floppies=4 +floppy_speed=100 +; +; *** Hard Drives +; +; +; *** CD / CD32 +; +cd_speed=100 +; +; *** Display / Screen Setup +; +gfx_framerate=0 +gfx_width=NULL +gfx_height=NULL +gfx_refreshrate=50 +gfx_refreshrate_rtg=50 +gfx_lores=false +gfx_resolution=hires +gfx_linemode=none +gfx_fullscreen_amiga=false +gfx_fullscreen_picasso=false +ntsc=false +; +; *** CPU options +; +cpu_speed=real +cpu_type=68000 +cpu_model=68000 +cpu_compatible=false +cpu_24bit_addressing=true +fpu_strict=false +compfpu=true +cachesize=8192 +; +; *** Memory +; +chipmem_size=2 +z3mapping=real +fastmem_size=0 +a3000mem_size=0 +mbresmem_size=0 +z3mem_size=0 +z3mem_start=0x40000000 +bogomem_size=0 +rtg_modes=0x502 +; +; *** Chipset +; +chipset=ecs +chipset_refreshrate=50.000000 +collision_level=playfields +chipset_compatible=Generic +rtc=MSM6242B +immediate_blits=false +fast_copper=true +; +; *** Sound Options +; +sound_output=exact +sound_channels=stereo +sound_stereo_separation=7 +sound_stereo_mixing_delay=0 +sound_frequency=44100 +sound_interpol=none +sound_filter=off +sound_filter_type=standard +sound_volume_cd=20 +; +; *** Misc. Options +; +bsdsocket_emu=false diff --git a/projects/ArchR/packages/emulators/standalone/amiberry/config/conf/AmigaA500-default.uae b/projects/ArchR/packages/emulators/standalone/amiberry/config/conf/AmigaA500-default.uae new file mode 100644 index 0000000000..19f33cefe7 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/amiberry/config/conf/AmigaA500-default.uae @@ -0,0 +1,197 @@ +config_description=UAE Amiga 500 default configuration +config_hardware=true +config_host=true +config_version=3.6.0 +rtg_nocustom=true +a1000ram=false +synchronize_clock=yes +sound_auto=yes +pandora.jump=-1 +pandora.autofire_button=3 +pandora.button2=1 +pandora.button1=2 +pandora.move_y=0 +pandora.move_x=0 +pandora.custom_r=0 +pandora.custom_l=0 +pandora.custom_y=0 +pandora.custom_x=0 +pandora.custom_b=0 +pandora.custom_a=0 +pandora.custom_right=0 +pandora.custom_left=0 +pandora.custom_down=0 +pandora.custom_up=0 +pandora.custom_dpad=0 +pandora.custom_controls=0 +pandora.tap_delay=10 +pandora.stylus_offset=0 +pandora.joy_port=0 +pandora.joy_conf=0 +pandora.cpu_speed=600 +pandora.hardfile_path=/storage/.config/amiberry/ +pandora.floppy_path=/storage/.config/amiberry/disks/ +pandora.rom_path=/storage/.config/amiberry/kickstarts/ +amiberry.rom_path=/storage/.config/amiberry/kickstarts/ +amiberry.floppy_path=/storage/.config/amiberry/disks/ +amiberry.hardfile_path=/storage/.config/amiberry/ +amiberry.cd_path=/storage/.config/amiberry/cd32/ +; +; +config_path=/storage/.config/amiberry/conf +controllers_path=/usr/config/SDL-GameControllerDB +retroarch_config=/storage/.config/retroarch/retroarch.cfg +; +; *** Controller/Input Configuration +; +joyport0=mouse +joyport0_autofire=none +joyport0_friendlyname=Mouse +joyport0_name=MOUSE0 +; +joyport1=joy0 +joyport1_autofire=normal +joyport1_friendlyname=Retrogame Joypad +joyport1_name=JOY0 +; +; +joyport1_amiberry_custom_none_a=Joy1 Fire/Mouse1 Left Button +joyport1_amiberry_custom_none_b=Swap joystick ports +joyport1_amiberry_custom_none_x=Joy1 2nd Button/Mouse1 Right Button +joyport1_amiberry_custom_none_y=Toggle Virtual Keyboard +joyport1_amiberry_custom_none_start=Pause emulation +joyport1_amiberry_custom_none_leftshoulder=Quick restore state +joyport1_amiberry_custom_none_rightshoulder=Quick save state +joyport1_amiberry_custom_none_dpup=Joy1 Up +joyport1_amiberry_custom_none_dpdown=Joy2 Down +joyport1_amiberry_custom_none_dpleft=Joy2 Left +joyport1_amiberry_custom_none_dpright=Joy2 Right +joyport1_amiberry_custom_axis_none_leftx=Joy1 Horizontal +joyport1_amiberry_custom_axis_none_lefty=Joy1 Vertical +joyport1_amiberry_custom_axis_none_rightx=Mouse1 Horizontal +joyport1_amiberry_custom_axis_none_righty=Mouse1 Vertical +; +; +input.joymouse_speed_analog=2 +input.joymouse_speed_digital=10 +input.joymouse_deadzone=33 +input.joystick_deadzone=33 +input.analog_joystick_multiplier=15 +input.analog_joystick_offset=-1 +input.mouse_speed=100 +input.autofire_speed=2496 +kbd_lang=us +; +; *** Host-Specific +; +amiberry.vertical_offset=0 +amiberry.hide_idle_led=0 +amiberry.gfx_correct_aspect=1 +amiberry.kbd_led_num=-1 +amiberry.kbd_led_scr=-1 +amiberry.scaling_method=-1 +amiberry.use_analogue_remap=false +amiberry.use_retroarch_quit=true +amiberry.use_retroarch_menu=true +amiberry.use_retroarch_reset=false +default_retroarch_vkbd=yes +default_vkbd_exit=yes +default_vkbd_hires=yes +default_vkbd_enabled=yes +vkbd_style=Original +vkbd_language=US +vkbd_transparency=0 +vkbd_exit=true +vkbd_hires=true +amiberry.use_retroarch_vkbd=true +amiberry.vkbd_enabled=true +amiberry.vkbd_hires=true +amiberry.vkbd_exit=true +; +; *** Common / Paths +; +use_gui=no +kickstart_rom_file=@BIOS_PATH@/kick34005.A500.rom +kickstart_ext_rom_file= +ide_mb_rom_file=:ENABLED +flash_file= +cart_file= +; +; *** Floppy Drives +; +;floppy0= +;floppy1= +;floppy2= +;floppy3= +nr_floppies=4 +floppy_speed=100 +; +; *** Hard Drives +; +; +; *** CD / CD32 +; +cd_speed=100 +; +; *** Display / Screen Setup +; +gfx_framerate=0 +gfx_width=NULL +gfx_height=NULL +gfx_refreshrate=50 +gfx_refreshrate_rtg=50 +gfx_lores=false +gfx_resolution=hires +gfx_linemode=none +gfx_fullscreen_amiga=false +gfx_fullscreen_picasso=false +ntsc=false +; +; *** CPU options +; +cpu_speed=real +cpu_type=68000 +cpu_model=68000 +cpu_compatible=false +cpu_24bit_addressing=true +fpu_strict=false +compfpu=true +cachesize=8192 +; +; *** Memory +; +chipmem_size=2 +z3mapping=real +fastmem_size=0 +a3000mem_size=0 +mbresmem_size=0 +z3mem_size=0 +z3mem_start=0x40000000 +bogomem_size=0 +rtg_modes=0x502 +; +; *** Chipset +; +chipset=ecs +chipset_refreshrate=50.000000 +collision_level=playfields +chipset_compatible=Generic +rtc=MSM6242B +immediate_blits=false +fast_copper=true +; +; *** Sound Options +; +sound_output=exact +sound_channels=stereo +sound_stereo_separation=7 +sound_stereo_mixing_delay=0 +sound_frequency=44100 +sound_interpol=none +sound_filter=off +sound_filter_type=standard +sound_volume_cd=20 +; +; *** Misc. Options +; +bsdsocket_emu=false diff --git a/projects/ArchR/packages/emulators/standalone/amiberry/config/conf/adfdir.conf b/projects/ArchR/packages/emulators/standalone/amiberry/config/conf/adfdir.conf new file mode 100644 index 0000000000..9ae98c169c --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/amiberry/config/conf/adfdir.conf @@ -0,0 +1,35 @@ +path=/storage/roms/amiga/ +config_path=/storage/.config/amiberry/conf/ +controllers_path=/storage/.config/amiberry/controller/ +retroarch_config=/storage/.config/retroarch/retroarch.cfg +rom_path=/storage/.config/amiberry/kickstarts/ +ROMs=6 +ROMName=KS ROM v1.2 (A500,A1000,A2000) rev 33.180 (256k) [315093-01] +ROMPath=/storage/.config/amiberry/kickstarts/kick33180.A500.rom +ROMType=256 +ROMName=KS ROM v1.3 (A500,A1000,A2000) rev 34.5 (256k) [315093-02] +ROMPath=/storage/.config/amiberry/kickstarts/kick34005.A500.rom +ROMType=256 +ROMName=KS ROM v2.04 (A500+) rev 37.175 (512k) [390979-01] +ROMPath=/storage/.config/amiberry/kickstarts/kick37175.A500.rom +ROMType=256 +ROMName=KS ROM v3.0 (A1200) rev 39.106 (512k) [391523-01/391524-01] +ROMPath=/storage/.config/amiberry/kickstarts/kick39106.A1200.rom +ROMType=256 +ROMName=KS ROM v3.1 (A1200) rev 40.68 (512k) [391773-01/391774-01] +ROMPath=/storage/.config/amiberry/kickstarts/kick40068.A1200.rom +ROMType=256 +ROMName=KS ROM v3.1 (A4000) rev 40.68 (512k) +ROMPath=/storage/.config/amiberry/kickstarts/kick40068.A4000.rom +ROMType=256 +MRUDiskList=1 +Diskfile= +MRUCDList=0 +Quickstart=1 +read_config_descriptions=yes +swap_win_alt_keys=no +gui_joystick_control=yes +use_sdl2_render_thread=no +input_default_mouse_speed=100 +input_keyboard_as_joystick_stop_keypresses=no +default_open_gui_key=F12 diff --git a/projects/ArchR/packages/emulators/standalone/amiberry/package.mk b/projects/ArchR/packages/emulators/standalone/amiberry/package.mk new file mode 100644 index 0000000000..45927036b4 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/amiberry/package.mk @@ -0,0 +1,54 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2018-present Frank Hartung (supervisedthinking (@) gmail.com) + +PKG_NAME="amiberry" +PKG_ARCH="aarch64" +PKG_VERSION="5c54536997c0039aaa72bb0552cefdc3c967ad8d" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/midwan/amiberry" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain linux glibc bzip2 zlib SDL2 SDL2_image SDL2_ttf capsimg freetype libxml2 flac libogg mpg123 libpng libmpeg2 libserialport" +PKG_LONGDESC="Amiberry is an optimized Amiga emulator for ARM-based boards." +GET_HANDLER_SUPPORT="git" +PKG_TOOLCHAIN="make" +PKG_GIT_CLONE_BRANCH="master" +PKG_PATCH_DIRS+=" ${DEVICE}" + +if [ ! "${OPENGL}" = "no" ]; then + PKG_PATCH_DIRS+=" opengl" +fi + +pre_configure_target() { + export LDFLAGS="${LDFLAGS} -logg" + + cd ${PKG_BUILD} + export SYSROOT_PREFIX=${SYSROOT_PREFIX} + AMIBERRY_PLATFORM="PLATFORM=${DEVICE}" + + sed -i "s|AS = as|AS \?= as|" Makefile + PKG_MAKE_OPTS_TARGET+="${AMIBERRY_PLATFORM} all SDL_CONFIG=${SYSROOT_PREFIX}/usr/bin/sdl2-config" +} + +makeinstall_target() { + # Create directories + mkdir -p ${INSTALL}/usr/bin + mkdir -p ${INSTALL}/usr/lib + mkdir -p ${INSTALL}/usr/config/amiberry + # mkdir -p ${INSTALL}/usr/config/amiberry/controller + + # Copy ressources + cp -ra ${PKG_DIR}/config/* ${INSTALL}/usr/config/amiberry/ + cp -a data ${INSTALL}/usr/config/amiberry/ + cp -a savestates ${INSTALL}/usr/config/amiberry/ + cp -a screenshots ${INSTALL}/usr/config/amiberry/ + cp -a whdboot ${INSTALL}/usr/config/amiberry/ + ln -s /storage/roms/bios ${INSTALL}/usr/config/amiberry/kickstarts + + # Create links to Retroarch controller files + ln -s "/usr/share/libretro/autoconfig" "${INSTALL}/usr/config/amiberry/controller" + + # Copy binary, scripts & link libcapsimg + cp -a amiberry* ${INSTALL}/usr/bin/amiberry + cp -a ${PKG_DIR}/scripts/* ${INSTALL}/usr/bin + ln -sf /usr/lib/libcapsimage.so.5.1 ${INSTALL}/usr/config/amiberry/capsimg.so +} diff --git a/projects/ArchR/packages/emulators/standalone/amiberry/patches/01-platform.patch b/projects/ArchR/packages/emulators/standalone/amiberry/patches/01-platform.patch new file mode 100644 index 0000000000..a10f040c4a --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/amiberry/patches/01-platform.patch @@ -0,0 +1,52 @@ +diff -rupN amiberry.orig/Makefile amiberry/Makefile +--- amiberry/Makefile 2022-04-16 16:23:12.481980516 -0400 ++++ amiberry/Makefile 2022-04-16 23:36:53.638425501 -0400 +@@ -43,10 +43,10 @@ + export SDL_CFLAGS := $(shell $(SDL_CONFIG) --cflags) + export SDL_LDFLAGS := $(shell $(SDL_CONFIG) --libs) + +-CPPFLAGS = -MD -MT $@ -MF $(@:%.o=%.d) $(SDL_CFLAGS) -Iexternal/libguisan/include -Isrc -Isrc/osdep -Isrc/threaddep -Isrc/include -Isrc/archivers -Isrc/floppybridge -DAMIBERRY -D_FILE_OFFSET_BITS=64 ++CPPFLAGS = $(CXXFLAGS) -MD -MT $@ -MF $(@:%.o=%.d) $(SDL_CFLAGS) -Iexternal/libguisan/include -Isrc -Isrc/osdep -Isrc/threaddep -Isrc/include -Isrc/archivers -Isrc/floppybridge -DAMIBERRY -D_FILE_OFFSET_BITS=64 +-CFLAGS=-pipe -Wno-shift-overflow -Wno-narrowing ++CFLAGS += -pipe -Wno-shift-overflow -Wno-narrowing + USE_LD ?= gold +-LDFLAGS = $(SDL_LDFLAGS) -lSDL2_image -lSDL2_ttf -lserialport -lguisan -Lexternal/libguisan/lib ++LDFLAGS += $(SDL_LDFLAGS) -lSDL2_image -lSDL2_ttf -lserialport -lguisan -Lexternal/libguisan/lib + ifneq ($(strip $(USE_LD)),) + LDFLAGS += -fuse-ld=$(USE_LD) + endif +@@ -228,30 +228,12 @@ else ifeq ($(PLATFORM),a64) + else ifeq ($(PLATFORM),x86-64) + CPPFLAGS += -DUSE_RENDER_THREAD + +-# RK3288 e.g. Asus Tinker Board +-# RK3328 e.g. PINE64 Rock64 +-# RK3399 e.g. PINE64 RockPro64 +-# RK3326 e.g. Odroid Go Advance - 32-bit userspace +-else ifneq (,$(findstring RK,$(PLATFORM))) +- CPPFLAGS += $(CPPFLAGS32) $(NEON_FLAGS) ++# @DEVICE@ ++else ifeq ($(PLATFORM),@DEVICE@) ++ CPPFLAGS += $(CPPFLAGS64) -O3 -ffast-math -DUSE_RENDER_THREAD ++ AARCH64 = 1 + HAVE_NEON = 1 + +- ifneq (,$(findstring RK33,$(PLATFORM))) +- CPUFLAGS = -mfloat-abi=hard -mfpu=neon-fp-armv8 +- ifneq (,$(findstring RK3399,$(PLATFORM))) +- CPUFLAGS += -mcpu=cortex-a72 +- else ifneq (,$(findstring RK3328,$(PLATFORM))) +- CPUFLAGS += -mcpu=cortex-a53 +- CPPFLAGS += -DUSE_RENDER_THREAD +- else ifneq (,$(findstring RK3326,$(PLATFORM))) +- CPUFLAGS += -mcpu=cortex-a35 +- CPPFLAGS += -DUSE_RENDER_THREAD +- endif +- else ifneq (,$(findstring RK3288,$(PLATFORM))) +- CPUFLAGS = -mcpu=cortex-a17 -mfloat-abi=hard -mfpu=neon-vfpv4 +- CPPFLAGS += -DUSE_RENDER_THREAD +- endif +- + # sun8i Allwinner H2+ / H3 like Orange PI, Nano PI, Banana PI, Tritium, AlphaCore2, MPCORE-HUB + else ifeq ($(PLATFORM),sun8i) + CPUFLAGS = -mcpu=cortex-a7 -mfpu=neon-vfpv4 diff --git a/projects/ArchR/packages/emulators/standalone/amiberry/patches/02-fix-building-with-gcc15.patch b/projects/ArchR/packages/emulators/standalone/amiberry/patches/02-fix-building-with-gcc15.patch new file mode 100644 index 0000000000..4ccf4cc912 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/amiberry/patches/02-fix-building-with-gcc15.patch @@ -0,0 +1,11 @@ +--- a/src/archivers/chd/corestr.cpp ++++ b/src/archivers/chd/corestr.cpp +@@ -16,7 +16,7 @@ + + #include + #include +- ++#include + + /*------------------------------------------------- + core_stricmp - case-insensitive string compare diff --git a/projects/ArchR/packages/emulators/standalone/amiberry/patches/opengl/001-fix-sdl.patch b/projects/ArchR/packages/emulators/standalone/amiberry/patches/opengl/001-fix-sdl.patch new file mode 100644 index 0000000000..61b4f77186 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/amiberry/patches/opengl/001-fix-sdl.patch @@ -0,0 +1,20 @@ +diff --git a/src/osdep/amiberry.cpp b/src/osdep/amiberry.cpp +index 13237df9..95e6b04e 100644 +--- a/src/osdep/amiberry.cpp ++++ b/src/osdep/amiberry.cpp +@@ -3691,12 +3691,9 @@ int main(int argc, char* argv[]) + write_log("SDL could not initialize! SDL_Error: %s\n", SDL_GetError()); + abort(); + } +-#ifdef USE_OPENGL +- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); +- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); +- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); +- //SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); +-#endif ++ ++ SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); ++ + atexit(SDL_Quit); + write_log(_T("Sorting devices and modes...\n")); + sortdisplays(); diff --git a/projects/ArchR/packages/emulators/standalone/amiberry/scripts/start_amiberry.sh b/projects/ArchR/packages/emulators/standalone/amiberry/scripts/start_amiberry.sh new file mode 100755 index 0000000000..8fcf03e702 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/amiberry/scripts/start_amiberry.sh @@ -0,0 +1,159 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 0riginally created by Escalade (https://github.com/escalade) +# Copyright (C) 2018-present 5schatten (https://github.com/5schatten) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +set_kill set "-9 amiberry" + +# Set some common variables +AMIBERRY_DIR="/storage/.config/amiberry" +AMIBERRY_CONFIG_DIR="${AMIBERRY_DIR}/conf" +AMIBERRY_TMP_DIR="/tmp/emulation/amiberry" +AMIBERRY_TMP_CONFIG="${AMIBERRY_TMP_DIR}/.amiberry_conf.uae" +AMIBERRY_LOG="/var/log/amiberry.log" +BIOS_PATH="/storage/roms/bios" +MAX_DRIVES=4 +i=0 + +echo "Amiberry Log" > "${AMIBERRY_LOG}" + +if [ ! -d "${AMIBERRY_TMP_DIR}" ] +then + mkdir -p "${AMIBERRY_TMP_DIR}" +fi + +if [ ! -d "${AMIBERRY_DIR}" ] +then + cp -rf /usr/config/amiberry ${AMIBERRY_DIR} +fi + +### Refresh the configs so we can manage them. +cp -f /usr/config/amiberry/conf/* ${AMIBERRY_DIR}/conf + +find_gamepad() { + # Check for js0 first, else fall back to joypad + if grep -q "js0" /proc/bus/input/devices; then + GAMEPAD=$(grep -b4 js0 /proc/bus/input/devices | awk 'BEGIN {FS="\""}; /Name/ {printf $2}') + else + GAMEPAD=$(grep -b4 joypad /proc/bus/input/devices | awk 'BEGIN {FS="\""}; /Name/ {printf $2}') + fi + sed -i "s|joyport1_friendlyname=.*|joyport1_friendlyname=${GAMEPAD}|" "${AMIBERRY_TMP_CONFIG}" + echo "Gamepad used ${GAMEPAD}" >> "${AMIBERRY_LOG}" +} + +# Which file should amiberry load? +echo "Trying to boot this game:" "$1" >> ${AMIBERRY_LOG} + +# Change working directory cause amiberry loads assets from there +cd ${AMIBERRY_DIR} + +# Create a clean working directory +if [ -d "${AMIBERRY_TMP_DIR}" ]; then + echo "Clean up old working directory." >> ${AMIBERRY_LOG} + rm -rf "${AMIBERRY_TMP_DIR}" +fi +mkdir -p "${AMIBERRY_TMP_DIR}" + +# Check if the file is an Amiga 1200/CD32 game and set configuration options for an Amiga 1200 +AMIBERRY_SET_CONF() { + if [ `echo $1 | grep -E 'AGA|CD32' | wc -l` -eq 1 -o `echo "${AMIBERRY_TMP_DIR}"/* | grep -e 'AGA|CD32' | wc -l` -eq 1 ]; then + echo "Loading Amiga 1200/CD32 config." >> ${AMIBERRY_LOG} + cp ${AMIBERRY_CONFIG_DIR}/AmigaA1200-default.uae "${AMIBERRY_TMP_CONFIG}" + else + echo "Loading Amiga 500 config." >> ${AMIBERRY_LOG} + cp ${AMIBERRY_CONFIG_DIR}/AmigaA500-default.uae "${AMIBERRY_TMP_CONFIG}" + fi + sed -i "s#@BIOS_PATH@#${BIOS_PATH}#g" ${AMIBERRY_TMP_CONFIG} + sed -i "s#gfx_width=.*\$#$(fbwidth)#g" ${AMIBERRY_TMP_CONFIG} + sed -i "s#gfx_height=.*\$#$(fbheight)#g" ${AMIBERRY_TMP_CONFIG} + find_gamepad +} + +# Check if we are loading a .zip file +if [ `echo $1 | grep -i .zip | wc -l` -eq 1 ]; then + + # Unpack the zip file + unzip -q -o "$1" -d "${AMIBERRY_TMP_DIR}" + + if [ -f "${AMIBERRY_TMP_DIR}"/*.*nfo ] && [ -f "${AMIBERRY_TMP_DIR}"/*/*.*lave ]; then + + # WHDLoad file detected + echo "Loading a WHDLoad (.zip) file..." >> ${AMIBERRY_LOG} + + # Set default config + AMIBERRY_SET_CONF "$1" + + # Add amiberry.uae conf & start amiberry with WHDLoad + amiberry -f "${AMIBERRY_TMP_CONFIG}" --autoload "$1" >> ${AMIBERRY_LOG} 2>&1 + + else + # .zip file detected + echo "Loading a .zip file..." >> ${AMIBERRY_LOG} + + # Set default config + AMIBERRY_SET_CONF "$1" + + # Assign files to floppy0-3 + for FILE in "${AMIBERRY_TMP_DIR}"/* + do + ARGS="${ARGS}\nfloppy$i="${FILE}"" + i=$(($i+1)) + # This emulator supports 4 floppies max + if [ $i -eq ${MAX_DRIVES} ]; then + break; + fi + done + + # Add game files as floppies 0-3 to amiberry.uae & start amiberry + echo -e ";" >> "${AMIBERRY_TMP_CONFIG}" + echo -e "; *** temporary added Floppy Drives" >> "${AMIBERRY_TMP_CONFIG}" + echo -e ";" >> "${AMIBERRY_TMP_CONFIG}" + echo -e ${ARGS} >> "${AMIBERRY_TMP_CONFIG}" + echo -e "\nAssigned floppy drives:" ${ARGS} "\n" >> "${AMIBERRY_LOG}" + amiberry -f "${AMIBERRY_TMP_CONFIG}" >> ${AMIBERRY_LOG} 2>&1 + fi + +# Check for WHDload files (.lha) +elif [ `echo $1 | grep -i .lha | wc -l` -eq 1 ]; then + + #.lha file detected + echo "Loading a WHDLoad (.lha) file..." >> ${AMIBERRY_LOG} + + # Set default config + AMIBERRY_SET_CONF "$1" + + # Add amiberry.uae conf & start amiberry with WHDLoad + amiberry -f "${AMIBERRY_TMP_CONFIG}" --autoload "$1" >> ${AMIBERRY_LOG} 2>&1 + +# Check for .uae config file +elif [ `echo $1 | grep -i .uae | wc -l` -eq 1 ]; then + + # .uae file detected + echo "Loading an .uae file..." >> ${AMIBERRY_LOG} + + # Load .uae config file + amiberry -f "$1" >> ${AMIBERRY_LOG} 2>&1 + +# All other files (.adf .adz .ipf) +else + + #.adf or .adz or .ipf file detected + echo "Loading a single .adf or .adz or .ipf file..." >> ${AMIBERRY_LOG} + + # Set default config + AMIBERRY_SET_CONF "$1" + + # Add game file as floppy0 to amiberry.uae & start amiberry + echo -e ";" >> "${AMIBERRY_TMP_CONFIG}" + echo -e "; *** temporary added Floppy Drives" >> "${AMIBERRY_TMP_CONFIG}" + echo -e ";" >> "${AMIBERRY_TMP_CONFIG}" + echo -e "\nfloppy0=$1" >> "${AMIBERRY_TMP_CONFIG}" + echo -e "\nAssigned floppy drive:\nfloppy0=$1\n" >> "${AMIBERRY_LOG}" + amiberry -f "${AMIBERRY_TMP_CONFIG}" >> ${AMIBERRY_LOG} 2>&1 +fi + +# Remove temporary dir +rm -rf "${AMIBERRY_TMP_DIR}" diff --git a/projects/ArchR/packages/emulators/standalone/daedalusx64-sa/config/Preferences.ini b/projects/ArchR/packages/emulators/standalone/daedalusx64-sa/config/Preferences.ini new file mode 100644 index 0000000000..f8b5ad6f89 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/daedalusx64-sa/config/Preferences.ini @@ -0,0 +1,13 @@ +DisplayFramerate=no +ForceLinearFilter=no +RumblePak=no +BatteryWarning=no +LargeROMBuffer=yes +GuiColor=0 +StickMinDeadzone=0.280000 +StickMaxDeadzone=1.000000 +Language=English +ViewportType=2 +TVEnable=no +TVLaced=no +TVType=0 diff --git a/projects/ArchR/packages/emulators/standalone/daedalusx64-sa/package.mk b/projects/ArchR/packages/emulators/standalone/daedalusx64-sa/package.mk new file mode 100644 index 0000000000..168d854e7e --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/daedalusx64-sa/package.mk @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2025-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="daedalusx64-sa" +PKG_VERSION="f17e9ed86f3806fadeb69abd29c9526ab2d4bd1b" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/DaedalusX64/daedalus" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain libfmt SDL2 SDL2_ttf glew mesa glm" +PKG_LONGDESC="DaedalusX64 is a Nintendo 64 emulator for PSP, 3DS, Vita, Linux, macOS and Windows" +PKG_PATCH_DIRS+="${DEVICE}" + +if [ "${ARCH}" = "aarch64" ]; then + PKG_TOOLCHAIN="manual" +else + PKG_TOOLCHAIN="cmake" +fi + +if [ "${OPENGL_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL}" +elif [ "${OPENGLES_SUPPORT}" = yes ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" +fi + +makeinstall_target() { + if [ "${ARCH}" = "aarch64" ] + then + mkdir -p ${INSTALL}/usr + cp -r ${ROOT}/build.${DISTRO}-${DEVICE}.arm/install_pkg/daedalusx64-sa-${PKG_VERSION}/usr/* ${INSTALL}/usr/ + chmod +x ${INSTALL}/usr/bin/* + else + mkdir -p ${INSTALL}/usr/bin + mkdir -p ${INSTALL}/usr/config/DaedalusX64 + cp ${PKG_BUILD}/.${TARGET_NAME}/Source/daedalus ${INSTALL}/usr/config/DaedalusX64/daedalus + cp ${PKG_DIR}/scripts/* ${INSTALL}/usr/bin + cp ${PKG_DIR}/config/* ${INSTALL}/usr/config/DaedalusX64 + cp -r ${PKG_BUILD}/Data/* ${INSTALL}/usr/config/DaedalusX64 + cp -r ${PKG_BUILD}/Source/SysGL/HLEGraphics/n64.psh ${INSTALL}/usr/config/DaedalusX64 + chmod +x ${INSTALL}/usr/bin/* + fi +} diff --git a/projects/ArchR/packages/emulators/standalone/daedalusx64-sa/patches/000-input.patch b/projects/ArchR/packages/emulators/standalone/daedalusx64-sa/patches/000-input.patch new file mode 100644 index 0000000000..e4d59f795e --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/daedalusx64-sa/patches/000-input.patch @@ -0,0 +1,151 @@ +diff --git a/Source/Input/SDL/InputManagerSDL.cpp b/Source/Input/SDL/InputManagerSDL.cpp +index 1ffd1741..358f2e49 100644 +--- a/Source/Input/SDL/InputManagerSDL.cpp ++++ b/Source/Input/SDL/InputManagerSDL.cpp +@@ -131,66 +131,96 @@ void IInputManager::GetJoyPad(OSContPad *pPad) + + //ToDo: Different gamepads will need different configuration, this is for PS3/PS2 controller + if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_START)) pPad->button |= START_BUTTON; +- if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_A)) pPad->button |= A_BUTTON; +- if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_B)) pPad->button |= B_BUTTON; +- if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_LEFTSHOULDER)) pPad->button |= Z_TRIG; +- if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER)) pPad->button |= Z_TRIG; +- if (SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_TRIGGERLEFT) > 16383) pPad->button |= L_TRIG; +- if (SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_TRIGGERRIGHT) > 16383) pPad->button |= R_TRIG; ++ if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_B)) pPad->button |= A_BUTTON; ++ if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_Y)) pPad->button |= B_BUTTON; ++ if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_LEFTSHOULDER)) pPad->button |= L_TRIG; ++ if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER)) pPad->button |= R_TRIG; ++ if (SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_TRIGGERLEFT) > 16383) pPad->button |= Z_TRIG; ++ if (SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_TRIGGERRIGHT) > 16383) pPad->button |= Z_TRIG; + + if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_UP)) pPad->button |= U_JPAD; + if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_DOWN)) pPad->button |= D_JPAD; + if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_LEFT)) pPad->button |= L_JPAD; + if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_RIGHT)) pPad->button |= R_JPAD; + +- // Hold O button and use hat buttons for N64 c buttons (same as the PSP) +- // We could use the second analog stick to map them, but will require to translate asix >=2 +- if(SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_X)) +- { +- if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_UP)) pPad->button |= U_CBUTTONS; +- if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_DOWN)) pPad->button |= D_CBUTTONS; +- if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_LEFT)) pPad->button |= L_CBUTTONS; +- if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_RIGHT)) pPad->button |= R_CBUTTONS; +- } +- +- // Used to see key presses, useful to add a different button configuration +- //for(int i = 0; i < num_buttons; i++) +- //{ +- // if(buttons[i]) +- // printf("%d\n",i); +- //} ++ if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_X)) pPad->button |= U_CBUTTONS; ++ if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_A)) pPad->button |= R_CBUTTONS; + ++ // Axis values for the first joystick (Left Stick - Joystick 1) + const s32 SDL_AXIS_MIN = -32768; + const s32 SDL_AXIS_MAX = 32767; + +- // Get the raw axis values +- s32 raw_x = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTX); +- s32 raw_y = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTY); ++ // Get the raw axis values for Left Stick (Joystick 1) ++ s32 raw_x_joystick1 = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTX); ++ s32 raw_y_joystick1 = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTY); + + // Normalize the axis values to the range [-1, 1] +- float normalized_x = raw_x / 32767.0f; +- float normalized_y = raw_y / 32767.0f; +- +- // Scale the normalized values to the N64 range +- s8 scaled_x = static_cast(normalized_x * N64_ANALOGUE_STICK_RANGE); +- s8 scaled_y = static_cast(normalized_y * N64_ANALOGUE_STICK_RANGE); +- +- // Manually clamp the values to ensure they are within the valid range +- if (scaled_x > N64_ANALOGUE_STICK_RANGE) { +- scaled_x = N64_ANALOGUE_STICK_RANGE; +- } else if (scaled_x < -N64_ANALOGUE_STICK_RANGE) { +- scaled_x = -N64_ANALOGUE_STICK_RANGE; ++ float normalized_x_joystick1 = raw_x_joystick1 / 32767.0f; ++ float normalized_y_joystick1 = raw_y_joystick1 / 32767.0f; ++ ++ // Scale the normalized values to the N64 range for Joystick 1 ++ s8 scaled_x_joystick1 = static_cast(normalized_x_joystick1 * N64_ANALOGUE_STICK_RANGE); ++ s8 scaled_y_joystick1 = static_cast(normalized_y_joystick1 * N64_ANALOGUE_STICK_RANGE); ++ ++ // Manually clamp the values to ensure they are within the valid range for N64 Joystick 1 ++ if (scaled_x_joystick1 > N64_ANALOGUE_STICK_RANGE) { ++ scaled_x_joystick1 = N64_ANALOGUE_STICK_RANGE; ++ } else if (scaled_x_joystick1 < -N64_ANALOGUE_STICK_RANGE) { ++ scaled_x_joystick1 = -N64_ANALOGUE_STICK_RANGE; + } + +- if (scaled_y > N64_ANALOGUE_STICK_RANGE) { +- scaled_y = N64_ANALOGUE_STICK_RANGE; +- } else if (scaled_y < -N64_ANALOGUE_STICK_RANGE) { +- scaled_y = -N64_ANALOGUE_STICK_RANGE; ++ if (scaled_y_joystick1 > N64_ANALOGUE_STICK_RANGE) { ++ scaled_y_joystick1 = N64_ANALOGUE_STICK_RANGE; ++ } else if (scaled_y_joystick1 < -N64_ANALOGUE_STICK_RANGE) { ++ scaled_y_joystick1 = -N64_ANALOGUE_STICK_RANGE; ++ } ++ ++ // Assign the left joystick values to N64 joystick analog stick ++ pPad->stick_x = scaled_x_joystick1; ++ pPad->stick_y = -1 * scaled_y_joystick1; ++ ++ // C buttons are controlled by the Right Stick (Joystick 2) ++ s32 raw_x_joystick2 = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_RIGHTX); ++ s32 raw_y_joystick2 = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_RIGHTY); ++ ++ // Normalize the axis values for Joystick 2 to the range [-1, 1] (Right Stick for C Buttons) ++ float normalized_x_joystick2 = raw_x_joystick2 / 32767.0f; ++ float normalized_y_joystick2 = raw_y_joystick2 / 32767.0f; ++ ++ // Scale the normalized values for C button range ++ s8 scaled_x_joystick2 = static_cast(normalized_x_joystick2 * N64_ANALOGUE_STICK_RANGE); ++ s8 scaled_y_joystick2 = static_cast(normalized_y_joystick2 * N64_ANALOGUE_STICK_RANGE); ++ ++ // Manually clamp the values for C buttons ++ if (scaled_x_joystick2 > N64_ANALOGUE_STICK_RANGE) { ++ scaled_x_joystick2 = N64_ANALOGUE_STICK_RANGE; ++ } else if (scaled_x_joystick2 < -N64_ANALOGUE_STICK_RANGE) { ++ scaled_x_joystick2 = -N64_ANALOGUE_STICK_RANGE; + } + +- pPad->stick_x = scaled_x; +- pPad->stick_y = -1 * scaled_y; ++ if (scaled_y_joystick2 > N64_ANALOGUE_STICK_RANGE) { ++ scaled_y_joystick2 = N64_ANALOGUE_STICK_RANGE; ++ } else if (scaled_y_joystick2 < -N64_ANALOGUE_STICK_RANGE) { ++ scaled_y_joystick2 = -N64_ANALOGUE_STICK_RANGE; ++ } + ++ // Use the values from the second joystick for C buttons ++ // Check for the dominant axis to avoid diagonal triggering both buttons ++ if (abs(scaled_x_joystick2) > abs(scaled_y_joystick2)) { ++ // Horizontal C buttons (left/right) ++ if (scaled_x_joystick2 > 20) { // Right movement ++ pPad->button |= R_CBUTTONS; ++ } else if (scaled_x_joystick2 < -20) { // Left movement ++ pPad->button |= L_CBUTTONS; ++ } ++ } else { ++ // Vertical C buttons (up/down) ++ if (scaled_y_joystick2 > 20) { // Up movement ++ pPad->button |= U_CBUTTONS; ++ } else if (scaled_y_joystick2 < -20) { // Down movement ++ pPad->button |= D_CBUTTONS; ++ } ++ } + } + + void IInputManager::GetState( OSContPad pPad[4] ) +@@ -449,4 +479,4 @@ glm::vec2 ApplyDeadzone( const glm::vec2 & in, f32 min_deadzone, f32 max_deadzon + scale = std::clamp( scale, 0.0f, 1.0f ); + + return ProjectToUnitSquare( in * (scale / length) ); +-} +\ No newline at end of file ++} diff --git a/projects/ArchR/packages/emulators/standalone/daedalusx64-sa/scripts/start_daedalusx64.sh b/projects/ArchR/packages/emulators/standalone/daedalusx64-sa/scripts/start_daedalusx64.sh new file mode 100644 index 0000000000..6c4a2b12b6 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/daedalusx64-sa/scripts/start_daedalusx64.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2025-present ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile +set_kill set "-9 daedalus" + +#Check if DaedalusX64 exists in .config +if [ ! -d "/storage/.config/DaedalusX64" ]; then + cp -r "/usr/config/DaedalusX64" "/storage/.config/" +fi + +#Check if n64 save state folders exist +if [ ! -d "/storage/roms/savestates/n64/daedalus" ]; then + mkdir -p "/storage/roms/savestates/n64/daedalus" +fi + +# Link Roms, Saves, and SaveStates to correct dir +rm "/storage/.config/DaedalusX64/Roms" +ln -sf "/storage/roms/n64" "/storage/.config/DaedalusX64/Roms" +rm "/storage/.config/DaedalusX64/SavesGames" +ln -sf "/storage/roms/n64" "/storage/.config/DaedalusX64/SavesGames" +rm "/storage/.config/DaedalusX64/SaveStates" +ln -sf "/storage/roms/savestates/n64/daedalus" "/storage/.config/DaedalusX64/SaveStates" + +#Emulation Station Features +GAME=$(echo "${1}"| sed "s#^/.*/##") +PLATFORM=$(echo "${2}"| sed "s#^/.*/##") + +#Set the cores to use +CORES=$(get_setting "cores" "${PLATFORM}" "${GAME}") +if [ "${CORES}" = "little" ] +then + EMUPERF="${SLOW_CORES}" +elif [ "${CORES}" = "big" ] +then + EMUPERF="${FAST_CORES}" +else + ### All.. + unset EMUPERF +fi + +#Always grab the latest daedalus bin +shasum1=$(sha1sum /usr/config/DaedalusX64/daedalus | awk '{print $1}') +shasum2=$(sha1sum /storage/.config/DaedalusX64/daedalus | awk '{print $1}') + +if [ "$shasum1" <> "$shasum2" ]; then + cp -r "/usr/config/DaedalusX64/daedalus" "/storage/.config/DaedalusX64/daedalus" +fi + +cd /storage/.config/DaedalusX64/ + +${EMUPERF} /storage/.config/DaedalusX64/daedalus "${1}" diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/InputPlumber/GamecubeControllerProfiles/GCPadNew.ini.east b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/InputPlumber/GamecubeControllerProfiles/GCPadNew.ini.east new file mode 100644 index 0000000000..ef28b82a1a --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/InputPlumber/GamecubeControllerProfiles/GCPadNew.ini.east @@ -0,0 +1,36 @@ +[GCPad1] +Device = evdev/0/Microsoft X-Box 360 pad +Buttons/A = Button 0 +Buttons/B = Button 1 +Buttons/Start = Button 7 +Buttons/X = Button 3 +Buttons/Y = Button 2 +Buttons/Z = Button 5 +Buttons/Hotkey = Button 6 +C-Stick/Dead Zone = 25.000000000000000 +C-Stick/Down = Axis 4+ +C-Stick/Left = Axis 3- +C-Stick/Modifier = Control_L +C-Stick/Modifier/Range = 50.000000000000000 +C-Stick/Right = Axis 3+ +C-Stick/Up = Axis 4- +D-Pad/Down = Axis 7+ +D-Pad/Left = Axis 6- +D-Pad/Right = Axis 6+ +D-Pad/Up = Axis 7- +Main Stick/Dead Zone = 25.000000000000000 +Main Stick/Down = Axis 1+ +Main Stick/Left = Axis 0- +Main Stick/Modifier = Shift_L +Main Stick/Modifier/Range = 50.000000000000000 +Main Stick/Right = Axis 0+ +Main Stick/Up = Axis 1- +Triggers/Dead Zone = 0. +Triggers/Threshold = 90. +Triggers/L = Axis 2+ +Triggers/R = Axis 5+ +Triggers/L-Analog = Axis 2+ +Triggers/R-Analog = Axis 5+ +Rumble/Motor = `evdev/0/AYN Odin2 Gamepad:Strong` +Triforce/Coin = Button 8 +Triforce/Service = Button 4 diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/InputPlumber/GamecubeControllerProfiles/GCPadNew.ini.south b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/InputPlumber/GamecubeControllerProfiles/GCPadNew.ini.south new file mode 100644 index 0000000000..253e7b2604 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/InputPlumber/GamecubeControllerProfiles/GCPadNew.ini.south @@ -0,0 +1,36 @@ +[GCPad1] +Device = evdev/0/Microsoft X-Box 360 pad +Buttons/A = Button 1 +Buttons/B = Button 2 +Buttons/Start = Button 7 +Buttons/X = Button 0 +Buttons/Y = Button 3 +Buttons/Z = Button 5 +Buttons/Hotkey = Button 6 +C-Stick/Dead Zone = 25.000000000000000 +C-Stick/Down = Axis 4+ +C-Stick/Left = Axis 3- +C-Stick/Modifier = Control_L +C-Stick/Modifier/Range = 50.000000000000000 +C-Stick/Right = Axis 3+ +C-Stick/Up = Axis 4- +D-Pad/Down = Axis 7+ +D-Pad/Left = Axis 6- +D-Pad/Right = Axis 6+ +D-Pad/Up = Axis 7- +Main Stick/Dead Zone = 25.000000000000000 +Main Stick/Down = Axis 1+ +Main Stick/Left = Axis 0- +Main Stick/Modifier = Shift_L +Main Stick/Modifier/Range = 50.000000000000000 +Main Stick/Right = Axis 0+ +Main Stick/Up = Axis 1- +Triggers/Dead Zone = 0. +Triggers/Threshold = 90. +Triggers/L = Axis 2+ +Triggers/R = Axis 5+ +Triggers/L-Analog = Axis 2+ +Triggers/R-Analog = Axis 5+ +Rumble/Motor = `evdev/0/AYN Odin2 Gamepad:Strong` +Triforce/Coin = Button 8 +Triforce/Service = Button 4 diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/InputPlumber/Hotkeys.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/InputPlumber/Hotkeys.ini new file mode 100644 index 0000000000..838c89f486 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/InputPlumber/Hotkeys.ini @@ -0,0 +1,10 @@ +[Hotkeys] +Device = evdev/0/Microsoft X-Box 360 pad +Graphics Toggles/Toggle Aspect Ratio = @(MODE+EAST) +General/Take Screenshot = @(MODE+SOUTH) +Save State/Save to Selected Slot = @(MODE+TR) +Load State/Load State Slot 1 = @(MODE+TL) +Other State Hotkeys/Increase Selected State Slot = @(MODE+`Axis 7-`) +Other State Hotkeys/Decrease Selected State Slot = @(MODE+`Axis 7+`) +Emulation Speed/Increase Emulation Speed = @(MODE+`Full Axis 5+`) +Emulation Speed/Decrease Emulation Speed = @(MODE+`Full Axis 2+`) diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/InputPlumber/WiiControllerProfiles/classic.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/InputPlumber/WiiControllerProfiles/classic.ini new file mode 100644 index 0000000000..77f260bf57 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/InputPlumber/WiiControllerProfiles/classic.ini @@ -0,0 +1,28 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Extension = Classic +Source = 1 +Classic/Buttons/A = Button 1 +Classic/Buttons/B = Button 0 +Classic/Buttons/X = Button 2 +Classic/Buttons/Y = Button 3 +Classic/Buttons/ZL = Axis 2+ +Classic/Buttons/ZR = Axis 5+ +Classic/Buttons/- = Button 6 +Classic/Buttons/+ = Button 7 +Classic/Buttons/Home = Button 8 +Classic/Left Stick/Up = Axis 1- +Classic/Left Stick/Down = Axis 1+ +Classic/Left Stick/Left = Axis 0- +Classic/Left Stick/Right = Axis 0+ +Classic/Right Stick/Up = Axis 4- +Classic/Right Stick/Down = Axis 4+ +Classic/Right Stick/Left = Axis 3- +Classic/Right Stick/Right = Axis 3+ +Classic/Triggers/L = Button 4 +Classic/Triggers/R = Button 5 +Classic/D-Pad/Up = Axis 7- +Classic/D-Pad/Down = Axis 7+ +Classic/D-Pad/Left = Axis 6- +Classic/D-Pad/Right = Axis 6+ +Rumble/Motor = `evdev/0/AYN Odin2 Gamepad:Strong` diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/InputPlumber/WiiControllerProfiles/hremote.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/InputPlumber/WiiControllerProfiles/hremote.ini new file mode 100644 index 0000000000..a424c70bed --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/InputPlumber/WiiControllerProfiles/hremote.ini @@ -0,0 +1,21 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Buttons/A = Button 3 +Buttons/B = Button 2 +Buttons/1 = Button 0 +Buttons/2 = Button 1 +Buttons/- = Button 6 +Buttons/+ = Button 7 +Buttons/Home = Button 8 +Shake/X = Button 4 +Shake/Y = Button 4 +Shake/Z = Button 4 +D-Pad/Up = `Axis 6-` | `Axis 0-` +D-Pad/Down = `Axis 6+` | `Axis 0+` +D-Pad/Left = `Axis 7+` | `Axis 1+` +D-Pad/Right = `Axis 7-` | `Axis 1-` +IR/Up = `Axis 4-` +IR/Down = `Axis 4+` +IR/Left = `Axis 3-` +IR/Right = `Axis 3+` +Rumble/Motor = `evdev/0/AYN Odin2 Gamepad:Strong` diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/InputPlumber/WiiControllerProfiles/nunchuck.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/InputPlumber/WiiControllerProfiles/nunchuck.ini new file mode 100644 index 0000000000..da607132d5 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/InputPlumber/WiiControllerProfiles/nunchuck.ini @@ -0,0 +1,31 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Extension = Nunchuk +Buttons/A = Button 1 +Buttons/B = Button 0 +Buttons/1 = Button 3 +Buttons/2 = Button 2 +Buttons/- = Button 6 +Buttons/+ = Button 7 +D-Pad/Up = Axis 7- +D-Pad/Down = Axis 7+ +D-Pad/Left = Axis 6- +D-Pad/Right = Axis 6+ +Buttons/Home = Button 8 +Shake/X = Button 4 +Shake/Y = Button 4 +Shake/Z = Button 4 +Nunchuk/Buttons/C = Button 5 +Nunchuk/Buttons/Z = Axis 5+ +Nunchuk/Stick/Up = Axis 1- +Nunchuk/Stick/Down = Axis 1+ +Nunchuk/Stick/Left = Axis 0- +Nunchuk/Stick/Right = Axis 0+ +Nunchuk/Shake/X = Axis 2+ +Nunchuk/Shake/Y = Axis 2+ +Nunchuk/Shake/Z = Axis 2+ +IR/Up = `Axis 4-` +IR/Down = `Axis 4+` +IR/Left = `Axis 3-` +IR/Right = `Axis 3+` +Rumble/Motor = `evdev/0/AYN Odin2 Gamepad:Strong` diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/InputPlumber/WiiControllerProfiles/vremote.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/InputPlumber/WiiControllerProfiles/vremote.ini new file mode 100644 index 0000000000..5e35a10901 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/InputPlumber/WiiControllerProfiles/vremote.ini @@ -0,0 +1,21 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Buttons/A = Button 1 +Buttons/B = Button 0 +Buttons/1 = Button 3 +Buttons/2 = Button 2 +Buttons/- = Button 6 +Buttons/+ = Button 7 +Buttons/Home = Button 8 +Shake/X = Button 4 +Shake/Y = Button 4 +Shake/Z = Button 4 +D-Pad/Up = `Axis 7-` | `Axis 1-` +D-Pad/Down = `Axis 7+` | `Axis 1+` +D-Pad/Left = `Axis 6-` | `Axis 0-` +D-Pad/Right = `Axis 6+` | `Axis 0+` +IR/Up = `Axis 4-` +IR/Down = `Axis 4+` +IR/Left = `Axis 3-` +IR/Right = `Axis 3+` +Rumble/Motor = `evdev/0/AYN Odin2 Gamepad:Strong` diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3399/Dolphin.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3399/Dolphin.ini new file mode 100755 index 0000000000..887e02bd7c --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3399/Dolphin.ini @@ -0,0 +1,153 @@ +[General] +LastFilename = +ShowLag = False +ShowFrameCount = False +ISOPath0 = /storage/roms/gamecube +ISOPath1 = /storage/roms/wii +ISOPaths = 2 +RecursiveISOPaths = False +NANDRootPath = +WirelessMac = +[Interface] +ConfirmStop = True +UsePanicHandlers = True +OnScreenDisplayMessages = True +HideCursor = False +AutoHideCursor = False +MainWindowPosX = 403 +MainWindowPosY = 148 +MainWindowWidth = 800 +MainWindowHeight = 600 +Language = 0 +ShowToolbar = True +ShowStatusbar = True +ShowLogWindow = False +ShowLogConfigWindow = False +ExtendedFPSInfo = False +ThemeName40 = Clean Blue +PauseOnFocusLost = False +[Display] +FullscreenResolution = Auto +Fullscreen = True +RenderToMain = False +RenderWindowXPos = -1 +RenderWindowYPos = -1 +RenderWindowWidth = 640 +RenderWindowHeight = 480 +RenderWindowAutoSize = False +KeepWindowOnTop = False +ProgressiveScan = False +PAL60 = True +DisableScreenSaver = True +ForceNTSCJ = False +[GameList] +ListDrives = False +ListWad = True +ListElfDol = True +ListWii = True +ListGC = True +ListJap = True +ListPal = True +ListUsa = True +ListAustralia = True +ListFrance = True +ListGermany = True +ListItaly = True +ListKorea = True +ListNetherlands = True +ListRussia = True +ListSpain = True +ListTaiwan = True +ListWorld = True +ListUnknown = True +ListSort = 3 +ListSortSecondary = 0 +ColorCompressed = True +ColumnPlatform = True +ColumnBanner = True +ColumnNotes = True +ColumnFileName = False +ColumnID = False +ColumnRegion = True +ColumnSize = True +ColumnState = True +[Core] +SkipIPL = True +HLE_BS2 = False +TimingVariance = 40 +CPUCore = 4 +Fastmem = True +CPUThread = True +DSPHLE = True +SkipIdle = True +SyncOnSkipIdle = True +SyncGPU = False +SyncGpuMaxDistance = 200000 +SyncGpuMinDistance = -200000 +SyncGpuOverclock = 1.00000000 +FPRF = False +AccurateNaNs = False +DefaultISO = +DVDRoot = +Apploader = +EnableCheats = True +SelectedLanguage = 0 +OverrideGCLang = False +DPL2Decoder = False +Latency = 2 +MemcardAPath = +MemcardBPath = +AgpCartAPath = +AgpCartBPath = +GCIFolderAPath = /storage/roms/bios/GC/USA +SlotA = 1 +SlotB = 255 +SerialPort1 = 255 +BBA_MAC = +SIDevice0 = 6 +AdapterRumble0 = True +SimulateKonga0 = False +SIDevice1 = 6 +AdapterRumble1 = True +SimulateKonga1 = False +SIDevice2 = 0 +AdapterRumble2 = True +SimulateKonga2 = False +SIDevice3 = 0 +AdapterRumble3 = True +SimulateKonga3 = False +WiiSDCard = False +WiiKeyboard = False +WiimoteContinuousScanning = False +WiimoteEnableSpeaker = False +RunCompareServer = False +RunCompareClient = False +EmulationSpeed = 1.00000000 +FrameSkip = 0x00000003 +Overclock = 4.00000000 +OverclockEnable = False +GFXBackend = +GPUDeterminismMode = auto +PerfMapDir = +AutoDiscChange = True +[Movie] +PauseMovie = False +Author = +DumpFrames = False +DumpFramesSilent = False +ShowInputDisplay = False +[DSP] +EnableJIT = True +DumpAudio = False +DumpUCode = False +Backend = Pulse +Volume = 100 +CaptureLog = False +[Input] +BackgroundInput = False +[FifoPlayer] +LoopReplay = True +[Analytics] +ID = 5082f0c30a7e422b1220107f69d6c108 +Enabled = False +PermissionAsked = True diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3399/GFX.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3399/GFX.ini new file mode 100755 index 0000000000..6cd269c601 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3399/GFX.ini @@ -0,0 +1,61 @@ +[Hardware] +VSync = False +Adapter = 0 +[Settings] +AspectRatio = 2 +InternalResolution = 1 +Crop = False +wideScreenHack = False +UseXFB = False +UseRealXFB = False +SafeTextureCacheColorSamples = 128 +ShowFPS = False +LogRenderTimeToFile = False +OverlayStats = False +OverlayProjStats = False +DumpTextures = False +HiresTextures = False +ConvertHiresTextures = False +CacheHiresTextures = False +DumpEFBTarget = False +FreeLook = False +UseFFV1 = False +EnablePixelLighting = False +FastDepthCalc = True +MSAA = 1 +SSAA = False +EFBScale = 2 +TexFmtOverlayEnable = False +TexFmtOverlayCenter = False +Wireframe = False +DisableFog = False +EnableShaderDebugging = False +BorderlessFullscreen = False +SWZComploc = True +SWZFreeze = True +SWDumpObjects = False +SWDumpTevStages = False +SWDumpTevTexFetches = False +SWDrawStart = 0 +SWDrawEnd = 100000 +ShaderCompilationMode = 0 +WaitForShadersBeforeStarting = True +BackendMultithreading = True +EnableGPUTextureDecoding = True +[Enhancements] +ForceFiltering = False +MaxAnisotropy = 0 +PostProcessingShader = +[Stereoscopy] +StereoMode = 0 +StereoDepth = 20 +StereoConvergencePercentage = 100 +StereoSwapEyes = False +[Hacks] +EFBAccessEnable = False +BBoxEnable = False +ForceProgressive = True +EFBToTextureEnable = True +EFBScaledCopy = False +EFBEmulateFormatChanges = False +SkipDuplicateXFBs = True diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3399/GamecubeControllerProfiles/GCPadNew.ini.east b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3399/GamecubeControllerProfiles/GCPadNew.ini.east new file mode 100755 index 0000000000..dbd6fae001 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3399/GamecubeControllerProfiles/GCPadNew.ini.east @@ -0,0 +1,31 @@ +[GCPad1] +Device = evdev/0/Microsoft X-Box 360 pad +Buttons/A = Button 1 +Buttons/B = Button 0 +Buttons/Start = Button 7 +Buttons/X = Button 2 +Buttons/Y = Button 3 +Buttons/Z = Button 5 +Buttons/Hotkey = Button 6 +C-Stick/Dead Zone = 25.000000000000000 +C-Stick/Down = Axis 4+ +C-Stick/Left = Axis 3- +C-Stick/Modifier = Control_L +C-Stick/Modifier/Range = 50.000000000000000 +C-Stick/Right = Axis 3+ +C-Stick/Up = Axis 4- +D-Pad/Down = Axis 7+ +D-Pad/Left = Axis 6- +D-Pad/Right = Axis 6+ +D-Pad/Up = Axis 7- +Main Stick/Dead Zone = 25.000000000000000 +Main Stick/Down = Axis 1+ +Main Stick/Left = Axis 0- +Main Stick/Modifier = Shift_L +Main Stick/Modifier/Range = 50.000000000000000 +Main Stick/Right = Axis 0+ +Main Stick/Up = Axis 1- +Triggers/L = Axis 2+ +Triggers/R = Axis 5+ +Triforce/Coin = Button 8 +Triforce/Service = Button 4 diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3399/GamecubeControllerProfiles/GCPadNew.ini.south b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3399/GamecubeControllerProfiles/GCPadNew.ini.south new file mode 100755 index 0000000000..8cd2c76826 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3399/GamecubeControllerProfiles/GCPadNew.ini.south @@ -0,0 +1,31 @@ +[GCPad1] +Device = evdev/0/Microsoft X-Box 360 pad +Buttons/A = Button 0 +Buttons/B = Button 3 +Buttons/Start = Button 7 +Buttons/X = Button 1 +Buttons/Y = Button 2 +Buttons/Z = Button 5 +Buttons/Hotkey = Button 6 +C-Stick/Dead Zone = 25.000000000000000 +C-Stick/Down = Axis 4+ +C-Stick/Left = Axis 3- +C-Stick/Modifier = Control_L +C-Stick/Modifier/Range = 50.000000000000000 +C-Stick/Right = Axis 3+ +C-Stick/Up = Axis 4- +D-Pad/Down = Axis 7+ +D-Pad/Left = Axis 6- +D-Pad/Right = Axis 6+ +D-Pad/Up = Axis 7- +Main Stick/Dead Zone = 25.000000000000000 +Main Stick/Down = Axis 1+ +Main Stick/Left = Axis 0- +Main Stick/Modifier = Shift_L +Main Stick/Modifier/Range = 50.000000000000000 +Main Stick/Right = Axis 0+ +Main Stick/Up = Axis 1- +Triggers/L = Axis 2+ +Triggers/R = Axis 5+ +Triforce/Coin = Button 8 +Triforce/Service = Button 4 diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3399/Hotkeys.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3399/Hotkeys.ini new file mode 100644 index 0000000000..8b2e2b8b4f --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3399/Hotkeys.ini @@ -0,0 +1,10 @@ +[Hotkeys] +Device = evdev/0/Microsoft X-Box 360 pad +Graphics Toggles/Toggle Aspect Ratio = @(SELECT+EAST) +General/Take Screenshot = @(SELECT+SOUTH) +Save State/Save to Selected Slot = @(SELECT+TR) +Load State/Load State Slot 1 = @(SELECT+TL) +Other State Hotkeys/Increase Selected State Slot = @(SELECT+`Axis 7-`) +Other State Hotkeys/Decrease Selected State Slot = @(SELECT+`Axis 7+`) +Emulation Speed/Increase Emulation Speed = @(SELECT+`Full Axis 5+`) +Emulation Speed/Decrease Emulation Speed = @(SELECT+`Full Axis 2+`) diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3399/WiiControllerProfiles/classic.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3399/WiiControllerProfiles/classic.ini new file mode 100755 index 0000000000..3c92a42bf0 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3399/WiiControllerProfiles/classic.ini @@ -0,0 +1,27 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Extension = Classic +Source = 1 +Classic/Buttons/A = Button 1 +Classic/Buttons/B = Button 0 +Classic/Buttons/X = Button 2 +Classic/Buttons/Y = Button 3 +Classic/Buttons/ZL = Axis 2+ +Classic/Buttons/ZR = Axis 5+ +Classic/Buttons/- = Button 6 +Classic/Buttons/+ = Button 7 +Classic/Buttons/Home = Button 8 +Classic/Left Stick/Up = Axis 1- +Classic/Left Stick/Down = Axis 1+ +Classic/Left Stick/Left = Axis 0- +Classic/Left Stick/Right = Axis 0+ +Classic/Right Stick/Up = Axis 4- +Classic/Right Stick/Down = Axis 4+ +Classic/Right Stick/Left = Axis 3- +Classic/Right Stick/Right = Axis 3+ +Classic/Triggers/L = Button 4 +Classic/Triggers/R = Button 5 +Classic/D-Pad/Up = Axis 7- +Classic/D-Pad/Down = Axis 7+ +Classic/D-Pad/Left = Axis 6- +Classic/D-Pad/Right = Axis 6+ diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3399/WiiControllerProfiles/hremote.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3399/WiiControllerProfiles/hremote.ini new file mode 100755 index 0000000000..5482c9e295 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3399/WiiControllerProfiles/hremote.ini @@ -0,0 +1,20 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Buttons/A = Button 3 +Buttons/B = Button 2 +Buttons/1 = Button 0 +Buttons/2 = Button 1 +Buttons/- = Button 6 +Buttons/+ = Button 7 +Buttons/Home = Button 8 +Shake/X = Button 4 +Shake/Y = Button 4 +Shake/Z = Button 4 +D-Pad/Up = Axis 6- +D-Pad/Down = Axis 6+ +D-Pad/Left = Axis 7+ +D-Pad/Right = Axis 7- +IR/Up = `Axis 4-` +IR/Down = `Axis 4+` +IR/Left = `Axis 3-` +IR/Right = `Axis 3+` diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3399/WiiControllerProfiles/nunchuck.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3399/WiiControllerProfiles/nunchuck.ini new file mode 100755 index 0000000000..8850d84ce8 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3399/WiiControllerProfiles/nunchuck.ini @@ -0,0 +1,30 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Extension = Nunchuk +Buttons/A = Button 1 +Buttons/B = Button 0 +Buttons/1 = Button 3 +Buttons/2 = Button 2 +Buttons/- = Button 6 +Buttons/+ = Button 7 +D-Pad/Up = Axis 7- +D-Pad/Down = Axis 7+ +D-Pad/Left = Axis 6- +D-Pad/Right = Axis 6+ +Buttons/Home = Button 8 +Shake/X = Button 4 +Shake/Y = Button 4 +Shake/Z = Button 4 +Nunchuk/Buttons/C = Button 5 +Nunchuk/Buttons/Z = Axis 5+ +Nunchuk/Stick/Up = Axis 1- +Nunchuk/Stick/Down = Axis 1+ +Nunchuk/Stick/Left = Axis 0- +Nunchuk/Stick/Right = Axis 0+ +Nunchuk/Shake/X = Axis 2+ +Nunchuk/Shake/Y = Axis 2+ +Nunchuk/Shake/Z = Axis 2+ +IR/Up = `Axis 4-` +IR/Down = `Axis 4+` +IR/Left = `Axis 3-` +IR/Right = `Axis 3+` diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3399/WiiControllerProfiles/vremote.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3399/WiiControllerProfiles/vremote.ini new file mode 100755 index 0000000000..8c0691d587 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3399/WiiControllerProfiles/vremote.ini @@ -0,0 +1,20 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Buttons/A = Button 1 +Buttons/B = Button 0 +Buttons/1 = Button 3 +Buttons/2 = Button 2 +Buttons/- = Button 6 +Buttons/+ = Button 7 +Buttons/Home = Button 8 +Shake/X = Button 4 +Shake/Y = Button 4 +Shake/Z = Button 4 +D-Pad/Up = Axis 7- +D-Pad/Down = Axis 7+ +D-Pad/Left = Axis 6- +D-Pad/Right = Axis 6+ +IR/Up = `Axis 4-` +IR/Down = `Axis 4+` +IR/Left = `Axis 3-` +IR/Right = `Axis 3+` diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3566/Dolphin.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3566/Dolphin.ini new file mode 100755 index 0000000000..887e02bd7c --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3566/Dolphin.ini @@ -0,0 +1,153 @@ +[General] +LastFilename = +ShowLag = False +ShowFrameCount = False +ISOPath0 = /storage/roms/gamecube +ISOPath1 = /storage/roms/wii +ISOPaths = 2 +RecursiveISOPaths = False +NANDRootPath = +WirelessMac = +[Interface] +ConfirmStop = True +UsePanicHandlers = True +OnScreenDisplayMessages = True +HideCursor = False +AutoHideCursor = False +MainWindowPosX = 403 +MainWindowPosY = 148 +MainWindowWidth = 800 +MainWindowHeight = 600 +Language = 0 +ShowToolbar = True +ShowStatusbar = True +ShowLogWindow = False +ShowLogConfigWindow = False +ExtendedFPSInfo = False +ThemeName40 = Clean Blue +PauseOnFocusLost = False +[Display] +FullscreenResolution = Auto +Fullscreen = True +RenderToMain = False +RenderWindowXPos = -1 +RenderWindowYPos = -1 +RenderWindowWidth = 640 +RenderWindowHeight = 480 +RenderWindowAutoSize = False +KeepWindowOnTop = False +ProgressiveScan = False +PAL60 = True +DisableScreenSaver = True +ForceNTSCJ = False +[GameList] +ListDrives = False +ListWad = True +ListElfDol = True +ListWii = True +ListGC = True +ListJap = True +ListPal = True +ListUsa = True +ListAustralia = True +ListFrance = True +ListGermany = True +ListItaly = True +ListKorea = True +ListNetherlands = True +ListRussia = True +ListSpain = True +ListTaiwan = True +ListWorld = True +ListUnknown = True +ListSort = 3 +ListSortSecondary = 0 +ColorCompressed = True +ColumnPlatform = True +ColumnBanner = True +ColumnNotes = True +ColumnFileName = False +ColumnID = False +ColumnRegion = True +ColumnSize = True +ColumnState = True +[Core] +SkipIPL = True +HLE_BS2 = False +TimingVariance = 40 +CPUCore = 4 +Fastmem = True +CPUThread = True +DSPHLE = True +SkipIdle = True +SyncOnSkipIdle = True +SyncGPU = False +SyncGpuMaxDistance = 200000 +SyncGpuMinDistance = -200000 +SyncGpuOverclock = 1.00000000 +FPRF = False +AccurateNaNs = False +DefaultISO = +DVDRoot = +Apploader = +EnableCheats = True +SelectedLanguage = 0 +OverrideGCLang = False +DPL2Decoder = False +Latency = 2 +MemcardAPath = +MemcardBPath = +AgpCartAPath = +AgpCartBPath = +GCIFolderAPath = /storage/roms/bios/GC/USA +SlotA = 1 +SlotB = 255 +SerialPort1 = 255 +BBA_MAC = +SIDevice0 = 6 +AdapterRumble0 = True +SimulateKonga0 = False +SIDevice1 = 6 +AdapterRumble1 = True +SimulateKonga1 = False +SIDevice2 = 0 +AdapterRumble2 = True +SimulateKonga2 = False +SIDevice3 = 0 +AdapterRumble3 = True +SimulateKonga3 = False +WiiSDCard = False +WiiKeyboard = False +WiimoteContinuousScanning = False +WiimoteEnableSpeaker = False +RunCompareServer = False +RunCompareClient = False +EmulationSpeed = 1.00000000 +FrameSkip = 0x00000003 +Overclock = 4.00000000 +OverclockEnable = False +GFXBackend = +GPUDeterminismMode = auto +PerfMapDir = +AutoDiscChange = True +[Movie] +PauseMovie = False +Author = +DumpFrames = False +DumpFramesSilent = False +ShowInputDisplay = False +[DSP] +EnableJIT = True +DumpAudio = False +DumpUCode = False +Backend = Pulse +Volume = 100 +CaptureLog = False +[Input] +BackgroundInput = False +[FifoPlayer] +LoopReplay = True +[Analytics] +ID = 5082f0c30a7e422b1220107f69d6c108 +Enabled = False +PermissionAsked = True diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3566/GFX.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3566/GFX.ini new file mode 100755 index 0000000000..6cd269c601 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3566/GFX.ini @@ -0,0 +1,61 @@ +[Hardware] +VSync = False +Adapter = 0 +[Settings] +AspectRatio = 2 +InternalResolution = 1 +Crop = False +wideScreenHack = False +UseXFB = False +UseRealXFB = False +SafeTextureCacheColorSamples = 128 +ShowFPS = False +LogRenderTimeToFile = False +OverlayStats = False +OverlayProjStats = False +DumpTextures = False +HiresTextures = False +ConvertHiresTextures = False +CacheHiresTextures = False +DumpEFBTarget = False +FreeLook = False +UseFFV1 = False +EnablePixelLighting = False +FastDepthCalc = True +MSAA = 1 +SSAA = False +EFBScale = 2 +TexFmtOverlayEnable = False +TexFmtOverlayCenter = False +Wireframe = False +DisableFog = False +EnableShaderDebugging = False +BorderlessFullscreen = False +SWZComploc = True +SWZFreeze = True +SWDumpObjects = False +SWDumpTevStages = False +SWDumpTevTexFetches = False +SWDrawStart = 0 +SWDrawEnd = 100000 +ShaderCompilationMode = 0 +WaitForShadersBeforeStarting = True +BackendMultithreading = True +EnableGPUTextureDecoding = True +[Enhancements] +ForceFiltering = False +MaxAnisotropy = 0 +PostProcessingShader = +[Stereoscopy] +StereoMode = 0 +StereoDepth = 20 +StereoConvergencePercentage = 100 +StereoSwapEyes = False +[Hacks] +EFBAccessEnable = False +BBoxEnable = False +ForceProgressive = True +EFBToTextureEnable = True +EFBScaledCopy = False +EFBEmulateFormatChanges = False +SkipDuplicateXFBs = True diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3566/GamecubeControllerProfiles/GCPadNew.ini.east b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3566/GamecubeControllerProfiles/GCPadNew.ini.east new file mode 100755 index 0000000000..d9d0185cb6 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3566/GamecubeControllerProfiles/GCPadNew.ini.east @@ -0,0 +1,29 @@ +[GCPad1] +Device = evdev/0/Microsoft X-Box 360 pad +Buttons/A = Button 1 +Buttons/B = Button 0 +Buttons/Start = Button 7 +Buttons/X = Button 2 +Buttons/Y = Button 3 +Buttons/Z = Button 5 +Buttons/Hotkey = Button 6 +C-Stick/Dead Zone = 25.000000000000000 +C-Stick/Down = Axis 4+ +C-Stick/Left = Axis 3- +C-Stick/Modifier = Control_L +C-Stick/Modifier/Range = 50.000000000000000 +C-Stick/Right = Axis 3+ +C-Stick/Up = Axis 4- +D-Pad/Down = Axis 7+ +D-Pad/Left = Axis 6- +D-Pad/Right = Axis 6+ +D-Pad/Up = Axis 7- +Main Stick/Dead Zone = 25.000000000000000 +Main Stick/Down = Axis 1+ +Main Stick/Left = Axis 0- +Main Stick/Modifier = Shift_L +Main Stick/Modifier/Range = 50.000000000000000 +Main Stick/Right = Axis 0+ +Main Stick/Up = Axis 1- +Triggers/L = Axis 2+ +Triggers/R = Axis 5+ diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3566/GamecubeControllerProfiles/GCPadNew.ini.south b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3566/GamecubeControllerProfiles/GCPadNew.ini.south new file mode 100755 index 0000000000..d34241032c --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3566/GamecubeControllerProfiles/GCPadNew.ini.south @@ -0,0 +1,29 @@ +[GCPad1] +Device = evdev/0/Microsoft X-Box 360 pad +Buttons/A = Button 0 +Buttons/B = Button 3 +Buttons/Start = Button 7 +Buttons/X = Button 1 +Buttons/Y = Button 2 +Buttons/Z = Button 5 +Buttons/Hotkey = Button 6 +C-Stick/Dead Zone = 25.000000000000000 +C-Stick/Down = Axis 4+ +C-Stick/Left = Axis 3- +C-Stick/Modifier = Control_L +C-Stick/Modifier/Range = 50.000000000000000 +C-Stick/Right = Axis 3+ +C-Stick/Up = Axis 4- +D-Pad/Down = Axis 7+ +D-Pad/Left = Axis 6- +D-Pad/Right = Axis 6+ +D-Pad/Up = Axis 7- +Main Stick/Dead Zone = 25.000000000000000 +Main Stick/Down = Axis 1+ +Main Stick/Left = Axis 0- +Main Stick/Modifier = Shift_L +Main Stick/Modifier/Range = 50.000000000000000 +Main Stick/Right = Axis 0+ +Main Stick/Up = Axis 1- +Triggers/L = Axis 2+ +Triggers/R = Axis 5+ diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3566/WiiControllerProfiles/classic.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3566/WiiControllerProfiles/classic.ini new file mode 100755 index 0000000000..3c92a42bf0 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3566/WiiControllerProfiles/classic.ini @@ -0,0 +1,27 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Extension = Classic +Source = 1 +Classic/Buttons/A = Button 1 +Classic/Buttons/B = Button 0 +Classic/Buttons/X = Button 2 +Classic/Buttons/Y = Button 3 +Classic/Buttons/ZL = Axis 2+ +Classic/Buttons/ZR = Axis 5+ +Classic/Buttons/- = Button 6 +Classic/Buttons/+ = Button 7 +Classic/Buttons/Home = Button 8 +Classic/Left Stick/Up = Axis 1- +Classic/Left Stick/Down = Axis 1+ +Classic/Left Stick/Left = Axis 0- +Classic/Left Stick/Right = Axis 0+ +Classic/Right Stick/Up = Axis 4- +Classic/Right Stick/Down = Axis 4+ +Classic/Right Stick/Left = Axis 3- +Classic/Right Stick/Right = Axis 3+ +Classic/Triggers/L = Button 4 +Classic/Triggers/R = Button 5 +Classic/D-Pad/Up = Axis 7- +Classic/D-Pad/Down = Axis 7+ +Classic/D-Pad/Left = Axis 6- +Classic/D-Pad/Right = Axis 6+ diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3566/WiiControllerProfiles/hremote.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3566/WiiControllerProfiles/hremote.ini new file mode 100755 index 0000000000..9c675c1d12 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3566/WiiControllerProfiles/hremote.ini @@ -0,0 +1,20 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Buttons/A = Button 3 +Buttons/B = Button 2 +Buttons/1 = Button 0 +Buttons/2 = Button 1 +Buttons/- = Button 6 +Buttons/+ = Button 7 +Buttons/Home = Button 8 +Shake/X = Button 4 +Shake/Y = Button 4 +Shake/Z = Button 4 +D-Pad/Up = `Axis 6-` | `Axis 0-` +D-Pad/Down = `Axis 6+` | `Axis 0+` +D-Pad/Left = `Axis 7+` | `Axis 1+` +D-Pad/Right = `Axis 7-` | `Axis 1-` +IR/Up = `Axis 4-` +IR/Down = `Axis 4+` +IR/Left = `Axis 3-` +IR/Right = `Axis 3+` diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3566/WiiControllerProfiles/nunchuck.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3566/WiiControllerProfiles/nunchuck.ini new file mode 100755 index 0000000000..8850d84ce8 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3566/WiiControllerProfiles/nunchuck.ini @@ -0,0 +1,30 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Extension = Nunchuk +Buttons/A = Button 1 +Buttons/B = Button 0 +Buttons/1 = Button 3 +Buttons/2 = Button 2 +Buttons/- = Button 6 +Buttons/+ = Button 7 +D-Pad/Up = Axis 7- +D-Pad/Down = Axis 7+ +D-Pad/Left = Axis 6- +D-Pad/Right = Axis 6+ +Buttons/Home = Button 8 +Shake/X = Button 4 +Shake/Y = Button 4 +Shake/Z = Button 4 +Nunchuk/Buttons/C = Button 5 +Nunchuk/Buttons/Z = Axis 5+ +Nunchuk/Stick/Up = Axis 1- +Nunchuk/Stick/Down = Axis 1+ +Nunchuk/Stick/Left = Axis 0- +Nunchuk/Stick/Right = Axis 0+ +Nunchuk/Shake/X = Axis 2+ +Nunchuk/Shake/Y = Axis 2+ +Nunchuk/Shake/Z = Axis 2+ +IR/Up = `Axis 4-` +IR/Down = `Axis 4+` +IR/Left = `Axis 3-` +IR/Right = `Axis 3+` diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3566/WiiControllerProfiles/vremote.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3566/WiiControllerProfiles/vremote.ini new file mode 100755 index 0000000000..90ef876567 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3566/WiiControllerProfiles/vremote.ini @@ -0,0 +1,20 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Buttons/A = Button 1 +Buttons/B = Button 0 +Buttons/1 = Button 3 +Buttons/2 = Button 2 +Buttons/- = Button 6 +Buttons/+ = Button 7 +Buttons/Home = Button 8 +Shake/X = Button 4 +Shake/Y = Button 4 +Shake/Z = Button 4 +D-Pad/Up = `Axis 7-` | `Axis 1-` +D-Pad/Down = `Axis 7+` | `Axis 1+` +D-Pad/Left = `Axis 6-` | `Axis 0-` +D-Pad/Right = `Axis 6+` | `Axis 0+` +IR/Up = `Axis 4-` +IR/Down = `Axis 4+` +IR/Left = `Axis 3-` +IR/Right = `Axis 3+` diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3588/Dolphin.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3588/Dolphin.ini new file mode 100644 index 0000000000..8c81872bc9 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3588/Dolphin.ini @@ -0,0 +1,154 @@ +[General] +LastFilename = +ShowLag = False +ShowFrameCount = False +ISOPath0 = /storage/roms/gamecube +ISOPath1 = /storage/roms/wii +ISOPaths = 2 +RecursiveISOPaths = False +NANDRootPath = +WirelessMac = +[Interface] +ConfirmStop = True +UsePanicHandlers = True +OnScreenDisplayMessages = True +HideCursor = False +AutoHideCursor = False +MainWindowPosX = 403 +MainWindowPosY = 148 +MainWindowWidth = 800 +MainWindowHeight = 600 +Language = 0 +ShowToolbar = True +ShowStatusbar = True +ShowLogWindow = False +ShowLogConfigWindow = False +ExtendedFPSInfo = False +ThemeName40 = Clean Blue +PauseOnFocusLost = False +[Display] +FullscreenResolution = Auto +Fullscreen = True +RenderToMain = False +RenderWindowXPos = -1 +RenderWindowYPos = -1 +RenderWindowWidth = 640 +RenderWindowHeight = 480 +RenderWindowAutoSize = False +KeepWindowOnTop = False +ProgressiveScan = False +PAL60 = True +DisableScreenSaver = True +ForceNTSCJ = False +[GameList] +ListDrives = False +ListWad = True +ListElfDol = True +ListWii = True +ListGC = True +ListJap = True +ListPal = True +ListUsa = True +ListAustralia = True +ListFrance = True +ListGermany = True +ListItaly = True +ListKorea = True +ListNetherlands = True +ListRussia = True +ListSpain = True +ListTaiwan = True +ListWorld = True +ListUnknown = True +ListSort = 3 +ListSortSecondary = 0 +ColorCompressed = True +ColumnPlatform = True +ColumnBanner = True +ColumnNotes = True +ColumnFileName = False +ColumnID = False +ColumnRegion = True +ColumnSize = True +ColumnState = True +[Core] +SkipIPL = True +HLE_BS2 = False +TimingVariance = 40 +CPUCore = 4 +Fastmem = True +CPUThread = True +DSPHLE = True +SkipIdle = True +SyncOnSkipIdle = False +SyncGPU = False +SyncGpuMaxDistance = 200000 +SyncGpuMinDistance = -200000 +SyncGpuOverclock = 1.00000000 +FPRF = False +AccurateNaNs = False +DefaultISO = +DVDRoot = +Apploader = +EnableCheats = True +SelectedLanguage = 0 +OverrideGCLang = False +DPL2Decoder = False +Latency = 2 +MemcardAPath = +MemcardBPath = +AgpCartAPath = +AgpCartBPath = +GCIFolderAPath = /storage/roms/bios/GC/USA +SlotA = 1 +SlotB = 255 +SerialPort1 = 255 +BBA_MAC = +SIDevice0 = 6 +AdapterRumble0 = True +SimulateKonga0 = False +SIDevice1 = 6 +AdapterRumble1 = True +SimulateKonga1 = False +SIDevice2 = 0 +AdapterRumble2 = True +SimulateKonga2 = False +SIDevice3 = 0 +AdapterRumble3 = True +SimulateKonga3 = False +WiiSDCard = False +WiiKeyboard = False +WiimoteContinuousScanning = False +WiimoteEnableSpeaker = False +RunCompareServer = False +RunCompareClient = False +EmulationSpeed = 1.00000000 +FrameSkip = 0x00000003 +Overclock = 1.0 +OverclockEnable = False +GFXBackend = OGL +GPUDeterminismMode = auto +PerfMapDir = +AutoDiscChange = True +[Movie] +PauseMovie = False +Author = +DumpFrames = False +DumpFramesSilent = False +ShowInputDisplay = False +[DSP] +EnableJIT = True +DumpAudio = False +DumpUCode = False +Backend = Pulse +Volume = 100 +CaptureLog = False +DSPThread = True +[Input] +BackgroundInput = False +[FifoPlayer] +LoopReplay = True +[Analytics] +ID = 5082f0c30a7e422b1220107f69d6c108 +Enabled = False +PermissionAsked = True diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3588/GFX.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3588/GFX.ini new file mode 100644 index 0000000000..6fcca41798 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3588/GFX.ini @@ -0,0 +1,62 @@ +[Hardware] +VSync = False +Adapter = 0 +[Settings] +PreferGLES = True +AspectRatio = 0 +InternalResolution = 2 +Crop = False +wideScreenHack = False +UseXFB = False +UseRealXFB = False +SafeTextureCacheColorSamples = 128 +ShowFPS = False +LogRenderTimeToFile = False +OverlayStats = False +OverlayProjStats = False +DumpTextures = False +HiresTextures = False +ConvertHiresTextures = False +CacheHiresTextures = False +DumpEFBTarget = False +FreeLook = False +UseFFV1 = False +EnablePixelLighting = False +FastDepthCalc = True +MSAA = 1 +SSAA = False +EFBScale = 2 +TexFmtOverlayEnable = False +TexFmtOverlayCenter = False +Wireframe = False +DisableFog = False +EnableShaderDebugging = False +BorderlessFullscreen = False +SWZComploc = True +SWZFreeze = True +SWDumpObjects = False +SWDumpTevStages = False +SWDumpTevTexFetches = False +SWDrawStart = 0 +SWDrawEnd = 100000 +ShaderCompilationMode = 0 +WaitForShadersBeforeStarting = True +BackendMultithreading = True +EnableGPUTextureDecoding = True +[Enhancements] +ForceTextureFiltering = False +MaxAnisotropy = 0 +PostProcessingShader = +[Stereoscopy] +StereoMode = 0 +StereoDepth = 20 +StereoConvergencePercentage = 100 +StereoSwapEyes = False +[Hacks] +EFBAccessEnable = False +BBoxEnable = False +ForceProgressive = True +EFBToTextureEnable = True +EFBScaledCopy = False +EFBEmulateFormatChanges = False +SkipDuplicateXFBs = True diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3588/GamecubeControllerProfiles/GCPadNew.ini.east b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3588/GamecubeControllerProfiles/GCPadNew.ini.east new file mode 100644 index 0000000000..7cbb844c54 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3588/GamecubeControllerProfiles/GCPadNew.ini.east @@ -0,0 +1,35 @@ +[GCPad1] +Device = evdev/0/Microsoft X-Box 360 pad +Buttons/A = Button 1 +Buttons/B = Button 0 +Buttons/Start = Button 7 +Buttons/X = Button 2 +Buttons/Y = Button 3 +Buttons/Z = Button 5 +Buttons/Hotkey = Button 6 +C-Stick/Dead Zone = 25.000000000000000 +C-Stick/Down = Axis 4+ +C-Stick/Left = Axis 3- +C-Stick/Modifier = Control_L +C-Stick/Modifier/Range = 50.000000000000000 +C-Stick/Right = Axis 3+ +C-Stick/Up = Axis 4- +D-Pad/Down = Axis 7+ +D-Pad/Left = Axis 6- +D-Pad/Right = Axis 6+ +D-Pad/Up = Axis 7- +Main Stick/Dead Zone = 25.000000000000000 +Main Stick/Down = Axis 1+ +Main Stick/Left = Axis 0- +Main Stick/Modifier = Shift_L +Main Stick/Modifier/Range = 50.000000000000000 +Main Stick/Right = Axis 0+ +Main Stick/Up = Axis 1- +Triggers/Dead Zone = 0. +Triggers/Threshold = 90. +Triggers/L = Axis 2+ +Triggers/R = Axis 5+ +Triggers/L-Analog = Axis 2+ +Triggers/R-Analog = Axis 5+ +Triforce/Coin = Button 8 +Triforce/Service = Button 4 diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3588/GamecubeControllerProfiles/GCPadNew.ini.south b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3588/GamecubeControllerProfiles/GCPadNew.ini.south new file mode 100644 index 0000000000..0547f74b72 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3588/GamecubeControllerProfiles/GCPadNew.ini.south @@ -0,0 +1,35 @@ +[GCPad1] +Device = evdev/0/Microsoft X-Box 360 pad +Buttons/A = Button 0 +Buttons/B = Button 3 +Buttons/Start = Button 7 +Buttons/X = Button 1 +Buttons/Y = Button 2 +Buttons/Z = Button 5 +Buttons/Hotkey = Button 6 +C-Stick/Dead Zone = 25.000000000000000 +C-Stick/Down = Axis 4+ +C-Stick/Left = Axis 3- +C-Stick/Modifier = Control_L +C-Stick/Modifier/Range = 50.000000000000000 +C-Stick/Right = Axis 3+ +C-Stick/Up = Axis 4- +D-Pad/Down = Axis 7+ +D-Pad/Left = Axis 6- +D-Pad/Right = Axis 6+ +D-Pad/Up = Axis 7- +Main Stick/Dead Zone = 25.000000000000000 +Main Stick/Down = Axis 1+ +Main Stick/Left = Axis 0- +Main Stick/Modifier = Shift_L +Main Stick/Modifier/Range = 50.000000000000000 +Main Stick/Right = Axis 0+ +Main Stick/Up = Axis 1- +Triggers/Dead Zone = 0. +Triggers/Threshold = 90. +Triggers/L = Axis 2+ +Triggers/R = Axis 5+ +Triggers/L-Analog = Axis 2+ +Triggers/R-Analog = Axis 5+ +Triforce/Coin = Button 8 +Triforce/Service = Button 4 diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3588/WiiControllerProfiles/classic.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3588/WiiControllerProfiles/classic.ini new file mode 100644 index 0000000000..3c92a42bf0 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3588/WiiControllerProfiles/classic.ini @@ -0,0 +1,27 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Extension = Classic +Source = 1 +Classic/Buttons/A = Button 1 +Classic/Buttons/B = Button 0 +Classic/Buttons/X = Button 2 +Classic/Buttons/Y = Button 3 +Classic/Buttons/ZL = Axis 2+ +Classic/Buttons/ZR = Axis 5+ +Classic/Buttons/- = Button 6 +Classic/Buttons/+ = Button 7 +Classic/Buttons/Home = Button 8 +Classic/Left Stick/Up = Axis 1- +Classic/Left Stick/Down = Axis 1+ +Classic/Left Stick/Left = Axis 0- +Classic/Left Stick/Right = Axis 0+ +Classic/Right Stick/Up = Axis 4- +Classic/Right Stick/Down = Axis 4+ +Classic/Right Stick/Left = Axis 3- +Classic/Right Stick/Right = Axis 3+ +Classic/Triggers/L = Button 4 +Classic/Triggers/R = Button 5 +Classic/D-Pad/Up = Axis 7- +Classic/D-Pad/Down = Axis 7+ +Classic/D-Pad/Left = Axis 6- +Classic/D-Pad/Right = Axis 6+ diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3588/WiiControllerProfiles/hremote.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3588/WiiControllerProfiles/hremote.ini new file mode 100644 index 0000000000..9c675c1d12 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3588/WiiControllerProfiles/hremote.ini @@ -0,0 +1,20 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Buttons/A = Button 3 +Buttons/B = Button 2 +Buttons/1 = Button 0 +Buttons/2 = Button 1 +Buttons/- = Button 6 +Buttons/+ = Button 7 +Buttons/Home = Button 8 +Shake/X = Button 4 +Shake/Y = Button 4 +Shake/Z = Button 4 +D-Pad/Up = `Axis 6-` | `Axis 0-` +D-Pad/Down = `Axis 6+` | `Axis 0+` +D-Pad/Left = `Axis 7+` | `Axis 1+` +D-Pad/Right = `Axis 7-` | `Axis 1-` +IR/Up = `Axis 4-` +IR/Down = `Axis 4+` +IR/Left = `Axis 3-` +IR/Right = `Axis 3+` diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3588/WiiControllerProfiles/nunchuck.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3588/WiiControllerProfiles/nunchuck.ini new file mode 100644 index 0000000000..8850d84ce8 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3588/WiiControllerProfiles/nunchuck.ini @@ -0,0 +1,30 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Extension = Nunchuk +Buttons/A = Button 1 +Buttons/B = Button 0 +Buttons/1 = Button 3 +Buttons/2 = Button 2 +Buttons/- = Button 6 +Buttons/+ = Button 7 +D-Pad/Up = Axis 7- +D-Pad/Down = Axis 7+ +D-Pad/Left = Axis 6- +D-Pad/Right = Axis 6+ +Buttons/Home = Button 8 +Shake/X = Button 4 +Shake/Y = Button 4 +Shake/Z = Button 4 +Nunchuk/Buttons/C = Button 5 +Nunchuk/Buttons/Z = Axis 5+ +Nunchuk/Stick/Up = Axis 1- +Nunchuk/Stick/Down = Axis 1+ +Nunchuk/Stick/Left = Axis 0- +Nunchuk/Stick/Right = Axis 0+ +Nunchuk/Shake/X = Axis 2+ +Nunchuk/Shake/Y = Axis 2+ +Nunchuk/Shake/Z = Axis 2+ +IR/Up = `Axis 4-` +IR/Down = `Axis 4+` +IR/Left = `Axis 3-` +IR/Right = `Axis 3+` diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3588/WiiControllerProfiles/vremote.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3588/WiiControllerProfiles/vremote.ini new file mode 100644 index 0000000000..90ef876567 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/RK3588/WiiControllerProfiles/vremote.ini @@ -0,0 +1,20 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Buttons/A = Button 1 +Buttons/B = Button 0 +Buttons/1 = Button 3 +Buttons/2 = Button 2 +Buttons/- = Button 6 +Buttons/+ = Button 7 +Buttons/Home = Button 8 +Shake/X = Button 4 +Shake/Y = Button 4 +Shake/Z = Button 4 +D-Pad/Up = `Axis 7-` | `Axis 1-` +D-Pad/Down = `Axis 7+` | `Axis 1+` +D-Pad/Left = `Axis 6-` | `Axis 0-` +D-Pad/Right = `Axis 6+` | `Axis 0+` +IR/Up = `Axis 4-` +IR/Down = `Axis 4+` +IR/Left = `Axis 3-` +IR/Right = `Axis 3+` diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/S922X/Dolphin.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/S922X/Dolphin.ini new file mode 100644 index 0000000000..f0d5885d3d --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/S922X/Dolphin.ini @@ -0,0 +1,152 @@ +[General] +LastFilename = +ShowLag = False +ShowFrameCount = False +ISOPaths = 1 +RecursiveISOPaths = False +NANDRootPath = +WirelessMac = +[Interface] +ConfirmStop = True +UsePanicHandlers = True +OnScreenDisplayMessages = True +HideCursor = False +AutoHideCursor = False +MainWindowPosX = 403 +MainWindowPosY = 148 +MainWindowWidth = 800 +MainWindowHeight = 600 +Language = 0 +ShowToolbar = True +ShowStatusbar = True +ShowLogWindow = False +ShowLogConfigWindow = False +ExtendedFPSInfo = False +ThemeName40 = Clean Blue +PauseOnFocusLost = False +[Display] +FullscreenResolution = Auto +Fullscreen = True +RenderToMain = False +RenderWindowXPos = -1 +RenderWindowYPos = -1 +RenderWindowWidth = 640 +RenderWindowHeight = 480 +RenderWindowAutoSize = False +KeepWindowOnTop = False +ProgressiveScan = False +PAL60 = True +DisableScreenSaver = True +ForceNTSCJ = False +[GameList] +ListDrives = False +ListWad = True +ListElfDol = True +ListWii = True +ListGC = True +ListJap = True +ListPal = True +ListUsa = True +ListAustralia = True +ListFrance = True +ListGermany = True +ListItaly = True +ListKorea = True +ListNetherlands = True +ListRussia = True +ListSpain = True +ListTaiwan = True +ListWorld = True +ListUnknown = True +ListSort = 3 +ListSortSecondary = 0 +ColorCompressed = True +ColumnPlatform = True +ColumnBanner = True +ColumnNotes = True +ColumnFileName = False +ColumnID = False +ColumnRegion = True +ColumnSize = True +ColumnState = True +[Core] +SkipIPL = True +HLE_BS2 = False +TimingVariance = 40 +CPUCore = 4 +Fastmem = True +CPUThread = True +DSPHLE = True +SkipIdle = True +SyncOnSkipIdle = False +SyncGPU = False +SyncGpuMaxDistance = 200000 +SyncGpuMinDistance = -200000 +SyncGpuOverclock = 1.00000000 +FPRF = False +AccurateNaNs = False +DefaultISO = +DVDRoot = +Apploader = +EnableCheats = True +SelectedLanguage = 0 +OverrideGCLang = False +DPL2Decoder = False +Latency = 2 +MemcardAPath = +MemcardBPath = +AgpCartAPath = +AgpCartBPath = +GCIFolderAPath = /storage/roms/bios/GC/USA +SlotA = 1 +SlotB = 255 +SerialPort1 = 255 +BBA_MAC = +SIDevice0 = 6 +AdapterRumble0 = True +SimulateKonga0 = False +SIDevice1 = 6 +AdapterRumble1 = True +SimulateKonga1 = False +SIDevice2 = 0 +AdapterRumble2 = True +SimulateKonga2 = False +SIDevice3 = 0 +AdapterRumble3 = True +SimulateKonga3 = False +WiiSDCard = False +WiiKeyboard = False +WiimoteContinuousScanning = False +WiimoteEnableSpeaker = False +RunCompareServer = False +RunCompareClient = False +EmulationSpeed = 1.00000000 +FrameSkip = 0x00000003 +Overclock = 1.0 +OverclockEnable = False +GFXBackend = Vulkan +GPUDeterminismMode = auto +PerfMapDir = +AutoDiscChange = True +[Movie] +PauseMovie = False +Author = +DumpFrames = False +DumpFramesSilent = False +ShowInputDisplay = False +[DSP] +EnableJIT = True +DumpAudio = False +DumpUCode = False +Backend = Pulse +Volume = 100 +CaptureLog = False +DSPThread = True +[Input] +BackgroundInput = False +[FifoPlayer] +LoopReplay = True +[Analytics] +ID = 5082f0c30a7e422b1220107f69d6c108 +Enabled = False +PermissionAsked = True diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/S922X/GFX.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/S922X/GFX.ini new file mode 100644 index 0000000000..4076f48287 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/S922X/GFX.ini @@ -0,0 +1,61 @@ +[Hardware] +VSync = False +Adapter = 0 +[Settings] +AspectRatio = 0 +InternalResolution = 2 +Crop = False +wideScreenHack = False +UseXFB = False +UseRealXFB = False +SafeTextureCacheColorSamples = 128 +ShowFPS = False +LogRenderTimeToFile = False +OverlayStats = False +OverlayProjStats = False +DumpTextures = False +HiresTextures = False +ConvertHiresTextures = False +CacheHiresTextures = False +DumpEFBTarget = False +FreeLook = False +UseFFV1 = False +EnablePixelLighting = False +FastDepthCalc = True +MSAA = 1 +SSAA = False +EFBScale = 2 +TexFmtOverlayEnable = False +TexFmtOverlayCenter = False +Wireframe = False +DisableFog = False +EnableShaderDebugging = False +BorderlessFullscreen = False +SWZComploc = True +SWZFreeze = True +SWDumpObjects = False +SWDumpTevStages = False +SWDumpTevTexFetches = False +SWDrawStart = 0 +SWDrawEnd = 100000 +ShaderCompilationMode = 0 +WaitForShadersBeforeStarting = True +BackendMultithreading = True +EnableGPUTextureDecoding = True +[Enhancements] +ForceTextureFiltering = False +MaxAnisotropy = 0 +PostProcessingShader = +[Stereoscopy] +StereoMode = 0 +StereoDepth = 20 +StereoConvergencePercentage = 100 +StereoSwapEyes = False +[Hacks] +EFBAccessEnable = False +BBoxEnable = False +ForceProgressive = True +EFBToTextureEnable = True +EFBScaledCopy = False +EFBEmulateFormatChanges = False +SkipDuplicateXFBs = True diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/S922X/GamecubeControllerProfiles/GCPadNew.ini.east b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/S922X/GamecubeControllerProfiles/GCPadNew.ini.east new file mode 100644 index 0000000000..7c37ae856e --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/S922X/GamecubeControllerProfiles/GCPadNew.ini.east @@ -0,0 +1,29 @@ +[GCPad1] +Device = evdev/0/Microsoft X-Box 360 pad +Buttons/A = Button 1 +Buttons/B = Button 0 +Buttons/Start = Button 7 +Buttons/X = Button 2 +Buttons/Y = Button 3 +Buttons/Z = Axis 5+ +Buttons/Hotkey = Button 6 +C-Stick/Dead Zone = 25.000000000000000 +C-Stick/Down = Axis 4+ +C-Stick/Left = Axis 3- +C-Stick/Modifier = Control_L +C-Stick/Modifier/Range = 50.000000000000000 +C-Stick/Right = Axis 3+ +C-Stick/Up = Axis 4- +D-Pad/Down = Axis 7+ +D-Pad/Left = Axis 6- +D-Pad/Right = Axis 6+ +D-Pad/Up = Axis 7- +Main Stick/Dead Zone = 25.000000000000000 +Main Stick/Down = Axis 1+ +Main Stick/Left = Axis 0- +Main Stick/Modifier = Shift_L +Main Stick/Modifier/Range = 50.000000000000000 +Main Stick/Right = Axis 0+ +Main Stick/Up = Axis 1- +Triggers/L = Button 4 +Triggers/R = Button 5 diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/S922X/GamecubeControllerProfiles/GCPadNew.ini.south b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/S922X/GamecubeControllerProfiles/GCPadNew.ini.south new file mode 100644 index 0000000000..6f3ae8606b --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/S922X/GamecubeControllerProfiles/GCPadNew.ini.south @@ -0,0 +1,29 @@ +[GCPad1] +Device = evdev/0/Microsoft X-Box 360 pad +Buttons/A = Button 0 +Buttons/B = Button 3 +Buttons/Start = Button 7 +Buttons/X = Button 1 +Buttons/Y = Button 2 +Buttons/Z = Axis 5+ +Buttons/Hotkey = Button 6 +C-Stick/Dead Zone = 25.000000000000000 +C-Stick/Down = Axis 4+ +C-Stick/Left = Axis 3- +C-Stick/Modifier = Control_L +C-Stick/Modifier/Range = 50.000000000000000 +C-Stick/Right = Axis 3+ +C-Stick/Up = Axis 4- +D-Pad/Down = Axis 7+ +D-Pad/Left = Axis 6- +D-Pad/Right = Axis 6+ +D-Pad/Up = Axis 7- +Main Stick/Dead Zone = 25.000000000000000 +Main Stick/Down = Axis 1+ +Main Stick/Left = Axis 0- +Main Stick/Modifier = Shift_L +Main Stick/Modifier/Range = 50.000000000000000 +Main Stick/Right = Axis 0+ +Main Stick/Up = Axis 1- +Triggers/L = Button 4 +Triggers/R = Button 5 diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/S922X/WiiControllerProfiles/classic.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/S922X/WiiControllerProfiles/classic.ini new file mode 100644 index 0000000000..3c92a42bf0 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/S922X/WiiControllerProfiles/classic.ini @@ -0,0 +1,27 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Extension = Classic +Source = 1 +Classic/Buttons/A = Button 1 +Classic/Buttons/B = Button 0 +Classic/Buttons/X = Button 2 +Classic/Buttons/Y = Button 3 +Classic/Buttons/ZL = Axis 2+ +Classic/Buttons/ZR = Axis 5+ +Classic/Buttons/- = Button 6 +Classic/Buttons/+ = Button 7 +Classic/Buttons/Home = Button 8 +Classic/Left Stick/Up = Axis 1- +Classic/Left Stick/Down = Axis 1+ +Classic/Left Stick/Left = Axis 0- +Classic/Left Stick/Right = Axis 0+ +Classic/Right Stick/Up = Axis 4- +Classic/Right Stick/Down = Axis 4+ +Classic/Right Stick/Left = Axis 3- +Classic/Right Stick/Right = Axis 3+ +Classic/Triggers/L = Button 4 +Classic/Triggers/R = Button 5 +Classic/D-Pad/Up = Axis 7- +Classic/D-Pad/Down = Axis 7+ +Classic/D-Pad/Left = Axis 6- +Classic/D-Pad/Right = Axis 6+ diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/S922X/WiiControllerProfiles/hremote.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/S922X/WiiControllerProfiles/hremote.ini new file mode 100644 index 0000000000..9c675c1d12 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/S922X/WiiControllerProfiles/hremote.ini @@ -0,0 +1,20 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Buttons/A = Button 3 +Buttons/B = Button 2 +Buttons/1 = Button 0 +Buttons/2 = Button 1 +Buttons/- = Button 6 +Buttons/+ = Button 7 +Buttons/Home = Button 8 +Shake/X = Button 4 +Shake/Y = Button 4 +Shake/Z = Button 4 +D-Pad/Up = `Axis 6-` | `Axis 0-` +D-Pad/Down = `Axis 6+` | `Axis 0+` +D-Pad/Left = `Axis 7+` | `Axis 1+` +D-Pad/Right = `Axis 7-` | `Axis 1-` +IR/Up = `Axis 4-` +IR/Down = `Axis 4+` +IR/Left = `Axis 3-` +IR/Right = `Axis 3+` diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/S922X/WiiControllerProfiles/nunchuck.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/S922X/WiiControllerProfiles/nunchuck.ini new file mode 100644 index 0000000000..8850d84ce8 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/S922X/WiiControllerProfiles/nunchuck.ini @@ -0,0 +1,30 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Extension = Nunchuk +Buttons/A = Button 1 +Buttons/B = Button 0 +Buttons/1 = Button 3 +Buttons/2 = Button 2 +Buttons/- = Button 6 +Buttons/+ = Button 7 +D-Pad/Up = Axis 7- +D-Pad/Down = Axis 7+ +D-Pad/Left = Axis 6- +D-Pad/Right = Axis 6+ +Buttons/Home = Button 8 +Shake/X = Button 4 +Shake/Y = Button 4 +Shake/Z = Button 4 +Nunchuk/Buttons/C = Button 5 +Nunchuk/Buttons/Z = Axis 5+ +Nunchuk/Stick/Up = Axis 1- +Nunchuk/Stick/Down = Axis 1+ +Nunchuk/Stick/Left = Axis 0- +Nunchuk/Stick/Right = Axis 0+ +Nunchuk/Shake/X = Axis 2+ +Nunchuk/Shake/Y = Axis 2+ +Nunchuk/Shake/Z = Axis 2+ +IR/Up = `Axis 4-` +IR/Down = `Axis 4+` +IR/Left = `Axis 3-` +IR/Right = `Axis 3+` diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/S922X/WiiControllerProfiles/vremote.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/S922X/WiiControllerProfiles/vremote.ini new file mode 100644 index 0000000000..90ef876567 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/S922X/WiiControllerProfiles/vremote.ini @@ -0,0 +1,20 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Buttons/A = Button 1 +Buttons/B = Button 0 +Buttons/1 = Button 3 +Buttons/2 = Button 2 +Buttons/- = Button 6 +Buttons/+ = Button 7 +Buttons/Home = Button 8 +Shake/X = Button 4 +Shake/Y = Button 4 +Shake/Z = Button 4 +D-Pad/Up = `Axis 7-` | `Axis 1-` +D-Pad/Down = `Axis 7+` | `Axis 1+` +D-Pad/Left = `Axis 6-` | `Axis 0-` +D-Pad/Right = `Axis 6+` | `Axis 0+` +IR/Up = `Axis 4-` +IR/Down = `Axis 4+` +IR/Left = `Axis 3-` +IR/Right = `Axis 3+` diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SDM845/Dolphin.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SDM845/Dolphin.ini new file mode 100644 index 0000000000..823db4700a --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SDM845/Dolphin.ini @@ -0,0 +1,154 @@ +[General] +LastFilename = +ShowLag = False +ShowFrameCount = False +ISOPath0 = /storage/roms/gamecube +ISOPath1 = /storage/roms/wii +ISOPaths = 2 +RecursiveISOPaths = False +NANDRootPath = +WirelessMac = +[Interface] +ConfirmStop = True +UsePanicHandlers = True +OnScreenDisplayMessages = True +HideCursor = False +AutoHideCursor = False +MainWindowPosX = 403 +MainWindowPosY = 148 +MainWindowWidth = 800 +MainWindowHeight = 600 +Language = 0 +ShowToolbar = True +ShowStatusbar = True +ShowLogWindow = False +ShowLogConfigWindow = False +ExtendedFPSInfo = False +ThemeName40 = Clean Blue +PauseOnFocusLost = False +[Display] +FullscreenResolution = Auto +Fullscreen = True +RenderToMain = False +RenderWindowXPos = -1 +RenderWindowYPos = -1 +RenderWindowWidth = 640 +RenderWindowHeight = 480 +RenderWindowAutoSize = False +KeepWindowOnTop = False +ProgressiveScan = False +PAL60 = True +DisableScreenSaver = True +ForceNTSCJ = False +[GameList] +ListDrives = False +ListWad = True +ListElfDol = True +ListWii = True +ListGC = True +ListJap = True +ListPal = True +ListUsa = True +ListAustralia = True +ListFrance = True +ListGermany = True +ListItaly = True +ListKorea = True +ListNetherlands = True +ListRussia = True +ListSpain = True +ListTaiwan = True +ListWorld = True +ListUnknown = True +ListSort = 3 +ListSortSecondary = 0 +ColorCompressed = True +ColumnPlatform = True +ColumnBanner = True +ColumnNotes = True +ColumnFileName = False +ColumnID = False +ColumnRegion = True +ColumnSize = True +ColumnState = True +[Core] +SkipIPL = True +HLE_BS2 = False +TimingVariance = 40 +CPUCore = 4 +Fastmem = True +CPUThread = True +DSPHLE = True +SkipIdle = True +SyncOnSkipIdle = False +SyncGPU = False +SyncGpuMaxDistance = 200000 +SyncGpuMinDistance = -200000 +SyncGpuOverclock = 1.00000000 +FPRF = False +AccurateNaNs = False +DefaultISO = +DVDRoot = +Apploader = +EnableCheats = True +SelectedLanguage = 0 +OverrideGCLang = False +DPL2Decoder = False +Latency = 2 +MemcardAPath = +MemcardBPath = +AgpCartAPath = +AgpCartBPath = +GCIFolderAPath = /storage/roms/bios/GC/USA +SlotA = 1 +SlotB = 255 +SerialPort1 = 255 +BBA_MAC = +SIDevice0 = 6 +AdapterRumble0 = True +SimulateKonga0 = False +SIDevice1 = 6 +AdapterRumble1 = True +SimulateKonga1 = False +SIDevice2 = 0 +AdapterRumble2 = True +SimulateKonga2 = False +SIDevice3 = 0 +AdapterRumble3 = True +SimulateKonga3 = False +WiiSDCard = False +WiiKeyboard = False +WiimoteContinuousScanning = False +WiimoteEnableSpeaker = False +RunCompareServer = False +RunCompareClient = False +EmulationSpeed = 1.00000000 +FrameSkip = 0x00000003 +Overclock = 1.0 +OverclockEnable = False +GFXBackend = Vulkan +GPUDeterminismMode = auto +PerfMapDir = +AutoDiscChange = True +[Movie] +PauseMovie = False +Author = +DumpFrames = False +DumpFramesSilent = False +ShowInputDisplay = False +[DSP] +EnableJIT = True +DumpAudio = False +DumpUCode = False +Backend = Pulse +Volume = 100 +CaptureLog = False +DSPThread = True +[Input] +BackgroundInput = False +[FifoPlayer] +LoopReplay = True +[Analytics] +ID = 5082f0c30a7e422b1220107f69d6c108 +Enabled = False +PermissionAsked = True diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SDM845/GFX.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SDM845/GFX.ini new file mode 100644 index 0000000000..ad0f286a21 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SDM845/GFX.ini @@ -0,0 +1,62 @@ +[Hardware] +VSync = False +Adapter = 0 +[Settings] +AspectRatio = 0 +InternalResolution = 2 +Crop = False +wideScreenHack = False +UseXFB = False +UseRealXFB = False +SafeTextureCacheColorSamples = 128 +ShowFPS = False +LogRenderTimeToFile = False +OverlayStats = False +OverlayProjStats = False +DumpTextures = False +HiresTextures = False +ConvertHiresTextures = False +CacheHiresTextures = False +DumpEFBTarget = False +FreeLook = False +UseFFV1 = False +EnablePixelLighting = False +FastDepthCalc = True +MSAA = 1 +SSAA = False +EFBScale = 2 +TexFmtOverlayEnable = False +TexFmtOverlayCenter = False +Wireframe = False +DisableFog = False +EnableShaderDebugging = False +BorderlessFullscreen = False +SWZComploc = True +SWZFreeze = True +SWDumpObjects = False +SWDumpTevStages = False +SWDumpTevTexFetches = False +SWDrawStart = 0 +SWDrawEnd = 100000 +ShaderCompilationMode = 0 +WaitForShadersBeforeStarting = True +BackendMultithreading = True +EnableGPUTextureDecoding = True +[Enhancements] +ForceTextureFiltering = False +MaxAnisotropy = 0 +PostProcessingShader = +[Stereoscopy] +StereoMode = 0 +StereoDepth = 20 +StereoConvergencePercentage = 100 +StereoSwapEyes = False +[Hacks] +EFBAccessEnable = False +BBoxEnable = False +ForceProgressive = True +EFBToTextureEnable = True +EFBScaledCopy = False +EFBEmulateFormatChanges = False +SkipDuplicateXFBs = True +XFBToTextureEnable = False diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SDM845/GamecubeControllerProfiles/GCPadNew.ini.east b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SDM845/GamecubeControllerProfiles/GCPadNew.ini.east new file mode 100644 index 0000000000..9389302558 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SDM845/GamecubeControllerProfiles/GCPadNew.ini.east @@ -0,0 +1,36 @@ +[GCPad1] +Device = evdev/0/Microsoft X-Box 360 pad +Buttons/A = Button 1 +Buttons/B = Button 0 +Buttons/Start = Button 7 +Buttons/X = Button 2 +Buttons/Y = Button 3 +Buttons/Z = Button 5 +Buttons/Hotkey = Button 6 +C-Stick/Dead Zone = 25.000000000000000 +C-Stick/Down = Axis 4+ +C-Stick/Left = Axis 3- +C-Stick/Modifier = Control_L +C-Stick/Modifier/Range = 50.000000000000000 +C-Stick/Right = Axis 3+ +C-Stick/Up = Axis 4- +D-Pad/Down = Axis 7+ +D-Pad/Left = Axis 6- +D-Pad/Right = Axis 6+ +D-Pad/Up = Axis 7- +Main Stick/Dead Zone = 25.000000000000000 +Main Stick/Down = Axis 1+ +Main Stick/Left = Axis 0- +Main Stick/Modifier = Shift_L +Main Stick/Modifier/Range = 50.000000000000000 +Main Stick/Right = Axis 0+ +Main Stick/Up = Axis 1- +Triggers/Dead Zone = 0. +Triggers/Threshold = 90. +Triggers/L = Axis 2+ +Triggers/R = Axis 5+ +Triggers/L-Analog = Axis 2+ +Triggers/R-Analog = Axis 5+ +Rumble/Motor = `evdev/0/Retroid Pocket Gamepad:Strong` +Triforce/Coin = Button 8 +Triforce/Service = Button 4 diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SDM845/GamecubeControllerProfiles/GCPadNew.ini.south b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SDM845/GamecubeControllerProfiles/GCPadNew.ini.south new file mode 100644 index 0000000000..20373880fd --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SDM845/GamecubeControllerProfiles/GCPadNew.ini.south @@ -0,0 +1,36 @@ +[GCPad1] +Device = evdev/0/Microsoft X-Box 360 pad +Buttons/A = Button 0 +Buttons/B = Button 3 +Buttons/Start = Button 7 +Buttons/X = Button 1 +Buttons/Y = Button 2 +Buttons/Z = Button 5 +Buttons/Hotkey = Button 6 +C-Stick/Dead Zone = 25.000000000000000 +C-Stick/Down = Axis 4+ +C-Stick/Left = Axis 3- +C-Stick/Modifier = Control_L +C-Stick/Modifier/Range = 50.000000000000000 +C-Stick/Right = Axis 3+ +C-Stick/Up = Axis 4- +D-Pad/Down = Axis 7+ +D-Pad/Left = Axis 6- +D-Pad/Right = Axis 6+ +D-Pad/Up = Axis 7- +Main Stick/Dead Zone = 25.000000000000000 +Main Stick/Down = Axis 1+ +Main Stick/Left = Axis 0- +Main Stick/Modifier = Shift_L +Main Stick/Modifier/Range = 50.000000000000000 +Main Stick/Right = Axis 0+ +Main Stick/Up = Axis 1- +Triggers/Dead Zone = 0. +Triggers/Threshold = 90. +Triggers/L = Axis 2+ +Triggers/R = Axis 5+ +Triggers/L-Analog = Axis 2+ +Triggers/R-Analog = Axis 5+ +Rumble/Motor = `evdev/0/Retroid Pocket Gamepad:Strong` +Triforce/Coin = Button 8 +Triforce/Service = Button 4 diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SDM845/Hotkeys.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SDM845/Hotkeys.ini new file mode 100644 index 0000000000..838c89f486 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SDM845/Hotkeys.ini @@ -0,0 +1,10 @@ +[Hotkeys] +Device = evdev/0/Microsoft X-Box 360 pad +Graphics Toggles/Toggle Aspect Ratio = @(MODE+EAST) +General/Take Screenshot = @(MODE+SOUTH) +Save State/Save to Selected Slot = @(MODE+TR) +Load State/Load State Slot 1 = @(MODE+TL) +Other State Hotkeys/Increase Selected State Slot = @(MODE+`Axis 7-`) +Other State Hotkeys/Decrease Selected State Slot = @(MODE+`Axis 7+`) +Emulation Speed/Increase Emulation Speed = @(MODE+`Full Axis 5+`) +Emulation Speed/Decrease Emulation Speed = @(MODE+`Full Axis 2+`) diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SDM845/WiiControllerProfiles/classic.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SDM845/WiiControllerProfiles/classic.ini new file mode 100644 index 0000000000..08839512ea --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SDM845/WiiControllerProfiles/classic.ini @@ -0,0 +1,28 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Extension = Classic +Source = 1 +Classic/Buttons/A = Button 1 +Classic/Buttons/B = Button 0 +Classic/Buttons/X = Button 2 +Classic/Buttons/Y = Button 3 +Classic/Buttons/ZL = Axis 2+ +Classic/Buttons/ZR = Axis 5+ +Classic/Buttons/- = Button 6 +Classic/Buttons/+ = Button 7 +Classic/Buttons/Home = Button 8 +Classic/Left Stick/Up = Axis 1- +Classic/Left Stick/Down = Axis 1+ +Classic/Left Stick/Left = Axis 0- +Classic/Left Stick/Right = Axis 0+ +Classic/Right Stick/Up = Axis 4- +Classic/Right Stick/Down = Axis 4+ +Classic/Right Stick/Left = Axis 3- +Classic/Right Stick/Right = Axis 3+ +Classic/Triggers/L = Button 4 +Classic/Triggers/R = Button 5 +Classic/D-Pad/Up = Axis 7- +Classic/D-Pad/Down = Axis 7+ +Classic/D-Pad/Left = Axis 6- +Classic/D-Pad/Right = Axis 6+ +Rumble/Motor = `evdev/0/Retroid Pocket Gamepad:Strong` diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SDM845/WiiControllerProfiles/hremote.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SDM845/WiiControllerProfiles/hremote.ini new file mode 100644 index 0000000000..7514cde014 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SDM845/WiiControllerProfiles/hremote.ini @@ -0,0 +1,21 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Buttons/A = Button 3 +Buttons/B = Button 2 +Buttons/1 = Button 0 +Buttons/2 = Button 1 +Buttons/- = Button 6 +Buttons/+ = Button 7 +Buttons/Home = Button 8 +Shake/X = Button 4 +Shake/Y = Button 4 +Shake/Z = Button 4 +D-Pad/Up = `Axis 6-` | `Axis 0-` +D-Pad/Down = `Axis 6+` | `Axis 0+` +D-Pad/Left = `Axis 7+` | `Axis 1+` +D-Pad/Right = `Axis 7-` | `Axis 1-` +IR/Up = `Axis 4-` +IR/Down = `Axis 4+` +IR/Left = `Axis 3-` +IR/Right = `Axis 3+` +Rumble/Motor = `evdev/0/Retroid Pocket Gamepad:Strong` diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SDM845/WiiControllerProfiles/nunchuck.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SDM845/WiiControllerProfiles/nunchuck.ini new file mode 100644 index 0000000000..83b23d7eb3 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SDM845/WiiControllerProfiles/nunchuck.ini @@ -0,0 +1,31 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Extension = Nunchuk +Buttons/A = Button 1 +Buttons/B = Button 0 +Buttons/1 = Button 3 +Buttons/2 = Button 2 +Buttons/- = Button 6 +Buttons/+ = Button 7 +D-Pad/Up = Axis 7- +D-Pad/Down = Axis 7+ +D-Pad/Left = Axis 6- +D-Pad/Right = Axis 6+ +Buttons/Home = Button 8 +Shake/X = Button 4 +Shake/Y = Button 4 +Shake/Z = Button 4 +Nunchuk/Buttons/C = Button 5 +Nunchuk/Buttons/Z = Axis 5+ +Nunchuk/Stick/Up = Axis 1- +Nunchuk/Stick/Down = Axis 1+ +Nunchuk/Stick/Left = Axis 0- +Nunchuk/Stick/Right = Axis 0+ +Nunchuk/Shake/X = Axis 2+ +Nunchuk/Shake/Y = Axis 2+ +Nunchuk/Shake/Z = Axis 2+ +IR/Up = `Axis 4-` +IR/Down = `Axis 4+` +IR/Left = `Axis 3-` +IR/Right = `Axis 3+` +Rumble/Motor = `evdev/0/Retroid Pocket Gamepad:Strong` diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SDM845/WiiControllerProfiles/vremote.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SDM845/WiiControllerProfiles/vremote.ini new file mode 100644 index 0000000000..cea8ee0448 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SDM845/WiiControllerProfiles/vremote.ini @@ -0,0 +1,21 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Buttons/A = Button 1 +Buttons/B = Button 0 +Buttons/1 = Button 3 +Buttons/2 = Button 2 +Buttons/- = Button 6 +Buttons/+ = Button 7 +Buttons/Home = Button 8 +Shake/X = Button 4 +Shake/Y = Button 4 +Shake/Z = Button 4 +D-Pad/Up = `Axis 7-` | `Axis 1-` +D-Pad/Down = `Axis 7+` | `Axis 1+` +D-Pad/Left = `Axis 6-` | `Axis 0-` +D-Pad/Right = `Axis 6+` | `Axis 0+` +IR/Up = `Axis 4-` +IR/Down = `Axis 4+` +IR/Left = `Axis 3-` +IR/Right = `Axis 3+` +Rumble/Motor = `evdev/0/Retroid Pocket Gamepad:Strong` diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8250/Dolphin.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8250/Dolphin.ini new file mode 100644 index 0000000000..823db4700a --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8250/Dolphin.ini @@ -0,0 +1,154 @@ +[General] +LastFilename = +ShowLag = False +ShowFrameCount = False +ISOPath0 = /storage/roms/gamecube +ISOPath1 = /storage/roms/wii +ISOPaths = 2 +RecursiveISOPaths = False +NANDRootPath = +WirelessMac = +[Interface] +ConfirmStop = True +UsePanicHandlers = True +OnScreenDisplayMessages = True +HideCursor = False +AutoHideCursor = False +MainWindowPosX = 403 +MainWindowPosY = 148 +MainWindowWidth = 800 +MainWindowHeight = 600 +Language = 0 +ShowToolbar = True +ShowStatusbar = True +ShowLogWindow = False +ShowLogConfigWindow = False +ExtendedFPSInfo = False +ThemeName40 = Clean Blue +PauseOnFocusLost = False +[Display] +FullscreenResolution = Auto +Fullscreen = True +RenderToMain = False +RenderWindowXPos = -1 +RenderWindowYPos = -1 +RenderWindowWidth = 640 +RenderWindowHeight = 480 +RenderWindowAutoSize = False +KeepWindowOnTop = False +ProgressiveScan = False +PAL60 = True +DisableScreenSaver = True +ForceNTSCJ = False +[GameList] +ListDrives = False +ListWad = True +ListElfDol = True +ListWii = True +ListGC = True +ListJap = True +ListPal = True +ListUsa = True +ListAustralia = True +ListFrance = True +ListGermany = True +ListItaly = True +ListKorea = True +ListNetherlands = True +ListRussia = True +ListSpain = True +ListTaiwan = True +ListWorld = True +ListUnknown = True +ListSort = 3 +ListSortSecondary = 0 +ColorCompressed = True +ColumnPlatform = True +ColumnBanner = True +ColumnNotes = True +ColumnFileName = False +ColumnID = False +ColumnRegion = True +ColumnSize = True +ColumnState = True +[Core] +SkipIPL = True +HLE_BS2 = False +TimingVariance = 40 +CPUCore = 4 +Fastmem = True +CPUThread = True +DSPHLE = True +SkipIdle = True +SyncOnSkipIdle = False +SyncGPU = False +SyncGpuMaxDistance = 200000 +SyncGpuMinDistance = -200000 +SyncGpuOverclock = 1.00000000 +FPRF = False +AccurateNaNs = False +DefaultISO = +DVDRoot = +Apploader = +EnableCheats = True +SelectedLanguage = 0 +OverrideGCLang = False +DPL2Decoder = False +Latency = 2 +MemcardAPath = +MemcardBPath = +AgpCartAPath = +AgpCartBPath = +GCIFolderAPath = /storage/roms/bios/GC/USA +SlotA = 1 +SlotB = 255 +SerialPort1 = 255 +BBA_MAC = +SIDevice0 = 6 +AdapterRumble0 = True +SimulateKonga0 = False +SIDevice1 = 6 +AdapterRumble1 = True +SimulateKonga1 = False +SIDevice2 = 0 +AdapterRumble2 = True +SimulateKonga2 = False +SIDevice3 = 0 +AdapterRumble3 = True +SimulateKonga3 = False +WiiSDCard = False +WiiKeyboard = False +WiimoteContinuousScanning = False +WiimoteEnableSpeaker = False +RunCompareServer = False +RunCompareClient = False +EmulationSpeed = 1.00000000 +FrameSkip = 0x00000003 +Overclock = 1.0 +OverclockEnable = False +GFXBackend = Vulkan +GPUDeterminismMode = auto +PerfMapDir = +AutoDiscChange = True +[Movie] +PauseMovie = False +Author = +DumpFrames = False +DumpFramesSilent = False +ShowInputDisplay = False +[DSP] +EnableJIT = True +DumpAudio = False +DumpUCode = False +Backend = Pulse +Volume = 100 +CaptureLog = False +DSPThread = True +[Input] +BackgroundInput = False +[FifoPlayer] +LoopReplay = True +[Analytics] +ID = 5082f0c30a7e422b1220107f69d6c108 +Enabled = False +PermissionAsked = True diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8250/GFX.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8250/GFX.ini new file mode 100644 index 0000000000..ad0f286a21 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8250/GFX.ini @@ -0,0 +1,62 @@ +[Hardware] +VSync = False +Adapter = 0 +[Settings] +AspectRatio = 0 +InternalResolution = 2 +Crop = False +wideScreenHack = False +UseXFB = False +UseRealXFB = False +SafeTextureCacheColorSamples = 128 +ShowFPS = False +LogRenderTimeToFile = False +OverlayStats = False +OverlayProjStats = False +DumpTextures = False +HiresTextures = False +ConvertHiresTextures = False +CacheHiresTextures = False +DumpEFBTarget = False +FreeLook = False +UseFFV1 = False +EnablePixelLighting = False +FastDepthCalc = True +MSAA = 1 +SSAA = False +EFBScale = 2 +TexFmtOverlayEnable = False +TexFmtOverlayCenter = False +Wireframe = False +DisableFog = False +EnableShaderDebugging = False +BorderlessFullscreen = False +SWZComploc = True +SWZFreeze = True +SWDumpObjects = False +SWDumpTevStages = False +SWDumpTevTexFetches = False +SWDrawStart = 0 +SWDrawEnd = 100000 +ShaderCompilationMode = 0 +WaitForShadersBeforeStarting = True +BackendMultithreading = True +EnableGPUTextureDecoding = True +[Enhancements] +ForceTextureFiltering = False +MaxAnisotropy = 0 +PostProcessingShader = +[Stereoscopy] +StereoMode = 0 +StereoDepth = 20 +StereoConvergencePercentage = 100 +StereoSwapEyes = False +[Hacks] +EFBAccessEnable = False +BBoxEnable = False +ForceProgressive = True +EFBToTextureEnable = True +EFBScaledCopy = False +EFBEmulateFormatChanges = False +SkipDuplicateXFBs = True +XFBToTextureEnable = False diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8250/GamecubeControllerProfiles/GCPadNew.ini.east b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8250/GamecubeControllerProfiles/GCPadNew.ini.east new file mode 100644 index 0000000000..9389302558 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8250/GamecubeControllerProfiles/GCPadNew.ini.east @@ -0,0 +1,36 @@ +[GCPad1] +Device = evdev/0/Microsoft X-Box 360 pad +Buttons/A = Button 1 +Buttons/B = Button 0 +Buttons/Start = Button 7 +Buttons/X = Button 2 +Buttons/Y = Button 3 +Buttons/Z = Button 5 +Buttons/Hotkey = Button 6 +C-Stick/Dead Zone = 25.000000000000000 +C-Stick/Down = Axis 4+ +C-Stick/Left = Axis 3- +C-Stick/Modifier = Control_L +C-Stick/Modifier/Range = 50.000000000000000 +C-Stick/Right = Axis 3+ +C-Stick/Up = Axis 4- +D-Pad/Down = Axis 7+ +D-Pad/Left = Axis 6- +D-Pad/Right = Axis 6+ +D-Pad/Up = Axis 7- +Main Stick/Dead Zone = 25.000000000000000 +Main Stick/Down = Axis 1+ +Main Stick/Left = Axis 0- +Main Stick/Modifier = Shift_L +Main Stick/Modifier/Range = 50.000000000000000 +Main Stick/Right = Axis 0+ +Main Stick/Up = Axis 1- +Triggers/Dead Zone = 0. +Triggers/Threshold = 90. +Triggers/L = Axis 2+ +Triggers/R = Axis 5+ +Triggers/L-Analog = Axis 2+ +Triggers/R-Analog = Axis 5+ +Rumble/Motor = `evdev/0/Retroid Pocket Gamepad:Strong` +Triforce/Coin = Button 8 +Triforce/Service = Button 4 diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8250/GamecubeControllerProfiles/GCPadNew.ini.south b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8250/GamecubeControllerProfiles/GCPadNew.ini.south new file mode 100644 index 0000000000..20373880fd --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8250/GamecubeControllerProfiles/GCPadNew.ini.south @@ -0,0 +1,36 @@ +[GCPad1] +Device = evdev/0/Microsoft X-Box 360 pad +Buttons/A = Button 0 +Buttons/B = Button 3 +Buttons/Start = Button 7 +Buttons/X = Button 1 +Buttons/Y = Button 2 +Buttons/Z = Button 5 +Buttons/Hotkey = Button 6 +C-Stick/Dead Zone = 25.000000000000000 +C-Stick/Down = Axis 4+ +C-Stick/Left = Axis 3- +C-Stick/Modifier = Control_L +C-Stick/Modifier/Range = 50.000000000000000 +C-Stick/Right = Axis 3+ +C-Stick/Up = Axis 4- +D-Pad/Down = Axis 7+ +D-Pad/Left = Axis 6- +D-Pad/Right = Axis 6+ +D-Pad/Up = Axis 7- +Main Stick/Dead Zone = 25.000000000000000 +Main Stick/Down = Axis 1+ +Main Stick/Left = Axis 0- +Main Stick/Modifier = Shift_L +Main Stick/Modifier/Range = 50.000000000000000 +Main Stick/Right = Axis 0+ +Main Stick/Up = Axis 1- +Triggers/Dead Zone = 0. +Triggers/Threshold = 90. +Triggers/L = Axis 2+ +Triggers/R = Axis 5+ +Triggers/L-Analog = Axis 2+ +Triggers/R-Analog = Axis 5+ +Rumble/Motor = `evdev/0/Retroid Pocket Gamepad:Strong` +Triforce/Coin = Button 8 +Triforce/Service = Button 4 diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8250/Hotkeys.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8250/Hotkeys.ini new file mode 100644 index 0000000000..838c89f486 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8250/Hotkeys.ini @@ -0,0 +1,10 @@ +[Hotkeys] +Device = evdev/0/Microsoft X-Box 360 pad +Graphics Toggles/Toggle Aspect Ratio = @(MODE+EAST) +General/Take Screenshot = @(MODE+SOUTH) +Save State/Save to Selected Slot = @(MODE+TR) +Load State/Load State Slot 1 = @(MODE+TL) +Other State Hotkeys/Increase Selected State Slot = @(MODE+`Axis 7-`) +Other State Hotkeys/Decrease Selected State Slot = @(MODE+`Axis 7+`) +Emulation Speed/Increase Emulation Speed = @(MODE+`Full Axis 5+`) +Emulation Speed/Decrease Emulation Speed = @(MODE+`Full Axis 2+`) diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8250/WiiControllerProfiles/classic.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8250/WiiControllerProfiles/classic.ini new file mode 100644 index 0000000000..08839512ea --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8250/WiiControllerProfiles/classic.ini @@ -0,0 +1,28 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Extension = Classic +Source = 1 +Classic/Buttons/A = Button 1 +Classic/Buttons/B = Button 0 +Classic/Buttons/X = Button 2 +Classic/Buttons/Y = Button 3 +Classic/Buttons/ZL = Axis 2+ +Classic/Buttons/ZR = Axis 5+ +Classic/Buttons/- = Button 6 +Classic/Buttons/+ = Button 7 +Classic/Buttons/Home = Button 8 +Classic/Left Stick/Up = Axis 1- +Classic/Left Stick/Down = Axis 1+ +Classic/Left Stick/Left = Axis 0- +Classic/Left Stick/Right = Axis 0+ +Classic/Right Stick/Up = Axis 4- +Classic/Right Stick/Down = Axis 4+ +Classic/Right Stick/Left = Axis 3- +Classic/Right Stick/Right = Axis 3+ +Classic/Triggers/L = Button 4 +Classic/Triggers/R = Button 5 +Classic/D-Pad/Up = Axis 7- +Classic/D-Pad/Down = Axis 7+ +Classic/D-Pad/Left = Axis 6- +Classic/D-Pad/Right = Axis 6+ +Rumble/Motor = `evdev/0/Retroid Pocket Gamepad:Strong` diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8250/WiiControllerProfiles/hremote.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8250/WiiControllerProfiles/hremote.ini new file mode 100644 index 0000000000..7514cde014 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8250/WiiControllerProfiles/hremote.ini @@ -0,0 +1,21 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Buttons/A = Button 3 +Buttons/B = Button 2 +Buttons/1 = Button 0 +Buttons/2 = Button 1 +Buttons/- = Button 6 +Buttons/+ = Button 7 +Buttons/Home = Button 8 +Shake/X = Button 4 +Shake/Y = Button 4 +Shake/Z = Button 4 +D-Pad/Up = `Axis 6-` | `Axis 0-` +D-Pad/Down = `Axis 6+` | `Axis 0+` +D-Pad/Left = `Axis 7+` | `Axis 1+` +D-Pad/Right = `Axis 7-` | `Axis 1-` +IR/Up = `Axis 4-` +IR/Down = `Axis 4+` +IR/Left = `Axis 3-` +IR/Right = `Axis 3+` +Rumble/Motor = `evdev/0/Retroid Pocket Gamepad:Strong` diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8250/WiiControllerProfiles/nunchuck.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8250/WiiControllerProfiles/nunchuck.ini new file mode 100644 index 0000000000..83b23d7eb3 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8250/WiiControllerProfiles/nunchuck.ini @@ -0,0 +1,31 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Extension = Nunchuk +Buttons/A = Button 1 +Buttons/B = Button 0 +Buttons/1 = Button 3 +Buttons/2 = Button 2 +Buttons/- = Button 6 +Buttons/+ = Button 7 +D-Pad/Up = Axis 7- +D-Pad/Down = Axis 7+ +D-Pad/Left = Axis 6- +D-Pad/Right = Axis 6+ +Buttons/Home = Button 8 +Shake/X = Button 4 +Shake/Y = Button 4 +Shake/Z = Button 4 +Nunchuk/Buttons/C = Button 5 +Nunchuk/Buttons/Z = Axis 5+ +Nunchuk/Stick/Up = Axis 1- +Nunchuk/Stick/Down = Axis 1+ +Nunchuk/Stick/Left = Axis 0- +Nunchuk/Stick/Right = Axis 0+ +Nunchuk/Shake/X = Axis 2+ +Nunchuk/Shake/Y = Axis 2+ +Nunchuk/Shake/Z = Axis 2+ +IR/Up = `Axis 4-` +IR/Down = `Axis 4+` +IR/Left = `Axis 3-` +IR/Right = `Axis 3+` +Rumble/Motor = `evdev/0/Retroid Pocket Gamepad:Strong` diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8250/WiiControllerProfiles/vremote.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8250/WiiControllerProfiles/vremote.ini new file mode 100644 index 0000000000..cea8ee0448 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8250/WiiControllerProfiles/vremote.ini @@ -0,0 +1,21 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Buttons/A = Button 1 +Buttons/B = Button 0 +Buttons/1 = Button 3 +Buttons/2 = Button 2 +Buttons/- = Button 6 +Buttons/+ = Button 7 +Buttons/Home = Button 8 +Shake/X = Button 4 +Shake/Y = Button 4 +Shake/Z = Button 4 +D-Pad/Up = `Axis 7-` | `Axis 1-` +D-Pad/Down = `Axis 7+` | `Axis 1+` +D-Pad/Left = `Axis 6-` | `Axis 0-` +D-Pad/Right = `Axis 6+` | `Axis 0+` +IR/Up = `Axis 4-` +IR/Down = `Axis 4+` +IR/Left = `Axis 3-` +IR/Right = `Axis 3+` +Rumble/Motor = `evdev/0/Retroid Pocket Gamepad:Strong` diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8550/Dolphin.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8550/Dolphin.ini new file mode 100644 index 0000000000..823db4700a --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8550/Dolphin.ini @@ -0,0 +1,154 @@ +[General] +LastFilename = +ShowLag = False +ShowFrameCount = False +ISOPath0 = /storage/roms/gamecube +ISOPath1 = /storage/roms/wii +ISOPaths = 2 +RecursiveISOPaths = False +NANDRootPath = +WirelessMac = +[Interface] +ConfirmStop = True +UsePanicHandlers = True +OnScreenDisplayMessages = True +HideCursor = False +AutoHideCursor = False +MainWindowPosX = 403 +MainWindowPosY = 148 +MainWindowWidth = 800 +MainWindowHeight = 600 +Language = 0 +ShowToolbar = True +ShowStatusbar = True +ShowLogWindow = False +ShowLogConfigWindow = False +ExtendedFPSInfo = False +ThemeName40 = Clean Blue +PauseOnFocusLost = False +[Display] +FullscreenResolution = Auto +Fullscreen = True +RenderToMain = False +RenderWindowXPos = -1 +RenderWindowYPos = -1 +RenderWindowWidth = 640 +RenderWindowHeight = 480 +RenderWindowAutoSize = False +KeepWindowOnTop = False +ProgressiveScan = False +PAL60 = True +DisableScreenSaver = True +ForceNTSCJ = False +[GameList] +ListDrives = False +ListWad = True +ListElfDol = True +ListWii = True +ListGC = True +ListJap = True +ListPal = True +ListUsa = True +ListAustralia = True +ListFrance = True +ListGermany = True +ListItaly = True +ListKorea = True +ListNetherlands = True +ListRussia = True +ListSpain = True +ListTaiwan = True +ListWorld = True +ListUnknown = True +ListSort = 3 +ListSortSecondary = 0 +ColorCompressed = True +ColumnPlatform = True +ColumnBanner = True +ColumnNotes = True +ColumnFileName = False +ColumnID = False +ColumnRegion = True +ColumnSize = True +ColumnState = True +[Core] +SkipIPL = True +HLE_BS2 = False +TimingVariance = 40 +CPUCore = 4 +Fastmem = True +CPUThread = True +DSPHLE = True +SkipIdle = True +SyncOnSkipIdle = False +SyncGPU = False +SyncGpuMaxDistance = 200000 +SyncGpuMinDistance = -200000 +SyncGpuOverclock = 1.00000000 +FPRF = False +AccurateNaNs = False +DefaultISO = +DVDRoot = +Apploader = +EnableCheats = True +SelectedLanguage = 0 +OverrideGCLang = False +DPL2Decoder = False +Latency = 2 +MemcardAPath = +MemcardBPath = +AgpCartAPath = +AgpCartBPath = +GCIFolderAPath = /storage/roms/bios/GC/USA +SlotA = 1 +SlotB = 255 +SerialPort1 = 255 +BBA_MAC = +SIDevice0 = 6 +AdapterRumble0 = True +SimulateKonga0 = False +SIDevice1 = 6 +AdapterRumble1 = True +SimulateKonga1 = False +SIDevice2 = 0 +AdapterRumble2 = True +SimulateKonga2 = False +SIDevice3 = 0 +AdapterRumble3 = True +SimulateKonga3 = False +WiiSDCard = False +WiiKeyboard = False +WiimoteContinuousScanning = False +WiimoteEnableSpeaker = False +RunCompareServer = False +RunCompareClient = False +EmulationSpeed = 1.00000000 +FrameSkip = 0x00000003 +Overclock = 1.0 +OverclockEnable = False +GFXBackend = Vulkan +GPUDeterminismMode = auto +PerfMapDir = +AutoDiscChange = True +[Movie] +PauseMovie = False +Author = +DumpFrames = False +DumpFramesSilent = False +ShowInputDisplay = False +[DSP] +EnableJIT = True +DumpAudio = False +DumpUCode = False +Backend = Pulse +Volume = 100 +CaptureLog = False +DSPThread = True +[Input] +BackgroundInput = False +[FifoPlayer] +LoopReplay = True +[Analytics] +ID = 5082f0c30a7e422b1220107f69d6c108 +Enabled = False +PermissionAsked = True diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8550/GFX.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8550/GFX.ini new file mode 100644 index 0000000000..ad0f286a21 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8550/GFX.ini @@ -0,0 +1,62 @@ +[Hardware] +VSync = False +Adapter = 0 +[Settings] +AspectRatio = 0 +InternalResolution = 2 +Crop = False +wideScreenHack = False +UseXFB = False +UseRealXFB = False +SafeTextureCacheColorSamples = 128 +ShowFPS = False +LogRenderTimeToFile = False +OverlayStats = False +OverlayProjStats = False +DumpTextures = False +HiresTextures = False +ConvertHiresTextures = False +CacheHiresTextures = False +DumpEFBTarget = False +FreeLook = False +UseFFV1 = False +EnablePixelLighting = False +FastDepthCalc = True +MSAA = 1 +SSAA = False +EFBScale = 2 +TexFmtOverlayEnable = False +TexFmtOverlayCenter = False +Wireframe = False +DisableFog = False +EnableShaderDebugging = False +BorderlessFullscreen = False +SWZComploc = True +SWZFreeze = True +SWDumpObjects = False +SWDumpTevStages = False +SWDumpTevTexFetches = False +SWDrawStart = 0 +SWDrawEnd = 100000 +ShaderCompilationMode = 0 +WaitForShadersBeforeStarting = True +BackendMultithreading = True +EnableGPUTextureDecoding = True +[Enhancements] +ForceTextureFiltering = False +MaxAnisotropy = 0 +PostProcessingShader = +[Stereoscopy] +StereoMode = 0 +StereoDepth = 20 +StereoConvergencePercentage = 100 +StereoSwapEyes = False +[Hacks] +EFBAccessEnable = False +BBoxEnable = False +ForceProgressive = True +EFBToTextureEnable = True +EFBScaledCopy = False +EFBEmulateFormatChanges = False +SkipDuplicateXFBs = True +XFBToTextureEnable = False diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8550/GamecubeControllerProfiles b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8550/GamecubeControllerProfiles new file mode 120000 index 0000000000..adef25610d --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8550/GamecubeControllerProfiles @@ -0,0 +1 @@ +../InputPlumber/GamecubeControllerProfiles \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8550/Hotkeys.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8550/Hotkeys.ini new file mode 120000 index 0000000000..d65ca4e2bd --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8550/Hotkeys.ini @@ -0,0 +1 @@ +../InputPlumber/Hotkeys.ini \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8550/WiiControllerProfiles b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8550/WiiControllerProfiles new file mode 120000 index 0000000000..d0c169d967 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8550/WiiControllerProfiles @@ -0,0 +1 @@ +../InputPlumber/WiiControllerProfiles \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8650/Dolphin.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8650/Dolphin.ini new file mode 100644 index 0000000000..823db4700a --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8650/Dolphin.ini @@ -0,0 +1,154 @@ +[General] +LastFilename = +ShowLag = False +ShowFrameCount = False +ISOPath0 = /storage/roms/gamecube +ISOPath1 = /storage/roms/wii +ISOPaths = 2 +RecursiveISOPaths = False +NANDRootPath = +WirelessMac = +[Interface] +ConfirmStop = True +UsePanicHandlers = True +OnScreenDisplayMessages = True +HideCursor = False +AutoHideCursor = False +MainWindowPosX = 403 +MainWindowPosY = 148 +MainWindowWidth = 800 +MainWindowHeight = 600 +Language = 0 +ShowToolbar = True +ShowStatusbar = True +ShowLogWindow = False +ShowLogConfigWindow = False +ExtendedFPSInfo = False +ThemeName40 = Clean Blue +PauseOnFocusLost = False +[Display] +FullscreenResolution = Auto +Fullscreen = True +RenderToMain = False +RenderWindowXPos = -1 +RenderWindowYPos = -1 +RenderWindowWidth = 640 +RenderWindowHeight = 480 +RenderWindowAutoSize = False +KeepWindowOnTop = False +ProgressiveScan = False +PAL60 = True +DisableScreenSaver = True +ForceNTSCJ = False +[GameList] +ListDrives = False +ListWad = True +ListElfDol = True +ListWii = True +ListGC = True +ListJap = True +ListPal = True +ListUsa = True +ListAustralia = True +ListFrance = True +ListGermany = True +ListItaly = True +ListKorea = True +ListNetherlands = True +ListRussia = True +ListSpain = True +ListTaiwan = True +ListWorld = True +ListUnknown = True +ListSort = 3 +ListSortSecondary = 0 +ColorCompressed = True +ColumnPlatform = True +ColumnBanner = True +ColumnNotes = True +ColumnFileName = False +ColumnID = False +ColumnRegion = True +ColumnSize = True +ColumnState = True +[Core] +SkipIPL = True +HLE_BS2 = False +TimingVariance = 40 +CPUCore = 4 +Fastmem = True +CPUThread = True +DSPHLE = True +SkipIdle = True +SyncOnSkipIdle = False +SyncGPU = False +SyncGpuMaxDistance = 200000 +SyncGpuMinDistance = -200000 +SyncGpuOverclock = 1.00000000 +FPRF = False +AccurateNaNs = False +DefaultISO = +DVDRoot = +Apploader = +EnableCheats = True +SelectedLanguage = 0 +OverrideGCLang = False +DPL2Decoder = False +Latency = 2 +MemcardAPath = +MemcardBPath = +AgpCartAPath = +AgpCartBPath = +GCIFolderAPath = /storage/roms/bios/GC/USA +SlotA = 1 +SlotB = 255 +SerialPort1 = 255 +BBA_MAC = +SIDevice0 = 6 +AdapterRumble0 = True +SimulateKonga0 = False +SIDevice1 = 6 +AdapterRumble1 = True +SimulateKonga1 = False +SIDevice2 = 0 +AdapterRumble2 = True +SimulateKonga2 = False +SIDevice3 = 0 +AdapterRumble3 = True +SimulateKonga3 = False +WiiSDCard = False +WiiKeyboard = False +WiimoteContinuousScanning = False +WiimoteEnableSpeaker = False +RunCompareServer = False +RunCompareClient = False +EmulationSpeed = 1.00000000 +FrameSkip = 0x00000003 +Overclock = 1.0 +OverclockEnable = False +GFXBackend = Vulkan +GPUDeterminismMode = auto +PerfMapDir = +AutoDiscChange = True +[Movie] +PauseMovie = False +Author = +DumpFrames = False +DumpFramesSilent = False +ShowInputDisplay = False +[DSP] +EnableJIT = True +DumpAudio = False +DumpUCode = False +Backend = Pulse +Volume = 100 +CaptureLog = False +DSPThread = True +[Input] +BackgroundInput = False +[FifoPlayer] +LoopReplay = True +[Analytics] +ID = 5082f0c30a7e422b1220107f69d6c108 +Enabled = False +PermissionAsked = True diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8650/GFX.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8650/GFX.ini new file mode 100644 index 0000000000..ad0f286a21 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8650/GFX.ini @@ -0,0 +1,62 @@ +[Hardware] +VSync = False +Adapter = 0 +[Settings] +AspectRatio = 0 +InternalResolution = 2 +Crop = False +wideScreenHack = False +UseXFB = False +UseRealXFB = False +SafeTextureCacheColorSamples = 128 +ShowFPS = False +LogRenderTimeToFile = False +OverlayStats = False +OverlayProjStats = False +DumpTextures = False +HiresTextures = False +ConvertHiresTextures = False +CacheHiresTextures = False +DumpEFBTarget = False +FreeLook = False +UseFFV1 = False +EnablePixelLighting = False +FastDepthCalc = True +MSAA = 1 +SSAA = False +EFBScale = 2 +TexFmtOverlayEnable = False +TexFmtOverlayCenter = False +Wireframe = False +DisableFog = False +EnableShaderDebugging = False +BorderlessFullscreen = False +SWZComploc = True +SWZFreeze = True +SWDumpObjects = False +SWDumpTevStages = False +SWDumpTevTexFetches = False +SWDrawStart = 0 +SWDrawEnd = 100000 +ShaderCompilationMode = 0 +WaitForShadersBeforeStarting = True +BackendMultithreading = True +EnableGPUTextureDecoding = True +[Enhancements] +ForceTextureFiltering = False +MaxAnisotropy = 0 +PostProcessingShader = +[Stereoscopy] +StereoMode = 0 +StereoDepth = 20 +StereoConvergencePercentage = 100 +StereoSwapEyes = False +[Hacks] +EFBAccessEnable = False +BBoxEnable = False +ForceProgressive = True +EFBToTextureEnable = True +EFBScaledCopy = False +EFBEmulateFormatChanges = False +SkipDuplicateXFBs = True +XFBToTextureEnable = False diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8650/GamecubeControllerProfiles b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8650/GamecubeControllerProfiles new file mode 120000 index 0000000000..adef25610d --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8650/GamecubeControllerProfiles @@ -0,0 +1 @@ +../InputPlumber/GamecubeControllerProfiles \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8650/Hotkeys.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8650/Hotkeys.ini new file mode 120000 index 0000000000..d65ca4e2bd --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8650/Hotkeys.ini @@ -0,0 +1 @@ +../InputPlumber/Hotkeys.ini \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8650/WiiControllerProfiles b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8650/WiiControllerProfiles new file mode 120000 index 0000000000..d0c169d967 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/config/SM8650/WiiControllerProfiles @@ -0,0 +1 @@ +../InputPlumber/WiiControllerProfiles \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/package.mk b/projects/ArchR/packages/emulators/standalone/dolphin-sa/package.mk new file mode 100644 index 0000000000..d60865be4c --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/package.mk @@ -0,0 +1,122 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="dolphin-sa" +PKG_LICENSE="GPLv2" +PKG_DEPENDS_TARGET="toolchain libevdev libdrm ffmpeg zlib libpng lzo libusb zstd ecm openal-soft pulseaudio alsa-lib libfmt hidapi curl" +PKG_LONGDESC="Dolphin is a GameCube / Wii / Triforce emulator, allowing you to play games for these two platforms on PC with improvements. " +PKG_TOOLCHAIN="cmake" + +case ${DEVICE} in + SM8250|SM8550|SDM845|RK3399|SM8650) + PKG_VERSION="9323074ada4b1d372809dc71ed092efe8d0e4c8e" + PKG_SITE="https://github.com/dolphin-emu/dolphin" + PKG_URL="${PKG_SITE}.git" + PKG_DEPENDS_TARGET+=" qt6" + PKG_PATCH_DIRS+=" qt6" + PKG_CMAKE_OPTS_TARGET+=" -DENABLE_QT=ON \ + -DUSE_RETRO_ACHIEVEMENTS=ON \ + -DENABLE_HEADLESS=OFF \ + -DCMAKE_EXE_LINKER_FLAGS=-flto=$(nproc)" + ;; + *) + PKG_VERSION="e6583f8bec814d8f3748f1d7738457600ce0de56" + PKG_SITE="https://github.com/dolphin-emu/dolphin" + PKG_URL="${PKG_SITE}.git" + PKG_PATCH_DIRS+=" wayland" + PKG_CMAKE_OPTS_TARGET+=" -DENABLE_QT=OFF \ + -DENABLE_WAYLAND=ON \ + -DUSE_RETRO_ACHIEVEMENTS=OFF \ + -DENABLE_HEADLESS=ON" + ;; +esac + +if [ "${OPENGL_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" + PKG_CMAKE_OPTS_TARGET+=" -DENABLE_EGL=ON" +elif [ "${OPENGLES_SUPPORT}" = yes ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" + PKG_CMAKE_OPTS_TARGET+=" -DENABLE_EGL=ON" +fi + +if [ "${DISPLAYSERVER}" = "wl" ]; then + PKG_DEPENDS_TARGET+=" wayland ${WINDOWMANAGER} xwayland xrandr libXi" + PKG_CMAKE_OPTS_TARGET+=" -DENABLE_X11=ON" +else + PKG_CMAKE_OPTS_TARGET+=" -DENABLE_X11=OFF" +fi + +if [ "${VULKAN_SUPPORT}" = "yes" ] +then + PKG_DEPENDS_TARGET+=" ${VULKAN}" + PKG_CMAKE_OPTS_TARGET+=" -DENABLE_VULKAN=ON" + GRENDERER="Vulkan" +else + PKG_CMAKE_OPTS_TARGET+=" -DENABLE_VULKAN=OFF" + GRENDERER="OGL" +fi + +pre_configure_target() { + PKG_CMAKE_OPTS_TARGET+=" -DCMAKE_BUILD_TYPE=Release \ + -DDISTRIBUTOR="ArchR" \ + -DENABLE_NOGUI=ON \ + -DENABLE_EVDEV=ON \ + -DUSE_DISCORD_PRESENCE=OFF \ + -DBUILD_SHARED_LIBS=OFF \ + -DLINUX_LOCAL_DEV=OFF \ + -DENABLE_PULSEAUDIO=ON \ + -DENABLE_ALSA=ON \ + -DENABLE_TESTS=OFF \ + -DENABLE_LLVM=OFF \ + -DENABLE_ANALYTICS=OFF \ + -DENABLE_LTO=ON \ + -DENCODE_FRAMEDUMPS=OFF \ + -DENABLE_AUTOUPDATE=OFF \ + -DUSE_MGBA=OFF \ + -DENABLE_CLI_TOOL=OFF \ + -DCMAKE_POLICY_VERSION_MINIMUM=3.5" + + sed -i 's~#include ~#include \n#include ~g' ${PKG_BUILD}/Externals/VulkanMemoryAllocator/include/vk_mem_alloc.h + sed -i 's~#include ~#include \n#include ~g' ${PKG_BUILD}/Externals/VulkanMemoryAllocator/include/vk_mem_alloc.h +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp -rf ${PKG_BUILD}/.${TARGET_NAME}/Binaries/dolphin* ${INSTALL}/usr/bin + cp -rf ${PKG_DIR}/scripts/* ${INSTALL}/usr/bin + + chmod +x ${INSTALL}/usr/bin/* + + mkdir -p ${INSTALL}/usr/config/dolphin-emu + cp -rf ${PKG_BUILD}/Data/Sys/* ${INSTALL}/usr/config/dolphin-emu + cp -rfH ${PKG_DIR}/config/${DEVICE}/* ${INSTALL}/usr/config/dolphin-emu + cp -rf ${PKG_DIR}/triforce ${INSTALL}/usr/config/dolphin-emu/triforce_gecko_codes +} + +post_install() { + case ${DEVICE} in + RK3588) + DOLPHIN_BACKEND="\${DOLPHIN_BACKEND}" + EXPORTS="if [ ! -z 'lsmod | grep panthor' ]; then LD_LIBRARY_PATH='\/usr\/lib\/libmali-valhall-g610-g13p0-x11-gbm.so' DOLPHIN_BACKEND='wayland'; else DOLPHIN_BACKEND='x11'; fi" + ;; + SM8250|SM8550|RK3399|SM8650) + DOLPHIN_BACKEND="x11" + EXPORTS="export QT_QPA_PLATFORM=xcb" + ;; + *) + DOLPHIN_BACKEND="wayland" + EXPORTS="" + ;; + esac + sed -e "s/@DOLPHIN_BACKEND@/${DOLPHIN_BACKEND}/g" -i ${INSTALL}/usr/bin/start_dolphin_gc.sh + sed -e "s/@DOLPHIN_BACKEND@/${DOLPHIN_BACKEND}/g" -i ${INSTALL}/usr/bin/start_dolphin_wii.sh + + sed -e "s/@GRENDERER@/${GRENDERER}/g" -i ${INSTALL}/usr/bin/start_dolphin_gc.sh + sed -e "s/@GRENDERER@/${GRENDERER}/g" -i ${INSTALL}/usr/bin/start_dolphin_wii.sh + + sed -e "s/@EXPORTS@/${EXPORTS}/g" \ + -i ${INSTALL}/usr/bin/start_dolphin_gc.sh + sed -e "s/@EXPORTS@/${EXPORTS}/g" \ + -i ${INSTALL}/usr/bin/start_dolphin_wii.sh +} diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/000-hotkeys.patch b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/000-hotkeys.patch new file mode 100644 index 0000000000..f4fb78a1bd --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/000-hotkeys.patch @@ -0,0 +1,179 @@ +diff -rupN dolphin.orig/Source/Core/Core/HW/GCPadEmu.cpp dolphin/Source/Core/Core/HW/GCPadEmu.cpp +--- dolphin.orig/Source/Core/Core/HW/GCPadEmu.cpp 2024-03-27 04:51:20.527212738 +0000 ++++ dolphin/Source/Core/Core/HW/GCPadEmu.cpp 2024-03-27 06:07:26.630071515 +0000 +@@ -26,6 +26,7 @@ static const u16 button_bitmasks[] = { + PAD_BUTTON_Y, + PAD_TRIGGER_Z, + PAD_BUTTON_START, ++ PAD_BUTTON_HOTKEY, + 0 // MIC HAX + }; + +@@ -50,6 +51,9 @@ GCPad::GCPad(const unsigned int index) : + // i18n: The START/PAUSE button on GameCube controllers + m_buttons->AddInput(Translatability::Translate, START_BUTTON, _trans("START")); + ++ // Hotkey Button ++ m_buttons->AddInput(Translatability::Translate, HOTKEY_BUTTON, _trans("HOTKEY")); ++ + // sticks + groups.emplace_back(m_main_stick = new ControllerEmu::OctagonAnalogStick( + MAIN_STICK_GROUP, _trans("Control Stick"), MAIN_STICK_GATE_RADIUS)); +diff -rupN dolphin.orig/Source/Core/Core/HW/GCPadEmu.h dolphin/Source/Core/Core/HW/GCPadEmu.h +--- dolphin.orig/Source/Core/Core/HW/GCPadEmu.h 2024-03-27 04:51:20.527212738 +0000 ++++ dolphin/Source/Core/Core/HW/GCPadEmu.h 2024-03-27 05:15:39.652307739 +0000 +@@ -68,6 +68,7 @@ public: + static constexpr const char* Y_BUTTON = "Y"; + static constexpr const char* Z_BUTTON = "Z"; + static constexpr const char* START_BUTTON = "Start"; ++ static constexpr const char* HOTKEY_BUTTON = "Hotkey"; + + // i18n: The left trigger button (labeled L on real controllers) + static constexpr const char* L_DIGITAL = _trans("L"); +diff -rupN dolphin.orig/Source/Core/DolphinNoGUI/PlatformX11.cpp dolphin/Source/Core/DolphinNoGUI/PlatformX11.cpp +--- dolphin.orig/Source/Core/DolphinNoGUI/PlatformX11.cpp 2024-03-27 04:51:20.535212986 +0000 ++++ dolphin/Source/Core/DolphinNoGUI/PlatformX11.cpp 2024-03-27 12:56:29.701030775 +0000 +@@ -15,7 +15,14 @@ static constexpr auto X_None = None; + #include "Core/Config/MainSettings.h" + #include "Core/Core.h" + #include "Core/State.h" ++ + #include "Core/System.h" ++#include "Core/HW/GCPad.h" ++#include "InputCommon/GCPadStatus.h" ++#include ++#include "Core/Config/GraphicsSettings.h" ++#include "VideoCommon/VideoConfig.h" ++#include "VideoCommon/OnScreenDisplay.h" + + #include + #include +@@ -151,11 +158,117 @@ void PlatformX11::MainLoop() + { + while (IsRunning()) + { ++ static int hotkey = 0; ++ static int slot = 0; ++ static int fps = 0; ++ static int aspect = 0; ++ static int fforward = 0; ++ static int ires = 0; ++ + UpdateRunningFlag(); + Core::HostDispatchJobs(Core::System::GetInstance()); + ProcessEvents(); + UpdateWindowPosition(); + ++ if(Pad::IsInitialized()) { ++ GCPadStatus x = Pad::GetStatus(0); ++ ++ if( (x.button & PAD_BUTTON_HOTKEY) == PAD_BUTTON_HOTKEY) { // hotkey pressed ++ if(hotkey == 1) { ++ hotkey = 2; ++ } ++ } else { ++ hotkey = 1; // assure hotkey is released between actions ++ } ++ ++ if(hotkey == 2) { // hotkey pressed ++ if( (x.button & PAD_BUTTON_START) == PAD_BUTTON_START) { ++ RequestShutdown(); ++ hotkey = 0; ++ } ++ ++ if( (x.button & PAD_TRIGGER_L) == PAD_TRIGGER_L) { ++ State::Load(Core::System::GetInstance(), slot); ++ hotkey = 0; ++ } ++ if( (x.button & PAD_TRIGGER_R) == PAD_TRIGGER_R) { ++ State::Save(Core::System::GetInstance(), slot); ++ hotkey = 0; ++ } ++ if( (x.button & PAD_BUTTON_DOWN) == PAD_BUTTON_DOWN) { ++ if(slot > 0) slot--; ++ Core::DisplayMessage(fmt::format("Slot {} selected", slot), 4000); ++ hotkey = 0; ++ } ++ if( (x.button & PAD_BUTTON_UP) == PAD_BUTTON_UP) { ++ if(slot < 10) slot++; ++ Core::DisplayMessage(fmt::format("Slot {} selected", slot), 4000); ++ hotkey = 0; ++ } ++ if( (x.button & PAD_BUTTON_A) == PAD_BUTTON_A) { ++ Core::SaveScreenShot(); ++ hotkey = 0; ++ } ++ if( (x.button & PAD_BUTTON_Y) == PAD_BUTTON_Y) { ++ if(fps == 0) { ++ Config::SetCurrent(Config::GFX_SHOW_FPS, True); ++ fps = 1; ++ } else { ++ Config::SetCurrent(Config::GFX_SHOW_FPS, False); ++ fps = 0; ++ } ++ hotkey = 0; ++ } ++ if( (x.button & PAD_BUTTON_X) == PAD_BUTTON_X) { ++ if(aspect == 0) { ++ Config::SetCurrent(Config::GFX_ASPECT_RATIO, AspectMode::Stretch); ++ aspect = 1; ++ } else { ++ Config::SetCurrent(Config::GFX_ASPECT_RATIO, AspectMode::Auto); ++ aspect = 0; ++ } ++ hotkey = 0; ++ } ++ if( (x.button & PAD_BUTTON_B) == PAD_BUTTON_B) { ++ if(ires == 0) { ++ Config::SetCurrent(Config::GFX_EFB_SCALE, 2); ++ OSD::AddMessage("Internal Resolution: 480P"); ++ ires = 2; ++ } ++ else if(ires == 2) { ++ Config::SetCurrent(Config::GFX_EFB_SCALE, 4); ++ OSD::AddMessage("Internal Resolution: 720P"); ++ ires = 4; ++ } ++ else if(ires == 4) { ++ Config::SetCurrent(Config::GFX_EFB_SCALE, 6); ++ OSD::AddMessage("Internal Resolution: 1080P"); ++ ires = 6; ++ } else { ++ Config::SetCurrent(Config::GFX_EFB_SCALE, 1); ++ OSD::AddMessage("Internal Resolution: 240P"); ++ ires = 0; ++ } ++ hotkey = 0; ++ } ++ if( (x.button & PAD_TRIGGER_Z) == PAD_TRIGGER_Z) { ++ if(fforward == 0) { ++ auto speed = Config::Get(Config::MAIN_EMULATION_SPEED) + 1.0; ++ speed = (speed >= 0.95 && speed <= 1.05) ? 1.0 : speed; ++ Config::SetCurrent(Config::MAIN_EMULATION_SPEED, speed); ++ OSD::AddMessage("Fast Forward: ON"); ++ fforward = 1; ++ } else { ++ auto speed = Config::Get(Config::MAIN_EMULATION_SPEED) - 1.0; ++ speed = (speed <= 0 || (speed >= 0.95 && speed <= 1.05)) ? 1.0 : speed; ++ Config::SetCurrent(Config::MAIN_EMULATION_SPEED, speed); ++ OSD::AddMessage("Fast Forward: OFF"); ++ fforward = 0; ++ } ++ hotkey = 0; ++ } ++ } ++ } + // TODO: Is this sleep appropriate? + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } +diff -rupN dolphin.orig/Source/Core/InputCommon/GCPadStatus.h dolphin/Source/Core/InputCommon/GCPadStatus.h +--- dolphin.orig/Source/Core/InputCommon/GCPadStatus.h 2024-03-27 04:51:20.543213235 +0000 ++++ dolphin/Source/Core/InputCommon/GCPadStatus.h 2024-03-27 06:05:14.489860245 +0000 +@@ -26,6 +26,7 @@ enum PadButton + PAD_BUTTON_X = 0x0400, + PAD_BUTTON_Y = 0x0800, + PAD_BUTTON_START = 0x1000, ++ PAD_BUTTON_HOTKEY = 0x2000, + }; + + struct GCPadStatus diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/001-padorder.patch b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/001-padorder.patch new file mode 100644 index 0000000000..187a57efca --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/001-padorder.patch @@ -0,0 +1,111 @@ +diff --git a/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp b/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp +index 6df37b4..64ade4a 100644 +--- a/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp ++++ b/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp +@@ -392,6 +392,65 @@ void Init() + StartHotplugThread(); + } + ++struct joypad_udev_entry ++{ ++ const char *devnode; ++ struct udev_device *dev; ++}; ++ ++int isNumber(const char *s) { ++ int n; ++ ++ if(strlen(s) == 0) { ++ return 0; ++ } ++ ++ for(n=0; ndevnode, bb->devnode); ++} ++ + // Only call this when ControllerInterface::m_devices_population_mutex is locked + void PopulateDevices() + { +@@ -404,6 +463,10 @@ void PopulateDevices() + // We use udev to iterate over all /dev/input/event* devices. + // Note: the Linux kernel is currently limited to just 32 event devices. If + // this ever changes, hopefully udev will take care of this. ++ unsigned sorted_count = 0; ++ struct joypad_udev_entry sorted[64]; ++ const char* devnode; ++ int i; + + udev* const udev = udev_new(); + ASSERT_MSG(CONTROLLERINTERFACE, udev != nullptr, "Couldn't initialize libudev."); +@@ -422,11 +485,25 @@ void PopulateDevices() + + udev_device* dev = udev_device_new_from_syspath(udev, path); + +- if (const char* devnode = udev_device_get_devnode(dev)) +- AddDeviceNode(devnode); +- +- udev_device_unref(dev); ++ devnode = udev_device_get_devnode(dev); ++ if (devnode != NULL && sorted_count < 64) { ++ sorted[sorted_count].devnode = devnode; ++ sorted[sorted_count].dev = dev; ++ sorted_count++; ++ } else { ++ udev_device_unref(dev); ++ } + } ++ ++ /* Sort the udev entries by devnode name so that they are ++ * created in the proper order */ ++ qsort(sorted, sorted_count, sizeof(struct joypad_udev_entry), sort_devnodes); ++ ++ for (i = 0; i < sorted_count; i++) { ++ AddDeviceNode(sorted[i].devnode); ++ udev_device_unref(sorted[i].dev); ++ } ++ + udev_enumerate_unref(enumerate); + udev_unref(udev); + } diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/002-savestate-names.patch b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/002-savestate-names.patch new file mode 100644 index 0000000000..e87521b4e3 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/002-savestate-names.patch @@ -0,0 +1,191 @@ +diff --git a/Source/Core/Core/BootManager.cpp b/Source/Core/Core/BootManager.cpp +index fc93d01a1e..915e77da77 100644 +--- a/Source/Core/Core/BootManager.cpp ++++ b/Source/Core/Core/BootManager.cpp +@@ -66,6 +66,11 @@ bool BootCore(Core::System& system, std::unique_ptr boot, + if (!StartUp.SetPathsAndGameMetadata(system, *boot)) + return false; + ++ if (std::holds_alternative(boot->parameters)) ++ { ++ StartUp.SetBaseSaveState(PathToFileName(std::get(boot->parameters).path)); ++ } ++ + // Movie settings + auto& movie = system.GetMovie(); + if (movie.IsPlayingInput() && movie.IsConfigSaved()) +diff --git a/Source/Core/Core/ConfigManager.cpp b/Source/Core/Core/ConfigManager.cpp +index 5a123c87cd..06890be2dd 100644 +--- a/Source/Core/Core/ConfigManager.cpp ++++ b/Source/Core/Core/ConfigManager.cpp +@@ -183,6 +183,10 @@ void SConfig::SetRunningGameMetadata(const std::string& game_id) + SetRunningGameMetadata(game_id, "", 0, 0, DiscIO::Region::Unknown); + } + ++void SConfig::SetBaseSaveState(const std::string& base_save_state) { ++ m_base_save_state = base_save_state; ++} ++ + void SConfig::SetRunningGameMetadata(const std::string& game_id, const std::string& gametdb_id, + u64 title_id, u16 revision, DiscIO::Region region) + { +diff --git a/Source/Core/Core/ConfigManager.h b/Source/Core/Core/ConfigManager.h +index d21b087a51..f0ce0b7e71 100644 +--- a/Source/Core/Core/ConfigManager.h ++++ b/Source/Core/Core/ConfigManager.h +@@ -63,6 +63,8 @@ struct SConfig + // TODO: remove this as soon as the ticket view hack in IOS/ES/Views is dropped. + bool m_disc_booted_from_game_list = false; + ++ const std::string& GetBaseSaveState() const { return m_base_save_state; } ++ void SetBaseSaveState(const std::string& base_save_state); + const std::string GetGameID() const; + const std::string GetGameTDBID() const; + const std::string GetTitleName() const; +@@ -118,6 +120,7 @@ private: + static SConfig* m_Instance; + mutable std::recursive_mutex m_metadata_lock; + ++ std::string m_base_save_state; + std::string m_game_id; + std::string m_gametdb_id; + std::string m_title_name; +diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp +index a244fda1b6..13d5baa453 100644 +--- a/Source/Core/Core/State.cpp ++++ b/Source/Core/Core/State.cpp +@@ -248,11 +248,10 @@ static std::string SystemTimeAsDoubleToString(double time) + return fmt::format(std::locale{""}, "{:%x %X}", *local_time); + } + +-static std::string MakeStateFilename(int number) +-{ +- return fmt::format("{}{}.s{:02d}", File::GetUserPath(D_STATESAVES_IDX), +- SConfig::GetInstance().GetGameID(), number); +-} ++static std::string MakeStateFilename(bool useId, int number); ++static std::string MakeStateFilename_partdirectory(int number); ++static std::string MakeStateFilename_partfileName(int number); ++static std::string MakeStateFilename_partfileID(int number); + + static std::vector GetUsedSlotsWithTimestamp() + { +@@ -256,7 +259,7 @@ static std::vector GetUsedSlotsWithTimestamp() + StateHeader header; + for (int i = 1; i <= int(NUM_STATES); ++i) + { +- std::string filename = MakeStateFilename(i); ++ std::string filename = MakeStateFilename(true, i); + if (!File::Exists(filename) || !ReadHeader(filename, header)) + continue; + +@@ -525,7 +528,7 @@ std::string GetInfoStringOfSlot(int slot, bool translate) + { + std::lock_guard lk{s_state_saves_in_progress}; + +- std::string filename = MakeStateFilename(slot); ++ std::string filename = MakeStateFilename(true, slot); + if (!File::Exists(filename)) + return translate ? Common::GetStringT("Empty") : "Empty"; + +@@ -538,6 +541,6 @@ u64 GetUnixTimeOfSlot(int slot) + + State::StateHeader header; +- if (!ReadHeader(MakeStateFilename(slot), header)) ++ if (!ReadHeader(MakeStateFilename(true, slot), header)) + return 0; + + constexpr u64 MS_PER_SEC = 1000; +@@ -703,52 +706,88 @@ void Shutdown() + s_flush_unsaved_data_hook.reset(); + } + ++static std::string MakeStateFilename(bool useId, int number) ++{ ++ // Priority: file named by disc filename over file named by game ID. ++ // If the game was not loaded from a disc image, fall back to game ID. ++ std::string filePartName = MakeStateFilename_partfileName(number); ++ std::string fileWithName = ++ fmt::format("{}{}", MakeStateFilename_partdirectory(number), filePartName); ++ if (File::Exists(fileWithName) && filePartName != "") ++ return fileWithName; ++ std::string fileWithId = ++ fmt::format("{}{}", MakeStateFilename_partdirectory(number), MakeStateFilename_partfileID(number)); ++ if (File::Exists(fileWithId) && useId) ++ return fileWithId; ++ if (filePartName == "") ++ return fileWithId; ++ return fileWithName; ++} ++ ++static std::string MakeStateFilename_partdirectory(int number) ++{ ++ return File::GetUserPath(D_STATESAVES_IDX); ++} ++ ++static std::string MakeStateFilename_partfileID(int number) ++{ ++ return fmt::format("{}.s{:02d}", SConfig::GetInstance().GetGameID(), number); ++} ++ ++static std::string MakeStateFilename_partfileName(int number) ++{ ++ std::string basesavestate = SConfig::GetInstance().GetBaseSaveState(); ++ if (basesavestate == "") ++ return ""; ++ return fmt::format("{}.s{:02d}", basesavestate, number); ++} ++ + void Save(Core::System& system, int slot) + { +- SaveAs(system, MakeStateFilename(slot)); ++ SaveAs(system, MakeStateFilename(false, slot)); + } + + void Load(Core::System& system, int slot) + { +- LoadAs(system, MakeStateFilename(slot)); ++ LoadAs(system, MakeStateFilename(true, slot)); + } + + void LoadLastSaved(Core::System& system, int i) + { + if (!CheckIfStateLoadIsAllowed(system)) + return; + + Core::RunOnCPUThread(system, [&system, i] { + // Data must reach the filesystem for up to date "UsedSlots". + s_compress_and_dump_thread.WaitForCompletion(); + + std::vector used_slots = GetUsedSlotsWithTimestamp(); + if (std::size_t(i) > used_slots.size()) + { + Core::DisplayMessage("State doesn't exist", 2000); + return; + } + + std::ranges::stable_sort(used_slots, std::ranges::greater{}, &SlotWithTimestamp::timestamp); +- LoadAsFromCore(system, MakeStateFilename(used_slots[i].slot)); ++ LoadAsFromCore(system, MakeStateFilename(true, used_slots[i].slot)); + }); + } + + void SaveFirstSaved(Core::System& system) + { + Core::RunOnCPUThread(system, [&system, lock = GetStateSaveTaskLock()] { + // Data must reach the filesystem for up to date "UsedSlots". + s_compress_and_dump_thread.WaitForCompletion(); + + std::vector used_slots = GetUsedSlotsWithTimestamp(); + auto slot = GetEmptySlot(used_slots); + if (!slot.has_value()) + { + // overwrite the oldest state + std::ranges::stable_sort(used_slots, {}, &SlotWithTimestamp::timestamp); + slot = used_slots.front().slot; + } + +- SaveAsFromCore(system, MakeStateFilename(*slot)); ++ SaveAsFromCore(system, MakeStateFilename(false, *slot)); + }); + } diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/003-hide-osd-msg.patch b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/003-hide-osd-msg.patch new file mode 100644 index 0000000000..8da14f3922 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/003-hide-osd-msg.patch @@ -0,0 +1,14 @@ +diff -rupN dolphin.orig/Source/Core/VideoBackends/OGL/OGLConfig.cpp dolphin/Source/Core/VideoBackends/OGL/OGLConfig.cpp +--- dolphin.orig/Source/Core/VideoBackends/OGL/OGLConfig.cpp 2024-06-17 15:48:10.116157156 +0000 ++++ dolphin/Source/Core/VideoBackends/OGL/OGLConfig.cpp 2024-06-17 16:21:36.934162183 +0000 +@@ -726,10 +726,6 @@ bool PopulateConfig(GLContext* m_main_gl + g_Config.VerifyValidity(); + UpdateActiveConfig(); + +- OSD::AddMessage(fmt::format("Video Info: {}, {}, {}", g_ogl_config.gl_vendor, +- g_ogl_config.gl_renderer, g_ogl_config.gl_version), +- 5000); +- + if (!g_ogl_config.bSupportsGLBufferStorage && !g_ogl_config.bSupportsGLPinnedMemory) + { + OSD::AddMessage(fmt::format("Your OpenGL driver does not support {}_buffer_storage.", diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/004-enable-240p-res.patch b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/004-enable-240p-res.patch new file mode 100644 index 0000000000..518f51482e --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/004-enable-240p-res.patch @@ -0,0 +1,161 @@ +diff -rupN dolphin.orig/Source/Core/VideoCommon/FramebufferManager.cpp dolphin/Source/Core/VideoCommon/FramebufferManager.cpp +--- dolphin.orig/Source/Core/VideoCommon/FramebufferManager.cpp 2024-06-17 15:48:10.120157247 +0000 ++++ dolphin/Source/Core/VideoCommon/FramebufferManager.cpp 2024-06-17 17:17:45.953589800 +0000 +@@ -185,19 +185,24 @@ FramebufferManager::ConvertEFBRectangle( + return result; + } + +-unsigned int FramebufferManager::GetEFBScale() const ++bool FramebufferManager::IsUnscaled() const + { +- return m_efb_scale; ++ return m_efb_scale == 2; ++} ++ ++float FramebufferManager::GetEFBScalef() const ++{ ++ return m_efb_scale / 2.0f; + } + + int FramebufferManager::EFBToScaledX(int x) const + { +- return x * static_cast(m_efb_scale); ++ return x * static_cast(m_efb_scale) / 2; + } + + int FramebufferManager::EFBToScaledY(int y) const + { +- return y * static_cast(m_efb_scale); ++ return y * static_cast(m_efb_scale) / 2;; + } + + float FramebufferManager::EFBToScaledXf(float x) const +@@ -221,8 +226,8 @@ std::tuple FramebufferManager: + if (max_size < EFB_WIDTH * m_efb_scale) + m_efb_scale = max_size / EFB_WIDTH; + +- u32 new_efb_width = std::max(EFB_WIDTH * static_cast(m_efb_scale), 1u); +- u32 new_efb_height = std::max(EFB_HEIGHT * static_cast(m_efb_scale), 1u); ++ u32 new_efb_width = std::max(EFB_WIDTH * static_cast(m_efb_scale) / 2, 1u); ++ u32 new_efb_height = std::max(EFB_HEIGHT * static_cast(m_efb_scale) / 2, 1u); + + return std::make_tuple(new_efb_width, new_efb_height); + } +@@ -695,7 +700,8 @@ void FramebufferManager::DestroyReadback + + bool FramebufferManager::CreateReadbackFramebuffer() + { +- if (GetEFBScale() != 1) ++ //if (GetEFBScale() != 1) ++ if (IsUnscaled()) + { + const TextureConfig color_config(IsUsingTiledEFBCache() ? m_efb_cache_tile_size : EFB_WIDTH, + IsUsingTiledEFBCache() ? m_efb_cache_tile_size : EFB_HEIGHT, 1, +@@ -717,7 +723,8 @@ bool FramebufferManager::CreateReadbackF + (IsUsingTiledEFBCache() && !g_ActiveConfig.backend_info.bSupportsPartialDepthCopies) || + !AbstractTexture::IsCompatibleDepthAndColorFormats(m_efb_depth_texture->GetFormat(), + GetEFBDepthCopyFormat()) || +- GetEFBScale() != 1) ++ //GetEFBScale() != 1) ++ IsUnscaled()) + { + const TextureConfig depth_config(IsUsingTiledEFBCache() ? m_efb_cache_tile_size : EFB_WIDTH, + IsUsingTiledEFBCache() ? m_efb_cache_tile_size : EFB_HEIGHT, 1, +@@ -800,7 +807,8 @@ void FramebufferManager::PopulateEFBCach + const MathUtil::Rectangle native_rect = ConvertEFBRectangle(rect); + AbstractTexture* src_texture = + depth ? ResolveEFBDepthTexture(native_rect) : ResolveEFBColorTexture(native_rect); +- if (GetEFBScale() != 1 || force_intermediate_copy) ++ //if (GetEFBScale() != 1 || force_intermediate_copy) ++ if (IsUnscaled() || force_intermediate_copy) + { + // Downsample from internal resolution to 1x. + // TODO: This won't produce correct results at IRs above 2x. More samples are required. +@@ -989,7 +997,7 @@ void FramebufferManager::CreatePokeVerti + // GPU will expand the point to a quad. + const float cs_x = (static_cast(x) + 0.5f) * cs_pixel_width - 1.0f; + const float cs_y = 1.0f - (static_cast(y) + 0.5f) * cs_pixel_height; +- const float point_size = static_cast(GetEFBScale()); ++ const float point_size = GetEFBScalef(); + destination_list->push_back({{cs_x, cs_y, z, point_size}, color}); + return; + } +diff -rupN dolphin.orig/Source/Core/VideoCommon/FramebufferManager.h dolphin/Source/Core/VideoCommon/FramebufferManager.h +--- dolphin.orig/Source/Core/VideoCommon/FramebufferManager.h 2024-06-17 15:48:10.120157247 +0000 ++++ dolphin/Source/Core/VideoCommon/FramebufferManager.h 2024-06-17 17:14:56.241373087 +0000 +@@ -74,7 +74,8 @@ public: + // Use this to convert a whole native EFB rect to backbuffer coordinates + MathUtil::Rectangle ConvertEFBRectangle(const MathUtil::Rectangle& rc) const; + +- unsigned int GetEFBScale() const; ++ bool IsUnscaled() const; ++ float GetEFBScalef() const; + + // Use this to upscale native EFB coordinates to IDEAL internal resolution + int EFBToScaledX(int x) const; +@@ -194,7 +195,8 @@ protected: + void DoLoadState(PointerWrap& p); + void DoSaveState(PointerWrap& p); + +- float m_efb_scale = 1.0f; ++ //float m_efb_scale = 1.0f; ++ float m_efb_scale = 2.0f; + PixelFormat m_prev_efb_format; + + std::unique_ptr m_efb_color_texture; +diff -rupN dolphin.orig/Source/Core/VideoCommon/Present.cpp dolphin/Source/Core/VideoCommon/Present.cpp +--- dolphin.orig/Source/Core/VideoCommon/Present.cpp 2024-06-17 15:48:10.120157247 +0000 ++++ dolphin/Source/Core/VideoCommon/Present.cpp 2024-06-17 17:19:31.308204563 +0000 +@@ -78,7 +78,7 @@ static void TryToSnapToXFBSize(int& widt + // The reason why the threshold is 1 pixel (per internal resolution multiplier) is because of + // minor inaccuracies of the VI aspect ratio (and because some resolutions are rounded + // while other are floored). +- const unsigned int efb_scale = g_framebuffer_manager->GetEFBScale(); ++ const unsigned int efb_scale = g_framebuffer_manager->GetEFBScalef(); + const unsigned int pixel_difference_width = std::abs(width - xfb_width); + const unsigned int pixel_difference_height = std::abs(height - xfb_height); + // We ignore this if there's an offset on both hor and ver size, +diff -rupN dolphin.orig/Source/Core/VideoCommon/TextureCacheBase.cpp dolphin/Source/Core/VideoCommon/TextureCacheBase.cpp +--- dolphin.orig/Source/Core/VideoCommon/TextureCacheBase.cpp 2024-06-17 15:48:10.120157247 +0000 ++++ dolphin/Source/Core/VideoCommon/TextureCacheBase.cpp 2024-06-17 17:01:12.572725778 +0000 +@@ -1066,7 +1066,8 @@ SamplerState TextureCacheBase::GetSample + // that have arbitrary contents, eg. are used for fog effects where the + // distance they kick in at is important to preserve at any resolution. + // Correct this with the upscaling factor of custom textures. +- s32 lod_offset = std::log2(g_framebuffer_manager->GetEFBScale() / custom_tex_scale) * 256.f; ++ //s32 lod_offset = std::log2(g_framebuffer_manager->GetEFBScale() / custom_tex_scale) * 256.f; ++ s64 lod_offset = std::log2(g_framebuffer_manager->GetEFBScalef() / custom_tex_scale) * (s64) 256.f; + state.tm0.lod_bias = std::clamp(state.tm0.lod_bias + lod_offset, -32768, 32767); + + // Anisotropic also pushes mips farther away so it cannot be used either +@@ -2349,7 +2350,8 @@ void TextureCacheBase::CopyRenderTargetT + // complex down filtering to average all pixels and produce the correct result. + const bool linear_filter = + !is_depth_copy && +- (scaleByHalf || g_framebuffer_manager->GetEFBScale() != 1 || y_scale > 1.0f); ++ //(scaleByHalf || g_framebuffer_manager->GetEFBScale() != 1 || y_scale > 1.0f); ++ (scaleByHalf || g_framebuffer_manager->IsUnscaled() || y_scale > 1.0f); + + RcTcacheEntry entry; + if (copy_to_vram) +diff -rupN dolphin.orig/Source/Core/VideoCommon/VideoConfig.cpp dolphin/Source/Core/VideoCommon/VideoConfig.cpp +--- dolphin.orig/Source/Core/VideoCommon/VideoConfig.cpp 2024-06-17 15:48:10.120157247 +0000 ++++ dolphin/Source/Core/VideoCommon/VideoConfig.cpp 2024-06-17 17:20:19.009387860 +0000 +@@ -355,7 +355,7 @@ void CheckForConfigChanges() + if (changed_bits == 0) + return; + +- float old_scale = g_framebuffer_manager->GetEFBScale(); ++ float old_scale = g_framebuffer_manager->GetEFBScalef(); + + // Framebuffer changed? + if (changed_bits & (CONFIG_CHANGE_BIT_MULTISAMPLES | CONFIG_CHANGE_BIT_STEREO_MODE | +@@ -364,7 +364,7 @@ void CheckForConfigChanges() + g_framebuffer_manager->RecreateEFBFramebuffer(); + } + +- if (old_scale != g_framebuffer_manager->GetEFBScale()) ++ if (old_scale != g_framebuffer_manager->GetEFBScalef()) + { + auto& system = Core::System::GetInstance(); + auto& pixel_shader_manager = system.GetPixelShaderManager(); diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/005-set-defaults.patch b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/005-set-defaults.patch new file mode 100644 index 0000000000..37106e7e1a --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/005-set-defaults.patch @@ -0,0 +1,15 @@ +diff --git a/Source/Core/Core/Config/MainSettings.cpp b/Source/Core/Core/Config/MainSettings.cpp +index 6d5f260f07..7358a9ea41 100644 +--- a/Source/Core/Core/Config/MainSettings.cpp ++++ b/Source/Core/Core/Config/MainSettings.cpp +@@ -431,8 +431,8 @@ const Info MAIN_USE_PANIC_HANDLERS{{System::Main, "Interface", "UsePanicHa + const Info MAIN_ABORT_ON_PANIC_ALERT{{System::Main, "Interface", "AbortOnPanicAlert"}, false}; + const Info MAIN_OSD_MESSAGES{{System::Main, "Interface", "OnScreenDisplayMessages"}, true}; + const Info MAIN_OSD_FONT_SIZE{{System::Main, "Settings", "OSDFontSize"}, 13}; +-const Info MAIN_SKIP_NKIT_WARNING{{System::Main, "Interface", "SkipNKitWarning"}, false}; +-const Info MAIN_CONFIRM_ON_STOP{{System::Main, "Interface", "ConfirmStop"}, true}; ++const Info MAIN_SKIP_NKIT_WARNING{{System::Main, "Interface", "SkipNKitWarning"}, true}; ++const Info MAIN_CONFIRM_ON_STOP{{System::Main, "Interface", "ConfirmStop"}, false}; + const Info MAIN_SHOW_CURSOR{{System::Main, "Interface", "CursorVisibility"}, + ShowCursor::OnMovement}; + const Info MAIN_LOCK_CURSOR{{System::Main, "Interface", "LockCursor"}, false}; diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/006-dolphin-version.patch b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/006-dolphin-version.patch new file mode 100644 index 0000000000..a2d8f3c796 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/006-dolphin-version.patch @@ -0,0 +1,19 @@ +diff --git a/CMake/ScmRevGen.cmake b/CMake/ScmRevGen.cmake +index 12ee7727b2..889cc02b52 100644 +--- a/CMake/ScmRevGen.cmake ++++ b/CMake/ScmRevGen.cmake +@@ -37,12 +37,12 @@ set(DOLPHIN_VERSION_PATCH ${DOLPHIN_WC_REVISION}) + + # If Dolphin is not built from a Git repository, default the version info to + # reasonable values. +-if(NOT DOLPHIN_WC_REVISION) ++#if(NOT DOLPHIN_WC_REVISION) + set(DOLPHIN_WC_DESCRIBE "${DOLPHIN_VERSION_MAJOR}.${DOLPHIN_VERSION_MINOR}") + set(DOLPHIN_WC_REVISION "${DOLPHIN_WC_DESCRIBE} (no further info)") + set(DOLPHIN_WC_BRANCH "master") + set(DOLPHIN_WC_COMMITS_AHEAD_MASTER 0) +-endif() ++#endif() + + # If this is a tag (i.e. a release), then set the current patch version and + # the number of commits ahead to zero. diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/007-fix-qt.patch b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/007-fix-qt.patch new file mode 100644 index 0000000000..6ec4c865ad --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/007-fix-qt.patch @@ -0,0 +1,13 @@ +diff --git a/Source/Core/DolphinQt/Resources.cpp b/Source/Core/DolphinQt/Resources.cpp +index 84fbcc8df8..21c82a1484 100644 +--- a/Source/Core/DolphinQt/Resources.cpp ++++ b/Source/Core/DolphinQt/Resources.cpp +@@ -50,7 +50,7 @@ QIcon Resources::LoadNamedIcon(std::string_view name, const QString& dir) + for (auto scale : {1, 2, 4}) + load_png(scale); + +- ASSERT(icon.availableSizes().size() > 0); ++ //ASSERT(icon.availableSizes().size() > 0); + + return icon; + } diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/008-bios-dir.patch b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/008-bios-dir.patch new file mode 100644 index 0000000000..d9be1c4668 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/008-bios-dir.patch @@ -0,0 +1,35 @@ +diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp +index b21d15478..5b62db919 100644 +--- a/Source/Core/Core/Boot/Boot.cpp ++++ b/Source/Core/Core/Boot/Boot.cpp +@@ -423,7 +423,7 @@ bool CBoot::Load_BS2(Core::System& system, const std::string& boot_rom_filename) + known_ipl = true; + break; + default: +- PanicAlertFmtT("The IPL file is not a known good dump. (CRC32: {0:x})", ipl_hash); ++ known_ipl = true; + break; + } + +@@ -598,7 +598,7 @@ bool CBoot::BootUp(Core::System& system, std::unique_ptr boot) + if (!File::Exists(ipl.path)) + { + if (ipl.disc) +- PanicAlertFmtT("Cannot start the game, because the GC IPL could not be found."); ++ PanicAlertFmtT("Gamecube bios not found, please add your IPL.bin to /storage/roms/bios/GC/(USA/JAP/EUR)/."); + else + PanicAlertFmtT("Cannot find the GC IPL."); + return false; +diff --git a/Source/Core/Core/Config/MainSettings.cpp b/Source/Core/Core/Config/MainSettings.cpp +index 0442347fdd..af148e79f9 100644 +--- a/Source/Core/Core/Config/MainSettings.cpp ++++ b/Source/Core/Core/Config/MainSettings.cpp +@@ -616,7 +616,7 @@ const char* GetDirectoryForRegion(DiscIO::Region region, RegionDirectoryStyle st + std::string GetBootROMPath(const std::string& region_directory) + { + const std::string path = +- File::GetUserPath(D_GCUSER_IDX) + DIR_SEP + region_directory + DIR_SEP GC_IPL; ++ std::string("/storage/roms/bios/GC/") + DIR_SEP + region_directory + DIR_SEP + GC_IPL; + if (!File::Exists(path)) + return File::GetSysDirectory() + GC_SYS_DIR + DIR_SEP + region_directory + DIR_SEP GC_IPL; + return path; diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/009-supress-warnings.patch b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/009-supress-warnings.patch new file mode 100644 index 0000000000..d330842e2a --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/009-supress-warnings.patch @@ -0,0 +1,253 @@ +diff --git a/Source/Core/Core/HW/DVD/AMMediaboard.cpp b/Source/Core/Core/HW/DVD/AMMediaboard.cpp +index 5cd69f8a62..ebea8a3736 100644 +--- a/Source/Core/Core/HW/DVD/AMMediaboard.cpp ++++ b/Source/Core/Core/HW/DVD/AMMediaboard.cpp +@@ -472,19 +472,19 @@ void Init() + // This is the firmware for the Triforce + const std::string sega_boot_filename = base_path + "segaboot.gcm"; + +- if (!File::Exists(sega_boot_filename)) +- { +- PanicAlertFmt("Failed to open segaboot.gcm({}), which is required for test menus.", +- sega_boot_filename.c_str()); +- return; +- } ++ //if (!File::Exists(sega_boot_filename)) ++ //{ ++ // PanicAlertFmt("Failed to open segaboot.gcm({}), which is required for test menus.", ++ // sega_boot_filename.c_str()); ++ // return; ++ //} + + File::IOFile sega_boot(sega_boot_filename, "rb+"); +- if (!sega_boot.IsOpen()) +- { +- PanicAlertFmt("Failed to read: {}", sega_boot_filename); +- return; +- } ++ //if (!sega_boot.IsOpen()) ++ //{ ++ // PanicAlertFmt("Failed to read: {}", sega_boot_filename); ++ // return; ++ //} + + const u64 length = std::min(sega_boot.GetSize(), sizeof(s_firmware)); + sega_boot.ReadBytes(s_firmware.data(), length); +diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp b/Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp +index 82650ff1a0..587d1d577e 100644 +--- a/Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp ++++ b/Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp +@@ -328,16 +328,16 @@ void CEXIIPL::TransferByte(u8& data) + + if ((dev_addr >= 0x001AFF00) && (dev_addr <= 0x001FF474) && !m_fonts_loaded) + { +- if (dev_addr >= 0x001FCF00) +- { +- PanicAlertFmtT("Error: Trying to access Windows-1252 fonts but they are not loaded. " +- "Games may not show fonts correctly, or crash."); +- } +- else +- { +- PanicAlertFmtT("Error: Trying to access Shift JIS fonts but they are not loaded. " +- "Games may not show fonts correctly, or crash."); +- } ++ //if (dev_addr >= 0x001FCF00) ++ //{ ++ // PanicAlertFmtT("Error: Trying to access Windows-1252 fonts but they are not loaded. " ++ // "Games may not show fonts correctly, or crash."); ++ //} ++ //else ++ //{ ++ // PanicAlertFmtT("Error: Trying to access Shift JIS fonts but they are not loaded. " ++ // "Games may not show fonts correctly, or crash."); ++ //} + // Don't be a nag + m_fonts_loaded = true; + } +diff --git a/Source/Core/Core/HW/Memmap.cpp b/Source/Core/Core/HW/Memmap.cpp +index c7ec1debb0..17d740c158 100644 +--- a/Source/Core/Core/HW/Memmap.cpp ++++ b/Source/Core/Core/HW/Memmap.cpp +@@ -149,9 +149,9 @@ void MemoryManager::Init() + + if (!*region.out_pointer) + { +- PanicAlertFmt( +- "Memory::Init(): Failed to create view for physical region at 0x{:08X} (size 0x{:08X}).", +- region.physical_address, region.size); ++ //PanicAlertFmt( ++ // "Memory::Init(): Failed to create view for physical region at 0x{:08X} (size 0x{:08X}).", ++ // region.physical_address, region.size); + exit(0); + } + +@@ -216,7 +216,7 @@ bool MemoryManager::InitFastmemArena() + m_fastmem_arena = m_arena.ReserveMemoryRegion(memory_size); + if (!m_fastmem_arena) + { +- PanicAlertFmt("Memory::InitFastmemArena(): Failed finding a memory base."); ++ //PanicAlertFmt("Memory::InitFastmemArena(): Failed finding a memory base."); + return false; + } + +@@ -233,9 +233,9 @@ bool MemoryManager::InitFastmemArena() + + if (base != view) + { +- PanicAlertFmt("Memory::InitFastmemArena(): Failed to map memory region at 0x{:08X} " +- "(size 0x{:08X}) into physical fastmem region.", +- region.physical_address, region.size); ++ //PanicAlertFmt("Memory::InitFastmemArena(): Failed to map memory region at 0x{:08X} " ++ // "(size 0x{:08X}) into physical fastmem region.", ++ // region.physical_address, region.size); + return false; + } + } +@@ -302,9 +302,9 @@ void MemoryManager::UpdateDBATMappings(const PowerPC::BatTable& dbat_table) + void* mapped_pointer = m_arena.MapInMemoryRegion(position, mapped_size, base, true); + if (!mapped_pointer) + { +- PanicAlertFmt("Memory::UpdateDBATMappings(): Failed to map memory region at 0x{:08X} " +- "(size 0x{:08X}) into logical fastmem region at 0x{:08X}.", +- intersection_start, mapped_size, logical_address); ++ //PanicAlertFmt("Memory::UpdateDBATMappings(): Failed to map memory region at 0x{:08X} " ++ // "(size 0x{:08X}) into logical fastmem region at 0x{:08X}.", ++ // intersection_start, mapped_size, logical_address); + continue; + } + m_dbat_mapped_entries.emplace(logical_address, +@@ -629,7 +629,7 @@ u8* MemoryManager::GetPointerForRange(u32 address, size_t size) const + if (span.size() < size) + { + // The start address is in a valid region, but the end address is beyond the end of that region. +- PanicAlertFmt("Oversized range in GetPointerForRange. {:x} bytes at {:#010x}", size, address); ++ //PanicAlertFmt("Oversized range in GetPointerForRange. {:x} bytes at {:#010x}", size, address); + return nullptr; + } + +@@ -644,7 +644,7 @@ void MemoryManager::CopyFromEmu(void* data, u32 address, size_t size) const + void* pointer = GetPointerForRange(address, size); + if (!pointer) + { +- PanicAlertFmt("Invalid range in CopyFromEmu. {:x} bytes from {:#010x}", size, address); ++ //PanicAlertFmt("Invalid range in CopyFromEmu. {:x} bytes from {:#010x}", size, address); + return; + } + memcpy(data, pointer, size); +@@ -658,7 +658,7 @@ void MemoryManager::CopyToEmu(u32 address, const void* data, size_t size) + void* pointer = GetPointerForRange(address, size); + if (!pointer) + { +- PanicAlertFmt("Invalid range in CopyToEmu. {:x} bytes to {:#010x}", size, address); ++ //PanicAlertFmt("Invalid range in CopyToEmu. {:x} bytes to {:#010x}", size, address); + return; + } + memcpy(pointer, data, size); +@@ -672,7 +672,7 @@ void MemoryManager::Memset(u32 address, u8 value, size_t size) + void* pointer = GetPointerForRange(address, size); + if (!pointer) + { +- PanicAlertFmt("Invalid range in Memset. {:x} bytes at {:#010x}", size, address); ++ //PanicAlertFmt("Invalid range in Memset. {:x} bytes at {:#010x}", size, address); + return; + } + memset(pointer, value, size); +@@ -723,8 +723,8 @@ std::span MemoryManager::GetSpanForAddress(u32 address) const + } + + auto& ppc_state = m_system.GetPPCState(); +- PanicAlertFmt("Unknown Pointer {:#010x} PC {:#010x} LR {:#010x}", address, ppc_state.pc, +- LR(ppc_state)); ++ //PanicAlertFmt("Unknown Pointer {:#010x} PC {:#010x} LR {:#010x}", address, ppc_state.pc, ++ // LR(ppc_state)); + return {}; + } + +diff --git a/Source/Core/VideoBackends/OGL/OGLTexture.cpp b/Source/Core/VideoBackends/OGL/OGLTexture.cpp +index 003a7ec442..5924317c24 100644 +--- a/Source/Core/VideoBackends/OGL/OGLTexture.cpp ++++ b/Source/Core/VideoBackends/OGL/OGLTexture.cpp +@@ -279,19 +279,19 @@ void OGLTexture::ResolveFromTexture(const AbstractTexture* src, + void OGLTexture::Load(u32 level, u32 width, u32 height, u32 row_length, const u8* buffer, + size_t buffer_size, u32 layer) + { +- if (level >= m_config.levels) +- PanicAlertFmt("Texture only has {} levels, can't update level {}", m_config.levels, level); ++ //if (level >= m_config.levels) ++ // PanicAlertFmt("Texture only has {} levels, can't update level {}", m_config.levels, level); + +- if (layer >= m_config.layers) +- PanicAlertFmt("Texture only has {} layer, can't update layer {}", m_config.layers, layer); ++ //if (layer >= m_config.layers) ++ // PanicAlertFmt("Texture only has {} layer, can't update layer {}", m_config.layers, layer); + + const auto expected_width = std::max(1U, m_config.width >> level); + const auto expected_height = std::max(1U, m_config.height >> level); +- if (width != expected_width || height != expected_height) +- { +- PanicAlertFmt("Size of level {} must be {}x{}, but {}x{} requested", level, expected_width, +- expected_height, width, height); +- } ++ //if (width != expected_width || height != expected_height) ++ //{ ++ // PanicAlertFmt("Size of level {} must be {}x{}, but {}x{} requested", level, expected_width, ++ // expected_height, width, height); ++ //} + + const GLenum target = GetGLTarget(); + glActiveTexture(GL_MUTABLE_TEXTURE_INDEX); +@@ -343,10 +343,10 @@ void OGLTexture::Load(u32 level, u32 width, u32 height, u32 row_length, const u8 + static_cast(buffer_size), buffer); + } + } +- else +- { +- PanicAlertFmt("Failed to handle compressed texture load - unhandled type"); +- } ++ //else ++ //{ ++ // PanicAlertFmt("Failed to handle compressed texture load - unhandled type"); ++ //} + } + else + { +@@ -389,10 +389,10 @@ void OGLTexture::Load(u32 level, u32 width, u32 height, u32 row_length, const u8 + buffer); + } + } +- else +- { +- PanicAlertFmt("Failed to handle texture load - unhandled type"); +- } ++ //else ++ //{ ++ // PanicAlertFmt("Failed to handle texture load - unhandled type"); ++ //} + } + + if (row_length != width) +diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp +index 0d91284038..376e009dd4 100644 +--- a/Source/Core/VideoCommon/CommandProcessor.cpp ++++ b/Source/Core/VideoCommon/CommandProcessor.cpp +@@ -704,13 +704,13 @@ void CommandProcessorManager::HandleUnknownOpcode(u8 cmd_byte, const u8* buffer, + "game from working, please report it to the developers."); + } + +- PanicAlertFmtT("GFX FIFO: Unknown Opcode ({0:#04x} @ {1}, preprocess={2}).\n" +- "\n" +- "{3}\n" +- "\n" +- "Further errors will be sent to the Video Backend log and " +- "Dolphin will now likely crash or hang.", +- cmd_byte, fmt::ptr(buffer), preprocess, Common::GetStringT(advice)); ++ //PanicAlertFmtT("GFX FIFO: Unknown Opcode ({0:#04x} @ {1}, preprocess={2}).\n" ++ // "\n" ++ // "{3}\n" ++ // "\n" ++ // "Further errors will be sent to the Video Backend log and " ++ // "Dolphin will now likely crash or hang.", ++ // cmd_byte, fmt::ptr(buffer), preprocess, Common::GetStringT(advice)); + } + } + diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/010-codehandlers-bin-path.patch b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/010-codehandlers-bin-path.patch new file mode 100644 index 0000000000..847cdc319c --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/qt6/010-codehandlers-bin-path.patch @@ -0,0 +1,14 @@ +diff --git a/Source/Core/Core/GeckoCode.cpp b/Source/Core/Core/GeckoCode.cpp +index 62d2dc5481..411b1c6204 100644 +--- a/Source/Core/Core/GeckoCode.cpp ++++ b/Source/Core/Core/GeckoCode.cpp +@@ -109,7 +109,8 @@ std::vector SetAndReturnActiveCodes(std::span gcodes + static Installation InstallCodeHandlerLocked(const Core::CPUThreadGuard& guard) + { + std::string data; +- if (!File::ReadFileToString(File::GetSysDirectory() + GECKO_CODE_HANDLER, data)) ++ const std::string custom_handler_path = "/storage/.config/dolphin-emu/" GECKO_CODE_HANDLER; ++ if (!File::ReadFileToString(custom_handler_path, data)) + { + ERROR_LOG_FMT(ACTIONREPLAY, + "Could not enable cheats because " GECKO_CODE_HANDLER " was missing."); diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/wayland/000-add-wayland.patch b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/wayland/000-add-wayland.patch new file mode 100644 index 0000000000..ffbb76dd7f --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/wayland/000-add-wayland.patch @@ -0,0 +1,5370 @@ +diff -rupN dolphin.orig/CMake/FindWaylandProtocols.cmake dolphin/CMake/FindWaylandProtocols.cmake +--- dolphin.orig/CMake/FindWaylandProtocols.cmake 1970-01-01 00:00:00.000000000 +0000 ++++ dolphin/CMake/FindWaylandProtocols.cmake 2024-03-05 04:06:08.240295843 +0000 +@@ -0,0 +1,28 @@ ++# from https://github.com/glfw/glfw/blob/master/CMake/modules/FindWaylandProtocols.cmake ++ ++find_package(PkgConfig) ++ ++pkg_check_modules(WaylandProtocols QUIET wayland-protocols>=${WaylandProtocols_FIND_VERSION}) ++ ++execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=pkgdatadir wayland-protocols ++ OUTPUT_VARIABLE WaylandProtocols_PKGDATADIR ++ RESULT_VARIABLE _pkgconfig_failed) ++if (_pkgconfig_failed) ++ message(FATAL_ERROR "Missing wayland-protocols pkgdatadir") ++endif() ++ ++string(REGEX REPLACE "[\r\n]" "" WaylandProtocols_PKGDATADIR "${WaylandProtocols_PKGDATADIR}") ++ ++find_package_handle_standard_args(WaylandProtocols ++ FOUND_VAR ++ WaylandProtocols_FOUND ++ REQUIRED_VARS ++ WaylandProtocols_PKGDATADIR ++ VERSION_VAR ++ WaylandProtocols_VERSION ++ HANDLE_COMPONENTS ++) ++ ++set(WAYLAND_PROTOCOLS_FOUND ${WaylandProtocols_FOUND}) ++set(WAYLAND_PROTOCOLS_PKGDATADIR ${WaylandProtocols_PKGDATADIR}) ++set(WAYLAND_PROTOCOLS_VERSION ${WaylandProtocols_VERSION}) +diff -rupN dolphin.orig/CMake/FindXKBCommon.cmake dolphin/CMake/FindXKBCommon.cmake +--- dolphin.orig/CMake/FindXKBCommon.cmake 1970-01-01 00:00:00.000000000 +0000 ++++ dolphin/CMake/FindXKBCommon.cmake 2024-03-05 04:06:08.240295843 +0000 +@@ -0,0 +1,33 @@ ++# - Try to find XKBCommon ++# Once done, this will define ++# ++# XKBCOMMON_FOUND - System has XKBCommon ++# XKBCOMMON_INCLUDE_DIRS - The XKBCommon include directories ++# XKBCOMMON_LIBRARIES - The libraries needed to use XKBCommon ++# XKBCOMMON_DEFINITIONS - Compiler switches required for using XKBCommon ++ ++find_package(PkgConfig) ++pkg_check_modules(PC_XKBCOMMON QUIET xkbcommon) ++set(XKBCOMMON_DEFINITIONS ${PC_XKBCOMMON_CFLAGS_OTHER}) ++ ++find_path(XKBCOMMON_INCLUDE_DIR ++ NAMES xkbcommon/xkbcommon.h ++ HINTS ${PC_XKBCOMMON_INCLUDE_DIR} ${PC_XKBCOMMON_INCLUDE_DIRS} ++) ++ ++find_library(XKBCOMMON_LIBRARY ++ NAMES xkbcommon ++ HINTS ${PC_XKBCOMMON_LIBRARY} ${PC_XKBCOMMON_LIBRARY_DIRS} ++) ++ ++set(XKBCOMMON_LIBRARIES ${XKBCOMMON_LIBRARY}) ++set(XKBCOMMON_LIBRARY_DIRS ${XKBCOMMON_LIBRARY_DIRS}) ++set(XKBCOMMON_INCLUDE_DIRS ${XKBCOMMON_INCLUDE_DIR}) ++ ++include(FindPackageHandleStandardArgs) ++find_package_handle_standard_args(XKBCommon DEFAULT_MSG ++ XKBCOMMON_LIBRARY ++ XKBCOMMON_INCLUDE_DIR ++) ++ ++mark_as_advanced(XKBCOMMON_LIBRARY XKBCOMMON_INCLUDE_DIR) +diff -rupN dolphin.orig/CMakeLists.txt dolphin/CMakeLists.txt +--- dolphin.orig/CMakeLists.txt 2024-03-05 04:05:25.878960469 +0000 ++++ dolphin/CMakeLists.txt 2024-03-05 04:06:08.240295843 +0000 +@@ -47,6 +47,7 @@ set(DOLPHIN_DEFAULT_UPDATE_TRACK "" CACH + + if(UNIX AND NOT APPLE AND NOT ANDROID) + option(ENABLE_X11 "Enables X11 Support" ON) ++ option(ENABLE_WAYLAND "Enables Wayland Support" OFF) + endif() + if(NOT WIN32 AND NOT APPLE AND NOT HAIKU) + option(ENABLE_EGL "Enables EGL OpenGL Interface" ON) +@@ -543,6 +544,17 @@ if(ENABLE_X11) + endif() + endif() + ++if(ENABLE_WAYLAND) ++ find_package(ECM REQUIRED NO_MODULE) ++ list(APPEND CMAKE_MODULE_PATH "${ECM_MODULE_PATH}") ++ find_package(Wayland REQUIRED Client Egl) ++ find_package(WaylandScanner REQUIRED) ++ find_package(WaylandProtocols 1.15 REQUIRED) ++ find_package(XKBCommon REQUIRED) ++ add_definitions(-DHAVE_WAYLAND=1) ++ message(STATUS "Wayland support enabled") ++endif() ++ + if(ENABLE_EGL) + find_package(EGL) + if(EGL_FOUND) +diff -rupN dolphin.orig/Source/Core/Common/CMakeLists.txt dolphin/Source/Core/Common/CMakeLists.txt +--- dolphin.orig/Source/Core/Common/CMakeLists.txt 2024-03-05 04:05:26.574982411 +0000 ++++ dolphin/Source/Core/Common/CMakeLists.txt 2024-03-05 04:06:08.240295843 +0000 +@@ -253,11 +253,20 @@ if(ENABLE_EGL AND EGL_FOUND) + GL/GLInterface/EGLAndroid.cpp + GL/GLInterface/EGLAndroid.h + ) +- elseif(ENABLE_X11 AND X11_FOUND) +- target_sources(common PRIVATE +- GL/GLInterface/EGLX11.cpp +- GL/GLInterface/EGLX11.h +- ) ++ else() ++ if(ENABLE_X11 AND X11_FOUND) ++ target_sources(common PRIVATE ++ GL/GLInterface/EGLX11.cpp ++ GL/GLInterface/EGLX11.h ++ ) ++ endif() ++ if(ENABLE_WAYLAND AND WAYLAND_FOUND) ++ target_sources(common PRIVATE ++ GL/GLInterface/EGLWayland.cpp ++ GL/GLInterface/EGLWayland.h ++ ) ++ target_link_libraries(common PRIVATE Wayland::Egl) ++ endif() + endif() + target_include_directories(common PRIVATE ${EGL_INCLUDE_DIRS}) + target_link_libraries(common PUBLIC ${EGL_LIBRARIES}) +diff -rupN dolphin.orig/Source/Core/Common/GL/GLContext.cpp dolphin/Source/Core/Common/GL/GLContext.cpp +--- dolphin.orig/Source/Core/Common/GL/GLContext.cpp 2024-03-05 04:05:26.578982537 +0000 ++++ dolphin/Source/Core/Common/GL/GLContext.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -25,6 +25,9 @@ + #if defined(ANDROID) + #include "Common/GL/GLInterface/EGLAndroid.h" + #endif ++#if HAVE_WAYLAND ++#include "Common/GL/GLInterface/EGLWayland.h" ++#endif + #endif + + const std::array, 9> GLContext::s_desktop_opengl_versions = { +@@ -57,11 +60,11 @@ bool GLContext::ClearCurrent() + return false; + } + +-void GLContext::Update() ++void GLContext::UpdateDimensions(int window_width, int window_height) + { + } + +-void GLContext::UpdateSurface(void* window_handle) ++void GLContext::UpdateSurface(void* window_handle, int window_width, int window_height) + { + } + +@@ -113,6 +116,10 @@ std::unique_ptr GLContext::Cr + #endif + } + #endif ++#if HAVE_WAYLAND ++ if (wsi.type == WindowSystemType::Wayland) ++ context = std::make_unique(); ++#endif + #if HAVE_EGL + if (wsi.type == WindowSystemType::Headless || wsi.type == WindowSystemType::FBDev) + context = std::make_unique(); +diff -rupN dolphin.orig/Source/Core/Common/GL/GLContext.h dolphin/Source/Core/Common/GL/GLContext.h +--- dolphin.orig/Source/Core/Common/GL/GLContext.h 2024-03-05 04:05:26.578982537 +0000 ++++ dolphin/Source/Core/Common/GL/GLContext.h 2024-03-05 04:06:08.240295843 +0000 +@@ -36,8 +36,8 @@ public: + virtual bool MakeCurrent(); + virtual bool ClearCurrent(); + +- virtual void Update(); +- virtual void UpdateSurface(void* window_handle); ++ virtual void UpdateDimensions(int window_width, int window_height); ++ virtual void UpdateSurface(void* window_handle, int window_width, int window_height); + + virtual void Swap(); + virtual void SwapInterval(int interval); +diff -rupN dolphin.orig/Source/Core/Common/GL/GLInterface/AGL.h dolphin/Source/Core/Common/GL/GLInterface/AGL.h +--- dolphin.orig/Source/Core/Common/GL/GLInterface/AGL.h 2024-03-05 04:05:26.578982537 +0000 ++++ dolphin/Source/Core/Common/GL/GLInterface/AGL.h 2024-03-05 04:06:08.240295843 +0000 +@@ -27,6 +27,8 @@ public: + + bool MakeCurrent() override; + bool ClearCurrent() override; ++ ++ void UpdateDimensions(int window_width, int window_height) override; + + void Update() override; + +diff -rupN dolphin.orig/Source/Core/Common/GL/GLInterface/AGL.mm dolphin/Source/Core/Common/GL/GLInterface/AGL.mm +--- dolphin.orig/Source/Core/Common/GL/GLInterface/AGL.mm 2024-03-05 04:05:26.578982537 +0000 ++++ dolphin/Source/Core/Common/GL/GLInterface/AGL.mm 2024-03-05 04:06:08.240295843 +0000 +@@ -144,7 +144,7 @@ bool GLContextAGL::ClearCurrent() + return true; + } + +-void GLContextAGL::Update() ++void GLContextAGL::UpdateDimensions(int window_width, int window_height) + { + if (!m_view) + return; +diff -rupN dolphin.orig/Source/Core/Common/GL/GLInterface/EGL.cpp dolphin/Source/Core/Common/GL/GLInterface/EGL.cpp +--- dolphin.orig/Source/Core/Common/GL/GLInterface/EGL.cpp 2024-03-05 04:05:26.578982537 +0000 ++++ dolphin/Source/Core/Common/GL/GLInterface/EGL.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -292,8 +292,8 @@ bool GLContextEGL::CreateWindowSurface() + { + if (!IsHeadless()) + { +- EGLNativeWindowType native_window = GetEGLNativeWindow(m_config); +- m_egl_surface = eglCreateWindowSurface(m_egl_display, m_config, native_window, nullptr); ++ m_native_window = GetEGLNativeWindow(m_config); ++ m_egl_surface = eglCreateWindowSurface(m_egl_display, m_config, m_native_window, nullptr); + if (!m_egl_surface) + { + INFO_LOG_FMT(VIDEO, "Error: eglCreateWindowSurface failed"); +@@ -301,15 +301,7 @@ bool GLContextEGL::CreateWindowSurface() + } + + // Get dimensions from the surface. +- EGLint surface_width = 1, surface_height = 1; +- if (!eglQuerySurface(m_egl_display, m_egl_surface, EGL_WIDTH, &surface_width) || +- !eglQuerySurface(m_egl_display, m_egl_surface, EGL_HEIGHT, &surface_height)) +- { +- WARN_LOG_FMT(VIDEO, +- "Failed to get surface dimensions via eglQuerySurface. Size may be incorrect."); +- } +- m_backbuffer_width = static_cast(surface_width); +- m_backbuffer_height = static_cast(surface_height); ++ QueryDimensions(); + } + else if (!m_supports_surfaceless) + { +@@ -347,9 +339,16 @@ bool GLContextEGL::MakeCurrent() + return eglMakeCurrent(m_egl_display, m_egl_surface, m_egl_surface, m_egl_context); + } + +-void GLContextEGL::UpdateSurface(void* window_handle) ++void GLContextEGL::UpdateDimensions(int window_width, int window_height) ++{ ++ QueryDimensions(); ++} ++ ++void GLContextEGL::UpdateSurface(void* window_handle, int window_width, int window_height) + { + m_wsi.render_surface = window_handle; ++ m_wsi.render_surface_width = window_width; ++ m_wsi.render_surface_height = window_height; + ClearCurrent(); + DestroyWindowSurface(); + CreateWindowSurface(); +@@ -376,3 +375,15 @@ void GLContextEGL::DestroyContext() + m_egl_context = EGL_NO_CONTEXT; + m_egl_display = EGL_NO_DISPLAY; + } ++ ++void GLContextEGL::QueryDimensions() ++{ ++ EGLint surface_width = 1, surface_height = 1; ++ if (!eglQuerySurface(m_egl_display, m_egl_surface, EGL_WIDTH, &surface_width) || ++ !eglQuerySurface(m_egl_display, m_egl_surface, EGL_HEIGHT, &surface_height)) ++ { ++ INFO_LOG_FMT(VIDEO, "Failed to get surface dimensions via eglQuerySurface. Size may be incorrect."); ++ } ++ m_backbuffer_width = static_cast(surface_width); ++ m_backbuffer_height = static_cast(surface_height); ++} +diff -rupN dolphin.orig/Source/Core/Common/GL/GLInterface/EGL.h dolphin/Source/Core/Common/GL/GLInterface/EGL.h +--- dolphin.orig/Source/Core/Common/GL/GLInterface/EGL.h 2024-03-05 04:05:26.578982537 +0000 ++++ dolphin/Source/Core/Common/GL/GLInterface/EGL.h 2024-03-05 04:06:08.240295843 +0000 +@@ -22,7 +22,8 @@ public: + bool MakeCurrent() override; + bool ClearCurrent() override; + +- void UpdateSurface(void* window_handle) override; ++ void UpdateDimensions(int window_width, int window_height); ++ void UpdateSurface(void* window_handle, int window_width, int window_height) override; + + void Swap() override; + void SwapInterval(int interval) override; +@@ -39,9 +40,12 @@ protected: + void DestroyWindowSurface(); + void DetectMode(); + void DestroyContext(); ++ void QueryDimensions(); + + WindowSystemInfo m_wsi = {}; + ++ EGLNativeWindowType m_native_window = {}; ++ + EGLConfig m_config; + bool m_supports_surfaceless = false; + std::vector m_attribs; +diff -rupN dolphin.orig/Source/Core/Common/GL/GLInterface/EGLWayland.cpp dolphin/Source/Core/Common/GL/GLInterface/EGLWayland.cpp +--- dolphin.orig/Source/Core/Common/GL/GLInterface/EGLWayland.cpp 1970-01-01 00:00:00.000000000 +0000 ++++ dolphin/Source/Core/Common/GL/GLInterface/EGLWayland.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -0,0 +1,36 @@ ++// Copyright 2019 Dolphin Emulator Project ++// Licensed under GPLv2+ ++// Refer to the license.txt file included. ++ ++#include "Common/GL/GLInterface/EGLWayland.h" ++#include ++ ++GLContextEGLWayland::~GLContextEGLWayland() ++{ ++ if (m_native_window) ++ wl_egl_window_destroy(reinterpret_cast(m_native_window)); ++} ++ ++EGLDisplay GLContextEGLWayland::OpenEGLDisplay() ++{ ++ return eglGetDisplay(reinterpret_cast(m_wsi.display_connection)); ++} ++ ++void GLContextEGLWayland::UpdateDimensions(int window_width, int window_height) ++{ ++ wl_egl_window_resize(reinterpret_cast(m_native_window), window_width, ++ window_height, 0, 0); ++ m_backbuffer_width = window_width; ++ m_backbuffer_height = window_height; ++} ++ ++EGLNativeWindowType GLContextEGLWayland::GetEGLNativeWindow(EGLConfig config) ++{ ++ wl_egl_window* window = ++ wl_egl_window_create(static_cast(m_wsi.render_surface), ++ m_wsi.render_surface_width, m_wsi.render_surface_height); ++ if (!window) ++ return {}; ++ ++ return reinterpret_cast(window); ++} +diff -rupN dolphin.orig/Source/Core/Common/GL/GLInterface/EGLWayland.h dolphin/Source/Core/Common/GL/GLInterface/EGLWayland.h +--- dolphin.orig/Source/Core/Common/GL/GLInterface/EGLWayland.h 1970-01-01 00:00:00.000000000 +0000 ++++ dolphin/Source/Core/Common/GL/GLInterface/EGLWayland.h 2024-03-05 04:06:08.240295843 +0000 +@@ -0,0 +1,19 @@ ++// Copyright 2019 Dolphin Emulator Project ++// Licensed under GPLv2+ ++// Refer to the license.txt file included. ++ ++#pragma once ++ ++#include "Common/GL/GLInterface/EGL.h" ++ ++class GLContextEGLWayland : public GLContextEGL ++{ ++public: ++ ~GLContextEGLWayland(); ++ ++ void UpdateDimensions(int window_width, int window_height) override; ++ ++protected: ++ EGLDisplay OpenEGLDisplay() override; ++ EGLNativeWindowType GetEGLNativeWindow(EGLConfig config) override; ++}; +diff -rupN dolphin.orig/Source/Core/Common/GL/GLInterface/EGLX11.cpp dolphin/Source/Core/Common/GL/GLInterface/EGLX11.cpp +--- dolphin.orig/Source/Core/Common/GL/GLInterface/EGLX11.cpp 2024-03-05 04:05:26.578982537 +0000 ++++ dolphin/Source/Core/Common/GL/GLInterface/EGLX11.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -11,7 +11,7 @@ GLContextEGLX11::~GLContextEGLX11() + m_render_window.reset(); + } + +-void GLContextEGLX11::Update() ++void GLContextEGLX11::UpdateDimensions(int window_width, int window_height) + { + m_render_window->UpdateDimensions(); + m_backbuffer_width = m_render_window->GetWidth(); +diff -rupN dolphin.orig/Source/Core/Common/GL/GLInterface/EGLX11.h dolphin/Source/Core/Common/GL/GLInterface/EGLX11.h +--- dolphin.orig/Source/Core/Common/GL/GLInterface/EGLX11.h 2024-03-05 04:05:26.578982537 +0000 ++++ dolphin/Source/Core/Common/GL/GLInterface/EGLX11.h 2024-03-05 04:06:08.240295843 +0000 +@@ -13,7 +13,7 @@ class GLContextEGLX11 final : public GLC + public: + ~GLContextEGLX11() override; + +- void Update() override; ++void UpdateDimensions(int window_width, int window_height) override; + + protected: + EGLDisplay OpenEGLDisplay() override; +diff -rupN dolphin.orig/Source/Core/Common/GL/GLInterface/GLX.cpp dolphin/Source/Core/Common/GL/GLInterface/GLX.cpp +--- dolphin.orig/Source/Core/Common/GL/GLInterface/GLX.cpp 2024-03-05 04:05:26.578982537 +0000 ++++ dolphin/Source/Core/Common/GL/GLInterface/GLX.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -310,7 +310,7 @@ bool GLContextGLX::ClearCurrent() + return glXMakeCurrent(m_display, None, nullptr); + } + +-void GLContextGLX::Update() ++void GLContextGLX::UpdateDimensions(int window_width, int window_height) + { + m_render_window->UpdateDimensions(); + m_backbuffer_width = m_render_window->GetWidth(); +diff -rupN dolphin.orig/Source/Core/Common/GL/GLInterface/GLX.h dolphin/Source/Core/Common/GL/GLInterface/GLX.h +--- dolphin.orig/Source/Core/Common/GL/GLInterface/GLX.h 2024-03-05 04:05:26.578982537 +0000 ++++ dolphin/Source/Core/Common/GL/GLInterface/GLX.h 2024-03-05 04:06:08.240295843 +0000 +@@ -24,7 +24,7 @@ public: + bool MakeCurrent() override; + bool ClearCurrent() override; + +- void Update() override; ++ void UpdateDimensions(int window_width, int window_height) override; + + void SwapInterval(int Interval) override; + void Swap() override; +diff -rupN dolphin.orig/Source/Core/Common/GL/GLInterface/WGL.cpp dolphin/Source/Core/Common/GL/GLInterface/WGL.cpp +--- dolphin.orig/Source/Core/Common/GL/GLInterface/WGL.cpp 2024-03-05 04:05:26.578982537 +0000 ++++ dolphin/Source/Core/Common/GL/GLInterface/WGL.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -480,7 +480,7 @@ bool GLContextWGL::ClearCurrent() + } + + // Update window width, size and etc. Called from Render.cpp +-void GLContextWGL::Update() ++void GLContextWGL::UpdateDimensions(int window_width, int window_height) + { + RECT rcWindow; + GetClientRect(m_window_handle, &rcWindow); +diff -rupN dolphin.orig/Source/Core/Common/GL/GLInterface/WGL.h dolphin/Source/Core/Common/GL/GLInterface/WGL.h +--- dolphin.orig/Source/Core/Common/GL/GLInterface/WGL.h 2024-03-05 04:05:26.578982537 +0000 ++++ dolphin/Source/Core/Common/GL/GLInterface/WGL.h 2024-03-05 04:06:08.240295843 +0000 +@@ -19,7 +19,7 @@ public: + bool MakeCurrent() override; + bool ClearCurrent() override; + +- void Update() override; ++ void UpdateDimensions(int window_width, int window_height) override; + + void Swap() override; + void SwapInterval(int interval) override; +diff -rupN dolphin.orig/Source/Core/Common/WindowSystemInfo.h dolphin/Source/Core/Common/WindowSystemInfo.h +--- dolphin.orig/Source/Core/Common/WindowSystemInfo.h 2024-03-05 04:05:26.578982537 +0000 ++++ dolphin/Source/Core/Common/WindowSystemInfo.h 2024-03-05 04:06:08.240295843 +0000 +@@ -40,7 +40,11 @@ struct WindowSystemInfo + // This is kept seperate as input may require a different handle to rendering, and + // during video backend startup the surface pointer may change (MoltenVK). + void* render_surface = nullptr; +- ++ ++ // Dimensions of the render surface, if this is determined by the frontend. ++ int render_surface_width = 0; ++ int render_surface_height = 0; ++ + // Scale of the render surface. For hidpi systems, this will be >1. + float render_surface_scale = 1.0f; + }; +diff -rupN dolphin.orig/Source/Core/Core/BootManager.cpp dolphin/Source/Core/Core/BootManager.cpp +--- dolphin.orig/Source/Core/Core/BootManager.cpp 2024-03-05 04:05:26.578982537 +0000 ++++ dolphin/Source/Core/Core/BootManager.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -64,6 +64,11 @@ bool BootCore(std::unique_ptr(boot->parameters)) ++ { ++ StartUp.SetBaseSaveState(PathToFileName(std::get(boot->parameters).path)); ++ } ++ + // Movie settings + if (Movie::IsPlayingInput() && Movie::IsConfigSaved()) + { +diff -rupN dolphin.orig/Source/Core/Core/ConfigManager.cpp dolphin/Source/Core/Core/ConfigManager.cpp +--- dolphin.orig/Source/Core/Core/ConfigManager.cpp 2024-03-05 04:05:26.578982537 +0000 ++++ dolphin/Source/Core/Core/ConfigManager.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -139,6 +139,10 @@ void SConfig::SetRunningGameMetadata(con + SetRunningGameMetadata(game_id, "", 0, 0, DiscIO::Region::Unknown); + } + ++void SConfig::SetBaseSaveState(const std::string& base_save_state) { ++ m_base_save_state = base_save_state; ++} ++ + void SConfig::SetRunningGameMetadata(const std::string& game_id, const std::string& gametdb_id, + u64 title_id, u16 revision, DiscIO::Region region) + { +diff -rupN dolphin.orig/Source/Core/Core/ConfigManager.h dolphin/Source/Core/Core/ConfigManager.h +--- dolphin.orig/Source/Core/Core/ConfigManager.h 2024-03-05 04:05:26.578982537 +0000 ++++ dolphin/Source/Core/Core/ConfigManager.h 2024-03-05 04:06:08.240295843 +0000 +@@ -56,6 +56,8 @@ struct SConfig + // TODO: remove this as soon as the ticket view hack in IOS/ES/Views is dropped. + bool m_disc_booted_from_game_list = false; + ++ const std::string& GetBaseSaveState() const { return m_base_save_state; } ++ void SetBaseSaveState(const std::string& base_save_state); + const std::string& GetGameID() const { return m_game_id; } + const std::string& GetGameTDBID() const { return m_gametdb_id; } + const std::string& GetTitleName() const { return m_title_name; } +@@ -109,6 +111,7 @@ private: + + static SConfig* m_Instance; + ++ std::string m_base_save_state; + std::string m_game_id; + std::string m_gametdb_id; + std::string m_title_name; +diff -rupN dolphin.orig/Source/Core/Core/Core.cpp dolphin/Source/Core/Core/Core.cpp +--- dolphin.orig/Source/Core/Core/Core.cpp 2024-03-05 04:05:26.578982537 +0000 ++++ dolphin/Source/Core/Core/Core.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -474,6 +474,8 @@ static void EmuThread(std::unique_ptrAddInput(ControllerEmu::Translate, START_BUTTON, _trans("START")); + ++ // Hotkey Button ++ m_buttons->AddInput(ControllerEmu::Translate, HOTKEY_BUTTON, _trans("HOTKEY")); ++ + // sticks + groups.emplace_back(m_main_stick = new ControllerEmu::OctagonAnalogStick( + MAIN_STICK_GROUP, _trans("Control Stick"), MAIN_STICK_GATE_RADIUS)); +diff -rupN dolphin.orig/Source/Core/Core/HW/GCPadEmu.h dolphin/Source/Core/Core/HW/GCPadEmu.h +--- dolphin.orig/Source/Core/Core/HW/GCPadEmu.h 2024-03-05 04:05:26.582982663 +0000 ++++ dolphin/Source/Core/Core/HW/GCPadEmu.h 2024-03-05 14:38:20.524919664 +0000 +@@ -66,6 +66,8 @@ public: + static constexpr const char* Y_BUTTON = "Y"; + static constexpr const char* Z_BUTTON = "Z"; + static constexpr const char* START_BUTTON = "Start"; ++ static constexpr const char* HOTKEY_BUTTON = "Hotkey"; ++ + + // i18n: The left trigger button (labeled L on real controllers) + static constexpr const char* L_DIGITAL = _trans("L"); +diff -rupN dolphin.orig/Source/Core/Core/State.cpp dolphin/Source/Core/Core/State.cpp +--- dolphin.orig/Source/Core/Core/State.cpp 2024-03-05 04:05:26.586982789 +0000 ++++ dolphin/Source/Core/Core/State.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -327,7 +327,10 @@ static std::string SystemTimeAsDoubleToS + #endif + } + +-static std::string MakeStateFilename(int number); ++static std::string MakeStateFilename(bool useId, int number); ++static std::string MakeStateFilename_partdirectory(int number); ++static std::string MakeStateFilename_partfileName(int number); ++static std::string MakeStateFilename_partfileID(int number); + + // read state timestamps + static std::map GetSavedStates() +@@ -336,7 +339,7 @@ static std::map GetSavedSta + std::map m; + for (int i = 1; i <= (int)NUM_STATES; i++) + { +- std::string filename = MakeStateFilename(i); ++ std::string filename = MakeStateFilename(true, i); + if (File::Exists(filename)) + { + if (ReadHeader(filename, header)) +@@ -536,7 +539,7 @@ bool ReadHeader(const std::string& filen + + std::string GetInfoStringOfSlot(int slot, bool translate) + { +- std::string filename = MakeStateFilename(slot); ++ std::string filename = MakeStateFilename(true, slot); + if (!File::Exists(filename)) + return translate ? Common::GetStringT("Empty") : "Empty"; + +@@ -550,7 +553,7 @@ std::string GetInfoStringOfSlot(int slot + u64 GetUnixTimeOfSlot(int slot) + { + State::StateHeader header; +- if (!ReadHeader(MakeStateFilename(slot), header)) ++ if (!ReadHeader(MakeStateFilename(true, slot), header)) + return 0; + + constexpr u64 MS_PER_SEC = 1000; +@@ -751,20 +754,48 @@ void Shutdown() + } + } + +-static std::string MakeStateFilename(int number) ++static std::string MakeStateFilename(bool useId, int number) + { +- return fmt::format("{}{}.s{:02d}", File::GetUserPath(D_STATESAVES_IDX), +- SConfig::GetInstance().GetGameID(), number); ++ // if the useId flag is set : if the file with name exits, returns it, otherwise, if the file with id exists, returns it, otherwise, return the file with name ++ // => priority with the file with name. ++ // if the game is not loaded from a file (disk), use the gameId ++ std::string filePartName = MakeStateFilename_partfileName(number); ++ std::string fileWithName = fmt::format("{}{}", MakeStateFilename_partdirectory(number), filePartName); ++ if (File::Exists(fileWithName) && filePartName != "") ++ return fileWithName; ++ std::string fileWithId = fmt::format("{}{}", MakeStateFilename_partdirectory(number), MakeStateFilename_partfileID(number)); ++ if (File::Exists(fileWithId) && useId) ++ return fileWithId; ++ if(filePartName == "") return fileWithId; ++ return fileWithName; ++} ++ ++static std::string MakeStateFilename_partdirectory(int number) ++{ ++ return File::GetUserPath(D_STATESAVES_IDX); ++} ++ ++static std::string MakeStateFilename_partfileID(int number) ++{ ++ return fmt::format("{}.s{:02d}", SConfig::GetInstance().GetGameID(), number); ++} ++ ++static std::string MakeStateFilename_partfileName(int number) ++{ ++ std::string basesavestate = SConfig::GetInstance().GetBaseSaveState(); ++ if(basesavestate == "") return ""; ++ return fmt::format("{}.s{:02d}", basesavestate, number); + } + + void Save(int slot, bool wait) + { +- SaveAs(MakeStateFilename(slot), wait); ++ std::string savePath = MakeStateFilename(false, slot); ++ SaveAs(savePath, wait); + } + + void Load(int slot) + { +- LoadAs(MakeStateFilename(slot)); ++ LoadAs(MakeStateFilename(true, slot)); + } + + void LoadLastSaved(int i) +diff -rupN dolphin.orig/Source/Core/DolphinLib.props dolphin/Source/Core/DolphinLib.props +--- dolphin.orig/Source/Core/DolphinLib.props 2024-03-05 04:05:26.590982915 +0000 ++++ dolphin/Source/Core/DolphinLib.props 2024-03-05 04:06:08.240295843 +0000 +@@ -1207,6 +1207,7 @@ + + + ++ + + + +diff -rupN dolphin.orig/Source/Core/DolphinNoGUI/CMakeLists.txt dolphin/Source/Core/DolphinNoGUI/CMakeLists.txt +--- dolphin.orig/Source/Core/DolphinNoGUI/CMakeLists.txt 2024-03-05 04:05:26.590982915 +0000 ++++ dolphin/Source/Core/DolphinNoGUI/CMakeLists.txt 2024-03-05 04:06:08.240295843 +0000 +@@ -17,6 +17,22 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux" + target_sources(dolphin-nogui PRIVATE PlatformFBDev.cpp) + endif() + ++if(ENABLE_WAYLAND AND WAYLAND_FOUND) ++ set(WAYLAND_PLATFORM_SRCS PlatformWayland.cpp) ++ ++ # Generate the xdg-shell and xdg-decoration protocols at build-time. ++ ecm_add_wayland_client_protocol(WAYLAND_PLATFORM_SRCS ++ PROTOCOL "${WAYLAND_PROTOCOLS_PKGDATADIR}/stable/xdg-shell/xdg-shell.xml" ++ BASENAME xdg-shell) ++ ecm_add_wayland_client_protocol(WAYLAND_PLATFORM_SRCS ++ PROTOCOL "${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml" ++ BASENAME xdg-decoration) ++ ++ target_include_directories(dolphin-nogui PRIVATE "${CMAKE_CURRENT_BINARY_DIR}") ++ target_sources(dolphin-nogui PRIVATE "${WAYLAND_PLATFORM_SRCS}") ++ target_link_libraries(dolphin-nogui PRIVATE Wayland::Client) ++endif() ++ + set_target_properties(dolphin-nogui PROPERTIES OUTPUT_NAME dolphin-emu-nogui) + + target_link_libraries(dolphin-nogui +diff -rupN dolphin.orig/Source/Core/DolphinNoGUI/MainNoGUI.cpp dolphin/Source/Core/DolphinNoGUI/MainNoGUI.cpp +--- dolphin.orig/Source/Core/DolphinNoGUI/MainNoGUI.cpp 2024-03-05 04:05:26.590982915 +0000 ++++ dolphin/Source/Core/DolphinNoGUI/MainNoGUI.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -155,6 +155,11 @@ static std::unique_ptr GetPlat + { + std::string platform_name = static_cast(options.get("platform")); + ++#if HAVE_WAYLAND ++ if (platform_name == "wayland") ++ return Platform::CreateWaylandPlatform(); ++#endif ++ + #if HAVE_X11 + if (platform_name == "x11" || platform_name.empty()) + return Platform::CreateX11Platform(); +@@ -200,6 +205,10 @@ int main(int argc, char* argv[]) + , + "win32" + #endif ++#ifdef HAVE_WAYLAND ++ , ++ "wayland" ++#endif + }); + + optparse::Values& options = CommandLineParse::ParseArguments(parser.get(), argc, argv); +diff -rupN dolphin.orig/Source/Core/DolphinNoGUI/Platform.h dolphin/Source/Core/DolphinNoGUI/Platform.h +--- dolphin.orig/Source/Core/DolphinNoGUI/Platform.h 2024-03-05 04:05:26.590982915 +0000 ++++ dolphin/Source/Core/DolphinNoGUI/Platform.h 2024-03-05 04:06:08.240295843 +0000 +@@ -35,6 +35,10 @@ public: + static std::unique_ptr CreateX11Platform(); + #endif + ++#ifdef HAVE_WAYLAND ++ static std::unique_ptr CreateWaylandPlatform(); ++#endif ++ + #ifdef __linux__ + static std::unique_ptr CreateFBDevPlatform(); + #endif +diff -rupN dolphin.orig/Source/Core/DolphinNoGUI/PlatformWayland.cpp dolphin/Source/Core/DolphinNoGUI/PlatformWayland.cpp +--- dolphin.orig/Source/Core/DolphinNoGUI/PlatformWayland.cpp 1970-01-01 00:00:00.000000000 +0000 ++++ dolphin/Source/Core/DolphinNoGUI/PlatformWayland.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -0,0 +1,364 @@ ++// Copyright 2018 Dolphin Emulator Project ++// Licensed under GPLv2+ ++// Refer to the license.txt file included. ++ ++#include ++ ++#include "DolphinNoGUI/Platform.h" ++ ++#include "Common/MsgHandler.h" ++#include "Core/Config/MainSettings.h" ++#include "Core/Core.h" ++#include "Core/State.h" ++ ++#include "Core/HW/GCPad.h" ++#include "InputCommon/GCPadStatus.h" ++#include ++#include "Core/Config/GraphicsSettings.h" ++#include "VideoCommon/VideoConfig.h" ++#include "VideoCommon/OnScreenDisplay.h" ++ ++#include ++#include ++#include ++ ++#include ++#include "wayland-xdg-decoration-client-protocol.h" ++#include "wayland-xdg-shell-client-protocol.h" ++ ++#include "UICommon/X11Utils.h" ++#include "VideoCommon/RenderBase.h" ++ ++namespace ++{ ++class PlatformWayland : public Platform ++{ ++public: ++ ~PlatformWayland() override; ++ ++ bool Init() override; ++ void SetTitle(const std::string& string) override; ++ void MainLoop() override; ++ ++ WindowSystemInfo GetWindowSystemInfo() const; ++ ++private: ++ void ProcessEvents(); ++ ++ static void GlobalRegistryHandler(void* data, wl_registry* registry, uint32_t id, ++ const char* interface, uint32_t version); ++ static void GlobalRegistryRemover(void* data, wl_registry* registry, uint32_t id); ++ static void XDGWMBasePing(void* data, struct xdg_wm_base* xdg_wm_base, uint32_t serial); ++ static void XDGSurfaceConfigure(void* data, struct xdg_surface* xdg_surface, uint32_t serial); ++ static void TopLevelConfigure(void* data, struct xdg_toplevel* xdg_toplevel, int32_t width, ++ int32_t height, struct wl_array* states); ++ static void TopLevelClose(void* data, struct xdg_toplevel* xdg_toplevel); ++ ++ wl_display* m_display = nullptr; ++ wl_registry* m_registry = nullptr; ++ wl_compositor* m_compositor = nullptr; ++ xdg_wm_base* m_xdg_wm_base = nullptr; ++ wl_surface* m_surface = nullptr; ++ wl_region* m_region = nullptr; ++ xdg_surface* m_xdg_surface = nullptr; ++ xdg_toplevel* m_xdg_toplevel = nullptr; ++ zxdg_decoration_manager_v1* m_decoration_manager = nullptr; ++ zxdg_toplevel_decoration_v1* m_toplevel_decoration = nullptr; ++ ++ int m_surface_width = 0; ++ int m_surface_height = 0; ++}; ++ ++PlatformWayland::~PlatformWayland() ++{ ++ if (m_xdg_toplevel) ++ xdg_toplevel_destroy(m_xdg_toplevel); ++ if (m_xdg_surface) ++ xdg_surface_destroy(m_xdg_surface); ++ if (m_surface) ++ wl_surface_destroy(m_surface); ++ if (m_region) ++ wl_region_destroy(m_region); ++ if (m_xdg_wm_base) ++ xdg_wm_base_destroy(m_xdg_wm_base); ++ if (m_compositor) ++ wl_compositor_destroy(m_compositor); ++ if (m_registry) ++ wl_registry_destroy(m_registry); ++ if (m_display) ++ wl_display_disconnect(m_display); ++} ++ ++void PlatformWayland::GlobalRegistryHandler(void* data, wl_registry* registry, uint32_t id, ++ const char* interface, uint32_t version) ++{ ++ PlatformWayland* platform = static_cast(data); ++ if (std::strcmp(interface, wl_compositor_interface.name) == 0) ++ { ++ platform->m_compositor = static_cast( ++ wl_registry_bind(platform->m_registry, id, &wl_compositor_interface, 1)); ++ } ++ else if (std::strcmp(interface, xdg_wm_base_interface.name) == 0) ++ { ++ platform->m_xdg_wm_base = static_cast( ++ wl_registry_bind(platform->m_registry, id, &xdg_wm_base_interface, 1)); ++ } ++ else if (std::strcmp(interface, zxdg_decoration_manager_v1_interface.name) == 0) ++ { ++ platform->m_decoration_manager = static_cast( ++ wl_registry_bind(platform->m_registry, id, &zxdg_decoration_manager_v1_interface, 1)); ++ } ++} ++ ++void PlatformWayland::GlobalRegistryRemover(void* data, wl_registry* registry, uint32_t id) ++{ ++} ++ ++void PlatformWayland::XDGWMBasePing(void* data, struct xdg_wm_base* xdg_wm_base, uint32_t serial) ++{ ++ xdg_wm_base_pong(xdg_wm_base, serial); ++} ++ ++void PlatformWayland::XDGSurfaceConfigure(void* data, struct xdg_surface* xdg_surface, ++ uint32_t serial) ++{ ++ xdg_surface_ack_configure(xdg_surface, serial); ++} ++ ++void PlatformWayland::TopLevelConfigure(void* data, struct xdg_toplevel* xdg_toplevel, ++ int32_t width, int32_t height, struct wl_array* states) ++{ ++ // If this is zero, it's asking us to set the size. ++ if (width == 0 || height == 0) ++ return; ++ ++ PlatformWayland* platform = static_cast(data); ++ platform->m_surface_width = width; ++ platform->m_surface_height = height; ++ if (g_renderer) ++ g_renderer->ResizeSurface(width, height); ++ //if (g_controller_interface.IsInit()) ++ //g_controller_interface.OnWindowResized(width, height); ++} ++ ++void PlatformWayland::TopLevelClose(void* data, struct xdg_toplevel* xdg_toplevel) ++{ ++ PlatformWayland* platform = static_cast(data); ++ platform->Stop(); ++} ++ ++bool PlatformWayland::Init() ++{ ++ m_display = wl_display_connect(nullptr); ++ if (!m_display) ++ { ++ //PanicAlert("Failed to connect to Wayland display."); ++ return false; ++ } ++ ++ static const wl_registry_listener registry_listener = {GlobalRegistryHandler, ++ GlobalRegistryRemover}; ++ m_registry = wl_display_get_registry(m_display); ++ wl_registry_add_listener(m_registry, ®istry_listener, this); ++ ++ // Call back to registry listener to get compositor/shell. ++ wl_display_dispatch(m_display); ++ wl_display_roundtrip(m_display); ++ ++ // We need a shell/compositor, or at least one we understand. ++ if (!m_compositor || !m_display || !m_xdg_wm_base) ++ { ++ std::fprintf(stderr, "Missing Wayland shell/compositor\n"); ++ return false; ++ } ++ ++ // Create the compositor and shell surface. ++ if (!(m_surface = wl_compositor_create_surface(m_compositor)) || ++ !(m_xdg_surface = xdg_wm_base_get_xdg_surface(m_xdg_wm_base, m_surface)) || ++ !(m_xdg_toplevel = xdg_surface_get_toplevel(m_xdg_surface))) ++ { ++ std::fprintf(stderr, "Failed to create compositor/shell surfaces\n"); ++ return false; ++ } ++ ++ static const xdg_wm_base_listener xdg_wm_base_listener = {XDGWMBasePing}; ++ xdg_wm_base_add_listener(m_xdg_wm_base, &xdg_wm_base_listener, this); ++ ++ static const xdg_surface_listener shell_surface_listener = {XDGSurfaceConfigure}; ++ xdg_surface_add_listener(m_xdg_surface, &shell_surface_listener, this); ++ ++ static const xdg_toplevel_listener toplevel_listener = {TopLevelConfigure, TopLevelClose}; ++ xdg_toplevel_add_listener(m_xdg_toplevel, &toplevel_listener, this); ++ ++ // Create region in the surface to draw into. ++ m_surface_width = Config::Get(Config::MAIN_RENDER_WINDOW_WIDTH); ++ m_surface_height = Config::Get(Config::MAIN_RENDER_WINDOW_HEIGHT); ++ m_region = wl_compositor_create_region(m_compositor); ++ wl_region_add(m_region, 0, 0, m_surface_width, m_surface_height); ++ wl_surface_set_opaque_region(m_surface, m_region); ++ wl_surface_commit(m_surface); ++ ++ // This doesn't seem to have any effect on kwin... ++ xdg_surface_set_window_geometry(m_xdg_surface, Config::Get(Config::MAIN_RENDER_WINDOW_XPOS), ++ Config::Get(Config::MAIN_RENDER_WINDOW_YPOS), ++ Config::Get(Config::MAIN_RENDER_WINDOW_WIDTH), ++ Config::Get(Config::MAIN_RENDER_WINDOW_HEIGHT)); ++ ++ if (m_decoration_manager) ++ { ++ m_toplevel_decoration = ++ zxdg_decoration_manager_v1_get_toplevel_decoration(m_decoration_manager, m_xdg_toplevel); ++ if (m_toplevel_decoration) ++ zxdg_toplevel_decoration_v1_set_mode(m_toplevel_decoration, ++ ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); ++ } ++ ++ return true; ++} ++ ++void PlatformWayland::SetTitle(const std::string& string) ++{ ++ xdg_toplevel_set_title(m_xdg_toplevel, string.c_str()); ++} ++ ++void PlatformWayland::MainLoop() ++{ ++ while (IsRunning()) ++ { ++ static int hotkey = 0; ++ static int slot = 0; ++ static int fps = 0; ++ static int aspect = 0; ++ static int fforward = 0; ++ static int ires = 0; ++ ++ UpdateRunningFlag(); ++ Core::HostDispatchJobs(); ++ ProcessEvents(); ++ ++ if(Pad::IsInitialized()) { ++ GCPadStatus x = Pad::GetStatus(0); ++ ++ if( (x.button & PAD_BUTTON_HOTKEY) == PAD_BUTTON_HOTKEY) { // hotkey pressed ++ if(hotkey == 1) { ++ hotkey = 2; ++ } ++ } else { ++ hotkey = 1; // assure hotkey is released between actions ++ } ++ ++ if(hotkey == 2) { // hotkey pressed ++ if( (x.button & PAD_BUTTON_START) == PAD_BUTTON_START) { ++ RequestShutdown(); ++ hotkey = 0; ++ } ++ ++ if( (x.button & PAD_TRIGGER_L) == PAD_TRIGGER_L) { ++ State::Load(slot); ++ hotkey = 0; ++ } ++ if( (x.button & PAD_TRIGGER_R) == PAD_TRIGGER_R) { ++ State::Save(slot); ++ hotkey = 0; ++ } ++ if( (x.button & PAD_BUTTON_DOWN) == PAD_BUTTON_DOWN) { ++ if(slot > 0) slot--; ++ Core::DisplayMessage(fmt::format("Slot {} selected", slot), 4000); ++ hotkey = 0; ++ } ++ if( (x.button & PAD_BUTTON_UP) == PAD_BUTTON_UP) { ++ if(slot < 10) slot++; ++ Core::DisplayMessage(fmt::format("Slot {} selected", slot), 4000); ++ hotkey = 0; ++ } ++ if( (x.button & PAD_BUTTON_A) == PAD_BUTTON_A) { ++ Core::SaveScreenShot(); ++ hotkey = 0; ++ } ++ if( (x.button & PAD_BUTTON_Y) == PAD_BUTTON_Y) { ++ if(fps == 0) { ++ Config::SetCurrent(Config::GFX_SHOW_FPS, True); ++ fps = 1; ++ } else { ++ Config::SetCurrent(Config::GFX_SHOW_FPS, False); ++ fps = 0; ++ } ++ hotkey = 0; ++ } ++ if( (x.button & PAD_BUTTON_X) == PAD_BUTTON_X) { ++ if(aspect == 0) { ++ Config::SetCurrent(Config::GFX_ASPECT_RATIO, AspectMode::Stretch); ++ aspect = 1; ++ } else { ++ Config::SetCurrent(Config::GFX_ASPECT_RATIO, AspectMode::Auto); ++ aspect = 0; ++ } ++ hotkey = 0; ++ } ++ if( (x.button & PAD_BUTTON_B) == PAD_BUTTON_B) { ++ if(ires == 0) { ++ Config::SetCurrent(Config::GFX_EFB_SCALE, 2); ++ OSD::AddMessage("Internal Resolution: 480P"); ++ ires = 2; ++ } ++ else if(ires == 2) { ++ Config::SetCurrent(Config::GFX_EFB_SCALE, 4); ++ OSD::AddMessage("Internal Resolution: 720P"); ++ ires = 4; ++ } ++ else if(ires == 4) { ++ Config::SetCurrent(Config::GFX_EFB_SCALE, 6); ++ OSD::AddMessage("Internal Resolution: 1080P"); ++ ires = 6; ++ } else { ++ Config::SetCurrent(Config::GFX_EFB_SCALE, 1); ++ OSD::AddMessage("Internal Resolution: 240P"); ++ ires = 0; ++ } ++ hotkey = 0; ++ } ++ if( (x.button & PAD_TRIGGER_Z) == PAD_TRIGGER_Z) { ++ if(fforward == 0) { ++ auto speed = Config::Get(Config::MAIN_EMULATION_SPEED) + 1.0; ++ speed = (speed >= 0.95 && speed <= 1.05) ? 1.0 : speed; ++ Config::SetCurrent(Config::MAIN_EMULATION_SPEED, speed); ++ OSD::AddMessage("Fast Forward: ON"); ++ fforward = 1; ++ } else { ++ auto speed = Config::Get(Config::MAIN_EMULATION_SPEED) - 1.0; ++ speed = (speed <= 0 || (speed >= 0.95 && speed <= 1.05)) ? 1.0 : speed; ++ Config::SetCurrent(Config::MAIN_EMULATION_SPEED, speed); ++ OSD::AddMessage("Fast Forward: OFF"); ++ fforward = 0; ++ } ++ hotkey = 0; ++ } ++ } ++ } ++ ++ // TODO: Is this sleep appropriate? ++ std::this_thread::sleep_for(std::chrono::milliseconds(1)); ++ } ++} ++ ++WindowSystemInfo PlatformWayland::GetWindowSystemInfo() const ++{ ++ WindowSystemInfo wsi; ++ wsi.type = WindowSystemType::Wayland; ++ wsi.display_connection = static_cast(m_display); ++ wsi.render_surface = reinterpret_cast(m_surface); ++ wsi.render_surface_width = m_surface_width; ++ wsi.render_surface_height = m_surface_height; ++ return wsi; ++} ++ ++void PlatformWayland::ProcessEvents() ++{ ++ wl_display_dispatch_pending(m_display); ++} ++} // namespace ++ ++std::unique_ptr Platform::CreateWaylandPlatform() ++{ ++ return std::make_unique(); ++} +diff -rupN dolphin.orig/Source/Core/DolphinNoGUI/PlatformX11.cpp dolphin/Source/Core/DolphinNoGUI/PlatformX11.cpp +--- dolphin.orig/Source/Core/DolphinNoGUI/PlatformX11.cpp 2024-03-05 04:05:26.590982915 +0000 ++++ dolphin/Source/Core/DolphinNoGUI/PlatformX11.cpp 2024-03-05 04:21:20.855117890 +0000 +@@ -16,6 +16,13 @@ static constexpr auto X_None = None; + #include "Core/Core.h" + #include "Core/State.h" + ++#include "Core/HW/GCPad.h" ++#include "InputCommon/GCPadStatus.h" ++#include ++#include "Core/Config/GraphicsSettings.h" ++#include "VideoCommon/VideoConfig.h" ++#include "VideoCommon/OnScreenDisplay.h" ++ + #include + #include + #include +@@ -57,8 +64,8 @@ private: + #endif + int m_window_x = Config::Get(Config::MAIN_RENDER_WINDOW_XPOS); + int m_window_y = Config::Get(Config::MAIN_RENDER_WINDOW_YPOS); +- unsigned int m_window_width = Config::Get(Config::MAIN_RENDER_WINDOW_WIDTH); +- unsigned int m_window_height = Config::Get(Config::MAIN_RENDER_WINDOW_HEIGHT); ++ int m_window_width = Config::Get(Config::MAIN_RENDER_WINDOW_WIDTH); ++ int m_window_height = Config::Get(Config::MAIN_RENDER_WINDOW_HEIGHT); + }; + + PlatformX11::~PlatformX11() +@@ -149,11 +156,118 @@ void PlatformX11::MainLoop() + { + while (IsRunning()) + { ++ static int hotkey = 0; ++ static int slot = 0; ++ static int fps = 0; ++ static int aspect = 0; ++ static int fforward = 0; ++ static int ires = 0; ++ + UpdateRunningFlag(); + Core::HostDispatchJobs(); + ProcessEvents(); + UpdateWindowPosition(); + ++ if(Pad::IsInitialized()) { ++ GCPadStatus x = Pad::GetStatus(0); ++ ++ if( (x.button & PAD_BUTTON_HOTKEY) == PAD_BUTTON_HOTKEY) { // hotkey pressed ++ if(hotkey == 1) { ++ hotkey = 2; ++ } ++ } else { ++ hotkey = 1; // assure hotkey is released between actions ++ } ++ ++ if(hotkey == 2) { // hotkey pressed ++ if( (x.button & PAD_BUTTON_START) == PAD_BUTTON_START) { ++ RequestShutdown(); ++ hotkey = 0; ++ } ++ ++ if( (x.button & PAD_TRIGGER_L) == PAD_TRIGGER_L) { ++ State::Load(slot); ++ hotkey = 0; ++ } ++ if( (x.button & PAD_TRIGGER_R) == PAD_TRIGGER_R) { ++ State::Save(slot); ++ hotkey = 0; ++ } ++ if( (x.button & PAD_BUTTON_DOWN) == PAD_BUTTON_DOWN) { ++ if(slot > 0) slot--; ++ Core::DisplayMessage(fmt::format("Slot {} selected", slot), 4000); ++ hotkey = 0; ++ } ++ if( (x.button & PAD_BUTTON_UP) == PAD_BUTTON_UP) { ++ if(slot < 10) slot++; ++ Core::DisplayMessage(fmt::format("Slot {} selected", slot), 4000); ++ hotkey = 0; ++ } ++ if( (x.button & PAD_BUTTON_A) == PAD_BUTTON_A) { ++ Core::SaveScreenShot(); ++ hotkey = 0; ++ } ++ if( (x.button & PAD_BUTTON_Y) == PAD_BUTTON_Y) { ++ if(fps == 0) { ++ Config::SetCurrent(Config::GFX_SHOW_FPS, True); ++ fps = 1; ++ } else { ++ Config::SetCurrent(Config::GFX_SHOW_FPS, False); ++ fps = 0; ++ } ++ hotkey = 0; ++ } ++ if( (x.button & PAD_BUTTON_X) == PAD_BUTTON_X) { ++ if(aspect == 0) { ++ Config::SetCurrent(Config::GFX_ASPECT_RATIO, AspectMode::Stretch); ++ aspect = 1; ++ } else { ++ Config::SetCurrent(Config::GFX_ASPECT_RATIO, AspectMode::Auto); ++ aspect = 0; ++ } ++ hotkey = 0; ++ } ++ if( (x.button & PAD_BUTTON_B) == PAD_BUTTON_B) { ++ if(ires == 0) { ++ Config::SetCurrent(Config::GFX_EFB_SCALE, 2); ++ OSD::AddMessage("Internal Resolution: 480P"); ++ ires = 2; ++ } ++ else if(ires == 2) { ++ Config::SetCurrent(Config::GFX_EFB_SCALE, 4); ++ OSD::AddMessage("Internal Resolution: 720P"); ++ ires = 4; ++ } ++ else if(ires == 4) { ++ Config::SetCurrent(Config::GFX_EFB_SCALE, 6); ++ OSD::AddMessage("Internal Resolution: 1080P"); ++ ires = 6; ++ } else { ++ Config::SetCurrent(Config::GFX_EFB_SCALE, 1); ++ OSD::AddMessage("Internal Resolution: 240P"); ++ ires = 0; ++ } ++ hotkey = 0; ++ } ++ if( (x.button & PAD_TRIGGER_Z) == PAD_TRIGGER_Z) { ++ if(fforward == 0) { ++ auto speed = Config::Get(Config::MAIN_EMULATION_SPEED) + 1.0; ++ speed = (speed >= 0.95 && speed <= 1.05) ? 1.0 : speed; ++ Config::SetCurrent(Config::MAIN_EMULATION_SPEED, speed); ++ OSD::AddMessage("Fast Forward: ON"); ++ fforward = 1; ++ } else { ++ auto speed = Config::Get(Config::MAIN_EMULATION_SPEED) - 1.0; ++ speed = (speed <= 0 || (speed >= 0.95 && speed <= 1.05)) ? 1.0 : speed; ++ Config::SetCurrent(Config::MAIN_EMULATION_SPEED, speed); ++ OSD::AddMessage("Fast Forward: OFF"); ++ fforward = 0; ++ } ++ hotkey = 0; ++ } ++ } ++ } ++ + // TODO: Is this sleep appropriate? + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } +@@ -166,6 +280,8 @@ WindowSystemInfo PlatformX11::GetWindowS + wsi.display_connection = static_cast(m_display); + wsi.render_window = reinterpret_cast(m_window); + wsi.render_surface = reinterpret_cast(m_window); ++ wsi.render_surface_width = m_window_width; ++ wsi.render_surface_height = m_window_height; + return wsi; + } + +@@ -176,8 +292,9 @@ void PlatformX11::UpdateWindowPosition() + + Window winDummy; + unsigned int borderDummy, depthDummy; +- XGetGeometry(m_display, m_window, &winDummy, &m_window_x, &m_window_y, &m_window_width, +- &m_window_height, &borderDummy, &depthDummy); ++ XGetGeometry(m_display, m_window, &winDummy, &m_window_x, &m_window_y, ++ reinterpret_cast(&m_window_width), ++ reinterpret_cast(&m_window_height), &borderDummy, &depthDummy); + } + + void PlatformX11::ProcessEvents() +@@ -264,7 +381,10 @@ void PlatformX11::ProcessEvents() + case ConfigureNotify: + { + if (g_renderer) +- g_renderer->ResizeSurface(); ++ { ++ UpdateWindowPosition(); ++ g_renderer->ResizeSurface(m_window_width, m_window_height); ++ } + } + break; + } +diff -rupN dolphin.orig/Source/Core/InputCommon/GCPadStatus.h dolphin/Source/Core/InputCommon/GCPadStatus.h +--- dolphin.orig/Source/Core/InputCommon/GCPadStatus.h 2024-03-05 04:05:26.598983167 +0000 ++++ dolphin/Source/Core/InputCommon/GCPadStatus.h 2024-03-05 04:06:08.240295843 +0000 +@@ -26,6 +26,7 @@ enum PadButton + PAD_BUTTON_X = 0x0400, + PAD_BUTTON_Y = 0x0800, + PAD_BUTTON_START = 0x1000, ++ PAD_BUTTON_HOTKEY = 0x2000, + }; + + struct GCPadStatus +diff -rupN dolphin.orig/Source/Core/VideoBackends/OGL/OGLRender.cpp dolphin/Source/Core/VideoBackends/OGL/OGLRender.cpp +--- dolphin.orig/Source/Core/VideoBackends/OGL/OGLRender.cpp 2024-03-05 04:05:26.598983167 +0000 ++++ dolphin/Source/Core/VideoBackends/OGL/OGLRender.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -471,11 +471,7 @@ Renderer::Renderer(std::unique_ptrIsGLES()) + { +- g_ogl_config.SupportedESPointSize = GLExtensions::Supports("GL_OES_geometry_point_size") ? 1 : +- GLExtensions::Supports("GL_EXT_geometry_point_size") ? 2 : +- 0; ++ g_ogl_config.SupportedESPointSize = ++ GLExtensions::Supports("GL_OES_geometry_point_size") ? EsPointSizeType::PointSizeOes : ++ GLExtensions::Supports("GL_EXT_geometry_point_size") ? EsPointSizeType::PointSizeExt : ++ EsPointSizeType::PointSizeNone; + g_ogl_config.SupportedESTextureBuffer = + GLExtensions::Supports("VERSION_GLES_3_2") ? EsTexbufType::TexbufCore : + GLExtensions::Supports("GL_OES_texture_buffer") ? EsTexbufType::TexbufOes : +@@ -548,21 +545,16 @@ Renderer::Renderer(std::unique_ptr 0; ++ g_Config.backend_info.bSupportsGeometryShaders && ++ g_ogl_config.SupportedESPointSize != EsPointSizeType::PointSizeNone; + g_Config.backend_info.bSupportsSSAA = g_ogl_config.bSupportsAEP; + g_Config.backend_info.bSupportsFragmentStoresAndAtomics = true; + g_ogl_config.bSupportsMSAA = true; + g_ogl_config.bSupportsTextureStorage = true; +- g_ogl_config.bSupports2DTextureStorageMultisample = true; ++ if (GLExtensions::Supports("GL_OES_texture_storage_multisample_2d_array")) ++ g_ogl_config.SupportedMultisampleTexStorage = MultisampleTexStorageType::TexStorageOes; + g_Config.backend_info.bSupportsBitfield = true; + g_Config.backend_info.bSupportsDynamicSamplerIndexing = g_ogl_config.bSupportsAEP; +- if (g_ActiveConfig.stereo_mode != StereoMode::Off && g_ActiveConfig.iMultisamples > 1 && +- !g_ogl_config.bSupports3DTextureStorageMultisample) +- { +- // GLES 3.1 can't support stereo rendering and MSAA +- OSD::AddMessage("MSAA Stereo rendering isn't supported by your GPU.", 10000); +- Config::SetCurrent(Config::GFX_MSAA, UINT32_C(1)); +- } + } + else + { +@@ -572,7 +564,8 @@ Renderer::Renderer(std::unique_ptr 0; ++ g_Config.backend_info.bSupportsGSInstancing = ++ g_ogl_config.SupportedESPointSize != EsPointSizeType::PointSizeNone; + g_Config.backend_info.bSupportsPaletteConversion = true; + g_Config.backend_info.bSupportsSSAA = true; + g_Config.backend_info.bSupportsFragmentStoresAndAtomics = true; +@@ -581,8 +574,7 @@ Renderer::Renderer(std::unique_ptrUpdateSurface(m_new_surface_handle); ++ m_main_gl_context->UpdateSurface(m_new_surface_handle, m_new_surface_width, m_new_surface_height); + m_new_surface_handle = nullptr; + + // With a surface change, the window likely has new dimensions. +@@ -1093,7 +1088,7 @@ void Renderer::CheckForSurfaceResize() + if (!m_surface_resized.TestAndClear()) + return; + +- m_main_gl_context->Update(); ++ m_main_gl_context->UpdateDimensions(m_new_surface_width, m_new_surface_height); + m_backbuffer_width = m_main_gl_context->GetBackBufferWidth(); + m_backbuffer_height = m_main_gl_context->GetBackBufferHeight(); + m_system_framebuffer->UpdateDimensions(m_backbuffer_width, m_backbuffer_height); +diff -rupN dolphin.orig/Source/Core/VideoBackends/OGL/OGLRender.h dolphin/Source/Core/VideoBackends/OGL/OGLRender.h +--- dolphin.orig/Source/Core/VideoBackends/OGL/OGLRender.h 2024-03-05 04:05:26.598983167 +0000 ++++ dolphin/Source/Core/VideoBackends/OGL/OGLRender.h 2024-03-05 04:06:08.240295843 +0000 +@@ -31,6 +31,14 @@ enum GlslVersion + GlslEs310, // GLES 3.1 + GlslEs320, // GLES 3.2 + }; ++ ++enum class EsPointSizeType ++{ ++ PointSizeNone, ++ PointSizeOes, ++ PointSizeExt, ++}; ++ + enum class EsTexbufType + { + TexbufNone, +@@ -46,6 +54,13 @@ enum class EsFbFetchType + FbFetchArm, + }; + ++enum class MultisampleTexStorageType ++{ ++ TexStorageNone, ++ TexStorageCore, ++ TexStorageOes, ++}; ++ + // ogl-only config, so not in VideoConfig.h + struct VideoConfig + { +@@ -60,11 +75,10 @@ struct VideoConfig + bool bSupportsAEP; + bool bSupportsDebug; + bool bSupportsCopySubImage; +- u8 SupportedESPointSize; ++ EsPointSizeType SupportedESPointSize; + EsTexbufType SupportedESTextureBuffer; + bool bSupportsTextureStorage; +- bool bSupports2DTextureStorageMultisample; +- bool bSupports3DTextureStorageMultisample; ++ MultisampleTexStorageType SupportedMultisampleTexStorage; + bool bSupportsConservativeDepth; + bool bSupportsImageLoadStore; + bool bSupportsAniso; +diff -rupN dolphin.orig/Source/Core/VideoBackends/OGL/OGLTexture.cpp dolphin/Source/Core/VideoBackends/OGL/OGLTexture.cpp +--- dolphin.orig/Source/Core/VideoBackends/OGL/OGLTexture.cpp 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoBackends/OGL/OGLTexture.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -128,12 +128,18 @@ OGLTexture::OGLTexture(const TextureConf + GLenum gl_internal_format = GetGLInternalFormatForTextureFormat(m_config.format, true); + if (tex_config.IsMultisampled()) + { +- if (g_ogl_config.bSupportsTextureStorage) ++ ASSERT(g_ogl_config.bSupportsMSAA); ++ if (g_ogl_config.SupportedMultisampleTexStorage != MultisampleTexStorageType::TexStorageNone) ++ { + glTexStorage3DMultisample(target, tex_config.samples, gl_internal_format, m_config.width, + m_config.height, m_config.layers, GL_FALSE); ++ } + else ++ { ++ ASSERT(!g_ogl_config.bIsES); + glTexImage3DMultisample(target, tex_config.samples, gl_internal_format, m_config.width, + m_config.height, m_config.layers, GL_FALSE); ++ } + } + else if (g_ogl_config.bSupportsTextureStorage) + { +diff -rupN dolphin.orig/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp dolphin/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp +--- dolphin.orig/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -661,12 +661,13 @@ void ProgramShaderCache::CreateHeader() + std::string SupportedESTextureBuffer; + switch (g_ogl_config.SupportedESPointSize) + { +- case 1: ++ case EsPointSizeType::PointSizeOes: + SupportedESPointSize = "#extension GL_OES_geometry_point_size : enable"; + break; +- case 2: ++ case EsPointSizeType::PointSizeExt: + SupportedESPointSize = "#extension GL_EXT_geometry_point_size : enable"; + break; ++ case EsPointSizeType::PointSizeNone: + default: + SupportedESPointSize = ""; + break; +@@ -718,6 +719,13 @@ void ProgramShaderCache::CreateHeader() + break; + } + ++ // The sampler2DMSArray keyword is reserved in GLSL ES 3.0 and 3.1, but is available in 3.2 and ++ // with GL_OES_texture_storage_multisample_2d_array for 3.1. ++ // See https://bugs.dolphin-emu.org/issues/13198. ++ const bool use_multisample_2d_array_precision = ++ v >= GlslEs320 || ++ g_ogl_config.SupportedMultisampleTexStorage != MultisampleTexStorageType::TexStorageNone; ++ + std::string shader_shuffle_string; + if (g_ogl_config.bSupportsShaderThreadShuffleNV) + { +@@ -762,6 +770,7 @@ void ProgramShaderCache::CreateHeader() + "{}\n" // shader thread shuffle + "{}\n" // derivative control + "{}\n" // query levels ++ "{}\n" // OES multisample texture storage + + // Precision defines for GLSL ES + "{}\n" +@@ -847,12 +856,18 @@ void ProgramShaderCache::CreateHeader() + g_ActiveConfig.backend_info.bSupportsTextureQueryLevels ? + "#extension GL_ARB_texture_query_levels : enable" : + "", ++ // Note: GL_ARB_texture_storage_multisample doesn't have an #extension, as it doesn't ++ // need to change GLSL, but on GLES 3.1 sampler2DMSArray is a reserved keyword unless ++ // the extension is enabled. Thus, we don't need to check TexStorageCore/have an ARB version. ++ g_ogl_config.SupportedMultisampleTexStorage == MultisampleTexStorageType::TexStorageOes ? ++ "#extension GL_OES_texture_storage_multisample_2d_array : enable" : ++ "", + is_glsles ? "precision highp float;" : "", is_glsles ? "precision highp int;" : "", + is_glsles ? "precision highp sampler2DArray;" : "", + (is_glsles && g_ActiveConfig.backend_info.bSupportsPaletteConversion) ? + "precision highp usamplerBuffer;" : + "", +- v > GlslEs300 ? "precision highp sampler2DMSArray;" : "", ++ use_multisample_2d_array_precision ? "precision highp sampler2DMSArray;" : "", + v >= GlslEs310 ? "precision highp image2DArray;" : ""); + } + +diff -rupN dolphin.orig/Source/Core/VideoBackends/Software/SWOGLWindow.cpp dolphin/Source/Core/VideoBackends/Software/SWOGLWindow.cpp +--- dolphin.orig/Source/Core/VideoBackends/Software/SWOGLWindow.cpp 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoBackends/Software/SWOGLWindow.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -32,6 +32,16 @@ bool SWOGLWindow::IsHeadless() const + return m_gl_context->IsHeadless(); + } + ++u32 SWOGLWindow::GetWidth() const ++{ ++ return m_gl_context->GetBackBufferWidth(); ++} ++ ++u32 SWOGLWindow::GetHeight() const ++{ ++ return m_gl_context->GetBackBufferHeight(); ++} ++ + bool SWOGLWindow::Initialize(const WindowSystemInfo& wsi) + { + m_gl_context = GLContext::Create(wsi); +@@ -84,11 +94,17 @@ bool SWOGLWindow::Initialize(const Windo + return true; + } + ++ ++void SWOGLWindow::UpdateDimensions(int window_width, int window_height) ++{ ++ // just updates the render window position and the backbuffer size ++ m_gl_context->UpdateDimensions(window_width, window_height); ++} ++ + void SWOGLWindow::ShowImage(const AbstractTexture* image, + const MathUtil::Rectangle& xfb_region) + { + const SW::SWTexture* sw_image = static_cast(image); +- m_gl_context->Update(); // just updates the render window position and the backbuffer size + + GLsizei glWidth = (GLsizei)m_gl_context->GetBackBufferWidth(); + GLsizei glHeight = (GLsizei)m_gl_context->GetBackBufferHeight(); +diff -rupN dolphin.orig/Source/Core/VideoBackends/Software/SWOGLWindow.h dolphin/Source/Core/VideoBackends/Software/SWOGLWindow.h +--- dolphin.orig/Source/Core/VideoBackends/Software/SWOGLWindow.h 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoBackends/Software/SWOGLWindow.h 2024-03-05 04:06:08.240295843 +0000 +@@ -20,6 +20,10 @@ public: + GLContext* GetContext() const { return m_gl_context.get(); } + bool IsHeadless() const; + ++ u32 GetWidth() const; ++ u32 GetHeight() const; ++ void UpdateDimensions(int window_width, int window_height); ++ + // Image to show, will be swapped immediately + void ShowImage(const AbstractTexture* image, const MathUtil::Rectangle& xfb_region); + +diff -rupN dolphin.orig/Source/Core/VideoBackends/Software/SWRenderer.cpp dolphin/Source/Core/VideoBackends/Software/SWRenderer.cpp +--- dolphin.orig/Source/Core/VideoBackends/Software/SWRenderer.cpp 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoBackends/Software/SWRenderer.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -60,17 +60,17 @@ SWRenderer::CreateFramebuffer(AbstractTe + static_cast(depth_attachment)); + } + +-void SWRenderer::BindBackbuffer(const ClearColor& clear_color) +-{ ++//void SWRenderer::BindBackbuffer(const ClearColor& clear_color) ++//{ + // Look for framebuffer resizes +- if (!m_surface_resized.TestAndClear()) +- return; ++ //if (!m_surface_resized.TestAndClear()) ++ //return; + +- GLContext* context = m_window->GetContext(); +- context->Update(); +- m_backbuffer_width = context->GetBackBufferWidth(); +- m_backbuffer_height = context->GetBackBufferHeight(); +-} ++ //GLContext* context = m_window->GetContext(); ++ //context->UpdateDimensions(window_width, window_height); ++ //m_backbuffer_width = context->GetBackBufferWidth(); ++ //m_backbuffer_height = context->GetBackBufferHeight(); ++//} + + class SWShader final : public AbstractShader + { +@@ -108,7 +108,7 @@ std::unique_ptr SWRend + { + return std::make_unique(); + } +- ++ + // Called on the GPU thread + void SWRenderer::RenderXFBToScreen(const MathUtil::Rectangle& target_rc, + const AbstractTexture* source_texture, +@@ -118,6 +118,16 @@ void SWRenderer::RenderXFBToScreen(const + m_window->ShowImage(source_texture, source_rc); + } + ++void SWRenderer::CheckForSurfaceResize() ++{ ++ if (!m_surface_resized.TestAndClear()) ++ return; ++ ++ m_window->UpdateDimensions(m_new_surface_width, m_new_surface_height); ++ m_backbuffer_width = static_cast(m_window->GetWidth()); ++ m_backbuffer_height = static_cast(m_window->GetHeight()); ++} ++ + u32 SWRenderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputData) + { + u32 value = 0; +diff -rupN dolphin.orig/Source/Core/VideoBackends/Software/SWRenderer.h dolphin/Source/Core/VideoBackends/Software/SWRenderer.h +--- dolphin.orig/Source/Core/VideoBackends/Software/SWRenderer.h 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoBackends/Software/SWRenderer.h 2024-03-05 04:06:08.240295843 +0000 +@@ -29,7 +29,7 @@ public: + std::unique_ptr + CreateFramebuffer(AbstractTexture* color_attachment, AbstractTexture* depth_attachment) override; + +- void BindBackbuffer(const ClearColor& clear_color = {}) override; ++ //void BindBackbuffer(const ClearColor& clear_color = {}) override; + + std::unique_ptr CreateShaderFromSource(ShaderStage stage, std::string_view source, + std::string_view name) override; +@@ -64,6 +64,8 @@ protected: + std::unique_ptr CreateBoundingBox() const override; + + private: ++void CheckForSurfaceResize(); ++ + std::unique_ptr m_window; + }; + } // namespace SW +diff -rupN dolphin.orig/Source/Core/VideoBackends/Vulkan/CMakeLists.txt dolphin/Source/Core/VideoBackends/Vulkan/CMakeLists.txt +--- dolphin.orig/Source/Core/VideoBackends/Vulkan/CMakeLists.txt 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoBackends/Vulkan/CMakeLists.txt 2024-03-05 04:06:08.240295843 +0000 +@@ -35,6 +35,8 @@ add_library(videovulkan + VulkanContext.h + VulkanLoader.cpp + VulkanLoader.h ++ VKScheduler.h ++ VKScheduler.cpp + ) + + target_link_libraries(videovulkan +diff -rupN dolphin.orig/Source/Core/VideoBackends/Vulkan/CommandBufferManager.cpp dolphin/Source/Core/VideoBackends/Vulkan/CommandBufferManager.cpp +--- dolphin.orig/Source/Core/VideoBackends/Vulkan/CommandBufferManager.cpp 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoBackends/Vulkan/CommandBufferManager.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -10,24 +10,24 @@ + #include "Common/MsgHandler.h" + #include "Common/Thread.h" + ++#include "VideoBackends/Vulkan/StateTracker.h" + #include "VideoBackends/Vulkan/VulkanContext.h" + + namespace Vulkan + { +-CommandBufferManager::CommandBufferManager(bool use_threaded_submission) +- : m_use_threaded_submission(use_threaded_submission) ++CommandBufferManager::CommandBufferManager() ++ : m_state_tracker(std::make_unique(this)), m_last_present_done(true) + { + } + + CommandBufferManager::~CommandBufferManager() + { + // If the worker thread is enabled, stop and block until it exits. +- if (m_use_threaded_submission) +- { +- WaitForWorkerThreadIdle(); +- m_submit_loop->Stop(); +- m_submit_thread.join(); +- } ++ WaitForSubmitWorkerThreadIdle(); ++ m_submit_loop->Stop(); ++ m_fence_loop->Stop(); ++ m_submit_thread.join(); ++ m_fence_thread.join(); + + DestroyCommandBuffers(); + } +@@ -37,10 +37,13 @@ bool CommandBufferManager::Initialize() + if (!CreateCommandBuffers()) + return false; + +- if (m_use_threaded_submission && !CreateSubmitThread()) ++ if (!CreateFenceThread()) + return false; + +- return true; ++ if (!CreateSubmitThread()) ++ return false; ++ ++ return m_state_tracker->Initialize(); + } + + bool CommandBufferManager::CreateCommandBuffers() +@@ -86,13 +89,6 @@ bool CommandBufferManager::CreateCommand + LOG_VULKAN_ERROR(res, "vkCreateFence failed: "); + return false; + } +- +- res = vkCreateSemaphore(device, &semaphore_create_info, nullptr, &resources.semaphore); +- if (res != VK_SUCCESS) +- { +- LOG_VULKAN_ERROR(res, "vkCreateSemaphore failed: "); +- return false; +- } + } + + res = vkCreateSemaphore(device, &semaphore_create_info, nullptr, &m_present_semaphore); +@@ -125,9 +121,6 @@ void CommandBufferManager::DestroyComman + for (auto& it : resources.cleanup_resources) + it(); + +- if (resources.semaphore != VK_NULL_HANDLE) +- vkDestroySemaphore(device, resources.semaphore, nullptr); +- + if (resources.fence != VK_NULL_HANDLE) + vkDestroyFence(device, resources.fence, nullptr); + } +@@ -215,11 +208,42 @@ VkDescriptorSet CommandBufferManager::Al + return descriptor_set; + } + ++bool CommandBufferManager::CreateFenceThread() ++{ ++ m_fence_loop = std::make_unique(); ++ m_fence_thread = std::thread([this]() { ++ Common::SetCurrentThreadName("Vulkan FenceThread"); ++ m_fence_loop->Run([this]() { ++ PendingFenceCounter fence; ++ { ++ std::lock_guard guard(m_pending_fences_lock); ++ if (m_pending_fences.empty()) ++ { ++ m_fence_condvar.notify_all(); ++ m_fence_loop->AllowSleep(); ++ return; ++ } ++ ++ fence = m_pending_fences.front(); ++ m_pending_fences.pop_front(); ++ } ++ ++ vkWaitForFences(g_vulkan_context->GetDevice(), 1, &fence.fence, true, ~0ul); ++ ++ std::lock_guard guard(m_pending_fences_lock); ++ m_completed_fence_counter.store(fence.counter, std::memory_order_release); ++ m_fence_condvar.notify_all(); ++ }); ++ }); ++ ++ return true; ++} ++ + bool CommandBufferManager::CreateSubmitThread() + { + m_submit_loop = std::make_unique(); + m_submit_thread = std::thread([this]() { +- Common::SetCurrentThreadName("Vulkan CommandBufferManager SubmitThread"); ++ Common::SetCurrentThreadName("Vulkan SubmitThread"); + + m_submit_loop->Run([this]() { + PendingCommandBufferSubmit submit; +@@ -227,9 +251,9 @@ bool CommandBufferManager::CreateSubmitT + std::lock_guard guard(m_pending_submit_lock); + if (m_pending_submits.empty()) + { +- m_submit_loop->AllowSleep(); + m_submit_worker_idle = true; + m_submit_worker_condvar.notify_all(); ++ m_submit_loop->AllowSleep(); + return; + } + +@@ -239,16 +263,12 @@ bool CommandBufferManager::CreateSubmitT + + SubmitCommandBuffer(submit.command_buffer_index, submit.present_swap_chain, + submit.present_image_index); +- CmdBufferResources& resources = m_command_buffers[submit.command_buffer_index]; +- resources.waiting_for_submit.store(false, std::memory_order_release); + ++ std::lock_guard guard(m_pending_submit_lock); ++ if (m_pending_submits.empty()) + { +- std::lock_guard guard(m_pending_submit_lock); +- if (m_pending_submits.empty()) +- { +- m_submit_worker_idle = true; +- m_submit_worker_condvar.notify_all(); +- } ++ m_submit_worker_idle = true; ++ m_submit_worker_condvar.notify_all(); + } + }); + }); +@@ -256,55 +276,28 @@ bool CommandBufferManager::CreateSubmitT + return true; + } + +-void CommandBufferManager::WaitForWorkerThreadIdle() ++void CommandBufferManager::WaitForSubmitWorkerThreadIdle() + { +- if (!m_use_threaded_submission) +- return; +- + std::unique_lock lock{m_pending_submit_lock}; + m_submit_worker_condvar.wait(lock, [&] { return m_submit_worker_idle; }); + } + + void CommandBufferManager::WaitForFenceCounter(u64 fence_counter) + { +- if (m_completed_fence_counter >= fence_counter) ++ if (m_completed_fence_counter.load(std::memory_order_relaxed) >= fence_counter) [[likely]] + return; + +- // Find the first command buffer which covers this counter value. +- u32 index = (m_current_cmd_buffer + 1) % NUM_COMMAND_BUFFERS; +- while (index != m_current_cmd_buffer) +- { +- if (m_command_buffers[index].fence_counter >= fence_counter) +- break; +- +- index = (index + 1) % NUM_COMMAND_BUFFERS; +- } +- +- ASSERT(index != m_current_cmd_buffer); +- WaitForCommandBufferCompletion(index); ++ std::unique_lock lock{m_pending_fences_lock}; ++ m_fence_condvar.wait(lock, [&] { ++ return m_completed_fence_counter.load(std::memory_order_relaxed) >= fence_counter; ++ }); + } + +-void CommandBufferManager::WaitForCommandBufferCompletion(u32 index) ++void CommandBufferManager::CleanupCompletedCommandBuffers() + { +- CmdBufferResources& resources = m_command_buffers[index]; +- +- // Ensure this command buffer has been submitted. +- if (resources.waiting_for_submit.load(std::memory_order_acquire)) +- { +- WaitForWorkerThreadIdle(); +- ASSERT_MSG(VIDEO, !resources.waiting_for_submit.load(std::memory_order_relaxed), +- "Submit thread is idle but command buffer is still waiting for submission!"); +- } +- +- // Wait for this command buffer to be completed. +- VkResult res = +- vkWaitForFences(g_vulkan_context->GetDevice(), 1, &resources.fence, VK_TRUE, UINT64_MAX); +- if (res != VK_SUCCESS) +- LOG_VULKAN_ERROR(res, "vkWaitForFences failed: "); +- + // Clean up any resources for command buffers between the last known completed buffer and this + // now-completed command buffer. If we use >2 buffers, this may be more than one buffer. +- const u64 now_completed_counter = resources.fence_counter; ++ const u64 now_completed_counter = m_completed_fence_counter.load(std::memory_order_acquire); + u32 cleanup_index = (m_current_cmd_buffer + 1) % NUM_COMMAND_BUFFERS; + while (cleanup_index != m_current_cmd_buffer) + { +@@ -312,26 +305,22 @@ void CommandBufferManager::WaitForComman + if (cleanup_resources.fence_counter > now_completed_counter) + break; + +- if (cleanup_resources.fence_counter > m_completed_fence_counter) +- { +- for (auto& it : cleanup_resources.cleanup_resources) +- it(); +- cleanup_resources.cleanup_resources.clear(); +- } ++ for (auto& it : cleanup_resources.cleanup_resources) ++ it(); ++ cleanup_resources.cleanup_resources.clear(); + + cleanup_index = (cleanup_index + 1) % NUM_COMMAND_BUFFERS; + } +- +- m_completed_fence_counter = now_completed_counter; + } + +-void CommandBufferManager::SubmitCommandBuffer(bool submit_on_worker_thread, ++void CommandBufferManager::SubmitCommandBuffer(u64 fence_counter, bool submit_on_worker_thread, + bool wait_for_completion, + VkSwapchainKHR present_swap_chain, + uint32_t present_image_index) + { + // End the current command buffer. + CmdBufferResources& resources = GetCurrentCmdBufferResources(); ++ resources.fence_counter = fence_counter; + for (VkCommandBuffer command_buffer : resources.command_buffers) + { + VkResult res = vkEndCommandBuffer(command_buffer); +@@ -344,32 +333,37 @@ void CommandBufferManager::SubmitCommand + } + + // Submitting off-thread? +- if (m_use_threaded_submission && submit_on_worker_thread && !wait_for_completion) ++ if (submit_on_worker_thread && !wait_for_completion) + { +- resources.waiting_for_submit.store(true, std::memory_order_relaxed); + // Push to the pending submit queue. + { + std::lock_guard guard(m_pending_submit_lock); + m_submit_worker_idle = false; + m_pending_submits.push_back({present_swap_chain, present_image_index, m_current_cmd_buffer}); +- } + +- // Wake up the worker thread for a single iteration. +- m_submit_loop->Wakeup(); ++ // Wake up the worker thread for a single iteration. ++ m_submit_loop->Wakeup(); ++ } + } + else + { +- WaitForWorkerThreadIdle(); ++ WaitForSubmitWorkerThreadIdle(); + + // Pass through to normal submission path. + SubmitCommandBuffer(m_current_cmd_buffer, present_swap_chain, present_image_index); + if (wait_for_completion) +- WaitForCommandBufferCompletion(m_current_cmd_buffer); ++ { ++ std::unique_lock lock{m_pending_fences_lock}; ++ m_fence_condvar.wait(lock, [&] { ++ return m_completed_fence_counter.load(std::memory_order_relaxed) >= resources.fence_counter; ++ }); ++ } + } + + if (present_swap_chain != VK_NULL_HANDLE) + { + m_current_frame = (m_current_frame + 1) % NUM_FRAMES_IN_FLIGHT; ++ const u64 now_completed_counter = m_completed_fence_counter.load(std::memory_order_acquire); + + // Wait for all command buffers that used the descriptor pool to finish + u32 cmd_buffer_index = (m_current_cmd_buffer + 1) % NUM_COMMAND_BUFFERS; +@@ -377,9 +371,9 @@ void CommandBufferManager::SubmitCommand + { + CmdBufferResources& cmd_buffer = m_command_buffers[cmd_buffer_index]; + if (cmd_buffer.frame_index == m_current_frame && cmd_buffer.fence_counter != 0 && +- cmd_buffer.fence_counter > m_completed_fence_counter) ++ cmd_buffer.fence_counter > now_completed_counter) + { +- WaitForCommandBufferCompletion(cmd_buffer_index); ++ WaitForFenceCounter(cmd_buffer.fence_counter); + } + cmd_buffer_index = (cmd_buffer_index + 1) % NUM_COMMAND_BUFFERS; + } +@@ -411,6 +405,7 @@ void CommandBufferManager::SubmitCommand + + // Switch to next cmdbuffer. + BeginCommandBuffer(); ++ m_state_tracker->InvalidateCachedState(); + } + + void CommandBufferManager::SubmitCommandBuffer(u32 command_buffer_index, +@@ -455,8 +450,15 @@ void CommandBufferManager::SubmitCommand + if (res != VK_SUCCESS) + { + LOG_VULKAN_ERROR(res, "vkQueueSubmit failed: "); +- PanicAlertFmt("Failed to submit command buffer: {} ({})", VkResultToString(res), +- static_cast(res)); ++ PanicAlertFmt("Failed to submit command buffer: {} ({}), semaphore used: {}, has present sc {}", ++ VkResultToString(res), static_cast(res), resources.semaphore_used, ++ present_swap_chain != VK_NULL_HANDLE); ++ } ++ ++ { ++ std::lock_guard guard(m_pending_fences_lock); ++ m_pending_fences.push_back({resources.fence, resources.fence_counter}); ++ m_fence_loop->Wakeup(); + } + + // Do we have a swap chain to present? +@@ -471,28 +473,27 @@ void CommandBufferManager::SubmitCommand + &present_swap_chain, + &present_image_index, + nullptr}; +- +- m_last_present_result = vkQueuePresentKHR(g_vulkan_context->GetPresentQueue(), &present_info); +- m_last_present_done.Set(); +- if (m_last_present_result != VK_SUCCESS) ++ res = vkQueuePresentKHR(g_vulkan_context->GetPresentQueue(), &present_info); ++ if (res != VK_SUCCESS) + { + // VK_ERROR_OUT_OF_DATE_KHR is not fatal, just means we need to recreate our swap chain. +- if (m_last_present_result != VK_ERROR_OUT_OF_DATE_KHR && +- m_last_present_result != VK_SUBOPTIMAL_KHR && +- m_last_present_result != VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT) ++ if (res != VK_ERROR_OUT_OF_DATE_KHR && res != VK_SUBOPTIMAL_KHR && ++ res != VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT) + { +- LOG_VULKAN_ERROR(m_last_present_result, "vkQueuePresentKHR failed: "); ++ LOG_VULKAN_ERROR(res, "vkQueuePresentKHR failed: "); + } + + // Don't treat VK_SUBOPTIMAL_KHR as fatal on Android. Android 10+ requires prerotation. + // See https://twitter.com/Themaister/status/1207062674011574273 + #ifdef VK_USE_PLATFORM_ANDROID_KHR +- if (m_last_present_result != VK_SUBOPTIMAL_KHR) ++ if (res != VK_SUBOPTIMAL_KHR) + m_last_present_failed.Set(); + #else + m_last_present_failed.Set(); + #endif + } ++ m_last_present_result.store(res); ++ m_last_present_done.Set(); + } + } + +@@ -503,8 +504,11 @@ void CommandBufferManager::BeginCommandB + CmdBufferResources& resources = m_command_buffers[next_buffer_index]; + + // Wait for the GPU to finish with all resources for this command buffer. +- if (resources.fence_counter > m_completed_fence_counter) +- WaitForCommandBufferCompletion(next_buffer_index); ++ if (resources.fence_counter > m_completed_fence_counter.load(std::memory_order_acquire) && ++ resources.fence_counter != 0) ++ WaitForFenceCounter(resources.fence_counter); ++ ++ CleanupCompletedCommandBuffers(); + + // Reset fence to unsignaled before starting. + VkResult res = vkResetFences(g_vulkan_context->GetDevice(), 1, &resources.fence); +@@ -526,10 +530,9 @@ void CommandBufferManager::BeginCommandB + LOG_VULKAN_ERROR(res, "vkBeginCommandBuffer failed: "); + } + +- // Reset upload command buffer state ++ // Reset command buffer state + resources.init_command_buffer_used = false; + resources.semaphore_used = false; +- resources.fence_counter = m_next_fence_counter++; + resources.frame_index = m_current_frame; + m_current_cmd_buffer = next_buffer_index; + } +@@ -569,6 +572,4 @@ void CommandBufferManager::DeferImageVie + cmd_buffer_resources.cleanup_resources.push_back( + [object]() { vkDestroyImageView(g_vulkan_context->GetDevice(), object, nullptr); }); + } +- +-std::unique_ptr g_command_buffer_mgr; + } // namespace Vulkan +diff -rupN dolphin.orig/Source/Core/VideoBackends/Vulkan/CommandBufferManager.h dolphin/Source/Core/VideoBackends/Vulkan/CommandBufferManager.h +--- dolphin.orig/Source/Core/VideoBackends/Vulkan/CommandBufferManager.h 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoBackends/Vulkan/CommandBufferManager.h 2024-03-05 04:06:08.240295843 +0000 +@@ -22,10 +22,12 @@ + + namespace Vulkan + { ++class StateTracker; ++ + class CommandBufferManager + { + public: +- explicit CommandBufferManager(bool use_threaded_submission); ++ explicit CommandBufferManager(); + ~CommandBufferManager(); + + bool Initialize(); +@@ -50,39 +52,37 @@ public: + // If the last completed fence counter is greater or equal to N, it means that the work + // associated counter N has been completed by the GPU. The value of N to associate with + // commands can be retreived by calling GetCurrentFenceCounter(). +- u64 GetCompletedFenceCounter() const { return m_completed_fence_counter; } +- +- // Gets the fence that will be signaled when the currently executing command buffer is +- // queued and executed. Do not wait for this fence before the buffer is executed. +- u64 GetCurrentFenceCounter() const ++ // THREAD SAFE ++ u64 GetCompletedFenceCounter() const + { +- auto& resources = m_command_buffers[m_current_cmd_buffer]; +- return resources.fence_counter; ++ return m_completed_fence_counter.load(std::memory_order_acquire); + } + + // Returns the semaphore for the current command buffer, which can be used to ensure the + // swap chain image is ready before the command buffer executes. +- VkSemaphore GetCurrentCommandBufferSemaphore() ++ void SetWaitSemaphoreForCurrentCommandBuffer(VkSemaphore semaphore) + { + auto& resources = m_command_buffers[m_current_cmd_buffer]; + resources.semaphore_used = true; +- return resources.semaphore; ++ resources.semaphore = semaphore; + } + + // Ensure that the worker thread has submitted any previous command buffers and is idle. +- void WaitForWorkerThreadIdle(); ++ void WaitForSubmitWorkerThreadIdle(); + + // Wait for a fence to be completed. + // Also invokes callbacks for completion. ++ // THREAD SAFE + void WaitForFenceCounter(u64 fence_counter); + +- void SubmitCommandBuffer(bool submit_on_worker_thread, bool wait_for_completion, ++ void SubmitCommandBuffer(u64 fence_counter, bool submit_on_worker_thread, ++ bool wait_for_completion, + VkSwapchainKHR present_swap_chain = VK_NULL_HANDLE, + uint32_t present_image_index = 0xFFFFFFFF); + + // Was the last present submitted to the queue a failure? If so, we must recreate our swapchain. + bool CheckLastPresentFail() { return m_last_present_failed.TestAndClear(); } +- VkResult GetLastPresentResult() const { return m_last_present_result; } ++ VkResult GetLastPresentResult() const { return m_last_present_result.load(); } + bool CheckLastPresentDone() { return m_last_present_done.TestAndClear(); } + + // Schedule a vulkan resource for destruction later on. This will occur when the command buffer +@@ -93,17 +93,21 @@ public: + void DeferImageDestruction(VkImage object, VmaAllocation alloc); + void DeferImageViewDestruction(VkImageView object); + ++ StateTracker* GetStateTracker() { return m_state_tracker.get(); } ++ + private: + bool CreateCommandBuffers(); + void DestroyCommandBuffers(); + ++ bool CreateFenceThread(); + bool CreateSubmitThread(); + +- void WaitForCommandBufferCompletion(u32 command_buffer_index); + void SubmitCommandBuffer(u32 command_buffer_index, VkSwapchainKHR present_swap_chain, + u32 present_image_index); + void BeginCommandBuffer(); + ++ void CleanupCompletedCommandBuffers(); ++ + VkDescriptorPool CreateDescriptorPool(u32 descriptor_sizes); + + const u32 DESCRIPTOR_SETS_PER_POOL = 1024; +@@ -118,7 +122,6 @@ private: + u64 fence_counter = 0; + bool init_command_buffer_used = false; + bool semaphore_used = false; +- std::atomic waiting_for_submit{false}; + u32 frame_index = 0; + + std::vector> cleanup_resources; +@@ -137,14 +140,15 @@ private: + return m_command_buffers[m_current_cmd_buffer]; + } + +- u64 m_next_fence_counter = 1; +- u64 m_completed_fence_counter = 0; ++ std::atomic m_completed_fence_counter = 0; + + std::array m_frame_resources; + std::array m_command_buffers; + u32 m_current_frame = 0; + u32 m_current_cmd_buffer = 0; + ++ std::unique_ptr m_state_tracker; ++ + // Threaded command buffer execution + std::thread m_submit_thread; + std::unique_ptr m_submit_loop; +@@ -161,11 +165,20 @@ private: + bool m_submit_worker_idle = true; + Common::Flag m_last_present_failed; + Common::Flag m_last_present_done; +- VkResult m_last_present_result = VK_SUCCESS; +- bool m_use_threaded_submission = false; ++ std::atomic m_last_present_result = VK_SUCCESS; + u32 m_descriptor_set_count = DESCRIPTOR_SETS_PER_POOL; +-}; + +-extern std::unique_ptr g_command_buffer_mgr; ++ // Fence thread ++ std::thread m_fence_thread; ++ std::unique_ptr m_fence_loop; ++ struct PendingFenceCounter ++ { ++ VkFence fence; ++ u64 counter; ++ }; ++ std::deque m_pending_fences; ++ std::mutex m_pending_fences_lock; ++ std::condition_variable m_fence_condvar; ++}; + + } // namespace Vulkan +diff -rupN dolphin.orig/Source/Core/VideoBackends/Vulkan/Constants.h dolphin/Source/Core/VideoBackends/Vulkan/Constants.h +--- dolphin.orig/Source/Core/VideoBackends/Vulkan/Constants.h 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoBackends/Vulkan/Constants.h 2024-03-05 04:06:08.240295843 +0000 +@@ -12,7 +12,7 @@ + namespace Vulkan + { + // Number of command buffers. +-constexpr size_t NUM_COMMAND_BUFFERS = 8; ++constexpr size_t NUM_COMMAND_BUFFERS = 16; + + // Number of frames in flight, will be used to decide how many descriptor pools are used + constexpr size_t NUM_FRAMES_IN_FLIGHT = 2; +diff -rupN dolphin.orig/Source/Core/VideoBackends/Vulkan/ObjectCache.cpp dolphin/Source/Core/VideoBackends/Vulkan/ObjectCache.cpp +--- dolphin.orig/Source/Core/VideoBackends/Vulkan/ObjectCache.cpp 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoBackends/Vulkan/ObjectCache.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -389,6 +389,8 @@ VkSampler ObjectCache::GetSampler(const + VkRenderPass ObjectCache::GetRenderPass(VkFormat color_format, VkFormat depth_format, + u32 multisamples, VkAttachmentLoadOp load_op) + { ++ std::scoped_lock lock(m_render_pass_mutex); ++ + auto key = std::tie(color_format, depth_format, multisamples, load_op); + auto it = m_render_pass_cache.find(key); + if (it != m_render_pass_cache.end()) +@@ -467,6 +469,8 @@ VkRenderPass ObjectCache::GetRenderPass( + + void ObjectCache::DestroyRenderPassCache() + { ++ std::scoped_lock lock(m_render_pass_mutex); ++ + for (auto& it : m_render_pass_cache) + vkDestroyRenderPass(g_vulkan_context->GetDevice(), it.second, nullptr); + m_render_pass_cache.clear(); +diff -rupN dolphin.orig/Source/Core/VideoBackends/Vulkan/ObjectCache.h dolphin/Source/Core/VideoBackends/Vulkan/ObjectCache.h +--- dolphin.orig/Source/Core/VideoBackends/Vulkan/ObjectCache.h 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoBackends/Vulkan/ObjectCache.h 2024-03-05 04:06:08.240295843 +0000 +@@ -7,6 +7,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -102,6 +103,7 @@ private: + std::unique_ptr m_dummy_texture; + + // Render pass cache ++ std::mutex m_render_pass_mutex; + using RenderPassCacheKey = std::tuple; + std::map m_render_pass_cache; + +diff -rupN dolphin.orig/Source/Core/VideoBackends/Vulkan/StagingBuffer.cpp dolphin/Source/Core/VideoBackends/Vulkan/StagingBuffer.cpp +--- dolphin.orig/Source/Core/VideoBackends/Vulkan/StagingBuffer.cpp 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoBackends/Vulkan/StagingBuffer.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -8,6 +8,7 @@ + + #include "Common/Assert.h" + ++#include "VKScheduler.h" + #include "VideoBackends/Vulkan/CommandBufferManager.h" + #include "VideoBackends/Vulkan/VulkanContext.h" + #include "VideoCommon/DriverDetails.h" +@@ -26,7 +27,10 @@ StagingBuffer::~StagingBuffer() + if (m_map_pointer) + Unmap(); + +- g_command_buffer_mgr->DeferBufferDestruction(m_buffer, m_alloc); ++ g_scheduler->Record( ++ [c_alloc = m_alloc, c_buffer = m_buffer](CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->DeferBufferDestruction(c_buffer, c_alloc); ++ }); + } + + void StagingBuffer::BufferMemoryBarrier(VkCommandBuffer command_buffer, VkBuffer buffer, +diff -rupN dolphin.orig/Source/Core/VideoBackends/Vulkan/StateTracker.cpp dolphin/Source/Core/VideoBackends/Vulkan/StateTracker.cpp +--- dolphin.orig/Source/Core/VideoBackends/Vulkan/StateTracker.cpp 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoBackends/Vulkan/StateTracker.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -16,59 +16,93 @@ + + namespace Vulkan + { +-static std::unique_ptr s_state_tracker; +- +-StateTracker::StateTracker() = default; +- +-StateTracker::~StateTracker() = default; ++StateTracker::StateTracker(CommandBufferManager* command_buffer_mgr) ++ : m_command_buffer_mgr(command_buffer_mgr) ++{ ++} + +-StateTracker* StateTracker::GetInstance() ++StateTracker::~StateTracker() + { +- return s_state_tracker.get(); ++ vkDestroyImageView(g_vulkan_context->GetDevice(), m_dummy_view, nullptr); ++ vmaDestroyImage(g_vulkan_context->GetMemoryAllocator(), m_dummy_image, m_dummy_alloc); + } + +-bool StateTracker::CreateInstance() ++bool StateTracker::Initialize() + { +- ASSERT(!s_state_tracker); +- s_state_tracker = std::make_unique(); +- if (!s_state_tracker->Initialize()) ++ // Create a dummy texture which can be used in place of a real binding. ++ VkImageCreateInfo dummy_info; ++ dummy_info.pNext = nullptr; ++ dummy_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; ++ dummy_info.extent = {1, 1, 1}; ++ dummy_info.arrayLayers = 1; ++ dummy_info.mipLevels = 1; ++ dummy_info.flags = 0; ++ dummy_info.imageType = VK_IMAGE_TYPE_2D; ++ dummy_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; ++ dummy_info.samples = VK_SAMPLE_COUNT_1_BIT; ++ dummy_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; ++ dummy_info.format = VK_FORMAT_R8G8B8A8_UNORM; ++ dummy_info.tiling = VK_IMAGE_TILING_OPTIMAL; ++ dummy_info.queueFamilyIndexCount = 0; ++ dummy_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT; ++ dummy_info.pQueueFamilyIndices = nullptr; ++ ++ VmaAllocationCreateInfo alloc_create_info = {}; ++ alloc_create_info.flags = VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT; ++ alloc_create_info.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; ++ alloc_create_info.pool = VK_NULL_HANDLE; ++ alloc_create_info.pUserData = nullptr; ++ alloc_create_info.priority = 0.0; ++ alloc_create_info.requiredFlags = 0; ++ alloc_create_info.preferredFlags = 0; ++ ++ VkResult res = vmaCreateImage(g_vulkan_context->GetMemoryAllocator(), &dummy_info, ++ &alloc_create_info, &m_dummy_image, &m_dummy_alloc, nullptr); ++ if (res != VK_SUCCESS) + { +- s_state_tracker.reset(); ++ LOG_VULKAN_ERROR(res, "vmaCreateImage failed: "); + return false; + } +- return true; +-} + +-void StateTracker::DestroyInstance() +-{ +- if (!s_state_tracker) +- return; ++ VkImageViewCreateInfo dummy_view_info; ++ dummy_view_info.pNext = nullptr; ++ dummy_view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; ++ dummy_view_info.flags = 0; ++ dummy_view_info.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; ++ dummy_view_info.format = VK_FORMAT_R8G8B8A8_UNORM; ++ dummy_view_info.components = {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, ++ VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY}; ++ dummy_view_info.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; ++ dummy_view_info.image = m_dummy_image; + +- // When the dummy texture is destroyed, it unbinds itself, then references itself. +- // Clear everything out so this doesn't happen. +- for (auto& it : s_state_tracker->m_bindings.samplers) +- it.imageView = VK_NULL_HANDLE; +- s_state_tracker->m_bindings.image_texture.imageView = VK_NULL_HANDLE; +- s_state_tracker->m_dummy_texture.reset(); +- +- s_state_tracker.reset(); +-} +- +-bool StateTracker::Initialize() +-{ +- // Create a dummy texture which can be used in place of a real binding. +- m_dummy_texture = +- VKTexture::Create(TextureConfig(1, 1, 1, 1, 1, AbstractTextureFormat::RGBA8, 0), ""); +- if (!m_dummy_texture) ++ res = vkCreateImageView(g_vulkan_context->GetDevice(), &dummy_view_info, nullptr, &m_dummy_view); ++ if (res != VK_SUCCESS) ++ { ++ LOG_VULKAN_ERROR(res, "vkCreateImageView failed: "); + return false; +- m_dummy_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentInitCommandBuffer(), +- VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); ++ } ++ ++ VkImageMemoryBarrier img_barrier; ++ img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; ++ img_barrier.pNext = nullptr; ++ img_barrier.srcAccessMask = 0; ++ img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; ++ img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; ++ img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; ++ img_barrier.image = m_dummy_image; ++ img_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; ++ img_barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; ++ img_barrier.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; ++ ++ vkCmdPipelineBarrier(m_command_buffer_mgr->GetCurrentInitCommandBuffer(), ++ VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, ++ nullptr, 0, nullptr, 1, &img_barrier); + + // Initialize all samplers to point by default + for (size_t i = 0; i < NUM_PIXEL_SHADER_SAMPLERS; i++) + { + m_bindings.samplers[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; +- m_bindings.samplers[i].imageView = m_dummy_texture->GetView(); ++ m_bindings.samplers[i].imageView = m_dummy_view; + m_bindings.samplers[i].sampler = g_object_cache->GetPointSampler(); + } + +@@ -107,11 +141,17 @@ void StateTracker::SetIndexBuffer(VkBuff + m_dirty_flags |= DIRTY_FLAG_INDEX_BUFFER; + } + +-void StateTracker::SetFramebuffer(VKFramebuffer* framebuffer) ++void StateTracker::SetFramebuffer(VkFramebuffer framebuffer, VkRect2D render_area, ++ VkRenderPass load_render_pass, VkRenderPass clear_render_pass, ++ VkRenderPass discard_render_pass) + { + // Should not be changed within a render pass. + ASSERT(!InRenderPass()); + m_framebuffer = framebuffer; ++ m_framebuffer_render_area = render_area; ++ m_framebuffer_load_render_pass = load_render_pass; ++ m_framebuffer_clear_render_pass = clear_render_pass; ++ m_framebuffer_discard_render_pass = discard_render_pass; + } + + void StateTracker::SetPipeline(const VKPipeline* pipeline) +@@ -232,14 +272,14 @@ void StateTracker::UnbindTexture(VkImage + { + if (it.imageView == view) + { +- it.imageView = m_dummy_texture->GetView(); ++ it.imageView = m_dummy_view; + it.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + } + } + + if (m_bindings.image_texture.imageView == view) + { +- m_bindings.image_texture.imageView = m_dummy_texture->GetView(); ++ m_bindings.image_texture.imageView = m_dummy_view; + m_bindings.image_texture.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + } + } +@@ -263,18 +303,18 @@ void StateTracker::BeginRenderPass() + if (InRenderPass()) + return; + +- m_current_render_pass = m_framebuffer->GetLoadRenderPass(); +- m_framebuffer_render_area = m_framebuffer->GetRect(); ++ m_current_render_pass = m_framebuffer_load_render_pass; ++ m_render_area = m_framebuffer_render_area; + + VkRenderPassBeginInfo begin_info = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + nullptr, + m_current_render_pass, +- m_framebuffer->GetFB(), +- m_framebuffer_render_area, ++ m_framebuffer, ++ m_render_area, + 0, + nullptr}; + +- vkCmdBeginRenderPass(g_command_buffer_mgr->GetCurrentCommandBuffer(), &begin_info, ++ vkCmdBeginRenderPass(m_command_buffer_mgr->GetCurrentCommandBuffer(), &begin_info, + VK_SUBPASS_CONTENTS_INLINE); + } + +@@ -283,18 +323,18 @@ void StateTracker::BeginDiscardRenderPas + if (InRenderPass()) + return; + +- m_current_render_pass = m_framebuffer->GetDiscardRenderPass(); +- m_framebuffer_render_area = m_framebuffer->GetRect(); ++ m_current_render_pass = m_framebuffer_discard_render_pass; ++ m_render_area = m_framebuffer_render_area; + + VkRenderPassBeginInfo begin_info = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + nullptr, + m_current_render_pass, +- m_framebuffer->GetFB(), +- m_framebuffer_render_area, ++ m_framebuffer, ++ m_render_area, + 0, + nullptr}; + +- vkCmdBeginRenderPass(g_command_buffer_mgr->GetCurrentCommandBuffer(), &begin_info, ++ vkCmdBeginRenderPass(m_command_buffer_mgr->GetCurrentCommandBuffer(), &begin_info, + VK_SUBPASS_CONTENTS_INLINE); + } + +@@ -303,7 +343,7 @@ void StateTracker::EndRenderPass() + if (!InRenderPass()) + return; + +- vkCmdEndRenderPass(g_command_buffer_mgr->GetCurrentCommandBuffer()); ++ vkCmdEndRenderPass(m_command_buffer_mgr->GetCurrentCommandBuffer()); + m_current_render_pass = VK_NULL_HANDLE; + } + +@@ -312,18 +352,18 @@ void StateTracker::BeginClearRenderPass( + { + ASSERT(!InRenderPass()); + +- m_current_render_pass = m_framebuffer->GetClearRenderPass(); +- m_framebuffer_render_area = area; ++ m_current_render_pass = m_framebuffer_clear_render_pass; ++ m_render_area = area; + + VkRenderPassBeginInfo begin_info = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + nullptr, + m_current_render_pass, +- m_framebuffer->GetFB(), +- m_framebuffer_render_area, ++ m_framebuffer, ++ m_render_area, + num_clear_values, + clear_values}; + +- vkCmdBeginRenderPass(g_command_buffer_mgr->GetCurrentCommandBuffer(), &begin_info, ++ vkCmdBeginRenderPass(m_command_buffer_mgr->GetCurrentCommandBuffer(), &begin_info, + VK_SUBPASS_CONTENTS_INLINE); + } + +@@ -352,7 +392,7 @@ bool StateTracker::Bind() + return false; + + // Check the render area if we were in a clear pass. +- if (m_current_render_pass == m_framebuffer->GetClearRenderPass() && !IsViewportWithinRenderArea()) ++ if (m_current_render_pass == m_framebuffer_clear_render_pass && !IsViewportWithinRenderArea()) + EndRenderPass(); + + // Get a new descriptor set if any parts have changed +@@ -363,7 +403,7 @@ bool StateTracker::Bind() + BeginRenderPass(); + + // Re-bind parts of the pipeline +- const VkCommandBuffer command_buffer = g_command_buffer_mgr->GetCurrentCommandBuffer(); ++ const VkCommandBuffer command_buffer = m_command_buffer_mgr->GetCurrentCommandBuffer(); + const bool needs_vertex_buffer = !g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader || + m_pipeline->GetUsage() != AbstractPipelineUsage::GXUber; + if (needs_vertex_buffer && (m_dirty_flags & DIRTY_FLAG_VERTEX_BUFFER)) +@@ -398,7 +438,7 @@ bool StateTracker::BindCompute() + if (InRenderPass()) + EndRenderPass(); + +- const VkCommandBuffer command_buffer = g_command_buffer_mgr->GetCurrentCommandBuffer(); ++ const VkCommandBuffer command_buffer = m_command_buffer_mgr->GetCurrentCommandBuffer(); + if (m_dirty_flags & DIRTY_FLAG_COMPUTE_SHADER) + { + vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, +@@ -414,10 +454,10 @@ bool StateTracker::IsWithinRenderArea(s3 + { + // Check that the viewport does not lie outside the render area. + // If it does, we need to switch to a normal load/store render pass. +- s32 left = m_framebuffer_render_area.offset.x; +- s32 top = m_framebuffer_render_area.offset.y; +- s32 right = left + static_cast(m_framebuffer_render_area.extent.width); +- s32 bottom = top + static_cast(m_framebuffer_render_area.extent.height); ++ s32 left = m_render_area.offset.x; ++ s32 top = m_render_area.offset.y; ++ s32 right = left + static_cast(m_render_area.extent.width); ++ s32 bottom = top + static_cast(m_render_area.extent.height); + s32 test_left = x; + s32 test_top = y; + s32 test_right = test_left + static_cast(width); +@@ -434,7 +474,7 @@ bool StateTracker::IsViewportWithinRende + + void StateTracker::EndClearRenderPass() + { +- if (m_current_render_pass != m_framebuffer->GetClearRenderPass()) ++ if (m_current_render_pass != m_framebuffer_clear_render_pass) + return; + + // End clear render pass. Bind() will call BeginRenderPass() which +@@ -463,7 +503,7 @@ void StateTracker::UpdateGXDescriptorSet + + if (m_dirty_flags & DIRTY_FLAG_GX_UBOS || m_gx_descriptor_sets[0] == VK_NULL_HANDLE) + { +- m_gx_descriptor_sets[0] = g_command_buffer_mgr->AllocateDescriptorSet( ++ m_gx_descriptor_sets[0] = m_command_buffer_mgr->AllocateDescriptorSet( + g_object_cache->GetDescriptorSetLayout(DESCRIPTOR_SET_LAYOUT_STANDARD_UNIFORM_BUFFERS)); + + for (size_t i = 0; i < NUM_UBO_DESCRIPTOR_SET_BINDINGS; i++) +@@ -490,7 +530,7 @@ void StateTracker::UpdateGXDescriptorSet + + if (m_dirty_flags & DIRTY_FLAG_GX_SAMPLERS || m_gx_descriptor_sets[1] == VK_NULL_HANDLE) + { +- m_gx_descriptor_sets[1] = g_command_buffer_mgr->AllocateDescriptorSet( ++ m_gx_descriptor_sets[1] = m_command_buffer_mgr->AllocateDescriptorSet( + g_object_cache->GetDescriptorSetLayout(DESCRIPTOR_SET_LAYOUT_STANDARD_SAMPLERS)); + + writes[num_writes++] = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, +@@ -516,7 +556,7 @@ void StateTracker::UpdateGXDescriptorSet + (m_dirty_flags & DIRTY_FLAG_GX_SSBO || m_gx_descriptor_sets[2] == VK_NULL_HANDLE)) + { + m_gx_descriptor_sets[2] = +- g_command_buffer_mgr->AllocateDescriptorSet(g_object_cache->GetDescriptorSetLayout( ++ m_command_buffer_mgr->AllocateDescriptorSet(g_object_cache->GetDescriptorSetLayout( + DESCRIPTOR_SET_LAYOUT_STANDARD_SHADER_STORAGE_BUFFERS)); + + writes[num_writes++] = { +@@ -546,7 +586,7 @@ void StateTracker::UpdateGXDescriptorSet + + if (m_dirty_flags & DIRTY_FLAG_DESCRIPTOR_SETS) + { +- vkCmdBindDescriptorSets(g_command_buffer_mgr->GetCurrentCommandBuffer(), ++ vkCmdBindDescriptorSets(m_command_buffer_mgr->GetCurrentCommandBuffer(), + VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline->GetVkPipelineLayout(), 0, + needs_ssbo ? NUM_GX_DESCRIPTOR_SETS : (NUM_GX_DESCRIPTOR_SETS - 1), + m_gx_descriptor_sets.data(), +@@ -558,7 +598,7 @@ void StateTracker::UpdateGXDescriptorSet + else if (m_dirty_flags & DIRTY_FLAG_GX_UBO_OFFSETS) + { + vkCmdBindDescriptorSets( +- g_command_buffer_mgr->GetCurrentCommandBuffer(), VK_PIPELINE_BIND_POINT_GRAPHICS, ++ m_command_buffer_mgr->GetCurrentCommandBuffer(), VK_PIPELINE_BIND_POINT_GRAPHICS, + m_pipeline->GetVkPipelineLayout(), 0, 1, m_gx_descriptor_sets.data(), + needs_gs_ubo ? NUM_UBO_DESCRIPTOR_SET_BINDINGS : (NUM_UBO_DESCRIPTOR_SET_BINDINGS - 1), + m_bindings.gx_ubo_offsets.data()); +@@ -575,7 +615,7 @@ void StateTracker::UpdateUtilityDescript + // Allocate descriptor sets. + if (m_dirty_flags & DIRTY_FLAG_UTILITY_UBO || m_utility_descriptor_sets[0] == VK_NULL_HANDLE) + { +- m_utility_descriptor_sets[0] = g_command_buffer_mgr->AllocateDescriptorSet( ++ m_utility_descriptor_sets[0] = m_command_buffer_mgr->AllocateDescriptorSet( + g_object_cache->GetDescriptorSetLayout(DESCRIPTOR_SET_LAYOUT_UTILITY_UNIFORM_BUFFER)); + + dswrites[writes++] = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, +@@ -594,7 +634,7 @@ void StateTracker::UpdateUtilityDescript + + if (m_dirty_flags & DIRTY_FLAG_UTILITY_BINDINGS || m_utility_descriptor_sets[1] == VK_NULL_HANDLE) + { +- m_utility_descriptor_sets[1] = g_command_buffer_mgr->AllocateDescriptorSet( ++ m_utility_descriptor_sets[1] = m_command_buffer_mgr->AllocateDescriptorSet( + g_object_cache->GetDescriptorSetLayout(DESCRIPTOR_SET_LAYOUT_UTILITY_SAMPLERS)); + + dswrites[writes++] = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, +@@ -626,7 +666,7 @@ void StateTracker::UpdateUtilityDescript + + if (m_dirty_flags & DIRTY_FLAG_DESCRIPTOR_SETS) + { +- vkCmdBindDescriptorSets(g_command_buffer_mgr->GetCurrentCommandBuffer(), ++ vkCmdBindDescriptorSets(m_command_buffer_mgr->GetCurrentCommandBuffer(), + VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline->GetVkPipelineLayout(), 0, + NUM_UTILITY_DESCRIPTOR_SETS, m_utility_descriptor_sets.data(), 1, + &m_bindings.utility_ubo_offset); +@@ -634,7 +674,7 @@ void StateTracker::UpdateUtilityDescript + } + else if (m_dirty_flags & DIRTY_FLAG_UTILITY_UBO_OFFSET) + { +- vkCmdBindDescriptorSets(g_command_buffer_mgr->GetCurrentCommandBuffer(), ++ vkCmdBindDescriptorSets(m_command_buffer_mgr->GetCurrentCommandBuffer(), + VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline->GetVkPipelineLayout(), 0, + 1, m_utility_descriptor_sets.data(), 1, &m_bindings.utility_ubo_offset); + m_dirty_flags &= ~(DIRTY_FLAG_DESCRIPTOR_SETS | DIRTY_FLAG_UTILITY_UBO_OFFSET); +@@ -649,7 +689,7 @@ void StateTracker::UpdateComputeDescript + // Allocate descriptor sets. + if (m_dirty_flags & DIRTY_FLAG_COMPUTE_BINDINGS) + { +- m_compute_descriptor_set = g_command_buffer_mgr->AllocateDescriptorSet( ++ m_compute_descriptor_set = m_command_buffer_mgr->AllocateDescriptorSet( + g_object_cache->GetDescriptorSetLayout(DESCRIPTOR_SET_LAYOUT_COMPUTE)); + dswrites[0] = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + nullptr, +@@ -700,7 +740,7 @@ void StateTracker::UpdateComputeDescript + + if (m_dirty_flags & DIRTY_FLAG_COMPUTE_DESCRIPTOR_SET) + { +- vkCmdBindDescriptorSets(g_command_buffer_mgr->GetCurrentCommandBuffer(), ++ vkCmdBindDescriptorSets(m_command_buffer_mgr->GetCurrentCommandBuffer(), + VK_PIPELINE_BIND_POINT_COMPUTE, + g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_COMPUTE), 0, 1, + &m_compute_descriptor_set, 1, &m_bindings.utility_ubo_offset); +diff -rupN dolphin.orig/Source/Core/VideoBackends/Vulkan/StateTracker.h dolphin/Source/Core/VideoBackends/Vulkan/StateTracker.h +--- dolphin.orig/Source/Core/VideoBackends/Vulkan/StateTracker.h 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoBackends/Vulkan/StateTracker.h 2024-03-05 04:06:08.240295843 +0000 +@@ -13,28 +13,24 @@ + + namespace Vulkan + { +-class VKFramebuffer; + class VKShader; + class VKPipeline; +-class VKTexture; +-class StreamBuffer; +-class VertexFormat; ++class CommandBufferManager; + + class StateTracker + { + public: +- StateTracker(); ++ StateTracker(CommandBufferManager* command_buffer_mgr); + ~StateTracker(); + +- static StateTracker* GetInstance(); +- static bool CreateInstance(); +- static void DestroyInstance(); ++ bool Initialize(); + +- VKFramebuffer* GetFramebuffer() const { return m_framebuffer; } + const VKPipeline* GetPipeline() const { return m_pipeline; } + void SetVertexBuffer(VkBuffer buffer, VkDeviceSize offset, u32 size); + void SetIndexBuffer(VkBuffer buffer, VkDeviceSize offset, VkIndexType type); +- void SetFramebuffer(VKFramebuffer* framebuffer); ++ void SetFramebuffer(VkFramebuffer framebuffer, VkRect2D render_area, ++ VkRenderPass load_render_pass, VkRenderPass clear_render_pass, ++ VkRenderPass discard_render_pass); + void SetPipeline(const VKPipeline* pipeline); + void SetComputeShader(const VKShader* shader); + void SetGXUniformBuffer(u32 index, VkBuffer buffer, u32 offset, u32 size); +@@ -110,8 +106,6 @@ private: + DIRTY_FLAG_UTILITY_BINDINGS | DIRTY_FLAG_COMPUTE_BINDINGS + }; + +- bool Initialize(); +- + // Check that the specified viewport is within the render area. + // If not, ends the render pass if it is a clear render pass. + bool IsViewportWithinRenderArea() const; +@@ -121,6 +115,8 @@ private: + void UpdateUtilityDescriptorSet(); + void UpdateComputeDescriptorSet(); + ++ CommandBufferManager* m_command_buffer_mgr; ++ + // Which bindings/state has to be updated before the next draw. + u32 m_dirty_flags = 0; + +@@ -157,10 +153,17 @@ private: + VkRect2D m_scissor = {{0, 0}, {1, 1}}; + + // uniform buffers +- std::unique_ptr m_dummy_texture; ++ VkImage m_dummy_image; ++ VkImageView m_dummy_view; ++ VmaAllocation m_dummy_alloc; + +- VKFramebuffer* m_framebuffer = nullptr; +- VkRenderPass m_current_render_pass = VK_NULL_HANDLE; ++ VkFramebuffer m_framebuffer = VK_NULL_HANDLE; + VkRect2D m_framebuffer_render_area = {}; ++ VkRenderPass m_framebuffer_load_render_pass = VK_NULL_HANDLE; ++ VkRenderPass m_framebuffer_discard_render_pass = VK_NULL_HANDLE; ++ VkRenderPass m_framebuffer_clear_render_pass = VK_NULL_HANDLE; ++ ++ VkRenderPass m_current_render_pass = VK_NULL_HANDLE; ++ VkRect2D m_render_area = {}; + }; + } // namespace Vulkan +diff -rupN dolphin.orig/Source/Core/VideoBackends/Vulkan/VKBoundingBox.cpp dolphin/Source/Core/VideoBackends/Vulkan/VKBoundingBox.cpp +--- dolphin.orig/Source/Core/VideoBackends/Vulkan/VKBoundingBox.cpp 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoBackends/Vulkan/VKBoundingBox.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -12,6 +12,7 @@ + #include "VideoBackends/Vulkan/StagingBuffer.h" + #include "VideoBackends/Vulkan/StateTracker.h" + #include "VideoBackends/Vulkan/VKRenderer.h" ++#include "VideoBackends/Vulkan/VKScheduler.h" + #include "VideoBackends/Vulkan/VulkanContext.h" + + namespace Vulkan +@@ -33,36 +34,43 @@ bool VKBoundingBox::Initialize() + return false; + + // Bind bounding box to state tracker +- StateTracker::GetInstance()->SetSSBO(m_gpu_buffer, 0, BUFFER_SIZE); ++ g_scheduler->Record([c_gpu_buffer = m_gpu_buffer](CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->GetStateTracker()->SetSSBO(c_gpu_buffer, 0, BUFFER_SIZE); ++ }); + return true; + } + + std::vector VKBoundingBox::Read(u32 index, u32 length) + { +- // Can't be done within a render pass. +- StateTracker::GetInstance()->EndRenderPass(); +- +- // Ensure all writes are completed to the GPU buffer prior to the transfer. +- StagingBuffer::BufferMemoryBarrier( +- g_command_buffer_mgr->GetCurrentCommandBuffer(), m_gpu_buffer, +- VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, 0, +- BUFFER_SIZE, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); +- m_readback_buffer->PrepareForGPUWrite(g_command_buffer_mgr->GetCurrentCommandBuffer(), +- VK_ACCESS_TRANSFER_WRITE_BIT, +- VK_PIPELINE_STAGE_TRANSFER_BIT); +- +- // Copy from GPU -> readback buffer. +- VkBufferCopy region = {0, 0, BUFFER_SIZE}; +- vkCmdCopyBuffer(g_command_buffer_mgr->GetCurrentCommandBuffer(), m_gpu_buffer, +- m_readback_buffer->GetBuffer(), 1, ®ion); +- +- // Restore GPU buffer access. +- StagingBuffer::BufferMemoryBarrier( +- g_command_buffer_mgr->GetCurrentCommandBuffer(), m_gpu_buffer, VK_ACCESS_TRANSFER_READ_BIT, +- VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, 0, BUFFER_SIZE, +- VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); +- m_readback_buffer->FlushGPUCache(g_command_buffer_mgr->GetCurrentCommandBuffer(), +- VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); ++ std::vector values(length); ++ // We can just take a reference here, we'll sync immediately afterwards ++ g_scheduler->Record([&](CommandBufferManager* command_buffer_mgr) { ++ // Can't be done within a render pass. ++ command_buffer_mgr->GetStateTracker()->EndRenderPass(); ++ ++ // Ensure all writes are completed to the GPU buffer prior to the transfer. ++ StagingBuffer::BufferMemoryBarrier( ++ command_buffer_mgr->GetCurrentCommandBuffer(), m_gpu_buffer, ++ VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, 0, ++ BUFFER_SIZE, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); ++ ++ m_readback_buffer->PrepareForGPUWrite(command_buffer_mgr->GetCurrentCommandBuffer(), ++ VK_ACCESS_TRANSFER_WRITE_BIT, ++ VK_PIPELINE_STAGE_TRANSFER_BIT); ++ ++ // Copy from GPU -> readback buffer. ++ VkBufferCopy region = {0, 0, BUFFER_SIZE}; ++ vkCmdCopyBuffer(command_buffer_mgr->GetCurrentCommandBuffer(), m_gpu_buffer, ++ m_readback_buffer->GetBuffer(), 1, ®ion); ++ ++ // Restore GPU buffer access. ++ StagingBuffer::BufferMemoryBarrier( ++ command_buffer_mgr->GetCurrentCommandBuffer(), m_gpu_buffer, VK_ACCESS_TRANSFER_READ_BIT, ++ VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, 0, BUFFER_SIZE, ++ VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); ++ m_readback_buffer->FlushGPUCache(command_buffer_mgr->GetCurrentCommandBuffer(), ++ VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); ++ }); + + // Wait until these commands complete. + Renderer::GetInstance()->ExecuteCommandBuffer(false, true); +@@ -71,34 +79,37 @@ std::vector VKBoundingBox::Rea + m_readback_buffer->InvalidateCPUCache(); + + // Read out the values and return +- std::vector values(length); + m_readback_buffer->Read(index * sizeof(BBoxType), values.data(), length * sizeof(BBoxType), + false); ++ + return values; + } + + void VKBoundingBox::Write(u32 index, const std::vector& values) + { +- // We can't issue vkCmdUpdateBuffer within a render pass. +- // However, the writes must be serialized, so we can't put it in the init buffer. +- StateTracker::GetInstance()->EndRenderPass(); +- +- // Ensure GPU buffer is in a state where it can be transferred to. +- StagingBuffer::BufferMemoryBarrier( +- g_command_buffer_mgr->GetCurrentCommandBuffer(), m_gpu_buffer, +- VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, 0, +- BUFFER_SIZE, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); +- +- // Write the values to the GPU buffer +- vkCmdUpdateBuffer(g_command_buffer_mgr->GetCurrentCommandBuffer(), m_gpu_buffer, +- index * sizeof(BBoxType), values.size() * sizeof(BBoxType), +- reinterpret_cast(values.data())); +- +- // Restore fragment shader access to the buffer. +- StagingBuffer::BufferMemoryBarrier( +- g_command_buffer_mgr->GetCurrentCommandBuffer(), m_gpu_buffer, VK_ACCESS_TRANSFER_WRITE_BIT, +- VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, 0, BUFFER_SIZE, +- VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); ++ g_scheduler->Record([c_gpu_buffer = m_gpu_buffer, c_values = values, ++ c_index = index](CommandBufferManager* command_buffer_mgr) { ++ // We can't issue vkCmdUpdateBuffer within a render pass. ++ // However, the writes must be serialized, so we can't put it in the init buffer. ++ command_buffer_mgr->GetStateTracker()->EndRenderPass(); ++ ++ // Ensure GPU buffer is in a state where it can be transferred to. ++ StagingBuffer::BufferMemoryBarrier( ++ command_buffer_mgr->GetCurrentCommandBuffer(), c_gpu_buffer, ++ VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, 0, ++ BUFFER_SIZE, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); ++ ++ // Write the values to the GPU buffer ++ vkCmdUpdateBuffer(command_buffer_mgr->GetCurrentCommandBuffer(), c_gpu_buffer, ++ c_index * sizeof(BBoxType), c_values.size() * sizeof(BBoxType), ++ reinterpret_cast(c_values.data())); ++ ++ // Restore fragment shader access to the buffer. ++ StagingBuffer::BufferMemoryBarrier( ++ command_buffer_mgr->GetCurrentCommandBuffer(), c_gpu_buffer, VK_ACCESS_TRANSFER_WRITE_BIT, ++ VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, 0, BUFFER_SIZE, ++ VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); ++ }); + } + + bool VKBoundingBox::CreateGPUBuffer() +diff -rupN dolphin.orig/Source/Core/VideoBackends/Vulkan/VKMain.cpp dolphin/Source/Core/VideoBackends/Vulkan/VKMain.cpp +--- dolphin.orig/Source/Core/VideoBackends/Vulkan/VKMain.cpp 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoBackends/Vulkan/VKMain.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -18,6 +18,7 @@ + #include "VideoBackends/Vulkan/VKVertexManager.h" + #include "VideoBackends/Vulkan/VulkanContext.h" + ++#include "VKScheduler.h" + #include "VideoCommon/FramebufferManager.h" + #include "VideoCommon/TextureCacheBase.h" + #include "VideoCommon/VideoBackendBase.h" +@@ -196,14 +197,7 @@ bool VideoBackend::Initialize(const Wind + // With the backend information populated, we can now initialize videocommon. + InitializeShared(); + +- // Create command buffers. We do this separately because the other classes depend on it. +- g_command_buffer_mgr = std::make_unique(g_Config.bBackendMultithreading); +- if (!g_command_buffer_mgr->Initialize()) +- { +- PanicAlertFmt("Failed to create Vulkan command buffers"); +- Shutdown(); +- return false; +- } ++ g_scheduler = std::make_unique(); + + // Remaining classes are also dependent on object cache. + g_object_cache = std::make_unique(); +@@ -214,6 +208,14 @@ bool VideoBackend::Initialize(const Wind + return false; + } + ++ // Has to be initialized after the object cache ++ if (!g_scheduler->Initialize()) ++ { ++ PanicAlertFmt("Failed to initialize Vulkan scheduler."); ++ Shutdown(); ++ return false; ++ } ++ + // Create swap chain. This has to be done early so that the target size is correct for auto-scale. + std::unique_ptr swap_chain; + if (surface != VK_NULL_HANDLE) +@@ -227,13 +229,6 @@ bool VideoBackend::Initialize(const Wind + } + } + +- if (!StateTracker::CreateInstance()) +- { +- PanicAlertFmt("Failed to create state tracker"); +- Shutdown(); +- return false; +- } +- + // Create main wrapper instances. + g_renderer = std::make_unique(std::move(swap_chain), wsi.render_surface_scale); + g_vertex_manager = std::make_unique(); +@@ -257,6 +252,9 @@ bool VideoBackend::Initialize(const Wind + + void VideoBackend::Shutdown() + { ++ if (g_scheduler) ++ g_scheduler->SyncWorker(); ++ + if (g_vulkan_context) + vkDeviceWaitIdle(g_vulkan_context->GetDevice()); + +@@ -269,6 +267,9 @@ void VideoBackend::Shutdown() + if (g_renderer) + g_renderer->Shutdown(); + ++ if (g_scheduler) ++ g_scheduler->Shutdown(); ++ + g_perf_query.reset(); + g_texture_cache.reset(); + g_framebuffer_manager.reset(); +@@ -276,8 +277,7 @@ void VideoBackend::Shutdown() + g_vertex_manager.reset(); + g_renderer.reset(); + g_object_cache.reset(); +- StateTracker::DestroyInstance(); +- g_command_buffer_mgr.reset(); ++ g_scheduler.reset(); + g_vulkan_context.reset(); + ShutdownShared(); + UnloadVulkanLibrary(); +diff -rupN dolphin.orig/Source/Core/VideoBackends/Vulkan/VKPerfQuery.cpp dolphin/Source/Core/VideoBackends/Vulkan/VKPerfQuery.cpp +--- dolphin.orig/Source/Core/VideoBackends/Vulkan/VKPerfQuery.cpp 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoBackends/Vulkan/VKPerfQuery.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -11,6 +11,7 @@ + #include "Common/Logging/Log.h" + #include "Common/MsgHandler.h" + ++#include "VKScheduler.h" + #include "VideoBackends/Vulkan/CommandBufferManager.h" + #include "VideoBackends/Vulkan/StateTracker.h" + #include "VideoBackends/Vulkan/VKRenderer.h" +@@ -49,9 +50,11 @@ void PerfQuery::EnableQuery(PerfQueryGro + if (query_count > m_query_buffer.size() / 2) + PartialFlush(query_count == PERF_QUERY_BUFFER_SIZE); + +- // Ensure command buffer is ready to go before beginning the query, that way we don't submit +- // a buffer with open queries. +- StateTracker::GetInstance()->Bind(); ++ g_scheduler->Record([](CommandBufferManager* command_buffer_mgr) { ++ // Ensure command buffer is ready to go before beginning the query, that way we don't submit ++ // a buffer with open queries. ++ command_buffer_mgr->GetStateTracker()->Bind(); ++ }); + + if (group == PQG_ZCOMP_ZCOMPLOC || group == PQG_ZCOMP) + { +@@ -59,15 +62,16 @@ void PerfQuery::EnableQuery(PerfQueryGro + DEBUG_ASSERT(!entry.has_value); + entry.has_value = true; + entry.query_group = group; +- +- // Use precise queries if supported, otherwise boolean (which will be incorrect). +- VkQueryControlFlags flags = +- g_vulkan_context->SupportsPreciseOcclusionQueries() ? VK_QUERY_CONTROL_PRECISE_BIT : 0; +- +- // Ensure the query starts within a render pass. +- StateTracker::GetInstance()->BeginRenderPass(); +- vkCmdBeginQuery(g_command_buffer_mgr->GetCurrentCommandBuffer(), m_query_pool, m_query_next_pos, +- flags); ++ g_scheduler->Record([c_query_pool = m_query_pool, ++ c_pos = m_query_next_pos](CommandBufferManager* command_buffer_mgr) { ++ // Use precise queries if supported, otherwise boolean (which will be incorrect). ++ VkQueryControlFlags flags = ++ g_vulkan_context->SupportsPreciseOcclusionQueries() ? VK_QUERY_CONTROL_PRECISE_BIT : 0; ++ ++ // Ensure the query starts within a render pass. ++ command_buffer_mgr->GetStateTracker()->BeginRenderPass(); ++ vkCmdBeginQuery(command_buffer_mgr->GetCurrentCommandBuffer(), c_query_pool, c_pos, flags); ++ }); + } + } + +@@ -75,10 +79,13 @@ void PerfQuery::DisableQuery(PerfQueryGr + { + if (group == PQG_ZCOMP_ZCOMPLOC || group == PQG_ZCOMP) + { +- vkCmdEndQuery(g_command_buffer_mgr->GetCurrentCommandBuffer(), m_query_pool, m_query_next_pos); +- ActiveQuery& entry = m_query_buffer[m_query_next_pos]; +- entry.fence_counter = g_command_buffer_mgr->GetCurrentFenceCounter(); ++ g_scheduler->Record([c_query_pool = m_query_pool, c_pos = m_query_next_pos + ++ ](CommandBufferManager* command_buffer_mgr) { ++ vkCmdEndQuery(command_buffer_mgr->GetCurrentCommandBuffer(), c_query_pool, c_pos); ++ }); ++ ActiveQuery& entry = m_query_buffer[m_query_next_pos]; ++ entry.fence_counter = g_scheduler->GetCurrentFenceCounter(); + m_query_next_pos = (m_query_next_pos + 1) % PERF_QUERY_BUFFER_SIZE; + m_query_count.fetch_add(1, std::memory_order_relaxed); + } +@@ -93,10 +100,11 @@ void PerfQuery::ResetQuery() + m_results[i].store(0, std::memory_order_relaxed); + + // Reset entire query pool, ensuring all queries are ready to write to. +- StateTracker::GetInstance()->EndRenderPass(); +- vkCmdResetQueryPool(g_command_buffer_mgr->GetCurrentCommandBuffer(), m_query_pool, 0, +- PERF_QUERY_BUFFER_SIZE); +- ++ g_scheduler->Record([c_query_pool = m_query_pool](CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->GetStateTracker()->EndRenderPass(); ++ vkCmdResetQueryPool(command_buffer_mgr->GetCurrentCommandBuffer(), c_query_pool, 0, ++ PERF_QUERY_BUFFER_SIZE); ++ }); + std::memset(m_query_buffer.data(), 0, sizeof(ActiveQuery) * m_query_buffer.size()); + } + +@@ -160,7 +168,7 @@ bool PerfQuery::CreateQueryPool() + + void PerfQuery::ReadbackQueries() + { +- const u64 completed_fence_counter = g_command_buffer_mgr->GetCompletedFenceCounter(); ++ const u64 completed_fence_counter = g_scheduler->GetCompletedFenceCounter(); + + // Need to save these since ProcessResults will modify them. + const u32 outstanding_queries = m_query_count.load(std::memory_order_relaxed); +@@ -201,9 +209,12 @@ void PerfQuery::ReadbackQueries(u32 quer + if (res != VK_SUCCESS) + LOG_VULKAN_ERROR(res, "vkGetQueryPoolResults failed: "); + +- StateTracker::GetInstance()->EndRenderPass(); +- vkCmdResetQueryPool(g_command_buffer_mgr->GetCurrentCommandBuffer(), m_query_pool, +- m_query_readback_pos, query_count); ++ g_scheduler->Record([c_query_pool = m_query_pool, c_query_readback_pos = m_query_readback_pos, ++ query_count](CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->GetStateTracker()->EndRenderPass(); ++ vkCmdResetQueryPool(command_buffer_mgr->GetCurrentCommandBuffer(), c_query_pool, ++ c_query_readback_pos, query_count); ++ }); + + // Remove pending queries. + for (u32 i = 0; i < query_count; i++) +@@ -231,8 +242,8 @@ void PerfQuery::ReadbackQueries(u32 quer + void PerfQuery::PartialFlush(bool blocking) + { + // Submit a command buffer in the background if the front query is not bound to one. +- if (blocking || m_query_buffer[m_query_readback_pos].fence_counter == +- g_command_buffer_mgr->GetCurrentFenceCounter()) ++ if (blocking || ++ m_query_buffer[m_query_readback_pos].fence_counter == g_scheduler->GetCurrentFenceCounter()) + { + Renderer::GetInstance()->ExecuteCommandBuffer(true, blocking); + } +diff -rupN dolphin.orig/Source/Core/VideoBackends/Vulkan/VKRenderer.cpp dolphin/Source/Core/VideoBackends/Vulkan/VKRenderer.cpp +--- dolphin.orig/Source/Core/VideoBackends/Vulkan/VKRenderer.cpp 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoBackends/Vulkan/VKRenderer.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -31,6 +31,7 @@ + #include "VideoBackends/Vulkan/VKVertexFormat.h" + #include "VideoBackends/Vulkan/VulkanContext.h" + ++#include "VKScheduler.h" + #include "VideoCommon/DriverDetails.h" + #include "VideoCommon/FramebufferManager.h" + #include "VideoCommon/RenderState.h" +@@ -124,7 +125,10 @@ std::unique_ptr Ren + + void Renderer::SetPipeline(const AbstractPipeline* pipeline) + { +- StateTracker::GetInstance()->SetPipeline(static_cast(pipeline)); ++ g_scheduler->Record([c_pipeline = static_cast(pipeline)]( ++ CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->GetStateTracker()->SetPipeline(c_pipeline); ++ }); + } + + std::unique_ptr Renderer::CreateBoundingBox() const +@@ -138,17 +142,6 @@ void Renderer::ClearScreen(const MathUti + g_framebuffer_manager->FlushEFBPokes(); + g_framebuffer_manager->FlagPeekCacheAsOutOfDate(); + +- // Native -> EFB coordinates +- MathUtil::Rectangle target_rc = Renderer::ConvertEFBRectangle(rc); +- +- // Size we pass this size to vkBeginRenderPass, it has to be clamped to the framebuffer +- // dimensions. The other backends just silently ignore this case. +- target_rc.ClampUL(0, 0, m_target_width, m_target_height); +- +- VkRect2D target_vk_rc = { +- {target_rc.left, target_rc.top}, +- {static_cast(target_rc.GetWidth()), static_cast(target_rc.GetHeight())}}; +- + // Determine whether the EFB has an alpha channel. If it doesn't, we can clear the alpha + // channel to 0xFF. This hopefully allows us to use the fast path in most cases. + if (bpmem.zcontrol.pixel_format == PixelFormat::RGB565_Z16 || +@@ -161,84 +154,98 @@ void Renderer::ClearScreen(const MathUti + color &= 0x00FFFFFF; + } + +- // Convert RGBA8 -> floating-point values. +- VkClearValue clear_color_value = {}; +- VkClearValue clear_depth_value = {}; +- clear_color_value.color.float32[0] = static_cast((color >> 16) & 0xFF) / 255.0f; +- clear_color_value.color.float32[1] = static_cast((color >> 8) & 0xFF) / 255.0f; +- clear_color_value.color.float32[2] = static_cast((color >> 0) & 0xFF) / 255.0f; +- clear_color_value.color.float32[3] = static_cast((color >> 24) & 0xFF) / 255.0f; +- clear_depth_value.depthStencil.depth = static_cast(z & 0xFFFFFF) / 16777216.0f; +- if (!g_ActiveConfig.backend_info.bSupportsReversedDepthRange) +- clear_depth_value.depthStencil.depth = 1.0f - clear_depth_value.depthStencil.depth; +- +- // If we're not in a render pass (start of the frame), we can use a clear render pass +- // to discard the data, rather than loading and then clearing. +- bool use_clear_attachments = (color_enable && alpha_enable) || z_enable; +- bool use_clear_render_pass = +- !StateTracker::GetInstance()->InRenderPass() && color_enable && alpha_enable && z_enable; +- +- // The NVIDIA Vulkan driver causes the GPU to lock up, or throw exceptions if MSAA is enabled, +- // a non-full clear rect is specified, and a clear loadop or vkCmdClearAttachments is used. +- if (g_ActiveConfig.iMultisamples > 1 && +- DriverDetails::HasBug(DriverDetails::BUG_BROKEN_MSAA_CLEAR)) +- { +- use_clear_render_pass = false; +- use_clear_attachments = false; +- } +- +- // This path cannot be used if the driver implementation doesn't guarantee pixels with no drawn +- // geometry in "this" renderpass won't be cleared +- if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_CLEAR_LOADOP_RENDERPASS)) +- use_clear_render_pass = false; +- +- // Fastest path: Use a render pass to clear the buffers. +- if (use_clear_render_pass) +- { +- const std::array clear_values = {{clear_color_value, clear_depth_value}}; +- StateTracker::GetInstance()->BeginClearRenderPass(target_vk_rc, clear_values.data(), +- static_cast(clear_values.size())); +- return; +- } ++ // Native -> EFB coordinates ++ MathUtil::Rectangle target_rc = Renderer::ConvertEFBRectangle(rc); ++ ++ // Size we pass this size to vkBeginRenderPass, it has to be clamped to the framebuffer ++ // dimensions. The other backends just silently ignore this case. ++ target_rc.ClampUL(0, 0, m_target_width, m_target_height); ++ ++ g_scheduler->Record([color, z, color_enable, alpha_enable, z_enable, ++ target_rc](CommandBufferManager* command_buffer_mgr) mutable { ++ VkRect2D target_vk_rc = {{target_rc.left, target_rc.top}, ++ {static_cast(target_rc.GetWidth()), ++ static_cast(target_rc.GetHeight())}}; ++ ++ // Convert RGBA8 -> floating-point values. ++ VkClearValue clear_color_value = {}; ++ VkClearValue clear_depth_value = {}; ++ clear_color_value.color.float32[0] = static_cast((color >> 16) & 0xFF) / 255.0f; ++ clear_color_value.color.float32[1] = static_cast((color >> 8) & 0xFF) / 255.0f; ++ clear_color_value.color.float32[2] = static_cast((color >> 0) & 0xFF) / 255.0f; ++ clear_color_value.color.float32[3] = static_cast((color >> 24) & 0xFF) / 255.0f; ++ clear_depth_value.depthStencil.depth = static_cast(z & 0xFFFFFF) / 16777216.0f; ++ if (!g_ActiveConfig.backend_info.bSupportsReversedDepthRange) ++ clear_depth_value.depthStencil.depth = 1.0f - clear_depth_value.depthStencil.depth; ++ ++ // If we're not in a render pass (start of the frame), we can use a clear render pass ++ // to discard the data, rather than loading and then clearing. ++ bool use_clear_attachments = (color_enable && alpha_enable) || z_enable; ++ bool use_clear_render_pass = !command_buffer_mgr->GetStateTracker()->InRenderPass() && ++ color_enable && alpha_enable && z_enable; ++ ++ // The NVIDIA Vulkan driver causes the GPU to lock up, or throw exceptions if MSAA is enabled, ++ // a non-full clear rect is specified, and a clear loadop or vkCmdClearAttachments is used. ++ if (g_ActiveConfig.iMultisamples > 1 && ++ DriverDetails::HasBug(DriverDetails::BUG_BROKEN_MSAA_CLEAR)) ++ { ++ use_clear_render_pass = false; ++ use_clear_attachments = false; ++ } ++ ++ // This path cannot be used if the driver implementation doesn't guarantee pixels with no drawn ++ // geometry in "this" renderpass won't be cleared ++ if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_CLEAR_LOADOP_RENDERPASS)) ++ use_clear_render_pass = false; + +- // Fast path: Use vkCmdClearAttachments to clear the buffers within a render path +- // We can't use this when preserving alpha but clearing color. +- if (use_clear_attachments) +- { +- VkClearAttachment clear_attachments[2]; +- uint32_t num_clear_attachments = 0; +- if (color_enable && alpha_enable) +- { +- clear_attachments[num_clear_attachments].aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; +- clear_attachments[num_clear_attachments].colorAttachment = 0; +- clear_attachments[num_clear_attachments].clearValue = clear_color_value; +- num_clear_attachments++; +- color_enable = false; +- alpha_enable = false; +- } +- if (z_enable) +- { +- clear_attachments[num_clear_attachments].aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; +- clear_attachments[num_clear_attachments].colorAttachment = 0; +- clear_attachments[num_clear_attachments].clearValue = clear_depth_value; +- num_clear_attachments++; +- z_enable = false; +- } +- if (num_clear_attachments > 0) +- { +- VkClearRect vk_rect = {target_vk_rc, 0, g_framebuffer_manager->GetEFBLayers()}; +- if (!StateTracker::GetInstance()->IsWithinRenderArea( +- target_vk_rc.offset.x, target_vk_rc.offset.y, target_vk_rc.extent.width, +- target_vk_rc.extent.height)) ++ // Fastest path: Use a render pass to clear the buffers. ++ if (use_clear_render_pass) ++ { ++ const std::array clear_values = {{clear_color_value, clear_depth_value}}; ++ command_buffer_mgr->GetStateTracker()->BeginClearRenderPass( ++ target_vk_rc, clear_values.data(), static_cast(clear_values.size())); ++ return; ++ } ++ ++ // Fast path: Use vkCmdClearAttachments to clear the buffers within a render path ++ // We can't use this when preserving alpha but clearing color. ++ if (use_clear_attachments) ++ { ++ VkClearAttachment clear_attachments[2]; ++ uint32_t num_clear_attachments = 0; ++ if (color_enable && alpha_enable) ++ { ++ clear_attachments[num_clear_attachments].aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; ++ clear_attachments[num_clear_attachments].colorAttachment = 0; ++ clear_attachments[num_clear_attachments].clearValue = clear_color_value; ++ num_clear_attachments++; ++ color_enable = false; ++ alpha_enable = false; ++ } ++ if (z_enable) + { +- StateTracker::GetInstance()->EndClearRenderPass(); ++ clear_attachments[num_clear_attachments].aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; ++ clear_attachments[num_clear_attachments].colorAttachment = 0; ++ clear_attachments[num_clear_attachments].clearValue = clear_depth_value; ++ num_clear_attachments++; ++ z_enable = false; + } +- StateTracker::GetInstance()->BeginRenderPass(); ++ if (num_clear_attachments > 0) ++ { ++ VkClearRect vk_rect = {target_vk_rc, 0, g_framebuffer_manager->GetEFBLayers()}; ++ if (!command_buffer_mgr->GetStateTracker()->IsWithinRenderArea( ++ target_vk_rc.offset.x, target_vk_rc.offset.y, target_vk_rc.extent.width, ++ target_vk_rc.extent.height)) ++ { ++ command_buffer_mgr->GetStateTracker()->EndClearRenderPass(); ++ } ++ command_buffer_mgr->GetStateTracker()->BeginRenderPass(); + +- vkCmdClearAttachments(g_command_buffer_mgr->GetCurrentCommandBuffer(), num_clear_attachments, +- clear_attachments, 1, &vk_rect); ++ vkCmdClearAttachments(command_buffer_mgr->GetCurrentCommandBuffer(), num_clear_attachments, ++ clear_attachments, 1, &vk_rect); ++ } + } +- } ++ }); + + // Anything left over for the slow path? + if (!color_enable && !alpha_enable && !z_enable) +@@ -259,10 +266,11 @@ void Renderer::WaitForGPUIdle() + + void Renderer::BindBackbuffer(const ClearColor& clear_color) + { +- StateTracker::GetInstance()->EndRenderPass(); +- +- if (!g_command_buffer_mgr->CheckLastPresentDone()) +- g_command_buffer_mgr->WaitForWorkerThreadIdle(); ++ g_scheduler->Record([](CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->GetStateTracker()->EndRenderPass(); ++ }); ++ if (!g_scheduler->CheckLastPresentDone()) ++ g_scheduler->SynchronizeSubmissionThread(); + + // Handle host window resizes. + CheckForSurfaceChange(); +@@ -276,9 +284,21 @@ void Renderer::BindBackbuffer(const Clea + m_swap_chain->SetNextFullscreenState(m_swap_chain->GetCurrentFullscreenState()); + } + +- const bool present_fail = g_command_buffer_mgr->CheckLastPresentFail(); +- VkResult res = present_fail ? g_command_buffer_mgr->GetLastPresentResult() : +- m_swap_chain->AcquireNextImage(); ++ VkSemaphore semaphore = VK_NULL_HANDLE; ++ VkResult res; ++ const bool present_fail = g_scheduler->CheckLastPresentFail(); ++ if (!present_fail) ++ { ++ semaphore = m_swap_chain->GetNextSemaphore(); ++ g_scheduler->Record([c_semaphore = semaphore](CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->SetWaitSemaphoreForCurrentCommandBuffer(c_semaphore); ++ }); ++ res = m_swap_chain->AcquireNextImage(semaphore); ++ } ++ else ++ { ++ res = g_scheduler->GetLastPresentResult(); ++ } + + if (res == VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT && + !m_swap_chain->GetCurrentFullscreenState()) +@@ -289,8 +309,13 @@ void Renderer::BindBackbuffer(const Clea + res = VK_SUCCESS; + if (present_fail) + { ++ if (semaphore == VK_NULL_HANDLE) ++ { ++ semaphore = m_swap_chain->GetNextSemaphore(); ++ } ++ + // We still need to acquire an image. +- res = m_swap_chain->AcquireNextImage(); ++ res = m_swap_chain->AcquireNextImage(semaphore); + } + } + +@@ -309,7 +334,7 @@ void Renderer::BindBackbuffer(const Clea + else if (res == VK_SUBOPTIMAL_KHR || res == VK_ERROR_OUT_OF_DATE_KHR) + { + INFO_LOG_FMT(VIDEO, "Resizing swap chain due to suboptimal/out-of-date"); +- m_swap_chain->ResizeSwapChain(); ++ m_swap_chain->ResizeSwapChain(m_backbuffer_width, m_backbuffer_height); + } + else + { +@@ -318,7 +343,12 @@ void Renderer::BindBackbuffer(const Clea + m_swap_chain->RecreateSwapChain(); + } + +- res = m_swap_chain->AcquireNextImage(); ++ semaphore = m_swap_chain->GetNextSemaphore(); ++ g_scheduler->Record([c_semaphore = semaphore](CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->SetWaitSemaphoreForCurrentCommandBuffer(c_semaphore); ++ }); ++ ++ res = m_swap_chain->AcquireNextImage(semaphore); + if (res != VK_SUCCESS) + PanicAlertFmt("Failed to grab image from swap chain: {:#010X} {}", static_cast(res), + VkResultToString(res)); +@@ -328,8 +358,7 @@ void Renderer::BindBackbuffer(const Clea + // color attachment ready for writing. These transitions must occur outside + // a render pass, unless the render pass declares a self-dependency. + m_swap_chain->GetCurrentTexture()->OverrideImageLayout(VK_IMAGE_LAYOUT_UNDEFINED); +- m_swap_chain->GetCurrentTexture()->TransitionToLayout( +- g_command_buffer_mgr->GetCurrentCommandBuffer(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); ++ m_swap_chain->GetCurrentTexture()->TransitionToLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + SetAndClearFramebuffer(m_swap_chain->GetCurrentFramebuffer(), + ClearColor{{0.0f, 0.0f, 0.0f, 1.0f}}); + } +@@ -337,22 +366,20 @@ void Renderer::BindBackbuffer(const Clea + void Renderer::PresentBackbuffer() + { + // End drawing to backbuffer +- StateTracker::GetInstance()->EndRenderPass(); ++ g_scheduler->Record([](CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->GetStateTracker()->EndRenderPass(); ++ }); + + // Transition the backbuffer to PRESENT_SRC to ensure all commands drawing + // to it have finished before present. +- m_swap_chain->GetCurrentTexture()->TransitionToLayout( +- g_command_buffer_mgr->GetCurrentCommandBuffer(), VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); ++ m_swap_chain->GetCurrentTexture()->TransitionToLayout(VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); + + // Submit the current command buffer, signaling rendering finished semaphore when it's done + // Because this final command buffer is rendering to the swap chain, we need to wait for + // the available semaphore to be signaled before executing the buffer. This final submission + // can happen off-thread in the background while we're preparing the next frame. +- g_command_buffer_mgr->SubmitCommandBuffer(true, false, m_swap_chain->GetSwapChain(), +- m_swap_chain->GetCurrentImageIndex()); +- +- // New cmdbuffer, so invalidate state. +- StateTracker::GetInstance()->InvalidateCachedState(); ++ g_scheduler->SubmitCommandBuffer(true, false, m_swap_chain->GetSwapChain(), ++ m_swap_chain->GetCurrentImageIndex()); + } + + void Renderer::SetFullscreen(bool enable_fullscreen) +@@ -370,11 +397,7 @@ bool Renderer::IsFullscreen() const + + void Renderer::ExecuteCommandBuffer(bool submit_off_thread, bool wait_for_completion) + { +- StateTracker::GetInstance()->EndRenderPass(); +- +- g_command_buffer_mgr->SubmitCommandBuffer(submit_off_thread, wait_for_completion); +- +- StateTracker::GetInstance()->InvalidateCachedState(); ++ g_scheduler->SubmitCommandBuffer(submit_off_thread, wait_for_completion); + } + + void Renderer::CheckForSurfaceChange() +@@ -382,15 +405,20 @@ void Renderer::CheckForSurfaceChange() + if (!m_surface_changed.TestAndClear() || !m_swap_chain) + return; + ++ g_scheduler->SyncWorker(); ++ + // Submit the current draws up until rendering the XFB. + ExecuteCommandBuffer(false, true); + + // Clear the present failed flag, since we don't want to resize after recreating. +- g_command_buffer_mgr->CheckLastPresentFail(); ++ g_scheduler->CheckLastPresentFail(); + + // Recreate the surface. If this fails we're in trouble. +- if (!m_swap_chain->RecreateSurface(m_new_surface_handle)) ++ if (!m_swap_chain->RecreateSurface(m_new_surface_handle, m_new_surface_width, ++ m_new_surface_height)) ++ { + PanicAlertFmt("Failed to recreate Vulkan surface. Cannot continue."); ++ } + m_new_surface_handle = nullptr; + + // Handle case where the dimensions are now different. +@@ -402,6 +430,8 @@ void Renderer::CheckForSurfaceResize() + if (!m_surface_resized.TestAndClear()) + return; + ++ g_scheduler->SyncWorker(); ++ + // If we don't have a surface, how can we resize the swap chain? + // CheckForSurfaceChange should handle this case. + if (!m_swap_chain) +@@ -414,17 +444,21 @@ void Renderer::CheckForSurfaceResize() + ExecuteCommandBuffer(false, true); + + // Clear the present failed flag, since we don't want to resize after recreating. +- g_command_buffer_mgr->CheckLastPresentFail(); ++ g_scheduler->CheckLastPresentFail(); + + // Resize the swap chain. +- m_swap_chain->RecreateSwapChain(); ++ m_swap_chain->ResizeSwapChain(m_new_surface_width, m_new_surface_height); + OnSwapChainResized(); + } + + void Renderer::OnConfigChanged(u32 bits) + { + if (bits & CONFIG_CHANGE_BIT_HOST_CONFIG) +- g_object_cache->ReloadPipelineCache(); ++ { ++ g_scheduler->Record([](CommandBufferManager* command_buffer_manager) { ++ g_object_cache->ReloadPipelineCache(); ++ }); ++ } + + // For vsync, we need to change the present mode, which means recreating the swap chain. + if (m_swap_chain && bits & CONFIG_CHANGE_BIT_VSYNC) +@@ -456,22 +490,32 @@ void Renderer::OnSwapChainResized() + + void Renderer::BindFramebuffer(VKFramebuffer* fb) + { +- StateTracker::GetInstance()->EndRenderPass(); ++ g_scheduler->Record([fb](CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->GetStateTracker()->EndRenderPass(); + +- // Shouldn't be bound as a texture. +- if (fb->GetColorAttachment()) +- { +- StateTracker::GetInstance()->UnbindTexture( +- static_cast(fb->GetColorAttachment())->GetView()); +- } +- if (fb->GetDepthAttachment()) +- { +- StateTracker::GetInstance()->UnbindTexture( +- static_cast(fb->GetDepthAttachment())->GetView()); +- } ++ // Shouldn't be bound as a texture. ++ if (fb->GetColorAttachment()) ++ { ++ command_buffer_mgr->GetStateTracker()->UnbindTexture( ++ static_cast(fb->GetColorAttachment())->GetView()); ++ } ++ if (fb->GetDepthAttachment()) ++ { ++ command_buffer_mgr->GetStateTracker()->UnbindTexture( ++ static_cast(fb->GetDepthAttachment())->GetView()); ++ } ++ }); + + fb->TransitionForRender(); +- StateTracker::GetInstance()->SetFramebuffer(fb); ++ ++ g_scheduler->Record([c_framebuffer = fb->GetFB(), c_rect = fb->GetRect(), ++ c_load_render_pass = fb->GetLoadRenderPass(), ++ c_clear_render_pass = fb->GetClearRenderPass(), ++ c_discard_render_pass = ++ fb->GetDiscardRenderPass()](CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->GetStateTracker()->SetFramebuffer( ++ c_framebuffer, c_rect, c_load_render_pass, c_clear_render_pass, c_discard_render_pass); ++ }); + m_current_framebuffer = fb; + } + +@@ -494,7 +538,9 @@ void Renderer::SetAndDiscardFramebuffer( + + // If we're discarding, begin the discard pass, then switch to a load pass. + // This way if the command buffer is flushed, we don't start another discard pass. +- StateTracker::GetInstance()->BeginDiscardRenderPass(); ++ g_scheduler->Record([](CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->GetStateTracker()->BeginDiscardRenderPass(); ++ }); + } + + void Renderer::SetAndClearFramebuffer(AbstractFramebuffer* framebuffer, +@@ -503,22 +549,25 @@ void Renderer::SetAndClearFramebuffer(Ab + VKFramebuffer* vkfb = static_cast(framebuffer); + BindFramebuffer(vkfb); + +- std::array clear_values; +- u32 num_clear_values = 0; +- if (vkfb->GetColorFormat() != AbstractTextureFormat::Undefined) +- { +- std::memcpy(clear_values[num_clear_values].color.float32, color_value.data(), +- sizeof(clear_values[num_clear_values].color.float32)); +- num_clear_values++; +- } +- if (vkfb->GetDepthFormat() != AbstractTextureFormat::Undefined) +- { +- clear_values[num_clear_values].depthStencil.depth = depth_value; +- clear_values[num_clear_values].depthStencil.stencil = 0; +- num_clear_values++; +- } +- StateTracker::GetInstance()->BeginClearRenderPass(vkfb->GetRect(), clear_values.data(), +- num_clear_values); ++ g_scheduler->Record( ++ [vkfb, c_color_value = color_value, depth_value](CommandBufferManager* command_buffer_mgr) { ++ std::array clear_values; ++ u32 num_clear_values = 0; ++ if (vkfb->GetColorFormat() != AbstractTextureFormat::Undefined) ++ { ++ std::memcpy(clear_values[num_clear_values].color.float32, c_color_value.data(), ++ sizeof(clear_values[num_clear_values].color.float32)); ++ num_clear_values++; ++ } ++ if (vkfb->GetDepthFormat() != AbstractTextureFormat::Undefined) ++ { ++ clear_values[num_clear_values].depthStencil.depth = depth_value; ++ clear_values[num_clear_values].depthStencil.stencil = 0; ++ num_clear_values++; ++ } ++ command_buffer_mgr->GetStateTracker()->BeginClearRenderPass( ++ vkfb->GetRect(), clear_values.data(), num_clear_values); ++ }); + } + + void Renderer::SetTexture(u32 index, const AbstractTexture* texture) +@@ -526,25 +575,31 @@ void Renderer::SetTexture(u32 index, con + // Texture should always be in SHADER_READ_ONLY layout prior to use. + // This is so we don't need to transition during render passes. + const VKTexture* tex = static_cast(texture); ++ + if (tex) + { + if (tex->GetLayout() != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + { +- if (StateTracker::GetInstance()->InRenderPass()) +- { +- WARN_LOG_FMT(VIDEO, "Transitioning image in render pass in Renderer::SetTexture()"); +- StateTracker::GetInstance()->EndRenderPass(); +- } ++ g_scheduler->Record([](CommandBufferManager* command_buffer_mgr) { ++ if (command_buffer_mgr->GetStateTracker()->InRenderPass()) ++ { ++ WARN_LOG_FMT(VIDEO, "Transitioning image in render pass in Renderer::SetTexture()"); ++ command_buffer_mgr->GetStateTracker()->EndRenderPass(); ++ } ++ }); + +- tex->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), +- VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); ++ tex->TransitionToLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + } + +- StateTracker::GetInstance()->SetTexture(index, tex->GetView()); ++ g_scheduler->Record([c_view = tex->GetView(), index](CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->GetStateTracker()->SetTexture(index, c_view); ++ }); + } + else + { +- StateTracker::GetInstance()->SetTexture(0, VK_NULL_HANDLE); ++ g_scheduler->Record([](CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->GetStateTracker()->SetTexture(0, VK_NULL_HANDLE); ++ }); + } + } + +@@ -554,15 +609,17 @@ void Renderer::SetSamplerState(u32 index + if (m_sampler_states[index] == state) + return; + +- // Look up new state and replace in state tracker. +- VkSampler sampler = g_object_cache->GetSampler(state); +- if (sampler == VK_NULL_HANDLE) +- { +- ERROR_LOG_FMT(VIDEO, "Failed to create sampler"); +- sampler = g_object_cache->GetPointSampler(); +- } ++ g_scheduler->Record([index, c_sampler_state = state](CommandBufferManager* command_buffer_mgr) { ++ // Look up new state and replace in state tracker. ++ VkSampler sampler = g_object_cache->GetSampler(c_sampler_state); ++ if (sampler == VK_NULL_HANDLE) ++ { ++ ERROR_LOG_FMT(VIDEO, "Failed to create sampler"); ++ sampler = g_object_cache->GetPointSampler(); ++ } + +- StateTracker::GetInstance()->SetSampler(index, sampler); ++ command_buffer_mgr->GetStateTracker()->SetSampler(index, sampler); ++ }); + m_sampler_states[index] = state; + } + +@@ -571,87 +628,116 @@ void Renderer::SetComputeImageTexture(Ab + VKTexture* vk_texture = static_cast(texture); + if (vk_texture) + { +- StateTracker::GetInstance()->EndRenderPass(); +- StateTracker::GetInstance()->SetImageTexture(vk_texture->GetView()); +- vk_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), +- read ? (write ? VKTexture::ComputeImageLayout::ReadWrite : ++ g_scheduler->Record([c_view = vk_texture->GetView()](CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->GetStateTracker()->EndRenderPass(); ++ command_buffer_mgr->GetStateTracker()->SetImageTexture(c_view); ++ }); ++ ++ vk_texture->TransitionToLayout(read ? (write ? VKTexture::ComputeImageLayout::ReadWrite : + VKTexture::ComputeImageLayout::ReadOnly) : + VKTexture::ComputeImageLayout::WriteOnly); + } + else + { +- StateTracker::GetInstance()->SetImageTexture(VK_NULL_HANDLE); ++ g_scheduler->Record([](CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->GetStateTracker()->SetImageTexture(VK_NULL_HANDLE); ++ }); + } + } + + void Renderer::UnbindTexture(const AbstractTexture* texture) + { +- StateTracker::GetInstance()->UnbindTexture(static_cast(texture)->GetView()); ++ g_scheduler->Record([c_view = static_cast(texture)->GetView()]( ++ CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->GetStateTracker()->UnbindTexture(c_view); ++ }); + } + + void Renderer::ResetSamplerStates() + { +- // Invalidate all sampler states, next draw will re-initialize them. + for (u32 i = 0; i < m_sampler_states.size(); i++) + { + m_sampler_states[i] = RenderState::GetPointSamplerState(); +- StateTracker::GetInstance()->SetSampler(i, g_object_cache->GetPointSampler()); + } + +- // Invalidate all sampler objects (some will be unused now). +- g_object_cache->ClearSamplerCache(); ++ g_scheduler->Record( ++ [c_sampler_count = m_sampler_states.size()](CommandBufferManager* command_buffer_mgr) { ++ // Invalidate all sampler states, next draw will re-initialize them. ++ for (u32 i = 0; i < c_sampler_count; i++) ++ { ++ command_buffer_mgr->GetStateTracker()->SetSampler(i, g_object_cache->GetPointSampler()); ++ } ++ ++ // Invalidate all sampler objects (some will be unused now). ++ g_object_cache->ClearSamplerCache(); ++ }); + } + + void Renderer::SetScissorRect(const MathUtil::Rectangle& rc) + { +- VkRect2D scissor = {{rc.left, rc.top}, +- {static_cast(rc.GetWidth()), static_cast(rc.GetHeight())}}; +- +- // See Vulkan spec for vkCmdSetScissor: +- // The x and y members of offset must be greater than or equal to 0. +- if (scissor.offset.x < 0) +- { +- scissor.extent.width -= -scissor.offset.x; +- scissor.offset.x = 0; +- } +- if (scissor.offset.y < 0) +- { +- scissor.extent.height -= -scissor.offset.y; +- scissor.offset.y = 0; +- } +- StateTracker::GetInstance()->SetScissor(scissor); ++ g_scheduler->Record([c_rc = rc](CommandBufferManager* command_buffer_mgr) { ++ VkRect2D scissor = {{c_rc.left, c_rc.top}, ++ {static_cast(c_rc.GetWidth()), static_cast(c_rc.GetHeight())}}; ++ ++ // See Vulkan spec for vkCmdSetScissor: ++ // The x and y members of offset must be greater than or equal to 0. ++ if (scissor.offset.x < 0) ++ { ++ scissor.extent.width -= -scissor.offset.x; ++ scissor.offset.x = 0; ++ } ++ if (scissor.offset.y < 0) ++ { ++ scissor.extent.height -= -scissor.offset.y; ++ scissor.offset.y = 0; ++ } ++ command_buffer_mgr->GetStateTracker()->SetScissor(scissor); ++ }); + } + + void Renderer::SetViewport(float x, float y, float width, float height, float near_depth, + float far_depth) + { + VkViewport viewport = {x, y, width, height, near_depth, far_depth}; +- StateTracker::GetInstance()->SetViewport(viewport); ++ g_scheduler->Record([viewport](CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->GetStateTracker()->SetViewport(viewport); ++ }); + } + + void Renderer::Draw(u32 base_vertex, u32 num_vertices) + { +- if (!StateTracker::GetInstance()->Bind()) +- return; ++ g_scheduler->Record([base_vertex, num_vertices](CommandBufferManager* command_buffer_mgr) { ++ if (!command_buffer_mgr->GetStateTracker()->Bind()) ++ return; + +- vkCmdDraw(g_command_buffer_mgr->GetCurrentCommandBuffer(), num_vertices, 1, base_vertex, 0); ++ vkCmdDraw(command_buffer_mgr->GetCurrentCommandBuffer(), num_vertices, 1, base_vertex, 0); ++ }); + } + + void Renderer::DrawIndexed(u32 base_index, u32 num_indices, u32 base_vertex) + { +- if (!StateTracker::GetInstance()->Bind()) +- return; +- +- vkCmdDrawIndexed(g_command_buffer_mgr->GetCurrentCommandBuffer(), num_indices, 1, base_index, +- base_vertex, 0); ++ g_scheduler->Record( ++ [base_vertex, num_indices, base_index](CommandBufferManager* command_buffer_mgr) { ++ if (!command_buffer_mgr->GetStateTracker()->Bind()) ++ return; ++ ++ vkCmdDrawIndexed(command_buffer_mgr->GetCurrentCommandBuffer(), num_indices, 1, base_index, ++ base_vertex, 0); ++ }); + } + + void Renderer::DispatchComputeShader(const AbstractShader* shader, u32 groupsize_x, u32 groupsize_y, + u32 groupsize_z, u32 groups_x, u32 groups_y, u32 groups_z) + { +- StateTracker::GetInstance()->SetComputeShader(static_cast(shader)); +- if (StateTracker::GetInstance()->BindCompute()) +- vkCmdDispatch(g_command_buffer_mgr->GetCurrentCommandBuffer(), groups_x, groups_y, groups_z); ++ g_scheduler->Record([groups_x, groups_y, groups_z, ++ shader](CommandBufferManager* command_buffer_mgr) { ++ if (!command_buffer_mgr->GetStateTracker()->Bind()) ++ return; ++ ++ command_buffer_mgr->GetStateTracker()->SetComputeShader(static_cast(shader)); ++ if (command_buffer_mgr->GetStateTracker()->BindCompute()) ++ vkCmdDispatch(command_buffer_mgr->GetCurrentCommandBuffer(), groups_x, groups_y, groups_z); ++ }); + } + + } // namespace Vulkan +diff -rupN dolphin.orig/Source/Core/VideoBackends/Vulkan/VKScheduler.cpp dolphin/Source/Core/VideoBackends/Vulkan/VKScheduler.cpp +--- dolphin.orig/Source/Core/VideoBackends/Vulkan/VKScheduler.cpp 1970-01-01 00:00:00.000000000 +0000 ++++ dolphin/Source/Core/VideoBackends/Vulkan/VKScheduler.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -0,0 +1,155 @@ ++// Copyright 2022 Dolphin Emulator Project ++// SPDX-License-Identifier: GPL-2.0-or-later ++ ++#include "VKScheduler.h" ++#include ++#include "Common/Thread.h" ++#include "StateTracker.h" ++ ++namespace Vulkan ++{ ++Scheduler::Scheduler() ++ : m_commandBufferManager(std::make_unique()), ++ m_submit_loop(std::make_unique()) ++{ ++ AcquireNewChunk(); ++ ++ m_worker = std::thread([this]() { ++ Common::SetCurrentThreadName("Vulkan CS Thread"); ++ WorkerThread(); ++ }); ++} ++ ++Scheduler::~Scheduler() ++{ ++ m_submit_loop->Stop(); ++ m_worker.join(); ++} ++ ++bool Scheduler::Initialize() ++{ ++ return m_commandBufferManager->Initialize(); ++} ++ ++void Scheduler::CommandChunk::ExecuteAll(CommandBufferManager* cmdbuf) ++{ ++ auto command = first; ++ while (command != nullptr) ++ { ++ auto next = command->GetNext(); ++ command->Execute(cmdbuf); ++ command->~Command(); ++ command = next; ++ } ++ command_offset = 0; ++ first = nullptr; ++ last = nullptr; ++} ++ ++void Scheduler::AcquireNewChunk() ++{ ++ std::scoped_lock lock{m_reserve_mutex}; ++ if (m_chunk_reserve.empty()) ++ { ++ m_chunk = std::make_unique(); ++ return; ++ } ++ m_chunk = std::move(m_chunk_reserve.back()); ++ m_chunk_reserve.pop_back(); ++} ++ ++void Scheduler::Flush() ++{ ++ if (m_chunk->Empty()) ++ return; ++ ++ { ++ std::scoped_lock lock{m_work_mutex}; ++ m_worker_idle = false; ++ m_work_queue.push(std::move(m_chunk)); ++ m_submit_loop->Wakeup(); ++ } ++ AcquireNewChunk(); ++} ++ ++void Scheduler::SyncWorker() ++{ ++ Flush(); ++ std::unique_lock lock{m_work_mutex}; ++ m_idle_condvar.wait(lock, [this] { return m_worker_idle; }); ++} ++ ++void Scheduler::WorkerThread() ++{ ++ m_submit_loop->Run([this]() { ++ std::unique_ptr work; ++ { ++ std::scoped_lock lock{m_work_mutex}; ++ if (m_work_queue.empty()) ++ { ++ m_worker_idle = true; ++ m_idle_condvar.notify_all(); ++ m_submit_loop->AllowSleep(); ++ return; ++ } ++ work = std::move(m_work_queue.front()); ++ m_work_queue.pop(); ++ } ++ ++ work->ExecuteAll(m_commandBufferManager.get()); ++ { ++ std::scoped_lock reserve_lock{m_reserve_mutex}; ++ m_chunk_reserve.push_back(std::move(work)); ++ } ++ { ++ std::scoped_lock lock{m_work_mutex}; ++ if (m_work_queue.empty()) ++ { ++ m_worker_idle = true; ++ m_idle_condvar.notify_all(); ++ } ++ } ++ }); ++} ++ ++void Scheduler::Shutdown() ++{ ++ SyncWorker(); ++ SynchronizeSubmissionThread(); ++} ++ ++void Scheduler::SynchronizeSubmissionThread() ++{ ++ SyncWorker(); ++ m_commandBufferManager->WaitForSubmitWorkerThreadIdle(); ++} ++ ++void Scheduler::WaitForFenceCounter(u64 counter) ++{ ++ if (m_commandBufferManager->GetCompletedFenceCounter() >= counter) ++ return; ++ ++ SyncWorker(); ++ m_commandBufferManager->WaitForFenceCounter(counter); ++} ++ ++void Scheduler::SubmitCommandBuffer(bool submit_on_worker_thread, bool wait_for_completion, ++ VkSwapchainKHR present_swap_chain, uint32_t present_image_index) ++{ ++ const u64 fence_counter = ++m_current_fence_counter; ++ Record([fence_counter, submit_on_worker_thread, wait_for_completion, present_swap_chain, ++ present_image_index](CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->GetStateTracker()->EndRenderPass(); ++ command_buffer_mgr->SubmitCommandBuffer(fence_counter, submit_on_worker_thread, ++ wait_for_completion, present_swap_chain, ++ present_image_index); ++ }); ++ ++ if (wait_for_completion) [[unlikely]] ++ g_scheduler->WaitForFenceCounter(fence_counter); ++ else ++ Flush(); ++} ++ ++std::unique_ptr g_scheduler; ++} // namespace Vulkan +diff -rupN dolphin.orig/Source/Core/VideoBackends/Vulkan/VKScheduler.h dolphin/Source/Core/VideoBackends/Vulkan/VKScheduler.h +--- dolphin.orig/Source/Core/VideoBackends/Vulkan/VKScheduler.h 1970-01-01 00:00:00.000000000 +0000 ++++ dolphin/Source/Core/VideoBackends/Vulkan/VKScheduler.h 2024-03-05 04:06:08.240295843 +0000 +@@ -0,0 +1,160 @@ ++// Copyright 2022 Dolphin Emulator Project ++// SPDX-License-Identifier: GPL-2.0-or-later ++ ++#pragma once ++ ++#include ++#include ++ ++#include "CommandBufferManager.h" ++#include "Common/Align.h" ++ ++namespace Vulkan ++{ ++class Scheduler ++{ ++ class Command ++ { ++ public: ++ virtual ~Command() = default; ++ ++ virtual void Execute(CommandBufferManager* cmdbuf) = 0; ++ ++ Command* GetNext() const { return next; } ++ ++ void SetNext(Command* next_) { next = next_; } ++ ++ private: ++ Command* next = nullptr; ++ }; ++ ++ template ++ class alignas(16) TypedCommand final : public Command ++ { ++ public: ++ explicit TypedCommand(T&& command_) : command{std::move(command_)} {} ++ ++ ~TypedCommand() override = default; ++ ++ TypedCommand(TypedCommand&&) = delete; ++ ++ TypedCommand& operator=(TypedCommand&&) = delete; ++ ++ void Execute(CommandBufferManager* cmdbuf) override { command(cmdbuf); } ++ ++ private: ++ T command; ++ }; ++ ++ class CommandChunk final ++ { ++ public: ++ void ExecuteAll(CommandBufferManager* cmdbuf); ++ ++ template ++ bool Record(T& command) ++ { ++ using FuncType = TypedCommand; ++ static_assert(sizeof(FuncType) < sizeof(data), "Lambda is too large"); ++ ++ command_offset = Common::AlignUp(command_offset, alignof(FuncType)); ++ if (command_offset > sizeof(data) - sizeof(FuncType)) [[unlikely]] ++ { ++ return false; ++ } ++ Command* const current_last = last; ++ last = new (data.data() + command_offset) FuncType(std::move(command)); ++ ++ if (current_last) [[likely]] ++ { ++ current_last->SetNext(last); ++ } ++ else ++ { ++ first = last; ++ } ++ command_offset += sizeof(FuncType); ++ return true; ++ } ++ ++ bool Empty() const { return command_offset == 0; } ++ ++ private: ++ Command* first = nullptr; ++ Command* last = nullptr; ++ ++ size_t command_offset = 0; ++ alignas(64) std::array data{}; ++ }; ++ ++public: ++ Scheduler(); ++ ~Scheduler(); ++ ++ bool Initialize(); ++ ++ void Flush(); ++ void SyncWorker(); ++ ++ void Shutdown(); ++ ++ template ++ void Record(T&& command) ++ { ++#ifdef VULKAN_DISABLE_THREADING ++ command(m_commandBufferManager.get()); ++ return; ++#endif ++ ++ if (m_chunk->Record(command)) [[likely]] ++ return; ++ ++ Flush(); ++ (void)m_chunk->Record(command); ++ } ++ ++ uint64_t GetCompletedFenceCounter() const ++ { ++ return m_commandBufferManager->GetCompletedFenceCounter(); ++ } ++ ++ uint64_t GetCurrentFenceCounter() const ++ { ++ return m_current_fence_counter.load(std::memory_order_acquire); ++ } ++ ++ void WaitForFenceCounter(u64 counter); ++ void SynchronizeSubmissionThread(); ++ ++ bool CheckLastPresentFail() { return m_commandBufferManager->CheckLastPresentFail(); } ++ VkResult GetLastPresentResult() const { return m_commandBufferManager->GetLastPresentResult(); } ++ bool CheckLastPresentDone() { return m_commandBufferManager->CheckLastPresentDone(); } ++ ++ void SubmitCommandBuffer(bool submit_on_worker_thread, bool wait_for_completion, ++ VkSwapchainKHR present_swap_chain = VK_NULL_HANDLE, ++ uint32_t present_image_index = 0xFFFFFFFF); ++ ++private: ++ void WorkerThread(); ++ void AcquireNewChunk(); ++ ++ std::unique_ptr m_commandBufferManager; ++ ++ std::unique_ptr m_chunk; ++ ++ std::thread m_worker; ++ std::unique_ptr m_submit_loop; ++ ++ std::atomic m_current_fence_counter = 1; ++ ++ std::queue> m_work_queue; ++ std::mutex m_work_mutex; ++ std::condition_variable m_idle_condvar; ++ bool m_worker_idle{true}; ++ ++ std::vector> m_chunk_reserve; ++ std::mutex m_reserve_mutex; ++}; ++ ++extern std::unique_ptr g_scheduler; ++} // namespace Vulkan +diff -rupN dolphin.orig/Source/Core/VideoBackends/Vulkan/VKStreamBuffer.cpp dolphin/Source/Core/VideoBackends/Vulkan/VKStreamBuffer.cpp +--- dolphin.orig/Source/Core/VideoBackends/Vulkan/VKStreamBuffer.cpp 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoBackends/Vulkan/VKStreamBuffer.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -12,6 +12,7 @@ + #include "Common/MsgHandler.h" + + #include "VideoBackends/Vulkan/CommandBufferManager.h" ++#include "VideoBackends/Vulkan/VKScheduler.h" + #include "VideoBackends/Vulkan/VulkanContext.h" + + namespace Vulkan +@@ -24,7 +25,13 @@ StreamBuffer::~StreamBuffer() + { + // VMA_ALLOCATION_CREATE_MAPPED_BIT automatically handles unmapping for us + if (m_buffer != VK_NULL_HANDLE) +- g_command_buffer_mgr->DeferBufferDestruction(m_buffer, m_alloc); ++ { ++ g_scheduler->Record( ++ [c_buffer = m_buffer, c_alloc = m_alloc](CommandBufferManager* command_buffer_mgr) { ++ if (c_buffer != VK_NULL_HANDLE) ++ command_buffer_mgr->DeferBufferDestruction(c_buffer, c_alloc); ++ }); ++ } + } + + std::unique_ptr StreamBuffer::Create(VkBufferUsageFlags usage, u32 size) +@@ -75,8 +82,11 @@ bool StreamBuffer::AllocateBuffer() + + // Destroy the backings for the buffer after the command buffer executes + // VMA_ALLOCATION_CREATE_MAPPED_BIT automatically handles unmapping for us +- if (m_buffer != VK_NULL_HANDLE) +- g_command_buffer_mgr->DeferBufferDestruction(m_buffer, m_alloc); ++ g_scheduler->Record( ++ [c_buffer = m_buffer, c_alloc = m_alloc](CommandBufferManager* command_buffer_mgr) { ++ if (c_buffer != VK_NULL_HANDLE) ++ command_buffer_mgr->DeferBufferDestruction(c_buffer, c_alloc); ++ }); + + // Replace with the new buffer + m_buffer = buffer; +@@ -175,7 +185,7 @@ void StreamBuffer::UpdateCurrentFencePos + return; + + // Has the offset changed since the last fence? +- const u64 counter = g_command_buffer_mgr->GetCurrentFenceCounter(); ++ const u64 counter = g_scheduler->GetCurrentFenceCounter(); + if (!m_tracked_fences.empty() && m_tracked_fences.back().first == counter) + { + // Still haven't executed a command buffer, so just update the offset. +@@ -193,7 +203,7 @@ void StreamBuffer::UpdateGPUPosition() + auto start = m_tracked_fences.begin(); + auto end = start; + +- const u64 completed_counter = g_command_buffer_mgr->GetCompletedFenceCounter(); ++ const u64 completed_counter = g_scheduler->GetCompletedFenceCounter(); + while (end != m_tracked_fences.end() && completed_counter >= end->first) + { + m_current_gpu_position = end->second; +@@ -266,14 +276,13 @@ bool StreamBuffer::WaitForClearSpace(u32 + + // Did any fences satisfy this condition? + // Has the command buffer been executed yet? If not, the caller should execute it. +- if (iter == m_tracked_fences.end() || +- iter->first == g_command_buffer_mgr->GetCurrentFenceCounter()) ++ if (iter == m_tracked_fences.end() || iter->first == g_scheduler->GetCurrentFenceCounter()) + { + return false; + } + + // Wait until this fence is signaled. This will fire the callback, updating the GPU position. +- g_command_buffer_mgr->WaitForFenceCounter(iter->first); ++ g_scheduler->WaitForFenceCounter(iter->first); + m_tracked_fences.erase(m_tracked_fences.begin(), + m_current_offset == iter->second ? m_tracked_fences.end() : ++iter); + m_current_offset = new_offset; +diff -rupN dolphin.orig/Source/Core/VideoBackends/Vulkan/VKSwapChain.cpp dolphin/Source/Core/VideoBackends/Vulkan/VKSwapChain.cpp +--- dolphin.orig/Source/Core/VideoBackends/Vulkan/VKSwapChain.cpp 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoBackends/Vulkan/VKSwapChain.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -13,9 +13,9 @@ + + #include "VideoBackends/Vulkan/CommandBufferManager.h" + #include "VideoBackends/Vulkan/ObjectCache.h" ++#include "VideoBackends/Vulkan/VKScheduler.h" + #include "VideoBackends/Vulkan/VKTexture.h" + #include "VideoBackends/Vulkan/VulkanContext.h" +-#include "VideoCommon/RenderBase.h" + + #if defined(VK_USE_PLATFORM_XLIB_KHR) + #include +@@ -25,15 +25,18 @@ namespace Vulkan + { + SwapChain::SwapChain(const WindowSystemInfo& wsi, VkSurfaceKHR surface, bool vsync) + : m_wsi(wsi), m_surface(surface), m_vsync_enabled(vsync), +- m_fullscreen_supported(g_vulkan_context->SupportsExclusiveFullscreen(wsi, surface)) ++ m_fullscreen_supported(g_vulkan_context->SupportsExclusiveFullscreen(wsi, surface)), ++ m_width(wsi.render_surface_width), m_height(wsi.render_surface_height) + { + } + + SwapChain::~SwapChain() + { ++ g_scheduler->SyncWorker(); + DestroySwapChainImages(); + DestroySwapChain(); + DestroySurface(); ++ DestroySemaphores(); + } + + VkSurfaceKHR SwapChain::CreateVulkanSurface(VkInstance instance, const WindowSystemInfo& wsi) +@@ -84,6 +87,29 @@ VkSurfaceKHR SwapChain::CreateVulkanSurf + } + #endif + ++#if defined(VK_USE_PLATFORM_WAYLAND_KHR) ++ if (wsi.type == WindowSystemType::Wayland) ++ { ++ VkWaylandSurfaceCreateInfoKHR surface_create_info = { ++ VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR, // VkStructureType sType ++ nullptr, // const void* pNext ++ 0, // VkWaylandSurfaceCreateFlagsKHR flags ++ static_cast(wsi.display_connection), // struct wl_display* display ++ static_cast(wsi.render_surface) // struct wl_surface* surface ++ }; ++ ++ VkSurfaceKHR surface; ++ VkResult res = vkCreateWaylandSurfaceKHR(instance, &surface_create_info, nullptr, &surface); ++ if (res != VK_SUCCESS) ++ { ++ LOG_VULKAN_ERROR(res, "vkCreateWaylandSurfaceKHR failed: "); ++ return VK_NULL_HANDLE; ++ } ++ ++ return surface; ++ } ++#endif ++ + #if defined(VK_USE_PLATFORM_ANDROID_KHR) + if (wsi.type == WindowSystemType::Android) + { +@@ -132,7 +158,8 @@ std::unique_ptr SwapChain::Cr + bool vsync) + { + std::unique_ptr swap_chain = std::make_unique(wsi, surface, vsync); +- if (!swap_chain->CreateSwapChain() || !swap_chain->SetupSwapChainImages()) ++ if (!swap_chain->CreateSwapChain() || !swap_chain->SetupSwapChainImages() || ++ !swap_chain->CreateSemaphores()) + return nullptr; + + return swap_chain; +@@ -237,6 +264,23 @@ bool SwapChain::SelectPresentMode() + return true; + } + ++bool SwapChain::CreateSemaphores() ++{ ++ static constexpr VkSemaphoreCreateInfo semaphore_create_info = { ++ VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0}; ++ for (VkSemaphore& semaphore : m_semaphores) ++ { ++ VkResult res = vkCreateSemaphore(g_vulkan_context->GetDevice(), &semaphore_create_info, nullptr, ++ &semaphore); ++ if (res != VK_SUCCESS) ++ { ++ LOG_VULKAN_ERROR(res, "vkCreateSemaphore failed: "); ++ return false; ++ } ++ } ++ return true; ++} ++ + bool SwapChain::CreateSwapChain() + { + // Look up surface properties to determine image count and dimensions +@@ -265,8 +309,8 @@ bool SwapChain::CreateSwapChain() + VkExtent2D size = surface_capabilities.currentExtent; + if (size.width == UINT32_MAX) + { +- size.width = std::max(g_renderer->GetBackbufferWidth(), 1); +- size.height = std::max(g_renderer->GetBackbufferHeight(), 1); ++ size.width = static_cast(m_wsi.render_surface_width); ++ size.height = static_cast(m_wsi.render_surface_height); + } + size.width = std::clamp(size.width, surface_capabilities.minImageExtent.width, + surface_capabilities.maxImageExtent.width); +@@ -452,20 +496,33 @@ void SwapChain::DestroySwapChain() + m_swap_chain = VK_NULL_HANDLE; + } + +-VkResult SwapChain::AcquireNextImage() ++void SwapChain::DestroySemaphores() + { +- VkResult res = vkAcquireNextImageKHR(g_vulkan_context->GetDevice(), m_swap_chain, UINT64_MAX, +- g_command_buffer_mgr->GetCurrentCommandBufferSemaphore(), +- VK_NULL_HANDLE, &m_current_swap_chain_image_index); ++ for (VkSemaphore semaphore : m_semaphores) ++ { ++ if (semaphore != VK_NULL_HANDLE) ++ { ++ vkDestroySemaphore(g_vulkan_context->GetDevice(), semaphore, nullptr); ++ } ++ } ++} ++ ++VkResult SwapChain::AcquireNextImage(VkSemaphore semaphore) ++{ ++ VkResult res = ++ vkAcquireNextImageKHR(g_vulkan_context->GetDevice(), m_swap_chain, UINT64_MAX, semaphore, ++ VK_NULL_HANDLE, &m_current_swap_chain_image_index); + if (res != VK_SUCCESS && res != VK_ERROR_OUT_OF_DATE_KHR && res != VK_SUBOPTIMAL_KHR) + LOG_VULKAN_ERROR(res, "vkAcquireNextImageKHR failed: "); + + return res; + } + +-bool SwapChain::ResizeSwapChain() ++bool SwapChain::ResizeSwapChain(int window_width, int window_height) + { + DestroySwapChainImages(); ++ m_wsi.render_surface_width = window_width; ++ m_wsi.render_surface_height = window_height; + if (!CreateSwapChain() || !SetupSwapChainImages()) + { + PanicAlertFmt("Failed to re-configure swap chain images, this is fatal (for now)"); +@@ -531,7 +588,7 @@ bool SwapChain::SetFullscreenState(bool + #endif + } + +-bool SwapChain::RecreateSurface(void* native_handle) ++bool SwapChain::RecreateSurface(void* native_handle, int window_width, int window_height) + { + // Destroy the old swap chain, images, and surface. + DestroySwapChainImages(); +@@ -540,6 +597,8 @@ bool SwapChain::RecreateSurface(void* na + + // Re-create the surface with the new native handle + m_wsi.render_surface = native_handle; ++ m_wsi.render_surface_width = window_width; ++ m_wsi.render_surface_height = window_height; + m_surface = CreateVulkanSurface(g_vulkan_context->GetVulkanInstance(), m_wsi); + if (m_surface == VK_NULL_HANDLE) + return false; +diff -rupN dolphin.orig/Source/Core/VideoBackends/Vulkan/VKSwapChain.h dolphin/Source/Core/VideoBackends/Vulkan/VKSwapChain.h +--- dolphin.orig/Source/Core/VideoBackends/Vulkan/VKSwapChain.h 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoBackends/Vulkan/VKSwapChain.h 2024-03-05 04:06:08.240295843 +0000 +@@ -3,6 +3,7 @@ + + #pragma once + ++#include + #include + #include + +@@ -50,10 +51,10 @@ public: + { + return m_swap_chain_images[m_current_swap_chain_image_index].framebuffer.get(); + } +- VkResult AcquireNextImage(); ++ VkResult AcquireNextImage(VkSemaphore semaphore); + +- bool RecreateSurface(void* native_handle); +- bool ResizeSwapChain(); ++ bool RecreateSurface(void* native_handle, int window_width, int window_height); ++ bool ResizeSwapChain(int window_width, int window_height); + bool RecreateSwapChain(); + + // Change vsync enabled state. This may fail as it causes a swapchain recreation. +@@ -70,10 +71,19 @@ public: + // Updates the fullscreen state. Must call on-thread. + bool SetFullscreenState(bool state); + ++ VkSemaphore GetNextSemaphore() ++ { ++ m_semaphore_index = (m_semaphore_index + 1) % NUM_COMMAND_BUFFERS; ++ return m_semaphores[m_semaphore_index]; ++ } ++ + private: + bool SelectSurfaceFormat(); + bool SelectPresentMode(); + ++ bool CreateSemaphores(); ++ void DestroySemaphores(); ++ + bool CreateSwapChain(); + void DestroySwapChain(); + +@@ -103,6 +113,9 @@ private: + std::vector m_swap_chain_images; + u32 m_current_swap_chain_image_index = 0; + ++ std::array m_semaphores = {}; ++ u32 m_semaphore_index = 0; ++ + u32 m_width = 0; + u32 m_height = 0; + u32 m_layers = 0; +diff -rupN dolphin.orig/Source/Core/VideoBackends/Vulkan/VKTexture.cpp dolphin/Source/Core/VideoBackends/Vulkan/VKTexture.cpp +--- dolphin.orig/Source/Core/VideoBackends/Vulkan/VKTexture.cpp 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoBackends/Vulkan/VKTexture.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -21,6 +21,7 @@ + #include "VideoBackends/Vulkan/VKStreamBuffer.h" + #include "VideoBackends/Vulkan/VulkanContext.h" + ++#include "VKScheduler.h" + #include "VideoCommon/DriverDetails.h" + #include "VideoCommon/VideoConfig.h" + +@@ -45,14 +46,17 @@ VKTexture::VKTexture(const TextureConfig + + VKTexture::~VKTexture() + { +- StateTracker::GetInstance()->UnbindTexture(m_view); +- g_command_buffer_mgr->DeferImageViewDestruction(m_view); ++ g_scheduler->Record([c_view = m_view, c_image = m_image, ++ c_alloc = m_alloc](CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->GetStateTracker()->UnbindTexture(c_view); ++ command_buffer_mgr->DeferImageViewDestruction(c_view); + +- // If we don't have device memory allocated, the image is not owned by us (e.g. swapchain) +- if (m_alloc != VK_NULL_HANDLE) +- { +- g_command_buffer_mgr->DeferImageDestruction(m_image, m_alloc); +- } ++ // If we don't have device memory allocated, the image is not owned by us (e.g. swapchain) ++ if (c_alloc != VK_NULL_HANDLE) ++ { ++ command_buffer_mgr->DeferImageDestruction(c_image, c_alloc); ++ } ++ }); + } + + std::unique_ptr VKTexture::Create(const TextureConfig& tex_config, std::string_view name) +@@ -265,30 +269,35 @@ void VKTexture::CopyRectangleFromTexture + static_cast(dst_rect.GetHeight()) <= m_config.height, + "Dest rect is too large for CopyRectangleFromTexture"); + +- const u32 copy_layer_count = 1; +- +- VkImageCopy image_copy = { +- {VK_IMAGE_ASPECT_COLOR_BIT, src_level, src_layer, copy_layer_count}, +- {src_rect.left, src_rect.top, 0}, +- {VK_IMAGE_ASPECT_COLOR_BIT, dst_level, dst_layer, copy_layer_count}, +- {dst_rect.left, dst_rect.top, 0}, +- {static_cast(src_rect.GetWidth()), static_cast(src_rect.GetHeight()), 1}}; +- +- // Must be called outside of a render pass. +- StateTracker::GetInstance()->EndRenderPass(); ++ g_scheduler->Record([](CommandBufferManager* command_buffer_mgr) { ++ // Must be called outside of a render pass. ++ command_buffer_mgr->GetStateTracker()->EndRenderPass(); ++ }); + + const VkImageLayout old_src_layout = src_texture->GetLayout(); +- src_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), +- VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); +- TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), +- VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); +- +- vkCmdCopyImage(g_command_buffer_mgr->GetCurrentCommandBuffer(), src_texture->m_image, +- VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_image, +- VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &image_copy); ++ src_texture->TransitionToLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); ++ TransitionToLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); ++ ++ g_scheduler->Record([c_src_image = src_texture->GetImage(), c_image = m_image, ++ c_src_level = src_level, c_src_layer = src_layer, ++ c_src_layers = src_texture->GetLayers(), c_src_rect = src_rect, ++ c_dst_level = dst_level, c_dst_layer = dst_layer, ++ c_dst_layers = m_config.layers, ++ c_dst_rect = dst_rect](CommandBufferManager* command_buffer_mgr) { ++ VkImageCopy image_copy = {{VK_IMAGE_ASPECT_COLOR_BIT, c_src_level, c_src_layer, c_src_layers}, ++ {c_src_rect.left, c_src_rect.top, 0}, ++ {VK_IMAGE_ASPECT_COLOR_BIT, c_dst_level, c_dst_layer, c_dst_layers}, ++ {c_dst_rect.left, c_dst_rect.top, 0}, ++ {static_cast(c_src_rect.GetWidth()), ++ static_cast(c_src_rect.GetHeight()), 1}}; ++ ++ vkCmdCopyImage(command_buffer_mgr->GetCurrentCommandBuffer(), c_src_image, ++ VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, c_image, ++ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &image_copy); ++ }); + + // Only restore the source layout. Destination is restored by FinishedRendering(). +- src_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), old_src_layout); ++ src_texture->TransitionToLayout(old_src_layout); + } + + void VKTexture::ResolveFromTexture(const AbstractTexture* src, const MathUtil::Rectangle& rect, +@@ -301,24 +310,28 @@ void VKTexture::ResolveFromTexture(const + rect.top + rect.GetHeight() <= static_cast(srcentry->m_config.height)); + + // Resolving is considered to be a transfer operation. +- StateTracker::GetInstance()->EndRenderPass(); ++ g_scheduler->Record([](CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->GetStateTracker()->EndRenderPass(); ++ }); + VkImageLayout old_src_layout = srcentry->m_layout; +- srcentry->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), +- VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); +- TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), +- VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); +- +- VkImageResolve resolve = { +- {VK_IMAGE_ASPECT_COLOR_BIT, level, layer, 1}, // srcSubresource +- {rect.left, rect.top, 0}, // srcOffset +- {VK_IMAGE_ASPECT_COLOR_BIT, level, layer, 1}, // dstSubresource +- {rect.left, rect.top, 0}, // dstOffset +- {static_cast(rect.GetWidth()), static_cast(rect.GetHeight()), 1} // extent +- }; +- vkCmdResolveImage(g_command_buffer_mgr->GetCurrentCommandBuffer(), srcentry->m_image, +- srcentry->m_layout, m_image, m_layout, 1, &resolve); ++ srcentry->TransitionToLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); ++ TransitionToLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + +- srcentry->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), old_src_layout); ++ g_scheduler->Record([c_src_image = srcentry->GetImage(), c_image = m_image, ++ c_src_layout = srcentry->GetLayout(), c_dst_layout = m_layout, c_rect = rect, ++ c_layer = layer, c_level = level](CommandBufferManager* command_buffer_mgr) { ++ VkImageResolve resolve = { ++ {VK_IMAGE_ASPECT_COLOR_BIT, c_level, c_layer, 1}, // srcSubresource ++ {c_rect.left, c_rect.top, 0}, // srcOffset ++ {VK_IMAGE_ASPECT_COLOR_BIT, c_level, c_layer, 1}, // dstSubresource ++ {c_rect.left, c_rect.top, 0}, // dstOffset ++ {static_cast(c_rect.GetWidth()), static_cast(c_rect.GetHeight()), 1} // extent ++ }; ++ vkCmdResolveImage(command_buffer_mgr->GetCurrentCommandBuffer(), c_src_image, c_src_layout, ++ c_image, c_dst_layout, 1, &resolve); ++ }); ++ ++ srcentry->TransitionToLayout(old_src_layout); + } + + void VKTexture::Load(u32 level, u32 width, u32 height, u32 row_length, const u8* buffer, +@@ -344,8 +357,7 @@ void VKTexture::Load(u32 level, u32 widt + // When the last mip level is uploaded, we transition to SHADER_READ_ONLY, ready for use. This is + // because we can't transition in a render pass, and we don't necessarily know when this texture + // is going to be used. +- TransitionToLayout(g_command_buffer_mgr->GetCurrentInitCommandBuffer(), +- VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); ++ TransitionToLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true); + + // For unaligned textures, we can save some memory in the transfer buffer by skipping the rows + // that lie outside of the texture's dimensions. +@@ -396,26 +408,30 @@ void VKTexture::Load(u32 level, u32 widt + temp_buffer->Unmap(); + } + +- // Copy from the streaming buffer to the actual image. +- VkBufferImageCopy image_copy = { +- upload_buffer_offset, // VkDeviceSize bufferOffset +- row_length, // uint32_t bufferRowLength +- 0, // uint32_t bufferImageHeight +- {VK_IMAGE_ASPECT_COLOR_BIT, level, layer, 1}, // VkImageSubresourceLayers imageSubresource +- {0, 0, 0}, // VkOffset3D imageOffset +- {width, height, 1} // VkExtent3D imageExtent +- }; +- vkCmdCopyBufferToImage(g_command_buffer_mgr->GetCurrentInitCommandBuffer(), upload_buffer, +- m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &image_copy); ++ g_scheduler->Record([c_upload_buffer_offset = upload_buffer_offset, c_row_length = row_length, ++ c_level = level, c_width = width, c_height = height, ++ c_upload_buffer = upload_buffer, ++ c_image = m_image](CommandBufferManager* command_buffer_mgr) { ++ // Copy from the streaming buffer to the actual image. ++ VkBufferImageCopy image_copy = { ++ c_upload_buffer_offset, // VkDeviceSize bufferOffset ++ c_row_length, // uint32_t bufferRowLength ++ 0, // uint32_t bufferImageHeight ++ {VK_IMAGE_ASPECT_COLOR_BIT, c_level, 0, 1}, // VkImageSubresourceLayers imageSubresource ++ {0, 0, 0}, // VkOffset3D imageOffset ++ {c_width, c_height, 1} // VkExtent3D imageExtent ++ }; ++ vkCmdCopyBufferToImage(command_buffer_mgr->GetCurrentInitCommandBuffer(), c_upload_buffer, ++ c_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &image_copy); ++ }); + + // Preemptively transition to shader read only after uploading the last mip level, as we're + // likely finished with writes to this texture for now. We can't do this in common with a + // FinishedRendering() call because the upload happens in the init command buffer, and we + // don't want to interrupt the render pass with calls which were executed ages before. +- if (level == (m_config.levels - 1) && layer == (m_config.layers - 1)) ++ if (level == (m_config.levels - 1)) + { +- TransitionToLayout(g_command_buffer_mgr->GetCurrentInitCommandBuffer(), +- VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); ++ TransitionToLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, true); + } + } + +@@ -424,9 +440,10 @@ void VKTexture::FinishedRendering() + if (m_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + return; + +- StateTracker::GetInstance()->EndRenderPass(); +- TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), +- VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); ++ g_scheduler->Record([](CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->GetStateTracker()->EndRenderPass(); ++ }); ++ TransitionToLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + } + + void VKTexture::OverrideImageLayout(VkImageLayout new_layout) +@@ -434,9 +451,9 @@ void VKTexture::OverrideImageLayout(VkIm + m_layout = new_layout; + } + +-void VKTexture::TransitionToLayout(VkCommandBuffer command_buffer, VkImageLayout new_layout) const ++void VKTexture::TransitionToLayout(VkImageLayout new_layout, bool init_command_buffer) const + { +- if (m_layout == new_layout) ++ if (m_layout == new_layout) [[likely]] + return; + + VkImageMemoryBarrier barrier = { +@@ -573,14 +590,19 @@ void VKTexture::TransitionToLayout(VkCom + } + m_compute_layout = ComputeImageLayout::Undefined; + +- vkCmdPipelineBarrier(command_buffer, srcStageMask, dstStageMask, 0, 0, nullptr, 0, nullptr, 1, +- &barrier); ++ g_scheduler->Record([c_src_stage_mask = srcStageMask, c_dst_stage_mask = dstStageMask, ++ c_barrier = barrier, ++ init_command_buffer](CommandBufferManager* command_buffer_mgr) { ++ vkCmdPipelineBarrier(init_command_buffer ? command_buffer_mgr->GetCurrentInitCommandBuffer() : ++ command_buffer_mgr->GetCurrentCommandBuffer(), ++ c_src_stage_mask, c_dst_stage_mask, 0, 0, nullptr, 0, nullptr, 1, ++ &c_barrier); ++ }); + + m_layout = new_layout; + } + +-void VKTexture::TransitionToLayout(VkCommandBuffer command_buffer, +- ComputeImageLayout new_layout) const ++void VKTexture::TransitionToLayout(ComputeImageLayout new_layout, bool init_command_buffer) const + { + ASSERT(new_layout != ComputeImageLayout::Undefined); + if (m_compute_layout == new_layout) +@@ -678,8 +700,14 @@ void VKTexture::TransitionToLayout(VkCom + m_layout = barrier.newLayout; + m_compute_layout = new_layout; + +- vkCmdPipelineBarrier(command_buffer, srcStageMask, dstStageMask, 0, 0, nullptr, 0, nullptr, 1, +- &barrier); ++ g_scheduler->Record([c_src_stage_mask = srcStageMask, c_dst_stage_mask = dstStageMask, ++ c_barrier = barrier, ++ init_command_buffer](CommandBufferManager* command_buffer_mgr) { ++ vkCmdPipelineBarrier(init_command_buffer ? command_buffer_mgr->GetCurrentInitCommandBuffer() : ++ command_buffer_mgr->GetCurrentCommandBuffer(), ++ c_src_stage_mask, c_dst_stage_mask, 0, 0, nullptr, 0, nullptr, 1, ++ &c_barrier); ++ }); + } + + VKStagingTexture::VKStagingTexture(PrivateTag, StagingTextureType type, const TextureConfig& config, +@@ -694,7 +722,11 @@ VKStagingTexture::~VKStagingTexture() + { + if (m_linear_image != VK_NULL_HANDLE) + { +- g_command_buffer_mgr->DeferImageDestruction(m_linear_image, m_linear_image_alloc); ++ g_scheduler->Record( ++ [c_linear_image = m_linear_image, ++ c_linear_image_alloc = m_linear_image_alloc](CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->DeferImageDestruction(c_linear_image, c_linear_image_alloc); ++ }); + } + } + +@@ -816,12 +848,12 @@ void VKStagingTexture::CopyFromTexture(c + src_rect.top >= 0 && static_cast(src_rect.bottom) <= src_tex->GetHeight()); + ASSERT(dst_rect.left >= 0 && static_cast(dst_rect.right) <= m_config.width && + dst_rect.top >= 0 && static_cast(dst_rect.bottom) <= m_config.height); +- +- StateTracker::GetInstance()->EndRenderPass(); ++ g_scheduler->Record([](CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->GetStateTracker()->EndRenderPass(); ++ }); + + VkImageLayout old_layout = src_tex->GetLayout(); +- src_tex->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), +- VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); ++ src_tex->TransitionToLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + + // Issue the image->buffer copy, but delay it for now. + VkBufferImageCopy image_copy = {}; +@@ -844,15 +876,17 @@ void VKStagingTexture::CopyFromTexture(c + image_copy.imageOffset = {0, 0, 0}; + } + +- vkCmdCopyImageToBuffer(g_command_buffer_mgr->GetCurrentCommandBuffer(), src_image, +- VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_staging_buffer->GetBuffer(), 1, +- &image_copy); ++ g_scheduler->Record([c_src_image = src_image, c_dst_buffer = m_staging_buffer->GetBuffer(), ++ c_image_copy = image_copy](CommandBufferManager* command_buffer_mgr) { ++ vkCmdCopyImageToBuffer(command_buffer_mgr->GetCurrentCommandBuffer(), c_src_image, ++ VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, c_dst_buffer, 1, &c_image_copy); ++ }); + + // Restore old source texture layout. +- src_tex->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), old_layout); ++ src_tex->TransitionToLayout(old_layout); + + m_needs_flush = true; +- m_flush_fence_counter = g_command_buffer_mgr->GetCurrentFenceCounter(); ++ m_flush_fence_counter = g_scheduler->GetCurrentFenceCounter(); + } + + void VKStagingTexture::CopyFromTextureToLinearImage(const VKTexture* src_tex, +@@ -864,44 +898,49 @@ void VKStagingTexture::CopyFromTextureTo + // with optimal tiling (VK_IMAGE_TILING_OPTIMAL) to a buffer. + // That allocation is very slow, so we just do it ourself and reuse the intermediate image. + +- const VkImageAspectFlags aspect = VKTexture::GetImageViewAspectForFormat(src_tex->GetFormat()); +- +- VkImageMemoryBarrier linear_image_barrier = {}; +- linear_image_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; +- linear_image_barrier.pNext = nullptr; +- linear_image_barrier.srcAccessMask = 0; +- linear_image_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_TRANSFER_READ_BIT; +- linear_image_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; +- linear_image_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; +- linear_image_barrier.image = m_linear_image; +- linear_image_barrier.subresourceRange = {aspect, 0, 1, 0, 1}; +- vkCmdPipelineBarrier(g_command_buffer_mgr->GetCurrentCommandBuffer(), +- VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, +- nullptr, 0, nullptr, 1, &linear_image_barrier); +- +- VkImageBlit blit; +- blit.srcSubresource = {aspect, src_level, src_layer, 1}; +- blit.dstSubresource.layerCount = 1; +- blit.dstSubresource.baseArrayLayer = 0; +- blit.dstSubresource.mipLevel = 0; +- blit.dstSubresource.aspectMask = linear_image_barrier.subresourceRange.aspectMask; +- blit.srcOffsets[0] = {src_rect.left, src_rect.top, 0}; +- blit.srcOffsets[1] = {static_cast(blit.srcOffsets[0].x + src_rect.GetWidth()), +- static_cast(blit.srcOffsets[0].y + src_rect.GetHeight()), 1}; +- blit.dstOffsets[0] = {0, 0, 0}; +- blit.dstOffsets[1] = {dst_rect.GetWidth(), dst_rect.GetHeight(), 1u}; +- +- vkCmdBlitImage(g_command_buffer_mgr->GetCurrentCommandBuffer(), src_tex->GetImage(), +- VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_linear_image, +- VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit, VK_FILTER_NEAREST); +- +- linear_image_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; +- linear_image_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; +- linear_image_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; +- +- vkCmdPipelineBarrier(g_command_buffer_mgr->GetCurrentCommandBuffer(), +- VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, +- nullptr, 0, nullptr, 1, &linear_image_barrier); ++ g_scheduler->Record([c_linear_image = m_linear_image, c_src_image = src_tex->GetImage(), ++ c_src_format = src_tex->GetFormat(), c_src_rect = src_rect, ++ c_dst_rect = dst_rect, c_src_layer = src_layer, ++ c_src_level = src_level](CommandBufferManager* command_buffer_mgr) { ++ const VkImageAspectFlags aspect = VKTexture::GetImageViewAspectForFormat(c_src_format); ++ ++ VkImageMemoryBarrier linear_image_barrier = {}; ++ linear_image_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; ++ linear_image_barrier.pNext = nullptr; ++ linear_image_barrier.srcAccessMask = 0; ++ linear_image_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_TRANSFER_READ_BIT; ++ linear_image_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; ++ linear_image_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; ++ linear_image_barrier.image = c_linear_image; ++ linear_image_barrier.subresourceRange = {aspect, 0, 1, 0, 1}; ++ vkCmdPipelineBarrier(command_buffer_mgr->GetCurrentCommandBuffer(), ++ VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, ++ nullptr, 0, nullptr, 1, &linear_image_barrier); ++ ++ VkImageBlit blit; ++ blit.srcSubresource = {aspect, c_src_level, c_src_layer, 1}; ++ blit.dstSubresource.layerCount = 1; ++ blit.dstSubresource.baseArrayLayer = 0; ++ blit.dstSubresource.mipLevel = 0; ++ blit.dstSubresource.aspectMask = linear_image_barrier.subresourceRange.aspectMask; ++ blit.srcOffsets[0] = {c_src_rect.left, c_src_rect.top, 0}; ++ blit.srcOffsets[1] = {static_cast(blit.srcOffsets[0].x + c_src_rect.GetWidth()), ++ static_cast(blit.srcOffsets[0].y + c_src_rect.GetHeight()), 1}; ++ blit.dstOffsets[0] = {0, 0, 0}; ++ blit.dstOffsets[1] = {c_dst_rect.GetWidth(), c_dst_rect.GetHeight(), 1u}; ++ ++ vkCmdBlitImage(command_buffer_mgr->GetCurrentCommandBuffer(), c_src_image, ++ VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, c_linear_image, ++ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit, VK_FILTER_NEAREST); ++ ++ linear_image_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; ++ linear_image_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; ++ linear_image_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; ++ ++ vkCmdPipelineBarrier(command_buffer_mgr->GetCurrentCommandBuffer(), ++ VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, ++ nullptr, 0, nullptr, 1, &linear_image_barrier); ++ }); + } + + void VKStagingTexture::CopyToTexture(const MathUtil::Rectangle& src_rect, AbstractTexture* dst, +@@ -919,32 +958,40 @@ void VKStagingTexture::CopyToTexture(con + + // Flush caches before copying. + m_staging_buffer->FlushCPUCache(); +- StateTracker::GetInstance()->EndRenderPass(); ++ ++ g_scheduler->Record([](CommandBufferManager* command_buffer_manager) { ++ command_buffer_manager->GetStateTracker()->EndRenderPass(); ++ }); + + VkImageLayout old_layout = dst_tex->GetLayout(); +- dst_tex->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), +- VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); ++ dst_tex->TransitionToLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + +- // Issue the image->buffer copy, but delay it for now. +- VkBufferImageCopy image_copy = {}; +- image_copy.bufferOffset = +- static_cast(static_cast(src_rect.top) * m_config.GetStride() + +- static_cast(src_rect.left) * m_texel_size); +- image_copy.bufferRowLength = static_cast(m_config.width); +- image_copy.bufferImageHeight = 0; +- image_copy.imageSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, dst_level, dst_layer, 1}; +- image_copy.imageOffset = {dst_rect.left, dst_rect.top, 0}; +- image_copy.imageExtent = {static_cast(dst_rect.GetWidth()), +- static_cast(dst_rect.GetHeight()), 1u}; +- vkCmdCopyBufferToImage(g_command_buffer_mgr->GetCurrentCommandBuffer(), +- m_staging_buffer->GetBuffer(), dst_tex->GetImage(), +- VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &image_copy); ++ g_scheduler->Record( ++ [c_src_rect = src_rect, c_dst_rect = dst_rect, c_dst_layer = dst_layer, ++ c_dst_level = dst_level, c_width = m_config.width, c_height = m_config.height, ++ c_stride = m_config.GetStride(), c_texel_size = m_texel_size, ++ c_staging_buffer = m_staging_buffer->GetBuffer(), ++ c_dst_image = dst_tex->GetImage()](CommandBufferManager* command_buffer_mgr) { ++ // Issue the image->buffer copy, but delay it for now. ++ VkBufferImageCopy image_copy = {}; ++ image_copy.bufferOffset = ++ static_cast(static_cast(c_src_rect.top) * c_stride + ++ static_cast(c_src_rect.left) * c_texel_size); ++ image_copy.bufferRowLength = static_cast(c_width); ++ image_copy.bufferImageHeight = 0; ++ image_copy.imageSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, c_dst_level, c_dst_layer, 1}; ++ image_copy.imageOffset = {c_dst_rect.left, c_dst_rect.top, 0}; ++ image_copy.imageExtent = {static_cast(c_dst_rect.GetWidth()), ++ static_cast(c_dst_rect.GetHeight()), 1u}; ++ vkCmdCopyBufferToImage(command_buffer_mgr->GetCurrentCommandBuffer(), c_staging_buffer, ++ c_dst_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &image_copy); ++ }); + + // Restore old source texture layout. +- dst_tex->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), old_layout); ++ dst_tex->TransitionToLayout(old_layout); + + m_needs_flush = true; +- m_flush_fence_counter = g_command_buffer_mgr->GetCurrentFenceCounter(); ++ m_flush_fence_counter = g_scheduler->GetCurrentFenceCounter(); + } + + bool VKStagingTexture::Map() +@@ -964,7 +1011,7 @@ void VKStagingTexture::Flush() + return; + + // Is this copy in the current command buffer? +- if (g_command_buffer_mgr->GetCurrentFenceCounter() == m_flush_fence_counter) ++ if (g_scheduler->GetCurrentFenceCounter() == m_flush_fence_counter) + { + // Execute the command buffer and wait for it to finish. + Renderer::GetInstance()->ExecuteCommandBuffer(false, true); +@@ -972,7 +1019,7 @@ void VKStagingTexture::Flush() + else + { + // Wait for the GPU to finish with it. +- g_command_buffer_mgr->WaitForFenceCounter(m_flush_fence_counter); ++ g_scheduler->WaitForFenceCounter(m_flush_fence_counter); + } + + // For readback textures, invalidate the CPU cache as there is new data there. +@@ -998,7 +1045,11 @@ VKFramebuffer::VKFramebuffer(VKTexture* + + VKFramebuffer::~VKFramebuffer() + { +- g_command_buffer_mgr->DeferFramebufferDestruction(m_fb); ++ g_scheduler->SyncWorker(); // TODO ++ ++ g_scheduler->Record([c_fb = m_fb](CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->DeferFramebufferDestruction(c_fb); ++ }); + } + + std::unique_ptr VKFramebuffer::Create(VKTexture* color_attachment, +@@ -1067,15 +1118,13 @@ void VKFramebuffer::TransitionForRender( + if (m_color_attachment) + { + static_cast(m_color_attachment) +- ->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), +- VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); ++ ->TransitionToLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + } + + if (m_depth_attachment) + { + static_cast(m_depth_attachment) +- ->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), +- VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); ++ ->TransitionToLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); + } + } + } // namespace Vulkan +diff -rupN dolphin.orig/Source/Core/VideoBackends/Vulkan/VKTexture.h dolphin/Source/Core/VideoBackends/Vulkan/VKTexture.h +--- dolphin.orig/Source/Core/VideoBackends/Vulkan/VKTexture.h 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoBackends/Vulkan/VKTexture.h 2024-03-05 04:06:08.240295843 +0000 +@@ -67,8 +67,8 @@ public: + // irrelevant and will not be loaded. + void OverrideImageLayout(VkImageLayout new_layout); + +- void TransitionToLayout(VkCommandBuffer command_buffer, VkImageLayout new_layout) const; +- void TransitionToLayout(VkCommandBuffer command_buffer, ComputeImageLayout new_layout) const; ++ void TransitionToLayout(VkImageLayout new_layout, bool init_command_buffer = false) const; ++ void TransitionToLayout(ComputeImageLayout new_layout, bool init_command_buffer = false) const; + + private: + bool CreateView(VkImageViewType type); +diff -rupN dolphin.orig/Source/Core/VideoBackends/Vulkan/VKVertexManager.cpp dolphin/Source/Core/VideoBackends/Vulkan/VKVertexManager.cpp +--- dolphin.orig/Source/Core/VideoBackends/Vulkan/VKVertexManager.cpp 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoBackends/Vulkan/VKVertexManager.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -15,6 +15,7 @@ + #include "VideoBackends/Vulkan/CommandBufferManager.h" + #include "VideoBackends/Vulkan/StateTracker.h" + #include "VideoBackends/Vulkan/VKRenderer.h" ++#include "VideoBackends/Vulkan/VKScheduler.h" + #include "VideoBackends/Vulkan/VKStreamBuffer.h" + #include "VideoBackends/Vulkan/VKVertexFormat.h" + #include "VideoBackends/Vulkan/VulkanContext.h" +@@ -67,11 +68,11 @@ bool VertexManager::Initialize() + + m_vertex_stream_buffer = + StreamBuffer::Create(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, +- VERTEX_STREAM_BUFFER_SIZE); ++ VERTEX_STREAM_BUFFER_SIZE * 2); + m_index_stream_buffer = +- StreamBuffer::Create(VK_BUFFER_USAGE_INDEX_BUFFER_BIT, INDEX_STREAM_BUFFER_SIZE); ++ StreamBuffer::Create(VK_BUFFER_USAGE_INDEX_BUFFER_BIT, INDEX_STREAM_BUFFER_SIZE * 2); + m_uniform_stream_buffer = +- StreamBuffer::Create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, UNIFORM_STREAM_BUFFER_SIZE); ++ StreamBuffer::Create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, UNIFORM_STREAM_BUFFER_SIZE * 2); + if (!m_vertex_stream_buffer || !m_index_stream_buffer || !m_uniform_stream_buffer) + { + PanicAlertFmt("Failed to allocate streaming buffers"); +@@ -121,13 +122,18 @@ bool VertexManager::Initialize() + + // Bind the buffers to all the known spots even if it's not used, to keep the driver happy. + UploadAllConstants(); +- StateTracker::GetInstance()->SetUtilityUniformBuffer(m_uniform_stream_buffer->GetBuffer(), 0, +- sizeof(VertexShaderConstants)); +- for (u32 i = 0; i < NUM_COMPUTE_TEXEL_BUFFERS; i++) +- { +- StateTracker::GetInstance()->SetTexelBuffer(i, +- m_texel_buffer_views[TEXEL_BUFFER_FORMAT_R8_UINT]); +- } ++ ++ g_scheduler->Record([c_buffer = m_uniform_stream_buffer->GetBuffer(), ++ c_texel_buffer_view = m_texel_buffer_views[TEXEL_BUFFER_FORMAT_R8_UINT]]( ++ CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->GetStateTracker()->SetUtilityUniformBuffer(c_buffer, 0, ++ sizeof(VertexShaderConstants)); ++ ++ for (u32 i = 0; i < NUM_COMPUTE_TEXEL_BUFFERS; i++) ++ { ++ command_buffer_mgr->GetStateTracker()->SetTexelBuffer(i, c_texel_buffer_view); ++ } ++ }); + + return true; + } +@@ -189,10 +195,13 @@ void VertexManager::CommitBuffer(u32 num + ADDSTAT(g_stats.this_frame.bytes_vertex_streamed, static_cast(vertex_data_size)); + ADDSTAT(g_stats.this_frame.bytes_index_streamed, static_cast(index_data_size)); + +- StateTracker::GetInstance()->SetVertexBuffer(m_vertex_stream_buffer->GetBuffer(), 0, +- VERTEX_STREAM_BUFFER_SIZE); +- StateTracker::GetInstance()->SetIndexBuffer(m_index_stream_buffer->GetBuffer(), 0, +- VK_INDEX_TYPE_UINT16); ++ g_scheduler->Record([c_vertex_buffer = m_vertex_stream_buffer->GetBuffer(), ++ c_index_buffer = m_index_stream_buffer->GetBuffer()]( ++ CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->GetStateTracker()->SetVertexBuffer(c_vertex_buffer, 0, ++ VERTEX_STREAM_BUFFER_SIZE); ++ command_buffer_mgr->GetStateTracker()->SetIndexBuffer(c_index_buffer, 0, VK_INDEX_TYPE_UINT16); ++ }); + } + + void VertexManager::UploadUniforms() +@@ -210,9 +219,12 @@ void VertexManager::UpdateVertexShaderCo + if (!vertex_shader_manager.dirty || !ReserveConstantStorage()) + return; + +- StateTracker::GetInstance()->SetGXUniformBuffer( +- UBO_DESCRIPTOR_SET_BINDING_VS, m_uniform_stream_buffer->GetBuffer(), +- m_uniform_stream_buffer->GetCurrentOffset(), sizeof(VertexShaderConstants)); ++ g_scheduler->Record([c_buffer = m_uniform_stream_buffer->GetBuffer(), ++ c_offset = m_uniform_stream_buffer->GetCurrentOffset()]( ++ CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->GetStateTracker()->SetGXUniformBuffer( ++ UBO_DESCRIPTOR_SET_BINDING_VS, c_buffer, c_offset, sizeof(VertexShaderConstants)); ++ }); + std::memcpy(m_uniform_stream_buffer->GetCurrentHostPointer(), &vertex_shader_manager.constants, + sizeof(VertexShaderConstants)); + m_uniform_stream_buffer->CommitMemory(sizeof(VertexShaderConstants)); +@@ -228,9 +240,13 @@ void VertexManager::UpdateGeometryShader + if (!geometry_shader_manager.dirty || !ReserveConstantStorage()) + return; + +- StateTracker::GetInstance()->SetGXUniformBuffer( +- UBO_DESCRIPTOR_SET_BINDING_GS, m_uniform_stream_buffer->GetBuffer(), +- m_uniform_stream_buffer->GetCurrentOffset(), sizeof(GeometryShaderConstants)); ++ g_scheduler->Record([c_buffer = m_uniform_stream_buffer->GetBuffer(), ++ c_offset = m_uniform_stream_buffer->GetCurrentOffset()]( ++ CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->GetStateTracker()->SetGXUniformBuffer( ++ UBO_DESCRIPTOR_SET_BINDING_GS, c_buffer, c_offset, sizeof(GeometryShaderConstants)); ++ }); ++ + std::memcpy(m_uniform_stream_buffer->GetCurrentHostPointer(), &geometry_shader_manager.constants, + sizeof(GeometryShaderConstants)); + m_uniform_stream_buffer->CommitMemory(sizeof(GeometryShaderConstants)); +@@ -246,9 +262,13 @@ void VertexManager::UpdatePixelShaderCon + if (!pixel_shader_manager.dirty || !ReserveConstantStorage()) + return; + +- StateTracker::GetInstance()->SetGXUniformBuffer( +- UBO_DESCRIPTOR_SET_BINDING_PS, m_uniform_stream_buffer->GetBuffer(), +- m_uniform_stream_buffer->GetCurrentOffset(), sizeof(PixelShaderConstants)); ++ g_scheduler->Record([c_buffer = m_uniform_stream_buffer->GetBuffer(), ++ c_offset = m_uniform_stream_buffer->GetCurrentOffset()]( ++ CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->GetStateTracker()->SetGXUniformBuffer( ++ UBO_DESCRIPTOR_SET_BINDING_PS, c_buffer, c_offset, sizeof(PixelShaderConstants)); ++ }); ++ + std::memcpy(m_uniform_stream_buffer->GetCurrentHostPointer(), &pixel_shader_manager.constants, + sizeof(PixelShaderConstants)); + m_uniform_stream_buffer->CommitMemory(sizeof(PixelShaderConstants)); +@@ -299,18 +319,21 @@ void VertexManager::UploadAllConstants() + auto& geometry_shader_manager = system.GetGeometryShaderManager(); + + // Update bindings +- StateTracker::GetInstance()->SetGXUniformBuffer( +- UBO_DESCRIPTOR_SET_BINDING_PS, m_uniform_stream_buffer->GetBuffer(), +- m_uniform_stream_buffer->GetCurrentOffset() + pixel_constants_offset, +- sizeof(PixelShaderConstants)); +- StateTracker::GetInstance()->SetGXUniformBuffer( +- UBO_DESCRIPTOR_SET_BINDING_VS, m_uniform_stream_buffer->GetBuffer(), +- m_uniform_stream_buffer->GetCurrentOffset() + vertex_constants_offset, +- sizeof(VertexShaderConstants)); +- StateTracker::GetInstance()->SetGXUniformBuffer( +- UBO_DESCRIPTOR_SET_BINDING_GS, m_uniform_stream_buffer->GetBuffer(), +- m_uniform_stream_buffer->GetCurrentOffset() + geometry_constants_offset, +- sizeof(GeometryShaderConstants)); ++ g_scheduler->Record( ++ [c_buffer = m_uniform_stream_buffer->GetBuffer(), ++ c_ps_offset = m_uniform_stream_buffer->GetCurrentOffset() + pixel_constants_offset, ++ c_vs_offset = m_uniform_stream_buffer->GetCurrentOffset() + vertex_constants_offset, ++ c_gs_offset = m_uniform_stream_buffer->GetCurrentOffset() + ++ geometry_constants_offset](CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->GetStateTracker()->SetGXUniformBuffer( ++ UBO_DESCRIPTOR_SET_BINDING_PS, c_buffer, c_ps_offset, sizeof(PixelShaderConstants)); ++ ++ command_buffer_mgr->GetStateTracker()->SetGXUniformBuffer( ++ UBO_DESCRIPTOR_SET_BINDING_VS, c_buffer, c_vs_offset, sizeof(VertexShaderConstants)); ++ ++ command_buffer_mgr->GetStateTracker()->SetGXUniformBuffer( ++ UBO_DESCRIPTOR_SET_BINDING_VS, c_buffer, c_gs_offset, sizeof(GeometryShaderConstants)); ++ }); + + // Copy the actual data in + std::memcpy(m_uniform_stream_buffer->GetCurrentHostPointer() + pixel_constants_offset, +@@ -340,8 +363,11 @@ void VertexManager::UploadUtilityUniform + Renderer::GetInstance()->ExecuteCommandBuffer(false); + } + +- StateTracker::GetInstance()->SetUtilityUniformBuffer( +- m_uniform_stream_buffer->GetBuffer(), m_uniform_stream_buffer->GetCurrentOffset(), data_size); ++ g_scheduler->Record([c_buffer = m_uniform_stream_buffer->GetBuffer(), ++ c_offset = m_uniform_stream_buffer->GetCurrentOffset(), ++ c_size = data_size](CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->GetStateTracker()->SetUtilityUniformBuffer(c_buffer, c_offset, c_size); ++ }); + std::memcpy(m_uniform_stream_buffer->GetCurrentHostPointer(), data, data_size); + m_uniform_stream_buffer->CommitMemory(data_size); + ADDSTAT(g_stats.this_frame.bytes_uniform_streamed, data_size); +@@ -370,7 +396,10 @@ bool VertexManager::UploadTexelBuffer(co + *out_offset = static_cast(m_texel_stream_buffer->GetCurrentOffset()) / elem_size; + m_texel_stream_buffer->CommitMemory(data_size); + ADDSTAT(g_stats.this_frame.bytes_uniform_streamed, data_size); +- StateTracker::GetInstance()->SetTexelBuffer(0, m_texel_buffer_views[format]); ++ g_scheduler->Record([c_texel_buffer_view = ++ m_texel_buffer_views[format]](CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->GetStateTracker()->SetTexelBuffer(0, c_texel_buffer_view); ++ }); + return true; + } + +@@ -407,8 +436,13 @@ bool VertexManager::UploadTexelBuffer(co + + m_texel_stream_buffer->CommitMemory(palette_byte_offset + palette_size); + ADDSTAT(g_stats.this_frame.bytes_uniform_streamed, palette_byte_offset + palette_size); +- StateTracker::GetInstance()->SetTexelBuffer(0, m_texel_buffer_views[format]); +- StateTracker::GetInstance()->SetTexelBuffer(1, m_texel_buffer_views[palette_format]); ++ ++ g_scheduler->Record([c_texel_buffer_view = m_texel_buffer_views[format], ++ c_palette_texel_buffer_view = m_texel_buffer_views[palette_format]]( ++ CommandBufferManager* command_buffer_mgr) { ++ command_buffer_mgr->GetStateTracker()->SetTexelBuffer(0, c_texel_buffer_view); ++ command_buffer_mgr->GetStateTracker()->SetTexelBuffer(1, c_palette_texel_buffer_view); ++ }); + return true; + } + } // namespace Vulkan +diff -rupN dolphin.orig/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp dolphin/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp +--- dolphin.orig/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -274,6 +274,13 @@ bool VulkanContext::SelectInstanceExtens + return false; + } + #endif ++#if defined(VK_USE_PLATFORM_WAYLAND_KHR) ++ if (wstype == WindowSystemType::Wayland && ++ !AddExtension(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, true)) ++ { ++ return false; ++ } ++#endif + #if defined(VK_USE_PLATFORM_ANDROID_KHR) + if (wstype == WindowSystemType::Android && + !AddExtension(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, true)) +diff -rupN dolphin.orig/Source/Core/VideoBackends/Vulkan/VulkanEntryPoints.inl dolphin/Source/Core/VideoBackends/Vulkan/VulkanEntryPoints.inl +--- dolphin.orig/Source/Core/VideoBackends/Vulkan/VulkanEntryPoints.inl 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoBackends/Vulkan/VulkanEntryPoints.inl 2024-03-05 04:06:08.240295843 +0000 +@@ -49,6 +49,11 @@ VULKAN_INSTANCE_ENTRY_POINT(vkCreateXlib + VULKAN_INSTANCE_ENTRY_POINT(vkGetPhysicalDeviceXlibPresentationSupportKHR, false) + #endif + ++#if defined(VK_USE_PLATFORM_WAYLAND_KHR) ++VULKAN_INSTANCE_ENTRY_POINT(vkCreateWaylandSurfaceKHR, false) ++VULKAN_INSTANCE_ENTRY_POINT(vkGetPhysicalDeviceWaylandPresentationSupportKHR, false) ++#endif ++ + #if defined(VK_USE_PLATFORM_ANDROID_KHR) + VULKAN_INSTANCE_ENTRY_POINT(vkCreateAndroidSurfaceKHR, false) + #endif +diff -rupN dolphin.orig/Source/Core/VideoBackends/Vulkan/VulkanLoader.h dolphin/Source/Core/VideoBackends/Vulkan/VulkanLoader.h +--- dolphin.orig/Source/Core/VideoBackends/Vulkan/VulkanLoader.h 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoBackends/Vulkan/VulkanLoader.h 2024-03-05 04:06:08.240295843 +0000 +@@ -13,6 +13,10 @@ + #define VK_USE_PLATFORM_XLIB_KHR + #endif + ++#if defined(HAVE_WAYLAND) ++#define VK_USE_PLATFORM_WAYLAND_KHR ++#endif ++ + #if defined(ANDROID) + #define VK_USE_PLATFORM_ANDROID_KHR + #endif +diff -rupN dolphin.orig/Source/Core/VideoCommon/FramebufferManager.cpp dolphin/Source/Core/VideoCommon/FramebufferManager.cpp +--- dolphin.orig/Source/Core/VideoCommon/FramebufferManager.cpp 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoCommon/FramebufferManager.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -630,7 +630,7 @@ void FramebufferManager::DestroyReadback + + bool FramebufferManager::CreateReadbackFramebuffer() + { +- if (g_renderer->GetEFBScale() != 1) ++ if (g_renderer->IsUnscaled()) + { + const TextureConfig color_config(IsUsingTiledEFBCache() ? m_efb_cache_tile_size : EFB_WIDTH, + IsUsingTiledEFBCache() ? m_efb_cache_tile_size : EFB_HEIGHT, 1, +@@ -651,7 +651,7 @@ bool FramebufferManager::CreateReadbackF + (IsUsingTiledEFBCache() && !g_ActiveConfig.backend_info.bSupportsPartialDepthCopies) || + !AbstractTexture::IsCompatibleDepthAndColorFormats(m_efb_depth_texture->GetFormat(), + GetEFBDepthCopyFormat()) || +- g_renderer->GetEFBScale() != 1) ++ g_renderer->IsUnscaled()) + { + const TextureConfig depth_config(IsUsingTiledEFBCache() ? m_efb_cache_tile_size : EFB_WIDTH, + IsUsingTiledEFBCache() ? m_efb_cache_tile_size : EFB_HEIGHT, 1, +@@ -731,7 +731,7 @@ void FramebufferManager::PopulateEFBCach + const MathUtil::Rectangle native_rect = g_renderer->ConvertEFBRectangle(rect); + AbstractTexture* src_texture = + depth ? ResolveEFBDepthTexture(native_rect) : ResolveEFBColorTexture(native_rect); +- if (g_renderer->GetEFBScale() != 1 || force_intermediate_copy) ++ if (g_renderer->IsUnscaled() || force_intermediate_copy) + { + // Downsample from internal resolution to 1x. + // TODO: This won't produce correct results at IRs above 2x. More samples are required. +@@ -918,7 +918,7 @@ void FramebufferManager::CreatePokeVerti + // GPU will expand the point to a quad. + const float cs_x = (static_cast(x) + 0.5f) * cs_pixel_width - 1.0f; + const float cs_y = 1.0f - (static_cast(y) + 0.5f) * cs_pixel_height; +- const float point_size = static_cast(g_renderer->GetEFBScale()); ++ const float point_size = g_renderer->GetEFBScalef(); + destination_list->push_back({{cs_x, cs_y, z, point_size}, color}); + return; + } +diff -rupN dolphin.orig/Source/Core/VideoCommon/RenderBase.cpp dolphin/Source/Core/VideoCommon/RenderBase.cpp +--- dolphin.orig/Source/Core/VideoCommon/RenderBase.cpp 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoCommon/RenderBase.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -364,19 +364,24 @@ void Renderer::RenderToXFB(u32 xfbAddr, + return; + } + +-unsigned int Renderer::GetEFBScale() const ++bool Renderer::IsUnscaled() const + { +- return m_efb_scale; ++ return m_efb_scale == 2; ++} ++ ++float Renderer::GetEFBScalef() const ++{ ++ return m_efb_scale / 2.0f; + } + + int Renderer::EFBToScaledX(int x) const + { +- return x * static_cast(m_efb_scale); ++ return x * static_cast(m_efb_scale) / 2; + } + + int Renderer::EFBToScaledY(int y) const + { +- return y * static_cast(m_efb_scale); ++ return y * static_cast(m_efb_scale) / 2; + } + + float Renderer::EFBToScaledXf(float x) const +@@ -391,7 +396,7 @@ float Renderer::EFBToScaledYf(float y) c + + std::tuple Renderer::CalculateTargetScale(int x, int y) const + { +- return std::make_tuple(x * static_cast(m_efb_scale), y * static_cast(m_efb_scale)); ++ return std::make_tuple(x * static_cast(m_efb_scale) / 2, y * static_cast(m_efb_scale) / 2); + } + + // return true if target size changed +@@ -711,16 +716,20 @@ bool Renderer::IsHeadless() const + return true; + } + +-void Renderer::ChangeSurface(void* new_surface_handle) ++void Renderer::ChangeSurface(void* new_surface_handle, int new_width, int new_height) + { + std::lock_guard lock(m_swap_mutex); + m_new_surface_handle = new_surface_handle; ++ m_new_surface_width = new_width; ++ m_new_surface_height = new_height; + m_surface_changed.Set(); + } + +-void Renderer::ResizeSurface() ++void Renderer::ResizeSurface(int new_width, int new_height) + { + std::lock_guard lock(m_swap_mutex); ++ m_new_surface_width = new_width; ++ m_new_surface_height = new_height; + m_surface_resized.Set(); + } + +diff -rupN dolphin.orig/Source/Core/VideoCommon/RenderBase.h dolphin/Source/Core/VideoCommon/RenderBase.h +--- dolphin.orig/Source/Core/VideoCommon/RenderBase.h 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoCommon/RenderBase.h 2024-03-05 04:06:08.240295843 +0000 +@@ -193,7 +193,8 @@ public: + std::tuple, MathUtil::Rectangle> + ConvertStereoRectangle(const MathUtil::Rectangle& rc) const; + +- unsigned int GetEFBScale() const; ++ bool IsUnscaled() const; ++ float GetEFBScalef() const; + + // Use this to upscale native EFB coordinates to IDEAL internal resolution + int EFBToScaledX(int x) const; +@@ -246,8 +247,8 @@ public: + VideoCommon::PostProcessing* GetPostProcessor() const { return m_post_processor.get(); } + // Final surface changing + // This is called when the surface is resized (WX) or the window changes (Android). +- void ChangeSurface(void* new_surface_handle); +- void ResizeSurface(); ++ void ChangeSurface(void* new_surface_handle, int new_width, int new_height); ++ void ResizeSurface(int new_width, int new_height); + bool UseVertexDepthRange() const; + void DoState(PointerWrap& p); + +@@ -342,6 +343,8 @@ protected: + std::unique_ptr m_post_processor; + + void* m_new_surface_handle = nullptr; ++ int m_new_surface_width = 0; ++ int m_new_surface_height = 0; + Common::Flag m_surface_changed; + Common::Flag m_surface_resized; + std::mutex m_swap_mutex; +@@ -357,7 +360,8 @@ private: + std::tuple CalculateOutputDimensions(int width, int height) const; + + PixelFormat m_prev_efb_format = PixelFormat::INVALID_FMT; +- unsigned int m_efb_scale = 1; ++ // Scale in steps of 0.5x. Value of 2 is scale of 1 (unscaled). ++ unsigned int m_efb_scale = 2; + + // These will be set on the first call to SetWindowSize. + int m_last_window_request_width = 0; +diff -rupN dolphin.orig/Source/Core/VideoCommon/TextureCacheBase.cpp dolphin/Source/Core/VideoCommon/TextureCacheBase.cpp +--- dolphin.orig/Source/Core/VideoCommon/TextureCacheBase.cpp 2024-03-05 04:05:26.602983293 +0000 ++++ dolphin/Source/Core/VideoCommon/TextureCacheBase.cpp 2024-03-05 04:06:08.240295843 +0000 +@@ -1046,7 +1046,7 @@ static void SetSamplerState(u32 index, f + // that have arbitrary contents, eg. are used for fog effects where the + // distance they kick in at is important to preserve at any resolution. + // Correct this with the upscaling factor of custom textures. +- s32 lod_offset = std::log2(g_renderer->GetEFBScale() / custom_tex_scale) * 256.f; ++ s64 lod_offset = std::log2(g_renderer->GetEFBScalef() / custom_tex_scale) * (s64) 256.f; + state.tm0.lod_bias = std::clamp(state.tm0.lod_bias + lod_offset, -32768, 32767); + + // Anisotropic also pushes mips farther away so it cannot be used either +@@ -2221,7 +2221,7 @@ void TextureCacheBase::CopyRenderTargetT + // TODO: This only produces perfect downsampling for 2x IR, other resolutions will need more + // complex down filtering to average all pixels and produce the correct result. + const bool linear_filter = +- !is_depth_copy && (scaleByHalf || g_renderer->GetEFBScale() != 1 || y_scale > 1.0f); ++ !is_depth_copy && (scaleByHalf || g_renderer->IsUnscaled() || y_scale > 1.0f); + + TCacheEntry* entry = nullptr; + if (copy_to_vram) diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/wayland/001-padorder.patch b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/wayland/001-padorder.patch new file mode 100644 index 0000000000..187a57efca --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/wayland/001-padorder.patch @@ -0,0 +1,111 @@ +diff --git a/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp b/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp +index 6df37b4..64ade4a 100644 +--- a/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp ++++ b/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp +@@ -392,6 +392,65 @@ void Init() + StartHotplugThread(); + } + ++struct joypad_udev_entry ++{ ++ const char *devnode; ++ struct udev_device *dev; ++}; ++ ++int isNumber(const char *s) { ++ int n; ++ ++ if(strlen(s) == 0) { ++ return 0; ++ } ++ ++ for(n=0; ndevnode, bb->devnode); ++} ++ + // Only call this when ControllerInterface::m_devices_population_mutex is locked + void PopulateDevices() + { +@@ -404,6 +463,10 @@ void PopulateDevices() + // We use udev to iterate over all /dev/input/event* devices. + // Note: the Linux kernel is currently limited to just 32 event devices. If + // this ever changes, hopefully udev will take care of this. ++ unsigned sorted_count = 0; ++ struct joypad_udev_entry sorted[64]; ++ const char* devnode; ++ int i; + + udev* const udev = udev_new(); + ASSERT_MSG(CONTROLLERINTERFACE, udev != nullptr, "Couldn't initialize libudev."); +@@ -422,11 +485,25 @@ void PopulateDevices() + + udev_device* dev = udev_device_new_from_syspath(udev, path); + +- if (const char* devnode = udev_device_get_devnode(dev)) +- AddDeviceNode(devnode); +- +- udev_device_unref(dev); ++ devnode = udev_device_get_devnode(dev); ++ if (devnode != NULL && sorted_count < 64) { ++ sorted[sorted_count].devnode = devnode; ++ sorted[sorted_count].dev = dev; ++ sorted_count++; ++ } else { ++ udev_device_unref(dev); ++ } + } ++ ++ /* Sort the udev entries by devnode name so that they are ++ * created in the proper order */ ++ qsort(sorted, sorted_count, sizeof(struct joypad_udev_entry), sort_devnodes); ++ ++ for (i = 0; i < sorted_count; i++) { ++ AddDeviceNode(sorted[i].devnode); ++ udev_device_unref(sorted[i].dev); ++ } ++ + udev_enumerate_unref(enumerate); + udev_unref(udev); + } diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/wayland/002-fix-bba.patch b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/wayland/002-fix-bba.patch new file mode 100644 index 0000000000..b9fb92b1cb --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/wayland/002-fix-bba.patch @@ -0,0 +1,46 @@ +From beebe0a2000826de66c911344c7efca4872262ff Mon Sep 17 00:00:00 2001 +From: "Admiral H. Curtiss" +Date: Wed, 4 Oct 2023 16:13:16 +0200 +Subject: [PATCH] Core/BBA/BuiltIn: Replace IP_PROTOCOL with IPV4_ETHERTYPE to + avoid conflict with Linux headers. + +--- + Source/Core/Core/HW/EXI/BBA/BuiltIn.cpp | 3 ++- + Source/Core/Core/HW/EXI/BBA/BuiltIn.h | 3 --- + 2 files changed, 2 insertions(+), 4 deletions(-) + +diff --git a/Source/Core/Core/HW/EXI/BBA/BuiltIn.cpp b/Source/Core/Core/HW/EXI/BBA/BuiltIn.cpp +index 6e5c3eac9749..4782a0a8b0a7 100644 +--- a/Source/Core/Core/HW/EXI/BBA/BuiltIn.cpp ++++ b/Source/Core/Core/HW/EXI/BBA/BuiltIn.cpp +@@ -13,6 +13,7 @@ + #include "Common/BitUtils.h" + #include "Common/Logging/Log.h" + #include "Common/MsgHandler.h" ++#include "Common/Network.h" + #include "Common/ScopeGuard.h" + #include "Core/HW/EXI/EXI_Device.h" + #include "Core/HW/EXI/EXI_DeviceEthernet.h" +@@ -746,7 +747,7 @@ void CEXIETHERNET::BuiltInBBAInterface::ReadThreadHandler(CEXIETHERNET::BuiltInB + u8* buffer = reinterpret_cast(self->m_eth_ref->mRecvBuffer.get()); + Common::PacketView packet(buffer, datasize); + const auto packet_type = packet.GetEtherType(); +- if (packet_type.has_value() && packet_type == IP_PROTOCOL) ++ if (packet_type.has_value() && packet_type == Common::IPV4_ETHERTYPE) + { + SetIPIdentification(buffer, datasize, ++self->m_ip_frame_id); + } +diff --git a/Source/Core/Core/HW/EXI/BBA/BuiltIn.h b/Source/Core/Core/HW/EXI/BBA/BuiltIn.h +index 4478f4de48da..afcf39d2931b 100644 +--- a/Source/Core/Core/HW/EXI/BBA/BuiltIn.h ++++ b/Source/Core/Core/HW/EXI/BBA/BuiltIn.h +@@ -20,9 +20,6 @@ constexpr u16 TCP_FLAG_PSH = 0x8; + constexpr u16 TCP_FLAG_FIN = 0x1; + constexpr u16 TCP_FLAG_RST = 0x4; + +-constexpr u16 IP_PROTOCOL = 0x800; +-constexpr u16 ARP_PROTOCOL = 0x806; +- + constexpr u8 MAX_TCP_BUFFER = 4; + constexpr u16 MAX_UDP_LENGTH = 1500; + constexpr u16 MAX_TCP_LENGTH = 440; diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/wayland/004-git.patch b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/wayland/004-git.patch new file mode 100644 index 0000000000..cbc4b582d1 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/wayland/004-git.patch @@ -0,0 +1,13 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index eb0f83f..9d41166 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -128,7 +128,7 @@ endif() + include(CCache) + + # for revision info +-find_package(Git) ++#find_package(Git) + if(GIT_FOUND) + # make sure version information gets re-run when the current Git HEAD changes + execute_process(WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND ${GIT_EXECUTABLE} rev-parse --git-path HEAD diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/wayland/005-hide-osd-msg.patch b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/wayland/005-hide-osd-msg.patch new file mode 100644 index 0000000000..5005309837 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/wayland/005-hide-osd-msg.patch @@ -0,0 +1,13 @@ +--- a/Source/Core/VideoBackends/OGL/OGLRender.cpp 2020-12-31 00:27:53.998709857 +0100 ++++ b/Source/Core/VideoBackends/OGL/OGLRender.cpp 2020-12-31 00:28:40.414557344 +0100 +@@ -736,10 +736,6 @@ + g_Config.VerifyValidity(); + UpdateActiveConfig(); + +- OSD::AddMessage(fmt::format("Video Info: {}, {}, {}", g_ogl_config.gl_vendor, +- g_ogl_config.gl_renderer, g_ogl_config.gl_version), +- 5000); +- + if (!g_ogl_config.bSupportsGLBufferStorage && !g_ogl_config.bSupportsGLPinnedMemory) + { + OSD::AddMessage(fmt::format("Your OpenGL driver does not support {}_buffer_storage.", diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/wayland/008-bios-dir.patch b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/wayland/008-bios-dir.patch new file mode 100644 index 0000000000..d9be1c4668 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/patches/wayland/008-bios-dir.patch @@ -0,0 +1,35 @@ +diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp +index b21d15478..5b62db919 100644 +--- a/Source/Core/Core/Boot/Boot.cpp ++++ b/Source/Core/Core/Boot/Boot.cpp +@@ -423,7 +423,7 @@ bool CBoot::Load_BS2(Core::System& system, const std::string& boot_rom_filename) + known_ipl = true; + break; + default: +- PanicAlertFmtT("The IPL file is not a known good dump. (CRC32: {0:x})", ipl_hash); ++ known_ipl = true; + break; + } + +@@ -598,7 +598,7 @@ bool CBoot::BootUp(Core::System& system, std::unique_ptr boot) + if (!File::Exists(ipl.path)) + { + if (ipl.disc) +- PanicAlertFmtT("Cannot start the game, because the GC IPL could not be found."); ++ PanicAlertFmtT("Gamecube bios not found, please add your IPL.bin to /storage/roms/bios/GC/(USA/JAP/EUR)/."); + else + PanicAlertFmtT("Cannot find the GC IPL."); + return false; +diff --git a/Source/Core/Core/Config/MainSettings.cpp b/Source/Core/Core/Config/MainSettings.cpp +index 0442347fdd..af148e79f9 100644 +--- a/Source/Core/Core/Config/MainSettings.cpp ++++ b/Source/Core/Core/Config/MainSettings.cpp +@@ -616,7 +616,7 @@ const char* GetDirectoryForRegion(DiscIO::Region region, RegionDirectoryStyle st + std::string GetBootROMPath(const std::string& region_directory) + { + const std::string path = +- File::GetUserPath(D_GCUSER_IDX) + DIR_SEP + region_directory + DIR_SEP GC_IPL; ++ std::string("/storage/roms/bios/GC/") + DIR_SEP + region_directory + DIR_SEP + GC_IPL; + if (!File::Exists(path)) + return File::GetSysDirectory() + GC_SYS_DIR + DIR_SEP + region_directory + DIR_SEP GC_IPL; + return path; diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/scripts/cheevos_dolphin.sh b/projects/ArchR/packages/emulators/standalone/dolphin-sa/scripts/cheevos_dolphin.sh new file mode 100644 index 0000000000..5a99e38251 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/scripts/cheevos_dolphin.sh @@ -0,0 +1,66 @@ +#! /bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile + +LOG_FILE="/var/log/cheevos.log" + +# Extract username, password, token, if enabled, and hardcore mode from system.cfg +username=$(get_setting "global.retroachievements.username") +password=$(get_setting "global.retroachievements.password") +token=$(get_setting "global.retroachievements.token") +enabled=$(get_setting "global.retroachievements") +hardcore=$(get_setting "global.retroachievements.hardcore") +encore=$(get_setting "global.retroachievements.encore") +unofficial=$(get_setting "global.retroachievements.testunofficial") + +# Check if RetroAchievements are enabled in Emulation Station +if [ "${enabled}" = 1 ]; then + enabled="True" +else + echo "RetroAchievements are not enabled, please turn them on in Emulation Station." > ${LOG_FILE} + enabled="False" + exit 1 +fi + +# Check if api token is present in system.cfg +if [ -z "${token}" ]; then + echo "RetroAchievements token is empty, please log in with your RetroAchievements credentials in Emulation Station." > ${LOG_FILE} + exit 1 +fi + +# Set hardcore mode +if [ "${hardcore}" = 1 ]; then + hardcore="True" +else + hardcore="False" +fi + +# Set encore mode +if [ "${encore}" = 1 ]; then + encore="True" +else + encore="False" +fi + +# Set unofficial mode +if [ "${unofficial}" = 1 ]; then + unofficial="True" +else + unofficial="False" +fi + +cat </storage/.config/dolphin-emu/RetroAchievements.ini +[Achievements] +DiscordPresenceEnabled = False +Enabled = ${enabled} +EncoreEnabled = ${encore} +HardcoreEnabled = ${hardcore} +ProgressEnabled = False +SpectatorEnabled = False +UnofficialEnabled = ${unofficial} +Username = ${username} +ApiToken = ${token} +EOF diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/scripts/start_dolphin_gc.sh b/projects/ArchR/packages/emulators/standalone/dolphin-sa/scripts/start_dolphin_gc.sh new file mode 100644 index 0000000000..ac5ca417bb --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/scripts/start_dolphin_gc.sh @@ -0,0 +1,429 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile + +# Detect version of Dolphin +DOLPHIN_CORE=$(echo "${3}"| sed "s#^/.*/##") +if [ "${DOLPHIN_CORE}" = 'dolphin-qt-gc' ]; then + DOLPHIN_CORE="dolphin-emu" +else + DOLPHIN_CORE="dolphin-emu-nogui" +fi + +set_kill set "-9 ${DOLPHIN_CORE}" + +# Load gptokeyb support files +control-gen_init.sh +source /storage/.config/gptokeyb/control.ini +get_controls + +# Conf files vars +CONF_DIR="/storage/.config/dolphin-emu" +DOLPHIN_INI="Dolphin.ini" +GFX_INI="GFX.ini" +CONTROLLER_INI="GCPadNew.ini" + +# Check if dolphin-emu exists in .config +if [ ! -d "${CONF_DIR}" ]; then + cp -r "/usr/config/dolphin-emu" "/storage/.config/" +fi + +# Check if Hotkeys.ini exists +if [ "${DOLPHIN_CORE}" = 'dolphin-emu' ]; then + if [ ! -f "${CONF_DIR}/Hotkeys.ini" ]; then + cp -r "/usr/config/dolphin-emu/Hotkeys.ini" "${CONF_DIR}/" + fi +fi + +# Check if GC controller dir exists in .config/dolphin-emu/GamecubeControllerProfiles +if [ ! -d "${CONF_DIR}/GamecubeControllerProfiles" ]; then + cp -r "/usr/config/dolphin-emu/GamecubeControllerProfiles" "${CONF_DIR}/" +fi + +# Check if GC custom east profile exists in .config/dolphin-emu/GamecubeControllerProfiles +if [ ! -f "${CONF_DIR}/GamecubeControllerProfiles/GCPadNew.ini.east" ]; then + cp -r "/usr/config/dolphin-emu/GamecubeControllerProfiles/GCPadNew.ini.east" "${CONF_DIR}/GamecubeControllerProfiles/GCPadNew.ini.east" +fi + +# Check if GC custom controller profile exists in .config/dolphin-emu/GamecubeControllerProfiles +if [ ! -f "${CONF_DIR}/GamecubeControllerProfiles/GCPadNew.ini.custom" ]; then + cp -r "/usr/config/dolphin-emu/GamecubeControllerProfiles/GCPadNew.ini.south" "${CONF_DIR}/GamecubeControllerProfiles/GCPadNew.ini.custom" +fi + +# Link Save States to /roms/savestates/gamecube +if [ ! -d "/storage/roms/savestates/gamecube/" ]; then + mkdir -p "/storage/roms/savestates/gamecube/" +fi + +rm -rf ${CONF_DIR}/StateSaves +ln -sf /storage/roms/savestates/gamecube ${CONF_DIR}/StateSaves + +# Copy bios, memory cards and other system stuff to roms +if [ ! -d "/storage/roms/bios/GC/" ]; then + mkdir -p /storage/roms/bios/GC/{USA,JAP,EUR} + cp -r ${CONF_DIR}/GC /storage/roms/bios/ +fi + +# Create Triforce Bios folder if does not exist +if [ ! -d "/storage/roms/bios/GC/Triforce" ]; then + mkdir -p /storage/roms/bios/GC/Triforce + cp -r ${CONF_DIR}/GC/Triforce /storage/roms/bios/GC/ +fi + +# Make sure all Triforce Gecko codes are copied to GameSettings +for f in /usr/config/dolphin-emu/triforce_gecko_codes/*; do + [ -e "/storage/.config/dolphin-emu/GameSettings/$(basename "$f")" ] || cp -fH "$f" "/storage/.config/dolphin-emu/GameSettings/" +done +rm -rf "/storage/.config/dolphin-emu/triforce_gecko_codes" + +# Link bios and memory cards to roms +for REGION in EUR JAP USA +do + # Link bios + rm -rf "${CONF_DIR}/GC/${REGION}" + ln -sf "/storage/roms/bios/GC/${REGION}" "${CONF_DIR}/GC/${REGION}" + + # Link memory cards, copying to roms/bios first as needed + for SLOT in A B + do + MEM_CARD_FILE="MemoryCard${SLOT}.${REGION}.raw" + CONFIG_MEM_CARD="${CONF_DIR}/GC/${MEM_CARD_FILE}" + ROMS_BIOS_MEM_CARD="/storage/roms/bios/GC/${MEM_CARD_FILE}" + + if [ -f "${ROMS_BIOS_MEM_CARD}" ]; then + # Exists in roms/bios, remove from .config and link + rm -f "${CONFIG_MEM_CARD}" + ln -sf "${ROMS_BIOS_MEM_CARD}" "${CONFIG_MEM_CARD}" + elif [ -f "${CONFIG_MEM_CARD}" ]; then + # Only exists in .config, move to roms/bios and link + mv -f "${CONFIG_MEM_CARD}" "${ROMS_BIOS_MEM_CARD}" + ln -sf "${ROMS_BIOS_MEM_CARD}" "${CONFIG_MEM_CARD}" + fi + done +done + +# Emulation Station Features +GAME=$(echo "${1}"| sed "s#^/.*/##") +PLATFORM=$(echo "${2}"| sed "s#^/.*/##") +AA=$(get_setting anti_aliasing "${PLATFORM}" "${GAME}") +ASPECT=$(get_setting aspect_ratio "${PLATFORM}" "${GAME}") +AUDIOBE=$(get_setting audio_backend "${PLATFORM}" "${GAME}") +ASWAPDISCS=$(get_setting auto_swap_discs "${PLATFORM}" "${GAME}") +CLOCK=$(get_setting clock_speed "${PLATFORM}" "${GAME}") +ENBCHEATS=$(get_setting enable_cheats "${PLATFORM}" "${GAME}") +GRENDERER=$(get_setting graphics_backend "${PLATFORM}" "${GAME}") +IRES=$(get_setting internal_resolution "${PLATFORM}" "${GAME}") +FPS=$(get_setting show_fps "${PLATFORM}" "${GAME}") +CON=$(get_setting gamecube_controller_profile "${PLATFORM}" "${GAME}") +HKEY=$(get_setting hotkey_enable_button "${PLATFORM}" "${GAME}") +SAVETYPE=$(get_setting save_type "${PLATFORM}" "${GAME}") +SAVEREG=$(get_setting save_gci_region "${PLATFORM}" "${GAME}") +SHADERM=$(get_setting shader_mode "${PLATFORM}" "${GAME}") +SHADERP=$(get_setting shader_precompile "${PLATFORM}" "${GAME}") +VSYNC=$(get_setting vsync "${PLATFORM}" "${GAME}") +SKIPBIOS=$(get_setting use_bios "${PLATFORM}" "${GAME}") +EFBACCESS=$(get_setting skip_efb_cpu_access "${PLATFORM}" "${GAME}") +EFBTEXTURE=$(get_setting store_efb_to_texture_only "${PLATFORM}" "${GAME}") +XFBTEXTURE=$(get_setting store_xfb_to_texture_only "${PLATFORM}" "${GAME}") +TEXTURE_CACHE_ACCURACY=$(get_setting texture_cache_accuracy "${PLATFORM}" "${GAME}") +RUMBLE=$(get_setting rumble "${PLATFORM}" "${GAME}") +WHACK=$(get_setting widescreen_hack "${PLATFORM}" "${GAME}") +WPC=$(get_setting write_protect_configs "${PLATFORM}" "${GAME}") + +# Grab clean config files during boot, unless disabled in emulationstation +if [ "$WPC" != "false" ]; then + cp -r /usr/config/dolphin-emu/GFX.ini ${CONF_DIR}/${GFX_INI} + cp -r /usr/config/dolphin-emu/Dolphin.ini ${CONF_DIR}/${DOLPHIN_INI} +fi + +# Set the cores to use +CORES=$(get_setting "cores" "${PLATFORM}" "${GAME}") +if [ "${CORES}" = "little" ] +then + EMUPERF="${SLOW_CORES}" +elif [ "${CORES}" = "big" ] +then + EMUPERF="${FAST_CORES}" +else + ### All.. + unset EMUPERF +fi + +### Emulation Station features: + # Anti-Aliasing + if [ "$AA" = "2m" ]; then + sed -i '/MSAA/c\MSAA = 2' ${CONF_DIR}/${GFX_INI} + sed -i '/SSAA/c\SSAA = False' ${CONF_DIR}/${GFX_INI} + elif [ "$AA" = "2s" ]; then + sed -i '/MSAA/c\MSAA = 2' ${CONF_DIR}/${GFX_INI} + sed -i '/SSAA/c\SSAA = True' ${CONF_DIR}/${GFX_INI} + elif [ "$AA" = "4m" ]; then + sed -i '/MSAA/c\MSAA = 4' ${CONF_DIR}/${GFX_INI} + sed -i '/SSAA/c\SSAA = False' ${CONF_DIR}/${GFX_INI} + elif [ "$AA" = "4s" ]; then + sed -i '/MSAA/c\MSAA = 4' ${CONF_DIR}/${GFX_INI} + sed -i '/SSAA/c\SSAA = True' ${CONF_DIR}/${GFX_INI} + elif [ "$AA" = "8m" ]; then + sed -i '/MSAA/c\MSAA = 8' ${CONF_DIR}/${GFX_INI} + sed -i '/SSAA/c\SSAA = False' ${CONF_DIR}/${GFX_INI} + elif [ "$AA" = "8s" ]; then + sed -i '/MSAA/c\MSAA = 8' ${CONF_DIR}/${GFX_INI} + sed -i '/SSAA/c\SSAA = True' ${CONF_DIR}/${GFX_INI} + else + sed -i '/MSAA/c\MSAA = 0' ${CONF_DIR}/${GFX_INI} + sed -i '/SSAA/c\SSAA = False' ${CONF_DIR}/${GFX_INI} + fi + + # Aspect Ratio + if [ "$ASPECT" = "1" ]; then + sed -i '/AspectRatio/c\AspectRatio = 1' ${CONF_DIR}/${GFX_INI} + elif [ "$ASPECT" = "2" ]; then + sed -i '/AspectRatio/c\AspectRatio = 2' ${CONF_DIR}/${GFX_INI} + elif [ "$ASPECT" = "3" ]; then + sed -i '/AspectRatio/c\AspectRatio = 3' ${CONF_DIR}/${GFX_INI} + else + sed -i '/AspectRatio/c\AspectRatio = 0' ${CONF_DIR}/${GFX_INI} + fi + + # Audio Backend + if [ "$AUDIOBE" = "lle" ]; then + AUDIO_BACKEND="LLE" + else + AUDIO_BACKEND="HLE" + fi + + # Auto Swap Discs + if [ "$ASWAPDISCS" = "0" ]; then + sed -i '/AutoDiscChange/c\AutoDiscChange = False' ${CONF_DIR}/${DOLPHIN_INI} + else + sed -i '/AutoDiscChange/c\AutoDiscChange = True' ${CONF_DIR}/${DOLPHIN_INI} + fi + + # Clock Speed + if [ "$CLOCK" = "050" ]; then + sed -i '/^Overclock =/c\Overclock = 0.5' ${CONF_DIR}/${DOLPHIN_INI} + sed -i '/^OverclockEnable =/c\OverclockEnable = True' ${CONF_DIR}/${DOLPHIN_INI} + elif [ "$CLOCK" = "075" ]; then + sed -i '/^Overclock =/c\Overclock = 0.75' ${CONF_DIR}/${DOLPHIN_INI} + sed -i '/^OverclockEnable =/c\OverclockEnable = True' ${CONF_DIR}/${DOLPHIN_INI} + elif [ "$CLOCK" = "100" ]; then + sed -i '/^Overclock =/c\Overclock = 1.0' ${CONF_DIR}/${DOLPHIN_INI} + sed -i '/^OverclockEnable =/c\OverclockEnable = False' ${CONF_DIR}/${DOLPHIN_INI} + elif [ "$CLOCK" = "125" ]; then + sed -i '/^Overclock =/c\Overclock = 1.25' ${CONF_DIR}/${DOLPHIN_INI} + sed -i '/^OverclockEnable =/c\OverclockEnable = True' ${CONF_DIR}/${DOLPHIN_INI} + elif [ "$CLOCK" = "150" ]; then + sed -i '/^Overclock =/c\Overclock = 1.5' ${CONF_DIR}/${DOLPHIN_INI} + sed -i '/^OverclockEnable =/c\OverclockEnable = True' ${CONF_DIR}/${DOLPHIN_INI} + elif [ "$CLOCK" = "200" ]; then + sed -i '/^Overclock =/c\Overclock = 2.0' ${CONF_DIR}/${DOLPHIN_INI} + sed -i '/^OverclockEnable =/c\OverclockEnable = True' ${CONF_DIR}/${DOLPHIN_INI} + elif [ "$CLOCK" = "300" ]; then + sed -i '/^Overclock =/c\Overclock = 3.0' ${CONF_DIR}/${DOLPHIN_INI} + sed -i '/^OverclockEnable =/c\OverclockEnable = True' ${CONF_DIR}/${DOLPHIN_INI} + elif [ "$CLOCK" = "400" ]; then + sed -i '/^Overclock =/c\Overclock = 4.0' ${CONF_DIR}/${DOLPHIN_INI} + sed -i '/^OverclockEnable =/c\OverclockEnable = True' ${CONF_DIR}/${DOLPHIN_INI} + else + sed -i '/^OverclockEnable =/c\OverclockEnable = False' ${CONF_DIR}/${DOLPHIN_INI} + fi + + # Enable Cheats + if [ "$ENBCHEATS" = "1" ]; then + sed -i '/EnableCheats/c\EnableCheats = True' ${CONF_DIR}/${DOLPHIN_INI} + else + sed -i '/EnableCheats/c\EnableCheats = False' ${CONF_DIR}/${DOLPHIN_INI} + fi + + # Graphics Backend + if [ "$GRENDERER" = "vulkan" ]; then + sed -i '/GFXBackend/c\GFXBackend = Vulkan' ${CONF_DIR}/${DOLPHIN_INI} + elif [ "$GRENDERER" = "opengl" ]; then + sed -i '/GFXBackend/c\GFXBackend = OGL' ${CONF_DIR}/${DOLPHIN_INI} + else + sed -i '/GFXBackend/c\GFXBackend = @GRENDERER@' ${CONF_DIR}/${DOLPHIN_INI} + fi + + # Internal Resolution + if [ "$IRES" = "1" ]; then + sed -i '/InternalResolution/c\InternalResolution = 1' ${CONF_DIR}/${GFX_INI} + elif [ "$IRES" = "3" ]; then + sed -i '/InternalResolution/c\InternalResolution = 3' ${CONF_DIR}/${GFX_INI} + elif [ "$IRES" = "4" ]; then + sed -i '/InternalResolution/c\InternalResolution = 4' ${CONF_DIR}/${GFX_INI} + elif [ "$IRES" = "6" ]; then + sed -i '/InternalResolution/c\InternalResolution = 6' ${CONF_DIR}/${GFX_INI} + else + sed -i '/InternalResolution/c\InternalResolution = 2' ${CONF_DIR}/${GFX_INI} + fi + + # Save Type + if [ "$SAVETYPE" = "8" ]; then + sed -i '/SlotA/c\SlotA = 8' ${CONF_DIR}/${DOLPHIN_INI} + else + sed -i '/SlotA/c\SlotA = 1' ${CONF_DIR}/${DOLPHIN_INI} + fi + + # Save Reg + if [ "$SAVEREG" = "eur" ]; then + sed -i '/GCIFolderAPath/c\GCIFolderAPath = \/storage\/roms\/bios\/GC\/EUR' ${CONF_DIR}/${DOLPHIN_INI} + elif [ "$SAVEREG" = "jap" ]; then + sed -i '/GCIFolderAPath/c\GCIFolderAPath = \/storage\/roms\/bios\/GC\/JAP' ${CONF_DIR}/${DOLPHIN_INI} + else + sed -i '/GCIFolderAPath/c\GCIFolderAPath = \/storage\/roms\/bios\/GC\/USA' ${CONF_DIR}/${DOLPHIN_INI} + fi + + # Shader Mode + if [ "$SHADERM" = "0" ]; then + sed -i '/ShaderCompilationMode =/c\ShaderCompilationMode = 0' ${CONF_DIR}/${GFX_INI} + elif [ "$SHADERM" = "1" ]; then + sed -i '/ShaderCompilationMode =/c\ShaderCompilationMode = 1' ${CONF_DIR}/${GFX_INI} + elif [ "$SHADERM" = "2" ]; then + sed -i '/ShaderCompilationMode =/c\ShaderCompilationMode = 2' ${CONF_DIR}/${GFX_INI} + elif [ "$SHADERM" = "3" ]; then + sed -i '/ShaderCompilationMode =/c\ShaderCompilationMode = 3' ${CONF_DIR}/${GFX_INI} + fi + + #Shader Precompile + if [ "$SHADERP" = "false" ]; then + sed -i '/WaitForShadersBeforeStarting =/c\WaitForShadersBeforeStarting = False' ${CONF_DIR}/${GFX_INI} + elif [ "$SHADERP" = "true" ]; then + sed -i '/WaitForShadersBeforeStarting =/c\WaitForShadersBeforeStarting = True' ${CONF_DIR}/${GFX_INI} + fi + + # Show FPS + if [ "$FPS" = "true" ]; then + sed -i '/ShowFPS/c\ShowFPS = True' ${CONF_DIR}/${GFX_INI} + else + sed -i '/ShowFPS/c\ShowFPS = False' ${CONF_DIR}/${GFX_INI} + fi + + # Skip Bios + if [ "$SKIPBIOS" = "false" ]; then + sed -i '/SkipIPL/c\SkipIPL = False' ${CONF_DIR}/${DOLPHIN_INI} + else + sed -i '/SkipIPL/c\SkipIPL = True' ${CONF_DIR}/${DOLPHIN_INI} + fi + + # Skip EFB CPU Access + if [ "$EFBACCESS" = "false" ]; then + sed -i '/EFBAccessEnable =/c\EFBAccessEnable = False' ${CONF_DIR}/${GFX_INI} + else + sed -i '/EFBAccessEnable =/c\EFBAccessEnable = True' ${CONF_DIR}/${GFX_INI} + fi + + # Store EFB to texture only + if [ "$EFBTEXTURE" = "false" ]; then + sed -i '/EFBToTextureEnable =/c\EFBToTextureEnable = False' ${CONF_DIR}/${GFX_INI} + else + sed -i '/EFBToTextureEnable =/c\EFBToTextureEnable = True' ${CONF_DIR}/${GFX_INI} + fi + + # Store XFB to texture only + if [ "$XFBTEXTURE" = "false" ]; then + sed -i '/XFBToTextureEnable =/c\XFBToTextureEnable = False' ${CONF_DIR}/${GFX_INI} + else + sed -i '/XFBToTextureEnable =/c\XFBToTextureEnable = True' ${CONF_DIR}/${GFX_INI} + fi + + # Texture cache accuracy + if [ "$TEXTURE_CACHE_ACCURACY" = "0" ]; then + sed -i '/SafeTextureCacheColorSamples =/c\SafeTextureCacheColorSamples = 0' ${CONF_DIR}/${GFX_INI} + elif [ "$TEXTURE_CACHE_ACCURACY" = "512" ]; then + sed -i '/SafeTextureCacheColorSamples =/c\SafeTextureCacheColorSamples = 512' ${CONF_DIR}/${GFX_INI} + else + # Default to 128 = fast + sed -i '/SafeTextureCacheColorSamples =/c\SafeTextureCacheColorSamples = 128' ${CONF_DIR}/${GFX_INI} + fi + + # Widescreen Hack + if [ "$WHACK" = "true" ]; then + sed -i '/wideScreenHack =/c\wideScreenHack = True' ${CONF_DIR}/${GFX_INI} + else + sed -i '/wideScreenHack =/c\wideScreenHack = False' ${CONF_DIR}/${GFX_INI} + fi + + # GC Controller Profile + if [ "$CON" = "east" ]; then + cp -r ${CONF_DIR}/GamecubeControllerProfiles/GCPadNew.ini.east ${CONF_DIR}/${CONTROLLER_INI} + elif [ "$CON" = "custom" ]; then + cp -r ${CONF_DIR}/GamecubeControllerProfiles/GCPadNew.ini.custom ${CONF_DIR}/${CONTROLLER_INI} + else + cp -r ${CONF_DIR}/GamecubeControllerProfiles/GCPadNew.ini.south ${CONF_DIR}/${CONTROLLER_INI} + fi + + # GC Controller Rumble + if [ "$RUMBLE" = "false" ]; then + sed -i '/^Rumble/d' ${CONF_DIR}/${CONTROLLER_INI} + fi + + # GC Controller Hotkey Enable + if [ "$HKEY" = "mode" ]; then + sed -i '/^Buttons\/Hotkey =/c\Buttons\/Hotkey = Button 8' ${CONF_DIR}/${CONTROLLER_INI} + else + sed -i '/^Buttons\/Hotkey =/c\Buttons\/Hotkey = Button 6' ${CONF_DIR}/${CONTROLLER_INI} + fi + + # Vsync + if [ "$VSYNC" = "1" ]; then + sed -i '/VSync =/c\VSync = True' ${CONF_DIR}/${GFX_INI} + else + sed -i '/VSync =/c\VSync = False' ${CONF_DIR}/${GFX_INI} + fi + +# Link .config/dolphin-emu to .local +rm -rf /storage/.local/share/dolphin-emu +ln -sf /storage/.config/dolphin-emu /storage/.local/share/dolphin-emu + +@EXPORTS@ + +# Retroachievements + /usr/bin/cheevos_dolphin.sh + +# Set video and audio backend + CMD="${CMD} -v $GRENDERER" + +if [ ${DOLPHIN_CORE} = "dolphin-emu" ]; then + CMD="-b -a ${AUDIO_BACKEND}" +else + CMD="-p @DOLPHIN_BACKEND@ -a ${AUDIO_BACKEND}" +fi + +# Debugging info: + echo "GAME set to: ${GAME}" + echo "PLATFORM set to: ${PLATFORM}" + echo "CPU CORES set to: ${EMUPERF}" + echo "AA set to: ${AA}" + echo "ASPECT set to: ${ASPECT}" + echo "AUDIOBE set to: ${AUDIOBE}" + echo "ASWAPDISCS set to: ${ASWAPDISCS}" + echo "CLOCK set to: ${CLOCK}" + echo "DOLPHIN_BACKEND set to: ${DOLPHIN_BACKEND}" + echo "ENBCHEATS set to: ${ENBCHEATS}" + echo "GRENDERER set to: ${GRENDERER}" + echo "IRES set to: ${IRES}" + echo "FPS set to: ${FPS}" + echo "CON set to: ${CON}" + echo "HKEY set to: ${HKEY}" + echo "SAVETYPE set to: ${SAVETYPE}" + echo "SAVEREG set to: ${SAVEREG}" + echo "SHADERM set to: ${SHADERM}" + echo "SHADERP set to: ${SHADERP}" + echo "VSYNC set to: ${VSYNC}" + echo "SKIPBIOS set to: ${SKIPBIOS}" + echo "EFBACCESS set to: ${EFBACCESS}" + echo "EFBTEXTURE set to: ${EFBTEXTURE}" + echo "XFBTEXTURE set to: ${XFBTEXTURE}" + echo "TEXTURE_CACHE_ACCURACY set to: ${TEXTURE_CACHE_ACCURACY}" + echo "RUMBLE set to: ${RUMBLE}" + echo "WHACK set to: ${WHACK}" + echo "WPC set to: ${WPC}" + echo "Launching /usr/bin/${DOLPHIN_CORE} ${CMD} -e ${1}" + +# Run Dolphin emulator + ${GPTOKEYB} ${DOLPHIN_CORE} xbox360 & + ${EMUPERF} /usr/bin/${DOLPHIN_CORE} ${CMD} -e "${1}" + kill -9 "$(pidof gptokeyb)" diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/scripts/start_dolphin_wii.sh b/projects/ArchR/packages/emulators/standalone/dolphin-sa/scripts/start_dolphin_wii.sh new file mode 100755 index 0000000000..f709d915c0 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/scripts/start_dolphin_wii.sh @@ -0,0 +1,399 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile + +# Detect version of Dolphin +DOLPHIN_CORE=$(echo "${3}"| sed "s#^/.*/##") +if [ "${DOLPHIN_CORE}" = 'dolphin-qt-wii' ]; then + DOLPHIN_CORE="dolphin-emu" +else + DOLPHIN_CORE="dolphin-emu-nogui" +fi + +set_kill set "-9 ${DOLPHIN_CORE}" + +# Load gptokeyb support files +control-gen_init.sh +source /storage/.config/gptokeyb/control.ini +get_controls + +# Conf files vars +CONF_DIR="/storage/.config/dolphin-emu" +DOLPHIN_INI="Dolphin.ini" +GFX_INI="GFX.ini" +GC_CONTROLLER_INI="GCPadNew.ini" + +# Check if dolphin-emu exists in .config +if [ ! -d "${CONF_DIR}" ]; then + cp -r "/usr/config/dolphin-emu" "/storage/.config/" +fi + +# Check if Hotkeys.ini exists +if [ "${DOLPHIN_CORE}" = 'dolphin-emu' ]; then + if [ ! -f "${CONF_DIR}/Hotkeys.ini" ]; then + cp -r "/usr/config/dolphin-emu/Hotkeys.ini" "${CONF_DIR}/" + fi +fi + +# Check if GC controller dir exists in .config/dolphin-emu/GamecubeControllerProfiles +if [ ! -d "${CONF_DIR}/GamecubeControllerProfiles" ]; then + cp -r "/usr/config/dolphin-emu/GamecubeControllerProfiles" "${CONF_DIR}/" +fi + +# Check if Wii controller dir exists in .config/dolphin-emu/WiiControllerProfiles +if [ ! -d "${CONF_DIR}/WiiControllerProfiles" ]; then + cp -r "/usr/config/dolphin-emu/WiiControllerProfiles" "${CONF_DIR}/dolphin-emu/" +fi + +# Check if Wii custom controller profile exists in .config/dolphin-emu +if [ ! -f "${CONF_DIR}/WiiControllerProfiles/custom.ini" ]; then + cp -r "${CONF_DIR}/WiiControllerProfiles/vremote.ini" "${CONF_DIR}/WiiControllerProfiles/custom.ini" +fi + +# Gamecube controller profile needed for hotkeys to work on SA +if [ "${DOLPHIN_CORE}" = 'dolphin-emu-nogui' ]; then + cp -r "/storage/.config/dolphin-emu/GamecubeControllerProfiles/GCPadNew.ini.south" "/storage/.config/dolphin-emu/GCPadNew.ini" +else + rm -r "/storage/.config/dolphin-emu/GCPadNew.ini" +fi + +# Link Save States to /roms/savestates/wii +if [ ! -d "/storage/roms/savestates/wii/" ]; then + mkdir -p "/storage/roms/savestates/wii/" +fi + +rm -rf ${CONF_DIR}/StateSaves +ln -sf /storage/roms/savestates/wii ${CONF_DIR}/StateSaves + +# Copy bios, memory cards and other system stuff to roms +if [ ! -d "/storage/roms/bios/GC/" ]; then + mkdir -p /storage/roms/bios/GC/{USA,JAP,EUR} + cp -r ${CONF_DIR}/GC /storage/roms/bios/ +fi + +# Link bios and memory cards to roms +for REGION in EUR JAP USA +do + # Link bios + rm -rf "${CONF_DIR}/GC/${REGION}" + ln -sf "/storage/roms/bios/GC/${REGION}" "${CONF_DIR}/GC/${REGION}" + + # Link memory cards, copying to roms/bios first as needed + for SLOT in A B + do + MEM_CARD_FILE="MemoryCard${SLOT}.${REGION}.raw" + CONFIG_MEM_CARD="${CONF_DIR}/GC/${MEM_CARD_FILE}" + ROMS_BIOS_MEM_CARD="/storage/roms/bios/GC/${MEM_CARD_FILE}" + + if [ -f "${ROMS_BIOS_MEM_CARD}" ]; then + # Exists in roms/bios, remove from .config and link + rm -f "${CONFIG_MEM_CARD}" + ln -sf "${ROMS_BIOS_MEM_CARD}" "${CONFIG_MEM_CARD}" + elif [ -f "${CONFIG_MEM_CARD}" ]; then + # Only exists in .config, move to roms/bios and link + mv -f "${CONFIG_MEM_CARD}" "${ROMS_BIOS_MEM_CARD}" + ln -sf "${ROMS_BIOS_MEM_CARD}" "${CONFIG_MEM_CARD}" + fi + done +done + +# Emulation Station Features +GAME=$(echo "${1}"| sed "s#^/.*/##") +PLATFORM=$(echo "${2}"| sed "s#^/.*/##") +AA=$(get_setting anti_aliasing "${PLATFORM}" "${GAME}") +ASPECT=$(get_setting aspect_ratio "${PLATFORM}" "${GAME}") +AUDIOBE=$(get_setting audio_backend "${PLATFORM}" "${GAME}") +CLOCK=$(get_setting clock_speed "${PLATFORM}" "${GAME}") +ENBCHEATS=$(get_setting enable_cheats "${PLATFORM}" "${GAME}") +GRENDERER=$(get_setting graphics_backend "${PLATFORM}" "${GAME}") +IRES=$(get_setting internal_resolution "${PLATFORM}" "${GAME}") +FPS=$(get_setting show_fps "${PLATFORM}" "${GAME}") +CON=$(get_setting wii_controller_profile "${PLATFORM}" "${GAME}") +HKEY=$(get_setting hotkey_enable_button "${PLATFORM}" "${GAME}") +SHADERM=$(get_setting shader_mode "${PLATFORM}" "${GAME}") +SHADERP=$(get_setting shader_precompile "${PLATFORM}" "${GAME}") +VSYNC=$(get_setting vsync "${PLATFORM}" "${GAME}") +EFBACCESS=$(get_setting skip_efb_cpu_access "${PLATFORM}" "${GAME}") +EFBTEXTURE=$(get_setting store_efb_to_texture_only "${PLATFORM}" "${GAME}") +XFBTEXTURE=$(get_setting store_xfb_to_texture_only "${PLATFORM}" "${GAME}") +TEXTURE_CACHE_ACCURACY=$(get_setting texture_cache_accuracy "${PLATFORM}" "${GAME}") +RUMBLE=$(get_setting rumble "${PLATFORM}" "${GAME}") +WHACK=$(get_setting widescreen_hack "${PLATFORM}" "${GAME}") +WPC=$(get_setting write_protect_configs "${PLATFORM}" "${GAME}") + +# Grab clean config files during boot, unless disabled in emulationstation +if [ "$WPC" != "false" ]; then + cp -r /usr/config/dolphin-emu/GFX.ini ${CONF_DIR}/${GFX_INI} + cp -r /usr/config/dolphin-emu/Dolphin.ini ${CONF_DIR}/${DOLPHIN_INI} +fi + +# Set the cores to use +CORES=$(get_setting "cores" "${PLATFORM}" "${GAME}") +if [ "${CORES}" = "little" ] +then + EMUPERF="${SLOW_CORES}" +elif [ "${CORES}" = "big" ] +then + EMUPERF="${FAST_CORES}" +else + ### All.. + unset EMUPERF +fi + +### Emulation Station features: + # Anti-Aliasing + if [ "$AA" = "2m" ]; then + sed -i '/MSAA/c\MSAA = 2' ${CONF_DIR}/${GFX_INI} + sed -i '/SSAA/c\SSAA = False' ${CONF_DIR}/${GFX_INI} + elif [ "$AA" = "2s" ]; then + sed -i '/MSAA/c\MSAA = 2' ${CONF_DIR}/${GFX_INI} + sed -i '/SSAA/c\SSAA = True' ${CONF_DIR}/${GFX_INI} + elif [ "$AA" = "4m" ]; then + sed -i '/MSAA/c\MSAA = 4' ${CONF_DIR}/${GFX_INI} + sed -i '/SSAA/c\SSAA = False' ${CONF_DIR}/${GFX_INI} + elif [ "$AA" = "4s" ]; then + sed -i '/MSAA/c\MSAA = 4' ${CONF_DIR}/${GFX_INI} + sed -i '/SSAA/c\SSAA = True' ${CONF_DIR}/${GFX_INI} + elif [ "$AA" = "8m" ]; then + sed -i '/MSAA/c\MSAA = 8' ${CONF_DIR}/${GFX_INI} + sed -i '/SSAA/c\SSAA = False' ${CONF_DIR}/${GFX_INI} + elif [ "$AA" = "8s" ]; then + sed -i '/MSAA/c\MSAA = 8' ${CONF_DIR}/${GFX_INI} + sed -i '/SSAA/c\SSAA = True' ${CONF_DIR}/${GFX_INI} + else + sed -i '/MSAA/c\MSAA = 0' ${CONF_DIR}/${GFX_INI} + sed -i '/SSAA/c\SSAA = False' ${CONF_DIR}/${GFX_INI} + fi + + # Aspect Ratio + if [ "$ASPECT" = "1" ]; then + sed -i '/AspectRatio/c\AspectRatio = 1' ${CONF_DIR}/${GFX_INI} + elif [ "$ASPECT" = "2" ]; then + sed -i '/AspectRatio/c\AspectRatio = 2' ${CONF_DIR}/${GFX_INI} + elif [ "$ASPECT" = "3" ]; then + sed -i '/AspectRatio/c\AspectRatio = 3' ${CONF_DIR}/${GFX_INI} + else + sed -i '/AspectRatio/c\AspectRatio = 0' ${CONF_DIR}/${GFX_INI} + fi + + # Audio Backend + if [ "$AUDIOBE" = "lle" ]; then + AUDIO_BACKEND="LLE" + else + AUDIO_BACKEND="HLE" + fi + + # Clock Speed + if [ "$CLOCK" = "050" ]; then + sed -i '/^Overclock =/c\Overclock = 0.5' ${CONF_DIR}/${DOLPHIN_INI} + sed -i '/^OverclockEnable =/c\OverclockEnable = True' ${CONF_DIR}/${DOLPHIN_INI} + elif [ "$CLOCK" = "075" ]; then + sed -i '/^Overclock =/c\Overclock = 0.75' ${CONF_DIR}/${DOLPHIN_INI} + sed -i '/^OverclockEnable =/c\OverclockEnable = True' ${CONF_DIR}/${DOLPHIN_INI} + elif [ "$CLOCK" = "100" ]; then + sed -i '/^Overclock =/c\Overclock = 1.0' ${CONF_DIR}/${DOLPHIN_INI} + sed -i '/^OverclockEnable =/c\OverclockEnable = False' ${CONF_DIR}/${DOLPHIN_INI} + elif [ "$CLOCK" = "125" ]; then + sed -i '/^Overclock =/c\Overclock = 1.25' ${CONF_DIR}/${DOLPHIN_INI} + sed -i '/^OverclockEnable =/c\OverclockEnable = True' ${CONF_DIR}/${DOLPHIN_INI} + elif [ "$CLOCK" = "150" ]; then + sed -i '/^Overclock =/c\Overclock = 1.5' ${CONF_DIR}/${DOLPHIN_INI} + sed -i '/^OverclockEnable =/c\OverclockEnable = True' ${CONF_DIR}/${DOLPHIN_INI} + elif [ "$CLOCK" = "200" ]; then + sed -i '/^Overclock =/c\Overclock = 2.0' ${CONF_DIR}/${DOLPHIN_INI} + sed -i '/^OverclockEnable =/c\OverclockEnable = True' ${CONF_DIR}/${DOLPHIN_INI} + elif [ "$CLOCK" = "300" ]; then + sed -i '/^Overclock =/c\Overclock = 3.0' ${CONF_DIR}/${DOLPHIN_INI} + sed -i '/^OverclockEnable =/c\OverclockEnable = True' ${CONF_DIR}/${DOLPHIN_INI} + elif [ "$CLOCK" = "400" ]; then + sed -i '/^Overclock =/c\Overclock = 4.0' ${CONF_DIR}/${DOLPHIN_INI} + sed -i '/^OverclockEnable =/c\OverclockEnable = True' ${CONF_DIR}/${DOLPHIN_INI} + else + sed -i '/^OverclockEnable =/c\OverclockEnable = False' ${CONF_DIR}/${DOLPHIN_INI} + fi + + # Enable Cheats + if [ "$ENBCHEATS" = "1" ]; then + sed -i '/EnableCheats/c\EnableCheats = True' ${CONF_DIR}/${DOLPHIN_INI} + else + sed -i '/EnableCheats/c\EnableCheats = False' ${CONF_DIR}/${DOLPHIN_INI} + fi + + # Graphics Backend + if [ "$GRENDERER" = "vulkan" ]; then + sed -i '/GFXBackend/c\GFXBackend = Vulkan' ${CONF_DIR}/${DOLPHIN_INI} + elif [ "$GRENDERER" = "opengl" ]; then + sed -i '/GFXBackend/c\GFXBackend = OGL' ${CONF_DIR}/${DOLPHIN_INI} + else + sed -i '/GFXBackend/c\GFXBackend = @GRENDERER@' ${CONF_DIR}/${DOLPHIN_INI} + fi + + # Internal Resolution + if [ "$IRES" = "1" ]; then + sed -i '/InternalResolution/c\InternalResolution = 1' ${CONF_DIR}/${GFX_INI} + elif [ "$IRES" = "3" ]; then + sed -i '/InternalResolution/c\InternalResolution = 3' ${CONF_DIR}/${GFX_INI} + elif [ "$IRES" = "4" ]; then + sed -i '/InternalResolution/c\InternalResolution = 4' ${CONF_DIR}/${GFX_INI} + elif [ "$IRES" = "6" ]; then + sed -i '/InternalResolution/c\InternalResolution = 6' ${CONF_DIR}/${GFX_INI} + else + sed -i '/InternalResolution/c\InternalResolution = 2' ${CONF_DIR}/${GFX_INI} + fi + + # Shader Mode + if [ "$SHADERM" = "0" ]; then + sed -i '/ShaderCompilationMode =/c\ShaderCompilationMode = 0' ${CONF_DIR}/${GFX_INI} + elif [ "$SHADERM" = "1" ]; then + sed -i '/ShaderCompilationMode =/c\ShaderCompilationMode = 1' ${CONF_DIR}/${GFX_INI} + elif [ "$SHADERM" = "2" ]; then + sed -i '/ShaderCompilationMode =/c\ShaderCompilationMode = 2' ${CONF_DIR}/${GFX_INI} + elif [ "$SHADERM" = "3" ]; then + sed -i '/ShaderCompilationMode =/c\ShaderCompilationMode = 3' ${CONF_DIR}/${GFX_INI} + fi + + #Shader Precompile + if [ "$SHADERP" = "false" ]; then + sed -i '/WaitForShadersBeforeStarting =/c\WaitForShadersBeforeStarting = False' ${CONF_DIR}/${GFX_INI} + elif [ "$SHADERP" = "true" ]; then + sed -i '/WaitForShadersBeforeStarting =/c\WaitForShadersBeforeStarting = True' ${CONF_DIR}/${GFX_INI} + fi + + # Show FPS + if [ "$FPS" = "true" ]; then + sed -i '/ShowFPS/c\ShowFPS = True' ${CONF_DIR}/${GFX_INI} + else + sed -i '/ShowFPS/c\ShowFPS = False' ${CONF_DIR}/${GFX_INI} + fi + + # Wii Controller Profile + if [ "$CON" = "classic" ]; then + cp -r ${CONF_DIR}/WiiControllerProfiles/classic.ini ${CONF_DIR}/WiimoteNew.ini + elif [ "$CON" = "vremote" ]; then + cp -r ${CONF_DIR}/WiiControllerProfiles/vremote.ini ${CONF_DIR}/WiimoteNew.ini + elif [ "$CON" = "nunchuck" ]; then + cp -r ${CONF_DIR}/WiiControllerProfiles/nunchuck.ini ${CONF_DIR}/WiimoteNew.ini + elif [ "$CON" = "custom" ]; then + cp -r ${CONF_DIR}/WiiControllerProfiles/custom.ini ${CONF_DIR}/WiimoteNew.ini + else + cp -r ${CONF_DIR}/WiiControllerProfiles/hremote.ini ${CONF_DIR}/WiimoteNew.ini + fi + + # Wii Controller Rumble + if [ "$RUMBLE" = "false" ]; then + sed -i '/^Rumble/d' ${DOLPHIN_INI}/WiimoteNew.ini + fi + + # Wii Controller Hotkey Enable + if [ "$HKEY" = "mode" ]; then + sed -i '/^Buttons\/Hotkey =/c\Buttons\/Hotkey = Button 8' ${CONF_DIR}/GCPadNew.ini + else + sed -i '/^Buttons\/Hotkey =/c\Buttons\/Hotkey = Button 6' ${CONF_DIR}/GCPadNew.ini + fi + # Skip EFB CPU Access + if [ "$EFBACCESS" = "false" ]; then + sed -i '/EFBAccessEnable =/c\EFBAccessEnable = False' ${CONF_DIR}/${GFX_INI} + else + sed -i '/EFBAccessEnable =/c\EFBAccessEnable = True' ${CONF_DIR}/${GFX_INI} + fi + + # Store EFB to texture only + if [ "$EFBTEXTURE" = "false" ]; then + sed -i '/EFBToTextureEnable =/c\EFBToTextureEnable = False' ${CONF_DIR}/${GFX_INI} + else + sed -i '/EFBToTextureEnable =/c\EFBToTextureEnable = True' ${CONF_DIR}/${GFX_INI} + fi + + # Store XFB to texture only + if [ "$XFBTEXTURE" = "false" ]; then + sed -i '/XFBToTextureEnable =/c\XFBToTextureEnable = False' ${CONF_DIR}/${GFX_INI} + else + sed -i '/XFBToTextureEnable =/c\XFBToTextureEnable = True' ${CONF_DIR}/${GFX_INI} + fi + + # Texture cache accuracy + if [ "$TEXTURE_CACHE_ACCURACY" = "0" ]; then + sed -i '/SafeTextureCacheColorSamples =/c\SafeTextureCacheColorSamples = 0' ${CONF_DIR}/${GFX_INI} + elif [ "$TEXTURE_CACHE_ACCURACY" = "512" ]; then + sed -i '/SafeTextureCacheColorSamples =/c\SafeTextureCacheColorSamples = 512' ${CONF_DIR}/${GFX_INI} + else + # Default to 128 = fast + sed -i '/SafeTextureCacheColorSamples =/c\SafeTextureCacheColorSamples = 128' ${CONF_DIR}/${GFX_INI} + fi + + # Widescreen Hack + if [ "$WHACK" = "true" ]; then + sed -i '/wideScreenHack =/c\wideScreenHack = True' ${CONF_DIR}/${GFX_INI} + else + sed -i '/wideScreenHack =/c\wideScreenHack = False' ${CONF_DIR}/${GFX_INI} + fi + +# Skip bios always, it's untested for Wii +sed -i '/SkipIPL/c\SkipIPL = True' ${CONF_DIR}/${DOLPHIN_INI} + + # GC Controller Hotkey Enable + if [ "$HKEY" = "mode" ]; then + sed -i '/^Buttons\/Hotkey =/c\Buttons\/Hotkey = Button 8' ${CONF_DIR}/${GC_CONTROLLER_INI} + else + sed -i '/^Buttons\/Hotkey =/c\Buttons\/Hotkey = Button 6' ${CONF_DIR}/${GC_CONTROLLER_INI} + fi + + # Vsync + if [ "$VSYNC" = "1" ]; then + sed -i '/VSync =/c\VSync = True' ${CONF_DIR}/${GFX_INI} + else + sed -i '/VSync =/c\VSync = False' ${CONF_DIR}/${GFX_INI} + fi + +# Link .config/dolphin-emu to .local +rm -rf /storage/.local/share/dolphin-emu +ln -sf /storage/.config/dolphin-emu /storage/.local/share/dolphin-emu + +@EXPORTS@ + +# Retroachievements + /usr/bin/cheevos_dolphin.sh + +# Set video and audio backend + CMD="${CMD} -v $GRENDERER" + +if [ ${DOLPHIN_CORE} = "dolphin-emu" ]; then + CMD="-b -a ${AUDIO_BACKEND}" +else + CMD="-p @DOLPHIN_BACKEND@ -a ${AUDIO_BACKEND}" +fi + +# Debugging info: + echo "GAME set to: ${GAME}" + echo "PLATFORM set to: ${PLATFORM}" + echo "CPU CORES set to ${EMUPERF}" + echo "AA set to: ${AA}" + echo "ASPECT set to: ${ASPECT}" + echo "AUDIOBE set to: ${AUDIOBE}" + echo "CLOCK set to: ${CLOCK}" + echo "DOLPHIN_BACKEND set to: ${DOLPHIN_BACKEND}" + echo "ENBCHEATS set to: ${ENBCHEATS}" + echo "GRENDERER set to: ${GRENDERER}" + echo "IRES set to: ${IRES}" + echo "FPS set to: ${FPS}" + echo "CON set to: ${CON}" + echo "HKEY set to: ${HKEY}" + echo "SHADERM set to: ${SHADERM}" + echo "SHADERP set to: ${SHADERP}" + echo "VSYNC set to: ${VSYNC}" + echo "EFBACCESS set to: ${EFBACCESS}" + echo "EFBTEXTURE set to: ${EFBTEXTURE}" + echo "XFBTEXTURE set to: ${XFBTEXTURE}" + echo "TEXTURE_CACHE_ACCURACY set to: ${TEXTURE_CACHE_ACCURACY}" + echo "RUMBLE set to: ${RUMBLE}" + echo "WHACK set to: ${WHACK}" + echo "WPC set to: ${WPC}" + echo "Launching /usr/bin/${DOLPHIN_CORE} ${CMD} -e ${1}" + +# Run Dolphin emulator + ${GPTOKEYB} ${DOLPHIN_CORE} xbox360 & + ${EMUPERF} /usr/bin/${DOLPHIN_CORE} ${CMD} -e "${1}" + kill -9 "$(pidof gptokeyb)" diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/triforce/GEYP6E.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/triforce/GEYP6E.ini new file mode 100644 index 0000000000..6361b66f96 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/triforce/GEYP6E.ini @@ -0,0 +1,10 @@ +# GEYP6E - Virtua Striker 2002 (Export, Type3) +[Core] +FPRF = True +[Gecko] +$Force Japan Version +04054234 60000000 +$ Unlock Special Teams +024E2F73 00004142 +004E2FA3 00000001 +004E2F9E 00000002 diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/triforce/GGGE6E.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/triforce/GGGE6E.ini new file mode 100644 index 0000000000..19ebe4c210 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/triforce/GGGE6E.ini @@ -0,0 +1,57 @@ +# GGGE6E - F-ZERO AX +[Core] +FPRF = True +CPUThread = True +[Gecko] +$Widescreen +044461B4 3FE40000 +$Infinite Time +0437C964 EA000000 +$Infinite Energy +04C43a04 42C80000 +[OnFrame] +$Disable Motor Setup (Rev. C) +0x8024DB74:dword:0x801809F8 +0x8024DB78:dword:0x8018085C +$Disable Motor Setup (Rev. D) +0x8024E034:dword:0x80180D5C +0x8024E038:dword:0x80180BC0 +$Disable Motor Setup (Rev. E) +0x8024E4B4:dword:0x801812E8 +0x8024E4B8:dword:0x8018114C +$Advertise Sound ON +0x803D0175:byte:0x00000001 +$Advertise Sound OFF +0x803D0175:byte:0x00000000 +$Game Difficulty (very easy) +0x803D0176:byte:0x00000000 +$Game Difficulty (easy) +0x803D0176:byte:0x00000001 +$Game Difficulty (normal) +0x803D0176:byte:0x00000002 +$Game Difficulty (hard) +0x803D0176:byte:0x00000003 +$Game Difficulty (hardest) +0x803D0176:byte:0x00000004 +$Race Mode Laps (normal) +0x803D0179:byte:0x00000000 +$Race Mode Laps (set 1) +0x803D0179:byte:0x00000001 +$Race Mode Laps (set 2) +0x803D0179:byte:0x00000002 +$Race Mode Laps (set 3) +0x803D0179:byte:0x00000003 +$Race Mode Laps (set 4) +0x803D0179:byte:0x00000004 +$Race Mode Laps (set 5) +0x803D0179:byte:0x00000005 +$Handicap On +0x803D132E:byte:0x00000001 +$Handicap Off +0x803D132E:byte:0x00000000 +[OnFrame_Enabled] +$Disable Motor Setup (Rev. C) +$Disable Motor Setup (Rev. D) +$Disable Motor Setup (Rev. E) +$Advertise Sound ON +$Game Difficulty (easy) diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/triforce/GHAE6E.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/triforce/GHAE6E.ini new file mode 100644 index 0000000000..af2f040bc3 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/triforce/GHAE6E.ini @@ -0,0 +1,18 @@ +# GHAE6E - F-ZERO AX (Monster) +[OnFrame] +$Disable Motor Setup +0x8023A0F4:dword:0x8016B4EC +0x8023A0F8:dword:0x8016B350 +[Core] +FPRF = True +CPUThread = True +[OnFrame_Enabled] +$Disable Motor Setup +[Gecko] +$Bypass Cycraft +0043137B 00000086 +$Slowdown Fix +0043137E 00000000 +[Gecko_Enabled] +$Bypass Cycraft +$Slowdown Fix diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/triforce/GKPJ6E.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/triforce/GKPJ6E.ini new file mode 100644 index 0000000000..45d5d81eb0 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/triforce/GKPJ6E.ini @@ -0,0 +1,53 @@ +# GKPJ6E - Mario Kart Arcade GP +[OnFrame] +$Disable NAMCAM +0x800790A0:dword:0x98650025 +$Loop Fix +0x8003226C:dword:0x60000000 +0x80032278:dword:0x41820158 +$Card Saving Fix +0x801be2dc:dword:0x4082009c +$Game Over Hang Fix +0x8003b020:dword:0x40820040 +$Loop fix2 +0x80031BF0:dword:0x60000000 +0x80031BFC:dword:0x60000000 +0x800BE10C:dword:0x4800002C +0x8009F1E0:dword:0x60000000 +[OnFrame_Enabled] +$Disable NAMCAM +$Card Saving Fix +$Game Over Hang Fix +$Loop Fix +$Loop fix2 +[Gecko] +$WIDESCREEN JPN +C228C800 00000009 +C03F0034 9421FFE0 +93C10004 93E10008 +DBE1000C 7FC802A6 +48000009 3FAAAAAB +7FE802A6 C3FF0000 +EC3F0072 7FC803A6 +83C10004 83E10008 +CBE1000C 38210020 +60000000 00000000 +$WIDESCREEN USA +C22C80D4 00000009 +C03F0034 9421FFE0 +93C10004 93E10008 +DBE1000C 7FC802A6 +48000009 3FAAAAAB +7FE802A6 C3FF0000 +EC3F0072 7FC803A6 +83C10004 83E10008 +CBE1000C 38210020 +60000000 00000000 +$Slowdowns Fix (Required) +041b2238 60000000 +$Link Check Skip +04032410 60000000 +$Skip Boot Checks +040320fc 60000000 +[Gecko_Enabled] +$Slowdowns Fix (Required) diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/triforce/GLLP6E.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/triforce/GLLP6E.ini new file mode 100644 index 0000000000..4f809a8c4d --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/triforce/GLLP6E.ini @@ -0,0 +1,8 @@ +# GLLP6E - VIRTUA STRIKER 4 Ver.2006 (Export) +[Core] +FPRF = True +[OnFrame_Enabled] +$bypass code +[OnFrame] +$bypass code +0x80414CE8:byte:0x00000005 diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/triforce/GNLJ82.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/triforce/GNLJ82.ini new file mode 100644 index 0000000000..161d238009 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/triforce/GNLJ82.ini @@ -0,0 +1,46 @@ +# GNLJ82 - Mario Kart Arcade GP 2 +[OnFrame] +$Disable NAMCAM +0x805986E5:byte:0x00000000 +0x80073BD8:dword:0x98650025 +[OnFrame_Enabled] +$Disable NAMCAM +[Gecko] +$WIDESCREEN +C22C80D4 00000009 +C03F0034 9421FFE0 +93C10004 93E10008 +DBE1000C 7FC802A6 +48000009 3FAAAAAB +7FE802A6 C3FF0000 +EC3F0072 7FC803A6 +83C10004 83E10008 +CBE1000C 38210020 +60000000 00000000 +$Slowdowns Fix (US - Required) +04086150 60000000 +$Link Check Skip (US - Optional) +0402eb6c 60000000 +$Skip boot checks (US - Optional) +0402e858 60000000 +$Card Save Hang Fix (US - Required) +04249958 38000000 +0424995c 980da504 +04249960 980da509 +04249964 480000ac +$Slowdowns Fix (JPN - Required) +04086768 60000000 +$Link Check Skip (JPN - Optional) +0402ebcc 60000000 +$Skip boot checks (JPN - Optional) +0402e8b8 60000000 +$Card Save Hang Fix (JPN - Required) +04249f60 38000000 +04249f64 980da504 +04249f68 980da509 +04249f6c 480000ac + +[Gecko_Enabled] +$WIDESCREEN +$Slowdowns Fix (US - Required) +$Link Check Skip (US - Optional) diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/triforce/SBJA.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/triforce/SBJA.ini new file mode 100644 index 0000000000..0b0bbfc456 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/triforce/SBJA.ini @@ -0,0 +1,8 @@ +# Virtua Striker 4 (Export) +[Core] +FPRF = True +[Gecko] +$bypass code +0405214c 60000000 +[Gecko_Enabled] +$bypass code diff --git a/projects/ArchR/packages/emulators/standalone/dolphin-sa/triforce/SBLK.ini b/projects/ArchR/packages/emulators/standalone/dolphin-sa/triforce/SBLK.ini new file mode 100644 index 0000000000..5fda0e0bbe --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/dolphin-sa/triforce/SBLK.ini @@ -0,0 +1,8 @@ +# Virtua Striker 4 Ver.2006 (Japan) +[Core] +FPRF = True +[Gecko] +$Bypass boot +040568D8 60000000 +[Gecko_Enabled] +$Bypass boot diff --git a/projects/ArchR/packages/emulators/standalone/drastic-sa/config/H700/drastic.cfg b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/H700/drastic.cfg new file mode 100644 index 0000000000..9a29b95575 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/H700/drastic.cfg @@ -0,0 +1,111 @@ +frameskip_type = 2 +frameskip_value = 3 +safe_frameskip = 0 +show_frame_counter = 0 +screen_orientation = 1 +screen_swap = 0 +savestate_number = 0 +fast_forward = 0 +enable_sound = 1 +clock_speed = 0 +threaded_3d = 1 +mirror_touch = 0 +compress_savestates = 1 +savestate_snapshot = 1 +unzip_roms = 0 +preload_roms = 0 +backup_in_savestates = 1 +ignore_gamecard_limit = 0 +frame_interval = 0 +trim_roms = 0 +fix_main_2d_screen = 0 +disable_edge_marking = 0 +interframe_blend = 0 +hires_3d = 1 +use_rtc_custom_time = 0 +rtc_custom_time = 0 +rtc_system_time = 0 +slot2_device_type = 0 +rumble_frames = 3 +firmware.username = Dr DraStic +firmware.language = 1 +firmware.favorite_color = 0 +firmware.birthday_month = 1 +firmware.birthday_day = 1 +enable_cheats = 1 +controls_a[CONTROL_INDEX_UP] = 1217 +controls_a[CONTROL_INDEX_DOWN] = 1153 +controls_a[CONTROL_INDEX_LEFT] = 1216 +controls_a[CONTROL_INDEX_RIGHT] = 1152 +controls_a[CONTROL_INDEX_A] = 65535 +controls_a[CONTROL_INDEX_B] = 65535 +controls_a[CONTROL_INDEX_X] = 65535 +controls_a[CONTROL_INDEX_Y] = 65535 +controls_a[CONTROL_INDEX_L] = 65535 +controls_a[CONTROL_INDEX_R] = 65535 +controls_a[CONTROL_INDEX_START] = 65535 +controls_a[CONTROL_INDEX_SELECT] = 65535 +controls_a[CONTROL_INDEX_HINGE] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_UP] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 65535 +controls_a[CONTROL_INDEX_MENU] = 65535 +controls_a[CONTROL_INDEX_SAVE_STATE] = 65535 +controls_a[CONTROL_INDEX_LOAD_STATE] = 65535 +controls_a[CONTROL_INDEX_FAST_FORWARD] = 65535 +controls_a[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_A] = 65535 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_B] = 65535 +controls_a[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_a[CONTROL_INDEX_QUIT] = 65535 +controls_a[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_a[CONTROL_INDEX_UI_UP] = 1217 +controls_a[CONTROL_INDEX_UI_DOWN] = 1153 +controls_a[CONTROL_INDEX_UI_LEFT] = 1216 +controls_a[CONTROL_INDEX_UI_RIGHT] = 1152 +controls_a[CONTROL_INDEX_UI_SELECT] = 65535 +controls_a[CONTROL_INDEX_UI_BACK] = 65535 +controls_a[CONTROL_INDEX_UI_EXIT] = 65535 +controls_a[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_a[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_a[CONTROL_INDEX_UI_SWITCH] = 65535 +controls_b[CONTROL_INDEX_UP] = 1037 +controls_b[CONTROL_INDEX_DOWN] = 1038 +controls_b[CONTROL_INDEX_LEFT] = 1039 +controls_b[CONTROL_INDEX_RIGHT] = 1040 +controls_b[CONTROL_INDEX_A] = 1025 +controls_b[CONTROL_INDEX_B] = 1024 +controls_b[CONTROL_INDEX_X] = 1026 +controls_b[CONTROL_INDEX_Y] = 1027 +controls_b[CONTROL_INDEX_L] = 1028 +controls_b[CONTROL_INDEX_R] = 1029 +controls_b[CONTROL_INDEX_START] = 1033 +controls_b[CONTROL_INDEX_SELECT] = 1032 +controls_b[CONTROL_INDEX_HINGE] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_UP] = 1219 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 1155 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 1218 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 1154 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 1036 +controls_b[CONTROL_INDEX_MENU] = 1035 +controls_b[CONTROL_INDEX_SAVE_STATE] = 65535 +controls_b[CONTROL_INDEX_LOAD_STATE] = 65535 +controls_b[CONTROL_INDEX_FAST_FORWARD] = 65535 +controls_b[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_A] = 1030 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_B] = 1031 +controls_b[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_b[CONTROL_INDEX_QUIT] = 65535 +controls_b[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_b[CONTROL_INDEX_UI_UP] = 1037 +controls_b[CONTROL_INDEX_UI_DOWN] = 1038 +controls_b[CONTROL_INDEX_UI_LEFT] = 1039 +controls_b[CONTROL_INDEX_UI_RIGHT] = 1040 +controls_b[CONTROL_INDEX_UI_SELECT] = 1025 +controls_b[CONTROL_INDEX_UI_BACK] = 65535 +controls_b[CONTROL_INDEX_UI_EXIT] = 1024 +controls_b[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_b[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_b[CONTROL_INDEX_UI_SWITCH] = 65535 diff --git a/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg new file mode 100644 index 0000000000..dc9efe3e2f --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg @@ -0,0 +1,111 @@ +frameskip_type = 2 +frameskip_value = 3 +safe_frameskip = 0 +show_frame_counter = 0 +screen_orientation = 1 +screen_swap = 0 +savestate_number = 0 +fast_forward = 0 +enable_sound = 1 +clock_speed = 0 +threaded_3d = 1 +mirror_touch = 0 +compress_savestates = 1 +savestate_snapshot = 1 +unzip_roms = 0 +preload_roms = 0 +backup_in_savestates = 1 +ignore_gamecard_limit = 0 +frame_interval = 0 +trim_roms = 0 +fix_main_2d_screen = 0 +disable_edge_marking = 0 +interframe_blend = 0 +hires_3d = 1 +use_rtc_custom_time = 0 +rtc_custom_time = 0 +rtc_system_time = 0 +slot2_device_type = 0 +rumble_frames = 3 +firmware.username = Dr DraStic +firmware.language = 1 +firmware.favorite_color = 0 +firmware.birthday_month = 1 +firmware.birthday_day = 1 +enable_cheats = 1 +controls_a[CONTROL_INDEX_UP] = 1089 +controls_a[CONTROL_INDEX_DOWN] = 1092 +controls_a[CONTROL_INDEX_LEFT] = 1096 +controls_a[CONTROL_INDEX_RIGHT] = 1090 +controls_a[CONTROL_INDEX_A] = 32 +controls_a[CONTROL_INDEX_B] = 480 +controls_a[CONTROL_INDEX_X] = 122 +controls_a[CONTROL_INDEX_Y] = 120 +controls_a[CONTROL_INDEX_L] = 481 +controls_a[CONTROL_INDEX_R] = 99 +controls_a[CONTROL_INDEX_START] = 13 +controls_a[CONTROL_INDEX_SELECT] = 485 +controls_a[CONTROL_INDEX_HINGE] = 104 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_UP] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 1024 +controls_a[CONTROL_INDEX_MENU] = 1032 +controls_a[CONTROL_INDEX_SAVE_STATE] = 318 +controls_a[CONTROL_INDEX_LOAD_STATE] = 320 +controls_a[CONTROL_INDEX_FAST_FORWARD] = 8 +controls_a[CONTROL_INDEX_SWAP_SCREENS] = 1034 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_A] = 97 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_B] = 1035 +controls_a[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_a[CONTROL_INDEX_QUIT] = 65535 +controls_a[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_a[CONTROL_INDEX_UI_UP] = 338 +controls_a[CONTROL_INDEX_UI_DOWN] = 337 +controls_a[CONTROL_INDEX_UI_LEFT] = 336 +controls_a[CONTROL_INDEX_UI_RIGHT] = 335 +controls_a[CONTROL_INDEX_UI_SELECT] = 13 +controls_a[CONTROL_INDEX_UI_BACK] = 8 +controls_a[CONTROL_INDEX_UI_EXIT] = 27 +controls_a[CONTROL_INDEX_UI_PAGE_UP] = 331 +controls_a[CONTROL_INDEX_UI_PAGE_DOWN] = 334 +controls_a[CONTROL_INDEX_UI_SWITCH] = 481 +controls_b[CONTROL_INDEX_UP] = 1153 +controls_b[CONTROL_INDEX_DOWN] = 1217 +controls_b[CONTROL_INDEX_LEFT] = 1152 +controls_b[CONTROL_INDEX_RIGHT] = 1216 +controls_b[CONTROL_INDEX_A] = 1024 +controls_b[CONTROL_INDEX_B] = 1025 +controls_b[CONTROL_INDEX_X] = 1026 +controls_b[CONTROL_INDEX_Y] = 1027 +controls_b[CONTROL_INDEX_L] = 1028 +controls_b[CONTROL_INDEX_R] = 1029 +controls_b[CONTROL_INDEX_START] = 1030 +controls_b[CONTROL_INDEX_SELECT] = 1031 +controls_b[CONTROL_INDEX_HINGE] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_UP] = 1219 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 1155 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 1218 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 1154 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 1033 +controls_b[CONTROL_INDEX_MENU] = 65535 +controls_b[CONTROL_INDEX_SAVE_STATE] = 65535 +controls_b[CONTROL_INDEX_LOAD_STATE] = 65535 +controls_b[CONTROL_INDEX_FAST_FORWARD] = 65535 +controls_b[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_A] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_B] = 65535 +controls_b[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_b[CONTROL_INDEX_QUIT] = 65535 +controls_b[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_b[CONTROL_INDEX_UI_UP] = 1089 +controls_b[CONTROL_INDEX_UI_DOWN] = 1092 +controls_b[CONTROL_INDEX_UI_LEFT] = 1096 +controls_b[CONTROL_INDEX_UI_RIGHT] = 1090 +controls_b[CONTROL_INDEX_UI_SELECT] = 1024 +controls_b[CONTROL_INDEX_UI_BACK] = 1034 +controls_b[CONTROL_INDEX_UI_EXIT] = 1025 +controls_b[CONTROL_INDEX_UI_PAGE_UP] = 1028 +controls_b[CONTROL_INDEX_UI_PAGE_DOWN] = 1029 +controls_b[CONTROL_INDEX_UI_SWITCH] = 1035 diff --git a/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg.oga b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg.oga new file mode 100644 index 0000000000..704e8d9692 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg.oga @@ -0,0 +1,111 @@ +frameskip_type = 2 +frameskip_value = 3 +safe_frameskip = 0 +show_frame_counter = 0 +screen_orientation = 1 +screen_swap = 0 +savestate_number = 1 +fast_forward = 0 +enable_sound = 1 +clock_speed = 0 +threaded_3d = 1 +mirror_touch = 0 +compress_savestates = 1 +savestate_snapshot = 1 +unzip_roms = 0 +preload_roms = 0 +backup_in_savestates = 1 +ignore_gamecard_limit = 0 +frame_interval = 0 +trim_roms = 0 +fix_main_2d_screen = 0 +disable_edge_marking = 0 +interframe_blend = 0 +hires_3d = 1 +use_rtc_custom_time = 0 +rtc_custom_time = 0 +rtc_system_time = 0 +slot2_device_type = 0 +rumble_frames = 3 +firmware.username = Dr DraStic +firmware.language = 1 +firmware.favorite_color = 0 +firmware.birthday_month = 1 +firmware.birthday_day = 1 +enable_cheats = 1 +controls_a[CONTROL_INDEX_UP] = 1030 +controls_a[CONTROL_INDEX_DOWN] = 1031 +controls_a[CONTROL_INDEX_LEFT] = 1032 +controls_a[CONTROL_INDEX_RIGHT] = 1033 +controls_a[CONTROL_INDEX_A] = 1025 +controls_a[CONTROL_INDEX_B] = 1024 +controls_a[CONTROL_INDEX_X] = 1026 +controls_a[CONTROL_INDEX_Y] = 1027 +controls_a[CONTROL_INDEX_L] = 1028 +controls_a[CONTROL_INDEX_R] = 1029 +controls_a[CONTROL_INDEX_START] = 1037 +controls_a[CONTROL_INDEX_SELECT] = 1034 +controls_a[CONTROL_INDEX_HINGE] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_UP] = 1217 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 1153 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 1216 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 1152 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 1036 +controls_a[CONTROL_INDEX_MENU] = 1035 +controls_a[CONTROL_INDEX_SAVE_STATE] = 65535 +controls_a[CONTROL_INDEX_LOAD_STATE] = 65535 +controls_a[CONTROL_INDEX_FAST_FORWARD] = 65535 +controls_a[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_A] = 65535 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_B] = 65535 +controls_a[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_a[CONTROL_INDEX_QUIT] = 65535 +controls_a[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_a[CONTROL_INDEX_UI_UP] = 1030 +controls_a[CONTROL_INDEX_UI_DOWN] = 1031 +controls_a[CONTROL_INDEX_UI_LEFT] = 1032 +controls_a[CONTROL_INDEX_UI_RIGHT] = 1033 +controls_a[CONTROL_INDEX_UI_SELECT] = 1025 +controls_a[CONTROL_INDEX_UI_BACK] = 65535 +controls_a[CONTROL_INDEX_UI_EXIT] = 1024 +controls_a[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_a[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_a[CONTROL_INDEX_UI_SWITCH] = 65535 +controls_b[CONTROL_INDEX_UP] = 65535 +controls_b[CONTROL_INDEX_DOWN] = 65535 +controls_b[CONTROL_INDEX_LEFT] = 65535 +controls_b[CONTROL_INDEX_RIGHT] = 65535 +controls_b[CONTROL_INDEX_A] = 65535 +controls_b[CONTROL_INDEX_B] = 65535 +controls_b[CONTROL_INDEX_X] = 65535 +controls_b[CONTROL_INDEX_Y] = 65535 +controls_b[CONTROL_INDEX_L] = 65535 +controls_b[CONTROL_INDEX_R] = 65535 +controls_b[CONTROL_INDEX_START] = 65535 +controls_b[CONTROL_INDEX_SELECT] = 65535 +controls_b[CONTROL_INDEX_HINGE] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_UP] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 65535 +controls_b[CONTROL_INDEX_MENU] = 65535 +controls_b[CONTROL_INDEX_SAVE_STATE] = 65535 +controls_b[CONTROL_INDEX_LOAD_STATE] = 65535 +controls_b[CONTROL_INDEX_FAST_FORWARD] = 65535 +controls_b[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_A] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_B] = 65535 +controls_b[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_b[CONTROL_INDEX_QUIT] = 65535 +controls_b[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_b[CONTROL_INDEX_UI_UP] = 1217 +controls_b[CONTROL_INDEX_UI_DOWN] = 1153 +controls_b[CONTROL_INDEX_UI_LEFT] = 1216 +controls_b[CONTROL_INDEX_UI_RIGHT] = 1152 +controls_b[CONTROL_INDEX_UI_SELECT] = 65535 +controls_b[CONTROL_INDEX_UI_BACK] = 65535 +controls_b[CONTROL_INDEX_UI_EXIT] = 65535 +controls_b[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_b[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_b[CONTROL_INDEX_UI_SWITCH] = 65535 diff --git a/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg.ogabe b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg.ogabe new file mode 100644 index 0000000000..592dec4beb --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg.ogabe @@ -0,0 +1,111 @@ +frameskip_type = 2 +frameskip_value = 3 +safe_frameskip = 0 +show_frame_counter = 0 +screen_orientation = 1 +screen_swap = 0 +savestate_number = 0 +fast_forward = 0 +enable_sound = 1 +clock_speed = 0 +threaded_3d = 1 +mirror_touch = 0 +compress_savestates = 1 +savestate_snapshot = 1 +unzip_roms = 0 +preload_roms = 0 +backup_in_savestates = 1 +ignore_gamecard_limit = 0 +frame_interval = 0 +trim_roms = 0 +fix_main_2d_screen = 0 +disable_edge_marking = 0 +interframe_blend = 0 +hires_3d = 1 +use_rtc_custom_time = 0 +rtc_custom_time = 0 +rtc_system_time = 0 +slot2_device_type = 0 +rumble_frames = 3 +firmware.username = Dr DraStic +firmware.language = 1 +firmware.favorite_color = 0 +firmware.birthday_month = 1 +firmware.birthday_day = 1 +enable_cheats = 1 +controls_a[CONTROL_INDEX_UP] = 1036 +controls_a[CONTROL_INDEX_DOWN] = 1037 +controls_a[CONTROL_INDEX_LEFT] = 1038 +controls_a[CONTROL_INDEX_RIGHT] = 1039 +controls_a[CONTROL_INDEX_A] = 100 +controls_a[CONTROL_INDEX_B] = 99 +controls_a[CONTROL_INDEX_X] = 122 +controls_a[CONTROL_INDEX_Y] = 118 +controls_a[CONTROL_INDEX_L] = 113 +controls_a[CONTROL_INDEX_R] = 111 +controls_a[CONTROL_INDEX_START] = 1033 +controls_a[CONTROL_INDEX_SELECT] = 1032 +controls_a[CONTROL_INDEX_HINGE] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_UP] = 1217 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 1153 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 1216 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 1152 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 1035 +controls_a[CONTROL_INDEX_MENU] = 1034 +controls_a[CONTROL_INDEX_SAVE_STATE] = 65535 +controls_a[CONTROL_INDEX_LOAD_STATE] = 65535 +controls_a[CONTROL_INDEX_FAST_FORWARD] = 65535 +controls_a[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_A] = 1030 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_B] = 1031 +controls_a[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_a[CONTROL_INDEX_QUIT] = 65535 +controls_a[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_a[CONTROL_INDEX_UI_UP] = 1032 +controls_a[CONTROL_INDEX_UI_DOWN] = 1033 +controls_a[CONTROL_INDEX_UI_LEFT] = 1034 +controls_a[CONTROL_INDEX_UI_RIGHT] = 1035 +controls_a[CONTROL_INDEX_UI_SELECT] = 1025 +controls_a[CONTROL_INDEX_UI_BACK] = 65535 +controls_a[CONTROL_INDEX_UI_EXIT] = 1024 +controls_a[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_a[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_a[CONTROL_INDEX_UI_SWITCH] = 65535 +controls_b[CONTROL_INDEX_UP] = 65535 +controls_b[CONTROL_INDEX_DOWN] = 65535 +controls_b[CONTROL_INDEX_LEFT] = 65535 +controls_b[CONTROL_INDEX_RIGHT] = 65535 +controls_b[CONTROL_INDEX_A] = 65535 +controls_b[CONTROL_INDEX_B] = 65535 +controls_b[CONTROL_INDEX_X] = 65535 +controls_b[CONTROL_INDEX_Y] = 65535 +controls_b[CONTROL_INDEX_L] = 65535 +controls_b[CONTROL_INDEX_R] = 65535 +controls_b[CONTROL_INDEX_START] = 65535 +controls_b[CONTROL_INDEX_SELECT] = 65535 +controls_b[CONTROL_INDEX_HINGE] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_UP] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 65535 +controls_b[CONTROL_INDEX_MENU] = 65535 +controls_b[CONTROL_INDEX_SAVE_STATE] = 65535 +controls_b[CONTROL_INDEX_LOAD_STATE] = 65535 +controls_b[CONTROL_INDEX_FAST_FORWARD] = 65535 +controls_b[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_A] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_B] = 65535 +controls_b[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_b[CONTROL_INDEX_QUIT] = 65535 +controls_b[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_b[CONTROL_INDEX_UI_UP] = 1217 +controls_b[CONTROL_INDEX_UI_DOWN] = 1153 +controls_b[CONTROL_INDEX_UI_LEFT] = 1216 +controls_b[CONTROL_INDEX_UI_RIGHT] = 1152 +controls_b[CONTROL_INDEX_UI_SELECT] = 65535 +controls_b[CONTROL_INDEX_UI_BACK] = 65535 +controls_b[CONTROL_INDEX_UI_EXIT] = 65535 +controls_b[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_b[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_b[CONTROL_INDEX_UI_SWITCH] = 65535 diff --git a/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg.ogs b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg.ogs new file mode 100644 index 0000000000..7ee2ee6ca8 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg.ogs @@ -0,0 +1,111 @@ +frameskip_type = 2 +frameskip_value = 4 +safe_frameskip = 0 +show_frame_counter = 0 +screen_orientation = 0 +screen_swap = 0 +savestate_number = 0 +fast_forward = 0 +enable_sound = 1 +clock_speed = 0 +threaded_3d = 0 +mirror_touch = 0 +compress_savestates = 1 +savestate_snapshot = 1 +unzip_roms = 0 +preload_roms = 0 +backup_in_savestates = 1 +ignore_gamecard_limit = 0 +frame_interval = 0 +trim_roms = 0 +fix_main_2d_screen = 0 +disable_edge_marking = 0 +interframe_blend = 0 +hires_3d = 0 +use_rtc_custom_time = 0 +rtc_custom_time = 0 +rtc_system_time = 0 +slot2_device_type = 0 +rumble_frames = 3 +firmware.username = Dr DraStic +firmware.language = 1 +firmware.favorite_color = 0 +firmware.birthday_month = 1 +firmware.birthday_day = 1 +enable_cheats = 1 +controls_a[CONTROL_INDEX_UP] = 1036 +controls_a[CONTROL_INDEX_DOWN] = 1037 +controls_a[CONTROL_INDEX_LEFT] = 1038 +controls_a[CONTROL_INDEX_RIGHT] = 1039 +controls_a[CONTROL_INDEX_A] = 1025 +controls_a[CONTROL_INDEX_B] = 1024 +controls_a[CONTROL_INDEX_X] = 1026 +controls_a[CONTROL_INDEX_Y] = 1027 +controls_a[CONTROL_INDEX_L] = 1028 +controls_a[CONTROL_INDEX_R] = 1029 +controls_a[CONTROL_INDEX_START] = 1033 +controls_a[CONTROL_INDEX_SELECT] = 1032 +controls_a[CONTROL_INDEX_HINGE] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_UP] = 1219 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 1155 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 1218 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 1154 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 1035 +controls_a[CONTROL_INDEX_MENU] = 1040 +controls_a[CONTROL_INDEX_SAVE_STATE] = 1031 +controls_a[CONTROL_INDEX_LOAD_STATE] = 1030 +controls_a[CONTROL_INDEX_FAST_FORWARD] = 65535 +controls_a[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_A] = 1034 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_B] = 1041 +controls_a[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_a[CONTROL_INDEX_QUIT] = 65535 +controls_a[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_a[CONTROL_INDEX_UI_UP] = 1036 +controls_a[CONTROL_INDEX_UI_DOWN] = 1037 +controls_a[CONTROL_INDEX_UI_LEFT] = 1038 +controls_a[CONTROL_INDEX_UI_RIGHT] = 1039 +controls_a[CONTROL_INDEX_UI_SELECT] = 1025 +controls_a[CONTROL_INDEX_UI_BACK] = 1026 +controls_a[CONTROL_INDEX_UI_EXIT] = 1024 +controls_a[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_a[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_a[CONTROL_INDEX_UI_SWITCH] = 65535 +controls_b[CONTROL_INDEX_UP] = 1217 +controls_b[CONTROL_INDEX_DOWN] = 1153 +controls_b[CONTROL_INDEX_LEFT] = 1216 +controls_b[CONTROL_INDEX_RIGHT] = 1152 +controls_b[CONTROL_INDEX_A] = 65535 +controls_b[CONTROL_INDEX_B] = 65535 +controls_b[CONTROL_INDEX_X] = 65535 +controls_b[CONTROL_INDEX_Y] = 65535 +controls_b[CONTROL_INDEX_L] = 65535 +controls_b[CONTROL_INDEX_R] = 65535 +controls_b[CONTROL_INDEX_START] = 65535 +controls_b[CONTROL_INDEX_SELECT] = 65535 +controls_b[CONTROL_INDEX_HINGE] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_UP] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 65535 +controls_b[CONTROL_INDEX_MENU] = 65535 +controls_b[CONTROL_INDEX_SAVE_STATE] = 65535 +controls_b[CONTROL_INDEX_LOAD_STATE] = 65535 +controls_b[CONTROL_INDEX_FAST_FORWARD] = 65535 +controls_b[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_A] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_B] = 65535 +controls_b[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_b[CONTROL_INDEX_QUIT] = 65535 +controls_b[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_b[CONTROL_INDEX_UI_UP] = 1217 +controls_b[CONTROL_INDEX_UI_DOWN] = 1153 +controls_b[CONTROL_INDEX_UI_LEFT] = 1216 +controls_b[CONTROL_INDEX_UI_RIGHT] = 1152 +controls_b[CONTROL_INDEX_UI_SELECT] = 1033 +controls_b[CONTROL_INDEX_UI_BACK] = 65535 +controls_b[CONTROL_INDEX_UI_EXIT] = 1032 +controls_b[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_b[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_b[CONTROL_INDEX_UI_SWITCH] = 65535 diff --git a/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg.r33s b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg.r33s new file mode 100644 index 0000000000..7b2bf24e50 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg.r33s @@ -0,0 +1,111 @@ +frameskip_type = 2 +frameskip_value = 3 +safe_frameskip = 0 +show_frame_counter = 0 +screen_orientation = 0 +screen_swap = 0 +savestate_number = 0 +fast_forward = 0 +enable_sound = 1 +clock_speed = 0 +threaded_3d = 0 +mirror_touch = 0 +compress_savestates = 1 +savestate_snapshot = 1 +unzip_roms = 0 +preload_roms = 0 +backup_in_savestates = 1 +ignore_gamecard_limit = 0 +frame_interval = 0 +trim_roms = 0 +fix_main_2d_screen = 0 +disable_edge_marking = 0 +interframe_blend = 0 +hires_3d = 1 +use_rtc_custom_time = 0 +rtc_custom_time = 0 +rtc_system_time = 0 +slot2_device_type = 0 +rumble_frames = 3 +firmware.username = Dr DraStic +firmware.language = 1 +firmware.favorite_color = 0 +firmware.birthday_month = 1 +firmware.birthday_day = 1 +enable_cheats = 1 +controls_a[CONTROL_INDEX_UP] = 1034 +controls_a[CONTROL_INDEX_DOWN] = 1035 +controls_a[CONTROL_INDEX_LEFT] = 1036 +controls_a[CONTROL_INDEX_RIGHT] = 1037 +controls_a[CONTROL_INDEX_A] = 100 +controls_a[CONTROL_INDEX_B] = 99 +controls_a[CONTROL_INDEX_X] = 122 +controls_a[CONTROL_INDEX_Y] = 118 +controls_a[CONTROL_INDEX_L] = 113 +controls_a[CONTROL_INDEX_R] = 111 +controls_a[CONTROL_INDEX_START] = 1033 +controls_a[CONTROL_INDEX_SELECT] = 101 +controls_a[CONTROL_INDEX_HINGE] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_UP] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 65535 +controls_a[CONTROL_INDEX_MENU] = 120 +controls_a[CONTROL_INDEX_SAVE_STATE] = 115 +controls_a[CONTROL_INDEX_LOAD_STATE] = 108 +controls_a[CONTROL_INDEX_FAST_FORWARD] = 116 +controls_a[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_A] = 112 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_B] = 110 +controls_a[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_a[CONTROL_INDEX_QUIT] = 65535 +controls_a[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_a[CONTROL_INDEX_UI_UP] = 338 +controls_a[CONTROL_INDEX_UI_DOWN] = 337 +controls_a[CONTROL_INDEX_UI_LEFT] = 336 +controls_a[CONTROL_INDEX_UI_RIGHT] = 335 +controls_a[CONTROL_INDEX_UI_SELECT] = 13 +controls_a[CONTROL_INDEX_UI_BACK] = 8 +controls_a[CONTROL_INDEX_UI_EXIT] = 27 +controls_a[CONTROL_INDEX_UI_PAGE_UP] = 331 +controls_a[CONTROL_INDEX_UI_PAGE_DOWN] = 334 +controls_a[CONTROL_INDEX_UI_SWITCH] = 481 +controls_b[CONTROL_INDEX_UP] = 65535 +controls_b[CONTROL_INDEX_DOWN] = 65535 +controls_b[CONTROL_INDEX_LEFT] = 65535 +controls_b[CONTROL_INDEX_RIGHT] = 65535 +controls_b[CONTROL_INDEX_A] = 65535 +controls_b[CONTROL_INDEX_B] = 65535 +controls_b[CONTROL_INDEX_X] = 65535 +controls_b[CONTROL_INDEX_Y] = 65535 +controls_b[CONTROL_INDEX_L] = 65535 +controls_b[CONTROL_INDEX_R] = 65535 +controls_b[CONTROL_INDEX_START] = 65535 +controls_b[CONTROL_INDEX_SELECT] = 65535 +controls_b[CONTROL_INDEX_HINGE] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_UP] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 65535 +controls_b[CONTROL_INDEX_MENU] = 32 +controls_b[CONTROL_INDEX_SAVE_STATE] = 65535 +controls_b[CONTROL_INDEX_LOAD_STATE] = 65535 +controls_b[CONTROL_INDEX_FAST_FORWARD] = 65535 +controls_b[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_A] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_B] = 65535 +controls_b[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_b[CONTROL_INDEX_QUIT] = 65535 +controls_b[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_b[CONTROL_INDEX_UI_UP] = 1034 +controls_b[CONTROL_INDEX_UI_DOWN] = 1035 +controls_b[CONTROL_INDEX_UI_LEFT] = 1036 +controls_b[CONTROL_INDEX_UI_RIGHT] = 1037 +controls_b[CONTROL_INDEX_UI_SELECT] = 1033 +controls_b[CONTROL_INDEX_UI_BACK] = 65535 +controls_b[CONTROL_INDEX_UI_EXIT] = 101 +controls_b[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_b[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_b[CONTROL_INDEX_UI_SWITCH] = 118 diff --git a/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg.r36s b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg.r36s new file mode 100644 index 0000000000..fac972367f --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg.r36s @@ -0,0 +1,100 @@ +frameskip_type = 2 +frameskip_value = 3 +safe_frameskip = 0 +show_frame_counter = 0 +screen_orientation = 1 +screen_swap = 0 +savestate_number = 1 +fast_forward = 0 +enable_sound = 1 +clock_speed = 0 +threaded_3d = 1 +mirror_touch = 0 +compress_savestates = 1 +savestate_snapshot = 1 +unzip_roms = 0 +preload_roms = 0 +backup_in_savestates = 1 +ignore_gamecard_limit = 0 +frame_interval = 0 +trim_roms = 0 +fix_main_2d_screen = 0 +disable_edge_marking = 0 +interframe_blend = 0 +hires_3d = 1 +use_rtc_custom_time = 0 +rtc_custom_time = 0 +rtc_system_time = 0 +slot2_device_type = 0 +rumble_frames = 3 +firmware.username = Dr DraStic +firmware.language = 1 +firmware.favorite_color = 0 +firmware.birthday_month = 1 +firmware.birthday_day = 1 +enable_cheats = 1 +controls_a[CONTROL_INDEX_UP] = 1037 +controls_a[CONTROL_INDEX_DOWN] = 1038 +controls_a[CONTROL_INDEX_LEFT] = 1039 +controls_a[CONTROL_INDEX_RIGHT] = 1040 +controls_a[CONTROL_INDEX_A] = 1025 +controls_a[CONTROL_INDEX_B] = 1024 +controls_a[CONTROL_INDEX_X] = 1026 +controls_a[CONTROL_INDEX_Y] = 1027 +controls_a[CONTROL_INDEX_L] = 1028 +controls_a[CONTROL_INDEX_R] = 1029 +controls_a[CONTROL_INDEX_START] = 1033 +controls_a[CONTROL_INDEX_SELECT] = 1032 +controls_a[CONTROL_INDEX_HINGE] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_UP] = 1219 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 1155 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 1218 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 1154 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 1036 +controls_a[CONTROL_INDEX_MENU] = 1034 +controls_a[CONTROL_INDEX_SAVE_STATE] = 65535 +controls_a[CONTROL_INDEX_LOAD_STATE] = 65535 +controls_a[CONTROL_INDEX_FAST_FORWARD] = 65535 +controls_a[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_A] = 1030 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_B] = 1031 +controls_a[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_a[CONTROL_INDEX_QUIT] = 65535 +controls_a[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_a[CONTROL_INDEX_UI_UP] = 1037 +controls_a[CONTROL_INDEX_UI_DOWN] = 1038 +controls_a[CONTROL_INDEX_UI_LEFT] = 1039 +controls_a[CONTROL_INDEX_UI_RIGHT] = 1040 +controls_a[CONTROL_INDEX_UI_SELECT] = 1025 +controls_a[CONTROL_INDEX_UI_BACK] = 1026 +controls_a[CONTROL_INDEX_UI_EXIT] = 1024 +controls_a[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_a[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_a[CONTROL_INDEX_UI_SWITCH] = 65535 +controls_b[CONTROL_INDEX_UP] = 1217 +controls_b[CONTROL_INDEX_DOWN] = 1153 +controls_b[CONTROL_INDEX_LEFT] = 1216 +controls_b[CONTROL_INDEX_RIGHT] = 1152 +controls_b[CONTROL_INDEX_A] = 65535 +controls_b[CONTROL_INDEX_B] = 65535 +controls_b[CONTROL_INDEX_X] = 65535 +controls_b[CONTROL_INDEX_Y] = 65535 +controls_b[CONTROL_INDEX_L] = 65535 +controls_b[CONTROL_INDEX_R] = 65535 +controls_b[CONTROL_INDEX_START] = 65535 +controls_b[CONTROL_INDEX_SELECT] = 65535 +controls_b[CONTROL_INDEX_HINGE] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_UP] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 65535 +controls_b[CONTROL_INDEX_MENU] = 65535 +controls_b[CONTROL_INDEX_SAVE_STATE] = 65535 +controls_b[CONTROL_INDEX_LOAD_STATE] = 65535 +controls_b[CONTROL_INDEX_FAST_FORWARD] = 65535 +controls_b[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_A] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_B] = 65535 +controls_b[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_b[CONTROL_INDEX_QUIT] = 65535 diff --git a/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg.rgb20s b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg.rgb20s new file mode 100644 index 0000000000..948b690ea0 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg.rgb20s @@ -0,0 +1,111 @@ +frameskip_type = 2 +frameskip_value = 4 +safe_frameskip = 0 +show_frame_counter = 0 +screen_orientation = 0 +screen_swap = 0 +savestate_number = 0 +fast_forward = 0 +enable_sound = 1 +clock_speed = 0 +threaded_3d = 0 +mirror_touch = 0 +compress_savestates = 1 +savestate_snapshot = 1 +unzip_roms = 0 +preload_roms = 0 +backup_in_savestates = 1 +ignore_gamecard_limit = 0 +frame_interval = 0 +trim_roms = 0 +fix_main_2d_screen = 0 +disable_edge_marking = 0 +interframe_blend = 0 +hires_3d = 0 +use_rtc_custom_time = 0 +rtc_custom_time = 0 +rtc_system_time = 0 +slot2_device_type = 0 +rumble_frames = 3 +firmware.username = Dr DraStic +firmware.language = 1 +firmware.favorite_color = 0 +firmware.birthday_month = 1 +firmware.birthday_day = 1 +enable_cheats = 1 +controls_a[CONTROL_INDEX_UP] = 1032 +controls_a[CONTROL_INDEX_DOWN] = 1033 +controls_a[CONTROL_INDEX_LEFT] = 1034 +controls_a[CONTROL_INDEX_RIGHT] = 1035 +controls_a[CONTROL_INDEX_A] = 1025 +controls_a[CONTROL_INDEX_B] = 1024 +controls_a[CONTROL_INDEX_X] = 1026 +controls_a[CONTROL_INDEX_Y] = 1027 +controls_a[CONTROL_INDEX_L] = 1028 +controls_a[CONTROL_INDEX_R] = 1029 +controls_a[CONTROL_INDEX_START] = 1037 +controls_a[CONTROL_INDEX_SELECT] = 1036 +controls_a[CONTROL_INDEX_HINGE] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_UP] = 1219 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 1155 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 1218 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 1154 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 1039 +controls_a[CONTROL_INDEX_MENU] = 1038 +controls_a[CONTROL_INDEX_SAVE_STATE] = 1031 +controls_a[CONTROL_INDEX_LOAD_STATE] = 1030 +controls_a[CONTROL_INDEX_FAST_FORWARD] = 65535 +controls_a[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_A] = 110 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_B] = 112 +controls_a[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_a[CONTROL_INDEX_QUIT] = 65535 +controls_a[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_a[CONTROL_INDEX_UI_UP] = 1032 +controls_a[CONTROL_INDEX_UI_DOWN] = 1033 +controls_a[CONTROL_INDEX_UI_LEFT] = 1034 +controls_a[CONTROL_INDEX_UI_RIGHT] = 1035 +controls_a[CONTROL_INDEX_UI_SELECT] = 1025 +controls_a[CONTROL_INDEX_UI_BACK] = 1026 +controls_a[CONTROL_INDEX_UI_EXIT] = 1024 +controls_a[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_a[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_a[CONTROL_INDEX_UI_SWITCH] = 65535 +controls_b[CONTROL_INDEX_UP] = 1217 +controls_b[CONTROL_INDEX_DOWN] = 1153 +controls_b[CONTROL_INDEX_LEFT] = 1216 +controls_b[CONTROL_INDEX_RIGHT] = 1152 +controls_b[CONTROL_INDEX_A] = 65535 +controls_b[CONTROL_INDEX_B] = 65535 +controls_b[CONTROL_INDEX_X] = 65535 +controls_b[CONTROL_INDEX_Y] = 65535 +controls_b[CONTROL_INDEX_L] = 65535 +controls_b[CONTROL_INDEX_R] = 65535 +controls_b[CONTROL_INDEX_START] = 65535 +controls_b[CONTROL_INDEX_SELECT] = 65535 +controls_b[CONTROL_INDEX_HINGE] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_UP] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 65535 +controls_b[CONTROL_INDEX_MENU] = 65535 +controls_b[CONTROL_INDEX_SAVE_STATE] = 65535 +controls_b[CONTROL_INDEX_LOAD_STATE] = 65535 +controls_b[CONTROL_INDEX_FAST_FORWARD] = 65535 +controls_b[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_A] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_B] = 65535 +controls_b[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_b[CONTROL_INDEX_QUIT] = 65535 +controls_b[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_b[CONTROL_INDEX_UI_UP] = 1217 +controls_b[CONTROL_INDEX_UI_DOWN] = 1153 +controls_b[CONTROL_INDEX_UI_LEFT] = 1216 +controls_b[CONTROL_INDEX_UI_RIGHT] = 1152 +controls_b[CONTROL_INDEX_UI_SELECT] = 1037 +controls_b[CONTROL_INDEX_UI_BACK] = 65535 +controls_b[CONTROL_INDEX_UI_EXIT] = 1036 +controls_b[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_b[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_b[CONTROL_INDEX_UI_SWITCH] = 65535 diff --git a/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg.s1_f2 b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg.s1_f2 new file mode 100644 index 0000000000..bfee20eb9b --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg.s1_f2 @@ -0,0 +1,111 @@ +frameskip_type = 2 +frameskip_value = 3 +safe_frameskip = 0 +show_frame_counter = 0 +screen_orientation = 2 +screen_swap = 0 +savestate_number = 0 +fast_forward = 0 +enable_sound = 1 +clock_speed = 0 +threaded_3d = 1 +mirror_touch = 0 +compress_savestates = 1 +savestate_snapshot = 1 +unzip_roms = 0 +preload_roms = 0 +backup_in_savestates = 1 +ignore_gamecard_limit = 0 +frame_interval = 0 +trim_roms = 0 +fix_main_2d_screen = 0 +disable_edge_marking = 0 +interframe_blend = 0 +hires_3d = 0 +use_rtc_custom_time = 0 +rtc_custom_time = 0 +rtc_system_time = 0 +slot2_device_type = 0 +rumble_frames = 3 +firmware.username = Dr DraStic +firmware.language = 1 +firmware.favorite_color = 0 +firmware.birthday_month = 1 +firmware.birthday_day = 1 +enable_cheats = 1 +controls_a[CONTROL_INDEX_UP] = 1037 +controls_a[CONTROL_INDEX_DOWN] = 1038 +controls_a[CONTROL_INDEX_LEFT] = 1039 +controls_a[CONTROL_INDEX_RIGHT] = 1040 +controls_a[CONTROL_INDEX_A] = 99 +controls_a[CONTROL_INDEX_B] = 100 +controls_a[CONTROL_INDEX_X] = 122 +controls_a[CONTROL_INDEX_Y] = 118 +controls_a[CONTROL_INDEX_L] = 113 +controls_a[CONTROL_INDEX_R] = 111 +controls_a[CONTROL_INDEX_START] = 1033 +controls_a[CONTROL_INDEX_SELECT] = 1032 +controls_a[CONTROL_INDEX_HINGE] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_UP] = 1217 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 1153 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 1216 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 1152 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 1035 +controls_a[CONTROL_INDEX_MENU] = 1034 +controls_a[CONTROL_INDEX_SAVE_STATE] = 65535 +controls_a[CONTROL_INDEX_LOAD_STATE] = 65535 +controls_a[CONTROL_INDEX_FAST_FORWARD] = 1036 +controls_a[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_A] = 1030 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_B] = 1031 +controls_a[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_a[CONTROL_INDEX_QUIT] = 65535 +controls_a[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_a[CONTROL_INDEX_UI_UP] = 1032 +controls_a[CONTROL_INDEX_UI_DOWN] = 1033 +controls_a[CONTROL_INDEX_UI_LEFT] = 1034 +controls_a[CONTROL_INDEX_UI_RIGHT] = 1035 +controls_a[CONTROL_INDEX_UI_SELECT] = 1025 +controls_a[CONTROL_INDEX_UI_BACK] = 65535 +controls_a[CONTROL_INDEX_UI_EXIT] = 1024 +controls_a[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_a[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_a[CONTROL_INDEX_UI_SWITCH] = 65535 +controls_b[CONTROL_INDEX_UP] = 65535 +controls_b[CONTROL_INDEX_DOWN] = 65535 +controls_b[CONTROL_INDEX_LEFT] = 65535 +controls_b[CONTROL_INDEX_RIGHT] = 65535 +controls_b[CONTROL_INDEX_A] = 65535 +controls_b[CONTROL_INDEX_B] = 65535 +controls_b[CONTROL_INDEX_X] = 65535 +controls_b[CONTROL_INDEX_Y] = 65535 +controls_b[CONTROL_INDEX_L] = 65535 +controls_b[CONTROL_INDEX_R] = 65535 +controls_b[CONTROL_INDEX_START] = 65535 +controls_b[CONTROL_INDEX_SELECT] = 65535 +controls_b[CONTROL_INDEX_HINGE] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_UP] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 65535 +controls_b[CONTROL_INDEX_MENU] = 65535 +controls_b[CONTROL_INDEX_SAVE_STATE] = 65535 +controls_b[CONTROL_INDEX_LOAD_STATE] = 65535 +controls_b[CONTROL_INDEX_FAST_FORWARD] = 65535 +controls_b[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_A] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_B] = 65535 +controls_b[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_b[CONTROL_INDEX_QUIT] = 65535 +controls_b[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_b[CONTROL_INDEX_UI_UP] = 1217 +controls_b[CONTROL_INDEX_UI_DOWN] = 1153 +controls_b[CONTROL_INDEX_UI_LEFT] = 1216 +controls_b[CONTROL_INDEX_UI_RIGHT] = 1152 +controls_b[CONTROL_INDEX_UI_SELECT] = 65535 +controls_b[CONTROL_INDEX_UI_BACK] = 65535 +controls_b[CONTROL_INDEX_UI_EXIT] = 65535 +controls_b[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_b[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_b[CONTROL_INDEX_UI_SWITCH] = 65535 diff --git a/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg.xut b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg.xut new file mode 100644 index 0000000000..dd6a317de3 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg.xut @@ -0,0 +1,111 @@ +frameskip_type = 2 +frameskip_value = 1 +safe_frameskip = 0 +show_frame_counter = 0 +screen_orientation = 1 +screen_swap = 0 +savestate_number = 0 +fast_forward = 0 +enable_sound = 1 +clock_speed = 0 +threaded_3d = 0 +mirror_touch = 0 +compress_savestates = 1 +savestate_snapshot = 1 +unzip_roms = 0 +preload_roms = 0 +backup_in_savestates = 1 +ignore_gamecard_limit = 0 +frame_interval = 0 +trim_roms = 0 +fix_main_2d_screen = 0 +disable_edge_marking = 0 +interframe_blend = 0 +hires_3d = 1 +use_rtc_custom_time = 0 +rtc_custom_time = 0 +rtc_system_time = 0 +slot2_device_type = 0 +rumble_frames = 3 +firmware.username = Dr DraStic +firmware.language = 1 +firmware.favorite_color = 0 +firmware.birthday_month = 1 +firmware.birthday_day = 1 +enable_cheats = 1 +controls_a[CONTROL_INDEX_UP] = 338 +controls_a[CONTROL_INDEX_DOWN] = 337 +controls_a[CONTROL_INDEX_LEFT] = 336 +controls_a[CONTROL_INDEX_RIGHT] = 335 +controls_a[CONTROL_INDEX_A] = 32 +controls_a[CONTROL_INDEX_B] = 480 +controls_a[CONTROL_INDEX_X] = 122 +controls_a[CONTROL_INDEX_Y] = 120 +controls_a[CONTROL_INDEX_L] = 481 +controls_a[CONTROL_INDEX_R] = 99 +controls_a[CONTROL_INDEX_START] = 13 +controls_a[CONTROL_INDEX_SELECT] = 485 +controls_a[CONTROL_INDEX_HINGE] = 104 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_UP] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 65535 +controls_a[CONTROL_INDEX_MENU] = 65535 +controls_a[CONTROL_INDEX_SAVE_STATE] = 65535 +controls_a[CONTROL_INDEX_LOAD_STATE] = 65535 +controls_a[CONTROL_INDEX_FAST_FORWARD] = 65535 +controls_a[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_A] = 65535 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_B] = 65535 +controls_a[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_a[CONTROL_INDEX_QUIT] = 65535 +controls_a[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_a[CONTROL_INDEX_UI_UP] = 338 +controls_a[CONTROL_INDEX_UI_DOWN] = 337 +controls_a[CONTROL_INDEX_UI_LEFT] = 336 +controls_a[CONTROL_INDEX_UI_RIGHT] = 335 +controls_a[CONTROL_INDEX_UI_SELECT] = 13 +controls_a[CONTROL_INDEX_UI_BACK] = 8 +controls_a[CONTROL_INDEX_UI_EXIT] = 27 +controls_a[CONTROL_INDEX_UI_PAGE_UP] = 331 +controls_a[CONTROL_INDEX_UI_PAGE_DOWN] = 334 +controls_a[CONTROL_INDEX_UI_SWITCH] = 481 +controls_b[CONTROL_INDEX_UP] = 1036 +controls_b[CONTROL_INDEX_DOWN] = 1037 +controls_b[CONTROL_INDEX_LEFT] = 1038 +controls_b[CONTROL_INDEX_RIGHT] = 1039 +controls_b[CONTROL_INDEX_A] = 1026 +controls_b[CONTROL_INDEX_B] = 1025 +controls_b[CONTROL_INDEX_X] = 1027 +controls_b[CONTROL_INDEX_Y] = 1024 +controls_b[CONTROL_INDEX_L] = 1028 +controls_b[CONTROL_INDEX_R] = 1029 +controls_b[CONTROL_INDEX_START] = 1033 +controls_b[CONTROL_INDEX_SELECT] = 1032 +controls_b[CONTROL_INDEX_HINGE] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_UP] = 1219 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 1155 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 1218 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 1154 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 1035 +controls_b[CONTROL_INDEX_MENU] = 1040 +controls_b[CONTROL_INDEX_SAVE_STATE] = 65535 +controls_b[CONTROL_INDEX_LOAD_STATE] = 65535 +controls_b[CONTROL_INDEX_FAST_FORWARD] = 65535 +controls_b[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_A] = 1031 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_B] = 1030 +controls_b[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_b[CONTROL_INDEX_QUIT] = 65535 +controls_b[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_b[CONTROL_INDEX_UI_UP] = 1036 +controls_b[CONTROL_INDEX_UI_DOWN] = 1037 +controls_b[CONTROL_INDEX_UI_LEFT] = 1038 +controls_b[CONTROL_INDEX_UI_RIGHT] = 1039 +controls_b[CONTROL_INDEX_UI_SELECT] = 1026 +controls_b[CONTROL_INDEX_UI_BACK] = 1025 +controls_b[CONTROL_INDEX_UI_EXIT] = 1024 +controls_b[CONTROL_INDEX_UI_PAGE_UP] = 1029 +controls_b[CONTROL_INDEX_UI_PAGE_DOWN] = 1028 +controls_b[CONTROL_INDEX_UI_SWITCH] = 1027 diff --git a/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3399/drastic.cfg b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3399/drastic.cfg new file mode 100644 index 0000000000..bf348a0155 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3399/drastic.cfg @@ -0,0 +1,111 @@ +frameskip_type = 0 +frameskip_value = 4 +safe_frameskip = 0 +show_frame_counter = 0 +screen_orientation = 0 +screen_swap = 0 +savestate_number = 0 +fast_forward = 0 +enable_sound = 1 +clock_speed = 0 +threaded_3d = 0 +mirror_touch = 0 +compress_savestates = 1 +savestate_snapshot = 1 +unzip_roms = 0 +preload_roms = 0 +backup_in_savestates = 1 +ignore_gamecard_limit = 0 +frame_interval = 0 +trim_roms = 0 +fix_main_2d_screen = 0 +disable_edge_marking = 0 +interframe_blend = 0 +hires_3d = 1 +use_rtc_custom_time = 0 +rtc_custom_time = 0 +rtc_system_time = 0 +slot2_device_type = 0 +rumble_frames = 3 +firmware.username = Dr DraStic +firmware.language = 1 +firmware.favorite_color = 0 +firmware.birthday_month = 1 +firmware.birthday_day = 1 +enable_cheats = 1 +controls_a[CONTROL_INDEX_UP] = 1217 +controls_a[CONTROL_INDEX_DOWN] = 1153 +controls_a[CONTROL_INDEX_LEFT] = 1216 +controls_a[CONTROL_INDEX_RIGHT] = 1152 +controls_a[CONTROL_INDEX_A] = 65535 +controls_a[CONTROL_INDEX_B] = 65535 +controls_a[CONTROL_INDEX_X] = 65535 +controls_a[CONTROL_INDEX_Y] = 65535 +controls_a[CONTROL_INDEX_L] = 65535 +controls_a[CONTROL_INDEX_R] = 65535 +controls_a[CONTROL_INDEX_START] = 65535 +controls_a[CONTROL_INDEX_SELECT] = 65535 +controls_a[CONTROL_INDEX_HINGE] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_UP] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 65535 +controls_a[CONTROL_INDEX_MENU] = 120 +controls_a[CONTROL_INDEX_SAVE_STATE] = 115 +controls_a[CONTROL_INDEX_LOAD_STATE] = 108 +controls_a[CONTROL_INDEX_FAST_FORWARD] = 116 +controls_a[CONTROL_INDEX_SWAP_SCREENS] = 109 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_A] = 65535 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_B] = 65535 +controls_a[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_a[CONTROL_INDEX_QUIT] = 65535 +controls_a[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_a[CONTROL_INDEX_UI_UP] = 1217 +controls_a[CONTROL_INDEX_UI_DOWN] = 1153 +controls_a[CONTROL_INDEX_UI_LEFT] = 1216 +controls_a[CONTROL_INDEX_UI_RIGHT] = 1152 +controls_a[CONTROL_INDEX_UI_SELECT] = 65535 +controls_a[CONTROL_INDEX_UI_BACK] = 65535 +controls_a[CONTROL_INDEX_UI_EXIT] = 65535 +controls_a[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_a[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_a[CONTROL_INDEX_UI_SWITCH] = 65535 +controls_b[CONTROL_INDEX_UP] = 1037 +controls_b[CONTROL_INDEX_DOWN] = 1038 +controls_b[CONTROL_INDEX_LEFT] = 1039 +controls_b[CONTROL_INDEX_RIGHT] = 1040 +controls_b[CONTROL_INDEX_A] = 1025 +controls_b[CONTROL_INDEX_B] = 1024 +controls_b[CONTROL_INDEX_X] = 1026 +controls_b[CONTROL_INDEX_Y] = 1027 +controls_b[CONTROL_INDEX_L] = 1028 +controls_b[CONTROL_INDEX_R] = 1029 +controls_b[CONTROL_INDEX_START] = 1033 +controls_b[CONTROL_INDEX_SELECT] = 1032 +controls_b[CONTROL_INDEX_HINGE] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_UP] = 1219 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 1155 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 1218 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 1154 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 1036 +controls_b[CONTROL_INDEX_MENU] = 1035 +controls_b[CONTROL_INDEX_SAVE_STATE] = 65535 +controls_b[CONTROL_INDEX_LOAD_STATE] = 65535 +controls_b[CONTROL_INDEX_FAST_FORWARD] = 65535 +controls_b[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_A] = 1030 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_B] = 1031 +controls_b[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_b[CONTROL_INDEX_QUIT] = 65535 +controls_b[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_b[CONTROL_INDEX_UI_UP] = 1037 +controls_b[CONTROL_INDEX_UI_DOWN] = 1038 +controls_b[CONTROL_INDEX_UI_LEFT] = 1039 +controls_b[CONTROL_INDEX_UI_RIGHT] = 1040 +controls_b[CONTROL_INDEX_UI_SELECT] = 1025 +controls_b[CONTROL_INDEX_UI_BACK] = 65535 +controls_b[CONTROL_INDEX_UI_EXIT] = 1024 +controls_b[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_b[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_b[CONTROL_INDEX_UI_SWITCH] = 65535 diff --git a/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3566/drastic.cfg b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3566/drastic.cfg new file mode 100644 index 0000000000..83c8ed1cf8 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3566/drastic.cfg @@ -0,0 +1,111 @@ +frameskip_type = 0 +frameskip_value = 1 +safe_frameskip = 1 +show_frame_counter = 0 +screen_orientation = 0 +screen_swap = 0 +savestate_number = 0 +fast_forward = 0 +enable_sound = 1 +clock_speed = 0 +threaded_3d = 1 +mirror_touch = 0 +compress_savestates = 1 +savestate_snapshot = 1 +unzip_roms = 0 +preload_roms = 0 +backup_in_savestates = 1 +ignore_gamecard_limit = 0 +frame_interval = 0 +trim_roms = 0 +fix_main_2d_screen = 0 +disable_edge_marking = 0 +interframe_blend = 0 +hires_3d = 1 +use_rtc_custom_time = 0 +rtc_custom_time = 0 +rtc_system_time = 0 +slot2_device_type = 0 +rumble_frames = 3 +firmware.username = Dr DraStic +firmware.language = 1 +firmware.favorite_color = 0 +firmware.birthday_month = 1 +firmware.birthday_day = 1 +enable_cheats = 1 +controls_a[CONTROL_INDEX_UP] = 1217 +controls_a[CONTROL_INDEX_DOWN] = 1153 +controls_a[CONTROL_INDEX_LEFT] = 1216 +controls_a[CONTROL_INDEX_RIGHT] = 1152 +controls_a[CONTROL_INDEX_A] = 65535 +controls_a[CONTROL_INDEX_B] = 65535 +controls_a[CONTROL_INDEX_X] = 65535 +controls_a[CONTROL_INDEX_Y] = 65535 +controls_a[CONTROL_INDEX_L] = 65535 +controls_a[CONTROL_INDEX_R] = 65535 +controls_a[CONTROL_INDEX_START] = 65535 +controls_a[CONTROL_INDEX_SELECT] = 65535 +controls_a[CONTROL_INDEX_HINGE] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_UP] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 65535 +controls_a[CONTROL_INDEX_MENU] = 65535 +controls_a[CONTROL_INDEX_SAVE_STATE] = 65535 +controls_a[CONTROL_INDEX_LOAD_STATE] = 65535 +controls_a[CONTROL_INDEX_FAST_FORWARD] = 65535 +controls_a[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_A] = 65535 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_B] = 65535 +controls_a[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_a[CONTROL_INDEX_QUIT] = 65535 +controls_a[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_a[CONTROL_INDEX_UI_UP] = 1217 +controls_a[CONTROL_INDEX_UI_DOWN] = 1153 +controls_a[CONTROL_INDEX_UI_LEFT] = 1216 +controls_a[CONTROL_INDEX_UI_RIGHT] = 1152 +controls_a[CONTROL_INDEX_UI_SELECT] = 65535 +controls_a[CONTROL_INDEX_UI_BACK] = 65535 +controls_a[CONTROL_INDEX_UI_EXIT] = 65535 +controls_a[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_a[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_a[CONTROL_INDEX_UI_SWITCH] = 65535 +controls_b[CONTROL_INDEX_UP] = 1037 +controls_b[CONTROL_INDEX_DOWN] = 1038 +controls_b[CONTROL_INDEX_LEFT] = 1039 +controls_b[CONTROL_INDEX_RIGHT] = 1040 +controls_b[CONTROL_INDEX_A] = 1025 +controls_b[CONTROL_INDEX_B] = 1024 +controls_b[CONTROL_INDEX_X] = 1026 +controls_b[CONTROL_INDEX_Y] = 1027 +controls_b[CONTROL_INDEX_L] = 1028 +controls_b[CONTROL_INDEX_R] = 1029 +controls_b[CONTROL_INDEX_START] = 1033 +controls_b[CONTROL_INDEX_SELECT] = 1032 +controls_b[CONTROL_INDEX_HINGE] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_UP] = 1219 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 1155 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 1218 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 1154 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 1036 +controls_b[CONTROL_INDEX_MENU] = 1035 +controls_b[CONTROL_INDEX_SAVE_STATE] = 65535 +controls_b[CONTROL_INDEX_LOAD_STATE] = 65535 +controls_b[CONTROL_INDEX_FAST_FORWARD] = 65535 +controls_b[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_A] = 1030 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_B] = 1031 +controls_b[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_b[CONTROL_INDEX_QUIT] = 65535 +controls_b[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_b[CONTROL_INDEX_UI_UP] = 1037 +controls_b[CONTROL_INDEX_UI_DOWN] = 1038 +controls_b[CONTROL_INDEX_UI_LEFT] = 1039 +controls_b[CONTROL_INDEX_UI_RIGHT] = 1040 +controls_b[CONTROL_INDEX_UI_SELECT] = 1025 +controls_b[CONTROL_INDEX_UI_BACK] = 65535 +controls_b[CONTROL_INDEX_UI_EXIT] = 1024 +controls_b[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_b[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_b[CONTROL_INDEX_UI_SWITCH] = 65535 diff --git a/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3566/drastic.cfg.arc b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3566/drastic.cfg.arc new file mode 100644 index 0000000000..3c98537dcd --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3566/drastic.cfg.arc @@ -0,0 +1,111 @@ +frameskip_type = 0 +frameskip_value = 1 +safe_frameskip = 1 +show_frame_counter = 0 +screen_orientation = 3 +screen_swap = 0 +savestate_number = 0 +fast_forward = 0 +enable_sound = 1 +clock_speed = 0 +threaded_3d = 1 +mirror_touch = 0 +compress_savestates = 1 +savestate_snapshot = 1 +unzip_roms = 0 +preload_roms = 0 +backup_in_savestates = 1 +ignore_gamecard_limit = 0 +frame_interval = 0 +trim_roms = 0 +fix_main_2d_screen = 0 +disable_edge_marking = 0 +interframe_blend = 0 +hires_3d = 1 +use_rtc_custom_time = 0 +rtc_custom_time = 0 +rtc_system_time = 0 +slot2_device_type = 0 +rumble_frames = 3 +firmware.username = Dr DraStic +firmware.language = 1 +firmware.favorite_color = 0 +firmware.birthday_month = 1 +firmware.birthday_day = 1 +enable_cheats = 1 +controls_a[CONTROL_INDEX_UP] = 1036 +controls_a[CONTROL_INDEX_DOWN] = 1037 +controls_a[CONTROL_INDEX_LEFT] = 1038 +controls_a[CONTROL_INDEX_RIGHT] = 1039 +controls_a[CONTROL_INDEX_A] = 100 +controls_a[CONTROL_INDEX_B] = 99 +controls_a[CONTROL_INDEX_X] = 122 +controls_a[CONTROL_INDEX_Y] = 118 +controls_a[CONTROL_INDEX_L] = 113 +controls_a[CONTROL_INDEX_R] = 111 +controls_a[CONTROL_INDEX_START] = 1035 +controls_a[CONTROL_INDEX_SELECT] = 1034 +controls_a[CONTROL_INDEX_HINGE] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_UP] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 65535 +controls_a[CONTROL_INDEX_MENU] = 1029 +controls_a[CONTROL_INDEX_SAVE_STATE] = 65535 +controls_a[CONTROL_INDEX_LOAD_STATE] = 65535 +controls_a[CONTROL_INDEX_FAST_FORWARD] = 65535 +controls_a[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_A] = 110 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_B] = 112 +controls_a[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_a[CONTROL_INDEX_QUIT] = 65535 +controls_a[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_a[CONTROL_INDEX_UI_UP] = 1036 +controls_a[CONTROL_INDEX_UI_DOWN] = 1037 +controls_a[CONTROL_INDEX_UI_LEFT] = 1038 +controls_a[CONTROL_INDEX_UI_RIGHT] = 1039 +controls_a[CONTROL_INDEX_UI_SELECT] = 1024 +controls_a[CONTROL_INDEX_UI_BACK] = 65535 +controls_a[CONTROL_INDEX_UI_EXIT] = 65535 +controls_a[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_a[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_a[CONTROL_INDEX_UI_SWITCH] = 65535 +controls_b[CONTROL_INDEX_UP] = 1036 +controls_b[CONTROL_INDEX_DOWN] = 1037 +controls_b[CONTROL_INDEX_LEFT] = 1038 +controls_b[CONTROL_INDEX_RIGHT] = 1039 +controls_b[CONTROL_INDEX_A] = 100 +controls_b[CONTROL_INDEX_B] = 99 +controls_b[CONTROL_INDEX_X] = 122 +controls_b[CONTROL_INDEX_Y] = 118 +controls_b[CONTROL_INDEX_L] = 113 +controls_b[CONTROL_INDEX_R] = 111 +controls_b[CONTROL_INDEX_START] = 1035 +controls_b[CONTROL_INDEX_SELECT] = 1034 +controls_b[CONTROL_INDEX_HINGE] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_UP] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 65535 +controls_b[CONTROL_INDEX_MENU] = 1029 +controls_b[CONTROL_INDEX_SAVE_STATE] = 65535 +controls_b[CONTROL_INDEX_LOAD_STATE] = 65535 +controls_b[CONTROL_INDEX_FAST_FORWARD] = 65535 +controls_b[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_A] = 110 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_B] = 112 +controls_b[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_b[CONTROL_INDEX_QUIT] = 65535 +controls_b[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_b[CONTROL_INDEX_UI_UP] = 1036 +controls_b[CONTROL_INDEX_UI_DOWN] = 1037 +controls_b[CONTROL_INDEX_UI_LEFT] = 1038 +controls_b[CONTROL_INDEX_UI_RIGHT] = 1039 +controls_b[CONTROL_INDEX_UI_SELECT] = 65535 +controls_b[CONTROL_INDEX_UI_BACK] = 65535 +controls_b[CONTROL_INDEX_UI_EXIT] = 65535 +controls_b[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_b[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_b[CONTROL_INDEX_UI_SWITCH] = 65535 diff --git a/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3566/drastic.cfg.rgds b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3566/drastic.cfg.rgds new file mode 100644 index 0000000000..dc74b4d149 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3566/drastic.cfg.rgds @@ -0,0 +1,111 @@ +frameskip_type = 0 +frameskip_value = 1 +safe_frameskip = 1 +show_frame_counter = 0 +screen_orientation = 1 +screen_swap = 0 +savestate_number = 0 +fast_forward = 0 +enable_sound = 1 +clock_speed = 0 +threaded_3d = 0 +mirror_touch = 0 +compress_savestates = 1 +savestate_snapshot = 1 +unzip_roms = 0 +preload_roms = 0 +backup_in_savestates = 1 +ignore_gamecard_limit = 0 +frame_interval = 0 +trim_roms = 0 +fix_main_2d_screen = 0 +disable_edge_marking = 0 +interframe_blend = 0 +hires_3d = 0 +use_rtc_custom_time = 0 +rtc_custom_time = 0 +rtc_system_time = 0 +slot2_device_type = 0 +rumble_frames = 3 +firmware.username = Dr DraStic +firmware.language = 1 +firmware.favorite_color = 0 +firmware.birthday_month = 1 +firmware.birthday_day = 1 +enable_cheats = 1 +controls_a[CONTROL_INDEX_UP] = 1217 +controls_a[CONTROL_INDEX_DOWN] = 1153 +controls_a[CONTROL_INDEX_LEFT] = 1216 +controls_a[CONTROL_INDEX_RIGHT] = 1152 +controls_a[CONTROL_INDEX_A] = 65535 +controls_a[CONTROL_INDEX_B] = 65535 +controls_a[CONTROL_INDEX_X] = 65535 +controls_a[CONTROL_INDEX_Y] = 65535 +controls_a[CONTROL_INDEX_L] = 65535 +controls_a[CONTROL_INDEX_R] = 65535 +controls_a[CONTROL_INDEX_START] = 65535 +controls_a[CONTROL_INDEX_SELECT] = 65535 +controls_a[CONTROL_INDEX_HINGE] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_UP] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 65535 +controls_a[CONTROL_INDEX_MENU] = 1035 +controls_a[CONTROL_INDEX_SAVE_STATE] = 1031 +controls_a[CONTROL_INDEX_LOAD_STATE] = 1030 +controls_a[CONTROL_INDEX_FAST_FORWARD] = 1036 +controls_a[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_A] = 65535 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_B] = 65535 +controls_a[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_a[CONTROL_INDEX_QUIT] = 65535 +controls_a[CONTROL_INDEX_FAKE_MICROPHONE] = 327 +controls_a[CONTROL_INDEX_UI_UP] = 1217 +controls_a[CONTROL_INDEX_UI_DOWN] = 1153 +controls_a[CONTROL_INDEX_UI_LEFT] = 1216 +controls_a[CONTROL_INDEX_UI_RIGHT] = 1152 +controls_a[CONTROL_INDEX_UI_SELECT] = 65535 +controls_a[CONTROL_INDEX_UI_BACK] = 65535 +controls_a[CONTROL_INDEX_UI_EXIT] = 65535 +controls_a[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_a[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_a[CONTROL_INDEX_UI_SWITCH] = 65535 +controls_b[CONTROL_INDEX_UP] = 1037 +controls_b[CONTROL_INDEX_DOWN] = 1038 +controls_b[CONTROL_INDEX_LEFT] = 1039 +controls_b[CONTROL_INDEX_RIGHT] = 1040 +controls_b[CONTROL_INDEX_A] = 1025 +controls_b[CONTROL_INDEX_B] = 1024 +controls_b[CONTROL_INDEX_X] = 1026 +controls_b[CONTROL_INDEX_Y] = 1027 +controls_b[CONTROL_INDEX_L] = 1028 +controls_b[CONTROL_INDEX_R] = 1029 +controls_b[CONTROL_INDEX_START] = 1033 +controls_b[CONTROL_INDEX_SELECT] = 1032 +controls_b[CONTROL_INDEX_HINGE] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_UP] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 65535 +controls_b[CONTROL_INDEX_MENU] = 1035 +controls_b[CONTROL_INDEX_SAVE_STATE] = 1031 +controls_b[CONTROL_INDEX_LOAD_STATE] = 1030 +controls_b[CONTROL_INDEX_FAST_FORWARD] = 1036 +controls_b[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_A] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_B] = 65535 +controls_b[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_b[CONTROL_INDEX_QUIT] = 65535 +controls_b[CONTROL_INDEX_FAKE_MICROPHONE] = 327 +controls_b[CONTROL_INDEX_UI_UP] = 1037 +controls_b[CONTROL_INDEX_UI_DOWN] = 1038 +controls_b[CONTROL_INDEX_UI_LEFT] = 1039 +controls_b[CONTROL_INDEX_UI_RIGHT] = 1040 +controls_b[CONTROL_INDEX_UI_SELECT] = 1025 +controls_b[CONTROL_INDEX_UI_BACK] = 65535 +controls_b[CONTROL_INDEX_UI_EXIT] = 1024 +controls_b[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_b[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_b[CONTROL_INDEX_UI_SWITCH] = 65535 diff --git a/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3588/drastic.cfg b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3588/drastic.cfg new file mode 100644 index 0000000000..2faa194290 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/RK3588/drastic.cfg @@ -0,0 +1,111 @@ +frameskip_type = 0 +frameskip_value = 4 +safe_frameskip = 0 +show_frame_counter = 0 +screen_orientation = 1 +screen_swap = 0 +savestate_number = 0 +fast_forward = 0 +enable_sound = 1 +clock_speed = 0 +threaded_3d = 0 +mirror_touch = 0 +compress_savestates = 1 +savestate_snapshot = 1 +unzip_roms = 0 +preload_roms = 0 +backup_in_savestates = 1 +ignore_gamecard_limit = 0 +frame_interval = 0 +trim_roms = 0 +fix_main_2d_screen = 0 +disable_edge_marking = 0 +interframe_blend = 0 +hires_3d = 1 +use_rtc_custom_time = 0 +rtc_custom_time = 0 +rtc_system_time = 0 +slot2_device_type = 0 +rumble_frames = 3 +firmware.username = Dr DraStic +firmware.language = 1 +firmware.favorite_color = 0 +firmware.birthday_month = 1 +firmware.birthday_day = 1 +enable_cheats = 1 +controls_a[CONTROL_INDEX_UP] = 338 +controls_a[CONTROL_INDEX_DOWN] = 337 +controls_a[CONTROL_INDEX_LEFT] = 336 +controls_a[CONTROL_INDEX_RIGHT] = 335 +controls_a[CONTROL_INDEX_A] = 32 +controls_a[CONTROL_INDEX_B] = 480 +controls_a[CONTROL_INDEX_X] = 122 +controls_a[CONTROL_INDEX_Y] = 120 +controls_a[CONTROL_INDEX_L] = 113 +controls_a[CONTROL_INDEX_R] = 111 +controls_a[CONTROL_INDEX_START] = 13 +controls_a[CONTROL_INDEX_SELECT] = 485 +controls_a[CONTROL_INDEX_HINGE] = 104 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_UP] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 65535 +controls_a[CONTROL_INDEX_MENU] = 27 +controls_a[CONTROL_INDEX_SAVE_STATE] = 115 +controls_a[CONTROL_INDEX_LOAD_STATE] = 108 +controls_a[CONTROL_INDEX_FAST_FORWARD] = 116 +controls_a[CONTROL_INDEX_SWAP_SCREENS] = 109 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_A] = 1026 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_B] = 65535 +controls_a[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_a[CONTROL_INDEX_QUIT] = 65535 +controls_a[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_a[CONTROL_INDEX_UI_UP] = 338 +controls_a[CONTROL_INDEX_UI_DOWN] = 337 +controls_a[CONTROL_INDEX_UI_LEFT] = 336 +controls_a[CONTROL_INDEX_UI_RIGHT] = 335 +controls_a[CONTROL_INDEX_UI_SELECT] = 13 +controls_a[CONTROL_INDEX_UI_BACK] = 8 +controls_a[CONTROL_INDEX_UI_EXIT] = 27 +controls_a[CONTROL_INDEX_UI_PAGE_UP] = 331 +controls_a[CONTROL_INDEX_UI_PAGE_DOWN] = 334 +controls_a[CONTROL_INDEX_UI_SWITCH] = 481 +controls_b[CONTROL_INDEX_UP] = 1036 +controls_b[CONTROL_INDEX_DOWN] = 1037 +controls_b[CONTROL_INDEX_LEFT] = 1038 +controls_b[CONTROL_INDEX_RIGHT] = 1039 +controls_b[CONTROL_INDEX_A] = 1025 +controls_b[CONTROL_INDEX_B] = 1024 +controls_b[CONTROL_INDEX_X] = 1027 +controls_b[CONTROL_INDEX_Y] = 1028 +controls_b[CONTROL_INDEX_L] = 1218 +controls_b[CONTROL_INDEX_R] = 1221 +controls_b[CONTROL_INDEX_START] = 1032 +controls_b[CONTROL_INDEX_SELECT] = 1031 +controls_b[CONTROL_INDEX_HINGE] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_UP] = 1220 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 1156 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 1219 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 1155 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 1035 +controls_b[CONTROL_INDEX_MENU] = 120 +controls_b[CONTROL_INDEX_SAVE_STATE] = 65535 +controls_b[CONTROL_INDEX_LOAD_STATE] = 65535 +controls_b[CONTROL_INDEX_FAST_FORWARD] = 65535 +controls_b[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_A] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_B] = 65535 +controls_b[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_b[CONTROL_INDEX_QUIT] = 65535 +controls_b[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_b[CONTROL_INDEX_UI_UP] = 1036 +controls_b[CONTROL_INDEX_UI_DOWN] = 1037 +controls_b[CONTROL_INDEX_UI_LEFT] = 1038 +controls_b[CONTROL_INDEX_UI_RIGHT] = 1039 +controls_b[CONTROL_INDEX_UI_SELECT] = 1025 +controls_b[CONTROL_INDEX_UI_BACK] = 1027 +controls_b[CONTROL_INDEX_UI_EXIT] = 1024 +controls_b[CONTROL_INDEX_UI_PAGE_UP] = 1152 +controls_b[CONTROL_INDEX_UI_PAGE_DOWN] = 1216 +controls_b[CONTROL_INDEX_UI_SWITCH] = 1026 diff --git a/projects/ArchR/packages/emulators/standalone/drastic-sa/config/S922X/drastic.cfg b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/S922X/drastic.cfg new file mode 100644 index 0000000000..791068a137 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/S922X/drastic.cfg @@ -0,0 +1,111 @@ +frameskip_type = 0 +frameskip_value = 1 +safe_frameskip = 1 +show_frame_counter = 0 +screen_orientation = 1 +screen_swap = 0 +savestate_number = 0 +fast_forward = 0 +enable_sound = 1 +clock_speed = 0 +threaded_3d = 1 +mirror_touch = 0 +compress_savestates = 1 +savestate_snapshot = 1 +unzip_roms = 0 +preload_roms = 0 +backup_in_savestates = 1 +ignore_gamecard_limit = 0 +frame_interval = 0 +trim_roms = 0 +fix_main_2d_screen = 0 +disable_edge_marking = 0 +interframe_blend = 0 +hires_3d = 1 +use_rtc_custom_time = 0 +rtc_custom_time = 0 +rtc_system_time = 0 +slot2_device_type = 0 +rumble_frames = 3 +firmware.username = Dr DraStic +firmware.language = 1 +firmware.favorite_color = 0 +firmware.birthday_month = 1 +firmware.birthday_day = 1 +enable_cheats = 1 +controls_a[CONTROL_INDEX_UP] = 1217 +controls_a[CONTROL_INDEX_DOWN] = 1153 +controls_a[CONTROL_INDEX_LEFT] = 1216 +controls_a[CONTROL_INDEX_RIGHT] = 1152 +controls_a[CONTROL_INDEX_A] = 65535 +controls_a[CONTROL_INDEX_B] = 65535 +controls_a[CONTROL_INDEX_X] = 65535 +controls_a[CONTROL_INDEX_Y] = 65535 +controls_a[CONTROL_INDEX_L] = 65535 +controls_a[CONTROL_INDEX_R] = 65535 +controls_a[CONTROL_INDEX_START] = 65535 +controls_a[CONTROL_INDEX_SELECT] = 65535 +controls_a[CONTROL_INDEX_HINGE] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_UP] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 65535 +controls_a[CONTROL_INDEX_MENU] = 1026 +controls_a[CONTROL_INDEX_SAVE_STATE] = 65535 +controls_a[CONTROL_INDEX_LOAD_STATE] = 65535 +controls_a[CONTROL_INDEX_FAST_FORWARD] = 65535 +controls_a[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_A] = 65535 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_B] = 65535 +controls_a[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_a[CONTROL_INDEX_QUIT] = 65535 +controls_a[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_a[CONTROL_INDEX_UI_UP] = 1038 +controls_a[CONTROL_INDEX_UI_DOWN] = 1039 +controls_a[CONTROL_INDEX_UI_LEFT] = 1040 +controls_a[CONTROL_INDEX_UI_RIGHT] = 1041 +controls_a[CONTROL_INDEX_UI_SELECT] = 65535 +controls_a[CONTROL_INDEX_UI_BACK] = 65535 +controls_a[CONTROL_INDEX_UI_EXIT] = 65535 +controls_a[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_a[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_a[CONTROL_INDEX_UI_SWITCH] = 65535 +controls_b[CONTROL_INDEX_UP] = 1038 +controls_b[CONTROL_INDEX_DOWN] = 1039 +controls_b[CONTROL_INDEX_LEFT] = 1040 +controls_b[CONTROL_INDEX_RIGHT] = 1041 +controls_b[CONTROL_INDEX_A] = 1025 +controls_b[CONTROL_INDEX_B] = 1024 +controls_b[CONTROL_INDEX_X] = 1027 +controls_b[CONTROL_INDEX_Y] = 1028 +controls_b[CONTROL_INDEX_L] = 1029 +controls_b[CONTROL_INDEX_R] = 1030 +controls_b[CONTROL_INDEX_START] = 1034 +controls_b[CONTROL_INDEX_SELECT] = 1033 +controls_b[CONTROL_INDEX_HINGE] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_UP] = 1219 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 1155 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 1218 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 1154 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 1037 +controls_b[CONTROL_INDEX_MENU] = 1026 +controls_b[CONTROL_INDEX_SAVE_STATE] = 115 +controls_b[CONTROL_INDEX_LOAD_STATE] = 108 +controls_b[CONTROL_INDEX_FAST_FORWARD] = 116 +controls_b[CONTROL_INDEX_SWAP_SCREENS] = 109 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_A] = 1031 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_B] = 1032 +controls_b[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_b[CONTROL_INDEX_QUIT] = 65535 +controls_b[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_b[CONTROL_INDEX_UI_UP] = 1217 +controls_b[CONTROL_INDEX_UI_DOWN] = 1153 +controls_b[CONTROL_INDEX_UI_LEFT] = 1216 +controls_b[CONTROL_INDEX_UI_RIGHT] = 1152 +controls_b[CONTROL_INDEX_UI_SELECT] = 1025 +controls_b[CONTROL_INDEX_UI_BACK] = 65535 +controls_b[CONTROL_INDEX_UI_EXIT] = 1024 +controls_b[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_b[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_b[CONTROL_INDEX_UI_SWITCH] = 65535 diff --git a/projects/ArchR/packages/emulators/standalone/drastic-sa/config/SM8250/drastic.cfg b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/SM8250/drastic.cfg new file mode 100644 index 0000000000..af4dd6cc80 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/SM8250/drastic.cfg @@ -0,0 +1,111 @@ +frameskip_type = 0 +frameskip_value = 4 +safe_frameskip = 0 +show_frame_counter = 0 +screen_orientation = 0 +screen_swap = 0 +savestate_number = 0 +fast_forward = 0 +enable_sound = 1 +clock_speed = 0 +threaded_3d = 0 +mirror_touch = 0 +compress_savestates = 1 +savestate_snapshot = 1 +unzip_roms = 0 +preload_roms = 0 +backup_in_savestates = 1 +ignore_gamecard_limit = 0 +frame_interval = 0 +trim_roms = 0 +fix_main_2d_screen = 0 +disable_edge_marking = 0 +interframe_blend = 0 +hires_3d = 1 +use_rtc_custom_time = 0 +rtc_custom_time = 0 +rtc_system_time = 0 +slot2_device_type = 0 +rumble_frames = 3 +firmware.username = Dr DraStic +firmware.language = 1 +firmware.favorite_color = 0 +firmware.birthday_month = 1 +firmware.birthday_day = 1 +enable_cheats = 1 +controls_a[CONTROL_INDEX_UP] = 1035 +controls_a[CONTROL_INDEX_DOWN] = 1036 +controls_a[CONTROL_INDEX_LEFT] = 1037 +controls_a[CONTROL_INDEX_RIGHT] = 1038 +controls_a[CONTROL_INDEX_A] = 65535 +controls_a[CONTROL_INDEX_B] = 65535 +controls_a[CONTROL_INDEX_X] = 65535 +controls_a[CONTROL_INDEX_Y] = 65535 +controls_a[CONTROL_INDEX_L] = 65535 +controls_a[CONTROL_INDEX_R] = 65535 +controls_a[CONTROL_INDEX_START] = 65535 +controls_a[CONTROL_INDEX_SELECT] = 65535 +controls_a[CONTROL_INDEX_HINGE] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_UP] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 65535 +controls_a[CONTROL_INDEX_MENU] = 1032 +controls_a[CONTROL_INDEX_SAVE_STATE] = 115 +controls_a[CONTROL_INDEX_LOAD_STATE] = 108 +controls_a[CONTROL_INDEX_FAST_FORWARD] = 116 +controls_a[CONTROL_INDEX_SWAP_SCREENS] = 1039 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_A] = 110 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_B] = 112 +controls_a[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_a[CONTROL_INDEX_QUIT] = 65535 +controls_a[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_a[CONTROL_INDEX_UI_UP] = 1035 +controls_a[CONTROL_INDEX_UI_DOWN] = 1036 +controls_a[CONTROL_INDEX_UI_LEFT] = 1037 +controls_a[CONTROL_INDEX_UI_RIGHT] = 1038 +controls_a[CONTROL_INDEX_UI_SELECT] = 65535 +controls_a[CONTROL_INDEX_UI_BACK] = 65535 +controls_a[CONTROL_INDEX_UI_EXIT] = 65535 +controls_a[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_a[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_a[CONTROL_INDEX_UI_SWITCH] = 65535 +controls_b[CONTROL_INDEX_UP] = 1217 +controls_b[CONTROL_INDEX_DOWN] = 1153 +controls_b[CONTROL_INDEX_LEFT] = 1216 +controls_b[CONTROL_INDEX_RIGHT] = 1152 +controls_b[CONTROL_INDEX_A] = 1025 +controls_b[CONTROL_INDEX_B] = 1024 +controls_b[CONTROL_INDEX_X] = 1026 +controls_b[CONTROL_INDEX_Y] = 1027 +controls_b[CONTROL_INDEX_L] = 1028 +controls_b[CONTROL_INDEX_R] = 1029 +controls_b[CONTROL_INDEX_START] = 1031 +controls_b[CONTROL_INDEX_SELECT] = 1030 +controls_b[CONTROL_INDEX_HINGE] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_UP] = 1220 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 1156 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 1219 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 1155 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 1034 +controls_b[CONTROL_INDEX_MENU] = 120 +controls_b[CONTROL_INDEX_SAVE_STATE] = 65535 +controls_b[CONTROL_INDEX_LOAD_STATE] = 65535 +controls_b[CONTROL_INDEX_FAST_FORWARD] = 65535 +controls_b[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_A] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_B] = 65535 +controls_b[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_b[CONTROL_INDEX_QUIT] = 65535 +controls_b[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_b[CONTROL_INDEX_UI_UP] = 1217 +controls_b[CONTROL_INDEX_UI_DOWN] = 1153 +controls_b[CONTROL_INDEX_UI_LEFT] = 1216 +controls_b[CONTROL_INDEX_UI_RIGHT] = 1152 +controls_b[CONTROL_INDEX_UI_SELECT] = 1025 +controls_b[CONTROL_INDEX_UI_BACK] = 65535 +controls_b[CONTROL_INDEX_UI_EXIT] = 1024 +controls_b[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_b[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_b[CONTROL_INDEX_UI_SWITCH] = 65535 diff --git a/projects/ArchR/packages/emulators/standalone/drastic-sa/config/SM8550/drastic.cfg b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/SM8550/drastic.cfg new file mode 100644 index 0000000000..af4dd6cc80 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/SM8550/drastic.cfg @@ -0,0 +1,111 @@ +frameskip_type = 0 +frameskip_value = 4 +safe_frameskip = 0 +show_frame_counter = 0 +screen_orientation = 0 +screen_swap = 0 +savestate_number = 0 +fast_forward = 0 +enable_sound = 1 +clock_speed = 0 +threaded_3d = 0 +mirror_touch = 0 +compress_savestates = 1 +savestate_snapshot = 1 +unzip_roms = 0 +preload_roms = 0 +backup_in_savestates = 1 +ignore_gamecard_limit = 0 +frame_interval = 0 +trim_roms = 0 +fix_main_2d_screen = 0 +disable_edge_marking = 0 +interframe_blend = 0 +hires_3d = 1 +use_rtc_custom_time = 0 +rtc_custom_time = 0 +rtc_system_time = 0 +slot2_device_type = 0 +rumble_frames = 3 +firmware.username = Dr DraStic +firmware.language = 1 +firmware.favorite_color = 0 +firmware.birthday_month = 1 +firmware.birthday_day = 1 +enable_cheats = 1 +controls_a[CONTROL_INDEX_UP] = 1035 +controls_a[CONTROL_INDEX_DOWN] = 1036 +controls_a[CONTROL_INDEX_LEFT] = 1037 +controls_a[CONTROL_INDEX_RIGHT] = 1038 +controls_a[CONTROL_INDEX_A] = 65535 +controls_a[CONTROL_INDEX_B] = 65535 +controls_a[CONTROL_INDEX_X] = 65535 +controls_a[CONTROL_INDEX_Y] = 65535 +controls_a[CONTROL_INDEX_L] = 65535 +controls_a[CONTROL_INDEX_R] = 65535 +controls_a[CONTROL_INDEX_START] = 65535 +controls_a[CONTROL_INDEX_SELECT] = 65535 +controls_a[CONTROL_INDEX_HINGE] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_UP] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 65535 +controls_a[CONTROL_INDEX_MENU] = 1032 +controls_a[CONTROL_INDEX_SAVE_STATE] = 115 +controls_a[CONTROL_INDEX_LOAD_STATE] = 108 +controls_a[CONTROL_INDEX_FAST_FORWARD] = 116 +controls_a[CONTROL_INDEX_SWAP_SCREENS] = 1039 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_A] = 110 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_B] = 112 +controls_a[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_a[CONTROL_INDEX_QUIT] = 65535 +controls_a[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_a[CONTROL_INDEX_UI_UP] = 1035 +controls_a[CONTROL_INDEX_UI_DOWN] = 1036 +controls_a[CONTROL_INDEX_UI_LEFT] = 1037 +controls_a[CONTROL_INDEX_UI_RIGHT] = 1038 +controls_a[CONTROL_INDEX_UI_SELECT] = 65535 +controls_a[CONTROL_INDEX_UI_BACK] = 65535 +controls_a[CONTROL_INDEX_UI_EXIT] = 65535 +controls_a[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_a[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_a[CONTROL_INDEX_UI_SWITCH] = 65535 +controls_b[CONTROL_INDEX_UP] = 1217 +controls_b[CONTROL_INDEX_DOWN] = 1153 +controls_b[CONTROL_INDEX_LEFT] = 1216 +controls_b[CONTROL_INDEX_RIGHT] = 1152 +controls_b[CONTROL_INDEX_A] = 1025 +controls_b[CONTROL_INDEX_B] = 1024 +controls_b[CONTROL_INDEX_X] = 1026 +controls_b[CONTROL_INDEX_Y] = 1027 +controls_b[CONTROL_INDEX_L] = 1028 +controls_b[CONTROL_INDEX_R] = 1029 +controls_b[CONTROL_INDEX_START] = 1031 +controls_b[CONTROL_INDEX_SELECT] = 1030 +controls_b[CONTROL_INDEX_HINGE] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_UP] = 1220 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 1156 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 1219 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 1155 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 1034 +controls_b[CONTROL_INDEX_MENU] = 120 +controls_b[CONTROL_INDEX_SAVE_STATE] = 65535 +controls_b[CONTROL_INDEX_LOAD_STATE] = 65535 +controls_b[CONTROL_INDEX_FAST_FORWARD] = 65535 +controls_b[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_A] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_B] = 65535 +controls_b[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_b[CONTROL_INDEX_QUIT] = 65535 +controls_b[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_b[CONTROL_INDEX_UI_UP] = 1217 +controls_b[CONTROL_INDEX_UI_DOWN] = 1153 +controls_b[CONTROL_INDEX_UI_LEFT] = 1216 +controls_b[CONTROL_INDEX_UI_RIGHT] = 1152 +controls_b[CONTROL_INDEX_UI_SELECT] = 1025 +controls_b[CONTROL_INDEX_UI_BACK] = 65535 +controls_b[CONTROL_INDEX_UI_EXIT] = 1024 +controls_b[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_b[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_b[CONTROL_INDEX_UI_SWITCH] = 65535 diff --git a/projects/ArchR/packages/emulators/standalone/drastic-sa/config/drastic.gptk b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/drastic.gptk new file mode 100644 index 0000000000..13dcd76844 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/drastic-sa/config/drastic.gptk @@ -0,0 +1,32 @@ +back = e +start = \\ +a = d +a_hk = a +b = c +b_hk = b +x = z +x_hk = x +y = v +y_hk = y +l1 = q +l1_hk = l +l2 = n +l2_hk = m +l3 = \\ +r1 = o +r1_hk = s +r2 = p +r2_hk = t +r3 = \\ +up = \\ +down = \\ +left = \\ +right = \\ +left_analog_up = \\ +left_analog_down = \\ +left_analog_left = \\ +left_analog_right = \\ +right_analog_up = \\ +right_analog_down = \\ +right_analog_left = \\ +right_analog_right = \\ diff --git a/projects/ArchR/packages/emulators/standalone/drastic-sa/package.mk b/projects/ArchR/packages/emulators/standalone/drastic-sa/package.mk new file mode 100644 index 0000000000..bcfd5bddcf --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/drastic-sa/package.mk @@ -0,0 +1,50 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="drastic-sa" +PKG_VERSION="1.0" +PKG_LICENSE="Proprietary:DRASTIC.pdf" +PKG_ARCH="aarch64" +PKG_URL="https://github.com/archr-linux/packages/raw/main/drastic.tar.gz" +PKG_DEPENDS_TARGET="toolchain archr-hotkey" +PKG_LONGDESC="Install Drastic Launcher script, will download bin on first run" +PKG_TOOLCHAIN="make" + +if [ "${DEVICE}" = "S922X" ]; then + PKG_DEPENDS_TARGET+=" libegl" +fi + +make_target() { + ${CC} ${CFLAGS} -shared -fPIC -o libdrastouch.so \ + ${PKG_DIR}/sources/libdrastouch.c -ldl +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp -rf ${PKG_DIR}/scripts/* ${INSTALL}/usr/bin + chmod +x ${INSTALL}/usr/bin/start_drastic.sh + + mkdir -p ${INSTALL}/usr/lib + cp -f ${PKG_BUILD}/libdrastouch.so ${INSTALL}/usr/lib/ + + mkdir -p ${INSTALL}/usr/config/drastic/config + cp -rf ${PKG_BUILD}/drastic_aarch64/* ${INSTALL}/usr/config/drastic/ + cp -rf ${PKG_DIR}/config/${DEVICE}/* ${INSTALL}/usr/config/drastic/config/ + cp -rf ${PKG_DIR}/config/drastic.gptk ${INSTALL}/usr/config/drastic/ + + mkdir -p ${INSTALL}/usr/config/drastic/microphone + cp -f ${PKG_DIR}/sources/microphone.wav ${INSTALL}/usr/config/drastic/microphone/ +} + +post_install() { + case ${DEVICE} in + RK3588) + HOTKEY="export HOTKEY="guide"" + ;; + *) + HOTKEY="" + ;; + esac + sed -e "s/@HOTKEY@/${HOTKEY}/g" \ + -i ${INSTALL}/usr/bin/start_drastic.sh +} diff --git a/projects/ArchR/packages/emulators/standalone/drastic-sa/scripts/start_drastic.sh b/projects/ArchR/packages/emulators/standalone/drastic-sa/scripts/start_drastic.sh new file mode 100644 index 0000000000..b687ffb8f2 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/drastic-sa/scripts/start_drastic.sh @@ -0,0 +1,101 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile +. /etc/os-release + +set_kill set "-9 drastic" + +#Get game/platform info +GAME=$(echo "${1}"| sed "s#^/.*/##") +PLATFORM="nds" + +#Get ES feature settings +HIRES3D=$(get_setting hires_3d "${PLATFORM}" "${GAME}") +THREADED3D=$(get_setting threaded_3d "${PLATFORM}" "${GAME}") +FOLLOW3D=$(get_setting follow_3d_renderer "${PLATFORM}" "${GAME}") +MICTHRESH=$(get_setting microphone_sensitivity "${PLATFORM}" "${GAME}") + +#load gptokeyb support files +control-gen_init.sh +source /storage/.config/gptokeyb/control.ini +get_controls + +#Copy drastic files to .config +if [ ! -d "/storage/.config/drastic" ]; then + mkdir -p /storage/.config/drastic/ + cp -r /usr/config/drastic/* /storage/.config/drastic/ +fi + +if [ ! -d "/storage/.config/drastic/system" ]; then + mkdir -p /storage/.config/drastic/system +fi + +for bios in nds_bios_arm9.bin nds_bios_arm7.bin +do + if [ ! -e "/storage/.config/drastic/system/${bios}" ]; then + if [ -e "/storage/roms/bios/${bios}" ]; then + ln -sf /storage/roms/bios/${bios} /storage/.config/drastic/system + fi + fi +done + +#Copy drastic files to .config +if [ ! -f "/storage/.config/drastic/drastic.gptk" ]; then + cp -r /usr/config/drastic/drastic.gptk /storage/.config/drastic/ +fi + +#Make drastic savestate folder +if [ ! -d "/storage/roms/savestates/nds" ]; then + mkdir -p /storage/roms/savestates/nds +fi + +#Link savestates to roms/savestates/nds +rm -rf /storage/.config/drastic/savestates +ln -sf /storage/roms/savestates/nds /storage/.config/drastic/savestates + +#Link saves to roms/nds/saves +rm -rf /storage/.config/drastic/backup +ln -sf /storage/roms/nds /storage/.config/drastic/backup + +#Apply ES features to config +if [ "${HIRES3D}" = "1" ]; then + sed -i 's/^hires_3d = .*/hires_3d = 1/' /storage/.config/drastic/config/drastic.cfg +else + sed -i 's/^hires_3d = .*/hires_3d = 0/' /storage/.config/drastic/config/drastic.cfg +fi + +if [ "${THREADED3D}" = "1" ]; then + sed -i 's/^threaded_3d = .*/threaded_3d = 1/' /storage/.config/drastic/config/drastic.cfg +else + sed -i 's/^threaded_3d = .*/threaded_3d = 0/' /storage/.config/drastic/config/drastic.cfg +fi + +if [ "${FOLLOW3D}" = "1" ]; then + sed -i 's/^fix_main_2d_screen = .*/fix_main_2d_screen = 1/' /storage/.config/drastic/config/drastic.cfg +else + sed -i 's/^fix_main_2d_screen = .*/fix_main_2d_screen = 0/' /storage/.config/drastic/config/drastic.cfg +fi + +cd /storage/.config/drastic/ +@HOTKEY@ + +# Fix for libmali gpu driver on S922X platform +if [ "${HW_DEVICE}" = "S922X" ]; then + GPUDRIVER=$(/usr/bin/gpudriver) + + if [ "${GPUDRIVER}" = "libmali" ]; then + export SDL_VIDEO_GL_DRIVER=\/usr\/lib\/egl\/libGL.so.1 + export SDL_VIDEO_EGL_DRIVER=\/usr\/lib\/egl\/libEGL.so.1 + fi +fi + +$GPTOKEYB "drastic" -c "drastic.gptk" & +# Fix actual touch inputs by replacing touch->mouse translation and add hw mic support +export LD_PRELOAD="/usr/lib/libdrastouch.so" +export SDL_TOUCH_MOUSE_EVENTS="0" +export DSHOOK_MIC_THRESH="${MICTHRESH}" +./drastic "$1" +kill -9 $(pidof gptokeyb) diff --git a/projects/ArchR/packages/emulators/standalone/drastic-sa/sources/libdrastouch.c b/projects/ArchR/packages/emulators/standalone/drastic-sa/sources/libdrastouch.c new file mode 100644 index 0000000000..790923bca9 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/drastic-sa/sources/libdrastouch.c @@ -0,0 +1,378 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include + +static int ds_screen_width = 256; +static int ds_screen_height = 192; +static int last_x = -1; +static int last_y = -1; +static int xy_idx = 0; +static int phys_width = -1; +static int phys_height = -1; +static int logical_width = -1; +static int logical_height = -1; +static int actual_touch = 0; + +// Microphone monitoring +static SDL_AudioDeviceID mic_device = 0; +static int mic_key_held = 0; +static float mic_threshold = 0.0f; +static int mic_enabled = 0; +static float mic_baseline = 0.0f; +static int mic_baseline_samples = 0; + +static SDL_Texture* screens[4]; +static SDL_Texture* stylus_tex[2]; +static SDL_Rect touch_rect_storage = {0}; +static SDL_Rect* touch_rect = NULL; +static SDL_Renderer* renderer = NULL; +static SDL_Window* (*real_SDL_CreateWindow)(const char*, int, int, int, int, Uint32) = NULL; +static void (*real_SDL_SetWindowSize)(SDL_Window* window, int w, int h) = NULL; +static SDL_Renderer* (*real_SDL_CreateRenderer)(SDL_Window*, int, Uint32) = NULL; +static int (*real_SDL_RenderSetLogicalSize)(SDL_Renderer*, int, int) = NULL; +static SDL_Texture* (*real_SDL_CreateTexture)(SDL_Renderer*, Uint32, int, int, int) = NULL; +static int (*real_SDL_RenderCopy)(SDL_Renderer*, SDL_Texture*, const SDL_Rect*, const SDL_Rect*) = NULL; +static int (*real_SDL_PollEvent)(SDL_Event*) = NULL; +static int (*real_SDL_PushEvent)(SDL_Event*) = NULL; +static Uint32 (*real_SDL_WasInit)(Uint32) = NULL; +static int (*real_SDL_InitSubSystem)(Uint32) = NULL; +static SDL_AudioDeviceID (*real_SDL_OpenAudioDevice)(const char*, int, const SDL_AudioSpec*, SDL_AudioSpec*, int) = NULL; +static void (*real_SDL_PauseAudioDevice)(SDL_AudioDeviceID, int) = NULL; +static void (*real_SDL_CloseAudioDevice)(SDL_AudioDeviceID) = NULL; +static int (*real_SDL_GetNumAudioDevices)(int) = NULL; +static const char* (*real_SDL_GetAudioDeviceName)(int, int) = NULL; + +SDL_Window* SDL_CreateWindow(const char* title, int x, int y, int w, int h, Uint32 flags) { + int num_displays = SDL_GetNumVideoDisplays(); + int total_width = 0; + int total_height = 0; + int last_width = 0; + int last_height = 0; + + // Change window to total screen size + // Prevents empty spacing on dual displays + for (int i = 0; i < num_displays; ++i) { + SDL_Rect bounds; + if (SDL_GetDisplayBounds(i, &bounds) == 0) { + last_width = bounds.w; + last_height = bounds.h; + if (bounds.w + bounds.x > total_width) + total_width += bounds.w; + if (bounds.h + bounds.y > total_height) + total_height += bounds.h; + } + } + + // Record screen size for rect tracking/conversion + phys_width = total_width; + phys_height = total_height; + + // DraStic starts in the center of the native virtual screen + last_x = 128; + last_y = 96; + + // Check which screen side is longer for dual screens + if (num_displays > 1) + xy_idx = (last_width > last_height) ? 1 : 2; + + // Set window size to single screen to fix offsets when resizing + return real_SDL_CreateWindow(title, 0, 0, last_width, last_height, flags); +} + +void SDL_SetWindowSize(SDL_Window* window, int w, int h) { + static int init_resize = 2; + + if (init_resize > 0) { + real_SDL_SetWindowSize(window, w, h); + init_resize -= 1; + } + + // Force window size to fill AFTER DraStic does its weird init thing + // Also check if this is a resize after init, if so, toggle a scale down to allow DraStic menu visibility + if (init_resize == 0) { + real_SDL_SetWindowSize(window, phys_width, phys_height); + init_resize = -1; + } else if (init_resize == -1) { + if (xy_idx == 1) + w = phys_width / 2; + if (xy_idx == 2) + h = phys_height / 2; + + real_SDL_SetWindowSize(window, w, h); + init_resize = 0; + } + +} + +SDL_Renderer* SDL_CreateRenderer(SDL_Window* window, int index, Uint32 flags) { + renderer = real_SDL_CreateRenderer(window, index, flags); + // Just in case it's already set + SDL_RenderGetLogicalSize(renderer, &logical_width, &logical_height); + return renderer; +} + +int SDL_RenderSetLogicalSize(SDL_Renderer* renderer, int w, int h) { + int result = real_SDL_RenderSetLogicalSize(renderer, w, h); + // Otherwise store it here + logical_width = w; + logical_height = h; + return result; +} + +SDL_Texture* SDL_CreateTexture(SDL_Renderer *renderer, Uint32 format, int type, int w, int h) { + SDL_Texture* texture = real_SDL_CreateTexture(renderer, format, type, w, h); + // Identify DS screen and stylus textures + if (type == SDL_TEXTUREACCESS_STREAMING) { + if (w == 512 && h == 384) { + ds_screen_width = 512; + ds_screen_height = 384; + if (!screens[0]) screens[0] = texture; + else if (!screens[1]) screens[1] = texture; + } else if (w == 256 && h == 192 && !screens[0]) { + if (!screens[2]) screens[2] = texture; + else if (!screens[3]) screens[3] = texture; + } + } + if (w == 32 && h == 32) { + if (!stylus_tex[0]) stylus_tex[0] = texture; + else if (!stylus_tex[1]) stylus_tex[1] = texture; + } + return texture; +} + +int SDL_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_Rect *dstrect) { + if ((screens[0] && texture == screens[0] && ds_screen_width == 512) || + (screens[3] && texture == screens[3] && ds_screen_width == 256)) { + // Convert renderer coordinates to physical screen coordinates + if (logical_width > 0 && logical_height > 0) { + int output_w, output_h; + SDL_GetRendererOutputSize(renderer, &output_w, &output_h); + float scale_x = (float)output_w / logical_width; + float scale_y = (float)output_h / logical_height; + + touch_rect_storage.x = (int)(dstrect->x * scale_x); + touch_rect_storage.y = (int)(dstrect->y * scale_y); + touch_rect_storage.w = (int)(dstrect->w * scale_x); + touch_rect_storage.h = (int)(dstrect->h * scale_y); + } else { + // Fallback and hope they're right + touch_rect_storage.x = dstrect->x; + touch_rect_storage.y = dstrect->y; + touch_rect_storage.w = dstrect->w; + touch_rect_storage.h = dstrect->h; + } + touch_rect = &touch_rect_storage; + } + + // Make stylus fully transparent for actual touchscreens + if (actual_touch && (texture == stylus_tex[0] || texture == stylus_tex[1])) + SDL_SetTextureAlphaMod(texture, 0); + + return real_SDL_RenderCopy(renderer, texture, srcrect, dstrect); +} + +void mic_audio_callback(void* userdata, Uint8* stream, int len) { + if (!mic_enabled) return; + + Sint16* samples = (Sint16*)stream; + int sample_count = len / 2; + + // Calculate RMS amplitude + float sum = 0.0f; + for (int i = 0; i < sample_count; i++) { + float sample = samples[i] / 32768.0f; // Normalize to [-1.0..1.0] + sum += sample * sample; + } + float rms = sqrtf(sum / sample_count); + + // Build ambient baseline over first ~3 seconds + if (mic_baseline_samples < 60) { + mic_baseline = (mic_baseline * mic_baseline_samples + rms) / (mic_baseline_samples + 1); + mic_baseline_samples++; + return; // Don't trigger during calibration + } + + mic_baseline = mic_baseline * 0.999f + rms * 0.001f; + + // Trigger only if significantly above baseline + float trigger_level = mic_baseline + mic_threshold; + int should_hold = (rms > trigger_level); + if (should_hold && !mic_key_held) { + // Noise detected, press Scroll Lock + SDL_Event key_event = {0}; + key_event.type = SDL_KEYDOWN; + key_event.key.state = SDL_PRESSED; + key_event.key.keysym.scancode = SDL_SCANCODE_SCROLLLOCK; + key_event.key.keysym.sym = SDLK_SCROLLLOCK; + real_SDL_PushEvent(&key_event); + mic_key_held = 1; + } else if (!should_hold && mic_key_held) { + // Noise dropped below threshold, release Scroll Lock + SDL_Event key_event = {0}; + key_event.type = SDL_KEYUP; + key_event.key.state = SDL_RELEASED; + key_event.key.keysym.scancode = SDL_SCANCODE_SCROLLLOCK; + key_event.key.keysym.sym = SDLK_SCROLLLOCK; + real_SDL_PushEvent(&key_event); + mic_key_held = 0; + } +} + +int SDL_PollEvent(SDL_Event* event) { + // Loop required to filter events we don't want to pass along + while (1) { + int result = real_SDL_PollEvent(event); + if (!result) return 0; + + switch (event->type) { + case SDL_FINGERDOWN: { + if (!actual_touch) + actual_touch = 1; + + int x = (int)(event->tfinger.x * phys_width); + int y = (int)(event->tfinger.y * phys_height); + if (xy_idx == 1) + x *= 2; + if (xy_idx == 2) + y *= 2; + + if (x < touch_rect->x || x > touch_rect->x + touch_rect->w || + y < touch_rect->y || y > touch_rect->y + touch_rect->h) + return 0; // Outside valid coords, don't convert + + // Scale to native virtual touchscreen + x = ((x - touch_rect->x) * 256) / touch_rect->w; + y = ((y - touch_rect->y) * 192) / touch_rect->h; + + // Queue click for after jump + event->type = SDL_MOUSEBUTTONDOWN; + event->button.button = SDL_BUTTON_LEFT; + event->button.state = SDL_PRESSED; + event->button.x = x; + event->button.y = y; + real_SDL_PushEvent(event); + + // Jump to new position + event->type = SDL_MOUSEMOTION; + event->motion.x = x; + event->motion.y = y; + event->motion.xrel = x - last_x; + event->motion.yrel = y - last_y; + + // Update to keep position accurate + last_x = x; + last_y = y; + break; + } + case SDL_FINGERMOTION: { + int x = (int)(event->tfinger.x * phys_width); + int y = (int)(event->tfinger.y * phys_height); + if (xy_idx == 1) + x *= 2; + if (xy_idx == 2) + y *= 2; + + if (x < touch_rect->x || x > touch_rect->x + touch_rect->w || + y < touch_rect->y || y > touch_rect->y + touch_rect->h) + return 0; + + x = ((x - touch_rect->x) * 256) / touch_rect->w; + y = ((y - touch_rect->y) * 192) / touch_rect->h; + int xrel = x - last_x; + int yrel = y - last_y; + + // Motion is also used when already clicked but not moving + // Always update it + event->type = SDL_MOUSEMOTION; + event->motion.x = x; + event->motion.y = y; + event->motion.xrel = xrel; + event->motion.yrel = yrel; + + last_x = x; + last_y = y; + break; + } + case SDL_FINGERUP: { + event->type = SDL_MOUSEBUTTONUP; + event->button.button = SDL_BUTTON_LEFT; + event->button.state = SDL_RELEASED; + event->button.x = last_x; + event->button.y = last_y; + break; + } + } + return result; + } +} + +__attribute__((constructor)) +static void init(void) { + real_SDL_CreateWindow = dlsym(RTLD_NEXT, "SDL_CreateWindow"); + real_SDL_SetWindowSize = dlsym(RTLD_NEXT, "SDL_SetWindowSize"); + real_SDL_CreateRenderer = dlsym(RTLD_NEXT, "SDL_CreateRenderer"); + real_SDL_RenderSetLogicalSize = dlsym(RTLD_NEXT, "SDL_RenderSetLogicalSize"); + real_SDL_CreateTexture = dlsym(RTLD_NEXT, "SDL_CreateTexture"); + real_SDL_RenderCopy = dlsym(RTLD_NEXT, "SDL_RenderCopy"); + real_SDL_PollEvent = dlsym(RTLD_NEXT, "SDL_PollEvent"); + real_SDL_PushEvent = dlsym(RTLD_NEXT, "SDL_PushEvent"); + real_SDL_WasInit = dlsym(RTLD_NEXT, "SDL_WasInit"); + real_SDL_InitSubSystem = dlsym(RTLD_NEXT, "SDL_InitSubSystem"); + real_SDL_OpenAudioDevice = dlsym(RTLD_NEXT, "SDL_OpenAudioDevice"); + real_SDL_PauseAudioDevice = dlsym(RTLD_NEXT, "SDL_PauseAudioDevice"); + real_SDL_CloseAudioDevice = dlsym(RTLD_NEXT, "SDL_CloseAudioDevice"); + real_SDL_GetNumAudioDevices = dlsym(RTLD_NEXT, "SDL_GetNumAudioDevices"); + real_SDL_GetAudioDeviceName = dlsym(RTLD_NEXT, "SDL_GetAudioDeviceName"); + + const char* threshold_str = getenv("DSHOOK_MIC_THRESH"); + if (threshold_str) { + mic_threshold = atof(threshold_str); + if (mic_threshold > 0.0f) { + mic_enabled = 1; + + // Make sure SDL audio is ready, just in case + if (real_SDL_WasInit(SDL_INIT_AUDIO) == 0) + real_SDL_InitSubSystem(SDL_INIT_AUDIO); + + int num_devices = real_SDL_GetNumAudioDevices(1); + const char* device_name = NULL; + for (int i = 0; i < num_devices; i++) { + const char* name = real_SDL_GetAudioDeviceName(i, 1); + // Use first available device (or look for Built-in) + if (name && (i == 0 || strstr(name, "Built-in"))) { + device_name = name; + break; + } + } + + // Configure audio capture + SDL_AudioSpec desired_spec = {0}; + desired_spec.freq = 44100; + desired_spec.format = AUDIO_S16SYS; + desired_spec.channels = 1; + desired_spec.samples = 2048; + desired_spec.callback = mic_audio_callback; + + SDL_AudioSpec obtained_spec; + mic_device = real_SDL_OpenAudioDevice(device_name, 1, &desired_spec, &obtained_spec, 0); + + if (mic_device > 0) // Opened, start capture + real_SDL_PauseAudioDevice(mic_device, 0); + else // Couldn't open, fallback to disable + mic_enabled = 0; + } + } +} + +__attribute__((destructor)) +static void cleanup(void) { + if (mic_device > 0 && real_SDL_CloseAudioDevice) { + real_SDL_CloseAudioDevice(mic_device); + } +} + +// Major thanks/credit to Shaun Inman for providing the basis of this hook library! \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/drastic-sa/sources/microphone.wav b/projects/ArchR/packages/emulators/standalone/drastic-sa/sources/microphone.wav new file mode 100644 index 0000000000..7d58159181 Binary files /dev/null and b/projects/ArchR/packages/emulators/standalone/drastic-sa/sources/microphone.wav differ diff --git a/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/H700/settings.ini b/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/H700/settings.ini new file mode 100644 index 0000000000..3d91aa7780 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/H700/settings.ini @@ -0,0 +1,265 @@ +[Main] +SettingsVersion = 3 +StartFullscreen = true +EmulationSpeed = 1.000000 +FastForwardSpeed = 0.000000 +TurboSpeed = 0.000000 +SyncToHostRefreshRate = false +IncreaseTimerResolution = true +InhibitScreensaver = true +StartPaused = false +PauseOnFocusLoss = false +PauseOnMenu = true +SaveStateOnExit = true +ConfirmPowerOff = false +LoadDevicesFromSaveStates = false +ApplyGameSettings = true +AutoLoadCheats = true +DisableAllEnhancements = false +RewindEnable = false +RewindFrequency = 10.000000 +RewindSaveSlots = 10 +RunaheadFrameCount = 0 +NoDesktopFile = true + + +[BIOS] +SearchDirectory = /storage/roms/bios +PathNTSCU = +PathNTSCJ = +PathPAL = +PatchTTYEnable = false +PatchFastBoot = true + + +[GPU] +Renderer = Software +Adapter = +ResolutionScale = 1 +Multisamples = 1 +UseDebugDevice = false +PerSampleShading = false +UseThread = true +ThreadedPresentation = true +UseSoftwareRendererForReadbacks = false +TrueColor = false +ScaledDithering = false +TextureFilter = Nearest +DownsampleMode = Disabled +DisableInterlacing = false +ForceNTSCTimings = false +WidescreenHack = false +ChromaSmoothing24Bit = false +PGXPEnable = false +PGXPCulling = true +PGXPTextureCorrection = true +PGXPVertexCache = false +PGXPCPU = false +PGXPPreserveProjFP = false +PGXPTolerance = -1.000000 +PGXPDepthBuffer = false +PGXPDepthClearThreshold = 300.000000 + + +[Display] +CropMode = Overscan +ActiveStartOffset = 0 +ActiveEndOffset = 0 +LineStartOffset = 0 +LineEndOffset = 0 +Force4_3For24Bit = false +AspectRatio = 4:3 +CustomAspectRatioNumerator = 4 +LinearFiltering = true +IntegerScaling = false +Stretch = false +PostProcessing = false +ShowOSDMessages = true +ShowFPS = false +ShowVPS = false +ShowSpeed = false +ShowResolution = false +ShowStatusIndicators = true +ShowEnhancements = false +DisplayAllFrames = true +VSync = false +MaxFPS = 0.000000 + + +[Hotkeys] +OpenPauseMenu = SDL-0/Guide & SDL-0/X +FastForward = SDL-0/Guide & SDL-0/+RightTrigger +Screenshot = SDL-0/Guide & SDL-0/A +LoadSelectedSaveState = SDL-0/Guide & SDL-0/LeftShoulder +SaveSelectedSaveState = SDL-0/Guide & SDL-0/RightShoulder +PowerOff = SDL-0/Guide & SDL-0/Start + + +[Logging] +LogLevel = Error +LogFilter = +LogToConsole = false +LogToDebug = false +LogToWindow = false +LogToFile = false + + +[Controller1] +Type = AnalogController +ButtonUp = Controller0/Button11 +ButtonDown = Controller0/Button12 +ButtonLeft = Controller0/Button13 +ButtonRight = Controller0/Button14 +ButtonSelect = Controller0/Button4 +ButtonStart = Controller0/Button6 +ButtonTriangle = Controller0/Button2 +ButtonCross = Controller0/Button1 +ButtonSquare = Controller0/Button3 +ButtonCircle = Controller0/Button0 +ButtonL1 = Controller0/Button9 +ButtonL2 = Controller0/+Axis4 +ButtonR1 = Controller0/Button10 +ButtonR2 = Controller0/+Axis5 +AxisLeftX = Controller0/Axis0 +AxisLeftY = Controller0/Axis1 +ButtonL3 = Controller0/Button7 +ButtonR3 = Controller0/Button8 +AxisRightX = Controller0/Axis2 +AxisRightY = Controller0/Axis3 +AnalogDPadInDigitalMode = false + + +[GameList] +RecursivePaths = /storage/roms/psx + + +[MemoryCards] +UsePlaylistTitle = true +Directory = /storage/roms/psx +Card1Type = PerGameTitle +Card2Type = None + + +[Console] +Region = Auto +Enable8MBRAM = false + + +[CPU] +ExecutionMode = Recompiler +OverclockEnable = false +OverclockNumerator = 1 +OverclockDenominator = 1 +RecompilerMemoryExceptions = false +RecompilerBlockLinking = true +RecompilerICache = false +FastmemMode = MMap + + +[CDROM] +ReadaheadSectors = 8 +RegionCheck = false +LoadImageToRAM = false +MuteCDAudio = false +ReadSpeedup = 1 +SeekSpeedup = 1 + + +[Audio] +Backend = SDL +OutputVolume = 100 +FastForwardVolume = 100 +BufferSize = 2048 +Resampling = true +OutputMuted = false +Sync = true +DumpOnBoot = false + + +[Hacks] +DMAMaxSliceTicks = 1000 +DMAHaltTicks = 100 +GPUFIFOSize = 16 +GPUMaxRunAhead = 128 + + +[Controller2] +Type = None + + +[Controller3] +Type = None + + +[Controller4] +Type = None + + +[Controller5] +Type = None + + +[Controller6] +Type = None + + +[Controller7] +Type = None + + +[Controller8] +Type = None + + +[ControllerPorts] +MultitapMode = Disabled + + +[Debug] +ShowVRAM = false +DumpCPUToVRAMCopies = false +DumpVRAMToCPUCopies = false +ShowGPUState = false +ShowCDROMState = false +ShowSPUState = false +ShowTimersState = false +ShowMDECState = false +ShowDMAState = false + + +[TextureReplacements] +EnableVRAMWriteReplacements = false +PreloadTextures = false +DumpVRAMWrites = false +DumpVRAMWriteForceAlphaChannel = true +DumpVRAMWriteWidthThreshold = 128 +DumpVRAMWriteHeightThreshold = 128 + + +[Pad1] +Up = SDL-0/DPadUp +Right = SDL-0/DPadRight +Down = SDL-0/DPadDown +Left = SDL-0/DPadLeft +Triangle = SDL-0/X +Circle = SDL-0/A +Cross = SDL-0/B +Square = SDL-0/Y +Select = SDL-0/Back +Start = SDL-0/Start +L1 = SDL-0/LeftShoulder +R1 = SDL-0/RightShoulder +L2 = SDL-0/+LeftTrigger +R2 = SDL-0/+RightTrigger +L3 = SDL-0/LeftStick +R3 = SDL-0/RightStick +LLeft = SDL-0/-LeftX +LRight = SDL-0/+LeftX +LDown = SDL-0/+LeftY +LUp = SDL-0/-LeftY +RLeft = SDL-0/+RightX +RRight = SDL-0/-RightX +RDown = SDL-0/+RightY +RUp = SDL-0/-RightY +LargeMotor = SDL-0/LargeMotor +SmallMotor = SDL-0/SmallMotor diff --git a/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/InputPlumber/settings.ini b/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/InputPlumber/settings.ini new file mode 100644 index 0000000000..2e9be3c1a1 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/InputPlumber/settings.ini @@ -0,0 +1,266 @@ +[Main] +SettingsVersion = 3 +StartFullscreen = true +EmulationSpeed = 1.000000 +FastForwardSpeed = 0.000000 +TurboSpeed = 0.000000 +SyncToHostRefreshRate = false +IncreaseTimerResolution = true +InhibitScreensaver = true +StartPaused = false +PauseOnFocusLoss = false +PauseOnMenu = true +SaveStateOnExit = true +ConfirmPowerOff = false +LoadDevicesFromSaveStates = false +ApplyGameSettings = true +AutoLoadCheats = true +DisableAllEnhancements = false +RewindEnable = false +RewindFrequency = 10.000000 +RewindSaveSlots = 10 +RunaheadFrameCount = 0 +NoDesktopFile = true + + +[BIOS] +SearchDirectory = /storage/roms/bios +PathNTSCU = +PathNTSCJ = +PathPAL = +PatchTTYEnable = false +PatchFastBoot = true + + +[GPU] +Renderer = Software +Adapter = +ResolutionScale = 1 +Multisamples = 1 +UseDebugDevice = false +PerSampleShading = false +UseThread = true +ThreadedPresentation = true +UseSoftwareRendererForReadbacks = false +TrueColor = false +ScaledDithering = false +TextureFilter = Nearest +DownsampleMode = Disabled +DisableInterlacing = false +ForceNTSCTimings = false +WidescreenHack = false +ChromaSmoothing24Bit = false +PGXPEnable = false +PGXPCulling = true +PGXPTextureCorrection = true +PGXPVertexCache = false +PGXPCPU = false +PGXPPreserveProjFP = false +PGXPTolerance = -1.000000 +PGXPDepthBuffer = false +PGXPDepthClearThreshold = 300.000000 + + +[Display] +CropMode = Overscan +ActiveStartOffset = 0 +ActiveEndOffset = 0 +LineStartOffset = 0 +LineEndOffset = 0 +Force4_3For24Bit = false +AspectRatio = 4:3 +CustomAspectRatioNumerator = 4 +LinearFiltering = true +IntegerScaling = false +Stretch = false +PostProcessing = false +ShowOSDMessages = true +ShowFPS = false +ShowVPS = false +ShowSpeed = false +ShowResolution = false +ShowStatusIndicators = true +ShowEnhancements = false +DisplayAllFrames = true +VSync = true +MaxFPS = 0.000000 + + +[Hotkeys] +OpenPauseMenu = SDL-0/Guide & SDL-0/Y +FastForward = SDL-0/Guide & SDL-0/+RightTrigger +Screenshot = SDL-0/Guide & SDL-0/B +LoadSelectedSaveState = SDL-0/Guide & SDL-0/LeftShoulder +SaveSelectedSaveState = SDL-0/Guide & SDL-0/RightShoulder +PowerOff = SDL-0/Guide & SDL-0/Start + + +[Logging] +LogLevel = Error +LogFilter = +LogToConsole = false +LogToDebug = false +LogToWindow = false +LogToFile = false + + +[Controller1] +Type = AnalogController +ButtonUp = Controller0/Button11 +ButtonDown = Controller0/Button12 +ButtonLeft = Controller0/Button13 +ButtonRight = Controller0/Button14 +ButtonSelect = Controller0/Button4 +ButtonStart = Controller0/Button6 +ButtonTriangle = Controller0/Button2 +ButtonCross = Controller0/Button1 +ButtonSquare = Controller0/Button3 +ButtonCircle = Controller0/Button0 +ButtonL1 = Controller0/Button9 +ButtonL2 = Controller0/+Axis4 +ButtonR1 = Controller0/Button10 +ButtonR2 = Controller0/+Axis5 +AxisLeftX = Controller0/Axis0 +AxisLeftY = Controller0/Axis1 +ButtonL3 = Controller0/Button7 +ButtonR3 = Controller0/Button8 +AxisRightX = Controller0/Axis2 +AxisRightY = Controller0/Axis3 +AnalogDPadInDigitalMode = false + + +[GameList] +RecursivePaths = /storage/roms/psx + + +[MemoryCards] +UsePlaylistTitle = true +Directory = /storage/roms/psx +Card1Type = PerGameTitle +Card2Type = None + + +[Console] +Region = Auto +Enable8MBRAM = false + + +[CPU] +ExecutionMode = Recompiler +OverclockEnable = false +OverclockNumerator = 1 +OverclockDenominator = 1 +RecompilerMemoryExceptions = false +RecompilerBlockLinking = true +RecompilerICache = false +FastmemMode = MMap + + +[CDROM] +ReadaheadSectors = 8 +RegionCheck = false +LoadImageToRAM = false +MuteCDAudio = false +ReadSpeedup = 1 +SeekSpeedup = 1 + + +[Audio] +Backend = SDL +OutputVolume = 100 +FastForwardVolume = 100 +BufferSize = 2048 +Resampling = true +OutputMuted = false +Sync = true +DumpOnBoot = false +BufferMS = 100 + + +[Hacks] +DMAMaxSliceTicks = 1000 +DMAHaltTicks = 100 +GPUFIFOSize = 16 +GPUMaxRunAhead = 128 + + +[Controller2] +Type = None + + +[Controller3] +Type = None + + +[Controller4] +Type = None + + +[Controller5] +Type = None + + +[Controller6] +Type = None + + +[Controller7] +Type = None + + +[Controller8] +Type = None + + +[ControllerPorts] +MultitapMode = Disabled + + +[Debug] +ShowVRAM = false +DumpCPUToVRAMCopies = false +DumpVRAMToCPUCopies = false +ShowGPUState = false +ShowCDROMState = false +ShowSPUState = false +ShowTimersState = false +ShowMDECState = false +ShowDMAState = false + + +[TextureReplacements] +EnableVRAMWriteReplacements = false +PreloadTextures = false +DumpVRAMWrites = false +DumpVRAMWriteForceAlphaChannel = true +DumpVRAMWriteWidthThreshold = 128 +DumpVRAMWriteHeightThreshold = 128 + + +[Pad1] +Up = SDL-0/DPadUp +Right = SDL-0/DPadRight +Down = SDL-0/DPadDown +Left = SDL-0/DPadLeft +Triangle = SDL-0/Y +Circle = SDL-0/B +Cross = SDL-0/A +Square = SDL-0/X +Select = SDL-0/Back +Start = SDL-0/Start +L1 = SDL-0/LeftShoulder +R1 = SDL-0/RightShoulder +L2 = SDL-0/+LeftTrigger +R2 = SDL-0/+RightTrigger +L3 = SDL-0/LeftStick +R3 = SDL-0/RightStick +LLeft = SDL-0/-LeftX +LRight = SDL-0/+LeftX +LDown = SDL-0/+LeftY +LUp = SDL-0/-LeftY +RLeft = SDL-0/+RightX +RRight = SDL-0/-RightX +RDown = SDL-0/+RightY +RUp = SDL-0/-RightY +LargeMotor = SDL-0/LargeMotor +SmallMotor = SDL-0/SmallMotor diff --git a/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/RK3326/settings.ini b/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/RK3326/settings.ini new file mode 100644 index 0000000000..cd84914a12 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/RK3326/settings.ini @@ -0,0 +1,263 @@ +[Main] +SettingsVersion = 3 +StartFullscreen = true +EmulationSpeed = 1.000000 +FastForwardSpeed = 0.000000 +TurboSpeed = 0.000000 +SyncToHostRefreshRate = false +IncreaseTimerResolution = true +InhibitScreensaver = true +StartPaused = false +PauseOnFocusLoss = false +PauseOnMenu = true +SaveStateOnExit = true +ConfirmPowerOff = false +LoadDevicesFromSaveStates = false +ApplyGameSettings = true +AutoLoadCheats = true +DisableAllEnhancements = false +RewindEnable = false +RewindFrequency = 10.000000 +RewindSaveSlots = 10 +RunaheadFrameCount = 0 +NoDesktopFile = true + + +[BIOS] +SearchDirectory = /storage/roms/bios +PathNTSCU = +PathNTSCJ = +PathPAL = +PatchTTYEnable = false +PatchFastBoot = true + + +[GPU] +Renderer = Software +Adapter = +ResolutionScale = 1 +Multisamples = 1 +UseDebugDevice = false +PerSampleShading = false +UseThread = true +ThreadedPresentation = true +UseSoftwareRendererForReadbacks = false +TrueColor = false +ScaledDithering = false +TextureFilter = Nearest +DownsampleMode = Disabled +DisableInterlacing = false +ForceNTSCTimings = false +WidescreenHack = false +ChromaSmoothing24Bit = false +PGXPEnable = false +PGXPCulling = true +PGXPTextureCorrection = true +PGXPVertexCache = false +PGXPCPU = false +PGXPPreserveProjFP = false +PGXPTolerance = -1.000000 +PGXPDepthBuffer = false +PGXPDepthClearThreshold = 300.000000 + + +[Display] +CropMode = Overscan +ActiveStartOffset = 0 +ActiveEndOffset = 0 +LineStartOffset = 0 +LineEndOffset = 0 +Force4_3For24Bit = false +AspectRatio = 4:3 +CustomAspectRatioNumerator = 4 +LinearFiltering = true +IntegerScaling = false +Stretch = false +PostProcessing = false +ShowOSDMessages = true +ShowFPS = false +ShowVPS = false +ShowSpeed = false +ShowResolution = false +ShowStatusIndicators = true +ShowEnhancements = false +DisplayAllFrames = true +VSync = false +MaxFPS = 0.000000 + + +[Hotkeys] +OpenPauseMenu = SDL-0/Back & SDL-0/X +FastForward = SDL-0/Back & SDL-0/+RightTrigger +Screenshot = SDL-0/Back & SDL-0/A +LoadSelectedSaveState = SDL-0/Back & SDL-0/LeftShoulder +SaveSelectedSaveState = SDL-0/Back & SDL-0/RightShoulder +PowerOff = SDL-0/Back & SDL-0/Start + + +[Logging] +LogLevel = Error +LogFilter = +LogToConsole = false +LogToDebug = false +LogToWindow = false +LogToFile = false + + +[Controller1] +Type = AnalogController +ButtonUp = Controller0/Button11 +ButtonDown = Controller0/Button12 +ButtonLeft = Controller0/Button13 +ButtonRight = Controller0/Button14 +ButtonSelect = Controller0/Button4 +ButtonStart = Controller0/Button6 +ButtonTriangle = Controller0/Button2 +ButtonCross = Controller0/Button1 +ButtonSquare = Controller0/Button3 +ButtonCircle = Controller0/Button0 +ButtonL1 = Controller0/Button9 +ButtonL2 = Controller0/+Axis4 +ButtonR1 = Controller0/Button10 +ButtonR2 = Controller0/+Axis5 +AxisLeftX = Controller0/Axis0 +AxisLeftY = Controller0/Axis1 +ButtonL3 = Controller0/Button7 +ButtonR3 = Controller0/Button8 +AxisRightX = Controller0/Axis2 +AxisRightY = Controller0/Axis3 +AnalogDPadInDigitalMode = false + + +[GameList] +RecursivePaths = /storage/roms/psx + + +[MemoryCards] +UsePlaylistTitle = true +Directory = /storage/roms/psx +Card1Type = PerGameTitle +Card2Type = None + + +[Console] +Region = Auto +Enable8MBRAM = false + + +[CPU] +ExecutionMode = Recompiler +OverclockEnable = false +OverclockNumerator = 1 +OverclockDenominator = 1 +RecompilerMemoryExceptions = false +RecompilerBlockLinking = true +RecompilerICache = false +FastmemMode = MMap + + +[CDROM] +ReadaheadSectors = 8 +RegionCheck = false +LoadImageToRAM = false +MuteCDAudio = false +ReadSpeedup = 1 +SeekSpeedup = 1 + + +[Audio] +Backend = SDL +OutputVolume = 100 +FastForwardVolume = 100 +BufferSize = 2048 +Resampling = true +OutputMuted = false +Sync = true +DumpOnBoot = false + + +[Hacks] +DMAMaxSliceTicks = 1000 +DMAHaltTicks = 100 +GPUFIFOSize = 16 +GPUMaxRunAhead = 128 + + +[Controller2] +Type = None + + +[Controller3] +Type = None + + +[Controller4] +Type = None + + +[Controller5] +Type = None + + +[Controller6] +Type = None + + +[Controller7] +Type = None + + +[Controller8] +Type = None + + +[ControllerPorts] +MultitapMode = Disabled + + +[Debug] +ShowVRAM = false +DumpCPUToVRAMCopies = false +DumpVRAMToCPUCopies = false +ShowGPUState = false +ShowCDROMState = false +ShowSPUState = false +ShowTimersState = false +ShowMDECState = false +ShowDMAState = false + + +[TextureReplacements] +EnableVRAMWriteReplacements = false +PreloadTextures = false +DumpVRAMWrites = false +DumpVRAMWriteForceAlphaChannel = true +DumpVRAMWriteWidthThreshold = 128 +DumpVRAMWriteHeightThreshold = 128 + + +[Pad1] +Up = SDL-0/DPadUp +Right = SDL-0/DPadRight +Down = SDL-0/DPadDown +Left = SDL-0/DPadLeft +Triangle = SDL-0/X +Circle = SDL-0/A +Cross = SDL-0/B +Square = SDL-0/Y +Select = SDL-0/Back +Start = SDL-0/Start +L1 = SDL-0/LeftShoulder +R1 = SDL-0/RightShoulder +L2 = SDL-0/+LeftTrigger +R2 = SDL-0/+RightTrigger +L3 = SDL-0/LeftStick +R3 = SDL-0/RightStick +LLeft = SDL-0/-LeftX +LRight = SDL-0/+LeftX +LDown = SDL-0/+LeftY +LUp = SDL-0/-LeftY +RLeft = SDL-0/+RightX +RRight = SDL-0/-RightX +RDown = SDL-0/+RightY +RUp = SDL-0/-RightY diff --git a/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/RK3399/settings.ini b/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/RK3399/settings.ini new file mode 100644 index 0000000000..4894932bf6 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/RK3399/settings.ini @@ -0,0 +1,242 @@ +[Main] +SettingsVersion = 3 +StartFullscreen = true +EmulationSpeed = 1.000000 +FastForwardSpeed = 0.000000 +TurboSpeed = 0.000000 +SyncToHostRefreshRate = false +IncreaseTimerResolution = true +InhibitScreensaver = true +StartPaused = false +PauseOnFocusLoss = false +PauseOnMenu = true +SaveStateOnExit = true +ConfirmPowerOff = false +LoadDevicesFromSaveStates = false +ApplyGameSettings = true +AutoLoadCheats = true +DisableAllEnhancements = false +RewindEnable = false +RewindFrequency = 10.000000 +RewindSaveSlots = 10 +RunaheadFrameCount = 0 +NoDesktopFile = true + + +[BIOS] +SearchDirectory = /storage/roms/bios +PathNTSCU = +PathNTSCJ = +PathPAL = +PatchTTYEnable = false +PatchFastBoot = true + + +[GPU] +Renderer = Software +Adapter = +ResolutionScale = 1 +Multisamples = 1 +UseDebugDevice = false +PerSampleShading = false +UseThread = true +ThreadedPresentation = true +UseSoftwareRendererForReadbacks = false +TrueColor = false +ScaledDithering = false +TextureFilter = Nearest +DownsampleMode = Disabled +DisableInterlacing = false +ForceNTSCTimings = false +WidescreenHack = false +ChromaSmoothing24Bit = false +PGXPEnable = false +PGXPCulling = true +PGXPTextureCorrection = true +PGXPVertexCache = false +PGXPCPU = false +PGXPPreserveProjFP = false +PGXPTolerance = -1.000000 +PGXPDepthBuffer = false +PGXPDepthClearThreshold = 300.000000 + + +[Display] +CropMode = Overscan +ActiveStartOffset = 0 +ActiveEndOffset = 0 +LineStartOffset = 0 +LineEndOffset = 0 +Force4_3For24Bit = false +AspectRatio = 4:3 +CustomAspectRatioNumerator = 4 +LinearFiltering = true +IntegerScaling = false +Stretch = false +PostProcessing = false +ShowOSDMessages = true +ShowFPS = false +ShowVPS = false +ShowSpeed = false +ShowResolution = false +ShowStatusIndicators = true +ShowEnhancements = false +DisplayAllFrames = true +VSync = false +MaxFPS = 0.000000 + + +[Hotkeys] +OpenPauseMenu = SDL-0/Back & SDL-0/X +FastForward = SDL-0/Back & SDL-0/+RightTrigger +Screenshot = SDL-0/Back & SDL-0/A +LoadSelectedSaveState = SDL-0/Back & SDL-0/LeftShoulder +SaveSelectedSaveState = SDL-0/Back & SDL-0/RightShoulder +PowerOff = SDL-0/Back & SDL-0/Start + + +[Logging] +LogLevel = Error +LogFilter = +LogToConsole = false +LogToDebug = false +LogToWindow = false +LogToFile = false + + +[GameList] +RecursivePaths = /storage/roms/psx + + +[MemoryCards] +UsePlaylistTitle = true +Directory = /storage/roms/psx +Card1Type = PerGameTitle +Card2Type = None + + +[Console] +Region = Auto +Enable8MBRAM = false + + +[CPU] +ExecutionMode = Recompiler +OverclockEnable = false +OverclockNumerator = 1 +OverclockDenominator = 1 +RecompilerMemoryExceptions = false +RecompilerBlockLinking = true +RecompilerICache = false +FastmemMode = MMap + + +[CDROM] +ReadaheadSectors = 8 +RegionCheck = false +LoadImageToRAM = false +MuteCDAudio = false +ReadSpeedup = 1 +SeekSpeedup = 1 + + +[Audio] +Backend = SDL +OutputVolume = 100 +FastForwardVolume = 100 +BufferSize = 2048 +Resampling = true +OutputMuted = false +Sync = true +DumpOnBoot = false + + +[Hacks] +DMAMaxSliceTicks = 1000 +DMAHaltTicks = 100 +GPUFIFOSize = 16 +GPUMaxRunAhead = 128 + + +[Controller1] +Type = AnalogController + + +[Controller2] +Type = None + + +[Controller3] +Type = None + + +[Controller4] +Type = None + + +[Controller5] +Type = None + + +[Controller6] +Type = None + + +[Controller7] +Type = None + + +[Controller8] +Type = None + + +[ControllerPorts] +MultitapMode = Disabled + + +[Debug] +ShowVRAM = false +DumpCPUToVRAMCopies = false +DumpVRAMToCPUCopies = false +ShowGPUState = false +ShowCDROMState = false +ShowSPUState = false +ShowTimersState = false +ShowMDECState = false +ShowDMAState = false + + +[TextureReplacements] +EnableVRAMWriteReplacements = false +PreloadTextures = false +DumpVRAMWrites = false +DumpVRAMWriteForceAlphaChannel = true +DumpVRAMWriteWidthThreshold = 128 +DumpVRAMWriteHeightThreshold = 128 + + +[Pad1] +Up = SDL-0/DPadUp +Right = SDL-0/DPadRight +Down = SDL-0/DPadDown +Left = SDL-0/DPadLeft +Triangle = SDL-0/X +Circle = SDL-0/A +Cross = SDL-0/B +Square = SDL-0/Y +Select = SDL-0/Back +Start = SDL-0/Start +L1 = SDL-0/LeftShoulder +R1 = SDL-0/RightShoulder +L2 = SDL-0/+LeftTrigger +R2 = SDL-0/+RightTrigger +L3 = SDL-0/LeftStick +R3 = SDL-0/RightStick +LLeft = SDL-0/-LeftX +LRight = SDL-0/+LeftX +LDown = SDL-0/+LeftY +LUp = SDL-0/-LeftY +RLeft = SDL-0/+RightX +RRight = SDL-0/-RightX +RDown = SDL-0/+RightY +RUp = SDL-0/-RightY diff --git a/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/RK3566/settings.ini b/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/RK3566/settings.ini new file mode 100644 index 0000000000..9750aebd96 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/RK3566/settings.ini @@ -0,0 +1,240 @@ +[Main] +SettingsVersion = 3 +StartFullscreen = true +EmulationSpeed = 1.000000 +FastForwardSpeed = 0.000000 +TurboSpeed = 0.000000 +SyncToHostRefreshRate = false +IncreaseTimerResolution = true +InhibitScreensaver = true +StartPaused = false +PauseOnFocusLoss = false +PauseOnMenu = true +SaveStateOnExit = true +ConfirmPowerOff = false +LoadDevicesFromSaveStates = false +ApplyGameSettings = true +AutoLoadCheats = true +DisableAllEnhancements = false +RewindEnable = false +RewindFrequency = 10.000000 +RewindSaveSlots = 10 +RunaheadFrameCount = 0 +NoDesktopFile = true + + +[BIOS] +SearchDirectory = /storage/roms/bios +PathNTSCU = +PathNTSCJ = +PathPAL = +PatchTTYEnable = false +PatchFastBoot = true + + +[GPU] +Renderer = Software +Adapter = +ResolutionScale = 1 +Multisamples = 1 +UseDebugDevice = false +PerSampleShading = false +UseThread = true +ThreadedPresentation = true +UseSoftwareRendererForReadbacks = false +TrueColor = false +ScaledDithering = false +TextureFilter = Nearest +DownsampleMode = Disabled +DisableInterlacing = false +ForceNTSCTimings = false +WidescreenHack = false +ChromaSmoothing24Bit = false +PGXPEnable = false +PGXPCulling = true +PGXPTextureCorrection = true +PGXPVertexCache = false +PGXPCPU = false +PGXPPreserveProjFP = false +PGXPTolerance = -1.000000 +PGXPDepthBuffer = false +PGXPDepthClearThreshold = 300.000000 + + +[Display] +CropMode = Overscan +ActiveStartOffset = 0 +ActiveEndOffset = 0 +LineStartOffset = 0 +LineEndOffset = 0 +Force4_3For24Bit = false +AspectRatio = 4:3 +CustomAspectRatioNumerator = 4 +LinearFiltering = true +IntegerScaling = false +Stretch = false +PostProcessing = false +ShowOSDMessages = true +ShowFPS = false +ShowVPS = false +ShowSpeed = false +ShowResolution = false +ShowStatusIndicators = true +ShowEnhancements = false +DisplayAllFrames = true +VSync = false +MaxFPS = 0.000000 +Rotation = 0 + + +[Hotkeys] +OpenPauseMenu = SDL-0/Back & SDL-0/X +FastForward = SDL-0/Back & SDL-0/+RightTrigger +Screenshot = SDL-0/Back & SDL-0/A +LoadSelectedSaveState = SDL-0/Back & SDL-0/LeftShoulder +SaveSelectedSaveState = SDL-0/Back & SDL-0/RightShoulder +PowerOff = SDL-0/Back & SDL-0/Start + +[Logging] +LogLevel = Error +LogFilter = +LogToConsole = false +LogToDebug = false +LogToWindow = false +LogToFile = false + + +[GameList] +RecursivePaths = /storage/roms/psx + + +[MemoryCards] +UsePlaylistTitle = true +Directory = /storage/roms/psx +Card1Type = PerGameTitle +Card2Type = None + + +[Console] +Region = Auto +Enable8MBRAM = false + + +[CPU] +ExecutionMode = Recompiler +OverclockEnable = false +OverclockNumerator = 1 +OverclockDenominator = 1 +RecompilerMemoryExceptions = false +RecompilerBlockLinking = true +RecompilerICache = false +FastmemMode = MMap + + +[CDROM] +ReadaheadSectors = 8 +RegionCheck = false +LoadImageToRAM = false +MuteCDAudio = false +ReadSpeedup = 1 +SeekSpeedup = 1 + + +[Audio] +Backend = SDL +OutputVolume = 100 +FastForwardVolume = 100 +BufferSize = 2048 +Resampling = true +OutputMuted = false +Sync = true +DumpOnBoot = false + + +[Hacks] +DMAMaxSliceTicks = 1000 +DMAHaltTicks = 100 +GPUFIFOSize = 16 +GPUMaxRunAhead = 128 + +[Controller1] +Type = AnalogController + + +[Controller2] +Type = None + + +[Controller3] +Type = None + + +[Controller4] +Type = None + + +[Controller5] +Type = None + + +[Controller6] +Type = None + + +[Controller7] +Type = None + + +[Controller8] +Type = None + + +[ControllerPorts] +MultitapMode = Disabled + + +[Debug] +ShowVRAM = false +DumpCPUToVRAMCopies = false +DumpVRAMToCPUCopies = false +ShowGPUState = false +ShowCDROMState = false +ShowSPUState = false +ShowTimersState = false +ShowMDECState = false +ShowDMAState = false + + +[TextureReplacements] +EnableVRAMWriteReplacements = false +PreloadTextures = false +DumpVRAMWrites = false +DumpVRAMWriteForceAlphaChannel = true +DumpVRAMWriteWidthThreshold = 128 +DumpVRAMWriteHeightThreshold = 128 + +[Pad1] +Up = SDL-0/DPadUp +Right = SDL-0/DPadRight +Down = SDL-0/DPadDown +Left = SDL-0/DPadLeft +Triangle = SDL-0/X +Circle = SDL-0/A +Cross = SDL-0/B +Square = SDL-0/Y +Select = SDL-0/Back +Start = SDL-0/Start +L1 = SDL-0/LeftShoulder +R1 = SDL-0/RightShoulder +L2 = SDL-0/+LeftTrigger +R2 = SDL-0/+RightTrigger +L3 = SDL-0/LeftStick +R3 = SDL-0/RightStick +LLeft = SDL-0/-LeftX +LRight = SDL-0/+LeftX +LDown = SDL-0/+LeftY +LUp = SDL-0/-LeftY +RLeft = SDL-0/+RightX +RRight = SDL-0/-RightX +RDown = SDL-0/+RightY +RUp = SDL-0/-RightY diff --git a/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/RK3588/settings.ini b/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/RK3588/settings.ini new file mode 100644 index 0000000000..07a70fac16 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/RK3588/settings.ini @@ -0,0 +1,242 @@ +[Main] +SettingsVersion = 3 +StartFullscreen = true +EmulationSpeed = 1.000000 +FastForwardSpeed = 0.000000 +TurboSpeed = 0.000000 +SyncToHostRefreshRate = false +IncreaseTimerResolution = true +InhibitScreensaver = true +StartPaused = false +PauseOnFocusLoss = false +PauseOnMenu = true +SaveStateOnExit = true +ConfirmPowerOff = false +LoadDevicesFromSaveStates = false +ApplyGameSettings = true +AutoLoadCheats = true +DisableAllEnhancements = false +RewindEnable = false +RewindFrequency = 10.000000 +RewindSaveSlots = 10 +RunaheadFrameCount = 0 +NoDesktopFile = true + + +[BIOS] +SearchDirectory = /storage/roms/bios +PathNTSCU = +PathNTSCJ = +PathPAL = +PatchTTYEnable = false +PatchFastBoot = true + + +[GPU] +Renderer = Software +Adapter = +ResolutionScale = 1 +Multisamples = 1 +UseDebugDevice = false +PerSampleShading = false +UseThread = true +ThreadedPresentation = true +UseSoftwareRendererForReadbacks = false +TrueColor = false +ScaledDithering = false +TextureFilter = Nearest +DownsampleMode = Disabled +DisableInterlacing = false +ForceNTSCTimings = false +WidescreenHack = false +ChromaSmoothing24Bit = false +PGXPEnable = false +PGXPCulling = true +PGXPTextureCorrection = true +PGXPVertexCache = false +PGXPCPU = false +PGXPPreserveProjFP = false +PGXPTolerance = -1.000000 +PGXPDepthBuffer = false +PGXPDepthClearThreshold = 300.000000 + + +[Display] +CropMode = Overscan +ActiveStartOffset = 0 +ActiveEndOffset = 0 +LineStartOffset = 0 +LineEndOffset = 0 +Force4_3For24Bit = false +AspectRatio = 4:3 +CustomAspectRatioNumerator = 4 +LinearFiltering = true +IntegerScaling = false +Stretch = false +PostProcessing = false +ShowOSDMessages = true +ShowFPS = false +ShowVPS = false +ShowSpeed = false +ShowResolution = false +ShowStatusIndicators = true +ShowEnhancements = false +DisplayAllFrames = true +VSync = false +MaxFPS = 0.000000 + + +[Hotkeys] +OpenPauseMenu = SDL-0/Guide & SDL-0/X +FastForward = SDL-0/Guide & SDL-0/+RightTrigger +Screenshot = SDL-0/Guide & SDL-0/A +LoadSelectedSaveState = SDL-0/Guide & SDL-0/LeftShoulder +SaveSelectedSaveState = SDL-0/Guide & SDL-0/RightShoulder +PowerOff = SDL-0/Guide & SDL-0/Start + + +[Logging] +LogLevel = Error +LogFilter = +LogToConsole = false +LogToDebug = false +LogToWindow = false +LogToFile = false + + +[GameList] +RecursivePaths = /storage/roms/psx + + +[MemoryCards] +UsePlaylistTitle = true +Directory = /storage/roms/psx +Card1Type = PerGameTitle +Card2Type = None + + +[Console] +Region = Auto +Enable8MBRAM = false + + +[CPU] +ExecutionMode = Recompiler +OverclockEnable = false +OverclockNumerator = 1 +OverclockDenominator = 1 +RecompilerMemoryExceptions = false +RecompilerBlockLinking = true +RecompilerICache = false +FastmemMode = MMap + + +[CDROM] +ReadaheadSectors = 8 +RegionCheck = false +LoadImageToRAM = false +MuteCDAudio = false +ReadSpeedup = 1 +SeekSpeedup = 1 + + +[Audio] +Backend = SDL +OutputVolume = 100 +FastForwardVolume = 100 +BufferSize = 2048 +Resampling = true +OutputMuted = false +Sync = true +DumpOnBoot = false + + +[Hacks] +DMAMaxSliceTicks = 1000 +DMAHaltTicks = 100 +GPUFIFOSize = 16 +GPUMaxRunAhead = 128 + + +[Controller1] +Type = AnalogController + + +[Controller2] +Type = None + + +[Controller3] +Type = None + + +[Controller4] +Type = None + + +[Controller5] +Type = None + + +[Controller6] +Type = None + + +[Controller7] +Type = None + + +[Controller8] +Type = None + + +[ControllerPorts] +MultitapMode = Disabled + + +[Debug] +ShowVRAM = false +DumpCPUToVRAMCopies = false +DumpVRAMToCPUCopies = false +ShowGPUState = false +ShowCDROMState = false +ShowSPUState = false +ShowTimersState = false +ShowMDECState = false +ShowDMAState = false + + +[TextureReplacements] +EnableVRAMWriteReplacements = false +PreloadTextures = false +DumpVRAMWrites = false +DumpVRAMWriteForceAlphaChannel = true +DumpVRAMWriteWidthThreshold = 128 +DumpVRAMWriteHeightThreshold = 128 + + +[Pad1] +Up = SDL-0/DPadUp +Right = SDL-0/DPadRight +Down = SDL-0/DPadDown +Left = SDL-0/DPadLeft +Triangle = SDL-0/X +Circle = SDL-0/A +Cross = SDL-0/B +Square = SDL-0/Y +Select = SDL-0/Back +Start = SDL-0/Start +L1 = SDL-0/LeftShoulder +R1 = SDL-0/RightShoulder +L2 = SDL-0/+LeftTrigger +R2 = SDL-0/+RightTrigger +L3 = SDL-0/LeftStick +R3 = SDL-0/RightStick +LLeft = SDL-0/-LeftX +LRight = SDL-0/+LeftX +LDown = SDL-0/+LeftY +LUp = SDL-0/-LeftY +RLeft = SDL-0/-RightX +RRight = SDL-0/+RightX +RDown = SDL-0/+RightY +RUp = SDL-0/-RightY diff --git a/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/S922X/settings.ini b/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/S922X/settings.ini new file mode 100644 index 0000000000..8cab1f305f --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/S922X/settings.ini @@ -0,0 +1,321 @@ +[Main] +SettingsVersion = 3 +EmulationSpeed = 1.000000 +FastForwardSpeed = 0.000000 +TurboSpeed = 0.000000 +SyncToHostRefreshRate = false +IncreaseTimerResolution = true +InhibitScreensaver = true +StartPaused = false +StartFullscreen = true +PauseOnFocusLoss = false +PauseOnMenu = true +SaveStateOnExit = true +CreateSaveStateBackups = true +CompressSaveStates = true +ConfirmPowerOff = false +LoadDevicesFromSaveStates = false +ApplyCompatibilitySettings = true +ApplyGameSettings = true +AutoLoadCheats = true +DisableAllEnhancements = false +RewindEnable = false +RewindFrequency = 10.000000 +RewindSaveSlots = 10 +RunaheadFrameCount = 0 +NoDesktopFile = true + + +[Console] +Region = Auto +Enable8MBRAM = false + + +[CPU] +ExecutionMode = Recompiler +OverclockEnable = false +OverclockNumerator = 1 +OverclockDenominator = 1 +RecompilerMemoryExceptions = false +RecompilerBlockLinking = true +RecompilerICache = false +FastmemMode = MMap + + +[GPU] +Renderer = Software +Adapter = +ResolutionScale = 1 +Multisamples = 1 +UseDebugDevice = false +PerSampleShading = false +UseThread = true +ThreadedPresentation = true +UseSoftwareRendererForReadbacks = false +TrueColor = true +ScaledDithering = true +TextureFilter = Nearest +DownsampleMode = Disabled +DisableInterlacing = true +ForceNTSCTimings = false +WidescreenHack = false +ChromaSmoothing24Bit = false +PGXPEnable = false +PGXPCulling = true +PGXPTextureCorrection = true +PGXPVertexCache = false +PGXPCPU = false +PGXPPreserveProjFP = false +PGXPTolerance = -1.000000 +PGXPDepthBuffer = false +PGXPDepthClearThreshold = 1228800.000000 +FullscreenMode = + + +[Display] +CropMode = Overscan +ActiveStartOffset = 0 +ActiveEndOffset = 0 +LineStartOffset = 0 +LineEndOffset = 0 +Force4_3For24Bit = false +AspectRatio = Auto (Game Native) +CustomAspectRatioNumerator = 0 +LinearFiltering = true +IntegerScaling = false +Stretch = false +PostProcessing = false +ShowOSDMessages = true +ShowFPS = false +ShowSpeed = false +ShowResolution = false +ShowCPU = false +ShowGPU = false +ShowStatusIndicators = true +ShowInputs = false +ShowEnhancements = false +DisplayAllFrames = false +InternalResolutionScreenshots = false +VSync = false +MaxFPS = 0.000000 +OSDScale = 100.000000 + + +[CDROM] +ReadaheadSectors = 8 +RegionCheck = false +LoadImageToRAM = false +LoadImagePatches = false +MuteCDAudio = false +ReadSpeedup = 1 +SeekSpeedup = 1 + + +[Audio] +Backend = Cubeb +Driver = +StretchMode = TimeStretch +BufferMS = 50 +OutputLatencyMS = 20 +OutputVolume = 100 +FastForwardVolume = 100 +OutputMuted = false +DumpOnBoot = false + + +[Hacks] +DMAMaxSliceTicks = 1000 +DMAHaltTicks = 100 +GPUFIFOSize = 16 +GPUMaxRunAhead = 128 + + +[BIOS] +SearchDirectory = /storage/roms/bios +PathNTSCU = +PathNTSCJ = +PathPAL = +PatchTTYEnable = false +PatchFastBoot = true + + +[Controller1] +Type = AnalogController + + +[Controller2] +Type = None + + +[Controller3] +Type = None + + +[Controller4] +Type = None + + +[Controller5] +Type = None + + +[Controller6] +Type = None + + +[Controller7] +Type = None + + +[Controller8] +Type = None + + +[MemoryCards] +Card1Type = PerGameTitle +Card2Type = None +UsePlaylistTitle = true +Directory = memcards + + +[ControllerPorts] +MultitapMode = Disabled +PointerXScale = 8.000000 +PointerYScale = 8.000000 +PointerXInvert = false +PointerYInvert = false + + +[Cheevos] +Enabled = false +TestMode = false +UnofficialTestMode = false +UseFirstDiscFromPlaylist = true +RichPresence = false +ChallengeMode = false + + +[Logging] +LogLevel = Error +LogFilter = +LogToConsole = false +LogToDebug = false +LogToWindow = false +LogToFile = false + + +[Debug] +ShowVRAM = false +DumpCPUToVRAMCopies = false +DumpVRAMToCPUCopies = false +ShowGPUState = false +ShowCDROMState = false +ShowSPUState = false +ShowTimersState = false +ShowMDECState = false +ShowDMAState = false + + +[TextureReplacements] +EnableVRAMWriteReplacements = false +PreloadTextures = false +DumpVRAMWrites = false +DumpVRAMWriteForceAlphaChannel = true +DumpVRAMWriteWidthThreshold = 128 +DumpVRAMWriteHeightThreshold = 128 + + +[Folders] +Cache = cache +Cheats = cheats +Covers = covers +Dumps = dump +GameSettings = gamesettings +InputProfiles = inputprofiles +SaveStates = savestates +Screenshots = screenshots +Shaders = shaders +Textures = textures + + +[InputSources] +SDL = true +SDLControllerEnhancedMode = false +Evdev = false +XInput = false +RawInput = false + + +[Pad1] +Up = SDL-0/DPadUp +Right = SDL-0/DPadRight +Down = SDL-0/DPadDown +Left = SDL-0/DPadLeft +Triangle = SDL-0/X +Circle = SDL-0/A +Cross = SDL-0/B +Square = SDL-0/Y +Select = SDL-0/Back +Start = SDL-0/Start +L1 = SDL-0/LeftShoulder +R1 = SDL-0/RightShoulder +L2 = SDL-0/+LeftTrigger +R2 = SDL-0/+RightTrigger +L3 = SDL-0/LeftStick +R3 = SDL-0/RightStick +LLeft = SDL-0/-LeftX +LRight = SDL-0/+LeftX +LDown = SDL-0/+LeftY +LUp = SDL-0/-LeftY +RLeft = SDL-0/-RightX +RRight = SDL-0/+RightX +RDown = SDL-0/+RightY +RUp = SDL-0/-RightY + + +[Pad2] +Type = None + + +[Pad3] +Type = None + + +[Pad4] +Type = None + + +[Pad5] +Type = None + + +[Pad6] +Type = None + + +[Pad7] +Type = None + + +[Pad8] +Type = None + + +[Hotkeys] +OpenPauseMenu = SDL-0/Guide & SDL-0/X +FastForward = SDL-0/Guide & SDL-0/+RightTrigger +Screenshot = SDL-0/Guide & SDL-0/A +LoadSelectedSaveState = SDL-0/Guide & SDL-0/LeftShoulder +SaveSelectedSaveState = SDL-0/Guide & SDL-0/RightShoulder +PowerOff = SDL-0/Guide & SDL-0/Start + + +[NoGUI] +WindowX = 0 +WindowY = 0 +WindowWidth = 854 +WindowHeight = 480 + + +[GameList] +RecursivePaths = /storage/roms/psx diff --git a/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/SDM845/settings.ini b/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/SDM845/settings.ini new file mode 100644 index 0000000000..362f424d47 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/SDM845/settings.ini @@ -0,0 +1,264 @@ +[Main] +SettingsVersion = 3 +StartFullscreen = true +EmulationSpeed = 1.000000 +FastForwardSpeed = 0.000000 +TurboSpeed = 0.000000 +SyncToHostRefreshRate = false +IncreaseTimerResolution = true +InhibitScreensaver = true +StartPaused = false +PauseOnFocusLoss = false +PauseOnMenu = true +SaveStateOnExit = true +ConfirmPowerOff = false +LoadDevicesFromSaveStates = false +ApplyGameSettings = true +AutoLoadCheats = true +DisableAllEnhancements = false +RewindEnable = false +RewindFrequency = 10.000000 +RewindSaveSlots = 10 +RunaheadFrameCount = 0 +NoDesktopFile = true + + +[BIOS] +SearchDirectory = /storage/roms/bios +PathNTSCU = +PathNTSCJ = +PathPAL = +PatchTTYEnable = false +PatchFastBoot = true + + +[GPU] +Renderer = Software +Adapter = +ResolutionScale = 1 +Multisamples = 1 +UseDebugDevice = false +PerSampleShading = false +UseThread = true +ThreadedPresentation = true +UseSoftwareRendererForReadbacks = false +TrueColor = false +ScaledDithering = false +TextureFilter = Nearest +DownsampleMode = Disabled +DisableInterlacing = false +ForceNTSCTimings = false +WidescreenHack = false +ChromaSmoothing24Bit = false +PGXPEnable = false +PGXPCulling = true +PGXPTextureCorrection = true +PGXPVertexCache = false +PGXPCPU = false +PGXPPreserveProjFP = false +PGXPTolerance = -1.000000 +PGXPDepthBuffer = false +PGXPDepthClearThreshold = 300.000000 + + +[Display] +CropMode = Overscan +ActiveStartOffset = 0 +ActiveEndOffset = 0 +LineStartOffset = 0 +LineEndOffset = 0 +Force4_3For24Bit = false +AspectRatio = 4:3 +CustomAspectRatioNumerator = 4 +LinearFiltering = true +IntegerScaling = false +Stretch = false +PostProcessing = false +ShowOSDMessages = true +ShowFPS = false +ShowVPS = false +ShowSpeed = false +ShowResolution = false +ShowStatusIndicators = true +ShowEnhancements = false +DisplayAllFrames = true +VSync = true +MaxFPS = 0.000000 + + +[Hotkeys] +OpenPauseMenu = SDL-0/Guide & SDL-0/X +FastForward = SDL-0/Guide & SDL-0/+RightTrigger +Screenshot = SDL-0/Back & SDL-0/A +LoadSelectedSaveState = SDL-0/Guide & SDL-0/LeftShoulder +SaveSelectedSaveState = SDL-0/Guide & SDL-0/RightShoulder +PowerOff = SDL-0/Guide & SDL-0/Start + + +[Logging] +LogLevel = Error +LogFilter = +LogToConsole = false +LogToDebug = false +LogToWindow = false +LogToFile = false + + +[Controller1] +Type = AnalogController +ButtonUp = Controller0/Button11 +ButtonDown = Controller0/Button12 +ButtonLeft = Controller0/Button13 +ButtonRight = Controller0/Button14 +ButtonSelect = Controller0/Button4 +ButtonStart = Controller0/Button6 +ButtonTriangle = Controller0/Button2 +ButtonCross = Controller0/Button1 +ButtonSquare = Controller0/Button3 +ButtonCircle = Controller0/Button0 +ButtonL1 = Controller0/Button9 +ButtonL2 = Controller0/+Axis4 +ButtonR1 = Controller0/Button10 +ButtonR2 = Controller0/+Axis5 +AxisLeftX = Controller0/Axis0 +AxisLeftY = Controller0/Axis1 +ButtonL3 = Controller0/Button7 +ButtonR3 = Controller0/Button8 +AxisRightX = Controller0/Axis2 +AxisRightY = Controller0/Axis3 +AnalogDPadInDigitalMode = false + + +[GameList] +RecursivePaths = /storage/roms/psx + + +[MemoryCards] +UsePlaylistTitle = true +Directory = /storage/roms/psx +Card1Type = PerGameTitle +Card2Type = None + + +[Console] +Region = Auto +Enable8MBRAM = false + + +[CPU] +ExecutionMode = Recompiler +OverclockEnable = false +OverclockNumerator = 1 +OverclockDenominator = 1 +RecompilerMemoryExceptions = false +RecompilerBlockLinking = true +RecompilerICache = false +FastmemMode = MMap + + +[CDROM] +ReadaheadSectors = 8 +RegionCheck = false +LoadImageToRAM = false +MuteCDAudio = false +ReadSpeedup = 1 +SeekSpeedup = 1 + + +[Audio] +Backend = SDL +OutputVolume = 100 +FastForwardVolume = 100 +BufferSize = 2048 +Resampling = true +OutputMuted = false +Sync = true +DumpOnBoot = false +BufferMS = 100 + + +[Hacks] +DMAMaxSliceTicks = 1000 +DMAHaltTicks = 100 +GPUFIFOSize = 16 +GPUMaxRunAhead = 128 + + +[Controller2] +Type = None + + +[Controller3] +Type = None + + +[Controller4] +Type = None + + +[Controller5] +Type = None + + +[Controller6] +Type = None + + +[Controller7] +Type = None + + +[Controller8] +Type = None + + +[ControllerPorts] +MultitapMode = Disabled + + +[Debug] +ShowVRAM = false +DumpCPUToVRAMCopies = false +DumpVRAMToCPUCopies = false +ShowGPUState = false +ShowCDROMState = false +ShowSPUState = false +ShowTimersState = false +ShowMDECState = false +ShowDMAState = false + + +[TextureReplacements] +EnableVRAMWriteReplacements = false +PreloadTextures = false +DumpVRAMWrites = false +DumpVRAMWriteForceAlphaChannel = true +DumpVRAMWriteWidthThreshold = 128 +DumpVRAMWriteHeightThreshold = 128 + + +[Pad1] +Up = SDL-0/DPadUp +Right = SDL-0/DPadRight +Down = SDL-0/DPadDown +Left = SDL-0/DPadLeft +Triangle = SDL-0/X +Circle = SDL-0/A +Cross = SDL-0/B +Square = SDL-0/Y +Select = SDL-0/Back +Start = SDL-0/Start +L1 = SDL-0/LeftShoulder +R1 = SDL-0/RightShoulder +L2 = SDL-0/+LeftTrigger +R2 = SDL-0/+RightTrigger +L3 = SDL-0/LeftStick +R3 = SDL-0/RightStick +LLeft = SDL-0/-LeftX +LRight = SDL-0/+LeftX +LDown = SDL-0/+LeftY +LUp = SDL-0/-LeftY +RLeft = SDL-0/+RightX +RRight = SDL-0/-RightX +RDown = SDL-0/+RightY +RUp = SDL-0/-RightY diff --git a/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/SM8250/settings.ini b/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/SM8250/settings.ini new file mode 100644 index 0000000000..362f424d47 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/SM8250/settings.ini @@ -0,0 +1,264 @@ +[Main] +SettingsVersion = 3 +StartFullscreen = true +EmulationSpeed = 1.000000 +FastForwardSpeed = 0.000000 +TurboSpeed = 0.000000 +SyncToHostRefreshRate = false +IncreaseTimerResolution = true +InhibitScreensaver = true +StartPaused = false +PauseOnFocusLoss = false +PauseOnMenu = true +SaveStateOnExit = true +ConfirmPowerOff = false +LoadDevicesFromSaveStates = false +ApplyGameSettings = true +AutoLoadCheats = true +DisableAllEnhancements = false +RewindEnable = false +RewindFrequency = 10.000000 +RewindSaveSlots = 10 +RunaheadFrameCount = 0 +NoDesktopFile = true + + +[BIOS] +SearchDirectory = /storage/roms/bios +PathNTSCU = +PathNTSCJ = +PathPAL = +PatchTTYEnable = false +PatchFastBoot = true + + +[GPU] +Renderer = Software +Adapter = +ResolutionScale = 1 +Multisamples = 1 +UseDebugDevice = false +PerSampleShading = false +UseThread = true +ThreadedPresentation = true +UseSoftwareRendererForReadbacks = false +TrueColor = false +ScaledDithering = false +TextureFilter = Nearest +DownsampleMode = Disabled +DisableInterlacing = false +ForceNTSCTimings = false +WidescreenHack = false +ChromaSmoothing24Bit = false +PGXPEnable = false +PGXPCulling = true +PGXPTextureCorrection = true +PGXPVertexCache = false +PGXPCPU = false +PGXPPreserveProjFP = false +PGXPTolerance = -1.000000 +PGXPDepthBuffer = false +PGXPDepthClearThreshold = 300.000000 + + +[Display] +CropMode = Overscan +ActiveStartOffset = 0 +ActiveEndOffset = 0 +LineStartOffset = 0 +LineEndOffset = 0 +Force4_3For24Bit = false +AspectRatio = 4:3 +CustomAspectRatioNumerator = 4 +LinearFiltering = true +IntegerScaling = false +Stretch = false +PostProcessing = false +ShowOSDMessages = true +ShowFPS = false +ShowVPS = false +ShowSpeed = false +ShowResolution = false +ShowStatusIndicators = true +ShowEnhancements = false +DisplayAllFrames = true +VSync = true +MaxFPS = 0.000000 + + +[Hotkeys] +OpenPauseMenu = SDL-0/Guide & SDL-0/X +FastForward = SDL-0/Guide & SDL-0/+RightTrigger +Screenshot = SDL-0/Back & SDL-0/A +LoadSelectedSaveState = SDL-0/Guide & SDL-0/LeftShoulder +SaveSelectedSaveState = SDL-0/Guide & SDL-0/RightShoulder +PowerOff = SDL-0/Guide & SDL-0/Start + + +[Logging] +LogLevel = Error +LogFilter = +LogToConsole = false +LogToDebug = false +LogToWindow = false +LogToFile = false + + +[Controller1] +Type = AnalogController +ButtonUp = Controller0/Button11 +ButtonDown = Controller0/Button12 +ButtonLeft = Controller0/Button13 +ButtonRight = Controller0/Button14 +ButtonSelect = Controller0/Button4 +ButtonStart = Controller0/Button6 +ButtonTriangle = Controller0/Button2 +ButtonCross = Controller0/Button1 +ButtonSquare = Controller0/Button3 +ButtonCircle = Controller0/Button0 +ButtonL1 = Controller0/Button9 +ButtonL2 = Controller0/+Axis4 +ButtonR1 = Controller0/Button10 +ButtonR2 = Controller0/+Axis5 +AxisLeftX = Controller0/Axis0 +AxisLeftY = Controller0/Axis1 +ButtonL3 = Controller0/Button7 +ButtonR3 = Controller0/Button8 +AxisRightX = Controller0/Axis2 +AxisRightY = Controller0/Axis3 +AnalogDPadInDigitalMode = false + + +[GameList] +RecursivePaths = /storage/roms/psx + + +[MemoryCards] +UsePlaylistTitle = true +Directory = /storage/roms/psx +Card1Type = PerGameTitle +Card2Type = None + + +[Console] +Region = Auto +Enable8MBRAM = false + + +[CPU] +ExecutionMode = Recompiler +OverclockEnable = false +OverclockNumerator = 1 +OverclockDenominator = 1 +RecompilerMemoryExceptions = false +RecompilerBlockLinking = true +RecompilerICache = false +FastmemMode = MMap + + +[CDROM] +ReadaheadSectors = 8 +RegionCheck = false +LoadImageToRAM = false +MuteCDAudio = false +ReadSpeedup = 1 +SeekSpeedup = 1 + + +[Audio] +Backend = SDL +OutputVolume = 100 +FastForwardVolume = 100 +BufferSize = 2048 +Resampling = true +OutputMuted = false +Sync = true +DumpOnBoot = false +BufferMS = 100 + + +[Hacks] +DMAMaxSliceTicks = 1000 +DMAHaltTicks = 100 +GPUFIFOSize = 16 +GPUMaxRunAhead = 128 + + +[Controller2] +Type = None + + +[Controller3] +Type = None + + +[Controller4] +Type = None + + +[Controller5] +Type = None + + +[Controller6] +Type = None + + +[Controller7] +Type = None + + +[Controller8] +Type = None + + +[ControllerPorts] +MultitapMode = Disabled + + +[Debug] +ShowVRAM = false +DumpCPUToVRAMCopies = false +DumpVRAMToCPUCopies = false +ShowGPUState = false +ShowCDROMState = false +ShowSPUState = false +ShowTimersState = false +ShowMDECState = false +ShowDMAState = false + + +[TextureReplacements] +EnableVRAMWriteReplacements = false +PreloadTextures = false +DumpVRAMWrites = false +DumpVRAMWriteForceAlphaChannel = true +DumpVRAMWriteWidthThreshold = 128 +DumpVRAMWriteHeightThreshold = 128 + + +[Pad1] +Up = SDL-0/DPadUp +Right = SDL-0/DPadRight +Down = SDL-0/DPadDown +Left = SDL-0/DPadLeft +Triangle = SDL-0/X +Circle = SDL-0/A +Cross = SDL-0/B +Square = SDL-0/Y +Select = SDL-0/Back +Start = SDL-0/Start +L1 = SDL-0/LeftShoulder +R1 = SDL-0/RightShoulder +L2 = SDL-0/+LeftTrigger +R2 = SDL-0/+RightTrigger +L3 = SDL-0/LeftStick +R3 = SDL-0/RightStick +LLeft = SDL-0/-LeftX +LRight = SDL-0/+LeftX +LDown = SDL-0/+LeftY +LUp = SDL-0/-LeftY +RLeft = SDL-0/+RightX +RRight = SDL-0/-RightX +RDown = SDL-0/+RightY +RUp = SDL-0/-RightY diff --git a/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/SM8550 b/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/SM8550 new file mode 120000 index 0000000000..72081d3859 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/SM8550 @@ -0,0 +1 @@ +InputPlumber \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/SM8650 b/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/SM8650 new file mode 120000 index 0000000000..72081d3859 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/duckstation-sa/config/SM8650 @@ -0,0 +1 @@ +InputPlumber \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/duckstation-sa/package.mk b/projects/ArchR/packages/emulators/standalone/duckstation-sa/package.mk new file mode 100644 index 0000000000..ed691a1dab --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/duckstation-sa/package.mk @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="duckstation-sa" +PKG_LICENSE="GPLv3" +PKG_DEPENDS_TARGET="toolchain" +PKG_SITE="https://github.com/stenzek/duckstation" +PKG_VERSION="0.1-10861" +PKG_LONGDESC="Fast PlayStation 1 emulator for x86-64/AArch32/AArch64 " +PKG_TOOLCHAIN="manual" + +case ${TARGET_ARCH} in + x86_64) + PKG_URL="${PKG_SITE}/releases/download/v${PKG_VERSION}/DuckStation-x64.AppImage" + ;; + aarch64) + PKG_URL="${PKG_SITE}/releases/download/v${PKG_VERSION}/DuckStation-arm64.AppImage" + ;; +esac + +install_script() { + if [ ! -d "${INSTALL}/usr/config/modules" ] + then + mkdir -p ${INSTALL}/usr/config/modules + fi + cp -rf ${PKG_DIR}/sources/"${1}" ${INSTALL}/usr/config/modules + chmod 0755 ${INSTALL}/usr/config/modules/"${1}" +} + +makeinstall_target() { + # Redefine strip or the AppImage will be stripped rendering it unusable. + export STRIP=true + mkdir -p ${INSTALL}/usr/bin + cp ${PKG_BUILD}/${PKG_NAME}-${PKG_VERSION}.AppImage ${INSTALL}/usr/bin/${PKG_NAME} + cp -rf ${PKG_DIR}/scripts/*.sh ${INSTALL}/usr/bin + chmod 755 ${INSTALL}/usr/bin/* + + mkdir -p ${INSTALL}/usr/config/duckstation + cp -rf ${PKG_DIR}/config/${DEVICE}/* ${INSTALL}/usr/config/duckstation + + install_script "Start Duckstation.sh" +} diff --git a/projects/ArchR/packages/emulators/standalone/duckstation-sa/scripts/cheevos_duckstation.sh b/projects/ArchR/packages/emulators/standalone/duckstation-sa/scripts/cheevos_duckstation.sh new file mode 100644 index 0000000000..f6fd1e4cb6 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/duckstation-sa/scripts/cheevos_duckstation.sh @@ -0,0 +1,66 @@ +#! /bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present Hector Calvarro (https://github.com/kelvfimer) +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile + +DUCK_CFG="/storage/.config/duckstation/settings.ini" +LOG_FILE="/var/log/cheevos.log" + +# Extract username, password, token, if enabled, and hardcore mode from system.cfg +username=$(get_setting "global.retroachievements.username") +password=$(get_setting "global.retroachievements.password") +token=$(get_setting "global.retroachievements.token") +enabled=$(get_setting "global.retroachievements") +hardcore=$(get_setting "global.retroachievements.hardcore") + +# Check if RetroAchievements are enabled in Emulation Station +if [ ! ${enabled} = 1 ]; then + echo "RetroAchievements are not enabled, please turn them on in Emulation Station." > ${LOG_FILE} + sed -i '/\[Cheevos\]/,/^\s*$/s/Enabled =.*/Enabled = false/' ${DUCK_CFG} + exit 1 +fi + +# Check if api token is present in system.cfg +if [ -z "${token}" ]; then + echo "RetroAchievements token is empty, please log in with your RetroAchievements credentials in Emulation Station." > ${LOG_FILE} + exit 1 +fi + +# Set hardcore mode +if [ "${hardcore}" = 1 ]; then + hardcore="true" +else + hardcore="false" +fi + +# Update emulator config with RetroAchievements settings +zcheevos=$(grep -Fx "[Cheevos]" ${DUCK_CFG}) +datets=$(date +%s%N | cut -b1-13) + +if [ -z "${zcheevos}" ]; then + sed -i "\$a [Cheevos]\nEnabled = true\nUsername = ${username}\nToken = ${token}\nLoginTimestamp = ${datets}\nChallengeMode = ${hardcore}" ${DUCK_CFG} +else + sed -i '/\[Cheevos\]/,/^\s*$/s/Enabled =.*/Enabled = true/' ${DUCK_CFG} + if ! grep -q "^Username = " ${DUCK_CFG}; then + sed -i "/^\[Cheevos\]/a Username = ${username}" ${DUCK_CFG} + else + sed -i "/^\[Cheevos\]/,/^\[/{s/^Username = .*/Username = ${username}/;}" ${DUCK_CFG} + fi + + if ! grep -q "^Token = " ${DUCK_CFG}; then + sed -i "/^\[Cheevos\]/a Token = ${token}" ${DUCK_CFG} + else + sed -i "/^\[Cheevos\]/,/^\[/{s/^Token = .*/Token = ${token}/;}" ${DUCK_CFG} + fi + + if ! grep -q "^ChallengeMode = " ${DUCK_CFG}; then + sed -i "/^\[Cheevos\]/a ChallengeMode = ${hardcore}" ${DUCK_CFG} + else + sed -i "/^\[Cheevos\]/,/^\[/{s/^ChallengeMode = .*/ChallengeMode = ${hardcore}/;}" ${DUCK_CFG} + fi + + sed -i "/^\[Cheevos\]/,/^\[/{s/^LoginTimestamp = .*/LoginTimestamp = ${datets}/;}" ${DUCK_CFG} +fi diff --git a/projects/ArchR/packages/emulators/standalone/duckstation-sa/scripts/start_duckstation.sh b/projects/ArchR/packages/emulators/standalone/duckstation-sa/scripts/start_duckstation.sh new file mode 100644 index 0000000000..db64c6f82d --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/duckstation-sa/scripts/start_duckstation.sh @@ -0,0 +1,126 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile +set_kill set "-9 duckstation-mini" + +# Filesystem vars +IMMUTABLE_CONF_DIR="/usr/config/duckstation" +IMMUTABLE_CONF_FILE="${IMMUTABLE_CONF_DIR}/settings.ini" +APPIMAGE_CONF_DIR="/storage/.local/share/duckstation" +CONF_DIR="/storage/.config/duckstation" +CONF_FILE="${CONF_DIR}/settings.ini" +SAVESTATES_DIR="/storage/roms/savestates/psx" +MEMCARDS_DIR="/storage/roms/psx/duckstation/memcards" + +#Init config dir if required +[ ! -d "${CONF_DIR}" ] && cp -r "${IMMUTABLE_CONF_DIR}" /storage/.config + +#Init config file if required +[ ! -f "${CONF_FILE}" ] && cp ${IMMUTABLE_CONF_FILE} ${CONF_FILE} + +#Link config dir to where appimage can find it +mkdir -p /storage/.local/share +rm -rf "${APPIMAGE_CONF_DIR}" +ln -sfv "${CONF_DIR}" "${APPIMAGE_CONF_DIR}" + +#Link savestates to roms/savestates +[ ! -d "${SAVESTATES_DIR}" ] && mkdir -p "${SAVESTATES_DIR}" +[ -d "${CONF_DIR}/savestates" ] && rm -rf "${CONF_DIR}/savestates" +ln -sfv "${SAVESTATES_DIR}" "${CONF_DIR}/savestates" + +# Link memcards to roms +if [ ! -d "${MEMCARDS_DIR}" ]; then + mkdir -p ${MEMCARDS_DIR} + + # Migrate any existing memcards + if [ -d "${CONF_DIR}/memcards" ]; then + cp -rf ${CONF_DIR}/memcards/* ${MEMCARDS_DIR} + fi +fi + +[ -d "${CONF_DIR}/memcards" ] && rm -rf ${CONF_DIR}/memcards +ln -sfv ${MEMCARDS_DIR} ${CONF_DIR}/memcards + +#Link gamecontrollerdb.txt +ln -sf /usr/config/SDL-GameControllerDB/gamecontrollerdb.txt "${CONF_DIR}/gamecontrollerdb.txt" + +#Emulation Station Features +GAME=$(echo "${1}"| sed "s#^/.*/##") +PLATFORM=$(echo "${2}"| sed "s#^/.*/##") +ASPECT=$(get_setting aspect_ratio "${PLATFORM}" "${GAME}") +FPS=$(get_setting show_fps "${PLATFORM}" "${GAME}") +IRES=$(get_setting internal_resolution "${PLATFORM}" "${GAME}") +RENDERER=$(get_setting graphics_backend "${PLATFORM}" "${GAME}") +VSYNC=$(get_setting vsync "${PLATFORM}" "${GAME}") + +#Set the cores to use +CORES=$(get_setting "cores" "${PLATFORM}" "${GAME}") +if [ "${CORES}" = "little" ] +then + EMUPERF="${SLOW_CORES}" +elif [ "${CORES}" = "big" ] +then + EMUPERF="${FAST_CORES}" +else + ### All.. + unset EMUPERF +fi + + #Aspect Ratio + if [ "$ASPECT" = "1" ]; then + sed -i '/^AspectRatio/c\AspectRatio = 16:9' ${CONF_FILE} + elif [ "$ASPECT" = "2" ]; then + sed -i '/^AspectRatio/c\AspectRatio = Stretch To Fill' ${CONF_FILE} + else + #Default to 4:3 aspect ratio + sed -i '/^AspectRatio/c\AspectRatio = 4:3' ${CONF_FILE} + fi + + #Show FPS + if [ "$FPS" = "true" ]; then + sed -i '/^ShowFPS/c\ShowFPS = true' ${CONF_FILE} + else + #Default to not show FPS + sed -i '/^ShowFPS/c\ShowFPS = false' ${CONF_FILE} + fi + + #Internal Resolution + if [ "$IRES" = "2" ]; then + sed -i '/^ResolutionScale =/c\ResolutionScale = 2' ${CONF_FILE} + elif [ "$IRES" = "3" ]; then + sed -i '/^ResolutionScale =/c\ResolutionScale = 3' ${CONF_FILE} + elif [ "$IRES" = "4" ]; then + sed -i '/^ResolutionScale =/c\ResolutionScale = 4' ${CONF_FILE} + elif [ "$IRES" = "5" ]; then + sed -i '/^ResolutionScale =/c\ResolutionScale = 5' ${CONF_FILE} + else + #Default to native resolution + sed -i '/^ResolutionScale =/c\ResolutionScale = 1' ${CONF_FILE} + fi + + #Video Backend + if [ "$RENDERER" = "opengl" ]; then + sed -i '/^Renderer =/c\Renderer = OpenGL' ${CONF_FILE} + elif [ "$RENDERER" = "vulkan" ]; then + sed -i '/^Renderer =/c\Renderer = Vulkan' ${CONF_FILE} + else + #Default to software renderer + sed -i '/^Renderer =/c\Renderer = Software' ${CONF_FILE} + fi + + #VSYNC + if [ "$VSYNC" = "off" ]; then + sed -i '/^VSync =/c\VSync = false' ${CONF_FILE} + else + #Default to vsync on + sed -i '/^VSync =/c\VSync = true' ${CONF_FILE} + fi + +#Retroachievements +/usr/bin/cheevos_duckstation.sh + +#Run Duckstation +${EMUPERF} duckstation-sa -fullscreen -bigpicture -nogui -- "${1}" > /dev/null 2>&1 diff --git a/projects/ArchR/packages/emulators/standalone/duckstation-sa/sources/Start Duckstation.sh b/projects/ArchR/packages/emulators/standalone/duckstation-sa/sources/Start Duckstation.sh new file mode 100644 index 0000000000..635587de29 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/duckstation-sa/sources/Start Duckstation.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile +set_kill set "-9 duckstation-sa" + +# Filesystem vars +IMMUTABLE_CONF_DIR="/usr/config/duckstation" +IMMUTABLE_CONF_FILE="${IMMUTABLE_CONF_DIR}/settings.ini" +APPIMAGE_CONF_DIR="/storage/.local/share/duckstation" +CONF_DIR="/storage/.config/duckstation" +CONF_FILE="${CONF_DIR}/settings.ini" + +#Init config dir if required +[ ! -d "${CONF_DIR}" ] && cp -r "${IMMUTABLE_CONF_DIR}" /storage/.config + +#Link config dir to where appimage can find it +mkdir -p /storage/.local/share +rm -rf "${APPIMAGE_CONF_DIR}" +ln -sfv "${CONF_DIR}" "${APPIMAGE_CONF_DIR}" + +#Init config file if required +[ ! -f "${CONF_FILE}" ] && cp ${IMMUTABLE_CONF_FILE} ${CONF_FILE} + +#Link gamecontrollerdb.txt +ln -sf /usr/config/SDL-GameControllerDB/gamecontrollerdb.txt "${CONF_DIR}/gamecontrollerdb.txt" + +/usr/bin/duckstation-sa -fullscreen -bigpicture diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/config/H700/emu.cfg b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/H700/emu.cfg new file mode 100644 index 0000000000..ce42e97956 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/H700/emu.cfg @@ -0,0 +1,13 @@ +[audio] +backend = pulse + +[input] +maple_sdl_joystick_0 = 0 +maple_sdl_joystick_1 = 1 + +device1 = 0 +device1.1 = 1 +device1.2 = 1 +device2 = 0 +device2.1 = 1 +device2.2 = 1 diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/config/H700/mappings/SDL_H700 Gamepad.cfg b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/H700/mappings/SDL_H700 Gamepad.cfg new file mode 100644 index 0000000000..33743839c1 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/H700/mappings/SDL_H700 Gamepad.cfg @@ -0,0 +1,32 @@ +[analog] +bind0 = 0-:btn_analog_left +bind1 = 0+:btn_analog_right +bind2 = 1-:btn_analog_up +bind3 = 1+:btn_analog_down +bind4 = 2-:axis2_left +bind5 = 2+:axis2_right +bind6 = 3-:axis2_up +bind7 = 3+:axis2_down + +[digital] +bind0 = 0:btn_a +bind1 = 1:btn_b +bind10 = 13:btn_dpad1_up +bind11 = 14:btn_dpad1_down +bind12 = 15:btn_dpad1_left +bind13 = 16:btn_dpad1_right +bind2 = 2:btn_x +bind3 = 3:btn_y +bind4 = 4:btn_trigger_left +bind5 = 5:btn_trigger_right +bind6 = 6:btn_trigger2_left +bind7 = 7:btn_trigger2_right +bind8 = 8:btn_menu +bind9 = 9:btn_start + +[emulator] +dead_zone = 10 +mapping_name = H700 Gamepad +rumble_power = 100 +saturation = 100 +version = 3 diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/config/InputPlumber/SDL_Xbox Series X Controller.cfg b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/InputPlumber/SDL_Xbox Series X Controller.cfg new file mode 100644 index 0000000000..685c10973e --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/InputPlumber/SDL_Xbox Series X Controller.cfg @@ -0,0 +1,40 @@ +[analog] +bind0 = 0-:btn_analog_left +bind1 = 0+:btn_analog_right +bind2 = 1-:btn_analog_up +bind3 = 1+:btn_analog_down +bind4 = 2+:btn_trigger_left +bind5 = 3-:axis2_left +bind6 = 3+:axis2_right +bind7 = 4-:axis2_up +bind8 = 4+:axis2_down +bind9 = 5+:btn_trigger_right + +[combo] +bind0 = 8,4:btn_jump_state:0 +bind1 = 8,5:btn_quick_save:0 +bind2 = 8,7:btn_escape:0 + +[digital] +bind0 = 0:btn_a +bind1 = 1:btn_b +bind10 = 257:btn_dpad1_down +bind11 = 258:btn_dpad1_left +bind12 = 259:btn_dpad1_right +bind2 = 2:btn_x +bind3 = 3:btn_y +bind4 = 4:btn_z +bind5 = 5:btn_c +bind6 = 6:btn_menu +bind7 = 7:btn_start +bind8 = 8:btn_dpad2_up +bind9 = 256:btn_dpad1_up + +[emulator] +dead_zone = 10 +mapping_name = Microsoft Xbox Series Controller +rumble_power = 100 +saturation = 100 +triggers = 2,5 +version = 4 + diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/config/RK3326/emu.cfg b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/RK3326/emu.cfg new file mode 100644 index 0000000000..7def526a21 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/RK3326/emu.cfg @@ -0,0 +1,16 @@ +[audio] +backend = pulse + +[config] +rend.Resolution = 240 + +[input] +maple_sdl_joystick_0 = 0 +maple_sdl_joystick_1 = 1 + +device1 = 0 +device1.1 = 1 +device1.2 = 1 +device2 = 0 +device2.1 = 1 +device2.2 = 1 diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/config/RK3326/mappings/SDL_odroidgo2__joypad.cfg b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/RK3326/mappings/SDL_odroidgo2__joypad.cfg new file mode 100644 index 0000000000..e0f04b97ef --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/RK3326/mappings/SDL_odroidgo2__joypad.cfg @@ -0,0 +1,32 @@ +[analog] +bind0 = 0-:btn_analog_left +bind1 = 0+:btn_analog_right +bind2 = 1-:btn_analog_up +bind3 = 1+:btn_analog_down +bind4 = 2-:axis2_left +bind5 = 2+:axis2_right +bind6 = 3-:axis2_up +bind7 = 3+:axis2_down + +[digital] +bind0 = 0:btn_a +bind1 = 1:btn_b +bind10 = 12:btn_escape +bind11 = 13:btn_menu +bind12 = 14:btn_fforward +bind13 = 15:btn_start +bind2 = 2:btn_x +bind3 = 3:btn_y +bind4 = 4:btn_trigger_left +bind5 = 5:btn_trigger_right +bind6 = 8:btn_dpad1_up +bind7 = 9:btn_dpad1_down +bind8 = 10:btn_dpad1_left +bind9 = 11:btn_dpad1_right + +[emulator] +dead_zone = 10 +mapping_name = ODROID Go 2 +rumble_power = 100 +version = 3 + diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/config/RK3326/mappings/SDL_odroidgo2_v11_joypad.cfg b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/RK3326/mappings/SDL_odroidgo2_v11_joypad.cfg new file mode 100644 index 0000000000..e0f04b97ef --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/RK3326/mappings/SDL_odroidgo2_v11_joypad.cfg @@ -0,0 +1,32 @@ +[analog] +bind0 = 0-:btn_analog_left +bind1 = 0+:btn_analog_right +bind2 = 1-:btn_analog_up +bind3 = 1+:btn_analog_down +bind4 = 2-:axis2_left +bind5 = 2+:axis2_right +bind6 = 3-:axis2_up +bind7 = 3+:axis2_down + +[digital] +bind0 = 0:btn_a +bind1 = 1:btn_b +bind10 = 12:btn_escape +bind11 = 13:btn_menu +bind12 = 14:btn_fforward +bind13 = 15:btn_start +bind2 = 2:btn_x +bind3 = 3:btn_y +bind4 = 4:btn_trigger_left +bind5 = 5:btn_trigger_right +bind6 = 8:btn_dpad1_up +bind7 = 9:btn_dpad1_down +bind8 = 10:btn_dpad1_left +bind9 = 11:btn_dpad1_right + +[emulator] +dead_zone = 10 +mapping_name = ODROID Go 2 +rumble_power = 100 +version = 3 + diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/config/RK3326/mappings/SDL_r33s_joypad.cfg b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/RK3326/mappings/SDL_r33s_joypad.cfg new file mode 100644 index 0000000000..abd5b1c153 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/RK3326/mappings/SDL_r33s_joypad.cfg @@ -0,0 +1,21 @@ +[digital] +bind0 = 0:btn_a +bind1 = 1:btn_b +bind10 = 10:btn_analog_up +bind11 = 11:btn_analog_down +bind12 = 12:btn_analog_left +bind13 = 13:btn_analog_right +bind2 = 2:btn_y +bind3 = 3:btn_x +bind4 = 4:btn_trigger_left +bind5 = 5:btn_trigger_right +bind6 = 6:btn_jump_state +bind7 = 7:btn_quick_save +bind8 = 8:btn_menu +bind9 = 9:btn_start + +[emulator] +dead_zone = 10 +mapping_name = r33s_joypad +rumble_power = 100 +version = 3 diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/config/RK3399/emu.cfg b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/RK3399/emu.cfg new file mode 100644 index 0000000000..9b66c3d516 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/RK3399/emu.cfg @@ -0,0 +1,22 @@ +[audio] +backend = pulse + +[config] +pvr.AutoSkipFrame = 2 +rend.Resolution = 480 + +[input] +maple_sdl_joystick_0 = 0 +maple_sdl_joystick_1 = 1 + +device1 = 0 +device1.1 = 1 +device1.2 = 1 +device2 = 0 +device2.1 = 1 +device2.2 = 1 + +[window] +fullscreen = yes +height = 1152 +width = 1920 diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/config/RK3399/mappings/SDL_retrogame_joypad.cfg b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/RK3399/mappings/SDL_retrogame_joypad.cfg new file mode 100644 index 0000000000..1471462970 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/RK3399/mappings/SDL_retrogame_joypad.cfg @@ -0,0 +1,32 @@ +[analog] +bind0 = 0-:btn_analog_left +bind1 = 0+:btn_analog_right +bind2 = 1-:btn_analog_up +bind3 = 1+:btn_analog_down +bind4 = 2-:axis2_left +bind5 = 2+:axis2_right +bind6 = 3-:axis2_up +bind7 = 3+:axis2_down + +[digital] +bind0 = 0:btn_a +bind1 = 1:btn_b +bind10 = 13:btn_dpad1_up +bind11 = 14:btn_dpad1_down +bind12 = 15:btn_dpad1_left +bind13 = 16:btn_dpad1_right +bind2 = 2:btn_y +bind3 = 3:btn_x +bind4 = 4:btn_trigger_left +bind5 = 5:btn_trigger_right +bind6 = 6:btn_jump_state +bind7 = 7:btn_quick_save +bind8 = 8:btn_menu +bind9 = 9:btn_start + +[emulator] +dead_zone = 10 +mapping_name = rg552_joypad +rumble_power = 100 +version = 3 + diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/config/RK3566/emu.cfg b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/RK3566/emu.cfg new file mode 100644 index 0000000000..1718e69fd5 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/RK3566/emu.cfg @@ -0,0 +1,21 @@ +[audio] +backend = pulse + +[input] +device1 = 0 +device1.1 = 1 +device1.2 = 1 +device2 = 0 +device2.1 = 1 +device2.2 = 1 +maple_sdl_joystick_0 = 0 +maple_sdl_joystick_1 = 1 + +[config] +pvr.AutoSkipFrame = 1 +pvr.rend = 0 +rend.Resolution = 240 +rend.vsync = no +ta.skip = 1 + + diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/config/RK3566/mappings/SDL_retrogame_joypad.cfg b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/RK3566/mappings/SDL_retrogame_joypad.cfg new file mode 100644 index 0000000000..3e61e80e12 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/RK3566/mappings/SDL_retrogame_joypad.cfg @@ -0,0 +1,34 @@ +[analog] +bind0 = 0-:btn_analog_left +bind1 = 0+:btn_analog_right +bind2 = 1-:btn_analog_up +bind3 = 1+:btn_analog_down +bind4 = 2-:axis2_left +bind5 = 2+:axis2_right +bind6 = 3-:axis2_up +bind7 = 3+:axis2_down + +[digital] +bind0 = 0:btn_a +bind1 = 1:btn_b +bind10 = 13:btn_dpad1_up +bind11 = 14:btn_dpad1_down +bind12 = 15:btn_dpad1_left +bind13 = 16:btn_dpad1_right +bind2 = 2:btn_y +bind3 = 3:btn_x +bind4 = 4:btn_trigger_left +bind5 = 5:btn_trigger_right +bind6 = 6:btn_trigger2_left +bind7 = 7:btn_trigger2_right +bind8 = 8:btn_menu +bind9 = 9:btn_start + +[emulator] +dead_zone = 10 +mapping_name = RetroGame Joypad +rumble_power = 100 +saturation = 100 +version = 3 + + diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/config/RK3588/emu.cfg b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/RK3588/emu.cfg new file mode 100644 index 0000000000..9282480349 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/RK3588/emu.cfg @@ -0,0 +1,21 @@ +[audio] +backend = pulse + +[config] +rend.Resolution = 480 + +[input] +maple_sdl_joystick_0 = 0 +maple_sdl_joystick_1 = 1 + +device1 = 0 +device1.1 = 1 +device1.2 = 1 +device2 = 0 +device2.1 = 1 +device2.2 = 1 + +[window] +fullscreen = yes +height = 1080 +width = 1920 diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/config/RK3588/mappings/SDL_GameForce ACE Gamepad.cfg b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/RK3588/mappings/SDL_GameForce ACE Gamepad.cfg new file mode 100644 index 0000000000..6a6ecb4b44 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/RK3588/mappings/SDL_GameForce ACE Gamepad.cfg @@ -0,0 +1,32 @@ +[analog] +bind0 = 1+:btn_analog_down +bind1 = 1-:btn_analog_up +bind2 = 0-:btn_analog_left +bind3 = 0+:btn_analog_right +bind4 = 2+:btn_trigger_left +bind5 = 3-:axis2_left +bind6 = 3+:axis2_right +bind7 = 4-:axis2_up +bind8 = 4+:axis2_down +bind9 = 5+:btn_trigger_right + +[digital] +bind0 = 0:btn_a +bind1 = 1:btn_b +bind10 = 14:btn_dpad1_left +bind11 = 15:btn_dpad1_right +bind2 = 3:btn_y +bind3 = 4:btn_x +bind4 = 5:btn_z +bind5 = 6:btn_c +bind6 = 9:btn_menu +bind7 = 8:btn_start +bind8 = 12:btn_dpad1_up +bind9 = 13:btn_dpad1_down + +[emulator] +dead_zone = 10 +mapping_name = GameForce ACE Gamepad +rumble_power = 100 +saturation = 100 +version = 3 diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/config/S922X/emu.cfg b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/S922X/emu.cfg new file mode 100644 index 0000000000..7c02ea27d7 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/S922X/emu.cfg @@ -0,0 +1,21 @@ +[audio] +backend = pulse + +[config] +rend.Resolution = 480 + +[input] +maple_sdl_joystick_0 = 0 +maple_sdl_joystick_1 = 1 + +device1 = 0 +device1.1 = 1 +device1.2 = 1 +device2 = 0 +device2.1 = 1 +device2.2 = 1 + +[window] +fullscreen = yes +height = 854 +width = 480 diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/config/S922X/mappings/SDL_GO-Ultra Gamepad.cfg b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/S922X/mappings/SDL_GO-Ultra Gamepad.cfg new file mode 100644 index 0000000000..9e9113bfc8 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/S922X/mappings/SDL_GO-Ultra Gamepad.cfg @@ -0,0 +1,33 @@ +[analog] +bind0 = 0-:btn_analog_left +bind1 = 0+:btn_analog_right +bind2 = 1-:btn_analog_up +bind3 = 1+:btn_analog_down +bind4 = 2-:axis2_left +bind5 = 2+:axis2_right +bind6 = 3-:axis2_up +bind7 = 3+:axis2_down + +[digital] +bind0 = 0:btn_a +bind1 = 1:btn_b +bind10 = 13:btn_dpad2_up +bind11 = 14:btn_dpad1_up +bind12 = 15:btn_dpad1_down +bind13 = 16:btn_dpad1_left +bind14 = 17:btn_dpad1_right +bind2 = 3:btn_y +bind3 = 4:btn_x +bind4 = 5:btn_trigger_left +bind5 = 6:btn_trigger_right +bind6 = 7:btn_jump_state +bind7 = 8:btn_quick_save +bind8 = 10:btn_start +bind9 = 11:btn_menu + +[emulator] +dead_zone = 10 +mapping_name = GO-Ultra Gamepad +rumble_power = 100 +saturation = 100 +version = 3 diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/config/SDL_Keyboard.cfg b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/SDL_Keyboard.cfg new file mode 100644 index 0000000000..114b67a6f7 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/SDL_Keyboard.cfg @@ -0,0 +1,11 @@ +digital] +bind0 = 9:btn_fforward +bind1 = 15:btn_jump_state +bind2 = 22:btn_quick_save + +[emulator] +dead_zone = 10 +mapping_name = Keyboard +rumble_power = 100 +saturation = 100 +version = 3 diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/config/SDM845/emu.cfg b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/SDM845/emu.cfg new file mode 100644 index 0000000000..eb221fc9ef --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/SDM845/emu.cfg @@ -0,0 +1,23 @@ +[audio] +backend = pulse + +[config] +pvr.AutoSkipFrame = 2 +pvr.rend = 0 +rend.Resolution = 480 + +[input] +maple_sdl_joystick_0 = 0 +maple_sdl_joystick_1 = 1 + +device1 = 0 +device1.1 = 1 +device1.2 = 1 +device2 = 0 +device2.1 = 1 +device2.2 = 1 + +[window] +fullscreen = yes +height = 1080 +width = 1920 diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/config/SDM845/mappings/SDL_AYN Odin Gamepad.cfg b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/SDM845/mappings/SDL_AYN Odin Gamepad.cfg new file mode 100644 index 0000000000..d3b399a6bd --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/SDM845/mappings/SDL_AYN Odin Gamepad.cfg @@ -0,0 +1,32 @@ +[analog] +bind0 = 0-:btn_analog_left +bind1 = 0+:btn_analog_right +bind2 = 1-:btn_analog_up +bind3 = 1+:btn_analog_down +bind4 = 2-:axis2_left +bind5 = 2+:axis2_right +bind6 = 3-:axis2_up +bind7 = 3+:axis2_down +bind8 = 4+:btn_trigger_right +bind9 = 5+:btn_trigger_left + +[digital] +bind0 = 0:btn_a +bind1 = 1:btn_b +bind10 = 15:btn_dpad1_left +bind11 = 16:btn_dpad1_right +bind2 = 2:btn_y +bind3 = 3:btn_x +bind4 = 4:btn_jump_state +bind5 = 5:btn_quick_save +bind6 = 9:btn_start +bind7 = 10:btn_menu +bind8 = 13:btn_dpad1_up +bind9 = 14:btn_dpad1_down + +[emulator] +dead_zone = 10 +mapping_name = AYN Odin Gamepad +rumble_power = 100 +saturation = 100 +version = 3 diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/config/SM8250/emu.cfg b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/SM8250/emu.cfg new file mode 100644 index 0000000000..eb221fc9ef --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/SM8250/emu.cfg @@ -0,0 +1,23 @@ +[audio] +backend = pulse + +[config] +pvr.AutoSkipFrame = 2 +pvr.rend = 0 +rend.Resolution = 480 + +[input] +maple_sdl_joystick_0 = 0 +maple_sdl_joystick_1 = 1 + +device1 = 0 +device1.1 = 1 +device1.2 = 1 +device2 = 0 +device2.1 = 1 +device2.2 = 1 + +[window] +fullscreen = yes +height = 1080 +width = 1920 diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/config/SM8250/mappings/SDL_Retroid Pocket Gamepad.cfg b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/SM8250/mappings/SDL_Retroid Pocket Gamepad.cfg new file mode 100644 index 0000000000..f6ce3818ef --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/SM8250/mappings/SDL_Retroid Pocket Gamepad.cfg @@ -0,0 +1,33 @@ +[analog] +bind0 = 0-:btn_analog_left +bind1 = 0+:btn_analog_right +bind2 = 1-:btn_analog_up +bind3 = 1+:btn_analog_down +bind4 = 3-:axis2_left +bind5 = 3+:axis2_right +bind6 = 4-:axis2_up +bind7 = 4+:axis2_down +bind8 = 6+:btn_trigger2_left +bind9 = 7+:btn_trigger2_right + +[digital] +bind0 = 0:btn_a +bind1 = 1:btn_b +bind10 = 13:btn_dpad1_left +bind11 = 14:btn_dpad1_right +bind12 = 15:btn_menu +bind2 = 2:btn_y +bind3 = 3:btn_x +bind4 = 4:btn_trigger_left +bind5 = 5:btn_trigger_right +bind6 = 6:reload +bind7 = 7:btn_start +bind8 = 11:btn_dpad1_up +bind9 = 12:btn_dpad1_down + +[emulator] +dead_zone = 10 +mapping_name = Retroid Pocket Gamepad +rumble_power = 100 +saturation = 100 +version = 3 diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/config/SM8550/emu.cfg b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/SM8550/emu.cfg new file mode 100644 index 0000000000..eb221fc9ef --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/SM8550/emu.cfg @@ -0,0 +1,23 @@ +[audio] +backend = pulse + +[config] +pvr.AutoSkipFrame = 2 +pvr.rend = 0 +rend.Resolution = 480 + +[input] +maple_sdl_joystick_0 = 0 +maple_sdl_joystick_1 = 1 + +device1 = 0 +device1.1 = 1 +device1.2 = 1 +device2 = 0 +device2.1 = 1 +device2.2 = 1 + +[window] +fullscreen = yes +height = 1080 +width = 1920 diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/config/SM8550/mappings b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/SM8550/mappings new file mode 120000 index 0000000000..67e264f17b --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/SM8550/mappings @@ -0,0 +1 @@ +../InputPlumber \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/config/SM8650/emu.cfg b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/SM8650/emu.cfg new file mode 100644 index 0000000000..eb221fc9ef --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/SM8650/emu.cfg @@ -0,0 +1,23 @@ +[audio] +backend = pulse + +[config] +pvr.AutoSkipFrame = 2 +pvr.rend = 0 +rend.Resolution = 480 + +[input] +maple_sdl_joystick_0 = 0 +maple_sdl_joystick_1 = 1 + +device1 = 0 +device1.1 = 1 +device1.2 = 1 +device2 = 0 +device2.1 = 1 +device2.2 = 1 + +[window] +fullscreen = yes +height = 1080 +width = 1920 diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/config/SM8650/mappings b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/SM8650/mappings new file mode 120000 index 0000000000..67e264f17b --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/SM8650/mappings @@ -0,0 +1 @@ +../InputPlumber \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/config/flycast.gptk b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/flycast.gptk new file mode 100644 index 0000000000..cc9dafc882 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/config/flycast.gptk @@ -0,0 +1,31 @@ +back = \\ +start = \\ +a = \\ +b = \\ +x = \\ +y = \\ +l1 = \\ +l1_hk = l +l2 = \\ +l2_hk = \\ +l3 = \\ +r1 = \\ +r1_hk = s +r2 = \\ +r2_hk = f +r3 = \\ +up = \\ +down = \\ +left = \\ +right = \\ +left_analog_up = \\ +left_analog_down = \\ +left_analog_left = \\ +left_analog_right = \\ +right_analog_up = \\ +right_analog_down = \\ +right_analog_left = \\ +right_analog_right = \\ +deadzone_triggers = \\ +mouse_scale = \\ +mouse_delay = \\ diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/package.mk b/projects/ArchR/packages/emulators/standalone/flycast-sa/package.mk new file mode 100644 index 0000000000..a3c1968629 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/package.mk @@ -0,0 +1,53 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2021-present Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="flycast-sa" +PKG_VERSION="392a429e8b040b3e5bf6696cb4f984274fc44123" #v2.6 +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/flyinghead/flycast" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain alsa SDL2 libzip zip curl miniupnpc lua54 libao" +PKG_LONGDESC="Flycast is a multiplatform Sega Dreamcast, Naomi and Atomiswave emulator" +PKG_TOOLCHAIN="cmake" +PKG_PATCH_DIRS+="${DEVICE}" + +if [ "${OPENGL_SUPPORT}" = "yes" ] && [ ! "${PREFER_GLES}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" + PKG_CMAKE_OPTS_TARGET+=" -DUSE_OPENGL=ON -DUSE_GLES=OFF" + +elif [ "${OPENGLES_SUPPORT}" = yes ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" + PKG_CMAKE_OPTS_TARGET+=" -DUSE_GLES=ON" +fi + +if [ "${VULKAN_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${VULKAN}" + PKG_CMAKE_OPTS_TARGET+=" -DUSE_VULKAN=ON" + GRENDERER="4" +else + PKG_CMAKE_OPTS_TARGET+=" -DUSE_VULKAN=OFF" + GRENDERER="0" +fi + +pre_configure_target() { + export CXXFLAGS="${CXXFLAGS} -Wno-error=array-bounds" + PKG_CMAKE_OPTS_TARGET+=" -DUSE_OPENMP=ON" + sed -i 's/\-O[23]/-Ofast/' ${PKG_BUILD}/CMakeLists.txt +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + mkdir -p ${INSTALL}/usr/config/flycast + cp ${PKG_BUILD}/.${TARGET_NAME}/flycast ${INSTALL}/usr/bin/flycast + cp ${PKG_DIR}/scripts/* ${INSTALL}/usr/bin + cp -rH ${PKG_DIR}/config/${DEVICE}/* ${INSTALL}/usr/config/flycast + cp -rf ${PKG_DIR}/config/flycast.gptk ${INSTALL}/usr/config/flycast + cp -rf ${PKG_DIR}/config/SDL_Keyboard.cfg ${INSTALL}/usr/config/flycast/mappings + + chmod +x ${INSTALL}/usr/bin/* +} + +post_install() { + sed -e "s/@GRENDERER@/${GRENDERER}/g" -i ${INSTALL}/usr/bin/start_flycast.sh +} diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/patches/000-conf-dir.patch b/projects/ArchR/packages/emulators/standalone/flycast-sa/patches/000-conf-dir.patch new file mode 100644 index 0000000000..171694b7b5 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/patches/000-conf-dir.patch @@ -0,0 +1,83 @@ +diff --git a/core/linux-dist/main.cpp b/core/linux-dist/main.cpp +index 83a18bc7..1c3ac548 100644 +--- a/core/linux-dist/main.cpp ++++ b/core/linux-dist/main.cpp +@@ -42,6 +42,10 @@ void common_linux_setup(); + // $HOME/.config/flycast on linux + static std::string find_user_config_dir() + { ++#ifdef __unix__ ++ flycast::mkdir("/storage/.config/flycast", 0755); ++ return "/storage/.config/flycast/"; ++#else + std::string xdg_home; + if (nowide::getenv("XDG_CONFIG_HOME") != nullptr) + // If XDG_CONFIG_HOME is set explicitly, we'll use that instead of $HOME/.config +@@ -65,12 +69,17 @@ static std::string find_user_config_dir() + } + // Unable to detect config dir, use the current folder + return "."; ++#endif + } + + // Find the user data directory. + // $HOME/.local/share/flycast on linux + static std::string find_user_data_dir() + { ++#ifdef __unix__ ++ flycast::mkdir("/storage/roms/dreamcast/data", 0755); ++ return "/storage/roms/dreamcast/data/"; ++#else + std::string xdg_home; + if (nowide::getenv("XDG_DATA_HOME") != nullptr) + // If XDG_DATA_HOME is set explicitly, we'll use that instead of $HOME/.local/share +@@ -94,6 +103,7 @@ static std::string find_user_data_dir() + } + // Unable to detect data dir, use the current folder + return "."; ++#endif + } + + static void addDirectoriesFromPath(std::vector& dirs, const std::string& path, const std::string& suffix) +@@ -123,8 +133,10 @@ static void addDirectoriesFromPath(std::vector& dirs, const std::st + // . + static std::vector find_system_config_dirs() + { +- std::vector dirs; +- ++ std::vector dirs; ++#ifdef __unix__ ++ dirs.push_back("/storage/.config/flycast/"); ++#else + std::string xdg_home; + if (nowide::getenv("XDG_CONFIG_HOME") != nullptr) + // If XDG_CONFIG_HOME is set explicitly, we'll use that instead of $HOME/.config +@@ -150,7 +162,7 @@ static std::vector find_system_config_dirs() + dirs.push_back("/etc/xdg/flycast/"); + } + dirs.push_back("./"); +- ++#endif + return dirs; + } + +@@ -168,7 +180,9 @@ static std::vector find_system_config_dirs() + static std::vector find_system_data_dirs() + { + std::vector dirs; +- ++#ifdef __unix__ ++ dirs.push_back("/storage/roms/dreamcast/data/"); ++#else + std::string xdg_home; + if (nowide::getenv("XDG_DATA_HOME") != nullptr) + // If XDG_DATA_HOME is set explicitly, we'll use that instead of $HOME/.local/share +@@ -200,7 +214,7 @@ static std::vector find_system_data_dirs() + } + dirs.push_back("./"); + dirs.push_back("data/"); +- ++#endif + return dirs; + } + diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/patches/001-fix-building-with-gcc15.patch b/projects/ArchR/packages/emulators/standalone/flycast-sa/patches/001-fix-building-with-gcc15.patch new file mode 100644 index 0000000000..84157201e5 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/patches/001-fix-building-with-gcc15.patch @@ -0,0 +1,10 @@ +--- a/core/deps/glslang/SPIRV/SpvBuilder.h ++++ b/core/deps/glslang/SPIRV/SpvBuilder.h +@@ -63,6 +63,7 @@ + #include + #include + #include ++#include + + namespace spv { + diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/patches/003-fix-sdl-controller.patch b/projects/ArchR/packages/emulators/standalone/flycast-sa/patches/003-fix-sdl-controller.patch new file mode 100644 index 0000000000..acdf902ef0 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/patches/003-fix-sdl-controller.patch @@ -0,0 +1,16 @@ +diff --git a/core/sdl/sdl.cpp b/core/sdl/sdl.cpp +index 62467d08..cb167b4f 100644 +--- a/core/sdl/sdl.cpp ++++ b/core/sdl/sdl.cpp +@@ -160,6 +160,11 @@ void input_sdl_init() + #endif + std::string db = get_readonly_data_path("gamecontrollerdb.txt"); + int rv = SDL_GameControllerAddMappingsFromFile(db.c_str()); ++ if (rv < 0 && (nowide::getenv("SDL_GAMECONTROLLERCONFIG_FILE") != NULL)) ++ { ++ db = (std::string) nowide::getenv("SDL_GAMECONTROLLERCONFIG_FILE"); ++ rv = SDL_GameControllerAddMappingsFromFile(db.c_str()); ++ } + if (rv < 0) + { + db = get_readonly_config_path("gamecontrollerdb.txt"); diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/scripts/cheevos_flycast.sh b/projects/ArchR/packages/emulators/standalone/flycast-sa/scripts/cheevos_flycast.sh new file mode 100644 index 0000000000..469072e5f8 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/scripts/cheevos_flycast.sh @@ -0,0 +1,63 @@ +#! /bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present Hector Calvarro (https://github.com/kelvfimer) +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile + +FLYCAST_CFG="/storage/.config/flycast/emu.cfg" +LOG_FILE="/var/log/cheevos.log" + +# Extract username, password, token, if enabled, and hardcore mode from system.cfg +username=$(get_setting "global.retroachievements.username") +password=$(get_setting "global.retroachievements.password") +token=$(get_setting "global.retroachievements.token") +enabled=$(get_setting "global.retroachievements") +hardcore=$(get_setting "global.retroachievements.hardcore") + +# Check if RetroAchievements are enabled in Emulation Station +if [ ! ${enabled} = 1 ]; then + echo "RetroAchievements are not enabled, please turn them on in Emulation Station." > ${LOG_FILE} + sed -i '/\[achievements\]/,/^\s*$/s/Enabled =.*/Enabled = no/' ${FLYCAST_CFG} + exit 1 +fi + +# Check if api token is present in system.cfg +if [ -z "${token}" ]; then + echo "RetroAchievements token is empty, please log in with your RetroAchievements credentials in Emulation Station." > ${LOG_FILE} + exit 1 +fi + +# Set hardcore mode +if [ "${hardcore}" = 1 ]; then + hardcore="true" +else + hardcore="false" +fi + +# Update emulator config with RetroAchievements settings +zcheevos=$(grep -Fx "[achievements]" ${FLYCAST_CFG}) + +if [ -z "${zcheevos}" ]; then + sed -i "\$a [achievements]\nEnabled = yes\nHardcoreMode = ${hardcore}\nUserName = ${username}\nToken = ${token}" ${FLYCAST_CFG} +else + sed -i '/\[achievements\]/,/^\s*$/s/Enabled =.*/Enabled = yes/' ${FLYCAST_CFG} + if ! grep -q "^HardcoreMode = " ${FLYCAST_CFG}; then + sed -i "/^\[achievements\]/a HardcoreMode = ${hardcore}" ${FLYCAST_CFG} + else + sed -i "/^\[achievements\]/,/^\[/{s/^HardcoreMode = .*/HardcoreMode = ${hardcore}/;}" ${FLYCAST_CFG} + fi + + if ! grep -q "^UserName = " ${FLYCAST_CFG}; then + sed -i "/^\[achievements\]/a UserName = ${username}" ${FLYCAST_CFG} + else + sed -i "/^\[achievements\]/,/^\[/{s/^UserName = .*/UserName = ${username}/;}" ${FLYCAST_CFG} + fi + + if ! grep -q "^Token = " ${FLYCAST_CFG}; then + sed -i "/^\[achievements\]/a Token = ${token}" ${FLYCAST_CFG} + else + sed -i "/^\[achievements\]/,/^\[/{s/^Token = .*/Token = ${token}/;}" ${FLYCAST_CFG} + fi +fi diff --git a/projects/ArchR/packages/emulators/standalone/flycast-sa/scripts/start_flycast.sh b/projects/ArchR/packages/emulators/standalone/flycast-sa/scripts/start_flycast.sh new file mode 100644 index 0000000000..9546338fd9 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/flycast-sa/scripts/start_flycast.sh @@ -0,0 +1,149 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile +set_kill set "-9 flycast" + +#load gptokeyb support files +control-gen_init.sh +source /storage/.config/gptokeyb/control.ini +get_controls + +# Conf files vars +SOURCE_DIR="/usr/config/flycast" +CONF_DIR="/storage/.config/flycast" +FLYCAST_INI="emu.cfg" + +#Check if flycast exists in .config +if [ ! -d "/storage/.config/flycast" ]; then + cp -r "${SOURCE_DIR}" "${CONF_DIR}" +fi + +#Move save file storage/roms +if [ -d "${CONF_DIR}/data" ]; then + mv "${CONF_DIR}/data" "/storage/roms/dreamcast/" +fi + +#Make flycast bios folder +if [ ! -d "/storage/roms/bios/dc" ]; then + mkdir -p "/storage/roms/bios/dc" +fi + +#Link .config/flycast to .local +ln -sf "/storage/roms/bios/dc" "/storage/roms/dreamcast/data" + + +#Make sure flycast gptk config exists +if [ ! -f "${CONF_DIR}/flycast.gptk" ]; then + cp -r "/usr/config/flycast/flycast.gptk" "${CONF_DIR}/flycast.gptk" +fi + +#Make sure flycast gptk SDL_Keyboard.cfg exists +if [ ! -f "${CONF_DIR}/mappings/SDL_Keyboard.cfg" ]; then + cp -r "/usr/config/flycast/mappings/SDL_Keyboard.cfg" "${CONF_DIR}/mappings/SDL_Keyboard.cfg" +fi + +#Emulation Station Features +GAME=$(echo "${1}"| sed "s#^/.*/##") +PLATFORM=$(echo "${2}"| sed "s#^/.*/##") +ASPECT=$(get_setting aspect_ratio "${PLATFORM}" "${GAME}") +ASKIP=$(get_setting auto_frame_skip "${PLATFORM}" "${GAME}") +FPS=$(get_setting show_fps "${PLATFORM}" "${GAME}") +IRES=$(get_setting internal_resolution "${PLATFORM}" "${GAME}") +GRENDERER=$(get_setting graphics_backend "${PLATFORM}" "${GAME}") +VSYNC=$(get_setting vsync "${PLATFORM}" "${GAME}") + +#Set the cores to use +CORES=$(get_setting "cores" "${PLATFORM}" "${GAME}") +if [ "${CORES}" = "little" ] +then + EMUPERF="${SLOW_CORES}" +elif [ "${CORES}" = "big" ] +then + EMUPERF="${FAST_CORES}" +else + ### All.. + unset EMUPERF +fi + + #AspectRatio + if [ "$ASPECT" = "w" ]; then + sed -i '/^rend.WideScreen =/c\rend.WideScreen = yes' "${CONF_DIR}/${FLYCAST_INI}" + sed -i '/^rend.SuperWideScreen =/c\rend.SuperWideScreen = no' "${CONF_DIR}/${FLYCAST_INI}" + elif [ "$ASPECT" = "sw" ]; then + sed -i '/^rend.WideScreen =/c\rend.WideScreen = yes' "${CONF_DIR}/${FLYCAST_INI}" + sed -i '/^rend.SuperWideScreen =/c\rend.SuperWideScreen = yes' "${CONF_DIR}/${FLYCAST_INI}" + else + sed -i '/^rend.WideScreen =/c\rend.WideScreen = no' "${CONF_DIR}/${FLYCAST_INI}" + sed -i '/^rend.SuperWideScreen =/c\rend.SuperWideScreen = no' "${CONF_DIR}/${FLYCAST_INI}" + fi + + #AutoFrameSkip + if [ "$ASKIP" = "normal" ]; then + sed -i '/^pvr.AutoSkipFrame =/c\pvr.AutoSkipFrame = 1' "${CONF_DIR}/${FLYCAST_INI}" + elif [ "$ASKIP" = "max" ]; then + sed -i '/^pvr.AutoSkipFrame =/c\pvr.AutoSkipFrame = 2' "${CONF_DIR}/${FLYCAST_INI}" + else + sed -i '/^pvr.AutoSkipFrame =/c\pvr.AutoSkipFrame = 0' "${CONF_DIR}/${FLYCAST_INI}" + fi + + #Internal Resolution + if [ "$IRES" = "0" ]; then + sed -i '/rend.Resolution =/c\rend.Resolution = 240' "${CONF_DIR}/${FLYCAST_INI}" + elif [ "$IRES" = "2" ]; then + sed -i '/rend.Resolution =/c\rend.Resolution = 720' "${CONF_DIR}/${FLYCAST_INI}" + elif [ "$IRES" = "3" ]; then + sed -i '/rend.Resolution =/c\rend.Resolution = 960' "${CONF_DIR}/${FLYCAST_INI}" + elif [ "$IRES" = "4" ]; then + sed -i '/rend.Resolution =/c\rend.Resolution = 1200' "${CONF_DIR}/${FLYCAST_INI}" + elif [ "$IRES" = "5" ]; then + sed -i '/rend.Resolution =/c\rend.Resolution = 1440' "${CONF_DIR}/${FLYCAST_INI}" + else + sed -i '/rend.Resolution =/c\rend.Resolution = 480' "${CONF_DIR}/${FLYCAST_INI}" + fi + + #Graphics Renderer + if [ "$GRENDERER" = "opengl" ]; then + sed -i '/^pvr.rend =/c\pvr.rend = 0' "${CONF_DIR}/${FLYCAST_INI}" + elif [ "$GRENDERER" = "vulkan" ]; then + sed -i '/^pvr.rend =/c\pvr.rend = 4' "${CONF_DIR}/${FLYCAST_INI}" + else + sed -i '/^pvr.rend =/c\pvr.rend = @GRENDERER@' "${CONF_DIR}/${FLYCAST_INI}" + fi + + #ShowFPS + if [ "$FPS" = "1" ]; then + sed -i '/^rend.ShowFPS =/c\rend.ShowFPS = yes' "${CONF_DIR}/${FLYCAST_INI}" + else + sed -i '/^rend.ShowFPS =/c\rend.ShowFPS = no' "${CONF_DIR}/${FLYCAST_INI}" + fi + + #Vsync + if [ "$VSYNC" = "1" ];then + sed -i '/^rend.vsync =/c\rend.vsync = yes' "${CONF_DIR}/${FLYCAST_INI}" + else + sed -i '/^rend.vsync =/c\rend.vsync = no' "${CONF_DIR}/${FLYCAST_INI}" + fi + +#Retroachievements +/usr/bin/cheevos_flycast.sh + +# Debugging info: + echo "GAME set to: ${GAME}" + echo "PLATFORM set to: ${PLATFORM}" + echo "CONF DIR: ${CONF_DIR}/${FLYCAST_INI}" + echo "CPU CORES set to: ${EMUPERF}" + echo "ASPECT RATIO set to: ${ASPECT}" + echo "AUTO FRAME SKIP set to: ${ASKIP}" + echo "INTERNAL RESOLUTION set to: ${IRES}" + echo "GRAPHICS RENDERER set to: ${GRENDERER}" + echo "FPS set to: ${FPS}" + echo "VSYNC set to: ${VSYNC}" + echo "Launching /usr/bin/flycast ${1}" + +#Run flycast emulator +$GPTOKEYB "flycast" -c "${CONF_DIR}/flycast.gptk" & +${EMUPERF} /usr/bin/flycast "${1}" +kill -9 "$(pidof gptokeyb)" diff --git a/projects/ArchR/packages/emulators/standalone/gzdoom-sa/config/gzdoom.ini b/projects/ArchR/packages/emulators/standalone/gzdoom-sa/config/gzdoom.ini new file mode 100644 index 0000000000..31f69a36ac --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/gzdoom-sa/config/gzdoom.ini @@ -0,0 +1,749 @@ +# This file was generated by GZDoom g4.8pre-28-gbc75dc056 on 2021-10-16 16:14:47 +# These are the directories to automatically search for IWADs. +# Each directory should be on a separate line, preceded by Path= +[IWADSearch.Directories] +Path=. +Path=$DOOMWADDIR +Path=/storage/.config/gzdoom +Path=/storage/roms/doom + +# These are the directories to search for wads added with the -file +# command line parameter, if they cannot be found with the path +# as-is. Layout is the same as for IWADSearch.Directories +[FileSearch.Directories] +Path=/storage/.config/gzdoom +Path=/storage/roms/doom +Path=$DOOMWADDIR + +# These are the directories to search for soundfonts that let listed in the menu. +# Layout is the same as for IWADSearch.Directories +[SoundfontSearch.Directories] +Path=/storage/.config/gzdoom/soundfonts +Path=/storage/.config/gzdoom/fm_banks + +# Files to automatically execute when running the corresponding game. +# Each file should be on its own line, preceded by Path= + +[Doom.AutoExec] +Path=/storage/.config/gzdoom/autoexec.cfg + +[Heretic.AutoExec] +Path=/storage/.config/gzdoom/autoexec.cfg + +[Hexen.AutoExec] +Path=/storage/.config/gzdoom/autoexec.cfg + +[Strife.AutoExec] +Path=/storage/.config/gzdoom/autoexec.cfg + +[Chex.AutoExec] +Path=/storage/.config/gzdoom/autoexec.cfg + +# WAD files to always load. These are loaded after the IWAD but before +# any files added with -file. Place each file on its own line, preceded +# by Path= +[Global.Autoload] + +# Wad files to automatically load depending on the game and IWAD you are +# playing. You may have have files that are loaded for all similar IWADs +# (the game) and files that are only loaded for particular IWADs. For example, +# any files listed under 'doom.Autoload' will be loaded for any version of Doom, +# but files listed under 'doom.doom2.Autoload' will only load when you are +# playing a Doom 2 based game (doom2.wad, tnt.wad or plutonia.wad), and files listed under +# 'doom.doom2.commercial.Autoload' only when playing doom2.wad. + +[doom.Autoload] + +[doom.id.Autoload] + +[doom.id.doom2.Autoload] + +[doom.id.doom2.commercial.Autoload] + +[doom.id.doom2.commercial.french.Autoload] + +[doom.id.doom2.commercial.xbox.Autoload] + +[doom.id.doom2.unity.Autoload] + +[doom.id.doom2.bfg.Autoload] + +[doom.id.doom2.plutonia.Autoload] + +[doom.id.doom2.plutonia.unity.Autoload] + +[doom.id.doom2.tnt.Autoload] + +[doom.id.doom2.tnt.unity.Autoload] + +[doom.id.doom1.Autoload] + +[doom.id.doom1.registered.Autoload] + +[doom.id.doom1.ultimate.Autoload] + +[doom.id.doom1.ultimate.xbox.Autoload] + +[doom.id.wadsmoosh.Autoload] + +[doom.id.doom1.unity.Autoload] + +[doom.id.doom1.bfg.Autoload] + +[doom.freedoom.Autoload] + +[doom.freedoom.demo.Autoload] + +[doom.freedoom.phase1.Autoload] + +[doom.freedoom.phase2.Autoload] + +[doom.freedoom.freedm.Autoload] + +[heretic.Autoload] + +[heretic.heretic.Autoload] + +[heretic.shadow.Autoload] + +[blasphemer.Autoload] + +[hexen.Autoload] + +[hexen.deathkings.Autoload] + +[hexen.hexen.Autoload] + +[strife.Autoload] + +[strife.strife.Autoload] + +[strife.veteran.Autoload] + +[chex.Autoload] + +[chex.chex1.Autoload] + +[chex.chex3.Autoload] + +[urbanbrawl.Autoload] + +[hacx.Autoload] + +[hacx.hacx1.Autoload] + +[hacx.hacx2.Autoload] + +[harmony.Autoload] + +[square.Autoload] + +[square.squareware.Autoload] + +[square.square.Autoload] + +[delaweare.Autoload] + +[woolball.Autoload] + +[woolball.rotwb.Autoload] + +[LastRun] +Version=222 + +[GlobalSettings] +I_FriendlyWindowTitle=1 +adl_chips_count=6 +adl_emulator_id=0 +adl_fullpan=true +adl_run_at_pcm_rate=false +adl_volume_model=0 +autoloadbrightmaps=false +autoloadlights=false +autoloadwidescreen=true +autosavecount=4 +autosavenum=1 +chase_dist=90 +chase_height=-8 +cl_capfps=false +cl_defaultconfiguration=0 +cl_noprediction=false +cl_oldfreelooklimit=false +cl_predict_lerpscale=0.05000000074505806 +cl_predict_lerpthreshold=2 +cl_predict_specials=true +cl_run=false +cl_waitforsave=true +con_4bitansi=false +con_buffersize=-1 +con_ctrl_d= +con_notifylines=4 +con_printansi=true +defaultiwad= +demo_compress=true +developer=0 +disableautoload=false +disableautosave=0 +enablescriptscreenshot=false +fluid_chorus=false +fluid_chorus_depth=8 +fluid_chorus_level=1 +fluid_chorus_speed=0.30000001192092896 +fluid_chorus_type=0 +fluid_chorus_voices=3 +fluid_gain=0.5 +fluid_interp=1 +fluid_lib= +fluid_patchset=gzdoom +fluid_reverb=false +fluid_reverb_damping=0.23000000417232513 +fluid_reverb_level=0.5699999928474426 +fluid_reverb_roomsize=0.6100000143051147 +fluid_reverb_width=0.7599999904632568 +fluid_samplerate=0 +fluid_threads=1 +fluid_voices=128 +freelook=true +gl_billboard_faces_camera=false +gl_billboard_mode=0 +gl_billboard_particles=true +gl_cachenodes=true +gl_cachetime=0.6000000238418579 +gl_debug=false +gl_debug_breakpoint=false +gl_debug_level=0 +gl_distfog=70 +gl_dither_bpc=0 +gl_enhanced_nv_stealth=3 +gl_es=true +gl_finishbeforeswap=false +gl_fxaa=0 +gl_lens=false +gl_lens_chromatic=1.1200000047683716 +gl_lens_k=-0.11999999731779099 +gl_lens_kcube=0.10000000149011612 +gl_light_particles=true +gl_light_shadowmap=false +gl_light_sprites=true +gl_lights=false +gl_mask_sprite_threshold=0.5 +gl_mask_threshold=0.5 +gl_mirror_envmap=true +gl_multisample=1 +gl_multithread=true +gl_no_skyclear=false +gl_particles_style=2 +gl_pipeline_depth=0 +gl_plane_reflection=true +gl_satformula=1 +gl_seamless=false +gl_shadowmap_filter=1 +gl_shadowmap_quality=512 +gl_sort_textures=false +gl_sprite_blend=false +gl_ssao=0 +gl_ssao_portals=1 +gl_ssao_strength=0.699999988079071 +gl_texture_filter=6 +gl_texture_filter_anisotropic=2 +gl_texture_hqresize_maxinputsize=512 +gl_texture_hqresize_mt_height=4 +gl_texture_hqresize_mt_width=16 +gl_texture_hqresize_multithread=true +gl_texture_hqresize_targets=15 +gl_texture_hqresizemode=0 +gl_texture_hqresizemult=1 +gl_usecolorblending=true +gme_stereodepth=0 +gus_memsize=0 +gus_patchdir= +i_soundinbackground=false +inter_subtitles=false +invertmouse=false +invertmousex=false +language=auto +longsavemessages=true +lookstrafe=false +m_blockcontrollers=false +m_cleanscale=false +m_filter=false +m_forward=1 +m_pitch=1 +m_sensitivity_x=4 +m_sensitivity_y=2 +m_show_backbutton=0 +m_showinputgrid=0 +m_side=2 +m_simpleoptions=false +m_use_mouse=2 +m_yaw=1 +map_point_coordinates=true +midi_config=gzdoom +midi_dmxgus=false +midi_voices=32 +mod_autochip=false +mod_autochip_scan_threshold=12 +mod_autochip_size_force=100 +mod_autochip_size_scan=500 +mod_dumb_mastervolume=1 +mod_interp=2 +mod_samplerate=0 +mod_volramp=2 +mouse_capturemode=1 +mus_calcgain=true +mus_enabled=true +mus_gainoffset=0 +mus_usereplaygain=false +nointerscrollabort=false +nomonsterinterpolation=false +opl_core=0 +opl_fullpan=true +opl_numchips=2 +opn_chips_count=8 +opn_emulator_id=1 +opn_fullpan=true +opn_run_at_pcm_rate=false +os_isanyof=true +png_gamma=0 +png_level=5 +queryiwad=true +quicksavenum=-1 +quicksaverotation=false +quicksaverotationcount=4 +r_actorspriteshadow=1 +r_actorspriteshadowdist=1500 +r_blendmethod=false +r_dynlights=true +r_fakecontrast=1 +r_fullbrightignoresectorcolor=true +r_fuzzscale=true +r_line_distance_cull=0 +r_linearsky=false +r_magfilter=false +r_minfilter=true +r_mipmap=true +r_mirror_recursions=4 +r_models=true +r_multithreaded=1 +r_noaccel=false +r_quakeintensity=1 +r_sprite_distance_cull=0 +r_spriteadjust=2 +r_ticstability=true +save_dir= +save_formatted=false +saveloadconfirmation=true +savestatistics=0 +screenshot_dir= +screenshot_quiet=false +screenshot_type=png +show_messages=true +showendoom=0 +snd_aldevice=Default +snd_alresampler=Default +snd_backend=openal +snd_buffersize=0 +snd_channels=128 +snd_efx=true +snd_enabled=true +snd_hrtf=-1 +snd_mastervolume=1 +snd_mididevice=-5 +snd_midiprecache=false +snd_musicvolume=0.5 +snd_samplerate=0 +snd_sfxvolume=1 +snd_streambuffersize=64 +snd_waterreverb=true +statfile=zdoomstat.txt +storesavepic=true +strictdecorate=false +telezoom=true +timidity_channel_pressure=false +timidity_chorus=0 +timidity_config=gzdoom +timidity_drum_effect=false +timidity_drum_power=1 +timidity_key_adjust=0 +timidity_lpf_def=1 +timidity_min_sustain_time=5000 +timidity_modulation_envelope=true +timidity_modulation_wheel=true +timidity_overlap_voice_allow=true +timidity_pan_delay=false +timidity_portamento=true +timidity_reverb=0 +timidity_reverb_level=0 +timidity_surround_chorus=false +timidity_temper_control=true +timidity_tempo_adjust=1 +turnspeedsprintfast=1280 +turnspeedsprintslow=320 +turnspeedwalkfast=640 +turnspeedwalkslow=320 +use_joystick=true +use_mouse=false +vid_activeinbackground=false +vid_adapter=0 +vid_aspect=0 +vid_brightness=0 +vid_contrast=1 +vid_cropaspect=true +vid_defheight=1920 +vid_defwidth=1080 +vid_fullscreen=true +vid_gamma=1 +vid_hdr=false +vid_maxfps=0 +vid_preferbackend=3 +vid_rendermode=4 +vid_saturation=1 +vid_scale_customheight=200 +vid_scale_custompixelaspect=1 +vid_scale_customwidth=320 +vid_scale_linear=false +vid_scalefactor=1 +vid_scalemode=0 +vid_sdl_render_driver= +vid_vsync=false +vr_hunits_per_meter=41 +vr_ipd=0.06199999898672104 +vr_mode=0 +vr_screendist=0.800000011920929 +vr_swap_eyes=false +wildmidi_config= +wildmidi_enhanced_resampling=true +wildmidi_reverb=false +win_h=384 +win_maximized=false +win_w=512 +win_x=-1 +win_y=-1 +xbrz_centerdirectionbias=4 +xbrz_colorformat=0 +xbrz_dominantdirectionthreshold=3.5999999046325684 +xbrz_equalcolortolerance=30 +xbrz_luminanceweight=1 +xbrz_steepdirectionthreshold=2.200000047683716 + +[GlobalSettings.Unknown] + +[Doom.Player] +autoaim=35 +classicflight=false +color=40 cf 00 +colorset=0 +fov=90 +gender=male +movebob=0.25 +name=Player +neverswitchonpickup=false +playerclass=Fighter +skin=base +stillbob=0 +team=255 +wbobfire=0 +wbobspeed=1 +wi_noautostartmap=false + +[Doom.ConsoleVariables] +addrocketexplosion=false +adl_bank=14 +adl_custom_bank= +adl_use_custom_bank=false +allcheats=false +am_backcolor=6c 54 40 +am_cdwallcolor=4c 38 20 +am_colorset=0 +am_customcolors=true +am_drawmapback=1 +am_efwallcolor=66 55 55 +am_emptyspacemargin=0 +am_fdwallcolor=88 70 58 +am_followplayer=true +am_gridcolor=8b 5a 2b +am_interlevelcolor=ff 00 00 +am_intralevelcolor=00 00 ff +am_linealpha=1 +am_linethickness=1 +am_lockedcolor=00 78 00 +am_map_secrets=1 +am_markcolor=2 +am_markfont=AMMNUMx +am_notseencolor=6c 6c 6c +am_ovcdwallcolor=00 88 44 +am_ovefwallcolor=00 88 44 +am_overlay=0 +am_ovfdwallcolor=00 88 44 +am_ovinterlevelcolor=ff ff 00 +am_ovlockedcolor=00 88 44 +am_ovotherwallscolor=00 88 44 +am_ovportalcolor=00 40 22 +am_ovsecretsectorcolor=00 ff ff +am_ovsecretwallcolor=00 88 44 +am_ovspecialwallcolor=ff ff ff +am_ovtelecolor=ff ff 00 +am_ovthingcolor=e8 88 00 +am_ovthingcolor_citem=e8 88 00 +am_ovthingcolor_friend=e8 88 00 +am_ovthingcolor_item=e8 88 00 +am_ovthingcolor_monster=e8 88 00 +am_ovthingcolor_ncmonster=e8 88 00 +am_ovunexploredsecretcolor=00 ff ff +am_ovunseencolor=00 22 6e +am_ovwallcolor=00 ff 00 +am_ovyourcolor=fc e8 d8 +am_portalcolor=40 40 40 +am_portaloverlay=true +am_rotate=1 +am_secretsectorcolor=ff 00 ff +am_secretwallcolor=00 00 00 +am_showgrid=false +am_showitems=true +am_showkeys=true +am_showkeys_always=false +am_showmaplabel=2 +am_showmonsters=true +am_showsecrets=true +am_showthingsprites=0 +am_showtime=true +am_showtotaltime=false +am_showtriggerlines=0 +am_specialwallcolor=ff ff ff +am_textured=true +am_thingcolor=fc fc fc +am_thingcolor_citem=fc fc fc +am_thingcolor_friend=fc fc fc +am_thingcolor_item=fc fc fc +am_thingcolor_monster=fc fc fc +am_thingcolor_ncmonster=fc fc fc +am_thingrenderstyles=true +am_tswallcolor=88 88 88 +am_unexploredsecretcolor=ff 00 ff +am_wallcolor=2c 18 08 +am_xhaircolor=80 80 80 +am_yourcolor=fc e8 d8 +am_zoomdir=0 +blood_fade_scalar=1 +chat_substitution=false +chatmacro0=No +chatmacro1=I'm ready to kick butt! +chatmacro2=I'm OK. +chatmacro3=I'm not looking too good! +chatmacro4=Help! +chatmacro5=You suck! +chatmacro6=Next time, scumbag... +chatmacro7=Come here! +chatmacro8=I'll take care of it. +chatmacro9=Yes +cl_bbannounce=false +cl_bloodsplats=true +cl_bloodtype=0 +cl_custominvulmapcolor1=00 00 1a +cl_custominvulmapcolor2=a6 a6 7a +cl_customizeinvulmap=false +cl_doautoaim=false +cl_gfxlocalization=3 +cl_maxdecals=1024 +cl_missiledecals=true +cl_pufftype=0 +cl_rockettrails=1 +cl_showmultikills=true +cl_showsecretmessage=true +cl_showsprees=true +cl_spreaddecals=true +classic_scaling_factor=1 +classic_scaling_pixelaspect=1.2000000476837158 +compatmode=0 +con_alpha=0.75 +con_centernotify=false +con_midtime=3 +con_notablist=false +con_notifytime=3 +con_pulsetext=false +con_scale=0 +con_scaletext=0 +crosshair=0 +crosshaircolor=ff 00 00 +crosshairforce=false +crosshairgrow=false +crosshairhealth=2 +crosshairon=true +crosshairscale=0.5 +dehload=0 +dimamount=-1 +dimcolor=ff d7 00 +displaynametags=0 +dlg_musicvolume=1 +dlg_vgafont=false +gl_aalines=false +gl_bandedswlight=false +gl_bloom=true +gl_bloom_amount=1.399999976158142 +gl_brightfog=false +gl_enhanced_nightvision=true +gl_exposure_base=0.3499999940395355 +gl_exposure_min=0.3499999940395355 +gl_exposure_scale=1.2999999523162842 +gl_exposure_speed=0.05000000074505806 +gl_fogmode=1 +gl_fuzztype=0 +gl_interpolate_model_frames=true +gl_light_models=true +gl_lightadditivesurfaces=false +gl_lightmode=2 +gl_menu_blur=-1 +gl_paltonemap_powtable=2 +gl_paltonemap_reverselookup=true +gl_precache=true +gl_scale_viewport=true +gl_sclipfactor=1.7999999523162842 +gl_sclipthreshold=10 +gl_spriteclip=2 +gl_tonemap=0 +gl_weaponlight=8 +hud_althud=false +hud_althud_forceinternal=false +hud_althudscale=0 +hud_ammo_order=0 +hud_ammo_red=25 +hud_ammo_yellow=50 +hud_armor_green=100 +hud_armor_red=25 +hud_armor_yellow=50 +hud_aspectscale=true +hud_berserk_health=true +hud_health_green=100 +hud_health_red=25 +hud_health_yellow=50 +hud_oldscale=true +hud_scale=-1 +hud_scalefactor=1 +hud_showammo=2 +hud_showangles=false +hud_showitems=false +hud_showlag=0 +hud_showmonsters=true +hud_showscore=false +hud_showsecrets=true +hud_showstats=false +hud_showtime=0 +hud_showweapons=true +hud_timecolor=5 +hudcolor_ltim=8 +hudcolor_statnames=6 +hudcolor_stats=3 +hudcolor_time=6 +hudcolor_titl=10 +hudcolor_ttim=5 +hudcolor_xyco=3 +inter_classic_scaling=true +log_vgafont=false +lookspring=true +m_quickexit=false +msg=0 +msg0color=11 +msg1color=5 +msg2color=2 +msg3color=3 +msg4color=3 +msgmidcolor=11 +msgmidcolor2=4 +nametagcolor=5 +nocheats=false +opn_custom_bank= +opn_use_custom_bank=false +paletteflash=0 +pickup_fade_scalar=1 +r_deathcamera=false +r_drawfuzz=1 +r_maxparticles=4000 +r_portal_recursions=4 +r_rail_smartspiral=false +r_rail_spiralsparsity=1 +r_rail_trailsparsity=1 +r_skymode=2 +r_vanillatrans=0 +sb_cooperative_enable=true +sb_cooperative_headingcolor=6 +sb_cooperative_otherplayercolor=2 +sb_cooperative_yourplayercolor=3 +sb_deathmatch_enable=true +sb_deathmatch_headingcolor=6 +sb_deathmatch_otherplayercolor=2 +sb_deathmatch_yourplayercolor=3 +sb_teamdeathmatch_enable=true +sb_teamdeathmatch_headingcolor=6 +screenblocks=10 +setslotstrict=true +show_obituaries=true +snd_menuvolume=0.6000000238418579 +snd_pitched=false +st_oldouch=false +st_scale=-1 +transsouls=0.75 +ui_screenborder_classic_scaling=true +uiscale=3 +underwater_fade_scalar=1 +vid_allowtrueultrawide=1 +vid_cursor=None +vid_nopalsubstitutions=false +wi_cleantextscale=false +wi_percents=true +wi_showtotaltime=true +wipetype=1 + +[Doom.LocalServerInfo] +compatflags=0 +compatflags2=0 +forcewater=false +maxviewpitch=90 +sv_corpsequeuesize=64 +sv_disableautohealth=false +sv_dropstyle=0 +sv_portal_recursions=4 +sv_smartaim=0 + +[Doom.ConfigOnlyVariables] + +[Doom.UnknownConsoleVariables] + +[Doom.ConsoleAliases] + +[Doom.Bindings] +Joy1=+use +Joy5=+speed +Joy6=+attack +Joy7=+crouch +Joy8=+jump +Joy9= +Joy10= +Joy11=weapprev +Joy12=weapnext +Joy13=togglemap +Joy14=menu_main +Joy16=centerview +Joy18= +Joy3=turn180 +Joy4=+reload + +[Doom.DoubleBindings] + +[Doom.AutomapBindings] +MWheelUp=am_zoom 1.2 +MWheelDown=am_zoom -1.2 +Joy5=+am_zoomout +Joy6=+am_zoomin + +[Joy:JS:0] +Axis0deadzone=0.200001 +Axis0scale=0.8 +Axis1deadzone=0.200001 +Axis1scale=0.6 +Axis2deadzone=0.200001 +Axis2scale=0.6 +Axis2map=0 +Axis3deadzone=0.400001 +Axis3scale=0.2 +Axis3map=1 + diff --git a/projects/ArchR/packages/emulators/standalone/gzdoom-sa/package.mk b/projects/ArchR/packages/emulators/standalone/gzdoom-sa/package.mk new file mode 100644 index 0000000000..4d2d37bfa6 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/gzdoom-sa/package.mk @@ -0,0 +1,62 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2021-present 351ELEC (https://github.com/351ELEC) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="gzdoom-sa" +PKG_VERSION="g4.14.2" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/ZDoom/gzdoom" +PKG_URL="https://github.com/ZDoom/gzdoom/archive/refs/tags/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_HOST="toolchain SDL2:host zmusic:host libvpx:host libwebp:host" +PKG_DEPENDS_TARGET="toolchain SDL2 gzdoom-sa:host zmusic libvpx libwebp" +PKG_LONGDESC="GZDoom is a modder-friendly OpenGL and Vulkan source port based on the DOOM engine" +PKG_TOOLCHAIN="cmake-make" + +pre_configure_host() { + unset HOST_CMAKE_OPTS + PKG_CMAKE_OPTS_HOST+=" -DZMUSIC_LIBRARIES=${TOOLCHAIN}/usr/lib/libzmusic.so \ + -DZMUSIC_INCLUDE_DIR=${TOOLCHAIN}/usr/include \ + -DNO_GTK=ON \ + -DHAVE_VULKAN=OFF \ + -DHAVE_GLES2=OFF" +} + +makeinstall_host() { + : +} + +pre_configure_target() { + + PKG_CMAKE_OPTS_TARGET+=" -DNO_GTK=ON \ + -DFORCE_CROSSCOMPILE=ON \ + -DIMPORT_EXECUTABLES=${PKG_BUILD}/.${HOST_NAME}/ImportExecutables.cmake \ + -DCMAKE_BUILD_TYPE=Release \ + -DZMUSIC_LIBRARIES=${SYSROOT_PREFIX}/usr/lib/libzmusic.so -DZMUSIC_INCLUDE_DIR=${SYSROOT_PREFIX}/usr/include" + ### Enable GLES on devices that don't support OpenGL. + if [ ! "${OPENGL_SUPPORT}" = "yes" ] || [ ${PREFER_GLES} = "yes" ] + then + PKG_CMAKE_OPTS_TARGET+=" -DHAVE_GLES2=ON" + fi + + ### Enable vulkan support on devices that have it available. + if [ "${VULKAN_SUPPORT}" = "yes" ] + then + PKG_CMAKE_OPTS_TARGET+=" -DHAVE_VULKAN=ON" + else + PKG_CMAKE_OPTS_TARGET+=" -DHAVE_VULKAN=OFF" + fi +} + +makeinstall_target() { + + mkdir -p ${INSTALL}/usr/bin + cp ${PKG_BUILD}/.${TARGET_NAME}/gzdoom ${INSTALL}/usr/bin + cp ${PKG_DIR}/scripts/start_gzdoom.sh ${INSTALL}/usr/bin/ + chmod +x ${INSTALL}/usr/bin/* + + mkdir -p ${INSTALL}/usr/config/gzdoom + cp ${PKG_DIR}/config/* ${INSTALL}/usr/config/gzdoom + cp ${PKG_BUILD}/.${TARGET_NAME}/*.pk3 ${INSTALL}/usr/config/gzdoom + cp -r ${PKG_BUILD}/.${TARGET_NAME}/soundfonts ${INSTALL}/usr/config/gzdoom + cp -r ${PKG_BUILD}/.${TARGET_NAME}/fm_banks ${INSTALL}/usr/config/gzdoom +} diff --git a/projects/ArchR/packages/emulators/standalone/gzdoom-sa/patches/000-fix-build.patch b/projects/ArchR/packages/emulators/standalone/gzdoom-sa/patches/000-fix-build.patch new file mode 100644 index 0000000000..4d6d089da2 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/gzdoom-sa/patches/000-fix-build.patch @@ -0,0 +1,140 @@ +diff --git a/specs/udmf_zdoom.txt b/specs/udmf_zdoom.txt +index ebc831d57..f2d7974a8 100644 +--- a/specs/udmf_zdoom.txt ++++ b/specs/udmf_zdoom.txt +@@ -218,6 +218,9 @@ Note: All fields default to false unless mentioned otherwise. + useowncolors_bottom = ; // Set to 1 to use the colors set in the sidedef. Default is using the colors from the owning sector. + uppercolor_bottom = ; // Material color of the top of the lower tier. + lowercolor_bottom = ; // Material color of the bottom of the lower tier. (Hardware rendering only.) ++ colorscalefactor_top = // scales the material color by the given factor. Default is 1. ++ colorscalefactor_mid = // scales the material color by the given factor. Default is 1. ++ colorscalefactor_bottom = // scales the material color by the given factor. Default is 1. + + useowncoloradd_top = ; // Controls where the advanced colorization properties are taken from. + useowncoloradd_mid = ; // 0: From the containing sector, 1: from the given part of the linedef itself +diff --git a/src/common/console/keydef.h b/src/common/console/keydef.h +index 108806774..971ab398f 100644 +--- a/src/common/console/keydef.h ++++ b/src/common/console/keydef.h +@@ -75,8 +75,13 @@ enum EKeyCodes + KEY_JOY6, + KEY_JOY7, + KEY_JOY8, +- KEY_JOY14 = KEY_FIRSTJOYBUTTON+13, +- KEY_JOY15 = KEY_FIRSTJOYBUTTON+14, ++ KEY_JOY9, ++ KEY_JOY10, ++ KEY_JOY11, ++ KEY_JOY12, ++ KEY_JOY13, ++ KEY_JOY14, ++ KEY_JOY15, + KEY_LASTJOYBUTTON = 0x187, + KEY_JOYPOV1_UP = 0x188, + KEY_JOYPOV1_RIGHT = 0x189, +diff --git a/src/common/menu/menu.cpp b/src/common/menu/menu.cpp +index 448b196a1..62f4819aa 100644 +--- a/src/common/menu/menu.cpp ++++ b/src/common/menu/menu.cpp +@@ -687,15 +687,12 @@ bool M_Responder (event_t *ev) + ch = ev->data1; + switch (ch) + { +- case KEY_JOY1: +- case KEY_JOY3: +- case KEY_JOY15: ++ case KEY_JOY2: + case KEY_PAD_A: + mkey = MKEY_Enter; + break; + +- case KEY_JOY2: +- case KEY_JOY14: ++ case KEY_JOY1: + case KEY_PAD_B: + mkey = MKEY_Back; + break; +@@ -719,6 +716,7 @@ bool M_Responder (event_t *ev) + case KEY_PAD_LTHUMB_UP: + case KEY_JOYAXIS2MINUS: + case KEY_JOYPOV1_UP: ++ case KEY_JOY9: + mkey = MKEY_Up; + break; + +@@ -726,6 +724,7 @@ bool M_Responder (event_t *ev) + case KEY_PAD_LTHUMB_DOWN: + case KEY_JOYAXIS2PLUS: + case KEY_JOYPOV1_DOWN: ++ case KEY_JOY10: + mkey = MKEY_Down; + break; + +@@ -733,6 +732,7 @@ bool M_Responder (event_t *ev) + case KEY_PAD_LTHUMB_LEFT: + case KEY_JOYAXIS1MINUS: + case KEY_JOYPOV1_LEFT: ++ case KEY_JOY11: + mkey = MKEY_Left; + break; + +@@ -740,6 +740,7 @@ bool M_Responder (event_t *ev) + case KEY_PAD_LTHUMB_RIGHT: + case KEY_JOYAXIS1PLUS: + case KEY_JOYPOV1_RIGHT: ++ case KEY_JOY12: + mkey = MKEY_Right; + break; + } +diff --git a/src/common/platform/posix/sdl/i_gui.cpp b/src/common/platform/posix/sdl/i_gui.cpp +index 9290f063f..62df74a35 100644 +--- a/src/common/platform/posix/sdl/i_gui.cpp ++++ b/src/common/platform/posix/sdl/i_gui.cpp +@@ -68,7 +68,7 @@ bool I_SetCursor(FGameTexture *cursorpic) + SDL_FreeCursor (cursor); + cursor = SDL_CreateColorCursor (cursorSurface, 0, 0); + SDL_SetCursor (cursor); +- SDL_ShowCursor(SDL_ENABLE); ++ SDL_ShowCursor(SDL_DISABLE); + } + else + { +diff --git a/src/gamedata/doomfont.h b/src/gamedata/doomfont.h +index fedeb513c..23b2c0759 100644 +--- a/src/gamedata/doomfont.h ++++ b/src/gamedata/doomfont.h +@@ -57,6 +57,6 @@ void InitDoomFonts() + } + else if (fileSystem.CheckNumForName("STCFN033", FileSys::ns_graphics) >= 0) + { +- OriginalSmallFont = new FFont("OriginalSmallFont", "STCFN%.3d", "defsmallfont", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART, -1, -1, false, true, true); ++ OriginalSmallFont = new FFont("OriginalSmallFont", "STCFN%.3d", "defsmallfont", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART, -1, -1, false, true); + } + +diff --git a/wadsrc/static/language.def b/wadsrc/static/language.def +index da8ddfb4a..a0e3cc60d 100644 +--- a/wadsrc/static/language.def ++++ b/wadsrc/static/language.def +@@ -99,6 +99,9 @@ STARTUP3 = ""; + STARTUP4 = ""; + STARTUP5 = ""; + ++// Engine strings ++CNTRLMNU_OPEN_MAIN = "Open Main Menu"; ++ + // Placeholder definitions for strings that are in the game content table where the labels are needed even when that file is not loaded. + + // Level names + +diff --git a/src/common/rendering/gles/gles_system.cpp b/src/common/rendering/gles/gles_system.cpp +index d9bedafdd..2b02dfcd8 100644 +--- a/src/common/rendering/gles/gles_system.cpp ++++ b/src/common/rendering/gles/gles_system.cpp +@@ -208,6 +208,7 @@ namespace OpenGLESRenderer + gles.npotAvailable = CheckExtension("GL_OES_texture_npot"); + gles.depthClampAvailable = CheckExtension("GL_EXT_depth_clamp"); + gles.anistropicFilterAvailable = CheckExtension("GL_EXT_texture_filter_anisotropic"); ++ gles.useMappedBuffers = true; + } + else if (gles.glesMode == GLES_MODE_OGL2) + { diff --git a/projects/ArchR/packages/emulators/standalone/gzdoom-sa/scripts/start_gzdoom.sh b/projects/ArchR/packages/emulators/standalone/gzdoom-sa/scripts/start_gzdoom.sh new file mode 100644 index 0000000000..741c60cdd8 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/gzdoom-sa/scripts/start_gzdoom.sh @@ -0,0 +1,88 @@ +#!/usr/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2021-present 351ELEC (https://github.com/351ELEC) + +. /etc/profile +set_kill set "-9 gzdoom" + +RUN_DIR="/storage/roms/doom" +CONFIG="/storage/.config/gzdoom/gzdoom.ini" +SAVE_DIR="/storage/roms/gzdoom" + +#Emulation Station Features +GAME=$(echo "${1}"| sed "s#^/.*/##") +PLATFORM=$(echo "${2}"| sed "s#^/.*/##") +VSYNC=$(get_setting vsync "${PLATFORM}" "${GAME}") + + +if [ ! -d "/storage/.config/gzdoom/" ]; then + cp -rf /usr/config/gzdoom /storage/.config/ +fi + +if [ ! -f "/storage/.config/gzdoom/gzdoom.ini" ]; then + cp -rf /usr/config/gzdoom/gzdoom.ini /storage/.config/gzdoom/ +fi + +# Check for newer pk3 files +SHASUMSRC=$(sha256sum "/usr/config/gzdoom/gzdoom.pk3" | awk '{print $1}') +SHASUMDST=$(sha256sum "/storage/.config/gzdoom/gzdoom.pk3" | awk '{print $1}') + +if [ $SHASUMSRC != $SHASUMDST ]; then + cp /usr/config/gzdoom/*.pk3 /storage/.config/gzdoom/ +fi + +# set resolution +sed -i '/vid_defheight=/c\vid_defheight='$(fbheight) /storage/.config/gzdoom/gzdoom.ini +sed -i '/vid_defwidth=/c\vid_defwidth='$(fbwidth) /storage/.config/gzdoom/gzdoom.ini + +if [ ! -d "/storage/roms/doom/iwads" ]; then + mkdir /storage/roms/doom/iwads +fi + +if [ ! -d "/storage/roms/doom/mods" ]; then + mkdir /storage/roms/doom/mods +fi + +mkdir -p ${SAVE_DIR} + +params=" -config ${CONFIG} -savedir ${SAVE_DIR}" +params+=" +gl_es 1 +vid_preferbackend 3 +cl_capfps 0 +vid_fps 0" + +if [ "$VSYNC" = "false" ]; then + params+=" +vid_vsync 0" +else + params+=" +vid_vsync 1" +fi + +# EXT can be wad, WAD, iwad, IWAD, pwad, PWAD or doom +EXT=${1##*.} + +# If its not a simple wad (extension .doom) read the file and parse the data +if [ ${EXT} == "doom" ]; then + dos2unix "${1}" + while IFS== read -r key value; do + if [ "$key" == "IWAD" ]; then + params+=" -iwad $value" + fi + if [ "$key" == "MOD" ]; then + params+=" -file $value" + fi + done <"${1}" +else + params+=" -iwad ${1}" +fi + +#Set the cores to use +CORES=$(get_setting "cores" "${PLATFORM}" "${GAME}") +if [ "${CORES}" = "little" ]; then + EMUPERF="${SLOW_CORES}" +elif [ "${CORES}" = "big" ]; then + EMUPERF="${FAST_CORES}" +else + ### All.. + unset EMUPERF +fi + +cd "${RUN_DIR}" +echo ${params} | ${EMUPERF} xargs /usr/bin/gzdoom >/var/log/gzdoom.log 2>&1 diff --git a/projects/ArchR/packages/emulators/standalone/gzdoom-sa/zmusic/package.mk b/projects/ArchR/packages/emulators/standalone/gzdoom-sa/zmusic/package.mk new file mode 100644 index 0000000000..21a563bd5b --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/gzdoom-sa/zmusic/package.mk @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2021-present 351ELEC (https://github.com/351ELEC) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="zmusic" +PKG_VERSION="1.1.14" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/ZDoom/ZMusic" +PKG_URL="https://github.com/ZDoom/ZMusic/archive/refs/tags/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_HOST="toolchain" +PKG_DEPENDS_TARGET="toolchain zmusic:host glib" +PKG_LONGDESC="GZDoom's music system as a standalone library" +PKG_TOOLCHAIN="cmake-make" + +make_host() { + [ -d "${PKG_BUILD}/build" ] && rm -rf ${PKG_BUILD}/build + mkdir ${PKG_BUILD}/build + cd ${PKG_BUILD}/build + unset HOST_CMAKE_OPTS + cmake -DCMAKE_BUILD_TYPE=Release .. + cmake --build . +} + +make_target() { + [ -d "${PKG_BUILD}/build" ] && rm -rf ${PKG_BUILD}/build + mkdir ${PKG_BUILD}/build + cd ${PKG_BUILD}/build + cmake -DCMAKE_BUILD_TYPE=Release .. + cmake --build . +} + +makeinstall_host() { + mkdir -p ${TOOLCHAIN}/usr/{lib,include} + cp -f ${PKG_BUILD}/build/source/libzmusic* ${TOOLCHAIN}/usr/lib/ + cp -f ${PKG_BUILD}/include/zmusic.h ${TOOLCHAIN}/usr/include +} + +makeinstall_target() { + mkdir -p ${SYSROOT_PREFIX}/usr/{lib,include} + cp -f ${PKG_BUILD}/build/source/libzmusic* ${SYSROOT_PREFIX}/usr/lib/ + cp -f ${PKG_BUILD}/include/zmusic.h ${SYSROOT_PREFIX}/usr/include + + mkdir -p ${INSTALL}/usr/lib + cp -f ${PKG_BUILD}/build/source/libzmusic* ${INSTALL}/usr/lib +} diff --git a/projects/ArchR/packages/emulators/standalone/hatarisa/config/conf/Atari-ST-default.cfg b/projects/ArchR/packages/emulators/standalone/hatarisa/config/conf/Atari-ST-default.cfg new file mode 100644 index 0000000000..f242a8e4aa --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/hatarisa/config/conf/Atari-ST-default.cfg @@ -0,0 +1,252 @@ +[Log] +sLogFileName = stderr +sTraceFileName = stderr +nTextLogLevel = 3 +nAlertDlgLogLevel = 1 +bConfirmQuit = FALSE +bNatFeats = FALSE +bConsoleWindow = FALSE + +[Debugger] +nNumberBase = 10 +nSymbolLines = -1 +nMemdumpLines = -1 +nDisasmLines = -1 +nExceptionDebugMask = 515 +nDisasmOptions = 15 +bDisasmUAE = FALSE +bSymbolsResident = FALSE +bMatchAllSymbols = FALSE + +[Screen] +nMonitorType = 1 +nFrameSkips = 5 +bFullScreen = TRUE +bKeepResolution = TRUE +bResizable = TRUE +bAllowOverscan = TRUE +nSpec512Threshold = 1 +nForceBpp = 0 +bAspectCorrect = TRUE +bUseExtVdiResolutions = FALSE +nVdiWidth = 640 +nVdiHeight = 480 +nVdiColors = 2 +bMouseWarp = TRUE +bShowStatusbar = FALSE +bShowDriveLed = FALSE +bCrop = FALSE +bForceMax = FALSE +nMaxWidth = 832 +nMaxHeight = 588 +bUseSdlRenderer = TRUE +nRenderScaleQuality = 0 +bUseVsync = TRUE + +[Joystick0] +nJoystickMode = 0 +bEnableAutoFire = FALSE +bEnableJumpOnFire2 = FALSE +nJoyId = 0 +kUp = Up +kDown = Down +kLeft = Left +kRight = Right +kFire = Right Ctrl + +[Joystick1] +nJoystickMode = 1 +bEnableAutoFire = FALSE +bEnableJumpOnFire2 = FALSE +nJoyId = 0 +kUp = Up +kDown = Down +kLeft = Left +kRight = Right +kFire = Right Ctrl + +[Joystick2] +nJoystickMode = 0 +bEnableAutoFire = FALSE +bEnableJumpOnFire2 = FALSE +nJoyId = 0 +kUp = Up +kDown = Down +kLeft = Left +kRight = Right +kFire = Right Ctrl + +[Joystick3] +nJoystickMode = 0 +bEnableAutoFire = FALSE +bEnableJumpOnFire2 = FALSE +nJoyId = 0 +kUp = Up +kDown = Down +kLeft = Left +kRight = Right +kFire = Right Ctrl + +[Joystick4] +nJoystickMode = 0 +bEnableAutoFire = FALSE +bEnableJumpOnFire2 = FALSE +nJoyId = 0 +kUp = Up +kDown = Down +kLeft = Left +kRight = Right +kFire = Right Ctrl + +[Joystick5] +nJoystickMode = 0 +bEnableAutoFire = FALSE +bEnableJumpOnFire2 = FALSE +nJoyId = 0 +kUp = Up +kDown = Down +kLeft = Left +kRight = Right +kFire = Right Ctrl + +[Keyboard] +bDisableKeyRepeat = FALSE +nKeymapType = 0 +szMappingFileName = + +[KeyShortcutsWithMod] +kOptions = O +kFullScreen = F +kBorders = B +kMouseMode = M +kColdReset = C +kWarmReset = R +kScreenShot = G +kBossKey = I +kCursorEmu = J +kFastForward = X +kRecAnim = A +kRecSound = Y +kSound = S +kPause = +kDebugger = Pause +kQuit = Q +kLoadMem = L +kSaveMem = K +kInsertDiskA = D +kSwitchJoy0 = F1 +kSwitchJoy1 = F2 +kSwitchPadA = F3 +kSwitchPadB = F4 + +[KeyShortcutsWithoutMod] +kOptions = F12 +kFullScreen = F11 +kBorders = +kMouseMode = +kColdReset = +kWarmReset = +kScreenShot = +kBossKey = +kCursorEmu = +kFastForward = +kRecAnim = +kRecSound = +kSound = +kPause = Pause +kDebugger = +kQuit = +kLoadMem = +kSaveMem = +kInsertDiskA = +kSwitchJoy0 = +kSwitchJoy1 = +kSwitchPadA = +kSwitchPadB = + +[Sound] +bEnableMicrophone = TRUE +bEnableSound = TRUE +bEnableSoundSync = FALSE +nPlaybackFreq = 44100 +nSdlAudioBufferSize = 0 +szYMCaptureFileName = /storage/.hatari/hatari.wav +YmVolumeMixing = 2 + +[Memory] +nMemorySize = 1024 +nTTRamSize = 0 +bAutoSave = FALSE +szMemoryCaptureFileName = /storage/.config/hatari/hatari.sav +szAutoSaveFileName = /storage/.config/hatari/auto.sav + +[HardDisk] +nGemdosDrive = 0 +bBootFromHardDisk = FALSE +bUseHardDiskDirectory = FALSE +szHardDiskDirectory = /storage/.hatari +nGemdosCase = 0 +nWriteProtection = 0 +bFilenameConversion = FALSE +bGemdosHostTime = FALSE +bUseHardDiskImage = FALSE +szHardDiskImage = /storage/.hatari +bUseIdeMasterHardDiskImage = FALSE +bUseIdeSlaveHardDiskImage = FALSE +szIdeMasterHardDiskImage = /storage/.hatari +szIdeSlaveHardDiskImage = /storage/.hatari + +[ROM] +szTosImageFileName = /storage/roms/bios/tos.img +bPatchTos = TRUE +szCartridgeImageFileName = + +[RS232] +bEnableRS232 = FALSE +szOutFileName = /dev/modem +szInFileName = /dev/modem + +[Printer] +bEnablePrinting = FALSE +szPrintToFileName = /storage/.config/hatari/hatari.prn + +[Midi] +bEnableMidi = FALSE +sMidiInFileName = /dev/snd/midiC1D0 +sMidiOutFileName = /dev/snd/midiC1D0 +sMidiInPortName = Off +sMidiOutPortName = Off + +[System] +nCpuLevel = 0 +nCpuFreq = 8 +bCompatibleCpu = TRUE +nModelType = 0 +bBlitter = FALSE +nDSPType = 0 +bPatchTimerD = FALSE +bFastBoot = FALSE +bFastForward = FALSE +bAddressSpace24 = TRUE +bCycleExactCpu = TRUE +n_FPUType = 0 +bSoftFloatFPU = FALSE +bMMU = FALSE +VideoTiming = 3 + +[Video] +AviRecordVcodec = 2 +AviRecordFps = 0 +AviRecordFile = /storage/.hatari/hatari.avi + +[Floppy] +bAutoInsertDiskB = TRUE +FastFloppy = TRUE +EnableDriveA = TRUE +DriveA_NumberOfHeads = 2 +EnableDriveB = TRUE +DriveB_NumberOfHeads = 2 +nWriteProtection = 0 +szDiskImageDirectory = /storage/roms/atarist +szDiskAZipPath = +szDiskBZipPath = diff --git a/projects/ArchR/packages/emulators/standalone/hatarisa/package.mk b/projects/ArchR/packages/emulators/standalone/hatarisa/package.mk new file mode 100644 index 0000000000..54b5377fd1 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/hatarisa/package.mk @@ -0,0 +1,43 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2018-present 5schatten (https://github.com/5schatten) + +PKG_NAME="hatarisa" +PKG_VERSION="6da06056d89bb39777063388d82d065d9e2e31fd" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/hatari/hatari" +PKG_URL="https://github.com/hatari/hatari/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain linux glibc systemd alsa-lib SDL2 portaudio zlib capsimg libpng" +PKG_LONGDESC="Hatari is an Atari ST/STE/TT/Falcon emulator" + + +pre_configure_target() { + PKG_CMAKE_OPTS_TARGET="-DCMAKE_SKIP_RPATH=ON \ + -DDATADIR="/usr/config/hatari" \ + -DBIN2DATADIR="../../storage/.config/hatari" \ + -DCAPSIMAGE_INCLUDE_DIR=${PKG_BUILD}/src/include \ + -DCAPSIMAGE_LIBRARY=${PKG_BUILD}/libcapsimage.so.5.1" + + # copy IPF Support Library include files + mkdir -p ${PKG_BUILD}/src/includes/caps/ + cp -R $(get_build_dir capsimg)/LibIPF/* ${PKG_BUILD}/src/includes/caps/ + cp -R $(get_build_dir capsimg)/Core/CommonTypes.h ${PKG_BUILD}/src/includes/caps/ + cp -R $(get_install_dir capsimg)/usr/lib/libcapsimage.so.5.1 ${PKG_BUILD}/ + + # add library search path for loading libcapsimage library + LDFLAGS="${LDFLAGS} -Wl,-rpath='${PKG_BUILD}'" +} + +makeinstall_target() { + # create directories + mkdir -p ${INSTALL}/usr/bin + mkdir -p ${INSTALL}/usr/config/hatari + + # copy config files + touch ${INSTALL}/usr/config/hatari/hatari.nvram + cp -R ${PKG_DIR}/config/* ${INSTALL}/usr/config/hatari + + # copy binary & start script + cp src/hatari ${INSTALL}/usr/bin/hatarisa + cp -R ${PKG_DIR}/scripts/start_hatari.sh ${INSTALL}/usr/bin/ + chmod 0755 ${INSTALL}/usr/bin/start_hatari.sh +} diff --git a/projects/ArchR/packages/emulators/standalone/hatarisa/portaudio/package.mk b/projects/ArchR/packages/emulators/standalone/hatarisa/portaudio/package.mk new file mode 100644 index 0000000000..21281b7716 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/hatarisa/portaudio/package.mk @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2018-present 5schatten (https://github.com/5schatten) + +PKG_NAME="portaudio" +PKG_VERSION="64d1bf913433d7a2835526b80a93487d5038cb8e" +PKG_SHA256="c33e48217a844cca3b66ab88571b90beefb8fcb6967177951d4dc283587bf834" +PKG_LICENSE="GPL" +PKG_SITE="https://portaudio.com" +PKG_URL="https://github.com/zhang-ray/portaudio/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain alsa-lib" +PKG_LONGDESC="PortAudio is a free, cross-platform, open-source, audio I/O library." + +PKG_CMAKE_OPTS_TARGET="-DCMAKE_POLICY_VERSION_MINIMUM=3.5" diff --git a/projects/ArchR/packages/emulators/standalone/hatarisa/scripts/start_hatari.sh b/projects/ArchR/packages/emulators/standalone/hatarisa/scripts/start_hatari.sh new file mode 100755 index 0000000000..5f55c2886b --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/hatarisa/scripts/start_hatari.sh @@ -0,0 +1,74 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2018-present 5schatten (https://github.com/5schatten) + +. /etc/profile + +# Set some common variables +HATARI_DIR_HOME=/storage/.hatari +HATARI_DIR=/storage/.config/hatari +HATARI_CONFIG_DIR=$HATARI_DIR/conf +HATARI_TMP_DIR=/tmp/hatari +HATARI_TMP_CONFIG="$HATARI_TMP_DIR"/.hatari-temp.cfg +HATARI_LOG="/var/log/hatari.log" +MAX_DRIVES=2 +i=0 + +# create symlink to hatari config dir +if [ ! -L $HATARI_DIR_HOME ]; then + rm -rf $HATARI_DIR_HOME + ln -s $HATARI_DIR $HATARI_DIR_HOME +fi + +# Which file should hatari load? +echo "Trying to boot this game:" "$1" >> $HATARI_LOG + +# Create a clean working directory +if [ -d "$HATARI_TMP_DIR" ]; then + echo "Clean up old working directory." >> $HATARI_LOG + rm -rf "$HATARI_TMP_DIR" +fi +mkdir -p "$HATARI_TMP_DIR" + +# copy default config file to tmp +cp $HATARI_CONFIG_DIR/Atari-ST-default.cfg "$HATARI_TMP_CONFIG" + +# Check if we are loading a .zip file +if [ `echo $1 | grep -i .zip | wc -l` -eq 1 ]; then + + #unpack the zip file + unzip -q -o "$1" -d "$HATARI_TMP_DIR" + + # Assign files to floppy 1 & 2 + for FILE in "$HATARI_TMP_DIR"/* + do + i=$(($i+1)) + case "$i" in + 1) + ARGS="\nszDiskAFileName = "$FILE"" + ;; + 2) + ARGS="${ARGS}\nszDiskBFileName = "$FILE"" + ;; + esac + + # This emulator supports 2 floppies max + if [ $i -eq $MAX_DRIVES ]; then + break; + fi + done + + # Add game files as floppy 1 & 2 to .hatari-temp.cfg & start hatari + echo -e ${ARGS} >> "$HATARI_TMP_CONFIG" + echo -e "\nAssigned floppy drives:" ${ARGS} "\n" >> "$HATARI_LOG" + nice -n -19 hatarisa --configfile "$HATARI_TMP_CONFIG" >> $HATARI_LOG 2>&1 + +# Check for .cfg config file +elif [ `echo $1 | grep -i .cfg | wc -l` -eq 1 ]; then + nice -n -19 hatarisa --configfile "$1" >> $HATARI_LOG 2>&1 +# All other files +else + nice -n -19 hatarisa --configfile "$HATARI_TMP_CONFIG" --disk-a "$1" >> $HATARI_LOG 2>&1 +fi +# Remove temporary dir +rm -rf "$HATARI_TMP_DIR" diff --git a/projects/ArchR/packages/emulators/standalone/hypseus-singe/package.mk b/projects/ArchR/packages/emulators/standalone/hypseus-singe/package.mk new file mode 100644 index 0000000000..f3f4284f9c --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/hypseus-singe/package.mk @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2021-present Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="hypseus-singe" +PKG_VERSION="b353e1728bf56d8b6c6fb606df78b7296a203702" +PKG_LICENSE="GPL3" +PKG_SITE="https://github.com/DirtBagXon/hypseus-singe" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain SDL2 SDL2_ttf SDL2_image libmpeg2 libogg libvorbis libzip" +PKG_LONGDESC="Hypseus is a fork of Daphne. A program that lets one play the original versions of many laserdisc arcade games on one's PC." +PKG_TOOLCHAIN="cmake" +GET_HANDLER_SUPPORT="git" + +PKG_CMAKE_OPTS_TARGET=" ./src" + +pre_configure_target() { + mkdir -p ${INSTALL}/usr/config/game/configs/hypseus + ln -fs /storage/roms/daphne/roms ${INSTALL}/usr/config/game/configs/hypseus/roms + ln -fs /usr/share/daphne/sound ${INSTALL}/usr/config/game/configs/hypseus/sound + ln -fs /usr/share/daphne/fonts ${INSTALL}/usr/config/game/configs/hypseus/fonts + ln -fs /usr/share/daphne/pics ${INSTALL}/usr/config/game/configs/hypseus/pics +} + +post_makeinstall_target() { + cp -rf ${PKG_BUILD}/doc/hypinput.ini ${INSTALL}/usr/config/game/configs/hypseus/ + ln -fs /storage/.config/game/configs/hypseus/hypinput.ini ${INSTALL}/usr/share/daphne/hypinput.ini + cp ${PKG_BUILD}/start_hypseus.sh ${INSTALL}/usr/bin +} diff --git a/projects/ArchR/packages/emulators/standalone/hypseus-singe/patches/hypseus-singe-001-buildfix.patch b/projects/ArchR/packages/emulators/standalone/hypseus-singe/patches/hypseus-singe-001-buildfix.patch new file mode 100644 index 0000000000..3e8887f125 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/hypseus-singe/patches/hypseus-singe-001-buildfix.patch @@ -0,0 +1,89 @@ +--- a/src/CMakeLists.txt 2021-06-07 19:12:18.646828485 +0200 ++++ b/src/CMakeLists.txt 2021-06-07 19:13:56.113491528 +0200 +@@ -45,14 +45,12 @@ + include(GNUInstallDirs) + include(InstallRequiredSystemLibraries) + include(FindPkgConfig) +-include(ExternalProject) +-include(BuildLibMPEG2) + + use_cxx11( ) + + PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2) + PKG_SEARCH_MODULE(SDL2_TTF REQUIRED SDL2_ttf) +-build_libmpeg2( ) ++PKG_SEARCH_MODULE(MPEG2 REQUIRED libmpeg2) + + message(STATUS "Target: ${CMAKE_SYSTEM_NAME} ${CMAKE_TARGET_ARCHITECTURES}") + +@@ -91,7 +89,6 @@ + add_subdirectory(video) + add_subdirectory(vldp) + +-add_dependencies( vldp libmpeg2 ) + add_dependencies( ldp-out vldp ) + add_dependencies( game vldp ) + add_dependencies( sound vldp ) +@@ -129,3 +129,5 @@ set(CPACK_PACKAGE_VERSION_MINOR "${VER_MINOR}") + set(CPACK_PACKAGE_VERSION_PATCH "${VER_PATCH}") + + include(CPack) ++install(TARGETS hypseus DESTINATION bin) ++install(DIRECTORY ../pics ../fonts ../sound DESTINATION /usr/share/daphne) +diff --git a/src/vldp/vldp.h b/src/vldp/vldp.h +index a59c723..3c986dc 100644 +--- a/src/vldp/vldp.h ++++ b/src/vldp/vldp.h +@@ -34,6 +34,8 @@ extern "C" { + // Ubuntu Linux complains with plain + #include // only used for threading + ++#include ++ + struct yuv_buf { + uint8_t *Y; // Y channel + uint8_t *U; // U channel +diff --git a/src/vldp/vldp_internal.h b/src/vldp/vldp_internal.h +index cd046fe..67cea2d 100644 +--- a/src/vldp/vldp_internal.h ++++ b/src/vldp/vldp_internal.h +@@ -27,7 +27,6 @@ + + #include "vldp.h" // for the VLDP_BOOL definition and SDL.h + +-#include + + // this is which version of the .dat file format we are using + #define DAT_VERSION 2 + +--- a/src/manymouse/manymouse.c ++++ b/src/manymouse/manymouse.c +@@ -17,7 +17,6 @@ + extern const ManyMouseDriver *ManyMouseDriver_evdev; + extern const ManyMouseDriver *ManyMouseDriver_hidmanager; + extern const ManyMouseDriver *ManyMouseDriver_hidutilities; +-extern const ManyMouseDriver *ManyMouseDriver_xinput2; + + /* + * These have to be in the favored order...obviously it doesn't matter if the +@@ -31,7 +30,6 @@ + */ + static const ManyMouseDriver **mice_drivers[] = + { +- &ManyMouseDriver_xinput2, + &ManyMouseDriver_evdev, + &ManyMouseDriver_windows, + &ManyMouseDriver_hidmanager, + +--- a/src/manymouse/CMakeLists.txt ++++ b/src/manymouse/CMakeLists.txt +@@ -1,7 +1,8 @@ ++ ++ + set( LIB_SOURCES + manymouse.c linux_evdev.c macosx_hidmanager.c + macosx_hidutilities.c windows_wminput.c +- x11_xinput2.c + ) + + set( LIB_HEADERS diff --git a/projects/ArchR/packages/emulators/standalone/hypseus-singe/patches/hypseus-singe-002-headersfix.patch b/projects/ArchR/packages/emulators/standalone/hypseus-singe/patches/hypseus-singe-002-headersfix.patch new file mode 100644 index 0000000000..55a74a2f88 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/hypseus-singe/patches/hypseus-singe-002-headersfix.patch @@ -0,0 +1,13 @@ +diff --git a/src/game/singe.cpp b/src/game/singe.cpp +index b6506b8..fb2af4e 100644 +--- a/src/game/singe.cpp ++++ b/src/game/singe.cpp +@@ -28,6 +28,8 @@ + + #include "singe.h" + #include "singe/singe_interface.h" ++#include ++#include + + // Win32 doesn't use strcasecmp, it uses stricmp (lame) + #ifdef WIN32 diff --git a/projects/ArchR/packages/emulators/standalone/hypseus-singe/sources/start_hypseus.sh b/projects/ArchR/packages/emulators/standalone/hypseus-singe/sources/start_hypseus.sh new file mode 100755 index 0000000000..df3fb8e1f9 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/hypseus-singe/sources/start_hypseus.sh @@ -0,0 +1,87 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2021-present Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +dir="${1}" +name=${dir##*/} +name=${name%.*} +config="/storage/.config/game/configs/hypseus" +configfile="${config}/hypinput.ini" + +# Attempt to auto configure gamepad +# +GAMEPADINFO="$(sdljoytest -skip_loop)" +#JOYGUID=$(echo "${GAMEPADINFO}" | grep "Joystick 0 Guid " | sed "s|Joystick 0 Guid ||") +JOYNAME=$(echo "${GAMEPADINFO}" | grep "Joystick 0 name " | sed "s|Joystick 0 name ||" | sed "s|'||g") +# + +for file in /usr/share/libretro/autoconfig/*.cfg; do + GAMEPAD=$(cat "$file" | grep input_device | cut -d'"' -f 2) + if [ "${JOYNAME}" == "${GAMEPAD}" ]; then + GPFILE="${file}" + # Other keys to consider KEY_SCREENSHOT KEY_QUIT KEY_PAUSE + for key in KEY_UP KEY_DOWN KEY_LEFT KEY_RIGHT KEY_BUTTON1 KEY_BUTTON2 KEY_BUTTON3 KEY_START1 KEY_COIN1; do + case ${key} in + "KEY_UP") + button=$(cat "${GPFILE}" | grep -E 'input_up_btn' | cut -d '"' -f2) + keyboard="1073741906 0" + ;; + "KEY_DOWN") + button=$(cat "${GPFILE}" | grep -E 'input_down_btn' | cut -d '"' -f2) + keyboard="1073741905 0" + ;; + "KEY_LEFT") + button=$(cat "${GPFILE}" | grep -E 'input_left_btn' | cut -d '"' -f2) + keyboard="1073741904 0" + ;; + "KEY_RIGHT") + button=$(cat "${GPFILE}" | grep -E 'input_right_btn' | cut -d '"' -f2) + keyboard="1073741903 0" + ;; + "KEY_BUTTON1") + button=$(cat "${GPFILE}" | grep -E 'input_a_btn' | cut -d '"' -f2) + keyboard="1073742048 0" + ;; + "KEY_BUTTON2") + button=$(cat "${GPFILE}" | grep -E 'input_b_btn' | cut -d '"' -f2) + keyboard="1073742050 0" + ;; + "KEY_BUTTON3") + button=$(cat "${GPFILE}" | grep -E 'input_x_btn' | cut -d '"' -f2) + keyboard="32 0" + ;; + "KEY_START1") + button=$(cat "${GPFILE}" | grep -E 'input_start_btn' | cut -d '"' -f2) + keyboard="49 0" + ;; + "KEY_COIN1") + button=$(cat "${GPFILE}" | grep -E 'input_select_btn' | cut -d '"' -f2) + keyboard="53 54" + ;; + esac + + # if the button is in fact a hat extract the number, else use the button number+1 + if [[ "${button}" == "h"* ]]; then + button="0 ${button:1:1}" + else + button="$((${button} + 1))" + fi + + sed -i "s|${key}.*|${key} = ${keyboard} ${button} |" ${configfile} + done + fi +done # finish auto gamepad + +if [[ -f "${dir}/${name}.commands" ]]; then + params=$(<"${dir}/${name}.commands") +fi + +cd "${config}" + +if [[ -f "${dir}/${name}.singe" ]]; then + hypseus singe vldp -framefile "${dir}/${name}.txt" -script "${dir}/${name}.singe" -fullscreen -useoverlaysb 2 $params +else + hypseus "${name}" vldp -framefile "${dir}/${name}.txt" -fullscreen -useoverlaysb 2 $params +fi diff --git a/projects/ArchR/packages/emulators/standalone/mednafen/config/common/mednafen.template b/projects/ArchR/packages/emulators/standalone/mednafen/config/common/mednafen.template new file mode 100644 index 0000000000..1acdc0776d --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mednafen/config/common/mednafen.template @@ -0,0 +1,17652 @@ +;VERSION 1.31.0-UNSTABLE +;Edit this file at your own risk! +;DO NOT EDIT THIS FILE WHILE AN INSTANCE OF MEDNAFEN THAT USES IT IS RUNNING. +;File format: +; +;Dummy guard line to prevent settings file corruption by accidentally running ancient versions of Mednafen. Dummy guard line to prevent settings file corruption by accidentally running ancient versions of Mednafen. Dummy guard line to prevent settings file corruption by accidentally running ancient versions of Mednafen. Dummy guard line to prevent settings file corruption by accidentally running ancient versions of Mednafen. Dummy guard line to prevent settings file corruption by accidentally running ancient versions of Mednafen. Dummy guard line to prevent settings file corruption by accidentally running ancient versions of Mednafen. Dummy guard line to prevent settings file corruption by accidentally running ancient versions of Mednafen. Dummy guard line to prevent settings file corruption by accidentally running ancient versions of Mednafen. Dummy guard line to prevent settings file corruption by accidentally running ancient versions of Mednafen.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;fs ~ + +;CD read threads CPU affinity mask. +affinity.cd 0 + +;Main emulation thread CPU affinity mask. +affinity.emu 0x3 + +;Video blitting thread CPU affinity mask. +affinity.video 0 + +;Automatically load/save state on game load/close. +autosave 0 + +;Cache entire CD images in memory. +cd.image_memcache 0 + +;M3U total number of disc images limit. +cd.m3u.disc_limit 50 + +;M3U recursion limit. +cd.m3u.recursion_limit 9 + +;Enable (automatic) usage of this module. +cdplay.enable 1 + +;Force monophonic sound output. +cdplay.forcemono 0 + +;cdplay, Built-In, Controller: Next Track +cdplay.input.builtin.controller.next_track keyboard 0x0 79 + +;cdplay, Built-In, Controller: Next Track 10 +cdplay.input.builtin.controller.next_track_10 keyboard 0x0 82 + +;cdplay, Built-In, Controller: Play/Pause +cdplay.input.builtin.controller.play_pause keyboard 0x0 44 + +;cdplay, Built-In, Controller: Previous Track +cdplay.input.builtin.controller.previous_track keyboard 0x0 80 + +;cdplay, Built-In, Controller: Previous Track 10 +cdplay.input.builtin.controller.previous_track_10 keyboard 0x0 81 + +;cdplay, Built-In, Controller: Scan Forward +cdplay.input.builtin.controller.scan_forward keyboard 0x0 75 + +;cdplay, Built-In, Controller: Scan Reverse +cdplay.input.builtin.controller.scan_reverse keyboard 0x0 78 + +;cdplay, Built-In, Controller: Stop +cdplay.input.builtin.controller.stop keyboard 0x0 40 + +;Enable scanlines with specified opacity. +cdplay.scanlines 0 + +;Enable specified OpenGL shader. +cdplay.shader none + +;Force interlaced video to be treated as progressive. +cdplay.shader.goat.fprog 0 + +;Constant RGB horizontal divergence. +cdplay.shader.goat.hdiv 0.50 + +;Mask pattern. +cdplay.shader.goat.pat goatron + +;Enable scanlines effect. +cdplay.shader.goat.slen 1 + +;Transparency of otherwise-opaque mask areas. +cdplay.shader.goat.tp 0.50 + +;Constant RGB vertical divergence. +cdplay.shader.goat.vdiv 0.50 + +;Enable specified special video scaler. +cdplay.special none + +;Stretch to fill screen. +cdplay.stretch aspect + +;Enable video temporal blur(50/50 previous/current frame by default). +cdplay.tblur 0 + +;Accumulate color data rather than discarding it. +cdplay.tblur.accum 0 + +;Blur amount in accumulation mode, specified in percentage of accumulation buffer to mix with the current frame. +cdplay.tblur.accum.amount 50 + +;Enable (bi)linear interpolation. +cdplay.videoip 0 + +;Enable simple waveform visualization. +cdplay.visualization 1 + +;Full-screen horizontal resolution. +cdplay.xres 0 + +;Scaling factor for the X axis in windowed mode. +cdplay.xscale 5.000000 + +;Scaling factor for the X axis in fullscreen mode. +cdplay.xscalefs 1.000000 + +;Full-screen vertical resolution. +cdplay.yres 0 + +;Scaling factor for the Y axis in windowed mode. +cdplay.yscale 5.000000 + +;Scaling factor for the Y axis in fullscreen mode. +cdplay.yscalefs 1.000000 + +;Enable cheats. +cheats 1 + +;Save state 0 select +command.0 keyboard 0x0 39 + +;Save state 1 select +command.1 keyboard 0x0 30 + +;Save state 2 select +command.2 keyboard 0x0 31 + +;Save state 3 select +command.3 keyboard 0x0 32 + +;Save state 4 select +command.4 keyboard 0x0 33 + +;Save state 5 select +command.5 keyboard 0x0 34 + +;Save state 6 select +command.6 keyboard 0x0 35 + +;Save state 7 select +command.7 keyboard 0x0 36 + +;Save state 8 select +command.8 keyboard 0x0 37 + +;Save state 9 select +command.9 keyboard 0x0 38 + +;Activate barcode(for Famicom) +command.activate_barcode keyboard 0x0 65 + +;Advance frame +command.advance_frame keyboard 0x0 4+alt + +;Select virtual device on virtual input port 1 +command.device_select1 keyboard 0x0 30+ctrl+shift + +;Select virtual device on virtual input port 10 +command.device_select10 keyboard 0x0 39+ctrl+shift + +;Select virtual device on virtual input port 11 +command.device_select11 keyboard 0x0 89+ctrl+shift + +;Select virtual device on virtual input port 12 +command.device_select12 keyboard 0x0 90+ctrl+shift + +;Select virtual device on virtual input port 13 +command.device_select13 keyboard 0x0 91+ctrl+shift + +;Select virtual device on virtual input port 2 +command.device_select2 keyboard 0x0 31+ctrl+shift + +;Select virtual device on virtual input port 3 +command.device_select3 keyboard 0x0 32+ctrl+shift + +;Select virtual device on virtual input port 4 +command.device_select4 keyboard 0x0 33+ctrl+shift + +;Select virtual device on virtual input port 5 +command.device_select5 keyboard 0x0 34+ctrl+shift + +;Select virtual device on virtual input port 6 +command.device_select6 keyboard 0x0 35+ctrl+shift + +;Select virtual device on virtual input port 7 +command.device_select7 keyboard 0x0 36+ctrl+shift + +;Select virtual device on virtual input port 8 +command.device_select8 keyboard 0x0 37+ctrl+shift + +;Select virtual device on virtual input port 9 +command.device_select9 keyboard 0x0 38+ctrl+shift + +;Exit +command.exit joystick @GUID1@ @DEVICE_FUNC_KEYA_MODIFIER@ && joystick @GUID1@ @DEVICE_BTN_START@ + +;Fast-forward +command.fast_forward joystick @GUID1@ @DEVICE_FUNC_KEYA_MODIFIER@ && joystick @GUID1@ @DEVICE_BTN_TR2@ + +;Configure buttons on virtual port 1 +command.input_config1 keyboard 0x0 30+alt+shift || joystick @GUID1@ @DEVICE_FUNC_KEYB_MODIFIER@ && joystick @GUID1@ @DEVICE_BTN_TL2@ + +;Configure buttons on virtual port 10 +command.input_config10 keyboard 0x0 39+alt+shift + +;Configure buttons on virtual port 11 +command.input_config11 keyboard 0x0 89+alt+shift + +;Configure buttons on virtual port 12 +command.input_config12 keyboard 0x0 90+alt+shift + +;Configure buttons on virtual port 13 +command.input_config13 keyboard 0x0 91+alt+shift + +;Configure buttons on virtual port 2 +command.input_config2 keyboard 0x0 31+alt+shift + +;Configure buttons on virtual port 3 +command.input_config3 keyboard 0x0 32+alt+shift + +;Configure buttons on virtual port 4 +command.input_config4 keyboard 0x0 33+alt+shift + +;Configure buttons on virtual port 5 +command.input_config5 keyboard 0x0 34+alt+shift + +;Configure buttons on virtual port 6 +command.input_config6 keyboard 0x0 35+alt+shift + +;Configure buttons on virtual port 7 +command.input_config7 keyboard 0x0 36+alt+shift + +;Configure buttons on virtual port 8 +command.input_config8 keyboard 0x0 37+alt+shift + +;Configure buttons on virtual port 9 +command.input_config9 keyboard 0x0 38+alt+shift + +;Detect analog buttons on physical joysticks/gamepads(for use with the input configuration process). +command.input_config_abd keyboard 0x0 60 + +;Configure command key +command.input_configc keyboard 0x0 59 + +;Configure command key, for all-pressed-to-trigger mode +command.input_configc_am keyboard 0x0 59+shift + +;Insert coin +command.insert_coin keyboard 0x0 65 || joystick @GUID1@ @DEVICE_FUNC_KEYB_MODIFIER@ && joystick @GUID1@ @DEVICE_BTN_TR2@ + +;Insert/Eject disk/disc +command.insert_eject_disk joystick @GUID1@ @DEVICE_FUNC_KEYB_MODIFIER@ && joystick @GUID1@ @DEVICE_BTN_TR@ + +;Load movie +command.load_movie keyboard 0x0 64+shift + +;Load state +command.load_state joystick @GUID1@ @DEVICE_FUNC_KEYA_MODIFIER@ && joystick @GUID1@ @DEVICE_BTN_TL@ + +;Movie 0 select +command.m0 keyboard 0x0 39+shift + +;Movie 1 select +command.m1 keyboard 0x0 30+shift + +;Movie 2 select +command.m2 keyboard 0x0 31+shift + +;Movie 3 select +command.m3 keyboard 0x0 32+shift + +;Movie 4 select +command.m4 keyboard 0x0 33+shift + +;Movie 5 select +command.m5 keyboard 0x0 34+shift + +;Movie 6 select +command.m6 keyboard 0x0 35+shift + +;Movie 7 select +command.m7 keyboard 0x0 36+shift + +;Movie 8 select +command.m8 keyboard 0x0 37+shift + +;Movie 9 select +command.m9 keyboard 0x0 38+shift + +;Pause/Unpause +command.pause keyboard 0x0 72 + +;Power toggle +command.power keyboard 0x0 68 + +;Reinitialize physical joysticks/gamepads. +command.reinit_joysticks keyboard 0x0 60+shift + +;Reset +command.reset keyboard 0x0 67 + +;Rotate screen +command.rotate_screen keyboard 0x0 18+alt + +;Return to normal mode after advancing frames +command.run_normal keyboard 0x0 21+alt + +;Save movie +command.save_movie keyboard 0x0 62+shift + +;Save state +command.save_state joystick @GUID1@ @DEVICE_FUNC_KEYA_MODIFIER@ && joystick @GUID1@ @DEVICE_BTN_TR@ + +;Select disk/disc +command.select_disk joystick @GUID1@ @DEVICE_FUNC_KEYB_MODIFIER@ && joystick @GUID1@ @DEVICE_BTN_TL@ + +;Select drive +command.select_drive keyboard 0x0 63+shift + +;Slow-forward +command.slow_forward keyboard 0x0 49 + +;Rewind +command.state_rewind joystick @GUID1@ @DEVICE_FUNC_KEYA_MODIFIER@ && joystick @GUID1@ @DEVICE_BTN_TL2@ + +;Decrease selected save state slot by 1 +command.state_slot_dec joystick @GUID1@ @DEVICE_FUNC_KEYB_MODIFIER@ && joystick @GUID1@ @DEVICE_BTN_DPAD_LEFT@ + +;Increase selected save state slot by 1 +command.state_slot_inc joystick @GUID1@ @DEVICE_FUNC_KEYB_MODIFIER@ && joystick @GUID1@ @DEVICE_BTN_DPAD_RIGHT@ + +;Take scaled(and filtered) screen snapshot +command.take_scaled_snapshot keyboard 0x0 66+shift + +;Take screen snapshot +command.take_snapshot joystick @GUID1@ @DEVICE_FUNC_KEYA_MODIFIER@ && joystick @GUID1@ @DEVICE_BTN_EAST@ + +;Toggle graphics layer 1 +command.tl1 keyboard 0x0 30+ctrl + +;Toggle graphics layer 2 +command.tl2 keyboard 0x0 31+ctrl + +;Toggle graphics layer 3 +command.tl3 keyboard 0x0 32+ctrl + +;Toggle graphics layer 4 +command.tl4 keyboard 0x0 33+ctrl + +;Toggle graphics layer 5 +command.tl5 keyboard 0x0 34+ctrl + +;Toggle graphics layer 6 +command.tl6 keyboard 0x0 35+ctrl + +;Toggle graphics layer 7 +command.tl7 keyboard 0x0 36+ctrl + +;Toggle graphics layer 8 +command.tl8 keyboard 0x0 37+ctrl + +;Toggle graphics layer 9 +command.tl9 keyboard 0x0 38+ctrl + +;Toggle debugger +command.toggle_debugger keyboard 0x0 7+alt + +;Toggle DIP switch view +command.toggle_dipview keyboard 0x0 63 + +;Toggle frames-per-second display +command.toggle_fps_view joystick @GUID1@ @DEVICE_FUNC_KEYA_MODIFIER@ && joystick @GUID1@ @DEVICE_BTN_WEST@ + +;Toggle fullscreen mode +command.toggle_fs keyboard 0x0 40+alt + +;Grab input +command.toggle_grab keyboard 0x0 101+ctrl+shift + +;Toggle help screen +command.toggle_help keyboard 0x0 58 + +;Toggle state rewind functionality +command.toggle_state_rewind keyboard 0x0 35+alt + +;Enable/Disable cheats +command.togglecheatactive keyboard 0x0 23+alt + +;Toggle cheat console +command.togglecheatview keyboard 0x0 6+alt + +;Toggle netplay console +command.togglenetview keyboard 0x0 23 + +;Automatically go into the debugger's step mode after a game is loaded. +debugger.autostepmode 0 + +;Enable (automatic) usage of this module. +demo.enable 1 + +;Force monophonic sound output. +demo.forcemono 0 + +;demo, Port 1, Controller: Rumble Control Strong +demo.input.port1.controller.rcstrong + +;demo, Port 1, Controller: Rumble Control Weak +demo.input.port1.controller.rcweak + +;demo, Port 1, Controller: Stick DOWN +demo.input.port1.controller.stick_down + +;demo, Port 1, Controller: Stick LEFT +demo.input.port1.controller.stick_left + +;demo, Port 1, Controller: Stick RIGHT +demo.input.port1.controller.stick_right + +;demo, Port 1, Controller: Stick UP +demo.input.port1.controller.stick_up + +;demo, Port 1, Controller: Select Test Mode +demo.input.port1.controller.stm + +;demo, Port 1, Controller: Switch Meow +demo.input.port1.controller.swt + +;Default position for switch "Switch Meow". +demo.input.port1.controller.swt.defpos waffles + +;demo, Port 1, Controller: Toggle Interlace Mode +demo.input.port1.controller.toggle_ilace + +;demo, Port 2, Controller: Rumble Control Strong +demo.input.port2.controller.rcstrong + +;demo, Port 2, Controller: Rumble Control Weak +demo.input.port2.controller.rcweak + +;demo, Port 2, Controller: Stick DOWN +demo.input.port2.controller.stick_down + +;demo, Port 2, Controller: Stick LEFT +demo.input.port2.controller.stick_left + +;demo, Port 2, Controller: Stick RIGHT +demo.input.port2.controller.stick_right + +;demo, Port 2, Controller: Stick UP +demo.input.port2.controller.stick_up + +;demo, Port 2, Controller: Select Test Mode +demo.input.port2.controller.stm + +;demo, Port 2, Controller: Switch Meow +demo.input.port2.controller.swt + +;Default position for switch "Switch Meow". +demo.input.port2.controller.swt.defpos waffles + +;demo, Port 2, Controller: Toggle Interlace Mode +demo.input.port2.controller.toggle_ilace + +;Multi-enum test. +demo.multi_enum + +;Sound quality. +demo.resamp_quality 3 + +;Sound output rate tolerance. +demo.resamp_rate_error 0.0000009 + +;Enable scanlines with specified opacity. +demo.scanlines 0 + +;Enable specified OpenGL shader. +demo.shader none + +;Force interlaced video to be treated as progressive. +demo.shader.goat.fprog 0 + +;Constant RGB horizontal divergence. +demo.shader.goat.hdiv 0.50 + +;Mask pattern. +demo.shader.goat.pat goatron + +;Enable scanlines effect. +demo.shader.goat.slen 1 + +;Transparency of otherwise-opaque mask areas. +demo.shader.goat.tp 0.50 + +;Constant RGB vertical divergence. +demo.shader.goat.vdiv 0.50 + +;Enable specified special video scaler. +demo.special none + +;Stretch to fill screen. +demo.stretch aspect + +;Enable video temporal blur(50/50 previous/current frame by default). +demo.tblur 0 + +;Accumulate color data rather than discarding it. +demo.tblur.accum 0 + +;Blur amount in accumulation mode, specified in percentage of accumulation buffer to mix with the current frame. +demo.tblur.accum.amount 50 + +;Enable (bi)linear interpolation. +demo.videoip 1 + +;Full-screen horizontal resolution. +demo.xres 0 + +;Scaling factor for the X axis in windowed mode. +demo.xscale 2.000000 + +;Scaling factor for the X axis in fullscreen mode. +demo.xscalefs 1.000000 + +;Full-screen vertical resolution. +demo.yres 0 + +;Scaling factor for the Y axis in windowed mode. +demo.yscale 2.000000 + +;Scaling factor for the Y axis in fullscreen mode. +demo.yscalefs 1.000000 + +;Silence sound output when fast-forwarding. +ffnosound 0 + +;Fast-forwarding speed multiplier. +ffspeed 15 + +;Treat the fast-forward button as a toggle. +fftoggle 1 + +;Format string for movie filename. +filesys.fname_movie %f.%M%p.mednafen.%x + +;Format string for save games filename. +filesys.fname_sav %f.mednafen.%M%x + +;Format string for save game backups filename. +filesys.fname_savbackup %f.%m%z%p.mednafen.%x + +;Format string for screen snapshot filenames. +filesys.fname_snap %f-%p.mednafen.%x + +;Format string for state filename. +filesys.fname_state %f.mednafen.%M%X + +;Enable old handling of .gz file extensions with respect to data file path construction. +filesys.old_gz_naming 0 + +;Path to directory for cheats. +filesys.path_cheat cheats + +;Path to directory for firmware. +filesys.path_firmware /storage/roms/bios/ + +;Path to directory for movies. +filesys.path_movie mcm + +;Path to directory for custom palettes. +filesys.path_palette palettes + +;Path to directory for per-game configuration override files. +filesys.path_pgconfig pgconfig + +;Path to directory for save games and nonvolatile memory. +filesys.path_sav /storage/roms/@PLATFORM@/ + +;Path to directory for backups of save games and nonvolatile memory. +filesys.path_savbackup /storage/roms/@PLATFORM@/ + +;Path to directory for screen snapshots. +filesys.path_snap /storage/roms/screenshots/ + +;Path to directory for save states. +filesys.path_state /storage/roms/savestates/@PLATFORM@/ + +;Save state file compression level. +filesys.state_comp_level 6 + +;Enable untrusted file-inclusion path security check. +filesys.untrusted_fip_check 1 + +;Automatically enable FPS display on startup. +fps.autoenable 0 + +;FPS display background color. +fps.bgcolor 0x80000000 + +;FPS display font. +fps.font 5x7 + +;FPS display position. +fps.position upper_left + +;FPS display scale factor. +fps.scale 0 + +;FPS display text color. +fps.textcolor 0xFFFFFFFF + +;Enable (automatic) usage of this module. +gb.enable 1 + +;Force monophonic sound output. +gb.forcemono 0 + +;gb, Built-In, Gamepad: A +gb.input.builtin.gamepad.a joystick @GUID1@ @DEVICE_BTN_EAST@ + +;gb, Built-In, Gamepad: B +gb.input.builtin.gamepad.b joystick @GUID1@ @DEVICE_BTN_SOUTH@ + +;gb, Built-In, Gamepad: DOWN ↓ +gb.input.builtin.gamepad.down joystick @GUID1@ @DEVICE_BTN_DPAD_DOWN@ + +;gb, Built-In, Gamepad: LEFT ← +gb.input.builtin.gamepad.left joystick @GUID1@ @DEVICE_BTN_DPAD_LEFT@ + +;gb, Built-In, Gamepad: Rapid A +gb.input.builtin.gamepad.rapid_a joystick @GUID1@ @DEVICE_BTN_NORTH@ + +;gb, Built-In, Gamepad: Rapid B +gb.input.builtin.gamepad.rapid_b joystick @GUID1@ @DEVICE_BTN_WEST@ + +;gb, Built-In, Gamepad: RIGHT → +gb.input.builtin.gamepad.right joystick @GUID1@ @DEVICE_BTN_DPAD_RIGHT@ + +;gb, Built-In, Gamepad: SELECT +gb.input.builtin.gamepad.select joystick @GUID1@ @DEVICE_BTN_SELECT@ + +;gb, Built-In, Gamepad: START +gb.input.builtin.gamepad.start joystick @GUID1@ @DEVICE_BTN_START@ + +;gb, Built-In, Gamepad: UP ↑ +gb.input.builtin.gamepad.up joystick @GUID1@ @DEVICE_BTN_DPAD_UP@ + +;gb, Tilt, Tilt: DOWN ↓ +gb.input.tilt.tilt.down + +;gb, Tilt, Tilt: LEFT ← +gb.input.tilt.tilt.left + +;gb, Tilt, Tilt: RIGHT → +gb.input.tilt.tilt.right + +;gb, Tilt, Tilt: UP ↑ +gb.input.tilt.tilt.up + +;Enable scanlines with specified opacity. +gb.scanlines 0 + +;Enable specified OpenGL shader. +gb.shader ipsharper + +;Force interlaced video to be treated as progressive. +gb.shader.goat.fprog 0 + +;Constant RGB horizontal divergence. +gb.shader.goat.hdiv 0.50 + +;Mask pattern. +gb.shader.goat.pat goatron + +;Enable scanlines effect. +gb.shader.goat.slen 1 + +;Transparency of otherwise-opaque mask areas. +gb.shader.goat.tp 0.50 + +;Constant RGB vertical divergence. +gb.shader.goat.vdiv 0.50 + +;Enable specified special video scaler. +gb.special none + +;Stretch to fill screen. +gb.stretch aspect + +;Emulated GB type. +gb.system_type dmg + +;Enable video temporal blur(50/50 previous/current frame by default). +gb.tblur 0 + +;Accumulate color data rather than discarding it. +gb.tblur.accum 0 + +;Blur amount in accumulation mode, specified in percentage of accumulation buffer to mix with the current frame. +gb.tblur.accum.amount 50 + +;Enable (bi)linear interpolation. +gb.videoip 0 + +;Full-screen horizontal resolution. +gb.xres 0 + +;Scaling factor for the X axis in windowed mode. +gb.xscale 6.000000 + +;Scaling factor for the X axis in fullscreen mode. +gb.xscalefs 1.000000 + +;Full-screen vertical resolution. +gb.yres 0 + +;Scaling factor for the Y axis in windowed mode. +gb.yscale 6.000000 + +;Scaling factor for the Y axis in fullscreen mode. +gb.yscalefs 1.000000 + +;Path to optional GBA BIOS ROM image. +gba.bios gba_bios.bin + +;Enable (automatic) usage of this module. +gba.enable 1 + +;Force monophonic sound output. +gba.forcemono 0 + +;gba, Built-In, Gamepad: A +gba.input.builtin.gamepad.a joystick @GUID1@ @DEVICE_BTN_EAST@ + +;gba, Built-In, Gamepad: B +gba.input.builtin.gamepad.b joystick @GUID1@ @DEVICE_BTN_SOUTH@ + +;gba, Built-In, Gamepad: DOWN ↓ +gba.input.builtin.gamepad.down joystick @GUID1@ @DEVICE_BTN_DPAD_DOWN@ + +;gba, Built-In, Gamepad: LEFT ← +gba.input.builtin.gamepad.left joystick @GUID1@ @DEVICE_BTN_DPAD_LEFT@ + +;gba, Built-In, Gamepad: Rapid A +gba.input.builtin.gamepad.rapid_a joystick @GUID1@ @DEVICE_BTN_NORTH@ + +;gba, Built-In, Gamepad: Rapid B +gba.input.builtin.gamepad.rapid_b joystick @GUID1@ @DEVICE_BTN_WEST@ + +;gba, Built-In, Gamepad: RIGHT → +gba.input.builtin.gamepad.right joystick @GUID1@ @DEVICE_BTN_DPAD_RIGHT@ + +;gba, Built-In, Gamepad: SELECT +gba.input.builtin.gamepad.select joystick @GUID1@ @DEVICE_BTN_SELECT@ + +;gba, Built-In, Gamepad: SHOULDER L +gba.input.builtin.gamepad.shoulder_l joystick @GUID1@ @DEVICE_BTN_TL@ + +;gba, Built-In, Gamepad: SHOULDER R +gba.input.builtin.gamepad.shoulder_r joystick @GUID1@ @DEVICE_BTN_TR@ + +;gba, Built-In, Gamepad: START +gba.input.builtin.gamepad.start joystick @GUID1@ @DEVICE_BTN_START@ + +;gba, Built-In, Gamepad: UP ↑ +gba.input.builtin.gamepad.up joystick @GUID1@ @DEVICE_BTN_DPAD_UP@ + +;Enable scanlines with specified opacity. +gba.scanlines 0 + +;Enable specified OpenGL shader. +gba.shader none + +;Force interlaced video to be treated as progressive. +gba.shader.goat.fprog 0 + +;Constant RGB horizontal divergence. +gba.shader.goat.hdiv 0.50 + +;Mask pattern. +gba.shader.goat.pat goatron + +;Enable scanlines effect. +gba.shader.goat.slen 1 + +;Transparency of otherwise-opaque mask areas. +gba.shader.goat.tp 0.50 + +;Constant RGB vertical divergence. +gba.shader.goat.vdiv 0.50 + +;Enable specified special video scaler. +gba.special none + +;Stretch to fill screen. +gba.stretch aspect_int + +;Enable video temporal blur(50/50 previous/current frame by default). +gba.tblur 1 + +;Accumulate color data rather than discarding it. +gba.tblur.accum 0 + +;Blur amount in accumulation mode, specified in percentage of accumulation buffer to mix with the current frame. +gba.tblur.accum.amount 50 + +;Enable (bi)linear interpolation. +gba.videoip 0 + +;Full-screen horizontal resolution. +gba.xres 0 + +;Scaling factor for the X axis in windowed mode. +gba.xscale 4.000000 + +;Scaling factor for the X axis in fullscreen mode. +gba.xscalefs 1.000000 + +;Full-screen vertical resolution. +gba.yres 0 + +;Scaling factor for the Y axis in windowed mode. +gba.yscale 4.000000 + +;Scaling factor for the Y axis in fullscreen mode. +gba.yscalefs 1.000000 + +;Enable (automatic) usage of this module. +gg.enable 1 + +;Force monophonic sound output. +gg.forcemono 0 + +;gg, Built-In, Gamepad: Button 1 +gg.input.builtin.gamepad.button1 joystick @GUID1@ @DEVICE_BTN_SOUTH@ + +;gg, Built-In, Gamepad: Button 2 +gg.input.builtin.gamepad.button2 joystick @GUID1@ @DEVICE_BTN_EAST@ + +;gg, Built-In, Gamepad: DOWN ↓ +gg.input.builtin.gamepad.down joystick @GUID1@ @DEVICE_BTN_DPAD_DOWN@ + +;gg, Built-In, Gamepad: LEFT ← +gg.input.builtin.gamepad.left joystick @GUID1@ @DEVICE_BTN_DPAD_LEFT@ + +;gg, Built-In, Gamepad: Rapid Button 1 +gg.input.builtin.gamepad.rapid_button1 joystick @GUID1@ @DEVICE_BTN_WEST@ + +;gg, Built-In, Gamepad: Rapid Button 2 +gg.input.builtin.gamepad.rapid_button2 joystick @GUID1@ @DEVICE_BTN_NORTH@ + +;gg, Built-In, Gamepad: RIGHT → +gg.input.builtin.gamepad.right joystick @GUID1@ @DEVICE_BTN_DPAD_RIGHT@ + +;gg, Built-In, Gamepad: Start +gg.input.builtin.gamepad.start joystick @GUID1@ @DEVICE_BTN_START@ + +;gg, Built-In, Gamepad: UP ↑ +gg.input.builtin.gamepad.up joystick @GUID1@ @DEVICE_BTN_DPAD_UP@ + +;Enable scanlines with specified opacity. +gg.scanlines 0 + +;Enable specified OpenGL shader. +gg.shader ipsharper + +;Force interlaced video to be treated as progressive. +gg.shader.goat.fprog 0 + +;Constant RGB horizontal divergence. +gg.shader.goat.hdiv 0.50 + +;Mask pattern. +gg.shader.goat.pat goatron + +;Enable scanlines effect. +gg.shader.goat.slen 1 + +;Transparency of otherwise-opaque mask areas. +gg.shader.goat.tp 0.50 + +;Constant RGB vertical divergence. +gg.shader.goat.vdiv 0.50 + +;Enable specified special video scaler. +gg.special none + +;Stretch to fill screen. +gg.stretch full + +;Enable video temporal blur(50/50 previous/current frame by default). +gg.tblur 0 + +;Accumulate color data rather than discarding it. +gg.tblur.accum 0 + +;Blur amount in accumulation mode, specified in percentage of accumulation buffer to mix with the current frame. +gg.tblur.accum.amount 50 + +;Enable (bi)linear interpolation. +gg.videoip 0 + +;Full-screen horizontal resolution. +gg.xres 0 + +;Scaling factor for the X axis in windowed mode. +gg.xscale 6.000000 + +;Scaling factor for the X axis in fullscreen mode. +gg.xscalefs 1.000000 + +;Full-screen vertical resolution. +gg.yres 0 + +;Scaling factor for the Y axis in windowed mode. +gg.yscale 6.000000 + +;Scaling factor for the Y axis in fullscreen mode. +gg.yscalefs 1.000000 + +;Auto-fire frequency. +input.autofirefreq 3 + +;Dangerous key action delay. +input.ckdelay 1500 + +;Analog axis binary press detection threshold. +input.joystick.axis_threshold 75 + +;Update physical joystick(s) internal state in Mednafen even when Mednafen lacks OS focus. +input.joystick.global_focus 1 + +;Enable (automatic) usage of this module. +lynx.enable 1 + +;Force monophonic sound output. +lynx.forcemono 0 + +;lynx, Built-In, Gamepad: A (outer) +lynx.input.builtin.gamepad.a joystick @GUID1@ @DEVICE_BTN_EAST@ + +;lynx, Built-In, Gamepad: B (inner) +lynx.input.builtin.gamepad.b joystick @GUID1@ @DEVICE_BTN_SOUTH@ + +;lynx, Built-In, Gamepad: DOWN ↓ +lynx.input.builtin.gamepad.down joystick @GUID1@ @DEVICE_BTN_DPAD_DOWN@ + +;lynx, Built-In, Gamepad: LEFT ← +lynx.input.builtin.gamepad.left joystick @GUID1@ @DEVICE_BTN_DPAD_LEFT@ + +;lynx, Built-In, Gamepad: Option 1 (upper) +lynx.input.builtin.gamepad.option_1 joystick @GUID1@ @DEVICE_BTN_TL@ + +;lynx, Built-In, Gamepad: Option 2 (lower) +lynx.input.builtin.gamepad.option_2 joystick @GUID1@ @DEVICE_BTN_TR@ + +;lynx, Built-In, Gamepad: PAUSE +lynx.input.builtin.gamepad.pause joystick @GUID1@ @DEVICE_BTN_START@ + +;lynx, Built-In, Gamepad: Rapid A (outer) +lynx.input.builtin.gamepad.rapid_a joystick @GUID1@ @DEVICE_BTN_NORTH@ + +;lynx, Built-In, Gamepad: Rapid B (inner) +lynx.input.builtin.gamepad.rapid_b joystick @GUID1@ @DEVICE_BTN_WEST@ + +;lynx, Built-In, Gamepad: Rapid Option 1 (upper) +lynx.input.builtin.gamepad.rapid_option_1 joystick @GUID1@ @DEVICE_BTN_TL2@ + +;lynx, Built-In, Gamepad: Rapid Option 2 (lower) +lynx.input.builtin.gamepad.rapid_option_2 joystick @GUID1@ @DEVICE_BTN_TR2@ + +;lynx, Built-In, Gamepad: RIGHT → +lynx.input.builtin.gamepad.right joystick @GUID1@ @DEVICE_BTN_DPAD_RIGHT@ + +;lynx, Built-In, Gamepad: UP ↑ +lynx.input.builtin.gamepad.up joystick @GUID1@ @DEVICE_BTN_DPAD_UP@ + +;Enable sound output lowpass filter. +lynx.lowpass 1 + +;Virtually rotate the D-pad when the screen is rotated. +lynx.rotateinput 1 + +;Enable scanlines with specified opacity. +lynx.scanlines 0 + +;Enable specified OpenGL shader. +lynx.shader ipsharper + +;Force interlaced video to be treated as progressive. +lynx.shader.goat.fprog 0 + +;Constant RGB horizontal divergence. +lynx.shader.goat.hdiv 0.50 + +;Mask pattern. +lynx.shader.goat.pat goatron + +;Enable scanlines effect. +lynx.shader.goat.slen 1 + +;Transparency of otherwise-opaque mask areas. +lynx.shader.goat.tp 0.50 + +;Constant RGB vertical divergence. +lynx.shader.goat.vdiv 0.50 + +;Enable specified special video scaler. +lynx.special none + +;Stretch to fill screen. +lynx.stretch aspect_int + +;Enable video temporal blur(50/50 previous/current frame by default). +lynx.tblur 0 + +;Accumulate color data rather than discarding it. +lynx.tblur.accum 0 + +;Blur amount in accumulation mode, specified in percentage of accumulation buffer to mix with the current frame. +lynx.tblur.accum.amount 50 + +;Enable (bi)linear interpolation. +lynx.videoip 0 + +;Full-screen horizontal resolution. +lynx.xres 0 + +;Scaling factor for the X axis in windowed mode. +lynx.xscale 6.000000 + +;Scaling factor for the X axis in fullscreen mode. +lynx.xscalefs 1.000000 + +;Full-screen vertical resolution. +lynx.yres 0 + +;Scaling factor for the Y axis in windowed mode. +lynx.yscale 6.000000 + +;Scaling factor for the Y axis in fullscreen mode. +lynx.yscalefs 1.000000 + +;Path to the CD BIOS +md.cdbios us_scd1_9210.bin + +;Correct the aspect ratio. +md.correct_aspect 1 + +;Disassembly font size. +md.debugger.disfontsize 5x7 + +;Character encoding for the debugger's memory editor. +md.debugger.memcharenc shift_jis + +;Enable (automatic) usage of this module. +md.enable 1 + +;Force monophonic sound output. +md.forcemono 0 + +;Automatically select appropriate input devices. +md.input.auto 1 + +;Emulated mouse sensitivity. +md.input.mouse_sensitivity 1.00 + +;Enable multitap(s). +md.input.multitap none + +;Input device for Virtual Port 1 +md.input.port1 gamepad + +;md, Virtual Port 1, 3-Button Gamepad: A +md.input.port1.gamepad.a joystick @GUID1@ @DEVICE_BTN_WEST@ + +;md, Virtual Port 1, 3-Button Gamepad: B +md.input.port1.gamepad.b joystick @GUID1@ @DEVICE_BTN_SOUTH@ + +;md, Virtual Port 1, 3-Button Gamepad: C +md.input.port1.gamepad.c joystick @GUID1@ @DEVICE_BTN_EAST@ + +;md, Virtual Port 1, 3-Button Gamepad: DOWN ↓ +md.input.port1.gamepad.down joystick @GUID1@ @DEVICE_BTN_DPAD_DOWN@ + +;md, Virtual Port 1, 3-Button Gamepad: LEFT ← +md.input.port1.gamepad.left joystick @GUID1@ @DEVICE_BTN_DPAD_LEFT@ + +;md, Virtual Port 1, 3-Button Gamepad: Rapid A +md.input.port1.gamepad.rapid_a joystick @GUID1@ @DEVICE_BTN_TL@ + +;md, Virtual Port 1, 3-Button Gamepad: Rapid B +md.input.port1.gamepad.rapid_b joystick @GUID1@ @DEVICE_BTN_NORTH@ + +;md, Virtual Port 1, 3-Button Gamepad: Rapid C +md.input.port1.gamepad.rapid_c joystick @GUID1@ @DEVICE_BTN_TR@ + +;md, Virtual Port 1, 3-Button Gamepad: RIGHT → +md.input.port1.gamepad.right joystick @GUID1@ @DEVICE_BTN_DPAD_RIGHT@ + +;md, Virtual Port 1, 3-Button Gamepad: Start +md.input.port1.gamepad.start joystick @GUID1@ @DEVICE_BTN_START@ + +;md, Virtual Port 1, 3-Button Gamepad: UP ↑ +md.input.port1.gamepad.up joystick @GUID1@ @DEVICE_BTN_DPAD_UP@ + +;md, Virtual Port 1, 2-Button Gamepad: A +md.input.port1.gamepad2.a + +;md, Virtual Port 1, 2-Button Gamepad: B +md.input.port1.gamepad2.b + +;md, Virtual Port 1, 2-Button Gamepad: DOWN ↓ +md.input.port1.gamepad2.down + +;md, Virtual Port 1, 2-Button Gamepad: LEFT ← +md.input.port1.gamepad2.left + +;md, Virtual Port 1, 2-Button Gamepad: Rapid A +md.input.port1.gamepad2.rapid_a + +;md, Virtual Port 1, 2-Button Gamepad: Rapid B +md.input.port1.gamepad2.rapid_b + +;md, Virtual Port 1, 2-Button Gamepad: RIGHT → +md.input.port1.gamepad2.right + +;md, Virtual Port 1, 2-Button Gamepad: Start +md.input.port1.gamepad2.start + +;md, Virtual Port 1, 2-Button Gamepad: UP ↑ +md.input.port1.gamepad2.up + +;md, Virtual Port 1, 6-Button Gamepad: A +md.input.port1.gamepad6.a joystick @GUID1@ @DEVICE_BTN_WEST@ + +;md, Virtual Port 1, 6-Button Gamepad: B +md.input.port1.gamepad6.b joystick @GUID1@ @DEVICE_BTN_SOUTH@ + +;md, Virtual Port 1, 6-Button Gamepad: C +md.input.port1.gamepad6.c joystick @GUID1@ @DEVICE_BTN_EAST@ + +;md, Virtual Port 1, 6-Button Gamepad: DOWN ↓ +md.input.port1.gamepad6.down joystick @GUID1@ @DEVICE_BTN_DPAD_DOWN@ + +;md, Virtual Port 1, 6-Button Gamepad: LEFT ← +md.input.port1.gamepad6.left joystick @GUID1@ @DEVICE_BTN_DPAD_LEFT@ + +;md, Virtual Port 1, 6-Button Gamepad: Mode +md.input.port1.gamepad6.mode joystick @GUID1@ @DEVICE_BTN_SELECT@ + +;md, Virtual Port 1, 6-Button Gamepad: Rapid A +md.input.port1.gamepad6.rapid_a + +;md, Virtual Port 1, 6-Button Gamepad: Rapid B +md.input.port1.gamepad6.rapid_b + +;md, Virtual Port 1, 6-Button Gamepad: Rapid C +md.input.port1.gamepad6.rapid_c + +;md, Virtual Port 1, 6-Button Gamepad: Rapid X +md.input.port1.gamepad6.rapid_x + +;md, Virtual Port 1, 6-Button Gamepad: Rapid Y +md.input.port1.gamepad6.rapid_y + +;md, Virtual Port 1, 6-Button Gamepad: Rapid Z +md.input.port1.gamepad6.rapid_z + +;md, Virtual Port 1, 6-Button Gamepad: RIGHT → +md.input.port1.gamepad6.right joystick @GUID1@ @DEVICE_BTN_DPAD_RIGHT@ + +;md, Virtual Port 1, 6-Button Gamepad: Start +md.input.port1.gamepad6.start joystick @GUID1@ @DEVICE_BTN_START@ + +;md, Virtual Port 1, 6-Button Gamepad: UP ↑ +md.input.port1.gamepad6.up joystick @GUID1@ @DEVICE_BTN_DPAD_UP@ + +;md, Virtual Port 1, 6-Button Gamepad: X +md.input.port1.gamepad6.x joystick @GUID1@ @DEVICE_BTN_TL@ + +;md, Virtual Port 1, 6-Button Gamepad: Y +md.input.port1.gamepad6.y joystick @GUID1@ @DEVICE_BTN_NORTH@ + +;md, Virtual Port 1, 6-Button Gamepad: Z +md.input.port1.gamepad6.z joystick @GUID1@ @DEVICE_BTN_TR@ + +;md, Virtual Port 1, Sega Mega Mouse: Left Button +md.input.port1.megamouse.left mouse 0x0 button_left + +;md, Virtual Port 1, Sega Mega Mouse: Middle Button +md.input.port1.megamouse.middle mouse 0x0 button_middle + +;md, Virtual Port 1, Sega Mega Mouse: Motion Down +md.input.port1.megamouse.motion_down mouse 0x0 rel_y+ + +;md, Virtual Port 1, Sega Mega Mouse: Motion Left +md.input.port1.megamouse.motion_left mouse 0x0 rel_x- + +;md, Virtual Port 1, Sega Mega Mouse: Motion Right +md.input.port1.megamouse.motion_right mouse 0x0 rel_x+ + +;md, Virtual Port 1, Sega Mega Mouse: Motion Up +md.input.port1.megamouse.motion_up mouse 0x0 rel_y- + +;md, Virtual Port 1, Sega Mega Mouse: Right Button +md.input.port1.megamouse.right mouse 0x0 button_right + +;md, Virtual Port 1, Sega Mega Mouse: Start Button +md.input.port1.megamouse.start keyboard 0x0 40 + +;Input device for Virtual Port 2 +md.input.port2 gamepad + +;md, Virtual Port 2, 3-Button Gamepad: A +md.input.port2.gamepad.a + +;md, Virtual Port 2, 3-Button Gamepad: B +md.input.port2.gamepad.b + +;md, Virtual Port 2, 3-Button Gamepad: C +md.input.port2.gamepad.c + +;md, Virtual Port 2, 3-Button Gamepad: DOWN ↓ +md.input.port2.gamepad.down + +;md, Virtual Port 2, 3-Button Gamepad: LEFT ← +md.input.port2.gamepad.left + +;md, Virtual Port 2, 3-Button Gamepad: Rapid A +md.input.port2.gamepad.rapid_a + +;md, Virtual Port 2, 3-Button Gamepad: Rapid B +md.input.port2.gamepad.rapid_b + +;md, Virtual Port 2, 3-Button Gamepad: Rapid C +md.input.port2.gamepad.rapid_c + +;md, Virtual Port 2, 3-Button Gamepad: RIGHT → +md.input.port2.gamepad.right + +;md, Virtual Port 2, 3-Button Gamepad: Start +md.input.port2.gamepad.start + +;md, Virtual Port 2, 3-Button Gamepad: UP ↑ +md.input.port2.gamepad.up + +;md, Virtual Port 2, 2-Button Gamepad: A +md.input.port2.gamepad2.a + +;md, Virtual Port 2, 2-Button Gamepad: B +md.input.port2.gamepad2.b + +;md, Virtual Port 2, 2-Button Gamepad: DOWN ↓ +md.input.port2.gamepad2.down + +;md, Virtual Port 2, 2-Button Gamepad: LEFT ← +md.input.port2.gamepad2.left + +;md, Virtual Port 2, 2-Button Gamepad: Rapid A +md.input.port2.gamepad2.rapid_a + +;md, Virtual Port 2, 2-Button Gamepad: Rapid B +md.input.port2.gamepad2.rapid_b + +;md, Virtual Port 2, 2-Button Gamepad: RIGHT → +md.input.port2.gamepad2.right + +;md, Virtual Port 2, 2-Button Gamepad: Start +md.input.port2.gamepad2.start + +;md, Virtual Port 2, 2-Button Gamepad: UP ↑ +md.input.port2.gamepad2.up + +;md, Virtual Port 2, 6-Button Gamepad: A +md.input.port2.gamepad6.a + +;md, Virtual Port 2, 6-Button Gamepad: B +md.input.port2.gamepad6.b + +;md, Virtual Port 2, 6-Button Gamepad: C +md.input.port2.gamepad6.c + +;md, Virtual Port 2, 6-Button Gamepad: DOWN ↓ +md.input.port2.gamepad6.down + +;md, Virtual Port 2, 6-Button Gamepad: LEFT ← +md.input.port2.gamepad6.left + +;md, Virtual Port 2, 6-Button Gamepad: Mode +md.input.port2.gamepad6.mode + +;md, Virtual Port 2, 6-Button Gamepad: Rapid A +md.input.port2.gamepad6.rapid_a + +;md, Virtual Port 2, 6-Button Gamepad: Rapid B +md.input.port2.gamepad6.rapid_b + +;md, Virtual Port 2, 6-Button Gamepad: Rapid C +md.input.port2.gamepad6.rapid_c + +;md, Virtual Port 2, 6-Button Gamepad: Rapid X +md.input.port2.gamepad6.rapid_x + +;md, Virtual Port 2, 6-Button Gamepad: Rapid Y +md.input.port2.gamepad6.rapid_y + +;md, Virtual Port 2, 6-Button Gamepad: Rapid Z +md.input.port2.gamepad6.rapid_z + +;md, Virtual Port 2, 6-Button Gamepad: RIGHT → +md.input.port2.gamepad6.right + +;md, Virtual Port 2, 6-Button Gamepad: Start +md.input.port2.gamepad6.start + +;md, Virtual Port 2, 6-Button Gamepad: UP ↑ +md.input.port2.gamepad6.up + +;md, Virtual Port 2, 6-Button Gamepad: X +md.input.port2.gamepad6.x + +;md, Virtual Port 2, 6-Button Gamepad: Y +md.input.port2.gamepad6.y + +;md, Virtual Port 2, 6-Button Gamepad: Z +md.input.port2.gamepad6.z + +;md, Virtual Port 2, Sega Mega Mouse: Left Button +md.input.port2.megamouse.left mouse 0x0 button_left + +;md, Virtual Port 2, Sega Mega Mouse: Middle Button +md.input.port2.megamouse.middle mouse 0x0 button_middle + +;md, Virtual Port 2, Sega Mega Mouse: Motion Down +md.input.port2.megamouse.motion_down mouse 0x0 rel_y+ + +;md, Virtual Port 2, Sega Mega Mouse: Motion Left +md.input.port2.megamouse.motion_left mouse 0x0 rel_x- + +;md, Virtual Port 2, Sega Mega Mouse: Motion Right +md.input.port2.megamouse.motion_right mouse 0x0 rel_x+ + +;md, Virtual Port 2, Sega Mega Mouse: Motion Up +md.input.port2.megamouse.motion_up mouse 0x0 rel_y- + +;md, Virtual Port 2, Sega Mega Mouse: Right Button +md.input.port2.megamouse.right mouse 0x0 button_right + +;md, Virtual Port 2, Sega Mega Mouse: Start Button +md.input.port2.megamouse.start keyboard 0x0 40 + +;Input device for Virtual Port 3 +md.input.port3 gamepad + +;md, Virtual Port 3, 3-Button Gamepad: A +md.input.port3.gamepad.a + +;md, Virtual Port 3, 3-Button Gamepad: B +md.input.port3.gamepad.b + +;md, Virtual Port 3, 3-Button Gamepad: C +md.input.port3.gamepad.c + +;md, Virtual Port 3, 3-Button Gamepad: DOWN ↓ +md.input.port3.gamepad.down + +;md, Virtual Port 3, 3-Button Gamepad: LEFT ← +md.input.port3.gamepad.left + +;md, Virtual Port 3, 3-Button Gamepad: Rapid A +md.input.port3.gamepad.rapid_a + +;md, Virtual Port 3, 3-Button Gamepad: Rapid B +md.input.port3.gamepad.rapid_b + +;md, Virtual Port 3, 3-Button Gamepad: Rapid C +md.input.port3.gamepad.rapid_c + +;md, Virtual Port 3, 3-Button Gamepad: RIGHT → +md.input.port3.gamepad.right + +;md, Virtual Port 3, 3-Button Gamepad: Start +md.input.port3.gamepad.start + +;md, Virtual Port 3, 3-Button Gamepad: UP ↑ +md.input.port3.gamepad.up + +;md, Virtual Port 3, 2-Button Gamepad: A +md.input.port3.gamepad2.a + +;md, Virtual Port 3, 2-Button Gamepad: B +md.input.port3.gamepad2.b + +;md, Virtual Port 3, 2-Button Gamepad: DOWN ↓ +md.input.port3.gamepad2.down + +;md, Virtual Port 3, 2-Button Gamepad: LEFT ← +md.input.port3.gamepad2.left + +;md, Virtual Port 3, 2-Button Gamepad: Rapid A +md.input.port3.gamepad2.rapid_a + +;md, Virtual Port 3, 2-Button Gamepad: Rapid B +md.input.port3.gamepad2.rapid_b + +;md, Virtual Port 3, 2-Button Gamepad: RIGHT → +md.input.port3.gamepad2.right + +;md, Virtual Port 3, 2-Button Gamepad: Start +md.input.port3.gamepad2.start + +;md, Virtual Port 3, 2-Button Gamepad: UP ↑ +md.input.port3.gamepad2.up + +;md, Virtual Port 3, 6-Button Gamepad: A +md.input.port3.gamepad6.a + +;md, Virtual Port 3, 6-Button Gamepad: B +md.input.port3.gamepad6.b + +;md, Virtual Port 3, 6-Button Gamepad: C +md.input.port3.gamepad6.c + +;md, Virtual Port 3, 6-Button Gamepad: DOWN ↓ +md.input.port3.gamepad6.down + +;md, Virtual Port 3, 6-Button Gamepad: LEFT ← +md.input.port3.gamepad6.left + +;md, Virtual Port 3, 6-Button Gamepad: Mode +md.input.port3.gamepad6.mode + +;md, Virtual Port 3, 6-Button Gamepad: Rapid A +md.input.port3.gamepad6.rapid_a + +;md, Virtual Port 3, 6-Button Gamepad: Rapid B +md.input.port3.gamepad6.rapid_b + +;md, Virtual Port 3, 6-Button Gamepad: Rapid C +md.input.port3.gamepad6.rapid_c + +;md, Virtual Port 3, 6-Button Gamepad: Rapid X +md.input.port3.gamepad6.rapid_x + +;md, Virtual Port 3, 6-Button Gamepad: Rapid Y +md.input.port3.gamepad6.rapid_y + +;md, Virtual Port 3, 6-Button Gamepad: Rapid Z +md.input.port3.gamepad6.rapid_z + +;md, Virtual Port 3, 6-Button Gamepad: RIGHT → +md.input.port3.gamepad6.right + +;md, Virtual Port 3, 6-Button Gamepad: Start +md.input.port3.gamepad6.start + +;md, Virtual Port 3, 6-Button Gamepad: UP ↑ +md.input.port3.gamepad6.up + +;md, Virtual Port 3, 6-Button Gamepad: X +md.input.port3.gamepad6.x + +;md, Virtual Port 3, 6-Button Gamepad: Y +md.input.port3.gamepad6.y + +;md, Virtual Port 3, 6-Button Gamepad: Z +md.input.port3.gamepad6.z + +;md, Virtual Port 3, Sega Mega Mouse: Left Button +md.input.port3.megamouse.left mouse 0x0 button_left + +;md, Virtual Port 3, Sega Mega Mouse: Middle Button +md.input.port3.megamouse.middle mouse 0x0 button_middle + +;md, Virtual Port 3, Sega Mega Mouse: Motion Down +md.input.port3.megamouse.motion_down mouse 0x0 rel_y+ + +;md, Virtual Port 3, Sega Mega Mouse: Motion Left +md.input.port3.megamouse.motion_left mouse 0x0 rel_x- + +;md, Virtual Port 3, Sega Mega Mouse: Motion Right +md.input.port3.megamouse.motion_right mouse 0x0 rel_x+ + +;md, Virtual Port 3, Sega Mega Mouse: Motion Up +md.input.port3.megamouse.motion_up mouse 0x0 rel_y- + +;md, Virtual Port 3, Sega Mega Mouse: Right Button +md.input.port3.megamouse.right mouse 0x0 button_right + +;md, Virtual Port 3, Sega Mega Mouse: Start Button +md.input.port3.megamouse.start keyboard 0x0 40 + +;Input device for Virtual Port 4 +md.input.port4 gamepad + +;md, Virtual Port 4, 3-Button Gamepad: A +md.input.port4.gamepad.a + +;md, Virtual Port 4, 3-Button Gamepad: B +md.input.port4.gamepad.b + +;md, Virtual Port 4, 3-Button Gamepad: C +md.input.port4.gamepad.c + +;md, Virtual Port 4, 3-Button Gamepad: DOWN ↓ +md.input.port4.gamepad.down + +;md, Virtual Port 4, 3-Button Gamepad: LEFT ← +md.input.port4.gamepad.left + +;md, Virtual Port 4, 3-Button Gamepad: Rapid A +md.input.port4.gamepad.rapid_a + +;md, Virtual Port 4, 3-Button Gamepad: Rapid B +md.input.port4.gamepad.rapid_b + +;md, Virtual Port 4, 3-Button Gamepad: Rapid C +md.input.port4.gamepad.rapid_c + +;md, Virtual Port 4, 3-Button Gamepad: RIGHT → +md.input.port4.gamepad.right + +;md, Virtual Port 4, 3-Button Gamepad: Start +md.input.port4.gamepad.start + +;md, Virtual Port 4, 3-Button Gamepad: UP ↑ +md.input.port4.gamepad.up + +;md, Virtual Port 4, 2-Button Gamepad: A +md.input.port4.gamepad2.a + +;md, Virtual Port 4, 2-Button Gamepad: B +md.input.port4.gamepad2.b + +;md, Virtual Port 4, 2-Button Gamepad: DOWN ↓ +md.input.port4.gamepad2.down + +;md, Virtual Port 4, 2-Button Gamepad: LEFT ← +md.input.port4.gamepad2.left + +;md, Virtual Port 4, 2-Button Gamepad: Rapid A +md.input.port4.gamepad2.rapid_a + +;md, Virtual Port 4, 2-Button Gamepad: Rapid B +md.input.port4.gamepad2.rapid_b + +;md, Virtual Port 4, 2-Button Gamepad: RIGHT → +md.input.port4.gamepad2.right + +;md, Virtual Port 4, 2-Button Gamepad: Start +md.input.port4.gamepad2.start + +;md, Virtual Port 4, 2-Button Gamepad: UP ↑ +md.input.port4.gamepad2.up + +;md, Virtual Port 4, 6-Button Gamepad: A +md.input.port4.gamepad6.a + +;md, Virtual Port 4, 6-Button Gamepad: B +md.input.port4.gamepad6.b + +;md, Virtual Port 4, 6-Button Gamepad: C +md.input.port4.gamepad6.c + +;md, Virtual Port 4, 6-Button Gamepad: DOWN ↓ +md.input.port4.gamepad6.down + +;md, Virtual Port 4, 6-Button Gamepad: LEFT ← +md.input.port4.gamepad6.left + +;md, Virtual Port 4, 6-Button Gamepad: Mode +md.input.port4.gamepad6.mode + +;md, Virtual Port 4, 6-Button Gamepad: Rapid A +md.input.port4.gamepad6.rapid_a + +;md, Virtual Port 4, 6-Button Gamepad: Rapid B +md.input.port4.gamepad6.rapid_b + +;md, Virtual Port 4, 6-Button Gamepad: Rapid C +md.input.port4.gamepad6.rapid_c + +;md, Virtual Port 4, 6-Button Gamepad: Rapid X +md.input.port4.gamepad6.rapid_x + +;md, Virtual Port 4, 6-Button Gamepad: Rapid Y +md.input.port4.gamepad6.rapid_y + +;md, Virtual Port 4, 6-Button Gamepad: Rapid Z +md.input.port4.gamepad6.rapid_z + +;md, Virtual Port 4, 6-Button Gamepad: RIGHT → +md.input.port4.gamepad6.right + +;md, Virtual Port 4, 6-Button Gamepad: Start +md.input.port4.gamepad6.start + +;md, Virtual Port 4, 6-Button Gamepad: UP ↑ +md.input.port4.gamepad6.up + +;md, Virtual Port 4, 6-Button Gamepad: X +md.input.port4.gamepad6.x + +;md, Virtual Port 4, 6-Button Gamepad: Y +md.input.port4.gamepad6.y + +;md, Virtual Port 4, 6-Button Gamepad: Z +md.input.port4.gamepad6.z + +;md, Virtual Port 4, Sega Mega Mouse: Left Button +md.input.port4.megamouse.left mouse 0x0 button_left + +;md, Virtual Port 4, Sega Mega Mouse: Middle Button +md.input.port4.megamouse.middle mouse 0x0 button_middle + +;md, Virtual Port 4, Sega Mega Mouse: Motion Down +md.input.port4.megamouse.motion_down mouse 0x0 rel_y+ + +;md, Virtual Port 4, Sega Mega Mouse: Motion Left +md.input.port4.megamouse.motion_left mouse 0x0 rel_x- + +;md, Virtual Port 4, Sega Mega Mouse: Motion Right +md.input.port4.megamouse.motion_right mouse 0x0 rel_x+ + +;md, Virtual Port 4, Sega Mega Mouse: Motion Up +md.input.port4.megamouse.motion_up mouse 0x0 rel_y- + +;md, Virtual Port 4, Sega Mega Mouse: Right Button +md.input.port4.megamouse.right mouse 0x0 button_right + +;md, Virtual Port 4, Sega Mega Mouse: Start Button +md.input.port4.megamouse.start keyboard 0x0 40 + +;Input device for Virtual Port 5 +md.input.port5 gamepad + +;md, Virtual Port 5, 3-Button Gamepad: A +md.input.port5.gamepad.a + +;md, Virtual Port 5, 3-Button Gamepad: B +md.input.port5.gamepad.b + +;md, Virtual Port 5, 3-Button Gamepad: C +md.input.port5.gamepad.c + +;md, Virtual Port 5, 3-Button Gamepad: DOWN ↓ +md.input.port5.gamepad.down + +;md, Virtual Port 5, 3-Button Gamepad: LEFT ← +md.input.port5.gamepad.left + +;md, Virtual Port 5, 3-Button Gamepad: Rapid A +md.input.port5.gamepad.rapid_a + +;md, Virtual Port 5, 3-Button Gamepad: Rapid B +md.input.port5.gamepad.rapid_b + +;md, Virtual Port 5, 3-Button Gamepad: Rapid C +md.input.port5.gamepad.rapid_c + +;md, Virtual Port 5, 3-Button Gamepad: RIGHT → +md.input.port5.gamepad.right + +;md, Virtual Port 5, 3-Button Gamepad: Start +md.input.port5.gamepad.start + +;md, Virtual Port 5, 3-Button Gamepad: UP ↑ +md.input.port5.gamepad.up + +;md, Virtual Port 5, 2-Button Gamepad: A +md.input.port5.gamepad2.a + +;md, Virtual Port 5, 2-Button Gamepad: B +md.input.port5.gamepad2.b + +;md, Virtual Port 5, 2-Button Gamepad: DOWN ↓ +md.input.port5.gamepad2.down + +;md, Virtual Port 5, 2-Button Gamepad: LEFT ← +md.input.port5.gamepad2.left + +;md, Virtual Port 5, 2-Button Gamepad: Rapid A +md.input.port5.gamepad2.rapid_a + +;md, Virtual Port 5, 2-Button Gamepad: Rapid B +md.input.port5.gamepad2.rapid_b + +;md, Virtual Port 5, 2-Button Gamepad: RIGHT → +md.input.port5.gamepad2.right + +;md, Virtual Port 5, 2-Button Gamepad: Start +md.input.port5.gamepad2.start + +;md, Virtual Port 5, 2-Button Gamepad: UP ↑ +md.input.port5.gamepad2.up + +;md, Virtual Port 5, 6-Button Gamepad: A +md.input.port5.gamepad6.a + +;md, Virtual Port 5, 6-Button Gamepad: B +md.input.port5.gamepad6.b + +;md, Virtual Port 5, 6-Button Gamepad: C +md.input.port5.gamepad6.c + +;md, Virtual Port 5, 6-Button Gamepad: DOWN ↓ +md.input.port5.gamepad6.down + +;md, Virtual Port 5, 6-Button Gamepad: LEFT ← +md.input.port5.gamepad6.left + +;md, Virtual Port 5, 6-Button Gamepad: Mode +md.input.port5.gamepad6.mode + +;md, Virtual Port 5, 6-Button Gamepad: Rapid A +md.input.port5.gamepad6.rapid_a + +;md, Virtual Port 5, 6-Button Gamepad: Rapid B +md.input.port5.gamepad6.rapid_b + +;md, Virtual Port 5, 6-Button Gamepad: Rapid C +md.input.port5.gamepad6.rapid_c + +;md, Virtual Port 5, 6-Button Gamepad: Rapid X +md.input.port5.gamepad6.rapid_x + +;md, Virtual Port 5, 6-Button Gamepad: Rapid Y +md.input.port5.gamepad6.rapid_y + +;md, Virtual Port 5, 6-Button Gamepad: Rapid Z +md.input.port5.gamepad6.rapid_z + +;md, Virtual Port 5, 6-Button Gamepad: RIGHT → +md.input.port5.gamepad6.right + +;md, Virtual Port 5, 6-Button Gamepad: Start +md.input.port5.gamepad6.start + +;md, Virtual Port 5, 6-Button Gamepad: UP ↑ +md.input.port5.gamepad6.up + +;md, Virtual Port 5, 6-Button Gamepad: X +md.input.port5.gamepad6.x + +;md, Virtual Port 5, 6-Button Gamepad: Y +md.input.port5.gamepad6.y + +;md, Virtual Port 5, 6-Button Gamepad: Z +md.input.port5.gamepad6.z + +;md, Virtual Port 5, Sega Mega Mouse: Left Button +md.input.port5.megamouse.left mouse 0x0 button_left + +;md, Virtual Port 5, Sega Mega Mouse: Middle Button +md.input.port5.megamouse.middle mouse 0x0 button_middle + +;md, Virtual Port 5, Sega Mega Mouse: Motion Down +md.input.port5.megamouse.motion_down mouse 0x0 rel_y+ + +;md, Virtual Port 5, Sega Mega Mouse: Motion Left +md.input.port5.megamouse.motion_left mouse 0x0 rel_x- + +;md, Virtual Port 5, Sega Mega Mouse: Motion Right +md.input.port5.megamouse.motion_right mouse 0x0 rel_x+ + +;md, Virtual Port 5, Sega Mega Mouse: Motion Up +md.input.port5.megamouse.motion_up mouse 0x0 rel_y- + +;md, Virtual Port 5, Sega Mega Mouse: Right Button +md.input.port5.megamouse.right mouse 0x0 button_right + +;md, Virtual Port 5, Sega Mega Mouse: Start Button +md.input.port5.megamouse.start keyboard 0x0 40 + +;Input device for Virtual Port 6 +md.input.port6 gamepad + +;md, Virtual Port 6, 3-Button Gamepad: A +md.input.port6.gamepad.a + +;md, Virtual Port 6, 3-Button Gamepad: B +md.input.port6.gamepad.b + +;md, Virtual Port 6, 3-Button Gamepad: C +md.input.port6.gamepad.c + +;md, Virtual Port 6, 3-Button Gamepad: DOWN ↓ +md.input.port6.gamepad.down + +;md, Virtual Port 6, 3-Button Gamepad: LEFT ← +md.input.port6.gamepad.left + +;md, Virtual Port 6, 3-Button Gamepad: Rapid A +md.input.port6.gamepad.rapid_a + +;md, Virtual Port 6, 3-Button Gamepad: Rapid B +md.input.port6.gamepad.rapid_b + +;md, Virtual Port 6, 3-Button Gamepad: Rapid C +md.input.port6.gamepad.rapid_c + +;md, Virtual Port 6, 3-Button Gamepad: RIGHT → +md.input.port6.gamepad.right + +;md, Virtual Port 6, 3-Button Gamepad: Start +md.input.port6.gamepad.start + +;md, Virtual Port 6, 3-Button Gamepad: UP ↑ +md.input.port6.gamepad.up + +;md, Virtual Port 6, 2-Button Gamepad: A +md.input.port6.gamepad2.a + +;md, Virtual Port 6, 2-Button Gamepad: B +md.input.port6.gamepad2.b + +;md, Virtual Port 6, 2-Button Gamepad: DOWN ↓ +md.input.port6.gamepad2.down + +;md, Virtual Port 6, 2-Button Gamepad: LEFT ← +md.input.port6.gamepad2.left + +;md, Virtual Port 6, 2-Button Gamepad: Rapid A +md.input.port6.gamepad2.rapid_a + +;md, Virtual Port 6, 2-Button Gamepad: Rapid B +md.input.port6.gamepad2.rapid_b + +;md, Virtual Port 6, 2-Button Gamepad: RIGHT → +md.input.port6.gamepad2.right + +;md, Virtual Port 6, 2-Button Gamepad: Start +md.input.port6.gamepad2.start + +;md, Virtual Port 6, 2-Button Gamepad: UP ↑ +md.input.port6.gamepad2.up + +;md, Virtual Port 6, 6-Button Gamepad: A +md.input.port6.gamepad6.a + +;md, Virtual Port 6, 6-Button Gamepad: B +md.input.port6.gamepad6.b + +;md, Virtual Port 6, 6-Button Gamepad: C +md.input.port6.gamepad6.c + +;md, Virtual Port 6, 6-Button Gamepad: DOWN ↓ +md.input.port6.gamepad6.down + +;md, Virtual Port 6, 6-Button Gamepad: LEFT ← +md.input.port6.gamepad6.left + +;md, Virtual Port 6, 6-Button Gamepad: Mode +md.input.port6.gamepad6.mode + +;md, Virtual Port 6, 6-Button Gamepad: Rapid A +md.input.port6.gamepad6.rapid_a + +;md, Virtual Port 6, 6-Button Gamepad: Rapid B +md.input.port6.gamepad6.rapid_b + +;md, Virtual Port 6, 6-Button Gamepad: Rapid C +md.input.port6.gamepad6.rapid_c + +;md, Virtual Port 6, 6-Button Gamepad: Rapid X +md.input.port6.gamepad6.rapid_x + +;md, Virtual Port 6, 6-Button Gamepad: Rapid Y +md.input.port6.gamepad6.rapid_y + +;md, Virtual Port 6, 6-Button Gamepad: Rapid Z +md.input.port6.gamepad6.rapid_z + +;md, Virtual Port 6, 6-Button Gamepad: RIGHT → +md.input.port6.gamepad6.right + +;md, Virtual Port 6, 6-Button Gamepad: Start +md.input.port6.gamepad6.start + +;md, Virtual Port 6, 6-Button Gamepad: UP ↑ +md.input.port6.gamepad6.up + +;md, Virtual Port 6, 6-Button Gamepad: X +md.input.port6.gamepad6.x + +;md, Virtual Port 6, 6-Button Gamepad: Y +md.input.port6.gamepad6.y + +;md, Virtual Port 6, 6-Button Gamepad: Z +md.input.port6.gamepad6.z + +;md, Virtual Port 6, Sega Mega Mouse: Left Button +md.input.port6.megamouse.left mouse 0x0 button_left + +;md, Virtual Port 6, Sega Mega Mouse: Middle Button +md.input.port6.megamouse.middle mouse 0x0 button_middle + +;md, Virtual Port 6, Sega Mega Mouse: Motion Down +md.input.port6.megamouse.motion_down mouse 0x0 rel_y+ + +;md, Virtual Port 6, Sega Mega Mouse: Motion Left +md.input.port6.megamouse.motion_left mouse 0x0 rel_x- + +;md, Virtual Port 6, Sega Mega Mouse: Motion Right +md.input.port6.megamouse.motion_right mouse 0x0 rel_x+ + +;md, Virtual Port 6, Sega Mega Mouse: Motion Up +md.input.port6.megamouse.motion_up mouse 0x0 rel_y- + +;md, Virtual Port 6, Sega Mega Mouse: Right Button +md.input.port6.megamouse.right mouse 0x0 button_right + +;md, Virtual Port 6, Sega Mega Mouse: Start Button +md.input.port6.megamouse.start keyboard 0x0 40 + +;Input device for Virtual Port 7 +md.input.port7 gamepad + +;md, Virtual Port 7, 3-Button Gamepad: A +md.input.port7.gamepad.a + +;md, Virtual Port 7, 3-Button Gamepad: B +md.input.port7.gamepad.b + +;md, Virtual Port 7, 3-Button Gamepad: C +md.input.port7.gamepad.c + +;md, Virtual Port 7, 3-Button Gamepad: DOWN ↓ +md.input.port7.gamepad.down + +;md, Virtual Port 7, 3-Button Gamepad: LEFT ← +md.input.port7.gamepad.left + +;md, Virtual Port 7, 3-Button Gamepad: Rapid A +md.input.port7.gamepad.rapid_a + +;md, Virtual Port 7, 3-Button Gamepad: Rapid B +md.input.port7.gamepad.rapid_b + +;md, Virtual Port 7, 3-Button Gamepad: Rapid C +md.input.port7.gamepad.rapid_c + +;md, Virtual Port 7, 3-Button Gamepad: RIGHT → +md.input.port7.gamepad.right + +;md, Virtual Port 7, 3-Button Gamepad: Start +md.input.port7.gamepad.start + +;md, Virtual Port 7, 3-Button Gamepad: UP ↑ +md.input.port7.gamepad.up + +;md, Virtual Port 7, 2-Button Gamepad: A +md.input.port7.gamepad2.a + +;md, Virtual Port 7, 2-Button Gamepad: B +md.input.port7.gamepad2.b + +;md, Virtual Port 7, 2-Button Gamepad: DOWN ↓ +md.input.port7.gamepad2.down + +;md, Virtual Port 7, 2-Button Gamepad: LEFT ← +md.input.port7.gamepad2.left + +;md, Virtual Port 7, 2-Button Gamepad: Rapid A +md.input.port7.gamepad2.rapid_a + +;md, Virtual Port 7, 2-Button Gamepad: Rapid B +md.input.port7.gamepad2.rapid_b + +;md, Virtual Port 7, 2-Button Gamepad: RIGHT → +md.input.port7.gamepad2.right + +;md, Virtual Port 7, 2-Button Gamepad: Start +md.input.port7.gamepad2.start + +;md, Virtual Port 7, 2-Button Gamepad: UP ↑ +md.input.port7.gamepad2.up + +;md, Virtual Port 7, 6-Button Gamepad: A +md.input.port7.gamepad6.a + +;md, Virtual Port 7, 6-Button Gamepad: B +md.input.port7.gamepad6.b + +;md, Virtual Port 7, 6-Button Gamepad: C +md.input.port7.gamepad6.c + +;md, Virtual Port 7, 6-Button Gamepad: DOWN ↓ +md.input.port7.gamepad6.down + +;md, Virtual Port 7, 6-Button Gamepad: LEFT ← +md.input.port7.gamepad6.left + +;md, Virtual Port 7, 6-Button Gamepad: Mode +md.input.port7.gamepad6.mode + +;md, Virtual Port 7, 6-Button Gamepad: Rapid A +md.input.port7.gamepad6.rapid_a + +;md, Virtual Port 7, 6-Button Gamepad: Rapid B +md.input.port7.gamepad6.rapid_b + +;md, Virtual Port 7, 6-Button Gamepad: Rapid C +md.input.port7.gamepad6.rapid_c + +;md, Virtual Port 7, 6-Button Gamepad: Rapid X +md.input.port7.gamepad6.rapid_x + +;md, Virtual Port 7, 6-Button Gamepad: Rapid Y +md.input.port7.gamepad6.rapid_y + +;md, Virtual Port 7, 6-Button Gamepad: Rapid Z +md.input.port7.gamepad6.rapid_z + +;md, Virtual Port 7, 6-Button Gamepad: RIGHT → +md.input.port7.gamepad6.right + +;md, Virtual Port 7, 6-Button Gamepad: Start +md.input.port7.gamepad6.start + +;md, Virtual Port 7, 6-Button Gamepad: UP ↑ +md.input.port7.gamepad6.up + +;md, Virtual Port 7, 6-Button Gamepad: X +md.input.port7.gamepad6.x + +;md, Virtual Port 7, 6-Button Gamepad: Y +md.input.port7.gamepad6.y + +;md, Virtual Port 7, 6-Button Gamepad: Z +md.input.port7.gamepad6.z + +;md, Virtual Port 7, Sega Mega Mouse: Left Button +md.input.port7.megamouse.left mouse 0x0 button_left + +;md, Virtual Port 7, Sega Mega Mouse: Middle Button +md.input.port7.megamouse.middle mouse 0x0 button_middle + +;md, Virtual Port 7, Sega Mega Mouse: Motion Down +md.input.port7.megamouse.motion_down mouse 0x0 rel_y+ + +;md, Virtual Port 7, Sega Mega Mouse: Motion Left +md.input.port7.megamouse.motion_left mouse 0x0 rel_x- + +;md, Virtual Port 7, Sega Mega Mouse: Motion Right +md.input.port7.megamouse.motion_right mouse 0x0 rel_x+ + +;md, Virtual Port 7, Sega Mega Mouse: Motion Up +md.input.port7.megamouse.motion_up mouse 0x0 rel_y- + +;md, Virtual Port 7, Sega Mega Mouse: Right Button +md.input.port7.megamouse.right mouse 0x0 button_right + +;md, Virtual Port 7, Sega Mega Mouse: Start Button +md.input.port7.megamouse.start keyboard 0x0 40 + +;Input device for Virtual Port 8 +md.input.port8 gamepad + +;md, Virtual Port 8, 3-Button Gamepad: A +md.input.port8.gamepad.a + +;md, Virtual Port 8, 3-Button Gamepad: B +md.input.port8.gamepad.b + +;md, Virtual Port 8, 3-Button Gamepad: C +md.input.port8.gamepad.c + +;md, Virtual Port 8, 3-Button Gamepad: DOWN ↓ +md.input.port8.gamepad.down + +;md, Virtual Port 8, 3-Button Gamepad: LEFT ← +md.input.port8.gamepad.left + +;md, Virtual Port 8, 3-Button Gamepad: Rapid A +md.input.port8.gamepad.rapid_a + +;md, Virtual Port 8, 3-Button Gamepad: Rapid B +md.input.port8.gamepad.rapid_b + +;md, Virtual Port 8, 3-Button Gamepad: Rapid C +md.input.port8.gamepad.rapid_c + +;md, Virtual Port 8, 3-Button Gamepad: RIGHT → +md.input.port8.gamepad.right + +;md, Virtual Port 8, 3-Button Gamepad: Start +md.input.port8.gamepad.start + +;md, Virtual Port 8, 3-Button Gamepad: UP ↑ +md.input.port8.gamepad.up + +;md, Virtual Port 8, 2-Button Gamepad: A +md.input.port8.gamepad2.a + +;md, Virtual Port 8, 2-Button Gamepad: B +md.input.port8.gamepad2.b + +;md, Virtual Port 8, 2-Button Gamepad: DOWN ↓ +md.input.port8.gamepad2.down + +;md, Virtual Port 8, 2-Button Gamepad: LEFT ← +md.input.port8.gamepad2.left + +;md, Virtual Port 8, 2-Button Gamepad: Rapid A +md.input.port8.gamepad2.rapid_a + +;md, Virtual Port 8, 2-Button Gamepad: Rapid B +md.input.port8.gamepad2.rapid_b + +;md, Virtual Port 8, 2-Button Gamepad: RIGHT → +md.input.port8.gamepad2.right + +;md, Virtual Port 8, 2-Button Gamepad: Start +md.input.port8.gamepad2.start + +;md, Virtual Port 8, 2-Button Gamepad: UP ↑ +md.input.port8.gamepad2.up + +;md, Virtual Port 8, 6-Button Gamepad: A +md.input.port8.gamepad6.a + +;md, Virtual Port 8, 6-Button Gamepad: B +md.input.port8.gamepad6.b + +;md, Virtual Port 8, 6-Button Gamepad: C +md.input.port8.gamepad6.c + +;md, Virtual Port 8, 6-Button Gamepad: DOWN ↓ +md.input.port8.gamepad6.down + +;md, Virtual Port 8, 6-Button Gamepad: LEFT ← +md.input.port8.gamepad6.left + +;md, Virtual Port 8, 6-Button Gamepad: Mode +md.input.port8.gamepad6.mode + +;md, Virtual Port 8, 6-Button Gamepad: Rapid A +md.input.port8.gamepad6.rapid_a + +;md, Virtual Port 8, 6-Button Gamepad: Rapid B +md.input.port8.gamepad6.rapid_b + +;md, Virtual Port 8, 6-Button Gamepad: Rapid C +md.input.port8.gamepad6.rapid_c + +;md, Virtual Port 8, 6-Button Gamepad: Rapid X +md.input.port8.gamepad6.rapid_x + +;md, Virtual Port 8, 6-Button Gamepad: Rapid Y +md.input.port8.gamepad6.rapid_y + +;md, Virtual Port 8, 6-Button Gamepad: Rapid Z +md.input.port8.gamepad6.rapid_z + +;md, Virtual Port 8, 6-Button Gamepad: RIGHT → +md.input.port8.gamepad6.right + +;md, Virtual Port 8, 6-Button Gamepad: Start +md.input.port8.gamepad6.start + +;md, Virtual Port 8, 6-Button Gamepad: UP ↑ +md.input.port8.gamepad6.up + +;md, Virtual Port 8, 6-Button Gamepad: X +md.input.port8.gamepad6.x + +;md, Virtual Port 8, 6-Button Gamepad: Y +md.input.port8.gamepad6.y + +;md, Virtual Port 8, 6-Button Gamepad: Z +md.input.port8.gamepad6.z + +;md, Virtual Port 8, Sega Mega Mouse: Left Button +md.input.port8.megamouse.left mouse 0x0 button_left + +;md, Virtual Port 8, Sega Mega Mouse: Middle Button +md.input.port8.megamouse.middle mouse 0x0 button_middle + +;md, Virtual Port 8, Sega Mega Mouse: Motion Down +md.input.port8.megamouse.motion_down mouse 0x0 rel_y+ + +;md, Virtual Port 8, Sega Mega Mouse: Motion Left +md.input.port8.megamouse.motion_left mouse 0x0 rel_x- + +;md, Virtual Port 8, Sega Mega Mouse: Motion Right +md.input.port8.megamouse.motion_right mouse 0x0 rel_x+ + +;md, Virtual Port 8, Sega Mega Mouse: Motion Up +md.input.port8.megamouse.motion_up mouse 0x0 rel_y- + +;md, Virtual Port 8, Sega Mega Mouse: Right Button +md.input.port8.megamouse.right mouse 0x0 button_right + +;md, Virtual Port 8, Sega Mega Mouse: Start Button +md.input.port8.megamouse.start keyboard 0x0 40 + +;Emulate the specified region's Genesis/MegaDrive +md.region game + +;Region reported to the game. +md.reported_region same + +;Enable scanlines with specified opacity. +md.scanlines 0 + +;Enable specified OpenGL shader. +md.shader none + +;Force interlaced video to be treated as progressive. +md.shader.goat.fprog 0 + +;Constant RGB horizontal divergence. +md.shader.goat.hdiv 0.50 + +;Mask pattern. +md.shader.goat.pat goatron + +;Enable scanlines effect. +md.shader.goat.slen 1 + +;Transparency of otherwise-opaque mask areas. +md.shader.goat.tp 0.50 + +;Constant RGB vertical divergence. +md.shader.goat.vdiv 0.50 + +;Enable specified special video scaler. +md.special none + +;Stretch to fill screen. +md.stretch aspect + +;Enable video temporal blur(50/50 previous/current frame by default). +md.tblur 0 + +;Accumulate color data rather than discarding it. +md.tblur.accum 0 + +;Blur amount in accumulation mode, specified in percentage of accumulation buffer to mix with the current frame. +md.tblur.accum.amount 50 + +;Enable (bi)linear interpolation. +md.videoip 0 + +;Full-screen horizontal resolution. +md.xres 0 + +;Scaling factor for the X axis in windowed mode. +md.xscale 3.000000 + +;Scaling factor for the X axis in fullscreen mode. +md.xscalefs 1.000000 + +;Full-screen vertical resolution. +md.yres 0 + +;Scaling factor for the Y axis in windowed mode. +md.yscale 3.000000 + +;Scaling factor for the Y axis in fullscreen mode. +md.yscalefs 1.000000 + +;Clip left+right 8 pixel columns. +nes.clipsides 0 + +;Correct the aspect ratio. +nes.correct_aspect 1 + +;Disassembly font size. +nes.debugger.disfontsize 5x7 + +;Character encoding for the debugger's memory editor. +nes.debugger.memcharenc cp437 + +;Enable (automatic) usage of this module. +nes.enable 1 + +;Scan filename for (U),(J),(E),etc. strings to en/dis-able PAL emulation. +nes.fnscan 1 + +;Enable Game Genie emulation. +nes.gg 0 + +;Path to Game Genie ROM image. +nes.ggrom gg.rom + +;Input device for Famicom Expansion Port +nes.input.fcexp none + +;nes, Famicom Expansion Port, Arkanoid Paddle: Button +nes.input.fcexp.arkanoid.button mouse 0x0 button_left + +;nes, Famicom Expansion Port, Arkanoid Paddle: X Axis +nes.input.fcexp.arkanoid.x_axis mouse 0x0 cursor_x-+ + +;nes, Famicom Expansion Port, Family Keyboard: 0 +nes.input.fcexp.fkb.0 keyboard 0x0 39 + +;nes, Famicom Expansion Port, Family Keyboard: 1 +nes.input.fcexp.fkb.1 keyboard 0x0 30 + +;nes, Famicom Expansion Port, Family Keyboard: 2 +nes.input.fcexp.fkb.2 keyboard 0x0 31 + +;nes, Famicom Expansion Port, Family Keyboard: 3 +nes.input.fcexp.fkb.3 keyboard 0x0 32 + +;nes, Famicom Expansion Port, Family Keyboard: 4 +nes.input.fcexp.fkb.4 keyboard 0x0 33 + +;nes, Famicom Expansion Port, Family Keyboard: 5 +nes.input.fcexp.fkb.5 keyboard 0x0 34 + +;nes, Famicom Expansion Port, Family Keyboard: 6 +nes.input.fcexp.fkb.6 keyboard 0x0 35 + +;nes, Famicom Expansion Port, Family Keyboard: 7 +nes.input.fcexp.fkb.7 keyboard 0x0 36 + +;nes, Famicom Expansion Port, Family Keyboard: 8 +nes.input.fcexp.fkb.8 keyboard 0x0 37 + +;nes, Famicom Expansion Port, Family Keyboard: 9 +nes.input.fcexp.fkb.9 keyboard 0x0 38 + +;nes, Famicom Expansion Port, Family Keyboard: A +nes.input.fcexp.fkb.a keyboard 0x0 4 + +;nes, Famicom Expansion Port, Family Keyboard: @ +nes.input.fcexp.fkb.at keyboard 0x0 53 + +;nes, Famicom Expansion Port, Family Keyboard: B +nes.input.fcexp.fkb.b keyboard 0x0 5 + +;nes, Famicom Expansion Port, Family Keyboard: \ +nes.input.fcexp.fkb.backslash keyboard 0x0 49 + +;nes, Famicom Expansion Port, Family Keyboard: C +nes.input.fcexp.fkb.c keyboard 0x0 6 + +;nes, Famicom Expansion Port, Family Keyboard: ^ +nes.input.fcexp.fkb.caret keyboard 0x0 46 + +;nes, Famicom Expansion Port, Family Keyboard: CLR +nes.input.fcexp.fkb.clear keyboard 0x0 76 + +;nes, Famicom Expansion Port, Family Keyboard: : +nes.input.fcexp.fkb.colon keyboard 0x0 52 + +;nes, Famicom Expansion Port, Family Keyboard: , +nes.input.fcexp.fkb.comma keyboard 0x0 54 + +;nes, Famicom Expansion Port, Family Keyboard: CTR +nes.input.fcexp.fkb.ctrl keyboard 0x0 224 + +;nes, Famicom Expansion Port, Family Keyboard: D +nes.input.fcexp.fkb.d keyboard 0x0 7 + +;nes, Famicom Expansion Port, Family Keyboard: DEL +nes.input.fcexp.fkb.delete keyboard 0x0 78 + +;nes, Famicom Expansion Port, Family Keyboard: DOWN +nes.input.fcexp.fkb.down keyboard 0x0 81 + +;nes, Famicom Expansion Port, Family Keyboard: E +nes.input.fcexp.fkb.e keyboard 0x0 8 + +;nes, Famicom Expansion Port, Family Keyboard: Empty +nes.input.fcexp.fkb.empty keyboard 0x0 230 + +;nes, Famicom Expansion Port, Family Keyboard: ESC +nes.input.fcexp.fkb.escape keyboard 0x0 41 + +;nes, Famicom Expansion Port, Family Keyboard: F +nes.input.fcexp.fkb.f keyboard 0x0 9 + +;nes, Famicom Expansion Port, Family Keyboard: F1 +nes.input.fcexp.fkb.f1 keyboard 0x0 58 + +;nes, Famicom Expansion Port, Family Keyboard: F2 +nes.input.fcexp.fkb.f2 keyboard 0x0 59 + +;nes, Famicom Expansion Port, Family Keyboard: F3 +nes.input.fcexp.fkb.f3 keyboard 0x0 60 + +;nes, Famicom Expansion Port, Family Keyboard: F4 +nes.input.fcexp.fkb.f4 keyboard 0x0 61 + +;nes, Famicom Expansion Port, Family Keyboard: F5 +nes.input.fcexp.fkb.f5 keyboard 0x0 62 + +;nes, Famicom Expansion Port, Family Keyboard: F6 +nes.input.fcexp.fkb.f6 keyboard 0x0 63 + +;nes, Famicom Expansion Port, Family Keyboard: F7 +nes.input.fcexp.fkb.f7 keyboard 0x0 64 + +;nes, Famicom Expansion Port, Family Keyboard: F8 +nes.input.fcexp.fkb.f8 keyboard 0x0 65 + +;nes, Famicom Expansion Port, Family Keyboard: G +nes.input.fcexp.fkb.g keyboard 0x0 10 + +;nes, Famicom Expansion Port, Family Keyboard: GRPH +nes.input.fcexp.fkb.graph keyboard 0x0 226 + +;nes, Famicom Expansion Port, Family Keyboard: H +nes.input.fcexp.fkb.h keyboard 0x0 11 + +;nes, Famicom Expansion Port, Family Keyboard: I +nes.input.fcexp.fkb.i keyboard 0x0 12 + +;nes, Famicom Expansion Port, Family Keyboard: INS +nes.input.fcexp.fkb.insert keyboard 0x0 77 + +;nes, Famicom Expansion Port, Family Keyboard: J +nes.input.fcexp.fkb.j keyboard 0x0 13 + +;nes, Famicom Expansion Port, Family Keyboard: K +nes.input.fcexp.fkb.k keyboard 0x0 14 + +;nes, Famicom Expansion Port, Family Keyboard: カナ +nes.input.fcexp.fkb.kana keyboard 0x0 73 + +;nes, Famicom Expansion Port, Family Keyboard: L +nes.input.fcexp.fkb.l keyboard 0x0 15 + +;nes, Famicom Expansion Port, Family Keyboard: LEFT +nes.input.fcexp.fkb.left keyboard 0x0 80 + +;nes, Famicom Expansion Port, Family Keyboard: [ +nes.input.fcexp.fkb.left_bracket keyboard 0x0 47 + +;nes, Famicom Expansion Port, Family Keyboard: Left SHIFT +nes.input.fcexp.fkb.left_shift keyboard 0x0 225 + +;nes, Famicom Expansion Port, Family Keyboard: M +nes.input.fcexp.fkb.m keyboard 0x0 16 + +;nes, Famicom Expansion Port, Family Keyboard: - +nes.input.fcexp.fkb.minus keyboard 0x0 45 + +;nes, Famicom Expansion Port, Family Keyboard: N +nes.input.fcexp.fkb.n keyboard 0x0 17 + +;nes, Famicom Expansion Port, Family Keyboard: O +nes.input.fcexp.fkb.o keyboard 0x0 18 + +;nes, Famicom Expansion Port, Family Keyboard: P +nes.input.fcexp.fkb.p keyboard 0x0 19 + +;nes, Famicom Expansion Port, Family Keyboard: . +nes.input.fcexp.fkb.period keyboard 0x0 55 + +;nes, Famicom Expansion Port, Family Keyboard: Q +nes.input.fcexp.fkb.q keyboard 0x0 20 + +;nes, Famicom Expansion Port, Family Keyboard: R +nes.input.fcexp.fkb.r keyboard 0x0 21 + +;nes, Famicom Expansion Port, Family Keyboard: RETURN +nes.input.fcexp.fkb.return keyboard 0x0 40 + +;nes, Famicom Expansion Port, Family Keyboard: RIGHT +nes.input.fcexp.fkb.right keyboard 0x0 79 + +;nes, Famicom Expansion Port, Family Keyboard: ] +nes.input.fcexp.fkb.right_bracket keyboard 0x0 48 + +;nes, Famicom Expansion Port, Family Keyboard: Right SHIFT +nes.input.fcexp.fkb.right_shift keyboard 0x0 229 + +;nes, Famicom Expansion Port, Family Keyboard: S +nes.input.fcexp.fkb.s keyboard 0x0 22 + +;nes, Famicom Expansion Port, Family Keyboard: ; +nes.input.fcexp.fkb.semicolon keyboard 0x0 51 + +;nes, Famicom Expansion Port, Family Keyboard: / +nes.input.fcexp.fkb.slash keyboard 0x0 56 + +;nes, Famicom Expansion Port, Family Keyboard: SPACE +nes.input.fcexp.fkb.space keyboard 0x0 44 + +;nes, Famicom Expansion Port, Family Keyboard: STOP +nes.input.fcexp.fkb.stop keyboard 0x0 42 + +;nes, Famicom Expansion Port, Family Keyboard: T +nes.input.fcexp.fkb.t keyboard 0x0 23 + +;nes, Famicom Expansion Port, Family Keyboard: U +nes.input.fcexp.fkb.u keyboard 0x0 24 + +;nes, Famicom Expansion Port, Family Keyboard: UP +nes.input.fcexp.fkb.up keyboard 0x0 82 + +;nes, Famicom Expansion Port, Family Keyboard: V +nes.input.fcexp.fkb.v keyboard 0x0 25 + +;nes, Famicom Expansion Port, Family Keyboard: W +nes.input.fcexp.fkb.w keyboard 0x0 26 + +;nes, Famicom Expansion Port, Family Keyboard: X +nes.input.fcexp.fkb.x keyboard 0x0 27 + +;nes, Famicom Expansion Port, Family Keyboard: Y +nes.input.fcexp.fkb.y keyboard 0x0 28 + +;nes, Famicom Expansion Port, Family Keyboard: Z +nes.input.fcexp.fkb.z keyboard 0x0 29 + +;nes, Famicom Expansion Port, Family Trainer Side A: 1 +nes.input.fcexp.ftrainera.1 keyboard 0x0 18 + +;nes, Famicom Expansion Port, Family Trainer Side A: 10 +nes.input.fcexp.ftrainera.10 keyboard 0x0 54 + +;nes, Famicom Expansion Port, Family Trainer Side A: 11 +nes.input.fcexp.ftrainera.11 keyboard 0x0 55 + +;nes, Famicom Expansion Port, Family Trainer Side A: 12 +nes.input.fcexp.ftrainera.12 keyboard 0x0 56 + +;nes, Famicom Expansion Port, Family Trainer Side A: 2 +nes.input.fcexp.ftrainera.2 keyboard 0x0 19 + +;nes, Famicom Expansion Port, Family Trainer Side A: 3 +nes.input.fcexp.ftrainera.3 keyboard 0x0 47 + +;nes, Famicom Expansion Port, Family Trainer Side A: 4 +nes.input.fcexp.ftrainera.4 keyboard 0x0 48 + +;nes, Famicom Expansion Port, Family Trainer Side A: 5 +nes.input.fcexp.ftrainera.5 keyboard 0x0 14 + +;nes, Famicom Expansion Port, Family Trainer Side A: 6 +nes.input.fcexp.ftrainera.6 keyboard 0x0 15 + +;nes, Famicom Expansion Port, Family Trainer Side A: 7 +nes.input.fcexp.ftrainera.7 keyboard 0x0 51 + +;nes, Famicom Expansion Port, Family Trainer Side A: 8 +nes.input.fcexp.ftrainera.8 keyboard 0x0 52 + +;nes, Famicom Expansion Port, Family Trainer Side A: 9 +nes.input.fcexp.ftrainera.9 keyboard 0x0 16 + +;nes, Famicom Expansion Port, Family Trainer Side B: 1 +nes.input.fcexp.ftrainerb.1 keyboard 0x0 18 + +;nes, Famicom Expansion Port, Family Trainer Side B: 10 +nes.input.fcexp.ftrainerb.10 keyboard 0x0 54 + +;nes, Famicom Expansion Port, Family Trainer Side B: 11 +nes.input.fcexp.ftrainerb.11 keyboard 0x0 55 + +;nes, Famicom Expansion Port, Family Trainer Side B: 12 +nes.input.fcexp.ftrainerb.12 keyboard 0x0 56 + +;nes, Famicom Expansion Port, Family Trainer Side B: 2 +nes.input.fcexp.ftrainerb.2 keyboard 0x0 19 + +;nes, Famicom Expansion Port, Family Trainer Side B: 3 +nes.input.fcexp.ftrainerb.3 keyboard 0x0 47 + +;nes, Famicom Expansion Port, Family Trainer Side B: 4 +nes.input.fcexp.ftrainerb.4 keyboard 0x0 48 + +;nes, Famicom Expansion Port, Family Trainer Side B: 5 +nes.input.fcexp.ftrainerb.5 keyboard 0x0 14 + +;nes, Famicom Expansion Port, Family Trainer Side B: 6 +nes.input.fcexp.ftrainerb.6 keyboard 0x0 15 + +;nes, Famicom Expansion Port, Family Trainer Side B: 7 +nes.input.fcexp.ftrainerb.7 keyboard 0x0 51 + +;nes, Famicom Expansion Port, Family Trainer Side B: 8 +nes.input.fcexp.ftrainerb.8 keyboard 0x0 52 + +;nes, Famicom Expansion Port, Family Trainer Side B: 9 +nes.input.fcexp.ftrainerb.9 keyboard 0x0 16 + +;nes, Famicom Expansion Port, Hypershot Paddles: I, JUMP +nes.input.fcexp.hypershot.i_jump keyboard 0x0 26 + +;nes, Famicom Expansion Port, Hypershot Paddles: I, RUN +nes.input.fcexp.hypershot.i_run keyboard 0x0 20 + +;nes, Famicom Expansion Port, Hypershot Paddles: II, JUMP +nes.input.fcexp.hypershot.ii_jump keyboard 0x0 21 + +;nes, Famicom Expansion Port, Hypershot Paddles: II, RUN +nes.input.fcexp.hypershot.ii_run keyboard 0x0 8 + +;nes, Famicom Expansion Port, Hypershot Paddles: Rapid I, JUMP +nes.input.fcexp.hypershot.rapid_i_jump + +;nes, Famicom Expansion Port, Hypershot Paddles: Rapid I, RUN +nes.input.fcexp.hypershot.rapid_i_run + +;nes, Famicom Expansion Port, Hypershot Paddles: Rapid II, JUMP +nes.input.fcexp.hypershot.rapid_ii_jump + +;nes, Famicom Expansion Port, Hypershot Paddles: Rapid II, RUN +nes.input.fcexp.hypershot.rapid_ii_run + +;nes, Famicom Expansion Port, Mahjong Controller: 1 +nes.input.fcexp.mahjong.1 keyboard 0x0 20 + +;nes, Famicom Expansion Port, Mahjong Controller: 10 +nes.input.fcexp.mahjong.10 keyboard 0x0 10 + +;nes, Famicom Expansion Port, Mahjong Controller: 11 +nes.input.fcexp.mahjong.11 keyboard 0x0 11 + +;nes, Famicom Expansion Port, Mahjong Controller: 12 +nes.input.fcexp.mahjong.12 keyboard 0x0 13 + +;nes, Famicom Expansion Port, Mahjong Controller: 13 +nes.input.fcexp.mahjong.13 keyboard 0x0 14 + +;nes, Famicom Expansion Port, Mahjong Controller: 14 +nes.input.fcexp.mahjong.14 keyboard 0x0 15 + +;nes, Famicom Expansion Port, Mahjong Controller: 15 +nes.input.fcexp.mahjong.15 keyboard 0x0 29 + +;nes, Famicom Expansion Port, Mahjong Controller: 16 +nes.input.fcexp.mahjong.16 keyboard 0x0 27 + +;nes, Famicom Expansion Port, Mahjong Controller: 17 +nes.input.fcexp.mahjong.17 keyboard 0x0 6 + +;nes, Famicom Expansion Port, Mahjong Controller: 18 +nes.input.fcexp.mahjong.18 keyboard 0x0 25 + +;nes, Famicom Expansion Port, Mahjong Controller: 19 +nes.input.fcexp.mahjong.19 keyboard 0x0 5 + +;nes, Famicom Expansion Port, Mahjong Controller: 2 +nes.input.fcexp.mahjong.2 keyboard 0x0 26 + +;nes, Famicom Expansion Port, Mahjong Controller: 20 +nes.input.fcexp.mahjong.20 keyboard 0x0 17 + +;nes, Famicom Expansion Port, Mahjong Controller: 21 +nes.input.fcexp.mahjong.21 keyboard 0x0 16 + +;nes, Famicom Expansion Port, Mahjong Controller: 3 +nes.input.fcexp.mahjong.3 keyboard 0x0 8 + +;nes, Famicom Expansion Port, Mahjong Controller: 4 +nes.input.fcexp.mahjong.4 keyboard 0x0 21 + +;nes, Famicom Expansion Port, Mahjong Controller: 5 +nes.input.fcexp.mahjong.5 keyboard 0x0 23 + +;nes, Famicom Expansion Port, Mahjong Controller: 6 +nes.input.fcexp.mahjong.6 keyboard 0x0 4 + +;nes, Famicom Expansion Port, Mahjong Controller: 7 +nes.input.fcexp.mahjong.7 keyboard 0x0 22 + +;nes, Famicom Expansion Port, Mahjong Controller: 8 +nes.input.fcexp.mahjong.8 keyboard 0x0 7 + +;nes, Famicom Expansion Port, Mahjong Controller: 9 +nes.input.fcexp.mahjong.9 keyboard 0x0 9 + +;nes, Famicom Expansion Port, Oeka Kids Tablet: Button +nes.input.fcexp.oekakids.button mouse 0x0 button_left + +;nes, Famicom Expansion Port, Oeka Kids Tablet: X Axis +nes.input.fcexp.oekakids.x_axis mouse 0x0 cursor_x-+ + +;nes, Famicom Expansion Port, Oeka Kids Tablet: Y Axis +nes.input.fcexp.oekakids.y_axis mouse 0x0 cursor_y-+ + +;nes, Famicom Expansion Port, Party Tap: Buzzer 1 +nes.input.fcexp.partytap.buzzer_1 keyboard 0x0 20 + +;nes, Famicom Expansion Port, Party Tap: Buzzer 2 +nes.input.fcexp.partytap.buzzer_2 keyboard 0x0 26 + +;nes, Famicom Expansion Port, Party Tap: Buzzer 3 +nes.input.fcexp.partytap.buzzer_3 keyboard 0x0 8 + +;nes, Famicom Expansion Port, Party Tap: Buzzer 4 +nes.input.fcexp.partytap.buzzer_4 keyboard 0x0 21 + +;nes, Famicom Expansion Port, Party Tap: Buzzer 5 +nes.input.fcexp.partytap.buzzer_5 keyboard 0x0 23 + +;nes, Famicom Expansion Port, Party Tap: Buzzer 6 +nes.input.fcexp.partytap.buzzer_6 keyboard 0x0 28 + +;nes, Famicom Expansion Port, Space Shadow Gun: Away Trigger +nes.input.fcexp.shadow.away_trigger mouse 0x0 button_right + +;nes, Famicom Expansion Port, Space Shadow Gun: Trigger +nes.input.fcexp.shadow.trigger mouse 0x0 button_left + +;nes, Famicom Expansion Port, Space Shadow Gun: X Axis +nes.input.fcexp.shadow.x_axis mouse 0x0 cursor_x-+ + +;nes, Famicom Expansion Port, Space Shadow Gun: Y Axis +nes.input.fcexp.shadow.y_axis mouse 0x0 cursor_y-+ + +;Input device for Port 1 +nes.input.port1 gamepad + +;nes, Port 1, Arkanoid Paddle: Button +nes.input.port1.arkanoid.button mouse 0x0 button_left + +;nes, Port 1, Arkanoid Paddle: X Axis +nes.input.port1.arkanoid.x_axis mouse 0x0 cursor_x-+ + +;nes, Port 1, Gamepad: A +nes.input.port1.gamepad.a joystick @GUID1@ @DEVICE_BTN_EAST@ + +;nes, Port 1, Gamepad: B +nes.input.port1.gamepad.b joystick @GUID1@ @DEVICE_BTN_SOUTH@ + +;nes, Port 1, Gamepad: DOWN ↓ +nes.input.port1.gamepad.down joystick @GUID1@ @DEVICE_BTN_DPAD_DOWN@ + +;nes, Port 1, Gamepad: LEFT ← +nes.input.port1.gamepad.left joystick @GUID1@ @DEVICE_BTN_DPAD_LEFT@ + +;nes, Port 1, Gamepad: Rapid A +nes.input.port1.gamepad.rapid_a joystick @GUID1@ @DEVICE_BTN_NORTH@ + +;nes, Port 1, Gamepad: Rapid B +nes.input.port1.gamepad.rapid_b joystick @GUID1@ @DEVICE_BTN_WEST@ + +;nes, Port 1, Gamepad: RIGHT → +nes.input.port1.gamepad.right joystick @GUID1@ @DEVICE_BTN_DPAD_RIGHT@ + +;nes, Port 1, Gamepad: SELECT +nes.input.port1.gamepad.select joystick @GUID1@ @DEVICE_BTN_SELECT@ + +;nes, Port 1, Gamepad: START +nes.input.port1.gamepad.start joystick @GUID1@ @DEVICE_BTN_START@ + +;nes, Port 1, Gamepad: UP ↑ +nes.input.port1.gamepad.up joystick @GUID1@ @DEVICE_BTN_DPAD_UP@ + +;nes, Port 1, Power Pad Side A: 1 +nes.input.port1.powerpada.1 keyboard 0x0 18 + +;nes, Port 1, Power Pad Side A: 10 +nes.input.port1.powerpada.10 keyboard 0x0 54 + +;nes, Port 1, Power Pad Side A: 11 +nes.input.port1.powerpada.11 keyboard 0x0 55 + +;nes, Port 1, Power Pad Side A: 12 +nes.input.port1.powerpada.12 keyboard 0x0 56 + +;nes, Port 1, Power Pad Side A: 2 +nes.input.port1.powerpada.2 keyboard 0x0 19 + +;nes, Port 1, Power Pad Side A: 3 +nes.input.port1.powerpada.3 keyboard 0x0 47 + +;nes, Port 1, Power Pad Side A: 4 +nes.input.port1.powerpada.4 keyboard 0x0 48 + +;nes, Port 1, Power Pad Side A: 5 +nes.input.port1.powerpada.5 keyboard 0x0 14 + +;nes, Port 1, Power Pad Side A: 6 +nes.input.port1.powerpada.6 keyboard 0x0 15 + +;nes, Port 1, Power Pad Side A: 7 +nes.input.port1.powerpada.7 keyboard 0x0 51 + +;nes, Port 1, Power Pad Side A: 8 +nes.input.port1.powerpada.8 keyboard 0x0 52 + +;nes, Port 1, Power Pad Side A: 9 +nes.input.port1.powerpada.9 keyboard 0x0 16 + +;nes, Port 1, Power Pad Side B: 1 +nes.input.port1.powerpadb.1 keyboard 0x0 18 + +;nes, Port 1, Power Pad Side B: 10 +nes.input.port1.powerpadb.10 keyboard 0x0 54 + +;nes, Port 1, Power Pad Side B: 11 +nes.input.port1.powerpadb.11 keyboard 0x0 55 + +;nes, Port 1, Power Pad Side B: 12 +nes.input.port1.powerpadb.12 keyboard 0x0 56 + +;nes, Port 1, Power Pad Side B: 2 +nes.input.port1.powerpadb.2 keyboard 0x0 19 + +;nes, Port 1, Power Pad Side B: 3 +nes.input.port1.powerpadb.3 keyboard 0x0 47 + +;nes, Port 1, Power Pad Side B: 4 +nes.input.port1.powerpadb.4 keyboard 0x0 48 + +;nes, Port 1, Power Pad Side B: 5 +nes.input.port1.powerpadb.5 keyboard 0x0 14 + +;nes, Port 1, Power Pad Side B: 6 +nes.input.port1.powerpadb.6 keyboard 0x0 15 + +;nes, Port 1, Power Pad Side B: 7 +nes.input.port1.powerpadb.7 keyboard 0x0 51 + +;nes, Port 1, Power Pad Side B: 8 +nes.input.port1.powerpadb.8 keyboard 0x0 52 + +;nes, Port 1, Power Pad Side B: 9 +nes.input.port1.powerpadb.9 keyboard 0x0 16 + +;nes, Port 1, Zapper: Away Trigger +nes.input.port1.zapper.away_trigger mouse 0x0 button_right + +;nes, Port 1, Zapper: Trigger +nes.input.port1.zapper.trigger mouse 0x0 button_left + +;nes, Port 1, Zapper: X Axis +nes.input.port1.zapper.x_axis mouse 0x0 cursor_x-+ + +;nes, Port 1, Zapper: Y Axis +nes.input.port1.zapper.y_axis mouse 0x0 cursor_y-+ + +;Input device for Port 2 +nes.input.port2 gamepad + +;nes, Port 2, Arkanoid Paddle: Button +nes.input.port2.arkanoid.button mouse 0x0 button_left + +;nes, Port 2, Arkanoid Paddle: X Axis +nes.input.port2.arkanoid.x_axis mouse 0x0 cursor_x-+ + +;nes, Port 2, Gamepad: A +nes.input.port2.gamepad.a + +;nes, Port 2, Gamepad: B +nes.input.port2.gamepad.b + +;nes, Port 2, Gamepad: DOWN ↓ +nes.input.port2.gamepad.down + +;nes, Port 2, Gamepad: LEFT ← +nes.input.port2.gamepad.left + +;nes, Port 2, Gamepad: Rapid A +nes.input.port2.gamepad.rapid_a + +;nes, Port 2, Gamepad: Rapid B +nes.input.port2.gamepad.rapid_b + +;nes, Port 2, Gamepad: RIGHT → +nes.input.port2.gamepad.right + +;nes, Port 2, Gamepad: SELECT +nes.input.port2.gamepad.select + +;nes, Port 2, Gamepad: START +nes.input.port2.gamepad.start + +;nes, Port 2, Gamepad: UP ↑ +nes.input.port2.gamepad.up + +;nes, Port 2, Power Pad Side A: 1 +nes.input.port2.powerpada.1 keyboard 0x0 18 + +;nes, Port 2, Power Pad Side A: 10 +nes.input.port2.powerpada.10 keyboard 0x0 54 + +;nes, Port 2, Power Pad Side A: 11 +nes.input.port2.powerpada.11 keyboard 0x0 55 + +;nes, Port 2, Power Pad Side A: 12 +nes.input.port2.powerpada.12 keyboard 0x0 56 + +;nes, Port 2, Power Pad Side A: 2 +nes.input.port2.powerpada.2 keyboard 0x0 19 + +;nes, Port 2, Power Pad Side A: 3 +nes.input.port2.powerpada.3 keyboard 0x0 47 + +;nes, Port 2, Power Pad Side A: 4 +nes.input.port2.powerpada.4 keyboard 0x0 48 + +;nes, Port 2, Power Pad Side A: 5 +nes.input.port2.powerpada.5 keyboard 0x0 14 + +;nes, Port 2, Power Pad Side A: 6 +nes.input.port2.powerpada.6 keyboard 0x0 15 + +;nes, Port 2, Power Pad Side A: 7 +nes.input.port2.powerpada.7 keyboard 0x0 51 + +;nes, Port 2, Power Pad Side A: 8 +nes.input.port2.powerpada.8 keyboard 0x0 52 + +;nes, Port 2, Power Pad Side A: 9 +nes.input.port2.powerpada.9 keyboard 0x0 16 + +;nes, Port 2, Power Pad Side B: 1 +nes.input.port2.powerpadb.1 keyboard 0x0 18 + +;nes, Port 2, Power Pad Side B: 10 +nes.input.port2.powerpadb.10 keyboard 0x0 54 + +;nes, Port 2, Power Pad Side B: 11 +nes.input.port2.powerpadb.11 keyboard 0x0 55 + +;nes, Port 2, Power Pad Side B: 12 +nes.input.port2.powerpadb.12 keyboard 0x0 56 + +;nes, Port 2, Power Pad Side B: 2 +nes.input.port2.powerpadb.2 keyboard 0x0 19 + +;nes, Port 2, Power Pad Side B: 3 +nes.input.port2.powerpadb.3 keyboard 0x0 47 + +;nes, Port 2, Power Pad Side B: 4 +nes.input.port2.powerpadb.4 keyboard 0x0 48 + +;nes, Port 2, Power Pad Side B: 5 +nes.input.port2.powerpadb.5 keyboard 0x0 14 + +;nes, Port 2, Power Pad Side B: 6 +nes.input.port2.powerpadb.6 keyboard 0x0 15 + +;nes, Port 2, Power Pad Side B: 7 +nes.input.port2.powerpadb.7 keyboard 0x0 51 + +;nes, Port 2, Power Pad Side B: 8 +nes.input.port2.powerpadb.8 keyboard 0x0 52 + +;nes, Port 2, Power Pad Side B: 9 +nes.input.port2.powerpadb.9 keyboard 0x0 16 + +;nes, Port 2, Zapper: Away Trigger +nes.input.port2.zapper.away_trigger mouse 0x0 button_right + +;nes, Port 2, Zapper: Trigger +nes.input.port2.zapper.trigger mouse 0x0 button_left + +;nes, Port 2, Zapper: X Axis +nes.input.port2.zapper.x_axis mouse 0x0 cursor_x-+ + +;nes, Port 2, Zapper: Y Axis +nes.input.port2.zapper.y_axis mouse 0x0 cursor_y-+ + +;Input device for Port 3 +nes.input.port3 gamepad + +;nes, Port 3, Gamepad: A +nes.input.port3.gamepad.a + +;nes, Port 3, Gamepad: B +nes.input.port3.gamepad.b + +;nes, Port 3, Gamepad: DOWN ↓ +nes.input.port3.gamepad.down + +;nes, Port 3, Gamepad: LEFT ← +nes.input.port3.gamepad.left + +;nes, Port 3, Gamepad: Rapid A +nes.input.port3.gamepad.rapid_a + +;nes, Port 3, Gamepad: Rapid B +nes.input.port3.gamepad.rapid_b + +;nes, Port 3, Gamepad: RIGHT → +nes.input.port3.gamepad.right + +;nes, Port 3, Gamepad: SELECT +nes.input.port3.gamepad.select + +;nes, Port 3, Gamepad: START +nes.input.port3.gamepad.start + +;nes, Port 3, Gamepad: UP ↑ +nes.input.port3.gamepad.up + +;Input device for Port 4 +nes.input.port4 gamepad + +;nes, Port 4, Gamepad: A +nes.input.port4.gamepad.a + +;nes, Port 4, Gamepad: B +nes.input.port4.gamepad.b + +;nes, Port 4, Gamepad: DOWN ↓ +nes.input.port4.gamepad.down + +;nes, Port 4, Gamepad: LEFT ← +nes.input.port4.gamepad.left + +;nes, Port 4, Gamepad: Rapid A +nes.input.port4.gamepad.rapid_a + +;nes, Port 4, Gamepad: Rapid B +nes.input.port4.gamepad.rapid_b + +;nes, Port 4, Gamepad: RIGHT → +nes.input.port4.gamepad.right + +;nes, Port 4, Gamepad: SELECT +nes.input.port4.gamepad.select + +;nes, Port 4, Gamepad: START +nes.input.port4.gamepad.start + +;nes, Port 4, Gamepad: UP ↑ +nes.input.port4.gamepad.up + +;Enable less-accurate, but better sounding, Namco 106(mapper 19) sound emulation. +nes.n106bs 0 + +;Remove 8-sprites-per-scanline hardware limit. +nes.no8lim 0 + +;Disable four-score emulation. +nes.nofs 0 + +;NTSC composite blitter brightness. +nes.ntsc.brightness 0 + +;NTSC composite blitter contrast. +nes.ntsc.contrast 0 + +;NTSC composite blitter hue. +nes.ntsc.hue 0 + +;Enable NTSC custom decoder matrix. +nes.ntsc.matrix 0 + +;NTSC custom decoder matrix element 0(red, value * V). +nes.ntsc.matrix.0 1.539 + +;NTSC custom decoder matrix element 1(red, value * U). +nes.ntsc.matrix.1 -0.622 + +;NTSC custom decoder matrix element 2(green, value * V). +nes.ntsc.matrix.2 -0.571 + +;NTSC custom decoder matrix element 3(green, value * U). +nes.ntsc.matrix.3 -0.185 + +;NTSC custom decoder matrix element 4(blue, value * V). +nes.ntsc.matrix.4 0.000 + +;NTSC custom decoder matrix element 5(blue, value * U. +nes.ntsc.matrix.5 2.000 + +;Merge fields to partially work around !=60.1Hz refresh rates. +nes.ntsc.mergefields 0 + +;Video quality/type preset. +nes.ntsc.preset none + +;NTSC composite blitter saturation. +nes.ntsc.saturation 0 + +;NTSC composite blitter sharpness. +nes.ntsc.sharpness 0 + +;Enable NTSC color generation and blitter. +nes.ntscblitter 0 + +;Enable PAL(50Hz) NES emulation. +nes.pal 0 + +;Enable scanlines with specified opacity. +nes.scanlines 0 + +;Enable specified OpenGL shader. +nes.shader ipsharper + +;Force interlaced video to be treated as progressive. +nes.shader.goat.fprog 0 + +;Constant RGB horizontal divergence. +nes.shader.goat.hdiv 0.50 + +;Mask pattern. +nes.shader.goat.pat goatron + +;Enable scanlines effect. +nes.shader.goat.slen 1 + +;Transparency of otherwise-opaque mask areas. +nes.shader.goat.tp 0.50 + +;Constant RGB vertical divergence. +nes.shader.goat.vdiv 0.50 + +;Last displayed scanline in NTSC mode. +nes.slend 231 + +;Last displayed scanline in PAL mode. +nes.slendp 239 + +;First displayed scanline in NTSC mode. +nes.slstart 8 + +;First displayed scanline in PAL mode. +nes.slstartp 0 + +;Output rate tolerance. +nes.sound_rate_error 0.00004 + +;Sound quality. +nes.soundq 0 + +;Enable specified special video scaler. +nes.special none + +;Stretch to fill screen. +nes.stretch full + +;Enable video temporal blur(50/50 previous/current frame by default). +nes.tblur 0 + +;Accumulate color data rather than discarding it. +nes.tblur.accum 0 + +;Blur amount in accumulation mode, specified in percentage of accumulation buffer to mix with the current frame. +nes.tblur.accum.amount 50 + +;Enable (bi)linear interpolation. +nes.videoip 0 + +;Full-screen horizontal resolution. +nes.xres 0 + +;Scaling factor for the X axis in windowed mode. +nes.xscale 4.000000 + +;Scaling factor for the X axis in fullscreen mode. +nes.xscalefs 1.000000 + +;Full-screen vertical resolution. +nes.yres 0 + +;Scaling factor for the Y axis in windowed mode. +nes.yscale 4.000000 + +;Scaling factor for the Y axis in fullscreen mode. +nes.yscalefs 1.000000 + +;Font for netplay chat console. +netplay.console.font 9x18 + +;Height of chat console, in lines. +netplay.console.lines 5 + +;Netplay chat console text scale factor. +netplay.console.scale 1 + +;Key to hash with the MD5 hash of the game. +netplay.gamekey + +;Server hostname. +netplay.host netplay.fobby.net + +;Local player count. +netplay.localplayers 1 + +;Nickname. +netplay.nick + +;Server password. +netplay.password + +;Server port. +netplay.port 4046 + +;Enable (automatic) usage of this module. +ngp.enable 1 + +;Force monophonic sound output. +ngp.forcemono 0 + +;ngp, Built-In, Gamepad: A +ngp.input.builtin.gamepad.a joystick @GUID1@ @DEVICE_BTN_SOUTH@ + +;ngp, Built-In, Gamepad: B +ngp.input.builtin.gamepad.b joystick @GUID1@ @DEVICE_BTN_EAST@ + +;ngp, Built-In, Gamepad: DOWN ↓ +ngp.input.builtin.gamepad.down joystick @GUID1@ @DEVICE_BTN_DPAD_DOWN@ + +;ngp, Built-In, Gamepad: LEFT ← +ngp.input.builtin.gamepad.left joystick @GUID1@ @DEVICE_BTN_DPAD_LEFT@ + +;ngp, Built-In, Gamepad: OPTION +ngp.input.builtin.gamepad.option joystick @GUID1@ @DEVICE_BTN_START@ + +;ngp, Built-In, Gamepad: Rapid A +ngp.input.builtin.gamepad.rapid_a joystick @GUID1@ @DEVICE_BTN_WEST@ + +;ngp, Built-In, Gamepad: Rapid B +ngp.input.builtin.gamepad.rapid_b joystick @GUID1@ @DEVICE_BTN_NORTH@ + +;ngp, Built-In, Gamepad: RIGHT → +ngp.input.builtin.gamepad.right joystick @GUID1@ @DEVICE_BTN_DPAD_RIGHT@ + +;ngp, Built-In, Gamepad: UP ↑ +ngp.input.builtin.gamepad.up joystick @GUID1@ @DEVICE_BTN_DPAD_UP@ + +;Language games should display text in. +ngp.language english + +;Enable scanlines with specified opacity. +ngp.scanlines 0 + +;Enable specified OpenGL shader. +ngp.shader ipsharper + +;Force interlaced video to be treated as progressive. +ngp.shader.goat.fprog 0 + +;Constant RGB horizontal divergence. +ngp.shader.goat.hdiv 0.50 + +;Mask pattern. +ngp.shader.goat.pat goatron + +;Enable scanlines effect. +ngp.shader.goat.slen 1 + +;Transparency of otherwise-opaque mask areas. +ngp.shader.goat.tp 0.50 + +;Constant RGB vertical divergence. +ngp.shader.goat.vdiv 0.50 + +;Enable specified special video scaler. +ngp.special none + +;Stretch to fill screen. +ngp.stretch aspect + +;Enable video temporal blur(50/50 previous/current frame by default). +ngp.tblur 0 + +;Accumulate color data rather than discarding it. +ngp.tblur.accum 0 + +;Blur amount in accumulation mode, specified in percentage of accumulation buffer to mix with the current frame. +ngp.tblur.accum.amount 50 + +;Enable (bi)linear interpolation. +ngp.videoip 0 + +;Full-screen horizontal resolution. +ngp.xres 0 + +;Scaling factor for the X axis in windowed mode. +ngp.xscale 6.000000 + +;Scaling factor for the X axis in fullscreen mode. +ngp.xscalefs 1.000000 + +;Full-screen vertical resolution. +ngp.yres 0 + +;Scaling factor for the Y axis in windowed mode. +ngp.yscale 6.000000 + +;Scaling factor for the Y axis in fullscreen mode. +ngp.yscalefs 1.000000 + +;Disable speed throttling when sound is disabled. +nothrottle 0 + +;Enable alpha blending for OSD elements. +osd.alpha_blend 1 + +;Length of time, in milliseconds, to display internal status and error messages +osd.message_display_time 2500 + +;Length of time, in milliseconds, to display the save state or the movie selector after selecting a state or movie. +osd.state_display_time 2000 + +;Output the full 12-bit ADPCM predictor. +pce.adpcmextraprec 0 + +;ADPCM volume. +pce.adpcmvolume 100 + +;Enable Arcade Card emulation. +pce.arcadecard 1 + +;Path to the CD BIOS +pce.cdbios syscard3.pce + +;CD-DA volume. +pce.cddavolume 100 + +;PSG volume when playing a CD game. +pce.cdpsgvolume 100 + +;Disassembly font size. +pce.debugger.disfontsize 5x7 + +;Character encoding for the debugger's memory editor. +pce.debugger.memcharenc shift_jis + +;Disable BRAM(saved game memory) for CD games. +pce.disable_bram_cd 0 + +;Disable BRAM(saved game memory) for HuCard games. +pce.disable_bram_hucard 0 + +;If set, when RUN+SEL are pressed simultaneously, disable both buttons temporarily. +pce.disable_softreset 0 + +;Enable (automatic) usage of this module. +pce.enable 1 + +;Force monophonic sound output. +pce.forcemono 0 + +;Force SuperGrafx emulation. +pce.forcesgx 0 + +;Path to the GE CD BIOS +pce.gecdbios gecard.pce + +;Show horizontal overscan area. +pce.h_overscan 0 + +;Enable multitap(TurboTap) emulation. +pce.input.multitap 1 + +;Input device for Port 1 +pce.input.port1 gamepad + +;pce, Port 1, Gamepad: DOWN ↓ +pce.input.port1.gamepad.down joystick @GUID1@ @DEVICE_BTN_DPAD_DOWN@ + +;pce, Port 1, Gamepad: I +pce.input.port1.gamepad.i joystick @GUID1@ @DEVICE_BTN_EAST@ + +;pce, Port 1, Gamepad: II +pce.input.port1.gamepad.ii joystick @GUID1@ @DEVICE_BTN_SOUTH@ + +;pce, Port 1, Gamepad: III +pce.input.port1.gamepad.iii joystick @GUID1@ @DEVICE_BTN_WEST@ + +;pce, Port 1, Gamepad: IV +pce.input.port1.gamepad.iv joystick @GUID1@ @DEVICE_BTN_NORTH@ + +;pce, Port 1, Gamepad: LEFT ← +pce.input.port1.gamepad.left joystick @GUID1@ @DEVICE_BTN_DPAD_LEFT@ + +;pce, Port 1, Gamepad: Mode +pce.input.port1.gamepad.mode_select keyboard 0x0 20 + +;Default position for switch "Mode". +pce.input.port1.gamepad.mode_select.defpos 2 + +;pce, Port 1, Gamepad: Rapid I +pce.input.port1.gamepad.rapid_i keyboard 0x0 17 + +;pce, Port 1, Gamepad: Rapid II +pce.input.port1.gamepad.rapid_ii keyboard 0x0 17 + +;pce, Port 1, Gamepad: RIGHT → +pce.input.port1.gamepad.right joystick @GUID1@ @DEVICE_BTN_DPAD_RIGHT@ + +;pce, Port 1, Gamepad: RUN +pce.input.port1.gamepad.run joystick @GUID1@ @DEVICE_BTN_START@ + +;pce, Port 1, Gamepad: SELECT +pce.input.port1.gamepad.select joystick @GUID1@ @DEVICE_BTN_SELECT@ + +;pce, Port 1, Gamepad: UP ↑ +pce.input.port1.gamepad.up joystick @GUID1@ @DEVICE_BTN_DPAD_UP@ + +;pce, Port 1, Gamepad: V +pce.input.port1.gamepad.v joystick @GUID1@ @DEVICE_BTN_TL@ + +;pce, Port 1, Gamepad: VI +pce.input.port1.gamepad.vi joystick @GUID1@ @DEVICE_BTN_TR@ + +;pce, Port 1, Mouse: Left Button +pce.input.port1.mouse.left mouse 0x0 button_left + +;pce, Port 1, Mouse: Motion Down +pce.input.port1.mouse.motion_down mouse 0x0 rel_y+ + +;pce, Port 1, Mouse: Motion Left +pce.input.port1.mouse.motion_left mouse 0x0 rel_x- + +;pce, Port 1, Mouse: Motion Right +pce.input.port1.mouse.motion_right mouse 0x0 rel_x+ + +;pce, Port 1, Mouse: Motion Up +pce.input.port1.mouse.motion_up mouse 0x0 rel_y- + +;pce, Port 1, Mouse: Right Button +pce.input.port1.mouse.right mouse 0x0 button_right + +;pce, Port 1, Mouse: RUN +pce.input.port1.mouse.run keyboard 0x0 40 + +;pce, Port 1, Mouse: SELECT +pce.input.port1.mouse.select keyboard 0x0 43 + +;pce, Port 1, Tsushin Keyboard: 0 +pce.input.port1.tsushinkb.0 keyboard 0x0 39 + +;pce, Port 1, Tsushin Keyboard: 1 +pce.input.port1.tsushinkb.1 keyboard 0x0 30 + +;pce, Port 1, Tsushin Keyboard: 2 +pce.input.port1.tsushinkb.2 keyboard 0x0 31 + +;pce, Port 1, Tsushin Keyboard: 3 +pce.input.port1.tsushinkb.3 keyboard 0x0 32 + +;pce, Port 1, Tsushin Keyboard: 4 +pce.input.port1.tsushinkb.4 keyboard 0x0 33 + +;pce, Port 1, Tsushin Keyboard: 5 +pce.input.port1.tsushinkb.5 keyboard 0x0 34 + +;pce, Port 1, Tsushin Keyboard: 6 +pce.input.port1.tsushinkb.6 keyboard 0x0 35 + +;pce, Port 1, Tsushin Keyboard: 7 +pce.input.port1.tsushinkb.7 keyboard 0x0 36 + +;pce, Port 1, Tsushin Keyboard: 8 +pce.input.port1.tsushinkb.8 keyboard 0x0 37 + +;pce, Port 1, Tsushin Keyboard: 9 +pce.input.port1.tsushinkb.9 keyboard 0x0 38 + +;pce, Port 1, Tsushin Keyboard: a +pce.input.port1.tsushinkb.a keyboard 0x0 4 + +;pce, Port 1, Tsushin Keyboard: @ +pce.input.port1.tsushinkb.at keyboard 0x0 53 + +;pce, Port 1, Tsushin Keyboard: b +pce.input.port1.tsushinkb.b keyboard 0x0 5 + +;pce, Port 1, Tsushin Keyboard: backspace +pce.input.port1.tsushinkb.backspace keyboard 0x0 42 + +;pce, Port 1, Tsushin Keyboard: c +pce.input.port1.tsushinkb.c keyboard 0x0 6 + +;pce, Port 1, Tsushin Keyboard: Caps Lock +pce.input.port1.tsushinkb.caps_lock keyboard 0x0 57 + +;pce, Port 1, Tsushin Keyboard: ^ +pce.input.port1.tsushinkb.caret keyboard 0x0 46 + +;pce, Port 1, Tsushin Keyboard: clear +pce.input.port1.tsushinkb.clear keyboard 0x0 74 + +;pce, Port 1, Tsushin Keyboard: : +pce.input.port1.tsushinkb.colon keyboard 0x0 52 + +;pce, Port 1, Tsushin Keyboard: , +pce.input.port1.tsushinkb.comma keyboard 0x0 54 + +;pce, Port 1, Tsushin Keyboard: 変換 +pce.input.port1.tsushinkb.convert keyboard 0x0 230 + +;pce, Port 1, Tsushin Keyboard: Copy +pce.input.port1.tsushinkb.copy keyboard 0x0 70 + +;pce, Port 1, Tsushin Keyboard: CTRL/Control +pce.input.port1.tsushinkb.ctrl keyboard 0x0 224 + +;pce, Port 1, Tsushin Keyboard: d +pce.input.port1.tsushinkb.d keyboard 0x0 7 + +;pce, Port 1, Tsushin Keyboard: Delete +pce.input.port1.tsushinkb.delete keyboard 0x0 76 + +;pce, Port 1, Tsushin Keyboard: down +pce.input.port1.tsushinkb.down keyboard 0x0 81 + +;pce, Port 1, Tsushin Keyboard: e +pce.input.port1.tsushinkb.e keyboard 0x0 8 + +;pce, Port 1, Tsushin Keyboard: Escape +pce.input.port1.tsushinkb.escape keyboard 0x0 41 + +;pce, Port 1, Tsushin Keyboard: f +pce.input.port1.tsushinkb.f keyboard 0x0 9 + +;pce, Port 1, Tsushin Keyboard: F1 +pce.input.port1.tsushinkb.f1 keyboard 0x0 58 + +;pce, Port 1, Tsushin Keyboard: F10 +pce.input.port1.tsushinkb.f10 keyboard 0x0 67 + +;pce, Port 1, Tsushin Keyboard: F2 +pce.input.port1.tsushinkb.f2 keyboard 0x0 59 + +;pce, Port 1, Tsushin Keyboard: F3 +pce.input.port1.tsushinkb.f3 keyboard 0x0 60 + +;pce, Port 1, Tsushin Keyboard: F4 +pce.input.port1.tsushinkb.f4 keyboard 0x0 61 + +;pce, Port 1, Tsushin Keyboard: F5 +pce.input.port1.tsushinkb.f5 keyboard 0x0 62 + +;pce, Port 1, Tsushin Keyboard: f6 +pce.input.port1.tsushinkb.f6 keyboard 0x0 63 + +;pce, Port 1, Tsushin Keyboard: f7 +pce.input.port1.tsushinkb.f7 keyboard 0x0 64 + +;pce, Port 1, Tsushin Keyboard: f8 +pce.input.port1.tsushinkb.f8 keyboard 0x0 65 + +;pce, Port 1, Tsushin Keyboard: f9 +pce.input.port1.tsushinkb.f9 keyboard 0x0 66 + +;pce, Port 1, Tsushin Keyboard: g +pce.input.port1.tsushinkb.g keyboard 0x0 10 + +;pce, Port 1, Tsushin Keyboard: GRPH +pce.input.port1.tsushinkb.grph keyboard 0x0 0 + +;pce, Port 1, Tsushin Keyboard: h +pce.input.port1.tsushinkb.h keyboard 0x0 11 + +;pce, Port 1, Tsushin Keyboard: Help +pce.input.port1.tsushinkb.help keyboard 0x0 77 + +;pce, Port 1, Tsushin Keyboard: i +pce.input.port1.tsushinkb.i keyboard 0x0 12 + +;pce, Port 1, Tsushin Keyboard: insert +pce.input.port1.tsushinkb.insert keyboard 0x0 73 + +;pce, Port 1, Tsushin Keyboard: j +pce.input.port1.tsushinkb.j keyboard 0x0 13 + +;pce, Port 1, Tsushin Keyboard: k +pce.input.port1.tsushinkb.k keyboard 0x0 14 + +;pce, Port 1, Tsushin Keyboard: カナ +pce.input.port1.tsushinkb.kana keyboard 0x0 227 + +;pce, Port 1, Tsushin Keyboard: Keypad 0 +pce.input.port1.tsushinkb.kp_0 keyboard 0x0 98 + +;pce, Port 1, Tsushin Keyboard: Keypad 1 +pce.input.port1.tsushinkb.kp_1 keyboard 0x0 89 + +;pce, Port 1, Tsushin Keyboard: Keypad 2 +pce.input.port1.tsushinkb.kp_2 keyboard 0x0 90 + +;pce, Port 1, Tsushin Keyboard: Keypad 3 +pce.input.port1.tsushinkb.kp_3 keyboard 0x0 91 + +;pce, Port 1, Tsushin Keyboard: Keypad 4 +pce.input.port1.tsushinkb.kp_4 keyboard 0x0 92 + +;pce, Port 1, Tsushin Keyboard: Keypad 5 +pce.input.port1.tsushinkb.kp_5 keyboard 0x0 93 + +;pce, Port 1, Tsushin Keyboard: Keypad 6 +pce.input.port1.tsushinkb.kp_6 keyboard 0x0 94 + +;pce, Port 1, Tsushin Keyboard: Keypad 7 +pce.input.port1.tsushinkb.kp_7 keyboard 0x0 95 + +;pce, Port 1, Tsushin Keyboard: Keypad 8 +pce.input.port1.tsushinkb.kp_8 keyboard 0x0 96 + +;pce, Port 1, Tsushin Keyboard: Keypad 9 +pce.input.port1.tsushinkb.kp_9 keyboard 0x0 97 + +;pce, Port 1, Tsushin Keyboard: Keypad , +pce.input.port1.tsushinkb.kp_comma keyboard 0x0 0 + +;pce, Port 1, Tsushin Keyboard: Keypad Divide +pce.input.port1.tsushinkb.kp_divide keyboard 0x0 84 + +;pce, Port 1, Tsushin Keyboard: Keypad Enter +pce.input.port1.tsushinkb.kp_enter keyboard 0x0 88 + +;pce, Port 1, Tsushin Keyboard: Keypad = +pce.input.port1.tsushinkb.kp_equals keyboard 0x0 103 + +;pce, Port 1, Tsushin Keyboard: Keypad Minus +pce.input.port1.tsushinkb.kp_minus keyboard 0x0 86 + +;pce, Port 1, Tsushin Keyboard: Keypad * +pce.input.port1.tsushinkb.kp_multiply keyboard 0x0 85 + +;pce, Port 1, Tsushin Keyboard: Keypad . +pce.input.port1.tsushinkb.kp_period keyboard 0x0 99 + +;pce, Port 1, Tsushin Keyboard: Keypad + +pce.input.port1.tsushinkb.kp_plus keyboard 0x0 87 + +;pce, Port 1, Tsushin Keyboard: l +pce.input.port1.tsushinkb.l keyboard 0x0 15 + +;pce, Port 1, Tsushin Keyboard: left +pce.input.port1.tsushinkb.left keyboard 0x0 80 + +;pce, Port 1, Tsushin Keyboard: [ +pce.input.port1.tsushinkb.left_bracket keyboard 0x0 47 + +;pce, Port 1, Tsushin Keyboard: Left Shift +pce.input.port1.tsushinkb.left_shift keyboard 0x0 225 + +;pce, Port 1, Tsushin Keyboard: m +pce.input.port1.tsushinkb.m keyboard 0x0 16 + +;pce, Port 1, Tsushin Keyboard: Minus +pce.input.port1.tsushinkb.minus keyboard 0x0 45 + +;pce, Port 1, Tsushin Keyboard: n +pce.input.port1.tsushinkb.n keyboard 0x0 17 + +;pce, Port 1, Tsushin Keyboard: 決定 +pce.input.port1.tsushinkb.nonconvert keyboard 0x0 226 + +;pce, Port 1, Tsushin Keyboard: o +pce.input.port1.tsushinkb.o keyboard 0x0 18 + +;pce, Port 1, Tsushin Keyboard: p +pce.input.port1.tsushinkb.p keyboard 0x0 19 + +;pce, Port 1, Tsushin Keyboard: PC +pce.input.port1.tsushinkb.pc keyboard 0x0 231 + +;pce, Port 1, Tsushin Keyboard: . +pce.input.port1.tsushinkb.period keyboard 0x0 55 + +;pce, Port 1, Tsushin Keyboard: q +pce.input.port1.tsushinkb.q keyboard 0x0 20 + +;pce, Port 1, Tsushin Keyboard: r +pce.input.port1.tsushinkb.r keyboard 0x0 21 + +;pce, Port 1, Tsushin Keyboard: return +pce.input.port1.tsushinkb.return keyboard 0x0 40 + +;pce, Port 1, Tsushin Keyboard: right +pce.input.port1.tsushinkb.right keyboard 0x0 79 + +;pce, Port 1, Tsushin Keyboard: ] +pce.input.port1.tsushinkb.right_bracket keyboard 0x0 48 + +;pce, Port 1, Tsushin Keyboard: Right Shift +pce.input.port1.tsushinkb.right_shift keyboard 0x0 229 + +;pce, Port 1, Tsushin Keyboard: ROLL DOWN +pce.input.port1.tsushinkb.roll_down keyboard 0x0 78 + +;pce, Port 1, Tsushin Keyboard: ROLL UP +pce.input.port1.tsushinkb.roll_up keyboard 0x0 75 + +;pce, Port 1, Tsushin Keyboard: s +pce.input.port1.tsushinkb.s keyboard 0x0 22 + +;pce, Port 1, Tsushin Keyboard: ; +pce.input.port1.tsushinkb.semicolon keyboard 0x0 51 + +;pce, Port 1, Tsushin Keyboard: / +pce.input.port1.tsushinkb.slash keyboard 0x0 56 + +;pce, Port 1, Tsushin Keyboard: space +pce.input.port1.tsushinkb.space keyboard 0x0 44 + +;pce, Port 1, Tsushin Keyboard: STOP +pce.input.port1.tsushinkb.stop keyboard 0x0 72 + +;pce, Port 1, Tsushin Keyboard: t +pce.input.port1.tsushinkb.t keyboard 0x0 23 + +;pce, Port 1, Tsushin Keyboard: Tab +pce.input.port1.tsushinkb.tab keyboard 0x0 43 + +;pce, Port 1, Tsushin Keyboard: u +pce.input.port1.tsushinkb.u keyboard 0x0 24 + +;pce, Port 1, Tsushin Keyboard: Underscore +pce.input.port1.tsushinkb.underscore keyboard 0x0 0 + +;pce, Port 1, Tsushin Keyboard: up +pce.input.port1.tsushinkb.up keyboard 0x0 82 + +;pce, Port 1, Tsushin Keyboard: v +pce.input.port1.tsushinkb.v keyboard 0x0 25 + +;pce, Port 1, Tsushin Keyboard: w +pce.input.port1.tsushinkb.w keyboard 0x0 26 + +;pce, Port 1, Tsushin Keyboard: 変換 +pce.input.port1.tsushinkb.width keyboard 0x0 228 + +;pce, Port 1, Tsushin Keyboard: x +pce.input.port1.tsushinkb.x keyboard 0x0 27 + +;pce, Port 1, Tsushin Keyboard: y +pce.input.port1.tsushinkb.y keyboard 0x0 28 + +;pce, Port 1, Tsushin Keyboard: Yen +pce.input.port1.tsushinkb.yen keyboard 0x0 46 + +;pce, Port 1, Tsushin Keyboard: z +pce.input.port1.tsushinkb.z keyboard 0x0 29 + +;Input device for Port 2 +pce.input.port2 gamepad + +;pce, Port 2, Gamepad: DOWN ↓ +pce.input.port2.gamepad.down + +;pce, Port 2, Gamepad: I +pce.input.port2.gamepad.i + +;pce, Port 2, Gamepad: II +pce.input.port2.gamepad.ii + +;pce, Port 2, Gamepad: III +pce.input.port2.gamepad.iii + +;pce, Port 2, Gamepad: IV +pce.input.port2.gamepad.iv + +;pce, Port 2, Gamepad: LEFT ← +pce.input.port2.gamepad.left + +;pce, Port 2, Gamepad: Mode +pce.input.port2.gamepad.mode_select + +;Default position for switch "Mode". +pce.input.port2.gamepad.mode_select.defpos 2 + +;pce, Port 2, Gamepad: Rapid I +pce.input.port2.gamepad.rapid_i + +;pce, Port 2, Gamepad: Rapid II +pce.input.port2.gamepad.rapid_ii + +;pce, Port 2, Gamepad: RIGHT → +pce.input.port2.gamepad.right + +;pce, Port 2, Gamepad: RUN +pce.input.port2.gamepad.run + +;pce, Port 2, Gamepad: SELECT +pce.input.port2.gamepad.select + +;pce, Port 2, Gamepad: UP ↑ +pce.input.port2.gamepad.up + +;pce, Port 2, Gamepad: V +pce.input.port2.gamepad.v + +;pce, Port 2, Gamepad: VI +pce.input.port2.gamepad.vi + +;pce, Port 2, Mouse: Left Button +pce.input.port2.mouse.left mouse 0x0 button_left + +;pce, Port 2, Mouse: Motion Down +pce.input.port2.mouse.motion_down mouse 0x0 rel_y+ + +;pce, Port 2, Mouse: Motion Left +pce.input.port2.mouse.motion_left mouse 0x0 rel_x- + +;pce, Port 2, Mouse: Motion Right +pce.input.port2.mouse.motion_right mouse 0x0 rel_x+ + +;pce, Port 2, Mouse: Motion Up +pce.input.port2.mouse.motion_up mouse 0x0 rel_y- + +;pce, Port 2, Mouse: Right Button +pce.input.port2.mouse.right mouse 0x0 button_right + +;pce, Port 2, Mouse: RUN +pce.input.port2.mouse.run keyboard 0x0 40 + +;pce, Port 2, Mouse: SELECT +pce.input.port2.mouse.select keyboard 0x0 43 + +;Input device for Port 3 +pce.input.port3 gamepad + +;pce, Port 3, Gamepad: DOWN ↓ +pce.input.port3.gamepad.down + +;pce, Port 3, Gamepad: I +pce.input.port3.gamepad.i + +;pce, Port 3, Gamepad: II +pce.input.port3.gamepad.ii + +;pce, Port 3, Gamepad: III +pce.input.port3.gamepad.iii + +;pce, Port 3, Gamepad: IV +pce.input.port3.gamepad.iv + +;pce, Port 3, Gamepad: LEFT ← +pce.input.port3.gamepad.left + +;pce, Port 3, Gamepad: Mode +pce.input.port3.gamepad.mode_select + +;Default position for switch "Mode". +pce.input.port3.gamepad.mode_select.defpos 2 + +;pce, Port 3, Gamepad: Rapid I +pce.input.port3.gamepad.rapid_i + +;pce, Port 3, Gamepad: Rapid II +pce.input.port3.gamepad.rapid_ii + +;pce, Port 3, Gamepad: RIGHT → +pce.input.port3.gamepad.right + +;pce, Port 3, Gamepad: RUN +pce.input.port3.gamepad.run + +;pce, Port 3, Gamepad: SELECT +pce.input.port3.gamepad.select + +;pce, Port 3, Gamepad: UP ↑ +pce.input.port3.gamepad.up + +;pce, Port 3, Gamepad: V +pce.input.port3.gamepad.v + +;pce, Port 3, Gamepad: VI +pce.input.port3.gamepad.vi + +;pce, Port 3, Mouse: Left Button +pce.input.port3.mouse.left mouse 0x0 button_left + +;pce, Port 3, Mouse: Motion Down +pce.input.port3.mouse.motion_down mouse 0x0 rel_y+ + +;pce, Port 3, Mouse: Motion Left +pce.input.port3.mouse.motion_left mouse 0x0 rel_x- + +;pce, Port 3, Mouse: Motion Right +pce.input.port3.mouse.motion_right mouse 0x0 rel_x+ + +;pce, Port 3, Mouse: Motion Up +pce.input.port3.mouse.motion_up mouse 0x0 rel_y- + +;pce, Port 3, Mouse: Right Button +pce.input.port3.mouse.right mouse 0x0 button_right + +;pce, Port 3, Mouse: RUN +pce.input.port3.mouse.run keyboard 0x0 40 + +;pce, Port 3, Mouse: SELECT +pce.input.port3.mouse.select keyboard 0x0 43 + +;Input device for Port 4 +pce.input.port4 gamepad + +;pce, Port 4, Gamepad: DOWN ↓ +pce.input.port4.gamepad.down + +;pce, Port 4, Gamepad: I +pce.input.port4.gamepad.i + +;pce, Port 4, Gamepad: II +pce.input.port4.gamepad.ii + +;pce, Port 4, Gamepad: III +pce.input.port4.gamepad.iii + +;pce, Port 4, Gamepad: IV +pce.input.port4.gamepad.iv + +;pce, Port 4, Gamepad: LEFT ← +pce.input.port4.gamepad.left + +;pce, Port 4, Gamepad: Mode +pce.input.port4.gamepad.mode_select + +;Default position for switch "Mode". +pce.input.port4.gamepad.mode_select.defpos 2 + +;pce, Port 4, Gamepad: Rapid I +pce.input.port4.gamepad.rapid_i + +;pce, Port 4, Gamepad: Rapid II +pce.input.port4.gamepad.rapid_ii + +;pce, Port 4, Gamepad: RIGHT → +pce.input.port4.gamepad.right + +;pce, Port 4, Gamepad: RUN +pce.input.port4.gamepad.run + +;pce, Port 4, Gamepad: SELECT +pce.input.port4.gamepad.select + +;pce, Port 4, Gamepad: UP ↑ +pce.input.port4.gamepad.up + +;pce, Port 4, Gamepad: V +pce.input.port4.gamepad.v + +;pce, Port 4, Gamepad: VI +pce.input.port4.gamepad.vi + +;pce, Port 4, Mouse: Left Button +pce.input.port4.mouse.left mouse 0x0 button_left + +;pce, Port 4, Mouse: Motion Down +pce.input.port4.mouse.motion_down mouse 0x0 rel_y+ + +;pce, Port 4, Mouse: Motion Left +pce.input.port4.mouse.motion_left mouse 0x0 rel_x- + +;pce, Port 4, Mouse: Motion Right +pce.input.port4.mouse.motion_right mouse 0x0 rel_x+ + +;pce, Port 4, Mouse: Motion Up +pce.input.port4.mouse.motion_up mouse 0x0 rel_y- + +;pce, Port 4, Mouse: Right Button +pce.input.port4.mouse.right mouse 0x0 button_right + +;pce, Port 4, Mouse: RUN +pce.input.port4.mouse.run keyboard 0x0 40 + +;pce, Port 4, Mouse: SELECT +pce.input.port4.mouse.select keyboard 0x0 43 + +;Input device for Port 5 +pce.input.port5 gamepad + +;pce, Port 5, Gamepad: DOWN ↓ +pce.input.port5.gamepad.down + +;pce, Port 5, Gamepad: I +pce.input.port5.gamepad.i + +;pce, Port 5, Gamepad: II +pce.input.port5.gamepad.ii + +;pce, Port 5, Gamepad: III +pce.input.port5.gamepad.iii + +;pce, Port 5, Gamepad: IV +pce.input.port5.gamepad.iv + +;pce, Port 5, Gamepad: LEFT ← +pce.input.port5.gamepad.left + +;pce, Port 5, Gamepad: Mode +pce.input.port5.gamepad.mode_select + +;Default position for switch "Mode". +pce.input.port5.gamepad.mode_select.defpos 2 + +;pce, Port 5, Gamepad: Rapid I +pce.input.port5.gamepad.rapid_i + +;pce, Port 5, Gamepad: Rapid II +pce.input.port5.gamepad.rapid_ii + +;pce, Port 5, Gamepad: RIGHT → +pce.input.port5.gamepad.right + +;pce, Port 5, Gamepad: RUN +pce.input.port5.gamepad.run + +;pce, Port 5, Gamepad: SELECT +pce.input.port5.gamepad.select + +;pce, Port 5, Gamepad: UP ↑ +pce.input.port5.gamepad.up + +;pce, Port 5, Gamepad: V +pce.input.port5.gamepad.v + +;pce, Port 5, Gamepad: VI +pce.input.port5.gamepad.vi + +;pce, Port 5, Mouse: Left Button +pce.input.port5.mouse.left mouse 0x0 button_left + +;pce, Port 5, Mouse: Motion Down +pce.input.port5.mouse.motion_down mouse 0x0 rel_y+ + +;pce, Port 5, Mouse: Motion Left +pce.input.port5.mouse.motion_left mouse 0x0 rel_x- + +;pce, Port 5, Mouse: Motion Right +pce.input.port5.mouse.motion_right mouse 0x0 rel_x+ + +;pce, Port 5, Mouse: Motion Up +pce.input.port5.mouse.motion_up mouse 0x0 rel_y- + +;pce, Port 5, Mouse: Right Button +pce.input.port5.mouse.right mouse 0x0 button_right + +;pce, Port 5, Mouse: RUN +pce.input.port5.mouse.run keyboard 0x0 40 + +;pce, Port 5, Mouse: SELECT +pce.input.port5.mouse.select keyboard 0x0 43 + +;Emulated mouse sensitivity. +pce.mouse_sensitivity 0.50 + +;Remove 16-sprites-per-scanline hardware limit. +pce.nospritelimit 0 + +;Select PSG revision. +pce.psgrevision match + +;Sound quality. +pce.resamp_quality 3 + +;Sound output rate tolerance. +pce.resamp_rate_error 0.0000009 + +;Enable scanlines with specified opacity. +pce.scanlines 0 + +;Enable specified OpenGL shader. +pce.shader ipsharper + +;Force interlaced video to be treated as progressive. +pce.shader.goat.fprog 0 + +;Constant RGB horizontal divergence. +pce.shader.goat.hdiv 0.50 + +;Mask pattern. +pce.shader.goat.pat goatron + +;Enable scanlines effect. +pce.shader.goat.slen 1 + +;Transparency of otherwise-opaque mask areas. +pce.shader.goat.tp 0.50 + +;Constant RGB vertical divergence. +pce.shader.goat.vdiv 0.50 + +;Last rendered scanline. +pce.slend 235 + +;First rendered scanline. +pce.slstart 4 + +;Enable specified special video scaler. +pce.special none + +;Stretch to fill screen. +pce.stretch full + +;Enable video temporal blur(50/50 previous/current frame by default). +pce.tblur 0 + +;Accumulate color data rather than discarding it. +pce.tblur.accum 0 + +;Blur amount in accumulation mode, specified in percentage of accumulation buffer to mix with the current frame. +pce.tblur.accum.amount 50 + +;Enable (bi)linear interpolation. +pce.videoip 0 + +;Size of emulated VRAM per VDC in 16-bit words. DO NOT CHANGE THIS UNLESS YOU KNOW WTF YOU ARE DOING. +pce.vramsize 32768 + +;Full-screen horizontal resolution. +pce.xres 0 + +;Scaling factor for the X axis in windowed mode. +pce.xscale 3.000000 + +;Scaling factor for the X axis in fullscreen mode. +pce.xscalefs 1.000000 + +;Full-screen vertical resolution. +pce.yres 0 + +;Scaling factor for the Y axis in windowed mode. +pce.yscale 3.000000 + +;Scaling factor for the Y axis in fullscreen mode. +pce.yscalefs 1.000000 + +;Enable dynamic ADPCM lowpass filter. +pce_fast.adpcmlp 0 + +;ADPCM volume. +pce_fast.adpcmvolume 100 + +;Enable Arcade Card emulation. +pce_fast.arcadecard 1 + +;Path to the CD BIOS +pce_fast.cdbios syscard3.pce + +;CD-DA volume. +pce_fast.cddavolume 100 + +;PSG volume when playing a CD game. +pce_fast.cdpsgvolume 100 + +;CD-ROM data transfer speed multiplier. +pce_fast.cdspeed 1 + +;Correct the aspect ratio. +pce_fast.correct_aspect 1 + +;If set, when RUN+SEL are pressed simultaneously, disable both buttons temporarily. +pce_fast.disable_softreset 0 + +;Enable (automatic) usage of this module. +pce_fast.enable 1 + +;Force monophonic sound output. +pce_fast.forcemono 0 + +;Force SuperGrafx emulation. +pce_fast.forcesgx 0 + +;Input device for Port 1 +pce_fast.input.port1 gamepad + +;pce_fast, Port 1, Gamepad: DOWN ↓ +pce_fast.input.port1.gamepad.down joystick @GUID1@ @DEVICE_BTN_DPAD_DOWN@ + +;pce_fast, Port 1, Gamepad: I +pce_fast.input.port1.gamepad.i joystick @GUID1@ @DEVICE_BTN_EAST@ + +;pce_fast, Port 1, Gamepad: II +pce_fast.input.port1.gamepad.ii joystick @GUID1@ @DEVICE_BTN_SOUTH@ + +;pce_fast, Port 1, Gamepad: III +pce_fast.input.port1.gamepad.iii joystick @GUID1@ @DEVICE_BTN_WEST@ + +;pce_fast, Port 1, Gamepad: IV +pce_fast.input.port1.gamepad.iv joystick @GUID1@ @DEVICE_BTN_NORTH@ + +;pce_fast, Port 1, Gamepad: LEFT ← +pce_fast.input.port1.gamepad.left joystick @GUID1@ @DEVICE_BTN_DPAD_LEFT@ + +;pce_fast, Port 1, Gamepad: Mode +pce_fast.input.port1.gamepad.mode_select keyboard 0x0 20 + +;Default position for switch "Mode". +pce_fast.input.port1.gamepad.mode_select.defpos 2 + +;pce_fast, Port 1, Gamepad: Rapid I +pce_fast.input.port1.gamepad.rapid_i keyboard 0x0 17 + +;pce_fast, Port 1, Gamepad: Rapid II +pce_fast.input.port1.gamepad.rapid_ii keyboard 0x0 17 + +;pce_fast, Port 1, Gamepad: RIGHT → +pce_fast.input.port1.gamepad.right joystick @GUID1@ @DEVICE_BTN_DPAD_RIGHT@ + +;pce_fast, Port 1, Gamepad: RUN +pce_fast.input.port1.gamepad.run joystick @GUID1@ @DEVICE_BTN_START@ + +;pce_fast, Port 1, Gamepad: SELECT +pce_fast.input.port1.gamepad.select joystick @GUID1@ @DEVICE_BTN_SELECT@ + +;pce_fast, Port 1, Gamepad: UP ↑ +pce_fast.input.port1.gamepad.up joystick @GUID1@ @DEVICE_BTN_DPAD_UP@ + +;pce_fast, Port 1, Gamepad: V +pce_fast.input.port1.gamepad.v joystick @GUID1@ @DEVICE_BTN_TL@ + +;pce_fast, Port 1, Gamepad: VI +pce_fast.input.port1.gamepad.vi joystick @GUID1@ @DEVICE_BTN_TR@ + +;pce_fast, Port 1, Mouse: Left Button +pce_fast.input.port1.mouse.left mouse 0x0 button_left + +;pce_fast, Port 1, Mouse: Motion Down +pce_fast.input.port1.mouse.motion_down mouse 0x0 rel_y+ + +;pce_fast, Port 1, Mouse: Motion Left +pce_fast.input.port1.mouse.motion_left mouse 0x0 rel_x- + +;pce_fast, Port 1, Mouse: Motion Right +pce_fast.input.port1.mouse.motion_right mouse 0x0 rel_x+ + +;pce_fast, Port 1, Mouse: Motion Up +pce_fast.input.port1.mouse.motion_up mouse 0x0 rel_y- + +;pce_fast, Port 1, Mouse: Right Button +pce_fast.input.port1.mouse.right mouse 0x0 button_right + +;pce_fast, Port 1, Mouse: RUN +pce_fast.input.port1.mouse.run keyboard 0x0 40 + +;pce_fast, Port 1, Mouse: SELECT +pce_fast.input.port1.mouse.select keyboard 0x0 43 + +;Input device for Port 2 +pce_fast.input.port2 gamepad + +;pce_fast, Port 2, Gamepad: DOWN ↓ +pce_fast.input.port2.gamepad.down + +;pce_fast, Port 2, Gamepad: I +pce_fast.input.port2.gamepad.i + +;pce_fast, Port 2, Gamepad: II +pce_fast.input.port2.gamepad.ii + +;pce_fast, Port 2, Gamepad: III +pce_fast.input.port2.gamepad.iii + +;pce_fast, Port 2, Gamepad: IV +pce_fast.input.port2.gamepad.iv + +;pce_fast, Port 2, Gamepad: LEFT ← +pce_fast.input.port2.gamepad.left + +;pce_fast, Port 2, Gamepad: Mode +pce_fast.input.port2.gamepad.mode_select + +;Default position for switch "Mode". +pce_fast.input.port2.gamepad.mode_select.defpos 2 + +;pce_fast, Port 2, Gamepad: Rapid I +pce_fast.input.port2.gamepad.rapid_i + +;pce_fast, Port 2, Gamepad: Rapid II +pce_fast.input.port2.gamepad.rapid_ii + +;pce_fast, Port 2, Gamepad: RIGHT → +pce_fast.input.port2.gamepad.right + +;pce_fast, Port 2, Gamepad: RUN +pce_fast.input.port2.gamepad.run + +;pce_fast, Port 2, Gamepad: SELECT +pce_fast.input.port2.gamepad.select + +;pce_fast, Port 2, Gamepad: UP ↑ +pce_fast.input.port2.gamepad.up + +;pce_fast, Port 2, Gamepad: V +pce_fast.input.port2.gamepad.v + +;pce_fast, Port 2, Gamepad: VI +pce_fast.input.port2.gamepad.vi + +;pce_fast, Port 2, Mouse: Left Button +pce_fast.input.port2.mouse.left mouse 0x0 button_left + +;pce_fast, Port 2, Mouse: Motion Down +pce_fast.input.port2.mouse.motion_down mouse 0x0 rel_y+ + +;pce_fast, Port 2, Mouse: Motion Left +pce_fast.input.port2.mouse.motion_left mouse 0x0 rel_x- + +;pce_fast, Port 2, Mouse: Motion Right +pce_fast.input.port2.mouse.motion_right mouse 0x0 rel_x+ + +;pce_fast, Port 2, Mouse: Motion Up +pce_fast.input.port2.mouse.motion_up mouse 0x0 rel_y- + +;pce_fast, Port 2, Mouse: Right Button +pce_fast.input.port2.mouse.right mouse 0x0 button_right + +;pce_fast, Port 2, Mouse: RUN +pce_fast.input.port2.mouse.run keyboard 0x0 40 + +;pce_fast, Port 2, Mouse: SELECT +pce_fast.input.port2.mouse.select keyboard 0x0 43 + +;Input device for Port 3 +pce_fast.input.port3 gamepad + +;pce_fast, Port 3, Gamepad: DOWN ↓ +pce_fast.input.port3.gamepad.down + +;pce_fast, Port 3, Gamepad: I +pce_fast.input.port3.gamepad.i + +;pce_fast, Port 3, Gamepad: II +pce_fast.input.port3.gamepad.ii + +;pce_fast, Port 3, Gamepad: III +pce_fast.input.port3.gamepad.iii + +;pce_fast, Port 3, Gamepad: IV +pce_fast.input.port3.gamepad.iv + +;pce_fast, Port 3, Gamepad: LEFT ← +pce_fast.input.port3.gamepad.left + +;pce_fast, Port 3, Gamepad: Mode +pce_fast.input.port3.gamepad.mode_select + +;Default position for switch "Mode". +pce_fast.input.port3.gamepad.mode_select.defpos 2 + +;pce_fast, Port 3, Gamepad: Rapid I +pce_fast.input.port3.gamepad.rapid_i + +;pce_fast, Port 3, Gamepad: Rapid II +pce_fast.input.port3.gamepad.rapid_ii + +;pce_fast, Port 3, Gamepad: RIGHT → +pce_fast.input.port3.gamepad.right + +;pce_fast, Port 3, Gamepad: RUN +pce_fast.input.port3.gamepad.run + +;pce_fast, Port 3, Gamepad: SELECT +pce_fast.input.port3.gamepad.select + +;pce_fast, Port 3, Gamepad: UP ↑ +pce_fast.input.port3.gamepad.up + +;pce_fast, Port 3, Gamepad: V +pce_fast.input.port3.gamepad.v + +;pce_fast, Port 3, Gamepad: VI +pce_fast.input.port3.gamepad.vi + +;pce_fast, Port 3, Mouse: Left Button +pce_fast.input.port3.mouse.left mouse 0x0 button_left + +;pce_fast, Port 3, Mouse: Motion Down +pce_fast.input.port3.mouse.motion_down mouse 0x0 rel_y+ + +;pce_fast, Port 3, Mouse: Motion Left +pce_fast.input.port3.mouse.motion_left mouse 0x0 rel_x- + +;pce_fast, Port 3, Mouse: Motion Right +pce_fast.input.port3.mouse.motion_right mouse 0x0 rel_x+ + +;pce_fast, Port 3, Mouse: Motion Up +pce_fast.input.port3.mouse.motion_up mouse 0x0 rel_y- + +;pce_fast, Port 3, Mouse: Right Button +pce_fast.input.port3.mouse.right mouse 0x0 button_right + +;pce_fast, Port 3, Mouse: RUN +pce_fast.input.port3.mouse.run keyboard 0x0 40 + +;pce_fast, Port 3, Mouse: SELECT +pce_fast.input.port3.mouse.select keyboard 0x0 43 + +;Input device for Port 4 +pce_fast.input.port4 gamepad + +;pce_fast, Port 4, Gamepad: DOWN ↓ +pce_fast.input.port4.gamepad.down + +;pce_fast, Port 4, Gamepad: I +pce_fast.input.port4.gamepad.i + +;pce_fast, Port 4, Gamepad: II +pce_fast.input.port4.gamepad.ii + +;pce_fast, Port 4, Gamepad: III +pce_fast.input.port4.gamepad.iii + +;pce_fast, Port 4, Gamepad: IV +pce_fast.input.port4.gamepad.iv + +;pce_fast, Port 4, Gamepad: LEFT ← +pce_fast.input.port4.gamepad.left + +;pce_fast, Port 4, Gamepad: Mode +pce_fast.input.port4.gamepad.mode_select + +;Default position for switch "Mode". +pce_fast.input.port4.gamepad.mode_select.defpos 2 + +;pce_fast, Port 4, Gamepad: Rapid I +pce_fast.input.port4.gamepad.rapid_i + +;pce_fast, Port 4, Gamepad: Rapid II +pce_fast.input.port4.gamepad.rapid_ii + +;pce_fast, Port 4, Gamepad: RIGHT → +pce_fast.input.port4.gamepad.right + +;pce_fast, Port 4, Gamepad: RUN +pce_fast.input.port4.gamepad.run + +;pce_fast, Port 4, Gamepad: SELECT +pce_fast.input.port4.gamepad.select + +;pce_fast, Port 4, Gamepad: UP ↑ +pce_fast.input.port4.gamepad.up + +;pce_fast, Port 4, Gamepad: V +pce_fast.input.port4.gamepad.v + +;pce_fast, Port 4, Gamepad: VI +pce_fast.input.port4.gamepad.vi + +;pce_fast, Port 4, Mouse: Left Button +pce_fast.input.port4.mouse.left mouse 0x0 button_left + +;pce_fast, Port 4, Mouse: Motion Down +pce_fast.input.port4.mouse.motion_down mouse 0x0 rel_y+ + +;pce_fast, Port 4, Mouse: Motion Left +pce_fast.input.port4.mouse.motion_left mouse 0x0 rel_x- + +;pce_fast, Port 4, Mouse: Motion Right +pce_fast.input.port4.mouse.motion_right mouse 0x0 rel_x+ + +;pce_fast, Port 4, Mouse: Motion Up +pce_fast.input.port4.mouse.motion_up mouse 0x0 rel_y- + +;pce_fast, Port 4, Mouse: Right Button +pce_fast.input.port4.mouse.right mouse 0x0 button_right + +;pce_fast, Port 4, Mouse: RUN +pce_fast.input.port4.mouse.run keyboard 0x0 40 + +;pce_fast, Port 4, Mouse: SELECT +pce_fast.input.port4.mouse.select keyboard 0x0 43 + +;Input device for Port 5 +pce_fast.input.port5 gamepad + +;pce_fast, Port 5, Gamepad: DOWN ↓ +pce_fast.input.port5.gamepad.down + +;pce_fast, Port 5, Gamepad: I +pce_fast.input.port5.gamepad.i + +;pce_fast, Port 5, Gamepad: II +pce_fast.input.port5.gamepad.ii + +;pce_fast, Port 5, Gamepad: III +pce_fast.input.port5.gamepad.iii + +;pce_fast, Port 5, Gamepad: IV +pce_fast.input.port5.gamepad.iv + +;pce_fast, Port 5, Gamepad: LEFT ← +pce_fast.input.port5.gamepad.left + +;pce_fast, Port 5, Gamepad: Mode +pce_fast.input.port5.gamepad.mode_select + +;Default position for switch "Mode". +pce_fast.input.port5.gamepad.mode_select.defpos 2 + +;pce_fast, Port 5, Gamepad: Rapid I +pce_fast.input.port5.gamepad.rapid_i + +;pce_fast, Port 5, Gamepad: Rapid II +pce_fast.input.port5.gamepad.rapid_ii + +;pce_fast, Port 5, Gamepad: RIGHT → +pce_fast.input.port5.gamepad.right + +;pce_fast, Port 5, Gamepad: RUN +pce_fast.input.port5.gamepad.run + +;pce_fast, Port 5, Gamepad: SELECT +pce_fast.input.port5.gamepad.select + +;pce_fast, Port 5, Gamepad: UP ↑ +pce_fast.input.port5.gamepad.up + +;pce_fast, Port 5, Gamepad: V +pce_fast.input.port5.gamepad.v + +;pce_fast, Port 5, Gamepad: VI +pce_fast.input.port5.gamepad.vi + +;pce_fast, Port 5, Mouse: Left Button +pce_fast.input.port5.mouse.left mouse 0x0 button_left + +;pce_fast, Port 5, Mouse: Motion Down +pce_fast.input.port5.mouse.motion_down mouse 0x0 rel_y+ + +;pce_fast, Port 5, Mouse: Motion Left +pce_fast.input.port5.mouse.motion_left mouse 0x0 rel_x- + +;pce_fast, Port 5, Mouse: Motion Right +pce_fast.input.port5.mouse.motion_right mouse 0x0 rel_x+ + +;pce_fast, Port 5, Mouse: Motion Up +pce_fast.input.port5.mouse.motion_up mouse 0x0 rel_y- + +;pce_fast, Port 5, Mouse: Right Button +pce_fast.input.port5.mouse.right mouse 0x0 button_right + +;pce_fast, Port 5, Mouse: RUN +pce_fast.input.port5.mouse.run keyboard 0x0 40 + +;pce_fast, Port 5, Mouse: SELECT +pce_fast.input.port5.mouse.select keyboard 0x0 43 + +;Mouse sensitivity. +pce_fast.mouse_sensitivity 0.50 + +;Remove 16-sprites-per-scanline hardware limit. +pce_fast.nospritelimit 1 + +;CPU overclock multiplier. +pce_fast.ocmultiplier 2 + +;Enable scanlines with specified opacity. +pce_fast.scanlines 0 + +;Enable specified OpenGL shader. +pce_fast.shader none + +;Force interlaced video to be treated as progressive. +pce_fast.shader.goat.fprog 0 + +;Constant RGB horizontal divergence. +pce_fast.shader.goat.hdiv 0.50 + +;Mask pattern. +pce_fast.shader.goat.pat goatron + +;Enable scanlines effect. +pce_fast.shader.goat.slen 1 + +;Transparency of otherwise-opaque mask areas. +pce_fast.shader.goat.tp 0.50 + +;Constant RGB vertical divergence. +pce_fast.shader.goat.vdiv 0.50 + +;Last rendered scanline. +pce_fast.slend 235 + +;First rendered scanline. +pce_fast.slstart 4 + +;Enable specified special video scaler. +pce_fast.special none + +;Stretch to fill screen. +pce_fast.stretch full + +;Enable video temporal blur(50/50 previous/current frame by default). +pce_fast.tblur 0 + +;Accumulate color data rather than discarding it. +pce_fast.tblur.accum 0 + +;Blur amount in accumulation mode, specified in percentage of accumulation buffer to mix with the current frame. +pce_fast.tblur.accum.amount 50 + +;Enable (bi)linear interpolation. +pce_fast.videoip 0 + +;Full-screen horizontal resolution. +pce_fast.xres 0 + +;Scaling factor for the X axis in windowed mode. +pce_fast.xscale 3.000000 + +;Scaling factor for the X axis in fullscreen mode. +pce_fast.xscalefs 1.000000 + +;Full-screen vertical resolution. +pce_fast.yres 0 + +;Scaling factor for the Y axis in windowed mode. +pce_fast.yscale 3.000000 + +;Scaling factor for the Y axis in fullscreen mode. +pce_fast.yscalefs 1.000000 + +;Hack that emulates the codec a buggy ADPCM encoder used for some games' ADPCM. +pcfx.adpcm.emulate_buggy_codec 0 + +;Hack to suppress clicks caused by forced channel resets. +pcfx.adpcm.suppress_channel_reset_clicks 1 + +;Path to the ROM BIOS +pcfx.bios pcfx.rom + +;Emulated CD-ROM speed. +pcfx.cdspeed 2 + +;CPU emulation mode. +pcfx.cpu_emulation auto + +;Disassembly font size. +pcfx.debugger.disfontsize 5x7 + +;Character encoding for the debugger's memory editor. +pcfx.debugger.memcharenc shift_jis + +;Disable internal and external BRAM. +pcfx.disable_bram 0 + +;When RUN+SEL are pressed simultaneously, disable both buttons temporarily. +pcfx.disable_softreset 0 + +;Enable (automatic) usage of this module. +pcfx.enable 1 + +;Force monophonic sound output. +pcfx.forcemono 0 + +;Path to the FX-SCSI ROM +pcfx.fxscsi 0 + +;Emulated width for 7.16MHz dot-clock mode. +pcfx.high_dotclock_width 1024 + +;Input device for Port 1 +pcfx.input.port1 gamepad + +;pcfx, Port 1, Gamepad: DOWN ↓ +pcfx.input.port1.gamepad.down joystick @GUID1@ @DEVICE_BTN_DPAD_DOWN@ + +;pcfx, Port 1, Gamepad: I +pcfx.input.port1.gamepad.i joystick @GUID1@ @DEVICE_BTN_EAST@ + +;pcfx, Port 1, Gamepad: II +pcfx.input.port1.gamepad.ii joystick @GUID1@ @DEVICE_BTN_SOUTH@ + +;pcfx, Port 1, Gamepad: III +pcfx.input.port1.gamepad.iii joystick @GUID1@ @DEVICE_BTN_NORTH@ + +;pcfx, Port 1, Gamepad: IV +pcfx.input.port1.gamepad.iv joystick @GUID1@ @DEVICE_BTN_WEST@ + +;pcfx, Port 1, Gamepad: LEFT ← +pcfx.input.port1.gamepad.left joystick @GUID1@ @DEVICE_BTN_DPAD_LEFT@ + +;pcfx, Port 1, Gamepad: MODE 1 +pcfx.input.port1.gamepad.mode1 joystick @GUID1@ @DEVICE_BTN_TL2@ + +;Default position for switch "MODE 1". +pcfx.input.port1.gamepad.mode1.defpos a + +;pcfx, Port 1, Gamepad: MODE 2 +pcfx.input.port1.gamepad.mode2 joystick @GUID1@ @DEVICE_BTN_TR2@ + +;Default position for switch "MODE 2". +pcfx.input.port1.gamepad.mode2.defpos a + +;pcfx, Port 1, Gamepad: RIGHT → +pcfx.input.port1.gamepad.right joystick @GUID1@ @DEVICE_BTN_DPAD_RIGHT@ + +;pcfx, Port 1, Gamepad: RUN +pcfx.input.port1.gamepad.run joystick @GUID1@ @DEVICE_BTN_START@ + +;pcfx, Port 1, Gamepad: SELECT +pcfx.input.port1.gamepad.select joystick @GUID1@ @DEVICE_BTN_SELECT@ + +;pcfx, Port 1, Gamepad: UP ↑ +pcfx.input.port1.gamepad.up joystick @GUID1@ @DEVICE_BTN_DPAD_UP@ + +;pcfx, Port 1, Gamepad: V +pcfx.input.port1.gamepad.v joystick @GUID1@ @DEVICE_BTN_TL@ + +;pcfx, Port 1, Gamepad: VI +pcfx.input.port1.gamepad.vi joystick @GUID1@ @DEVICE_BTN_TR@ + +;pcfx, Port 1, Mouse: Left Button +pcfx.input.port1.mouse.left mouse 0x0 button_left + +;pcfx, Port 1, Mouse: Motion Down +pcfx.input.port1.mouse.motion_down mouse 0x0 rel_y+ + +;pcfx, Port 1, Mouse: Motion Left +pcfx.input.port1.mouse.motion_left mouse 0x0 rel_x- + +;pcfx, Port 1, Mouse: Motion Right +pcfx.input.port1.mouse.motion_right mouse 0x0 rel_x+ + +;pcfx, Port 1, Mouse: Motion Up +pcfx.input.port1.mouse.motion_up mouse 0x0 rel_y- + +;pcfx, Port 1, Mouse: Right Button +pcfx.input.port1.mouse.right mouse 0x0 button_right + +;Enable multitap on PC-FX port 1. +pcfx.input.port1.multitap 0 + +;Input device for Port 2 +pcfx.input.port2 gamepad + +;pcfx, Port 2, Gamepad: DOWN ↓ +pcfx.input.port2.gamepad.down + +;pcfx, Port 2, Gamepad: I +pcfx.input.port2.gamepad.i + +;pcfx, Port 2, Gamepad: II +pcfx.input.port2.gamepad.ii + +;pcfx, Port 2, Gamepad: III +pcfx.input.port2.gamepad.iii + +;pcfx, Port 2, Gamepad: IV +pcfx.input.port2.gamepad.iv + +;pcfx, Port 2, Gamepad: LEFT ← +pcfx.input.port2.gamepad.left + +;pcfx, Port 2, Gamepad: MODE 1 +pcfx.input.port2.gamepad.mode1 + +;Default position for switch "MODE 1". +pcfx.input.port2.gamepad.mode1.defpos a + +;pcfx, Port 2, Gamepad: MODE 2 +pcfx.input.port2.gamepad.mode2 + +;Default position for switch "MODE 2". +pcfx.input.port2.gamepad.mode2.defpos a + +;pcfx, Port 2, Gamepad: RIGHT → +pcfx.input.port2.gamepad.right + +;pcfx, Port 2, Gamepad: RUN +pcfx.input.port2.gamepad.run + +;pcfx, Port 2, Gamepad: SELECT +pcfx.input.port2.gamepad.select + +;pcfx, Port 2, Gamepad: UP ↑ +pcfx.input.port2.gamepad.up + +;pcfx, Port 2, Gamepad: V +pcfx.input.port2.gamepad.v + +;pcfx, Port 2, Gamepad: VI +pcfx.input.port2.gamepad.vi + +;pcfx, Port 2, Mouse: Left Button +pcfx.input.port2.mouse.left mouse 0x0 button_left + +;pcfx, Port 2, Mouse: Motion Down +pcfx.input.port2.mouse.motion_down mouse 0x0 rel_y+ + +;pcfx, Port 2, Mouse: Motion Left +pcfx.input.port2.mouse.motion_left mouse 0x0 rel_x- + +;pcfx, Port 2, Mouse: Motion Right +pcfx.input.port2.mouse.motion_right mouse 0x0 rel_x+ + +;pcfx, Port 2, Mouse: Motion Up +pcfx.input.port2.mouse.motion_up mouse 0x0 rel_y- + +;pcfx, Port 2, Mouse: Right Button +pcfx.input.port2.mouse.right mouse 0x0 button_right + +;Enable multitap on PC-FX port 2. +pcfx.input.port2.multitap 0 + +;Input device for Port 3 +pcfx.input.port3 gamepad + +;pcfx, Port 3, Gamepad: DOWN ↓ +pcfx.input.port3.gamepad.down + +;pcfx, Port 3, Gamepad: I +pcfx.input.port3.gamepad.i + +;pcfx, Port 3, Gamepad: II +pcfx.input.port3.gamepad.ii + +;pcfx, Port 3, Gamepad: III +pcfx.input.port3.gamepad.iii + +;pcfx, Port 3, Gamepad: IV +pcfx.input.port3.gamepad.iv + +;pcfx, Port 3, Gamepad: LEFT ← +pcfx.input.port3.gamepad.left + +;pcfx, Port 3, Gamepad: MODE 1 +pcfx.input.port3.gamepad.mode1 + +;Default position for switch "MODE 1". +pcfx.input.port3.gamepad.mode1.defpos a + +;pcfx, Port 3, Gamepad: MODE 2 +pcfx.input.port3.gamepad.mode2 + +;Default position for switch "MODE 2". +pcfx.input.port3.gamepad.mode2.defpos a + +;pcfx, Port 3, Gamepad: RIGHT → +pcfx.input.port3.gamepad.right + +;pcfx, Port 3, Gamepad: RUN +pcfx.input.port3.gamepad.run + +;pcfx, Port 3, Gamepad: SELECT +pcfx.input.port3.gamepad.select + +;pcfx, Port 3, Gamepad: UP ↑ +pcfx.input.port3.gamepad.up + +;pcfx, Port 3, Gamepad: V +pcfx.input.port3.gamepad.v + +;pcfx, Port 3, Gamepad: VI +pcfx.input.port3.gamepad.vi + +;pcfx, Port 3, Mouse: Left Button +pcfx.input.port3.mouse.left mouse 0x0 button_left + +;pcfx, Port 3, Mouse: Motion Down +pcfx.input.port3.mouse.motion_down mouse 0x0 rel_y+ + +;pcfx, Port 3, Mouse: Motion Left +pcfx.input.port3.mouse.motion_left mouse 0x0 rel_x- + +;pcfx, Port 3, Mouse: Motion Right +pcfx.input.port3.mouse.motion_right mouse 0x0 rel_x+ + +;pcfx, Port 3, Mouse: Motion Up +pcfx.input.port3.mouse.motion_up mouse 0x0 rel_y- + +;pcfx, Port 3, Mouse: Right Button +pcfx.input.port3.mouse.right mouse 0x0 button_right + +;Input device for Port 4 +pcfx.input.port4 gamepad + +;pcfx, Port 4, Gamepad: DOWN ↓ +pcfx.input.port4.gamepad.down + +;pcfx, Port 4, Gamepad: I +pcfx.input.port4.gamepad.i + +;pcfx, Port 4, Gamepad: II +pcfx.input.port4.gamepad.ii + +;pcfx, Port 4, Gamepad: III +pcfx.input.port4.gamepad.iii + +;pcfx, Port 4, Gamepad: IV +pcfx.input.port4.gamepad.iv + +;pcfx, Port 4, Gamepad: LEFT ← +pcfx.input.port4.gamepad.left + +;pcfx, Port 4, Gamepad: MODE 1 +pcfx.input.port4.gamepad.mode1 + +;Default position for switch "MODE 1". +pcfx.input.port4.gamepad.mode1.defpos a + +;pcfx, Port 4, Gamepad: MODE 2 +pcfx.input.port4.gamepad.mode2 + +;Default position for switch "MODE 2". +pcfx.input.port4.gamepad.mode2.defpos a + +;pcfx, Port 4, Gamepad: RIGHT → +pcfx.input.port4.gamepad.right + +;pcfx, Port 4, Gamepad: RUN +pcfx.input.port4.gamepad.run + +;pcfx, Port 4, Gamepad: SELECT +pcfx.input.port4.gamepad.select + +;pcfx, Port 4, Gamepad: UP ↑ +pcfx.input.port4.gamepad.up + +;pcfx, Port 4, Gamepad: V +pcfx.input.port4.gamepad.v + +;pcfx, Port 4, Gamepad: VI +pcfx.input.port4.gamepad.vi + +;pcfx, Port 4, Mouse: Left Button +pcfx.input.port4.mouse.left mouse 0x0 button_left + +;pcfx, Port 4, Mouse: Motion Down +pcfx.input.port4.mouse.motion_down mouse 0x0 rel_y+ + +;pcfx, Port 4, Mouse: Motion Left +pcfx.input.port4.mouse.motion_left mouse 0x0 rel_x- + +;pcfx, Port 4, Mouse: Motion Right +pcfx.input.port4.mouse.motion_right mouse 0x0 rel_x+ + +;pcfx, Port 4, Mouse: Motion Up +pcfx.input.port4.mouse.motion_up mouse 0x0 rel_y- + +;pcfx, Port 4, Mouse: Right Button +pcfx.input.port4.mouse.right mouse 0x0 button_right + +;Input device for Port 5 +pcfx.input.port5 gamepad + +;pcfx, Port 5, Gamepad: DOWN ↓ +pcfx.input.port5.gamepad.down + +;pcfx, Port 5, Gamepad: I +pcfx.input.port5.gamepad.i + +;pcfx, Port 5, Gamepad: II +pcfx.input.port5.gamepad.ii + +;pcfx, Port 5, Gamepad: III +pcfx.input.port5.gamepad.iii + +;pcfx, Port 5, Gamepad: IV +pcfx.input.port5.gamepad.iv + +;pcfx, Port 5, Gamepad: LEFT ← +pcfx.input.port5.gamepad.left + +;pcfx, Port 5, Gamepad: MODE 1 +pcfx.input.port5.gamepad.mode1 + +;Default position for switch "MODE 1". +pcfx.input.port5.gamepad.mode1.defpos a + +;pcfx, Port 5, Gamepad: MODE 2 +pcfx.input.port5.gamepad.mode2 + +;Default position for switch "MODE 2". +pcfx.input.port5.gamepad.mode2.defpos a + +;pcfx, Port 5, Gamepad: RIGHT → +pcfx.input.port5.gamepad.right + +;pcfx, Port 5, Gamepad: RUN +pcfx.input.port5.gamepad.run + +;pcfx, Port 5, Gamepad: SELECT +pcfx.input.port5.gamepad.select + +;pcfx, Port 5, Gamepad: UP ↑ +pcfx.input.port5.gamepad.up + +;pcfx, Port 5, Gamepad: V +pcfx.input.port5.gamepad.v + +;pcfx, Port 5, Gamepad: VI +pcfx.input.port5.gamepad.vi + +;pcfx, Port 5, Mouse: Left Button +pcfx.input.port5.mouse.left mouse 0x0 button_left + +;pcfx, Port 5, Mouse: Motion Down +pcfx.input.port5.mouse.motion_down mouse 0x0 rel_y+ + +;pcfx, Port 5, Mouse: Motion Left +pcfx.input.port5.mouse.motion_left mouse 0x0 rel_x- + +;pcfx, Port 5, Mouse: Motion Right +pcfx.input.port5.mouse.motion_right mouse 0x0 rel_x+ + +;pcfx, Port 5, Mouse: Motion Up +pcfx.input.port5.mouse.motion_up mouse 0x0 rel_y- + +;pcfx, Port 5, Mouse: Right Button +pcfx.input.port5.mouse.right mouse 0x0 button_right + +;Input device for Port 6 +pcfx.input.port6 gamepad + +;pcfx, Port 6, Gamepad: DOWN ↓ +pcfx.input.port6.gamepad.down + +;pcfx, Port 6, Gamepad: I +pcfx.input.port6.gamepad.i + +;pcfx, Port 6, Gamepad: II +pcfx.input.port6.gamepad.ii + +;pcfx, Port 6, Gamepad: III +pcfx.input.port6.gamepad.iii + +;pcfx, Port 6, Gamepad: IV +pcfx.input.port6.gamepad.iv + +;pcfx, Port 6, Gamepad: LEFT ← +pcfx.input.port6.gamepad.left + +;pcfx, Port 6, Gamepad: MODE 1 +pcfx.input.port6.gamepad.mode1 + +;Default position for switch "MODE 1". +pcfx.input.port6.gamepad.mode1.defpos a + +;pcfx, Port 6, Gamepad: MODE 2 +pcfx.input.port6.gamepad.mode2 + +;Default position for switch "MODE 2". +pcfx.input.port6.gamepad.mode2.defpos a + +;pcfx, Port 6, Gamepad: RIGHT → +pcfx.input.port6.gamepad.right + +;pcfx, Port 6, Gamepad: RUN +pcfx.input.port6.gamepad.run + +;pcfx, Port 6, Gamepad: SELECT +pcfx.input.port6.gamepad.select + +;pcfx, Port 6, Gamepad: UP ↑ +pcfx.input.port6.gamepad.up + +;pcfx, Port 6, Gamepad: V +pcfx.input.port6.gamepad.v + +;pcfx, Port 6, Gamepad: VI +pcfx.input.port6.gamepad.vi + +;pcfx, Port 6, Mouse: Left Button +pcfx.input.port6.mouse.left mouse 0x0 button_left + +;pcfx, Port 6, Mouse: Motion Down +pcfx.input.port6.mouse.motion_down mouse 0x0 rel_y+ + +;pcfx, Port 6, Mouse: Motion Left +pcfx.input.port6.mouse.motion_left mouse 0x0 rel_x- + +;pcfx, Port 6, Mouse: Motion Right +pcfx.input.port6.mouse.motion_right mouse 0x0 rel_x+ + +;pcfx, Port 6, Mouse: Motion Up +pcfx.input.port6.mouse.motion_up mouse 0x0 rel_y- + +;pcfx, Port 6, Mouse: Right Button +pcfx.input.port6.mouse.right mouse 0x0 button_right + +;Input device for Port 7 +pcfx.input.port7 gamepad + +;pcfx, Port 7, Gamepad: DOWN ↓ +pcfx.input.port7.gamepad.down + +;pcfx, Port 7, Gamepad: I +pcfx.input.port7.gamepad.i + +;pcfx, Port 7, Gamepad: II +pcfx.input.port7.gamepad.ii + +;pcfx, Port 7, Gamepad: III +pcfx.input.port7.gamepad.iii + +;pcfx, Port 7, Gamepad: IV +pcfx.input.port7.gamepad.iv + +;pcfx, Port 7, Gamepad: LEFT ← +pcfx.input.port7.gamepad.left + +;pcfx, Port 7, Gamepad: MODE 1 +pcfx.input.port7.gamepad.mode1 + +;Default position for switch "MODE 1". +pcfx.input.port7.gamepad.mode1.defpos a + +;pcfx, Port 7, Gamepad: MODE 2 +pcfx.input.port7.gamepad.mode2 + +;Default position for switch "MODE 2". +pcfx.input.port7.gamepad.mode2.defpos a + +;pcfx, Port 7, Gamepad: RIGHT → +pcfx.input.port7.gamepad.right + +;pcfx, Port 7, Gamepad: RUN +pcfx.input.port7.gamepad.run + +;pcfx, Port 7, Gamepad: SELECT +pcfx.input.port7.gamepad.select + +;pcfx, Port 7, Gamepad: UP ↑ +pcfx.input.port7.gamepad.up + +;pcfx, Port 7, Gamepad: V +pcfx.input.port7.gamepad.v + +;pcfx, Port 7, Gamepad: VI +pcfx.input.port7.gamepad.vi + +;pcfx, Port 7, Mouse: Left Button +pcfx.input.port7.mouse.left mouse 0x0 button_left + +;pcfx, Port 7, Mouse: Motion Down +pcfx.input.port7.mouse.motion_down mouse 0x0 rel_y+ + +;pcfx, Port 7, Mouse: Motion Left +pcfx.input.port7.mouse.motion_left mouse 0x0 rel_x- + +;pcfx, Port 7, Mouse: Motion Right +pcfx.input.port7.mouse.motion_right mouse 0x0 rel_x+ + +;pcfx, Port 7, Mouse: Motion Up +pcfx.input.port7.mouse.motion_up mouse 0x0 rel_y- + +;pcfx, Port 7, Mouse: Right Button +pcfx.input.port7.mouse.right mouse 0x0 button_right + +;Input device for Port 8 +pcfx.input.port8 gamepad + +;pcfx, Port 8, Gamepad: DOWN ↓ +pcfx.input.port8.gamepad.down + +;pcfx, Port 8, Gamepad: I +pcfx.input.port8.gamepad.i + +;pcfx, Port 8, Gamepad: II +pcfx.input.port8.gamepad.ii + +;pcfx, Port 8, Gamepad: III +pcfx.input.port8.gamepad.iii + +;pcfx, Port 8, Gamepad: IV +pcfx.input.port8.gamepad.iv + +;pcfx, Port 8, Gamepad: LEFT ← +pcfx.input.port8.gamepad.left + +;pcfx, Port 8, Gamepad: MODE 1 +pcfx.input.port8.gamepad.mode1 + +;Default position for switch "MODE 1". +pcfx.input.port8.gamepad.mode1.defpos a + +;pcfx, Port 8, Gamepad: MODE 2 +pcfx.input.port8.gamepad.mode2 + +;Default position for switch "MODE 2". +pcfx.input.port8.gamepad.mode2.defpos a + +;pcfx, Port 8, Gamepad: RIGHT → +pcfx.input.port8.gamepad.right + +;pcfx, Port 8, Gamepad: RUN +pcfx.input.port8.gamepad.run + +;pcfx, Port 8, Gamepad: SELECT +pcfx.input.port8.gamepad.select + +;pcfx, Port 8, Gamepad: UP ↑ +pcfx.input.port8.gamepad.up + +;pcfx, Port 8, Gamepad: V +pcfx.input.port8.gamepad.v + +;pcfx, Port 8, Gamepad: VI +pcfx.input.port8.gamepad.vi + +;pcfx, Port 8, Mouse: Left Button +pcfx.input.port8.mouse.left mouse 0x0 button_left + +;pcfx, Port 8, Mouse: Motion Down +pcfx.input.port8.mouse.motion_down mouse 0x0 rel_y+ + +;pcfx, Port 8, Mouse: Motion Left +pcfx.input.port8.mouse.motion_left mouse 0x0 rel_x- + +;pcfx, Port 8, Mouse: Motion Right +pcfx.input.port8.mouse.motion_right mouse 0x0 rel_x+ + +;pcfx, Port 8, Mouse: Motion Up +pcfx.input.port8.mouse.motion_up mouse 0x0 rel_y- + +;pcfx, Port 8, Mouse: Right Button +pcfx.input.port8.mouse.right mouse 0x0 button_right + +;Mouse sensitivity. +pcfx.mouse_sensitivity 1.25 + +;Remove 16-sprites-per-scanline hardware limit. +pcfx.nospritelimit 0 + +;Enable bilinear interpolation on the chroma channel of RAINBOW YUV output. +pcfx.rainbow.chromaip 0 + +;Sound quality. +pcfx.resamp_quality 3 + +;Output rate tolerance. +pcfx.resamp_rate_error 0.0000009 + +;Enable scanlines with specified opacity. +pcfx.scanlines 0 + +;Enable specified OpenGL shader. +pcfx.shader ipsharper + +;Force interlaced video to be treated as progressive. +pcfx.shader.goat.fprog 0 + +;Constant RGB horizontal divergence. +pcfx.shader.goat.hdiv 0.50 + +;Mask pattern. +pcfx.shader.goat.pat goatron + +;Enable scanlines effect. +pcfx.shader.goat.slen 1 + +;Transparency of otherwise-opaque mask areas. +pcfx.shader.goat.tp 0.50 + +;Constant RGB vertical divergence. +pcfx.shader.goat.vdiv 0.50 + +;Last rendered scanline. +pcfx.slend 235 + +;First rendered scanline. +pcfx.slstart 4 + +;Enable specified special video scaler. +pcfx.special none + +;Stretch to fill screen. +pcfx.stretch full + +;Enable video temporal blur(50/50 previous/current frame by default). +pcfx.tblur 0 + +;Accumulate color data rather than discarding it. +pcfx.tblur.accum 0 + +;Blur amount in accumulation mode, specified in percentage of accumulation buffer to mix with the current frame. +pcfx.tblur.accum.amount 50 + +;Enable (bi)linear interpolation. +pcfx.videoip 0 + +;Full-screen horizontal resolution. +pcfx.xres 0 + +;Scaling factor for the X axis in windowed mode. +pcfx.xscale 3.000000 + +;Scaling factor for the X axis in fullscreen mode. +pcfx.xscalefs 1.000000 + +;Full-screen vertical resolution. +pcfx.yres 0 + +;Scaling factor for the Y axis in windowed mode. +pcfx.yscale 3.000000 + +;Scaling factor for the Y axis in fullscreen mode. +pcfx.yscalefs 1.000000 + +;Enable scanlines with specified opacity. +player.scanlines 0 + +;Enable specified OpenGL shader. +player.shader none + +;Force interlaced video to be treated as progressive. +player.shader.goat.fprog 0 + +;Constant RGB horizontal divergence. +player.shader.goat.hdiv 0.50 + +;Mask pattern. +player.shader.goat.pat goatron + +;Enable scanlines effect. +player.shader.goat.slen 1 + +;Transparency of otherwise-opaque mask areas. +player.shader.goat.tp 0.50 + +;Constant RGB vertical divergence. +player.shader.goat.vdiv 0.50 + +;Enable specified special video scaler. +player.special none + +;Stretch to fill screen. +player.stretch aspect + +;Enable (bi)linear interpolation. +player.videoip 0 + +;Full-screen horizontal resolution. +player.xres 0 + +;Scaling factor for the X axis in windowed mode. +player.xscale 2.000000 + +;Scaling factor for the X axis in fullscreen mode. +player.xscalefs 1.000000 + +;Full-screen vertical resolution. +player.yres 0 + +;Scaling factor for the Y axis in windowed mode. +player.yscale 2.000000 + +;Scaling factor for the Y axis in fullscreen mode. +player.yscalefs 1.000000 + +;Double the raw image's height if it's below this threshold. +qtrecord.h_double_threshold 256 + +;Video codec to use. +qtrecord.vcodec cscd + +;Double the raw image's width if it's below this threshold. +qtrecord.w_double_threshold 384 + +;SLOW-forwarding speed multiplier. +sfspeed 0.75 + +;Treat the SLOW-forward button as a toggle. +sftoggle 0 + +;Enable (automatic) usage of this module. +sms.enable 1 + +;Enable FM sound emulation when playing domestic/Japan-region games. +sms.fm 1 + +;Force monophonic sound output. +sms.forcemono 0 + +;sms, Port 1, Gamepad: DOWN ↓ +sms.input.port1.gamepad.down joystick @GUID1@ @DEVICE_BTN_DPAD_DOWN@ + +;sms, Port 1, Gamepad: Fire 1/Start +sms.input.port1.gamepad.fire1 joystick @GUID1@ @DEVICE_BTN_SOUTH@ + +;sms, Port 1, Gamepad: Fire 2 +sms.input.port1.gamepad.fire2 joystick @GUID1@ @DEVICE_BTN_EAST@ + +;sms, Port 1, Gamepad: LEFT ← +sms.input.port1.gamepad.left joystick @GUID1@ @DEVICE_BTN_DPAD_LEFT@ + +;sms, Port 1, Gamepad: Pause +sms.input.port1.gamepad.pause joystick @GUID1@ @DEVICE_BTN_START@ + +;sms, Port 1, Gamepad: Rapid Fire 1/Start +sms.input.port1.gamepad.rapid_fire1 joystick @GUID1@ @DEVICE_BTN_WEST@ + +;sms, Port 1, Gamepad: Rapid Fire 2 +sms.input.port1.gamepad.rapid_fire2 joystick @GUID1@ @DEVICE_BTN_NORTH@ + +;sms, Port 1, Gamepad: RIGHT → +sms.input.port1.gamepad.right joystick @GUID1@ @DEVICE_BTN_DPAD_RIGHT@ + +;sms, Port 1, Gamepad: UP ↑ +sms.input.port1.gamepad.up joystick @GUID1@ @DEVICE_BTN_DPAD_UP@ + +;sms, Port 2, Gamepad: DOWN ↓ +sms.input.port2.gamepad.down + +;sms, Port 2, Gamepad: Fire 1/Start +sms.input.port2.gamepad.fire1 + +;sms, Port 2, Gamepad: Fire 2 +sms.input.port2.gamepad.fire2 + +;sms, Port 2, Gamepad: LEFT ← +sms.input.port2.gamepad.left + +;sms, Port 2, Gamepad: Pause +sms.input.port2.gamepad.pause + +;sms, Port 2, Gamepad: Rapid Fire 1/Start +sms.input.port2.gamepad.rapid_fire1 + +;sms, Port 2, Gamepad: Rapid Fire 2 +sms.input.port2.gamepad.rapid_fire2 + +;sms, Port 2, Gamepad: RIGHT → +sms.input.port2.gamepad.right + +;sms, Port 2, Gamepad: UP ↑ +sms.input.port2.gamepad.up + +;Enable scanlines with specified opacity. +sms.scanlines 0 + +;Enable specified OpenGL shader. +sms.shader ipsharper + +;Force interlaced video to be treated as progressive. +sms.shader.goat.fprog 0 + +;Constant RGB horizontal divergence. +sms.shader.goat.hdiv 0.50 + +;Mask pattern. +sms.shader.goat.pat goatron + +;Enable scanlines effect. +sms.shader.goat.slen 1 + +;Transparency of otherwise-opaque mask areas. +sms.shader.goat.tp 0.50 + +;Constant RGB vertical divergence. +sms.shader.goat.vdiv 0.50 + +;Last displayed scanline in NTSC mode. +sms.slend 215 + +;Last displayed scanline in PAL mode. +sms.slendp 231 + +;First displayed scanline in NTSC mode. +sms.slstart 24 + +;First displayed scanline in PAL mode. +sms.slstartp 8 + +;Enable specified special video scaler. +sms.special none + +;Stretch to fill screen. +sms.stretch aspect + +;Enable video temporal blur(50/50 previous/current frame by default). +sms.tblur 0 + +;Accumulate color data rather than discarding it. +sms.tblur.accum 0 + +;Blur amount in accumulation mode, specified in percentage of accumulation buffer to mix with the current frame. +sms.tblur.accum.amount 50 + +;System territory/region. +sms.territory export + +;Enable (bi)linear interpolation. +sms.videoip 0 + +;Full-screen horizontal resolution. +sms.xres 0 + +;Scaling factor for the X axis in windowed mode. +sms.xscale 4.000000 + +;Scaling factor for the X axis in fullscreen mode. +sms.xscalefs 1.000000 + +;Full-screen vertical resolution. +sms.yres 0 + +;Scaling factor for the Y axis in windowed mode. +sms.yscale 4.000000 + +;Scaling factor for the Y axis in fullscreen mode. +sms.yscalefs 1.000000 + +;APU output resampler quality. +snes.apu.resamp_quality 5 + +;Correct the aspect ratio. +snes.correct_aspect 0 + +;Enable (automatic) usage of this module. +snes.enable 1 + +;Force monophonic sound output. +snes.forcemono 0 + +;Enable horizontal blend(blur) filter. +snes.h_blend 0 + +;Input device for Port 1/1A +snes.input.port1 gamepad + +;snes, Virtual Port 1/1A, Gamepad: A (right) +snes.input.port1.gamepad.a joystick @GUID1@ @DEVICE_BTN_EAST@ + +;snes, Virtual Port 1/1A, Gamepad: B (center, lower) +snes.input.port1.gamepad.b joystick @GUID1@ @DEVICE_BTN_SOUTH@ + +;snes, Virtual Port 1/1A, Gamepad: DOWN (down) +snes.input.port1.gamepad.down joystick @GUID1@ @DEVICE_BTN_DPAD_DOWN@ + +;snes, Virtual Port 1/1A, Gamepad: Left Shoulder +snes.input.port1.gamepad.l joystick @GUID1@ @DEVICE_BTN_TL@ + +;snes, Virtual Port 1/1A, Gamepad: LEFT (left) +snes.input.port1.gamepad.left joystick @GUID1@ @DEVICE_BTN_DPAD_LEFT@ + +;snes, Virtual Port 1/1A, Gamepad: Right Shoulder +snes.input.port1.gamepad.r joystick @GUID1@ @DEVICE_BTN_TR@ + +;snes, Virtual Port 1/1A, Gamepad: Rapid A (right) +snes.input.port1.gamepad.rapid_a keyboard 0x0 17 + +;snes, Virtual Port 1/1A, Gamepad: Rapid B (center, lower) +snes.input.port1.gamepad.rapid_b keyboard 0x0 17 + +;snes, Virtual Port 1/1A, Gamepad: Rapid X (center, upper) +snes.input.port1.gamepad.rapid_x keyboard 0x0 17 + +;snes, Virtual Port 1/1A, Gamepad: Rapid Y (left) +snes.input.port1.gamepad.rapid_y keyboard 0x0 17 + +;snes, Virtual Port 1/1A, Gamepad: RIGHT (right) +snes.input.port1.gamepad.right joystick @GUID1@ @DEVICE_BTN_DPAD_RIGHT@ + +;snes, Virtual Port 1/1A, Gamepad: SELECT +snes.input.port1.gamepad.select joystick @GUID1@ @DEVICE_BTN_SELECT@ + +;snes, Virtual Port 1/1A, Gamepad: START +snes.input.port1.gamepad.start joystick @GUID1@ @DEVICE_BTN_START@ + +;snes, Virtual Port 1/1A, Gamepad: UP +snes.input.port1.gamepad.up joystick @GUID1@ @DEVICE_BTN_DPAD_UP@ + +;snes, Virtual Port 1/1A, Gamepad: X (center, upper) +snes.input.port1.gamepad.x joystick @GUID1@ @DEVICE_BTN_NORTH@ + +;snes, Virtual Port 1/1A, Gamepad: Y (left) +snes.input.port1.gamepad.y joystick @GUID1@ @DEVICE_BTN_WEST@ + +;snes, Port 1/1A, Mouse: Left Button +snes.input.port1.mouse.left mouse 0x0 button_left + +;snes, Port 1/1A, Mouse: Motion Down +snes.input.port1.mouse.motion_down mouse 0x0 rel_y+ + +;snes, Port 1/1A, Mouse: Motion Left +snes.input.port1.mouse.motion_left mouse 0x0 rel_x- + +;snes, Port 1/1A, Mouse: Motion Right +snes.input.port1.mouse.motion_right mouse 0x0 rel_x+ + +;snes, Port 1/1A, Mouse: Motion Up +snes.input.port1.mouse.motion_up mouse 0x0 rel_y- + +;snes, Port 1/1A, Mouse: Right Button +snes.input.port1.mouse.right mouse 0x0 button_right + +;Enable multitap on SNES port 1. +snes.input.port1.multitap 0 + +;Input device for Port 2/2A +snes.input.port2 gamepad + +;snes, Port 2/2A, Gamepad: A (right) +snes.input.port2.gamepad.a + +;snes, Port 2/2A, Gamepad: B (center, lower) +snes.input.port2.gamepad.b + +;snes, Port 2/2A, Gamepad: DOWN ↓ +snes.input.port2.gamepad.down + +;snes, Port 2/2A, Gamepad: Left Shoulder +snes.input.port2.gamepad.l + +;snes, Port 2/2A, Gamepad: LEFT ← +snes.input.port2.gamepad.left + +;snes, Port 2/2A, Gamepad: Right Shoulder +snes.input.port2.gamepad.r + +;snes, Port 2/2A, Gamepad: Rapid A (right) +snes.input.port2.gamepad.rapid_a + +;snes, Port 2/2A, Gamepad: Rapid B (center, lower) +snes.input.port2.gamepad.rapid_b + +;snes, Port 2/2A, Gamepad: Rapid X (center, upper) +snes.input.port2.gamepad.rapid_x + +;snes, Port 2/2A, Gamepad: Rapid Y (left) +snes.input.port2.gamepad.rapid_y + +;snes, Port 2/2A, Gamepad: RIGHT → +snes.input.port2.gamepad.right + +;snes, Port 2/2A, Gamepad: SELECT +snes.input.port2.gamepad.select + +;snes, Port 2/2A, Gamepad: START +snes.input.port2.gamepad.start + +;snes, Port 2/2A, Gamepad: UP ↑ +snes.input.port2.gamepad.up + +;snes, Port 2/2A, Gamepad: X (center, upper) +snes.input.port2.gamepad.x + +;snes, Port 2/2A, Gamepad: Y (left) +snes.input.port2.gamepad.y + +;snes, Port 2/2A, Mouse: Left Button +snes.input.port2.mouse.left mouse 0x0 button_left + +;snes, Port 2/2A, Mouse: Motion Down +snes.input.port2.mouse.motion_down mouse 0x0 rel_y+ + +;snes, Port 2/2A, Mouse: Motion Left +snes.input.port2.mouse.motion_left mouse 0x0 rel_x- + +;snes, Port 2/2A, Mouse: Motion Right +snes.input.port2.mouse.motion_right mouse 0x0 rel_x+ + +;snes, Port 2/2A, Mouse: Motion Up +snes.input.port2.mouse.motion_up mouse 0x0 rel_y- + +;snes, Port 2/2A, Mouse: Right Button +snes.input.port2.mouse.right mouse 0x0 button_right + +;Enable multitap on SNES port 2. +snes.input.port2.multitap 0 + +;snes, Port 2/2A, Super Scope: Cursor +snes.input.port2.superscope.cursor mouse 0x0 button_right + +;snes, Port 2/2A, Super Scope: Offscreen Shot(Simulated) +snes.input.port2.superscope.offscreen_shot keyboard 0x0 44 + +;snes, Port 2/2A, Super Scope: Pause +snes.input.port2.superscope.pause mouse 0x0 button_middle + +;snes, Port 2/2A, Super Scope: Trigger +snes.input.port2.superscope.trigger mouse 0x0 button_left + +;snes, Port 2/2A, Super Scope: Turbo +snes.input.port2.superscope.turbo keyboard 0x0 77 + +;snes, Port 2/2A, Super Scope: X Axis +snes.input.port2.superscope.x_axis mouse 0x0 cursor_x-+ + +;snes, Port 2/2A, Super Scope: Y Axis +snes.input.port2.superscope.y_axis mouse 0x0 cursor_y-+ + +;snes, Port 2B, Gamepad: A (right) +snes.input.port3.gamepad.a + +;snes, Port 2B, Gamepad: B (center, lower) +snes.input.port3.gamepad.b + +;snes, Port 2B, Gamepad: DOWN ↓ +snes.input.port3.gamepad.down + +;snes, Port 2B, Gamepad: Left Shoulder +snes.input.port3.gamepad.l + +;snes, Port 2B, Gamepad: LEFT ← +snes.input.port3.gamepad.left + +;snes, Port 2B, Gamepad: Right Shoulder +snes.input.port3.gamepad.r + +;snes, Port 2B, Gamepad: Rapid A (right) +snes.input.port3.gamepad.rapid_a + +;snes, Port 2B, Gamepad: Rapid B (center, lower) +snes.input.port3.gamepad.rapid_b + +;snes, Port 2B, Gamepad: Rapid X (center, upper) +snes.input.port3.gamepad.rapid_x + +;snes, Port 2B, Gamepad: Rapid Y (left) +snes.input.port3.gamepad.rapid_y + +;snes, Port 2B, Gamepad: RIGHT → +snes.input.port3.gamepad.right + +;snes, Port 2B, Gamepad: SELECT +snes.input.port3.gamepad.select + +;snes, Port 2B, Gamepad: START +snes.input.port3.gamepad.start + +;snes, Port 2B, Gamepad: UP ↑ +snes.input.port3.gamepad.up + +;snes, Port 2B, Gamepad: X (center, upper) +snes.input.port3.gamepad.x + +;snes, Port 2B, Gamepad: Y (left) +snes.input.port3.gamepad.y + +;snes, Port 2C, Gamepad: A (right) +snes.input.port4.gamepad.a + +;snes, Port 2C, Gamepad: B (center, lower) +snes.input.port4.gamepad.b + +;snes, Port 2C, Gamepad: DOWN ↓ +snes.input.port4.gamepad.down + +;snes, Port 2C, Gamepad: Left Shoulder +snes.input.port4.gamepad.l + +;snes, Port 2C, Gamepad: LEFT ← +snes.input.port4.gamepad.left + +;snes, Port 2C, Gamepad: Right Shoulder +snes.input.port4.gamepad.r + +;snes, Port 2C, Gamepad: Rapid A (right) +snes.input.port4.gamepad.rapid_a + +;snes, Port 2C, Gamepad: Rapid B (center, lower) +snes.input.port4.gamepad.rapid_b + +;snes, Port 2C, Gamepad: Rapid X (center, upper) +snes.input.port4.gamepad.rapid_x + +;snes, Port 2C, Gamepad: Rapid Y (left) +snes.input.port4.gamepad.rapid_y + +;snes, Port 2C, Gamepad: RIGHT → +snes.input.port4.gamepad.right + +;snes, Port 2C, Gamepad: SELECT +snes.input.port4.gamepad.select + +;snes, Port 2C, Gamepad: START +snes.input.port4.gamepad.start + +;snes, Port 2C, Gamepad: UP ↑ +snes.input.port4.gamepad.up + +;snes, Port 2C, Gamepad: X (center, upper) +snes.input.port4.gamepad.x + +;snes, Port 2C, Gamepad: Y (left) +snes.input.port4.gamepad.y + +;snes, Port 2D, Gamepad: A (right) +snes.input.port5.gamepad.a + +;snes, Port 2D, Gamepad: B (center, lower) +snes.input.port5.gamepad.b + +;snes, Port 2D, Gamepad: DOWN ↓ +snes.input.port5.gamepad.down + +;snes, Port 2D, Gamepad: Left Shoulder +snes.input.port5.gamepad.l + +;snes, Port 2D, Gamepad: LEFT ← +snes.input.port5.gamepad.left + +;snes, Port 2D, Gamepad: Right Shoulder +snes.input.port5.gamepad.r + +;snes, Port 2D, Gamepad: Rapid A (right) +snes.input.port5.gamepad.rapid_a + +;snes, Port 2D, Gamepad: Rapid B (center, lower) +snes.input.port5.gamepad.rapid_b + +;snes, Port 2D, Gamepad: Rapid X (center, upper) +snes.input.port5.gamepad.rapid_x + +;snes, Port 2D, Gamepad: Rapid Y (left) +snes.input.port5.gamepad.rapid_y + +;snes, Port 2D, Gamepad: RIGHT → +snes.input.port5.gamepad.right + +;snes, Port 2D, Gamepad: SELECT +snes.input.port5.gamepad.select + +;snes, Port 2D, Gamepad: START +snes.input.port5.gamepad.start + +;snes, Port 2D, Gamepad: UP ↑ +snes.input.port5.gamepad.up + +;snes, Port 2D, Gamepad: X (center, upper) +snes.input.port5.gamepad.x + +;snes, Port 2D, Gamepad: Y (left) +snes.input.port5.gamepad.y + +;snes, Port 1B, Gamepad: A (right) +snes.input.port6.gamepad.a + +;snes, Port 1B, Gamepad: B (center, lower) +snes.input.port6.gamepad.b + +;snes, Port 1B, Gamepad: DOWN ↓ +snes.input.port6.gamepad.down + +;snes, Port 1B, Gamepad: Left Shoulder +snes.input.port6.gamepad.l + +;snes, Port 1B, Gamepad: LEFT ← +snes.input.port6.gamepad.left + +;snes, Port 1B, Gamepad: Right Shoulder +snes.input.port6.gamepad.r + +;snes, Port 1B, Gamepad: Rapid A (right) +snes.input.port6.gamepad.rapid_a + +;snes, Port 1B, Gamepad: Rapid B (center, lower) +snes.input.port6.gamepad.rapid_b + +;snes, Port 1B, Gamepad: Rapid X (center, upper) +snes.input.port6.gamepad.rapid_x + +;snes, Port 1B, Gamepad: Rapid Y (left) +snes.input.port6.gamepad.rapid_y + +;snes, Port 1B, Gamepad: RIGHT → +snes.input.port6.gamepad.right + +;snes, Port 1B, Gamepad: SELECT +snes.input.port6.gamepad.select + +;snes, Port 1B, Gamepad: START +snes.input.port6.gamepad.start + +;snes, Port 1B, Gamepad: UP ↑ +snes.input.port6.gamepad.up + +;snes, Port 1B, Gamepad: X (center, upper) +snes.input.port6.gamepad.x + +;snes, Port 1B, Gamepad: Y (left) +snes.input.port6.gamepad.y + +;snes, Port 1C, Gamepad: A (right) +snes.input.port7.gamepad.a + +;snes, Port 1C, Gamepad: B (center, lower) +snes.input.port7.gamepad.b + +;snes, Port 1C, Gamepad: DOWN ↓ +snes.input.port7.gamepad.down + +;snes, Port 1C, Gamepad: Left Shoulder +snes.input.port7.gamepad.l + +;snes, Port 1C, Gamepad: LEFT ← +snes.input.port7.gamepad.left + +;snes, Port 1C, Gamepad: Right Shoulder +snes.input.port7.gamepad.r + +;snes, Port 1C, Gamepad: Rapid A (right) +snes.input.port7.gamepad.rapid_a + +;snes, Port 1C, Gamepad: Rapid B (center, lower) +snes.input.port7.gamepad.rapid_b + +;snes, Port 1C, Gamepad: Rapid X (center, upper) +snes.input.port7.gamepad.rapid_x + +;snes, Port 1C, Gamepad: Rapid Y (left) +snes.input.port7.gamepad.rapid_y + +;snes, Port 1C, Gamepad: RIGHT → +snes.input.port7.gamepad.right + +;snes, Port 1C, Gamepad: SELECT +snes.input.port7.gamepad.select + +;snes, Port 1C, Gamepad: START +snes.input.port7.gamepad.start + +;snes, Port 1C, Gamepad: UP ↑ +snes.input.port7.gamepad.up + +;snes, Port 1C, Gamepad: X (center, upper) +snes.input.port7.gamepad.x + +;snes, Port 1C, Gamepad: Y (left) +snes.input.port7.gamepad.y + +;snes, Port 1D, Gamepad: A (right) +snes.input.port8.gamepad.a + +;snes, Port 1D, Gamepad: B (center, lower) +snes.input.port8.gamepad.b + +;snes, Port 1D, Gamepad: DOWN ↓ +snes.input.port8.gamepad.down + +;snes, Port 1D, Gamepad: Left Shoulder +snes.input.port8.gamepad.l + +;snes, Port 1D, Gamepad: LEFT ← +snes.input.port8.gamepad.left + +;snes, Port 1D, Gamepad: Right Shoulder +snes.input.port8.gamepad.r + +;snes, Port 1D, Gamepad: Rapid A (right) +snes.input.port8.gamepad.rapid_a + +;snes, Port 1D, Gamepad: Rapid B (center, lower) +snes.input.port8.gamepad.rapid_b + +;snes, Port 1D, Gamepad: Rapid X (center, upper) +snes.input.port8.gamepad.rapid_x + +;snes, Port 1D, Gamepad: Rapid Y (left) +snes.input.port8.gamepad.rapid_y + +;snes, Port 1D, Gamepad: RIGHT → +snes.input.port8.gamepad.right + +;snes, Port 1D, Gamepad: SELECT +snes.input.port8.gamepad.select + +;snes, Port 1D, Gamepad: START +snes.input.port8.gamepad.start + +;snes, Port 1D, Gamepad: UP ↑ +snes.input.port8.gamepad.up + +;snes, Port 1D, Gamepad: X (center, upper) +snes.input.port8.gamepad.x + +;snes, Port 1D, Gamepad: Y (left) +snes.input.port8.gamepad.y + +;Emulated mouse sensitivity. +snes.mouse_sensitivity 0.50 + +;Enable scanlines with specified opacity. +snes.scanlines 0 + +;Enable specified OpenGL shader. +snes.shader none + +;Force interlaced video to be treated as progressive. +snes.shader.goat.fprog 0 + +;Constant RGB horizontal divergence. +snes.shader.goat.hdiv 0.50 + +;Mask pattern. +snes.shader.goat.pat goatron + +;Enable scanlines effect. +snes.shader.goat.slen 1 + +;Transparency of otherwise-opaque mask areas. +snes.shader.goat.tp 0.50 + +;Constant RGB vertical divergence. +snes.shader.goat.vdiv 0.50 + +;Enable specified special video scaler. +snes.special none + +;Stretch to fill screen. +snes.stretch aspect + +;Enable video temporal blur(50/50 previous/current frame by default). +snes.tblur 0 + +;Accumulate color data rather than discarding it. +snes.tblur.accum 0 + +;Blur amount in accumulation mode, specified in percentage of accumulation buffer to mix with the current frame. +snes.tblur.accum.amount 50 + +;Enable (bi)linear interpolation. +snes.videoip 0 + +;Full-screen horizontal resolution. +snes.xres 0 + +;Scaling factor for the X axis in windowed mode. +snes.xscale 4.000000 + +;Scaling factor for the X axis in fullscreen mode. +snes.xscalefs 1.000000 + +;Full-screen vertical resolution. +snes.yres 0 + +;Scaling factor for the Y axis in windowed mode. +snes.yscale 4.000000 + +;Scaling factor for the Y axis in fullscreen mode. +snes.yscalefs 1.000000 + +;MSU1 audio read thread CPU affinity mask. +snes_faust.affinity.msu1.audio 0 + +;MSU1 data read thread CPU affinity mask. +snes_faust.affinity.msu1.data 0 + +;PPU rendering thread CPU affinity mask. +snes_faust.affinity.ppu 0xc + +;Correct aspect ratio. +snes_faust.correct_aspect 1 + +;CX4 clock rate, specified in percentage of normal. +snes_faust.cx4.clock_rate 100 + +;Enable (automatic) usage of this module. +snes_faust.enable 1 + +;Force monophonic sound output. +snes_faust.forcemono 0 + +;Horizontal blending/doubling filter. +snes_faust.h_filter none + +;Emulated mouse sensitivity. +snes_faust.input.mouse_sensitivity 0.50 + +;Input device for Virtual Port 1 +snes_faust.input.port1 gamepad + +;snes_faust, Virtual Port 1, Gamepad: A (right) +snes_faust.input.port1.gamepad.a joystick @GUID1@ @DEVICE_BTN_EAST@ + +;snes_faust, Virtual Port 1, Gamepad: B (center, lower) +snes_faust.input.port1.gamepad.b joystick @GUID1@ @DEVICE_BTN_SOUTH@ + +;snes_faust, Virtual Port 1, Gamepad: DOWN ↓ +snes_faust.input.port1.gamepad.down joystick @GUID1@ @DEVICE_BTN_DPAD_DOWN@ + +;snes_faust, Virtual Port 1, Gamepad: Left Shoulder +snes_faust.input.port1.gamepad.l joystick @GUID1@ @DEVICE_BTN_TL@ + +;snes_faust, Virtual Port 1, Gamepad: LEFT ← +snes_faust.input.port1.gamepad.left joystick @GUID1@ @DEVICE_BTN_DPAD_LEFT@ + +;snes_faust, Virtual Port 1, Gamepad: Right Shoulder +snes_faust.input.port1.gamepad.r joystick @GUID1@ @DEVICE_BTN_TR@ + +;snes_faust, Virtual Port 1, Gamepad: Rapid A (right) +snes_faust.input.port1.gamepad.rapid_a keyboard 0x0 17 + +;snes_faust, Virtual Port 1, Gamepad: Rapid B (center, lower) +snes_faust.input.port1.gamepad.rapid_b keyboard 0x0 17 + +;snes_faust, Virtual Port 1, Gamepad: Rapid X (center, upper) +snes_faust.input.port1.gamepad.rapid_x keyboard 0x0 17 + +;snes_faust, Virtual Port 1, Gamepad: Rapid Y (left) +snes_faust.input.port1.gamepad.rapid_y keyboard 0x0 17 + +;snes_faust, Virtual Port 1, Gamepad: RIGHT → +snes_faust.input.port1.gamepad.right joystick @GUID1@ @DEVICE_BTN_DPAD_RIGHT@ + +;snes_faust, Virtual Port 1, Gamepad: SELECT +snes_faust.input.port1.gamepad.select joystick @GUID1@ @DEVICE_BTN_SELECT@ + +;snes_faust, Virtual Port 1, Gamepad: START +snes_faust.input.port1.gamepad.start joystick @GUID1@ @DEVICE_BTN_START@ + +;snes_faust, Virtual Port 1, Gamepad: UP ↑ +snes_faust.input.port1.gamepad.up joystick @GUID1@ @DEVICE_BTN_DPAD_UP@ + +;snes_faust, Virtual Port 1, Gamepad: X (center, upper) +snes_faust.input.port1.gamepad.x joystick @GUID1@ @DEVICE_BTN_NORTH@ + +;snes_faust, Virtual Port 1, Gamepad: Y (left) +snes_faust.input.port1.gamepad.y joystick @GUID1@ @DEVICE_BTN_WEST@ + +;snes_faust, Virtual Port 1, Mouse: Left Button +snes_faust.input.port1.mouse.left mouse 0x0 button_left + +;snes_faust, Virtual Port 1, Mouse: Motion Down +snes_faust.input.port1.mouse.motion_down mouse 0x0 rel_y+ + +;snes_faust, Virtual Port 1, Mouse: Motion Left +snes_faust.input.port1.mouse.motion_left mouse 0x0 rel_x- + +;snes_faust, Virtual Port 1, Mouse: Motion Right +snes_faust.input.port1.mouse.motion_right mouse 0x0 rel_x+ + +;snes_faust, Virtual Port 1, Mouse: Motion Up +snes_faust.input.port1.mouse.motion_up mouse 0x0 rel_y- + +;snes_faust, Virtual Port 1, Mouse: Right Button +snes_faust.input.port1.mouse.right mouse 0x0 button_right + +;Input device for Virtual Port 2 +snes_faust.input.port2 gamepad + +;snes_faust, Virtual Port 2, Gamepad: A (right) +snes_faust.input.port2.gamepad.a + +;snes_faust, Virtual Port 2, Gamepad: B (center, lower) +snes_faust.input.port2.gamepad.b + +;snes_faust, Virtual Port 2, Gamepad: DOWN ↓ +snes_faust.input.port2.gamepad.down + +;snes_faust, Virtual Port 2, Gamepad: Left Shoulder +snes_faust.input.port2.gamepad.l + +;snes_faust, Virtual Port 2, Gamepad: LEFT ← +snes_faust.input.port2.gamepad.left + +;snes_faust, Virtual Port 2, Gamepad: Right Shoulder +snes_faust.input.port2.gamepad.r + +;snes_faust, Virtual Port 2, Gamepad: Rapid A (right) +snes_faust.input.port2.gamepad.rapid_a + +;snes_faust, Virtual Port 2, Gamepad: Rapid B (center, lower) +snes_faust.input.port2.gamepad.rapid_b + +;snes_faust, Virtual Port 2, Gamepad: Rapid X (center, upper) +snes_faust.input.port2.gamepad.rapid_x + +;snes_faust, Virtual Port 2, Gamepad: Rapid Y (left) +snes_faust.input.port2.gamepad.rapid_y + +;snes_faust, Virtual Port 2, Gamepad: RIGHT → +snes_faust.input.port2.gamepad.right + +;snes_faust, Virtual Port 2, Gamepad: SELECT +snes_faust.input.port2.gamepad.select + +;snes_faust, Virtual Port 2, Gamepad: START +snes_faust.input.port2.gamepad.start + +;snes_faust, Virtual Port 2, Gamepad: UP ↑ +snes_faust.input.port2.gamepad.up + +;snes_faust, Virtual Port 2, Gamepad: X (center, upper) +snes_faust.input.port2.gamepad.x + +;snes_faust, Virtual Port 2, Gamepad: Y (left) +snes_faust.input.port2.gamepad.y + +;snes_faust, Virtual Port 2, Mouse: Left Button +snes_faust.input.port2.mouse.left mouse 0x0 button_left + +;snes_faust, Virtual Port 2, Mouse: Motion Down +snes_faust.input.port2.mouse.motion_down mouse 0x0 rel_y+ + +;snes_faust, Virtual Port 2, Mouse: Motion Left +snes_faust.input.port2.mouse.motion_left mouse 0x0 rel_x- + +;snes_faust, Virtual Port 2, Mouse: Motion Right +snes_faust.input.port2.mouse.motion_right mouse 0x0 rel_x+ + +;snes_faust, Virtual Port 2, Mouse: Motion Up +snes_faust.input.port2.mouse.motion_up mouse 0x0 rel_y- + +;snes_faust, Virtual Port 2, Mouse: Right Button +snes_faust.input.port2.mouse.right mouse 0x0 button_right + +;Input device for Virtual Port 3 +snes_faust.input.port3 gamepad + +;snes_faust, Virtual Port 3, Gamepad: A (right) +snes_faust.input.port3.gamepad.a + +;snes_faust, Virtual Port 3, Gamepad: B (center, lower) +snes_faust.input.port3.gamepad.b + +;snes_faust, Virtual Port 3, Gamepad: DOWN ↓ +snes_faust.input.port3.gamepad.down + +;snes_faust, Virtual Port 3, Gamepad: Left Shoulder +snes_faust.input.port3.gamepad.l + +;snes_faust, Virtual Port 3, Gamepad: LEFT ← +snes_faust.input.port3.gamepad.left + +;snes_faust, Virtual Port 3, Gamepad: Right Shoulder +snes_faust.input.port3.gamepad.r + +;snes_faust, Virtual Port 3, Gamepad: Rapid A (right) +snes_faust.input.port3.gamepad.rapid_a + +;snes_faust, Virtual Port 3, Gamepad: Rapid B (center, lower) +snes_faust.input.port3.gamepad.rapid_b + +;snes_faust, Virtual Port 3, Gamepad: Rapid X (center, upper) +snes_faust.input.port3.gamepad.rapid_x + +;snes_faust, Virtual Port 3, Gamepad: Rapid Y (left) +snes_faust.input.port3.gamepad.rapid_y + +;snes_faust, Virtual Port 3, Gamepad: RIGHT → +snes_faust.input.port3.gamepad.right + +;snes_faust, Virtual Port 3, Gamepad: SELECT +snes_faust.input.port3.gamepad.select + +;snes_faust, Virtual Port 3, Gamepad: START +snes_faust.input.port3.gamepad.start + +;snes_faust, Virtual Port 3, Gamepad: UP ↑ +snes_faust.input.port3.gamepad.up + +;snes_faust, Virtual Port 3, Gamepad: X (center, upper) +snes_faust.input.port3.gamepad.x + +;snes_faust, Virtual Port 3, Gamepad: Y (left) +snes_faust.input.port3.gamepad.y + +;snes_faust, Virtual Port 3, Mouse: Left Button +snes_faust.input.port3.mouse.left mouse 0x0 button_left + +;snes_faust, Virtual Port 3, Mouse: Motion Down +snes_faust.input.port3.mouse.motion_down mouse 0x0 rel_y+ + +;snes_faust, Virtual Port 3, Mouse: Motion Left +snes_faust.input.port3.mouse.motion_left mouse 0x0 rel_x- + +;snes_faust, Virtual Port 3, Mouse: Motion Right +snes_faust.input.port3.mouse.motion_right mouse 0x0 rel_x+ + +;snes_faust, Virtual Port 3, Mouse: Motion Up +snes_faust.input.port3.mouse.motion_up mouse 0x0 rel_y- + +;snes_faust, Virtual Port 3, Mouse: Right Button +snes_faust.input.port3.mouse.right mouse 0x0 button_right + +;Input device for Virtual Port 4 +snes_faust.input.port4 gamepad + +;snes_faust, Virtual Port 4, Gamepad: A (right) +snes_faust.input.port4.gamepad.a + +;snes_faust, Virtual Port 4, Gamepad: B (center, lower) +snes_faust.input.port4.gamepad.b + +;snes_faust, Virtual Port 4, Gamepad: DOWN ↓ +snes_faust.input.port4.gamepad.down + +;snes_faust, Virtual Port 4, Gamepad: Left Shoulder +snes_faust.input.port4.gamepad.l + +;snes_faust, Virtual Port 4, Gamepad: LEFT ← +snes_faust.input.port4.gamepad.left + +;snes_faust, Virtual Port 4, Gamepad: Right Shoulder +snes_faust.input.port4.gamepad.r + +;snes_faust, Virtual Port 4, Gamepad: Rapid A (right) +snes_faust.input.port4.gamepad.rapid_a + +;snes_faust, Virtual Port 4, Gamepad: Rapid B (center, lower) +snes_faust.input.port4.gamepad.rapid_b + +;snes_faust, Virtual Port 4, Gamepad: Rapid X (center, upper) +snes_faust.input.port4.gamepad.rapid_x + +;snes_faust, Virtual Port 4, Gamepad: Rapid Y (left) +snes_faust.input.port4.gamepad.rapid_y + +;snes_faust, Virtual Port 4, Gamepad: RIGHT → +snes_faust.input.port4.gamepad.right + +;snes_faust, Virtual Port 4, Gamepad: SELECT +snes_faust.input.port4.gamepad.select + +;snes_faust, Virtual Port 4, Gamepad: START +snes_faust.input.port4.gamepad.start + +;snes_faust, Virtual Port 4, Gamepad: UP ↑ +snes_faust.input.port4.gamepad.up + +;snes_faust, Virtual Port 4, Gamepad: X (center, upper) +snes_faust.input.port4.gamepad.x + +;snes_faust, Virtual Port 4, Gamepad: Y (left) +snes_faust.input.port4.gamepad.y + +;snes_faust, Virtual Port 4, Mouse: Left Button +snes_faust.input.port4.mouse.left mouse 0x0 button_left + +;snes_faust, Virtual Port 4, Mouse: Motion Down +snes_faust.input.port4.mouse.motion_down mouse 0x0 rel_y+ + +;snes_faust, Virtual Port 4, Mouse: Motion Left +snes_faust.input.port4.mouse.motion_left mouse 0x0 rel_x- + +;snes_faust, Virtual Port 4, Mouse: Motion Right +snes_faust.input.port4.mouse.motion_right mouse 0x0 rel_x+ + +;snes_faust, Virtual Port 4, Mouse: Motion Up +snes_faust.input.port4.mouse.motion_up mouse 0x0 rel_y- + +;snes_faust, Virtual Port 4, Mouse: Right Button +snes_faust.input.port4.mouse.right mouse 0x0 button_right + +;Input device for Virtual Port 5 +snes_faust.input.port5 gamepad + +;snes_faust, Virtual Port 5, Gamepad: A (right) +snes_faust.input.port5.gamepad.a + +;snes_faust, Virtual Port 5, Gamepad: B (center, lower) +snes_faust.input.port5.gamepad.b + +;snes_faust, Virtual Port 5, Gamepad: DOWN ↓ +snes_faust.input.port5.gamepad.down + +;snes_faust, Virtual Port 5, Gamepad: Left Shoulder +snes_faust.input.port5.gamepad.l + +;snes_faust, Virtual Port 5, Gamepad: LEFT ← +snes_faust.input.port5.gamepad.left + +;snes_faust, Virtual Port 5, Gamepad: Right Shoulder +snes_faust.input.port5.gamepad.r + +;snes_faust, Virtual Port 5, Gamepad: Rapid A (right) +snes_faust.input.port5.gamepad.rapid_a + +;snes_faust, Virtual Port 5, Gamepad: Rapid B (center, lower) +snes_faust.input.port5.gamepad.rapid_b + +;snes_faust, Virtual Port 5, Gamepad: Rapid X (center, upper) +snes_faust.input.port5.gamepad.rapid_x + +;snes_faust, Virtual Port 5, Gamepad: Rapid Y (left) +snes_faust.input.port5.gamepad.rapid_y + +;snes_faust, Virtual Port 5, Gamepad: RIGHT → +snes_faust.input.port5.gamepad.right + +;snes_faust, Virtual Port 5, Gamepad: SELECT +snes_faust.input.port5.gamepad.select + +;snes_faust, Virtual Port 5, Gamepad: START +snes_faust.input.port5.gamepad.start + +;snes_faust, Virtual Port 5, Gamepad: UP ↑ +snes_faust.input.port5.gamepad.up + +;snes_faust, Virtual Port 5, Gamepad: X (center, upper) +snes_faust.input.port5.gamepad.x + +;snes_faust, Virtual Port 5, Gamepad: Y (left) +snes_faust.input.port5.gamepad.y + +;snes_faust, Virtual Port 5, Mouse: Left Button +snes_faust.input.port5.mouse.left mouse 0x0 button_left + +;snes_faust, Virtual Port 5, Mouse: Motion Down +snes_faust.input.port5.mouse.motion_down mouse 0x0 rel_y+ + +;snes_faust, Virtual Port 5, Mouse: Motion Left +snes_faust.input.port5.mouse.motion_left mouse 0x0 rel_x- + +;snes_faust, Virtual Port 5, Mouse: Motion Right +snes_faust.input.port5.mouse.motion_right mouse 0x0 rel_x+ + +;snes_faust, Virtual Port 5, Mouse: Motion Up +snes_faust.input.port5.mouse.motion_up mouse 0x0 rel_y- + +;snes_faust, Virtual Port 5, Mouse: Right Button +snes_faust.input.port5.mouse.right mouse 0x0 button_right + +;Input device for Virtual Port 6 +snes_faust.input.port6 gamepad + +;snes_faust, Virtual Port 6, Gamepad: A (right) +snes_faust.input.port6.gamepad.a + +;snes_faust, Virtual Port 6, Gamepad: B (center, lower) +snes_faust.input.port6.gamepad.b + +;snes_faust, Virtual Port 6, Gamepad: DOWN ↓ +snes_faust.input.port6.gamepad.down + +;snes_faust, Virtual Port 6, Gamepad: Left Shoulder +snes_faust.input.port6.gamepad.l + +;snes_faust, Virtual Port 6, Gamepad: LEFT ← +snes_faust.input.port6.gamepad.left + +;snes_faust, Virtual Port 6, Gamepad: Right Shoulder +snes_faust.input.port6.gamepad.r + +;snes_faust, Virtual Port 6, Gamepad: Rapid A (right) +snes_faust.input.port6.gamepad.rapid_a + +;snes_faust, Virtual Port 6, Gamepad: Rapid B (center, lower) +snes_faust.input.port6.gamepad.rapid_b + +;snes_faust, Virtual Port 6, Gamepad: Rapid X (center, upper) +snes_faust.input.port6.gamepad.rapid_x + +;snes_faust, Virtual Port 6, Gamepad: Rapid Y (left) +snes_faust.input.port6.gamepad.rapid_y + +;snes_faust, Virtual Port 6, Gamepad: RIGHT → +snes_faust.input.port6.gamepad.right + +;snes_faust, Virtual Port 6, Gamepad: SELECT +snes_faust.input.port6.gamepad.select + +;snes_faust, Virtual Port 6, Gamepad: START +snes_faust.input.port6.gamepad.start + +;snes_faust, Virtual Port 6, Gamepad: UP ↑ +snes_faust.input.port6.gamepad.up + +;snes_faust, Virtual Port 6, Gamepad: X (center, upper) +snes_faust.input.port6.gamepad.x + +;snes_faust, Virtual Port 6, Gamepad: Y (left) +snes_faust.input.port6.gamepad.y + +;snes_faust, Virtual Port 6, Mouse: Left Button +snes_faust.input.port6.mouse.left mouse 0x0 button_left + +;snes_faust, Virtual Port 6, Mouse: Motion Down +snes_faust.input.port6.mouse.motion_down mouse 0x0 rel_y+ + +;snes_faust, Virtual Port 6, Mouse: Motion Left +snes_faust.input.port6.mouse.motion_left mouse 0x0 rel_x- + +;snes_faust, Virtual Port 6, Mouse: Motion Right +snes_faust.input.port6.mouse.motion_right mouse 0x0 rel_x+ + +;snes_faust, Virtual Port 6, Mouse: Motion Up +snes_faust.input.port6.mouse.motion_up mouse 0x0 rel_y- + +;snes_faust, Virtual Port 6, Mouse: Right Button +snes_faust.input.port6.mouse.right mouse 0x0 button_right + +;Input device for Virtual Port 7 +snes_faust.input.port7 gamepad + +;snes_faust, Virtual Port 7, Gamepad: A (right) +snes_faust.input.port7.gamepad.a + +;snes_faust, Virtual Port 7, Gamepad: B (center, lower) +snes_faust.input.port7.gamepad.b + +;snes_faust, Virtual Port 7, Gamepad: DOWN ↓ +snes_faust.input.port7.gamepad.down + +;snes_faust, Virtual Port 7, Gamepad: Left Shoulder +snes_faust.input.port7.gamepad.l + +;snes_faust, Virtual Port 7, Gamepad: LEFT ← +snes_faust.input.port7.gamepad.left + +;snes_faust, Virtual Port 7, Gamepad: Right Shoulder +snes_faust.input.port7.gamepad.r + +;snes_faust, Virtual Port 7, Gamepad: Rapid A (right) +snes_faust.input.port7.gamepad.rapid_a + +;snes_faust, Virtual Port 7, Gamepad: Rapid B (center, lower) +snes_faust.input.port7.gamepad.rapid_b + +;snes_faust, Virtual Port 7, Gamepad: Rapid X (center, upper) +snes_faust.input.port7.gamepad.rapid_x + +;snes_faust, Virtual Port 7, Gamepad: Rapid Y (left) +snes_faust.input.port7.gamepad.rapid_y + +;snes_faust, Virtual Port 7, Gamepad: RIGHT → +snes_faust.input.port7.gamepad.right + +;snes_faust, Virtual Port 7, Gamepad: SELECT +snes_faust.input.port7.gamepad.select + +;snes_faust, Virtual Port 7, Gamepad: START +snes_faust.input.port7.gamepad.start + +;snes_faust, Virtual Port 7, Gamepad: UP ↑ +snes_faust.input.port7.gamepad.up + +;snes_faust, Virtual Port 7, Gamepad: X (center, upper) +snes_faust.input.port7.gamepad.x + +;snes_faust, Virtual Port 7, Gamepad: Y (left) +snes_faust.input.port7.gamepad.y + +;snes_faust, Virtual Port 7, Mouse: Left Button +snes_faust.input.port7.mouse.left mouse 0x0 button_left + +;snes_faust, Virtual Port 7, Mouse: Motion Down +snes_faust.input.port7.mouse.motion_down mouse 0x0 rel_y+ + +;snes_faust, Virtual Port 7, Mouse: Motion Left +snes_faust.input.port7.mouse.motion_left mouse 0x0 rel_x- + +;snes_faust, Virtual Port 7, Mouse: Motion Right +snes_faust.input.port7.mouse.motion_right mouse 0x0 rel_x+ + +;snes_faust, Virtual Port 7, Mouse: Motion Up +snes_faust.input.port7.mouse.motion_up mouse 0x0 rel_y- + +;snes_faust, Virtual Port 7, Mouse: Right Button +snes_faust.input.port7.mouse.right mouse 0x0 button_right + +;Input device for Virtual Port 8 +snes_faust.input.port8 gamepad + +;snes_faust, Virtual Port 8, Gamepad: A (right) +snes_faust.input.port8.gamepad.a + +;snes_faust, Virtual Port 8, Gamepad: B (center, lower) +snes_faust.input.port8.gamepad.b + +;snes_faust, Virtual Port 8, Gamepad: DOWN ↓ +snes_faust.input.port8.gamepad.down + +;snes_faust, Virtual Port 8, Gamepad: Left Shoulder +snes_faust.input.port8.gamepad.l + +;snes_faust, Virtual Port 8, Gamepad: LEFT ← +snes_faust.input.port8.gamepad.left + +;snes_faust, Virtual Port 8, Gamepad: Right Shoulder +snes_faust.input.port8.gamepad.r + +;snes_faust, Virtual Port 8, Gamepad: Rapid A (right) +snes_faust.input.port8.gamepad.rapid_a + +;snes_faust, Virtual Port 8, Gamepad: Rapid B (center, lower) +snes_faust.input.port8.gamepad.rapid_b + +;snes_faust, Virtual Port 8, Gamepad: Rapid X (center, upper) +snes_faust.input.port8.gamepad.rapid_x + +;snes_faust, Virtual Port 8, Gamepad: Rapid Y (left) +snes_faust.input.port8.gamepad.rapid_y + +;snes_faust, Virtual Port 8, Gamepad: RIGHT → +snes_faust.input.port8.gamepad.right + +;snes_faust, Virtual Port 8, Gamepad: SELECT +snes_faust.input.port8.gamepad.select + +;snes_faust, Virtual Port 8, Gamepad: START +snes_faust.input.port8.gamepad.start + +;snes_faust, Virtual Port 8, Gamepad: UP ↑ +snes_faust.input.port8.gamepad.up + +;snes_faust, Virtual Port 8, Gamepad: X (center, upper) +snes_faust.input.port8.gamepad.x + +;snes_faust, Virtual Port 8, Gamepad: Y (left) +snes_faust.input.port8.gamepad.y + +;snes_faust, Virtual Port 8, Mouse: Left Button +snes_faust.input.port8.mouse.left mouse 0x0 button_left + +;snes_faust, Virtual Port 8, Mouse: Motion Down +snes_faust.input.port8.mouse.motion_down mouse 0x0 rel_y+ + +;snes_faust, Virtual Port 8, Mouse: Motion Left +snes_faust.input.port8.mouse.motion_left mouse 0x0 rel_x- + +;snes_faust, Virtual Port 8, Mouse: Motion Right +snes_faust.input.port8.mouse.motion_right mouse 0x0 rel_x+ + +;snes_faust, Virtual Port 8, Mouse: Motion Up +snes_faust.input.port8.mouse.motion_up mouse 0x0 rel_y- + +;snes_faust, Virtual Port 8, Mouse: Right Button +snes_faust.input.port8.mouse.right mouse 0x0 button_right + +;Enable multitap on SNES port 1. +snes_faust.input.sport1.multitap 0 + +;Enable multitap on SNES port 2. +snes_faust.input.sport2.multitap 0 + +;MSU1 sound quality. +snes_faust.msu1.resamp_quality 4 + +;Region of SNES to emulate. +snes_faust.region auto + +;PPU renderer. +snes_faust.renderer mt + +;Sound quality. +snes_faust.resamp_quality 3 + +;Sound output rate tolerance. +snes_faust.resamp_rate_error 0.000035 + +;Enable scanlines with specified opacity. +snes_faust.scanlines 0 + +;Enable specified OpenGL shader. +snes_faust.shader autoip + +;Force interlaced video to be treated as progressive. +snes_faust.shader.goat.fprog 0 + +;Constant RGB horizontal divergence. +snes_faust.shader.goat.hdiv 0.50 + +;Mask pattern. +snes_faust.shader.goat.pat goatron + +;Enable scanlines effect. +snes_faust.shader.goat.slen 1 + +;Transparency of otherwise-opaque mask areas. +snes_faust.shader.goat.tp 0.50 + +;Constant RGB vertical divergence. +snes_faust.shader.goat.vdiv 0.50 + +;Last displayed scanline in NTSC mode. +snes_faust.slend 223 + +;Last displayed scanline in PAL mode. +snes_faust.slendp 238 + +;First displayed scanline in NTSC mode. +snes_faust.slstart 0 + +;First displayed scanline in PAL mode. +snes_faust.slstartp 0 + +;Enable specified special video scaler. +snes_faust.special none + +;Enable 1-frame speculative execution for video output. +snes_faust.spex 0 + +;Enable speculative execution for sound output too. +snes_faust.spex.sound 1 + +;Stretch to fill screen. +snes_faust.stretch full + +;Super FX clock rate, specified in percentage of normal. +snes_faust.superfx.clock_rate 100 + +;Enable SuperFX instruction cache emulation. +snes_faust.superfx.icache 0 + +;Enable video temporal blur(50/50 previous/current frame by default). +snes_faust.tblur 0 + +;Accumulate color data rather than discarding it. +snes_faust.tblur.accum 0 + +;Blur amount in accumulation mode, specified in percentage of accumulation buffer to mix with the current frame. +snes_faust.tblur.accum.amount 50 + +;Enable (bi)linear interpolation. +snes_faust.videoip 0 + +;Full-screen horizontal resolution. +snes_faust.xres 0 + +;Scaling factor for the X axis in windowed mode. +snes_faust.xscale 3.000000 + +;Scaling factor for the X axis in fullscreen mode. +snes_faust.xscalefs 1.000000 + +;Full-screen vertical resolution. +snes_faust.yres 0 + +;Scaling factor for the Y axis in windowed mode. +snes_faust.yscale 3.000000 + +;Scaling factor for the Y axis in fullscreen mode. +snes_faust.yscalefs 1.000000 + +;Enable sound output. +sound 1 + +;Desired buffer size in milliseconds(ms). +sound.buffer_time 0 + +;Select sound output device. +sound.device sexyal-literal-default + +;Select sound driver. +sound.driver default + +;Desired period size in microseconds(μs). +sound.period_time 0 + +;Specifies the sound playback rate, in sound frames per second("Hz"). +sound.rate 48000 + +;Sound volume level, in percent. +sound.volume 100 + +;DO NOT USE UNLESS YOU'RE A SPACE GOAT +srwautoenable 0 + +;Number of frames to keep states for when state rewinding is enabled. +srwframes 600 + +;3D mode. +vb.3dmode anaglyph + +;Reverse left/right 3D views. +vb.3dreverse 0 + +;Allow draw skipping. +vb.allow_draw_skip 0 + +;Anaglyph maximum-brightness color for left view. +vb.anaglyph.lcolor 0xff0000 + +;Anaglyph preset colors. +vb.anaglyph.preset disabled + +;Anaglyph maximum-brightness color for right view. +vb.anaglyph.rcolor 0x000000 + +;CPU emulation mode. +vb.cpu_emulation accurate + +;Disassembly font size. +vb.debugger.disfontsize 5x7 + +;Character encoding for the debugger's memory editor. +vb.debugger.memcharenc shift_jis + +;Default maximum-brightness color to use in non-anaglyph 3D modes. +vb.default_color 0xF0F0F0 + +;Disable parallax for BG and OBJ rendering. +vb.disable_parallax 0 + +;Enable (automatic) usage of this module. +vb.enable 1 + +;Force monophonic sound output. +vb.forcemono 0 + +;vb, Built-In, Gamepad: A +vb.input.builtin.gamepad.a joystick @GUID1@ @DEVICE_BTN_EAST@ + +;vb, Built-In, Gamepad: B +vb.input.builtin.gamepad.b joystick @GUID1@ @DEVICE_BTN_SOUTH@ + +;vb, Built-In, Gamepad: DOWN ↓ (Left D-Pad) +vb.input.builtin.gamepad.down-l joystick @GUID1@ @DEVICE_BTN_DPAD_DOWN@ + +;vb, Built-In, Gamepad: DOWN ↓ (Right D-Pad) +vb.input.builtin.gamepad.down-r joystick @GUID1@ abs_1+ + +;vb, Built-In, Gamepad: LEFT ← (Left D-Pad) +vb.input.builtin.gamepad.left-l joystick @GUID1@ @DEVICE_BTN_DPAD_LEFT@ + +;vb, Built-In, Gamepad: LEFT ← (Right D-Pad) +vb.input.builtin.gamepad.left-r joystick @GUID1@ abs_0- + +;vb, Built-In, Gamepad: Left-Back +vb.input.builtin.gamepad.lt joystick @GUID1@ @DEVICE_BTN_TL@ + +;vb, Built-In, Gamepad: Rapid A +vb.input.builtin.gamepad.rapid_a joystick @GUID1@ @DEVICE_BTN_NORTH@ + +;vb, Built-In, Gamepad: Rapid B +vb.input.builtin.gamepad.rapid_b joystick @GUID1@ @DEVICE_BTN_WEST@ + +;vb, Built-In, Gamepad: RIGHT → (Left D-Pad) +vb.input.builtin.gamepad.right-l joystick @GUID1@ @DEVICE_BTN_DPAD_RIGHT@ + +;vb, Built-In, Gamepad: RIGHT → (Right D-Pad) +vb.input.builtin.gamepad.right-r joystick @GUID1@ abs_0+ + +;vb, Built-In, Gamepad: Right-Back +vb.input.builtin.gamepad.rt joystick @GUID1@ @DEVICE_BTN_TR@ + +;vb, Built-In, Gamepad: Select +vb.input.builtin.gamepad.select joystick @GUID1@ @DEVICE_BTN_SELECT@ + +;vb, Built-In, Gamepad: Start +vb.input.builtin.gamepad.start joystick @GUID1@ @DEVICE_BTN_START@ + +;vb, Built-In, Gamepad: UP ↑ (Left D-Pad) +vb.input.builtin.gamepad.up-l joystick @GUID1@ @DEVICE_BTN_DPAD_UP@ + +;vb, Built-In, Gamepad: UP ↑ (Right D-Pad) +vb.input.builtin.gamepad.up-r joystick @GUID1@ abs_1- + +;Input latency reduction hack. +vb.input.instant_read_hack 1 + +;vb, System, Misc: Battery Voltage +vb.input.system.misc.battery + +;Default position for switch "Battery Voltage". +vb.input.system.misc.battery.defpos normal + +;Display latency reduction hack. +vb.instant_display_hack 0 + +;LED on duration to linear RGB conversion coefficient. +vb.ledonscale 1.75 + +;Line Interlaced prescale. +vb.liprescale 2 + +;Enable scanlines with specified opacity. +vb.scanlines 0 + +;Enable specified OpenGL shader. +vb.shader ipxnoty + +;Force interlaced video to be treated as progressive. +vb.shader.goat.fprog 0 + +;Constant RGB horizontal divergence. +vb.shader.goat.hdiv 0.50 + +;Mask pattern. +vb.shader.goat.pat goatron + +;Enable scanlines effect. +vb.shader.goat.slen 1 + +;Transparency of otherwise-opaque mask areas. +vb.shader.goat.tp 0.50 + +;Constant RGB vertical divergence. +vb.shader.goat.vdiv 0.50 + +;Number of pixels to separate L/R views by. +vb.sidebyside.separation 0 + +;Enable specified special video scaler. +vb.special none + +;Stretch to fill screen. +vb.stretch full + +;Enable video temporal blur(50/50 previous/current frame by default). +vb.tblur 0 + +;Accumulate color data rather than discarding it. +vb.tblur.accum 0 + +;Blur amount in accumulation mode, specified in percentage of accumulation buffer to mix with the current frame. +vb.tblur.accum.amount 50 + +;Enable (bi)linear interpolation. +vb.videoip 0 + +;Full-screen horizontal resolution. +vb.xres 0 + +;Scaling factor for the X axis in windowed mode. +vb.xscale 2.000000 + +;Scaling factor for the X axis in fullscreen mode. +vb.xscalefs 1.000000 + +;Full-screen vertical resolution. +vb.yres 0 + +;Scaling factor for the Y axis in windowed mode. +vb.yscale 2.000000 + +;Scaling factor for the Y axis in fullscreen mode. +vb.yscalefs 1.000000 + +;Enable time synchronization(waiting) for frame blitting. +video.blit_timesync 1 + +;Preferred window manager cursor visibility. +video.cursorvis hidden + +;Deinterlacer to use for interlaced video. +video.deinterlacer weave + +;Attempt to disable desktop composition. +video.disable_composition 1 + +;Video output driver. +video.driver opengl + +;Force backbuffer clear before drawing. +video.force_bbclear 0 + +;Enable frameskip during emulation rendering. +video.frameskip 1 + +;Enable fullscreen mode. +video.fs 1 + +;Display to use with fullscreen mode. +video.fs.display -1 + +;Preferred source data pixel format for emulated video. +video.glformat auto + +;Attempt to synchronize OpenGL page flips to vertical retrace period. +video.glvsync 1 + +;Birth Day +wswan.bday 23 + +;Blood Type +wswan.blood O + +;Birth Month +wswan.bmonth 6 + +;Birth Year +wswan.byear 1989 + +;Disassembly font size. +wswan.debugger.disfontsize 5x7 + +;Character encoding for the debugger's memory editor. +wswan.debugger.memcharenc shift_jis + +;Enable (automatic) usage of this module. +wswan.enable 1 + +;Enable comms to external program. +wswan.excomm 0 + +;Comms external program path. +wswan.excomm.path wonderfence + +;Force monophonic sound output. +wswan.forcemono 0 + +;Input device for Built-In +wswan.input.builtin gamepad + +;wswan, Built-In, Gamepad: A +wswan.input.builtin.gamepad.a joystick @GUID1@ @DEVICE_BTN_EAST@ + +;wswan, Built-In, Gamepad: B +wswan.input.builtin.gamepad.b joystick @GUID1@ @DEVICE_BTN_SOUTH@ + +;wswan, Built-In, Gamepad: X3(X DOWN ↓) +wswan.input.builtin.gamepad.down-x joystick @GUID1@ @DEVICE_BTN_DPAD_DOWN@ + +;wswan, Built-In, Gamepad: Y3(Y DOWN ↓) +wswan.input.builtin.gamepad.down-y joystick @GUID1@ @DEVICE_BTN_TL2@ + +;wswan, Built-In, Gamepad: X4(X LEFT ←) +wswan.input.builtin.gamepad.left-x joystick @GUID1@ @DEVICE_BTN_DPAD_LEFT@ + +;wswan, Built-In, Gamepad: Y4(Y LEFT ←) +wswan.input.builtin.gamepad.left-y joystick @GUID1@ @DEVICE_BTN_TL@ + +;wswan, Built-In, Gamepad: Rapid A +wswan.input.builtin.gamepad.rapid_a joystick @GUID1@ @DEVICE_BTN_NORTH@ + +;wswan, Built-In, Gamepad: Rapid B +wswan.input.builtin.gamepad.rapid_b joystick @GUID1@ @DEVICE_BTN_WEST@ + +;wswan, Built-In, Gamepad: X2(X RIGHT →) +wswan.input.builtin.gamepad.right-x joystick @GUID1@ @DEVICE_BTN_DPAD_RIGHT@ + +;wswan, Built-In, Gamepad: Y2(Y RIGHT →) +wswan.input.builtin.gamepad.right-y joystick @GUID1@ @DEVICE_BTN_TR@ + +;wswan, Built-In, Gamepad: Start +wswan.input.builtin.gamepad.start joystick @GUID1@ @DEVICE_BTN_START@ + +;wswan, Built-In, Gamepad: X1(X UP ↑) +wswan.input.builtin.gamepad.up-x joystick @GUID1@ @DEVICE_BTN_DPAD_UP@ + +;wswan, Built-In, Gamepad: Y1(Y UP ↑) +wswan.input.builtin.gamepad.up-y joystick @GUID1@ @DEVICE_BTN_TR2@ + +;wswan, Built-In, Gamepad(Rotation Auto-Adjust): A (right) +wswan.input.builtin.gamepadraa.a keyboard 0x0 91 + +;wswan, Built-In, Gamepad(Rotation Auto-Adjust): A'(center, upper) +wswan.input.builtin.gamepadraa.ap keyboard 0x0 94 + +;wswan, Built-In, Gamepad(Rotation Auto-Adjust): B (center, lower) +wswan.input.builtin.gamepadraa.b keyboard 0x0 90 + +;wswan, Built-In, Gamepad(Rotation Auto-Adjust): B'(left) +wswan.input.builtin.gamepadraa.bp keyboard 0x0 93 + +;wswan, Built-In, Gamepad(Rotation Auto-Adjust): X3(X DOWN ↓) +wswan.input.builtin.gamepadraa.down-x keyboard 0x0 22 + +;wswan, Built-In, Gamepad(Rotation Auto-Adjust): Y3(Y DOWN ↓) +wswan.input.builtin.gamepadraa.down-y keyboard 0x0 81 + +;wswan, Built-In, Gamepad(Rotation Auto-Adjust): X4(X LEFT ←) +wswan.input.builtin.gamepadraa.left-x keyboard 0x0 4 + +;wswan, Built-In, Gamepad(Rotation Auto-Adjust): Y4(Y LEFT ←) +wswan.input.builtin.gamepadraa.left-y keyboard 0x0 80 + +;wswan, Built-In, Gamepad(Rotation Auto-Adjust): X2(X RIGHT →) +wswan.input.builtin.gamepadraa.right-x keyboard 0x0 7 + +;wswan, Built-In, Gamepad(Rotation Auto-Adjust): Y2(Y RIGHT →) +wswan.input.builtin.gamepadraa.right-y keyboard 0x0 79 + +;wswan, Built-In, Gamepad(Rotation Auto-Adjust): Start +wswan.input.builtin.gamepadraa.start keyboard 0x0 40 + +;wswan, Built-In, Gamepad(Rotation Auto-Adjust): X1(X UP ↑) +wswan.input.builtin.gamepadraa.up-x keyboard 0x0 26 + +;wswan, Built-In, Gamepad(Rotation Auto-Adjust): Y1(Y UP ↑) +wswan.input.builtin.gamepadraa.up-y keyboard 0x0 82 + +;Language games should display text in. +wswan.language english + +;Name +wswan.name Mednafen + +;Enable scanlines with specified opacity. +wswan.scanlines 0 + +;Sex +wswan.sex F + +;Enable specified OpenGL shader. +wswan.shader ipsharper + +;Force interlaced video to be treated as progressive. +wswan.shader.goat.fprog 0 + +;Constant RGB horizontal divergence. +wswan.shader.goat.hdiv 0.50 + +;Mask pattern. +wswan.shader.goat.pat goatron + +;Enable scanlines effect. +wswan.shader.goat.slen 1 + +;Transparency of otherwise-opaque mask areas. +wswan.shader.goat.tp 0.50 + +;Constant RGB vertical divergence. +wswan.shader.goat.vdiv 0.50 + +;Enable specified special video scaler. +wswan.special none + +;Stretch to fill screen. +wswan.stretch full + +;Enable video temporal blur(50/50 previous/current frame by default). +wswan.tblur 0 + +;Accumulate color data rather than discarding it. +wswan.tblur.accum 0 + +;Blur amount in accumulation mode, specified in percentage of accumulation buffer to mix with the current frame. +wswan.tblur.accum.amount 50 + +;Enable (bi)linear interpolation. +wswan.videoip 0 + +;Full-screen horizontal resolution. +wswan.xres 0 + +;Scaling factor for the X axis in windowed mode. +wswan.xscale 4.000000 + +;Scaling factor for the X axis in fullscreen mode. +wswan.xscalefs 1.000000 + +;Full-screen vertical resolution. +wswan.yres 0 + +;Scaling factor for the Y axis in windowed mode. +wswan.yscale 4.000000 + +;Scaling factor for the Y axis in fullscreen mode. +wswan.yscalefs 1.000000 + + +; +;Unrecognized settings follow: +; + +command.insert_eject_joystick @GUID1@ @DEVICE_BTN_TL@ + +apple2.enable 1 + +apple2.input.keyboard.twopiece.0 keyboard 0x0 39 + +apple2.input.keyboard.twopiece.1 keyboard 0x0 30 + +apple2.input.keyboard.twopiece.2 keyboard 0x0 31 + +apple2.input.keyboard.twopiece.3 keyboard 0x0 32 + +apple2.input.keyboard.twopiece.4 keyboard 0x0 33 + +apple2.input.keyboard.twopiece.5 keyboard 0x0 34 + +apple2.input.keyboard.twopiece.6 keyboard 0x0 35 + +apple2.input.keyboard.twopiece.7 keyboard 0x0 36 + +apple2.input.keyboard.twopiece.8 keyboard 0x0 37 + +apple2.input.keyboard.twopiece.9 keyboard 0x0 38 + +apple2.input.keyboard.twopiece.a keyboard 0x0 4 || keyboard 0x0 82 || keyboard 0x0 96 + +apple2.input.keyboard.twopiece.b keyboard 0x0 5 + +apple2.input.keyboard.twopiece.bs keyboard 0x0 80 || keyboard 0x0 42 || keyboard 0x0 93 || keyboard 0x0 76 + +apple2.input.keyboard.twopiece.c keyboard 0x0 6 + +apple2.input.keyboard.twopiece.colon keyboard 0x0 45 + +apple2.input.keyboard.twopiece.comma keyboard 0x0 54 + +apple2.input.keyboard.twopiece.cr keyboard 0x0 40 || keyboard 0x0 49 || keyboard 0x0 74 + +apple2.input.keyboard.twopiece.ctrl keyboard 0x0 57 || keyboard 0x0 224 || keyboard 0x0 228 + +apple2.input.keyboard.twopiece.d keyboard 0x0 7 + +apple2.input.keyboard.twopiece.e keyboard 0x0 8 + +apple2.input.keyboard.twopiece.esc keyboard 0x0 41 || keyboard 0x0 43 + +apple2.input.keyboard.twopiece.f keyboard 0x0 9 + +apple2.input.keyboard.twopiece.g keyboard 0x0 10 + +apple2.input.keyboard.twopiece.h keyboard 0x0 11 + +apple2.input.keyboard.twopiece.i keyboard 0x0 12 + +apple2.input.keyboard.twopiece.j keyboard 0x0 13 + +apple2.input.keyboard.twopiece.k keyboard 0x0 14 + +apple2.input.keyboard.twopiece.l keyboard 0x0 15 + +apple2.input.keyboard.twopiece.lshift keyboard 0x0 225 + +apple2.input.keyboard.twopiece.m keyboard 0x0 16 + +apple2.input.keyboard.twopiece.minus keyboard 0x0 46 + +apple2.input.keyboard.twopiece.n keyboard 0x0 17 + +apple2.input.keyboard.twopiece.nak keyboard 0x0 79 || keyboard 0x0 94 || keyboard 0x0 78 + +apple2.input.keyboard.twopiece.o keyboard 0x0 18 + +apple2.input.keyboard.twopiece.p keyboard 0x0 19 + +apple2.input.keyboard.twopiece.period keyboard 0x0 55 + +apple2.input.keyboard.twopiece.q keyboard 0x0 20 + +apple2.input.keyboard.twopiece.r keyboard 0x0 21 + +apple2.input.keyboard.twopiece.rept keyboard 0x0 47 || keyboard 0x0 226 || keyboard 0x0 230 + +apple2.input.keyboard.twopiece.reset keyboard 0x0 73 + +apple2.input.keyboard.twopiece.rshift keyboard 0x0 229 + +apple2.input.keyboard.twopiece.s keyboard 0x0 22 + +apple2.input.keyboard.twopiece.semicolon keyboard 0x0 51 || keyboard 0x0 92 + +apple2.input.keyboard.twopiece.slash keyboard 0x0 56 || keyboard 0x0 77 + +apple2.input.keyboard.twopiece.sp keyboard 0x0 44 + +apple2.input.keyboard.twopiece.t keyboard 0x0 23 + +apple2.input.keyboard.twopiece.u keyboard 0x0 24 + +apple2.input.keyboard.twopiece.v keyboard 0x0 25 + +apple2.input.keyboard.twopiece.w keyboard 0x0 26 + +apple2.input.keyboard.twopiece.x keyboard 0x0 27 + +apple2.input.keyboard.twopiece.y keyboard 0x0 28 + +apple2.input.keyboard.twopiece.z keyboard 0x0 29 || keyboard 0x0 81 || keyboard 0x0 90 + +apple2.input.port1 joystick + +apple2.input.port1.atari.button + +apple2.input.port1.atari.down + +apple2.input.port1.atari.left + +apple2.input.port1.atari.right + +apple2.input.port1.atari.up + +apple2.input.port1.gamepad.button1 + +apple2.input.port1.gamepad.button2 + +apple2.input.port1.gamepad.down + +apple2.input.port1.gamepad.left + +apple2.input.port1.gamepad.resistance_select + +apple2.input.port1.gamepad.resistance_select.defpos 2 + +apple2.input.port1.gamepad.right + +apple2.input.port1.gamepad.up + +apple2.input.port1.joystick.axis_scale 1.00 + +apple2.input.port1.joystick.button1 + +apple2.input.port1.joystick.button2 + +apple2.input.port1.joystick.resistance_select + +apple2.input.port1.joystick.resistance_select.defpos 2 + +apple2.input.port1.joystick.stick_down + +apple2.input.port1.joystick.stick_left + +apple2.input.port1.joystick.stick_right + +apple2.input.port1.joystick.stick_up + +apple2.input.port1.paddle.button + +apple2.input.port1.paddle.dial_left + +apple2.input.port1.paddle.dial_right + +apple2.input.port2 paddle + +apple2.input.port2.atari.button + +apple2.input.port2.atari.down + +apple2.input.port2.atari.left + +apple2.input.port2.atari.right + +apple2.input.port2.atari.up + +apple2.input.port2.paddle.button + +apple2.input.port2.paddle.dial_left + +apple2.input.port2.paddle.dial_right + +apple2.scanlines 0 + +apple2.shader none + +apple2.shader.goat.fprog 0 + +apple2.shader.goat.hdiv 0.50 + +apple2.shader.goat.pat goatron + +apple2.shader.goat.slen 1 + +apple2.shader.goat.tp 0.50 + +apple2.shader.goat.vdiv 0.50 + +apple2.special none + +apple2.stretch aspect + +apple2.tblur 0 + +apple2.tblur.accum 0 + +apple2.tblur.accum.amount 50 + +apple2.video.brightness 0.0 + +apple2.video.color_lumafilter -3 + +apple2.video.color_smooth 0 + +apple2.video.contrast 0.0 + +apple2.video.force_mono 0x000000 + +apple2.video.hue 0.0 + +apple2.video.matrix mednafen + +apple2.video.matrix.blue.i -1.11 + +apple2.video.matrix.blue.q 1.70 + +apple2.video.matrix.green.i -0.28 + +apple2.video.matrix.green.q -0.64 + +apple2.video.matrix.red.i 0.96 + +apple2.video.matrix.red.q 0.62 + +apple2.video.mixed_text_mono 0 + +apple2.video.mode composite + +apple2.video.mono_lumafilter 5 + +apple2.video.saturation 0.0 + +apple2.videoip x + +apple2.xres 0 + +apple2.xscale 4.000000 + +apple2.xscalefs 1.000000 + +apple2.yres 0 + +apple2.yscale 4.000000 + +apple2.yscalefs 1.000000 + +psx.bios_eu scph5502.bin + +psx.bios_jp scph5500.bin + +psx.bios_na scph5501.bin + +psx.bios_sanity 1 + +psx.cd_sanity 1 + +psx.correct_aspect 1 + +psx.dbg_exe_cdpath + +psx.dbg_level 0 + +psx.debugger.disfontsize 5x7 + +psx.debugger.memcharenc shift_jis + +psx.enable 1 + +psx.forcemono 0 + +psx.h_overscan 1 + +psx.input.analog_mode_ct 0 + +psx.input.analog_mode_ct.compare 0x0F09 + +psx.input.mouse_sensitivity 1.00 + +psx.input.port1 gamepad + +psx.input.port1.analogjoy.axis_scale 1.00 + +psx.input.port1.analogjoy.circle joystick @GUID1@ @DEVICE_BTN_EAST@ + +psx.input.port1.analogjoy.cross joystick @GUID1@ @DEVICE_BTN_SOUTH@ + +psx.input.port1.analogjoy.down joystick @GUID1@ @DEVICE_BTN_DPAD_DOWN@ + +psx.input.port1.analogjoy.l1 joystick @GUID1@ @DEVICE_BTN_TL@ + +psx.input.port1.analogjoy.l2 joystick @GUID1@ @DEVICE_BTN_TL2@ + +psx.input.port1.analogjoy.left joystick @GUID1@ @DEVICE_BTN_DPAD_LEFT@ + +psx.input.port1.analogjoy.lstick_down joystick @GUID1@ @DEVICE_BTN_AL_DOWN@ + +psx.input.port1.analogjoy.lstick_left joystick @GUID1@ @DEVICE_BTN_AL_LEFT@ + +psx.input.port1.analogjoy.lstick_right joystick @GUID1@ @DEVICE_BTN_AL_RIGHT@ + +psx.input.port1.analogjoy.lstick_up joystick @GUID1@ @DEVICE_BTN_AL_UP@ + +psx.input.port1.analogjoy.r1 joystick @GUID1@ @DEVICE_BTN_TR@ + +psx.input.port1.analogjoy.r2 joystick @GUID1@ @DEVICE_BTN_TR2@ + +psx.input.port1.analogjoy.right joystick @GUID1@ @DEVICE_BTN_DPAD_RIGHT@ + +psx.input.port1.analogjoy.rstick_down joystick @GUID1@ @DEVICE_BTN_AR_DOWN@ + +psx.input.port1.analogjoy.rstick_left joystick @GUID1@ @DEVICE_BTN_AR_LEFT@ + +psx.input.port1.analogjoy.rstick_right joystick @GUID1@ @DEVICE_BTN_AR_RIGHT@ + +psx.input.port1.analogjoy.rstick_up joystick @GUID1@ @DEVICE_BTN_AR_UP@ + +psx.input.port1.analogjoy.select joystick @GUID1@ @DEVICE_BTN_SELECT@ + +psx.input.port1.analogjoy.square joystick @GUID1@ @DEVICE_BTN_WEST@ + +psx.input.port1.analogjoy.start joystick @GUID1@ @DEVICE_BTN_START@ + +psx.input.port1.analogjoy.triangle joystick @GUID1@ @DEVICE_BTN_NORTH@ + +psx.input.port1.analogjoy.up joystick @GUID1@ @DEVICE_BTN_DPAD_UP@ + +psx.input.port1.dancepad.circle keyboard 0x0 97 + +psx.input.port1.dancepad.cross keyboard 0x0 95 + +psx.input.port1.dancepad.down keyboard 0x0 90 + +psx.input.port1.dancepad.left keyboard 0x0 92 + +psx.input.port1.dancepad.right keyboard 0x0 94 + +psx.input.port1.dancepad.select keyboard 0x0 84 + +psx.input.port1.dancepad.square keyboard 0x0 91 + +psx.input.port1.dancepad.start keyboard 0x0 85 + +psx.input.port1.dancepad.triangle keyboard 0x0 89 + +psx.input.port1.dancepad.up keyboard 0x0 96 + +psx.input.port1.dualanalog.axis_scale 1.00 + +psx.input.port1.dualanalog.circle + +psx.input.port1.dualanalog.cross + +psx.input.port1.dualanalog.down + +psx.input.port1.dualanalog.l1 + +psx.input.port1.dualanalog.l2 + +psx.input.port1.dualanalog.l3 + +psx.input.port1.dualanalog.left + +psx.input.port1.dualanalog.lstick_down + +psx.input.port1.dualanalog.lstick_left + +psx.input.port1.dualanalog.lstick_right + +psx.input.port1.dualanalog.lstick_up + +psx.input.port1.dualanalog.r1 + +psx.input.port1.dualanalog.r2 + +psx.input.port1.dualanalog.r3 + +psx.input.port1.dualanalog.rapid_circle + +psx.input.port1.dualanalog.rapid_cross + +psx.input.port1.dualanalog.rapid_square + +psx.input.port1.dualanalog.rapid_triangle + +psx.input.port1.dualanalog.right + +psx.input.port1.dualanalog.rstick_down + +psx.input.port1.dualanalog.rstick_left + +psx.input.port1.dualanalog.rstick_right + +psx.input.port1.dualanalog.rstick_up + +psx.input.port1.dualanalog.select + +psx.input.port1.dualanalog.square + +psx.input.port1.dualanalog.start + +psx.input.port1.dualanalog.triangle + +psx.input.port1.dualanalog.up + +psx.input.port1.dualshock.analog + +psx.input.port1.dualshock.axis_scale 1.00 + +psx.input.port1.dualshock.circle joystick @GUID1@ @DEVICE_BTN_EAST@ + +psx.input.port1.dualshock.cross joystick @GUID1@ @DEVICE_BTN_SOUTH@ + +psx.input.port1.dualshock.down joystick @GUID1@ @DEVICE_BTN_DPAD_DOWN@ + +psx.input.port1.dualshock.l1 joystick @GUID1@ @DEVICE_BTN_TL@ + +psx.input.port1.dualshock.l2 joystick @GUID1@ @DEVICE_BTN_TL2@ + +psx.input.port1.dualshock.l3 joystick @GUID1@ @DEVICE_BTN_THUMBL@ + +psx.input.port1.dualshock.left joystick @GUID1@ @DEVICE_BTN_DPAD_LEFT@ + +psx.input.port1.dualshock.lstick_down joystick @GUID1@ @DEVICE_BTN_AL_DOWN@ + +psx.input.port1.dualshock.lstick_left joystick @GUID1@ @DEVICE_BTN_AL_LEFT@ + +psx.input.port1.dualshock.lstick_right joystick @GUID1@ @DEVICE_BTN_AL_RIGHT@ + +psx.input.port1.dualshock.lstick_up joystick @GUID1@ @DEVICE_BTN_AL_UP@ + +psx.input.port1.dualshock.r1 joystick @GUID1@ @DEVICE_BTN_TR@ + +psx.input.port1.dualshock.r2 joystick @GUID1@ @DEVICE_BTN_TR2@ + +psx.input.port1.dualshock.r3 joystick @GUID1@ @DEVICE_BTN_THUMBR@ + +psx.input.port1.dualshock.rapid_circle + +psx.input.port1.dualshock.rapid_cross + +psx.input.port1.dualshock.rapid_square + +psx.input.port1.dualshock.rapid_triangle + +psx.input.port1.dualshock.right joystick @GUID1@ @DEVICE_BTN_DPAD_RIGHT@ + +psx.input.port1.dualshock.rstick_down joystick @GUID1@ @DEVICE_BTN_AR_DOWN@ + +psx.input.port1.dualshock.rstick_left joystick @GUID1@ @DEVICE_BTN_AR_LEFT@ + +psx.input.port1.dualshock.rstick_right joystick @GUID1@ @DEVICE_BTN_AR_RIGHT@ + +psx.input.port1.dualshock.rstick_up joystick @GUID1@ @DEVICE_BTN_AR_UP@ + +psx.input.port1.dualshock.select joystick @GUID1@ @DEVICE_BTN_SELECT@ + +psx.input.port1.dualshock.square joystick @GUID1@ @DEVICE_BTN_WEST@ + +psx.input.port1.dualshock.start joystick @GUID1@ @DEVICE_BTN_START@ + +psx.input.port1.dualshock.triangle joystick @GUID1@ @DEVICE_BTN_NORTH@ + +psx.input.port1.dualshock.up joystick @GUID1@ @DEVICE_BTN_DPAD_UP@ + +psx.input.port1.gamepad.circle joystick @GUID1@ @DEVICE_BTN_EAST@ + +psx.input.port1.gamepad.cross joystick @GUID1@ @DEVICE_BTN_SOUTH@ + +psx.input.port1.gamepad.down joystick @GUID1@ @DEVICE_BTN_DPAD_DOWN@ + +psx.input.port1.gamepad.l1 joystick @GUID1@ @DEVICE_BTN_TL@ + +psx.input.port1.gamepad.l2 joystick @GUID1@ @DEVICE_BTN_TL2@ + +psx.input.port1.gamepad.left joystick @GUID1@ @DEVICE_BTN_DPAD_LEFT@ + +psx.input.port1.gamepad.r1 joystick @GUID1@ @DEVICE_BTN_TR@ + +psx.input.port1.gamepad.r2 joystick @GUID1@ @DEVICE_BTN_TR2@ + +psx.input.port1.gamepad.rapid_circle + +psx.input.port1.gamepad.rapid_cross + +psx.input.port1.gamepad.rapid_square + +psx.input.port1.gamepad.rapid_triangle + +psx.input.port1.gamepad.right joystick @GUID1@ @DEVICE_BTN_DPAD_RIGHT@ + +psx.input.port1.gamepad.select joystick @GUID1@ @DEVICE_BTN_SELECT@ + +psx.input.port1.gamepad.square joystick @GUID1@ @DEVICE_BTN_WEST@ + +psx.input.port1.gamepad.start joystick @GUID1@ @DEVICE_BTN_START@ + +psx.input.port1.gamepad.triangle joystick @GUID1@ @DEVICE_BTN_NORTH@ + +psx.input.port1.gamepad.up joystick @GUID1@ @DEVICE_BTN_DPAD_UP@ + +psx.input.port1.gun_chairs 0xFF0000 + +psx.input.port1.guncon.a mouse 0x0 button_right + +psx.input.port1.guncon.b mouse 0x0 button_middle + +psx.input.port1.guncon.offscreen_shot keyboard 0x0 44 + +psx.input.port1.guncon.trigger mouse 0x0 button_left + +psx.input.port1.guncon.x_axis mouse 0x0 cursor_x-+ + +psx.input.port1.guncon.y_axis mouse 0x0 cursor_y-+ + +psx.input.port1.justifier.o mouse 0x0 button_right + +psx.input.port1.justifier.offscreen_shot keyboard 0x0 44 + +psx.input.port1.justifier.start mouse 0x0 button_middle + +psx.input.port1.justifier.trigger mouse 0x0 button_left + +psx.input.port1.justifier.x_axis mouse 0x0 cursor_x-+ + +psx.input.port1.justifier.y_axis mouse 0x0 cursor_y-+ + +psx.input.port1.memcard 1 + +psx.input.port1.mouse.left mouse 0x0 button_left + +psx.input.port1.mouse.motion_down mouse 0x0 rel_y+ + +psx.input.port1.mouse.motion_left mouse 0x0 rel_x- + +psx.input.port1.mouse.motion_right mouse 0x0 rel_x+ + +psx.input.port1.mouse.motion_up mouse 0x0 rel_y- + +psx.input.port1.mouse.right mouse 0x0 button_right + +psx.input.port1.negcon.a + +psx.input.port1.negcon.b + +psx.input.port1.negcon.down + +psx.input.port1.negcon.i + +psx.input.port1.negcon.ii + +psx.input.port1.negcon.l + +psx.input.port1.negcon.left + +psx.input.port1.negcon.r + +psx.input.port1.negcon.right + +psx.input.port1.negcon.start + +psx.input.port1.negcon.twist_ccwise + +psx.input.port1.negcon.twist_cwise + +psx.input.port1.negcon.up + +psx.input.port2 gamepad + +psx.input.port2.analogjoy.axis_scale 1.00 + +psx.input.port2.analogjoy.circle + +psx.input.port2.analogjoy.cross + +psx.input.port2.analogjoy.down + +psx.input.port2.analogjoy.l1 + +psx.input.port2.analogjoy.l2 + +psx.input.port2.analogjoy.left + +psx.input.port2.analogjoy.lstick_down + +psx.input.port2.analogjoy.lstick_left + +psx.input.port2.analogjoy.lstick_right + +psx.input.port2.analogjoy.lstick_up + +psx.input.port2.analogjoy.r1 + +psx.input.port2.analogjoy.r2 + +psx.input.port2.analogjoy.right + +psx.input.port2.analogjoy.rstick_down + +psx.input.port2.analogjoy.rstick_left + +psx.input.port2.analogjoy.rstick_right + +psx.input.port2.analogjoy.rstick_up + +psx.input.port2.analogjoy.select + +psx.input.port2.analogjoy.square + +psx.input.port2.analogjoy.start + +psx.input.port2.analogjoy.triangle + +psx.input.port2.analogjoy.up + +psx.input.port2.dancepad.circle + +psx.input.port2.dancepad.cross + +psx.input.port2.dancepad.down + +psx.input.port2.dancepad.left + +psx.input.port2.dancepad.right + +psx.input.port2.dancepad.select + +psx.input.port2.dancepad.square + +psx.input.port2.dancepad.start + +psx.input.port2.dancepad.triangle + +psx.input.port2.dancepad.up + +psx.input.port2.dualanalog.axis_scale 1.00 + +psx.input.port2.dualanalog.circle + +psx.input.port2.dualanalog.cross + +psx.input.port2.dualanalog.down + +psx.input.port2.dualanalog.l1 + +psx.input.port2.dualanalog.l2 + +psx.input.port2.dualanalog.l3 + +psx.input.port2.dualanalog.left + +psx.input.port2.dualanalog.lstick_down + +psx.input.port2.dualanalog.lstick_left + +psx.input.port2.dualanalog.lstick_right + +psx.input.port2.dualanalog.lstick_up + +psx.input.port2.dualanalog.r1 + +psx.input.port2.dualanalog.r2 + +psx.input.port2.dualanalog.r3 + +psx.input.port2.dualanalog.rapid_circle + +psx.input.port2.dualanalog.rapid_cross + +psx.input.port2.dualanalog.rapid_square + +psx.input.port2.dualanalog.rapid_triangle + +psx.input.port2.dualanalog.right + +psx.input.port2.dualanalog.rstick_down + +psx.input.port2.dualanalog.rstick_left + +psx.input.port2.dualanalog.rstick_right + +psx.input.port2.dualanalog.rstick_up + +psx.input.port2.dualanalog.select + +psx.input.port2.dualanalog.square + +psx.input.port2.dualanalog.start + +psx.input.port2.dualanalog.triangle + +psx.input.port2.dualanalog.up + +psx.input.port2.dualshock.analog + +psx.input.port2.dualshock.axis_scale 1.00 + +psx.input.port2.dualshock.circle + +psx.input.port2.dualshock.cross + +psx.input.port2.dualshock.down + +psx.input.port2.dualshock.l1 + +psx.input.port2.dualshock.l2 + +psx.input.port2.dualshock.l3 + +psx.input.port2.dualshock.left + +psx.input.port2.dualshock.lstick_down + +psx.input.port2.dualshock.lstick_left + +psx.input.port2.dualshock.lstick_right + +psx.input.port2.dualshock.lstick_up + +psx.input.port2.dualshock.r1 + +psx.input.port2.dualshock.r2 + +psx.input.port2.dualshock.r3 + +psx.input.port2.dualshock.rapid_circle + +psx.input.port2.dualshock.rapid_cross + +psx.input.port2.dualshock.rapid_square + +psx.input.port2.dualshock.rapid_triangle + +psx.input.port2.dualshock.right + +psx.input.port2.dualshock.rstick_down + +psx.input.port2.dualshock.rstick_left + +psx.input.port2.dualshock.rstick_right + +psx.input.port2.dualshock.rstick_up + +psx.input.port2.dualshock.select + +psx.input.port2.dualshock.square + +psx.input.port2.dualshock.start + +psx.input.port2.dualshock.triangle + +psx.input.port2.dualshock.up + +psx.input.port2.gamepad.circle + +psx.input.port2.gamepad.cross + +psx.input.port2.gamepad.down + +psx.input.port2.gamepad.l1 + +psx.input.port2.gamepad.l2 + +psx.input.port2.gamepad.left + +psx.input.port2.gamepad.r1 + +psx.input.port2.gamepad.r2 + +psx.input.port2.gamepad.rapid_circle + +psx.input.port2.gamepad.rapid_cross + +psx.input.port2.gamepad.rapid_square + +psx.input.port2.gamepad.rapid_triangle + +psx.input.port2.gamepad.right + +psx.input.port2.gamepad.select + +psx.input.port2.gamepad.square + +psx.input.port2.gamepad.start + +psx.input.port2.gamepad.triangle + +psx.input.port2.gamepad.up + +psx.input.port2.gun_chairs 0x00FF00 + +psx.input.port2.guncon.a mouse 0x0 button_right + +psx.input.port2.guncon.b mouse 0x0 button_middle + +psx.input.port2.guncon.offscreen_shot keyboard 0x0 44 + +psx.input.port2.guncon.trigger mouse 0x0 button_left + +psx.input.port2.guncon.x_axis mouse 0x0 cursor_x-+ + +psx.input.port2.guncon.y_axis mouse 0x0 cursor_y-+ + +psx.input.port2.justifier.o mouse 0x0 button_right + +psx.input.port2.justifier.offscreen_shot keyboard 0x0 44 + +psx.input.port2.justifier.start mouse 0x0 button_middle + +psx.input.port2.justifier.trigger mouse 0x0 button_left + +psx.input.port2.justifier.x_axis mouse 0x0 cursor_x-+ + +psx.input.port2.justifier.y_axis mouse 0x0 cursor_y-+ + +psx.input.port2.memcard 1 + +psx.input.port2.mouse.left mouse 0x0 button_left + +psx.input.port2.mouse.motion_down mouse 0x0 rel_y+ + +psx.input.port2.mouse.motion_left mouse 0x0 rel_x- + +psx.input.port2.mouse.motion_right mouse 0x0 rel_x+ + +psx.input.port2.mouse.motion_up mouse 0x0 rel_y- + +psx.input.port2.mouse.right mouse 0x0 button_right + +psx.input.port2.negcon.a + +psx.input.port2.negcon.b + +psx.input.port2.negcon.down + +psx.input.port2.negcon.i + +psx.input.port2.negcon.ii + +psx.input.port2.negcon.l + +psx.input.port2.negcon.left + +psx.input.port2.negcon.r + +psx.input.port2.negcon.right + +psx.input.port2.negcon.start + +psx.input.port2.negcon.twist_ccwise + +psx.input.port2.negcon.twist_cwise + +psx.input.port2.negcon.up + +psx.input.port3 gamepad + +psx.input.port3.analogjoy.axis_scale 1.00 + +psx.input.port3.analogjoy.circle + +psx.input.port3.analogjoy.cross + +psx.input.port3.analogjoy.down + +psx.input.port3.analogjoy.l1 + +psx.input.port3.analogjoy.l2 + +psx.input.port3.analogjoy.left + +psx.input.port3.analogjoy.lstick_down + +psx.input.port3.analogjoy.lstick_left + +psx.input.port3.analogjoy.lstick_right + +psx.input.port3.analogjoy.lstick_up + +psx.input.port3.analogjoy.r1 + +psx.input.port3.analogjoy.r2 + +psx.input.port3.analogjoy.right + +psx.input.port3.analogjoy.rstick_down + +psx.input.port3.analogjoy.rstick_left + +psx.input.port3.analogjoy.rstick_right + +psx.input.port3.analogjoy.rstick_up + +psx.input.port3.analogjoy.select + +psx.input.port3.analogjoy.square + +psx.input.port3.analogjoy.start + +psx.input.port3.analogjoy.triangle + +psx.input.port3.analogjoy.up + +psx.input.port3.dancepad.circle + +psx.input.port3.dancepad.cross + +psx.input.port3.dancepad.down + +psx.input.port3.dancepad.left + +psx.input.port3.dancepad.right + +psx.input.port3.dancepad.select + +psx.input.port3.dancepad.square + +psx.input.port3.dancepad.start + +psx.input.port3.dancepad.triangle + +psx.input.port3.dancepad.up + +psx.input.port3.dualanalog.axis_scale 1.00 + +psx.input.port3.dualanalog.circle + +psx.input.port3.dualanalog.cross + +psx.input.port3.dualanalog.down + +psx.input.port3.dualanalog.l1 + +psx.input.port3.dualanalog.l2 + +psx.input.port3.dualanalog.l3 + +psx.input.port3.dualanalog.left + +psx.input.port3.dualanalog.lstick_down + +psx.input.port3.dualanalog.lstick_left + +psx.input.port3.dualanalog.lstick_right + +psx.input.port3.dualanalog.lstick_up + +psx.input.port3.dualanalog.r1 + +psx.input.port3.dualanalog.r2 + +psx.input.port3.dualanalog.r3 + +psx.input.port3.dualanalog.rapid_circle + +psx.input.port3.dualanalog.rapid_cross + +psx.input.port3.dualanalog.rapid_square + +psx.input.port3.dualanalog.rapid_triangle + +psx.input.port3.dualanalog.right + +psx.input.port3.dualanalog.rstick_down + +psx.input.port3.dualanalog.rstick_left + +psx.input.port3.dualanalog.rstick_right + +psx.input.port3.dualanalog.rstick_up + +psx.input.port3.dualanalog.select + +psx.input.port3.dualanalog.square + +psx.input.port3.dualanalog.start + +psx.input.port3.dualanalog.triangle + +psx.input.port3.dualanalog.up + +psx.input.port3.dualshock.analog + +psx.input.port3.dualshock.axis_scale 1.00 + +psx.input.port3.dualshock.circle + +psx.input.port3.dualshock.cross + +psx.input.port3.dualshock.down + +psx.input.port3.dualshock.l1 + +psx.input.port3.dualshock.l2 + +psx.input.port3.dualshock.l3 + +psx.input.port3.dualshock.left + +psx.input.port3.dualshock.lstick_down + +psx.input.port3.dualshock.lstick_left + +psx.input.port3.dualshock.lstick_right + +psx.input.port3.dualshock.lstick_up + +psx.input.port3.dualshock.r1 + +psx.input.port3.dualshock.r2 + +psx.input.port3.dualshock.r3 + +psx.input.port3.dualshock.rapid_circle + +psx.input.port3.dualshock.rapid_cross + +psx.input.port3.dualshock.rapid_square + +psx.input.port3.dualshock.rapid_triangle + +psx.input.port3.dualshock.right + +psx.input.port3.dualshock.rstick_down + +psx.input.port3.dualshock.rstick_left + +psx.input.port3.dualshock.rstick_right + +psx.input.port3.dualshock.rstick_up + +psx.input.port3.dualshock.select + +psx.input.port3.dualshock.square + +psx.input.port3.dualshock.start + +psx.input.port3.dualshock.triangle + +psx.input.port3.dualshock.up + +psx.input.port3.gamepad.circle + +psx.input.port3.gamepad.cross + +psx.input.port3.gamepad.down + +psx.input.port3.gamepad.l1 + +psx.input.port3.gamepad.l2 + +psx.input.port3.gamepad.left + +psx.input.port3.gamepad.r1 + +psx.input.port3.gamepad.r2 + +psx.input.port3.gamepad.rapid_circle + +psx.input.port3.gamepad.rapid_cross + +psx.input.port3.gamepad.rapid_square + +psx.input.port3.gamepad.rapid_triangle + +psx.input.port3.gamepad.right + +psx.input.port3.gamepad.select + +psx.input.port3.gamepad.square + +psx.input.port3.gamepad.start + +psx.input.port3.gamepad.triangle + +psx.input.port3.gamepad.up + +psx.input.port3.gun_chairs 0xFF00FF + +psx.input.port3.guncon.a mouse 0x0 button_right + +psx.input.port3.guncon.b mouse 0x0 button_middle + +psx.input.port3.guncon.offscreen_shot keyboard 0x0 44 + +psx.input.port3.guncon.trigger mouse 0x0 button_left + +psx.input.port3.guncon.x_axis mouse 0x0 cursor_x-+ + +psx.input.port3.guncon.y_axis mouse 0x0 cursor_y-+ + +psx.input.port3.justifier.o + +psx.input.port3.justifier.offscreen_shot + +psx.input.port3.justifier.start + +psx.input.port3.justifier.trigger + +psx.input.port3.justifier.x_axis + +psx.input.port3.justifier.y_axis + +psx.input.port3.memcard 1 + +psx.input.port3.mouse.left mouse 0x0 button_left + +psx.input.port3.mouse.motion_down mouse 0x0 rel_y+ + +psx.input.port3.mouse.motion_left mouse 0x0 rel_x- + +psx.input.port3.mouse.motion_right mouse 0x0 rel_x+ + +psx.input.port3.mouse.motion_up mouse 0x0 rel_y- + +psx.input.port3.mouse.right mouse 0x0 button_right + +psx.input.port3.negcon.a + +psx.input.port3.negcon.b + +psx.input.port3.negcon.down + +psx.input.port3.negcon.i + +psx.input.port3.negcon.ii + +psx.input.port3.negcon.l + +psx.input.port3.negcon.left + +psx.input.port3.negcon.r + +psx.input.port3.negcon.right + +psx.input.port3.negcon.start + +psx.input.port3.negcon.twist_ccwise + +psx.input.port3.negcon.twist_cwise + +psx.input.port3.negcon.up + +psx.input.port4 gamepad + +psx.input.port4.analogjoy.axis_scale 1.00 + +psx.input.port4.analogjoy.circle + +psx.input.port4.analogjoy.cross + +psx.input.port4.analogjoy.down + +psx.input.port4.analogjoy.l1 + +psx.input.port4.analogjoy.l2 + +psx.input.port4.analogjoy.left + +psx.input.port4.analogjoy.lstick_down + +psx.input.port4.analogjoy.lstick_left + +psx.input.port4.analogjoy.lstick_right + +psx.input.port4.analogjoy.lstick_up + +psx.input.port4.analogjoy.r1 + +psx.input.port4.analogjoy.r2 + +psx.input.port4.analogjoy.right + +psx.input.port4.analogjoy.rstick_down + +psx.input.port4.analogjoy.rstick_left + +psx.input.port4.analogjoy.rstick_right + +psx.input.port4.analogjoy.rstick_up + +psx.input.port4.analogjoy.select + +psx.input.port4.analogjoy.square + +psx.input.port4.analogjoy.start + +psx.input.port4.analogjoy.triangle + +psx.input.port4.analogjoy.up + +psx.input.port4.dancepad.circle + +psx.input.port4.dancepad.cross + +psx.input.port4.dancepad.down + +psx.input.port4.dancepad.left + +psx.input.port4.dancepad.right + +psx.input.port4.dancepad.select + +psx.input.port4.dancepad.square + +psx.input.port4.dancepad.start + +psx.input.port4.dancepad.triangle + +psx.input.port4.dancepad.up + +psx.input.port4.dualanalog.axis_scale 1.00 + +psx.input.port4.dualanalog.circle + +psx.input.port4.dualanalog.cross + +psx.input.port4.dualanalog.down + +psx.input.port4.dualanalog.l1 + +psx.input.port4.dualanalog.l2 + +psx.input.port4.dualanalog.l3 + +psx.input.port4.dualanalog.left + +psx.input.port4.dualanalog.lstick_down + +psx.input.port4.dualanalog.lstick_left + +psx.input.port4.dualanalog.lstick_right + +psx.input.port4.dualanalog.lstick_up + +psx.input.port4.dualanalog.r1 + +psx.input.port4.dualanalog.r2 + +psx.input.port4.dualanalog.r3 + +psx.input.port4.dualanalog.rapid_circle + +psx.input.port4.dualanalog.rapid_cross + +psx.input.port4.dualanalog.rapid_square + +psx.input.port4.dualanalog.rapid_triangle + +psx.input.port4.dualanalog.right + +psx.input.port4.dualanalog.rstick_down + +psx.input.port4.dualanalog.rstick_left + +psx.input.port4.dualanalog.rstick_right + +psx.input.port4.dualanalog.rstick_up + +psx.input.port4.dualanalog.select + +psx.input.port4.dualanalog.square + +psx.input.port4.dualanalog.start + +psx.input.port4.dualanalog.triangle + +psx.input.port4.dualanalog.up + +psx.input.port4.dualshock.analog + +psx.input.port4.dualshock.axis_scale 1.00 + +psx.input.port4.dualshock.circle + +psx.input.port4.dualshock.cross + +psx.input.port4.dualshock.down + +psx.input.port4.dualshock.l1 + +psx.input.port4.dualshock.l2 + +psx.input.port4.dualshock.l3 + +psx.input.port4.dualshock.left + +psx.input.port4.dualshock.lstick_down + +psx.input.port4.dualshock.lstick_left + +psx.input.port4.dualshock.lstick_right + +psx.input.port4.dualshock.lstick_up + +psx.input.port4.dualshock.r1 + +psx.input.port4.dualshock.r2 + +psx.input.port4.dualshock.r3 + +psx.input.port4.dualshock.rapid_circle + +psx.input.port4.dualshock.rapid_cross + +psx.input.port4.dualshock.rapid_square + +psx.input.port4.dualshock.rapid_triangle + +psx.input.port4.dualshock.right + +psx.input.port4.dualshock.rstick_down + +psx.input.port4.dualshock.rstick_left + +psx.input.port4.dualshock.rstick_right + +psx.input.port4.dualshock.rstick_up + +psx.input.port4.dualshock.select + +psx.input.port4.dualshock.square + +psx.input.port4.dualshock.start + +psx.input.port4.dualshock.triangle + +psx.input.port4.dualshock.up + +psx.input.port4.gamepad.circle + +psx.input.port4.gamepad.cross + +psx.input.port4.gamepad.down + +psx.input.port4.gamepad.l1 + +psx.input.port4.gamepad.l2 + +psx.input.port4.gamepad.left + +psx.input.port4.gamepad.r1 + +psx.input.port4.gamepad.r2 + +psx.input.port4.gamepad.rapid_circle + +psx.input.port4.gamepad.rapid_cross + +psx.input.port4.gamepad.rapid_square + +psx.input.port4.gamepad.rapid_triangle + +psx.input.port4.gamepad.right + +psx.input.port4.gamepad.select + +psx.input.port4.gamepad.square + +psx.input.port4.gamepad.start + +psx.input.port4.gamepad.triangle + +psx.input.port4.gamepad.up + +psx.input.port4.gun_chairs 0xFF8000 + +psx.input.port4.guncon.a mouse 0x0 button_right + +psx.input.port4.guncon.b mouse 0x0 button_middle + +psx.input.port4.guncon.offscreen_shot keyboard 0x0 44 + +psx.input.port4.guncon.trigger mouse 0x0 button_left + +psx.input.port4.guncon.x_axis mouse 0x0 cursor_x-+ + +psx.input.port4.guncon.y_axis mouse 0x0 cursor_y-+ + +psx.input.port4.justifier.o + +psx.input.port4.justifier.offscreen_shot + +psx.input.port4.justifier.start + +psx.input.port4.justifier.trigger + +psx.input.port4.justifier.x_axis + +psx.input.port4.justifier.y_axis + +psx.input.port4.memcard 1 + +psx.input.port4.mouse.left mouse 0x0 button_left + +psx.input.port4.mouse.motion_down mouse 0x0 rel_y+ + +psx.input.port4.mouse.motion_left mouse 0x0 rel_x- + +psx.input.port4.mouse.motion_right mouse 0x0 rel_x+ + +psx.input.port4.mouse.motion_up mouse 0x0 rel_y- + +psx.input.port4.mouse.right mouse 0x0 button_right + +psx.input.port4.negcon.a + +psx.input.port4.negcon.b + +psx.input.port4.negcon.down + +psx.input.port4.negcon.i + +psx.input.port4.negcon.ii + +psx.input.port4.negcon.l + +psx.input.port4.negcon.left + +psx.input.port4.negcon.r + +psx.input.port4.negcon.right + +psx.input.port4.negcon.start + +psx.input.port4.negcon.twist_ccwise + +psx.input.port4.negcon.twist_cwise + +psx.input.port4.negcon.up + +psx.input.port5 gamepad + +psx.input.port5.analogjoy.axis_scale 1.00 + +psx.input.port5.analogjoy.circle + +psx.input.port5.analogjoy.cross + +psx.input.port5.analogjoy.down + +psx.input.port5.analogjoy.l1 + +psx.input.port5.analogjoy.l2 + +psx.input.port5.analogjoy.left + +psx.input.port5.analogjoy.lstick_down + +psx.input.port5.analogjoy.lstick_left + +psx.input.port5.analogjoy.lstick_right + +psx.input.port5.analogjoy.lstick_up + +psx.input.port5.analogjoy.r1 + +psx.input.port5.analogjoy.r2 + +psx.input.port5.analogjoy.right + +psx.input.port5.analogjoy.rstick_down + +psx.input.port5.analogjoy.rstick_left + +psx.input.port5.analogjoy.rstick_right + +psx.input.port5.analogjoy.rstick_up + +psx.input.port5.analogjoy.select + +psx.input.port5.analogjoy.square + +psx.input.port5.analogjoy.start + +psx.input.port5.analogjoy.triangle + +psx.input.port5.analogjoy.up + +psx.input.port5.dancepad.circle + +psx.input.port5.dancepad.cross + +psx.input.port5.dancepad.down + +psx.input.port5.dancepad.left + +psx.input.port5.dancepad.right + +psx.input.port5.dancepad.select + +psx.input.port5.dancepad.square + +psx.input.port5.dancepad.start + +psx.input.port5.dancepad.triangle + +psx.input.port5.dancepad.up + +psx.input.port5.dualanalog.axis_scale 1.00 + +psx.input.port5.dualanalog.circle + +psx.input.port5.dualanalog.cross + +psx.input.port5.dualanalog.down + +psx.input.port5.dualanalog.l1 + +psx.input.port5.dualanalog.l2 + +psx.input.port5.dualanalog.l3 + +psx.input.port5.dualanalog.left + +psx.input.port5.dualanalog.lstick_down + +psx.input.port5.dualanalog.lstick_left + +psx.input.port5.dualanalog.lstick_right + +psx.input.port5.dualanalog.lstick_up + +psx.input.port5.dualanalog.r1 + +psx.input.port5.dualanalog.r2 + +psx.input.port5.dualanalog.r3 + +psx.input.port5.dualanalog.rapid_circle + +psx.input.port5.dualanalog.rapid_cross + +psx.input.port5.dualanalog.rapid_square + +psx.input.port5.dualanalog.rapid_triangle + +psx.input.port5.dualanalog.right + +psx.input.port5.dualanalog.rstick_down + +psx.input.port5.dualanalog.rstick_left + +psx.input.port5.dualanalog.rstick_right + +psx.input.port5.dualanalog.rstick_up + +psx.input.port5.dualanalog.select + +psx.input.port5.dualanalog.square + +psx.input.port5.dualanalog.start + +psx.input.port5.dualanalog.triangle + +psx.input.port5.dualanalog.up + +psx.input.port5.dualshock.analog + +psx.input.port5.dualshock.axis_scale 1.00 + +psx.input.port5.dualshock.circle + +psx.input.port5.dualshock.cross + +psx.input.port5.dualshock.down + +psx.input.port5.dualshock.l1 + +psx.input.port5.dualshock.l2 + +psx.input.port5.dualshock.l3 + +psx.input.port5.dualshock.left + +psx.input.port5.dualshock.lstick_down + +psx.input.port5.dualshock.lstick_left + +psx.input.port5.dualshock.lstick_right + +psx.input.port5.dualshock.lstick_up + +psx.input.port5.dualshock.r1 + +psx.input.port5.dualshock.r2 + +psx.input.port5.dualshock.r3 + +psx.input.port5.dualshock.rapid_circle + +psx.input.port5.dualshock.rapid_cross + +psx.input.port5.dualshock.rapid_square + +psx.input.port5.dualshock.rapid_triangle + +psx.input.port5.dualshock.right + +psx.input.port5.dualshock.rstick_down + +psx.input.port5.dualshock.rstick_left + +psx.input.port5.dualshock.rstick_right + +psx.input.port5.dualshock.rstick_up + +psx.input.port5.dualshock.select + +psx.input.port5.dualshock.square + +psx.input.port5.dualshock.start + +psx.input.port5.dualshock.triangle + +psx.input.port5.dualshock.up + +psx.input.port5.gamepad.circle + +psx.input.port5.gamepad.cross + +psx.input.port5.gamepad.down + +psx.input.port5.gamepad.l1 + +psx.input.port5.gamepad.l2 + +psx.input.port5.gamepad.left + +psx.input.port5.gamepad.r1 + +psx.input.port5.gamepad.r2 + +psx.input.port5.gamepad.rapid_circle + +psx.input.port5.gamepad.rapid_cross + +psx.input.port5.gamepad.rapid_square + +psx.input.port5.gamepad.rapid_triangle + +psx.input.port5.gamepad.right + +psx.input.port5.gamepad.select + +psx.input.port5.gamepad.square + +psx.input.port5.gamepad.start + +psx.input.port5.gamepad.triangle + +psx.input.port5.gamepad.up + +psx.input.port5.gun_chairs 0xFFFF00 + +psx.input.port5.guncon.a mouse 0x0 button_right + +psx.input.port5.guncon.b mouse 0x0 button_middle + +psx.input.port5.guncon.offscreen_shot keyboard 0x0 44 + +psx.input.port5.guncon.trigger mouse 0x0 button_left + +psx.input.port5.guncon.x_axis mouse 0x0 cursor_x-+ + +psx.input.port5.guncon.y_axis mouse 0x0 cursor_y-+ + +psx.input.port5.justifier.o + +psx.input.port5.justifier.offscreen_shot + +psx.input.port5.justifier.start + +psx.input.port5.justifier.trigger + +psx.input.port5.justifier.x_axis + +psx.input.port5.justifier.y_axis + +psx.input.port5.memcard 1 + +psx.input.port5.mouse.left mouse 0x0 button_left + +psx.input.port5.mouse.motion_down mouse 0x0 rel_y+ + +psx.input.port5.mouse.motion_left mouse 0x0 rel_x- + +psx.input.port5.mouse.motion_right mouse 0x0 rel_x+ + +psx.input.port5.mouse.motion_up mouse 0x0 rel_y- + +psx.input.port5.mouse.right mouse 0x0 button_right + +psx.input.port5.negcon.a + +psx.input.port5.negcon.b + +psx.input.port5.negcon.down + +psx.input.port5.negcon.i + +psx.input.port5.negcon.ii + +psx.input.port5.negcon.l + +psx.input.port5.negcon.left + +psx.input.port5.negcon.r + +psx.input.port5.negcon.right + +psx.input.port5.negcon.start + +psx.input.port5.negcon.twist_ccwise + +psx.input.port5.negcon.twist_cwise + +psx.input.port5.negcon.up + +psx.input.port6 gamepad + +psx.input.port6.analogjoy.axis_scale 1.00 + +psx.input.port6.analogjoy.circle + +psx.input.port6.analogjoy.cross + +psx.input.port6.analogjoy.down + +psx.input.port6.analogjoy.l1 + +psx.input.port6.analogjoy.l2 + +psx.input.port6.analogjoy.left + +psx.input.port6.analogjoy.lstick_down + +psx.input.port6.analogjoy.lstick_left + +psx.input.port6.analogjoy.lstick_right + +psx.input.port6.analogjoy.lstick_up + +psx.input.port6.analogjoy.r1 + +psx.input.port6.analogjoy.r2 + +psx.input.port6.analogjoy.right + +psx.input.port6.analogjoy.rstick_down + +psx.input.port6.analogjoy.rstick_left + +psx.input.port6.analogjoy.rstick_right + +psx.input.port6.analogjoy.rstick_up + +psx.input.port6.analogjoy.select + +psx.input.port6.analogjoy.square + +psx.input.port6.analogjoy.start + +psx.input.port6.analogjoy.triangle + +psx.input.port6.analogjoy.up + +psx.input.port6.dancepad.circle + +psx.input.port6.dancepad.cross + +psx.input.port6.dancepad.down + +psx.input.port6.dancepad.left + +psx.input.port6.dancepad.right + +psx.input.port6.dancepad.select + +psx.input.port6.dancepad.square + +psx.input.port6.dancepad.start + +psx.input.port6.dancepad.triangle + +psx.input.port6.dancepad.up + +psx.input.port6.dualanalog.axis_scale 1.00 + +psx.input.port6.dualanalog.circle + +psx.input.port6.dualanalog.cross + +psx.input.port6.dualanalog.down + +psx.input.port6.dualanalog.l1 + +psx.input.port6.dualanalog.l2 + +psx.input.port6.dualanalog.l3 + +psx.input.port6.dualanalog.left + +psx.input.port6.dualanalog.lstick_down + +psx.input.port6.dualanalog.lstick_left + +psx.input.port6.dualanalog.lstick_right + +psx.input.port6.dualanalog.lstick_up + +psx.input.port6.dualanalog.r1 + +psx.input.port6.dualanalog.r2 + +psx.input.port6.dualanalog.r3 + +psx.input.port6.dualanalog.rapid_circle + +psx.input.port6.dualanalog.rapid_cross + +psx.input.port6.dualanalog.rapid_square + +psx.input.port6.dualanalog.rapid_triangle + +psx.input.port6.dualanalog.right + +psx.input.port6.dualanalog.rstick_down + +psx.input.port6.dualanalog.rstick_left + +psx.input.port6.dualanalog.rstick_right + +psx.input.port6.dualanalog.rstick_up + +psx.input.port6.dualanalog.select + +psx.input.port6.dualanalog.square + +psx.input.port6.dualanalog.start + +psx.input.port6.dualanalog.triangle + +psx.input.port6.dualanalog.up + +psx.input.port6.dualshock.analog + +psx.input.port6.dualshock.axis_scale 1.00 + +psx.input.port6.dualshock.circle + +psx.input.port6.dualshock.cross + +psx.input.port6.dualshock.down + +psx.input.port6.dualshock.l1 + +psx.input.port6.dualshock.l2 + +psx.input.port6.dualshock.l3 + +psx.input.port6.dualshock.left + +psx.input.port6.dualshock.lstick_down + +psx.input.port6.dualshock.lstick_left + +psx.input.port6.dualshock.lstick_right + +psx.input.port6.dualshock.lstick_up + +psx.input.port6.dualshock.r1 + +psx.input.port6.dualshock.r2 + +psx.input.port6.dualshock.r3 + +psx.input.port6.dualshock.rapid_circle + +psx.input.port6.dualshock.rapid_cross + +psx.input.port6.dualshock.rapid_square + +psx.input.port6.dualshock.rapid_triangle + +psx.input.port6.dualshock.right + +psx.input.port6.dualshock.rstick_down + +psx.input.port6.dualshock.rstick_left + +psx.input.port6.dualshock.rstick_right + +psx.input.port6.dualshock.rstick_up + +psx.input.port6.dualshock.select + +psx.input.port6.dualshock.square + +psx.input.port6.dualshock.start + +psx.input.port6.dualshock.triangle + +psx.input.port6.dualshock.up + +psx.input.port6.gamepad.circle + +psx.input.port6.gamepad.cross + +psx.input.port6.gamepad.down + +psx.input.port6.gamepad.l1 + +psx.input.port6.gamepad.l2 + +psx.input.port6.gamepad.left + +psx.input.port6.gamepad.r1 + +psx.input.port6.gamepad.r2 + +psx.input.port6.gamepad.rapid_circle + +psx.input.port6.gamepad.rapid_cross + +psx.input.port6.gamepad.rapid_square + +psx.input.port6.gamepad.rapid_triangle + +psx.input.port6.gamepad.right + +psx.input.port6.gamepad.select + +psx.input.port6.gamepad.square + +psx.input.port6.gamepad.start + +psx.input.port6.gamepad.triangle + +psx.input.port6.gamepad.up + +psx.input.port6.gun_chairs 0x00FFFF + +psx.input.port6.guncon.a mouse 0x0 button_right + +psx.input.port6.guncon.b mouse 0x0 button_middle + +psx.input.port6.guncon.offscreen_shot keyboard 0x0 44 + +psx.input.port6.guncon.trigger mouse 0x0 button_left + +psx.input.port6.guncon.x_axis mouse 0x0 cursor_x-+ + +psx.input.port6.guncon.y_axis mouse 0x0 cursor_y-+ + +psx.input.port6.justifier.o + +psx.input.port6.justifier.offscreen_shot + +psx.input.port6.justifier.start + +psx.input.port6.justifier.trigger + +psx.input.port6.justifier.x_axis + +psx.input.port6.justifier.y_axis + +psx.input.port6.memcard 1 + +psx.input.port6.mouse.left mouse 0x0 button_left + +psx.input.port6.mouse.motion_down mouse 0x0 rel_y+ + +psx.input.port6.mouse.motion_left mouse 0x0 rel_x- + +psx.input.port6.mouse.motion_right mouse 0x0 rel_x+ + +psx.input.port6.mouse.motion_up mouse 0x0 rel_y- + +psx.input.port6.mouse.right mouse 0x0 button_right + +psx.input.port6.negcon.a + +psx.input.port6.negcon.b + +psx.input.port6.negcon.down + +psx.input.port6.negcon.i + +psx.input.port6.negcon.ii + +psx.input.port6.negcon.l + +psx.input.port6.negcon.left + +psx.input.port6.negcon.r + +psx.input.port6.negcon.right + +psx.input.port6.negcon.start + +psx.input.port6.negcon.twist_ccwise + +psx.input.port6.negcon.twist_cwise + +psx.input.port6.negcon.up + +psx.input.port7 gamepad + +psx.input.port7.analogjoy.axis_scale 1.00 + +psx.input.port7.analogjoy.circle + +psx.input.port7.analogjoy.cross + +psx.input.port7.analogjoy.down + +psx.input.port7.analogjoy.l1 + +psx.input.port7.analogjoy.l2 + +psx.input.port7.analogjoy.left + +psx.input.port7.analogjoy.lstick_down + +psx.input.port7.analogjoy.lstick_left + +psx.input.port7.analogjoy.lstick_right + +psx.input.port7.analogjoy.lstick_up + +psx.input.port7.analogjoy.r1 + +psx.input.port7.analogjoy.r2 + +psx.input.port7.analogjoy.right + +psx.input.port7.analogjoy.rstick_down + +psx.input.port7.analogjoy.rstick_left + +psx.input.port7.analogjoy.rstick_right + +psx.input.port7.analogjoy.rstick_up + +psx.input.port7.analogjoy.select + +psx.input.port7.analogjoy.square + +psx.input.port7.analogjoy.start + +psx.input.port7.analogjoy.triangle + +psx.input.port7.analogjoy.up + +psx.input.port7.dancepad.circle + +psx.input.port7.dancepad.cross + +psx.input.port7.dancepad.down + +psx.input.port7.dancepad.left + +psx.input.port7.dancepad.right + +psx.input.port7.dancepad.select + +psx.input.port7.dancepad.square + +psx.input.port7.dancepad.start + +psx.input.port7.dancepad.triangle + +psx.input.port7.dancepad.up + +psx.input.port7.dualanalog.axis_scale 1.00 + +psx.input.port7.dualanalog.circle + +psx.input.port7.dualanalog.cross + +psx.input.port7.dualanalog.down + +psx.input.port7.dualanalog.l1 + +psx.input.port7.dualanalog.l2 + +psx.input.port7.dualanalog.l3 + +psx.input.port7.dualanalog.left + +psx.input.port7.dualanalog.lstick_down + +psx.input.port7.dualanalog.lstick_left + +psx.input.port7.dualanalog.lstick_right + +psx.input.port7.dualanalog.lstick_up + +psx.input.port7.dualanalog.r1 + +psx.input.port7.dualanalog.r2 + +psx.input.port7.dualanalog.r3 + +psx.input.port7.dualanalog.rapid_circle + +psx.input.port7.dualanalog.rapid_cross + +psx.input.port7.dualanalog.rapid_square + +psx.input.port7.dualanalog.rapid_triangle + +psx.input.port7.dualanalog.right + +psx.input.port7.dualanalog.rstick_down + +psx.input.port7.dualanalog.rstick_left + +psx.input.port7.dualanalog.rstick_right + +psx.input.port7.dualanalog.rstick_up + +psx.input.port7.dualanalog.select + +psx.input.port7.dualanalog.square + +psx.input.port7.dualanalog.start + +psx.input.port7.dualanalog.triangle + +psx.input.port7.dualanalog.up + +psx.input.port7.dualshock.analog + +psx.input.port7.dualshock.axis_scale 1.00 + +psx.input.port7.dualshock.circle + +psx.input.port7.dualshock.cross + +psx.input.port7.dualshock.down + +psx.input.port7.dualshock.l1 + +psx.input.port7.dualshock.l2 + +psx.input.port7.dualshock.l3 + +psx.input.port7.dualshock.left + +psx.input.port7.dualshock.lstick_down + +psx.input.port7.dualshock.lstick_left + +psx.input.port7.dualshock.lstick_right + +psx.input.port7.dualshock.lstick_up + +psx.input.port7.dualshock.r1 + +psx.input.port7.dualshock.r2 + +psx.input.port7.dualshock.r3 + +psx.input.port7.dualshock.rapid_circle + +psx.input.port7.dualshock.rapid_cross + +psx.input.port7.dualshock.rapid_square + +psx.input.port7.dualshock.rapid_triangle + +psx.input.port7.dualshock.right + +psx.input.port7.dualshock.rstick_down + +psx.input.port7.dualshock.rstick_left + +psx.input.port7.dualshock.rstick_right + +psx.input.port7.dualshock.rstick_up + +psx.input.port7.dualshock.select + +psx.input.port7.dualshock.square + +psx.input.port7.dualshock.start + +psx.input.port7.dualshock.triangle + +psx.input.port7.dualshock.up + +psx.input.port7.gamepad.circle + +psx.input.port7.gamepad.cross + +psx.input.port7.gamepad.down + +psx.input.port7.gamepad.l1 + +psx.input.port7.gamepad.l2 + +psx.input.port7.gamepad.left + +psx.input.port7.gamepad.r1 + +psx.input.port7.gamepad.r2 + +psx.input.port7.gamepad.rapid_circle + +psx.input.port7.gamepad.rapid_cross + +psx.input.port7.gamepad.rapid_square + +psx.input.port7.gamepad.rapid_triangle + +psx.input.port7.gamepad.right + +psx.input.port7.gamepad.select + +psx.input.port7.gamepad.square + +psx.input.port7.gamepad.start + +psx.input.port7.gamepad.triangle + +psx.input.port7.gamepad.up + +psx.input.port7.gun_chairs 0x0080FF + +psx.input.port7.guncon.a mouse 0x0 button_right + +psx.input.port7.guncon.b mouse 0x0 button_middle + +psx.input.port7.guncon.offscreen_shot keyboard 0x0 44 + +psx.input.port7.guncon.trigger mouse 0x0 button_left + +psx.input.port7.guncon.x_axis mouse 0x0 cursor_x-+ + +psx.input.port7.guncon.y_axis mouse 0x0 cursor_y-+ + +psx.input.port7.justifier.o + +psx.input.port7.justifier.offscreen_shot + +psx.input.port7.justifier.start + +psx.input.port7.justifier.trigger + +psx.input.port7.justifier.x_axis + +psx.input.port7.justifier.y_axis + +psx.input.port7.memcard 1 + +psx.input.port7.mouse.left mouse 0x0 button_left + +psx.input.port7.mouse.motion_down mouse 0x0 rel_y+ + +psx.input.port7.mouse.motion_left mouse 0x0 rel_x- + +psx.input.port7.mouse.motion_right mouse 0x0 rel_x+ + +psx.input.port7.mouse.motion_up mouse 0x0 rel_y- + +psx.input.port7.mouse.right mouse 0x0 button_right + +psx.input.port7.negcon.a + +psx.input.port7.negcon.b + +psx.input.port7.negcon.down + +psx.input.port7.negcon.i + +psx.input.port7.negcon.ii + +psx.input.port7.negcon.l + +psx.input.port7.negcon.left + +psx.input.port7.negcon.r + +psx.input.port7.negcon.right + +psx.input.port7.negcon.start + +psx.input.port7.negcon.twist_ccwise + +psx.input.port7.negcon.twist_cwise + +psx.input.port7.negcon.up + +psx.input.port8 gamepad + +psx.input.port8.analogjoy.axis_scale 1.00 + +psx.input.port8.analogjoy.circle + +psx.input.port8.analogjoy.cross + +psx.input.port8.analogjoy.down + +psx.input.port8.analogjoy.l1 + +psx.input.port8.analogjoy.l2 + +psx.input.port8.analogjoy.left + +psx.input.port8.analogjoy.lstick_down + +psx.input.port8.analogjoy.lstick_left + +psx.input.port8.analogjoy.lstick_right + +psx.input.port8.analogjoy.lstick_up + +psx.input.port8.analogjoy.r1 + +psx.input.port8.analogjoy.r2 + +psx.input.port8.analogjoy.right + +psx.input.port8.analogjoy.rstick_down + +psx.input.port8.analogjoy.rstick_left + +psx.input.port8.analogjoy.rstick_right + +psx.input.port8.analogjoy.rstick_up + +psx.input.port8.analogjoy.select + +psx.input.port8.analogjoy.square + +psx.input.port8.analogjoy.start + +psx.input.port8.analogjoy.triangle + +psx.input.port8.analogjoy.up + +psx.input.port8.dancepad.circle + +psx.input.port8.dancepad.cross + +psx.input.port8.dancepad.down + +psx.input.port8.dancepad.left + +psx.input.port8.dancepad.right + +psx.input.port8.dancepad.select + +psx.input.port8.dancepad.square + +psx.input.port8.dancepad.start + +psx.input.port8.dancepad.triangle + +psx.input.port8.dancepad.up + +psx.input.port8.dualanalog.axis_scale 1.00 + +psx.input.port8.dualanalog.circle + +psx.input.port8.dualanalog.cross + +psx.input.port8.dualanalog.down + +psx.input.port8.dualanalog.l1 + +psx.input.port8.dualanalog.l2 + +psx.input.port8.dualanalog.l3 + +psx.input.port8.dualanalog.left + +psx.input.port8.dualanalog.lstick_down + +psx.input.port8.dualanalog.lstick_left + +psx.input.port8.dualanalog.lstick_right + +psx.input.port8.dualanalog.lstick_up + +psx.input.port8.dualanalog.r1 + +psx.input.port8.dualanalog.r2 + +psx.input.port8.dualanalog.r3 + +psx.input.port8.dualanalog.rapid_circle + +psx.input.port8.dualanalog.rapid_cross + +psx.input.port8.dualanalog.rapid_square + +psx.input.port8.dualanalog.rapid_triangle + +psx.input.port8.dualanalog.right + +psx.input.port8.dualanalog.rstick_down + +psx.input.port8.dualanalog.rstick_left + +psx.input.port8.dualanalog.rstick_right + +psx.input.port8.dualanalog.rstick_up + +psx.input.port8.dualanalog.select + +psx.input.port8.dualanalog.square + +psx.input.port8.dualanalog.start + +psx.input.port8.dualanalog.triangle + +psx.input.port8.dualanalog.up + +psx.input.port8.dualshock.analog + +psx.input.port8.dualshock.axis_scale 1.00 + +psx.input.port8.dualshock.circle + +psx.input.port8.dualshock.cross + +psx.input.port8.dualshock.down + +psx.input.port8.dualshock.l1 + +psx.input.port8.dualshock.l2 + +psx.input.port8.dualshock.l3 + +psx.input.port8.dualshock.left + +psx.input.port8.dualshock.lstick_down + +psx.input.port8.dualshock.lstick_left + +psx.input.port8.dualshock.lstick_right + +psx.input.port8.dualshock.lstick_up + +psx.input.port8.dualshock.r1 + +psx.input.port8.dualshock.r2 + +psx.input.port8.dualshock.r3 + +psx.input.port8.dualshock.rapid_circle + +psx.input.port8.dualshock.rapid_cross + +psx.input.port8.dualshock.rapid_square + +psx.input.port8.dualshock.rapid_triangle + +psx.input.port8.dualshock.right + +psx.input.port8.dualshock.rstick_down + +psx.input.port8.dualshock.rstick_left + +psx.input.port8.dualshock.rstick_right + +psx.input.port8.dualshock.rstick_up + +psx.input.port8.dualshock.select + +psx.input.port8.dualshock.square + +psx.input.port8.dualshock.start + +psx.input.port8.dualshock.triangle + +psx.input.port8.dualshock.up + +psx.input.port8.gamepad.circle + +psx.input.port8.gamepad.cross + +psx.input.port8.gamepad.down + +psx.input.port8.gamepad.l1 + +psx.input.port8.gamepad.l2 + +psx.input.port8.gamepad.left + +psx.input.port8.gamepad.r1 + +psx.input.port8.gamepad.r2 + +psx.input.port8.gamepad.rapid_circle + +psx.input.port8.gamepad.rapid_cross + +psx.input.port8.gamepad.rapid_square + +psx.input.port8.gamepad.rapid_triangle + +psx.input.port8.gamepad.right + +psx.input.port8.gamepad.select + +psx.input.port8.gamepad.square + +psx.input.port8.gamepad.start + +psx.input.port8.gamepad.triangle + +psx.input.port8.gamepad.up + +psx.input.port8.gun_chairs 0x8000FF + +psx.input.port8.guncon.a mouse 0x0 button_right + +psx.input.port8.guncon.b mouse 0x0 button_middle + +psx.input.port8.guncon.offscreen_shot keyboard 0x0 44 + +psx.input.port8.guncon.trigger mouse 0x0 button_left + +psx.input.port8.guncon.x_axis mouse 0x0 cursor_x-+ + +psx.input.port8.guncon.y_axis mouse 0x0 cursor_y-+ + +psx.input.port8.justifier.o + +psx.input.port8.justifier.offscreen_shot + +psx.input.port8.justifier.start + +psx.input.port8.justifier.trigger + +psx.input.port8.justifier.x_axis + +psx.input.port8.justifier.y_axis + +psx.input.port8.memcard 1 + +psx.input.port8.mouse.left mouse 0x0 button_left + +psx.input.port8.mouse.motion_down mouse 0x0 rel_y+ + +psx.input.port8.mouse.motion_left mouse 0x0 rel_x- + +psx.input.port8.mouse.motion_right mouse 0x0 rel_x+ + +psx.input.port8.mouse.motion_up mouse 0x0 rel_y- + +psx.input.port8.mouse.right mouse 0x0 button_right + +psx.input.port8.negcon.a + +psx.input.port8.negcon.b + +psx.input.port8.negcon.down + +psx.input.port8.negcon.i + +psx.input.port8.negcon.ii + +psx.input.port8.negcon.l + +psx.input.port8.negcon.left + +psx.input.port8.negcon.r + +psx.input.port8.negcon.right + +psx.input.port8.negcon.start + +psx.input.port8.negcon.twist_ccwise + +psx.input.port8.negcon.twist_cwise + +psx.input.port8.negcon.up + +psx.input.pport1.multitap 0 + +psx.input.pport2.multitap 0 + +psx.region_autodetect 1 + +psx.region_default jp + +psx.scanlines 0 + +psx.shader none + +psx.shader.goat.fprog 0 + +psx.shader.goat.hdiv 0.50 + +psx.shader.goat.pat goatron + +psx.shader.goat.slen 1 + +psx.shader.goat.tp 0.50 + +psx.shader.goat.vdiv 0.50 + +psx.slend 239 + +psx.slendp 287 + +psx.slstart 0 + +psx.slstartp 0 + +psx.special none + +psx.spu.resamp_quality 5 + +psx.stretch aspect + +psx.tblur 0 + +psx.tblur.accum 0 + +psx.tblur.accum.amount 50 + +psx.videoip 1 + +psx.xres 0 + +psx.xscale 3.000000 + +psx.xscalefs 1.000000 + +psx.yres 0 + +psx.yscale 3.000000 + +psx.yscalefs 1.000000 + +sasplay.enable 1 + +sasplay.forcemono 0 + +sasplay.input.builtin.controller.next_song keyboard 0x0 7 || keyboard 0x0 79 + +sasplay.input.builtin.controller.next_song_10 keyboard 0x0 26 || keyboard 0x0 82 + +sasplay.input.builtin.controller.previous_song keyboard 0x0 4 || keyboard 0x0 80 + +sasplay.input.builtin.controller.previous_song_10 keyboard 0x0 22 || keyboard 0x0 81 + +sasplay.input.builtin.controller.restart keyboard 0x0 40 + +sasplay.resamp_quality 5 + +sasplay.scanlines 0 + +sasplay.shader none + +sasplay.shader.goat.fprog 0 + +sasplay.shader.goat.hdiv 0.50 + +sasplay.shader.goat.pat goatron + +sasplay.shader.goat.slen 1 + +sasplay.shader.goat.tp 0.50 + +sasplay.shader.goat.vdiv 0.50 + +sasplay.special none + +sasplay.stretch aspect + +sasplay.tblur 0 + +sasplay.tblur.accum 0 + +sasplay.tblur.accum.amount 50 + +sasplay.videoip 0 + +sasplay.xres 0 + +sasplay.xscale 2.000000 + +sasplay.xscalefs 1.000000 + +sasplay.yres 0 + +sasplay.yscale 2.000000 + +sasplay.yscalefs 1.000000 + +ss.affinity.vdp2 0 + +ss.bios_jp sega_101.bin + +ss.bios_na_eu mpr-17933.bin + +ss.bios_sanity 1 + +ss.bios_stv_eu epr-17954a.ic8 + +ss.bios_stv_jp epr-20091.ic8 + +ss.bios_stv_na epr-17952a.ic8 + +ss.cart auto + +ss.cart.auto_default backup + +ss.cart.kof95_path mpr-18811-mx.ic1 + +ss.cart.ultraman_path mpr-19367-mx.ic1 + +ss.cd_sanity 1 + +ss.correct_aspect 1 + +ss.dbg_exe_cdpath + +ss.debugger.disfontsize 5x7 + +ss.debugger.memcharenc SJIS + +ss.enable 1 + +ss.forcemono 0 + +ss.h_blend 0 + +ss.h_overscan 1 + +ss.input.builtin.builtin.smpc_reset + +ss.input.builtin.builtin.stv_pause keyboard 0x0 86 && keyboard 0x0 88 + +ss.input.builtin.builtin.stv_service keyboard 0x0 86 && keyboard 0x0 87 + +ss.input.builtin.builtin.stv_test keyboard 0x0 86 && keyboard 0x0 84 + +ss.input.mouse_sensitivity 0.50 + +ss.input.port1 gamepad + +ss.input.port1.3dpad.a joystick @GUID1@ @DEVICE_BTN_WEST@ + +ss.input.port1.3dpad.analog_down joystick @GUID1@ @DEVICE_BTN_AL_DOWN@ + +ss.input.port1.3dpad.analog_left joystick @GUID1@ @DEVICE_BTN_AL_LEFT@ + +ss.input.port1.3dpad.analog_right joystick @GUID1@ @DEVICE_BTN_AL_RIGHT@ + +ss.input.port1.3dpad.analog_up joystick @GUID1@ @DEVICE_BTN_AL_UP@ + +ss.input.port1.3dpad.b joystick @GUID1@ @DEVICE_BTN_SOUTH@ + +ss.input.port1.3dpad.c joystick @GUID1@ @DEVICE_BTN_TR@ + +ss.input.port1.3dpad.down joystick @GUID1@ @DEVICE_BTN_DPAD_DOWN@ + +ss.input.port1.3dpad.left joystick @GUID1@ @DEVICE_BTN_DPAD_LEFT@ + +ss.input.port1.3dpad.ls joystick @GUID1@ @DEVICE_BTN_TL2@ || joystick @GUID1@ @DEVICE_BTN_TL2_MINUS@ + +ss.input.port1.3dpad.mode joystick + +ss.input.port1.3dpad.mode.defpos analog + +ss.input.port1.3dpad.right joystick @GUID1@ @DEVICE_BTN_DPAD_RIGHT@ + +ss.input.port1.3dpad.rs joystick @GUID1@ @DEVICE_BTN_TR2@ || joystick @GUID1@ @DEVICE_BTN_TR2_MINUS@ + +ss.input.port1.3dpad.start joystick @GUID1@ @DEVICE_BTN_START@ + +ss.input.port1.3dpad.up joystick @GUID1@ @DEVICE_BTN_DPAD_UP@ + +ss.input.port1.3dpad.x joystick @GUID1@ @DEVICE_BTN_EAST@ + +ss.input.port1.3dpad.y joystick @GUID1@ @DEVICE_BTN_NORTH@ + +ss.input.port1.3dpad.z joystick @GUID1@ @DEVICE_BTN_TL@ + +ss.input.port1.dmission.a + +ss.input.port1.dmission.afa + +ss.input.port1.dmission.afa.defpos off + +ss.input.port1.dmission.afb + +ss.input.port1.dmission.afb.defpos off + +ss.input.port1.dmission.afc + +ss.input.port1.dmission.afc.defpos off + +ss.input.port1.dmission.afl + +ss.input.port1.dmission.afl.defpos off + +ss.input.port1.dmission.afr + +ss.input.port1.dmission.afr.defpos off + +ss.input.port1.dmission.afspeed + +ss.input.port1.dmission.afspeed.defpos 1 + +ss.input.port1.dmission.afx + +ss.input.port1.dmission.afx.defpos off + +ss.input.port1.dmission.afy + +ss.input.port1.dmission.afy.defpos off + +ss.input.port1.dmission.afz + +ss.input.port1.dmission.afz.defpos off + +ss.input.port1.dmission.b + +ss.input.port1.dmission.c + +ss.input.port1.dmission.l + +ss.input.port1.dmission.lstick_back + +ss.input.port1.dmission.lstick_fore + +ss.input.port1.dmission.lstick_left + +ss.input.port1.dmission.lstick_right + +ss.input.port1.dmission.lthrottle_down + +ss.input.port1.dmission.lthrottle_up + +ss.input.port1.dmission.r + +ss.input.port1.dmission.rstick_back + +ss.input.port1.dmission.rstick_fore + +ss.input.port1.dmission.rstick_left + +ss.input.port1.dmission.rstick_right + +ss.input.port1.dmission.rthrottle_down + +ss.input.port1.dmission.rthrottle_up + +ss.input.port1.dmission.start + +ss.input.port1.dmission.x + +ss.input.port1.dmission.y + +ss.input.port1.dmission.z + +ss.input.port1.gamepad.a joystick @GUID1@ @DEVICE_BTN_WEST@ + +ss.input.port1.gamepad.b joystick @GUID1@ @DEVICE_BTN_SOUTH@ + +ss.input.port1.gamepad.c joystick @GUID1@ @DEVICE_BTN_TR@ + +ss.input.port1.gamepad.down joystick @GUID1@ @DEVICE_BTN_DPAD_DOWN@ + +ss.input.port1.gamepad.left joystick @GUID1@ @DEVICE_BTN_DPAD_LEFT@ + +ss.input.port1.gamepad.ls joystick @GUID1@ @DEVICE_BTN_TL2@ + +ss.input.port1.gamepad.right joystick @GUID1@ @DEVICE_BTN_DPAD_RIGHT@ + +ss.input.port1.gamepad.rs joystick @GUID1@ @DEVICE_BTN_TR2@ + +ss.input.port1.gamepad.start joystick @GUID1@ @DEVICE_BTN_START@ + +ss.input.port1.gamepad.up joystick @GUID1@ @DEVICE_BTN_DPAD_UP@ + +ss.input.port1.gamepad.x joystick @GUID1@ @DEVICE_BTN_EAST@ + +ss.input.port1.gamepad.y joystick @GUID1@ @DEVICE_BTN_NORTH@ + +ss.input.port1.gamepad.z joystick @GUID1@ @DEVICE_BTN_TL@ + +ss.input.port1.gun.offscreen_shot joystick @GUID1@ @DEVICE_BTN_SOUTH@ + +ss.input.port1.gun.start joystick @GUID1@ @DEVICE_BTN_EAST@ + +ss.input.port1.gun.trigger mouse 0x0 button_left + +ss.input.port1.gun.x_axis mouse 0x0 cursor_x-+ + +ss.input.port1.gun.y_axis mouse 0x0 cursor_y-+ + +ss.input.port1.gun_chairs 0xFF0000 + +ss.input.port1.jpkeyboard.0 keyboard 0x0 39 + +ss.input.port1.jpkeyboard.1 keyboard 0x0 30 + +ss.input.port1.jpkeyboard.2 keyboard 0x0 31 + +ss.input.port1.jpkeyboard.3 keyboard 0x0 32 + +ss.input.port1.jpkeyboard.4 keyboard 0x0 33 + +ss.input.port1.jpkeyboard.5 keyboard 0x0 34 + +ss.input.port1.jpkeyboard.6 keyboard 0x0 35 + +ss.input.port1.jpkeyboard.7 keyboard 0x0 36 + +ss.input.port1.jpkeyboard.8 keyboard 0x0 37 + +ss.input.port1.jpkeyboard.9 keyboard 0x0 38 + +ss.input.port1.jpkeyboard.a keyboard 0x0 4 + +ss.input.port1.jpkeyboard.at keyboard 0x0 47 + +ss.input.port1.jpkeyboard.b keyboard 0x0 5 + +ss.input.port1.jpkeyboard.backslash keyboard 0x0 135 + +ss.input.port1.jpkeyboard.backspace keyboard 0x0 42 + +ss.input.port1.jpkeyboard.c keyboard 0x0 6 + +ss.input.port1.jpkeyboard.capslock keyboard 0x0 57 + +ss.input.port1.jpkeyboard.circumflex keyboard 0x0 46 + +ss.input.port1.jpkeyboard.colon keyboard 0x0 52 + +ss.input.port1.jpkeyboard.comma keyboard 0x0 54 + +ss.input.port1.jpkeyboard.conv keyboard 0x0 138 + +ss.input.port1.jpkeyboard.d keyboard 0x0 7 + +ss.input.port1.jpkeyboard.delete keyboard 0x0 76 + +ss.input.port1.jpkeyboard.down keyboard 0x0 81 + +ss.input.port1.jpkeyboard.e keyboard 0x0 8 + +ss.input.port1.jpkeyboard.end keyboard 0x0 77 + +ss.input.port1.jpkeyboard.enter keyboard 0x0 40 + +ss.input.port1.jpkeyboard.esc keyboard 0x0 41 + +ss.input.port1.jpkeyboard.f keyboard 0x0 9 + +ss.input.port1.jpkeyboard.f1 keyboard 0x0 58 + +ss.input.port1.jpkeyboard.f10 keyboard 0x0 67 + +ss.input.port1.jpkeyboard.f11 keyboard 0x0 68 + +ss.input.port1.jpkeyboard.f12 keyboard 0x0 69 + +ss.input.port1.jpkeyboard.f2 keyboard 0x0 59 + +ss.input.port1.jpkeyboard.f3 keyboard 0x0 60 + +ss.input.port1.jpkeyboard.f4 keyboard 0x0 61 + +ss.input.port1.jpkeyboard.f5 keyboard 0x0 62 + +ss.input.port1.jpkeyboard.f6 keyboard 0x0 63 + +ss.input.port1.jpkeyboard.f7 keyboard 0x0 64 + +ss.input.port1.jpkeyboard.f8 keyboard 0x0 65 + +ss.input.port1.jpkeyboard.f9 keyboard 0x0 66 + +ss.input.port1.jpkeyboard.g keyboard 0x0 10 + +ss.input.port1.jpkeyboard.h keyboard 0x0 11 + +ss.input.port1.jpkeyboard.hkr keyboard 0x0 136 + +ss.input.port1.jpkeyboard.home keyboard 0x0 74 + +ss.input.port1.jpkeyboard.hwfw keyboard 0x0 53 + +ss.input.port1.jpkeyboard.i keyboard 0x0 12 + +ss.input.port1.jpkeyboard.insert keyboard 0x0 73 + +ss.input.port1.jpkeyboard.j keyboard 0x0 13 + +ss.input.port1.jpkeyboard.k keyboard 0x0 14 + +ss.input.port1.jpkeyboard.l keyboard 0x0 15 + +ss.input.port1.jpkeyboard.lalt keyboard 0x0 226 + +ss.input.port1.jpkeyboard.lctrl keyboard 0x0 224 + +ss.input.port1.jpkeyboard.left keyboard 0x0 80 + +ss.input.port1.jpkeyboard.leftbracket keyboard 0x0 48 + +ss.input.port1.jpkeyboard.lshift keyboard 0x0 225 + +ss.input.port1.jpkeyboard.m keyboard 0x0 16 + +ss.input.port1.jpkeyboard.minus keyboard 0x0 45 + +ss.input.port1.jpkeyboard.n keyboard 0x0 17 + +ss.input.port1.jpkeyboard.nonconv keyboard 0x0 139 + +ss.input.port1.jpkeyboard.o keyboard 0x0 18 + +ss.input.port1.jpkeyboard.p keyboard 0x0 19 + +ss.input.port1.jpkeyboard.pagedown keyboard 0x0 78 + +ss.input.port1.jpkeyboard.pageup keyboard 0x0 75 + +ss.input.port1.jpkeyboard.pause keyboard 0x0 72 || keyboard 0x0 83 + +ss.input.port1.jpkeyboard.period keyboard 0x0 55 + +ss.input.port1.jpkeyboard.printscreen keyboard 0x0 70 + +ss.input.port1.jpkeyboard.q keyboard 0x0 20 + +ss.input.port1.jpkeyboard.r keyboard 0x0 21 + +ss.input.port1.jpkeyboard.ralt keyboard 0x0 230 + +ss.input.port1.jpkeyboard.rctrl keyboard 0x0 228 + +ss.input.port1.jpkeyboard.right keyboard 0x0 79 + +ss.input.port1.jpkeyboard.rightbracket keyboard 0x0 49 + +ss.input.port1.jpkeyboard.rshift keyboard 0x0 229 + +ss.input.port1.jpkeyboard.s keyboard 0x0 22 + +ss.input.port1.jpkeyboard.scrolllock keyboard 0x0 71 + +ss.input.port1.jpkeyboard.semicolon keyboard 0x0 51 + +ss.input.port1.jpkeyboard.slash keyboard 0x0 56 + +ss.input.port1.jpkeyboard.space keyboard 0x0 44 + +ss.input.port1.jpkeyboard.t keyboard 0x0 23 + +ss.input.port1.jpkeyboard.tab keyboard 0x0 43 + +ss.input.port1.jpkeyboard.u keyboard 0x0 24 + +ss.input.port1.jpkeyboard.up keyboard 0x0 82 + +ss.input.port1.jpkeyboard.v keyboard 0x0 25 + +ss.input.port1.jpkeyboard.w keyboard 0x0 26 + +ss.input.port1.jpkeyboard.x keyboard 0x0 27 + +ss.input.port1.jpkeyboard.y keyboard 0x0 28 + +ss.input.port1.jpkeyboard.yen keyboard 0x0 137 + +ss.input.port1.jpkeyboard.z keyboard 0x0 29 + +ss.input.port1.keyboard.0 keyboard 0x0 39 + +ss.input.port1.keyboard.1 keyboard 0x0 30 + +ss.input.port1.keyboard.2 keyboard 0x0 31 + +ss.input.port1.keyboard.3 keyboard 0x0 32 + +ss.input.port1.keyboard.4 keyboard 0x0 33 + +ss.input.port1.keyboard.5 keyboard 0x0 34 + +ss.input.port1.keyboard.6 keyboard 0x0 35 + +ss.input.port1.keyboard.7 keyboard 0x0 36 + +ss.input.port1.keyboard.8 keyboard 0x0 37 + +ss.input.port1.keyboard.9 keyboard 0x0 38 + +ss.input.port1.keyboard.a keyboard 0x0 4 + +ss.input.port1.keyboard.b keyboard 0x0 5 + +ss.input.port1.keyboard.backslash keyboard 0x0 49 || keyboard 0x0 135 + +ss.input.port1.keyboard.backspace keyboard 0x0 42 + +ss.input.port1.keyboard.c keyboard 0x0 6 + +ss.input.port1.keyboard.capslock keyboard 0x0 57 + +ss.input.port1.keyboard.comma keyboard 0x0 54 + +ss.input.port1.keyboard.d keyboard 0x0 7 + +ss.input.port1.keyboard.delete keyboard 0x0 76 + +ss.input.port1.keyboard.down keyboard 0x0 81 + +ss.input.port1.keyboard.e keyboard 0x0 8 + +ss.input.port1.keyboard.end keyboard 0x0 77 + +ss.input.port1.keyboard.enter keyboard 0x0 40 + +ss.input.port1.keyboard.equals keyboard 0x0 46 + +ss.input.port1.keyboard.esc keyboard 0x0 41 + +ss.input.port1.keyboard.f keyboard 0x0 9 + +ss.input.port1.keyboard.f1 keyboard 0x0 58 + +ss.input.port1.keyboard.f10 keyboard 0x0 67 + +ss.input.port1.keyboard.f11 keyboard 0x0 68 + +ss.input.port1.keyboard.f12 keyboard 0x0 69 + +ss.input.port1.keyboard.f2 keyboard 0x0 59 + +ss.input.port1.keyboard.f3 keyboard 0x0 60 + +ss.input.port1.keyboard.f4 keyboard 0x0 61 + +ss.input.port1.keyboard.f5 keyboard 0x0 62 + +ss.input.port1.keyboard.f6 keyboard 0x0 63 + +ss.input.port1.keyboard.f7 keyboard 0x0 64 + +ss.input.port1.keyboard.f8 keyboard 0x0 65 + +ss.input.port1.keyboard.f9 keyboard 0x0 66 + +ss.input.port1.keyboard.g keyboard 0x0 10 + +ss.input.port1.keyboard.grave keyboard 0x0 53 + +ss.input.port1.keyboard.h keyboard 0x0 11 + +ss.input.port1.keyboard.home keyboard 0x0 74 + +ss.input.port1.keyboard.i keyboard 0x0 12 + +ss.input.port1.keyboard.insert keyboard 0x0 73 + +ss.input.port1.keyboard.j keyboard 0x0 13 + +ss.input.port1.keyboard.k keyboard 0x0 14 + +ss.input.port1.keyboard.kp_asterisk keyboard 0x0 85 + +ss.input.port1.keyboard.kp_center keyboard 0x0 93 + +ss.input.port1.keyboard.kp_delete keyboard 0x0 99 + +ss.input.port1.keyboard.kp_down keyboard 0x0 90 + +ss.input.port1.keyboard.kp_end keyboard 0x0 89 + +ss.input.port1.keyboard.kp_enter keyboard 0x0 88 + +ss.input.port1.keyboard.kp_home keyboard 0x0 95 + +ss.input.port1.keyboard.kp_insert keyboard 0x0 98 + +ss.input.port1.keyboard.kp_left keyboard 0x0 92 + +ss.input.port1.keyboard.kp_minus keyboard 0x0 86 + +ss.input.port1.keyboard.kp_pagedown keyboard 0x0 91 + +ss.input.port1.keyboard.kp_pageup keyboard 0x0 97 + +ss.input.port1.keyboard.kp_plus keyboard 0x0 87 + +ss.input.port1.keyboard.kp_right keyboard 0x0 94 + +ss.input.port1.keyboard.kp_slash keyboard 0x0 84 + +ss.input.port1.keyboard.kp_up keyboard 0x0 96 + +ss.input.port1.keyboard.l keyboard 0x0 15 + +ss.input.port1.keyboard.lalt keyboard 0x0 226 + +ss.input.port1.keyboard.lctrl keyboard 0x0 224 + +ss.input.port1.keyboard.left keyboard 0x0 80 + +ss.input.port1.keyboard.leftbracket keyboard 0x0 47 + +ss.input.port1.keyboard.lshift keyboard 0x0 225 + +ss.input.port1.keyboard.m keyboard 0x0 16 + +ss.input.port1.keyboard.minus keyboard 0x0 45 + +ss.input.port1.keyboard.n keyboard 0x0 17 + +ss.input.port1.keyboard.numlock keyboard 0x0 83 + +ss.input.port1.keyboard.o keyboard 0x0 18 + +ss.input.port1.keyboard.p keyboard 0x0 19 + +ss.input.port1.keyboard.pagedown keyboard 0x0 78 + +ss.input.port1.keyboard.pageup keyboard 0x0 75 + +ss.input.port1.keyboard.pause keyboard 0x0 72 + +ss.input.port1.keyboard.period keyboard 0x0 55 + +ss.input.port1.keyboard.printscreen keyboard 0x0 70 + +ss.input.port1.keyboard.q keyboard 0x0 20 + +ss.input.port1.keyboard.quote keyboard 0x0 52 + +ss.input.port1.keyboard.r keyboard 0x0 21 + +ss.input.port1.keyboard.ralt keyboard 0x0 230 + +ss.input.port1.keyboard.rctrl keyboard 0x0 228 + +ss.input.port1.keyboard.right keyboard 0x0 79 + +ss.input.port1.keyboard.rightbracket keyboard 0x0 48 + +ss.input.port1.keyboard.rshift keyboard 0x0 229 + +ss.input.port1.keyboard.s keyboard 0x0 22 + +ss.input.port1.keyboard.scrolllock keyboard 0x0 71 + +ss.input.port1.keyboard.semicolon keyboard 0x0 51 + +ss.input.port1.keyboard.slash keyboard 0x0 56 + +ss.input.port1.keyboard.space keyboard 0x0 44 + +ss.input.port1.keyboard.t keyboard 0x0 23 + +ss.input.port1.keyboard.tab keyboard 0x0 43 + +ss.input.port1.keyboard.u keyboard 0x0 24 + +ss.input.port1.keyboard.up keyboard 0x0 82 + +ss.input.port1.keyboard.v keyboard 0x0 25 + +ss.input.port1.keyboard.w keyboard 0x0 26 + +ss.input.port1.keyboard.x keyboard 0x0 27 + +ss.input.port1.keyboard.y keyboard 0x0 28 + +ss.input.port1.keyboard.z keyboard 0x0 29 + +ss.input.port1.mission.a + +ss.input.port1.mission.afa + +ss.input.port1.mission.afa.defpos off + +ss.input.port1.mission.afb + +ss.input.port1.mission.afb.defpos off + +ss.input.port1.mission.afc + +ss.input.port1.mission.afc.defpos off + +ss.input.port1.mission.afl + +ss.input.port1.mission.afl.defpos off + +ss.input.port1.mission.afr + +ss.input.port1.mission.afr.defpos off + +ss.input.port1.mission.afspeed + +ss.input.port1.mission.afspeed.defpos 1 + +ss.input.port1.mission.afx + +ss.input.port1.mission.afx.defpos off + +ss.input.port1.mission.afy + +ss.input.port1.mission.afy.defpos off + +ss.input.port1.mission.afz + +ss.input.port1.mission.afz.defpos off + +ss.input.port1.mission.b + +ss.input.port1.mission.c + +ss.input.port1.mission.l + +ss.input.port1.mission.r + +ss.input.port1.mission.start + +ss.input.port1.mission.stick_back + +ss.input.port1.mission.stick_fore + +ss.input.port1.mission.stick_left + +ss.input.port1.mission.stick_right + +ss.input.port1.mission.throttle_down + +ss.input.port1.mission.throttle_up + +ss.input.port1.mission.x + +ss.input.port1.mission.y + +ss.input.port1.mission.z + +ss.input.port1.mouse.left mouse 0x0 button_left + +ss.input.port1.mouse.middle mouse 0x0 button_middle + +ss.input.port1.mouse.motion_down mouse 0x0 rel_y+ + +ss.input.port1.mouse.motion_left mouse 0x0 rel_x- + +ss.input.port1.mouse.motion_right mouse 0x0 rel_x+ + +ss.input.port1.mouse.motion_up mouse 0x0 rel_y- + +ss.input.port1.mouse.right mouse 0x0 button_right + +ss.input.port1.mouse.start keyboard 0x0 40 + +ss.input.port1.wheel.a + +ss.input.port1.wheel.analog_left + +ss.input.port1.wheel.analog_right + +ss.input.port1.wheel.b + +ss.input.port1.wheel.c + +ss.input.port1.wheel.down + +ss.input.port1.wheel.start + +ss.input.port1.wheel.up + +ss.input.port1.wheel.x + +ss.input.port1.wheel.y + +ss.input.port1.wheel.z + +ss.input.port10 gamepad + +ss.input.port10.3dpad.a + +ss.input.port10.3dpad.analog_down + +ss.input.port10.3dpad.analog_left + +ss.input.port10.3dpad.analog_right + +ss.input.port10.3dpad.analog_up + +ss.input.port10.3dpad.b + +ss.input.port10.3dpad.c + +ss.input.port10.3dpad.down + +ss.input.port10.3dpad.left + +ss.input.port10.3dpad.ls + +ss.input.port10.3dpad.mode + +ss.input.port10.3dpad.mode.defpos digital + +ss.input.port10.3dpad.right + +ss.input.port10.3dpad.rs + +ss.input.port10.3dpad.start + +ss.input.port10.3dpad.up + +ss.input.port10.3dpad.x + +ss.input.port10.3dpad.y + +ss.input.port10.3dpad.z + +ss.input.port10.dmission.a + +ss.input.port10.dmission.afa + +ss.input.port10.dmission.afa.defpos off + +ss.input.port10.dmission.afb + +ss.input.port10.dmission.afb.defpos off + +ss.input.port10.dmission.afc + +ss.input.port10.dmission.afc.defpos off + +ss.input.port10.dmission.afl + +ss.input.port10.dmission.afl.defpos off + +ss.input.port10.dmission.afr + +ss.input.port10.dmission.afr.defpos off + +ss.input.port10.dmission.afspeed + +ss.input.port10.dmission.afspeed.defpos 1 + +ss.input.port10.dmission.afx + +ss.input.port10.dmission.afx.defpos off + +ss.input.port10.dmission.afy + +ss.input.port10.dmission.afy.defpos off + +ss.input.port10.dmission.afz + +ss.input.port10.dmission.afz.defpos off + +ss.input.port10.dmission.b + +ss.input.port10.dmission.c + +ss.input.port10.dmission.l + +ss.input.port10.dmission.lstick_back + +ss.input.port10.dmission.lstick_fore + +ss.input.port10.dmission.lstick_left + +ss.input.port10.dmission.lstick_right + +ss.input.port10.dmission.lthrottle_down + +ss.input.port10.dmission.lthrottle_up + +ss.input.port10.dmission.r + +ss.input.port10.dmission.rstick_back + +ss.input.port10.dmission.rstick_fore + +ss.input.port10.dmission.rstick_left + +ss.input.port10.dmission.rstick_right + +ss.input.port10.dmission.rthrottle_down + +ss.input.port10.dmission.rthrottle_up + +ss.input.port10.dmission.start + +ss.input.port10.dmission.x + +ss.input.port10.dmission.y + +ss.input.port10.dmission.z + +ss.input.port10.gamepad.a + +ss.input.port10.gamepad.b + +ss.input.port10.gamepad.c + +ss.input.port10.gamepad.down + +ss.input.port10.gamepad.left + +ss.input.port10.gamepad.ls + +ss.input.port10.gamepad.right + +ss.input.port10.gamepad.rs + +ss.input.port10.gamepad.start + +ss.input.port10.gamepad.up + +ss.input.port10.gamepad.x + +ss.input.port10.gamepad.y + +ss.input.port10.gamepad.z + +ss.input.port10.gun.offscreen_shot mouse 0x0 button_right + +ss.input.port10.gun.start mouse 0x0 button_middle + +ss.input.port10.gun.trigger mouse 0x0 button_left + +ss.input.port10.gun.x_axis mouse 0x0 cursor_x-+ + +ss.input.port10.gun.y_axis mouse 0x0 cursor_y-+ + +ss.input.port10.gun_chairs 0x00FF80 + +ss.input.port10.jpkeyboard.0 keyboard 0x0 39 + +ss.input.port10.jpkeyboard.1 keyboard 0x0 30 + +ss.input.port10.jpkeyboard.2 keyboard 0x0 31 + +ss.input.port10.jpkeyboard.3 keyboard 0x0 32 + +ss.input.port10.jpkeyboard.4 keyboard 0x0 33 + +ss.input.port10.jpkeyboard.5 keyboard 0x0 34 + +ss.input.port10.jpkeyboard.6 keyboard 0x0 35 + +ss.input.port10.jpkeyboard.7 keyboard 0x0 36 + +ss.input.port10.jpkeyboard.8 keyboard 0x0 37 + +ss.input.port10.jpkeyboard.9 keyboard 0x0 38 + +ss.input.port10.jpkeyboard.a keyboard 0x0 4 + +ss.input.port10.jpkeyboard.at keyboard 0x0 47 + +ss.input.port10.jpkeyboard.b keyboard 0x0 5 + +ss.input.port10.jpkeyboard.backslash keyboard 0x0 135 + +ss.input.port10.jpkeyboard.backspace keyboard 0x0 42 + +ss.input.port10.jpkeyboard.c keyboard 0x0 6 + +ss.input.port10.jpkeyboard.capslock keyboard 0x0 57 + +ss.input.port10.jpkeyboard.circumflex keyboard 0x0 46 + +ss.input.port10.jpkeyboard.colon keyboard 0x0 52 + +ss.input.port10.jpkeyboard.comma keyboard 0x0 54 + +ss.input.port10.jpkeyboard.conv keyboard 0x0 138 + +ss.input.port10.jpkeyboard.d keyboard 0x0 7 + +ss.input.port10.jpkeyboard.delete keyboard 0x0 76 + +ss.input.port10.jpkeyboard.down keyboard 0x0 81 + +ss.input.port10.jpkeyboard.e keyboard 0x0 8 + +ss.input.port10.jpkeyboard.end keyboard 0x0 77 + +ss.input.port10.jpkeyboard.enter keyboard 0x0 40 + +ss.input.port10.jpkeyboard.esc keyboard 0x0 41 + +ss.input.port10.jpkeyboard.f keyboard 0x0 9 + +ss.input.port10.jpkeyboard.f1 keyboard 0x0 58 + +ss.input.port10.jpkeyboard.f10 keyboard 0x0 67 + +ss.input.port10.jpkeyboard.f11 keyboard 0x0 68 + +ss.input.port10.jpkeyboard.f12 keyboard 0x0 69 + +ss.input.port10.jpkeyboard.f2 keyboard 0x0 59 + +ss.input.port10.jpkeyboard.f3 keyboard 0x0 60 + +ss.input.port10.jpkeyboard.f4 keyboard 0x0 61 + +ss.input.port10.jpkeyboard.f5 keyboard 0x0 62 + +ss.input.port10.jpkeyboard.f6 keyboard 0x0 63 + +ss.input.port10.jpkeyboard.f7 keyboard 0x0 64 + +ss.input.port10.jpkeyboard.f8 keyboard 0x0 65 + +ss.input.port10.jpkeyboard.f9 keyboard 0x0 66 + +ss.input.port10.jpkeyboard.g keyboard 0x0 10 + +ss.input.port10.jpkeyboard.h keyboard 0x0 11 + +ss.input.port10.jpkeyboard.hkr keyboard 0x0 136 + +ss.input.port10.jpkeyboard.home keyboard 0x0 74 + +ss.input.port10.jpkeyboard.hwfw keyboard 0x0 53 + +ss.input.port10.jpkeyboard.i keyboard 0x0 12 + +ss.input.port10.jpkeyboard.insert keyboard 0x0 73 + +ss.input.port10.jpkeyboard.j keyboard 0x0 13 + +ss.input.port10.jpkeyboard.k keyboard 0x0 14 + +ss.input.port10.jpkeyboard.l keyboard 0x0 15 + +ss.input.port10.jpkeyboard.lalt keyboard 0x0 226 + +ss.input.port10.jpkeyboard.lctrl keyboard 0x0 224 + +ss.input.port10.jpkeyboard.left keyboard 0x0 80 + +ss.input.port10.jpkeyboard.leftbracket keyboard 0x0 48 + +ss.input.port10.jpkeyboard.lshift keyboard 0x0 225 + +ss.input.port10.jpkeyboard.m keyboard 0x0 16 + +ss.input.port10.jpkeyboard.minus keyboard 0x0 45 + +ss.input.port10.jpkeyboard.n keyboard 0x0 17 + +ss.input.port10.jpkeyboard.nonconv keyboard 0x0 139 + +ss.input.port10.jpkeyboard.o keyboard 0x0 18 + +ss.input.port10.jpkeyboard.p keyboard 0x0 19 + +ss.input.port10.jpkeyboard.pagedown keyboard 0x0 78 + +ss.input.port10.jpkeyboard.pageup keyboard 0x0 75 + +ss.input.port10.jpkeyboard.pause keyboard 0x0 72 || keyboard 0x0 83 + +ss.input.port10.jpkeyboard.period keyboard 0x0 55 + +ss.input.port10.jpkeyboard.printscreen keyboard 0x0 70 + +ss.input.port10.jpkeyboard.q keyboard 0x0 20 + +ss.input.port10.jpkeyboard.r keyboard 0x0 21 + +ss.input.port10.jpkeyboard.ralt keyboard 0x0 230 + +ss.input.port10.jpkeyboard.rctrl keyboard 0x0 228 + +ss.input.port10.jpkeyboard.right keyboard 0x0 79 + +ss.input.port10.jpkeyboard.rightbracket keyboard 0x0 49 + +ss.input.port10.jpkeyboard.rshift keyboard 0x0 229 + +ss.input.port10.jpkeyboard.s keyboard 0x0 22 + +ss.input.port10.jpkeyboard.scrolllock keyboard 0x0 71 + +ss.input.port10.jpkeyboard.semicolon keyboard 0x0 51 + +ss.input.port10.jpkeyboard.slash keyboard 0x0 56 + +ss.input.port10.jpkeyboard.space keyboard 0x0 44 + +ss.input.port10.jpkeyboard.t keyboard 0x0 23 + +ss.input.port10.jpkeyboard.tab keyboard 0x0 43 + +ss.input.port10.jpkeyboard.u keyboard 0x0 24 + +ss.input.port10.jpkeyboard.up keyboard 0x0 82 + +ss.input.port10.jpkeyboard.v keyboard 0x0 25 + +ss.input.port10.jpkeyboard.w keyboard 0x0 26 + +ss.input.port10.jpkeyboard.x keyboard 0x0 27 + +ss.input.port10.jpkeyboard.y keyboard 0x0 28 + +ss.input.port10.jpkeyboard.yen keyboard 0x0 137 + +ss.input.port10.jpkeyboard.z keyboard 0x0 29 + +ss.input.port10.keyboard.0 keyboard 0x0 39 + +ss.input.port10.keyboard.1 keyboard 0x0 30 + +ss.input.port10.keyboard.2 keyboard 0x0 31 + +ss.input.port10.keyboard.3 keyboard 0x0 32 + +ss.input.port10.keyboard.4 keyboard 0x0 33 + +ss.input.port10.keyboard.5 keyboard 0x0 34 + +ss.input.port10.keyboard.6 keyboard 0x0 35 + +ss.input.port10.keyboard.7 keyboard 0x0 36 + +ss.input.port10.keyboard.8 keyboard 0x0 37 + +ss.input.port10.keyboard.9 keyboard 0x0 38 + +ss.input.port10.keyboard.a keyboard 0x0 4 + +ss.input.port10.keyboard.b keyboard 0x0 5 + +ss.input.port10.keyboard.backslash keyboard 0x0 49 || keyboard 0x0 135 + +ss.input.port10.keyboard.backspace keyboard 0x0 42 + +ss.input.port10.keyboard.c keyboard 0x0 6 + +ss.input.port10.keyboard.capslock keyboard 0x0 57 + +ss.input.port10.keyboard.comma keyboard 0x0 54 + +ss.input.port10.keyboard.d keyboard 0x0 7 + +ss.input.port10.keyboard.delete keyboard 0x0 76 + +ss.input.port10.keyboard.down keyboard 0x0 81 + +ss.input.port10.keyboard.e keyboard 0x0 8 + +ss.input.port10.keyboard.end keyboard 0x0 77 + +ss.input.port10.keyboard.enter keyboard 0x0 40 + +ss.input.port10.keyboard.equals keyboard 0x0 46 + +ss.input.port10.keyboard.esc keyboard 0x0 41 + +ss.input.port10.keyboard.f keyboard 0x0 9 + +ss.input.port10.keyboard.f1 keyboard 0x0 58 + +ss.input.port10.keyboard.f10 keyboard 0x0 67 + +ss.input.port10.keyboard.f11 keyboard 0x0 68 + +ss.input.port10.keyboard.f12 keyboard 0x0 69 + +ss.input.port10.keyboard.f2 keyboard 0x0 59 + +ss.input.port10.keyboard.f3 keyboard 0x0 60 + +ss.input.port10.keyboard.f4 keyboard 0x0 61 + +ss.input.port10.keyboard.f5 keyboard 0x0 62 + +ss.input.port10.keyboard.f6 keyboard 0x0 63 + +ss.input.port10.keyboard.f7 keyboard 0x0 64 + +ss.input.port10.keyboard.f8 keyboard 0x0 65 + +ss.input.port10.keyboard.f9 keyboard 0x0 66 + +ss.input.port10.keyboard.g keyboard 0x0 10 + +ss.input.port10.keyboard.grave keyboard 0x0 53 + +ss.input.port10.keyboard.h keyboard 0x0 11 + +ss.input.port10.keyboard.home keyboard 0x0 74 + +ss.input.port10.keyboard.i keyboard 0x0 12 + +ss.input.port10.keyboard.insert keyboard 0x0 73 + +ss.input.port10.keyboard.j keyboard 0x0 13 + +ss.input.port10.keyboard.k keyboard 0x0 14 + +ss.input.port10.keyboard.kp_asterisk keyboard 0x0 85 + +ss.input.port10.keyboard.kp_center keyboard 0x0 93 + +ss.input.port10.keyboard.kp_delete keyboard 0x0 99 + +ss.input.port10.keyboard.kp_down keyboard 0x0 90 + +ss.input.port10.keyboard.kp_end keyboard 0x0 89 + +ss.input.port10.keyboard.kp_enter keyboard 0x0 88 + +ss.input.port10.keyboard.kp_home keyboard 0x0 95 + +ss.input.port10.keyboard.kp_insert keyboard 0x0 98 + +ss.input.port10.keyboard.kp_left keyboard 0x0 92 + +ss.input.port10.keyboard.kp_minus keyboard 0x0 86 + +ss.input.port10.keyboard.kp_pagedown keyboard 0x0 91 + +ss.input.port10.keyboard.kp_pageup keyboard 0x0 97 + +ss.input.port10.keyboard.kp_plus keyboard 0x0 87 + +ss.input.port10.keyboard.kp_right keyboard 0x0 94 + +ss.input.port10.keyboard.kp_slash keyboard 0x0 84 + +ss.input.port10.keyboard.kp_up keyboard 0x0 96 + +ss.input.port10.keyboard.l keyboard 0x0 15 + +ss.input.port10.keyboard.lalt keyboard 0x0 226 + +ss.input.port10.keyboard.lctrl keyboard 0x0 224 + +ss.input.port10.keyboard.left keyboard 0x0 80 + +ss.input.port10.keyboard.leftbracket keyboard 0x0 47 + +ss.input.port10.keyboard.lshift keyboard 0x0 225 + +ss.input.port10.keyboard.m keyboard 0x0 16 + +ss.input.port10.keyboard.minus keyboard 0x0 45 + +ss.input.port10.keyboard.n keyboard 0x0 17 + +ss.input.port10.keyboard.numlock keyboard 0x0 83 + +ss.input.port10.keyboard.o keyboard 0x0 18 + +ss.input.port10.keyboard.p keyboard 0x0 19 + +ss.input.port10.keyboard.pagedown keyboard 0x0 78 + +ss.input.port10.keyboard.pageup keyboard 0x0 75 + +ss.input.port10.keyboard.pause keyboard 0x0 72 + +ss.input.port10.keyboard.period keyboard 0x0 55 + +ss.input.port10.keyboard.printscreen keyboard 0x0 70 + +ss.input.port10.keyboard.q keyboard 0x0 20 + +ss.input.port10.keyboard.quote keyboard 0x0 52 + +ss.input.port10.keyboard.r keyboard 0x0 21 + +ss.input.port10.keyboard.ralt keyboard 0x0 230 + +ss.input.port10.keyboard.rctrl keyboard 0x0 228 + +ss.input.port10.keyboard.right keyboard 0x0 79 + +ss.input.port10.keyboard.rightbracket keyboard 0x0 48 + +ss.input.port10.keyboard.rshift keyboard 0x0 229 + +ss.input.port10.keyboard.s keyboard 0x0 22 + +ss.input.port10.keyboard.scrolllock keyboard 0x0 71 + +ss.input.port10.keyboard.semicolon keyboard 0x0 51 + +ss.input.port10.keyboard.slash keyboard 0x0 56 + +ss.input.port10.keyboard.space keyboard 0x0 44 + +ss.input.port10.keyboard.t keyboard 0x0 23 + +ss.input.port10.keyboard.tab keyboard 0x0 43 + +ss.input.port10.keyboard.u keyboard 0x0 24 + +ss.input.port10.keyboard.up keyboard 0x0 82 + +ss.input.port10.keyboard.v keyboard 0x0 25 + +ss.input.port10.keyboard.w keyboard 0x0 26 + +ss.input.port10.keyboard.x keyboard 0x0 27 + +ss.input.port10.keyboard.y keyboard 0x0 28 + +ss.input.port10.keyboard.z keyboard 0x0 29 + +ss.input.port10.mission.a + +ss.input.port10.mission.afa + +ss.input.port10.mission.afa.defpos off + +ss.input.port10.mission.afb + +ss.input.port10.mission.afb.defpos off + +ss.input.port10.mission.afc + +ss.input.port10.mission.afc.defpos off + +ss.input.port10.mission.afl + +ss.input.port10.mission.afl.defpos off + +ss.input.port10.mission.afr + +ss.input.port10.mission.afr.defpos off + +ss.input.port10.mission.afspeed + +ss.input.port10.mission.afspeed.defpos 1 + +ss.input.port10.mission.afx + +ss.input.port10.mission.afx.defpos off + +ss.input.port10.mission.afy + +ss.input.port10.mission.afy.defpos off + +ss.input.port10.mission.afz + +ss.input.port10.mission.afz.defpos off + +ss.input.port10.mission.b + +ss.input.port10.mission.c + +ss.input.port10.mission.l + +ss.input.port10.mission.r + +ss.input.port10.mission.start + +ss.input.port10.mission.stick_back + +ss.input.port10.mission.stick_fore + +ss.input.port10.mission.stick_left + +ss.input.port10.mission.stick_right + +ss.input.port10.mission.throttle_down + +ss.input.port10.mission.throttle_up + +ss.input.port10.mission.x + +ss.input.port10.mission.y + +ss.input.port10.mission.z + +ss.input.port10.mouse.left mouse 0x0 button_left + +ss.input.port10.mouse.middle mouse 0x0 button_middle + +ss.input.port10.mouse.motion_down mouse 0x0 rel_y+ + +ss.input.port10.mouse.motion_left mouse 0x0 rel_x- + +ss.input.port10.mouse.motion_right mouse 0x0 rel_x+ + +ss.input.port10.mouse.motion_up mouse 0x0 rel_y- + +ss.input.port10.mouse.right mouse 0x0 button_right + +ss.input.port10.mouse.start keyboard 0x0 40 + +ss.input.port10.wheel.a + +ss.input.port10.wheel.analog_left + +ss.input.port10.wheel.analog_right + +ss.input.port10.wheel.b + +ss.input.port10.wheel.c + +ss.input.port10.wheel.down + +ss.input.port10.wheel.start + +ss.input.port10.wheel.up + +ss.input.port10.wheel.x + +ss.input.port10.wheel.y + +ss.input.port10.wheel.z + +ss.input.port11 gamepad + +ss.input.port11.3dpad.a + +ss.input.port11.3dpad.analog_down + +ss.input.port11.3dpad.analog_left + +ss.input.port11.3dpad.analog_right + +ss.input.port11.3dpad.analog_up + +ss.input.port11.3dpad.b + +ss.input.port11.3dpad.c + +ss.input.port11.3dpad.down + +ss.input.port11.3dpad.left + +ss.input.port11.3dpad.ls + +ss.input.port11.3dpad.mode + +ss.input.port11.3dpad.mode.defpos digital + +ss.input.port11.3dpad.right + +ss.input.port11.3dpad.rs + +ss.input.port11.3dpad.start + +ss.input.port11.3dpad.up + +ss.input.port11.3dpad.x + +ss.input.port11.3dpad.y + +ss.input.port11.3dpad.z + +ss.input.port11.dmission.a + +ss.input.port11.dmission.afa + +ss.input.port11.dmission.afa.defpos off + +ss.input.port11.dmission.afb + +ss.input.port11.dmission.afb.defpos off + +ss.input.port11.dmission.afc + +ss.input.port11.dmission.afc.defpos off + +ss.input.port11.dmission.afl + +ss.input.port11.dmission.afl.defpos off + +ss.input.port11.dmission.afr + +ss.input.port11.dmission.afr.defpos off + +ss.input.port11.dmission.afspeed + +ss.input.port11.dmission.afspeed.defpos 1 + +ss.input.port11.dmission.afx + +ss.input.port11.dmission.afx.defpos off + +ss.input.port11.dmission.afy + +ss.input.port11.dmission.afy.defpos off + +ss.input.port11.dmission.afz + +ss.input.port11.dmission.afz.defpos off + +ss.input.port11.dmission.b + +ss.input.port11.dmission.c + +ss.input.port11.dmission.l + +ss.input.port11.dmission.lstick_back + +ss.input.port11.dmission.lstick_fore + +ss.input.port11.dmission.lstick_left + +ss.input.port11.dmission.lstick_right + +ss.input.port11.dmission.lthrottle_down + +ss.input.port11.dmission.lthrottle_up + +ss.input.port11.dmission.r + +ss.input.port11.dmission.rstick_back + +ss.input.port11.dmission.rstick_fore + +ss.input.port11.dmission.rstick_left + +ss.input.port11.dmission.rstick_right + +ss.input.port11.dmission.rthrottle_down + +ss.input.port11.dmission.rthrottle_up + +ss.input.port11.dmission.start + +ss.input.port11.dmission.x + +ss.input.port11.dmission.y + +ss.input.port11.dmission.z + +ss.input.port11.gamepad.a + +ss.input.port11.gamepad.b + +ss.input.port11.gamepad.c + +ss.input.port11.gamepad.down + +ss.input.port11.gamepad.left + +ss.input.port11.gamepad.ls + +ss.input.port11.gamepad.right + +ss.input.port11.gamepad.rs + +ss.input.port11.gamepad.start + +ss.input.port11.gamepad.up + +ss.input.port11.gamepad.x + +ss.input.port11.gamepad.y + +ss.input.port11.gamepad.z + +ss.input.port11.gun.offscreen_shot mouse 0x0 button_right + +ss.input.port11.gun.start mouse 0x0 button_middle + +ss.input.port11.gun.trigger mouse 0x0 button_left + +ss.input.port11.gun.x_axis mouse 0x0 cursor_x-+ + +ss.input.port11.gun.y_axis mouse 0x0 cursor_y-+ + +ss.input.port11.gun_chairs 0x8080FF + +ss.input.port11.jpkeyboard.0 keyboard 0x0 39 + +ss.input.port11.jpkeyboard.1 keyboard 0x0 30 + +ss.input.port11.jpkeyboard.2 keyboard 0x0 31 + +ss.input.port11.jpkeyboard.3 keyboard 0x0 32 + +ss.input.port11.jpkeyboard.4 keyboard 0x0 33 + +ss.input.port11.jpkeyboard.5 keyboard 0x0 34 + +ss.input.port11.jpkeyboard.6 keyboard 0x0 35 + +ss.input.port11.jpkeyboard.7 keyboard 0x0 36 + +ss.input.port11.jpkeyboard.8 keyboard 0x0 37 + +ss.input.port11.jpkeyboard.9 keyboard 0x0 38 + +ss.input.port11.jpkeyboard.a keyboard 0x0 4 + +ss.input.port11.jpkeyboard.at keyboard 0x0 47 + +ss.input.port11.jpkeyboard.b keyboard 0x0 5 + +ss.input.port11.jpkeyboard.backslash keyboard 0x0 135 + +ss.input.port11.jpkeyboard.backspace keyboard 0x0 42 + +ss.input.port11.jpkeyboard.c keyboard 0x0 6 + +ss.input.port11.jpkeyboard.capslock keyboard 0x0 57 + +ss.input.port11.jpkeyboard.circumflex keyboard 0x0 46 + +ss.input.port11.jpkeyboard.colon keyboard 0x0 52 + +ss.input.port11.jpkeyboard.comma keyboard 0x0 54 + +ss.input.port11.jpkeyboard.conv keyboard 0x0 138 + +ss.input.port11.jpkeyboard.d keyboard 0x0 7 + +ss.input.port11.jpkeyboard.delete keyboard 0x0 76 + +ss.input.port11.jpkeyboard.down keyboard 0x0 81 + +ss.input.port11.jpkeyboard.e keyboard 0x0 8 + +ss.input.port11.jpkeyboard.end keyboard 0x0 77 + +ss.input.port11.jpkeyboard.enter keyboard 0x0 40 + +ss.input.port11.jpkeyboard.esc keyboard 0x0 41 + +ss.input.port11.jpkeyboard.f keyboard 0x0 9 + +ss.input.port11.jpkeyboard.f1 keyboard 0x0 58 + +ss.input.port11.jpkeyboard.f10 keyboard 0x0 67 + +ss.input.port11.jpkeyboard.f11 keyboard 0x0 68 + +ss.input.port11.jpkeyboard.f12 keyboard 0x0 69 + +ss.input.port11.jpkeyboard.f2 keyboard 0x0 59 + +ss.input.port11.jpkeyboard.f3 keyboard 0x0 60 + +ss.input.port11.jpkeyboard.f4 keyboard 0x0 61 + +ss.input.port11.jpkeyboard.f5 keyboard 0x0 62 + +ss.input.port11.jpkeyboard.f6 keyboard 0x0 63 + +ss.input.port11.jpkeyboard.f7 keyboard 0x0 64 + +ss.input.port11.jpkeyboard.f8 keyboard 0x0 65 + +ss.input.port11.jpkeyboard.f9 keyboard 0x0 66 + +ss.input.port11.jpkeyboard.g keyboard 0x0 10 + +ss.input.port11.jpkeyboard.h keyboard 0x0 11 + +ss.input.port11.jpkeyboard.hkr keyboard 0x0 136 + +ss.input.port11.jpkeyboard.home keyboard 0x0 74 + +ss.input.port11.jpkeyboard.hwfw keyboard 0x0 53 + +ss.input.port11.jpkeyboard.i keyboard 0x0 12 + +ss.input.port11.jpkeyboard.insert keyboard 0x0 73 + +ss.input.port11.jpkeyboard.j keyboard 0x0 13 + +ss.input.port11.jpkeyboard.k keyboard 0x0 14 + +ss.input.port11.jpkeyboard.l keyboard 0x0 15 + +ss.input.port11.jpkeyboard.lalt keyboard 0x0 226 + +ss.input.port11.jpkeyboard.lctrl keyboard 0x0 224 + +ss.input.port11.jpkeyboard.left keyboard 0x0 80 + +ss.input.port11.jpkeyboard.leftbracket keyboard 0x0 48 + +ss.input.port11.jpkeyboard.lshift keyboard 0x0 225 + +ss.input.port11.jpkeyboard.m keyboard 0x0 16 + +ss.input.port11.jpkeyboard.minus keyboard 0x0 45 + +ss.input.port11.jpkeyboard.n keyboard 0x0 17 + +ss.input.port11.jpkeyboard.nonconv keyboard 0x0 139 + +ss.input.port11.jpkeyboard.o keyboard 0x0 18 + +ss.input.port11.jpkeyboard.p keyboard 0x0 19 + +ss.input.port11.jpkeyboard.pagedown keyboard 0x0 78 + +ss.input.port11.jpkeyboard.pageup keyboard 0x0 75 + +ss.input.port11.jpkeyboard.pause keyboard 0x0 72 || keyboard 0x0 83 + +ss.input.port11.jpkeyboard.period keyboard 0x0 55 + +ss.input.port11.jpkeyboard.printscreen keyboard 0x0 70 + +ss.input.port11.jpkeyboard.q keyboard 0x0 20 + +ss.input.port11.jpkeyboard.r keyboard 0x0 21 + +ss.input.port11.jpkeyboard.ralt keyboard 0x0 230 + +ss.input.port11.jpkeyboard.rctrl keyboard 0x0 228 + +ss.input.port11.jpkeyboard.right keyboard 0x0 79 + +ss.input.port11.jpkeyboard.rightbracket keyboard 0x0 49 + +ss.input.port11.jpkeyboard.rshift keyboard 0x0 229 + +ss.input.port11.jpkeyboard.s keyboard 0x0 22 + +ss.input.port11.jpkeyboard.scrolllock keyboard 0x0 71 + +ss.input.port11.jpkeyboard.semicolon keyboard 0x0 51 + +ss.input.port11.jpkeyboard.slash keyboard 0x0 56 + +ss.input.port11.jpkeyboard.space keyboard 0x0 44 + +ss.input.port11.jpkeyboard.t keyboard 0x0 23 + +ss.input.port11.jpkeyboard.tab keyboard 0x0 43 + +ss.input.port11.jpkeyboard.u keyboard 0x0 24 + +ss.input.port11.jpkeyboard.up keyboard 0x0 82 + +ss.input.port11.jpkeyboard.v keyboard 0x0 25 + +ss.input.port11.jpkeyboard.w keyboard 0x0 26 + +ss.input.port11.jpkeyboard.x keyboard 0x0 27 + +ss.input.port11.jpkeyboard.y keyboard 0x0 28 + +ss.input.port11.jpkeyboard.yen keyboard 0x0 137 + +ss.input.port11.jpkeyboard.z keyboard 0x0 29 + +ss.input.port11.keyboard.0 keyboard 0x0 39 + +ss.input.port11.keyboard.1 keyboard 0x0 30 + +ss.input.port11.keyboard.2 keyboard 0x0 31 + +ss.input.port11.keyboard.3 keyboard 0x0 32 + +ss.input.port11.keyboard.4 keyboard 0x0 33 + +ss.input.port11.keyboard.5 keyboard 0x0 34 + +ss.input.port11.keyboard.6 keyboard 0x0 35 + +ss.input.port11.keyboard.7 keyboard 0x0 36 + +ss.input.port11.keyboard.8 keyboard 0x0 37 + +ss.input.port11.keyboard.9 keyboard 0x0 38 + +ss.input.port11.keyboard.a keyboard 0x0 4 + +ss.input.port11.keyboard.b keyboard 0x0 5 + +ss.input.port11.keyboard.backslash keyboard 0x0 49 || keyboard 0x0 135 + +ss.input.port11.keyboard.backspace keyboard 0x0 42 + +ss.input.port11.keyboard.c keyboard 0x0 6 + +ss.input.port11.keyboard.capslock keyboard 0x0 57 + +ss.input.port11.keyboard.comma keyboard 0x0 54 + +ss.input.port11.keyboard.d keyboard 0x0 7 + +ss.input.port11.keyboard.delete keyboard 0x0 76 + +ss.input.port11.keyboard.down keyboard 0x0 81 + +ss.input.port11.keyboard.e keyboard 0x0 8 + +ss.input.port11.keyboard.end keyboard 0x0 77 + +ss.input.port11.keyboard.enter keyboard 0x0 40 + +ss.input.port11.keyboard.equals keyboard 0x0 46 + +ss.input.port11.keyboard.esc keyboard 0x0 41 + +ss.input.port11.keyboard.f keyboard 0x0 9 + +ss.input.port11.keyboard.f1 keyboard 0x0 58 + +ss.input.port11.keyboard.f10 keyboard 0x0 67 + +ss.input.port11.keyboard.f11 keyboard 0x0 68 + +ss.input.port11.keyboard.f12 keyboard 0x0 69 + +ss.input.port11.keyboard.f2 keyboard 0x0 59 + +ss.input.port11.keyboard.f3 keyboard 0x0 60 + +ss.input.port11.keyboard.f4 keyboard 0x0 61 + +ss.input.port11.keyboard.f5 keyboard 0x0 62 + +ss.input.port11.keyboard.f6 keyboard 0x0 63 + +ss.input.port11.keyboard.f7 keyboard 0x0 64 + +ss.input.port11.keyboard.f8 keyboard 0x0 65 + +ss.input.port11.keyboard.f9 keyboard 0x0 66 + +ss.input.port11.keyboard.g keyboard 0x0 10 + +ss.input.port11.keyboard.grave keyboard 0x0 53 + +ss.input.port11.keyboard.h keyboard 0x0 11 + +ss.input.port11.keyboard.home keyboard 0x0 74 + +ss.input.port11.keyboard.i keyboard 0x0 12 + +ss.input.port11.keyboard.insert keyboard 0x0 73 + +ss.input.port11.keyboard.j keyboard 0x0 13 + +ss.input.port11.keyboard.k keyboard 0x0 14 + +ss.input.port11.keyboard.kp_asterisk keyboard 0x0 85 + +ss.input.port11.keyboard.kp_center keyboard 0x0 93 + +ss.input.port11.keyboard.kp_delete keyboard 0x0 99 + +ss.input.port11.keyboard.kp_down keyboard 0x0 90 + +ss.input.port11.keyboard.kp_end keyboard 0x0 89 + +ss.input.port11.keyboard.kp_enter keyboard 0x0 88 + +ss.input.port11.keyboard.kp_home keyboard 0x0 95 + +ss.input.port11.keyboard.kp_insert keyboard 0x0 98 + +ss.input.port11.keyboard.kp_left keyboard 0x0 92 + +ss.input.port11.keyboard.kp_minus keyboard 0x0 86 + +ss.input.port11.keyboard.kp_pagedown keyboard 0x0 91 + +ss.input.port11.keyboard.kp_pageup keyboard 0x0 97 + +ss.input.port11.keyboard.kp_plus keyboard 0x0 87 + +ss.input.port11.keyboard.kp_right keyboard 0x0 94 + +ss.input.port11.keyboard.kp_slash keyboard 0x0 84 + +ss.input.port11.keyboard.kp_up keyboard 0x0 96 + +ss.input.port11.keyboard.l keyboard 0x0 15 + +ss.input.port11.keyboard.lalt keyboard 0x0 226 + +ss.input.port11.keyboard.lctrl keyboard 0x0 224 + +ss.input.port11.keyboard.left keyboard 0x0 80 + +ss.input.port11.keyboard.leftbracket keyboard 0x0 47 + +ss.input.port11.keyboard.lshift keyboard 0x0 225 + +ss.input.port11.keyboard.m keyboard 0x0 16 + +ss.input.port11.keyboard.minus keyboard 0x0 45 + +ss.input.port11.keyboard.n keyboard 0x0 17 + +ss.input.port11.keyboard.numlock keyboard 0x0 83 + +ss.input.port11.keyboard.o keyboard 0x0 18 + +ss.input.port11.keyboard.p keyboard 0x0 19 + +ss.input.port11.keyboard.pagedown keyboard 0x0 78 + +ss.input.port11.keyboard.pageup keyboard 0x0 75 + +ss.input.port11.keyboard.pause keyboard 0x0 72 + +ss.input.port11.keyboard.period keyboard 0x0 55 + +ss.input.port11.keyboard.printscreen keyboard 0x0 70 + +ss.input.port11.keyboard.q keyboard 0x0 20 + +ss.input.port11.keyboard.quote keyboard 0x0 52 + +ss.input.port11.keyboard.r keyboard 0x0 21 + +ss.input.port11.keyboard.ralt keyboard 0x0 230 + +ss.input.port11.keyboard.rctrl keyboard 0x0 228 + +ss.input.port11.keyboard.right keyboard 0x0 79 + +ss.input.port11.keyboard.rightbracket keyboard 0x0 48 + +ss.input.port11.keyboard.rshift keyboard 0x0 229 + +ss.input.port11.keyboard.s keyboard 0x0 22 + +ss.input.port11.keyboard.scrolllock keyboard 0x0 71 + +ss.input.port11.keyboard.semicolon keyboard 0x0 51 + +ss.input.port11.keyboard.slash keyboard 0x0 56 + +ss.input.port11.keyboard.space keyboard 0x0 44 + +ss.input.port11.keyboard.t keyboard 0x0 23 + +ss.input.port11.keyboard.tab keyboard 0x0 43 + +ss.input.port11.keyboard.u keyboard 0x0 24 + +ss.input.port11.keyboard.up keyboard 0x0 82 + +ss.input.port11.keyboard.v keyboard 0x0 25 + +ss.input.port11.keyboard.w keyboard 0x0 26 + +ss.input.port11.keyboard.x keyboard 0x0 27 + +ss.input.port11.keyboard.y keyboard 0x0 28 + +ss.input.port11.keyboard.z keyboard 0x0 29 + +ss.input.port11.mission.a + +ss.input.port11.mission.afa + +ss.input.port11.mission.afa.defpos off + +ss.input.port11.mission.afb + +ss.input.port11.mission.afb.defpos off + +ss.input.port11.mission.afc + +ss.input.port11.mission.afc.defpos off + +ss.input.port11.mission.afl + +ss.input.port11.mission.afl.defpos off + +ss.input.port11.mission.afr + +ss.input.port11.mission.afr.defpos off + +ss.input.port11.mission.afspeed + +ss.input.port11.mission.afspeed.defpos 1 + +ss.input.port11.mission.afx + +ss.input.port11.mission.afx.defpos off + +ss.input.port11.mission.afy + +ss.input.port11.mission.afy.defpos off + +ss.input.port11.mission.afz + +ss.input.port11.mission.afz.defpos off + +ss.input.port11.mission.b + +ss.input.port11.mission.c + +ss.input.port11.mission.l + +ss.input.port11.mission.r + +ss.input.port11.mission.start + +ss.input.port11.mission.stick_back + +ss.input.port11.mission.stick_fore + +ss.input.port11.mission.stick_left + +ss.input.port11.mission.stick_right + +ss.input.port11.mission.throttle_down + +ss.input.port11.mission.throttle_up + +ss.input.port11.mission.x + +ss.input.port11.mission.y + +ss.input.port11.mission.z + +ss.input.port11.mouse.left mouse 0x0 button_left + +ss.input.port11.mouse.middle mouse 0x0 button_middle + +ss.input.port11.mouse.motion_down mouse 0x0 rel_y+ + +ss.input.port11.mouse.motion_left mouse 0x0 rel_x- + +ss.input.port11.mouse.motion_right mouse 0x0 rel_x+ + +ss.input.port11.mouse.motion_up mouse 0x0 rel_y- + +ss.input.port11.mouse.right mouse 0x0 button_right + +ss.input.port11.mouse.start keyboard 0x0 40 + +ss.input.port11.wheel.a + +ss.input.port11.wheel.analog_left + +ss.input.port11.wheel.analog_right + +ss.input.port11.wheel.b + +ss.input.port11.wheel.c + +ss.input.port11.wheel.down + +ss.input.port11.wheel.start + +ss.input.port11.wheel.up + +ss.input.port11.wheel.x + +ss.input.port11.wheel.y + +ss.input.port11.wheel.z + +ss.input.port12 gamepad + +ss.input.port12.3dpad.a + +ss.input.port12.3dpad.analog_down + +ss.input.port12.3dpad.analog_left + +ss.input.port12.3dpad.analog_right + +ss.input.port12.3dpad.analog_up + +ss.input.port12.3dpad.b + +ss.input.port12.3dpad.c + +ss.input.port12.3dpad.down + +ss.input.port12.3dpad.left + +ss.input.port12.3dpad.ls + +ss.input.port12.3dpad.mode + +ss.input.port12.3dpad.mode.defpos digital + +ss.input.port12.3dpad.right + +ss.input.port12.3dpad.rs + +ss.input.port12.3dpad.start + +ss.input.port12.3dpad.up + +ss.input.port12.3dpad.x + +ss.input.port12.3dpad.y + +ss.input.port12.3dpad.z + +ss.input.port12.dmission.a + +ss.input.port12.dmission.afa + +ss.input.port12.dmission.afa.defpos off + +ss.input.port12.dmission.afb + +ss.input.port12.dmission.afb.defpos off + +ss.input.port12.dmission.afc + +ss.input.port12.dmission.afc.defpos off + +ss.input.port12.dmission.afl + +ss.input.port12.dmission.afl.defpos off + +ss.input.port12.dmission.afr + +ss.input.port12.dmission.afr.defpos off + +ss.input.port12.dmission.afspeed + +ss.input.port12.dmission.afspeed.defpos 1 + +ss.input.port12.dmission.afx + +ss.input.port12.dmission.afx.defpos off + +ss.input.port12.dmission.afy + +ss.input.port12.dmission.afy.defpos off + +ss.input.port12.dmission.afz + +ss.input.port12.dmission.afz.defpos off + +ss.input.port12.dmission.b + +ss.input.port12.dmission.c + +ss.input.port12.dmission.l + +ss.input.port12.dmission.lstick_back + +ss.input.port12.dmission.lstick_fore + +ss.input.port12.dmission.lstick_left + +ss.input.port12.dmission.lstick_right + +ss.input.port12.dmission.lthrottle_down + +ss.input.port12.dmission.lthrottle_up + +ss.input.port12.dmission.r + +ss.input.port12.dmission.rstick_back + +ss.input.port12.dmission.rstick_fore + +ss.input.port12.dmission.rstick_left + +ss.input.port12.dmission.rstick_right + +ss.input.port12.dmission.rthrottle_down + +ss.input.port12.dmission.rthrottle_up + +ss.input.port12.dmission.start + +ss.input.port12.dmission.x + +ss.input.port12.dmission.y + +ss.input.port12.dmission.z + +ss.input.port12.gamepad.a + +ss.input.port12.gamepad.b + +ss.input.port12.gamepad.c + +ss.input.port12.gamepad.down + +ss.input.port12.gamepad.left + +ss.input.port12.gamepad.ls + +ss.input.port12.gamepad.right + +ss.input.port12.gamepad.rs + +ss.input.port12.gamepad.start + +ss.input.port12.gamepad.up + +ss.input.port12.gamepad.x + +ss.input.port12.gamepad.y + +ss.input.port12.gamepad.z + +ss.input.port12.gun.offscreen_shot mouse 0x0 button_right + +ss.input.port12.gun.start mouse 0x0 button_middle + +ss.input.port12.gun.trigger mouse 0x0 button_left + +ss.input.port12.gun.x_axis mouse 0x0 cursor_x-+ + +ss.input.port12.gun.y_axis mouse 0x0 cursor_y-+ + +ss.input.port12.gun_chairs 0xFF8080 + +ss.input.port12.jpkeyboard.0 keyboard 0x0 39 + +ss.input.port12.jpkeyboard.1 keyboard 0x0 30 + +ss.input.port12.jpkeyboard.2 keyboard 0x0 31 + +ss.input.port12.jpkeyboard.3 keyboard 0x0 32 + +ss.input.port12.jpkeyboard.4 keyboard 0x0 33 + +ss.input.port12.jpkeyboard.5 keyboard 0x0 34 + +ss.input.port12.jpkeyboard.6 keyboard 0x0 35 + +ss.input.port12.jpkeyboard.7 keyboard 0x0 36 + +ss.input.port12.jpkeyboard.8 keyboard 0x0 37 + +ss.input.port12.jpkeyboard.9 keyboard 0x0 38 + +ss.input.port12.jpkeyboard.a keyboard 0x0 4 + +ss.input.port12.jpkeyboard.at keyboard 0x0 47 + +ss.input.port12.jpkeyboard.b keyboard 0x0 5 + +ss.input.port12.jpkeyboard.backslash keyboard 0x0 135 + +ss.input.port12.jpkeyboard.backspace keyboard 0x0 42 + +ss.input.port12.jpkeyboard.c keyboard 0x0 6 + +ss.input.port12.jpkeyboard.capslock keyboard 0x0 57 + +ss.input.port12.jpkeyboard.circumflex keyboard 0x0 46 + +ss.input.port12.jpkeyboard.colon keyboard 0x0 52 + +ss.input.port12.jpkeyboard.comma keyboard 0x0 54 + +ss.input.port12.jpkeyboard.conv keyboard 0x0 138 + +ss.input.port12.jpkeyboard.d keyboard 0x0 7 + +ss.input.port12.jpkeyboard.delete keyboard 0x0 76 + +ss.input.port12.jpkeyboard.down keyboard 0x0 81 + +ss.input.port12.jpkeyboard.e keyboard 0x0 8 + +ss.input.port12.jpkeyboard.end keyboard 0x0 77 + +ss.input.port12.jpkeyboard.enter keyboard 0x0 40 + +ss.input.port12.jpkeyboard.esc keyboard 0x0 41 + +ss.input.port12.jpkeyboard.f keyboard 0x0 9 + +ss.input.port12.jpkeyboard.f1 keyboard 0x0 58 + +ss.input.port12.jpkeyboard.f10 keyboard 0x0 67 + +ss.input.port12.jpkeyboard.f11 keyboard 0x0 68 + +ss.input.port12.jpkeyboard.f12 keyboard 0x0 69 + +ss.input.port12.jpkeyboard.f2 keyboard 0x0 59 + +ss.input.port12.jpkeyboard.f3 keyboard 0x0 60 + +ss.input.port12.jpkeyboard.f4 keyboard 0x0 61 + +ss.input.port12.jpkeyboard.f5 keyboard 0x0 62 + +ss.input.port12.jpkeyboard.f6 keyboard 0x0 63 + +ss.input.port12.jpkeyboard.f7 keyboard 0x0 64 + +ss.input.port12.jpkeyboard.f8 keyboard 0x0 65 + +ss.input.port12.jpkeyboard.f9 keyboard 0x0 66 + +ss.input.port12.jpkeyboard.g keyboard 0x0 10 + +ss.input.port12.jpkeyboard.h keyboard 0x0 11 + +ss.input.port12.jpkeyboard.hkr keyboard 0x0 136 + +ss.input.port12.jpkeyboard.home keyboard 0x0 74 + +ss.input.port12.jpkeyboard.hwfw keyboard 0x0 53 + +ss.input.port12.jpkeyboard.i keyboard 0x0 12 + +ss.input.port12.jpkeyboard.insert keyboard 0x0 73 + +ss.input.port12.jpkeyboard.j keyboard 0x0 13 + +ss.input.port12.jpkeyboard.k keyboard 0x0 14 + +ss.input.port12.jpkeyboard.l keyboard 0x0 15 + +ss.input.port12.jpkeyboard.lalt keyboard 0x0 226 + +ss.input.port12.jpkeyboard.lctrl keyboard 0x0 224 + +ss.input.port12.jpkeyboard.left keyboard 0x0 80 + +ss.input.port12.jpkeyboard.leftbracket keyboard 0x0 48 + +ss.input.port12.jpkeyboard.lshift keyboard 0x0 225 + +ss.input.port12.jpkeyboard.m keyboard 0x0 16 + +ss.input.port12.jpkeyboard.minus keyboard 0x0 45 + +ss.input.port12.jpkeyboard.n keyboard 0x0 17 + +ss.input.port12.jpkeyboard.nonconv keyboard 0x0 139 + +ss.input.port12.jpkeyboard.o keyboard 0x0 18 + +ss.input.port12.jpkeyboard.p keyboard 0x0 19 + +ss.input.port12.jpkeyboard.pagedown keyboard 0x0 78 + +ss.input.port12.jpkeyboard.pageup keyboard 0x0 75 + +ss.input.port12.jpkeyboard.pause keyboard 0x0 72 || keyboard 0x0 83 + +ss.input.port12.jpkeyboard.period keyboard 0x0 55 + +ss.input.port12.jpkeyboard.printscreen keyboard 0x0 70 + +ss.input.port12.jpkeyboard.q keyboard 0x0 20 + +ss.input.port12.jpkeyboard.r keyboard 0x0 21 + +ss.input.port12.jpkeyboard.ralt keyboard 0x0 230 + +ss.input.port12.jpkeyboard.rctrl keyboard 0x0 228 + +ss.input.port12.jpkeyboard.right keyboard 0x0 79 + +ss.input.port12.jpkeyboard.rightbracket keyboard 0x0 49 + +ss.input.port12.jpkeyboard.rshift keyboard 0x0 229 + +ss.input.port12.jpkeyboard.s keyboard 0x0 22 + +ss.input.port12.jpkeyboard.scrolllock keyboard 0x0 71 + +ss.input.port12.jpkeyboard.semicolon keyboard 0x0 51 + +ss.input.port12.jpkeyboard.slash keyboard 0x0 56 + +ss.input.port12.jpkeyboard.space keyboard 0x0 44 + +ss.input.port12.jpkeyboard.t keyboard 0x0 23 + +ss.input.port12.jpkeyboard.tab keyboard 0x0 43 + +ss.input.port12.jpkeyboard.u keyboard 0x0 24 + +ss.input.port12.jpkeyboard.up keyboard 0x0 82 + +ss.input.port12.jpkeyboard.v keyboard 0x0 25 + +ss.input.port12.jpkeyboard.w keyboard 0x0 26 + +ss.input.port12.jpkeyboard.x keyboard 0x0 27 + +ss.input.port12.jpkeyboard.y keyboard 0x0 28 + +ss.input.port12.jpkeyboard.yen keyboard 0x0 137 + +ss.input.port12.jpkeyboard.z keyboard 0x0 29 + +ss.input.port12.keyboard.0 keyboard 0x0 39 + +ss.input.port12.keyboard.1 keyboard 0x0 30 + +ss.input.port12.keyboard.2 keyboard 0x0 31 + +ss.input.port12.keyboard.3 keyboard 0x0 32 + +ss.input.port12.keyboard.4 keyboard 0x0 33 + +ss.input.port12.keyboard.5 keyboard 0x0 34 + +ss.input.port12.keyboard.6 keyboard 0x0 35 + +ss.input.port12.keyboard.7 keyboard 0x0 36 + +ss.input.port12.keyboard.8 keyboard 0x0 37 + +ss.input.port12.keyboard.9 keyboard 0x0 38 + +ss.input.port12.keyboard.a keyboard 0x0 4 + +ss.input.port12.keyboard.b keyboard 0x0 5 + +ss.input.port12.keyboard.backslash keyboard 0x0 49 || keyboard 0x0 135 + +ss.input.port12.keyboard.backspace keyboard 0x0 42 + +ss.input.port12.keyboard.c keyboard 0x0 6 + +ss.input.port12.keyboard.capslock keyboard 0x0 57 + +ss.input.port12.keyboard.comma keyboard 0x0 54 + +ss.input.port12.keyboard.d keyboard 0x0 7 + +ss.input.port12.keyboard.delete keyboard 0x0 76 + +ss.input.port12.keyboard.down keyboard 0x0 81 + +ss.input.port12.keyboard.e keyboard 0x0 8 + +ss.input.port12.keyboard.end keyboard 0x0 77 + +ss.input.port12.keyboard.enter keyboard 0x0 40 + +ss.input.port12.keyboard.equals keyboard 0x0 46 + +ss.input.port12.keyboard.esc keyboard 0x0 41 + +ss.input.port12.keyboard.f keyboard 0x0 9 + +ss.input.port12.keyboard.f1 keyboard 0x0 58 + +ss.input.port12.keyboard.f10 keyboard 0x0 67 + +ss.input.port12.keyboard.f11 keyboard 0x0 68 + +ss.input.port12.keyboard.f12 keyboard 0x0 69 + +ss.input.port12.keyboard.f2 keyboard 0x0 59 + +ss.input.port12.keyboard.f3 keyboard 0x0 60 + +ss.input.port12.keyboard.f4 keyboard 0x0 61 + +ss.input.port12.keyboard.f5 keyboard 0x0 62 + +ss.input.port12.keyboard.f6 keyboard 0x0 63 + +ss.input.port12.keyboard.f7 keyboard 0x0 64 + +ss.input.port12.keyboard.f8 keyboard 0x0 65 + +ss.input.port12.keyboard.f9 keyboard 0x0 66 + +ss.input.port12.keyboard.g keyboard 0x0 10 + +ss.input.port12.keyboard.grave keyboard 0x0 53 + +ss.input.port12.keyboard.h keyboard 0x0 11 + +ss.input.port12.keyboard.home keyboard 0x0 74 + +ss.input.port12.keyboard.i keyboard 0x0 12 + +ss.input.port12.keyboard.insert keyboard 0x0 73 + +ss.input.port12.keyboard.j keyboard 0x0 13 + +ss.input.port12.keyboard.k keyboard 0x0 14 + +ss.input.port12.keyboard.kp_asterisk keyboard 0x0 85 + +ss.input.port12.keyboard.kp_center keyboard 0x0 93 + +ss.input.port12.keyboard.kp_delete keyboard 0x0 99 + +ss.input.port12.keyboard.kp_down keyboard 0x0 90 + +ss.input.port12.keyboard.kp_end keyboard 0x0 89 + +ss.input.port12.keyboard.kp_enter keyboard 0x0 88 + +ss.input.port12.keyboard.kp_home keyboard 0x0 95 + +ss.input.port12.keyboard.kp_insert keyboard 0x0 98 + +ss.input.port12.keyboard.kp_left keyboard 0x0 92 + +ss.input.port12.keyboard.kp_minus keyboard 0x0 86 + +ss.input.port12.keyboard.kp_pagedown keyboard 0x0 91 + +ss.input.port12.keyboard.kp_pageup keyboard 0x0 97 + +ss.input.port12.keyboard.kp_plus keyboard 0x0 87 + +ss.input.port12.keyboard.kp_right keyboard 0x0 94 + +ss.input.port12.keyboard.kp_slash keyboard 0x0 84 + +ss.input.port12.keyboard.kp_up keyboard 0x0 96 + +ss.input.port12.keyboard.l keyboard 0x0 15 + +ss.input.port12.keyboard.lalt keyboard 0x0 226 + +ss.input.port12.keyboard.lctrl keyboard 0x0 224 + +ss.input.port12.keyboard.left keyboard 0x0 80 + +ss.input.port12.keyboard.leftbracket keyboard 0x0 47 + +ss.input.port12.keyboard.lshift keyboard 0x0 225 + +ss.input.port12.keyboard.m keyboard 0x0 16 + +ss.input.port12.keyboard.minus keyboard 0x0 45 + +ss.input.port12.keyboard.n keyboard 0x0 17 + +ss.input.port12.keyboard.numlock keyboard 0x0 83 + +ss.input.port12.keyboard.o keyboard 0x0 18 + +ss.input.port12.keyboard.p keyboard 0x0 19 + +ss.input.port12.keyboard.pagedown keyboard 0x0 78 + +ss.input.port12.keyboard.pageup keyboard 0x0 75 + +ss.input.port12.keyboard.pause keyboard 0x0 72 + +ss.input.port12.keyboard.period keyboard 0x0 55 + +ss.input.port12.keyboard.printscreen keyboard 0x0 70 + +ss.input.port12.keyboard.q keyboard 0x0 20 + +ss.input.port12.keyboard.quote keyboard 0x0 52 + +ss.input.port12.keyboard.r keyboard 0x0 21 + +ss.input.port12.keyboard.ralt keyboard 0x0 230 + +ss.input.port12.keyboard.rctrl keyboard 0x0 228 + +ss.input.port12.keyboard.right keyboard 0x0 79 + +ss.input.port12.keyboard.rightbracket keyboard 0x0 48 + +ss.input.port12.keyboard.rshift keyboard 0x0 229 + +ss.input.port12.keyboard.s keyboard 0x0 22 + +ss.input.port12.keyboard.scrolllock keyboard 0x0 71 + +ss.input.port12.keyboard.semicolon keyboard 0x0 51 + +ss.input.port12.keyboard.slash keyboard 0x0 56 + +ss.input.port12.keyboard.space keyboard 0x0 44 + +ss.input.port12.keyboard.t keyboard 0x0 23 + +ss.input.port12.keyboard.tab keyboard 0x0 43 + +ss.input.port12.keyboard.u keyboard 0x0 24 + +ss.input.port12.keyboard.up keyboard 0x0 82 + +ss.input.port12.keyboard.v keyboard 0x0 25 + +ss.input.port12.keyboard.w keyboard 0x0 26 + +ss.input.port12.keyboard.x keyboard 0x0 27 + +ss.input.port12.keyboard.y keyboard 0x0 28 + +ss.input.port12.keyboard.z keyboard 0x0 29 + +ss.input.port12.mission.a + +ss.input.port12.mission.afa + +ss.input.port12.mission.afa.defpos off + +ss.input.port12.mission.afb + +ss.input.port12.mission.afb.defpos off + +ss.input.port12.mission.afc + +ss.input.port12.mission.afc.defpos off + +ss.input.port12.mission.afl + +ss.input.port12.mission.afl.defpos off + +ss.input.port12.mission.afr + +ss.input.port12.mission.afr.defpos off + +ss.input.port12.mission.afspeed + +ss.input.port12.mission.afspeed.defpos 1 + +ss.input.port12.mission.afx + +ss.input.port12.mission.afx.defpos off + +ss.input.port12.mission.afy + +ss.input.port12.mission.afy.defpos off + +ss.input.port12.mission.afz + +ss.input.port12.mission.afz.defpos off + +ss.input.port12.mission.b + +ss.input.port12.mission.c + +ss.input.port12.mission.l + +ss.input.port12.mission.r + +ss.input.port12.mission.start + +ss.input.port12.mission.stick_back + +ss.input.port12.mission.stick_fore + +ss.input.port12.mission.stick_left + +ss.input.port12.mission.stick_right + +ss.input.port12.mission.throttle_down + +ss.input.port12.mission.throttle_up + +ss.input.port12.mission.x + +ss.input.port12.mission.y + +ss.input.port12.mission.z + +ss.input.port12.mouse.left mouse 0x0 button_left + +ss.input.port12.mouse.middle mouse 0x0 button_middle + +ss.input.port12.mouse.motion_down mouse 0x0 rel_y+ + +ss.input.port12.mouse.motion_left mouse 0x0 rel_x- + +ss.input.port12.mouse.motion_right mouse 0x0 rel_x+ + +ss.input.port12.mouse.motion_up mouse 0x0 rel_y- + +ss.input.port12.mouse.right mouse 0x0 button_right + +ss.input.port12.mouse.start keyboard 0x0 40 + +ss.input.port12.wheel.a + +ss.input.port12.wheel.analog_left + +ss.input.port12.wheel.analog_right + +ss.input.port12.wheel.b + +ss.input.port12.wheel.c + +ss.input.port12.wheel.down + +ss.input.port12.wheel.start + +ss.input.port12.wheel.up + +ss.input.port12.wheel.x + +ss.input.port12.wheel.y + +ss.input.port12.wheel.z + +ss.input.port2 gamepad + +ss.input.port2.3dpad.a + +ss.input.port2.3dpad.analog_down + +ss.input.port2.3dpad.analog_left + +ss.input.port2.3dpad.analog_right + +ss.input.port2.3dpad.analog_up + +ss.input.port2.3dpad.b + +ss.input.port2.3dpad.c + +ss.input.port2.3dpad.down + +ss.input.port2.3dpad.left + +ss.input.port2.3dpad.ls + +ss.input.port2.3dpad.mode + +ss.input.port2.3dpad.mode.defpos digital + +ss.input.port2.3dpad.right + +ss.input.port2.3dpad.rs + +ss.input.port2.3dpad.start + +ss.input.port2.3dpad.up + +ss.input.port2.3dpad.x + +ss.input.port2.3dpad.y + +ss.input.port2.3dpad.z + +ss.input.port2.dmission.a + +ss.input.port2.dmission.afa + +ss.input.port2.dmission.afa.defpos off + +ss.input.port2.dmission.afb + +ss.input.port2.dmission.afb.defpos off + +ss.input.port2.dmission.afc + +ss.input.port2.dmission.afc.defpos off + +ss.input.port2.dmission.afl + +ss.input.port2.dmission.afl.defpos off + +ss.input.port2.dmission.afr + +ss.input.port2.dmission.afr.defpos off + +ss.input.port2.dmission.afspeed + +ss.input.port2.dmission.afspeed.defpos 1 + +ss.input.port2.dmission.afx + +ss.input.port2.dmission.afx.defpos off + +ss.input.port2.dmission.afy + +ss.input.port2.dmission.afy.defpos off + +ss.input.port2.dmission.afz + +ss.input.port2.dmission.afz.defpos off + +ss.input.port2.dmission.b + +ss.input.port2.dmission.c + +ss.input.port2.dmission.l + +ss.input.port2.dmission.lstick_back + +ss.input.port2.dmission.lstick_fore + +ss.input.port2.dmission.lstick_left + +ss.input.port2.dmission.lstick_right + +ss.input.port2.dmission.lthrottle_down + +ss.input.port2.dmission.lthrottle_up + +ss.input.port2.dmission.r + +ss.input.port2.dmission.rstick_back + +ss.input.port2.dmission.rstick_fore + +ss.input.port2.dmission.rstick_left + +ss.input.port2.dmission.rstick_right + +ss.input.port2.dmission.rthrottle_down + +ss.input.port2.dmission.rthrottle_up + +ss.input.port2.dmission.start + +ss.input.port2.dmission.x + +ss.input.port2.dmission.y + +ss.input.port2.dmission.z + +ss.input.port2.gamepad.a + +ss.input.port2.gamepad.b + +ss.input.port2.gamepad.c + +ss.input.port2.gamepad.down + +ss.input.port2.gamepad.left + +ss.input.port2.gamepad.ls + +ss.input.port2.gamepad.right + +ss.input.port2.gamepad.rs + +ss.input.port2.gamepad.start + +ss.input.port2.gamepad.up + +ss.input.port2.gamepad.x + +ss.input.port2.gamepad.y + +ss.input.port2.gamepad.z + +ss.input.port2.gun.offscreen_shot mouse 0x0 button_right + +ss.input.port2.gun.start mouse 0x0 button_middle + +ss.input.port2.gun.trigger mouse 0x0 button_left + +ss.input.port2.gun.x_axis mouse 0x0 cursor_x-+ + +ss.input.port2.gun.y_axis mouse 0x0 cursor_y-+ + +ss.input.port2.gun_chairs 0x00FF00 + +ss.input.port2.jpkeyboard.0 keyboard 0x0 39 + +ss.input.port2.jpkeyboard.1 keyboard 0x0 30 + +ss.input.port2.jpkeyboard.2 keyboard 0x0 31 + +ss.input.port2.jpkeyboard.3 keyboard 0x0 32 + +ss.input.port2.jpkeyboard.4 keyboard 0x0 33 + +ss.input.port2.jpkeyboard.5 keyboard 0x0 34 + +ss.input.port2.jpkeyboard.6 keyboard 0x0 35 + +ss.input.port2.jpkeyboard.7 keyboard 0x0 36 + +ss.input.port2.jpkeyboard.8 keyboard 0x0 37 + +ss.input.port2.jpkeyboard.9 keyboard 0x0 38 + +ss.input.port2.jpkeyboard.a keyboard 0x0 4 + +ss.input.port2.jpkeyboard.at keyboard 0x0 47 + +ss.input.port2.jpkeyboard.b keyboard 0x0 5 + +ss.input.port2.jpkeyboard.backslash keyboard 0x0 135 + +ss.input.port2.jpkeyboard.backspace keyboard 0x0 42 + +ss.input.port2.jpkeyboard.c keyboard 0x0 6 + +ss.input.port2.jpkeyboard.capslock keyboard 0x0 57 + +ss.input.port2.jpkeyboard.circumflex keyboard 0x0 46 + +ss.input.port2.jpkeyboard.colon keyboard 0x0 52 + +ss.input.port2.jpkeyboard.comma keyboard 0x0 54 + +ss.input.port2.jpkeyboard.conv keyboard 0x0 138 + +ss.input.port2.jpkeyboard.d keyboard 0x0 7 + +ss.input.port2.jpkeyboard.delete keyboard 0x0 76 + +ss.input.port2.jpkeyboard.down keyboard 0x0 81 + +ss.input.port2.jpkeyboard.e keyboard 0x0 8 + +ss.input.port2.jpkeyboard.end keyboard 0x0 77 + +ss.input.port2.jpkeyboard.enter keyboard 0x0 40 + +ss.input.port2.jpkeyboard.esc keyboard 0x0 41 + +ss.input.port2.jpkeyboard.f keyboard 0x0 9 + +ss.input.port2.jpkeyboard.f1 keyboard 0x0 58 + +ss.input.port2.jpkeyboard.f10 keyboard 0x0 67 + +ss.input.port2.jpkeyboard.f11 keyboard 0x0 68 + +ss.input.port2.jpkeyboard.f12 keyboard 0x0 69 + +ss.input.port2.jpkeyboard.f2 keyboard 0x0 59 + +ss.input.port2.jpkeyboard.f3 keyboard 0x0 60 + +ss.input.port2.jpkeyboard.f4 keyboard 0x0 61 + +ss.input.port2.jpkeyboard.f5 keyboard 0x0 62 + +ss.input.port2.jpkeyboard.f6 keyboard 0x0 63 + +ss.input.port2.jpkeyboard.f7 keyboard 0x0 64 + +ss.input.port2.jpkeyboard.f8 keyboard 0x0 65 + +ss.input.port2.jpkeyboard.f9 keyboard 0x0 66 + +ss.input.port2.jpkeyboard.g keyboard 0x0 10 + +ss.input.port2.jpkeyboard.h keyboard 0x0 11 + +ss.input.port2.jpkeyboard.hkr keyboard 0x0 136 + +ss.input.port2.jpkeyboard.home keyboard 0x0 74 + +ss.input.port2.jpkeyboard.hwfw keyboard 0x0 53 + +ss.input.port2.jpkeyboard.i keyboard 0x0 12 + +ss.input.port2.jpkeyboard.insert keyboard 0x0 73 + +ss.input.port2.jpkeyboard.j keyboard 0x0 13 + +ss.input.port2.jpkeyboard.k keyboard 0x0 14 + +ss.input.port2.jpkeyboard.l keyboard 0x0 15 + +ss.input.port2.jpkeyboard.lalt keyboard 0x0 226 + +ss.input.port2.jpkeyboard.lctrl keyboard 0x0 224 + +ss.input.port2.jpkeyboard.left keyboard 0x0 80 + +ss.input.port2.jpkeyboard.leftbracket keyboard 0x0 48 + +ss.input.port2.jpkeyboard.lshift keyboard 0x0 225 + +ss.input.port2.jpkeyboard.m keyboard 0x0 16 + +ss.input.port2.jpkeyboard.minus keyboard 0x0 45 + +ss.input.port2.jpkeyboard.n keyboard 0x0 17 + +ss.input.port2.jpkeyboard.nonconv keyboard 0x0 139 + +ss.input.port2.jpkeyboard.o keyboard 0x0 18 + +ss.input.port2.jpkeyboard.p keyboard 0x0 19 + +ss.input.port2.jpkeyboard.pagedown keyboard 0x0 78 + +ss.input.port2.jpkeyboard.pageup keyboard 0x0 75 + +ss.input.port2.jpkeyboard.pause keyboard 0x0 72 || keyboard 0x0 83 + +ss.input.port2.jpkeyboard.period keyboard 0x0 55 + +ss.input.port2.jpkeyboard.printscreen keyboard 0x0 70 + +ss.input.port2.jpkeyboard.q keyboard 0x0 20 + +ss.input.port2.jpkeyboard.r keyboard 0x0 21 + +ss.input.port2.jpkeyboard.ralt keyboard 0x0 230 + +ss.input.port2.jpkeyboard.rctrl keyboard 0x0 228 + +ss.input.port2.jpkeyboard.right keyboard 0x0 79 + +ss.input.port2.jpkeyboard.rightbracket keyboard 0x0 49 + +ss.input.port2.jpkeyboard.rshift keyboard 0x0 229 + +ss.input.port2.jpkeyboard.s keyboard 0x0 22 + +ss.input.port2.jpkeyboard.scrolllock keyboard 0x0 71 + +ss.input.port2.jpkeyboard.semicolon keyboard 0x0 51 + +ss.input.port2.jpkeyboard.slash keyboard 0x0 56 + +ss.input.port2.jpkeyboard.space keyboard 0x0 44 + +ss.input.port2.jpkeyboard.t keyboard 0x0 23 + +ss.input.port2.jpkeyboard.tab keyboard 0x0 43 + +ss.input.port2.jpkeyboard.u keyboard 0x0 24 + +ss.input.port2.jpkeyboard.up keyboard 0x0 82 + +ss.input.port2.jpkeyboard.v keyboard 0x0 25 + +ss.input.port2.jpkeyboard.w keyboard 0x0 26 + +ss.input.port2.jpkeyboard.x keyboard 0x0 27 + +ss.input.port2.jpkeyboard.y keyboard 0x0 28 + +ss.input.port2.jpkeyboard.yen keyboard 0x0 137 + +ss.input.port2.jpkeyboard.z keyboard 0x0 29 + +ss.input.port2.keyboard.0 keyboard 0x0 39 + +ss.input.port2.keyboard.1 keyboard 0x0 30 + +ss.input.port2.keyboard.2 keyboard 0x0 31 + +ss.input.port2.keyboard.3 keyboard 0x0 32 + +ss.input.port2.keyboard.4 keyboard 0x0 33 + +ss.input.port2.keyboard.5 keyboard 0x0 34 + +ss.input.port2.keyboard.6 keyboard 0x0 35 + +ss.input.port2.keyboard.7 keyboard 0x0 36 + +ss.input.port2.keyboard.8 keyboard 0x0 37 + +ss.input.port2.keyboard.9 keyboard 0x0 38 + +ss.input.port2.keyboard.a keyboard 0x0 4 + +ss.input.port2.keyboard.b keyboard 0x0 5 + +ss.input.port2.keyboard.backslash keyboard 0x0 49 || keyboard 0x0 135 + +ss.input.port2.keyboard.backspace keyboard 0x0 42 + +ss.input.port2.keyboard.c keyboard 0x0 6 + +ss.input.port2.keyboard.capslock keyboard 0x0 57 + +ss.input.port2.keyboard.comma keyboard 0x0 54 + +ss.input.port2.keyboard.d keyboard 0x0 7 + +ss.input.port2.keyboard.delete keyboard 0x0 76 + +ss.input.port2.keyboard.down keyboard 0x0 81 + +ss.input.port2.keyboard.e keyboard 0x0 8 + +ss.input.port2.keyboard.end keyboard 0x0 77 + +ss.input.port2.keyboard.enter keyboard 0x0 40 + +ss.input.port2.keyboard.equals keyboard 0x0 46 + +ss.input.port2.keyboard.esc keyboard 0x0 41 + +ss.input.port2.keyboard.f keyboard 0x0 9 + +ss.input.port2.keyboard.f1 keyboard 0x0 58 + +ss.input.port2.keyboard.f10 keyboard 0x0 67 + +ss.input.port2.keyboard.f11 keyboard 0x0 68 + +ss.input.port2.keyboard.f12 keyboard 0x0 69 + +ss.input.port2.keyboard.f2 keyboard 0x0 59 + +ss.input.port2.keyboard.f3 keyboard 0x0 60 + +ss.input.port2.keyboard.f4 keyboard 0x0 61 + +ss.input.port2.keyboard.f5 keyboard 0x0 62 + +ss.input.port2.keyboard.f6 keyboard 0x0 63 + +ss.input.port2.keyboard.f7 keyboard 0x0 64 + +ss.input.port2.keyboard.f8 keyboard 0x0 65 + +ss.input.port2.keyboard.f9 keyboard 0x0 66 + +ss.input.port2.keyboard.g keyboard 0x0 10 + +ss.input.port2.keyboard.grave keyboard 0x0 53 + +ss.input.port2.keyboard.h keyboard 0x0 11 + +ss.input.port2.keyboard.home keyboard 0x0 74 + +ss.input.port2.keyboard.i keyboard 0x0 12 + +ss.input.port2.keyboard.insert keyboard 0x0 73 + +ss.input.port2.keyboard.j keyboard 0x0 13 + +ss.input.port2.keyboard.k keyboard 0x0 14 + +ss.input.port2.keyboard.kp_asterisk keyboard 0x0 85 + +ss.input.port2.keyboard.kp_center keyboard 0x0 93 + +ss.input.port2.keyboard.kp_delete keyboard 0x0 99 + +ss.input.port2.keyboard.kp_down keyboard 0x0 90 + +ss.input.port2.keyboard.kp_end keyboard 0x0 89 + +ss.input.port2.keyboard.kp_enter keyboard 0x0 88 + +ss.input.port2.keyboard.kp_home keyboard 0x0 95 + +ss.input.port2.keyboard.kp_insert keyboard 0x0 98 + +ss.input.port2.keyboard.kp_left keyboard 0x0 92 + +ss.input.port2.keyboard.kp_minus keyboard 0x0 86 + +ss.input.port2.keyboard.kp_pagedown keyboard 0x0 91 + +ss.input.port2.keyboard.kp_pageup keyboard 0x0 97 + +ss.input.port2.keyboard.kp_plus keyboard 0x0 87 + +ss.input.port2.keyboard.kp_right keyboard 0x0 94 + +ss.input.port2.keyboard.kp_slash keyboard 0x0 84 + +ss.input.port2.keyboard.kp_up keyboard 0x0 96 + +ss.input.port2.keyboard.l keyboard 0x0 15 + +ss.input.port2.keyboard.lalt keyboard 0x0 226 + +ss.input.port2.keyboard.lctrl keyboard 0x0 224 + +ss.input.port2.keyboard.left keyboard 0x0 80 + +ss.input.port2.keyboard.leftbracket keyboard 0x0 47 + +ss.input.port2.keyboard.lshift keyboard 0x0 225 + +ss.input.port2.keyboard.m keyboard 0x0 16 + +ss.input.port2.keyboard.minus keyboard 0x0 45 + +ss.input.port2.keyboard.n keyboard 0x0 17 + +ss.input.port2.keyboard.numlock keyboard 0x0 83 + +ss.input.port2.keyboard.o keyboard 0x0 18 + +ss.input.port2.keyboard.p keyboard 0x0 19 + +ss.input.port2.keyboard.pagedown keyboard 0x0 78 + +ss.input.port2.keyboard.pageup keyboard 0x0 75 + +ss.input.port2.keyboard.pause keyboard 0x0 72 + +ss.input.port2.keyboard.period keyboard 0x0 55 + +ss.input.port2.keyboard.printscreen keyboard 0x0 70 + +ss.input.port2.keyboard.q keyboard 0x0 20 + +ss.input.port2.keyboard.quote keyboard 0x0 52 + +ss.input.port2.keyboard.r keyboard 0x0 21 + +ss.input.port2.keyboard.ralt keyboard 0x0 230 + +ss.input.port2.keyboard.rctrl keyboard 0x0 228 + +ss.input.port2.keyboard.right keyboard 0x0 79 + +ss.input.port2.keyboard.rightbracket keyboard 0x0 48 + +ss.input.port2.keyboard.rshift keyboard 0x0 229 + +ss.input.port2.keyboard.s keyboard 0x0 22 + +ss.input.port2.keyboard.scrolllock keyboard 0x0 71 + +ss.input.port2.keyboard.semicolon keyboard 0x0 51 + +ss.input.port2.keyboard.slash keyboard 0x0 56 + +ss.input.port2.keyboard.space keyboard 0x0 44 + +ss.input.port2.keyboard.t keyboard 0x0 23 + +ss.input.port2.keyboard.tab keyboard 0x0 43 + +ss.input.port2.keyboard.u keyboard 0x0 24 + +ss.input.port2.keyboard.up keyboard 0x0 82 + +ss.input.port2.keyboard.v keyboard 0x0 25 + +ss.input.port2.keyboard.w keyboard 0x0 26 + +ss.input.port2.keyboard.x keyboard 0x0 27 + +ss.input.port2.keyboard.y keyboard 0x0 28 + +ss.input.port2.keyboard.z keyboard 0x0 29 + +ss.input.port2.mission.a + +ss.input.port2.mission.afa + +ss.input.port2.mission.afa.defpos off + +ss.input.port2.mission.afb + +ss.input.port2.mission.afb.defpos off + +ss.input.port2.mission.afc + +ss.input.port2.mission.afc.defpos off + +ss.input.port2.mission.afl + +ss.input.port2.mission.afl.defpos off + +ss.input.port2.mission.afr + +ss.input.port2.mission.afr.defpos off + +ss.input.port2.mission.afspeed + +ss.input.port2.mission.afspeed.defpos 1 + +ss.input.port2.mission.afx + +ss.input.port2.mission.afx.defpos off + +ss.input.port2.mission.afy + +ss.input.port2.mission.afy.defpos off + +ss.input.port2.mission.afz + +ss.input.port2.mission.afz.defpos off + +ss.input.port2.mission.b + +ss.input.port2.mission.c + +ss.input.port2.mission.l + +ss.input.port2.mission.r + +ss.input.port2.mission.start + +ss.input.port2.mission.stick_back + +ss.input.port2.mission.stick_fore + +ss.input.port2.mission.stick_left + +ss.input.port2.mission.stick_right + +ss.input.port2.mission.throttle_down + +ss.input.port2.mission.throttle_up + +ss.input.port2.mission.x + +ss.input.port2.mission.y + +ss.input.port2.mission.z + +ss.input.port2.mouse.left mouse 0x0 button_left + +ss.input.port2.mouse.middle mouse 0x0 button_middle + +ss.input.port2.mouse.motion_down mouse 0x0 rel_y+ + +ss.input.port2.mouse.motion_left mouse 0x0 rel_x- + +ss.input.port2.mouse.motion_right mouse 0x0 rel_x+ + +ss.input.port2.mouse.motion_up mouse 0x0 rel_y- + +ss.input.port2.mouse.right mouse 0x0 button_right + +ss.input.port2.mouse.start keyboard 0x0 40 + +ss.input.port2.wheel.a + +ss.input.port2.wheel.analog_left + +ss.input.port2.wheel.analog_right + +ss.input.port2.wheel.b + +ss.input.port2.wheel.c + +ss.input.port2.wheel.down + +ss.input.port2.wheel.start + +ss.input.port2.wheel.up + +ss.input.port2.wheel.x + +ss.input.port2.wheel.y + +ss.input.port2.wheel.z + +ss.input.port3 gamepad + +ss.input.port3.3dpad.a + +ss.input.port3.3dpad.analog_down + +ss.input.port3.3dpad.analog_left + +ss.input.port3.3dpad.analog_right + +ss.input.port3.3dpad.analog_up + +ss.input.port3.3dpad.b + +ss.input.port3.3dpad.c + +ss.input.port3.3dpad.down + +ss.input.port3.3dpad.left + +ss.input.port3.3dpad.ls + +ss.input.port3.3dpad.mode + +ss.input.port3.3dpad.mode.defpos digital + +ss.input.port3.3dpad.right + +ss.input.port3.3dpad.rs + +ss.input.port3.3dpad.start + +ss.input.port3.3dpad.up + +ss.input.port3.3dpad.x + +ss.input.port3.3dpad.y + +ss.input.port3.3dpad.z + +ss.input.port3.dmission.a + +ss.input.port3.dmission.afa + +ss.input.port3.dmission.afa.defpos off + +ss.input.port3.dmission.afb + +ss.input.port3.dmission.afb.defpos off + +ss.input.port3.dmission.afc + +ss.input.port3.dmission.afc.defpos off + +ss.input.port3.dmission.afl + +ss.input.port3.dmission.afl.defpos off + +ss.input.port3.dmission.afr + +ss.input.port3.dmission.afr.defpos off + +ss.input.port3.dmission.afspeed + +ss.input.port3.dmission.afspeed.defpos 1 + +ss.input.port3.dmission.afx + +ss.input.port3.dmission.afx.defpos off + +ss.input.port3.dmission.afy + +ss.input.port3.dmission.afy.defpos off + +ss.input.port3.dmission.afz + +ss.input.port3.dmission.afz.defpos off + +ss.input.port3.dmission.b + +ss.input.port3.dmission.c + +ss.input.port3.dmission.l + +ss.input.port3.dmission.lstick_back + +ss.input.port3.dmission.lstick_fore + +ss.input.port3.dmission.lstick_left + +ss.input.port3.dmission.lstick_right + +ss.input.port3.dmission.lthrottle_down + +ss.input.port3.dmission.lthrottle_up + +ss.input.port3.dmission.r + +ss.input.port3.dmission.rstick_back + +ss.input.port3.dmission.rstick_fore + +ss.input.port3.dmission.rstick_left + +ss.input.port3.dmission.rstick_right + +ss.input.port3.dmission.rthrottle_down + +ss.input.port3.dmission.rthrottle_up + +ss.input.port3.dmission.start + +ss.input.port3.dmission.x + +ss.input.port3.dmission.y + +ss.input.port3.dmission.z + +ss.input.port3.gamepad.a + +ss.input.port3.gamepad.b + +ss.input.port3.gamepad.c + +ss.input.port3.gamepad.down + +ss.input.port3.gamepad.left + +ss.input.port3.gamepad.ls + +ss.input.port3.gamepad.right + +ss.input.port3.gamepad.rs + +ss.input.port3.gamepad.start + +ss.input.port3.gamepad.up + +ss.input.port3.gamepad.x + +ss.input.port3.gamepad.y + +ss.input.port3.gamepad.z + +ss.input.port3.gun.offscreen_shot mouse 0x0 button_right + +ss.input.port3.gun.start mouse 0x0 button_middle + +ss.input.port3.gun.trigger mouse 0x0 button_left + +ss.input.port3.gun.x_axis mouse 0x0 cursor_x-+ + +ss.input.port3.gun.y_axis mouse 0x0 cursor_y-+ + +ss.input.port3.gun_chairs 0xFF00FF + +ss.input.port3.jpkeyboard.0 keyboard 0x0 39 + +ss.input.port3.jpkeyboard.1 keyboard 0x0 30 + +ss.input.port3.jpkeyboard.2 keyboard 0x0 31 + +ss.input.port3.jpkeyboard.3 keyboard 0x0 32 + +ss.input.port3.jpkeyboard.4 keyboard 0x0 33 + +ss.input.port3.jpkeyboard.5 keyboard 0x0 34 + +ss.input.port3.jpkeyboard.6 keyboard 0x0 35 + +ss.input.port3.jpkeyboard.7 keyboard 0x0 36 + +ss.input.port3.jpkeyboard.8 keyboard 0x0 37 + +ss.input.port3.jpkeyboard.9 keyboard 0x0 38 + +ss.input.port3.jpkeyboard.a keyboard 0x0 4 + +ss.input.port3.jpkeyboard.at keyboard 0x0 47 + +ss.input.port3.jpkeyboard.b keyboard 0x0 5 + +ss.input.port3.jpkeyboard.backslash keyboard 0x0 135 + +ss.input.port3.jpkeyboard.backspace keyboard 0x0 42 + +ss.input.port3.jpkeyboard.c keyboard 0x0 6 + +ss.input.port3.jpkeyboard.capslock keyboard 0x0 57 + +ss.input.port3.jpkeyboard.circumflex keyboard 0x0 46 + +ss.input.port3.jpkeyboard.colon keyboard 0x0 52 + +ss.input.port3.jpkeyboard.comma keyboard 0x0 54 + +ss.input.port3.jpkeyboard.conv keyboard 0x0 138 + +ss.input.port3.jpkeyboard.d keyboard 0x0 7 + +ss.input.port3.jpkeyboard.delete keyboard 0x0 76 + +ss.input.port3.jpkeyboard.down keyboard 0x0 81 + +ss.input.port3.jpkeyboard.e keyboard 0x0 8 + +ss.input.port3.jpkeyboard.end keyboard 0x0 77 + +ss.input.port3.jpkeyboard.enter keyboard 0x0 40 + +ss.input.port3.jpkeyboard.esc keyboard 0x0 41 + +ss.input.port3.jpkeyboard.f keyboard 0x0 9 + +ss.input.port3.jpkeyboard.f1 keyboard 0x0 58 + +ss.input.port3.jpkeyboard.f10 keyboard 0x0 67 + +ss.input.port3.jpkeyboard.f11 keyboard 0x0 68 + +ss.input.port3.jpkeyboard.f12 keyboard 0x0 69 + +ss.input.port3.jpkeyboard.f2 keyboard 0x0 59 + +ss.input.port3.jpkeyboard.f3 keyboard 0x0 60 + +ss.input.port3.jpkeyboard.f4 keyboard 0x0 61 + +ss.input.port3.jpkeyboard.f5 keyboard 0x0 62 + +ss.input.port3.jpkeyboard.f6 keyboard 0x0 63 + +ss.input.port3.jpkeyboard.f7 keyboard 0x0 64 + +ss.input.port3.jpkeyboard.f8 keyboard 0x0 65 + +ss.input.port3.jpkeyboard.f9 keyboard 0x0 66 + +ss.input.port3.jpkeyboard.g keyboard 0x0 10 + +ss.input.port3.jpkeyboard.h keyboard 0x0 11 + +ss.input.port3.jpkeyboard.hkr keyboard 0x0 136 + +ss.input.port3.jpkeyboard.home keyboard 0x0 74 + +ss.input.port3.jpkeyboard.hwfw keyboard 0x0 53 + +ss.input.port3.jpkeyboard.i keyboard 0x0 12 + +ss.input.port3.jpkeyboard.insert keyboard 0x0 73 + +ss.input.port3.jpkeyboard.j keyboard 0x0 13 + +ss.input.port3.jpkeyboard.k keyboard 0x0 14 + +ss.input.port3.jpkeyboard.l keyboard 0x0 15 + +ss.input.port3.jpkeyboard.lalt keyboard 0x0 226 + +ss.input.port3.jpkeyboard.lctrl keyboard 0x0 224 + +ss.input.port3.jpkeyboard.left keyboard 0x0 80 + +ss.input.port3.jpkeyboard.leftbracket keyboard 0x0 48 + +ss.input.port3.jpkeyboard.lshift keyboard 0x0 225 + +ss.input.port3.jpkeyboard.m keyboard 0x0 16 + +ss.input.port3.jpkeyboard.minus keyboard 0x0 45 + +ss.input.port3.jpkeyboard.n keyboard 0x0 17 + +ss.input.port3.jpkeyboard.nonconv keyboard 0x0 139 + +ss.input.port3.jpkeyboard.o keyboard 0x0 18 + +ss.input.port3.jpkeyboard.p keyboard 0x0 19 + +ss.input.port3.jpkeyboard.pagedown keyboard 0x0 78 + +ss.input.port3.jpkeyboard.pageup keyboard 0x0 75 + +ss.input.port3.jpkeyboard.pause keyboard 0x0 72 || keyboard 0x0 83 + +ss.input.port3.jpkeyboard.period keyboard 0x0 55 + +ss.input.port3.jpkeyboard.printscreen keyboard 0x0 70 + +ss.input.port3.jpkeyboard.q keyboard 0x0 20 + +ss.input.port3.jpkeyboard.r keyboard 0x0 21 + +ss.input.port3.jpkeyboard.ralt keyboard 0x0 230 + +ss.input.port3.jpkeyboard.rctrl keyboard 0x0 228 + +ss.input.port3.jpkeyboard.right keyboard 0x0 79 + +ss.input.port3.jpkeyboard.rightbracket keyboard 0x0 49 + +ss.input.port3.jpkeyboard.rshift keyboard 0x0 229 + +ss.input.port3.jpkeyboard.s keyboard 0x0 22 + +ss.input.port3.jpkeyboard.scrolllock keyboard 0x0 71 + +ss.input.port3.jpkeyboard.semicolon keyboard 0x0 51 + +ss.input.port3.jpkeyboard.slash keyboard 0x0 56 + +ss.input.port3.jpkeyboard.space keyboard 0x0 44 + +ss.input.port3.jpkeyboard.t keyboard 0x0 23 + +ss.input.port3.jpkeyboard.tab keyboard 0x0 43 + +ss.input.port3.jpkeyboard.u keyboard 0x0 24 + +ss.input.port3.jpkeyboard.up keyboard 0x0 82 + +ss.input.port3.jpkeyboard.v keyboard 0x0 25 + +ss.input.port3.jpkeyboard.w keyboard 0x0 26 + +ss.input.port3.jpkeyboard.x keyboard 0x0 27 + +ss.input.port3.jpkeyboard.y keyboard 0x0 28 + +ss.input.port3.jpkeyboard.yen keyboard 0x0 137 + +ss.input.port3.jpkeyboard.z keyboard 0x0 29 + +ss.input.port3.keyboard.0 keyboard 0x0 39 + +ss.input.port3.keyboard.1 keyboard 0x0 30 + +ss.input.port3.keyboard.2 keyboard 0x0 31 + +ss.input.port3.keyboard.3 keyboard 0x0 32 + +ss.input.port3.keyboard.4 keyboard 0x0 33 + +ss.input.port3.keyboard.5 keyboard 0x0 34 + +ss.input.port3.keyboard.6 keyboard 0x0 35 + +ss.input.port3.keyboard.7 keyboard 0x0 36 + +ss.input.port3.keyboard.8 keyboard 0x0 37 + +ss.input.port3.keyboard.9 keyboard 0x0 38 + +ss.input.port3.keyboard.a keyboard 0x0 4 + +ss.input.port3.keyboard.b keyboard 0x0 5 + +ss.input.port3.keyboard.backslash keyboard 0x0 49 || keyboard 0x0 135 + +ss.input.port3.keyboard.backspace keyboard 0x0 42 + +ss.input.port3.keyboard.c keyboard 0x0 6 + +ss.input.port3.keyboard.capslock keyboard 0x0 57 + +ss.input.port3.keyboard.comma keyboard 0x0 54 + +ss.input.port3.keyboard.d keyboard 0x0 7 + +ss.input.port3.keyboard.delete keyboard 0x0 76 + +ss.input.port3.keyboard.down keyboard 0x0 81 + +ss.input.port3.keyboard.e keyboard 0x0 8 + +ss.input.port3.keyboard.end keyboard 0x0 77 + +ss.input.port3.keyboard.enter keyboard 0x0 40 + +ss.input.port3.keyboard.equals keyboard 0x0 46 + +ss.input.port3.keyboard.esc keyboard 0x0 41 + +ss.input.port3.keyboard.f keyboard 0x0 9 + +ss.input.port3.keyboard.f1 keyboard 0x0 58 + +ss.input.port3.keyboard.f10 keyboard 0x0 67 + +ss.input.port3.keyboard.f11 keyboard 0x0 68 + +ss.input.port3.keyboard.f12 keyboard 0x0 69 + +ss.input.port3.keyboard.f2 keyboard 0x0 59 + +ss.input.port3.keyboard.f3 keyboard 0x0 60 + +ss.input.port3.keyboard.f4 keyboard 0x0 61 + +ss.input.port3.keyboard.f5 keyboard 0x0 62 + +ss.input.port3.keyboard.f6 keyboard 0x0 63 + +ss.input.port3.keyboard.f7 keyboard 0x0 64 + +ss.input.port3.keyboard.f8 keyboard 0x0 65 + +ss.input.port3.keyboard.f9 keyboard 0x0 66 + +ss.input.port3.keyboard.g keyboard 0x0 10 + +ss.input.port3.keyboard.grave keyboard 0x0 53 + +ss.input.port3.keyboard.h keyboard 0x0 11 + +ss.input.port3.keyboard.home keyboard 0x0 74 + +ss.input.port3.keyboard.i keyboard 0x0 12 + +ss.input.port3.keyboard.insert keyboard 0x0 73 + +ss.input.port3.keyboard.j keyboard 0x0 13 + +ss.input.port3.keyboard.k keyboard 0x0 14 + +ss.input.port3.keyboard.kp_asterisk keyboard 0x0 85 + +ss.input.port3.keyboard.kp_center keyboard 0x0 93 + +ss.input.port3.keyboard.kp_delete keyboard 0x0 99 + +ss.input.port3.keyboard.kp_down keyboard 0x0 90 + +ss.input.port3.keyboard.kp_end keyboard 0x0 89 + +ss.input.port3.keyboard.kp_enter keyboard 0x0 88 + +ss.input.port3.keyboard.kp_home keyboard 0x0 95 + +ss.input.port3.keyboard.kp_insert keyboard 0x0 98 + +ss.input.port3.keyboard.kp_left keyboard 0x0 92 + +ss.input.port3.keyboard.kp_minus keyboard 0x0 86 + +ss.input.port3.keyboard.kp_pagedown keyboard 0x0 91 + +ss.input.port3.keyboard.kp_pageup keyboard 0x0 97 + +ss.input.port3.keyboard.kp_plus keyboard 0x0 87 + +ss.input.port3.keyboard.kp_right keyboard 0x0 94 + +ss.input.port3.keyboard.kp_slash keyboard 0x0 84 + +ss.input.port3.keyboard.kp_up keyboard 0x0 96 + +ss.input.port3.keyboard.l keyboard 0x0 15 + +ss.input.port3.keyboard.lalt keyboard 0x0 226 + +ss.input.port3.keyboard.lctrl keyboard 0x0 224 + +ss.input.port3.keyboard.left keyboard 0x0 80 + +ss.input.port3.keyboard.leftbracket keyboard 0x0 47 + +ss.input.port3.keyboard.lshift keyboard 0x0 225 + +ss.input.port3.keyboard.m keyboard 0x0 16 + +ss.input.port3.keyboard.minus keyboard 0x0 45 + +ss.input.port3.keyboard.n keyboard 0x0 17 + +ss.input.port3.keyboard.numlock keyboard 0x0 83 + +ss.input.port3.keyboard.o keyboard 0x0 18 + +ss.input.port3.keyboard.p keyboard 0x0 19 + +ss.input.port3.keyboard.pagedown keyboard 0x0 78 + +ss.input.port3.keyboard.pageup keyboard 0x0 75 + +ss.input.port3.keyboard.pause keyboard 0x0 72 + +ss.input.port3.keyboard.period keyboard 0x0 55 + +ss.input.port3.keyboard.printscreen keyboard 0x0 70 + +ss.input.port3.keyboard.q keyboard 0x0 20 + +ss.input.port3.keyboard.quote keyboard 0x0 52 + +ss.input.port3.keyboard.r keyboard 0x0 21 + +ss.input.port3.keyboard.ralt keyboard 0x0 230 + +ss.input.port3.keyboard.rctrl keyboard 0x0 228 + +ss.input.port3.keyboard.right keyboard 0x0 79 + +ss.input.port3.keyboard.rightbracket keyboard 0x0 48 + +ss.input.port3.keyboard.rshift keyboard 0x0 229 + +ss.input.port3.keyboard.s keyboard 0x0 22 + +ss.input.port3.keyboard.scrolllock keyboard 0x0 71 + +ss.input.port3.keyboard.semicolon keyboard 0x0 51 + +ss.input.port3.keyboard.slash keyboard 0x0 56 + +ss.input.port3.keyboard.space keyboard 0x0 44 + +ss.input.port3.keyboard.t keyboard 0x0 23 + +ss.input.port3.keyboard.tab keyboard 0x0 43 + +ss.input.port3.keyboard.u keyboard 0x0 24 + +ss.input.port3.keyboard.up keyboard 0x0 82 + +ss.input.port3.keyboard.v keyboard 0x0 25 + +ss.input.port3.keyboard.w keyboard 0x0 26 + +ss.input.port3.keyboard.x keyboard 0x0 27 + +ss.input.port3.keyboard.y keyboard 0x0 28 + +ss.input.port3.keyboard.z keyboard 0x0 29 + +ss.input.port3.mission.a + +ss.input.port3.mission.afa + +ss.input.port3.mission.afa.defpos off + +ss.input.port3.mission.afb + +ss.input.port3.mission.afb.defpos off + +ss.input.port3.mission.afc + +ss.input.port3.mission.afc.defpos off + +ss.input.port3.mission.afl + +ss.input.port3.mission.afl.defpos off + +ss.input.port3.mission.afr + +ss.input.port3.mission.afr.defpos off + +ss.input.port3.mission.afspeed + +ss.input.port3.mission.afspeed.defpos 1 + +ss.input.port3.mission.afx + +ss.input.port3.mission.afx.defpos off + +ss.input.port3.mission.afy + +ss.input.port3.mission.afy.defpos off + +ss.input.port3.mission.afz + +ss.input.port3.mission.afz.defpos off + +ss.input.port3.mission.b + +ss.input.port3.mission.c + +ss.input.port3.mission.l + +ss.input.port3.mission.r + +ss.input.port3.mission.start + +ss.input.port3.mission.stick_back + +ss.input.port3.mission.stick_fore + +ss.input.port3.mission.stick_left + +ss.input.port3.mission.stick_right + +ss.input.port3.mission.throttle_down + +ss.input.port3.mission.throttle_up + +ss.input.port3.mission.x + +ss.input.port3.mission.y + +ss.input.port3.mission.z + +ss.input.port3.mouse.left mouse 0x0 button_left + +ss.input.port3.mouse.middle mouse 0x0 button_middle + +ss.input.port3.mouse.motion_down mouse 0x0 rel_y+ + +ss.input.port3.mouse.motion_left mouse 0x0 rel_x- + +ss.input.port3.mouse.motion_right mouse 0x0 rel_x+ + +ss.input.port3.mouse.motion_up mouse 0x0 rel_y- + +ss.input.port3.mouse.right mouse 0x0 button_right + +ss.input.port3.mouse.start keyboard 0x0 40 + +ss.input.port3.wheel.a + +ss.input.port3.wheel.analog_left + +ss.input.port3.wheel.analog_right + +ss.input.port3.wheel.b + +ss.input.port3.wheel.c + +ss.input.port3.wheel.down + +ss.input.port3.wheel.start + +ss.input.port3.wheel.up + +ss.input.port3.wheel.x + +ss.input.port3.wheel.y + +ss.input.port3.wheel.z + +ss.input.port4 gamepad + +ss.input.port4.3dpad.a + +ss.input.port4.3dpad.analog_down + +ss.input.port4.3dpad.analog_left + +ss.input.port4.3dpad.analog_right + +ss.input.port4.3dpad.analog_up + +ss.input.port4.3dpad.b + +ss.input.port4.3dpad.c + +ss.input.port4.3dpad.down + +ss.input.port4.3dpad.left + +ss.input.port4.3dpad.ls + +ss.input.port4.3dpad.mode + +ss.input.port4.3dpad.mode.defpos digital + +ss.input.port4.3dpad.right + +ss.input.port4.3dpad.rs + +ss.input.port4.3dpad.start + +ss.input.port4.3dpad.up + +ss.input.port4.3dpad.x + +ss.input.port4.3dpad.y + +ss.input.port4.3dpad.z + +ss.input.port4.dmission.a + +ss.input.port4.dmission.afa + +ss.input.port4.dmission.afa.defpos off + +ss.input.port4.dmission.afb + +ss.input.port4.dmission.afb.defpos off + +ss.input.port4.dmission.afc + +ss.input.port4.dmission.afc.defpos off + +ss.input.port4.dmission.afl + +ss.input.port4.dmission.afl.defpos off + +ss.input.port4.dmission.afr + +ss.input.port4.dmission.afr.defpos off + +ss.input.port4.dmission.afspeed + +ss.input.port4.dmission.afspeed.defpos 1 + +ss.input.port4.dmission.afx + +ss.input.port4.dmission.afx.defpos off + +ss.input.port4.dmission.afy + +ss.input.port4.dmission.afy.defpos off + +ss.input.port4.dmission.afz + +ss.input.port4.dmission.afz.defpos off + +ss.input.port4.dmission.b + +ss.input.port4.dmission.c + +ss.input.port4.dmission.l + +ss.input.port4.dmission.lstick_back + +ss.input.port4.dmission.lstick_fore + +ss.input.port4.dmission.lstick_left + +ss.input.port4.dmission.lstick_right + +ss.input.port4.dmission.lthrottle_down + +ss.input.port4.dmission.lthrottle_up + +ss.input.port4.dmission.r + +ss.input.port4.dmission.rstick_back + +ss.input.port4.dmission.rstick_fore + +ss.input.port4.dmission.rstick_left + +ss.input.port4.dmission.rstick_right + +ss.input.port4.dmission.rthrottle_down + +ss.input.port4.dmission.rthrottle_up + +ss.input.port4.dmission.start + +ss.input.port4.dmission.x + +ss.input.port4.dmission.y + +ss.input.port4.dmission.z + +ss.input.port4.gamepad.a + +ss.input.port4.gamepad.b + +ss.input.port4.gamepad.c + +ss.input.port4.gamepad.down + +ss.input.port4.gamepad.left + +ss.input.port4.gamepad.ls + +ss.input.port4.gamepad.right + +ss.input.port4.gamepad.rs + +ss.input.port4.gamepad.start + +ss.input.port4.gamepad.up + +ss.input.port4.gamepad.x + +ss.input.port4.gamepad.y + +ss.input.port4.gamepad.z + +ss.input.port4.gun.offscreen_shot mouse 0x0 button_right + +ss.input.port4.gun.start mouse 0x0 button_middle + +ss.input.port4.gun.trigger mouse 0x0 button_left + +ss.input.port4.gun.x_axis mouse 0x0 cursor_x-+ + +ss.input.port4.gun.y_axis mouse 0x0 cursor_y-+ + +ss.input.port4.gun_chairs 0xFF8000 + +ss.input.port4.jpkeyboard.0 keyboard 0x0 39 + +ss.input.port4.jpkeyboard.1 keyboard 0x0 30 + +ss.input.port4.jpkeyboard.2 keyboard 0x0 31 + +ss.input.port4.jpkeyboard.3 keyboard 0x0 32 + +ss.input.port4.jpkeyboard.4 keyboard 0x0 33 + +ss.input.port4.jpkeyboard.5 keyboard 0x0 34 + +ss.input.port4.jpkeyboard.6 keyboard 0x0 35 + +ss.input.port4.jpkeyboard.7 keyboard 0x0 36 + +ss.input.port4.jpkeyboard.8 keyboard 0x0 37 + +ss.input.port4.jpkeyboard.9 keyboard 0x0 38 + +ss.input.port4.jpkeyboard.a keyboard 0x0 4 + +ss.input.port4.jpkeyboard.at keyboard 0x0 47 + +ss.input.port4.jpkeyboard.b keyboard 0x0 5 + +ss.input.port4.jpkeyboard.backslash keyboard 0x0 135 + +ss.input.port4.jpkeyboard.backspace keyboard 0x0 42 + +ss.input.port4.jpkeyboard.c keyboard 0x0 6 + +ss.input.port4.jpkeyboard.capslock keyboard 0x0 57 + +ss.input.port4.jpkeyboard.circumflex keyboard 0x0 46 + +ss.input.port4.jpkeyboard.colon keyboard 0x0 52 + +ss.input.port4.jpkeyboard.comma keyboard 0x0 54 + +ss.input.port4.jpkeyboard.conv keyboard 0x0 138 + +ss.input.port4.jpkeyboard.d keyboard 0x0 7 + +ss.input.port4.jpkeyboard.delete keyboard 0x0 76 + +ss.input.port4.jpkeyboard.down keyboard 0x0 81 + +ss.input.port4.jpkeyboard.e keyboard 0x0 8 + +ss.input.port4.jpkeyboard.end keyboard 0x0 77 + +ss.input.port4.jpkeyboard.enter keyboard 0x0 40 + +ss.input.port4.jpkeyboard.esc keyboard 0x0 41 + +ss.input.port4.jpkeyboard.f keyboard 0x0 9 + +ss.input.port4.jpkeyboard.f1 keyboard 0x0 58 + +ss.input.port4.jpkeyboard.f10 keyboard 0x0 67 + +ss.input.port4.jpkeyboard.f11 keyboard 0x0 68 + +ss.input.port4.jpkeyboard.f12 keyboard 0x0 69 + +ss.input.port4.jpkeyboard.f2 keyboard 0x0 59 + +ss.input.port4.jpkeyboard.f3 keyboard 0x0 60 + +ss.input.port4.jpkeyboard.f4 keyboard 0x0 61 + +ss.input.port4.jpkeyboard.f5 keyboard 0x0 62 + +ss.input.port4.jpkeyboard.f6 keyboard 0x0 63 + +ss.input.port4.jpkeyboard.f7 keyboard 0x0 64 + +ss.input.port4.jpkeyboard.f8 keyboard 0x0 65 + +ss.input.port4.jpkeyboard.f9 keyboard 0x0 66 + +ss.input.port4.jpkeyboard.g keyboard 0x0 10 + +ss.input.port4.jpkeyboard.h keyboard 0x0 11 + +ss.input.port4.jpkeyboard.hkr keyboard 0x0 136 + +ss.input.port4.jpkeyboard.home keyboard 0x0 74 + +ss.input.port4.jpkeyboard.hwfw keyboard 0x0 53 + +ss.input.port4.jpkeyboard.i keyboard 0x0 12 + +ss.input.port4.jpkeyboard.insert keyboard 0x0 73 + +ss.input.port4.jpkeyboard.j keyboard 0x0 13 + +ss.input.port4.jpkeyboard.k keyboard 0x0 14 + +ss.input.port4.jpkeyboard.l keyboard 0x0 15 + +ss.input.port4.jpkeyboard.lalt keyboard 0x0 226 + +ss.input.port4.jpkeyboard.lctrl keyboard 0x0 224 + +ss.input.port4.jpkeyboard.left keyboard 0x0 80 + +ss.input.port4.jpkeyboard.leftbracket keyboard 0x0 48 + +ss.input.port4.jpkeyboard.lshift keyboard 0x0 225 + +ss.input.port4.jpkeyboard.m keyboard 0x0 16 + +ss.input.port4.jpkeyboard.minus keyboard 0x0 45 + +ss.input.port4.jpkeyboard.n keyboard 0x0 17 + +ss.input.port4.jpkeyboard.nonconv keyboard 0x0 139 + +ss.input.port4.jpkeyboard.o keyboard 0x0 18 + +ss.input.port4.jpkeyboard.p keyboard 0x0 19 + +ss.input.port4.jpkeyboard.pagedown keyboard 0x0 78 + +ss.input.port4.jpkeyboard.pageup keyboard 0x0 75 + +ss.input.port4.jpkeyboard.pause keyboard 0x0 72 || keyboard 0x0 83 + +ss.input.port4.jpkeyboard.period keyboard 0x0 55 + +ss.input.port4.jpkeyboard.printscreen keyboard 0x0 70 + +ss.input.port4.jpkeyboard.q keyboard 0x0 20 + +ss.input.port4.jpkeyboard.r keyboard 0x0 21 + +ss.input.port4.jpkeyboard.ralt keyboard 0x0 230 + +ss.input.port4.jpkeyboard.rctrl keyboard 0x0 228 + +ss.input.port4.jpkeyboard.right keyboard 0x0 79 + +ss.input.port4.jpkeyboard.rightbracket keyboard 0x0 49 + +ss.input.port4.jpkeyboard.rshift keyboard 0x0 229 + +ss.input.port4.jpkeyboard.s keyboard 0x0 22 + +ss.input.port4.jpkeyboard.scrolllock keyboard 0x0 71 + +ss.input.port4.jpkeyboard.semicolon keyboard 0x0 51 + +ss.input.port4.jpkeyboard.slash keyboard 0x0 56 + +ss.input.port4.jpkeyboard.space keyboard 0x0 44 + +ss.input.port4.jpkeyboard.t keyboard 0x0 23 + +ss.input.port4.jpkeyboard.tab keyboard 0x0 43 + +ss.input.port4.jpkeyboard.u keyboard 0x0 24 + +ss.input.port4.jpkeyboard.up keyboard 0x0 82 + +ss.input.port4.jpkeyboard.v keyboard 0x0 25 + +ss.input.port4.jpkeyboard.w keyboard 0x0 26 + +ss.input.port4.jpkeyboard.x keyboard 0x0 27 + +ss.input.port4.jpkeyboard.y keyboard 0x0 28 + +ss.input.port4.jpkeyboard.yen keyboard 0x0 137 + +ss.input.port4.jpkeyboard.z keyboard 0x0 29 + +ss.input.port4.keyboard.0 keyboard 0x0 39 + +ss.input.port4.keyboard.1 keyboard 0x0 30 + +ss.input.port4.keyboard.2 keyboard 0x0 31 + +ss.input.port4.keyboard.3 keyboard 0x0 32 + +ss.input.port4.keyboard.4 keyboard 0x0 33 + +ss.input.port4.keyboard.5 keyboard 0x0 34 + +ss.input.port4.keyboard.6 keyboard 0x0 35 + +ss.input.port4.keyboard.7 keyboard 0x0 36 + +ss.input.port4.keyboard.8 keyboard 0x0 37 + +ss.input.port4.keyboard.9 keyboard 0x0 38 + +ss.input.port4.keyboard.a keyboard 0x0 4 + +ss.input.port4.keyboard.b keyboard 0x0 5 + +ss.input.port4.keyboard.backslash keyboard 0x0 49 || keyboard 0x0 135 + +ss.input.port4.keyboard.backspace keyboard 0x0 42 + +ss.input.port4.keyboard.c keyboard 0x0 6 + +ss.input.port4.keyboard.capslock keyboard 0x0 57 + +ss.input.port4.keyboard.comma keyboard 0x0 54 + +ss.input.port4.keyboard.d keyboard 0x0 7 + +ss.input.port4.keyboard.delete keyboard 0x0 76 + +ss.input.port4.keyboard.down keyboard 0x0 81 + +ss.input.port4.keyboard.e keyboard 0x0 8 + +ss.input.port4.keyboard.end keyboard 0x0 77 + +ss.input.port4.keyboard.enter keyboard 0x0 40 + +ss.input.port4.keyboard.equals keyboard 0x0 46 + +ss.input.port4.keyboard.esc keyboard 0x0 41 + +ss.input.port4.keyboard.f keyboard 0x0 9 + +ss.input.port4.keyboard.f1 keyboard 0x0 58 + +ss.input.port4.keyboard.f10 keyboard 0x0 67 + +ss.input.port4.keyboard.f11 keyboard 0x0 68 + +ss.input.port4.keyboard.f12 keyboard 0x0 69 + +ss.input.port4.keyboard.f2 keyboard 0x0 59 + +ss.input.port4.keyboard.f3 keyboard 0x0 60 + +ss.input.port4.keyboard.f4 keyboard 0x0 61 + +ss.input.port4.keyboard.f5 keyboard 0x0 62 + +ss.input.port4.keyboard.f6 keyboard 0x0 63 + +ss.input.port4.keyboard.f7 keyboard 0x0 64 + +ss.input.port4.keyboard.f8 keyboard 0x0 65 + +ss.input.port4.keyboard.f9 keyboard 0x0 66 + +ss.input.port4.keyboard.g keyboard 0x0 10 + +ss.input.port4.keyboard.grave keyboard 0x0 53 + +ss.input.port4.keyboard.h keyboard 0x0 11 + +ss.input.port4.keyboard.home keyboard 0x0 74 + +ss.input.port4.keyboard.i keyboard 0x0 12 + +ss.input.port4.keyboard.insert keyboard 0x0 73 + +ss.input.port4.keyboard.j keyboard 0x0 13 + +ss.input.port4.keyboard.k keyboard 0x0 14 + +ss.input.port4.keyboard.kp_asterisk keyboard 0x0 85 + +ss.input.port4.keyboard.kp_center keyboard 0x0 93 + +ss.input.port4.keyboard.kp_delete keyboard 0x0 99 + +ss.input.port4.keyboard.kp_down keyboard 0x0 90 + +ss.input.port4.keyboard.kp_end keyboard 0x0 89 + +ss.input.port4.keyboard.kp_enter keyboard 0x0 88 + +ss.input.port4.keyboard.kp_home keyboard 0x0 95 + +ss.input.port4.keyboard.kp_insert keyboard 0x0 98 + +ss.input.port4.keyboard.kp_left keyboard 0x0 92 + +ss.input.port4.keyboard.kp_minus keyboard 0x0 86 + +ss.input.port4.keyboard.kp_pagedown keyboard 0x0 91 + +ss.input.port4.keyboard.kp_pageup keyboard 0x0 97 + +ss.input.port4.keyboard.kp_plus keyboard 0x0 87 + +ss.input.port4.keyboard.kp_right keyboard 0x0 94 + +ss.input.port4.keyboard.kp_slash keyboard 0x0 84 + +ss.input.port4.keyboard.kp_up keyboard 0x0 96 + +ss.input.port4.keyboard.l keyboard 0x0 15 + +ss.input.port4.keyboard.lalt keyboard 0x0 226 + +ss.input.port4.keyboard.lctrl keyboard 0x0 224 + +ss.input.port4.keyboard.left keyboard 0x0 80 + +ss.input.port4.keyboard.leftbracket keyboard 0x0 47 + +ss.input.port4.keyboard.lshift keyboard 0x0 225 + +ss.input.port4.keyboard.m keyboard 0x0 16 + +ss.input.port4.keyboard.minus keyboard 0x0 45 + +ss.input.port4.keyboard.n keyboard 0x0 17 + +ss.input.port4.keyboard.numlock keyboard 0x0 83 + +ss.input.port4.keyboard.o keyboard 0x0 18 + +ss.input.port4.keyboard.p keyboard 0x0 19 + +ss.input.port4.keyboard.pagedown keyboard 0x0 78 + +ss.input.port4.keyboard.pageup keyboard 0x0 75 + +ss.input.port4.keyboard.pause keyboard 0x0 72 + +ss.input.port4.keyboard.period keyboard 0x0 55 + +ss.input.port4.keyboard.printscreen keyboard 0x0 70 + +ss.input.port4.keyboard.q keyboard 0x0 20 + +ss.input.port4.keyboard.quote keyboard 0x0 52 + +ss.input.port4.keyboard.r keyboard 0x0 21 + +ss.input.port4.keyboard.ralt keyboard 0x0 230 + +ss.input.port4.keyboard.rctrl keyboard 0x0 228 + +ss.input.port4.keyboard.right keyboard 0x0 79 + +ss.input.port4.keyboard.rightbracket keyboard 0x0 48 + +ss.input.port4.keyboard.rshift keyboard 0x0 229 + +ss.input.port4.keyboard.s keyboard 0x0 22 + +ss.input.port4.keyboard.scrolllock keyboard 0x0 71 + +ss.input.port4.keyboard.semicolon keyboard 0x0 51 + +ss.input.port4.keyboard.slash keyboard 0x0 56 + +ss.input.port4.keyboard.space keyboard 0x0 44 + +ss.input.port4.keyboard.t keyboard 0x0 23 + +ss.input.port4.keyboard.tab keyboard 0x0 43 + +ss.input.port4.keyboard.u keyboard 0x0 24 + +ss.input.port4.keyboard.up keyboard 0x0 82 + +ss.input.port4.keyboard.v keyboard 0x0 25 + +ss.input.port4.keyboard.w keyboard 0x0 26 + +ss.input.port4.keyboard.x keyboard 0x0 27 + +ss.input.port4.keyboard.y keyboard 0x0 28 + +ss.input.port4.keyboard.z keyboard 0x0 29 + +ss.input.port4.mission.a + +ss.input.port4.mission.afa + +ss.input.port4.mission.afa.defpos off + +ss.input.port4.mission.afb + +ss.input.port4.mission.afb.defpos off + +ss.input.port4.mission.afc + +ss.input.port4.mission.afc.defpos off + +ss.input.port4.mission.afl + +ss.input.port4.mission.afl.defpos off + +ss.input.port4.mission.afr + +ss.input.port4.mission.afr.defpos off + +ss.input.port4.mission.afspeed + +ss.input.port4.mission.afspeed.defpos 1 + +ss.input.port4.mission.afx + +ss.input.port4.mission.afx.defpos off + +ss.input.port4.mission.afy + +ss.input.port4.mission.afy.defpos off + +ss.input.port4.mission.afz + +ss.input.port4.mission.afz.defpos off + +ss.input.port4.mission.b + +ss.input.port4.mission.c + +ss.input.port4.mission.l + +ss.input.port4.mission.r + +ss.input.port4.mission.start + +ss.input.port4.mission.stick_back + +ss.input.port4.mission.stick_fore + +ss.input.port4.mission.stick_left + +ss.input.port4.mission.stick_right + +ss.input.port4.mission.throttle_down + +ss.input.port4.mission.throttle_up + +ss.input.port4.mission.x + +ss.input.port4.mission.y + +ss.input.port4.mission.z + +ss.input.port4.mouse.left mouse 0x0 button_left + +ss.input.port4.mouse.middle mouse 0x0 button_middle + +ss.input.port4.mouse.motion_down mouse 0x0 rel_y+ + +ss.input.port4.mouse.motion_left mouse 0x0 rel_x- + +ss.input.port4.mouse.motion_right mouse 0x0 rel_x+ + +ss.input.port4.mouse.motion_up mouse 0x0 rel_y- + +ss.input.port4.mouse.right mouse 0x0 button_right + +ss.input.port4.mouse.start keyboard 0x0 40 + +ss.input.port4.wheel.a + +ss.input.port4.wheel.analog_left + +ss.input.port4.wheel.analog_right + +ss.input.port4.wheel.b + +ss.input.port4.wheel.c + +ss.input.port4.wheel.down + +ss.input.port4.wheel.start + +ss.input.port4.wheel.up + +ss.input.port4.wheel.x + +ss.input.port4.wheel.y + +ss.input.port4.wheel.z + +ss.input.port5 gamepad + +ss.input.port5.3dpad.a + +ss.input.port5.3dpad.analog_down + +ss.input.port5.3dpad.analog_left + +ss.input.port5.3dpad.analog_right + +ss.input.port5.3dpad.analog_up + +ss.input.port5.3dpad.b + +ss.input.port5.3dpad.c + +ss.input.port5.3dpad.down + +ss.input.port5.3dpad.left + +ss.input.port5.3dpad.ls + +ss.input.port5.3dpad.mode + +ss.input.port5.3dpad.mode.defpos digital + +ss.input.port5.3dpad.right + +ss.input.port5.3dpad.rs + +ss.input.port5.3dpad.start + +ss.input.port5.3dpad.up + +ss.input.port5.3dpad.x + +ss.input.port5.3dpad.y + +ss.input.port5.3dpad.z + +ss.input.port5.dmission.a + +ss.input.port5.dmission.afa + +ss.input.port5.dmission.afa.defpos off + +ss.input.port5.dmission.afb + +ss.input.port5.dmission.afb.defpos off + +ss.input.port5.dmission.afc + +ss.input.port5.dmission.afc.defpos off + +ss.input.port5.dmission.afl + +ss.input.port5.dmission.afl.defpos off + +ss.input.port5.dmission.afr + +ss.input.port5.dmission.afr.defpos off + +ss.input.port5.dmission.afspeed + +ss.input.port5.dmission.afspeed.defpos 1 + +ss.input.port5.dmission.afx + +ss.input.port5.dmission.afx.defpos off + +ss.input.port5.dmission.afy + +ss.input.port5.dmission.afy.defpos off + +ss.input.port5.dmission.afz + +ss.input.port5.dmission.afz.defpos off + +ss.input.port5.dmission.b + +ss.input.port5.dmission.c + +ss.input.port5.dmission.l + +ss.input.port5.dmission.lstick_back + +ss.input.port5.dmission.lstick_fore + +ss.input.port5.dmission.lstick_left + +ss.input.port5.dmission.lstick_right + +ss.input.port5.dmission.lthrottle_down + +ss.input.port5.dmission.lthrottle_up + +ss.input.port5.dmission.r + +ss.input.port5.dmission.rstick_back + +ss.input.port5.dmission.rstick_fore + +ss.input.port5.dmission.rstick_left + +ss.input.port5.dmission.rstick_right + +ss.input.port5.dmission.rthrottle_down + +ss.input.port5.dmission.rthrottle_up + +ss.input.port5.dmission.start + +ss.input.port5.dmission.x + +ss.input.port5.dmission.y + +ss.input.port5.dmission.z + +ss.input.port5.gamepad.a + +ss.input.port5.gamepad.b + +ss.input.port5.gamepad.c + +ss.input.port5.gamepad.down + +ss.input.port5.gamepad.left + +ss.input.port5.gamepad.ls + +ss.input.port5.gamepad.right + +ss.input.port5.gamepad.rs + +ss.input.port5.gamepad.start + +ss.input.port5.gamepad.up + +ss.input.port5.gamepad.x + +ss.input.port5.gamepad.y + +ss.input.port5.gamepad.z + +ss.input.port5.gun.offscreen_shot mouse 0x0 button_right + +ss.input.port5.gun.start mouse 0x0 button_middle + +ss.input.port5.gun.trigger mouse 0x0 button_left + +ss.input.port5.gun.x_axis mouse 0x0 cursor_x-+ + +ss.input.port5.gun.y_axis mouse 0x0 cursor_y-+ + +ss.input.port5.gun_chairs 0xFFFF00 + +ss.input.port5.jpkeyboard.0 keyboard 0x0 39 + +ss.input.port5.jpkeyboard.1 keyboard 0x0 30 + +ss.input.port5.jpkeyboard.2 keyboard 0x0 31 + +ss.input.port5.jpkeyboard.3 keyboard 0x0 32 + +ss.input.port5.jpkeyboard.4 keyboard 0x0 33 + +ss.input.port5.jpkeyboard.5 keyboard 0x0 34 + +ss.input.port5.jpkeyboard.6 keyboard 0x0 35 + +ss.input.port5.jpkeyboard.7 keyboard 0x0 36 + +ss.input.port5.jpkeyboard.8 keyboard 0x0 37 + +ss.input.port5.jpkeyboard.9 keyboard 0x0 38 + +ss.input.port5.jpkeyboard.a keyboard 0x0 4 + +ss.input.port5.jpkeyboard.at keyboard 0x0 47 + +ss.input.port5.jpkeyboard.b keyboard 0x0 5 + +ss.input.port5.jpkeyboard.backslash keyboard 0x0 135 + +ss.input.port5.jpkeyboard.backspace keyboard 0x0 42 + +ss.input.port5.jpkeyboard.c keyboard 0x0 6 + +ss.input.port5.jpkeyboard.capslock keyboard 0x0 57 + +ss.input.port5.jpkeyboard.circumflex keyboard 0x0 46 + +ss.input.port5.jpkeyboard.colon keyboard 0x0 52 + +ss.input.port5.jpkeyboard.comma keyboard 0x0 54 + +ss.input.port5.jpkeyboard.conv keyboard 0x0 138 + +ss.input.port5.jpkeyboard.d keyboard 0x0 7 + +ss.input.port5.jpkeyboard.delete keyboard 0x0 76 + +ss.input.port5.jpkeyboard.down keyboard 0x0 81 + +ss.input.port5.jpkeyboard.e keyboard 0x0 8 + +ss.input.port5.jpkeyboard.end keyboard 0x0 77 + +ss.input.port5.jpkeyboard.enter keyboard 0x0 40 + +ss.input.port5.jpkeyboard.esc keyboard 0x0 41 + +ss.input.port5.jpkeyboard.f keyboard 0x0 9 + +ss.input.port5.jpkeyboard.f1 keyboard 0x0 58 + +ss.input.port5.jpkeyboard.f10 keyboard 0x0 67 + +ss.input.port5.jpkeyboard.f11 keyboard 0x0 68 + +ss.input.port5.jpkeyboard.f12 keyboard 0x0 69 + +ss.input.port5.jpkeyboard.f2 keyboard 0x0 59 + +ss.input.port5.jpkeyboard.f3 keyboard 0x0 60 + +ss.input.port5.jpkeyboard.f4 keyboard 0x0 61 + +ss.input.port5.jpkeyboard.f5 keyboard 0x0 62 + +ss.input.port5.jpkeyboard.f6 keyboard 0x0 63 + +ss.input.port5.jpkeyboard.f7 keyboard 0x0 64 + +ss.input.port5.jpkeyboard.f8 keyboard 0x0 65 + +ss.input.port5.jpkeyboard.f9 keyboard 0x0 66 + +ss.input.port5.jpkeyboard.g keyboard 0x0 10 + +ss.input.port5.jpkeyboard.h keyboard 0x0 11 + +ss.input.port5.jpkeyboard.hkr keyboard 0x0 136 + +ss.input.port5.jpkeyboard.home keyboard 0x0 74 + +ss.input.port5.jpkeyboard.hwfw keyboard 0x0 53 + +ss.input.port5.jpkeyboard.i keyboard 0x0 12 + +ss.input.port5.jpkeyboard.insert keyboard 0x0 73 + +ss.input.port5.jpkeyboard.j keyboard 0x0 13 + +ss.input.port5.jpkeyboard.k keyboard 0x0 14 + +ss.input.port5.jpkeyboard.l keyboard 0x0 15 + +ss.input.port5.jpkeyboard.lalt keyboard 0x0 226 + +ss.input.port5.jpkeyboard.lctrl keyboard 0x0 224 + +ss.input.port5.jpkeyboard.left keyboard 0x0 80 + +ss.input.port5.jpkeyboard.leftbracket keyboard 0x0 48 + +ss.input.port5.jpkeyboard.lshift keyboard 0x0 225 + +ss.input.port5.jpkeyboard.m keyboard 0x0 16 + +ss.input.port5.jpkeyboard.minus keyboard 0x0 45 + +ss.input.port5.jpkeyboard.n keyboard 0x0 17 + +ss.input.port5.jpkeyboard.nonconv keyboard 0x0 139 + +ss.input.port5.jpkeyboard.o keyboard 0x0 18 + +ss.input.port5.jpkeyboard.p keyboard 0x0 19 + +ss.input.port5.jpkeyboard.pagedown keyboard 0x0 78 + +ss.input.port5.jpkeyboard.pageup keyboard 0x0 75 + +ss.input.port5.jpkeyboard.pause keyboard 0x0 72 || keyboard 0x0 83 + +ss.input.port5.jpkeyboard.period keyboard 0x0 55 + +ss.input.port5.jpkeyboard.printscreen keyboard 0x0 70 + +ss.input.port5.jpkeyboard.q keyboard 0x0 20 + +ss.input.port5.jpkeyboard.r keyboard 0x0 21 + +ss.input.port5.jpkeyboard.ralt keyboard 0x0 230 + +ss.input.port5.jpkeyboard.rctrl keyboard 0x0 228 + +ss.input.port5.jpkeyboard.right keyboard 0x0 79 + +ss.input.port5.jpkeyboard.rightbracket keyboard 0x0 49 + +ss.input.port5.jpkeyboard.rshift keyboard 0x0 229 + +ss.input.port5.jpkeyboard.s keyboard 0x0 22 + +ss.input.port5.jpkeyboard.scrolllock keyboard 0x0 71 + +ss.input.port5.jpkeyboard.semicolon keyboard 0x0 51 + +ss.input.port5.jpkeyboard.slash keyboard 0x0 56 + +ss.input.port5.jpkeyboard.space keyboard 0x0 44 + +ss.input.port5.jpkeyboard.t keyboard 0x0 23 + +ss.input.port5.jpkeyboard.tab keyboard 0x0 43 + +ss.input.port5.jpkeyboard.u keyboard 0x0 24 + +ss.input.port5.jpkeyboard.up keyboard 0x0 82 + +ss.input.port5.jpkeyboard.v keyboard 0x0 25 + +ss.input.port5.jpkeyboard.w keyboard 0x0 26 + +ss.input.port5.jpkeyboard.x keyboard 0x0 27 + +ss.input.port5.jpkeyboard.y keyboard 0x0 28 + +ss.input.port5.jpkeyboard.yen keyboard 0x0 137 + +ss.input.port5.jpkeyboard.z keyboard 0x0 29 + +ss.input.port5.keyboard.0 keyboard 0x0 39 + +ss.input.port5.keyboard.1 keyboard 0x0 30 + +ss.input.port5.keyboard.2 keyboard 0x0 31 + +ss.input.port5.keyboard.3 keyboard 0x0 32 + +ss.input.port5.keyboard.4 keyboard 0x0 33 + +ss.input.port5.keyboard.5 keyboard 0x0 34 + +ss.input.port5.keyboard.6 keyboard 0x0 35 + +ss.input.port5.keyboard.7 keyboard 0x0 36 + +ss.input.port5.keyboard.8 keyboard 0x0 37 + +ss.input.port5.keyboard.9 keyboard 0x0 38 + +ss.input.port5.keyboard.a keyboard 0x0 4 + +ss.input.port5.keyboard.b keyboard 0x0 5 + +ss.input.port5.keyboard.backslash keyboard 0x0 49 || keyboard 0x0 135 + +ss.input.port5.keyboard.backspace keyboard 0x0 42 + +ss.input.port5.keyboard.c keyboard 0x0 6 + +ss.input.port5.keyboard.capslock keyboard 0x0 57 + +ss.input.port5.keyboard.comma keyboard 0x0 54 + +ss.input.port5.keyboard.d keyboard 0x0 7 + +ss.input.port5.keyboard.delete keyboard 0x0 76 + +ss.input.port5.keyboard.down keyboard 0x0 81 + +ss.input.port5.keyboard.e keyboard 0x0 8 + +ss.input.port5.keyboard.end keyboard 0x0 77 + +ss.input.port5.keyboard.enter keyboard 0x0 40 + +ss.input.port5.keyboard.equals keyboard 0x0 46 + +ss.input.port5.keyboard.esc keyboard 0x0 41 + +ss.input.port5.keyboard.f keyboard 0x0 9 + +ss.input.port5.keyboard.f1 keyboard 0x0 58 + +ss.input.port5.keyboard.f10 keyboard 0x0 67 + +ss.input.port5.keyboard.f11 keyboard 0x0 68 + +ss.input.port5.keyboard.f12 keyboard 0x0 69 + +ss.input.port5.keyboard.f2 keyboard 0x0 59 + +ss.input.port5.keyboard.f3 keyboard 0x0 60 + +ss.input.port5.keyboard.f4 keyboard 0x0 61 + +ss.input.port5.keyboard.f5 keyboard 0x0 62 + +ss.input.port5.keyboard.f6 keyboard 0x0 63 + +ss.input.port5.keyboard.f7 keyboard 0x0 64 + +ss.input.port5.keyboard.f8 keyboard 0x0 65 + +ss.input.port5.keyboard.f9 keyboard 0x0 66 + +ss.input.port5.keyboard.g keyboard 0x0 10 + +ss.input.port5.keyboard.grave keyboard 0x0 53 + +ss.input.port5.keyboard.h keyboard 0x0 11 + +ss.input.port5.keyboard.home keyboard 0x0 74 + +ss.input.port5.keyboard.i keyboard 0x0 12 + +ss.input.port5.keyboard.insert keyboard 0x0 73 + +ss.input.port5.keyboard.j keyboard 0x0 13 + +ss.input.port5.keyboard.k keyboard 0x0 14 + +ss.input.port5.keyboard.kp_asterisk keyboard 0x0 85 + +ss.input.port5.keyboard.kp_center keyboard 0x0 93 + +ss.input.port5.keyboard.kp_delete keyboard 0x0 99 + +ss.input.port5.keyboard.kp_down keyboard 0x0 90 + +ss.input.port5.keyboard.kp_end keyboard 0x0 89 + +ss.input.port5.keyboard.kp_enter keyboard 0x0 88 + +ss.input.port5.keyboard.kp_home keyboard 0x0 95 + +ss.input.port5.keyboard.kp_insert keyboard 0x0 98 + +ss.input.port5.keyboard.kp_left keyboard 0x0 92 + +ss.input.port5.keyboard.kp_minus keyboard 0x0 86 + +ss.input.port5.keyboard.kp_pagedown keyboard 0x0 91 + +ss.input.port5.keyboard.kp_pageup keyboard 0x0 97 + +ss.input.port5.keyboard.kp_plus keyboard 0x0 87 + +ss.input.port5.keyboard.kp_right keyboard 0x0 94 + +ss.input.port5.keyboard.kp_slash keyboard 0x0 84 + +ss.input.port5.keyboard.kp_up keyboard 0x0 96 + +ss.input.port5.keyboard.l keyboard 0x0 15 + +ss.input.port5.keyboard.lalt keyboard 0x0 226 + +ss.input.port5.keyboard.lctrl keyboard 0x0 224 + +ss.input.port5.keyboard.left keyboard 0x0 80 + +ss.input.port5.keyboard.leftbracket keyboard 0x0 47 + +ss.input.port5.keyboard.lshift keyboard 0x0 225 + +ss.input.port5.keyboard.m keyboard 0x0 16 + +ss.input.port5.keyboard.minus keyboard 0x0 45 + +ss.input.port5.keyboard.n keyboard 0x0 17 + +ss.input.port5.keyboard.numlock keyboard 0x0 83 + +ss.input.port5.keyboard.o keyboard 0x0 18 + +ss.input.port5.keyboard.p keyboard 0x0 19 + +ss.input.port5.keyboard.pagedown keyboard 0x0 78 + +ss.input.port5.keyboard.pageup keyboard 0x0 75 + +ss.input.port5.keyboard.pause keyboard 0x0 72 + +ss.input.port5.keyboard.period keyboard 0x0 55 + +ss.input.port5.keyboard.printscreen keyboard 0x0 70 + +ss.input.port5.keyboard.q keyboard 0x0 20 + +ss.input.port5.keyboard.quote keyboard 0x0 52 + +ss.input.port5.keyboard.r keyboard 0x0 21 + +ss.input.port5.keyboard.ralt keyboard 0x0 230 + +ss.input.port5.keyboard.rctrl keyboard 0x0 228 + +ss.input.port5.keyboard.right keyboard 0x0 79 + +ss.input.port5.keyboard.rightbracket keyboard 0x0 48 + +ss.input.port5.keyboard.rshift keyboard 0x0 229 + +ss.input.port5.keyboard.s keyboard 0x0 22 + +ss.input.port5.keyboard.scrolllock keyboard 0x0 71 + +ss.input.port5.keyboard.semicolon keyboard 0x0 51 + +ss.input.port5.keyboard.slash keyboard 0x0 56 + +ss.input.port5.keyboard.space keyboard 0x0 44 + +ss.input.port5.keyboard.t keyboard 0x0 23 + +ss.input.port5.keyboard.tab keyboard 0x0 43 + +ss.input.port5.keyboard.u keyboard 0x0 24 + +ss.input.port5.keyboard.up keyboard 0x0 82 + +ss.input.port5.keyboard.v keyboard 0x0 25 + +ss.input.port5.keyboard.w keyboard 0x0 26 + +ss.input.port5.keyboard.x keyboard 0x0 27 + +ss.input.port5.keyboard.y keyboard 0x0 28 + +ss.input.port5.keyboard.z keyboard 0x0 29 + +ss.input.port5.mission.a + +ss.input.port5.mission.afa + +ss.input.port5.mission.afa.defpos off + +ss.input.port5.mission.afb + +ss.input.port5.mission.afb.defpos off + +ss.input.port5.mission.afc + +ss.input.port5.mission.afc.defpos off + +ss.input.port5.mission.afl + +ss.input.port5.mission.afl.defpos off + +ss.input.port5.mission.afr + +ss.input.port5.mission.afr.defpos off + +ss.input.port5.mission.afspeed + +ss.input.port5.mission.afspeed.defpos 1 + +ss.input.port5.mission.afx + +ss.input.port5.mission.afx.defpos off + +ss.input.port5.mission.afy + +ss.input.port5.mission.afy.defpos off + +ss.input.port5.mission.afz + +ss.input.port5.mission.afz.defpos off + +ss.input.port5.mission.b + +ss.input.port5.mission.c + +ss.input.port5.mission.l + +ss.input.port5.mission.r + +ss.input.port5.mission.start + +ss.input.port5.mission.stick_back + +ss.input.port5.mission.stick_fore + +ss.input.port5.mission.stick_left + +ss.input.port5.mission.stick_right + +ss.input.port5.mission.throttle_down + +ss.input.port5.mission.throttle_up + +ss.input.port5.mission.x + +ss.input.port5.mission.y + +ss.input.port5.mission.z + +ss.input.port5.mouse.left mouse 0x0 button_left + +ss.input.port5.mouse.middle mouse 0x0 button_middle + +ss.input.port5.mouse.motion_down mouse 0x0 rel_y+ + +ss.input.port5.mouse.motion_left mouse 0x0 rel_x- + +ss.input.port5.mouse.motion_right mouse 0x0 rel_x+ + +ss.input.port5.mouse.motion_up mouse 0x0 rel_y- + +ss.input.port5.mouse.right mouse 0x0 button_right + +ss.input.port5.mouse.start keyboard 0x0 40 + +ss.input.port5.wheel.a + +ss.input.port5.wheel.analog_left + +ss.input.port5.wheel.analog_right + +ss.input.port5.wheel.b + +ss.input.port5.wheel.c + +ss.input.port5.wheel.down + +ss.input.port5.wheel.start + +ss.input.port5.wheel.up + +ss.input.port5.wheel.x + +ss.input.port5.wheel.y + +ss.input.port5.wheel.z + +ss.input.port6 gamepad + +ss.input.port6.3dpad.a + +ss.input.port6.3dpad.analog_down + +ss.input.port6.3dpad.analog_left + +ss.input.port6.3dpad.analog_right + +ss.input.port6.3dpad.analog_up + +ss.input.port6.3dpad.b + +ss.input.port6.3dpad.c + +ss.input.port6.3dpad.down + +ss.input.port6.3dpad.left + +ss.input.port6.3dpad.ls + +ss.input.port6.3dpad.mode + +ss.input.port6.3dpad.mode.defpos digital + +ss.input.port6.3dpad.right + +ss.input.port6.3dpad.rs + +ss.input.port6.3dpad.start + +ss.input.port6.3dpad.up + +ss.input.port6.3dpad.x + +ss.input.port6.3dpad.y + +ss.input.port6.3dpad.z + +ss.input.port6.dmission.a + +ss.input.port6.dmission.afa + +ss.input.port6.dmission.afa.defpos off + +ss.input.port6.dmission.afb + +ss.input.port6.dmission.afb.defpos off + +ss.input.port6.dmission.afc + +ss.input.port6.dmission.afc.defpos off + +ss.input.port6.dmission.afl + +ss.input.port6.dmission.afl.defpos off + +ss.input.port6.dmission.afr + +ss.input.port6.dmission.afr.defpos off + +ss.input.port6.dmission.afspeed + +ss.input.port6.dmission.afspeed.defpos 1 + +ss.input.port6.dmission.afx + +ss.input.port6.dmission.afx.defpos off + +ss.input.port6.dmission.afy + +ss.input.port6.dmission.afy.defpos off + +ss.input.port6.dmission.afz + +ss.input.port6.dmission.afz.defpos off + +ss.input.port6.dmission.b + +ss.input.port6.dmission.c + +ss.input.port6.dmission.l + +ss.input.port6.dmission.lstick_back + +ss.input.port6.dmission.lstick_fore + +ss.input.port6.dmission.lstick_left + +ss.input.port6.dmission.lstick_right + +ss.input.port6.dmission.lthrottle_down + +ss.input.port6.dmission.lthrottle_up + +ss.input.port6.dmission.r + +ss.input.port6.dmission.rstick_back + +ss.input.port6.dmission.rstick_fore + +ss.input.port6.dmission.rstick_left + +ss.input.port6.dmission.rstick_right + +ss.input.port6.dmission.rthrottle_down + +ss.input.port6.dmission.rthrottle_up + +ss.input.port6.dmission.start + +ss.input.port6.dmission.x + +ss.input.port6.dmission.y + +ss.input.port6.dmission.z + +ss.input.port6.gamepad.a + +ss.input.port6.gamepad.b + +ss.input.port6.gamepad.c + +ss.input.port6.gamepad.down + +ss.input.port6.gamepad.left + +ss.input.port6.gamepad.ls + +ss.input.port6.gamepad.right + +ss.input.port6.gamepad.rs + +ss.input.port6.gamepad.start + +ss.input.port6.gamepad.up + +ss.input.port6.gamepad.x + +ss.input.port6.gamepad.y + +ss.input.port6.gamepad.z + +ss.input.port6.gun.offscreen_shot mouse 0x0 button_right + +ss.input.port6.gun.start mouse 0x0 button_middle + +ss.input.port6.gun.trigger mouse 0x0 button_left + +ss.input.port6.gun.x_axis mouse 0x0 cursor_x-+ + +ss.input.port6.gun.y_axis mouse 0x0 cursor_y-+ + +ss.input.port6.gun_chairs 0x00FFFF + +ss.input.port6.jpkeyboard.0 keyboard 0x0 39 + +ss.input.port6.jpkeyboard.1 keyboard 0x0 30 + +ss.input.port6.jpkeyboard.2 keyboard 0x0 31 + +ss.input.port6.jpkeyboard.3 keyboard 0x0 32 + +ss.input.port6.jpkeyboard.4 keyboard 0x0 33 + +ss.input.port6.jpkeyboard.5 keyboard 0x0 34 + +ss.input.port6.jpkeyboard.6 keyboard 0x0 35 + +ss.input.port6.jpkeyboard.7 keyboard 0x0 36 + +ss.input.port6.jpkeyboard.8 keyboard 0x0 37 + +ss.input.port6.jpkeyboard.9 keyboard 0x0 38 + +ss.input.port6.jpkeyboard.a keyboard 0x0 4 + +ss.input.port6.jpkeyboard.at keyboard 0x0 47 + +ss.input.port6.jpkeyboard.b keyboard 0x0 5 + +ss.input.port6.jpkeyboard.backslash keyboard 0x0 135 + +ss.input.port6.jpkeyboard.backspace keyboard 0x0 42 + +ss.input.port6.jpkeyboard.c keyboard 0x0 6 + +ss.input.port6.jpkeyboard.capslock keyboard 0x0 57 + +ss.input.port6.jpkeyboard.circumflex keyboard 0x0 46 + +ss.input.port6.jpkeyboard.colon keyboard 0x0 52 + +ss.input.port6.jpkeyboard.comma keyboard 0x0 54 + +ss.input.port6.jpkeyboard.conv keyboard 0x0 138 + +ss.input.port6.jpkeyboard.d keyboard 0x0 7 + +ss.input.port6.jpkeyboard.delete keyboard 0x0 76 + +ss.input.port6.jpkeyboard.down keyboard 0x0 81 + +ss.input.port6.jpkeyboard.e keyboard 0x0 8 + +ss.input.port6.jpkeyboard.end keyboard 0x0 77 + +ss.input.port6.jpkeyboard.enter keyboard 0x0 40 + +ss.input.port6.jpkeyboard.esc keyboard 0x0 41 + +ss.input.port6.jpkeyboard.f keyboard 0x0 9 + +ss.input.port6.jpkeyboard.f1 keyboard 0x0 58 + +ss.input.port6.jpkeyboard.f10 keyboard 0x0 67 + +ss.input.port6.jpkeyboard.f11 keyboard 0x0 68 + +ss.input.port6.jpkeyboard.f12 keyboard 0x0 69 + +ss.input.port6.jpkeyboard.f2 keyboard 0x0 59 + +ss.input.port6.jpkeyboard.f3 keyboard 0x0 60 + +ss.input.port6.jpkeyboard.f4 keyboard 0x0 61 + +ss.input.port6.jpkeyboard.f5 keyboard 0x0 62 + +ss.input.port6.jpkeyboard.f6 keyboard 0x0 63 + +ss.input.port6.jpkeyboard.f7 keyboard 0x0 64 + +ss.input.port6.jpkeyboard.f8 keyboard 0x0 65 + +ss.input.port6.jpkeyboard.f9 keyboard 0x0 66 + +ss.input.port6.jpkeyboard.g keyboard 0x0 10 + +ss.input.port6.jpkeyboard.h keyboard 0x0 11 + +ss.input.port6.jpkeyboard.hkr keyboard 0x0 136 + +ss.input.port6.jpkeyboard.home keyboard 0x0 74 + +ss.input.port6.jpkeyboard.hwfw keyboard 0x0 53 + +ss.input.port6.jpkeyboard.i keyboard 0x0 12 + +ss.input.port6.jpkeyboard.insert keyboard 0x0 73 + +ss.input.port6.jpkeyboard.j keyboard 0x0 13 + +ss.input.port6.jpkeyboard.k keyboard 0x0 14 + +ss.input.port6.jpkeyboard.l keyboard 0x0 15 + +ss.input.port6.jpkeyboard.lalt keyboard 0x0 226 + +ss.input.port6.jpkeyboard.lctrl keyboard 0x0 224 + +ss.input.port6.jpkeyboard.left keyboard 0x0 80 + +ss.input.port6.jpkeyboard.leftbracket keyboard 0x0 48 + +ss.input.port6.jpkeyboard.lshift keyboard 0x0 225 + +ss.input.port6.jpkeyboard.m keyboard 0x0 16 + +ss.input.port6.jpkeyboard.minus keyboard 0x0 45 + +ss.input.port6.jpkeyboard.n keyboard 0x0 17 + +ss.input.port6.jpkeyboard.nonconv keyboard 0x0 139 + +ss.input.port6.jpkeyboard.o keyboard 0x0 18 + +ss.input.port6.jpkeyboard.p keyboard 0x0 19 + +ss.input.port6.jpkeyboard.pagedown keyboard 0x0 78 + +ss.input.port6.jpkeyboard.pageup keyboard 0x0 75 + +ss.input.port6.jpkeyboard.pause keyboard 0x0 72 || keyboard 0x0 83 + +ss.input.port6.jpkeyboard.period keyboard 0x0 55 + +ss.input.port6.jpkeyboard.printscreen keyboard 0x0 70 + +ss.input.port6.jpkeyboard.q keyboard 0x0 20 + +ss.input.port6.jpkeyboard.r keyboard 0x0 21 + +ss.input.port6.jpkeyboard.ralt keyboard 0x0 230 + +ss.input.port6.jpkeyboard.rctrl keyboard 0x0 228 + +ss.input.port6.jpkeyboard.right keyboard 0x0 79 + +ss.input.port6.jpkeyboard.rightbracket keyboard 0x0 49 + +ss.input.port6.jpkeyboard.rshift keyboard 0x0 229 + +ss.input.port6.jpkeyboard.s keyboard 0x0 22 + +ss.input.port6.jpkeyboard.scrolllock keyboard 0x0 71 + +ss.input.port6.jpkeyboard.semicolon keyboard 0x0 51 + +ss.input.port6.jpkeyboard.slash keyboard 0x0 56 + +ss.input.port6.jpkeyboard.space keyboard 0x0 44 + +ss.input.port6.jpkeyboard.t keyboard 0x0 23 + +ss.input.port6.jpkeyboard.tab keyboard 0x0 43 + +ss.input.port6.jpkeyboard.u keyboard 0x0 24 + +ss.input.port6.jpkeyboard.up keyboard 0x0 82 + +ss.input.port6.jpkeyboard.v keyboard 0x0 25 + +ss.input.port6.jpkeyboard.w keyboard 0x0 26 + +ss.input.port6.jpkeyboard.x keyboard 0x0 27 + +ss.input.port6.jpkeyboard.y keyboard 0x0 28 + +ss.input.port6.jpkeyboard.yen keyboard 0x0 137 + +ss.input.port6.jpkeyboard.z keyboard 0x0 29 + +ss.input.port6.keyboard.0 keyboard 0x0 39 + +ss.input.port6.keyboard.1 keyboard 0x0 30 + +ss.input.port6.keyboard.2 keyboard 0x0 31 + +ss.input.port6.keyboard.3 keyboard 0x0 32 + +ss.input.port6.keyboard.4 keyboard 0x0 33 + +ss.input.port6.keyboard.5 keyboard 0x0 34 + +ss.input.port6.keyboard.6 keyboard 0x0 35 + +ss.input.port6.keyboard.7 keyboard 0x0 36 + +ss.input.port6.keyboard.8 keyboard 0x0 37 + +ss.input.port6.keyboard.9 keyboard 0x0 38 + +ss.input.port6.keyboard.a keyboard 0x0 4 + +ss.input.port6.keyboard.b keyboard 0x0 5 + +ss.input.port6.keyboard.backslash keyboard 0x0 49 || keyboard 0x0 135 + +ss.input.port6.keyboard.backspace keyboard 0x0 42 + +ss.input.port6.keyboard.c keyboard 0x0 6 + +ss.input.port6.keyboard.capslock keyboard 0x0 57 + +ss.input.port6.keyboard.comma keyboard 0x0 54 + +ss.input.port6.keyboard.d keyboard 0x0 7 + +ss.input.port6.keyboard.delete keyboard 0x0 76 + +ss.input.port6.keyboard.down keyboard 0x0 81 + +ss.input.port6.keyboard.e keyboard 0x0 8 + +ss.input.port6.keyboard.end keyboard 0x0 77 + +ss.input.port6.keyboard.enter keyboard 0x0 40 + +ss.input.port6.keyboard.equals keyboard 0x0 46 + +ss.input.port6.keyboard.esc keyboard 0x0 41 + +ss.input.port6.keyboard.f keyboard 0x0 9 + +ss.input.port6.keyboard.f1 keyboard 0x0 58 + +ss.input.port6.keyboard.f10 keyboard 0x0 67 + +ss.input.port6.keyboard.f11 keyboard 0x0 68 + +ss.input.port6.keyboard.f12 keyboard 0x0 69 + +ss.input.port6.keyboard.f2 keyboard 0x0 59 + +ss.input.port6.keyboard.f3 keyboard 0x0 60 + +ss.input.port6.keyboard.f4 keyboard 0x0 61 + +ss.input.port6.keyboard.f5 keyboard 0x0 62 + +ss.input.port6.keyboard.f6 keyboard 0x0 63 + +ss.input.port6.keyboard.f7 keyboard 0x0 64 + +ss.input.port6.keyboard.f8 keyboard 0x0 65 + +ss.input.port6.keyboard.f9 keyboard 0x0 66 + +ss.input.port6.keyboard.g keyboard 0x0 10 + +ss.input.port6.keyboard.grave keyboard 0x0 53 + +ss.input.port6.keyboard.h keyboard 0x0 11 + +ss.input.port6.keyboard.home keyboard 0x0 74 + +ss.input.port6.keyboard.i keyboard 0x0 12 + +ss.input.port6.keyboard.insert keyboard 0x0 73 + +ss.input.port6.keyboard.j keyboard 0x0 13 + +ss.input.port6.keyboard.k keyboard 0x0 14 + +ss.input.port6.keyboard.kp_asterisk keyboard 0x0 85 + +ss.input.port6.keyboard.kp_center keyboard 0x0 93 + +ss.input.port6.keyboard.kp_delete keyboard 0x0 99 + +ss.input.port6.keyboard.kp_down keyboard 0x0 90 + +ss.input.port6.keyboard.kp_end keyboard 0x0 89 + +ss.input.port6.keyboard.kp_enter keyboard 0x0 88 + +ss.input.port6.keyboard.kp_home keyboard 0x0 95 + +ss.input.port6.keyboard.kp_insert keyboard 0x0 98 + +ss.input.port6.keyboard.kp_left keyboard 0x0 92 + +ss.input.port6.keyboard.kp_minus keyboard 0x0 86 + +ss.input.port6.keyboard.kp_pagedown keyboard 0x0 91 + +ss.input.port6.keyboard.kp_pageup keyboard 0x0 97 + +ss.input.port6.keyboard.kp_plus keyboard 0x0 87 + +ss.input.port6.keyboard.kp_right keyboard 0x0 94 + +ss.input.port6.keyboard.kp_slash keyboard 0x0 84 + +ss.input.port6.keyboard.kp_up keyboard 0x0 96 + +ss.input.port6.keyboard.l keyboard 0x0 15 + +ss.input.port6.keyboard.lalt keyboard 0x0 226 + +ss.input.port6.keyboard.lctrl keyboard 0x0 224 + +ss.input.port6.keyboard.left keyboard 0x0 80 + +ss.input.port6.keyboard.leftbracket keyboard 0x0 47 + +ss.input.port6.keyboard.lshift keyboard 0x0 225 + +ss.input.port6.keyboard.m keyboard 0x0 16 + +ss.input.port6.keyboard.minus keyboard 0x0 45 + +ss.input.port6.keyboard.n keyboard 0x0 17 + +ss.input.port6.keyboard.numlock keyboard 0x0 83 + +ss.input.port6.keyboard.o keyboard 0x0 18 + +ss.input.port6.keyboard.p keyboard 0x0 19 + +ss.input.port6.keyboard.pagedown keyboard 0x0 78 + +ss.input.port6.keyboard.pageup keyboard 0x0 75 + +ss.input.port6.keyboard.pause keyboard 0x0 72 + +ss.input.port6.keyboard.period keyboard 0x0 55 + +ss.input.port6.keyboard.printscreen keyboard 0x0 70 + +ss.input.port6.keyboard.q keyboard 0x0 20 + +ss.input.port6.keyboard.quote keyboard 0x0 52 + +ss.input.port6.keyboard.r keyboard 0x0 21 + +ss.input.port6.keyboard.ralt keyboard 0x0 230 + +ss.input.port6.keyboard.rctrl keyboard 0x0 228 + +ss.input.port6.keyboard.right keyboard 0x0 79 + +ss.input.port6.keyboard.rightbracket keyboard 0x0 48 + +ss.input.port6.keyboard.rshift keyboard 0x0 229 + +ss.input.port6.keyboard.s keyboard 0x0 22 + +ss.input.port6.keyboard.scrolllock keyboard 0x0 71 + +ss.input.port6.keyboard.semicolon keyboard 0x0 51 + +ss.input.port6.keyboard.slash keyboard 0x0 56 + +ss.input.port6.keyboard.space keyboard 0x0 44 + +ss.input.port6.keyboard.t keyboard 0x0 23 + +ss.input.port6.keyboard.tab keyboard 0x0 43 + +ss.input.port6.keyboard.u keyboard 0x0 24 + +ss.input.port6.keyboard.up keyboard 0x0 82 + +ss.input.port6.keyboard.v keyboard 0x0 25 + +ss.input.port6.keyboard.w keyboard 0x0 26 + +ss.input.port6.keyboard.x keyboard 0x0 27 + +ss.input.port6.keyboard.y keyboard 0x0 28 + +ss.input.port6.keyboard.z keyboard 0x0 29 + +ss.input.port6.mission.a + +ss.input.port6.mission.afa + +ss.input.port6.mission.afa.defpos off + +ss.input.port6.mission.afb + +ss.input.port6.mission.afb.defpos off + +ss.input.port6.mission.afc + +ss.input.port6.mission.afc.defpos off + +ss.input.port6.mission.afl + +ss.input.port6.mission.afl.defpos off + +ss.input.port6.mission.afr + +ss.input.port6.mission.afr.defpos off + +ss.input.port6.mission.afspeed + +ss.input.port6.mission.afspeed.defpos 1 + +ss.input.port6.mission.afx + +ss.input.port6.mission.afx.defpos off + +ss.input.port6.mission.afy + +ss.input.port6.mission.afy.defpos off + +ss.input.port6.mission.afz + +ss.input.port6.mission.afz.defpos off + +ss.input.port6.mission.b + +ss.input.port6.mission.c + +ss.input.port6.mission.l + +ss.input.port6.mission.r + +ss.input.port6.mission.start + +ss.input.port6.mission.stick_back + +ss.input.port6.mission.stick_fore + +ss.input.port6.mission.stick_left + +ss.input.port6.mission.stick_right + +ss.input.port6.mission.throttle_down + +ss.input.port6.mission.throttle_up + +ss.input.port6.mission.x + +ss.input.port6.mission.y + +ss.input.port6.mission.z + +ss.input.port6.mouse.left mouse 0x0 button_left + +ss.input.port6.mouse.middle mouse 0x0 button_middle + +ss.input.port6.mouse.motion_down mouse 0x0 rel_y+ + +ss.input.port6.mouse.motion_left mouse 0x0 rel_x- + +ss.input.port6.mouse.motion_right mouse 0x0 rel_x+ + +ss.input.port6.mouse.motion_up mouse 0x0 rel_y- + +ss.input.port6.mouse.right mouse 0x0 button_right + +ss.input.port6.mouse.start keyboard 0x0 40 + +ss.input.port6.wheel.a + +ss.input.port6.wheel.analog_left + +ss.input.port6.wheel.analog_right + +ss.input.port6.wheel.b + +ss.input.port6.wheel.c + +ss.input.port6.wheel.down + +ss.input.port6.wheel.start + +ss.input.port6.wheel.up + +ss.input.port6.wheel.x + +ss.input.port6.wheel.y + +ss.input.port6.wheel.z + +ss.input.port7 gamepad + +ss.input.port7.3dpad.a + +ss.input.port7.3dpad.analog_down + +ss.input.port7.3dpad.analog_left + +ss.input.port7.3dpad.analog_right + +ss.input.port7.3dpad.analog_up + +ss.input.port7.3dpad.b + +ss.input.port7.3dpad.c + +ss.input.port7.3dpad.down + +ss.input.port7.3dpad.left + +ss.input.port7.3dpad.ls + +ss.input.port7.3dpad.mode + +ss.input.port7.3dpad.mode.defpos digital + +ss.input.port7.3dpad.right + +ss.input.port7.3dpad.rs + +ss.input.port7.3dpad.start + +ss.input.port7.3dpad.up + +ss.input.port7.3dpad.x + +ss.input.port7.3dpad.y + +ss.input.port7.3dpad.z + +ss.input.port7.dmission.a + +ss.input.port7.dmission.afa + +ss.input.port7.dmission.afa.defpos off + +ss.input.port7.dmission.afb + +ss.input.port7.dmission.afb.defpos off + +ss.input.port7.dmission.afc + +ss.input.port7.dmission.afc.defpos off + +ss.input.port7.dmission.afl + +ss.input.port7.dmission.afl.defpos off + +ss.input.port7.dmission.afr + +ss.input.port7.dmission.afr.defpos off + +ss.input.port7.dmission.afspeed + +ss.input.port7.dmission.afspeed.defpos 1 + +ss.input.port7.dmission.afx + +ss.input.port7.dmission.afx.defpos off + +ss.input.port7.dmission.afy + +ss.input.port7.dmission.afy.defpos off + +ss.input.port7.dmission.afz + +ss.input.port7.dmission.afz.defpos off + +ss.input.port7.dmission.b + +ss.input.port7.dmission.c + +ss.input.port7.dmission.l + +ss.input.port7.dmission.lstick_back + +ss.input.port7.dmission.lstick_fore + +ss.input.port7.dmission.lstick_left + +ss.input.port7.dmission.lstick_right + +ss.input.port7.dmission.lthrottle_down + +ss.input.port7.dmission.lthrottle_up + +ss.input.port7.dmission.r + +ss.input.port7.dmission.rstick_back + +ss.input.port7.dmission.rstick_fore + +ss.input.port7.dmission.rstick_left + +ss.input.port7.dmission.rstick_right + +ss.input.port7.dmission.rthrottle_down + +ss.input.port7.dmission.rthrottle_up + +ss.input.port7.dmission.start + +ss.input.port7.dmission.x + +ss.input.port7.dmission.y + +ss.input.port7.dmission.z + +ss.input.port7.gamepad.a + +ss.input.port7.gamepad.b + +ss.input.port7.gamepad.c + +ss.input.port7.gamepad.down + +ss.input.port7.gamepad.left + +ss.input.port7.gamepad.ls + +ss.input.port7.gamepad.right + +ss.input.port7.gamepad.rs + +ss.input.port7.gamepad.start + +ss.input.port7.gamepad.up + +ss.input.port7.gamepad.x + +ss.input.port7.gamepad.y + +ss.input.port7.gamepad.z + +ss.input.port7.gun.offscreen_shot mouse 0x0 button_right + +ss.input.port7.gun.start mouse 0x0 button_middle + +ss.input.port7.gun.trigger mouse 0x0 button_left + +ss.input.port7.gun.x_axis mouse 0x0 cursor_x-+ + +ss.input.port7.gun.y_axis mouse 0x0 cursor_y-+ + +ss.input.port7.gun_chairs 0x0080FF + +ss.input.port7.jpkeyboard.0 keyboard 0x0 39 + +ss.input.port7.jpkeyboard.1 keyboard 0x0 30 + +ss.input.port7.jpkeyboard.2 keyboard 0x0 31 + +ss.input.port7.jpkeyboard.3 keyboard 0x0 32 + +ss.input.port7.jpkeyboard.4 keyboard 0x0 33 + +ss.input.port7.jpkeyboard.5 keyboard 0x0 34 + +ss.input.port7.jpkeyboard.6 keyboard 0x0 35 + +ss.input.port7.jpkeyboard.7 keyboard 0x0 36 + +ss.input.port7.jpkeyboard.8 keyboard 0x0 37 + +ss.input.port7.jpkeyboard.9 keyboard 0x0 38 + +ss.input.port7.jpkeyboard.a keyboard 0x0 4 + +ss.input.port7.jpkeyboard.at keyboard 0x0 47 + +ss.input.port7.jpkeyboard.b keyboard 0x0 5 + +ss.input.port7.jpkeyboard.backslash keyboard 0x0 135 + +ss.input.port7.jpkeyboard.backspace keyboard 0x0 42 + +ss.input.port7.jpkeyboard.c keyboard 0x0 6 + +ss.input.port7.jpkeyboard.capslock keyboard 0x0 57 + +ss.input.port7.jpkeyboard.circumflex keyboard 0x0 46 + +ss.input.port7.jpkeyboard.colon keyboard 0x0 52 + +ss.input.port7.jpkeyboard.comma keyboard 0x0 54 + +ss.input.port7.jpkeyboard.conv keyboard 0x0 138 + +ss.input.port7.jpkeyboard.d keyboard 0x0 7 + +ss.input.port7.jpkeyboard.delete keyboard 0x0 76 + +ss.input.port7.jpkeyboard.down keyboard 0x0 81 + +ss.input.port7.jpkeyboard.e keyboard 0x0 8 + +ss.input.port7.jpkeyboard.end keyboard 0x0 77 + +ss.input.port7.jpkeyboard.enter keyboard 0x0 40 + +ss.input.port7.jpkeyboard.esc keyboard 0x0 41 + +ss.input.port7.jpkeyboard.f keyboard 0x0 9 + +ss.input.port7.jpkeyboard.f1 keyboard 0x0 58 + +ss.input.port7.jpkeyboard.f10 keyboard 0x0 67 + +ss.input.port7.jpkeyboard.f11 keyboard 0x0 68 + +ss.input.port7.jpkeyboard.f12 keyboard 0x0 69 + +ss.input.port7.jpkeyboard.f2 keyboard 0x0 59 + +ss.input.port7.jpkeyboard.f3 keyboard 0x0 60 + +ss.input.port7.jpkeyboard.f4 keyboard 0x0 61 + +ss.input.port7.jpkeyboard.f5 keyboard 0x0 62 + +ss.input.port7.jpkeyboard.f6 keyboard 0x0 63 + +ss.input.port7.jpkeyboard.f7 keyboard 0x0 64 + +ss.input.port7.jpkeyboard.f8 keyboard 0x0 65 + +ss.input.port7.jpkeyboard.f9 keyboard 0x0 66 + +ss.input.port7.jpkeyboard.g keyboard 0x0 10 + +ss.input.port7.jpkeyboard.h keyboard 0x0 11 + +ss.input.port7.jpkeyboard.hkr keyboard 0x0 136 + +ss.input.port7.jpkeyboard.home keyboard 0x0 74 + +ss.input.port7.jpkeyboard.hwfw keyboard 0x0 53 + +ss.input.port7.jpkeyboard.i keyboard 0x0 12 + +ss.input.port7.jpkeyboard.insert keyboard 0x0 73 + +ss.input.port7.jpkeyboard.j keyboard 0x0 13 + +ss.input.port7.jpkeyboard.k keyboard 0x0 14 + +ss.input.port7.jpkeyboard.l keyboard 0x0 15 + +ss.input.port7.jpkeyboard.lalt keyboard 0x0 226 + +ss.input.port7.jpkeyboard.lctrl keyboard 0x0 224 + +ss.input.port7.jpkeyboard.left keyboard 0x0 80 + +ss.input.port7.jpkeyboard.leftbracket keyboard 0x0 48 + +ss.input.port7.jpkeyboard.lshift keyboard 0x0 225 + +ss.input.port7.jpkeyboard.m keyboard 0x0 16 + +ss.input.port7.jpkeyboard.minus keyboard 0x0 45 + +ss.input.port7.jpkeyboard.n keyboard 0x0 17 + +ss.input.port7.jpkeyboard.nonconv keyboard 0x0 139 + +ss.input.port7.jpkeyboard.o keyboard 0x0 18 + +ss.input.port7.jpkeyboard.p keyboard 0x0 19 + +ss.input.port7.jpkeyboard.pagedown keyboard 0x0 78 + +ss.input.port7.jpkeyboard.pageup keyboard 0x0 75 + +ss.input.port7.jpkeyboard.pause keyboard 0x0 72 || keyboard 0x0 83 + +ss.input.port7.jpkeyboard.period keyboard 0x0 55 + +ss.input.port7.jpkeyboard.printscreen keyboard 0x0 70 + +ss.input.port7.jpkeyboard.q keyboard 0x0 20 + +ss.input.port7.jpkeyboard.r keyboard 0x0 21 + +ss.input.port7.jpkeyboard.ralt keyboard 0x0 230 + +ss.input.port7.jpkeyboard.rctrl keyboard 0x0 228 + +ss.input.port7.jpkeyboard.right keyboard 0x0 79 + +ss.input.port7.jpkeyboard.rightbracket keyboard 0x0 49 + +ss.input.port7.jpkeyboard.rshift keyboard 0x0 229 + +ss.input.port7.jpkeyboard.s keyboard 0x0 22 + +ss.input.port7.jpkeyboard.scrolllock keyboard 0x0 71 + +ss.input.port7.jpkeyboard.semicolon keyboard 0x0 51 + +ss.input.port7.jpkeyboard.slash keyboard 0x0 56 + +ss.input.port7.jpkeyboard.space keyboard 0x0 44 + +ss.input.port7.jpkeyboard.t keyboard 0x0 23 + +ss.input.port7.jpkeyboard.tab keyboard 0x0 43 + +ss.input.port7.jpkeyboard.u keyboard 0x0 24 + +ss.input.port7.jpkeyboard.up keyboard 0x0 82 + +ss.input.port7.jpkeyboard.v keyboard 0x0 25 + +ss.input.port7.jpkeyboard.w keyboard 0x0 26 + +ss.input.port7.jpkeyboard.x keyboard 0x0 27 + +ss.input.port7.jpkeyboard.y keyboard 0x0 28 + +ss.input.port7.jpkeyboard.yen keyboard 0x0 137 + +ss.input.port7.jpkeyboard.z keyboard 0x0 29 + +ss.input.port7.keyboard.0 keyboard 0x0 39 + +ss.input.port7.keyboard.1 keyboard 0x0 30 + +ss.input.port7.keyboard.2 keyboard 0x0 31 + +ss.input.port7.keyboard.3 keyboard 0x0 32 + +ss.input.port7.keyboard.4 keyboard 0x0 33 + +ss.input.port7.keyboard.5 keyboard 0x0 34 + +ss.input.port7.keyboard.6 keyboard 0x0 35 + +ss.input.port7.keyboard.7 keyboard 0x0 36 + +ss.input.port7.keyboard.8 keyboard 0x0 37 + +ss.input.port7.keyboard.9 keyboard 0x0 38 + +ss.input.port7.keyboard.a keyboard 0x0 4 + +ss.input.port7.keyboard.b keyboard 0x0 5 + +ss.input.port7.keyboard.backslash keyboard 0x0 49 || keyboard 0x0 135 + +ss.input.port7.keyboard.backspace keyboard 0x0 42 + +ss.input.port7.keyboard.c keyboard 0x0 6 + +ss.input.port7.keyboard.capslock keyboard 0x0 57 + +ss.input.port7.keyboard.comma keyboard 0x0 54 + +ss.input.port7.keyboard.d keyboard 0x0 7 + +ss.input.port7.keyboard.delete keyboard 0x0 76 + +ss.input.port7.keyboard.down keyboard 0x0 81 + +ss.input.port7.keyboard.e keyboard 0x0 8 + +ss.input.port7.keyboard.end keyboard 0x0 77 + +ss.input.port7.keyboard.enter keyboard 0x0 40 + +ss.input.port7.keyboard.equals keyboard 0x0 46 + +ss.input.port7.keyboard.esc keyboard 0x0 41 + +ss.input.port7.keyboard.f keyboard 0x0 9 + +ss.input.port7.keyboard.f1 keyboard 0x0 58 + +ss.input.port7.keyboard.f10 keyboard 0x0 67 + +ss.input.port7.keyboard.f11 keyboard 0x0 68 + +ss.input.port7.keyboard.f12 keyboard 0x0 69 + +ss.input.port7.keyboard.f2 keyboard 0x0 59 + +ss.input.port7.keyboard.f3 keyboard 0x0 60 + +ss.input.port7.keyboard.f4 keyboard 0x0 61 + +ss.input.port7.keyboard.f5 keyboard 0x0 62 + +ss.input.port7.keyboard.f6 keyboard 0x0 63 + +ss.input.port7.keyboard.f7 keyboard 0x0 64 + +ss.input.port7.keyboard.f8 keyboard 0x0 65 + +ss.input.port7.keyboard.f9 keyboard 0x0 66 + +ss.input.port7.keyboard.g keyboard 0x0 10 + +ss.input.port7.keyboard.grave keyboard 0x0 53 + +ss.input.port7.keyboard.h keyboard 0x0 11 + +ss.input.port7.keyboard.home keyboard 0x0 74 + +ss.input.port7.keyboard.i keyboard 0x0 12 + +ss.input.port7.keyboard.insert keyboard 0x0 73 + +ss.input.port7.keyboard.j keyboard 0x0 13 + +ss.input.port7.keyboard.k keyboard 0x0 14 + +ss.input.port7.keyboard.kp_asterisk keyboard 0x0 85 + +ss.input.port7.keyboard.kp_center keyboard 0x0 93 + +ss.input.port7.keyboard.kp_delete keyboard 0x0 99 + +ss.input.port7.keyboard.kp_down keyboard 0x0 90 + +ss.input.port7.keyboard.kp_end keyboard 0x0 89 + +ss.input.port7.keyboard.kp_enter keyboard 0x0 88 + +ss.input.port7.keyboard.kp_home keyboard 0x0 95 + +ss.input.port7.keyboard.kp_insert keyboard 0x0 98 + +ss.input.port7.keyboard.kp_left keyboard 0x0 92 + +ss.input.port7.keyboard.kp_minus keyboard 0x0 86 + +ss.input.port7.keyboard.kp_pagedown keyboard 0x0 91 + +ss.input.port7.keyboard.kp_pageup keyboard 0x0 97 + +ss.input.port7.keyboard.kp_plus keyboard 0x0 87 + +ss.input.port7.keyboard.kp_right keyboard 0x0 94 + +ss.input.port7.keyboard.kp_slash keyboard 0x0 84 + +ss.input.port7.keyboard.kp_up keyboard 0x0 96 + +ss.input.port7.keyboard.l keyboard 0x0 15 + +ss.input.port7.keyboard.lalt keyboard 0x0 226 + +ss.input.port7.keyboard.lctrl keyboard 0x0 224 + +ss.input.port7.keyboard.left keyboard 0x0 80 + +ss.input.port7.keyboard.leftbracket keyboard 0x0 47 + +ss.input.port7.keyboard.lshift keyboard 0x0 225 + +ss.input.port7.keyboard.m keyboard 0x0 16 + +ss.input.port7.keyboard.minus keyboard 0x0 45 + +ss.input.port7.keyboard.n keyboard 0x0 17 + +ss.input.port7.keyboard.numlock keyboard 0x0 83 + +ss.input.port7.keyboard.o keyboard 0x0 18 + +ss.input.port7.keyboard.p keyboard 0x0 19 + +ss.input.port7.keyboard.pagedown keyboard 0x0 78 + +ss.input.port7.keyboard.pageup keyboard 0x0 75 + +ss.input.port7.keyboard.pause keyboard 0x0 72 + +ss.input.port7.keyboard.period keyboard 0x0 55 + +ss.input.port7.keyboard.printscreen keyboard 0x0 70 + +ss.input.port7.keyboard.q keyboard 0x0 20 + +ss.input.port7.keyboard.quote keyboard 0x0 52 + +ss.input.port7.keyboard.r keyboard 0x0 21 + +ss.input.port7.keyboard.ralt keyboard 0x0 230 + +ss.input.port7.keyboard.rctrl keyboard 0x0 228 + +ss.input.port7.keyboard.right keyboard 0x0 79 + +ss.input.port7.keyboard.rightbracket keyboard 0x0 48 + +ss.input.port7.keyboard.rshift keyboard 0x0 229 + +ss.input.port7.keyboard.s keyboard 0x0 22 + +ss.input.port7.keyboard.scrolllock keyboard 0x0 71 + +ss.input.port7.keyboard.semicolon keyboard 0x0 51 + +ss.input.port7.keyboard.slash keyboard 0x0 56 + +ss.input.port7.keyboard.space keyboard 0x0 44 + +ss.input.port7.keyboard.t keyboard 0x0 23 + +ss.input.port7.keyboard.tab keyboard 0x0 43 + +ss.input.port7.keyboard.u keyboard 0x0 24 + +ss.input.port7.keyboard.up keyboard 0x0 82 + +ss.input.port7.keyboard.v keyboard 0x0 25 + +ss.input.port7.keyboard.w keyboard 0x0 26 + +ss.input.port7.keyboard.x keyboard 0x0 27 + +ss.input.port7.keyboard.y keyboard 0x0 28 + +ss.input.port7.keyboard.z keyboard 0x0 29 + +ss.input.port7.mission.a + +ss.input.port7.mission.afa + +ss.input.port7.mission.afa.defpos off + +ss.input.port7.mission.afb + +ss.input.port7.mission.afb.defpos off + +ss.input.port7.mission.afc + +ss.input.port7.mission.afc.defpos off + +ss.input.port7.mission.afl + +ss.input.port7.mission.afl.defpos off + +ss.input.port7.mission.afr + +ss.input.port7.mission.afr.defpos off + +ss.input.port7.mission.afspeed + +ss.input.port7.mission.afspeed.defpos 1 + +ss.input.port7.mission.afx + +ss.input.port7.mission.afx.defpos off + +ss.input.port7.mission.afy + +ss.input.port7.mission.afy.defpos off + +ss.input.port7.mission.afz + +ss.input.port7.mission.afz.defpos off + +ss.input.port7.mission.b + +ss.input.port7.mission.c + +ss.input.port7.mission.l + +ss.input.port7.mission.r + +ss.input.port7.mission.start + +ss.input.port7.mission.stick_back + +ss.input.port7.mission.stick_fore + +ss.input.port7.mission.stick_left + +ss.input.port7.mission.stick_right + +ss.input.port7.mission.throttle_down + +ss.input.port7.mission.throttle_up + +ss.input.port7.mission.x + +ss.input.port7.mission.y + +ss.input.port7.mission.z + +ss.input.port7.mouse.left mouse 0x0 button_left + +ss.input.port7.mouse.middle mouse 0x0 button_middle + +ss.input.port7.mouse.motion_down mouse 0x0 rel_y+ + +ss.input.port7.mouse.motion_left mouse 0x0 rel_x- + +ss.input.port7.mouse.motion_right mouse 0x0 rel_x+ + +ss.input.port7.mouse.motion_up mouse 0x0 rel_y- + +ss.input.port7.mouse.right mouse 0x0 button_right + +ss.input.port7.mouse.start keyboard 0x0 40 + +ss.input.port7.wheel.a + +ss.input.port7.wheel.analog_left + +ss.input.port7.wheel.analog_right + +ss.input.port7.wheel.b + +ss.input.port7.wheel.c + +ss.input.port7.wheel.down + +ss.input.port7.wheel.start + +ss.input.port7.wheel.up + +ss.input.port7.wheel.x + +ss.input.port7.wheel.y + +ss.input.port7.wheel.z + +ss.input.port8 gamepad + +ss.input.port8.3dpad.a + +ss.input.port8.3dpad.analog_down + +ss.input.port8.3dpad.analog_left + +ss.input.port8.3dpad.analog_right + +ss.input.port8.3dpad.analog_up + +ss.input.port8.3dpad.b + +ss.input.port8.3dpad.c + +ss.input.port8.3dpad.down + +ss.input.port8.3dpad.left + +ss.input.port8.3dpad.ls + +ss.input.port8.3dpad.mode + +ss.input.port8.3dpad.mode.defpos digital + +ss.input.port8.3dpad.right + +ss.input.port8.3dpad.rs + +ss.input.port8.3dpad.start + +ss.input.port8.3dpad.up + +ss.input.port8.3dpad.x + +ss.input.port8.3dpad.y + +ss.input.port8.3dpad.z + +ss.input.port8.dmission.a + +ss.input.port8.dmission.afa + +ss.input.port8.dmission.afa.defpos off + +ss.input.port8.dmission.afb + +ss.input.port8.dmission.afb.defpos off + +ss.input.port8.dmission.afc + +ss.input.port8.dmission.afc.defpos off + +ss.input.port8.dmission.afl + +ss.input.port8.dmission.afl.defpos off + +ss.input.port8.dmission.afr + +ss.input.port8.dmission.afr.defpos off + +ss.input.port8.dmission.afspeed + +ss.input.port8.dmission.afspeed.defpos 1 + +ss.input.port8.dmission.afx + +ss.input.port8.dmission.afx.defpos off + +ss.input.port8.dmission.afy + +ss.input.port8.dmission.afy.defpos off + +ss.input.port8.dmission.afz + +ss.input.port8.dmission.afz.defpos off + +ss.input.port8.dmission.b + +ss.input.port8.dmission.c + +ss.input.port8.dmission.l + +ss.input.port8.dmission.lstick_back + +ss.input.port8.dmission.lstick_fore + +ss.input.port8.dmission.lstick_left + +ss.input.port8.dmission.lstick_right + +ss.input.port8.dmission.lthrottle_down + +ss.input.port8.dmission.lthrottle_up + +ss.input.port8.dmission.r + +ss.input.port8.dmission.rstick_back + +ss.input.port8.dmission.rstick_fore + +ss.input.port8.dmission.rstick_left + +ss.input.port8.dmission.rstick_right + +ss.input.port8.dmission.rthrottle_down + +ss.input.port8.dmission.rthrottle_up + +ss.input.port8.dmission.start + +ss.input.port8.dmission.x + +ss.input.port8.dmission.y + +ss.input.port8.dmission.z + +ss.input.port8.gamepad.a + +ss.input.port8.gamepad.b + +ss.input.port8.gamepad.c + +ss.input.port8.gamepad.down + +ss.input.port8.gamepad.left + +ss.input.port8.gamepad.ls + +ss.input.port8.gamepad.right + +ss.input.port8.gamepad.rs + +ss.input.port8.gamepad.start + +ss.input.port8.gamepad.up + +ss.input.port8.gamepad.x + +ss.input.port8.gamepad.y + +ss.input.port8.gamepad.z + +ss.input.port8.gun.offscreen_shot mouse 0x0 button_right + +ss.input.port8.gun.start mouse 0x0 button_middle + +ss.input.port8.gun.trigger mouse 0x0 button_left + +ss.input.port8.gun.x_axis mouse 0x0 cursor_x-+ + +ss.input.port8.gun.y_axis mouse 0x0 cursor_y-+ + +ss.input.port8.gun_chairs 0x8000FF + +ss.input.port8.jpkeyboard.0 keyboard 0x0 39 + +ss.input.port8.jpkeyboard.1 keyboard 0x0 30 + +ss.input.port8.jpkeyboard.2 keyboard 0x0 31 + +ss.input.port8.jpkeyboard.3 keyboard 0x0 32 + +ss.input.port8.jpkeyboard.4 keyboard 0x0 33 + +ss.input.port8.jpkeyboard.5 keyboard 0x0 34 + +ss.input.port8.jpkeyboard.6 keyboard 0x0 35 + +ss.input.port8.jpkeyboard.7 keyboard 0x0 36 + +ss.input.port8.jpkeyboard.8 keyboard 0x0 37 + +ss.input.port8.jpkeyboard.9 keyboard 0x0 38 + +ss.input.port8.jpkeyboard.a keyboard 0x0 4 + +ss.input.port8.jpkeyboard.at keyboard 0x0 47 + +ss.input.port8.jpkeyboard.b keyboard 0x0 5 + +ss.input.port8.jpkeyboard.backslash keyboard 0x0 135 + +ss.input.port8.jpkeyboard.backspace keyboard 0x0 42 + +ss.input.port8.jpkeyboard.c keyboard 0x0 6 + +ss.input.port8.jpkeyboard.capslock keyboard 0x0 57 + +ss.input.port8.jpkeyboard.circumflex keyboard 0x0 46 + +ss.input.port8.jpkeyboard.colon keyboard 0x0 52 + +ss.input.port8.jpkeyboard.comma keyboard 0x0 54 + +ss.input.port8.jpkeyboard.conv keyboard 0x0 138 + +ss.input.port8.jpkeyboard.d keyboard 0x0 7 + +ss.input.port8.jpkeyboard.delete keyboard 0x0 76 + +ss.input.port8.jpkeyboard.down keyboard 0x0 81 + +ss.input.port8.jpkeyboard.e keyboard 0x0 8 + +ss.input.port8.jpkeyboard.end keyboard 0x0 77 + +ss.input.port8.jpkeyboard.enter keyboard 0x0 40 + +ss.input.port8.jpkeyboard.esc keyboard 0x0 41 + +ss.input.port8.jpkeyboard.f keyboard 0x0 9 + +ss.input.port8.jpkeyboard.f1 keyboard 0x0 58 + +ss.input.port8.jpkeyboard.f10 keyboard 0x0 67 + +ss.input.port8.jpkeyboard.f11 keyboard 0x0 68 + +ss.input.port8.jpkeyboard.f12 keyboard 0x0 69 + +ss.input.port8.jpkeyboard.f2 keyboard 0x0 59 + +ss.input.port8.jpkeyboard.f3 keyboard 0x0 60 + +ss.input.port8.jpkeyboard.f4 keyboard 0x0 61 + +ss.input.port8.jpkeyboard.f5 keyboard 0x0 62 + +ss.input.port8.jpkeyboard.f6 keyboard 0x0 63 + +ss.input.port8.jpkeyboard.f7 keyboard 0x0 64 + +ss.input.port8.jpkeyboard.f8 keyboard 0x0 65 + +ss.input.port8.jpkeyboard.f9 keyboard 0x0 66 + +ss.input.port8.jpkeyboard.g keyboard 0x0 10 + +ss.input.port8.jpkeyboard.h keyboard 0x0 11 + +ss.input.port8.jpkeyboard.hkr keyboard 0x0 136 + +ss.input.port8.jpkeyboard.home keyboard 0x0 74 + +ss.input.port8.jpkeyboard.hwfw keyboard 0x0 53 + +ss.input.port8.jpkeyboard.i keyboard 0x0 12 + +ss.input.port8.jpkeyboard.insert keyboard 0x0 73 + +ss.input.port8.jpkeyboard.j keyboard 0x0 13 + +ss.input.port8.jpkeyboard.k keyboard 0x0 14 + +ss.input.port8.jpkeyboard.l keyboard 0x0 15 + +ss.input.port8.jpkeyboard.lalt keyboard 0x0 226 + +ss.input.port8.jpkeyboard.lctrl keyboard 0x0 224 + +ss.input.port8.jpkeyboard.left keyboard 0x0 80 + +ss.input.port8.jpkeyboard.leftbracket keyboard 0x0 48 + +ss.input.port8.jpkeyboard.lshift keyboard 0x0 225 + +ss.input.port8.jpkeyboard.m keyboard 0x0 16 + +ss.input.port8.jpkeyboard.minus keyboard 0x0 45 + +ss.input.port8.jpkeyboard.n keyboard 0x0 17 + +ss.input.port8.jpkeyboard.nonconv keyboard 0x0 139 + +ss.input.port8.jpkeyboard.o keyboard 0x0 18 + +ss.input.port8.jpkeyboard.p keyboard 0x0 19 + +ss.input.port8.jpkeyboard.pagedown keyboard 0x0 78 + +ss.input.port8.jpkeyboard.pageup keyboard 0x0 75 + +ss.input.port8.jpkeyboard.pause keyboard 0x0 72 || keyboard 0x0 83 + +ss.input.port8.jpkeyboard.period keyboard 0x0 55 + +ss.input.port8.jpkeyboard.printscreen keyboard 0x0 70 + +ss.input.port8.jpkeyboard.q keyboard 0x0 20 + +ss.input.port8.jpkeyboard.r keyboard 0x0 21 + +ss.input.port8.jpkeyboard.ralt keyboard 0x0 230 + +ss.input.port8.jpkeyboard.rctrl keyboard 0x0 228 + +ss.input.port8.jpkeyboard.right keyboard 0x0 79 + +ss.input.port8.jpkeyboard.rightbracket keyboard 0x0 49 + +ss.input.port8.jpkeyboard.rshift keyboard 0x0 229 + +ss.input.port8.jpkeyboard.s keyboard 0x0 22 + +ss.input.port8.jpkeyboard.scrolllock keyboard 0x0 71 + +ss.input.port8.jpkeyboard.semicolon keyboard 0x0 51 + +ss.input.port8.jpkeyboard.slash keyboard 0x0 56 + +ss.input.port8.jpkeyboard.space keyboard 0x0 44 + +ss.input.port8.jpkeyboard.t keyboard 0x0 23 + +ss.input.port8.jpkeyboard.tab keyboard 0x0 43 + +ss.input.port8.jpkeyboard.u keyboard 0x0 24 + +ss.input.port8.jpkeyboard.up keyboard 0x0 82 + +ss.input.port8.jpkeyboard.v keyboard 0x0 25 + +ss.input.port8.jpkeyboard.w keyboard 0x0 26 + +ss.input.port8.jpkeyboard.x keyboard 0x0 27 + +ss.input.port8.jpkeyboard.y keyboard 0x0 28 + +ss.input.port8.jpkeyboard.yen keyboard 0x0 137 + +ss.input.port8.jpkeyboard.z keyboard 0x0 29 + +ss.input.port8.keyboard.0 keyboard 0x0 39 + +ss.input.port8.keyboard.1 keyboard 0x0 30 + +ss.input.port8.keyboard.2 keyboard 0x0 31 + +ss.input.port8.keyboard.3 keyboard 0x0 32 + +ss.input.port8.keyboard.4 keyboard 0x0 33 + +ss.input.port8.keyboard.5 keyboard 0x0 34 + +ss.input.port8.keyboard.6 keyboard 0x0 35 + +ss.input.port8.keyboard.7 keyboard 0x0 36 + +ss.input.port8.keyboard.8 keyboard 0x0 37 + +ss.input.port8.keyboard.9 keyboard 0x0 38 + +ss.input.port8.keyboard.a keyboard 0x0 4 + +ss.input.port8.keyboard.b keyboard 0x0 5 + +ss.input.port8.keyboard.backslash keyboard 0x0 49 || keyboard 0x0 135 + +ss.input.port8.keyboard.backspace keyboard 0x0 42 + +ss.input.port8.keyboard.c keyboard 0x0 6 + +ss.input.port8.keyboard.capslock keyboard 0x0 57 + +ss.input.port8.keyboard.comma keyboard 0x0 54 + +ss.input.port8.keyboard.d keyboard 0x0 7 + +ss.input.port8.keyboard.delete keyboard 0x0 76 + +ss.input.port8.keyboard.down keyboard 0x0 81 + +ss.input.port8.keyboard.e keyboard 0x0 8 + +ss.input.port8.keyboard.end keyboard 0x0 77 + +ss.input.port8.keyboard.enter keyboard 0x0 40 + +ss.input.port8.keyboard.equals keyboard 0x0 46 + +ss.input.port8.keyboard.esc keyboard 0x0 41 + +ss.input.port8.keyboard.f keyboard 0x0 9 + +ss.input.port8.keyboard.f1 keyboard 0x0 58 + +ss.input.port8.keyboard.f10 keyboard 0x0 67 + +ss.input.port8.keyboard.f11 keyboard 0x0 68 + +ss.input.port8.keyboard.f12 keyboard 0x0 69 + +ss.input.port8.keyboard.f2 keyboard 0x0 59 + +ss.input.port8.keyboard.f3 keyboard 0x0 60 + +ss.input.port8.keyboard.f4 keyboard 0x0 61 + +ss.input.port8.keyboard.f5 keyboard 0x0 62 + +ss.input.port8.keyboard.f6 keyboard 0x0 63 + +ss.input.port8.keyboard.f7 keyboard 0x0 64 + +ss.input.port8.keyboard.f8 keyboard 0x0 65 + +ss.input.port8.keyboard.f9 keyboard 0x0 66 + +ss.input.port8.keyboard.g keyboard 0x0 10 + +ss.input.port8.keyboard.grave keyboard 0x0 53 + +ss.input.port8.keyboard.h keyboard 0x0 11 + +ss.input.port8.keyboard.home keyboard 0x0 74 + +ss.input.port8.keyboard.i keyboard 0x0 12 + +ss.input.port8.keyboard.insert keyboard 0x0 73 + +ss.input.port8.keyboard.j keyboard 0x0 13 + +ss.input.port8.keyboard.k keyboard 0x0 14 + +ss.input.port8.keyboard.kp_asterisk keyboard 0x0 85 + +ss.input.port8.keyboard.kp_center keyboard 0x0 93 + +ss.input.port8.keyboard.kp_delete keyboard 0x0 99 + +ss.input.port8.keyboard.kp_down keyboard 0x0 90 + +ss.input.port8.keyboard.kp_end keyboard 0x0 89 + +ss.input.port8.keyboard.kp_enter keyboard 0x0 88 + +ss.input.port8.keyboard.kp_home keyboard 0x0 95 + +ss.input.port8.keyboard.kp_insert keyboard 0x0 98 + +ss.input.port8.keyboard.kp_left keyboard 0x0 92 + +ss.input.port8.keyboard.kp_minus keyboard 0x0 86 + +ss.input.port8.keyboard.kp_pagedown keyboard 0x0 91 + +ss.input.port8.keyboard.kp_pageup keyboard 0x0 97 + +ss.input.port8.keyboard.kp_plus keyboard 0x0 87 + +ss.input.port8.keyboard.kp_right keyboard 0x0 94 + +ss.input.port8.keyboard.kp_slash keyboard 0x0 84 + +ss.input.port8.keyboard.kp_up keyboard 0x0 96 + +ss.input.port8.keyboard.l keyboard 0x0 15 + +ss.input.port8.keyboard.lalt keyboard 0x0 226 + +ss.input.port8.keyboard.lctrl keyboard 0x0 224 + +ss.input.port8.keyboard.left keyboard 0x0 80 + +ss.input.port8.keyboard.leftbracket keyboard 0x0 47 + +ss.input.port8.keyboard.lshift keyboard 0x0 225 + +ss.input.port8.keyboard.m keyboard 0x0 16 + +ss.input.port8.keyboard.minus keyboard 0x0 45 + +ss.input.port8.keyboard.n keyboard 0x0 17 + +ss.input.port8.keyboard.numlock keyboard 0x0 83 + +ss.input.port8.keyboard.o keyboard 0x0 18 + +ss.input.port8.keyboard.p keyboard 0x0 19 + +ss.input.port8.keyboard.pagedown keyboard 0x0 78 + +ss.input.port8.keyboard.pageup keyboard 0x0 75 + +ss.input.port8.keyboard.pause keyboard 0x0 72 + +ss.input.port8.keyboard.period keyboard 0x0 55 + +ss.input.port8.keyboard.printscreen keyboard 0x0 70 + +ss.input.port8.keyboard.q keyboard 0x0 20 + +ss.input.port8.keyboard.quote keyboard 0x0 52 + +ss.input.port8.keyboard.r keyboard 0x0 21 + +ss.input.port8.keyboard.ralt keyboard 0x0 230 + +ss.input.port8.keyboard.rctrl keyboard 0x0 228 + +ss.input.port8.keyboard.right keyboard 0x0 79 + +ss.input.port8.keyboard.rightbracket keyboard 0x0 48 + +ss.input.port8.keyboard.rshift keyboard 0x0 229 + +ss.input.port8.keyboard.s keyboard 0x0 22 + +ss.input.port8.keyboard.scrolllock keyboard 0x0 71 + +ss.input.port8.keyboard.semicolon keyboard 0x0 51 + +ss.input.port8.keyboard.slash keyboard 0x0 56 + +ss.input.port8.keyboard.space keyboard 0x0 44 + +ss.input.port8.keyboard.t keyboard 0x0 23 + +ss.input.port8.keyboard.tab keyboard 0x0 43 + +ss.input.port8.keyboard.u keyboard 0x0 24 + +ss.input.port8.keyboard.up keyboard 0x0 82 + +ss.input.port8.keyboard.v keyboard 0x0 25 + +ss.input.port8.keyboard.w keyboard 0x0 26 + +ss.input.port8.keyboard.x keyboard 0x0 27 + +ss.input.port8.keyboard.y keyboard 0x0 28 + +ss.input.port8.keyboard.z keyboard 0x0 29 + +ss.input.port8.mission.a + +ss.input.port8.mission.afa + +ss.input.port8.mission.afa.defpos off + +ss.input.port8.mission.afb + +ss.input.port8.mission.afb.defpos off + +ss.input.port8.mission.afc + +ss.input.port8.mission.afc.defpos off + +ss.input.port8.mission.afl + +ss.input.port8.mission.afl.defpos off + +ss.input.port8.mission.afr + +ss.input.port8.mission.afr.defpos off + +ss.input.port8.mission.afspeed + +ss.input.port8.mission.afspeed.defpos 1 + +ss.input.port8.mission.afx + +ss.input.port8.mission.afx.defpos off + +ss.input.port8.mission.afy + +ss.input.port8.mission.afy.defpos off + +ss.input.port8.mission.afz + +ss.input.port8.mission.afz.defpos off + +ss.input.port8.mission.b + +ss.input.port8.mission.c + +ss.input.port8.mission.l + +ss.input.port8.mission.r + +ss.input.port8.mission.start + +ss.input.port8.mission.stick_back + +ss.input.port8.mission.stick_fore + +ss.input.port8.mission.stick_left + +ss.input.port8.mission.stick_right + +ss.input.port8.mission.throttle_down + +ss.input.port8.mission.throttle_up + +ss.input.port8.mission.x + +ss.input.port8.mission.y + +ss.input.port8.mission.z + +ss.input.port8.mouse.left mouse 0x0 button_left + +ss.input.port8.mouse.middle mouse 0x0 button_middle + +ss.input.port8.mouse.motion_down mouse 0x0 rel_y+ + +ss.input.port8.mouse.motion_left mouse 0x0 rel_x- + +ss.input.port8.mouse.motion_right mouse 0x0 rel_x+ + +ss.input.port8.mouse.motion_up mouse 0x0 rel_y- + +ss.input.port8.mouse.right mouse 0x0 button_right + +ss.input.port8.mouse.start keyboard 0x0 40 + +ss.input.port8.wheel.a + +ss.input.port8.wheel.analog_left + +ss.input.port8.wheel.analog_right + +ss.input.port8.wheel.b + +ss.input.port8.wheel.c + +ss.input.port8.wheel.down + +ss.input.port8.wheel.start + +ss.input.port8.wheel.up + +ss.input.port8.wheel.x + +ss.input.port8.wheel.y + +ss.input.port8.wheel.z + +ss.input.port9 gamepad + +ss.input.port9.3dpad.a + +ss.input.port9.3dpad.analog_down + +ss.input.port9.3dpad.analog_left + +ss.input.port9.3dpad.analog_right + +ss.input.port9.3dpad.analog_up + +ss.input.port9.3dpad.b + +ss.input.port9.3dpad.c + +ss.input.port9.3dpad.down + +ss.input.port9.3dpad.left + +ss.input.port9.3dpad.ls + +ss.input.port9.3dpad.mode + +ss.input.port9.3dpad.mode.defpos digital + +ss.input.port9.3dpad.right + +ss.input.port9.3dpad.rs + +ss.input.port9.3dpad.start + +ss.input.port9.3dpad.up + +ss.input.port9.3dpad.x + +ss.input.port9.3dpad.y + +ss.input.port9.3dpad.z + +ss.input.port9.dmission.a + +ss.input.port9.dmission.afa + +ss.input.port9.dmission.afa.defpos off + +ss.input.port9.dmission.afb + +ss.input.port9.dmission.afb.defpos off + +ss.input.port9.dmission.afc + +ss.input.port9.dmission.afc.defpos off + +ss.input.port9.dmission.afl + +ss.input.port9.dmission.afl.defpos off + +ss.input.port9.dmission.afr + +ss.input.port9.dmission.afr.defpos off + +ss.input.port9.dmission.afspeed + +ss.input.port9.dmission.afspeed.defpos 1 + +ss.input.port9.dmission.afx + +ss.input.port9.dmission.afx.defpos off + +ss.input.port9.dmission.afy + +ss.input.port9.dmission.afy.defpos off + +ss.input.port9.dmission.afz + +ss.input.port9.dmission.afz.defpos off + +ss.input.port9.dmission.b + +ss.input.port9.dmission.c + +ss.input.port9.dmission.l + +ss.input.port9.dmission.lstick_back + +ss.input.port9.dmission.lstick_fore + +ss.input.port9.dmission.lstick_left + +ss.input.port9.dmission.lstick_right + +ss.input.port9.dmission.lthrottle_down + +ss.input.port9.dmission.lthrottle_up + +ss.input.port9.dmission.r + +ss.input.port9.dmission.rstick_back + +ss.input.port9.dmission.rstick_fore + +ss.input.port9.dmission.rstick_left + +ss.input.port9.dmission.rstick_right + +ss.input.port9.dmission.rthrottle_down + +ss.input.port9.dmission.rthrottle_up + +ss.input.port9.dmission.start + +ss.input.port9.dmission.x + +ss.input.port9.dmission.y + +ss.input.port9.dmission.z + +ss.input.port9.gamepad.a + +ss.input.port9.gamepad.b + +ss.input.port9.gamepad.c + +ss.input.port9.gamepad.down + +ss.input.port9.gamepad.left + +ss.input.port9.gamepad.ls + +ss.input.port9.gamepad.right + +ss.input.port9.gamepad.rs + +ss.input.port9.gamepad.start + +ss.input.port9.gamepad.up + +ss.input.port9.gamepad.x + +ss.input.port9.gamepad.y + +ss.input.port9.gamepad.z + +ss.input.port9.gun.offscreen_shot mouse 0x0 button_right + +ss.input.port9.gun.start mouse 0x0 button_middle + +ss.input.port9.gun.trigger mouse 0x0 button_left + +ss.input.port9.gun.x_axis mouse 0x0 cursor_x-+ + +ss.input.port9.gun.y_axis mouse 0x0 cursor_y-+ + +ss.input.port9.gun_chairs 0xFF80FF + +ss.input.port9.jpkeyboard.0 keyboard 0x0 39 + +ss.input.port9.jpkeyboard.1 keyboard 0x0 30 + +ss.input.port9.jpkeyboard.2 keyboard 0x0 31 + +ss.input.port9.jpkeyboard.3 keyboard 0x0 32 + +ss.input.port9.jpkeyboard.4 keyboard 0x0 33 + +ss.input.port9.jpkeyboard.5 keyboard 0x0 34 + +ss.input.port9.jpkeyboard.6 keyboard 0x0 35 + +ss.input.port9.jpkeyboard.7 keyboard 0x0 36 + +ss.input.port9.jpkeyboard.8 keyboard 0x0 37 + +ss.input.port9.jpkeyboard.9 keyboard 0x0 38 + +ss.input.port9.jpkeyboard.a keyboard 0x0 4 + +ss.input.port9.jpkeyboard.at keyboard 0x0 47 + +ss.input.port9.jpkeyboard.b keyboard 0x0 5 + +ss.input.port9.jpkeyboard.backslash keyboard 0x0 135 + +ss.input.port9.jpkeyboard.backspace keyboard 0x0 42 + +ss.input.port9.jpkeyboard.c keyboard 0x0 6 + +ss.input.port9.jpkeyboard.capslock keyboard 0x0 57 + +ss.input.port9.jpkeyboard.circumflex keyboard 0x0 46 + +ss.input.port9.jpkeyboard.colon keyboard 0x0 52 + +ss.input.port9.jpkeyboard.comma keyboard 0x0 54 + +ss.input.port9.jpkeyboard.conv keyboard 0x0 138 + +ss.input.port9.jpkeyboard.d keyboard 0x0 7 + +ss.input.port9.jpkeyboard.delete keyboard 0x0 76 + +ss.input.port9.jpkeyboard.down keyboard 0x0 81 + +ss.input.port9.jpkeyboard.e keyboard 0x0 8 + +ss.input.port9.jpkeyboard.end keyboard 0x0 77 + +ss.input.port9.jpkeyboard.enter keyboard 0x0 40 + +ss.input.port9.jpkeyboard.esc keyboard 0x0 41 + +ss.input.port9.jpkeyboard.f keyboard 0x0 9 + +ss.input.port9.jpkeyboard.f1 keyboard 0x0 58 + +ss.input.port9.jpkeyboard.f10 keyboard 0x0 67 + +ss.input.port9.jpkeyboard.f11 keyboard 0x0 68 + +ss.input.port9.jpkeyboard.f12 keyboard 0x0 69 + +ss.input.port9.jpkeyboard.f2 keyboard 0x0 59 + +ss.input.port9.jpkeyboard.f3 keyboard 0x0 60 + +ss.input.port9.jpkeyboard.f4 keyboard 0x0 61 + +ss.input.port9.jpkeyboard.f5 keyboard 0x0 62 + +ss.input.port9.jpkeyboard.f6 keyboard 0x0 63 + +ss.input.port9.jpkeyboard.f7 keyboard 0x0 64 + +ss.input.port9.jpkeyboard.f8 keyboard 0x0 65 + +ss.input.port9.jpkeyboard.f9 keyboard 0x0 66 + +ss.input.port9.jpkeyboard.g keyboard 0x0 10 + +ss.input.port9.jpkeyboard.h keyboard 0x0 11 + +ss.input.port9.jpkeyboard.hkr keyboard 0x0 136 + +ss.input.port9.jpkeyboard.home keyboard 0x0 74 + +ss.input.port9.jpkeyboard.hwfw keyboard 0x0 53 + +ss.input.port9.jpkeyboard.i keyboard 0x0 12 + +ss.input.port9.jpkeyboard.insert keyboard 0x0 73 + +ss.input.port9.jpkeyboard.j keyboard 0x0 13 + +ss.input.port9.jpkeyboard.k keyboard 0x0 14 + +ss.input.port9.jpkeyboard.l keyboard 0x0 15 + +ss.input.port9.jpkeyboard.lalt keyboard 0x0 226 + +ss.input.port9.jpkeyboard.lctrl keyboard 0x0 224 + +ss.input.port9.jpkeyboard.left keyboard 0x0 80 + +ss.input.port9.jpkeyboard.leftbracket keyboard 0x0 48 + +ss.input.port9.jpkeyboard.lshift keyboard 0x0 225 + +ss.input.port9.jpkeyboard.m keyboard 0x0 16 + +ss.input.port9.jpkeyboard.minus keyboard 0x0 45 + +ss.input.port9.jpkeyboard.n keyboard 0x0 17 + +ss.input.port9.jpkeyboard.nonconv keyboard 0x0 139 + +ss.input.port9.jpkeyboard.o keyboard 0x0 18 + +ss.input.port9.jpkeyboard.p keyboard 0x0 19 + +ss.input.port9.jpkeyboard.pagedown keyboard 0x0 78 + +ss.input.port9.jpkeyboard.pageup keyboard 0x0 75 + +ss.input.port9.jpkeyboard.pause keyboard 0x0 72 || keyboard 0x0 83 + +ss.input.port9.jpkeyboard.period keyboard 0x0 55 + +ss.input.port9.jpkeyboard.printscreen keyboard 0x0 70 + +ss.input.port9.jpkeyboard.q keyboard 0x0 20 + +ss.input.port9.jpkeyboard.r keyboard 0x0 21 + +ss.input.port9.jpkeyboard.ralt keyboard 0x0 230 + +ss.input.port9.jpkeyboard.rctrl keyboard 0x0 228 + +ss.input.port9.jpkeyboard.right keyboard 0x0 79 + +ss.input.port9.jpkeyboard.rightbracket keyboard 0x0 49 + +ss.input.port9.jpkeyboard.rshift keyboard 0x0 229 + +ss.input.port9.jpkeyboard.s keyboard 0x0 22 + +ss.input.port9.jpkeyboard.scrolllock keyboard 0x0 71 + +ss.input.port9.jpkeyboard.semicolon keyboard 0x0 51 + +ss.input.port9.jpkeyboard.slash keyboard 0x0 56 + +ss.input.port9.jpkeyboard.space keyboard 0x0 44 + +ss.input.port9.jpkeyboard.t keyboard 0x0 23 + +ss.input.port9.jpkeyboard.tab keyboard 0x0 43 + +ss.input.port9.jpkeyboard.u keyboard 0x0 24 + +ss.input.port9.jpkeyboard.up keyboard 0x0 82 + +ss.input.port9.jpkeyboard.v keyboard 0x0 25 + +ss.input.port9.jpkeyboard.w keyboard 0x0 26 + +ss.input.port9.jpkeyboard.x keyboard 0x0 27 + +ss.input.port9.jpkeyboard.y keyboard 0x0 28 + +ss.input.port9.jpkeyboard.yen keyboard 0x0 137 + +ss.input.port9.jpkeyboard.z keyboard 0x0 29 + +ss.input.port9.keyboard.0 keyboard 0x0 39 + +ss.input.port9.keyboard.1 keyboard 0x0 30 + +ss.input.port9.keyboard.2 keyboard 0x0 31 + +ss.input.port9.keyboard.3 keyboard 0x0 32 + +ss.input.port9.keyboard.4 keyboard 0x0 33 + +ss.input.port9.keyboard.5 keyboard 0x0 34 + +ss.input.port9.keyboard.6 keyboard 0x0 35 + +ss.input.port9.keyboard.7 keyboard 0x0 36 + +ss.input.port9.keyboard.8 keyboard 0x0 37 + +ss.input.port9.keyboard.9 keyboard 0x0 38 + +ss.input.port9.keyboard.a keyboard 0x0 4 + +ss.input.port9.keyboard.b keyboard 0x0 5 + +ss.input.port9.keyboard.backslash keyboard 0x0 49 || keyboard 0x0 135 + +ss.input.port9.keyboard.backspace keyboard 0x0 42 + +ss.input.port9.keyboard.c keyboard 0x0 6 + +ss.input.port9.keyboard.capslock keyboard 0x0 57 + +ss.input.port9.keyboard.comma keyboard 0x0 54 + +ss.input.port9.keyboard.d keyboard 0x0 7 + +ss.input.port9.keyboard.delete keyboard 0x0 76 + +ss.input.port9.keyboard.down keyboard 0x0 81 + +ss.input.port9.keyboard.e keyboard 0x0 8 + +ss.input.port9.keyboard.end keyboard 0x0 77 + +ss.input.port9.keyboard.enter keyboard 0x0 40 + +ss.input.port9.keyboard.equals keyboard 0x0 46 + +ss.input.port9.keyboard.esc keyboard 0x0 41 + +ss.input.port9.keyboard.f keyboard 0x0 9 + +ss.input.port9.keyboard.f1 keyboard 0x0 58 + +ss.input.port9.keyboard.f10 keyboard 0x0 67 + +ss.input.port9.keyboard.f11 keyboard 0x0 68 + +ss.input.port9.keyboard.f12 keyboard 0x0 69 + +ss.input.port9.keyboard.f2 keyboard 0x0 59 + +ss.input.port9.keyboard.f3 keyboard 0x0 60 + +ss.input.port9.keyboard.f4 keyboard 0x0 61 + +ss.input.port9.keyboard.f5 keyboard 0x0 62 + +ss.input.port9.keyboard.f6 keyboard 0x0 63 + +ss.input.port9.keyboard.f7 keyboard 0x0 64 + +ss.input.port9.keyboard.f8 keyboard 0x0 65 + +ss.input.port9.keyboard.f9 keyboard 0x0 66 + +ss.input.port9.keyboard.g keyboard 0x0 10 + +ss.input.port9.keyboard.grave keyboard 0x0 53 + +ss.input.port9.keyboard.h keyboard 0x0 11 + +ss.input.port9.keyboard.home keyboard 0x0 74 + +ss.input.port9.keyboard.i keyboard 0x0 12 + +ss.input.port9.keyboard.insert keyboard 0x0 73 + +ss.input.port9.keyboard.j keyboard 0x0 13 + +ss.input.port9.keyboard.k keyboard 0x0 14 + +ss.input.port9.keyboard.kp_asterisk keyboard 0x0 85 + +ss.input.port9.keyboard.kp_center keyboard 0x0 93 + +ss.input.port9.keyboard.kp_delete keyboard 0x0 99 + +ss.input.port9.keyboard.kp_down keyboard 0x0 90 + +ss.input.port9.keyboard.kp_end keyboard 0x0 89 + +ss.input.port9.keyboard.kp_enter keyboard 0x0 88 + +ss.input.port9.keyboard.kp_home keyboard 0x0 95 + +ss.input.port9.keyboard.kp_insert keyboard 0x0 98 + +ss.input.port9.keyboard.kp_left keyboard 0x0 92 + +ss.input.port9.keyboard.kp_minus keyboard 0x0 86 + +ss.input.port9.keyboard.kp_pagedown keyboard 0x0 91 + +ss.input.port9.keyboard.kp_pageup keyboard 0x0 97 + +ss.input.port9.keyboard.kp_plus keyboard 0x0 87 + +ss.input.port9.keyboard.kp_right keyboard 0x0 94 + +ss.input.port9.keyboard.kp_slash keyboard 0x0 84 + +ss.input.port9.keyboard.kp_up keyboard 0x0 96 + +ss.input.port9.keyboard.l keyboard 0x0 15 + +ss.input.port9.keyboard.lalt keyboard 0x0 226 + +ss.input.port9.keyboard.lctrl keyboard 0x0 224 + +ss.input.port9.keyboard.left keyboard 0x0 80 + +ss.input.port9.keyboard.leftbracket keyboard 0x0 47 + +ss.input.port9.keyboard.lshift keyboard 0x0 225 + +ss.input.port9.keyboard.m keyboard 0x0 16 + +ss.input.port9.keyboard.minus keyboard 0x0 45 + +ss.input.port9.keyboard.n keyboard 0x0 17 + +ss.input.port9.keyboard.numlock keyboard 0x0 83 + +ss.input.port9.keyboard.o keyboard 0x0 18 + +ss.input.port9.keyboard.p keyboard 0x0 19 + +ss.input.port9.keyboard.pagedown keyboard 0x0 78 + +ss.input.port9.keyboard.pageup keyboard 0x0 75 + +ss.input.port9.keyboard.pause keyboard 0x0 72 + +ss.input.port9.keyboard.period keyboard 0x0 55 + +ss.input.port9.keyboard.printscreen keyboard 0x0 70 + +ss.input.port9.keyboard.q keyboard 0x0 20 + +ss.input.port9.keyboard.quote keyboard 0x0 52 + +ss.input.port9.keyboard.r keyboard 0x0 21 + +ss.input.port9.keyboard.ralt keyboard 0x0 230 + +ss.input.port9.keyboard.rctrl keyboard 0x0 228 + +ss.input.port9.keyboard.right keyboard 0x0 79 + +ss.input.port9.keyboard.rightbracket keyboard 0x0 48 + +ss.input.port9.keyboard.rshift keyboard 0x0 229 + +ss.input.port9.keyboard.s keyboard 0x0 22 + +ss.input.port9.keyboard.scrolllock keyboard 0x0 71 + +ss.input.port9.keyboard.semicolon keyboard 0x0 51 + +ss.input.port9.keyboard.slash keyboard 0x0 56 + +ss.input.port9.keyboard.space keyboard 0x0 44 + +ss.input.port9.keyboard.t keyboard 0x0 23 + +ss.input.port9.keyboard.tab keyboard 0x0 43 + +ss.input.port9.keyboard.u keyboard 0x0 24 + +ss.input.port9.keyboard.up keyboard 0x0 82 + +ss.input.port9.keyboard.v keyboard 0x0 25 + +ss.input.port9.keyboard.w keyboard 0x0 26 + +ss.input.port9.keyboard.x keyboard 0x0 27 + +ss.input.port9.keyboard.y keyboard 0x0 28 + +ss.input.port9.keyboard.z keyboard 0x0 29 + +ss.input.port9.mission.a + +ss.input.port9.mission.afa + +ss.input.port9.mission.afa.defpos off + +ss.input.port9.mission.afb + +ss.input.port9.mission.afb.defpos off + +ss.input.port9.mission.afc + +ss.input.port9.mission.afc.defpos off + +ss.input.port9.mission.afl + +ss.input.port9.mission.afl.defpos off + +ss.input.port9.mission.afr + +ss.input.port9.mission.afr.defpos off + +ss.input.port9.mission.afspeed + +ss.input.port9.mission.afspeed.defpos 1 + +ss.input.port9.mission.afx + +ss.input.port9.mission.afx.defpos off + +ss.input.port9.mission.afy + +ss.input.port9.mission.afy.defpos off + +ss.input.port9.mission.afz + +ss.input.port9.mission.afz.defpos off + +ss.input.port9.mission.b + +ss.input.port9.mission.c + +ss.input.port9.mission.l + +ss.input.port9.mission.r + +ss.input.port9.mission.start + +ss.input.port9.mission.stick_back + +ss.input.port9.mission.stick_fore + +ss.input.port9.mission.stick_left + +ss.input.port9.mission.stick_right + +ss.input.port9.mission.throttle_down + +ss.input.port9.mission.throttle_up + +ss.input.port9.mission.x + +ss.input.port9.mission.y + +ss.input.port9.mission.z + +ss.input.port9.mouse.left mouse 0x0 button_left + +ss.input.port9.mouse.middle mouse 0x0 button_middle + +ss.input.port9.mouse.motion_down mouse 0x0 rel_y+ + +ss.input.port9.mouse.motion_left mouse 0x0 rel_x- + +ss.input.port9.mouse.motion_right mouse 0x0 rel_x+ + +ss.input.port9.mouse.motion_up mouse 0x0 rel_y- + +ss.input.port9.mouse.right mouse 0x0 button_right + +ss.input.port9.mouse.start keyboard 0x0 40 + +ss.input.port9.wheel.a + +ss.input.port9.wheel.analog_left + +ss.input.port9.wheel.analog_right + +ss.input.port9.wheel.b + +ss.input.port9.wheel.c + +ss.input.port9.wheel.down + +ss.input.port9.wheel.start + +ss.input.port9.wheel.up + +ss.input.port9.wheel.x + +ss.input.port9.wheel.y + +ss.input.port9.wheel.z + +ss.input.sport1.multitap 0 + +ss.input.sport2.multitap 0 + +ss.region_autodetect 1 + +ss.region_default jp + +ss.scanlines 0 + +ss.scsp.resamp_quality 4 + +ss.shader none + +ss.shader.goat.fprog 0 + +ss.shader.goat.hdiv 0.50 + +ss.shader.goat.pat goatron + +ss.shader.goat.slen 1 + +ss.shader.goat.tp 0.50 + +ss.shader.goat.vdiv 0.50 + +ss.slend 239 + +ss.slendp 255 + +ss.slstart 0 + +ss.slstartp 0 + +ss.smpc.autortc 1 + +ss.smpc.autortc.lang english + +ss.special none + +ss.stretch aspect + +ss.tblur 0 + +ss.tblur.accum 0 + +ss.tblur.accum.amount 50 + +ss.videoip 1 + +ss.xres 0 + +ss.xscale 3.000000 + +ss.xscalefs 1.000000 + +ss.yres 0 + +ss.yscale 3.000000 + +ss.yscalefs 1.000000 + +ssfplay.enable 1 + +ssfplay.forcemono 0 + +ssfplay.resamp_quality 4 + +ssfplay.scanlines 0 + +ssfplay.shader none + +ssfplay.shader.goat.fprog 0 + +ssfplay.shader.goat.hdiv 0.50 + +ssfplay.shader.goat.pat goatron + +ssfplay.shader.goat.slen 1 + +ssfplay.shader.goat.tp 0.50 + +ssfplay.shader.goat.vdiv 0.50 + +ssfplay.special none + +ssfplay.stretch aspect + +ssfplay.tblur 0 + +ssfplay.tblur.accum 0 + +ssfplay.tblur.accum.amount 50 + +ssfplay.videoip 0 + +ssfplay.xres 0 + +ssfplay.xscale 2.000000 + +ssfplay.xscalefs 1.000000 + +ssfplay.yres 0 + +ssfplay.yscale 2.000000 + +ssfplay.yscalefs 1.000000 diff --git a/projects/ArchR/packages/emulators/standalone/mednafen/package.mk b/projects/ArchR/packages/emulators/standalone/mednafen/package.mk new file mode 100644 index 0000000000..e255cd7b21 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mednafen/package.mk @@ -0,0 +1,65 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="mednafen" +PKG_VERSION="1.32.1" +PKG_LICENSE="mixed" +PKG_SITE="https://mednafen.github.io/" +# Upstream pull url +#PKG_URL="${PKG_SITE}/releases/files/${PKG_NAME}-${PKG_VERSION}.tar.xz" +# Fork with CHD additions +PKG_URL="https://github.com/sydarn/mednafen/archive/refs/tags/1.32.1-chd.tar.gz" +PKG_DEPENDS_TARGET="toolchain SDL2 flac zstd zlib" +PKG_TOOLCHAIN="configure" + +case ${DEVICE} in + H700|SM8*) + PKG_PATCH_DIRS+=" sdl-input" + ;; +esac + +pre_configure_target() { + +export CFLAGS="${CFLAGS} -flto -fipa-pta" +export CXXFLAGS="${CXXFLAGS} -flto -fipa-pta" +export LDFLAGS="${LDFLAGS} -flto -fipa-pta" + +# unsupported modules +DISABLED_MODULES+=" --disable-apple2 \ + --disable-sasplay \ + --disable-ssfplay" + +case ${DEVICE} in + RK3326|RK3566*|H700) + DISABLED_MODULES+=" --disable-snes \ + --disable-ss \ + --disable-psx" + ;; + RK3399) + DISABLED_MODULES+=" --disable-snes \ + --disable-ss" + ;; + RK3588*) + DISABLED_MODULES+=" --disable-snes" + ;; +esac + +PKG_CONFIGURE_OPTS_TARGET="${DISABLED_MODULES}" +# Need to update automake files + ( + cd .. + sh autogen.sh + ) +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp -rf ${PKG_BUILD}/.${TARGET_NAME}/src/mednafen ${INSTALL}/usr/bin + cp -rf ${PKG_DIR}/scripts/* ${INSTALL}/usr/bin + + chmod +x ${INSTALL}/usr/bin/start_mednafen.sh + chmod +x ${INSTALL}/usr/bin/mednafen_gen_config.sh + + mkdir -p ${INSTALL}/usr/config/${PKG_NAME} + cp ${PKG_DIR}/config/common/* ${INSTALL}/usr/config/${PKG_NAME} +} diff --git a/projects/ArchR/packages/emulators/standalone/mednafen/patches/0001-list-joysticks.patch b/projects/ArchR/packages/emulators/standalone/mednafen/patches/0001-list-joysticks.patch new file mode 100644 index 0000000000..56c281a4a1 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mednafen/patches/0001-list-joysticks.patch @@ -0,0 +1,20 @@ +diff --git a/src/drivers/main.cpp b/src/drivers/main.cpp +index a6f7db2..e69e4c4 100644 +--- a/src/drivers/main.cpp ++++ b/src/drivers/main.cpp +@@ -1980,6 +1980,13 @@ __attribute__((force_align_arg_pointer)) // Not sure what's going on to cause th + #endif + int main(int argc, char *argv[]) + { ++ if(argc == 2) { ++ const char* ljoy = "--list-joysticks"; ++ size_t size = ljoy < argv[1] ? strlen(ljoy) : strlen(argv[1]); ++ if(!strncmp(ljoy, argv[1], size)) ++ JoystickManager::Init(); ++ return 0; ++ } + // SuppressErrorPopups must be set very early. + { + char* mnp = getenv("MEDNAFEN_NOPOPUPS"); +-- +2.39.2 diff --git a/projects/ArchR/packages/emulators/standalone/mednafen/patches/sdl-input/001-force-sdl-joystick.patch b/projects/ArchR/packages/emulators/standalone/mednafen/patches/sdl-input/001-force-sdl-joystick.patch new file mode 100644 index 0000000000..3c872a7d7e --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mednafen/patches/sdl-input/001-force-sdl-joystick.patch @@ -0,0 +1,21 @@ +diff --git a/src/drivers/Joystick.cpp b/src/drivers/Joystick.cpp +index 4944723..978d1bc 100644 +--- a/src/drivers/Joystick.cpp ++++ b/src/drivers/Joystick.cpp +@@ -175,16 +175,7 @@ void Init(void) + + try + { +- #ifdef HAVE_LINUX_JOYSTICK +- main_driver = JoystickDriver_Linux_New(); +- #elif defined(WIN32) +- { +- hicp_driver = JoystickDriver_XInput_New(); +- main_driver = JoystickDriver_DX5_New(hicp_driver != NULL && hicp_driver->NumJoysticks() > 0); +- } +- #elif defined(HAVE_SDL) + main_driver = JoystickDriver_SDL_New(); +- #endif + + if(hicp_driver != NULL) + { diff --git a/projects/ArchR/packages/emulators/standalone/mednafen/scripts/mednafen_gen_config.sh b/projects/ArchR/packages/emulators/standalone/mednafen/scripts/mednafen_gen_config.sh new file mode 100644 index 0000000000..9165eba895 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mednafen/scripts/mednafen_gen_config.sh @@ -0,0 +1,77 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +# Generate controller config +# Set controller guid, just take the first one mednafen lists +GUID1="$(mednafen --list-joysticks | grep ID | awk 'NR==1 {print $2}')" +sed -e "s/@GUID1@/${GUID1}/g" ${MEDNAFEN_CONFIG} >> $MEDNAFEN_HOME/mednafen.cfg + +NAME="$(mednafen --list-joysticks | grep ID | awk 'NR==1 {print $5$6}')" +if [[ "$(mednafen --list-joysticks | grep ID | awk 'NR==1 {print $4}')" = "8BitDo" ]] +then +NAME="X-Box360" +fi + +if [[ "${NAME}" = "X-Box360" ]] +then +export DEVICE_FUNC_KEYA_MODIFIER="BTN_THUMBL" +export DEVICE_FUNC_KEYB_MODIFIER="BTN_THUMBR" +fi + +# explcitly override d-pad that are hats, they are somehow randomly mapped as analog in mednafen +if [[ "${NAME}" = "X-Box360" ]] +then +DEVICE_BTN_DPAD_UP="7-" +DEVICE_BTN_DPAD_DOWN="7+" +DEVICE_BTN_DPAD_LEFT="6-" +DEVICE_BTN_DPAD_RIGHT="6+" +elif [[ "${NAME}" = "OSHPB" ]] +then +DEVICE_BTN_DPAD_UP="6-" +DEVICE_BTN_DPAD_DOWN="6+" +DEVICE_BTN_DPAD_LEFT="5-" +DEVICE_BTN_DPAD_RIGHT="5+" +fi + +# Replace modifiers with actual buttons +for MOD in DEVICE_FUNC_KEYA_MODIFIER DEVICE_FUNC_KEYB_MODIFIER +do + sed -i -e "s/${MOD}/DEVICE_${!MOD}/g" $MEDNAFEN_HOME/mednafen.cfg +done + +# If not trigger minus axes, default to same as trigger button +if [[ -z "${DEVICE_BTN_TL2_MINUS}" ]]; then +DEVICE_BTN_TL2_MINUS=${DEVICE_BTN_TL2} +fi +if [[ -z "${DEVICE_BTN_TR2_MINUS}" ]]; then +DEVICE_BTN_TR2_MINUS=${DEVICE_BTN_TR2} +fi +# General case our 098-controller is right, we just need prefixes. First axes that are prefixed with abs_ +for CONTROL in DEVICE_BTN_AL_DOWN DEVICE_BTN_AL_UP DEVICE_BTN_AL_LEFT \ + DEVICE_BTN_AL_RIGHT DEVICE_BTN_AR_DOWN DEVICE_BTN_AR_UP \ + DEVICE_BTN_AR_LEFT DEVICE_BTN_AR_RIGHT \ + DEVICE_BTN_SOUTH DEVICE_BTN_EAST DEVICE_BTN_NORTH \ + DEVICE_BTN_WEST DEVICE_BTN_TL DEVICE_BTN_TR \ + DEVICE_BTN_TL2 DEVICE_BTN_TR2 DEVICE_BTN_SELECT \ + DEVICE_BTN_START DEVICE_BTN_MODE DEVICE_BTN_THUMBL \ + DEVICE_BTN_THUMBR DEVICE_BTN_DPAD_UP DEVICE_BTN_DPAD_DOWN \ + DEVICE_BTN_DPAD_LEFT DEVICE_BTN_DPAD_RIGHT \ + DEVICE_BTN_TL2_MINUS DEVICE_BTN_TR2_MINUS + +do + # Detect axes, and treat appropriately. Default is button + if [[ ${!CONTROL} =~ [+|-]$ ]]; then + sed -i -e "s/@${CONTROL}@/abs_${!CONTROL}/g" $MEDNAFEN_HOME/mednafen.cfg + elif [[ ${!CONTROL} =~ ^[0-9]+$ ]]; then + # if it's just a number its a button + sed -i -e "s/@${CONTROL}@/button_${!CONTROL}/g" $MEDNAFEN_HOME/mednafen.cfg + else + # unidentifiable buttons or non-existent on this pad + # Set a non-consequential value so that we don't get a syntax error in mednafen config + # I randomly picked button_99 here. + sed -i -e "s/@${CONTROL}@/button_99/g" $MEDNAFEN_HOME/mednafen.cfg + fi +done diff --git a/projects/ArchR/packages/emulators/standalone/mednafen/scripts/start_mednafen.sh b/projects/ArchR/packages/emulators/standalone/mednafen/scripts/start_mednafen.sh new file mode 100644 index 0000000000..176885bdc2 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mednafen/scripts/start_mednafen.sh @@ -0,0 +1,240 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile +. /etc/os-release + +set -x +set_kill set "-9 mednafen" + +export MEDNAFEN_HOME=/storage/.config/mednafen +export MEDNAFEN_CONFIG=/usr/config/mednafen/mednafen.template + +if [ ! -d "$MEDNAFEN_HOME" ] +then + mkdir /storage/.config/mednafen +fi + +if [ ! -f "$MEDNAFEN_HOME/mednafen.cfg" ] +then + /usr/bin/bash /usr/bin/mednafen_gen_config.sh +fi + +#Emulation Station Features +GAME=$(echo "${1}"| sed "s#^/.*/##") +CORE=$(echo "${2}"| sed "s#^/.*/##") +PLATFORM=$(echo "${3}"| sed "s#^/.*/##") +STRETCH=$(get_setting stretch "${PLATFORM}" "${GAME}") +SHADER=$(get_setting shader "${PLATFORM}" "${GAME}") + +#Set the cores to use +CORES=$(get_setting "cores" "${PLATFORM}" "${GAME}") +FEATURES_CMDLINE="" +if [ "${CORES}" = "little" ] +then + EMUPERF="${SLOW_CORES}" +elif [ "${CORES}" = "big" ] +then + EMUPERF="${FAST_CORES}" + if [ "${HW_DEVICE}" = "RK3588" ]; then + FEATURES_CMDLINE+=" -affinity.emu 0x30 " + FEATURES_CMDLINE+=" -ss.affinity.vdp2 0xc0 " + elif [ "${HW_DEVICE}" = "RK3399" ]; then + FEATURES_CMDLINE+=" -affinity.emu 0x10 " + FEATURES_CMDLINE+=" -ss.affinity.vdp2 0x20 " + fi +else + ### All.. + unset EMUPERF +fi + +#Set Save paths +sed -i "s/filesys.path_sav .*/filesys.path_sav \/storage\/roms\/${PLATFORM}/g" $MEDNAFEN_HOME/mednafen.cfg +sed -i "s/filesys.path_savbackup.*/filesys.path_savbackup \/storage\/roms\/${PLATFORM}/g" $MEDNAFEN_HOME/mednafen.cfg +sed -i "s/filesys.path_state.*/filesys.path_state \/storage\/roms\/savestates\/${PLATFORM}/g" $MEDNAFEN_HOME/mednafen.cfg + +# Get command line switches +CORRECT_ASPECT=$(get_setting correct_aspect ${PLATFORM} "${GAME}") +CR="" +if [ ! -z "${CORRECT_ASPECT}" ] +then + CR=" -${CORE}.correct_aspect ${CORRECT_ASPECT}" +fi +if [[ "${CORE}" =~ pce[_fast] ]] +then + if [ "$(get_setting nospritelimit ${PLATFORM} "${GAME}")" = "1" ] + then + FEATURES_CMDLINE+=" -${CORE}.nospritelimit 1" + else + FEATURES_CMDLINE+=" -${CORE}.nospritelimit 0" + fi + if [ "$(get_setting forcesgx ${PLATFORM} "${GAME}")" = "1" ] + then + FEATURES_CMDLINE+=" -${CORE}.forcesgx 1" + else + FEATURES_CMDLINE+=" -${CORE}.forcesgx 0" + fi + if [ "${CORE}" = pce_fast ] + then + FEATURES_CMDLINE+=$CR + OCM=$(get_setting ocmultiplier ${PLATFORM} "${GAME}") + if [ ${OCM} > 1 ] + then + FEATURES_CMDLINE+=" -${CORE}.ocmultiplier ${OCM}" + else + FEATURES_CMDLINE+=" -${CORE}.ocmultiplier 1" + fi + CDS=$(get_setting cdspeed ${PLATFORM} "${GAME}") + if [ ${CDS} > 1 ] + then + FEATURES_CMDLINE+=" -${CORE}.cdspeed ${CDS}" + else + FEATURES_CMDLINE+=" -${CORE}.cdspeed 1" + fi + fi +elif [ "${CORE}" = "gb" ] +then + ST=$(get_setting system_type "${PLATFORM}" "${GAME}") + if [[ "${ST}" =~ auto|dmg|cgb|agb ]] + then + FEATURES_CMDLINE+=" -${CORE}.system_type ${ST}" + else + FEATURES_CMDLINE+=" -${CORE}.system_type auto" + fi +elif [ "${CORE}" = "gba" ] +then + if [ $(get_setting tblur "${PLATFORM}" "${GAME}") = "1" ] + then + FEATURES_CMDLINE+=" -${CORE}.tblur 1" + else + FEATURES_CMDLINE+=" -${CORE}.tblur 0" + fi +elif [ "${CORE}" = "nes" ] +then + FEATURES_CMDLINE+=$CR + if [ $(get_setting clipsides "${PLATFORM}" "${GAME}") = "1" ] + then + FEATURES_CMDLINE+=" -${CORE}.clipsides 1" + else + FEATURES_CMDLINE+=" -${CORE}.clipsides 0" + fi + if [ $(get_setting no8lim "${PLATFORM}" "${GAME}") = "1" ] + then + FEATURES_CMDLINE+=" -${CORE}.no8lim 1" + else + FEATURES_CMDLINE+=" -${CORE}.no8lim 0" + fi +elif [ "${CORE}" = "snes_faust" ] +then + FEATURES_CMDLINE+=$CR + if [ $(get_setting spex "${PLATFORM}" "${GAME}") = "1" ] + then + FEATURES_CMDLINE+=" -${CORE}.spex 1" + else + FEATURES_CMDLINE+=" -${CORE}.spex 0" + fi + if [ $(get_setting spex.sound "${PLATFORM}" "${GAME}") = "1" ] + then + FEATURES_CMDLINE+=" -${CORE}.spex.sound 1" + else + FEATURES_CMDLINE+=" -${CORE}.spex.sound 0" + fi + SFXCR=$(get_setting superfx.clock_rate ${PLATFORM} "${GAME}") + if [ ${SFXCR} > 1 ] + then + FEATURES_CMDLINE+=" -${CORE}.superfx.clock_rate ${SFXCR}" + else + FEATURES_CMDLINE+=" -${CORE}.superfx.clock_rate 100" + fi + if [[ "$(get_setting superfx.icache ${PLATFORM} "${GAME}")" == "1" ]] + then + FEATURES_CMDLINE+=" -${CORE}.superfx.icache 1" + else + FEATURES_CMDLINE+=" -${CORE}.superfx.icache 0" + fi + CX4CR=$(get_setting cx4.clock_rate ${PLATFORM} "${GAME}") + if [ ${CX4CR} > 1 ] + then + FEATURES_CMDLINE+=" -${CORE}.cx4.clock_rate ${CX4CR}" + else + FEATURES_CMDLINE+=" -${CORE}.cx4.clock_rate 100" + fi +elif [ "${CORE}" = "vb" ] +then + CE=$(get_setting cpu_emulation "${PLATFORM}" "${GAME}") + if [[ "${CE}" =~ fast|accurate ]] + then + FEATURES_CMDLINE+=" -${CORE}.cpu_emulation ${CE}" + else + FEATURES_CMDLINE+=" -${CORE}.cpu_emulation fast" + fi + DM=$(get_setting 3dmode "${PLATFORM}" "${GAME}") + if [[ "${DM}" =~ anaglyph|cscope|sidebyside|vli|hli|left|right] ]] + then + FEATURES_CMDLINE+=" -${CORE}.3dmode ${CE}" + fi +elif [ "${CORE}" = "pcfx" ] +then + CE=$(get_setting cpu_emulation "${PLATFORM}" "${GAME}") + if [[ "${CE}" =~ auto|fast|accurate ]] + then + FEATURES_CMDLINE+=" -${CORE}.cpu_emulation ${CE}" + else + FEATURES_CMDLINE+=" -${CORE}.cpu_emulation auto" + fi + CS=$(get_setting cdspeed "${PLATFORM}" "${GAME}") + if [ CS > 2] + then + FEATURES_CMDLINE+=" -${CORE}.cdspeed ${CS}" + else + FEATURES_CMDLINE+=" -${CORE}.cdspeed 2" + fi +elif [ "${CORE}" = "ss" ] +then + FEATURES_CMDLINE+=$CR + IP1=$(get_setting input.port1 "${PLATFORM}" "${GAME}") + if [[ "${IP1}" =~ gamepad|3dpad|gun ]] + then + FEATURES_CMDLINE+=" -${CORE}.input.port1 ${IP1}" + else + FEATURES_CMDLINE+=" -${CORE}.input.port1 gamepad" + fi + IP13DMODE=$(get_setting input.port1.3dpad.mode.defpos "${PLATFORM}" "${GAME}") + if [[ "${IP13DMODE}" =~ digital|analog ]] + then + FEATURES_CMDLINE+=" -${CORE}.input.port1.3dpad.mode.defpos ${IP13DMODE}" + else + FEATURES_CMDLINE+=" -${CORE}.input.port1.3dpad.mode.defpos analog" + fi + CART=$(get_setting cart "${PLATFORM}" "${GAME}") + if [[ "${CART}" =~ auto|none|backup|extram1|extram4|cs1ram16 ]] + then + FEATURES_CMDLINE+=" -${CORE}.cart ${CART}" + else + FEATURES_CMDLINE+=" -${CORE}.cart auto" + fi + CARTAD=$(get_setting cart.auto_default "${PLATFORM}" "${GAME}") + if [[ "${CARTAD}" =~ none|backup|extram1|extram4|cs1ram16 ]] + then + FEATURES_CMDLINE+=" -${CORE}.cart.auto_default ${CARTAD}" + else + FEATURES_CMDLINE+=" -${CORE}.cart.auto_default none" + fi +elif [ "${CORE}" = "md" ] +then + FEATURES_CMDLINE+=$CR +elif [ "${CORE}" = "psx" ] +then + FEATURES_CMDLINE+=$CR + IP1=$(get_setting input.port1 "${PLATFORM}" "${GAME}") + if [[ "${IP1}" =~ gamepad|dualshock ]] + then + FEATURES_CMDLINE+=" -${CORE}.input.port1 ${IP1}" + else + FEATURES_CMDLINE+=" -${CORE}.input.port1 gamepad" + fi +fi + +#Run mednafen +${EMUPERF} /usr/bin/mednafen -force_module ${CORE} -${CORE}.stretch ${STRETCH:="aspect"} -${CORE}.shader ${SHADER:="ipsharper"} ${FEATURES_CMDLINE} "${1}" diff --git a/projects/ArchR/packages/emulators/standalone/melonds-sa/config/InputPlumber/melonDS.ini b/projects/ArchR/packages/emulators/standalone/melonds-sa/config/InputPlumber/melonDS.ini new file mode 100644 index 0000000000..36fb65fba3 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/melonds-sa/config/InputPlumber/melonDS.ini @@ -0,0 +1,157 @@ +Key_A=-1 +Key_B=-1 +Key_Select=-1 +Key_Start=-1 +Key_Right=-1 +Key_Left=-1 +Key_Up=-1 +Key_Down=-1 +Key_R=-1 +Key_L=-1 +Key_X=-1 +Key_Y=-1 +Joy_A=1 +Joy_B=0 +Joy_Select=6 +Joy_Start=7 +Joy_Right=65550 +Joy_Left=1114125 +Joy_Up=17891339 +Joy_Down=16842764 +Joy_R=5 +Joy_L=4 +Joy_X=2 +Joy_Y=3 +HKKey_Lid=-1 +HKKey_Mic=-1 +HKKey_Pause=-1 +HKKey_Reset=-1 +HKKey_FastForward=-1 +HKKey_FastForwardToggle=70 +HKKey_FullscreenToggle=-1 +HKKey_SwapScreens=-1 +HKKey_SwapScreenEmphasis=-1 +HKKey_SolarSensorDecrease=-1 +HKKey_SolarSensorIncrease=-1 +HKKey_FrameStep=-1 +HKKey_PowerButton=-1 +HKKey_VolumeUp=-1 +HKKey_VolumeDown=-1 +HKKey_SaveState=83 +HKKey_LoadState=76 +HKJoy_Lid=-1 +HKJoy_Mic=-1 +HKJoy_Pause=-1 +HKJoy_Reset=-1 +HKJoy_FastForward=-1 +HKJoy_FastForwardToggle=-1 +HKJoy_FullscreenToggle=-1 +HKJoy_SwapScreens=15 +HKJoy_SwapScreenEmphasis=-1 +HKJoy_SolarSensorDecrease=-1 +HKJoy_SolarSensorIncrease=-1 +HKJoy_FrameStep=-1 +HKJoy_PowerButton=-1 +HKJoy_VolumeUp=-1 +HKJoy_VolumeDown=-1 +HKJoy_SaveState=-1 +HKJoy_LoadState=-1 +JoystickID=0 +WindowWidth=1920 +WindowHeight=1080 +WindowMax=0 +ScreenRotation=0 +ScreenGap=0 +ScreenLayout=2 +ScreenSwap=1 +ScreenSizing=0 +IntegerScaling=0 +ScreenAspectTop=0 +ScreenAspectBot=0 +ScreenFilter=1 +ScreenUseGL=1 +ScreenVSync=0 +ScreenVSyncInterval=1 +3DRenderer=0 +Threaded3D=1 +GL_ScaleFactor=1 +GL_BetterPolygons=0 +LimitFPS=1 +AudioSync=0 +ShowOSD=1 +ConsoleType=0 +DirectBoot=1 +JIT_Enable=0 +JIT_MaxBlockSize=32 +JIT_BranchOptimisations=1 +JIT_LiteralOptimisations=1 +JIT_FastMemory=1 +ExternalBIOSEnable=0 +BIOS9Path=/storage/roms/bios/bios9.bin +BIOS7Path=/storage/roms/bios/bios7.bin +FirmwarePath=/storage/roms/bios/firmware.bin +DSiBIOS9Path=/storage/roms/bios/dsi_bios9.bin +DSiBIOS7Path=/storage/roms/bios/dsi_bios7.bin +DSiFirmwarePath=/storage/roms/bios/dsi_firmware.bin +DSiNANDPath=/storage/roms/bios/dsi_nand.bin +DLDIEnable=0 +DLDISDPath=dldi.bin +DLDISize=0 +DLDIReadOnly=0 +DLDIFolderSync=0 +DLDIFolderPath= +DSiSDEnable=0 +DSiSDPath=dsisd.bin +DSiSDSize=0 +DSiSDReadOnly=0 +DSiSDFolderSync=0 +DSiSDFolderPath= +FirmwareOverrideSettings=0 +FirmwareUsername=melonDS +FirmwareLanguage=1 +FirmwareBirthdayMonth=1 +FirmwareBirthdayDay=1 +FirmwareFavouriteColour=0 +FirmwareMessage= +FirmwareMAC= +MPAudioMode=1 +MPRecvTimeout=25 +LANDevice= +DirectLAN=0 +SavStaRelocSRAM=0 +AudioInterp=0 +AudioBitrate=0 +AudioVolume=256 +DSiVolumeSync=0 +MicInputType=0 +MicWavPath= +LastROMFolder= +LastBIOSFolder= +RecentROM_0= +RecentROM_1= +RecentROM_2= +RecentROM_3= +RecentROM_4= +RecentROM_5= +RecentROM_6= +RecentROM_7= +RecentROM_8= +RecentROM_9= +SaveFilePath=/storage/roms/nds +SavestatePath=/storage/roms/savestates/nds +CheatFilePath= +EnableCheats=0 +MouseHide=0 +MouseHideSeconds=5 +PauseLostFocus=0 +DSBatteryLevelOkay=1 +DSiBatteryLevel=15 +DSiBatteryCharging=1 +Camera0_InputType=0 +Camera0_ImagePath= +Camera0_CamDeviceName= +Camera0_XFlip=0 +Camera1_InputType=0 +Camera1_ImagePath= +Camera1_CamDeviceName= +Camera1_XFlip=0 diff --git a/projects/ArchR/packages/emulators/standalone/melonds-sa/config/RK3399/melonDS.ini b/projects/ArchR/packages/emulators/standalone/melonds-sa/config/RK3399/melonDS.ini new file mode 100644 index 0000000000..0bdc8ac05e --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/melonds-sa/config/RK3399/melonDS.ini @@ -0,0 +1,160 @@ +Key_A=-1 +Key_B=-1 +Key_Select=-1 +Key_Start=-1 +Key_Right=-1 +Key_Left=-1 +Key_Up=-1 +Key_Down=-1 +Key_R=-1 +Key_L=-1 +Key_X=-1 +Key_Y=-1 +Joy_A=1 +Joy_B=0 +Joy_Select=8 +Joy_Start=9 +Joy_Right=65552 +Joy_Left=1114127 +Joy_Up=17891341 +Joy_Down=16842766 +Joy_R=5 +Joy_L=4 +Joy_X=2 +Joy_Y=3 +HKKey_Lid=-1 +HKKey_Mic=-1 +HKKey_Pause=-1 +HKKey_Reset=-1 +HKKey_FastForward=-1 +HKKey_FastForwardToggle=70 +HKKey_FullscreenToggle=-1 +HKKey_SwapScreens=-1 +HKKey_SwapScreenEmphasis=-1 +HKKey_SolarSensorDecrease=-1 +HKKey_SolarSensorIncrease=-1 +HKKey_FrameStep=-1 +HKKey_PowerButton=-1 +HKKey_VolumeUp=-1 +HKKey_VolumeDown=-1 +HKKey_SaveState=83 +HKKey_LoadState=76 +HKJoy_Lid=-1 +HKJoy_Mic=-1 +HKJoy_Pause=-1 +HKJoy_Reset=-1 +HKJoy_FastForward=-1 +HKJoy_FastForwardToggle=-1 +HKJoy_FullscreenToggle=-1 +HKJoy_SwapScreens=11 +HKJoy_SwapScreenEmphasis=-1 +HKJoy_SolarSensorDecrease=-1 +HKJoy_SolarSensorIncrease=-1 +HKJoy_FrameStep=-1 +HKJoy_PowerButton=-1 +HKJoy_VolumeUp=-1 +HKJoy_VolumeDown=-1 +HKJoy_SaveState=-1 +HKJoy_LoadState=-1 +JoystickID=0 +WindowWidth=1920 +WindowHeight=1152 +WindowMax=0 +ScreenRotation=0 +ScreenGap=0 +ScreenLayout=2 +ScreenSwap=1 +ScreenSizing=0 +Screen1Layout=2 +Screen1Enabled=false +Screen1Sizing=5 +IntegerScaling=0 +ScreenAspectTop=0 +ScreenAspectBot=0 +ScreenFilter=1 +ScreenUseGL=1 +ScreenVSync=0 +ScreenVSyncInterval=1 +3DRenderer=0 +Threaded3D=1 +GL_ScaleFactor=1 +GL_BetterPolygons=0 +LimitFPS=1 +AudioSync=0 +ShowOSD=1 +ConsoleType=0 +DirectBoot=1 +JIT_Enable=0 +JIT_MaxBlockSize=32 +JIT_BranchOptimisations=1 +JIT_LiteralOptimisations=1 +JIT_FastMemory=1 +ExternalBIOSEnable=0 +BIOS9Path=/storage/roms/bios/bios9.bin +BIOS7Path=/storage/roms/bios/bios7.bin +FirmwarePath=/storage/roms/bios/firmware.bin +DSiBIOS9Path=/storage/roms/bios/dsi_bios9.bin +DSiBIOS7Path=/storage/roms/bios/dsi_bios7.bin +DSiFirmwarePath=/storage/roms/bios/dsi_firmware.bin +DSiNANDPath=/storage/roms/bios/dsi_nand.bin +DLDIEnable=0 +DLDISDPath=dldi.bin +DLDISize=0 +DLDIReadOnly=0 +DLDIFolderSync=0 +DLDIFolderPath= +DSiSDEnable=0 +DSiSDPath=dsisd.bin +DSiSDSize=0 +DSiSDReadOnly=0 +DSiSDFolderSync=0 +DSiSDFolderPath= +FirmwareOverrideSettings=0 +FirmwareUsername=melonDS +FirmwareLanguage=1 +FirmwareBirthdayMonth=1 +FirmwareBirthdayDay=1 +FirmwareFavouriteColour=0 +FirmwareMessage= +FirmwareMAC= +MPAudioMode=1 +MPRecvTimeout=25 +LANDevice= +DirectLAN=0 +SavStaRelocSRAM=0 +AudioInterp=0 +AudioBitrate=0 +AudioVolume=256 +DSiVolumeSync=0 +MicInputType=0 +MicWavPath= +LastROMFolder= +LastBIOSFolder= +RecentROM_0= +RecentROM_1= +RecentROM_2= +RecentROM_3= +RecentROM_4= +RecentROM_5= +RecentROM_6= +RecentROM_7= +RecentROM_8= +RecentROM_9= +SaveFilePath=/storage/roms/nds +SavestatePath=/storage/roms/savestates/nds +CheatFilePath= +EnableCheats=0 +MouseHide=0 +MouseHideSeconds=5 +PauseLostFocus=0 +DSBatteryLevelOkay=1 +DSiBatteryLevel=15 +DSiBatteryCharging=1 +Camera0_InputType=0 +Camera0_ImagePath= +Camera0_CamDeviceName= +Camera0_XFlip=0 +Camera1_InputType=0 +Camera1_ImagePath= +Camera1_CamDeviceName= +Camera1_XFlip=0 diff --git a/projects/ArchR/packages/emulators/standalone/melonds-sa/config/RK3566/melonDS.ini b/projects/ArchR/packages/emulators/standalone/melonds-sa/config/RK3566/melonDS.ini new file mode 100644 index 0000000000..3e1ecce8e4 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/melonds-sa/config/RK3566/melonDS.ini @@ -0,0 +1,160 @@ +Key_A=-1 +Key_B=-1 +Key_Select=-1 +Key_Start=-1 +Key_Right=-1 +Key_Left=-1 +Key_Up=-1 +Key_Down=-1 +Key_R=-1 +Key_L=-1 +Key_X=-1 +Key_Y=-1 +Joy_A=1 +Joy_B=0 +Joy_Select=8 +Joy_Start=9 +Joy_Right=65552 +Joy_Left=1114127 +Joy_Up=17891341 +Joy_Down=16842766 +Joy_R=5 +Joy_L=4 +Joy_X=2 +Joy_Y=3 +HKKey_Lid=-1 +HKKey_Mic=-1 +HKKey_Pause=-1 +HKKey_Reset=-1 +HKKey_FastForward=-1 +HKKey_FastForwardToggle=-1 +HKKey_FullscreenToggle=-1 +HKKey_SwapScreens=-1 +HKKey_SwapScreenEmphasis=-1 +HKKey_SolarSensorDecrease=-1 +HKKey_SolarSensorIncrease=-1 +HKKey_FrameStep=-1 +HKKey_PowerButton=-1 +HKKey_VolumeUp=-1 +HKKey_VolumeDown=-1 +HKKey_SaveState=-1 +HKKey_LoadState=-1 +HKJoy_Lid=-1 +HKJoy_Mic=-1 +HKJoy_Pause=-1 +HKJoy_Reset=-1 +HKJoy_FastForward=-1 +HKJoy_FastForwardToggle=-1 +HKJoy_FullscreenToggle=-1 +HKJoy_SwapScreens=11 +HKJoy_SwapScreenEmphasis=-1 +HKJoy_SolarSensorDecrease=-1 +HKJoy_SolarSensorIncrease=-1 +HKJoy_FrameStep=-1 +HKJoy_PowerButton=-1 +HKJoy_VolumeUp=-1 +HKJoy_VolumeDown=-1 +HKJoy_SaveState=7 +HKJoy_LoadState=6 +JoystickID=0 +WindowWidth=1920 +WindowHeight=1152 +WindowMax=0 +ScreenRotation=0 +ScreenGap=0 +ScreenLayout=2 +ScreenSwap=1 +ScreenSizing=0 +Screen1Layout=2 +Screen1Enabled=false +Screen1Sizing=5 +IntegerScaling=0 +ScreenAspectTop=0 +ScreenAspectBot=0 +ScreenFilter=1 +ScreenUseGL=1 +ScreenVSync=0 +ScreenVSyncInterval=1 +3DRenderer=0 +Threaded3D=1 +GL_ScaleFactor=1 +GL_BetterPolygons=0 +LimitFPS=1 +AudioSync=0 +ShowOSD=1 +ConsoleType=0 +DirectBoot=1 +JIT_Enable=1 +JIT_MaxBlockSize=32 +JIT_BranchOptimisations=1 +JIT_LiteralOptimisations=1 +JIT_FastMemory=1 +ExternalBIOSEnable=0 +BIOS9Path=/storage/roms/bios/bios9.bin +BIOS7Path=/storage/roms/bios/bios7.bin +FirmwarePath=/storage/roms/bios/firmware.bin +DSiBIOS9Path=/storage/roms/bios/dsi_bios9.bin +DSiBIOS7Path=/storage/roms/bios/dsi_bios7.bin +DSiFirmwarePath=/storage/roms/bios/dsi_firmware.bin +DSiNANDPath=/storage/roms/bios/dsi_nand.bin +DLDIEnable=0 +DLDISDPath=dldi.bin +DLDISize=0 +DLDIReadOnly=0 +DLDIFolderSync=0 +DLDIFolderPath= +DSiSDEnable=0 +DSiSDPath=dsisd.bin +DSiSDSize=0 +DSiSDReadOnly=0 +DSiSDFolderSync=0 +DSiSDFolderPath= +FirmwareOverrideSettings=0 +FirmwareUsername=melonDS +FirmwareLanguage=1 +FirmwareBirthdayMonth=1 +FirmwareBirthdayDay=1 +FirmwareFavouriteColour=0 +FirmwareMessage= +FirmwareMAC= +MPAudioMode=1 +MPRecvTimeout=25 +LANDevice= +DirectLAN=0 +SavStaRelocSRAM=0 +AudioInterp=0 +AudioBitrate=0 +AudioVolume=256 +DSiVolumeSync=0 +MicInputType=0 +MicWavPath= +LastROMFolder= +LastBIOSFolder= +RecentROM_0= +RecentROM_1= +RecentROM_2= +RecentROM_3= +RecentROM_4= +RecentROM_5= +RecentROM_6= +RecentROM_7= +RecentROM_8= +RecentROM_9= +SaveFilePath=/storage/roms/nds +SavestatePath=/storage/roms/savestates/nds +CheatFilePath= +EnableCheats=0 +MouseHide=0 +MouseHideSeconds=5 +PauseLostFocus=0 +DSBatteryLevelOkay=1 +DSiBatteryLevel=15 +DSiBatteryCharging=1 +Camera0_InputType=0 +Camera0_ImagePath= +Camera0_CamDeviceName= +Camera0_XFlip=0 +Camera1_InputType=0 +Camera1_ImagePath= +Camera1_CamDeviceName= +Camera1_XFlip=0 diff --git a/projects/ArchR/packages/emulators/standalone/melonds-sa/config/RK3588/melonDS.ini b/projects/ArchR/packages/emulators/standalone/melonds-sa/config/RK3588/melonDS.ini new file mode 100644 index 0000000000..6fd5e441c3 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/melonds-sa/config/RK3588/melonDS.ini @@ -0,0 +1,160 @@ +Key_A=-1 +Key_B=-1 +Key_Select=-1 +Key_Start=-1 +Key_Right=-1 +Key_Left=-1 +Key_Up=-1 +Key_Down=-1 +Key_R=-1 +Key_L=-1 +Key_X=-1 +Key_Y=-1 +Joy_A=1 +Joy_B=0 +Joy_Select=7 +Joy_Start=8 +Joy_Right=16842767 +Joy_Left=17891342 +Joy_Up=65548 +Joy_Down=1114125 +Joy_R=85065727 +Joy_L=34734079 +Joy_X=3 +Joy_Y=4 +HKKey_Lid=-1 +HKKey_Mic=77 +HKKey_Pause=-1 +HKKey_Reset=-1 +HKKey_FastForward=70 +HKKey_FastForwardToggle=-1 +HKKey_FullscreenToggle=-1 +HKKey_SwapScreens=-1 +HKKey_SwapScreenEmphasis=-1 +HKKey_SolarSensorDecrease=-1 +HKKey_SolarSensorIncrease=-1 +HKKey_FrameStep=-1 +HKKey_PowerButton=-1 +HKKey_VolumeUp=-1 +HKKey_VolumeDown=-1 +HKKey_SaveState=83 +HKKey_LoadState=76 +HKJoy_Lid=-1 +HKJoy_Mic=-1 +HKJoy_Pause=-1 +HKJoy_Reset=-1 +HKJoy_FastForward=-1 +HKJoy_FastForwardToggle=-1 +HKJoy_FullscreenToggle=-1 +HKJoy_SwapScreens=2 +HKJoy_SwapScreenEmphasis=-1 +HKJoy_SolarSensorDecrease=-1 +HKJoy_SolarSensorIncrease=-1 +HKJoy_FrameStep=-1 +HKJoy_PowerButton=-1 +HKJoy_VolumeUp=-1 +HKJoy_VolumeDown=-1 +HKJoy_SaveState=-1 +HKJoy_LoadState=-1 +JoystickID=0 +WindowWidth=1920 +WindowHeight=1080 +WindowMax=0 +ScreenRotation=0 +ScreenGap=0 +ScreenLayout=2 +ScreenSwap=0 +ScreenSizing=3 +Screen1Layout=2 +Screen1Enabled=false +Screen1Sizing=5 +IntegerScaling=0 +ScreenAspectTop=0 +ScreenAspectBot=0 +ScreenFilter=1 +ScreenUseGL=0 +ScreenVSync=0 +ScreenVSyncInterval=1 +3DRenderer=0 +Threaded3D=1 +GL_ScaleFactor=1 +GL_BetterPolygons=0 +LimitFPS=1 +AudioSync=0 +ShowOSD=1 +ConsoleType=0 +DirectBoot=1 +JIT_Enable=0 +JIT_MaxBlockSize=32 +JIT_BranchOptimisations=1 +JIT_LiteralOptimisations=1 +JIT_FastMemory=1 +ExternalBIOSEnable=0 +BIOS9Path=/storage/roms/bios/bios9.bin +BIOS7Path=/storage/roms/bios/bios7.bin +FirmwarePath=/storage/roms/bios/firmware.bin +DSiBIOS9Path=/storage/roms/bios/dsi_bios9.bin +DSiBIOS7Path=/storage/roms/bios/dsi_bios7.bin +DSiFirmwarePath=/storage/roms/bios/dsi_firmware.bin +DSiNANDPath=/storage/roms/bios/dsi_nand.bin +DLDIEnable=0 +DLDISDPath=dldi.bin +DLDISize=0 +DLDIReadOnly=0 +DLDIFolderSync=0 +DLDIFolderPath= +DSiSDEnable=0 +DSiSDPath=dsisd.bin +DSiSDSize=0 +DSiSDReadOnly=0 +DSiSDFolderSync=0 +DSiSDFolderPath= +FirmwareOverrideSettings=0 +FirmwareUsername=melonDS +FirmwareLanguage=1 +FirmwareBirthdayMonth=1 +FirmwareBirthdayDay=1 +FirmwareFavouriteColour=0 +FirmwareMessage= +FirmwareMAC= +MPAudioMode=1 +MPRecvTimeout=25 +LANDevice= +DirectLAN=0 +SavStaRelocSRAM=0 +AudioInterp=0 +AudioBitrate=0 +AudioVolume=256 +DSiVolumeSync=0 +MicInputType=0 +MicWavPath= +LastROMFolder= +LastBIOSFolder= +RecentROM_0= +RecentROM_1= +RecentROM_2= +RecentROM_3= +RecentROM_4= +RecentROM_5= +RecentROM_6= +RecentROM_7= +RecentROM_8= +RecentROM_9= +SaveFilePath=/storage/roms/nds +SavestatePath=/storage/roms/savestates/nds +CheatFilePath= +EnableCheats=0 +MouseHide=0 +MouseHideSeconds=5 +PauseLostFocus=0 +DSBatteryLevelOkay=1 +DSiBatteryLevel=15 +DSiBatteryCharging=1 +Camera0_InputType=0 +Camera0_ImagePath= +Camera0_CamDeviceName= +Camera0_XFlip=0 +Camera1_InputType=0 +Camera1_ImagePath= +Camera1_CamDeviceName= +Camera1_XFlip=0 diff --git a/projects/ArchR/packages/emulators/standalone/melonds-sa/config/S922X/melonDS.ini b/projects/ArchR/packages/emulators/standalone/melonds-sa/config/S922X/melonDS.ini new file mode 100644 index 0000000000..c424999feb --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/melonds-sa/config/S922X/melonDS.ini @@ -0,0 +1,170 @@ +Key_A=-1 +Key_B=-1 +Key_Select=-1 +Key_Start=-1 +Key_Right=-1 +Key_Left=-1 +Key_Up=-1 +Key_Down=-1 +Key_R=-1 +Key_L=-1 +Key_X=-1 +Key_Y=-1 +Joy_A=1 +Joy_B=0 +Joy_Select=9 +Joy_Start=10 +Joy_Right=17 +Joy_Left=16 +Joy_Up=14 +Joy_Down=15 +Joy_R=6 +Joy_L=5 +Joy_X=3 +Joy_Y=4 +HKKey_Lid=-1 +HKKey_Mic=-1 +HKKey_Pause=-1 +HKKey_Reset=-1 +HKKey_FastForward=-1 +HKKey_FastForwardToggle=-1 +HKKey_FullscreenToggle=-1 +HKKey_SwapScreens=-1 +HKKey_SwapScreenEmphasis=-1 +HKKey_SolarSensorDecrease=-1 +HKKey_SolarSensorIncrease=-1 +HKKey_FrameStep=-1 +HKKey_PowerButton=-1 +HKKey_VolumeUp=-1 +HKKey_VolumeDown=-1 +HKKey_SaveState=83 +HKKey_LoadState=76 +HKJoy_Lid=-1 +HKJoy_Mic=-1 +HKJoy_Pause=-1 +HKJoy_Reset=-1 +HKJoy_FastForward=-1 +HKJoy_FastForwardToggle=-1 +HKJoy_FullscreenToggle=-1 +HKJoy_SwapScreens=7 +HKJoy_SwapScreenEmphasis=-1 +HKJoy_SolarSensorDecrease=-1 +HKJoy_SolarSensorIncrease=-1 +HKJoy_FrameStep=-1 +HKJoy_PowerButton=-1 +HKJoy_VolumeUp=-1 +HKJoy_VolumeDown=-1 +HKJoy_SaveState=-1 +HKJoy_LoadState=-1 +JoystickID=0 +WindowWidth=854 +WindowHeight=480 +WindowMax=0 +ScreenRotation=0 +ScreenGap=0 +ScreenLayout=2 +ScreenSwap=0 +ScreenSizing=1 +Screen1Layout=2 +Screen1Enabled=false +Screen1Sizing=5 +IntegerScaling=0 +ScreenAspectTop=0 +ScreenAspectBot=0 +ScreenFilter=1 +ScreenUseGL=1 +ScreenVSync=0 +ScreenVSyncInterval=1 +3DRenderer=0 +Threaded3D=1 +GL_ScaleFactor=1 +GL_BetterPolygons=0 +GL_HiresCoordinates=1 +LimitFPS=1 +MaxFPS=1000 +AudioSync=0 +ShowOSD=1 +ConsoleType=0 +DirectBoot=1 +JIT_Enable=0 +JIT_MaxBlockSize=32 +JIT_BranchOptimisations=1 +JIT_LiteralOptimisations=1 +JIT_FastMemory=1 +ExternalBIOSEnable=0 +BIOS9Path=/storage/roms/bios/bios9.bin +BIOS7Path=/storage/roms/bios/bios7.bin +FirmwarePath=/storage/roms/bios/firmware.bin +DSiBIOS9Path=/storage/roms/bios/dsi_bios9.bin +DSiBIOS7Path=/storage/roms/bios/dsi_bios7.bin +DSiFirmwarePath=/storage/roms/bios/dsi_firmware.bin +DSiNANDPath=/storage/roms/bios/dsi_nand.bin +DLDIEnable=0 +DLDISDPath=dldi.bin +DLDISize=0 +DLDIReadOnly=0 +DLDIFolderSync=0 +DLDIFolderPath= +DSiSDEnable=0 +DSiSDPath=dsisd.bin +DSiSDSize=0 +DSiSDReadOnly=0 +DSiSDFolderSync=0 +DSiSDFolderPath= +FirmwareOverrideSettings=0 +FirmwareUsername=melonDS +FirmwareLanguage=1 +FirmwareBirthdayMonth=1 +FirmwareBirthdayDay=1 +FirmwareFavouriteColour=0 +FirmwareMessage= +FirmwareMAC= +MPAudioMode=1 +MPRecvTimeout=25 +LANDevice= +DirectLAN=0 +SavStaRelocSRAM=0 +AudioInterp=0 +AudioBitDepth=0 +AudioVolume=256 +DSiVolumeSync=0 +MicInputType=0 +MicWavPath= +LastROMFolder= +LastBIOSFolder= +RecentROM_0= +RecentROM_1= +RecentROM_2= +RecentROM_3= +RecentROM_4= +RecentROM_5= +RecentROM_6= +RecentROM_7= +RecentROM_8= +RecentROM_9= +SaveFilePath=/storage/roms/nds +SavestatePath=/storage/roms/savestates/nds +CheatFilePath= +EnableCheats=0 +MouseHide=0 +MouseHideSeconds=5 +PauseLostFocus=0 +UITheme= +RTCOffset=0 +DSBatteryLevelOkay=1 +DSiBatteryLevel=15 +DSiBatteryCharging=1 +DSiFullBIOSBoot=0 +GdbEnabled=0 +GdbPortARM7=3334 +GdbPortARM9=3333 +GdbARM7BreakOnStartup=0 +GdbARM9BreakOnStartup=0 +Camera0_InputType=0 +Camera0_ImagePath= +Camera0_CamDeviceName= +Camera0_XFlip=0 +Camera1_InputType=0 +Camera1_ImagePath= +Camera1_CamDeviceName= +Camera1_XFlip=0 diff --git a/projects/ArchR/packages/emulators/standalone/melonds-sa/config/SDM845/melonDS.ini b/projects/ArchR/packages/emulators/standalone/melonds-sa/config/SDM845/melonDS.ini new file mode 100644 index 0000000000..4425f4752e --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/melonds-sa/config/SDM845/melonDS.ini @@ -0,0 +1,171 @@ +Key_A=-1 +Key_B=-1 +Key_Select=-1 +Key_Start=-1 +Key_Right=-1 +Key_Left=-1 +Key_Up=-1 +Key_Down=-1 +Key_R=-1 +Key_L=-1 +Key_X=-1 +Key_Y=-1 +Joy_A=1 +Joy_B=0 +Joy_Select=8 +Joy_Start=9 +Joy_Right=65552 +Joy_Left=1114127 +Joy_Up=17891341 +Joy_Down=16842766 +Joy_R=5 +Joy_L=4 +Joy_X=2 +Joy_Y=3 +HKKey_Lid=-1 +HKKey_Mic=-1 +HKKey_Pause=-1 +HKKey_Reset=-1 +HKKey_FastForward=-1 +HKKey_FastForwardToggle=-1 +HKKey_FullscreenToggle=-1 +HKKey_SwapScreens=70 +HKKey_SwapScreenEmphasis=77 +HKKey_SolarSensorDecrease=-1 +HKKey_SolarSensorIncrease=-1 +HKKey_FrameStep=-1 +HKKey_PowerButton=-1 +HKKey_VolumeUp=-1 +HKKey_VolumeDown=-1 +HKKey_SaveState=83 +HKKey_LoadState=76 +HKJoy_Lid=-1 +HKJoy_Mic=-1 +HKJoy_Pause=-1 +HKJoy_Reset=-1 +HKJoy_FastForward=-1 +HKJoy_FastForwardToggle=-1 +HKJoy_FullscreenToggle=-1 +HKJoy_SwapScreens=-1 +HKJoy_SwapScreenEmphasis=-1 +HKJoy_SolarSensorDecrease=-1 +HKJoy_SolarSensorIncrease=-1 +HKJoy_FrameStep=-1 +HKJoy_PowerButton=-1 +HKJoy_VolumeUp=-1 +HKJoy_VolumeDown=-1 +HKJoy_SaveState=-1 +HKJoy_LoadState=-1 +JoystickID=0 +WindowWidth=960 +WindowHeight=1080 +WindowMax=0 +ScreenRotation=0 +ScreenGap=0 +ScreenLayout=2 +ScreenSwap=0 +ScreenSizing=0 +Screen1Layout=2 +Screen1Enabled=false +Screen1Sizing=5 +IntegerScaling=0 +ScreenAspectTop=0 +ScreenAspectBot=0 +ScreenFilter=1 +ScreenUseGL=1 +ScreenVSync=0 +ScreenVSyncInterval=1 +3DRenderer=0 +Threaded3D=1 +GL_ScaleFactor=1 +GL_BetterPolygons=0 +GL_HiresCoordinates=1 +LimitFPS=1 +MaxFPS=1000 +AudioSync=0 +ShowOSD=1 +ConsoleType=0 +DirectBoot=1 +JIT_Enable=0 +JIT_MaxBlockSize=32 +JIT_BranchOptimisations=1 +JIT_LiteralOptimisations=1 +JIT_FastMemory=1 +ExternalBIOSEnable=0 +BIOS9Path=/storage/roms/bios/bios9.bin +BIOS7Path=/storage/roms/bios/bios7.bin +FirmwarePath=/storage/roms/bios/firmware.bin +DSiBIOS9Path=/storage/roms/bios/dsi_bios9.bin +DSiBIOS7Path=/storage/roms/bios/dsi_bios7.bin +DSiFirmwarePath=/storage/roms/bios/dsi_firmware.bin +DSiNANDPath=/storage/roms/bios/dsi_nand.bin +DLDIEnable=0 +DLDISDPath=dldi.bin +DLDISize=0 +DLDIReadOnly=0 +DLDIFolderSync=0 +DLDIFolderPath= +DSiSDEnable=0 +DSiSDPath=dsisd.bin +DSiSDSize=0 +DSiSDReadOnly=0 +DSiSDFolderSync=0 +DSiSDFolderPath= +FirmwareOverrideSettings=0 +FirmwareUsername=melonDS +FirmwareLanguage=1 +FirmwareBirthdayMonth=1 +FirmwareBirthdayDay=1 +FirmwareFavouriteColour=0 +FirmwareMessage= +FirmwareMAC= +MPAudioMode=1 +MPRecvTimeout=25 +LANDevice= +DirectLAN=0 +SavStaRelocSRAM=0 +AudioInterp=0 +AudioBitDepth=0 +AudioVolume=256 +DSiVolumeSync=0 +MicInputType=0 +MicDevice= +MicWavPath= +LastROMFolder= +LastBIOSFolder= +RecentROM_0=/storage/roms/nds/DiagnoSe.nds +RecentROM_1=/storage/roms/nds/Chrono Trigger.nds +RecentROM_2= +RecentROM_3= +RecentROM_4= +RecentROM_5= +RecentROM_6= +RecentROM_7= +RecentROM_8= +RecentROM_9= +SaveFilePath=/storage/roms/nds +SavestatePath=/storage/roms/savestates/nds +CheatFilePath= +EnableCheats=0 +MouseHide=0 +MouseHideSeconds=5 +PauseLostFocus=0 +UITheme= +RTCOffset=0 +DSBatteryLevelOkay=1 +DSiBatteryLevel=15 +DSiBatteryCharging=1 +DSiFullBIOSBoot=0 +GdbEnabled=0 +GdbPortARM7=3334 +GdbPortARM9=3333 +GdbARM7BreakOnStartup=0 +GdbARM9BreakOnStartup=0 +Camera0_InputType=0 +Camera0_ImagePath= +Camera0_CamDeviceName= +Camera0_XFlip=0 +Camera1_InputType=0 +Camera1_ImagePath= +Camera1_CamDeviceName= +Camera1_XFlip=0 diff --git a/projects/ArchR/packages/emulators/standalone/melonds-sa/config/SM8250/melonDS.ini b/projects/ArchR/packages/emulators/standalone/melonds-sa/config/SM8250/melonDS.ini new file mode 100644 index 0000000000..b1bbebfaa7 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/melonds-sa/config/SM8250/melonDS.ini @@ -0,0 +1,160 @@ +Key_A=-1 +Key_B=-1 +Key_Select=-1 +Key_Start=-1 +Key_Right=-1 +Key_Left=-1 +Key_Up=-1 +Key_Down=-1 +Key_R=-1 +Key_L=-1 +Key_X=-1 +Key_Y=-1 +Joy_A=1 +Joy_B=0 +Joy_Select=6 +Joy_Start=7 +Joy_Right=65550 +Joy_Left=1114125 +Joy_Up=17891339 +Joy_Down=16842764 +Joy_R=5 +Joy_L=4 +Joy_X=2 +Joy_Y=3 +HKKey_Lid=-1 +HKKey_Mic=-1 +HKKey_Pause=-1 +HKKey_Reset=-1 +HKKey_FastForward=-1 +HKKey_FastForwardToggle=70 +HKKey_FullscreenToggle=-1 +HKKey_SwapScreens=-1 +HKKey_SwapScreenEmphasis=-1 +HKKey_SolarSensorDecrease=-1 +HKKey_SolarSensorIncrease=-1 +HKKey_FrameStep=-1 +HKKey_PowerButton=-1 +HKKey_VolumeUp=-1 +HKKey_VolumeDown=-1 +HKKey_SaveState=83 +HKKey_LoadState=76 +HKJoy_Lid=-1 +HKJoy_Mic=-1 +HKJoy_Pause=-1 +HKJoy_Reset=-1 +HKJoy_FastForward=-1 +HKJoy_FastForwardToggle=-1 +HKJoy_FullscreenToggle=-1 +HKJoy_SwapScreens=15 +HKJoy_SwapScreenEmphasis=-1 +HKJoy_SolarSensorDecrease=-1 +HKJoy_SolarSensorIncrease=-1 +HKJoy_FrameStep=-1 +HKJoy_PowerButton=-1 +HKJoy_VolumeUp=-1 +HKJoy_VolumeDown=-1 +HKJoy_SaveState=-1 +HKJoy_LoadState=-1 +JoystickID=0 +WindowWidth=1920 +WindowHeight=1080 +WindowMax=0 +ScreenRotation=0 +ScreenGap=0 +ScreenLayout=2 +ScreenSwap=1 +ScreenSizing=4 +Screen1Layout=2 +Screen1Enabled=false +Screen1Sizing=5 +IntegerScaling=0 +ScreenAspectTop=0 +ScreenAspectBot=0 +ScreenFilter=1 +ScreenUseGL=1 +ScreenVSync=0 +ScreenVSyncInterval=1 +3DRenderer=0 +Threaded3D=1 +GL_ScaleFactor=1 +GL_BetterPolygons=0 +LimitFPS=1 +AudioSync=0 +ShowOSD=1 +ConsoleType=0 +DirectBoot=1 +JIT_Enable=0 +JIT_MaxBlockSize=32 +JIT_BranchOptimisations=1 +JIT_LiteralOptimisations=1 +JIT_FastMemory=1 +ExternalBIOSEnable=0 +BIOS9Path=/storage/roms/bios/bios9.bin +BIOS7Path=/storage/roms/bios/bios7.bin +FirmwarePath=/storage/roms/bios/firmware.bin +DSiBIOS9Path=/storage/roms/bios/dsi_bios9.bin +DSiBIOS7Path=/storage/roms/bios/dsi_bios7.bin +DSiFirmwarePath=/storage/roms/bios/dsi_firmware.bin +DSiNANDPath=/storage/roms/bios/dsi_nand.bin +DLDIEnable=0 +DLDISDPath=dldi.bin +DLDISize=0 +DLDIReadOnly=0 +DLDIFolderSync=0 +DLDIFolderPath= +DSiSDEnable=0 +DSiSDPath=dsisd.bin +DSiSDSize=0 +DSiSDReadOnly=0 +DSiSDFolderSync=0 +DSiSDFolderPath= +FirmwareOverrideSettings=0 +FirmwareUsername=melonDS +FirmwareLanguage=1 +FirmwareBirthdayMonth=1 +FirmwareBirthdayDay=1 +FirmwareFavouriteColour=0 +FirmwareMessage= +FirmwareMAC= +MPAudioMode=1 +MPRecvTimeout=25 +LANDevice= +DirectLAN=0 +SavStaRelocSRAM=0 +AudioInterp=0 +AudioBitrate=0 +AudioVolume=256 +DSiVolumeSync=0 +MicInputType=0 +MicWavPath= +LastROMFolder= +LastBIOSFolder= +RecentROM_0= +RecentROM_1= +RecentROM_2= +RecentROM_3= +RecentROM_4= +RecentROM_5= +RecentROM_6= +RecentROM_7= +RecentROM_8= +RecentROM_9= +SaveFilePath=/storage/roms/nds +SavestatePath=/storage/roms/savestates/nds +CheatFilePath= +EnableCheats=0 +MouseHide=0 +MouseHideSeconds=5 +PauseLostFocus=0 +DSBatteryLevelOkay=1 +DSiBatteryLevel=15 +DSiBatteryCharging=1 +Camera0_InputType=0 +Camera0_ImagePath= +Camera0_CamDeviceName= +Camera0_XFlip=0 +Camera1_InputType=0 +Camera1_ImagePath= +Camera1_CamDeviceName= +Camera1_XFlip=0 diff --git a/projects/ArchR/packages/emulators/standalone/melonds-sa/config/SM8550 b/projects/ArchR/packages/emulators/standalone/melonds-sa/config/SM8550 new file mode 120000 index 0000000000..72081d3859 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/melonds-sa/config/SM8550 @@ -0,0 +1 @@ +InputPlumber \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/melonds-sa/config/SM8650 b/projects/ArchR/packages/emulators/standalone/melonds-sa/config/SM8650 new file mode 120000 index 0000000000..72081d3859 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/melonds-sa/config/SM8650 @@ -0,0 +1 @@ +InputPlumber \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/melonds-sa/config/melonDS.gptk b/projects/ArchR/packages/emulators/standalone/melonds-sa/config/melonDS.gptk new file mode 100644 index 0000000000..a9253ebf6a --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/melonds-sa/config/melonDS.gptk @@ -0,0 +1,31 @@ +back = \\ +start = \\ +a = \\ +b = \\ +x = \\ +y = \\ +l1 = \\ +l1_hk = l +l2 = \\ +l2_hk = m +l3 = \\ +r1 = \\ +r1_hk = s +r2 = \\ +r2_hk = f +r3 = mouse_left +up = \\ +down = \\ +left = \\ +right = \\ +left_analog_up = \\ +left_analog_down = \\ +left_analog_left = \\ +left_analog_right = \\ +right_analog_up = mouse_movement_up +right_analog_down = mouse_movement_down +right_analog_left = mouse_movement_left +right_analog_right = mouse_movement_right +deadzone_triggers = 3000 +mouse_scale = 6128 +mouse_delay = 16 diff --git a/projects/ArchR/packages/emulators/standalone/melonds-sa/package.mk b/projects/ArchR/packages/emulators/standalone/melonds-sa/package.mk new file mode 100644 index 0000000000..76c4073e69 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/melonds-sa/package.mk @@ -0,0 +1,101 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="melonds-sa" +PKG_VERSION="bdd85c9ccb40c0a3fcaa6103baf79c2d2d52d6ad" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/melonDS-emu/melonDS" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="SDL2 qt6 libslirp libepoxy libarchive ecm libpcap control-gen faad2" +PKG_LONGDESC="DS emulator, sorta. The goal is to do things right and fast" +PKG_TOOLCHAIN="cmake" + +if [ "${OPENGL_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" +fi + +if [ "${OPENGLES_SUPPORT}" = yes ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" +fi + +if [ "${DISPLAYSERVER}" = "wl" ]; then + PKG_DEPENDS_TARGET+=" wayland ${WINDOWMANAGER} xwayland xrandr libXi" +fi + +if [ "${VULKAN_SUPPORT}" = "yes" ] +then + PKG_DEPENDS_TARGET+=" ${VULKAN}" +fi + +get_graphicdrivers +if listcontains "${GRAPHIC_DRIVERS}" "(panfrost)"; then + GRAPHICS_DRIVER="panfrost" +fi + +pre_configure_target() { +export CFLAGS+=" -Wno-sign-compare" +export CXXFLAGS="${CXXFLAGS} -Wno-sign-compare" + +PKG_CMAKE_OPTS_TARGET+=" -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX="/usr" \ + -DUSE_QT6=ON \ + -DENABLE_RETROACHIEVEMENTS=ON \ + -DBUILD_SHARED_LIBS=OFF" + +mkdir -p ${PKG_BUILD}/src/frontend/qt_sdl/retroachievements/resources/sounds +mkdir -p ${PKG_BUILD}/src/frontend/qt_sdl/retroachievements/resources/icons +touch ${PKG_BUILD}/src/frontend/qt_sdl/retroachievements/resources/sounds/unlock.wav +cp -rf ${PKG_DIR}/resources/ra-icon.png ${PKG_BUILD}/src/frontend/qt_sdl/retroachievements/resources/icons/ra-icon.png +touch ${PKG_BUILD}/src/frontend/qt_sdl/retroachievements/resources/icons/placeholder.png +} + + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp -rf ${PKG_BUILD}/.${TARGET_NAME}/melonDS ${INSTALL}/usr/bin + + mkdir -p ${INSTALL}/usr/config/melonDS + cp -rf ${PKG_DIR}/config/${DEVICE}/* ${INSTALL}/usr/config/melonDS + cp -rf ${PKG_DIR}/config/melonDS.gptk ${INSTALL}/usr/config/melonDS + + cp -rf ${PKG_DIR}/scripts/* ${INSTALL}/usr/bin + chmod +x ${INSTALL}/usr/bin/* +} + +post_install() { + case ${GRAPHICS_DRIVER} in + panfrost) + PANFROST="export MESA_GL_VERSION_OVERRIDE=3.3" + ;; + *) + PANFROST="" + ;; + esac + sed -e "s/@PANFROST@/${PANFROST}/g" \ + -i ${INSTALL}/usr/bin/start_melonds.sh + + # Platform hotkeys + case ${DEVICE} in + RK3588|S922X|SM8*) + HOTKEY="export HOTKEY="guide"" + ;; + *) + HOTKEY="" + ;; + esac + + # Libmali check - force software renderer + case ${DEVICE} in + RK3588|S922X|RK3566) + LIBMALI="if [[ -x \"\/usr\/bin\/gpudriver\" ]] \&\& [[ \"\$\(\/usr\/bin\/gpudriver\)\" = \"libmali\" ]]; then sed -i '\/ScreenUseGL=\/c\\\ScreenUseGL=0' \/storage\/.config\/melonDS\/melonDS.ini; fi" + ;; + *) + LIBMALI="" + ;; + esac + + sed -e "s/@HOTKEY@/${HOTKEY}/g" \ + -i ${INSTALL}/usr/bin/start_melonds.sh + sed -e "s/@LIBMALI@/${LIBMALI}/g" \ + -i ${INSTALL}/usr/bin/start_melonds.sh +} diff --git a/projects/ArchR/packages/emulators/standalone/melonds-sa/patches/000-retro-achievements.patch b/projects/ArchR/packages/emulators/standalone/melonds-sa/patches/000-retro-achievements.patch new file mode 100644 index 0000000000..2856680c8f --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/melonds-sa/patches/000-retro-achievements.patch @@ -0,0 +1,42806 @@ +diff -rupbN melonDS.orig/src/CMakeLists.txt melonDS.ra/src/CMakeLists.txt +--- melonDS.orig/src/CMakeLists.txt 2026-03-06 21:36:14.522056951 +0000 ++++ melonDS.ra/src/CMakeLists.txt 2026-03-06 21:37:07.046799886 +0000 +@@ -226,6 +226,65 @@ if (ENABLE_JIT_PROFILING) + target_link_libraries(core PRIVATE "${VTUNE_LIBRARY}") + endif() + ++# --- RetroAchievements --- ++option(ENABLE_RETROACHIEVEMENTS "Enable RetroAchievements support" OFF) ++ ++if (ENABLE_RETROACHIEVEMENTS) ++ message(STATUS "RetroAchievements: ENABLED") ++ ++ if (WIN32) ++ target_compile_definitions(core PUBLIC RETROACHIEVEMENTS_ENABLED HAVE_CURL CURL_STATICLIB) ++ ++ set(CURL_DEPENDENCY_NAMES ++ curl nghttp2 nghttp3 ngtcp2 ssh2 psl ssl crypto brotlidec ++ brotlicommon brotlienc zstd idn2 unistring iconv z ++ ) ++ ++ set(CURL_FOUND_LIBS "") ++ foreach(LIB_NAME ${CURL_DEPENDENCY_NAMES}) ++ find_library(LIB_PATH_${LIB_NAME} NAMES ${LIB_NAME} REQUIRED) ++ if(LIB_PATH_${LIB_NAME}) ++ list(APPEND CURL_FOUND_LIBS ${LIB_PATH_${LIB_NAME}}) ++ endif() ++ endforeach() ++ ++ find_library(LIB_NGTCP2_CRYPTO NAMES ngtcp2_crypto_ossl ngtcp2_crypto_openssl) ++ if(LIB_NGTCP2_CRYPTO) ++ list(INSERT CURL_FOUND_LIBS 4 ${LIB_NGTCP2_CRYPTO}) ++ endif() ++ ++ target_link_libraries(core PRIVATE ++ ${CURL_FOUND_LIBS} ++ ws2_32 wldap32 crypt32 normaliz advapi32 secur32 bcrypt ++ ) ++ else() ++ find_package(CURL REQUIRED) ++ target_compile_definitions(core PUBLIC RETROACHIEVEMENTS_ENABLED HAVE_CURL) ++ target_link_libraries(core PRIVATE ${CURL_LIBRARIES}) ++ target_include_directories(core PRIVATE ${CURL_INCLUDE_DIRS}) ++ endif() ++ ++ target_include_directories(core PRIVATE ++ "${CMAKE_CURRENT_SOURCE_DIR}/RetroAchievements" ++ "${CMAKE_CURRENT_SOURCE_DIR}" ++ ) ++ ++ target_sources(core PRIVATE ++ RetroAchievements/RAClient.cpp ++ RetroAchievements/RAClient.h ++ ) ++ ++ file(GLOB_RECURSE RCH_ALL "${CMAKE_CURRENT_SOURCE_DIR}/rcheevos/src/*.c") ++ list(FILTER RCH_ALL EXCLUDE REGEX "rc_libretro.c|rc_client_external.c|rhash/aes.c") ++ target_sources(core PRIVATE ${RCH_ALL}) ++ target_include_directories(core PRIVATE ++ "${CMAKE_CURRENT_SOURCE_DIR}/rcheevos/include" ++ "${CMAKE_CURRENT_SOURCE_DIR}/rcheevos/src" ++ ) ++else() ++ message(STATUS "RetroAchievements: DISABLED (default)") ++endif() ++ + #if(CMAKE_BUILD_TYPE MATCHES "Debug") + # set( + # CMAKE_C_FLAGS +diff -rupbN melonDS.orig/src/NDS.cpp melonDS.ra/src/NDS.cpp +--- melonDS.orig/src/NDS.cpp 2026-03-06 21:36:14.530057064 +0000 ++++ melonDS.ra/src/NDS.cpp 2026-03-06 21:37:07.046799886 +0000 +@@ -44,6 +44,11 @@ + #include "DSi_DSP.h" + #include "ARMJIT.h" + #include "ARMJIT_Memory.h" ++#include ++ ++#ifdef RETROACHIEVEMENTS_ENABLED ++#include "RetroAchievements/RAClient.h" ++#endif + + namespace melonDS + { +@@ -539,6 +544,9 @@ void NDS::Reset() + SPI.Reset(); + RTC.Reset(); + Wifi.Reset(); ++ memset(MainRAM, 0, MainRAMMask + 1); ++ memset(SharedWRAM, 0, 0x8000); ++ memset(ARM7WRAM, 0, 0x10000); + } + + void NDS::Start() +@@ -761,6 +769,16 @@ bool NDS::DoSavestate(Savestate* file) + #endif + } + ++#ifdef RETROACHIEVEMENTS_ENABLED ++ if (ra) ++ { ++ if (file->Saving) ++ ra->SaveSavestate(file); ++ else ++ ra->LoadSavestate(file); ++ } ++#endif ++ + file->Finish(); + + return true; +@@ -772,6 +790,16 @@ void NDS::SetNDSCart(std::unique_ptrGetRAHash(); ++ if (h && h[0]) ++ ra->SetPendingGameHash(h); ++ } ++ } ++ #endif + } + + void NDS::SetNDSSave(const u8* savedata, u32 savelen) +@@ -918,6 +946,11 @@ void NDS::RunSystemSleep(u64 timestamp) + template + u32 NDS::RunFrame() + { ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ if (ra) { ++ ra->DoFrame(); ++ } ++ #endif + Current = this; + + FrameStartTimestamp = SysTimestamp; +@@ -1593,6 +1626,11 @@ void NDS::MonitorARM9Jump(u32 addr) + { + Log(LogLevel::Info, "Game is now booting\n"); + RunningGame = true; ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ if (ra) { ++ ra->AttachNDS(this); ++ } ++ #endif + } + } + } +diff -rupbN melonDS.orig/src/NDS.h melonDS.ra/src/NDS.h +--- melonDS.orig/src/NDS.h 2026-03-06 21:36:14.530057064 +0000 ++++ melonDS.ra/src/NDS.h 2026-03-06 21:37:07.046799886 +0000 +@@ -44,6 +44,9 @@ + #include "DMA.h" + #include "FreeBIOS.h" + ++#ifdef RETROACHIEVEMENTS_ENABLED ++#include "RetroAchievements/RAClient.h" ++#endif + // when touching the main loop/timing code, pls test a lot of shit + // with this enabled, to make sure it doesn't desync + //#define DEBUG_CHECK_DESYNC +@@ -248,6 +251,11 @@ private: + #endif + + public: // TODO: Encapsulate the rest of these members ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ RAContext* ra = nullptr; ++ void SetRAContext(RAContext* ctx) noexcept { ra = ctx; } ++ bool IsGameRunning() const { return RunningGame; } ++ #endif + void* UserData; + + int ConsoleType; +diff -rupbN melonDS.orig/src/NDSCart.cpp melonDS.ra/src/NDSCart.cpp +--- melonDS.orig/src/NDSCart.cpp 2026-03-06 21:36:14.530057064 +0000 ++++ melonDS.ra/src/NDSCart.cpp 2026-03-06 21:37:07.046799886 +0000 +@@ -27,6 +27,11 @@ + #include "FATStorage.h" + #include "Utils.h" + ++#ifdef RETROACHIEVEMENTS_ENABLED ++#include "RetroAchievements/RAClient.h" ++#include ++#endif ++ + namespace melonDS + { + using Platform::Log; +@@ -202,6 +207,25 @@ CartCommon::CartCommon(std::unique_ptr 0) ++ { ++ const bool ok = rc_hash_generate_from_buffer( ++ this->ra_hash, ++ RC_CONSOLE_NINTENDO_DS, ++ ROM.get(), ++ ROMLength ++ ); ++ ++ if (ok) ++ { ++ if (ra) ++ { ++ ra->SetPendingGameHash(this->ra_hash); ++ } ++ } ++ } ++ #endif + memcpy(&Header, ROM.get(), sizeof(Header)); + IsDSi = Header.IsDSi() && !badDSiDump; + DSiBase = Header.DSiRegionStart << 19; +diff -rupbN melonDS.orig/src/NDSCart.h melonDS.ra/src/NDSCart.h +--- melonDS.orig/src/NDSCart.h 2026-03-06 21:36:14.530057064 +0000 ++++ melonDS.ra/src/NDSCart.h 2026-03-06 21:37:07.046799886 +0000 +@@ -30,6 +30,10 @@ + #include "FATStorage.h" + #include "ROMList.h" + ++#ifdef RETROACHIEVEMENTS_ENABLED ++#include "RetroAchievements/RAClient.h" ++#endif ++ + namespace melonDS + { + class NDS; +@@ -76,6 +80,11 @@ struct NDSCartArgs + class CartCommon + { + public: ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ RAContext* ra = nullptr; ++ const char* GetRAHash() const { return ra_hash; } ++ char ra_hash[33] = {0}; ++ #endif + CartCommon(const u8* rom, u32 len, u32 chipid, bool badDSiDump, ROMListEntry romparams, CartType type, void* userdata); + CartCommon(std::unique_ptr&& rom, u32 len, u32 chipid, bool badDSiDump, ROMListEntry romparams, CartType type, void* userdata); + virtual ~CartCommon(); +diff -rupbN melonDS.orig/src/RetroAchievements/RAClient.cpp melonDS.ra/src/RetroAchievements/RAClient.cpp +--- melonDS.orig/src/RetroAchievements/RAClient.cpp 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/RetroAchievements/RAClient.cpp 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,1119 @@ ++#include "RAClient.h" ++#include "../NDS.h" ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "RetroAchievements/cacert.c" ++#include "version.h" ++#include "Savestate.h" ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++struct RAHttpJob { ++ std::string url; ++ std::string post_data; ++ rc_client_server_callback_t callback; ++ void* userdata; ++}; ++ ++struct RAPendingCallback { ++ rc_client_server_callback_t callback; ++ rc_api_server_response_t resp; ++ std::string body; ++ void* userdata; ++}; ++ ++static void PerformServerCall(const RAHttpJob& job); ++static void EnsureHTTPThread(); ++ ++static std::mutex s_httpMutex; ++static std::condition_variable s_httpCV; ++static std::queue s_httpJobs; ++ ++static std::mutex s_cbMutex; ++static std::queue s_pendingCallbacks; ++ ++static std::thread s_httpThread; ++static std::atomic s_httpRunning{false}; ++ ++static std::once_flag s_curlInitOnce; ++static thread_local CURL* s_curl = nullptr; ++static void EnsureCurlInit() ++{ ++ std::call_once(s_curlInitOnce, [] { ++ curl_global_init(CURL_GLOBAL_DEFAULT); ++ }); ++} ++static bool s_raOffline = false; ++static int s_pendingCount = 0; ++extern const unsigned char _accacert[]; ++extern const size_t _accacert_len; ++void RAContext::SetDisplayName(const char* name) ++{ ++ m_displayName = name ? name : ""; ++} ++ ++const std::string& RAContext::GetDisplayName() const ++{ ++ return m_displayName; ++} ++static uint64_t g_ra_mem_reads = 0; ++static uint64_t g_ra_mem_logged = 0; ++static size_t CurlWrite(void* ptr, size_t size, size_t nmemb, void* userdata) ++{ ++ std::string* s = static_cast(userdata); ++ s->append(static_cast(ptr), size * nmemb); ++ return size * nmemb; ++} ++bool RAContext::CanPause(uint32_t* frames_remaining) { ++ if (!client) return true; ++ return rc_client_can_pause(client, frames_remaining) != 0; ++} ++ ++void RAContext::SetPaused(bool paused) { ++ m_IsPaused = paused; ++} ++ ++RAContext::RAContext() : nds(nullptr), client(nullptr) ++{ ++} ++ ++RAContext::~RAContext() ++{ ++ Shutdown(); ++} ++ ++void RAContext::Init(melonDS::NDS* nds_) ++{ ++ EnsureCurlInit(); ++ nds = nds_; ++ client = rc_client_create( ++ &RAContext::ReadMemory, ++ &RAContext::ServerCall ++ ); ++ rc_client_set_userdata(client, this); ++ rc_client_set_allow_background_memory_reads(client, 1); ++ rc_runtime_init(&m_runtime); ++ rc_client_set_event_handler(client, ++ [](const rc_client_event_t* event, rc_client_t* client) ++ { ++ auto* ctx = static_cast(rc_client_get_userdata(client)); ++ if (!ctx) return; ++ switch (event->type) ++ { ++ case RC_CLIENT_EVENT_ACHIEVEMENT_TRIGGERED: ++ { ++ const rc_client_achievement_t* ach = (const rc_client_achievement_t*)event->achievement; ++ ++ for (auto& a : ctx->allAchievements) ++ { ++ if (a.id == ach->id) ++ { ++ a.unlocked = true; ++ a.measured = false; ++ a.state = ach->state; ++ break; ++ } ++ } ++ ++ if (ctx->m_onAchievementUnlocked) ++ ctx->m_onAchievementUnlocked( ++ ach->title, ++ ach->description, ++ ach->badge_url ++ ); ++ ctx->m_progressThrottle.erase(ach->id); ++ break; ++ } ++ case RC_CLIENT_EVENT_LEADERBOARD_STARTED: ++ { ++ printf("[RA][LB] START id=%u title=%s\n", ++ event->leaderboard->id, ++ event->leaderboard->title); ++ auto* ctx = static_cast(rc_client_get_userdata(client)); ++ if (ctx && ctx->onLeaderboardStarted) ++ ctx->onLeaderboardStarted(event->leaderboard); ++ break; ++ } ++ ++ case RC_CLIENT_EVENT_LEADERBOARD_FAILED: ++ { ++ printf("[RA][LB] FAILED id=%u\n", ++ event->leaderboard->id); ++ auto* ctx = static_cast(rc_client_get_userdata(client)); ++ if (ctx && ctx->onLeaderboardFailed) ++ ctx->onLeaderboardFailed(event->leaderboard); ++ break; ++ } ++ ++ case RC_CLIENT_EVENT_LEADERBOARD_SCOREBOARD: ++ { ++ auto* ctx = static_cast(rc_client_get_userdata(client)); ++ if (ctx && ctx->m_onLeaderboardSubmitted && event->leaderboard_scoreboard) { ++ bool isNewRecord = (strcmp(event->leaderboard_scoreboard->submitted_score, ++ event->leaderboard_scoreboard->best_score) == 0); ++ ++ const char* title = isNewRecord ? "New Personal Best!" : "Score Submitted"; ++ ++ ctx->m_onLeaderboardSubmitted( ++ title, ++ event->leaderboard_scoreboard->submitted_score, ++ event->leaderboard_scoreboard->new_rank ++ ); ++ } ++ break; ++ } ++ ++ case RC_CLIENT_EVENT_LEADERBOARD_SUBMITTED: ++ break; ++ case RC_CLIENT_EVENT_LEADERBOARD_TRACKER_SHOW: ++ { ++ if (event->leaderboard_tracker) { ++ ctx->activeTrackers[event->leaderboard_tracker->id] = { ++ event->leaderboard_tracker->id, ++ event->leaderboard_tracker->display ++ }; ++ } ++ break; ++ } ++ case RC_CLIENT_EVENT_LEADERBOARD_TRACKER_UPDATE: ++ { ++ if (event->leaderboard_tracker) { ++ auto it = ctx->activeTrackers.find(event->leaderboard_tracker->id); ++ if (it != ctx->activeTrackers.end()) { ++ it->second.display = event->leaderboard_tracker->display; ++ } ++ } ++ break; ++ } ++ case RC_CLIENT_EVENT_LEADERBOARD_TRACKER_HIDE: ++ { ++ if (event->leaderboard_tracker) { ++ ctx->activeTrackers.erase(event->leaderboard_tracker->id); ++ } ++ break; ++ } ++ case RC_CLIENT_EVENT_ACHIEVEMENT_CHALLENGE_INDICATOR_SHOW: ++ { ++ const rc_client_achievement_t* ach = (const rc_client_achievement_t*)event->achievement; ++ if (ach && ctx->m_onChallenge) { ++ ctx->m_onChallenge(ach->badge_name); ++ } ++ break; ++ } ++ case RC_CLIENT_EVENT_ACHIEVEMENT_CHALLENGE_INDICATOR_HIDE: ++ { ++ if (ctx->m_onChallengeHide) ++ ctx->m_onChallengeHide(); ++ break; ++ } ++ case RC_CLIENT_EVENT_GAME_COMPLETED: ++ { ++ RAContext* ctx = static_cast(rc_client_get_userdata(client)); ++ if (ctx && ctx->m_onGameMastered) ++ { ++ const rc_client_game_t* game = rc_client_get_game_info(client); ++ std::string gameTitle = (game && game->title) ? game->title : "Unknown Game"; ++ ++ char rp_buffer[256]; ++ rc_client_get_rich_presence_message(client, rp_buffer, sizeof(rp_buffer)); ++ ++ ctx->m_onGameMastered( ++ gameTitle, ++ rp_buffer ++ ); ++ } ++ break; ++ } ++ ++ case RC_CLIENT_EVENT_ACHIEVEMENT_PROGRESS_INDICATOR_SHOW: ++ { ++ if (ctx->m_suppressProgressFrames > 0) break; ++ ++ const rc_client_achievement_t* ach = (const rc_client_achievement_t*)event->achievement; ++ ++ if (ctx->m_onAchievementProgress && ctx->ShouldShowProgress(ach->id, (unsigned)ach->measured_percent, 100)) { ++ ctx->m_onAchievementProgress( ++ ach->title, ++ ach->measured_progress, ++ ach->badge_locked_url ? ach->badge_locked_url : ach->badge_url ++ ); ++ } ++ break; ++ } ++ ++ case RC_CLIENT_EVENT_ACHIEVEMENT_PROGRESS_INDICATOR_UPDATE: ++ { ++ if (ctx->m_suppressProgressFrames > 0) break; ++ ++ const rc_client_achievement_t* ach = (const rc_client_achievement_t*)event->achievement; ++ ++ if (ctx->m_onAchievementProgress && ctx->ShouldShowProgress(ach->id, (unsigned)ach->measured_percent, 100)) { ++ ctx->m_onAchievementProgress( ++ ach->title, ++ ach->measured_progress, ++ ach->badge_locked_url ? ach->badge_locked_url : ach->badge_url ++ ); ++ } ++ break; ++ } ++ ++ case RC_CLIENT_EVENT_ACHIEVEMENT_PROGRESS_INDICATOR_HIDE: ++ { ++ if (ctx->m_onChallengeHide) { ++ } ++ break; ++ } ++ default: ++ break; ++ } ++ }); ++} ++ ++void RAContext::Shutdown() ++{ ++ s_httpRunning = false; ++ s_httpCV.notify_all(); ++ if (s_httpThread.joinable()) ++ s_httpThread.join(); ++ m_onRADisconnected = nullptr; ++ m_onRAReconnected = nullptr; ++ m_onRAPendingSent = nullptr; ++ m_onLeaderboardSubmitted = nullptr; ++ m_onLeaderboardTrackerUpdate = nullptr; ++ m_onAchievementUnlocked = nullptr; ++ m_onAchievementProgress = nullptr; ++ m_onMeasuredProgress = nullptr; ++ m_onChallenge = nullptr; ++ m_onChallengeHide = nullptr; ++ m_onGameMastered = nullptr; ++ m_onLogin = nullptr; ++ onGameLoaded = nullptr; ++ SavePlaytime(); ++ if (client) { ++ rc_client_destroy(client); ++ client = nullptr; ++ } ++ rc_runtime_destroy(&m_runtime); ++ ResetGameState(); ++} ++ ++uint32_t RC_CCONV RuntimePeek(uint32_t address, uint32_t num_bytes, void* ud) ++{ ++ RAContext* ctx = static_cast(ud); ++ if (!ctx || !ctx->client) ++ return 0; ++ ++ uint8_t buffer[4] = {0}; ++ ++ ctx->ReadMemory(address, buffer, num_bytes, ctx->client); ++ ++ uint32_t value = 0; ++ memcpy(&value, buffer, num_bytes); ++ return value; ++} ++ ++void RAContext::DoFrame() ++{ ++ { ++ std::queue local; ++ ++ { ++ std::lock_guard lock(s_cbMutex); ++ std::swap(local, s_pendingCallbacks); ++ } ++ ++ while (!local.empty()) { ++ auto& cb = local.front(); ++ if (cb.callback) { ++ if (!cb.body.empty()) { ++ cb.resp.body = cb.body.c_str(); ++ cb.resp.body_length = (uint32_t)cb.body.size(); ++ } ++ cb.callback( ++ cb.resp.body ? &cb.resp : nullptr, ++ cb.userdata ++ ); ++ } ++ local.pop(); ++ } ++ } ++ if (!nds || !client || m_IsPaused) ++ return; ++ ++ std::string currentHash = pendingGameHash.value_or(""); ++ if (currentHash != m_lastHash) { ++ gameLoaded = false; ++ m_lastHash = currentHash; ++ pendingLoadFailed = false; ++ isLoading = false; ++ } ++ ++ if (pendingLoadFailed || isLoading) return; ++ ++ if (!gameLoaded && ++ pendingGameHash.has_value() && ++ nds->IsGameRunning()) ++ { ++ isLoading = true; ++ LoadGame(pendingGameHash->c_str()); ++ return; ++ } ++ ++ if (!gameLoaded) return; ++ ++ if (rc_client_is_processing_required(client) == 0) { ++ return; ++ } ++ ++ if (m_suppressProgressFrames > 0) ++ m_suppressProgressFrames--; ++ ++ rc_runtime_do_frame( ++ &m_runtime, ++ nullptr, ++ &RuntimePeek, ++ this, ++ nullptr ++ ); ++ ++ auto f0 = std::chrono::steady_clock::now(); ++ ++ rc_client_do_frame(client); ++ ++ auto f1 = std::chrono::steady_clock::now(); ++ auto fms = std::chrono::duration_cast(f1 - f0).count(); ++ ++ if (fms > 20) { ++ printf("[RA][FRAME] rc_client_do_frame blocked %lld ms\n", fms); ++ } ++ ++ if (m_onLeaderboardTrackerUpdate) { ++ if (activeTrackers.empty()) { ++ m_onLeaderboardTrackerUpdate(""); ++ } else { ++ std::string combinedDisplay = ""; ++ for (auto const& [id, tracker] : activeTrackers) { ++ if (!combinedDisplay.empty()) combinedDisplay += "\n"; ++ combinedDisplay += tracker.display; ++ } ++ m_onLeaderboardTrackerUpdate(combinedDisplay.c_str()); ++ } ++ } ++ ++ static int playtimeSaveCounter = 0; ++ if (gameLoaded && ++playtimeSaveCounter >= 3600) { ++ SavePlaytime(); ++ playtimeSaveCounter = 0; ++ } ++} ++ ++void RAContext::UpdateMeasuredAchievements() ++{ ++ if (!client || trackedAchievements.empty()) ++ return; ++ ++ char formatted[128]; ++ ++ for (auto& ach : trackedAchievements) ++ { ++ unsigned value = 0; ++ unsigned target = 0; ++ ++ bool isMeasured = rc_runtime_get_achievement_measured(&m_runtime, ach.id, &value, &target) != 0; ++ ++ if (!isMeasured) ++ continue; ++ ++ rc_runtime_format_achievement_measured(&m_runtime, ach.id, formatted, sizeof(formatted)); ++ ++ bool valueChanged = (value != ach.prev_value); ++ ++ if (valueChanged) { ++ ach.prev_value = value; ++ if (m_onMeasuredProgress && ShouldShowProgress(ach.id, value, target)) { ++ m_onMeasuredProgress(ach.id, value, target, formatted); ++ } ++ } ++ for (auto& full : allAchievements) ++ { ++ if (full.id == ach.id) ++ { ++ if (!full.measured || full.value != value || full.target != target) ++ { ++ full.measured = true; ++ full.value = value; ++ full.target = target; ++ full.progressText = formatted; ++ full.measured_percent = (target > 0) ++ ? (static_cast(value) / static_cast(target) * 100.0f) ++ : 0.0f; ++ } ++ break; ++ } ++ } ++ } ++} ++ ++void RAContext::SetLoggedIn(bool v) ++{ ++ if (m_logged_in == v) ++ return; ++ m_logged_in = v; ++ ++ if (m_onLogin) ++ m_onLogin(); ++} ++ ++void RAContext::SetEncoreMode(bool enabled) ++{ ++ if (client) { ++ rc_client_set_encore_mode_enabled(client, enabled ? 1 : 0); ++ } ++} ++ ++void RAContext::SetUnofficialEnabled(bool enabled) ++{ ++ if (client) { ++ rc_client_set_unofficial_enabled(client, enabled ? 1 : 0); ++ } ++} ++ ++static void LoginPasswordCallback(int result, const char* err, rc_client_t* client, void* userdata) ++{ ++ RAContext* ctx = static_cast(userdata); ++ if (result == RC_OK) ++ { ++ const rc_client_user_t* user_info = rc_client_get_user_info(client); ++ ctx->SetToken(user_info->token ? user_info->token : ""); ++ ctx->SetLoggedIn(true); ++ if (ctx->onLoginResponse) { ++ ctx->onLoginResponse(true, "Logged in Successfully!"); ++ } ++ } ++ else ++ { ++ ctx->loginSuccess = false; ++ ctx->loginErrorMessage = err ? err : "Unknown error"; ++ ctx->SetLoggedIn(false); ++ if (ctx->onLoginResponse) { ++ ctx->onLoginResponse(false, ctx->loginErrorMessage); ++ } ++ } ++} ++ ++void RAContext::LoadGame(const char* hash) ++{ ++ if (!client) return; ++ rc_client_begin_load_game( ++ client, ++ hash, ++ [](int result, const char* err, rc_client_t*, void* userdata) ++ { ++ auto* context = static_cast(userdata); ++ ++ if (result != RC_OK) ++ { ++ context->gameLoaded = false; ++ context->pendingLoadError = err ? err : "Unknown error"; ++ context->pendingLoadFailed = true; ++ context->isLoading = false; ++ ++ if (context->onGameLoaded) ++ context->onGameLoaded(); ++ ++ return; ++ } ++ ++ rc_runtime_reset(&context->m_runtime); ++ context->ResetGameState(); ++ context->trackedAchievements.clear(); ++ context->allAchievements.clear(); ++ context->pendingLoadFailed = false; ++ context->isLoading = false; ++ context->gameLoaded = true; ++ context->currentGameInfo = rc_client_get_game_info(context->client); ++ ++ if (context->currentGameInfo) { ++ context->m_currentGameId = context->currentGameInfo->id; ++ context->m_sessionStart = time(nullptr); ++ context->m_accumulatedTime = 0; ++ ++ if (context->m_playtimeLoader) { ++ context->m_accumulatedTime = context->m_playtimeLoader(context->m_currentGameId); ++ } ++ } ++ ++ rc_client_achievement_list_t* list = rc_client_create_achievement_list( ++ context->client, ++ RC_CLIENT_ACHIEVEMENT_CATEGORY_CORE_AND_UNOFFICIAL, ++ RC_CLIENT_ACHIEVEMENT_LIST_GROUPING_PROGRESS ++ ); ++ ++ for (uint32_t i = 0; i < list->num_buckets; ++i) { ++ const rc_client_achievement_bucket_t& bucket = list->buckets[i]; ++ ++ for (uint32_t j = 0; j < bucket.num_achievements; ++j) { ++ const rc_client_achievement_t* ach = bucket.achievements[j]; ++ ++ FullAchievement fa; ++ fa.id = ach->id; ++ fa.title = ach->title ? ach->title : ""; ++ fa.description = ach->description ? ach->description : ""; ++ fa.points = ach->points; ++ fa.unlocked = (ach->state == RC_CLIENT_ACHIEVEMENT_STATE_UNLOCKED); ++ ++ fa.measured = false; ++ fa.progressText.clear(); ++ fa.measured_percent = 0.0f; ++ fa.value = 0; ++ fa.target = 0; ++ ++ if (ach->type == RC_CLIENT_ACHIEVEMENT_TYPE_PROGRESSION || ++ ach->type == RC_CLIENT_ACHIEVEMENT_TYPE_STANDARD) ++ { ++ context->trackedAchievements.push_back({ ach->id, 0 }); ++ } ++ ++ fa.value = 0; ++ fa.target = 0; ++ ++ std::strncpy(fa.badge_name, ach->badge_name, sizeof(fa.badge_name)); ++ fa.unlock_time = ach->unlock_time; ++ fa.state = ach->state; ++ fa.category = ach->category; ++ fa.bucket = ach->bucket; ++ fa.rarity = ach->rarity; ++ fa.rarity_hardcore = ach->rarity_hardcore; ++ fa.type = ach->type; ++ fa.badge_url = ach->badge_url; ++ fa.badge_locked_url = ach->badge_locked_url; ++ ++ fa.bucket_type = bucket.bucket_type; ++ fa.label = bucket.label ? bucket.label : ""; ++ fa.num_achievements = bucket.num_achievements; ++ fa.achievements = bucket.achievements; ++ ++ context->allAchievements.push_back(fa); ++ } ++ } ++ ++ rc_client_destroy_achievement_list(list); ++ ++ context->m_suppressProgressFrames = 50; ++ ++ if (context->onGameLoaded) ++ context->onGameLoaded(); ++ }, ++ this ++ ); ++} ++ ++uint32_t RAContext::ReadMemory(uint32_t address, uint8_t* buffer, uint32_t size, rc_client_t* client) ++{ ++ g_ra_mem_reads++; ++ RAContext* ctx = static_cast(rc_client_get_userdata(client)); ++ ++ if (!ctx || !ctx->nds || !buffer || size == 0) ++ return 0; ++ ++ memset(buffer, 0, size); ++ ++ if (address < 0x00400000) ++ { ++ uint32_t count = std::min(size, 0x00400000 - address); ++ memcpy(buffer, ctx->nds->MainRAM + address, count); ++ return count; ++ } ++ ++ if (address >= 0x00400000 && address < 0x00408000) ++ { ++ uint32_t offset = address - 0x00400000; ++ uint32_t count = std::min(size, 0x00408000 - address); ++ memcpy(buffer, ctx->nds->SharedWRAM + offset, count); ++ return count; ++ } ++ ++ if (address >= 0x00408000 && address < 0x00418000) ++ { ++ uint32_t offset = address - 0x00408000; ++ uint32_t count = std::min(size, 0x00418000 - address); ++ memcpy(buffer, ctx->nds->ARM7WRAM + offset, count); ++ return count; ++ } ++ ++ if (address >= 0x00480000 && address < 0x00580000) ++ { ++ uint32_t offset = address - 0x00480000; ++ uint32_t remaining = std::min(size, 0x00580000 - address); ++ uint32_t copied = 0; ++ ++ struct { uint8_t* data; uint32_t size; } banks[] = { ++ {ctx->nds->GPU.VRAM_A, 128*1024}, ++ {ctx->nds->GPU.VRAM_B, 128*1024}, ++ {ctx->nds->GPU.VRAM_C, 128*1024}, ++ {ctx->nds->GPU.VRAM_D, 128*1024}, ++ {ctx->nds->GPU.VRAM_E, 64*1024}, ++ {ctx->nds->GPU.VRAM_F, 16*1024}, ++ {ctx->nds->GPU.VRAM_G, 16*1024}, ++ {ctx->nds->GPU.VRAM_H, 32*1024}, ++ {ctx->nds->GPU.VRAM_I, 16*1024} ++ }; ++ uint32_t bank_offset = 0; ++ ++ for (int i = 0; i < 9; ++i) { ++ if (offset >= bank_offset + banks[i].size) { ++ bank_offset += banks[i].size; ++ continue; ++ } ++ ++ uint32_t local_offset = offset - bank_offset; ++ uint32_t to_copy = std::min(remaining - copied, banks[i].size - local_offset); ++ memcpy(buffer + copied, banks[i].data + local_offset, to_copy); ++ copied += to_copy; ++ ++ if (copied >= remaining) break; ++ ++ bank_offset += banks[i].size; ++ } ++ ++ return copied; ++ } ++ ++ if (address >= 0x00600000 && address < 0x00602000) ++ { ++ uint32_t offset = address - 0x00600000; ++ uint32_t count = std::min(size, 0x00602000 - address); ++ uint32_t io_base = 0x04000000 + offset; ++ ++ for (uint32_t i = 0; i < count; ++i) { ++ buffer[i] = ctx->nds->ARM9Read8(io_base + i); ++ } ++ return count; ++ } ++ return 0; ++} ++ ++static curl_blob s_cacertBlob = { ++ (void*)_accacert, ++ _accacert_len, ++ CURL_BLOB_COPY ++}; ++ ++static std::set s_pendingAchiIDs; ++ ++void RAContext::ServerCall(const rc_api_request_t* request, ++ rc_client_server_callback_t callback, ++ void* userdata, ++ rc_client_t*) ++{ ++ EnsureHTTPThread(); ++ ++ RAHttpJob job; ++ job.url = request->url; ++ job.post_data = request->post_data ? request->post_data : ""; ++ job.callback = callback; ++ job.userdata = userdata; ++ ++ { ++ std::lock_guard lock(s_httpMutex); ++ s_httpJobs.push(std::move(job)); ++ } ++ ++ s_httpCV.notify_one(); ++} ++void RAContext::Reset() { ++ if (client) ++ rc_client_reset(client); ++ ResetGameState(); ++} ++ ++void RAContext::LoginWithPassword(const char* username, const char* password, bool hardcore) ++{ ++ if (!client) return; ++ ++ rc_client_set_hardcore_enabled(client, hardcore ? 1 : 0); ++ ++ rc_client_begin_login_with_password( ++ client, ++ username, ++ password, ++ &LoginPasswordCallback, ++ this ++ ); ++} ++void RAContext::SetCredentials(const char* user, const char* password, bool hardcore) { ++ m_user = user; ++ m_password = password; ++ m_hardcore = hardcore; ++} ++ ++void RAContext::SetPendingGameHash(const char* hash) ++{ ++ if (!hash || !*hash) ++ return; ++ ++ pendingGameHash = std::string(hash); ++ gameLoaded = false; ++} ++void RAContext::AttachNDS(melonDS::NDS* nds_) ++{ ++ if (nds == nds_) ++ return; ++ ++ nds = nds_; ++} ++ ++void RAContext::Enable() ++{ ++ if (m_enabled) ++ return; ++ ++ m_enabled = true; ++ ++ Init(nds); ++ ++ if (!IsLoggedIn()) ++ { ++ LoginNow(); ++ } ++} ++ ++void RAContext::Disable() ++{ ++ if (!m_enabled) ++ return; ++ ++ m_enabled = false; ++ ++ Shutdown(); ++ m_logged_in = false; ++ gameLoaded = false; ++ pendingGameHash.reset(); ++ ResetGameState(); ++} ++ ++void RAContext::LoginNow() ++{ ++ if (m_logged_in) ++ return; ++ ++ if (!m_user.empty() && !m_password.empty()) ++ { ++ LoginWithPassword(m_user.c_str(), m_password.c_str(), m_hardcore); ++ } ++} ++ ++void RAContext::SetOnAchievementUnlocked(AchievementUnlockedCallback cb) ++{ ++ m_onAchievementUnlocked = std::move(cb); ++} ++void RAContext::SetOnAchievementProgress(AchievementProgressCallback cb) ++{ ++ m_onAchievementProgress = std::move(cb); ++} ++ ++void RAContext::SetOnGameLoadedCallback(std::function cb) ++{ ++ onGameLoaded = std::move(cb); ++} ++void RAContext::SetOnMeasuredProgress(MeasuredProgressCallback cb) ++{ ++ m_onMeasuredProgress = std::move(cb); ++} ++void RAContext::ResetGameState() ++{ ++ trackedAchievements.clear(); ++ allAchievements.clear(); ++ activeTrackers.clear(); ++ m_sessionStart = 0; ++ m_accumulatedTime = 0; ++ m_currentGameId = 0; ++} ++void RAContext::showProgressIndicator(const rc_client_achievement_t* ach) ++{ ++ if (ach) { ++ printf("[RA] PROGRESS SHOW: %s (%s)\n", ach->title, ach->measured_progress); ++ } ++} ++ ++void RAContext::updateProgressIndicator(const rc_client_achievement_t* ach) ++{ ++ if (ach) { ++ printf("[RA] PROGRESS UPDATE: %s (%s)\n", ach->title, ach->measured_progress); ++ } ++} ++ ++void RAContext::hideProgressIndicator() ++{ ++ printf("[RA] PROGRESS HIDE\n"); ++} ++ ++void RAContext::SaveSavestate(melonDS::Savestate* file) ++{ ++ printf("wywołanie savesavestate"); ++ if (!client) ++ return; ++ ++ uint32_t size = rc_client_progress_size(client); ++ std::vector buffer(size); ++ ++ if (rc_client_serialize_progress(client, buffer.data()) != RC_OK) ++ return; ++ ++ file->Section("RACH"); ++ file->Var32(&size); ++ file->VarArray(buffer.data(), size); ++} ++ ++void RAContext::LoadSavestate(melonDS::Savestate* file) ++{ ++ printf("wywołanie loadsavestate"); ++ if (!client) ++ return; ++ ++ file->Section("RACH"); ++ ++ if (file->Error) ++ { ++ rc_client_deserialize_progress(client, nullptr); ++ return; ++ } ++ ++ uint32_t size = 0; ++ file->Var32(&size); ++ ++ std::vector buffer(size); ++ file->VarArray(buffer.data(), size); ++ ++ rc_client_deserialize_progress(client, buffer.data()); ++} ++void RAContext::SetOnChallenge(ChallengeShowCallback cb) ++{ ++ m_onChallenge = cb; ++} ++ ++void RAContext::SetOnChallengeHide(ChallengeHideCallback cb) ++{ ++ m_onChallengeHide = cb; ++} ++ ++void RAContext::SetOnGameMastered(GameMasteredCallback cb) ++{ ++ m_onGameMastered = cb; ++} ++const std::vector& RAContext::GetAllAchievements() ++{ ++ if (!client) return allAchievements; ++ ++ for (auto& ach : allAchievements) ++ { ++ const rc_client_achievement_t* rc_ach = rc_client_get_achievement_info(client, ach.id); ++ ++ if (rc_ach) ++ { ++ ach.unlocked = (rc_ach->unlocked != RC_CLIENT_ACHIEVEMENT_UNLOCKED_NONE); ++ ++ if (rc_ach->measured_progress[0] != '\0') ++ { ++ ach.measured = true; ++ ach.progressText = std::string(rc_ach->measured_progress); ++ ach.measured_percent = rc_ach->measured_percent; ++ } ++ else ++ { ++ ach.measured = false; ++ ach.measured_percent = 0.0f; ++ ach.progressText = ""; ++ } ++ } ++ } ++ ++ return allAchievements; ++} ++void RAContext::SavePlaytime() { ++ if (m_currentGameId == 0 || !gameLoaded) return; ++ ++ uint32_t totalMinutes = GetGamePlaytime(); ++ ++ if (m_playtimeSaver) { ++ m_playtimeSaver(m_currentGameId, totalMinutes); ++ } ++} ++bool RAContext::ShouldShowProgress(uint32_t id, unsigned value, unsigned target) { ++ if (target == 0) return false; ++ ++ auto nowObj = std::chrono::steady_clock::now(); ++ uint64_t now = std::chrono::duration_cast(nowObj.time_since_epoch()).count(); ++ ++ auto& s = m_progressThrottle[id]; ++ float percent = (static_cast(value) / static_cast(target)); ++ ++ if (now - s.rapidWindowStart > 3000) { ++ s.rapidWindowStart = now; ++ s.rapidChanges = 0; ++ } ++ if (value != s.lastValue) s.rapidChanges++; ++ ++ if (s.rapidChanges > 5) { ++ s.lastValue = value; ++ return false; ++ } ++ ++ float milestone = 0.0f; ++ if (percent >= 0.95f) milestone = 0.95f; ++ else if (percent >= 0.90f) milestone = 0.90f; ++ else if (percent >= 0.75f) milestone = 0.75f; ++ else if (percent >= 0.50f) milestone = 0.50f; ++ else if (percent >= 0.25f) milestone = 0.25f; ++ ++ if (milestone > s.lastPercent) { ++ s.lastPercent = milestone; ++ s.lastValue = value; ++ s.lastShownMs = now; ++ return true; ++ } ++ ++ return false; ++} ++std::vector RAContext::GetActiveTrackerTexts() { ++ std::vector texts; ++ for (auto const& [id, tracker] : activeTrackers) { ++ texts.push_back(tracker.display); ++ } ++ return texts; ++} ++void RAContext::SetOnLeaderboardTrackerUpdate(LeaderboardTrackerUpdateCallback cb) { ++ m_onLeaderboardTrackerUpdate = std::move(cb); ++} ++ ++void RAContext::SetOnLeaderboardSubmitted(LeaderboardSubmittedCallback cb) { ++ m_onLeaderboardSubmitted = std::move(cb); ++} ++void RAContext::SetOnRADisconnected(std::function cb) ++{ ++ m_onRADisconnected = std::move(cb); ++} ++ ++void RAContext::SetOnRAReconnected(std::function cb) ++{ ++ m_onRAReconnected = std::move(cb); ++} ++ ++void RAContext::SetOnRAPendingSent(RAPendingSentCallback cb) ++{ ++ m_onRAPendingSent = std::move(cb); ++} ++ ++static void PerformServerCall(const RAHttpJob& job) ++{ ++ EnsureCurlInit(); ++ ++ CURL* curl = curl_easy_init(); ++ if (!curl) { ++ return; ++ } ++ ++ curl_easy_setopt(curl, CURLOPT_CAINFO_BLOB, &s_cacertBlob); ++ curl_easy_setopt(curl, CURLOPT_URL, job.url.c_str()); ++ ++ if (!job.post_data.empty()) { ++ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, job.post_data.c_str()); ++ } ++ ++ std::string response_body; ++ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWrite); ++ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_body); ++ ++ curl_easy_setopt(curl, CURLOPT_TIMEOUT, 15L); ++ curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 5L); ++ ++ CURLcode res = curl_easy_perform(curl); ++ ++ if (res == CURLE_OK) { ++ long http_code = 0; ++ curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); ++ ++ RAPendingCallback cb; ++ cb.callback = job.callback; ++ cb.userdata = job.userdata; ++ cb.body = std::move(response_body); ++ cb.resp.http_status_code = (int)http_code; ++ // NOTE: resp.body and resp.body_length are set in DoFrame/ProcessAsyncCallbacks ++ // after dequeue, to avoid a dangling pointer after std::move(cb). ++ ++ { ++ std::lock_guard lock(s_cbMutex); ++ s_pendingCallbacks.push(std::move(cb)); ++ } ++ } ++ else { ++ RAPendingCallback cb; ++ cb.callback = job.callback; ++ cb.userdata = job.userdata; ++ cb.resp = {}; ++ { ++ std::lock_guard lock(s_cbMutex); ++ s_pendingCallbacks.push(std::move(cb)); ++ } ++ } ++ ++ curl_easy_cleanup(curl); ++} ++ ++static void EnsureHTTPThread() ++{ ++ if (s_httpRunning) ++ return; ++ ++ s_httpRunning = true; ++ s_httpThread = std::thread([] { ++ while (s_httpRunning) { ++ RAHttpJob job; ++ ++ { ++ std::unique_lock lock(s_httpMutex); ++ s_httpCV.wait(lock, [] { ++ return !s_httpJobs.empty() || !s_httpRunning; ++ }); ++ ++ if (!s_httpRunning) ++ return; ++ ++ job = std::move(s_httpJobs.front()); ++ s_httpJobs.pop(); ++ } ++ ++ PerformServerCall(job); ++ } ++ }); ++} ++ ++void RAContext::ProcessAsyncCallbacks() ++{ ++ std::lock_guard lock(s_cbMutex); ++ while (!s_pendingCallbacks.empty()) ++ { ++ RAPendingCallback cb = std::move(s_pendingCallbacks.front()); ++ s_pendingCallbacks.pop(); ++ ++ cb.resp.body = cb.body.empty() ? nullptr : cb.body.c_str(); ++ cb.resp.body_length = (uint32_t)cb.body.size(); ++ ++ if (cb.callback) { ++ cb.callback(&cb.resp, cb.userdata); ++ } ++ } ++} +diff -rupbN melonDS.orig/src/RetroAchievements/RAClient.h melonDS.ra/src/RetroAchievements/RAClient.h +--- melonDS.orig/src/RetroAchievements/RAClient.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/RetroAchievements/RAClient.h 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,250 @@ ++#pragma once ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++using AchievementUnlockedCallback = ++ std::function; ++using MeasuredProgressCallback = ++ std::function; ++using AchievementProgressCallback = ++ std::function; ++using ChallengeShowCallback = ++ std::function; ++using ChallengeHideCallback = ++ std::function; ++using LeaderboardTrackerUpdateCallback = ++ std::function; ++using LeaderboardSubmittedCallback = ++ std::function; ++using GameMasteredCallback = ++ std::function; ++using RADisconnectedCallback = std::function; ++using RAReconnectedCallback = std::function; ++using RAPendingSentCallback = std::function; ++using LoginCallback = std::function; ++using LeaderboardCallback = std::function; ++ ++struct TrackedAchievement ++{ ++ uint32_t id = 0; ++ unsigned prev_value = 0; ++}; ++namespace melonDS { ++ class NDS; ++ class Savestate; ++} ++class RAContext { ++public: ++ void ProcessAsyncCallbacks(); ++ using PlaytimeLoadHandler = std::function; ++ using PlaytimeSaveHandler = std::function; ++ ++ void SetPlaytimeHandlers(PlaytimeLoadHandler loader, PlaytimeSaveHandler saver) { ++ m_playtimeLoader = std::move(loader); ++ m_playtimeSaver = std::move(saver); ++ } ++ int m_suppressProgressFrames = 0; ++ void SaveSavestate(melonDS::Savestate* file); ++ void LoadSavestate(melonDS::Savestate* file); ++ ++ void showProgressIndicator(const rc_client_achievement_t* ach); ++ void updateProgressIndicator(const rc_client_achievement_t* ach); ++ void hideProgressIndicator(); ++ struct LeaderboardTracker { ++ uint32_t id; ++ std::string display; ++ }; ++ std::unordered_map activeTrackers; ++ friend uint32_t RC_CCONV RuntimePeek(uint32_t, uint32_t, void*); ++ struct FullAchievement ++ { ++ uint32_t id = 0; ++ std::string title; ++ std::string description; ++ uint32_t points = 0; ++ bool unlocked = false; ++ ++ bool measured = false; ++ int value = 0; ++ int target = 0; ++ std::string progressText; ++ ++ char badge_name[8] = {}; ++ float measured_percent = 0.0f; ++ time_t unlock_time = 0; ++ uint8_t state = 0; ++ uint8_t category = 0; ++ uint8_t bucket = 0; ++ float rarity = 0.0f; ++ float rarity_hardcore = 0.0f; ++ uint8_t type = 0; ++ const char* badge_url = nullptr; ++ const char* badge_locked_url = nullptr; ++ const rc_client_achievement_t** achievements = nullptr; ++ uint32_t num_achievements; ++ ++ const char* label; ++ uint32_t subset_id; ++ uint8_t bucket_type; ++ }; ++ ++ ++ const std::vector& GetAllAchievements(); ++ void ResetGameState(); ++ RAContext(); ++ ~RAContext(); ++ bool m_shuttingDown = false; ++ bool m_IsPaused = false; ++ bool CanPause(uint32_t* frames_remaining); ++ void SetPaused(bool paused); ++ std::function onLoginResponse; ++ bool pendingLoginResult = false; ++ bool loginSuccess = false; ++ std::string loginErrorMessage; ++ bool isLoading = false; ++ std::string m_lastHash; ++ std::string pendingLoadError; ++ bool pendingLoadFailed = false; ++ void SetOnGameLoadedCallback(std::function cb); ++ std::function onGameLoaded; ++ const rc_client_game_t* GetCurrentGameInfo() const { return currentGameInfo; } ++ bool IsGameLoaded() const { return gameLoaded; } ++ void SetOnAchievementUnlocked(AchievementUnlockedCallback cb); ++ void SetOnAchievementProgress(AchievementProgressCallback cb); ++ void SetOnChallenge(ChallengeShowCallback cb); ++ void SetOnChallengeHide(ChallengeHideCallback cb); ++ void SetOnLeaderboardTrackerUpdate(LeaderboardTrackerUpdateCallback cb); ++ void SetOnLeaderboardSubmitted(LeaderboardSubmittedCallback cb); ++ void SetOnRADisconnected(RADisconnectedCallback cb); ++ void SetOnRAReconnected(RAReconnectedCallback cb); ++ void SetOnRAPendingSent(RAPendingSentCallback cb); ++ void SetOnGameMastered(GameMasteredCallback cb); ++ void SetOnMeasuredProgress(MeasuredProgressCallback cb); ++ void SetOnLogin(LoginCallback cb); ++ void UpdateMeasuredAchievements(); ++ void LoginNow(); ++ void Enable(); ++ void Disable(); ++ bool IsEnabled() const { return m_enabled; } ++ bool IsHardcoreEnabled() const { return m_hardcore; } ++ void SetEncoreMode(bool enabled); ++ void SetUnofficialEnabled(bool enabled); ++ void AttachNDS(melonDS::NDS* nds_); ++ void SetPendingGameHash(const char* hash); ++ void SetToken(const std::string& token) { m_token = token; } ++ void SetLoggedIn(bool v); ++ void Init(melonDS::NDS* nds); ++ void Shutdown(); ++ void DoFrame(); ++ void LoginWithPassword(const char* username, const char* password, bool hardcore); ++ void SetCredentials(const char* user, const char* password, bool hardcore); ++ void LoadGame(const char* hash); ++ void Reset(); ++ bool IsLoggedIn() const { return m_logged_in; } ++ const std::string& GetUser() const { return m_user; } ++ const std::string& GetToken() const { return m_token; } ++ const std::string& GetDisplayName() const; ++ melonDS::NDS* nds = nullptr; ++ rc_client_t* client = nullptr; ++ bool m_logged_in = false; ++ const char* GetUserPicURL() const { ++ const rc_client_user_t* user = rc_client_get_user_info(client); ++ return (user) ? user->avatar_url : nullptr; ++ } ++ ++ const char* GetGameTitle() const { ++ const rc_client_game_t* game = rc_client_get_game_info(client); ++ return (game) ? game->title : "Unknown Game"; ++ } ++ ++ const char* GetGameIconURL() const { ++ const rc_client_game_t* game = rc_client_get_game_info(client); ++ return (game) ? game->badge_url : nullptr; ++ } ++ ++ uint32_t GetGameID() const { ++ const rc_client_game_t* game = rc_client_get_game_info(client); ++ return (game) ? game->id : 0; ++ } ++ uint32_t GetGamePlaytime() const { ++ if (!gameLoaded || m_sessionStart == 0) return m_accumulatedTime; ++ uint32_t sessionMinutes = (uint32_t)((time(nullptr) - m_sessionStart) / 60); ++ return m_accumulatedTime + sessionMinutes; ++ } ++ std::vector GetActiveTrackerTexts(); ++private: ++ void InitHTTPThread(); ++ struct ProgressThrottleState { ++ unsigned lastValue = 0; ++ float lastPercent = 0.0f; ++ uint64_t lastShownMs = 0; ++ int rapidChanges = 0; ++ uint64_t rapidWindowStart = 0; ++ }; ++ ++ std::unordered_map m_progressThrottle; ++ bool ShouldShowProgress(uint32_t id, unsigned value, unsigned target); ++ PlaytimeLoadHandler m_playtimeLoader; ++ PlaytimeSaveHandler m_playtimeSaver; ++ void SavePlaytime(); ++ time_t m_sessionStart = 0; ++ uint32_t m_accumulatedTime = 0; ++ uint32_t m_currentGameId = 0; ++ rc_runtime_t m_runtime; ++ std::vector trackedAchievements; ++ std::vector allAchievements; ++ void SetDisplayName(const char* name); ++ LeaderboardCallback onLeaderboardStarted; ++ LeaderboardCallback onLeaderboardFailed; ++ LeaderboardCallback onLeaderboardSubmitted; ++ AchievementUnlockedCallback m_onAchievementUnlocked; ++ MeasuredProgressCallback m_onMeasuredProgress; ++ AchievementProgressCallback m_onAchievementProgress; ++ ChallengeShowCallback m_onChallenge; ++ ChallengeHideCallback m_onChallengeHide; ++ LeaderboardTrackerUpdateCallback m_onLeaderboardTrackerUpdate; ++ LeaderboardSubmittedCallback m_onLeaderboardSubmitted; ++ GameMasteredCallback m_onGameMastered; ++ RADisconnectedCallback m_onRADisconnected; ++ RAReconnectedCallback m_onRAReconnected; ++ RAPendingSentCallback m_onRAPendingSent; ++ LoginCallback m_onLogin; ++ std::string m_displayName; ++ const rc_client_game_t* currentGameInfo = nullptr; ++ bool m_enabled = false; ++ std::optional pendingGameHash; ++ bool gameLoaded = false; ++ std::string m_user; ++ std::string m_token; ++ std::string m_password; ++ bool m_hardcore = false; ++ static uint32_t ReadMemory( ++ uint32_t address, ++ uint8_t* buffer, ++ uint32_t size, ++ rc_client_t* client ++ ); ++ static void ServerCall( ++ const rc_api_request_t* request, ++ rc_client_server_callback_t callback, ++ void* userdata, ++ rc_client_t* client ++ ); ++}; +\ No newline at end of file +diff -rupbN melonDS.orig/src/RetroAchievements/cacert.c melonDS.ra/src/RetroAchievements/cacert.c +--- melonDS.orig/src/RetroAchievements/cacert.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/RetroAchievements/cacert.c 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,5642 @@ ++/* ++ C-file generated by Bin2C ++ Compiled: Nov 20 2025 at 10:44:24 ++ ++ Copyright (C) 2018 ++ Segger Microcontroller GmbH ++ www.segger.com ++ ++ The Embedded Experts ++*/ ++ ++const unsigned char _accacert[225076UL + 1] = { ++ 0x23, 0x23, 0x0A, 0x23, 0x23, 0x20, 0x42, 0x75, 0x6E, 0x64, 0x6C, 0x65, 0x20, 0x6F, 0x66, 0x20, 0x43, 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x0A, 0x23, 0x23, 0x0A, ++ 0x23, 0x23, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x66, 0x72, 0x6F, 0x6D, 0x20, 0x4D, 0x6F, 0x7A, 0x69, 0x6C, 0x6C, 0x61, 0x20, 0x61, 0x73, 0x20, 0x6F, 0x66, 0x3A, 0x20, ++ 0x54, 0x75, 0x65, 0x20, 0x44, 0x65, 0x63, 0x20, 0x20, 0x32, 0x20, 0x30, 0x34, 0x3A, 0x31, 0x32, 0x3A, 0x30, 0x32, 0x20, 0x32, 0x30, 0x32, 0x35, 0x20, 0x47, 0x4D, 0x54, 0x0A, 0x23, 0x23, 0x0A, 0x23, 0x23, 0x20, 0x46, 0x69, 0x6E, 0x64, 0x20, ++ 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x73, 0x20, 0x68, 0x65, 0x72, 0x65, 0x3A, 0x20, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3A, 0x2F, 0x2F, 0x63, 0x75, 0x72, 0x6C, 0x2E, 0x73, 0x65, 0x2F, 0x64, ++ 0x6F, 0x63, 0x73, 0x2F, 0x63, 0x61, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2E, 0x68, 0x74, 0x6D, 0x6C, 0x0A, 0x23, 0x23, 0x0A, 0x23, 0x23, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x62, 0x75, 0x6E, 0x64, 0x6C, ++ 0x65, 0x20, 0x6F, 0x66, 0x20, 0x58, 0x2E, 0x35, 0x30, 0x39, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x20, 0x6F, 0x66, 0x20, 0x70, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, ++ 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x69, 0x65, 0x73, 0x0A, 0x23, 0x23, 0x20, 0x28, 0x43, 0x41, 0x29, 0x2E, 0x20, 0x54, 0x68, 0x65, 0x73, 0x65, 0x20, 0x77, 0x65, 0x72, 0x65, 0x20, 0x61, 0x75, ++ 0x74, 0x6F, 0x6D, 0x61, 0x74, 0x69, 0x63, 0x61, 0x6C, 0x6C, 0x79, 0x20, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6F, 0x6D, 0x20, 0x4D, 0x6F, 0x7A, 0x69, 0x6C, 0x6C, 0x61, 0x27, 0x73, 0x20, 0x72, 0x6F, 0x6F, ++ 0x74, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x0A, 0x23, 0x23, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x20, 0x28, 0x63, 0x65, 0x72, 0x74, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x74, 0x78, 0x74, 0x29, 0x2E, 0x20, 0x20, ++ 0x54, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x20, 0x63, 0x61, 0x6E, 0x20, 0x62, 0x65, 0x20, 0x66, 0x6F, 0x75, 0x6E, 0x64, 0x20, 0x69, 0x6E, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6D, 0x6F, 0x7A, 0x69, 0x6C, 0x6C, 0x61, 0x20, 0x73, 0x6F, ++ 0x75, 0x72, 0x63, 0x65, 0x20, 0x74, 0x72, 0x65, 0x65, 0x3A, 0x0A, 0x23, 0x23, 0x20, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3A, 0x2F, 0x2F, 0x72, 0x61, 0x77, 0x2E, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x75, 0x73, 0x65, 0x72, 0x63, 0x6F, 0x6E, 0x74, ++ 0x65, 0x6E, 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x6D, 0x6F, 0x7A, 0x69, 0x6C, 0x6C, 0x61, 0x2D, 0x66, 0x69, 0x72, 0x65, 0x66, 0x6F, 0x78, 0x2F, 0x66, 0x69, 0x72, 0x65, 0x66, 0x6F, 0x78, 0x2F, 0x72, 0x65, 0x66, 0x73, 0x2F, 0x68, 0x65, 0x61, ++ 0x64, 0x73, 0x2F, 0x72, 0x65, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x2F, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2F, 0x6E, 0x73, 0x73, 0x2F, 0x6C, 0x69, 0x62, 0x2F, 0x63, 0x6B, 0x66, 0x77, 0x2F, 0x62, 0x75, 0x69, 0x6C, 0x74, 0x69, 0x6E, ++ 0x73, 0x2F, 0x63, 0x65, 0x72, 0x74, 0x64, 0x61, 0x74, 0x61, 0x2E, 0x74, 0x78, 0x74, 0x0A, 0x23, 0x23, 0x0A, 0x23, 0x23, 0x20, 0x49, 0x74, 0x20, 0x63, 0x6F, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x65, 0x72, ++ 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x20, 0x69, 0x6E, 0x20, 0x50, 0x45, 0x4D, 0x20, 0x66, 0x6F, 0x72, 0x6D, 0x61, 0x74, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x66, 0x6F, 0x72, 0x65, 0x0A, 0x23, 0x23, ++ 0x20, 0x63, 0x61, 0x6E, 0x20, 0x62, 0x65, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6C, 0x79, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x63, 0x75, 0x72, 0x6C, 0x20, 0x2F, 0x20, 0x6C, 0x69, 0x62, 0x63, 0x75, 0x72, ++ 0x6C, 0x20, 0x2F, 0x20, 0x70, 0x68, 0x70, 0x5F, 0x63, 0x75, 0x72, 0x6C, 0x2C, 0x20, 0x6F, 0x72, 0x20, 0x77, 0x69, 0x74, 0x68, 0x0A, 0x23, 0x23, 0x20, 0x61, 0x6E, 0x20, 0x41, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2B, 0x6D, 0x6F, 0x64, 0x5F, 0x73, ++ 0x73, 0x6C, 0x20, 0x77, 0x65, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x53, 0x53, 0x4C, 0x20, 0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, ++ 0x6F, 0x6E, 0x2E, 0x0A, 0x23, 0x23, 0x20, 0x4A, 0x75, 0x73, 0x74, 0x20, 0x63, 0x6F, 0x6E, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x53, ++ 0x53, 0x4C, 0x43, 0x41, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6C, 0x65, 0x2E, 0x0A, 0x23, 0x23, 0x0A, 0x23, 0x23, 0x20, 0x43, 0x6F, 0x6E, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x20, 0x64, 0x6F, ++ 0x6E, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x6D, 0x6B, 0x2D, 0x63, 0x61, 0x2D, 0x62, 0x75, 0x6E, 0x64, 0x6C, 0x65, 0x2E, 0x70, 0x6C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x20, 0x31, 0x2E, 0x33, 0x30, 0x2E, 0x0A, 0x23, 0x23, ++ 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x3A, 0x20, 0x61, 0x39, 0x30, 0x33, 0x62, 0x33, 0x63, 0x64, 0x30, 0x35, 0x32, 0x33, 0x31, 0x65, 0x33, 0x39, 0x33, 0x33, 0x32, 0x35, 0x31, 0x35, 0x65, 0x66, 0x37, 0x65, 0x62, 0x65, 0x33, 0x37, 0x65, ++ 0x36, 0x39, 0x37, 0x32, 0x36, 0x32, 0x66, 0x33, 0x39, 0x35, 0x31, 0x35, 0x61, 0x35, 0x32, 0x30, 0x31, 0x35, 0x63, 0x32, 0x33, 0x63, 0x36, 0x32, 0x38, 0x30, 0x35, 0x62, 0x37, 0x33, 0x63, 0x64, 0x30, 0x0A, 0x23, 0x23, 0x0A, 0x0A, 0x0A, 0x45, ++ 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, ++ 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x45, 0x6B, 0x54, 0x43, 0x43, 0x41, 0x33, 0x6D, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, ++ 0x45, 0x52, 0x57, 0x74, 0x51, 0x56, 0x44, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x44, 0x43, 0x42, 0x73, 0x44, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, ++ 0x45, 0x42, 0x68, 0x4D, 0x43, 0x56, 0x56, 0x4D, 0x78, 0x46, 0x6A, 0x41, 0x55, 0x42, 0x67, 0x4E, 0x56, 0x0A, 0x42, 0x41, 0x6F, 0x54, 0x44, 0x55, 0x56, 0x75, 0x64, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x73, 0x49, 0x45, 0x6C, 0x75, 0x59, 0x79, ++ 0x34, 0x78, 0x4F, 0x54, 0x41, 0x33, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x73, 0x54, 0x4D, 0x48, 0x64, 0x33, 0x64, 0x79, 0x35, 0x6C, 0x62, 0x6E, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x4C, 0x6D, 0x35, 0x6C, 0x64, 0x43, 0x39, 0x44, 0x55, 0x46, ++ 0x4D, 0x67, 0x61, 0x58, 0x4D, 0x67, 0x61, 0x57, 0x35, 0x6A, 0x62, 0x33, 0x4A, 0x77, 0x0A, 0x62, 0x33, 0x4A, 0x68, 0x64, 0x47, 0x56, 0x6B, 0x49, 0x47, 0x4A, 0x35, 0x49, 0x48, 0x4A, 0x6C, 0x5A, 0x6D, 0x56, 0x79, 0x5A, 0x57, 0x35, 0x6A, 0x5A, ++ 0x54, 0x45, 0x66, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4D, 0x57, 0x4B, 0x47, 0x4D, 0x70, 0x49, 0x44, 0x49, 0x77, 0x4D, 0x44, 0x59, 0x67, 0x52, 0x57, 0x35, 0x30, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x43, 0x77, 0x67, 0x53, ++ 0x57, 0x35, 0x6A, 0x4C, 0x6A, 0x45, 0x74, 0x4D, 0x43, 0x73, 0x47, 0x0A, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x6B, 0x52, 0x57, 0x35, 0x30, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x43, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x6C, ++ 0x63, 0x6E, 0x52, 0x70, 0x5A, 0x6D, 0x6C, 0x6A, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52, 0x35, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x41, 0x32, 0x4D, 0x54, 0x45, 0x79, ++ 0x4E, 0x7A, 0x49, 0x77, 0x4D, 0x6A, 0x4D, 0x30, 0x0A, 0x4D, 0x6C, 0x6F, 0x58, 0x44, 0x54, 0x49, 0x32, 0x4D, 0x54, 0x45, 0x79, 0x4E, 0x7A, 0x49, 0x77, 0x4E, 0x54, 0x4D, 0x30, 0x4D, 0x6C, 0x6F, 0x77, 0x67, 0x62, 0x41, 0x78, 0x43, 0x7A, 0x41, ++ 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6C, 0x56, 0x54, 0x4D, 0x52, 0x59, 0x77, 0x46, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x77, 0x31, 0x46, 0x62, 0x6E, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x4C, 0x43, 0x42, ++ 0x4A, 0x62, 0x6D, 0x4D, 0x75, 0x0A, 0x4D, 0x54, 0x6B, 0x77, 0x4E, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, 0x45, 0x7A, 0x42, 0x33, 0x64, 0x33, 0x63, 0x75, 0x5A, 0x57, 0x35, 0x30, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x43, 0x35, 0x75, 0x5A, 0x58, ++ 0x51, 0x76, 0x51, 0x31, 0x42, 0x54, 0x49, 0x47, 0x6C, 0x7A, 0x49, 0x47, 0x6C, 0x75, 0x59, 0x32, 0x39, 0x79, 0x63, 0x47, 0x39, 0x79, 0x59, 0x58, 0x52, 0x6C, 0x5A, 0x43, 0x42, 0x69, 0x65, 0x53, 0x42, 0x79, 0x5A, 0x57, 0x5A, 0x6C, 0x63, 0x6D, ++ 0x56, 0x75, 0x0A, 0x59, 0x32, 0x55, 0x78, 0x48, 0x7A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x73, 0x54, 0x46, 0x69, 0x68, 0x6A, 0x4B, 0x53, 0x41, 0x79, 0x4D, 0x44, 0x41, 0x32, 0x49, 0x45, 0x56, 0x75, 0x64, 0x48, 0x4A, 0x31, 0x63, ++ 0x33, 0x51, 0x73, 0x49, 0x45, 0x6C, 0x75, 0x59, 0x79, 0x34, 0x78, 0x4C, 0x54, 0x41, 0x72, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x4A, 0x45, 0x56, 0x75, 0x64, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x0A, ++ 0x64, 0x43, 0x42, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x61, 0x57, 0x5A, 0x70, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x49, 0x45, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6D, 0x6C, 0x30, 0x65, 0x54, 0x43, 0x43, 0x41, 0x53, 0x49, 0x77, ++ 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x51, 0x6F, 0x43, 0x67, 0x67, 0x45, 0x42, 0x0A, 0x41, 0x4C, 0x61, ++ 0x56, 0x74, 0x6B, 0x4E, 0x43, 0x2B, 0x73, 0x5A, 0x74, 0x4B, 0x6D, 0x39, 0x49, 0x33, 0x35, 0x52, 0x4D, 0x4F, 0x56, 0x63, 0x46, 0x37, 0x73, 0x4E, 0x35, 0x45, 0x55, 0x46, 0x6F, 0x4E, 0x75, 0x33, 0x73, 0x2F, 0x70, 0x6F, 0x42, 0x6A, 0x36, 0x45, ++ 0x34, 0x4B, 0x50, 0x7A, 0x33, 0x45, 0x45, 0x5A, 0x6D, 0x4C, 0x6B, 0x30, 0x65, 0x47, 0x72, 0x45, 0x61, 0x54, 0x73, 0x62, 0x52, 0x77, 0x4A, 0x57, 0x49, 0x73, 0x4D, 0x6E, 0x2F, 0x4D, 0x59, 0x73, 0x7A, 0x0A, 0x41, 0x39, 0x75, 0x33, 0x67, 0x33, ++ 0x73, 0x2B, 0x49, 0x49, 0x52, 0x65, 0x37, 0x62, 0x4A, 0x57, 0x4B, 0x4B, 0x66, 0x34, 0x34, 0x4C, 0x6C, 0x41, 0x63, 0x54, 0x66, 0x46, 0x79, 0x30, 0x63, 0x4F, 0x6C, 0x79, 0x70, 0x6F, 0x77, 0x43, 0x4B, 0x56, 0x59, 0x68, 0x58, 0x62, 0x52, 0x39, ++ 0x6E, 0x31, 0x30, 0x43, 0x76, 0x2F, 0x67, 0x6B, 0x76, 0x4A, 0x72, 0x54, 0x37, 0x65, 0x54, 0x4E, 0x75, 0x51, 0x67, 0x46, 0x41, 0x2F, 0x43, 0x59, 0x71, 0x45, 0x41, 0x4F, 0x77, 0x77, 0x0A, 0x43, 0x6A, 0x30, 0x59, 0x7A, 0x66, 0x76, 0x39, 0x4B, ++ 0x6C, 0x6D, 0x61, 0x49, 0x35, 0x55, 0x58, 0x4C, 0x45, 0x57, 0x65, 0x48, 0x32, 0x35, 0x44, 0x65, 0x57, 0x30, 0x4D, 0x58, 0x4A, 0x6A, 0x2B, 0x53, 0x4B, 0x66, 0x46, 0x49, 0x30, 0x64, 0x63, 0x58, 0x76, 0x31, 0x75, 0x35, 0x78, 0x36, 0x30, 0x39, ++ 0x6D, 0x68, 0x46, 0x30, 0x59, 0x61, 0x44, 0x57, 0x36, 0x4B, 0x4B, 0x6A, 0x62, 0x48, 0x6A, 0x4B, 0x59, 0x44, 0x2B, 0x4A, 0x58, 0x47, 0x49, 0x72, 0x62, 0x36, 0x38, 0x0A, 0x6A, 0x36, 0x78, 0x53, 0x6C, 0x6B, 0x75, 0x71, 0x55, 0x59, 0x33, 0x6B, ++ 0x45, 0x7A, 0x45, 0x5A, 0x36, 0x45, 0x35, 0x4E, 0x6E, 0x39, 0x75, 0x73, 0x73, 0x32, 0x72, 0x56, 0x76, 0x44, 0x6C, 0x55, 0x63, 0x63, 0x70, 0x36, 0x65, 0x6E, 0x2B, 0x51, 0x33, 0x58, 0x30, 0x64, 0x67, 0x4E, 0x6D, 0x42, 0x75, 0x31, 0x6B, 0x6D, ++ 0x77, 0x68, 0x48, 0x2B, 0x35, 0x70, 0x50, 0x69, 0x39, 0x34, 0x44, 0x6B, 0x5A, 0x66, 0x73, 0x30, 0x4E, 0x77, 0x34, 0x70, 0x67, 0x48, 0x42, 0x4E, 0x0A, 0x72, 0x7A, 0x69, 0x47, 0x4C, 0x70, 0x35, 0x2F, 0x56, 0x36, 0x2B, 0x65, 0x46, 0x36, 0x37, ++ 0x72, 0x48, 0x4D, 0x73, 0x6F, 0x49, 0x56, 0x2B, 0x32, 0x48, 0x4E, 0x6A, 0x6E, 0x6F, 0x67, 0x51, 0x69, 0x2B, 0x64, 0x50, 0x61, 0x32, 0x4D, 0x73, 0x43, 0x41, 0x77, 0x45, 0x41, 0x41, 0x61, 0x4F, 0x42, 0x73, 0x44, 0x43, 0x42, 0x72, 0x54, 0x41, ++ 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x51, 0x59, 0x77, 0x0A, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, ++ 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x72, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x41, 0x45, 0x4A, 0x44, 0x41, 0x69, 0x67, 0x41, 0x38, 0x79, 0x4D, 0x44, 0x41, 0x32, 0x4D, 0x54, 0x45, 0x79, 0x4E, 0x7A, 0x49, 0x77, 0x4D, 0x6A, 0x4D, 0x30, 0x4D, 0x6C, ++ 0x71, 0x42, 0x44, 0x7A, 0x49, 0x77, 0x4D, 0x6A, 0x59, 0x78, 0x4D, 0x54, 0x49, 0x33, 0x4D, 0x6A, 0x41, 0x31, 0x0A, 0x4D, 0x7A, 0x51, 0x79, 0x57, 0x6A, 0x41, 0x66, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x53, 0x4D, 0x45, 0x47, 0x44, 0x41, 0x57, 0x67, ++ 0x42, 0x52, 0x6F, 0x6B, 0x4F, 0x52, 0x6E, 0x70, 0x4B, 0x5A, 0x54, 0x67, 0x4D, 0x65, 0x47, 0x5A, 0x71, 0x54, 0x78, 0x39, 0x30, 0x74, 0x44, 0x2B, 0x34, 0x53, 0x39, 0x62, 0x54, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, ++ 0x67, 0x51, 0x55, 0x61, 0x4A, 0x44, 0x6B, 0x5A, 0x36, 0x53, 0x6D, 0x55, 0x34, 0x44, 0x48, 0x0A, 0x68, 0x6D, 0x61, 0x6B, 0x38, 0x66, 0x64, 0x4C, 0x51, 0x2F, 0x75, 0x45, 0x76, 0x57, 0x30, 0x77, 0x48, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, ++ 0x68, 0x76, 0x5A, 0x39, 0x42, 0x30, 0x45, 0x41, 0x42, 0x42, 0x41, 0x77, 0x44, 0x68, 0x73, 0x49, 0x56, 0x6A, 0x63, 0x75, 0x4D, 0x54, 0x6F, 0x30, 0x4C, 0x6A, 0x41, 0x44, 0x41, 0x67, 0x53, 0x51, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, ++ 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x42, 0x51, 0x55, 0x41, 0x0A, 0x41, 0x34, 0x49, 0x42, 0x41, 0x51, 0x43, 0x54, 0x31, 0x44, 0x43, 0x77, 0x31, 0x77, 0x4D, 0x67, 0x4B, 0x74, 0x44, 0x35, 0x59, 0x2B, 0x69, 0x52, 0x44, 0x41, 0x55, ++ 0x67, 0x71, 0x56, 0x38, 0x5A, 0x79, 0x6E, 0x74, 0x79, 0x54, 0x74, 0x53, 0x78, 0x32, 0x39, 0x43, 0x57, 0x2B, 0x31, 0x52, 0x61, 0x47, 0x53, 0x77, 0x4D, 0x43, 0x50, 0x65, 0x79, 0x76, 0x49, 0x57, 0x6F, 0x6E, 0x58, 0x39, 0x74, 0x4F, 0x31, 0x4B, ++ 0x7A, 0x4B, 0x74, 0x76, 0x6E, 0x31, 0x49, 0x53, 0x4D, 0x0A, 0x59, 0x2F, 0x59, 0x50, 0x79, 0x79, 0x59, 0x42, 0x6B, 0x56, 0x42, 0x73, 0x39, 0x46, 0x38, 0x55, 0x34, 0x70, 0x4E, 0x30, 0x77, 0x42, 0x4F, 0x65, 0x4D, 0x44, 0x70, 0x51, 0x34, 0x37, ++ 0x52, 0x67, 0x78, 0x52, 0x7A, 0x77, 0x49, 0x6B, 0x53, 0x4E, 0x63, 0x55, 0x65, 0x73, 0x79, 0x42, 0x72, 0x4A, 0x36, 0x5A, 0x75, 0x61, 0x41, 0x47, 0x41, 0x54, 0x2F, 0x33, 0x42, 0x2B, 0x58, 0x78, 0x46, 0x4E, 0x53, 0x52, 0x75, 0x7A, 0x46, 0x56, ++ 0x4A, 0x37, 0x79, 0x56, 0x54, 0x61, 0x0A, 0x76, 0x35, 0x32, 0x56, 0x72, 0x32, 0x75, 0x61, 0x32, 0x4A, 0x37, 0x70, 0x38, 0x65, 0x52, 0x44, 0x6A, 0x65, 0x49, 0x52, 0x52, 0x44, 0x71, 0x2F, 0x72, 0x37, 0x32, 0x44, 0x51, 0x6E, 0x4E, 0x53, 0x69, ++ 0x36, 0x71, 0x37, 0x70, 0x79, 0x6E, 0x50, 0x39, 0x57, 0x51, 0x63, 0x43, 0x6B, 0x33, 0x52, 0x76, 0x4B, 0x71, 0x73, 0x6E, 0x79, 0x72, 0x51, 0x2F, 0x33, 0x39, 0x2F, 0x32, 0x6E, 0x33, 0x71, 0x73, 0x65, 0x30, 0x77, 0x4A, 0x63, 0x47, 0x45, 0x32, ++ 0x6A, 0x54, 0x53, 0x0A, 0x57, 0x33, 0x69, 0x44, 0x56, 0x75, 0x79, 0x63, 0x4E, 0x73, 0x4D, 0x6D, 0x34, 0x68, 0x48, 0x32, 0x5A, 0x30, 0x6B, 0x64, 0x6B, 0x71, 0x75, 0x4D, 0x2B, 0x2B, 0x76, 0x2F, 0x65, 0x75, 0x36, 0x46, 0x53, 0x71, 0x64, 0x51, ++ 0x67, 0x50, 0x43, 0x6E, 0x58, 0x45, 0x71, 0x55, 0x4C, 0x6C, 0x38, 0x46, 0x6D, 0x54, 0x78, 0x53, 0x51, 0x65, 0x44, 0x4E, 0x74, 0x47, 0x50, 0x50, 0x41, 0x55, 0x4F, 0x36, 0x6E, 0x49, 0x50, 0x63, 0x6A, 0x32, 0x41, 0x37, 0x38, 0x31, 0x71, 0x30, ++ 0x0A, 0x74, 0x48, 0x75, 0x75, 0x32, 0x67, 0x75, 0x51, 0x4F, 0x48, 0x58, 0x76, 0x67, 0x52, 0x31, 0x6D, 0x30, 0x76, 0x64, 0x58, 0x63, 0x44, 0x61, 0x7A, 0x76, 0x2F, 0x77, 0x6F, 0x72, 0x33, 0x45, 0x6C, 0x68, 0x56, 0x73, 0x54, 0x2F, 0x68, 0x35, ++ 0x2F, 0x57, 0x72, 0x51, 0x38, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, ++ 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, ++ 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x74, 0x7A, 0x43, 0x43, 0x41, 0x35, 0x2B, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x43, 0x42, ++ 0x51, 0x6B, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x46, 0x42, 0x51, 0x41, 0x77, 0x52, 0x54, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x51, ++ 0x6B, 0x30, 0x78, 0x47, 0x54, 0x41, 0x58, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x0A, 0x45, 0x46, 0x46, 0x31, 0x62, 0x31, 0x5A, 0x68, 0x5A, 0x47, 0x6C, 0x7A, 0x49, 0x45, 0x78, 0x70, 0x62, 0x57, 0x6C, 0x30, 0x5A, 0x57, 0x51, 0x78, ++ 0x47, 0x7A, 0x41, 0x5A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x45, 0x6C, 0x46, 0x31, 0x62, 0x31, 0x5A, 0x68, 0x5A, 0x47, 0x6C, 0x7A, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x4D, 0x6A, 0x41, 0x65, ++ 0x46, 0x77, 0x30, 0x77, 0x4E, 0x6A, 0x45, 0x78, 0x4D, 0x6A, 0x51, 0x78, 0x0A, 0x4F, 0x44, 0x49, 0x33, 0x4D, 0x44, 0x42, 0x61, 0x46, 0x77, 0x30, 0x7A, 0x4D, 0x54, 0x45, 0x78, 0x4D, 0x6A, 0x51, 0x78, 0x4F, 0x44, 0x49, 0x7A, 0x4D, 0x7A, 0x4E, ++ 0x61, 0x4D, 0x45, 0x55, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x4A, 0x4E, 0x4D, 0x52, 0x6B, 0x77, 0x46, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x78, 0x42, 0x52, 0x64, 0x57, 0x39, ++ 0x57, 0x59, 0x57, 0x52, 0x70, 0x63, 0x79, 0x42, 0x4D, 0x0A, 0x61, 0x57, 0x31, 0x70, 0x64, 0x47, 0x56, 0x6B, 0x4D, 0x52, 0x73, 0x77, 0x47, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x4A, 0x52, 0x64, 0x57, 0x39, 0x57, 0x59, 0x57, ++ 0x52, 0x70, 0x63, 0x79, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x49, 0x44, 0x49, 0x77, 0x67, 0x67, 0x49, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, ++ 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x0A, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x43, 0x61, 0x47, 0x4D, 0x70, 0x4C, 0x6C, 0x41, 0x30, 0x41, 0x4C, 0x61, 0x38, 0x44, 0x4B, 0x59, 0x72, 0x77, 0x44, ++ 0x34, 0x48, 0x49, 0x72, 0x6B, 0x77, 0x5A, 0x68, 0x52, 0x30, 0x49, 0x6E, 0x36, 0x73, 0x70, 0x52, 0x49, 0x58, 0x7A, 0x4C, 0x34, 0x47, 0x74, 0x4D, 0x68, 0x36, 0x51, 0x52, 0x72, 0x2B, 0x6A, 0x68, 0x69, 0x59, 0x61, 0x48, 0x76, 0x35, 0x2B, 0x48, ++ 0x42, 0x67, 0x36, 0x0A, 0x58, 0x4A, 0x78, 0x67, 0x46, 0x79, 0x6F, 0x36, 0x64, 0x49, 0x4D, 0x7A, 0x4D, 0x48, 0x31, 0x68, 0x56, 0x42, 0x48, 0x4C, 0x37, 0x61, 0x76, 0x67, 0x35, 0x74, 0x4B, 0x69, 0x66, 0x76, 0x56, 0x72, 0x62, 0x78, 0x69, 0x33, ++ 0x43, 0x67, 0x73, 0x74, 0x2F, 0x65, 0x6B, 0x2B, 0x37, 0x77, 0x72, 0x47, 0x73, 0x78, 0x44, 0x70, 0x33, 0x4D, 0x4A, 0x47, 0x46, 0x2F, 0x68, 0x64, 0x2F, 0x61, 0x54, 0x61, 0x2F, 0x35, 0x35, 0x4A, 0x57, 0x70, 0x7A, 0x6D, 0x4D, 0x2B, 0x59, 0x6B, ++ 0x0A, 0x6C, 0x76, 0x63, 0x2F, 0x75, 0x6C, 0x73, 0x72, 0x48, 0x48, 0x6F, 0x31, 0x77, 0x74, 0x5A, 0x6E, 0x2F, 0x71, 0x74, 0x6D, 0x55, 0x49, 0x74, 0x74, 0x4B, 0x47, 0x41, 0x72, 0x37, 0x39, 0x64, 0x67, 0x77, 0x38, 0x65, 0x54, 0x76, 0x49, 0x30, ++ 0x32, 0x6B, 0x66, 0x4E, 0x2F, 0x2B, 0x4E, 0x73, 0x52, 0x45, 0x38, 0x53, 0x63, 0x64, 0x33, 0x62, 0x42, 0x72, 0x72, 0x63, 0x43, 0x61, 0x6F, 0x46, 0x36, 0x71, 0x55, 0x57, 0x44, 0x34, 0x67, 0x58, 0x6D, 0x75, 0x56, 0x62, 0x42, 0x0A, 0x6C, 0x44, ++ 0x65, 0x50, 0x53, 0x48, 0x46, 0x6A, 0x49, 0x75, 0x77, 0x58, 0x5A, 0x51, 0x65, 0x56, 0x69, 0x6B, 0x76, 0x66, 0x6A, 0x38, 0x5A, 0x61, 0x43, 0x75, 0x57, 0x77, 0x34, 0x31, 0x39, 0x65, 0x61, 0x78, 0x47, 0x72, 0x44, 0x50, 0x6D, 0x46, 0x36, 0x30, ++ 0x54, 0x70, 0x2B, 0x41, 0x52, 0x7A, 0x38, 0x75, 0x6E, 0x2B, 0x58, 0x4A, 0x69, 0x4D, 0x39, 0x58, 0x4F, 0x76, 0x61, 0x37, 0x52, 0x2B, 0x7A, 0x64, 0x52, 0x63, 0x41, 0x69, 0x74, 0x4D, 0x4F, 0x65, 0x47, 0x79, 0x0A, 0x6C, 0x5A, 0x55, 0x74, 0x51, ++ 0x6F, 0x66, 0x58, 0x31, 0x62, 0x4F, 0x51, 0x51, 0x37, 0x64, 0x73, 0x45, 0x2F, 0x48, 0x65, 0x33, 0x66, 0x62, 0x45, 0x2B, 0x49, 0x6B, 0x2F, 0x30, 0x58, 0x58, 0x31, 0x6B, 0x73, 0x4F, 0x52, 0x31, 0x59, 0x71, 0x49, 0x30, 0x4A, 0x44, 0x73, 0x33, ++ 0x47, 0x33, 0x65, 0x69, 0x63, 0x4A, 0x6C, 0x63, 0x5A, 0x61, 0x4C, 0x44, 0x51, 0x50, 0x39, 0x6E, 0x4C, 0x39, 0x62, 0x46, 0x71, 0x79, 0x53, 0x32, 0x2B, 0x72, 0x2B, 0x65, 0x58, 0x79, 0x74, 0x0A, 0x36, 0x36, 0x2F, 0x33, 0x46, 0x73, 0x76, 0x62, ++ 0x7A, 0x53, 0x55, 0x72, 0x35, 0x52, 0x2F, 0x37, 0x6D, 0x70, 0x2F, 0x69, 0x55, 0x63, 0x77, 0x36, 0x55, 0x77, 0x78, 0x49, 0x35, 0x67, 0x36, 0x39, 0x79, 0x62, 0x52, 0x32, 0x42, 0x6C, 0x4C, 0x6D, 0x45, 0x52, 0x4F, 0x46, 0x63, 0x6D, 0x4D, 0x44, ++ 0x42, 0x4F, 0x41, 0x45, 0x4E, 0x69, 0x73, 0x67, 0x47, 0x51, 0x4C, 0x6F, 0x64, 0x4B, 0x63, 0x66, 0x74, 0x73, 0x6C, 0x57, 0x5A, 0x76, 0x42, 0x31, 0x4A, 0x64, 0x78, 0x6E, 0x0A, 0x77, 0x51, 0x35, 0x68, 0x59, 0x49, 0x69, 0x7A, 0x50, 0x74, 0x47, ++ 0x6F, 0x2F, 0x4B, 0x50, 0x61, 0x48, 0x62, 0x44, 0x52, 0x73, 0x53, 0x4E, 0x55, 0x33, 0x30, 0x52, 0x32, 0x62, 0x65, 0x31, 0x42, 0x32, 0x4D, 0x47, 0x79, 0x49, 0x72, 0x5A, 0x54, 0x48, 0x4E, 0x38, 0x31, 0x48, 0x64, 0x79, 0x68, 0x64, 0x79, 0x6F, ++ 0x78, 0x35, 0x43, 0x33, 0x31, 0x35, 0x65, 0x58, 0x62, 0x79, 0x4F, 0x44, 0x2F, 0x35, 0x59, 0x44, 0x58, 0x43, 0x32, 0x4F, 0x67, 0x2F, 0x7A, 0x4F, 0x68, 0x0A, 0x44, 0x37, 0x6F, 0x73, 0x46, 0x52, 0x58, 0x71, 0x6C, 0x37, 0x50, 0x53, 0x6F, 0x72, ++ 0x57, 0x2B, 0x38, 0x6F, 0x79, 0x57, 0x48, 0x68, 0x71, 0x50, 0x48, 0x57, 0x79, 0x6B, 0x59, 0x54, 0x65, 0x35, 0x68, 0x6E, 0x4D, 0x7A, 0x31, 0x35, 0x65, 0x57, 0x6E, 0x69, 0x4E, 0x39, 0x67, 0x71, 0x52, 0x4D, 0x67, 0x65, 0x4B, 0x68, 0x30, 0x62, ++ 0x70, 0x6E, 0x58, 0x35, 0x55, 0x48, 0x6F, 0x79, 0x63, 0x52, 0x37, 0x68, 0x59, 0x51, 0x65, 0x37, 0x78, 0x46, 0x53, 0x6B, 0x79, 0x79, 0x0A, 0x42, 0x4E, 0x4B, 0x72, 0x37, 0x39, 0x58, 0x39, 0x44, 0x46, 0x48, 0x4F, 0x55, 0x47, 0x6F, 0x49, 0x4D, ++ 0x66, 0x6D, 0x52, 0x32, 0x67, 0x79, 0x50, 0x5A, 0x46, 0x77, 0x44, 0x77, 0x7A, 0x71, 0x4C, 0x49, 0x44, 0x39, 0x75, 0x6A, 0x57, 0x63, 0x39, 0x4F, 0x74, 0x62, 0x2B, 0x66, 0x56, 0x75, 0x49, 0x79, 0x56, 0x37, 0x37, 0x7A, 0x47, 0x48, 0x63, 0x69, ++ 0x7A, 0x4E, 0x33, 0x30, 0x30, 0x51, 0x79, 0x4E, 0x51, 0x6C, 0x69, 0x42, 0x4A, 0x49, 0x57, 0x45, 0x4E, 0x69, 0x65, 0x0A, 0x4A, 0x30, 0x66, 0x37, 0x4F, 0x79, 0x48, 0x6A, 0x2B, 0x4F, 0x73, 0x64, 0x57, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, ++ 0x6F, 0x34, 0x47, 0x77, 0x4D, 0x49, 0x47, 0x74, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x43, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, ++ 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x0A, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x51, 0x61, 0x68, 0x47, 0x4B, 0x38, 0x53, 0x45, 0x77, 0x7A, 0x4A, 0x51, 0x54, 0x55, 0x37, 0x74, 0x44, ++ 0x32, 0x41, 0x38, 0x51, 0x5A, 0x52, 0x74, 0x47, 0x55, 0x61, 0x7A, 0x42, 0x75, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x53, 0x4D, 0x45, 0x5A, 0x7A, 0x42, 0x6C, 0x67, 0x42, 0x51, 0x61, 0x68, 0x47, 0x4B, 0x38, 0x53, 0x45, 0x77, 0x7A, 0x4A, 0x51, 0x54, ++ 0x55, 0x37, 0x74, 0x44, 0x32, 0x41, 0x38, 0x51, 0x5A, 0x52, 0x74, 0x47, 0x55, 0x0A, 0x61, 0x36, 0x46, 0x4A, 0x70, 0x45, 0x63, 0x77, 0x52, 0x54, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x51, 0x6B, ++ 0x30, 0x78, 0x47, 0x54, 0x41, 0x58, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x45, 0x46, 0x46, 0x31, 0x62, 0x31, 0x5A, 0x68, 0x5A, 0x47, 0x6C, 0x7A, 0x49, 0x45, 0x78, 0x70, 0x62, 0x57, 0x6C, 0x30, 0x5A, 0x57, 0x51, 0x78, 0x47, 0x7A, ++ 0x41, 0x5A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x0A, 0x45, 0x6C, 0x46, 0x31, 0x62, 0x31, 0x5A, 0x68, 0x5A, 0x47, 0x6C, 0x7A, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x4D, 0x6F, 0x49, 0x43, 0x42, ++ 0x51, 0x6B, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x46, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x42, 0x41, 0x44, 0x34, 0x4B, 0x46, 0x6B, 0x32, 0x66, 0x42, 0x6C, 0x75, 0x6F, 0x72, ++ 0x6E, 0x46, 0x64, 0x4C, 0x77, 0x55, 0x76, 0x0A, 0x5A, 0x2B, 0x59, 0x54, 0x52, 0x59, 0x50, 0x45, 0x4E, 0x76, 0x62, 0x7A, 0x77, 0x43, 0x59, 0x4D, 0x44, 0x62, 0x56, 0x48, 0x5A, 0x46, 0x33, 0x34, 0x74, 0x48, 0x4C, 0x4A, 0x52, 0x71, 0x55, 0x44, ++ 0x47, 0x43, 0x64, 0x56, 0x69, 0x58, 0x68, 0x39, 0x64, 0x75, 0x71, 0x57, 0x4E, 0x49, 0x41, 0x58, 0x49, 0x4E, 0x7A, 0x6E, 0x67, 0x2F, 0x69, 0x4E, 0x2F, 0x41, 0x65, 0x34, 0x32, 0x6C, 0x39, 0x4E, 0x4C, 0x6D, 0x65, 0x79, 0x68, 0x50, 0x33, 0x5A, ++ 0x52, 0x50, 0x78, 0x33, 0x0A, 0x55, 0x49, 0x48, 0x6D, 0x66, 0x4C, 0x54, 0x4A, 0x44, 0x51, 0x74, 0x79, 0x55, 0x2F, 0x68, 0x32, 0x42, 0x77, 0x64, 0x42, 0x52, 0x35, 0x59, 0x4D, 0x2B, 0x2B, 0x43, 0x43, 0x4A, 0x70, 0x4E, 0x56, 0x6A, 0x50, 0x34, ++ 0x69, 0x48, 0x32, 0x42, 0x6C, 0x66, 0x46, 0x2F, 0x6E, 0x4A, 0x72, 0x50, 0x33, 0x4D, 0x70, 0x43, 0x59, 0x55, 0x4E, 0x51, 0x33, 0x63, 0x56, 0x58, 0x32, 0x6B, 0x69, 0x46, 0x34, 0x39, 0x35, 0x56, 0x35, 0x2B, 0x76, 0x67, 0x74, 0x4A, 0x6F, 0x64, ++ 0x6D, 0x0A, 0x56, 0x6A, 0x42, 0x33, 0x70, 0x6A, 0x64, 0x34, 0x4D, 0x31, 0x49, 0x51, 0x57, 0x4B, 0x34, 0x2F, 0x59, 0x59, 0x37, 0x79, 0x61, 0x72, 0x48, 0x76, 0x47, 0x48, 0x35, 0x4B, 0x57, 0x57, 0x50, 0x4B, 0x6A, 0x61, 0x4A, 0x57, 0x31, 0x61, ++ 0x63, 0x76, 0x76, 0x46, 0x59, 0x66, 0x7A, 0x7A, 0x6E, 0x42, 0x34, 0x76, 0x73, 0x4B, 0x71, 0x42, 0x55, 0x73, 0x66, 0x55, 0x31, 0x36, 0x59, 0x38, 0x5A, 0x73, 0x6C, 0x30, 0x51, 0x38, 0x30, 0x6D, 0x2F, 0x44, 0x53, 0x68, 0x63, 0x4B, 0x0A, 0x2B, ++ 0x4A, 0x44, 0x53, 0x56, 0x36, 0x49, 0x5A, 0x55, 0x61, 0x55, 0x74, 0x6C, 0x30, 0x48, 0x61, 0x42, 0x30, 0x2B, 0x70, 0x55, 0x4E, 0x71, 0x51, 0x6A, 0x5A, 0x52, 0x47, 0x34, 0x54, 0x37, 0x77, 0x6C, 0x50, 0x30, 0x51, 0x41, 0x44, 0x6A, 0x31, 0x4F, ++ 0x2B, 0x68, 0x41, 0x34, 0x62, 0x52, 0x75, 0x56, 0x68, 0x6F, 0x67, 0x7A, 0x47, 0x39, 0x59, 0x6A, 0x65, 0x30, 0x75, 0x52, 0x59, 0x2F, 0x57, 0x36, 0x5A, 0x4D, 0x2F, 0x35, 0x37, 0x45, 0x73, 0x33, 0x7A, 0x72, 0x57, 0x0A, 0x49, 0x6F, 0x7A, 0x63, ++ 0x68, 0x4C, 0x73, 0x69, 0x62, 0x39, 0x44, 0x34, 0x35, 0x4D, 0x59, 0x35, 0x36, 0x51, 0x53, 0x49, 0x50, 0x4D, 0x4F, 0x36, 0x36, 0x31, 0x56, 0x36, 0x62, 0x59, 0x43, 0x5A, 0x4A, 0x50, 0x56, 0x73, 0x41, 0x66, 0x76, 0x34, 0x6C, 0x37, 0x43, 0x55, ++ 0x57, 0x2B, 0x76, 0x39, 0x30, 0x6D, 0x2F, 0x78, 0x64, 0x32, 0x67, 0x4E, 0x4E, 0x57, 0x51, 0x6A, 0x72, 0x4C, 0x68, 0x56, 0x6F, 0x51, 0x50, 0x52, 0x54, 0x55, 0x49, 0x5A, 0x33, 0x50, 0x68, 0x31, 0x0A, 0x57, 0x56, 0x61, 0x6A, 0x2B, 0x61, 0x68, ++ 0x4A, 0x65, 0x66, 0x69, 0x76, 0x44, 0x72, 0x6B, 0x52, 0x6F, 0x48, 0x79, 0x33, 0x61, 0x75, 0x30, 0x30, 0x30, 0x4C, 0x59, 0x6D, 0x59, 0x6A, 0x67, 0x61, 0x68, 0x77, 0x7A, 0x34, 0x36, 0x50, 0x30, 0x75, 0x30, 0x35, 0x42, 0x2F, 0x42, 0x35, 0x45, ++ 0x71, 0x48, 0x64, 0x5A, 0x2B, 0x58, 0x49, 0x57, 0x44, 0x6D, 0x62, 0x41, 0x34, 0x43, 0x44, 0x2F, 0x70, 0x58, 0x76, 0x6B, 0x31, 0x42, 0x2B, 0x54, 0x4A, 0x59, 0x6D, 0x35, 0x58, 0x0A, 0x66, 0x36, 0x64, 0x51, 0x6C, 0x66, 0x65, 0x36, 0x79, 0x4A, ++ 0x76, 0x6D, 0x6A, 0x71, 0x49, 0x42, 0x78, 0x64, 0x5A, 0x6D, 0x76, 0x33, 0x6C, 0x68, 0x38, 0x7A, 0x77, 0x63, 0x34, 0x62, 0x6D, 0x43, 0x58, 0x46, 0x32, 0x67, 0x77, 0x2B, 0x6E, 0x59, 0x53, 0x4C, 0x30, 0x5A, 0x6F, 0x68, 0x45, 0x55, 0x47, 0x57, ++ 0x36, 0x79, 0x68, 0x68, 0x74, 0x6F, 0x50, 0x6B, 0x67, 0x33, 0x47, 0x6F, 0x69, 0x33, 0x58, 0x5A, 0x5A, 0x65, 0x6E, 0x4D, 0x66, 0x76, 0x4A, 0x32, 0x49, 0x49, 0x0A, 0x34, 0x70, 0x45, 0x5A, 0x58, 0x4E, 0x4C, 0x78, 0x49, 0x64, 0x32, 0x36, 0x46, ++ 0x30, 0x4B, 0x43, 0x6C, 0x33, 0x47, 0x42, 0x55, 0x7A, 0x47, 0x70, 0x6E, 0x2F, 0x5A, 0x39, 0x59, 0x72, 0x39, 0x79, 0x34, 0x61, 0x4F, 0x54, 0x48, 0x63, 0x79, 0x4B, 0x4A, 0x6C, 0x6F, 0x4A, 0x4F, 0x4E, 0x44, 0x4F, 0x31, 0x77, 0x32, 0x41, 0x46, ++ 0x72, 0x52, 0x34, 0x70, 0x54, 0x71, 0x48, 0x54, 0x49, 0x32, 0x4B, 0x70, 0x64, 0x56, 0x47, 0x6C, 0x2F, 0x49, 0x73, 0x45, 0x4C, 0x6D, 0x38, 0x0A, 0x56, 0x43, 0x4C, 0x41, 0x41, 0x56, 0x42, 0x70, 0x51, 0x35, 0x37, 0x30, 0x73, 0x75, 0x39, 0x74, ++ 0x2B, 0x4F, 0x7A, 0x61, 0x38, 0x65, 0x4F, 0x78, 0x37, 0x39, 0x2B, 0x52, 0x6A, 0x31, 0x51, 0x71, 0x43, 0x79, 0x58, 0x42, 0x4A, 0x68, 0x6E, 0x45, 0x55, 0x68, 0x41, 0x46, 0x5A, 0x64, 0x57, 0x43, 0x45, 0x4F, 0x72, 0x43, 0x4D, 0x63, 0x30, 0x75, ++ 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x52, 0x6F, 0x6F, ++ 0x74, 0x20, 0x43, 0x41, 0x20, 0x33, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, ++ 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x47, 0x6E, 0x54, 0x43, 0x43, 0x42, 0x49, 0x57, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x43, 0x42, 0x63, 0x59, 0x77, 0x44, 0x51, ++ 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x46, 0x42, 0x51, 0x41, 0x77, 0x52, 0x54, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x51, 0x6B, 0x30, 0x78, 0x47, 0x54, ++ 0x41, 0x58, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x0A, 0x45, 0x46, 0x46, 0x31, 0x62, 0x31, 0x5A, 0x68, 0x5A, 0x47, 0x6C, 0x7A, 0x49, 0x45, 0x78, 0x70, 0x62, 0x57, 0x6C, 0x30, 0x5A, 0x57, 0x51, 0x78, 0x47, 0x7A, 0x41, 0x5A, 0x42, ++ 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x45, 0x6C, 0x46, 0x31, 0x62, 0x31, 0x5A, 0x68, 0x5A, 0x47, 0x6C, 0x7A, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x4D, 0x7A, 0x41, 0x65, 0x46, 0x77, 0x30, 0x77, 0x4E, ++ 0x6A, 0x45, 0x78, 0x4D, 0x6A, 0x51, 0x78, 0x0A, 0x4F, 0x54, 0x45, 0x78, 0x4D, 0x6A, 0x4E, 0x61, 0x46, 0x77, 0x30, 0x7A, 0x4D, 0x54, 0x45, 0x78, 0x4D, 0x6A, 0x51, 0x78, 0x4F, 0x54, 0x41, 0x32, 0x4E, 0x44, 0x52, 0x61, 0x4D, 0x45, 0x55, 0x78, ++ 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x4A, 0x4E, 0x4D, 0x52, 0x6B, 0x77, 0x46, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x78, 0x42, 0x52, 0x64, 0x57, 0x39, 0x57, 0x59, 0x57, 0x52, 0x70, ++ 0x63, 0x79, 0x42, 0x4D, 0x0A, 0x61, 0x57, 0x31, 0x70, 0x64, 0x47, 0x56, 0x6B, 0x4D, 0x52, 0x73, 0x77, 0x47, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x4A, 0x52, 0x64, 0x57, 0x39, 0x57, 0x59, 0x57, 0x52, 0x70, 0x63, 0x79, 0x42, ++ 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x49, 0x44, 0x4D, 0x77, 0x67, 0x67, 0x49, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, ++ 0x43, 0x0A, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x44, 0x4D, 0x56, 0x30, 0x49, 0x57, 0x56, 0x4A, 0x7A, 0x6D, 0x6D, 0x4E, 0x50, 0x54, 0x54, 0x65, 0x37, 0x2B, 0x37, 0x63, 0x65, 0x66, 0x51, 0x7A, ++ 0x6C, 0x4B, 0x5A, 0x62, 0x50, 0x6F, 0x46, 0x6F, 0x67, 0x30, 0x32, 0x77, 0x31, 0x5A, 0x6B, 0x58, 0x54, 0x50, 0x6B, 0x72, 0x67, 0x45, 0x51, 0x4B, 0x30, 0x43, 0x53, 0x7A, 0x47, 0x72, 0x76, 0x49, 0x32, 0x52, 0x61, 0x4E, 0x67, 0x67, 0x0A, 0x44, ++ 0x68, 0x6F, 0x42, 0x34, 0x68, 0x70, 0x37, 0x54, 0x68, 0x64, 0x64, 0x34, 0x6F, 0x71, 0x33, 0x50, 0x35, 0x6B, 0x61, 0x7A, 0x65, 0x74, 0x68, 0x71, 0x38, 0x4A, 0x6C, 0x70, 0x68, 0x2B, 0x33, 0x74, 0x37, 0x32, 0x33, 0x6A, 0x2F, 0x7A, 0x39, 0x63, ++ 0x49, 0x38, 0x4C, 0x6F, 0x47, 0x65, 0x2B, 0x41, 0x61, 0x4A, 0x5A, 0x7A, 0x33, 0x48, 0x6D, 0x44, 0x79, 0x6C, 0x32, 0x2F, 0x37, 0x46, 0x57, 0x65, 0x55, 0x55, 0x72, 0x48, 0x35, 0x35, 0x36, 0x56, 0x4F, 0x69, 0x6A, 0x0A, 0x4B, 0x54, 0x56, 0x6F, ++ 0x70, 0x41, 0x46, 0x50, 0x44, 0x36, 0x51, 0x75, 0x4E, 0x2B, 0x38, 0x62, 0x76, 0x2B, 0x4F, 0x50, 0x45, 0x4B, 0x68, 0x79, 0x71, 0x31, 0x68, 0x58, 0x35, 0x31, 0x53, 0x47, 0x79, 0x4D, 0x6E, 0x7A, 0x57, 0x39, 0x6F, 0x73, 0x32, 0x6C, 0x32, 0x4F, ++ 0x62, 0x6A, 0x79, 0x6A, 0x50, 0x74, 0x72, 0x37, 0x67, 0x75, 0x58, 0x64, 0x38, 0x6C, 0x79, 0x79, 0x42, 0x54, 0x4E, 0x76, 0x69, 0x6A, 0x62, 0x4F, 0x30, 0x42, 0x4E, 0x4F, 0x2F, 0x37, 0x39, 0x4B, 0x0A, 0x44, 0x44, 0x52, 0x4D, 0x70, 0x73, 0x4D, ++ 0x68, 0x76, 0x56, 0x41, 0x45, 0x56, 0x65, 0x75, 0x78, 0x75, 0x35, 0x33, 0x37, 0x52, 0x52, 0x35, 0x6B, 0x46, 0x64, 0x35, 0x56, 0x41, 0x59, 0x77, 0x43, 0x64, 0x72, 0x58, 0x4C, 0x6F, 0x54, 0x39, 0x43, 0x61, 0x62, 0x77, 0x76, 0x76, 0x57, 0x68, ++ 0x44, 0x46, 0x6C, 0x61, 0x4A, 0x4B, 0x6A, 0x64, 0x68, 0x6B, 0x66, 0x32, 0x6D, 0x72, 0x6B, 0x37, 0x41, 0x79, 0x78, 0x52, 0x6C, 0x6C, 0x44, 0x64, 0x4C, 0x6B, 0x67, 0x62, 0x76, 0x0A, 0x42, 0x4E, 0x44, 0x49, 0x6E, 0x49, 0x6A, 0x62, 0x43, 0x33, ++ 0x75, 0x42, 0x72, 0x37, 0x45, 0x39, 0x4B, 0x73, 0x52, 0x6C, 0x4F, 0x6E, 0x69, 0x32, 0x37, 0x74, 0x79, 0x41, 0x73, 0x64, 0x4C, 0x54, 0x6D, 0x5A, 0x77, 0x36, 0x37, 0x6D, 0x74, 0x61, 0x61, 0x37, 0x4F, 0x4E, 0x74, 0x39, 0x58, 0x4F, 0x6E, 0x4D, ++ 0x4B, 0x2B, 0x70, 0x55, 0x73, 0x76, 0x46, 0x72, 0x47, 0x65, 0x61, 0x44, 0x73, 0x47, 0x62, 0x36, 0x35, 0x39, 0x6E, 0x2F, 0x6A, 0x65, 0x37, 0x4D, 0x77, 0x70, 0x0A, 0x70, 0x35, 0x69, 0x6A, 0x4A, 0x55, 0x4D, 0x76, 0x37, 0x2F, 0x46, 0x66, 0x4A, ++ 0x75, 0x47, 0x49, 0x54, 0x66, 0x68, 0x65, 0x62, 0x74, 0x66, 0x5A, 0x46, 0x47, 0x34, 0x5A, 0x4D, 0x32, 0x6D, 0x6E, 0x4F, 0x34, 0x53, 0x4A, 0x6B, 0x38, 0x52, 0x54, 0x56, 0x52, 0x4F, 0x68, 0x55, 0x58, 0x68, 0x41, 0x2B, 0x4C, 0x6A, 0x4A, 0x6F, ++ 0x75, 0x35, 0x37, 0x75, 0x6C, 0x4A, 0x43, 0x67, 0x35, 0x34, 0x55, 0x37, 0x51, 0x56, 0x53, 0x57, 0x6C, 0x6C, 0x57, 0x70, 0x35, 0x66, 0x38, 0x0A, 0x6E, 0x54, 0x38, 0x4B, 0x4B, 0x64, 0x6A, 0x63, 0x54, 0x35, 0x45, 0x4F, 0x45, 0x37, 0x7A, 0x65, ++ 0x6C, 0x61, 0x54, 0x66, 0x69, 0x35, 0x6D, 0x2B, 0x72, 0x4A, 0x73, 0x7A, 0x69, 0x4F, 0x2B, 0x31, 0x67, 0x61, 0x38, 0x62, 0x78, 0x69, 0x4A, 0x54, 0x79, 0x50, 0x62, 0x48, 0x37, 0x70, 0x63, 0x55, 0x73, 0x4D, 0x56, 0x38, 0x65, 0x46, 0x4C, 0x49, ++ 0x38, 0x4D, 0x35, 0x75, 0x64, 0x32, 0x43, 0x45, 0x70, 0x75, 0x6B, 0x71, 0x64, 0x69, 0x44, 0x74, 0x57, 0x41, 0x45, 0x58, 0x0A, 0x4D, 0x4A, 0x50, 0x70, 0x47, 0x6F, 0x76, 0x67, 0x63, 0x32, 0x50, 0x5A, 0x61, 0x70, 0x4B, 0x55, 0x53, 0x55, 0x36, ++ 0x30, 0x72, 0x55, 0x71, 0x46, 0x78, 0x4B, 0x4D, 0x69, 0x4D, 0x50, 0x77, 0x4A, 0x37, 0x57, 0x67, 0x69, 0x63, 0x36, 0x61, 0x49, 0x44, 0x46, 0x55, 0x68, 0x57, 0x4D, 0x58, 0x68, 0x4F, 0x70, 0x38, 0x71, 0x33, 0x63, 0x72, 0x68, 0x6B, 0x4F, 0x44, ++ 0x5A, 0x63, 0x36, 0x74, 0x73, 0x67, 0x4C, 0x6A, 0x6F, 0x43, 0x32, 0x53, 0x54, 0x6F, 0x4A, 0x79, 0x4D, 0x0A, 0x47, 0x66, 0x2B, 0x7A, 0x30, 0x67, 0x7A, 0x73, 0x6B, 0x53, 0x61, 0x48, 0x69, 0x72, 0x4F, 0x69, 0x34, 0x58, 0x43, 0x50, 0x4C, 0x41, ++ 0x72, 0x6C, 0x7A, 0x57, 0x31, 0x6F, 0x55, 0x65, 0x76, 0x61, 0x50, 0x77, 0x56, 0x2F, 0x69, 0x7A, 0x4C, 0x6D, 0x45, 0x31, 0x78, 0x72, 0x2F, 0x6C, 0x39, 0x41, 0x34, 0x69, 0x4C, 0x49, 0x74, 0x4C, 0x52, 0x6B, 0x54, 0x39, 0x61, 0x36, 0x66, 0x55, ++ 0x67, 0x2B, 0x71, 0x47, 0x6B, 0x4D, 0x31, 0x37, 0x75, 0x47, 0x63, 0x63, 0x6C, 0x7A, 0x0A, 0x75, 0x44, 0x38, 0x37, 0x6E, 0x53, 0x56, 0x4C, 0x32, 0x76, 0x39, 0x41, 0x36, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6F, 0x34, 0x49, 0x42, 0x6C, ++ 0x54, 0x43, 0x43, 0x41, 0x5A, 0x45, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x43, 0x42, 0x34, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x67, 0x42, ++ 0x49, 0x48, 0x5A, 0x4D, 0x49, 0x48, 0x57, 0x4D, 0x49, 0x48, 0x54, 0x0A, 0x42, 0x67, 0x6B, 0x72, 0x42, 0x67, 0x45, 0x45, 0x41, 0x62, 0x35, 0x59, 0x41, 0x41, 0x4D, 0x77, 0x67, 0x63, 0x55, 0x77, 0x67, 0x5A, 0x4D, 0x47, 0x43, 0x43, 0x73, 0x47, ++ 0x41, 0x51, 0x55, 0x46, 0x42, 0x77, 0x49, 0x43, 0x4D, 0x49, 0x47, 0x47, 0x47, 0x6F, 0x47, 0x44, 0x51, 0x57, 0x35, 0x35, 0x49, 0x48, 0x56, 0x7A, 0x5A, 0x53, 0x42, 0x76, 0x5A, 0x69, 0x42, 0x30, 0x61, 0x47, 0x6C, 0x7A, 0x49, 0x45, 0x4E, 0x6C, ++ 0x63, 0x6E, 0x52, 0x70, 0x5A, 0x6D, 0x6C, 0x6A, 0x0A, 0x59, 0x58, 0x52, 0x6C, 0x49, 0x47, 0x4E, 0x76, 0x62, 0x6E, 0x4E, 0x30, 0x61, 0x58, 0x52, 0x31, 0x64, 0x47, 0x56, 0x7A, 0x49, 0x47, 0x46, 0x6A, 0x59, 0x32, 0x56, 0x77, 0x64, 0x47, 0x46, ++ 0x75, 0x59, 0x32, 0x55, 0x67, 0x62, 0x32, 0x59, 0x67, 0x64, 0x47, 0x68, 0x6C, 0x49, 0x46, 0x46, 0x31, 0x62, 0x31, 0x5A, 0x68, 0x5A, 0x47, 0x6C, 0x7A, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x4D, 0x79, 0x42, ++ 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x0A, 0x61, 0x57, 0x5A, 0x70, 0x59, 0x32, 0x46, 0x30, 0x5A, 0x53, 0x42, 0x51, 0x62, 0x32, 0x78, 0x70, 0x59, 0x33, 0x6B, 0x67, 0x4C, 0x79, 0x42, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x61, 0x57, 0x5A, 0x70, 0x59, 0x32, ++ 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x49, 0x46, 0x42, 0x79, 0x59, 0x57, 0x4E, 0x30, 0x61, 0x57, 0x4E, 0x6C, 0x49, 0x46, 0x4E, 0x30, 0x59, 0x58, 0x52, 0x6C, 0x62, 0x57, 0x56, 0x75, 0x64, 0x43, 0x34, 0x77, 0x4C, 0x51, 0x59, 0x49, 0x4B, 0x77, ++ 0x59, 0x42, 0x0A, 0x42, 0x51, 0x55, 0x48, 0x41, 0x67, 0x45, 0x57, 0x49, 0x57, 0x68, 0x30, 0x64, 0x48, 0x41, 0x36, 0x4C, 0x79, 0x39, 0x33, 0x64, 0x33, 0x63, 0x75, 0x63, 0x58, 0x56, 0x76, 0x64, 0x6D, 0x46, 0x6B, 0x61, 0x58, 0x4E, 0x6E, 0x62, ++ 0x47, 0x39, 0x69, 0x59, 0x57, 0x77, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4C, 0x32, 0x4E, 0x77, 0x63, 0x7A, 0x41, 0x4C, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x51, 0x59, 0x77, 0x48, 0x51, 0x59, 0x44, 0x0A, ++ 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x46, 0x50, 0x4C, 0x41, 0x45, 0x2B, 0x43, 0x43, 0x51, 0x7A, 0x37, 0x37, 0x37, 0x69, 0x39, 0x6E, 0x4D, 0x70, 0x59, 0x31, 0x58, 0x4E, 0x75, 0x34, 0x79, 0x77, 0x4C, 0x51, 0x4D, 0x47, 0x34, 0x47, ++ 0x41, 0x31, 0x55, 0x64, 0x49, 0x77, 0x52, 0x6E, 0x4D, 0x47, 0x57, 0x41, 0x46, 0x50, 0x4C, 0x41, 0x45, 0x2B, 0x43, 0x43, 0x51, 0x7A, 0x37, 0x37, 0x37, 0x69, 0x39, 0x6E, 0x4D, 0x70, 0x59, 0x31, 0x58, 0x4E, 0x75, 0x34, 0x0A, 0x79, 0x77, 0x4C, ++ 0x51, 0x6F, 0x55, 0x6D, 0x6B, 0x52, 0x7A, 0x42, 0x46, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x43, 0x54, 0x54, 0x45, 0x5A, 0x4D, 0x42, 0x63, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, ++ 0x51, 0x55, 0x58, 0x56, 0x76, 0x56, 0x6D, 0x46, 0x6B, 0x61, 0x58, 0x4D, 0x67, 0x54, 0x47, 0x6C, 0x74, 0x61, 0x58, 0x52, 0x6C, 0x5A, 0x44, 0x45, 0x62, 0x4D, 0x42, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0A, 0x41, 0x78, 0x4D, 0x53, 0x55, 0x58, ++ 0x56, 0x76, 0x56, 0x6D, 0x46, 0x6B, 0x61, 0x58, 0x4D, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x53, 0x41, 0x7A, 0x67, 0x67, 0x49, 0x46, 0x78, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, ++ 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x67, 0x45, 0x41, 0x54, 0x36, 0x32, 0x67, 0x4C, 0x45, 0x7A, 0x36, 0x77, 0x50, 0x4A, 0x76, 0x39, 0x32, 0x5A, 0x56, 0x0A, 0x71, 0x79, 0x4D, 0x30, 0x37, 0x75, 0x63, 0x70, 0x32, ++ 0x73, 0x4E, 0x62, 0x74, 0x72, 0x43, 0x44, 0x32, 0x64, 0x44, 0x51, 0x34, 0x69, 0x48, 0x37, 0x38, 0x32, 0x43, 0x6E, 0x4F, 0x31, 0x31, 0x67, 0x55, 0x79, 0x65, 0x69, 0x6D, 0x2F, 0x59, 0x49, 0x49, 0x69, 0x72, 0x6E, 0x76, 0x36, 0x42, 0x79, 0x35, ++ 0x5A, 0x77, 0x6B, 0x61, 0x6A, 0x47, 0x78, 0x6B, 0x48, 0x6F, 0x6E, 0x32, 0x34, 0x51, 0x52, 0x69, 0x53, 0x65, 0x6D, 0x64, 0x31, 0x6F, 0x34, 0x31, 0x37, 0x2B, 0x73, 0x0A, 0x68, 0x76, 0x7A, 0x75, 0x58, 0x59, 0x4F, 0x38, 0x42, 0x73, 0x62, 0x52, ++ 0x64, 0x32, 0x73, 0x50, 0x62, 0x53, 0x51, 0x76, 0x53, 0x33, 0x70, 0x73, 0x70, 0x77, 0x65, 0x57, 0x79, 0x75, 0x4F, 0x45, 0x6E, 0x36, 0x32, 0x49, 0x69, 0x78, 0x32, 0x72, 0x46, 0x6F, 0x31, 0x62, 0x5A, 0x68, 0x66, 0x5A, 0x46, 0x76, 0x53, 0x4C, ++ 0x67, 0x4E, 0x4C, 0x64, 0x2B, 0x4C, 0x4A, 0x32, 0x77, 0x2F, 0x77, 0x34, 0x45, 0x36, 0x6F, 0x4D, 0x33, 0x6B, 0x4A, 0x70, 0x4B, 0x32, 0x37, 0x7A, 0x0A, 0x50, 0x4F, 0x75, 0x41, 0x4A, 0x39, 0x76, 0x31, 0x70, 0x6B, 0x51, 0x4E, 0x6E, 0x31, 0x70, ++ 0x56, 0x57, 0x51, 0x76, 0x56, 0x44, 0x56, 0x4A, 0x49, 0x78, 0x61, 0x36, 0x66, 0x38, 0x69, 0x2B, 0x41, 0x78, 0x65, 0x6F, 0x79, 0x55, 0x44, 0x55, 0x53, 0x6C, 0x79, 0x37, 0x42, 0x34, 0x66, 0x2F, 0x78, 0x49, 0x34, 0x68, 0x52, 0x4F, 0x4A, 0x2F, ++ 0x79, 0x5A, 0x6C, 0x5A, 0x32, 0x35, 0x77, 0x39, 0x52, 0x6C, 0x36, 0x56, 0x53, 0x44, 0x45, 0x31, 0x4A, 0x55, 0x5A, 0x55, 0x32, 0x0A, 0x50, 0x62, 0x2B, 0x69, 0x53, 0x77, 0x77, 0x51, 0x48, 0x59, 0x61, 0x5A, 0x54, 0x4B, 0x72, 0x7A, 0x63, 0x68, ++ 0x47, 0x54, 0x35, 0x4F, 0x72, 0x32, 0x6D, 0x39, 0x71, 0x6F, 0x58, 0x61, 0x64, 0x4E, 0x74, 0x35, 0x34, 0x43, 0x72, 0x6E, 0x4D, 0x41, 0x79, 0x4E, 0x6F, 0x6A, 0x41, 0x2B, 0x6A, 0x35, 0x36, 0x68, 0x6C, 0x30, 0x59, 0x67, 0x43, 0x55, 0x79, 0x79, ++ 0x49, 0x67, 0x76, 0x70, 0x53, 0x6E, 0x57, 0x62, 0x57, 0x43, 0x61, 0x72, 0x36, 0x5A, 0x65, 0x58, 0x71, 0x70, 0x0A, 0x38, 0x6B, 0x6F, 0x6B, 0x55, 0x76, 0x64, 0x30, 0x2F, 0x62, 0x70, 0x4F, 0x35, 0x71, 0x67, 0x64, 0x41, 0x6D, 0x36, 0x78, 0x44, ++ 0x59, 0x42, 0x45, 0x77, 0x61, 0x37, 0x54, 0x49, 0x7A, 0x64, 0x66, 0x75, 0x34, 0x56, 0x38, 0x4B, 0x35, 0x49, 0x75, 0x36, 0x48, 0x36, 0x6C, 0x69, 0x39, 0x32, 0x5A, 0x34, 0x62, 0x38, 0x6E, 0x62, 0x79, 0x31, 0x64, 0x71, 0x6E, 0x75, 0x48, 0x2F, ++ 0x67, 0x72, 0x64, 0x53, 0x2F, 0x79, 0x4F, 0x39, 0x53, 0x62, 0x6B, 0x62, 0x6E, 0x42, 0x43, 0x0A, 0x62, 0x6A, 0x50, 0x73, 0x4D, 0x5A, 0x35, 0x37, 0x6B, 0x38, 0x48, 0x6B, 0x79, 0x57, 0x6B, 0x61, 0x50, 0x63, 0x42, 0x72, 0x54, 0x69, 0x4A, 0x74, ++ 0x37, 0x71, 0x74, 0x59, 0x54, 0x63, 0x62, 0x51, 0x51, 0x63, 0x45, 0x72, 0x36, 0x6B, 0x38, 0x53, 0x68, 0x31, 0x37, 0x72, 0x52, 0x64, 0x68, 0x73, 0x39, 0x5A, 0x67, 0x43, 0x30, 0x36, 0x44, 0x59, 0x56, 0x59, 0x6F, 0x47, 0x6D, 0x52, 0x6D, 0x69, ++ 0x6F, 0x48, 0x66, 0x52, 0x4D, 0x4A, 0x36, 0x73, 0x7A, 0x48, 0x58, 0x75, 0x0A, 0x67, 0x2F, 0x57, 0x77, 0x59, 0x6A, 0x6E, 0x50, 0x62, 0x46, 0x66, 0x69, 0x54, 0x4E, 0x4B, 0x52, 0x43, 0x77, 0x35, 0x31, 0x4B, 0x42, 0x75, 0x61, 0x76, 0x2F, 0x30, ++ 0x61, 0x51, 0x2F, 0x48, 0x4B, 0x64, 0x2F, 0x73, 0x37, 0x6A, 0x32, 0x47, 0x34, 0x61, 0x53, 0x67, 0x57, 0x51, 0x67, 0x52, 0x65, 0x63, 0x43, 0x6F, 0x63, 0x49, 0x64, 0x69, 0x50, 0x34, 0x62, 0x30, 0x6A, 0x57, 0x79, 0x31, 0x30, 0x51, 0x4A, 0x4C, ++ 0x5A, 0x59, 0x78, 0x6B, 0x4E, 0x63, 0x39, 0x31, 0x70, 0x0A, 0x76, 0x47, 0x4A, 0x48, 0x76, 0x4F, 0x42, 0x30, 0x4B, 0x37, 0x4C, 0x72, 0x66, 0x62, 0x35, 0x42, 0x47, 0x37, 0x58, 0x41, 0x52, 0x73, 0x57, 0x68, 0x49, 0x73, 0x74, 0x66, 0x54, 0x73, ++ 0x45, 0x6F, 0x6B, 0x74, 0x34, 0x59, 0x75, 0x74, 0x55, 0x71, 0x4B, 0x4C, 0x73, 0x52, 0x69, 0x78, 0x65, 0x54, 0x6D, 0x4A, 0x6C, 0x67, 0x6C, 0x46, 0x77, 0x6A, 0x7A, 0x31, 0x6F, 0x6E, 0x6C, 0x31, 0x34, 0x4C, 0x42, 0x51, 0x61, 0x54, 0x4E, 0x78, ++ 0x34, 0x37, 0x61, 0x54, 0x62, 0x72, 0x0A, 0x71, 0x5A, 0x35, 0x68, 0x48, 0x59, 0x38, 0x79, 0x32, 0x6F, 0x34, 0x4D, 0x31, 0x6E, 0x51, 0x2B, 0x65, 0x77, 0x6B, 0x6B, 0x32, 0x67, 0x46, 0x33, 0x52, 0x38, 0x51, 0x37, 0x7A, 0x54, 0x53, 0x4D, 0x6D, ++ 0x66, 0x58, 0x4B, 0x34, 0x53, 0x56, 0x68, 0x4D, 0x37, 0x4A, 0x5A, 0x47, 0x2B, 0x4A, 0x75, 0x31, 0x7A, 0x64, 0x58, 0x74, 0x67, 0x32, 0x70, 0x45, 0x74, 0x6F, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, ++ 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, ++ 0x43, 0x41, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, ++ 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x44, 0x74, 0x7A, 0x43, 0x43, 0x41, 0x70, 0x2B, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x44, ++ 0x4F, 0x66, 0x67, 0x35, 0x52, 0x66, 0x59, 0x52, 0x76, 0x36, 0x50, 0x35, 0x57, 0x44, 0x38, 0x47, 0x2F, 0x41, 0x77, 0x4F, 0x54, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, ++ 0x44, 0x42, 0x6C, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0A, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x56, 0x4D, 0x42, 0x4D, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x4D, 0x52, 0x47, 0x6C, 0x6E, ++ 0x61, 0x55, 0x4E, 0x6C, 0x63, 0x6E, 0x51, 0x67, 0x53, 0x57, 0x35, 0x6A, 0x4D, 0x52, 0x6B, 0x77, 0x46, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, 0x45, 0x78, 0x42, 0x33, 0x64, 0x33, 0x63, 0x75, 0x5A, 0x47, 0x6C, 0x6E, 0x61, 0x57, 0x4E, 0x6C, ++ 0x63, 0x6E, 0x51, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4D, 0x53, 0x51, 0x77, 0x0A, 0x49, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x74, 0x45, 0x61, 0x57, 0x64, 0x70, 0x51, 0x32, 0x56, 0x79, 0x64, 0x43, 0x42, 0x42, 0x63, 0x33, 0x4E, ++ 0x31, 0x63, 0x6D, 0x56, 0x6B, 0x49, 0x45, 0x6C, 0x45, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x44, 0x59, 0x78, 0x4D, 0x54, 0x45, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x41, ++ 0x77, 0x57, 0x68, 0x63, 0x4E, 0x4D, 0x7A, 0x45, 0x78, 0x0A, 0x4D, 0x54, 0x45, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x57, 0x6A, 0x42, 0x6C, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, ++ 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x56, 0x4D, 0x42, 0x4D, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x4D, 0x52, 0x47, 0x6C, 0x6E, 0x61, 0x55, 0x4E, 0x6C, 0x63, 0x6E, 0x51, 0x67, 0x53, 0x57, 0x35, 0x6A, 0x4D, 0x52, 0x6B, 0x77, 0x46, 0x77, ++ 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, 0x0A, 0x45, 0x78, 0x42, 0x33, 0x64, 0x33, 0x63, 0x75, 0x5A, 0x47, 0x6C, 0x6E, 0x61, 0x57, 0x4E, 0x6C, 0x63, 0x6E, 0x51, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4D, 0x53, 0x51, 0x77, 0x49, 0x67, 0x59, 0x44, 0x56, ++ 0x51, 0x51, 0x44, 0x45, 0x78, 0x74, 0x45, 0x61, 0x57, 0x64, 0x70, 0x51, 0x32, 0x56, 0x79, 0x64, 0x43, 0x42, 0x42, 0x63, 0x33, 0x4E, 0x31, 0x63, 0x6D, 0x56, 0x6B, 0x49, 0x45, 0x6C, 0x45, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, ++ 0x30, 0x45, 0x77, 0x0A, 0x67, 0x67, 0x45, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x45, 0x4B, ++ 0x41, 0x6F, 0x49, 0x42, 0x41, 0x51, 0x43, 0x74, 0x44, 0x68, 0x58, 0x4F, 0x35, 0x45, 0x4F, 0x41, 0x58, 0x4C, 0x47, 0x48, 0x38, 0x37, 0x64, 0x67, 0x2B, 0x58, 0x45, 0x53, 0x70, 0x61, 0x37, 0x63, 0x4A, 0x70, 0x53, 0x49, 0x71, 0x76, 0x54, 0x4F, ++ 0x0A, 0x39, 0x53, 0x41, 0x35, 0x4B, 0x46, 0x68, 0x67, 0x44, 0x50, 0x69, 0x41, 0x32, 0x71, 0x6B, 0x56, 0x6C, 0x54, 0x4A, 0x68, 0x50, 0x4C, 0x57, 0x78, 0x4B, 0x49, 0x53, 0x4B, 0x69, 0x74, 0x79, 0x66, 0x43, 0x67, 0x79, 0x44, 0x46, 0x33, 0x71, ++ 0x50, 0x6B, 0x4B, 0x79, 0x4B, 0x35, 0x33, 0x6C, 0x54, 0x58, 0x44, 0x47, 0x45, 0x4B, 0x76, 0x59, 0x50, 0x6D, 0x44, 0x49, 0x32, 0x64, 0x73, 0x7A, 0x65, 0x33, 0x54, 0x79, 0x6F, 0x6F, 0x75, 0x39, 0x71, 0x2B, 0x79, 0x48, 0x79, 0x0A, 0x55, 0x6D, ++ 0x48, 0x66, 0x6E, 0x79, 0x44, 0x58, 0x48, 0x2B, 0x4B, 0x78, 0x32, 0x66, 0x34, 0x59, 0x5A, 0x4E, 0x49, 0x53, 0x57, 0x31, 0x2F, 0x35, 0x57, 0x42, 0x67, 0x31, 0x76, 0x45, 0x66, 0x4E, 0x6F, 0x54, 0x62, 0x35, 0x61, 0x33, 0x2F, 0x55, 0x73, 0x44, ++ 0x67, 0x2B, 0x77, 0x52, 0x76, 0x44, 0x6A, 0x44, 0x50, 0x5A, 0x32, 0x43, 0x38, 0x59, 0x2F, 0x69, 0x67, 0x50, 0x73, 0x36, 0x65, 0x44, 0x31, 0x73, 0x4E, 0x75, 0x52, 0x4D, 0x42, 0x68, 0x4E, 0x5A, 0x59, 0x57, 0x0A, 0x2F, 0x6C, 0x6D, 0x63, 0x69, ++ 0x33, 0x5A, 0x74, 0x31, 0x2F, 0x47, 0x69, 0x53, 0x77, 0x30, 0x72, 0x2F, 0x77, 0x74, 0x79, 0x32, 0x70, 0x35, 0x67, 0x30, 0x49, 0x36, 0x51, 0x4E, 0x63, 0x5A, 0x34, 0x56, 0x59, 0x63, 0x67, 0x6F, 0x63, 0x2F, 0x6C, 0x62, 0x51, 0x72, 0x49, 0x53, ++ 0x58, 0x77, 0x78, 0x6D, 0x44, 0x4E, 0x73, 0x49, 0x75, 0x6D, 0x48, 0x30, 0x44, 0x4A, 0x61, 0x6F, 0x72, 0x6F, 0x54, 0x67, 0x68, 0x48, 0x74, 0x4F, 0x52, 0x65, 0x64, 0x6D, 0x54, 0x70, 0x79, 0x0A, 0x6F, 0x65, 0x62, 0x36, 0x70, 0x4E, 0x6E, 0x56, ++ 0x46, 0x7A, 0x46, 0x31, 0x72, 0x6F, 0x56, 0x39, 0x49, 0x71, 0x34, 0x2F, 0x41, 0x55, 0x61, 0x47, 0x39, 0x69, 0x68, 0x35, 0x79, 0x4C, 0x48, 0x61, 0x35, 0x46, 0x63, 0x58, 0x78, 0x48, 0x34, 0x63, 0x44, 0x72, 0x43, 0x30, 0x6B, 0x71, 0x5A, 0x57, ++ 0x73, 0x37, 0x32, 0x79, 0x6C, 0x2B, 0x32, 0x71, 0x70, 0x2F, 0x43, 0x33, 0x78, 0x61, 0x67, 0x2F, 0x6C, 0x52, 0x62, 0x51, 0x2F, 0x36, 0x47, 0x57, 0x36, 0x77, 0x68, 0x66, 0x0A, 0x47, 0x48, 0x64, 0x50, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, ++ 0x6A, 0x59, 0x7A, 0x42, 0x68, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x68, 0x6A, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, ++ 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x52, 0x46, 0x0A, 0x36, 0x36, 0x4B, 0x76, 0x39, 0x4A, 0x4C, 0x4C, 0x67, 0x6A, 0x45, 0x74, 0x55, 0x59, ++ 0x75, 0x6E, 0x70, 0x79, 0x47, 0x64, 0x38, 0x32, 0x33, 0x49, 0x44, 0x7A, 0x41, 0x66, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x53, 0x4D, 0x45, 0x47, 0x44, 0x41, 0x57, 0x67, 0x42, 0x52, 0x46, 0x36, 0x36, 0x4B, 0x76, 0x39, 0x4A, 0x4C, 0x4C, 0x67, 0x6A, ++ 0x45, 0x74, 0x55, 0x59, 0x75, 0x6E, 0x70, 0x79, 0x47, 0x64, 0x38, 0x32, 0x33, 0x49, 0x44, 0x7A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x0A, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, ++ 0x51, 0x45, 0x41, 0x6F, 0x67, 0x36, 0x38, 0x33, 0x2B, 0x4C, 0x74, 0x38, 0x4F, 0x4E, 0x79, 0x63, 0x33, 0x70, 0x6B, 0x6C, 0x4C, 0x2F, 0x33, 0x63, 0x6D, 0x62, 0x59, 0x4D, 0x75, 0x52, 0x43, 0x64, 0x57, 0x4B, 0x75, 0x68, 0x2B, 0x76, 0x79, 0x31, ++ 0x64, 0x6E, 0x65, 0x56, 0x72, 0x4F, 0x66, 0x7A, 0x4D, 0x34, 0x55, 0x4B, 0x4C, 0x6B, 0x4E, 0x6C, 0x32, 0x42, 0x63, 0x0A, 0x45, 0x6B, 0x78, 0x59, 0x35, 0x4E, 0x4D, 0x39, 0x67, 0x30, 0x6C, 0x46, 0x57, 0x4A, 0x63, 0x31, 0x61, 0x52, 0x71, 0x6F, ++ 0x52, 0x2B, 0x70, 0x57, 0x78, 0x6E, 0x6D, 0x72, 0x45, 0x74, 0x68, 0x6E, 0x67, 0x59, 0x54, 0x66, 0x66, 0x77, 0x6B, 0x38, 0x6C, 0x4F, 0x61, 0x34, 0x4A, 0x69, 0x77, 0x67, 0x76, 0x54, 0x32, 0x7A, 0x4B, 0x49, 0x6E, 0x33, 0x58, 0x2F, 0x38, 0x69, ++ 0x34, 0x70, 0x65, 0x45, 0x48, 0x2B, 0x6C, 0x6C, 0x37, 0x34, 0x66, 0x67, 0x33, 0x38, 0x46, 0x6E, 0x0A, 0x53, 0x62, 0x4E, 0x64, 0x36, 0x37, 0x49, 0x4A, 0x4B, 0x75, 0x73, 0x6D, 0x37, 0x58, 0x69, 0x2B, 0x66, 0x54, 0x38, 0x72, 0x38, 0x37, 0x63, ++ 0x6D, 0x4E, 0x57, 0x31, 0x66, 0x69, 0x51, 0x47, 0x32, 0x53, 0x56, 0x75, 0x66, 0x41, 0x51, 0x57, 0x62, 0x71, 0x7A, 0x30, 0x6C, 0x77, 0x63, 0x79, 0x32, 0x66, 0x38, 0x4C, 0x78, 0x62, 0x34, 0x62, 0x47, 0x2B, 0x6D, 0x52, 0x6F, 0x36, 0x34, 0x45, ++ 0x74, 0x6C, 0x4F, 0x74, 0x43, 0x74, 0x2F, 0x71, 0x4D, 0x48, 0x74, 0x31, 0x69, 0x0A, 0x38, 0x62, 0x35, 0x51, 0x5A, 0x37, 0x64, 0x73, 0x76, 0x66, 0x50, 0x78, 0x48, 0x32, 0x73, 0x4D, 0x4E, 0x67, 0x63, 0x57, 0x66, 0x7A, 0x64, 0x38, 0x71, 0x56, ++ 0x74, 0x74, 0x65, 0x76, 0x45, 0x53, 0x52, 0x6D, 0x43, 0x44, 0x31, 0x79, 0x63, 0x45, 0x76, 0x6B, 0x76, 0x4F, 0x6C, 0x37, 0x37, 0x44, 0x5A, 0x79, 0x70, 0x6F, 0x45, 0x64, 0x2B, 0x41, 0x35, 0x77, 0x77, 0x7A, 0x5A, 0x72, 0x38, 0x54, 0x44, 0x52, ++ 0x52, 0x75, 0x38, 0x33, 0x38, 0x66, 0x59, 0x78, 0x41, 0x65, 0x0A, 0x2B, 0x6F, 0x30, 0x62, 0x4A, 0x57, 0x31, 0x73, 0x6A, 0x36, 0x57, 0x33, 0x59, 0x51, 0x47, 0x78, 0x30, 0x71, 0x4D, 0x6D, 0x6F, 0x52, 0x42, 0x78, 0x6E, 0x61, 0x33, 0x69, 0x77, ++ 0x2F, 0x6E, 0x44, 0x6D, 0x56, 0x47, 0x33, 0x4B, 0x77, 0x63, 0x49, 0x7A, 0x69, 0x37, 0x6D, 0x55, 0x4C, 0x4B, 0x6E, 0x2B, 0x67, 0x70, 0x46, 0x4C, 0x36, 0x4C, 0x77, 0x38, 0x67, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, ++ 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, ++ 0x43, 0x41, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, ++ 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x44, 0x72, 0x7A, 0x43, 0x43, 0x41, 0x70, 0x65, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x43, 0x44, 0x76, 0x67, 0x56, ++ 0x70, 0x42, 0x43, 0x52, 0x72, 0x47, 0x68, 0x64, 0x57, 0x72, 0x4A, 0x57, 0x5A, 0x48, 0x48, 0x53, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x44, 0x42, 0x68, 0x4D, ++ 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0A, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x56, 0x4D, 0x42, 0x4D, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x4D, 0x52, 0x47, 0x6C, 0x6E, 0x61, 0x55, 0x4E, 0x6C, ++ 0x63, 0x6E, 0x51, 0x67, 0x53, 0x57, 0x35, 0x6A, 0x4D, 0x52, 0x6B, 0x77, 0x46, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, 0x45, 0x78, 0x42, 0x33, 0x64, 0x33, 0x63, 0x75, 0x5A, 0x47, 0x6C, 0x6E, 0x61, 0x57, 0x4E, 0x6C, 0x63, 0x6E, 0x51, 0x75, ++ 0x59, 0x32, 0x39, 0x74, 0x4D, 0x53, 0x41, 0x77, 0x0A, 0x48, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x64, 0x45, 0x61, 0x57, 0x64, 0x70, 0x51, 0x32, 0x56, 0x79, 0x64, 0x43, 0x42, 0x48, 0x62, 0x47, 0x39, 0x69, 0x59, 0x57, 0x77, ++ 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x54, 0x41, 0x65, 0x46, 0x77, 0x30, 0x77, 0x4E, 0x6A, 0x45, 0x78, 0x4D, 0x54, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x42, 0x61, 0x46, 0x77, 0x30, 0x7A, 0x4D, 0x54, 0x45, ++ 0x78, 0x4D, 0x54, 0x41, 0x77, 0x0A, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x42, 0x61, 0x4D, 0x47, 0x45, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6C, 0x56, 0x54, 0x4D, 0x52, 0x55, 0x77, 0x45, 0x77, ++ 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x77, 0x78, 0x45, 0x61, 0x57, 0x64, 0x70, 0x51, 0x32, 0x56, 0x79, 0x64, 0x43, 0x42, 0x4A, 0x62, 0x6D, 0x4D, 0x78, 0x47, 0x54, 0x41, 0x58, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x73, 0x54, 0x45, 0x48, ++ 0x64, 0x33, 0x0A, 0x64, 0x79, 0x35, 0x6B, 0x61, 0x57, 0x64, 0x70, 0x59, 0x32, 0x56, 0x79, 0x64, 0x43, 0x35, 0x6A, 0x62, 0x32, 0x30, 0x78, 0x49, 0x44, 0x41, 0x65, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x46, 0x30, 0x52, 0x70, 0x5A, ++ 0x32, 0x6C, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x49, 0x45, 0x64, 0x73, 0x62, 0x32, 0x4A, 0x68, 0x62, 0x43, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x4D, 0x49, 0x49, 0x42, 0x49, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x0A, ++ 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x51, 0x38, 0x41, 0x4D, 0x49, 0x49, 0x42, 0x43, 0x67, 0x4B, 0x43, 0x41, 0x51, 0x45, 0x41, 0x34, 0x6A, 0x76, 0x68, 0x45, 0x58, 0x4C, 0x65, ++ 0x71, 0x4B, 0x54, 0x54, 0x6F, 0x31, 0x65, 0x71, 0x55, 0x4B, 0x4B, 0x50, 0x43, 0x33, 0x65, 0x51, 0x79, 0x61, 0x4B, 0x6C, 0x37, 0x68, 0x4C, 0x4F, 0x6C, 0x6C, 0x73, 0x42, 0x43, 0x53, 0x44, 0x4D, 0x41, 0x5A, 0x4F, 0x6E, 0x0A, 0x54, 0x6A, 0x43, ++ 0x33, 0x55, 0x2F, 0x64, 0x44, 0x78, 0x47, 0x6B, 0x41, 0x56, 0x35, 0x33, 0x69, 0x6A, 0x53, 0x4C, 0x64, 0x68, 0x77, 0x5A, 0x41, 0x41, 0x49, 0x45, 0x4A, 0x7A, 0x73, 0x34, 0x62, 0x67, 0x37, 0x2F, 0x66, 0x7A, 0x54, 0x74, 0x78, 0x52, 0x75, 0x4C, ++ 0x57, 0x5A, 0x73, 0x63, 0x46, 0x73, 0x33, 0x59, 0x6E, 0x46, 0x6F, 0x39, 0x37, 0x6E, 0x68, 0x36, 0x56, 0x66, 0x65, 0x36, 0x33, 0x53, 0x4B, 0x4D, 0x49, 0x32, 0x74, 0x61, 0x76, 0x65, 0x67, 0x77, 0x35, 0x0A, 0x42, 0x6D, 0x56, 0x2F, 0x53, 0x6C, ++ 0x30, 0x66, 0x76, 0x42, 0x66, 0x34, 0x71, 0x37, 0x37, 0x75, 0x4B, 0x4E, 0x64, 0x30, 0x66, 0x33, 0x70, 0x34, 0x6D, 0x56, 0x6D, 0x46, 0x61, 0x47, 0x35, 0x63, 0x49, 0x7A, 0x4A, 0x4C, 0x76, 0x30, 0x37, 0x41, 0x36, 0x46, 0x70, 0x74, 0x34, 0x33, ++ 0x43, 0x2F, 0x64, 0x78, 0x43, 0x2F, 0x2F, 0x41, 0x48, 0x32, 0x68, 0x64, 0x6D, 0x6F, 0x52, 0x42, 0x42, 0x59, 0x4D, 0x71, 0x6C, 0x31, 0x47, 0x4E, 0x58, 0x52, 0x6F, 0x72, 0x35, 0x48, 0x0A, 0x34, 0x69, 0x64, 0x71, 0x39, 0x4A, 0x6F, 0x7A, 0x2B, ++ 0x45, 0x6B, 0x49, 0x59, 0x49, 0x76, 0x55, 0x58, 0x37, 0x51, 0x36, 0x68, 0x4C, 0x2B, 0x68, 0x71, 0x6B, 0x70, 0x4D, 0x66, 0x54, 0x37, 0x50, 0x54, 0x31, 0x39, 0x73, 0x64, 0x6C, 0x36, 0x67, 0x53, 0x7A, 0x65, 0x52, 0x6E, 0x74, 0x77, 0x69, 0x35, ++ 0x6D, 0x33, 0x4F, 0x46, 0x42, 0x71, 0x4F, 0x61, 0x73, 0x76, 0x2B, 0x7A, 0x62, 0x4D, 0x55, 0x5A, 0x42, 0x66, 0x48, 0x57, 0x79, 0x6D, 0x65, 0x4D, 0x72, 0x2F, 0x79, 0x0A, 0x37, 0x76, 0x72, 0x54, 0x43, 0x30, 0x4C, 0x55, 0x71, 0x37, 0x64, 0x42, ++ 0x4D, 0x74, 0x6F, 0x4D, 0x31, 0x4F, 0x2F, 0x34, 0x67, 0x64, 0x57, 0x37, 0x6A, 0x56, 0x67, 0x2F, 0x74, 0x52, 0x76, 0x6F, 0x53, 0x53, 0x69, 0x69, 0x63, 0x4E, 0x6F, 0x78, 0x42, 0x4E, 0x33, 0x33, 0x73, 0x68, 0x62, 0x79, 0x54, 0x41, 0x70, 0x4F, ++ 0x42, 0x36, 0x6A, 0x74, 0x53, 0x6A, 0x31, 0x65, 0x74, 0x58, 0x2B, 0x6A, 0x6B, 0x4D, 0x4F, 0x76, 0x4A, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x0A, 0x6F, 0x32, 0x4D, 0x77, 0x59, 0x54, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, ++ 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x59, 0x59, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x64, 0x42, 0x67, 0x4E, ++ 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x41, 0x39, 0x35, 0x51, 0x4E, 0x56, 0x62, 0x52, 0x54, 0x4C, 0x74, 0x6D, 0x0A, 0x38, 0x4B, 0x50, 0x69, 0x47, 0x78, 0x76, 0x44, 0x6C, 0x37, 0x49, 0x39, 0x30, 0x56, 0x55, 0x77, 0x48, 0x77, ++ 0x59, 0x44, 0x56, 0x52, 0x30, 0x6A, 0x42, 0x42, 0x67, 0x77, 0x46, 0x6F, 0x41, 0x55, 0x41, 0x39, 0x35, 0x51, 0x4E, 0x56, 0x62, 0x52, 0x54, 0x4C, 0x74, 0x6D, 0x38, 0x4B, 0x50, 0x69, 0x47, 0x78, 0x76, 0x44, 0x6C, 0x37, 0x49, 0x39, 0x30, 0x56, ++ 0x55, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x46, 0x0A, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x42, 0x41, 0x4D, 0x75, 0x63, 0x4E, 0x36, 0x70, 0x49, 0x45, 0x78, 0x49, 0x4B, 0x2B, ++ 0x74, 0x31, 0x45, 0x6E, 0x45, 0x39, 0x53, 0x73, 0x50, 0x54, 0x66, 0x72, 0x67, 0x54, 0x31, 0x65, 0x58, 0x6B, 0x49, 0x6F, 0x79, 0x51, 0x59, 0x2F, 0x45, 0x73, 0x72, 0x68, 0x4D, 0x41, 0x74, 0x75, 0x64, 0x58, 0x48, 0x2F, 0x76, 0x54, 0x42, 0x48, ++ 0x31, 0x6A, 0x4C, 0x75, 0x47, 0x32, 0x63, 0x65, 0x6E, 0x54, 0x6E, 0x6D, 0x43, 0x6D, 0x72, 0x0A, 0x45, 0x62, 0x58, 0x6A, 0x63, 0x4B, 0x43, 0x68, 0x7A, 0x55, 0x79, 0x49, 0x6D, 0x5A, 0x4F, 0x4D, 0x6B, 0x58, 0x44, 0x69, 0x71, 0x77, 0x38, 0x63, ++ 0x76, 0x70, 0x4F, 0x70, 0x2F, 0x32, 0x50, 0x56, 0x35, 0x41, 0x64, 0x67, 0x30, 0x36, 0x4F, 0x2F, 0x6E, 0x56, 0x73, 0x4A, 0x38, 0x64, 0x57, 0x4F, 0x34, 0x31, 0x50, 0x30, 0x6A, 0x6D, 0x50, 0x36, 0x50, 0x36, 0x66, 0x62, 0x74, 0x47, 0x62, 0x66, ++ 0x59, 0x6D, 0x62, 0x57, 0x30, 0x57, 0x35, 0x42, 0x6A, 0x66, 0x49, 0x74, 0x0A, 0x74, 0x65, 0x70, 0x33, 0x53, 0x70, 0x2B, 0x64, 0x57, 0x4F, 0x49, 0x72, 0x57, 0x63, 0x42, 0x41, 0x49, 0x2B, 0x30, 0x74, 0x4B, 0x49, 0x4A, 0x46, 0x50, 0x6E, 0x6C, ++ 0x55, 0x6B, 0x69, 0x61, 0x59, 0x34, 0x49, 0x42, 0x49, 0x71, 0x44, 0x66, 0x76, 0x38, 0x4E, 0x5A, 0x35, 0x59, 0x42, 0x62, 0x65, 0x72, 0x4F, 0x67, 0x4F, 0x7A, 0x57, 0x36, 0x73, 0x52, 0x42, 0x63, 0x34, 0x4C, 0x30, 0x6E, 0x61, 0x34, 0x55, 0x55, ++ 0x2B, 0x4B, 0x72, 0x6B, 0x32, 0x55, 0x38, 0x38, 0x36, 0x0A, 0x55, 0x41, 0x62, 0x33, 0x4C, 0x75, 0x6A, 0x45, 0x56, 0x30, 0x6C, 0x73, 0x59, 0x53, 0x45, 0x59, 0x31, 0x51, 0x53, 0x74, 0x65, 0x44, 0x77, 0x73, 0x4F, 0x6F, 0x42, 0x72, 0x70, 0x2B, ++ 0x75, 0x76, 0x46, 0x52, 0x54, 0x70, 0x32, 0x49, 0x6E, 0x42, 0x75, 0x54, 0x68, 0x73, 0x34, 0x70, 0x46, 0x73, 0x69, 0x76, 0x39, 0x6B, 0x75, 0x58, 0x63, 0x6C, 0x56, 0x7A, 0x44, 0x41, 0x47, 0x79, 0x53, 0x6A, 0x34, 0x64, 0x7A, 0x70, 0x33, 0x30, ++ 0x64, 0x38, 0x74, 0x62, 0x51, 0x6B, 0x0A, 0x43, 0x41, 0x55, 0x77, 0x37, 0x43, 0x32, 0x39, 0x43, 0x37, 0x39, 0x46, 0x76, 0x31, 0x43, 0x35, 0x71, 0x66, 0x50, 0x72, 0x6D, 0x41, 0x45, 0x53, 0x72, 0x63, 0x69, 0x49, 0x78, 0x70, 0x67, 0x30, 0x58, ++ 0x34, 0x30, 0x4B, 0x50, 0x4D, 0x62, 0x70, 0x31, 0x5A, 0x57, 0x56, 0x62, 0x64, 0x34, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x2D, 0x0A, 0x0A, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x48, 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6E, 0x63, 0x65, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x0A, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, ++ 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x44, 0x78, 0x54, 0x43, 0x43, 0x41, 0x71, 0x32, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, ++ 0x51, 0x41, 0x71, 0x78, 0x63, 0x4A, 0x6D, 0x6F, 0x4C, 0x51, 0x4A, 0x75, 0x50, 0x43, 0x33, 0x6E, 0x79, 0x72, 0x6B, 0x59, 0x6C, 0x64, 0x7A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, ++ 0x46, 0x41, 0x44, 0x42, 0x73, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0A, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x56, 0x4D, 0x42, 0x4D, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x4D, 0x52, 0x47, ++ 0x6C, 0x6E, 0x61, 0x55, 0x4E, 0x6C, 0x63, 0x6E, 0x51, 0x67, 0x53, 0x57, 0x35, 0x6A, 0x4D, 0x52, 0x6B, 0x77, 0x46, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, 0x45, 0x78, 0x42, 0x33, 0x64, 0x33, 0x63, 0x75, 0x5A, 0x47, 0x6C, 0x6E, 0x61, 0x57, ++ 0x4E, 0x6C, 0x63, 0x6E, 0x51, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4D, 0x53, 0x73, 0x77, 0x0A, 0x4B, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x79, 0x4A, 0x45, 0x61, 0x57, 0x64, 0x70, 0x51, 0x32, 0x56, 0x79, 0x64, 0x43, 0x42, 0x49, 0x61, ++ 0x57, 0x64, 0x6F, 0x49, 0x45, 0x46, 0x7A, 0x63, 0x33, 0x56, 0x79, 0x59, 0x57, 0x35, 0x6A, 0x5A, 0x53, 0x42, 0x46, 0x56, 0x69, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x41, 0x32, 0x4D, ++ 0x54, 0x45, 0x78, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x0A, 0x4D, 0x46, 0x6F, 0x58, 0x44, 0x54, 0x4D, 0x78, 0x4D, 0x54, 0x45, 0x78, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x46, 0x6F, 0x77, 0x62, 0x44, 0x45, 0x4C, ++ 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x56, 0x56, 0x4D, 0x78, 0x46, 0x54, 0x41, 0x54, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x44, 0x45, 0x52, 0x70, 0x5A, 0x32, 0x6C, 0x44, 0x5A, 0x58, 0x4A, 0x30, ++ 0x49, 0x45, 0x6C, 0x75, 0x59, 0x7A, 0x45, 0x5A, 0x0A, 0x4D, 0x42, 0x63, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4D, 0x51, 0x64, 0x33, 0x64, 0x33, 0x4C, 0x6D, 0x52, 0x70, 0x5A, 0x32, 0x6C, 0x6A, 0x5A, 0x58, 0x4A, 0x30, 0x4C, 0x6D, 0x4E, ++ 0x76, 0x62, 0x54, 0x45, 0x72, 0x4D, 0x43, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x69, 0x52, 0x47, 0x6C, 0x6E, 0x61, 0x55, 0x4E, 0x6C, 0x63, 0x6E, 0x51, 0x67, 0x53, 0x47, 0x6C, 0x6E, 0x61, 0x43, 0x42, 0x42, 0x63, 0x33, 0x4E, ++ 0x31, 0x63, 0x6D, 0x46, 0x75, 0x0A, 0x59, 0x32, 0x55, 0x67, 0x52, 0x56, 0x59, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x54, 0x43, 0x43, 0x41, 0x53, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, ++ 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x51, 0x6F, 0x43, 0x67, 0x67, 0x45, 0x42, 0x41, 0x4D, 0x62, 0x4D, 0x35, 0x58, 0x50, 0x6D, 0x2B, 0x39, 0x53, 0x37, 0x35, 0x53, ++ 0x30, 0x74, 0x0A, 0x4D, 0x71, 0x62, 0x66, 0x35, 0x59, 0x45, 0x2F, 0x79, 0x63, 0x30, 0x6C, 0x53, 0x62, 0x5A, 0x78, 0x4B, 0x73, 0x50, 0x56, 0x6C, 0x44, 0x52, 0x6E, 0x6F, 0x67, 0x6F, 0x63, 0x73, 0x46, 0x39, 0x70, 0x70, 0x6B, 0x43, 0x78, 0x78, ++ 0x4C, 0x65, 0x79, 0x6A, 0x39, 0x43, 0x59, 0x70, 0x4B, 0x6C, 0x42, 0x57, 0x54, 0x72, 0x54, 0x33, 0x4A, 0x54, 0x57, 0x50, 0x4E, 0x74, 0x30, 0x4F, 0x4B, 0x52, 0x4B, 0x7A, 0x45, 0x30, 0x6C, 0x67, 0x76, 0x64, 0x4B, 0x70, 0x56, 0x4D, 0x53, 0x0A, ++ 0x4F, 0x4F, 0x37, 0x7A, 0x53, 0x57, 0x31, 0x78, 0x6B, 0x58, 0x35, 0x6A, 0x74, 0x71, 0x75, 0x6D, 0x58, 0x38, 0x4F, 0x6B, 0x68, 0x50, 0x68, 0x50, 0x59, 0x6C, 0x47, 0x2B, 0x2B, 0x4D, 0x58, 0x73, 0x32, 0x7A, 0x69, 0x53, 0x34, 0x77, 0x62, 0x6C, ++ 0x43, 0x4A, 0x45, 0x4D, 0x78, 0x43, 0x68, 0x42, 0x56, 0x66, 0x76, 0x4C, 0x57, 0x6F, 0x6B, 0x56, 0x66, 0x6E, 0x48, 0x6F, 0x4E, 0x62, 0x39, 0x4E, 0x63, 0x67, 0x6B, 0x39, 0x76, 0x6A, 0x6F, 0x34, 0x55, 0x46, 0x74, 0x33, 0x0A, 0x4D, 0x52, 0x75, ++ 0x4E, 0x73, 0x38, 0x63, 0x6B, 0x52, 0x5A, 0x71, 0x6E, 0x72, 0x47, 0x30, 0x41, 0x46, 0x46, 0x6F, 0x45, 0x74, 0x37, 0x6F, 0x54, 0x36, 0x31, 0x45, 0x4B, 0x6D, 0x45, 0x46, 0x42, 0x49, 0x6B, 0x35, 0x6C, 0x59, 0x59, 0x65, 0x42, 0x51, 0x56, 0x43, ++ 0x6D, 0x65, 0x56, 0x79, 0x4A, 0x33, 0x68, 0x6C, 0x4B, 0x56, 0x39, 0x55, 0x75, 0x35, 0x6C, 0x30, 0x63, 0x55, 0x79, 0x78, 0x2B, 0x6D, 0x4D, 0x30, 0x61, 0x42, 0x68, 0x61, 0x6B, 0x61, 0x48, 0x50, 0x51, 0x0A, 0x4E, 0x41, 0x51, 0x54, 0x58, 0x4B, ++ 0x46, 0x78, 0x30, 0x31, 0x70, 0x38, 0x56, 0x64, 0x74, 0x65, 0x5A, 0x4F, 0x45, 0x33, 0x68, 0x7A, 0x42, 0x57, 0x42, 0x4F, 0x55, 0x52, 0x74, 0x43, 0x6D, 0x41, 0x45, 0x76, 0x46, 0x35, 0x4F, 0x59, 0x69, 0x69, 0x41, 0x68, 0x46, 0x38, 0x4A, 0x32, ++ 0x61, 0x33, 0x69, 0x4C, 0x64, 0x34, 0x38, 0x73, 0x6F, 0x4B, 0x71, 0x44, 0x69, 0x72, 0x43, 0x6D, 0x54, 0x43, 0x76, 0x32, 0x5A, 0x64, 0x6C, 0x59, 0x54, 0x42, 0x6F, 0x53, 0x55, 0x65, 0x0A, 0x68, 0x31, 0x30, 0x61, 0x55, 0x41, 0x73, 0x67, 0x45, ++ 0x73, 0x78, 0x42, 0x75, 0x32, 0x34, 0x4C, 0x55, 0x54, 0x69, 0x34, 0x53, 0x38, 0x73, 0x43, 0x41, 0x77, 0x45, 0x41, 0x41, 0x61, 0x4E, 0x6A, 0x4D, 0x47, 0x45, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, ++ 0x41, 0x51, 0x44, 0x41, 0x67, 0x47, 0x47, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x0A, 0x41, 0x66, 0x38, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, ++ 0x42, 0x42, 0x59, 0x45, 0x46, 0x4C, 0x45, 0x2B, 0x77, 0x32, 0x6B, 0x44, 0x2B, 0x4C, 0x39, 0x48, 0x41, 0x64, 0x53, 0x59, 0x4A, 0x68, 0x6F, 0x49, 0x41, 0x75, 0x39, 0x6A, 0x5A, 0x43, 0x76, 0x44, 0x4D, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, ++ 0x49, 0x77, 0x51, 0x59, 0x4D, 0x42, 0x61, 0x41, 0x46, 0x4C, 0x45, 0x2B, 0x77, 0x32, 0x6B, 0x44, 0x2B, 0x4C, 0x39, 0x48, 0x41, 0x64, 0x53, 0x59, 0x0A, 0x4A, 0x68, 0x6F, 0x49, 0x41, 0x75, 0x39, 0x6A, 0x5A, 0x43, 0x76, 0x44, 0x4D, 0x41, 0x30, ++ 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x42, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x41, 0x51, 0x41, 0x63, 0x47, 0x67, 0x61, 0x58, 0x33, 0x4E, 0x65, 0x63, 0x6E, 0x7A, 0x79, 0x49, 0x5A, 0x67, 0x59, ++ 0x49, 0x56, 0x79, 0x48, 0x62, 0x49, 0x55, 0x66, 0x34, 0x4B, 0x6D, 0x65, 0x71, 0x76, 0x78, 0x67, 0x79, 0x64, 0x6B, 0x41, 0x51, 0x0A, 0x56, 0x38, 0x47, 0x4B, 0x38, 0x33, 0x72, 0x5A, 0x45, 0x57, 0x57, 0x4F, 0x4E, 0x66, 0x71, 0x65, 0x2F, 0x45, ++ 0x57, 0x31, 0x6E, 0x74, 0x6C, 0x4D, 0x4D, 0x55, 0x75, 0x34, 0x6B, 0x65, 0x68, 0x44, 0x4C, 0x49, 0x36, 0x7A, 0x65, 0x4D, 0x37, 0x62, 0x34, 0x31, 0x4E, 0x35, 0x63, 0x64, 0x62, 0x6C, 0x49, 0x5A, 0x51, 0x42, 0x32, 0x6C, 0x57, 0x48, 0x6D, 0x69, ++ 0x52, 0x6B, 0x39, 0x6F, 0x70, 0x6D, 0x7A, 0x4E, 0x36, 0x63, 0x4E, 0x38, 0x32, 0x6F, 0x4E, 0x4C, 0x46, 0x70, 0x0A, 0x6D, 0x79, 0x50, 0x49, 0x6E, 0x6E, 0x67, 0x69, 0x4B, 0x33, 0x42, 0x44, 0x34, 0x31, 0x56, 0x48, 0x4D, 0x57, 0x45, 0x5A, 0x37, ++ 0x31, 0x6A, 0x46, 0x68, 0x53, 0x39, 0x4F, 0x4D, 0x50, 0x61, 0x67, 0x4D, 0x52, 0x59, 0x6A, 0x79, 0x4F, 0x66, 0x69, 0x5A, 0x52, 0x59, 0x7A, 0x79, 0x37, 0x38, 0x61, 0x47, 0x36, 0x41, 0x39, 0x2B, 0x4D, 0x70, 0x65, 0x69, 0x7A, 0x47, 0x4C, 0x59, ++ 0x41, 0x69, 0x4A, 0x4C, 0x51, 0x77, 0x47, 0x58, 0x46, 0x4B, 0x33, 0x78, 0x50, 0x6B, 0x4B, 0x0A, 0x6D, 0x4E, 0x45, 0x56, 0x58, 0x35, 0x38, 0x53, 0x76, 0x6E, 0x77, 0x32, 0x59, 0x7A, 0x69, 0x39, 0x52, 0x4B, 0x52, 0x2F, 0x35, 0x43, 0x59, 0x72, ++ 0x43, 0x73, 0x53, 0x58, 0x61, 0x51, 0x33, 0x70, 0x6A, 0x4F, 0x4C, 0x41, 0x45, 0x46, 0x65, 0x34, 0x79, 0x48, 0x59, 0x53, 0x6B, 0x56, 0x58, 0x79, 0x53, 0x47, 0x6E, 0x59, 0x76, 0x43, 0x6F, 0x43, 0x57, 0x77, 0x39, 0x45, 0x31, 0x43, 0x41, 0x78, ++ 0x32, 0x2F, 0x53, 0x36, 0x63, 0x43, 0x5A, 0x64, 0x6B, 0x47, 0x43, 0x65, 0x0A, 0x76, 0x45, 0x73, 0x58, 0x43, 0x53, 0x2B, 0x30, 0x79, 0x78, 0x35, 0x44, 0x61, 0x4D, 0x6B, 0x48, 0x4A, 0x38, 0x48, 0x53, 0x58, 0x50, 0x66, 0x71, 0x49, 0x62, 0x6C, ++ 0x6F, 0x45, 0x70, 0x77, 0x38, 0x6E, 0x4C, 0x2B, 0x65, 0x2F, 0x49, 0x42, 0x63, 0x6D, 0x32, 0x50, 0x4E, 0x37, 0x45, 0x65, 0x71, 0x4A, 0x53, 0x64, 0x6E, 0x6F, 0x44, 0x66, 0x7A, 0x41, 0x49, 0x4A, 0x39, 0x56, 0x4E, 0x65, 0x70, 0x2B, 0x4F, 0x6B, ++ 0x75, 0x45, 0x36, 0x4E, 0x33, 0x36, 0x42, 0x39, 0x4B, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x53, 0x77, 0x69, ++ 0x73, 0x73, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x47, 0x6F, 0x6C, 0x64, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x32, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x75, 0x6A, 0x43, 0x43, 0x41, ++ 0x36, 0x4B, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x4A, 0x41, 0x4C, 0x74, 0x41, 0x48, 0x45, 0x50, 0x31, 0x58, 0x6B, 0x2B, 0x77, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x42, ++ 0x51, 0x55, 0x41, 0x4D, 0x45, 0x55, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x4E, 0x49, 0x4D, 0x52, 0x55, 0x77, 0x0A, 0x45, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x77, 0x78, 0x54, ++ 0x64, 0x32, 0x6C, 0x7A, 0x63, 0x31, 0x4E, 0x70, 0x5A, 0x32, 0x34, 0x67, 0x51, 0x55, 0x63, 0x78, 0x48, 0x7A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x46, 0x6C, 0x4E, 0x33, 0x61, 0x58, 0x4E, 0x7A, 0x55, 0x32, 0x6C, 0x6E, ++ 0x62, 0x69, 0x42, 0x48, 0x62, 0x32, 0x78, 0x6B, 0x49, 0x45, 0x4E, 0x42, 0x49, 0x43, 0x30, 0x67, 0x52, 0x7A, 0x49, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x0A, 0x4D, 0x44, 0x59, 0x78, 0x4D, 0x44, 0x49, 0x31, 0x4D, 0x44, 0x67, 0x7A, 0x4D, 0x44, 0x4D, ++ 0x31, 0x57, 0x68, 0x63, 0x4E, 0x4D, 0x7A, 0x59, 0x78, 0x4D, 0x44, 0x49, 0x31, 0x4D, 0x44, 0x67, 0x7A, 0x4D, 0x44, 0x4D, 0x31, 0x57, 0x6A, 0x42, 0x46, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, ++ 0x44, 0x53, 0x44, 0x45, 0x56, 0x4D, 0x42, 0x4D, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x4D, 0x55, 0x33, 0x64, 0x70, 0x0A, 0x63, 0x33, 0x4E, 0x54, 0x61, 0x57, 0x64, 0x75, 0x49, 0x45, 0x46, 0x48, 0x4D, 0x52, 0x38, 0x77, 0x48, 0x51, ++ 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x5A, 0x54, 0x64, 0x32, 0x6C, 0x7A, 0x63, 0x31, 0x4E, 0x70, 0x5A, 0x32, 0x34, 0x67, 0x52, 0x32, 0x39, 0x73, 0x5A, 0x43, 0x42, 0x44, 0x51, 0x53, 0x41, 0x74, 0x49, 0x45, 0x63, 0x79, 0x4D, 0x49, ++ 0x49, 0x43, 0x49, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x0A, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x67, 0x38, 0x41, 0x4D, 0x49, 0x49, 0x43, 0x43, 0x67, 0x4B, 0x43, 0x41, ++ 0x67, 0x45, 0x41, 0x72, 0x2B, 0x54, 0x75, 0x66, 0x6F, 0x73, 0x6B, 0x44, 0x68, 0x4A, 0x75, 0x71, 0x56, 0x41, 0x74, 0x46, 0x6B, 0x51, 0x37, 0x6B, 0x70, 0x4A, 0x63, 0x79, 0x72, 0x68, 0x64, 0x68, 0x4A, 0x4A, 0x43, 0x45, 0x79, 0x71, 0x38, 0x5A, ++ 0x56, 0x65, 0x43, 0x51, 0x44, 0x35, 0x58, 0x4A, 0x4D, 0x31, 0x51, 0x69, 0x79, 0x55, 0x71, 0x0A, 0x74, 0x32, 0x2F, 0x38, 0x37, 0x36, 0x4C, 0x51, 0x77, 0x42, 0x38, 0x43, 0x4A, 0x45, 0x6F, 0x54, 0x6C, 0x6F, 0x38, 0x6A, 0x45, 0x2B, 0x59, 0x6F, ++ 0x57, 0x41, 0x43, 0x6A, 0x52, 0x38, 0x63, 0x47, 0x70, 0x34, 0x51, 0x6A, 0x4B, 0x37, 0x75, 0x39, 0x6C, 0x69, 0x74, 0x2F, 0x56, 0x63, 0x79, 0x4C, 0x77, 0x56, 0x63, 0x66, 0x44, 0x6D, 0x4A, 0x6C, 0x44, 0x39, 0x30, 0x39, 0x56, 0x6F, 0x70, 0x7A, ++ 0x32, 0x71, 0x35, 0x2B, 0x62, 0x62, 0x71, 0x42, 0x48, 0x48, 0x35, 0x43, 0x0A, 0x6A, 0x43, 0x41, 0x31, 0x32, 0x55, 0x4E, 0x4E, 0x68, 0x50, 0x71, 0x45, 0x32, 0x31, 0x49, 0x73, 0x38, 0x77, 0x34, 0x6E, 0x64, 0x77, 0x74, 0x72, 0x76, 0x78, 0x45, ++ 0x76, 0x63, 0x6E, 0x69, 0x66, 0x4C, 0x74, 0x67, 0x2B, 0x35, 0x68, 0x67, 0x33, 0x57, 0x69, 0x70, 0x79, 0x2B, 0x64, 0x70, 0x69, 0x6B, 0x4A, 0x4B, 0x56, 0x79, 0x68, 0x2B, 0x63, 0x36, 0x62, 0x4D, 0x38, 0x4B, 0x38, 0x76, 0x7A, 0x41, 0x52, 0x4F, ++ 0x2F, 0x57, 0x73, 0x2F, 0x42, 0x74, 0x51, 0x70, 0x67, 0x0A, 0x76, 0x64, 0x32, 0x31, 0x6D, 0x57, 0x52, 0x54, 0x75, 0x4B, 0x43, 0x57, 0x73, 0x32, 0x2F, 0x69, 0x4A, 0x6E, 0x65, 0x52, 0x6A, 0x4F, 0x42, 0x69, 0x45, 0x41, 0x4B, 0x66, 0x4E, 0x41, ++ 0x2B, 0x6B, 0x31, 0x5A, 0x49, 0x7A, 0x55, 0x64, 0x36, 0x2B, 0x6A, 0x62, 0x71, 0x45, 0x65, 0x6D, 0x41, 0x38, 0x61, 0x74, 0x75, 0x66, 0x4B, 0x2B, 0x7A, 0x65, 0x33, 0x67, 0x45, 0x2F, 0x62, 0x6B, 0x33, 0x6C, 0x55, 0x49, 0x62, 0x4C, 0x74, 0x4B, ++ 0x2F, 0x74, 0x52, 0x45, 0x44, 0x46, 0x0A, 0x79, 0x6C, 0x71, 0x4D, 0x32, 0x74, 0x49, 0x72, 0x66, 0x4B, 0x6A, 0x75, 0x76, 0x71, 0x62, 0x6C, 0x43, 0x71, 0x6F, 0x4F, 0x70, 0x64, 0x38, 0x46, 0x55, 0x72, 0x64, 0x56, 0x78, 0x79, 0x4A, 0x64, 0x4D, ++ 0x6D, 0x71, 0x58, 0x6C, 0x32, 0x4D, 0x54, 0x32, 0x38, 0x6E, 0x62, 0x65, 0x54, 0x5A, 0x37, 0x68, 0x54, 0x70, 0x4B, 0x78, 0x56, 0x4B, 0x4A, 0x2B, 0x53, 0x54, 0x6E, 0x6E, 0x58, 0x65, 0x70, 0x67, 0x76, 0x39, 0x56, 0x48, 0x4B, 0x56, 0x78, 0x61, ++ 0x53, 0x76, 0x52, 0x0A, 0x41, 0x69, 0x54, 0x79, 0x73, 0x79, 0x62, 0x55, 0x61, 0x39, 0x6F, 0x45, 0x56, 0x65, 0x58, 0x42, 0x43, 0x73, 0x64, 0x74, 0x4D, 0x44, 0x65, 0x51, 0x4B, 0x75, 0x53, 0x65, 0x46, 0x44, 0x4E, 0x65, 0x46, 0x68, 0x64, 0x56, ++ 0x78, 0x56, 0x75, 0x31, 0x79, 0x7A, 0x53, 0x4A, 0x6B, 0x76, 0x47, 0x64, 0x4A, 0x6F, 0x2B, 0x68, 0x42, 0x39, 0x54, 0x47, 0x73, 0x6E, 0x68, 0x51, 0x32, 0x77, 0x77, 0x4D, 0x43, 0x33, 0x77, 0x4C, 0x6A, 0x45, 0x48, 0x58, 0x75, 0x65, 0x6E, 0x64, ++ 0x0A, 0x6A, 0x49, 0x6A, 0x33, 0x6F, 0x30, 0x32, 0x79, 0x4D, 0x73, 0x7A, 0x59, 0x46, 0x39, 0x72, 0x4E, 0x74, 0x38, 0x35, 0x6D, 0x6E, 0x64, 0x54, 0x39, 0x58, 0x76, 0x2B, 0x39, 0x6C, 0x7A, 0x34, 0x70, 0x64, 0x65, 0x64, 0x2B, 0x70, 0x32, 0x4A, ++ 0x59, 0x72, 0x79, 0x55, 0x30, 0x70, 0x55, 0x48, 0x48, 0x50, 0x62, 0x77, 0x4E, 0x55, 0x4D, 0x6F, 0x44, 0x41, 0x77, 0x38, 0x49, 0x57, 0x68, 0x2B, 0x56, 0x63, 0x33, 0x68, 0x69, 0x76, 0x36, 0x39, 0x79, 0x46, 0x47, 0x6B, 0x4F, 0x0A, 0x70, 0x65, ++ 0x55, 0x44, 0x44, 0x6E, 0x69, 0x4F, 0x4A, 0x69, 0x68, 0x43, 0x38, 0x41, 0x63, 0x4C, 0x59, 0x69, 0x41, 0x51, 0x5A, 0x7A, 0x6C, 0x47, 0x2B, 0x71, 0x6B, 0x44, 0x7A, 0x41, 0x51, 0x34, 0x65, 0x6D, 0x62, 0x76, 0x49, 0x49, 0x4F, 0x31, 0x6A, 0x45, ++ 0x70, 0x57, 0x6A, 0x70, 0x45, 0x41, 0x2F, 0x49, 0x35, 0x63, 0x67, 0x74, 0x36, 0x49, 0x6F, 0x4D, 0x50, 0x69, 0x61, 0x47, 0x35, 0x39, 0x6A, 0x65, 0x38, 0x38, 0x33, 0x57, 0x58, 0x30, 0x58, 0x61, 0x78, 0x52, 0x0A, 0x37, 0x79, 0x53, 0x41, 0x72, ++ 0x71, 0x70, 0x57, 0x6C, 0x32, 0x2F, 0x35, 0x72, 0x58, 0x33, 0x61, 0x59, 0x54, 0x2B, 0x59, 0x64, 0x7A, 0x79, 0x6C, 0x6B, 0x62, 0x59, 0x63, 0x6A, 0x43, 0x62, 0x61, 0x5A, 0x61, 0x49, 0x4A, 0x62, 0x63, 0x48, 0x69, 0x56, 0x4F, 0x4F, 0x35, 0x79, ++ 0x6B, 0x78, 0x4D, 0x67, 0x49, 0x39, 0x33, 0x65, 0x32, 0x43, 0x61, 0x48, 0x74, 0x2B, 0x32, 0x38, 0x6B, 0x67, 0x65, 0x44, 0x72, 0x70, 0x4F, 0x56, 0x47, 0x32, 0x59, 0x34, 0x4F, 0x47, 0x69, 0x0A, 0x47, 0x71, 0x4A, 0x33, 0x55, 0x4D, 0x2F, 0x45, ++ 0x59, 0x35, 0x4C, 0x73, 0x52, 0x78, 0x6D, 0x64, 0x36, 0x2B, 0x5A, 0x72, 0x7A, 0x73, 0x45, 0x43, 0x41, 0x77, 0x45, 0x41, 0x41, 0x61, 0x4F, 0x42, 0x72, 0x44, 0x43, 0x42, 0x71, 0x54, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, ++ 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x51, 0x59, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x0A, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x64, 0x42, 0x67, 0x4E, ++ 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x57, 0x79, 0x56, 0x37, 0x6C, 0x71, 0x52, 0x6C, 0x55, 0x58, 0x36, 0x34, 0x4F, 0x66, 0x50, 0x41, 0x65, 0x47, 0x5A, 0x65, 0x36, 0x44, 0x72, 0x6E, 0x38, 0x4F, 0x34, 0x77, 0x48, 0x77, 0x59, ++ 0x44, 0x56, 0x52, 0x30, 0x6A, 0x42, 0x42, 0x67, 0x77, 0x46, 0x6F, 0x41, 0x55, 0x57, 0x79, 0x56, 0x37, 0x6C, 0x71, 0x52, 0x6C, 0x55, 0x58, 0x36, 0x34, 0x0A, 0x4F, 0x66, 0x50, 0x41, 0x65, 0x47, 0x5A, 0x65, 0x36, 0x44, 0x72, 0x6E, 0x38, 0x4F, ++ 0x34, 0x77, 0x52, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x67, 0x42, 0x44, 0x38, 0x77, 0x50, 0x54, 0x41, 0x37, 0x42, 0x67, 0x6C, 0x67, 0x68, 0x58, 0x51, 0x42, 0x57, 0x51, 0x45, 0x43, 0x41, 0x51, 0x45, 0x77, 0x4C, 0x6A, 0x41, 0x73, 0x42, 0x67, ++ 0x67, 0x72, 0x42, 0x67, 0x45, 0x46, 0x42, 0x51, 0x63, 0x43, 0x41, 0x52, 0x59, 0x67, 0x61, 0x48, 0x52, 0x30, 0x63, 0x44, 0x6F, 0x76, 0x0A, 0x4C, 0x33, 0x4A, 0x6C, 0x63, 0x47, 0x39, 0x7A, 0x61, 0x58, 0x52, 0x76, 0x63, 0x6E, 0x6B, 0x75, 0x63, ++ 0x33, 0x64, 0x70, 0x63, 0x33, 0x4E, 0x7A, 0x61, 0x57, 0x64, 0x75, 0x4C, 0x6D, 0x4E, 0x76, 0x62, 0x53, 0x38, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x46, 0x42, 0x51, 0x41, 0x44, 0x67, ++ 0x67, 0x49, 0x42, 0x41, 0x43, 0x65, 0x36, 0x34, 0x35, 0x52, 0x38, 0x38, 0x61, 0x37, 0x41, 0x33, 0x68, 0x66, 0x6D, 0x0A, 0x35, 0x64, 0x6A, 0x56, 0x39, 0x56, 0x53, 0x77, 0x67, 0x2F, 0x53, 0x37, 0x7A, 0x56, 0x34, 0x46, 0x65, 0x30, 0x2B, 0x66, ++ 0x64, 0x57, 0x61, 0x76, 0x50, 0x4F, 0x68, 0x57, 0x66, 0x76, 0x78, 0x79, 0x65, 0x44, 0x67, 0x44, 0x32, 0x53, 0x74, 0x69, 0x47, 0x77, 0x43, 0x35, 0x2B, 0x4F, 0x6C, 0x67, 0x7A, 0x63, 0x7A, 0x4F, 0x55, 0x59, 0x72, 0x48, 0x55, 0x44, 0x46, 0x75, ++ 0x34, 0x55, 0x70, 0x2B, 0x47, 0x43, 0x39, 0x70, 0x57, 0x62, 0x59, 0x39, 0x5A, 0x49, 0x45, 0x72, 0x0A, 0x34, 0x34, 0x4F, 0x45, 0x35, 0x69, 0x4B, 0x48, 0x6A, 0x6E, 0x33, 0x67, 0x37, 0x67, 0x4B, 0x5A, 0x59, 0x62, 0x67, 0x65, 0x39, 0x4C, 0x67, ++ 0x72, 0x69, 0x42, 0x49, 0x57, 0x68, 0x4D, 0x49, 0x78, 0x6B, 0x7A, 0x69, 0x57, 0x4D, 0x61, 0x61, 0x35, 0x4F, 0x31, 0x4D, 0x2F, 0x77, 0x79, 0x53, 0x54, 0x56, 0x6C, 0x74, 0x70, 0x6B, 0x75, 0x7A, 0x46, 0x77, 0x62, 0x73, 0x34, 0x41, 0x4F, 0x50, ++ 0x73, 0x46, 0x36, 0x6D, 0x34, 0x33, 0x4D, 0x64, 0x38, 0x41, 0x59, 0x4F, 0x66, 0x0A, 0x4D, 0x6B, 0x65, 0x36, 0x55, 0x69, 0x49, 0x30, 0x48, 0x54, 0x4A, 0x36, 0x43, 0x56, 0x61, 0x6E, 0x66, 0x43, 0x55, 0x32, 0x71, 0x54, 0x31, 0x4C, 0x32, 0x73, ++ 0x43, 0x43, 0x62, 0x77, 0x71, 0x37, 0x45, 0x73, 0x69, 0x48, 0x53, 0x79, 0x63, 0x52, 0x2B, 0x52, 0x34, 0x74, 0x78, 0x35, 0x4D, 0x2F, 0x6E, 0x74, 0x74, 0x66, 0x4A, 0x6D, 0x74, 0x53, 0x32, 0x53, 0x36, 0x4B, 0x38, 0x52, 0x54, 0x47, 0x52, 0x49, ++ 0x30, 0x56, 0x71, 0x62, 0x65, 0x2F, 0x76, 0x64, 0x36, 0x6D, 0x0A, 0x47, 0x75, 0x36, 0x75, 0x4C, 0x66, 0x74, 0x49, 0x64, 0x78, 0x66, 0x2B, 0x75, 0x2B, 0x79, 0x76, 0x47, 0x50, 0x55, 0x71, 0x55, 0x66, 0x41, 0x35, 0x68, 0x4A, 0x65, 0x56, 0x62, ++ 0x47, 0x34, 0x62, 0x77, 0x79, 0x76, 0x45, 0x64, 0x47, 0x42, 0x35, 0x4A, 0x62, 0x41, 0x4B, 0x4A, 0x39, 0x2F, 0x66, 0x58, 0x74, 0x49, 0x35, 0x7A, 0x30, 0x56, 0x39, 0x51, 0x6B, 0x76, 0x66, 0x73, 0x79, 0x77, 0x65, 0x78, 0x63, 0x5A, 0x64, 0x79, ++ 0x6C, 0x55, 0x36, 0x6F, 0x4A, 0x78, 0x70, 0x0A, 0x6D, 0x6F, 0x2F, 0x61, 0x37, 0x37, 0x4B, 0x77, 0x50, 0x4A, 0x2B, 0x48, 0x62, 0x42, 0x49, 0x72, 0x5A, 0x58, 0x41, 0x56, 0x55, 0x6A, 0x45, 0x61, 0x4A, 0x4D, 0x39, 0x76, 0x4D, 0x53, 0x4E, 0x51, ++ 0x48, 0x34, 0x78, 0x50, 0x6A, 0x79, 0x50, 0x44, 0x64, 0x45, 0x46, 0x6A, 0x48, 0x46, 0x57, 0x6F, 0x46, 0x4E, 0x30, 0x2B, 0x34, 0x46, 0x46, 0x51, 0x7A, 0x2F, 0x45, 0x62, 0x4D, 0x46, 0x59, 0x4F, 0x6B, 0x72, 0x43, 0x43, 0x68, 0x64, 0x69, 0x44, ++ 0x79, 0x79, 0x4A, 0x6B, 0x0A, 0x76, 0x43, 0x32, 0x34, 0x4A, 0x64, 0x56, 0x55, 0x6F, 0x72, 0x67, 0x47, 0x36, 0x71, 0x32, 0x53, 0x70, 0x43, 0x53, 0x67, 0x77, 0x59, 0x61, 0x31, 0x53, 0x68, 0x4E, 0x71, 0x52, 0x38, 0x38, 0x75, 0x43, 0x31, 0x61, ++ 0x56, 0x56, 0x4D, 0x76, 0x4F, 0x6D, 0x74, 0x74, 0x71, 0x74, 0x4B, 0x61, 0x79, 0x32, 0x30, 0x45, 0x49, 0x68, 0x69, 0x64, 0x33, 0x39, 0x32, 0x71, 0x67, 0x51, 0x6D, 0x77, 0x4C, 0x4F, 0x4D, 0x37, 0x58, 0x64, 0x56, 0x41, 0x79, 0x6B, 0x73, 0x4C, ++ 0x66, 0x0A, 0x4B, 0x7A, 0x41, 0x69, 0x53, 0x4E, 0x44, 0x56, 0x51, 0x54, 0x67, 0x6C, 0x58, 0x61, 0x54, 0x70, 0x58, 0x5A, 0x2F, 0x47, 0x6C, 0x48, 0x58, 0x51, 0x52, 0x66, 0x30, 0x77, 0x6C, 0x30, 0x4F, 0x50, 0x6B, 0x4B, 0x73, 0x4B, 0x78, 0x34, ++ 0x5A, 0x7A, 0x59, 0x45, 0x70, 0x70, 0x4C, 0x64, 0x36, 0x6C, 0x65, 0x4E, 0x63, 0x47, 0x32, 0x6D, 0x71, 0x65, 0x53, 0x7A, 0x35, 0x33, 0x4F, 0x69, 0x41, 0x54, 0x49, 0x67, 0x48, 0x51, 0x76, 0x32, 0x69, 0x65, 0x59, 0x32, 0x42, 0x72, 0x0A, 0x4E, ++ 0x55, 0x30, 0x4C, 0x62, 0x62, 0x71, 0x68, 0x50, 0x63, 0x43, 0x54, 0x34, 0x48, 0x38, 0x6A, 0x73, 0x31, 0x57, 0x74, 0x63, 0x69, 0x56, 0x4F, 0x52, 0x76, 0x6E, 0x53, 0x46, 0x75, 0x2B, 0x77, 0x5A, 0x4D, 0x45, 0x42, 0x6E, 0x75, 0x6E, 0x4B, 0x6F, ++ 0x47, 0x71, 0x59, 0x44, 0x73, 0x2F, 0x59, 0x59, 0x50, 0x49, 0x76, 0x53, 0x62, 0x6A, 0x6B, 0x51, 0x75, 0x45, 0x34, 0x4E, 0x52, 0x62, 0x30, 0x79, 0x47, 0x35, 0x50, 0x39, 0x34, 0x46, 0x57, 0x36, 0x4C, 0x71, 0x6A, 0x0A, 0x76, 0x69, 0x4F, 0x76, ++ 0x72, 0x76, 0x31, 0x76, 0x41, 0x2B, 0x41, 0x43, 0x4F, 0x7A, 0x42, 0x32, 0x2B, 0x68, 0x74, 0x74, 0x51, 0x63, 0x38, 0x42, 0x73, 0x65, 0x6D, 0x34, 0x79, 0x57, 0x62, 0x30, 0x32, 0x79, 0x62, 0x7A, 0x4F, 0x71, 0x52, 0x30, 0x38, 0x6B, 0x6B, 0x6B, ++ 0x57, 0x38, 0x6D, 0x77, 0x30, 0x46, 0x66, 0x42, 0x2B, 0x6A, 0x35, 0x36, 0x34, 0x5A, 0x66, 0x4A, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, ++ 0x2D, 0x2D, 0x0A, 0x0A, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x43, 0x41, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, ++ 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x44, 0x75, 0x44, 0x43, 0x43, 0x41, 0x71, 0x43, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, ++ 0x49, 0x51, 0x44, 0x50, 0x43, 0x4F, 0x58, 0x41, 0x67, 0x57, 0x70, 0x61, 0x31, 0x43, 0x66, 0x2F, 0x44, 0x72, 0x4A, 0x78, 0x68, 0x5A, 0x30, 0x44, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, ++ 0x55, 0x46, 0x41, 0x44, 0x42, 0x49, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0A, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x67, 0x4D, 0x42, 0x34, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x58, 0x55, ++ 0x32, 0x56, 0x6A, 0x64, 0x58, 0x4A, 0x6C, 0x56, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x67, 0x51, 0x32, 0x39, 0x79, 0x63, 0x47, 0x39, 0x79, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x78, 0x46, 0x7A, 0x41, 0x56, 0x42, 0x67, 0x4E, 0x56, 0x42, ++ 0x41, 0x4D, 0x54, 0x44, 0x6C, 0x4E, 0x6C, 0x59, 0x33, 0x56, 0x79, 0x5A, 0x56, 0x52, 0x79, 0x0A, 0x64, 0x58, 0x4E, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x41, 0x32, 0x4D, 0x54, 0x45, 0x77, 0x4E, 0x7A, 0x45, 0x35, ++ 0x4D, 0x7A, 0x45, 0x78, 0x4F, 0x46, 0x6F, 0x58, 0x44, 0x54, 0x49, 0x35, 0x4D, 0x54, 0x49, 0x7A, 0x4D, 0x54, 0x45, 0x35, 0x4E, 0x44, 0x41, 0x31, 0x4E, 0x56, 0x6F, 0x77, 0x53, 0x44, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, ++ 0x42, 0x68, 0x4D, 0x43, 0x56, 0x56, 0x4D, 0x78, 0x49, 0x44, 0x41, 0x65, 0x0A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x46, 0x31, 0x4E, 0x6C, 0x59, 0x33, 0x56, 0x79, 0x5A, 0x56, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x49, 0x45, 0x4E, ++ 0x76, 0x63, 0x6E, 0x42, 0x76, 0x63, 0x6D, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x4D, 0x52, 0x63, 0x77, 0x46, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x77, 0x35, 0x54, 0x5A, 0x57, 0x4E, 0x31, 0x63, 0x6D, 0x56, 0x55, 0x63, 0x6E, 0x56, ++ 0x7A, 0x64, 0x43, 0x42, 0x44, 0x51, 0x54, 0x43, 0x43, 0x0A, 0x41, 0x53, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x50, 0x41, 0x44, ++ 0x43, 0x43, 0x41, 0x51, 0x6F, 0x43, 0x67, 0x67, 0x45, 0x42, 0x41, 0x4B, 0x75, 0x6B, 0x67, 0x65, 0x57, 0x56, 0x7A, 0x66, 0x58, 0x32, 0x46, 0x49, 0x37, 0x43, 0x54, 0x38, 0x72, 0x55, 0x34, 0x6E, 0x69, 0x56, 0x57, 0x4A, 0x78, 0x42, 0x34, 0x51, ++ 0x32, 0x5A, 0x51, 0x43, 0x51, 0x58, 0x0A, 0x4F, 0x5A, 0x45, 0x7A, 0x5A, 0x75, 0x6D, 0x2B, 0x34, 0x59, 0x4F, 0x76, 0x59, 0x6C, 0x79, 0x4A, 0x30, 0x66, 0x77, 0x6B, 0x57, 0x32, 0x47, 0x7A, 0x34, 0x42, 0x45, 0x52, 0x51, 0x52, 0x77, 0x64, 0x62, ++ 0x76, 0x43, 0x34, 0x75, 0x2F, 0x6A, 0x65, 0x70, 0x34, 0x47, 0x36, 0x70, 0x6B, 0x6A, 0x47, 0x6E, 0x78, 0x32, 0x39, 0x76, 0x6F, 0x36, 0x70, 0x51, 0x54, 0x36, 0x34, 0x6C, 0x4F, 0x30, 0x70, 0x47, 0x74, 0x53, 0x4F, 0x30, 0x67, 0x4D, 0x64, 0x41, ++ 0x2B, 0x39, 0x74, 0x0A, 0x44, 0x57, 0x63, 0x63, 0x56, 0x39, 0x63, 0x47, 0x72, 0x63, 0x72, 0x49, 0x39, 0x66, 0x34, 0x4F, 0x72, 0x32, 0x59, 0x6C, 0x53, 0x41, 0x53, 0x57, 0x43, 0x31, 0x32, 0x6A, 0x75, 0x68, 0x62, 0x44, 0x43, 0x45, 0x2F, 0x52, ++ 0x52, 0x76, 0x67, 0x55, 0x58, 0x50, 0x4C, 0x49, 0x58, 0x67, 0x47, 0x5A, 0x62, 0x66, 0x32, 0x49, 0x7A, 0x49, 0x61, 0x6F, 0x77, 0x57, 0x38, 0x78, 0x51, 0x6D, 0x78, 0x53, 0x50, 0x6D, 0x6A, 0x4C, 0x38, 0x78, 0x6B, 0x30, 0x33, 0x37, 0x75, 0x48, ++ 0x0A, 0x47, 0x46, 0x61, 0x41, 0x4A, 0x73, 0x54, 0x51, 0x33, 0x4D, 0x42, 0x76, 0x33, 0x39, 0x36, 0x67, 0x77, 0x70, 0x45, 0x57, 0x6F, 0x47, 0x51, 0x52, 0x53, 0x30, 0x53, 0x38, 0x48, 0x76, 0x62, 0x6E, 0x2B, 0x6D, 0x50, 0x65, 0x5A, 0x71, 0x78, ++ 0x32, 0x70, 0x48, 0x47, 0x6A, 0x37, 0x44, 0x61, 0x55, 0x61, 0x48, 0x70, 0x33, 0x70, 0x4C, 0x48, 0x6E, 0x44, 0x69, 0x2B, 0x42, 0x65, 0x75, 0x4B, 0x31, 0x63, 0x6F, 0x62, 0x76, 0x6F, 0x6D, 0x75, 0x4C, 0x38, 0x41, 0x2F, 0x62, 0x0A, 0x30, 0x31, ++ 0x6B, 0x2F, 0x75, 0x6E, 0x4B, 0x38, 0x52, 0x43, 0x53, 0x63, 0x34, 0x33, 0x4F, 0x7A, 0x39, 0x36, 0x39, 0x58, 0x4C, 0x30, 0x49, 0x6D, 0x6E, 0x61, 0x6C, 0x30, 0x75, 0x67, 0x42, 0x53, 0x38, 0x6B, 0x76, 0x4E, 0x55, 0x33, 0x78, 0x48, 0x43, 0x7A, ++ 0x61, 0x46, 0x44, 0x6D, 0x61, 0x70, 0x43, 0x4A, 0x63, 0x57, 0x4E, 0x46, 0x66, 0x42, 0x5A, 0x76, 0x65, 0x41, 0x34, 0x2B, 0x31, 0x77, 0x56, 0x4D, 0x65, 0x54, 0x34, 0x43, 0x34, 0x6F, 0x46, 0x56, 0x6D, 0x48, 0x0A, 0x75, 0x72, 0x73, 0x43, 0x41, ++ 0x77, 0x45, 0x41, 0x41, 0x61, 0x4F, 0x42, 0x6E, 0x54, 0x43, 0x42, 0x6D, 0x6A, 0x41, 0x54, 0x42, 0x67, 0x6B, 0x72, 0x42, 0x67, 0x45, 0x45, 0x41, 0x59, 0x49, 0x33, 0x46, 0x41, 0x49, 0x45, 0x42, 0x68, 0x34, 0x45, 0x41, 0x45, 0x4D, 0x41, 0x51, ++ 0x54, 0x41, 0x4C, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x59, 0x59, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x0A, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, ++ 0x2F, 0x7A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x51, 0x6A, 0x4B, 0x32, 0x46, 0x76, 0x6F, 0x45, 0x2F, 0x66, 0x35, 0x64, 0x53, 0x33, 0x72, 0x44, 0x2F, 0x66, 0x64, 0x4D, 0x51, 0x42, 0x31, 0x61, ++ 0x51, 0x36, 0x38, 0x77, 0x4E, 0x41, 0x59, 0x44, 0x56, 0x52, 0x30, 0x66, 0x42, 0x43, 0x30, 0x77, 0x4B, 0x7A, 0x41, 0x70, 0x6F, 0x43, 0x65, 0x67, 0x4A, 0x59, 0x59, 0x6A, 0x0A, 0x61, 0x48, 0x52, 0x30, 0x63, 0x44, 0x6F, 0x76, 0x4C, 0x32, 0x4E, ++ 0x79, 0x62, 0x43, 0x35, 0x7A, 0x5A, 0x57, 0x4E, 0x31, 0x63, 0x6D, 0x56, 0x30, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x43, 0x35, 0x6A, 0x62, 0x32, 0x30, 0x76, 0x55, 0x31, 0x52, 0x44, 0x51, 0x53, 0x35, 0x6A, 0x63, 0x6D, 0x77, 0x77, 0x45, 0x41, 0x59, ++ 0x4A, 0x4B, 0x77, 0x59, 0x42, 0x42, 0x41, 0x47, 0x43, 0x4E, 0x78, 0x55, 0x42, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x51, 0x41, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x0A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x46, 0x42, 0x51, ++ 0x41, 0x44, 0x67, 0x67, 0x45, 0x42, 0x41, 0x44, 0x44, 0x74, 0x54, 0x30, 0x72, 0x68, 0x57, 0x44, 0x70, 0x53, 0x63, 0x6C, 0x75, 0x31, 0x70, 0x71, 0x4E, 0x6C, 0x47, 0x4B, 0x61, 0x37, 0x55, 0x54, 0x74, 0x33, 0x36, 0x5A, 0x33, 0x71, 0x30, 0x35, ++ 0x39, 0x63, 0x34, 0x45, 0x56, 0x6C, 0x65, 0x77, 0x33, 0x4B, 0x57, 0x2B, 0x4A, 0x77, 0x55, 0x4C, 0x4B, 0x55, 0x42, 0x52, 0x53, 0x75, 0x0A, 0x53, 0x63, 0x65, 0x4E, 0x51, 0x51, 0x63, 0x53, 0x63, 0x35, 0x52, 0x2B, 0x44, 0x43, 0x4D, 0x68, 0x2F, ++ 0x62, 0x77, 0x51, 0x66, 0x32, 0x41, 0x51, 0x57, 0x6E, 0x4C, 0x31, 0x6D, 0x41, 0x36, 0x73, 0x37, 0x4C, 0x6C, 0x2F, 0x33, 0x58, 0x70, 0x76, 0x58, 0x64, 0x4D, 0x63, 0x39, 0x50, 0x2B, 0x49, 0x42, 0x57, 0x6C, 0x43, 0x71, 0x51, 0x56, 0x78, 0x79, ++ 0x4C, 0x65, 0x73, 0x4A, 0x75, 0x67, 0x75, 0x74, 0x49, 0x78, 0x71, 0x2F, 0x33, 0x48, 0x63, 0x75, 0x4C, 0x48, 0x66, 0x0A, 0x6D, 0x62, 0x78, 0x38, 0x49, 0x56, 0x51, 0x72, 0x35, 0x46, 0x69, 0x69, 0x75, 0x31, 0x63, 0x70, 0x72, 0x70, 0x36, 0x70, ++ 0x6F, 0x78, 0x6B, 0x6D, 0x44, 0x35, 0x6B, 0x75, 0x43, 0x4C, 0x44, 0x76, 0x2F, 0x57, 0x6E, 0x50, 0x6D, 0x52, 0x6F, 0x4A, 0x6A, 0x65, 0x4F, 0x6E, 0x6E, 0x79, 0x76, 0x4A, 0x4E, 0x6A, 0x52, 0x37, 0x4A, 0x4C, 0x4E, 0x34, 0x54, 0x4A, 0x55, 0x58, ++ 0x70, 0x41, 0x59, 0x6D, 0x48, 0x72, 0x5A, 0x6B, 0x55, 0x6A, 0x5A, 0x66, 0x59, 0x47, 0x66, 0x5A, 0x0A, 0x6E, 0x4D, 0x55, 0x46, 0x64, 0x41, 0x76, 0x6E, 0x5A, 0x79, 0x50, 0x53, 0x43, 0x50, 0x79, 0x49, 0x36, 0x61, 0x36, 0x4C, 0x66, 0x2B, 0x45, ++ 0x77, 0x39, 0x44, 0x64, 0x2B, 0x2F, 0x63, 0x59, 0x79, 0x32, 0x69, 0x32, 0x65, 0x52, 0x44, 0x41, 0x77, 0x62, 0x4F, 0x34, 0x48, 0x33, 0x74, 0x49, 0x30, 0x2F, 0x4E, 0x4C, 0x2F, 0x51, 0x50, 0x5A, 0x4C, 0x39, 0x47, 0x5A, 0x47, 0x42, 0x6C, 0x53, ++ 0x6D, 0x38, 0x6A, 0x49, 0x4B, 0x59, 0x79, 0x59, 0x77, 0x61, 0x35, 0x76, 0x52, 0x0A, 0x33, 0x49, 0x74, 0x48, 0x75, 0x75, 0x47, 0x35, 0x31, 0x57, 0x4C, 0x51, 0x6F, 0x71, 0x44, 0x30, 0x5A, 0x77, 0x56, 0x34, 0x4B, 0x57, 0x4D, 0x61, 0x62, 0x77, ++ 0x54, 0x57, 0x2B, 0x4D, 0x5A, 0x4D, 0x6F, 0x35, 0x71, 0x78, 0x4E, 0x37, 0x53, 0x4E, 0x35, 0x53, 0x68, 0x4C, 0x48, 0x5A, 0x34, 0x73, 0x77, 0x72, 0x68, 0x6F, 0x76, 0x4F, 0x30, 0x43, 0x37, 0x6A, 0x45, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x43, 0x41, 0x0A, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, ++ 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x44, 0x76, 0x44, 0x43, 0x43, 0x41, 0x71, 0x53, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x42, 0x31, 0x59, 0x69, 0x70, 0x4F, 0x6A, 0x55, 0x69, 0x6F, 0x6C, 0x4E, 0x39, 0x42, 0x50, 0x49, ++ 0x38, 0x50, 0x6A, 0x71, 0x70, 0x54, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x44, 0x42, 0x4B, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, ++ 0x0A, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x67, 0x4D, 0x42, 0x34, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x58, 0x55, 0x32, 0x56, 0x6A, 0x64, 0x58, 0x4A, 0x6C, 0x56, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x67, 0x51, 0x32, 0x39, ++ 0x79, 0x63, 0x47, 0x39, 0x79, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x78, 0x47, 0x54, 0x41, 0x58, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x45, 0x46, 0x4E, 0x6C, 0x59, 0x33, 0x56, 0x79, 0x5A, 0x53, 0x42, 0x48, 0x0A, 0x62, 0x47, ++ 0x39, 0x69, 0x59, 0x57, 0x77, 0x67, 0x51, 0x30, 0x45, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x44, 0x59, 0x78, 0x4D, 0x54, 0x41, 0x33, 0x4D, 0x54, 0x6B, 0x30, 0x4D, 0x6A, 0x49, 0x34, 0x57, 0x68, 0x63, 0x4E, 0x4D, 0x6A, 0x6B, 0x78, 0x4D, 0x6A, ++ 0x4D, 0x78, 0x4D, 0x54, 0x6B, 0x31, 0x4D, 0x6A, 0x41, 0x32, 0x57, 0x6A, 0x42, 0x4B, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x67, 0x0A, 0x4D, 0x42, 0x34, 0x47, 0x41, ++ 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x58, 0x55, 0x32, 0x56, 0x6A, 0x64, 0x58, 0x4A, 0x6C, 0x56, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x67, 0x51, 0x32, 0x39, 0x79, 0x63, 0x47, 0x39, 0x79, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x78, 0x47, ++ 0x54, 0x41, 0x58, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x45, 0x46, 0x4E, 0x6C, 0x59, 0x33, 0x56, 0x79, 0x5A, 0x53, 0x42, 0x48, 0x62, 0x47, 0x39, 0x69, 0x59, 0x57, 0x77, 0x67, 0x0A, 0x51, 0x30, 0x45, 0x77, 0x67, 0x67, 0x45, 0x69, ++ 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x45, 0x4B, 0x41, 0x6F, 0x49, 0x42, 0x41, 0x51, 0x43, 0x76, ++ 0x4E, 0x53, 0x37, 0x59, 0x72, 0x47, 0x78, 0x56, 0x61, 0x51, 0x5A, 0x78, 0x35, 0x52, 0x4E, 0x6F, 0x4A, 0x4C, 0x4E, 0x50, 0x32, 0x4D, 0x77, 0x68, 0x52, 0x2F, 0x6A, 0x78, 0x0A, 0x59, 0x44, 0x69, 0x4A, 0x69, 0x51, 0x50, 0x70, 0x76, 0x65, 0x70, ++ 0x65, 0x52, 0x6C, 0x4D, 0x4A, 0x33, 0x46, 0x7A, 0x31, 0x57, 0x75, 0x6A, 0x33, 0x52, 0x53, 0x6F, 0x43, 0x36, 0x7A, 0x46, 0x68, 0x31, 0x79, 0x6B, 0x7A, 0x54, 0x4D, 0x37, 0x48, 0x66, 0x41, 0x6F, 0x33, 0x66, 0x67, 0x2B, 0x36, 0x4D, 0x70, 0x6A, ++ 0x68, 0x48, 0x5A, 0x65, 0x76, 0x6A, 0x38, 0x66, 0x63, 0x79, 0x54, 0x69, 0x57, 0x38, 0x39, 0x73, 0x61, 0x2F, 0x46, 0x48, 0x74, 0x61, 0x4D, 0x62, 0x51, 0x0A, 0x62, 0x71, 0x52, 0x38, 0x4A, 0x4E, 0x47, 0x75, 0x51, 0x73, 0x69, 0x57, 0x55, 0x47, ++ 0x4D, 0x75, 0x34, 0x50, 0x35, 0x31, 0x2F, 0x70, 0x69, 0x6E, 0x58, 0x30, 0x6B, 0x75, 0x6C, 0x65, 0x4D, 0x35, 0x4D, 0x32, 0x53, 0x4F, 0x48, 0x71, 0x52, 0x66, 0x6B, 0x4E, 0x4A, 0x6E, 0x50, 0x4C, 0x4C, 0x5A, 0x2F, 0x6B, 0x47, 0x35, 0x56, 0x61, ++ 0x63, 0x4A, 0x6A, 0x6E, 0x49, 0x46, 0x48, 0x6F, 0x76, 0x64, 0x52, 0x49, 0x57, 0x43, 0x51, 0x74, 0x42, 0x4A, 0x77, 0x42, 0x31, 0x67, 0x0A, 0x38, 0x4E, 0x45, 0x58, 0x4C, 0x4A, 0x58, 0x72, 0x39, 0x71, 0x58, 0x42, 0x6B, 0x71, 0x50, 0x46, 0x77, ++ 0x71, 0x63, 0x49, 0x59, 0x41, 0x31, 0x67, 0x42, 0x42, 0x43, 0x57, 0x65, 0x5A, 0x34, 0x57, 0x4E, 0x4F, 0x61, 0x70, 0x74, 0x76, 0x6F, 0x6C, 0x52, 0x54, 0x6E, 0x49, 0x48, 0x6D, 0x58, 0x35, 0x6B, 0x2F, 0x57, 0x71, 0x38, 0x56, 0x4C, 0x63, 0x6D, ++ 0x5A, 0x67, 0x39, 0x70, 0x59, 0x59, 0x61, 0x44, 0x44, 0x55, 0x7A, 0x2B, 0x6B, 0x75, 0x6C, 0x42, 0x41, 0x59, 0x56, 0x0A, 0x48, 0x44, 0x47, 0x41, 0x37, 0x36, 0x6F, 0x59, 0x61, 0x38, 0x4A, 0x37, 0x31, 0x39, 0x72, 0x4F, 0x2B, 0x54, 0x4D, 0x67, ++ 0x31, 0x66, 0x57, 0x39, 0x61, 0x6A, 0x4D, 0x74, 0x67, 0x51, 0x54, 0x37, 0x73, 0x46, 0x7A, 0x55, 0x6E, 0x4B, 0x50, 0x69, 0x58, 0x42, 0x33, 0x6A, 0x71, 0x55, 0x4A, 0x31, 0x58, 0x6E, 0x76, 0x55, 0x64, 0x2B, 0x38, 0x35, 0x56, 0x4C, 0x72, 0x4A, ++ 0x43, 0x68, 0x67, 0x62, 0x45, 0x70, 0x6C, 0x4A, 0x4C, 0x34, 0x68, 0x4C, 0x2F, 0x56, 0x42, 0x69, 0x0A, 0x30, 0x58, 0x50, 0x6E, 0x6A, 0x33, 0x70, 0x44, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, 0x67, 0x5A, 0x30, 0x77, 0x67, 0x5A, 0x6F, ++ 0x77, 0x45, 0x77, 0x59, 0x4A, 0x4B, 0x77, 0x59, 0x42, 0x42, 0x41, 0x47, 0x43, 0x4E, 0x78, 0x51, 0x43, 0x42, 0x41, 0x59, 0x65, 0x42, 0x41, 0x42, 0x44, 0x41, 0x45, 0x45, 0x77, 0x43, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x42, 0x41, 0x51, ++ 0x44, 0x41, 0x67, 0x47, 0x47, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x0A, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, ++ 0x59, 0x45, 0x46, 0x4B, 0x39, 0x45, 0x42, 0x4D, 0x4A, 0x42, 0x66, 0x6B, 0x69, 0x44, 0x32, 0x30, 0x34, 0x35, 0x41, 0x75, 0x7A, 0x73, 0x68, 0x48, 0x72, 0x6D, 0x7A, 0x73, 0x6D, 0x6B, 0x4D, 0x44, 0x51, 0x47, 0x41, 0x31, 0x55, 0x64, 0x48, 0x77, ++ 0x51, 0x74, 0x4D, 0x43, 0x73, 0x77, 0x4B, 0x61, 0x41, 0x6E, 0x0A, 0x6F, 0x43, 0x57, 0x47, 0x49, 0x32, 0x68, 0x30, 0x64, 0x48, 0x41, 0x36, 0x4C, 0x79, 0x39, 0x6A, 0x63, 0x6D, 0x77, 0x75, 0x63, 0x32, 0x56, 0x6A, 0x64, 0x58, 0x4A, 0x6C, 0x64, ++ 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4C, 0x31, 0x4E, 0x48, 0x51, 0x30, 0x45, 0x75, 0x59, 0x33, 0x4A, 0x73, 0x4D, 0x42, 0x41, 0x47, 0x43, 0x53, 0x73, 0x47, 0x41, 0x51, 0x51, 0x42, 0x67, 0x6A, 0x63, 0x56, 0x41, ++ 0x51, 0x51, 0x44, 0x41, 0x67, 0x45, 0x41, 0x0A, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x42, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x41, 0x51, 0x42, 0x6A, 0x47, 0x67, 0x68, 0x41, ++ 0x66, 0x61, 0x52, 0x65, 0x55, 0x77, 0x31, 0x33, 0x32, 0x48, 0x71, 0x75, 0x48, 0x77, 0x30, 0x4C, 0x55, 0x52, 0x59, 0x44, 0x37, 0x78, 0x68, 0x38, 0x79, 0x4F, 0x4F, 0x76, 0x61, 0x6C, 0x69, 0x54, 0x46, 0x47, 0x43, 0x52, 0x73, 0x6F, 0x54, 0x63, ++ 0x69, 0x45, 0x36, 0x2B, 0x0A, 0x4F, 0x59, 0x6F, 0x36, 0x38, 0x2B, 0x61, 0x43, 0x69, 0x56, 0x30, 0x42, 0x4E, 0x37, 0x4F, 0x72, 0x4A, 0x4B, 0x51, 0x56, 0x44, 0x70, 0x49, 0x31, 0x57, 0x6B, 0x70, 0x45, 0x58, 0x6B, 0x35, 0x58, 0x2B, 0x6E, 0x58, ++ 0x4F, 0x48, 0x30, 0x6A, 0x4F, 0x5A, 0x76, 0x51, 0x38, 0x51, 0x43, 0x61, 0x53, 0x6D, 0x47, 0x77, 0x62, 0x37, 0x69, 0x52, 0x47, 0x44, 0x42, 0x65, 0x7A, 0x55, 0x71, 0x58, 0x62, 0x70, 0x5A, 0x47, 0x52, 0x7A, 0x7A, 0x66, 0x54, 0x62, 0x2B, 0x63, ++ 0x6E, 0x0A, 0x43, 0x44, 0x70, 0x4F, 0x47, 0x52, 0x38, 0x36, 0x70, 0x31, 0x68, 0x63, 0x46, 0x38, 0x39, 0x35, 0x50, 0x34, 0x76, 0x6B, 0x70, 0x39, 0x4D, 0x6D, 0x49, 0x35, 0x30, 0x6D, 0x44, 0x31, 0x68, 0x70, 0x2F, 0x45, 0x64, 0x2B, 0x73, 0x74, ++ 0x43, 0x4E, 0x69, 0x35, 0x4F, 0x2F, 0x4B, 0x55, 0x39, 0x44, 0x61, 0x58, 0x52, 0x32, 0x5A, 0x30, 0x76, 0x50, 0x42, 0x34, 0x7A, 0x6D, 0x41, 0x76, 0x65, 0x31, 0x34, 0x62, 0x52, 0x44, 0x74, 0x55, 0x73, 0x74, 0x46, 0x4A, 0x2F, 0x35, 0x0A, 0x33, ++ 0x43, 0x59, 0x4E, 0x76, 0x36, 0x5A, 0x48, 0x64, 0x41, 0x62, 0x59, 0x69, 0x4E, 0x45, 0x36, 0x4B, 0x54, 0x43, 0x45, 0x7A, 0x74, 0x49, 0x35, 0x67, 0x47, 0x49, 0x62, 0x71, 0x4D, 0x64, 0x58, 0x53, 0x62, 0x78, 0x71, 0x56, 0x56, 0x46, 0x6E, 0x46, ++ 0x55, 0x71, 0x2B, 0x4E, 0x51, 0x66, 0x6B, 0x31, 0x58, 0x57, 0x59, 0x4E, 0x33, 0x6B, 0x77, 0x46, 0x4E, 0x73, 0x70, 0x6E, 0x57, 0x7A, 0x46, 0x61, 0x63, 0x78, 0x48, 0x56, 0x61, 0x49, 0x77, 0x39, 0x38, 0x78, 0x63, 0x0A, 0x66, 0x38, 0x4C, 0x44, ++ 0x6D, 0x42, 0x78, 0x72, 0x54, 0x68, 0x61, 0x41, 0x36, 0x33, 0x70, 0x34, 0x5A, 0x55, 0x57, 0x69, 0x41, 0x42, 0x71, 0x76, 0x44, 0x41, 0x31, 0x56, 0x5A, 0x44, 0x52, 0x49, 0x75, 0x4A, 0x4B, 0x35, 0x38, 0x62, 0x52, 0x51, 0x4B, 0x66, 0x4A, 0x50, ++ 0x49, 0x78, 0x2F, 0x61, 0x62, 0x4B, 0x77, 0x66, 0x52, 0x4F, 0x48, 0x64, 0x49, 0x33, 0x68, 0x52, 0x57, 0x38, 0x63, 0x57, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, ++ 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x0A, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, ++ 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x45, 0x48, 0x54, 0x43, 0x43, 0x41, 0x77, 0x57, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x54, 0x6F, ++ 0x45, 0x74, 0x69, 0x6F, 0x4A, 0x6C, 0x34, 0x41, 0x73, 0x43, 0x37, 0x6A, 0x34, 0x31, 0x41, 0x6B, 0x62, 0x6C, 0x50, 0x54, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x44, ++ 0x43, 0x42, 0x67, 0x54, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0A, 0x42, 0x68, 0x4D, 0x43, 0x52, 0x30, 0x49, 0x78, 0x47, 0x7A, 0x41, 0x5A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x67, 0x54, 0x45, 0x6B, 0x64, 0x79, 0x5A, ++ 0x57, 0x46, 0x30, 0x5A, 0x58, 0x49, 0x67, 0x54, 0x57, 0x46, 0x75, 0x59, 0x32, 0x68, 0x6C, 0x63, 0x33, 0x52, 0x6C, 0x63, 0x6A, 0x45, 0x51, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x78, 0x4D, 0x48, 0x55, 0x32, 0x46, 0x73, 0x5A, ++ 0x6D, 0x39, 0x79, 0x5A, 0x44, 0x45, 0x61, 0x4D, 0x42, 0x67, 0x47, 0x0A, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x52, 0x51, 0x30, 0x39, 0x4E, 0x54, 0x30, 0x52, 0x50, 0x49, 0x45, 0x4E, 0x42, 0x49, 0x45, 0x78, 0x70, 0x62, 0x57, 0x6C, 0x30, ++ 0x5A, 0x57, 0x51, 0x78, 0x4A, 0x7A, 0x41, 0x6C, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x48, 0x6B, 0x4E, 0x50, 0x54, 0x55, 0x39, 0x45, 0x54, 0x79, 0x42, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x61, 0x57, 0x5A, 0x70, 0x59, 0x32, 0x46, 0x30, ++ 0x61, 0x57, 0x39, 0x75, 0x49, 0x45, 0x46, 0x31, 0x0A, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6D, 0x6C, 0x30, 0x65, 0x54, 0x41, 0x65, 0x46, 0x77, 0x30, 0x77, 0x4E, 0x6A, 0x45, 0x79, 0x4D, 0x44, 0x45, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x42, ++ 0x61, 0x46, 0x77, 0x30, 0x79, 0x4F, 0x54, 0x45, 0x79, 0x4D, 0x7A, 0x45, 0x79, 0x4D, 0x7A, 0x55, 0x35, 0x4E, 0x54, 0x6C, 0x61, 0x4D, 0x49, 0x47, 0x42, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, ++ 0x48, 0x51, 0x6A, 0x45, 0x62, 0x0A, 0x4D, 0x42, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x42, 0x4D, 0x53, 0x52, 0x33, 0x4A, 0x6C, 0x59, 0x58, 0x52, 0x6C, 0x63, 0x69, 0x42, 0x4E, 0x59, 0x57, 0x35, 0x6A, 0x61, 0x47, 0x56, 0x7A, 0x64, 0x47, ++ 0x56, 0x79, 0x4D, 0x52, 0x41, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x48, 0x45, 0x77, 0x64, 0x54, 0x59, 0x57, 0x78, 0x6D, 0x62, 0x33, 0x4A, 0x6B, 0x4D, 0x52, 0x6F, 0x77, 0x47, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x78, ++ 0x46, 0x44, 0x0A, 0x54, 0x30, 0x31, 0x50, 0x52, 0x45, 0x38, 0x67, 0x51, 0x30, 0x45, 0x67, 0x54, 0x47, 0x6C, 0x74, 0x61, 0x58, 0x52, 0x6C, 0x5A, 0x44, 0x45, 0x6E, 0x4D, 0x43, 0x55, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x65, 0x51, ++ 0x30, 0x39, 0x4E, 0x54, 0x30, 0x52, 0x50, 0x49, 0x45, 0x4E, 0x6C, 0x63, 0x6E, 0x52, 0x70, 0x5A, 0x6D, 0x6C, 0x6A, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52, 0x35, 0x0A, ++ 0x4D, 0x49, 0x49, 0x42, 0x49, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x51, 0x38, 0x41, 0x4D, 0x49, 0x49, 0x42, 0x43, 0x67, 0x4B, 0x43, ++ 0x41, 0x51, 0x45, 0x41, 0x30, 0x45, 0x43, 0x4C, 0x69, 0x33, 0x4C, 0x6A, 0x6B, 0x52, 0x76, 0x33, 0x55, 0x63, 0x45, 0x62, 0x56, 0x41, 0x53, 0x59, 0x30, 0x36, 0x6D, 0x2F, 0x77, 0x65, 0x61, 0x4B, 0x58, 0x54, 0x75, 0x48, 0x0A, 0x2B, 0x37, 0x75, ++ 0x49, 0x7A, 0x67, 0x33, 0x6A, 0x4C, 0x7A, 0x38, 0x47, 0x6C, 0x76, 0x43, 0x69, 0x4B, 0x56, 0x43, 0x5A, 0x72, 0x74, 0x73, 0x37, 0x6F, 0x56, 0x65, 0x77, 0x64, 0x46, 0x46, 0x78, 0x7A, 0x65, 0x31, 0x43, 0x6B, 0x55, 0x31, 0x42, 0x2F, 0x71, 0x6E, ++ 0x49, 0x32, 0x47, 0x71, 0x47, 0x64, 0x30, 0x53, 0x37, 0x57, 0x57, 0x61, 0x58, 0x55, 0x46, 0x36, 0x30, 0x31, 0x43, 0x78, 0x77, 0x52, 0x4D, 0x2F, 0x61, 0x4E, 0x35, 0x56, 0x43, 0x61, 0x54, 0x77, 0x77, 0x0A, 0x78, 0x48, 0x47, 0x7A, 0x55, 0x76, ++ 0x41, 0x68, 0x54, 0x61, 0x48, 0x59, 0x75, 0x6A, 0x6C, 0x38, 0x48, 0x4A, 0x36, 0x6A, 0x4A, 0x4A, 0x33, 0x79, 0x67, 0x78, 0x61, 0x59, 0x71, 0x68, 0x5A, 0x38, 0x51, 0x35, 0x73, 0x56, 0x57, 0x37, 0x65, 0x75, 0x4E, 0x4A, 0x48, 0x2B, 0x31, 0x47, ++ 0x49, 0x6D, 0x47, 0x45, 0x61, 0x61, 0x50, 0x2B, 0x76, 0x42, 0x2B, 0x66, 0x47, 0x51, 0x56, 0x2B, 0x75, 0x73, 0x65, 0x67, 0x32, 0x4C, 0x32, 0x33, 0x49, 0x77, 0x61, 0x6D, 0x62, 0x56, 0x0A, 0x34, 0x45, 0x61, 0x6A, 0x63, 0x4E, 0x78, 0x6F, 0x32, ++ 0x66, 0x38, 0x45, 0x53, 0x49, 0x6C, 0x33, 0x33, 0x72, 0x58, 0x70, 0x2B, 0x32, 0x64, 0x74, 0x51, 0x65, 0x6D, 0x38, 0x4F, 0x62, 0x30, 0x79, 0x32, 0x57, 0x49, 0x43, 0x38, 0x62, 0x47, 0x6F, 0x50, 0x57, 0x34, 0x33, 0x6E, 0x4F, 0x49, 0x76, 0x34, ++ 0x74, 0x4F, 0x69, 0x4A, 0x6F, 0x76, 0x47, 0x75, 0x46, 0x56, 0x44, 0x69, 0x4F, 0x45, 0x6A, 0x50, 0x71, 0x58, 0x53, 0x4A, 0x44, 0x6C, 0x71, 0x52, 0x36, 0x73, 0x41, 0x0A, 0x31, 0x4B, 0x47, 0x7A, 0x71, 0x53, 0x58, 0x2B, 0x44, 0x54, 0x2B, 0x6E, ++ 0x48, 0x62, 0x72, 0x54, 0x55, 0x63, 0x45, 0x4C, 0x70, 0x4E, 0x71, 0x73, 0x4F, 0x4F, 0x39, 0x56, 0x55, 0x43, 0x51, 0x46, 0x5A, 0x55, 0x61, 0x54, 0x4E, 0x45, 0x38, 0x74, 0x6A, 0x61, 0x33, 0x47, 0x31, 0x43, 0x45, 0x5A, 0x30, 0x6F, 0x37, 0x4B, ++ 0x42, 0x57, 0x46, 0x78, 0x42, 0x33, 0x4E, 0x48, 0x35, 0x59, 0x6F, 0x5A, 0x45, 0x72, 0x30, 0x45, 0x54, 0x63, 0x35, 0x4F, 0x6E, 0x4B, 0x56, 0x49, 0x0A, 0x72, 0x4C, 0x73, 0x6D, 0x39, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6F, 0x34, 0x47, ++ 0x4F, 0x4D, 0x49, 0x47, 0x4C, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x51, 0x4C, 0x57, 0x4F, 0x57, 0x4C, 0x78, 0x6B, 0x77, 0x56, 0x4E, 0x36, 0x52, 0x41, 0x71, 0x54, 0x43, 0x70, 0x49, 0x62, 0x35, ++ 0x48, 0x4E, 0x6C, 0x70, 0x57, 0x2F, 0x7A, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x0A, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x51, 0x59, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, ++ 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x42, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x38, 0x45, 0x51, 0x6A, 0x42, 0x41, 0x4D, 0x44, 0x36, 0x67, 0x50, 0x4B, 0x41, 0x36, 0x68, 0x6A, 0x68, 0x6F, 0x64, 0x48, ++ 0x52, 0x77, 0x4F, 0x69, 0x38, 0x76, 0x59, 0x33, 0x4A, 0x73, 0x4C, 0x6D, 0x4E, 0x76, 0x62, 0x57, 0x39, 0x6B, 0x0A, 0x62, 0x32, 0x4E, 0x68, 0x4C, 0x6D, 0x4E, 0x76, 0x62, 0x53, 0x39, 0x44, 0x54, 0x30, 0x31, 0x50, 0x52, 0x45, 0x39, 0x44, 0x5A, ++ 0x58, 0x4A, 0x30, 0x61, 0x57, 0x5A, 0x70, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52, 0x35, 0x4C, 0x6D, 0x4E, 0x79, 0x62, 0x44, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, ++ 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x0A, 0x41, 0x51, 0x45, 0x41, 0x50, 0x70, 0x69, 0x65, 0x6D, 0x2F, 0x59, 0x62, 0x36, 0x64, 0x63, 0x35, 0x74, 0x33, 0x69, 0x75, 0x48, 0x58, 0x49, 0x59, ++ 0x53, 0x64, 0x4F, 0x48, 0x35, 0x45, 0x4F, 0x43, 0x36, 0x7A, 0x2F, 0x4A, 0x71, 0x76, 0x57, 0x6F, 0x74, 0x65, 0x39, 0x56, 0x66, 0x43, 0x46, 0x53, 0x5A, 0x66, 0x6E, 0x56, 0x44, 0x65, 0x46, 0x73, 0x39, 0x44, 0x36, 0x4D, 0x6B, 0x33, 0x4F, 0x52, ++ 0x4C, 0x67, 0x4C, 0x45, 0x54, 0x67, 0x64, 0x78, 0x62, 0x38, 0x43, 0x50, 0x0A, 0x4F, 0x47, 0x45, 0x49, 0x71, 0x42, 0x36, 0x42, 0x43, 0x73, 0x41, 0x76, 0x49, 0x43, 0x39, 0x42, 0x69, 0x35, 0x48, 0x63, 0x53, 0x45, 0x57, 0x38, 0x38, 0x63, 0x62, ++ 0x65, 0x75, 0x6E, 0x5A, 0x72, 0x4D, 0x38, 0x67, 0x41, 0x4C, 0x54, 0x46, 0x47, 0x54, 0x4F, 0x33, 0x6E, 0x6E, 0x63, 0x2B, 0x49, 0x6C, 0x50, 0x38, 0x7A, 0x77, 0x46, 0x62, 0x6F, 0x4A, 0x49, 0x59, 0x6D, 0x75, 0x4E, 0x67, 0x34, 0x4F, 0x4E, 0x38, ++ 0x71, 0x61, 0x39, 0x30, 0x53, 0x7A, 0x4D, 0x63, 0x2F, 0x0A, 0x52, 0x78, 0x64, 0x4D, 0x6F, 0x73, 0x49, 0x47, 0x6C, 0x67, 0x6E, 0x57, 0x32, 0x2F, 0x34, 0x2F, 0x50, 0x45, 0x5A, 0x42, 0x33, 0x31, 0x6A, 0x69, 0x56, 0x67, 0x38, 0x38, 0x4F, 0x38, ++ 0x45, 0x63, 0x6B, 0x7A, 0x58, 0x5A, 0x4F, 0x46, 0x4B, 0x73, 0x37, 0x73, 0x6A, 0x73, 0x4C, 0x6A, 0x42, 0x4F, 0x6C, 0x44, 0x57, 0x30, 0x4A, 0x42, 0x39, 0x4C, 0x65, 0x47, 0x6E, 0x61, 0x38, 0x67, 0x49, 0x34, 0x7A, 0x4A, 0x56, 0x53, 0x6B, 0x2F, ++ 0x42, 0x77, 0x4A, 0x56, 0x6D, 0x63, 0x0A, 0x49, 0x47, 0x66, 0x45, 0x37, 0x76, 0x6D, 0x4C, 0x56, 0x32, 0x48, 0x30, 0x6B, 0x6E, 0x5A, 0x39, 0x50, 0x34, 0x53, 0x4E, 0x56, 0x62, 0x66, 0x6F, 0x35, 0x61, 0x7A, 0x56, 0x38, 0x66, 0x55, 0x5A, 0x56, ++ 0x71, 0x5A, 0x61, 0x2B, 0x35, 0x41, 0x63, 0x72, 0x35, 0x50, 0x72, 0x35, 0x52, 0x7A, 0x55, 0x5A, 0x35, 0x64, 0x64, 0x42, 0x41, 0x36, 0x2B, 0x43, 0x34, 0x4F, 0x6D, 0x46, 0x34, 0x4F, 0x35, 0x4D, 0x42, 0x4B, 0x67, 0x78, 0x54, 0x4D, 0x56, 0x42, ++ 0x62, 0x6B, 0x4E, 0x0A, 0x2B, 0x38, 0x63, 0x46, 0x64, 0x75, 0x50, 0x59, 0x53, 0x6F, 0x33, 0x38, 0x4E, 0x42, 0x65, 0x6A, 0x78, 0x69, 0x45, 0x6F, 0x76, 0x6A, 0x42, 0x46, 0x4D, 0x52, 0x37, 0x48, 0x65, 0x4C, 0x35, 0x59, 0x59, 0x54, 0x69, 0x73, ++ 0x4F, 0x2B, 0x49, 0x42, 0x5A, 0x51, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x43, 0x4F, 0x4D, 0x4F, ++ 0x44, 0x4F, 0x20, 0x45, 0x43, 0x43, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, ++ 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x69, 0x54, 0x43, 0x43, 0x41, 0x67, 0x2B, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x48, 0x30, 0x65, 0x76, 0x71, 0x6D, ++ 0x49, 0x41, 0x63, 0x46, 0x42, 0x55, 0x54, 0x41, 0x47, 0x65, 0x6D, 0x32, 0x4F, 0x5A, 0x4B, 0x6A, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x7A, 0x43, 0x42, 0x68, 0x54, 0x45, 0x4C, 0x4D, 0x41, ++ 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x0A, 0x52, 0x30, 0x49, 0x78, 0x47, 0x7A, 0x41, 0x5A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x67, 0x54, 0x45, 0x6B, 0x64, 0x79, 0x5A, 0x57, 0x46, 0x30, 0x5A, 0x58, 0x49, 0x67, 0x54, ++ 0x57, 0x46, 0x75, 0x59, 0x32, 0x68, 0x6C, 0x63, 0x33, 0x52, 0x6C, 0x63, 0x6A, 0x45, 0x51, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x78, 0x4D, 0x48, 0x55, 0x32, 0x46, 0x73, 0x5A, 0x6D, 0x39, 0x79, 0x5A, 0x44, 0x45, 0x61, 0x4D, ++ 0x42, 0x67, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0A, 0x43, 0x68, 0x4D, 0x52, 0x51, 0x30, 0x39, 0x4E, 0x54, 0x30, 0x52, 0x50, 0x49, 0x45, 0x4E, 0x42, 0x49, 0x45, 0x78, 0x70, 0x62, 0x57, 0x6C, 0x30, 0x5A, 0x57, 0x51, 0x78, 0x4B, 0x7A, 0x41, 0x70, ++ 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x49, 0x6B, 0x4E, 0x50, 0x54, 0x55, 0x39, 0x45, 0x54, 0x79, 0x42, 0x46, 0x51, 0x30, 0x4D, 0x67, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6C, 0x6D, 0x61, 0x57, 0x4E, 0x68, 0x64, 0x47, 0x6C, 0x76, ++ 0x62, 0x69, 0x42, 0x42, 0x0A, 0x64, 0x58, 0x52, 0x6F, 0x62, 0x33, 0x4A, 0x70, 0x64, 0x48, 0x6B, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x44, 0x67, 0x77, 0x4D, 0x7A, 0x41, 0x32, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x57, 0x68, 0x63, ++ 0x4E, 0x4D, 0x7A, 0x67, 0x77, 0x4D, 0x54, 0x45, 0x34, 0x4D, 0x6A, 0x4D, 0x31, 0x4F, 0x54, 0x55, 0x35, 0x57, 0x6A, 0x43, 0x42, 0x68, 0x54, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x52, 0x30, 0x49, ++ 0x78, 0x0A, 0x47, 0x7A, 0x41, 0x5A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x67, 0x54, 0x45, 0x6B, 0x64, 0x79, 0x5A, 0x57, 0x46, 0x30, 0x5A, 0x58, 0x49, 0x67, 0x54, 0x57, 0x46, 0x75, 0x59, 0x32, 0x68, 0x6C, 0x63, 0x33, 0x52, 0x6C, 0x63, 0x6A, ++ 0x45, 0x51, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x78, 0x4D, 0x48, 0x55, 0x32, 0x46, 0x73, 0x5A, 0x6D, 0x39, 0x79, 0x5A, 0x44, 0x45, 0x61, 0x4D, 0x42, 0x67, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x52, 0x0A, 0x51, ++ 0x30, 0x39, 0x4E, 0x54, 0x30, 0x52, 0x50, 0x49, 0x45, 0x4E, 0x42, 0x49, 0x45, 0x78, 0x70, 0x62, 0x57, 0x6C, 0x30, 0x5A, 0x57, 0x51, 0x78, 0x4B, 0x7A, 0x41, 0x70, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x49, 0x6B, 0x4E, 0x50, 0x54, ++ 0x55, 0x39, 0x45, 0x54, 0x79, 0x42, 0x46, 0x51, 0x30, 0x4D, 0x67, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6C, 0x6D, 0x61, 0x57, 0x4E, 0x68, 0x64, 0x47, 0x6C, 0x76, 0x62, 0x69, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6F, 0x0A, 0x62, 0x33, 0x4A, 0x70, ++ 0x64, 0x48, 0x6B, 0x77, 0x64, 0x6A, 0x41, 0x51, 0x42, 0x67, 0x63, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x49, 0x42, 0x42, 0x67, 0x55, 0x72, 0x67, 0x51, 0x51, 0x41, 0x49, 0x67, 0x4E, 0x69, 0x41, 0x41, 0x51, 0x44, 0x52, 0x33, 0x73, 0x76, ++ 0x64, 0x63, 0x6D, 0x43, 0x46, 0x59, 0x58, 0x37, 0x64, 0x65, 0x53, 0x52, 0x46, 0x74, 0x53, 0x72, 0x59, 0x70, 0x6E, 0x31, 0x50, 0x6C, 0x49, 0x4C, 0x42, 0x73, 0x35, 0x42, 0x41, 0x48, 0x2B, 0x58, 0x0A, 0x34, 0x51, 0x6F, 0x6B, 0x50, 0x42, 0x30, ++ 0x42, 0x42, 0x4F, 0x34, 0x39, 0x30, 0x6F, 0x30, 0x4A, 0x6C, 0x77, 0x7A, 0x67, 0x64, 0x65, 0x54, 0x36, 0x2B, 0x33, 0x65, 0x4B, 0x4B, 0x76, 0x55, 0x44, 0x59, 0x45, 0x73, 0x32, 0x69, 0x78, 0x59, 0x6A, 0x46, 0x71, 0x30, 0x4A, 0x63, 0x66, 0x52, ++ 0x4B, 0x39, 0x43, 0x68, 0x51, 0x74, 0x50, 0x36, 0x49, 0x48, 0x47, 0x34, 0x2F, 0x62, 0x43, 0x38, 0x76, 0x43, 0x56, 0x6C, 0x62, 0x70, 0x56, 0x73, 0x4C, 0x4D, 0x35, 0x6E, 0x69, 0x0A, 0x77, 0x7A, 0x32, 0x4A, 0x2B, 0x57, 0x6F, 0x73, 0x37, 0x37, ++ 0x4C, 0x54, 0x42, 0x75, 0x6D, 0x6A, 0x51, 0x6A, 0x42, 0x41, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x52, 0x31, 0x63, 0x61, 0x63, 0x5A, 0x53, 0x42, 0x6D, 0x38, 0x6E, 0x5A, 0x33, 0x71, 0x51, 0x55, ++ 0x66, 0x66, 0x6C, 0x4D, 0x52, 0x49, 0x64, 0x35, 0x6E, 0x54, 0x65, 0x54, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x0A, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x51, 0x59, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, ++ 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x77, 0x4E, 0x6F, 0x41, 0x44, 0x42, 0x6C, 0x41, ++ 0x6A, 0x45, 0x41, 0x37, 0x77, 0x4E, 0x62, 0x65, 0x71, 0x79, 0x33, 0x65, 0x41, 0x70, 0x79, 0x74, 0x34, 0x6A, 0x66, 0x2F, 0x37, 0x56, 0x47, 0x0A, 0x46, 0x41, 0x6B, 0x4B, 0x2B, 0x71, 0x44, 0x6D, 0x66, 0x51, 0x6A, 0x47, 0x47, 0x6F, 0x65, 0x39, ++ 0x47, 0x4B, 0x68, 0x7A, 0x76, 0x53, 0x62, 0x4B, 0x59, 0x41, 0x79, 0x64, 0x7A, 0x70, 0x6D, 0x66, 0x7A, 0x31, 0x77, 0x50, 0x4D, 0x4F, 0x47, 0x2B, 0x46, 0x44, 0x48, 0x71, 0x41, 0x6A, 0x41, 0x55, 0x39, 0x4A, 0x4D, 0x38, 0x53, 0x61, 0x63, 0x7A, ++ 0x65, 0x70, 0x42, 0x47, 0x52, 0x37, 0x4E, 0x6A, 0x66, 0x52, 0x4F, 0x62, 0x54, 0x72, 0x64, 0x76, 0x47, 0x44, 0x65, 0x41, 0x0A, 0x55, 0x2F, 0x37, 0x64, 0x49, 0x4F, 0x41, 0x31, 0x6D, 0x6A, 0x62, 0x52, 0x78, 0x77, 0x47, 0x35, 0x35, 0x74, 0x7A, ++ 0x64, 0x38, 0x2F, 0x38, 0x64, 0x4C, 0x44, 0x6F, 0x57, 0x56, 0x39, 0x6D, 0x53, 0x4F, 0x64, 0x59, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, ++ 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x43, 0x65, 0x72, 0x74, 0x69, 0x67, 0x6E, 0x61, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, ++ 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x44, 0x71, 0x44, 0x43, 0x43, 0x41, 0x70, 0x43, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x4A, 0x41, 0x50, 0x37, 0x63, 0x34, 0x77, 0x45, 0x50, 0x79, ++ 0x55, 0x6A, 0x2F, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x42, 0x51, 0x55, 0x41, 0x4D, 0x44, 0x51, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, ++ 0x6B, 0x5A, 0x53, 0x4D, 0x52, 0x49, 0x77, 0x0A, 0x45, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x44, 0x41, 0x6C, 0x45, 0x61, 0x47, 0x6C, 0x74, 0x65, 0x57, 0x39, 0x30, 0x61, 0x58, 0x4D, 0x78, 0x45, 0x54, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, ++ 0x42, 0x41, 0x4D, 0x4D, 0x43, 0x45, 0x4E, 0x6C, 0x63, 0x6E, 0x52, 0x70, 0x5A, 0x32, 0x35, 0x68, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x41, 0x33, 0x4D, 0x44, 0x59, 0x79, 0x4F, 0x54, 0x45, 0x31, 0x4D, 0x54, 0x4D, 0x77, 0x4E, 0x56, 0x6F, 0x58, ++ 0x44, 0x54, 0x49, 0x33, 0x0A, 0x4D, 0x44, 0x59, 0x79, 0x4F, 0x54, 0x45, 0x31, 0x4D, 0x54, 0x4D, 0x77, 0x4E, 0x56, 0x6F, 0x77, 0x4E, 0x44, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x52, 0x6C, 0x49, ++ 0x78, 0x45, 0x6A, 0x41, 0x51, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x43, 0x55, 0x52, 0x6F, 0x61, 0x57, 0x31, 0x35, 0x62, 0x33, 0x52, 0x70, 0x63, 0x7A, 0x45, 0x52, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, ++ 0x49, 0x0A, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6C, 0x6E, 0x62, 0x6D, 0x45, 0x77, 0x67, 0x67, 0x45, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, ++ 0x49, 0x42, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x45, 0x4B, 0x41, 0x6F, 0x49, 0x42, 0x41, 0x51, 0x44, 0x49, 0x61, 0x50, 0x48, 0x4A, 0x31, 0x74, 0x61, 0x7A, 0x4E, 0x48, 0x55, 0x6D, 0x67, 0x68, 0x37, 0x73, 0x74, 0x4C, 0x37, 0x71, 0x0A, 0x58, ++ 0x4F, 0x45, 0x6D, 0x37, 0x52, 0x46, 0x48, 0x59, 0x65, 0x47, 0x69, 0x66, 0x42, 0x5A, 0x34, 0x51, 0x43, 0x48, 0x6B, 0x59, 0x4A, 0x35, 0x61, 0x79, 0x47, 0x50, 0x68, 0x78, 0x4C, 0x47, 0x57, 0x6B, 0x76, 0x38, 0x59, 0x62, 0x57, 0x6B, 0x6A, 0x34, ++ 0x53, 0x74, 0x69, 0x39, 0x39, 0x33, 0x69, 0x4E, 0x69, 0x2B, 0x52, 0x42, 0x37, 0x6C, 0x49, 0x7A, 0x77, 0x37, 0x73, 0x65, 0x62, 0x59, 0x73, 0x35, 0x7A, 0x52, 0x4C, 0x63, 0x41, 0x67, 0x6C, 0x6F, 0x7A, 0x79, 0x48, 0x0A, 0x47, 0x78, 0x6E, 0x79, ++ 0x67, 0x51, 0x63, 0x50, 0x4F, 0x4A, 0x41, 0x5A, 0x30, 0x78, 0x48, 0x2B, 0x68, 0x72, 0x54, 0x79, 0x30, 0x56, 0x34, 0x65, 0x48, 0x70, 0x62, 0x4E, 0x67, 0x47, 0x7A, 0x4F, 0x4F, 0x7A, 0x47, 0x54, 0x74, 0x76, 0x4B, 0x67, 0x30, 0x4B, 0x6D, 0x56, ++ 0x45, 0x6E, 0x32, 0x6C, 0x6D, 0x73, 0x78, 0x72, 0x79, 0x49, 0x52, 0x57, 0x69, 0x6A, 0x4F, 0x70, 0x35, 0x79, 0x49, 0x56, 0x55, 0x78, 0x62, 0x77, 0x7A, 0x42, 0x66, 0x73, 0x56, 0x31, 0x2F, 0x70, 0x0A, 0x6F, 0x67, 0x71, 0x59, 0x43, 0x64, 0x37, ++ 0x6A, 0x58, 0x35, 0x78, 0x76, 0x33, 0x45, 0x6A, 0x6A, 0x68, 0x51, 0x73, 0x56, 0x57, 0x71, 0x61, 0x36, 0x6E, 0x36, 0x78, 0x49, 0x34, 0x77, 0x6D, 0x79, 0x39, 0x2F, 0x51, 0x79, 0x33, 0x6C, 0x34, 0x30, 0x76, 0x68, 0x78, 0x34, 0x58, 0x55, 0x4A, ++ 0x62, 0x7A, 0x67, 0x34, 0x69, 0x6A, 0x30, 0x32, 0x51, 0x31, 0x33, 0x30, 0x79, 0x47, 0x4C, 0x4D, 0x4C, 0x4C, 0x47, 0x71, 0x2F, 0x6A, 0x6A, 0x38, 0x55, 0x45, 0x59, 0x6B, 0x67, 0x0A, 0x44, 0x6E, 0x63, 0x55, 0x74, 0x54, 0x32, 0x55, 0x43, 0x49, ++ 0x66, 0x33, 0x4A, 0x52, 0x37, 0x56, 0x73, 0x6D, 0x41, 0x41, 0x37, 0x47, 0x38, 0x71, 0x4B, 0x43, 0x56, 0x75, 0x4B, 0x6A, 0x34, 0x59, 0x59, 0x78, 0x63, 0x6C, 0x50, 0x7A, 0x35, 0x45, 0x49, 0x42, 0x62, 0x32, 0x4A, 0x73, 0x67, 0x6C, 0x72, 0x67, ++ 0x56, 0x4B, 0x74, 0x4F, 0x64, 0x6A, 0x4C, 0x50, 0x4F, 0x4D, 0x46, 0x6C, 0x4E, 0x2B, 0x58, 0x50, 0x73, 0x52, 0x47, 0x67, 0x6A, 0x42, 0x52, 0x6D, 0x4B, 0x66, 0x0A, 0x49, 0x72, 0x6A, 0x78, 0x77, 0x6F, 0x31, 0x70, 0x33, 0x50, 0x6F, 0x36, 0x57, ++ 0x41, 0x62, 0x66, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, 0x67, 0x62, 0x77, 0x77, 0x67, 0x62, 0x6B, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, ++ 0x7A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x47, 0x75, 0x33, 0x2B, 0x51, 0x54, 0x6D, 0x51, 0x0A, 0x74, 0x43, 0x52, 0x5A, 0x76, 0x67, 0x48, 0x79, 0x55, 0x74, 0x56, 0x46, 0x39, 0x6C, 0x6F, 0x35, ++ 0x33, 0x42, 0x45, 0x77, 0x5A, 0x41, 0x59, 0x44, 0x56, 0x52, 0x30, 0x6A, 0x42, 0x46, 0x30, 0x77, 0x57, 0x34, 0x41, 0x55, 0x47, 0x75, 0x33, 0x2B, 0x51, 0x54, 0x6D, 0x51, 0x74, 0x43, 0x52, 0x5A, 0x76, 0x67, 0x48, 0x79, 0x55, 0x74, 0x56, 0x46, ++ 0x39, 0x6C, 0x6F, 0x35, 0x33, 0x42, 0x47, 0x68, 0x4F, 0x4B, 0x51, 0x32, 0x4D, 0x44, 0x51, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x0A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x5A, 0x53, 0x4D, 0x52, 0x49, 0x77, 0x45, 0x41, 0x59, ++ 0x44, 0x56, 0x51, 0x51, 0x4B, 0x44, 0x41, 0x6C, 0x45, 0x61, 0x47, 0x6C, 0x74, 0x65, 0x57, 0x39, 0x30, 0x61, 0x58, 0x4D, 0x78, 0x45, 0x54, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x43, 0x45, 0x4E, 0x6C, 0x63, 0x6E, 0x52, ++ 0x70, 0x5A, 0x32, 0x35, 0x68, 0x67, 0x67, 0x6B, 0x41, 0x2F, 0x74, 0x7A, 0x6A, 0x41, 0x51, 0x2F, 0x4A, 0x0A, 0x53, 0x50, 0x38, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, ++ 0x45, 0x47, 0x4D, 0x42, 0x45, 0x47, 0x43, 0x57, 0x43, 0x47, 0x53, 0x41, 0x47, 0x47, 0x2B, 0x45, 0x49, 0x42, 0x41, 0x51, 0x51, 0x45, 0x41, 0x77, 0x49, 0x41, 0x42, 0x7A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, ++ 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x51, 0x45, 0x41, 0x0A, 0x68, 0x51, 0x4D, 0x65, 0x6B, 0x6E, 0x48, 0x32, 0x51, 0x71, 0x2F, 0x68, 0x6F, 0x32, 0x47, 0x65, 0x36, 0x2F, 0x50, 0x41, 0x44, 0x2F, 0x4B, 0x6C, 0x31, ++ 0x4E, 0x71, 0x56, 0x35, 0x74, 0x61, 0x2B, 0x61, 0x44, 0x59, 0x39, 0x66, 0x6D, 0x34, 0x66, 0x54, 0x49, 0x72, 0x76, 0x30, 0x51, 0x38, 0x68, 0x62, 0x56, 0x36, 0x6C, 0x55, 0x6D, 0x50, 0x4F, 0x45, 0x76, 0x6A, 0x76, 0x4B, 0x74, 0x70, 0x76, 0x36, ++ 0x7A, 0x66, 0x2B, 0x45, 0x77, 0x4C, 0x48, 0x79, 0x7A, 0x73, 0x2B, 0x0A, 0x49, 0x6D, 0x76, 0x61, 0x59, 0x53, 0x35, 0x2F, 0x31, 0x48, 0x49, 0x39, 0x33, 0x54, 0x44, 0x68, 0x48, 0x6B, 0x78, 0x41, 0x47, 0x59, 0x77, 0x50, 0x31, 0x35, 0x7A, 0x52, ++ 0x67, 0x7A, 0x42, 0x37, 0x6D, 0x46, 0x6E, 0x63, 0x66, 0x63, 0x61, 0x35, 0x44, 0x43, 0x6C, 0x4D, 0x6F, 0x54, 0x4F, 0x69, 0x36, 0x32, 0x63, 0x36, 0x5A, 0x59, 0x54, 0x54, 0x6C, 0x75, 0x4C, 0x74, 0x64, 0x6B, 0x56, 0x77, 0x6A, 0x37, 0x55, 0x72, ++ 0x33, 0x76, 0x6B, 0x6A, 0x31, 0x6B, 0x6C, 0x75, 0x0A, 0x50, 0x42, 0x53, 0x31, 0x78, 0x70, 0x38, 0x31, 0x48, 0x6C, 0x44, 0x51, 0x77, 0x59, 0x39, 0x71, 0x63, 0x45, 0x51, 0x43, 0x59, 0x73, 0x75, 0x75, 0x48, 0x57, 0x68, 0x42, 0x70, 0x36, 0x70, ++ 0x58, 0x36, 0x46, 0x4F, 0x71, 0x42, 0x39, 0x49, 0x47, 0x39, 0x74, 0x55, 0x55, 0x42, 0x67, 0x75, 0x52, 0x41, 0x33, 0x55, 0x73, 0x62, 0x48, 0x4B, 0x31, 0x59, 0x5A, 0x57, 0x61, 0x44, 0x59, 0x75, 0x35, 0x44, 0x65, 0x66, 0x31, 0x33, 0x31, 0x54, ++ 0x4E, 0x33, 0x75, 0x62, 0x59, 0x0A, 0x31, 0x67, 0x6B, 0x49, 0x6C, 0x32, 0x50, 0x6C, 0x77, 0x53, 0x36, 0x77, 0x74, 0x30, 0x51, 0x6D, 0x77, 0x43, 0x62, 0x41, 0x72, 0x31, 0x55, 0x77, 0x6E, 0x6A, 0x76, 0x56, 0x4E, 0x69, 0x6F, 0x5A, 0x42, 0x50, ++ 0x52, 0x63, 0x48, 0x76, 0x2F, 0x50, 0x4C, 0x4C, 0x66, 0x2F, 0x30, 0x50, 0x32, 0x48, 0x51, 0x42, 0x48, 0x56, 0x45, 0x53, 0x4F, 0x37, 0x53, 0x4D, 0x41, 0x68, 0x71, 0x61, 0x51, 0x6F, 0x4C, 0x66, 0x30, 0x56, 0x2B, 0x4C, 0x42, 0x4F, 0x4B, 0x2F, ++ 0x51, 0x77, 0x0A, 0x57, 0x79, 0x48, 0x38, 0x45, 0x5A, 0x45, 0x30, 0x76, 0x6B, 0x48, 0x76, 0x65, 0x35, 0x32, 0x58, 0x64, 0x66, 0x2B, 0x58, 0x6C, 0x63, 0x43, 0x57, 0x57, 0x43, 0x2F, 0x71, 0x75, 0x30, 0x62, 0x58, 0x75, 0x2B, 0x54, 0x5A, 0x4C, ++ 0x67, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x65, 0x50, 0x4B, 0x49, 0x20, 0x52, 0x6F, 0x6F, 0x74, ++ 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, ++ 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x73, 0x44, 0x43, 0x43, 0x41, 0x35, 0x69, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x46, 0x63, 0x69, 0x39, 0x5A, 0x55, 0x64, 0x63, 0x72, 0x37, 0x69, 0x58, 0x41, ++ 0x46, 0x37, 0x6B, 0x42, 0x74, 0x4B, 0x38, 0x6E, 0x54, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x44, 0x42, 0x65, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, ++ 0x51, 0x51, 0x47, 0x0A, 0x45, 0x77, 0x4A, 0x55, 0x56, 0x7A, 0x45, 0x6A, 0x4D, 0x43, 0x45, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x61, 0x51, 0x32, 0x68, 0x31, 0x62, 0x6D, 0x64, 0x6F, 0x64, 0x32, 0x45, 0x67, 0x56, 0x47, 0x56, 0x73, ++ 0x5A, 0x57, 0x4E, 0x76, 0x62, 0x53, 0x42, 0x44, 0x62, 0x79, 0x34, 0x73, 0x49, 0x45, 0x78, 0x30, 0x5A, 0x43, 0x34, 0x78, 0x4B, 0x6A, 0x41, 0x6F, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x73, 0x4D, 0x49, 0x57, 0x56, 0x51, 0x53, 0x30, 0x6B, 0x67, ++ 0x0A, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x61, 0x57, 0x5A, 0x70, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x49, 0x45, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6D, 0x6C, 0x30, 0x65, 0x54, 0x41, ++ 0x65, 0x46, 0x77, 0x30, 0x77, 0x4E, 0x44, 0x45, 0x79, 0x4D, 0x6A, 0x41, 0x77, 0x4D, 0x6A, 0x4D, 0x78, 0x4D, 0x6A, 0x64, 0x61, 0x46, 0x77, 0x30, 0x7A, 0x4E, 0x44, 0x45, 0x79, 0x4D, 0x6A, 0x41, 0x77, 0x4D, 0x6A, 0x4D, 0x78, 0x0A, 0x4D, 0x6A, ++ 0x64, 0x61, 0x4D, 0x46, 0x34, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6C, 0x52, 0x58, 0x4D, 0x53, 0x4D, 0x77, 0x49, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x44, 0x42, 0x70, 0x44, 0x61, 0x48, ++ 0x56, 0x75, 0x5A, 0x32, 0x68, 0x33, 0x59, 0x53, 0x42, 0x55, 0x5A, 0x57, 0x78, 0x6C, 0x59, 0x32, 0x39, 0x74, 0x49, 0x45, 0x4E, 0x76, 0x4C, 0x69, 0x77, 0x67, 0x54, 0x48, 0x52, 0x6B, 0x4C, 0x6A, 0x45, 0x71, 0x0A, 0x4D, 0x43, 0x67, 0x47, 0x41, ++ 0x31, 0x55, 0x45, 0x43, 0x77, 0x77, 0x68, 0x5A, 0x56, 0x42, 0x4C, 0x53, 0x53, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x6C, 0x63, 0x6E, 0x52, 0x70, 0x5A, 0x6D, 0x6C, 0x6A, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x67, 0x51, ++ 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52, 0x35, 0x4D, 0x49, 0x49, 0x43, 0x49, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x0A, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x4F, 0x43, ++ 0x41, 0x67, 0x38, 0x41, 0x4D, 0x49, 0x49, 0x43, 0x43, 0x67, 0x4B, 0x43, 0x41, 0x67, 0x45, 0x41, 0x34, 0x53, 0x55, 0x50, 0x37, 0x6F, 0x33, 0x62, 0x69, 0x44, 0x4E, 0x31, 0x5A, 0x38, 0x32, 0x74, 0x48, 0x33, 0x30, 0x36, 0x54, 0x6D, 0x32, 0x64, ++ 0x30, 0x79, 0x38, 0x55, 0x38, 0x32, 0x4E, 0x30, 0x79, 0x77, 0x45, 0x68, 0x61, 0x6A, 0x66, 0x71, 0x68, 0x46, 0x41, 0x48, 0x53, 0x79, 0x5A, 0x62, 0x43, 0x55, 0x4E, 0x73, 0x0A, 0x49, 0x5A, 0x35, 0x71, 0x79, 0x4E, 0x55, 0x44, 0x39, 0x57, 0x42, ++ 0x70, 0x6A, 0x38, 0x7A, 0x77, 0x49, 0x75, 0x51, 0x66, 0x35, 0x2F, 0x64, 0x71, 0x49, 0x6A, 0x47, 0x33, 0x4C, 0x42, 0x58, 0x79, 0x34, 0x50, 0x34, 0x41, 0x61, 0x6B, 0x50, 0x2F, 0x68, 0x32, 0x58, 0x47, 0x74, 0x52, 0x72, 0x42, 0x70, 0x30, 0x78, ++ 0x74, 0x49, 0x6E, 0x41, 0x68, 0x69, 0x6A, 0x48, 0x79, 0x6C, 0x33, 0x53, 0x4A, 0x43, 0x52, 0x49, 0x6D, 0x48, 0x4A, 0x37, 0x4B, 0x32, 0x52, 0x4B, 0x69, 0x0A, 0x6C, 0x54, 0x7A, 0x61, 0x36, 0x57, 0x65, 0x2F, 0x43, 0x4B, 0x42, 0x6B, 0x34, 0x39, ++ 0x5A, 0x43, 0x74, 0x30, 0x58, 0x76, 0x6C, 0x2F, 0x54, 0x32, 0x39, 0x64, 0x65, 0x31, 0x53, 0x68, 0x55, 0x43, 0x57, 0x48, 0x32, 0x59, 0x57, 0x45, 0x74, 0x67, 0x76, 0x4D, 0x33, 0x58, 0x44, 0x5A, 0x6F, 0x54, 0x4D, 0x31, 0x50, 0x52, 0x59, 0x66, ++ 0x6C, 0x36, 0x31, 0x64, 0x64, 0x34, 0x73, 0x35, 0x6F, 0x7A, 0x39, 0x77, 0x43, 0x47, 0x7A, 0x68, 0x31, 0x4E, 0x6C, 0x44, 0x69, 0x76, 0x0A, 0x71, 0x4F, 0x78, 0x34, 0x55, 0x58, 0x43, 0x4B, 0x58, 0x42, 0x43, 0x44, 0x55, 0x53, 0x48, 0x33, 0x45, ++ 0x54, 0x30, 0x30, 0x68, 0x6C, 0x37, 0x6C, 0x53, 0x4D, 0x32, 0x58, 0x67, 0x59, 0x49, 0x31, 0x54, 0x42, 0x6E, 0x73, 0x5A, 0x66, 0x5A, 0x72, 0x78, 0x51, 0x57, 0x68, 0x37, 0x6B, 0x63, 0x54, 0x31, 0x72, 0x4D, 0x68, 0x4A, 0x35, 0x51, 0x51, 0x43, ++ 0x74, 0x6B, 0x6B, 0x4F, 0x37, 0x71, 0x2B, 0x52, 0x42, 0x4E, 0x47, 0x4D, 0x44, 0x2B, 0x58, 0x50, 0x4E, 0x6A, 0x58, 0x0A, 0x31, 0x32, 0x72, 0x75, 0x4F, 0x7A, 0x6A, 0x6A, 0x4B, 0x39, 0x53, 0x58, 0x44, 0x72, 0x6B, 0x62, 0x35, 0x77, 0x64, 0x4A, ++ 0x66, 0x7A, 0x63, 0x71, 0x2B, 0x58, 0x64, 0x34, 0x7A, 0x31, 0x54, 0x74, 0x57, 0x30, 0x61, 0x64, 0x6F, 0x34, 0x41, 0x4F, 0x6B, 0x55, 0x50, 0x42, 0x31, 0x6C, 0x74, 0x66, 0x46, 0x4C, 0x71, 0x66, 0x70, 0x6F, 0x30, 0x6B, 0x52, 0x30, 0x42, 0x5A, ++ 0x76, 0x33, 0x49, 0x34, 0x73, 0x6A, 0x5A, 0x73, 0x4E, 0x2F, 0x2B, 0x5A, 0x30, 0x56, 0x30, 0x4F, 0x0A, 0x57, 0x51, 0x71, 0x72, 0x61, 0x66, 0x66, 0x41, 0x73, 0x67, 0x52, 0x46, 0x65, 0x6C, 0x51, 0x41, 0x72, 0x72, 0x35, 0x54, 0x39, 0x72, 0x58, ++ 0x6E, 0x34, 0x66, 0x67, 0x38, 0x6F, 0x7A, 0x48, 0x53, 0x71, 0x66, 0x34, 0x68, 0x55, 0x6D, 0x54, 0x46, 0x70, 0x6D, 0x66, 0x77, 0x64, 0x51, 0x63, 0x47, 0x6C, 0x42, 0x53, 0x42, 0x56, 0x63, 0x59, 0x6E, 0x35, 0x41, 0x47, 0x50, 0x46, 0x38, 0x46, ++ 0x71, 0x63, 0x64, 0x65, 0x2B, 0x53, 0x2F, 0x75, 0x55, 0x57, 0x48, 0x31, 0x2B, 0x0A, 0x45, 0x54, 0x4F, 0x78, 0x51, 0x76, 0x64, 0x69, 0x62, 0x42, 0x6A, 0x57, 0x7A, 0x77, 0x6C, 0x6F, 0x50, 0x6E, 0x39, 0x73, 0x39, 0x68, 0x36, 0x50, 0x59, 0x71, ++ 0x32, 0x6C, 0x59, 0x39, 0x73, 0x4A, 0x70, 0x78, 0x38, 0x69, 0x51, 0x6B, 0x45, 0x65, 0x62, 0x35, 0x6D, 0x4B, 0x50, 0x74, 0x66, 0x35, 0x50, 0x30, 0x42, 0x36, 0x65, 0x62, 0x43, 0x6C, 0x41, 0x5A, 0x4C, 0x53, 0x6E, 0x54, 0x30, 0x49, 0x46, 0x61, ++ 0x55, 0x51, 0x41, 0x53, 0x32, 0x7A, 0x4D, 0x6E, 0x61, 0x6F, 0x0A, 0x6C, 0x51, 0x32, 0x7A, 0x65, 0x70, 0x72, 0x37, 0x42, 0x78, 0x42, 0x34, 0x45, 0x57, 0x2F, 0x68, 0x6A, 0x38, 0x65, 0x36, 0x44, 0x79, 0x55, 0x61, 0x64, 0x43, 0x72, 0x6C, 0x48, ++ 0x4A, 0x68, 0x42, 0x6D, 0x64, 0x38, 0x68, 0x68, 0x2B, 0x69, 0x56, 0x42, 0x6D, 0x6F, 0x4B, 0x73, 0x32, 0x70, 0x48, 0x64, 0x6D, 0x58, 0x32, 0x4F, 0x73, 0x2B, 0x50, 0x59, 0x68, 0x63, 0x5A, 0x65, 0x77, 0x6F, 0x6F, 0x7A, 0x52, 0x72, 0x53, 0x67, ++ 0x78, 0x34, 0x68, 0x78, 0x79, 0x79, 0x2F, 0x0A, 0x76, 0x76, 0x39, 0x68, 0x61, 0x4C, 0x64, 0x6E, 0x47, 0x37, 0x74, 0x34, 0x54, 0x59, 0x33, 0x4F, 0x5A, 0x2B, 0x58, 0x6B, 0x77, 0x59, 0x36, 0x33, 0x49, 0x32, 0x62, 0x69, 0x6E, 0x5A, 0x42, 0x31, ++ 0x4E, 0x4A, 0x69, 0x70, 0x4E, 0x69, 0x75, 0x4B, 0x6D, 0x70, 0x53, 0x35, 0x6E, 0x65, 0x7A, 0x4D, 0x69, 0x72, 0x48, 0x34, 0x4A, 0x59, 0x6C, 0x63, 0x57, 0x72, 0x59, 0x76, 0x6A, 0x42, 0x39, 0x74, 0x65, 0x53, 0x53, 0x6E, 0x55, 0x6D, 0x6A, 0x44, ++ 0x68, 0x44, 0x58, 0x69, 0x0A, 0x5A, 0x6F, 0x31, 0x6A, 0x44, 0x69, 0x56, 0x4E, 0x31, 0x52, 0x6D, 0x79, 0x35, 0x6E, 0x6B, 0x33, 0x70, 0x79, 0x4B, 0x64, 0x56, 0x44, 0x45, 0x43, 0x41, 0x77, 0x45, 0x41, 0x41, 0x61, 0x4E, 0x71, 0x4D, 0x47, 0x67, ++ 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x46, 0x42, 0x34, 0x4D, 0x39, 0x37, 0x5A, 0x6E, 0x38, 0x75, 0x47, 0x53, 0x4A, 0x67, 0x6C, 0x46, 0x77, 0x46, 0x55, 0x35, 0x4C, 0x6E, 0x63, 0x2F, 0x51, 0x6B, 0x71, ++ 0x69, 0x0A, 0x4D, 0x41, 0x77, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x4F, 0x51, 0x59, 0x45, 0x5A, 0x79, 0x6F, 0x48, 0x41, 0x41, 0x51, 0x78, 0x4D, 0x43, 0x38, 0x77, 0x4C, 0x51, ++ 0x49, 0x42, 0x41, 0x44, 0x41, 0x4A, 0x42, 0x67, 0x55, 0x72, 0x44, 0x67, 0x4D, 0x43, 0x47, 0x67, 0x55, 0x41, 0x4D, 0x41, 0x63, 0x47, 0x42, 0x57, 0x63, 0x71, 0x41, 0x77, 0x41, 0x41, 0x42, 0x42, 0x52, 0x46, 0x73, 0x4D, 0x4C, 0x48, 0x0A, 0x43, ++ 0x6C, 0x5A, 0x38, 0x37, 0x6C, 0x74, 0x34, 0x44, 0x4A, 0x58, 0x35, 0x47, 0x46, 0x50, 0x42, 0x70, 0x68, 0x7A, 0x59, 0x45, 0x44, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, ++ 0x41, 0x4F, 0x43, 0x41, 0x67, 0x45, 0x41, 0x43, 0x62, 0x4F, 0x44, 0x55, 0x31, 0x6B, 0x42, 0x50, 0x70, 0x56, 0x4A, 0x75, 0x66, 0x47, 0x42, 0x75, 0x76, 0x6C, 0x32, 0x49, 0x43, 0x4F, 0x31, 0x4A, 0x32, 0x42, 0x30, 0x0A, 0x31, 0x47, 0x71, 0x5A, ++ 0x4E, 0x46, 0x35, 0x73, 0x41, 0x46, 0x50, 0x5A, 0x6E, 0x2F, 0x4B, 0x6D, 0x73, 0x53, 0x51, 0x48, 0x52, 0x47, 0x6F, 0x71, 0x78, 0x71, 0x57, 0x4F, 0x65, 0x42, 0x4C, 0x6F, 0x52, 0x39, 0x6C, 0x59, 0x47, 0x78, 0x4D, 0x71, 0x58, 0x6E, 0x6D, 0x62, ++ 0x6E, 0x77, 0x6F, 0x71, 0x5A, 0x36, 0x59, 0x6C, 0x50, 0x77, 0x5A, 0x70, 0x56, 0x6E, 0x50, 0x44, 0x69, 0x6D, 0x5A, 0x49, 0x2B, 0x79, 0x6D, 0x42, 0x56, 0x33, 0x51, 0x47, 0x79, 0x70, 0x7A, 0x71, 0x0A, 0x4B, 0x4F, 0x67, 0x34, 0x5A, 0x79, 0x59, ++ 0x72, 0x38, 0x64, 0x57, 0x31, 0x50, 0x32, 0x57, 0x54, 0x2B, 0x44, 0x5A, 0x64, 0x6A, 0x6F, 0x32, 0x4E, 0x51, 0x43, 0x43, 0x48, 0x47, 0x65, 0x72, 0x76, 0x4A, 0x38, 0x41, 0x39, 0x74, 0x44, 0x6B, 0x50, 0x4A, 0x58, 0x74, 0x6F, 0x55, 0x48, 0x52, ++ 0x56, 0x6E, 0x41, 0x78, 0x5A, 0x66, 0x56, 0x6F, 0x39, 0x51, 0x5A, 0x51, 0x6C, 0x55, 0x67, 0x6A, 0x67, 0x52, 0x79, 0x77, 0x56, 0x4D, 0x52, 0x6E, 0x56, 0x76, 0x77, 0x64, 0x56, 0x0A, 0x78, 0x72, 0x73, 0x53, 0x74, 0x5A, 0x66, 0x30, 0x58, 0x34, ++ 0x4F, 0x46, 0x75, 0x6E, 0x48, 0x42, 0x32, 0x57, 0x79, 0x42, 0x45, 0x58, 0x59, 0x4B, 0x43, 0x72, 0x43, 0x2F, 0x67, 0x70, 0x66, 0x33, 0x36, 0x6A, 0x33, 0x36, 0x2B, 0x75, 0x77, 0x74, 0x71, 0x53, 0x69, 0x55, 0x4F, 0x31, 0x62, 0x64, 0x30, 0x6C, ++ 0x45, 0x75, 0x72, 0x73, 0x43, 0x39, 0x43, 0x42, 0x57, 0x4D, 0x64, 0x31, 0x49, 0x30, 0x6C, 0x74, 0x61, 0x62, 0x72, 0x4E, 0x4D, 0x64, 0x6A, 0x6D, 0x45, 0x50, 0x0A, 0x4E, 0x58, 0x75, 0x62, 0x72, 0x6A, 0x6C, 0x70, 0x43, 0x32, 0x4A, 0x67, 0x51, ++ 0x43, 0x41, 0x32, 0x6A, 0x36, 0x2F, 0x37, 0x4E, 0x75, 0x34, 0x74, 0x43, 0x45, 0x6F, 0x64, 0x75, 0x4C, 0x2B, 0x62, 0x58, 0x50, 0x6A, 0x71, 0x70, 0x52, 0x75, 0x67, 0x63, 0x36, 0x62, 0x59, 0x2B, 0x47, 0x37, 0x67, 0x4D, 0x77, 0x52, 0x66, 0x61, ++ 0x4B, 0x6F, 0x6E, 0x68, 0x2B, 0x33, 0x5A, 0x77, 0x5A, 0x43, 0x63, 0x37, 0x62, 0x33, 0x6A, 0x61, 0x6A, 0x57, 0x76, 0x59, 0x39, 0x2B, 0x72, 0x0A, 0x47, 0x4E, 0x6D, 0x36, 0x35, 0x75, 0x6C, 0x4B, 0x36, 0x6C, 0x43, 0x4B, 0x44, 0x32, 0x47, 0x54, ++ 0x48, 0x75, 0x49, 0x74, 0x47, 0x65, 0x49, 0x77, 0x6C, 0x44, 0x57, 0x53, 0x58, 0x51, 0x36, 0x32, 0x42, 0x36, 0x38, 0x5A, 0x67, 0x49, 0x39, 0x48, 0x6B, 0x46, 0x46, 0x4C, 0x4C, 0x6B, 0x33, 0x64, 0x68, 0x65, 0x4C, 0x53, 0x43, 0x6C, 0x49, 0x4B, ++ 0x46, 0x35, 0x72, 0x38, 0x47, 0x72, 0x42, 0x51, 0x41, 0x75, 0x55, 0x42, 0x6F, 0x32, 0x4D, 0x33, 0x49, 0x55, 0x78, 0x45, 0x0A, 0x78, 0x4A, 0x74, 0x52, 0x6D, 0x52, 0x45, 0x4F, 0x63, 0x35, 0x77, 0x47, 0x6A, 0x31, 0x51, 0x75, 0x70, 0x79, 0x68, ++ 0x65, 0x52, 0x44, 0x6D, 0x48, 0x56, 0x69, 0x30, 0x33, 0x76, 0x59, 0x56, 0x45, 0x6C, 0x4F, 0x45, 0x4D, 0x53, 0x79, 0x79, 0x63, 0x77, 0x35, 0x4B, 0x46, 0x4E, 0x47, 0x48, 0x4C, 0x44, 0x37, 0x69, 0x62, 0x53, 0x6B, 0x4E, 0x53, 0x2F, 0x6A, 0x51, ++ 0x36, 0x66, 0x62, 0x6A, 0x70, 0x4B, 0x64, 0x78, 0x32, 0x71, 0x63, 0x67, 0x77, 0x2B, 0x42, 0x52, 0x78, 0x0A, 0x67, 0x4D, 0x59, 0x65, 0x4E, 0x6B, 0x68, 0x30, 0x49, 0x6B, 0x46, 0x63, 0x68, 0x34, 0x4C, 0x6F, 0x47, 0x48, 0x47, 0x4C, 0x51, 0x59, ++ 0x6C, 0x45, 0x35, 0x33, 0x35, 0x59, 0x57, 0x36, 0x69, 0x34, 0x6A, 0x52, 0x50, 0x70, 0x70, 0x32, 0x7A, 0x44, 0x52, 0x2B, 0x32, 0x7A, 0x47, 0x70, 0x31, 0x69, 0x72, 0x6F, 0x32, 0x43, 0x36, 0x70, 0x53, 0x65, 0x33, 0x56, 0x6B, 0x51, 0x77, 0x36, ++ 0x33, 0x64, 0x34, 0x6B, 0x33, 0x6A, 0x4D, 0x64, 0x58, 0x48, 0x37, 0x4F, 0x6A, 0x79, 0x0A, 0x73, 0x50, 0x36, 0x53, 0x48, 0x68, 0x59, 0x4B, 0x47, 0x76, 0x7A, 0x5A, 0x38, 0x2F, 0x67, 0x6E, 0x74, 0x73, 0x6D, 0x2B, 0x48, 0x62, 0x52, 0x73, 0x5A, ++ 0x4A, 0x42, 0x2F, 0x39, 0x4F, 0x54, 0x45, 0x57, 0x39, 0x63, 0x33, 0x72, 0x6B, 0x49, 0x4F, 0x33, 0x61, 0x51, 0x61, 0x62, 0x33, 0x79, 0x49, 0x56, 0x4D, 0x55, 0x57, 0x62, 0x75, 0x46, 0x36, 0x61, 0x43, 0x37, 0x34, 0x4F, 0x72, 0x38, 0x4E, 0x70, ++ 0x44, 0x79, 0x4A, 0x4F, 0x33, 0x69, 0x6E, 0x54, 0x6D, 0x4F, 0x44, 0x0A, 0x42, 0x43, 0x45, 0x49, 0x5A, 0x34, 0x33, 0x79, 0x67, 0x6B, 0x6E, 0x51, 0x57, 0x2F, 0x32, 0x78, 0x7A, 0x51, 0x2B, 0x44, 0x68, 0x4E, 0x51, 0x2B, 0x49, 0x49, 0x58, 0x33, ++ 0x53, 0x6A, 0x30, 0x72, 0x6E, 0x50, 0x30, 0x71, 0x43, 0x67, 0x6C, 0x4E, 0x36, 0x6F, 0x48, 0x34, 0x45, 0x5A, 0x77, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, ++ 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x63, 0x65, 0x72, 0x74, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x20, 0x43, 0x41, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x44, 0x4F, 0x44, 0x43, 0x43, 0x41, 0x69, ++ 0x43, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x47, 0x49, 0x41, 0x59, 0x46, 0x46, 0x6E, 0x41, 0x43, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x42, 0x51, 0x55, 0x41, 0x4D, 0x44, ++ 0x73, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6C, 0x4A, 0x50, 0x4D, 0x52, 0x45, 0x77, 0x44, 0x77, 0x59, 0x44, 0x0A, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x77, 0x68, 0x6A, 0x5A, 0x58, 0x4A, 0x30, 0x55, ++ 0x30, 0x6C, 0x48, 0x54, 0x6A, 0x45, 0x5A, 0x4D, 0x42, 0x63, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4D, 0x51, 0x59, 0x32, 0x56, 0x79, 0x64, 0x46, 0x4E, 0x4A, 0x52, 0x30, 0x34, 0x67, 0x55, 0x6B, 0x39, 0x50, 0x56, 0x43, 0x42, 0x44, 0x51, ++ 0x54, 0x41, 0x65, 0x46, 0x77, 0x30, 0x77, 0x4E, 0x6A, 0x41, 0x33, 0x4D, 0x44, 0x51, 0x78, 0x4E, 0x7A, 0x49, 0x77, 0x4D, 0x44, 0x52, 0x61, 0x0A, 0x46, 0x77, 0x30, 0x7A, 0x4D, 0x54, 0x41, 0x33, 0x4D, 0x44, 0x51, 0x78, 0x4E, 0x7A, 0x49, 0x77, ++ 0x4D, 0x44, 0x52, 0x61, 0x4D, 0x44, 0x73, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6C, 0x4A, 0x50, 0x4D, 0x52, 0x45, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x77, 0x68, 0x6A, ++ 0x5A, 0x58, 0x4A, 0x30, 0x55, 0x30, 0x6C, 0x48, 0x54, 0x6A, 0x45, 0x5A, 0x4D, 0x42, 0x63, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0A, 0x43, 0x78, 0x4D, 0x51, 0x59, 0x32, 0x56, 0x79, 0x64, 0x46, 0x4E, 0x4A, 0x52, 0x30, 0x34, 0x67, 0x55, 0x6B, 0x39, ++ 0x50, 0x56, 0x43, 0x42, 0x44, 0x51, 0x54, 0x43, 0x43, 0x41, 0x53, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x50, 0x41, 0x44, 0x43, ++ 0x43, 0x41, 0x51, 0x6F, 0x43, 0x67, 0x67, 0x45, 0x42, 0x41, 0x4C, 0x63, 0x7A, 0x75, 0x58, 0x37, 0x49, 0x0A, 0x4A, 0x55, 0x71, 0x4F, 0x74, 0x64, 0x75, 0x30, 0x4B, 0x42, 0x75, 0x71, 0x56, 0x35, 0x44, 0x6F, 0x30, 0x53, 0x4C, 0x54, 0x5A, 0x4C, ++ 0x72, 0x54, 0x6B, 0x2B, 0x6A, 0x55, 0x72, 0x49, 0x5A, 0x68, 0x51, 0x47, 0x70, 0x67, 0x56, 0x32, 0x68, 0x55, 0x68, 0x45, 0x32, 0x38, 0x61, 0x6C, 0x51, 0x43, 0x42, 0x66, 0x2F, 0x66, 0x6D, 0x35, 0x6F, 0x71, 0x72, 0x6C, 0x30, 0x48, 0x6A, 0x30, ++ 0x72, 0x44, 0x4B, 0x48, 0x2F, 0x76, 0x2B, 0x79, 0x76, 0x36, 0x65, 0x66, 0x48, 0x48, 0x0A, 0x72, 0x66, 0x41, 0x51, 0x55, 0x79, 0x53, 0x51, 0x69, 0x32, 0x62, 0x4A, 0x71, 0x49, 0x69, 0x72, 0x72, 0x31, 0x71, 0x6A, 0x41, 0x4F, 0x6D, 0x2B, 0x75, ++ 0x6B, 0x62, 0x75, 0x57, 0x33, 0x4E, 0x37, 0x4C, 0x42, 0x65, 0x43, 0x67, 0x56, 0x35, 0x69, 0x4C, 0x4B, 0x45, 0x43, 0x5A, 0x62, 0x4F, 0x39, 0x78, 0x53, 0x73, 0x41, 0x66, 0x73, 0x54, 0x38, 0x41, 0x7A, 0x4E, 0x58, 0x44, 0x65, 0x33, 0x69, 0x2B, ++ 0x73, 0x35, 0x64, 0x52, 0x64, 0x59, 0x34, 0x7A, 0x54, 0x57, 0x32, 0x0A, 0x73, 0x73, 0x48, 0x51, 0x6E, 0x49, 0x46, 0x4B, 0x71, 0x75, 0x53, 0x79, 0x41, 0x56, 0x77, 0x64, 0x6A, 0x31, 0x2B, 0x5A, 0x78, 0x4C, 0x47, 0x74, 0x32, 0x34, 0x67, 0x68, ++ 0x36, 0x35, 0x41, 0x49, 0x67, 0x6F, 0x44, 0x7A, 0x4D, 0x4B, 0x4E, 0x44, 0x35, 0x70, 0x43, 0x43, 0x72, 0x6C, 0x55, 0x6F, 0x53, 0x65, 0x31, 0x62, 0x31, 0x36, 0x6B, 0x51, 0x4F, 0x41, 0x37, 0x2B, 0x6A, 0x30, 0x78, 0x62, 0x6D, 0x30, 0x62, 0x71, ++ 0x51, 0x66, 0x57, 0x77, 0x43, 0x48, 0x54, 0x44, 0x0A, 0x30, 0x49, 0x67, 0x7A, 0x74, 0x6E, 0x7A, 0x58, 0x64, 0x4E, 0x2F, 0x63, 0x68, 0x4E, 0x46, 0x44, 0x44, 0x6E, 0x55, 0x35, 0x6F, 0x53, 0x56, 0x41, 0x4B, 0x4F, 0x70, 0x34, 0x79, 0x77, 0x34, ++ 0x73, 0x4C, 0x6A, 0x6D, 0x64, 0x6A, 0x49, 0x74, 0x75, 0x46, 0x68, 0x77, 0x76, 0x4A, 0x6F, 0x49, 0x51, 0x34, 0x75, 0x4E, 0x6C, 0x6C, 0x41, 0x6F, 0x45, 0x77, 0x46, 0x37, 0x33, 0x58, 0x56, 0x76, 0x34, 0x45, 0x4F, 0x4C, 0x51, 0x75, 0x6E, 0x70, ++ 0x4C, 0x2B, 0x39, 0x34, 0x33, 0x0A, 0x41, 0x41, 0x41, 0x61, 0x57, 0x79, 0x6A, 0x6A, 0x30, 0x70, 0x78, 0x7A, 0x50, 0x6A, 0x4B, 0x48, 0x6D, 0x4B, 0x48, 0x4A, 0x55, 0x53, 0x2F, 0x58, 0x33, 0x71, 0x77, 0x7A, 0x73, 0x30, 0x38, 0x43, 0x41, 0x77, ++ 0x45, 0x41, 0x41, 0x61, 0x4E, 0x43, 0x4D, 0x45, 0x41, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, ++ 0x38, 0x42, 0x0A, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x63, 0x59, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x46, 0x4F, 0x43, 0x4D, 0x6D, 0x39, 0x73, 0x6C, 0x53, 0x62, 0x50, 0x78, 0x66, ++ 0x49, 0x62, 0x57, 0x73, 0x6B, 0x4B, 0x48, 0x43, 0x39, 0x42, 0x72, 0x6F, 0x4E, 0x6E, 0x6B, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x42, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x0A, ++ 0x41, 0x51, 0x41, 0x2B, 0x30, 0x68, 0x79, 0x4A, 0x4C, 0x6A, 0x58, 0x38, 0x2B, 0x48, 0x58, 0x64, 0x35, 0x6E, 0x39, 0x6C, 0x69, 0x50, 0x52, 0x79, 0x54, 0x4D, 0x6B, 0x73, 0x31, 0x7A, 0x4A, 0x4F, 0x38, 0x39, 0x30, 0x5A, 0x65, 0x55, 0x65, 0x39, ++ 0x6A, 0x6A, 0x74, 0x62, 0x6B, 0x77, 0x39, 0x51, 0x53, 0x53, 0x51, 0x54, 0x61, 0x78, 0x51, 0x47, 0x63, 0x75, 0x38, 0x4A, 0x30, 0x36, 0x47, 0x68, 0x34, 0x30, 0x43, 0x45, 0x79, 0x65, 0x63, 0x59, 0x4D, 0x6E, 0x51, 0x38, 0x0A, 0x53, 0x47, 0x34, ++ 0x50, 0x6E, 0x30, 0x76, 0x55, 0x39, 0x78, 0x37, 0x54, 0x6B, 0x34, 0x5A, 0x6B, 0x56, 0x4A, 0x64, 0x6A, 0x63, 0x6C, 0x44, 0x56, 0x56, 0x63, 0x2F, 0x36, 0x49, 0x4A, 0x4D, 0x43, 0x6F, 0x70, 0x76, 0x44, 0x49, 0x35, 0x4E, 0x4F, 0x46, 0x6C, 0x56, ++ 0x32, 0x6F, 0x48, 0x42, 0x35, 0x62, 0x63, 0x30, 0x68, 0x48, 0x38, 0x38, 0x76, 0x4C, 0x62, 0x77, 0x5A, 0x34, 0x34, 0x67, 0x78, 0x2B, 0x46, 0x6B, 0x61, 0x67, 0x51, 0x6E, 0x49, 0x6C, 0x36, 0x5A, 0x30, 0x0A, 0x78, 0x32, 0x44, 0x45, 0x57, 0x38, ++ 0x78, 0x58, 0x6A, 0x72, 0x4A, 0x31, 0x2F, 0x52, 0x73, 0x43, 0x43, 0x64, 0x74, 0x5A, 0x62, 0x33, 0x4B, 0x54, 0x61, 0x66, 0x63, 0x78, 0x51, 0x64, 0x61, 0x49, 0x4F, 0x4C, 0x2B, 0x48, 0x73, 0x72, 0x30, 0x57, 0x65, 0x66, 0x6D, 0x71, 0x35, 0x4C, ++ 0x36, 0x49, 0x4A, 0x64, 0x31, 0x68, 0x4A, 0x79, 0x4D, 0x63, 0x74, 0x54, 0x45, 0x48, 0x42, 0x44, 0x61, 0x30, 0x47, 0x70, 0x43, 0x39, 0x6F, 0x48, 0x52, 0x78, 0x55, 0x49, 0x6C, 0x74, 0x0A, 0x76, 0x42, 0x54, 0x6A, 0x44, 0x34, 0x61, 0x75, 0x38, ++ 0x61, 0x73, 0x2B, 0x78, 0x36, 0x41, 0x4A, 0x7A, 0x4B, 0x4E, 0x49, 0x30, 0x65, 0x44, 0x62, 0x5A, 0x4F, 0x65, 0x53, 0x74, 0x63, 0x2B, 0x76, 0x63, 0x6B, 0x4E, 0x77, 0x69, 0x2F, 0x6E, 0x44, 0x68, 0x44, 0x77, 0x54, 0x71, 0x6E, 0x36, 0x53, 0x6D, ++ 0x31, 0x64, 0x54, 0x6B, 0x2F, 0x70, 0x77, 0x77, 0x70, 0x45, 0x4F, 0x4D, 0x66, 0x6D, 0x62, 0x5A, 0x31, 0x33, 0x70, 0x6C, 0x6A, 0x68, 0x65, 0x58, 0x37, 0x4E, 0x7A, 0x0A, 0x54, 0x6F, 0x67, 0x56, 0x5A, 0x39, 0x36, 0x65, 0x64, 0x68, 0x42, 0x69, ++ 0x49, 0x4C, 0x35, 0x56, 0x61, 0x5A, 0x56, 0x44, 0x41, 0x44, 0x6C, 0x4E, 0x39, 0x75, 0x36, 0x77, 0x57, 0x6B, 0x35, 0x4A, 0x52, 0x46, 0x52, 0x59, 0x58, 0x30, 0x4B, 0x44, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, ++ 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x4E, 0x65, 0x74, 0x4C, 0x6F, 0x63, 0x6B, 0x20, 0x41, 0x72, 0x61, 0x6E, 0x79, 0x20, 0x28, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x47, 0x6F, 0x6C, ++ 0x64, 0x29, 0x20, 0x46, 0xC5, 0x91, 0x74, 0x61, 0x6E, 0xC3, 0xBA, 0x73, 0xC3, 0xAD, 0x74, 0x76, 0xC3, 0xA1, 0x6E, 0x79, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, ++ 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x45, 0x46, 0x54, 0x43, 0x43, 0x41, 0x76, 0x32, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x47, 0x53, 0x55, 0x45, 0x73, 0x35, 0x41, 0x41, 0x51, 0x4D, 0x41, ++ 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43, 0x77, 0x55, 0x41, 0x4D, 0x49, 0x47, 0x6E, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x49, 0x56, 0x54, ++ 0x45, 0x52, 0x4D, 0x41, 0x38, 0x47, 0x0A, 0x41, 0x31, 0x55, 0x45, 0x42, 0x77, 0x77, 0x49, 0x51, 0x6E, 0x56, 0x6B, 0x59, 0x58, 0x42, 0x6C, 0x63, 0x33, 0x51, 0x78, 0x46, 0x54, 0x41, 0x54, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x44, ++ 0x45, 0x35, 0x6C, 0x64, 0x45, 0x78, 0x76, 0x59, 0x32, 0x73, 0x67, 0x53, 0x32, 0x5A, 0x30, 0x4C, 0x6A, 0x45, 0x33, 0x4D, 0x44, 0x55, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x77, 0x77, 0x75, 0x56, 0x47, 0x46, 0x75, 0x77, 0x37, 0x70, 0x7A, 0x77, ++ 0x36, 0x31, 0x30, 0x0A, 0x64, 0x73, 0x4F, 0x68, 0x62, 0x6E, 0x6C, 0x72, 0x61, 0x57, 0x46, 0x6B, 0x77, 0x37, 0x4E, 0x72, 0x49, 0x43, 0x68, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x61, 0x57, 0x5A, 0x70, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, ++ 0x49, 0x46, 0x4E, 0x6C, 0x63, 0x6E, 0x5A, 0x70, 0x59, 0x32, 0x56, 0x7A, 0x4B, 0x54, 0x45, 0x31, 0x4D, 0x44, 0x4D, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x73, 0x54, 0x6D, 0x56, 0x30, 0x54, 0x47, 0x39, 0x6A, 0x61, 0x79, 0x42, 0x42, ++ 0x0A, 0x63, 0x6D, 0x46, 0x75, 0x65, 0x53, 0x41, 0x6F, 0x51, 0x32, 0x78, 0x68, 0x63, 0x33, 0x4D, 0x67, 0x52, 0x32, 0x39, 0x73, 0x5A, 0x43, 0x6B, 0x67, 0x52, 0x73, 0x57, 0x52, 0x64, 0x47, 0x46, 0x75, 0x77, 0x37, 0x70, 0x7A, 0x77, 0x36, 0x31, ++ 0x30, 0x64, 0x73, 0x4F, 0x68, 0x62, 0x6E, 0x6B, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x44, 0x67, 0x78, 0x4D, 0x6A, 0x45, 0x78, 0x4D, 0x54, 0x55, 0x77, 0x4F, 0x44, 0x49, 0x78, 0x57, 0x68, 0x63, 0x4E, 0x4D, 0x6A, 0x67, 0x78, 0x0A, 0x4D, 0x6A, ++ 0x41, 0x32, 0x4D, 0x54, 0x55, 0x77, 0x4F, 0x44, 0x49, 0x78, 0x57, 0x6A, 0x43, 0x42, 0x70, 0x7A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x53, 0x46, 0x55, 0x78, 0x45, 0x54, 0x41, 0x50, 0x42, 0x67, ++ 0x4E, 0x56, 0x42, 0x41, 0x63, 0x4D, 0x43, 0x45, 0x4A, 0x31, 0x5A, 0x47, 0x46, 0x77, 0x5A, 0x58, 0x4E, 0x30, 0x4D, 0x52, 0x55, 0x77, 0x45, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x44, 0x41, 0x78, 0x4F, 0x0A, 0x5A, 0x58, 0x52, 0x4D, 0x62, ++ 0x32, 0x4E, 0x72, 0x49, 0x45, 0x74, 0x6D, 0x64, 0x43, 0x34, 0x78, 0x4E, 0x7A, 0x41, 0x31, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x73, 0x4D, 0x4C, 0x6C, 0x52, 0x68, 0x62, 0x73, 0x4F, 0x36, 0x63, 0x38, 0x4F, 0x74, 0x64, 0x48, 0x62, 0x44, 0x6F, ++ 0x57, 0x35, 0x35, 0x61, 0x32, 0x6C, 0x68, 0x5A, 0x4D, 0x4F, 0x7A, 0x61, 0x79, 0x41, 0x6F, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6C, 0x6D, 0x61, 0x57, 0x4E, 0x68, 0x64, 0x47, 0x6C, 0x76, 0x0A, 0x62, 0x69, 0x42, 0x54, 0x5A, 0x58, 0x4A, 0x32, ++ 0x61, 0x57, 0x4E, 0x6C, 0x63, 0x79, 0x6B, 0x78, 0x4E, 0x54, 0x41, 0x7A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x4C, 0x45, 0x35, 0x6C, 0x64, 0x45, 0x78, 0x76, 0x59, 0x32, 0x73, 0x67, 0x51, 0x58, 0x4A, 0x68, 0x62, 0x6E, 0x6B, 0x67, ++ 0x4B, 0x45, 0x4E, 0x73, 0x59, 0x58, 0x4E, 0x7A, 0x49, 0x45, 0x64, 0x76, 0x62, 0x47, 0x51, 0x70, 0x49, 0x45, 0x62, 0x46, 0x6B, 0x58, 0x52, 0x68, 0x62, 0x73, 0x4F, 0x36, 0x0A, 0x63, 0x38, 0x4F, 0x74, 0x64, 0x48, 0x62, 0x44, 0x6F, 0x57, 0x35, ++ 0x35, 0x4D, 0x49, 0x49, 0x42, 0x49, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x51, 0x38, 0x41, 0x4D, 0x49, 0x49, 0x42, 0x43, 0x67, 0x4B, ++ 0x43, 0x41, 0x51, 0x45, 0x41, 0x78, 0x43, 0x52, 0x65, 0x63, 0x37, 0x35, 0x4C, 0x62, 0x52, 0x54, 0x44, 0x6F, 0x66, 0x54, 0x6A, 0x6C, 0x35, 0x42, 0x75, 0x0A, 0x30, 0x6A, 0x42, 0x46, 0x48, 0x6A, 0x7A, 0x75, 0x5A, 0x39, 0x6C, 0x6B, 0x34, 0x42, ++ 0x71, 0x4B, 0x66, 0x38, 0x6F, 0x77, 0x79, 0x6F, 0x50, 0x6A, 0x49, 0x4D, 0x48, 0x6A, 0x39, 0x44, 0x72, 0x54, 0x6C, 0x46, 0x38, 0x61, 0x66, 0x46, 0x74, 0x74, 0x76, 0x7A, 0x42, 0x50, 0x68, 0x43, 0x66, 0x32, 0x6E, 0x78, 0x39, 0x4A, 0x76, 0x4D, ++ 0x61, 0x5A, 0x43, 0x70, 0x44, 0x79, 0x44, 0x2F, 0x56, 0x2F, 0x51, 0x34, 0x51, 0x33, 0x59, 0x31, 0x47, 0x4C, 0x65, 0x71, 0x56, 0x77, 0x0A, 0x2F, 0x48, 0x70, 0x59, 0x7A, 0x59, 0x36, 0x62, 0x37, 0x63, 0x4E, 0x47, 0x62, 0x49, 0x52, 0x77, 0x58, ++ 0x64, 0x72, 0x7A, 0x41, 0x5A, 0x41, 0x6A, 0x2F, 0x45, 0x34, 0x77, 0x71, 0x58, 0x37, 0x68, 0x4A, 0x32, 0x50, 0x6E, 0x37, 0x57, 0x51, 0x38, 0x6F, 0x4C, 0x6A, 0x4A, 0x4D, 0x32, 0x50, 0x2B, 0x46, 0x70, 0x44, 0x2F, 0x73, 0x4C, 0x6A, 0x39, 0x31, ++ 0x36, 0x6A, 0x41, 0x77, 0x4A, 0x52, 0x44, 0x43, 0x37, 0x62, 0x56, 0x57, 0x61, 0x61, 0x65, 0x56, 0x74, 0x41, 0x6B, 0x0A, 0x48, 0x33, 0x42, 0x35, 0x72, 0x39, 0x73, 0x35, 0x56, 0x41, 0x31, 0x6C, 0x64, 0x64, 0x6B, 0x56, 0x51, 0x5A, 0x51, 0x42, ++ 0x72, 0x31, 0x37, 0x73, 0x39, 0x6F, 0x33, 0x78, 0x2F, 0x36, 0x31, 0x6B, 0x2F, 0x69, 0x43, 0x61, 0x31, 0x31, 0x7A, 0x72, 0x2F, 0x71, 0x59, 0x66, 0x43, 0x47, 0x53, 0x6A, 0x69, 0x33, 0x5A, 0x56, 0x72, 0x52, 0x34, 0x37, 0x4B, 0x47, 0x41, 0x75, ++ 0x68, 0x79, 0x58, 0x6F, 0x71, 0x71, 0x38, 0x66, 0x78, 0x6D, 0x52, 0x47, 0x49, 0x4C, 0x64, 0x77, 0x0A, 0x66, 0x7A, 0x7A, 0x65, 0x53, 0x4E, 0x75, 0x57, 0x55, 0x37, 0x63, 0x35, 0x64, 0x2B, 0x51, 0x61, 0x34, 0x73, 0x63, 0x57, 0x68, 0x48, 0x61, ++ 0x58, 0x57, 0x79, 0x2B, 0x37, 0x47, 0x52, 0x57, 0x46, 0x2B, 0x47, 0x6D, 0x46, 0x39, 0x5A, 0x6D, 0x6E, 0x71, 0x66, 0x49, 0x30, 0x70, 0x36, 0x6D, 0x32, 0x70, 0x67, 0x50, 0x38, 0x62, 0x34, 0x59, 0x39, 0x56, 0x48, 0x78, 0x32, 0x42, 0x4A, 0x74, ++ 0x72, 0x2B, 0x55, 0x42, 0x64, 0x41, 0x44, 0x54, 0x48, 0x4C, 0x70, 0x6C, 0x31, 0x0A, 0x6E, 0x65, 0x57, 0x49, 0x41, 0x36, 0x70, 0x4E, 0x2B, 0x41, 0x50, 0x53, 0x51, 0x6E, 0x62, 0x41, 0x47, 0x77, 0x49, 0x44, 0x41, 0x4B, 0x69, 0x4C, 0x6F, 0x30, ++ 0x55, 0x77, 0x51, 0x7A, 0x41, 0x53, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x43, 0x44, 0x41, 0x47, 0x41, 0x51, 0x48, 0x2F, 0x41, 0x67, 0x45, 0x45, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, ++ 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x0A, 0x42, 0x6A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x7A, 0x50, 0x70, 0x6E, 0x6B, 0x2F, 0x43, 0x32, 0x75, 0x4E, 0x43, 0x6C, 0x77, ++ 0x42, 0x37, 0x7A, 0x55, 0x2F, 0x32, 0x4D, 0x55, 0x39, 0x2B, 0x44, 0x31, 0x35, 0x59, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x42, 0x41, ++ 0x4B, 0x74, 0x2F, 0x37, 0x68, 0x77, 0x57, 0x0A, 0x71, 0x5A, 0x77, 0x38, 0x55, 0x51, 0x43, 0x67, 0x77, 0x42, 0x45, 0x49, 0x42, 0x61, 0x65, 0x5A, 0x35, 0x6D, 0x38, 0x42, 0x69, 0x46, 0x52, 0x68, 0x62, 0x76, 0x47, 0x35, 0x47, 0x4B, 0x31, 0x4B, ++ 0x72, 0x66, 0x36, 0x42, 0x51, 0x43, 0x4F, 0x55, 0x4C, 0x2F, 0x74, 0x31, 0x66, 0x43, 0x38, 0x6F, 0x53, 0x32, 0x49, 0x6B, 0x67, 0x59, 0x49, 0x4C, 0x39, 0x57, 0x48, 0x78, 0x48, 0x47, 0x36, 0x34, 0x59, 0x54, 0x6A, 0x72, 0x67, 0x66, 0x70, 0x69, ++ 0x6F, 0x54, 0x74, 0x61, 0x0A, 0x59, 0x74, 0x4F, 0x55, 0x5A, 0x63, 0x54, 0x68, 0x35, 0x6D, 0x32, 0x43, 0x2B, 0x43, 0x38, 0x6C, 0x63, 0x4C, 0x49, 0x68, 0x4A, 0x73, 0x46, 0x79, 0x55, 0x52, 0x2B, 0x4D, 0x4C, 0x4D, 0x4F, 0x45, 0x6B, 0x4D, 0x4E, ++ 0x61, 0x6A, 0x37, 0x72, 0x50, 0x39, 0x4B, 0x64, 0x6C, 0x70, 0x65, 0x75, 0x59, 0x30, 0x66, 0x73, 0x46, 0x73, 0x6B, 0x5A, 0x31, 0x46, 0x53, 0x4E, 0x71, 0x62, 0x34, 0x56, 0x6A, 0x4D, 0x49, 0x44, 0x77, 0x31, 0x5A, 0x34, 0x66, 0x4B, 0x52, 0x7A, ++ 0x43, 0x0A, 0x62, 0x4C, 0x42, 0x51, 0x57, 0x56, 0x32, 0x51, 0x57, 0x7A, 0x75, 0x6F, 0x44, 0x54, 0x44, 0x50, 0x76, 0x33, 0x31, 0x2F, 0x7A, 0x76, 0x47, 0x64, 0x67, 0x37, 0x33, 0x4A, 0x52, 0x6D, 0x34, 0x67, 0x70, 0x76, 0x6C, 0x68, 0x55, 0x62, ++ 0x6F, 0x68, 0x4C, 0x33, 0x75, 0x2B, 0x70, 0x52, 0x56, 0x6A, 0x6F, 0x64, 0x53, 0x56, 0x68, 0x2F, 0x47, 0x65, 0x75, 0x66, 0x4F, 0x4A, 0x38, 0x7A, 0x32, 0x46, 0x75, 0x4C, 0x6A, 0x62, 0x76, 0x72, 0x57, 0x35, 0x4B, 0x66, 0x6E, 0x61, 0x0A, 0x4E, ++ 0x77, 0x55, 0x41, 0x53, 0x5A, 0x51, 0x44, 0x68, 0x45, 0x54, 0x6E, 0x76, 0x30, 0x4D, 0x78, 0x7A, 0x33, 0x57, 0x4C, 0x4A, 0x64, 0x48, 0x30, 0x70, 0x6D, 0x54, 0x31, 0x6B, 0x76, 0x61, 0x72, 0x42, 0x65, 0x73, 0x39, 0x36, 0x61, 0x55, 0x4C, 0x4E, ++ 0x6D, 0x4C, 0x61, 0x7A, 0x41, 0x5A, 0x66, 0x4E, 0x6F, 0x75, 0x32, 0x58, 0x6A, 0x47, 0x34, 0x4B, 0x76, 0x74, 0x65, 0x39, 0x6E, 0x48, 0x66, 0x52, 0x43, 0x61, 0x65, 0x78, 0x4F, 0x59, 0x4E, 0x6B, 0x62, 0x51, 0x75, 0x0A, 0x64, 0x5A, 0x57, 0x41, ++ 0x55, 0x57, 0x70, 0x4C, 0x4D, 0x4B, 0x61, 0x77, 0x59, 0x71, 0x47, 0x54, 0x38, 0x5A, 0x76, 0x59, 0x7A, 0x73, 0x52, 0x6A, 0x64, 0x54, 0x39, 0x5A, 0x52, 0x37, 0x45, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, ++ 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x65, 0x2D, 0x53, 0x7A, 0x69, 0x67, 0x6E, 0x6F, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, ++ 0x41, 0x20, 0x32, 0x30, 0x30, 0x39, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, ++ 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x45, 0x43, 0x6A, 0x43, 0x43, 0x41, 0x76, 0x4B, 0x67, 0x41, 0x77, ++ 0x49, 0x42, 0x41, 0x67, 0x49, 0x4A, 0x41, 0x4D, 0x4A, 0x2B, 0x51, 0x77, 0x52, 0x4F, 0x52, 0x7A, 0x38, 0x5A, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43, 0x77, 0x55, 0x41, 0x4D, 0x49, ++ 0x47, 0x43, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x49, 0x56, 0x54, 0x45, 0x52, 0x0A, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x77, 0x77, 0x49, 0x51, 0x6E, 0x56, 0x6B, 0x59, ++ 0x58, 0x42, 0x6C, 0x63, 0x33, 0x51, 0x78, 0x46, 0x6A, 0x41, 0x55, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x44, 0x55, 0x31, 0x70, 0x59, 0x33, 0x4A, 0x76, 0x63, 0x32, 0x56, 0x6A, 0x49, 0x45, 0x78, 0x30, 0x5A, 0x43, 0x34, 0x78, 0x4A, ++ 0x7A, 0x41, 0x6C, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x48, 0x6B, 0x31, 0x70, 0x59, 0x33, 0x4A, 0x76, 0x0A, 0x63, 0x32, 0x56, 0x6A, 0x49, 0x47, 0x55, 0x74, 0x55, 0x33, 0x70, 0x70, 0x5A, 0x32, 0x35, 0x76, 0x49, 0x46, 0x4A, 0x76, ++ 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x4D, 0x6A, 0x41, 0x77, 0x4F, 0x54, 0x45, 0x66, 0x4D, 0x42, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x4A, 0x41, 0x52, 0x59, 0x51, 0x61, 0x57, 0x35, 0x6D, ++ 0x62, 0x30, 0x42, 0x6C, 0x4C, 0x58, 0x4E, 0x36, 0x61, 0x57, 0x64, 0x75, 0x62, 0x79, 0x35, 0x6F, 0x0A, 0x64, 0x54, 0x41, 0x65, 0x46, 0x77, 0x30, 0x77, 0x4F, 0x54, 0x41, 0x32, 0x4D, 0x54, 0x59, 0x78, 0x4D, 0x54, 0x4D, 0x77, 0x4D, 0x54, 0x68, ++ 0x61, 0x46, 0x77, 0x30, 0x79, 0x4F, 0x54, 0x45, 0x79, 0x4D, 0x7A, 0x41, 0x78, 0x4D, 0x54, 0x4D, 0x77, 0x4D, 0x54, 0x68, 0x61, 0x4D, 0x49, 0x47, 0x43, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, ++ 0x49, 0x56, 0x54, 0x45, 0x52, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0A, 0x42, 0x77, 0x77, 0x49, 0x51, 0x6E, 0x56, 0x6B, 0x59, 0x58, 0x42, 0x6C, 0x63, 0x33, 0x51, 0x78, 0x46, 0x6A, 0x41, 0x55, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, ++ 0x6F, 0x4D, 0x44, 0x55, 0x31, 0x70, 0x59, 0x33, 0x4A, 0x76, 0x63, 0x32, 0x56, 0x6A, 0x49, 0x45, 0x78, 0x30, 0x5A, 0x43, 0x34, 0x78, 0x4A, 0x7A, 0x41, 0x6C, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x48, 0x6B, 0x31, 0x70, 0x59, 0x33, ++ 0x4A, 0x76, 0x63, 0x32, 0x56, 0x6A, 0x49, 0x47, 0x55, 0x74, 0x0A, 0x55, 0x33, 0x70, 0x70, 0x5A, 0x32, 0x35, 0x76, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x4D, 0x6A, 0x41, 0x77, 0x4F, 0x54, 0x45, 0x66, 0x4D, ++ 0x42, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x4A, 0x41, 0x52, 0x59, 0x51, 0x61, 0x57, 0x35, 0x6D, 0x62, 0x30, 0x42, 0x6C, 0x4C, 0x58, 0x4E, 0x36, 0x61, 0x57, 0x64, 0x75, 0x62, 0x79, 0x35, 0x6F, 0x64, ++ 0x54, 0x43, 0x43, 0x41, 0x53, 0x49, 0x77, 0x0A, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x51, 0x6F, 0x43, ++ 0x67, 0x67, 0x45, 0x42, 0x41, 0x4F, 0x6E, 0x34, 0x6A, 0x2F, 0x4E, 0x6A, 0x72, 0x64, 0x71, 0x47, 0x32, 0x4B, 0x66, 0x67, 0x51, 0x76, 0x76, 0x50, 0x6B, 0x64, 0x36, 0x6D, 0x4A, 0x76, 0x69, 0x5A, 0x70, 0x57, 0x4E, 0x77, 0x72, 0x5A, 0x75, 0x75, ++ 0x79, 0x6A, 0x4E, 0x41, 0x0A, 0x66, 0x57, 0x32, 0x57, 0x62, 0x71, 0x45, 0x4F, 0x52, 0x4F, 0x37, 0x68, 0x45, 0x35, 0x32, 0x55, 0x51, 0x6C, 0x4B, 0x61, 0x76, 0x58, 0x57, 0x46, 0x64, 0x43, 0x79, 0x6F, 0x44, 0x68, 0x32, 0x54, 0x74, 0x68, 0x69, ++ 0x33, 0x6A, 0x43, 0x79, 0x6F, 0x7A, 0x2F, 0x74, 0x63, 0x63, 0x62, 0x6E, 0x61, 0x37, 0x50, 0x37, 0x6F, 0x66, 0x6F, 0x2F, 0x6B, 0x4C, 0x78, 0x32, 0x79, 0x71, 0x48, 0x57, 0x48, 0x32, 0x4C, 0x65, 0x68, 0x35, 0x54, 0x76, 0x50, 0x6D, 0x55, 0x70, ++ 0x47, 0x0A, 0x30, 0x49, 0x4D, 0x5A, 0x66, 0x63, 0x43, 0x68, 0x45, 0x68, 0x79, 0x56, 0x62, 0x55, 0x72, 0x30, 0x32, 0x4D, 0x65, 0x6C, 0x54, 0x54, 0x4D, 0x75, 0x68, 0x54, 0x6C, 0x41, 0x64, 0x58, 0x34, 0x55, 0x66, 0x49, 0x41, 0x53, 0x6D, 0x46, ++ 0x44, 0x48, 0x51, 0x57, 0x65, 0x34, 0x6F, 0x49, 0x42, 0x68, 0x56, 0x4B, 0x5A, 0x73, 0x54, 0x68, 0x2F, 0x67, 0x6E, 0x51, 0x34, 0x48, 0x36, 0x63, 0x6D, 0x36, 0x4D, 0x2B, 0x66, 0x2B, 0x77, 0x46, 0x55, 0x6F, 0x4C, 0x41, 0x4B, 0x41, 0x0A, 0x70, ++ 0x78, 0x6E, 0x31, 0x6E, 0x74, 0x78, 0x56, 0x55, 0x77, 0x4F, 0x58, 0x65, 0x77, 0x64, 0x49, 0x2F, 0x35, 0x6E, 0x37, 0x4E, 0x34, 0x6F, 0x6B, 0x78, 0x46, 0x6E, 0x4D, 0x55, 0x42, 0x42, 0x6A, 0x6A, 0x71, 0x71, 0x70, 0x47, 0x72, 0x43, 0x45, 0x47, ++ 0x6F, 0x62, 0x35, 0x58, 0x37, 0x75, 0x78, 0x55, 0x47, 0x36, 0x6B, 0x30, 0x51, 0x72, 0x4D, 0x31, 0x58, 0x46, 0x2B, 0x48, 0x36, 0x63, 0x62, 0x66, 0x50, 0x56, 0x54, 0x62, 0x69, 0x4A, 0x66, 0x79, 0x79, 0x76, 0x6D, 0x0A, 0x31, 0x48, 0x78, 0x64, ++ 0x72, 0x74, 0x62, 0x43, 0x78, 0x6B, 0x7A, 0x6C, 0x42, 0x51, 0x48, 0x5A, 0x37, 0x56, 0x66, 0x38, 0x77, 0x53, 0x4E, 0x35, 0x2F, 0x50, 0x72, 0x49, 0x4A, 0x49, 0x4F, 0x56, 0x38, 0x37, 0x56, 0x71, 0x55, 0x51, 0x48, 0x51, 0x64, 0x39, 0x62, 0x70, ++ 0x45, 0x71, 0x48, 0x35, 0x47, 0x6F, 0x50, 0x37, 0x67, 0x68, 0x75, 0x35, 0x73, 0x4A, 0x66, 0x30, 0x64, 0x67, 0x59, 0x7A, 0x51, 0x30, 0x6D, 0x67, 0x2F, 0x77, 0x75, 0x31, 0x2B, 0x72, 0x55, 0x43, 0x0A, 0x41, 0x77, 0x45, 0x41, 0x41, 0x61, 0x4F, ++ 0x42, 0x67, 0x44, 0x42, 0x2B, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, ++ 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x54, 0x4C, 0x44, 0x38, 0x62, 0x66, 0x0A, 0x51, 0x6B, 0x50, 0x4D, 0x50, 0x63, 0x75, 0x31, 0x53, 0x43, ++ 0x4F, 0x68, 0x47, 0x6E, 0x71, 0x6D, 0x4B, 0x72, 0x73, 0x30, 0x61, 0x44, 0x41, 0x66, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x53, 0x4D, 0x45, 0x47, 0x44, 0x41, 0x57, 0x67, 0x42, 0x54, 0x4C, 0x44, 0x38, 0x62, 0x66, 0x51, 0x6B, 0x50, 0x4D, 0x50, 0x63, ++ 0x75, 0x31, 0x53, 0x43, 0x4F, 0x68, 0x47, 0x6E, 0x71, 0x6D, 0x4B, 0x72, 0x73, 0x30, 0x61, 0x44, 0x41, 0x62, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x45, 0x45, 0x0A, 0x46, 0x44, 0x41, 0x53, 0x67, 0x52, 0x42, 0x70, 0x62, 0x6D, 0x5A, 0x76, 0x51, ++ 0x47, 0x55, 0x74, 0x63, 0x33, 0x70, 0x70, 0x5A, 0x32, 0x35, 0x76, 0x4C, 0x6D, 0x68, 0x31, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43, 0x77, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x41, ++ 0x51, 0x44, 0x4A, 0x30, 0x51, 0x35, 0x65, 0x4C, 0x74, 0x58, 0x4D, 0x73, 0x33, 0x77, 0x2B, 0x79, 0x2F, 0x77, 0x39, 0x2F, 0x77, 0x30, 0x6F, 0x0A, 0x6C, 0x5A, 0x4D, 0x45, 0x79, 0x4C, 0x2F, 0x61, 0x7A, 0x58, 0x6D, 0x34, 0x51, 0x35, 0x44, 0x77, ++ 0x70, 0x4C, 0x37, 0x76, 0x38, 0x75, 0x38, 0x68, 0x6D, 0x4C, 0x7A, 0x55, 0x31, 0x46, 0x30, 0x47, 0x39, 0x75, 0x35, 0x43, 0x37, 0x44, 0x42, 0x73, 0x6F, 0x4B, 0x71, 0x70, 0x79, 0x76, 0x47, 0x76, 0x69, 0x76, 0x6F, 0x2F, 0x43, 0x33, 0x4E, 0x71, ++ 0x50, 0x75, 0x6F, 0x75, 0x51, 0x48, 0x34, 0x66, 0x72, 0x6C, 0x52, 0x68, 0x65, 0x65, 0x73, 0x75, 0x43, 0x44, 0x66, 0x58, 0x0A, 0x49, 0x2F, 0x4F, 0x4D, 0x6E, 0x37, 0x34, 0x64, 0x73, 0x65, 0x47, 0x6B, 0x64, 0x64, 0x75, 0x67, 0x34, 0x6C, 0x51, ++ 0x55, 0x73, 0x62, 0x6F, 0x63, 0x4B, 0x61, 0x51, 0x59, 0x39, 0x68, 0x4B, 0x36, 0x6F, 0x68, 0x51, 0x55, 0x34, 0x7A, 0x45, 0x31, 0x79, 0x45, 0x44, 0x2F, 0x74, 0x2B, 0x41, 0x46, 0x64, 0x6C, 0x66, 0x42, 0x48, 0x46, 0x6E, 0x79, 0x2B, 0x4C, 0x2F, ++ 0x6B, 0x37, 0x53, 0x56, 0x69, 0x58, 0x49, 0x54, 0x77, 0x66, 0x6E, 0x34, 0x66, 0x73, 0x37, 0x37, 0x35, 0x0A, 0x74, 0x79, 0x45, 0x52, 0x7A, 0x41, 0x4D, 0x42, 0x56, 0x6E, 0x43, 0x6E, 0x45, 0x4A, 0x49, 0x65, 0x47, 0x7A, 0x53, 0x42, 0x48, 0x71, ++ 0x32, 0x63, 0x47, 0x73, 0x4D, 0x45, 0x50, 0x4F, 0x30, 0x43, 0x59, 0x64, 0x59, 0x65, 0x42, 0x76, 0x4E, 0x66, 0x4F, 0x6F, 0x66, 0x79, 0x4B, 0x2F, 0x46, 0x46, 0x68, 0x2B, 0x55, 0x39, 0x72, 0x4E, 0x48, 0x48, 0x56, 0x34, 0x53, 0x39, 0x61, 0x36, ++ 0x37, 0x63, 0x32, 0x50, 0x6D, 0x32, 0x47, 0x32, 0x4A, 0x77, 0x43, 0x7A, 0x30, 0x32, 0x0A, 0x79, 0x55, 0x4C, 0x79, 0x4D, 0x74, 0x64, 0x36, 0x59, 0x65, 0x62, 0x53, 0x32, 0x7A, 0x33, 0x50, 0x79, 0x4B, 0x6E, 0x4A, 0x6D, 0x39, 0x7A, 0x62, 0x57, ++ 0x45, 0x54, 0x58, 0x62, 0x7A, 0x69, 0x76, 0x66, 0x33, 0x6A, 0x54, 0x6F, 0x36, 0x30, 0x61, 0x64, 0x62, 0x6F, 0x63, 0x77, 0x54, 0x5A, 0x38, 0x6A, 0x78, 0x35, 0x74, 0x48, 0x4D, 0x4E, 0x31, 0x52, 0x71, 0x34, 0x31, 0x42, 0x61, 0x62, 0x32, 0x58, ++ 0x44, 0x30, 0x68, 0x37, 0x6C, 0x62, 0x77, 0x79, 0x59, 0x49, 0x69, 0x0A, 0x4C, 0x58, 0x70, 0x55, 0x71, 0x33, 0x44, 0x44, 0x66, 0x53, 0x4A, 0x6C, 0x67, 0x6E, 0x43, 0x57, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, ++ 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x52, 0x33, 0x0A, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, ++ 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x44, 0x58, 0x7A, 0x43, 0x43, 0x41, 0x6B, 0x65, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x4C, 0x42, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x42, ++ 0x49, 0x56, 0x68, 0x54, 0x43, 0x4B, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x77, 0x54, 0x44, 0x45, 0x67, 0x4D, 0x42, 0x34, 0x47, 0x41, 0x31, 0x55, 0x45, ++ 0x43, 0x78, 0x4D, 0x58, 0x52, 0x32, 0x78, 0x76, 0x0A, 0x59, 0x6D, 0x46, 0x73, 0x55, 0x32, 0x6C, 0x6E, 0x62, 0x69, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x49, 0x43, 0x30, 0x67, 0x55, 0x6A, 0x4D, 0x78, 0x45, 0x7A, 0x41, ++ 0x52, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x43, 0x6B, 0x64, 0x73, 0x62, 0x32, 0x4A, 0x68, 0x62, 0x46, 0x4E, 0x70, 0x5A, 0x32, 0x34, 0x78, 0x45, 0x7A, 0x41, 0x52, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x43, 0x6B, 0x64, ++ 0x73, 0x62, 0x32, 0x4A, 0x68, 0x0A, 0x62, 0x46, 0x4E, 0x70, 0x5A, 0x32, 0x34, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x44, 0x6B, 0x77, 0x4D, 0x7A, 0x45, 0x34, 0x4D, 0x54, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x57, 0x68, 0x63, 0x4E, 0x4D, 0x6A, ++ 0x6B, 0x77, 0x4D, 0x7A, 0x45, 0x34, 0x4D, 0x54, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x57, 0x6A, 0x42, 0x4D, 0x4D, 0x53, 0x41, 0x77, 0x48, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, 0x45, 0x78, 0x64, 0x48, 0x62, 0x47, 0x39, 0x69, 0x59, 0x57, ++ 0x78, 0x54, 0x0A, 0x61, 0x57, 0x64, 0x75, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x4C, 0x53, 0x42, 0x53, 0x4D, 0x7A, 0x45, 0x54, 0x4D, 0x42, 0x45, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x4B, 0x52, ++ 0x32, 0x78, 0x76, 0x59, 0x6D, 0x46, 0x73, 0x55, 0x32, 0x6C, 0x6E, 0x62, 0x6A, 0x45, 0x54, 0x4D, 0x42, 0x45, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x4B, 0x52, 0x32, 0x78, 0x76, 0x59, 0x6D, 0x46, 0x73, 0x55, 0x32, 0x6C, 0x6E, 0x0A, ++ 0x62, 0x6A, 0x43, 0x43, 0x41, 0x53, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x51, 0x6F, 0x43, ++ 0x67, 0x67, 0x45, 0x42, 0x41, 0x4D, 0x77, 0x6C, 0x64, 0x70, 0x42, 0x35, 0x42, 0x6E, 0x67, 0x69, 0x46, 0x76, 0x58, 0x41, 0x67, 0x37, 0x61, 0x45, 0x79, 0x69, 0x69, 0x65, 0x2F, 0x51, 0x56, 0x32, 0x45, 0x63, 0x57, 0x74, 0x0A, 0x69, 0x48, 0x4C, ++ 0x38, 0x52, 0x67, 0x4A, 0x44, 0x78, 0x37, 0x4B, 0x4B, 0x6E, 0x51, 0x52, 0x66, 0x4A, 0x4D, 0x73, 0x75, 0x53, 0x2B, 0x46, 0x67, 0x67, 0x6B, 0x62, 0x68, 0x55, 0x71, 0x73, 0x4D, 0x67, 0x55, 0x64, 0x77, 0x62, 0x4E, 0x31, 0x6B, 0x30, 0x65, 0x76, ++ 0x31, 0x4C, 0x4B, 0x4D, 0x50, 0x67, 0x6A, 0x30, 0x4D, 0x4B, 0x36, 0x36, 0x58, 0x31, 0x37, 0x59, 0x55, 0x68, 0x68, 0x42, 0x35, 0x75, 0x7A, 0x73, 0x54, 0x67, 0x48, 0x65, 0x4D, 0x43, 0x4F, 0x46, 0x4A, 0x0A, 0x30, 0x6D, 0x70, 0x69, 0x4C, 0x78, ++ 0x39, 0x65, 0x2B, 0x70, 0x5A, 0x6F, 0x33, 0x34, 0x6B, 0x6E, 0x6C, 0x54, 0x69, 0x66, 0x42, 0x74, 0x63, 0x2B, 0x79, 0x63, 0x73, 0x6D, 0x57, 0x51, 0x31, 0x7A, 0x33, 0x72, 0x44, 0x49, 0x36, 0x53, 0x59, 0x4F, 0x67, 0x78, 0x58, 0x47, 0x37, 0x31, ++ 0x75, 0x4C, 0x30, 0x67, 0x52, 0x67, 0x79, 0x6B, 0x6D, 0x6D, 0x4B, 0x50, 0x5A, 0x70, 0x4F, 0x2F, 0x62, 0x4C, 0x79, 0x43, 0x69, 0x52, 0x35, 0x5A, 0x32, 0x4B, 0x59, 0x56, 0x63, 0x33, 0x0A, 0x72, 0x48, 0x51, 0x55, 0x33, 0x48, 0x54, 0x67, 0x4F, ++ 0x75, 0x35, 0x79, 0x4C, 0x79, 0x36, 0x63, 0x2B, 0x39, 0x43, 0x37, 0x76, 0x2F, 0x55, 0x39, 0x41, 0x4F, 0x45, 0x47, 0x4D, 0x2B, 0x69, 0x43, 0x4B, 0x36, 0x35, 0x54, 0x70, 0x6A, 0x6F, 0x57, 0x63, 0x34, 0x7A, 0x64, 0x51, 0x51, 0x34, 0x67, 0x4F, ++ 0x73, 0x43, 0x30, 0x70, 0x36, 0x48, 0x70, 0x73, 0x6B, 0x2B, 0x51, 0x4C, 0x6A, 0x4A, 0x67, 0x36, 0x56, 0x66, 0x4C, 0x75, 0x51, 0x53, 0x53, 0x61, 0x47, 0x6A, 0x6C, 0x0A, 0x4F, 0x43, 0x5A, 0x67, 0x64, 0x62, 0x4B, 0x66, 0x64, 0x2F, 0x2B, 0x52, ++ 0x46, 0x4F, 0x2B, 0x75, 0x49, 0x45, 0x6E, 0x38, 0x72, 0x55, 0x41, 0x56, 0x53, 0x4E, 0x45, 0x43, 0x4D, 0x57, 0x45, 0x5A, 0x58, 0x72, 0x69, 0x58, 0x37, 0x36, 0x31, 0x33, 0x74, 0x32, 0x53, 0x61, 0x65, 0x72, 0x39, 0x66, 0x77, 0x52, 0x50, 0x76, ++ 0x6D, 0x32, 0x4C, 0x37, 0x44, 0x57, 0x7A, 0x67, 0x56, 0x47, 0x6B, 0x57, 0x71, 0x51, 0x50, 0x61, 0x62, 0x75, 0x6D, 0x44, 0x6B, 0x33, 0x46, 0x32, 0x0A, 0x78, 0x6D, 0x6D, 0x46, 0x67, 0x68, 0x63, 0x43, 0x41, 0x77, 0x45, 0x41, 0x41, 0x61, 0x4E, ++ 0x43, 0x4D, 0x45, 0x41, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, ++ 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x0A, 0x46, 0x49, 0x2F, 0x77, 0x53, 0x33, 0x2B, 0x6F, 0x4C, 0x6B, 0x55, 0x6B, 0x72, 0x6B, 0x31, 0x51, 0x2B, 0x6D, ++ 0x4F, 0x61, 0x69, 0x39, 0x37, 0x69, 0x33, 0x52, 0x75, 0x38, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43, 0x77, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x41, 0x51, 0x42, 0x4C, 0x51, 0x4E, ++ 0x76, 0x41, 0x55, 0x4B, 0x72, 0x2B, 0x79, 0x41, 0x7A, 0x76, 0x39, 0x35, 0x5A, 0x55, 0x52, 0x55, 0x6D, 0x37, 0x0A, 0x6C, 0x67, 0x41, 0x4A, 0x51, 0x61, 0x79, 0x7A, 0x45, 0x34, 0x61, 0x47, 0x4B, 0x41, 0x63, 0x7A, 0x79, 0x6D, 0x76, 0x6D, 0x64, ++ 0x4C, 0x6D, 0x36, 0x41, 0x43, 0x32, 0x75, 0x70, 0x41, 0x72, 0x54, 0x39, 0x66, 0x48, 0x78, 0x44, 0x34, 0x71, 0x2F, 0x63, 0x32, 0x64, 0x4B, 0x67, 0x38, 0x64, 0x45, 0x65, 0x33, 0x6A, 0x67, 0x72, 0x32, 0x35, 0x73, 0x62, 0x77, 0x4D, 0x70, 0x6A, ++ 0x6A, 0x4D, 0x35, 0x52, 0x63, 0x4F, 0x4F, 0x35, 0x4C, 0x6C, 0x58, 0x62, 0x4B, 0x72, 0x38, 0x0A, 0x45, 0x70, 0x62, 0x73, 0x55, 0x38, 0x59, 0x74, 0x35, 0x43, 0x52, 0x73, 0x75, 0x5A, 0x52, 0x6A, 0x2B, 0x39, 0x78, 0x54, 0x61, 0x47, 0x64, 0x57, ++ 0x50, 0x6F, 0x4F, 0x34, 0x7A, 0x7A, 0x55, 0x68, 0x77, 0x38, 0x6C, 0x6F, 0x2F, 0x73, 0x37, 0x61, 0x77, 0x6C, 0x4F, 0x71, 0x7A, 0x4A, 0x43, 0x4B, 0x36, 0x66, 0x42, 0x64, 0x52, 0x6F, 0x79, 0x56, 0x33, 0x58, 0x70, 0x59, 0x4B, 0x42, 0x6F, 0x76, ++ 0x48, 0x64, 0x37, 0x4E, 0x41, 0x44, 0x64, 0x42, 0x6A, 0x2B, 0x31, 0x45, 0x0A, 0x62, 0x64, 0x64, 0x54, 0x4B, 0x4A, 0x64, 0x2B, 0x38, 0x32, 0x63, 0x45, 0x48, 0x68, 0x58, 0x58, 0x69, 0x70, 0x61, 0x30, 0x30, 0x39, 0x35, 0x4D, 0x4A, 0x36, 0x52, ++ 0x4D, 0x47, 0x33, 0x4E, 0x7A, 0x64, 0x76, 0x51, 0x58, 0x6D, 0x63, 0x49, 0x66, 0x65, 0x67, 0x37, 0x6A, 0x4C, 0x51, 0x69, 0x74, 0x43, 0x68, 0x77, 0x73, 0x2F, 0x7A, 0x79, 0x72, 0x56, 0x51, 0x34, 0x50, 0x6B, 0x58, 0x34, 0x32, 0x36, 0x38, 0x4E, ++ 0x58, 0x53, 0x62, 0x37, 0x68, 0x4C, 0x69, 0x31, 0x38, 0x0A, 0x59, 0x49, 0x76, 0x44, 0x51, 0x56, 0x45, 0x54, 0x49, 0x35, 0x33, 0x4F, 0x39, 0x7A, 0x4A, 0x72, 0x6C, 0x41, 0x47, 0x6F, 0x6D, 0x65, 0x63, 0x73, 0x4D, 0x78, 0x38, 0x36, 0x4F, 0x79, ++ 0x58, 0x53, 0x68, 0x6B, 0x44, 0x4F, 0x4F, 0x79, 0x79, 0x47, 0x65, 0x4D, 0x6C, 0x68, 0x4C, 0x78, 0x53, 0x36, 0x37, 0x74, 0x74, 0x56, 0x62, 0x39, 0x2B, 0x45, 0x37, 0x67, 0x55, 0x4A, 0x54, 0x62, 0x30, 0x6F, 0x32, 0x48, 0x4C, 0x4F, 0x30, 0x32, ++ 0x4A, 0x51, 0x5A, 0x52, 0x37, 0x72, 0x0A, 0x6B, 0x70, 0x65, 0x44, 0x4D, 0x64, 0x6D, 0x7A, 0x74, 0x63, 0x70, 0x48, 0x57, 0x44, 0x39, 0x66, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, ++ 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x49, 0x7A, 0x65, 0x6E, 0x70, 0x65, 0x2E, 0x63, 0x6F, 0x6D, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, ++ 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x38, 0x54, 0x43, 0x43, 0x41, 0x39, 0x6D, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, ++ 0x51, 0x41, 0x4C, 0x43, 0x33, 0x57, 0x68, 0x5A, 0x49, 0x58, 0x37, 0x2F, 0x68, 0x79, 0x2F, 0x57, 0x4C, 0x31, 0x78, 0x6E, 0x6D, 0x66, 0x54, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, ++ 0x46, 0x41, 0x44, 0x41, 0x34, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0A, 0x45, 0x77, 0x4A, 0x46, 0x55, 0x7A, 0x45, 0x55, 0x4D, 0x42, 0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x4C, 0x53, 0x56, ++ 0x70, 0x46, 0x54, 0x6C, 0x42, 0x46, 0x49, 0x46, 0x4D, 0x75, 0x51, 0x53, 0x34, 0x78, 0x45, 0x7A, 0x41, 0x52, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x43, 0x6B, 0x6C, 0x36, 0x5A, 0x57, 0x35, 0x77, 0x5A, 0x53, 0x35, 0x6A, 0x62, 0x32, ++ 0x30, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x44, 0x63, 0x78, 0x4D, 0x6A, 0x45, 0x7A, 0x0A, 0x4D, 0x54, 0x4D, 0x77, 0x4F, 0x44, 0x49, 0x34, 0x57, 0x68, 0x63, 0x4E, 0x4D, 0x7A, 0x63, 0x78, 0x4D, 0x6A, 0x45, 0x7A, 0x4D, 0x44, 0x67, 0x79, 0x4E, ++ 0x7A, 0x49, 0x31, 0x57, 0x6A, 0x41, 0x34, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x46, 0x55, 0x7A, 0x45, 0x55, 0x4D, 0x42, 0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x4C, 0x53, ++ 0x56, 0x70, 0x46, 0x54, 0x6C, 0x42, 0x46, 0x49, 0x46, 0x4D, 0x75, 0x0A, 0x51, 0x53, 0x34, 0x78, 0x45, 0x7A, 0x41, 0x52, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x43, 0x6B, 0x6C, 0x36, 0x5A, 0x57, 0x35, 0x77, 0x5A, 0x53, 0x35, 0x6A, ++ 0x62, 0x32, 0x30, 0x77, 0x67, 0x67, 0x49, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4B, ++ 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x44, 0x4A, 0x0A, 0x30, 0x33, 0x72, 0x4B, 0x44, 0x78, 0x36, 0x73, 0x70, 0x34, 0x62, 0x6F, 0x46, 0x6D, 0x56, 0x71, 0x73, 0x63, 0x49, 0x62, 0x52, 0x54, 0x4A, 0x78, 0x6C, 0x64, 0x6E, 0x2B, 0x45, 0x46, 0x76, ++ 0x4D, 0x72, 0x2B, 0x65, 0x6C, 0x65, 0x51, 0x47, 0x50, 0x69, 0x63, 0x50, 0x4B, 0x38, 0x6C, 0x56, 0x78, 0x39, 0x33, 0x65, 0x2B, 0x64, 0x35, 0x54, 0x7A, 0x63, 0x71, 0x51, 0x73, 0x52, 0x4E, 0x69, 0x65, 0x6B, 0x70, 0x73, 0x55, 0x4F, 0x71, 0x48, ++ 0x6E, 0x4A, 0x4A, 0x41, 0x4B, 0x0A, 0x43, 0x6C, 0x61, 0x4F, 0x78, 0x64, 0x67, 0x6D, 0x6C, 0x4F, 0x48, 0x5A, 0x53, 0x4F, 0x45, 0x74, 0x50, 0x74, 0x6F, 0x4B, 0x63, 0x74, 0x32, 0x6A, 0x6D, 0x52, 0x58, 0x61, 0x67, 0x61, 0x4B, 0x48, 0x39, 0x48, ++ 0x74, 0x75, 0x4A, 0x6E, 0x65, 0x4A, 0x57, 0x4B, 0x33, 0x57, 0x36, 0x77, 0x79, 0x79, 0x51, 0x58, 0x70, 0x7A, 0x62, 0x6D, 0x33, 0x62, 0x65, 0x6E, 0x68, 0x42, 0x36, 0x51, 0x69, 0x49, 0x45, 0x6E, 0x36, 0x48, 0x4C, 0x6D, 0x59, 0x52, 0x59, 0x32, ++ 0x78, 0x55, 0x0A, 0x2B, 0x7A, 0x79, 0x64, 0x63, 0x73, 0x43, 0x38, 0x4C, 0x76, 0x2F, 0x43, 0x74, 0x39, 0x30, 0x4E, 0x64, 0x75, 0x4D, 0x36, 0x31, 0x2F, 0x65, 0x30, 0x61, 0x4C, 0x36, 0x69, 0x39, 0x65, 0x4F, 0x42, 0x62, 0x73, 0x46, 0x47, 0x62, ++ 0x31, 0x32, 0x4E, 0x34, 0x45, 0x33, 0x47, 0x56, 0x46, 0x57, 0x4A, 0x47, 0x6A, 0x4D, 0x78, 0x43, 0x72, 0x46, 0x58, 0x75, 0x61, 0x4F, 0x4B, 0x6D, 0x4D, 0x50, 0x73, 0x4F, 0x7A, 0x54, 0x46, 0x6C, 0x55, 0x46, 0x70, 0x66, 0x6E, 0x58, 0x43, 0x0A, ++ 0x50, 0x43, 0x44, 0x46, 0x59, 0x62, 0x70, 0x52, 0x52, 0x36, 0x41, 0x67, 0x6B, 0x4A, 0x4F, 0x68, 0x6B, 0x45, 0x76, 0x7A, 0x54, 0x6E, 0x79, 0x46, 0x52, 0x56, 0x53, 0x61, 0x30, 0x51, 0x55, 0x6D, 0x51, 0x62, 0x43, 0x31, 0x54, 0x52, 0x30, 0x7A, ++ 0x76, 0x73, 0x51, 0x44, 0x79, 0x43, 0x56, 0x38, 0x77, 0x58, 0x44, 0x62, 0x4F, 0x2F, 0x51, 0x4A, 0x4C, 0x56, 0x51, 0x6E, 0x53, 0x4B, 0x77, 0x76, 0x34, 0x63, 0x53, 0x73, 0x50, 0x73, 0x6A, 0x4C, 0x6B, 0x6B, 0x78, 0x54, 0x0A, 0x4F, 0x54, 0x63, ++ 0x6A, 0x37, 0x4E, 0x4D, 0x42, 0x2B, 0x65, 0x41, 0x4A, 0x52, 0x45, 0x31, 0x4E, 0x5A, 0x4D, 0x44, 0x68, 0x44, 0x56, 0x71, 0x48, 0x49, 0x72, 0x79, 0x74, 0x47, 0x36, 0x50, 0x2B, 0x4A, 0x72, 0x55, 0x56, 0x38, 0x36, 0x66, 0x38, 0x68, 0x42, 0x6E, ++ 0x70, 0x37, 0x4B, 0x47, 0x49, 0x74, 0x45, 0x52, 0x70, 0x68, 0x49, 0x50, 0x7A, 0x69, 0x64, 0x46, 0x30, 0x42, 0x71, 0x6E, 0x4D, 0x43, 0x39, 0x62, 0x43, 0x33, 0x69, 0x65, 0x46, 0x55, 0x43, 0x62, 0x4B, 0x0A, 0x46, 0x37, 0x6A, 0x4A, 0x65, 0x6F, ++ 0x64, 0x57, 0x4C, 0x42, 0x6F, 0x42, 0x48, 0x6D, 0x79, 0x2B, 0x45, 0x36, 0x30, 0x51, 0x72, 0x4C, 0x55, 0x6B, 0x39, 0x54, 0x69, 0x52, 0x6F, 0x64, 0x5A, 0x4C, 0x32, 0x76, 0x47, 0x37, 0x30, 0x74, 0x35, 0x48, 0x74, 0x66, 0x47, 0x38, 0x67, 0x66, ++ 0x5A, 0x5A, 0x61, 0x38, 0x38, 0x5A, 0x55, 0x2B, 0x6D, 0x4E, 0x46, 0x63, 0x74, 0x4B, 0x79, 0x36, 0x6C, 0x76, 0x52, 0x4F, 0x55, 0x62, 0x51, 0x63, 0x2F, 0x68, 0x68, 0x71, 0x66, 0x4B, 0x0A, 0x30, 0x47, 0x71, 0x66, 0x76, 0x45, 0x79, 0x4E, 0x42, ++ 0x6A, 0x4E, 0x61, 0x6F, 0x6F, 0x58, 0x6C, 0x6B, 0x44, 0x57, 0x67, 0x59, 0x6C, 0x77, 0x57, 0x54, 0x76, 0x44, 0x6A, 0x6F, 0x76, 0x6F, 0x44, 0x47, 0x72, 0x51, 0x73, 0x63, 0x62, 0x4E, 0x59, 0x4C, 0x4E, 0x35, 0x37, 0x43, 0x39, 0x73, 0x61, 0x44, ++ 0x2B, 0x76, 0x65, 0x49, 0x52, 0x38, 0x47, 0x64, 0x77, 0x59, 0x44, 0x73, 0x4D, 0x6E, 0x76, 0x6D, 0x66, 0x7A, 0x41, 0x75, 0x55, 0x38, 0x4C, 0x68, 0x69, 0x6A, 0x2B, 0x0A, 0x30, 0x72, 0x6E, 0x71, 0x34, 0x39, 0x71, 0x6C, 0x77, 0x30, 0x64, 0x70, ++ 0x45, 0x75, 0x44, 0x62, 0x38, 0x50, 0x59, 0x5A, 0x69, 0x2B, 0x31, 0x37, 0x63, 0x4E, 0x63, 0x43, 0x31, 0x75, 0x32, 0x48, 0x47, 0x43, 0x67, 0x73, 0x42, 0x43, 0x52, 0x4D, 0x64, 0x2B, 0x52, 0x49, 0x69, 0x68, 0x72, 0x47, 0x4F, 0x35, 0x72, 0x55, ++ 0x44, 0x38, 0x72, 0x36, 0x64, 0x64, 0x49, 0x42, 0x51, 0x46, 0x71, 0x4E, 0x65, 0x62, 0x2B, 0x4C, 0x7A, 0x30, 0x76, 0x50, 0x71, 0x68, 0x62, 0x42, 0x0A, 0x6C, 0x65, 0x53, 0x74, 0x54, 0x49, 0x6F, 0x2B, 0x46, 0x35, 0x48, 0x55, 0x73, 0x57, 0x4C, ++ 0x6C, 0x67, 0x75, 0x57, 0x41, 0x42, 0x4B, 0x51, 0x44, 0x66, 0x6F, 0x32, 0x2F, 0x32, 0x6E, 0x2B, 0x69, 0x44, 0x35, 0x64, 0x50, 0x44, 0x4E, 0x4D, 0x4E, 0x2B, 0x39, 0x66, 0x52, 0x35, 0x58, 0x4A, 0x2B, 0x48, 0x4D, 0x68, 0x33, 0x2F, 0x31, 0x75, ++ 0x61, 0x44, 0x37, 0x65, 0x75, 0x42, 0x55, 0x62, 0x6C, 0x38, 0x61, 0x67, 0x57, 0x37, 0x45, 0x65, 0x6B, 0x46, 0x77, 0x49, 0x44, 0x0A, 0x41, 0x51, 0x41, 0x42, 0x6F, 0x34, 0x48, 0x32, 0x4D, 0x49, 0x48, 0x7A, 0x4D, 0x49, 0x47, 0x77, 0x42, 0x67, ++ 0x4E, 0x56, 0x48, 0x52, 0x45, 0x45, 0x67, 0x61, 0x67, 0x77, 0x67, 0x61, 0x57, 0x42, 0x44, 0x32, 0x6C, 0x75, 0x5A, 0x6D, 0x39, 0x41, 0x61, 0x58, 0x70, 0x6C, 0x62, 0x6E, 0x42, 0x6C, 0x4C, 0x6D, 0x4E, 0x76, 0x62, 0x61, 0x53, 0x42, 0x6B, 0x54, ++ 0x43, 0x42, 0x6A, 0x6A, 0x46, 0x48, 0x4D, 0x45, 0x55, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x2B, 0x0A, 0x53, 0x56, 0x70, 0x46, 0x54, 0x6C, 0x42, 0x46, 0x49, 0x46, 0x4D, 0x75, 0x51, 0x53, 0x34, 0x67, 0x4C, 0x53, 0x42, 0x44, 0x53, ++ 0x55, 0x59, 0x67, 0x51, 0x54, 0x41, 0x78, 0x4D, 0x7A, 0x4D, 0x33, 0x4D, 0x6A, 0x59, 0x77, 0x4C, 0x56, 0x4A, 0x4E, 0x5A, 0x58, 0x4A, 0x6A, 0x4C, 0x6C, 0x5A, 0x70, 0x64, 0x47, 0x39, 0x79, 0x61, 0x57, 0x45, 0x74, 0x52, 0x32, 0x46, 0x7A, 0x64, ++ 0x47, 0x56, 0x70, 0x65, 0x69, 0x42, 0x55, 0x4D, 0x54, 0x41, 0x31, 0x4E, 0x53, 0x42, 0x47, 0x0A, 0x4E, 0x6A, 0x49, 0x67, 0x55, 0x7A, 0x67, 0x78, 0x51, 0x7A, 0x42, 0x42, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6B, 0x4D, 0x4F, 0x6B, 0x46, 0x32, ++ 0x5A, 0x47, 0x45, 0x67, 0x5A, 0x47, 0x56, 0x73, 0x49, 0x45, 0x31, 0x6C, 0x5A, 0x47, 0x6C, 0x30, 0x5A, 0x58, 0x4A, 0x79, 0x59, 0x57, 0x35, 0x6C, 0x62, 0x79, 0x42, 0x46, 0x64, 0x47, 0x39, 0x79, 0x59, 0x6D, 0x6C, 0x6B, 0x5A, 0x57, 0x45, 0x67, ++ 0x4D, 0x54, 0x51, 0x67, 0x4C, 0x53, 0x41, 0x77, 0x4D, 0x54, 0x41, 0x78, 0x0A, 0x4D, 0x43, 0x42, 0x57, 0x61, 0x58, 0x52, 0x76, 0x63, 0x6D, 0x6C, 0x68, 0x4C, 0x55, 0x64, 0x68, 0x63, 0x33, 0x52, 0x6C, 0x61, 0x58, 0x6F, 0x77, 0x44, 0x77, 0x59, ++ 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x51, 0x59, ++ 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x0A, 0x42, 0x42, 0x59, 0x45, 0x46, 0x42, 0x30, 0x63, 0x5A, 0x51, 0x36, 0x6F, 0x38, 0x69, 0x56, 0x37, 0x74, 0x4A, 0x48, 0x50, 0x35, 0x4C, 0x47, 0x78, 0x35, 0x72, 0x31, 0x56, 0x64, 0x47, ++ 0x77, 0x46, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43, 0x77, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x41, 0x51, 0x42, 0x34, 0x70, 0x67, 0x77, 0x57, 0x53, 0x70, 0x39, 0x4D, 0x69, 0x44, ++ 0x72, 0x41, 0x79, 0x77, 0x36, 0x6C, 0x0A, 0x46, 0x6E, 0x32, 0x66, 0x75, 0x55, 0x68, 0x66, 0x47, 0x49, 0x38, 0x4E, 0x59, 0x6A, 0x62, 0x32, 0x7A, 0x52, 0x6C, 0x72, 0x72, 0x4B, 0x76, 0x56, 0x39, 0x70, 0x46, 0x39, 0x72, 0x6E, 0x48, 0x7A, 0x50, ++ 0x37, 0x4D, 0x4F, 0x65, 0x49, 0x57, 0x62, 0x6C, 0x61, 0x51, 0x6E, 0x49, 0x55, 0x64, 0x43, 0x53, 0x6E, 0x78, 0x49, 0x4F, 0x76, 0x56, 0x46, 0x66, 0x4C, 0x4D, 0x4D, 0x6A, 0x6C, 0x46, 0x34, 0x72, 0x4A, 0x55, 0x54, 0x33, 0x73, 0x62, 0x39, 0x66, ++ 0x62, 0x67, 0x61, 0x0A, 0x6B, 0x45, 0x79, 0x72, 0x6B, 0x67, 0x50, 0x48, 0x37, 0x55, 0x49, 0x42, 0x7A, 0x67, 0x2F, 0x59, 0x73, 0x66, 0x71, 0x69, 0x6B, 0x75, 0x46, 0x67, 0x62, 0x61, 0x35, 0x36, 0x61, 0x77, 0x6D, 0x71, 0x78, 0x69, 0x6E, 0x75, ++ 0x61, 0x45, 0x6C, 0x6E, 0x4D, 0x49, 0x41, 0x6B, 0x65, 0x6A, 0x45, 0x57, 0x4F, 0x56, 0x74, 0x2B, 0x38, 0x52, 0x77, 0x75, 0x33, 0x57, 0x77, 0x4A, 0x72, 0x66, 0x49, 0x78, 0x77, 0x59, 0x4A, 0x4F, 0x75, 0x62, 0x76, 0x35, 0x76, 0x72, 0x38, 0x71, ++ 0x0A, 0x68, 0x54, 0x2F, 0x41, 0x51, 0x4B, 0x4D, 0x36, 0x57, 0x66, 0x78, 0x5A, 0x53, 0x7A, 0x77, 0x6F, 0x4A, 0x4E, 0x75, 0x30, 0x46, 0x58, 0x57, 0x75, 0x44, 0x59, 0x69, 0x36, 0x4C, 0x6E, 0x50, 0x41, 0x76, 0x56, 0x69, 0x48, 0x35, 0x55, 0x4C, ++ 0x79, 0x36, 0x31, 0x37, 0x75, 0x48, 0x6A, 0x41, 0x69, 0x6D, 0x63, 0x73, 0x33, 0x30, 0x63, 0x51, 0x68, 0x62, 0x49, 0x48, 0x73, 0x76, 0x6D, 0x30, 0x6D, 0x35, 0x68, 0x7A, 0x6B, 0x51, 0x69, 0x43, 0x65, 0x52, 0x37, 0x43, 0x73, 0x0A, 0x67, 0x31, ++ 0x6C, 0x77, 0x4C, 0x44, 0x58, 0x57, 0x72, 0x7A, 0x59, 0x30, 0x74, 0x4D, 0x30, 0x37, 0x2B, 0x44, 0x4B, 0x6F, 0x37, 0x2B, 0x4E, 0x34, 0x69, 0x66, 0x75, 0x4E, 0x52, 0x53, 0x7A, 0x61, 0x6E, 0x4C, 0x68, 0x2B, 0x51, 0x42, 0x78, 0x68, 0x35, 0x7A, ++ 0x36, 0x69, 0x6B, 0x69, 0x78, 0x4C, 0x38, 0x73, 0x33, 0x36, 0x6D, 0x4C, 0x59, 0x70, 0x2F, 0x2F, 0x50, 0x79, 0x65, 0x36, 0x6B, 0x66, 0x4C, 0x71, 0x43, 0x54, 0x56, 0x79, 0x76, 0x65, 0x68, 0x51, 0x50, 0x35, 0x0A, 0x61, 0x54, 0x66, 0x4C, 0x6E, ++ 0x6E, 0x68, 0x71, 0x42, 0x62, 0x54, 0x46, 0x4D, 0x58, 0x69, 0x4A, 0x37, 0x48, 0x71, 0x6E, 0x68, 0x65, 0x47, 0x35, 0x65, 0x7A, 0x7A, 0x65, 0x76, 0x68, 0x35, 0x35, 0x68, 0x4D, 0x36, 0x66, 0x63, 0x41, 0x35, 0x5A, 0x77, 0x6A, 0x55, 0x75, 0x6B, ++ 0x43, 0x6F, 0x78, 0x32, 0x65, 0x52, 0x46, 0x65, 0x6B, 0x47, 0x6B, 0x4C, 0x68, 0x4F, 0x62, 0x4E, 0x41, 0x35, 0x6D, 0x65, 0x30, 0x6D, 0x72, 0x5A, 0x4A, 0x66, 0x51, 0x52, 0x73, 0x4E, 0x35, 0x0A, 0x6E, 0x58, 0x4A, 0x51, 0x59, 0x36, 0x61, 0x59, ++ 0x57, 0x77, 0x61, 0x39, 0x53, 0x47, 0x33, 0x59, 0x4F, 0x59, 0x4E, 0x77, 0x36, 0x44, 0x58, 0x77, 0x42, 0x64, 0x47, 0x71, 0x76, 0x4F, 0x50, 0x62, 0x79, 0x41, 0x4C, 0x71, 0x66, 0x50, 0x32, 0x43, 0x32, 0x73, 0x4A, 0x62, 0x55, 0x6A, 0x57, 0x75, ++ 0x6D, 0x44, 0x71, 0x74, 0x75, 0x6A, 0x57, 0x54, 0x49, 0x36, 0x63, 0x66, 0x53, 0x4E, 0x30, 0x31, 0x52, 0x70, 0x69, 0x79, 0x45, 0x47, 0x6A, 0x6B, 0x70, 0x54, 0x48, 0x43, 0x0A, 0x43, 0x6C, 0x67, 0x75, 0x47, 0x59, 0x45, 0x51, 0x79, 0x56, 0x42, ++ 0x31, 0x2F, 0x4F, 0x70, 0x61, 0x46, 0x73, 0x34, 0x52, 0x31, 0x2B, 0x37, 0x76, 0x55, 0x49, 0x67, 0x74, 0x59, 0x66, 0x38, 0x2F, 0x51, 0x6E, 0x4D, 0x46, 0x6C, 0x45, 0x50, 0x56, 0x6A, 0x6A, 0x78, 0x4F, 0x41, 0x54, 0x6F, 0x5A, 0x70, 0x52, 0x39, ++ 0x47, 0x54, 0x6E, 0x66, 0x51, 0x58, 0x65, 0x57, 0x42, 0x49, 0x69, 0x47, 0x48, 0x2F, 0x70, 0x52, 0x39, 0x68, 0x4E, 0x69, 0x54, 0x72, 0x64, 0x5A, 0x6F, 0x0A, 0x51, 0x30, 0x69, 0x79, 0x32, 0x2B, 0x74, 0x7A, 0x4A, 0x4F, 0x65, 0x52, 0x66, 0x31, ++ 0x53, 0x6B, 0x74, 0x6F, 0x41, 0x2B, 0x6E, 0x61, 0x4D, 0x38, 0x54, 0x48, 0x4C, 0x43, 0x56, 0x38, 0x53, 0x67, 0x31, 0x4D, 0x77, 0x34, 0x4A, 0x38, 0x37, 0x56, 0x42, 0x70, 0x36, 0x69, 0x53, 0x4E, 0x6E, 0x70, 0x6E, 0x38, 0x36, 0x43, 0x63, 0x44, ++ 0x61, 0x54, 0x6D, 0x6A, 0x76, 0x66, 0x6C, 0x69, 0x48, 0x6A, 0x57, 0x62, 0x63, 0x4D, 0x32, 0x70, 0x45, 0x33, 0x38, 0x50, 0x31, 0x5A, 0x0A, 0x57, 0x72, 0x4F, 0x5A, 0x79, 0x47, 0x6C, 0x73, 0x51, 0x79, 0x59, 0x42, 0x4E, 0x57, 0x4E, 0x67, 0x56, ++ 0x59, 0x6B, 0x44, 0x4F, 0x6E, 0x58, 0x59, 0x75, 0x6B, 0x72, 0x5A, 0x56, 0x50, 0x2F, 0x75, 0x33, 0x6F, 0x44, 0x59, 0x4C, 0x64, 0x45, 0x34, 0x31, 0x56, 0x34, 0x74, 0x43, 0x35, 0x68, 0x39, 0x50, 0x6D, 0x7A, 0x62, 0x2F, 0x43, 0x61, 0x49, 0x78, ++ 0x77, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x47, 0x6F, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, ++ 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x47, 0x32, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, ++ 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x44, 0x78, 0x54, 0x43, 0x43, 0x41, 0x71, 0x32, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, ++ 0x42, 0x41, 0x44, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x43, 0x42, 0x67, 0x7A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, ++ 0x43, 0x56, 0x56, 0x4D, 0x78, 0x45, 0x44, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x67, 0x54, 0x0A, 0x42, 0x30, 0x46, 0x79, 0x61, 0x58, 0x70, 0x76, 0x62, 0x6D, 0x45, 0x78, 0x45, 0x7A, 0x41, 0x52, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, ++ 0x63, 0x54, 0x43, 0x6C, 0x4E, 0x6A, 0x62, 0x33, 0x52, 0x30, 0x63, 0x32, 0x52, 0x68, 0x62, 0x47, 0x55, 0x78, 0x47, 0x6A, 0x41, 0x59, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x45, 0x55, 0x64, 0x76, 0x52, 0x47, 0x46, 0x6B, 0x5A, 0x48, ++ 0x6B, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4C, 0x43, 0x42, 0x4A, 0x62, 0x6D, 0x4D, 0x75, 0x0A, 0x4D, 0x54, 0x45, 0x77, 0x4C, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x79, 0x68, 0x48, 0x62, 0x79, 0x42, 0x45, 0x59, 0x57, 0x52, 0x6B, 0x65, ++ 0x53, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x6C, 0x63, 0x6E, 0x52, 0x70, 0x5A, 0x6D, 0x6C, 0x6A, 0x59, 0x58, 0x52, 0x6C, 0x49, 0x45, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6D, 0x6C, 0x30, 0x65, 0x53, 0x41, 0x74, 0x49, ++ 0x45, 0x63, 0x79, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x41, 0x35, 0x0A, 0x4D, 0x44, 0x6B, 0x77, 0x4D, 0x54, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x46, 0x6F, 0x58, 0x44, 0x54, 0x4D, 0x33, 0x4D, 0x54, 0x49, 0x7A, 0x4D, 0x54, 0x49, 0x7A, ++ 0x4E, 0x54, 0x6B, 0x31, 0x4F, 0x56, 0x6F, 0x77, 0x67, 0x59, 0x4D, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6C, 0x56, 0x54, 0x4D, 0x52, 0x41, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x49, ++ 0x45, 0x77, 0x64, 0x42, 0x63, 0x6D, 0x6C, 0x36, 0x0A, 0x62, 0x32, 0x35, 0x68, 0x4D, 0x52, 0x4D, 0x77, 0x45, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x48, 0x45, 0x77, 0x70, 0x54, 0x59, 0x32, 0x39, 0x30, 0x64, 0x48, 0x4E, 0x6B, 0x59, 0x57, 0x78, ++ 0x6C, 0x4D, 0x52, 0x6F, 0x77, 0x47, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x78, 0x46, 0x48, 0x62, 0x30, 0x52, 0x68, 0x5A, 0x47, 0x52, 0x35, 0x4C, 0x6D, 0x4E, 0x76, 0x62, 0x53, 0x77, 0x67, 0x53, 0x57, 0x35, 0x6A, 0x4C, 0x6A, 0x45, ++ 0x78, 0x4D, 0x43, 0x38, 0x47, 0x0A, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x6F, 0x52, 0x32, 0x38, 0x67, 0x52, 0x47, 0x46, 0x6B, 0x5A, 0x48, 0x6B, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x61, 0x57, ++ 0x5A, 0x70, 0x59, 0x32, 0x46, 0x30, 0x5A, 0x53, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6F, 0x62, 0x33, 0x4A, 0x70, 0x64, 0x48, 0x6B, 0x67, 0x4C, 0x53, 0x42, 0x48, 0x4D, 0x6A, 0x43, 0x43, 0x41, 0x53, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, ++ 0x5A, 0x49, 0x0A, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x51, 0x6F, 0x43, 0x67, 0x67, 0x45, 0x42, 0x41, 0x4C, 0x39, 0x78, 0x59, 0x67, 0x6A, 0x78, 0x2B, ++ 0x6C, 0x6B, 0x30, 0x39, 0x78, 0x76, 0x4A, 0x47, 0x4B, 0x50, 0x33, 0x67, 0x45, 0x6C, 0x59, 0x36, 0x53, 0x4B, 0x44, 0x45, 0x36, 0x62, 0x46, 0x49, 0x45, 0x4D, 0x42, 0x4F, 0x34, 0x54, 0x78, 0x35, 0x6F, 0x56, 0x4A, 0x6E, 0x79, 0x66, 0x71, 0x0A, ++ 0x39, 0x6F, 0x51, 0x62, 0x54, 0x71, 0x43, 0x30, 0x32, 0x33, 0x43, 0x59, 0x78, 0x7A, 0x49, 0x42, 0x73, 0x51, 0x55, 0x2B, 0x42, 0x30, 0x37, 0x75, 0x39, 0x50, 0x70, 0x50, 0x4C, 0x31, 0x6B, 0x77, 0x49, 0x75, 0x65, 0x72, 0x47, 0x56, 0x5A, 0x72, ++ 0x34, 0x6F, 0x41, 0x48, 0x2F, 0x50, 0x4D, 0x57, 0x64, 0x59, 0x41, 0x35, 0x55, 0x58, 0x76, 0x6C, 0x2B, 0x54, 0x57, 0x32, 0x64, 0x45, 0x36, 0x70, 0x6A, 0x59, 0x49, 0x54, 0x35, 0x4C, 0x59, 0x2F, 0x71, 0x51, 0x4F, 0x44, 0x0A, 0x2B, 0x71, 0x4B, ++ 0x2B, 0x69, 0x68, 0x56, 0x71, 0x66, 0x39, 0x34, 0x4C, 0x77, 0x37, 0x59, 0x5A, 0x46, 0x41, 0x58, 0x4B, 0x36, 0x73, 0x4F, 0x6F, 0x42, 0x4A, 0x51, 0x37, 0x52, 0x6E, 0x77, 0x79, 0x44, 0x66, 0x4D, 0x41, 0x5A, 0x69, 0x4C, 0x49, 0x6A, 0x57, 0x6C, ++ 0x74, 0x4E, 0x6F, 0x77, 0x52, 0x47, 0x4C, 0x66, 0x54, 0x73, 0x68, 0x78, 0x67, 0x74, 0x44, 0x6A, 0x36, 0x41, 0x6F, 0x7A, 0x4F, 0x30, 0x39, 0x31, 0x47, 0x42, 0x39, 0x34, 0x4B, 0x50, 0x75, 0x74, 0x64, 0x0A, 0x66, 0x4D, 0x68, 0x38, 0x2B, 0x37, ++ 0x41, 0x72, 0x55, 0x36, 0x53, 0x53, 0x59, 0x6D, 0x6C, 0x52, 0x4A, 0x51, 0x56, 0x68, 0x47, 0x6B, 0x53, 0x42, 0x6A, 0x43, 0x79, 0x70, 0x51, 0x35, 0x59, 0x6A, 0x33, 0x36, 0x77, 0x36, 0x67, 0x5A, 0x6F, 0x4F, 0x4B, 0x63, 0x55, 0x63, 0x71, 0x65, ++ 0x6C, 0x64, 0x48, 0x72, 0x61, 0x65, 0x6E, 0x6A, 0x41, 0x4B, 0x4F, 0x63, 0x37, 0x78, 0x69, 0x49, 0x44, 0x37, 0x53, 0x31, 0x33, 0x4D, 0x4D, 0x75, 0x79, 0x46, 0x59, 0x6B, 0x4D, 0x6C, 0x0A, 0x4E, 0x41, 0x4A, 0x57, 0x4A, 0x77, 0x47, 0x52, 0x74, ++ 0x44, 0x74, 0x77, 0x4B, 0x6A, 0x39, 0x75, 0x73, 0x65, 0x69, 0x63, 0x69, 0x41, 0x46, 0x39, 0x6E, 0x39, 0x54, 0x35, 0x32, 0x31, 0x4E, 0x74, 0x59, 0x4A, 0x32, 0x2F, 0x4C, 0x4F, 0x64, 0x59, 0x71, 0x37, 0x68, 0x66, 0x52, 0x76, 0x7A, 0x4F, 0x78, ++ 0x42, 0x73, 0x44, 0x50, 0x41, 0x6E, 0x72, 0x53, 0x54, 0x46, 0x63, 0x61, 0x55, 0x61, 0x7A, 0x34, 0x45, 0x63, 0x43, 0x41, 0x77, 0x45, 0x41, 0x41, 0x61, 0x4E, 0x43, 0x0A, 0x4D, 0x45, 0x41, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, ++ 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x51, 0x59, 0x77, 0x48, 0x51, 0x59, 0x44, ++ 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x46, 0x44, 0x71, 0x61, 0x68, 0x51, 0x63, 0x51, 0x5A, 0x79, 0x69, 0x32, 0x37, 0x2F, 0x61, 0x39, 0x0A, 0x42, 0x55, 0x46, 0x75, 0x49, 0x4D, 0x47, 0x55, 0x32, 0x67, 0x2F, 0x65, 0x4D, 0x41, 0x30, ++ 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43, 0x77, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x41, 0x51, 0x43, 0x5A, 0x32, 0x31, 0x31, 0x35, 0x31, 0x66, 0x6D, 0x58, 0x57, 0x57, 0x63, 0x44, 0x59, 0x66, 0x46, ++ 0x2B, 0x4F, 0x77, 0x59, 0x78, 0x64, 0x53, 0x32, 0x68, 0x49, 0x49, 0x35, 0x50, 0x5A, 0x59, 0x65, 0x30, 0x39, 0x36, 0x61, 0x63, 0x0A, 0x76, 0x4E, 0x6A, 0x70, 0x4C, 0x39, 0x44, 0x62, 0x57, 0x75, 0x37, 0x50, 0x64, 0x49, 0x78, 0x7A, 0x74, 0x44, ++ 0x68, 0x43, 0x32, 0x67, 0x56, 0x37, 0x2B, 0x41, 0x4A, 0x31, 0x75, 0x50, 0x32, 0x6C, 0x73, 0x64, 0x65, 0x75, 0x39, 0x74, 0x66, 0x65, 0x45, 0x38, 0x74, 0x54, 0x45, 0x48, 0x36, 0x4B, 0x52, 0x74, 0x47, 0x58, 0x2B, 0x72, 0x63, 0x75, 0x4B, 0x78, ++ 0x47, 0x72, 0x6B, 0x4C, 0x41, 0x6E, 0x67, 0x50, 0x6E, 0x6F, 0x6E, 0x31, 0x72, 0x70, 0x4E, 0x35, 0x2B, 0x72, 0x0A, 0x35, 0x4E, 0x39, 0x73, 0x73, 0x34, 0x55, 0x58, 0x6E, 0x54, 0x33, 0x5A, 0x4A, 0x45, 0x39, 0x35, 0x6B, 0x54, 0x58, 0x57, 0x58, ++ 0x77, 0x54, 0x72, 0x67, 0x49, 0x4F, 0x72, 0x6D, 0x67, 0x49, 0x74, 0x74, 0x52, 0x44, 0x30, 0x32, 0x4A, 0x44, 0x48, 0x42, 0x48, 0x4E, 0x41, 0x37, 0x58, 0x49, 0x6C, 0x6F, 0x4B, 0x6D, 0x66, 0x37, 0x4A, 0x36, 0x72, 0x61, 0x42, 0x4B, 0x5A, 0x56, ++ 0x38, 0x61, 0x50, 0x45, 0x6A, 0x6F, 0x4A, 0x70, 0x4C, 0x31, 0x45, 0x2F, 0x51, 0x59, 0x56, 0x0A, 0x4E, 0x38, 0x47, 0x62, 0x35, 0x44, 0x4B, 0x6A, 0x37, 0x54, 0x6A, 0x6F, 0x32, 0x47, 0x54, 0x7A, 0x4C, 0x48, 0x34, 0x55, 0x2F, 0x41, 0x4C, 0x71, ++ 0x6E, 0x38, 0x33, 0x2F, 0x42, 0x32, 0x67, 0x58, 0x32, 0x79, 0x4B, 0x51, 0x4F, 0x43, 0x31, 0x36, 0x6A, 0x64, 0x46, 0x55, 0x38, 0x57, 0x6E, 0x6A, 0x58, 0x7A, 0x50, 0x4B, 0x65, 0x6A, 0x31, 0x37, 0x43, 0x75, 0x50, 0x4B, 0x66, 0x31, 0x38, 0x35, ++ 0x35, 0x65, 0x4A, 0x31, 0x75, 0x73, 0x56, 0x32, 0x47, 0x44, 0x50, 0x4F, 0x0A, 0x4C, 0x50, 0x41, 0x76, 0x54, 0x4B, 0x33, 0x33, 0x73, 0x65, 0x66, 0x4F, 0x54, 0x36, 0x6A, 0x45, 0x6D, 0x30, 0x70, 0x55, 0x42, 0x73, 0x56, 0x2F, 0x66, 0x64, 0x55, ++ 0x49, 0x44, 0x2B, 0x49, 0x63, 0x2F, 0x6E, 0x34, 0x58, 0x75, 0x4B, 0x78, 0x65, 0x39, 0x74, 0x51, 0x57, 0x73, 0x6B, 0x4D, 0x4A, 0x44, 0x45, 0x33, 0x32, 0x70, 0x32, 0x75, 0x30, 0x6D, 0x59, 0x52, 0x6C, 0x79, 0x6E, 0x71, 0x49, 0x34, 0x75, 0x4A, ++ 0x45, 0x76, 0x6C, 0x7A, 0x33, 0x36, 0x68, 0x7A, 0x31, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x53, 0x74, 0x61, ++ 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x47, 0x32, 0x0A, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x44, 0x33, 0x54, 0x43, 0x43, 0x41, 0x73, 0x57, ++ 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x42, 0x41, 0x44, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x43, 0x42, 0x6A, 0x7A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, ++ 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x56, 0x56, 0x4D, 0x78, 0x45, 0x44, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x67, 0x54, 0x0A, 0x42, 0x30, 0x46, 0x79, 0x61, 0x58, 0x70, 0x76, 0x62, 0x6D, 0x45, 0x78, 0x45, 0x7A, ++ 0x41, 0x52, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x63, 0x54, 0x43, 0x6C, 0x4E, 0x6A, 0x62, 0x33, 0x52, 0x30, 0x63, 0x32, 0x52, 0x68, 0x62, 0x47, 0x55, 0x78, 0x4A, 0x54, 0x41, 0x6A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x48, 0x46, ++ 0x4E, 0x30, 0x59, 0x58, 0x4A, 0x6D, 0x61, 0x57, 0x56, 0x73, 0x5A, 0x43, 0x42, 0x55, 0x5A, 0x57, 0x4E, 0x6F, 0x62, 0x6D, 0x39, 0x73, 0x0A, 0x62, 0x32, 0x64, 0x70, 0x5A, 0x58, 0x4D, 0x73, 0x49, 0x45, 0x6C, 0x75, 0x59, 0x79, 0x34, 0x78, 0x4D, ++ 0x6A, 0x41, 0x77, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x4B, 0x56, 0x4E, 0x30, 0x59, 0x58, 0x4A, 0x6D, 0x61, 0x57, 0x56, 0x73, 0x5A, 0x43, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x6C, 0x63, 0x6E, 0x52, 0x70, 0x5A, ++ 0x6D, 0x6C, 0x6A, 0x59, 0x58, 0x52, 0x6C, 0x49, 0x45, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6D, 0x6C, 0x30, 0x0A, 0x65, 0x53, 0x41, 0x74, 0x49, 0x45, 0x63, 0x79, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x41, 0x35, 0x4D, 0x44, 0x6B, 0x77, ++ 0x4D, 0x54, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x46, 0x6F, 0x58, 0x44, 0x54, 0x4D, 0x33, 0x4D, 0x54, 0x49, 0x7A, 0x4D, 0x54, 0x49, 0x7A, 0x4E, 0x54, 0x6B, 0x31, 0x4F, 0x56, 0x6F, 0x77, 0x67, 0x59, 0x38, 0x78, 0x43, 0x7A, 0x41, 0x4A, ++ 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6C, 0x56, 0x54, 0x4D, 0x52, 0x41, 0x77, 0x0A, 0x44, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x49, 0x45, 0x77, 0x64, 0x42, 0x63, 0x6D, 0x6C, 0x36, 0x62, 0x32, 0x35, 0x68, 0x4D, 0x52, 0x4D, ++ 0x77, 0x45, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x48, 0x45, 0x77, 0x70, 0x54, 0x59, 0x32, 0x39, 0x30, 0x64, 0x48, 0x4E, 0x6B, 0x59, 0x57, 0x78, 0x6C, 0x4D, 0x53, 0x55, 0x77, 0x49, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x78, 0x78, ++ 0x54, 0x64, 0x47, 0x46, 0x79, 0x5A, 0x6D, 0x6C, 0x6C, 0x62, 0x47, 0x51, 0x67, 0x0A, 0x56, 0x47, 0x56, 0x6A, 0x61, 0x47, 0x35, 0x76, 0x62, 0x47, 0x39, 0x6E, 0x61, 0x57, 0x56, 0x7A, 0x4C, 0x43, 0x42, 0x4A, 0x62, 0x6D, 0x4D, 0x75, 0x4D, 0x54, ++ 0x49, 0x77, 0x4D, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x79, 0x6C, 0x54, 0x64, 0x47, 0x46, 0x79, 0x5A, 0x6D, 0x6C, 0x6C, 0x62, 0x47, 0x51, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x61, 0x57, ++ 0x5A, 0x70, 0x59, 0x32, 0x46, 0x30, 0x5A, 0x53, 0x42, 0x42, 0x0A, 0x64, 0x58, 0x52, 0x6F, 0x62, 0x33, 0x4A, 0x70, 0x64, 0x48, 0x6B, 0x67, 0x4C, 0x53, 0x42, 0x48, 0x4D, 0x6A, 0x43, 0x43, 0x41, 0x53, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, ++ 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x51, 0x6F, 0x43, 0x67, 0x67, 0x45, 0x42, 0x41, 0x4C, 0x33, 0x74, 0x77, 0x51, 0x50, 0x38, 0x39, ++ 0x6F, 0x2F, 0x38, 0x41, 0x72, 0x46, 0x76, 0x0A, 0x57, 0x35, 0x39, 0x49, 0x32, 0x5A, 0x31, 0x35, 0x34, 0x71, 0x4B, 0x33, 0x41, 0x32, 0x46, 0x57, 0x47, 0x4D, 0x4E, 0x48, 0x74, 0x74, 0x66, 0x4B, 0x50, 0x54, 0x55, 0x75, 0x69, 0x55, 0x50, 0x33, ++ 0x6F, 0x57, 0x6D, 0x62, 0x33, 0x6F, 0x6F, 0x61, 0x2F, 0x52, 0x4D, 0x67, 0x6E, 0x4C, 0x52, 0x4A, 0x64, 0x7A, 0x49, 0x70, 0x56, 0x76, 0x32, 0x35, 0x37, 0x49, 0x7A, 0x64, 0x49, 0x76, 0x70, 0x79, 0x33, 0x43, 0x64, 0x68, 0x6C, 0x2B, 0x37, 0x32, ++ 0x57, 0x6F, 0x54, 0x73, 0x0A, 0x62, 0x68, 0x6D, 0x35, 0x69, 0x53, 0x7A, 0x63, 0x68, 0x46, 0x76, 0x56, 0x64, 0x50, 0x74, 0x72, 0x58, 0x38, 0x57, 0x4A, 0x70, 0x52, 0x42, 0x53, 0x69, 0x55, 0x5A, 0x56, 0x39, 0x4C, 0x68, 0x31, 0x48, 0x4F, 0x5A, ++ 0x2F, 0x35, 0x46, 0x53, 0x75, 0x53, 0x2F, 0x68, 0x56, 0x63, 0x6C, 0x63, 0x43, 0x47, 0x66, 0x67, 0x58, 0x63, 0x56, 0x6E, 0x72, 0x48, 0x69, 0x67, 0x48, 0x64, 0x4D, 0x57, 0x64, 0x53, 0x4C, 0x35, 0x73, 0x74, 0x50, 0x53, 0x6B, 0x73, 0x50, 0x4E, ++ 0x6B, 0x0A, 0x4E, 0x33, 0x6D, 0x53, 0x77, 0x4F, 0x78, 0x47, 0x58, 0x6E, 0x2F, 0x68, 0x62, 0x56, 0x4E, 0x4D, 0x59, 0x71, 0x2F, 0x4E, 0x48, 0x77, 0x74, 0x6A, 0x75, 0x7A, 0x71, 0x64, 0x2B, 0x2F, 0x78, 0x35, 0x41, 0x4A, 0x68, 0x68, 0x64, 0x4D, ++ 0x38, 0x6D, 0x67, 0x6B, 0x42, 0x6A, 0x38, 0x37, 0x4A, 0x79, 0x61, 0x68, 0x6B, 0x4E, 0x6D, 0x63, 0x72, 0x55, 0x44, 0x6E, 0x58, 0x4D, 0x4E, 0x2F, 0x75, 0x4C, 0x69, 0x63, 0x46, 0x5A, 0x38, 0x57, 0x4A, 0x2F, 0x58, 0x37, 0x4E, 0x66, 0x0A, 0x5A, ++ 0x54, 0x44, 0x34, 0x70, 0x37, 0x64, 0x4E, 0x64, 0x6C, 0x6F, 0x65, 0x64, 0x6C, 0x34, 0x30, 0x77, 0x4F, 0x69, 0x57, 0x56, 0x70, 0x6D, 0x4B, 0x73, 0x2F, 0x42, 0x2F, 0x70, 0x4D, 0x32, 0x39, 0x33, 0x44, 0x49, 0x78, 0x66, 0x4A, 0x48, 0x50, 0x34, ++ 0x46, 0x38, 0x52, 0x2B, 0x47, 0x75, 0x71, 0x53, 0x56, 0x7A, 0x52, 0x6D, 0x5A, 0x54, 0x52, 0x6F, 0x75, 0x4E, 0x6A, 0x57, 0x77, 0x6C, 0x32, 0x74, 0x56, 0x5A, 0x69, 0x34, 0x55, 0x74, 0x30, 0x48, 0x5A, 0x62, 0x55, 0x0A, 0x4A, 0x74, 0x51, 0x49, ++ 0x42, 0x46, 0x6E, 0x51, 0x6D, 0x41, 0x34, 0x4F, 0x35, 0x74, 0x37, 0x38, 0x77, 0x2B, 0x77, 0x66, 0x6B, 0x50, 0x45, 0x43, 0x41, 0x77, 0x45, 0x41, 0x41, 0x61, 0x4E, 0x43, 0x4D, 0x45, 0x41, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, ++ 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x0A, 0x41, 0x51, 0x59, 0x77, 0x48, 0x51, 0x59, ++ 0x44, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x46, 0x48, 0x77, 0x4D, 0x4D, 0x68, 0x2B, 0x6E, 0x32, 0x54, 0x42, 0x2F, 0x78, 0x48, 0x31, 0x6F, 0x6F, 0x32, 0x4B, 0x6F, 0x6F, 0x63, 0x36, 0x72, 0x42, 0x31, 0x73, 0x6E, 0x4D, 0x41, 0x30, ++ 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43, 0x77, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x41, 0x51, 0x41, 0x52, 0x57, 0x66, 0x6F, 0x6C, 0x0A, 0x54, 0x77, 0x4E, 0x76, 0x6C, 0x4A, 0x6B, 0x37, 0x6D, 0x68, ++ 0x2B, 0x43, 0x68, 0x54, 0x6E, 0x55, 0x64, 0x67, 0x57, 0x55, 0x58, 0x75, 0x45, 0x6F, 0x6B, 0x32, 0x31, 0x69, 0x58, 0x51, 0x6E, 0x43, 0x6F, 0x4B, 0x6A, 0x55, 0x73, 0x48, 0x55, 0x34, 0x38, 0x54, 0x52, 0x71, 0x6E, 0x65, 0x53, 0x66, 0x69, 0x6F, ++ 0x59, 0x6D, 0x55, 0x65, 0x59, 0x73, 0x30, 0x63, 0x59, 0x74, 0x62, 0x70, 0x55, 0x67, 0x53, 0x70, 0x49, 0x42, 0x37, 0x4C, 0x69, 0x4B, 0x5A, 0x33, 0x73, 0x78, 0x0A, 0x34, 0x6D, 0x63, 0x75, 0x6A, 0x4A, 0x55, 0x44, 0x4A, 0x69, 0x35, 0x44, 0x6E, ++ 0x55, 0x6F, 0x78, 0x39, 0x67, 0x36, 0x31, 0x44, 0x4C, 0x75, 0x33, 0x34, 0x6A, 0x64, 0x2F, 0x49, 0x72, 0x6F, 0x41, 0x6F, 0x77, 0x35, 0x37, 0x55, 0x76, 0x74, 0x72, 0x75, 0x7A, 0x76, 0x45, 0x30, 0x33, 0x6C, 0x52, 0x54, 0x73, 0x32, 0x51, 0x39, ++ 0x47, 0x63, 0x48, 0x47, 0x63, 0x67, 0x38, 0x52, 0x6E, 0x6F, 0x4E, 0x41, 0x58, 0x33, 0x46, 0x57, 0x4F, 0x64, 0x74, 0x35, 0x6F, 0x55, 0x77, 0x0A, 0x46, 0x35, 0x6F, 0x6B, 0x78, 0x42, 0x44, 0x67, 0x42, 0x50, 0x66, 0x67, 0x38, 0x6E, 0x2F, 0x55, ++ 0x71, 0x67, 0x72, 0x2F, 0x51, 0x68, 0x30, 0x33, 0x37, 0x5A, 0x54, 0x6C, 0x5A, 0x46, 0x6B, 0x53, 0x49, 0x48, 0x63, 0x34, 0x30, 0x7A, 0x49, 0x2B, 0x4F, 0x49, 0x46, 0x31, 0x6C, 0x6E, 0x50, 0x36, 0x61, 0x49, 0x2B, 0x78, 0x79, 0x38, 0x34, 0x66, ++ 0x78, 0x65, 0x7A, 0x36, 0x6E, 0x48, 0x37, 0x50, 0x66, 0x72, 0x48, 0x78, 0x42, 0x79, 0x32, 0x32, 0x2F, 0x4C, 0x2F, 0x4B, 0x0A, 0x70, 0x4C, 0x2F, 0x51, 0x6C, 0x77, 0x56, 0x4B, 0x76, 0x4F, 0x6F, 0x59, 0x4B, 0x41, 0x4B, 0x51, 0x76, 0x56, 0x52, ++ 0x34, 0x43, 0x53, 0x46, 0x78, 0x30, 0x39, 0x46, 0x39, 0x48, 0x64, 0x6B, 0x57, 0x73, 0x4B, 0x6C, 0x68, 0x50, 0x64, 0x41, 0x4B, 0x41, 0x43, 0x4C, 0x38, 0x78, 0x33, 0x76, 0x4C, 0x43, 0x57, 0x52, 0x46, 0x43, 0x7A, 0x74, 0x41, 0x67, 0x66, 0x64, ++ 0x39, 0x66, 0x44, 0x4C, 0x31, 0x6D, 0x4D, 0x70, 0x59, 0x6A, 0x6E, 0x30, 0x71, 0x37, 0x70, 0x42, 0x5A, 0x0A, 0x63, 0x32, 0x54, 0x35, 0x4E, 0x6E, 0x52, 0x65, 0x4A, 0x61, 0x48, 0x31, 0x5A, 0x67, 0x55, 0x75, 0x66, 0x7A, 0x6B, 0x56, 0x71, 0x53, ++ 0x72, 0x37, 0x55, 0x49, 0x75, 0x4F, 0x68, 0x57, 0x6E, 0x30, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x53, 0x74, ++ 0x61, 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, ++ 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x47, 0x32, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, ++ 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x44, 0x37, 0x7A, 0x43, 0x43, 0x41, 0x74, 0x65, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x42, 0x41, 0x44, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, ++ 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x43, 0x42, 0x6D, 0x44, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x56, 0x56, 0x4D, 0x78, 0x45, 0x44, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, ++ 0x42, 0x41, 0x67, 0x54, 0x0A, 0x42, 0x30, 0x46, 0x79, 0x61, 0x58, 0x70, 0x76, 0x62, 0x6D, 0x45, 0x78, 0x45, 0x7A, 0x41, 0x52, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x63, 0x54, 0x43, 0x6C, 0x4E, 0x6A, 0x62, 0x33, 0x52, 0x30, 0x63, 0x32, 0x52, ++ 0x68, 0x62, 0x47, 0x55, 0x78, 0x4A, 0x54, 0x41, 0x6A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x48, 0x46, 0x4E, 0x30, 0x59, 0x58, 0x4A, 0x6D, 0x61, 0x57, 0x56, 0x73, 0x5A, 0x43, 0x42, 0x55, 0x5A, 0x57, 0x4E, 0x6F, 0x62, 0x6D, 0x39, ++ 0x73, 0x0A, 0x62, 0x32, 0x64, 0x70, 0x5A, 0x58, 0x4D, 0x73, 0x49, 0x45, 0x6C, 0x75, 0x59, 0x79, 0x34, 0x78, 0x4F, 0x7A, 0x41, 0x35, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x4D, 0x6C, 0x4E, 0x30, 0x59, 0x58, 0x4A, 0x6D, 0x61, 0x57, ++ 0x56, 0x73, 0x5A, 0x43, 0x42, 0x54, 0x5A, 0x58, 0x4A, 0x32, 0x61, 0x57, 0x4E, 0x6C, 0x63, 0x79, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x6C, 0x63, 0x6E, 0x52, 0x70, 0x5A, 0x6D, 0x6C, 0x6A, 0x59, 0x58, 0x52, 0x6C, 0x0A, 0x49, ++ 0x45, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6D, 0x6C, 0x30, 0x65, 0x53, 0x41, 0x74, 0x49, 0x45, 0x63, 0x79, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x41, 0x35, 0x4D, 0x44, 0x6B, 0x77, 0x4D, 0x54, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x4D, ++ 0x46, 0x6F, 0x58, 0x44, 0x54, 0x4D, 0x33, 0x4D, 0x54, 0x49, 0x7A, 0x4D, 0x54, 0x49, 0x7A, 0x4E, 0x54, 0x6B, 0x31, 0x4F, 0x56, 0x6F, 0x77, 0x67, 0x5A, 0x67, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x0A, 0x42, 0x41, 0x59, 0x54, ++ 0x41, 0x6C, 0x56, 0x54, 0x4D, 0x52, 0x41, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x49, 0x45, 0x77, 0x64, 0x42, 0x63, 0x6D, 0x6C, 0x36, 0x62, 0x32, 0x35, 0x68, 0x4D, 0x52, 0x4D, 0x77, 0x45, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x48, ++ 0x45, 0x77, 0x70, 0x54, 0x59, 0x32, 0x39, 0x30, 0x64, 0x48, 0x4E, 0x6B, 0x59, 0x57, 0x78, 0x6C, 0x4D, 0x53, 0x55, 0x77, 0x49, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x78, 0x78, 0x54, 0x0A, 0x64, 0x47, 0x46, 0x79, 0x5A, 0x6D, 0x6C, ++ 0x6C, 0x62, 0x47, 0x51, 0x67, 0x56, 0x47, 0x56, 0x6A, 0x61, 0x47, 0x35, 0x76, 0x62, 0x47, 0x39, 0x6E, 0x61, 0x57, 0x56, 0x7A, 0x4C, 0x43, 0x42, 0x4A, 0x62, 0x6D, 0x4D, 0x75, 0x4D, 0x54, 0x73, 0x77, 0x4F, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, ++ 0x44, 0x45, 0x7A, 0x4A, 0x54, 0x64, 0x47, 0x46, 0x79, 0x5A, 0x6D, 0x6C, 0x6C, 0x62, 0x47, 0x51, 0x67, 0x55, 0x32, 0x56, 0x79, 0x64, 0x6D, 0x6C, 0x6A, 0x5A, 0x58, 0x4D, 0x67, 0x0A, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x5A, 0x58, ++ 0x4A, 0x30, 0x61, 0x57, 0x5A, 0x70, 0x59, 0x32, 0x46, 0x30, 0x5A, 0x53, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6F, 0x62, 0x33, 0x4A, 0x70, 0x64, 0x48, 0x6B, 0x67, 0x4C, 0x53, 0x42, 0x48, 0x4D, 0x6A, 0x43, 0x43, 0x41, 0x53, 0x49, 0x77, 0x44, 0x51, ++ 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x50, 0x41, 0x44, 0x43, 0x43, 0x0A, 0x41, 0x51, 0x6F, 0x43, 0x67, 0x67, 0x45, 0x42, 0x41, 0x4E, 0x55, 0x4D, 0x4F, ++ 0x73, 0x51, 0x71, 0x2B, 0x55, 0x37, 0x69, 0x39, 0x62, 0x34, 0x5A, 0x6C, 0x31, 0x2B, 0x4F, 0x69, 0x46, 0x4F, 0x78, 0x48, 0x7A, 0x2F, 0x4C, 0x7A, 0x35, 0x38, 0x67, 0x45, 0x32, 0x30, 0x70, 0x4F, 0x73, 0x67, 0x50, 0x66, 0x54, 0x7A, 0x33, 0x61, ++ 0x33, 0x59, 0x34, 0x59, 0x39, 0x6B, 0x32, 0x59, 0x4B, 0x69, 0x62, 0x58, 0x6C, 0x77, 0x41, 0x67, 0x4C, 0x49, 0x76, 0x57, 0x58, 0x2F, 0x32, 0x0A, 0x68, 0x2F, 0x6B, 0x6C, 0x51, 0x34, 0x62, 0x6E, 0x61, 0x52, 0x74, 0x53, 0x6D, 0x70, 0x44, 0x68, ++ 0x63, 0x65, 0x50, 0x59, 0x4C, 0x51, 0x31, 0x4F, 0x62, 0x2F, 0x62, 0x49, 0x53, 0x64, 0x6D, 0x32, 0x38, 0x78, 0x70, 0x57, 0x72, 0x69, 0x75, 0x32, 0x64, 0x42, 0x54, 0x72, 0x7A, 0x2F, 0x73, 0x6D, 0x34, 0x78, 0x71, 0x36, 0x48, 0x5A, 0x59, 0x75, ++ 0x61, 0x6A, 0x74, 0x59, 0x6C, 0x49, 0x6C, 0x48, 0x56, 0x76, 0x38, 0x6C, 0x6F, 0x4A, 0x4E, 0x77, 0x55, 0x34, 0x50, 0x61, 0x0A, 0x68, 0x48, 0x51, 0x55, 0x77, 0x32, 0x65, 0x65, 0x42, 0x47, 0x67, 0x36, 0x33, 0x34, 0x35, 0x41, 0x57, 0x68, 0x31, ++ 0x4B, 0x54, 0x73, 0x39, 0x44, 0x6B, 0x54, 0x76, 0x6E, 0x56, 0x74, 0x59, 0x41, 0x63, 0x4D, 0x74, 0x53, 0x37, 0x6E, 0x74, 0x39, 0x72, 0x6A, 0x72, 0x6E, 0x76, 0x44, 0x48, 0x35, 0x52, 0x66, 0x62, 0x43, 0x59, 0x4D, 0x38, 0x54, 0x57, 0x51, 0x49, ++ 0x72, 0x67, 0x4D, 0x77, 0x30, 0x52, 0x39, 0x2B, 0x35, 0x33, 0x70, 0x42, 0x6C, 0x62, 0x51, 0x4C, 0x50, 0x0A, 0x4C, 0x4A, 0x47, 0x6D, 0x70, 0x75, 0x66, 0x65, 0x68, 0x52, 0x68, 0x4A, 0x66, 0x47, 0x5A, 0x4F, 0x6F, 0x7A, 0x70, 0x74, 0x71, 0x62, ++ 0x58, 0x75, 0x4E, 0x43, 0x36, 0x36, 0x44, 0x51, 0x4F, 0x34, 0x4D, 0x39, 0x39, 0x48, 0x36, 0x37, 0x46, 0x72, 0x6A, 0x53, 0x58, 0x5A, 0x6D, 0x38, 0x36, 0x42, 0x30, 0x55, 0x56, 0x47, 0x4D, 0x70, 0x5A, 0x77, 0x68, 0x39, 0x34, 0x43, 0x44, 0x6B, ++ 0x6C, 0x44, 0x68, 0x62, 0x5A, 0x73, 0x63, 0x37, 0x74, 0x6B, 0x36, 0x6D, 0x46, 0x42, 0x0A, 0x72, 0x4D, 0x6E, 0x55, 0x56, 0x4E, 0x2B, 0x48, 0x4C, 0x38, 0x63, 0x69, 0x73, 0x69, 0x62, 0x4D, 0x6E, 0x31, 0x6C, 0x55, 0x61, 0x4A, 0x2F, 0x38, 0x76, ++ 0x69, 0x6F, 0x76, 0x78, 0x46, 0x55, 0x63, 0x64, 0x55, 0x42, 0x67, 0x46, 0x34, 0x55, 0x43, 0x56, 0x54, 0x6D, 0x4C, 0x66, 0x77, 0x55, 0x43, 0x41, 0x77, 0x45, 0x41, 0x41, 0x61, 0x4E, 0x43, 0x4D, 0x45, 0x41, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, ++ 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x0A, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x51, 0x59, 0x77, ++ 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x46, 0x4A, 0x78, 0x66, 0x41, 0x4E, 0x2B, 0x71, 0x41, 0x64, 0x63, 0x77, 0x4B, 0x7A, 0x69, 0x49, 0x6F, 0x72, 0x68, 0x74, 0x53, 0x70, 0x7A, 0x79, 0x45, 0x5A, 0x47, 0x44, ++ 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x0A, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43, 0x77, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x41, 0x51, 0x42, 0x4C, 0x4E, 0x71, 0x61, 0x45, 0x64, 0x32, 0x6E, 0x64, 0x4F, 0x78, 0x6D, ++ 0x66, 0x5A, 0x79, 0x4D, 0x49, 0x62, 0x77, 0x35, 0x68, 0x79, 0x66, 0x32, 0x45, 0x33, 0x46, 0x2F, 0x59, 0x4E, 0x6F, 0x48, 0x4E, 0x32, 0x42, 0x74, 0x42, 0x4C, 0x5A, 0x39, 0x67, 0x33, 0x63, 0x63, 0x61, 0x61, 0x4E, 0x6E, 0x52, 0x62, 0x6F, 0x62, ++ 0x68, 0x69, 0x43, 0x50, 0x50, 0x0A, 0x45, 0x39, 0x35, 0x44, 0x7A, 0x2B, 0x49, 0x30, 0x73, 0x77, 0x53, 0x64, 0x48, 0x79, 0x6E, 0x56, 0x76, 0x2F, 0x68, 0x65, 0x79, 0x4E, 0x58, 0x42, 0x76, 0x65, 0x36, 0x53, 0x62, 0x7A, 0x4A, 0x30, 0x38, 0x70, ++ 0x47, 0x43, 0x4C, 0x37, 0x32, 0x43, 0x51, 0x6E, 0x71, 0x74, 0x4B, 0x72, 0x63, 0x67, 0x66, 0x55, 0x32, 0x38, 0x65, 0x6C, 0x55, 0x53, 0x77, 0x68, 0x58, 0x71, 0x76, 0x66, 0x64, 0x71, 0x6C, 0x53, 0x35, 0x73, 0x64, 0x4A, 0x2F, 0x50, 0x48, 0x4C, ++ 0x54, 0x79, 0x0A, 0x78, 0x51, 0x47, 0x6A, 0x68, 0x64, 0x42, 0x79, 0x50, 0x71, 0x31, 0x7A, 0x71, 0x77, 0x75, 0x62, 0x64, 0x51, 0x78, 0x74, 0x52, 0x62, 0x65, 0x4F, 0x6C, 0x4B, 0x79, 0x57, 0x4E, 0x37, 0x57, 0x67, 0x30, 0x49, 0x38, 0x56, 0x52, ++ 0x77, 0x37, 0x6A, 0x36, 0x49, 0x50, 0x64, 0x6A, 0x2F, 0x33, 0x76, 0x51, 0x51, 0x46, 0x33, 0x7A, 0x43, 0x65, 0x70, 0x59, 0x6F, 0x55, 0x7A, 0x38, 0x6A, 0x63, 0x49, 0x37, 0x33, 0x48, 0x50, 0x64, 0x77, 0x62, 0x65, 0x79, 0x42, 0x6B, 0x64, 0x0A, ++ 0x69, 0x45, 0x44, 0x50, 0x66, 0x55, 0x59, 0x64, 0x2F, 0x78, 0x37, 0x48, 0x34, 0x63, 0x37, 0x2F, 0x49, 0x39, 0x76, 0x47, 0x2B, 0x6F, 0x31, 0x56, 0x54, 0x71, 0x6B, 0x43, 0x35, 0x30, 0x63, 0x52, 0x52, 0x6A, 0x37, 0x30, 0x2F, 0x62, 0x31, 0x37, ++ 0x4B, 0x53, 0x61, 0x37, 0x71, 0x57, 0x46, 0x69, 0x4E, 0x79, 0x69, 0x32, 0x4C, 0x53, 0x72, 0x32, 0x45, 0x49, 0x5A, 0x6B, 0x79, 0x58, 0x43, 0x6E, 0x30, 0x71, 0x32, 0x33, 0x4B, 0x58, 0x42, 0x35, 0x36, 0x6A, 0x7A, 0x61, 0x0A, 0x59, 0x79, 0x57, ++ 0x66, 0x2F, 0x57, 0x69, 0x33, 0x4D, 0x4F, 0x78, 0x77, 0x2B, 0x33, 0x57, 0x4B, 0x74, 0x32, 0x31, 0x67, 0x5A, 0x37, 0x49, 0x65, 0x79, 0x4C, 0x6E, 0x70, 0x32, 0x4B, 0x68, 0x76, 0x41, 0x6F, 0x74, 0x6E, 0x44, 0x55, 0x30, 0x6D, 0x56, 0x33, 0x48, ++ 0x61, 0x49, 0x50, 0x7A, 0x42, 0x53, 0x6C, 0x43, 0x4E, 0x73, 0x53, 0x69, 0x36, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, ++ 0x0A, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x43, 0x6F, 0x6D, 0x6D, 0x65, 0x72, 0x63, 0x69, 0x61, 0x6C, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x44, 0x54, ++ 0x44, 0x43, 0x43, 0x41, 0x6A, 0x53, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x49, 0x64, 0x33, 0x63, 0x47, 0x4A, 0x79, 0x61, 0x70, 0x73, 0x58, 0x77, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, ++ 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x77, 0x52, 0x44, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x56, 0x56, 0x4D, 0x78, 0x46, 0x44, 0x41, 0x53, 0x0A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, ++ 0x43, 0x30, 0x46, 0x6D, 0x5A, 0x6D, 0x6C, 0x79, 0x62, 0x56, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x4D, 0x52, 0x38, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x42, 0x5A, 0x42, 0x5A, 0x6D, 0x5A, 0x70, 0x63, 0x6D, 0x31, 0x55, ++ 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x43, 0x42, 0x44, 0x62, 0x32, 0x31, 0x74, 0x5A, 0x58, 0x4A, 0x6A, 0x61, 0x57, 0x46, 0x73, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x45, 0x77, 0x0A, 0x4D, 0x44, 0x45, 0x79, 0x4F, 0x54, 0x45, 0x30, 0x4D, 0x44, 0x59, ++ 0x77, 0x4E, 0x6C, 0x6F, 0x58, 0x44, 0x54, 0x4D, 0x77, 0x4D, 0x54, 0x49, 0x7A, 0x4D, 0x54, 0x45, 0x30, 0x4D, 0x44, 0x59, 0x77, 0x4E, 0x6C, 0x6F, 0x77, 0x52, 0x44, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, ++ 0x43, 0x56, 0x56, 0x4D, 0x78, 0x46, 0x44, 0x41, 0x53, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x43, 0x30, 0x46, 0x6D, 0x5A, 0x6D, 0x6C, 0x79, 0x0A, 0x62, 0x56, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x4D, 0x52, 0x38, 0x77, 0x48, 0x51, ++ 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x42, 0x5A, 0x42, 0x5A, 0x6D, 0x5A, 0x70, 0x63, 0x6D, 0x31, 0x55, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x43, 0x42, 0x44, 0x62, 0x32, 0x31, 0x74, 0x5A, 0x58, 0x4A, 0x6A, 0x61, 0x57, 0x46, 0x73, 0x4D, 0x49, ++ 0x49, 0x42, 0x49, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x0A, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x51, 0x38, 0x41, 0x4D, 0x49, 0x49, 0x42, 0x43, 0x67, 0x4B, 0x43, 0x41, ++ 0x51, 0x45, 0x41, 0x39, 0x68, 0x74, 0x50, 0x5A, 0x77, 0x63, 0x72, 0x6F, 0x52, 0x58, 0x31, 0x42, 0x69, 0x4C, 0x4C, 0x48, 0x77, 0x47, 0x79, 0x34, 0x33, 0x4E, 0x46, 0x42, 0x6B, 0x52, 0x4A, 0x4C, 0x4C, 0x74, 0x4A, 0x4A, 0x52, 0x54, 0x57, 0x7A, ++ 0x73, 0x4F, 0x33, 0x71, 0x79, 0x78, 0x50, 0x78, 0x6B, 0x45, 0x79, 0x6C, 0x46, 0x66, 0x36, 0x45, 0x71, 0x64, 0x62, 0x0A, 0x44, 0x75, 0x4B, 0x50, 0x48, 0x78, 0x36, 0x47, 0x47, 0x61, 0x65, 0x71, 0x74, 0x53, 0x32, 0x35, 0x58, 0x77, 0x32, 0x4B, ++ 0x77, 0x71, 0x2B, 0x46, 0x4E, 0x58, 0x6B, 0x79, 0x4C, 0x62, 0x73, 0x63, 0x59, 0x6A, 0x66, 0x79, 0x73, 0x56, 0x74, 0x4B, 0x50, 0x63, 0x72, 0x4E, 0x63, 0x56, 0x2F, 0x70, 0x51, 0x72, 0x36, 0x55, 0x36, 0x4D, 0x6A, 0x65, 0x2B, 0x53, 0x4A, 0x49, ++ 0x5A, 0x4D, 0x62, 0x6C, 0x71, 0x38, 0x59, 0x72, 0x62, 0x61, 0x30, 0x46, 0x38, 0x50, 0x72, 0x56, 0x0A, 0x43, 0x38, 0x2B, 0x61, 0x35, 0x66, 0x42, 0x51, 0x70, 0x49, 0x73, 0x37, 0x52, 0x36, 0x55, 0x6A, 0x57, 0x33, 0x70, 0x36, 0x2B, 0x44, 0x4D, ++ 0x2F, 0x75, 0x4F, 0x2B, 0x5A, 0x6C, 0x2B, 0x4D, 0x67, 0x77, 0x64, 0x59, 0x6F, 0x69, 0x63, 0x2B, 0x55, 0x2B, 0x37, 0x6C, 0x46, 0x37, 0x65, 0x4E, 0x41, 0x46, 0x78, 0x48, 0x55, 0x64, 0x50, 0x41, 0x4C, 0x4D, 0x65, 0x49, 0x72, 0x4A, 0x6D, 0x71, ++ 0x62, 0x54, 0x46, 0x65, 0x75, 0x72, 0x43, 0x41, 0x2B, 0x75, 0x6B, 0x56, 0x36, 0x0A, 0x42, 0x66, 0x4F, 0x39, 0x6D, 0x32, 0x6B, 0x56, 0x72, 0x6E, 0x31, 0x4F, 0x49, 0x47, 0x50, 0x45, 0x4E, 0x58, 0x59, 0x36, 0x42, 0x77, 0x4C, 0x4A, 0x4E, 0x2F, ++ 0x33, 0x48, 0x52, 0x2B, 0x37, 0x6F, 0x38, 0x58, 0x59, 0x64, 0x63, 0x78, 0x58, 0x79, 0x6C, 0x36, 0x53, 0x31, 0x79, 0x48, 0x70, 0x35, 0x32, 0x55, 0x4B, 0x71, 0x4B, 0x33, 0x39, 0x63, 0x2F, 0x73, 0x34, 0x6D, 0x54, 0x36, 0x4E, 0x6D, 0x67, 0x54, ++ 0x57, 0x76, 0x52, 0x4C, 0x70, 0x55, 0x48, 0x68, 0x77, 0x77, 0x0A, 0x4D, 0x6D, 0x57, 0x64, 0x35, 0x6A, 0x79, 0x54, 0x58, 0x6C, 0x42, 0x4F, 0x65, 0x75, 0x4D, 0x36, 0x31, 0x47, 0x37, 0x4D, 0x47, 0x76, 0x76, 0x35, 0x30, 0x6A, 0x65, 0x75, 0x4A, ++ 0x43, 0x71, 0x72, 0x56, 0x77, 0x4D, 0x69, 0x4B, 0x41, 0x31, 0x4A, 0x64, 0x58, 0x2B, 0x33, 0x4B, 0x4E, 0x70, 0x31, 0x76, 0x34, 0x37, 0x6A, 0x33, 0x41, 0x35, 0x35, 0x4D, 0x51, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6F, 0x30, 0x49, 0x77, 0x51, ++ 0x44, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x0A, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x6E, 0x5A, 0x50, 0x47, 0x55, 0x34, 0x74, 0x65, 0x79, 0x71, 0x38, 0x2F, 0x6E, 0x78, 0x34, 0x50, 0x35, 0x5A, 0x6D, 0x56, 0x76, 0x43, 0x54, 0x32, ++ 0x6C, 0x49, 0x38, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, ++ 0x42, 0x41, 0x4D, 0x43, 0x0A, 0x41, 0x51, 0x59, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x42, 0x41, 0x46, 0x69, 0x73, 0x39, 0x41, 0x51, ++ 0x4F, 0x7A, 0x63, 0x41, 0x4E, 0x2F, 0x77, 0x72, 0x39, 0x31, 0x4C, 0x6F, 0x57, 0x58, 0x79, 0x6D, 0x39, 0x65, 0x32, 0x69, 0x5A, 0x57, 0x45, 0x6E, 0x53, 0x74, 0x42, 0x30, 0x33, 0x54, 0x58, 0x38, 0x6E, 0x66, 0x55, 0x59, 0x47, 0x58, 0x55, 0x50, ++ 0x47, 0x0A, 0x68, 0x69, 0x34, 0x2B, 0x63, 0x37, 0x49, 0x6D, 0x66, 0x55, 0x2B, 0x54, 0x71, 0x62, 0x62, 0x45, 0x4B, 0x70, 0x71, 0x72, 0x49, 0x5A, 0x63, 0x55, 0x73, 0x64, 0x36, 0x4D, 0x30, 0x36, 0x75, 0x4A, 0x46, 0x64, 0x68, 0x72, 0x4A, 0x4E, ++ 0x54, 0x78, 0x46, 0x71, 0x37, 0x59, 0x70, 0x46, 0x7A, 0x55, 0x66, 0x31, 0x47, 0x4F, 0x37, 0x52, 0x67, 0x42, 0x73, 0x5A, 0x4E, 0x6A, 0x76, 0x62, 0x7A, 0x34, 0x59, 0x59, 0x43, 0x61, 0x6E, 0x72, 0x48, 0x4F, 0x51, 0x6E, 0x44, 0x69, 0x0A, 0x71, ++ 0x58, 0x30, 0x47, 0x4A, 0x58, 0x30, 0x6E, 0x6F, 0x66, 0x35, 0x76, 0x37, 0x4C, 0x4D, 0x65, 0x4A, 0x4E, 0x72, 0x6A, 0x53, 0x31, 0x55, 0x61, 0x41, 0x44, 0x73, 0x31, 0x74, 0x44, 0x76, 0x5A, 0x31, 0x31, 0x30, 0x77, 0x2F, 0x59, 0x45, 0x54, 0x69, ++ 0x66, 0x4C, 0x43, 0x42, 0x69, 0x76, 0x74, 0x5A, 0x38, 0x53, 0x4F, 0x79, 0x55, 0x4F, 0x79, 0x58, 0x47, 0x73, 0x56, 0x69, 0x51, 0x4B, 0x38, 0x59, 0x76, 0x78, 0x4F, 0x38, 0x72, 0x55, 0x7A, 0x71, 0x72, 0x4A, 0x76, 0x0A, 0x30, 0x77, 0x71, 0x69, ++ 0x55, 0x4F, 0x50, 0x32, 0x4F, 0x2B, 0x67, 0x75, 0x52, 0x4D, 0x4C, 0x62, 0x5A, 0x6A, 0x69, 0x70, 0x4D, 0x31, 0x5A, 0x49, 0x38, 0x57, 0x30, 0x62, 0x4D, 0x34, 0x30, 0x4E, 0x6A, 0x44, 0x39, 0x67, 0x4E, 0x35, 0x33, 0x54, 0x79, 0x6D, 0x31, 0x2B, ++ 0x4E, 0x48, 0x34, 0x4E, 0x6E, 0x33, 0x4A, 0x32, 0x69, 0x78, 0x75, 0x66, 0x63, 0x76, 0x31, 0x53, 0x4E, 0x55, 0x46, 0x46, 0x41, 0x70, 0x59, 0x76, 0x48, 0x4C, 0x4B, 0x61, 0x63, 0x30, 0x6B, 0x68, 0x0A, 0x73, 0x55, 0x6C, 0x48, 0x52, 0x55, 0x65, ++ 0x30, 0x37, 0x32, 0x6F, 0x30, 0x45, 0x63, 0x6C, 0x4E, 0x6D, 0x73, 0x78, 0x5A, 0x74, 0x39, 0x59, 0x43, 0x6E, 0x6C, 0x70, 0x4F, 0x5A, 0x62, 0x57, 0x55, 0x72, 0x68, 0x76, 0x66, 0x4B, 0x62, 0x41, 0x57, 0x38, 0x62, 0x38, 0x41, 0x6E, 0x67, 0x63, ++ 0x36, 0x46, 0x32, 0x53, 0x31, 0x42, 0x4C, 0x55, 0x6A, 0x49, 0x5A, 0x6B, 0x4B, 0x6C, 0x54, 0x75, 0x58, 0x66, 0x4F, 0x38, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, ++ 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x69, 0x6E, 0x67, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, ++ 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x44, 0x54, 0x44, 0x43, 0x43, 0x41, 0x6A, 0x53, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x49, 0x66, 0x45, 0x38, 0x45, 0x4F, 0x52, 0x7A, 0x55, 0x6D, 0x53, 0x30, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, ++ 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x46, 0x42, 0x51, 0x41, 0x77, 0x52, 0x44, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x56, 0x56, 0x4D, 0x78, 0x46, 0x44, 0x41, 0x53, 0x0A, ++ 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x43, 0x30, 0x46, 0x6D, 0x5A, 0x6D, 0x6C, 0x79, 0x62, 0x56, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x4D, 0x52, 0x38, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x42, 0x5A, 0x42, ++ 0x5A, 0x6D, 0x5A, 0x70, 0x63, 0x6D, 0x31, 0x55, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x43, 0x42, 0x4F, 0x5A, 0x58, 0x52, 0x33, 0x62, 0x33, 0x4A, 0x72, 0x61, 0x57, 0x35, 0x6E, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x45, 0x77, 0x0A, 0x4D, 0x44, 0x45, ++ 0x79, 0x4F, 0x54, 0x45, 0x30, 0x4D, 0x44, 0x67, 0x79, 0x4E, 0x46, 0x6F, 0x58, 0x44, 0x54, 0x4D, 0x77, 0x4D, 0x54, 0x49, 0x7A, 0x4D, 0x54, 0x45, 0x30, 0x4D, 0x44, 0x67, 0x79, 0x4E, 0x46, 0x6F, 0x77, 0x52, 0x44, 0x45, 0x4C, 0x4D, 0x41, 0x6B, ++ 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x56, 0x56, 0x4D, 0x78, 0x46, 0x44, 0x41, 0x53, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x43, 0x30, 0x46, 0x6D, 0x5A, 0x6D, 0x6C, 0x79, 0x0A, 0x62, 0x56, 0x52, 0x79, 0x64, 0x58, ++ 0x4E, 0x30, 0x4D, 0x52, 0x38, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x42, 0x5A, 0x42, 0x5A, 0x6D, 0x5A, 0x70, 0x63, 0x6D, 0x31, 0x55, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x43, 0x42, 0x4F, 0x5A, 0x58, 0x52, 0x33, 0x62, 0x33, ++ 0x4A, 0x72, 0x61, 0x57, 0x35, 0x6E, 0x4D, 0x49, 0x49, 0x42, 0x49, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x0A, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x51, 0x38, 0x41, 0x4D, ++ 0x49, 0x49, 0x42, 0x43, 0x67, 0x4B, 0x43, 0x41, 0x51, 0x45, 0x41, 0x74, 0x49, 0x54, 0x4D, 0x4D, 0x78, 0x63, 0x75, 0x61, 0x35, 0x52, 0x73, 0x61, 0x32, 0x46, 0x53, 0x6F, 0x4F, 0x75, 0x6A, 0x7A, 0x33, 0x6D, 0x55, 0x54, 0x4F, 0x57, 0x55, 0x67, ++ 0x4A, 0x6E, 0x4C, 0x56, 0x57, 0x52, 0x45, 0x5A, 0x59, 0x39, 0x6E, 0x5A, 0x4F, 0x49, 0x47, 0x34, 0x31, 0x77, 0x33, 0x53, 0x66, 0x59, 0x76, 0x6D, 0x34, 0x53, 0x45, 0x0A, 0x48, 0x69, 0x33, 0x79, 0x59, 0x4A, 0x30, 0x77, 0x54, 0x73, 0x79, 0x45, ++ 0x68, 0x65, 0x49, 0x73, 0x7A, 0x78, 0x36, 0x65, 0x2F, 0x6A, 0x61, 0x72, 0x4D, 0x33, 0x63, 0x31, 0x52, 0x4E, 0x67, 0x31, 0x6C, 0x68, 0x6F, 0x39, 0x4E, 0x75, 0x68, 0x36, 0x44, 0x74, 0x6A, 0x56, 0x52, 0x36, 0x46, 0x71, 0x61, 0x59, 0x76, 0x5A, ++ 0x2F, 0x4C, 0x73, 0x36, 0x72, 0x6E, 0x6C, 0x61, 0x31, 0x66, 0x54, 0x57, 0x63, 0x62, 0x75, 0x61, 0x6B, 0x43, 0x4E, 0x72, 0x6D, 0x72, 0x65, 0x49, 0x0A, 0x64, 0x49, 0x63, 0x4D, 0x48, 0x6C, 0x2B, 0x35, 0x6E, 0x69, 0x33, 0x36, 0x71, 0x31, 0x4D, ++ 0x72, 0x33, 0x4C, 0x74, 0x32, 0x50, 0x70, 0x4E, 0x4D, 0x43, 0x41, 0x69, 0x4D, 0x48, 0x71, 0x49, 0x6A, 0x48, 0x4E, 0x52, 0x71, 0x72, 0x53, 0x4B, 0x36, 0x6D, 0x51, 0x45, 0x75, 0x62, 0x57, 0x58, 0x4C, 0x76, 0x69, 0x52, 0x6D, 0x56, 0x53, 0x52, ++ 0x4C, 0x51, 0x45, 0x53, 0x78, 0x47, 0x39, 0x66, 0x68, 0x77, 0x6F, 0x58, 0x41, 0x33, 0x68, 0x41, 0x2F, 0x50, 0x65, 0x32, 0x34, 0x0A, 0x2F, 0x50, 0x48, 0x78, 0x49, 0x31, 0x50, 0x63, 0x76, 0x32, 0x57, 0x58, 0x62, 0x39, 0x6E, 0x35, 0x51, 0x48, ++ 0x47, 0x4E, 0x66, 0x62, 0x32, 0x56, 0x31, 0x4D, 0x36, 0x2B, 0x6F, 0x46, 0x34, 0x6E, 0x49, 0x39, 0x37, 0x39, 0x70, 0x74, 0x41, 0x6D, 0x44, 0x67, 0x41, 0x70, 0x36, 0x7A, 0x78, 0x47, 0x38, 0x44, 0x31, 0x67, 0x76, 0x7A, 0x39, 0x51, 0x30, 0x74, ++ 0x77, 0x6D, 0x51, 0x56, 0x47, 0x65, 0x46, 0x44, 0x64, 0x43, 0x42, 0x4B, 0x4E, 0x77, 0x56, 0x36, 0x67, 0x62, 0x0A, 0x68, 0x2B, 0x30, 0x74, 0x2B, 0x6E, 0x76, 0x75, 0x6A, 0x41, 0x72, 0x6A, 0x71, 0x57, 0x61, 0x4A, 0x47, 0x63, 0x74, 0x42, 0x2B, ++ 0x64, 0x31, 0x45, 0x4E, 0x6D, 0x48, 0x50, 0x34, 0x6E, 0x64, 0x47, 0x79, 0x48, 0x33, 0x32, 0x39, 0x4A, 0x4B, 0x42, 0x4E, 0x76, 0x33, 0x62, 0x4E, 0x50, 0x46, 0x79, 0x66, 0x76, 0x4D, 0x4D, 0x46, 0x72, 0x32, 0x30, 0x46, 0x51, 0x49, 0x44, 0x41, ++ 0x51, 0x41, 0x42, 0x6F, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x0A, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x42, 0x78, 0x2F, 0x53, 0x35, 0x35, 0x7A, 0x61, 0x77, 0x6D, 0x36, 0x69, 0x51, 0x4C, 0x53, 0x77, ++ 0x65, 0x6C, 0x41, 0x51, 0x55, 0x48, 0x54, 0x45, 0x79, 0x4C, 0x30, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, ++ 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x0A, 0x41, 0x51, 0x59, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x46, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, ++ 0x42, 0x41, 0x49, 0x6C, 0x58, 0x73, 0x68, 0x5A, 0x36, 0x71, 0x4D, 0x4C, 0x39, 0x31, 0x74, 0x6D, 0x62, 0x6D, 0x7A, 0x54, 0x43, 0x6E, 0x4C, 0x51, 0x79, 0x46, 0x45, 0x32, 0x6E, 0x70, 0x4E, 0x2F, 0x73, 0x76, 0x71, 0x65, 0x2B, 0x2B, 0x45, 0x50, ++ 0x62, 0x6B, 0x54, 0x66, 0x4F, 0x74, 0x44, 0x49, 0x75, 0x0A, 0x55, 0x46, 0x55, 0x61, 0x4E, 0x55, 0x35, 0x32, 0x51, 0x33, 0x45, 0x67, 0x37, 0x35, 0x4E, 0x33, 0x54, 0x68, 0x56, 0x77, 0x4C, 0x6F, 0x66, 0x44, 0x77, 0x52, 0x31, 0x74, 0x33, 0x4D, ++ 0x75, 0x31, 0x4A, 0x39, 0x51, 0x73, 0x56, 0x74, 0x46, 0x53, 0x55, 0x7A, 0x70, 0x45, 0x30, 0x6E, 0x50, 0x49, 0x78, 0x42, 0x73, 0x46, 0x5A, 0x56, 0x70, 0x69, 0x6B, 0x70, 0x7A, 0x75, 0x51, 0x59, 0x30, 0x78, 0x32, 0x2B, 0x63, 0x30, 0x36, 0x6C, ++ 0x6B, 0x68, 0x31, 0x51, 0x46, 0x36, 0x0A, 0x31, 0x32, 0x53, 0x34, 0x5A, 0x44, 0x6E, 0x4E, 0x79, 0x65, 0x32, 0x76, 0x37, 0x55, 0x73, 0x44, 0x53, 0x4B, 0x65, 0x67, 0x6D, 0x51, 0x47, 0x41, 0x33, 0x47, 0x57, 0x6A, 0x4E, 0x71, 0x35, 0x6C, 0x57, ++ 0x55, 0x68, 0x50, 0x67, 0x6B, 0x76, 0x49, 0x5A, 0x66, 0x46, 0x58, 0x48, 0x65, 0x56, 0x5A, 0x4C, 0x67, 0x6F, 0x2F, 0x62, 0x4E, 0x6A, 0x52, 0x39, 0x65, 0x55, 0x4A, 0x74, 0x47, 0x78, 0x55, 0x41, 0x41, 0x72, 0x67, 0x46, 0x55, 0x32, 0x48, 0x64, ++ 0x57, 0x32, 0x33, 0x0A, 0x57, 0x4A, 0x5A, 0x61, 0x33, 0x57, 0x33, 0x53, 0x41, 0x4B, 0x44, 0x30, 0x6D, 0x30, 0x69, 0x2B, 0x77, 0x7A, 0x65, 0x6B, 0x75, 0x6A, 0x62, 0x67, 0x66, 0x49, 0x65, 0x46, 0x6C, 0x78, 0x6F, 0x56, 0x6F, 0x74, 0x34, 0x75, ++ 0x6F, 0x6C, 0x75, 0x39, 0x72, 0x78, 0x6A, 0x35, 0x6B, 0x46, 0x44, 0x4E, 0x63, 0x46, 0x6E, 0x34, 0x4A, 0x32, 0x64, 0x48, 0x79, 0x38, 0x65, 0x67, 0x42, 0x7A, 0x70, 0x39, 0x30, 0x53, 0x78, 0x64, 0x62, 0x42, 0x6B, 0x36, 0x5A, 0x72, 0x56, 0x39, ++ 0x0A, 0x2F, 0x5A, 0x46, 0x76, 0x67, 0x72, 0x47, 0x2B, 0x43, 0x4A, 0x50, 0x62, 0x46, 0x45, 0x66, 0x78, 0x6F, 0x6A, 0x66, 0x48, 0x52, 0x5A, 0x34, 0x38, 0x78, 0x33, 0x65, 0x76, 0x5A, 0x4B, 0x69, 0x54, 0x33, 0x2F, 0x5A, 0x70, 0x67, 0x34, 0x4A, ++ 0x67, 0x38, 0x6B, 0x6C, 0x43, 0x4E, 0x4F, 0x31, 0x61, 0x41, 0x46, 0x53, 0x46, 0x48, 0x42, 0x59, 0x32, 0x6B, 0x67, 0x78, 0x63, 0x2B, 0x71, 0x61, 0x74, 0x76, 0x39, 0x73, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, ++ 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x72, 0x65, 0x6D, 0x69, 0x75, 0x6D, 0x0A, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, ++ 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x52, 0x6A, 0x43, 0x43, 0x41, 0x79, 0x36, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x49, 0x62, 0x59, 0x77, 0x55, 0x52, 0x72, 0x47, 0x6D, 0x43, 0x75, 0x34, 0x77, 0x44, 0x51, 0x59, ++ 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4D, 0x42, 0x51, 0x41, 0x77, 0x51, 0x54, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x56, 0x56, 0x4D, 0x78, 0x46, 0x44, 0x41, ++ 0x53, 0x0A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x43, 0x30, 0x46, 0x6D, 0x5A, 0x6D, 0x6C, 0x79, 0x62, 0x56, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x4D, 0x52, 0x77, 0x77, 0x47, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x42, ++ 0x4E, 0x42, 0x5A, 0x6D, 0x5A, 0x70, 0x63, 0x6D, 0x31, 0x55, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x43, 0x42, 0x51, 0x63, 0x6D, 0x56, 0x74, 0x61, 0x58, 0x56, 0x74, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x45, 0x77, 0x4D, 0x44, 0x45, 0x79, 0x0A, 0x4F, ++ 0x54, 0x45, 0x30, 0x4D, 0x54, 0x41, 0x7A, 0x4E, 0x6C, 0x6F, 0x58, 0x44, 0x54, 0x51, 0x77, 0x4D, 0x54, 0x49, 0x7A, 0x4D, 0x54, 0x45, 0x30, 0x4D, 0x54, 0x41, 0x7A, 0x4E, 0x6C, 0x6F, 0x77, 0x51, 0x54, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, ++ 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x56, 0x56, 0x4D, 0x78, 0x46, 0x44, 0x41, 0x53, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x43, 0x30, 0x46, 0x6D, 0x5A, 0x6D, 0x6C, 0x79, 0x62, 0x56, 0x52, 0x79, 0x0A, 0x64, 0x58, 0x4E, 0x30, ++ 0x4D, 0x52, 0x77, 0x77, 0x47, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x42, 0x4E, 0x42, 0x5A, 0x6D, 0x5A, 0x70, 0x63, 0x6D, 0x31, 0x55, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x43, 0x42, 0x51, 0x63, 0x6D, 0x56, 0x74, 0x61, 0x58, 0x56, 0x74, ++ 0x4D, 0x49, 0x49, 0x43, 0x49, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x67, 0x38, 0x41, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x43, 0x67, 0x4B, ++ 0x43, 0x41, 0x67, 0x45, 0x41, 0x78, 0x42, 0x4C, 0x66, 0x71, 0x56, 0x2F, 0x2B, 0x51, 0x64, 0x33, 0x64, 0x39, 0x5A, 0x2B, 0x4B, 0x34, 0x2F, 0x61, 0x73, 0x34, 0x54, 0x78, 0x34, 0x6D, 0x72, 0x7A, 0x59, 0x38, 0x48, 0x39, 0x36, 0x6F, 0x44, 0x4D, ++ 0x71, 0x33, 0x49, 0x30, 0x67, 0x57, 0x36, 0x34, 0x74, 0x62, 0x2B, 0x65, 0x54, 0x32, 0x54, 0x5A, 0x77, 0x61, 0x6D, 0x6A, 0x50, 0x6A, 0x6C, 0x47, 0x6A, 0x68, 0x56, 0x74, 0x6E, 0x0A, 0x42, 0x4B, 0x41, 0x51, 0x4A, 0x47, 0x39, 0x64, 0x4B, 0x49, ++ 0x4C, 0x42, 0x6C, 0x31, 0x66, 0x59, 0x53, 0x43, 0x6B, 0x54, 0x74, 0x75, 0x47, 0x2B, 0x6B, 0x55, 0x33, 0x66, 0x68, 0x51, 0x78, 0x54, 0x47, 0x4A, 0x6F, 0x65, 0x4A, 0x4B, 0x4A, 0x50, 0x6A, 0x2F, 0x43, 0x69, 0x68, 0x51, 0x76, 0x4C, 0x39, 0x43, ++ 0x6C, 0x2F, 0x30, 0x71, 0x52, 0x59, 0x37, 0x69, 0x5A, 0x4E, 0x79, 0x61, 0x71, 0x6F, 0x65, 0x35, 0x72, 0x5A, 0x2B, 0x6A, 0x6A, 0x65, 0x52, 0x46, 0x63, 0x56, 0x0A, 0x35, 0x66, 0x69, 0x4D, 0x79, 0x4E, 0x6C, 0x49, 0x34, 0x67, 0x30, 0x57, 0x4A, ++ 0x78, 0x30, 0x65, 0x79, 0x49, 0x4F, 0x46, 0x4A, 0x62, 0x65, 0x36, 0x71, 0x6C, 0x56, 0x42, 0x7A, 0x41, 0x4D, 0x69, 0x53, 0x79, 0x32, 0x52, 0x6A, 0x59, 0x76, 0x6D, 0x69, 0x61, 0x39, 0x6D, 0x78, 0x2B, 0x6E, 0x2F, 0x4B, 0x2B, 0x6B, 0x38, 0x72, ++ 0x4E, 0x72, 0x53, 0x73, 0x38, 0x50, 0x68, 0x61, 0x4A, 0x79, 0x4A, 0x2B, 0x48, 0x6F, 0x41, 0x56, 0x74, 0x37, 0x30, 0x56, 0x5A, 0x56, 0x73, 0x0A, 0x2B, 0x37, 0x70, 0x6B, 0x33, 0x57, 0x4B, 0x4C, 0x33, 0x77, 0x74, 0x33, 0x4D, 0x75, 0x74, 0x69, ++ 0x7A, 0x43, 0x61, 0x61, 0x6D, 0x37, 0x75, 0x71, 0x59, 0x6F, 0x4E, 0x4D, 0x74, 0x41, 0x5A, 0x36, 0x4D, 0x4D, 0x67, 0x70, 0x76, 0x2B, 0x30, 0x47, 0x54, 0x5A, 0x65, 0x35, 0x48, 0x4D, 0x51, 0x78, 0x4B, 0x39, 0x56, 0x66, 0x76, 0x46, 0x4D, 0x53, ++ 0x46, 0x35, 0x79, 0x5A, 0x56, 0x79, 0x6C, 0x6D, 0x64, 0x32, 0x45, 0x68, 0x4D, 0x51, 0x63, 0x75, 0x4A, 0x55, 0x6D, 0x64, 0x0A, 0x47, 0x50, 0x4C, 0x75, 0x38, 0x79, 0x74, 0x78, 0x6A, 0x4C, 0x57, 0x36, 0x4F, 0x51, 0x64, 0x4A, 0x64, 0x2F, 0x7A, ++ 0x76, 0x4C, 0x70, 0x4B, 0x51, 0x42, 0x59, 0x30, 0x74, 0x4C, 0x33, 0x64, 0x37, 0x37, 0x30, 0x4F, 0x2F, 0x4E, 0x62, 0x75, 0x61, 0x32, 0x50, 0x6C, 0x7A, 0x70, 0x79, 0x7A, 0x79, 0x30, 0x46, 0x66, 0x75, 0x4B, 0x45, 0x34, 0x6D, 0x58, 0x34, 0x2B, ++ 0x51, 0x61, 0x41, 0x6B, 0x76, 0x75, 0x50, 0x6A, 0x63, 0x42, 0x75, 0x6B, 0x75, 0x6D, 0x6A, 0x35, 0x52, 0x0A, 0x70, 0x39, 0x45, 0x69, 0x78, 0x41, 0x71, 0x6E, 0x4F, 0x45, 0x68, 0x73, 0x73, 0x2F, 0x6E, 0x2F, 0x66, 0x61, 0x75, 0x47, 0x56, 0x2B, ++ 0x4F, 0x36, 0x31, 0x6F, 0x56, 0x34, 0x64, 0x37, 0x70, 0x44, 0x36, 0x6B, 0x68, 0x2F, 0x39, 0x74, 0x69, 0x2B, 0x49, 0x32, 0x30, 0x65, 0x76, 0x39, 0x45, 0x32, 0x62, 0x46, 0x68, 0x63, 0x38, 0x65, 0x36, 0x6B, 0x47, 0x56, 0x51, 0x61, 0x39, 0x51, ++ 0x50, 0x53, 0x64, 0x75, 0x62, 0x68, 0x6A, 0x4C, 0x30, 0x38, 0x73, 0x39, 0x4E, 0x49, 0x0A, 0x53, 0x2B, 0x4C, 0x49, 0x2B, 0x48, 0x2B, 0x53, 0x71, 0x48, 0x5A, 0x47, 0x6E, 0x45, 0x4A, 0x6C, 0x50, 0x71, 0x51, 0x65, 0x77, 0x51, 0x63, 0x44, 0x57, ++ 0x6B, 0x59, 0x74, 0x75, 0x4A, 0x66, 0x7A, 0x74, 0x39, 0x57, 0x79, 0x56, 0x53, 0x48, 0x76, 0x75, 0x74, 0x78, 0x4D, 0x41, 0x4A, 0x66, 0x37, 0x46, 0x4A, 0x55, 0x6E, 0x4D, 0x37, 0x2F, 0x6F, 0x51, 0x30, 0x64, 0x47, 0x30, 0x67, 0x69, 0x5A, 0x46, ++ 0x6D, 0x41, 0x37, 0x6D, 0x6E, 0x37, 0x53, 0x35, 0x75, 0x30, 0x34, 0x0A, 0x36, 0x75, 0x77, 0x42, 0x48, 0x6A, 0x78, 0x49, 0x56, 0x6B, 0x6B, 0x4A, 0x78, 0x30, 0x77, 0x33, 0x41, 0x4A, 0x36, 0x49, 0x44, 0x73, 0x42, 0x7A, 0x34, 0x57, 0x39, 0x6D, ++ 0x36, 0x58, 0x4A, 0x48, 0x4D, 0x44, 0x34, 0x51, 0x35, 0x51, 0x73, 0x44, 0x79, 0x5A, 0x70, 0x43, 0x41, 0x47, 0x7A, 0x46, 0x6C, 0x48, 0x35, 0x68, 0x78, 0x49, 0x72, 0x66, 0x66, 0x34, 0x49, 0x61, 0x43, 0x31, 0x6E, 0x45, 0x57, 0x54, 0x4A, 0x33, ++ 0x73, 0x37, 0x78, 0x67, 0x61, 0x56, 0x59, 0x35, 0x0A, 0x2F, 0x62, 0x51, 0x47, 0x65, 0x79, 0x7A, 0x57, 0x5A, 0x44, 0x62, 0x5A, 0x76, 0x55, 0x6A, 0x74, 0x68, 0x42, 0x39, 0x2B, 0x70, 0x53, 0x4B, 0x50, 0x4B, 0x72, 0x68, 0x43, 0x39, 0x49, 0x4B, ++ 0x33, 0x31, 0x46, 0x4F, 0x51, 0x65, 0x45, 0x34, 0x74, 0x47, 0x76, 0x32, 0x42, 0x62, 0x30, 0x54, 0x58, 0x4F, 0x77, 0x46, 0x30, 0x6C, 0x6B, 0x4C, 0x67, 0x41, 0x4F, 0x49, 0x75, 0x61, 0x2B, 0x72, 0x46, 0x37, 0x6E, 0x4B, 0x73, 0x75, 0x37, 0x2F, ++ 0x2B, 0x36, 0x71, 0x71, 0x6F, 0x0A, 0x2B, 0x4E, 0x7A, 0x32, 0x73, 0x6E, 0x6D, 0x4B, 0x74, 0x6D, 0x63, 0x43, 0x41, 0x77, 0x45, 0x41, 0x41, 0x61, 0x4E, 0x43, 0x4D, 0x45, 0x41, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, ++ 0x59, 0x45, 0x46, 0x4A, 0x33, 0x41, 0x5A, 0x36, 0x59, 0x4D, 0x49, 0x74, 0x6B, 0x6D, 0x39, 0x55, 0x57, 0x72, 0x70, 0x6D, 0x56, 0x53, 0x45, 0x53, 0x66, 0x59, 0x52, 0x61, 0x78, 0x6A, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, ++ 0x45, 0x42, 0x0A, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4D, 0x41, 0x30, 0x47, 0x43, ++ 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x44, 0x41, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x41, 0x51, 0x43, 0x7A, 0x56, 0x30, 0x30, 0x51, 0x59, 0x6B, 0x34, 0x36, 0x35, 0x4B, 0x7A, 0x71, 0x75, 0x42, 0x79, 0x76, 0x0A, ++ 0x4D, 0x69, 0x50, 0x49, 0x73, 0x30, 0x6C, 0x61, 0x55, 0x5A, 0x78, 0x32, 0x4B, 0x49, 0x31, 0x35, 0x71, 0x6C, 0x64, 0x47, 0x46, 0x39, 0x58, 0x31, 0x55, 0x76, 0x61, 0x33, 0x52, 0x4F, 0x67, 0x49, 0x52, 0x4C, 0x38, 0x59, 0x68, 0x4E, 0x49, 0x4C, ++ 0x67, 0x4D, 0x33, 0x46, 0x45, 0x76, 0x30, 0x41, 0x56, 0x51, 0x56, 0x68, 0x68, 0x30, 0x48, 0x63, 0x74, 0x53, 0x53, 0x65, 0x50, 0x4D, 0x54, 0x59, 0x79, 0x50, 0x74, 0x77, 0x6E, 0x69, 0x39, 0x34, 0x6C, 0x6F, 0x4D, 0x67, 0x0A, 0x4E, 0x74, 0x35, ++ 0x38, 0x44, 0x32, 0x6B, 0x54, 0x69, 0x4B, 0x56, 0x31, 0x4E, 0x70, 0x67, 0x49, 0x70, 0x73, 0x62, 0x66, 0x72, 0x4D, 0x37, 0x6A, 0x57, 0x4E, 0x61, 0x33, 0x50, 0x74, 0x36, 0x36, 0x38, 0x2B, 0x73, 0x30, 0x51, 0x4E, 0x69, 0x69, 0x67, 0x66, 0x56, ++ 0x34, 0x50, 0x79, 0x2F, 0x56, 0x70, 0x66, 0x7A, 0x5A, 0x6F, 0x74, 0x52, 0x65, 0x42, 0x41, 0x34, 0x58, 0x72, 0x66, 0x35, 0x42, 0x38, 0x4F, 0x57, 0x79, 0x63, 0x76, 0x70, 0x45, 0x67, 0x6A, 0x4E, 0x43, 0x0A, 0x36, 0x43, 0x31, 0x59, 0x39, 0x31, ++ 0x61, 0x4D, 0x59, 0x6A, 0x2B, 0x36, 0x51, 0x72, 0x43, 0x63, 0x44, 0x46, 0x78, 0x2B, 0x4C, 0x6D, 0x55, 0x6D, 0x58, 0x46, 0x4E, 0x50, 0x41, 0x4C, 0x4A, 0x34, 0x66, 0x71, 0x45, 0x4E, 0x6D, 0x53, 0x32, 0x4E, 0x75, 0x42, 0x32, 0x4F, 0x6F, 0x73, ++ 0x53, 0x77, 0x2F, 0x57, 0x44, 0x51, 0x4D, 0x4B, 0x53, 0x4F, 0x79, 0x41, 0x52, 0x69, 0x71, 0x63, 0x54, 0x74, 0x4E, 0x64, 0x35, 0x36, 0x6C, 0x2B, 0x30, 0x4F, 0x4F, 0x46, 0x36, 0x53, 0x0A, 0x4C, 0x35, 0x4E, 0x77, 0x70, 0x61, 0x6D, 0x63, 0x62, ++ 0x36, 0x64, 0x39, 0x45, 0x78, 0x31, 0x2B, 0x78, 0x67, 0x68, 0x49, 0x73, 0x56, 0x35, 0x6E, 0x36, 0x31, 0x45, 0x49, 0x4A, 0x65, 0x6E, 0x6D, 0x4A, 0x57, 0x74, 0x53, 0x4B, 0x5A, 0x47, 0x63, 0x30, 0x6A, 0x6C, 0x7A, 0x43, 0x46, 0x66, 0x65, 0x6D, ++ 0x51, 0x61, 0x30, 0x57, 0x35, 0x30, 0x51, 0x42, 0x75, 0x48, 0x43, 0x41, 0x4B, 0x69, 0x34, 0x48, 0x45, 0x6F, 0x43, 0x43, 0x68, 0x54, 0x51, 0x77, 0x55, 0x48, 0x4B, 0x0A, 0x2B, 0x34, 0x77, 0x31, 0x49, 0x58, 0x32, 0x43, 0x4F, 0x50, 0x4B, 0x70, ++ 0x56, 0x4A, 0x45, 0x5A, 0x4E, 0x5A, 0x4F, 0x55, 0x62, 0x57, 0x6F, 0x36, 0x78, 0x62, 0x4C, 0x51, 0x75, 0x34, 0x6D, 0x47, 0x6B, 0x2B, 0x69, 0x62, 0x79, 0x51, 0x38, 0x36, 0x70, 0x33, 0x71, 0x34, 0x6F, 0x66, 0x42, 0x34, 0x52, 0x76, 0x72, 0x38, ++ 0x4E, 0x79, 0x2F, 0x6C, 0x69, 0x6F, 0x54, 0x7A, 0x33, 0x2F, 0x34, 0x45, 0x32, 0x61, 0x46, 0x6F, 0x6F, 0x43, 0x38, 0x6B, 0x34, 0x67, 0x6D, 0x56, 0x0A, 0x42, 0x74, 0x57, 0x56, 0x79, 0x75, 0x45, 0x6B, 0x6C, 0x75, 0x74, 0x38, 0x39, 0x70, 0x4D, ++ 0x46, 0x75, 0x2B, 0x31, 0x7A, 0x36, 0x53, 0x33, 0x52, 0x64, 0x54, 0x6E, 0x58, 0x35, 0x79, 0x54, 0x62, 0x32, 0x45, 0x35, 0x66, 0x51, 0x34, 0x2B, 0x65, 0x30, 0x42, 0x51, 0x35, 0x76, 0x31, 0x56, 0x77, 0x53, 0x4A, 0x6C, 0x58, 0x4D, 0x62, 0x53, ++ 0x63, 0x37, 0x6B, 0x71, 0x59, 0x41, 0x35, 0x59, 0x77, 0x48, 0x32, 0x41, 0x47, 0x37, 0x68, 0x73, 0x6A, 0x2F, 0x6F, 0x46, 0x67, 0x0A, 0x49, 0x78, 0x70, 0x48, 0x59, 0x6F, 0x57, 0x6C, 0x7A, 0x42, 0x6B, 0x30, 0x67, 0x47, 0x2B, 0x7A, 0x72, 0x42, ++ 0x72, 0x6A, 0x6E, 0x2F, 0x42, 0x37, 0x53, 0x4B, 0x33, 0x56, 0x41, 0x64, 0x6C, 0x6E, 0x74, 0x71, 0x6C, 0x79, 0x6B, 0x2B, 0x6F, 0x74, 0x5A, 0x72, 0x57, 0x79, 0x75, 0x4F, 0x51, 0x39, 0x50, 0x4C, 0x4C, 0x76, 0x54, 0x49, 0x7A, 0x71, 0x36, 0x77, ++ 0x65, 0x2F, 0x71, 0x7A, 0x57, 0x61, 0x56, 0x59, 0x61, 0x38, 0x47, 0x4B, 0x61, 0x31, 0x71, 0x46, 0x36, 0x30, 0x0A, 0x67, 0x32, 0x78, 0x72, 0x61, 0x55, 0x44, 0x54, 0x6E, 0x39, 0x7A, 0x78, 0x77, 0x32, 0x6C, 0x72, 0x75, 0x65, 0x46, 0x74, 0x43, ++ 0x66, 0x54, 0x78, 0x71, 0x6C, 0x42, 0x32, 0x43, 0x6E, 0x70, 0x39, 0x65, 0x68, 0x65, 0x68, 0x56, 0x5A, 0x5A, 0x43, 0x6D, 0x54, 0x45, 0x4A, 0x33, 0x57, 0x41, 0x52, 0x6A, 0x51, 0x55, 0x77, 0x66, 0x75, 0x61, 0x4F, 0x52, 0x74, 0x47, 0x64, 0x46, ++ 0x4E, 0x72, 0x48, 0x46, 0x2B, 0x51, 0x46, 0x6C, 0x6F, 0x7A, 0x45, 0x4A, 0x4C, 0x55, 0x62, 0x0A, 0x7A, 0x78, 0x51, 0x48, 0x73, 0x6B, 0x44, 0x34, 0x6F, 0x35, 0x35, 0x42, 0x68, 0x72, 0x77, 0x45, 0x30, 0x47, 0x75, 0x57, 0x79, 0x43, 0x71, 0x41, ++ 0x4E, 0x50, 0x32, 0x2F, 0x37, 0x77, 0x61, 0x6A, 0x33, 0x56, 0x6A, 0x46, 0x68, 0x54, 0x30, 0x2B, 0x6A, 0x2F, 0x36, 0x65, 0x4B, 0x65, 0x43, 0x32, 0x75, 0x41, 0x6C, 0x6F, 0x47, 0x52, 0x77, 0x59, 0x51, 0x77, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, ++ 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x72, 0x65, 0x6D, ++ 0x69, 0x75, 0x6D, 0x20, 0x45, 0x43, 0x43, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, ++ 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x42, 0x2F, 0x6A, 0x43, 0x43, 0x41, 0x59, 0x57, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x49, ++ 0x64, 0x4A, 0x63, 0x6C, 0x69, 0x73, 0x63, 0x2F, 0x65, 0x6C, 0x51, 0x77, 0x43, 0x67, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x45, 0x41, 0x77, 0x4D, 0x77, 0x52, 0x54, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, ++ 0x42, 0x68, 0x4D, 0x43, 0x56, 0x56, 0x4D, 0x78, 0x46, 0x44, 0x41, 0x53, 0x42, 0x67, 0x4E, 0x56, 0x0A, 0x42, 0x41, 0x6F, 0x4D, 0x43, 0x30, 0x46, 0x6D, 0x5A, 0x6D, 0x6C, 0x79, 0x62, 0x56, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x4D, 0x53, 0x41, ++ 0x77, 0x48, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x42, 0x64, 0x42, 0x5A, 0x6D, 0x5A, 0x70, 0x63, 0x6D, 0x31, 0x55, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x43, 0x42, 0x51, 0x63, 0x6D, 0x56, 0x74, 0x61, 0x58, 0x56, 0x74, 0x49, 0x45, 0x56, ++ 0x44, 0x51, 0x7A, 0x41, 0x65, 0x46, 0x77, 0x30, 0x78, 0x4D, 0x44, 0x41, 0x78, 0x0A, 0x4D, 0x6A, 0x6B, 0x78, 0x4E, 0x44, 0x49, 0x77, 0x4D, 0x6A, 0x52, 0x61, 0x46, 0x77, 0x30, 0x30, 0x4D, 0x44, 0x45, 0x79, 0x4D, 0x7A, 0x45, 0x78, 0x4E, 0x44, ++ 0x49, 0x77, 0x4D, 0x6A, 0x52, 0x61, 0x4D, 0x45, 0x55, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6C, 0x56, 0x54, 0x4D, 0x52, 0x51, 0x77, 0x45, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x44, 0x41, ++ 0x74, 0x42, 0x5A, 0x6D, 0x5A, 0x70, 0x63, 0x6D, 0x31, 0x55, 0x0A, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x44, 0x45, 0x67, 0x4D, 0x42, 0x34, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x58, 0x51, 0x57, 0x5A, 0x6D, 0x61, 0x58, 0x4A, 0x74, 0x56, ++ 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x67, 0x55, 0x48, 0x4A, 0x6C, 0x62, 0x57, 0x6C, 0x31, 0x62, 0x53, 0x42, 0x46, 0x51, 0x30, 0x4D, 0x77, 0x64, 0x6A, 0x41, 0x51, 0x42, 0x67, 0x63, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x49, 0x42, 0x42, ++ 0x67, 0x55, 0x72, 0x67, 0x51, 0x51, 0x41, 0x0A, 0x49, 0x67, 0x4E, 0x69, 0x41, 0x41, 0x51, 0x4E, 0x4D, 0x46, 0x34, 0x62, 0x46, 0x5A, 0x30, 0x44, 0x30, 0x4B, 0x46, 0x35, 0x4E, 0x62, 0x63, 0x36, 0x50, 0x4A, 0x4A, 0x36, 0x79, 0x68, 0x55, 0x63, ++ 0x7A, 0x57, 0x4C, 0x7A, 0x6E, 0x43, 0x5A, 0x63, 0x42, 0x7A, 0x33, 0x6C, 0x56, 0x50, 0x71, 0x6A, 0x31, 0x73, 0x77, 0x53, 0x36, 0x76, 0x51, 0x55, 0x58, 0x2B, 0x69, 0x4F, 0x47, 0x61, 0x73, 0x76, 0x4C, 0x6B, 0x6A, 0x6D, 0x72, 0x42, 0x68, 0x44, ++ 0x65, 0x4B, 0x7A, 0x51, 0x0A, 0x4E, 0x38, 0x4F, 0x39, 0x73, 0x73, 0x30, 0x73, 0x35, 0x6B, 0x66, 0x69, 0x47, 0x75, 0x5A, 0x6A, 0x75, 0x44, 0x30, 0x75, 0x4C, 0x33, 0x6A, 0x45, 0x54, 0x39, 0x76, 0x30, 0x44, 0x36, 0x52, 0x6F, 0x54, 0x46, 0x56, ++ 0x79, 0x61, 0x35, 0x55, 0x64, 0x54, 0x68, 0x68, 0x43, 0x6C, 0x58, 0x6A, 0x4D, 0x4E, 0x7A, 0x79, 0x52, 0x34, 0x70, 0x74, 0x6C, 0x4B, 0x79, 0x6D, 0x6A, 0x51, 0x6A, 0x42, 0x41, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, ++ 0x57, 0x0A, 0x42, 0x42, 0x53, 0x61, 0x72, 0x79, 0x6C, 0x36, 0x77, 0x42, 0x45, 0x31, 0x4E, 0x53, 0x5A, 0x52, 0x4D, 0x41, 0x44, 0x44, 0x61, 0x76, 0x35, 0x41, 0x31, 0x61, 0x37, 0x57, 0x50, 0x44, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, ++ 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6A, 0x41, 0x4B, 0x0A, 0x42, ++ 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x77, 0x4E, 0x6E, 0x41, 0x44, 0x42, 0x6B, 0x41, 0x6A, 0x41, 0x58, 0x43, 0x66, 0x4F, 0x48, 0x69, 0x46, 0x42, 0x61, 0x72, 0x38, 0x6A, 0x41, 0x51, 0x72, 0x39, 0x48, 0x58, ++ 0x2F, 0x56, 0x73, 0x61, 0x6F, 0x62, 0x67, 0x78, 0x43, 0x64, 0x30, 0x35, 0x44, 0x68, 0x54, 0x31, 0x77, 0x56, 0x2F, 0x47, 0x7A, 0x54, 0x6A, 0x78, 0x69, 0x2B, 0x7A, 0x79, 0x67, 0x6B, 0x38, 0x4E, 0x35, 0x33, 0x58, 0x0A, 0x35, 0x37, 0x68, 0x47, ++ 0x38, 0x66, 0x32, 0x68, 0x34, 0x6E, 0x45, 0x43, 0x4D, 0x45, 0x4A, 0x5A, 0x68, 0x30, 0x50, 0x55, 0x55, 0x64, 0x2B, 0x36, 0x30, 0x77, 0x6B, 0x79, 0x57, 0x73, 0x36, 0x49, 0x66, 0x6C, 0x63, 0x39, 0x6E, 0x46, 0x39, 0x43, 0x61, 0x2F, 0x55, 0x48, ++ 0x4C, 0x62, 0x58, 0x77, 0x67, 0x70, 0x50, 0x35, 0x57, 0x57, 0x2B, 0x75, 0x5A, 0x50, 0x70, 0x59, 0x35, 0x59, 0x73, 0x65, 0x34, 0x32, 0x4F, 0x2B, 0x74, 0x59, 0x48, 0x4E, 0x62, 0x77, 0x4B, 0x4D, 0x0A, 0x65, 0x51, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, ++ 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, ++ 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x20, 0x43, 0x41, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, ++ 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x44, 0x75, 0x7A, 0x43, 0x43, 0x41, 0x71, 0x4F, 0x67, 0x41, 0x77, 0x49, ++ 0x42, 0x41, 0x67, 0x49, 0x44, 0x42, 0x45, 0x54, 0x41, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x42, 0x51, 0x55, 0x41, 0x4D, 0x48, 0x34, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, ++ 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6C, 0x42, 0x4D, 0x4D, 0x53, 0x49, 0x77, 0x49, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x0A, 0x45, 0x78, 0x6C, 0x56, 0x62, 0x6D, 0x6C, 0x36, 0x5A, 0x58, 0x52, 0x76, 0x49, 0x46, 0x52, 0x6C, 0x59, 0x32, ++ 0x68, 0x75, 0x62, 0x32, 0x78, 0x76, 0x5A, 0x32, 0x6C, 0x6C, 0x63, 0x79, 0x42, 0x54, 0x4C, 0x6B, 0x45, 0x75, 0x4D, 0x53, 0x63, 0x77, 0x4A, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, 0x45, 0x78, 0x35, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x64, 0x57, ++ 0x30, 0x67, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6C, 0x6D, 0x61, 0x57, 0x4E, 0x68, 0x64, 0x47, 0x6C, 0x76, 0x0A, 0x62, 0x69, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6F, 0x62, 0x33, 0x4A, 0x70, 0x64, 0x48, 0x6B, 0x78, 0x49, 0x6A, 0x41, 0x67, 0x42, ++ 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x47, 0x55, 0x4E, 0x6C, 0x63, 0x6E, 0x52, 0x31, 0x62, 0x53, 0x42, 0x55, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x47, 0x56, 0x6B, 0x49, 0x45, 0x35, 0x6C, 0x64, 0x48, 0x64, 0x76, 0x63, 0x6D, 0x73, 0x67, 0x51, ++ 0x30, 0x45, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x44, 0x67, 0x78, 0x4D, 0x44, 0x49, 0x79, 0x0A, 0x4D, 0x54, 0x49, 0x77, 0x4E, 0x7A, 0x4D, 0x33, 0x57, 0x68, 0x63, 0x4E, 0x4D, 0x6A, 0x6B, 0x78, 0x4D, 0x6A, 0x4D, 0x78, 0x4D, 0x54, 0x49, 0x77, ++ 0x4E, 0x7A, 0x4D, 0x33, 0x57, 0x6A, 0x42, 0x2B, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x51, 0x54, 0x44, 0x45, 0x69, 0x4D, 0x43, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x5A, ++ 0x56, 0x57, 0x35, 0x70, 0x65, 0x6D, 0x56, 0x30, 0x62, 0x79, 0x42, 0x55, 0x0A, 0x5A, 0x57, 0x4E, 0x6F, 0x62, 0x6D, 0x39, 0x73, 0x62, 0x32, 0x64, 0x70, 0x5A, 0x58, 0x4D, 0x67, 0x55, 0x79, 0x35, 0x42, 0x4C, 0x6A, 0x45, 0x6E, 0x4D, 0x43, 0x55, ++ 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4D, 0x65, 0x51, 0x32, 0x56, 0x79, 0x64, 0x48, 0x56, 0x74, 0x49, 0x45, 0x4E, 0x6C, 0x63, 0x6E, 0x52, 0x70, 0x5A, 0x6D, 0x6C, 0x6A, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x67, 0x51, 0x58, 0x56, ++ 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52, 0x35, 0x0A, 0x4D, 0x53, 0x49, 0x77, 0x49, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x6C, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x64, 0x57, 0x30, 0x67, 0x56, 0x48, 0x4A, 0x31, 0x63, 0x33, ++ 0x52, 0x6C, 0x5A, 0x43, 0x42, 0x4F, 0x5A, 0x58, 0x52, 0x33, 0x62, 0x33, 0x4A, 0x72, 0x49, 0x45, 0x4E, 0x42, 0x4D, 0x49, 0x49, 0x42, 0x49, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, ++ 0x45, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x0A, 0x41, 0x51, 0x38, 0x41, 0x4D, 0x49, 0x49, 0x42, 0x43, 0x67, 0x4B, 0x43, 0x41, 0x51, 0x45, 0x41, 0x34, 0x2F, 0x74, 0x39, 0x6F, 0x33, 0x4B, 0x36, 0x77, 0x76, 0x44, 0x4A, 0x46, 0x49, 0x66, 0x31, 0x61, ++ 0x77, 0x46, 0x4F, 0x34, 0x57, 0x35, 0x41, 0x42, 0x37, 0x70, 0x74, 0x4A, 0x31, 0x31, 0x2F, 0x39, 0x31, 0x73, 0x74, 0x73, 0x31, 0x72, 0x48, 0x55, 0x56, 0x2B, 0x72, 0x70, 0x44, 0x4B, 0x6D, 0x59, 0x59, 0x65, 0x32, 0x62, 0x67, 0x2B, 0x47, 0x30, ++ 0x6A, 0x41, 0x43, 0x0A, 0x6C, 0x2F, 0x6A, 0x58, 0x61, 0x56, 0x65, 0x68, 0x47, 0x44, 0x6C, 0x64, 0x61, 0x6D, 0x52, 0x35, 0x78, 0x67, 0x46, 0x5A, 0x72, 0x44, 0x77, 0x78, 0x53, 0x6A, 0x68, 0x38, 0x30, 0x67, 0x54, 0x53, 0x53, 0x79, 0x6A, 0x6F, ++ 0x49, 0x46, 0x38, 0x37, 0x42, 0x36, 0x4C, 0x4D, 0x54, 0x58, 0x50, 0x62, 0x38, 0x36, 0x35, 0x50, 0x78, 0x31, 0x62, 0x56, 0x57, 0x71, 0x65, 0x57, 0x69, 0x66, 0x72, 0x7A, 0x71, 0x32, 0x6A, 0x55, 0x49, 0x34, 0x5A, 0x5A, 0x4A, 0x38, 0x38, 0x4A, ++ 0x0A, 0x4A, 0x37, 0x79, 0x73, 0x62, 0x6E, 0x4B, 0x44, 0x48, 0x44, 0x42, 0x79, 0x33, 0x2B, 0x43, 0x69, 0x36, 0x64, 0x4C, 0x68, 0x64, 0x48, 0x55, 0x5A, 0x76, 0x53, 0x71, 0x65, 0x65, 0x78, 0x56, 0x55, 0x42, 0x42, 0x76, 0x58, 0x51, 0x7A, 0x6D, ++ 0x74, 0x56, 0x53, 0x6A, 0x46, 0x34, 0x68, 0x71, 0x37, 0x39, 0x4D, 0x44, 0x6B, 0x72, 0x6A, 0x68, 0x4A, 0x4D, 0x38, 0x78, 0x32, 0x68, 0x5A, 0x38, 0x35, 0x52, 0x64, 0x4B, 0x6B, 0x6E, 0x76, 0x49, 0x53, 0x6A, 0x46, 0x48, 0x34, 0x0A, 0x66, 0x4F, ++ 0x51, 0x74, 0x66, 0x2F, 0x57, 0x73, 0x58, 0x2B, 0x73, 0x57, 0x6E, 0x37, 0x45, 0x74, 0x30, 0x62, 0x72, 0x4D, 0x6B, 0x55, 0x4A, 0x33, 0x54, 0x43, 0x58, 0x4A, 0x6B, 0x44, 0x68, 0x76, 0x32, 0x2F, 0x44, 0x4D, 0x2B, 0x34, 0x34, 0x65, 0x6C, 0x31, ++ 0x6B, 0x2B, 0x31, 0x57, 0x42, 0x4F, 0x35, 0x67, 0x55, 0x6F, 0x37, 0x55, 0x6C, 0x35, 0x45, 0x30, 0x75, 0x36, 0x53, 0x4E, 0x73, 0x76, 0x2B, 0x58, 0x4C, 0x54, 0x4F, 0x63, 0x72, 0x2B, 0x48, 0x39, 0x67, 0x30, 0x0A, 0x63, 0x76, 0x57, 0x30, 0x51, ++ 0x4D, 0x38, 0x78, 0x41, 0x63, 0x50, 0x73, 0x33, 0x68, 0x45, 0x74, 0x46, 0x31, 0x30, 0x66, 0x75, 0x46, 0x44, 0x52, 0x58, 0x68, 0x6D, 0x6E, 0x61, 0x64, 0x34, 0x48, 0x4D, 0x79, 0x6A, 0x4B, 0x55, 0x4A, 0x58, 0x35, 0x70, 0x31, 0x54, 0x4C, 0x56, ++ 0x49, 0x5A, 0x51, 0x52, 0x61, 0x6E, 0x35, 0x53, 0x51, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6F, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x0A, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, ++ 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x51, 0x49, 0x64, 0x73, 0x33, 0x4C, 0x42, 0x2F, 0x38, 0x6B, 0x39, 0x73, 0x58, 0x4E, 0x37, 0x62, 0x75, 0x51, 0x76, 0x4F, 0x4B, 0x45, ++ 0x4E, 0x30, 0x5A, 0x31, 0x39, 0x7A, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x51, 0x59, 0x77, 0x0A, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, ++ 0x4E, 0x41, 0x51, 0x45, 0x46, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x42, 0x41, 0x4B, 0x61, 0x6F, 0x72, 0x53, 0x4C, 0x4F, 0x41, 0x54, 0x32, 0x6D, 0x6F, 0x2F, 0x39, 0x69, 0x30, 0x45, 0x69, 0x64, 0x69, 0x31, 0x35, 0x79, 0x73, 0x48, 0x68, ++ 0x45, 0x34, 0x39, 0x77, 0x63, 0x72, 0x77, 0x6E, 0x39, 0x49, 0x30, 0x6A, 0x36, 0x76, 0x53, 0x72, 0x45, 0x75, 0x56, 0x55, 0x45, 0x74, 0x52, 0x43, 0x6A, 0x0A, 0x6A, 0x53, 0x66, 0x65, 0x43, 0x34, 0x4A, 0x6A, 0x30, 0x4F, 0x37, 0x65, 0x44, 0x44, ++ 0x64, 0x35, 0x51, 0x56, 0x73, 0x69, 0x73, 0x72, 0x43, 0x61, 0x51, 0x56, 0x79, 0x6D, 0x63, 0x4F, 0x44, 0x55, 0x30, 0x48, 0x66, 0x4C, 0x49, 0x39, 0x4D, 0x41, 0x34, 0x47, 0x78, 0x57, 0x4C, 0x2B, 0x46, 0x70, 0x44, 0x51, 0x33, 0x5A, 0x71, 0x72, ++ 0x38, 0x68, 0x67, 0x56, 0x44, 0x5A, 0x42, 0x71, 0x57, 0x6F, 0x2F, 0x35, 0x55, 0x33, 0x30, 0x4B, 0x72, 0x2B, 0x34, 0x72, 0x50, 0x31, 0x0A, 0x6D, 0x53, 0x31, 0x46, 0x68, 0x49, 0x72, 0x6C, 0x51, 0x67, 0x6E, 0x58, 0x64, 0x41, 0x49, 0x76, 0x39, ++ 0x34, 0x6E, 0x59, 0x6D, 0x65, 0x6D, 0x38, 0x4A, 0x39, 0x52, 0x48, 0x6A, 0x62, 0x6F, 0x4E, 0x52, 0x68, 0x78, 0x33, 0x7A, 0x78, 0x53, 0x6B, 0x48, 0x4C, 0x6D, 0x6B, 0x4D, 0x63, 0x53, 0x63, 0x4B, 0x48, 0x51, 0x44, 0x4E, 0x50, 0x38, 0x7A, 0x47, ++ 0x53, 0x61, 0x6C, 0x36, 0x51, 0x31, 0x30, 0x74, 0x7A, 0x36, 0x58, 0x78, 0x6E, 0x62, 0x6F, 0x4A, 0x35, 0x61, 0x6A, 0x0A, 0x5A, 0x74, 0x33, 0x68, 0x72, 0x76, 0x4A, 0x42, 0x57, 0x38, 0x71, 0x59, 0x56, 0x6F, 0x4E, 0x7A, 0x63, 0x4F, 0x53, 0x47, ++ 0x47, 0x74, 0x49, 0x78, 0x51, 0x62, 0x6F, 0x76, 0x76, 0x69, 0x30, 0x54, 0x57, 0x6E, 0x5A, 0x76, 0x54, 0x75, 0x68, 0x4F, 0x67, 0x51, 0x34, 0x2F, 0x57, 0x77, 0x4D, 0x69, 0x6F, 0x42, 0x4B, 0x2B, 0x5A, 0x6C, 0x67, 0x52, 0x53, 0x73, 0x73, 0x44, ++ 0x78, 0x4C, 0x51, 0x71, 0x4B, 0x69, 0x32, 0x57, 0x46, 0x2B, 0x41, 0x35, 0x56, 0x4C, 0x78, 0x49, 0x0A, 0x30, 0x33, 0x59, 0x6E, 0x6E, 0x5A, 0x6F, 0x74, 0x42, 0x71, 0x62, 0x4A, 0x37, 0x44, 0x6E, 0x53, 0x71, 0x39, 0x75, 0x66, 0x6D, 0x67, 0x73, ++ 0x6E, 0x41, 0x6A, 0x55, 0x70, 0x73, 0x55, 0x43, 0x56, 0x35, 0x2F, 0x6E, 0x6F, 0x6E, 0x46, 0x57, 0x49, 0x47, 0x55, 0x62, 0x57, 0x74, 0x7A, 0x54, 0x31, 0x66, 0x73, 0x34, 0x35, 0x6D, 0x74, 0x6B, 0x34, 0x38, 0x56, 0x48, 0x33, 0x54, 0x79, 0x77, ++ 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x54, 0x57, 0x43, 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, ++ 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, ++ 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x44, 0x65, 0x7A, 0x43, 0x43, 0x41, 0x6D, 0x4F, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x42, 0x41, 0x54, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, ++ 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x44, 0x42, 0x66, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x55, 0x56, 0x7A, 0x45, 0x53, 0x4D, 0x42, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, ++ 0x4A, 0x0A, 0x56, 0x45, 0x46, 0x4A, 0x56, 0x30, 0x46, 0x4F, 0x4C, 0x55, 0x4E, 0x42, 0x4D, 0x52, 0x41, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, 0x44, 0x41, 0x64, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x4D, 0x53, ++ 0x6F, 0x77, 0x4B, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x43, 0x46, 0x55, 0x56, 0x30, 0x4E, 0x42, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6C, 0x6D, 0x61, 0x57, 0x4E, 0x68, 0x0A, 0x64, ++ 0x47, 0x6C, 0x76, 0x62, 0x69, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6F, 0x62, 0x33, 0x4A, 0x70, 0x64, 0x48, 0x6B, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x44, 0x67, 0x77, 0x4F, 0x44, 0x49, 0x34, 0x4D, 0x44, 0x63, 0x79, 0x4E, 0x44, 0x4D, 0x7A, 0x57, ++ 0x68, 0x63, 0x4E, 0x4D, 0x7A, 0x41, 0x78, 0x4D, 0x6A, 0x4D, 0x78, 0x4D, 0x54, 0x55, 0x31, 0x4F, 0x54, 0x55, 0x35, 0x57, 0x6A, 0x42, 0x66, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0A, 0x45, 0x77, 0x4A, 0x55, ++ 0x56, 0x7A, 0x45, 0x53, 0x4D, 0x42, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x4A, 0x56, 0x45, 0x46, 0x4A, 0x56, 0x30, 0x46, 0x4F, 0x4C, 0x55, 0x4E, 0x42, 0x4D, 0x52, 0x41, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, ++ 0x44, 0x41, 0x64, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x4D, 0x53, 0x6F, 0x77, 0x4B, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x43, 0x46, 0x55, 0x56, 0x30, 0x4E, 0x42, 0x0A, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, ++ 0x67, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6C, 0x6D, 0x61, 0x57, 0x4E, 0x68, 0x64, 0x47, 0x6C, 0x76, 0x62, 0x69, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6F, 0x62, 0x33, 0x4A, 0x70, 0x64, 0x48, 0x6B, 0x77, 0x67, 0x67, 0x45, 0x69, 0x4D, 0x41, 0x30, ++ 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x45, 0x4B, 0x0A, 0x41, 0x6F, 0x49, 0x42, 0x41, 0x51, 0x43, 0x77, 0x66, 0x6E, ++ 0x4B, 0x34, 0x70, 0x41, 0x4F, 0x55, 0x35, 0x71, 0x66, 0x65, 0x43, 0x54, 0x69, 0x52, 0x53, 0x68, 0x46, 0x41, 0x68, 0x36, 0x64, 0x38, 0x57, 0x57, 0x51, 0x55, 0x65, 0x37, 0x55, 0x52, 0x45, 0x4E, 0x33, 0x2B, 0x76, 0x39, 0x58, 0x41, 0x75, 0x31, ++ 0x62, 0x69, 0x68, 0x53, 0x58, 0x30, 0x4E, 0x58, 0x49, 0x50, 0x2B, 0x46, 0x50, 0x51, 0x51, 0x65, 0x46, 0x45, 0x41, 0x63, 0x4B, 0x30, 0x48, 0x4D, 0x4D, 0x78, 0x0A, 0x51, 0x68, 0x5A, 0x48, 0x68, 0x54, 0x4D, 0x69, 0x64, 0x72, 0x49, 0x4B, 0x62, ++ 0x77, 0x2F, 0x6C, 0x4A, 0x56, 0x42, 0x50, 0x68, 0x59, 0x61, 0x2B, 0x76, 0x35, 0x67, 0x75, 0x45, 0x47, 0x63, 0x65, 0x76, 0x68, 0x45, 0x46, 0x68, 0x67, 0x57, 0x51, 0x78, 0x46, 0x6E, 0x51, 0x66, 0x48, 0x67, 0x51, 0x73, 0x49, 0x42, 0x63, 0x74, ++ 0x2B, 0x48, 0x48, 0x4B, 0x33, 0x58, 0x4C, 0x66, 0x4A, 0x2B, 0x75, 0x74, 0x64, 0x47, 0x64, 0x49, 0x7A, 0x64, 0x6A, 0x70, 0x39, 0x78, 0x43, 0x0A, 0x6F, 0x69, 0x32, 0x53, 0x42, 0x42, 0x74, 0x51, 0x77, 0x58, 0x75, 0x34, 0x50, 0x68, 0x76, 0x4A, ++ 0x56, 0x67, 0x53, 0x4C, 0x4C, 0x31, 0x4B, 0x62, 0x72, 0x61, 0x6C, 0x57, 0x36, 0x63, 0x48, 0x2F, 0x72, 0x61, 0x6C, 0x59, 0x68, 0x7A, 0x43, 0x32, 0x67, 0x66, 0x65, 0x58, 0x52, 0x66, 0x77, 0x5A, 0x56, 0x7A, 0x73, 0x72, 0x62, 0x2B, 0x52, 0x48, ++ 0x39, 0x4A, 0x6C, 0x46, 0x2F, 0x68, 0x33, 0x78, 0x2B, 0x4A, 0x65, 0x6A, 0x69, 0x42, 0x30, 0x33, 0x48, 0x46, 0x79, 0x50, 0x0A, 0x34, 0x48, 0x59, 0x6C, 0x6D, 0x6C, 0x44, 0x34, 0x6F, 0x46, 0x54, 0x2F, 0x52, 0x4A, 0x42, 0x32, 0x49, 0x39, 0x49, ++ 0x79, 0x78, 0x73, 0x4F, 0x72, 0x42, 0x72, 0x2F, 0x38, 0x2B, 0x37, 0x2F, 0x7A, 0x72, 0x58, 0x32, 0x53, 0x59, 0x67, 0x4A, 0x62, 0x4B, 0x64, 0x4D, 0x31, 0x6F, 0x35, 0x4F, 0x61, 0x51, 0x32, 0x52, 0x67, 0x58, 0x62, 0x4C, 0x36, 0x4D, 0x76, 0x38, ++ 0x37, 0x42, 0x4B, 0x39, 0x4E, 0x51, 0x47, 0x72, 0x35, 0x78, 0x2B, 0x50, 0x76, 0x49, 0x2F, 0x31, 0x72, 0x0A, 0x79, 0x2B, 0x55, 0x50, 0x69, 0x7A, 0x67, 0x4E, 0x37, 0x67, 0x72, 0x38, 0x2F, 0x67, 0x2B, 0x59, 0x6E, 0x7A, 0x41, 0x78, 0x33, 0x57, ++ 0x78, 0x53, 0x5A, 0x66, 0x6D, 0x4C, 0x67, 0x62, 0x34, 0x69, 0x34, 0x52, 0x78, 0x59, 0x41, 0x37, 0x71, 0x52, 0x47, 0x34, 0x6B, 0x48, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, 0x51, 0x6A, 0x42, 0x41, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, ++ 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x0A, 0x42, 0x6A, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2F, 0x4D, ++ 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x52, 0x71, 0x4F, 0x46, 0x73, 0x6D, 0x6A, 0x64, 0x36, 0x4C, 0x57, 0x76, 0x4A, 0x50, 0x65, 0x6C, 0x53, 0x44, 0x47, 0x52, 0x6A, 0x6A, 0x43, 0x44, 0x57, 0x6D, 0x75, ++ 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x0A, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x51, 0x45, 0x41, 0x50, 0x4E, 0x56, 0x33, 0x50, 0x64, 0x72, 0x66, 0x69, 0x62, 0x71, 0x48, ++ 0x44, 0x41, 0x68, 0x55, 0x61, 0x69, 0x42, 0x51, 0x6B, 0x72, 0x36, 0x77, 0x51, 0x54, 0x32, 0x35, 0x4A, 0x6D, 0x53, 0x44, 0x43, 0x69, 0x2F, 0x6F, 0x51, 0x4D, 0x43, 0x58, 0x4B, 0x43, 0x65, 0x43, 0x4D, 0x45, 0x72, 0x4A, 0x6B, 0x2F, 0x39, 0x71, ++ 0x35, 0x36, 0x59, 0x41, 0x66, 0x34, 0x6C, 0x43, 0x0A, 0x6D, 0x74, 0x59, 0x52, 0x35, 0x56, 0x50, 0x4F, 0x4C, 0x38, 0x7A, 0x79, 0x32, 0x67, 0x58, 0x45, 0x2F, 0x75, 0x4A, 0x51, 0x78, 0x44, 0x71, 0x47, 0x66, 0x63, 0x7A, 0x61, 0x66, 0x68, 0x41, ++ 0x4A, 0x4F, 0x35, 0x49, 0x31, 0x4B, 0x6C, 0x4F, 0x79, 0x2F, 0x75, 0x73, 0x72, 0x42, 0x64, 0x6C, 0x73, 0x58, 0x65, 0x62, 0x51, 0x37, 0x39, 0x4E, 0x71, 0x5A, 0x70, 0x34, 0x56, 0x4B, 0x49, 0x56, 0x36, 0x36, 0x49, 0x49, 0x41, 0x72, 0x42, 0x36, ++ 0x6E, 0x43, 0x57, 0x6C, 0x57, 0x0A, 0x51, 0x74, 0x4E, 0x6F, 0x55, 0x52, 0x69, 0x2B, 0x56, 0x4A, 0x71, 0x2F, 0x52, 0x45, 0x47, 0x36, 0x53, 0x62, 0x34, 0x67, 0x75, 0x6D, 0x6C, 0x63, 0x37, 0x72, 0x68, 0x33, 0x7A, 0x63, 0x35, 0x73, 0x48, 0x36, ++ 0x32, 0x44, 0x6C, 0x68, 0x68, 0x39, 0x44, 0x72, 0x55, 0x55, 0x4F, 0x59, 0x54, 0x78, 0x4B, 0x4F, 0x6B, 0x74, 0x6F, 0x35, 0x35, 0x37, 0x48, 0x6E, 0x70, 0x79, 0x57, 0x6F, 0x4F, 0x7A, 0x65, 0x57, 0x2F, 0x76, 0x74, 0x50, 0x7A, 0x51, 0x43, 0x71, ++ 0x56, 0x59, 0x0A, 0x54, 0x30, 0x62, 0x66, 0x2B, 0x32, 0x31, 0x35, 0x57, 0x66, 0x4B, 0x45, 0x49, 0x6C, 0x4B, 0x75, 0x44, 0x38, 0x7A, 0x37, 0x66, 0x44, 0x76, 0x6E, 0x61, 0x73, 0x70, 0x48, 0x59, 0x63, 0x4E, 0x36, 0x2B, 0x4E, 0x4F, 0x53, 0x42, ++ 0x42, 0x2B, 0x34, 0x49, 0x49, 0x54, 0x68, 0x4E, 0x6C, 0x51, 0x57, 0x78, 0x30, 0x44, 0x65, 0x4F, 0x34, 0x70, 0x7A, 0x33, 0x4E, 0x2F, 0x47, 0x43, 0x55, 0x7A, 0x66, 0x37, 0x4E, 0x72, 0x2F, 0x31, 0x46, 0x4E, 0x43, 0x6F, 0x63, 0x6E, 0x79, 0x0A, ++ 0x59, 0x68, 0x30, 0x69, 0x67, 0x7A, 0x79, 0x58, 0x78, 0x66, 0x6B, 0x5A, 0x59, 0x69, 0x65, 0x73, 0x5A, 0x53, 0x4C, 0x58, 0x30, 0x7A, 0x7A, 0x47, 0x35, 0x59, 0x36, 0x79, 0x55, 0x38, 0x78, 0x4A, 0x7A, 0x72, 0x77, 0x77, 0x2F, 0x6E, 0x73, 0x4F, ++ 0x4D, 0x35, 0x44, 0x37, 0x37, 0x64, 0x49, 0x55, 0x6B, 0x52, 0x38, 0x48, 0x72, 0x77, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, ++ 0x2D, 0x2D, 0x0A, 0x0A, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x43, 0x6F, 0x6D, 0x6D, 0x75, 0x6E, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, 0x32, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, ++ 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x44, 0x64, 0x7A, 0x43, 0x43, 0x41, 0x6C, 0x2B, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x42, 0x41, 0x44, 0x41, 0x4E, 0x42, 0x67, ++ 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x42, 0x64, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x4B, 0x55, 0x44, 0x45, 0x6C, 0x4D, 0x43, ++ 0x4D, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x63, 0x0A, 0x55, 0x30, 0x56, 0x44, 0x54, 0x30, 0x30, 0x67, 0x56, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x67, 0x55, 0x33, 0x6C, 0x7A, 0x64, 0x47, 0x56, 0x74, 0x63, 0x79, 0x42, 0x44, 0x54, ++ 0x79, 0x34, 0x73, 0x54, 0x46, 0x52, 0x45, 0x4C, 0x6A, 0x45, 0x6E, 0x4D, 0x43, 0x55, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4D, 0x65, 0x55, 0x32, 0x56, 0x6A, 0x64, 0x58, 0x4A, 0x70, 0x64, 0x48, 0x6B, 0x67, 0x51, 0x32, 0x39, 0x74, 0x62, ++ 0x58, 0x56, 0x75, 0x61, 0x57, 0x4E, 0x68, 0x0A, 0x64, 0x47, 0x6C, 0x76, 0x62, 0x69, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x51, 0x30, 0x45, 0x79, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x41, 0x35, 0x4D, 0x44, 0x55, 0x79, 0x4F, 0x54, 0x41, 0x31, ++ 0x4D, 0x44, 0x41, 0x7A, 0x4F, 0x56, 0x6F, 0x58, 0x44, 0x54, 0x49, 0x35, 0x4D, 0x44, 0x55, 0x79, 0x4F, 0x54, 0x41, 0x31, 0x4D, 0x44, 0x41, 0x7A, 0x4F, 0x56, 0x6F, 0x77, 0x58, 0x54, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, ++ 0x42, 0x68, 0x4D, 0x43, 0x0A, 0x53, 0x6C, 0x41, 0x78, 0x4A, 0x54, 0x41, 0x6A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x48, 0x46, 0x4E, 0x46, 0x51, 0x30, 0x39, 0x4E, 0x49, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x49, 0x46, 0x4E, ++ 0x35, 0x63, 0x33, 0x52, 0x6C, 0x62, 0x58, 0x4D, 0x67, 0x51, 0x30, 0x38, 0x75, 0x4C, 0x45, 0x78, 0x55, 0x52, 0x43, 0x34, 0x78, 0x4A, 0x7A, 0x41, 0x6C, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x73, 0x54, 0x48, 0x6C, 0x4E, 0x6C, 0x59, 0x33, 0x56, ++ 0x79, 0x0A, 0x61, 0x58, 0x52, 0x35, 0x49, 0x45, 0x4E, 0x76, 0x62, 0x57, 0x31, 0x31, 0x62, 0x6D, 0x6C, 0x6A, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x45, 0x4E, 0x42, 0x4D, 0x6A, 0x43, 0x43, 0x41, 0x53, ++ 0x49, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x51, 0x6F, 0x43, 0x67, 0x67, 0x45, 0x42, 0x0A, 0x41, ++ 0x4E, 0x41, 0x56, 0x4F, 0x56, 0x4B, 0x78, 0x55, 0x72, 0x4F, 0x36, 0x78, 0x56, 0x6D, 0x43, 0x78, 0x46, 0x31, 0x53, 0x72, 0x6A, 0x70, 0x44, 0x5A, 0x59, 0x42, 0x4C, 0x78, 0x2F, 0x4B, 0x57, 0x76, 0x4E, 0x73, 0x32, 0x6C, 0x39, 0x61, 0x6D, 0x5A, ++ 0x49, 0x79, 0x6F, 0x58, 0x76, 0x44, 0x6A, 0x43, 0x68, 0x7A, 0x33, 0x33, 0x35, 0x63, 0x39, 0x53, 0x36, 0x37, 0x32, 0x58, 0x65, 0x77, 0x68, 0x74, 0x55, 0x47, 0x72, 0x7A, 0x62, 0x6C, 0x2B, 0x64, 0x70, 0x2B, 0x2B, 0x0A, 0x2B, 0x54, 0x34, 0x32, ++ 0x4E, 0x4B, 0x41, 0x37, 0x77, 0x66, 0x59, 0x78, 0x45, 0x55, 0x56, 0x30, 0x6B, 0x7A, 0x31, 0x58, 0x67, 0x4D, 0x58, 0x35, 0x69, 0x5A, 0x6E, 0x4B, 0x35, 0x61, 0x74, 0x71, 0x31, 0x4C, 0x58, 0x61, 0x51, 0x5A, 0x41, 0x51, 0x77, 0x64, 0x62, 0x57, ++ 0x51, 0x6F, 0x6E, 0x43, 0x76, 0x2F, 0x51, 0x34, 0x45, 0x70, 0x56, 0x4D, 0x56, 0x41, 0x58, 0x33, 0x4E, 0x75, 0x52, 0x46, 0x67, 0x33, 0x73, 0x55, 0x5A, 0x64, 0x62, 0x63, 0x44, 0x45, 0x33, 0x52, 0x0A, 0x33, 0x6E, 0x34, 0x4D, 0x71, 0x7A, 0x76, ++ 0x45, 0x46, 0x62, 0x34, 0x36, 0x56, 0x71, 0x5A, 0x61, 0x62, 0x33, 0x5A, 0x70, 0x55, 0x71, 0x6C, 0x36, 0x75, 0x63, 0x6A, 0x72, 0x61, 0x70, 0x70, 0x64, 0x55, 0x74, 0x41, 0x74, 0x43, 0x6D, 0x73, 0x31, 0x46, 0x67, 0x6B, 0x51, 0x68, 0x4E, 0x42, ++ 0x71, 0x79, 0x6A, 0x6F, 0x47, 0x41, 0x44, 0x64, 0x48, 0x35, 0x48, 0x35, 0x58, 0x54, 0x7A, 0x2B, 0x4C, 0x36, 0x32, 0x65, 0x34, 0x69, 0x4B, 0x72, 0x46, 0x76, 0x6C, 0x4E, 0x56, 0x0A, 0x73, 0x70, 0x48, 0x45, 0x66, 0x62, 0x6D, 0x77, 0x68, 0x52, ++ 0x6B, 0x47, 0x65, 0x43, 0x37, 0x62, 0x59, 0x52, 0x72, 0x36, 0x68, 0x66, 0x56, 0x4B, 0x6B, 0x61, 0x48, 0x6E, 0x46, 0x74, 0x57, 0x4F, 0x6F, 0x6A, 0x6E, 0x66, 0x6C, 0x4C, 0x68, 0x77, 0x48, 0x79, 0x67, 0x2F, 0x69, 0x2F, 0x78, 0x41, 0x58, 0x6D, ++ 0x4F, 0x44, 0x50, 0x49, 0x4D, 0x71, 0x47, 0x70, 0x6C, 0x72, 0x7A, 0x39, 0x35, 0x5A, 0x61, 0x6A, 0x76, 0x38, 0x62, 0x78, 0x62, 0x58, 0x48, 0x2F, 0x31, 0x4B, 0x0A, 0x45, 0x4F, 0x74, 0x4F, 0x67, 0x68, 0x59, 0x36, 0x72, 0x43, 0x63, 0x4D, 0x55, ++ 0x2F, 0x47, 0x74, 0x31, 0x53, 0x53, 0x77, 0x61, 0x77, 0x4E, 0x51, 0x77, 0x53, 0x30, 0x38, 0x46, 0x74, 0x31, 0x45, 0x4E, 0x43, 0x63, 0x61, 0x64, 0x66, 0x73, 0x43, 0x41, 0x77, 0x45, 0x41, 0x41, 0x61, 0x4E, 0x43, 0x4D, 0x45, 0x41, 0x77, 0x48, ++ 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x46, 0x41, 0x71, 0x46, 0x71, 0x58, 0x64, 0x6C, 0x42, 0x5A, 0x68, 0x38, 0x0A, 0x51, 0x49, 0x48, 0x34, 0x44, 0x35, 0x63, 0x73, 0x4F, 0x50, 0x45, 0x4B, 0x37, 0x44, 0x7A, 0x50, ++ 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6A, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, ++ 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x0A, 0x43, 0x77, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x41, 0x51, 0x42, 0x4D, 0x4F, 0x71, 0x4E, 0x45, 0x72, 0x4C, 0x6C, ++ 0x46, 0x73, 0x63, 0x65, 0x54, 0x66, 0x73, 0x67, 0x4C, 0x43, 0x6B, 0x4C, 0x66, 0x5A, 0x4F, 0x6F, 0x63, 0x37, 0x6C, 0x6C, 0x73, 0x43, 0x4C, 0x71, 0x4A, 0x58, 0x32, 0x72, 0x4B, 0x53, 0x70, 0x57, 0x65, 0x65, 0x6F, 0x38, 0x48, 0x78, 0x64, 0x70, ++ 0x46, 0x63, 0x6F, 0x4A, 0x78, 0x44, 0x6A, 0x72, 0x53, 0x7A, 0x47, 0x2B, 0x6E, 0x74, 0x4B, 0x45, 0x6A, 0x0A, 0x75, 0x2F, 0x59, 0x6B, 0x6E, 0x38, 0x73, 0x58, 0x2F, 0x6F, 0x79, 0x6D, 0x7A, 0x73, 0x4C, 0x53, 0x32, 0x38, 0x79, 0x4E, 0x2F, 0x48, ++ 0x48, 0x38, 0x41, 0x79, 0x6E, 0x42, 0x62, 0x46, 0x30, 0x7A, 0x58, 0x32, 0x53, 0x32, 0x5A, 0x54, 0x75, 0x4A, 0x62, 0x78, 0x68, 0x32, 0x65, 0x50, 0x58, 0x63, 0x6F, 0x6B, 0x67, 0x66, 0x47, 0x54, 0x2B, 0x4F, 0x6B, 0x2B, 0x76, 0x78, 0x2B, 0x68, ++ 0x66, 0x75, 0x7A, 0x55, 0x37, 0x6A, 0x42, 0x42, 0x4A, 0x56, 0x31, 0x75, 0x58, 0x6B, 0x0A, 0x33, 0x66, 0x73, 0x2B, 0x42, 0x58, 0x7A, 0x69, 0x48, 0x56, 0x37, 0x47, 0x70, 0x37, 0x79, 0x58, 0x54, 0x32, 0x67, 0x36, 0x39, 0x65, 0x6B, 0x75, 0x43, ++ 0x6B, 0x4F, 0x32, 0x72, 0x31, 0x64, 0x63, 0x59, 0x6D, 0x68, 0x38, 0x74, 0x2F, 0x32, 0x6A, 0x69, 0x6F, 0x53, 0x67, 0x72, 0x47, 0x4B, 0x2B, 0x4B, 0x77, 0x6D, 0x48, 0x4E, 0x50, 0x42, 0x71, 0x41, 0x62, 0x75, 0x62, 0x4B, 0x56, 0x59, 0x38, 0x2F, ++ 0x67, 0x41, 0x33, 0x7A, 0x79, 0x4E, 0x73, 0x38, 0x55, 0x36, 0x71, 0x0A, 0x74, 0x6E, 0x52, 0x47, 0x45, 0x6D, 0x79, 0x52, 0x37, 0x6A, 0x54, 0x56, 0x37, 0x4A, 0x71, 0x52, 0x35, 0x30, 0x53, 0x2B, 0x6B, 0x44, 0x46, 0x79, 0x31, 0x55, 0x6B, 0x43, ++ 0x39, 0x67, 0x4C, 0x6C, 0x39, 0x42, 0x2F, 0x72, 0x66, 0x4E, 0x6D, 0x57, 0x56, 0x61, 0x6E, 0x2F, 0x37, 0x49, 0x72, 0x35, 0x6D, 0x55, 0x66, 0x2F, 0x4E, 0x56, 0x6F, 0x43, 0x71, 0x67, 0x54, 0x4C, 0x69, 0x6C, 0x75, 0x48, 0x63, 0x53, 0x6D, 0x52, ++ 0x76, 0x61, 0x53, 0x30, 0x65, 0x67, 0x32, 0x39, 0x0A, 0x6D, 0x76, 0x56, 0x58, 0x49, 0x77, 0x41, 0x48, 0x49, 0x52, 0x63, 0x2F, 0x53, 0x6A, 0x6E, 0x52, 0x42, 0x55, 0x6B, 0x4C, 0x70, 0x37, 0x59, 0x33, 0x67, 0x61, 0x56, 0x64, 0x6A, 0x4B, 0x6F, ++ 0x7A, 0x58, 0x6F, 0x45, 0x6F, 0x66, 0x4B, 0x64, 0x39, 0x4A, 0x2B, 0x73, 0x41, 0x72, 0x6F, 0x30, 0x33, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, ++ 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x41, 0x63, 0x74, 0x61, 0x6C, 0x69, 0x73, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, ++ 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x75, 0x7A, 0x43, 0x43, 0x41, 0x36, 0x4F, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x49, 0x56, 0x77, 0x6F, 0x52, 0x6C, ++ 0x30, 0x4C, 0x45, 0x34, 0x38, 0x77, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x77, 0x61, 0x7A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, ++ 0x68, 0x4D, 0x43, 0x53, 0x56, 0x51, 0x78, 0x44, 0x6A, 0x41, 0x4D, 0x0A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x63, 0x4D, 0x42, 0x55, 0x31, 0x70, 0x62, 0x47, 0x46, 0x75, 0x4D, 0x53, 0x4D, 0x77, 0x49, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, ++ 0x44, 0x42, 0x70, 0x42, 0x59, 0x33, 0x52, 0x68, 0x62, 0x47, 0x6C, 0x7A, 0x49, 0x46, 0x4D, 0x75, 0x63, 0x43, 0x35, 0x42, 0x4C, 0x69, 0x38, 0x77, 0x4D, 0x7A, 0x4D, 0x31, 0x4F, 0x44, 0x55, 0x79, 0x4D, 0x44, 0x6B, 0x32, 0x4E, 0x7A, 0x45, 0x6E, ++ 0x4D, 0x43, 0x55, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0A, 0x41, 0x77, 0x77, 0x65, 0x51, 0x57, 0x4E, 0x30, 0x59, 0x57, 0x78, 0x70, 0x63, 0x79, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6F, 0x5A, 0x57, 0x35, 0x30, 0x61, 0x57, 0x4E, 0x68, 0x64, 0x47, 0x6C, ++ 0x76, 0x62, 0x69, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x45, 0x78, 0x4D, 0x44, 0x6B, 0x79, 0x4D, 0x6A, 0x45, 0x78, 0x4D, 0x6A, 0x49, 0x77, 0x4D, 0x6C, 0x6F, 0x58, 0x44, 0x54, 0x4D, ++ 0x77, 0x4D, 0x44, 0x6B, 0x79, 0x0A, 0x4D, 0x6A, 0x45, 0x78, 0x4D, 0x6A, 0x49, 0x77, 0x4D, 0x6C, 0x6F, 0x77, 0x61, 0x7A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x53, 0x56, 0x51, 0x78, 0x44, 0x6A, ++ 0x41, 0x4D, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x63, 0x4D, 0x42, 0x55, 0x31, 0x70, 0x62, 0x47, 0x46, 0x75, 0x4D, 0x53, 0x4D, 0x77, 0x49, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x44, 0x42, 0x70, 0x42, 0x59, 0x33, 0x52, 0x68, 0x62, 0x47, ++ 0x6C, 0x7A, 0x0A, 0x49, 0x46, 0x4D, 0x75, 0x63, 0x43, 0x35, 0x42, 0x4C, 0x69, 0x38, 0x77, 0x4D, 0x7A, 0x4D, 0x31, 0x4F, 0x44, 0x55, 0x79, 0x4D, 0x44, 0x6B, 0x32, 0x4E, 0x7A, 0x45, 0x6E, 0x4D, 0x43, 0x55, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, ++ 0x77, 0x77, 0x65, 0x51, 0x57, 0x4E, 0x30, 0x59, 0x57, 0x78, 0x70, 0x63, 0x79, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6F, 0x5A, 0x57, 0x35, 0x30, 0x61, 0x57, 0x4E, 0x68, 0x64, 0x47, 0x6C, 0x76, 0x62, 0x69, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x0A, ++ 0x49, 0x45, 0x4E, 0x42, 0x4D, 0x49, 0x49, 0x43, 0x49, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x67, 0x38, 0x41, 0x4D, 0x49, 0x49, 0x43, ++ 0x43, 0x67, 0x4B, 0x43, 0x41, 0x67, 0x45, 0x41, 0x70, 0x38, 0x62, 0x45, 0x70, 0x53, 0x6D, 0x6B, 0x4C, 0x4F, 0x2F, 0x6C, 0x47, 0x4D, 0x57, 0x77, 0x55, 0x4B, 0x4E, 0x76, 0x55, 0x54, 0x75, 0x66, 0x43, 0x6C, 0x72, 0x4A, 0x0A, 0x77, 0x6B, 0x67, ++ 0x34, 0x43, 0x73, 0x49, 0x63, 0x6F, 0x42, 0x68, 0x2F, 0x6B, 0x62, 0x57, 0x48, 0x75, 0x55, 0x41, 0x2F, 0x33, 0x52, 0x31, 0x6F, 0x48, 0x77, 0x69, 0x44, 0x31, 0x53, 0x30, 0x65, 0x69, 0x4B, 0x44, 0x34, 0x6A, 0x31, 0x61, 0x50, 0x62, 0x5A, 0x6B, ++ 0x43, 0x6B, 0x70, 0x41, 0x57, 0x31, 0x56, 0x38, 0x49, 0x62, 0x49, 0x6E, 0x58, 0x34, 0x61, 0x79, 0x38, 0x49, 0x4D, 0x4B, 0x78, 0x34, 0x49, 0x4E, 0x52, 0x69, 0x6D, 0x6C, 0x4E, 0x41, 0x4A, 0x5A, 0x61, 0x0A, 0x62, 0x79, 0x2F, 0x41, 0x52, 0x48, ++ 0x36, 0x6A, 0x44, 0x75, 0x53, 0x52, 0x7A, 0x56, 0x6A, 0x75, 0x33, 0x50, 0x76, 0x48, 0x48, 0x6B, 0x56, 0x48, 0x33, 0x53, 0x65, 0x35, 0x43, 0x41, 0x47, 0x66, 0x70, 0x69, 0x45, 0x64, 0x39, 0x55, 0x45, 0x74, 0x4C, 0x30, 0x7A, 0x39, 0x4B, 0x4B, ++ 0x33, 0x67, 0x69, 0x71, 0x30, 0x69, 0x74, 0x46, 0x5A, 0x6C, 0x6A, 0x6F, 0x5A, 0x55, 0x6A, 0x35, 0x4E, 0x44, 0x4B, 0x64, 0x34, 0x35, 0x52, 0x6E, 0x69, 0x6A, 0x4D, 0x43, 0x4F, 0x36, 0x0A, 0x7A, 0x66, 0x42, 0x39, 0x45, 0x31, 0x66, 0x41, 0x58, ++ 0x64, 0x4B, 0x44, 0x61, 0x30, 0x68, 0x4D, 0x78, 0x4B, 0x75, 0x66, 0x67, 0x46, 0x70, 0x62, 0x4F, 0x72, 0x33, 0x4A, 0x70, 0x79, 0x49, 0x2F, 0x67, 0x43, 0x63, 0x7A, 0x57, 0x77, 0x36, 0x33, 0x69, 0x67, 0x78, 0x64, 0x42, 0x7A, 0x63, 0x49, 0x79, ++ 0x32, 0x7A, 0x53, 0x65, 0x6B, 0x63, 0x69, 0x52, 0x44, 0x58, 0x46, 0x7A, 0x4D, 0x77, 0x75, 0x6A, 0x74, 0x30, 0x71, 0x37, 0x62, 0x64, 0x39, 0x5A, 0x67, 0x31, 0x66, 0x0A, 0x59, 0x56, 0x45, 0x69, 0x56, 0x52, 0x76, 0x6A, 0x52, 0x75, 0x50, 0x6A, ++ 0x50, 0x64, 0x41, 0x31, 0x59, 0x70, 0x72, 0x62, 0x72, 0x78, 0x54, 0x49, 0x57, 0x36, 0x48, 0x4D, 0x69, 0x52, 0x76, 0x68, 0x4D, 0x43, 0x62, 0x38, 0x6F, 0x4A, 0x73, 0x66, 0x67, 0x61, 0x64, 0x48, 0x48, 0x77, 0x54, 0x72, 0x6F, 0x7A, 0x6D, 0x53, ++ 0x42, 0x70, 0x2B, 0x5A, 0x30, 0x37, 0x2F, 0x54, 0x36, 0x6B, 0x39, 0x51, 0x6E, 0x42, 0x6E, 0x2B, 0x6C, 0x6F, 0x63, 0x65, 0x50, 0x47, 0x58, 0x32, 0x0A, 0x6F, 0x78, 0x67, 0x6B, 0x67, 0x34, 0x59, 0x51, 0x35, 0x31, 0x51, 0x2B, 0x71, 0x44, 0x70, ++ 0x32, 0x4A, 0x45, 0x2B, 0x42, 0x49, 0x63, 0x58, 0x6A, 0x44, 0x77, 0x4C, 0x34, 0x6B, 0x35, 0x52, 0x48, 0x49, 0x4C, 0x76, 0x2B, 0x31, 0x41, 0x37, 0x54, 0x61, 0x4C, 0x6E, 0x64, 0x78, 0x48, 0x71, 0x45, 0x67, 0x75, 0x4E, 0x54, 0x56, 0x48, 0x6E, ++ 0x64, 0x32, 0x35, 0x7A, 0x53, 0x38, 0x67, 0x65, 0x62, 0x4C, 0x72, 0x61, 0x38, 0x50, 0x75, 0x32, 0x46, 0x62, 0x65, 0x38, 0x6C, 0x0A, 0x45, 0x66, 0x4B, 0x58, 0x47, 0x6B, 0x4A, 0x68, 0x39, 0x30, 0x71, 0x58, 0x36, 0x49, 0x75, 0x78, 0x45, 0x41, ++ 0x66, 0x36, 0x5A, 0x59, 0x47, 0x79, 0x6F, 0x6A, 0x6E, 0x50, 0x39, 0x7A, 0x7A, 0x2F, 0x47, 0x50, 0x76, 0x47, 0x38, 0x56, 0x71, 0x4C, 0x57, 0x65, 0x49, 0x43, 0x72, 0x48, 0x75, 0x53, 0x30, 0x45, 0x34, 0x55, 0x54, 0x31, 0x6C, 0x46, 0x39, 0x67, ++ 0x78, 0x65, 0x4B, 0x46, 0x2B, 0x77, 0x36, 0x44, 0x39, 0x46, 0x7A, 0x38, 0x2B, 0x76, 0x6D, 0x32, 0x2F, 0x37, 0x0A, 0x68, 0x4E, 0x4E, 0x33, 0x57, 0x70, 0x56, 0x76, 0x72, 0x4A, 0x53, 0x45, 0x6E, 0x75, 0x36, 0x38, 0x77, 0x45, 0x71, 0x50, 0x53, ++ 0x70, 0x50, 0x34, 0x52, 0x43, 0x48, 0x69, 0x4D, 0x55, 0x56, 0x68, 0x55, 0x45, 0x34, 0x51, 0x32, 0x4F, 0x4D, 0x31, 0x66, 0x45, 0x77, 0x5A, 0x74, 0x4E, 0x34, 0x46, 0x76, 0x36, 0x4D, 0x47, 0x6E, 0x38, 0x69, 0x31, 0x7A, 0x65, 0x51, 0x66, 0x31, ++ 0x78, 0x63, 0x47, 0x44, 0x58, 0x71, 0x56, 0x64, 0x46, 0x55, 0x4E, 0x61, 0x42, 0x72, 0x38, 0x0A, 0x45, 0x42, 0x74, 0x69, 0x5A, 0x4A, 0x31, 0x74, 0x34, 0x4A, 0x57, 0x67, 0x77, 0x35, 0x51, 0x48, 0x56, 0x77, 0x30, 0x55, 0x35, 0x72, 0x30, 0x46, ++ 0x2B, 0x37, 0x69, 0x66, 0x35, 0x74, 0x2B, 0x4C, 0x34, 0x73, 0x62, 0x6E, 0x66, 0x70, 0x62, 0x32, 0x55, 0x38, 0x57, 0x41, 0x4E, 0x46, 0x41, 0x6F, 0x57, 0x50, 0x41, 0x53, 0x55, 0x48, 0x45, 0x58, 0x4D, 0x4C, 0x72, 0x6D, 0x65, 0x47, 0x4F, 0x38, ++ 0x39, 0x4C, 0x4B, 0x74, 0x6D, 0x79, 0x75, 0x79, 0x2F, 0x75, 0x45, 0x35, 0x0A, 0x6A, 0x46, 0x36, 0x36, 0x43, 0x79, 0x43, 0x55, 0x33, 0x6E, 0x75, 0x44, 0x75, 0x50, 0x2F, 0x6A, 0x56, 0x6F, 0x32, 0x33, 0x45, 0x65, 0x6B, 0x37, 0x6A, 0x50, 0x4B, ++ 0x78, 0x77, 0x56, 0x32, 0x64, 0x70, 0x41, 0x74, 0x4D, 0x4B, 0x39, 0x6D, 0x79, 0x47, 0x50, 0x57, 0x31, 0x6E, 0x30, 0x73, 0x43, 0x41, 0x77, 0x45, 0x41, 0x41, 0x61, 0x4E, 0x6A, 0x4D, 0x47, 0x45, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, ++ 0x4F, 0x42, 0x42, 0x59, 0x45, 0x46, 0x46, 0x4C, 0x59, 0x0A, 0x69, 0x44, 0x72, 0x49, 0x6E, 0x33, 0x68, 0x6D, 0x37, 0x59, 0x6E, 0x7A, 0x65, 0x7A, 0x68, 0x77, 0x6C, 0x4D, 0x6B, 0x43, 0x41, 0x6A, 0x62, 0x51, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, ++ 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x48, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x6A, 0x42, 0x42, 0x67, 0x77, 0x46, 0x6F, 0x41, 0x55, 0x55, 0x74, 0x69, 0x49, 0x4F, 0x73, ++ 0x69, 0x66, 0x65, 0x47, 0x62, 0x74, 0x0A, 0x69, 0x66, 0x4E, 0x37, 0x4F, 0x48, 0x43, 0x55, 0x79, 0x51, 0x49, 0x43, 0x4E, 0x74, 0x41, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, ++ 0x67, 0x45, 0x47, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43, 0x77, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x41, 0x51, 0x41, 0x4C, 0x65, 0x33, 0x4B, 0x48, 0x77, 0x47, 0x43, 0x6D, 0x53, ++ 0x55, 0x79, 0x49, 0x0A, 0x57, 0x4F, 0x59, 0x64, 0x69, 0x50, 0x63, 0x55, 0x5A, 0x45, 0x69, 0x6D, 0x32, 0x46, 0x67, 0x4B, 0x44, 0x6B, 0x38, 0x54, 0x4E, 0x64, 0x38, 0x31, 0x48, 0x64, 0x54, 0x74, 0x42, 0x6A, 0x48, 0x49, 0x67, 0x54, 0x35, 0x71, ++ 0x31, 0x64, 0x30, 0x37, 0x47, 0x6A, 0x4C, 0x75, 0x6B, 0x44, 0x30, 0x52, 0x30, 0x69, 0x37, 0x30, 0x6A, 0x73, 0x4E, 0x6A, 0x4C, 0x69, 0x4E, 0x6D, 0x73, 0x47, 0x65, 0x2B, 0x62, 0x37, 0x62, 0x41, 0x45, 0x7A, 0x6C, 0x67, 0x71, 0x71, 0x49, 0x30, ++ 0x0A, 0x4A, 0x5A, 0x4E, 0x31, 0x55, 0x74, 0x36, 0x6E, 0x6E, 0x61, 0x30, 0x4F, 0x68, 0x34, 0x6C, 0x53, 0x63, 0x57, 0x6F, 0x57, 0x50, 0x42, 0x6B, 0x64, 0x67, 0x2F, 0x69, 0x61, 0x4B, 0x57, 0x57, 0x2B, 0x39, 0x44, 0x2B, 0x61, 0x32, 0x66, 0x44, ++ 0x7A, 0x57, 0x6F, 0x63, 0x68, 0x63, 0x59, 0x42, 0x4E, 0x79, 0x2B, 0x41, 0x34, 0x6D, 0x7A, 0x2B, 0x37, 0x2B, 0x75, 0x41, 0x77, 0x54, 0x63, 0x2B, 0x47, 0x30, 0x32, 0x55, 0x51, 0x47, 0x52, 0x6A, 0x52, 0x6C, 0x77, 0x4B, 0x78, 0x0A, 0x4B, 0x33, ++ 0x4A, 0x43, 0x61, 0x4B, 0x79, 0x67, 0x76, 0x55, 0x35, 0x61, 0x32, 0x68, 0x69, 0x2F, 0x61, 0x35, 0x69, 0x42, 0x30, 0x50, 0x32, 0x61, 0x76, 0x6C, 0x34, 0x56, 0x53, 0x4D, 0x30, 0x52, 0x46, 0x62, 0x6E, 0x41, 0x4B, 0x56, 0x79, 0x30, 0x36, 0x49, ++ 0x6A, 0x33, 0x50, 0x6A, 0x61, 0x75, 0x74, 0x32, 0x4C, 0x39, 0x48, 0x6D, 0x4C, 0x65, 0x63, 0x48, 0x67, 0x51, 0x48, 0x45, 0x68, 0x62, 0x32, 0x72, 0x79, 0x6B, 0x4F, 0x4C, 0x70, 0x6E, 0x37, 0x56, 0x55, 0x2B, 0x0A, 0x58, 0x6C, 0x66, 0x66, 0x31, ++ 0x41, 0x4E, 0x41, 0x54, 0x49, 0x47, 0x6B, 0x30, 0x6B, 0x39, 0x6A, 0x70, 0x77, 0x6C, 0x43, 0x43, 0x52, 0x54, 0x38, 0x41, 0x4B, 0x6E, 0x43, 0x67, 0x48, 0x4E, 0x50, 0x4C, 0x73, 0x42, 0x41, 0x32, 0x52, 0x46, 0x37, 0x53, 0x4F, 0x70, 0x36, 0x41, ++ 0x73, 0x44, 0x54, 0x36, 0x79, 0x67, 0x42, 0x4A, 0x6C, 0x68, 0x30, 0x77, 0x63, 0x42, 0x7A, 0x49, 0x6D, 0x32, 0x54, 0x6C, 0x66, 0x30, 0x35, 0x66, 0x62, 0x73, 0x71, 0x34, 0x2F, 0x61, 0x43, 0x0A, 0x34, 0x79, 0x79, 0x58, 0x58, 0x30, 0x34, 0x66, ++ 0x6B, 0x5A, 0x54, 0x36, 0x2F, 0x69, 0x79, 0x6A, 0x32, 0x48, 0x59, 0x61, 0x75, 0x45, 0x32, 0x79, 0x4F, 0x45, 0x2B, 0x62, 0x2B, 0x68, 0x31, 0x49, 0x59, 0x48, 0x6B, 0x6D, 0x34, 0x76, 0x50, 0x39, 0x71, 0x64, 0x43, 0x61, 0x36, 0x48, 0x43, 0x50, ++ 0x53, 0x58, 0x72, 0x57, 0x35, 0x62, 0x30, 0x4B, 0x44, 0x74, 0x73, 0x74, 0x38, 0x34, 0x32, 0x2F, 0x36, 0x2B, 0x4F, 0x6B, 0x66, 0x63, 0x76, 0x48, 0x6C, 0x58, 0x48, 0x6F, 0x0A, 0x32, 0x71, 0x4E, 0x38, 0x78, 0x63, 0x4C, 0x34, 0x64, 0x4A, 0x49, ++ 0x45, 0x47, 0x34, 0x61, 0x73, 0x70, 0x43, 0x4A, 0x54, 0x51, 0x4C, 0x61, 0x73, 0x2F, 0x6B, 0x78, 0x32, 0x7A, 0x2F, 0x75, 0x55, 0x4D, 0x73, 0x41, 0x31, 0x6E, 0x33, 0x59, 0x2F, 0x62, 0x75, 0x57, 0x51, 0x62, 0x71, 0x43, 0x6D, 0x4A, 0x71, 0x4B, ++ 0x34, 0x4C, 0x4C, 0x37, 0x52, 0x4B, 0x34, 0x58, 0x39, 0x70, 0x32, 0x6A, 0x49, 0x75, 0x67, 0x45, 0x72, 0x73, 0x57, 0x78, 0x30, 0x48, 0x62, 0x68, 0x7A, 0x0A, 0x6C, 0x65, 0x66, 0x75, 0x74, 0x38, 0x63, 0x6C, 0x38, 0x41, 0x42, 0x4D, 0x41, 0x4C, ++ 0x4A, 0x2B, 0x74, 0x67, 0x75, 0x4C, 0x48, 0x50, 0x50, 0x41, 0x55, 0x4A, 0x34, 0x6C, 0x75, 0x65, 0x41, 0x49, 0x33, 0x6A, 0x5A, 0x6D, 0x2F, 0x7A, 0x65, 0x6C, 0x30, 0x62, 0x74, 0x55, 0x5A, 0x43, 0x7A, 0x4A, 0x4A, 0x37, 0x56, 0x4C, 0x6B, 0x6E, ++ 0x35, 0x6C, 0x2F, 0x39, 0x4D, 0x74, 0x34, 0x62, 0x6C, 0x4F, 0x76, 0x48, 0x2B, 0x6B, 0x51, 0x53, 0x47, 0x51, 0x51, 0x58, 0x65, 0x6D, 0x0A, 0x4F, 0x52, 0x2F, 0x71, 0x6E, 0x75, 0x4F, 0x66, 0x30, 0x47, 0x5A, 0x76, 0x42, 0x65, 0x79, 0x71, 0x64, ++ 0x6E, 0x36, 0x2F, 0x61, 0x78, 0x61, 0x67, 0x36, 0x37, 0x58, 0x48, 0x2F, 0x4A, 0x4A, 0x55, 0x4C, 0x79, 0x73, 0x52, 0x4A, 0x79, 0x55, 0x33, 0x65, 0x45, 0x78, 0x52, 0x61, 0x72, 0x44, 0x7A, 0x7A, 0x46, 0x68, 0x64, 0x46, 0x50, 0x46, 0x71, 0x53, ++ 0x42, 0x58, 0x2F, 0x77, 0x67, 0x65, 0x32, 0x73, 0x59, 0x30, 0x50, 0x6A, 0x6C, 0x78, 0x51, 0x52, 0x72, 0x4D, 0x39, 0x0A, 0x76, 0x77, 0x47, 0x59, 0x54, 0x37, 0x4A, 0x5A, 0x56, 0x45, 0x63, 0x2B, 0x4E, 0x48, 0x74, 0x34, 0x62, 0x56, 0x61, 0x54, ++ 0x4C, 0x6E, 0x50, 0x71, 0x5A, 0x69, 0x68, 0x34, 0x7A, 0x52, 0x30, 0x55, 0x76, 0x36, 0x43, 0x50, 0x4C, 0x79, 0x36, 0x34, 0x4C, 0x6F, 0x37, 0x79, 0x46, 0x49, 0x72, 0x4D, 0x36, 0x62, 0x56, 0x38, 0x2B, 0x32, 0x79, 0x64, 0x44, 0x4B, 0x58, 0x68, ++ 0x6C, 0x67, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x42, 0x75, 0x79, 0x70, 0x61, 0x73, 0x73, 0x20, ++ 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, ++ 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x57, 0x54, 0x43, 0x43, 0x41, 0x30, 0x47, 0x67, ++ 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x42, 0x41, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x42, 0x4F, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, ++ 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x4F, 0x54, 0x7A, 0x45, 0x64, 0x4D, 0x42, 0x73, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x55, 0x0A, 0x51, 0x6E, 0x56, 0x35, 0x63, 0x47, 0x46, 0x7A, 0x63, 0x79, 0x42, 0x42, 0x55, 0x79, 0x30, ++ 0x35, 0x4F, 0x44, 0x4D, 0x78, 0x4E, 0x6A, 0x4D, 0x7A, 0x4D, 0x6A, 0x63, 0x78, 0x49, 0x44, 0x41, 0x65, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x46, 0x30, 0x4A, 0x31, 0x65, 0x58, 0x42, 0x68, 0x63, 0x33, 0x4D, 0x67, 0x51, 0x32, 0x78, ++ 0x68, 0x63, 0x33, 0x4D, 0x67, 0x4D, 0x69, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x4D, 0x42, 0x34, 0x58, 0x0A, 0x44, 0x54, 0x45, 0x77, 0x4D, 0x54, 0x41, 0x79, 0x4E, 0x6A, 0x41, 0x34, 0x4D, 0x7A, 0x67, 0x77, 0x4D, 0x31, ++ 0x6F, 0x58, 0x44, 0x54, 0x51, 0x77, 0x4D, 0x54, 0x41, 0x79, 0x4E, 0x6A, 0x41, 0x34, 0x4D, 0x7A, 0x67, 0x77, 0x4D, 0x31, 0x6F, 0x77, 0x54, 0x6A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x54, 0x6B, ++ 0x38, 0x78, 0x48, 0x54, 0x41, 0x62, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x46, 0x45, 0x4A, 0x31, 0x0A, 0x65, 0x58, 0x42, 0x68, 0x63, 0x33, 0x4D, 0x67, 0x51, 0x56, 0x4D, 0x74, 0x4F, 0x54, 0x67, 0x7A, 0x4D, 0x54, 0x59, 0x7A, 0x4D, ++ 0x7A, 0x49, 0x33, 0x4D, 0x53, 0x41, 0x77, 0x48, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x42, 0x64, 0x43, 0x64, 0x58, 0x6C, 0x77, 0x59, 0x58, 0x4E, 0x7A, 0x49, 0x45, 0x4E, 0x73, 0x59, 0x58, 0x4E, 0x7A, 0x49, 0x44, 0x49, 0x67, 0x55, ++ 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x54, 0x43, 0x43, 0x41, 0x69, 0x49, 0x77, 0x0A, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x50, ++ 0x41, 0x44, 0x43, 0x43, 0x41, 0x67, 0x6F, 0x43, 0x67, 0x67, 0x49, 0x42, 0x41, 0x4E, 0x66, 0x48, 0x58, 0x76, 0x66, 0x42, 0x42, 0x39, 0x52, 0x33, 0x2B, 0x30, 0x4D, 0x68, 0x39, 0x50, 0x54, 0x31, 0x61, 0x65, 0x54, 0x75, 0x4D, 0x67, 0x48, 0x62, ++ 0x6F, 0x34, 0x59, 0x66, 0x35, 0x46, 0x6B, 0x4E, 0x75, 0x75, 0x64, 0x31, 0x0A, 0x67, 0x31, 0x4C, 0x72, 0x36, 0x68, 0x78, 0x68, 0x46, 0x55, 0x69, 0x37, 0x48, 0x51, 0x66, 0x4B, 0x6A, 0x4B, 0x36, 0x77, 0x33, 0x4A, 0x61, 0x64, 0x36, 0x73, 0x4E, ++ 0x67, 0x6B, 0x6F, 0x61, 0x43, 0x4B, 0x48, 0x4F, 0x63, 0x56, 0x67, 0x62, 0x2F, 0x53, 0x32, 0x54, 0x77, 0x44, 0x43, 0x6F, 0x33, 0x53, 0x62, 0x58, 0x6C, 0x7A, 0x77, 0x78, 0x38, 0x37, 0x76, 0x46, 0x4B, 0x75, 0x33, 0x4D, 0x77, 0x5A, 0x66, 0x50, ++ 0x56, 0x4C, 0x34, 0x4F, 0x32, 0x66, 0x75, 0x50, 0x6E, 0x0A, 0x39, 0x5A, 0x36, 0x72, 0x59, 0x50, 0x6E, 0x54, 0x38, 0x5A, 0x32, 0x53, 0x64, 0x49, 0x72, 0x6B, 0x48, 0x4A, 0x61, 0x73, 0x57, 0x34, 0x44, 0x70, 0x74, 0x66, 0x51, 0x78, 0x68, 0x36, ++ 0x4E, 0x52, 0x2F, 0x4D, 0x64, 0x2B, 0x6F, 0x57, 0x2B, 0x4F, 0x55, 0x33, 0x66, 0x55, 0x6C, 0x38, 0x46, 0x56, 0x4D, 0x35, 0x49, 0x2B, 0x47, 0x43, 0x39, 0x31, 0x31, 0x4B, 0x32, 0x47, 0x53, 0x63, 0x75, 0x56, 0x72, 0x31, 0x51, 0x47, 0x62, 0x4E, ++ 0x67, 0x47, 0x45, 0x34, 0x31, 0x62, 0x0A, 0x2F, 0x2B, 0x45, 0x6D, 0x47, 0x56, 0x6E, 0x41, 0x4A, 0x4C, 0x71, 0x42, 0x63, 0x58, 0x6D, 0x51, 0x52, 0x46, 0x42, 0x6F, 0x4A, 0x4A, 0x52, 0x66, 0x75, 0x4C, 0x4D, 0x52, 0x38, 0x53, 0x6C, 0x42, 0x59, ++ 0x61, 0x4E, 0x42, 0x79, 0x79, 0x4D, 0x32, 0x31, 0x63, 0x48, 0x78, 0x4D, 0x6C, 0x41, 0x51, 0x54, 0x6E, 0x2F, 0x30, 0x68, 0x70, 0x50, 0x73, 0x68, 0x4E, 0x4F, 0x4F, 0x76, 0x45, 0x75, 0x2F, 0x58, 0x41, 0x46, 0x4F, 0x42, 0x7A, 0x33, 0x63, 0x46, ++ 0x49, 0x71, 0x55, 0x0A, 0x43, 0x71, 0x54, 0x71, 0x63, 0x2F, 0x73, 0x4C, 0x55, 0x65, 0x67, 0x54, 0x42, 0x78, 0x6A, 0x36, 0x44, 0x76, 0x45, 0x72, 0x30, 0x56, 0x51, 0x56, 0x66, 0x54, 0x7A, 0x68, 0x39, 0x37, 0x51, 0x5A, 0x51, 0x6D, 0x64, 0x69, ++ 0x58, 0x6E, 0x66, 0x67, 0x6F, 0x6C, 0x58, 0x73, 0x74, 0x74, 0x6C, 0x70, 0x46, 0x39, 0x55, 0x36, 0x72, 0x30, 0x54, 0x74, 0x53, 0x73, 0x57, 0x65, 0x35, 0x48, 0x6F, 0x6E, 0x66, 0x4F, 0x56, 0x31, 0x31, 0x36, 0x72, 0x4C, 0x4A, 0x65, 0x66, 0x66, ++ 0x0A, 0x61, 0x77, 0x72, 0x62, 0x44, 0x30, 0x32, 0x54, 0x54, 0x71, 0x69, 0x67, 0x7A, 0x58, 0x73, 0x75, 0x38, 0x6C, 0x6B, 0x42, 0x61, 0x72, 0x63, 0x4E, 0x75, 0x41, 0x65, 0x42, 0x66, 0x6F, 0x73, 0x34, 0x47, 0x7A, 0x6A, 0x6D, 0x43, 0x6C, 0x65, ++ 0x5A, 0x50, 0x65, 0x34, 0x68, 0x36, 0x4B, 0x50, 0x31, 0x44, 0x42, 0x62, 0x64, 0x69, 0x2B, 0x77, 0x30, 0x6A, 0x70, 0x77, 0x71, 0x48, 0x41, 0x41, 0x56, 0x46, 0x34, 0x31, 0x6F, 0x67, 0x39, 0x4A, 0x77, 0x6E, 0x78, 0x67, 0x49, 0x0A, 0x7A, 0x52, ++ 0x46, 0x6F, 0x31, 0x63, 0x6C, 0x72, 0x55, 0x73, 0x33, 0x45, 0x52, 0x6F, 0x2F, 0x63, 0x74, 0x66, 0x50, 0x59, 0x56, 0x33, 0x4D, 0x65, 0x36, 0x5A, 0x51, 0x35, 0x42, 0x4C, 0x2F, 0x54, 0x33, 0x6A, 0x6A, 0x65, 0x74, 0x46, 0x50, 0x73, 0x61, 0x52, ++ 0x79, 0x69, 0x66, 0x73, 0x53, 0x50, 0x35, 0x42, 0x74, 0x77, 0x72, 0x66, 0x4B, 0x69, 0x2B, 0x66, 0x76, 0x33, 0x46, 0x6D, 0x52, 0x6D, 0x61, 0x5A, 0x39, 0x4A, 0x55, 0x61, 0x4C, 0x69, 0x46, 0x52, 0x68, 0x6E, 0x0A, 0x42, 0x6B, 0x70, 0x2F, 0x31, ++ 0x57, 0x79, 0x31, 0x54, 0x62, 0x4D, 0x7A, 0x34, 0x47, 0x48, 0x72, 0x58, 0x62, 0x37, 0x70, 0x6D, 0x41, 0x38, 0x79, 0x31, 0x78, 0x31, 0x4C, 0x50, 0x43, 0x35, 0x61, 0x41, 0x56, 0x4B, 0x52, 0x43, 0x66, 0x4C, 0x66, 0x36, 0x6F, 0x33, 0x59, 0x42, ++ 0x6B, 0x42, 0x6A, 0x71, 0x68, 0x48, 0x6B, 0x2F, 0x73, 0x4D, 0x33, 0x6E, 0x68, 0x52, 0x53, 0x50, 0x2F, 0x54, 0x69, 0x7A, 0x50, 0x4A, 0x68, 0x6B, 0x39, 0x48, 0x39, 0x5A, 0x32, 0x76, 0x58, 0x0A, 0x55, 0x71, 0x36, 0x2F, 0x61, 0x4B, 0x74, 0x41, ++ 0x51, 0x36, 0x42, 0x58, 0x4E, 0x56, 0x4E, 0x34, 0x38, 0x46, 0x50, 0x34, 0x59, 0x55, 0x49, 0x48, 0x5A, 0x4D, 0x62, 0x58, 0x62, 0x35, 0x74, 0x4D, 0x4F, 0x41, 0x31, 0x6A, 0x72, 0x47, 0x4B, 0x76, 0x4E, 0x6F, 0x75, 0x69, 0x63, 0x77, 0x6F, 0x4E, ++ 0x39, 0x53, 0x47, 0x39, 0x64, 0x4B, 0x70, 0x4E, 0x36, 0x6E, 0x49, 0x44, 0x53, 0x64, 0x76, 0x48, 0x58, 0x78, 0x31, 0x69, 0x59, 0x38, 0x66, 0x39, 0x33, 0x5A, 0x48, 0x73, 0x0A, 0x4D, 0x2B, 0x37, 0x31, 0x62, 0x62, 0x52, 0x75, 0x4D, 0x47, 0x6A, ++ 0x65, 0x79, 0x4E, 0x59, 0x6D, 0x73, 0x48, 0x56, 0x65, 0x65, 0x37, 0x51, 0x48, 0x49, 0x4A, 0x69, 0x68, 0x64, 0x6A, 0x4B, 0x34, 0x54, 0x57, 0x78, 0x50, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, 0x51, 0x6A, 0x42, 0x41, 0x4D, 0x41, 0x38, ++ 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x48, 0x51, 0x59, 0x44, 0x0A, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x46, 0x4D, 0x6D, 0x41, 0x64, 0x2B, ++ 0x42, 0x69, 0x6B, 0x6F, 0x4C, 0x31, 0x52, 0x70, 0x7A, 0x7A, 0x75, 0x76, 0x64, 0x4D, 0x77, 0x39, 0x36, 0x34, 0x6F, 0x36, 0x30, 0x35, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, ++ 0x49, 0x42, 0x42, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x0A, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x67, 0x45, 0x41, 0x55, 0x31, 0x38, 0x68, 0x39, 0x62, 0x71, 0x77, 0x4F, ++ 0x6C, 0x49, 0x35, 0x4C, 0x4A, 0x4B, 0x77, 0x62, 0x41, 0x44, 0x4A, 0x37, 0x38, 0x34, 0x67, 0x37, 0x77, 0x62, 0x79, 0x6C, 0x70, 0x37, 0x70, 0x70, 0x48, 0x52, 0x2F, 0x65, 0x68, 0x62, 0x38, 0x74, 0x2F, 0x57, 0x32, 0x2B, 0x78, 0x55, 0x62, 0x50, ++ 0x36, 0x75, 0x6D, 0x77, 0x48, 0x4A, 0x64, 0x45, 0x4C, 0x46, 0x78, 0x37, 0x72, 0x78, 0x50, 0x34, 0x36, 0x32, 0x73, 0x0A, 0x41, 0x32, 0x30, 0x75, 0x63, 0x53, 0x36, 0x76, 0x78, 0x4F, 0x4F, 0x74, 0x6F, 0x37, 0x30, 0x4D, 0x45, 0x61, 0x65, 0x30, ++ 0x2F, 0x30, 0x71, 0x79, 0x65, 0x78, 0x41, 0x51, 0x48, 0x36, 0x64, 0x58, 0x51, 0x62, 0x4C, 0x41, 0x72, 0x76, 0x51, 0x73, 0x57, 0x64, 0x5A, 0x48, 0x45, 0x49, 0x6A, 0x7A, 0x49, 0x56, 0x45, 0x70, 0x4D, 0x4D, 0x70, 0x67, 0x68, 0x71, 0x39, 0x47, ++ 0x71, 0x78, 0x33, 0x74, 0x4F, 0x6C, 0x75, 0x77, 0x6C, 0x4E, 0x35, 0x45, 0x34, 0x30, 0x45, 0x49, 0x0A, 0x6F, 0x73, 0x48, 0x73, 0x48, 0x64, 0x62, 0x39, 0x54, 0x37, 0x62, 0x57, 0x52, 0x39, 0x41, 0x55, 0x43, 0x38, 0x72, 0x6D, 0x79, 0x72, 0x56, ++ 0x37, 0x64, 0x33, 0x35, 0x42, 0x48, 0x31, 0x36, 0x44, 0x78, 0x37, 0x61, 0x4D, 0x4F, 0x5A, 0x61, 0x77, 0x50, 0x35, 0x61, 0x42, 0x51, 0x57, 0x39, 0x67, 0x6B, 0x4F, 0x4C, 0x6F, 0x2B, 0x66, 0x73, 0x69, 0x63, 0x64, 0x6C, 0x39, 0x73, 0x7A, 0x31, ++ 0x47, 0x76, 0x37, 0x53, 0x45, 0x72, 0x35, 0x41, 0x63, 0x44, 0x34, 0x38, 0x53, 0x0A, 0x61, 0x71, 0x2F, 0x76, 0x37, 0x68, 0x35, 0x36, 0x72, 0x67, 0x4A, 0x4B, 0x69, 0x68, 0x63, 0x72, 0x64, 0x76, 0x36, 0x73, 0x56, 0x49, 0x6B, 0x6B, 0x4C, 0x45, ++ 0x38, 0x2F, 0x74, 0x72, 0x4B, 0x6E, 0x54, 0x6F, 0x79, 0x6F, 0x6B, 0x5A, 0x66, 0x37, 0x4B, 0x63, 0x5A, 0x37, 0x58, 0x43, 0x32, 0x35, 0x79, 0x32, 0x61, 0x32, 0x74, 0x36, 0x68, 0x62, 0x45, 0x6C, 0x47, 0x46, 0x74, 0x51, 0x6C, 0x2B, 0x59, 0x6E, ++ 0x68, 0x77, 0x2F, 0x71, 0x6C, 0x71, 0x59, 0x4C, 0x59, 0x64, 0x0A, 0x44, 0x6E, 0x6B, 0x4D, 0x2F, 0x63, 0x72, 0x71, 0x4A, 0x49, 0x42, 0x79, 0x77, 0x35, 0x63, 0x2F, 0x38, 0x6E, 0x65, 0x72, 0x51, 0x79, 0x49, 0x4B, 0x78, 0x2B, 0x75, 0x32, 0x44, ++ 0x49, 0x53, 0x43, 0x4C, 0x49, 0x42, 0x72, 0x51, 0x59, 0x6F, 0x49, 0x77, 0x4F, 0x75, 0x6C, 0x61, 0x39, 0x2B, 0x5A, 0x45, 0x73, 0x75, 0x4B, 0x31, 0x56, 0x36, 0x41, 0x44, 0x4A, 0x48, 0x67, 0x4A, 0x67, 0x67, 0x32, 0x53, 0x4D, 0x58, 0x36, 0x4F, ++ 0x42, 0x45, 0x31, 0x2F, 0x79, 0x57, 0x44, 0x0A, 0x4C, 0x66, 0x4A, 0x36, 0x76, 0x39, 0x72, 0x39, 0x6A, 0x76, 0x36, 0x6C, 0x79, 0x30, 0x55, 0x73, 0x48, 0x38, 0x53, 0x49, 0x55, 0x36, 0x35, 0x33, 0x44, 0x74, 0x6D, 0x61, 0x64, 0x73, 0x57, 0x4F, ++ 0x4C, 0x42, 0x32, 0x6A, 0x75, 0x74, 0x58, 0x73, 0x4D, 0x71, 0x37, 0x41, 0x71, 0x71, 0x7A, 0x33, 0x30, 0x58, 0x70, 0x4E, 0x36, 0x39, 0x51, 0x48, 0x34, 0x6B, 0x6A, 0x33, 0x49, 0x6F, 0x36, 0x77, 0x70, 0x4A, 0x39, 0x71, 0x7A, 0x6F, 0x36, 0x79, ++ 0x73, 0x6D, 0x44, 0x30, 0x0A, 0x6F, 0x79, 0x4C, 0x51, 0x49, 0x2B, 0x75, 0x55, 0x57, 0x6E, 0x70, 0x70, 0x33, 0x51, 0x2B, 0x2F, 0x51, 0x46, 0x65, 0x73, 0x61, 0x31, 0x6C, 0x51, 0x32, 0x61, 0x4F, 0x5A, 0x34, 0x57, 0x37, 0x2B, 0x6A, 0x51, 0x46, ++ 0x35, 0x4A, 0x79, 0x4D, 0x56, 0x33, 0x70, 0x4B, 0x64, 0x65, 0x77, 0x6C, 0x4E, 0x57, 0x75, 0x64, 0x4C, 0x53, 0x44, 0x42, 0x61, 0x47, 0x4F, 0x59, 0x4B, 0x62, 0x65, 0x61, 0x50, 0x34, 0x4E, 0x4B, 0x37, 0x35, 0x74, 0x39, 0x38, 0x62, 0x69, 0x47, ++ 0x43, 0x0A, 0x77, 0x57, 0x67, 0x35, 0x54, 0x62, 0x53, 0x59, 0x57, 0x47, 0x5A, 0x69, 0x7A, 0x45, 0x71, 0x51, 0x58, 0x73, 0x50, 0x36, 0x4A, 0x77, 0x53, 0x78, 0x65, 0x52, 0x56, 0x30, 0x6D, 0x63, 0x79, 0x2B, 0x72, 0x53, 0x44, 0x65, 0x4A, 0x6D, ++ 0x41, 0x63, 0x36, 0x31, 0x5A, 0x52, 0x70, 0x71, 0x50, 0x71, 0x35, 0x4B, 0x4D, 0x2F, 0x70, 0x2F, 0x39, 0x68, 0x33, 0x50, 0x46, 0x61, 0x54, 0x57, 0x77, 0x79, 0x49, 0x30, 0x50, 0x75, 0x72, 0x4B, 0x6A, 0x75, 0x37, 0x6B, 0x6F, 0x53, 0x0A, 0x43, ++ 0x54, 0x78, 0x64, 0x63, 0x63, 0x4B, 0x2B, 0x65, 0x66, 0x72, 0x43, 0x68, 0x32, 0x67, 0x64, 0x43, 0x2F, 0x31, 0x63, 0x61, 0x63, 0x77, 0x47, 0x30, 0x4A, 0x70, 0x39, 0x56, 0x4A, 0x6B, 0x71, 0x79, 0x54, 0x6B, 0x61, 0x47, 0x61, 0x39, 0x4C, 0x4B, ++ 0x6B, 0x50, 0x7A, 0x59, 0x31, 0x31, 0x61, 0x57, 0x4F, 0x49, 0x76, 0x34, 0x78, 0x33, 0x6B, 0x71, 0x64, 0x62, 0x51, 0x43, 0x74, 0x43, 0x65, 0x76, 0x39, 0x65, 0x42, 0x43, 0x66, 0x48, 0x4A, 0x78, 0x79, 0x59, 0x4E, 0x0A, 0x72, 0x4A, 0x67, 0x57, ++ 0x56, 0x71, 0x41, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x42, 0x75, 0x79, 0x70, 0x61, 0x73, 0x73, 0x20, ++ 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, ++ 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x57, 0x54, 0x43, 0x43, 0x41, 0x30, 0x47, 0x67, ++ 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x42, 0x41, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x42, 0x4F, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, ++ 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x4F, 0x54, 0x7A, 0x45, 0x64, 0x4D, 0x42, 0x73, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x55, 0x0A, 0x51, 0x6E, 0x56, 0x35, 0x63, 0x47, 0x46, 0x7A, 0x63, 0x79, 0x42, 0x42, 0x55, 0x79, 0x30, ++ 0x35, 0x4F, 0x44, 0x4D, 0x78, 0x4E, 0x6A, 0x4D, 0x7A, 0x4D, 0x6A, 0x63, 0x78, 0x49, 0x44, 0x41, 0x65, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x46, 0x30, 0x4A, 0x31, 0x65, 0x58, 0x42, 0x68, 0x63, 0x33, 0x4D, 0x67, 0x51, 0x32, 0x78, ++ 0x68, 0x63, 0x33, 0x4D, 0x67, 0x4D, 0x79, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x4D, 0x42, 0x34, 0x58, 0x0A, 0x44, 0x54, 0x45, 0x77, 0x4D, 0x54, 0x41, 0x79, 0x4E, 0x6A, 0x41, 0x34, 0x4D, 0x6A, 0x67, 0x31, 0x4F, 0x46, ++ 0x6F, 0x58, 0x44, 0x54, 0x51, 0x77, 0x4D, 0x54, 0x41, 0x79, 0x4E, 0x6A, 0x41, 0x34, 0x4D, 0x6A, 0x67, 0x31, 0x4F, 0x46, 0x6F, 0x77, 0x54, 0x6A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x54, 0x6B, ++ 0x38, 0x78, 0x48, 0x54, 0x41, 0x62, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x46, 0x45, 0x4A, 0x31, 0x0A, 0x65, 0x58, 0x42, 0x68, 0x63, 0x33, 0x4D, 0x67, 0x51, 0x56, 0x4D, 0x74, 0x4F, 0x54, 0x67, 0x7A, 0x4D, 0x54, 0x59, 0x7A, 0x4D, ++ 0x7A, 0x49, 0x33, 0x4D, 0x53, 0x41, 0x77, 0x48, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x42, 0x64, 0x43, 0x64, 0x58, 0x6C, 0x77, 0x59, 0x58, 0x4E, 0x7A, 0x49, 0x45, 0x4E, 0x73, 0x59, 0x58, 0x4E, 0x7A, 0x49, 0x44, 0x4D, 0x67, 0x55, ++ 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x54, 0x43, 0x43, 0x41, 0x69, 0x49, 0x77, 0x0A, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x50, ++ 0x41, 0x44, 0x43, 0x43, 0x41, 0x67, 0x6F, 0x43, 0x67, 0x67, 0x49, 0x42, 0x41, 0x4B, 0x58, 0x61, 0x43, 0x70, 0x55, 0x57, 0x55, 0x4F, 0x4F, 0x56, 0x38, 0x6C, 0x36, 0x64, 0x64, 0x6A, 0x45, 0x47, 0x4D, 0x6E, 0x71, 0x62, 0x38, 0x52, 0x42, 0x32, ++ 0x75, 0x41, 0x43, 0x61, 0x74, 0x56, 0x49, 0x32, 0x7A, 0x53, 0x52, 0x48, 0x0A, 0x73, 0x4A, 0x38, 0x59, 0x5A, 0x4C, 0x79, 0x61, 0x39, 0x76, 0x72, 0x56, 0x65, 0x64, 0x69, 0x51, 0x59, 0x6B, 0x77, 0x69, 0x4C, 0x39, 0x34, 0x34, 0x50, 0x64, 0x62, ++ 0x67, 0x71, 0x4F, 0x6B, 0x63, 0x4C, 0x4E, 0x74, 0x34, 0x45, 0x65, 0x6D, 0x4F, 0x61, 0x46, 0x45, 0x56, 0x63, 0x73, 0x66, 0x7A, 0x4D, 0x34, 0x66, 0x6B, 0x6F, 0x46, 0x30, 0x4C, 0x58, 0x4F, 0x42, 0x58, 0x42, 0x79, 0x6F, 0x77, 0x39, 0x63, 0x33, ++ 0x45, 0x4E, 0x33, 0x63, 0x6F, 0x54, 0x52, 0x69, 0x52, 0x0A, 0x35, 0x72, 0x2F, 0x56, 0x55, 0x76, 0x31, 0x78, 0x4C, 0x58, 0x41, 0x2B, 0x35, 0x38, 0x62, 0x45, 0x69, 0x75, 0x50, 0x77, 0x4B, 0x41, 0x76, 0x30, 0x64, 0x70, 0x69, 0x68, 0x69, 0x34, ++ 0x64, 0x56, 0x73, 0x6A, 0x6F, 0x54, 0x2F, 0x4C, 0x63, 0x2B, 0x4A, 0x7A, 0x65, 0x4F, 0x49, 0x75, 0x4F, 0x6F, 0x54, 0x79, 0x72, 0x76, 0x59, 0x4C, 0x73, 0x39, 0x74, 0x7A, 0x6E, 0x44, 0x44, 0x67, 0x46, 0x48, 0x6D, 0x56, 0x30, 0x53, 0x54, 0x39, ++ 0x74, 0x44, 0x2B, 0x6C, 0x65, 0x68, 0x0A, 0x37, 0x66, 0x6D, 0x64, 0x76, 0x68, 0x46, 0x48, 0x4A, 0x6C, 0x73, 0x54, 0x6D, 0x4B, 0x74, 0x64, 0x46, 0x6F, 0x71, 0x77, 0x4E, 0x78, 0x78, 0x58, 0x6E, 0x55, 0x58, 0x2F, 0x69, 0x4A, 0x59, 0x32, 0x76, ++ 0x37, 0x76, 0x4B, 0x42, 0x33, 0x74, 0x76, 0x68, 0x32, 0x50, 0x58, 0x30, 0x44, 0x4A, 0x71, 0x31, 0x6C, 0x31, 0x73, 0x44, 0x50, 0x47, 0x7A, 0x62, 0x6A, 0x6E, 0x69, 0x61, 0x7A, 0x45, 0x75, 0x4F, 0x51, 0x41, 0x6E, 0x46, 0x4E, 0x34, 0x34, 0x77, ++ 0x4F, 0x77, 0x5A, 0x0A, 0x5A, 0x6F, 0x59, 0x53, 0x36, 0x4A, 0x31, 0x79, 0x46, 0x68, 0x4E, 0x6B, 0x55, 0x73, 0x65, 0x70, 0x4E, 0x78, 0x7A, 0x39, 0x67, 0x6A, 0x44, 0x74, 0x68, 0x42, 0x67, 0x64, 0x39, 0x4B, 0x35, 0x63, 0x2F, 0x33, 0x41, 0x54, ++ 0x41, 0x4F, 0x75, 0x78, 0x39, 0x54, 0x4E, 0x36, 0x53, 0x39, 0x5A, 0x56, 0x2B, 0x41, 0x57, 0x4E, 0x53, 0x32, 0x6D, 0x77, 0x39, 0x62, 0x4D, 0x6F, 0x4E, 0x6C, 0x77, 0x55, 0x78, 0x46, 0x46, 0x7A, 0x54, 0x57, 0x73, 0x4C, 0x38, 0x54, 0x51, 0x48, ++ 0x0A, 0x32, 0x78, 0x63, 0x35, 0x31, 0x39, 0x77, 0x6F, 0x65, 0x32, 0x76, 0x31, 0x6E, 0x2F, 0x4D, 0x75, 0x77, 0x55, 0x38, 0x58, 0x4B, 0x68, 0x44, 0x7A, 0x7A, 0x4D, 0x72, 0x6F, 0x36, 0x2F, 0x31, 0x72, 0x71, 0x79, 0x36, 0x61, 0x6E, 0x79, 0x32, ++ 0x43, 0x62, 0x67, 0x54, 0x55, 0x55, 0x67, 0x47, 0x54, 0x4C, 0x54, 0x32, 0x47, 0x2F, 0x48, 0x37, 0x38, 0x33, 0x2B, 0x39, 0x43, 0x48, 0x61, 0x5A, 0x72, 0x37, 0x37, 0x6B, 0x67, 0x78, 0x76, 0x65, 0x39, 0x6F, 0x4B, 0x65, 0x56, 0x0A, 0x2F, 0x61, ++ 0x66, 0x6D, 0x69, 0x53, 0x54, 0x59, 0x7A, 0x49, 0x77, 0x30, 0x62, 0x4F, 0x49, 0x6A, 0x4C, 0x39, 0x6B, 0x53, 0x47, 0x69, 0x47, 0x35, 0x56, 0x5A, 0x46, 0x76, 0x43, 0x35, 0x46, 0x35, 0x47, 0x51, 0x79, 0x74, 0x51, 0x49, 0x67, 0x4C, 0x63, 0x4F, ++ 0x4A, 0x36, 0x30, 0x67, 0x37, 0x59, 0x61, 0x45, 0x69, 0x37, 0x67, 0x68, 0x4D, 0x35, 0x45, 0x46, 0x6A, 0x70, 0x32, 0x43, 0x6F, 0x48, 0x78, 0x68, 0x4C, 0x62, 0x57, 0x4E, 0x76, 0x53, 0x4F, 0x31, 0x55, 0x51, 0x0A, 0x52, 0x77, 0x55, 0x56, 0x5A, ++ 0x32, 0x4A, 0x2B, 0x47, 0x47, 0x4F, 0x6D, 0x52, 0x6A, 0x38, 0x4A, 0x44, 0x6C, 0x51, 0x79, 0x58, 0x72, 0x38, 0x4E, 0x59, 0x6E, 0x6F, 0x6E, 0x37, 0x34, 0x44, 0x6F, 0x32, 0x39, 0x6C, 0x4C, 0x42, 0x6C, 0x6F, 0x33, 0x57, 0x69, 0x58, 0x51, 0x43, ++ 0x42, 0x4A, 0x33, 0x31, 0x47, 0x38, 0x4A, 0x55, 0x4A, 0x63, 0x39, 0x79, 0x42, 0x33, 0x44, 0x33, 0x34, 0x78, 0x46, 0x4D, 0x46, 0x62, 0x47, 0x30, 0x32, 0x53, 0x72, 0x5A, 0x76, 0x50, 0x41, 0x0A, 0x58, 0x70, 0x61, 0x63, 0x77, 0x38, 0x54, 0x76, ++ 0x77, 0x33, 0x78, 0x72, 0x69, 0x7A, 0x70, 0x35, 0x66, 0x37, 0x4E, 0x4A, 0x7A, 0x7A, 0x33, 0x69, 0x69, 0x5A, 0x2B, 0x67, 0x4D, 0x45, 0x75, 0x46, 0x75, 0x5A, 0x79, 0x55, 0x4A, 0x48, 0x6D, 0x50, 0x66, 0x57, 0x75, 0x70, 0x52, 0x57, 0x67, 0x50, ++ 0x4B, 0x39, 0x44, 0x78, 0x32, 0x68, 0x7A, 0x4C, 0x61, 0x62, 0x6A, 0x4B, 0x53, 0x57, 0x4A, 0x74, 0x79, 0x4E, 0x42, 0x6A, 0x59, 0x74, 0x31, 0x67, 0x44, 0x31, 0x69, 0x71, 0x0A, 0x6A, 0x36, 0x47, 0x38, 0x42, 0x61, 0x56, 0x6D, 0x6F, 0x73, 0x38, ++ 0x62, 0x64, 0x72, 0x4B, 0x45, 0x5A, 0x4C, 0x46, 0x4D, 0x4F, 0x56, 0x4C, 0x41, 0x4D, 0x4C, 0x72, 0x77, 0x6A, 0x45, 0x73, 0x43, 0x73, 0x4C, 0x61, 0x33, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, 0x51, 0x6A, 0x42, 0x41, 0x4D, 0x41, 0x38, ++ 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x48, 0x51, 0x59, 0x44, 0x0A, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x46, 0x45, 0x65, 0x34, 0x7A, 0x66, ++ 0x2F, 0x6C, 0x62, 0x2B, 0x37, 0x34, 0x73, 0x75, 0x77, 0x76, 0x54, 0x67, 0x37, 0x35, 0x4A, 0x62, 0x43, 0x4F, 0x50, 0x47, 0x76, 0x44, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, ++ 0x49, 0x42, 0x42, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x0A, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x67, 0x45, 0x41, 0x41, 0x43, 0x41, 0x6A, 0x51, 0x54, 0x55, 0x45, 0x6B, ++ 0x4D, 0x4A, 0x41, 0x59, 0x6D, 0x44, 0x76, 0x34, 0x6A, 0x56, 0x4D, 0x31, 0x7A, 0x2B, 0x73, 0x34, 0x6A, 0x53, 0x51, 0x75, 0x4B, 0x46, 0x76, 0x64, 0x76, 0x6F, 0x57, 0x46, 0x71, 0x52, 0x49, 0x4E, 0x79, 0x7A, 0x70, 0x6B, 0x4D, 0x4C, 0x79, 0x50, ++ 0x50, 0x67, 0x4B, 0x6E, 0x39, 0x69, 0x42, 0x35, 0x62, 0x74, 0x62, 0x32, 0x69, 0x55, 0x73, 0x70, 0x4B, 0x64, 0x56, 0x0A, 0x63, 0x53, 0x51, 0x79, 0x39, 0x73, 0x67, 0x4C, 0x38, 0x72, 0x78, 0x71, 0x2B, 0x4A, 0x4F, 0x73, 0x73, 0x67, 0x66, 0x43, ++ 0x58, 0x35, 0x2F, 0x62, 0x7A, 0x4D, 0x69, 0x4B, 0x71, 0x72, 0x35, 0x71, 0x62, 0x2B, 0x46, 0x4A, 0x45, 0x4D, 0x77, 0x78, 0x31, 0x34, 0x43, 0x37, 0x75, 0x38, 0x6A, 0x59, 0x6F, 0x67, 0x35, 0x6B, 0x56, 0x2B, 0x71, 0x69, 0x39, 0x63, 0x4B, 0x70, ++ 0x4D, 0x52, 0x58, 0x53, 0x49, 0x47, 0x72, 0x73, 0x2F, 0x43, 0x49, 0x42, 0x4B, 0x4D, 0x2B, 0x47, 0x0A, 0x75, 0x49, 0x41, 0x65, 0x71, 0x63, 0x77, 0x52, 0x70, 0x54, 0x7A, 0x79, 0x46, 0x72, 0x4E, 0x48, 0x6E, 0x66, 0x7A, 0x53, 0x67, 0x43, 0x48, ++ 0x45, 0x79, 0x39, 0x42, 0x48, 0x63, 0x45, 0x47, 0x68, 0x79, 0x6F, 0x4D, 0x5A, 0x43, 0x43, 0x78, 0x74, 0x38, 0x6C, 0x31, 0x33, 0x6E, 0x49, 0x6F, 0x55, 0x45, 0x39, 0x51, 0x32, 0x48, 0x4A, 0x4C, 0x77, 0x35, 0x51, 0x59, 0x33, 0x33, 0x4B, 0x62, ++ 0x6D, 0x6B, 0x4A, 0x73, 0x34, 0x6A, 0x31, 0x78, 0x72, 0x47, 0x30, 0x61, 0x47, 0x0A, 0x51, 0x30, 0x4A, 0x66, 0x50, 0x67, 0x45, 0x48, 0x55, 0x31, 0x52, 0x64, 0x5A, 0x58, 0x33, 0x33, 0x69, 0x6E, 0x4F, 0x68, 0x6D, 0x6C, 0x52, 0x61, 0x48, 0x79, ++ 0x6C, 0x44, 0x46, 0x43, 0x66, 0x43, 0x68, 0x51, 0x2B, 0x31, 0x69, 0x48, 0x73, 0x61, 0x4F, 0x35, 0x53, 0x33, 0x48, 0x57, 0x43, 0x6E, 0x74, 0x5A, 0x7A, 0x6E, 0x4B, 0x57, 0x6C, 0x58, 0x57, 0x70, 0x75, 0x54, 0x65, 0x6B, 0x4D, 0x77, 0x47, 0x77, ++ 0x50, 0x58, 0x59, 0x73, 0x68, 0x41, 0x70, 0x71, 0x72, 0x38, 0x0A, 0x5A, 0x4F, 0x52, 0x4B, 0x31, 0x35, 0x46, 0x54, 0x41, 0x61, 0x67, 0x67, 0x69, 0x47, 0x36, 0x63, 0x58, 0x30, 0x53, 0x35, 0x79, 0x32, 0x43, 0x42, 0x4E, 0x4F, 0x78, 0x76, 0x30, ++ 0x33, 0x33, 0x61, 0x53, 0x46, 0x2F, 0x72, 0x74, 0x4A, 0x43, 0x38, 0x4C, 0x61, 0x6B, 0x63, 0x43, 0x36, 0x77, 0x63, 0x31, 0x61, 0x4A, 0x6F, 0x49, 0x49, 0x41, 0x45, 0x31, 0x76, 0x79, 0x78, 0x6A, 0x79, 0x2B, 0x37, 0x53, 0x6A, 0x45, 0x4E, 0x53, ++ 0x6F, 0x59, 0x63, 0x36, 0x2B, 0x49, 0x32, 0x0A, 0x4B, 0x53, 0x62, 0x31, 0x32, 0x74, 0x6A, 0x45, 0x38, 0x6E, 0x56, 0x68, 0x7A, 0x33, 0x36, 0x75, 0x64, 0x6D, 0x4E, 0x4B, 0x65, 0x6B, 0x42, 0x6C, 0x6B, 0x34, 0x66, 0x34, 0x48, 0x6F, 0x43, 0x4D, ++ 0x68, 0x75, 0x57, 0x47, 0x31, 0x6F, 0x38, 0x4F, 0x2F, 0x46, 0x4D, 0x73, 0x59, 0x4F, 0x67, 0x57, 0x59, 0x52, 0x71, 0x69, 0x50, 0x6B, 0x4E, 0x37, 0x7A, 0x54, 0x6C, 0x67, 0x56, 0x47, 0x72, 0x31, 0x38, 0x6F, 0x6B, 0x6D, 0x41, 0x57, 0x69, 0x44, ++ 0x53, 0x4B, 0x49, 0x7A, 0x0A, 0x36, 0x4D, 0x6B, 0x45, 0x6B, 0x62, 0x49, 0x52, 0x4E, 0x42, 0x45, 0x2B, 0x36, 0x74, 0x42, 0x44, 0x47, 0x52, 0x38, 0x44, 0x6B, 0x35, 0x41, 0x4D, 0x2F, 0x31, 0x45, 0x39, 0x56, 0x2F, 0x52, 0x42, 0x62, 0x75, 0x48, ++ 0x4C, 0x6F, 0x4C, 0x37, 0x72, 0x79, 0x57, 0x50, 0x4E, 0x62, 0x63, 0x7A, 0x6B, 0x2B, 0x44, 0x61, 0x71, 0x61, 0x4A, 0x33, 0x74, 0x76, 0x56, 0x32, 0x58, 0x63, 0x45, 0x51, 0x4E, 0x74, 0x67, 0x34, 0x31, 0x33, 0x4F, 0x45, 0x4D, 0x58, 0x62, 0x75, ++ 0x67, 0x0A, 0x55, 0x5A, 0x54, 0x4C, 0x66, 0x68, 0x62, 0x72, 0x45, 0x53, 0x2B, 0x6A, 0x6B, 0x6B, 0x58, 0x49, 0x54, 0x48, 0x48, 0x5A, 0x76, 0x4D, 0x6D, 0x5A, 0x55, 0x6C, 0x64, 0x47, 0x4C, 0x31, 0x44, 0x50, 0x76, 0x54, 0x56, 0x70, 0x39, 0x44, ++ 0x30, 0x56, 0x7A, 0x67, 0x61, 0x6C, 0x4C, 0x41, 0x38, 0x2B, 0x39, 0x6F, 0x47, 0x36, 0x6C, 0x4C, 0x76, 0x44, 0x75, 0x37, 0x39, 0x6C, 0x65, 0x4E, 0x4B, 0x47, 0x65, 0x66, 0x39, 0x4A, 0x4F, 0x78, 0x71, 0x44, 0x44, 0x50, 0x44, 0x65, 0x0A, 0x65, ++ 0x4F, 0x7A, 0x49, 0x38, 0x6B, 0x31, 0x4D, 0x47, 0x74, 0x36, 0x43, 0x4B, 0x66, 0x6A, 0x42, 0x57, 0x74, 0x72, 0x74, 0x37, 0x75, 0x59, 0x6E, 0x58, 0x75, 0x68, 0x46, 0x30, 0x4A, 0x30, 0x63, 0x55, 0x61, 0x68, 0x6F, 0x71, 0x30, 0x54, 0x6A, 0x30, ++ 0x49, 0x74, 0x71, 0x34, 0x2F, 0x67, 0x37, 0x75, 0x39, 0x78, 0x4E, 0x31, 0x32, 0x54, 0x79, 0x55, 0x62, 0x37, 0x6D, 0x71, 0x71, 0x74, 0x61, 0x36, 0x54, 0x48, 0x75, 0x42, 0x72, 0x78, 0x7A, 0x76, 0x78, 0x4E, 0x69, 0x0A, 0x43, 0x70, 0x2F, 0x48, ++ 0x75, 0x5A, 0x63, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x54, 0x2D, 0x54, 0x65, 0x6C, 0x65, 0x53, 0x65, ++ 0x63, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, ++ 0x49, 0x44, 0x77, 0x7A, 0x43, 0x43, 0x41, 0x71, 0x75, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x42, 0x41, 0x54, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, ++ 0x43, 0x42, 0x67, 0x6A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x52, 0x45, 0x55, 0x78, 0x4B, 0x7A, 0x41, 0x70, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x0A, 0x49, 0x6C, 0x51, 0x74, 0x55, ++ 0x33, 0x6C, 0x7A, 0x64, 0x47, 0x56, 0x74, 0x63, 0x79, 0x42, 0x46, 0x62, 0x6E, 0x52, 0x6C, 0x63, 0x6E, 0x42, 0x79, 0x61, 0x58, 0x4E, 0x6C, 0x49, 0x46, 0x4E, 0x6C, 0x63, 0x6E, 0x5A, 0x70, 0x59, 0x32, 0x56, 0x7A, 0x49, 0x45, 0x64, 0x74, 0x59, ++ 0x6B, 0x67, 0x78, 0x48, 0x7A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x73, 0x4D, 0x46, 0x6C, 0x51, 0x74, 0x55, 0x33, 0x6C, 0x7A, 0x64, 0x47, 0x56, 0x74, 0x63, 0x79, 0x42, 0x55, 0x0A, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x43, 0x42, 0x44, ++ 0x5A, 0x57, 0x35, 0x30, 0x5A, 0x58, 0x49, 0x78, 0x4A, 0x54, 0x41, 0x6A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x48, 0x46, 0x51, 0x74, 0x56, 0x47, 0x56, 0x73, 0x5A, 0x56, 0x4E, 0x6C, 0x59, 0x79, 0x42, 0x48, 0x62, 0x47, 0x39, 0x69, ++ 0x59, 0x57, 0x78, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x73, 0x59, 0x58, 0x4E, 0x7A, 0x49, 0x44, 0x4D, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x44, 0x67, 0x78, 0x0A, 0x4D, 0x44, 0x41, 0x78, 0x4D, 0x54, 0x41, 0x79, 0x4F, 0x54, 0x55, ++ 0x32, 0x57, 0x68, 0x63, 0x4E, 0x4D, 0x7A, 0x4D, 0x78, 0x4D, 0x44, 0x41, 0x78, 0x4D, 0x6A, 0x4D, 0x31, 0x4F, 0x54, 0x55, 0x35, 0x57, 0x6A, 0x43, 0x42, 0x67, 0x6A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, ++ 0x43, 0x52, 0x45, 0x55, 0x78, 0x4B, 0x7A, 0x41, 0x70, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x49, 0x6C, 0x51, 0x74, 0x55, 0x33, 0x6C, 0x7A, 0x0A, 0x64, 0x47, 0x56, 0x74, 0x63, 0x79, 0x42, 0x46, 0x62, 0x6E, 0x52, 0x6C, 0x63, 0x6E, ++ 0x42, 0x79, 0x61, 0x58, 0x4E, 0x6C, 0x49, 0x46, 0x4E, 0x6C, 0x63, 0x6E, 0x5A, 0x70, 0x59, 0x32, 0x56, 0x7A, 0x49, 0x45, 0x64, 0x74, 0x59, 0x6B, 0x67, 0x78, 0x48, 0x7A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x73, 0x4D, 0x46, 0x6C, ++ 0x51, 0x74, 0x55, 0x33, 0x6C, 0x7A, 0x64, 0x47, 0x56, 0x74, 0x63, 0x79, 0x42, 0x55, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x43, 0x42, 0x44, 0x0A, 0x5A, 0x57, 0x35, 0x30, 0x5A, 0x58, 0x49, 0x78, 0x4A, 0x54, 0x41, 0x6A, 0x42, 0x67, 0x4E, 0x56, 0x42, ++ 0x41, 0x4D, 0x4D, 0x48, 0x46, 0x51, 0x74, 0x56, 0x47, 0x56, 0x73, 0x5A, 0x56, 0x4E, 0x6C, 0x59, 0x79, 0x42, 0x48, 0x62, 0x47, 0x39, 0x69, 0x59, 0x57, 0x78, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x73, 0x59, 0x58, 0x4E, 0x7A, 0x49, ++ 0x44, 0x4D, 0x77, 0x67, 0x67, 0x45, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x0A, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x45, 0x4B, ++ 0x41, 0x6F, 0x49, 0x42, 0x41, 0x51, 0x43, 0x39, 0x64, 0x5A, 0x50, 0x77, 0x59, 0x69, 0x4A, 0x76, 0x4A, 0x4B, 0x37, 0x67, 0x65, 0x6E, 0x61, 0x73, 0x66, 0x62, 0x33, 0x5A, 0x4A, 0x4E, 0x57, 0x34, 0x74, 0x2F, 0x7A, 0x4E, 0x38, 0x45, 0x4C, 0x67, ++ 0x36, 0x33, 0x69, 0x49, 0x56, 0x6C, 0x36, 0x62, 0x6D, 0x6C, 0x51, 0x64, 0x54, 0x51, 0x79, 0x4B, 0x0A, 0x39, 0x74, 0x50, 0x50, 0x63, 0x50, 0x52, 0x53, 0x74, 0x64, 0x69, 0x54, 0x42, 0x4F, 0x4E, 0x47, 0x68, 0x6E, 0x46, 0x42, 0x53, 0x69, 0x76, ++ 0x77, 0x4B, 0x69, 0x78, 0x56, 0x41, 0x39, 0x5A, 0x49, 0x77, 0x2B, 0x41, 0x35, 0x4F, 0x4F, 0x33, 0x79, 0x58, 0x44, 0x77, 0x2F, 0x52, 0x4C, 0x79, 0x54, 0x50, 0x57, 0x47, 0x72, 0x54, 0x73, 0x30, 0x4E, 0x76, 0x76, 0x41, 0x67, 0x4A, 0x31, 0x67, ++ 0x4F, 0x52, 0x48, 0x38, 0x45, 0x47, 0x6F, 0x65, 0x6C, 0x31, 0x35, 0x59, 0x55, 0x0A, 0x4E, 0x70, 0x44, 0x51, 0x53, 0x58, 0x75, 0x68, 0x64, 0x66, 0x73, 0x61, 0x61, 0x33, 0x4F, 0x78, 0x2B, 0x4D, 0x36, 0x70, 0x43, 0x53, 0x7A, 0x79, 0x55, 0x39, ++ 0x58, 0x44, 0x46, 0x45, 0x53, 0x34, 0x68, 0x71, 0x58, 0x32, 0x69, 0x79, 0x73, 0x35, 0x32, 0x71, 0x4D, 0x7A, 0x56, 0x4E, 0x6E, 0x36, 0x63, 0x68, 0x72, 0x33, 0x49, 0x68, 0x55, 0x63, 0x69, 0x4A, 0x46, 0x72, 0x66, 0x32, 0x62, 0x6C, 0x77, 0x32, ++ 0x71, 0x41, 0x73, 0x43, 0x54, 0x7A, 0x33, 0x34, 0x5A, 0x46, 0x0A, 0x69, 0x50, 0x30, 0x5A, 0x66, 0x33, 0x57, 0x48, 0x48, 0x78, 0x2B, 0x78, 0x47, 0x77, 0x70, 0x7A, 0x4A, 0x46, 0x75, 0x35, 0x5A, 0x65, 0x41, 0x73, 0x56, 0x4D, 0x68, 0x67, 0x30, ++ 0x32, 0x59, 0x58, 0x50, 0x2B, 0x48, 0x4D, 0x56, 0x44, 0x4E, 0x7A, 0x6B, 0x51, 0x49, 0x36, 0x70, 0x6E, 0x39, 0x37, 0x64, 0x6A, 0x6D, 0x69, 0x48, 0x35, 0x61, 0x32, 0x4F, 0x4B, 0x36, 0x31, 0x79, 0x4A, 0x4E, 0x30, 0x48, 0x5A, 0x36, 0x35, 0x74, ++ 0x4F, 0x56, 0x67, 0x6E, 0x53, 0x39, 0x57, 0x0A, 0x30, 0x65, 0x44, 0x72, 0x58, 0x6C, 0x74, 0x4D, 0x45, 0x6E, 0x41, 0x4D, 0x62, 0x45, 0x51, 0x67, 0x71, 0x78, 0x48, 0x59, 0x39, 0x42, 0x6E, 0x32, 0x30, 0x70, 0x78, 0x53, 0x4E, 0x2B, 0x66, 0x36, ++ 0x74, 0x73, 0x49, 0x78, 0x4F, 0x30, 0x72, 0x55, 0x46, 0x4A, 0x6D, 0x74, 0x78, 0x78, 0x72, 0x31, 0x58, 0x56, 0x2F, 0x36, 0x42, 0x37, 0x68, 0x38, 0x44, 0x52, 0x2F, 0x57, 0x67, 0x78, 0x36, 0x7A, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, ++ 0x51, 0x6A, 0x42, 0x41, 0x0A, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, ++ 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x53, 0x31, 0x41, 0x2F, 0x64, 0x32, 0x4F, 0x32, 0x47, 0x43, 0x61, 0x68, 0x4B, 0x71, 0x47, 0x46, 0x50, ++ 0x72, 0x0A, 0x41, 0x79, 0x47, 0x55, 0x76, 0x2F, 0x37, 0x4F, 0x79, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x51, 0x45, 0x41, 0x56, 0x6A, ++ 0x33, 0x76, 0x6C, 0x4E, 0x57, 0x39, 0x32, 0x6E, 0x4F, 0x79, 0x57, 0x4C, 0x36, 0x75, 0x6B, 0x4B, 0x32, 0x59, 0x4A, 0x35, 0x66, 0x2B, 0x41, 0x62, 0x47, 0x77, 0x55, 0x67, 0x43, 0x34, 0x54, 0x65, 0x51, 0x62, 0x49, 0x58, 0x51, 0x62, 0x0A, 0x66, ++ 0x73, 0x44, 0x75, 0x58, 0x6D, 0x6B, 0x71, 0x4A, 0x61, 0x39, 0x63, 0x31, 0x68, 0x33, 0x61, 0x30, 0x6E, 0x6E, 0x4A, 0x38, 0x35, 0x63, 0x70, 0x34, 0x49, 0x61, 0x48, 0x33, 0x67, 0x52, 0x5A, 0x44, 0x2F, 0x46, 0x5A, 0x31, 0x47, 0x53, 0x46, 0x53, ++ 0x35, 0x6D, 0x76, 0x4A, 0x51, 0x51, 0x65, 0x79, 0x55, 0x61, 0x70, 0x6C, 0x39, 0x36, 0x43, 0x73, 0x68, 0x74, 0x77, 0x6E, 0x35, 0x7A, 0x32, 0x72, 0x33, 0x45, 0x78, 0x33, 0x58, 0x73, 0x46, 0x70, 0x53, 0x7A, 0x54, 0x0A, 0x75, 0x63, 0x70, 0x48, ++ 0x39, 0x73, 0x72, 0x79, 0x39, 0x75, 0x65, 0x74, 0x75, 0x55, 0x67, 0x2F, 0x76, 0x42, 0x61, 0x33, 0x77, 0x57, 0x33, 0x30, 0x36, 0x67, 0x6D, 0x76, 0x37, 0x50, 0x4F, 0x31, 0x35, 0x77, 0x57, 0x65, 0x70, 0x68, 0x36, 0x4B, 0x55, 0x31, 0x48, 0x57, ++ 0x6B, 0x34, 0x48, 0x4D, 0x64, 0x4A, 0x50, 0x32, 0x75, 0x64, 0x71, 0x6D, 0x4A, 0x51, 0x56, 0x30, 0x65, 0x56, 0x70, 0x2B, 0x51, 0x44, 0x36, 0x43, 0x53, 0x79, 0x59, 0x52, 0x4D, 0x47, 0x37, 0x68, 0x0A, 0x50, 0x30, 0x48, 0x48, 0x52, 0x77, 0x41, ++ 0x31, 0x31, 0x66, 0x58, 0x54, 0x39, 0x31, 0x51, 0x2B, 0x67, 0x54, 0x33, 0x61, 0x53, 0x57, 0x71, 0x61, 0x73, 0x2B, 0x38, 0x51, 0x50, 0x65, 0x62, 0x72, 0x62, 0x39, 0x48, 0x49, 0x49, 0x6B, 0x66, 0x4C, 0x7A, 0x4D, 0x38, 0x42, 0x4D, 0x5A, 0x4C, ++ 0x5A, 0x47, 0x4F, 0x4D, 0x69, 0x76, 0x67, 0x6B, 0x65, 0x47, 0x6A, 0x35, 0x61, 0x73, 0x75, 0x52, 0x72, 0x44, 0x46, 0x52, 0x36, 0x66, 0x55, 0x4E, 0x4F, 0x75, 0x49, 0x6D, 0x6C, 0x0A, 0x65, 0x39, 0x65, 0x69, 0x50, 0x5A, 0x61, 0x47, 0x7A, 0x50, ++ 0x49, 0x6D, 0x4E, 0x43, 0x31, 0x71, 0x6B, 0x70, 0x32, 0x61, 0x47, 0x74, 0x41, 0x77, 0x34, 0x6C, 0x31, 0x4F, 0x42, 0x4C, 0x42, 0x66, 0x69, 0x79, 0x42, 0x2B, 0x64, 0x38, 0x45, 0x39, 0x6C, 0x59, 0x4C, 0x52, 0x52, 0x70, 0x6F, 0x37, 0x50, 0x48, ++ 0x69, 0x34, 0x62, 0x36, 0x48, 0x51, 0x44, 0x57, 0x53, 0x69, 0x65, 0x42, 0x34, 0x70, 0x54, 0x70, 0x50, 0x44, 0x70, 0x46, 0x51, 0x55, 0x57, 0x77, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, ++ 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, ++ 0x32, 0x30, 0x30, 0x39, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x45, 0x4D, 0x7A, 0x43, 0x43, 0x41, 0x78, 0x75, 0x67, 0x41, 0x77, 0x49, 0x42, ++ 0x41, 0x67, 0x49, 0x44, 0x43, 0x59, 0x50, 0x7A, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43, 0x77, 0x55, 0x41, 0x4D, 0x45, 0x30, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, ++ 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x52, 0x46, 0x4D, 0x52, 0x55, 0x77, 0x45, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x0A, 0x44, 0x41, 0x78, 0x45, 0x4C, 0x56, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x49, 0x45, 0x64, 0x74, 0x59, 0x6B, 0x67, ++ 0x78, 0x4A, 0x7A, 0x41, 0x6C, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x48, 0x6B, 0x51, 0x74, 0x56, 0x46, 0x4A, 0x56, 0x55, 0x31, 0x51, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x62, 0x47, 0x46, 0x7A, 0x63, 0x79, 0x41, ++ 0x7A, 0x49, 0x45, 0x4E, 0x42, 0x49, 0x44, 0x49, 0x67, 0x4D, 0x6A, 0x41, 0x77, 0x4F, 0x54, 0x41, 0x65, 0x0A, 0x46, 0x77, 0x30, 0x77, 0x4F, 0x54, 0x45, 0x78, 0x4D, 0x44, 0x55, 0x77, 0x4F, 0x44, 0x4D, 0x31, 0x4E, 0x54, 0x68, 0x61, 0x46, 0x77, ++ 0x30, 0x79, 0x4F, 0x54, 0x45, 0x78, 0x4D, 0x44, 0x55, 0x77, 0x4F, 0x44, 0x4D, 0x31, 0x4E, 0x54, 0x68, 0x61, 0x4D, 0x45, 0x30, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x52, 0x46, 0x4D, 0x52, ++ 0x55, 0x77, 0x45, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x44, 0x41, 0x78, 0x45, 0x0A, 0x4C, 0x56, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x49, 0x45, 0x64, 0x74, 0x59, 0x6B, 0x67, 0x78, 0x4A, 0x7A, 0x41, 0x6C, 0x42, 0x67, 0x4E, 0x56, 0x42, ++ 0x41, 0x4D, 0x4D, 0x48, 0x6B, 0x51, 0x74, 0x56, 0x46, 0x4A, 0x56, 0x55, 0x31, 0x51, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x62, 0x47, 0x46, 0x7A, 0x63, 0x79, 0x41, 0x7A, 0x49, 0x45, 0x4E, 0x42, 0x49, 0x44, 0x49, 0x67, 0x4D, ++ 0x6A, 0x41, 0x77, 0x4F, 0x54, 0x43, 0x43, 0x41, 0x53, 0x49, 0x77, 0x0A, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x50, 0x41, 0x44, 0x43, 0x43, ++ 0x41, 0x51, 0x6F, 0x43, 0x67, 0x67, 0x45, 0x42, 0x41, 0x4E, 0x4F, 0x79, 0x53, 0x73, 0x39, 0x36, 0x52, 0x2B, 0x39, 0x31, 0x6D, 0x79, 0x50, 0x36, 0x4F, 0x69, 0x2F, 0x57, 0x55, 0x45, 0x57, 0x4A, 0x4E, 0x54, 0x72, 0x47, 0x61, 0x39, 0x76, 0x2B, ++ 0x32, 0x77, 0x42, 0x6F, 0x71, 0x4F, 0x41, 0x44, 0x0A, 0x45, 0x52, 0x30, 0x33, 0x55, 0x41, 0x69, 0x66, 0x54, 0x55, 0x70, 0x6F, 0x6C, 0x44, 0x57, 0x7A, 0x55, 0x39, 0x47, 0x55, 0x59, 0x36, 0x63, 0x67, 0x56, 0x71, 0x2F, 0x65, 0x55, 0x58, 0x6A, ++ 0x73, 0x4B, 0x6A, 0x33, 0x7A, 0x53, 0x45, 0x68, 0x51, 0x50, 0x67, 0x72, 0x66, 0x52, 0x6C, 0x57, 0x4C, 0x4A, 0x32, 0x33, 0x44, 0x45, 0x45, 0x30, 0x4E, 0x6B, 0x56, 0x4A, 0x44, 0x32, 0x49, 0x66, 0x67, 0x58, 0x55, 0x34, 0x32, 0x74, 0x53, 0x48, ++ 0x4B, 0x58, 0x7A, 0x6C, 0x41, 0x0A, 0x42, 0x46, 0x39, 0x62, 0x66, 0x73, 0x79, 0x6A, 0x78, 0x69, 0x75, 0x70, 0x51, 0x42, 0x37, 0x5A, 0x4E, 0x6F, 0x54, 0x57, 0x53, 0x50, 0x4F, 0x53, 0x48, 0x6A, 0x52, 0x47, 0x49, 0x43, 0x54, 0x42, 0x70, 0x46, ++ 0x47, 0x4F, 0x53, 0x68, 0x72, 0x76, 0x55, 0x44, 0x39, 0x70, 0x58, 0x52, 0x6C, 0x2F, 0x52, 0x63, 0x50, 0x48, 0x41, 0x59, 0x39, 0x52, 0x79, 0x53, 0x50, 0x6F, 0x63, 0x71, 0x36, 0x30, 0x76, 0x46, 0x59, 0x4A, 0x66, 0x78, 0x4C, 0x4C, 0x48, 0x4C, ++ 0x47, 0x76, 0x0A, 0x4B, 0x5A, 0x41, 0x4B, 0x79, 0x56, 0x58, 0x4D, 0x44, 0x39, 0x4F, 0x30, 0x47, 0x75, 0x31, 0x48, 0x4E, 0x56, 0x70, 0x4B, 0x37, 0x5A, 0x78, 0x7A, 0x42, 0x43, 0x48, 0x51, 0x71, 0x72, 0x30, 0x4D, 0x45, 0x37, 0x55, 0x41, 0x79, ++ 0x69, 0x5A, 0x73, 0x78, 0x47, 0x73, 0x4D, 0x6C, 0x46, 0x71, 0x56, 0x6C, 0x4E, 0x70, 0x51, 0x6D, 0x76, 0x48, 0x2F, 0x70, 0x53, 0x74, 0x6D, 0x4D, 0x61, 0x54, 0x4A, 0x4F, 0x4B, 0x44, 0x66, 0x48, 0x52, 0x2B, 0x34, 0x43, 0x53, 0x37, 0x7A, 0x0A, ++ 0x70, 0x2B, 0x68, 0x6E, 0x55, 0x71, 0x75, 0x56, 0x48, 0x2B, 0x42, 0x47, 0x50, 0x74, 0x69, 0x6B, 0x77, 0x38, 0x70, 0x61, 0x78, 0x54, 0x47, 0x41, 0x36, 0x45, 0x69, 0x61, 0x6E, 0x35, 0x52, 0x70, 0x2F, 0x68, 0x6E, 0x64, 0x32, 0x48, 0x4E, 0x38, ++ 0x67, 0x63, 0x71, 0x57, 0x33, 0x6F, 0x37, 0x74, 0x73, 0x7A, 0x49, 0x46, 0x5A, 0x59, 0x51, 0x30, 0x35, 0x75, 0x62, 0x39, 0x56, 0x78, 0x43, 0x31, 0x58, 0x33, 0x61, 0x2F, 0x4C, 0x37, 0x41, 0x51, 0x44, 0x63, 0x55, 0x43, 0x0A, 0x41, 0x77, 0x45, ++ 0x41, 0x41, 0x61, 0x4F, 0x43, 0x41, 0x52, 0x6F, 0x77, 0x67, 0x67, 0x45, 0x57, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x48, 0x51, 0x59, ++ 0x44, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x46, 0x50, 0x33, 0x61, 0x46, 0x4D, 0x53, 0x66, 0x4D, 0x4E, 0x34, 0x68, 0x76, 0x52, 0x35, 0x43, 0x4F, 0x66, 0x79, 0x72, 0x59, 0x79, 0x4E, 0x4A, 0x0A, 0x34, 0x50, 0x47, 0x45, 0x4D, 0x41, ++ 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6A, 0x43, 0x42, 0x30, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x66, 0x42, 0x49, 0x48, 0x4C, 0x4D, 0x49, 0x48, 0x49, 0x4D, 0x49, ++ 0x47, 0x41, 0x6F, 0x48, 0x36, 0x67, 0x66, 0x49, 0x5A, 0x36, 0x62, 0x47, 0x52, 0x68, 0x63, 0x44, 0x6F, 0x76, 0x4C, 0x32, 0x52, 0x70, 0x63, 0x6D, 0x56, 0x6A, 0x64, 0x47, 0x39, 0x79, 0x0A, 0x65, 0x53, 0x35, 0x6B, 0x4C, 0x58, 0x52, 0x79, 0x64, ++ 0x58, 0x4E, 0x30, 0x4C, 0x6D, 0x35, 0x6C, 0x64, 0x43, 0x39, 0x44, 0x54, 0x6A, 0x31, 0x45, 0x4C, 0x56, 0x52, 0x53, 0x56, 0x56, 0x4E, 0x55, 0x4A, 0x54, 0x49, 0x77, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x55, 0x79, 0x4D, 0x45, 0x4E, 0x73, 0x59, ++ 0x58, 0x4E, 0x7A, 0x4A, 0x54, 0x49, 0x77, 0x4D, 0x79, 0x55, 0x79, 0x4D, 0x45, 0x4E, 0x42, 0x4A, 0x54, 0x49, 0x77, 0x4D, 0x69, 0x55, 0x79, 0x4D, 0x44, 0x49, 0x77, 0x0A, 0x4D, 0x44, 0x6B, 0x73, 0x54, 0x7A, 0x31, 0x45, 0x4C, 0x56, 0x52, 0x79, ++ 0x64, 0x58, 0x4E, 0x30, 0x4A, 0x54, 0x49, 0x77, 0x52, 0x32, 0x31, 0x69, 0x53, 0x43, 0x78, 0x44, 0x50, 0x55, 0x52, 0x46, 0x50, 0x32, 0x4E, 0x6C, 0x63, 0x6E, 0x52, 0x70, 0x5A, 0x6D, 0x6C, 0x6A, 0x59, 0x58, 0x52, 0x6C, 0x63, 0x6D, 0x56, 0x32, ++ 0x62, 0x32, 0x4E, 0x68, 0x64, 0x47, 0x6C, 0x76, 0x62, 0x6D, 0x78, 0x70, 0x63, 0x33, 0x51, 0x77, 0x51, 0x36, 0x42, 0x42, 0x6F, 0x44, 0x2B, 0x47, 0x0A, 0x50, 0x57, 0x68, 0x30, 0x64, 0x48, 0x41, 0x36, 0x4C, 0x79, 0x39, 0x33, 0x64, 0x33, 0x63, ++ 0x75, 0x5A, 0x43, 0x31, 0x30, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x43, 0x35, 0x75, 0x5A, 0x58, 0x51, 0x76, 0x59, 0x33, 0x4A, 0x73, 0x4C, 0x32, 0x51, 0x74, 0x64, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x52, 0x66, 0x63, 0x6D, 0x39, 0x76, 0x64, 0x46, 0x39, ++ 0x6A, 0x62, 0x47, 0x46, 0x7A, 0x63, 0x31, 0x38, 0x7A, 0x58, 0x32, 0x4E, 0x68, 0x58, 0x7A, 0x4A, 0x66, 0x4D, 0x6A, 0x41, 0x77, 0x0A, 0x4F, 0x53, 0x35, 0x6A, 0x63, 0x6D, 0x77, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, ++ 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x42, 0x41, 0x48, 0x2B, 0x58, 0x32, 0x7A, 0x44, 0x49, 0x33, 0x36, 0x53, 0x63, 0x66, 0x53, 0x46, 0x36, 0x67, 0x48, 0x44, 0x4F, 0x46, 0x42, 0x4A, 0x70, 0x69, 0x42, ++ 0x53, 0x56, 0x59, 0x45, 0x51, 0x42, 0x72, 0x4C, 0x4C, 0x70, 0x4D, 0x45, 0x2B, 0x62, 0x55, 0x4D, 0x4A, 0x6D, 0x0A, 0x32, 0x48, 0x36, 0x4E, 0x4D, 0x4C, 0x56, 0x77, 0x4D, 0x65, 0x6E, 0x69, 0x61, 0x63, 0x66, 0x7A, 0x63, 0x4E, 0x73, 0x67, 0x46, ++ 0x59, 0x62, 0x51, 0x44, 0x66, 0x43, 0x2B, 0x72, 0x41, 0x46, 0x31, 0x68, 0x4D, 0x35, 0x2B, 0x6E, 0x30, 0x32, 0x2F, 0x74, 0x32, 0x41, 0x37, 0x6E, 0x50, 0x50, 0x4B, 0x48, 0x65, 0x4A, 0x65, 0x61, 0x4E, 0x69, 0x6A, 0x6E, 0x5A, 0x66, 0x6C, 0x51, ++ 0x47, 0x44, 0x53, 0x4E, 0x69, 0x48, 0x2B, 0x30, 0x4C, 0x53, 0x34, 0x46, 0x39, 0x70, 0x30, 0x0A, 0x6F, 0x33, 0x2F, 0x55, 0x33, 0x37, 0x43, 0x59, 0x41, 0x71, 0x78, 0x76, 0x61, 0x32, 0x73, 0x73, 0x4A, 0x53, 0x52, 0x79, 0x6F, 0x57, 0x58, 0x75, ++ 0x4A, 0x56, 0x72, 0x6C, 0x35, 0x6A, 0x4C, 0x6E, 0x38, 0x74, 0x2B, 0x72, 0x53, 0x66, 0x72, 0x7A, 0x6B, 0x47, 0x6B, 0x6A, 0x32, 0x77, 0x54, 0x5A, 0x35, 0x31, 0x78, 0x59, 0x2F, 0x47, 0x58, 0x55, 0x6C, 0x37, 0x37, 0x4D, 0x2F, 0x43, 0x34, 0x4B, ++ 0x7A, 0x43, 0x55, 0x71, 0x4E, 0x51, 0x54, 0x34, 0x59, 0x4A, 0x45, 0x56, 0x0A, 0x64, 0x54, 0x31, 0x42, 0x2F, 0x79, 0x4D, 0x66, 0x47, 0x63, 0x68, 0x73, 0x36, 0x34, 0x4A, 0x54, 0x42, 0x4B, 0x62, 0x6B, 0x54, 0x43, 0x4A, 0x4E, 0x6A, 0x59, 0x79, ++ 0x36, 0x7A, 0x6C, 0x74, 0x7A, 0x37, 0x47, 0x52, 0x55, 0x55, 0x47, 0x33, 0x52, 0x6E, 0x46, 0x58, 0x37, 0x61, 0x63, 0x4D, 0x32, 0x77, 0x34, 0x79, 0x38, 0x50, 0x49, 0x57, 0x6D, 0x61, 0x77, 0x6F, 0x6D, 0x44, 0x65, 0x43, 0x54, 0x6D, 0x47, 0x43, ++ 0x75, 0x66, 0x73, 0x59, 0x6B, 0x6C, 0x34, 0x70, 0x68, 0x0A, 0x58, 0x35, 0x47, 0x4F, 0x5A, 0x70, 0x49, 0x4A, 0x68, 0x7A, 0x62, 0x4E, 0x69, 0x35, 0x73, 0x74, 0x50, 0x76, 0x5A, 0x52, 0x31, 0x46, 0x44, 0x55, 0x57, 0x53, 0x69, 0x39, 0x67, 0x2F, ++ 0x4C, 0x4D, 0x4B, 0x48, 0x74, 0x54, 0x68, 0x6D, 0x33, 0x59, 0x4A, 0x6F, 0x68, 0x77, 0x31, 0x2B, 0x71, 0x52, 0x7A, 0x54, 0x36, 0x35, 0x79, 0x73, 0x43, 0x51, 0x62, 0x6C, 0x72, 0x47, 0x58, 0x6E, 0x52, 0x6C, 0x31, 0x31, 0x7A, 0x2B, 0x6F, 0x2B, ++ 0x49, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x52, 0x6F, ++ 0x6F, 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, 0x45, 0x56, 0x20, 0x32, 0x30, 0x30, 0x39, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, ++ 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x45, 0x51, 0x7A, 0x43, 0x43, 0x41, 0x79, 0x75, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x44, 0x43, 0x59, 0x50, 0x30, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, ++ 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43, 0x77, 0x55, 0x41, 0x4D, 0x46, 0x41, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x52, 0x46, 0x4D, 0x52, 0x55, 0x77, 0x45, 0x77, 0x59, 0x44, 0x56, 0x51, ++ 0x51, 0x4B, 0x0A, 0x44, 0x41, 0x78, 0x45, 0x4C, 0x56, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x49, 0x45, 0x64, 0x74, 0x59, 0x6B, 0x67, 0x78, 0x4B, 0x6A, 0x41, 0x6F, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x49, 0x55, 0x51, 0x74, 0x56, ++ 0x46, 0x4A, 0x56, 0x55, 0x31, 0x51, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x62, 0x47, 0x46, 0x7A, 0x63, 0x79, 0x41, 0x7A, 0x49, 0x45, 0x4E, 0x42, 0x49, 0x44, 0x49, 0x67, 0x52, 0x56, 0x59, 0x67, 0x4D, 0x6A, 0x41, 0x77, 0x0A, ++ 0x4F, 0x54, 0x41, 0x65, 0x46, 0x77, 0x30, 0x77, 0x4F, 0x54, 0x45, 0x78, 0x4D, 0x44, 0x55, 0x77, 0x4F, 0x44, 0x55, 0x77, 0x4E, 0x44, 0x5A, 0x61, 0x46, 0x77, 0x30, 0x79, 0x4F, 0x54, 0x45, 0x78, 0x4D, 0x44, 0x55, 0x77, 0x4F, 0x44, 0x55, 0x77, ++ 0x4E, 0x44, 0x5A, 0x61, 0x4D, 0x46, 0x41, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x52, 0x46, 0x4D, 0x52, 0x55, 0x77, 0x45, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x0A, 0x44, 0x41, 0x78, ++ 0x45, 0x4C, 0x56, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x49, 0x45, 0x64, 0x74, 0x59, 0x6B, 0x67, 0x78, 0x4B, 0x6A, 0x41, 0x6F, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x49, 0x55, 0x51, 0x74, 0x56, 0x46, 0x4A, 0x56, 0x55, 0x31, 0x51, ++ 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x62, 0x47, 0x46, 0x7A, 0x63, 0x79, 0x41, 0x7A, 0x49, 0x45, 0x4E, 0x42, 0x49, 0x44, 0x49, 0x67, 0x52, 0x56, 0x59, 0x67, 0x4D, 0x6A, 0x41, 0x77, 0x0A, 0x4F, 0x54, 0x43, 0x43, 0x41, 0x53, ++ 0x49, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x51, 0x6F, 0x43, 0x67, 0x67, 0x45, 0x42, 0x41, 0x4A, ++ 0x6E, 0x78, 0x68, 0x44, 0x52, 0x77, 0x75, 0x69, 0x2B, 0x33, 0x4D, 0x4B, 0x43, 0x4F, 0x76, 0x58, 0x77, 0x45, 0x7A, 0x37, 0x35, 0x69, 0x76, 0x4A, 0x6E, 0x39, 0x67, 0x70, 0x66, 0x53, 0x0A, 0x65, 0x67, 0x70, 0x6E, 0x6C, 0x6A, 0x67, 0x4A, 0x39, ++ 0x68, 0x42, 0x4F, 0x6C, 0x53, 0x4A, 0x7A, 0x6D, 0x59, 0x33, 0x61, 0x46, 0x53, 0x33, 0x6E, 0x42, 0x66, 0x77, 0x5A, 0x63, 0x79, 0x4B, 0x33, 0x6A, 0x70, 0x67, 0x41, 0x76, 0x44, 0x77, 0x39, 0x72, 0x4B, 0x46, 0x73, 0x2B, 0x39, 0x5A, 0x35, 0x4A, ++ 0x55, 0x75, 0x74, 0x38, 0x4D, 0x78, 0x6B, 0x32, 0x6F, 0x67, 0x2B, 0x4B, 0x62, 0x67, 0x50, 0x43, 0x64, 0x4D, 0x30, 0x33, 0x54, 0x50, 0x31, 0x59, 0x74, 0x48, 0x68, 0x0A, 0x7A, 0x52, 0x6E, 0x70, 0x37, 0x68, 0x68, 0x50, 0x54, 0x46, 0x69, 0x75, ++ 0x34, 0x68, 0x37, 0x57, 0x44, 0x46, 0x73, 0x56, 0x57, 0x74, 0x67, 0x36, 0x75, 0x4D, 0x51, 0x59, 0x5A, 0x42, 0x37, 0x6A, 0x4D, 0x37, 0x4B, 0x31, 0x69, 0x58, 0x64, 0x4F, 0x44, 0x4C, 0x2F, 0x5A, 0x6C, 0x47, 0x73, 0x54, 0x6C, 0x32, 0x38, 0x53, ++ 0x6F, 0x2F, 0x36, 0x5A, 0x71, 0x51, 0x54, 0x4D, 0x46, 0x65, 0x78, 0x67, 0x61, 0x44, 0x62, 0x74, 0x43, 0x48, 0x75, 0x33, 0x39, 0x62, 0x2B, 0x54, 0x0A, 0x37, 0x57, 0x59, 0x78, 0x67, 0x34, 0x7A, 0x47, 0x63, 0x54, 0x53, 0x48, 0x54, 0x68, 0x66, ++ 0x71, 0x72, 0x34, 0x75, 0x52, 0x6A, 0x52, 0x78, 0x57, 0x51, 0x61, 0x34, 0x69, 0x4E, 0x31, 0x34, 0x33, 0x38, 0x68, 0x33, 0x5A, 0x30, 0x53, 0x30, 0x4E, 0x4C, 0x32, 0x6C, 0x52, 0x70, 0x37, 0x35, 0x6D, 0x70, 0x6F, 0x6F, 0x36, 0x4B, 0x72, 0x33, ++ 0x48, 0x47, 0x72, 0x48, 0x68, 0x46, 0x50, 0x43, 0x2B, 0x4F, 0x68, 0x32, 0x35, 0x7A, 0x31, 0x75, 0x78, 0x61, 0x76, 0x36, 0x30, 0x0A, 0x73, 0x55, 0x59, 0x67, 0x6F, 0x76, 0x73, 0x65, 0x4F, 0x33, 0x44, 0x76, 0x6B, 0x35, 0x68, 0x39, 0x6A, 0x48, ++ 0x4F, 0x57, 0x38, 0x73, 0x58, 0x76, 0x68, 0x58, 0x43, 0x74, 0x4B, 0x53, 0x62, 0x38, 0x48, 0x67, 0x51, 0x2B, 0x48, 0x4B, 0x44, 0x59, 0x44, 0x38, 0x74, 0x53, 0x67, 0x32, 0x4A, 0x38, 0x37, 0x6F, 0x74, 0x54, 0x6C, 0x5A, 0x43, 0x70, 0x56, 0x36, ++ 0x4C, 0x71, 0x59, 0x51, 0x58, 0x59, 0x2B, 0x55, 0x33, 0x45, 0x4A, 0x2F, 0x70, 0x75, 0x72, 0x65, 0x33, 0x35, 0x0A, 0x31, 0x31, 0x48, 0x33, 0x61, 0x36, 0x55, 0x43, 0x41, 0x77, 0x45, 0x41, 0x41, 0x61, 0x4F, 0x43, 0x41, 0x53, 0x51, 0x77, 0x67, ++ 0x67, 0x45, 0x67, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x46, ++ 0x4E, 0x4F, 0x55, 0x69, 0x6B, 0x78, 0x69, 0x45, 0x79, 0x6F, 0x5A, 0x4C, 0x73, 0x79, 0x76, 0x0A, 0x63, 0x6F, 0x70, 0x39, 0x4E, 0x74, 0x65, 0x61, 0x48, 0x4E, 0x78, 0x6E, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, ++ 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6A, 0x43, 0x42, 0x33, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x66, 0x42, 0x49, 0x48, 0x56, 0x4D, 0x49, 0x48, 0x53, 0x4D, 0x49, 0x47, 0x48, 0x6F, 0x49, 0x47, 0x45, 0x6F, 0x49, 0x47, 0x42, ++ 0x68, 0x6E, 0x39, 0x73, 0x5A, 0x47, 0x46, 0x77, 0x4F, 0x69, 0x38, 0x76, 0x0A, 0x5A, 0x47, 0x6C, 0x79, 0x5A, 0x57, 0x4E, 0x30, 0x62, 0x33, 0x4A, 0x35, 0x4C, 0x6D, 0x51, 0x74, 0x64, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x75, 0x62, 0x6D, 0x56, ++ 0x30, 0x4C, 0x30, 0x4E, 0x4F, 0x50, 0x55, 0x51, 0x74, 0x56, 0x46, 0x4A, 0x56, 0x55, 0x31, 0x51, 0x6C, 0x4D, 0x6A, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x4A, 0x54, 0x49, 0x77, 0x51, 0x32, 0x78, 0x68, 0x63, 0x33, 0x4D, 0x6C, 0x4D, 0x6A, 0x41, ++ 0x7A, 0x4A, 0x54, 0x49, 0x77, 0x51, 0x30, 0x45, 0x6C, 0x0A, 0x4D, 0x6A, 0x41, 0x79, 0x4A, 0x54, 0x49, 0x77, 0x52, 0x56, 0x59, 0x6C, 0x4D, 0x6A, 0x41, 0x79, 0x4D, 0x44, 0x41, 0x35, 0x4C, 0x45, 0x38, 0x39, 0x52, 0x43, 0x31, 0x55, 0x63, 0x6E, ++ 0x56, 0x7A, 0x64, 0x43, 0x55, 0x79, 0x4D, 0x45, 0x64, 0x74, 0x59, 0x6B, 0x67, 0x73, 0x51, 0x7A, 0x31, 0x45, 0x52, 0x54, 0x39, 0x6A, 0x5A, 0x58, 0x4A, 0x30, 0x61, 0x57, 0x5A, 0x70, 0x59, 0x32, 0x46, 0x30, 0x5A, 0x58, 0x4A, 0x6C, 0x64, 0x6D, ++ 0x39, 0x6A, 0x59, 0x58, 0x52, 0x70, 0x0A, 0x62, 0x32, 0x35, 0x73, 0x61, 0x58, 0x4E, 0x30, 0x4D, 0x45, 0x61, 0x67, 0x52, 0x4B, 0x42, 0x43, 0x68, 0x6B, 0x42, 0x6F, 0x64, 0x48, 0x52, 0x77, 0x4F, 0x69, 0x38, 0x76, 0x64, 0x33, 0x64, 0x33, 0x4C, ++ 0x6D, 0x51, 0x74, 0x64, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x75, 0x62, 0x6D, 0x56, 0x30, 0x4C, 0x32, 0x4E, 0x79, 0x62, 0x43, 0x39, 0x6B, 0x4C, 0x58, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x58, 0x33, 0x4A, 0x76, 0x62, 0x33, 0x52, 0x66, 0x59, ++ 0x32, 0x78, 0x68, 0x0A, 0x63, 0x33, 0x4E, 0x66, 0x4D, 0x31, 0x39, 0x6A, 0x59, 0x56, 0x38, 0x79, 0x58, 0x32, 0x56, 0x32, 0x58, 0x7A, 0x49, 0x77, 0x4D, 0x44, 0x6B, 0x75, 0x59, 0x33, 0x4A, 0x73, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, ++ 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43, 0x77, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x41, 0x51, 0x41, 0x30, 0x37, 0x58, 0x74, 0x61, 0x50, 0x4B, 0x53, 0x55, 0x69, 0x4F, 0x38, 0x61, 0x45, 0x58, 0x55, 0x48, 0x4C, 0x37, 0x50, 0x2B, ++ 0x0A, 0x50, 0x50, 0x6F, 0x65, 0x55, 0x53, 0x62, 0x72, 0x68, 0x2F, 0x59, 0x70, 0x33, 0x75, 0x44, 0x78, 0x31, 0x4D, 0x59, 0x6B, 0x43, 0x65, 0x6E, 0x42, 0x7A, 0x31, 0x55, 0x62, 0x74, 0x44, 0x44, 0x5A, 0x7A, 0x68, 0x72, 0x2B, 0x42, 0x6C, 0x47, ++ 0x6D, 0x46, 0x61, 0x51, 0x74, 0x37, 0x37, 0x4A, 0x4C, 0x76, 0x79, 0x41, 0x6F, 0x4A, 0x55, 0x6E, 0x52, 0x70, 0x6A, 0x5A, 0x33, 0x4E, 0x4F, 0x68, 0x6B, 0x33, 0x31, 0x4B, 0x78, 0x45, 0x63, 0x64, 0x7A, 0x65, 0x73, 0x30, 0x35, 0x0A, 0x6E, 0x73, ++ 0x4B, 0x74, 0x6A, 0x48, 0x45, 0x68, 0x38, 0x6C, 0x70, 0x72, 0x72, 0x39, 0x38, 0x38, 0x54, 0x6C, 0x57, 0x76, 0x73, 0x6F, 0x52, 0x6C, 0x46, 0x49, 0x6D, 0x35, 0x64, 0x38, 0x73, 0x71, 0x4D, 0x62, 0x37, 0x50, 0x6F, 0x32, 0x33, 0x50, 0x62, 0x30, ++ 0x69, 0x55, 0x4D, 0x6B, 0x5A, 0x76, 0x35, 0x33, 0x47, 0x4D, 0x6F, 0x4B, 0x61, 0x45, 0x47, 0x54, 0x63, 0x48, 0x38, 0x67, 0x4E, 0x46, 0x43, 0x53, 0x75, 0x47, 0x64, 0x58, 0x7A, 0x66, 0x58, 0x32, 0x6C, 0x58, 0x0A, 0x41, 0x4E, 0x74, 0x75, 0x32, ++ 0x4B, 0x5A, 0x79, 0x49, 0x6B, 0x74, 0x51, 0x31, 0x48, 0x57, 0x59, 0x56, 0x74, 0x2B, 0x33, 0x47, 0x50, 0x39, 0x44, 0x51, 0x31, 0x43, 0x75, 0x65, 0x6B, 0x52, 0x37, 0x38, 0x48, 0x6C, 0x52, 0x31, 0x30, 0x4D, 0x39, 0x70, 0x39, 0x4F, 0x42, 0x30, ++ 0x2F, 0x44, 0x4A, 0x54, 0x37, 0x6E, 0x61, 0x78, 0x70, 0x65, 0x47, 0x30, 0x49, 0x4C, 0x44, 0x35, 0x45, 0x4A, 0x74, 0x2F, 0x72, 0x44, 0x69, 0x5A, 0x45, 0x34, 0x4F, 0x4A, 0x75, 0x64, 0x41, 0x0A, 0x4E, 0x43, 0x61, 0x31, 0x43, 0x49, 0x6E, 0x58, ++ 0x43, 0x47, 0x4E, 0x6A, 0x4F, 0x43, 0x64, 0x31, 0x48, 0x6A, 0x50, 0x71, 0x62, 0x71, 0x6A, 0x64, 0x6E, 0x35, 0x6C, 0x50, 0x64, 0x45, 0x32, 0x42, 0x69, 0x59, 0x42, 0x4C, 0x33, 0x5A, 0x71, 0x58, 0x4B, 0x56, 0x77, 0x76, 0x76, 0x6F, 0x46, 0x42, ++ 0x75, 0x59, 0x7A, 0x2F, 0x36, 0x6E, 0x31, 0x67, 0x42, 0x70, 0x37, 0x4E, 0x31, 0x7A, 0x33, 0x54, 0x4C, 0x71, 0x4D, 0x56, 0x76, 0x4B, 0x6A, 0x6D, 0x4A, 0x75, 0x56, 0x76, 0x0A, 0x77, 0x39, 0x79, 0x34, 0x41, 0x79, 0x48, 0x71, 0x6E, 0x78, 0x62, ++ 0x78, 0x4C, 0x46, 0x53, 0x31, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x43, 0x41, 0x20, 0x44, 0x69, 0x73, 0x69, ++ 0x67, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x32, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, ++ 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x61, 0x54, 0x43, 0x43, 0x41, 0x31, 0x47, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x4A, 0x41, 0x4A, 0x4B, 0x34, 0x69, ++ 0x4E, 0x75, 0x77, 0x69, 0x73, 0x46, 0x6A, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43, 0x77, 0x55, 0x41, 0x4D, 0x46, 0x49, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, ++ 0x41, 0x59, 0x54, 0x41, 0x6C, 0x4E, 0x4C, 0x4D, 0x52, 0x4D, 0x77, 0x0A, 0x45, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x48, 0x45, 0x77, 0x70, 0x43, 0x63, 0x6D, 0x46, 0x30, 0x61, 0x58, 0x4E, 0x73, 0x59, 0x58, 0x5A, 0x68, 0x4D, 0x52, 0x4D, 0x77, ++ 0x45, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x77, 0x70, 0x45, 0x61, 0x58, 0x4E, 0x70, 0x5A, 0x79, 0x42, 0x68, 0x4C, 0x6E, 0x4D, 0x75, 0x4D, 0x52, 0x6B, 0x77, 0x46, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x42, 0x44, ++ 0x51, 0x53, 0x42, 0x45, 0x61, 0x58, 0x4E, 0x70, 0x0A, 0x5A, 0x79, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x46, 0x49, 0x79, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x45, 0x79, 0x4D, 0x44, 0x63, 0x78, 0x4F, 0x54, 0x41, 0x35, 0x4D, 0x54, 0x55, ++ 0x7A, 0x4D, 0x46, 0x6F, 0x58, 0x44, 0x54, 0x51, 0x79, 0x4D, 0x44, 0x63, 0x78, 0x4F, 0x54, 0x41, 0x35, 0x4D, 0x54, 0x55, 0x7A, 0x4D, 0x46, 0x6F, 0x77, 0x55, 0x6A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, ++ 0x43, 0x55, 0x30, 0x73, 0x78, 0x0A, 0x45, 0x7A, 0x41, 0x52, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x63, 0x54, 0x43, 0x6B, 0x4A, 0x79, 0x59, 0x58, 0x52, 0x70, 0x63, 0x32, 0x78, 0x68, 0x64, 0x6D, 0x45, 0x78, 0x45, 0x7A, 0x41, 0x52, 0x42, 0x67, ++ 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x43, 0x6B, 0x52, 0x70, 0x63, 0x32, 0x6C, 0x6E, 0x49, 0x47, 0x45, 0x75, 0x63, 0x79, 0x34, 0x78, 0x47, 0x54, 0x41, 0x58, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x45, 0x45, 0x4E, 0x42, 0x49, 0x45, ++ 0x52, 0x70, 0x0A, 0x63, 0x32, 0x6C, 0x6E, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x55, 0x6A, 0x49, 0x77, 0x67, 0x67, 0x49, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, ++ 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x43, 0x69, 0x6F, 0x38, 0x51, 0x41, 0x43, 0x64, 0x61, 0x46, 0x58, 0x53, 0x31, 0x74, 0x46, 0x50, 0x62, 0x43, 0x0A, ++ 0x77, 0x33, 0x4F, 0x65, 0x4E, 0x63, 0x4A, 0x78, 0x56, 0x58, 0x36, 0x42, 0x2B, 0x36, 0x74, 0x47, 0x55, 0x4F, 0x44, 0x42, 0x66, 0x45, 0x6C, 0x34, 0x35, 0x71, 0x74, 0x35, 0x57, 0x44, 0x7A, 0x61, 0x2F, 0x33, 0x77, 0x63, 0x6E, 0x39, 0x69, 0x58, ++ 0x41, 0x6E, 0x67, 0x2B, 0x61, 0x30, 0x45, 0x45, 0x36, 0x55, 0x47, 0x39, 0x76, 0x67, 0x4D, 0x73, 0x52, 0x66, 0x59, 0x76, 0x5A, 0x4E, 0x53, 0x72, 0x58, 0x61, 0x4E, 0x48, 0x50, 0x57, 0x53, 0x62, 0x36, 0x57, 0x69, 0x61, 0x0A, 0x78, 0x73, 0x77, ++ 0x62, 0x50, 0x37, 0x71, 0x2B, 0x73, 0x6F, 0x73, 0x30, 0x41, 0x69, 0x36, 0x59, 0x56, 0x52, 0x6E, 0x38, 0x6A, 0x47, 0x2B, 0x71, 0x58, 0x39, 0x70, 0x4D, 0x7A, 0x6B, 0x30, 0x44, 0x49, 0x61, 0x50, 0x59, 0x30, 0x6A, 0x53, 0x54, 0x56, 0x70, 0x62, ++ 0x4C, 0x54, 0x41, 0x77, 0x41, 0x46, 0x6A, 0x78, 0x66, 0x47, 0x73, 0x33, 0x49, 0x78, 0x32, 0x79, 0x6D, 0x72, 0x64, 0x4D, 0x78, 0x70, 0x37, 0x7A, 0x6F, 0x35, 0x65, 0x46, 0x6D, 0x31, 0x74, 0x4C, 0x37, 0x0A, 0x41, 0x37, 0x52, 0x42, 0x5A, 0x63, ++ 0x6B, 0x51, 0x72, 0x67, 0x34, 0x46, 0x59, 0x38, 0x61, 0x41, 0x61, 0x6D, 0x6B, 0x77, 0x2F, 0x64, 0x4C, 0x75, 0x6B, 0x4F, 0x38, 0x4E, 0x4A, 0x39, 0x2B, 0x66, 0x6C, 0x58, 0x50, 0x30, 0x34, 0x53, 0x58, 0x61, 0x62, 0x42, 0x62, 0x65, 0x51, 0x54, ++ 0x67, 0x30, 0x36, 0x6F, 0x76, 0x38, 0x30, 0x65, 0x67, 0x45, 0x46, 0x47, 0x45, 0x74, 0x51, 0x58, 0x36, 0x73, 0x78, 0x33, 0x64, 0x4F, 0x79, 0x31, 0x46, 0x55, 0x2B, 0x31, 0x36, 0x53, 0x0A, 0x47, 0x42, 0x73, 0x45, 0x57, 0x6D, 0x6A, 0x47, 0x79, ++ 0x63, 0x54, 0x36, 0x74, 0x78, 0x4F, 0x67, 0x6D, 0x4C, 0x63, 0x52, 0x4B, 0x37, 0x66, 0x57, 0x56, 0x38, 0x78, 0x38, 0x6E, 0x68, 0x66, 0x52, 0x79, 0x79, 0x58, 0x2B, 0x68, 0x6B, 0x34, 0x6B, 0x4C, 0x6C, 0x59, 0x4D, 0x65, 0x45, 0x32, 0x65, 0x41, ++ 0x52, 0x4B, 0x6D, 0x4B, 0x36, 0x63, 0x42, 0x5A, 0x57, 0x35, 0x38, 0x59, 0x68, 0x32, 0x45, 0x68, 0x4E, 0x2F, 0x71, 0x77, 0x47, 0x75, 0x31, 0x70, 0x53, 0x71, 0x56, 0x0A, 0x67, 0x38, 0x4E, 0x54, 0x45, 0x51, 0x78, 0x7A, 0x48, 0x51, 0x75, 0x79, ++ 0x52, 0x70, 0x44, 0x52, 0x51, 0x6A, 0x72, 0x4F, 0x51, 0x47, 0x36, 0x56, 0x72, 0x66, 0x2F, 0x47, 0x6C, 0x4B, 0x31, 0x75, 0x6C, 0x34, 0x53, 0x4F, 0x66, 0x57, 0x2B, 0x65, 0x69, 0x6F, 0x41, 0x4E, 0x53, 0x57, 0x31, 0x7A, 0x34, 0x6E, 0x75, 0x53, ++ 0x48, 0x73, 0x50, 0x7A, 0x77, 0x66, 0x50, 0x72, 0x4C, 0x67, 0x56, 0x76, 0x32, 0x52, 0x76, 0x50, 0x4E, 0x33, 0x59, 0x45, 0x79, 0x4C, 0x52, 0x61, 0x0A, 0x35, 0x42, 0x65, 0x6E, 0x79, 0x39, 0x31, 0x32, 0x48, 0x39, 0x41, 0x5A, 0x64, 0x75, 0x67, ++ 0x73, 0x42, 0x62, 0x50, 0x57, 0x6E, 0x44, 0x54, 0x59, 0x6C, 0x74, 0x78, 0x68, 0x68, 0x35, 0x45, 0x46, 0x35, 0x45, 0x51, 0x49, 0x4D, 0x38, 0x48, 0x61, 0x75, 0x51, 0x68, 0x6C, 0x31, 0x4B, 0x36, 0x79, 0x4E, 0x67, 0x33, 0x72, 0x75, 0x6A, 0x69, ++ 0x36, 0x44, 0x4F, 0x57, 0x62, 0x6E, 0x75, 0x75, 0x4E, 0x5A, 0x74, 0x32, 0x5A, 0x7A, 0x39, 0x61, 0x4A, 0x51, 0x66, 0x59, 0x45, 0x0A, 0x6B, 0x6F, 0x6F, 0x70, 0x4B, 0x57, 0x31, 0x72, 0x4F, 0x68, 0x7A, 0x6E, 0x64, 0x58, 0x30, 0x43, 0x63, 0x51, ++ 0x37, 0x7A, 0x77, 0x4F, 0x65, 0x39, 0x79, 0x78, 0x6E, 0x64, 0x6E, 0x57, 0x43, 0x79, 0x77, 0x6D, 0x5A, 0x67, 0x74, 0x72, 0x45, 0x45, 0x37, 0x73, 0x6E, 0x6D, 0x68, 0x72, 0x6D, 0x61, 0x5A, 0x6B, 0x43, 0x6F, 0x35, 0x78, 0x48, 0x74, 0x67, 0x55, ++ 0x55, 0x44, 0x69, 0x2F, 0x5A, 0x6E, 0x57, 0x65, 0x6A, 0x42, 0x42, 0x68, 0x47, 0x39, 0x33, 0x63, 0x2B, 0x41, 0x0A, 0x41, 0x6B, 0x39, 0x6C, 0x51, 0x48, 0x68, 0x63, 0x52, 0x31, 0x44, 0x49, 0x6D, 0x2B, 0x59, 0x66, 0x67, 0x58, 0x76, 0x6B, 0x52, ++ 0x4B, 0x68, 0x62, 0x68, 0x5A, 0x72, 0x69, 0x33, 0x6C, 0x72, 0x56, 0x78, 0x2F, 0x6B, 0x36, 0x52, 0x47, 0x5A, 0x4C, 0x35, 0x44, 0x4A, 0x55, 0x66, 0x4F, 0x52, 0x73, 0x6E, 0x4C, 0x4D, 0x4F, 0x50, 0x52, 0x65, 0x69, 0x73, 0x6A, 0x51, 0x53, 0x31, ++ 0x6E, 0x36, 0x79, 0x71, 0x45, 0x6D, 0x37, 0x30, 0x58, 0x6F, 0x6F, 0x51, 0x4C, 0x36, 0x69, 0x0A, 0x46, 0x68, 0x2F, 0x66, 0x35, 0x44, 0x63, 0x66, 0x45, 0x58, 0x50, 0x37, 0x6B, 0x41, 0x70, 0x6C, 0x51, 0x36, 0x49, 0x4E, 0x66, 0x50, 0x67, 0x47, ++ 0x41, 0x56, 0x55, 0x7A, 0x66, 0x62, 0x41, 0x4E, 0x75, 0x50, 0x54, 0x31, 0x72, 0x71, 0x56, 0x43, 0x56, 0x33, 0x77, 0x32, 0x45, 0x59, 0x78, 0x37, 0x58, 0x73, 0x51, 0x44, 0x6E, 0x59, 0x78, 0x35, 0x6E, 0x51, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, ++ 0x6F, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x0A, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, ++ 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x74, 0x5A, 0x6E, 0x34, 0x72, 0x37, 0x43, 0x55, 0x39, 0x65, 0x4D, 0x67, 0x31, 0x67, 0x71, ++ 0x74, 0x7A, 0x6B, 0x35, 0x57, 0x70, 0x43, 0x35, 0x75, 0x0A, 0x51, 0x75, 0x30, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x42, 0x41, 0x43, ++ 0x59, 0x47, 0x58, 0x6E, 0x44, 0x6E, 0x5A, 0x54, 0x50, 0x49, 0x67, 0x6D, 0x37, 0x5A, 0x6E, 0x42, 0x63, 0x36, 0x47, 0x33, 0x70, 0x6D, 0x73, 0x67, 0x48, 0x32, 0x65, 0x44, 0x74, 0x70, 0x58, 0x69, 0x2F, 0x71, 0x2F, 0x30, 0x37, 0x35, 0x4B, 0x4D, ++ 0x4F, 0x59, 0x4B, 0x6D, 0x46, 0x4D, 0x0A, 0x74, 0x43, 0x51, 0x53, 0x69, 0x6E, 0x31, 0x74, 0x45, 0x52, 0x54, 0x33, 0x6E, 0x4C, 0x58, 0x4B, 0x35, 0x72, 0x79, 0x65, 0x4A, 0x34, 0x35, 0x4D, 0x47, 0x63, 0x69, 0x70, 0x76, 0x58, 0x72, 0x41, 0x31, ++ 0x7A, 0x59, 0x4F, 0x62, 0x59, 0x56, 0x79, 0x62, 0x71, 0x6A, 0x47, 0x6F, 0x6D, 0x33, 0x32, 0x2B, 0x6E, 0x4E, 0x6A, 0x66, 0x37, 0x78, 0x75, 0x65, 0x51, 0x67, 0x63, 0x6E, 0x59, 0x71, 0x66, 0x47, 0x6F, 0x70, 0x54, 0x70, 0x74, 0x69, 0x37, 0x32, ++ 0x54, 0x56, 0x56, 0x0A, 0x73, 0x52, 0x48, 0x46, 0x71, 0x51, 0x4F, 0x7A, 0x56, 0x6A, 0x75, 0x35, 0x68, 0x4A, 0x4D, 0x69, 0x58, 0x6E, 0x37, 0x42, 0x39, 0x68, 0x4A, 0x53, 0x69, 0x2B, 0x6F, 0x73, 0x5A, 0x37, 0x7A, 0x2B, 0x4E, 0x6B, 0x7A, 0x31, ++ 0x75, 0x4D, 0x2F, 0x52, 0x73, 0x30, 0x6D, 0x53, 0x4F, 0x39, 0x4D, 0x70, 0x44, 0x70, 0x6B, 0x62, 0x6C, 0x76, 0x64, 0x68, 0x75, 0x44, 0x76, 0x45, 0x4B, 0x37, 0x5A, 0x34, 0x62, 0x4C, 0x51, 0x6A, 0x62, 0x2F, 0x44, 0x39, 0x30, 0x37, 0x4A, 0x65, ++ 0x0A, 0x64, 0x52, 0x2B, 0x5A, 0x6C, 0x61, 0x69, 0x73, 0x39, 0x74, 0x72, 0x68, 0x78, 0x54, 0x46, 0x37, 0x2B, 0x39, 0x46, 0x47, 0x73, 0x39, 0x4B, 0x38, 0x5A, 0x37, 0x52, 0x69, 0x56, 0x4C, 0x6F, 0x4A, 0x39, 0x32, 0x4F, 0x77, 0x6B, 0x36, 0x4B, ++ 0x61, 0x2B, 0x65, 0x6C, 0x53, 0x4C, 0x6F, 0x74, 0x67, 0x45, 0x71, 0x76, 0x38, 0x39, 0x57, 0x42, 0x57, 0x37, 0x78, 0x42, 0x63, 0x69, 0x38, 0x51, 0x61, 0x51, 0x74, 0x79, 0x44, 0x57, 0x32, 0x51, 0x4F, 0x79, 0x37, 0x57, 0x38, 0x0A, 0x31, 0x6B, ++ 0x2F, 0x42, 0x66, 0x44, 0x78, 0x75, 0x6A, 0x52, 0x4E, 0x74, 0x2B, 0x33, 0x76, 0x72, 0x4D, 0x4E, 0x44, 0x63, 0x54, 0x61, 0x2F, 0x46, 0x31, 0x62, 0x61, 0x6C, 0x54, 0x46, 0x74, 0x78, 0x79, 0x65, 0x67, 0x78, 0x76, 0x75, 0x67, 0x34, 0x42, 0x6B, ++ 0x69, 0x68, 0x47, 0x75, 0x4C, 0x71, 0x30, 0x74, 0x34, 0x53, 0x4F, 0x56, 0x67, 0x61, 0x2F, 0x34, 0x41, 0x4F, 0x67, 0x6E, 0x58, 0x6D, 0x74, 0x38, 0x6B, 0x48, 0x62, 0x41, 0x37, 0x76, 0x2F, 0x7A, 0x6A, 0x78, 0x0A, 0x6D, 0x48, 0x48, 0x45, 0x74, ++ 0x33, 0x38, 0x4F, 0x46, 0x64, 0x41, 0x6C, 0x61, 0x62, 0x30, 0x69, 0x6E, 0x53, 0x76, 0x74, 0x42, 0x66, 0x5A, 0x47, 0x52, 0x36, 0x7A, 0x74, 0x77, 0x50, 0x44, 0x55, 0x4F, 0x2B, 0x4C, 0x73, 0x37, 0x70, 0x5A, 0x62, 0x6B, 0x42, 0x4E, 0x4F, 0x48, ++ 0x6C, 0x59, 0x36, 0x36, 0x37, 0x44, 0x76, 0x6C, 0x72, 0x75, 0x57, 0x49, 0x78, 0x47, 0x36, 0x38, 0x6B, 0x4F, 0x47, 0x64, 0x47, 0x53, 0x56, 0x79, 0x43, 0x68, 0x31, 0x33, 0x78, 0x30, 0x31, 0x0A, 0x75, 0x74, 0x49, 0x33, 0x67, 0x7A, 0x68, 0x54, ++ 0x4F, 0x44, 0x59, 0x37, 0x7A, 0x32, 0x7A, 0x70, 0x2B, 0x57, 0x73, 0x4F, 0x30, 0x50, 0x73, 0x45, 0x36, 0x45, 0x39, 0x33, 0x31, 0x32, 0x55, 0x42, 0x65, 0x49, 0x59, 0x4D, 0x65, 0x6A, 0x34, 0x68, 0x59, 0x76, 0x46, 0x2F, 0x59, 0x33, 0x45, 0x4D, ++ 0x79, 0x5A, 0x39, 0x45, 0x32, 0x36, 0x67, 0x6E, 0x6F, 0x6E, 0x57, 0x2B, 0x62, 0x6F, 0x45, 0x2B, 0x31, 0x38, 0x44, 0x72, 0x47, 0x35, 0x67, 0x50, 0x63, 0x46, 0x77, 0x30, 0x0A, 0x73, 0x6F, 0x72, 0x4D, 0x77, 0x49, 0x55, 0x59, 0x36, 0x32, 0x35, ++ 0x36, 0x73, 0x2F, 0x64, 0x61, 0x6F, 0x51, 0x65, 0x2F, 0x71, 0x55, 0x4B, 0x53, 0x38, 0x32, 0x41, 0x69, 0x6C, 0x2B, 0x51, 0x55, 0x6F, 0x51, 0x65, 0x62, 0x54, 0x6E, 0x62, 0x41, 0x6A, 0x6E, 0x33, 0x39, 0x70, 0x43, 0x58, 0x48, 0x52, 0x2B, 0x33, ++ 0x2F, 0x48, 0x33, 0x4F, 0x73, 0x7A, 0x4D, 0x4F, 0x6C, 0x36, 0x57, 0x38, 0x4B, 0x6A, 0x70, 0x74, 0x6C, 0x77, 0x6C, 0x43, 0x46, 0x74, 0x61, 0x4F, 0x67, 0x0A, 0x55, 0x78, 0x4C, 0x4D, 0x56, 0x59, 0x64, 0x68, 0x38, 0x34, 0x47, 0x75, 0x45, 0x45, ++ 0x5A, 0x68, 0x76, 0x55, 0x51, 0x68, 0x75, 0x4D, 0x49, 0x39, 0x64, 0x4D, 0x39, 0x2B, 0x4A, 0x44, 0x58, 0x36, 0x48, 0x41, 0x63, 0x4F, 0x6D, 0x7A, 0x30, 0x69, 0x79, 0x75, 0x38, 0x78, 0x4C, 0x34, 0x79, 0x73, 0x45, 0x72, 0x33, 0x76, 0x51, 0x43, ++ 0x6A, 0x38, 0x4B, 0x57, 0x65, 0x66, 0x73, 0x68, 0x4E, 0x50, 0x5A, 0x69, 0x54, 0x45, 0x55, 0x78, 0x6E, 0x70, 0x48, 0x69, 0x6B, 0x56, 0x0A, 0x37, 0x2B, 0x5A, 0x74, 0x73, 0x48, 0x38, 0x74, 0x5A, 0x2F, 0x33, 0x7A, 0x62, 0x42, 0x74, 0x31, 0x52, ++ 0x71, 0x50, 0x6C, 0x53, 0x68, 0x66, 0x70, 0x70, 0x4E, 0x63, 0x4C, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x41, ++ 0x43, 0x43, 0x56, 0x52, 0x41, 0x49, 0x5A, 0x31, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, ++ 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x48, 0x30, 0x7A, 0x43, 0x43, 0x42, 0x62, 0x75, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x49, 0x58, 0x73, 0x4F, 0x33, 0x70, 0x6B, 0x4E, 0x2F, 0x70, 0x4F, 0x41, 0x77, 0x44, ++ 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x46, 0x42, 0x51, 0x41, 0x77, 0x51, 0x6A, 0x45, 0x53, 0x4D, 0x42, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x4A, 0x51, 0x55, 0x4E, 0x44, 0x56, ++ 0x6C, 0x4A, 0x42, 0x0A, 0x53, 0x56, 0x6F, 0x78, 0x4D, 0x52, 0x41, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, 0x44, 0x41, 0x64, 0x51, 0x53, 0x30, 0x6C, 0x42, 0x51, 0x30, 0x4E, 0x57, 0x4D, 0x51, 0x30, 0x77, 0x43, 0x77, 0x59, 0x44, ++ 0x56, 0x51, 0x51, 0x4B, 0x44, 0x41, 0x52, 0x42, 0x51, 0x30, 0x4E, 0x57, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x46, 0x55, 0x7A, 0x41, 0x65, 0x46, 0x77, 0x30, 0x78, 0x4D, 0x54, 0x41, 0x31, ++ 0x0A, 0x4D, 0x44, 0x55, 0x77, 0x4F, 0x54, 0x4D, 0x33, 0x4D, 0x7A, 0x64, 0x61, 0x46, 0x77, 0x30, 0x7A, 0x4D, 0x44, 0x45, 0x79, 0x4D, 0x7A, 0x45, 0x77, 0x4F, 0x54, 0x4D, 0x33, 0x4D, 0x7A, 0x64, 0x61, 0x4D, 0x45, 0x49, 0x78, 0x45, 0x6A, 0x41, ++ 0x51, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x43, 0x55, 0x46, 0x44, 0x51, 0x31, 0x5A, 0x53, 0x51, 0x55, 0x6C, 0x61, 0x4D, 0x54, 0x45, 0x51, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x77, 0x77, 0x48, 0x0A, 0x55, 0x45, ++ 0x74, 0x4A, 0x51, 0x55, 0x4E, 0x44, 0x56, 0x6A, 0x45, 0x4E, 0x4D, 0x41, 0x73, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x45, 0x51, 0x55, 0x4E, 0x44, 0x56, 0x6A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, ++ 0x4D, 0x43, 0x52, 0x56, 0x4D, 0x77, 0x67, 0x67, 0x49, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x0A, 0x44, 0x77, 0x41, 0x77, 0x67, ++ 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x43, 0x62, 0x71, 0x61, 0x75, 0x2F, 0x59, 0x55, 0x71, 0x58, 0x72, 0x79, 0x2B, 0x58, 0x5A, 0x70, 0x70, 0x30, 0x58, 0x39, 0x44, 0x5A, 0x6C, 0x76, 0x33, 0x50, 0x34, 0x75, 0x52, 0x6D, 0x37, ++ 0x78, 0x38, 0x66, 0x52, 0x7A, 0x50, 0x43, 0x52, 0x4B, 0x50, 0x66, 0x6D, 0x74, 0x34, 0x66, 0x74, 0x56, 0x54, 0x64, 0x46, 0x58, 0x78, 0x70, 0x4E, 0x52, 0x46, 0x76, 0x75, 0x38, 0x67, 0x4D, 0x0A, 0x6A, 0x6D, 0x6F, 0x59, 0x48, 0x74, 0x69, 0x50, ++ 0x32, 0x52, 0x61, 0x38, 0x45, 0x45, 0x67, 0x32, 0x58, 0x50, 0x42, 0x6A, 0x73, 0x35, 0x42, 0x61, 0x58, 0x43, 0x51, 0x33, 0x31, 0x36, 0x50, 0x57, 0x79, 0x77, 0x6C, 0x78, 0x75, 0x66, 0x45, 0x42, 0x63, 0x6F, 0x53, 0x77, 0x66, 0x64, 0x74, 0x4E, ++ 0x67, 0x4D, 0x33, 0x38, 0x30, 0x32, 0x2F, 0x4A, 0x2B, 0x4E, 0x71, 0x32, 0x44, 0x6F, 0x4C, 0x53, 0x52, 0x59, 0x57, 0x6F, 0x47, 0x32, 0x69, 0x6F, 0x50, 0x65, 0x6A, 0x30, 0x0A, 0x52, 0x47, 0x79, 0x39, 0x6F, 0x63, 0x4C, 0x4C, 0x41, 0x37, 0x36, ++ 0x4D, 0x50, 0x68, 0x4D, 0x41, 0x68, 0x4E, 0x39, 0x4B, 0x53, 0x4D, 0x44, 0x6A, 0x49, 0x67, 0x72, 0x6F, 0x36, 0x54, 0x65, 0x6E, 0x47, 0x45, 0x79, 0x78, 0x43, 0x51, 0x30, 0x6A, 0x56, 0x6E, 0x38, 0x45, 0x54, 0x64, 0x6B, 0x58, 0x68, 0x42, 0x69, ++ 0x6C, 0x79, 0x4E, 0x70, 0x41, 0x6C, 0x48, 0x50, 0x72, 0x7A, 0x67, 0x35, 0x58, 0x50, 0x41, 0x4F, 0x42, 0x4F, 0x70, 0x30, 0x4B, 0x6F, 0x56, 0x64, 0x44, 0x0A, 0x61, 0x61, 0x78, 0x58, 0x62, 0x58, 0x6D, 0x51, 0x65, 0x4F, 0x57, 0x31, 0x74, 0x44, ++ 0x76, 0x59, 0x76, 0x45, 0x79, 0x4E, 0x4B, 0x4B, 0x47, 0x6E, 0x6F, 0x36, 0x65, 0x36, 0x41, 0x6B, 0x34, 0x6C, 0x30, 0x53, 0x71, 0x75, 0x37, 0x61, 0x34, 0x44, 0x49, 0x72, 0x68, 0x72, 0x49, 0x41, 0x38, 0x77, 0x4B, 0x46, 0x53, 0x56, 0x66, 0x2B, ++ 0x44, 0x75, 0x7A, 0x67, 0x70, 0x6D, 0x6E, 0x64, 0x46, 0x41, 0x4C, 0x57, 0x34, 0x69, 0x72, 0x35, 0x30, 0x61, 0x77, 0x51, 0x55, 0x5A, 0x0A, 0x30, 0x6D, 0x2F, 0x41, 0x38, 0x70, 0x2F, 0x34, 0x65, 0x37, 0x4D, 0x43, 0x51, 0x76, 0x74, 0x51, 0x71, ++ 0x52, 0x30, 0x74, 0x6B, 0x77, 0x38, 0x6A, 0x71, 0x38, 0x62, 0x42, 0x44, 0x35, 0x4C, 0x2F, 0x30, 0x4B, 0x49, 0x56, 0x39, 0x56, 0x4D, 0x4A, 0x63, 0x52, 0x7A, 0x2F, 0x52, 0x52, 0x4F, 0x45, 0x35, 0x69, 0x5A, 0x65, 0x2B, 0x4F, 0x43, 0x49, 0x48, ++ 0x41, 0x72, 0x38, 0x46, 0x72, 0x61, 0x6F, 0x63, 0x77, 0x61, 0x34, 0x38, 0x47, 0x4F, 0x45, 0x41, 0x71, 0x44, 0x47, 0x0A, 0x57, 0x75, 0x7A, 0x6E, 0x64, 0x4E, 0x39, 0x77, 0x72, 0x71, 0x4F, 0x44, 0x4A, 0x65, 0x72, 0x57, 0x78, 0x35, 0x65, 0x48, ++ 0x6B, 0x36, 0x66, 0x47, 0x69, 0x6F, 0x6F, 0x7A, 0x6C, 0x32, 0x41, 0x33, 0x45, 0x44, 0x36, 0x58, 0x50, 0x6D, 0x34, 0x70, 0x46, 0x64, 0x61, 0x68, 0x44, 0x39, 0x47, 0x49, 0x4C, 0x42, 0x4B, 0x66, 0x62, 0x36, 0x71, 0x6B, 0x78, 0x6B, 0x4C, 0x72, ++ 0x51, 0x61, 0x4C, 0x6A, 0x6C, 0x55, 0x50, 0x54, 0x41, 0x59, 0x56, 0x74, 0x6A, 0x72, 0x73, 0x37, 0x0A, 0x38, 0x79, 0x4D, 0x32, 0x78, 0x2F, 0x34, 0x37, 0x34, 0x4B, 0x45, 0x6C, 0x42, 0x30, 0x69, 0x72, 0x79, 0x59, 0x6C, 0x30, 0x2F, 0x77, 0x69, ++ 0x50, 0x67, 0x4C, 0x2F, 0x41, 0x6C, 0x6D, 0x58, 0x7A, 0x37, 0x75, 0x78, 0x4C, 0x61, 0x4C, 0x32, 0x64, 0x69, 0x4D, 0x4D, 0x78, 0x73, 0x30, 0x44, 0x78, 0x36, 0x4D, 0x2F, 0x32, 0x4F, 0x4C, 0x75, 0x63, 0x35, 0x4E, 0x46, 0x2F, 0x31, 0x4F, 0x56, ++ 0x59, 0x6D, 0x33, 0x7A, 0x36, 0x31, 0x50, 0x4D, 0x4F, 0x6D, 0x33, 0x57, 0x52, 0x0A, 0x35, 0x4C, 0x70, 0x53, 0x4C, 0x68, 0x6C, 0x2B, 0x30, 0x66, 0x58, 0x4E, 0x57, 0x68, 0x6E, 0x38, 0x75, 0x67, 0x62, 0x32, 0x2B, 0x31, 0x4B, 0x6F, 0x53, 0x35, ++ 0x6B, 0x45, 0x33, 0x66, 0x6A, 0x35, 0x74, 0x49, 0x74, 0x51, 0x6F, 0x30, 0x35, 0x69, 0x69, 0x66, 0x43, 0x48, 0x4A, 0x50, 0x71, 0x44, 0x51, 0x73, 0x47, 0x48, 0x2B, 0x74, 0x55, 0x74, 0x4B, 0x53, 0x70, 0x61, 0x63, 0x58, 0x70, 0x6B, 0x61, 0x74, ++ 0x63, 0x6E, 0x59, 0x47, 0x4D, 0x4E, 0x32, 0x38, 0x35, 0x4A, 0x0A, 0x39, 0x59, 0x30, 0x66, 0x6B, 0x49, 0x6B, 0x79, 0x46, 0x2F, 0x68, 0x7A, 0x51, 0x37, 0x6A, 0x53, 0x57, 0x70, 0x4F, 0x47, 0x59, 0x64, 0x62, 0x68, 0x64, 0x51, 0x72, 0x71, 0x65, ++ 0x57, 0x5A, 0x32, 0x69, 0x45, 0x39, 0x78, 0x36, 0x77, 0x51, 0x6C, 0x31, 0x67, 0x70, 0x61, 0x65, 0x70, 0x50, 0x6C, 0x75, 0x55, 0x73, 0x58, 0x51, 0x41, 0x2B, 0x78, 0x74, 0x72, 0x6E, 0x31, 0x33, 0x6B, 0x2F, 0x63, 0x34, 0x4C, 0x4F, 0x73, 0x4F, ++ 0x78, 0x46, 0x77, 0x59, 0x49, 0x52, 0x4B, 0x0A, 0x51, 0x32, 0x36, 0x5A, 0x49, 0x4D, 0x41, 0x70, 0x63, 0x51, 0x72, 0x41, 0x5A, 0x51, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6F, 0x34, 0x49, 0x43, 0x79, 0x7A, 0x43, 0x43, 0x41, 0x73, 0x63, 0x77, ++ 0x66, 0x51, 0x59, 0x49, 0x4B, 0x77, 0x59, 0x42, 0x42, 0x51, 0x55, 0x48, 0x41, 0x51, 0x45, 0x45, 0x63, 0x54, 0x42, 0x76, 0x4D, 0x45, 0x77, 0x47, 0x43, 0x43, 0x73, 0x47, 0x41, 0x51, 0x55, 0x46, 0x42, 0x7A, 0x41, 0x43, 0x68, 0x6B, 0x42, 0x6F, ++ 0x64, 0x48, 0x52, 0x77, 0x0A, 0x4F, 0x69, 0x38, 0x76, 0x64, 0x33, 0x64, 0x33, 0x4C, 0x6D, 0x46, 0x6A, 0x59, 0x33, 0x59, 0x75, 0x5A, 0x58, 0x4D, 0x76, 0x5A, 0x6D, 0x6C, 0x73, 0x5A, 0x57, 0x46, 0x6B, 0x62, 0x57, 0x6C, 0x75, 0x4C, 0x30, 0x46, ++ 0x79, 0x59, 0x32, 0x68, 0x70, 0x64, 0x6D, 0x39, 0x7A, 0x4C, 0x32, 0x4E, 0x6C, 0x63, 0x6E, 0x52, 0x70, 0x5A, 0x6D, 0x6C, 0x6A, 0x59, 0x57, 0x52, 0x76, 0x63, 0x79, 0x39, 0x79, 0x59, 0x57, 0x6C, 0x36, 0x59, 0x57, 0x4E, 0x6A, 0x64, 0x6A, 0x45, ++ 0x75, 0x0A, 0x59, 0x33, 0x4A, 0x30, 0x4D, 0x42, 0x38, 0x47, 0x43, 0x43, 0x73, 0x47, 0x41, 0x51, 0x55, 0x46, 0x42, 0x7A, 0x41, 0x42, 0x68, 0x68, 0x4E, 0x6F, 0x64, 0x48, 0x52, 0x77, 0x4F, 0x69, 0x38, 0x76, 0x62, 0x32, 0x4E, 0x7A, 0x63, 0x43, ++ 0x35, 0x68, 0x59, 0x32, 0x4E, 0x32, 0x4C, 0x6D, 0x56, 0x7A, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x54, 0x53, 0x68, 0x37, 0x54, 0x6A, 0x33, 0x7A, 0x63, 0x6E, 0x6B, 0x31, 0x58, 0x32, 0x0A, 0x56, ++ 0x75, 0x71, 0x42, 0x35, 0x54, 0x62, 0x4D, 0x6A, 0x42, 0x34, 0x2F, 0x76, 0x54, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x42, 0x38, 0x47, 0x41, ++ 0x31, 0x55, 0x64, 0x49, 0x77, 0x51, 0x59, 0x4D, 0x42, 0x61, 0x41, 0x46, 0x4E, 0x4B, 0x48, 0x74, 0x4F, 0x50, 0x66, 0x4E, 0x79, 0x65, 0x54, 0x56, 0x66, 0x5A, 0x57, 0x36, 0x6F, 0x48, 0x6C, 0x4E, 0x73, 0x79, 0x4D, 0x0A, 0x48, 0x6A, 0x2B, 0x39, ++ 0x4D, 0x49, 0x49, 0x42, 0x63, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x67, 0x42, 0x49, 0x49, 0x42, 0x61, 0x6A, 0x43, 0x43, 0x41, 0x57, 0x59, 0x77, 0x67, 0x67, 0x46, 0x69, 0x42, 0x67, 0x52, 0x56, 0x48, 0x53, 0x41, 0x41, 0x4D, 0x49, 0x49, 0x42, ++ 0x57, 0x44, 0x43, 0x43, 0x41, 0x53, 0x49, 0x47, 0x43, 0x43, 0x73, 0x47, 0x41, 0x51, 0x55, 0x46, 0x42, 0x77, 0x49, 0x43, 0x4D, 0x49, 0x49, 0x42, 0x46, 0x42, 0x36, 0x43, 0x41, 0x52, 0x41, 0x41, 0x0A, 0x51, 0x51, 0x42, 0x31, 0x41, 0x48, 0x51, ++ 0x41, 0x62, 0x77, 0x42, 0x79, 0x41, 0x47, 0x6B, 0x41, 0x5A, 0x41, 0x42, 0x68, 0x41, 0x47, 0x51, 0x41, 0x49, 0x41, 0x42, 0x6B, 0x41, 0x47, 0x55, 0x41, 0x49, 0x41, 0x42, 0x44, 0x41, 0x47, 0x55, 0x41, 0x63, 0x67, 0x42, 0x30, 0x41, 0x47, 0x6B, ++ 0x41, 0x5A, 0x67, 0x42, 0x70, 0x41, 0x47, 0x4D, 0x41, 0x59, 0x51, 0x42, 0x6A, 0x41, 0x47, 0x6B, 0x41, 0x38, 0x77, 0x42, 0x75, 0x41, 0x43, 0x41, 0x41, 0x55, 0x67, 0x42, 0x68, 0x0A, 0x41, 0x4F, 0x30, 0x41, 0x65, 0x67, 0x41, 0x67, 0x41, 0x47, ++ 0x51, 0x41, 0x5A, 0x51, 0x41, 0x67, 0x41, 0x47, 0x77, 0x41, 0x59, 0x51, 0x41, 0x67, 0x41, 0x45, 0x45, 0x41, 0x51, 0x77, 0x42, 0x44, 0x41, 0x46, 0x59, 0x41, 0x49, 0x41, 0x41, 0x6F, 0x41, 0x45, 0x45, 0x41, 0x5A, 0x77, 0x42, 0x6C, 0x41, 0x47, ++ 0x34, 0x41, 0x59, 0x77, 0x42, 0x70, 0x41, 0x47, 0x45, 0x41, 0x49, 0x41, 0x42, 0x6B, 0x41, 0x47, 0x55, 0x41, 0x49, 0x41, 0x42, 0x55, 0x41, 0x47, 0x55, 0x41, 0x0A, 0x59, 0x77, 0x42, 0x75, 0x41, 0x47, 0x38, 0x41, 0x62, 0x41, 0x42, 0x76, 0x41, ++ 0x47, 0x63, 0x41, 0x37, 0x51, 0x42, 0x68, 0x41, 0x43, 0x41, 0x41, 0x65, 0x51, 0x41, 0x67, 0x41, 0x45, 0x4D, 0x41, 0x5A, 0x51, 0x42, 0x79, 0x41, 0x48, 0x51, 0x41, 0x61, 0x51, 0x42, 0x6D, 0x41, 0x47, 0x6B, 0x41, 0x59, 0x77, 0x42, 0x68, 0x41, ++ 0x47, 0x4D, 0x41, 0x61, 0x51, 0x44, 0x7A, 0x41, 0x47, 0x34, 0x41, 0x49, 0x41, 0x42, 0x46, 0x41, 0x47, 0x77, 0x41, 0x5A, 0x51, 0x42, 0x6A, 0x0A, 0x41, 0x48, 0x51, 0x41, 0x63, 0x67, 0x44, 0x7A, 0x41, 0x47, 0x34, 0x41, 0x61, 0x51, 0x42, 0x6A, ++ 0x41, 0x47, 0x45, 0x41, 0x4C, 0x41, 0x41, 0x67, 0x41, 0x45, 0x4D, 0x41, 0x53, 0x51, 0x42, 0x47, 0x41, 0x43, 0x41, 0x41, 0x55, 0x51, 0x41, 0x30, 0x41, 0x44, 0x59, 0x41, 0x4D, 0x41, 0x41, 0x78, 0x41, 0x44, 0x45, 0x41, 0x4E, 0x51, 0x41, 0x32, ++ 0x41, 0x45, 0x55, 0x41, 0x4B, 0x51, 0x41, 0x75, 0x41, 0x43, 0x41, 0x41, 0x51, 0x77, 0x42, 0x51, 0x41, 0x46, 0x4D, 0x41, 0x0A, 0x49, 0x41, 0x42, 0x6C, 0x41, 0x47, 0x34, 0x41, 0x49, 0x41, 0x42, 0x6F, 0x41, 0x48, 0x51, 0x41, 0x64, 0x41, 0x42, ++ 0x77, 0x41, 0x44, 0x6F, 0x41, 0x4C, 0x77, 0x41, 0x76, 0x41, 0x48, 0x63, 0x41, 0x64, 0x77, 0x42, 0x33, 0x41, 0x43, 0x34, 0x41, 0x59, 0x51, 0x42, 0x6A, 0x41, 0x47, 0x4D, 0x41, 0x64, 0x67, 0x41, 0x75, 0x41, 0x47, 0x55, 0x41, 0x63, 0x7A, 0x41, ++ 0x77, 0x42, 0x67, 0x67, 0x72, 0x42, 0x67, 0x45, 0x46, 0x42, 0x51, 0x63, 0x43, 0x41, 0x52, 0x59, 0x6B, 0x0A, 0x61, 0x48, 0x52, 0x30, 0x63, 0x44, 0x6F, 0x76, 0x4C, 0x33, 0x64, 0x33, 0x64, 0x79, 0x35, 0x68, 0x59, 0x32, 0x4E, 0x32, 0x4C, 0x6D, ++ 0x56, 0x7A, 0x4C, 0x32, 0x78, 0x6C, 0x5A, 0x32, 0x6C, 0x7A, 0x62, 0x47, 0x46, 0x6A, 0x61, 0x57, 0x39, 0x75, 0x58, 0x32, 0x4D, 0x75, 0x61, 0x48, 0x52, 0x74, 0x4D, 0x46, 0x55, 0x47, 0x41, 0x31, 0x55, 0x64, 0x48, 0x77, 0x52, 0x4F, 0x4D, 0x45, ++ 0x77, 0x77, 0x53, 0x71, 0x42, 0x49, 0x6F, 0x45, 0x61, 0x47, 0x52, 0x47, 0x68, 0x30, 0x0A, 0x64, 0x48, 0x41, 0x36, 0x4C, 0x79, 0x39, 0x33, 0x64, 0x33, 0x63, 0x75, 0x59, 0x57, 0x4E, 0x6A, 0x64, 0x69, 0x35, 0x6C, 0x63, 0x79, 0x39, 0x6D, 0x61, ++ 0x57, 0x78, 0x6C, 0x59, 0x57, 0x52, 0x74, 0x61, 0x57, 0x34, 0x76, 0x51, 0x58, 0x4A, 0x6A, 0x61, 0x47, 0x6C, 0x32, 0x62, 0x33, 0x4D, 0x76, 0x59, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6C, 0x6D, 0x61, 0x57, 0x4E, 0x68, 0x5A, 0x47, 0x39, 0x7A, 0x4C, ++ 0x33, 0x4A, 0x68, 0x61, 0x58, 0x70, 0x68, 0x59, 0x32, 0x4E, 0x32, 0x0A, 0x4D, 0x56, 0x39, 0x6B, 0x5A, 0x58, 0x49, 0x75, 0x59, 0x33, 0x4A, 0x73, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, ++ 0x41, 0x77, 0x49, 0x42, 0x42, 0x6A, 0x41, 0x58, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x45, 0x45, 0x45, 0x44, 0x41, 0x4F, 0x67, 0x51, 0x78, 0x68, 0x59, 0x32, 0x4E, 0x32, 0x51, 0x47, 0x46, 0x6A, 0x59, 0x33, 0x59, 0x75, 0x5A, 0x58, 0x4D, 0x77, ++ 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x0A, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x46, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x42, 0x41, 0x4A, 0x63, 0x78, 0x41, 0x70, 0x2F, 0x6E, 0x2F, 0x55, 0x4E, 0x6E, 0x53, 0x45, 0x51, ++ 0x55, 0x35, 0x43, 0x6D, 0x48, 0x37, 0x55, 0x77, 0x6F, 0x5A, 0x74, 0x43, 0x50, 0x4E, 0x64, 0x70, 0x4E, 0x59, 0x62, 0x64, 0x4B, 0x6C, 0x30, 0x32, 0x31, 0x32, 0x35, 0x44, 0x67, 0x42, 0x53, 0x34, 0x4F, 0x78, 0x6E, 0x6E, 0x51, 0x38, 0x70, 0x64, ++ 0x70, 0x44, 0x37, 0x30, 0x45, 0x0A, 0x52, 0x39, 0x6D, 0x2B, 0x32, 0x37, 0x55, 0x70, 0x32, 0x70, 0x76, 0x5A, 0x72, 0x71, 0x6D, 0x5A, 0x31, 0x64, 0x4D, 0x38, 0x4D, 0x4A, 0x50, 0x31, 0x6A, 0x61, 0x47, 0x6F, 0x2F, 0x41, 0x61, 0x4E, 0x52, 0x50, ++ 0x54, 0x4B, 0x46, 0x70, 0x56, 0x38, 0x4D, 0x39, 0x78, 0x69, 0x69, 0x36, 0x67, 0x33, 0x2B, 0x43, 0x66, 0x59, 0x43, 0x53, 0x30, 0x62, 0x37, 0x38, 0x67, 0x55, 0x4A, 0x79, 0x43, 0x70, 0x5A, 0x45, 0x54, 0x2F, 0x4C, 0x74, 0x5A, 0x31, 0x71, 0x6D, ++ 0x78, 0x4E, 0x0A, 0x59, 0x45, 0x41, 0x5A, 0x53, 0x55, 0x4E, 0x55, 0x59, 0x39, 0x72, 0x69, 0x7A, 0x4C, 0x70, 0x6D, 0x35, 0x55, 0x39, 0x45, 0x65, 0x6C, 0x76, 0x5A, 0x61, 0x6F, 0x45, 0x72, 0x51, 0x4E, 0x56, 0x2F, 0x2B, 0x51, 0x45, 0x6E, 0x57, ++ 0x43, 0x7A, 0x49, 0x37, 0x55, 0x69, 0x52, 0x66, 0x44, 0x2B, 0x6D, 0x41, 0x4D, 0x2F, 0x45, 0x4B, 0x58, 0x4D, 0x52, 0x4E, 0x74, 0x36, 0x47, 0x47, 0x54, 0x36, 0x64, 0x37, 0x68, 0x6D, 0x4B, 0x47, 0x39, 0x57, 0x77, 0x37, 0x59, 0x34, 0x39, 0x0A, ++ 0x6E, 0x43, 0x72, 0x41, 0x44, 0x64, 0x67, 0x39, 0x5A, 0x75, 0x4D, 0x38, 0x44, 0x62, 0x33, 0x56, 0x6C, 0x46, 0x7A, 0x69, 0x34, 0x71, 0x63, 0x31, 0x47, 0x77, 0x51, 0x41, 0x39, 0x6A, 0x39, 0x61, 0x6A, 0x65, 0x70, 0x44, 0x76, 0x56, 0x2B, 0x4A, ++ 0x48, 0x61, 0x6E, 0x42, 0x73, 0x4D, 0x79, 0x5A, 0x34, 0x6B, 0x30, 0x41, 0x43, 0x74, 0x72, 0x4A, 0x4A, 0x31, 0x76, 0x6E, 0x45, 0x35, 0x42, 0x63, 0x35, 0x50, 0x55, 0x7A, 0x6F, 0x6C, 0x56, 0x74, 0x33, 0x4F, 0x41, 0x4A, 0x0A, 0x54, 0x53, 0x2B, ++ 0x78, 0x4A, 0x6C, 0x73, 0x6E, 0x64, 0x51, 0x41, 0x4A, 0x78, 0x47, 0x4A, 0x33, 0x4B, 0x51, 0x68, 0x66, 0x6E, 0x6C, 0x6D, 0x73, 0x74, 0x6E, 0x36, 0x74, 0x6E, 0x31, 0x51, 0x77, 0x49, 0x67, 0x50, 0x42, 0x48, 0x6E, 0x46, 0x6B, 0x2F, 0x76, 0x6B, ++ 0x34, 0x43, 0x70, 0x59, 0x59, 0x33, 0x51, 0x49, 0x55, 0x72, 0x43, 0x50, 0x4C, 0x42, 0x68, 0x77, 0x65, 0x70, 0x48, 0x32, 0x4E, 0x44, 0x64, 0x34, 0x6E, 0x51, 0x65, 0x69, 0x74, 0x32, 0x68, 0x57, 0x33, 0x0A, 0x73, 0x43, 0x50, 0x64, 0x4B, 0x36, ++ 0x6A, 0x54, 0x32, 0x69, 0x57, 0x48, 0x37, 0x65, 0x68, 0x56, 0x52, 0x45, 0x32, 0x49, 0x39, 0x44, 0x5A, 0x2B, 0x68, 0x4A, 0x70, 0x34, 0x72, 0x50, 0x63, 0x4F, 0x56, 0x6B, 0x6B, 0x4F, 0x31, 0x6A, 0x4D, 0x6C, 0x31, 0x6F, 0x52, 0x51, 0x51, 0x6D, ++ 0x77, 0x67, 0x45, 0x68, 0x30, 0x71, 0x31, 0x62, 0x36, 0x38, 0x38, 0x6E, 0x43, 0x42, 0x70, 0x48, 0x42, 0x67, 0x76, 0x67, 0x57, 0x31, 0x6D, 0x35, 0x34, 0x45, 0x52, 0x4C, 0x35, 0x68, 0x0A, 0x49, 0x36, 0x7A, 0x70, 0x70, 0x53, 0x53, 0x4D, 0x45, ++ 0x59, 0x43, 0x55, 0x57, 0x71, 0x4B, 0x69, 0x75, 0x55, 0x6E, 0x53, 0x77, 0x64, 0x7A, 0x52, 0x70, 0x2B, 0x30, 0x78, 0x45, 0x53, 0x79, 0x65, 0x47, 0x61, 0x62, 0x75, 0x34, 0x56, 0x58, 0x68, 0x77, 0x4F, 0x72, 0x50, 0x44, 0x59, 0x54, 0x6B, 0x46, ++ 0x37, 0x65, 0x69, 0x66, 0x4B, 0x58, 0x65, 0x56, 0x53, 0x55, 0x47, 0x37, 0x73, 0x7A, 0x41, 0x68, 0x31, 0x78, 0x41, 0x32, 0x73, 0x79, 0x56, 0x50, 0x31, 0x58, 0x67, 0x0A, 0x4E, 0x63, 0x65, 0x34, 0x68, 0x4C, 0x36, 0x30, 0x58, 0x63, 0x31, 0x36, ++ 0x67, 0x77, 0x46, 0x79, 0x37, 0x6F, 0x66, 0x6D, 0x58, 0x78, 0x32, 0x75, 0x74, 0x59, 0x58, 0x47, 0x4A, 0x74, 0x2F, 0x6D, 0x77, 0x5A, 0x72, 0x70, 0x48, 0x67, 0x4A, 0x48, 0x6E, 0x79, 0x71, 0x6F, 0x62, 0x61, 0x6C, 0x62, 0x7A, 0x2B, 0x78, 0x46, ++ 0x64, 0x33, 0x2B, 0x59, 0x4A, 0x35, 0x6F, 0x79, 0x58, 0x53, 0x72, 0x6A, 0x68, 0x4F, 0x37, 0x46, 0x6D, 0x47, 0x59, 0x76, 0x6C, 0x69, 0x41, 0x64, 0x0A, 0x33, 0x64, 0x6A, 0x44, 0x4A, 0x39, 0x65, 0x77, 0x2B, 0x66, 0x37, 0x5A, 0x66, 0x63, 0x33, ++ 0x51, 0x6E, 0x34, 0x38, 0x4C, 0x46, 0x46, 0x68, 0x52, 0x6E, 0x79, 0x2B, 0x4C, 0x77, 0x7A, 0x67, 0x74, 0x33, 0x75, 0x69, 0x50, 0x31, 0x6F, 0x32, 0x48, 0x70, 0x50, 0x56, 0x57, 0x51, 0x78, 0x61, 0x5A, 0x4C, 0x50, 0x53, 0x6B, 0x56, 0x72, 0x51, ++ 0x30, 0x75, 0x47, 0x45, 0x33, 0x79, 0x63, 0x4A, 0x59, 0x67, 0x42, 0x75, 0x67, 0x6C, 0x36, 0x48, 0x38, 0x57, 0x59, 0x33, 0x70, 0x0A, 0x45, 0x66, 0x62, 0x52, 0x44, 0x30, 0x74, 0x56, 0x4E, 0x45, 0x59, 0x71, 0x69, 0x34, 0x59, 0x37, 0x0A, 0x2D, ++ 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x54, 0x57, 0x43, 0x41, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, ++ 0x6F, 0x74, 0x20, 0x43, 0x41, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, ++ 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x51, 0x54, 0x43, 0x43, 0x41, 0x79, 0x6D, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x43, 0x44, 0x4C, 0x34, 0x77, 0x44, 0x51, ++ 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x77, 0x55, 0x54, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x56, 0x46, 0x63, 0x78, 0x45, 0x6A, ++ 0x41, 0x51, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x0A, 0x43, 0x56, 0x52, 0x42, 0x53, 0x56, 0x64, 0x42, 0x54, 0x69, 0x31, 0x44, 0x51, 0x54, 0x45, 0x51, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4D, 0x48, 0x55, ++ 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x54, 0x45, 0x63, 0x4D, 0x42, 0x6F, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x54, 0x56, 0x46, 0x64, 0x44, 0x51, 0x53, 0x42, 0x48, 0x62, 0x47, 0x39, 0x69, 0x59, 0x57, 0x77, 0x67, 0x55, ++ 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x0A, 0x51, 0x54, 0x41, 0x65, 0x46, 0x77, 0x30, 0x78, 0x4D, 0x6A, 0x41, 0x32, 0x4D, 0x6A, 0x63, 0x77, 0x4E, 0x6A, 0x49, 0x34, 0x4D, 0x7A, 0x4E, 0x61, 0x46, 0x77, 0x30, 0x7A, 0x4D, 0x44, 0x45, 0x79, ++ 0x4D, 0x7A, 0x45, 0x78, 0x4E, 0x54, 0x55, 0x35, 0x4E, 0x54, 0x6C, 0x61, 0x4D, 0x46, 0x45, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6C, 0x52, 0x58, 0x4D, 0x52, 0x49, 0x77, 0x45, 0x41, 0x59, 0x44, ++ 0x56, 0x51, 0x51, 0x4B, 0x0A, 0x45, 0x77, 0x6C, 0x55, 0x51, 0x55, 0x6C, 0x58, 0x51, 0x55, 0x34, 0x74, 0x51, 0x30, 0x45, 0x78, 0x45, 0x44, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x73, 0x54, 0x42, 0x31, 0x4A, 0x76, 0x62, 0x33, 0x51, ++ 0x67, 0x51, 0x30, 0x45, 0x78, 0x48, 0x44, 0x41, 0x61, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x45, 0x31, 0x52, 0x58, 0x51, 0x30, 0x45, 0x67, 0x52, 0x32, 0x78, 0x76, 0x59, 0x6D, 0x46, 0x73, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, ++ 0x67, 0x0A, 0x51, 0x30, 0x45, 0x77, 0x67, 0x67, 0x49, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, ++ 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x43, 0x77, 0x42, 0x64, 0x76, 0x49, 0x36, 0x34, 0x7A, 0x45, 0x62, 0x6F, 0x6F, 0x68, 0x37, 0x34, 0x35, 0x4E, 0x6E, 0x48, 0x45, 0x4B, 0x48, 0x31, 0x4A, 0x77, 0x37, 0x57, 0x32, 0x43, 0x0A, 0x6E, ++ 0x4A, 0x66, 0x46, 0x31, 0x30, 0x78, 0x4F, 0x52, 0x55, 0x6E, 0x4C, 0x51, 0x45, 0x4B, 0x31, 0x45, 0x6A, 0x52, 0x73, 0x47, 0x63, 0x4A, 0x30, 0x70, 0x44, 0x46, 0x66, 0x68, 0x51, 0x4B, 0x58, 0x37, 0x45, 0x4D, 0x7A, 0x43, 0x6C, 0x50, 0x53, 0x6E, ++ 0x49, 0x79, 0x4F, 0x74, 0x37, 0x68, 0x35, 0x32, 0x79, 0x76, 0x56, 0x61, 0x76, 0x4B, 0x4F, 0x5A, 0x73, 0x54, 0x75, 0x4B, 0x77, 0x45, 0x48, 0x6B, 0x74, 0x53, 0x7A, 0x30, 0x41, 0x4C, 0x66, 0x55, 0x50, 0x5A, 0x56, 0x0A, 0x72, 0x32, 0x59, 0x4F, ++ 0x79, 0x2B, 0x42, 0x48, 0x59, 0x43, 0x38, 0x72, 0x4D, 0x6A, 0x6B, 0x31, 0x55, 0x6A, 0x6F, 0x6F, 0x67, 0x2F, 0x68, 0x37, 0x46, 0x73, 0x59, 0x59, 0x75, 0x47, 0x4C, 0x57, 0x52, 0x79, 0x57, 0x52, 0x7A, 0x76, 0x41, 0x5A, 0x45, 0x6B, 0x32, 0x74, ++ 0x59, 0x2F, 0x58, 0x54, 0x50, 0x33, 0x56, 0x66, 0x4B, 0x66, 0x43, 0x68, 0x4D, 0x42, 0x77, 0x71, 0x6F, 0x4A, 0x69, 0x6D, 0x46, 0x62, 0x33, 0x75, 0x2F, 0x52, 0x6B, 0x32, 0x38, 0x4F, 0x4B, 0x52, 0x0A, 0x51, 0x34, 0x2F, 0x36, 0x79, 0x74, 0x59, ++ 0x51, 0x4A, 0x30, 0x6C, 0x4D, 0x37, 0x39, 0x33, 0x42, 0x38, 0x59, 0x56, 0x77, 0x6D, 0x38, 0x72, 0x71, 0x71, 0x46, 0x70, 0x44, 0x2F, 0x47, 0x32, 0x47, 0x62, 0x33, 0x50, 0x70, 0x4E, 0x30, 0x57, 0x70, 0x38, 0x44, 0x62, 0x48, 0x7A, 0x49, 0x68, ++ 0x31, 0x48, 0x72, 0x74, 0x73, 0x42, 0x76, 0x2B, 0x62, 0x61, 0x7A, 0x34, 0x58, 0x37, 0x47, 0x47, 0x71, 0x63, 0x58, 0x7A, 0x47, 0x48, 0x61, 0x4C, 0x33, 0x53, 0x65, 0x6B, 0x56, 0x0A, 0x74, 0x54, 0x7A, 0x57, 0x6F, 0x57, 0x48, 0x31, 0x45, 0x66, ++ 0x63, 0x46, 0x62, 0x78, 0x33, 0x39, 0x45, 0x62, 0x37, 0x51, 0x4D, 0x41, 0x66, 0x43, 0x4B, 0x62, 0x41, 0x4A, 0x54, 0x69, 0x62, 0x63, 0x34, 0x36, 0x4B, 0x6F, 0x6B, 0x57, 0x6F, 0x66, 0x77, 0x70, 0x46, 0x46, 0x69, 0x46, 0x7A, 0x6C, 0x6D, 0x4C, ++ 0x68, 0x78, 0x70, 0x52, 0x55, 0x5A, 0x79, 0x58, 0x78, 0x31, 0x45, 0x63, 0x78, 0x77, 0x64, 0x45, 0x38, 0x74, 0x6D, 0x78, 0x32, 0x52, 0x52, 0x50, 0x31, 0x57, 0x0A, 0x4B, 0x4B, 0x44, 0x2B, 0x75, 0x34, 0x5A, 0x71, 0x79, 0x50, 0x70, 0x63, 0x43, ++ 0x31, 0x6A, 0x63, 0x78, 0x6B, 0x74, 0x32, 0x79, 0x4B, 0x73, 0x69, 0x32, 0x58, 0x4D, 0x50, 0x70, 0x66, 0x52, 0x61, 0x41, 0x6F, 0x6B, 0x2F, 0x54, 0x35, 0x34, 0x69, 0x67, 0x75, 0x36, 0x69, 0x64, 0x46, 0x4D, 0x71, 0x50, 0x56, 0x4D, 0x6E, 0x61, ++ 0x52, 0x31, 0x73, 0x6A, 0x6A, 0x49, 0x73, 0x5A, 0x41, 0x41, 0x6D, 0x59, 0x32, 0x45, 0x32, 0x54, 0x71, 0x4E, 0x47, 0x74, 0x7A, 0x39, 0x39, 0x0A, 0x73, 0x79, 0x32, 0x73, 0x62, 0x5A, 0x43, 0x69, 0x6C, 0x61, 0x4C, 0x4F, 0x7A, 0x39, 0x71, 0x43, ++ 0x35, 0x77, 0x63, 0x30, 0x47, 0x5A, 0x62, 0x70, 0x75, 0x43, 0x47, 0x71, 0x4B, 0x58, 0x36, 0x6D, 0x4F, 0x4C, 0x36, 0x4F, 0x4B, 0x55, 0x6F, 0x68, 0x5A, 0x6E, 0x6B, 0x66, 0x73, 0x38, 0x4F, 0x31, 0x43, 0x57, 0x66, 0x65, 0x31, 0x74, 0x51, 0x48, ++ 0x52, 0x76, 0x4D, 0x71, 0x32, 0x75, 0x59, 0x69, 0x4E, 0x32, 0x44, 0x4C, 0x67, 0x62, 0x59, 0x50, 0x6F, 0x41, 0x2F, 0x70, 0x0A, 0x79, 0x4A, 0x56, 0x2F, 0x76, 0x31, 0x57, 0x52, 0x42, 0x58, 0x72, 0x50, 0x50, 0x52, 0x58, 0x41, 0x62, 0x39, 0x34, ++ 0x4A, 0x6C, 0x41, 0x47, 0x44, 0x31, 0x7A, 0x51, 0x62, 0x7A, 0x45, 0x43, 0x6C, 0x38, 0x4C, 0x69, 0x62, 0x5A, 0x39, 0x57, 0x59, 0x6B, 0x54, 0x75, 0x6E, 0x68, 0x48, 0x69, 0x56, 0x4A, 0x71, 0x52, 0x61, 0x43, 0x50, 0x67, 0x72, 0x64, 0x4C, 0x51, ++ 0x41, 0x42, 0x44, 0x7A, 0x66, 0x75, 0x42, 0x53, 0x4F, 0x36, 0x4E, 0x2B, 0x70, 0x6A, 0x57, 0x78, 0x6E, 0x0A, 0x6B, 0x6A, 0x4D, 0x64, 0x77, 0x4C, 0x66, 0x53, 0x37, 0x4A, 0x4C, 0x49, 0x76, 0x67, 0x6D, 0x2F, 0x4C, 0x43, 0x6B, 0x46, 0x62, 0x77, ++ 0x4A, 0x72, 0x6E, 0x75, 0x2B, 0x38, 0x76, 0x79, 0x71, 0x38, 0x57, 0x38, 0x42, 0x51, 0x6A, 0x30, 0x46, 0x77, 0x63, 0x59, 0x65, 0x79, 0x54, 0x62, 0x63, 0x45, 0x71, 0x59, 0x53, 0x6A, 0x4D, 0x71, 0x2B, 0x75, 0x37, 0x6D, 0x73, 0x58, 0x69, 0x37, ++ 0x4B, 0x78, 0x2F, 0x6D, 0x7A, 0x68, 0x6B, 0x49, 0x79, 0x49, 0x71, 0x4A, 0x64, 0x49, 0x0A, 0x7A, 0x73, 0x68, 0x4E, 0x79, 0x2F, 0x4D, 0x47, 0x7A, 0x31, 0x39, 0x71, 0x43, 0x6B, 0x4B, 0x78, 0x48, 0x68, 0x35, 0x33, 0x4C, 0x34, 0x36, 0x67, 0x35, ++ 0x70, 0x49, 0x4F, 0x42, 0x76, 0x77, 0x46, 0x49, 0x74, 0x49, 0x6D, 0x34, 0x54, 0x46, 0x52, 0x66, 0x54, 0x4C, 0x63, 0x44, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6F, 0x79, 0x4D, 0x77, 0x49, 0x54, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, ++ 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x0A, 0x41, 0x51, 0x59, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x4E, ++ 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x67, 0x45, 0x41, 0x58, 0x7A, 0x53, 0x42, 0x64, 0x75, 0x2B, 0x57, 0x48, 0x64, 0x58, 0x6C, 0x74, 0x64, 0x6B, 0x43, ++ 0x59, 0x34, 0x51, 0x57, 0x77, 0x61, 0x36, 0x67, 0x0A, 0x63, 0x46, 0x47, 0x6E, 0x39, 0x30, 0x78, 0x48, 0x4E, 0x63, 0x67, 0x4C, 0x31, 0x79, 0x67, 0x39, 0x69, 0x58, 0x48, 0x5A, 0x71, 0x6A, 0x4E, 0x42, 0x36, 0x68, 0x51, 0x62, 0x62, 0x43, 0x45, ++ 0x41, 0x77, 0x47, 0x78, 0x43, 0x47, 0x58, 0x36, 0x66, 0x61, 0x56, 0x73, 0x67, 0x51, 0x74, 0x2B, 0x69, 0x30, 0x74, 0x72, 0x45, 0x66, 0x4A, 0x64, 0x4C, 0x6A, 0x62, 0x44, 0x6F, 0x72, 0x4D, 0x6A, 0x75, 0x70, 0x57, 0x6B, 0x45, 0x6D, 0x51, 0x71, ++ 0x53, 0x70, 0x71, 0x73, 0x6E, 0x0A, 0x4C, 0x68, 0x70, 0x4E, 0x67, 0x62, 0x2B, 0x45, 0x31, 0x48, 0x41, 0x65, 0x72, 0x55, 0x66, 0x2B, 0x2F, 0x55, 0x71, 0x64, 0x4D, 0x2B, 0x44, 0x79, 0x75, 0x63, 0x52, 0x46, 0x43, 0x43, 0x45, 0x4B, 0x32, 0x6D, ++ 0x6C, 0x70, 0x63, 0x33, 0x49, 0x4E, 0x76, 0x6A, 0x54, 0x2B, 0x6C, 0x49, 0x75, 0x74, 0x77, 0x78, 0x34, 0x31, 0x31, 0x36, 0x4B, 0x44, 0x37, 0x2B, 0x55, 0x34, 0x78, 0x36, 0x57, 0x46, 0x48, 0x36, 0x76, 0x50, 0x4E, 0x4F, 0x77, 0x2F, 0x4B, 0x50, ++ 0x34, 0x4D, 0x0A, 0x38, 0x56, 0x65, 0x47, 0x54, 0x73, 0x6C, 0x56, 0x39, 0x78, 0x7A, 0x55, 0x32, 0x4B, 0x56, 0x39, 0x42, 0x6E, 0x70, 0x76, 0x31, 0x64, 0x38, 0x51, 0x33, 0x34, 0x46, 0x4F, 0x49, 0x57, 0x57, 0x78, 0x74, 0x75, 0x45, 0x58, 0x65, ++ 0x5A, 0x56, 0x46, 0x42, 0x73, 0x35, 0x66, 0x7A, 0x4E, 0x78, 0x47, 0x69, 0x57, 0x4E, 0x6F, 0x52, 0x49, 0x32, 0x54, 0x39, 0x47, 0x52, 0x77, 0x6F, 0x44, 0x32, 0x64, 0x4B, 0x41, 0x58, 0x44, 0x4F, 0x58, 0x43, 0x34, 0x59, 0x6E, 0x73, 0x67, 0x0A, ++ 0x2F, 0x65, 0x54, 0x62, 0x36, 0x51, 0x69, 0x68, 0x75, 0x4A, 0x34, 0x39, 0x43, 0x63, 0x64, 0x50, 0x2B, 0x79, 0x7A, 0x34, 0x6B, 0x33, 0x5A, 0x42, 0x33, 0x6C, 0x4C, 0x67, 0x34, 0x56, 0x66, 0x53, 0x6E, 0x51, 0x4F, 0x38, 0x64, 0x35, 0x37, 0x2B, ++ 0x6E, 0x69, 0x6C, 0x65, 0x39, 0x38, 0x46, 0x52, 0x59, 0x42, 0x2F, 0x65, 0x32, 0x67, 0x75, 0x79, 0x4C, 0x58, 0x57, 0x33, 0x51, 0x30, 0x69, 0x54, 0x35, 0x2F, 0x5A, 0x35, 0x78, 0x6F, 0x52, 0x64, 0x67, 0x46, 0x6C, 0x67, 0x0A, 0x6C, 0x50, 0x78, ++ 0x34, 0x6D, 0x49, 0x38, 0x38, 0x6B, 0x31, 0x48, 0x74, 0x51, 0x4A, 0x41, 0x48, 0x33, 0x32, 0x52, 0x6A, 0x4A, 0x4D, 0x74, 0x4F, 0x63, 0x51, 0x57, 0x68, 0x31, 0x35, 0x51, 0x61, 0x69, 0x44, 0x4C, 0x78, 0x49, 0x6E, 0x51, 0x69, 0x72, 0x71, 0x57, ++ 0x6D, 0x32, 0x42, 0x4A, 0x70, 0x54, 0x47, 0x43, 0x6A, 0x41, 0x75, 0x34, 0x72, 0x37, 0x4E, 0x52, 0x6A, 0x6B, 0x67, 0x74, 0x65, 0x76, 0x69, 0x39, 0x32, 0x61, 0x36, 0x4F, 0x32, 0x4A, 0x72, 0x79, 0x50, 0x0A, 0x41, 0x39, 0x67, 0x4B, 0x38, 0x6B, ++ 0x78, 0x6B, 0x52, 0x72, 0x30, 0x35, 0x59, 0x75, 0x57, 0x57, 0x36, 0x7A, 0x52, 0x6A, 0x45, 0x53, 0x6A, 0x4D, 0x6C, 0x66, 0x47, 0x74, 0x37, 0x2B, 0x2F, 0x63, 0x67, 0x46, 0x68, 0x49, 0x36, 0x55, 0x75, 0x34, 0x36, 0x6D, 0x57, 0x73, 0x36, 0x66, ++ 0x79, 0x41, 0x74, 0x62, 0x58, 0x49, 0x52, 0x66, 0x6D, 0x73, 0x77, 0x5A, 0x2F, 0x5A, 0x75, 0x65, 0x70, 0x69, 0x69, 0x49, 0x37, 0x45, 0x38, 0x55, 0x75, 0x44, 0x45, 0x71, 0x33, 0x6D, 0x0A, 0x69, 0x34, 0x54, 0x57, 0x6E, 0x73, 0x4C, 0x72, 0x67, ++ 0x78, 0x69, 0x66, 0x61, 0x72, 0x73, 0x62, 0x4A, 0x47, 0x41, 0x7A, 0x63, 0x4D, 0x7A, 0x73, 0x39, 0x7A, 0x4C, 0x7A, 0x58, 0x4E, 0x6C, 0x35, 0x66, 0x65, 0x2B, 0x65, 0x70, 0x50, 0x37, 0x4A, 0x49, 0x38, 0x4D, 0x6B, 0x37, 0x68, 0x57, 0x53, 0x73, ++ 0x54, 0x32, 0x52, 0x54, 0x79, 0x61, 0x47, 0x76, 0x57, 0x5A, 0x7A, 0x4A, 0x42, 0x50, 0x71, 0x70, 0x4B, 0x35, 0x6A, 0x77, 0x61, 0x31, 0x39, 0x68, 0x41, 0x4D, 0x38, 0x0A, 0x45, 0x48, 0x69, 0x47, 0x47, 0x33, 0x6E, 0x6A, 0x78, 0x50, 0x50, 0x79, ++ 0x42, 0x4A, 0x55, 0x67, 0x72, 0x69, 0x4F, 0x43, 0x78, 0x4C, 0x4D, 0x36, 0x41, 0x47, 0x4B, 0x2F, 0x35, 0x6A, 0x59, 0x6B, 0x34, 0x56, 0x65, 0x36, 0x78, 0x78, 0x36, 0x51, 0x64, 0x64, 0x56, 0x66, 0x50, 0x35, 0x56, 0x68, 0x4B, 0x38, 0x45, 0x37, ++ 0x7A, 0x65, 0x57, 0x7A, 0x61, 0x47, 0x48, 0x51, 0x52, 0x69, 0x61, 0x70, 0x49, 0x56, 0x4A, 0x70, 0x4C, 0x65, 0x73, 0x75, 0x78, 0x2B, 0x74, 0x33, 0x0A, 0x7A, 0x71, 0x59, 0x36, 0x74, 0x51, 0x4D, 0x7A, 0x54, 0x33, 0x62, 0x52, 0x35, 0x31, 0x78, ++ 0x55, 0x41, 0x56, 0x33, 0x4C, 0x65, 0x50, 0x54, 0x4A, 0x44, 0x4C, 0x2F, 0x50, 0x45, 0x6F, 0x34, 0x58, 0x4C, 0x53, 0x4E, 0x6F, 0x6C, 0x4F, 0x65, 0x72, 0x2F, 0x71, 0x6D, 0x79, 0x4B, 0x77, 0x62, 0x51, 0x42, 0x4D, 0x30, 0x3D, 0x0A, 0x2D, 0x2D, ++ 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x53, 0x6F, 0x6E, 0x65, 0x72, 0x61, 0x20, 0x52, 0x6F, 0x6F, ++ 0x74, 0x20, 0x43, 0x41, 0x20, 0x76, 0x31, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, ++ 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x4F, 0x44, 0x43, 0x43, 0x41, 0x79, 0x43, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x52, 0x41, ++ 0x4A, 0x57, 0x2B, 0x46, 0x71, 0x44, 0x33, 0x4C, 0x6B, 0x62, 0x78, 0x65, 0x7A, 0x6D, 0x43, 0x63, 0x76, 0x71, 0x4C, 0x7A, 0x5A, 0x59, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x46, 0x42, ++ 0x51, 0x41, 0x77, 0x4E, 0x7A, 0x45, 0x55, 0x4D, 0x42, 0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0A, 0x43, 0x67, 0x77, 0x4C, 0x56, 0x47, 0x56, 0x73, 0x61, 0x57, 0x46, 0x54, 0x62, 0x32, 0x35, 0x6C, 0x63, 0x6D, 0x45, 0x78, 0x48, 0x7A, 0x41, 0x64, ++ 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x46, 0x6C, 0x52, 0x6C, 0x62, 0x47, 0x6C, 0x68, 0x55, 0x32, 0x39, 0x75, 0x5A, 0x58, 0x4A, 0x68, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x64, 0x6A, 0x45, 0x77, ++ 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x44, 0x63, 0x78, 0x4D, 0x44, 0x45, 0x34, 0x0A, 0x4D, 0x54, 0x49, 0x77, 0x4D, 0x44, 0x55, 0x77, 0x57, 0x68, 0x63, 0x4E, 0x4D, 0x7A, 0x49, 0x78, 0x4D, 0x44, 0x45, 0x34, 0x4D, 0x54, 0x49, 0x77, 0x4D, 0x44, 0x55, ++ 0x77, 0x57, 0x6A, 0x41, 0x33, 0x4D, 0x52, 0x51, 0x77, 0x45, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x44, 0x41, 0x74, 0x55, 0x5A, 0x57, 0x78, 0x70, 0x59, 0x56, 0x4E, 0x76, 0x62, 0x6D, 0x56, 0x79, 0x59, 0x54, 0x45, 0x66, 0x4D, 0x42, 0x30, ++ 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x57, 0x0A, 0x56, 0x47, 0x56, 0x73, 0x61, 0x57, 0x46, 0x54, 0x62, 0x32, 0x35, 0x6C, 0x63, 0x6D, 0x45, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x53, 0x42, 0x32, 0x4D, 0x54, ++ 0x43, 0x43, 0x41, 0x69, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x67, 0x6F, 0x43, 0x67, 0x67, ++ 0x49, 0x42, 0x41, 0x4D, 0x4B, 0x2B, 0x0A, 0x36, 0x79, 0x66, 0x77, 0x49, 0x61, 0x50, 0x7A, 0x61, 0x53, 0x5A, 0x56, 0x66, 0x70, 0x33, 0x46, 0x56, 0x52, 0x61, 0x52, 0x58, 0x50, 0x33, 0x76, 0x49, 0x62, 0x39, 0x54, 0x67, 0x48, 0x6F, 0x74, 0x30, ++ 0x70, 0x47, 0x4D, 0x59, 0x7A, 0x48, 0x77, 0x37, 0x43, 0x54, 0x77, 0x77, 0x36, 0x58, 0x53, 0x63, 0x6E, 0x77, 0x51, 0x62, 0x66, 0x51, 0x33, 0x74, 0x2B, 0x58, 0x6D, 0x66, 0x48, 0x6E, 0x71, 0x6A, 0x4C, 0x57, 0x43, 0x69, 0x36, 0x35, 0x49, 0x74, ++ 0x71, 0x77, 0x41, 0x0A, 0x33, 0x47, 0x56, 0x31, 0x37, 0x43, 0x70, 0x4E, 0x58, 0x38, 0x47, 0x48, 0x39, 0x53, 0x42, 0x6C, 0x4B, 0x34, 0x47, 0x6F, 0x52, 0x7A, 0x36, 0x4A, 0x49, 0x35, 0x55, 0x77, 0x46, 0x70, 0x42, 0x2F, 0x36, 0x46, 0x63, 0x48, ++ 0x53, 0x4F, 0x63, 0x5A, 0x72, 0x72, 0x39, 0x46, 0x5A, 0x37, 0x45, 0x33, 0x47, 0x77, 0x59, 0x71, 0x2F, 0x74, 0x37, 0x35, 0x72, 0x48, 0x32, 0x44, 0x2B, 0x31, 0x36, 0x36, 0x35, 0x49, 0x2B, 0x58, 0x5A, 0x37, 0x35, 0x4C, 0x6A, 0x6F, 0x31, 0x6B, ++ 0x0A, 0x42, 0x31, 0x63, 0x34, 0x56, 0x57, 0x6B, 0x30, 0x4E, 0x6A, 0x30, 0x54, 0x53, 0x4F, 0x39, 0x50, 0x34, 0x74, 0x4E, 0x6D, 0x48, 0x71, 0x54, 0x50, 0x47, 0x72, 0x64, 0x65, 0x4E, 0x6A, 0x50, 0x55, 0x74, 0x41, 0x61, 0x39, 0x47, 0x41, 0x48, ++ 0x39, 0x64, 0x34, 0x52, 0x51, 0x41, 0x45, 0x58, 0x31, 0x6A, 0x46, 0x33, 0x6F, 0x49, 0x37, 0x78, 0x2B, 0x2F, 0x6A, 0x58, 0x68, 0x37, 0x56, 0x42, 0x37, 0x71, 0x54, 0x43, 0x4E, 0x47, 0x64, 0x4D, 0x4A, 0x6A, 0x6D, 0x68, 0x6E, 0x0A, 0x58, 0x62, ++ 0x38, 0x38, 0x6C, 0x78, 0x68, 0x54, 0x75, 0x79, 0x6C, 0x69, 0x78, 0x63, 0x70, 0x65, 0x63, 0x73, 0x48, 0x48, 0x6C, 0x74, 0x54, 0x62, 0x4C, 0x61, 0x43, 0x30, 0x48, 0x32, 0x6B, 0x44, 0x37, 0x4F, 0x72, 0x69, 0x55, 0x50, 0x45, 0x4D, 0x50, 0x50, ++ 0x43, 0x73, 0x38, 0x31, 0x4D, 0x74, 0x38, 0x42, 0x7A, 0x31, 0x37, 0x57, 0x77, 0x35, 0x4F, 0x58, 0x4F, 0x41, 0x46, 0x73, 0x68, 0x53, 0x73, 0x43, 0x50, 0x4E, 0x34, 0x44, 0x37, 0x63, 0x33, 0x54, 0x78, 0x48, 0x0A, 0x6F, 0x4C, 0x73, 0x31, 0x69, ++ 0x75, 0x4B, 0x59, 0x61, 0x49, 0x75, 0x2B, 0x35, 0x62, 0x39, 0x79, 0x37, 0x74, 0x4C, 0x36, 0x70, 0x65, 0x30, 0x53, 0x37, 0x66, 0x79, 0x59, 0x47, 0x4B, 0x6B, 0x6D, 0x64, 0x74, 0x77, 0x6F, 0x53, 0x78, 0x41, 0x67, 0x48, 0x4E, 0x4E, 0x2F, 0x46, ++ 0x6E, 0x63, 0x74, 0x37, 0x57, 0x2B, 0x41, 0x39, 0x30, 0x6D, 0x37, 0x55, 0x77, 0x57, 0x37, 0x58, 0x57, 0x6A, 0x48, 0x31, 0x4D, 0x68, 0x31, 0x46, 0x6A, 0x2B, 0x4A, 0x57, 0x6F, 0x76, 0x33, 0x0A, 0x46, 0x30, 0x66, 0x55, 0x54, 0x50, 0x48, 0x53, ++ 0x69, 0x58, 0x6B, 0x2B, 0x54, 0x54, 0x32, 0x59, 0x71, 0x47, 0x48, 0x65, 0x4F, 0x68, 0x37, 0x53, 0x2B, 0x46, 0x34, 0x44, 0x34, 0x4D, 0x48, 0x4A, 0x48, 0x49, 0x7A, 0x54, 0x6A, 0x55, 0x33, 0x54, 0x6C, 0x54, 0x61, 0x7A, 0x4E, 0x31, 0x39, 0x6A, ++ 0x59, 0x35, 0x73, 0x7A, 0x46, 0x50, 0x41, 0x74, 0x4A, 0x6D, 0x74, 0x54, 0x66, 0x49, 0x6D, 0x4D, 0x4D, 0x73, 0x4A, 0x75, 0x37, 0x44, 0x30, 0x68, 0x41, 0x44, 0x6E, 0x4A, 0x0A, 0x6F, 0x57, 0x6A, 0x69, 0x55, 0x49, 0x4D, 0x75, 0x73, 0x44, 0x6F, ++ 0x72, 0x38, 0x7A, 0x61, 0x67, 0x72, 0x43, 0x2F, 0x6B, 0x62, 0x32, 0x48, 0x43, 0x55, 0x51, 0x6B, 0x35, 0x50, 0x6F, 0x74, 0x54, 0x75, 0x62, 0x74, 0x6E, 0x32, 0x74, 0x78, 0x54, 0x75, 0x58, 0x5A, 0x5A, 0x4E, 0x70, 0x31, 0x44, 0x35, 0x53, 0x44, ++ 0x67, 0x50, 0x54, 0x4A, 0x67, 0x68, 0x53, 0x4A, 0x52, 0x74, 0x38, 0x63, 0x7A, 0x75, 0x39, 0x30, 0x56, 0x4C, 0x36, 0x52, 0x34, 0x70, 0x67, 0x64, 0x37, 0x0A, 0x67, 0x55, 0x59, 0x32, 0x42, 0x49, 0x62, 0x64, 0x65, 0x54, 0x58, 0x48, 0x6C, 0x53, ++ 0x77, 0x37, 0x73, 0x4B, 0x4D, 0x58, 0x4E, 0x65, 0x56, 0x7A, 0x48, 0x37, 0x52, 0x63, 0x57, 0x65, 0x2F, 0x61, 0x36, 0x68, 0x42, 0x6C, 0x65, 0x33, 0x72, 0x51, 0x66, 0x35, 0x2B, 0x7A, 0x74, 0x43, 0x6F, 0x33, 0x4F, 0x33, 0x43, 0x4C, 0x6D, 0x31, ++ 0x75, 0x35, 0x4B, 0x37, 0x66, 0x73, 0x73, 0x6C, 0x45, 0x53, 0x6C, 0x31, 0x4D, 0x70, 0x57, 0x74, 0x54, 0x77, 0x45, 0x68, 0x44, 0x63, 0x0A, 0x54, 0x77, 0x4B, 0x37, 0x45, 0x70, 0x49, 0x76, 0x59, 0x74, 0x51, 0x2F, 0x61, 0x55, 0x4E, 0x38, 0x44, ++ 0x64, 0x62, 0x38, 0x57, 0x48, 0x55, 0x42, 0x69, 0x4A, 0x31, 0x59, 0x46, 0x6B, 0x76, 0x65, 0x75, 0x70, 0x44, 0x2F, 0x52, 0x77, 0x47, 0x4A, 0x42, 0x6D, 0x72, 0x32, 0x58, 0x37, 0x4B, 0x51, 0x61, 0x72, 0x4D, 0x43, 0x70, 0x67, 0x4B, 0x49, 0x76, ++ 0x37, 0x4E, 0x48, 0x66, 0x69, 0x72, 0x5A, 0x31, 0x66, 0x70, 0x6F, 0x65, 0x44, 0x56, 0x4E, 0x41, 0x67, 0x4D, 0x42, 0x0A, 0x41, 0x41, 0x47, 0x6A, 0x50, 0x7A, 0x41, 0x39, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, ++ 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x43, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, ++ 0x42, 0x42, 0x54, 0x77, 0x6A, 0x31, 0x6B, 0x34, 0x41, 0x4C, 0x50, 0x31, 0x6A, 0x35, 0x71, 0x57, 0x0A, 0x44, 0x4E, 0x58, 0x72, 0x2B, 0x6E, 0x75, 0x71, 0x46, 0x2B, 0x67, 0x54, 0x45, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, ++ 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x67, 0x45, 0x41, 0x76, 0x75, 0x52, 0x63, 0x59, 0x6B, 0x34, 0x6B, 0x39, 0x41, 0x77, 0x49, 0x2F, 0x2F, 0x44, 0x54, 0x44, 0x47, 0x6A, 0x6B, 0x6B, 0x30, 0x6B, ++ 0x69, 0x50, 0x30, 0x51, 0x6E, 0x62, 0x37, 0x74, 0x74, 0x33, 0x6F, 0x4E, 0x6D, 0x0A, 0x7A, 0x71, 0x6A, 0x4D, 0x44, 0x66, 0x7A, 0x31, 0x6D, 0x67, 0x62, 0x6C, 0x64, 0x78, 0x53, 0x52, 0x36, 0x35, 0x31, 0x42, 0x65, 0x35, 0x6B, 0x71, 0x68, 0x4F, ++ 0x58, 0x2F, 0x2F, 0x43, 0x48, 0x42, 0x58, 0x66, 0x44, 0x6B, 0x48, 0x31, 0x65, 0x33, 0x64, 0x61, 0x6D, 0x68, 0x58, 0x77, 0x49, 0x6D, 0x2F, 0x39, 0x66, 0x48, 0x39, 0x30, 0x37, 0x65, 0x54, 0x2F, 0x6A, 0x33, 0x48, 0x45, 0x62, 0x41, 0x65, 0x6B, ++ 0x39, 0x41, 0x4C, 0x43, 0x49, 0x31, 0x38, 0x42, 0x6D, 0x78, 0x0A, 0x30, 0x47, 0x74, 0x6E, 0x4C, 0x4C, 0x43, 0x6F, 0x34, 0x4D, 0x42, 0x41, 0x4E, 0x7A, 0x58, 0x32, 0x68, 0x46, 0x78, 0x63, 0x34, 0x36, 0x39, 0x43, 0x65, 0x50, 0x36, 0x6E, 0x79, ++ 0x51, 0x31, 0x51, 0x36, 0x67, 0x32, 0x45, 0x64, 0x76, 0x5A, 0x52, 0x37, 0x34, 0x4E, 0x54, 0x78, 0x6E, 0x72, 0x2F, 0x44, 0x6C, 0x5A, 0x4A, 0x4C, 0x6F, 0x39, 0x36, 0x31, 0x67, 0x7A, 0x6D, 0x4A, 0x31, 0x54, 0x6A, 0x54, 0x51, 0x70, 0x67, 0x63, ++ 0x6D, 0x4C, 0x4E, 0x6B, 0x51, 0x66, 0x57, 0x0A, 0x70, 0x62, 0x2F, 0x49, 0x6D, 0x57, 0x76, 0x74, 0x78, 0x42, 0x6E, 0x6D, 0x71, 0x30, 0x77, 0x52, 0x4F, 0x4D, 0x56, 0x76, 0x4D, 0x65, 0x4A, 0x75, 0x53, 0x63, 0x67, 0x2F, 0x64, 0x6F, 0x41, 0x6D, ++ 0x41, 0x79, 0x59, 0x70, 0x34, 0x44, 0x62, 0x32, 0x39, 0x69, 0x42, 0x54, 0x34, 0x78, 0x64, 0x77, 0x4E, 0x42, 0x65, 0x64, 0x59, 0x32, 0x67, 0x65, 0x61, 0x2B, 0x7A, 0x44, 0x54, 0x59, 0x61, 0x34, 0x45, 0x7A, 0x41, 0x76, 0x58, 0x55, 0x59, 0x4E, ++ 0x52, 0x30, 0x50, 0x56, 0x0A, 0x47, 0x36, 0x70, 0x5A, 0x44, 0x72, 0x6C, 0x63, 0x6A, 0x51, 0x5A, 0x49, 0x72, 0x58, 0x53, 0x48, 0x58, 0x38, 0x66, 0x38, 0x4D, 0x56, 0x52, 0x42, 0x45, 0x2B, 0x4C, 0x48, 0x49, 0x51, 0x36, 0x65, 0x34, 0x42, 0x34, ++ 0x4E, 0x34, 0x63, 0x42, 0x37, 0x51, 0x34, 0x57, 0x51, 0x78, 0x59, 0x70, 0x59, 0x78, 0x6D, 0x55, 0x4B, 0x65, 0x46, 0x66, 0x79, 0x78, 0x69, 0x4D, 0x50, 0x41, 0x64, 0x6B, 0x67, 0x53, 0x39, 0x34, 0x50, 0x2B, 0x35, 0x4B, 0x46, 0x64, 0x53, 0x70, ++ 0x63, 0x0A, 0x63, 0x34, 0x31, 0x74, 0x65, 0x79, 0x57, 0x52, 0x79, 0x75, 0x35, 0x46, 0x72, 0x67, 0x5A, 0x4C, 0x41, 0x4D, 0x7A, 0x54, 0x73, 0x56, 0x6C, 0x51, 0x32, 0x6A, 0x71, 0x49, 0x4F, 0x79, 0x6C, 0x44, 0x52, 0x6C, 0x36, 0x58, 0x4B, 0x31, ++ 0x54, 0x4F, 0x55, 0x32, 0x2B, 0x4E, 0x53, 0x75, 0x65, 0x57, 0x2B, 0x72, 0x39, 0x78, 0x44, 0x6B, 0x4B, 0x4C, 0x66, 0x50, 0x30, 0x6F, 0x6F, 0x4E, 0x42, 0x49, 0x79, 0x74, 0x72, 0x45, 0x67, 0x55, 0x79, 0x37, 0x6F, 0x6E, 0x4F, 0x54, 0x0A, 0x4A, ++ 0x73, 0x6A, 0x72, 0x44, 0x4E, 0x59, 0x6D, 0x69, 0x4C, 0x62, 0x41, 0x4A, 0x4D, 0x2B, 0x37, 0x76, 0x56, 0x76, 0x72, 0x64, 0x58, 0x33, 0x70, 0x43, 0x49, 0x36, 0x47, 0x4D, 0x79, 0x78, 0x35, 0x64, 0x77, 0x6C, 0x70, 0x70, 0x59, 0x6E, 0x38, 0x73, ++ 0x33, 0x43, 0x51, 0x68, 0x33, 0x61, 0x50, 0x30, 0x79, 0x4B, 0x37, 0x51, 0x73, 0x36, 0x39, 0x63, 0x77, 0x73, 0x67, 0x4A, 0x69, 0x72, 0x51, 0x6D, 0x7A, 0x31, 0x77, 0x48, 0x69, 0x52, 0x73, 0x7A, 0x59, 0x64, 0x32, 0x0A, 0x71, 0x52, 0x65, 0x57, ++ 0x74, 0x38, 0x38, 0x4E, 0x6B, 0x76, 0x75, 0x4F, 0x47, 0x4B, 0x6D, 0x59, 0x53, 0x64, 0x47, 0x65, 0x2F, 0x6D, 0x42, 0x45, 0x63, 0x69, 0x47, 0x35, 0x47, 0x65, 0x33, 0x43, 0x39, 0x54, 0x48, 0x78, 0x4F, 0x55, 0x69, 0x49, 0x6B, 0x43, 0x52, 0x31, ++ 0x56, 0x42, 0x61, 0x74, 0x7A, 0x76, 0x54, 0x34, 0x61, 0x52, 0x52, 0x6B, 0x4F, 0x66, 0x75, 0x6A, 0x75, 0x4C, 0x70, 0x77, 0x51, 0x4D, 0x63, 0x6E, 0x48, 0x4C, 0x2F, 0x45, 0x56, 0x6C, 0x50, 0x36, 0x0A, 0x59, 0x32, 0x58, 0x51, 0x38, 0x78, 0x77, ++ 0x4F, 0x46, 0x76, 0x56, 0x72, 0x68, 0x6C, 0x68, 0x4E, 0x47, 0x4E, 0x54, 0x6B, 0x44, 0x59, 0x36, 0x6C, 0x6E, 0x56, 0x75, 0x52, 0x33, 0x48, 0x59, 0x6B, 0x55, 0x44, 0x2F, 0x47, 0x4B, 0x76, 0x76, 0x5A, 0x74, 0x35, 0x79, 0x31, 0x31, 0x75, 0x62, ++ 0x51, 0x32, 0x65, 0x67, 0x5A, 0x69, 0x78, 0x56, 0x78, 0x53, 0x4B, 0x32, 0x33, 0x36, 0x74, 0x68, 0x5A, 0x69, 0x4E, 0x53, 0x51, 0x76, 0x78, 0x61, 0x7A, 0x32, 0x65, 0x6D, 0x73, 0x0A, 0x57, 0x57, 0x46, 0x55, 0x79, 0x42, 0x79, 0x36, 0x79, 0x73, ++ 0x48, 0x4B, 0x34, 0x62, 0x6B, 0x67, 0x54, 0x49, 0x38, 0x36, 0x6B, 0x34, 0x6D, 0x6C, 0x6F, 0x4D, 0x79, 0x2F, 0x30, 0x2F, 0x5A, 0x31, 0x70, 0x48, 0x57, 0x57, 0x62, 0x56, 0x59, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, ++ 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x54, 0x2D, 0x54, 0x65, 0x6C, 0x65, 0x53, 0x65, 0x63, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, ++ 0x6C, 0x61, 0x73, 0x73, 0x20, 0x32, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x44, 0x77, 0x7A, 0x43, 0x43, 0x41, 0x71, 0x75, 0x67, 0x41, 0x77, 0x49, 0x42, ++ 0x41, 0x67, 0x49, 0x42, 0x41, 0x54, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x43, 0x42, 0x67, 0x6A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, ++ 0x42, 0x68, 0x4D, 0x43, 0x52, 0x45, 0x55, 0x78, 0x4B, 0x7A, 0x41, 0x70, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x0A, 0x49, 0x6C, 0x51, 0x74, 0x55, 0x33, 0x6C, 0x7A, 0x64, 0x47, 0x56, 0x74, 0x63, 0x79, 0x42, 0x46, 0x62, 0x6E, 0x52, ++ 0x6C, 0x63, 0x6E, 0x42, 0x79, 0x61, 0x58, 0x4E, 0x6C, 0x49, 0x46, 0x4E, 0x6C, 0x63, 0x6E, 0x5A, 0x70, 0x59, 0x32, 0x56, 0x7A, 0x49, 0x45, 0x64, 0x74, 0x59, 0x6B, 0x67, 0x78, 0x48, 0x7A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x73, ++ 0x4D, 0x46, 0x6C, 0x51, 0x74, 0x55, 0x33, 0x6C, 0x7A, 0x64, 0x47, 0x56, 0x74, 0x63, 0x79, 0x42, 0x55, 0x0A, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x43, 0x42, 0x44, 0x5A, 0x57, 0x35, 0x30, 0x5A, 0x58, 0x49, 0x78, 0x4A, 0x54, 0x41, 0x6A, 0x42, 0x67, ++ 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x48, 0x46, 0x51, 0x74, 0x56, 0x47, 0x56, 0x73, 0x5A, 0x56, 0x4E, 0x6C, 0x59, 0x79, 0x42, 0x48, 0x62, 0x47, 0x39, 0x69, 0x59, 0x57, 0x78, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x73, 0x59, 0x58, ++ 0x4E, 0x7A, 0x49, 0x44, 0x49, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x44, 0x67, 0x78, 0x0A, 0x4D, 0x44, 0x41, 0x78, 0x4D, 0x54, 0x41, 0x30, 0x4D, 0x44, 0x45, 0x30, 0x57, 0x68, 0x63, 0x4E, 0x4D, 0x7A, 0x4D, 0x78, 0x4D, 0x44, 0x41, 0x78, 0x4D, ++ 0x6A, 0x4D, 0x31, 0x4F, 0x54, 0x55, 0x35, 0x57, 0x6A, 0x43, 0x42, 0x67, 0x6A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x52, 0x45, 0x55, 0x78, 0x4B, 0x7A, 0x41, 0x70, 0x42, 0x67, 0x4E, 0x56, 0x42, ++ 0x41, 0x6F, 0x4D, 0x49, 0x6C, 0x51, 0x74, 0x55, 0x33, 0x6C, 0x7A, 0x0A, 0x64, 0x47, 0x56, 0x74, 0x63, 0x79, 0x42, 0x46, 0x62, 0x6E, 0x52, 0x6C, 0x63, 0x6E, 0x42, 0x79, 0x61, 0x58, 0x4E, 0x6C, 0x49, 0x46, 0x4E, 0x6C, 0x63, 0x6E, 0x5A, 0x70, ++ 0x59, 0x32, 0x56, 0x7A, 0x49, 0x45, 0x64, 0x74, 0x59, 0x6B, 0x67, 0x78, 0x48, 0x7A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x73, 0x4D, 0x46, 0x6C, 0x51, 0x74, 0x55, 0x33, 0x6C, 0x7A, 0x64, 0x47, 0x56, 0x74, 0x63, 0x79, 0x42, 0x55, ++ 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x43, 0x42, 0x44, 0x0A, 0x5A, 0x57, 0x35, 0x30, 0x5A, 0x58, 0x49, 0x78, 0x4A, 0x54, 0x41, 0x6A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x48, 0x46, 0x51, 0x74, 0x56, 0x47, 0x56, 0x73, 0x5A, 0x56, 0x4E, ++ 0x6C, 0x59, 0x79, 0x42, 0x48, 0x62, 0x47, 0x39, 0x69, 0x59, 0x57, 0x78, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x73, 0x59, 0x58, 0x4E, 0x7A, 0x49, 0x44, 0x49, 0x77, 0x67, 0x67, 0x45, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, ++ 0x47, 0x53, 0x49, 0x62, 0x33, 0x0A, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x45, 0x4B, 0x41, 0x6F, 0x49, 0x42, 0x41, 0x51, 0x43, 0x71, 0x58, 0x39, 0x6F, 0x62, 0x58, 0x2B, ++ 0x68, 0x7A, 0x6B, 0x65, 0x58, 0x61, 0x58, 0x50, 0x53, 0x69, 0x35, 0x6B, 0x66, 0x6C, 0x38, 0x32, 0x68, 0x56, 0x59, 0x41, 0x55, 0x64, 0x41, 0x71, 0x53, 0x7A, 0x6D, 0x31, 0x6E, 0x7A, 0x48, 0x6F, 0x71, 0x76, 0x4E, 0x4B, 0x33, 0x38, 0x44, 0x63, ++ 0x4C, 0x5A, 0x0A, 0x53, 0x42, 0x6E, 0x75, 0x61, 0x59, 0x2F, 0x4A, 0x49, 0x50, 0x77, 0x68, 0x71, 0x67, 0x63, 0x5A, 0x37, 0x62, 0x42, 0x63, 0x72, 0x47, 0x58, 0x48, 0x58, 0x2B, 0x30, 0x43, 0x66, 0x48, 0x74, 0x38, 0x4C, 0x52, 0x76, 0x57, 0x75, ++ 0x72, 0x6D, 0x41, 0x77, 0x68, 0x69, 0x43, 0x46, 0x6F, 0x54, 0x36, 0x5A, 0x72, 0x41, 0x49, 0x78, 0x6C, 0x51, 0x6A, 0x67, 0x65, 0x54, 0x4E, 0x75, 0x55, 0x6B, 0x2F, 0x39, 0x6B, 0x39, 0x75, 0x4E, 0x30, 0x67, 0x6F, 0x4F, 0x41, 0x2F, 0x46, 0x0A, ++ 0x76, 0x75, 0x64, 0x6F, 0x63, 0x50, 0x30, 0x35, 0x6C, 0x30, 0x33, 0x53, 0x78, 0x35, 0x69, 0x52, 0x55, 0x4B, 0x72, 0x45, 0x52, 0x4C, 0x4D, 0x6A, 0x66, 0x54, 0x6C, 0x48, 0x36, 0x56, 0x4A, 0x69, 0x31, 0x68, 0x4B, 0x54, 0x58, 0x72, 0x63, 0x78, ++ 0x6C, 0x6B, 0x49, 0x46, 0x2B, 0x33, 0x61, 0x6E, 0x48, 0x71, 0x50, 0x31, 0x77, 0x76, 0x7A, 0x70, 0x65, 0x73, 0x56, 0x73, 0x71, 0x58, 0x46, 0x50, 0x36, 0x73, 0x74, 0x34, 0x76, 0x47, 0x43, 0x76, 0x78, 0x39, 0x37, 0x30, 0x0A, 0x32, 0x63, 0x75, ++ 0x2B, 0x66, 0x6A, 0x4F, 0x6C, 0x62, 0x70, 0x53, 0x44, 0x38, 0x44, 0x54, 0x36, 0x49, 0x61, 0x76, 0x71, 0x6A, 0x6E, 0x4B, 0x67, 0x50, 0x36, 0x54, 0x65, 0x4D, 0x46, 0x76, 0x76, 0x68, 0x6B, 0x31, 0x71, 0x6C, 0x56, 0x74, 0x44, 0x52, 0x4B, 0x67, ++ 0x51, 0x46, 0x52, 0x7A, 0x6C, 0x41, 0x56, 0x66, 0x46, 0x6D, 0x50, 0x48, 0x6D, 0x42, 0x69, 0x69, 0x52, 0x71, 0x69, 0x44, 0x46, 0x74, 0x31, 0x4D, 0x6D, 0x55, 0x55, 0x4F, 0x79, 0x43, 0x78, 0x47, 0x56, 0x0A, 0x57, 0x4F, 0x48, 0x41, 0x44, 0x33, ++ 0x62, 0x5A, 0x77, 0x49, 0x31, 0x38, 0x67, 0x66, 0x4E, 0x79, 0x63, 0x4A, 0x35, 0x76, 0x2F, 0x68, 0x71, 0x4F, 0x32, 0x56, 0x38, 0x31, 0x78, 0x72, 0x4A, 0x76, 0x4E, 0x48, 0x79, 0x2B, 0x53, 0x45, 0x2F, 0x69, 0x57, 0x6A, 0x6E, 0x58, 0x32, 0x4A, ++ 0x31, 0x34, 0x6E, 0x70, 0x2B, 0x47, 0x50, 0x67, 0x4E, 0x65, 0x47, 0x59, 0x74, 0x45, 0x6F, 0x74, 0x58, 0x48, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, 0x51, 0x6A, 0x42, 0x41, 0x0A, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, ++ 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4D, 0x42, 0x30, 0x47, 0x41, ++ 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x53, 0x2F, 0x57, 0x53, 0x41, 0x32, 0x41, 0x48, 0x6D, 0x67, 0x6F, 0x43, 0x4A, 0x72, 0x6A, 0x4E, 0x58, 0x79, 0x0A, 0x59, 0x64, 0x4B, 0x34, 0x4C, 0x4D, 0x75, 0x43, 0x53, 0x6A, 0x41, 0x4E, ++ 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x51, 0x45, 0x41, 0x4D, 0x51, 0x4F, 0x69, 0x59, 0x51, 0x73, 0x66, 0x64, 0x4F, 0x68, 0x79, 0x4E, 0x73, 0x5A, 0x74, ++ 0x2B, 0x55, 0x32, 0x65, 0x2B, 0x69, 0x4B, 0x6F, 0x34, 0x59, 0x46, 0x57, 0x7A, 0x38, 0x32, 0x37, 0x6E, 0x2B, 0x71, 0x72, 0x6B, 0x52, 0x6B, 0x34, 0x0A, 0x72, 0x36, 0x70, 0x38, 0x46, 0x55, 0x33, 0x7A, 0x74, 0x71, 0x4F, 0x4E, 0x70, 0x66, 0x53, ++ 0x4F, 0x39, 0x6B, 0x53, 0x70, 0x70, 0x2B, 0x67, 0x68, 0x6C, 0x61, 0x30, 0x2B, 0x41, 0x47, 0x49, 0x57, 0x69, 0x50, 0x41, 0x43, 0x75, 0x76, 0x78, 0x68, 0x49, 0x2B, 0x59, 0x7A, 0x6D, 0x7A, 0x42, 0x36, 0x61, 0x7A, 0x5A, 0x69, 0x65, 0x36, 0x30, ++ 0x45, 0x49, 0x34, 0x52, 0x59, 0x5A, 0x65, 0x4C, 0x62, 0x4B, 0x34, 0x72, 0x6E, 0x4A, 0x56, 0x4D, 0x33, 0x59, 0x6C, 0x4E, 0x66, 0x0A, 0x76, 0x4E, 0x6F, 0x42, 0x59, 0x69, 0x6D, 0x69, 0x70, 0x69, 0x64, 0x78, 0x35, 0x6A, 0x6F, 0x69, 0x66, 0x73, ++ 0x46, 0x76, 0x48, 0x5A, 0x56, 0x77, 0x49, 0x45, 0x6F, 0x48, 0x4E, 0x4E, 0x2F, 0x71, 0x2F, 0x78, 0x57, 0x41, 0x35, 0x62, 0x72, 0x58, 0x65, 0x74, 0x68, 0x62, 0x64, 0x58, 0x77, 0x46, 0x65, 0x69, 0x6C, 0x48, 0x66, 0x6B, 0x43, 0x6F, 0x4D, 0x52, ++ 0x4E, 0x33, 0x7A, 0x55, 0x41, 0x37, 0x74, 0x46, 0x46, 0x48, 0x65, 0x69, 0x34, 0x52, 0x34, 0x30, 0x63, 0x52, 0x0A, 0x33, 0x70, 0x31, 0x6D, 0x30, 0x49, 0x76, 0x56, 0x56, 0x47, 0x62, 0x36, 0x67, 0x31, 0x58, 0x71, 0x66, 0x4D, 0x49, 0x70, 0x69, ++ 0x52, 0x76, 0x70, 0x62, 0x37, 0x50, 0x4F, 0x34, 0x67, 0x57, 0x45, 0x79, 0x53, 0x38, 0x2B, 0x65, 0x49, 0x56, 0x69, 0x62, 0x73, 0x6C, 0x66, 0x77, 0x58, 0x68, 0x6A, 0x64, 0x46, 0x6A, 0x41, 0x53, 0x42, 0x67, 0x4D, 0x6D, 0x54, 0x6E, 0x72, 0x70, ++ 0x4D, 0x77, 0x61, 0x74, 0x58, 0x6C, 0x61, 0x6A, 0x52, 0x57, 0x63, 0x32, 0x42, 0x51, 0x4E, 0x0A, 0x39, 0x6E, 0x6F, 0x48, 0x56, 0x38, 0x63, 0x69, 0x67, 0x77, 0x55, 0x74, 0x50, 0x4A, 0x73, 0x6C, 0x4A, 0x6A, 0x30, 0x59, 0x73, 0x36, 0x6C, 0x44, ++ 0x66, 0x4D, 0x6A, 0x49, 0x71, 0x32, 0x53, 0x50, 0x44, 0x71, 0x4F, 0x2F, 0x6E, 0x42, 0x75, 0x64, 0x4D, 0x4E, 0x76, 0x61, 0x30, 0x42, 0x6B, 0x75, 0x71, 0x6A, 0x7A, 0x78, 0x2B, 0x7A, 0x4F, 0x41, 0x64, 0x75, 0x54, 0x4E, 0x72, 0x52, 0x6C, 0x50, ++ 0x42, 0x53, 0x65, 0x4F, 0x45, 0x36, 0x46, 0x75, 0x77, 0x67, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, ++ 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x32, 0x30, 0x31, 0x31, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x44, 0x64, 0x7A, 0x43, 0x43, ++ 0x41, 0x6C, 0x2B, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x49, 0x58, 0x44, 0x50, 0x4C, 0x59, 0x69, 0x78, 0x66, 0x73, 0x7A, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, ++ 0x42, 0x51, 0x41, 0x77, 0x50, 0x44, 0x45, 0x65, 0x4D, 0x42, 0x77, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x56, 0x51, 0x58, 0x52, 0x76, 0x63, 0x79, 0x42, 0x55, 0x0A, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x47, 0x56, 0x6B, 0x55, 0x6D, 0x39, ++ 0x76, 0x64, 0x43, 0x41, 0x79, 0x4D, 0x44, 0x45, 0x78, 0x4D, 0x51, 0x30, 0x77, 0x43, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x44, 0x41, 0x52, 0x42, 0x64, 0x47, 0x39, 0x7A, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, ++ 0x47, 0x45, 0x77, 0x4A, 0x45, 0x52, 0x54, 0x41, 0x65, 0x46, 0x77, 0x30, 0x78, 0x4D, 0x54, 0x41, 0x33, 0x4D, 0x44, 0x63, 0x78, 0x4E, 0x44, 0x55, 0x34, 0x0A, 0x4D, 0x7A, 0x42, 0x61, 0x46, 0x77, 0x30, 0x7A, 0x4D, 0x44, 0x45, 0x79, 0x4D, 0x7A, ++ 0x45, 0x79, 0x4D, 0x7A, 0x55, 0x35, 0x4E, 0x54, 0x6C, 0x61, 0x4D, 0x44, 0x77, 0x78, 0x48, 0x6A, 0x41, 0x63, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x46, 0x55, 0x46, 0x30, 0x62, 0x33, 0x4D, 0x67, 0x56, 0x48, 0x4A, 0x31, 0x63, 0x33, ++ 0x52, 0x6C, 0x5A, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x4D, 0x6A, 0x41, 0x78, 0x4D, 0x54, 0x45, 0x4E, 0x4D, 0x41, 0x73, 0x47, 0x0A, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x45, 0x51, 0x58, 0x52, 0x76, 0x63, 0x7A, 0x45, 0x4C, 0x4D, ++ 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x52, 0x45, 0x55, 0x77, 0x67, 0x67, 0x45, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, ++ 0x34, 0x49, 0x42, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x45, 0x4B, 0x41, 0x6F, 0x49, 0x42, 0x41, 0x51, 0x43, 0x56, 0x0A, 0x68, 0x54, 0x75, 0x58, 0x62, 0x79, 0x6F, 0x37, 0x4C, 0x6A, 0x76, 0x50, 0x70, 0x76, 0x4D, 0x70, 0x4E, 0x62, 0x37, 0x50, ++ 0x47, 0x4B, 0x77, 0x2B, 0x71, 0x74, 0x6E, 0x34, 0x54, 0x61, 0x41, 0x2B, 0x47, 0x6B, 0x65, 0x35, 0x76, 0x4A, 0x72, 0x66, 0x38, 0x76, 0x37, 0x4D, 0x50, 0x6B, 0x66, 0x6F, 0x65, 0x70, 0x62, 0x43, 0x4A, 0x49, 0x34, 0x31, 0x39, 0x4B, 0x6B, 0x4D, ++ 0x2F, 0x49, 0x4C, 0x39, 0x62, 0x63, 0x46, 0x79, 0x59, 0x69, 0x65, 0x39, 0x36, 0x6D, 0x76, 0x72, 0x0A, 0x35, 0x34, 0x72, 0x4D, 0x56, 0x44, 0x36, 0x51, 0x55, 0x4D, 0x2B, 0x41, 0x31, 0x4A, 0x58, 0x37, 0x36, 0x4C, 0x57, 0x43, 0x31, 0x42, 0x54, ++ 0x46, 0x74, 0x71, 0x6C, 0x56, 0x4A, 0x56, 0x66, 0x62, 0x73, 0x56, 0x44, 0x32, 0x73, 0x47, 0x42, 0x6B, 0x57, 0x58, 0x70, 0x70, 0x7A, 0x77, 0x4F, 0x33, 0x62, 0x77, 0x32, 0x2B, 0x79, 0x6A, 0x35, 0x76, 0x64, 0x48, 0x4C, 0x71, 0x71, 0x6A, 0x41, ++ 0x71, 0x63, 0x32, 0x4B, 0x2B, 0x53, 0x5A, 0x46, 0x68, 0x79, 0x42, 0x48, 0x2B, 0x0A, 0x44, 0x67, 0x4D, 0x71, 0x39, 0x32, 0x6F, 0x67, 0x33, 0x41, 0x49, 0x56, 0x44, 0x56, 0x34, 0x56, 0x61, 0x76, 0x7A, 0x6A, 0x67, 0x73, 0x47, 0x31, 0x78, 0x5A, ++ 0x31, 0x6B, 0x43, 0x57, 0x79, 0x6A, 0x57, 0x5A, 0x67, 0x48, 0x4A, 0x38, 0x63, 0x62, 0x6C, 0x69, 0x74, 0x68, 0x64, 0x48, 0x46, 0x73, 0x51, 0x2F, 0x48, 0x33, 0x4E, 0x59, 0x6B, 0x51, 0x34, 0x4A, 0x37, 0x73, 0x56, 0x61, 0x45, 0x33, 0x49, 0x71, ++ 0x4B, 0x48, 0x42, 0x41, 0x55, 0x73, 0x52, 0x33, 0x32, 0x30, 0x0A, 0x48, 0x4C, 0x6C, 0x69, 0x4B, 0x57, 0x59, 0x6F, 0x79, 0x72, 0x66, 0x68, 0x6B, 0x2F, 0x57, 0x6B, 0x6C, 0x41, 0x4F, 0x5A, 0x75, 0x58, 0x43, 0x46, 0x74, 0x65, 0x5A, 0x49, 0x36, ++ 0x6F, 0x31, 0x51, 0x2F, 0x4E, 0x6E, 0x65, 0x7A, 0x47, 0x38, 0x48, 0x44, 0x74, 0x30, 0x4C, 0x63, 0x70, 0x32, 0x41, 0x4D, 0x42, 0x59, 0x48, 0x6C, 0x54, 0x38, 0x6F, 0x44, 0x76, 0x33, 0x46, 0x64, 0x55, 0x39, 0x54, 0x31, 0x6E, 0x53, 0x61, 0x74, ++ 0x43, 0x51, 0x75, 0x6A, 0x67, 0x4B, 0x52, 0x0A, 0x7A, 0x33, 0x62, 0x46, 0x6D, 0x78, 0x35, 0x56, 0x64, 0x4A, 0x78, 0x34, 0x49, 0x62, 0x48, 0x77, 0x4C, 0x66, 0x45, 0x4C, 0x6E, 0x38, 0x4C, 0x56, 0x6C, 0x68, 0x67, 0x66, 0x38, 0x46, 0x51, 0x69, ++ 0x65, 0x6F, 0x77, 0x48, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, 0x66, 0x54, 0x42, 0x37, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x53, 0x6E, 0x70, 0x51, 0x61, 0x78, 0x4C, 0x4B, 0x59, 0x4A, ++ 0x59, 0x4F, 0x37, 0x52, 0x0A, 0x6C, 0x2B, 0x6C, 0x77, 0x72, 0x72, 0x77, 0x37, 0x47, 0x57, 0x7A, 0x62, 0x49, 0x54, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, ++ 0x2F, 0x4D, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x49, 0x77, 0x51, 0x59, 0x4D, 0x42, 0x61, 0x41, 0x46, 0x4B, 0x65, 0x6C, 0x42, 0x72, 0x45, 0x73, 0x70, 0x67, 0x6C, 0x67, 0x37, 0x74, 0x47, 0x58, 0x36, 0x58, 0x43, 0x75, 0x76, 0x44, 0x73, ++ 0x5A, 0x0A, 0x62, 0x4E, 0x73, 0x68, 0x4D, 0x42, 0x67, 0x47, 0x41, 0x31, 0x55, 0x64, 0x49, 0x41, 0x51, 0x52, 0x4D, 0x41, 0x38, 0x77, 0x44, 0x51, 0x59, 0x4C, 0x4B, 0x77, 0x59, 0x42, 0x42, 0x41, 0x47, 0x77, 0x4C, 0x51, 0x4D, 0x45, 0x41, 0x51, ++ 0x45, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x47, 0x47, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x0A, 0x43, ++ 0x77, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x41, 0x51, 0x41, 0x6D, 0x64, 0x7A, 0x54, 0x62, 0x6C, 0x45, 0x69, 0x47, 0x4B, 0x6B, 0x47, 0x64, 0x4C, 0x44, 0x34, 0x47, 0x6B, 0x47, 0x44, 0x45, 0x6A, 0x4B, 0x77, 0x4C, 0x56, 0x4C, 0x67, 0x66, 0x75, ++ 0x58, 0x76, 0x54, 0x42, 0x7A, 0x6E, 0x6B, 0x2B, 0x6A, 0x35, 0x37, 0x73, 0x6A, 0x31, 0x4F, 0x37, 0x5A, 0x38, 0x6A, 0x76, 0x5A, 0x66, 0x7A, 0x61, 0x31, 0x7A, 0x76, 0x37, 0x76, 0x31, 0x41, 0x70, 0x74, 0x2B, 0x68, 0x0A, 0x6B, 0x36, 0x45, 0x4B, ++ 0x68, 0x71, 0x7A, 0x76, 0x49, 0x4E, 0x42, 0x35, 0x41, 0x62, 0x31, 0x34, 0x39, 0x78, 0x6E, 0x59, 0x4A, 0x44, 0x45, 0x30, 0x42, 0x41, 0x47, 0x6D, 0x75, 0x68, 0x57, 0x61, 0x77, 0x79, 0x66, 0x63, 0x32, 0x45, 0x38, 0x50, 0x7A, 0x42, 0x68, 0x6A, ++ 0x2F, 0x35, 0x6B, 0x50, 0x44, 0x70, 0x46, 0x72, 0x64, 0x52, 0x62, 0x68, 0x49, 0x66, 0x7A, 0x59, 0x4A, 0x73, 0x64, 0x48, 0x74, 0x36, 0x62, 0x50, 0x57, 0x48, 0x4A, 0x78, 0x66, 0x72, 0x72, 0x68, 0x0A, 0x54, 0x5A, 0x56, 0x48, 0x4F, 0x38, 0x6D, ++ 0x76, 0x62, 0x61, 0x47, 0x30, 0x77, 0x65, 0x79, 0x4A, 0x39, 0x72, 0x51, 0x50, 0x4F, 0x4C, 0x58, 0x69, 0x5A, 0x4E, 0x77, 0x6C, 0x7A, 0x36, 0x62, 0x62, 0x36, 0x35, 0x70, 0x63, 0x6D, 0x61, 0x48, 0x46, 0x43, 0x4E, 0x37, 0x39, 0x35, 0x74, 0x72, ++ 0x56, 0x31, 0x6C, 0x70, 0x46, 0x44, 0x4D, 0x53, 0x33, 0x77, 0x72, 0x55, 0x55, 0x37, 0x37, 0x51, 0x52, 0x2F, 0x77, 0x34, 0x56, 0x74, 0x66, 0x58, 0x31, 0x32, 0x38, 0x61, 0x39, 0x0A, 0x36, 0x31, 0x71, 0x6E, 0x38, 0x46, 0x59, 0x69, 0x71, 0x54, ++ 0x78, 0x6C, 0x56, 0x4D, 0x59, 0x56, 0x71, 0x4C, 0x32, 0x47, 0x6E, 0x73, 0x32, 0x44, 0x6C, 0x6D, 0x68, 0x36, 0x63, 0x59, 0x47, 0x4A, 0x34, 0x51, 0x76, 0x68, 0x36, 0x68, 0x45, 0x62, 0x61, 0x41, 0x6A, 0x4D, 0x61, 0x5A, 0x37, 0x73, 0x6E, 0x6B, ++ 0x47, 0x65, 0x52, 0x44, 0x49, 0x6D, 0x65, 0x75, 0x4B, 0x48, 0x43, 0x6E, 0x45, 0x39, 0x36, 0x2B, 0x52, 0x61, 0x70, 0x4E, 0x4C, 0x62, 0x78, 0x63, 0x33, 0x47, 0x0A, 0x33, 0x6D, 0x42, 0x2F, 0x75, 0x66, 0x4E, 0x50, 0x52, 0x4A, 0x4C, 0x76, 0x4B, ++ 0x72, 0x63, 0x59, 0x50, 0x71, 0x63, 0x5A, 0x32, 0x51, 0x74, 0x39, 0x73, 0x54, 0x64, 0x42, 0x51, 0x72, 0x43, 0x36, 0x59, 0x42, 0x33, 0x79, 0x2F, 0x67, 0x6B, 0x52, 0x73, 0x50, 0x43, 0x48, 0x65, 0x36, 0x65, 0x64, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, ++ 0x31, 0x20, 0x47, 0x33, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, ++ 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x59, 0x44, 0x43, 0x43, 0x41, 0x30, 0x69, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x55, 0x65, 0x46, 0x68, 0x66, 0x4C, ++ 0x71, 0x30, 0x73, 0x47, 0x55, 0x76, 0x6A, 0x4E, 0x77, 0x63, 0x31, 0x4E, 0x42, 0x4D, 0x6F, 0x74, 0x5A, 0x62, 0x55, 0x5A, 0x5A, 0x4D, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, ++ 0x51, 0x41, 0x77, 0x53, 0x44, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x0A, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x51, 0x6B, 0x30, 0x78, 0x47, 0x54, 0x41, 0x58, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x45, 0x46, 0x46, 0x31, ++ 0x62, 0x31, 0x5A, 0x68, 0x5A, 0x47, 0x6C, 0x7A, 0x49, 0x45, 0x78, 0x70, 0x62, 0x57, 0x6C, 0x30, 0x5A, 0x57, 0x51, 0x78, 0x48, 0x6A, 0x41, 0x63, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x46, 0x56, 0x46, 0x31, 0x62, 0x31, 0x5A, 0x68, ++ 0x5A, 0x47, 0x6C, 0x7A, 0x49, 0x46, 0x4A, 0x76, 0x0A, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x4D, 0x53, 0x42, 0x48, 0x4D, 0x7A, 0x41, 0x65, 0x46, 0x77, 0x30, 0x78, 0x4D, 0x6A, 0x41, 0x78, 0x4D, 0x54, 0x49, 0x78, 0x4E, 0x7A, 0x49, ++ 0x33, 0x4E, 0x44, 0x52, 0x61, 0x46, 0x77, 0x30, 0x30, 0x4D, 0x6A, 0x41, 0x78, 0x4D, 0x54, 0x49, 0x78, 0x4E, 0x7A, 0x49, 0x33, 0x4E, 0x44, 0x52, 0x61, 0x4D, 0x45, 0x67, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, ++ 0x54, 0x41, 0x6B, 0x4A, 0x4E, 0x0A, 0x4D, 0x52, 0x6B, 0x77, 0x46, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x78, 0x42, 0x52, 0x64, 0x57, 0x39, 0x57, 0x59, 0x57, 0x52, 0x70, 0x63, 0x79, 0x42, 0x4D, 0x61, 0x57, 0x31, 0x70, 0x64, 0x47, ++ 0x56, 0x6B, 0x4D, 0x52, 0x34, 0x77, 0x48, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x56, 0x52, 0x64, 0x57, 0x39, 0x57, 0x59, 0x57, 0x52, 0x70, 0x63, 0x79, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x49, 0x44, ++ 0x45, 0x67, 0x0A, 0x52, 0x7A, 0x4D, 0x77, 0x67, 0x67, 0x49, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x44, 0x77, 0x41, 0x77, 0x67, ++ 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x43, 0x67, 0x76, 0x6C, 0x41, 0x51, 0x6A, 0x75, 0x6E, 0x79, 0x62, 0x45, 0x43, 0x30, 0x42, 0x4A, 0x79, 0x46, 0x75, 0x54, 0x48, 0x4B, 0x33, 0x43, 0x33, 0x6B, 0x45, 0x61, 0x6B, 0x45, 0x0A, ++ 0x50, 0x42, 0x74, 0x56, 0x77, 0x65, 0x64, 0x59, 0x4D, 0x42, 0x30, 0x6B, 0x74, 0x4D, 0x50, 0x76, 0x68, 0x64, 0x36, 0x4D, 0x4C, 0x4F, 0x48, 0x42, 0x50, 0x64, 0x2B, 0x43, 0x35, 0x6B, 0x2B, 0x74, 0x52, 0x34, 0x64, 0x73, 0x37, 0x46, 0x74, 0x4A, ++ 0x77, 0x55, 0x72, 0x56, 0x75, 0x34, 0x2F, 0x73, 0x68, 0x36, 0x78, 0x2F, 0x67, 0x70, 0x71, 0x47, 0x37, 0x44, 0x30, 0x44, 0x6D, 0x56, 0x49, 0x42, 0x30, 0x6A, 0x57, 0x65, 0x72, 0x4E, 0x72, 0x77, 0x55, 0x38, 0x6C, 0x6D, 0x0A, 0x50, 0x4E, 0x53, ++ 0x73, 0x41, 0x67, 0x48, 0x61, 0x4A, 0x4E, 0x4D, 0x37, 0x71, 0x41, 0x4A, 0x47, 0x72, 0x36, 0x51, 0x63, 0x34, 0x2F, 0x68, 0x7A, 0x57, 0x48, 0x61, 0x33, 0x39, 0x67, 0x36, 0x51, 0x44, 0x62, 0x58, 0x77, 0x7A, 0x38, 0x7A, 0x36, 0x2B, 0x63, 0x5A, ++ 0x4D, 0x35, 0x63, 0x4F, 0x47, 0x4D, 0x41, 0x71, 0x4E, 0x46, 0x33, 0x34, 0x31, 0x36, 0x38, 0x58, 0x66, 0x75, 0x77, 0x36, 0x63, 0x77, 0x49, 0x32, 0x48, 0x34, 0x34, 0x67, 0x34, 0x68, 0x57, 0x66, 0x36, 0x0A, 0x50, 0x73, 0x65, 0x72, 0x34, 0x42, ++ 0x4F, 0x63, 0x42, 0x52, 0x69, 0x59, 0x7A, 0x35, 0x50, 0x31, 0x73, 0x5A, 0x4B, 0x30, 0x2F, 0x43, 0x50, 0x54, 0x7A, 0x39, 0x58, 0x45, 0x4A, 0x30, 0x6E, 0x67, 0x6E, 0x6A, 0x79, 0x62, 0x43, 0x4B, 0x4F, 0x4C, 0x58, 0x53, 0x6F, 0x68, 0x34, 0x50, ++ 0x77, 0x35, 0x71, 0x6C, 0x50, 0x61, 0x66, 0x58, 0x37, 0x50, 0x47, 0x67, 0x6C, 0x54, 0x76, 0x46, 0x30, 0x46, 0x42, 0x4D, 0x2B, 0x68, 0x53, 0x6F, 0x2B, 0x4C, 0x64, 0x6F, 0x49, 0x4E, 0x0A, 0x6F, 0x66, 0x6A, 0x53, 0x78, 0x78, 0x52, 0x33, 0x57, ++ 0x35, 0x41, 0x32, 0x42, 0x34, 0x47, 0x62, 0x50, 0x67, 0x62, 0x36, 0x55, 0x6C, 0x35, 0x6A, 0x78, 0x61, 0x59, 0x41, 0x2F, 0x71, 0x58, 0x70, 0x55, 0x68, 0x74, 0x53, 0x74, 0x5A, 0x49, 0x35, 0x63, 0x67, 0x4D, 0x4A, 0x59, 0x72, 0x32, 0x77, 0x59, ++ 0x42, 0x5A, 0x75, 0x70, 0x74, 0x30, 0x6C, 0x77, 0x67, 0x4E, 0x6D, 0x33, 0x66, 0x4D, 0x45, 0x30, 0x55, 0x44, 0x69, 0x54, 0x6F, 0x75, 0x47, 0x39, 0x47, 0x2F, 0x6C, 0x0A, 0x67, 0x36, 0x41, 0x6E, 0x68, 0x46, 0x34, 0x45, 0x77, 0x66, 0x57, 0x51, ++ 0x76, 0x54, 0x41, 0x39, 0x78, 0x4F, 0x2B, 0x6F, 0x61, 0x62, 0x77, 0x34, 0x6D, 0x36, 0x53, 0x6B, 0x6C, 0x74, 0x46, 0x69, 0x32, 0x6D, 0x6E, 0x41, 0x41, 0x5A, 0x61, 0x75, 0x79, 0x38, 0x52, 0x52, 0x4E, 0x4F, 0x6F, 0x4D, 0x71, 0x76, 0x38, 0x68, ++ 0x6A, 0x6C, 0x6D, 0x50, 0x53, 0x6C, 0x7A, 0x6B, 0x59, 0x5A, 0x71, 0x6E, 0x30, 0x75, 0x6B, 0x71, 0x65, 0x49, 0x31, 0x52, 0x50, 0x54, 0x6F, 0x56, 0x0A, 0x37, 0x71, 0x4A, 0x5A, 0x6A, 0x71, 0x6C, 0x63, 0x33, 0x73, 0x58, 0x35, 0x6B, 0x43, 0x4C, ++ 0x6C, 0x69, 0x45, 0x56, 0x78, 0x33, 0x5A, 0x47, 0x5A, 0x62, 0x48, 0x71, 0x66, 0x50, 0x54, 0x32, 0x59, 0x66, 0x46, 0x37, 0x32, 0x76, 0x68, 0x5A, 0x6F, 0x6F, 0x46, 0x36, 0x75, 0x43, 0x79, 0x50, 0x38, 0x57, 0x67, 0x2B, 0x71, 0x49, 0x6E, 0x59, ++ 0x74, 0x79, 0x61, 0x45, 0x51, 0x48, 0x65, 0x54, 0x54, 0x52, 0x43, 0x4F, 0x51, 0x69, 0x4A, 0x2F, 0x47, 0x4B, 0x75, 0x62, 0x58, 0x0A, 0x39, 0x5A, 0x71, 0x7A, 0x57, 0x42, 0x34, 0x76, 0x4D, 0x49, 0x6B, 0x49, 0x47, 0x31, 0x53, 0x69, 0x74, 0x5A, ++ 0x67, 0x6A, 0x37, 0x41, 0x68, 0x33, 0x48, 0x4A, 0x56, 0x64, 0x59, 0x64, 0x48, 0x4C, 0x69, 0x5A, 0x78, 0x66, 0x6F, 0x6B, 0x71, 0x52, 0x6D, 0x75, 0x38, 0x68, 0x71, 0x6B, 0x6B, 0x57, 0x43, 0x4B, 0x69, 0x39, 0x59, 0x53, 0x67, 0x78, 0x79, 0x58, ++ 0x53, 0x74, 0x68, 0x66, 0x62, 0x5A, 0x78, 0x62, 0x47, 0x4C, 0x30, 0x65, 0x55, 0x51, 0x4D, 0x6B, 0x31, 0x66, 0x0A, 0x69, 0x79, 0x41, 0x36, 0x50, 0x45, 0x6B, 0x66, 0x4D, 0x34, 0x56, 0x5A, 0x44, 0x64, 0x76, 0x4C, 0x43, 0x58, 0x56, 0x44, 0x61, ++ 0x58, 0x50, 0x37, 0x61, 0x33, 0x46, 0x39, 0x38, 0x4E, 0x2F, 0x45, 0x54, 0x48, 0x33, 0x47, 0x6F, 0x79, 0x37, 0x49, 0x6C, 0x58, 0x6E, 0x4C, 0x63, 0x36, 0x4B, 0x4F, 0x54, 0x6B, 0x30, 0x6B, 0x2B, 0x31, 0x37, 0x6B, 0x42, 0x4C, 0x35, 0x79, 0x47, ++ 0x36, 0x59, 0x6E, 0x4C, 0x55, 0x6C, 0x61, 0x6D, 0x58, 0x72, 0x58, 0x58, 0x41, 0x6B, 0x67, 0x0A, 0x74, 0x33, 0x2B, 0x55, 0x75, 0x55, 0x2F, 0x78, 0x44, 0x52, 0x78, 0x65, 0x69, 0x45, 0x49, 0x62, 0x45, 0x62, 0x66, 0x6E, 0x6B, 0x64, 0x75, 0x65, ++ 0x62, 0x50, 0x52, 0x71, 0x33, 0x34, 0x77, 0x47, 0x6D, 0x41, 0x4F, 0x74, 0x7A, 0x43, 0x6A, 0x76, 0x70, 0x55, 0x66, 0x7A, 0x55, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6F, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, ++ 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x0A, 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6A, 0x41, ++ 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x6F, 0x35, 0x66, 0x57, 0x38, 0x31, 0x36, 0x69, 0x45, 0x4F, 0x47, 0x72, 0x52, 0x5A, 0x38, 0x38, 0x46, 0x32, 0x51, 0x38, 0x37, 0x67, 0x46, 0x77, 0x6E, 0x4D, 0x77, ++ 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x0A, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x42, 0x41, 0x42, 0x6A, 0x36, 0x57, 0x33, 0x58, 0x38, 0x50, 0x6E, 0x72, 0x48, 0x58, 0x33, ++ 0x66, 0x48, 0x79, 0x74, 0x2F, 0x50, 0x58, 0x38, 0x4D, 0x53, 0x78, 0x45, 0x42, 0x64, 0x31, 0x44, 0x4B, 0x71, 0x75, 0x47, 0x72, 0x58, 0x31, 0x52, 0x55, 0x56, 0x52, 0x70, 0x67, 0x6A, 0x70, 0x65, 0x61, 0x51, 0x57, 0x78, 0x69, 0x5A, 0x54, 0x4F, ++ 0x4F, 0x74, 0x51, 0x71, 0x4F, 0x43, 0x0A, 0x4D, 0x54, 0x61, 0x49, 0x7A, 0x65, 0x6E, 0x37, 0x78, 0x41, 0x53, 0x57, 0x53, 0x49, 0x73, 0x42, 0x78, 0x34, 0x30, 0x42, 0x7A, 0x31, 0x73, 0x7A, 0x42, 0x70, 0x5A, 0x47, 0x5A, 0x6E, 0x51, 0x64, 0x54, ++ 0x2B, 0x33, 0x42, 0x74, 0x72, 0x6D, 0x30, 0x44, 0x57, 0x48, 0x4D, 0x59, 0x33, 0x37, 0x58, 0x4C, 0x6E, 0x65, 0x4D, 0x6C, 0x68, 0x77, 0x71, 0x49, 0x32, 0x68, 0x72, 0x68, 0x56, 0x64, 0x32, 0x63, 0x44, 0x4D, 0x54, 0x2F, 0x75, 0x46, 0x50, 0x70, ++ 0x69, 0x4E, 0x33, 0x0A, 0x47, 0x50, 0x6F, 0x61, 0x6A, 0x4F, 0x69, 0x39, 0x5A, 0x63, 0x6E, 0x50, 0x50, 0x2F, 0x54, 0x4A, 0x46, 0x39, 0x7A, 0x72, 0x78, 0x37, 0x7A, 0x41, 0x42, 0x43, 0x34, 0x74, 0x52, 0x69, 0x39, 0x70, 0x5A, 0x73, 0x4D, 0x62, ++ 0x6A, 0x2F, 0x37, 0x73, 0x50, 0x74, 0x50, 0x4B, 0x6C, 0x4C, 0x39, 0x32, 0x43, 0x69, 0x55, 0x4E, 0x71, 0x58, 0x73, 0x43, 0x48, 0x4B, 0x6E, 0x51, 0x4F, 0x31, 0x38, 0x4C, 0x77, 0x49, 0x45, 0x36, 0x50, 0x57, 0x54, 0x68, 0x76, 0x36, 0x63, 0x74, ++ 0x0A, 0x54, 0x72, 0x31, 0x4E, 0x78, 0x4E, 0x67, 0x70, 0x78, 0x69, 0x49, 0x59, 0x30, 0x4D, 0x57, 0x73, 0x63, 0x67, 0x4B, 0x43, 0x50, 0x36, 0x6F, 0x36, 0x6F, 0x6A, 0x6F, 0x69, 0x6C, 0x7A, 0x48, 0x64, 0x43, 0x47, 0x50, 0x44, 0x64, 0x52, 0x53, ++ 0x35, 0x59, 0x43, 0x67, 0x74, 0x57, 0x32, 0x6A, 0x67, 0x46, 0x71, 0x6C, 0x6D, 0x67, 0x69, 0x4E, 0x52, 0x39, 0x65, 0x74, 0x54, 0x32, 0x44, 0x47, 0x62, 0x65, 0x2B, 0x6D, 0x33, 0x6E, 0x55, 0x76, 0x72, 0x69, 0x42, 0x62, 0x50, 0x0A, 0x2B, 0x56, ++ 0x30, 0x34, 0x69, 0x6B, 0x6B, 0x77, 0x6A, 0x2B, 0x33, 0x78, 0x36, 0x78, 0x6E, 0x30, 0x64, 0x78, 0x6F, 0x78, 0x47, 0x45, 0x31, 0x6E, 0x56, 0x47, 0x77, 0x76, 0x62, 0x32, 0x58, 0x35, 0x32, 0x7A, 0x33, 0x73, 0x49, 0x65, 0x78, 0x65, 0x39, 0x50, ++ 0x53, 0x4C, 0x79, 0x6D, 0x42, 0x6C, 0x56, 0x4E, 0x46, 0x78, 0x5A, 0x50, 0x54, 0x35, 0x70, 0x71, 0x4F, 0x42, 0x4D, 0x7A, 0x59, 0x7A, 0x63, 0x66, 0x43, 0x6B, 0x65, 0x46, 0x39, 0x4F, 0x72, 0x59, 0x4D, 0x68, 0x0A, 0x33, 0x6A, 0x52, 0x4A, 0x6A, ++ 0x65, 0x68, 0x5A, 0x72, 0x4A, 0x33, 0x79, 0x64, 0x6C, 0x6F, 0x32, 0x38, 0x68, 0x50, 0x30, 0x72, 0x2B, 0x41, 0x4A, 0x78, 0x32, 0x45, 0x71, 0x62, 0x50, 0x66, 0x67, 0x6E, 0x61, 0x36, 0x37, 0x68, 0x6B, 0x6F, 0x6F, 0x62, 0x79, 0x37, 0x75, 0x74, ++ 0x48, 0x6E, 0x4E, 0x6B, 0x44, 0x50, 0x44, 0x73, 0x33, 0x62, 0x36, 0x39, 0x66, 0x42, 0x73, 0x6E, 0x51, 0x47, 0x51, 0x2B, 0x70, 0x36, 0x51, 0x39, 0x70, 0x78, 0x79, 0x7A, 0x30, 0x66, 0x61, 0x0A, 0x77, 0x78, 0x2F, 0x6B, 0x4E, 0x53, 0x42, 0x54, ++ 0x38, 0x6C, 0x54, 0x52, 0x33, 0x32, 0x47, 0x44, 0x70, 0x67, 0x4C, 0x69, 0x4A, 0x54, 0x6A, 0x65, 0x68, 0x54, 0x49, 0x74, 0x58, 0x6E, 0x4F, 0x51, 0x55, 0x6C, 0x31, 0x43, 0x78, 0x4D, 0x34, 0x39, 0x53, 0x2B, 0x48, 0x35, 0x47, 0x59, 0x51, 0x64, ++ 0x31, 0x61, 0x4A, 0x51, 0x7A, 0x45, 0x48, 0x37, 0x51, 0x52, 0x54, 0x44, 0x76, 0x64, 0x62, 0x4A, 0x57, 0x71, 0x4E, 0x6A, 0x5A, 0x67, 0x4B, 0x41, 0x76, 0x51, 0x55, 0x36, 0x0A, 0x4F, 0x30, 0x65, 0x63, 0x37, 0x41, 0x41, 0x6D, 0x54, 0x50, 0x57, ++ 0x49, 0x55, 0x62, 0x2B, 0x6F, 0x49, 0x33, 0x38, 0x59, 0x42, 0x37, 0x41, 0x4C, 0x37, 0x59, 0x73, 0x6D, 0x6F, 0x57, 0x54, 0x54, 0x59, 0x55, 0x72, 0x72, 0x58, 0x4A, 0x2F, 0x65, 0x73, 0x36, 0x39, 0x6E, 0x41, 0x37, 0x4D, 0x66, 0x33, 0x57, 0x31, ++ 0x64, 0x61, 0x57, 0x68, 0x70, 0x71, 0x31, 0x34, 0x36, 0x37, 0x48, 0x78, 0x70, 0x76, 0x4D, 0x63, 0x37, 0x68, 0x55, 0x36, 0x65, 0x46, 0x62, 0x6D, 0x30, 0x0A, 0x46, 0x55, 0x2F, 0x44, 0x6C, 0x58, 0x70, 0x59, 0x31, 0x38, 0x6C, 0x73, 0x36, 0x57, ++ 0x79, 0x35, 0x38, 0x79, 0x6C, 0x6A, 0x58, 0x72, 0x51, 0x73, 0x38, 0x43, 0x30, 0x39, 0x37, 0x56, 0x70, 0x6C, 0x34, 0x4B, 0x6C, 0x62, 0x51, 0x4D, 0x4A, 0x49, 0x6D, 0x59, 0x46, 0x74, 0x6E, 0x68, 0x38, 0x47, 0x4B, 0x6A, 0x77, 0x53, 0x74, 0x49, ++ 0x73, 0x50, 0x6D, 0x36, 0x49, 0x6B, 0x38, 0x4B, 0x61, 0x4E, 0x31, 0x6E, 0x72, 0x67, 0x53, 0x37, 0x5A, 0x6B, 0x6C, 0x6D, 0x4F, 0x56, 0x0A, 0x68, 0x4D, 0x4A, 0x4B, 0x7A, 0x52, 0x77, 0x75, 0x4A, 0x49, 0x63, 0x7A, 0x59, 0x4F, 0x58, 0x44, 0x0A, ++ 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, ++ 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, 0x47, 0x33, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, ++ 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x59, 0x44, 0x43, 0x43, 0x41, 0x30, 0x69, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x55, 0x52, ++ 0x46, 0x63, 0x30, 0x4A, 0x46, 0x75, 0x42, 0x69, 0x5A, 0x73, 0x31, 0x38, 0x73, 0x36, 0x34, 0x4B, 0x7A, 0x74, 0x62, 0x70, 0x79, 0x62, 0x77, 0x64, 0x53, 0x67, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, ++ 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x77, 0x53, 0x44, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x0A, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x51, 0x6B, 0x30, 0x78, 0x47, 0x54, 0x41, 0x58, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, ++ 0x45, 0x46, 0x46, 0x31, 0x62, 0x31, 0x5A, 0x68, 0x5A, 0x47, 0x6C, 0x7A, 0x49, 0x45, 0x78, 0x70, 0x62, 0x57, 0x6C, 0x30, 0x5A, 0x57, 0x51, 0x78, 0x48, 0x6A, 0x41, 0x63, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x46, 0x56, 0x46, 0x31, ++ 0x62, 0x31, 0x5A, 0x68, 0x5A, 0x47, 0x6C, 0x7A, 0x49, 0x46, 0x4A, 0x76, 0x0A, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x4D, 0x69, 0x42, 0x48, 0x4D, 0x7A, 0x41, 0x65, 0x46, 0x77, 0x30, 0x78, 0x4D, 0x6A, 0x41, 0x78, 0x4D, 0x54, 0x49, ++ 0x78, 0x4F, 0x44, 0x55, 0x35, 0x4D, 0x7A, 0x4A, 0x61, 0x46, 0x77, 0x30, 0x30, 0x4D, 0x6A, 0x41, 0x78, 0x4D, 0x54, 0x49, 0x78, 0x4F, 0x44, 0x55, 0x35, 0x4D, 0x7A, 0x4A, 0x61, 0x4D, 0x45, 0x67, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, ++ 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x4A, 0x4E, 0x0A, 0x4D, 0x52, 0x6B, 0x77, 0x46, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x78, 0x42, 0x52, 0x64, 0x57, 0x39, 0x57, 0x59, 0x57, 0x52, 0x70, 0x63, 0x79, 0x42, 0x4D, 0x61, 0x57, ++ 0x31, 0x70, 0x64, 0x47, 0x56, 0x6B, 0x4D, 0x52, 0x34, 0x77, 0x48, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x56, 0x52, 0x64, 0x57, 0x39, 0x57, 0x59, 0x57, 0x52, 0x70, 0x63, 0x79, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, ++ 0x4E, 0x42, 0x49, 0x44, 0x49, 0x67, 0x0A, 0x52, 0x7A, 0x4D, 0x77, 0x67, 0x67, 0x49, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x44, ++ 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x43, 0x68, 0x72, 0x69, 0x57, 0x79, 0x41, 0x52, 0x6A, 0x63, 0x56, 0x34, 0x67, 0x2F, 0x52, 0x75, 0x76, 0x35, 0x72, 0x2B, 0x4C, 0x72, 0x49, 0x33, 0x48, 0x69, 0x6D, ++ 0x74, 0x46, 0x68, 0x0A, 0x5A, 0x69, 0x46, 0x66, 0x71, 0x71, 0x38, 0x6E, 0x55, 0x65, 0x56, 0x75, 0x47, 0x78, 0x62, 0x55, 0x4C, 0x58, 0x31, 0x51, 0x73, 0x46, 0x4E, 0x33, 0x76, 0x58, 0x67, 0x36, 0x59, 0x4F, 0x4A, 0x6B, 0x41, 0x70, 0x74, 0x38, ++ 0x68, 0x70, 0x76, 0x57, 0x47, 0x6F, 0x36, 0x74, 0x2F, 0x78, 0x38, 0x56, 0x66, 0x39, 0x57, 0x56, 0x48, 0x68, 0x4C, 0x4C, 0x35, 0x68, 0x53, 0x45, 0x42, 0x4D, 0x48, 0x66, 0x4E, 0x72, 0x4D, 0x57, 0x6E, 0x34, 0x72, 0x6A, 0x79, 0x64, 0x75, 0x59, ++ 0x0A, 0x4E, 0x4D, 0x37, 0x59, 0x4D, 0x78, 0x63, 0x6F, 0x52, 0x76, 0x79, 0x6E, 0x79, 0x66, 0x44, 0x53, 0x74, 0x4E, 0x56, 0x4E, 0x43, 0x58, 0x4A, 0x4A, 0x2B, 0x66, 0x4B, 0x48, 0x34, 0x36, 0x6E, 0x61, 0x66, 0x61, 0x46, 0x39, 0x61, 0x37, 0x49, ++ 0x36, 0x4A, 0x61, 0x6C, 0x74, 0x55, 0x6B, 0x53, 0x73, 0x2B, 0x4C, 0x35, 0x75, 0x2B, 0x39, 0x79, 0x6D, 0x63, 0x35, 0x47, 0x51, 0x59, 0x61, 0x59, 0x44, 0x46, 0x43, 0x44, 0x79, 0x35, 0x34, 0x65, 0x6A, 0x69, 0x4B, 0x32, 0x74, 0x0A, 0x6F, 0x49, ++ 0x7A, 0x2F, 0x70, 0x67, 0x73, 0x6C, 0x55, 0x69, 0x58, 0x6E, 0x46, 0x67, 0x48, 0x56, 0x79, 0x37, 0x67, 0x31, 0x67, 0x51, 0x79, 0x6A, 0x4F, 0x2F, 0x44, 0x68, 0x34, 0x66, 0x78, 0x61, 0x58, 0x63, 0x36, 0x41, 0x63, 0x57, 0x33, 0x34, 0x53, 0x61, ++ 0x73, 0x2B, 0x4F, 0x37, 0x71, 0x34, 0x31, 0x34, 0x41, 0x42, 0x2B, 0x36, 0x58, 0x72, 0x57, 0x37, 0x50, 0x46, 0x58, 0x6D, 0x41, 0x71, 0x4D, 0x61, 0x43, 0x76, 0x4E, 0x2B, 0x67, 0x67, 0x4F, 0x70, 0x2B, 0x6F, 0x0A, 0x4D, 0x69, 0x77, 0x4D, 0x7A, ++ 0x41, 0x6B, 0x64, 0x30, 0x35, 0x36, 0x4F, 0x58, 0x62, 0x78, 0x4D, 0x6D, 0x4F, 0x37, 0x46, 0x47, 0x6D, 0x68, 0x37, 0x37, 0x46, 0x4F, 0x6D, 0x36, 0x52, 0x51, 0x31, 0x6F, 0x39, 0x2F, 0x4E, 0x67, 0x4A, 0x38, 0x4D, 0x53, 0x50, 0x73, 0x63, 0x39, ++ 0x50, 0x47, 0x2F, 0x53, 0x72, 0x6A, 0x36, 0x31, 0x59, 0x78, 0x78, 0x53, 0x73, 0x63, 0x66, 0x72, 0x66, 0x35, 0x42, 0x6D, 0x72, 0x4F, 0x44, 0x58, 0x66, 0x4B, 0x45, 0x56, 0x75, 0x2B, 0x6C, 0x0A, 0x56, 0x30, 0x50, 0x4F, 0x4B, 0x61, 0x32, 0x4D, ++ 0x71, 0x31, 0x57, 0x2F, 0x78, 0x50, 0x74, 0x62, 0x41, 0x64, 0x30, 0x6A, 0x49, 0x61, 0x46, 0x59, 0x41, 0x49, 0x37, 0x44, 0x30, 0x47, 0x6F, 0x54, 0x37, 0x52, 0x50, 0x6A, 0x45, 0x69, 0x75, 0x41, 0x33, 0x47, 0x66, 0x6D, 0x6C, 0x62, 0x4C, 0x4E, ++ 0x48, 0x69, 0x4A, 0x75, 0x4B, 0x76, 0x68, 0x42, 0x31, 0x50, 0x4C, 0x4B, 0x46, 0x41, 0x65, 0x4E, 0x69, 0x6C, 0x55, 0x53, 0x78, 0x6D, 0x6E, 0x31, 0x75, 0x49, 0x5A, 0x6F, 0x0A, 0x4C, 0x31, 0x4E, 0x65, 0x73, 0x4E, 0x4B, 0x71, 0x49, 0x63, 0x47, ++ 0x59, 0x35, 0x6A, 0x44, 0x6A, 0x5A, 0x31, 0x58, 0x48, 0x6D, 0x32, 0x36, 0x73, 0x47, 0x61, 0x68, 0x56, 0x70, 0x6B, 0x55, 0x47, 0x30, 0x43, 0x4D, 0x36, 0x32, 0x2B, 0x74, 0x6C, 0x58, 0x53, 0x6F, 0x52, 0x45, 0x66, 0x41, 0x37, 0x54, 0x38, 0x70, ++ 0x74, 0x39, 0x44, 0x54, 0x45, 0x63, 0x65, 0x54, 0x2F, 0x41, 0x46, 0x72, 0x32, 0x58, 0x4B, 0x34, 0x6A, 0x59, 0x49, 0x56, 0x7A, 0x38, 0x65, 0x51, 0x51, 0x0A, 0x73, 0x53, 0x57, 0x75, 0x31, 0x5A, 0x4B, 0x37, 0x45, 0x38, 0x45, 0x4D, 0x34, 0x44, ++ 0x6E, 0x61, 0x74, 0x44, 0x6C, 0x58, 0x74, 0x61, 0x73, 0x31, 0x71, 0x6E, 0x49, 0x68, 0x4F, 0x34, 0x4D, 0x31, 0x35, 0x7A, 0x48, 0x66, 0x65, 0x69, 0x46, 0x75, 0x75, 0x44, 0x49, 0x49, 0x66, 0x52, 0x30, 0x79, 0x6B, 0x52, 0x56, 0x4B, 0x59, 0x6E, ++ 0x4C, 0x50, 0x34, 0x33, 0x65, 0x68, 0x76, 0x4E, 0x55, 0x52, 0x47, 0x33, 0x59, 0x42, 0x5A, 0x77, 0x6A, 0x67, 0x51, 0x51, 0x76, 0x44, 0x0A, 0x36, 0x78, 0x56, 0x75, 0x2B, 0x4B, 0x51, 0x5A, 0x32, 0x61, 0x4B, 0x72, 0x72, 0x2B, 0x49, 0x6E, 0x55, ++ 0x6C, 0x59, 0x72, 0x41, 0x6F, 0x6F, 0x73, 0x46, 0x43, 0x54, 0x35, 0x76, 0x30, 0x49, 0x43, 0x76, 0x79, 0x62, 0x49, 0x78, 0x6F, 0x2F, 0x67, 0x62, 0x6A, 0x68, 0x39, 0x55, 0x79, 0x33, 0x6C, 0x37, 0x5A, 0x69, 0x7A, 0x6C, 0x57, 0x4E, 0x6F, 0x66, ++ 0x2F, 0x6B, 0x31, 0x39, 0x4E, 0x2B, 0x49, 0x78, 0x57, 0x41, 0x31, 0x6B, 0x73, 0x42, 0x38, 0x61, 0x52, 0x78, 0x68, 0x0A, 0x6C, 0x52, 0x62, 0x51, 0x36, 0x39, 0x34, 0x4C, 0x72, 0x7A, 0x34, 0x45, 0x45, 0x45, 0x56, 0x6C, 0x57, 0x46, 0x41, 0x34, ++ 0x72, 0x30, 0x6A, 0x79, 0x57, 0x62, 0x59, 0x57, 0x38, 0x6A, 0x77, 0x4E, 0x6B, 0x41, 0x4C, 0x47, 0x63, 0x43, 0x34, 0x42, 0x72, 0x54, 0x77, 0x56, 0x31, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6F, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, 0x50, ++ 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x0A, 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, ++ 0x42, 0x42, 0x6A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x37, 0x65, 0x64, 0x76, 0x64, 0x6C, 0x71, 0x2F, 0x59, 0x4F, 0x78, 0x4A, 0x57, 0x38, 0x61, 0x6C, 0x64, 0x37, 0x74, 0x79, 0x46, 0x6E, 0x47, ++ 0x62, 0x78, 0x44, 0x30, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x0A, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x42, 0x41, 0x4A, 0x48, 0x66, 0x67, 0x44, 0x39, 0x44, 0x43, 0x58, ++ 0x35, 0x78, 0x77, 0x76, 0x66, 0x72, 0x73, 0x34, 0x69, 0x50, 0x34, 0x56, 0x47, 0x79, 0x76, 0x44, 0x31, 0x31, 0x2B, 0x53, 0x68, 0x64, 0x79, 0x4C, 0x79, 0x5A, 0x6D, 0x33, 0x74, 0x64, 0x71, 0x75, 0x58, 0x4B, 0x34, 0x51, 0x72, 0x33, 0x36, 0x4C, ++ 0x4C, 0x54, 0x6E, 0x39, 0x31, 0x6E, 0x4D, 0x58, 0x36, 0x36, 0x0A, 0x41, 0x61, 0x72, 0x48, 0x61, 0x6B, 0x45, 0x37, 0x6B, 0x4E, 0x51, 0x49, 0x58, 0x4C, 0x4A, 0x67, 0x61, 0x70, 0x44, 0x77, 0x79, 0x4D, 0x34, 0x44, 0x59, 0x76, 0x6D, 0x4C, 0x37, ++ 0x66, 0x74, 0x75, 0x4B, 0x74, 0x77, 0x47, 0x54, 0x54, 0x77, 0x70, 0x44, 0x34, 0x6B, 0x57, 0x69, 0x6C, 0x68, 0x4D, 0x53, 0x41, 0x2F, 0x6F, 0x68, 0x47, 0x48, 0x71, 0x50, 0x48, 0x4B, 0x6D, 0x64, 0x2B, 0x52, 0x43, 0x72, 0x6F, 0x69, 0x6A, 0x51, ++ 0x31, 0x68, 0x35, 0x66, 0x71, 0x37, 0x4B, 0x0A, 0x70, 0x56, 0x4D, 0x4E, 0x71, 0x54, 0x31, 0x77, 0x76, 0x53, 0x41, 0x5A, 0x59, 0x61, 0x52, 0x73, 0x4F, 0x50, 0x78, 0x44, 0x4D, 0x75, 0x48, 0x42, 0x52, 0x2F, 0x2F, 0x34, 0x37, 0x50, 0x45, 0x52, ++ 0x49, 0x6A, 0x4B, 0x57, 0x6E, 0x4D, 0x4C, 0x32, 0x57, 0x32, 0x6D, 0x57, 0x65, 0x79, 0x41, 0x4D, 0x51, 0x30, 0x47, 0x61, 0x57, 0x2F, 0x5A, 0x5A, 0x47, 0x59, 0x6A, 0x65, 0x56, 0x59, 0x67, 0x33, 0x55, 0x51, 0x74, 0x34, 0x58, 0x41, 0x6F, 0x65, ++ 0x6F, 0x30, 0x4C, 0x39, 0x0A, 0x78, 0x35, 0x32, 0x49, 0x44, 0x38, 0x44, 0x79, 0x65, 0x41, 0x49, 0x6B, 0x56, 0x4A, 0x4F, 0x76, 0x69, 0x59, 0x65, 0x49, 0x79, 0x55, 0x71, 0x41, 0x48, 0x65, 0x72, 0x51, 0x62, 0x6A, 0x35, 0x68, 0x4C, 0x6A, 0x61, ++ 0x37, 0x4E, 0x51, 0x34, 0x6E, 0x6C, 0x76, 0x31, 0x6D, 0x4E, 0x44, 0x74, 0x68, 0x63, 0x6E, 0x50, 0x78, 0x46, 0x6C, 0x78, 0x48, 0x42, 0x6C, 0x52, 0x4A, 0x41, 0x48, 0x70, 0x59, 0x45, 0x72, 0x41, 0x4B, 0x37, 0x34, 0x58, 0x39, 0x73, 0x62, 0x67, ++ 0x7A, 0x0A, 0x64, 0x57, 0x71, 0x54, 0x48, 0x42, 0x4C, 0x6D, 0x59, 0x46, 0x35, 0x76, 0x48, 0x58, 0x2F, 0x4A, 0x48, 0x79, 0x50, 0x4C, 0x68, 0x47, 0x47, 0x66, 0x48, 0x6F, 0x4A, 0x45, 0x2B, 0x56, 0x2B, 0x74, 0x59, 0x6C, 0x55, 0x6B, 0x6D, 0x6C, ++ 0x4B, 0x59, 0x37, 0x56, 0x48, 0x6E, 0x6F, 0x58, 0x36, 0x58, 0x4F, 0x75, 0x59, 0x76, 0x48, 0x78, 0x48, 0x61, 0x55, 0x34, 0x41, 0x73, 0x68, 0x5A, 0x36, 0x72, 0x4E, 0x52, 0x44, 0x62, 0x49, 0x6C, 0x39, 0x71, 0x78, 0x56, 0x36, 0x58, 0x0A, 0x55, ++ 0x2F, 0x49, 0x79, 0x41, 0x67, 0x6B, 0x77, 0x6F, 0x31, 0x6A, 0x77, 0x44, 0x51, 0x48, 0x56, 0x63, 0x73, 0x61, 0x78, 0x66, 0x47, 0x6C, 0x37, 0x77, 0x2F, 0x55, 0x32, 0x52, 0x63, 0x78, 0x68, 0x62, 0x6C, 0x35, 0x4D, 0x6C, 0x4D, 0x56, 0x65, 0x72, ++ 0x75, 0x67, 0x4F, 0x58, 0x6F, 0x75, 0x2F, 0x39, 0x38, 0x33, 0x67, 0x37, 0x61, 0x45, 0x4F, 0x47, 0x7A, 0x50, 0x75, 0x56, 0x42, 0x6A, 0x2B, 0x44, 0x37, 0x37, 0x76, 0x66, 0x6F, 0x52, 0x72, 0x51, 0x2B, 0x4E, 0x77, 0x0A, 0x6D, 0x4E, 0x74, 0x64, ++ 0x64, 0x62, 0x49, 0x4E, 0x57, 0x51, 0x65, 0x46, 0x46, 0x53, 0x4D, 0x35, 0x31, 0x76, 0x48, 0x66, 0x71, 0x53, 0x59, 0x50, 0x31, 0x6B, 0x6A, 0x48, 0x73, 0x36, 0x59, 0x69, 0x39, 0x54, 0x4D, 0x33, 0x57, 0x70, 0x56, 0x48, 0x6E, 0x33, 0x75, 0x36, ++ 0x47, 0x42, 0x56, 0x76, 0x2F, 0x39, 0x59, 0x55, 0x5A, 0x49, 0x4E, 0x4A, 0x30, 0x67, 0x70, 0x6E, 0x49, 0x64, 0x73, 0x50, 0x4E, 0x57, 0x4E, 0x67, 0x4B, 0x43, 0x4C, 0x6A, 0x73, 0x5A, 0x57, 0x44, 0x0A, 0x7A, 0x59, 0x57, 0x6D, 0x33, 0x53, 0x38, ++ 0x50, 0x35, 0x32, 0x64, 0x53, 0x62, 0x72, 0x73, 0x76, 0x68, 0x58, 0x7A, 0x31, 0x53, 0x6E, 0x50, 0x6E, 0x78, 0x54, 0x37, 0x41, 0x76, 0x53, 0x45, 0x53, 0x42, 0x54, 0x2F, 0x38, 0x74, 0x77, 0x4E, 0x4A, 0x41, 0x6C, 0x76, 0x49, 0x4A, 0x65, 0x62, ++ 0x69, 0x56, 0x44, 0x6A, 0x31, 0x65, 0x59, 0x65, 0x4D, 0x48, 0x56, 0x4F, 0x79, 0x54, 0x6F, 0x56, 0x37, 0x42, 0x6A, 0x6A, 0x48, 0x4C, 0x50, 0x6A, 0x34, 0x73, 0x48, 0x4B, 0x4E, 0x0A, 0x4A, 0x65, 0x56, 0x33, 0x55, 0x76, 0x51, 0x44, 0x48, 0x45, ++ 0x69, 0x6D, 0x55, 0x46, 0x2B, 0x49, 0x49, 0x44, 0x42, 0x75, 0x38, 0x6F, 0x4A, 0x44, 0x71, 0x7A, 0x32, 0x58, 0x68, 0x4F, 0x64, 0x54, 0x2B, 0x79, 0x48, 0x42, 0x54, 0x77, 0x38, 0x69, 0x6D, 0x6F, 0x61, 0x34, 0x57, 0x53, 0x72, 0x32, 0x52, 0x7A, ++ 0x30, 0x5A, 0x69, 0x43, 0x33, 0x6F, 0x68, 0x65, 0x47, 0x65, 0x37, 0x49, 0x55, 0x49, 0x61, 0x72, 0x46, 0x73, 0x4E, 0x4D, 0x6B, 0x64, 0x37, 0x45, 0x67, 0x72, 0x0A, 0x4F, 0x33, 0x6A, 0x74, 0x5A, 0x73, 0x53, 0x4F, 0x65, 0x57, 0x6D, 0x44, 0x33, ++ 0x6E, 0x2B, 0x4D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, ++ 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33, 0x20, 0x47, 0x33, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x59, 0x44, 0x43, 0x43, 0x41, 0x30, 0x69, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, ++ 0x67, 0x49, 0x55, 0x4C, 0x76, 0x57, 0x62, 0x41, 0x69, 0x69, 0x6E, 0x32, 0x33, 0x72, 0x2F, 0x31, 0x61, 0x4F, 0x70, 0x37, 0x72, 0x30, 0x44, 0x6F, 0x4D, 0x38, 0x53, 0x61, 0x68, 0x30, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, ++ 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x77, 0x53, 0x44, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x0A, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x51, 0x6B, 0x30, 0x78, 0x47, 0x54, 0x41, 0x58, 0x42, 0x67, 0x4E, 0x56, ++ 0x42, 0x41, 0x6F, 0x54, 0x45, 0x46, 0x46, 0x31, 0x62, 0x31, 0x5A, 0x68, 0x5A, 0x47, 0x6C, 0x7A, 0x49, 0x45, 0x78, 0x70, 0x62, 0x57, 0x6C, 0x30, 0x5A, 0x57, 0x51, 0x78, 0x48, 0x6A, 0x41, 0x63, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, ++ 0x46, 0x56, 0x46, 0x31, 0x62, 0x31, 0x5A, 0x68, 0x5A, 0x47, 0x6C, 0x7A, 0x49, 0x46, 0x4A, 0x76, 0x0A, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x4D, 0x79, 0x42, 0x48, 0x4D, 0x7A, 0x41, 0x65, 0x46, 0x77, 0x30, 0x78, 0x4D, 0x6A, 0x41, ++ 0x78, 0x4D, 0x54, 0x49, 0x79, 0x4D, 0x44, 0x49, 0x32, 0x4D, 0x7A, 0x4A, 0x61, 0x46, 0x77, 0x30, 0x30, 0x4D, 0x6A, 0x41, 0x78, 0x4D, 0x54, 0x49, 0x79, 0x4D, 0x44, 0x49, 0x32, 0x4D, 0x7A, 0x4A, 0x61, 0x4D, 0x45, 0x67, 0x78, 0x43, 0x7A, 0x41, ++ 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x4A, 0x4E, 0x0A, 0x4D, 0x52, 0x6B, 0x77, 0x46, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x78, 0x42, 0x52, 0x64, 0x57, 0x39, 0x57, 0x59, 0x57, 0x52, 0x70, 0x63, 0x79, ++ 0x42, 0x4D, 0x61, 0x57, 0x31, 0x70, 0x64, 0x47, 0x56, 0x6B, 0x4D, 0x52, 0x34, 0x77, 0x48, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x56, 0x52, 0x64, 0x57, 0x39, 0x57, 0x59, 0x57, 0x52, 0x70, 0x63, 0x79, 0x42, 0x53, 0x62, 0x32, ++ 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x49, 0x44, 0x4D, 0x67, 0x0A, 0x52, 0x7A, 0x4D, 0x77, 0x67, 0x67, 0x49, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, ++ 0x34, 0x49, 0x43, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x43, 0x7A, 0x79, 0x77, 0x34, 0x51, 0x5A, 0x34, 0x37, 0x71, 0x46, 0x4A, 0x65, 0x6E, 0x4D, 0x69, 0x6F, 0x4B, 0x56, 0x6A, 0x5A, 0x2F, 0x61, ++ 0x45, 0x7A, 0x48, 0x73, 0x32, 0x38, 0x36, 0x0A, 0x49, 0x78, 0x53, 0x52, 0x2F, 0x78, 0x6C, 0x2F, 0x70, 0x63, 0x71, 0x73, 0x37, 0x72, 0x4E, 0x32, 0x6E, 0x58, 0x72, 0x70, 0x69, 0x78, 0x75, 0x72, 0x61, 0x7A, 0x48, 0x62, 0x2B, 0x67, 0x74, 0x54, ++ 0x54, 0x4B, 0x2F, 0x46, 0x70, 0x52, 0x70, 0x35, 0x50, 0x49, 0x70, 0x4D, 0x2F, 0x36, 0x7A, 0x66, 0x4A, 0x64, 0x35, 0x4F, 0x32, 0x59, 0x49, 0x79, 0x43, 0x30, 0x54, 0x65, 0x79, 0x74, 0x75, 0x4D, 0x72, 0x4B, 0x4E, 0x75, 0x46, 0x6F, 0x4D, 0x37, ++ 0x70, 0x6D, 0x52, 0x4C, 0x0A, 0x4D, 0x6F, 0x6E, 0x37, 0x46, 0x68, 0x59, 0x34, 0x66, 0x75, 0x74, 0x44, 0x34, 0x74, 0x4E, 0x30, 0x53, 0x73, 0x4A, 0x69, 0x43, 0x6E, 0x4D, 0x4B, 0x33, 0x55, 0x6D, 0x7A, 0x56, 0x39, 0x4B, 0x77, 0x43, 0x6F, 0x57, ++ 0x64, 0x63, 0x54, 0x7A, 0x65, 0x6F, 0x38, 0x76, 0x41, 0x4D, 0x76, 0x4D, 0x42, 0x4F, 0x53, 0x42, 0x44, 0x47, 0x7A, 0x58, 0x52, 0x55, 0x37, 0x4F, 0x78, 0x37, 0x73, 0x57, 0x54, 0x61, 0x59, 0x49, 0x2B, 0x46, 0x72, 0x55, 0x6F, 0x52, 0x71, 0x48, ++ 0x65, 0x0A, 0x36, 0x6F, 0x6B, 0x4A, 0x37, 0x55, 0x4F, 0x34, 0x42, 0x55, 0x61, 0x4B, 0x68, 0x76, 0x56, 0x5A, 0x52, 0x37, 0x34, 0x62, 0x62, 0x77, 0x45, 0x68, 0x45, 0x4C, 0x6E, 0x39, 0x71, 0x64, 0x49, 0x6F, 0x79, 0x68, 0x41, 0x35, 0x43, 0x63, ++ 0x6F, 0x54, 0x4E, 0x73, 0x2B, 0x63, 0x72, 0x61, 0x31, 0x41, 0x64, 0x48, 0x6B, 0x72, 0x41, 0x6A, 0x38, 0x30, 0x2F, 0x2F, 0x6F, 0x67, 0x61, 0x58, 0x33, 0x54, 0x37, 0x6D, 0x48, 0x31, 0x75, 0x72, 0x50, 0x6E, 0x4D, 0x4E, 0x41, 0x33, 0x0A, 0x49, ++ 0x34, 0x5A, 0x79, 0x59, 0x55, 0x55, 0x70, 0x53, 0x46, 0x6C, 0x6F, 0x62, 0x33, 0x65, 0x6D, 0x4C, 0x6F, 0x47, 0x2B, 0x42, 0x30, 0x31, 0x76, 0x72, 0x38, 0x37, 0x45, 0x52, 0x52, 0x4F, 0x52, 0x46, 0x48, 0x41, 0x47, 0x6A, 0x78, 0x2B, 0x66, 0x2B, ++ 0x49, 0x64, 0x70, 0x73, 0x51, 0x37, 0x76, 0x77, 0x34, 0x6B, 0x5A, 0x36, 0x2B, 0x6F, 0x63, 0x59, 0x66, 0x78, 0x36, 0x62, 0x49, 0x72, 0x63, 0x31, 0x67, 0x4D, 0x4C, 0x6E, 0x69, 0x61, 0x36, 0x45, 0x74, 0x33, 0x55, 0x0A, 0x56, 0x44, 0x6D, 0x72, ++ 0x4A, 0x71, 0x4D, 0x7A, 0x36, 0x6E, 0x57, 0x42, 0x32, 0x69, 0x33, 0x4E, 0x44, 0x30, 0x2F, 0x6B, 0x41, 0x39, 0x48, 0x76, 0x46, 0x5A, 0x63, 0x62, 0x61, 0x35, 0x44, 0x46, 0x41, 0x70, 0x43, 0x54, 0x5A, 0x67, 0x49, 0x68, 0x73, 0x55, 0x66, 0x65, ++ 0x69, 0x35, 0x70, 0x4B, 0x67, 0x4C, 0x6C, 0x56, 0x6A, 0x37, 0x57, 0x69, 0x4C, 0x38, 0x44, 0x57, 0x4D, 0x32, 0x66, 0x61, 0x66, 0x73, 0x53, 0x6E, 0x74, 0x41, 0x52, 0x45, 0x36, 0x30, 0x66, 0x37, 0x0A, 0x35, 0x6C, 0x69, 0x35, 0x39, 0x77, 0x7A, ++ 0x77, 0x65, 0x79, 0x75, 0x78, 0x77, 0x48, 0x41, 0x70, 0x77, 0x30, 0x42, 0x69, 0x4C, 0x54, 0x74, 0x49, 0x61, 0x64, 0x77, 0x6A, 0x50, 0x45, 0x6A, 0x72, 0x65, 0x77, 0x6C, 0x35, 0x71, 0x57, 0x33, 0x61, 0x71, 0x44, 0x43, 0x59, 0x7A, 0x34, 0x42, ++ 0x79, 0x41, 0x34, 0x69, 0x6D, 0x57, 0x30, 0x61, 0x75, 0x63, 0x6E, 0x6C, 0x38, 0x43, 0x41, 0x4D, 0x68, 0x5A, 0x61, 0x36, 0x33, 0x34, 0x52, 0x79, 0x6C, 0x73, 0x53, 0x71, 0x69, 0x0A, 0x4D, 0x64, 0x35, 0x6D, 0x42, 0x50, 0x66, 0x41, 0x64, 0x4F, ++ 0x68, 0x78, 0x33, 0x76, 0x38, 0x39, 0x57, 0x63, 0x79, 0x57, 0x4A, 0x68, 0x4B, 0x4C, 0x68, 0x5A, 0x56, 0x58, 0x47, 0x71, 0x74, 0x72, 0x64, 0x51, 0x74, 0x45, 0x50, 0x52, 0x45, 0x6F, 0x50, 0x48, 0x74, 0x68, 0x74, 0x2B, 0x4B, 0x50, 0x5A, 0x30, ++ 0x2F, 0x6C, 0x37, 0x44, 0x78, 0x4D, 0x59, 0x49, 0x42, 0x70, 0x56, 0x7A, 0x67, 0x65, 0x41, 0x56, 0x75, 0x4E, 0x56, 0x65, 0x6A, 0x48, 0x33, 0x38, 0x44, 0x4D, 0x0A, 0x64, 0x79, 0x4D, 0x30, 0x53, 0x58, 0x56, 0x38, 0x39, 0x70, 0x67, 0x52, 0x36, ++ 0x79, 0x33, 0x65, 0x37, 0x55, 0x45, 0x75, 0x46, 0x41, 0x55, 0x43, 0x66, 0x2B, 0x44, 0x2B, 0x49, 0x4F, 0x73, 0x31, 0x35, 0x78, 0x47, 0x73, 0x49, 0x73, 0x35, 0x58, 0x50, 0x64, 0x37, 0x4A, 0x4D, 0x47, 0x30, 0x51, 0x41, 0x34, 0x58, 0x4E, 0x38, ++ 0x66, 0x2B, 0x4D, 0x46, 0x72, 0x58, 0x42, 0x73, 0x6A, 0x36, 0x49, 0x62, 0x47, 0x42, 0x2F, 0x6B, 0x45, 0x2B, 0x56, 0x39, 0x2F, 0x59, 0x74, 0x0A, 0x72, 0x51, 0x45, 0x35, 0x42, 0x77, 0x54, 0x36, 0x64, 0x59, 0x42, 0x39, 0x76, 0x30, 0x6C, 0x51, ++ 0x37, 0x65, 0x2F, 0x4A, 0x78, 0x48, 0x77, 0x63, 0x36, 0x34, 0x42, 0x2B, 0x32, 0x37, 0x62, 0x51, 0x33, 0x52, 0x50, 0x2B, 0x79, 0x64, 0x4F, 0x63, 0x31, 0x37, 0x4B, 0x58, 0x71, 0x51, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6F, 0x30, 0x49, 0x77, ++ 0x51, 0x44, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x0A, 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, ++ 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x78, 0x68, 0x66, 0x51, 0x76, 0x4B, 0x6A, 0x71, 0x41, 0x6B, 0x50, 0x79, 0x47, 0x77, 0x61, 0x5A, 0x58, 0x53, 0x75, ++ 0x51, 0x49, 0x4C, 0x6E, 0x58, 0x6E, 0x4F, 0x51, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x0A, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x42, 0x41, 0x44, 0x52, 0x68, 0x32, 0x56, ++ 0x61, 0x31, 0x45, 0x6F, 0x64, 0x56, 0x54, 0x64, 0x32, 0x6A, 0x4E, 0x54, 0x46, 0x47, 0x75, 0x36, 0x51, 0x48, 0x63, 0x72, 0x78, 0x66, 0x59, 0x57, 0x4C, 0x6F, 0x70, 0x66, 0x73, 0x4C, 0x4E, 0x37, 0x45, 0x38, 0x74, 0x72, 0x50, 0x36, 0x4B, 0x5A, ++ 0x31, 0x2F, 0x41, 0x76, 0x57, 0x6B, 0x79, 0x61, 0x69, 0x54, 0x74, 0x33, 0x70, 0x78, 0x0A, 0x4B, 0x47, 0x6D, 0x50, 0x63, 0x2B, 0x46, 0x53, 0x6B, 0x4E, 0x72, 0x56, 0x76, 0x6A, 0x72, 0x6C, 0x74, 0x33, 0x5A, 0x71, 0x56, 0x6F, 0x41, 0x68, 0x33, ++ 0x31, 0x33, 0x6D, 0x36, 0x54, 0x71, 0x65, 0x35, 0x54, 0x37, 0x32, 0x6F, 0x6D, 0x6E, 0x48, 0x4B, 0x67, 0x71, 0x77, 0x47, 0x45, 0x66, 0x63, 0x49, 0x48, 0x42, 0x39, 0x55, 0x71, 0x4D, 0x2B, 0x57, 0x58, 0x7A, 0x42, 0x75, 0x73, 0x6E, 0x49, 0x46, ++ 0x55, 0x42, 0x68, 0x79, 0x6E, 0x4C, 0x57, 0x63, 0x4B, 0x7A, 0x53, 0x0A, 0x74, 0x2F, 0x41, 0x63, 0x35, 0x49, 0x59, 0x70, 0x38, 0x4D, 0x37, 0x76, 0x61, 0x47, 0x50, 0x51, 0x74, 0x53, 0x43, 0x4B, 0x46, 0x57, 0x47, 0x61, 0x66, 0x6F, 0x61, 0x59, ++ 0x74, 0x4D, 0x6E, 0x43, 0x64, 0x76, 0x76, 0x4D, 0x75, 0x6A, 0x41, 0x57, 0x7A, 0x4B, 0x4E, 0x68, 0x78, 0x6E, 0x51, 0x54, 0x35, 0x57, 0x76, 0x76, 0x6F, 0x78, 0x58, 0x71, 0x41, 0x2F, 0x34, 0x54, 0x69, 0x32, 0x54, 0x6B, 0x30, 0x38, 0x48, 0x53, ++ 0x36, 0x49, 0x54, 0x37, 0x53, 0x64, 0x45, 0x51, 0x0A, 0x54, 0x58, 0x6C, 0x6D, 0x36, 0x36, 0x72, 0x39, 0x39, 0x49, 0x30, 0x78, 0x48, 0x6E, 0x41, 0x55, 0x72, 0x64, 0x7A, 0x65, 0x5A, 0x78, 0x4E, 0x4D, 0x67, 0x52, 0x56, 0x68, 0x76, 0x4C, 0x66, ++ 0x5A, 0x6B, 0x58, 0x64, 0x78, 0x47, 0x59, 0x46, 0x67, 0x75, 0x2F, 0x42, 0x59, 0x70, 0x62, 0x57, 0x63, 0x43, 0x2F, 0x65, 0x50, 0x49, 0x6C, 0x55, 0x6E, 0x77, 0x45, 0x73, 0x42, 0x62, 0x54, 0x75, 0x5A, 0x44, 0x64, 0x51, 0x64, 0x6D, 0x32, 0x4E, ++ 0x6E, 0x4C, 0x39, 0x44, 0x75, 0x0A, 0x44, 0x63, 0x70, 0x6D, 0x76, 0x4A, 0x52, 0x50, 0x70, 0x71, 0x33, 0x74, 0x2F, 0x4F, 0x35, 0x6A, 0x72, 0x46, 0x63, 0x2F, 0x5A, 0x53, 0x58, 0x50, 0x73, 0x6F, 0x61, 0x50, 0x30, 0x41, 0x6A, 0x2F, 0x75, 0x48, ++ 0x59, 0x55, 0x62, 0x74, 0x37, 0x6C, 0x4A, 0x2B, 0x79, 0x72, 0x65, 0x4C, 0x56, 0x54, 0x75, 0x62, 0x59, 0x2F, 0x36, 0x43, 0x44, 0x35, 0x30, 0x71, 0x69, 0x2B, 0x59, 0x55, 0x62, 0x4B, 0x68, 0x34, 0x79, 0x45, 0x38, 0x2F, 0x6E, 0x78, 0x6F, 0x47, ++ 0x69, 0x62, 0x0A, 0x49, 0x68, 0x36, 0x42, 0x4A, 0x70, 0x73, 0x51, 0x42, 0x4A, 0x46, 0x78, 0x77, 0x41, 0x59, 0x66, 0x33, 0x4B, 0x44, 0x54, 0x75, 0x56, 0x61, 0x6E, 0x34, 0x35, 0x67, 0x74, 0x66, 0x34, 0x4F, 0x64, 0x33, 0x34, 0x77, 0x72, 0x6E, ++ 0x44, 0x4B, 0x4F, 0x4D, 0x70, 0x54, 0x77, 0x41, 0x54, 0x77, 0x69, 0x4B, 0x70, 0x39, 0x44, 0x77, 0x69, 0x37, 0x44, 0x6D, 0x44, 0x6B, 0x48, 0x4F, 0x48, 0x76, 0x38, 0x58, 0x67, 0x42, 0x43, 0x48, 0x2F, 0x4D, 0x79, 0x4A, 0x6E, 0x6D, 0x44, 0x0A, ++ 0x68, 0x50, 0x62, 0x6C, 0x38, 0x4D, 0x46, 0x52, 0x45, 0x73, 0x41, 0x4C, 0x48, 0x67, 0x51, 0x6A, 0x44, 0x46, 0x53, 0x6C, 0x54, 0x43, 0x39, 0x4A, 0x78, 0x55, 0x72, 0x52, 0x74, 0x6D, 0x35, 0x67, 0x44, 0x57, 0x76, 0x38, 0x61, 0x34, 0x75, 0x46, ++ 0x4A, 0x47, 0x53, 0x33, 0x69, 0x51, 0x36, 0x72, 0x4A, 0x55, 0x64, 0x62, 0x50, 0x4D, 0x39, 0x2B, 0x53, 0x62, 0x33, 0x48, 0x36, 0x51, 0x72, 0x47, 0x32, 0x76, 0x64, 0x2B, 0x44, 0x68, 0x63, 0x49, 0x30, 0x30, 0x69, 0x58, 0x0A, 0x30, 0x48, 0x47, ++ 0x53, 0x38, 0x41, 0x38, 0x35, 0x50, 0x6A, 0x52, 0x71, 0x48, 0x48, 0x33, 0x59, 0x38, 0x69, 0x4B, 0x75, 0x75, 0x32, 0x6E, 0x30, 0x4D, 0x37, 0x53, 0x6D, 0x53, 0x46, 0x58, 0x52, 0x44, 0x77, 0x34, 0x6D, 0x36, 0x4F, 0x79, 0x32, 0x43, 0x79, 0x32, ++ 0x6E, 0x68, 0x54, 0x58, 0x4E, 0x2F, 0x56, 0x6E, 0x49, 0x6E, 0x39, 0x48, 0x4E, 0x50, 0x6C, 0x6F, 0x70, 0x4E, 0x4C, 0x6B, 0x39, 0x68, 0x4D, 0x36, 0x78, 0x5A, 0x64, 0x52, 0x5A, 0x6B, 0x5A, 0x46, 0x57, 0x0A, 0x64, 0x53, 0x48, 0x42, 0x64, 0x35, ++ 0x37, 0x35, 0x65, 0x75, 0x46, 0x67, 0x6E, 0x64, 0x4F, 0x74, 0x42, 0x42, 0x6A, 0x30, 0x66, 0x4F, 0x74, 0x65, 0x6B, 0x34, 0x39, 0x54, 0x53, 0x69, 0x49, 0x70, 0x2B, 0x45, 0x67, 0x72, 0x50, 0x6B, 0x32, 0x47, 0x72, 0x46, 0x74, 0x2F, 0x79, 0x77, ++ 0x61, 0x5A, 0x57, 0x57, 0x44, 0x59, 0x57, 0x47, 0x57, 0x56, 0x6A, 0x55, 0x54, 0x52, 0x39, 0x33, 0x39, 0x2B, 0x4A, 0x33, 0x39, 0x39, 0x72, 0x6F, 0x44, 0x31, 0x42, 0x30, 0x79, 0x32, 0x0A, 0x50, 0x70, 0x78, 0x78, 0x56, 0x4A, 0x6B, 0x45, 0x53, ++ 0x2F, 0x31, 0x59, 0x2B, 0x5A, 0x6A, 0x30, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x44, 0x69, 0x67, 0x69, 0x43, ++ 0x65, 0x72, 0x74, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x32, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, ++ 0x49, 0x49, 0x44, 0x6C, 0x6A, 0x43, 0x43, 0x41, 0x6E, 0x36, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x43, 0x35, 0x4D, 0x63, 0x4F, 0x74, 0x59, 0x35, 0x5A, 0x2B, 0x70, 0x6E, 0x49, 0x37, 0x2F, 0x44, 0x72, 0x35, 0x72, 0x30, 0x53, ++ 0x7A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x42, 0x6C, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0A, 0x45, 0x77, 0x4A, 0x56, ++ 0x55, 0x7A, 0x45, 0x56, 0x4D, 0x42, 0x4D, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x4D, 0x52, 0x47, 0x6C, 0x6E, 0x61, 0x55, 0x4E, 0x6C, 0x63, 0x6E, 0x51, 0x67, 0x53, 0x57, 0x35, 0x6A, 0x4D, 0x52, 0x6B, 0x77, 0x46, 0x77, 0x59, 0x44, ++ 0x56, 0x51, 0x51, 0x4C, 0x45, 0x78, 0x42, 0x33, 0x64, 0x33, 0x63, 0x75, 0x5A, 0x47, 0x6C, 0x6E, 0x61, 0x57, 0x4E, 0x6C, 0x63, 0x6E, 0x51, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4D, 0x53, 0x51, 0x77, 0x0A, 0x49, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, ++ 0x44, 0x45, 0x78, 0x74, 0x45, 0x61, 0x57, 0x64, 0x70, 0x51, 0x32, 0x56, 0x79, 0x64, 0x43, 0x42, 0x42, 0x63, 0x33, 0x4E, 0x31, 0x63, 0x6D, 0x56, 0x6B, 0x49, 0x45, 0x6C, 0x45, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x52, 0x7A, 0x49, ++ 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x54, 0x4D, 0x77, 0x4F, 0x44, 0x41, 0x78, 0x4D, 0x54, 0x49, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x57, 0x68, 0x63, 0x4E, 0x4D, 0x7A, 0x67, 0x77, 0x0A, 0x4D, 0x54, 0x45, 0x31, 0x4D, 0x54, 0x49, 0x77, 0x4D, 0x44, ++ 0x41, 0x77, 0x57, 0x6A, 0x42, 0x6C, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x56, 0x4D, 0x42, 0x4D, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x4D, 0x52, 0x47, ++ 0x6C, 0x6E, 0x61, 0x55, 0x4E, 0x6C, 0x63, 0x6E, 0x51, 0x67, 0x53, 0x57, 0x35, 0x6A, 0x4D, 0x52, 0x6B, 0x77, 0x46, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, 0x0A, 0x45, 0x78, 0x42, 0x33, 0x64, 0x33, 0x63, 0x75, 0x5A, 0x47, 0x6C, 0x6E, 0x61, ++ 0x57, 0x4E, 0x6C, 0x63, 0x6E, 0x51, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4D, 0x53, 0x51, 0x77, 0x49, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x74, 0x45, 0x61, 0x57, 0x64, 0x70, 0x51, 0x32, 0x56, 0x79, 0x64, 0x43, 0x42, 0x42, 0x63, ++ 0x33, 0x4E, 0x31, 0x63, 0x6D, 0x56, 0x6B, 0x49, 0x45, 0x6C, 0x45, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x52, 0x7A, 0x49, 0x77, 0x0A, 0x67, 0x67, 0x45, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, ++ 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x45, 0x4B, 0x41, 0x6F, 0x49, 0x42, 0x41, 0x51, 0x44, 0x5A, 0x35, 0x79, 0x67, 0x76, 0x55, 0x6A, 0x38, 0x32, 0x63, 0x6B, 0x6D, 0x49, ++ 0x6B, 0x7A, 0x54, 0x7A, 0x2B, 0x47, 0x6F, 0x65, 0x4D, 0x56, 0x53, 0x41, 0x6E, 0x36, 0x31, 0x55, 0x51, 0x62, 0x56, 0x48, 0x0A, 0x33, 0x35, 0x61, 0x6F, 0x31, 0x4B, 0x2B, 0x41, 0x4C, 0x62, 0x6B, 0x4B, 0x7A, 0x33, 0x58, 0x39, 0x69, 0x61, 0x56, ++ 0x39, 0x4A, 0x50, 0x72, 0x6A, 0x49, 0x67, 0x77, 0x72, 0x76, 0x4A, 0x55, 0x58, 0x43, 0x7A, 0x4F, 0x2F, 0x47, 0x55, 0x31, 0x42, 0x42, 0x70, 0x41, 0x41, 0x76, 0x51, 0x78, 0x4E, 0x45, 0x50, 0x34, 0x48, 0x74, 0x65, 0x63, 0x63, 0x62, 0x69, 0x4A, ++ 0x56, 0x4D, 0x57, 0x57, 0x58, 0x76, 0x64, 0x4D, 0x58, 0x30, 0x68, 0x35, 0x69, 0x38, 0x39, 0x76, 0x71, 0x0A, 0x62, 0x46, 0x43, 0x4D, 0x50, 0x34, 0x51, 0x4D, 0x6C, 0x73, 0x2B, 0x33, 0x79, 0x77, 0x50, 0x67, 0x79, 0x6D, 0x32, 0x68, 0x46, 0x45, ++ 0x77, 0x62, 0x69, 0x64, 0x33, 0x74, 0x41, 0x4C, 0x42, 0x53, 0x66, 0x4B, 0x2B, 0x52, 0x62, 0x4C, 0x45, 0x34, 0x45, 0x39, 0x48, 0x70, 0x45, 0x67, 0x6A, 0x41, 0x41, 0x4C, 0x41, 0x63, 0x4B, 0x78, 0x48, 0x61, 0x64, 0x33, 0x41, 0x32, 0x6D, 0x36, ++ 0x37, 0x4F, 0x65, 0x59, 0x66, 0x63, 0x67, 0x6E, 0x44, 0x6D, 0x43, 0x58, 0x52, 0x77, 0x0A, 0x56, 0x57, 0x6D, 0x76, 0x6F, 0x32, 0x69, 0x66, 0x76, 0x39, 0x32, 0x32, 0x65, 0x62, 0x50, 0x79, 0x6E, 0x58, 0x41, 0x70, 0x56, 0x66, 0x53, 0x72, 0x2F, ++ 0x35, 0x56, 0x68, 0x38, 0x38, 0x6C, 0x41, 0x62, 0x78, 0x33, 0x52, 0x76, 0x70, 0x4F, 0x37, 0x30, 0x34, 0x67, 0x71, 0x75, 0x35, 0x32, 0x2F, 0x63, 0x6C, 0x70, 0x57, 0x63, 0x54, 0x73, 0x2F, 0x31, 0x50, 0x50, 0x52, 0x43, 0x76, 0x34, 0x6F, 0x37, ++ 0x36, 0x50, 0x75, 0x32, 0x5A, 0x6D, 0x76, 0x41, 0x39, 0x4F, 0x50, 0x0A, 0x59, 0x4C, 0x66, 0x79, 0x6B, 0x71, 0x47, 0x78, 0x76, 0x59, 0x6D, 0x4A, 0x48, 0x7A, 0x44, 0x4E, 0x77, 0x36, 0x59, 0x75, 0x59, 0x6A, 0x4F, 0x75, 0x46, 0x67, 0x4A, 0x33, ++ 0x52, 0x46, 0x72, 0x6E, 0x67, 0x51, 0x6F, 0x38, 0x70, 0x30, 0x51, 0x75, 0x65, 0x62, 0x67, 0x2F, 0x42, 0x4C, 0x78, 0x63, 0x6F, 0x49, 0x66, 0x68, 0x47, 0x36, 0x39, 0x52, 0x6A, 0x73, 0x33, 0x73, 0x4C, 0x50, 0x72, 0x34, 0x2F, 0x6D, 0x33, 0x77, ++ 0x4F, 0x6E, 0x79, 0x71, 0x69, 0x2B, 0x52, 0x6E, 0x0A, 0x6C, 0x54, 0x47, 0x4E, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, 0x51, 0x6A, 0x42, 0x41, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, ++ 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x47, 0x47, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, ++ 0x57, 0x42, 0x42, 0x54, 0x4F, 0x0A, 0x77, 0x30, 0x71, 0x35, 0x6D, 0x56, 0x58, 0x79, 0x75, 0x4E, 0x74, 0x67, 0x76, 0x36, 0x6C, 0x2B, 0x76, 0x56, 0x61, 0x31, 0x6C, 0x7A, 0x61, 0x6E, 0x31, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, ++ 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x51, 0x45, 0x41, 0x79, 0x71, 0x56, 0x56, 0x6A, 0x4F, 0x50, 0x49, 0x51, 0x57, 0x35, 0x70, 0x4A, 0x36, 0x64, 0x31, 0x45, 0x65, 0x38, 0x38, 0x68, 0x6A, ++ 0x5A, 0x76, 0x0A, 0x30, 0x70, 0x33, 0x47, 0x65, 0x44, 0x67, 0x64, 0x61, 0x5A, 0x61, 0x69, 0x6B, 0x6D, 0x6B, 0x75, 0x4F, 0x47, 0x79, 0x62, 0x66, 0x51, 0x54, 0x55, 0x69, 0x61, 0x57, 0x78, 0x4D, 0x54, 0x65, 0x4B, 0x79, 0x53, 0x48, 0x4D, 0x71, ++ 0x32, 0x7A, 0x4E, 0x69, 0x78, 0x79, 0x61, 0x31, 0x72, 0x39, 0x49, 0x30, 0x6A, 0x4A, 0x6D, 0x77, 0x59, 0x72, 0x41, 0x38, 0x79, 0x38, 0x36, 0x37, 0x38, 0x44, 0x6A, 0x31, 0x4A, 0x47, 0x47, 0x30, 0x56, 0x44, 0x6A, 0x41, 0x39, 0x74, 0x7A, 0x0A, ++ 0x64, 0x32, 0x39, 0x4B, 0x4F, 0x56, 0x50, 0x74, 0x33, 0x69, 0x62, 0x48, 0x74, 0x58, 0x32, 0x76, 0x4B, 0x30, 0x4C, 0x52, 0x64, 0x57, 0x4C, 0x6A, 0x53, 0x69, 0x73, 0x43, 0x78, 0x31, 0x42, 0x4C, 0x34, 0x47, 0x6E, 0x69, 0x6C, 0x6D, 0x77, 0x4F, ++ 0x52, 0x47, 0x59, 0x51, 0x52, 0x49, 0x2B, 0x74, 0x42, 0x65, 0x76, 0x34, 0x65, 0x61, 0x79, 0x6D, 0x47, 0x2B, 0x67, 0x33, 0x4E, 0x4A, 0x31, 0x54, 0x79, 0x57, 0x47, 0x71, 0x6F, 0x6C, 0x4B, 0x76, 0x53, 0x6E, 0x41, 0x57, 0x0A, 0x68, 0x73, 0x49, ++ 0x36, 0x79, 0x4C, 0x45, 0x54, 0x63, 0x44, 0x62, 0x59, 0x7A, 0x2B, 0x37, 0x30, 0x43, 0x6A, 0x54, 0x56, 0x57, 0x30, 0x7A, 0x39, 0x42, 0x35, 0x79, 0x69, 0x75, 0x74, 0x6B, 0x42, 0x63, 0x6C, 0x7A, 0x7A, 0x54, 0x63, 0x48, 0x64, 0x44, 0x72, 0x45, ++ 0x63, 0x44, 0x63, 0x52, 0x6A, 0x76, 0x71, 0x33, 0x30, 0x46, 0x50, 0x75, 0x4A, 0x37, 0x4B, 0x4A, 0x42, 0x44, 0x6B, 0x7A, 0x4D, 0x79, 0x46, 0x64, 0x41, 0x30, 0x47, 0x34, 0x44, 0x71, 0x73, 0x30, 0x4D, 0x0A, 0x6A, 0x6F, 0x6D, 0x5A, 0x6D, 0x57, ++ 0x7A, 0x77, 0x50, 0x44, 0x43, 0x76, 0x4F, 0x4E, 0x39, 0x76, 0x76, 0x4B, 0x4F, 0x2B, 0x4B, 0x53, 0x41, 0x6E, 0x71, 0x33, 0x54, 0x2F, 0x45, 0x79, 0x4A, 0x34, 0x33, 0x70, 0x64, 0x53, 0x56, 0x52, 0x36, 0x44, 0x74, 0x56, 0x51, 0x67, 0x41, 0x2B, ++ 0x36, 0x75, 0x77, 0x45, 0x39, 0x57, 0x33, 0x6A, 0x66, 0x4D, 0x77, 0x33, 0x2B, 0x71, 0x42, 0x43, 0x65, 0x37, 0x30, 0x33, 0x65, 0x34, 0x59, 0x74, 0x73, 0x58, 0x66, 0x4A, 0x77, 0x6F, 0x0A, 0x49, 0x68, 0x4E, 0x7A, 0x62, 0x4D, 0x38, 0x6D, 0x39, ++ 0x59, 0x6F, 0x70, 0x35, 0x77, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x44, 0x69, 0x67, 0x69, 0x43, ++ 0x65, 0x72, 0x74, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x33, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, ++ 0x49, 0x49, 0x43, 0x52, 0x6A, 0x43, 0x43, 0x41, 0x63, 0x32, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x43, 0x36, 0x46, 0x61, 0x2B, 0x68, 0x33, 0x66, 0x6F, 0x4C, 0x56, 0x4A, 0x52, 0x4B, 0x2F, 0x4E, 0x4A, 0x4B, 0x42, 0x73, 0x37, ++ 0x44, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x7A, 0x42, 0x6C, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, 0x0A, 0x55, 0x7A, 0x45, 0x56, ++ 0x4D, 0x42, 0x4D, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x4D, 0x52, 0x47, 0x6C, 0x6E, 0x61, 0x55, 0x4E, 0x6C, 0x63, 0x6E, 0x51, 0x67, 0x53, 0x57, 0x35, 0x6A, 0x4D, 0x52, 0x6B, 0x77, 0x46, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, ++ 0x45, 0x78, 0x42, 0x33, 0x64, 0x33, 0x63, 0x75, 0x5A, 0x47, 0x6C, 0x6E, 0x61, 0x57, 0x4E, 0x6C, 0x63, 0x6E, 0x51, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4D, 0x53, 0x51, 0x77, 0x49, 0x67, 0x59, 0x44, 0x0A, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x74, ++ 0x45, 0x61, 0x57, 0x64, 0x70, 0x51, 0x32, 0x56, 0x79, 0x64, 0x43, 0x42, 0x42, 0x63, 0x33, 0x4E, 0x31, 0x63, 0x6D, 0x56, 0x6B, 0x49, 0x45, 0x6C, 0x45, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x52, 0x7A, 0x4D, 0x77, 0x48, 0x68, 0x63, ++ 0x4E, 0x4D, 0x54, 0x4D, 0x77, 0x4F, 0x44, 0x41, 0x78, 0x4D, 0x54, 0x49, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x57, 0x68, 0x63, 0x4E, 0x4D, 0x7A, 0x67, 0x77, 0x4D, 0x54, 0x45, 0x31, 0x0A, 0x4D, 0x54, 0x49, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x57, 0x6A, ++ 0x42, 0x6C, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x56, 0x4D, 0x42, 0x4D, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x4D, 0x52, 0x47, 0x6C, 0x6E, 0x61, 0x55, ++ 0x4E, 0x6C, 0x63, 0x6E, 0x51, 0x67, 0x53, 0x57, 0x35, 0x6A, 0x4D, 0x52, 0x6B, 0x77, 0x46, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, 0x45, 0x78, 0x42, 0x33, 0x0A, 0x64, 0x33, 0x63, 0x75, 0x5A, 0x47, 0x6C, 0x6E, 0x61, 0x57, 0x4E, 0x6C, 0x63, ++ 0x6E, 0x51, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4D, 0x53, 0x51, 0x77, 0x49, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x74, 0x45, 0x61, 0x57, 0x64, 0x70, 0x51, 0x32, 0x56, 0x79, 0x64, 0x43, 0x42, 0x42, 0x63, 0x33, 0x4E, 0x31, 0x63, ++ 0x6D, 0x56, 0x6B, 0x49, 0x45, 0x6C, 0x45, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x52, 0x7A, 0x4D, 0x77, 0x64, 0x6A, 0x41, 0x51, 0x0A, 0x42, 0x67, 0x63, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x49, 0x42, 0x42, 0x67, 0x55, 0x72, ++ 0x67, 0x51, 0x51, 0x41, 0x49, 0x67, 0x4E, 0x69, 0x41, 0x41, 0x51, 0x5A, 0x35, 0x37, 0x79, 0x73, 0x52, 0x47, 0x58, 0x74, 0x7A, 0x62, 0x67, 0x2F, 0x57, 0x50, 0x75, 0x4E, 0x73, 0x56, 0x65, 0x70, 0x52, 0x43, 0x30, 0x46, 0x46, 0x66, 0x4C, 0x76, ++ 0x43, 0x2F, 0x38, 0x51, 0x64, 0x4A, 0x2B, 0x31, 0x59, 0x6C, 0x4A, 0x66, 0x5A, 0x6E, 0x34, 0x66, 0x35, 0x64, 0x77, 0x62, 0x0A, 0x52, 0x58, 0x6B, 0x4C, 0x7A, 0x4D, 0x5A, 0x54, 0x43, 0x70, 0x32, 0x4E, 0x58, 0x51, 0x4C, 0x5A, 0x71, 0x56, 0x6E, ++ 0x65, 0x41, 0x6C, 0x72, 0x32, 0x6C, 0x53, 0x6F, 0x4F, 0x6A, 0x54, 0x68, 0x4B, 0x69, 0x6B, 0x6E, 0x47, 0x76, 0x4D, 0x59, 0x44, 0x4F, 0x41, 0x64, 0x66, 0x56, 0x64, 0x70, 0x2B, 0x43, 0x57, 0x37, 0x69, 0x66, 0x31, 0x37, 0x51, 0x52, 0x53, 0x41, ++ 0x50, 0x57, 0x58, 0x59, 0x51, 0x31, 0x71, 0x41, 0x6B, 0x38, 0x43, 0x33, 0x65, 0x4E, 0x76, 0x4A, 0x73, 0x0A, 0x4B, 0x54, 0x6D, 0x6A, 0x51, 0x6A, 0x42, 0x41, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, ++ 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x47, 0x47, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, ++ 0x51, 0x57, 0x42, 0x42, 0x54, 0x4C, 0x30, 0x4C, 0x32, 0x70, 0x34, 0x5A, 0x67, 0x46, 0x0A, 0x55, 0x61, 0x46, 0x4E, 0x4E, 0x36, 0x4B, 0x44, 0x65, 0x63, 0x36, 0x4E, 0x48, 0x53, 0x72, 0x6B, 0x68, 0x44, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, ++ 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x77, 0x4E, 0x6E, 0x41, 0x44, 0x42, 0x6B, 0x41, 0x6A, 0x41, 0x6C, 0x70, 0x49, 0x46, 0x46, 0x41, 0x6D, 0x73, 0x53, 0x53, 0x33, 0x56, 0x30, 0x54, 0x38, 0x67, 0x6A, 0x34, 0x33, 0x44, 0x79, 0x64, ++ 0x58, 0x4C, 0x65, 0x66, 0x49, 0x6E, 0x77, 0x7A, 0x35, 0x46, 0x79, 0x0A, 0x59, 0x5A, 0x35, 0x65, 0x45, 0x4A, 0x4A, 0x5A, 0x56, 0x72, 0x6D, 0x44, 0x78, 0x78, 0x44, 0x6E, 0x4F, 0x4F, 0x6C, 0x59, 0x4A, 0x6A, 0x5A, 0x39, 0x31, 0x65, 0x51, 0x30, ++ 0x68, 0x6A, 0x6B, 0x43, 0x4D, 0x48, 0x77, 0x32, 0x55, 0x2F, 0x41, 0x77, 0x35, 0x57, 0x4A, 0x6A, 0x4F, 0x70, 0x6E, 0x69, 0x74, 0x71, 0x4D, 0x37, 0x6D, 0x7A, 0x54, 0x36, 0x48, 0x74, 0x6F, 0x51, 0x6B, 0x6E, 0x46, 0x65, 0x6B, 0x52, 0x4F, 0x6E, ++ 0x33, 0x61, 0x52, 0x75, 0x6B, 0x73, 0x77, 0x79, 0x0A, 0x31, 0x76, 0x55, 0x68, 0x5A, 0x73, 0x63, 0x76, 0x36, 0x70, 0x5A, 0x6A, 0x61, 0x6D, 0x56, 0x46, 0x6B, 0x70, 0x55, 0x42, 0x74, 0x41, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, ++ 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, ++ 0x74, 0x20, 0x47, 0x32, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, ++ 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x44, 0x6A, 0x6A, 0x43, 0x43, 0x41, 0x6E, 0x61, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x41, 0x7A, 0x72, ++ 0x78, 0x35, 0x71, 0x63, 0x52, 0x71, 0x61, 0x43, 0x37, 0x4B, 0x47, 0x53, 0x78, 0x48, 0x51, 0x6E, 0x36, 0x35, 0x54, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x42, ++ 0x68, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0A, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x56, 0x4D, 0x42, 0x4D, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x4D, 0x52, 0x47, 0x6C, 0x6E, 0x61, 0x55, ++ 0x4E, 0x6C, 0x63, 0x6E, 0x51, 0x67, 0x53, 0x57, 0x35, 0x6A, 0x4D, 0x52, 0x6B, 0x77, 0x46, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, 0x45, 0x78, 0x42, 0x33, 0x64, 0x33, 0x63, 0x75, 0x5A, 0x47, 0x6C, 0x6E, 0x61, 0x57, 0x4E, 0x6C, 0x63, 0x6E, ++ 0x51, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4D, 0x53, 0x41, 0x77, 0x0A, 0x48, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x64, 0x45, 0x61, 0x57, 0x64, 0x70, 0x51, 0x32, 0x56, 0x79, 0x64, 0x43, 0x42, 0x48, 0x62, 0x47, 0x39, 0x69, 0x59, ++ 0x57, 0x77, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x48, 0x4D, 0x6A, 0x41, 0x65, 0x46, 0x77, 0x30, 0x78, 0x4D, 0x7A, 0x41, 0x34, 0x4D, 0x44, 0x45, 0x78, 0x4D, 0x6A, 0x41, 0x77, 0x4D, 0x44, 0x42, 0x61, 0x46, 0x77, 0x30, 0x7A, 0x4F, ++ 0x44, 0x41, 0x78, 0x4D, 0x54, 0x55, 0x78, 0x0A, 0x4D, 0x6A, 0x41, 0x77, 0x4D, 0x44, 0x42, 0x61, 0x4D, 0x47, 0x45, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6C, 0x56, 0x54, 0x4D, 0x52, 0x55, 0x77, ++ 0x45, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x77, 0x78, 0x45, 0x61, 0x57, 0x64, 0x70, 0x51, 0x32, 0x56, 0x79, 0x64, 0x43, 0x42, 0x4A, 0x62, 0x6D, 0x4D, 0x78, 0x47, 0x54, 0x41, 0x58, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x73, 0x54, ++ 0x45, 0x48, 0x64, 0x33, 0x0A, 0x64, 0x79, 0x35, 0x6B, 0x61, 0x57, 0x64, 0x70, 0x59, 0x32, 0x56, 0x79, 0x64, 0x43, 0x35, 0x6A, 0x62, 0x32, 0x30, 0x78, 0x49, 0x44, 0x41, 0x65, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x46, 0x30, 0x52, ++ 0x70, 0x5A, 0x32, 0x6C, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x49, 0x45, 0x64, 0x73, 0x62, 0x32, 0x4A, 0x68, 0x62, 0x43, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x63, 0x79, 0x4D, 0x49, 0x49, 0x42, 0x49, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, ++ 0x71, 0x0A, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x51, 0x38, 0x41, 0x4D, 0x49, 0x49, 0x42, 0x43, 0x67, 0x4B, 0x43, 0x41, 0x51, 0x45, 0x41, 0x75, 0x7A, 0x66, 0x4E, 0x4E, 0x4E, ++ 0x78, 0x37, 0x61, 0x38, 0x6D, 0x79, 0x61, 0x4A, 0x43, 0x74, 0x53, 0x6E, 0x58, 0x2F, 0x52, 0x72, 0x6F, 0x68, 0x43, 0x67, 0x69, 0x4E, 0x39, 0x52, 0x6C, 0x55, 0x79, 0x66, 0x75, 0x49, 0x32, 0x2F, 0x4F, 0x75, 0x38, 0x6A, 0x71, 0x4A, 0x0A, 0x6B, ++ 0x54, 0x78, 0x36, 0x35, 0x71, 0x73, 0x47, 0x47, 0x6D, 0x76, 0x50, 0x72, 0x43, 0x33, 0x6F, 0x58, 0x67, 0x6B, 0x6B, 0x52, 0x4C, 0x70, 0x69, 0x6D, 0x6E, 0x37, 0x57, 0x6F, 0x36, 0x68, 0x2B, 0x34, 0x46, 0x52, 0x31, 0x49, 0x41, 0x57, 0x73, 0x55, ++ 0x4C, 0x65, 0x63, 0x59, 0x78, 0x70, 0x73, 0x4D, 0x4E, 0x7A, 0x61, 0x48, 0x78, 0x6D, 0x78, 0x31, 0x78, 0x37, 0x65, 0x2F, 0x64, 0x66, 0x67, 0x79, 0x35, 0x53, 0x44, 0x4E, 0x36, 0x37, 0x73, 0x48, 0x30, 0x4E, 0x4F, 0x0A, 0x33, 0x58, 0x73, 0x73, ++ 0x30, 0x72, 0x30, 0x75, 0x70, 0x53, 0x2F, 0x6B, 0x71, 0x62, 0x69, 0x74, 0x4F, 0x74, 0x53, 0x5A, 0x70, 0x4C, 0x59, 0x6C, 0x36, 0x5A, 0x74, 0x72, 0x41, 0x47, 0x43, 0x53, 0x59, 0x50, 0x39, 0x50, 0x49, 0x55, 0x6B, 0x59, 0x39, 0x32, 0x65, 0x51, ++ 0x71, 0x32, 0x45, 0x47, 0x6E, 0x49, 0x2F, 0x79, 0x75, 0x75, 0x6D, 0x30, 0x36, 0x5A, 0x49, 0x79, 0x61, 0x37, 0x58, 0x7A, 0x56, 0x2B, 0x68, 0x64, 0x47, 0x38, 0x32, 0x4D, 0x48, 0x61, 0x75, 0x56, 0x0A, 0x42, 0x4A, 0x56, 0x4A, 0x38, 0x7A, 0x55, ++ 0x74, 0x6C, 0x75, 0x4E, 0x4A, 0x62, 0x64, 0x31, 0x33, 0x34, 0x2F, 0x74, 0x4A, 0x53, 0x37, 0x53, 0x73, 0x56, 0x51, 0x65, 0x70, 0x6A, 0x35, 0x57, 0x7A, 0x74, 0x43, 0x4F, 0x37, 0x54, 0x47, 0x31, 0x46, 0x38, 0x50, 0x61, 0x70, 0x73, 0x70, 0x55, ++ 0x77, 0x74, 0x50, 0x31, 0x4D, 0x56, 0x59, 0x77, 0x6E, 0x53, 0x6C, 0x63, 0x55, 0x66, 0x49, 0x4B, 0x64, 0x7A, 0x58, 0x4F, 0x53, 0x30, 0x78, 0x5A, 0x4B, 0x42, 0x67, 0x79, 0x4D, 0x0A, 0x55, 0x4E, 0x47, 0x50, 0x48, 0x67, 0x6D, 0x2B, 0x46, 0x36, ++ 0x48, 0x6D, 0x49, 0x63, 0x72, 0x39, 0x67, 0x2B, 0x55, 0x51, 0x76, 0x49, 0x4F, 0x6C, 0x43, 0x73, 0x52, 0x6E, 0x4B, 0x50, 0x5A, 0x7A, 0x46, 0x42, 0x51, 0x39, 0x52, 0x6E, 0x62, 0x44, 0x68, 0x78, 0x53, 0x4A, 0x49, 0x54, 0x52, 0x4E, 0x72, 0x77, ++ 0x39, 0x46, 0x44, 0x4B, 0x5A, 0x4A, 0x6F, 0x62, 0x71, 0x37, 0x6E, 0x4D, 0x57, 0x78, 0x4D, 0x34, 0x4D, 0x70, 0x68, 0x51, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x0A, 0x6F, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x48, ++ 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x68, 0x6A, 0x41, 0x64, 0x42, ++ 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x54, 0x69, 0x4A, 0x55, 0x49, 0x42, 0x69, 0x56, 0x35, 0x75, 0x4E, 0x75, 0x0A, 0x35, 0x67, 0x2F, 0x36, 0x2B, 0x72, 0x6B, 0x53, 0x37, 0x51, 0x59, 0x58, 0x6A, 0x7A, 0x6B, 0x77, ++ 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x42, 0x41, 0x47, 0x42, 0x6E, 0x4B, 0x4A, 0x52, 0x76, 0x44, 0x6B, 0x68, 0x6A, 0x36, 0x7A, 0x48, 0x64, ++ 0x36, 0x6D, 0x63, 0x59, 0x31, 0x59, 0x6C, 0x39, 0x50, 0x4D, 0x57, 0x4C, 0x53, 0x6E, 0x2F, 0x70, 0x76, 0x74, 0x73, 0x72, 0x0A, 0x46, 0x39, 0x2B, 0x77, 0x58, 0x33, 0x4E, 0x33, 0x4B, 0x6A, 0x49, 0x54, 0x4F, 0x59, 0x46, 0x6E, 0x51, 0x6F, 0x51, ++ 0x6A, 0x38, 0x6B, 0x56, 0x6E, 0x4E, 0x65, 0x79, 0x49, 0x76, 0x2F, 0x69, 0x50, 0x73, 0x47, 0x45, 0x4D, 0x4E, 0x4B, 0x53, 0x75, 0x49, 0x45, 0x79, 0x45, 0x78, 0x74, 0x76, 0x34, 0x4E, 0x65, 0x46, 0x32, 0x32, 0x64, 0x2B, 0x6D, 0x51, 0x72, 0x76, ++ 0x48, 0x52, 0x41, 0x69, 0x47, 0x66, 0x7A, 0x5A, 0x30, 0x4A, 0x46, 0x72, 0x61, 0x62, 0x41, 0x30, 0x55, 0x0A, 0x57, 0x54, 0x57, 0x39, 0x38, 0x6B, 0x6E, 0x64, 0x74, 0x68, 0x2F, 0x4A, 0x73, 0x77, 0x31, 0x48, 0x4B, 0x6A, 0x32, 0x5A, 0x4C, 0x37, ++ 0x74, 0x63, 0x75, 0x37, 0x58, 0x55, 0x49, 0x4F, 0x47, 0x5A, 0x58, 0x31, 0x4E, 0x47, 0x46, 0x64, 0x74, 0x6F, 0x6D, 0x2F, 0x44, 0x7A, 0x4D, 0x4E, 0x55, 0x2B, 0x4D, 0x65, 0x4B, 0x4E, 0x68, 0x4A, 0x37, 0x6A, 0x69, 0x74, 0x72, 0x61, 0x6C, 0x6A, ++ 0x34, 0x31, 0x45, 0x36, 0x56, 0x66, 0x38, 0x50, 0x6C, 0x77, 0x55, 0x48, 0x42, 0x48, 0x0A, 0x51, 0x52, 0x46, 0x58, 0x47, 0x55, 0x37, 0x41, 0x6A, 0x36, 0x34, 0x47, 0x78, 0x4A, 0x55, 0x54, 0x46, 0x79, 0x38, 0x62, 0x4A, 0x5A, 0x39, 0x31, 0x38, ++ 0x72, 0x47, 0x4F, 0x6D, 0x61, 0x46, 0x76, 0x45, 0x37, 0x46, 0x42, 0x63, 0x66, 0x36, 0x49, 0x4B, 0x73, 0x68, 0x50, 0x45, 0x43, 0x42, 0x56, 0x31, 0x2F, 0x4D, 0x55, 0x52, 0x65, 0x58, 0x67, 0x52, 0x50, 0x54, 0x71, 0x68, 0x35, 0x55, 0x79, 0x6B, ++ 0x77, 0x37, 0x2B, 0x55, 0x30, 0x62, 0x36, 0x4C, 0x4A, 0x33, 0x2F, 0x0A, 0x69, 0x79, 0x4B, 0x35, 0x53, 0x39, 0x6B, 0x4A, 0x52, 0x61, 0x54, 0x65, 0x70, 0x4C, 0x69, 0x61, 0x57, 0x4E, 0x30, 0x62, 0x66, 0x56, 0x4B, 0x66, 0x6A, 0x6C, 0x6C, 0x44, ++ 0x69, 0x49, 0x47, 0x6B, 0x6E, 0x69, 0x62, 0x56, 0x62, 0x36, 0x33, 0x64, 0x44, 0x63, 0x59, 0x33, 0x66, 0x65, 0x30, 0x44, 0x6B, 0x68, 0x76, 0x6C, 0x64, 0x31, 0x39, 0x32, 0x37, 0x6A, 0x79, 0x4E, 0x78, 0x46, 0x31, 0x57, 0x57, 0x36, 0x4C, 0x5A, ++ 0x5A, 0x6D, 0x36, 0x7A, 0x4E, 0x54, 0x66, 0x6C, 0x0A, 0x4D, 0x72, 0x59, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, ++ 0x0A, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x33, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, ++ 0x43, 0x50, 0x7A, 0x43, 0x43, 0x41, 0x63, 0x57, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x42, 0x56, 0x56, 0x57, 0x76, 0x50, 0x4A, 0x65, 0x70, 0x44, 0x55, 0x31, 0x77, 0x36, 0x51, 0x50, 0x31, 0x61, 0x74, 0x46, 0x63, 0x6A, 0x41, ++ 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x7A, 0x42, 0x68, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, 0x0A, 0x55, 0x7A, 0x45, 0x56, 0x4D, 0x42, ++ 0x4D, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x4D, 0x52, 0x47, 0x6C, 0x6E, 0x61, 0x55, 0x4E, 0x6C, 0x63, 0x6E, 0x51, 0x67, 0x53, 0x57, 0x35, 0x6A, 0x4D, 0x52, 0x6B, 0x77, 0x46, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, 0x45, 0x78, ++ 0x42, 0x33, 0x64, 0x33, 0x63, 0x75, 0x5A, 0x47, 0x6C, 0x6E, 0x61, 0x57, 0x4E, 0x6C, 0x63, 0x6E, 0x51, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4D, 0x53, 0x41, 0x77, 0x48, 0x67, 0x59, 0x44, 0x0A, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x64, 0x45, 0x61, ++ 0x57, 0x64, 0x70, 0x51, 0x32, 0x56, 0x79, 0x64, 0x43, 0x42, 0x48, 0x62, 0x47, 0x39, 0x69, 0x59, 0x57, 0x77, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x48, 0x4D, 0x7A, 0x41, 0x65, 0x46, 0x77, 0x30, 0x78, 0x4D, 0x7A, 0x41, 0x34, 0x4D, ++ 0x44, 0x45, 0x78, 0x4D, 0x6A, 0x41, 0x77, 0x4D, 0x44, 0x42, 0x61, 0x46, 0x77, 0x30, 0x7A, 0x4F, 0x44, 0x41, 0x78, 0x4D, 0x54, 0x55, 0x78, 0x4D, 0x6A, 0x41, 0x77, 0x0A, 0x4D, 0x44, 0x42, 0x61, 0x4D, 0x47, 0x45, 0x78, 0x43, 0x7A, 0x41, 0x4A, ++ 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6C, 0x56, 0x54, 0x4D, 0x52, 0x55, 0x77, 0x45, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x77, 0x78, 0x45, 0x61, 0x57, 0x64, 0x70, 0x51, 0x32, 0x56, 0x79, 0x64, 0x43, 0x42, 0x4A, ++ 0x62, 0x6D, 0x4D, 0x78, 0x47, 0x54, 0x41, 0x58, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x73, 0x54, 0x45, 0x48, 0x64, 0x33, 0x64, 0x79, 0x35, 0x6B, 0x0A, 0x61, 0x57, 0x64, 0x70, 0x59, 0x32, 0x56, 0x79, 0x64, 0x43, 0x35, 0x6A, 0x62, 0x32, 0x30, ++ 0x78, 0x49, 0x44, 0x41, 0x65, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x46, 0x30, 0x52, 0x70, 0x5A, 0x32, 0x6C, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x49, 0x45, 0x64, 0x73, 0x62, 0x32, 0x4A, 0x68, 0x62, 0x43, 0x42, 0x53, 0x62, 0x32, 0x39, ++ 0x30, 0x49, 0x45, 0x63, 0x7A, 0x4D, 0x48, 0x59, 0x77, 0x45, 0x41, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x0A, 0x41, 0x51, 0x59, 0x46, 0x4B, 0x34, 0x45, 0x45, 0x41, 0x43, 0x49, 0x44, 0x59, 0x67, 0x41, 0x45, 0x33, 0x61, ++ 0x66, 0x5A, 0x75, 0x34, 0x71, 0x34, 0x43, 0x2F, 0x73, 0x4C, 0x66, 0x79, 0x48, 0x53, 0x38, 0x4C, 0x36, 0x2B, 0x63, 0x2F, 0x4D, 0x7A, 0x58, 0x52, 0x71, 0x38, 0x4E, 0x4F, 0x72, 0x65, 0x78, 0x70, 0x75, 0x38, 0x30, 0x4A, 0x58, 0x32, 0x38, 0x4D, ++ 0x7A, 0x51, 0x43, 0x37, 0x70, 0x68, 0x57, 0x31, 0x46, 0x47, 0x66, 0x70, 0x34, 0x74, 0x6E, 0x2B, 0x36, 0x4F, 0x0A, 0x59, 0x77, 0x77, 0x58, 0x37, 0x41, 0x64, 0x77, 0x39, 0x63, 0x2B, 0x45, 0x4C, 0x6B, 0x43, 0x44, 0x6E, 0x4F, 0x67, 0x2F, 0x51, ++ 0x57, 0x30, 0x37, 0x72, 0x64, 0x4F, 0x6B, 0x46, 0x46, 0x6B, 0x32, 0x65, 0x4A, 0x30, 0x44, 0x51, 0x2B, 0x34, 0x51, 0x45, 0x32, 0x78, 0x79, 0x33, 0x71, 0x36, 0x49, 0x70, 0x36, 0x46, 0x72, 0x74, 0x55, 0x50, 0x4F, 0x5A, 0x39, 0x77, 0x6A, 0x2F, ++ 0x77, 0x4D, 0x63, 0x6F, 0x2B, 0x49, 0x2B, 0x6F, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, 0x50, 0x0A, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x41, 0x34, 0x47, ++ 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x68, 0x6A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x73, 0x39, 0x74, 0x49, 0x70, 0x50, 0x6D, 0x68, ++ 0x78, 0x64, 0x69, 0x75, 0x4E, 0x6B, 0x48, 0x4D, 0x45, 0x57, 0x4E, 0x70, 0x0A, 0x59, 0x69, 0x6D, 0x38, 0x53, 0x38, 0x59, 0x77, 0x43, 0x67, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x45, 0x41, 0x77, 0x4D, 0x44, 0x61, 0x41, 0x41, ++ 0x77, 0x5A, 0x51, 0x49, 0x78, 0x41, 0x4B, 0x32, 0x38, 0x38, 0x6D, 0x77, 0x2F, 0x45, 0x6B, 0x72, 0x52, 0x4C, 0x54, 0x6E, 0x44, 0x43, 0x67, 0x6D, 0x58, 0x63, 0x2F, 0x53, 0x49, 0x4E, 0x6F, 0x79, 0x49, 0x4A, 0x37, 0x76, 0x6D, 0x69, 0x49, 0x31, ++ 0x51, 0x68, 0x61, 0x64, 0x6A, 0x2B, 0x5A, 0x34, 0x79, 0x0A, 0x33, 0x6D, 0x61, 0x54, 0x44, 0x2F, 0x48, 0x4D, 0x73, 0x51, 0x6D, 0x50, 0x33, 0x57, 0x79, 0x72, 0x2B, 0x6D, 0x74, 0x2F, 0x6F, 0x41, 0x49, 0x77, 0x4F, 0x57, 0x5A, 0x62, 0x77, 0x6D, ++ 0x53, 0x4E, 0x75, 0x4A, 0x35, 0x51, 0x33, 0x4B, 0x6A, 0x56, 0x53, 0x61, 0x4C, 0x74, 0x78, 0x39, 0x7A, 0x52, 0x53, 0x58, 0x38, 0x58, 0x41, 0x62, 0x6A, 0x49, 0x68, 0x6F, 0x39, 0x4F, 0x6A, 0x49, 0x67, 0x72, 0x71, 0x4A, 0x71, 0x70, 0x69, 0x73, ++ 0x58, 0x52, 0x41, 0x4C, 0x33, 0x34, 0x0A, 0x56, 0x4F, 0x4B, 0x61, 0x35, 0x56, 0x74, 0x38, 0x73, 0x79, 0x63, 0x58, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, ++ 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x34, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, ++ 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x6B, 0x44, 0x43, 0x43, 0x41, 0x33, 0x69, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x42, 0x5A, 0x73, 0x62, 0x56, 0x35, 0x36, 0x4F, 0x49, 0x54, 0x4C, 0x69, 0x4F, 0x51, 0x65, ++ 0x39, 0x70, 0x33, 0x64, 0x31, 0x58, 0x44, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x77, 0x46, 0x41, 0x44, 0x42, 0x69, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, ++ 0x47, 0x0A, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x56, 0x4D, 0x42, 0x4D, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x4D, 0x52, 0x47, 0x6C, 0x6E, 0x61, 0x55, 0x4E, 0x6C, 0x63, 0x6E, 0x51, 0x67, 0x53, 0x57, 0x35, 0x6A, 0x4D, 0x52, ++ 0x6B, 0x77, 0x46, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, 0x45, 0x78, 0x42, 0x33, 0x64, 0x33, 0x63, 0x75, 0x5A, 0x47, 0x6C, 0x6E, 0x61, 0x57, 0x4E, 0x6C, 0x63, 0x6E, 0x51, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4D, 0x53, 0x45, 0x77, 0x0A, 0x48, ++ 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x68, 0x45, 0x61, 0x57, 0x64, 0x70, 0x51, 0x32, 0x56, 0x79, 0x64, 0x43, 0x42, 0x55, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x47, 0x56, 0x6B, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x52, ++ 0x7A, 0x51, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x54, 0x4D, 0x77, 0x4F, 0x44, 0x41, 0x78, 0x4D, 0x54, 0x49, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x57, 0x68, 0x63, 0x4E, 0x4D, 0x7A, 0x67, 0x77, 0x4D, 0x54, 0x45, 0x31, 0x0A, 0x4D, 0x54, 0x49, 0x77, ++ 0x4D, 0x44, 0x41, 0x77, 0x57, 0x6A, 0x42, 0x69, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x56, 0x4D, 0x42, 0x4D, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x4D, ++ 0x52, 0x47, 0x6C, 0x6E, 0x61, 0x55, 0x4E, 0x6C, 0x63, 0x6E, 0x51, 0x67, 0x53, 0x57, 0x35, 0x6A, 0x4D, 0x52, 0x6B, 0x77, 0x46, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, 0x45, 0x78, 0x42, 0x33, 0x0A, 0x64, 0x33, 0x63, 0x75, 0x5A, 0x47, 0x6C, ++ 0x6E, 0x61, 0x57, 0x4E, 0x6C, 0x63, 0x6E, 0x51, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4D, 0x53, 0x45, 0x77, 0x48, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x68, 0x45, 0x61, 0x57, 0x64, 0x70, 0x51, 0x32, 0x56, 0x79, 0x64, 0x43, 0x42, ++ 0x55, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x47, 0x56, 0x6B, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x52, 0x7A, 0x51, 0x77, 0x67, 0x67, 0x49, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x0A, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, ++ 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x43, 0x2F, 0x35, 0x70, 0x42, 0x7A, 0x61, 0x4E, 0x36, 0x37, 0x35, 0x46, 0x31, 0x4B, 0x50, 0x44, ++ 0x41, 0x69, 0x4D, 0x47, 0x6B, 0x7A, 0x37, 0x4D, 0x4B, 0x6E, 0x4A, 0x53, 0x37, 0x4A, 0x49, 0x54, 0x33, 0x79, 0x69, 0x74, 0x68, 0x5A, 0x77, 0x75, 0x45, 0x70, 0x0A, 0x70, 0x7A, 0x31, 0x59, 0x71, 0x33, 0x61, 0x61, 0x7A, 0x61, 0x35, 0x37, 0x47, ++ 0x34, 0x51, 0x4E, 0x78, 0x44, 0x41, 0x66, 0x38, 0x78, 0x75, 0x6B, 0x4F, 0x42, 0x62, 0x72, 0x56, 0x73, 0x61, 0x58, 0x62, 0x52, 0x32, 0x72, 0x73, 0x6E, 0x6E, 0x79, 0x79, 0x68, 0x48, 0x53, 0x35, 0x46, 0x2F, 0x57, 0x42, 0x54, 0x78, 0x53, 0x44, ++ 0x31, 0x49, 0x66, 0x78, 0x70, 0x34, 0x56, 0x70, 0x58, 0x36, 0x2B, 0x6E, 0x36, 0x6C, 0x58, 0x46, 0x6C, 0x6C, 0x56, 0x63, 0x71, 0x39, 0x6F, 0x0A, 0x6B, 0x33, 0x44, 0x43, 0x73, 0x72, 0x70, 0x31, 0x6D, 0x57, 0x70, 0x7A, 0x4D, 0x70, 0x54, 0x52, ++ 0x45, 0x45, 0x51, 0x51, 0x4C, 0x74, 0x2B, 0x43, 0x38, 0x77, 0x65, 0x45, 0x35, 0x6E, 0x51, 0x37, 0x62, 0x58, 0x48, 0x69, 0x4C, 0x51, 0x77, 0x62, 0x37, 0x69, 0x44, 0x56, 0x79, 0x53, 0x41, 0x64, 0x59, 0x79, 0x6B, 0x74, 0x7A, 0x75, 0x78, 0x65, ++ 0x54, 0x73, 0x69, 0x54, 0x2B, 0x43, 0x46, 0x68, 0x6D, 0x7A, 0x54, 0x72, 0x42, 0x63, 0x5A, 0x65, 0x37, 0x46, 0x73, 0x61, 0x0A, 0x76, 0x4F, 0x76, 0x4A, 0x7A, 0x38, 0x32, 0x73, 0x4E, 0x45, 0x42, 0x66, 0x73, 0x58, 0x70, 0x6D, 0x37, 0x6E, 0x66, ++ 0x49, 0x53, 0x4B, 0x68, 0x6D, 0x56, 0x31, 0x65, 0x66, 0x56, 0x46, 0x69, 0x4F, 0x44, 0x43, 0x75, 0x33, 0x54, 0x36, 0x63, 0x77, 0x32, 0x56, 0x62, 0x75, 0x79, 0x6E, 0x74, 0x64, 0x34, 0x36, 0x33, 0x4A, 0x54, 0x31, 0x37, 0x6C, 0x4E, 0x65, 0x63, ++ 0x78, 0x79, 0x39, 0x71, 0x54, 0x58, 0x74, 0x79, 0x4F, 0x6A, 0x34, 0x44, 0x61, 0x74, 0x70, 0x47, 0x59, 0x0A, 0x51, 0x4A, 0x42, 0x35, 0x77, 0x33, 0x6A, 0x48, 0x74, 0x72, 0x48, 0x45, 0x74, 0x57, 0x6F, 0x59, 0x4F, 0x41, 0x4D, 0x51, 0x6A, 0x64, ++ 0x6A, 0x55, 0x4E, 0x36, 0x51, 0x75, 0x42, 0x58, 0x32, 0x49, 0x39, 0x59, 0x49, 0x2B, 0x45, 0x4A, 0x46, 0x77, 0x71, 0x31, 0x57, 0x43, 0x51, 0x54, 0x4C, 0x58, 0x32, 0x77, 0x52, 0x7A, 0x4B, 0x6D, 0x36, 0x52, 0x41, 0x58, 0x77, 0x68, 0x54, 0x4E, ++ 0x53, 0x38, 0x72, 0x68, 0x73, 0x44, 0x64, 0x56, 0x31, 0x34, 0x5A, 0x74, 0x6B, 0x36, 0x0A, 0x4D, 0x55, 0x53, 0x61, 0x4D, 0x30, 0x43, 0x2F, 0x43, 0x4E, 0x64, 0x61, 0x53, 0x61, 0x54, 0x43, 0x35, 0x71, 0x6D, 0x67, 0x5A, 0x39, 0x32, 0x6B, 0x4A, ++ 0x37, 0x79, 0x68, 0x54, 0x7A, 0x6D, 0x31, 0x45, 0x56, 0x67, 0x58, 0x39, 0x79, 0x52, 0x63, 0x52, 0x6F, 0x39, 0x6B, 0x39, 0x38, 0x46, 0x70, 0x69, 0x48, 0x61, 0x59, 0x64, 0x6A, 0x31, 0x5A, 0x58, 0x55, 0x4A, 0x32, 0x68, 0x34, 0x6D, 0x58, 0x61, ++ 0x58, 0x70, 0x49, 0x38, 0x4F, 0x43, 0x69, 0x45, 0x68, 0x74, 0x6D, 0x0A, 0x6D, 0x6E, 0x54, 0x4B, 0x33, 0x6B, 0x73, 0x65, 0x35, 0x77, 0x35, 0x6A, 0x72, 0x75, 0x62, 0x55, 0x37, 0x35, 0x4B, 0x53, 0x4F, 0x70, 0x34, 0x39, 0x33, 0x41, 0x44, 0x6B, ++ 0x52, 0x53, 0x57, 0x4A, 0x74, 0x70, 0x70, 0x45, 0x47, 0x53, 0x74, 0x2B, 0x77, 0x4A, 0x53, 0x30, 0x30, 0x6D, 0x46, 0x74, 0x36, 0x7A, 0x50, 0x5A, 0x78, 0x64, 0x39, 0x4C, 0x42, 0x41, 0x44, 0x4D, 0x66, 0x52, 0x79, 0x56, 0x77, 0x34, 0x2F, 0x33, ++ 0x49, 0x62, 0x4B, 0x79, 0x45, 0x62, 0x65, 0x37, 0x0A, 0x66, 0x2F, 0x4C, 0x56, 0x6A, 0x48, 0x41, 0x73, 0x51, 0x57, 0x43, 0x71, 0x73, 0x57, 0x4D, 0x59, 0x52, 0x4A, 0x55, 0x61, 0x64, 0x6D, 0x4A, 0x2B, 0x39, 0x6F, 0x43, 0x77, 0x2B, 0x2B, 0x68, ++ 0x6B, 0x70, 0x6A, 0x50, 0x52, 0x69, 0x51, 0x66, 0x68, 0x76, 0x62, 0x66, 0x6D, 0x51, 0x36, 0x51, 0x59, 0x75, 0x4B, 0x5A, 0x33, 0x41, 0x65, 0x45, 0x50, 0x6C, 0x41, 0x77, 0x68, 0x48, 0x62, 0x4A, 0x55, 0x4B, 0x53, 0x57, 0x4A, 0x62, 0x4F, 0x55, ++ 0x4F, 0x55, 0x6C, 0x46, 0x48, 0x0A, 0x64, 0x4C, 0x34, 0x6D, 0x72, 0x4C, 0x5A, 0x42, 0x64, 0x64, 0x35, 0x36, 0x72, 0x46, 0x2B, 0x4E, 0x50, 0x38, 0x6D, 0x38, 0x30, 0x30, 0x45, 0x52, 0x45, 0x6C, 0x76, 0x6C, 0x45, 0x46, 0x44, 0x72, 0x4D, 0x63, ++ 0x58, 0x4B, 0x63, 0x68, 0x59, 0x69, 0x43, 0x64, 0x39, 0x38, 0x54, 0x48, 0x55, 0x2F, 0x59, 0x2B, 0x77, 0x68, 0x58, 0x38, 0x51, 0x67, 0x55, 0x57, 0x74, 0x76, 0x73, 0x61, 0x75, 0x47, 0x69, 0x30, 0x2F, 0x43, 0x31, 0x6B, 0x56, 0x66, 0x6E, 0x53, ++ 0x44, 0x38, 0x0A, 0x6F, 0x52, 0x37, 0x46, 0x77, 0x49, 0x2B, 0x69, 0x73, 0x58, 0x34, 0x4B, 0x4A, 0x70, 0x6E, 0x31, 0x35, 0x47, 0x6B, 0x76, 0x6D, 0x42, 0x30, 0x74, 0x39, 0x64, 0x6D, 0x70, 0x73, 0x68, 0x33, 0x6C, 0x47, 0x77, 0x49, 0x44, 0x41, ++ 0x51, 0x41, 0x42, 0x6F, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x0A, ++ 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x68, 0x6A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x37, 0x4E, 0x66, 0x6A, 0x67, 0x74, 0x4A, 0x78, 0x58, 0x57, 0x52, 0x4D, ++ 0x33, 0x79, 0x35, 0x6E, 0x50, 0x2B, 0x65, 0x36, 0x6D, 0x4B, 0x34, 0x63, 0x44, 0x30, 0x38, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4D, 0x42, 0x51, 0x41, 0x44, 0x0A, 0x67, 0x67, 0x49, ++ 0x42, 0x41, 0x4C, 0x74, 0x68, 0x32, 0x58, 0x32, 0x70, 0x62, 0x4C, 0x34, 0x58, 0x78, 0x4A, 0x45, 0x62, 0x77, 0x36, 0x47, 0x69, 0x41, 0x49, 0x33, 0x6A, 0x5A, 0x47, 0x67, 0x50, 0x56, 0x73, 0x39, 0x33, 0x72, 0x6E, 0x44, 0x35, 0x2F, 0x5A, 0x70, ++ 0x4B, 0x6D, 0x62, 0x6E, 0x4A, 0x65, 0x46, 0x77, 0x4D, 0x44, 0x46, 0x2F, 0x6B, 0x35, 0x68, 0x51, 0x70, 0x56, 0x67, 0x73, 0x32, 0x53, 0x56, 0x31, 0x45, 0x59, 0x2B, 0x43, 0x74, 0x6E, 0x4A, 0x59, 0x59, 0x0A, 0x5A, 0x68, 0x73, 0x6A, 0x44, 0x54, ++ 0x31, 0x35, 0x36, 0x57, 0x31, 0x72, 0x31, 0x6C, 0x54, 0x34, 0x30, 0x6A, 0x7A, 0x42, 0x51, 0x30, 0x43, 0x75, 0x48, 0x56, 0x44, 0x31, 0x55, 0x76, 0x79, 0x51, 0x4F, 0x37, 0x75, 0x59, 0x6D, 0x57, 0x6C, 0x72, 0x78, 0x38, 0x47, 0x6E, 0x71, 0x47, ++ 0x69, 0x6B, 0x4A, 0x39, 0x79, 0x64, 0x2B, 0x53, 0x65, 0x75, 0x4D, 0x49, 0x57, 0x35, 0x39, 0x6D, 0x64, 0x4E, 0x4F, 0x6A, 0x36, 0x50, 0x57, 0x54, 0x6B, 0x69, 0x55, 0x30, 0x54, 0x72, 0x0A, 0x79, 0x46, 0x30, 0x44, 0x79, 0x75, 0x31, 0x51, 0x65, ++ 0x6E, 0x31, 0x69, 0x49, 0x51, 0x71, 0x41, 0x79, 0x48, 0x4E, 0x6D, 0x30, 0x61, 0x41, 0x46, 0x59, 0x46, 0x2F, 0x6F, 0x70, 0x62, 0x53, 0x6E, 0x72, 0x36, 0x6A, 0x33, 0x62, 0x54, 0x57, 0x63, 0x66, 0x46, 0x71, 0x4B, 0x31, 0x71, 0x49, 0x34, 0x6D, ++ 0x66, 0x4E, 0x34, 0x69, 0x2F, 0x52, 0x4E, 0x30, 0x69, 0x41, 0x4C, 0x33, 0x67, 0x54, 0x75, 0x6A, 0x4A, 0x74, 0x48, 0x67, 0x58, 0x49, 0x4E, 0x77, 0x42, 0x51, 0x79, 0x0A, 0x37, 0x7A, 0x42, 0x5A, 0x4C, 0x71, 0x37, 0x67, 0x63, 0x66, 0x4A, 0x57, ++ 0x35, 0x47, 0x71, 0x58, 0x62, 0x35, 0x4A, 0x51, 0x62, 0x5A, 0x61, 0x4E, 0x61, 0x48, 0x71, 0x61, 0x73, 0x6A, 0x59, 0x55, 0x65, 0x67, 0x62, 0x79, 0x4A, 0x4C, 0x6B, 0x4A, 0x45, 0x56, 0x44, 0x58, 0x43, 0x4C, 0x47, 0x34, 0x69, 0x58, 0x71, 0x45, ++ 0x49, 0x32, 0x46, 0x43, 0x4B, 0x65, 0x57, 0x6A, 0x7A, 0x61, 0x49, 0x67, 0x51, 0x64, 0x66, 0x52, 0x6E, 0x47, 0x54, 0x5A, 0x36, 0x69, 0x61, 0x68, 0x0A, 0x69, 0x78, 0x54, 0x58, 0x54, 0x42, 0x6D, 0x79, 0x55, 0x45, 0x46, 0x78, 0x50, 0x54, 0x39, ++ 0x4E, 0x63, 0x43, 0x4F, 0x47, 0x44, 0x45, 0x72, 0x63, 0x67, 0x64, 0x4C, 0x4D, 0x4D, 0x70, 0x53, 0x45, 0x44, 0x51, 0x67, 0x4A, 0x6C, 0x78, 0x78, 0x50, 0x77, 0x4F, 0x35, 0x72, 0x49, 0x48, 0x51, 0x77, 0x30, 0x75, 0x41, 0x35, 0x4E, 0x42, 0x43, ++ 0x46, 0x49, 0x52, 0x55, 0x42, 0x43, 0x4F, 0x68, 0x56, 0x4D, 0x74, 0x35, 0x78, 0x53, 0x64, 0x6B, 0x6F, 0x46, 0x31, 0x42, 0x4E, 0x0A, 0x35, 0x72, 0x35, 0x4E, 0x30, 0x58, 0x57, 0x73, 0x30, 0x4D, 0x72, 0x37, 0x51, 0x62, 0x68, 0x44, 0x70, 0x61, ++ 0x72, 0x54, 0x77, 0x77, 0x56, 0x45, 0x54, 0x79, 0x77, 0x32, 0x6D, 0x2B, 0x4C, 0x36, 0x34, 0x6B, 0x57, 0x34, 0x49, 0x31, 0x4E, 0x73, 0x42, 0x6D, 0x39, 0x6E, 0x56, 0x58, 0x39, 0x47, 0x74, 0x55, 0x77, 0x2F, 0x62, 0x69, 0x68, 0x61, 0x65, 0x53, ++ 0x62, 0x53, 0x70, 0x4B, 0x68, 0x69, 0x6C, 0x39, 0x49, 0x65, 0x34, 0x75, 0x31, 0x4B, 0x69, 0x37, 0x77, 0x62, 0x0A, 0x2F, 0x55, 0x64, 0x4B, 0x44, 0x64, 0x39, 0x6E, 0x5A, 0x6E, 0x36, 0x79, 0x57, 0x30, 0x48, 0x51, 0x4F, 0x2B, 0x54, 0x30, 0x4F, ++ 0x2F, 0x51, 0x45, 0x59, 0x2B, 0x6E, 0x76, 0x77, 0x6C, 0x51, 0x41, 0x55, 0x61, 0x43, 0x4B, 0x4B, 0x73, 0x6E, 0x4F, 0x65, 0x4D, 0x7A, 0x56, 0x36, 0x6F, 0x63, 0x45, 0x47, 0x4C, 0x50, 0x4F, 0x72, 0x30, 0x6D, 0x49, 0x72, 0x2F, 0x4F, 0x53, 0x6D, ++ 0x62, 0x61, 0x7A, 0x35, 0x6D, 0x45, 0x50, 0x30, 0x6F, 0x55, 0x41, 0x35, 0x31, 0x41, 0x61, 0x0A, 0x35, 0x42, 0x75, 0x56, 0x6E, 0x52, 0x6D, 0x68, 0x75, 0x5A, 0x79, 0x78, 0x6D, 0x37, 0x45, 0x41, 0x48, 0x75, 0x2F, 0x51, 0x44, 0x30, 0x39, 0x43, ++ 0x62, 0x4D, 0x6B, 0x4B, 0x76, 0x4F, 0x35, 0x44, 0x2B, 0x6A, 0x70, 0x78, 0x70, 0x63, 0x68, 0x4E, 0x4A, 0x71, 0x55, 0x31, 0x2F, 0x59, 0x6C, 0x64, 0x76, 0x49, 0x56, 0x69, 0x48, 0x54, 0x4C, 0x53, 0x6F, 0x43, 0x74, 0x55, 0x37, 0x5A, 0x70, 0x58, ++ 0x77, 0x64, 0x76, 0x36, 0x45, 0x4D, 0x38, 0x5A, 0x74, 0x34, 0x74, 0x4B, 0x0A, 0x47, 0x34, 0x38, 0x42, 0x74, 0x69, 0x65, 0x56, 0x55, 0x2B, 0x69, 0x32, 0x69, 0x57, 0x31, 0x62, 0x76, 0x47, 0x6A, 0x55, 0x49, 0x2B, 0x69, 0x4C, 0x55, 0x61, 0x4A, ++ 0x57, 0x2B, 0x66, 0x43, 0x6D, 0x67, 0x4B, 0x44, 0x57, 0x48, 0x72, 0x4F, 0x38, 0x44, 0x77, 0x39, 0x54, 0x64, 0x53, 0x6D, 0x71, 0x36, 0x68, 0x4E, 0x33, 0x35, 0x4E, 0x36, 0x4D, 0x67, 0x53, 0x47, 0x74, 0x42, 0x78, 0x42, 0x48, 0x45, 0x61, 0x32, ++ 0x48, 0x50, 0x51, 0x66, 0x52, 0x64, 0x62, 0x7A, 0x50, 0x0A, 0x38, 0x32, 0x5A, 0x2B, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x0A, 0x0A, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x0A, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, ++ 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x32, 0x44, 0x43, 0x43, 0x41, 0x38, 0x43, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, ++ 0x54, 0x4B, 0x72, 0x35, 0x79, 0x74, 0x74, 0x6A, 0x62, 0x2B, 0x41, 0x66, 0x39, 0x30, 0x37, 0x59, 0x57, 0x77, 0x4F, 0x47, 0x6E, 0x54, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x77, 0x46, ++ 0x41, 0x44, 0x43, 0x42, 0x68, 0x54, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0A, 0x42, 0x68, 0x4D, 0x43, 0x52, 0x30, 0x49, 0x78, 0x47, 0x7A, 0x41, 0x5A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x67, 0x54, 0x45, 0x6B, 0x64, ++ 0x79, 0x5A, 0x57, 0x46, 0x30, 0x5A, 0x58, 0x49, 0x67, 0x54, 0x57, 0x46, 0x75, 0x59, 0x32, 0x68, 0x6C, 0x63, 0x33, 0x52, 0x6C, 0x63, 0x6A, 0x45, 0x51, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x78, 0x4D, 0x48, 0x55, 0x32, 0x46, ++ 0x73, 0x5A, 0x6D, 0x39, 0x79, 0x5A, 0x44, 0x45, 0x61, 0x4D, 0x42, 0x67, 0x47, 0x0A, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x52, 0x51, 0x30, 0x39, 0x4E, 0x54, 0x30, 0x52, 0x50, 0x49, 0x45, 0x4E, 0x42, 0x49, 0x45, 0x78, 0x70, 0x62, 0x57, ++ 0x6C, 0x30, 0x5A, 0x57, 0x51, 0x78, 0x4B, 0x7A, 0x41, 0x70, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x49, 0x6B, 0x4E, 0x50, 0x54, 0x55, 0x39, 0x45, 0x54, 0x79, 0x42, 0x53, 0x55, 0x30, 0x45, 0x67, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, ++ 0x6C, 0x6D, 0x61, 0x57, 0x4E, 0x68, 0x64, 0x47, 0x6C, 0x76, 0x0A, 0x62, 0x69, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6F, 0x62, 0x33, 0x4A, 0x70, 0x64, 0x48, 0x6B, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x54, 0x41, 0x77, 0x4D, 0x54, 0x45, 0x35, 0x4D, ++ 0x44, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x57, 0x68, 0x63, 0x4E, 0x4D, 0x7A, 0x67, 0x77, 0x4D, 0x54, 0x45, 0x34, 0x4D, 0x6A, 0x4D, 0x31, 0x4F, 0x54, 0x55, 0x35, 0x57, 0x6A, 0x43, 0x42, 0x68, 0x54, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, ++ 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x0A, 0x52, 0x30, 0x49, 0x78, 0x47, 0x7A, 0x41, 0x5A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x67, 0x54, 0x45, 0x6B, 0x64, 0x79, 0x5A, 0x57, 0x46, 0x30, 0x5A, 0x58, 0x49, 0x67, 0x54, 0x57, 0x46, 0x75, ++ 0x59, 0x32, 0x68, 0x6C, 0x63, 0x33, 0x52, 0x6C, 0x63, 0x6A, 0x45, 0x51, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x78, 0x4D, 0x48, 0x55, 0x32, 0x46, 0x73, 0x5A, 0x6D, 0x39, 0x79, 0x5A, 0x44, 0x45, 0x61, 0x4D, 0x42, 0x67, 0x47, ++ 0x41, 0x31, 0x55, 0x45, 0x0A, 0x43, 0x68, 0x4D, 0x52, 0x51, 0x30, 0x39, 0x4E, 0x54, 0x30, 0x52, 0x50, 0x49, 0x45, 0x4E, 0x42, 0x49, 0x45, 0x78, 0x70, 0x62, 0x57, 0x6C, 0x30, 0x5A, 0x57, 0x51, 0x78, 0x4B, 0x7A, 0x41, 0x70, 0x42, 0x67, 0x4E, ++ 0x56, 0x42, 0x41, 0x4D, 0x54, 0x49, 0x6B, 0x4E, 0x50, 0x54, 0x55, 0x39, 0x45, 0x54, 0x79, 0x42, 0x53, 0x55, 0x30, 0x45, 0x67, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6C, 0x6D, 0x61, 0x57, 0x4E, 0x68, 0x64, 0x47, 0x6C, 0x76, 0x62, 0x69, 0x42, ++ 0x42, 0x0A, 0x64, 0x58, 0x52, 0x6F, 0x62, 0x33, 0x4A, 0x70, 0x64, 0x48, 0x6B, 0x77, 0x67, 0x67, 0x49, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, ++ 0x49, 0x43, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x43, 0x52, 0x36, 0x46, 0x53, 0x53, 0x30, 0x67, 0x70, 0x57, 0x73, 0x61, 0x77, 0x4E, 0x4A, 0x4E, 0x33, 0x46, 0x7A, 0x30, 0x52, 0x6E, 0x0A, 0x64, ++ 0x4A, 0x6B, 0x72, 0x4E, 0x36, 0x4E, 0x39, 0x49, 0x33, 0x41, 0x41, 0x63, 0x62, 0x78, 0x54, 0x33, 0x38, 0x54, 0x36, 0x4B, 0x68, 0x4B, 0x50, 0x53, 0x33, 0x38, 0x51, 0x56, 0x72, 0x32, 0x66, 0x63, 0x48, 0x4B, 0x33, 0x59, 0x58, 0x2F, 0x4A, 0x53, ++ 0x77, 0x38, 0x58, 0x70, 0x7A, 0x33, 0x6A, 0x73, 0x41, 0x52, 0x68, 0x37, 0x76, 0x38, 0x52, 0x6C, 0x38, 0x66, 0x30, 0x68, 0x6A, 0x34, 0x4B, 0x2B, 0x6A, 0x35, 0x63, 0x2B, 0x5A, 0x50, 0x6D, 0x4E, 0x48, 0x72, 0x5A, 0x0A, 0x46, 0x47, 0x76, 0x6E, ++ 0x6E, 0x4C, 0x4F, 0x46, 0x6F, 0x49, 0x4A, 0x36, 0x64, 0x71, 0x39, 0x78, 0x6B, 0x4E, 0x66, 0x73, 0x2F, 0x51, 0x33, 0x36, 0x6E, 0x47, 0x7A, 0x36, 0x33, 0x37, 0x43, 0x43, 0x39, 0x42, 0x52, 0x2B, 0x2B, 0x62, 0x37, 0x45, 0x70, 0x69, 0x39, 0x50, ++ 0x66, 0x35, 0x6C, 0x2F, 0x74, 0x66, 0x78, 0x6E, 0x51, 0x33, 0x4B, 0x39, 0x44, 0x41, 0x44, 0x57, 0x69, 0x65, 0x74, 0x72, 0x4C, 0x4E, 0x50, 0x74, 0x6A, 0x35, 0x67, 0x63, 0x46, 0x4B, 0x74, 0x2B, 0x0A, 0x35, 0x65, 0x4E, 0x75, 0x2F, 0x4E, 0x69, ++ 0x6F, 0x35, 0x4A, 0x49, 0x6B, 0x32, 0x6B, 0x4E, 0x72, 0x59, 0x72, 0x68, 0x56, 0x2F, 0x65, 0x72, 0x42, 0x76, 0x47, 0x79, 0x32, 0x69, 0x2F, 0x4D, 0x4F, 0x6A, 0x5A, 0x72, 0x6B, 0x6D, 0x32, 0x78, 0x70, 0x6D, 0x66, 0x68, 0x34, 0x53, 0x44, 0x42, ++ 0x46, 0x31, 0x61, 0x33, 0x68, 0x44, 0x54, 0x78, 0x46, 0x59, 0x50, 0x77, 0x79, 0x6C, 0x6C, 0x45, 0x6E, 0x76, 0x47, 0x66, 0x44, 0x79, 0x69, 0x36, 0x32, 0x61, 0x2B, 0x70, 0x47, 0x0A, 0x78, 0x38, 0x63, 0x67, 0x6F, 0x4C, 0x45, 0x66, 0x5A, 0x64, ++ 0x35, 0x49, 0x43, 0x4C, 0x71, 0x6B, 0x54, 0x71, 0x6E, 0x79, 0x67, 0x30, 0x59, 0x33, 0x68, 0x4F, 0x76, 0x6F, 0x7A, 0x49, 0x46, 0x49, 0x51, 0x32, 0x64, 0x4F, 0x63, 0x69, 0x71, 0x62, 0x58, 0x4C, 0x31, 0x4D, 0x47, 0x79, 0x69, 0x4B, 0x58, 0x43, ++ 0x4A, 0x37, 0x74, 0x4B, 0x75, 0x59, 0x32, 0x65, 0x37, 0x67, 0x55, 0x59, 0x50, 0x44, 0x43, 0x55, 0x5A, 0x4F, 0x62, 0x54, 0x36, 0x5A, 0x2B, 0x70, 0x55, 0x58, 0x0A, 0x32, 0x6E, 0x77, 0x7A, 0x56, 0x30, 0x45, 0x38, 0x6A, 0x56, 0x48, 0x74, 0x43, ++ 0x37, 0x5A, 0x63, 0x72, 0x79, 0x78, 0x6A, 0x47, 0x74, 0x39, 0x58, 0x79, 0x44, 0x2B, 0x38, 0x36, 0x56, 0x33, 0x45, 0x6D, 0x36, 0x39, 0x46, 0x6D, 0x65, 0x4B, 0x6A, 0x57, 0x69, 0x53, 0x30, 0x75, 0x71, 0x6C, 0x57, 0x50, 0x63, 0x39, 0x76, 0x71, ++ 0x76, 0x39, 0x4A, 0x57, 0x4C, 0x37, 0x77, 0x71, 0x50, 0x2F, 0x30, 0x75, 0x4B, 0x33, 0x70, 0x4E, 0x2F, 0x75, 0x36, 0x75, 0x50, 0x51, 0x4C, 0x0A, 0x4F, 0x76, 0x6E, 0x6F, 0x51, 0x30, 0x49, 0x65, 0x69, 0x64, 0x69, 0x45, 0x79, 0x78, 0x50, 0x78, ++ 0x32, 0x62, 0x76, 0x68, 0x69, 0x57, 0x43, 0x34, 0x6A, 0x43, 0x68, 0x57, 0x72, 0x42, 0x51, 0x64, 0x6E, 0x41, 0x72, 0x6E, 0x63, 0x65, 0x76, 0x50, 0x44, 0x74, 0x30, 0x39, 0x71, 0x5A, 0x61, 0x68, 0x53, 0x4C, 0x30, 0x38, 0x39, 0x36, 0x2B, 0x31, ++ 0x44, 0x53, 0x4A, 0x4D, 0x77, 0x42, 0x47, 0x42, 0x37, 0x46, 0x59, 0x37, 0x39, 0x74, 0x4F, 0x69, 0x34, 0x6C, 0x75, 0x33, 0x0A, 0x73, 0x67, 0x51, 0x69, 0x55, 0x70, 0x57, 0x41, 0x6B, 0x32, 0x6E, 0x6F, 0x6A, 0x6B, 0x78, 0x6C, 0x38, 0x5A, 0x45, ++ 0x44, 0x4C, 0x58, 0x42, 0x30, 0x41, 0x75, 0x71, 0x4C, 0x5A, 0x78, 0x55, 0x70, 0x61, 0x56, 0x49, 0x43, 0x75, 0x39, 0x66, 0x66, 0x55, 0x47, 0x70, 0x56, 0x52, 0x72, 0x2B, 0x67, 0x6F, 0x79, 0x68, 0x68, 0x66, 0x33, 0x44, 0x51, 0x77, 0x36, 0x4B, ++ 0x71, 0x4C, 0x43, 0x47, 0x71, 0x52, 0x38, 0x34, 0x6F, 0x6E, 0x41, 0x5A, 0x46, 0x64, 0x72, 0x2B, 0x43, 0x0A, 0x47, 0x43, 0x65, 0x30, 0x31, 0x61, 0x36, 0x30, 0x79, 0x31, 0x44, 0x6D, 0x61, 0x2F, 0x52, 0x4D, 0x68, 0x6E, 0x45, 0x77, 0x36, 0x61, ++ 0x62, 0x66, 0x46, 0x6F, 0x62, 0x67, 0x32, 0x50, 0x39, 0x41, 0x33, 0x66, 0x76, 0x51, 0x51, 0x6F, 0x68, 0x2F, 0x6F, 0x7A, 0x4D, 0x36, 0x4C, 0x6C, 0x77, 0x65, 0x51, 0x52, 0x47, 0x42, 0x59, 0x38, 0x34, 0x59, 0x63, 0x57, 0x73, 0x72, 0x37, 0x4B, ++ 0x61, 0x4B, 0x74, 0x7A, 0x46, 0x63, 0x4F, 0x6D, 0x70, 0x48, 0x34, 0x4D, 0x4E, 0x35, 0x0A, 0x57, 0x64, 0x59, 0x67, 0x47, 0x71, 0x2F, 0x79, 0x61, 0x70, 0x69, 0x71, 0x63, 0x72, 0x78, 0x58, 0x53, 0x74, 0x4A, 0x4C, 0x6E, 0x62, 0x73, 0x51, 0x2F, ++ 0x4C, 0x42, 0x4D, 0x51, 0x65, 0x58, 0x74, 0x48, 0x54, 0x31, 0x65, 0x4B, 0x4A, 0x32, 0x63, 0x7A, 0x4C, 0x2B, 0x7A, 0x55, 0x64, 0x71, 0x6E, 0x52, 0x2B, 0x57, 0x45, 0x55, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6F, 0x30, 0x49, 0x77, 0x51, ++ 0x44, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x0A, 0x46, 0x67, 0x51, 0x55, 0x75, 0x36, 0x39, 0x2B, 0x41, 0x6A, 0x33, 0x36, 0x70, 0x76, 0x45, 0x38, 0x68, 0x49, 0x36, 0x74, 0x37, 0x6A, 0x69, 0x59, 0x37, 0x4E, 0x6B, 0x79, ++ 0x4D, 0x74, 0x51, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, ++ 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x0A, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4D, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x42, 0x41, 0x41, 0x72, 0x78, 0x31, 0x55, 0x61, ++ 0x45, 0x74, 0x36, 0x35, 0x52, 0x75, 0x32, 0x79, 0x79, 0x54, 0x55, 0x45, 0x55, 0x41, 0x4A, 0x4E, 0x4D, 0x6E, 0x4D, 0x76, 0x6C, 0x77, 0x46, 0x54, 0x50, 0x6F, 0x43, 0x57, 0x4F, 0x41, 0x76, 0x6E, 0x39, 0x73, 0x4B, 0x49, 0x4E, 0x39, 0x53, 0x43, ++ 0x59, 0x50, 0x42, 0x4D, 0x74, 0x0A, 0x72, 0x46, 0x61, 0x69, 0x73, 0x4E, 0x5A, 0x2B, 0x45, 0x5A, 0x4C, 0x70, 0x4C, 0x72, 0x71, 0x65, 0x4C, 0x70, 0x70, 0x79, 0x73, 0x62, 0x30, 0x5A, 0x52, 0x47, 0x78, 0x68, 0x4E, 0x61, 0x4B, 0x61, 0x74, 0x42, ++ 0x59, 0x53, 0x61, 0x56, 0x71, 0x4D, 0x34, 0x64, 0x63, 0x2B, 0x70, 0x42, 0x72, 0x6F, 0x4C, 0x77, 0x50, 0x30, 0x72, 0x6D, 0x45, 0x64, 0x45, 0x42, 0x73, 0x71, 0x70, 0x49, 0x74, 0x36, 0x78, 0x66, 0x34, 0x46, 0x70, 0x75, 0x48, 0x41, 0x31, 0x73, ++ 0x6A, 0x2B, 0x0A, 0x6E, 0x71, 0x36, 0x50, 0x4B, 0x37, 0x6F, 0x39, 0x6D, 0x66, 0x6A, 0x59, 0x63, 0x77, 0x6C, 0x59, 0x52, 0x6D, 0x36, 0x6D, 0x6E, 0x50, 0x54, 0x58, 0x4A, 0x39, 0x4F, 0x56, 0x32, 0x6A, 0x65, 0x44, 0x63, 0x68, 0x7A, 0x54, 0x63, ++ 0x2B, 0x43, 0x69, 0x52, 0x35, 0x6B, 0x44, 0x4F, 0x46, 0x33, 0x56, 0x53, 0x58, 0x6B, 0x41, 0x4B, 0x52, 0x7A, 0x48, 0x37, 0x4A, 0x73, 0x67, 0x48, 0x41, 0x63, 0x6B, 0x61, 0x56, 0x64, 0x34, 0x73, 0x6A, 0x6E, 0x38, 0x4F, 0x6F, 0x53, 0x67, 0x0A, ++ 0x74, 0x5A, 0x78, 0x38, 0x6A, 0x62, 0x38, 0x75, 0x6B, 0x32, 0x49, 0x6E, 0x74, 0x7A, 0x6E, 0x61, 0x46, 0x78, 0x69, 0x75, 0x76, 0x54, 0x77, 0x4A, 0x61, 0x50, 0x2B, 0x45, 0x6D, 0x7A, 0x7A, 0x56, 0x31, 0x67, 0x73, 0x44, 0x34, 0x31, 0x65, 0x65, ++ 0x46, 0x50, 0x66, 0x52, 0x36, 0x30, 0x2F, 0x49, 0x76, 0x59, 0x63, 0x6A, 0x74, 0x37, 0x5A, 0x4A, 0x51, 0x33, 0x6D, 0x46, 0x58, 0x4C, 0x72, 0x72, 0x6B, 0x67, 0x75, 0x68, 0x78, 0x75, 0x68, 0x6F, 0x71, 0x45, 0x77, 0x57, 0x0A, 0x73, 0x52, 0x71, ++ 0x5A, 0x43, 0x75, 0x68, 0x54, 0x4C, 0x4A, 0x4B, 0x37, 0x6F, 0x51, 0x6B, 0x59, 0x64, 0x51, 0x78, 0x6C, 0x71, 0x48, 0x76, 0x4C, 0x49, 0x37, 0x63, 0x61, 0x77, 0x69, 0x69, 0x46, 0x77, 0x78, 0x76, 0x2F, 0x30, 0x43, 0x74, 0x69, 0x37, 0x36, 0x52, ++ 0x37, 0x43, 0x5A, 0x47, 0x59, 0x5A, 0x34, 0x77, 0x55, 0x41, 0x63, 0x31, 0x6F, 0x42, 0x6D, 0x70, 0x6A, 0x49, 0x58, 0x55, 0x44, 0x67, 0x49, 0x69, 0x4B, 0x62, 0x6F, 0x48, 0x47, 0x68, 0x66, 0x4B, 0x70, 0x0A, 0x70, 0x43, 0x33, 0x6E, 0x39, 0x4B, ++ 0x55, 0x6B, 0x45, 0x45, 0x65, 0x44, 0x79, 0x73, 0x33, 0x30, 0x6A, 0x58, 0x6C, 0x59, 0x73, 0x51, 0x61, 0x62, 0x35, 0x78, 0x6F, 0x71, 0x32, 0x5A, 0x30, 0x42, 0x31, 0x35, 0x52, 0x39, 0x37, 0x51, 0x4E, 0x4B, 0x79, 0x76, 0x44, 0x62, 0x36, 0x4B, ++ 0x6B, 0x42, 0x50, 0x76, 0x56, 0x57, 0x6D, 0x63, 0x6B, 0x65, 0x6A, 0x6B, 0x6B, 0x39, 0x75, 0x2B, 0x55, 0x4A, 0x75, 0x65, 0x42, 0x50, 0x53, 0x5A, 0x49, 0x39, 0x46, 0x6F, 0x4A, 0x41, 0x0A, 0x7A, 0x4D, 0x78, 0x5A, 0x78, 0x75, 0x59, 0x36, 0x37, ++ 0x52, 0x49, 0x75, 0x61, 0x54, 0x78, 0x73, 0x6C, 0x62, 0x48, 0x39, 0x71, 0x68, 0x31, 0x37, 0x66, 0x34, 0x61, 0x2B, 0x48, 0x67, 0x34, 0x79, 0x52, 0x76, 0x76, 0x37, 0x45, 0x34, 0x39, 0x31, 0x66, 0x30, 0x79, 0x4C, 0x53, 0x30, 0x5A, 0x6A, 0x2F, ++ 0x67, 0x41, 0x30, 0x51, 0x48, 0x44, 0x42, 0x77, 0x37, 0x6D, 0x68, 0x33, 0x61, 0x5A, 0x77, 0x34, 0x67, 0x53, 0x7A, 0x51, 0x62, 0x7A, 0x70, 0x67, 0x4A, 0x48, 0x71, 0x0A, 0x5A, 0x4A, 0x78, 0x36, 0x34, 0x53, 0x49, 0x44, 0x71, 0x5A, 0x78, 0x75, ++ 0x62, 0x77, 0x35, 0x6C, 0x54, 0x32, 0x79, 0x48, 0x68, 0x31, 0x37, 0x7A, 0x62, 0x71, 0x44, 0x35, 0x64, 0x61, 0x57, 0x62, 0x51, 0x4F, 0x68, 0x54, 0x73, 0x69, 0x65, 0x64, 0x53, 0x72, 0x6E, 0x41, 0x64, 0x79, 0x47, 0x4E, 0x2F, 0x34, 0x66, 0x79, ++ 0x33, 0x72, 0x79, 0x4D, 0x37, 0x78, 0x66, 0x66, 0x74, 0x30, 0x6B, 0x4C, 0x30, 0x66, 0x4A, 0x75, 0x4D, 0x41, 0x73, 0x61, 0x44, 0x6B, 0x35, 0x32, 0x0A, 0x37, 0x52, 0x48, 0x38, 0x39, 0x65, 0x6C, 0x57, 0x73, 0x6E, 0x32, 0x2F, 0x78, 0x32, 0x30, ++ 0x4B, 0x6B, 0x34, 0x79, 0x6C, 0x30, 0x4D, 0x43, 0x32, 0x48, 0x62, 0x34, 0x36, 0x54, 0x70, 0x53, 0x69, 0x31, 0x32, 0x35, 0x73, 0x43, 0x38, 0x4B, 0x4B, 0x66, 0x50, 0x6F, 0x67, 0x38, 0x38, 0x54, 0x6B, 0x35, 0x63, 0x30, 0x4E, 0x71, 0x4D, 0x75, ++ 0x52, 0x6B, 0x72, 0x46, 0x38, 0x68, 0x65, 0x79, 0x31, 0x46, 0x47, 0x6C, 0x6D, 0x44, 0x6F, 0x4C, 0x6E, 0x7A, 0x63, 0x37, 0x49, 0x0A, 0x4C, 0x61, 0x5A, 0x52, 0x66, 0x79, 0x48, 0x42, 0x4E, 0x56, 0x4F, 0x46, 0x42, 0x6B, 0x70, 0x64, 0x6E, 0x36, ++ 0x32, 0x37, 0x47, 0x31, 0x39, 0x30, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x55, 0x53, 0x45, 0x52, 0x54, 0x72, ++ 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, ++ 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x33, 0x6A, 0x43, 0x43, 0x41, 0x38, 0x61, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x41, 0x66, ++ 0x31, 0x74, 0x4D, 0x50, 0x79, 0x6A, 0x79, 0x6C, 0x47, 0x6F, 0x47, 0x37, 0x78, 0x6B, 0x44, 0x6A, 0x55, 0x44, 0x4C, 0x54, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x77, 0x46, 0x41, 0x44, ++ 0x43, 0x42, 0x69, 0x44, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0A, 0x42, 0x68, 0x4D, 0x43, 0x56, 0x56, 0x4D, 0x78, 0x45, 0x7A, 0x41, 0x52, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x67, 0x54, 0x43, 0x6B, 0x35, 0x6C, 0x64, ++ 0x79, 0x42, 0x4B, 0x5A, 0x58, 0x4A, 0x7A, 0x5A, 0x58, 0x6B, 0x78, 0x46, 0x44, 0x41, 0x53, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x63, 0x54, 0x43, 0x30, 0x70, 0x6C, 0x63, 0x6E, 0x4E, 0x6C, 0x65, 0x53, 0x42, 0x44, 0x61, 0x58, 0x52, 0x35, 0x4D, ++ 0x52, 0x34, 0x77, 0x48, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x0A, 0x45, 0x78, 0x56, 0x55, 0x61, 0x47, 0x55, 0x67, 0x56, 0x56, 0x4E, 0x46, 0x55, 0x6C, 0x52, 0x53, 0x56, 0x56, 0x4E, 0x55, 0x49, 0x45, 0x35, 0x6C, 0x64, 0x48, 0x64, 0x76, ++ 0x63, 0x6D, 0x73, 0x78, 0x4C, 0x6A, 0x41, 0x73, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x4A, 0x56, 0x56, 0x54, 0x52, 0x56, 0x4A, 0x55, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x43, 0x42, 0x53, 0x55, 0x30, 0x45, 0x67, 0x51, 0x32, 0x56, 0x79, ++ 0x64, 0x47, 0x6C, 0x6D, 0x61, 0x57, 0x4E, 0x68, 0x0A, 0x64, 0x47, 0x6C, 0x76, 0x62, 0x69, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6F, 0x62, 0x33, 0x4A, 0x70, 0x64, 0x48, 0x6B, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x54, 0x41, 0x77, 0x4D, 0x6A, 0x41, ++ 0x78, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x57, 0x68, 0x63, 0x4E, 0x4D, 0x7A, 0x67, 0x77, 0x4D, 0x54, 0x45, 0x34, 0x4D, 0x6A, 0x4D, 0x31, 0x4F, 0x54, 0x55, 0x35, 0x57, 0x6A, 0x43, 0x42, 0x69, 0x44, 0x45, 0x4C, 0x4D, 0x41, 0x6B, ++ 0x47, 0x41, 0x31, 0x55, 0x45, 0x0A, 0x42, 0x68, 0x4D, 0x43, 0x56, 0x56, 0x4D, 0x78, 0x45, 0x7A, 0x41, 0x52, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x67, 0x54, 0x43, 0x6B, 0x35, 0x6C, 0x64, 0x79, 0x42, 0x4B, 0x5A, 0x58, 0x4A, 0x7A, 0x5A, 0x58, ++ 0x6B, 0x78, 0x46, 0x44, 0x41, 0x53, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x63, 0x54, 0x43, 0x30, 0x70, 0x6C, 0x63, 0x6E, 0x4E, 0x6C, 0x65, 0x53, 0x42, 0x44, 0x61, 0x58, 0x52, 0x35, 0x4D, 0x52, 0x34, 0x77, 0x48, 0x41, 0x59, 0x44, 0x56, 0x51, ++ 0x51, 0x4B, 0x0A, 0x45, 0x78, 0x56, 0x55, 0x61, 0x47, 0x55, 0x67, 0x56, 0x56, 0x4E, 0x46, 0x55, 0x6C, 0x52, 0x53, 0x56, 0x56, 0x4E, 0x55, 0x49, 0x45, 0x35, 0x6C, 0x64, 0x48, 0x64, 0x76, 0x63, 0x6D, 0x73, 0x78, 0x4C, 0x6A, 0x41, 0x73, 0x42, ++ 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x4A, 0x56, 0x56, 0x54, 0x52, 0x56, 0x4A, 0x55, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x43, 0x42, 0x53, 0x55, 0x30, 0x45, 0x67, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6C, 0x6D, 0x61, 0x57, 0x4E, 0x68, 0x0A, ++ 0x64, 0x47, 0x6C, 0x76, 0x62, 0x69, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6F, 0x62, 0x33, 0x4A, 0x70, 0x64, 0x48, 0x6B, 0x77, 0x67, 0x67, 0x49, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, ++ 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x43, 0x41, 0x45, 0x6D, 0x55, 0x58, 0x4E, 0x67, 0x37, 0x44, 0x32, 0x77, 0x69, 0x7A, 0x0A, 0x30, 0x4B, 0x78, ++ 0x58, 0x44, 0x58, 0x62, 0x74, 0x7A, 0x53, 0x66, 0x54, 0x54, 0x4B, 0x31, 0x51, 0x67, 0x32, 0x48, 0x69, 0x71, 0x69, 0x42, 0x4E, 0x43, 0x53, 0x31, 0x6B, 0x43, 0x64, 0x7A, 0x4F, 0x69, 0x5A, 0x2F, 0x4D, 0x50, 0x61, 0x6E, 0x73, 0x39, 0x73, 0x2F, ++ 0x42, 0x33, 0x50, 0x48, 0x54, 0x73, 0x64, 0x5A, 0x37, 0x4E, 0x79, 0x67, 0x52, 0x4B, 0x30, 0x66, 0x61, 0x4F, 0x63, 0x61, 0x38, 0x4F, 0x68, 0x6D, 0x30, 0x58, 0x36, 0x61, 0x39, 0x66, 0x5A, 0x32, 0x6A, 0x0A, 0x59, 0x30, 0x4B, 0x32, 0x64, 0x76, ++ 0x4B, 0x70, 0x4F, 0x79, 0x75, 0x52, 0x2B, 0x4F, 0x4A, 0x76, 0x30, 0x4F, 0x77, 0x57, 0x49, 0x4A, 0x41, 0x4A, 0x50, 0x75, 0x4C, 0x6F, 0x64, 0x4D, 0x6B, 0x59, 0x74, 0x4A, 0x48, 0x55, 0x59, 0x6D, 0x54, 0x62, 0x66, 0x36, 0x4D, 0x47, 0x38, 0x59, ++ 0x67, 0x59, 0x61, 0x70, 0x41, 0x69, 0x50, 0x4C, 0x7A, 0x2B, 0x45, 0x2F, 0x43, 0x48, 0x46, 0x48, 0x76, 0x32, 0x35, 0x42, 0x2B, 0x4F, 0x31, 0x4F, 0x52, 0x52, 0x78, 0x68, 0x46, 0x6E, 0x0A, 0x52, 0x67, 0x68, 0x52, 0x79, 0x34, 0x59, 0x55, 0x56, ++ 0x44, 0x2B, 0x38, 0x4D, 0x2F, 0x35, 0x2B, 0x62, 0x4A, 0x7A, 0x2F, 0x46, 0x70, 0x30, 0x59, 0x76, 0x56, 0x47, 0x4F, 0x4E, 0x61, 0x61, 0x6E, 0x5A, 0x73, 0x68, 0x79, 0x5A, 0x39, 0x73, 0x68, 0x5A, 0x72, 0x48, 0x55, 0x6D, 0x33, 0x67, 0x44, 0x77, ++ 0x46, 0x41, 0x36, 0x36, 0x4D, 0x7A, 0x77, 0x33, 0x4C, 0x79, 0x65, 0x54, 0x50, 0x36, 0x76, 0x42, 0x5A, 0x59, 0x31, 0x48, 0x31, 0x64, 0x61, 0x74, 0x2F, 0x2F, 0x4F, 0x0A, 0x2B, 0x54, 0x32, 0x33, 0x4C, 0x4C, 0x62, 0x32, 0x56, 0x4E, 0x33, 0x49, ++ 0x35, 0x78, 0x49, 0x36, 0x54, 0x61, 0x35, 0x4D, 0x69, 0x72, 0x64, 0x63, 0x6D, 0x72, 0x53, 0x33, 0x49, 0x44, 0x33, 0x4B, 0x66, 0x79, 0x49, 0x30, 0x72, 0x6E, 0x34, 0x37, 0x61, 0x47, 0x59, 0x42, 0x52, 0x4F, 0x63, 0x42, 0x54, 0x6B, 0x5A, 0x54, ++ 0x6D, 0x7A, 0x4E, 0x67, 0x39, 0x35, 0x53, 0x2B, 0x55, 0x7A, 0x65, 0x51, 0x63, 0x30, 0x50, 0x7A, 0x4D, 0x73, 0x4E, 0x54, 0x37, 0x39, 0x75, 0x71, 0x0A, 0x2F, 0x6E, 0x52, 0x4F, 0x61, 0x63, 0x64, 0x72, 0x6A, 0x47, 0x43, 0x54, 0x33, 0x73, 0x54, ++ 0x48, 0x44, 0x4E, 0x2F, 0x68, 0x4D, 0x71, 0x37, 0x4D, 0x6B, 0x7A, 0x74, 0x52, 0x65, 0x4A, 0x56, 0x6E, 0x69, 0x2B, 0x34, 0x39, 0x56, 0x76, 0x34, 0x4D, 0x30, 0x47, 0x6B, 0x50, 0x47, 0x77, 0x2F, 0x7A, 0x4A, 0x53, 0x5A, 0x72, 0x4D, 0x32, 0x33, ++ 0x33, 0x62, 0x6B, 0x66, 0x36, 0x63, 0x30, 0x50, 0x6C, 0x66, 0x67, 0x36, 0x6C, 0x5A, 0x72, 0x45, 0x70, 0x66, 0x44, 0x4B, 0x45, 0x0A, 0x59, 0x31, 0x57, 0x4A, 0x78, 0x41, 0x33, 0x42, 0x6B, 0x31, 0x51, 0x77, 0x47, 0x52, 0x4F, 0x73, 0x30, 0x33, ++ 0x30, 0x33, 0x70, 0x2B, 0x74, 0x64, 0x4F, 0x6D, 0x77, 0x31, 0x58, 0x4E, 0x74, 0x42, 0x31, 0x78, 0x4C, 0x61, 0x71, 0x55, 0x6B, 0x4C, 0x33, 0x39, 0x69, 0x41, 0x69, 0x67, 0x6D, 0x54, 0x59, 0x6F, 0x36, 0x31, 0x5A, 0x73, 0x38, 0x6C, 0x69, 0x4D, ++ 0x32, 0x45, 0x75, 0x4C, 0x45, 0x2F, 0x70, 0x44, 0x6B, 0x50, 0x32, 0x51, 0x4B, 0x65, 0x36, 0x78, 0x4A, 0x4D, 0x0A, 0x6C, 0x58, 0x7A, 0x7A, 0x61, 0x77, 0x57, 0x70, 0x58, 0x68, 0x61, 0x44, 0x7A, 0x4C, 0x68, 0x6E, 0x34, 0x75, 0x67, 0x54, 0x6E, ++ 0x63, 0x78, 0x62, 0x67, 0x74, 0x4E, 0x4D, 0x73, 0x2B, 0x31, 0x62, 0x2F, 0x39, 0x37, 0x6C, 0x63, 0x36, 0x77, 0x6A, 0x4F, 0x79, 0x30, 0x41, 0x76, 0x7A, 0x56, 0x56, 0x64, 0x41, 0x6C, 0x4A, 0x32, 0x45, 0x6C, 0x59, 0x47, 0x6E, 0x2B, 0x53, 0x4E, ++ 0x75, 0x5A, 0x52, 0x6B, 0x67, 0x37, 0x7A, 0x4A, 0x6E, 0x30, 0x63, 0x54, 0x52, 0x65, 0x38, 0x0A, 0x79, 0x65, 0x78, 0x44, 0x4A, 0x74, 0x43, 0x2F, 0x51, 0x56, 0x39, 0x41, 0x71, 0x55, 0x52, 0x45, 0x39, 0x4A, 0x6E, 0x6E, 0x56, 0x34, 0x65, 0x65, ++ 0x55, 0x42, 0x39, 0x58, 0x56, 0x4B, 0x67, 0x2B, 0x2F, 0x58, 0x52, 0x6A, 0x4C, 0x37, 0x46, 0x51, 0x5A, 0x51, 0x6E, 0x6D, 0x57, 0x45, 0x49, 0x75, 0x51, 0x78, 0x70, 0x4D, 0x74, 0x50, 0x41, 0x6C, 0x52, 0x31, 0x6E, 0x36, 0x42, 0x42, 0x36, 0x54, ++ 0x31, 0x43, 0x5A, 0x47, 0x53, 0x6C, 0x43, 0x42, 0x73, 0x74, 0x36, 0x2B, 0x0A, 0x65, 0x4C, 0x66, 0x38, 0x5A, 0x78, 0x58, 0x68, 0x79, 0x56, 0x65, 0x45, 0x48, 0x67, 0x39, 0x6A, 0x31, 0x75, 0x6C, 0x69, 0x75, 0x74, 0x5A, 0x66, 0x56, 0x53, 0x37, ++ 0x71, 0x58, 0x4D, 0x59, 0x6F, 0x43, 0x41, 0x51, 0x6C, 0x4F, 0x62, 0x67, 0x4F, 0x4B, 0x36, 0x6E, 0x79, 0x54, 0x4A, 0x63, 0x63, 0x42, 0x7A, 0x38, 0x4E, 0x55, 0x76, 0x58, 0x74, 0x37, 0x79, 0x2B, 0x43, 0x44, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, ++ 0x42, 0x6F, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, 0x64, 0x0A, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x55, 0x33, 0x6D, 0x2F, 0x57, 0x71, 0x6F, 0x72, 0x53, 0x73, 0x39, 0x55, 0x67, 0x4F, 0x48, 0x59, 0x6D, 0x38, ++ 0x43, 0x64, 0x38, 0x72, 0x49, 0x44, 0x5A, 0x73, 0x73, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, ++ 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x0A, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4D, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x42, 0x41, ++ 0x46, 0x7A, 0x55, 0x66, 0x41, 0x33, 0x50, 0x39, 0x77, 0x46, 0x39, 0x51, 0x5A, 0x6C, 0x6C, 0x44, 0x48, 0x50, 0x46, 0x55, 0x70, 0x2F, 0x4C, 0x2B, 0x4D, 0x2B, 0x5A, 0x42, 0x6E, 0x38, 0x62, 0x32, 0x6B, 0x4D, 0x56, 0x6E, 0x35, 0x34, 0x43, 0x56, ++ 0x56, 0x65, 0x57, 0x0A, 0x46, 0x50, 0x46, 0x53, 0x50, 0x43, 0x65, 0x48, 0x6C, 0x43, 0x6A, 0x74, 0x48, 0x7A, 0x6F, 0x42, 0x4E, 0x36, 0x4A, 0x32, 0x2F, 0x46, 0x4E, 0x51, 0x77, 0x49, 0x53, 0x62, 0x78, 0x6D, 0x74, 0x4F, 0x75, 0x6F, 0x77, 0x68, ++ 0x54, 0x36, 0x4B, 0x4F, 0x56, 0x57, 0x4B, 0x52, 0x38, 0x32, 0x6B, 0x56, 0x32, 0x4C, 0x79, 0x49, 0x34, 0x38, 0x53, 0x71, 0x43, 0x2F, 0x33, 0x76, 0x71, 0x4F, 0x6C, 0x4C, 0x56, 0x53, 0x6F, 0x47, 0x49, 0x47, 0x31, 0x56, 0x65, 0x43, 0x6B, 0x5A, ++ 0x0A, 0x37, 0x6C, 0x38, 0x77, 0x58, 0x45, 0x73, 0x6B, 0x45, 0x56, 0x58, 0x2F, 0x4A, 0x4A, 0x70, 0x75, 0x58, 0x69, 0x6F, 0x72, 0x37, 0x67, 0x74, 0x4E, 0x6E, 0x33, 0x2F, 0x33, 0x41, 0x54, 0x69, 0x55, 0x46, 0x4A, 0x56, 0x44, 0x42, 0x77, 0x6E, ++ 0x37, 0x59, 0x4B, 0x6E, 0x75, 0x48, 0x4B, 0x73, 0x53, 0x6A, 0x4B, 0x43, 0x61, 0x58, 0x71, 0x65, 0x59, 0x61, 0x6C, 0x6C, 0x74, 0x69, 0x7A, 0x38, 0x49, 0x2B, 0x38, 0x6A, 0x52, 0x52, 0x61, 0x38, 0x59, 0x46, 0x57, 0x53, 0x51, 0x0A, 0x45, 0x67, ++ 0x39, 0x7A, 0x4B, 0x43, 0x37, 0x46, 0x34, 0x69, 0x52, 0x4F, 0x2F, 0x46, 0x6A, 0x73, 0x38, 0x50, 0x52, 0x46, 0x2F, 0x69, 0x4B, 0x7A, 0x36, 0x79, 0x2B, 0x4F, 0x30, 0x74, 0x6C, 0x46, 0x59, 0x51, 0x58, 0x42, 0x6C, 0x32, 0x2B, 0x6F, 0x64, 0x6E, ++ 0x4B, 0x50, 0x69, 0x34, 0x77, 0x32, 0x72, 0x37, 0x38, 0x4E, 0x42, 0x63, 0x35, 0x78, 0x6A, 0x65, 0x61, 0x6D, 0x62, 0x78, 0x39, 0x73, 0x70, 0x6E, 0x46, 0x69, 0x78, 0x64, 0x6A, 0x51, 0x67, 0x33, 0x49, 0x4D, 0x0A, 0x38, 0x57, 0x63, 0x52, 0x69, ++ 0x51, 0x79, 0x63, 0x45, 0x30, 0x78, 0x79, 0x4E, 0x4E, 0x2B, 0x38, 0x31, 0x58, 0x48, 0x66, 0x71, 0x6E, 0x48, 0x64, 0x34, 0x62, 0x6C, 0x73, 0x6A, 0x44, 0x77, 0x53, 0x58, 0x57, 0x58, 0x61, 0x76, 0x56, 0x63, 0x53, 0x74, 0x6B, 0x4E, 0x72, 0x2F, ++ 0x2B, 0x58, 0x65, 0x54, 0x57, 0x59, 0x52, 0x55, 0x63, 0x2B, 0x5A, 0x72, 0x75, 0x77, 0x58, 0x74, 0x75, 0x68, 0x78, 0x6B, 0x59, 0x7A, 0x65, 0x53, 0x66, 0x37, 0x64, 0x4E, 0x58, 0x47, 0x69, 0x0A, 0x46, 0x53, 0x65, 0x55, 0x48, 0x4D, 0x39, 0x68, ++ 0x34, 0x79, 0x61, 0x37, 0x62, 0x36, 0x4E, 0x6E, 0x4A, 0x53, 0x46, 0x64, 0x35, 0x74, 0x30, 0x64, 0x43, 0x79, 0x35, 0x6F, 0x47, 0x7A, 0x75, 0x43, 0x72, 0x2B, 0x79, 0x44, 0x5A, 0x34, 0x58, 0x55, 0x6D, 0x46, 0x46, 0x30, 0x73, 0x62, 0x6D, 0x5A, ++ 0x67, 0x49, 0x6E, 0x2F, 0x66, 0x33, 0x67, 0x5A, 0x58, 0x48, 0x6C, 0x4B, 0x59, 0x43, 0x36, 0x53, 0x51, 0x4B, 0x35, 0x4D, 0x4E, 0x79, 0x6F, 0x73, 0x79, 0x63, 0x64, 0x69, 0x0A, 0x79, 0x41, 0x35, 0x64, 0x39, 0x7A, 0x5A, 0x62, 0x79, 0x75, 0x41, ++ 0x6C, 0x4A, 0x51, 0x47, 0x30, 0x33, 0x52, 0x6F, 0x48, 0x6E, 0x48, 0x63, 0x41, 0x50, 0x39, 0x44, 0x63, 0x31, 0x65, 0x77, 0x39, 0x31, 0x50, 0x71, 0x37, 0x50, 0x38, 0x79, 0x46, 0x31, 0x6D, 0x39, 0x2F, 0x71, 0x53, 0x33, 0x66, 0x75, 0x51, 0x4C, ++ 0x33, 0x39, 0x5A, 0x65, 0x61, 0x74, 0x54, 0x58, 0x61, 0x77, 0x32, 0x65, 0x77, 0x68, 0x30, 0x71, 0x70, 0x4B, 0x4A, 0x34, 0x6A, 0x6A, 0x76, 0x39, 0x63, 0x0A, 0x4A, 0x32, 0x76, 0x68, 0x73, 0x45, 0x2F, 0x7A, 0x42, 0x2B, 0x34, 0x41, 0x4C, 0x74, ++ 0x52, 0x5A, 0x68, 0x38, 0x74, 0x53, 0x51, 0x5A, 0x58, 0x71, 0x39, 0x45, 0x66, 0x58, 0x37, 0x6D, 0x52, 0x42, 0x56, 0x58, 0x79, 0x4E, 0x57, 0x51, 0x4B, 0x56, 0x33, 0x57, 0x4B, 0x64, 0x77, 0x72, 0x6E, 0x75, 0x57, 0x69, 0x68, 0x30, 0x68, 0x4B, ++ 0x57, 0x62, 0x74, 0x35, 0x44, 0x48, 0x44, 0x41, 0x66, 0x66, 0x39, 0x59, 0x6B, 0x32, 0x64, 0x44, 0x4C, 0x57, 0x4B, 0x4D, 0x47, 0x77, 0x0A, 0x73, 0x41, 0x76, 0x67, 0x6E, 0x45, 0x7A, 0x44, 0x48, 0x4E, 0x62, 0x38, 0x34, 0x32, 0x6D, 0x31, 0x52, ++ 0x30, 0x61, 0x42, 0x4C, 0x36, 0x4B, 0x43, 0x71, 0x39, 0x4E, 0x6A, 0x52, 0x48, 0x44, 0x45, 0x6A, 0x66, 0x38, 0x74, 0x4D, 0x37, 0x71, 0x74, 0x6A, 0x33, 0x75, 0x31, 0x63, 0x49, 0x69, 0x75, 0x50, 0x68, 0x6E, 0x50, 0x51, 0x43, 0x6A, 0x59, 0x2F, ++ 0x4D, 0x69, 0x51, 0x75, 0x31, 0x32, 0x5A, 0x49, 0x76, 0x56, 0x53, 0x35, 0x6C, 0x6A, 0x46, 0x48, 0x34, 0x67, 0x78, 0x0A, 0x51, 0x2B, 0x36, 0x49, 0x48, 0x64, 0x66, 0x47, 0x6A, 0x6A, 0x78, 0x44, 0x61, 0x68, 0x32, 0x6E, 0x47, 0x4E, 0x35, 0x39, ++ 0x50, 0x52, 0x62, 0x78, 0x59, 0x76, 0x6E, 0x4B, 0x6B, 0x4B, 0x6A, 0x39, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, ++ 0x55, 0x53, 0x45, 0x52, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x0A, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x6A, 0x7A, 0x43, 0x43, 0x41, 0x68, 0x57, 0x67, 0x41, 0x77, 0x49, 0x42, ++ 0x41, 0x67, 0x49, 0x51, 0x58, 0x49, 0x75, 0x5A, 0x78, 0x56, 0x71, 0x55, 0x78, 0x64, 0x4A, 0x78, 0x56, 0x74, 0x37, 0x4E, 0x69, 0x59, 0x44, 0x4D, 0x4A, 0x6A, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, ++ 0x41, 0x7A, 0x43, 0x42, 0x69, 0x44, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x0A, 0x56, 0x56, 0x4D, 0x78, 0x45, 0x7A, 0x41, 0x52, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x67, 0x54, 0x43, 0x6B, 0x35, ++ 0x6C, 0x64, 0x79, 0x42, 0x4B, 0x5A, 0x58, 0x4A, 0x7A, 0x5A, 0x58, 0x6B, 0x78, 0x46, 0x44, 0x41, 0x53, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x63, 0x54, 0x43, 0x30, 0x70, 0x6C, 0x63, 0x6E, 0x4E, 0x6C, 0x65, 0x53, 0x42, 0x44, 0x61, 0x58, 0x52, ++ 0x35, 0x4D, 0x52, 0x34, 0x77, 0x48, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x78, 0x56, 0x55, 0x0A, 0x61, 0x47, 0x55, 0x67, 0x56, 0x56, 0x4E, 0x46, 0x55, 0x6C, 0x52, 0x53, 0x56, 0x56, 0x4E, 0x55, 0x49, 0x45, 0x35, 0x6C, 0x64, 0x48, ++ 0x64, 0x76, 0x63, 0x6D, 0x73, 0x78, 0x4C, 0x6A, 0x41, 0x73, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x4A, 0x56, 0x56, 0x54, 0x52, 0x56, 0x4A, 0x55, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x43, 0x42, 0x46, 0x51, 0x30, 0x4D, 0x67, 0x51, 0x32, ++ 0x56, 0x79, 0x64, 0x47, 0x6C, 0x6D, 0x61, 0x57, 0x4E, 0x68, 0x64, 0x47, 0x6C, 0x76, 0x0A, 0x62, 0x69, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6F, 0x62, 0x33, 0x4A, 0x70, 0x64, 0x48, 0x6B, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x54, 0x41, 0x77, 0x4D, ++ 0x6A, 0x41, 0x78, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x57, 0x68, 0x63, 0x4E, 0x4D, 0x7A, 0x67, 0x77, 0x4D, 0x54, 0x45, 0x34, 0x4D, 0x6A, 0x4D, 0x31, 0x4F, 0x54, 0x55, 0x35, 0x57, 0x6A, 0x43, 0x42, 0x69, 0x44, 0x45, 0x4C, 0x4D, ++ 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x0A, 0x56, 0x56, 0x4D, 0x78, 0x45, 0x7A, 0x41, 0x52, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x67, 0x54, 0x43, 0x6B, 0x35, 0x6C, 0x64, 0x79, 0x42, 0x4B, 0x5A, 0x58, 0x4A, 0x7A, ++ 0x5A, 0x58, 0x6B, 0x78, 0x46, 0x44, 0x41, 0x53, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x63, 0x54, 0x43, 0x30, 0x70, 0x6C, 0x63, 0x6E, 0x4E, 0x6C, 0x65, 0x53, 0x42, 0x44, 0x61, 0x58, 0x52, 0x35, 0x4D, 0x52, 0x34, 0x77, 0x48, 0x41, 0x59, 0x44, ++ 0x56, 0x51, 0x51, 0x4B, 0x45, 0x78, 0x56, 0x55, 0x0A, 0x61, 0x47, 0x55, 0x67, 0x56, 0x56, 0x4E, 0x46, 0x55, 0x6C, 0x52, 0x53, 0x56, 0x56, 0x4E, 0x55, 0x49, 0x45, 0x35, 0x6C, 0x64, 0x48, 0x64, 0x76, 0x63, 0x6D, 0x73, 0x78, 0x4C, 0x6A, 0x41, ++ 0x73, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x4A, 0x56, 0x56, 0x54, 0x52, 0x56, 0x4A, 0x55, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x43, 0x42, 0x46, 0x51, 0x30, 0x4D, 0x67, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6C, 0x6D, 0x61, 0x57, 0x4E, ++ 0x68, 0x64, 0x47, 0x6C, 0x76, 0x0A, 0x62, 0x69, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6F, 0x62, 0x33, 0x4A, 0x70, 0x64, 0x48, 0x6B, 0x77, 0x64, 0x6A, 0x41, 0x51, 0x42, 0x67, 0x63, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x49, 0x42, 0x42, 0x67, ++ 0x55, 0x72, 0x67, 0x51, 0x51, 0x41, 0x49, 0x67, 0x4E, 0x69, 0x41, 0x41, 0x51, 0x61, 0x72, 0x46, 0x52, 0x61, 0x71, 0x66, 0x6C, 0x6F, 0x49, 0x2B, 0x64, 0x36, 0x31, 0x53, 0x52, 0x76, 0x55, 0x38, 0x5A, 0x61, 0x32, 0x45, 0x75, 0x72, 0x78, 0x74, ++ 0x57, 0x32, 0x0A, 0x30, 0x65, 0x5A, 0x7A, 0x63, 0x61, 0x37, 0x64, 0x6E, 0x4E, 0x59, 0x4D, 0x59, 0x66, 0x33, 0x62, 0x6F, 0x49, 0x6B, 0x44, 0x75, 0x41, 0x55, 0x55, 0x37, 0x46, 0x66, 0x4F, 0x37, 0x6C, 0x30, 0x2F, 0x34, 0x69, 0x47, 0x7A, 0x7A, ++ 0x76, 0x66, 0x55, 0x69, 0x6E, 0x6E, 0x67, 0x6F, 0x34, 0x4E, 0x2B, 0x4C, 0x5A, 0x66, 0x51, 0x59, 0x63, 0x54, 0x78, 0x6D, 0x64, 0x77, 0x6C, 0x6B, 0x57, 0x4F, 0x72, 0x66, 0x7A, 0x43, 0x6A, 0x74, 0x48, 0x44, 0x69, 0x78, 0x36, 0x45, 0x7A, 0x0A, ++ 0x6E, 0x50, 0x4F, 0x2F, 0x4C, 0x6C, 0x78, 0x54, 0x73, 0x56, 0x2B, 0x7A, 0x66, 0x54, 0x4A, 0x2F, 0x69, 0x6A, 0x54, 0x6A, 0x65, 0x58, 0x6D, 0x6A, 0x51, 0x6A, 0x42, 0x41, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, ++ 0x42, 0x42, 0x51, 0x36, 0x34, 0x51, 0x6D, 0x47, 0x31, 0x4D, 0x38, 0x5A, 0x77, 0x70, 0x5A, 0x32, 0x64, 0x45, 0x6C, 0x32, 0x33, 0x4F, 0x41, 0x31, 0x78, 0x6D, 0x4E, 0x6A, 0x6D, 0x6A, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x0A, 0x48, 0x51, 0x38, ++ 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x51, 0x59, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x4B, 0x42, 0x67, 0x67, ++ 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x77, 0x4E, 0x6F, 0x41, 0x44, 0x42, 0x6C, 0x41, 0x6A, 0x41, 0x32, 0x5A, 0x36, 0x45, 0x57, 0x43, 0x4E, 0x7A, 0x6B, 0x6C, 0x77, 0x42, 0x42, 0x0A, 0x48, 0x55, 0x36, 0x2B, 0x34, 0x57, ++ 0x4D, 0x42, 0x7A, 0x7A, 0x75, 0x71, 0x51, 0x68, 0x46, 0x6B, 0x6F, 0x4A, 0x32, 0x55, 0x4F, 0x51, 0x49, 0x52, 0x65, 0x56, 0x78, 0x37, 0x48, 0x66, 0x70, 0x6B, 0x75, 0x65, 0x34, 0x57, 0x51, 0x72, 0x4F, 0x2F, 0x69, 0x73, 0x49, 0x4A, 0x78, 0x4F, ++ 0x7A, 0x6B, 0x73, 0x55, 0x30, 0x43, 0x4D, 0x51, 0x44, 0x70, 0x4B, 0x6D, 0x46, 0x48, 0x6A, 0x46, 0x4A, 0x4B, 0x53, 0x30, 0x34, 0x59, 0x63, 0x50, 0x62, 0x57, 0x52, 0x4E, 0x5A, 0x75, 0x0A, 0x39, 0x59, 0x4F, 0x36, 0x62, 0x56, 0x69, 0x39, 0x4A, ++ 0x4E, 0x6C, 0x57, 0x53, 0x4F, 0x72, 0x76, 0x78, 0x4B, 0x4A, 0x47, 0x67, 0x59, 0x68, 0x71, 0x4F, 0x6B, 0x62, 0x52, 0x71, 0x5A, 0x74, 0x4E, 0x79, 0x57, 0x48, 0x61, 0x30, 0x56, 0x31, 0x58, 0x61, 0x68, 0x67, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, ++ 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x52, 0x35, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, ++ 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x48, 0x6A, 0x43, 0x43, 0x41, 0x61, 0x53, 0x67, 0x41, ++ 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x52, 0x59, 0x46, 0x6C, 0x4A, 0x34, 0x43, 0x59, 0x75, 0x75, 0x31, 0x58, 0x35, 0x43, 0x6E, 0x65, 0x4B, 0x63, 0x66, 0x6C, 0x4B, 0x32, 0x47, 0x77, 0x77, 0x43, 0x67, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, ++ 0x6A, 0x30, 0x45, 0x41, 0x77, 0x4D, 0x77, 0x55, 0x44, 0x45, 0x6B, 0x4D, 0x43, 0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4D, 0x62, 0x0A, 0x52, 0x32, 0x78, 0x76, 0x59, 0x6D, 0x46, 0x73, 0x55, 0x32, 0x6C, 0x6E, 0x62, 0x69, 0x42, 0x46, ++ 0x51, 0x30, 0x4D, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x53, 0x41, 0x74, 0x49, 0x46, 0x49, 0x31, 0x4D, 0x52, 0x4D, 0x77, 0x45, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x77, 0x70, 0x48, 0x62, 0x47, 0x39, 0x69, ++ 0x59, 0x57, 0x78, 0x54, 0x61, 0x57, 0x64, 0x75, 0x4D, 0x52, 0x4D, 0x77, 0x45, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x0A, 0x45, 0x77, 0x70, 0x48, 0x62, 0x47, 0x39, 0x69, 0x59, 0x57, 0x78, 0x54, 0x61, 0x57, 0x64, 0x75, 0x4D, 0x42, 0x34, ++ 0x58, 0x44, 0x54, 0x45, 0x79, 0x4D, 0x54, 0x45, 0x78, 0x4D, 0x7A, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x46, 0x6F, 0x58, 0x44, 0x54, 0x4D, 0x34, 0x4D, 0x44, 0x45, 0x78, 0x4F, 0x54, 0x41, 0x7A, 0x4D, 0x54, 0x51, 0x77, 0x4E, 0x31, 0x6F, ++ 0x77, 0x55, 0x44, 0x45, 0x6B, 0x4D, 0x43, 0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4D, 0x62, 0x0A, 0x52, 0x32, 0x78, 0x76, 0x59, 0x6D, 0x46, 0x73, 0x55, 0x32, 0x6C, 0x6E, 0x62, 0x69, 0x42, 0x46, 0x51, 0x30, 0x4D, 0x67, 0x55, 0x6D, ++ 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x53, 0x41, 0x74, 0x49, 0x46, 0x49, 0x31, 0x4D, 0x52, 0x4D, 0x77, 0x45, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x77, 0x70, 0x48, 0x62, 0x47, 0x39, 0x69, 0x59, 0x57, 0x78, 0x54, 0x61, 0x57, ++ 0x64, 0x75, 0x4D, 0x52, 0x4D, 0x77, 0x45, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x0A, 0x45, 0x77, 0x70, 0x48, 0x62, 0x47, 0x39, 0x69, 0x59, 0x57, 0x78, 0x54, 0x61, 0x57, 0x64, 0x75, 0x4D, 0x48, 0x59, 0x77, 0x45, 0x41, 0x59, 0x48, 0x4B, ++ 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x46, 0x4B, 0x34, 0x45, 0x45, 0x41, 0x43, 0x49, 0x44, 0x59, 0x67, 0x41, 0x45, 0x52, 0x30, 0x55, 0x4F, 0x6C, 0x76, 0x74, 0x39, 0x58, 0x62, 0x2F, 0x70, 0x4F, 0x64, 0x45, 0x68, 0x2B, ++ 0x4A, 0x38, 0x4C, 0x74, 0x74, 0x56, 0x37, 0x48, 0x70, 0x49, 0x36, 0x0A, 0x53, 0x46, 0x6B, 0x63, 0x38, 0x47, 0x49, 0x78, 0x4C, 0x63, 0x42, 0x36, 0x4B, 0x50, 0x34, 0x61, 0x70, 0x31, 0x79, 0x7A, 0x74, 0x73, 0x79, 0x58, 0x35, 0x30, 0x58, 0x55, ++ 0x57, 0x50, 0x72, 0x52, 0x64, 0x32, 0x31, 0x44, 0x6F, 0x73, 0x43, 0x48, 0x5A, 0x54, 0x51, 0x4B, 0x48, 0x33, 0x72, 0x64, 0x36, 0x7A, 0x77, 0x7A, 0x6F, 0x63, 0x57, 0x64, 0x54, 0x61, 0x52, 0x76, 0x51, 0x5A, 0x55, 0x34, 0x66, 0x38, 0x6B, 0x65, ++ 0x68, 0x4F, 0x76, 0x52, 0x6E, 0x6B, 0x6D, 0x53, 0x0A, 0x68, 0x35, 0x53, 0x48, 0x44, 0x44, 0x71, 0x46, 0x53, 0x6D, 0x61, 0x66, 0x6E, 0x56, 0x6D, 0x54, 0x54, 0x5A, 0x64, 0x68, 0x42, 0x6F, 0x5A, 0x4B, 0x6F, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, ++ 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x51, 0x59, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, ++ 0x42, 0x2F, 0x7A, 0x41, 0x64, 0x0A, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x50, 0x65, 0x59, 0x70, 0x53, 0x4A, 0x76, 0x71, 0x42, 0x38, 0x6F, 0x68, 0x52, 0x45, 0x6F, 0x6D, 0x33, 0x6D, 0x37, 0x65, 0x30, 0x6F, ++ 0x50, 0x51, 0x6E, 0x31, 0x6B, 0x77, 0x43, 0x67, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x45, 0x41, 0x77, 0x4D, 0x44, 0x61, 0x41, 0x41, 0x77, 0x5A, 0x51, 0x49, 0x78, 0x41, 0x4F, 0x56, 0x70, 0x45, 0x73, 0x6C, 0x75, 0x32, 0x38, ++ 0x59, 0x78, 0x0A, 0x75, 0x67, 0x6C, 0x42, 0x34, 0x5A, 0x66, 0x34, 0x2B, 0x2F, 0x32, 0x61, 0x34, 0x6E, 0x30, 0x53, 0x79, 0x65, 0x31, 0x38, 0x5A, 0x4E, 0x50, 0x4C, 0x42, 0x53, 0x57, 0x4C, 0x56, 0x74, 0x6D, 0x67, 0x35, 0x31, 0x35, 0x64, 0x54, ++ 0x67, 0x75, 0x44, 0x6E, 0x46, 0x74, 0x32, 0x4B, 0x61, 0x41, 0x4A, 0x4A, 0x69, 0x46, 0x71, 0x59, 0x67, 0x49, 0x77, 0x63, 0x64, 0x4B, 0x31, 0x6A, 0x31, 0x7A, 0x71, 0x4F, 0x2B, 0x46, 0x34, 0x43, 0x59, 0x57, 0x6F, 0x64, 0x5A, 0x49, 0x37, 0x0A, ++ 0x79, 0x46, 0x7A, 0x39, 0x53, 0x4F, 0x38, 0x4E, 0x64, 0x43, 0x4B, 0x6F, 0x43, 0x4F, 0x4A, 0x75, 0x78, 0x55, 0x6E, 0x4F, 0x78, 0x77, 0x79, 0x38, 0x70, 0x32, 0x46, 0x70, 0x38, 0x66, 0x63, 0x37, 0x34, 0x53, 0x72, 0x4C, 0x2B, 0x53, 0x76, 0x7A, ++ 0x5A, 0x70, 0x41, 0x33, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x49, 0x64, 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, ++ 0x74, 0x20, 0x43, 0x6F, 0x6D, 0x6D, 0x65, 0x72, 0x63, 0x69, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x59, 0x44, 0x43, 0x43, 0x41, 0x30, 0x69, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x43, 0x67, 0x46, 0x43, 0x67, 0x41, 0x41, 0x41, 0x41, 0x55, 0x55, 0x6A, 0x79, 0x45, 0x53, 0x31, 0x41, 0x41, ++ 0x41, 0x41, 0x41, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x42, 0x4B, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0A, 0x45, ++ 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x53, 0x4D, 0x42, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x4A, 0x53, 0x57, 0x52, 0x6C, 0x62, 0x6C, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x4D, 0x53, 0x63, 0x77, 0x4A, 0x51, 0x59, 0x44, 0x56, ++ 0x51, 0x51, 0x44, 0x45, 0x78, 0x35, 0x4A, 0x5A, 0x47, 0x56, 0x75, 0x56, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x67, 0x51, 0x32, 0x39, 0x74, 0x62, 0x57, 0x56, 0x79, 0x59, 0x32, 0x6C, 0x68, 0x62, 0x43, 0x42, 0x53, 0x0A, 0x62, 0x32, 0x39, 0x30, ++ 0x49, 0x45, 0x4E, 0x42, 0x49, 0x44, 0x45, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x54, 0x51, 0x77, 0x4D, 0x54, 0x45, 0x32, 0x4D, 0x54, 0x67, 0x78, 0x4D, 0x6A, 0x49, 0x7A, 0x57, 0x68, 0x63, 0x4E, 0x4D, 0x7A, 0x51, 0x77, 0x4D, 0x54, 0x45, 0x32, ++ 0x4D, 0x54, 0x67, 0x78, 0x4D, 0x6A, 0x49, 0x7A, 0x57, 0x6A, 0x42, 0x4B, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x53, 0x0A, 0x4D, 0x42, 0x41, 0x47, 0x41, 0x31, 0x55, ++ 0x45, 0x43, 0x68, 0x4D, 0x4A, 0x53, 0x57, 0x52, 0x6C, 0x62, 0x6C, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x4D, 0x53, 0x63, 0x77, 0x4A, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x35, 0x4A, 0x5A, 0x47, 0x56, 0x75, 0x56, 0x48, 0x4A, ++ 0x31, 0x63, 0x33, 0x51, 0x67, 0x51, 0x32, 0x39, 0x74, 0x62, 0x57, 0x56, 0x79, 0x59, 0x32, 0x6C, 0x68, 0x62, 0x43, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x0A, 0x49, 0x44, 0x45, 0x77, 0x67, 0x67, 0x49, 0x69, 0x4D, 0x41, ++ 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x43, 0x6E, 0x55, 0x42, ++ 0x6E, 0x65, 0x50, 0x35, 0x6B, 0x39, 0x31, 0x44, 0x4E, 0x47, 0x38, 0x57, 0x39, 0x52, 0x59, 0x59, 0x4B, 0x79, 0x71, 0x55, 0x2B, 0x50, 0x5A, 0x34, 0x6C, 0x64, 0x0A, 0x68, 0x4E, 0x6C, 0x54, 0x33, 0x51, 0x77, 0x6F, 0x32, 0x64, 0x66, 0x77, 0x2F, ++ 0x36, 0x36, 0x56, 0x51, 0x33, 0x4B, 0x5A, 0x2B, 0x62, 0x56, 0x64, 0x66, 0x49, 0x72, 0x42, 0x51, 0x75, 0x45, 0x78, 0x55, 0x48, 0x54, 0x52, 0x67, 0x51, 0x31, 0x38, 0x7A, 0x5A, 0x73, 0x68, 0x71, 0x30, 0x50, 0x69, 0x72, 0x4B, 0x31, 0x65, 0x68, ++ 0x6D, 0x37, 0x7A, 0x43, 0x59, 0x6F, 0x66, 0x57, 0x6A, 0x4B, 0x39, 0x6F, 0x75, 0x75, 0x55, 0x2B, 0x65, 0x68, 0x63, 0x43, 0x75, 0x7A, 0x2F, 0x0A, 0x6D, 0x4E, 0x4B, 0x76, 0x63, 0x62, 0x4F, 0x30, 0x55, 0x35, 0x39, 0x4F, 0x68, 0x2B, 0x2B, 0x53, ++ 0x76, 0x4C, 0x33, 0x73, 0x54, 0x7A, 0x49, 0x77, 0x69, 0x45, 0x73, 0x58, 0x58, 0x6C, 0x66, 0x45, 0x55, 0x38, 0x4C, 0x32, 0x41, 0x70, 0x65, 0x4E, 0x32, 0x57, 0x49, 0x72, 0x76, 0x79, 0x51, 0x66, 0x59, 0x6F, 0x33, 0x66, 0x77, 0x37, 0x67, 0x70, ++ 0x53, 0x30, 0x6C, 0x34, 0x50, 0x4A, 0x4E, 0x67, 0x69, 0x43, 0x4C, 0x38, 0x6D, 0x64, 0x6F, 0x32, 0x79, 0x4D, 0x4B, 0x69, 0x0A, 0x31, 0x43, 0x78, 0x55, 0x41, 0x47, 0x63, 0x31, 0x62, 0x6E, 0x4F, 0x2F, 0x41, 0x6C, 0x6A, 0x77, 0x70, 0x4E, 0x33, ++ 0x6C, 0x73, 0x4B, 0x49, 0x6D, 0x65, 0x73, 0x72, 0x67, 0x4E, 0x71, 0x55, 0x5A, 0x46, 0x76, 0x58, 0x39, 0x74, 0x2B, 0x2B, 0x75, 0x50, 0x30, 0x44, 0x31, 0x62, 0x56, 0x6F, 0x45, 0x2F, 0x63, 0x34, 0x30, 0x79, 0x69, 0x54, 0x63, 0x64, 0x43, 0x4D, ++ 0x62, 0x58, 0x54, 0x4D, 0x54, 0x45, 0x6C, 0x33, 0x45, 0x41, 0x53, 0x58, 0x32, 0x4D, 0x4E, 0x30, 0x43, 0x0A, 0x58, 0x5A, 0x2F, 0x67, 0x31, 0x55, 0x65, 0x39, 0x74, 0x4F, 0x73, 0x62, 0x6F, 0x62, 0x74, 0x4A, 0x53, 0x64, 0x69, 0x66, 0x57, 0x77, ++ 0x4C, 0x7A, 0x69, 0x75, 0x51, 0x6B, 0x6B, 0x4F, 0x52, 0x69, 0x54, 0x30, 0x2F, 0x42, 0x72, 0x34, 0x73, 0x4F, 0x64, 0x42, 0x65, 0x6F, 0x30, 0x58, 0x4B, 0x49, 0x61, 0x6E, 0x6F, 0x42, 0x53, 0x63, 0x79, 0x30, 0x52, 0x6E, 0x6E, 0x47, 0x46, 0x37, ++ 0x48, 0x61, 0x6D, 0x42, 0x34, 0x48, 0x57, 0x66, 0x70, 0x31, 0x49, 0x59, 0x56, 0x6C, 0x0A, 0x33, 0x5A, 0x42, 0x57, 0x7A, 0x76, 0x75, 0x72, 0x70, 0x57, 0x43, 0x64, 0x78, 0x4A, 0x33, 0x35, 0x55, 0x72, 0x43, 0x4C, 0x76, 0x59, 0x66, 0x35, 0x6A, ++ 0x79, 0x73, 0x6A, 0x43, 0x69, 0x4E, 0x32, 0x4F, 0x2F, 0x63, 0x7A, 0x34, 0x63, 0x6B, 0x41, 0x38, 0x32, 0x6E, 0x35, 0x53, 0x36, 0x4C, 0x67, 0x54, 0x72, 0x78, 0x2B, 0x6B, 0x7A, 0x6D, 0x45, 0x42, 0x2F, 0x64, 0x45, 0x63, 0x48, 0x37, 0x2B, 0x42, ++ 0x31, 0x72, 0x6C, 0x73, 0x61, 0x7A, 0x52, 0x47, 0x4D, 0x7A, 0x79, 0x0A, 0x4E, 0x65, 0x56, 0x4A, 0x53, 0x51, 0x6A, 0x4B, 0x56, 0x73, 0x6B, 0x39, 0x2B, 0x77, 0x38, 0x59, 0x66, 0x59, 0x73, 0x37, 0x77, 0x52, 0x50, 0x43, 0x54, 0x59, 0x2F, 0x4A, ++ 0x54, 0x77, 0x34, 0x33, 0x36, 0x52, 0x2B, 0x68, 0x44, 0x6D, 0x72, 0x66, 0x59, 0x69, 0x37, 0x4C, 0x4E, 0x51, 0x5A, 0x52, 0x65, 0x53, 0x7A, 0x49, 0x4A, 0x54, 0x6A, 0x30, 0x2B, 0x6B, 0x75, 0x6E, 0x69, 0x56, 0x79, 0x63, 0x30, 0x75, 0x4D, 0x4E, ++ 0x4F, 0x59, 0x5A, 0x4B, 0x64, 0x48, 0x7A, 0x56, 0x0A, 0x57, 0x59, 0x66, 0x43, 0x50, 0x30, 0x34, 0x4D, 0x58, 0x46, 0x4C, 0x30, 0x50, 0x66, 0x64, 0x53, 0x67, 0x76, 0x48, 0x71, 0x6F, 0x36, 0x7A, 0x39, 0x53, 0x54, 0x51, 0x61, 0x4B, 0x50, 0x4E, ++ 0x42, 0x69, 0x44, 0x6F, 0x54, 0x37, 0x75, 0x6A, 0x65, 0x2F, 0x35, 0x6B, 0x64, 0x58, 0x37, 0x72, 0x4C, 0x36, 0x42, 0x37, 0x79, 0x75, 0x56, 0x42, 0x67, 0x77, 0x44, 0x48, 0x54, 0x63, 0x2B, 0x58, 0x76, 0x76, 0x71, 0x44, 0x74, 0x4D, 0x77, 0x74, ++ 0x30, 0x76, 0x69, 0x41, 0x67, 0x0A, 0x78, 0x47, 0x64, 0x73, 0x38, 0x41, 0x67, 0x44, 0x65, 0x6C, 0x57, 0x41, 0x66, 0x30, 0x5A, 0x4F, 0x6C, 0x71, 0x66, 0x30, 0x48, 0x6A, 0x37, 0x68, 0x39, 0x74, 0x67, 0x4A, 0x34, 0x54, 0x4E, 0x6B, 0x4B, 0x32, ++ 0x50, 0x58, 0x4D, 0x6C, 0x36, 0x66, 0x2B, 0x63, 0x42, 0x37, 0x44, 0x33, 0x68, 0x76, 0x6C, 0x37, 0x79, 0x54, 0x6D, 0x76, 0x6D, 0x63, 0x45, 0x70, 0x42, 0x34, 0x65, 0x6F, 0x43, 0x48, 0x46, 0x64, 0x64, 0x79, 0x64, 0x4A, 0x78, 0x56, 0x64, 0x48, ++ 0x69, 0x78, 0x0A, 0x75, 0x75, 0x46, 0x75, 0x63, 0x41, 0x53, 0x36, 0x54, 0x36, 0x43, 0x36, 0x61, 0x4D, 0x4E, 0x37, 0x2F, 0x7A, 0x48, 0x77, 0x63, 0x7A, 0x30, 0x39, 0x6C, 0x43, 0x71, 0x78, 0x43, 0x30, 0x45, 0x4F, 0x6F, 0x50, 0x35, 0x4E, 0x69, ++ 0x47, 0x56, 0x72, 0x65, 0x54, 0x4F, 0x30, 0x31, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6F, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x0A, ++ 0x41, 0x51, 0x59, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, ++ 0x37, 0x55, 0x51, 0x5A, 0x77, 0x4E, 0x50, 0x77, 0x42, 0x6F, 0x76, 0x75, 0x70, 0x48, 0x75, 0x2B, 0x51, 0x75, 0x63, 0x6D, 0x56, 0x4D, 0x69, 0x4F, 0x4E, 0x6E, 0x59, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x0A, 0x68, 0x76, 0x63, ++ 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x42, 0x41, 0x41, 0x32, 0x75, 0x6B, 0x44, 0x4C, 0x32, 0x70, 0x6B, 0x74, 0x38, 0x52, 0x48, 0x59, 0x5A, 0x59, 0x52, 0x34, 0x6E, 0x4B, 0x4D, 0x31, 0x65, 0x56, 0x4F, 0x38, ++ 0x6C, 0x76, 0x4F, 0x4D, 0x49, 0x6B, 0x50, 0x6B, 0x70, 0x31, 0x36, 0x35, 0x6F, 0x43, 0x4F, 0x47, 0x55, 0x41, 0x46, 0x6A, 0x76, 0x4C, 0x69, 0x35, 0x2B, 0x55, 0x31, 0x4B, 0x4D, 0x74, 0x6C, 0x77, 0x48, 0x0A, 0x36, 0x6F, 0x69, 0x36, 0x6D, 0x59, ++ 0x74, 0x51, 0x6C, 0x4E, 0x65, 0x43, 0x67, 0x4E, 0x39, 0x68, 0x43, 0x51, 0x43, 0x54, 0x72, 0x51, 0x30, 0x55, 0x35, 0x73, 0x37, 0x42, 0x38, 0x6A, 0x65, 0x55, 0x65, 0x4C, 0x42, 0x66, 0x6E, 0x4C, 0x4F, 0x69, 0x63, 0x37, 0x69, 0x50, 0x42, 0x5A, ++ 0x4D, 0x34, 0x7A, 0x59, 0x30, 0x2B, 0x73, 0x4C, 0x6A, 0x37, 0x77, 0x4D, 0x2B, 0x78, 0x38, 0x75, 0x77, 0x74, 0x4C, 0x52, 0x76, 0x4D, 0x37, 0x4B, 0x71, 0x61, 0x73, 0x36, 0x70, 0x67, 0x0A, 0x67, 0x68, 0x73, 0x74, 0x4F, 0x38, 0x4F, 0x45, 0x50, ++ 0x56, 0x65, 0x4B, 0x6C, 0x68, 0x36, 0x63, 0x64, 0x62, 0x6A, 0x54, 0x4D, 0x4D, 0x31, 0x67, 0x43, 0x49, 0x4F, 0x51, 0x30, 0x34, 0x35, 0x55, 0x38, 0x55, 0x31, 0x6D, 0x77, 0x46, 0x31, 0x30, 0x41, 0x30, 0x43, 0x6A, 0x37, 0x6F, 0x56, 0x2B, 0x77, ++ 0x68, 0x39, 0x33, 0x6E, 0x41, 0x62, 0x6F, 0x77, 0x61, 0x63, 0x59, 0x58, 0x56, 0x4B, 0x56, 0x37, 0x63, 0x6E, 0x64, 0x4A, 0x5A, 0x35, 0x74, 0x2B, 0x71, 0x6E, 0x74, 0x0A, 0x6F, 0x7A, 0x6F, 0x30, 0x30, 0x46, 0x6C, 0x37, 0x32, 0x75, 0x31, 0x51, ++ 0x38, 0x7A, 0x57, 0x2F, 0x37, 0x65, 0x73, 0x55, 0x54, 0x54, 0x48, 0x48, 0x59, 0x50, 0x54, 0x61, 0x38, 0x59, 0x65, 0x63, 0x34, 0x6B, 0x6A, 0x69, 0x78, 0x73, 0x55, 0x33, 0x2B, 0x77, 0x59, 0x51, 0x2B, 0x6E, 0x56, 0x5A, 0x5A, 0x6A, 0x46, 0x48, ++ 0x4B, 0x64, 0x70, 0x32, 0x6D, 0x68, 0x7A, 0x70, 0x67, 0x71, 0x37, 0x76, 0x6D, 0x72, 0x6C, 0x52, 0x39, 0x34, 0x67, 0x6A, 0x6D, 0x6D, 0x6D, 0x56, 0x0A, 0x59, 0x6A, 0x7A, 0x6C, 0x56, 0x59, 0x41, 0x32, 0x31, 0x31, 0x51, 0x43, 0x2F, 0x2F, 0x47, ++ 0x35, 0x58, 0x63, 0x37, 0x55, 0x49, 0x32, 0x2F, 0x59, 0x52, 0x59, 0x52, 0x4B, 0x57, 0x32, 0x58, 0x76, 0x69, 0x51, 0x7A, 0x64, 0x46, 0x4B, 0x63, 0x67, 0x79, 0x78, 0x69, 0x6C, 0x4A, 0x62, 0x51, 0x4E, 0x2B, 0x51, 0x48, 0x77, 0x6F, 0x74, 0x4C, ++ 0x30, 0x41, 0x4D, 0x68, 0x30, 0x6A, 0x71, 0x45, 0x71, 0x53, 0x49, 0x35, 0x6C, 0x32, 0x78, 0x50, 0x45, 0x34, 0x69, 0x55, 0x58, 0x0A, 0x66, 0x65, 0x75, 0x2B, 0x68, 0x31, 0x73, 0x58, 0x49, 0x46, 0x52, 0x52, 0x6B, 0x30, 0x70, 0x54, 0x41, 0x77, ++ 0x76, 0x73, 0x58, 0x63, 0x6F, 0x7A, 0x37, 0x57, 0x4C, 0x39, 0x52, 0x63, 0x63, 0x76, 0x57, 0x39, 0x78, 0x59, 0x6F, 0x49, 0x41, 0x35, 0x35, 0x76, 0x72, 0x58, 0x2F, 0x68, 0x4D, 0x55, 0x70, 0x75, 0x30, 0x39, 0x6C, 0x45, 0x70, 0x43, 0x64, 0x4E, ++ 0x54, 0x44, 0x64, 0x31, 0x6C, 0x7A, 0x7A, 0x59, 0x39, 0x47, 0x76, 0x6C, 0x55, 0x34, 0x37, 0x2F, 0x72, 0x6F, 0x0A, 0x6B, 0x54, 0x4C, 0x71, 0x6C, 0x31, 0x67, 0x45, 0x49, 0x74, 0x34, 0x34, 0x77, 0x38, 0x79, 0x38, 0x62, 0x63, 0x6B, 0x7A, 0x4F, ++ 0x6D, 0x6F, 0x4B, 0x61, 0x54, 0x2B, 0x67, 0x79, 0x4F, 0x70, 0x79, 0x6A, 0x34, 0x78, 0x6A, 0x68, 0x69, 0x4F, 0x39, 0x62, 0x54, 0x79, 0x57, 0x6E, 0x70, 0x58, 0x67, 0x53, 0x55, 0x79, 0x71, 0x6F, 0x72, 0x6B, 0x71, 0x47, 0x35, 0x77, 0x32, 0x67, ++ 0x58, 0x6A, 0x74, 0x77, 0x2B, 0x68, 0x47, 0x34, 0x69, 0x5A, 0x5A, 0x52, 0x48, 0x55, 0x65, 0x0A, 0x32, 0x58, 0x57, 0x4A, 0x55, 0x63, 0x30, 0x51, 0x68, 0x4A, 0x31, 0x68, 0x59, 0x4D, 0x74, 0x64, 0x2B, 0x5A, 0x63, 0x69, 0x54, 0x59, 0x36, 0x59, ++ 0x35, 0x75, 0x4E, 0x2F, 0x39, 0x6C, 0x75, 0x37, 0x72, 0x73, 0x33, 0x4B, 0x53, 0x6F, 0x46, 0x72, 0x58, 0x67, 0x76, 0x7A, 0x55, 0x65, 0x46, 0x30, 0x4B, 0x2B, 0x6C, 0x2B, 0x4A, 0x36, 0x66, 0x5A, 0x6D, 0x55, 0x6C, 0x4F, 0x2B, 0x4B, 0x57, 0x41, ++ 0x32, 0x79, 0x55, 0x50, 0x48, 0x47, 0x4E, 0x69, 0x69, 0x73, 0x6B, 0x7A, 0x0A, 0x5A, 0x32, 0x73, 0x38, 0x45, 0x49, 0x50, 0x47, 0x72, 0x64, 0x36, 0x6F, 0x7A, 0x52, 0x61, 0x4F, 0x6A, 0x66, 0x41, 0x48, 0x4E, 0x33, 0x47, 0x66, 0x38, 0x71, 0x76, ++ 0x38, 0x51, 0x66, 0x58, 0x42, 0x69, 0x2B, 0x77, 0x41, 0x4E, 0x31, 0x30, 0x4A, 0x35, 0x55, 0x36, 0x41, 0x37, 0x2F, 0x71, 0x78, 0x58, 0x44, 0x67, 0x47, 0x70, 0x52, 0x74, 0x4B, 0x34, 0x64, 0x77, 0x34, 0x4C, 0x54, 0x7A, 0x63, 0x71, 0x78, 0x2B, ++ 0x51, 0x47, 0x74, 0x56, 0x4B, 0x6E, 0x4F, 0x37, 0x52, 0x0A, 0x63, 0x47, 0x7A, 0x4D, 0x37, 0x76, 0x52, 0x58, 0x2B, 0x42, 0x69, 0x36, 0x68, 0x47, 0x36, 0x48, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, ++ 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x49, 0x64, 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x20, 0x53, 0x65, 0x63, 0x74, 0x6F, 0x72, 0x20, 0x52, 0x6F, ++ 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x5A, 0x6A, 0x43, 0x43, 0x41, 0x30, ++ 0x36, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x43, 0x67, 0x46, 0x43, 0x67, 0x41, 0x41, 0x41, 0x41, 0x55, 0x55, 0x6A, 0x7A, 0x30, 0x5A, 0x38, 0x41, 0x41, 0x41, 0x41, 0x41, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, ++ 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x42, 0x4E, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0A, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x53, 0x4D, 0x42, 0x41, 0x47, 0x41, ++ 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x4A, 0x53, 0x57, 0x52, 0x6C, 0x62, 0x6C, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x4D, 0x53, 0x6F, 0x77, 0x4B, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x79, 0x46, 0x4A, 0x5A, 0x47, 0x56, 0x75, 0x56, ++ 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x67, 0x55, 0x48, 0x56, 0x69, 0x62, 0x47, 0x6C, 0x6A, 0x49, 0x46, 0x4E, 0x6C, 0x59, 0x33, 0x52, 0x76, 0x0A, 0x63, 0x69, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x49, 0x44, 0x45, 0x77, ++ 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x54, 0x51, 0x77, 0x4D, 0x54, 0x45, 0x32, 0x4D, 0x54, 0x63, 0x31, 0x4D, 0x7A, 0x4D, 0x79, 0x57, 0x68, 0x63, 0x4E, 0x4D, 0x7A, 0x51, 0x77, 0x4D, 0x54, 0x45, 0x32, 0x4D, 0x54, 0x63, 0x31, 0x4D, 0x7A, 0x4D, 0x79, ++ 0x57, 0x6A, 0x42, 0x4E, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, 0x0A, 0x55, 0x7A, 0x45, 0x53, 0x4D, 0x42, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x4A, 0x53, 0x57, 0x52, ++ 0x6C, 0x62, 0x6C, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x4D, 0x53, 0x6F, 0x77, 0x4B, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x79, 0x46, 0x4A, 0x5A, 0x47, 0x56, 0x75, 0x56, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x67, 0x55, 0x48, 0x56, ++ 0x69, 0x62, 0x47, 0x6C, 0x6A, 0x49, 0x46, 0x4E, 0x6C, 0x59, 0x33, 0x52, 0x76, 0x63, 0x69, 0x42, 0x53, 0x0A, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x49, 0x44, 0x45, 0x77, 0x67, 0x67, 0x49, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, ++ 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x43, 0x32, 0x49, 0x70, 0x54, 0x38, 0x70, 0x45, ++ 0x69, 0x76, 0x36, 0x45, 0x64, 0x72, 0x43, 0x76, 0x73, 0x6E, 0x64, 0x75, 0x54, 0x79, 0x0A, 0x50, 0x34, 0x6F, 0x37, 0x65, 0x6B, 0x6F, 0x73, 0x4D, 0x53, 0x71, 0x4D, 0x6A, 0x62, 0x43, 0x70, 0x77, 0x7A, 0x46, 0x72, 0x71, 0x48, 0x64, 0x32, 0x68, ++ 0x43, 0x61, 0x32, 0x72, 0x49, 0x46, 0x43, 0x44, 0x51, 0x6A, 0x72, 0x56, 0x56, 0x69, 0x37, 0x65, 0x76, 0x69, 0x38, 0x5A, 0x58, 0x33, 0x79, 0x6F, 0x47, 0x32, 0x4C, 0x71, 0x45, 0x66, 0x70, 0x59, 0x6E, 0x59, 0x65, 0x45, 0x65, 0x34, 0x49, 0x46, ++ 0x4E, 0x47, 0x79, 0x52, 0x42, 0x62, 0x30, 0x36, 0x74, 0x44, 0x36, 0x0A, 0x48, 0x69, 0x39, 0x65, 0x32, 0x38, 0x74, 0x7A, 0x51, 0x61, 0x36, 0x38, 0x41, 0x4C, 0x42, 0x4B, 0x4B, 0x30, 0x43, 0x79, 0x72, 0x4F, 0x45, 0x37, 0x53, 0x38, 0x49, 0x74, ++ 0x6E, 0x65, 0x53, 0x68, 0x6D, 0x2B, 0x77, 0x61, 0x4F, 0x68, 0x37, 0x77, 0x43, 0x4C, 0x50, 0x51, 0x35, 0x43, 0x51, 0x31, 0x42, 0x35, 0x2B, 0x63, 0x74, 0x4D, 0x6C, 0x53, 0x62, 0x64, 0x73, 0x48, 0x79, 0x6F, 0x2B, 0x31, 0x57, 0x2F, 0x43, 0x44, ++ 0x38, 0x30, 0x2F, 0x48, 0x4C, 0x61, 0x58, 0x49, 0x0A, 0x72, 0x63, 0x75, 0x56, 0x49, 0x4B, 0x51, 0x78, 0x4B, 0x46, 0x64, 0x59, 0x57, 0x75, 0x53, 0x4E, 0x47, 0x35, 0x71, 0x72, 0x6E, 0x67, 0x30, 0x4D, 0x38, 0x67, 0x6F, 0x7A, 0x4F, 0x53, 0x49, ++ 0x35, 0x43, 0x70, 0x63, 0x75, 0x38, 0x31, 0x4E, 0x33, 0x75, 0x55, 0x52, 0x46, 0x2F, 0x59, 0x54, 0x4C, 0x4E, 0x69, 0x43, 0x42, 0x57, 0x53, 0x32, 0x61, 0x62, 0x32, 0x31, 0x49, 0x53, 0x47, 0x48, 0x4B, 0x54, 0x4E, 0x39, 0x54, 0x30, 0x61, 0x39, ++ 0x53, 0x76, 0x45, 0x53, 0x66, 0x0A, 0x71, 0x79, 0x39, 0x72, 0x67, 0x33, 0x4C, 0x76, 0x64, 0x59, 0x44, 0x61, 0x42, 0x6A, 0x4D, 0x62, 0x58, 0x63, 0x6A, 0x61, 0x59, 0x38, 0x5A, 0x4E, 0x7A, 0x61, 0x78, 0x6D, 0x4D, 0x63, 0x33, 0x52, 0x33, 0x6A, ++ 0x36, 0x48, 0x45, 0x44, 0x62, 0x68, 0x75, 0x61, 0x52, 0x36, 0x37, 0x32, 0x42, 0x51, 0x73, 0x73, 0x76, 0x4B, 0x70, 0x6C, 0x62, 0x67, 0x4E, 0x36, 0x2B, 0x72, 0x4E, 0x42, 0x4D, 0x35, 0x4A, 0x65, 0x67, 0x35, 0x5A, 0x75, 0x53, 0x59, 0x65, 0x71, ++ 0x6F, 0x53, 0x0A, 0x6D, 0x4A, 0x78, 0x5A, 0x5A, 0x6F, 0x59, 0x2B, 0x72, 0x66, 0x47, 0x77, 0x79, 0x6A, 0x34, 0x47, 0x44, 0x33, 0x76, 0x77, 0x45, 0x55, 0x73, 0x33, 0x6F, 0x45, 0x52, 0x74, 0x65, 0x38, 0x75, 0x6F, 0x6A, 0x48, 0x48, 0x30, 0x31, ++ 0x62, 0x57, 0x52, 0x4E, 0x73, 0x7A, 0x77, 0x46, 0x63, 0x59, 0x72, 0x33, 0x6C, 0x45, 0x58, 0x73, 0x5A, 0x64, 0x4D, 0x55, 0x44, 0x32, 0x78, 0x6C, 0x56, 0x6C, 0x38, 0x42, 0x58, 0x30, 0x74, 0x49, 0x64, 0x55, 0x41, 0x76, 0x77, 0x46, 0x6E, 0x0A, ++ 0x6F, 0x6C, 0x35, 0x37, 0x70, 0x6C, 0x7A, 0x79, 0x39, 0x79, 0x4C, 0x78, 0x6B, 0x41, 0x32, 0x54, 0x32, 0x36, 0x70, 0x45, 0x55, 0x57, 0x62, 0x4D, 0x66, 0x58, 0x59, 0x44, 0x36, 0x32, 0x71, 0x6F, 0x4B, 0x6A, 0x67, 0x5A, 0x6C, 0x33, 0x59, 0x4E, ++ 0x61, 0x34, 0x70, 0x68, 0x2B, 0x62, 0x7A, 0x32, 0x37, 0x6E, 0x62, 0x39, 0x63, 0x43, 0x76, 0x64, 0x4B, 0x54, 0x7A, 0x34, 0x43, 0x68, 0x35, 0x62, 0x51, 0x68, 0x79, 0x4C, 0x56, 0x69, 0x39, 0x56, 0x47, 0x78, 0x79, 0x68, 0x0A, 0x4C, 0x72, 0x58, ++ 0x48, 0x46, 0x75, 0x62, 0x34, 0x71, 0x6A, 0x79, 0x53, 0x6A, 0x6D, 0x6D, 0x32, 0x41, 0x63, 0x47, 0x31, 0x68, 0x70, 0x32, 0x4A, 0x44, 0x77, 0x73, 0x34, 0x6C, 0x46, 0x54, 0x6F, 0x36, 0x74, 0x79, 0x65, 0x50, 0x53, 0x57, 0x38, 0x55, 0x79, 0x62, ++ 0x74, 0x31, 0x61, 0x73, 0x35, 0x71, 0x73, 0x56, 0x41, 0x54, 0x46, 0x53, 0x72, 0x73, 0x72, 0x54, 0x5A, 0x32, 0x66, 0x6A, 0x58, 0x63, 0x74, 0x73, 0x63, 0x76, 0x47, 0x32, 0x39, 0x5A, 0x56, 0x2F, 0x76, 0x0A, 0x69, 0x44, 0x55, 0x71, 0x5A, 0x69, ++ 0x2F, 0x75, 0x39, 0x72, 0x4E, 0x6C, 0x38, 0x44, 0x4F, 0x4E, 0x66, 0x4A, 0x68, 0x42, 0x61, 0x55, 0x59, 0x50, 0x51, 0x78, 0x78, 0x70, 0x2B, 0x70, 0x75, 0x31, 0x30, 0x47, 0x46, 0x71, 0x7A, 0x63, 0x70, 0x4C, 0x32, 0x55, 0x79, 0x51, 0x52, 0x71, ++ 0x73, 0x56, 0x57, 0x61, 0x46, 0x48, 0x56, 0x43, 0x6B, 0x75, 0x67, 0x79, 0x68, 0x66, 0x48, 0x4D, 0x4B, 0x69, 0x71, 0x33, 0x49, 0x58, 0x41, 0x41, 0x61, 0x4F, 0x52, 0x65, 0x79, 0x4C, 0x0A, 0x34, 0x6A, 0x4D, 0x39, 0x66, 0x39, 0x6F, 0x5A, 0x52, ++ 0x4F, 0x52, 0x69, 0x63, 0x73, 0x50, 0x66, 0x49, 0x73, 0x62, 0x79, 0x56, 0x74, 0x54, 0x64, 0x58, 0x35, 0x56, 0x79, 0x37, 0x57, 0x31, 0x66, 0x39, 0x30, 0x67, 0x44, 0x57, 0x2F, 0x33, 0x46, 0x4B, 0x71, 0x44, 0x32, 0x63, 0x79, 0x4F, 0x45, 0x45, ++ 0x42, 0x73, 0x42, 0x35, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6F, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x0A, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x51, 0x59, 0x77, ++ 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x34, 0x33, 0x48, 0x67, ++ 0x6E, 0x74, 0x69, 0x6E, 0x51, 0x74, 0x6E, 0x62, 0x63, 0x5A, 0x46, 0x72, 0x6C, 0x4A, 0x50, 0x72, 0x77, 0x36, 0x50, 0x52, 0x46, 0x4B, 0x4D, 0x77, 0x0A, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, ++ 0x4C, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x42, 0x41, 0x45, 0x66, 0x36, 0x33, 0x51, 0x71, 0x77, 0x45, 0x5A, 0x45, 0x34, 0x72, 0x55, 0x31, 0x64, 0x39, 0x2B, 0x55, 0x4F, 0x6C, 0x31, 0x51, 0x5A, 0x67, 0x6B, 0x69, 0x48, 0x56, 0x49, 0x79, ++ 0x71, 0x5A, 0x4A, 0x6E, 0x59, 0x57, 0x76, 0x36, 0x49, 0x41, 0x63, 0x56, 0x59, 0x70, 0x5A, 0x6D, 0x78, 0x49, 0x31, 0x51, 0x6A, 0x0A, 0x74, 0x32, 0x6F, 0x64, 0x49, 0x46, 0x66, 0x6C, 0x41, 0x57, 0x4A, 0x42, 0x46, 0x39, 0x4D, 0x4A, 0x32, 0x33, ++ 0x58, 0x4C, 0x62, 0x6C, 0x53, 0x51, 0x64, 0x66, 0x34, 0x61, 0x6E, 0x34, 0x45, 0x4B, 0x77, 0x74, 0x33, 0x58, 0x39, 0x77, 0x6E, 0x51, 0x57, 0x33, 0x49, 0x56, 0x35, 0x42, 0x34, 0x4A, 0x61, 0x6A, 0x30, 0x7A, 0x38, 0x79, 0x47, 0x61, 0x35, 0x68, ++ 0x56, 0x2B, 0x72, 0x56, 0x48, 0x56, 0x44, 0x52, 0x44, 0x74, 0x66, 0x55, 0x4C, 0x41, 0x6A, 0x2B, 0x37, 0x41, 0x0A, 0x6D, 0x67, 0x6A, 0x56, 0x51, 0x64, 0x5A, 0x63, 0x44, 0x69, 0x46, 0x70, 0x62, 0x6F, 0x42, 0x68, 0x44, 0x68, 0x58, 0x41, 0x75, ++ 0x4D, 0x2F, 0x46, 0x53, 0x52, 0x4A, 0x53, 0x7A, 0x4C, 0x34, 0x36, 0x7A, 0x4E, 0x51, 0x75, 0x4F, 0x41, 0x58, 0x65, 0x4E, 0x66, 0x30, 0x66, 0x62, 0x37, 0x69, 0x41, 0x61, 0x4A, 0x67, 0x39, 0x54, 0x61, 0x44, 0x4B, 0x51, 0x47, 0x58, 0x53, 0x63, ++ 0x33, 0x7A, 0x31, 0x69, 0x39, 0x6B, 0x4B, 0x6C, 0x54, 0x2F, 0x59, 0x50, 0x79, 0x4E, 0x74, 0x0A, 0x47, 0x74, 0x45, 0x71, 0x4A, 0x42, 0x6E, 0x5A, 0x68, 0x62, 0x4D, 0x58, 0x37, 0x33, 0x68, 0x75, 0x71, 0x56, 0x6A, 0x52, 0x49, 0x39, 0x50, 0x48, ++ 0x45, 0x2B, 0x31, 0x79, 0x4A, 0x58, 0x39, 0x64, 0x73, 0x58, 0x4E, 0x77, 0x30, 0x48, 0x38, 0x47, 0x6C, 0x77, 0x6D, 0x45, 0x4B, 0x59, 0x42, 0x68, 0x48, 0x66, 0x70, 0x65, 0x2F, 0x33, 0x4F, 0x73, 0x6F, 0x4F, 0x4F, 0x4A, 0x75, 0x42, 0x78, 0x78, ++ 0x46, 0x63, 0x62, 0x65, 0x4D, 0x58, 0x38, 0x53, 0x33, 0x4F, 0x46, 0x74, 0x0A, 0x6D, 0x36, 0x2F, 0x6E, 0x36, 0x4A, 0x39, 0x31, 0x65, 0x45, 0x79, 0x72, 0x52, 0x6A, 0x75, 0x61, 0x7A, 0x72, 0x38, 0x46, 0x47, 0x46, 0x31, 0x4E, 0x46, 0x54, 0x77, ++ 0x57, 0x6D, 0x68, 0x6C, 0x51, 0x42, 0x4A, 0x71, 0x79, 0x6D, 0x6D, 0x39, 0x6C, 0x69, 0x31, 0x4A, 0x66, 0x50, 0x46, 0x67, 0x45, 0x4B, 0x43, 0x58, 0x41, 0x5A, 0x6D, 0x45, 0x78, 0x66, 0x72, 0x6E, 0x67, 0x64, 0x62, 0x6B, 0x61, 0x71, 0x49, 0x48, ++ 0x57, 0x63, 0x68, 0x65, 0x7A, 0x78, 0x51, 0x4D, 0x78, 0x0A, 0x4E, 0x52, 0x46, 0x34, 0x65, 0x4B, 0x4C, 0x67, 0x36, 0x54, 0x43, 0x4D, 0x66, 0x34, 0x44, 0x66, 0x57, 0x4E, 0x38, 0x38, 0x75, 0x69, 0x65, 0x57, 0x34, 0x6F, 0x41, 0x30, 0x62, 0x65, ++ 0x4F, 0x59, 0x30, 0x32, 0x51, 0x6E, 0x72, 0x45, 0x68, 0x2B, 0x4B, 0x48, 0x64, 0x63, 0x78, 0x69, 0x56, 0x68, 0x4A, 0x66, 0x69, 0x46, 0x44, 0x47, 0x58, 0x36, 0x78, 0x44, 0x49, 0x76, 0x70, 0x5A, 0x67, 0x46, 0x35, 0x50, 0x67, 0x4C, 0x5A, 0x78, ++ 0x59, 0x57, 0x78, 0x6F, 0x4B, 0x34, 0x0A, 0x4D, 0x68, 0x6E, 0x35, 0x2B, 0x62, 0x6C, 0x35, 0x33, 0x42, 0x2F, 0x4E, 0x36, 0x36, 0x2B, 0x72, 0x44, 0x74, 0x30, 0x62, 0x32, 0x30, 0x58, 0x6B, 0x65, 0x75, 0x63, 0x43, 0x34, 0x70, 0x56, 0x64, 0x2F, ++ 0x47, 0x6E, 0x77, 0x55, 0x32, 0x6C, 0x68, 0x6C, 0x58, 0x56, 0x35, 0x43, 0x31, 0x35, 0x56, 0x35, 0x6A, 0x67, 0x63, 0x6C, 0x4B, 0x6C, 0x5A, 0x4D, 0x35, 0x37, 0x49, 0x63, 0x58, 0x52, 0x35, 0x66, 0x31, 0x47, 0x4A, 0x74, 0x73, 0x68, 0x71, 0x75, ++ 0x44, 0x44, 0x49, 0x0A, 0x61, 0x6A, 0x6A, 0x44, 0x62, 0x70, 0x37, 0x68, 0x4E, 0x78, 0x62, 0x71, 0x42, 0x57, 0x4A, 0x4D, 0x57, 0x78, 0x4A, 0x48, 0x37, 0x61, 0x65, 0x30, 0x73, 0x31, 0x68, 0x57, 0x78, 0x30, 0x6E, 0x7A, 0x66, 0x78, 0x4A, 0x6F, ++ 0x43, 0x54, 0x46, 0x78, 0x38, 0x47, 0x33, 0x34, 0x54, 0x6B, 0x66, 0x37, 0x31, 0x6F, 0x58, 0x75, 0x78, 0x56, 0x68, 0x41, 0x47, 0x61, 0x51, 0x64, 0x70, 0x2F, 0x6C, 0x4C, 0x51, 0x7A, 0x66, 0x63, 0x61, 0x46, 0x70, 0x50, 0x7A, 0x2B, 0x76, 0x43, ++ 0x0A, 0x5A, 0x48, 0x54, 0x65, 0x74, 0x42, 0x58, 0x5A, 0x39, 0x46, 0x52, 0x55, 0x47, 0x69, 0x38, 0x63, 0x31, 0x35, 0x64, 0x78, 0x56, 0x4A, 0x43, 0x4F, 0x32, 0x53, 0x43, 0x64, 0x55, 0x79, 0x74, 0x2F, 0x71, 0x34, 0x2F, 0x69, 0x36, 0x6A, 0x43, ++ 0x38, 0x55, 0x44, 0x66, 0x76, 0x38, 0x55, 0x65, 0x31, 0x66, 0x58, 0x77, 0x73, 0x42, 0x4F, 0x78, 0x6F, 0x6E, 0x62, 0x52, 0x4A, 0x52, 0x42, 0x44, 0x30, 0x63, 0x6B, 0x73, 0x63, 0x5A, 0x4F, 0x66, 0x38, 0x35, 0x6D, 0x75, 0x51, 0x0A, 0x33, 0x57, ++ 0x6C, 0x39, 0x61, 0x66, 0x30, 0x41, 0x56, 0x71, 0x57, 0x33, 0x72, 0x4C, 0x61, 0x74, 0x74, 0x38, 0x6F, 0x2B, 0x41, 0x65, 0x2B, 0x63, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, ++ 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, ++ 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x47, 0x32, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x45, 0x50, 0x6A, 0x43, 0x43, 0x41, 0x79, 0x61, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x45, 0x53, 0x6C, 0x4F, 0x4D, 0x4B, 0x44, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, ++ 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x43, 0x42, 0x76, 0x6A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x56, 0x56, 0x4D, 0x78, 0x46, 0x6A, 0x41, 0x55, 0x42, 0x67, 0x4E, 0x56, 0x0A, 0x42, ++ 0x41, 0x6F, 0x54, 0x44, 0x55, 0x56, 0x75, 0x64, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x73, 0x49, 0x45, 0x6C, 0x75, 0x59, 0x79, 0x34, 0x78, 0x4B, 0x44, 0x41, 0x6D, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x73, 0x54, 0x48, 0x31, 0x4E, 0x6C, 0x5A, ++ 0x53, 0x42, 0x33, 0x64, 0x33, 0x63, 0x75, 0x5A, 0x57, 0x35, 0x30, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x43, 0x35, 0x75, 0x5A, 0x58, 0x51, 0x76, 0x62, 0x47, 0x56, 0x6E, 0x59, 0x57, 0x77, 0x74, 0x64, 0x47, 0x56, 0x79, 0x0A, 0x62, 0x58, 0x4D, 0x78, ++ 0x4F, 0x54, 0x41, 0x33, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x73, 0x54, 0x4D, 0x43, 0x68, 0x6A, 0x4B, 0x53, 0x41, 0x79, 0x4D, 0x44, 0x41, 0x35, 0x49, 0x45, 0x56, 0x75, 0x64, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x73, 0x49, 0x45, 0x6C, 0x75, ++ 0x59, 0x79, 0x34, 0x67, 0x4C, 0x53, 0x42, 0x6D, 0x62, 0x33, 0x49, 0x67, 0x59, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x70, 0x6C, 0x5A, 0x43, 0x42, 0x31, 0x63, 0x32, 0x55, 0x67, 0x0A, 0x62, 0x32, 0x35, 0x73, 0x65, 0x54, 0x45, ++ 0x79, 0x4D, 0x44, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x70, 0x52, 0x57, 0x35, 0x30, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x43, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x6C, 0x63, 0x6E, 0x52, 0x70, 0x5A, 0x6D, 0x6C, ++ 0x6A, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52, 0x35, 0x49, 0x43, 0x30, 0x67, 0x52, 0x7A, 0x49, 0x77, 0x0A, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x44, 0x6B, 0x77, 0x4E, 0x7A, ++ 0x41, 0x33, 0x4D, 0x54, 0x63, 0x79, 0x4E, 0x54, 0x55, 0x30, 0x57, 0x68, 0x63, 0x4E, 0x4D, 0x7A, 0x41, 0x78, 0x4D, 0x6A, 0x41, 0x33, 0x4D, 0x54, 0x63, 0x31, 0x4E, 0x54, 0x55, 0x30, 0x57, 0x6A, 0x43, 0x42, 0x76, 0x6A, 0x45, 0x4C, 0x4D, 0x41, ++ 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x56, 0x56, 0x4D, 0x78, 0x46, 0x6A, 0x41, 0x55, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x0A, 0x44, 0x55, 0x56, 0x75, 0x64, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x73, 0x49, ++ 0x45, 0x6C, 0x75, 0x59, 0x79, 0x34, 0x78, 0x4B, 0x44, 0x41, 0x6D, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x73, 0x54, 0x48, 0x31, 0x4E, 0x6C, 0x5A, 0x53, 0x42, 0x33, 0x64, 0x33, 0x63, 0x75, 0x5A, 0x57, 0x35, 0x30, 0x63, 0x6E, 0x56, 0x7A, 0x64, ++ 0x43, 0x35, 0x75, 0x5A, 0x58, 0x51, 0x76, 0x62, 0x47, 0x56, 0x6E, 0x59, 0x57, 0x77, 0x74, 0x64, 0x47, 0x56, 0x79, 0x62, 0x58, 0x4D, 0x78, 0x0A, 0x4F, 0x54, 0x41, 0x33, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x73, 0x54, 0x4D, 0x43, 0x68, 0x6A, ++ 0x4B, 0x53, 0x41, 0x79, 0x4D, 0x44, 0x41, 0x35, 0x49, 0x45, 0x56, 0x75, 0x64, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x73, 0x49, 0x45, 0x6C, 0x75, 0x59, 0x79, 0x34, 0x67, 0x4C, 0x53, 0x42, 0x6D, 0x62, 0x33, 0x49, 0x67, 0x59, 0x58, 0x56, 0x30, ++ 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x70, 0x6C, 0x5A, 0x43, 0x42, 0x31, 0x63, 0x32, 0x55, 0x67, 0x62, 0x32, 0x35, 0x73, 0x0A, 0x65, 0x54, 0x45, 0x79, 0x4D, 0x44, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x70, 0x52, 0x57, 0x35, ++ 0x30, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x43, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x6C, 0x63, 0x6E, 0x52, 0x70, 0x5A, 0x6D, 0x6C, 0x6A, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, ++ 0x79, 0x61, 0x58, 0x52, 0x35, 0x49, 0x43, 0x30, 0x67, 0x52, 0x7A, 0x49, 0x77, 0x67, 0x67, 0x45, 0x69, 0x0A, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, ++ 0x49, 0x42, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x45, 0x4B, 0x41, 0x6F, 0x49, 0x42, 0x41, 0x51, 0x43, 0x36, 0x68, 0x4C, 0x5A, 0x79, 0x32, 0x35, 0x34, 0x4D, 0x61, 0x2B, 0x4B, 0x5A, 0x36, 0x54, 0x41, 0x42, 0x70, 0x33, 0x62, 0x71, 0x4D, 0x72, ++ 0x69, 0x56, 0x51, 0x52, 0x72, 0x4A, 0x32, 0x6D, 0x46, 0x4F, 0x57, 0x48, 0x4C, 0x50, 0x0A, 0x2F, 0x76, 0x61, 0x43, 0x65, 0x62, 0x39, 0x7A, 0x59, 0x51, 0x59, 0x4B, 0x70, 0x53, 0x66, 0x59, 0x73, 0x31, 0x2F, 0x54, 0x52, 0x55, 0x34, 0x63, 0x63, ++ 0x74, 0x5A, 0x4F, 0x4D, 0x76, 0x4A, 0x79, 0x69, 0x67, 0x2F, 0x33, 0x67, 0x78, 0x6E, 0x51, 0x61, 0x6F, 0x43, 0x41, 0x41, 0x45, 0x55, 0x65, 0x73, 0x4D, 0x66, 0x6E, 0x6D, 0x72, 0x38, 0x53, 0x56, 0x79, 0x63, 0x63, 0x6F, 0x32, 0x67, 0x76, 0x43, ++ 0x6F, 0x65, 0x39, 0x61, 0x6D, 0x73, 0x4F, 0x58, 0x6D, 0x58, 0x7A, 0x0A, 0x48, 0x48, 0x66, 0x56, 0x31, 0x49, 0x57, 0x4E, 0x63, 0x43, 0x47, 0x30, 0x73, 0x7A, 0x4C, 0x6E, 0x69, 0x36, 0x4C, 0x56, 0x68, 0x6A, 0x6B, 0x43, 0x73, 0x62, 0x6A, 0x53, ++ 0x52, 0x38, 0x37, 0x6B, 0x79, 0x55, 0x6E, 0x45, 0x4F, 0x36, 0x66, 0x65, 0x2B, 0x31, 0x52, 0x39, 0x56, 0x37, 0x37, 0x77, 0x36, 0x47, 0x37, 0x43, 0x65, 0x62, 0x49, 0x36, 0x43, 0x31, 0x58, 0x69, 0x55, 0x4A, 0x67, 0x57, 0x4D, 0x68, 0x4E, 0x63, ++ 0x4C, 0x33, 0x68, 0x57, 0x77, 0x63, 0x4B, 0x55, 0x0A, 0x73, 0x2F, 0x4A, 0x61, 0x35, 0x43, 0x65, 0x61, 0x6E, 0x79, 0x54, 0x58, 0x78, 0x75, 0x7A, 0x51, 0x6D, 0x79, 0x57, 0x43, 0x34, 0x38, 0x7A, 0x43, 0x78, 0x45, 0x58, 0x46, 0x6A, 0x4A, 0x64, ++ 0x36, 0x42, 0x6D, 0x73, 0x71, 0x45, 0x5A, 0x2B, 0x70, 0x43, 0x6D, 0x35, 0x49, 0x4F, 0x32, 0x2F, 0x62, 0x31, 0x42, 0x45, 0x5A, 0x51, 0x76, 0x65, 0x50, 0x42, 0x37, 0x2F, 0x31, 0x55, 0x31, 0x2B, 0x63, 0x50, 0x76, 0x51, 0x58, 0x4C, 0x4F, 0x5A, ++ 0x70, 0x72, 0x45, 0x34, 0x79, 0x0A, 0x54, 0x47, 0x4A, 0x33, 0x36, 0x72, 0x66, 0x6F, 0x35, 0x62, 0x73, 0x30, 0x76, 0x42, 0x6D, 0x4C, 0x72, 0x70, 0x78, 0x52, 0x35, 0x37, 0x64, 0x2B, 0x74, 0x56, 0x4F, 0x78, 0x4D, 0x79, 0x4C, 0x6C, 0x62, 0x63, ++ 0x39, 0x77, 0x50, 0x42, 0x72, 0x36, 0x34, 0x70, 0x74, 0x6E, 0x74, 0x6F, 0x50, 0x30, 0x6A, 0x61, 0x57, 0x76, 0x59, 0x6B, 0x78, 0x4E, 0x34, 0x46, 0x69, 0x73, 0x5A, 0x44, 0x51, 0x53, 0x41, 0x2F, 0x69, 0x32, 0x6A, 0x5A, 0x52, 0x6A, 0x4A, 0x4B, ++ 0x52, 0x78, 0x0A, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, 0x51, 0x6A, 0x42, 0x41, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6A, 0x41, 0x50, 0x42, ++ 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x52, 0x71, 0x63, 0x69, 0x5A, 0x36, 0x0A, ++ 0x30, 0x42, 0x37, 0x76, 0x66, 0x65, 0x63, 0x37, 0x61, 0x56, 0x48, 0x55, 0x62, 0x49, 0x32, 0x66, 0x6B, 0x42, 0x4A, 0x6D, 0x71, 0x7A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, ++ 0x41, 0x41, 0x4F, 0x43, 0x41, 0x51, 0x45, 0x41, 0x65, 0x5A, 0x38, 0x64, 0x6C, 0x73, 0x61, 0x32, 0x65, 0x54, 0x38, 0x69, 0x6A, 0x59, 0x66, 0x54, 0x68, 0x77, 0x4D, 0x45, 0x59, 0x47, 0x70, 0x72, 0x6D, 0x69, 0x35, 0x5A, 0x0A, 0x69, 0x58, 0x4D, ++ 0x52, 0x72, 0x45, 0x50, 0x52, 0x39, 0x52, 0x50, 0x2F, 0x6A, 0x54, 0x6B, 0x72, 0x77, 0x50, 0x4B, 0x39, 0x54, 0x33, 0x43, 0x4D, 0x71, 0x53, 0x2F, 0x71, 0x46, 0x38, 0x51, 0x4C, 0x56, 0x4A, 0x37, 0x55, 0x47, 0x35, 0x61, 0x59, 0x4D, 0x7A, 0x79, ++ 0x6F, 0x72, 0x57, 0x4B, 0x69, 0x41, 0x48, 0x61, 0x72, 0x57, 0x57, 0x6C, 0x75, 0x42, 0x68, 0x31, 0x2B, 0x78, 0x4C, 0x6C, 0x45, 0x6A, 0x5A, 0x69, 0x76, 0x45, 0x74, 0x52, 0x68, 0x32, 0x77, 0x6F, 0x5A, 0x0A, 0x52, 0x6B, 0x66, 0x7A, 0x36, 0x2F, ++ 0x64, 0x6A, 0x77, 0x55, 0x41, 0x46, 0x51, 0x4B, 0x58, 0x53, 0x74, 0x2F, 0x53, 0x31, 0x6D, 0x6A, 0x61, 0x2F, 0x71, 0x59, 0x68, 0x32, 0x69, 0x41, 0x52, 0x56, 0x42, 0x43, 0x75, 0x63, 0x68, 0x33, 0x38, 0x61, 0x4E, 0x7A, 0x78, 0x2B, 0x4C, 0x61, ++ 0x55, 0x61, 0x32, 0x4E, 0x53, 0x4A, 0x58, 0x73, 0x71, 0x39, 0x72, 0x44, 0x31, 0x73, 0x32, 0x47, 0x32, 0x76, 0x31, 0x66, 0x4E, 0x32, 0x44, 0x38, 0x30, 0x37, 0x69, 0x44, 0x67, 0x69, 0x0A, 0x6E, 0x57, 0x79, 0x54, 0x6D, 0x73, 0x51, 0x39, 0x76, ++ 0x34, 0x49, 0x62, 0x5A, 0x54, 0x2B, 0x6D, 0x44, 0x31, 0x32, 0x71, 0x2F, 0x4F, 0x57, 0x79, 0x46, 0x63, 0x71, 0x31, 0x72, 0x63, 0x61, 0x38, 0x50, 0x64, 0x43, 0x45, 0x36, 0x4F, 0x6F, 0x47, 0x63, 0x72, 0x42, 0x4E, 0x4F, 0x54, 0x4A, 0x34, 0x76, ++ 0x7A, 0x34, 0x52, 0x6E, 0x41, 0x75, 0x6B, 0x6E, 0x5A, 0x6F, 0x68, 0x38, 0x2F, 0x43, 0x62, 0x43, 0x7A, 0x42, 0x34, 0x32, 0x38, 0x48, 0x63, 0x68, 0x30, 0x50, 0x2B, 0x0A, 0x76, 0x47, 0x4F, 0x61, 0x79, 0x73, 0x58, 0x43, 0x48, 0x4D, 0x6E, 0x48, ++ 0x6A, 0x66, 0x38, 0x37, 0x45, 0x6C, 0x67, 0x49, 0x35, 0x72, 0x59, 0x39, 0x37, 0x48, 0x6F, 0x73, 0x54, 0x76, 0x75, 0x44, 0x6C, 0x73, 0x34, 0x4D, 0x50, 0x47, 0x6D, 0x48, 0x56, 0x48, 0x4F, 0x6B, 0x63, 0x38, 0x4B, 0x54, 0x2F, 0x31, 0x45, 0x51, ++ 0x72, 0x42, 0x56, 0x55, 0x41, 0x64, 0x6A, 0x38, 0x42, 0x62, 0x47, 0x4A, 0x6F, 0x58, 0x39, 0x30, 0x67, 0x35, 0x70, 0x4A, 0x31, 0x39, 0x78, 0x4F, 0x0A, 0x65, 0x34, 0x70, 0x49, 0x62, 0x34, 0x74, 0x46, 0x39, 0x67, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, ++ 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, ++ 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x45, 0x43, 0x31, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, ++ 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x2B, 0x54, 0x43, 0x43, 0x41, 0x6F, 0x43, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x4E, 0x41, ++ 0x4B, 0x61, 0x4C, 0x65, 0x53, 0x6B, 0x41, 0x41, 0x41, 0x41, 0x41, 0x55, 0x4E, 0x43, 0x52, 0x2B, 0x54, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x7A, 0x43, 0x42, 0x76, 0x7A, 0x45, 0x4C, 0x4D, ++ 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x56, 0x56, 0x4D, 0x78, 0x0A, 0x46, 0x6A, 0x41, 0x55, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x44, 0x55, 0x56, 0x75, 0x64, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x73, ++ 0x49, 0x45, 0x6C, 0x75, 0x59, 0x79, 0x34, 0x78, 0x4B, 0x44, 0x41, 0x6D, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x73, 0x54, 0x48, 0x31, 0x4E, 0x6C, 0x5A, 0x53, 0x42, 0x33, 0x64, 0x33, 0x63, 0x75, 0x5A, 0x57, 0x35, 0x30, 0x63, 0x6E, 0x56, 0x7A, ++ 0x64, 0x43, 0x35, 0x75, 0x5A, 0x58, 0x51, 0x76, 0x62, 0x47, 0x56, 0x6E, 0x0A, 0x59, 0x57, 0x77, 0x74, 0x64, 0x47, 0x56, 0x79, 0x62, 0x58, 0x4D, 0x78, 0x4F, 0x54, 0x41, 0x33, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x73, 0x54, 0x4D, 0x43, 0x68, ++ 0x6A, 0x4B, 0x53, 0x41, 0x79, 0x4D, 0x44, 0x45, 0x79, 0x49, 0x45, 0x56, 0x75, 0x64, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x73, 0x49, 0x45, 0x6C, 0x75, 0x59, 0x79, 0x34, 0x67, 0x4C, 0x53, 0x42, 0x6D, 0x62, 0x33, 0x49, 0x67, 0x59, 0x58, 0x56, ++ 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x70, 0x6C, 0x0A, 0x5A, 0x43, 0x42, 0x31, 0x63, 0x32, 0x55, 0x67, 0x62, 0x32, 0x35, 0x73, 0x65, 0x54, 0x45, 0x7A, 0x4D, 0x44, 0x45, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x71, 0x52, 0x57, ++ 0x35, 0x30, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x43, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x6C, 0x63, 0x6E, 0x52, 0x70, 0x5A, 0x6D, 0x6C, 0x6A, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, ++ 0x39, 0x79, 0x61, 0x58, 0x52, 0x35, 0x0A, 0x49, 0x43, 0x30, 0x67, 0x52, 0x55, 0x4D, 0x78, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x45, 0x79, 0x4D, 0x54, 0x49, 0x78, 0x4F, 0x44, 0x45, 0x31, 0x4D, 0x6A, 0x55, 0x7A, 0x4E, 0x6C, 0x6F, 0x58, 0x44, ++ 0x54, 0x4D, 0x33, 0x4D, 0x54, 0x49, 0x78, 0x4F, 0x44, 0x45, 0x31, 0x4E, 0x54, 0x55, 0x7A, 0x4E, 0x6C, 0x6F, 0x77, 0x67, 0x62, 0x38, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6C, 0x56, 0x54, 0x4D, ++ 0x52, 0x59, 0x77, 0x0A, 0x46, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x77, 0x31, 0x46, 0x62, 0x6E, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x4C, 0x43, 0x42, 0x4A, 0x62, 0x6D, 0x4D, 0x75, 0x4D, 0x53, 0x67, 0x77, 0x4A, 0x67, 0x59, 0x44, ++ 0x56, 0x51, 0x51, 0x4C, 0x45, 0x78, 0x39, 0x54, 0x5A, 0x57, 0x55, 0x67, 0x64, 0x33, 0x64, 0x33, 0x4C, 0x6D, 0x56, 0x75, 0x64, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x75, 0x62, 0x6D, 0x56, 0x30, 0x4C, 0x32, 0x78, 0x6C, 0x5A, 0x32, 0x46, 0x73, ++ 0x0A, 0x4C, 0x58, 0x52, 0x6C, 0x63, 0x6D, 0x31, 0x7A, 0x4D, 0x54, 0x6B, 0x77, 0x4E, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, 0x45, 0x7A, 0x41, 0x6F, 0x59, 0x79, 0x6B, 0x67, 0x4D, 0x6A, 0x41, 0x78, 0x4D, 0x69, 0x42, 0x46, 0x62, 0x6E, 0x52, ++ 0x79, 0x64, 0x58, 0x4E, 0x30, 0x4C, 0x43, 0x42, 0x4A, 0x62, 0x6D, 0x4D, 0x75, 0x49, 0x43, 0x30, 0x67, 0x5A, 0x6D, 0x39, 0x79, 0x49, 0x47, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6D, 0x6C, 0x36, 0x5A, 0x57, 0x51, 0x67, 0x0A, 0x64, 0x58, ++ 0x4E, 0x6C, 0x49, 0x47, 0x39, 0x75, 0x62, 0x48, 0x6B, 0x78, 0x4D, 0x7A, 0x41, 0x78, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x4B, 0x6B, 0x56, 0x75, 0x64, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, ++ 0x42, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x61, 0x57, 0x5A, 0x70, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x49, 0x45, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6D, 0x6C, 0x30, 0x65, 0x53, 0x41, 0x74, 0x0A, 0x49, 0x45, 0x56, 0x44, 0x4D, ++ 0x54, 0x42, 0x32, 0x4D, 0x42, 0x41, 0x47, 0x42, 0x79, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x41, 0x67, 0x45, 0x47, 0x42, 0x53, 0x75, 0x42, 0x42, 0x41, 0x41, 0x69, 0x41, 0x32, 0x49, 0x41, 0x42, 0x49, 0x51, 0x54, 0x79, 0x64, 0x43, 0x36, 0x62, ++ 0x55, 0x46, 0x37, 0x34, 0x6D, 0x7A, 0x51, 0x36, 0x31, 0x56, 0x66, 0x5A, 0x67, 0x49, 0x61, 0x4A, 0x50, 0x52, 0x62, 0x69, 0x57, 0x6C, 0x48, 0x34, 0x37, 0x6A, 0x43, 0x66, 0x66, 0x48, 0x79, 0x0A, 0x41, 0x73, 0x57, 0x66, 0x6F, 0x50, 0x5A, 0x62, ++ 0x31, 0x59, 0x73, 0x47, 0x47, 0x59, 0x5A, 0x50, 0x55, 0x78, 0x42, 0x74, 0x42, 0x79, 0x51, 0x6E, 0x6F, 0x61, 0x44, 0x34, 0x31, 0x55, 0x63, 0x5A, 0x59, 0x55, 0x78, 0x39, 0x79, 0x70, 0x4D, 0x6E, 0x36, 0x6E, 0x51, 0x4D, 0x37, 0x32, 0x2B, 0x57, ++ 0x43, 0x66, 0x35, 0x6A, 0x37, 0x48, 0x42, 0x64, 0x4E, 0x71, 0x31, 0x6E, 0x64, 0x36, 0x37, 0x4A, 0x6E, 0x58, 0x78, 0x56, 0x52, 0x44, 0x71, 0x69, 0x59, 0x31, 0x45, 0x66, 0x0A, 0x39, 0x65, 0x4E, 0x69, 0x31, 0x4B, 0x6C, 0x48, 0x42, 0x7A, 0x37, ++ 0x4D, 0x49, 0x4B, 0x4E, 0x43, 0x4D, 0x45, 0x41, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, ++ 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x0A, 0x46, 0x4C, 0x64, 0x6A, 0x35, 0x78, 0x72, 0x64, 0x6A, 0x65, 0x6B, 0x49, 0x70, 0x6C, ++ 0x57, 0x44, 0x70, 0x4F, 0x42, 0x71, 0x55, 0x45, 0x46, 0x6C, 0x45, 0x55, 0x4A, 0x4A, 0x4D, 0x41, 0x6F, 0x47, 0x43, 0x43, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x42, 0x41, 0x4D, 0x44, 0x41, 0x32, 0x63, 0x41, 0x4D, 0x47, 0x51, 0x43, 0x4D, 0x47, ++ 0x46, 0x35, 0x32, 0x4F, 0x56, 0x43, 0x52, 0x39, 0x38, 0x63, 0x72, 0x6C, 0x4F, 0x5A, 0x46, 0x37, 0x5A, 0x76, 0x48, 0x48, 0x33, 0x68, 0x0A, 0x76, 0x78, 0x47, 0x55, 0x30, 0x51, 0x4F, 0x49, 0x64, 0x65, 0x53, 0x4E, 0x69, 0x61, 0x53, 0x4B, 0x64, ++ 0x30, 0x62, 0x65, 0x62, 0x57, 0x48, 0x76, 0x41, 0x76, 0x58, 0x37, 0x74, 0x64, 0x2F, 0x4D, 0x2F, 0x6B, 0x37, 0x2F, 0x2F, 0x71, 0x6E, 0x6D, 0x70, 0x77, 0x49, 0x77, 0x57, 0x35, 0x6E, 0x58, 0x68, 0x54, 0x63, 0x47, 0x74, 0x58, 0x73, 0x49, 0x2F, ++ 0x65, 0x73, 0x6E, 0x69, 0x30, 0x71, 0x55, 0x2B, 0x65, 0x48, 0x36, 0x70, 0x34, 0x34, 0x6D, 0x43, 0x4F, 0x68, 0x38, 0x0A, 0x6B, 0x6D, 0x68, 0x74, 0x63, 0x39, 0x68, 0x76, 0x4A, 0x71, 0x77, 0x68, 0x41, 0x72, 0x69, 0x5A, 0x74, 0x79, 0x5A, 0x42, ++ 0x57, 0x79, 0x56, 0x67, 0x72, 0x74, 0x42, 0x49, 0x47, 0x75, 0x34, 0x47, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, ++ 0x43, 0x46, 0x43, 0x41, 0x20, 0x45, 0x56, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, ++ 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x6A, 0x54, 0x43, 0x43, 0x41, 0x33, 0x57, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x45, 0x47, 0x45, 0x72, 0x4D, 0x31, 0x6A, ++ 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x42, 0x57, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x44, 0x54, 0x6A, ++ 0x45, 0x77, 0x4D, 0x43, 0x34, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0A, 0x43, 0x67, 0x77, 0x6E, 0x51, 0x32, 0x68, 0x70, 0x62, 0x6D, 0x45, 0x67, 0x52, 0x6D, 0x6C, 0x75, 0x59, 0x57, 0x35, 0x6A, 0x61, 0x57, 0x46, 0x73, 0x49, 0x45, 0x4E, 0x6C, 0x63, ++ 0x6E, 0x52, 0x70, 0x5A, 0x6D, 0x6C, 0x6A, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52, 0x35, 0x4D, 0x52, 0x55, 0x77, 0x45, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, ++ 0x41, 0x78, 0x44, 0x52, 0x6B, 0x4E, 0x42, 0x0A, 0x49, 0x45, 0x56, 0x57, 0x49, 0x46, 0x4A, 0x50, 0x54, 0x31, 0x51, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x54, 0x49, 0x77, 0x4F, 0x44, 0x41, 0x34, 0x4D, 0x44, 0x4D, 0x77, 0x4E, 0x7A, 0x41, 0x78, ++ 0x57, 0x68, 0x63, 0x4E, 0x4D, 0x6A, 0x6B, 0x78, 0x4D, 0x6A, 0x4D, 0x78, 0x4D, 0x44, 0x4D, 0x77, 0x4E, 0x7A, 0x41, 0x78, 0x57, 0x6A, 0x42, 0x57, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x44, ++ 0x54, 0x6A, 0x45, 0x77, 0x0A, 0x4D, 0x43, 0x34, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x6E, 0x51, 0x32, 0x68, 0x70, 0x62, 0x6D, 0x45, 0x67, 0x52, 0x6D, 0x6C, 0x75, 0x59, 0x57, 0x35, 0x6A, 0x61, 0x57, 0x46, 0x73, 0x49, 0x45, 0x4E, ++ 0x6C, 0x63, 0x6E, 0x52, 0x70, 0x5A, 0x6D, 0x6C, 0x6A, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52, 0x35, 0x4D, 0x52, 0x55, 0x77, 0x45, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, ++ 0x44, 0x0A, 0x44, 0x41, 0x78, 0x44, 0x52, 0x6B, 0x4E, 0x42, 0x49, 0x45, 0x56, 0x57, 0x49, 0x46, 0x4A, 0x50, 0x54, 0x31, 0x51, 0x77, 0x67, 0x67, 0x49, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, ++ 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x44, 0x58, 0x58, 0x57, 0x76, 0x4E, 0x45, 0x44, 0x38, 0x66, 0x42, 0x56, 0x6E, 0x56, 0x0A, 0x42, ++ 0x55, 0x30, 0x33, 0x73, 0x51, 0x37, 0x73, 0x6D, 0x43, 0x75, 0x4F, 0x46, 0x52, 0x33, 0x36, 0x6B, 0x30, 0x73, 0x58, 0x67, 0x69, 0x46, 0x78, 0x45, 0x46, 0x4C, 0x58, 0x55, 0x57, 0x52, 0x77, 0x46, 0x73, 0x4A, 0x56, 0x61, 0x55, 0x32, 0x4F, 0x46, ++ 0x57, 0x32, 0x66, 0x76, 0x77, 0x77, 0x62, 0x77, 0x75, 0x43, 0x6A, 0x5A, 0x39, 0x59, 0x4D, 0x72, 0x4D, 0x38, 0x69, 0x72, 0x71, 0x39, 0x33, 0x56, 0x43, 0x70, 0x4C, 0x54, 0x49, 0x70, 0x54, 0x55, 0x6E, 0x72, 0x44, 0x0A, 0x37, 0x69, 0x37, 0x65, ++ 0x73, 0x33, 0x45, 0x6C, 0x77, 0x65, 0x6C, 0x64, 0x50, 0x65, 0x36, 0x68, 0x4C, 0x36, 0x50, 0x33, 0x4B, 0x6A, 0x7A, 0x4A, 0x49, 0x78, 0x31, 0x71, 0x71, 0x78, 0x32, 0x68, 0x70, 0x2F, 0x48, 0x7A, 0x37, 0x4B, 0x44, 0x56, 0x52, 0x4D, 0x38, 0x56, ++ 0x7A, 0x33, 0x49, 0x76, 0x48, 0x57, 0x4F, 0x58, 0x36, 0x4A, 0x6E, 0x35, 0x2F, 0x5A, 0x4F, 0x6B, 0x56, 0x49, 0x42, 0x4D, 0x55, 0x74, 0x52, 0x53, 0x71, 0x79, 0x35, 0x4A, 0x33, 0x35, 0x44, 0x4E, 0x0A, 0x75, 0x46, 0x2B, 0x2B, 0x50, 0x39, 0x36, ++ 0x68, 0x79, 0x6B, 0x30, 0x67, 0x31, 0x43, 0x58, 0x6F, 0x68, 0x43, 0x6C, 0x54, 0x74, 0x37, 0x47, 0x49, 0x48, 0x2F, 0x2F, 0x36, 0x32, 0x70, 0x43, 0x66, 0x43, 0x71, 0x6B, 0x74, 0x51, 0x54, 0x2B, 0x78, 0x38, 0x52, 0x67, 0x70, 0x37, 0x68, 0x5A, ++ 0x5A, 0x4C, 0x44, 0x52, 0x4A, 0x47, 0x71, 0x67, 0x47, 0x31, 0x36, 0x69, 0x49, 0x30, 0x67, 0x4E, 0x79, 0x65, 0x6A, 0x4C, 0x69, 0x36, 0x6D, 0x68, 0x4E, 0x62, 0x69, 0x79, 0x57, 0x0A, 0x5A, 0x58, 0x76, 0x4B, 0x57, 0x66, 0x72, 0x79, 0x34, 0x74, ++ 0x33, 0x75, 0x4D, 0x43, 0x7A, 0x37, 0x7A, 0x45, 0x61, 0x73, 0x78, 0x47, 0x50, 0x72, 0x62, 0x33, 0x38, 0x32, 0x4B, 0x7A, 0x52, 0x7A, 0x45, 0x70, 0x52, 0x2F, 0x33, 0x38, 0x77, 0x6D, 0x6E, 0x76, 0x46, 0x79, 0x58, 0x56, 0x42, 0x6C, 0x57, 0x59, ++ 0x39, 0x70, 0x73, 0x34, 0x64, 0x65, 0x4D, 0x6D, 0x2F, 0x44, 0x47, 0x49, 0x71, 0x31, 0x6C, 0x59, 0x2B, 0x77, 0x65, 0x6A, 0x66, 0x65, 0x57, 0x6B, 0x55, 0x37, 0x0A, 0x78, 0x7A, 0x62, 0x68, 0x37, 0x32, 0x66, 0x52, 0x4F, 0x64, 0x4F, 0x58, 0x57, ++ 0x33, 0x4E, 0x69, 0x47, 0x55, 0x67, 0x74, 0x68, 0x78, 0x77, 0x47, 0x2B, 0x33, 0x53, 0x59, 0x49, 0x45, 0x6C, 0x7A, 0x38, 0x41, 0x58, 0x53, 0x47, 0x37, 0x47, 0x67, 0x6F, 0x37, 0x63, 0x62, 0x63, 0x4E, 0x4F, 0x49, 0x61, 0x62, 0x6C, 0x61, 0x31, ++ 0x6A, 0x6A, 0x30, 0x59, 0x74, 0x77, 0x6C, 0x69, 0x33, 0x69, 0x2F, 0x2B, 0x4F, 0x68, 0x2B, 0x75, 0x46, 0x7A, 0x4A, 0x6C, 0x55, 0x39, 0x66, 0x0A, 0x70, 0x79, 0x32, 0x35, 0x49, 0x47, 0x76, 0x50, 0x61, 0x39, 0x33, 0x31, 0x44, 0x66, 0x53, 0x43, ++ 0x74, 0x2F, 0x53, 0x79, 0x5A, 0x69, 0x34, 0x51, 0x4B, 0x50, 0x61, 0x58, 0x57, 0x6E, 0x75, 0x57, 0x46, 0x6F, 0x38, 0x42, 0x47, 0x53, 0x31, 0x73, 0x62, 0x6E, 0x38, 0x35, 0x57, 0x41, 0x5A, 0x6B, 0x67, 0x77, 0x47, 0x44, 0x67, 0x38, 0x4E, 0x4E, ++ 0x6B, 0x74, 0x30, 0x79, 0x78, 0x6F, 0x65, 0x6B, 0x4E, 0x2B, 0x6B, 0x57, 0x7A, 0x71, 0x6F, 0x74, 0x61, 0x4B, 0x38, 0x4B, 0x0A, 0x67, 0x57, 0x55, 0x36, 0x63, 0x4D, 0x47, 0x62, 0x72, 0x55, 0x31, 0x74, 0x56, 0x4D, 0x6F, 0x71, 0x4C, 0x55, 0x75, ++ 0x46, 0x47, 0x37, 0x4F, 0x41, 0x35, 0x6E, 0x42, 0x46, 0x44, 0x57, 0x74, 0x65, 0x4E, 0x66, 0x42, 0x2F, 0x4F, 0x37, 0x69, 0x63, 0x35, 0x41, 0x52, 0x77, 0x69, 0x52, 0x49, 0x6C, 0x6B, 0x39, 0x6F, 0x4B, 0x6D, 0x53, 0x4A, 0x67, 0x61, 0x6D, 0x4E, ++ 0x67, 0x54, 0x6E, 0x59, 0x47, 0x6D, 0x45, 0x36, 0x39, 0x67, 0x36, 0x30, 0x64, 0x57, 0x49, 0x6F, 0x6C, 0x0A, 0x68, 0x64, 0x4C, 0x48, 0x5A, 0x52, 0x34, 0x74, 0x6A, 0x73, 0x62, 0x66, 0x74, 0x73, 0x62, 0x68, 0x66, 0x34, 0x6F, 0x45, 0x49, 0x52, ++ 0x55, 0x70, 0x64, 0x50, 0x41, 0x2B, 0x6E, 0x4A, 0x43, 0x64, 0x44, 0x43, 0x37, 0x78, 0x69, 0x6A, 0x35, 0x61, 0x71, 0x67, 0x77, 0x4A, 0x48, 0x73, 0x66, 0x56, 0x50, 0x4B, 0x50, 0x74, 0x6C, 0x38, 0x4D, 0x65, 0x4E, 0x50, 0x6F, 0x34, 0x2B, 0x51, ++ 0x67, 0x4F, 0x34, 0x38, 0x42, 0x64, 0x4B, 0x34, 0x50, 0x52, 0x56, 0x6D, 0x72, 0x4A, 0x0A, 0x74, 0x71, 0x68, 0x55, 0x55, 0x79, 0x35, 0x34, 0x4D, 0x6D, 0x63, 0x39, 0x67, 0x6E, 0x39, 0x30, 0x30, 0x50, 0x76, 0x68, 0x74, 0x67, 0x56, 0x67, 0x75, ++ 0x58, 0x44, 0x62, 0x6A, 0x67, 0x76, 0x35, 0x45, 0x31, 0x68, 0x76, 0x63, 0x57, 0x41, 0x51, 0x55, 0x68, 0x43, 0x35, 0x77, 0x55, 0x45, 0x4A, 0x37, 0x33, 0x49, 0x66, 0x5A, 0x7A, 0x46, 0x34, 0x2F, 0x35, 0x59, 0x46, 0x6A, 0x51, 0x49, 0x44, 0x41, ++ 0x51, 0x41, 0x42, 0x6F, 0x32, 0x4D, 0x77, 0x59, 0x54, 0x41, 0x66, 0x0A, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x53, 0x4D, 0x45, 0x47, 0x44, 0x41, 0x57, 0x67, 0x42, 0x54, 0x6A, 0x2F, 0x69, 0x33, 0x39, 0x4B, 0x4E, 0x41, 0x4C, 0x74, 0x62, 0x71, 0x32, ++ 0x6F, 0x73, 0x53, 0x2F, 0x42, 0x71, 0x6F, 0x46, 0x6A, 0x4A, 0x50, 0x37, 0x4C, 0x7A, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x41, 0x34, 0x47, ++ 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x0A, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x34, 0x2F, 0x34, 0x74, 0x2F, 0x53, 0x6A, ++ 0x51, 0x43, 0x37, 0x57, 0x36, 0x74, 0x71, 0x4C, 0x45, 0x76, 0x77, 0x61, 0x71, 0x42, 0x59, 0x79, 0x54, 0x2B, 0x79, 0x38, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, ++ 0x44, 0x67, 0x67, 0x49, 0x42, 0x0A, 0x41, 0x43, 0x58, 0x47, 0x75, 0x6D, 0x76, 0x72, 0x68, 0x38, 0x76, 0x65, 0x67, 0x6A, 0x6D, 0x57, 0x50, 0x66, 0x42, 0x45, 0x70, 0x32, 0x75, 0x45, 0x63, 0x77, 0x50, 0x65, 0x6E, 0x53, 0x74, 0x50, 0x75, 0x69, ++ 0x42, 0x2F, 0x76, 0x48, 0x69, 0x79, 0x7A, 0x35, 0x65, 0x77, 0x47, 0x35, 0x7A, 0x7A, 0x31, 0x33, 0x6B, 0x75, 0x39, 0x55, 0x69, 0x32, 0x30, 0x76, 0x73, 0x58, 0x69, 0x4F, 0x62, 0x54, 0x65, 0x6A, 0x2F, 0x74, 0x55, 0x78, 0x50, 0x51, 0x34, 0x69, ++ 0x39, 0x71, 0x0A, 0x65, 0x63, 0x73, 0x41, 0x49, 0x79, 0x6A, 0x6D, 0x48, 0x6A, 0x64, 0x58, 0x4E, 0x59, 0x6D, 0x45, 0x77, 0x6E, 0x5A, 0x50, 0x4E, 0x44, 0x61, 0x74, 0x5A, 0x38, 0x50, 0x4F, 0x51, 0x51, 0x61, 0x49, 0x78, 0x66, 0x66, 0x75, 0x32, ++ 0x42, 0x71, 0x34, 0x31, 0x67, 0x74, 0x2F, 0x55, 0x50, 0x2B, 0x54, 0x71, 0x68, 0x64, 0x4C, 0x6A, 0x4F, 0x7A, 0x74, 0x55, 0x6D, 0x43, 0x79, 0x70, 0x41, 0x62, 0x71, 0x54, 0x75, 0x76, 0x30, 0x61, 0x78, 0x6E, 0x39, 0x36, 0x2F, 0x55, 0x61, 0x0A, ++ 0x34, 0x43, 0x55, 0x71, 0x6D, 0x74, 0x7A, 0x48, 0x51, 0x54, 0x62, 0x33, 0x79, 0x48, 0x51, 0x46, 0x68, 0x44, 0x6D, 0x56, 0x4F, 0x64, 0x59, 0x4C, 0x4F, 0x36, 0x51, 0x6E, 0x2B, 0x67, 0x6A, 0x59, 0x58, 0x42, 0x37, 0x34, 0x42, 0x47, 0x42, 0x53, ++ 0x45, 0x53, 0x67, 0x6F, 0x41, 0x2F, 0x2F, 0x76, 0x55, 0x32, 0x59, 0x41, 0x70, 0x55, 0x6F, 0x30, 0x46, 0x6D, 0x5A, 0x38, 0x2F, 0x51, 0x6D, 0x6B, 0x72, 0x70, 0x35, 0x6E, 0x47, 0x6D, 0x39, 0x42, 0x43, 0x32, 0x73, 0x47, 0x0A, 0x45, 0x35, 0x75, ++ 0x50, 0x68, 0x6E, 0x45, 0x46, 0x74, 0x43, 0x2B, 0x4E, 0x69, 0x57, 0x59, 0x7A, 0x4B, 0x58, 0x5A, 0x55, 0x6D, 0x68, 0x48, 0x34, 0x4A, 0x2F, 0x71, 0x79, 0x50, 0x35, 0x48, 0x67, 0x7A, 0x67, 0x30, 0x62, 0x38, 0x7A, 0x41, 0x61, 0x72, 0x62, 0x38, ++ 0x69, 0x58, 0x52, 0x76, 0x54, 0x76, 0x79, 0x55, 0x46, 0x54, 0x65, 0x47, 0x53, 0x47, 0x6E, 0x2B, 0x5A, 0x6E, 0x7A, 0x78, 0x45, 0x6B, 0x38, 0x72, 0x55, 0x51, 0x45, 0x6C, 0x73, 0x67, 0x49, 0x66, 0x58, 0x0A, 0x42, 0x44, 0x72, 0x44, 0x4D, 0x6C, ++ 0x49, 0x31, 0x44, 0x6C, 0x62, 0x34, 0x70, 0x64, 0x31, 0x39, 0x78, 0x49, 0x73, 0x4E, 0x45, 0x52, 0x39, 0x54, 0x79, 0x78, 0x36, 0x79, 0x46, 0x37, 0x5A, 0x6F, 0x64, 0x31, 0x72, 0x67, 0x31, 0x4D, 0x76, 0x49, 0x42, 0x36, 0x37, 0x31, 0x4F, 0x69, ++ 0x36, 0x4F, 0x4E, 0x37, 0x66, 0x51, 0x41, 0x55, 0x74, 0x44, 0x4B, 0x58, 0x65, 0x4D, 0x4F, 0x5A, 0x65, 0x50, 0x67, 0x6C, 0x72, 0x34, 0x55, 0x65, 0x57, 0x4A, 0x6F, 0x42, 0x6A, 0x6E, 0x0A, 0x61, 0x48, 0x39, 0x64, 0x43, 0x69, 0x37, 0x37, 0x6F, ++ 0x30, 0x63, 0x4F, 0x50, 0x61, 0x59, 0x6A, 0x65, 0x73, 0x59, 0x42, 0x78, 0x34, 0x2F, 0x49, 0x58, 0x72, 0x39, 0x74, 0x67, 0x46, 0x61, 0x2B, 0x69, 0x69, 0x53, 0x36, 0x4D, 0x2B, 0x71, 0x66, 0x34, 0x54, 0x49, 0x52, 0x6E, 0x76, 0x48, 0x53, 0x54, ++ 0x34, 0x44, 0x32, 0x47, 0x30, 0x43, 0x76, 0x4F, 0x4A, 0x34, 0x52, 0x55, 0x48, 0x6C, 0x7A, 0x45, 0x68, 0x4C, 0x4E, 0x35, 0x6D, 0x79, 0x64, 0x4C, 0x49, 0x68, 0x79, 0x0A, 0x50, 0x44, 0x43, 0x42, 0x42, 0x70, 0x45, 0x69, 0x36, 0x6C, 0x6D, 0x74, ++ 0x32, 0x68, 0x6B, 0x75, 0x49, 0x73, 0x4B, 0x4E, 0x75, 0x59, 0x79, 0x48, 0x34, 0x47, 0x61, 0x38, 0x63, 0x79, 0x4E, 0x66, 0x49, 0x57, 0x52, 0x6A, 0x67, 0x45, 0x6A, 0x31, 0x6F, 0x44, 0x77, 0x59, 0x50, 0x5A, 0x54, 0x49, 0x53, 0x45, 0x45, 0x64, ++ 0x51, 0x4C, 0x70, 0x65, 0x2F, 0x76, 0x35, 0x57, 0x4F, 0x61, 0x48, 0x49, 0x7A, 0x31, 0x36, 0x65, 0x47, 0x57, 0x52, 0x47, 0x45, 0x4E, 0x6F, 0x58, 0x0A, 0x6B, 0x62, 0x63, 0x46, 0x67, 0x4B, 0x79, 0x4C, 0x6D, 0x5A, 0x4A, 0x39, 0x35, 0x36, 0x4C, ++ 0x59, 0x42, 0x77, 0x73, 0x32, 0x4A, 0x2B, 0x64, 0x49, 0x65, 0x57, 0x43, 0x4B, 0x77, 0x39, 0x63, 0x54, 0x58, 0x50, 0x68, 0x79, 0x51, 0x4E, 0x39, 0x4B, 0x79, 0x38, 0x2B, 0x5A, 0x41, 0x41, 0x6F, 0x41, 0x43, 0x78, 0x47, 0x56, 0x32, 0x6C, 0x5A, ++ 0x46, 0x41, 0x34, 0x67, 0x4B, 0x6E, 0x32, 0x66, 0x51, 0x31, 0x58, 0x6D, 0x78, 0x71, 0x49, 0x31, 0x41, 0x62, 0x51, 0x33, 0x43, 0x0A, 0x65, 0x6B, 0x44, 0x36, 0x38, 0x31, 0x39, 0x6B, 0x52, 0x35, 0x4C, 0x4C, 0x55, 0x37, 0x6D, 0x37, 0x57, 0x63, ++ 0x35, 0x50, 0x2F, 0x64, 0x41, 0x56, 0x55, 0x77, 0x48, 0x59, 0x33, 0x2B, 0x76, 0x5A, 0x35, 0x6E, 0x62, 0x76, 0x30, 0x43, 0x4F, 0x37, 0x4F, 0x36, 0x6C, 0x35, 0x73, 0x39, 0x55, 0x43, 0x4B, 0x63, 0x32, 0x4A, 0x6F, 0x35, 0x59, 0x50, 0x53, 0x6A, ++ 0x58, 0x6E, 0x54, 0x6B, 0x4C, 0x41, 0x64, 0x63, 0x30, 0x48, 0x7A, 0x2B, 0x59, 0x73, 0x36, 0x33, 0x73, 0x75, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, ++ 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x4F, 0x49, 0x53, 0x54, 0x45, 0x20, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x42, 0x20, 0x43, 0x41, 0x0A, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, ++ 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x44, 0x74, 0x54, 0x43, 0x43, 0x41, 0x70, 0x32, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x64, 0x72, ++ 0x45, 0x67, 0x55, 0x6E, 0x54, 0x77, 0x68, 0x59, 0x64, 0x47, 0x73, 0x2F, 0x67, 0x6A, 0x47, 0x76, 0x62, 0x43, 0x77, 0x44, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, ++ 0x42, 0x74, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0A, 0x45, 0x77, 0x4A, 0x44, 0x53, 0x44, 0x45, 0x51, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x48, 0x56, 0x30, 0x6C, 0x54, 0x5A, ++ 0x55, 0x74, 0x6C, 0x65, 0x54, 0x45, 0x69, 0x4D, 0x43, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4D, 0x5A, 0x54, 0x30, 0x6C, 0x54, 0x56, 0x45, 0x55, 0x67, 0x52, 0x6D, 0x39, 0x31, 0x62, 0x6D, 0x52, 0x68, 0x64, 0x47, 0x6C, 0x76, 0x62, ++ 0x69, 0x42, 0x46, 0x62, 0x6D, 0x52, 0x76, 0x63, 0x6E, 0x4E, 0x6C, 0x0A, 0x5A, 0x44, 0x45, 0x6F, 0x4D, 0x43, 0x59, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x66, 0x54, 0x30, 0x6C, 0x54, 0x56, 0x45, 0x55, 0x67, 0x56, 0x30, 0x6C, 0x54, ++ 0x5A, 0x55, 0x74, 0x6C, 0x65, 0x53, 0x42, 0x48, 0x62, 0x47, 0x39, 0x69, 0x59, 0x57, 0x77, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x48, 0x51, 0x69, 0x42, 0x44, 0x51, 0x54, 0x41, 0x65, 0x46, 0x77, 0x30, 0x78, 0x4E, 0x44, 0x45, 0x79, ++ 0x4D, 0x44, 0x45, 0x78, 0x4E, 0x54, 0x41, 0x77, 0x0A, 0x4D, 0x7A, 0x4A, 0x61, 0x46, 0x77, 0x30, 0x7A, 0x4F, 0x54, 0x45, 0x79, 0x4D, 0x44, 0x45, 0x78, 0x4E, 0x54, 0x45, 0x77, 0x4D, 0x7A, 0x46, 0x61, 0x4D, 0x47, 0x30, 0x78, 0x43, 0x7A, 0x41, ++ 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x4E, 0x49, 0x4D, 0x52, 0x41, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x77, 0x64, 0x58, 0x53, 0x56, 0x4E, 0x6C, 0x53, 0x32, 0x56, 0x35, 0x4D, 0x53, 0x49, ++ 0x77, 0x49, 0x41, 0x59, 0x44, 0x0A, 0x56, 0x51, 0x51, 0x4C, 0x45, 0x78, 0x6C, 0x50, 0x53, 0x56, 0x4E, 0x55, 0x52, 0x53, 0x42, 0x47, 0x62, 0x33, 0x56, 0x75, 0x5A, 0x47, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x49, 0x45, 0x56, 0x75, 0x5A, 0x47, ++ 0x39, 0x79, 0x63, 0x32, 0x56, 0x6B, 0x4D, 0x53, 0x67, 0x77, 0x4A, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x39, 0x50, 0x53, 0x56, 0x4E, 0x55, 0x52, 0x53, 0x42, 0x58, 0x53, 0x56, 0x4E, 0x6C, 0x53, 0x32, 0x56, 0x35, 0x49, 0x45, ++ 0x64, 0x73, 0x0A, 0x62, 0x32, 0x4A, 0x68, 0x62, 0x43, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x64, 0x43, 0x49, 0x45, 0x4E, 0x42, 0x4D, 0x49, 0x49, 0x42, 0x49, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, ++ 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x51, 0x38, 0x41, 0x4D, 0x49, 0x49, 0x42, 0x43, 0x67, 0x4B, 0x43, 0x41, 0x51, 0x45, 0x41, 0x32, 0x42, 0x65, 0x33, 0x48, 0x45, 0x6F, 0x6B, 0x4B, 0x74, 0x61, 0x58, 0x0A, ++ 0x73, 0x63, 0x72, 0x69, 0x48, 0x76, 0x74, 0x39, 0x4F, 0x4F, 0x2B, 0x59, 0x39, 0x62, 0x49, 0x35, 0x6D, 0x45, 0x34, 0x6E, 0x75, 0x42, 0x46, 0x64, 0x65, 0x39, 0x49, 0x6C, 0x6C, 0x49, 0x69, 0x43, 0x46, 0x53, 0x5A, 0x71, 0x47, 0x7A, 0x47, 0x37, ++ 0x71, 0x46, 0x73, 0x68, 0x49, 0x53, 0x76, 0x59, 0x44, 0x30, 0x36, 0x66, 0x57, 0x76, 0x47, 0x78, 0x57, 0x75, 0x52, 0x35, 0x31, 0x6A, 0x49, 0x6A, 0x4B, 0x2B, 0x46, 0x54, 0x7A, 0x4A, 0x6C, 0x46, 0x58, 0x48, 0x74, 0x50, 0x0A, 0x72, 0x62, 0x79, ++ 0x2F, 0x68, 0x30, 0x6F, 0x4C, 0x53, 0x35, 0x64, 0x61, 0x71, 0x50, 0x5A, 0x49, 0x37, 0x48, 0x31, 0x37, 0x44, 0x63, 0x30, 0x68, 0x42, 0x74, 0x2B, 0x65, 0x46, 0x66, 0x31, 0x42, 0x69, 0x6B, 0x69, 0x33, 0x49, 0x50, 0x53, 0x68, 0x65, 0x68, 0x74, ++ 0x58, 0x31, 0x46, 0x31, 0x51, 0x2F, 0x37, 0x70, 0x6E, 0x32, 0x43, 0x4F, 0x5A, 0x48, 0x38, 0x67, 0x2F, 0x34, 0x39, 0x37, 0x2F, 0x62, 0x31, 0x74, 0x33, 0x73, 0x57, 0x74, 0x75, 0x75, 0x4D, 0x6C, 0x6B, 0x0A, 0x39, 0x2B, 0x48, 0x4B, 0x51, 0x55, ++ 0x59, 0x4F, 0x4B, 0x58, 0x48, 0x51, 0x75, 0x53, 0x50, 0x38, 0x79, 0x59, 0x46, 0x66, 0x54, 0x76, 0x64, 0x76, 0x33, 0x37, 0x2B, 0x45, 0x72, 0x58, 0x4E, 0x6B, 0x75, 0x37, 0x64, 0x43, 0x6A, 0x6D, 0x6E, 0x32, 0x31, 0x48, 0x59, 0x64, 0x66, 0x70, ++ 0x32, 0x6E, 0x75, 0x46, 0x65, 0x4B, 0x55, 0x57, 0x64, 0x79, 0x31, 0x39, 0x53, 0x6F, 0x75, 0x4A, 0x56, 0x55, 0x51, 0x48, 0x4D, 0x44, 0x39, 0x75, 0x72, 0x30, 0x36, 0x2F, 0x34, 0x6F, 0x0A, 0x51, 0x6E, 0x63, 0x2F, 0x6E, 0x53, 0x4D, 0x62, 0x73, ++ 0x72, 0x59, 0x39, 0x67, 0x42, 0x51, 0x48, 0x54, 0x43, 0x35, 0x50, 0x39, 0x39, 0x55, 0x4B, 0x46, 0x67, 0x32, 0x39, 0x5A, 0x6B, 0x4D, 0x33, 0x66, 0x69, 0x4E, 0x44, 0x65, 0x63, 0x4E, 0x41, 0x68, 0x76, 0x56, 0x4D, 0x4B, 0x64, 0x71, 0x4F, 0x6D, ++ 0x71, 0x30, 0x4E, 0x70, 0x51, 0x53, 0x48, 0x69, 0x42, 0x36, 0x46, 0x34, 0x2B, 0x6C, 0x54, 0x31, 0x5A, 0x76, 0x49, 0x69, 0x77, 0x4E, 0x6A, 0x65, 0x4F, 0x76, 0x67, 0x0A, 0x47, 0x55, 0x70, 0x75, 0x75, 0x79, 0x39, 0x72, 0x4D, 0x32, 0x52, 0x59, ++ 0x6B, 0x36, 0x31, 0x70, 0x76, 0x34, 0x38, 0x62, 0x37, 0x34, 0x4A, 0x49, 0x78, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6F, 0x31, 0x45, 0x77, 0x54, 0x7A, 0x41, 0x4C, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, ++ 0x41, 0x59, 0x59, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x0A, 0x2F, 0x7A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, ++ 0x55, 0x4E, 0x51, 0x2F, 0x49, 0x4E, 0x6D, 0x4E, 0x65, 0x34, 0x71, 0x50, 0x73, 0x2B, 0x54, 0x74, 0x6D, 0x46, 0x63, 0x35, 0x52, 0x55, 0x75, 0x4F, 0x52, 0x6D, 0x6A, 0x30, 0x77, 0x45, 0x41, 0x59, 0x4A, 0x4B, 0x77, 0x59, 0x42, 0x42, 0x41, 0x47, ++ 0x43, 0x4E, 0x78, 0x55, 0x42, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x51, 0x41, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x0A, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x42, 0x41, 0x45, ++ 0x42, 0x4D, 0x2B, 0x34, 0x65, 0x79, 0x6D, 0x59, 0x47, 0x51, 0x66, 0x70, 0x33, 0x46, 0x73, 0x4C, 0x41, 0x6D, 0x7A, 0x59, 0x68, 0x37, 0x4B, 0x7A, 0x4B, 0x4E, 0x62, 0x72, 0x67, 0x68, 0x63, 0x56, 0x69, 0x58, 0x66, 0x61, 0x34, 0x33, 0x46, 0x4B, ++ 0x38, 0x2B, 0x35, 0x2F, 0x65, 0x61, 0x34, 0x6E, 0x33, 0x32, 0x63, 0x5A, 0x69, 0x5A, 0x42, 0x4B, 0x70, 0x44, 0x0A, 0x64, 0x48, 0x69, 0x6A, 0x34, 0x30, 0x6C, 0x68, 0x50, 0x6E, 0x4F, 0x4D, 0x54, 0x5A, 0x54, 0x67, 0x2B, 0x58, 0x48, 0x45, 0x74, ++ 0x68, 0x59, 0x4F, 0x55, 0x33, 0x67, 0x66, 0x31, 0x71, 0x4B, 0x48, 0x4C, 0x77, 0x49, 0x35, 0x67, 0x53, 0x6B, 0x38, 0x72, 0x78, 0x57, 0x59, 0x49, 0x54, 0x44, 0x2B, 0x4B, 0x4A, 0x41, 0x41, 0x6A, 0x4E, 0x48, 0x68, 0x79, 0x2F, 0x70, 0x65, 0x79, ++ 0x50, 0x33, 0x34, 0x45, 0x45, 0x59, 0x37, 0x6F, 0x6E, 0x68, 0x43, 0x6B, 0x52, 0x64, 0x30, 0x0A, 0x56, 0x51, 0x72, 0x65, 0x55, 0x47, 0x64, 0x4E, 0x5A, 0x74, 0x47, 0x6E, 0x2F, 0x2F, 0x33, 0x5A, 0x77, 0x4C, 0x57, 0x6F, 0x6F, 0x34, 0x72, 0x4F, ++ 0x5A, 0x76, 0x55, 0x50, 0x51, 0x38, 0x32, 0x6E, 0x4B, 0x31, 0x64, 0x37, 0x59, 0x30, 0x5A, 0x71, 0x71, 0x69, 0x35, 0x53, 0x32, 0x50, 0x54, 0x74, 0x34, 0x57, 0x32, 0x74, 0x4B, 0x5A, 0x42, 0x34, 0x53, 0x4C, 0x72, 0x68, 0x49, 0x36, 0x71, 0x6A, ++ 0x69, 0x65, 0x79, 0x31, 0x71, 0x35, 0x62, 0x41, 0x74, 0x45, 0x75, 0x69, 0x0A, 0x48, 0x5A, 0x65, 0x65, 0x65, 0x76, 0x4A, 0x75, 0x51, 0x48, 0x48, 0x66, 0x61, 0x50, 0x46, 0x6C, 0x54, 0x63, 0x35, 0x38, 0x42, 0x64, 0x39, 0x54, 0x5A, 0x61, 0x6D, ++ 0x6C, 0x38, 0x4C, 0x47, 0x58, 0x42, 0x48, 0x41, 0x56, 0x52, 0x67, 0x4F, 0x59, 0x31, 0x4E, 0x4B, 0x2F, 0x56, 0x4C, 0x53, 0x67, 0x57, 0x48, 0x31, 0x53, 0x62, 0x39, 0x70, 0x57, 0x4A, 0x6D, 0x4C, 0x55, 0x32, 0x4E, 0x75, 0x4A, 0x4D, 0x57, 0x38, ++ 0x63, 0x38, 0x43, 0x4C, 0x43, 0x30, 0x32, 0x49, 0x63, 0x0A, 0x4E, 0x63, 0x31, 0x4D, 0x61, 0x52, 0x56, 0x55, 0x47, 0x70, 0x43, 0x59, 0x33, 0x75, 0x73, 0x65, 0x58, 0x38, 0x70, 0x33, 0x78, 0x38, 0x75, 0x4F, 0x50, 0x55, 0x4E, 0x70, 0x6E, 0x4A, ++ 0x70, 0x59, 0x30, 0x43, 0x51, 0x37, 0x33, 0x78, 0x74, 0x41, 0x6C, 0x6E, 0x34, 0x31, 0x72, 0x59, 0x48, 0x48, 0x54, 0x6E, 0x47, 0x36, 0x69, 0x42, 0x4D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, ++ 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x53, 0x5A, 0x41, 0x46, 0x49, 0x52, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x20, 0x43, 0x41, 0x32, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x44, 0x63, 0x6A, ++ 0x43, 0x43, 0x41, 0x6C, 0x71, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x55, 0x50, 0x6F, 0x70, 0x64, 0x42, 0x2B, 0x78, 0x56, 0x30, 0x6A, 0x4C, 0x56, 0x74, 0x2B, 0x4F, 0x32, 0x58, 0x77, 0x48, 0x72, 0x4C, 0x64, 0x7A, 0x6B, 0x31, 0x75, ++ 0x51, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x77, 0x55, 0x54, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x0A, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x55, ++ 0x45, 0x77, 0x78, 0x4B, 0x44, 0x41, 0x6D, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x48, 0x30, 0x74, 0x79, 0x59, 0x57, 0x70, 0x76, 0x64, 0x32, 0x45, 0x67, 0x53, 0x58, 0x70, 0x69, 0x59, 0x53, 0x42, 0x53, 0x62, 0x33, 0x70, 0x73, 0x61, ++ 0x57, 0x4E, 0x36, 0x5A, 0x57, 0x35, 0x70, 0x62, 0x33, 0x64, 0x68, 0x49, 0x46, 0x4D, 0x75, 0x51, 0x53, 0x34, 0x78, 0x47, 0x44, 0x41, 0x57, 0x42, 0x67, 0x4E, 0x56, 0x0A, 0x42, 0x41, 0x4D, 0x4D, 0x44, 0x31, 0x4E, 0x61, 0x51, 0x55, 0x5A, 0x4A, ++ 0x55, 0x69, 0x42, 0x53, 0x54, 0x30, 0x39, 0x55, 0x49, 0x45, 0x4E, 0x42, 0x4D, 0x6A, 0x41, 0x65, 0x46, 0x77, 0x30, 0x78, 0x4E, 0x54, 0x45, 0x77, 0x4D, 0x54, 0x6B, 0x77, 0x4E, 0x7A, 0x51, 0x7A, 0x4D, 0x7A, 0x42, 0x61, 0x46, 0x77, 0x30, 0x7A, ++ 0x4E, 0x54, 0x45, 0x77, 0x4D, 0x54, 0x6B, 0x77, 0x4E, 0x7A, 0x51, 0x7A, 0x4D, 0x7A, 0x42, 0x61, 0x4D, 0x46, 0x45, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x0A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6C, 0x42, 0x4D, 0x4D, 0x53, 0x67, ++ 0x77, 0x4A, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x44, 0x42, 0x39, 0x4C, 0x63, 0x6D, 0x46, 0x71, 0x62, 0x33, 0x64, 0x68, 0x49, 0x45, 0x6C, 0x36, 0x59, 0x6D, 0x45, 0x67, 0x55, 0x6D, 0x39, 0x36, 0x62, 0x47, 0x6C, 0x6A, 0x65, 0x6D, 0x56, ++ 0x75, 0x61, 0x57, 0x39, 0x33, 0x59, 0x53, 0x42, 0x54, 0x4C, 0x6B, 0x45, 0x75, 0x4D, 0x52, 0x67, 0x77, 0x46, 0x67, 0x59, 0x44, 0x0A, 0x56, 0x51, 0x51, 0x44, 0x44, 0x41, 0x39, 0x54, 0x57, 0x6B, 0x46, 0x47, 0x53, 0x56, 0x49, 0x67, 0x55, 0x6B, ++ 0x39, 0x50, 0x56, 0x43, 0x42, 0x44, 0x51, 0x54, 0x49, 0x77, 0x67, 0x67, 0x45, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x44, 0x77, ++ 0x41, 0x77, 0x67, 0x67, 0x45, 0x4B, 0x41, 0x6F, 0x49, 0x42, 0x41, 0x51, 0x43, 0x33, 0x76, 0x44, 0x35, 0x51, 0x0A, 0x71, 0x45, 0x76, 0x4E, 0x51, 0x4C, 0x58, 0x4F, 0x59, 0x65, 0x65, 0x57, 0x79, 0x72, 0x53, 0x68, 0x32, 0x67, 0x77, 0x69, 0x73, ++ 0x50, 0x71, 0x31, 0x65, 0x33, 0x59, 0x41, 0x64, 0x34, 0x77, 0x4C, 0x7A, 0x33, 0x32, 0x6F, 0x68, 0x73, 0x77, 0x6D, 0x55, 0x65, 0x51, 0x67, 0x50, 0x59, 0x55, 0x4D, 0x31, 0x6C, 0x6A, 0x6A, 0x35, 0x2F, 0x51, 0x71, 0x47, 0x4A, 0x33, 0x61, 0x30, ++ 0x61, 0x34, 0x6D, 0x37, 0x75, 0x74, 0x54, 0x33, 0x50, 0x53, 0x51, 0x31, 0x68, 0x4E, 0x4B, 0x0A, 0x44, 0x4A, 0x41, 0x38, 0x77, 0x2F, 0x54, 0x61, 0x30, 0x6F, 0x34, 0x4E, 0x6B, 0x6A, 0x72, 0x63, 0x73, 0x62, 0x48, 0x2F, 0x4F, 0x4E, 0x37, 0x44, ++ 0x75, 0x69, 0x31, 0x66, 0x67, 0x4C, 0x6B, 0x43, 0x76, 0x55, 0x71, 0x64, 0x47, 0x77, 0x2B, 0x30, 0x77, 0x38, 0x4C, 0x42, 0x5A, 0x77, 0x50, 0x64, 0x33, 0x42, 0x75, 0x63, 0x50, 0x62, 0x4F, 0x77, 0x33, 0x67, 0x41, 0x65, 0x71, 0x44, 0x52, 0x48, ++ 0x75, 0x35, 0x72, 0x72, 0x2F, 0x67, 0x73, 0x55, 0x76, 0x54, 0x61, 0x45, 0x0A, 0x32, 0x67, 0x30, 0x67, 0x76, 0x2F, 0x70, 0x62, 0x79, 0x36, 0x6B, 0x57, 0x49, 0x4B, 0x30, 0x35, 0x59, 0x4F, 0x34, 0x76, 0x64, 0x62, 0x62, 0x6E, 0x6C, 0x35, 0x7A, ++ 0x35, 0x50, 0x76, 0x31, 0x2B, 0x54, 0x57, 0x39, 0x4E, 0x4C, 0x2B, 0x2B, 0x49, 0x44, 0x57, 0x72, 0x36, 0x33, 0x66, 0x45, 0x39, 0x62, 0x69, 0x43, 0x6C, 0x6F, 0x42, 0x4B, 0x30, 0x54, 0x58, 0x43, 0x35, 0x7A, 0x74, 0x64, 0x79, 0x4F, 0x34, 0x6D, ++ 0x54, 0x70, 0x34, 0x43, 0x45, 0x48, 0x43, 0x64, 0x4A, 0x0A, 0x63, 0x6B, 0x6D, 0x31, 0x2F, 0x7A, 0x75, 0x56, 0x6E, 0x73, 0x48, 0x4D, 0x79, 0x41, 0x48, 0x73, 0x36, 0x41, 0x36, 0x4B, 0x43, 0x70, 0x62, 0x6E, 0x73, 0x36, 0x61, 0x48, 0x35, 0x64, ++ 0x62, 0x35, 0x42, 0x53, 0x73, 0x4E, 0x6C, 0x30, 0x42, 0x77, 0x50, 0x4C, 0x71, 0x73, 0x64, 0x56, 0x71, 0x63, 0x31, 0x55, 0x32, 0x64, 0x41, 0x67, 0x72, 0x53, 0x53, 0x35, 0x74, 0x6D, 0x53, 0x30, 0x59, 0x48, 0x46, 0x32, 0x57, 0x74, 0x6E, 0x32, ++ 0x79, 0x49, 0x41, 0x4E, 0x77, 0x69, 0x0A, 0x69, 0x65, 0x44, 0x68, 0x5A, 0x4E, 0x52, 0x6E, 0x76, 0x44, 0x46, 0x35, 0x59, 0x54, 0x79, 0x37, 0x79, 0x6B, 0x48, 0x4E, 0x58, 0x47, 0x6F, 0x41, 0x79, 0x44, 0x77, 0x34, 0x6A, 0x6C, 0x69, 0x76, 0x41, ++ 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, 0x51, 0x6A, 0x42, 0x41, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, ++ 0x52, 0x30, 0x50, 0x0A, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x51, 0x75, 0x46, 0x71, 0x6C, 0x4B, 0x47, 0x4C, 0x58, 0x4C, ++ 0x7A, 0x50, 0x56, 0x76, 0x55, 0x50, 0x4D, 0x6A, 0x58, 0x2F, 0x68, 0x64, 0x35, 0x36, 0x7A, 0x77, 0x79, 0x44, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x41, 0x4F, 0x43, ++ 0x0A, 0x41, 0x51, 0x45, 0x41, 0x74, 0x58, 0x50, 0x34, 0x41, 0x39, 0x78, 0x5A, 0x57, 0x78, 0x31, 0x32, 0x36, 0x61, 0x4D, 0x71, 0x65, 0x35, 0x41, 0x6F, 0x73, 0x6B, 0x33, 0x41, 0x4D, 0x30, 0x2B, 0x71, 0x6D, 0x72, 0x48, 0x55, 0x75, 0x4F, 0x51, ++ 0x6E, 0x2F, 0x36, 0x6D, 0x57, 0x6D, 0x63, 0x35, 0x47, 0x34, 0x47, 0x31, 0x38, 0x54, 0x4B, 0x49, 0x34, 0x70, 0x41, 0x5A, 0x77, 0x38, 0x50, 0x52, 0x42, 0x45, 0x65, 0x77, 0x2F, 0x52, 0x34, 0x30, 0x2F, 0x63, 0x6F, 0x66, 0x35, 0x0A, 0x4F, 0x2F, ++ 0x32, 0x6B, 0x62, 0x79, 0x74, 0x54, 0x41, 0x4F, 0x44, 0x2F, 0x4F, 0x62, 0x6C, 0x71, 0x42, 0x77, 0x37, 0x72, 0x48, 0x52, 0x7A, 0x32, 0x6F, 0x6E, 0x4B, 0x51, 0x79, 0x34, 0x49, 0x39, 0x45, 0x59, 0x4B, 0x4C, 0x30, 0x72, 0x75, 0x66, 0x4B, 0x71, ++ 0x38, 0x68, 0x35, 0x6D, 0x4F, 0x47, 0x6E, 0x58, 0x6B, 0x5A, 0x37, 0x2F, 0x65, 0x37, 0x44, 0x44, 0x57, 0x51, 0x77, 0x34, 0x72, 0x74, 0x54, 0x77, 0x2F, 0x31, 0x7A, 0x42, 0x4C, 0x5A, 0x70, 0x44, 0x36, 0x37, 0x0A, 0x6F, 0x50, 0x77, 0x67, 0x6C, ++ 0x56, 0x39, 0x50, 0x4A, 0x69, 0x38, 0x52, 0x49, 0x34, 0x4E, 0x4F, 0x64, 0x51, 0x63, 0x50, 0x76, 0x35, 0x76, 0x52, 0x74, 0x42, 0x33, 0x70, 0x45, 0x41, 0x54, 0x2B, 0x79, 0x6D, 0x43, 0x50, 0x6F, 0x6B, 0x79, 0x34, 0x72, 0x63, 0x2F, 0x68, 0x6B, ++ 0x41, 0x2F, 0x4E, 0x72, 0x67, 0x72, 0x48, 0x58, 0x58, 0x75, 0x33, 0x55, 0x4E, 0x4C, 0x55, 0x59, 0x66, 0x72, 0x56, 0x46, 0x64, 0x76, 0x58, 0x6E, 0x34, 0x64, 0x52, 0x56, 0x4F, 0x75, 0x6C, 0x0A, 0x34, 0x2B, 0x76, 0x4A, 0x68, 0x61, 0x41, 0x6C, ++ 0x49, 0x44, 0x66, 0x37, 0x6A, 0x73, 0x34, 0x4D, 0x4E, 0x49, 0x54, 0x68, 0x50, 0x49, 0x47, 0x79, 0x64, 0x30, 0x35, 0x44, 0x70, 0x59, 0x68, 0x66, 0x68, 0x6D, 0x65, 0x68, 0x50, 0x65, 0x61, 0x30, 0x58, 0x47, 0x47, 0x32, 0x50, 0x74, 0x76, 0x2B, ++ 0x74, 0x79, 0x6A, 0x46, 0x6F, 0x67, 0x65, 0x75, 0x74, 0x63, 0x72, 0x4B, 0x6A, 0x53, 0x6F, 0x53, 0x37, 0x35, 0x66, 0x74, 0x77, 0x6A, 0x43, 0x6B, 0x79, 0x53, 0x70, 0x36, 0x0A, 0x2B, 0x2F, 0x4E, 0x4E, 0x49, 0x78, 0x75, 0x5A, 0x4D, 0x7A, 0x53, ++ 0x67, 0x4C, 0x76, 0x57, 0x70, 0x43, 0x7A, 0x2F, 0x55, 0x58, 0x65, 0x48, 0x50, 0x68, 0x4A, 0x2F, 0x69, 0x47, 0x63, 0x4A, 0x66, 0x69, 0x74, 0x59, 0x67, 0x48, 0x75, 0x4E, 0x7A, 0x74, 0x77, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, ++ 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x4E, 0x65, 0x74, 0x77, ++ 0x6F, 0x72, 0x6B, 0x20, 0x43, 0x41, 0x20, 0x32, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, ++ 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x30, 0x6A, 0x43, 0x43, 0x41, 0x37, 0x71, 0x67, 0x41, 0x77, 0x49, ++ 0x42, 0x41, 0x67, 0x49, 0x51, 0x49, 0x64, 0x62, 0x51, 0x53, 0x6B, 0x38, 0x6C, 0x44, 0x38, 0x6B, 0x79, 0x4E, 0x2F, 0x79, 0x71, 0x58, 0x68, 0x4B, 0x4E, 0x36, 0x54, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, ++ 0x42, 0x41, 0x51, 0x30, 0x46, 0x41, 0x44, 0x43, 0x42, 0x67, 0x44, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0A, 0x42, 0x68, 0x4D, 0x43, 0x55, 0x45, 0x77, 0x78, 0x49, 0x6A, 0x41, 0x67, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, ++ 0x6F, 0x54, 0x47, 0x56, 0x56, 0x75, 0x61, 0x58, 0x70, 0x6C, 0x64, 0x47, 0x38, 0x67, 0x56, 0x47, 0x56, 0x6A, 0x61, 0x47, 0x35, 0x76, 0x62, 0x47, 0x39, 0x6E, 0x61, 0x57, 0x56, 0x7A, 0x49, 0x46, 0x4D, 0x75, 0x51, 0x53, 0x34, 0x78, 0x4A, 0x7A, ++ 0x41, 0x6C, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x73, 0x54, 0x48, 0x6B, 0x4E, 0x6C, 0x63, 0x6E, 0x52, 0x31, 0x0A, 0x62, 0x53, 0x42, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x61, 0x57, 0x5A, 0x70, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x49, ++ 0x45, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6D, 0x6C, 0x30, 0x65, 0x54, 0x45, 0x6B, 0x4D, 0x43, 0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x62, 0x51, 0x32, 0x56, 0x79, 0x64, 0x48, 0x56, 0x74, 0x49, 0x46, 0x52, 0x79, 0x64, ++ 0x58, 0x4E, 0x30, 0x5A, 0x57, 0x51, 0x67, 0x54, 0x6D, 0x56, 0x30, 0x64, 0x32, 0x39, 0x79, 0x0A, 0x61, 0x79, 0x42, 0x44, 0x51, 0x53, 0x41, 0x79, 0x4D, 0x43, 0x49, 0x59, 0x44, 0x7A, 0x49, 0x77, 0x4D, 0x54, 0x45, 0x78, 0x4D, 0x44, 0x41, 0x32, ++ 0x4D, 0x44, 0x67, 0x7A, 0x4F, 0x54, 0x55, 0x32, 0x57, 0x68, 0x67, 0x50, 0x4D, 0x6A, 0x41, 0x30, 0x4E, 0x6A, 0x45, 0x77, 0x4D, 0x44, 0x59, 0x77, 0x4F, 0x44, 0x4D, 0x35, 0x4E, 0x54, 0x5A, 0x61, 0x4D, 0x49, 0x47, 0x41, 0x4D, 0x51, 0x73, 0x77, ++ 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x51, 0x0A, 0x54, 0x44, 0x45, 0x69, 0x4D, 0x43, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x5A, 0x56, 0x57, 0x35, 0x70, 0x65, 0x6D, 0x56, 0x30, 0x62, 0x79, 0x42, ++ 0x55, 0x5A, 0x57, 0x4E, 0x6F, 0x62, 0x6D, 0x39, 0x73, 0x62, 0x32, 0x64, 0x70, 0x5A, 0x58, 0x4D, 0x67, 0x55, 0x79, 0x35, 0x42, 0x4C, 0x6A, 0x45, 0x6E, 0x4D, 0x43, 0x55, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4D, 0x65, 0x51, 0x32, 0x56, ++ 0x79, 0x64, 0x48, 0x56, 0x74, 0x49, 0x45, 0x4E, 0x6C, 0x0A, 0x63, 0x6E, 0x52, 0x70, 0x5A, 0x6D, 0x6C, 0x6A, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52, 0x35, 0x4D, 0x53, ++ 0x51, 0x77, 0x49, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x74, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x64, 0x57, 0x30, 0x67, 0x56, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x52, 0x6C, 0x5A, 0x43, 0x42, 0x4F, 0x5A, 0x58, 0x52, 0x33, 0x62, 0x33, ++ 0x4A, 0x72, 0x49, 0x45, 0x4E, 0x42, 0x0A, 0x49, 0x44, 0x49, 0x77, 0x67, 0x67, 0x49, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x44, ++ 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x43, 0x39, 0x2B, 0x58, 0x6A, 0x34, 0x35, 0x74, 0x57, 0x41, 0x44, 0x47, 0x53, 0x64, 0x68, 0x68, 0x75, 0x57, 0x5A, 0x47, 0x63, 0x2F, 0x49, 0x6A, 0x6F, 0x65, 0x64, ++ 0x51, 0x46, 0x39, 0x0A, 0x37, 0x2F, 0x74, 0x63, 0x5A, 0x34, 0x7A, 0x4A, 0x7A, 0x46, 0x78, 0x72, 0x71, 0x5A, 0x48, 0x6D, 0x75, 0x55, 0x4C, 0x6C, 0x49, 0x45, 0x75, 0x62, 0x32, 0x70, 0x74, 0x37, 0x75, 0x5A, 0x6C, 0x64, 0x32, 0x5A, 0x75, 0x41, ++ 0x53, 0x39, 0x65, 0x45, 0x51, 0x43, 0x73, 0x6E, 0x30, 0x2B, 0x69, 0x36, 0x4D, 0x4C, 0x73, 0x2B, 0x43, 0x52, 0x71, 0x6E, 0x53, 0x5A, 0x58, 0x76, 0x4B, 0x30, 0x41, 0x6B, 0x77, 0x70, 0x66, 0x48, 0x70, 0x2B, 0x36, 0x62, 0x4A, 0x65, 0x2B, 0x6F, ++ 0x0A, 0x43, 0x67, 0x43, 0x58, 0x68, 0x56, 0x71, 0x71, 0x6E, 0x64, 0x77, 0x70, 0x79, 0x65, 0x49, 0x31, 0x42, 0x2B, 0x74, 0x77, 0x54, 0x55, 0x72, 0x57, 0x77, 0x62, 0x4E, 0x57, 0x75, 0x4B, 0x46, 0x42, 0x4F, 0x4A, 0x76, 0x52, 0x2B, 0x7A, 0x46, ++ 0x2F, 0x6A, 0x2B, 0x42, 0x66, 0x34, 0x62, 0x45, 0x2F, 0x44, 0x34, 0x34, 0x57, 0x53, 0x57, 0x44, 0x58, 0x42, 0x6F, 0x30, 0x59, 0x2B, 0x61, 0x6F, 0x6D, 0x45, 0x4B, 0x73, 0x71, 0x30, 0x39, 0x44, 0x52, 0x5A, 0x34, 0x30, 0x62, 0x0A, 0x52, 0x72, ++ 0x35, 0x48, 0x4D, 0x4E, 0x55, 0x75, 0x63, 0x74, 0x48, 0x46, 0x59, 0x39, 0x72, 0x6E, 0x59, 0x33, 0x6C, 0x45, 0x66, 0x6B, 0x74, 0x6A, 0x4A, 0x49, 0x6D, 0x47, 0x4C, 0x6A, 0x51, 0x2F, 0x4B, 0x55, 0x78, 0x53, 0x69, 0x79, 0x71, 0x6E, 0x77, 0x4F, ++ 0x4B, 0x52, 0x4B, 0x49, 0x6D, 0x35, 0x77, 0x46, 0x76, 0x35, 0x48, 0x64, 0x6E, 0x6E, 0x4A, 0x36, 0x33, 0x2F, 0x6D, 0x67, 0x4B, 0x58, 0x77, 0x63, 0x5A, 0x51, 0x6B, 0x70, 0x73, 0x43, 0x4C, 0x4C, 0x32, 0x70, 0x0A, 0x75, 0x54, 0x52, 0x5A, 0x43, ++ 0x72, 0x2B, 0x45, 0x53, 0x76, 0x2F, 0x66, 0x2F, 0x72, 0x4F, 0x66, 0x36, 0x39, 0x6D, 0x65, 0x34, 0x4A, 0x67, 0x6A, 0x37, 0x4B, 0x5A, 0x72, 0x64, 0x78, 0x59, 0x71, 0x32, 0x38, 0x79, 0x74, 0x4F, 0x78, 0x79, 0x6B, 0x68, 0x39, 0x78, 0x47, 0x63, ++ 0x31, 0x34, 0x5A, 0x59, 0x6D, 0x68, 0x46, 0x56, 0x2B, 0x53, 0x51, 0x67, 0x6B, 0x4B, 0x37, 0x51, 0x74, 0x62, 0x77, 0x59, 0x65, 0x44, 0x42, 0x6F, 0x7A, 0x31, 0x6D, 0x6F, 0x31, 0x33, 0x30, 0x0A, 0x47, 0x4F, 0x36, 0x49, 0x79, 0x59, 0x30, 0x58, ++ 0x52, 0x53, 0x6D, 0x5A, 0x4D, 0x6E, 0x55, 0x43, 0x4D, 0x65, 0x34, 0x70, 0x4A, 0x73, 0x68, 0x72, 0x41, 0x75, 0x61, 0x31, 0x59, 0x6B, 0x56, 0x2F, 0x4E, 0x78, 0x56, 0x61, 0x49, 0x32, 0x69, 0x4A, 0x31, 0x44, 0x37, 0x65, 0x54, 0x69, 0x65, 0x77, ++ 0x38, 0x45, 0x41, 0x4D, 0x76, 0x45, 0x30, 0x58, 0x79, 0x30, 0x32, 0x69, 0x73, 0x78, 0x37, 0x51, 0x42, 0x6C, 0x72, 0x64, 0x39, 0x70, 0x50, 0x50, 0x56, 0x33, 0x57, 0x5A, 0x0A, 0x39, 0x66, 0x71, 0x47, 0x47, 0x6D, 0x64, 0x34, 0x73, 0x37, 0x2B, ++ 0x57, 0x2F, 0x6A, 0x54, 0x63, 0x76, 0x65, 0x64, 0x53, 0x56, 0x75, 0x57, 0x7A, 0x35, 0x58, 0x56, 0x37, 0x31, 0x30, 0x47, 0x52, 0x42, 0x64, 0x78, 0x64, 0x61, 0x65, 0x4F, 0x56, 0x44, 0x55, 0x4F, 0x35, 0x2F, 0x49, 0x4F, 0x57, 0x4F, 0x5A, 0x56, ++ 0x37, 0x62, 0x49, 0x42, 0x61, 0x54, 0x78, 0x4E, 0x79, 0x78, 0x74, 0x64, 0x39, 0x4B, 0x58, 0x70, 0x45, 0x75, 0x6C, 0x4B, 0x6B, 0x4B, 0x74, 0x56, 0x42, 0x0A, 0x52, 0x67, 0x6B, 0x67, 0x2F, 0x69, 0x4B, 0x67, 0x74, 0x6C, 0x73, 0x77, 0x6A, 0x62, ++ 0x79, 0x4A, 0x44, 0x4E, 0x58, 0x58, 0x63, 0x50, 0x69, 0x48, 0x55, 0x76, 0x33, 0x61, 0x37, 0x36, 0x78, 0x52, 0x4C, 0x67, 0x65, 0x7A, 0x54, 0x76, 0x37, 0x51, 0x43, 0x64, 0x70, 0x77, 0x37, 0x35, 0x6A, 0x36, 0x56, 0x75, 0x5A, 0x74, 0x32, 0x37, ++ 0x56, 0x58, 0x53, 0x39, 0x7A, 0x6C, 0x4C, 0x43, 0x55, 0x56, 0x79, 0x4A, 0x34, 0x75, 0x65, 0x45, 0x37, 0x34, 0x32, 0x70, 0x79, 0x65, 0x0A, 0x68, 0x69, 0x7A, 0x4B, 0x56, 0x2F, 0x4D, 0x61, 0x35, 0x63, 0x69, 0x53, 0x69, 0x78, 0x71, 0x43, 0x6C, ++ 0x6E, 0x72, 0x44, 0x76, 0x46, 0x41, 0x53, 0x61, 0x64, 0x67, 0x4F, 0x57, 0x6B, 0x61, 0x4C, 0x4F, 0x75, 0x73, 0x6D, 0x2B, 0x69, 0x50, 0x4A, 0x74, 0x72, 0x43, 0x42, 0x76, 0x6B, 0x49, 0x41, 0x70, 0x50, 0x6A, 0x57, 0x2F, 0x6A, 0x41, 0x75, 0x78, ++ 0x39, 0x4A, 0x47, 0x39, 0x75, 0x57, 0x4F, 0x64, 0x66, 0x33, 0x79, 0x7A, 0x4C, 0x6E, 0x51, 0x68, 0x31, 0x76, 0x4D, 0x0A, 0x42, 0x68, 0x42, 0x67, 0x75, 0x34, 0x4D, 0x31, 0x74, 0x31, 0x35, 0x6E, 0x33, 0x6B, 0x66, 0x73, 0x6D, 0x55, 0x6A, 0x78, ++ 0x70, 0x4B, 0x45, 0x56, 0x2F, 0x71, 0x32, 0x4D, 0x59, 0x6F, 0x34, 0x35, 0x56, 0x55, 0x38, 0x35, 0x46, 0x72, 0x6D, 0x78, 0x59, 0x35, 0x33, 0x2F, 0x74, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6F, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, 0x50, ++ 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x0A, 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x53, 0x32, 0x6F, 0x56, 0x51, ++ 0x35, 0x41, 0x73, 0x4F, 0x67, 0x50, 0x34, 0x36, 0x4B, 0x76, 0x50, 0x72, 0x55, 0x2B, 0x42, 0x79, 0x6D, 0x30, 0x54, 0x6F, 0x4F, 0x2F, 0x54, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, ++ 0x43, 0x41, 0x51, 0x59, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x0A, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4E, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x42, 0x41, 0x48, 0x47, 0x6C, 0x44, 0x73, 0x37, 0x6B, 0x36, 0x62, ++ 0x38, 0x2F, 0x4F, 0x4E, 0x57, 0x4A, 0x57, 0x73, 0x51, 0x43, 0x59, 0x66, 0x74, 0x4D, 0x78, 0x52, 0x51, 0x58, 0x4C, 0x59, 0x74, 0x50, 0x55, 0x32, 0x73, 0x51, 0x46, 0x2F, 0x78, 0x6C, 0x68, 0x4D, 0x63, 0x51, 0x53, 0x5A, 0x44, 0x65, 0x32, 0x38, ++ 0x63, 0x6D, 0x6B, 0x34, 0x67, 0x6D, 0x62, 0x33, 0x44, 0x57, 0x0A, 0x41, 0x6C, 0x34, 0x35, 0x6F, 0x50, 0x65, 0x50, 0x71, 0x35, 0x61, 0x31, 0x70, 0x52, 0x4E, 0x63, 0x67, 0x52, 0x52, 0x74, 0x44, 0x6F, 0x47, 0x43, 0x45, 0x52, 0x75, 0x4B, 0x54, ++ 0x73, 0x5A, 0x50, 0x70, 0x64, 0x31, 0x69, 0x48, 0x6B, 0x54, 0x66, 0x43, 0x56, 0x6E, 0x30, 0x57, 0x33, 0x63, 0x4C, 0x4E, 0x2B, 0x6D, 0x4C, 0x49, 0x4D, 0x62, 0x34, 0x43, 0x6B, 0x34, 0x75, 0x57, 0x42, 0x7A, 0x72, 0x4D, 0x39, 0x44, 0x50, 0x68, ++ 0x6D, 0x44, 0x4A, 0x32, 0x76, 0x75, 0x41, 0x0A, 0x4C, 0x35, 0x35, 0x4D, 0x59, 0x49, 0x52, 0x34, 0x50, 0x53, 0x46, 0x6B, 0x31, 0x76, 0x74, 0x42, 0x48, 0x78, 0x67, 0x50, 0x35, 0x38, 0x6C, 0x31, 0x63, 0x62, 0x32, 0x39, 0x58, 0x4E, 0x34, 0x30, ++ 0x68, 0x7A, 0x35, 0x42, 0x73, 0x41, 0x37, 0x32, 0x75, 0x64, 0x59, 0x2F, 0x43, 0x52, 0x4F, 0x57, 0x46, 0x43, 0x2F, 0x65, 0x6D, 0x68, 0x31, 0x61, 0x75, 0x56, 0x62, 0x4F, 0x4E, 0x54, 0x71, 0x77, 0x58, 0x33, 0x42, 0x4E, 0x58, 0x75, 0x4D, 0x70, ++ 0x38, 0x53, 0x4D, 0x6F, 0x0A, 0x63, 0x6C, 0x6D, 0x32, 0x71, 0x38, 0x4B, 0x4D, 0x5A, 0x69, 0x59, 0x63, 0x64, 0x79, 0x77, 0x6D, 0x64, 0x6A, 0x57, 0x4C, 0x4B, 0x4B, 0x64, 0x70, 0x6F, 0x50, 0x6B, 0x37, 0x39, 0x53, 0x50, 0x64, 0x68, 0x52, 0x42, ++ 0x30, 0x79, 0x5A, 0x41, 0x44, 0x56, 0x70, 0x48, 0x6E, 0x72, 0x37, 0x70, 0x48, 0x31, 0x42, 0x4B, 0x58, 0x45, 0x53, 0x4C, 0x6A, 0x6F, 0x6B, 0x6D, 0x55, 0x62, 0x4F, 0x65, 0x33, 0x6C, 0x45, 0x75, 0x36, 0x4C, 0x61, 0x54, 0x61, 0x4D, 0x34, 0x74, ++ 0x4D, 0x0A, 0x70, 0x6B, 0x54, 0x2F, 0x57, 0x6A, 0x7A, 0x47, 0x48, 0x57, 0x54, 0x59, 0x74, 0x54, 0x48, 0x6B, 0x70, 0x6A, 0x78, 0x36, 0x71, 0x46, 0x63, 0x4C, 0x32, 0x2B, 0x31, 0x68, 0x47, 0x73, 0x76, 0x78, 0x7A, 0x6E, 0x4E, 0x33, 0x59, 0x36, ++ 0x53, 0x48, 0x62, 0x30, 0x78, 0x52, 0x4F, 0x4E, 0x62, 0x6B, 0x58, 0x38, 0x65, 0x66, 0x74, 0x6F, 0x45, 0x71, 0x35, 0x49, 0x56, 0x49, 0x65, 0x56, 0x68, 0x65, 0x4F, 0x2F, 0x6A, 0x62, 0x41, 0x6F, 0x4A, 0x6E, 0x77, 0x54, 0x6E, 0x62, 0x0A, 0x77, ++ 0x33, 0x52, 0x4C, 0x50, 0x54, 0x59, 0x65, 0x2B, 0x53, 0x6D, 0x54, 0x69, 0x47, 0x68, 0x62, 0x71, 0x45, 0x51, 0x5A, 0x49, 0x66, 0x43, 0x6E, 0x36, 0x49, 0x45, 0x4E, 0x4C, 0x4F, 0x69, 0x54, 0x4E, 0x72, 0x51, 0x33, 0x73, 0x73, 0x71, 0x77, 0x47, ++ 0x79, 0x5A, 0x36, 0x6D, 0x69, 0x55, 0x66, 0x6D, 0x70, 0x71, 0x41, 0x6E, 0x6B, 0x73, 0x71, 0x50, 0x2F, 0x75, 0x6A, 0x6D, 0x76, 0x35, 0x7A, 0x4D, 0x6E, 0x48, 0x43, 0x6E, 0x73, 0x5A, 0x79, 0x34, 0x59, 0x70, 0x6F, 0x0A, 0x4A, 0x2F, 0x48, 0x6B, ++ 0x44, 0x37, 0x54, 0x45, 0x54, 0x4B, 0x56, 0x68, 0x6B, 0x2F, 0x69, 0x58, 0x45, 0x41, 0x63, 0x71, 0x4D, 0x43, 0x57, 0x70, 0x75, 0x63, 0x68, 0x78, 0x75, 0x4F, 0x39, 0x6F, 0x7A, 0x43, 0x31, 0x2B, 0x39, 0x65, 0x42, 0x2B, 0x44, 0x34, 0x4B, 0x6F, ++ 0x62, 0x37, 0x61, 0x36, 0x62, 0x49, 0x4E, 0x44, 0x64, 0x38, 0x32, 0x4B, 0x6B, 0x68, 0x65, 0x68, 0x6E, 0x6C, 0x74, 0x34, 0x46, 0x6A, 0x31, 0x46, 0x34, 0x6A, 0x4E, 0x79, 0x33, 0x65, 0x46, 0x6D, 0x0A, 0x79, 0x70, 0x6E, 0x54, 0x79, 0x63, 0x55, ++ 0x6D, 0x2F, 0x51, 0x31, 0x6F, 0x42, 0x45, 0x61, 0x75, 0x74, 0x74, 0x6D, 0x62, 0x6A, 0x4C, 0x34, 0x5A, 0x76, 0x72, 0x48, 0x47, 0x38, 0x68, 0x6E, 0x6A, 0x58, 0x41, 0x4C, 0x4B, 0x4C, 0x4E, 0x68, 0x76, 0x53, 0x67, 0x66, 0x5A, 0x79, 0x54, 0x58, ++ 0x61, 0x51, 0x48, 0x58, 0x79, 0x78, 0x4B, 0x63, 0x5A, 0x62, 0x35, 0x35, 0x43, 0x45, 0x4A, 0x68, 0x31, 0x35, 0x70, 0x57, 0x4C, 0x59, 0x4C, 0x7A, 0x74, 0x78, 0x52, 0x4C, 0x58, 0x0A, 0x69, 0x73, 0x37, 0x56, 0x6D, 0x46, 0x78, 0x57, 0x6C, 0x67, ++ 0x50, 0x46, 0x37, 0x6E, 0x63, 0x47, 0x4E, 0x66, 0x2F, 0x50, 0x35, 0x4F, 0x34, 0x2F, 0x45, 0x32, 0x48, 0x75, 0x32, 0x39, 0x6F, 0x74, 0x68, 0x66, 0x44, 0x4E, 0x72, 0x70, 0x32, 0x79, 0x47, 0x41, 0x6C, 0x46, 0x77, 0x35, 0x4B, 0x68, 0x63, 0x68, ++ 0x66, 0x38, 0x52, 0x37, 0x61, 0x67, 0x43, 0x79, 0x7A, 0x78, 0x78, 0x4E, 0x35, 0x44, 0x61, 0x41, 0x68, 0x71, 0x58, 0x7A, 0x76, 0x77, 0x64, 0x6D, 0x50, 0x37, 0x0A, 0x7A, 0x41, 0x59, 0x73, 0x70, 0x73, 0x62, 0x69, 0x44, 0x72, 0x57, 0x35, 0x76, ++ 0x69, 0x53, 0x50, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, 0x69, 0x63, 0x20, ++ 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, ++ 0x41, 0x20, 0x32, 0x30, 0x31, 0x35, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, ++ 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x47, 0x43, 0x7A, 0x43, 0x43, 0x41, 0x2F, 0x4F, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x42, 0x41, 0x44, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, ++ 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x43, 0x42, 0x70, 0x6A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x52, 0x31, 0x49, 0x78, 0x44, 0x7A, 0x41, 0x4E, 0x42, ++ 0x67, 0x4E, 0x56, 0x42, 0x41, 0x63, 0x54, 0x0A, 0x42, 0x6B, 0x46, 0x30, 0x61, 0x47, 0x56, 0x75, 0x63, 0x7A, 0x46, 0x45, 0x4D, 0x45, 0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x37, 0x53, 0x47, 0x56, 0x73, 0x62, 0x47, 0x56, 0x75, ++ 0x61, 0x57, 0x4D, 0x67, 0x51, 0x57, 0x4E, 0x68, 0x5A, 0x47, 0x56, 0x74, 0x61, 0x57, 0x4D, 0x67, 0x59, 0x57, 0x35, 0x6B, 0x49, 0x46, 0x4A, 0x6C, 0x63, 0x32, 0x56, 0x68, 0x63, 0x6D, 0x4E, 0x6F, 0x49, 0x45, 0x6C, 0x75, 0x63, 0x33, 0x52, 0x70, ++ 0x64, 0x48, 0x56, 0x30, 0x0A, 0x61, 0x57, 0x39, 0x75, 0x63, 0x79, 0x42, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x4C, 0x69, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6F, 0x62, 0x33, 0x4A, 0x70, 0x64, 0x48, 0x6B, 0x78, 0x51, 0x44, 0x41, 0x2B, 0x42, 0x67, 0x4E, ++ 0x56, 0x42, 0x41, 0x4D, 0x54, 0x4E, 0x30, 0x68, 0x6C, 0x62, 0x47, 0x78, 0x6C, 0x62, 0x6D, 0x6C, 0x6A, 0x49, 0x45, 0x46, 0x6A, 0x59, 0x57, 0x52, 0x6C, 0x62, 0x57, 0x6C, 0x6A, 0x49, 0x47, 0x46, 0x75, 0x5A, 0x43, 0x42, 0x53, 0x5A, 0x58, 0x4E, ++ 0x6C, 0x0A, 0x59, 0x58, 0x4A, 0x6A, 0x61, 0x43, 0x42, 0x4A, 0x62, 0x6E, 0x4E, 0x30, 0x61, 0x58, 0x52, 0x31, 0x64, 0x47, 0x6C, 0x76, 0x62, 0x6E, 0x4D, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x45, 0x4E, 0x42, 0x49, 0x44, 0x49, 0x77, 0x4D, 0x54, ++ 0x55, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x54, 0x55, 0x77, 0x4E, 0x7A, 0x41, 0x33, 0x4D, 0x54, 0x41, 0x78, 0x4D, 0x54, 0x49, 0x78, 0x57, 0x68, 0x63, 0x4E, 0x4E, 0x44, 0x41, 0x77, 0x4E, 0x6A, 0x4D, 0x77, 0x4D, 0x54, 0x41, 0x78, 0x0A, 0x4D, ++ 0x54, 0x49, 0x78, 0x57, 0x6A, 0x43, 0x42, 0x70, 0x6A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x52, 0x31, 0x49, 0x78, 0x44, 0x7A, 0x41, 0x4E, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x63, 0x54, 0x42, ++ 0x6B, 0x46, 0x30, 0x61, 0x47, 0x56, 0x75, 0x63, 0x7A, 0x46, 0x45, 0x4D, 0x45, 0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x37, 0x53, 0x47, 0x56, 0x73, 0x62, 0x47, 0x56, 0x75, 0x61, 0x57, 0x4D, 0x67, 0x0A, 0x51, 0x57, 0x4E, 0x68, ++ 0x5A, 0x47, 0x56, 0x74, 0x61, 0x57, 0x4D, 0x67, 0x59, 0x57, 0x35, 0x6B, 0x49, 0x46, 0x4A, 0x6C, 0x63, 0x32, 0x56, 0x68, 0x63, 0x6D, 0x4E, 0x6F, 0x49, 0x45, 0x6C, 0x75, 0x63, 0x33, 0x52, 0x70, 0x64, 0x48, 0x56, 0x30, 0x61, 0x57, 0x39, 0x75, ++ 0x63, 0x79, 0x42, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x4C, 0x69, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6F, 0x62, 0x33, 0x4A, 0x70, 0x64, 0x48, 0x6B, 0x78, 0x51, 0x44, 0x41, 0x2B, 0x42, 0x67, 0x4E, 0x56, 0x0A, 0x42, 0x41, 0x4D, 0x54, 0x4E, 0x30, 0x68, ++ 0x6C, 0x62, 0x47, 0x78, 0x6C, 0x62, 0x6D, 0x6C, 0x6A, 0x49, 0x45, 0x46, 0x6A, 0x59, 0x57, 0x52, 0x6C, 0x62, 0x57, 0x6C, 0x6A, 0x49, 0x47, 0x46, 0x75, 0x5A, 0x43, 0x42, 0x53, 0x5A, 0x58, 0x4E, 0x6C, 0x59, 0x58, 0x4A, 0x6A, 0x61, 0x43, 0x42, ++ 0x4A, 0x62, 0x6E, 0x4E, 0x30, 0x61, 0x58, 0x52, 0x31, 0x64, 0x47, 0x6C, 0x76, 0x62, 0x6E, 0x4D, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x45, 0x4E, 0x42, 0x49, 0x44, 0x49, 0x77, 0x0A, 0x4D, 0x54, 0x55, 0x77, 0x67, 0x67, 0x49, 0x69, 0x4D, 0x41, ++ 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x44, 0x43, 0x2B, 0x4B, ++ 0x6B, 0x2F, 0x47, 0x34, 0x6E, 0x38, 0x50, 0x44, 0x77, 0x45, 0x58, 0x54, 0x32, 0x51, 0x4E, 0x72, 0x43, 0x52, 0x4F, 0x6E, 0x6B, 0x38, 0x5A, 0x6C, 0x72, 0x76, 0x0A, 0x62, 0x54, 0x6B, 0x42, 0x53, 0x52, 0x71, 0x30, 0x74, 0x38, 0x39, 0x2F, 0x54, ++ 0x53, 0x4E, 0x54, 0x74, 0x35, 0x41, 0x41, 0x34, 0x78, 0x4D, 0x71, 0x4B, 0x4B, 0x59, 0x78, 0x38, 0x5A, 0x45, 0x41, 0x34, 0x79, 0x6A, 0x73, 0x72, 0x69, 0x46, 0x42, 0x7A, 0x68, 0x2F, 0x61, 0x2F, 0x58, 0x30, 0x53, 0x57, 0x77, 0x47, 0x44, 0x44, ++ 0x37, 0x6D, 0x77, 0x58, 0x35, 0x6E, 0x68, 0x38, 0x68, 0x4B, 0x44, 0x67, 0x45, 0x30, 0x47, 0x50, 0x74, 0x2B, 0x73, 0x72, 0x2B, 0x65, 0x68, 0x0A, 0x69, 0x47, 0x73, 0x78, 0x72, 0x2F, 0x43, 0x4C, 0x30, 0x42, 0x67, 0x7A, 0x75, 0x4E, 0x74, 0x46, ++ 0x61, 0x6A, 0x54, 0x30, 0x41, 0x6F, 0x41, 0x6B, 0x4B, 0x41, 0x6F, 0x43, 0x46, 0x5A, 0x56, 0x65, 0x64, 0x69, 0x6F, 0x4E, 0x6D, 0x54, 0x6F, 0x55, 0x57, 0x2F, 0x62, 0x4C, 0x79, 0x31, 0x4F, 0x38, 0x45, 0x30, 0x30, 0x42, 0x69, 0x44, 0x65, 0x55, ++ 0x4A, 0x52, 0x74, 0x43, 0x76, 0x43, 0x4C, 0x59, 0x6A, 0x71, 0x4F, 0x57, 0x58, 0x6A, 0x72, 0x5A, 0x4D, 0x74, 0x73, 0x2B, 0x0A, 0x36, 0x50, 0x41, 0x51, 0x5A, 0x65, 0x31, 0x30, 0x34, 0x53, 0x2B, 0x6E, 0x66, 0x4B, 0x38, 0x6E, 0x4E, 0x4C, 0x73, ++ 0x70, 0x66, 0x5A, 0x75, 0x32, 0x7A, 0x77, 0x6E, 0x49, 0x35, 0x64, 0x4D, 0x4B, 0x2F, 0x49, 0x68, 0x6C, 0x5A, 0x58, 0x51, 0x4B, 0x33, 0x48, 0x4D, 0x63, 0x58, 0x4D, 0x31, 0x41, 0x73, 0x52, 0x7A, 0x55, 0x74, 0x6F, 0x53, 0x4D, 0x54, 0x46, 0x44, ++ 0x50, 0x61, 0x49, 0x36, 0x6F, 0x57, 0x61, 0x37, 0x43, 0x4A, 0x30, 0x36, 0x43, 0x6F, 0x6A, 0x58, 0x64, 0x0A, 0x46, 0x50, 0x51, 0x66, 0x2F, 0x37, 0x4A, 0x33, 0x31, 0x59, 0x63, 0x76, 0x71, 0x6D, 0x35, 0x39, 0x4A, 0x43, 0x66, 0x6E, 0x78, 0x73, ++ 0x73, 0x6D, 0x35, 0x75, 0x58, 0x2B, 0x5A, 0x77, 0x64, 0x6A, 0x32, 0x45, 0x55, 0x4E, 0x33, 0x54, 0x70, 0x5A, 0x5A, 0x54, 0x6C, 0x59, 0x65, 0x70, 0x4B, 0x5A, 0x63, 0x6A, 0x32, 0x63, 0x68, 0x46, 0x36, 0x49, 0x49, 0x62, 0x6A, 0x56, 0x39, 0x43, ++ 0x7A, 0x38, 0x32, 0x58, 0x42, 0x53, 0x54, 0x33, 0x69, 0x34, 0x76, 0x54, 0x77, 0x72, 0x0A, 0x69, 0x35, 0x57, 0x59, 0x39, 0x62, 0x50, 0x52, 0x61, 0x4D, 0x38, 0x67, 0x46, 0x48, 0x35, 0x4D, 0x58, 0x46, 0x2F, 0x6E, 0x69, 0x2B, 0x58, 0x31, 0x4E, ++ 0x59, 0x45, 0x5A, 0x4E, 0x39, 0x63, 0x52, 0x43, 0x4C, 0x64, 0x6D, 0x76, 0x74, 0x4E, 0x4B, 0x7A, 0x6F, 0x4E, 0x58, 0x41, 0x44, 0x72, 0x44, 0x67, 0x66, 0x67, 0x58, 0x79, 0x35, 0x49, 0x32, 0x58, 0x64, 0x47, 0x6A, 0x32, 0x48, 0x55, 0x62, 0x34, ++ 0x59, 0x73, 0x6E, 0x36, 0x6E, 0x70, 0x49, 0x51, 0x66, 0x31, 0x46, 0x0A, 0x47, 0x51, 0x61, 0x74, 0x4A, 0x35, 0x6C, 0x4F, 0x77, 0x58, 0x42, 0x48, 0x33, 0x62, 0x57, 0x66, 0x67, 0x56, 0x4D, 0x53, 0x35, 0x62, 0x47, 0x4D, 0x53, 0x46, 0x30, 0x78, ++ 0x51, 0x78, 0x66, 0x6A, 0x6A, 0x4D, 0x5A, 0x36, 0x59, 0x35, 0x5A, 0x4C, 0x4B, 0x54, 0x42, 0x4F, 0x68, 0x45, 0x35, 0x69, 0x47, 0x56, 0x34, 0x38, 0x7A, 0x70, 0x65, 0x51, 0x70, 0x58, 0x38, 0x42, 0x36, 0x35, 0x33, 0x67, 0x2B, 0x49, 0x75, 0x4A, ++ 0x33, 0x53, 0x57, 0x59, 0x50, 0x5A, 0x4B, 0x32, 0x0A, 0x66, 0x75, 0x2F, 0x5A, 0x38, 0x56, 0x46, 0x52, 0x66, 0x53, 0x30, 0x6D, 0x79, 0x47, 0x6C, 0x5A, 0x59, 0x65, 0x43, 0x73, 0x61, 0x72, 0x67, 0x71, 0x4E, 0x68, 0x45, 0x45, 0x65, 0x6C, 0x43, ++ 0x39, 0x4D, 0x6F, 0x53, 0x2B, 0x4C, 0x39, 0x78, 0x79, 0x31, 0x64, 0x63, 0x64, 0x46, 0x6B, 0x66, 0x6B, 0x52, 0x32, 0x59, 0x67, 0x50, 0x2F, 0x53, 0x57, 0x78, 0x61, 0x2B, 0x4F, 0x41, 0x58, 0x71, 0x6C, 0x44, 0x33, 0x70, 0x6B, 0x39, 0x51, 0x30, ++ 0x59, 0x68, 0x39, 0x6D, 0x75, 0x0A, 0x69, 0x4E, 0x58, 0x36, 0x68, 0x4D, 0x45, 0x36, 0x77, 0x47, 0x6B, 0x6F, 0x4C, 0x66, 0x49, 0x4E, 0x61, 0x46, 0x47, 0x71, 0x34, 0x36, 0x56, 0x33, 0x78, 0x71, 0x53, 0x51, 0x44, 0x71, 0x45, 0x33, 0x69, 0x7A, ++ 0x45, 0x6A, 0x52, 0x38, 0x45, 0x4A, 0x43, 0x4F, 0x74, 0x75, 0x39, 0x33, 0x69, 0x62, 0x31, 0x34, 0x4C, 0x38, 0x68, 0x43, 0x43, 0x5A, 0x53, 0x52, 0x6D, 0x32, 0x45, 0x6B, 0x61, 0x78, 0x2B, 0x30, 0x56, 0x56, 0x46, 0x71, 0x6D, 0x6A, 0x5A, 0x61, ++ 0x79, 0x63, 0x0A, 0x42, 0x77, 0x2F, 0x71, 0x61, 0x39, 0x77, 0x66, 0x4C, 0x67, 0x5A, 0x79, 0x37, 0x49, 0x61, 0x49, 0x45, 0x75, 0x51, 0x74, 0x32, 0x31, 0x38, 0x46, 0x4C, 0x2B, 0x54, 0x77, 0x41, 0x39, 0x4D, 0x6D, 0x4D, 0x2B, 0x65, 0x41, 0x77, ++ 0x73, 0x31, 0x43, 0x6F, 0x52, 0x63, 0x30, 0x43, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6F, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x0A, ++ 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, ++ 0x63, 0x52, 0x56, 0x6E, 0x79, 0x4D, 0x6A, 0x4A, 0x76, 0x58, 0x56, 0x64, 0x63, 0x74, 0x41, 0x34, 0x47, 0x47, 0x71, 0x64, 0x38, 0x33, 0x45, 0x6B, 0x56, 0x41, 0x73, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x0A, 0x68, 0x76, 0x63, ++ 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x42, 0x41, 0x48, 0x57, 0x37, 0x62, 0x56, 0x52, 0x4C, 0x71, 0x68, 0x42, 0x59, 0x52, 0x6A, 0x54, 0x79, 0x59, 0x74, 0x63, 0x57, 0x4E, 0x6C, 0x30, 0x49, 0x58, 0x74, 0x56, ++ 0x73, 0x79, 0x49, 0x65, 0x39, 0x74, 0x43, 0x35, 0x47, 0x38, 0x6A, 0x48, 0x34, 0x66, 0x4F, 0x70, 0x43, 0x74, 0x5A, 0x4D, 0x57, 0x56, 0x64, 0x79, 0x68, 0x44, 0x42, 0x4B, 0x67, 0x32, 0x6D, 0x46, 0x2B, 0x0A, 0x44, 0x31, 0x68, 0x59, 0x63, 0x32, ++ 0x52, 0x79, 0x78, 0x2B, 0x68, 0x46, 0x6A, 0x74, 0x79, 0x70, 0x38, 0x69, 0x59, 0x2F, 0x78, 0x6E, 0x6D, 0x4D, 0x73, 0x56, 0x4D, 0x49, 0x4D, 0x34, 0x47, 0x77, 0x56, 0x68, 0x4F, 0x2B, 0x35, 0x6C, 0x46, 0x63, 0x32, 0x4A, 0x73, 0x4B, 0x54, 0x30, ++ 0x75, 0x63, 0x56, 0x6C, 0x4D, 0x43, 0x36, 0x55, 0x2F, 0x32, 0x44, 0x57, 0x44, 0x71, 0x54, 0x55, 0x4A, 0x56, 0x36, 0x48, 0x77, 0x62, 0x49, 0x53, 0x48, 0x54, 0x47, 0x7A, 0x72, 0x4D, 0x0A, 0x64, 0x2F, 0x4B, 0x34, 0x6B, 0x50, 0x46, 0x6F, 0x78, ++ 0x2F, 0x6C, 0x61, 0x2F, 0x76, 0x6F, 0x74, 0x39, 0x4C, 0x2F, 0x4A, 0x39, 0x55, 0x55, 0x62, 0x7A, 0x6A, 0x67, 0x51, 0x4B, 0x6A, 0x65, 0x4B, 0x65, 0x61, 0x4F, 0x30, 0x34, 0x77, 0x6C, 0x73, 0x68, 0x59, 0x61, 0x54, 0x2F, 0x34, 0x6D, 0x57, 0x4A, ++ 0x33, 0x69, 0x42, 0x6A, 0x32, 0x66, 0x6A, 0x52, 0x6E, 0x52, 0x55, 0x6A, 0x74, 0x6B, 0x4E, 0x61, 0x65, 0x4A, 0x4B, 0x39, 0x45, 0x31, 0x30, 0x41, 0x2F, 0x2B, 0x79, 0x0A, 0x64, 0x2B, 0x32, 0x56, 0x5A, 0x35, 0x66, 0x6B, 0x73, 0x63, 0x57, 0x72, ++ 0x76, 0x32, 0x6F, 0x6A, 0x36, 0x4E, 0x53, 0x55, 0x34, 0x6B, 0x51, 0x6F, 0x59, 0x73, 0x52, 0x4C, 0x34, 0x76, 0x44, 0x59, 0x34, 0x69, 0x6C, 0x72, 0x47, 0x6E, 0x42, 0x2B, 0x4A, 0x47, 0x47, 0x54, 0x65, 0x30, 0x38, 0x44, 0x4D, 0x69, 0x55, 0x4E, ++ 0x52, 0x53, 0x51, 0x72, 0x6C, 0x72, 0x52, 0x47, 0x61, 0x72, 0x39, 0x4B, 0x43, 0x2F, 0x65, 0x61, 0x6A, 0x38, 0x47, 0x73, 0x47, 0x73, 0x56, 0x6E, 0x0A, 0x38, 0x32, 0x38, 0x30, 0x30, 0x76, 0x70, 0x7A, 0x59, 0x34, 0x7A, 0x76, 0x46, 0x72, 0x43, ++ 0x6F, 0x70, 0x45, 0x59, 0x71, 0x2B, 0x4F, 0x73, 0x53, 0x37, 0x48, 0x4B, 0x30, 0x37, 0x2F, 0x67, 0x72, 0x66, 0x6F, 0x78, 0x53, 0x77, 0x49, 0x75, 0x45, 0x56, 0x50, 0x6B, 0x76, 0x50, 0x75, 0x4E, 0x56, 0x71, 0x4E, 0x78, 0x6D, 0x73, 0x64, 0x6E, ++ 0x68, 0x58, 0x39, 0x69, 0x7A, 0x6A, 0x46, 0x6B, 0x30, 0x57, 0x61, 0x53, 0x72, 0x54, 0x32, 0x79, 0x37, 0x48, 0x78, 0x6A, 0x62, 0x0A, 0x64, 0x61, 0x76, 0x59, 0x79, 0x35, 0x4C, 0x4E, 0x6C, 0x44, 0x68, 0x68, 0x44, 0x67, 0x63, 0x47, 0x48, 0x30, ++ 0x74, 0x47, 0x45, 0x50, 0x45, 0x56, 0x76, 0x6F, 0x32, 0x46, 0x58, 0x44, 0x74, 0x4B, 0x4B, 0x34, 0x46, 0x35, 0x44, 0x37, 0x52, 0x70, 0x6E, 0x30, 0x6C, 0x51, 0x6C, 0x30, 0x33, 0x33, 0x44, 0x6C, 0x5A, 0x64, 0x77, 0x4A, 0x56, 0x71, 0x77, 0x6A, ++ 0x62, 0x44, 0x47, 0x32, 0x6A, 0x4A, 0x39, 0x53, 0x72, 0x63, 0x52, 0x35, 0x71, 0x2B, 0x73, 0x73, 0x37, 0x46, 0x0A, 0x4A, 0x65, 0x6A, 0x36, 0x41, 0x37, 0x6E, 0x61, 0x2B, 0x52, 0x5A, 0x75, 0x6B, 0x59, 0x54, 0x31, 0x48, 0x43, 0x6A, 0x49, 0x2F, ++ 0x43, 0x62, 0x4D, 0x31, 0x78, 0x79, 0x51, 0x56, 0x71, 0x64, 0x66, 0x62, 0x7A, 0x6F, 0x45, 0x76, 0x4D, 0x31, 0x34, 0x69, 0x51, 0x75, 0x4F, 0x44, 0x79, 0x2B, 0x6A, 0x71, 0x6B, 0x2B, 0x69, 0x47, 0x78, 0x49, 0x39, 0x46, 0x67, 0x68, 0x41, 0x44, ++ 0x2F, 0x46, 0x47, 0x54, 0x4E, 0x65, 0x71, 0x65, 0x77, 0x6A, 0x42, 0x43, 0x76, 0x56, 0x74, 0x0A, 0x4A, 0x39, 0x34, 0x43, 0x6A, 0x38, 0x72, 0x44, 0x74, 0x53, 0x76, 0x4B, 0x36, 0x65, 0x76, 0x49, 0x49, 0x56, 0x4D, 0x34, 0x70, 0x63, 0x77, 0x37, ++ 0x32, 0x48, 0x63, 0x33, 0x4D, 0x4B, 0x4A, 0x50, 0x32, 0x57, 0x2F, 0x52, 0x38, 0x6B, 0x43, 0x74, 0x51, 0x58, 0x6F, 0x58, 0x78, 0x64, 0x5A, 0x4B, 0x4E, 0x59, 0x6D, 0x33, 0x51, 0x64, 0x56, 0x38, 0x68, 0x6E, 0x39, 0x56, 0x54, 0x59, 0x4E, 0x4B, ++ 0x70, 0x58, 0x4D, 0x67, 0x77, 0x44, 0x71, 0x76, 0x6B, 0x50, 0x47, 0x61, 0x0A, 0x4A, 0x49, 0x37, 0x5A, 0x6A, 0x6E, 0x48, 0x4B, 0x65, 0x37, 0x69, 0x47, 0x32, 0x72, 0x4B, 0x50, 0x6D, 0x54, 0x34, 0x64, 0x45, 0x77, 0x30, 0x53, 0x45, 0x65, 0x37, ++ 0x55, 0x71, 0x2F, 0x44, 0x70, 0x46, 0x58, 0x59, 0x43, 0x35, 0x4F, 0x44, 0x66, 0x71, 0x69, 0x41, 0x65, 0x57, 0x32, 0x47, 0x46, 0x5A, 0x45, 0x43, 0x70, 0x6B, 0x4A, 0x63, 0x4E, 0x72, 0x56, 0x50, 0x53, 0x57, 0x68, 0x32, 0x48, 0x61, 0x67, 0x43, ++ 0x58, 0x5A, 0x57, 0x4B, 0x30, 0x76, 0x6D, 0x39, 0x71, 0x0A, 0x70, 0x2F, 0x55, 0x73, 0x51, 0x75, 0x30, 0x79, 0x72, 0x62, 0x59, 0x68, 0x6E, 0x72, 0x36, 0x38, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, ++ 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, ++ 0x61, 0x72, 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, 0x35, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x77, 0x7A, 0x43, 0x43, 0x41, 0x6B, 0x71, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x42, 0x41, 0x44, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x6A, ++ 0x43, 0x42, 0x71, 0x6A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x52, 0x31, 0x49, 0x78, 0x44, 0x7A, 0x41, 0x4E, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x63, 0x54, 0x42, 0x6B, 0x46, 0x30, 0x0A, 0x61, ++ 0x47, 0x56, 0x75, 0x63, 0x7A, 0x46, 0x45, 0x4D, 0x45, 0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x37, 0x53, 0x47, 0x56, 0x73, 0x62, 0x47, 0x56, 0x75, 0x61, 0x57, 0x4D, 0x67, 0x51, 0x57, 0x4E, 0x68, 0x5A, 0x47, 0x56, 0x74, 0x61, ++ 0x57, 0x4D, 0x67, 0x59, 0x57, 0x35, 0x6B, 0x49, 0x46, 0x4A, 0x6C, 0x63, 0x32, 0x56, 0x68, 0x63, 0x6D, 0x4E, 0x6F, 0x49, 0x45, 0x6C, 0x75, 0x63, 0x33, 0x52, 0x70, 0x64, 0x48, 0x56, 0x30, 0x61, 0x57, 0x39, 0x75, 0x0A, 0x63, 0x79, 0x42, 0x44, ++ 0x5A, 0x58, 0x4A, 0x30, 0x4C, 0x69, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6F, 0x62, 0x33, 0x4A, 0x70, 0x64, 0x48, 0x6B, 0x78, 0x52, 0x44, 0x42, 0x43, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x4F, 0x30, 0x68, 0x6C, 0x62, 0x47, 0x78, 0x6C, ++ 0x62, 0x6D, 0x6C, 0x6A, 0x49, 0x45, 0x46, 0x6A, 0x59, 0x57, 0x52, 0x6C, 0x62, 0x57, 0x6C, 0x6A, 0x49, 0x47, 0x46, 0x75, 0x5A, 0x43, 0x42, 0x53, 0x5A, 0x58, 0x4E, 0x6C, 0x59, 0x58, 0x4A, 0x6A, 0x0A, 0x61, 0x43, 0x42, 0x4A, 0x62, 0x6E, 0x4E, ++ 0x30, 0x61, 0x58, 0x52, 0x31, 0x64, 0x47, 0x6C, 0x76, 0x62, 0x6E, 0x4D, 0x67, 0x52, 0x55, 0x4E, 0x44, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x52, 0x44, 0x51, 0x53, 0x41, 0x79, 0x4D, 0x44, 0x45, 0x31, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x45, ++ 0x31, 0x4D, 0x44, 0x63, 0x77, 0x4E, 0x7A, 0x45, 0x77, 0x4D, 0x7A, 0x63, 0x78, 0x4D, 0x6C, 0x6F, 0x58, 0x44, 0x54, 0x51, 0x77, 0x4D, 0x44, 0x59, 0x7A, 0x4D, 0x44, 0x45, 0x77, 0x0A, 0x4D, 0x7A, 0x63, 0x78, 0x4D, 0x6C, 0x6F, 0x77, 0x67, 0x61, ++ 0x6F, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x64, 0x53, 0x4D, 0x51, 0x38, 0x77, 0x44, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x48, 0x45, 0x77, 0x5A, 0x42, 0x64, 0x47, 0x68, 0x6C, 0x62, 0x6E, ++ 0x4D, 0x78, 0x52, 0x44, 0x42, 0x43, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x4F, 0x30, 0x68, 0x6C, 0x62, 0x47, 0x78, 0x6C, 0x62, 0x6D, 0x6C, 0x6A, 0x0A, 0x49, 0x45, 0x46, 0x6A, 0x59, 0x57, 0x52, 0x6C, 0x62, 0x57, 0x6C, 0x6A, 0x49, ++ 0x47, 0x46, 0x75, 0x5A, 0x43, 0x42, 0x53, 0x5A, 0x58, 0x4E, 0x6C, 0x59, 0x58, 0x4A, 0x6A, 0x61, 0x43, 0x42, 0x4A, 0x62, 0x6E, 0x4E, 0x30, 0x61, 0x58, 0x52, 0x31, 0x64, 0x47, 0x6C, 0x76, 0x62, 0x6E, 0x4D, 0x67, 0x51, 0x32, 0x56, 0x79, 0x64, ++ 0x43, 0x34, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52, 0x35, 0x4D, 0x55, 0x51, 0x77, 0x51, 0x67, 0x59, 0x44, 0x0A, 0x56, 0x51, 0x51, 0x44, 0x45, 0x7A, 0x74, 0x49, 0x5A, 0x57, 0x78, 0x73, 0x5A, 0x57, 0x35, 0x70, ++ 0x59, 0x79, 0x42, 0x42, 0x59, 0x32, 0x46, 0x6B, 0x5A, 0x57, 0x31, 0x70, 0x59, 0x79, 0x42, 0x68, 0x62, 0x6D, 0x51, 0x67, 0x55, 0x6D, 0x56, 0x7A, 0x5A, 0x57, 0x46, 0x79, 0x59, 0x32, 0x67, 0x67, 0x53, 0x57, 0x35, 0x7A, 0x64, 0x47, 0x6C, 0x30, ++ 0x64, 0x58, 0x52, 0x70, 0x62, 0x32, 0x35, 0x7A, 0x49, 0x45, 0x56, 0x44, 0x51, 0x79, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x0A, 0x51, 0x30, 0x45, 0x67, 0x4D, 0x6A, 0x41, 0x78, 0x4E, 0x54, 0x42, 0x32, 0x4D, 0x42, 0x41, 0x47, 0x42, 0x79, 0x71, ++ 0x47, 0x53, 0x4D, 0x34, 0x39, 0x41, 0x67, 0x45, 0x47, 0x42, 0x53, 0x75, 0x42, 0x42, 0x41, 0x41, 0x69, 0x41, 0x32, 0x49, 0x41, 0x42, 0x4A, 0x4B, 0x67, 0x51, 0x65, 0x68, 0x4C, 0x67, 0x6F, 0x52, 0x63, 0x34, 0x76, 0x67, 0x78, 0x45, 0x5A, 0x6D, ++ 0x47, 0x5A, 0x45, 0x34, 0x4A, 0x4A, 0x53, 0x2B, 0x64, 0x51, 0x53, 0x38, 0x4B, 0x72, 0x6A, 0x56, 0x50, 0x0A, 0x64, 0x4A, 0x57, 0x79, 0x55, 0x57, 0x52, 0x72, 0x6A, 0x57, 0x76, 0x6D, 0x50, 0x33, 0x43, 0x56, 0x38, 0x41, 0x56, 0x45, 0x52, 0x36, ++ 0x5A, 0x79, 0x4F, 0x46, 0x42, 0x32, 0x6C, 0x51, 0x4A, 0x61, 0x6A, 0x71, 0x34, 0x6F, 0x6E, 0x76, 0x6B, 0x74, 0x54, 0x70, 0x6E, 0x76, 0x4C, 0x45, 0x68, 0x76, 0x54, 0x43, 0x55, 0x70, 0x36, 0x4E, 0x46, 0x78, 0x57, 0x39, 0x38, 0x64, 0x77, 0x58, ++ 0x55, 0x33, 0x74, 0x4E, 0x66, 0x36, 0x65, 0x33, 0x70, 0x43, 0x6E, 0x47, 0x6F, 0x4B, 0x0A, 0x56, 0x6C, 0x70, 0x38, 0x61, 0x51, 0x75, 0x71, 0x67, 0x41, 0x6B, 0x6B, 0x62, 0x48, 0x37, 0x42, 0x52, 0x71, 0x4E, 0x43, 0x4D, 0x45, 0x41, 0x77, 0x44, ++ 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x41, ++ 0x51, 0x59, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x0A, 0x42, 0x42, 0x59, 0x45, 0x46, 0x4C, 0x51, 0x69, 0x43, 0x34, 0x4B, 0x5A, 0x4A, 0x41, 0x45, 0x4F, 0x6E, 0x4C, 0x76, 0x6B, 0x44, 0x76, 0x32, 0x2F, 0x2B, 0x35, 0x63, 0x67, ++ 0x6B, 0x35, 0x6B, 0x71, 0x4D, 0x41, 0x6F, 0x47, 0x43, 0x43, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x32, 0x63, 0x41, 0x4D, 0x47, 0x51, 0x43, 0x4D, 0x47, 0x66, 0x4F, 0x46, 0x6D, 0x49, 0x34, 0x6F, 0x71, 0x78, 0x69, ++ 0x52, 0x61, 0x65, 0x70, 0x6C, 0x53, 0x54, 0x41, 0x0A, 0x47, 0x69, 0x65, 0x63, 0x4D, 0x6A, 0x76, 0x41, 0x77, 0x4E, 0x57, 0x36, 0x71, 0x65, 0x66, 0x34, 0x42, 0x45, 0x4E, 0x54, 0x68, 0x65, 0x35, 0x53, 0x49, 0x64, 0x36, 0x64, 0x39, 0x53, 0x57, ++ 0x44, 0x50, 0x70, 0x35, 0x59, 0x53, 0x79, 0x2F, 0x58, 0x5A, 0x78, 0x4D, 0x4F, 0x49, 0x51, 0x49, 0x77, 0x42, 0x65, 0x46, 0x31, 0x41, 0x64, 0x35, 0x6F, 0x37, 0x53, 0x6F, 0x66, 0x54, 0x55, 0x77, 0x4A, 0x43, 0x41, 0x33, 0x73, 0x53, 0x36, 0x31, ++ 0x6B, 0x46, 0x79, 0x6A, 0x6E, 0x0A, 0x64, 0x63, 0x35, 0x46, 0x5A, 0x58, 0x49, 0x68, 0x46, 0x38, 0x73, 0x69, 0x51, 0x51, 0x36, 0x4D, 0x45, 0x35, 0x67, 0x34, 0x6D, 0x6C, 0x52, 0x74, 0x6D, 0x38, 0x72, 0x69, 0x66, 0x4F, 0x6F, 0x43, 0x57, 0x43, ++ 0x4B, 0x52, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x49, 0x53, 0x52, 0x47, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, ++ 0x58, 0x31, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, ++ 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x61, 0x7A, 0x43, 0x43, 0x41, 0x31, 0x4F, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x52, 0x41, 0x49, 0x49, 0x51, 0x7A, 0x37, 0x44, 0x53, 0x51, 0x4F, 0x4E, 0x5A, 0x52, 0x47, 0x50, 0x67, ++ 0x75, 0x32, 0x4F, 0x43, 0x69, 0x77, 0x41, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x77, 0x54, 0x7A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, ++ 0x0A, 0x42, 0x68, 0x4D, 0x43, 0x56, 0x56, 0x4D, 0x78, 0x4B, 0x54, 0x41, 0x6E, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x49, 0x45, 0x6C, 0x75, 0x64, 0x47, 0x56, 0x79, 0x62, 0x6D, 0x56, 0x30, 0x49, 0x46, 0x4E, 0x6C, 0x59, 0x33, 0x56, ++ 0x79, 0x61, 0x58, 0x52, 0x35, 0x49, 0x46, 0x4A, 0x6C, 0x63, 0x32, 0x56, 0x68, 0x63, 0x6D, 0x4E, 0x6F, 0x49, 0x45, 0x64, 0x79, 0x62, 0x33, 0x56, 0x77, 0x4D, 0x52, 0x55, 0x77, 0x45, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x0A, 0x45, 0x77, ++ 0x78, 0x4A, 0x55, 0x31, 0x4A, 0x48, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x57, 0x44, 0x45, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x54, 0x55, 0x77, 0x4E, 0x6A, 0x41, 0x30, 0x4D, 0x54, 0x45, 0x77, 0x4E, 0x44, 0x4D, 0x34, 0x57, 0x68, ++ 0x63, 0x4E, 0x4D, 0x7A, 0x55, 0x77, 0x4E, 0x6A, 0x41, 0x30, 0x4D, 0x54, 0x45, 0x77, 0x4E, 0x44, 0x4D, 0x34, 0x57, 0x6A, 0x42, 0x50, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0A, 0x45, 0x77, 0x4A, 0x56, 0x55, ++ 0x7A, 0x45, 0x70, 0x4D, 0x43, 0x63, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x67, 0x53, 0x57, 0x35, 0x30, 0x5A, 0x58, 0x4A, 0x75, 0x5A, 0x58, 0x51, 0x67, 0x55, 0x32, 0x56, 0x6A, 0x64, 0x58, 0x4A, 0x70, 0x64, 0x48, 0x6B, 0x67, 0x55, ++ 0x6D, 0x56, 0x7A, 0x5A, 0x57, 0x46, 0x79, 0x59, 0x32, 0x67, 0x67, 0x52, 0x33, 0x4A, 0x76, 0x64, 0x58, 0x41, 0x78, 0x46, 0x54, 0x41, 0x54, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x0A, 0x44, 0x45, 0x6C, 0x54, 0x55, 0x6B, 0x63, 0x67, ++ 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x59, 0x4D, 0x54, 0x43, 0x43, 0x41, 0x69, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x50, ++ 0x41, 0x44, 0x43, 0x43, 0x41, 0x67, 0x6F, 0x43, 0x67, 0x67, 0x49, 0x42, 0x41, 0x4B, 0x33, 0x6F, 0x4A, 0x48, 0x50, 0x30, 0x46, 0x44, 0x66, 0x7A, 0x6D, 0x35, 0x34, 0x72, 0x0A, 0x56, 0x79, 0x67, 0x63, 0x68, 0x37, 0x37, 0x63, 0x74, 0x39, 0x38, ++ 0x34, 0x6B, 0x49, 0x78, 0x75, 0x50, 0x4F, 0x5A, 0x58, 0x6F, 0x48, 0x6A, 0x33, 0x64, 0x63, 0x4B, 0x69, 0x2F, 0x76, 0x56, 0x71, 0x62, 0x76, 0x59, 0x41, 0x54, 0x79, 0x6A, 0x62, 0x33, 0x6D, 0x69, 0x47, 0x62, 0x45, 0x53, 0x54, 0x74, 0x72, 0x46, ++ 0x6A, 0x2F, 0x52, 0x51, 0x53, 0x61, 0x37, 0x38, 0x66, 0x30, 0x75, 0x6F, 0x78, 0x6D, 0x79, 0x46, 0x2B, 0x30, 0x54, 0x4D, 0x38, 0x75, 0x6B, 0x6A, 0x31, 0x0A, 0x33, 0x58, 0x6E, 0x66, 0x73, 0x37, 0x6A, 0x2F, 0x45, 0x76, 0x45, 0x68, 0x6D, 0x6B, ++ 0x76, 0x42, 0x69, 0x6F, 0x5A, 0x78, 0x61, 0x55, 0x70, 0x6D, 0x5A, 0x6D, 0x79, 0x50, 0x66, 0x6A, 0x78, 0x77, 0x76, 0x36, 0x30, 0x70, 0x49, 0x67, 0x62, 0x7A, 0x35, 0x4D, 0x44, 0x6D, 0x67, 0x4B, 0x37, 0x69, 0x53, 0x34, 0x2B, 0x33, 0x6D, 0x58, ++ 0x36, 0x55, 0x41, 0x35, 0x2F, 0x54, 0x52, 0x35, 0x64, 0x38, 0x6D, 0x55, 0x67, 0x6A, 0x55, 0x2B, 0x67, 0x34, 0x72, 0x6B, 0x38, 0x4B, 0x0A, 0x62, 0x34, 0x4D, 0x75, 0x30, 0x55, 0x6C, 0x58, 0x6A, 0x49, 0x42, 0x30, 0x74, 0x74, 0x6F, 0x76, 0x30, ++ 0x44, 0x69, 0x4E, 0x65, 0x77, 0x4E, 0x77, 0x49, 0x52, 0x74, 0x31, 0x38, 0x6A, 0x41, 0x38, 0x2B, 0x6F, 0x2B, 0x75, 0x33, 0x64, 0x70, 0x6A, 0x71, 0x2B, 0x73, 0x57, 0x54, 0x38, 0x4B, 0x4F, 0x45, 0x55, 0x74, 0x2B, 0x7A, 0x77, 0x76, 0x6F, 0x2F, ++ 0x37, 0x56, 0x33, 0x4C, 0x76, 0x53, 0x79, 0x65, 0x30, 0x72, 0x67, 0x54, 0x42, 0x49, 0x6C, 0x44, 0x48, 0x43, 0x4E, 0x0A, 0x41, 0x79, 0x6D, 0x67, 0x34, 0x56, 0x4D, 0x6B, 0x37, 0x42, 0x50, 0x5A, 0x37, 0x68, 0x6D, 0x2F, 0x45, 0x4C, 0x4E, 0x4B, ++ 0x6A, 0x44, 0x2B, 0x4A, 0x6F, 0x32, 0x46, 0x52, 0x33, 0x71, 0x79, 0x48, 0x42, 0x35, 0x54, 0x30, 0x59, 0x33, 0x48, 0x73, 0x4C, 0x75, 0x4A, 0x76, 0x57, 0x35, 0x69, 0x42, 0x34, 0x59, 0x6C, 0x63, 0x4E, 0x48, 0x6C, 0x73, 0x64, 0x75, 0x38, 0x37, ++ 0x6B, 0x47, 0x4A, 0x35, 0x35, 0x74, 0x75, 0x6B, 0x6D, 0x69, 0x38, 0x6D, 0x78, 0x64, 0x41, 0x51, 0x0A, 0x34, 0x51, 0x37, 0x65, 0x32, 0x52, 0x43, 0x4F, 0x46, 0x76, 0x75, 0x33, 0x39, 0x36, 0x6A, 0x33, 0x78, 0x2B, 0x55, 0x43, 0x42, 0x35, 0x69, ++ 0x50, 0x4E, 0x67, 0x69, 0x56, 0x35, 0x2B, 0x49, 0x33, 0x6C, 0x67, 0x30, 0x32, 0x64, 0x5A, 0x37, 0x37, 0x44, 0x6E, 0x4B, 0x78, 0x48, 0x5A, 0x75, 0x38, 0x41, 0x2F, 0x6C, 0x4A, 0x42, 0x64, 0x69, 0x42, 0x33, 0x51, 0x57, 0x30, 0x4B, 0x74, 0x5A, ++ 0x42, 0x36, 0x61, 0x77, 0x42, 0x64, 0x70, 0x55, 0x4B, 0x44, 0x39, 0x6A, 0x66, 0x0A, 0x31, 0x62, 0x30, 0x53, 0x48, 0x7A, 0x55, 0x76, 0x4B, 0x42, 0x64, 0x73, 0x30, 0x70, 0x6A, 0x42, 0x71, 0x41, 0x6C, 0x6B, 0x64, 0x32, 0x35, 0x48, 0x4E, 0x37, ++ 0x72, 0x4F, 0x72, 0x46, 0x6C, 0x65, 0x61, 0x4A, 0x31, 0x2F, 0x63, 0x74, 0x61, 0x4A, 0x78, 0x51, 0x5A, 0x42, 0x4B, 0x54, 0x35, 0x5A, 0x50, 0x74, 0x30, 0x6D, 0x39, 0x53, 0x54, 0x4A, 0x45, 0x61, 0x64, 0x61, 0x6F, 0x30, 0x78, 0x41, 0x48, 0x30, ++ 0x61, 0x68, 0x6D, 0x62, 0x57, 0x6E, 0x4F, 0x6C, 0x46, 0x75, 0x0A, 0x68, 0x6A, 0x75, 0x65, 0x66, 0x58, 0x4B, 0x6E, 0x45, 0x67, 0x56, 0x34, 0x57, 0x65, 0x30, 0x2B, 0x55, 0x58, 0x67, 0x56, 0x43, 0x77, 0x4F, 0x50, 0x6A, 0x64, 0x41, 0x76, 0x42, ++ 0x62, 0x49, 0x2B, 0x65, 0x30, 0x6F, 0x63, 0x53, 0x33, 0x4D, 0x46, 0x45, 0x76, 0x7A, 0x47, 0x36, 0x75, 0x42, 0x51, 0x45, 0x33, 0x78, 0x44, 0x6B, 0x33, 0x53, 0x7A, 0x79, 0x6E, 0x54, 0x6E, 0x6A, 0x68, 0x38, 0x42, 0x43, 0x4E, 0x41, 0x77, 0x31, ++ 0x46, 0x74, 0x78, 0x4E, 0x72, 0x51, 0x48, 0x0A, 0x75, 0x73, 0x45, 0x77, 0x4D, 0x46, 0x78, 0x49, 0x74, 0x34, 0x49, 0x37, 0x6D, 0x4B, 0x5A, 0x39, 0x59, 0x49, 0x71, 0x69, 0x6F, 0x79, 0x6D, 0x43, 0x7A, 0x4C, 0x71, 0x39, 0x67, 0x77, 0x51, 0x62, ++ 0x6F, 0x6F, 0x4D, 0x44, 0x51, 0x61, 0x48, 0x57, 0x42, 0x66, 0x45, 0x62, 0x77, 0x72, 0x62, 0x77, 0x71, 0x48, 0x79, 0x47, 0x4F, 0x30, 0x61, 0x6F, 0x53, 0x43, 0x71, 0x49, 0x33, 0x48, 0x61, 0x61, 0x64, 0x72, 0x38, 0x66, 0x61, 0x71, 0x55, 0x39, ++ 0x47, 0x59, 0x2F, 0x72, 0x0A, 0x4F, 0x50, 0x4E, 0x6B, 0x33, 0x73, 0x67, 0x72, 0x44, 0x51, 0x6F, 0x6F, 0x2F, 0x2F, 0x66, 0x62, 0x34, 0x68, 0x56, 0x43, 0x31, 0x43, 0x4C, 0x51, 0x4A, 0x31, 0x33, 0x68, 0x65, 0x66, 0x34, 0x59, 0x35, 0x33, 0x43, ++ 0x49, 0x72, 0x55, 0x37, 0x6D, 0x32, 0x59, 0x73, 0x36, 0x78, 0x74, 0x30, 0x6E, 0x55, 0x57, 0x37, 0x2F, 0x76, 0x47, 0x54, 0x31, 0x4D, 0x30, 0x4E, 0x50, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, 0x51, 0x6A, 0x42, 0x41, 0x4D, 0x41, 0x34, ++ 0x47, 0x0A, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6A, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, ++ 0x48, 0x2F, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x52, 0x35, 0x74, 0x46, 0x6E, 0x6D, 0x65, 0x37, 0x62, 0x6C, 0x35, 0x41, 0x46, 0x7A, 0x67, 0x41, 0x69, 0x49, 0x79, 0x42, 0x70, 0x59, 0x0A, 0x39, ++ 0x75, 0x6D, 0x62, 0x62, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x67, 0x45, 0x41, 0x56, 0x52, 0x39, 0x59, 0x71, 0x62, 0x79, 0x79, 0x71, ++ 0x46, 0x44, 0x51, 0x44, 0x4C, 0x48, 0x59, 0x47, 0x6D, 0x6B, 0x67, 0x4A, 0x79, 0x6B, 0x49, 0x72, 0x47, 0x46, 0x31, 0x58, 0x49, 0x70, 0x75, 0x2B, 0x49, 0x4C, 0x6C, 0x61, 0x53, 0x2F, 0x56, 0x39, 0x6C, 0x5A, 0x4C, 0x0A, 0x75, 0x62, 0x68, 0x7A, ++ 0x45, 0x46, 0x6E, 0x54, 0x49, 0x5A, 0x64, 0x2B, 0x35, 0x30, 0x78, 0x78, 0x2B, 0x37, 0x4C, 0x53, 0x59, 0x4B, 0x30, 0x35, 0x71, 0x41, 0x76, 0x71, 0x46, 0x79, 0x46, 0x57, 0x68, 0x66, 0x46, 0x51, 0x44, 0x6C, 0x6E, 0x72, 0x7A, 0x75, 0x42, 0x5A, ++ 0x36, 0x62, 0x72, 0x4A, 0x46, 0x65, 0x2B, 0x47, 0x6E, 0x59, 0x2B, 0x45, 0x67, 0x50, 0x62, 0x6B, 0x36, 0x5A, 0x47, 0x51, 0x33, 0x42, 0x65, 0x62, 0x59, 0x68, 0x74, 0x46, 0x38, 0x47, 0x61, 0x56, 0x0A, 0x30, 0x6E, 0x78, 0x76, 0x77, 0x75, 0x6F, ++ 0x37, 0x37, 0x78, 0x2F, 0x50, 0x79, 0x39, 0x61, 0x75, 0x4A, 0x2F, 0x47, 0x70, 0x73, 0x4D, 0x69, 0x75, 0x2F, 0x58, 0x31, 0x2B, 0x6D, 0x76, 0x6F, 0x69, 0x42, 0x4F, 0x76, 0x2F, 0x32, 0x58, 0x2F, 0x71, 0x6B, 0x53, 0x73, 0x69, 0x73, 0x52, 0x63, ++ 0x4F, 0x6A, 0x2F, 0x4B, 0x4B, 0x4E, 0x46, 0x74, 0x59, 0x32, 0x50, 0x77, 0x42, 0x79, 0x56, 0x53, 0x35, 0x75, 0x43, 0x62, 0x4D, 0x69, 0x6F, 0x67, 0x7A, 0x69, 0x55, 0x77, 0x74, 0x0A, 0x68, 0x44, 0x79, 0x43, 0x33, 0x2B, 0x36, 0x57, 0x56, 0x77, ++ 0x57, 0x36, 0x4C, 0x4C, 0x76, 0x33, 0x78, 0x4C, 0x66, 0x48, 0x54, 0x6A, 0x75, 0x43, 0x76, 0x6A, 0x48, 0x49, 0x49, 0x6E, 0x4E, 0x7A, 0x6B, 0x74, 0x48, 0x43, 0x67, 0x4B, 0x51, 0x35, 0x4F, 0x52, 0x41, 0x7A, 0x49, 0x34, 0x4A, 0x4D, 0x50, 0x4A, ++ 0x2B, 0x47, 0x73, 0x6C, 0x57, 0x59, 0x48, 0x62, 0x34, 0x70, 0x68, 0x6F, 0x77, 0x69, 0x6D, 0x35, 0x37, 0x69, 0x61, 0x7A, 0x74, 0x58, 0x4F, 0x6F, 0x4A, 0x77, 0x0A, 0x54, 0x64, 0x77, 0x4A, 0x78, 0x34, 0x6E, 0x4C, 0x43, 0x67, 0x64, 0x4E, 0x62, ++ 0x4F, 0x68, 0x64, 0x6A, 0x73, 0x6E, 0x76, 0x7A, 0x71, 0x76, 0x48, 0x75, 0x37, 0x55, 0x72, 0x54, 0x6B, 0x58, 0x57, 0x53, 0x74, 0x41, 0x6D, 0x7A, 0x4F, 0x56, 0x79, 0x79, 0x67, 0x68, 0x71, 0x70, 0x5A, 0x58, 0x6A, 0x46, 0x61, 0x48, 0x33, 0x70, ++ 0x4F, 0x33, 0x4A, 0x4C, 0x46, 0x2B, 0x6C, 0x2B, 0x2F, 0x2B, 0x73, 0x4B, 0x41, 0x49, 0x75, 0x76, 0x74, 0x64, 0x37, 0x75, 0x2B, 0x4E, 0x78, 0x0A, 0x65, 0x35, 0x41, 0x57, 0x30, 0x77, 0x64, 0x65, 0x52, 0x6C, 0x4E, 0x38, 0x4E, 0x77, 0x64, 0x43, ++ 0x6A, 0x4E, 0x50, 0x45, 0x6C, 0x70, 0x7A, 0x56, 0x6D, 0x62, 0x55, 0x71, 0x34, 0x4A, 0x55, 0x61, 0x67, 0x45, 0x69, 0x75, 0x54, 0x44, 0x6B, 0x48, 0x7A, 0x73, 0x78, 0x48, 0x70, 0x46, 0x4B, 0x56, 0x4B, 0x37, 0x71, 0x34, 0x2B, 0x36, 0x33, 0x53, ++ 0x4D, 0x31, 0x4E, 0x39, 0x35, 0x52, 0x31, 0x4E, 0x62, 0x64, 0x57, 0x68, 0x73, 0x63, 0x64, 0x43, 0x62, 0x2B, 0x5A, 0x41, 0x0A, 0x4A, 0x7A, 0x56, 0x63, 0x6F, 0x79, 0x69, 0x33, 0x42, 0x34, 0x33, 0x6E, 0x6A, 0x54, 0x4F, 0x51, 0x35, 0x79, 0x4F, ++ 0x66, 0x2B, 0x31, 0x43, 0x63, 0x65, 0x57, 0x78, 0x47, 0x31, 0x62, 0x51, 0x56, 0x73, 0x35, 0x5A, 0x75, 0x66, 0x70, 0x73, 0x4D, 0x6C, 0x6A, 0x71, 0x34, 0x55, 0x69, 0x30, 0x2F, 0x31, 0x6C, 0x76, 0x68, 0x2B, 0x77, 0x6A, 0x43, 0x68, 0x50, 0x34, ++ 0x6B, 0x71, 0x4B, 0x4F, 0x4A, 0x32, 0x71, 0x78, 0x71, 0x34, 0x52, 0x67, 0x71, 0x73, 0x61, 0x68, 0x44, 0x0A, 0x59, 0x56, 0x76, 0x54, 0x48, 0x39, 0x77, 0x37, 0x6A, 0x58, 0x62, 0x79, 0x4C, 0x65, 0x69, 0x4E, 0x64, 0x64, 0x38, 0x58, 0x4D, 0x32, ++ 0x77, 0x39, 0x55, 0x2F, 0x74, 0x37, 0x79, 0x30, 0x46, 0x66, 0x2F, 0x39, 0x79, 0x69, 0x30, 0x47, 0x45, 0x34, 0x34, 0x5A, 0x61, 0x34, 0x72, 0x46, 0x32, 0x4C, 0x4E, 0x39, 0x64, 0x31, 0x31, 0x54, 0x50, 0x41, 0x6D, 0x52, 0x47, 0x75, 0x6E, 0x55, ++ 0x48, 0x42, 0x63, 0x6E, 0x57, 0x45, 0x76, 0x67, 0x4A, 0x42, 0x51, 0x6C, 0x39, 0x6E, 0x0A, 0x4A, 0x45, 0x69, 0x55, 0x30, 0x5A, 0x73, 0x6E, 0x76, 0x67, 0x63, 0x2F, 0x75, 0x62, 0x68, 0x50, 0x67, 0x58, 0x52, 0x52, 0x34, 0x58, 0x71, 0x33, 0x37, ++ 0x5A, 0x30, 0x6A, 0x34, 0x72, 0x37, 0x67, 0x31, 0x53, 0x67, 0x45, 0x45, 0x7A, 0x77, 0x78, 0x41, 0x35, 0x37, 0x64, 0x65, 0x6D, 0x79, 0x50, 0x78, 0x67, 0x63, 0x59, 0x78, 0x6E, 0x2F, 0x65, 0x52, 0x34, 0x34, 0x2F, 0x4B, 0x4A, 0x34, 0x45, 0x42, ++ 0x73, 0x2B, 0x6C, 0x56, 0x44, 0x52, 0x33, 0x76, 0x65, 0x79, 0x4A, 0x0A, 0x6D, 0x2B, 0x6B, 0x58, 0x51, 0x39, 0x39, 0x62, 0x32, 0x31, 0x2F, 0x2B, 0x6A, 0x68, 0x35, 0x58, 0x6F, 0x73, 0x31, 0x41, 0x6E, 0x58, 0x35, 0x69, 0x49, 0x74, 0x72, 0x65, ++ 0x47, 0x43, 0x63, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x41, 0x43, 0x20, 0x52, 0x41, 0x49, 0x5A, 0x20, ++ 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, ++ 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x67, 0x7A, 0x43, 0x43, 0x41, 0x32, 0x75, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x50, 0x58, 0x5A, 0x4F, 0x4E, 0x4D, 0x47, ++ 0x63, 0x32, 0x79, 0x41, 0x59, 0x64, 0x47, 0x73, 0x64, 0x55, 0x68, 0x47, 0x6B, 0x48, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43, 0x77, 0x55, 0x41, 0x4D, 0x44, 0x73, 0x78, 0x43, 0x7A, ++ 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x0A, 0x41, 0x6B, 0x56, 0x54, 0x4D, 0x52, 0x45, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x44, 0x41, 0x68, 0x47, 0x54, 0x6B, 0x31, 0x55, 0x4C, 0x56, 0x4A, 0x44, 0x54, ++ 0x54, 0x45, 0x5A, 0x4D, 0x42, 0x63, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x77, 0x77, 0x51, 0x51, 0x55, 0x4D, 0x67, 0x55, 0x6B, 0x46, 0x4A, 0x57, 0x69, 0x42, 0x47, 0x54, 0x6B, 0x31, 0x55, 0x4C, 0x56, 0x4A, 0x44, 0x54, 0x54, 0x41, 0x65, 0x46, ++ 0x77, 0x30, 0x77, 0x4F, 0x44, 0x45, 0x77, 0x0A, 0x4D, 0x6A, 0x6B, 0x78, 0x4E, 0x54, 0x55, 0x35, 0x4E, 0x54, 0x5A, 0x61, 0x46, 0x77, 0x30, 0x7A, 0x4D, 0x44, 0x41, 0x78, 0x4D, 0x44, 0x45, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x42, 0x61, ++ 0x4D, 0x44, 0x73, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x56, 0x54, 0x4D, 0x52, 0x45, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x44, 0x41, 0x68, 0x47, 0x54, 0x6B, 0x31, 0x55, ++ 0x4C, 0x56, 0x4A, 0x44, 0x0A, 0x54, 0x54, 0x45, 0x5A, 0x4D, 0x42, 0x63, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x77, 0x77, 0x51, 0x51, 0x55, 0x4D, 0x67, 0x55, 0x6B, 0x46, 0x4A, 0x57, 0x69, 0x42, 0x47, 0x54, 0x6B, 0x31, 0x55, 0x4C, 0x56, 0x4A, ++ 0x44, 0x54, 0x54, 0x43, 0x43, 0x41, 0x69, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x67, 0x6F, ++ 0x43, 0x0A, 0x67, 0x67, 0x49, 0x42, 0x41, 0x4C, 0x70, 0x78, 0x67, 0x48, 0x70, 0x4D, 0x68, 0x6D, 0x35, 0x2F, 0x79, 0x42, 0x4E, 0x74, 0x77, 0x4D, 0x5A, 0x39, 0x48, 0x41, 0x43, 0x58, 0x6A, 0x79, 0x77, 0x4D, 0x49, 0x37, 0x73, 0x51, 0x6D, 0x6B, ++ 0x43, 0x70, 0x47, 0x72, 0x65, 0x48, 0x69, 0x50, 0x69, 0x62, 0x56, 0x6D, 0x72, 0x37, 0x35, 0x6E, 0x75, 0x4F, 0x69, 0x35, 0x4B, 0x4F, 0x70, 0x79, 0x56, 0x64, 0x57, 0x52, 0x48, 0x62, 0x4E, 0x69, 0x36, 0x33, 0x55, 0x52, 0x63, 0x66, 0x0A, 0x71, ++ 0x51, 0x67, 0x66, 0x42, 0x42, 0x63, 0x6B, 0x57, 0x4B, 0x6F, 0x33, 0x53, 0x68, 0x6A, 0x66, 0x35, 0x54, 0x6E, 0x55, 0x56, 0x2F, 0x33, 0x58, 0x77, 0x53, 0x79, 0x52, 0x41, 0x5A, 0x48, 0x69, 0x49, 0x74, 0x51, 0x44, 0x77, 0x46, 0x6A, 0x38, 0x64, ++ 0x30, 0x66, 0x73, 0x6A, 0x7A, 0x35, 0x30, 0x51, 0x37, 0x71, 0x73, 0x4E, 0x49, 0x31, 0x4E, 0x4F, 0x48, 0x5A, 0x6E, 0x6A, 0x72, 0x44, 0x49, 0x62, 0x7A, 0x41, 0x7A, 0x57, 0x48, 0x46, 0x63, 0x74, 0x50, 0x56, 0x72, 0x0A, 0x62, 0x74, 0x51, 0x42, ++ 0x55, 0x4C, 0x67, 0x54, 0x66, 0x6D, 0x78, 0x4B, 0x6F, 0x30, 0x6E, 0x52, 0x49, 0x42, 0x6E, 0x75, 0x76, 0x4D, 0x41, 0x70, 0x47, 0x47, 0x57, 0x6E, 0x33, 0x76, 0x37, 0x76, 0x33, 0x51, 0x71, 0x51, 0x49, 0x65, 0x63, 0x61, 0x5A, 0x35, 0x4A, 0x43, ++ 0x45, 0x4A, 0x68, 0x66, 0x54, 0x7A, 0x43, 0x38, 0x50, 0x68, 0x78, 0x46, 0x74, 0x42, 0x44, 0x58, 0x61, 0x45, 0x41, 0x55, 0x77, 0x45, 0x44, 0x36, 0x35, 0x33, 0x63, 0x58, 0x65, 0x75, 0x59, 0x4C, 0x0A, 0x6A, 0x32, 0x56, 0x62, 0x50, 0x4E, 0x6D, ++ 0x61, 0x55, 0x74, 0x75, 0x31, 0x76, 0x5A, 0x35, 0x47, 0x7A, 0x7A, 0x33, 0x72, 0x6B, 0x51, 0x55, 0x43, 0x77, 0x4A, 0x61, 0x79, 0x64, 0x6B, 0x78, 0x4E, 0x45, 0x4A, 0x59, 0x37, 0x6B, 0x76, 0x71, 0x63, 0x66, 0x77, 0x2B, 0x5A, 0x33, 0x37, 0x34, ++ 0x6A, 0x4E, 0x55, 0x55, 0x65, 0x41, 0x6C, 0x7A, 0x2B, 0x74, 0x61, 0x69, 0x62, 0x6D, 0x53, 0x58, 0x61, 0x58, 0x76, 0x4D, 0x69, 0x77, 0x7A, 0x6E, 0x31, 0x35, 0x43, 0x6F, 0x75, 0x0A, 0x30, 0x38, 0x59, 0x66, 0x78, 0x47, 0x79, 0x71, 0x78, 0x52, ++ 0x78, 0x71, 0x41, 0x51, 0x56, 0x4B, 0x4C, 0x39, 0x4C, 0x46, 0x77, 0x61, 0x67, 0x30, 0x4A, 0x6C, 0x31, 0x6D, 0x70, 0x64, 0x49, 0x43, 0x49, 0x66, 0x6B, 0x59, 0x74, 0x77, 0x62, 0x31, 0x54, 0x70, 0x6C, 0x76, 0x71, 0x4B, 0x74, 0x4D, 0x55, 0x65, ++ 0x6A, 0x50, 0x55, 0x42, 0x6A, 0x46, 0x64, 0x38, 0x67, 0x35, 0x43, 0x53, 0x78, 0x4A, 0x6B, 0x6A, 0x4B, 0x5A, 0x71, 0x4C, 0x73, 0x58, 0x46, 0x33, 0x6D, 0x77, 0x0A, 0x57, 0x73, 0x58, 0x6D, 0x6F, 0x38, 0x52, 0x5A, 0x5A, 0x55, 0x63, 0x31, 0x67, ++ 0x31, 0x36, 0x70, 0x36, 0x44, 0x55, 0x4C, 0x6D, 0x62, 0x76, 0x6B, 0x7A, 0x53, 0x44, 0x47, 0x6D, 0x30, 0x6F, 0x47, 0x4F, 0x62, 0x56, 0x6F, 0x2F, 0x43, 0x4B, 0x36, 0x37, 0x6C, 0x57, 0x4D, 0x4B, 0x30, 0x37, 0x71, 0x38, 0x37, 0x48, 0x6A, 0x2F, ++ 0x4C, 0x61, 0x5A, 0x6D, 0x74, 0x56, 0x43, 0x2B, 0x6E, 0x46, 0x4E, 0x43, 0x4D, 0x2B, 0x48, 0x48, 0x6D, 0x70, 0x78, 0x66, 0x66, 0x6E, 0x54, 0x0A, 0x74, 0x4F, 0x6D, 0x6C, 0x63, 0x59, 0x46, 0x37, 0x77, 0x6B, 0x35, 0x48, 0x6C, 0x71, 0x58, 0x32, ++ 0x64, 0x6F, 0x57, 0x6A, 0x4B, 0x49, 0x2F, 0x70, 0x67, 0x47, 0x36, 0x42, 0x55, 0x36, 0x56, 0x74, 0x58, 0x37, 0x68, 0x49, 0x2B, 0x63, 0x4C, 0x35, 0x4E, 0x71, 0x59, 0x75, 0x53, 0x66, 0x2B, 0x34, 0x6C, 0x73, 0x4B, 0x4D, 0x42, 0x37, 0x4F, 0x62, ++ 0x69, 0x46, 0x6A, 0x38, 0x36, 0x78, 0x73, 0x63, 0x33, 0x69, 0x31, 0x77, 0x34, 0x70, 0x65, 0x53, 0x4D, 0x4B, 0x47, 0x4A, 0x0A, 0x34, 0x37, 0x78, 0x56, 0x71, 0x43, 0x66, 0x57, 0x53, 0x2B, 0x32, 0x51, 0x72, 0x59, 0x76, 0x36, 0x59, 0x79, 0x56, ++ 0x5A, 0x4C, 0x61, 0x67, 0x31, 0x33, 0x63, 0x71, 0x58, 0x4D, 0x37, 0x7A, 0x6C, 0x7A, 0x63, 0x65, 0x64, 0x30, 0x65, 0x7A, 0x76, 0x58, 0x67, 0x35, 0x4B, 0x6B, 0x41, 0x59, 0x6D, 0x59, 0x36, 0x32, 0x35, 0x32, 0x54, 0x55, 0x74, 0x42, 0x37, 0x70, ++ 0x32, 0x5A, 0x53, 0x79, 0x73, 0x56, 0x34, 0x39, 0x39, 0x39, 0x41, 0x65, 0x55, 0x31, 0x34, 0x45, 0x43, 0x0A, 0x6C, 0x6C, 0x32, 0x6A, 0x42, 0x30, 0x6E, 0x56, 0x65, 0x74, 0x42, 0x58, 0x2B, 0x52, 0x76, 0x6E, 0x55, 0x30, 0x5A, 0x31, 0x71, 0x72, ++ 0x42, 0x35, 0x51, 0x73, 0x74, 0x6F, 0x63, 0x51, 0x6A, 0x70, 0x59, 0x4C, 0x30, 0x35, 0x61, 0x63, 0x37, 0x30, 0x72, 0x38, 0x4E, 0x57, 0x51, 0x4D, 0x65, 0x74, 0x55, 0x71, 0x49, 0x4A, 0x35, 0x47, 0x2B, 0x47, 0x52, 0x34, 0x6F, 0x66, 0x36, 0x79, ++ 0x67, 0x6E, 0x58, 0x59, 0x4D, 0x67, 0x72, 0x77, 0x54, 0x4A, 0x62, 0x46, 0x61, 0x61, 0x0A, 0x69, 0x30, 0x62, 0x31, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, 0x67, 0x59, 0x4D, 0x77, 0x67, 0x59, 0x41, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, ++ 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x51, 0x59, 0x77, 0x48, ++ 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x0A, 0x46, 0x50, 0x64, 0x39, 0x78, 0x66, 0x33, 0x45, 0x36, 0x4A, 0x6F, 0x62, 0x64, 0x32, 0x53, 0x6E, 0x39, 0x52, 0x32, 0x67, 0x7A, 0x4C, 0x2B, 0x48, 0x59, 0x4A, 0x70, 0x74, ++ 0x4D, 0x44, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x49, 0x41, 0x51, 0x33, 0x4D, 0x44, 0x55, 0x77, 0x4D, 0x77, 0x59, 0x45, 0x56, 0x52, 0x30, 0x67, 0x41, 0x44, 0x41, 0x72, 0x4D, 0x43, 0x6B, 0x47, 0x43, 0x43, 0x73, 0x47, 0x41, 0x51, 0x55, 0x46, ++ 0x42, 0x77, 0x49, 0x42, 0x46, 0x68, 0x31, 0x6F, 0x0A, 0x64, 0x48, 0x52, 0x77, 0x4F, 0x69, 0x38, 0x76, 0x64, 0x33, 0x64, 0x33, 0x4C, 0x6D, 0x4E, 0x6C, 0x63, 0x6E, 0x51, 0x75, 0x5A, 0x6D, 0x35, 0x74, 0x64, 0x43, 0x35, 0x6C, 0x63, 0x79, 0x39, ++ 0x6B, 0x63, 0x47, 0x4E, 0x7A, 0x4C, 0x7A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x67, 0x45, 0x41, 0x42, 0x35, 0x42, 0x4B, 0x33, 0x2F, 0x4D, ++ 0x6A, 0x54, 0x76, 0x44, 0x44, 0x0A, 0x6E, 0x46, 0x46, 0x6C, 0x6D, 0x35, 0x77, 0x69, 0x6F, 0x6F, 0x6F, 0x4D, 0x68, 0x66, 0x4E, 0x7A, 0x4B, 0x57, 0x74, 0x4E, 0x2F, 0x67, 0x48, 0x69, 0x71, 0x51, 0x78, 0x6A, 0x41, 0x62, 0x38, 0x45, 0x5A, 0x36, ++ 0x57, 0x64, 0x6D, 0x46, 0x2F, 0x39, 0x41, 0x52, 0x50, 0x36, 0x37, 0x4A, 0x70, 0x69, 0x36, 0x59, 0x62, 0x2B, 0x74, 0x6D, 0x4C, 0x53, 0x62, 0x6B, 0x79, 0x55, 0x2B, 0x38, 0x42, 0x31, 0x52, 0x58, 0x78, 0x6C, 0x44, 0x50, 0x69, 0x79, 0x4E, 0x38, ++ 0x2B, 0x73, 0x0A, 0x44, 0x38, 0x2B, 0x4E, 0x62, 0x2F, 0x6B, 0x5A, 0x39, 0x34, 0x2F, 0x73, 0x48, 0x76, 0x4A, 0x77, 0x6E, 0x76, 0x44, 0x4B, 0x75, 0x4F, 0x2B, 0x33, 0x2F, 0x33, 0x59, 0x33, 0x64, 0x6C, 0x76, 0x32, 0x62, 0x6F, 0x6A, 0x7A, 0x72, ++ 0x32, 0x49, 0x79, 0x49, 0x70, 0x4D, 0x4E, 0x4F, 0x6D, 0x71, 0x4F, 0x46, 0x47, 0x59, 0x4D, 0x4C, 0x56, 0x4E, 0x30, 0x56, 0x32, 0x55, 0x65, 0x31, 0x62, 0x4C, 0x64, 0x49, 0x34, 0x45, 0x37, 0x70, 0x57, 0x59, 0x6A, 0x4A, 0x32, 0x63, 0x4A, 0x0A, ++ 0x6A, 0x2B, 0x46, 0x33, 0x71, 0x6B, 0x50, 0x4E, 0x5A, 0x56, 0x45, 0x49, 0x37, 0x56, 0x46, 0x59, 0x2F, 0x75, 0x59, 0x35, 0x2B, 0x63, 0x74, 0x48, 0x68, 0x4B, 0x51, 0x56, 0x38, 0x58, 0x61, 0x37, 0x70, 0x4F, 0x36, 0x6B, 0x4F, 0x38, 0x52, 0x66, ++ 0x37, 0x37, 0x49, 0x7A, 0x6C, 0x68, 0x45, 0x59, 0x74, 0x38, 0x6C, 0x6C, 0x76, 0x68, 0x6A, 0x68, 0x6F, 0x36, 0x54, 0x63, 0x2B, 0x68, 0x6A, 0x35, 0x30, 0x37, 0x77, 0x54, 0x6D, 0x7A, 0x6C, 0x36, 0x4E, 0x4C, 0x72, 0x54, 0x0A, 0x51, 0x66, 0x76, ++ 0x36, 0x4D, 0x6F, 0x6F, 0x71, 0x74, 0x79, 0x75, 0x47, 0x43, 0x32, 0x6D, 0x44, 0x4F, 0x4C, 0x37, 0x4E, 0x69, 0x69, 0x34, 0x4C, 0x63, 0x4B, 0x32, 0x4E, 0x4A, 0x70, 0x4C, 0x75, 0x48, 0x76, 0x55, 0x42, 0x4B, 0x77, 0x72, 0x5A, 0x31, 0x70, 0x65, ++ 0x62, 0x62, 0x75, 0x43, 0x6F, 0x47, 0x52, 0x77, 0x36, 0x49, 0x59, 0x73, 0x4D, 0x48, 0x6B, 0x43, 0x74, 0x41, 0x2B, 0x66, 0x64, 0x5A, 0x6E, 0x37, 0x31, 0x75, 0x53, 0x41, 0x4E, 0x41, 0x2B, 0x69, 0x57, 0x0A, 0x2B, 0x59, 0x4A, 0x46, 0x31, 0x44, ++ 0x6E, 0x67, 0x6F, 0x41, 0x42, 0x64, 0x31, 0x35, 0x6A, 0x6D, 0x66, 0x5A, 0x35, 0x6E, 0x63, 0x38, 0x4F, 0x61, 0x4B, 0x76, 0x65, 0x72, 0x69, 0x36, 0x45, 0x36, 0x46, 0x4F, 0x38, 0x30, 0x76, 0x46, 0x49, 0x4F, 0x69, 0x5A, 0x69, 0x61, 0x42, 0x45, ++ 0x43, 0x45, 0x48, 0x58, 0x35, 0x46, 0x61, 0x5A, 0x4E, 0x58, 0x7A, 0x75, 0x76, 0x4F, 0x2B, 0x46, 0x42, 0x38, 0x54, 0x78, 0x78, 0x75, 0x42, 0x45, 0x4F, 0x62, 0x2B, 0x64, 0x59, 0x37, 0x0A, 0x49, 0x78, 0x6A, 0x70, 0x36, 0x6F, 0x37, 0x52, 0x54, ++ 0x55, 0x61, 0x4E, 0x38, 0x54, 0x76, 0x6B, 0x61, 0x73, 0x71, 0x36, 0x2B, 0x79, 0x4F, 0x33, 0x6D, 0x2F, 0x71, 0x5A, 0x41, 0x53, 0x6C, 0x61, 0x57, 0x46, 0x6F, 0x74, 0x34, 0x2F, 0x6E, 0x55, 0x62, 0x51, 0x34, 0x6D, 0x72, 0x63, 0x46, 0x75, 0x4E, ++ 0x4C, 0x77, 0x79, 0x2B, 0x41, 0x77, 0x46, 0x2B, 0x6D, 0x57, 0x6A, 0x32, 0x7A, 0x73, 0x33, 0x67, 0x79, 0x4C, 0x70, 0x31, 0x74, 0x78, 0x79, 0x4D, 0x2F, 0x31, 0x64, 0x0A, 0x38, 0x69, 0x43, 0x39, 0x64, 0x6A, 0x77, 0x6A, 0x32, 0x69, 0x6A, 0x33, ++ 0x2B, 0x52, 0x76, 0x72, 0x57, 0x57, 0x54, 0x56, 0x33, 0x46, 0x39, 0x79, 0x66, 0x69, 0x44, 0x38, 0x7A, 0x59, 0x6D, 0x31, 0x6B, 0x47, 0x64, 0x4E, 0x59, 0x6E, 0x6F, 0x2F, 0x54, 0x71, 0x30, 0x64, 0x77, 0x7A, 0x6E, 0x2B, 0x65, 0x76, 0x51, 0x6F, ++ 0x46, 0x74, 0x39, 0x42, 0x39, 0x6B, 0x69, 0x41, 0x42, 0x64, 0x63, 0x50, 0x55, 0x58, 0x6D, 0x73, 0x45, 0x4B, 0x76, 0x55, 0x37, 0x41, 0x4E, 0x6D, 0x0A, 0x35, 0x6D, 0x71, 0x77, 0x75, 0x6A, 0x47, 0x53, 0x51, 0x6B, 0x42, 0x71, 0x76, 0x6A, 0x72, ++ 0x54, 0x63, 0x75, 0x46, 0x71, 0x4E, 0x31, 0x57, 0x38, 0x72, 0x42, 0x32, 0x56, 0x74, 0x32, 0x6C, 0x68, 0x38, 0x6B, 0x4F, 0x52, 0x64, 0x4F, 0x61, 0x67, 0x30, 0x77, 0x6F, 0x6B, 0x52, 0x71, 0x45, 0x49, 0x72, 0x39, 0x62, 0x61, 0x52, 0x52, 0x6D, ++ 0x57, 0x31, 0x46, 0x4D, 0x64, 0x57, 0x34, 0x52, 0x35, 0x38, 0x4D, 0x44, 0x33, 0x52, 0x2B, 0x2B, 0x4C, 0x6A, 0x38, 0x55, 0x47, 0x0A, 0x72, 0x70, 0x31, 0x4D, 0x59, 0x70, 0x33, 0x2F, 0x52, 0x67, 0x54, 0x34, 0x30, 0x38, 0x6D, 0x32, 0x45, 0x43, ++ 0x56, 0x41, 0x64, 0x66, 0x34, 0x57, 0x71, 0x73, 0x6C, 0x4B, 0x59, 0x49, 0x59, 0x76, 0x75, 0x75, 0x38, 0x77, 0x64, 0x2B, 0x52, 0x55, 0x34, 0x72, 0x69, 0x45, 0x6D, 0x56, 0x69, 0x41, 0x71, 0x68, 0x4F, 0x4C, 0x55, 0x54, 0x70, 0x50, 0x53, 0x50, ++ 0x61, 0x4C, 0x74, 0x72, 0x4D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, ++ 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, ++ 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x44, 0x51, 0x54, 0x43, 0x43, 0x41, 0x69, 0x6D, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x54, 0x42, 0x6D, 0x79, 0x66, ++ 0x7A, 0x35, 0x6D, 0x2F, 0x6A, 0x41, 0x6F, 0x35, 0x34, 0x76, 0x42, 0x34, 0x69, 0x6B, 0x50, 0x6D, 0x6C, 0x6A, 0x5A, 0x62, 0x79, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, ++ 0x41, 0x44, 0x41, 0x35, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x0A, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x50, 0x4D, 0x41, 0x30, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x47, 0x51, 0x57, 0x31, ++ 0x68, 0x65, 0x6D, 0x39, 0x75, 0x4D, 0x52, 0x6B, 0x77, 0x46, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x42, 0x42, 0x62, 0x57, 0x46, 0x36, 0x62, 0x32, 0x34, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x53, 0x41, ++ 0x78, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x45, 0x31, 0x0A, 0x4D, 0x44, 0x55, 0x79, 0x4E, 0x6A, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x46, 0x6F, 0x58, 0x44, 0x54, 0x4D, 0x34, 0x4D, 0x44, 0x45, 0x78, 0x4E, 0x7A, 0x41, 0x77, 0x4D, 0x44, ++ 0x41, 0x77, 0x4D, 0x46, 0x6F, 0x77, 0x4F, 0x54, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x56, 0x56, 0x4D, 0x78, 0x44, 0x7A, 0x41, 0x4E, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x42, 0x6B, ++ 0x46, 0x74, 0x59, 0x58, 0x70, 0x76, 0x0A, 0x62, 0x6A, 0x45, 0x5A, 0x4D, 0x42, 0x63, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x51, 0x51, 0x57, 0x31, 0x68, 0x65, 0x6D, 0x39, 0x75, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, ++ 0x30, 0x45, 0x67, 0x4D, 0x54, 0x43, 0x43, 0x41, 0x53, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, ++ 0x51, 0x6F, 0x43, 0x0A, 0x67, 0x67, 0x45, 0x42, 0x41, 0x4C, 0x4A, 0x34, 0x67, 0x48, 0x48, 0x4B, 0x65, 0x4E, 0x58, 0x6A, 0x63, 0x61, 0x39, 0x48, 0x67, 0x46, 0x42, 0x30, 0x66, 0x57, 0x37, 0x59, 0x31, 0x34, 0x68, 0x32, 0x39, 0x4A, 0x6C, 0x6F, ++ 0x39, 0x31, 0x67, 0x68, 0x59, 0x50, 0x6C, 0x30, 0x68, 0x41, 0x45, 0x76, 0x72, 0x41, 0x49, 0x74, 0x68, 0x74, 0x4F, 0x67, 0x51, 0x33, 0x70, 0x4F, 0x73, 0x71, 0x54, 0x51, 0x4E, 0x72, 0x6F, 0x42, 0x76, 0x6F, 0x33, 0x62, 0x53, 0x4D, 0x67, 0x48, ++ 0x0A, 0x46, 0x7A, 0x5A, 0x4D, 0x39, 0x4F, 0x36, 0x49, 0x49, 0x38, 0x63, 0x2B, 0x36, 0x7A, 0x66, 0x31, 0x74, 0x52, 0x6E, 0x34, 0x53, 0x57, 0x69, 0x77, 0x33, 0x74, 0x65, 0x35, 0x64, 0x6A, 0x67, 0x64, 0x59, 0x5A, 0x36, 0x6B, 0x2F, 0x6F, 0x49, ++ 0x32, 0x70, 0x65, 0x56, 0x4B, 0x56, 0x75, 0x52, 0x46, 0x34, 0x66, 0x6E, 0x39, 0x74, 0x42, 0x62, 0x36, 0x64, 0x4E, 0x71, 0x63, 0x6D, 0x7A, 0x55, 0x35, 0x4C, 0x2F, 0x71, 0x77, 0x49, 0x46, 0x41, 0x47, 0x62, 0x48, 0x72, 0x51, 0x0A, 0x67, 0x4C, ++ 0x4B, 0x6D, 0x2B, 0x61, 0x2F, 0x73, 0x52, 0x78, 0x6D, 0x50, 0x55, 0x44, 0x67, 0x48, 0x33, 0x4B, 0x4B, 0x48, 0x4F, 0x56, 0x6A, 0x34, 0x75, 0x74, 0x57, 0x70, 0x2B, 0x55, 0x68, 0x6E, 0x4D, 0x4A, 0x62, 0x75, 0x6C, 0x48, 0x68, 0x65, 0x62, 0x34, ++ 0x6D, 0x6A, 0x55, 0x63, 0x41, 0x77, 0x68, 0x6D, 0x61, 0x68, 0x52, 0x57, 0x61, 0x36, 0x56, 0x4F, 0x75, 0x6A, 0x77, 0x35, 0x48, 0x35, 0x53, 0x4E, 0x7A, 0x2F, 0x30, 0x65, 0x67, 0x77, 0x4C, 0x58, 0x30, 0x74, 0x0A, 0x64, 0x48, 0x41, 0x31, 0x31, ++ 0x34, 0x67, 0x6B, 0x39, 0x35, 0x37, 0x45, 0x57, 0x57, 0x36, 0x37, 0x63, 0x34, 0x63, 0x58, 0x38, 0x6A, 0x4A, 0x47, 0x4B, 0x4C, 0x68, 0x44, 0x2B, 0x72, 0x63, 0x64, 0x71, 0x73, 0x71, 0x30, 0x38, 0x70, 0x38, 0x6B, 0x44, 0x69, 0x31, 0x4C, 0x39, ++ 0x33, 0x46, 0x63, 0x58, 0x6D, 0x6E, 0x2F, 0x36, 0x70, 0x55, 0x43, 0x79, 0x7A, 0x69, 0x4B, 0x72, 0x6C, 0x41, 0x34, 0x62, 0x39, 0x76, 0x37, 0x4C, 0x57, 0x49, 0x62, 0x78, 0x63, 0x63, 0x65, 0x0A, 0x56, 0x4F, 0x46, 0x33, 0x34, 0x47, 0x66, 0x49, ++ 0x44, 0x35, 0x79, 0x48, 0x49, 0x39, 0x59, 0x2F, 0x51, 0x43, 0x42, 0x2F, 0x49, 0x49, 0x44, 0x45, 0x67, 0x45, 0x77, 0x2B, 0x4F, 0x79, 0x51, 0x6D, 0x6A, 0x67, 0x53, 0x75, 0x62, 0x4A, 0x72, 0x49, 0x71, 0x67, 0x30, 0x43, 0x41, 0x77, 0x45, 0x41, ++ 0x41, 0x61, 0x4E, 0x43, 0x4D, 0x45, 0x41, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x0A, 0x2F, 0x7A, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, ++ 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x59, 0x59, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x46, 0x49, 0x51, 0x59, 0x7A, 0x49, 0x55, 0x30, 0x37, 0x4C, 0x77, 0x4D, 0x6C, 0x4A, 0x51, ++ 0x75, 0x43, 0x46, 0x6D, 0x63, 0x78, 0x37, 0x49, 0x51, 0x54, 0x67, 0x6F, 0x49, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x0A, 0x44, 0x51, 0x45, 0x42, 0x43, 0x77, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x41, 0x51, ++ 0x43, 0x59, 0x38, 0x6A, 0x64, 0x61, 0x51, 0x5A, 0x43, 0x68, 0x47, 0x73, 0x56, 0x32, 0x55, 0x53, 0x67, 0x67, 0x4E, 0x69, 0x4D, 0x4F, 0x72, 0x75, 0x59, 0x6F, 0x75, 0x36, 0x72, 0x34, 0x6C, 0x4B, 0x35, 0x49, 0x70, 0x44, 0x42, 0x2F, 0x47, 0x2F, ++ 0x77, 0x6B, 0x6A, 0x55, 0x75, 0x30, 0x79, 0x4B, 0x47, 0x58, 0x39, 0x72, 0x62, 0x78, 0x65, 0x6E, 0x44, 0x49, 0x55, 0x35, 0x50, 0x4D, 0x0A, 0x43, 0x43, 0x6A, 0x6A, 0x6D, 0x43, 0x58, 0x50, 0x49, 0x36, 0x54, 0x35, 0x33, 0x69, 0x48, 0x54, 0x66, ++ 0x49, 0x55, 0x4A, 0x72, 0x55, 0x36, 0x61, 0x64, 0x54, 0x72, 0x43, 0x43, 0x32, 0x71, 0x4A, 0x65, 0x48, 0x5A, 0x45, 0x52, 0x78, 0x68, 0x6C, 0x62, 0x49, 0x31, 0x42, 0x6A, 0x6A, 0x74, 0x2F, 0x6D, 0x73, 0x76, 0x30, 0x74, 0x61, 0x64, 0x51, 0x31, ++ 0x77, 0x55, 0x73, 0x4E, 0x2B, 0x67, 0x44, 0x53, 0x36, 0x33, 0x70, 0x59, 0x61, 0x41, 0x43, 0x62, 0x76, 0x58, 0x79, 0x0A, 0x38, 0x4D, 0x57, 0x79, 0x37, 0x56, 0x75, 0x33, 0x33, 0x50, 0x71, 0x55, 0x58, 0x48, 0x65, 0x65, 0x45, 0x36, 0x56, 0x2F, ++ 0x55, 0x71, 0x32, 0x56, 0x38, 0x76, 0x69, 0x54, 0x4F, 0x39, 0x36, 0x4C, 0x58, 0x46, 0x76, 0x4B, 0x57, 0x6C, 0x4A, 0x62, 0x59, 0x4B, 0x38, 0x55, 0x39, 0x30, 0x76, 0x76, 0x6F, 0x2F, 0x75, 0x66, 0x51, 0x4A, 0x56, 0x74, 0x4D, 0x56, 0x54, 0x38, ++ 0x51, 0x74, 0x50, 0x48, 0x52, 0x68, 0x38, 0x6A, 0x72, 0x64, 0x6B, 0x50, 0x53, 0x48, 0x43, 0x61, 0x0A, 0x32, 0x58, 0x56, 0x34, 0x63, 0x64, 0x46, 0x79, 0x51, 0x7A, 0x52, 0x31, 0x62, 0x6C, 0x64, 0x5A, 0x77, 0x67, 0x4A, 0x63, 0x4A, 0x6D, 0x41, ++ 0x70, 0x7A, 0x79, 0x4D, 0x5A, 0x46, 0x6F, 0x36, 0x49, 0x51, 0x36, 0x58, 0x55, 0x35, 0x4D, 0x73, 0x49, 0x2B, 0x79, 0x4D, 0x52, 0x51, 0x2B, 0x68, 0x44, 0x4B, 0x58, 0x4A, 0x69, 0x6F, 0x61, 0x6C, 0x64, 0x58, 0x67, 0x6A, 0x55, 0x6B, 0x4B, 0x36, ++ 0x34, 0x32, 0x4D, 0x34, 0x55, 0x77, 0x74, 0x42, 0x56, 0x38, 0x6F, 0x62, 0x32, 0x0A, 0x78, 0x4A, 0x4E, 0x44, 0x64, 0x32, 0x5A, 0x68, 0x77, 0x4C, 0x6E, 0x6F, 0x51, 0x64, 0x65, 0x58, 0x65, 0x47, 0x41, 0x44, 0x62, 0x6B, 0x70, 0x79, 0x72, 0x71, ++ 0x58, 0x52, 0x66, 0x62, 0x6F, 0x51, 0x6E, 0x6F, 0x5A, 0x73, 0x47, 0x34, 0x71, 0x35, 0x57, 0x54, 0x50, 0x34, 0x36, 0x38, 0x53, 0x51, 0x76, 0x76, 0x47, 0x35, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, ++ 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, ++ 0x51, 0x54, 0x43, 0x43, 0x41, 0x79, 0x6D, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x54, 0x42, 0x6D, 0x79, 0x66, 0x30, 0x70, 0x59, 0x31, 0x68, 0x70, 0x38, 0x4B, 0x44, 0x2B, 0x57, 0x47, 0x65, 0x50, 0x68, 0x62, 0x4A, 0x72, 0x75, 0x4B, ++ 0x4E, 0x7A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x77, 0x46, 0x41, 0x44, 0x41, 0x35, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x0A, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, ++ 0x56, 0x55, 0x7A, 0x45, 0x50, 0x4D, 0x41, 0x30, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x47, 0x51, 0x57, 0x31, 0x68, 0x65, 0x6D, 0x39, 0x75, 0x4D, 0x52, 0x6B, 0x77, 0x46, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x42, ++ 0x42, 0x62, 0x57, 0x46, 0x36, 0x62, 0x32, 0x34, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x53, 0x41, 0x79, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x45, 0x31, 0x0A, 0x4D, 0x44, 0x55, 0x79, 0x4E, 0x6A, 0x41, 0x77, 0x4D, 0x44, ++ 0x41, 0x77, 0x4D, 0x46, 0x6F, 0x58, 0x44, 0x54, 0x51, 0x77, 0x4D, 0x44, 0x55, 0x79, 0x4E, 0x6A, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x46, 0x6F, 0x77, 0x4F, 0x54, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, ++ 0x4D, 0x43, 0x56, 0x56, 0x4D, 0x78, 0x44, 0x7A, 0x41, 0x4E, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x42, 0x6B, 0x46, 0x74, 0x59, 0x58, 0x70, 0x76, 0x0A, 0x62, 0x6A, 0x45, 0x5A, 0x4D, 0x42, 0x63, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, ++ 0x78, 0x4D, 0x51, 0x51, 0x57, 0x31, 0x68, 0x65, 0x6D, 0x39, 0x75, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x4D, 0x6A, 0x43, 0x43, 0x41, 0x69, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, ++ 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x67, 0x6F, 0x43, 0x0A, 0x67, 0x67, 0x49, 0x42, 0x41, 0x4B, 0x32, 0x57, 0x6E, 0x79, 0x32, 0x63, 0x53, 0x6B, 0x78, 0x4B, ++ 0x67, 0x58, 0x6C, 0x52, 0x6D, 0x65, 0x79, 0x4B, 0x79, 0x32, 0x74, 0x67, 0x55, 0x52, 0x4F, 0x38, 0x54, 0x57, 0x30, 0x47, 0x2F, 0x4C, 0x41, 0x49, 0x6A, 0x64, 0x30, 0x5A, 0x45, 0x47, 0x72, 0x48, 0x4A, 0x67, 0x77, 0x31, 0x32, 0x4D, 0x42, 0x76, ++ 0x49, 0x49, 0x54, 0x70, 0x6C, 0x4C, 0x47, 0x62, 0x68, 0x51, 0x50, 0x44, 0x57, 0x39, 0x74, 0x4B, 0x36, 0x4D, 0x6A, 0x34, 0x0A, 0x6B, 0x48, 0x62, 0x5A, 0x57, 0x30, 0x2F, 0x6A, 0x54, 0x4F, 0x67, 0x47, 0x4E, 0x6B, 0x33, 0x4D, 0x6D, 0x71, 0x77, ++ 0x39, 0x44, 0x4A, 0x41, 0x72, 0x6B, 0x74, 0x51, 0x47, 0x47, 0x57, 0x43, 0x73, 0x4E, 0x30, 0x52, 0x35, 0x68, 0x59, 0x47, 0x43, 0x72, 0x56, 0x6F, 0x33, 0x34, 0x41, 0x33, 0x4D, 0x6E, 0x61, 0x5A, 0x4D, 0x55, 0x6E, 0x62, 0x71, 0x51, 0x35, 0x32, ++ 0x33, 0x42, 0x4E, 0x46, 0x51, 0x39, 0x6C, 0x58, 0x67, 0x31, 0x64, 0x4B, 0x6D, 0x53, 0x59, 0x58, 0x70, 0x0A, 0x4E, 0x2B, 0x6E, 0x4B, 0x66, 0x71, 0x35, 0x63, 0x6C, 0x55, 0x31, 0x49, 0x6D, 0x6A, 0x2B, 0x75, 0x49, 0x46, 0x70, 0x74, 0x69, 0x4A, ++ 0x58, 0x5A, 0x4E, 0x4C, 0x68, 0x53, 0x47, 0x6B, 0x4F, 0x51, 0x73, 0x4C, 0x39, 0x73, 0x42, 0x62, 0x6D, 0x32, 0x65, 0x4C, 0x66, 0x71, 0x30, 0x4F, 0x51, 0x36, 0x50, 0x42, 0x4A, 0x54, 0x59, 0x76, 0x39, 0x4B, 0x38, 0x6E, 0x75, 0x2B, 0x4E, 0x51, ++ 0x57, 0x70, 0x45, 0x6A, 0x54, 0x6A, 0x38, 0x32, 0x52, 0x30, 0x59, 0x69, 0x77, 0x39, 0x0A, 0x41, 0x45, 0x6C, 0x61, 0x4B, 0x50, 0x34, 0x79, 0x52, 0x4C, 0x75, 0x48, 0x33, 0x57, 0x55, 0x6E, 0x41, 0x6E, 0x45, 0x37, 0x32, 0x6B, 0x72, 0x33, 0x48, ++ 0x39, 0x72, 0x4E, 0x39, 0x79, 0x46, 0x56, 0x6B, 0x45, 0x38, 0x50, 0x37, 0x4B, 0x36, 0x43, 0x34, 0x5A, 0x39, 0x72, 0x32, 0x55, 0x58, 0x54, 0x75, 0x2F, 0x42, 0x66, 0x68, 0x2B, 0x30, 0x38, 0x4C, 0x44, 0x6D, 0x47, 0x32, 0x6A, 0x2F, 0x65, 0x37, ++ 0x48, 0x4A, 0x56, 0x36, 0x33, 0x6D, 0x6A, 0x72, 0x64, 0x76, 0x64, 0x0A, 0x66, 0x4C, 0x43, 0x36, 0x48, 0x4D, 0x37, 0x38, 0x33, 0x6B, 0x38, 0x31, 0x64, 0x73, 0x38, 0x50, 0x2B, 0x48, 0x67, 0x66, 0x61, 0x6A, 0x5A, 0x52, 0x52, 0x69, 0x64, 0x68, ++ 0x57, 0x2B, 0x6D, 0x65, 0x7A, 0x2F, 0x43, 0x69, 0x56, 0x58, 0x31, 0x38, 0x4A, 0x59, 0x70, 0x76, 0x4C, 0x37, 0x54, 0x46, 0x7A, 0x34, 0x51, 0x75, 0x4B, 0x2F, 0x30, 0x4E, 0x55, 0x52, 0x42, 0x73, 0x2B, 0x31, 0x38, 0x62, 0x76, 0x42, 0x74, 0x2B, ++ 0x78, 0x61, 0x34, 0x37, 0x6D, 0x41, 0x45, 0x78, 0x0A, 0x6B, 0x76, 0x38, 0x4C, 0x56, 0x2F, 0x53, 0x61, 0x73, 0x72, 0x6C, 0x58, 0x36, 0x61, 0x76, 0x76, 0x44, 0x58, 0x62, 0x52, 0x38, 0x4F, 0x37, 0x30, 0x7A, 0x6F, 0x61, 0x6E, 0x34, 0x47, 0x37, ++ 0x70, 0x74, 0x47, 0x6D, 0x68, 0x33, 0x32, 0x6E, 0x32, 0x4D, 0x38, 0x5A, 0x70, 0x4C, 0x70, 0x63, 0x54, 0x6E, 0x71, 0x57, 0x48, 0x73, 0x46, 0x63, 0x51, 0x67, 0x54, 0x66, 0x4A, 0x55, 0x37, 0x4F, 0x37, 0x66, 0x2F, 0x61, 0x53, 0x30, 0x5A, 0x7A, ++ 0x51, 0x47, 0x50, 0x53, 0x53, 0x0A, 0x62, 0x74, 0x71, 0x44, 0x54, 0x36, 0x5A, 0x6A, 0x6D, 0x55, 0x79, 0x6C, 0x2B, 0x31, 0x37, 0x76, 0x49, 0x57, 0x52, 0x36, 0x49, 0x46, 0x39, 0x73, 0x5A, 0x49, 0x55, 0x56, 0x79, 0x7A, 0x66, 0x70, 0x59, 0x67, ++ 0x77, 0x4C, 0x4B, 0x68, 0x62, 0x63, 0x41, 0x53, 0x34, 0x79, 0x32, 0x6A, 0x35, 0x4C, 0x39, 0x5A, 0x34, 0x36, 0x39, 0x68, 0x64, 0x41, 0x6C, 0x4F, 0x2B, 0x65, 0x6B, 0x51, 0x69, 0x47, 0x2B, 0x72, 0x35, 0x6A, 0x71, 0x46, 0x6F, 0x7A, 0x37, 0x4D, ++ 0x74, 0x30, 0x0A, 0x51, 0x35, 0x58, 0x35, 0x62, 0x47, 0x6C, 0x53, 0x4E, 0x73, 0x63, 0x70, 0x62, 0x2F, 0x78, 0x56, 0x41, 0x31, 0x77, 0x66, 0x2B, 0x35, 0x2B, 0x39, 0x52, 0x2B, 0x76, 0x6E, 0x53, 0x55, 0x65, 0x56, 0x43, 0x30, 0x36, 0x4A, 0x49, ++ 0x67, 0x6C, 0x4A, 0x34, 0x50, 0x56, 0x68, 0x48, 0x76, 0x47, 0x2F, 0x4C, 0x6F, 0x70, 0x79, 0x62, 0x6F, 0x42, 0x5A, 0x2F, 0x31, 0x63, 0x36, 0x2B, 0x58, 0x55, 0x79, 0x6F, 0x30, 0x35, 0x66, 0x37, 0x4F, 0x30, 0x6F, 0x59, 0x74, 0x6C, 0x4E, 0x0A, ++ 0x63, 0x2F, 0x4C, 0x4D, 0x67, 0x52, 0x64, 0x67, 0x37, 0x63, 0x33, 0x72, 0x33, 0x4E, 0x75, 0x6E, 0x79, 0x73, 0x56, 0x2B, 0x41, 0x72, 0x33, 0x79, 0x56, 0x41, 0x68, 0x55, 0x2F, 0x62, 0x51, 0x74, 0x43, 0x53, 0x77, 0x58, 0x56, 0x45, 0x71, 0x59, ++ 0x30, 0x56, 0x54, 0x68, 0x55, 0x57, 0x63, 0x49, 0x30, 0x75, 0x31, 0x75, 0x66, 0x6D, 0x38, 0x2F, 0x30, 0x69, 0x32, 0x42, 0x57, 0x53, 0x6C, 0x6D, 0x79, 0x35, 0x41, 0x35, 0x6C, 0x52, 0x45, 0x65, 0x64, 0x43, 0x66, 0x2B, 0x0A, 0x33, 0x65, 0x75, ++ 0x76, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, 0x51, 0x6A, 0x42, 0x41, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x44, 0x67, 0x59, ++ 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x47, 0x47, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x53, 0x77, 0x0A, 0x44, 0x50, 0x42, 0x4D, 0x4D, 0x50, ++ 0x51, 0x46, 0x57, 0x41, 0x4A, 0x49, 0x2F, 0x54, 0x50, 0x6C, 0x55, 0x71, 0x39, 0x4C, 0x68, 0x4F, 0x4E, 0x6D, 0x55, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x77, 0x46, 0x41, 0x41, ++ 0x4F, 0x43, 0x41, 0x67, 0x45, 0x41, 0x71, 0x71, 0x69, 0x41, 0x6A, 0x77, 0x35, 0x34, 0x6F, 0x2B, 0x43, 0x69, 0x31, 0x4D, 0x33, 0x6D, 0x39, 0x5A, 0x68, 0x36, 0x4F, 0x2B, 0x6F, 0x41, 0x0A, 0x41, 0x37, 0x43, 0x58, 0x44, 0x70, 0x4F, 0x38, 0x57, ++ 0x71, 0x6A, 0x32, 0x4C, 0x49, 0x78, 0x79, 0x68, 0x36, 0x6D, 0x78, 0x2F, 0x48, 0x39, 0x7A, 0x2F, 0x57, 0x4E, 0x78, 0x65, 0x4B, 0x57, 0x48, 0x57, 0x63, 0x38, 0x77, 0x34, 0x51, 0x30, 0x51, 0x73, 0x68, 0x4E, 0x61, 0x62, 0x59, 0x4C, 0x31, 0x61, ++ 0x75, 0x61, 0x41, 0x6E, 0x36, 0x41, 0x46, 0x43, 0x32, 0x6A, 0x6B, 0x52, 0x32, 0x76, 0x48, 0x61, 0x74, 0x2B, 0x32, 0x2F, 0x58, 0x63, 0x79, 0x63, 0x75, 0x55, 0x59, 0x0A, 0x2B, 0x67, 0x6E, 0x30, 0x6F, 0x4A, 0x4D, 0x73, 0x58, 0x64, 0x4B, 0x4D, ++ 0x64, 0x59, 0x56, 0x32, 0x5A, 0x5A, 0x41, 0x4D, 0x41, 0x33, 0x6D, 0x33, 0x4D, 0x53, 0x4E, 0x6A, 0x72, 0x58, 0x69, 0x44, 0x43, 0x59, 0x5A, 0x6F, 0x68, 0x4D, 0x72, 0x2F, 0x2B, 0x63, 0x38, 0x6D, 0x6D, 0x70, 0x4A, 0x35, 0x35, 0x38, 0x31, 0x4C, ++ 0x78, 0x65, 0x64, 0x68, 0x70, 0x78, 0x66, 0x4C, 0x38, 0x36, 0x6B, 0x53, 0x6B, 0x35, 0x4E, 0x72, 0x70, 0x2B, 0x67, 0x76, 0x55, 0x35, 0x4C, 0x45, 0x0A, 0x59, 0x46, 0x69, 0x77, 0x7A, 0x41, 0x4A, 0x52, 0x47, 0x46, 0x75, 0x46, 0x6A, 0x57, 0x4A, ++ 0x5A, 0x59, 0x37, 0x61, 0x74, 0x74, 0x4E, 0x36, 0x61, 0x2B, 0x79, 0x62, 0x33, 0x41, 0x43, 0x66, 0x41, 0x58, 0x56, 0x55, 0x33, 0x64, 0x4A, 0x6E, 0x4A, 0x55, 0x48, 0x2F, 0x6A, 0x57, 0x53, 0x35, 0x45, 0x34, 0x79, 0x77, 0x6C, 0x37, 0x75, 0x78, ++ 0x4D, 0x4D, 0x6E, 0x65, 0x30, 0x6E, 0x78, 0x72, 0x70, 0x53, 0x31, 0x30, 0x67, 0x78, 0x64, 0x72, 0x39, 0x48, 0x49, 0x63, 0x57, 0x0A, 0x78, 0x6B, 0x50, 0x6F, 0x31, 0x4C, 0x73, 0x6D, 0x6D, 0x6B, 0x56, 0x77, 0x58, 0x71, 0x6B, 0x4C, 0x4E, 0x31, ++ 0x50, 0x69, 0x52, 0x6E, 0x73, 0x6E, 0x2F, 0x65, 0x42, 0x47, 0x38, 0x6F, 0x6D, 0x33, 0x7A, 0x45, 0x4B, 0x32, 0x79, 0x79, 0x67, 0x6D, 0x62, 0x74, 0x6D, 0x6C, 0x79, 0x54, 0x72, 0x49, 0x51, 0x52, 0x4E, 0x67, 0x39, 0x31, 0x43, 0x4D, 0x46, 0x61, ++ 0x36, 0x79, 0x62, 0x52, 0x6F, 0x56, 0x47, 0x6C, 0x64, 0x34, 0x35, 0x70, 0x49, 0x71, 0x32, 0x57, 0x57, 0x51, 0x0A, 0x67, 0x6A, 0x39, 0x73, 0x41, 0x71, 0x2B, 0x75, 0x45, 0x6A, 0x6F, 0x6E, 0x6C, 0x6A, 0x59, 0x45, 0x31, 0x78, 0x32, 0x69, 0x67, ++ 0x47, 0x4F, 0x70, 0x6D, 0x2F, 0x48, 0x6C, 0x75, 0x72, 0x52, 0x38, 0x46, 0x4C, 0x42, 0x4F, 0x79, 0x62, 0x45, 0x66, 0x64, 0x46, 0x38, 0x34, 0x39, 0x6C, 0x48, 0x71, 0x6D, 0x2F, 0x6F, 0x73, 0x6F, 0x68, 0x48, 0x55, 0x71, 0x53, 0x30, 0x6E, 0x47, ++ 0x6B, 0x57, 0x78, 0x72, 0x37, 0x4A, 0x4F, 0x63, 0x51, 0x33, 0x41, 0x57, 0x45, 0x62, 0x57, 0x0A, 0x61, 0x51, 0x62, 0x4C, 0x55, 0x38, 0x75, 0x7A, 0x2F, 0x6D, 0x74, 0x42, 0x7A, 0x55, 0x46, 0x2B, 0x66, 0x55, 0x77, 0x50, 0x66, 0x48, 0x4A, 0x35, ++ 0x65, 0x6C, 0x6E, 0x4E, 0x58, 0x6B, 0x6F, 0x4F, 0x72, 0x4A, 0x75, 0x70, 0x6D, 0x48, 0x4E, 0x35, 0x66, 0x4C, 0x54, 0x30, 0x7A, 0x4C, 0x6D, 0x34, 0x42, 0x77, 0x79, 0x79, 0x64, 0x46, 0x79, 0x34, 0x78, 0x32, 0x2B, 0x49, 0x6F, 0x5A, 0x43, 0x6E, ++ 0x39, 0x4B, 0x72, 0x35, 0x76, 0x32, 0x63, 0x36, 0x39, 0x42, 0x6F, 0x56, 0x0A, 0x59, 0x68, 0x36, 0x33, 0x6E, 0x37, 0x34, 0x39, 0x73, 0x53, 0x6D, 0x76, 0x5A, 0x36, 0x45, 0x53, 0x38, 0x6C, 0x67, 0x51, 0x47, 0x56, 0x4D, 0x44, 0x4D, 0x42, 0x75, ++ 0x34, 0x47, 0x6F, 0x6E, 0x32, 0x6E, 0x4C, 0x32, 0x58, 0x41, 0x34, 0x36, 0x6A, 0x43, 0x66, 0x4D, 0x64, 0x69, 0x79, 0x48, 0x78, 0x74, 0x4E, 0x2F, 0x6B, 0x48, 0x4E, 0x47, 0x66, 0x5A, 0x51, 0x49, 0x47, 0x36, 0x6C, 0x7A, 0x57, 0x45, 0x37, 0x4F, ++ 0x45, 0x37, 0x36, 0x4B, 0x6C, 0x58, 0x49, 0x78, 0x33, 0x0A, 0x4B, 0x61, 0x64, 0x6F, 0x77, 0x47, 0x75, 0x75, 0x51, 0x4E, 0x4B, 0x6F, 0x74, 0x4F, 0x72, 0x4E, 0x38, 0x49, 0x31, 0x4C, 0x4F, 0x4A, 0x77, 0x5A, 0x6D, 0x68, 0x73, 0x6F, 0x56, 0x4C, ++ 0x69, 0x4A, 0x6B, 0x4F, 0x2F, 0x4B, 0x64, 0x59, 0x45, 0x2B, 0x48, 0x76, 0x4A, 0x6B, 0x4A, 0x4D, 0x63, 0x59, 0x72, 0x30, 0x37, 0x2F, 0x52, 0x35, 0x34, 0x48, 0x39, 0x6A, 0x56, 0x6C, 0x70, 0x4E, 0x4D, 0x4B, 0x56, 0x76, 0x2F, 0x31, 0x46, 0x32, ++ 0x52, 0x73, 0x37, 0x36, 0x67, 0x69, 0x0A, 0x4A, 0x55, 0x6D, 0x54, 0x74, 0x74, 0x38, 0x41, 0x46, 0x39, 0x70, 0x59, 0x66, 0x6C, 0x33, 0x75, 0x78, 0x52, 0x75, 0x77, 0x30, 0x64, 0x46, 0x66, 0x49, 0x52, 0x44, 0x48, 0x2B, 0x66, 0x4F, 0x36, 0x41, ++ 0x67, 0x6F, 0x6E, 0x42, 0x38, 0x58, 0x78, 0x31, 0x73, 0x66, 0x54, 0x34, 0x50, 0x73, 0x4A, 0x59, 0x47, 0x77, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, ++ 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x42, 0x74, 0x6A, 0x43, 0x43, 0x41, 0x56, 0x75, ++ 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x54, 0x42, 0x6D, 0x79, 0x66, 0x31, 0x58, 0x53, 0x58, 0x4E, 0x6D, 0x59, 0x2F, 0x4F, 0x77, 0x75, 0x61, 0x32, 0x65, 0x69, 0x65, 0x64, 0x67, 0x50, 0x79, 0x53, 0x6A, 0x41, 0x4B, 0x42, 0x67, 0x67, ++ 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x6A, 0x41, 0x35, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0A, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x50, 0x4D, 0x41, 0x30, 0x47, 0x41, 0x31, ++ 0x55, 0x45, 0x43, 0x68, 0x4D, 0x47, 0x51, 0x57, 0x31, 0x68, 0x65, 0x6D, 0x39, 0x75, 0x4D, 0x52, 0x6B, 0x77, 0x46, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x42, 0x42, 0x62, 0x57, 0x46, 0x36, 0x62, 0x32, 0x34, 0x67, 0x55, 0x6D, ++ 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x53, 0x41, 0x7A, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x45, 0x31, 0x4D, 0x44, 0x55, 0x79, 0x0A, 0x4E, 0x6A, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x46, 0x6F, 0x58, 0x44, 0x54, 0x51, 0x77, 0x4D, ++ 0x44, 0x55, 0x79, 0x4E, 0x6A, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x46, 0x6F, 0x77, 0x4F, 0x54, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x56, 0x56, 0x4D, 0x78, 0x44, 0x7A, 0x41, 0x4E, 0x42, ++ 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x42, 0x6B, 0x46, 0x74, 0x59, 0x58, 0x70, 0x76, 0x62, 0x6A, 0x45, 0x5A, 0x0A, 0x4D, 0x42, 0x63, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x51, 0x51, 0x57, 0x31, 0x68, 0x65, 0x6D, 0x39, 0x75, ++ 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x4D, 0x7A, 0x42, 0x5A, 0x4D, 0x42, 0x4D, 0x47, 0x42, 0x79, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x41, 0x67, 0x45, 0x47, 0x43, 0x43, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, ++ 0x41, 0x77, 0x45, 0x48, 0x41, 0x30, 0x49, 0x41, 0x42, 0x43, 0x6D, 0x58, 0x70, 0x38, 0x5A, 0x42, 0x0A, 0x66, 0x38, 0x41, 0x4E, 0x6D, 0x2B, 0x67, 0x42, 0x47, 0x31, 0x62, 0x47, 0x38, 0x6C, 0x4B, 0x6C, 0x75, 0x69, 0x32, 0x79, 0x45, 0x75, 0x6A, ++ 0x53, 0x4C, 0x74, 0x66, 0x36, 0x79, 0x63, 0x58, 0x59, 0x71, 0x6D, 0x30, 0x66, 0x63, 0x34, 0x45, 0x37, 0x4F, 0x35, 0x68, 0x72, 0x4F, 0x58, 0x77, 0x7A, 0x70, 0x63, 0x56, 0x4F, 0x68, 0x6F, 0x36, 0x41, 0x46, 0x32, 0x68, 0x69, 0x52, 0x56, 0x64, ++ 0x39, 0x52, 0x46, 0x67, 0x64, 0x73, 0x7A, 0x66, 0x6C, 0x5A, 0x77, 0x6A, 0x72, 0x0A, 0x5A, 0x74, 0x36, 0x6A, 0x51, 0x6A, 0x42, 0x41, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, ++ 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x47, 0x47, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, ++ 0x53, 0x72, 0x74, 0x74, 0x76, 0x58, 0x42, 0x70, 0x34, 0x33, 0x0A, 0x72, 0x44, 0x43, 0x47, 0x42, 0x35, 0x46, 0x77, 0x78, 0x35, 0x7A, 0x45, 0x47, 0x62, 0x46, 0x34, 0x77, 0x44, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, ++ 0x51, 0x51, 0x44, 0x41, 0x67, 0x4E, 0x4A, 0x41, 0x44, 0x42, 0x47, 0x41, 0x69, 0x45, 0x41, 0x34, 0x49, 0x57, 0x53, 0x6F, 0x78, 0x65, 0x33, 0x6A, 0x66, 0x6B, 0x72, 0x42, 0x71, 0x57, 0x54, 0x72, 0x42, 0x71, 0x59, 0x61, 0x47, 0x46, 0x79, 0x2B, ++ 0x75, 0x47, 0x68, 0x30, 0x50, 0x73, 0x63, 0x0A, 0x65, 0x47, 0x43, 0x6D, 0x51, 0x35, 0x6E, 0x46, 0x75, 0x4D, 0x51, 0x43, 0x49, 0x51, 0x43, 0x63, 0x41, 0x75, 0x2F, 0x78, 0x6C, 0x4A, 0x79, 0x7A, 0x6C, 0x76, 0x6E, 0x72, 0x78, 0x69, 0x72, 0x34, ++ 0x74, 0x69, 0x7A, 0x2B, 0x4F, 0x70, 0x41, 0x55, 0x46, 0x74, 0x65, 0x4D, 0x59, 0x79, 0x52, 0x49, 0x48, 0x4E, 0x38, 0x77, 0x66, 0x64, 0x56, 0x6F, 0x4F, 0x77, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, ++ 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x34, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, ++ 0x49, 0x42, 0x38, 0x6A, 0x43, 0x43, 0x41, 0x58, 0x69, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x54, 0x42, 0x6D, 0x79, 0x66, 0x31, 0x38, 0x47, 0x37, 0x45, 0x45, 0x77, 0x70, 0x51, 0x2B, 0x56, 0x78, 0x65, 0x33, 0x73, 0x73, 0x79, 0x42, ++ 0x72, 0x42, 0x44, 0x6A, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x7A, 0x41, 0x35, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0A, 0x45, 0x77, 0x4A, 0x56, 0x55, ++ 0x7A, 0x45, 0x50, 0x4D, 0x41, 0x30, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x47, 0x51, 0x57, 0x31, 0x68, 0x65, 0x6D, 0x39, 0x75, 0x4D, 0x52, 0x6B, 0x77, 0x46, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x42, 0x42, 0x62, ++ 0x57, 0x46, 0x36, 0x62, 0x32, 0x34, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x53, 0x41, 0x30, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x45, 0x31, 0x4D, 0x44, 0x55, 0x79, 0x0A, 0x4E, 0x6A, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, ++ 0x4D, 0x46, 0x6F, 0x58, 0x44, 0x54, 0x51, 0x77, 0x4D, 0x44, 0x55, 0x79, 0x4E, 0x6A, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x46, 0x6F, 0x77, 0x4F, 0x54, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, ++ 0x56, 0x56, 0x4D, 0x78, 0x44, 0x7A, 0x41, 0x4E, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x42, 0x6B, 0x46, 0x74, 0x59, 0x58, 0x70, 0x76, 0x62, 0x6A, 0x45, 0x5A, 0x0A, 0x4D, 0x42, 0x63, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, ++ 0x51, 0x51, 0x57, 0x31, 0x68, 0x65, 0x6D, 0x39, 0x75, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x4E, 0x44, 0x42, 0x32, 0x4D, 0x42, 0x41, 0x47, 0x42, 0x79, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x41, 0x67, 0x45, ++ 0x47, 0x42, 0x53, 0x75, 0x42, 0x42, 0x41, 0x41, 0x69, 0x41, 0x32, 0x49, 0x41, 0x42, 0x4E, 0x4B, 0x72, 0x69, 0x6A, 0x64, 0x50, 0x6F, 0x31, 0x4D, 0x4E, 0x0A, 0x2F, 0x73, 0x47, 0x4B, 0x65, 0x30, 0x75, 0x6F, 0x65, 0x30, 0x5A, 0x4C, 0x59, 0x37, ++ 0x42, 0x69, 0x39, 0x69, 0x30, 0x62, 0x32, 0x77, 0x68, 0x78, 0x49, 0x64, 0x49, 0x41, 0x36, 0x47, 0x4F, 0x39, 0x6D, 0x69, 0x66, 0x37, 0x38, 0x44, 0x6C, 0x75, 0x58, 0x65, 0x6F, 0x39, 0x70, 0x63, 0x6D, 0x42, 0x71, 0x71, 0x4E, 0x62, 0x49, 0x4A, ++ 0x68, 0x46, 0x58, 0x52, 0x62, 0x62, 0x2F, 0x65, 0x67, 0x51, 0x62, 0x65, 0x4F, 0x63, 0x34, 0x4F, 0x4F, 0x39, 0x58, 0x34, 0x52, 0x69, 0x0A, 0x38, 0x33, 0x42, 0x6B, 0x4D, 0x36, 0x44, 0x4C, 0x4A, 0x43, 0x39, 0x77, 0x75, 0x6F, 0x69, 0x68, 0x4B, ++ 0x71, 0x42, 0x31, 0x2B, 0x49, 0x47, 0x75, 0x59, 0x67, 0x62, 0x45, 0x67, 0x64, 0x73, 0x35, 0x62, 0x69, 0x6D, 0x77, 0x48, 0x76, 0x6F, 0x75, 0x58, 0x4B, 0x4E, 0x43, 0x4D, 0x45, 0x41, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, ++ 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x0A, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x59, 0x59, 0x77, 0x48, 0x51, 0x59, 0x44, ++ 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x46, 0x4E, 0x50, 0x73, 0x78, 0x7A, 0x70, 0x6C, 0x62, 0x73, 0x7A, 0x68, 0x32, 0x6E, 0x61, 0x61, 0x56, 0x76, 0x75, 0x63, 0x38, 0x34, 0x5A, 0x74, 0x56, 0x2B, 0x57, 0x42, 0x4D, 0x41, 0x6F, 0x47, ++ 0x43, 0x43, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x42, 0x41, 0x4D, 0x44, 0x41, 0x32, 0x67, 0x41, 0x0A, 0x4D, 0x47, 0x55, 0x43, 0x4D, 0x44, 0x71, 0x4C, 0x49, 0x66, 0x47, 0x39, 0x66, 0x68, 0x47, 0x74, 0x30, 0x4F, 0x39, 0x59, 0x6C, 0x69, 0x2F, ++ 0x57, 0x36, 0x35, 0x31, 0x2B, 0x6B, 0x49, 0x30, 0x72, 0x7A, 0x32, 0x5A, 0x56, 0x77, 0x79, 0x7A, 0x6A, 0x4B, 0x4B, 0x6C, 0x77, 0x43, 0x6B, 0x63, 0x4F, 0x38, 0x44, 0x64, 0x5A, 0x45, 0x76, 0x38, 0x74, 0x6D, 0x5A, 0x51, 0x6F, 0x54, 0x69, 0x70, ++ 0x50, 0x4E, 0x55, 0x30, 0x7A, 0x57, 0x67, 0x49, 0x78, 0x41, 0x4F, 0x70, 0x31, 0x0A, 0x41, 0x45, 0x34, 0x37, 0x78, 0x44, 0x71, 0x55, 0x45, 0x70, 0x48, 0x4A, 0x57, 0x45, 0x61, 0x64, 0x49, 0x52, 0x4E, 0x79, 0x70, 0x34, 0x69, 0x63, 0x69, 0x75, ++ 0x52, 0x4D, 0x53, 0x74, 0x75, 0x57, 0x31, 0x4B, 0x79, 0x4C, 0x61, 0x32, 0x74, 0x4A, 0x45, 0x6C, 0x4D, 0x7A, 0x72, 0x64, 0x66, 0x6B, 0x76, 0x69, 0x54, 0x38, 0x74, 0x51, 0x70, 0x32, 0x31, 0x4B, 0x57, 0x38, 0x45, 0x41, 0x3D, 0x3D, 0x0A, 0x2D, ++ 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x54, 0x55, 0x42, 0x49, 0x54, 0x41, 0x4B, 0x20, 0x4B, 0x61, 0x6D, 0x75, 0x20, 0x53, ++ 0x4D, 0x20, 0x53, 0x53, 0x4C, 0x20, 0x4B, 0x6F, 0x6B, 0x20, 0x53, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x6B, 0x61, 0x73, 0x69, 0x20, 0x2D, 0x20, 0x53, 0x75, 0x72, 0x75, 0x6D, 0x20, 0x31, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, ++ 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x45, 0x59, 0x7A, 0x43, 0x43, 0x41, 0x30, 0x75, 0x67, 0x41, 0x77, ++ 0x49, 0x42, 0x41, 0x67, 0x49, 0x42, 0x41, 0x54, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x43, 0x42, 0x30, 0x6A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, ++ 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x56, 0x46, 0x49, 0x78, 0x47, 0x44, 0x41, 0x57, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x63, 0x54, 0x0A, 0x44, 0x30, 0x64, 0x6C, 0x59, 0x6E, 0x70, 0x6C, 0x49, 0x43, 0x30, 0x67, 0x53, 0x32, 0x39, 0x6A, 0x59, ++ 0x57, 0x56, 0x73, 0x61, 0x54, 0x46, 0x43, 0x4D, 0x45, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x35, 0x56, 0x48, 0x56, 0x79, 0x61, 0x32, 0x6C, 0x35, 0x5A, 0x53, 0x42, 0x43, 0x61, 0x57, 0x78, 0x70, 0x62, 0x58, 0x4E, 0x6C, 0x62, ++ 0x43, 0x42, 0x32, 0x5A, 0x53, 0x42, 0x55, 0x5A, 0x57, 0x74, 0x75, 0x62, 0x32, 0x78, 0x76, 0x61, 0x6D, 0x6C, 0x72, 0x0A, 0x49, 0x45, 0x46, 0x79, 0x59, 0x58, 0x4E, 0x30, 0x61, 0x58, 0x4A, 0x74, 0x59, 0x53, 0x42, 0x4C, 0x64, 0x58, 0x4A, 0x31, ++ 0x62, 0x58, 0x55, 0x67, 0x4C, 0x53, 0x42, 0x55, 0x56, 0x55, 0x4A, 0x4A, 0x56, 0x45, 0x46, 0x4C, 0x4D, 0x53, 0x30, 0x77, 0x4B, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, 0x45, 0x79, 0x52, 0x4C, 0x59, 0x57, 0x31, 0x31, 0x49, 0x46, 0x4E, 0x6C, ++ 0x63, 0x6E, 0x52, 0x70, 0x5A, 0x6D, 0x6C, 0x72, 0x59, 0x58, 0x4E, 0x35, 0x62, 0x32, 0x34, 0x67, 0x0A, 0x54, 0x57, 0x56, 0x79, 0x61, 0x32, 0x56, 0x36, 0x61, 0x53, 0x41, 0x74, 0x49, 0x45, 0x74, 0x68, 0x62, 0x58, 0x55, 0x67, 0x55, 0x30, 0x30, ++ 0x78, 0x4E, 0x6A, 0x41, 0x30, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x4C, 0x56, 0x52, 0x56, 0x51, 0x6B, 0x6C, 0x55, 0x51, 0x55, 0x73, 0x67, 0x53, 0x32, 0x46, 0x74, 0x64, 0x53, 0x42, 0x54, 0x54, 0x53, 0x42, 0x54, 0x55, 0x30, 0x77, ++ 0x67, 0x53, 0x32, 0x39, 0x72, 0x49, 0x46, 0x4E, 0x6C, 0x63, 0x6E, 0x52, 0x70, 0x0A, 0x5A, 0x6D, 0x6C, 0x72, 0x59, 0x58, 0x4E, 0x70, 0x49, 0x43, 0x30, 0x67, 0x55, 0x33, 0x56, 0x79, 0x64, 0x57, 0x30, 0x67, 0x4D, 0x54, 0x41, 0x65, 0x46, 0x77, ++ 0x30, 0x78, 0x4D, 0x7A, 0x45, 0x78, 0x4D, 0x6A, 0x55, 0x77, 0x4F, 0x44, 0x49, 0x31, 0x4E, 0x54, 0x56, 0x61, 0x46, 0x77, 0x30, 0x30, 0x4D, 0x7A, 0x45, 0x77, 0x4D, 0x6A, 0x55, 0x77, 0x4F, 0x44, 0x49, 0x31, 0x4E, 0x54, 0x56, 0x61, 0x4D, 0x49, ++ 0x48, 0x53, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x0A, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x55, 0x55, 0x6A, 0x45, 0x59, 0x4D, 0x42, 0x59, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x78, 0x4D, 0x50, 0x52, 0x32, 0x56, 0x69, 0x65, ++ 0x6D, 0x55, 0x67, 0x4C, 0x53, 0x42, 0x4C, 0x62, 0x32, 0x4E, 0x68, 0x5A, 0x57, 0x78, 0x70, 0x4D, 0x55, 0x49, 0x77, 0x51, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x7A, 0x6C, 0x55, 0x64, 0x58, 0x4A, 0x72, 0x61, 0x58, 0x6C, 0x6C, 0x49, ++ 0x45, 0x4A, 0x70, 0x62, 0x47, 0x6C, 0x74, 0x0A, 0x63, 0x32, 0x56, 0x73, 0x49, 0x48, 0x5A, 0x6C, 0x49, 0x46, 0x52, 0x6C, 0x61, 0x32, 0x35, 0x76, 0x62, 0x47, 0x39, 0x71, 0x61, 0x57, 0x73, 0x67, 0x51, 0x58, 0x4A, 0x68, 0x63, 0x33, 0x52, 0x70, ++ 0x63, 0x6D, 0x31, 0x68, 0x49, 0x45, 0x74, 0x31, 0x63, 0x6E, 0x56, 0x74, 0x64, 0x53, 0x41, 0x74, 0x49, 0x46, 0x52, 0x56, 0x51, 0x6B, 0x6C, 0x55, 0x51, 0x55, 0x73, 0x78, 0x4C, 0x54, 0x41, 0x72, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x73, 0x54, ++ 0x4A, 0x45, 0x74, 0x68, 0x0A, 0x62, 0x58, 0x55, 0x67, 0x55, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6C, 0x6D, 0x61, 0x57, 0x74, 0x68, 0x63, 0x33, 0x6C, 0x76, 0x62, 0x69, 0x42, 0x4E, 0x5A, 0x58, 0x4A, 0x72, 0x5A, 0x58, 0x70, 0x70, 0x49, 0x43, 0x30, ++ 0x67, 0x53, 0x32, 0x46, 0x74, 0x64, 0x53, 0x42, 0x54, 0x54, 0x54, 0x45, 0x32, 0x4D, 0x44, 0x51, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x74, 0x56, 0x46, 0x56, 0x43, 0x53, 0x56, 0x52, 0x42, 0x53, 0x79, 0x42, 0x4C, 0x59, 0x57, 0x31, ++ 0x31, 0x0A, 0x49, 0x46, 0x4E, 0x4E, 0x49, 0x46, 0x4E, 0x54, 0x54, 0x43, 0x42, 0x4C, 0x62, 0x32, 0x73, 0x67, 0x55, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6C, 0x6D, 0x61, 0x57, 0x74, 0x68, 0x63, 0x32, 0x6B, 0x67, 0x4C, 0x53, 0x42, 0x54, 0x64, 0x58, ++ 0x4A, 0x31, 0x62, 0x53, 0x41, 0x78, 0x4D, 0x49, 0x49, 0x42, 0x49, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x51, 0x38, 0x41, 0x0A, 0x4D, ++ 0x49, 0x49, 0x42, 0x43, 0x67, 0x4B, 0x43, 0x41, 0x51, 0x45, 0x41, 0x72, 0x33, 0x55, 0x77, 0x4D, 0x36, 0x71, 0x37, 0x61, 0x39, 0x4F, 0x5A, 0x4C, 0x42, 0x49, 0x33, 0x68, 0x4E, 0x6D, 0x4E, 0x65, 0x35, 0x65, 0x41, 0x30, 0x32, 0x37, 0x6E, 0x2F, ++ 0x35, 0x74, 0x51, 0x6C, 0x54, 0x36, 0x51, 0x6C, 0x56, 0x5A, 0x43, 0x31, 0x78, 0x6C, 0x38, 0x4A, 0x6F, 0x53, 0x4E, 0x6B, 0x76, 0x6F, 0x42, 0x48, 0x54, 0x6F, 0x50, 0x34, 0x6D, 0x51, 0x34, 0x74, 0x34, 0x79, 0x38, 0x0A, 0x36, 0x49, 0x6A, 0x35, ++ 0x69, 0x79, 0x53, 0x72, 0x4C, 0x71, 0x50, 0x31, 0x4E, 0x2B, 0x52, 0x41, 0x6A, 0x68, 0x67, 0x6C, 0x65, 0x59, 0x4E, 0x31, 0x48, 0x7A, 0x76, 0x2F, 0x62, 0x4B, 0x6A, 0x46, 0x78, 0x6C, 0x62, 0x34, 0x74, 0x4F, 0x32, 0x4B, 0x52, 0x4B, 0x4F, 0x72, ++ 0x62, 0x45, 0x7A, 0x38, 0x48, 0x64, 0x44, 0x63, 0x37, 0x32, 0x69, 0x39, 0x7A, 0x2B, 0x53, 0x71, 0x7A, 0x76, 0x42, 0x56, 0x39, 0x36, 0x49, 0x30, 0x31, 0x49, 0x4E, 0x72, 0x4E, 0x33, 0x77, 0x63, 0x0A, 0x77, 0x76, 0x36, 0x31, 0x41, 0x2B, 0x78, ++ 0x58, 0x7A, 0x72, 0x79, 0x30, 0x74, 0x63, 0x58, 0x74, 0x41, 0x41, 0x39, 0x54, 0x4E, 0x79, 0x70, 0x4E, 0x39, 0x45, 0x38, 0x4D, 0x67, 0x2F, 0x75, 0x47, 0x7A, 0x38, 0x76, 0x2B, 0x6A, 0x45, 0x36, 0x39, 0x68, 0x2F, 0x6D, 0x6E, 0x69, 0x79, 0x46, ++ 0x58, 0x6E, 0x48, 0x72, 0x66, 0x41, 0x32, 0x65, 0x4A, 0x4C, 0x4A, 0x32, 0x58, 0x59, 0x61, 0x63, 0x51, 0x75, 0x46, 0x57, 0x51, 0x66, 0x77, 0x34, 0x74, 0x4A, 0x7A, 0x68, 0x30, 0x0A, 0x33, 0x2B, 0x66, 0x39, 0x32, 0x6B, 0x34, 0x53, 0x34, 0x30, ++ 0x30, 0x56, 0x49, 0x67, 0x4C, 0x49, 0x34, 0x4F, 0x44, 0x38, 0x44, 0x36, 0x32, 0x4B, 0x31, 0x38, 0x6C, 0x55, 0x55, 0x4D, 0x77, 0x37, 0x44, 0x38, 0x6F, 0x57, 0x67, 0x49, 0x54, 0x51, 0x55, 0x56, 0x62, 0x44, 0x6A, 0x6C, 0x5A, 0x2F, 0x69, 0x53, ++ 0x49, 0x7A, 0x4C, 0x2B, 0x61, 0x46, 0x43, 0x72, 0x32, 0x6C, 0x71, 0x42, 0x73, 0x32, 0x33, 0x74, 0x50, 0x63, 0x4C, 0x47, 0x30, 0x37, 0x78, 0x78, 0x4F, 0x39, 0x0A, 0x57, 0x53, 0x4D, 0x73, 0x35, 0x75, 0x57, 0x6B, 0x39, 0x39, 0x67, 0x4C, 0x37, ++ 0x65, 0x71, 0x51, 0x51, 0x45, 0x53, 0x6F, 0x6C, 0x62, 0x75, 0x54, 0x31, 0x64, 0x43, 0x41, 0x4E, 0x4C, 0x5A, 0x47, 0x65, 0x41, 0x34, 0x66, 0x41, 0x4A, 0x4E, 0x47, 0x34, 0x65, 0x37, 0x70, 0x2B, 0x65, 0x78, 0x50, 0x46, 0x77, 0x49, 0x44, 0x41, ++ 0x51, 0x41, 0x42, 0x6F, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x0A, 0x5A, 0x54, 0x2F, 0x48, 0x69, 0x6F, 0x62, 0x47, 0x50, 0x4E, 0x30, 0x38, 0x56, 0x46, 0x77, 0x31, ++ 0x2B, 0x44, 0x72, 0x74, 0x55, 0x67, 0x78, 0x48, 0x56, 0x38, 0x67, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, ++ 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x0A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, ++ 0x42, 0x41, 0x43, 0x6F, 0x2F, 0x34, 0x66, 0x45, 0x79, 0x6A, 0x71, 0x37, 0x68, 0x6D, 0x46, 0x78, 0x4C, 0x58, 0x73, 0x39, 0x72, 0x48, 0x6D, 0x6F, 0x4A, 0x30, 0x69, 0x4B, 0x70, 0x45, 0x73, 0x64, 0x65, 0x56, 0x33, 0x31, 0x7A, 0x56, 0x6D, 0x53, ++ 0x41, 0x68, 0x48, 0x71, 0x54, 0x35, 0x41, 0x6D, 0x35, 0x45, 0x4D, 0x32, 0x66, 0x4B, 0x69, 0x66, 0x68, 0x0A, 0x41, 0x48, 0x65, 0x2B, 0x53, 0x4D, 0x67, 0x31, 0x71, 0x49, 0x47, 0x66, 0x35, 0x4C, 0x67, 0x73, 0x79, 0x58, 0x38, 0x4F, 0x73, 0x4E, ++ 0x4A, 0x4C, 0x4E, 0x31, 0x33, 0x71, 0x75, 0x64, 0x55, 0x4C, 0x58, 0x6A, 0x53, 0x39, 0x39, 0x48, 0x4D, 0x70, 0x77, 0x2B, 0x30, 0x6D, 0x46, 0x5A, 0x78, 0x2B, 0x43, 0x46, 0x4F, 0x4B, 0x57, 0x49, 0x33, 0x51, 0x53, 0x79, 0x6A, 0x66, 0x77, 0x62, ++ 0x50, 0x66, 0x49, 0x50, 0x50, 0x35, 0x34, 0x2B, 0x4D, 0x36, 0x33, 0x38, 0x79, 0x63, 0x0A, 0x6C, 0x4E, 0x68, 0x4F, 0x54, 0x38, 0x4E, 0x72, 0x46, 0x37, 0x66, 0x33, 0x63, 0x75, 0x69, 0x74, 0x5A, 0x6A, 0x4F, 0x31, 0x4A, 0x56, 0x4F, 0x72, 0x34, ++ 0x50, 0x68, 0x4D, 0x71, 0x5A, 0x33, 0x39, 0x38, 0x67, 0x32, 0x36, 0x72, 0x72, 0x6E, 0x5A, 0x71, 0x73, 0x5A, 0x72, 0x2B, 0x5A, 0x4F, 0x37, 0x72, 0x71, 0x75, 0x34, 0x6C, 0x7A, 0x77, 0x44, 0x47, 0x72, 0x70, 0x44, 0x78, 0x70, 0x61, 0x35, 0x52, ++ 0x58, 0x49, 0x34, 0x73, 0x36, 0x65, 0x68, 0x6C, 0x6A, 0x32, 0x52, 0x0A, 0x65, 0x33, 0x37, 0x41, 0x49, 0x56, 0x4E, 0x4D, 0x68, 0x2B, 0x33, 0x79, 0x43, 0x31, 0x53, 0x56, 0x55, 0x5A, 0x50, 0x56, 0x49, 0x71, 0x55, 0x4E, 0x69, 0x76, 0x47, 0x54, ++ 0x44, 0x6A, 0x35, 0x55, 0x44, 0x72, 0x44, 0x59, 0x79, 0x55, 0x37, 0x63, 0x38, 0x6A, 0x45, 0x79, 0x56, 0x75, 0x70, 0x6B, 0x2B, 0x65, 0x71, 0x31, 0x6E, 0x52, 0x5A, 0x6D, 0x51, 0x6E, 0x4C, 0x7A, 0x66, 0x39, 0x4F, 0x78, 0x4D, 0x55, 0x50, 0x38, ++ 0x70, 0x49, 0x34, 0x58, 0x38, 0x57, 0x30, 0x6A, 0x0A, 0x71, 0x35, 0x52, 0x6D, 0x2B, 0x4B, 0x33, 0x37, 0x44, 0x77, 0x68, 0x75, 0x4A, 0x69, 0x31, 0x2F, 0x46, 0x77, 0x63, 0x4A, 0x73, 0x6F, 0x7A, 0x37, 0x55, 0x4D, 0x43, 0x66, 0x6C, 0x6F, 0x33, ++ 0x50, 0x74, 0x76, 0x30, 0x41, 0x6E, 0x56, 0x6F, 0x55, 0x6D, 0x72, 0x38, 0x43, 0x52, 0x50, 0x58, 0x42, 0x77, 0x70, 0x38, 0x69, 0x58, 0x71, 0x49, 0x50, 0x6F, 0x65, 0x4D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, ++ 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x47, 0x44, 0x43, 0x41, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x55, 0x54, 0x48, 0x20, 0x52, 0x35, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x0A, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, ++ 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x69, 0x44, 0x43, 0x43, 0x41, 0x33, 0x43, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x49, 0x66, 0x51, 0x6D, 0x58, 0x2F, 0x76, 0x42, 0x48, 0x36, ++ 0x6E, 0x6F, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x77, 0x59, 0x6A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x51, ++ 0x30, 0x34, 0x78, 0x4D, 0x6A, 0x41, 0x77, 0x0A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x4B, 0x55, 0x64, 0x56, 0x51, 0x55, 0x35, 0x48, 0x49, 0x45, 0x52, 0x50, 0x54, 0x6B, 0x63, 0x67, 0x51, 0x30, 0x56, 0x53, 0x56, 0x45, 0x6C, 0x47, ++ 0x53, 0x55, 0x4E, 0x42, 0x56, 0x45, 0x55, 0x67, 0x51, 0x56, 0x56, 0x55, 0x53, 0x45, 0x39, 0x53, 0x53, 0x56, 0x52, 0x5A, 0x49, 0x45, 0x4E, 0x50, 0x4C, 0x69, 0x78, 0x4D, 0x56, 0x45, 0x51, 0x75, 0x4D, 0x52, 0x38, 0x77, 0x48, 0x51, 0x59, 0x44, ++ 0x56, 0x51, 0x51, 0x44, 0x0A, 0x44, 0x42, 0x5A, 0x48, 0x52, 0x45, 0x4E, 0x42, 0x49, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x51, 0x56, 0x56, 0x55, 0x53, 0x43, 0x42, 0x53, 0x4E, 0x53, 0x42, 0x53, 0x54, 0x30, 0x39, 0x55, 0x4D, 0x42, 0x34, ++ 0x58, 0x44, 0x54, 0x45, 0x30, 0x4D, 0x54, 0x45, 0x79, 0x4E, 0x6A, 0x41, 0x31, 0x4D, 0x54, 0x4D, 0x78, 0x4E, 0x56, 0x6F, 0x58, 0x44, 0x54, 0x51, 0x77, 0x4D, 0x54, 0x49, 0x7A, 0x4D, 0x54, 0x45, 0x31, 0x4E, 0x54, 0x6B, 0x31, 0x4F, 0x56, 0x6F, ++ 0x77, 0x0A, 0x59, 0x6A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x51, 0x30, 0x34, 0x78, 0x4D, 0x6A, 0x41, 0x77, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x4B, 0x55, 0x64, 0x56, 0x51, 0x55, ++ 0x35, 0x48, 0x49, 0x45, 0x52, 0x50, 0x54, 0x6B, 0x63, 0x67, 0x51, 0x30, 0x56, 0x53, 0x56, 0x45, 0x6C, 0x47, 0x53, 0x55, 0x4E, 0x42, 0x56, 0x45, 0x55, 0x67, 0x51, 0x56, 0x56, 0x55, 0x53, 0x45, 0x39, 0x53, 0x53, 0x56, 0x52, 0x5A, 0x0A, 0x49, ++ 0x45, 0x4E, 0x50, 0x4C, 0x69, 0x78, 0x4D, 0x56, 0x45, 0x51, 0x75, 0x4D, 0x52, 0x38, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x42, 0x5A, 0x48, 0x52, 0x45, 0x4E, 0x42, 0x49, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x51, ++ 0x56, 0x56, 0x55, 0x53, 0x43, 0x42, 0x53, 0x4E, 0x53, 0x42, 0x53, 0x54, 0x30, 0x39, 0x55, 0x4D, 0x49, 0x49, 0x43, 0x49, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x0A, 0x41, 0x51, 0x45, 0x46, ++ 0x41, 0x41, 0x4F, 0x43, 0x41, 0x67, 0x38, 0x41, 0x4D, 0x49, 0x49, 0x43, 0x43, 0x67, 0x4B, 0x43, 0x41, 0x67, 0x45, 0x41, 0x32, 0x61, 0x4D, 0x57, 0x38, 0x4D, 0x68, 0x30, 0x64, 0x48, 0x65, 0x62, 0x37, 0x7A, 0x4D, 0x4E, 0x4F, 0x77, 0x5A, 0x2B, ++ 0x56, 0x66, 0x79, 0x31, 0x59, 0x49, 0x39, 0x32, 0x68, 0x68, 0x4A, 0x43, 0x66, 0x56, 0x5A, 0x6D, 0x50, 0x6F, 0x69, 0x43, 0x37, 0x58, 0x4A, 0x6A, 0x44, 0x70, 0x36, 0x4C, 0x33, 0x54, 0x51, 0x73, 0x0A, 0x41, 0x6C, 0x46, 0x52, 0x77, 0x78, 0x6E, ++ 0x39, 0x57, 0x56, 0x53, 0x45, 0x79, 0x66, 0x46, 0x72, 0x73, 0x30, 0x79, 0x77, 0x36, 0x65, 0x68, 0x47, 0x58, 0x54, 0x6A, 0x47, 0x6F, 0x71, 0x63, 0x75, 0x45, 0x56, 0x65, 0x36, 0x67, 0x68, 0x57, 0x69, 0x6E, 0x49, 0x39, 0x74, 0x73, 0x4A, 0x6C, ++ 0x4B, 0x43, 0x76, 0x4C, 0x72, 0x69, 0x58, 0x42, 0x6A, 0x54, 0x6E, 0x6E, 0x45, 0x74, 0x31, 0x75, 0x39, 0x6F, 0x6C, 0x32, 0x78, 0x38, 0x6B, 0x45, 0x43, 0x4B, 0x36, 0x32, 0x70, 0x0A, 0x4F, 0x71, 0x50, 0x73, 0x65, 0x51, 0x72, 0x73, 0x58, 0x7A, ++ 0x72, 0x6A, 0x2F, 0x65, 0x2B, 0x41, 0x50, 0x4B, 0x30, 0x30, 0x6D, 0x78, 0x71, 0x72, 0x69, 0x43, 0x5A, 0x37, 0x56, 0x71, 0x4B, 0x43, 0x68, 0x68, 0x2F, 0x72, 0x4E, 0x59, 0x6D, 0x44, 0x66, 0x31, 0x2B, 0x75, 0x4B, 0x55, 0x34, 0x39, 0x74, 0x6D, ++ 0x37, 0x73, 0x72, 0x73, 0x48, 0x77, 0x4A, 0x35, 0x75, 0x75, 0x34, 0x2F, 0x54, 0x73, 0x37, 0x36, 0x35, 0x2F, 0x39, 0x34, 0x59, 0x39, 0x63, 0x6E, 0x72, 0x72, 0x0A, 0x70, 0x66, 0x74, 0x5A, 0x54, 0x71, 0x66, 0x72, 0x6C, 0x59, 0x77, 0x69, 0x4F, ++ 0x58, 0x6E, 0x68, 0x4C, 0x51, 0x69, 0x50, 0x7A, 0x4C, 0x79, 0x52, 0x75, 0x45, 0x48, 0x33, 0x46, 0x4D, 0x45, 0x6A, 0x71, 0x63, 0x4F, 0x74, 0x6D, 0x6B, 0x56, 0x45, 0x73, 0x37, 0x4C, 0x58, 0x4C, 0x4D, 0x33, 0x47, 0x4B, 0x65, 0x4A, 0x51, 0x45, ++ 0x4B, 0x35, 0x63, 0x79, 0x34, 0x4B, 0x4F, 0x46, 0x78, 0x67, 0x32, 0x66, 0x5A, 0x66, 0x6D, 0x69, 0x4A, 0x71, 0x77, 0x54, 0x54, 0x51, 0x4A, 0x0A, 0x39, 0x43, 0x79, 0x35, 0x57, 0x6D, 0x59, 0x71, 0x73, 0x42, 0x65, 0x62, 0x6E, 0x68, 0x35, 0x32, ++ 0x6E, 0x55, 0x70, 0x6D, 0x4D, 0x55, 0x48, 0x66, 0x50, 0x2F, 0x76, 0x46, 0x42, 0x75, 0x38, 0x62, 0x74, 0x6E, 0x34, 0x61, 0x52, 0x6A, 0x62, 0x33, 0x5A, 0x47, 0x4D, 0x37, 0x34, 0x7A, 0x6B, 0x59, 0x49, 0x2B, 0x64, 0x6E, 0x64, 0x52, 0x54, 0x56, ++ 0x64, 0x56, 0x65, 0x53, 0x4E, 0x37, 0x32, 0x2B, 0x61, 0x68, 0x73, 0x6D, 0x55, 0x50, 0x49, 0x32, 0x4A, 0x67, 0x61, 0x51, 0x0A, 0x78, 0x58, 0x41, 0x42, 0x5A, 0x47, 0x31, 0x32, 0x5A, 0x75, 0x47, 0x52, 0x32, 0x32, 0x34, 0x48, 0x77, 0x47, 0x47, ++ 0x41, 0x4C, 0x72, 0x49, 0x75, 0x4C, 0x34, 0x78, 0x77, 0x70, 0x39, 0x45, 0x37, 0x50, 0x4C, 0x4F, 0x52, 0x35, 0x47, 0x36, 0x32, 0x78, 0x44, 0x74, 0x77, 0x38, 0x6D, 0x79, 0x53, 0x6C, 0x77, 0x6E, 0x4E, 0x52, 0x33, 0x30, 0x59, 0x77, 0x50, 0x4F, ++ 0x37, 0x6E, 0x67, 0x2F, 0x57, 0x69, 0x36, 0x34, 0x48, 0x74, 0x6C, 0x6F, 0x50, 0x7A, 0x67, 0x73, 0x4D, 0x0A, 0x52, 0x36, 0x66, 0x6C, 0x50, 0x72, 0x69, 0x39, 0x66, 0x63, 0x65, 0x62, 0x4E, 0x61, 0x42, 0x68, 0x6C, 0x7A, 0x70, 0x42, 0x64, 0x52, ++ 0x66, 0x4D, 0x4B, 0x35, 0x5A, 0x33, 0x4B, 0x70, 0x49, 0x68, 0x48, 0x74, 0x6D, 0x56, 0x64, 0x69, 0x42, 0x6E, 0x61, 0x4D, 0x38, 0x4E, 0x76, 0x64, 0x2F, 0x57, 0x48, 0x77, 0x6C, 0x71, 0x6D, 0x75, 0x4C, 0x4D, 0x63, 0x33, 0x47, 0x6B, 0x4C, 0x33, ++ 0x30, 0x53, 0x67, 0x4C, 0x64, 0x54, 0x4D, 0x45, 0x5A, 0x65, 0x53, 0x31, 0x53, 0x5A, 0x0A, 0x44, 0x32, 0x66, 0x4A, 0x70, 0x63, 0x6A, 0x79, 0x49, 0x4D, 0x47, 0x43, 0x37, 0x4A, 0x30, 0x52, 0x33, 0x38, 0x49, 0x43, 0x2B, 0x78, 0x6F, 0x37, 0x30, ++ 0x65, 0x30, 0x67, 0x6D, 0x75, 0x39, 0x6C, 0x5A, 0x4A, 0x49, 0x51, 0x44, 0x53, 0x72, 0x69, 0x33, 0x6E, 0x44, 0x78, 0x47, 0x47, 0x65, 0x43, 0x6A, 0x47, 0x48, 0x65, 0x75, 0x4C, 0x7A, 0x52, 0x4C, 0x35, 0x7A, 0x37, 0x44, 0x39, 0x41, 0x72, 0x37, ++ 0x52, 0x74, 0x32, 0x75, 0x65, 0x51, 0x35, 0x56, 0x66, 0x6A, 0x34, 0x0A, 0x6F, 0x52, 0x32, 0x34, 0x71, 0x6F, 0x41, 0x41, 0x54, 0x49, 0x4C, 0x6E, 0x73, 0x6E, 0x38, 0x4A, 0x75, 0x4C, 0x77, 0x77, 0x6F, 0x43, 0x38, 0x4E, 0x39, 0x56, 0x4B, 0x65, ++ 0x6A, 0x76, 0x65, 0x53, 0x73, 0x77, 0x6F, 0x41, 0x48, 0x51, 0x42, 0x55, 0x6C, 0x77, 0x62, 0x67, 0x73, 0x51, 0x66, 0x5A, 0x78, 0x77, 0x39, 0x63, 0x5A, 0x58, 0x30, 0x38, 0x62, 0x56, 0x6C, 0x58, 0x35, 0x4F, 0x32, 0x6C, 0x6A, 0x65, 0x6C, 0x41, ++ 0x55, 0x35, 0x38, 0x56, 0x53, 0x36, 0x42, 0x78, 0x0A, 0x39, 0x68, 0x6F, 0x68, 0x34, 0x39, 0x70, 0x77, 0x42, 0x69, 0x46, 0x59, 0x46, 0x49, 0x65, 0x46, 0x64, 0x33, 0x6D, 0x71, 0x67, 0x6E, 0x6B, 0x43, 0x41, 0x77, 0x45, 0x41, 0x41, 0x61, 0x4E, ++ 0x43, 0x4D, 0x45, 0x41, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x46, 0x4F, 0x4C, 0x4A, 0x51, 0x4A, 0x39, 0x4E, 0x7A, 0x75, 0x69, 0x61, 0x6F, 0x58, 0x7A, 0x50, 0x44, 0x6A, 0x39, 0x6C, 0x78, 0x53, 0x6D, ++ 0x49, 0x61, 0x68, 0x6C, 0x52, 0x0A, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, ++ 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x47, 0x47, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43, 0x77, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x41, 0x51, 0x44, 0x52, 0x53, 0x56, ++ 0x66, 0x67, 0x0A, 0x70, 0x38, 0x78, 0x6F, 0x57, 0x4C, 0x6F, 0x42, 0x44, 0x79, 0x73, 0x5A, 0x7A, 0x59, 0x32, 0x77, 0x59, 0x55, 0x57, 0x73, 0x45, 0x65, 0x31, 0x6A, 0x55, 0x47, 0x6E, 0x34, 0x48, 0x33, 0x2B, 0x2B, 0x46, 0x6F, 0x2F, 0x39, 0x6E, ++ 0x65, 0x73, 0x4C, 0x71, 0x6A, 0x4A, 0x48, 0x64, 0x74, 0x4A, 0x6E, 0x4A, 0x4F, 0x32, 0x39, 0x66, 0x44, 0x4D, 0x79, 0x6C, 0x79, 0x72, 0x48, 0x42, 0x59, 0x5A, 0x6D, 0x44, 0x52, 0x64, 0x39, 0x46, 0x42, 0x55, 0x62, 0x31, 0x4F, 0x76, 0x39, 0x0A, ++ 0x48, 0x35, 0x72, 0x32, 0x58, 0x70, 0x64, 0x70, 0x74, 0x78, 0x6F, 0x6C, 0x70, 0x41, 0x71, 0x7A, 0x6B, 0x54, 0x39, 0x66, 0x4E, 0x71, 0x79, 0x4C, 0x37, 0x46, 0x65, 0x6F, 0x50, 0x75, 0x65, 0x42, 0x69, 0x68, 0x68, 0x58, 0x4F, 0x59, 0x56, 0x30, ++ 0x47, 0x6B, 0x4C, 0x48, 0x36, 0x56, 0x73, 0x54, 0x58, 0x34, 0x2F, 0x35, 0x43, 0x4F, 0x6D, 0x53, 0x64, 0x49, 0x33, 0x31, 0x52, 0x39, 0x4B, 0x72, 0x4F, 0x39, 0x62, 0x37, 0x65, 0x47, 0x5A, 0x4F, 0x4E, 0x6E, 0x33, 0x35, 0x0A, 0x36, 0x5A, 0x4C, ++ 0x70, 0x42, 0x4E, 0x37, 0x39, 0x53, 0x57, 0x50, 0x38, 0x62, 0x66, 0x73, 0x55, 0x63, 0x5A, 0x4E, 0x6E, 0x4C, 0x30, 0x64, 0x4B, 0x74, 0x37, 0x6E, 0x2F, 0x48, 0x69, 0x70, 0x7A, 0x63, 0x45, 0x59, 0x77, 0x76, 0x31, 0x72, 0x79, 0x4C, 0x33, 0x6D, ++ 0x6C, 0x34, 0x59, 0x30, 0x4D, 0x32, 0x66, 0x6D, 0x79, 0x59, 0x7A, 0x65, 0x4D, 0x4E, 0x32, 0x57, 0x46, 0x63, 0x47, 0x70, 0x63, 0x57, 0x77, 0x6C, 0x79, 0x75, 0x61, 0x31, 0x6A, 0x50, 0x4C, 0x48, 0x64, 0x0A, 0x2B, 0x50, 0x77, 0x79, 0x76, 0x7A, ++ 0x65, 0x47, 0x35, 0x4C, 0x75, 0x4F, 0x6D, 0x43, 0x64, 0x2B, 0x75, 0x68, 0x38, 0x57, 0x34, 0x58, 0x41, 0x52, 0x38, 0x67, 0x50, 0x66, 0x4A, 0x57, 0x49, 0x79, 0x4A, 0x79, 0x59, 0x59, 0x4D, 0x6F, 0x53, 0x66, 0x2F, 0x77, 0x41, 0x36, 0x45, 0x37, ++ 0x71, 0x61, 0x54, 0x66, 0x52, 0x50, 0x75, 0x42, 0x52, 0x77, 0x49, 0x72, 0x48, 0x4B, 0x4B, 0x35, 0x44, 0x4F, 0x4B, 0x63, 0x46, 0x77, 0x39, 0x43, 0x2B, 0x64, 0x66, 0x2F, 0x4B, 0x51, 0x0A, 0x48, 0x74, 0x5A, 0x61, 0x33, 0x37, 0x64, 0x47, 0x2F, ++ 0x4F, 0x61, 0x47, 0x2B, 0x73, 0x76, 0x67, 0x49, 0x48, 0x5A, 0x36, 0x75, 0x71, 0x62, 0x4C, 0x39, 0x58, 0x7A, 0x65, 0x59, 0x71, 0x57, 0x78, 0x69, 0x2B, 0x37, 0x65, 0x67, 0x6D, 0x61, 0x4B, 0x54, 0x6A, 0x6F, 0x77, 0x48, 0x7A, 0x2B, 0x41, 0x79, ++ 0x36, 0x30, 0x6E, 0x75, 0x67, 0x78, 0x65, 0x31, 0x39, 0x43, 0x78, 0x56, 0x73, 0x70, 0x33, 0x63, 0x62, 0x4B, 0x31, 0x64, 0x61, 0x46, 0x51, 0x71, 0x55, 0x42, 0x44, 0x0A, 0x46, 0x38, 0x49, 0x6F, 0x32, 0x63, 0x39, 0x53, 0x69, 0x31, 0x76, 0x49, ++ 0x59, 0x39, 0x52, 0x43, 0x50, 0x71, 0x41, 0x7A, 0x65, 0x6B, 0x59, 0x75, 0x39, 0x77, 0x6F, 0x67, 0x52, 0x6C, 0x52, 0x2B, 0x61, 0x6B, 0x38, 0x78, 0x38, 0x59, 0x46, 0x2B, 0x51, 0x6E, 0x51, 0x34, 0x5A, 0x58, 0x4D, 0x6E, 0x37, 0x73, 0x5A, 0x38, ++ 0x75, 0x49, 0x37, 0x58, 0x70, 0x54, 0x72, 0x58, 0x6D, 0x4B, 0x47, 0x63, 0x6A, 0x42, 0x42, 0x56, 0x30, 0x39, 0x74, 0x4C, 0x37, 0x45, 0x43, 0x51, 0x0A, 0x38, 0x73, 0x31, 0x75, 0x56, 0x39, 0x4A, 0x69, 0x44, 0x6E, 0x78, 0x58, 0x6B, 0x37, 0x47, ++ 0x6E, 0x62, 0x63, 0x32, 0x64, 0x67, 0x37, 0x73, 0x71, 0x35, 0x2B, 0x57, 0x32, 0x4F, 0x33, 0x46, 0x59, 0x72, 0x66, 0x33, 0x52, 0x52, 0x62, 0x78, 0x61, 0x6B, 0x65, 0x35, 0x54, 0x46, 0x57, 0x2F, 0x54, 0x52, 0x51, 0x6C, 0x31, 0x62, 0x72, 0x71, ++ 0x51, 0x58, 0x52, 0x34, 0x45, 0x7A, 0x7A, 0x66, 0x66, 0x48, 0x71, 0x68, 0x6D, 0x73, 0x59, 0x7A, 0x6D, 0x49, 0x47, 0x72, 0x76, 0x0A, 0x2F, 0x45, 0x68, 0x4F, 0x64, 0x4A, 0x68, 0x43, 0x72, 0x79, 0x6C, 0x76, 0x4C, 0x6D, 0x72, 0x48, 0x2B, 0x33, ++ 0x33, 0x52, 0x5A, 0x6A, 0x45, 0x69, 0x7A, 0x49, 0x59, 0x41, 0x66, 0x6D, 0x61, 0x44, 0x44, 0x45, 0x4C, 0x30, 0x76, 0x54, 0x53, 0x53, 0x77, 0x78, 0x72, 0x71, 0x54, 0x38, 0x70, 0x2B, 0x63, 0x6B, 0x30, 0x4C, 0x63, 0x49, 0x79, 0x6D, 0x53, 0x4C, ++ 0x75, 0x6D, 0x6F, 0x52, 0x54, 0x32, 0x2B, 0x31, 0x68, 0x45, 0x6D, 0x52, 0x53, 0x75, 0x71, 0x67, 0x75, 0x54, 0x0A, 0x61, 0x61, 0x41, 0x70, 0x4A, 0x55, 0x71, 0x6C, 0x79, 0x79, 0x76, 0x64, 0x69, 0x6D, 0x59, 0x48, 0x46, 0x6E, 0x67, 0x56, 0x56, ++ 0x33, 0x45, 0x62, 0x37, 0x50, 0x56, 0x48, 0x68, 0x50, 0x4F, 0x65, 0x4D, 0x54, 0x64, 0x36, 0x31, 0x58, 0x38, 0x6B, 0x72, 0x65, 0x53, 0x38, 0x2F, 0x66, 0x33, 0x4D, 0x62, 0x6F, 0x50, 0x6F, 0x44, 0x4B, 0x69, 0x33, 0x51, 0x57, 0x77, 0x48, 0x33, ++ 0x62, 0x30, 0x38, 0x68, 0x70, 0x63, 0x76, 0x30, 0x67, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x53, ++ 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x53, 0x41, 0x0A, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x33, 0x54, 0x43, 0x43, 0x41, 0x38, 0x57, ++ 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x49, 0x65, 0x79, 0x79, 0x62, 0x30, 0x78, 0x61, 0x41, 0x4D, 0x70, 0x6B, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, ++ 0x77, 0x66, 0x44, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x56, 0x56, 0x4D, 0x78, 0x44, 0x6A, 0x41, 0x4D, 0x0A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x67, 0x4D, 0x42, 0x56, 0x52, 0x6C, 0x65, 0x47, ++ 0x46, 0x7A, 0x4D, 0x52, 0x41, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x48, 0x44, 0x41, 0x64, 0x49, 0x62, 0x33, 0x56, 0x7A, 0x64, 0x47, 0x39, 0x75, 0x4D, 0x52, 0x67, 0x77, 0x46, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x44, 0x41, ++ 0x39, 0x54, 0x55, 0x30, 0x77, 0x67, 0x51, 0x32, 0x39, 0x79, 0x63, 0x47, 0x39, 0x79, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x78, 0x0A, 0x4D, 0x54, 0x41, 0x76, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x4B, 0x46, 0x4E, 0x54, 0x54, ++ 0x43, 0x35, 0x6A, 0x62, 0x32, 0x30, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x61, 0x57, 0x5A, 0x70, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x49, 0x45, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63, ++ 0x6D, 0x6C, 0x30, 0x65, 0x53, 0x42, 0x53, 0x55, 0x30, 0x45, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x54, 0x59, 0x77, 0x0A, 0x4D, 0x6A, 0x45, 0x79, 0x4D, 0x54, 0x63, 0x7A, 0x4F, 0x54, 0x4D, 0x35, 0x57, 0x68, 0x63, 0x4E, 0x4E, 0x44, 0x45, 0x77, ++ 0x4D, 0x6A, 0x45, 0x79, 0x4D, 0x54, 0x63, 0x7A, 0x4F, 0x54, 0x4D, 0x35, 0x57, 0x6A, 0x42, 0x38, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x4F, 0x4D, 0x41, 0x77, 0x47, ++ 0x41, 0x31, 0x55, 0x45, 0x43, 0x41, 0x77, 0x46, 0x56, 0x47, 0x56, 0x34, 0x59, 0x58, 0x4D, 0x78, 0x0A, 0x45, 0x44, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x63, 0x4D, 0x42, 0x30, 0x68, 0x76, 0x64, 0x58, 0x4E, 0x30, 0x62, 0x32, 0x34, ++ 0x78, 0x47, 0x44, 0x41, 0x57, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x44, 0x31, 0x4E, 0x54, 0x54, 0x43, 0x42, 0x44, 0x62, 0x33, 0x4A, 0x77, 0x62, 0x33, 0x4A, 0x68, 0x64, 0x47, 0x6C, 0x76, 0x62, 0x6A, 0x45, 0x78, 0x4D, 0x43, 0x38, ++ 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x6F, 0x55, 0x31, 0x4E, 0x4D, 0x0A, 0x4C, 0x6D, 0x4E, 0x76, 0x62, 0x53, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x6C, 0x63, 0x6E, 0x52, 0x70, 0x5A, 0x6D, 0x6C, 0x6A, 0x59, 0x58, ++ 0x52, 0x70, 0x62, 0x32, 0x34, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52, 0x35, 0x49, 0x46, 0x4A, 0x54, 0x51, 0x54, 0x43, 0x43, 0x41, 0x69, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, ++ 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x0A, 0x67, 0x67, 0x49, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x67, 0x6F, 0x43, 0x67, 0x67, 0x49, 0x42, 0x41, 0x50, 0x6B, 0x50, 0x33, 0x61, 0x4D, 0x72, 0x66, 0x63, 0x76, 0x51, 0x4B, ++ 0x76, 0x37, 0x73, 0x5A, 0x34, 0x57, 0x6D, 0x35, 0x79, 0x34, 0x62, 0x75, 0x6E, 0x66, 0x68, 0x34, 0x2F, 0x57, 0x76, 0x70, 0x4F, 0x7A, 0x36, 0x53, 0x6C, 0x32, 0x52, 0x78, 0x46, 0x64, 0x48, 0x61, 0x78, 0x68, 0x33, 0x61, 0x33, 0x62, 0x79, 0x2F, ++ 0x5A, 0x50, 0x6B, 0x50, 0x51, 0x2F, 0x43, 0x0A, 0x46, 0x70, 0x34, 0x4C, 0x5A, 0x73, 0x4E, 0x57, 0x6C, 0x4A, 0x34, 0x58, 0x67, 0x34, 0x58, 0x4F, 0x56, 0x75, 0x2F, 0x79, 0x46, 0x76, 0x30, 0x41, 0x59, 0x76, 0x55, 0x69, 0x43, 0x56, 0x54, 0x6F, ++ 0x5A, 0x52, 0x64, 0x4F, 0x51, 0x62, 0x6E, 0x67, 0x54, 0x30, 0x61, 0x58, 0x71, 0x68, 0x76, 0x49, 0x75, 0x47, 0x35, 0x69, 0x58, 0x6D, 0x6D, 0x78, 0x58, 0x39, 0x73, 0x71, 0x41, 0x6E, 0x37, 0x38, 0x62, 0x4D, 0x72, 0x7A, 0x51, 0x64, 0x6A, 0x74, ++ 0x30, 0x4F, 0x6A, 0x38, 0x0A, 0x50, 0x32, 0x46, 0x49, 0x37, 0x62, 0x41, 0x44, 0x46, 0x42, 0x30, 0x51, 0x44, 0x6B, 0x73, 0x5A, 0x34, 0x4C, 0x74, 0x4F, 0x37, 0x49, 0x5A, 0x6C, 0x2F, 0x7A, 0x62, 0x7A, 0x58, 0x6D, 0x63, 0x43, 0x43, 0x35, 0x32, ++ 0x47, 0x56, 0x57, 0x48, 0x39, 0x65, 0x6A, 0x6A, 0x74, 0x2F, 0x75, 0x49, 0x5A, 0x41, 0x4C, 0x64, 0x76, 0x6F, 0x56, 0x42, 0x69, 0x64, 0x58, 0x51, 0x38, 0x6F, 0x50, 0x72, 0x49, 0x4A, 0x5A, 0x4B, 0x30, 0x62, 0x6E, 0x6F, 0x69, 0x78, 0x2F, 0x67, ++ 0x65, 0x0A, 0x6F, 0x65, 0x4F, 0x79, 0x33, 0x5A, 0x45, 0x78, 0x71, 0x79, 0x73, 0x64, 0x42, 0x50, 0x2B, 0x6C, 0x53, 0x67, 0x51, 0x33, 0x36, 0x59, 0x57, 0x6B, 0x4D, 0x79, 0x76, 0x39, 0x34, 0x74, 0x5A, 0x56, 0x4E, 0x48, 0x77, 0x5A, 0x70, 0x45, ++ 0x70, 0x6F, 0x78, 0x37, 0x4B, 0x6F, 0x30, 0x37, 0x66, 0x4B, 0x6F, 0x5A, 0x4F, 0x49, 0x36, 0x38, 0x47, 0x58, 0x76, 0x49, 0x7A, 0x35, 0x48, 0x64, 0x6B, 0x69, 0x68, 0x43, 0x52, 0x30, 0x78, 0x77, 0x51, 0x39, 0x61, 0x71, 0x6B, 0x70, 0x0A, 0x6B, ++ 0x38, 0x7A, 0x72, 0x75, 0x46, 0x76, 0x68, 0x2F, 0x6C, 0x38, 0x6C, 0x71, 0x6A, 0x52, 0x59, 0x79, 0x4D, 0x45, 0x6A, 0x56, 0x4A, 0x30, 0x62, 0x6D, 0x42, 0x48, 0x44, 0x4F, 0x4A, 0x78, 0x2B, 0x50, 0x59, 0x5A, 0x73, 0x70, 0x51, 0x39, 0x41, 0x68, ++ 0x6E, 0x77, 0x43, 0x39, 0x46, 0x77, 0x43, 0x54, 0x79, 0x6A, 0x4C, 0x72, 0x6E, 0x47, 0x66, 0x44, 0x7A, 0x72, 0x49, 0x4D, 0x2F, 0x34, 0x52, 0x4A, 0x54, 0x58, 0x71, 0x2F, 0x4C, 0x72, 0x46, 0x59, 0x44, 0x33, 0x5A, 0x0A, 0x66, 0x42, 0x6A, 0x56, ++ 0x73, 0x71, 0x6E, 0x54, 0x64, 0x58, 0x67, 0x44, 0x63, 0x69, 0x4C, 0x4B, 0x4F, 0x73, 0x4D, 0x66, 0x37, 0x79, 0x7A, 0x6C, 0x4C, 0x71, 0x6E, 0x36, 0x6E, 0x69, 0x79, 0x32, 0x55, 0x55, 0x62, 0x39, 0x72, 0x77, 0x50, 0x57, 0x36, 0x6D, 0x42, 0x6F, ++ 0x36, 0x6F, 0x55, 0x57, 0x4E, 0x6D, 0x75, 0x46, 0x36, 0x52, 0x37, 0x41, 0x73, 0x39, 0x33, 0x45, 0x4A, 0x4E, 0x79, 0x41, 0x4B, 0x6F, 0x46, 0x42, 0x62, 0x5A, 0x51, 0x2B, 0x79, 0x4F, 0x44, 0x4A, 0x0A, 0x67, 0x55, 0x45, 0x41, 0x6E, 0x6C, 0x36, ++ 0x2F, 0x66, 0x38, 0x55, 0x49, 0x6D, 0x4B, 0x49, 0x59, 0x4C, 0x45, 0x4A, 0x41, 0x73, 0x2F, 0x6C, 0x76, 0x4F, 0x43, 0x64, 0x4C, 0x54, 0x6F, 0x44, 0x30, 0x50, 0x59, 0x46, 0x48, 0x34, 0x49, 0x68, 0x38, 0x36, 0x68, 0x7A, 0x4F, 0x74, 0x58, 0x56, ++ 0x63, 0x55, 0x53, 0x34, 0x63, 0x4B, 0x33, 0x38, 0x61, 0x63, 0x69, 0x6A, 0x6E, 0x41, 0x4C, 0x58, 0x52, 0x64, 0x4D, 0x62, 0x58, 0x35, 0x4A, 0x2B, 0x74, 0x42, 0x35, 0x4F, 0x32, 0x0A, 0x55, 0x7A, 0x55, 0x31, 0x2F, 0x44, 0x66, 0x6B, 0x77, 0x2F, ++ 0x5A, 0x64, 0x46, 0x72, 0x34, 0x68, 0x63, 0x39, 0x36, 0x53, 0x43, 0x76, 0x69, 0x67, 0x59, 0x32, 0x71, 0x38, 0x6C, 0x70, 0x4A, 0x71, 0x50, 0x76, 0x69, 0x38, 0x5A, 0x56, 0x57, 0x62, 0x33, 0x76, 0x55, 0x4E, 0x69, 0x53, 0x59, 0x45, 0x2F, 0x43, ++ 0x55, 0x61, 0x70, 0x69, 0x56, 0x70, 0x79, 0x38, 0x4A, 0x74, 0x79, 0x6E, 0x7A, 0x69, 0x57, 0x56, 0x2B, 0x58, 0x72, 0x4F, 0x76, 0x76, 0x4C, 0x73, 0x69, 0x38, 0x0A, 0x31, 0x78, 0x74, 0x5A, 0x50, 0x43, 0x76, 0x4D, 0x38, 0x68, 0x6E, 0x49, 0x6B, ++ 0x32, 0x73, 0x6E, 0x59, 0x78, 0x6E, 0x50, 0x2F, 0x4F, 0x6B, 0x6D, 0x2B, 0x4D, 0x70, 0x78, 0x6D, 0x33, 0x2B, 0x54, 0x2F, 0x6A, 0x52, 0x6E, 0x68, 0x45, 0x36, 0x5A, 0x36, 0x2F, 0x79, 0x7A, 0x65, 0x41, 0x6B, 0x7A, 0x63, 0x4C, 0x70, 0x6D, 0x70, ++ 0x6E, 0x62, 0x74, 0x47, 0x33, 0x50, 0x72, 0x47, 0x71, 0x55, 0x4E, 0x78, 0x43, 0x49, 0x54, 0x49, 0x4A, 0x52, 0x57, 0x43, 0x6B, 0x34, 0x73, 0x0A, 0x62, 0x45, 0x36, 0x78, 0x2F, 0x63, 0x2B, 0x63, 0x43, 0x62, 0x71, 0x69, 0x4D, 0x2B, 0x32, 0x48, ++ 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, 0x59, 0x7A, 0x42, 0x68, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x54, 0x64, 0x42, 0x41, 0x6B, 0x48, 0x6F, 0x76, 0x56, 0x36, 0x66, 0x56, 0x4A, 0x54, ++ 0x45, 0x70, 0x4B, 0x56, 0x37, 0x6A, 0x69, 0x41, 0x4A, 0x51, 0x32, 0x6D, 0x57, 0x54, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x0A, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x42, 0x38, ++ 0x47, 0x41, 0x31, 0x55, 0x64, 0x49, 0x77, 0x51, 0x59, 0x4D, 0x42, 0x61, 0x41, 0x46, 0x4E, 0x30, 0x45, 0x43, 0x51, 0x65, 0x69, 0x39, 0x58, 0x70, 0x39, 0x55, 0x6C, 0x4D, 0x53, 0x6B, 0x70, 0x58, 0x75, 0x4F, 0x49, 0x41, 0x6C, 0x44, 0x61, 0x5A, ++ 0x5A, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x0A, 0x41, 0x77, 0x49, 0x42, 0x68, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, ++ 0x73, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x67, 0x45, 0x41, 0x49, 0x42, 0x67, 0x52, 0x6C, 0x43, 0x6E, 0x37, 0x4A, 0x70, 0x30, 0x63, 0x48, 0x68, 0x35, 0x77, 0x59, 0x66, 0x47, 0x56, 0x63, 0x70, 0x4E, 0x78, 0x4A, 0x4B, 0x31, 0x6F, 0x6B, 0x31, ++ 0x69, 0x4F, 0x4D, 0x71, 0x38, 0x62, 0x73, 0x33, 0x41, 0x44, 0x2F, 0x43, 0x55, 0x72, 0x0A, 0x64, 0x49, 0x57, 0x51, 0x50, 0x58, 0x68, 0x71, 0x39, 0x4C, 0x6D, 0x4C, 0x70, 0x5A, 0x63, 0x37, 0x74, 0x52, 0x69, 0x52, 0x75, 0x78, 0x36, 0x6E, 0x2B, ++ 0x55, 0x42, 0x62, 0x6B, 0x66, 0x6C, 0x56, 0x6D, 0x61, 0x38, 0x65, 0x45, 0x64, 0x42, 0x63, 0x48, 0x61, 0x64, 0x6D, 0x34, 0x37, 0x47, 0x55, 0x42, 0x77, 0x77, 0x79, 0x4F, 0x61, 0x62, 0x71, 0x47, 0x37, 0x42, 0x35, 0x32, 0x42, 0x32, 0x63, 0x63, ++ 0x45, 0x54, 0x6A, 0x69, 0x74, 0x33, 0x45, 0x2B, 0x5A, 0x55, 0x66, 0x0A, 0x69, 0x6A, 0x68, 0x44, 0x50, 0x77, 0x47, 0x46, 0x70, 0x55, 0x65, 0x6E, 0x50, 0x55, 0x61, 0x79, 0x76, 0x4F, 0x55, 0x69, 0x61, 0x50, 0x64, 0x37, 0x6E, 0x4E, 0x67, 0x73, ++ 0x50, 0x67, 0x6F, 0x68, 0x79, 0x43, 0x30, 0x7A, 0x72, 0x4C, 0x2F, 0x46, 0x67, 0x5A, 0x6B, 0x78, 0x64, 0x4D, 0x46, 0x31, 0x63, 0x63, 0x57, 0x2B, 0x73, 0x66, 0x41, 0x6A, 0x52, 0x66, 0x53, 0x64, 0x61, 0x2F, 0x77, 0x5A, 0x59, 0x35, 0x32, 0x6A, ++ 0x76, 0x41, 0x54, 0x47, 0x47, 0x41, 0x73, 0x6C, 0x0A, 0x75, 0x31, 0x4F, 0x4A, 0x44, 0x37, 0x4F, 0x41, 0x55, 0x4E, 0x35, 0x46, 0x37, 0x6B, 0x52, 0x2F, 0x71, 0x35, 0x52, 0x34, 0x5A, 0x4A, 0x6A, 0x54, 0x39, 0x69, 0x6A, 0x64, 0x68, 0x39, 0x68, ++ 0x77, 0x5A, 0x58, 0x54, 0x37, 0x44, 0x72, 0x6B, 0x54, 0x36, 0x36, 0x63, 0x50, 0x59, 0x61, 0x6B, 0x79, 0x6C, 0x73, 0x7A, 0x65, 0x75, 0x2B, 0x31, 0x6A, 0x54, 0x42, 0x69, 0x37, 0x71, 0x55, 0x44, 0x33, 0x6F, 0x46, 0x52, 0x75, 0x49, 0x49, 0x68, ++ 0x78, 0x64, 0x52, 0x6A, 0x71, 0x0A, 0x65, 0x72, 0x51, 0x30, 0x63, 0x75, 0x41, 0x6A, 0x4A, 0x33, 0x64, 0x63, 0x74, 0x70, 0x44, 0x71, 0x68, 0x69, 0x56, 0x41, 0x71, 0x2B, 0x38, 0x7A, 0x44, 0x38, 0x75, 0x66, 0x67, 0x72, 0x36, 0x69, 0x49, 0x50, ++ 0x76, 0x32, 0x74, 0x53, 0x30, 0x61, 0x35, 0x73, 0x4B, 0x46, 0x73, 0x58, 0x51, 0x50, 0x2B, 0x38, 0x68, 0x6C, 0x41, 0x71, 0x52, 0x53, 0x41, 0x55, 0x66, 0x64, 0x53, 0x53, 0x4C, 0x42, 0x76, 0x39, 0x6A, 0x72, 0x61, 0x36, 0x78, 0x2B, 0x33, 0x75, ++ 0x78, 0x6A, 0x0A, 0x4D, 0x78, 0x57, 0x33, 0x49, 0x77, 0x69, 0x50, 0x78, 0x67, 0x2B, 0x4E, 0x51, 0x56, 0x72, 0x64, 0x6A, 0x73, 0x57, 0x35, 0x6A, 0x2B, 0x56, 0x46, 0x50, 0x33, 0x6A, 0x62, 0x75, 0x74, 0x49, 0x62, 0x51, 0x4C, 0x48, 0x2B, 0x63, ++ 0x55, 0x30, 0x2F, 0x34, 0x49, 0x47, 0x69, 0x75, 0x6C, 0x36, 0x30, 0x37, 0x42, 0x58, 0x67, 0x6B, 0x39, 0x30, 0x49, 0x48, 0x33, 0x37, 0x68, 0x56, 0x5A, 0x6B, 0x4C, 0x49, 0x64, 0x36, 0x54, 0x6E, 0x67, 0x72, 0x37, 0x35, 0x71, 0x4E, 0x4A, 0x0A, ++ 0x76, 0x54, 0x59, 0x77, 0x2F, 0x75, 0x64, 0x33, 0x73, 0x71, 0x42, 0x31, 0x6C, 0x37, 0x55, 0x74, 0x67, 0x59, 0x67, 0x58, 0x5A, 0x53, 0x44, 0x33, 0x32, 0x70, 0x41, 0x41, 0x6E, 0x38, 0x6C, 0x53, 0x7A, 0x44, 0x4C, 0x4B, 0x4E, 0x58, 0x7A, 0x31, ++ 0x50, 0x51, 0x2F, 0x59, 0x4B, 0x39, 0x66, 0x31, 0x4A, 0x6D, 0x7A, 0x4A, 0x42, 0x6A, 0x53, 0x57, 0x46, 0x75, 0x70, 0x77, 0x57, 0x52, 0x6F, 0x79, 0x65, 0x58, 0x6B, 0x4C, 0x74, 0x6F, 0x68, 0x2F, 0x44, 0x31, 0x4A, 0x49, 0x0A, 0x50, 0x62, 0x39, ++ 0x73, 0x32, 0x4B, 0x4A, 0x45, 0x4C, 0x74, 0x46, 0x4F, 0x74, 0x33, 0x4A, 0x59, 0x30, 0x34, 0x6B, 0x54, 0x6C, 0x66, 0x35, 0x45, 0x71, 0x2F, 0x6A, 0x58, 0x69, 0x78, 0x74, 0x75, 0x6E, 0x4C, 0x77, 0x73, 0x6F, 0x46, 0x76, 0x56, 0x61, 0x67, 0x43, ++ 0x76, 0x58, 0x7A, 0x66, 0x68, 0x31, 0x66, 0x6F, 0x51, 0x43, 0x35, 0x69, 0x63, 0x68, 0x75, 0x63, 0x6D, 0x6A, 0x38, 0x37, 0x77, 0x37, 0x47, 0x36, 0x4B, 0x56, 0x77, 0x75, 0x41, 0x34, 0x30, 0x36, 0x79, 0x0A, 0x77, 0x4B, 0x42, 0x6A, 0x59, 0x5A, ++ 0x43, 0x36, 0x56, 0x57, 0x67, 0x33, 0x64, 0x47, 0x71, 0x32, 0x6B, 0x74, 0x75, 0x66, 0x6F, 0x59, 0x59, 0x69, 0x74, 0x6D, 0x55, 0x6E, 0x44, 0x75, 0x79, 0x32, 0x6E, 0x30, 0x4A, 0x67, 0x35, 0x47, 0x66, 0x43, 0x74, 0x64, 0x70, 0x42, 0x43, 0x38, ++ 0x54, 0x54, 0x69, 0x32, 0x45, 0x62, 0x76, 0x50, 0x6F, 0x66, 0x6B, 0x53, 0x76, 0x58, 0x52, 0x41, 0x64, 0x65, 0x75, 0x69, 0x6D, 0x73, 0x32, 0x63, 0x58, 0x70, 0x37, 0x31, 0x4E, 0x49, 0x0A, 0x57, 0x75, 0x75, 0x41, 0x38, 0x53, 0x68, 0x59, 0x49, ++ 0x63, 0x32, 0x77, 0x42, 0x6C, 0x58, 0x37, 0x4A, 0x7A, 0x39, 0x54, 0x6B, 0x48, 0x43, 0x70, 0x42, 0x42, 0x35, 0x58, 0x4A, 0x37, 0x6B, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, ++ 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, ++ 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x45, 0x43, 0x43, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x6A, 0x54, 0x43, 0x43, 0x41, 0x68, 0x53, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x49, 0x64, 0x65, 0x62, 0x66, 0x79, 0x38, 0x46, 0x6F, 0x57, 0x36, 0x67, 0x77, 0x43, 0x67, 0x59, 0x49, 0x4B, 0x6F, 0x5A, ++ 0x49, 0x7A, 0x6A, 0x30, 0x45, 0x41, 0x77, 0x49, 0x77, 0x66, 0x44, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x56, 0x56, 0x4D, 0x78, 0x44, 0x6A, 0x41, 0x4D, 0x42, 0x67, 0x4E, 0x56, 0x0A, 0x42, 0x41, ++ 0x67, 0x4D, 0x42, 0x56, 0x52, 0x6C, 0x65, 0x47, 0x46, 0x7A, 0x4D, 0x52, 0x41, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x48, 0x44, 0x41, 0x64, 0x49, 0x62, 0x33, 0x56, 0x7A, 0x64, 0x47, 0x39, 0x75, 0x4D, 0x52, 0x67, 0x77, 0x46, 0x67, ++ 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x44, 0x41, 0x39, 0x54, 0x55, 0x30, 0x77, 0x67, 0x51, 0x32, 0x39, 0x79, 0x63, 0x47, 0x39, 0x79, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x78, 0x4D, 0x54, 0x41, 0x76, 0x0A, 0x42, 0x67, 0x4E, 0x56, 0x42, ++ 0x41, 0x4D, 0x4D, 0x4B, 0x46, 0x4E, 0x54, 0x54, 0x43, 0x35, 0x6A, 0x62, 0x32, 0x30, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x61, 0x57, 0x5A, 0x70, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x49, ++ 0x45, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6D, 0x6C, 0x30, 0x65, 0x53, 0x42, 0x46, 0x51, 0x30, 0x4D, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x54, 0x59, 0x77, 0x4D, 0x6A, 0x45, 0x79, 0x0A, 0x4D, 0x54, 0x67, 0x78, 0x4E, 0x44, 0x41, 0x7A, ++ 0x57, 0x68, 0x63, 0x4E, 0x4E, 0x44, 0x45, 0x77, 0x4D, 0x6A, 0x45, 0x79, 0x4D, 0x54, 0x67, 0x78, 0x4E, 0x44, 0x41, 0x7A, 0x57, 0x6A, 0x42, 0x38, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, ++ 0x55, 0x7A, 0x45, 0x4F, 0x4D, 0x41, 0x77, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x41, 0x77, 0x46, 0x56, 0x47, 0x56, 0x34, 0x59, 0x58, 0x4D, 0x78, 0x45, 0x44, 0x41, 0x4F, 0x0A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x63, 0x4D, 0x42, 0x30, 0x68, ++ 0x76, 0x64, 0x58, 0x4E, 0x30, 0x62, 0x32, 0x34, 0x78, 0x47, 0x44, 0x41, 0x57, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x44, 0x31, 0x4E, 0x54, 0x54, 0x43, 0x42, 0x44, 0x62, 0x33, 0x4A, 0x77, 0x62, 0x33, 0x4A, 0x68, 0x64, 0x47, 0x6C, ++ 0x76, 0x62, 0x6A, 0x45, 0x78, 0x4D, 0x43, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x6F, 0x55, 0x31, 0x4E, 0x4D, 0x4C, 0x6D, 0x4E, 0x76, 0x0A, 0x62, 0x53, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x6C, 0x63, 0x6E, ++ 0x52, 0x70, 0x5A, 0x6D, 0x6C, 0x6A, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52, 0x35, 0x49, 0x45, 0x56, 0x44, 0x51, 0x7A, 0x42, 0x32, 0x4D, 0x42, 0x41, 0x47, 0x42, 0x79, ++ 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x41, 0x67, 0x45, 0x47, 0x42, 0x53, 0x75, 0x42, 0x42, 0x41, 0x41, 0x69, 0x41, 0x32, 0x49, 0x41, 0x0A, 0x42, 0x45, 0x56, 0x75, 0x71, 0x56, 0x44, 0x45, 0x70, 0x69, 0x4D, 0x32, 0x6E, 0x6C, 0x38, 0x6F, 0x6A, ++ 0x52, 0x66, 0x4C, 0x6C, 0x69, 0x4A, 0x6B, 0x50, 0x39, 0x78, 0x36, 0x6A, 0x68, 0x33, 0x4D, 0x43, 0x4C, 0x4F, 0x69, 0x63, 0x53, 0x53, 0x36, 0x6A, 0x6B, 0x6D, 0x35, 0x42, 0x42, 0x74, 0x48, 0x6C, 0x6C, 0x69, 0x72, 0x4C, 0x5A, 0x58, 0x49, 0x37, ++ 0x5A, 0x34, 0x49, 0x4E, 0x63, 0x67, 0x6E, 0x36, 0x34, 0x6D, 0x4D, 0x55, 0x31, 0x6A, 0x72, 0x59, 0x6F, 0x72, 0x2B, 0x0A, 0x38, 0x46, 0x73, 0x50, 0x61, 0x7A, 0x46, 0x53, 0x59, 0x30, 0x45, 0x37, 0x69, 0x63, 0x33, 0x73, 0x37, 0x4C, 0x61, 0x4E, ++ 0x47, 0x64, 0x4D, 0x30, 0x42, 0x39, 0x79, 0x37, 0x78, 0x67, 0x5A, 0x2F, 0x77, 0x6B, 0x57, 0x56, 0x37, 0x4D, 0x74, 0x2F, 0x71, 0x43, 0x50, 0x67, 0x43, 0x65, 0x6D, 0x42, 0x2B, 0x76, 0x4E, 0x48, 0x30, 0x36, 0x4E, 0x6A, 0x4D, 0x47, 0x45, 0x77, ++ 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x46, 0x49, 0x4C, 0x52, 0x0A, 0x68, 0x58, 0x4D, 0x77, 0x35, 0x7A, 0x55, 0x45, 0x30, 0x34, 0x34, 0x43, 0x6B, 0x76, 0x76, 0x6C, 0x70, 0x4E, 0x48, 0x45, 0x49, 0x65, 0x6A, ++ 0x4E, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x48, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x6A, 0x42, 0x42, 0x67, 0x77, 0x46, 0x6F, 0x41, ++ 0x55, 0x67, 0x74, 0x47, 0x46, 0x63, 0x7A, 0x44, 0x6E, 0x4E, 0x51, 0x54, 0x54, 0x0A, 0x6A, 0x67, 0x4B, 0x53, 0x2B, 0x2B, 0x57, 0x6B, 0x30, 0x63, 0x51, 0x68, 0x36, 0x4D, 0x30, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, ++ 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x47, 0x47, 0x4D, 0x41, 0x6F, 0x47, 0x43, 0x43, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x32, 0x63, 0x41, 0x4D, 0x47, 0x51, 0x43, 0x4D, 0x47, 0x2F, 0x6E, 0x36, 0x31, ++ 0x6B, 0x52, 0x70, 0x47, 0x44, 0x50, 0x59, 0x62, 0x43, 0x57, 0x0A, 0x65, 0x2B, 0x30, 0x46, 0x2B, 0x53, 0x38, 0x54, 0x6B, 0x64, 0x7A, 0x74, 0x35, 0x66, 0x78, 0x51, 0x61, 0x78, 0x46, 0x47, 0x52, 0x72, 0x4D, 0x63, 0x49, 0x51, 0x42, 0x69, 0x75, ++ 0x37, 0x37, 0x44, 0x35, 0x2B, 0x6A, 0x4E, 0x42, 0x35, 0x6E, 0x35, 0x44, 0x51, 0x74, 0x64, 0x63, 0x6A, 0x37, 0x45, 0x71, 0x67, 0x49, 0x77, 0x48, 0x37, 0x79, 0x36, 0x43, 0x2B, 0x49, 0x77, 0x4A, 0x50, 0x74, 0x38, 0x62, 0x59, 0x42, 0x56, 0x43, ++ 0x70, 0x6B, 0x2B, 0x67, 0x41, 0x30, 0x7A, 0x0A, 0x35, 0x57, 0x61, 0x6A, 0x73, 0x36, 0x4F, 0x37, 0x70, 0x64, 0x57, 0x4C, 0x6A, 0x77, 0x6B, 0x73, 0x70, 0x6C, 0x31, 0x2B, 0x34, 0x76, 0x41, 0x48, 0x43, 0x47, 0x68, 0x74, 0x30, 0x6E, 0x78, 0x70, ++ 0x62, 0x6C, 0x2F, 0x66, 0x35, 0x57, 0x70, 0x6C, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x53, 0x53, 0x4C, 0x2E, ++ 0x63, 0x6F, 0x6D, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x53, 0x41, 0x20, ++ 0x52, 0x32, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, ++ 0x49, 0x46, 0x36, 0x7A, 0x43, 0x43, 0x41, 0x39, 0x4F, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x49, 0x56, 0x72, 0x59, 0x70, 0x7A, 0x54, 0x53, 0x38, 0x65, 0x50, 0x59, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, ++ 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x77, 0x67, 0x59, 0x49, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6C, 0x56, 0x54, 0x4D, 0x51, 0x34, 0x77, 0x0A, 0x44, 0x41, 0x59, 0x44, 0x56, ++ 0x51, 0x51, 0x49, 0x44, 0x41, 0x56, 0x55, 0x5A, 0x58, 0x68, 0x68, 0x63, 0x7A, 0x45, 0x51, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x77, 0x77, 0x48, 0x53, 0x47, 0x39, 0x31, 0x63, 0x33, 0x52, 0x76, 0x62, 0x6A, 0x45, 0x59, 0x4D, ++ 0x42, 0x59, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x50, 0x55, 0x31, 0x4E, 0x4D, 0x49, 0x45, 0x4E, 0x76, 0x63, 0x6E, 0x42, 0x76, 0x63, 0x6D, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x0A, 0x4D, 0x54, 0x63, 0x77, 0x4E, 0x51, 0x59, 0x44, ++ 0x56, 0x51, 0x51, 0x44, 0x44, 0x43, 0x35, 0x54, 0x55, 0x30, 0x77, 0x75, 0x59, 0x32, 0x39, 0x74, 0x49, 0x45, 0x56, 0x57, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6C, 0x6D, 0x61, 0x57, 0x4E, 0x68, ++ 0x64, 0x47, 0x6C, 0x76, 0x62, 0x69, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6F, 0x62, 0x33, 0x4A, 0x70, 0x64, 0x48, 0x6B, 0x67, 0x55, 0x6C, 0x4E, 0x42, 0x49, 0x46, 0x49, 0x79, 0x0A, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x45, 0x33, 0x4D, 0x44, 0x55, ++ 0x7A, 0x4D, 0x54, 0x45, 0x34, 0x4D, 0x54, 0x51, 0x7A, 0x4E, 0x31, 0x6F, 0x58, 0x44, 0x54, 0x51, 0x79, 0x4D, 0x44, 0x55, 0x7A, 0x4D, 0x44, 0x45, 0x34, 0x4D, 0x54, 0x51, 0x7A, 0x4E, 0x31, 0x6F, 0x77, 0x67, 0x59, 0x49, 0x78, 0x43, 0x7A, 0x41, ++ 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6C, 0x56, 0x54, 0x4D, 0x51, 0x34, 0x77, 0x44, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x49, 0x0A, 0x44, 0x41, 0x56, 0x55, 0x5A, 0x58, 0x68, 0x68, 0x63, 0x7A, 0x45, 0x51, 0x4D, 0x41, ++ 0x34, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x77, 0x77, 0x48, 0x53, 0x47, 0x39, 0x31, 0x63, 0x33, 0x52, 0x76, 0x62, 0x6A, 0x45, 0x59, 0x4D, 0x42, 0x59, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x50, 0x55, 0x31, 0x4E, 0x4D, 0x49, 0x45, ++ 0x4E, 0x76, 0x63, 0x6E, 0x42, 0x76, 0x63, 0x6D, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x4D, 0x54, 0x63, 0x77, 0x4E, 0x51, 0x59, 0x44, 0x0A, 0x56, 0x51, 0x51, 0x44, 0x44, 0x43, 0x35, 0x54, 0x55, 0x30, 0x77, 0x75, 0x59, 0x32, 0x39, 0x74, 0x49, ++ 0x45, 0x56, 0x57, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6C, 0x6D, 0x61, 0x57, 0x4E, 0x68, 0x64, 0x47, 0x6C, 0x76, 0x62, 0x69, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6F, 0x62, 0x33, 0x4A, 0x70, 0x64, ++ 0x48, 0x6B, 0x67, 0x55, 0x6C, 0x4E, 0x42, 0x49, 0x46, 0x49, 0x79, 0x4D, 0x49, 0x49, 0x43, 0x49, 0x6A, 0x41, 0x4E, 0x0A, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x4F, 0x43, ++ 0x41, 0x67, 0x38, 0x41, 0x4D, 0x49, 0x49, 0x43, 0x43, 0x67, 0x4B, 0x43, 0x41, 0x67, 0x45, 0x41, 0x6A, 0x7A, 0x5A, 0x6C, 0x51, 0x4F, 0x48, 0x57, 0x54, 0x63, 0x44, 0x58, 0x74, 0x4F, 0x6C, 0x47, 0x32, 0x6D, 0x76, 0x71, 0x4D, 0x30, 0x66, 0x4E, ++ 0x54, 0x50, 0x6C, 0x39, 0x66, 0x62, 0x36, 0x39, 0x4C, 0x54, 0x33, 0x77, 0x32, 0x33, 0x6A, 0x68, 0x0A, 0x68, 0x71, 0x58, 0x5A, 0x75, 0x67, 0x6C, 0x58, 0x61, 0x4F, 0x31, 0x58, 0x50, 0x71, 0x44, 0x51, 0x43, 0x45, 0x47, 0x44, 0x35, 0x79, 0x68, ++ 0x42, 0x4A, 0x42, 0x2F, 0x6A, 0x63, 0x68, 0x58, 0x51, 0x41, 0x52, 0x72, 0x37, 0x58, 0x6E, 0x41, 0x6A, 0x73, 0x73, 0x75, 0x66, 0x4F, 0x65, 0x50, 0x50, 0x78, 0x55, 0x37, 0x47, 0x6B, 0x6D, 0x30, 0x6D, 0x78, 0x6E, 0x75, 0x37, 0x73, 0x39, 0x6F, ++ 0x6E, 0x6E, 0x51, 0x71, 0x47, 0x36, 0x59, 0x45, 0x33, 0x42, 0x66, 0x37, 0x77, 0x0A, 0x63, 0x58, 0x48, 0x73, 0x77, 0x78, 0x7A, 0x70, 0x59, 0x36, 0x49, 0x58, 0x46, 0x4A, 0x33, 0x76, 0x47, 0x32, 0x66, 0x54, 0x68, 0x56, 0x55, 0x43, 0x41, 0x74, ++ 0x5A, 0x4A, 0x79, 0x63, 0x78, 0x61, 0x34, 0x62, 0x48, 0x33, 0x62, 0x7A, 0x4B, 0x66, 0x79, 0x64, 0x51, 0x37, 0x69, 0x45, 0x47, 0x6F, 0x6E, 0x4C, 0x33, 0x4C, 0x71, 0x39, 0x74, 0x74, 0x65, 0x77, 0x6B, 0x66, 0x6F, 0x6B, 0x78, 0x79, 0x6B, 0x4E, ++ 0x6F, 0x72, 0x43, 0x50, 0x7A, 0x50, 0x50, 0x46, 0x54, 0x4F, 0x0A, 0x5A, 0x77, 0x2B, 0x6F, 0x7A, 0x31, 0x32, 0x57, 0x47, 0x51, 0x76, 0x45, 0x34, 0x33, 0x4C, 0x72, 0x72, 0x64, 0x46, 0x39, 0x48, 0x53, 0x66, 0x76, 0x6B, 0x75, 0x73, 0x51, 0x76, ++ 0x31, 0x76, 0x72, 0x4F, 0x36, 0x2F, 0x50, 0x67, 0x4E, 0x33, 0x42, 0x30, 0x70, 0x59, 0x45, 0x57, 0x33, 0x70, 0x2B, 0x70, 0x4B, 0x6B, 0x38, 0x4F, 0x48, 0x61, 0x6B, 0x59, 0x6F, 0x36, 0x67, 0x4F, 0x56, 0x37, 0x71, 0x64, 0x38, 0x39, 0x64, 0x41, ++ 0x46, 0x6D, 0x50, 0x5A, 0x69, 0x77, 0x2B, 0x0A, 0x42, 0x36, 0x4B, 0x6A, 0x42, 0x53, 0x59, 0x52, 0x61, 0x5A, 0x66, 0x71, 0x68, 0x62, 0x63, 0x50, 0x6C, 0x67, 0x74, 0x4C, 0x79, 0x45, 0x44, 0x68, 0x55, 0x4C, 0x6F, 0x75, 0x69, 0x73, 0x76, 0x33, ++ 0x44, 0x35, 0x6F, 0x69, 0x35, 0x33, 0x2B, 0x61, 0x4E, 0x78, 0x50, 0x4E, 0x38, 0x6B, 0x30, 0x54, 0x61, 0x79, 0x48, 0x52, 0x77, 0x4D, 0x77, 0x69, 0x38, 0x71, 0x46, 0x47, 0x39, 0x6B, 0x52, 0x70, 0x6E, 0x4D, 0x70, 0x68, 0x4E, 0x51, 0x63, 0x41, ++ 0x62, 0x39, 0x5A, 0x68, 0x0A, 0x43, 0x42, 0x48, 0x71, 0x75, 0x72, 0x6A, 0x32, 0x36, 0x62, 0x4E, 0x67, 0x35, 0x55, 0x32, 0x35, 0x37, 0x4A, 0x38, 0x55, 0x5A, 0x73, 0x6C, 0x58, 0x57, 0x4E, 0x76, 0x4E, 0x68, 0x32, 0x6E, 0x34, 0x69, 0x6F, 0x59, ++ 0x53, 0x41, 0x30, 0x65, 0x2F, 0x5A, 0x68, 0x4E, 0x32, 0x72, 0x48, 0x64, 0x39, 0x4E, 0x43, 0x53, 0x46, 0x67, 0x38, 0x33, 0x58, 0x71, 0x70, 0x79, 0x51, 0x47, 0x70, 0x38, 0x68, 0x4C, 0x48, 0x39, 0x34, 0x74, 0x32, 0x53, 0x34, 0x32, 0x4F, 0x69, ++ 0x6D, 0x0A, 0x39, 0x48, 0x69, 0x7A, 0x56, 0x63, 0x75, 0x45, 0x30, 0x6A, 0x4C, 0x45, 0x65, 0x4B, 0x36, 0x6A, 0x6A, 0x32, 0x48, 0x64, 0x7A, 0x67, 0x68, 0x54, 0x72, 0x65, 0x79, 0x49, 0x2F, 0x42, 0x58, 0x6B, 0x6D, 0x67, 0x33, 0x6D, 0x6E, 0x78, ++ 0x70, 0x33, 0x7A, 0x6B, 0x79, 0x50, 0x75, 0x42, 0x51, 0x56, 0x50, 0x57, 0x4B, 0x63, 0x68, 0x6A, 0x67, 0x47, 0x41, 0x47, 0x59, 0x53, 0x35, 0x46, 0x6C, 0x32, 0x57, 0x6C, 0x50, 0x41, 0x41, 0x70, 0x69, 0x69, 0x45, 0x43, 0x74, 0x6F, 0x0A, 0x52, ++ 0x48, 0x75, 0x4F, 0x65, 0x63, 0x34, 0x7A, 0x53, 0x6E, 0x61, 0x71, 0x57, 0x34, 0x45, 0x57, 0x47, 0x37, 0x57, 0x4B, 0x32, 0x4E, 0x41, 0x41, 0x65, 0x31, 0x35, 0x69, 0x74, 0x41, 0x6E, 0x57, 0x68, 0x6D, 0x4D, 0x4F, 0x70, 0x67, 0x57, 0x56, 0x53, ++ 0x62, 0x6F, 0x6F, 0x69, 0x34, 0x69, 0x54, 0x73, 0x6A, 0x51, 0x63, 0x32, 0x4B, 0x52, 0x56, 0x62, 0x72, 0x63, 0x63, 0x30, 0x4E, 0x36, 0x5A, 0x56, 0x54, 0x73, 0x6A, 0x39, 0x43, 0x4C, 0x67, 0x2B, 0x53, 0x6C, 0x6D, 0x0A, 0x4A, 0x75, 0x77, 0x67, ++ 0x55, 0x48, 0x66, 0x62, 0x53, 0x67, 0x75, 0x50, 0x76, 0x75, 0x55, 0x43, 0x59, 0x48, 0x42, 0x42, 0x58, 0x74, 0x53, 0x75, 0x55, 0x44, 0x6B, 0x69, 0x46, 0x43, 0x62, 0x4C, 0x73, 0x6A, 0x74, 0x7A, 0x64, 0x46, 0x56, 0x48, 0x42, 0x33, 0x6D, 0x42, ++ 0x4F, 0x61, 0x67, 0x77, 0x45, 0x30, 0x54, 0x6C, 0x42, 0x49, 0x71, 0x75, 0x6C, 0x68, 0x4D, 0x6C, 0x51, 0x67, 0x2B, 0x35, 0x55, 0x38, 0x53, 0x62, 0x2F, 0x4D, 0x33, 0x6B, 0x48, 0x4E, 0x34, 0x38, 0x0A, 0x2B, 0x71, 0x76, 0x57, 0x42, 0x6B, 0x6F, ++ 0x66, 0x5A, 0x36, 0x61, 0x59, 0x4D, 0x42, 0x7A, 0x64, 0x4C, 0x4E, 0x76, 0x63, 0x47, 0x4A, 0x56, 0x58, 0x5A, 0x73, 0x62, 0x2F, 0x58, 0x49, 0x74, 0x57, 0x39, 0x58, 0x63, 0x43, 0x41, 0x77, 0x45, 0x41, 0x41, 0x61, 0x4E, 0x6A, 0x4D, 0x47, 0x45, ++ 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x66, 0x42, 0x67, 0x4E, 0x56, 0x0A, 0x48, 0x53, 0x4D, 0x45, 0x47, 0x44, 0x41, 0x57, 0x67, 0x42, ++ 0x54, 0x35, 0x59, 0x4C, 0x76, 0x55, 0x34, 0x39, 0x55, 0x30, 0x39, 0x72, 0x6A, 0x31, 0x42, 0x6F, 0x41, 0x6C, 0x70, 0x33, 0x50, 0x62, 0x52, 0x6D, 0x6D, 0x6F, 0x6E, 0x6A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, ++ 0x51, 0x55, 0x2B, 0x57, 0x43, 0x37, 0x31, 0x4F, 0x50, 0x56, 0x4E, 0x50, 0x61, 0x34, 0x39, 0x51, 0x61, 0x41, 0x4A, 0x61, 0x64, 0x7A, 0x32, 0x30, 0x5A, 0x70, 0x0A, 0x71, 0x4A, 0x34, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, ++ 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x47, 0x47, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43, 0x77, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x41, 0x51, 0x42, 0x57, 0x73, ++ 0x34, 0x37, 0x4C, 0x43, 0x70, 0x31, 0x4A, 0x6A, 0x72, 0x2B, 0x6B, 0x78, 0x4A, 0x47, 0x37, 0x5A, 0x68, 0x63, 0x46, 0x55, 0x5A, 0x68, 0x31, 0x0A, 0x2B, 0x2B, 0x56, 0x51, 0x4C, 0x48, 0x71, 0x65, 0x38, 0x52, 0x54, 0x36, 0x71, 0x39, 0x4F, 0x4B, ++ 0x50, 0x76, 0x2B, 0x52, 0x4B, 0x59, 0x39, 0x6A, 0x69, 0x39, 0x69, 0x30, 0x71, 0x56, 0x51, 0x42, 0x44, 0x62, 0x36, 0x54, 0x68, 0x69, 0x2F, 0x35, 0x53, 0x6D, 0x33, 0x48, 0x58, 0x76, 0x56, 0x58, 0x2B, 0x63, 0x70, 0x56, 0x48, 0x42, 0x4B, 0x2B, ++ 0x52, 0x77, 0x38, 0x32, 0x78, 0x64, 0x39, 0x71, 0x74, 0x39, 0x74, 0x31, 0x77, 0x6B, 0x63, 0x6C, 0x66, 0x37, 0x6E, 0x78, 0x0A, 0x59, 0x2F, 0x68, 0x6F, 0x4C, 0x56, 0x55, 0x45, 0x30, 0x66, 0x4B, 0x4E, 0x73, 0x4B, 0x54, 0x50, 0x76, 0x44, 0x78, ++ 0x65, 0x48, 0x33, 0x6A, 0x6E, 0x70, 0x61, 0x41, 0x67, 0x63, 0x4C, 0x41, 0x45, 0x78, 0x62, 0x66, 0x33, 0x63, 0x71, 0x66, 0x65, 0x49, 0x67, 0x32, 0x39, 0x4D, 0x79, 0x56, 0x47, 0x6A, 0x47, 0x53, 0x53, 0x4A, 0x75, 0x4D, 0x2B, 0x4C, 0x6D, 0x4F, ++ 0x57, 0x32, 0x70, 0x75, 0x4D, 0x50, 0x66, 0x67, 0x59, 0x43, 0x64, 0x63, 0x44, 0x7A, 0x48, 0x32, 0x47, 0x0A, 0x67, 0x75, 0x44, 0x4B, 0x42, 0x41, 0x64, 0x52, 0x55, 0x4E, 0x66, 0x2F, 0x6B, 0x74, 0x55, 0x4D, 0x37, 0x39, 0x71, 0x47, 0x6E, 0x35, ++ 0x6E, 0x58, 0x36, 0x37, 0x65, 0x76, 0x61, 0x4F, 0x49, 0x35, 0x4A, 0x70, 0x53, 0x36, 0x61, 0x4C, 0x65, 0x2F, 0x67, 0x39, 0x50, 0x71, 0x65, 0x6D, 0x63, 0x39, 0x59, 0x6D, 0x65, 0x75, 0x4A, 0x65, 0x56, 0x79, 0x36, 0x4F, 0x4C, 0x6B, 0x37, 0x4B, ++ 0x34, 0x53, 0x39, 0x6B, 0x73, 0x72, 0x50, 0x4A, 0x2F, 0x70, 0x73, 0x45, 0x44, 0x7A, 0x0A, 0x4F, 0x46, 0x53, 0x7A, 0x2F, 0x62, 0x64, 0x6F, 0x79, 0x4E, 0x72, 0x47, 0x6A, 0x31, 0x45, 0x38, 0x73, 0x76, 0x75, 0x52, 0x33, 0x42, 0x7A, 0x6E, 0x6D, ++ 0x35, 0x33, 0x68, 0x74, 0x77, 0x31, 0x79, 0x6A, 0x2B, 0x4B, 0x6B, 0x78, 0x4B, 0x6C, 0x34, 0x2B, 0x65, 0x73, 0x55, 0x72, 0x4D, 0x5A, 0x44, 0x42, 0x63, 0x4A, 0x6C, 0x4F, 0x53, 0x67, 0x59, 0x41, 0x73, 0x4F, 0x43, 0x73, 0x70, 0x30, 0x46, 0x76, ++ 0x6D, 0x58, 0x74, 0x6C, 0x6C, 0x39, 0x6C, 0x64, 0x44, 0x7A, 0x37, 0x0A, 0x43, 0x54, 0x55, 0x75, 0x65, 0x35, 0x77, 0x54, 0x2F, 0x52, 0x73, 0x50, 0x58, 0x63, 0x64, 0x74, 0x67, 0x54, 0x70, 0x57, 0x44, 0x38, 0x77, 0x37, 0x34, 0x61, 0x38, 0x43, ++ 0x4C, 0x79, 0x4B, 0x73, 0x52, 0x73, 0x70, 0x47, 0x50, 0x4B, 0x41, 0x63, 0x54, 0x4E, 0x5A, 0x45, 0x74, 0x46, 0x34, 0x75, 0x58, 0x42, 0x56, 0x6D, 0x43, 0x65, 0x45, 0x6D, 0x4B, 0x66, 0x37, 0x47, 0x55, 0x6D, 0x47, 0x36, 0x73, 0x58, 0x50, 0x2F, ++ 0x77, 0x77, 0x79, 0x63, 0x35, 0x57, 0x78, 0x71, 0x0A, 0x6C, 0x44, 0x38, 0x55, 0x79, 0x6B, 0x41, 0x57, 0x6C, 0x59, 0x54, 0x7A, 0x57, 0x61, 0x6D, 0x73, 0x58, 0x30, 0x78, 0x68, 0x6B, 0x32, 0x33, 0x52, 0x4F, 0x38, 0x79, 0x69, 0x6C, 0x51, 0x77, ++ 0x69, 0x70, 0x6D, 0x64, 0x6E, 0x52, 0x43, 0x36, 0x35, 0x32, 0x64, 0x4B, 0x4B, 0x51, 0x62, 0x4E, 0x6D, 0x43, 0x31, 0x72, 0x37, 0x66, 0x53, 0x4F, 0x6C, 0x38, 0x68, 0x71, 0x77, 0x2F, 0x39, 0x36, 0x62, 0x67, 0x35, 0x51, 0x75, 0x30, 0x54, 0x2F, ++ 0x66, 0x6B, 0x72, 0x65, 0x52, 0x0A, 0x72, 0x77, 0x55, 0x37, 0x5A, 0x63, 0x65, 0x67, 0x62, 0x4C, 0x48, 0x4E, 0x59, 0x68, 0x4C, 0x44, 0x6B, 0x42, 0x76, 0x6A, 0x4A, 0x63, 0x34, 0x30, 0x76, 0x47, 0x39, 0x33, 0x64, 0x72, 0x45, 0x51, 0x77, 0x2F, ++ 0x63, 0x46, 0x47, 0x73, 0x44, 0x57, 0x72, 0x33, 0x52, 0x69, 0x53, 0x42, 0x64, 0x33, 0x6B, 0x6D, 0x6D, 0x51, 0x59, 0x52, 0x7A, 0x65, 0x6C, 0x59, 0x42, 0x30, 0x56, 0x49, 0x38, 0x59, 0x48, 0x4D, 0x50, 0x7A, 0x41, 0x39, 0x43, 0x2F, 0x70, 0x45, ++ 0x4E, 0x31, 0x0A, 0x68, 0x6C, 0x4D, 0x59, 0x65, 0x67, 0x6F, 0x75, 0x43, 0x52, 0x77, 0x32, 0x6E, 0x35, 0x48, 0x39, 0x67, 0x6F, 0x6F, 0x69, 0x53, 0x39, 0x45, 0x4F, 0x55, 0x43, 0x58, 0x64, 0x79, 0x77, 0x4D, 0x4D, 0x46, 0x38, 0x6D, 0x44, 0x41, ++ 0x41, 0x68, 0x4F, 0x4E, 0x55, 0x32, 0x4B, 0x69, 0x2B, 0x33, 0x77, 0x41, 0x70, 0x52, 0x6D, 0x4C, 0x45, 0x52, 0x2F, 0x79, 0x35, 0x55, 0x6E, 0x6C, 0x68, 0x65, 0x74, 0x43, 0x54, 0x43, 0x73, 0x74, 0x6E, 0x45, 0x58, 0x62, 0x6F, 0x73, 0x58, 0x0A, ++ 0x39, 0x68, 0x77, 0x4A, 0x31, 0x43, 0x30, 0x37, 0x6D, 0x4B, 0x56, 0x78, 0x30, 0x31, 0x51, 0x54, 0x32, 0x57, 0x44, 0x7A, 0x39, 0x55, 0x74, 0x6D, 0x54, 0x2F, 0x72, 0x78, 0x37, 0x69, 0x41, 0x53, 0x6A, 0x62, 0x53, 0x73, 0x56, 0x37, 0x46, 0x46, ++ 0x59, 0x36, 0x47, 0x73, 0x64, 0x71, 0x6E, 0x43, 0x2B, 0x77, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, ++ 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, ++ 0x45, 0x43, 0x43, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, ++ 0x6C, 0x44, 0x43, 0x43, 0x41, 0x68, 0x71, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x49, 0x4C, 0x43, 0x6D, 0x63, 0x57, 0x78, 0x62, 0x74, 0x42, 0x5A, 0x55, 0x77, 0x43, 0x67, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x45, ++ 0x41, 0x77, 0x49, 0x77, 0x66, 0x7A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x56, 0x56, 0x4D, 0x78, 0x44, 0x6A, 0x41, 0x4D, 0x42, 0x67, 0x4E, 0x56, 0x0A, 0x42, 0x41, 0x67, 0x4D, 0x42, 0x56, 0x52, ++ 0x6C, 0x65, 0x47, 0x46, 0x7A, 0x4D, 0x52, 0x41, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x48, 0x44, 0x41, 0x64, 0x49, 0x62, 0x33, 0x56, 0x7A, 0x64, 0x47, 0x39, 0x75, 0x4D, 0x52, 0x67, 0x77, 0x46, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, ++ 0x4B, 0x44, 0x41, 0x39, 0x54, 0x55, 0x30, 0x77, 0x67, 0x51, 0x32, 0x39, 0x79, 0x63, 0x47, 0x39, 0x79, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x78, 0x4E, 0x44, 0x41, 0x79, 0x0A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x4B, 0x31, ++ 0x4E, 0x54, 0x54, 0x43, 0x35, 0x6A, 0x62, 0x32, 0x30, 0x67, 0x52, 0x56, 0x59, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x61, 0x57, 0x5A, 0x70, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x49, 0x45, ++ 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6D, 0x6C, 0x30, 0x65, 0x53, 0x42, 0x46, 0x51, 0x30, 0x4D, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x54, 0x59, 0x77, 0x0A, 0x4D, 0x6A, 0x45, 0x79, 0x4D, 0x54, 0x67, 0x78, 0x4E, 0x54, 0x49, 0x7A, 0x57, ++ 0x68, 0x63, 0x4E, 0x4E, 0x44, 0x45, 0x77, 0x4D, 0x6A, 0x45, 0x79, 0x4D, 0x54, 0x67, 0x78, 0x4E, 0x54, 0x49, 0x7A, 0x57, 0x6A, 0x42, 0x2F, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, 0x55, ++ 0x7A, 0x45, 0x4F, 0x4D, 0x41, 0x77, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x41, 0x77, 0x46, 0x56, 0x47, 0x56, 0x34, 0x59, 0x58, 0x4D, 0x78, 0x0A, 0x45, 0x44, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x63, 0x4D, 0x42, 0x30, 0x68, 0x76, ++ 0x64, 0x58, 0x4E, 0x30, 0x62, 0x32, 0x34, 0x78, 0x47, 0x44, 0x41, 0x57, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x44, 0x31, 0x4E, 0x54, 0x54, 0x43, 0x42, 0x44, 0x62, 0x33, 0x4A, 0x77, 0x62, 0x33, 0x4A, 0x68, 0x64, 0x47, 0x6C, 0x76, ++ 0x62, 0x6A, 0x45, 0x30, 0x4D, 0x44, 0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x72, 0x55, 0x31, 0x4E, 0x4D, 0x0A, 0x4C, 0x6D, 0x4E, 0x76, 0x62, 0x53, 0x42, 0x46, 0x56, 0x69, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, ++ 0x6C, 0x63, 0x6E, 0x52, 0x70, 0x5A, 0x6D, 0x6C, 0x6A, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52, 0x35, 0x49, 0x45, 0x56, 0x44, 0x51, 0x7A, 0x42, 0x32, 0x4D, 0x42, 0x41, ++ 0x47, 0x42, 0x79, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x41, 0x67, 0x45, 0x47, 0x42, 0x53, 0x75, 0x42, 0x0A, 0x42, 0x41, 0x41, 0x69, 0x41, 0x32, 0x49, 0x41, 0x42, 0x4B, 0x6F, 0x53, 0x52, 0x35, 0x43, 0x59, 0x47, 0x2F, 0x76, 0x76, 0x77, 0x30, ++ 0x41, 0x48, 0x67, 0x79, 0x42, 0x4F, 0x38, 0x54, 0x43, 0x43, 0x6F, 0x67, 0x62, 0x52, 0x38, 0x70, 0x4B, 0x47, 0x59, 0x66, 0x4C, 0x32, 0x49, 0x57, 0x6A, 0x4B, 0x41, 0x4D, 0x54, 0x48, 0x36, 0x6B, 0x4D, 0x41, 0x56, 0x49, 0x62, 0x63, 0x2F, 0x52, ++ 0x2F, 0x66, 0x41, 0x4C, 0x68, 0x42, 0x59, 0x6C, 0x7A, 0x63, 0x63, 0x42, 0x59, 0x79, 0x0A, 0x33, 0x68, 0x2B, 0x5A, 0x31, 0x4D, 0x7A, 0x46, 0x42, 0x38, 0x67, 0x49, 0x48, 0x32, 0x45, 0x57, 0x42, 0x31, 0x45, 0x39, 0x66, 0x56, 0x77, 0x48, 0x55, ++ 0x2B, 0x4D, 0x31, 0x4F, 0x49, 0x7A, 0x66, 0x7A, 0x5A, 0x2F, 0x5A, 0x4C, 0x67, 0x31, 0x4B, 0x74, 0x68, 0x6B, 0x75, 0x57, 0x6E, 0x42, 0x61, 0x42, 0x75, 0x32, 0x2B, 0x38, 0x4B, 0x47, 0x77, 0x79, 0x74, 0x41, 0x4A, 0x4B, 0x61, 0x4E, 0x6A, 0x4D, ++ 0x47, 0x45, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x0A, 0x42, 0x42, 0x59, 0x45, 0x46, 0x46, 0x76, 0x4B, 0x58, 0x75, 0x58, 0x65, 0x30, 0x6F, 0x47, 0x71, 0x7A, 0x61, 0x67, 0x74, 0x5A, 0x46, 0x47, 0x32, 0x32, 0x58, 0x4B, 0x62, ++ 0x6C, 0x2B, 0x5A, 0x50, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x48, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x6A, 0x42, 0x42, 0x67, 0x77, ++ 0x46, 0x6F, 0x41, 0x55, 0x57, 0x38, 0x70, 0x65, 0x0A, 0x35, 0x64, 0x37, 0x53, 0x67, 0x61, 0x72, 0x4E, 0x71, 0x43, 0x31, 0x6B, 0x55, 0x62, 0x62, 0x5A, 0x63, 0x70, 0x75, 0x58, 0x35, 0x6B, 0x38, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, ++ 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x47, 0x47, 0x4D, 0x41, 0x6F, 0x47, 0x43, 0x43, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x32, 0x67, 0x41, 0x4D, 0x47, 0x55, 0x43, 0x4D, 0x51, 0x43, ++ 0x4B, 0x35, 0x6B, 0x43, 0x4A, 0x0A, 0x4E, 0x2B, 0x76, 0x70, 0x31, 0x52, 0x50, 0x5A, 0x79, 0x74, 0x52, 0x72, 0x4A, 0x50, 0x4F, 0x77, 0x50, 0x59, 0x64, 0x47, 0x57, 0x42, 0x72, 0x73, 0x73, 0x64, 0x39, 0x76, 0x2B, 0x31, 0x61, 0x36, 0x63, 0x47, ++ 0x76, 0x48, 0x4F, 0x4D, 0x7A, 0x6F, 0x73, 0x59, 0x78, 0x50, 0x44, 0x2F, 0x66, 0x78, 0x5A, 0x33, 0x59, 0x4F, 0x67, 0x39, 0x41, 0x65, 0x55, 0x59, 0x38, 0x43, 0x4D, 0x44, 0x33, 0x32, 0x49, 0x79, 0x67, 0x6D, 0x54, 0x4D, 0x5A, 0x67, 0x68, 0x35, ++ 0x4D, 0x6D, 0x0A, 0x6D, 0x37, 0x49, 0x31, 0x48, 0x72, 0x72, 0x57, 0x39, 0x7A, 0x7A, 0x52, 0x48, 0x4D, 0x37, 0x36, 0x4A, 0x54, 0x79, 0x6D, 0x47, 0x6F, 0x45, 0x56, 0x57, 0x2F, 0x4D, 0x53, 0x44, 0x32, 0x7A, 0x75, 0x5A, 0x59, 0x72, 0x4A, 0x68, ++ 0x36, 0x6A, 0x35, 0x42, 0x2B, 0x42, 0x69, 0x6D, 0x6F, 0x78, 0x63, 0x53, 0x67, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x2D, 0x0A, 0x0A, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x52, 0x36, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, ++ 0x49, 0x49, 0x46, 0x67, 0x7A, 0x43, 0x43, 0x41, 0x32, 0x75, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x4F, 0x52, 0x65, 0x61, 0x37, 0x41, 0x34, 0x4D, 0x7A, 0x77, 0x34, 0x56, 0x6C, 0x53, 0x4F, 0x62, 0x2F, 0x52, 0x56, 0x45, 0x77, 0x44, ++ 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4D, 0x42, 0x51, 0x41, 0x77, 0x54, 0x44, 0x45, 0x67, 0x4D, 0x42, 0x34, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4D, 0x58, 0x0A, 0x52, 0x32, 0x78, 0x76, ++ 0x59, 0x6D, 0x46, 0x73, 0x55, 0x32, 0x6C, 0x6E, 0x62, 0x69, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x49, 0x43, 0x30, 0x67, 0x55, 0x6A, 0x59, 0x78, 0x45, 0x7A, 0x41, 0x52, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, ++ 0x43, 0x6B, 0x64, 0x73, 0x62, 0x32, 0x4A, 0x68, 0x62, 0x46, 0x4E, 0x70, 0x5A, 0x32, 0x34, 0x78, 0x45, 0x7A, 0x41, 0x52, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x43, 0x6B, 0x64, 0x73, 0x0A, 0x62, 0x32, 0x4A, 0x68, 0x62, 0x46, 0x4E, ++ 0x70, 0x5A, 0x32, 0x34, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x54, 0x51, 0x78, 0x4D, 0x6A, 0x45, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x57, 0x68, 0x63, 0x4E, 0x4D, 0x7A, 0x51, 0x78, 0x4D, 0x6A, 0x45, 0x77, 0x4D, 0x44, 0x41, ++ 0x77, 0x4D, 0x44, 0x41, 0x77, 0x57, 0x6A, 0x42, 0x4D, 0x4D, 0x53, 0x41, 0x77, 0x48, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, 0x45, 0x78, 0x64, 0x48, 0x62, 0x47, 0x39, 0x69, 0x0A, 0x59, 0x57, 0x78, 0x54, 0x61, 0x57, 0x64, 0x75, 0x49, 0x46, ++ 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x4C, 0x53, 0x42, 0x53, 0x4E, 0x6A, 0x45, 0x54, 0x4D, 0x42, 0x45, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x4B, 0x52, 0x32, 0x78, 0x76, 0x59, 0x6D, 0x46, 0x73, 0x55, 0x32, ++ 0x6C, 0x6E, 0x62, 0x6A, 0x45, 0x54, 0x4D, 0x42, 0x45, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x4B, 0x52, 0x32, 0x78, 0x76, 0x59, 0x6D, 0x46, 0x73, 0x0A, 0x55, 0x32, 0x6C, 0x6E, 0x62, 0x6A, 0x43, 0x43, 0x41, 0x69, 0x49, 0x77, 0x44, ++ 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x67, 0x6F, 0x43, 0x67, 0x67, 0x49, 0x42, 0x41, 0x4A, 0x55, 0x48, 0x36, ++ 0x48, 0x50, 0x4B, 0x5A, 0x76, 0x6E, 0x73, 0x46, 0x4D, 0x70, 0x37, 0x50, 0x50, 0x63, 0x4E, 0x43, 0x50, 0x47, 0x30, 0x52, 0x51, 0x73, 0x73, 0x0A, 0x67, 0x72, 0x52, 0x49, 0x78, 0x75, 0x74, 0x62, 0x50, 0x4B, 0x36, 0x44, 0x75, 0x45, 0x47, 0x53, ++ 0x4D, 0x78, 0x53, 0x6B, 0x62, 0x33, 0x2F, 0x70, 0x4B, 0x73, 0x7A, 0x47, 0x73, 0x49, 0x68, 0x72, 0x78, 0x62, 0x61, 0x4A, 0x30, 0x63, 0x61, 0x79, 0x2F, 0x78, 0x54, 0x4F, 0x55, 0x52, 0x51, 0x68, 0x37, 0x45, 0x72, 0x64, 0x47, 0x31, 0x72, 0x47, ++ 0x31, 0x6F, 0x66, 0x75, 0x54, 0x54, 0x6F, 0x56, 0x42, 0x75, 0x31, 0x6B, 0x5A, 0x67, 0x75, 0x53, 0x67, 0x4D, 0x70, 0x45, 0x0A, 0x33, 0x6E, 0x4F, 0x55, 0x54, 0x76, 0x4F, 0x6E, 0x69, 0x58, 0x39, 0x50, 0x65, 0x47, 0x4D, 0x49, 0x79, 0x42, 0x4A, ++ 0x51, 0x62, 0x55, 0x4A, 0x6D, 0x4C, 0x30, 0x32, 0x35, 0x65, 0x53, 0x68, 0x4E, 0x55, 0x68, 0x71, 0x4B, 0x47, 0x6F, 0x43, 0x33, 0x47, 0x59, 0x45, 0x4F, 0x66, 0x73, 0x53, 0x4B, 0x76, 0x47, 0x52, 0x4D, 0x49, 0x52, 0x78, 0x44, 0x61, 0x4E, 0x63, ++ 0x39, 0x50, 0x49, 0x72, 0x46, 0x73, 0x6D, 0x62, 0x56, 0x6B, 0x4A, 0x71, 0x33, 0x4D, 0x51, 0x62, 0x46, 0x0A, 0x76, 0x75, 0x4A, 0x74, 0x4D, 0x67, 0x61, 0x6D, 0x48, 0x76, 0x6D, 0x35, 0x36, 0x36, 0x71, 0x6A, 0x75, 0x4C, 0x2B, 0x2B, 0x67, 0x6D, ++ 0x4E, 0x51, 0x30, 0x50, 0x41, 0x59, 0x69, 0x64, 0x2F, 0x6B, 0x44, 0x33, 0x6E, 0x31, 0x36, 0x71, 0x49, 0x66, 0x4B, 0x74, 0x4A, 0x77, 0x4C, 0x6E, 0x76, 0x6E, 0x76, 0x4A, 0x4F, 0x37, 0x62, 0x56, 0x50, 0x69, 0x53, 0x48, 0x79, 0x4D, 0x45, 0x41, ++ 0x63, 0x34, 0x2F, 0x32, 0x61, 0x79, 0x64, 0x32, 0x46, 0x2B, 0x34, 0x4F, 0x71, 0x4D, 0x0A, 0x50, 0x4B, 0x71, 0x30, 0x70, 0x50, 0x62, 0x7A, 0x6C, 0x55, 0x6F, 0x53, 0x42, 0x32, 0x33, 0x39, 0x6A, 0x4C, 0x4B, 0x4A, 0x7A, 0x39, 0x43, 0x67, 0x59, ++ 0x58, 0x66, 0x49, 0x57, 0x48, 0x53, 0x77, 0x31, 0x43, 0x4D, 0x36, 0x39, 0x31, 0x30, 0x36, 0x79, 0x71, 0x4C, 0x62, 0x6E, 0x51, 0x6E, 0x65, 0x58, 0x55, 0x51, 0x74, 0x6B, 0x50, 0x47, 0x42, 0x7A, 0x56, 0x65, 0x53, 0x2B, 0x6E, 0x36, 0x38, 0x55, ++ 0x41, 0x52, 0x6A, 0x4E, 0x4E, 0x39, 0x72, 0x6B, 0x78, 0x69, 0x2B, 0x0A, 0x61, 0x7A, 0x61, 0x79, 0x4F, 0x65, 0x53, 0x73, 0x4A, 0x44, 0x61, 0x33, 0x38, 0x4F, 0x2B, 0x32, 0x48, 0x42, 0x4E, 0x58, 0x6B, 0x37, 0x62, 0x65, 0x73, 0x76, 0x6A, 0x69, ++ 0x68, 0x62, 0x64, 0x7A, 0x6F, 0x72, 0x67, 0x31, 0x71, 0x6B, 0x58, 0x79, 0x34, 0x4A, 0x30, 0x32, 0x6F, 0x57, 0x39, 0x55, 0x69, 0x76, 0x46, 0x79, 0x56, 0x6D, 0x34, 0x75, 0x69, 0x4D, 0x56, 0x52, 0x51, 0x6B, 0x51, 0x56, 0x6C, 0x4F, 0x36, 0x6A, ++ 0x78, 0x54, 0x69, 0x57, 0x6D, 0x30, 0x35, 0x4F, 0x0A, 0x57, 0x67, 0x74, 0x48, 0x38, 0x77, 0x59, 0x32, 0x53, 0x58, 0x63, 0x77, 0x76, 0x48, 0x45, 0x33, 0x35, 0x61, 0x62, 0x73, 0x49, 0x51, 0x68, 0x31, 0x2F, 0x4F, 0x5A, 0x68, 0x46, 0x6A, 0x39, ++ 0x33, 0x31, 0x64, 0x6D, 0x52, 0x6C, 0x34, 0x51, 0x4B, 0x62, 0x4E, 0x51, 0x43, 0x54, 0x58, 0x54, 0x41, 0x46, 0x4F, 0x33, 0x39, 0x4F, 0x66, 0x75, 0x44, 0x38, 0x6C, 0x34, 0x55, 0x6F, 0x51, 0x53, 0x77, 0x43, 0x2B, 0x6E, 0x2B, 0x37, 0x6F, 0x2F, ++ 0x68, 0x62, 0x67, 0x75, 0x79, 0x0A, 0x43, 0x4C, 0x4E, 0x68, 0x5A, 0x67, 0x6C, 0x71, 0x73, 0x51, 0x59, 0x36, 0x5A, 0x5A, 0x5A, 0x5A, 0x77, 0x50, 0x41, 0x31, 0x2F, 0x63, 0x6E, 0x61, 0x4B, 0x49, 0x30, 0x61, 0x45, 0x59, 0x64, 0x77, 0x67, 0x51, ++ 0x71, 0x6F, 0x6D, 0x6E, 0x55, 0x64, 0x6E, 0x6A, 0x71, 0x47, 0x42, 0x51, 0x43, 0x65, 0x32, 0x34, 0x44, 0x57, 0x4A, 0x66, 0x6E, 0x63, 0x42, 0x5A, 0x34, 0x6E, 0x57, 0x55, 0x78, 0x32, 0x4F, 0x56, 0x76, 0x71, 0x2B, 0x61, 0x57, 0x68, 0x32, 0x49, ++ 0x4D, 0x50, 0x0A, 0x30, 0x66, 0x2F, 0x66, 0x4D, 0x42, 0x48, 0x35, 0x68, 0x63, 0x38, 0x7A, 0x53, 0x50, 0x58, 0x4B, 0x62, 0x57, 0x51, 0x55, 0x4C, 0x48, 0x70, 0x59, 0x54, 0x39, 0x4E, 0x4C, 0x43, 0x45, 0x6E, 0x46, 0x6C, 0x57, 0x51, 0x61, 0x59, ++ 0x77, 0x35, 0x35, 0x50, 0x66, 0x57, 0x7A, 0x6A, 0x4D, 0x70, 0x59, 0x72, 0x5A, 0x78, 0x43, 0x52, 0x58, 0x6C, 0x75, 0x44, 0x6F, 0x63, 0x5A, 0x58, 0x46, 0x53, 0x78, 0x5A, 0x62, 0x61, 0x2F, 0x6A, 0x4A, 0x76, 0x63, 0x45, 0x2B, 0x6B, 0x4E, 0x0A, ++ 0x62, 0x37, 0x67, 0x75, 0x33, 0x47, 0x64, 0x75, 0x79, 0x59, 0x73, 0x52, 0x74, 0x59, 0x51, 0x55, 0x69, 0x67, 0x41, 0x5A, 0x63, 0x49, 0x4E, 0x35, 0x6B, 0x5A, 0x65, 0x52, 0x31, 0x42, 0x6F, 0x6E, 0x76, 0x7A, 0x63, 0x65, 0x4D, 0x67, 0x66, 0x59, ++ 0x46, 0x47, 0x4D, 0x38, 0x4B, 0x45, 0x79, 0x76, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, 0x59, 0x7A, 0x42, 0x68, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x0A, 0x41, 0x77, 0x49, ++ 0x42, 0x42, 0x6A, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x53, ++ 0x75, 0x62, 0x41, 0x57, 0x6A, 0x6B, 0x78, 0x50, 0x69, 0x6F, 0x75, 0x66, 0x69, 0x31, 0x78, 0x7A, 0x57, 0x78, 0x2F, 0x42, 0x2F, 0x79, 0x47, 0x64, 0x54, 0x6F, 0x44, 0x41, 0x66, 0x42, 0x67, 0x4E, 0x56, 0x0A, 0x48, 0x53, 0x4D, 0x45, 0x47, 0x44, ++ 0x41, 0x57, 0x67, 0x42, 0x53, 0x75, 0x62, 0x41, 0x57, 0x6A, 0x6B, 0x78, 0x50, 0x69, 0x6F, 0x75, 0x66, 0x69, 0x31, 0x78, 0x7A, 0x57, 0x78, 0x2F, 0x42, 0x2F, 0x79, 0x47, 0x64, 0x54, 0x6F, 0x44, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, ++ 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x77, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x67, 0x45, 0x41, 0x67, 0x79, 0x58, 0x74, 0x36, 0x4E, 0x48, 0x39, 0x6C, 0x56, 0x4C, 0x4E, 0x0A, 0x6E, 0x73, 0x41, 0x45, 0x6F, 0x4A, 0x46, 0x70, 0x35, ++ 0x6C, 0x7A, 0x51, 0x68, 0x4E, 0x37, 0x63, 0x72, 0x61, 0x4A, 0x50, 0x36, 0x45, 0x64, 0x34, 0x31, 0x6D, 0x57, 0x59, 0x71, 0x56, 0x75, 0x6F, 0x50, 0x49, 0x64, 0x38, 0x41, 0x6F, 0x72, 0x52, 0x62, 0x72, 0x63, 0x57, 0x63, 0x2B, 0x5A, 0x66, 0x77, ++ 0x46, 0x53, 0x59, 0x31, 0x58, 0x53, 0x2B, 0x77, 0x63, 0x33, 0x69, 0x45, 0x5A, 0x47, 0x74, 0x49, 0x78, 0x67, 0x39, 0x33, 0x65, 0x46, 0x79, 0x52, 0x4A, 0x61, 0x30, 0x0A, 0x6C, 0x56, 0x37, 0x41, 0x65, 0x34, 0x36, 0x5A, 0x65, 0x42, 0x5A, 0x44, ++ 0x45, 0x31, 0x5A, 0x58, 0x73, 0x36, 0x4B, 0x7A, 0x4F, 0x37, 0x56, 0x33, 0x33, 0x45, 0x42, 0x79, 0x72, 0x4B, 0x50, 0x72, 0x6D, 0x7A, 0x55, 0x2B, 0x73, 0x51, 0x67, 0x68, 0x6F, 0x65, 0x66, 0x45, 0x51, 0x7A, 0x64, 0x35, 0x4D, 0x72, 0x36, 0x31, ++ 0x35, 0x35, 0x77, 0x73, 0x54, 0x4C, 0x78, 0x44, 0x4B, 0x5A, 0x6D, 0x4F, 0x4D, 0x4E, 0x4F, 0x73, 0x49, 0x65, 0x44, 0x6A, 0x48, 0x66, 0x72, 0x59, 0x0A, 0x42, 0x7A, 0x4E, 0x32, 0x56, 0x41, 0x41, 0x69, 0x4B, 0x72, 0x6C, 0x4E, 0x49, 0x43, 0x35, ++ 0x77, 0x61, 0x4E, 0x72, 0x6C, 0x55, 0x2F, 0x79, 0x44, 0x58, 0x4E, 0x4F, 0x64, 0x38, 0x76, 0x39, 0x45, 0x44, 0x45, 0x52, 0x6D, 0x38, 0x74, 0x4C, 0x6A, 0x76, 0x55, 0x59, 0x41, 0x47, 0x6D, 0x30, 0x43, 0x75, 0x69, 0x56, 0x64, 0x6A, 0x61, 0x45, ++ 0x78, 0x55, 0x64, 0x31, 0x55, 0x52, 0x68, 0x78, 0x4E, 0x32, 0x35, 0x6D, 0x57, 0x37, 0x78, 0x6F, 0x63, 0x42, 0x46, 0x79, 0x6D, 0x0A, 0x46, 0x65, 0x39, 0x34, 0x34, 0x48, 0x6E, 0x2B, 0x58, 0x64, 0x73, 0x2B, 0x71, 0x6B, 0x78, 0x56, 0x2F, 0x5A, ++ 0x6F, 0x56, 0x71, 0x57, 0x2F, 0x68, 0x70, 0x76, 0x76, 0x66, 0x63, 0x44, 0x44, 0x70, 0x77, 0x2B, 0x35, 0x43, 0x52, 0x75, 0x33, 0x43, 0x6B, 0x77, 0x57, 0x4A, 0x2B, 0x6E, 0x31, 0x6A, 0x65, 0x7A, 0x2F, 0x51, 0x63, 0x59, 0x46, 0x38, 0x41, 0x4F, ++ 0x69, 0x59, 0x72, 0x67, 0x35, 0x34, 0x4E, 0x4D, 0x4D, 0x6C, 0x2B, 0x36, 0x38, 0x4B, 0x6E, 0x79, 0x42, 0x72, 0x0A, 0x33, 0x54, 0x73, 0x54, 0x6A, 0x78, 0x4B, 0x4D, 0x34, 0x6B, 0x45, 0x61, 0x53, 0x48, 0x70, 0x7A, 0x6F, 0x48, 0x64, 0x70, 0x78, ++ 0x37, 0x5A, 0x63, 0x66, 0x34, 0x4C, 0x49, 0x48, 0x76, 0x35, 0x59, 0x47, 0x79, 0x67, 0x72, 0x71, 0x47, 0x79, 0x74, 0x58, 0x6D, 0x33, 0x41, 0x42, 0x64, 0x4A, 0x37, 0x74, 0x2B, 0x75, 0x41, 0x2F, 0x69, 0x55, 0x33, 0x2F, 0x67, 0x4B, 0x62, 0x61, ++ 0x4B, 0x78, 0x43, 0x58, 0x63, 0x50, 0x75, 0x39, 0x63, 0x7A, 0x63, 0x38, 0x46, 0x42, 0x31, 0x0A, 0x30, 0x6A, 0x5A, 0x70, 0x6E, 0x4F, 0x5A, 0x37, 0x42, 0x4E, 0x39, 0x75, 0x42, 0x6D, 0x6D, 0x32, 0x33, 0x67, 0x6F, 0x4A, 0x53, 0x46, 0x6D, 0x48, ++ 0x36, 0x33, 0x73, 0x55, 0x59, 0x48, 0x70, 0x6B, 0x71, 0x6D, 0x6C, 0x44, 0x37, 0x35, 0x48, 0x48, 0x54, 0x4F, 0x77, 0x59, 0x33, 0x57, 0x7A, 0x76, 0x55, 0x79, 0x32, 0x4D, 0x6D, 0x65, 0x46, 0x65, 0x38, 0x6E, 0x49, 0x2B, 0x7A, 0x31, 0x54, 0x49, ++ 0x76, 0x57, 0x66, 0x73, 0x70, 0x41, 0x39, 0x4D, 0x52, 0x66, 0x2F, 0x54, 0x0A, 0x75, 0x54, 0x41, 0x6A, 0x42, 0x30, 0x79, 0x50, 0x45, 0x4C, 0x2B, 0x47, 0x6C, 0x74, 0x6D, 0x5A, 0x57, 0x72, 0x53, 0x5A, 0x56, 0x78, 0x79, 0x6B, 0x7A, 0x4C, 0x73, ++ 0x56, 0x69, 0x56, 0x4F, 0x36, 0x4C, 0x41, 0x55, 0x50, 0x35, 0x4D, 0x53, 0x65, 0x47, 0x62, 0x45, 0x59, 0x4E, 0x4E, 0x56, 0x4D, 0x6E, 0x62, 0x72, 0x74, 0x39, 0x78, 0x2B, 0x76, 0x4A, 0x4A, 0x55, 0x45, 0x65, 0x4B, 0x67, 0x44, 0x75, 0x2B, 0x36, ++ 0x42, 0x35, 0x64, 0x70, 0x66, 0x66, 0x49, 0x74, 0x4B, 0x0A, 0x6F, 0x5A, 0x42, 0x30, 0x4A, 0x61, 0x65, 0x7A, 0x50, 0x6B, 0x76, 0x49, 0x4C, 0x46, 0x61, 0x39, 0x78, 0x38, 0x6A, 0x76, 0x4F, 0x4F, 0x4A, 0x63, 0x6B, 0x76, 0x42, 0x35, 0x39, 0x35, ++ 0x79, 0x45, 0x75, 0x6E, 0x51, 0x74, 0x59, 0x51, 0x45, 0x67, 0x66, 0x6E, 0x37, 0x52, 0x38, 0x6B, 0x38, 0x48, 0x57, 0x56, 0x2B, 0x4C, 0x4C, 0x55, 0x4E, 0x53, 0x36, 0x30, 0x59, 0x4D, 0x6C, 0x4F, 0x48, 0x31, 0x5A, 0x6B, 0x64, 0x35, 0x64, 0x39, ++ 0x56, 0x55, 0x57, 0x78, 0x2B, 0x74, 0x0A, 0x4A, 0x44, 0x66, 0x4C, 0x52, 0x56, 0x70, 0x4F, 0x6F, 0x45, 0x52, 0x49, 0x79, 0x4E, 0x69, 0x77, 0x6D, 0x63, 0x55, 0x56, 0x68, 0x41, 0x6E, 0x32, 0x31, 0x6B, 0x6C, 0x4A, 0x77, 0x47, 0x57, 0x34, 0x35, ++ 0x68, 0x70, 0x78, 0x62, 0x71, 0x43, 0x6F, 0x38, 0x59, 0x4C, 0x6F, 0x52, 0x54, 0x35, 0x73, 0x31, 0x67, 0x4C, 0x58, 0x43, 0x6D, 0x65, 0x44, 0x42, 0x56, 0x72, 0x4A, 0x70, 0x42, 0x41, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, ++ 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x4F, 0x49, 0x53, 0x54, 0x45, 0x20, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, ++ 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x43, 0x20, 0x43, 0x41, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x61, 0x54, 0x43, 0x43, 0x41, ++ 0x65, 0x2B, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x49, 0x53, 0x70, 0x57, 0x44, 0x4B, 0x37, 0x61, 0x44, 0x4B, 0x74, 0x41, 0x52, 0x62, 0x38, 0x72, 0x6F, 0x69, 0x30, 0x36, 0x36, 0x6A, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, ++ 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x7A, 0x42, 0x74, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x44, 0x0A, 0x53, 0x44, 0x45, 0x51, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x45, ++ 0x43, 0x68, 0x4D, 0x48, 0x56, 0x30, 0x6C, 0x54, 0x5A, 0x55, 0x74, 0x6C, 0x65, 0x54, 0x45, 0x69, 0x4D, 0x43, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4D, 0x5A, 0x54, 0x30, 0x6C, 0x54, 0x56, 0x45, 0x55, 0x67, 0x52, 0x6D, 0x39, 0x31, ++ 0x62, 0x6D, 0x52, 0x68, 0x64, 0x47, 0x6C, 0x76, 0x62, 0x69, 0x42, 0x46, 0x62, 0x6D, 0x52, 0x76, 0x63, 0x6E, 0x4E, 0x6C, 0x5A, 0x44, 0x45, 0x6F, 0x0A, 0x4D, 0x43, 0x59, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x66, 0x54, 0x30, 0x6C, ++ 0x54, 0x56, 0x45, 0x55, 0x67, 0x56, 0x30, 0x6C, 0x54, 0x5A, 0x55, 0x74, 0x6C, 0x65, 0x53, 0x42, 0x48, 0x62, 0x47, 0x39, 0x69, 0x59, 0x57, 0x77, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x48, 0x51, 0x79, 0x42, 0x44, 0x51, 0x54, 0x41, ++ 0x65, 0x46, 0x77, 0x30, 0x78, 0x4E, 0x7A, 0x41, 0x31, 0x4D, 0x44, 0x6B, 0x77, 0x4F, 0x54, 0x51, 0x34, 0x4D, 0x7A, 0x52, 0x61, 0x0A, 0x46, 0x77, 0x30, 0x30, 0x4D, 0x6A, 0x41, 0x31, 0x4D, 0x44, 0x6B, 0x77, 0x4F, 0x54, 0x55, 0x34, 0x4D, 0x7A, ++ 0x4E, 0x61, 0x4D, 0x47, 0x30, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x4E, 0x49, 0x4D, 0x52, 0x41, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x77, 0x64, 0x58, 0x53, 0x56, ++ 0x4E, 0x6C, 0x53, 0x32, 0x56, 0x35, 0x4D, 0x53, 0x49, 0x77, 0x49, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, 0x0A, 0x45, 0x78, 0x6C, 0x50, 0x53, 0x56, 0x4E, 0x55, 0x52, 0x53, 0x42, 0x47, 0x62, 0x33, 0x56, 0x75, 0x5A, 0x47, 0x46, 0x30, 0x61, ++ 0x57, 0x39, 0x75, 0x49, 0x45, 0x56, 0x75, 0x5A, 0x47, 0x39, 0x79, 0x63, 0x32, 0x56, 0x6B, 0x4D, 0x53, 0x67, 0x77, 0x4A, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x39, 0x50, 0x53, 0x56, 0x4E, 0x55, 0x52, 0x53, 0x42, 0x58, 0x53, ++ 0x56, 0x4E, 0x6C, 0x53, 0x32, 0x56, 0x35, 0x49, 0x45, 0x64, 0x73, 0x62, 0x32, 0x4A, 0x68, 0x0A, 0x62, 0x43, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x64, 0x44, 0x49, 0x45, 0x4E, 0x42, 0x4D, 0x48, 0x59, 0x77, 0x45, 0x41, 0x59, 0x48, ++ 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x46, 0x4B, 0x34, 0x45, 0x45, 0x41, 0x43, 0x49, 0x44, 0x59, 0x67, 0x41, 0x45, 0x54, 0x4F, 0x6C, 0x51, 0x77, 0x4D, 0x59, 0x50, 0x63, 0x68, 0x69, 0x38, 0x32, 0x50, 0x47, 0x36, ++ 0x73, 0x34, 0x6E, 0x69, 0x65, 0x55, 0x71, 0x6A, 0x46, 0x71, 0x64, 0x72, 0x0A, 0x56, 0x43, 0x54, 0x62, 0x55, 0x66, 0x2F, 0x71, 0x39, 0x41, 0x6B, 0x6B, 0x77, 0x77, 0x73, 0x69, 0x6E, 0x38, 0x74, 0x71, 0x4A, 0x34, 0x4B, 0x42, 0x44, 0x64, 0x4C, ++ 0x41, 0x72, 0x7A, 0x48, 0x6B, 0x64, 0x49, 0x4A, 0x75, 0x79, 0x69, 0x58, 0x5A, 0x6A, 0x48, 0x57, 0x64, 0x38, 0x64, 0x76, 0x51, 0x6D, 0x71, 0x4A, 0x4C, 0x49, 0x58, 0x34, 0x57, 0x70, 0x32, 0x4F, 0x51, 0x30, 0x6A, 0x6E, 0x55, 0x73, 0x59, 0x64, ++ 0x34, 0x58, 0x78, 0x69, 0x57, 0x44, 0x31, 0x41, 0x62, 0x0A, 0x4E, 0x54, 0x63, 0x50, 0x61, 0x73, 0x62, 0x63, 0x32, 0x52, 0x4E, 0x4E, 0x70, 0x49, 0x36, 0x51, 0x4E, 0x2B, 0x61, 0x39, 0x57, 0x7A, 0x47, 0x52, 0x6F, 0x31, 0x51, 0x77, 0x55, 0x6A, ++ 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x51, 0x59, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, ++ 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x64, 0x0A, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x53, 0x49, 0x63, 0x55, 0x72, 0x4F, 0x50, 0x44, 0x6E, 0x70, 0x42, 0x67, 0x4F, 0x74, 0x66, 0x4B, 0x69, 0x65, 0x37, 0x54, 0x72, ++ 0x59, 0x79, 0x30, 0x55, 0x47, 0x59, 0x77, 0x45, 0x41, 0x59, 0x4A, 0x4B, 0x77, 0x59, 0x42, 0x42, 0x41, 0x47, 0x43, 0x4E, 0x78, 0x55, 0x42, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x51, 0x41, 0x77, 0x43, 0x67, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, ++ 0x6A, 0x30, 0x45, 0x0A, 0x41, 0x77, 0x4D, 0x44, 0x61, 0x41, 0x41, 0x77, 0x5A, 0x51, 0x49, 0x77, 0x4A, 0x73, 0x64, 0x70, 0x57, 0x39, 0x7A, 0x56, 0x35, 0x37, 0x4C, 0x6E, 0x79, 0x41, 0x79, 0x4D, 0x6A, 0x4D, 0x50, 0x64, 0x65, 0x59, 0x77, 0x62, ++ 0x59, 0x39, 0x58, 0x4A, 0x55, 0x70, 0x52, 0x4F, 0x54, 0x59, 0x4A, 0x4B, 0x63, 0x78, 0x36, 0x79, 0x67, 0x49, 0x53, 0x70, 0x4A, 0x63, 0x42, 0x4D, 0x57, 0x6D, 0x31, 0x4A, 0x4B, 0x57, 0x42, 0x34, 0x45, 0x2B, 0x4A, 0x2B, 0x53, 0x4F, 0x74, 0x6B, ++ 0x0A, 0x41, 0x6A, 0x45, 0x41, 0x32, 0x7A, 0x51, 0x67, 0x4D, 0x67, 0x6A, 0x2F, 0x6D, 0x6B, 0x6B, 0x43, 0x74, 0x6F, 0x6A, 0x65, 0x46, 0x4B, 0x39, 0x64, 0x62, 0x4A, 0x6C, 0x78, 0x6A, 0x52, 0x6F, 0x2F, 0x69, 0x39, 0x66, 0x67, 0x6F, 0x6A, 0x61, ++ 0x47, 0x48, 0x41, 0x65, 0x43, 0x4F, 0x6E, 0x5A, 0x54, 0x2F, 0x63, 0x4B, 0x69, 0x37, 0x65, 0x39, 0x37, 0x73, 0x49, 0x42, 0x50, 0x57, 0x41, 0x39, 0x4C, 0x55, 0x7A, 0x6D, 0x39, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, ++ 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x55, 0x43, 0x41, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x47, 0x32, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, ++ 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x52, 0x6A, 0x43, 0x43, 0x41, 0x79, 0x36, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x58, 0x64, 0x2B, 0x78, 0x32, 0x6C, 0x71, 0x6A, 0x37, 0x56, 0x32, 0x2B, 0x57, 0x6D, 0x55, 0x67, 0x5A, ++ 0x51, 0x4F, 0x51, 0x37, 0x7A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x41, 0x39, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0A, ++ 0x45, 0x77, 0x4A, 0x44, 0x54, 0x6A, 0x45, 0x52, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x49, 0x56, 0x57, 0x35, 0x70, 0x56, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x78, 0x47, 0x7A, 0x41, 0x5A, 0x42, 0x67, 0x4E, 0x56, ++ 0x42, 0x41, 0x4D, 0x4D, 0x45, 0x6C, 0x56, 0x44, 0x51, 0x53, 0x42, 0x48, 0x62, 0x47, 0x39, 0x69, 0x59, 0x57, 0x77, 0x67, 0x52, 0x7A, 0x49, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x44, 0x41, 0x65, 0x46, 0x77, 0x30, 0x78, 0x0A, 0x4E, 0x6A, 0x41, ++ 0x7A, 0x4D, 0x54, 0x45, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x42, 0x61, 0x46, 0x77, 0x30, 0x30, 0x4D, 0x44, 0x45, 0x79, 0x4D, 0x7A, 0x45, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x42, 0x61, 0x4D, 0x44, 0x30, 0x78, 0x43, 0x7A, 0x41, ++ 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x4E, 0x4F, 0x4D, 0x52, 0x45, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x44, 0x41, 0x68, 0x56, 0x62, 0x6D, 0x6C, 0x55, 0x0A, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x44, ++ 0x45, 0x62, 0x4D, 0x42, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x53, 0x56, 0x55, 0x4E, 0x42, 0x49, 0x45, 0x64, 0x73, 0x62, 0x32, 0x4A, 0x68, 0x62, 0x43, 0x42, 0x48, 0x4D, 0x69, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x4D, 0x49, ++ 0x49, 0x43, 0x49, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x67, 0x38, 0x41, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x43, 0x67, 0x4B, 0x43, 0x41, ++ 0x67, 0x45, 0x41, 0x78, 0x65, 0x59, 0x72, 0x62, 0x33, 0x7A, 0x76, 0x4A, 0x67, 0x55, 0x6E, 0x6F, 0x34, 0x45, 0x6B, 0x32, 0x6D, 0x2F, 0x4C, 0x41, 0x66, 0x6D, 0x5A, 0x6D, 0x71, 0x6B, 0x79, 0x77, 0x69, 0x4B, 0x48, 0x59, 0x55, 0x47, 0x52, 0x4F, ++ 0x38, 0x76, 0x44, 0x61, 0x42, 0x73, 0x47, 0x78, 0x55, 0x79, 0x70, 0x4B, 0x38, 0x46, 0x6E, 0x46, 0x79, 0x49, 0x64, 0x4B, 0x2B, 0x33, 0x35, 0x4B, 0x59, 0x6D, 0x54, 0x0A, 0x6F, 0x6E, 0x69, 0x39, 0x6B, 0x6D, 0x75, 0x67, 0x6F, 0x77, 0x32, 0x69, ++ 0x66, 0x73, 0x71, 0x54, 0x73, 0x36, 0x62, 0x52, 0x6A, 0x44, 0x58, 0x56, 0x64, 0x66, 0x6B, 0x58, 0x39, 0x73, 0x39, 0x46, 0x78, 0x65, 0x56, 0x36, 0x37, 0x48, 0x65, 0x54, 0x6F, 0x49, 0x38, 0x6A, 0x72, 0x67, 0x34, 0x61, 0x41, 0x33, 0x2B, 0x2B, ++ 0x31, 0x4E, 0x44, 0x74, 0x4C, 0x6E, 0x75, 0x72, 0x52, 0x69, 0x4E, 0x62, 0x2F, 0x79, 0x7A, 0x6D, 0x56, 0x48, 0x71, 0x55, 0x77, 0x43, 0x6F, 0x56, 0x0A, 0x38, 0x4D, 0x6D, 0x4E, 0x73, 0x48, 0x6F, 0x37, 0x4A, 0x4F, 0x48, 0x58, 0x61, 0x4F, 0x49, ++ 0x78, 0x50, 0x41, 0x59, 0x7A, 0x52, 0x72, 0x5A, 0x55, 0x45, 0x61, 0x61, 0x6C, 0x4C, 0x79, 0x4A, 0x55, 0x4B, 0x6C, 0x67, 0x4E, 0x41, 0x51, 0x4C, 0x78, 0x2B, 0x68, 0x56, 0x52, 0x5A, 0x32, 0x7A, 0x41, 0x2B, 0x74, 0x65, 0x32, 0x47, 0x33, 0x2F, ++ 0x52, 0x56, 0x6F, 0x67, 0x76, 0x47, 0x6A, 0x71, 0x4E, 0x4F, 0x37, 0x75, 0x43, 0x45, 0x65, 0x42, 0x48, 0x41, 0x4E, 0x42, 0x53, 0x0A, 0x68, 0x36, 0x76, 0x37, 0x68, 0x6E, 0x34, 0x50, 0x4A, 0x47, 0x74, 0x41, 0x6E, 0x54, 0x52, 0x6E, 0x76, 0x49, ++ 0x33, 0x48, 0x4C, 0x59, 0x5A, 0x76, 0x65, 0x54, 0x36, 0x4F, 0x71, 0x54, 0x77, 0x58, 0x53, 0x33, 0x2B, 0x77, 0x6D, 0x65, 0x4F, 0x77, 0x63, 0x57, 0x44, 0x63, 0x43, 0x2F, 0x56, 0x6B, 0x77, 0x38, 0x35, 0x44, 0x76, 0x47, 0x31, 0x78, 0x75, 0x64, ++ 0x4C, 0x65, 0x4A, 0x31, 0x75, 0x4B, 0x36, 0x4E, 0x6A, 0x47, 0x72, 0x75, 0x46, 0x5A, 0x66, 0x63, 0x38, 0x6F, 0x0A, 0x4C, 0x54, 0x57, 0x34, 0x6C, 0x56, 0x59, 0x61, 0x38, 0x62, 0x4A, 0x59, 0x53, 0x37, 0x63, 0x53, 0x4E, 0x38, 0x68, 0x38, 0x73, ++ 0x2B, 0x31, 0x4C, 0x67, 0x4F, 0x47, 0x4E, 0x2B, 0x6A, 0x49, 0x6A, 0x74, 0x6D, 0x2B, 0x33, 0x53, 0x4A, 0x55, 0x49, 0x73, 0x55, 0x52, 0x4F, 0x68, 0x59, 0x77, 0x36, 0x41, 0x6C, 0x51, 0x67, 0x4C, 0x39, 0x2B, 0x2F, 0x56, 0x30, 0x38, 0x37, 0x4F, ++ 0x70, 0x41, 0x68, 0x31, 0x38, 0x45, 0x6D, 0x4E, 0x56, 0x51, 0x67, 0x37, 0x4D, 0x63, 0x2F, 0x0A, 0x52, 0x2B, 0x7A, 0x76, 0x57, 0x72, 0x39, 0x4C, 0x65, 0x73, 0x47, 0x74, 0x4F, 0x78, 0x64, 0x51, 0x58, 0x47, 0x4C, 0x59, 0x44, 0x30, 0x74, 0x4B, ++ 0x33, 0x43, 0x76, 0x36, 0x62, 0x72, 0x78, 0x7A, 0x6B, 0x73, 0x33, 0x73, 0x78, 0x31, 0x44, 0x6F, 0x51, 0x5A, 0x62, 0x58, 0x71, 0x58, 0x35, 0x74, 0x32, 0x4F, 0x6B, 0x64, 0x6A, 0x34, 0x71, 0x31, 0x75, 0x56, 0x69, 0x53, 0x75, 0x6B, 0x71, 0x53, ++ 0x4B, 0x77, 0x78, 0x57, 0x2F, 0x59, 0x44, 0x72, 0x43, 0x50, 0x42, 0x65, 0x0A, 0x4B, 0x57, 0x34, 0x62, 0x48, 0x41, 0x79, 0x76, 0x6A, 0x35, 0x4F, 0x4A, 0x72, 0x64, 0x75, 0x39, 0x6F, 0x35, 0x34, 0x68, 0x79, 0x6F, 0x6B, 0x5A, 0x37, 0x4E, 0x2B, ++ 0x31, 0x77, 0x78, 0x72, 0x72, 0x46, 0x76, 0x35, 0x34, 0x4E, 0x6B, 0x7A, 0x57, 0x62, 0x74, 0x41, 0x2B, 0x46, 0x78, 0x79, 0x51, 0x46, 0x32, 0x73, 0x6D, 0x75, 0x76, 0x74, 0x36, 0x4C, 0x37, 0x38, 0x52, 0x48, 0x42, 0x67, 0x4F, 0x4C, 0x58, 0x4D, ++ 0x44, 0x6A, 0x36, 0x44, 0x6C, 0x4E, 0x61, 0x42, 0x61, 0x0A, 0x34, 0x6B, 0x78, 0x31, 0x48, 0x58, 0x48, 0x68, 0x4F, 0x54, 0x68, 0x54, 0x65, 0x45, 0x44, 0x4D, 0x67, 0x35, 0x50, 0x58, 0x43, 0x70, 0x36, 0x64, 0x57, 0x34, 0x2B, 0x4B, 0x35, 0x4F, ++ 0x58, 0x67, 0x53, 0x4F, 0x52, 0x49, 0x73, 0x6B, 0x66, 0x4E, 0x54, 0x69, 0x70, 0x31, 0x4B, 0x6E, 0x76, 0x79, 0x49, 0x76, 0x62, 0x4A, 0x76, 0x67, 0x6D, 0x52, 0x6C, 0x6C, 0x64, 0x36, 0x69, 0x49, 0x69, 0x73, 0x37, 0x6E, 0x43, 0x73, 0x2B, 0x64, ++ 0x77, 0x70, 0x34, 0x77, 0x77, 0x63, 0x0A, 0x4F, 0x78, 0x4A, 0x4F, 0x52, 0x4E, 0x61, 0x6E, 0x54, 0x72, 0x41, 0x6D, 0x79, 0x50, 0x50, 0x5A, 0x47, 0x70, 0x65, 0x52, 0x61, 0x4F, 0x72, 0x76, 0x6A, 0x55, 0x59, 0x47, 0x30, 0x6C, 0x5A, 0x46, 0x57, ++ 0x4A, 0x6F, 0x38, 0x44, 0x41, 0x2B, 0x44, 0x75, 0x41, 0x55, 0x6C, 0x77, 0x7A, 0x6E, 0x50, 0x4F, 0x36, 0x51, 0x30, 0x69, 0x62, 0x64, 0x35, 0x45, 0x69, 0x39, 0x48, 0x78, 0x65, 0x65, 0x70, 0x6C, 0x32, 0x6E, 0x38, 0x70, 0x6E, 0x64, 0x6E, 0x74, ++ 0x64, 0x39, 0x37, 0x0A, 0x38, 0x58, 0x70, 0x6C, 0x46, 0x65, 0x52, 0x68, 0x56, 0x6D, 0x55, 0x43, 0x41, 0x77, 0x45, 0x41, 0x41, 0x61, 0x4E, 0x43, 0x4D, 0x45, 0x41, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, ++ 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, ++ 0x0A, 0x42, 0x42, 0x59, 0x45, 0x46, 0x49, 0x48, 0x45, 0x6A, 0x4D, 0x7A, 0x31, 0x35, 0x44, 0x44, 0x2F, 0x70, 0x51, 0x77, 0x49, 0x58, 0x34, 0x77, 0x56, 0x5A, 0x79, 0x46, 0x30, 0x41, 0x64, 0x2F, 0x66, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, ++ 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43, 0x77, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x41, 0x51, 0x41, 0x54, 0x5A, 0x53, 0x4C, 0x31, 0x6A, 0x69, 0x75, 0x74, 0x52, 0x4F, 0x54, 0x4C, 0x2F, 0x37, 0x6C, 0x6F, 0x0A, 0x35, 0x73, ++ 0x4F, 0x41, 0x53, 0x44, 0x30, 0x45, 0x65, 0x2F, 0x6F, 0x6A, 0x4C, 0x33, 0x72, 0x74, 0x4E, 0x74, 0x71, 0x79, 0x7A, 0x6D, 0x33, 0x32, 0x35, 0x70, 0x37, 0x6C, 0x58, 0x31, 0x69, 0x50, 0x79, 0x7A, 0x63, 0x79, 0x6F, 0x63, 0x68, 0x6C, 0x74, 0x71, ++ 0x34, 0x34, 0x50, 0x54, 0x55, 0x62, 0x50, 0x72, 0x77, 0x37, 0x74, 0x67, 0x54, 0x51, 0x76, 0x50, 0x6C, 0x4A, 0x39, 0x5A, 0x76, 0x33, 0x68, 0x63, 0x55, 0x32, 0x74, 0x73, 0x75, 0x38, 0x2B, 0x4D, 0x67, 0x35, 0x0A, 0x31, 0x65, 0x52, 0x66, 0x42, ++ 0x37, 0x30, 0x56, 0x56, 0x4A, 0x64, 0x30, 0x79, 0x73, 0x72, 0x74, 0x54, 0x37, 0x71, 0x36, 0x5A, 0x48, 0x61, 0x66, 0x67, 0x62, 0x69, 0x45, 0x52, 0x55, 0x6C, 0x4D, 0x6A, 0x57, 0x2B, 0x69, 0x36, 0x37, 0x48, 0x4D, 0x30, 0x63, 0x4F, 0x55, 0x32, ++ 0x6B, 0x54, 0x43, 0x35, 0x75, 0x4C, 0x71, 0x47, 0x4F, 0x69, 0x69, 0x48, 0x79, 0x63, 0x46, 0x75, 0x74, 0x66, 0x6C, 0x31, 0x71, 0x6E, 0x4E, 0x33, 0x65, 0x39, 0x32, 0x6D, 0x49, 0x30, 0x41, 0x0A, 0x44, 0x73, 0x30, 0x62, 0x2B, 0x67, 0x4F, 0x33, ++ 0x6A, 0x6F, 0x42, 0x59, 0x44, 0x69, 0x63, 0x2F, 0x55, 0x76, 0x75, 0x55, 0x6F, 0x73, 0x70, 0x65, 0x5A, 0x63, 0x6E, 0x57, 0x68, 0x4E, 0x71, 0x35, 0x4E, 0x58, 0x48, 0x7A, 0x4A, 0x73, 0x42, 0x50, 0x64, 0x2B, 0x61, 0x42, 0x4A, 0x39, 0x4A, 0x33, ++ 0x4F, 0x35, 0x6F, 0x55, 0x62, 0x33, 0x6E, 0x30, 0x39, 0x74, 0x44, 0x68, 0x30, 0x35, 0x53, 0x36, 0x30, 0x46, 0x64, 0x52, 0x76, 0x53, 0x63, 0x46, 0x44, 0x63, 0x48, 0x39, 0x0A, 0x79, 0x42, 0x49, 0x77, 0x37, 0x6D, 0x2B, 0x4E, 0x45, 0x53, 0x73, ++ 0x49, 0x6E, 0x64, 0x54, 0x55, 0x76, 0x34, 0x42, 0x46, 0x46, 0x4A, 0x71, 0x49, 0x52, 0x4E, 0x6F, 0x77, 0x36, 0x72, 0x53, 0x6E, 0x34, 0x2B, 0x37, 0x76, 0x57, 0x34, 0x4C, 0x56, 0x50, 0x74, 0x61, 0x74, 0x65, 0x4A, 0x4C, 0x62, 0x58, 0x44, 0x7A, ++ 0x7A, 0x32, 0x4B, 0x33, 0x36, 0x75, 0x47, 0x74, 0x2F, 0x78, 0x44, 0x59, 0x6F, 0x74, 0x67, 0x49, 0x56, 0x69, 0x6C, 0x51, 0x73, 0x6E, 0x4C, 0x41, 0x58, 0x0A, 0x63, 0x34, 0x37, 0x51, 0x4E, 0x36, 0x4D, 0x55, 0x50, 0x4A, 0x69, 0x56, 0x41, 0x41, ++ 0x77, 0x70, 0x42, 0x56, 0x75, 0x65, 0x53, 0x55, 0x6D, 0x78, 0x58, 0x38, 0x66, 0x6A, 0x79, 0x38, 0x38, 0x6E, 0x5A, 0x59, 0x34, 0x31, 0x46, 0x37, 0x64, 0x58, 0x79, 0x44, 0x44, 0x5A, 0x51, 0x56, 0x75, 0x35, 0x46, 0x4C, 0x62, 0x6F, 0x77, 0x67, ++ 0x2B, 0x55, 0x4D, 0x61, 0x65, 0x55, 0x6D, 0x4D, 0x78, 0x71, 0x36, 0x37, 0x58, 0x68, 0x4A, 0x2F, 0x55, 0x51, 0x71, 0x41, 0x48, 0x6F, 0x0A, 0x6A, 0x68, 0x4A, 0x69, 0x36, 0x49, 0x6A, 0x4D, 0x74, 0x58, 0x39, 0x47, 0x6C, 0x38, 0x43, 0x62, 0x45, ++ 0x47, 0x59, 0x34, 0x47, 0x6A, 0x5A, 0x47, 0x58, 0x79, 0x4A, 0x6F, 0x50, 0x64, 0x2F, 0x4A, 0x78, 0x68, 0x4D, 0x6E, 0x71, 0x31, 0x4D, 0x47, 0x72, 0x4B, 0x49, 0x38, 0x68, 0x67, 0x5A, 0x6C, 0x62, 0x37, 0x46, 0x2B, 0x73, 0x53, 0x6C, 0x45, 0x6D, ++ 0x71, 0x4F, 0x36, 0x53, 0x57, 0x6B, 0x6F, 0x61, 0x59, 0x2F, 0x58, 0x35, 0x56, 0x2B, 0x74, 0x42, 0x49, 0x5A, 0x6B, 0x0A, 0x62, 0x78, 0x71, 0x67, 0x44, 0x4D, 0x55, 0x49, 0x59, 0x73, 0x36, 0x41, 0x6F, 0x39, 0x44, 0x7A, 0x37, 0x47, 0x6A, 0x65, ++ 0x76, 0x6A, 0x50, 0x48, 0x46, 0x31, 0x74, 0x2F, 0x67, 0x4D, 0x52, 0x4D, 0x54, 0x4C, 0x47, 0x6D, 0x68, 0x49, 0x72, 0x44, 0x4F, 0x37, 0x67, 0x4A, 0x7A, 0x52, 0x53, 0x42, 0x75, 0x68, 0x6A, 0x6A, 0x56, 0x46, 0x63, 0x32, 0x2F, 0x74, 0x73, 0x76, ++ 0x66, 0x45, 0x65, 0x68, 0x4F, 0x6A, 0x50, 0x49, 0x2B, 0x56, 0x67, 0x37, 0x52, 0x45, 0x2B, 0x78, 0x0A, 0x79, 0x67, 0x4B, 0x4A, 0x42, 0x4A, 0x59, 0x6F, 0x61, 0x4D, 0x56, 0x4C, 0x75, 0x43, 0x61, 0x4A, 0x75, 0x39, 0x59, 0x7A, 0x4C, 0x31, 0x44, ++ 0x56, 0x2F, 0x70, 0x71, 0x4A, 0x75, 0x68, 0x67, 0x79, 0x6B, 0x6C, 0x54, 0x47, 0x57, 0x2B, 0x43, 0x64, 0x2B, 0x56, 0x37, 0x6C, 0x44, 0x53, 0x4B, 0x62, 0x39, 0x74, 0x72, 0x69, 0x79, 0x43, 0x47, 0x79, 0x59, 0x69, 0x47, 0x71, 0x68, 0x6B, 0x43, ++ 0x79, 0x4C, 0x6D, 0x54, 0x54, 0x58, 0x38, 0x6A, 0x6A, 0x66, 0x68, 0x46, 0x6E, 0x0A, 0x52, 0x52, 0x38, 0x46, 0x2F, 0x75, 0x4F, 0x69, 0x37, 0x37, 0x4F, 0x6F, 0x73, 0x2F, 0x4E, 0x39, 0x6A, 0x2F, 0x67, 0x4D, 0x48, 0x79, 0x49, 0x66, 0x4C, 0x58, ++ 0x43, 0x30, 0x75, 0x41, 0x45, 0x30, 0x64, 0x6A, 0x41, 0x41, 0x35, 0x53, 0x4E, 0x34, 0x70, 0x31, 0x62, 0x58, 0x55, 0x42, 0x2B, 0x4B, 0x2B, 0x77, 0x62, 0x31, 0x77, 0x68, 0x6E, 0x77, 0x30, 0x41, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x55, 0x43, 0x41, 0x20, 0x45, 0x78, 0x74, 0x65, 0x6E, 0x64, 0x65, 0x64, 0x20, 0x56, 0x61, 0x6C, 0x69, 0x64, ++ 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, ++ 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x57, 0x6A, 0x43, 0x43, 0x41, 0x30, 0x4B, 0x67, ++ 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x54, 0x39, 0x49, 0x72, 0x6A, 0x2F, 0x56, 0x6B, 0x79, 0x44, 0x4F, 0x65, 0x54, 0x7A, 0x52, 0x59, 0x5A, 0x69, 0x4E, 0x77, 0x59, 0x44, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, ++ 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x42, 0x48, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0A, 0x45, 0x77, 0x4A, 0x44, 0x54, 0x6A, 0x45, 0x52, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, ++ 0x45, 0x43, 0x67, 0x77, 0x49, 0x56, 0x57, 0x35, 0x70, 0x56, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x78, 0x4A, 0x54, 0x41, 0x6A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x48, 0x46, 0x56, 0x44, 0x51, 0x53, 0x42, 0x46, 0x65, 0x48, 0x52, ++ 0x6C, 0x62, 0x6D, 0x52, 0x6C, 0x5A, 0x43, 0x42, 0x57, 0x59, 0x57, 0x78, 0x70, 0x5A, 0x47, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x0A, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x54, 0x55, 0x77, 0x4D, 0x7A, ++ 0x45, 0x7A, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x57, 0x68, 0x63, 0x4E, 0x4D, 0x7A, 0x67, 0x78, 0x4D, 0x6A, 0x4D, 0x78, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x57, 0x6A, 0x42, 0x48, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, ++ 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x44, 0x54, 0x6A, 0x45, 0x52, 0x4D, 0x41, 0x38, 0x47, 0x0A, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x49, 0x56, 0x57, 0x35, 0x70, 0x56, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x78, 0x4A, ++ 0x54, 0x41, 0x6A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x48, 0x46, 0x56, 0x44, 0x51, 0x53, 0x42, 0x46, 0x65, 0x48, 0x52, 0x6C, 0x62, 0x6D, 0x52, 0x6C, 0x5A, 0x43, 0x42, 0x57, 0x59, 0x57, 0x78, 0x70, 0x5A, 0x47, 0x46, 0x30, 0x61, ++ 0x57, 0x39, 0x75, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x77, 0x67, 0x67, 0x49, 0x69, 0x0A, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, ++ 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x43, 0x70, 0x43, 0x51, 0x63, 0x6F, 0x45, 0x77, 0x4B, 0x77, 0x6D, 0x65, 0x42, 0x6B, 0x71, 0x68, 0x35, 0x44, 0x46, 0x6E, 0x70, 0x7A, 0x73, 0x5A, 0x47, 0x67, ++ 0x64, 0x54, 0x36, 0x6F, 0x2B, 0x75, 0x4D, 0x34, 0x41, 0x48, 0x72, 0x73, 0x0A, 0x69, 0x57, 0x6F, 0x67, 0x44, 0x34, 0x76, 0x46, 0x73, 0x4A, 0x73, 0x7A, 0x41, 0x31, 0x71, 0x47, 0x78, 0x6C, 0x69, 0x47, 0x31, 0x63, 0x47, 0x46, 0x75, 0x30, 0x2F, ++ 0x47, 0x6E, 0x45, 0x42, 0x4E, 0x79, 0x72, 0x37, 0x75, 0x61, 0x5A, 0x61, 0x34, 0x72, 0x59, 0x45, 0x77, 0x6D, 0x6E, 0x79, 0x53, 0x42, 0x65, 0x73, 0x46, 0x4B, 0x35, 0x70, 0x49, 0x30, 0x4C, 0x68, 0x32, 0x50, 0x70, 0x62, 0x49, 0x49, 0x4C, 0x76, ++ 0x53, 0x73, 0x50, 0x47, 0x50, 0x32, 0x4B, 0x78, 0x46, 0x0A, 0x52, 0x76, 0x2B, 0x71, 0x5A, 0x32, 0x43, 0x30, 0x64, 0x33, 0x35, 0x71, 0x48, 0x7A, 0x77, 0x61, 0x55, 0x6E, 0x6F, 0x45, 0x50, 0x51, 0x63, 0x38, 0x68, 0x51, 0x32, 0x45, 0x30, 0x42, ++ 0x39, 0x32, 0x43, 0x76, 0x64, 0x71, 0x46, 0x4E, 0x39, 0x79, 0x34, 0x7A, 0x52, 0x38, 0x56, 0x30, 0x35, 0x57, 0x41, 0x54, 0x35, 0x35, 0x38, 0x61, 0x6F, 0x70, 0x4F, 0x32, 0x7A, 0x36, 0x2B, 0x49, 0x39, 0x74, 0x54, 0x63, 0x67, 0x31, 0x33, 0x36, ++ 0x37, 0x72, 0x33, 0x43, 0x54, 0x75, 0x0A, 0x65, 0x55, 0x57, 0x6E, 0x68, 0x62, 0x59, 0x46, 0x69, 0x4E, 0x36, 0x49, 0x58, 0x53, 0x56, 0x38, 0x6C, 0x32, 0x52, 0x6E, 0x43, 0x64, 0x6D, 0x2F, 0x57, 0x68, 0x55, 0x46, 0x68, 0x76, 0x4D, 0x4A, 0x48, ++ 0x75, 0x78, 0x59, 0x4D, 0x6A, 0x4D, 0x52, 0x38, 0x33, 0x64, 0x6B, 0x73, 0x48, 0x59, 0x66, 0x35, 0x42, 0x41, 0x31, 0x46, 0x78, 0x76, 0x79, 0x44, 0x72, 0x46, 0x73, 0x70, 0x43, 0x71, 0x6A, 0x63, 0x2F, 0x77, 0x4A, 0x48, 0x78, 0x34, 0x79, 0x47, ++ 0x56, 0x4D, 0x52, 0x0A, 0x35, 0x39, 0x6D, 0x7A, 0x4C, 0x43, 0x35, 0x32, 0x4C, 0x71, 0x47, 0x6A, 0x33, 0x6E, 0x35, 0x71, 0x69, 0x41, 0x6E, 0x6F, 0x38, 0x67, 0x65, 0x4B, 0x2B, 0x4C, 0x4C, 0x4E, 0x45, 0x4F, 0x66, 0x69, 0x63, 0x30, 0x43, 0x54, ++ 0x75, 0x77, 0x6A, 0x52, 0x50, 0x2B, 0x48, 0x38, 0x43, 0x35, 0x53, 0x7A, 0x4A, 0x65, 0x39, 0x38, 0x70, 0x74, 0x66, 0x52, 0x72, 0x35, 0x2F, 0x2F, 0x6C, 0x70, 0x72, 0x31, 0x6B, 0x58, 0x75, 0x59, 0x43, 0x33, 0x66, 0x55, 0x66, 0x75, 0x67, 0x48, ++ 0x0A, 0x30, 0x6D, 0x4B, 0x31, 0x6C, 0x54, 0x6E, 0x6A, 0x38, 0x2F, 0x46, 0x74, 0x44, 0x77, 0x35, 0x6C, 0x68, 0x49, 0x70, 0x6A, 0x56, 0x4D, 0x57, 0x41, 0x74, 0x75, 0x43, 0x65, 0x53, 0x33, 0x31, 0x48, 0x4A, 0x71, 0x63, 0x42, 0x43, 0x46, 0x33, ++ 0x52, 0x69, 0x4A, 0x37, 0x58, 0x77, 0x7A, 0x4A, 0x45, 0x2B, 0x6F, 0x4A, 0x4B, 0x43, 0x6D, 0x68, 0x55, 0x66, 0x7A, 0x68, 0x54, 0x41, 0x38, 0x79, 0x6B, 0x41, 0x44, 0x4E, 0x6B, 0x55, 0x56, 0x6B, 0x4C, 0x6F, 0x34, 0x4B, 0x52, 0x0A, 0x65, 0x6C, ++ 0x37, 0x73, 0x46, 0x73, 0x4C, 0x7A, 0x4B, 0x75, 0x5A, 0x69, 0x32, 0x69, 0x72, 0x62, 0x57, 0x57, 0x49, 0x51, 0x4A, 0x55, 0x6F, 0x71, 0x67, 0x51, 0x74, 0x48, 0x42, 0x30, 0x4D, 0x47, 0x63, 0x49, 0x66, 0x53, 0x2B, 0x70, 0x4D, 0x52, 0x4B, 0x58, ++ 0x70, 0x49, 0x54, 0x65, 0x75, 0x55, 0x78, 0x33, 0x42, 0x4E, 0x72, 0x32, 0x66, 0x56, 0x55, 0x62, 0x47, 0x41, 0x49, 0x41, 0x45, 0x42, 0x74, 0x48, 0x6F, 0x49, 0x70, 0x70, 0x42, 0x2F, 0x54, 0x75, 0x44, 0x76, 0x0A, 0x42, 0x30, 0x47, 0x48, 0x72, ++ 0x32, 0x71, 0x6C, 0x58, 0x6F, 0x76, 0x37, 0x7A, 0x31, 0x43, 0x79, 0x6D, 0x6C, 0x53, 0x76, 0x77, 0x34, 0x6D, 0x36, 0x57, 0x43, 0x33, 0x31, 0x4D, 0x4A, 0x69, 0x78, 0x4E, 0x6E, 0x49, 0x35, 0x66, 0x6B, 0x6B, 0x45, 0x2F, 0x53, 0x6D, 0x6E, 0x54, ++ 0x48, 0x6E, 0x6B, 0x42, 0x56, 0x66, 0x62, 0x6C, 0x4C, 0x6B, 0x57, 0x55, 0x34, 0x31, 0x47, 0x73, 0x78, 0x32, 0x56, 0x59, 0x56, 0x64, 0x57, 0x66, 0x36, 0x2F, 0x77, 0x46, 0x6C, 0x74, 0x68, 0x0A, 0x57, 0x47, 0x38, 0x32, 0x55, 0x42, 0x45, 0x4C, ++ 0x32, 0x4B, 0x77, 0x72, 0x6C, 0x52, 0x59, 0x61, 0x44, 0x68, 0x38, 0x49, 0x7A, 0x54, 0x59, 0x30, 0x5A, 0x52, 0x42, 0x69, 0x5A, 0x74, 0x57, 0x41, 0x58, 0x78, 0x51, 0x67, 0x58, 0x79, 0x30, 0x4D, 0x6F, 0x48, 0x67, 0x4B, 0x61, 0x4E, 0x59, 0x73, ++ 0x31, 0x2B, 0x6C, 0x76, 0x4B, 0x39, 0x4A, 0x4B, 0x42, 0x5A, 0x50, 0x38, 0x6E, 0x6D, 0x39, 0x72, 0x5A, 0x2F, 0x2B, 0x49, 0x38, 0x55, 0x36, 0x6C, 0x61, 0x55, 0x70, 0x53, 0x0A, 0x4E, 0x77, 0x58, 0x71, 0x78, 0x68, 0x61, 0x4E, 0x30, 0x73, 0x53, ++ 0x5A, 0x30, 0x59, 0x49, 0x72, 0x4F, 0x37, 0x6F, 0x31, 0x64, 0x66, 0x64, 0x52, 0x55, 0x56, 0x6A, 0x7A, 0x79, 0x41, 0x66, 0x64, 0x35, 0x4C, 0x51, 0x44, 0x66, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6F, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, ++ 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x32, 0x58, 0x51, 0x36, 0x35, 0x44, 0x41, 0x39, 0x44, 0x66, 0x63, 0x53, 0x0A, 0x33, 0x48, 0x35, 0x61, 0x42, 0x5A, 0x38, 0x65, 0x4E, 0x4A, 0x72, 0x33, 0x34, 0x52, ++ 0x51, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, ++ 0x4D, 0x43, 0x41, 0x59, 0x59, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x0A, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x42, 0x41, 0x44, 0x61, 0x4E, 0x6C, 0x38, 0x78, 0x43, 0x46, ++ 0x57, 0x51, 0x70, 0x4E, 0x35, 0x73, 0x6D, 0x4C, 0x4E, 0x62, 0x37, 0x72, 0x68, 0x56, 0x70, 0x4C, 0x47, 0x73, 0x61, 0x47, 0x76, 0x64, 0x66, 0x74, 0x76, 0x6B, 0x48, 0x54, 0x46, 0x6E, 0x71, 0x38, 0x38, 0x6E, 0x49, 0x75, 0x61, 0x37, 0x4D, 0x75, ++ 0x69, 0x35, 0x36, 0x33, 0x4D, 0x44, 0x31, 0x73, 0x43, 0x33, 0x41, 0x4F, 0x36, 0x2B, 0x66, 0x63, 0x41, 0x55, 0x52, 0x0A, 0x61, 0x70, 0x38, 0x6C, 0x54, 0x77, 0x45, 0x70, 0x63, 0x4F, 0x50, 0x6C, 0x44, 0x4F, 0x48, 0x71, 0x57, 0x6E, 0x7A, 0x63, ++ 0x53, 0x62, 0x76, 0x42, 0x48, 0x69, 0x71, 0x42, 0x39, 0x52, 0x5A, 0x4C, 0x63, 0x70, 0x48, 0x49, 0x6F, 0x6A, 0x47, 0x35, 0x71, 0x74, 0x72, 0x38, 0x6E, 0x52, 0x2F, 0x7A, 0x58, 0x55, 0x41, 0x43, 0x45, 0x2F, 0x78, 0x4F, 0x48, 0x41, 0x62, 0x4B, ++ 0x73, 0x78, 0x53, 0x51, 0x56, 0x42, 0x63, 0x5A, 0x45, 0x68, 0x72, 0x78, 0x48, 0x39, 0x63, 0x4D, 0x0A, 0x61, 0x56, 0x72, 0x32, 0x63, 0x58, 0x6A, 0x30, 0x6C, 0x48, 0x32, 0x52, 0x43, 0x34, 0x37, 0x73, 0x6B, 0x46, 0x53, 0x4F, 0x76, 0x47, 0x2B, ++ 0x68, 0x54, 0x4B, 0x76, 0x38, 0x64, 0x47, 0x54, 0x39, 0x63, 0x5A, 0x72, 0x34, 0x51, 0x51, 0x65, 0x68, 0x7A, 0x5A, 0x48, 0x6B, 0x50, 0x4A, 0x72, 0x67, 0x6D, 0x7A, 0x49, 0x35, 0x63, 0x36, 0x73, 0x71, 0x31, 0x57, 0x6E, 0x49, 0x65, 0x4A, 0x45, ++ 0x6D, 0x4D, 0x58, 0x33, 0x69, 0x78, 0x7A, 0x44, 0x78, 0x2F, 0x42, 0x52, 0x34, 0x0A, 0x64, 0x78, 0x49, 0x4F, 0x45, 0x2F, 0x54, 0x64, 0x46, 0x70, 0x53, 0x2F, 0x53, 0x32, 0x64, 0x37, 0x63, 0x46, 0x4F, 0x46, 0x79, 0x72, 0x43, 0x37, 0x38, 0x7A, ++ 0x68, 0x4E, 0x4C, 0x4A, 0x41, 0x35, 0x77, 0x41, 0x33, 0x43, 0x58, 0x57, 0x76, 0x70, 0x34, 0x75, 0x58, 0x56, 0x69, 0x49, 0x33, 0x57, 0x4C, 0x4C, 0x2B, 0x72, 0x47, 0x37, 0x36, 0x31, 0x4B, 0x49, 0x63, 0x53, 0x46, 0x33, 0x52, 0x75, 0x2F, 0x48, ++ 0x33, 0x38, 0x6A, 0x39, 0x43, 0x48, 0x4A, 0x72, 0x41, 0x62, 0x0A, 0x2B, 0x37, 0x6C, 0x73, 0x71, 0x2B, 0x4B, 0x65, 0x50, 0x52, 0x58, 0x42, 0x4F, 0x79, 0x35, 0x6E, 0x41, 0x6C, 0x69, 0x52, 0x6E, 0x2B, 0x2F, 0x34, 0x51, 0x68, 0x38, 0x73, 0x74, ++ 0x32, 0x6A, 0x31, 0x64, 0x61, 0x33, 0x50, 0x74, 0x66, 0x62, 0x2F, 0x45, 0x58, 0x33, 0x43, 0x38, 0x43, 0x53, 0x6C, 0x72, 0x64, 0x50, 0x36, 0x6F, 0x44, 0x79, 0x70, 0x2B, 0x6C, 0x33, 0x63, 0x70, 0x61, 0x44, 0x76, 0x52, 0x4B, 0x53, 0x2B, 0x31, ++ 0x75, 0x6A, 0x6C, 0x35, 0x42, 0x4F, 0x57, 0x0A, 0x46, 0x33, 0x73, 0x47, 0x50, 0x6A, 0x4C, 0x74, 0x78, 0x37, 0x64, 0x43, 0x76, 0x48, 0x61, 0x6A, 0x32, 0x47, 0x55, 0x34, 0x4B, 0x7A, 0x67, 0x31, 0x55, 0x53, 0x45, 0x4F, 0x44, 0x6D, 0x38, 0x75, ++ 0x4E, 0x42, 0x4E, 0x41, 0x34, 0x53, 0x74, 0x6E, 0x44, 0x47, 0x31, 0x4B, 0x51, 0x54, 0x41, 0x59, 0x49, 0x31, 0x6F, 0x79, 0x56, 0x5A, 0x6E, 0x4A, 0x46, 0x2B, 0x41, 0x38, 0x33, 0x76, 0x62, 0x73, 0x65, 0x61, 0x30, 0x72, 0x57, 0x42, 0x6D, 0x69, ++ 0x72, 0x53, 0x77, 0x69, 0x0A, 0x47, 0x70, 0x57, 0x4F, 0x76, 0x70, 0x61, 0x51, 0x58, 0x55, 0x4A, 0x58, 0x78, 0x50, 0x6B, 0x55, 0x41, 0x7A, 0x55, 0x72, 0x48, 0x43, 0x31, 0x52, 0x56, 0x77, 0x69, 0x6E, 0x4F, 0x74, 0x34, 0x2F, 0x35, 0x4D, 0x69, ++ 0x30, 0x41, 0x33, 0x50, 0x43, 0x77, 0x53, 0x61, 0x41, 0x75, 0x77, 0x74, 0x43, 0x48, 0x36, 0x30, 0x4E, 0x72, 0x79, 0x5A, 0x79, 0x32, 0x73, 0x79, 0x2B, 0x73, 0x36, 0x4F, 0x44, 0x57, 0x41, 0x32, 0x43, 0x78, 0x52, 0x39, 0x47, 0x55, 0x65, 0x4F, ++ 0x63, 0x0A, 0x47, 0x4D, 0x79, 0x4E, 0x6D, 0x34, 0x33, 0x73, 0x53, 0x65, 0x74, 0x31, 0x55, 0x4E, 0x57, 0x4D, 0x4B, 0x46, 0x6E, 0x4B, 0x64, 0x44, 0x54, 0x61, 0x6A, 0x41, 0x73, 0x68, 0x71, 0x78, 0x37, 0x71, 0x47, 0x2B, 0x58, 0x48, 0x2F, 0x52, ++ 0x55, 0x2B, 0x77, 0x42, 0x65, 0x71, 0x2B, 0x79, 0x4E, 0x75, 0x4A, 0x6B, 0x62, 0x4C, 0x2B, 0x76, 0x6D, 0x78, 0x63, 0x6D, 0x74, 0x70, 0x7A, 0x79, 0x4B, 0x45, 0x43, 0x32, 0x49, 0x50, 0x72, 0x4E, 0x6B, 0x5A, 0x41, 0x4A, 0x53, 0x69, 0x0A, 0x64, ++ 0x6A, 0x7A, 0x55, 0x4C, 0x5A, 0x72, 0x74, 0x42, 0x4A, 0x34, 0x74, 0x42, 0x6D, 0x49, 0x51, 0x4E, 0x31, 0x49, 0x63, 0x68, 0x58, 0x49, 0x62, 0x4A, 0x2B, 0x58, 0x4D, 0x78, 0x6A, 0x48, 0x73, 0x4E, 0x2B, 0x78, 0x6A, 0x57, 0x5A, 0x73, 0x4C, 0x48, ++ 0x58, 0x62, 0x4D, 0x66, 0x6A, 0x4B, 0x61, 0x69, 0x4A, 0x55, 0x49, 0x4E, 0x6C, 0x4B, 0x37, 0x33, 0x6E, 0x5A, 0x66, 0x64, 0x6B, 0x6C, 0x4A, 0x72, 0x58, 0x2B, 0x39, 0x5A, 0x53, 0x43, 0x79, 0x79, 0x63, 0x45, 0x72, 0x0A, 0x64, 0x68, 0x68, 0x32, ++ 0x6E, 0x31, 0x61, 0x78, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x43, 0x65, 0x72, 0x74, 0x69, 0x67, 0x6E, 0x61, ++ 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, ++ 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x47, 0x57, 0x7A, 0x43, 0x43, 0x42, 0x45, 0x4F, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x52, 0x41, 0x4D, 0x72, 0x70, 0x47, 0x34, ++ 0x6E, 0x78, 0x56, 0x51, 0x4D, 0x4E, 0x6F, 0x2B, 0x5A, 0x42, 0x62, 0x63, 0x54, 0x6A, 0x70, 0x75, 0x45, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x77, 0x57, 0x6A, ++ 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0A, 0x42, 0x68, 0x4D, 0x43, 0x52, 0x6C, 0x49, 0x78, 0x45, 0x6A, 0x41, 0x51, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x43, 0x55, 0x52, 0x6F, 0x61, 0x57, 0x31, 0x35, 0x62, ++ 0x33, 0x52, 0x70, 0x63, 0x7A, 0x45, 0x63, 0x4D, 0x42, 0x6F, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x77, 0x77, 0x54, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x69, 0x41, 0x30, 0x4F, 0x44, 0x45, 0x30, 0x4E, 0x6A, 0x4D, 0x77, 0x4F, 0x44, 0x45, 0x77, 0x4D, ++ 0x44, 0x41, 0x7A, 0x4E, 0x6A, 0x45, 0x5A, 0x0A, 0x4D, 0x42, 0x63, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x51, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6C, 0x6E, 0x62, 0x6D, 0x45, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, ++ 0x51, 0x54, 0x41, 0x65, 0x46, 0x77, 0x30, 0x78, 0x4D, 0x7A, 0x45, 0x77, 0x4D, 0x44, 0x45, 0x77, 0x4F, 0x44, 0x4D, 0x79, 0x4D, 0x6A, 0x64, 0x61, 0x46, 0x77, 0x30, 0x7A, 0x4D, 0x7A, 0x45, 0x77, 0x4D, 0x44, 0x45, 0x77, 0x4F, 0x44, 0x4D, 0x79, ++ 0x4D, 0x6A, 0x64, 0x61, 0x0A, 0x4D, 0x46, 0x6F, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x5A, 0x53, 0x4D, 0x52, 0x49, 0x77, 0x45, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x44, 0x41, 0x6C, ++ 0x45, 0x61, 0x47, 0x6C, 0x74, 0x65, 0x57, 0x39, 0x30, 0x61, 0x58, 0x4D, 0x78, 0x48, 0x44, 0x41, 0x61, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x73, 0x4D, 0x45, 0x7A, 0x41, 0x77, 0x4D, 0x44, 0x49, 0x67, 0x4E, 0x44, 0x67, 0x78, 0x4E, 0x44, 0x59, ++ 0x7A, 0x0A, 0x4D, 0x44, 0x67, 0x78, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x7A, 0x59, 0x78, 0x47, 0x54, 0x41, 0x58, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x45, 0x45, 0x4E, 0x6C, 0x63, 0x6E, 0x52, 0x70, 0x5A, 0x32, 0x35, 0x68, 0x49, 0x46, ++ 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x77, 0x67, 0x67, 0x49, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x0A, 0x44, ++ 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x44, 0x4E, 0x47, 0x44, 0x6C, 0x6C, 0x47, 0x6C, 0x6D, 0x78, 0x36, 0x6D, 0x51, 0x57, 0x44, 0x6F, 0x79, 0x55, 0x4A, 0x4A, 0x56, 0x38, 0x67, 0x39, 0x50, 0x46, 0x4F, ++ 0x53, 0x62, 0x63, 0x44, 0x4F, 0x38, 0x57, 0x56, 0x34, 0x33, 0x58, 0x32, 0x4B, 0x79, 0x6A, 0x51, 0x6E, 0x2B, 0x43, 0x79, 0x75, 0x33, 0x4E, 0x57, 0x39, 0x73, 0x4F, 0x74, 0x79, 0x33, 0x74, 0x52, 0x51, 0x67, 0x58, 0x0A, 0x73, 0x74, 0x6D, 0x7A, ++ 0x79, 0x39, 0x59, 0x58, 0x55, 0x6E, 0x49, 0x6F, 0x32, 0x34, 0x35, 0x4F, 0x6E, 0x6F, 0x71, 0x32, 0x43, 0x2F, 0x6D, 0x65, 0x68, 0x4A, 0x70, 0x4E, 0x64, 0x74, 0x34, 0x69, 0x4B, 0x56, 0x7A, 0x53, 0x73, 0x39, 0x49, 0x47, 0x50, 0x6A, 0x41, 0x35, ++ 0x71, 0x58, 0x53, 0x6A, 0x6B, 0x6C, 0x59, 0x63, 0x6F, 0x57, 0x39, 0x4D, 0x43, 0x69, 0x42, 0x74, 0x6E, 0x79, 0x4E, 0x36, 0x74, 0x4D, 0x62, 0x61, 0x4C, 0x4F, 0x51, 0x64, 0x4C, 0x4E, 0x79, 0x7A, 0x0A, 0x4B, 0x4E, 0x41, 0x54, 0x38, 0x6B, 0x78, ++ 0x4F, 0x41, 0x6B, 0x6D, 0x68, 0x56, 0x45, 0x43, 0x65, 0x35, 0x75, 0x55, 0x46, 0x6F, 0x43, 0x32, 0x45, 0x79, 0x50, 0x2B, 0x59, 0x62, 0x4E, 0x44, 0x72, 0x69, 0x68, 0x71, 0x45, 0x43, 0x42, 0x36, 0x33, 0x61, 0x43, 0x50, 0x75, 0x49, 0x39, 0x56, ++ 0x77, 0x7A, 0x6D, 0x31, 0x52, 0x61, 0x52, 0x44, 0x75, 0x6F, 0x58, 0x72, 0x43, 0x30, 0x53, 0x49, 0x78, 0x77, 0x6F, 0x4B, 0x46, 0x30, 0x76, 0x4A, 0x56, 0x64, 0x6C, 0x42, 0x38, 0x0A, 0x4A, 0x58, 0x72, 0x4A, 0x68, 0x46, 0x77, 0x4C, 0x72, 0x4E, ++ 0x31, 0x43, 0x54, 0x69, 0x76, 0x6E, 0x67, 0x71, 0x49, 0x6B, 0x69, 0x63, 0x75, 0x51, 0x73, 0x74, 0x44, 0x75, 0x49, 0x37, 0x70, 0x6D, 0x54, 0x4C, 0x74, 0x69, 0x70, 0x50, 0x6C, 0x54, 0x57, 0x6D, 0x52, 0x37, 0x66, 0x4A, 0x6A, 0x36, 0x6F, 0x30, ++ 0x69, 0x65, 0x44, 0x35, 0x57, 0x75, 0x70, 0x78, 0x6A, 0x30, 0x61, 0x75, 0x77, 0x75, 0x41, 0x30, 0x57, 0x76, 0x38, 0x48, 0x54, 0x34, 0x4B, 0x73, 0x31, 0x36, 0x0A, 0x58, 0x64, 0x47, 0x2B, 0x52, 0x43, 0x59, 0x79, 0x4B, 0x66, 0x48, 0x78, 0x39, ++ 0x57, 0x7A, 0x4D, 0x66, 0x67, 0x49, 0x68, 0x43, 0x35, 0x39, 0x76, 0x70, 0x44, 0x2B, 0x2B, 0x6E, 0x56, 0x50, 0x69, 0x7A, 0x33, 0x32, 0x70, 0x4C, 0x48, 0x78, 0x59, 0x47, 0x70, 0x66, 0x68, 0x50, 0x54, 0x63, 0x33, 0x47, 0x47, 0x59, 0x6F, 0x30, ++ 0x6B, 0x44, 0x46, 0x55, 0x59, 0x71, 0x4D, 0x77, 0x79, 0x33, 0x4F, 0x55, 0x34, 0x67, 0x6B, 0x57, 0x47, 0x51, 0x77, 0x46, 0x73, 0x57, 0x71, 0x0A, 0x34, 0x4E, 0x59, 0x4B, 0x70, 0x6B, 0x44, 0x66, 0x65, 0x50, 0x62, 0x31, 0x42, 0x48, 0x78, 0x70, ++ 0x45, 0x34, 0x53, 0x38, 0x30, 0x64, 0x47, 0x6E, 0x42, 0x73, 0x38, 0x42, 0x39, 0x32, 0x6A, 0x41, 0x71, 0x46, 0x65, 0x37, 0x4F, 0x6D, 0x47, 0x74, 0x42, 0x49, 0x79, 0x54, 0x34, 0x36, 0x33, 0x38, 0x38, 0x4E, 0x74, 0x45, 0x62, 0x56, 0x6E, 0x63, ++ 0x53, 0x56, 0x6D, 0x75, 0x72, 0x4A, 0x71, 0x5A, 0x4E, 0x6A, 0x42, 0x42, 0x65, 0x33, 0x59, 0x7A, 0x49, 0x6F, 0x65, 0x6A, 0x0A, 0x77, 0x70, 0x4B, 0x47, 0x62, 0x76, 0x6C, 0x77, 0x37, 0x71, 0x36, 0x48, 0x68, 0x35, 0x55, 0x62, 0x78, 0x48, 0x71, ++ 0x39, 0x4D, 0x66, 0x50, 0x55, 0x30, 0x75, 0x57, 0x5A, 0x2F, 0x37, 0x35, 0x49, 0x37, 0x48, 0x58, 0x31, 0x65, 0x42, 0x59, 0x64, 0x70, 0x6E, 0x44, 0x42, 0x66, 0x7A, 0x77, 0x62, 0x6F, 0x5A, 0x4C, 0x37, 0x7A, 0x38, 0x67, 0x38, 0x31, 0x73, 0x57, ++ 0x54, 0x43, 0x6F, 0x2F, 0x31, 0x56, 0x54, 0x70, 0x32, 0x6C, 0x63, 0x35, 0x5A, 0x6D, 0x49, 0x6F, 0x4A, 0x0A, 0x6C, 0x58, 0x63, 0x79, 0x6D, 0x6F, 0x4F, 0x36, 0x4C, 0x41, 0x51, 0x36, 0x6C, 0x37, 0x33, 0x55, 0x4C, 0x37, 0x37, 0x58, 0x62, 0x4A, ++ 0x75, 0x69, 0x79, 0x6E, 0x31, 0x74, 0x4A, 0x73, 0x6C, 0x56, 0x31, 0x63, 0x2F, 0x44, 0x65, 0x56, 0x49, 0x49, 0x43, 0x5A, 0x6B, 0x48, 0x4A, 0x43, 0x31, 0x6B, 0x4A, 0x57, 0x75, 0x6D, 0x49, 0x57, 0x6D, 0x62, 0x61, 0x74, 0x31, 0x30, 0x54, 0x57, ++ 0x75, 0x58, 0x65, 0x6B, 0x47, 0x39, 0x71, 0x78, 0x66, 0x35, 0x6B, 0x42, 0x64, 0x49, 0x0A, 0x6A, 0x7A, 0x62, 0x35, 0x4C, 0x64, 0x58, 0x46, 0x32, 0x2B, 0x36, 0x71, 0x68, 0x55, 0x56, 0x42, 0x2B, 0x73, 0x30, 0x36, 0x52, 0x62, 0x46, 0x6F, 0x35, ++ 0x6A, 0x5A, 0x4D, 0x6D, 0x35, 0x42, 0x58, 0x37, 0x43, 0x4F, 0x35, 0x68, 0x77, 0x6A, 0x43, 0x78, 0x41, 0x6E, 0x78, 0x6C, 0x34, 0x59, 0x71, 0x4B, 0x45, 0x33, 0x69, 0x64, 0x4D, 0x44, 0x61, 0x78, 0x49, 0x7A, 0x62, 0x33, 0x2B, 0x4B, 0x68, 0x46, ++ 0x31, 0x6E, 0x4F, 0x4A, 0x46, 0x6C, 0x30, 0x4D, 0x64, 0x70, 0x2F, 0x0A, 0x2F, 0x54, 0x42, 0x74, 0x32, 0x64, 0x7A, 0x68, 0x61, 0x75, 0x48, 0x38, 0x58, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6F, 0x34, 0x49, 0x42, 0x47, 0x6A, 0x43, 0x43, ++ 0x41, 0x52, 0x59, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, ++ 0x42, 0x41, 0x4D, 0x43, 0x41, 0x51, 0x59, 0x77, 0x0A, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x46, 0x42, 0x69, 0x48, 0x56, 0x75, 0x42, 0x75, 0x64, 0x2B, 0x34, 0x6B, 0x4E, 0x54, 0x78, 0x4F, 0x63, 0x35, 0x6F, ++ 0x66, 0x31, 0x75, 0x48, 0x69, 0x65, 0x58, 0x34, 0x72, 0x4D, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x49, 0x77, 0x51, 0x59, 0x4D, 0x42, 0x61, 0x41, 0x46, 0x42, 0x69, 0x48, 0x56, 0x75, 0x42, 0x75, 0x64, 0x2B, 0x34, 0x6B, 0x4E, 0x54, 0x78, ++ 0x4F, 0x63, 0x35, 0x6F, 0x66, 0x0A, 0x31, 0x75, 0x48, 0x69, 0x65, 0x58, 0x34, 0x72, 0x4D, 0x45, 0x51, 0x47, 0x41, 0x31, 0x55, 0x64, 0x49, 0x41, 0x51, 0x39, 0x4D, 0x44, 0x73, 0x77, 0x4F, 0x51, 0x59, 0x45, 0x56, 0x52, 0x30, 0x67, 0x41, 0x44, ++ 0x41, 0x78, 0x4D, 0x43, 0x38, 0x47, 0x43, 0x43, 0x73, 0x47, 0x41, 0x51, 0x55, 0x46, 0x42, 0x77, 0x49, 0x42, 0x46, 0x69, 0x4E, 0x6F, 0x64, 0x48, 0x52, 0x77, 0x63, 0x7A, 0x6F, 0x76, 0x4C, 0x33, 0x64, 0x33, 0x64, 0x33, 0x63, 0x75, 0x59, 0x32, ++ 0x56, 0x79, 0x0A, 0x64, 0x47, 0x6C, 0x6E, 0x62, 0x6D, 0x45, 0x75, 0x5A, 0x6E, 0x49, 0x76, 0x59, 0x58, 0x56, 0x30, 0x62, 0x33, 0x4A, 0x70, 0x64, 0x47, 0x56, 0x7A, 0x4C, 0x7A, 0x42, 0x74, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x38, 0x45, 0x5A, ++ 0x6A, 0x42, 0x6B, 0x4D, 0x43, 0x2B, 0x67, 0x4C, 0x61, 0x41, 0x72, 0x68, 0x69, 0x6C, 0x6F, 0x64, 0x48, 0x52, 0x77, 0x4F, 0x69, 0x38, 0x76, 0x59, 0x33, 0x4A, 0x73, 0x4C, 0x6D, 0x4E, 0x6C, 0x63, 0x6E, 0x52, 0x70, 0x5A, 0x32, 0x35, 0x68, 0x0A, ++ 0x4C, 0x6D, 0x5A, 0x79, 0x4C, 0x32, 0x4E, 0x6C, 0x63, 0x6E, 0x52, 0x70, 0x5A, 0x32, 0x35, 0x68, 0x63, 0x6D, 0x39, 0x76, 0x64, 0x47, 0x4E, 0x68, 0x4C, 0x6D, 0x4E, 0x79, 0x62, 0x44, 0x41, 0x78, 0x6F, 0x43, 0x2B, 0x67, 0x4C, 0x59, 0x59, 0x72, ++ 0x61, 0x48, 0x52, 0x30, 0x63, 0x44, 0x6F, 0x76, 0x4C, 0x32, 0x4E, 0x79, 0x62, 0x43, 0x35, 0x6B, 0x61, 0x47, 0x6C, 0x74, 0x65, 0x57, 0x39, 0x30, 0x61, 0x58, 0x4D, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4C, 0x32, 0x4E, 0x6C, 0x0A, 0x63, 0x6E, 0x52, ++ 0x70, 0x5A, 0x32, 0x35, 0x68, 0x63, 0x6D, 0x39, 0x76, 0x64, 0x47, 0x4E, 0x68, 0x4C, 0x6D, 0x4E, 0x79, 0x62, 0x44, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x41, 0x4F, ++ 0x43, 0x41, 0x67, 0x45, 0x41, 0x6C, 0x4C, 0x69, 0x65, 0x54, 0x2F, 0x44, 0x6A, 0x6C, 0x51, 0x67, 0x69, 0x35, 0x38, 0x31, 0x6F, 0x51, 0x66, 0x63, 0x63, 0x56, 0x64, 0x56, 0x38, 0x41, 0x4F, 0x49, 0x74, 0x0A, 0x4F, 0x6F, 0x6C, 0x64, 0x61, 0x44, ++ 0x67, 0x76, 0x55, 0x53, 0x49, 0x4C, 0x53, 0x6F, 0x33, 0x4C, 0x36, 0x62, 0x74, 0x64, 0x50, 0x72, 0x74, 0x63, 0x50, 0x62, 0x45, 0x6F, 0x2F, 0x75, 0x52, 0x54, 0x56, 0x52, 0x50, 0x50, 0x6F, 0x5A, 0x41, 0x62, 0x41, 0x68, 0x31, 0x66, 0x5A, 0x6B, ++ 0x59, 0x4A, 0x4D, 0x79, 0x6A, 0x68, 0x44, 0x53, 0x53, 0x58, 0x63, 0x4E, 0x4D, 0x51, 0x48, 0x2B, 0x70, 0x6B, 0x56, 0x35, 0x61, 0x37, 0x58, 0x64, 0x72, 0x6E, 0x78, 0x49, 0x78, 0x50, 0x0A, 0x54, 0x47, 0x52, 0x47, 0x48, 0x56, 0x79, 0x48, 0x34, ++ 0x31, 0x6E, 0x65, 0x51, 0x74, 0x47, 0x62, 0x71, 0x48, 0x36, 0x6D, 0x69, 0x64, 0x32, 0x50, 0x48, 0x4D, 0x6B, 0x77, 0x67, 0x75, 0x30, 0x37, 0x6E, 0x4D, 0x33, 0x41, 0x36, 0x52, 0x6E, 0x67, 0x61, 0x74, 0x67, 0x43, 0x64, 0x54, 0x65, 0x72, 0x39, ++ 0x7A, 0x51, 0x6F, 0x4B, 0x4A, 0x48, 0x79, 0x42, 0x41, 0x70, 0x50, 0x4E, 0x65, 0x4E, 0x67, 0x4A, 0x67, 0x48, 0x36, 0x30, 0x42, 0x47, 0x4D, 0x2B, 0x52, 0x46, 0x71, 0x0A, 0x37, 0x71, 0x38, 0x39, 0x77, 0x31, 0x44, 0x54, 0x6A, 0x31, 0x38, 0x7A, ++ 0x65, 0x54, 0x79, 0x47, 0x71, 0x48, 0x4E, 0x46, 0x6B, 0x49, 0x77, 0x67, 0x74, 0x6E, 0x4A, 0x7A, 0x46, 0x79, 0x4F, 0x2B, 0x42, 0x32, 0x58, 0x6C, 0x65, 0x4A, 0x49, 0x4E, 0x75, 0x67, 0x48, 0x41, 0x36, 0x34, 0x77, 0x63, 0x5A, 0x72, 0x2B, 0x73, ++ 0x68, 0x6E, 0x63, 0x42, 0x6C, 0x41, 0x32, 0x63, 0x35, 0x75, 0x6B, 0x35, 0x6A, 0x52, 0x2B, 0x6D, 0x55, 0x59, 0x79, 0x5A, 0x44, 0x44, 0x6C, 0x33, 0x0A, 0x34, 0x62, 0x53, 0x62, 0x2B, 0x68, 0x78, 0x6E, 0x56, 0x32, 0x39, 0x71, 0x61, 0x6F, 0x36, ++ 0x70, 0x4B, 0x30, 0x78, 0x58, 0x65, 0x58, 0x70, 0x58, 0x49, 0x73, 0x2F, 0x4E, 0x58, 0x32, 0x4E, 0x47, 0x6A, 0x56, 0x78, 0x5A, 0x4F, 0x6F, 0x62, 0x34, 0x4D, 0x6B, 0x64, 0x69, 0x6F, 0x32, 0x63, 0x4E, 0x47, 0x4A, 0x48, 0x63, 0x2B, 0x36, 0x5A, ++ 0x72, 0x39, 0x55, 0x68, 0x68, 0x63, 0x79, 0x4E, 0x5A, 0x6A, 0x67, 0x4B, 0x6E, 0x76, 0x45, 0x54, 0x71, 0x39, 0x45, 0x6D, 0x64, 0x0A, 0x38, 0x56, 0x52, 0x59, 0x2B, 0x57, 0x43, 0x76, 0x32, 0x68, 0x69, 0x6B, 0x4C, 0x79, 0x68, 0x46, 0x33, 0x48, ++ 0x71, 0x67, 0x69, 0x49, 0x5A, 0x64, 0x38, 0x7A, 0x76, 0x6E, 0x2F, 0x79, 0x6B, 0x31, 0x67, 0x50, 0x78, 0x6B, 0x51, 0x35, 0x54, 0x6D, 0x34, 0x78, 0x78, 0x76, 0x76, 0x71, 0x30, 0x4F, 0x4B, 0x6D, 0x4F, 0x5A, 0x4B, 0x38, 0x6C, 0x2B, 0x68, 0x66, ++ 0x5A, 0x78, 0x36, 0x41, 0x59, 0x44, 0x6C, 0x66, 0x37, 0x65, 0x6A, 0x30, 0x67, 0x63, 0x57, 0x74, 0x53, 0x53, 0x0A, 0x36, 0x43, 0x76, 0x75, 0x35, 0x7A, 0x48, 0x62, 0x75, 0x67, 0x52, 0x71, 0x68, 0x35, 0x6A, 0x6E, 0x78, 0x56, 0x2F, 0x76, 0x66, ++ 0x61, 0x63, 0x69, 0x39, 0x77, 0x48, 0x59, 0x54, 0x66, 0x6D, 0x4A, 0x30, 0x41, 0x36, 0x61, 0x42, 0x56, 0x6D, 0x6B, 0x6E, 0x70, 0x6A, 0x5A, 0x62, 0x79, 0x76, 0x4B, 0x63, 0x4C, 0x35, 0x6B, 0x77, 0x6C, 0x57, 0x6A, 0x39, 0x4F, 0x6D, 0x76, 0x77, ++ 0x35, 0x49, 0x70, 0x33, 0x49, 0x67, 0x57, 0x4A, 0x4A, 0x6B, 0x38, 0x6A, 0x53, 0x61, 0x59, 0x0A, 0x74, 0x6C, 0x75, 0x33, 0x7A, 0x4D, 0x36, 0x33, 0x4E, 0x77, 0x66, 0x39, 0x4A, 0x74, 0x6D, 0x59, 0x68, 0x53, 0x54, 0x2F, 0x57, 0x53, 0x4D, 0x44, ++ 0x6D, 0x75, 0x32, 0x64, 0x6E, 0x61, 0x6A, 0x6B, 0x58, 0x6A, 0x6A, 0x4F, 0x31, 0x31, 0x49, 0x4E, 0x62, 0x39, 0x49, 0x2F, 0x62, 0x62, 0x45, 0x46, 0x61, 0x30, 0x6E, 0x4F, 0x69, 0x70, 0x46, 0x47, 0x63, 0x2F, 0x54, 0x32, 0x4C, 0x2F, 0x43, 0x6F, ++ 0x63, 0x33, 0x63, 0x4F, 0x5A, 0x61, 0x79, 0x68, 0x6A, 0x57, 0x5A, 0x53, 0x0A, 0x61, 0x58, 0x35, 0x4C, 0x61, 0x41, 0x7A, 0x48, 0x48, 0x6A, 0x63, 0x6E, 0x67, 0x36, 0x57, 0x4D, 0x78, 0x77, 0x4C, 0x6B, 0x46, 0x4D, 0x31, 0x4A, 0x41, 0x62, 0x42, ++ 0x7A, 0x73, 0x2F, 0x33, 0x47, 0x6B, 0x44, 0x70, 0x76, 0x30, 0x6D, 0x7A, 0x74, 0x4F, 0x2B, 0x37, 0x73, 0x6B, 0x62, 0x36, 0x69, 0x51, 0x31, 0x32, 0x4C, 0x41, 0x45, 0x70, 0x6D, 0x4A, 0x55, 0x52, 0x77, 0x33, 0x6B, 0x41, 0x50, 0x2B, 0x48, 0x77, ++ 0x56, 0x39, 0x36, 0x4C, 0x4F, 0x50, 0x4E, 0x64, 0x65, 0x0A, 0x45, 0x34, 0x79, 0x42, 0x46, 0x78, 0x67, 0x58, 0x30, 0x62, 0x33, 0x78, 0x64, 0x78, 0x41, 0x36, 0x31, 0x47, 0x55, 0x35, 0x77, 0x53, 0x65, 0x73, 0x56, 0x79, 0x77, 0x6C, 0x56, 0x50, ++ 0x2B, 0x69, 0x32, 0x6B, 0x2B, 0x4B, 0x59, 0x54, 0x6C, 0x65, 0x72, 0x6A, 0x31, 0x4B, 0x6A, 0x4C, 0x30, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, ++ 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x31, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x44, 0x6C, 0x44, ++ 0x43, 0x43, 0x41, 0x6E, 0x79, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x4B, 0x4D, 0x66, 0x58, 0x6B, 0x59, 0x67, 0x78, 0x73, 0x57, 0x4F, 0x33, 0x57, 0x32, 0x44, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, ++ 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x42, 0x6E, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x4A, 0x54, 0x6A, 0x45, 0x54, 0x0A, 0x4D, 0x42, 0x45, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, ++ 0x78, 0x4D, 0x4B, 0x5A, 0x57, 0x31, 0x54, 0x61, 0x57, 0x64, 0x75, 0x49, 0x46, 0x42, 0x4C, 0x53, 0x54, 0x45, 0x6C, 0x4D, 0x43, 0x4D, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x63, 0x5A, 0x55, 0x31, 0x31, 0x5A, 0x47, 0x68, 0x79, 0x59, ++ 0x53, 0x42, 0x55, 0x5A, 0x57, 0x4E, 0x6F, 0x62, 0x6D, 0x39, 0x73, 0x62, 0x32, 0x64, 0x70, 0x5A, 0x58, 0x4D, 0x67, 0x54, 0x47, 0x6C, 0x74, 0x61, 0x58, 0x52, 0x6C, 0x0A, 0x5A, 0x44, 0x45, 0x63, 0x4D, 0x42, 0x6F, 0x47, 0x41, 0x31, 0x55, 0x45, ++ 0x41, 0x78, 0x4D, 0x54, 0x5A, 0x57, 0x31, 0x54, 0x61, 0x57, 0x64, 0x75, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x4C, 0x53, 0x42, 0x48, 0x4D, 0x54, 0x41, 0x65, 0x46, 0x77, 0x30, 0x78, 0x4F, 0x44, 0x41, 0x79, ++ 0x4D, 0x54, 0x67, 0x78, 0x4F, 0x44, 0x4D, 0x77, 0x4D, 0x44, 0x42, 0x61, 0x46, 0x77, 0x30, 0x30, 0x4D, 0x7A, 0x41, 0x79, 0x4D, 0x54, 0x67, 0x78, 0x0A, 0x4F, 0x44, 0x4D, 0x77, 0x4D, 0x44, 0x42, 0x61, 0x4D, 0x47, 0x63, 0x78, 0x43, 0x7A, 0x41, ++ 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x6C, 0x4F, 0x4D, 0x52, 0x4D, 0x77, 0x45, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, 0x45, 0x77, 0x70, 0x6C, 0x62, 0x56, 0x4E, 0x70, 0x5A, 0x32, 0x34, 0x67, 0x55, 0x45, 0x74, ++ 0x4A, 0x4D, 0x53, 0x55, 0x77, 0x49, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x78, 0x78, 0x6C, 0x54, 0x58, 0x56, 0x6B, 0x0A, 0x61, 0x48, 0x4A, 0x68, 0x49, 0x46, 0x52, 0x6C, 0x59, 0x32, 0x68, 0x75, 0x62, 0x32, 0x78, 0x76, 0x5A, 0x32, ++ 0x6C, 0x6C, 0x63, 0x79, 0x42, 0x4D, 0x61, 0x57, 0x31, 0x70, 0x64, 0x47, 0x56, 0x6B, 0x4D, 0x52, 0x77, 0x77, 0x47, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x4E, 0x6C, 0x62, 0x56, 0x4E, 0x70, 0x5A, 0x32, 0x34, 0x67, 0x55, 0x6D, ++ 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x53, 0x41, 0x74, 0x49, 0x45, 0x63, 0x78, 0x4D, 0x49, 0x49, 0x42, 0x0A, 0x49, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, ++ 0x41, 0x4F, 0x43, 0x41, 0x51, 0x38, 0x41, 0x4D, 0x49, 0x49, 0x42, 0x43, 0x67, 0x4B, 0x43, 0x41, 0x51, 0x45, 0x41, 0x6B, 0x30, 0x75, 0x37, 0x36, 0x57, 0x61, 0x4B, 0x37, 0x70, 0x31, 0x62, 0x31, 0x54, 0x53, 0x54, 0x30, 0x42, 0x73, 0x65, 0x77, ++ 0x2B, 0x65, 0x65, 0x75, 0x47, 0x51, 0x7A, 0x66, 0x32, 0x4E, 0x34, 0x61, 0x4C, 0x54, 0x4E, 0x0A, 0x4C, 0x6E, 0x46, 0x31, 0x31, 0x35, 0x73, 0x67, 0x78, 0x6B, 0x30, 0x70, 0x76, 0x4C, 0x5A, 0x6F, 0x59, 0x49, 0x72, 0x33, 0x49, 0x5A, 0x70, 0x57, ++ 0x4E, 0x56, 0x72, 0x7A, 0x64, 0x72, 0x33, 0x59, 0x7A, 0x5A, 0x72, 0x2F, 0x6B, 0x31, 0x5A, 0x4C, 0x70, 0x56, 0x6B, 0x47, 0x6F, 0x5A, 0x4D, 0x30, 0x4B, 0x64, 0x30, 0x57, 0x4E, 0x48, 0x56, 0x4F, 0x38, 0x6F, 0x47, 0x30, 0x78, 0x35, 0x5A, 0x4F, ++ 0x72, 0x52, 0x6B, 0x56, 0x55, 0x6B, 0x72, 0x2B, 0x50, 0x48, 0x42, 0x31, 0x0A, 0x63, 0x4D, 0x32, 0x76, 0x4B, 0x36, 0x73, 0x56, 0x6D, 0x6A, 0x4D, 0x38, 0x71, 0x72, 0x4F, 0x4C, 0x71, 0x73, 0x31, 0x44, 0x2F, 0x66, 0x58, 0x71, 0x63, 0x50, 0x2F, ++ 0x74, 0x7A, 0x78, 0x45, 0x37, 0x6C, 0x4D, 0x35, 0x4F, 0x4D, 0x68, 0x62, 0x54, 0x49, 0x30, 0x41, 0x71, 0x64, 0x37, 0x4F, 0x76, 0x50, 0x41, 0x45, 0x73, 0x62, 0x4F, 0x32, 0x5A, 0x4C, 0x49, 0x76, 0x5A, 0x54, 0x6D, 0x6D, 0x59, 0x73, 0x76, 0x65, ++ 0x50, 0x51, 0x62, 0x41, 0x79, 0x65, 0x47, 0x48, 0x57, 0x0A, 0x44, 0x56, 0x2F, 0x44, 0x2B, 0x71, 0x4A, 0x41, 0x6B, 0x68, 0x31, 0x63, 0x46, 0x2B, 0x5A, 0x77, 0x50, 0x6A, 0x58, 0x6E, 0x6F, 0x72, 0x66, 0x43, 0x59, 0x75, 0x4B, 0x72, 0x70, 0x44, ++ 0x68, 0x4D, 0x74, 0x54, 0x6B, 0x31, 0x62, 0x2B, 0x6F, 0x44, 0x61, 0x66, 0x6F, 0x36, 0x56, 0x47, 0x69, 0x46, 0x62, 0x64, 0x62, 0x79, 0x4C, 0x30, 0x4E, 0x56, 0x48, 0x70, 0x45, 0x4E, 0x44, 0x74, 0x6A, 0x56, 0x61, 0x71, 0x53, 0x57, 0x30, 0x52, ++ 0x4D, 0x38, 0x4C, 0x48, 0x68, 0x51, 0x0A, 0x36, 0x44, 0x71, 0x53, 0x30, 0x68, 0x64, 0x57, 0x35, 0x54, 0x55, 0x61, 0x51, 0x42, 0x77, 0x2B, 0x6A, 0x53, 0x7A, 0x74, 0x4F, 0x64, 0x39, 0x43, 0x34, 0x49, 0x4E, 0x42, 0x64, 0x4E, 0x2B, 0x6A, 0x7A, ++ 0x63, 0x4B, 0x47, 0x59, 0x45, 0x68, 0x6F, 0x34, 0x32, 0x6B, 0x4C, 0x56, 0x41, 0x43, 0x4C, 0x35, 0x48, 0x5A, 0x70, 0x49, 0x51, 0x31, 0x35, 0x54, 0x6A, 0x51, 0x49, 0x58, 0x68, 0x54, 0x43, 0x7A, 0x4C, 0x47, 0x33, 0x72, 0x64, 0x64, 0x38, 0x63, ++ 0x49, 0x72, 0x48, 0x0A, 0x68, 0x51, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6F, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x2B, 0x2B, 0x38, 0x4E, 0x68, 0x70, 0x36, 0x77, ++ 0x34, 0x39, 0x32, 0x70, 0x75, 0x66, 0x45, 0x68, 0x46, 0x33, 0x38, 0x2B, 0x2F, 0x50, 0x42, 0x33, 0x4B, 0x78, 0x6F, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, ++ 0x0A, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, ++ 0x4C, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x42, 0x41, 0x46, 0x6E, 0x2F, 0x38, 0x6F, 0x7A, 0x31, 0x68, 0x33, 0x31, 0x78, 0x50, 0x61, 0x4F, 0x66, 0x47, 0x31, 0x76, 0x52, 0x32, 0x76, 0x6A, 0x54, 0x6E, 0x47, 0x73, 0x32, 0x0A, 0x76, 0x5A, ++ 0x75, 0x70, 0x59, 0x65, 0x76, 0x65, 0x46, 0x69, 0x78, 0x30, 0x50, 0x5A, 0x37, 0x6D, 0x64, 0x64, 0x72, 0x58, 0x75, 0x71, 0x65, 0x38, 0x51, 0x68, 0x66, 0x6E, 0x50, 0x5A, 0x48, 0x72, 0x35, 0x58, 0x33, 0x64, 0x50, 0x70, 0x7A, 0x78, 0x7A, 0x35, ++ 0x4B, 0x73, 0x62, 0x45, 0x6A, 0x4D, 0x77, 0x69, 0x49, 0x2F, 0x61, 0x54, 0x76, 0x46, 0x74, 0x68, 0x55, 0x76, 0x6F, 0x7A, 0x58, 0x47, 0x61, 0x43, 0x6F, 0x63, 0x56, 0x36, 0x38, 0x35, 0x37, 0x34, 0x33, 0x51, 0x0A, 0x4E, 0x63, 0x4D, 0x59, 0x44, ++ 0x48, 0x73, 0x41, 0x56, 0x68, 0x7A, 0x4E, 0x69, 0x78, 0x6C, 0x30, 0x33, 0x72, 0x34, 0x50, 0x45, 0x75, 0x44, 0x51, 0x71, 0x71, 0x45, 0x2F, 0x41, 0x6A, 0x53, 0x78, 0x63, 0x4D, 0x36, 0x64, 0x47, 0x4E, 0x59, 0x49, 0x41, 0x77, 0x6C, 0x47, 0x37, ++ 0x6D, 0x44, 0x67, 0x66, 0x72, 0x62, 0x45, 0x53, 0x51, 0x52, 0x52, 0x66, 0x58, 0x42, 0x67, 0x76, 0x4B, 0x71, 0x79, 0x2F, 0x33, 0x6C, 0x79, 0x65, 0x71, 0x59, 0x64, 0x50, 0x56, 0x38, 0x71, 0x0A, 0x2B, 0x4D, 0x72, 0x69, 0x2F, 0x54, 0x6D, 0x33, ++ 0x52, 0x37, 0x6E, 0x72, 0x66, 0x74, 0x38, 0x45, 0x49, 0x36, 0x2F, 0x36, 0x6E, 0x41, 0x59, 0x48, 0x36, 0x66, 0x74, 0x6A, 0x6B, 0x34, 0x42, 0x41, 0x74, 0x63, 0x5A, 0x73, 0x43, 0x6A, 0x45, 0x6F, 0x7A, 0x67, 0x79, 0x66, 0x7A, 0x37, 0x4D, 0x6A, ++ 0x4E, 0x59, 0x42, 0x42, 0x6A, 0x57, 0x7A, 0x45, 0x4E, 0x33, 0x75, 0x42, 0x4C, 0x34, 0x43, 0x68, 0x51, 0x45, 0x4B, 0x46, 0x36, 0x64, 0x6B, 0x34, 0x6A, 0x65, 0x69, 0x68, 0x0A, 0x55, 0x38, 0x30, 0x42, 0x76, 0x32, 0x6E, 0x6F, 0x57, 0x67, 0x62, ++ 0x79, 0x52, 0x51, 0x75, 0x51, 0x2B, 0x71, 0x37, 0x68, 0x76, 0x35, 0x33, 0x79, 0x72, 0x6C, 0x63, 0x38, 0x70, 0x61, 0x36, 0x79, 0x56, 0x76, 0x53, 0x4C, 0x5A, 0x55, 0x44, 0x70, 0x2F, 0x54, 0x47, 0x42, 0x4C, 0x50, 0x51, 0x35, 0x43, 0x64, 0x6A, ++ 0x75, 0x61, 0x36, 0x65, 0x30, 0x70, 0x68, 0x30, 0x56, 0x70, 0x5A, 0x6A, 0x33, 0x41, 0x59, 0x48, 0x59, 0x68, 0x58, 0x33, 0x7A, 0x55, 0x56, 0x78, 0x78, 0x0A, 0x69, 0x4E, 0x36, 0x36, 0x7A, 0x42, 0x2B, 0x41, 0x66, 0x6B, 0x6F, 0x3D, 0x0A, 0x2D, ++ 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, ++ 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x33, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, ++ 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x54, 0x6A, 0x43, 0x43, 0x41, 0x64, 0x4F, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, ++ 0x49, 0x4B, 0x50, 0x50, 0x59, 0x48, 0x71, 0x57, 0x68, 0x77, 0x44, 0x74, 0x71, 0x4C, 0x68, 0x44, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x7A, 0x42, 0x72, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, ++ 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x4A, 0x54, 0x6A, 0x45, 0x54, 0x4D, 0x42, 0x45, 0x47, 0x0A, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4D, 0x4B, 0x5A, 0x57, 0x31, 0x54, 0x61, 0x57, 0x64, 0x75, 0x49, 0x46, 0x42, 0x4C, 0x53, ++ 0x54, 0x45, 0x6C, 0x4D, 0x43, 0x4D, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x63, 0x5A, 0x55, 0x31, 0x31, 0x5A, 0x47, 0x68, 0x79, 0x59, 0x53, 0x42, 0x55, 0x5A, 0x57, 0x4E, 0x6F, 0x62, 0x6D, 0x39, 0x73, 0x62, 0x32, 0x64, 0x70, 0x5A, ++ 0x58, 0x4D, 0x67, 0x54, 0x47, 0x6C, 0x74, 0x61, 0x58, 0x52, 0x6C, 0x5A, 0x44, 0x45, 0x67, 0x0A, 0x4D, 0x42, 0x34, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x58, 0x5A, 0x57, 0x31, 0x54, 0x61, 0x57, 0x64, 0x75, 0x49, 0x45, 0x56, 0x44, ++ 0x51, 0x79, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x49, 0x43, 0x30, 0x67, 0x52, 0x7A, 0x4D, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x54, 0x67, 0x77, 0x4D, 0x6A, 0x45, 0x34, 0x4D, 0x54, 0x67, 0x7A, 0x4D, 0x44, 0x41, 0x77, ++ 0x57, 0x68, 0x63, 0x4E, 0x4E, 0x44, 0x4D, 0x77, 0x4D, 0x6A, 0x45, 0x34, 0x0A, 0x4D, 0x54, 0x67, 0x7A, 0x4D, 0x44, 0x41, 0x77, 0x57, 0x6A, 0x42, 0x72, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, ++ 0x4A, 0x54, 0x6A, 0x45, 0x54, 0x4D, 0x42, 0x45, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4D, 0x4B, 0x5A, 0x57, 0x31, 0x54, 0x61, 0x57, 0x64, 0x75, 0x49, 0x46, 0x42, 0x4C, 0x53, 0x54, 0x45, 0x6C, 0x4D, 0x43, 0x4D, 0x47, 0x41, 0x31, 0x55, ++ 0x45, 0x43, 0x68, 0x4D, 0x63, 0x5A, 0x55, 0x31, 0x31, 0x0A, 0x5A, 0x47, 0x68, 0x79, 0x59, 0x53, 0x42, 0x55, 0x5A, 0x57, 0x4E, 0x6F, 0x62, 0x6D, 0x39, 0x73, 0x62, 0x32, 0x64, 0x70, 0x5A, 0x58, 0x4D, 0x67, 0x54, 0x47, 0x6C, 0x74, 0x61, 0x58, ++ 0x52, 0x6C, 0x5A, 0x44, 0x45, 0x67, 0x4D, 0x42, 0x34, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x58, 0x5A, 0x57, 0x31, 0x54, 0x61, 0x57, 0x64, 0x75, 0x49, 0x45, 0x56, 0x44, 0x51, 0x79, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, ++ 0x4E, 0x42, 0x49, 0x43, 0x30, 0x67, 0x0A, 0x52, 0x7A, 0x4D, 0x77, 0x64, 0x6A, 0x41, 0x51, 0x42, 0x67, 0x63, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x49, 0x42, 0x42, 0x67, 0x55, 0x72, 0x67, 0x51, 0x51, 0x41, 0x49, 0x67, 0x4E, 0x69, 0x41, ++ 0x41, 0x51, 0x6A, 0x70, 0x51, 0x79, 0x34, 0x4C, 0x52, 0x4C, 0x31, 0x4B, 0x50, 0x4F, 0x78, 0x73, 0x74, 0x33, 0x69, 0x41, 0x68, 0x4B, 0x41, 0x6E, 0x6A, 0x6C, 0x66, 0x53, 0x55, 0x32, 0x66, 0x79, 0x53, 0x55, 0x30, 0x57, 0x58, 0x54, 0x73, 0x75, ++ 0x77, 0x59, 0x63, 0x0A, 0x35, 0x38, 0x42, 0x79, 0x72, 0x2B, 0x69, 0x75, 0x4C, 0x2B, 0x46, 0x42, 0x56, 0x49, 0x63, 0x55, 0x71, 0x45, 0x71, 0x79, 0x36, 0x48, 0x79, 0x43, 0x35, 0x6C, 0x74, 0x71, 0x74, 0x64, 0x79, 0x7A, 0x64, 0x63, 0x36, 0x4C, ++ 0x42, 0x74, 0x43, 0x47, 0x49, 0x37, 0x39, 0x47, 0x31, 0x59, 0x34, 0x50, 0x50, 0x77, 0x54, 0x30, 0x31, 0x78, 0x79, 0x53, 0x66, 0x76, 0x61, 0x6C, 0x59, 0x38, 0x4C, 0x31, 0x58, 0x34, 0x34, 0x75, 0x54, 0x36, 0x45, 0x59, 0x47, 0x51, 0x49, 0x72, ++ 0x0A, 0x4D, 0x67, 0x71, 0x43, 0x5A, 0x48, 0x30, 0x57, 0x6B, 0x39, 0x47, 0x6A, 0x51, 0x6A, 0x42, 0x41, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x52, 0x38, 0x58, 0x51, 0x4B, 0x45, 0x45, 0x39, 0x54, ++ 0x4D, 0x69, 0x70, 0x75, 0x42, 0x7A, 0x68, 0x63, 0x63, 0x4C, 0x69, 0x6B, 0x65, 0x6E, 0x45, 0x68, 0x6A, 0x51, 0x6A, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x0A, 0x41, 0x51, ++ 0x59, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x77, ++ 0x4E, 0x70, 0x41, 0x44, 0x42, 0x6D, 0x41, 0x6A, 0x45, 0x41, 0x76, 0x76, 0x4E, 0x68, 0x7A, 0x77, 0x49, 0x51, 0x48, 0x57, 0x53, 0x56, 0x42, 0x37, 0x67, 0x59, 0x62, 0x6F, 0x69, 0x46, 0x42, 0x53, 0x2B, 0x44, 0x0A, 0x43, 0x42, 0x65, 0x51, 0x79, ++ 0x68, 0x2B, 0x4B, 0x54, 0x4F, 0x67, 0x4E, 0x47, 0x33, 0x71, 0x78, 0x72, 0x64, 0x57, 0x42, 0x43, 0x55, 0x66, 0x76, 0x4F, 0x36, 0x77, 0x49, 0x42, 0x48, 0x78, 0x63, 0x6D, 0x62, 0x48, 0x74, 0x52, 0x77, 0x66, 0x53, 0x41, 0x6A, 0x45, 0x41, 0x6E, ++ 0x62, 0x70, 0x56, 0x2F, 0x4B, 0x6C, 0x4B, 0x36, 0x4F, 0x33, 0x74, 0x35, 0x6E, 0x59, 0x42, 0x51, 0x6E, 0x76, 0x49, 0x2B, 0x47, 0x44, 0x5A, 0x6A, 0x56, 0x47, 0x4C, 0x56, 0x54, 0x76, 0x37, 0x0A, 0x6A, 0x48, 0x76, 0x72, 0x5A, 0x51, 0x6E, 0x44, ++ 0x2B, 0x4A, 0x62, 0x4E, 0x52, 0x36, 0x69, 0x43, 0x38, 0x68, 0x5A, 0x56, 0x64, 0x79, 0x52, 0x2B, 0x45, 0x68, 0x43, 0x56, 0x42, 0x43, 0x79, 0x6A, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, ++ 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x43, 0x31, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, ++ 0x4D, 0x49, 0x49, 0x44, 0x63, 0x7A, 0x43, 0x43, 0x41, 0x6C, 0x75, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x4C, 0x41, 0x4B, 0x37, 0x50, 0x41, 0x4C, 0x72, 0x45, 0x7A, 0x7A, 0x4C, 0x34, 0x51, 0x37, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4A, ++ 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x77, 0x56, 0x6A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x56, 0x56, 0x4D, 0x78, 0x0A, 0x45, 0x7A, 0x41, ++ 0x52, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x73, 0x54, 0x43, 0x6D, 0x56, 0x74, 0x55, 0x32, 0x6C, 0x6E, 0x62, 0x69, 0x42, 0x51, 0x53, 0x30, 0x6B, 0x78, 0x46, 0x44, 0x41, 0x53, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x43, 0x32, 0x56, ++ 0x4E, 0x64, 0x57, 0x52, 0x6F, 0x63, 0x6D, 0x45, 0x67, 0x53, 0x57, 0x35, 0x6A, 0x4D, 0x52, 0x77, 0x77, 0x47, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x4E, 0x6C, 0x62, 0x56, 0x4E, 0x70, 0x0A, 0x5A, 0x32, 0x34, 0x67, 0x55, 0x6D, ++ 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x53, 0x41, 0x74, 0x49, 0x45, 0x4D, 0x78, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x45, 0x34, 0x4D, 0x44, 0x49, 0x78, 0x4F, 0x44, 0x45, 0x34, 0x4D, 0x7A, 0x41, 0x77, 0x4D, 0x46, 0x6F, 0x58, 0x44, 0x54, ++ 0x51, 0x7A, 0x4D, 0x44, 0x49, 0x78, 0x4F, 0x44, 0x45, 0x34, 0x4D, 0x7A, 0x41, 0x77, 0x4D, 0x46, 0x6F, 0x77, 0x56, 0x6A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0A, 0x42, 0x68, 0x4D, 0x43, 0x56, 0x56, 0x4D, 0x78, 0x45, ++ 0x7A, 0x41, 0x52, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x73, 0x54, 0x43, 0x6D, 0x56, 0x74, 0x55, 0x32, 0x6C, 0x6E, 0x62, 0x69, 0x42, 0x51, 0x53, 0x30, 0x6B, 0x78, 0x46, 0x44, 0x41, 0x53, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x43, ++ 0x32, 0x56, 0x4E, 0x64, 0x57, 0x52, 0x6F, 0x63, 0x6D, 0x45, 0x67, 0x53, 0x57, 0x35, 0x6A, 0x4D, 0x52, 0x77, 0x77, 0x47, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x0A, 0x45, 0x78, 0x4E, 0x6C, 0x62, 0x56, 0x4E, 0x70, 0x5A, 0x32, 0x34, 0x67, ++ 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x53, 0x41, 0x74, 0x49, 0x45, 0x4D, 0x78, 0x4D, 0x49, 0x49, 0x42, 0x49, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, ++ 0x41, 0x41, 0x4F, 0x43, 0x41, 0x51, 0x38, 0x41, 0x4D, 0x49, 0x49, 0x42, 0x43, 0x67, 0x4B, 0x43, 0x41, 0x51, 0x45, 0x41, 0x7A, 0x2B, 0x75, 0x70, 0x0A, 0x75, 0x66, 0x47, 0x5A, 0x42, 0x63, 0x7A, 0x59, 0x4B, 0x43, 0x46, 0x4B, 0x38, 0x33, 0x4D, ++ 0x30, 0x55, 0x59, 0x52, 0x57, 0x45, 0x50, 0x57, 0x67, 0x54, 0x79, 0x77, 0x53, 0x34, 0x2F, 0x6F, 0x54, 0x6D, 0x69, 0x66, 0x51, 0x7A, 0x2F, 0x6C, 0x35, 0x47, 0x6E, 0x52, 0x66, 0x48, 0x58, 0x6B, 0x35, 0x2F, 0x46, 0x76, 0x34, 0x63, 0x49, 0x37, ++ 0x67, 0x6B, 0x6C, 0x4C, 0x33, 0x35, 0x43, 0x58, 0x35, 0x56, 0x49, 0x50, 0x5A, 0x48, 0x64, 0x50, 0x49, 0x57, 0x6F, 0x55, 0x2F, 0x0A, 0x58, 0x73, 0x65, 0x32, 0x42, 0x2B, 0x34, 0x2B, 0x77, 0x4D, 0x36, 0x61, 0x72, 0x36, 0x78, 0x57, 0x51, 0x69, ++ 0x6F, 0x35, 0x4A, 0x58, 0x44, 0x57, 0x76, 0x37, 0x56, 0x37, 0x4E, 0x71, 0x32, 0x73, 0x39, 0x6E, 0x50, 0x63, 0x7A, 0x64, 0x63, 0x64, 0x69, 0x6F, 0x4F, 0x6C, 0x2B, 0x79, 0x75, 0x51, 0x46, 0x54, 0x64, 0x72, 0x48, 0x43, 0x5A, 0x48, 0x33, 0x44, ++ 0x73, 0x70, 0x56, 0x70, 0x4E, 0x71, 0x73, 0x38, 0x46, 0x71, 0x4F, 0x70, 0x30, 0x39, 0x39, 0x63, 0x47, 0x58, 0x0A, 0x4F, 0x46, 0x67, 0x46, 0x69, 0x78, 0x77, 0x52, 0x34, 0x2B, 0x53, 0x30, 0x75, 0x46, 0x32, 0x46, 0x48, 0x59, 0x50, 0x2B, 0x65, ++ 0x46, 0x38, 0x4C, 0x52, 0x57, 0x67, 0x59, 0x53, 0x4B, 0x56, 0x47, 0x63, 0x7A, 0x51, 0x37, 0x2F, 0x67, 0x2F, 0x49, 0x64, 0x72, 0x76, 0x48, 0x47, 0x50, 0x4D, 0x46, 0x30, 0x59, 0x62, 0x7A, 0x68, 0x65, 0x33, 0x6E, 0x75, 0x64, 0x6B, 0x79, 0x72, ++ 0x56, 0x57, 0x49, 0x7A, 0x71, 0x61, 0x32, 0x6B, 0x62, 0x42, 0x50, 0x72, 0x48, 0x34, 0x56, 0x0A, 0x49, 0x35, 0x62, 0x32, 0x50, 0x2F, 0x41, 0x67, 0x4E, 0x42, 0x62, 0x65, 0x43, 0x73, 0x62, 0x45, 0x42, 0x45, 0x56, 0x35, 0x66, 0x36, 0x66, 0x39, ++ 0x76, 0x74, 0x4B, 0x70, 0x70, 0x61, 0x2B, 0x63, 0x78, 0x53, 0x4D, 0x71, 0x39, 0x7A, 0x77, 0x68, 0x62, 0x4C, 0x32, 0x76, 0x6A, 0x30, 0x37, 0x46, 0x4F, 0x72, 0x4C, 0x7A, 0x4E, 0x42, 0x4C, 0x38, 0x33, 0x34, 0x41, 0x61, 0x53, 0x61, 0x54, 0x55, ++ 0x71, 0x5A, 0x58, 0x33, 0x6E, 0x6F, 0x6C, 0x65, 0x6F, 0x6F, 0x6D, 0x73, 0x0A, 0x6C, 0x4D, 0x75, 0x6F, 0x61, 0x4A, 0x75, 0x76, 0x69, 0x6D, 0x55, 0x6E, 0x7A, 0x59, 0x6E, 0x75, 0x33, 0x59, 0x79, 0x31, 0x61, 0x79, 0x6C, 0x77, 0x51, 0x36, 0x42, ++ 0x70, 0x43, 0x2B, 0x53, 0x35, 0x44, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6F, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x2F, 0x71, 0x48, 0x67, 0x63, 0x42, 0x34, ++ 0x71, 0x41, 0x7A, 0x6C, 0x53, 0x57, 0x6B, 0x4B, 0x2B, 0x0A, 0x58, 0x4A, 0x47, 0x46, 0x65, 0x68, 0x69, 0x71, 0x54, 0x62, 0x55, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, ++ 0x45, 0x47, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, ++ 0x45, 0x4C, 0x42, 0x51, 0x41, 0x44, 0x0A, 0x67, 0x67, 0x45, 0x42, 0x41, 0x4D, 0x4A, 0x4B, 0x56, 0x76, 0x6F, 0x56, 0x49, 0x58, 0x73, 0x6F, 0x6F, 0x75, 0x6E, 0x6C, 0x48, 0x66, 0x76, 0x34, 0x4C, 0x63, 0x51, 0x35, 0x6C, 0x6B, 0x46, 0x4D, 0x4F, ++ 0x79, 0x63, 0x73, 0x78, 0x47, 0x77, 0x59, 0x46, 0x59, 0x44, 0x47, 0x72, 0x4B, 0x39, 0x48, 0x57, 0x53, 0x38, 0x6D, 0x43, 0x2B, 0x4D, 0x32, 0x73, 0x4F, 0x38, 0x37, 0x2F, 0x6B, 0x4F, 0x58, 0x53, 0x54, 0x4B, 0x5A, 0x45, 0x68, 0x56, 0x62, 0x33, ++ 0x78, 0x45, 0x70, 0x0A, 0x2F, 0x36, 0x74, 0x54, 0x2B, 0x4C, 0x76, 0x42, 0x65, 0x41, 0x2B, 0x73, 0x6E, 0x46, 0x4F, 0x76, 0x56, 0x37, 0x31, 0x6F, 0x6A, 0x44, 0x31, 0x70, 0x4D, 0x2F, 0x43, 0x6A, 0x6F, 0x43, 0x4E, 0x6A, 0x4F, 0x32, 0x52, 0x6E, ++ 0x49, 0x6B, 0x53, 0x74, 0x31, 0x58, 0x48, 0x4C, 0x56, 0x69, 0x70, 0x34, 0x6B, 0x71, 0x4E, 0x50, 0x45, 0x6A, 0x45, 0x32, 0x4E, 0x75, 0x4C, 0x65, 0x2F, 0x67, 0x44, 0x45, 0x6F, 0x32, 0x41, 0x50, 0x4A, 0x36, 0x32, 0x67, 0x73, 0x49, 0x71, 0x31, ++ 0x0A, 0x4E, 0x6E, 0x70, 0x53, 0x6F, 0x62, 0x30, 0x6E, 0x39, 0x43, 0x41, 0x6E, 0x59, 0x75, 0x68, 0x4E, 0x6C, 0x43, 0x51, 0x54, 0x35, 0x41, 0x6F, 0x45, 0x36, 0x54, 0x79, 0x72, 0x4C, 0x73, 0x68, 0x44, 0x43, 0x55, 0x72, 0x47, 0x59, 0x51, 0x54, ++ 0x6C, 0x53, 0x54, 0x52, 0x2B, 0x30, 0x38, 0x54, 0x49, 0x39, 0x51, 0x2F, 0x41, 0x71, 0x75, 0x6D, 0x36, 0x56, 0x46, 0x37, 0x7A, 0x59, 0x79, 0x74, 0x50, 0x54, 0x31, 0x44, 0x55, 0x2F, 0x72, 0x6C, 0x37, 0x6D, 0x59, 0x77, 0x39, 0x0A, 0x77, 0x43, ++ 0x36, 0x38, 0x41, 0x69, 0x76, 0x54, 0x78, 0x45, 0x44, 0x6B, 0x69, 0x67, 0x63, 0x78, 0x48, 0x70, 0x76, 0x4F, 0x4A, 0x70, 0x6B, 0x54, 0x2B, 0x78, 0x48, 0x71, 0x6D, 0x69, 0x49, 0x4D, 0x45, 0x52, 0x6E, 0x48, 0x58, 0x68, 0x75, 0x42, 0x55, 0x44, ++ 0x44, 0x49, 0x6C, 0x68, 0x4A, 0x75, 0x35, 0x38, 0x74, 0x42, 0x66, 0x35, 0x45, 0x37, 0x6F, 0x6B, 0x65, 0x33, 0x56, 0x49, 0x41, 0x62, 0x33, 0x41, 0x44, 0x4D, 0x6D, 0x70, 0x44, 0x71, 0x77, 0x38, 0x4E, 0x51, 0x0A, 0x42, 0x6D, 0x49, 0x4D, 0x4D, ++ 0x4D, 0x41, 0x56, 0x53, 0x4B, 0x65, 0x6F, 0x57, 0x58, 0x7A, 0x68, 0x72, 0x69, 0x4B, 0x69, 0x34, 0x67, 0x70, 0x36, 0x44, 0x2F, 0x70, 0x69, 0x71, 0x31, 0x4A, 0x4D, 0x34, 0x66, 0x48, 0x66, 0x79, 0x72, 0x36, 0x44, 0x44, 0x55, 0x49, 0x3D, 0x0A, ++ 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, ++ 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x43, 0x33, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x4B, 0x7A, 0x43, 0x43, 0x41, 0x62, 0x47, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, ++ 0x67, 0x49, 0x4B, 0x65, 0x33, 0x47, 0x32, 0x67, 0x6C, 0x61, 0x34, 0x45, 0x6E, 0x79, 0x63, 0x71, 0x44, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x7A, 0x42, 0x61, 0x4D, 0x51, 0x73, 0x77, 0x43, ++ 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x54, 0x4D, 0x42, 0x45, 0x47, 0x0A, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4D, 0x4B, 0x5A, 0x57, 0x31, 0x54, 0x61, 0x57, 0x64, 0x75, 0x49, 0x46, 0x42, 0x4C, ++ 0x53, 0x54, 0x45, 0x55, 0x4D, 0x42, 0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x4C, 0x5A, 0x55, 0x31, 0x31, 0x5A, 0x47, 0x68, 0x79, 0x59, 0x53, 0x42, 0x4A, 0x62, 0x6D, 0x4D, 0x78, 0x49, 0x44, 0x41, 0x65, 0x42, 0x67, 0x4E, 0x56, ++ 0x42, 0x41, 0x4D, 0x54, 0x46, 0x32, 0x56, 0x74, 0x55, 0x32, 0x6C, 0x6E, 0x62, 0x69, 0x42, 0x46, 0x0A, 0x51, 0x30, 0x4D, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x53, 0x41, 0x74, 0x49, 0x45, 0x4D, 0x7A, 0x4D, 0x42, 0x34, ++ 0x58, 0x44, 0x54, 0x45, 0x34, 0x4D, 0x44, 0x49, 0x78, 0x4F, 0x44, 0x45, 0x34, 0x4D, 0x7A, 0x41, 0x77, 0x4D, 0x46, 0x6F, 0x58, 0x44, 0x54, 0x51, 0x7A, 0x4D, 0x44, 0x49, 0x78, 0x4F, 0x44, 0x45, 0x34, 0x4D, 0x7A, 0x41, 0x77, 0x4D, 0x46, 0x6F, ++ 0x77, 0x57, 0x6A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0A, 0x42, 0x68, 0x4D, 0x43, 0x56, 0x56, 0x4D, 0x78, 0x45, 0x7A, 0x41, 0x52, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x73, 0x54, 0x43, 0x6D, 0x56, 0x74, 0x55, 0x32, ++ 0x6C, 0x6E, 0x62, 0x69, 0x42, 0x51, 0x53, 0x30, 0x6B, 0x78, 0x46, 0x44, 0x41, 0x53, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x43, 0x32, 0x56, 0x4E, 0x64, 0x57, 0x52, 0x6F, 0x63, 0x6D, 0x45, 0x67, 0x53, 0x57, 0x35, 0x6A, 0x4D, 0x53, ++ 0x41, 0x77, 0x48, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x0A, 0x45, 0x78, 0x64, 0x6C, 0x62, 0x56, 0x4E, 0x70, 0x5A, 0x32, 0x34, 0x67, 0x52, 0x55, 0x4E, 0x44, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x4C, ++ 0x53, 0x42, 0x44, 0x4D, 0x7A, 0x42, 0x32, 0x4D, 0x42, 0x41, 0x47, 0x42, 0x79, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x41, 0x67, 0x45, 0x47, 0x42, 0x53, 0x75, 0x42, 0x42, 0x41, 0x41, 0x69, 0x41, 0x32, 0x49, 0x41, 0x42, 0x50, 0x32, 0x6C, 0x59, ++ 0x61, 0x35, 0x37, 0x4A, 0x68, 0x41, 0x64, 0x0A, 0x36, 0x62, 0x63, 0x69, 0x4D, 0x4B, 0x34, 0x47, 0x39, 0x49, 0x47, 0x7A, 0x73, 0x55, 0x4A, 0x78, 0x6C, 0x54, 0x6D, 0x38, 0x30, 0x31, 0x4C, 0x6A, 0x72, 0x36, 0x2F, 0x35, 0x38, 0x70, 0x63, 0x31, ++ 0x6B, 0x6A, 0x5A, 0x47, 0x44, 0x6F, 0x65, 0x56, 0x6A, 0x62, 0x6B, 0x35, 0x57, 0x75, 0x6D, 0x37, 0x33, 0x39, 0x44, 0x2B, 0x79, 0x41, 0x64, 0x42, 0x50, 0x4C, 0x74, 0x56, 0x62, 0x34, 0x4F, 0x6A, 0x61, 0x76, 0x74, 0x69, 0x73, 0x49, 0x47, 0x4A, ++ 0x41, 0x6E, 0x42, 0x39, 0x0A, 0x53, 0x4D, 0x56, 0x4B, 0x34, 0x2B, 0x6B, 0x69, 0x56, 0x43, 0x4A, 0x4E, 0x6B, 0x37, 0x74, 0x43, 0x44, 0x4B, 0x39, 0x33, 0x6E, 0x43, 0x4F, 0x6D, 0x66, 0x64, 0x64, 0x68, 0x45, 0x63, 0x35, 0x6C, 0x78, 0x2F, 0x68, ++ 0x2F, 0x2F, 0x76, 0x58, 0x79, 0x71, 0x61, 0x4E, 0x43, 0x4D, 0x45, 0x41, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x46, 0x50, 0x74, 0x61, 0x53, 0x4E, 0x43, 0x41, 0x49, 0x45, 0x44, 0x79, 0x71, 0x4F, 0x6B, ++ 0x41, 0x0A, 0x42, 0x32, 0x6B, 0x5A, 0x64, 0x36, 0x66, 0x6D, 0x77, 0x2F, 0x54, 0x50, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6A, 0x41, 0x50, 0x42, 0x67, ++ 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x41, 0x6F, 0x47, 0x43, 0x43, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x42, 0x41, 0x4D, 0x44, 0x41, 0x32, 0x67, 0x41, 0x0A, 0x4D, ++ 0x47, 0x55, 0x43, 0x4D, 0x51, 0x43, 0x30, 0x32, 0x43, 0x38, 0x43, 0x69, 0x66, 0x32, 0x32, 0x54, 0x47, 0x4B, 0x36, 0x51, 0x30, 0x34, 0x54, 0x68, 0x48, 0x4B, 0x31, 0x72, 0x74, 0x30, 0x63, 0x33, 0x74, 0x61, 0x31, 0x33, 0x46, 0x61, 0x50, 0x57, ++ 0x45, 0x42, 0x61, 0x4C, 0x64, 0x34, 0x67, 0x54, 0x43, 0x4B, 0x44, 0x79, 0x70, 0x4F, 0x6F, 0x66, 0x75, 0x34, 0x53, 0x51, 0x4D, 0x66, 0x57, 0x68, 0x30, 0x2F, 0x34, 0x33, 0x34, 0x55, 0x43, 0x4D, 0x42, 0x77, 0x55, 0x0A, 0x5A, 0x4F, 0x52, 0x38, ++ 0x6C, 0x6F, 0x4D, 0x52, 0x6E, 0x4C, 0x44, 0x52, 0x57, 0x6D, 0x46, 0x4C, 0x70, 0x67, 0x39, 0x4A, 0x30, 0x77, 0x44, 0x38, 0x6F, 0x66, 0x7A, 0x6B, 0x70, 0x66, 0x39, 0x2F, 0x72, 0x64, 0x63, 0x77, 0x30, 0x4D, 0x64, 0x33, 0x66, 0x37, 0x36, 0x42, ++ 0x42, 0x31, 0x55, 0x77, 0x55, 0x43, 0x41, 0x55, 0x39, 0x56, 0x63, 0x34, 0x43, 0x71, 0x67, 0x78, 0x55, 0x51, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, ++ 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x48, 0x6F, 0x6E, 0x67, 0x6B, 0x6F, 0x6E, 0x67, 0x20, 0x50, 0x6F, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, ++ 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x7A, 0x7A, 0x43, 0x43, 0x41, 0x37, 0x65, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x55, 0x43, 0x42, 0x5A, 0x66, 0x69, 0x6B, 0x79, 0x6C, 0x37, 0x41, 0x44, 0x4A, 0x6B, 0x30, 0x44, 0x66, ++ 0x78, 0x4D, 0x61, 0x75, 0x49, 0x37, 0x67, 0x63, 0x57, 0x71, 0x51, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x77, 0x62, 0x7A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, ++ 0x0A, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x53, 0x45, 0x73, 0x78, 0x45, 0x6A, 0x41, 0x51, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x67, 0x54, 0x43, 0x55, 0x68, 0x76, 0x62, 0x6D, 0x63, 0x67, 0x53, 0x32, 0x39, 0x75, 0x5A, 0x7A, 0x45, ++ 0x53, 0x4D, 0x42, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x78, 0x4D, 0x4A, 0x53, 0x47, 0x39, 0x75, 0x5A, 0x79, 0x42, 0x4C, 0x62, 0x32, 0x35, 0x6E, 0x4D, 0x52, 0x59, 0x77, 0x46, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x0A, 0x45, 0x77, ++ 0x31, 0x49, 0x62, 0x32, 0x35, 0x6E, 0x61, 0x32, 0x39, 0x75, 0x5A, 0x79, 0x42, 0x51, 0x62, 0x33, 0x4E, 0x30, 0x4D, 0x53, 0x41, 0x77, 0x48, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x64, 0x49, 0x62, 0x32, 0x35, 0x6E, 0x61, 0x32, ++ 0x39, 0x75, 0x5A, 0x79, 0x42, 0x51, 0x62, 0x33, 0x4E, 0x30, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x4D, 0x7A, 0x41, 0x65, 0x46, 0x77, 0x30, 0x78, 0x4E, 0x7A, 0x41, 0x32, 0x0A, 0x4D, 0x44, 0x4D, 0x77, 0x4D, ++ 0x6A, 0x49, 0x35, 0x4E, 0x44, 0x5A, 0x61, 0x46, 0x77, 0x30, 0x30, 0x4D, 0x6A, 0x41, 0x32, 0x4D, 0x44, 0x4D, 0x77, 0x4D, 0x6A, 0x49, 0x35, 0x4E, 0x44, 0x5A, 0x61, 0x4D, 0x47, 0x38, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, ++ 0x41, 0x59, 0x54, 0x41, 0x6B, 0x68, 0x4C, 0x4D, 0x52, 0x49, 0x77, 0x45, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x49, 0x45, 0x77, 0x6C, 0x49, 0x62, 0x32, 0x35, 0x6E, 0x49, 0x45, 0x74, 0x76, 0x0A, 0x62, 0x6D, 0x63, 0x78, 0x45, 0x6A, 0x41, 0x51, ++ 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x63, 0x54, 0x43, 0x55, 0x68, 0x76, 0x62, 0x6D, 0x63, 0x67, 0x53, 0x32, 0x39, 0x75, 0x5A, 0x7A, 0x45, 0x57, 0x4D, 0x42, 0x51, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x4E, 0x53, 0x47, 0x39, 0x75, ++ 0x5A, 0x32, 0x74, 0x76, 0x62, 0x6D, 0x63, 0x67, 0x55, 0x47, 0x39, 0x7A, 0x64, 0x44, 0x45, 0x67, 0x4D, 0x42, 0x34, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x58, 0x0A, 0x53, 0x47, 0x39, 0x75, 0x5A, 0x32, 0x74, 0x76, 0x62, 0x6D, 0x63, ++ 0x67, 0x55, 0x47, 0x39, 0x7A, 0x64, 0x43, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x49, 0x44, 0x4D, 0x77, 0x67, 0x67, 0x49, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, ++ 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x43, 0x7A, 0x0A, 0x69, 0x4E, 0x66, 0x71, 0x7A, 0x67, 0x38, 0x67, 0x54, 0x72, 0x37, 0x6D, 0x31, 0x67, ++ 0x4E, 0x74, 0x37, 0x6C, 0x6E, 0x38, 0x77, 0x6C, 0x66, 0x66, 0x4B, 0x57, 0x69, 0x68, 0x67, 0x77, 0x34, 0x2B, 0x61, 0x4D, 0x64, 0x6F, 0x57, 0x4A, 0x77, 0x63, 0x59, 0x45, 0x75, 0x4A, 0x51, 0x77, 0x79, 0x35, 0x31, 0x42, 0x57, 0x79, 0x37, 0x73, ++ 0x46, 0x4F, 0x64, 0x65, 0x6D, 0x31, 0x70, 0x2B, 0x2F, 0x6C, 0x36, 0x54, 0x57, 0x5A, 0x35, 0x4D, 0x77, 0x63, 0x35, 0x30, 0x74, 0x66, 0x0A, 0x6A, 0x54, 0x4D, 0x77, 0x49, 0x44, 0x4E, 0x54, 0x32, 0x61, 0x61, 0x37, 0x31, 0x54, 0x34, 0x54, 0x6A, ++ 0x75, 0x6B, 0x66, 0x68, 0x30, 0x6D, 0x74, 0x55, 0x43, 0x31, 0x51, 0x79, 0x68, 0x69, 0x2B, 0x41, 0x56, 0x69, 0x69, 0x45, 0x33, 0x43, 0x57, 0x75, 0x34, 0x6D, 0x49, 0x56, 0x6F, 0x42, 0x63, 0x2B, 0x4C, 0x30, 0x73, 0x50, 0x4F, 0x46, 0x4D, 0x56, ++ 0x34, 0x69, 0x37, 0x30, 0x37, 0x6D, 0x56, 0x37, 0x38, 0x76, 0x48, 0x39, 0x74, 0x6F, 0x78, 0x64, 0x43, 0x69, 0x6D, 0x0A, 0x35, 0x6C, 0x53, 0x4A, 0x39, 0x55, 0x45, 0x78, 0x79, 0x75, 0x55, 0x6D, 0x47, 0x73, 0x32, 0x43, 0x34, 0x48, 0x44, 0x61, ++ 0x4F, 0x79, 0x6D, 0x37, 0x31, 0x51, 0x50, 0x31, 0x6D, 0x62, 0x70, 0x56, 0x39, 0x57, 0x54, 0x52, 0x59, 0x41, 0x36, 0x7A, 0x69, 0x55, 0x6D, 0x34, 0x69, 0x69, 0x38, 0x46, 0x30, 0x6F, 0x52, 0x46, 0x4B, 0x48, 0x79, 0x50, 0x61, 0x46, 0x41, 0x53, ++ 0x65, 0x50, 0x77, 0x4C, 0x74, 0x56, 0x50, 0x4C, 0x77, 0x70, 0x67, 0x63, 0x68, 0x4B, 0x4F, 0x65, 0x0A, 0x73, 0x4C, 0x34, 0x6A, 0x70, 0x4E, 0x72, 0x63, 0x79, 0x43, 0x73, 0x65, 0x32, 0x6D, 0x35, 0x46, 0x48, 0x6F, 0x6D, 0x59, 0x32, 0x76, 0x6B, ++ 0x41, 0x4C, 0x67, 0x62, 0x70, 0x44, 0x44, 0x74, 0x77, 0x31, 0x56, 0x41, 0x6C, 0x69, 0x4A, 0x6E, 0x4C, 0x7A, 0x58, 0x4E, 0x67, 0x39, 0x39, 0x58, 0x2F, 0x4E, 0x57, 0x66, 0x46, 0x6F, 0x62, 0x78, 0x65, 0x71, 0x38, 0x31, 0x4B, 0x75, 0x45, 0x58, ++ 0x72, 0x79, 0x47, 0x67, 0x65, 0x44, 0x51, 0x30, 0x55, 0x52, 0x68, 0x4C, 0x6A, 0x0A, 0x30, 0x6D, 0x52, 0x69, 0x69, 0x6B, 0x4B, 0x59, 0x76, 0x4C, 0x54, 0x47, 0x43, 0x41, 0x6A, 0x34, 0x2F, 0x61, 0x68, 0x4D, 0x5A, 0x4A, 0x78, 0x32, 0x41, 0x62, ++ 0x30, 0x76, 0x71, 0x57, 0x77, 0x7A, 0x44, 0x39, 0x67, 0x2F, 0x4B, 0x4C, 0x67, 0x38, 0x61, 0x51, 0x46, 0x43, 0x68, 0x6E, 0x35, 0x70, 0x77, 0x63, 0x6B, 0x47, 0x79, 0x75, 0x56, 0x36, 0x52, 0x6D, 0x58, 0x70, 0x77, 0x74, 0x5A, 0x51, 0x51, 0x53, ++ 0x34, 0x2F, 0x74, 0x2B, 0x54, 0x74, 0x62, 0x4E, 0x65, 0x2F, 0x0A, 0x4A, 0x67, 0x45, 0x52, 0x6F, 0x68, 0x59, 0x70, 0x53, 0x6D, 0x73, 0x30, 0x42, 0x70, 0x44, 0x73, 0x45, 0x39, 0x4B, 0x32, 0x2B, 0x32, 0x70, 0x32, 0x30, 0x6A, 0x7A, 0x74, 0x38, ++ 0x4E, 0x59, 0x74, 0x33, 0x65, 0x45, 0x56, 0x37, 0x4B, 0x4F, 0x62, 0x4C, 0x79, 0x7A, 0x4A, 0x50, 0x69, 0x76, 0x6B, 0x61, 0x54, 0x76, 0x2F, 0x63, 0x69, 0x57, 0x78, 0x4E, 0x6F, 0x5A, 0x62, 0x78, 0x33, 0x39, 0x72, 0x69, 0x31, 0x55, 0x62, 0x53, ++ 0x73, 0x55, 0x67, 0x59, 0x54, 0x32, 0x75, 0x0A, 0x79, 0x31, 0x44, 0x68, 0x43, 0x44, 0x71, 0x2B, 0x73, 0x49, 0x39, 0x6A, 0x51, 0x56, 0x4D, 0x77, 0x43, 0x46, 0x6B, 0x38, 0x6D, 0x42, 0x31, 0x33, 0x75, 0x6D, 0x4F, 0x52, 0x65, 0x73, 0x6F, 0x51, ++ 0x55, 0x47, 0x43, 0x2F, 0x38, 0x4E, 0x65, 0x38, 0x6C, 0x59, 0x65, 0x50, 0x6C, 0x38, 0x58, 0x2B, 0x6C, 0x32, 0x6F, 0x42, 0x6C, 0x4B, 0x4E, 0x38, 0x57, 0x34, 0x55, 0x64, 0x4B, 0x6A, 0x6B, 0x36, 0x30, 0x46, 0x53, 0x68, 0x30, 0x54, 0x6C, 0x78, ++ 0x6E, 0x66, 0x30, 0x68, 0x0A, 0x2B, 0x62, 0x56, 0x37, 0x38, 0x4F, 0x4C, 0x67, 0x41, 0x6F, 0x39, 0x75, 0x6C, 0x69, 0x51, 0x6C, 0x4C, 0x4B, 0x41, 0x65, 0x4C, 0x4B, 0x6A, 0x45, 0x69, 0x61, 0x66, 0x76, 0x37, 0x5A, 0x6B, 0x47, 0x4C, 0x37, 0x59, ++ 0x4B, 0x54, 0x45, 0x2F, 0x62, 0x6F, 0x73, 0x77, 0x33, 0x47, 0x71, 0x39, 0x48, 0x68, 0x53, 0x32, 0x4B, 0x58, 0x38, 0x51, 0x30, 0x4E, 0x45, 0x77, 0x41, 0x2F, 0x52, 0x69, 0x54, 0x5A, 0x78, 0x50, 0x52, 0x4E, 0x2B, 0x5A, 0x49, 0x74, 0x49, 0x73, ++ 0x47, 0x0A, 0x78, 0x56, 0x64, 0x37, 0x47, 0x59, 0x59, 0x4B, 0x65, 0x63, 0x73, 0x41, 0x79, 0x56, 0x4B, 0x76, 0x51, 0x76, 0x38, 0x33, 0x6A, 0x2B, 0x47, 0x6A, 0x48, 0x6E, 0x6F, 0x39, 0x55, 0x4B, 0x74, 0x6A, 0x42, 0x75, 0x63, 0x56, 0x74, 0x54, ++ 0x2B, 0x32, 0x52, 0x54, 0x65, 0x55, 0x4E, 0x37, 0x46, 0x2B, 0x38, 0x6B, 0x6A, 0x44, 0x66, 0x38, 0x56, 0x31, 0x2F, 0x70, 0x65, 0x4E, 0x52, 0x59, 0x38, 0x61, 0x70, 0x78, 0x70, 0x79, 0x4B, 0x42, 0x70, 0x41, 0x44, 0x77, 0x49, 0x44, 0x0A, 0x41, ++ 0x51, 0x41, 0x42, 0x6F, 0x32, 0x4D, 0x77, 0x59, 0x54, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, ++ 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6A, 0x41, 0x66, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x53, 0x4D, 0x45, 0x47, 0x44, 0x41, 0x57, 0x67, 0x42, 0x51, 0x58, 0x6E, 0x63, 0x30, 0x65, 0x0A, 0x69, 0x39, 0x59, 0x35, ++ 0x4B, 0x33, 0x44, 0x54, 0x58, 0x4E, 0x53, 0x67, 0x75, 0x42, 0x2B, 0x77, 0x41, 0x50, 0x7A, 0x46, 0x59, 0x54, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x46, 0x35, 0x33, 0x4E, 0x48, 0x6F, 0x76, 0x57, ++ 0x4F, 0x53, 0x74, 0x77, 0x30, 0x31, 0x7A, 0x55, 0x6F, 0x4C, 0x67, 0x66, 0x73, 0x41, 0x44, 0x38, 0x78, 0x57, 0x45, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x0A, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, ++ 0x44, 0x67, 0x67, 0x49, 0x42, 0x41, 0x46, 0x62, 0x56, 0x65, 0x32, 0x37, 0x6D, 0x49, 0x67, 0x48, 0x53, 0x51, 0x70, 0x73, 0x59, 0x31, 0x51, 0x37, 0x58, 0x5A, 0x69, 0x4E, 0x63, 0x34, 0x2F, 0x36, 0x67, 0x78, 0x35, 0x4C, 0x53, 0x36, 0x5A, 0x53, ++ 0x74, 0x53, 0x36, 0x4C, 0x47, 0x37, 0x42, 0x4A, 0x38, 0x64, 0x4E, 0x56, 0x49, 0x30, 0x6C, 0x6B, 0x55, 0x6D, 0x63, 0x44, 0x72, 0x75, 0x64, 0x48, 0x72, 0x39, 0x45, 0x67, 0x77, 0x0A, 0x57, 0x36, 0x32, 0x6E, 0x56, 0x33, 0x4F, 0x5A, 0x71, 0x64, ++ 0x50, 0x6C, 0x74, 0x39, 0x45, 0x75, 0x57, 0x53, 0x52, 0x59, 0x33, 0x47, 0x67, 0x75, 0x4C, 0x6D, 0x4C, 0x59, 0x61, 0x75, 0x52, 0x77, 0x43, 0x79, 0x30, 0x67, 0x55, 0x43, 0x43, 0x6B, 0x4D, 0x70, 0x58, 0x52, 0x41, 0x4A, 0x69, 0x37, 0x30, 0x2F, ++ 0x33, 0x33, 0x4D, 0x76, 0x4A, 0x4A, 0x72, 0x73, 0x5A, 0x36, 0x34, 0x45, 0x65, 0x2B, 0x62, 0x73, 0x37, 0x4C, 0x6F, 0x33, 0x49, 0x36, 0x4C, 0x57, 0x6C, 0x64, 0x0A, 0x79, 0x38, 0x6A, 0x6F, 0x52, 0x54, 0x6E, 0x55, 0x2B, 0x6B, 0x4C, 0x42, 0x45, ++ 0x55, 0x78, 0x33, 0x58, 0x5A, 0x4C, 0x37, 0x61, 0x76, 0x39, 0x59, 0x52, 0x4F, 0x58, 0x72, 0x67, 0x5A, 0x36, 0x76, 0x6F, 0x4A, 0x6D, 0x74, 0x76, 0x71, 0x6B, 0x42, 0x5A, 0x73, 0x73, 0x34, 0x48, 0x54, 0x7A, 0x66, 0x51, 0x78, 0x2F, 0x30, 0x54, ++ 0x57, 0x36, 0x30, 0x75, 0x68, 0x64, 0x47, 0x2F, 0x48, 0x33, 0x39, 0x68, 0x34, 0x46, 0x35, 0x61, 0x67, 0x30, 0x7A, 0x44, 0x2F, 0x6F, 0x76, 0x0A, 0x2B, 0x42, 0x53, 0x35, 0x67, 0x4C, 0x4E, 0x64, 0x54, 0x61, 0x71, 0x58, 0x34, 0x66, 0x6E, 0x6B, ++ 0x47, 0x4D, 0x58, 0x34, 0x31, 0x54, 0x69, 0x4D, 0x4A, 0x6A, 0x7A, 0x39, 0x38, 0x69, 0x6A, 0x69, 0x37, 0x6C, 0x70, 0x4A, 0x69, 0x43, 0x7A, 0x66, 0x65, 0x54, 0x32, 0x4F, 0x6E, 0x70, 0x41, 0x38, 0x76, 0x55, 0x46, 0x4B, 0x4F, 0x74, 0x31, 0x62, ++ 0x39, 0x70, 0x71, 0x30, 0x7A, 0x6A, 0x38, 0x6C, 0x4D, 0x48, 0x38, 0x79, 0x66, 0x61, 0x49, 0x44, 0x6C, 0x4E, 0x44, 0x63, 0x0A, 0x65, 0x71, 0x46, 0x53, 0x33, 0x6D, 0x36, 0x54, 0x6A, 0x52, 0x67, 0x6D, 0x2F, 0x56, 0x57, 0x73, 0x76, 0x59, 0x2B, ++ 0x62, 0x30, 0x73, 0x2B, 0x76, 0x35, 0x34, 0x59, 0x73, 0x79, 0x78, 0x38, 0x4A, 0x62, 0x36, 0x4E, 0x76, 0x71, 0x59, 0x54, 0x55, 0x63, 0x37, 0x39, 0x4E, 0x6F, 0x58, 0x51, 0x62, 0x54, 0x69, 0x4E, 0x67, 0x38, 0x73, 0x77, 0x4F, 0x71, 0x6E, 0x2B, ++ 0x6B, 0x6E, 0x45, 0x77, 0x6C, 0x71, 0x4C, 0x4A, 0x6D, 0x4F, 0x7A, 0x6A, 0x2F, 0x32, 0x5A, 0x51, 0x77, 0x0A, 0x39, 0x6E, 0x4B, 0x45, 0x76, 0x6D, 0x68, 0x56, 0x45, 0x41, 0x2F, 0x47, 0x63, 0x79, 0x77, 0x57, 0x61, 0x5A, 0x4D, 0x48, 0x2F, 0x72, ++ 0x46, 0x46, 0x37, 0x62, 0x75, 0x69, 0x56, 0x57, 0x71, 0x77, 0x32, 0x72, 0x56, 0x4B, 0x41, 0x69, 0x55, 0x6E, 0x68, 0x64, 0x65, 0x33, 0x74, 0x34, 0x5A, 0x45, 0x46, 0x6F, 0x6C, 0x73, 0x67, 0x43, 0x73, 0x2B, 0x6C, 0x36, 0x6D, 0x63, 0x31, 0x58, ++ 0x35, 0x56, 0x54, 0x4D, 0x62, 0x65, 0x52, 0x52, 0x41, 0x63, 0x36, 0x75, 0x6B, 0x37, 0x0A, 0x6E, 0x77, 0x4E, 0x54, 0x37, 0x75, 0x35, 0x36, 0x41, 0x51, 0x49, 0x57, 0x65, 0x4E, 0x54, 0x6F, 0x77, 0x72, 0x35, 0x47, 0x64, 0x6F, 0x67, 0x54, 0x50, ++ 0x79, 0x4B, 0x37, 0x53, 0x42, 0x49, 0x64, 0x55, 0x67, 0x43, 0x30, 0x41, 0x6E, 0x34, 0x68, 0x47, 0x68, 0x36, 0x63, 0x4A, 0x66, 0x54, 0x7A, 0x50, 0x56, 0x34, 0x65, 0x30, 0x68, 0x7A, 0x35, 0x73, 0x79, 0x32, 0x32, 0x39, 0x7A, 0x64, 0x63, 0x78, ++ 0x73, 0x73, 0x68, 0x54, 0x72, 0x44, 0x33, 0x6D, 0x55, 0x63, 0x59, 0x0A, 0x68, 0x63, 0x45, 0x72, 0x75, 0x6C, 0x57, 0x75, 0x42, 0x75, 0x72, 0x51, 0x42, 0x37, 0x4C, 0x63, 0x71, 0x39, 0x43, 0x43, 0x6C, 0x6E, 0x58, 0x4F, 0x30, 0x6C, 0x44, 0x2B, ++ 0x6D, 0x65, 0x66, 0x50, 0x4C, 0x35, 0x2F, 0x6E, 0x64, 0x74, 0x46, 0x68, 0x4B, 0x76, 0x73, 0x68, 0x75, 0x7A, 0x48, 0x51, 0x71, 0x70, 0x39, 0x48, 0x70, 0x4C, 0x49, 0x69, 0x79, 0x68, 0x59, 0x36, 0x55, 0x46, 0x66, 0x45, 0x57, 0x30, 0x4E, 0x6E, ++ 0x78, 0x57, 0x56, 0x69, 0x41, 0x30, 0x6B, 0x42, 0x0A, 0x36, 0x30, 0x50, 0x5A, 0x32, 0x50, 0x69, 0x65, 0x72, 0x63, 0x2B, 0x78, 0x59, 0x77, 0x35, 0x46, 0x39, 0x4B, 0x42, 0x61, 0x4C, 0x4A, 0x73, 0x74, 0x78, 0x61, 0x62, 0x41, 0x72, 0x61, 0x68, ++ 0x48, 0x39, 0x43, 0x64, 0x4D, 0x4F, 0x41, 0x30, 0x75, 0x47, 0x30, 0x6B, 0x37, 0x55, 0x76, 0x54, 0x6F, 0x69, 0x49, 0x4D, 0x72, 0x56, 0x43, 0x6A, 0x55, 0x38, 0x6A, 0x56, 0x53, 0x74, 0x44, 0x4B, 0x44, 0x59, 0x6D, 0x6C, 0x6B, 0x44, 0x4A, 0x47, ++ 0x63, 0x6E, 0x35, 0x66, 0x71, 0x0A, 0x64, 0x42, 0x62, 0x39, 0x48, 0x78, 0x45, 0x47, 0x6D, 0x70, 0x76, 0x30, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, ++ 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, ++ 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x32, 0x30, 0x31, 0x37, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, ++ 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x57, 0x54, 0x43, 0x43, 0x41, 0x64, 0x2B, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x5A, 0x76, 0x49, 0x39, 0x72, 0x34, 0x66, 0x65, 0x69, 0x37, 0x46, 0x4B, 0x36, 0x67, ++ 0x78, 0x58, 0x4D, 0x51, 0x48, 0x43, 0x37, 0x44, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x7A, 0x42, 0x6C, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, ++ 0x4A, 0x56, 0x0A, 0x55, 0x7A, 0x45, 0x65, 0x4D, 0x42, 0x77, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x56, 0x54, 0x57, 0x6C, 0x6A, 0x63, 0x6D, 0x39, 0x7A, 0x62, 0x32, 0x5A, 0x30, 0x49, 0x45, 0x4E, 0x76, 0x63, 0x6E, 0x42, 0x76, 0x63, ++ 0x6D, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x4D, 0x54, 0x59, 0x77, 0x4E, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x79, 0x31, 0x4E, 0x61, 0x57, 0x4E, 0x79, 0x62, 0x33, 0x4E, 0x76, 0x5A, 0x6E, 0x51, 0x67, 0x52, 0x55, 0x4E, 0x44, 0x0A, ++ 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6C, 0x6D, 0x61, 0x57, 0x4E, 0x68, 0x64, 0x47, 0x55, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52, 0x35, 0x49, 0x44, 0x49, 0x77, ++ 0x4D, 0x54, 0x63, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x54, 0x6B, 0x78, 0x4D, 0x6A, 0x45, 0x34, 0x4D, 0x6A, 0x4D, 0x77, 0x4E, 0x6A, 0x51, 0x31, 0x57, 0x68, 0x63, 0x4E, 0x4E, 0x44, 0x49, 0x77, 0x4E, 0x7A, 0x45, 0x34, 0x0A, 0x4D, 0x6A, 0x4D, ++ 0x78, 0x4E, 0x6A, 0x41, 0x30, 0x57, 0x6A, 0x42, 0x6C, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x65, 0x4D, 0x42, 0x77, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, ++ 0x56, 0x54, 0x57, 0x6C, 0x6A, 0x63, 0x6D, 0x39, 0x7A, 0x62, 0x32, 0x5A, 0x30, 0x49, 0x45, 0x4E, 0x76, 0x63, 0x6E, 0x42, 0x76, 0x63, 0x6D, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x4D, 0x54, 0x59, 0x77, 0x0A, 0x4E, 0x41, 0x59, 0x44, 0x56, 0x51, ++ 0x51, 0x44, 0x45, 0x79, 0x31, 0x4E, 0x61, 0x57, 0x4E, 0x79, 0x62, 0x33, 0x4E, 0x76, 0x5A, 0x6E, 0x51, 0x67, 0x52, 0x55, 0x4E, 0x44, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6C, 0x6D, 0x61, 0x57, ++ 0x4E, 0x68, 0x64, 0x47, 0x55, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52, 0x35, 0x49, 0x44, 0x49, 0x77, 0x4D, 0x54, 0x63, 0x77, 0x64, 0x6A, 0x41, 0x51, 0x0A, 0x42, 0x67, 0x63, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, ++ 0x51, 0x49, 0x42, 0x42, 0x67, 0x55, 0x72, 0x67, 0x51, 0x51, 0x41, 0x49, 0x67, 0x4E, 0x69, 0x41, 0x41, 0x54, 0x55, 0x76, 0x44, 0x30, 0x43, 0x51, 0x6E, 0x56, 0x42, 0x45, 0x79, 0x50, 0x4E, 0x67, 0x41, 0x53, 0x47, 0x41, 0x6C, 0x45, 0x76, 0x61, ++ 0x71, 0x69, 0x42, 0x59, 0x67, 0x74, 0x6C, 0x7A, 0x50, 0x62, 0x4B, 0x6E, 0x52, 0x35, 0x76, 0x53, 0x6D, 0x5A, 0x52, 0x6F, 0x67, 0x50, 0x5A, 0x6E, 0x5A, 0x48, 0x36, 0x0A, 0x74, 0x68, 0x61, 0x78, 0x6A, 0x47, 0x37, 0x65, 0x66, 0x4D, 0x33, 0x62, ++ 0x65, 0x61, 0x59, 0x76, 0x7A, 0x72, 0x76, 0x4F, 0x63, 0x53, 0x2F, 0x6C, 0x70, 0x61, 0x73, 0x6F, 0x37, 0x47, 0x4D, 0x45, 0x5A, 0x70, 0x6E, 0x34, 0x2B, 0x76, 0x4B, 0x54, 0x45, 0x41, 0x58, 0x68, 0x67, 0x53, 0x68, 0x43, 0x34, 0x38, 0x5A, 0x6F, ++ 0x39, 0x4F, 0x59, 0x62, 0x68, 0x47, 0x42, 0x4B, 0x69, 0x61, 0x2F, 0x74, 0x65, 0x51, 0x38, 0x37, 0x7A, 0x76, 0x48, 0x32, 0x52, 0x50, 0x55, 0x42, 0x0A, 0x65, 0x4D, 0x43, 0x6A, 0x56, 0x44, 0x42, 0x53, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, ++ 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x68, 0x6A, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x42, 0x30, ++ 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x54, 0x49, 0x79, 0x35, 0x6C, 0x79, 0x63, 0x46, 0x49, 0x4D, 0x0A, 0x2B, 0x4F, 0x61, 0x2B, 0x73, 0x67, 0x52, 0x58, 0x4B, 0x53, 0x72, 0x50, 0x51, 0x68, 0x44, 0x74, 0x4E, 0x54, ++ 0x41, 0x51, 0x42, 0x67, 0x6B, 0x72, 0x42, 0x67, 0x45, 0x45, 0x41, 0x59, 0x49, 0x33, 0x46, 0x51, 0x45, 0x45, 0x41, 0x77, 0x49, 0x42, 0x41, 0x44, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x77, ++ 0x4E, 0x6F, 0x41, 0x44, 0x42, 0x6C, 0x41, 0x6A, 0x42, 0x59, 0x38, 0x6B, 0x33, 0x71, 0x44, 0x50, 0x6C, 0x66, 0x0A, 0x58, 0x75, 0x35, 0x67, 0x4B, 0x63, 0x73, 0x36, 0x38, 0x74, 0x76, 0x57, 0x4D, 0x6F, 0x51, 0x5A, 0x50, 0x33, 0x7A, 0x56, 0x4C, ++ 0x38, 0x4B, 0x78, 0x7A, 0x4A, 0x4F, 0x75, 0x55, 0x4C, 0x73, 0x4A, 0x4D, 0x73, 0x62, 0x47, 0x37, 0x58, 0x37, 0x4A, 0x4E, 0x70, 0x51, 0x53, 0x35, 0x47, 0x69, 0x46, 0x42, 0x71, 0x49, 0x62, 0x30, 0x43, 0x38, 0x43, 0x4D, 0x51, 0x43, 0x5A, 0x36, ++ 0x52, 0x61, 0x30, 0x44, 0x76, 0x70, 0x57, 0x53, 0x4E, 0x53, 0x6B, 0x4D, 0x42, 0x61, 0x52, 0x0A, 0x65, 0x4E, 0x74, 0x55, 0x6A, 0x47, 0x55, 0x42, 0x69, 0x75, 0x64, 0x51, 0x5A, 0x73, 0x49, 0x78, 0x74, 0x7A, 0x6D, 0x36, 0x75, 0x42, 0x6F, 0x69, ++ 0x42, 0x30, 0x37, 0x38, 0x61, 0x31, 0x51, 0x57, 0x49, 0x50, 0x38, 0x72, 0x74, 0x65, 0x64, 0x4D, 0x44, 0x45, 0x32, 0x6D, 0x54, 0x33, 0x4D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, ++ 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, ++ 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x32, 0x30, 0x31, 0x37, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, ++ 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x71, 0x44, 0x43, 0x43, 0x41, 0x35, 0x43, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x48, 0x74, 0x4F, 0x58, 0x43, 0x56, 0x2F, 0x59, ++ 0x74, 0x4C, 0x4E, 0x48, 0x63, 0x42, 0x36, 0x71, 0x76, 0x6E, 0x39, 0x46, 0x73, 0x7A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x77, 0x46, 0x41, 0x44, 0x42, 0x6C, 0x4D, 0x51, 0x73, 0x77, ++ 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0A, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x65, 0x4D, 0x42, 0x77, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x56, 0x54, 0x57, 0x6C, 0x6A, 0x63, 0x6D, 0x39, 0x7A, 0x62, 0x32, 0x5A, ++ 0x30, 0x49, 0x45, 0x4E, 0x76, 0x63, 0x6E, 0x42, 0x76, 0x63, 0x6D, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x4D, 0x54, 0x59, 0x77, 0x4E, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x79, 0x31, 0x4E, 0x61, 0x57, 0x4E, 0x79, 0x62, 0x33, 0x4E, ++ 0x76, 0x5A, 0x6E, 0x51, 0x67, 0x0A, 0x55, 0x6C, 0x4E, 0x42, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6C, 0x6D, 0x61, 0x57, 0x4E, 0x68, 0x64, 0x47, 0x55, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, ++ 0x39, 0x79, 0x61, 0x58, 0x52, 0x35, 0x49, 0x44, 0x49, 0x77, 0x4D, 0x54, 0x63, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x54, 0x6B, 0x78, 0x4D, 0x6A, 0x45, 0x34, 0x4D, 0x6A, 0x49, 0x31, 0x4D, 0x54, 0x49, 0x79, 0x57, 0x68, 0x63, 0x4E, 0x4E, 0x44, ++ 0x49, 0x77, 0x0A, 0x4E, 0x7A, 0x45, 0x34, 0x4D, 0x6A, 0x4D, 0x77, 0x4D, 0x44, 0x49, 0x7A, 0x57, 0x6A, 0x42, 0x6C, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x65, 0x4D, ++ 0x42, 0x77, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x56, 0x54, 0x57, 0x6C, 0x6A, 0x63, 0x6D, 0x39, 0x7A, 0x62, 0x32, 0x5A, 0x30, 0x49, 0x45, 0x4E, 0x76, 0x63, 0x6E, 0x42, 0x76, 0x63, 0x6D, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x0A, ++ 0x4D, 0x54, 0x59, 0x77, 0x4E, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x79, 0x31, 0x4E, 0x61, 0x57, 0x4E, 0x79, 0x62, 0x33, 0x4E, 0x76, 0x5A, 0x6E, 0x51, 0x67, 0x55, 0x6C, 0x4E, 0x42, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, ++ 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6C, 0x6D, 0x61, 0x57, 0x4E, 0x68, 0x64, 0x47, 0x55, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52, 0x35, 0x49, 0x44, 0x49, 0x77, 0x4D, 0x54, 0x63, 0x77, 0x0A, 0x67, 0x67, 0x49, ++ 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x44, ++ 0x4B, 0x57, 0x37, 0x36, 0x55, 0x4D, 0x34, 0x77, 0x70, 0x6C, 0x5A, 0x45, 0x57, 0x43, 0x70, 0x57, 0x39, 0x52, 0x32, 0x4C, 0x42, 0x69, 0x66, 0x4F, 0x5A, 0x4E, 0x74, 0x39, 0x47, 0x6B, 0x4D, 0x6D, 0x6C, 0x0A, 0x37, 0x58, 0x68, 0x71, 0x62, 0x30, ++ 0x65, 0x52, 0x61, 0x50, 0x67, 0x6E, 0x5A, 0x31, 0x41, 0x7A, 0x48, 0x61, 0x47, 0x6D, 0x2B, 0x2B, 0x44, 0x6C, 0x51, 0x36, 0x4F, 0x45, 0x41, 0x6C, 0x63, 0x42, 0x58, 0x5A, 0x78, 0x49, 0x51, 0x49, 0x4A, 0x54, 0x45, 0x4C, 0x79, 0x2F, 0x78, 0x7A, ++ 0x74, 0x6F, 0x6B, 0x4C, 0x61, 0x43, 0x4C, 0x65, 0x58, 0x30, 0x5A, 0x64, 0x44, 0x4D, 0x62, 0x52, 0x6E, 0x4D, 0x6C, 0x66, 0x6C, 0x37, 0x72, 0x45, 0x71, 0x55, 0x72, 0x51, 0x37, 0x65, 0x0A, 0x53, 0x30, 0x4D, 0x64, 0x68, 0x77, 0x65, 0x53, 0x45, ++ 0x35, 0x43, 0x41, 0x67, 0x32, 0x51, 0x31, 0x4F, 0x51, 0x54, 0x38, 0x35, 0x65, 0x6C, 0x73, 0x73, 0x37, 0x59, 0x66, 0x55, 0x4A, 0x51, 0x34, 0x5A, 0x56, 0x42, 0x63, 0x46, 0x30, 0x61, 0x35, 0x74, 0x6F, 0x57, 0x31, 0x48, 0x4C, 0x55, 0x58, 0x36, ++ 0x4E, 0x5A, 0x46, 0x6E, 0x64, 0x69, 0x79, 0x4A, 0x72, 0x44, 0x4B, 0x78, 0x48, 0x42, 0x4B, 0x72, 0x6D, 0x43, 0x6B, 0x33, 0x62, 0x50, 0x5A, 0x37, 0x50, 0x77, 0x37, 0x0A, 0x31, 0x56, 0x64, 0x79, 0x76, 0x44, 0x2F, 0x49, 0x79, 0x62, 0x4C, 0x65, ++ 0x53, 0x32, 0x76, 0x34, 0x49, 0x32, 0x77, 0x44, 0x77, 0x41, 0x57, 0x39, 0x6C, 0x63, 0x66, 0x4E, 0x63, 0x7A, 0x74, 0x6D, 0x67, 0x47, 0x54, 0x6A, 0x47, 0x71, 0x77, 0x75, 0x2B, 0x55, 0x63, 0x46, 0x38, 0x67, 0x61, 0x32, 0x6D, 0x33, 0x50, 0x31, ++ 0x65, 0x44, 0x4E, 0x62, 0x78, 0x36, 0x48, 0x37, 0x4A, 0x79, 0x71, 0x68, 0x74, 0x4A, 0x71, 0x52, 0x6A, 0x4A, 0x48, 0x54, 0x4F, 0x6F, 0x49, 0x2B, 0x0A, 0x64, 0x6B, 0x43, 0x30, 0x7A, 0x56, 0x4A, 0x68, 0x55, 0x58, 0x41, 0x6F, 0x50, 0x38, 0x58, ++ 0x46, 0x57, 0x76, 0x4C, 0x4A, 0x6A, 0x45, 0x6D, 0x37, 0x46, 0x46, 0x74, 0x4E, 0x79, 0x50, 0x39, 0x6E, 0x54, 0x55, 0x77, 0x53, 0x6C, 0x71, 0x33, 0x31, 0x2F, 0x6E, 0x69, 0x6F, 0x6C, 0x34, 0x66, 0x58, 0x2F, 0x56, 0x34, 0x67, 0x67, 0x4E, 0x79, ++ 0x68, 0x53, 0x79, 0x4C, 0x37, 0x31, 0x49, 0x6D, 0x74, 0x75, 0x73, 0x35, 0x48, 0x6C, 0x30, 0x64, 0x56, 0x65, 0x34, 0x39, 0x46, 0x0A, 0x79, 0x47, 0x63, 0x6F, 0x68, 0x4A, 0x55, 0x63, 0x61, 0x44, 0x44, 0x76, 0x37, 0x30, 0x6E, 0x67, 0x4E, 0x58, ++ 0x74, 0x6B, 0x35, 0x35, 0x69, 0x77, 0x6C, 0x4E, 0x70, 0x4E, 0x68, 0x54, 0x73, 0x2B, 0x56, 0x63, 0x51, 0x6F, 0x72, 0x31, 0x66, 0x7A, 0x6E, 0x68, 0x50, 0x62, 0x52, 0x69, 0x65, 0x66, 0x48, 0x71, 0x4A, 0x65, 0x52, 0x49, 0x4F, 0x6B, 0x70, 0x63, ++ 0x72, 0x56, 0x45, 0x37, 0x4E, 0x4C, 0x50, 0x38, 0x54, 0x6A, 0x77, 0x75, 0x61, 0x47, 0x59, 0x61, 0x52, 0x53, 0x0A, 0x4D, 0x4C, 0x6C, 0x36, 0x49, 0x45, 0x39, 0x76, 0x44, 0x7A, 0x68, 0x54, 0x79, 0x7A, 0x4D, 0x4D, 0x45, 0x79, 0x75, 0x50, 0x31, ++ 0x70, 0x71, 0x39, 0x4B, 0x73, 0x67, 0x74, 0x73, 0x52, 0x78, 0x39, 0x53, 0x31, 0x48, 0x4B, 0x52, 0x39, 0x46, 0x49, 0x4A, 0x33, 0x4A, 0x64, 0x68, 0x2B, 0x76, 0x56, 0x52, 0x65, 0x5A, 0x49, 0x5A, 0x5A, 0x32, 0x76, 0x55, 0x70, 0x43, 0x36, 0x57, ++ 0x36, 0x49, 0x59, 0x5A, 0x56, 0x63, 0x53, 0x6E, 0x32, 0x69, 0x35, 0x31, 0x42, 0x56, 0x72, 0x0A, 0x6C, 0x4D, 0x52, 0x70, 0x49, 0x70, 0x6A, 0x30, 0x4D, 0x2B, 0x44, 0x74, 0x2B, 0x56, 0x47, 0x4F, 0x51, 0x56, 0x44, 0x4A, 0x4E, 0x45, 0x39, 0x32, ++ 0x6B, 0x4B, 0x7A, 0x38, 0x4F, 0x4D, 0x48, 0x59, 0x34, 0x58, 0x75, 0x35, 0x34, 0x2B, 0x4F, 0x55, 0x34, 0x55, 0x5A, 0x70, 0x79, 0x77, 0x34, 0x4B, 0x55, 0x47, 0x73, 0x54, 0x75, 0x71, 0x77, 0x50, 0x4E, 0x31, 0x71, 0x33, 0x45, 0x72, 0x57, 0x51, ++ 0x67, 0x52, 0x35, 0x57, 0x72, 0x6C, 0x63, 0x69, 0x68, 0x74, 0x6E, 0x4A, 0x0A, 0x30, 0x74, 0x48, 0x58, 0x55, 0x65, 0x4F, 0x72, 0x4F, 0x38, 0x5A, 0x56, 0x2F, 0x52, 0x34, 0x4F, 0x30, 0x33, 0x51, 0x4B, 0x30, 0x64, 0x71, 0x71, 0x36, 0x6D, 0x6D, ++ 0x34, 0x6C, 0x79, 0x69, 0x50, 0x53, 0x4D, 0x51, 0x48, 0x2B, 0x46, 0x4A, 0x44, 0x4F, 0x76, 0x54, 0x4B, 0x56, 0x54, 0x55, 0x73, 0x73, 0x4B, 0x5A, 0x71, 0x77, 0x4A, 0x7A, 0x35, 0x38, 0x6F, 0x48, 0x68, 0x45, 0x6D, 0x72, 0x41, 0x52, 0x64, 0x6C, ++ 0x6E, 0x73, 0x38, 0x37, 0x2F, 0x49, 0x36, 0x4B, 0x4A, 0x0A, 0x43, 0x6C, 0x54, 0x55, 0x46, 0x4C, 0x6B, 0x71, 0x71, 0x4E, 0x66, 0x73, 0x2B, 0x61, 0x76, 0x4E, 0x4A, 0x56, 0x67, 0x79, 0x65, 0x59, 0x2B, 0x51, 0x57, 0x35, 0x67, 0x35, 0x78, 0x41, ++ 0x67, 0x47, 0x77, 0x61, 0x78, 0x2F, 0x44, 0x6A, 0x30, 0x41, 0x70, 0x51, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6F, 0x31, 0x51, 0x77, 0x55, 0x6A, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, ++ 0x4D, 0x43, 0x41, 0x59, 0x59, 0x77, 0x0A, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, ++ 0x67, 0x51, 0x55, 0x43, 0x63, 0x74, 0x5A, 0x66, 0x34, 0x61, 0x79, 0x63, 0x49, 0x38, 0x61, 0x77, 0x7A, 0x6E, 0x6A, 0x77, 0x4E, 0x6E, 0x70, 0x76, 0x37, 0x74, 0x4E, 0x73, 0x69, 0x4D, 0x77, 0x45, 0x41, 0x59, 0x4A, 0x4B, 0x77, 0x59, 0x42, 0x42, ++ 0x41, 0x47, 0x43, 0x0A, 0x4E, 0x78, 0x55, 0x42, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x51, 0x41, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4D, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x42, ++ 0x41, 0x4B, 0x79, 0x76, 0x50, 0x6C, 0x33, 0x43, 0x45, 0x5A, 0x61, 0x4A, 0x6A, 0x71, 0x50, 0x6E, 0x6B, 0x74, 0x61, 0x58, 0x46, 0x62, 0x67, 0x54, 0x6F, 0x71, 0x5A, 0x43, 0x4C, 0x67, 0x4C, 0x4E, 0x46, 0x67, 0x56, 0x5A, 0x4A, 0x38, 0x6F, 0x67, ++ 0x0A, 0x36, 0x4C, 0x71, 0x34, 0x36, 0x42, 0x72, 0x73, 0x54, 0x61, 0x69, 0x58, 0x56, 0x71, 0x35, 0x6C, 0x51, 0x37, 0x47, 0x50, 0x41, 0x4A, 0x74, 0x53, 0x7A, 0x56, 0x58, 0x4E, 0x55, 0x7A, 0x6C, 0x74, 0x59, 0x6B, 0x79, 0x4C, 0x44, 0x56, 0x74, ++ 0x38, 0x4C, 0x6B, 0x53, 0x2F, 0x67, 0x78, 0x43, 0x50, 0x38, 0x31, 0x4F, 0x43, 0x67, 0x4D, 0x4E, 0x50, 0x4F, 0x73, 0x64, 0x75, 0x45, 0x54, 0x2F, 0x6D, 0x34, 0x78, 0x61, 0x52, 0x68, 0x50, 0x74, 0x74, 0x68, 0x48, 0x38, 0x30, 0x0A, 0x64, 0x4B, ++ 0x32, 0x4A, 0x70, 0x38, 0x36, 0x35, 0x31, 0x39, 0x65, 0x66, 0x68, 0x47, 0x53, 0x53, 0x76, 0x70, 0x57, 0x68, 0x72, 0x51, 0x6C, 0x54, 0x4D, 0x39, 0x33, 0x75, 0x43, 0x75, 0x70, 0x4B, 0x55, 0x59, 0x35, 0x76, 0x56, 0x61, 0x75, 0x36, 0x74, 0x5A, ++ 0x52, 0x47, 0x72, 0x6F, 0x78, 0x2F, 0x32, 0x4B, 0x4A, 0x51, 0x4A, 0x57, 0x56, 0x67, 0x67, 0x45, 0x62, 0x62, 0x4D, 0x77, 0x53, 0x75, 0x62, 0x4C, 0x57, 0x59, 0x64, 0x46, 0x51, 0x6C, 0x33, 0x4A, 0x50, 0x6B, 0x0A, 0x2B, 0x4F, 0x4E, 0x56, 0x46, ++ 0x54, 0x32, 0x34, 0x62, 0x63, 0x4D, 0x4B, 0x70, 0x42, 0x4C, 0x42, 0x61, 0x59, 0x56, 0x75, 0x33, 0x32, 0x54, 0x78, 0x55, 0x35, 0x6E, 0x68, 0x53, 0x6E, 0x55, 0x67, 0x6E, 0x5A, 0x55, 0x50, 0x35, 0x4E, 0x62, 0x63, 0x41, 0x2F, 0x46, 0x5A, 0x47, ++ 0x4F, 0x68, 0x48, 0x69, 0x62, 0x4A, 0x58, 0x57, 0x70, 0x53, 0x32, 0x71, 0x64, 0x67, 0x58, 0x4B, 0x78, 0x64, 0x4A, 0x35, 0x58, 0x62, 0x4C, 0x77, 0x56, 0x61, 0x5A, 0x4F, 0x6A, 0x65, 0x78, 0x0A, 0x2F, 0x32, 0x6B, 0x73, 0x6B, 0x5A, 0x47, 0x54, ++ 0x34, 0x64, 0x39, 0x4D, 0x6F, 0x7A, 0x64, 0x32, 0x54, 0x61, 0x47, 0x66, 0x2B, 0x47, 0x30, 0x65, 0x48, 0x64, 0x50, 0x36, 0x37, 0x50, 0x76, 0x30, 0x52, 0x52, 0x30, 0x54, 0x62, 0x63, 0x2F, 0x33, 0x57, 0x65, 0x55, 0x69, 0x4A, 0x33, 0x49, 0x72, ++ 0x68, 0x76, 0x4E, 0x58, 0x75, 0x7A, 0x44, 0x74, 0x4A, 0x45, 0x33, 0x63, 0x66, 0x56, 0x61, 0x37, 0x6F, 0x37, 0x50, 0x34, 0x4E, 0x48, 0x6D, 0x4A, 0x77, 0x65, 0x44, 0x79, 0x0A, 0x41, 0x6D, 0x48, 0x33, 0x70, 0x76, 0x77, 0x50, 0x75, 0x78, 0x77, ++ 0x58, 0x43, 0x36, 0x35, 0x42, 0x32, 0x58, 0x79, 0x39, 0x4A, 0x36, 0x50, 0x39, 0x4C, 0x6A, 0x72, 0x52, 0x6B, 0x35, 0x53, 0x78, 0x63, 0x78, 0x30, 0x6B, 0x69, 0x36, 0x39, 0x62, 0x49, 0x49, 0x6D, 0x74, 0x74, 0x32, 0x64, 0x6D, 0x65, 0x66, 0x55, ++ 0x36, 0x78, 0x71, 0x61, 0x57, 0x4D, 0x2F, 0x35, 0x54, 0x6B, 0x73, 0x68, 0x47, 0x73, 0x52, 0x47, 0x52, 0x78, 0x70, 0x6C, 0x2F, 0x6A, 0x38, 0x6E, 0x57, 0x0A, 0x5A, 0x6A, 0x45, 0x67, 0x51, 0x52, 0x43, 0x48, 0x4C, 0x51, 0x7A, 0x57, 0x77, 0x61, ++ 0x38, 0x30, 0x6D, 0x4D, 0x70, 0x6B, 0x67, 0x2F, 0x73, 0x54, 0x56, 0x39, 0x48, 0x42, 0x38, 0x44, 0x78, 0x36, 0x6A, 0x4B, 0x58, 0x42, 0x2F, 0x5A, 0x55, 0x68, 0x6F, 0x48, 0x48, 0x42, 0x6B, 0x32, 0x64, 0x78, 0x45, 0x75, 0x71, 0x50, 0x69, 0x41, ++ 0x70, 0x70, 0x47, 0x57, 0x53, 0x5A, 0x49, 0x31, 0x62, 0x37, 0x72, 0x43, 0x6F, 0x75, 0x63, 0x4C, 0x35, 0x6D, 0x78, 0x41, 0x79, 0x45, 0x0A, 0x37, 0x2B, 0x57, 0x4C, 0x38, 0x35, 0x4D, 0x42, 0x2B, 0x47, 0x71, 0x51, 0x6B, 0x32, 0x64, 0x4C, 0x73, ++ 0x6D, 0x69, 0x6A, 0x74, 0x57, 0x4B, 0x50, 0x36, 0x54, 0x2B, 0x4D, 0x65, 0x6A, 0x74, 0x65, 0x44, 0x2B, 0x65, 0x4D, 0x75, 0x4D, 0x5A, 0x38, 0x37, 0x7A, 0x66, 0x39, 0x64, 0x4F, 0x4C, 0x49, 0x54, 0x7A, 0x4E, 0x79, 0x34, 0x5A, 0x51, 0x35, 0x62, ++ 0x62, 0x30, 0x53, 0x72, 0x37, 0x34, 0x4D, 0x54, 0x6E, 0x42, 0x38, 0x47, 0x32, 0x2B, 0x4E, 0x73, 0x7A, 0x4B, 0x54, 0x0A, 0x63, 0x30, 0x51, 0x57, 0x62, 0x65, 0x6A, 0x30, 0x39, 0x2B, 0x43, 0x56, 0x67, 0x49, 0x2B, 0x57, 0x58, 0x54, 0x69, 0x6B, ++ 0x39, 0x4B, 0x76, 0x65, 0x43, 0x6A, 0x43, 0x48, 0x6B, 0x39, 0x68, 0x4E, 0x41, 0x48, 0x46, 0x69, 0x52, 0x53, 0x64, 0x4C, 0x4F, 0x6B, 0x4B, 0x45, 0x57, 0x33, 0x39, 0x6C, 0x74, 0x32, 0x63, 0x30, 0x55, 0x69, 0x32, 0x63, 0x46, 0x6D, 0x75, 0x71, ++ 0x71, 0x4E, 0x68, 0x37, 0x6F, 0x30, 0x4A, 0x4D, 0x63, 0x63, 0x63, 0x4D, 0x79, 0x6A, 0x36, 0x44, 0x0A, 0x35, 0x4B, 0x62, 0x76, 0x74, 0x77, 0x45, 0x77, 0x58, 0x6C, 0x47, 0x6A, 0x65, 0x66, 0x56, 0x77, 0x61, 0x61, 0x5A, 0x42, 0x52, 0x41, 0x2B, ++ 0x47, 0x73, 0x43, 0x79, 0x52, 0x78, 0x6A, 0x33, 0x71, 0x72, 0x67, 0x2B, 0x45, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, ++ 0x0A, 0x65, 0x2D, 0x53, 0x7A, 0x69, 0x67, 0x6E, 0x6F, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, 0x37, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x51, 0x44, 0x43, ++ 0x43, 0x41, 0x65, 0x57, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x4D, 0x41, 0x56, 0x52, 0x49, 0x37, 0x79, 0x48, 0x39, 0x6C, 0x31, 0x6B, 0x4E, 0x39, 0x51, 0x51, 0x4B, 0x4D, 0x41, 0x6F, 0x47, 0x43, 0x43, 0x71, 0x47, 0x53, 0x4D, 0x34, ++ 0x39, 0x42, 0x41, 0x4D, 0x43, 0x4D, 0x48, 0x45, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x68, 0x56, 0x4D, 0x52, 0x45, 0x77, 0x0A, 0x44, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x48, 0x44, 0x41, ++ 0x68, 0x43, 0x64, 0x57, 0x52, 0x68, 0x63, 0x47, 0x56, 0x7A, 0x64, 0x44, 0x45, 0x57, 0x4D, 0x42, 0x51, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x4E, 0x54, 0x57, 0x6C, 0x6A, 0x63, 0x6D, 0x39, 0x7A, 0x5A, 0x57, 0x4D, 0x67, 0x54, 0x48, ++ 0x52, 0x6B, 0x4C, 0x6A, 0x45, 0x58, 0x4D, 0x42, 0x55, 0x47, 0x41, 0x31, 0x55, 0x45, 0x59, 0x51, 0x77, 0x4F, 0x56, 0x6B, 0x46, 0x55, 0x53, 0x46, 0x55, 0x74, 0x0A, 0x4D, 0x6A, 0x4D, 0x31, 0x4F, 0x44, 0x51, 0x30, 0x4F, 0x54, 0x63, 0x78, 0x48, ++ 0x6A, 0x41, 0x63, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x46, 0x57, 0x55, 0x74, 0x55, 0x33, 0x70, 0x70, 0x5A, 0x32, 0x35, 0x76, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x4D, 0x6A, 0x41, 0x78, 0x4E, ++ 0x7A, 0x41, 0x65, 0x46, 0x77, 0x30, 0x78, 0x4E, 0x7A, 0x41, 0x34, 0x4D, 0x6A, 0x49, 0x78, 0x4D, 0x6A, 0x41, 0x33, 0x4D, 0x44, 0x5A, 0x61, 0x0A, 0x46, 0x77, 0x30, 0x30, 0x4D, 0x6A, 0x41, 0x34, 0x4D, 0x6A, 0x49, 0x78, 0x4D, 0x6A, 0x41, 0x33, ++ 0x4D, 0x44, 0x5A, 0x61, 0x4D, 0x48, 0x45, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x68, 0x56, 0x4D, 0x52, 0x45, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x48, 0x44, 0x41, 0x68, 0x43, ++ 0x64, 0x57, 0x52, 0x68, 0x63, 0x47, 0x56, 0x7A, 0x64, 0x44, 0x45, 0x57, 0x4D, 0x42, 0x51, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0A, 0x43, 0x67, 0x77, 0x4E, 0x54, 0x57, 0x6C, 0x6A, 0x63, 0x6D, 0x39, 0x7A, 0x5A, 0x57, 0x4D, 0x67, 0x54, 0x48, 0x52, ++ 0x6B, 0x4C, 0x6A, 0x45, 0x58, 0x4D, 0x42, 0x55, 0x47, 0x41, 0x31, 0x55, 0x45, 0x59, 0x51, 0x77, 0x4F, 0x56, 0x6B, 0x46, 0x55, 0x53, 0x46, 0x55, 0x74, 0x4D, 0x6A, 0x4D, 0x31, 0x4F, 0x44, 0x51, 0x30, 0x4F, 0x54, 0x63, 0x78, 0x48, 0x6A, 0x41, ++ 0x63, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x46, 0x57, 0x55, 0x74, 0x55, 0x33, 0x70, 0x70, 0x0A, 0x5A, 0x32, 0x35, 0x76, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x4D, 0x6A, 0x41, 0x78, 0x4E, 0x7A, ++ 0x42, 0x5A, 0x4D, 0x42, 0x4D, 0x47, 0x42, 0x79, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x41, 0x67, 0x45, 0x47, 0x43, 0x43, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x41, 0x77, 0x45, 0x48, 0x41, 0x30, 0x49, 0x41, 0x42, 0x4A, 0x62, 0x63, 0x50, 0x59, ++ 0x72, 0x59, 0x73, 0x48, 0x74, 0x76, 0x78, 0x69, 0x65, 0x2B, 0x52, 0x4A, 0x43, 0x78, 0x0A, 0x73, 0x31, 0x59, 0x56, 0x65, 0x34, 0x35, 0x44, 0x4A, 0x48, 0x30, 0x61, 0x68, 0x46, 0x6E, 0x75, 0x59, 0x32, 0x69, 0x79, 0x78, 0x6C, 0x36, 0x48, 0x30, ++ 0x42, 0x56, 0x49, 0x48, 0x71, 0x69, 0x51, 0x72, 0x62, 0x31, 0x54, 0x6F, 0x74, 0x72, 0x65, 0x4F, 0x70, 0x43, 0x6D, 0x59, 0x46, 0x39, 0x6F, 0x4D, 0x72, 0x57, 0x47, 0x51, 0x64, 0x2B, 0x48, 0x57, 0x79, 0x78, 0x37, 0x78, 0x66, 0x35, 0x38, 0x65, ++ 0x74, 0x71, 0x6A, 0x59, 0x7A, 0x42, 0x68, 0x4D, 0x41, 0x38, 0x47, 0x0A, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, ++ 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x53, 0x48, 0x45, 0x52, 0x55, 0x49, 0x30, 0x61, 0x72, 0x42, 0x65, 0x41, 0x79, 0x78, ++ 0x72, 0x38, 0x37, 0x47, 0x79, 0x5A, 0x44, 0x76, 0x0A, 0x76, 0x7A, 0x41, 0x45, 0x77, 0x44, 0x41, 0x66, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x53, 0x4D, 0x45, 0x47, 0x44, 0x41, 0x57, 0x67, 0x42, 0x53, 0x48, 0x45, 0x52, 0x55, 0x49, 0x30, 0x61, 0x72, ++ 0x42, 0x65, 0x41, 0x79, 0x78, 0x72, 0x38, 0x37, 0x47, 0x79, 0x5A, 0x44, 0x76, 0x76, 0x7A, 0x41, 0x45, 0x77, 0x44, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x67, 0x4E, 0x4A, 0x41, 0x44, 0x42, ++ 0x47, 0x41, 0x69, 0x45, 0x41, 0x0A, 0x74, 0x56, 0x66, 0x64, 0x31, 0x34, 0x70, 0x56, 0x43, 0x7A, 0x62, 0x68, 0x68, 0x6B, 0x54, 0x36, 0x31, 0x4E, 0x6C, 0x6F, 0x6A, 0x62, 0x6A, 0x63, 0x49, 0x34, 0x71, 0x4B, 0x44, 0x64, 0x51, 0x76, 0x66, 0x65, ++ 0x70, 0x7A, 0x37, 0x4C, 0x39, 0x4E, 0x62, 0x4B, 0x67, 0x43, 0x49, 0x51, 0x44, 0x4C, 0x70, 0x62, 0x51, 0x53, 0x2B, 0x75, 0x65, 0x31, 0x36, 0x4D, 0x39, 0x2B, 0x6B, 0x2F, 0x7A, 0x7A, 0x4E, 0x59, 0x39, 0x76, 0x54, 0x6C, 0x70, 0x38, 0x74, 0x4C, ++ 0x78, 0x4F, 0x0A, 0x73, 0x76, 0x78, 0x79, 0x71, 0x6C, 0x74, 0x5A, 0x2B, 0x65, 0x66, 0x63, 0x4D, 0x51, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, ++ 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x63, 0x65, 0x72, 0x74, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x47, 0x32, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x52, ++ 0x7A, 0x43, 0x43, 0x41, 0x79, 0x2B, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x4A, 0x45, 0x51, 0x41, 0x30, 0x74, 0x6B, 0x37, 0x47, 0x4E, 0x69, 0x30, 0x32, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, ++ 0x51, 0x45, 0x42, 0x43, 0x77, 0x55, 0x41, 0x4D, 0x45, 0x45, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6C, 0x4A, 0x50, 0x4D, 0x52, 0x51, 0x77, 0x0A, 0x45, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, ++ 0x45, 0x77, 0x74, 0x44, 0x52, 0x56, 0x4A, 0x55, 0x55, 0x30, 0x6C, 0x48, 0x54, 0x69, 0x42, 0x54, 0x51, 0x54, 0x45, 0x63, 0x4D, 0x42, 0x6F, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4D, 0x54, 0x59, 0x32, 0x56, 0x79, 0x64, 0x46, 0x4E, 0x4A, ++ 0x52, 0x30, 0x34, 0x67, 0x55, 0x6B, 0x39, 0x50, 0x56, 0x43, 0x42, 0x44, 0x51, 0x53, 0x42, 0x48, 0x4D, 0x6A, 0x41, 0x65, 0x46, 0x77, 0x30, 0x78, 0x4E, 0x7A, 0x41, 0x79, 0x0A, 0x4D, 0x44, 0x59, 0x77, 0x4F, 0x54, 0x49, 0x33, 0x4D, 0x7A, 0x56, ++ 0x61, 0x46, 0x77, 0x30, 0x30, 0x4D, 0x6A, 0x41, 0x79, 0x4D, 0x44, 0x59, 0x77, 0x4F, 0x54, 0x49, 0x33, 0x4D, 0x7A, 0x56, 0x61, 0x4D, 0x45, 0x45, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6C, 0x4A, ++ 0x50, 0x4D, 0x52, 0x51, 0x77, 0x45, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x77, 0x74, 0x44, 0x52, 0x56, 0x4A, 0x55, 0x55, 0x30, 0x6C, 0x48, 0x0A, 0x54, 0x69, 0x42, 0x54, 0x51, 0x54, 0x45, 0x63, 0x4D, 0x42, 0x6F, 0x47, 0x41, 0x31, ++ 0x55, 0x45, 0x43, 0x78, 0x4D, 0x54, 0x59, 0x32, 0x56, 0x79, 0x64, 0x46, 0x4E, 0x4A, 0x52, 0x30, 0x34, 0x67, 0x55, 0x6B, 0x39, 0x50, 0x56, 0x43, 0x42, 0x44, 0x51, 0x53, 0x42, 0x48, 0x4D, 0x6A, 0x43, 0x43, 0x41, 0x69, 0x49, 0x77, 0x44, 0x51, ++ 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x50, 0x0A, 0x41, 0x44, 0x43, 0x43, 0x41, 0x67, 0x6F, 0x43, 0x67, 0x67, 0x49, 0x42, 0x41, 0x4D, 0x44, 0x46, 0x64, ++ 0x52, 0x6D, 0x52, 0x66, 0x55, 0x52, 0x30, 0x64, 0x49, 0x66, 0x2B, 0x44, 0x6A, 0x75, 0x57, 0x33, 0x4E, 0x67, 0x42, 0x46, 0x73, 0x7A, 0x75, 0x59, 0x35, 0x48, 0x6E, 0x43, 0x32, 0x2F, 0x4F, 0x4F, 0x77, 0x70, 0x70, 0x47, 0x6E, 0x7A, 0x43, 0x34, ++ 0x36, 0x2B, 0x43, 0x6A, 0x6F, 0x62, 0x58, 0x58, 0x6F, 0x39, 0x58, 0x36, 0x39, 0x4D, 0x68, 0x57, 0x66, 0x30, 0x35, 0x0A, 0x4E, 0x30, 0x49, 0x77, 0x76, 0x6C, 0x44, 0x71, 0x74, 0x67, 0x2B, 0x70, 0x69, 0x4E, 0x67, 0x75, 0x4C, 0x57, 0x6B, 0x68, ++ 0x35, 0x39, 0x45, 0x33, 0x47, 0x45, 0x35, 0x39, 0x6B, 0x64, 0x55, 0x57, 0x58, 0x32, 0x74, 0x62, 0x41, 0x4D, 0x49, 0x35, 0x51, 0x77, 0x30, 0x32, 0x68, 0x56, 0x4B, 0x35, 0x55, 0x32, 0x55, 0x50, 0x48, 0x55, 0x4C, 0x6C, 0x6A, 0x38, 0x38, 0x46, ++ 0x30, 0x2B, 0x37, 0x63, 0x44, 0x42, 0x72, 0x5A, 0x75, 0x49, 0x74, 0x34, 0x49, 0x6D, 0x66, 0x6B, 0x0A, 0x61, 0x62, 0x42, 0x6F, 0x78, 0x54, 0x7A, 0x6B, 0x62, 0x46, 0x70, 0x47, 0x35, 0x38, 0x33, 0x48, 0x2B, 0x75, 0x2F, 0x45, 0x37, 0x45, 0x75, ++ 0x39, 0x61, 0x71, 0x53, 0x73, 0x2F, 0x63, 0x77, 0x6F, 0x55, 0x65, 0x2B, 0x53, 0x74, 0x43, 0x6D, 0x72, 0x71, 0x7A, 0x57, 0x61, 0x54, 0x4F, 0x54, 0x45, 0x43, 0x4D, 0x59, 0x6D, 0x7A, 0x50, 0x68, 0x70, 0x6E, 0x2B, 0x53, 0x63, 0x38, 0x43, 0x6E, ++ 0x54, 0x58, 0x50, 0x6E, 0x47, 0x46, 0x69, 0x57, 0x65, 0x49, 0x38, 0x4D, 0x67, 0x0A, 0x77, 0x54, 0x30, 0x50, 0x50, 0x7A, 0x68, 0x41, 0x73, 0x50, 0x36, 0x43, 0x52, 0x44, 0x69, 0x71, 0x57, 0x68, 0x71, 0x4B, 0x61, 0x32, 0x4E, 0x59, 0x4F, 0x4C, ++ 0x51, 0x56, 0x30, 0x37, 0x59, 0x52, 0x61, 0x58, 0x73, 0x65, 0x56, 0x4F, 0x36, 0x4D, 0x47, 0x69, 0x4B, 0x73, 0x63, 0x70, 0x63, 0x2F, 0x49, 0x31, 0x6D, 0x62, 0x79, 0x53, 0x4B, 0x45, 0x77, 0x51, 0x64, 0x50, 0x7A, 0x48, 0x2F, 0x69, 0x56, 0x38, ++ 0x6F, 0x53, 0x63, 0x4C, 0x75, 0x6D, 0x5A, 0x66, 0x4E, 0x70, 0x0A, 0x64, 0x57, 0x4F, 0x39, 0x6C, 0x66, 0x73, 0x62, 0x6C, 0x38, 0x33, 0x6B, 0x71, 0x4B, 0x2F, 0x32, 0x30, 0x55, 0x36, 0x6F, 0x32, 0x59, 0x70, 0x78, 0x4A, 0x4D, 0x30, 0x32, 0x50, ++ 0x62, 0x79, 0x57, 0x78, 0x50, 0x46, 0x73, 0x71, 0x61, 0x37, 0x6C, 0x7A, 0x77, 0x31, 0x75, 0x4B, 0x41, 0x32, 0x77, 0x44, 0x72, 0x58, 0x4B, 0x55, 0x58, 0x74, 0x34, 0x46, 0x4D, 0x4D, 0x67, 0x4C, 0x33, 0x2F, 0x37, 0x46, 0x46, 0x58, 0x68, 0x45, ++ 0x5A, 0x6E, 0x39, 0x31, 0x51, 0x71, 0x68, 0x0A, 0x6E, 0x67, 0x4C, 0x6A, 0x59, 0x6C, 0x2F, 0x72, 0x4E, 0x55, 0x73, 0x73, 0x75, 0x48, 0x4C, 0x6F, 0x50, 0x6A, 0x31, 0x50, 0x72, 0x43, 0x79, 0x37, 0x4C, 0x6F, 0x62, 0x69, 0x6F, 0x33, 0x61, 0x50, ++ 0x35, 0x5A, 0x4D, 0x71, 0x7A, 0x36, 0x57, 0x72, 0x79, 0x46, 0x79, 0x4E, 0x53, 0x77, 0x62, 0x2F, 0x45, 0x6B, 0x61, 0x73, 0x65, 0x4D, 0x73, 0x55, 0x42, 0x7A, 0x58, 0x67, 0x71, 0x64, 0x2B, 0x4C, 0x36, 0x61, 0x38, 0x56, 0x54, 0x78, 0x61, 0x4A, ++ 0x57, 0x37, 0x33, 0x32, 0x0A, 0x6A, 0x63, 0x5A, 0x5A, 0x72, 0x6F, 0x69, 0x46, 0x44, 0x73, 0x47, 0x4A, 0x36, 0x78, 0x39, 0x6E, 0x78, 0x55, 0x57, 0x4F, 0x2F, 0x32, 0x30, 0x33, 0x4E, 0x69, 0x74, 0x34, 0x5A, 0x6F, 0x4F, 0x52, 0x55, 0x53, 0x73, ++ 0x39, 0x2F, 0x31, 0x46, 0x33, 0x64, 0x6D, 0x4B, 0x68, 0x37, 0x47, 0x63, 0x2B, 0x50, 0x6F, 0x47, 0x44, 0x34, 0x46, 0x61, 0x70, 0x55, 0x42, 0x38, 0x66, 0x65, 0x70, 0x6D, 0x72, 0x59, 0x37, 0x2B, 0x45, 0x46, 0x33, 0x66, 0x78, 0x44, 0x54, 0x76, ++ 0x66, 0x0A, 0x39, 0x35, 0x78, 0x68, 0x73, 0x7A, 0x57, 0x59, 0x69, 0x6A, 0x71, 0x79, 0x37, 0x44, 0x77, 0x61, 0x4E, 0x7A, 0x39, 0x2B, 0x6A, 0x35, 0x4C, 0x50, 0x32, 0x52, 0x49, 0x55, 0x5A, 0x4E, 0x6F, 0x51, 0x41, 0x68, 0x56, 0x42, 0x2F, 0x30, ++ 0x2F, 0x45, 0x36, 0x78, 0x79, 0x6A, 0x79, 0x66, 0x71, 0x5A, 0x39, 0x30, 0x62, 0x70, 0x34, 0x52, 0x6A, 0x5A, 0x73, 0x62, 0x67, 0x79, 0x4C, 0x63, 0x73, 0x55, 0x44, 0x46, 0x44, 0x59, 0x67, 0x32, 0x57, 0x44, 0x37, 0x72, 0x6C, 0x63, 0x0A, 0x7A, ++ 0x38, 0x73, 0x46, 0x57, 0x6B, 0x7A, 0x36, 0x47, 0x5A, 0x64, 0x72, 0x31, 0x6C, 0x30, 0x54, 0x30, 0x38, 0x4A, 0x63, 0x56, 0x4C, 0x77, 0x79, 0x63, 0x36, 0x42, 0x34, 0x39, 0x66, 0x46, 0x74, 0x48, 0x73, 0x75, 0x66, 0x70, 0x61, 0x61, 0x66, 0x49, ++ 0x74, 0x7A, 0x52, 0x55, 0x5A, 0x36, 0x43, 0x65, 0x57, 0x52, 0x67, 0x4B, 0x52, 0x4D, 0x2B, 0x6F, 0x2F, 0x31, 0x50, 0x63, 0x6D, 0x71, 0x72, 0x34, 0x74, 0x54, 0x6C, 0x75, 0x43, 0x52, 0x56, 0x4C, 0x45, 0x52, 0x4C, 0x0A, 0x69, 0x6F, 0x68, 0x45, ++ 0x6E, 0x4D, 0x71, 0x45, 0x30, 0x79, 0x6F, 0x37, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, 0x51, 0x6A, 0x42, 0x41, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, ++ 0x41, 0x66, 0x38, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x0A, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x53, ++ 0x43, 0x49, 0x53, 0x31, 0x6D, 0x78, 0x74, 0x65, 0x67, 0x34, 0x42, 0x58, 0x72, 0x7A, 0x6B, 0x77, 0x4A, 0x64, 0x38, 0x52, 0x67, 0x6E, 0x6C, 0x52, 0x75, 0x41, 0x7A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, ++ 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x67, 0x45, 0x41, 0x59, 0x4E, 0x34, 0x61, 0x75, 0x4F, 0x66, 0x79, 0x59, 0x49, 0x4C, 0x56, 0x41, 0x7A, 0x4F, 0x42, 0x0A, 0x79, 0x77, 0x61, 0x4B, 0x38, 0x53, 0x4A, 0x4A, 0x36, 0x65, ++ 0x6A, 0x71, 0x6B, 0x58, 0x2F, 0x47, 0x4D, 0x31, 0x35, 0x6F, 0x47, 0x51, 0x4F, 0x47, 0x4F, 0x30, 0x4D, 0x42, 0x7A, 0x77, 0x64, 0x77, 0x35, 0x41, 0x67, 0x65, 0x5A, 0x59, 0x57, 0x52, 0x35, 0x68, 0x45, 0x69, 0x74, 0x2F, 0x55, 0x43, 0x49, 0x34, ++ 0x36, 0x75, 0x75, 0x52, 0x35, 0x39, 0x48, 0x33, 0x35, 0x73, 0x35, 0x72, 0x30, 0x6C, 0x31, 0x5A, 0x55, 0x61, 0x38, 0x67, 0x57, 0x6D, 0x72, 0x34, 0x55, 0x43, 0x0A, 0x62, 0x36, 0x37, 0x34, 0x31, 0x6A, 0x48, 0x2F, 0x4A, 0x63, 0x6C, 0x4B, 0x79, ++ 0x4D, 0x65, 0x4B, 0x71, 0x64, 0x6D, 0x66, 0x53, 0x30, 0x6D, 0x62, 0x45, 0x56, 0x65, 0x5A, 0x6B, 0x6B, 0x4D, 0x52, 0x33, 0x72, 0x59, 0x7A, 0x70, 0x4D, 0x7A, 0x58, 0x6A, 0x57, 0x52, 0x39, 0x31, 0x4D, 0x30, 0x38, 0x4B, 0x43, 0x79, 0x30, 0x6D, ++ 0x70, 0x62, 0x71, 0x54, 0x66, 0x58, 0x45, 0x52, 0x4D, 0x51, 0x6C, 0x71, 0x69, 0x43, 0x41, 0x32, 0x43, 0x6C, 0x56, 0x39, 0x2B, 0x42, 0x42, 0x0A, 0x2F, 0x41, 0x59, 0x6D, 0x2F, 0x37, 0x6B, 0x32, 0x39, 0x55, 0x4D, 0x55, 0x41, 0x32, 0x5A, 0x34, ++ 0x34, 0x52, 0x47, 0x78, 0x32, 0x69, 0x42, 0x66, 0x52, 0x67, 0x42, 0x34, 0x41, 0x43, 0x47, 0x6C, 0x48, 0x67, 0x41, 0x6F, 0x59, 0x58, 0x68, 0x76, 0x71, 0x41, 0x45, 0x42, 0x6A, 0x35, 0x30, 0x30, 0x6D, 0x76, 0x2F, 0x30, 0x4F, 0x4A, 0x44, 0x37, ++ 0x75, 0x4E, 0x47, 0x7A, 0x63, 0x67, 0x62, 0x4A, 0x63, 0x65, 0x61, 0x42, 0x78, 0x58, 0x6E, 0x74, 0x43, 0x36, 0x5A, 0x35, 0x0A, 0x38, 0x68, 0x4D, 0x4C, 0x6E, 0x50, 0x64, 0x64, 0x44, 0x6E, 0x73, 0x6B, 0x6B, 0x37, 0x52, 0x49, 0x32, 0x34, 0x5A, ++ 0x66, 0x33, 0x6C, 0x43, 0x47, 0x65, 0x4F, 0x64, 0x41, 0x35, 0x6A, 0x47, 0x6F, 0x6B, 0x48, 0x5A, 0x77, 0x59, 0x61, 0x2B, 0x63, 0x4E, 0x79, 0x77, 0x52, 0x74, 0x59, 0x4B, 0x33, 0x71, 0x71, 0x34, 0x6B, 0x4E, 0x46, 0x74, 0x79, 0x44, 0x47, 0x6B, ++ 0x4E, 0x7A, 0x56, 0x6D, 0x66, 0x39, 0x6E, 0x47, 0x76, 0x6E, 0x41, 0x76, 0x52, 0x43, 0x6A, 0x6A, 0x35, 0x0A, 0x42, 0x69, 0x4B, 0x44, 0x55, 0x79, 0x55, 0x4D, 0x2F, 0x46, 0x48, 0x45, 0x35, 0x72, 0x37, 0x69, 0x4F, 0x5A, 0x55, 0x4C, 0x4A, 0x4B, ++ 0x32, 0x76, 0x30, 0x5A, 0x58, 0x6B, 0x6C, 0x74, 0x64, 0x30, 0x5A, 0x47, 0x74, 0x78, 0x54, 0x67, 0x49, 0x38, 0x71, 0x6F, 0x58, 0x7A, 0x49, 0x4B, 0x4E, 0x44, 0x4F, 0x58, 0x5A, 0x62, 0x62, 0x46, 0x44, 0x2B, 0x6D, 0x70, 0x77, 0x55, 0x48, 0x6D, ++ 0x55, 0x55, 0x69, 0x68, 0x57, 0x39, 0x6F, 0x34, 0x4A, 0x46, 0x57, 0x6B, 0x6C, 0x57, 0x0A, 0x61, 0x74, 0x4B, 0x63, 0x73, 0x57, 0x4D, 0x79, 0x35, 0x57, 0x48, 0x67, 0x55, 0x79, 0x49, 0x4F, 0x70, 0x77, 0x70, 0x4A, 0x36, 0x73, 0x74, 0x2B, 0x48, ++ 0x36, 0x6A, 0x69, 0x59, 0x6F, 0x44, 0x32, 0x45, 0x45, 0x56, 0x53, 0x6D, 0x41, 0x59, 0x59, 0x33, 0x71, 0x58, 0x4E, 0x4C, 0x33, 0x2B, 0x71, 0x31, 0x4F, 0x6B, 0x2B, 0x43, 0x48, 0x4C, 0x73, 0x49, 0x77, 0x4D, 0x43, 0x50, 0x4B, 0x61, 0x71, 0x32, ++ 0x4C, 0x78, 0x6E, 0x64, 0x44, 0x30, 0x55, 0x46, 0x2F, 0x74, 0x55, 0x0A, 0x53, 0x78, 0x66, 0x6A, 0x30, 0x33, 0x6B, 0x39, 0x62, 0x57, 0x74, 0x4A, 0x79, 0x53, 0x67, 0x4F, 0x4C, 0x6E, 0x52, 0x51, 0x76, 0x77, 0x7A, 0x5A, 0x52, 0x6A, 0x6F, 0x51, ++ 0x68, 0x73, 0x6D, 0x6E, 0x50, 0x2B, 0x6D, 0x67, 0x37, 0x48, 0x2F, 0x72, 0x70, 0x58, 0x64, 0x59, 0x61, 0x58, 0x48, 0x6D, 0x67, 0x77, 0x6F, 0x33, 0x38, 0x6F, 0x5A, 0x4A, 0x61, 0x72, 0x35, 0x35, 0x43, 0x4A, 0x44, 0x32, 0x41, 0x68, 0x5A, 0x6B, ++ 0x50, 0x75, 0x58, 0x61, 0x54, 0x48, 0x34, 0x4D, 0x0A, 0x4E, 0x4D, 0x6E, 0x35, 0x58, 0x37, 0x61, 0x7A, 0x4B, 0x46, 0x47, 0x6E, 0x70, 0x79, 0x75, 0x71, 0x53, 0x66, 0x71, 0x4E, 0x5A, 0x53, 0x6C, 0x4F, 0x34, 0x32, 0x73, 0x54, 0x70, 0x35, 0x53, ++ 0x6A, 0x4C, 0x56, 0x46, 0x74, 0x65, 0x41, 0x78, 0x45, 0x79, 0x39, 0x2F, 0x65, 0x43, 0x47, 0x2F, 0x4F, 0x6F, 0x32, 0x53, 0x72, 0x30, 0x35, 0x57, 0x45, 0x31, 0x4C, 0x6C, 0x53, 0x56, 0x48, 0x4A, 0x37, 0x6C, 0x69, 0x58, 0x4D, 0x76, 0x47, 0x6E, ++ 0x6A, 0x53, 0x47, 0x34, 0x4E, 0x0A, 0x30, 0x4D, 0x65, 0x64, 0x4A, 0x35, 0x71, 0x71, 0x2B, 0x42, 0x4F, 0x53, 0x33, 0x52, 0x37, 0x66, 0x59, 0x35, 0x38, 0x31, 0x71, 0x52, 0x59, 0x32, 0x37, 0x49, 0x79, 0x34, 0x67, 0x2F, 0x51, 0x39, 0x69, 0x59, ++ 0x2F, 0x4E, 0x74, 0x42, 0x64, 0x65, 0x31, 0x37, 0x4D, 0x58, 0x51, 0x52, 0x42, 0x64, 0x4A, 0x33, 0x4E, 0x67, 0x68, 0x56, 0x64, 0x4A, 0x49, 0x67, 0x63, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, ++ 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, ++ 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, ++ 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x32, 0x6A, 0x43, 0x43, 0x41, 0x38, 0x4B, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x4D, 0x42, 0x66, 0x63, 0x4F, 0x68, 0x74, 0x70, 0x4A, 0x38, 0x30, 0x59, 0x31, 0x4C, 0x72, 0x71, 0x79, ++ 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43, 0x77, 0x55, 0x41, 0x4D, 0x49, 0x47, 0x49, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, ++ 0x0A, 0x55, 0x7A, 0x45, 0x52, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x41, 0x77, 0x49, 0x53, 0x57, 0x78, 0x73, 0x61, 0x57, 0x35, 0x76, 0x61, 0x58, 0x4D, 0x78, 0x45, 0x44, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x63, ++ 0x4D, 0x42, 0x30, 0x4E, 0x6F, 0x61, 0x57, 0x4E, 0x68, 0x5A, 0x32, 0x38, 0x78, 0x49, 0x54, 0x41, 0x66, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x47, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x64, 0x32, 0x46, 0x32, 0x0A, 0x5A, 0x53, ++ 0x42, 0x49, 0x62, 0x32, 0x78, 0x6B, 0x61, 0x57, 0x35, 0x6E, 0x63, 0x79, 0x77, 0x67, 0x53, 0x57, 0x35, 0x6A, 0x4C, 0x6A, 0x45, 0x78, 0x4D, 0x43, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x6F, 0x56, 0x48, 0x4A, 0x31, 0x63, 0x33, ++ 0x52, 0x33, 0x59, 0x58, 0x5A, 0x6C, 0x49, 0x45, 0x64, 0x73, 0x62, 0x32, 0x4A, 0x68, 0x62, 0x43, 0x42, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x61, 0x57, 0x5A, 0x70, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x0A, 0x49, 0x45, 0x46, 0x31, 0x64, ++ 0x47, 0x68, 0x76, 0x63, 0x6D, 0x6C, 0x30, 0x65, 0x54, 0x41, 0x65, 0x46, 0x77, 0x30, 0x78, 0x4E, 0x7A, 0x41, 0x34, 0x4D, 0x6A, 0x4D, 0x78, 0x4F, 0x54, 0x4D, 0x30, 0x4D, 0x54, 0x4A, 0x61, 0x46, 0x77, 0x30, 0x30, 0x4D, 0x6A, 0x41, 0x34, 0x4D, ++ 0x6A, 0x4D, 0x78, 0x4F, 0x54, 0x4D, 0x30, 0x4D, 0x54, 0x4A, 0x61, 0x4D, 0x49, 0x47, 0x49, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, 0x0A, 0x55, 0x7A, 0x45, 0x52, 0x4D, 0x41, 0x38, 0x47, ++ 0x41, 0x31, 0x55, 0x45, 0x43, 0x41, 0x77, 0x49, 0x53, 0x57, 0x78, 0x73, 0x61, 0x57, 0x35, 0x76, 0x61, 0x58, 0x4D, 0x78, 0x45, 0x44, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x63, 0x4D, 0x42, 0x30, 0x4E, 0x6F, 0x61, 0x57, 0x4E, 0x68, ++ 0x5A, 0x32, 0x38, 0x78, 0x49, 0x54, 0x41, 0x66, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x47, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x64, 0x32, 0x46, 0x32, 0x0A, 0x5A, 0x53, 0x42, 0x49, 0x62, 0x32, 0x78, 0x6B, 0x61, 0x57, 0x35, ++ 0x6E, 0x63, 0x79, 0x77, 0x67, 0x53, 0x57, 0x35, 0x6A, 0x4C, 0x6A, 0x45, 0x78, 0x4D, 0x43, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x6F, 0x56, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x52, 0x33, 0x59, 0x58, 0x5A, 0x6C, 0x49, 0x45, 0x64, ++ 0x73, 0x62, 0x32, 0x4A, 0x68, 0x62, 0x43, 0x42, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x61, 0x57, 0x5A, 0x70, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x0A, 0x49, 0x45, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6D, 0x6C, 0x30, 0x65, 0x54, ++ 0x43, 0x43, 0x41, 0x69, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x67, 0x6F, 0x43, 0x67, 0x67, ++ 0x49, 0x42, 0x41, 0x4C, 0x6C, 0x64, 0x55, 0x53, 0x68, 0x4C, 0x50, 0x44, 0x65, 0x53, 0x30, 0x59, 0x4C, 0x4F, 0x76, 0x52, 0x32, 0x39, 0x0A, 0x7A, 0x64, 0x32, 0x34, 0x71, 0x38, 0x38, 0x4B, 0x50, 0x75, 0x46, 0x64, 0x35, 0x64, 0x79, 0x71, 0x43, ++ 0x62, 0x6C, 0x58, 0x41, 0x6A, 0x37, 0x6D, 0x59, 0x32, 0x48, 0x66, 0x38, 0x67, 0x2B, 0x43, 0x59, 0x36, 0x36, 0x6A, 0x39, 0x36, 0x78, 0x7A, 0x30, 0x58, 0x7A, 0x6E, 0x73, 0x77, 0x75, 0x76, 0x43, 0x41, 0x41, 0x4A, 0x57, 0x58, 0x2F, 0x4E, 0x4B, ++ 0x53, 0x71, 0x49, 0x6B, 0x34, 0x63, 0x58, 0x47, 0x49, 0x44, 0x74, 0x69, 0x4C, 0x4B, 0x30, 0x74, 0x68, 0x41, 0x66, 0x0A, 0x4C, 0x64, 0x5A, 0x66, 0x56, 0x61, 0x49, 0x54, 0x58, 0x64, 0x48, 0x47, 0x36, 0x77, 0x5A, 0x57, 0x69, 0x59, 0x6A, 0x2B, ++ 0x72, 0x44, 0x4B, 0x64, 0x2F, 0x56, 0x7A, 0x44, 0x42, 0x63, 0x64, 0x75, 0x37, 0x6F, 0x61, 0x4A, 0x75, 0x6F, 0x67, 0x44, 0x6E, 0x58, 0x49, 0x68, 0x68, 0x70, 0x43, 0x75, 0x6A, 0x77, 0x4F, 0x6C, 0x33, 0x4A, 0x2B, 0x49, 0x4B, 0x4D, 0x75, 0x6A, ++ 0x6B, 0x6B, 0x6B, 0x50, 0x37, 0x4E, 0x41, 0x50, 0x34, 0x6D, 0x31, 0x45, 0x54, 0x34, 0x42, 0x71, 0x0A, 0x73, 0x74, 0x54, 0x6E, 0x6F, 0x41, 0x70, 0x54, 0x41, 0x62, 0x71, 0x4F, 0x6C, 0x35, 0x46, 0x32, 0x62, 0x72, 0x7A, 0x38, 0x31, 0x57, 0x73, ++ 0x32, 0x35, 0x6B, 0x43, 0x49, 0x31, 0x6E, 0x73, 0x76, 0x58, 0x77, 0x58, 0x6F, 0x4C, 0x47, 0x30, 0x52, 0x38, 0x2B, 0x65, 0x79, 0x76, 0x70, 0x4A, 0x45, 0x54, 0x4E, 0x4B, 0x58, 0x70, 0x50, 0x37, 0x53, 0x63, 0x6F, 0x46, 0x44, 0x42, 0x35, 0x7A, ++ 0x70, 0x45, 0x54, 0x37, 0x31, 0x69, 0x78, 0x70, 0x5A, 0x66, 0x52, 0x39, 0x6F, 0x0A, 0x57, 0x4E, 0x30, 0x45, 0x41, 0x43, 0x79, 0x57, 0x38, 0x30, 0x4F, 0x7A, 0x66, 0x70, 0x67, 0x5A, 0x64, 0x4E, 0x6D, 0x63, 0x63, 0x39, 0x6B, 0x59, 0x76, 0x6B, ++ 0x48, 0x48, 0x4E, 0x48, 0x6E, 0x5A, 0x39, 0x47, 0x4C, 0x43, 0x51, 0x37, 0x6D, 0x7A, 0x4A, 0x37, 0x41, 0x69, 0x79, 0x2F, 0x6B, 0x39, 0x55, 0x73, 0x63, 0x77, 0x52, 0x37, 0x50, 0x4A, 0x50, 0x72, 0x68, 0x71, 0x34, 0x75, 0x66, 0x6F, 0x67, 0x58, ++ 0x42, 0x65, 0x51, 0x6F, 0x74, 0x50, 0x4A, 0x71, 0x58, 0x2B, 0x0A, 0x4F, 0x73, 0x49, 0x67, 0x62, 0x72, 0x76, 0x34, 0x46, 0x6F, 0x37, 0x4E, 0x44, 0x4B, 0x6D, 0x30, 0x47, 0x32, 0x78, 0x32, 0x45, 0x4F, 0x46, 0x59, 0x65, 0x55, 0x59, 0x2B, 0x56, ++ 0x4D, 0x36, 0x41, 0x71, 0x46, 0x63, 0x4A, 0x4E, 0x79, 0x6B, 0x62, 0x6D, 0x52, 0x4F, 0x50, 0x44, 0x4D, 0x6A, 0x57, 0x4C, 0x42, 0x7A, 0x37, 0x42, 0x65, 0x67, 0x49, 0x6C, 0x54, 0x31, 0x6C, 0x52, 0x74, 0x7A, 0x75, 0x7A, 0x57, 0x6E, 0x69, 0x54, ++ 0x59, 0x2B, 0x48, 0x4B, 0x45, 0x34, 0x30, 0x0A, 0x43, 0x7A, 0x37, 0x50, 0x46, 0x4E, 0x6D, 0x37, 0x33, 0x62, 0x5A, 0x51, 0x6D, 0x71, 0x31, 0x33, 0x31, 0x42, 0x6E, 0x57, 0x32, 0x68, 0x71, 0x49, 0x79, 0x45, 0x34, 0x62, 0x4A, 0x33, 0x58, 0x59, ++ 0x73, 0x67, 0x6A, 0x78, 0x72, 0x6F, 0x4D, 0x77, 0x75, 0x52, 0x45, 0x4F, 0x7A, 0x59, 0x66, 0x77, 0x68, 0x49, 0x30, 0x56, 0x63, 0x6E, 0x79, 0x68, 0x37, 0x38, 0x7A, 0x79, 0x69, 0x47, 0x47, 0x36, 0x39, 0x47, 0x6D, 0x37, 0x44, 0x49, 0x77, 0x4C, ++ 0x64, 0x56, 0x63, 0x45, 0x0A, 0x75, 0x45, 0x34, 0x71, 0x46, 0x43, 0x34, 0x39, 0x44, 0x78, 0x77, 0x65, 0x4D, 0x71, 0x5A, 0x69, 0x4E, 0x75, 0x35, 0x6D, 0x34, 0x69, 0x4B, 0x34, 0x42, 0x55, 0x42, 0x6A, 0x45, 0x43, 0x4C, 0x7A, 0x4D, 0x78, 0x31, ++ 0x30, 0x63, 0x6F, 0x6F, 0x73, 0x39, 0x54, 0x6B, 0x70, 0x6F, 0x4E, 0x50, 0x6E, 0x47, 0x34, 0x43, 0x45, 0x4C, 0x63, 0x55, 0x39, 0x34, 0x30, 0x32, 0x78, 0x2F, 0x52, 0x70, 0x76, 0x75, 0x6D, 0x55, 0x48, 0x4F, 0x31, 0x6A, 0x73, 0x51, 0x6B, 0x55, ++ 0x6D, 0x0A, 0x2B, 0x39, 0x6A, 0x61, 0x4A, 0x58, 0x4C, 0x45, 0x39, 0x67, 0x43, 0x78, 0x49, 0x6E, 0x6D, 0x39, 0x34, 0x33, 0x78, 0x5A, 0x59, 0x6B, 0x71, 0x63, 0x42, 0x57, 0x38, 0x39, 0x7A, 0x75, 0x62, 0x57, 0x52, 0x32, 0x4F, 0x5A, 0x78, 0x69, ++ 0x52, 0x76, 0x63, 0x68, 0x4C, 0x49, 0x72, 0x48, 0x2B, 0x51, 0x74, 0x41, 0x75, 0x52, 0x63, 0x4F, 0x69, 0x33, 0x35, 0x68, 0x59, 0x51, 0x63, 0x52, 0x66, 0x4F, 0x33, 0x67, 0x5A, 0x50, 0x53, 0x45, 0x46, 0x39, 0x4E, 0x55, 0x71, 0x6A, 0x0A, 0x69, ++ 0x66, 0x4C, 0x4A, 0x53, 0x33, 0x74, 0x42, 0x45, 0x57, 0x31, 0x6E, 0x74, 0x77, 0x69, 0x59, 0x54, 0x4F, 0x55, 0x52, 0x47, 0x61, 0x35, 0x43, 0x67, 0x4E, 0x7A, 0x37, 0x6B, 0x41, 0x58, 0x55, 0x2B, 0x46, 0x44, 0x4B, 0x76, 0x75, 0x53, 0x74, 0x78, ++ 0x38, 0x4B, 0x55, 0x31, 0x78, 0x61, 0x64, 0x35, 0x68, 0x65, 0x50, 0x72, 0x7A, 0x62, 0x37, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, 0x51, 0x6A, 0x42, 0x41, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x0A, 0x45, 0x77, 0x45, 0x42, ++ 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x46, 0x4A, 0x6E, 0x67, 0x47, 0x57, 0x63, 0x4E, 0x59, 0x74, 0x74, 0x32, 0x73, 0x39, 0x6F, 0x39, ++ 0x75, 0x46, 0x76, 0x6F, 0x2F, 0x55, 0x4C, 0x53, 0x4D, 0x51, 0x36, 0x48, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x0A, 0x42, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, ++ 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x67, 0x45, 0x41, 0x6D, 0x48, 0x4E, 0x77, 0x34, 0x72, 0x44, 0x54, 0x37, 0x54, 0x6E, 0x73, 0x54, 0x47, 0x44, 0x5A, 0x71, 0x52, 0x4B, ++ 0x47, 0x46, 0x78, 0x36, 0x57, 0x30, 0x4F, 0x68, 0x55, 0x4B, 0x44, 0x74, 0x6B, 0x4C, 0x53, 0x47, 0x6D, 0x2B, 0x4A, 0x31, 0x57, 0x45, 0x32, 0x70, 0x49, 0x50, 0x55, 0x2F, 0x48, 0x0A, 0x50, 0x69, 0x6E, 0x62, 0x62, 0x56, 0x69, 0x44, 0x56, 0x44, ++ 0x32, 0x48, 0x66, 0x53, 0x4D, 0x46, 0x31, 0x4F, 0x51, 0x63, 0x33, 0x4F, 0x67, 0x34, 0x5A, 0x59, 0x62, 0x46, 0x64, 0x61, 0x64, 0x61, 0x32, 0x7A, 0x55, 0x46, 0x76, 0x58, 0x66, 0x65, 0x75, 0x79, 0x6B, 0x33, 0x51, 0x41, 0x55, 0x48, 0x77, 0x35, ++ 0x52, 0x53, 0x6E, 0x38, 0x70, 0x6B, 0x33, 0x66, 0x45, 0x62, 0x4B, 0x39, 0x78, 0x47, 0x43, 0x68, 0x41, 0x43, 0x4D, 0x66, 0x31, 0x4B, 0x61, 0x41, 0x30, 0x48, 0x0A, 0x5A, 0x4A, 0x44, 0x6D, 0x48, 0x76, 0x55, 0x71, 0x6F, 0x61, 0x69, 0x37, 0x50, ++ 0x46, 0x33, 0x35, 0x6F, 0x77, 0x67, 0x4C, 0x45, 0x51, 0x7A, 0x78, 0x50, 0x79, 0x30, 0x51, 0x6C, 0x47, 0x2F, 0x2B, 0x34, 0x6A, 0x53, 0x48, 0x67, 0x39, 0x62, 0x50, 0x35, 0x52, 0x73, 0x31, 0x62, 0x64, 0x49, 0x44, 0x34, 0x62, 0x41, 0x4E, 0x71, ++ 0x4B, 0x43, 0x71, 0x52, 0x69, 0x65, 0x43, 0x4E, 0x71, 0x63, 0x56, 0x74, 0x67, 0x69, 0x6D, 0x51, 0x6C, 0x52, 0x58, 0x74, 0x70, 0x6C, 0x61, 0x0A, 0x34, 0x67, 0x74, 0x35, 0x6B, 0x4E, 0x64, 0x58, 0x45, 0x6C, 0x45, 0x31, 0x47, 0x59, 0x68, 0x42, ++ 0x61, 0x43, 0x58, 0x55, 0x4E, 0x78, 0x65, 0x45, 0x46, 0x66, 0x73, 0x42, 0x63, 0x74, 0x79, 0x56, 0x33, 0x6C, 0x49, 0x6D, 0x49, 0x4A, 0x67, 0x6D, 0x34, 0x6E, 0x62, 0x31, 0x4A, 0x32, 0x2F, 0x36, 0x41, 0x44, 0x74, 0x4B, 0x59, 0x64, 0x6B, 0x4E, ++ 0x79, 0x31, 0x47, 0x54, 0x4B, 0x76, 0x30, 0x57, 0x42, 0x70, 0x61, 0x6E, 0x49, 0x35, 0x6F, 0x6A, 0x53, 0x50, 0x35, 0x52, 0x0A, 0x76, 0x62, 0x62, 0x45, 0x73, 0x4C, 0x46, 0x55, 0x7A, 0x74, 0x35, 0x73, 0x51, 0x61, 0x30, 0x57, 0x5A, 0x33, 0x37, ++ 0x62, 0x2F, 0x54, 0x6A, 0x4E, 0x75, 0x54, 0x68, 0x4F, 0x73, 0x73, 0x46, 0x67, 0x79, 0x35, 0x30, 0x58, 0x33, 0x31, 0x69, 0x65, 0x65, 0x6D, 0x4B, 0x79, 0x4A, 0x6F, 0x39, 0x30, 0x6C, 0x5A, 0x76, 0x6B, 0x57, 0x78, 0x33, 0x53, 0x44, 0x39, 0x32, ++ 0x59, 0x48, 0x4A, 0x74, 0x5A, 0x75, 0x53, 0x50, 0x54, 0x4D, 0x61, 0x43, 0x6D, 0x2F, 0x7A, 0x6A, 0x64, 0x0A, 0x7A, 0x79, 0x42, 0x50, 0x36, 0x56, 0x68, 0x57, 0x4F, 0x6D, 0x66, 0x44, 0x30, 0x66, 0x61, 0x5A, 0x6D, 0x5A, 0x32, 0x36, 0x4E, 0x72, ++ 0x61, 0x41, 0x4C, 0x34, 0x68, 0x48, 0x54, 0x34, 0x61, 0x2F, 0x52, 0x44, 0x71, 0x41, 0x35, 0x44, 0x63, 0x63, 0x70, 0x72, 0x72, 0x71, 0x6C, 0x35, 0x67, 0x52, 0x30, 0x49, 0x52, 0x69, 0x52, 0x32, 0x51, 0x65, 0x71, 0x75, 0x35, 0x41, 0x76, 0x7A, ++ 0x53, 0x78, 0x6E, 0x49, 0x39, 0x4F, 0x34, 0x66, 0x4B, 0x53, 0x54, 0x78, 0x2B, 0x4F, 0x0A, 0x38, 0x35, 0x36, 0x58, 0x33, 0x76, 0x4F, 0x6D, 0x65, 0x57, 0x71, 0x4A, 0x63, 0x55, 0x39, 0x4C, 0x4A, 0x78, 0x64, 0x49, 0x2F, 0x75, 0x7A, 0x30, 0x55, ++ 0x41, 0x39, 0x50, 0x53, 0x58, 0x33, 0x4D, 0x52, 0x65, 0x4F, 0x39, 0x65, 0x6B, 0x44, 0x46, 0x51, 0x64, 0x78, 0x68, 0x56, 0x69, 0x63, 0x47, 0x61, 0x65, 0x56, 0x79, 0x51, 0x59, 0x48, 0x54, 0x74, 0x67, 0x47, 0x4A, 0x6F, 0x43, 0x38, 0x36, 0x63, ++ 0x6E, 0x6E, 0x2B, 0x4F, 0x6A, 0x43, 0x2F, 0x51, 0x65, 0x7A, 0x48, 0x0A, 0x59, 0x6A, 0x36, 0x52, 0x53, 0x38, 0x66, 0x5A, 0x4D, 0x58, 0x5A, 0x43, 0x2B, 0x66, 0x63, 0x38, 0x59, 0x2B, 0x77, 0x6D, 0x6A, 0x48, 0x4D, 0x4D, 0x66, 0x52, 0x6F, 0x64, ++ 0x36, 0x71, 0x68, 0x38, 0x68, 0x36, 0x6A, 0x43, 0x4A, 0x33, 0x7A, 0x68, 0x4D, 0x30, 0x45, 0x50, 0x7A, 0x38, 0x2F, 0x38, 0x41, 0x4B, 0x41, 0x69, 0x67, 0x4A, 0x35, 0x4B, 0x70, 0x32, 0x38, 0x41, 0x73, 0x45, 0x46, 0x46, 0x74, 0x79, 0x4C, 0x4B, ++ 0x61, 0x45, 0x6A, 0x46, 0x51, 0x71, 0x4B, 0x75, 0x0A, 0x33, 0x52, 0x33, 0x79, 0x34, 0x47, 0x35, 0x4F, 0x42, 0x56, 0x69, 0x78, 0x77, 0x4A, 0x41, 0x57, 0x4B, 0x71, 0x51, 0x39, 0x45, 0x45, 0x43, 0x2B, 0x6A, 0x32, 0x4A, 0x6A, 0x67, 0x36, 0x6D, ++ 0x63, 0x67, 0x6E, 0x30, 0x74, 0x41, 0x75, 0x6D, 0x44, 0x4D, 0x48, 0x7A, 0x4C, 0x4A, 0x38, 0x6E, 0x39, 0x48, 0x6D, 0x59, 0x41, 0x73, 0x43, 0x37, 0x54, 0x49, 0x53, 0x2B, 0x4F, 0x4D, 0x78, 0x5A, 0x73, 0x6D, 0x4F, 0x30, 0x51, 0x71, 0x41, 0x66, ++ 0x57, 0x7A, 0x4A, 0x50, 0x50, 0x0A, 0x32, 0x39, 0x46, 0x70, 0x48, 0x4F, 0x54, 0x4B, 0x79, 0x65, 0x43, 0x32, 0x6E, 0x4F, 0x6E, 0x4F, 0x63, 0x58, 0x48, 0x65, 0x62, 0x44, 0x38, 0x57, 0x70, 0x48, 0x6B, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x45, ++ 0x43, 0x43, 0x20, 0x50, 0x32, 0x35, 0x36, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x59, 0x44, 0x43, 0x43, 0x41, 0x67, ++ 0x65, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x4D, 0x44, 0x57, 0x70, 0x66, 0x43, 0x44, 0x38, 0x6F, 0x58, 0x44, 0x35, 0x52, 0x6C, 0x64, 0x39, 0x64, 0x4D, 0x41, 0x6F, 0x47, 0x43, 0x43, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x42, 0x41, ++ 0x4D, 0x43, 0x4D, 0x49, 0x47, 0x52, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x52, 0x0A, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x42, 0x4D, 0x49, 0x53, ++ 0x57, 0x78, 0x73, 0x61, 0x57, 0x35, 0x76, 0x61, 0x58, 0x4D, 0x78, 0x45, 0x44, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x63, 0x54, 0x42, 0x30, 0x4E, 0x6F, 0x61, 0x57, 0x4E, 0x68, 0x5A, 0x32, 0x38, 0x78, 0x49, 0x54, 0x41, 0x66, 0x42, ++ 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x47, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x64, 0x32, 0x46, 0x32, 0x5A, 0x53, 0x42, 0x49, 0x0A, 0x62, 0x32, 0x78, 0x6B, 0x61, 0x57, 0x35, 0x6E, 0x63, 0x79, 0x77, 0x67, 0x53, 0x57, 0x35, 0x6A, ++ 0x4C, 0x6A, 0x45, 0x36, 0x4D, 0x44, 0x67, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x78, 0x56, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x52, 0x33, 0x59, 0x58, 0x5A, 0x6C, 0x49, 0x45, 0x64, 0x73, 0x62, 0x32, 0x4A, 0x68, 0x62, 0x43, 0x42, 0x46, ++ 0x51, 0x30, 0x4D, 0x67, 0x55, 0x44, 0x49, 0x31, 0x4E, 0x69, 0x42, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x61, 0x57, 0x5A, 0x70, 0x0A, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x49, 0x45, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6D, 0x6C, ++ 0x30, 0x65, 0x54, 0x41, 0x65, 0x46, 0x77, 0x30, 0x78, 0x4E, 0x7A, 0x41, 0x34, 0x4D, 0x6A, 0x4D, 0x78, 0x4F, 0x54, 0x4D, 0x31, 0x4D, 0x54, 0x42, 0x61, 0x46, 0x77, 0x30, 0x30, 0x4D, 0x6A, 0x41, 0x34, 0x4D, 0x6A, 0x4D, 0x78, 0x4F, 0x54, 0x4D, ++ 0x31, 0x4D, 0x54, 0x42, 0x61, 0x4D, 0x49, 0x47, 0x52, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x0A, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x52, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x42, ++ 0x4D, 0x49, 0x53, 0x57, 0x78, 0x73, 0x61, 0x57, 0x35, 0x76, 0x61, 0x58, 0x4D, 0x78, 0x45, 0x44, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x63, 0x54, 0x42, 0x30, 0x4E, 0x6F, 0x61, 0x57, 0x4E, 0x68, 0x5A, 0x32, 0x38, 0x78, 0x49, 0x54, ++ 0x41, 0x66, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x47, 0x46, 0x52, 0x79, 0x0A, 0x64, 0x58, 0x4E, 0x30, 0x64, 0x32, 0x46, 0x32, 0x5A, 0x53, 0x42, 0x49, 0x62, 0x32, 0x78, 0x6B, 0x61, 0x57, 0x35, 0x6E, 0x63, 0x79, 0x77, 0x67, 0x53, ++ 0x57, 0x35, 0x6A, 0x4C, 0x6A, 0x45, 0x36, 0x4D, 0x44, 0x67, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x78, 0x56, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x52, 0x33, 0x59, 0x58, 0x5A, 0x6C, 0x49, 0x45, 0x64, 0x73, 0x62, 0x32, 0x4A, 0x68, 0x62, ++ 0x43, 0x42, 0x46, 0x51, 0x30, 0x4D, 0x67, 0x55, 0x44, 0x49, 0x31, 0x0A, 0x4E, 0x69, 0x42, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x61, 0x57, 0x5A, 0x70, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x49, 0x45, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, ++ 0x63, 0x6D, 0x6C, 0x30, 0x65, 0x54, 0x42, 0x5A, 0x4D, 0x42, 0x4D, 0x47, 0x42, 0x79, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x41, 0x67, 0x45, 0x47, 0x43, 0x43, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x41, 0x77, 0x45, 0x48, 0x41, 0x30, 0x49, 0x41, ++ 0x42, 0x48, 0x37, 0x37, 0x62, 0x4F, 0x59, 0x6A, 0x0A, 0x34, 0x33, 0x4D, 0x79, 0x43, 0x4D, 0x70, 0x67, 0x35, 0x6C, 0x4F, 0x63, 0x75, 0x6E, 0x53, 0x4E, 0x47, 0x4C, 0x42, 0x34, 0x6B, 0x46, 0x4B, 0x41, 0x33, 0x54, 0x6A, 0x41, 0x53, 0x68, 0x33, ++ 0x52, 0x71, 0x4D, 0x79, 0x54, 0x70, 0x4A, 0x63, 0x47, 0x4F, 0x4D, 0x6F, 0x4E, 0x46, 0x57, 0x4C, 0x47, 0x6A, 0x67, 0x45, 0x71, 0x5A, 0x5A, 0x32, 0x71, 0x33, 0x7A, 0x53, 0x52, 0x4C, 0x6F, 0x48, 0x42, 0x35, 0x44, 0x4F, 0x53, 0x4D, 0x63, 0x54, ++ 0x39, 0x43, 0x54, 0x71, 0x6D, 0x0A, 0x50, 0x36, 0x32, 0x6A, 0x51, 0x7A, 0x42, 0x42, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x44, 0x77, ++ 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x44, 0x41, 0x77, 0x63, 0x47, 0x41, 0x44, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x6F, 0x30, 0x45, 0x47, 0x72, 0x4A, ++ 0x42, 0x74, 0x0A, 0x30, 0x55, 0x72, 0x72, 0x64, 0x61, 0x56, 0x4B, 0x45, 0x4A, 0x6D, 0x7A, 0x73, 0x61, 0x47, 0x4C, 0x53, 0x76, 0x63, 0x77, 0x43, 0x67, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x45, 0x41, 0x77, 0x49, 0x44, 0x52, ++ 0x77, 0x41, 0x77, 0x52, 0x41, 0x49, 0x67, 0x42, 0x2B, 0x5A, 0x55, 0x32, 0x67, 0x36, 0x67, 0x57, 0x72, 0x4B, 0x75, 0x45, 0x5A, 0x2B, 0x48, 0x78, 0x62, 0x62, 0x2F, 0x61, 0x64, 0x34, 0x6C, 0x76, 0x76, 0x69, 0x67, 0x74, 0x77, 0x6A, 0x7A, 0x0A, ++ 0x52, 0x4D, 0x34, 0x71, 0x33, 0x77, 0x67, 0x68, 0x44, 0x44, 0x63, 0x43, 0x49, 0x43, 0x30, 0x6D, 0x41, 0x36, 0x41, 0x46, 0x76, 0x57, 0x76, 0x52, 0x39, 0x6C, 0x7A, 0x34, 0x5A, 0x63, 0x79, 0x47, 0x62, 0x62, 0x4F, 0x63, 0x4E, 0x45, 0x68, 0x6A, ++ 0x68, 0x41, 0x6E, 0x46, 0x6A, 0x58, 0x63, 0x61, 0x34, 0x73, 0x79, 0x63, 0x34, 0x58, 0x52, 0x37, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, ++ 0x2D, 0x2D, 0x0A, 0x0A, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x45, 0x43, 0x43, 0x20, 0x50, 0x33, 0x38, 0x34, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, ++ 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, ++ 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x6E, 0x54, 0x43, 0x43, 0x41, 0x69, 0x53, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x4D, 0x43, 0x4C, 0x32, 0x46, 0x6C, 0x32, 0x79, 0x5A, ++ 0x4A, 0x36, 0x53, 0x41, 0x61, 0x45, 0x63, 0x37, 0x4D, 0x41, 0x6F, 0x47, 0x43, 0x43, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x42, 0x41, 0x4D, 0x44, 0x4D, 0x49, 0x47, 0x52, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, ++ 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x52, 0x0A, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x42, 0x4D, 0x49, 0x53, 0x57, 0x78, 0x73, 0x61, 0x57, 0x35, 0x76, 0x61, 0x58, 0x4D, 0x78, 0x45, 0x44, 0x41, 0x4F, 0x42, 0x67, 0x4E, ++ 0x56, 0x42, 0x41, 0x63, 0x54, 0x42, 0x30, 0x4E, 0x6F, 0x61, 0x57, 0x4E, 0x68, 0x5A, 0x32, 0x38, 0x78, 0x49, 0x54, 0x41, 0x66, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x47, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x64, 0x32, 0x46, ++ 0x32, 0x5A, 0x53, 0x42, 0x49, 0x0A, 0x62, 0x32, 0x78, 0x6B, 0x61, 0x57, 0x35, 0x6E, 0x63, 0x79, 0x77, 0x67, 0x53, 0x57, 0x35, 0x6A, 0x4C, 0x6A, 0x45, 0x36, 0x4D, 0x44, 0x67, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x78, 0x56, 0x48, ++ 0x4A, 0x31, 0x63, 0x33, 0x52, 0x33, 0x59, 0x58, 0x5A, 0x6C, 0x49, 0x45, 0x64, 0x73, 0x62, 0x32, 0x4A, 0x68, 0x62, 0x43, 0x42, 0x46, 0x51, 0x30, 0x4D, 0x67, 0x55, 0x44, 0x4D, 0x34, 0x4E, 0x43, 0x42, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x61, 0x57, ++ 0x5A, 0x70, 0x0A, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x49, 0x45, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6D, 0x6C, 0x30, 0x65, 0x54, 0x41, 0x65, 0x46, 0x77, 0x30, 0x78, 0x4E, 0x7A, 0x41, 0x34, 0x4D, 0x6A, 0x4D, 0x78, 0x4F, ++ 0x54, 0x4D, 0x32, 0x4E, 0x44, 0x4E, 0x61, 0x46, 0x77, 0x30, 0x30, 0x4D, 0x6A, 0x41, 0x34, 0x4D, 0x6A, 0x4D, 0x78, 0x4F, 0x54, 0x4D, 0x32, 0x4E, 0x44, 0x4E, 0x61, 0x4D, 0x49, 0x47, 0x52, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x0A, ++ 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x52, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x42, 0x4D, 0x49, 0x53, 0x57, 0x78, 0x73, 0x61, 0x57, 0x35, 0x76, 0x61, 0x58, 0x4D, 0x78, 0x45, 0x44, 0x41, 0x4F, ++ 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x63, 0x54, 0x42, 0x30, 0x4E, 0x6F, 0x61, 0x57, 0x4E, 0x68, 0x5A, 0x32, 0x38, 0x78, 0x49, 0x54, 0x41, 0x66, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x47, 0x46, 0x52, 0x79, 0x0A, 0x64, 0x58, 0x4E, ++ 0x30, 0x64, 0x32, 0x46, 0x32, 0x5A, 0x53, 0x42, 0x49, 0x62, 0x32, 0x78, 0x6B, 0x61, 0x57, 0x35, 0x6E, 0x63, 0x79, 0x77, 0x67, 0x53, 0x57, 0x35, 0x6A, 0x4C, 0x6A, 0x45, 0x36, 0x4D, 0x44, 0x67, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, ++ 0x78, 0x56, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x52, 0x33, 0x59, 0x58, 0x5A, 0x6C, 0x49, 0x45, 0x64, 0x73, 0x62, 0x32, 0x4A, 0x68, 0x62, 0x43, 0x42, 0x46, 0x51, 0x30, 0x4D, 0x67, 0x55, 0x44, 0x4D, 0x34, 0x0A, 0x4E, 0x43, 0x42, 0x44, 0x5A, 0x58, ++ 0x4A, 0x30, 0x61, 0x57, 0x5A, 0x70, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x49, 0x45, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6D, 0x6C, 0x30, 0x65, 0x54, 0x42, 0x32, 0x4D, 0x42, 0x41, 0x47, 0x42, 0x79, 0x71, 0x47, 0x53, 0x4D, ++ 0x34, 0x39, 0x41, 0x67, 0x45, 0x47, 0x42, 0x53, 0x75, 0x42, 0x42, 0x41, 0x41, 0x69, 0x41, 0x32, 0x49, 0x41, 0x42, 0x47, 0x76, 0x61, 0x44, 0x58, 0x55, 0x31, 0x43, 0x44, 0x46, 0x48, 0x0A, 0x42, 0x61, 0x35, 0x46, 0x6D, 0x56, 0x58, 0x78, 0x45, ++ 0x52, 0x4D, 0x75, 0x53, 0x76, 0x67, 0x51, 0x4D, 0x53, 0x4F, 0x6A, 0x66, 0x6F, 0x50, 0x54, 0x66, 0x79, 0x67, 0x49, 0x4F, 0x69, 0x59, 0x61, 0x4F, 0x73, 0x2B, 0x58, 0x67, 0x68, 0x2B, 0x41, 0x74, 0x79, 0x63, 0x4A, 0x6A, 0x39, 0x47, 0x4F, 0x4D, ++ 0x4D, 0x51, 0x4B, 0x6D, 0x77, 0x36, 0x73, 0x57, 0x41, 0x53, 0x72, 0x39, 0x7A, 0x5A, 0x39, 0x6C, 0x43, 0x4F, 0x6B, 0x6D, 0x77, 0x71, 0x4B, 0x69, 0x36, 0x76, 0x72, 0x0A, 0x2F, 0x54, 0x6B, 0x6C, 0x5A, 0x76, 0x46, 0x65, 0x2F, 0x6F, 0x79, 0x75, ++ 0x6A, 0x55, 0x46, 0x35, 0x6E, 0x51, 0x6C, 0x67, 0x7A, 0x69, 0x69, 0x70, 0x30, 0x34, 0x70, 0x74, 0x38, 0x39, 0x5A, 0x46, 0x31, 0x50, 0x4B, 0x59, 0x68, 0x44, 0x68, 0x6C, 0x6F, 0x4B, 0x4E, 0x44, 0x4D, 0x45, 0x45, 0x77, 0x44, 0x77, 0x59, 0x44, ++ 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x0A, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x51, 0x4D, 0x44, 0x42, 0x77, 0x59, ++ 0x41, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x52, 0x56, 0x71, 0x59, 0x53, 0x4A, 0x30, 0x73, 0x45, 0x79, 0x76, 0x52, 0x6A, 0x4C, 0x62, 0x4B, 0x59, 0x48, 0x54, 0x73, 0x6A, 0x6E, 0x6E, 0x62, 0x36, ++ 0x43, 0x6B, 0x44, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x77, 0x4E, 0x6E, 0x0A, 0x41, 0x44, 0x42, 0x6B, 0x41, 0x6A, 0x41, 0x33, 0x41, 0x5A, 0x4B, 0x58, 0x52, 0x52, 0x4A, 0x2B, 0x6F, 0x50, ++ 0x4D, 0x2B, 0x72, 0x52, 0x6B, 0x36, 0x63, 0x74, 0x33, 0x30, 0x55, 0x4A, 0x4D, 0x44, 0x45, 0x72, 0x35, 0x45, 0x30, 0x6B, 0x39, 0x42, 0x70, 0x49, 0x79, 0x63, 0x6E, 0x52, 0x2B, 0x6A, 0x39, 0x73, 0x4B, 0x53, 0x35, 0x30, 0x67, 0x55, 0x2F, 0x6B, ++ 0x36, 0x62, 0x70, 0x5A, 0x46, 0x58, 0x72, 0x73, 0x59, 0x33, 0x63, 0x72, 0x73, 0x43, 0x4D, 0x47, 0x63, 0x6C, 0x0A, 0x43, 0x72, 0x45, 0x4D, 0x58, 0x75, 0x36, 0x70, 0x59, 0x35, 0x4A, 0x76, 0x35, 0x5A, 0x41, 0x4C, 0x2F, 0x6D, 0x59, 0x69, 0x79, ++ 0x6B, 0x66, 0x39, 0x69, 0x6A, 0x48, 0x33, 0x67, 0x2F, 0x35, 0x36, 0x76, 0x78, 0x43, 0x2B, 0x47, 0x43, 0x73, 0x65, 0x6A, 0x2F, 0x59, 0x70, 0x48, 0x70, 0x52, 0x5A, 0x37, 0x34, 0x34, 0x68, 0x4E, 0x38, 0x74, 0x52, 0x6D, 0x4B, 0x56, 0x75, 0x53, ++ 0x77, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x4E, 0x41, 0x56, 0x45, 0x52, 0x20, 0x47, 0x6C, 0x6F, ++ 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x6F, 0x6A, 0x43, 0x43, 0x41, 0x34, 0x71, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, ++ 0x67, 0x49, 0x55, 0x41, 0x5A, 0x51, 0x77, 0x48, 0x71, 0x49, 0x4C, 0x33, 0x66, 0x58, 0x46, 0x4D, 0x79, 0x71, 0x78, 0x51, 0x30, 0x52, 0x78, 0x2B, 0x4E, 0x5A, 0x51, 0x54, 0x51, 0x30, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, ++ 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4D, 0x42, 0x51, 0x41, 0x77, 0x61, 0x54, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x0A, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x53, 0x31, 0x49, 0x78, 0x4A, 0x6A, 0x41, 0x6B, 0x42, 0x67, 0x4E, 0x56, ++ 0x42, 0x41, 0x6F, 0x4D, 0x48, 0x55, 0x35, 0x42, 0x56, 0x6B, 0x56, 0x53, 0x49, 0x45, 0x4A, 0x56, 0x55, 0x30, 0x6C, 0x4F, 0x52, 0x56, 0x4E, 0x54, 0x49, 0x46, 0x42, 0x4D, 0x51, 0x56, 0x52, 0x47, 0x54, 0x31, 0x4A, 0x4E, 0x49, 0x45, 0x4E, 0x76, ++ 0x63, 0x6E, 0x41, 0x75, 0x4D, 0x54, 0x49, 0x77, 0x4D, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x0A, 0x44, 0x43, 0x6C, 0x4F, 0x51, 0x56, 0x5A, 0x46, 0x55, 0x69, 0x42, 0x48, 0x62, 0x47, 0x39, 0x69, 0x59, 0x57, 0x77, 0x67, 0x55, 0x6D, 0x39, ++ 0x76, 0x64, 0x43, 0x42, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x61, 0x57, 0x5A, 0x70, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x49, 0x45, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6D, 0x6C, 0x30, 0x65, 0x54, 0x41, 0x65, 0x46, 0x77, 0x30, ++ 0x78, 0x4E, 0x7A, 0x41, 0x34, 0x4D, 0x54, 0x67, 0x77, 0x4F, 0x44, 0x55, 0x34, 0x0A, 0x4E, 0x44, 0x4A, 0x61, 0x46, 0x77, 0x30, 0x7A, 0x4E, 0x7A, 0x41, 0x34, 0x4D, 0x54, 0x67, 0x79, 0x4D, 0x7A, 0x55, 0x35, 0x4E, 0x54, 0x6C, 0x61, 0x4D, 0x47, ++ 0x6B, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x74, 0x53, 0x4D, 0x53, 0x59, 0x77, 0x4A, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x44, 0x42, 0x31, 0x4F, 0x51, 0x56, 0x5A, 0x46, 0x55, 0x69, ++ 0x42, 0x43, 0x56, 0x56, 0x4E, 0x4A, 0x54, 0x6B, 0x56, 0x54, 0x0A, 0x55, 0x79, 0x42, 0x51, 0x54, 0x45, 0x46, 0x55, 0x52, 0x6B, 0x39, 0x53, 0x54, 0x53, 0x42, 0x44, 0x62, 0x33, 0x4A, 0x77, 0x4C, 0x6A, 0x45, 0x79, 0x4D, 0x44, 0x41, 0x47, 0x41, ++ 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x70, 0x54, 0x6B, 0x46, 0x57, 0x52, 0x56, 0x49, 0x67, 0x52, 0x32, 0x78, 0x76, 0x59, 0x6D, 0x46, 0x73, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6C, 0x6D, 0x61, ++ 0x57, 0x4E, 0x68, 0x64, 0x47, 0x6C, 0x76, 0x0A, 0x62, 0x69, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6F, 0x62, 0x33, 0x4A, 0x70, 0x64, 0x48, 0x6B, 0x77, 0x67, 0x67, 0x49, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, ++ 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x43, 0x32, 0x31, 0x50, 0x47, 0x54, 0x58, 0x4C, 0x56, 0x41, 0x69, 0x51, 0x71, 0x72, ++ 0x44, 0x5A, 0x42, 0x62, 0x0A, 0x55, 0x47, 0x4F, 0x75, 0x6B, 0x4A, 0x52, 0x30, 0x46, 0x30, 0x56, 0x79, 0x31, 0x6E, 0x74, 0x6C, 0x57, 0x69, 0x6C, 0x4C, 0x70, 0x31, 0x61, 0x67, 0x53, 0x37, 0x67, 0x76, 0x51, 0x6E, 0x58, 0x70, 0x32, 0x58, 0x73, ++ 0x6B, 0x57, 0x6A, 0x46, 0x6C, 0x71, 0x78, 0x63, 0x58, 0x30, 0x54, 0x4D, 0x36, 0x32, 0x52, 0x48, 0x63, 0x51, 0x44, 0x61, 0x48, 0x33, 0x38, 0x64, 0x71, 0x36, 0x53, 0x5A, 0x65, 0x57, 0x59, 0x70, 0x33, 0x34, 0x2B, 0x68, 0x49, 0x6E, 0x44, 0x45, ++ 0x57, 0x0A, 0x2B, 0x6A, 0x36, 0x52, 0x73, 0x63, 0x72, 0x4A, 0x6F, 0x2B, 0x4B, 0x66, 0x7A, 0x69, 0x46, 0x54, 0x6F, 0x77, 0x49, 0x32, 0x4D, 0x4D, 0x74, 0x53, 0x41, 0x75, 0x58, 0x61, 0x4D, 0x6C, 0x33, 0x44, 0x78, 0x65, 0x62, 0x35, 0x37, 0x68, ++ 0x48, 0x48, 0x69, 0x38, 0x6C, 0x45, 0x48, 0x6F, 0x53, 0x54, 0x47, 0x45, 0x71, 0x30, 0x6E, 0x2B, 0x55, 0x53, 0x5A, 0x47, 0x6E, 0x51, 0x4A, 0x6F, 0x56, 0x69, 0x41, 0x62, 0x62, 0x4A, 0x41, 0x68, 0x32, 0x2B, 0x67, 0x31, 0x47, 0x37, 0x0A, 0x58, ++ 0x4E, 0x72, 0x34, 0x72, 0x52, 0x56, 0x71, 0x6D, 0x66, 0x65, 0x53, 0x56, 0x50, 0x63, 0x30, 0x57, 0x2B, 0x6D, 0x2F, 0x36, 0x69, 0x6D, 0x42, 0x45, 0x74, 0x52, 0x54, 0x6B, 0x5A, 0x61, 0x7A, 0x6B, 0x56, 0x72, 0x64, 0x2F, 0x70, 0x42, 0x7A, 0x4B, ++ 0x50, 0x73, 0x77, 0x52, 0x72, 0x58, 0x4B, 0x43, 0x41, 0x66, 0x48, 0x63, 0x58, 0x4C, 0x4A, 0x5A, 0x74, 0x4D, 0x30, 0x6C, 0x2F, 0x61, 0x4D, 0x39, 0x42, 0x68, 0x4B, 0x34, 0x64, 0x41, 0x39, 0x57, 0x6B, 0x57, 0x32, 0x0A, 0x61, 0x61, 0x63, 0x70, ++ 0x2B, 0x79, 0x50, 0x4F, 0x69, 0x4E, 0x67, 0x53, 0x6E, 0x41, 0x42, 0x49, 0x71, 0x4B, 0x59, 0x50, 0x73, 0x7A, 0x75, 0x53, 0x6A, 0x58, 0x45, 0x4F, 0x64, 0x4D, 0x57, 0x4C, 0x79, 0x45, 0x7A, 0x35, 0x39, 0x4A, 0x75, 0x4F, 0x75, 0x44, 0x78, 0x70, ++ 0x37, 0x57, 0x38, 0x37, 0x55, 0x43, 0x39, 0x59, 0x37, 0x63, 0x53, 0x77, 0x30, 0x42, 0x77, 0x62, 0x61, 0x67, 0x7A, 0x69, 0x76, 0x45, 0x53, 0x71, 0x32, 0x4D, 0x30, 0x55, 0x58, 0x5A, 0x52, 0x34, 0x0A, 0x59, 0x62, 0x38, 0x4F, 0x62, 0x74, 0x6F, ++ 0x71, 0x76, 0x43, 0x38, 0x4D, 0x43, 0x33, 0x47, 0x6D, 0x73, 0x78, 0x59, 0x2F, 0x6E, 0x4F, 0x62, 0x35, 0x7A, 0x4A, 0x39, 0x54, 0x4E, 0x65, 0x49, 0x44, 0x6F, 0x4B, 0x41, 0x59, 0x76, 0x37, 0x76, 0x78, 0x76, 0x76, 0x54, 0x57, 0x6A, 0x49, 0x63, ++ 0x4E, 0x51, 0x76, 0x63, 0x47, 0x75, 0x66, 0x46, 0x74, 0x37, 0x51, 0x53, 0x55, 0x71, 0x50, 0x36, 0x32, 0x30, 0x77, 0x62, 0x47, 0x51, 0x47, 0x48, 0x66, 0x6E, 0x5A, 0x33, 0x7A, 0x0A, 0x56, 0x48, 0x62, 0x4F, 0x55, 0x7A, 0x6F, 0x42, 0x70, 0x70, ++ 0x4A, 0x42, 0x37, 0x41, 0x53, 0x6A, 0x6A, 0x77, 0x32, 0x69, 0x31, 0x51, 0x6E, 0x4B, 0x31, 0x73, 0x75, 0x61, 0x38, 0x65, 0x39, 0x44, 0x58, 0x63, 0x43, 0x72, 0x70, 0x55, 0x48, 0x50, 0x58, 0x46, 0x4E, 0x77, 0x63, 0x4D, 0x6D, 0x49, 0x70, 0x69, ++ 0x33, 0x55, 0x61, 0x32, 0x46, 0x7A, 0x55, 0x43, 0x61, 0x47, 0x59, 0x51, 0x35, 0x66, 0x47, 0x38, 0x49, 0x72, 0x34, 0x6F, 0x7A, 0x56, 0x75, 0x35, 0x33, 0x42, 0x0A, 0x41, 0x30, 0x4B, 0x36, 0x6C, 0x4E, 0x70, 0x66, 0x71, 0x62, 0x44, 0x4B, 0x7A, ++ 0x45, 0x30, 0x4B, 0x37, 0x30, 0x64, 0x70, 0x41, 0x79, 0x38, 0x69, 0x2B, 0x2F, 0x45, 0x6F, 0x7A, 0x72, 0x39, 0x64, 0x55, 0x47, 0x57, 0x6F, 0x6B, 0x47, 0x32, 0x7A, 0x64, 0x4C, 0x41, 0x49, 0x78, 0x36, 0x79, 0x6F, 0x30, 0x65, 0x73, 0x2B, 0x6E, ++ 0x50, 0x78, 0x64, 0x47, 0x6F, 0x4D, 0x75, 0x4B, 0x38, 0x75, 0x31, 0x38, 0x30, 0x53, 0x64, 0x4F, 0x71, 0x63, 0x58, 0x59, 0x5A, 0x61, 0x69, 0x0A, 0x63, 0x64, 0x4E, 0x77, 0x6C, 0x68, 0x56, 0x4E, 0x74, 0x30, 0x78, 0x7A, 0x37, 0x68, 0x6C, 0x63, ++ 0x78, 0x56, 0x73, 0x2B, 0x51, 0x66, 0x36, 0x73, 0x64, 0x57, 0x41, 0x37, 0x47, 0x32, 0x50, 0x4F, 0x41, 0x4E, 0x33, 0x61, 0x43, 0x4A, 0x42, 0x69, 0x74, 0x4F, 0x55, 0x74, 0x37, 0x6B, 0x69, 0x6E, 0x61, 0x78, 0x65, 0x5A, 0x56, 0x4C, 0x36, 0x48, ++ 0x53, 0x75, 0x4F, 0x70, 0x58, 0x67, 0x52, 0x4D, 0x36, 0x78, 0x42, 0x74, 0x56, 0x4E, 0x62, 0x76, 0x38, 0x65, 0x6A, 0x79, 0x0A, 0x59, 0x68, 0x62, 0x4C, 0x67, 0x47, 0x76, 0x74, 0x50, 0x65, 0x33, 0x31, 0x48, 0x7A, 0x43, 0x6C, 0x72, 0x6B, 0x76, ++ 0x4A, 0x45, 0x2B, 0x32, 0x4B, 0x41, 0x51, 0x48, 0x4A, 0x75, 0x46, 0x46, 0x59, 0x77, 0x47, 0x59, 0x36, 0x73, 0x57, 0x5A, 0x4C, 0x78, 0x4E, 0x55, 0x78, 0x41, 0x6D, 0x4C, 0x70, 0x64, 0x49, 0x51, 0x4D, 0x32, 0x30, 0x31, 0x47, 0x4C, 0x51, 0x49, ++ 0x44, 0x41, 0x51, 0x41, 0x42, 0x6F, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x0A, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x30, 0x70, 0x2B, 0x49, 0x33, 0x36, 0x48, 0x4E, 0x4C, 0x4C, 0x33, 0x73, 0x39, 0x54, ++ 0x73, 0x42, 0x41, 0x5A, 0x4D, 0x7A, 0x4A, 0x37, 0x4C, 0x72, 0x59, 0x45, 0x73, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, ++ 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x0A, 0x41, 0x66, 0x38, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4D, 0x42, 0x51, 0x41, 0x44, 0x67, ++ 0x67, 0x49, 0x42, 0x41, 0x44, 0x4C, 0x4B, 0x67, 0x4C, 0x4F, 0x64, 0x50, 0x56, 0x51, 0x47, 0x33, 0x64, 0x4C, 0x53, 0x4C, 0x76, 0x43, 0x6B, 0x41, 0x53, 0x45, 0x4C, 0x5A, 0x30, 0x6A, 0x4B, 0x62, 0x59, 0x37, 0x67, 0x79, 0x4B, 0x6F, 0x4E, 0x71, ++ 0x6F, 0x30, 0x68, 0x56, 0x34, 0x2F, 0x47, 0x50, 0x6E, 0x72, 0x4B, 0x0A, 0x32, 0x31, 0x48, 0x55, 0x55, 0x72, 0x50, 0x55, 0x6C, 0x6F, 0x53, 0x6C, 0x57, 0x47, 0x42, 0x2F, 0x35, 0x51, 0x75, 0x4F, 0x48, 0x2F, 0x58, 0x63, 0x43, 0x68, 0x57, 0x42, ++ 0x35, 0x54, 0x75, 0x32, 0x74, 0x79, 0x49, 0x76, 0x43, 0x5A, 0x77, 0x54, 0x46, 0x72, 0x46, 0x73, 0x44, 0x44, 0x55, 0x49, 0x62, 0x61, 0x74, 0x6A, 0x63, 0x75, 0x33, 0x63, 0x76, 0x75, 0x7A, 0x48, 0x56, 0x2B, 0x59, 0x77, 0x49, 0x48, 0x48, 0x57, ++ 0x31, 0x78, 0x44, 0x42, 0x45, 0x31, 0x55, 0x42, 0x0A, 0x6A, 0x43, 0x70, 0x44, 0x35, 0x45, 0x48, 0x78, 0x7A, 0x7A, 0x70, 0x36, 0x55, 0x35, 0x4C, 0x4F, 0x6F, 0x67, 0x4D, 0x46, 0x44, 0x54, 0x6A, 0x66, 0x41, 0x72, 0x73, 0x51, 0x4C, 0x74, 0x6B, ++ 0x37, 0x30, 0x70, 0x74, 0x36, 0x77, 0x4B, 0x47, 0x6D, 0x2B, 0x4C, 0x55, 0x78, 0x35, 0x76, 0x52, 0x31, 0x79, 0x62, 0x6C, 0x54, 0x6D, 0x58, 0x56, 0x48, 0x49, 0x6C, 0x6F, 0x55, 0x46, 0x63, 0x64, 0x34, 0x47, 0x37, 0x61, 0x64, 0x36, 0x51, 0x7A, ++ 0x34, 0x47, 0x33, 0x62, 0x78, 0x0A, 0x68, 0x59, 0x54, 0x65, 0x6F, 0x64, 0x6F, 0x53, 0x37, 0x36, 0x54, 0x69, 0x45, 0x4A, 0x64, 0x36, 0x65, 0x4E, 0x34, 0x4D, 0x55, 0x5A, 0x65, 0x6F, 0x49, 0x55, 0x43, 0x4C, 0x68, 0x72, 0x30, 0x4E, 0x38, 0x46, ++ 0x35, 0x4F, 0x53, 0x7A, 0x61, 0x37, 0x4F, 0x79, 0x41, 0x66, 0x69, 0x6B, 0x4A, 0x57, 0x34, 0x51, 0x73, 0x61, 0x76, 0x33, 0x76, 0x51, 0x49, 0x6B, 0x4D, 0x73, 0x52, 0x49, 0x7A, 0x37, 0x35, 0x53, 0x71, 0x30, 0x62, 0x42, 0x77, 0x63, 0x75, 0x70, ++ 0x54, 0x67, 0x0A, 0x45, 0x33, 0x34, 0x68, 0x35, 0x70, 0x72, 0x43, 0x79, 0x38, 0x56, 0x43, 0x5A, 0x4C, 0x51, 0x65, 0x6C, 0x48, 0x73, 0x49, 0x4A, 0x63, 0x68, 0x78, 0x7A, 0x49, 0x64, 0x46, 0x56, 0x34, 0x58, 0x54, 0x6E, 0x79, 0x6C, 0x69, 0x49, ++ 0x6F, 0x4E, 0x52, 0x6C, 0x77, 0x41, 0x59, 0x6C, 0x33, 0x64, 0x71, 0x6D, 0x4A, 0x4C, 0x4A, 0x66, 0x47, 0x42, 0x73, 0x33, 0x32, 0x78, 0x39, 0x53, 0x75, 0x52, 0x77, 0x54, 0x4D, 0x4B, 0x65, 0x75, 0x42, 0x33, 0x33, 0x30, 0x44, 0x54, 0x48, 0x0A, ++ 0x44, 0x38, 0x7A, 0x37, 0x70, 0x2F, 0x38, 0x44, 0x76, 0x71, 0x31, 0x77, 0x6B, 0x4E, 0x6F, 0x4C, 0x33, 0x63, 0x68, 0x74, 0x6C, 0x31, 0x2B, 0x61, 0x66, 0x77, 0x6B, 0x79, 0x51, 0x66, 0x33, 0x4E, 0x6F, 0x73, 0x78, 0x61, 0x62, 0x55, 0x7A, 0x79, ++ 0x71, 0x6B, 0x6E, 0x2B, 0x5A, 0x76, 0x6A, 0x70, 0x32, 0x44, 0x58, 0x72, 0x44, 0x69, 0x67, 0x65, 0x37, 0x6B, 0x67, 0x76, 0x4F, 0x74, 0x42, 0x35, 0x43, 0x54, 0x68, 0x38, 0x70, 0x69, 0x4B, 0x43, 0x6B, 0x35, 0x58, 0x51, 0x0A, 0x41, 0x37, 0x36, ++ 0x2B, 0x41, 0x71, 0x41, 0x46, 0x33, 0x53, 0x41, 0x69, 0x34, 0x32, 0x38, 0x64, 0x69, 0x44, 0x52, 0x67, 0x78, 0x75, 0x59, 0x4B, 0x75, 0x51, 0x6C, 0x31, 0x43, 0x2F, 0x41, 0x48, 0x36, 0x47, 0x6D, 0x57, 0x4E, 0x63, 0x66, 0x37, 0x49, 0x34, 0x47, ++ 0x4F, 0x4F, 0x44, 0x6D, 0x34, 0x52, 0x53, 0x74, 0x44, 0x65, 0x4B, 0x4C, 0x52, 0x4C, 0x42, 0x54, 0x2F, 0x44, 0x53, 0x68, 0x79, 0x63, 0x70, 0x57, 0x62, 0x58, 0x67, 0x6E, 0x62, 0x69, 0x55, 0x53, 0x59, 0x0A, 0x71, 0x71, 0x46, 0x4A, 0x75, 0x33, ++ 0x46, 0x53, 0x38, 0x72, 0x2F, 0x32, 0x2F, 0x79, 0x65, 0x68, 0x4E, 0x71, 0x2B, 0x34, 0x74, 0x6E, 0x65, 0x49, 0x33, 0x54, 0x71, 0x6B, 0x62, 0x5A, 0x73, 0x30, 0x6B, 0x4E, 0x77, 0x55, 0x58, 0x54, 0x43, 0x2F, 0x74, 0x2B, 0x73, 0x58, 0x35, 0x49, ++ 0x65, 0x33, 0x63, 0x64, 0x43, 0x68, 0x31, 0x33, 0x63, 0x56, 0x31, 0x45, 0x4C, 0x58, 0x38, 0x76, 0x4D, 0x78, 0x6D, 0x56, 0x32, 0x62, 0x33, 0x52, 0x5A, 0x74, 0x50, 0x2B, 0x6F, 0x47, 0x0A, 0x49, 0x2F, 0x68, 0x47, 0x6F, 0x69, 0x4C, 0x74, 0x6B, ++ 0x2F, 0x62, 0x64, 0x6D, 0x75, 0x59, 0x71, 0x68, 0x37, 0x47, 0x59, 0x56, 0x50, 0x45, 0x69, 0x39, 0x32, 0x74, 0x46, 0x34, 0x2B, 0x4B, 0x4F, 0x64, 0x68, 0x32, 0x61, 0x6A, 0x63, 0x51, 0x47, 0x6A, 0x54, 0x61, 0x33, 0x46, 0x50, 0x4F, 0x64, 0x56, ++ 0x47, 0x6D, 0x33, 0x6A, 0x6A, 0x7A, 0x56, 0x70, 0x47, 0x32, 0x54, 0x67, 0x62, 0x65, 0x74, 0x39, 0x72, 0x31, 0x6B, 0x65, 0x38, 0x4C, 0x4A, 0x61, 0x44, 0x6D, 0x67, 0x0A, 0x6B, 0x70, 0x7A, 0x4E, 0x4E, 0x49, 0x61, 0x52, 0x6B, 0x50, 0x70, 0x6B, ++ 0x55, 0x5A, 0x33, 0x2B, 0x2F, 0x75, 0x75, 0x6C, 0x39, 0x58, 0x58, 0x65, 0x69, 0x66, 0x64, 0x79, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, ++ 0x2D, 0x2D, 0x0A, 0x0A, 0x41, 0x43, 0x20, 0x52, 0x41, 0x49, 0x5A, 0x20, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x20, 0x53, 0x45, 0x52, 0x56, 0x49, 0x44, 0x4F, 0x52, 0x45, 0x53, 0x20, 0x53, 0x45, 0x47, 0x55, 0x52, 0x4F, 0x53, 0x0A, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x62, 0x6A, 0x43, 0x43, 0x41, 0x66, 0x4F, 0x67, 0x41, 0x77, 0x49, 0x42, ++ 0x41, 0x67, 0x49, 0x51, 0x59, 0x76, 0x59, 0x79, 0x62, 0x4F, 0x58, 0x45, 0x34, 0x32, 0x68, 0x63, 0x47, 0x32, 0x4C, 0x64, 0x6E, 0x43, 0x36, 0x64, 0x6C, 0x54, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, ++ 0x41, 0x7A, 0x42, 0x34, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x46, 0x0A, 0x55, 0x7A, 0x45, 0x52, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x49, 0x52, 0x6B, 0x35, ++ 0x4E, 0x56, 0x43, 0x31, 0x53, 0x51, 0x30, 0x30, 0x78, 0x44, 0x6A, 0x41, 0x4D, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x73, 0x4D, 0x42, 0x55, 0x4E, 0x6C, 0x63, 0x6D, 0x56, 0x7A, 0x4D, 0x52, 0x67, 0x77, 0x46, 0x67, 0x59, 0x44, 0x56, 0x51, 0x52, ++ 0x68, 0x44, 0x41, 0x39, 0x57, 0x51, 0x56, 0x52, 0x46, 0x55, 0x79, 0x31, 0x52, 0x4D, 0x6A, 0x67, 0x79, 0x0A, 0x4E, 0x6A, 0x41, 0x77, 0x4E, 0x45, 0x6F, 0x78, 0x4C, 0x44, 0x41, 0x71, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x49, 0x30, ++ 0x46, 0x44, 0x49, 0x46, 0x4A, 0x42, 0x53, 0x56, 0x6F, 0x67, 0x52, 0x6B, 0x35, 0x4E, 0x56, 0x43, 0x31, 0x53, 0x51, 0x30, 0x30, 0x67, 0x55, 0x30, 0x56, 0x53, 0x56, 0x6B, 0x6C, 0x45, 0x54, 0x31, 0x4A, 0x46, 0x55, 0x79, 0x42, 0x54, 0x52, 0x55, ++ 0x64, 0x56, 0x55, 0x6B, 0x39, 0x54, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x45, 0x34, 0x0A, 0x4D, 0x54, 0x49, 0x79, 0x4D, 0x44, 0x41, 0x35, 0x4D, 0x7A, 0x63, 0x7A, 0x4D, 0x31, 0x6F, 0x58, 0x44, 0x54, 0x51, 0x7A, 0x4D, 0x54, 0x49, 0x79, 0x4D, ++ 0x44, 0x41, 0x35, 0x4D, 0x7A, 0x63, 0x7A, 0x4D, 0x31, 0x6F, 0x77, 0x65, 0x44, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x52, 0x56, 0x4D, 0x78, 0x45, 0x54, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x42, ++ 0x41, 0x6F, 0x4D, 0x43, 0x45, 0x5A, 0x4F, 0x54, 0x56, 0x51, 0x74, 0x0A, 0x55, 0x6B, 0x4E, 0x4E, 0x4D, 0x51, 0x34, 0x77, 0x44, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, 0x44, 0x41, 0x56, 0x44, 0x5A, 0x58, 0x4A, 0x6C, 0x63, 0x7A, 0x45, 0x59, ++ 0x4D, 0x42, 0x59, 0x47, 0x41, 0x31, 0x55, 0x45, 0x59, 0x51, 0x77, 0x50, 0x56, 0x6B, 0x46, 0x55, 0x52, 0x56, 0x4D, 0x74, 0x55, 0x54, 0x49, 0x34, 0x4D, 0x6A, 0x59, 0x77, 0x4D, 0x44, 0x52, 0x4B, 0x4D, 0x53, 0x77, 0x77, 0x4B, 0x67, 0x59, 0x44, ++ 0x56, 0x51, 0x51, 0x44, 0x44, 0x43, 0x4E, 0x42, 0x0A, 0x51, 0x79, 0x42, 0x53, 0x51, 0x55, 0x6C, 0x61, 0x49, 0x45, 0x5A, 0x4F, 0x54, 0x56, 0x51, 0x74, 0x55, 0x6B, 0x4E, 0x4E, 0x49, 0x46, 0x4E, 0x46, 0x55, 0x6C, 0x5A, 0x4A, 0x52, 0x45, 0x39, ++ 0x53, 0x52, 0x56, 0x4D, 0x67, 0x55, 0x30, 0x56, 0x48, 0x56, 0x56, 0x4A, 0x50, 0x55, 0x7A, 0x42, 0x32, 0x4D, 0x42, 0x41, 0x47, 0x42, 0x79, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x41, 0x67, 0x45, 0x47, 0x42, 0x53, 0x75, 0x42, 0x42, 0x41, 0x41, ++ 0x69, 0x41, 0x32, 0x49, 0x41, 0x0A, 0x42, 0x50, 0x61, 0x36, 0x56, 0x31, 0x50, 0x49, 0x79, 0x71, 0x76, 0x66, 0x4E, 0x6B, 0x70, 0x53, 0x49, 0x65, 0x53, 0x58, 0x30, 0x6F, 0x4E, 0x6E, 0x6E, 0x76, 0x42, 0x6C, 0x55, 0x64, 0x42, 0x65, 0x68, 0x38, ++ 0x64, 0x48, 0x73, 0x56, 0x6E, 0x79, 0x56, 0x30, 0x65, 0x62, 0x41, 0x41, 0x4B, 0x54, 0x52, 0x42, 0x64, 0x70, 0x32, 0x30, 0x4C, 0x48, 0x73, 0x62, 0x49, 0x36, 0x47, 0x41, 0x36, 0x30, 0x58, 0x59, 0x79, 0x7A, 0x5A, 0x6C, 0x32, 0x68, 0x4E, 0x50, ++ 0x6B, 0x32, 0x0A, 0x4C, 0x45, 0x6E, 0x62, 0x38, 0x30, 0x62, 0x38, 0x73, 0x30, 0x52, 0x70, 0x52, 0x42, 0x4E, 0x6D, 0x2F, 0x64, 0x66, 0x46, 0x2F, 0x61, 0x38, 0x32, 0x54, 0x63, 0x34, 0x44, 0x54, 0x51, 0x64, 0x78, 0x7A, 0x36, 0x39, 0x71, 0x42, ++ 0x64, 0x4B, 0x69, 0x51, 0x31, 0x6F, 0x4B, 0x55, 0x6D, 0x38, 0x42, 0x41, 0x30, 0x36, 0x4F, 0x69, 0x36, 0x4E, 0x43, 0x4D, 0x45, 0x41, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x0A, ++ 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x51, 0x59, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, ++ 0x46, 0x41, 0x47, 0x35, 0x4C, 0x2B, 0x2B, 0x2F, 0x45, 0x59, 0x5A, 0x67, 0x38, 0x6B, 0x2F, 0x51, 0x51, 0x57, 0x36, 0x72, 0x63, 0x78, 0x2F, 0x6E, 0x30, 0x6D, 0x35, 0x4A, 0x4D, 0x41, 0x6F, 0x47, 0x43, 0x43, 0x71, 0x47, 0x0A, 0x53, 0x4D, 0x34, ++ 0x39, 0x42, 0x41, 0x4D, 0x44, 0x41, 0x32, 0x6B, 0x41, 0x4D, 0x47, 0x59, 0x43, 0x4D, 0x51, 0x43, 0x75, 0x53, 0x75, 0x4D, 0x72, 0x51, 0x4D, 0x4E, 0x30, 0x45, 0x66, 0x4B, 0x56, 0x72, 0x52, 0x59, 0x6A, 0x33, 0x6B, 0x34, 0x4D, 0x47, 0x75, 0x5A, ++ 0x64, 0x70, 0x53, 0x52, 0x65, 0x61, 0x30, 0x52, 0x37, 0x2F, 0x44, 0x6A, 0x69, 0x54, 0x38, 0x75, 0x63, 0x52, 0x52, 0x63, 0x52, 0x54, 0x42, 0x51, 0x6E, 0x4A, 0x6C, 0x55, 0x35, 0x64, 0x55, 0x6F, 0x44, 0x0A, 0x7A, 0x42, 0x4F, 0x51, 0x6E, 0x35, ++ 0x49, 0x43, 0x4D, 0x51, 0x44, 0x36, 0x53, 0x6D, 0x78, 0x67, 0x69, 0x48, 0x50, 0x7A, 0x37, 0x72, 0x69, 0x59, 0x59, 0x71, 0x6E, 0x4F, 0x4B, 0x38, 0x4C, 0x5A, 0x69, 0x71, 0x5A, 0x77, 0x4D, 0x52, 0x32, 0x76, 0x73, 0x4A, 0x52, 0x4D, 0x36, 0x30, ++ 0x2F, 0x47, 0x34, 0x39, 0x48, 0x7A, 0x59, 0x71, 0x63, 0x38, 0x2F, 0x35, 0x4D, 0x75, 0x42, 0x31, 0x78, 0x4A, 0x41, 0x57, 0x64, 0x70, 0x45, 0x67, 0x4A, 0x79, 0x76, 0x2B, 0x63, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, ++ 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x34, 0x36, 0x0A, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, ++ 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x57, 0x6A, 0x43, 0x43, 0x41, 0x30, 0x4B, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x53, 0x45, 0x64, 0x4B, 0x37, 0x75, 0x64, 0x63, 0x6A, 0x47, 0x4A, 0x35, 0x41, 0x58, 0x77, ++ 0x71, 0x64, 0x4C, 0x64, 0x44, 0x66, 0x4A, 0x57, 0x66, 0x52, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x44, 0x41, 0x55, 0x41, 0x4D, 0x45, 0x59, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, ++ 0x4E, 0x56, 0x0A, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x4A, 0x46, 0x4D, 0x52, 0x6B, 0x77, 0x46, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x78, 0x42, 0x48, 0x62, 0x47, 0x39, 0x69, 0x59, 0x57, 0x78, 0x54, 0x61, 0x57, 0x64, 0x75, 0x49, ++ 0x47, 0x35, 0x32, 0x4C, 0x58, 0x4E, 0x68, 0x4D, 0x52, 0x77, 0x77, 0x47, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x4E, 0x48, 0x62, 0x47, 0x39, 0x69, 0x59, 0x57, 0x78, 0x54, 0x61, 0x57, 0x64, 0x75, 0x49, 0x46, 0x4A, 0x76, 0x0A, ++ 0x62, 0x33, 0x51, 0x67, 0x55, 0x6A, 0x51, 0x32, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x45, 0x35, 0x4D, 0x44, 0x4D, 0x79, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x46, 0x6F, 0x58, 0x44, 0x54, 0x51, 0x32, 0x4D, 0x44, 0x4D, 0x79, ++ 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x46, 0x6F, 0x77, 0x52, 0x6A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x51, 0x6B, 0x55, 0x78, 0x47, 0x54, 0x41, 0x58, 0x0A, 0x42, 0x67, 0x4E, ++ 0x56, 0x42, 0x41, 0x6F, 0x54, 0x45, 0x45, 0x64, 0x73, 0x62, 0x32, 0x4A, 0x68, 0x62, 0x46, 0x4E, 0x70, 0x5A, 0x32, 0x34, 0x67, 0x62, 0x6E, 0x59, 0x74, 0x63, 0x32, 0x45, 0x78, 0x48, 0x44, 0x41, 0x61, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, ++ 0x54, 0x45, 0x30, 0x64, 0x73, 0x62, 0x32, 0x4A, 0x68, 0x62, 0x46, 0x4E, 0x70, 0x5A, 0x32, 0x34, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x53, 0x4E, 0x44, 0x59, 0x77, 0x67, 0x67, 0x49, 0x69, 0x0A, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, ++ 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x43, 0x73, 0x72, 0x48, 0x51, 0x79, 0x36, 0x4C, ++ 0x4E, 0x6C, 0x35, 0x62, 0x72, 0x74, 0x51, 0x79, 0x59, 0x64, 0x70, 0x6F, 0x6B, 0x4E, 0x52, 0x62, 0x6F, 0x70, 0x69, 0x4C, 0x4B, 0x6B, 0x48, 0x57, 0x50, 0x64, 0x30, 0x38, 0x45, 0x73, 0x0A, 0x43, 0x56, 0x65, 0x4A, 0x4F, 0x61, 0x46, 0x56, 0x36, ++ 0x57, 0x63, 0x30, 0x64, 0x77, 0x78, 0x75, 0x35, 0x46, 0x55, 0x64, 0x55, 0x69, 0x58, 0x53, 0x45, 0x32, 0x74, 0x65, 0x34, 0x52, 0x32, 0x70, 0x74, 0x33, 0x32, 0x4A, 0x4D, 0x6C, 0x38, 0x4E, 0x6E, 0x70, 0x38, 0x73, 0x65, 0x6D, 0x4E, 0x67, 0x51, ++ 0x42, 0x2B, 0x6D, 0x73, 0x4C, 0x5A, 0x34, 0x6A, 0x35, 0x6C, 0x55, 0x6C, 0x67, 0x68, 0x59, 0x72, 0x75, 0x51, 0x47, 0x76, 0x47, 0x49, 0x46, 0x41, 0x68, 0x61, 0x2F, 0x0A, 0x72, 0x36, 0x67, 0x6A, 0x41, 0x37, 0x61, 0x55, 0x44, 0x37, 0x78, 0x75, ++ 0x62, 0x4D, 0x4C, 0x4C, 0x31, 0x61, 0x61, 0x37, 0x44, 0x4F, 0x6E, 0x32, 0x77, 0x51, 0x4C, 0x37, 0x49, 0x64, 0x35, 0x6D, 0x33, 0x52, 0x65, 0x72, 0x64, 0x45, 0x4C, 0x76, 0x38, 0x48, 0x51, 0x76, 0x4A, 0x66, 0x54, 0x71, 0x61, 0x31, 0x56, 0x62, ++ 0x6B, 0x4E, 0x75, 0x64, 0x33, 0x31, 0x36, 0x48, 0x43, 0x6B, 0x44, 0x37, 0x72, 0x52, 0x6C, 0x72, 0x2B, 0x2F, 0x66, 0x4B, 0x59, 0x49, 0x6A, 0x65, 0x0A, 0x32, 0x73, 0x47, 0x50, 0x31, 0x71, 0x37, 0x56, 0x66, 0x39, 0x51, 0x38, 0x67, 0x2B, 0x37, ++ 0x58, 0x46, 0x6B, 0x79, 0x44, 0x52, 0x54, 0x4E, 0x72, 0x4A, 0x39, 0x43, 0x47, 0x30, 0x42, 0x77, 0x74, 0x61, 0x2F, 0x4F, 0x72, 0x66, 0x66, 0x47, 0x46, 0x71, 0x66, 0x55, 0x6F, 0x30, 0x71, 0x33, 0x76, 0x38, 0x34, 0x52, 0x4C, 0x48, 0x49, 0x66, ++ 0x38, 0x45, 0x36, 0x4D, 0x36, 0x63, 0x71, 0x4A, 0x61, 0x45, 0x53, 0x76, 0x57, 0x4A, 0x33, 0x45, 0x6E, 0x37, 0x59, 0x45, 0x74, 0x0A, 0x62, 0x57, 0x61, 0x42, 0x6B, 0x6F, 0x65, 0x30, 0x47, 0x31, 0x68, 0x36, 0x7A, 0x44, 0x38, 0x4B, 0x2B, 0x6B, ++ 0x5A, 0x50, 0x54, 0x58, 0x68, 0x63, 0x2B, 0x43, 0x74, 0x49, 0x34, 0x77, 0x53, 0x45, 0x79, 0x31, 0x33, 0x32, 0x74, 0x47, 0x71, 0x7A, 0x5A, 0x66, 0x78, 0x43, 0x6E, 0x6C, 0x45, 0x6D, 0x49, 0x79, 0x44, 0x4C, 0x50, 0x52, 0x54, 0x35, 0x67, 0x65, ++ 0x31, 0x6C, 0x46, 0x67, 0x42, 0x50, 0x47, 0x6D, 0x53, 0x58, 0x5A, 0x67, 0x6A, 0x50, 0x6A, 0x48, 0x76, 0x6A, 0x0A, 0x4B, 0x38, 0x43, 0x64, 0x2B, 0x52, 0x54, 0x79, 0x47, 0x2F, 0x46, 0x57, 0x61, 0x68, 0x61, 0x2F, 0x4C, 0x49, 0x57, 0x46, 0x7A, ++ 0x58, 0x67, 0x34, 0x6D, 0x75, 0x74, 0x43, 0x61, 0x67, 0x49, 0x30, 0x47, 0x49, 0x4D, 0x58, 0x54, 0x70, 0x52, 0x57, 0x2B, 0x4C, 0x61, 0x43, 0x74, 0x66, 0x4F, 0x57, 0x33, 0x54, 0x33, 0x7A, 0x76, 0x6E, 0x38, 0x67, 0x64, 0x7A, 0x35, 0x37, 0x47, ++ 0x53, 0x4E, 0x72, 0x4C, 0x4E, 0x52, 0x79, 0x63, 0x30, 0x4E, 0x58, 0x66, 0x65, 0x44, 0x34, 0x0A, 0x31, 0x32, 0x6C, 0x50, 0x46, 0x7A, 0x59, 0x45, 0x2B, 0x63, 0x43, 0x51, 0x59, 0x44, 0x64, 0x46, 0x33, 0x75, 0x59, 0x4D, 0x32, 0x48, 0x53, 0x4E, ++ 0x72, 0x70, 0x79, 0x69, 0x62, 0x58, 0x52, 0x64, 0x51, 0x72, 0x34, 0x47, 0x39, 0x64, 0x6C, 0x6B, 0x62, 0x67, 0x49, 0x51, 0x72, 0x49, 0x6D, 0x77, 0x54, 0x44, 0x73, 0x48, 0x54, 0x55, 0x42, 0x2B, 0x4A, 0x4D, 0x57, 0x4B, 0x6D, 0x49, 0x4A, 0x35, ++ 0x6A, 0x71, 0x53, 0x6E, 0x67, 0x69, 0x43, 0x4E, 0x49, 0x2F, 0x6F, 0x6E, 0x0A, 0x63, 0x63, 0x6E, 0x66, 0x78, 0x6B, 0x46, 0x30, 0x6F, 0x45, 0x33, 0x32, 0x6B, 0x52, 0x62, 0x63, 0x52, 0x6F, 0x78, 0x66, 0x4B, 0x57, 0x4D, 0x78, 0x57, 0x58, 0x45, ++ 0x4D, 0x32, 0x47, 0x2F, 0x43, 0x74, 0x6A, 0x4A, 0x39, 0x2B, 0x2B, 0x5A, 0x64, 0x55, 0x36, 0x5A, 0x2B, 0x46, 0x66, 0x79, 0x37, 0x64, 0x58, 0x78, 0x64, 0x37, 0x50, 0x6A, 0x32, 0x46, 0x78, 0x7A, 0x73, 0x78, 0x32, 0x73, 0x5A, 0x79, 0x2F, 0x4E, ++ 0x37, 0x38, 0x43, 0x73, 0x48, 0x70, 0x64, 0x6C, 0x73, 0x0A, 0x65, 0x56, 0x52, 0x32, 0x62, 0x4A, 0x30, 0x63, 0x70, 0x6D, 0x34, 0x4F, 0x36, 0x58, 0x6B, 0x4D, 0x71, 0x43, 0x4E, 0x71, 0x6F, 0x39, 0x38, 0x62, 0x4D, 0x44, 0x47, 0x66, 0x73, 0x56, ++ 0x52, 0x37, 0x2F, 0x6D, 0x72, 0x4C, 0x5A, 0x71, 0x72, 0x63, 0x5A, 0x64, 0x43, 0x69, 0x6E, 0x6B, 0x71, 0x61, 0x42, 0x79, 0x46, 0x72, 0x67, 0x59, 0x2F, 0x62, 0x78, 0x46, 0x6E, 0x36, 0x33, 0x69, 0x4C, 0x41, 0x42, 0x4A, 0x7A, 0x6A, 0x71, 0x6C, ++ 0x73, 0x32, 0x6B, 0x2B, 0x67, 0x39, 0x0A, 0x76, 0x58, 0x71, 0x68, 0x6E, 0x51, 0x74, 0x32, 0x73, 0x51, 0x76, 0x48, 0x6E, 0x66, 0x33, 0x50, 0x6D, 0x4B, 0x67, 0x47, 0x77, 0x76, 0x67, 0x71, 0x6F, 0x36, 0x47, 0x44, 0x6F, 0x4C, 0x63, 0x6C, 0x63, ++ 0x71, 0x55, 0x43, 0x34, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6F, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x59, 0x59, 0x77, 0x44, ++ 0x77, 0x59, 0x44, 0x0A, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x41, 0x31, 0x79, 0x72, ++ 0x63, 0x34, 0x47, 0x48, 0x71, 0x4D, 0x79, 0x77, 0x70, 0x74, 0x57, 0x55, 0x34, 0x6A, 0x61, 0x57, 0x53, 0x66, 0x38, 0x46, 0x6D, 0x53, 0x77, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4D, ++ 0x0A, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x42, 0x41, 0x48, 0x78, 0x34, 0x37, 0x50, 0x59, 0x43, 0x4C, 0x4C, 0x74, 0x62, 0x66, 0x70, 0x49, 0x72, 0x58, 0x54, 0x6E, 0x63, 0x76, 0x74, 0x67, 0x64, 0x6F, 0x6B, 0x49, 0x7A, 0x54, 0x66, 0x6E, ++ 0x76, 0x70, 0x43, 0x6F, 0x37, 0x52, 0x47, 0x6B, 0x65, 0x72, 0x4E, 0x6C, 0x46, 0x6F, 0x30, 0x34, 0x38, 0x70, 0x39, 0x67, 0x6B, 0x55, 0x62, 0x4A, 0x55, 0x48, 0x4A, 0x4E, 0x4F, 0x78, 0x4F, 0x39, 0x37, 0x6B, 0x34, 0x56, 0x67, 0x0A, 0x4A, 0x75, ++ 0x6F, 0x4A, 0x53, 0x4F, 0x44, 0x31, 0x75, 0x38, 0x66, 0x70, 0x61, 0x4E, 0x4B, 0x37, 0x61, 0x6A, 0x46, 0x78, 0x7A, 0x48, 0x6D, 0x75, 0x45, 0x61, 0x6A, 0x77, 0x6D, 0x66, 0x33, 0x6C, 0x48, 0x37, 0x77, 0x76, 0x71, 0x4D, 0x78, 0x58, 0x36, 0x33, ++ 0x62, 0x45, 0x49, 0x61, 0x5A, 0x48, 0x55, 0x31, 0x56, 0x4E, 0x61, 0x4C, 0x38, 0x46, 0x70, 0x4F, 0x37, 0x58, 0x4A, 0x71, 0x74, 0x69, 0x32, 0x6B, 0x4D, 0x33, 0x53, 0x2B, 0x4C, 0x47, 0x74, 0x65, 0x57, 0x79, 0x0A, 0x67, 0x78, 0x6B, 0x36, 0x78, ++ 0x39, 0x50, 0x62, 0x54, 0x5A, 0x34, 0x49, 0x65, 0x76, 0x50, 0x75, 0x7A, 0x7A, 0x35, 0x69, 0x2B, 0x36, 0x7A, 0x6F, 0x59, 0x4D, 0x7A, 0x52, 0x78, 0x36, 0x46, 0x63, 0x67, 0x30, 0x58, 0x45, 0x52, 0x63, 0x7A, 0x7A, 0x46, 0x32, 0x73, 0x55, 0x79, ++ 0x51, 0x51, 0x43, 0x50, 0x74, 0x49, 0x6B, 0x70, 0x6E, 0x6E, 0x70, 0x48, 0x73, 0x36, 0x69, 0x35, 0x38, 0x46, 0x5A, 0x46, 0x5A, 0x38, 0x64, 0x34, 0x6B, 0x75, 0x61, 0x50, 0x70, 0x39, 0x32, 0x0A, 0x43, 0x43, 0x31, 0x72, 0x32, 0x4C, 0x70, 0x58, ++ 0x46, 0x4E, 0x71, 0x44, 0x36, 0x76, 0x36, 0x4D, 0x56, 0x65, 0x6E, 0x51, 0x54, 0x71, 0x6E, 0x4D, 0x64, 0x7A, 0x47, 0x78, 0x52, 0x42, 0x46, 0x36, 0x58, 0x4C, 0x45, 0x2B, 0x30, 0x78, 0x52, 0x46, 0x46, 0x52, 0x68, 0x69, 0x4A, 0x42, 0x50, 0x53, ++ 0x79, 0x30, 0x33, 0x4F, 0x58, 0x49, 0x50, 0x42, 0x4E, 0x76, 0x49, 0x51, 0x74, 0x51, 0x36, 0x49, 0x62, 0x62, 0x6A, 0x68, 0x56, 0x70, 0x2B, 0x4A, 0x33, 0x70, 0x5A, 0x6D, 0x0A, 0x4F, 0x55, 0x64, 0x6B, 0x4C, 0x47, 0x35, 0x4E, 0x72, 0x6D, 0x4A, ++ 0x37, 0x76, 0x32, 0x42, 0x30, 0x47, 0x62, 0x68, 0x57, 0x72, 0x4A, 0x4B, 0x73, 0x46, 0x6A, 0x4C, 0x74, 0x72, 0x57, 0x68, 0x56, 0x2F, 0x70, 0x69, 0x36, 0x30, 0x7A, 0x54, 0x65, 0x39, 0x4D, 0x6C, 0x68, 0x77, 0x77, 0x36, 0x47, 0x39, 0x6B, 0x75, ++ 0x45, 0x59, 0x4F, 0x34, 0x4E, 0x65, 0x37, 0x55, 0x79, 0x57, 0x48, 0x6D, 0x52, 0x56, 0x53, 0x79, 0x42, 0x51, 0x37, 0x4E, 0x30, 0x48, 0x33, 0x71, 0x71, 0x0A, 0x4A, 0x5A, 0x34, 0x64, 0x31, 0x36, 0x47, 0x4C, 0x75, 0x63, 0x31, 0x43, 0x4C, 0x67, ++ 0x53, 0x6B, 0x5A, 0x6F, 0x4E, 0x4E, 0x69, 0x54, 0x57, 0x32, 0x62, 0x4B, 0x67, 0x32, 0x53, 0x6E, 0x6B, 0x68, 0x65, 0x43, 0x4C, 0x51, 0x51, 0x72, 0x7A, 0x52, 0x51, 0x44, 0x47, 0x51, 0x6F, 0x62, 0x34, 0x45, 0x7A, 0x38, 0x70, 0x6E, 0x37, 0x66, ++ 0x58, 0x77, 0x67, 0x4E, 0x4E, 0x67, 0x79, 0x59, 0x4D, 0x71, 0x49, 0x67, 0x58, 0x51, 0x42, 0x7A, 0x74, 0x53, 0x76, 0x77, 0x79, 0x65, 0x0A, 0x71, 0x69, 0x76, 0x35, 0x75, 0x2B, 0x59, 0x66, 0x6A, 0x79, 0x57, 0x36, 0x68, 0x59, 0x30, 0x58, 0x48, ++ 0x67, 0x4C, 0x2B, 0x58, 0x56, 0x41, 0x45, 0x56, 0x38, 0x2F, 0x2B, 0x4C, 0x62, 0x7A, 0x76, 0x58, 0x4D, 0x41, 0x61, 0x71, 0x37, 0x61, 0x66, 0x4A, 0x4D, 0x62, 0x66, 0x63, 0x32, 0x68, 0x49, 0x6B, 0x43, 0x77, 0x55, 0x39, 0x44, 0x39, 0x53, 0x47, ++ 0x75, 0x54, 0x53, 0x79, 0x78, 0x54, 0x44, 0x59, 0x57, 0x6E, 0x50, 0x34, 0x76, 0x6B, 0x59, 0x78, 0x62, 0x6F, 0x7A, 0x0A, 0x6E, 0x78, 0x53, 0x6A, 0x42, 0x46, 0x32, 0x35, 0x63, 0x66, 0x65, 0x31, 0x6C, 0x4E, 0x6A, 0x32, 0x4D, 0x38, 0x46, 0x61, ++ 0x77, 0x54, 0x53, 0x4C, 0x66, 0x4A, 0x76, 0x64, 0x6B, 0x7A, 0x72, 0x6E, 0x45, 0x36, 0x4A, 0x77, 0x59, 0x5A, 0x2B, 0x76, 0x6A, 0x2B, 0x76, 0x59, 0x78, 0x58, 0x58, 0x34, 0x4D, 0x32, 0x62, 0x55, 0x64, 0x47, 0x63, 0x36, 0x4E, 0x33, 0x65, 0x63, ++ 0x35, 0x39, 0x32, 0x6B, 0x44, 0x33, 0x5A, 0x44, 0x5A, 0x6F, 0x70, 0x44, 0x38, 0x70, 0x2F, 0x37, 0x0A, 0x44, 0x45, 0x4A, 0x34, 0x59, 0x39, 0x48, 0x69, 0x44, 0x32, 0x39, 0x37, 0x31, 0x4B, 0x45, 0x39, 0x64, 0x4A, 0x65, 0x46, 0x74, 0x30, 0x67, ++ 0x35, 0x51, 0x64, 0x59, 0x67, 0x2F, 0x4E, 0x41, 0x36, 0x73, 0x2F, 0x72, 0x6F, 0x62, 0x38, 0x53, 0x4B, 0x75, 0x6E, 0x45, 0x33, 0x76, 0x6F, 0x75, 0x58, 0x73, 0x58, 0x67, 0x78, 0x54, 0x37, 0x50, 0x6E, 0x74, 0x67, 0x4D, 0x54, 0x7A, 0x6C, 0x53, ++ 0x64, 0x72, 0x69, 0x56, 0x5A, 0x7A, 0x48, 0x38, 0x31, 0x58, 0x77, 0x6A, 0x33, 0x0A, 0x51, 0x45, 0x55, 0x78, 0x65, 0x43, 0x70, 0x36, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, ++ 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x45, 0x34, 0x36, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, ++ 0x49, 0x43, 0x43, 0x7A, 0x43, 0x43, 0x41, 0x5A, 0x47, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x53, 0x45, 0x64, 0x4B, 0x37, 0x75, 0x6A, 0x4E, 0x75, 0x31, 0x4C, 0x7A, 0x6D, 0x4A, 0x47, 0x6A, 0x46, 0x44, 0x59, 0x51, 0x64, 0x6D, 0x4F, ++ 0x68, 0x44, 0x4D, 0x41, 0x6F, 0x47, 0x43, 0x43, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x42, 0x41, 0x4D, 0x44, 0x4D, 0x45, 0x59, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x0A, 0x41, 0x6B, 0x4A, 0x46, 0x4D, ++ 0x52, 0x6B, 0x77, 0x46, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x78, 0x42, 0x48, 0x62, 0x47, 0x39, 0x69, 0x59, 0x57, 0x78, 0x54, 0x61, 0x57, 0x64, 0x75, 0x49, 0x47, 0x35, 0x32, 0x4C, 0x58, 0x4E, 0x68, 0x4D, 0x52, 0x77, 0x77, 0x47, ++ 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x4E, 0x48, 0x62, 0x47, 0x39, 0x69, 0x59, 0x57, 0x78, 0x54, 0x61, 0x57, 0x64, 0x75, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x0A, 0x52, 0x54, 0x51, 0x32, 0x4D, 0x42, 0x34, 0x58, ++ 0x44, 0x54, 0x45, 0x35, 0x4D, 0x44, 0x4D, 0x79, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x46, 0x6F, 0x58, 0x44, 0x54, 0x51, 0x32, 0x4D, 0x44, 0x4D, 0x79, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x46, 0x6F, 0x77, ++ 0x52, 0x6A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x51, 0x6B, 0x55, 0x78, 0x47, 0x54, 0x41, 0x58, 0x42, 0x67, 0x4E, 0x56, 0x0A, 0x42, 0x41, 0x6F, 0x54, 0x45, 0x45, 0x64, 0x73, 0x62, 0x32, 0x4A, ++ 0x68, 0x62, 0x46, 0x4E, 0x70, 0x5A, 0x32, 0x34, 0x67, 0x62, 0x6E, 0x59, 0x74, 0x63, 0x32, 0x45, 0x78, 0x48, 0x44, 0x41, 0x61, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x45, 0x30, 0x64, 0x73, 0x62, 0x32, 0x4A, 0x68, 0x62, 0x46, 0x4E, ++ 0x70, 0x5A, 0x32, 0x34, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x46, 0x4E, 0x44, 0x59, 0x77, 0x64, 0x6A, 0x41, 0x51, 0x42, 0x67, 0x63, 0x71, 0x0A, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x49, 0x42, 0x42, 0x67, 0x55, 0x72, 0x67, 0x51, ++ 0x51, 0x41, 0x49, 0x67, 0x4E, 0x69, 0x41, 0x41, 0x53, 0x63, 0x44, 0x72, 0x48, 0x50, 0x74, 0x2B, 0x69, 0x65, 0x55, 0x6E, 0x64, 0x31, 0x4E, 0x50, 0x71, 0x6C, 0x52, 0x71, 0x65, 0x74, 0x4D, 0x68, 0x6B, 0x79, 0x74, 0x41, 0x65, 0x70, 0x4A, 0x38, ++ 0x71, 0x55, 0x75, 0x77, 0x7A, 0x53, 0x43, 0x68, 0x44, 0x48, 0x32, 0x6F, 0x6D, 0x77, 0x6C, 0x77, 0x78, 0x77, 0x45, 0x77, 0x6B, 0x42, 0x0A, 0x6A, 0x74, 0x6A, 0x71, 0x52, 0x2B, 0x71, 0x2B, 0x73, 0x6F, 0x41, 0x72, 0x7A, 0x66, 0x77, 0x6F, 0x44, ++ 0x64, 0x75, 0x73, 0x76, 0x4B, 0x53, 0x47, 0x4E, 0x2B, 0x31, 0x77, 0x43, 0x41, 0x42, 0x31, 0x36, 0x70, 0x4D, 0x4C, 0x65, 0x79, 0x35, 0x53, 0x6E, 0x43, 0x4E, 0x6F, 0x49, 0x77, 0x5A, 0x44, 0x37, 0x4A, 0x49, 0x76, 0x55, 0x34, 0x54, 0x62, 0x2B, ++ 0x30, 0x63, 0x55, 0x42, 0x2B, 0x68, 0x66, 0x6C, 0x47, 0x64, 0x64, 0x79, 0x58, 0x71, 0x42, 0x50, 0x43, 0x43, 0x6A, 0x0A, 0x51, 0x6A, 0x42, 0x41, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, ++ 0x41, 0x77, 0x49, 0x42, 0x68, 0x6A, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, ++ 0x42, 0x42, 0x51, 0x78, 0x43, 0x70, 0x43, 0x50, 0x74, 0x73, 0x61, 0x64, 0x30, 0x6B, 0x52, 0x4C, 0x0A, 0x67, 0x4C, 0x57, 0x69, 0x35, 0x68, 0x2B, 0x78, 0x45, 0x6B, 0x38, 0x62, 0x6C, 0x54, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, ++ 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x77, 0x4E, 0x6F, 0x41, 0x44, 0x42, 0x6C, 0x41, 0x6A, 0x45, 0x41, 0x33, 0x31, 0x53, 0x51, 0x37, 0x5A, 0x76, 0x76, 0x69, 0x35, 0x51, 0x43, 0x6B, 0x78, 0x65, 0x43, 0x6D, 0x62, 0x36, 0x7A, 0x6E, 0x69, 0x7A, ++ 0x32, 0x43, 0x35, 0x47, 0x4D, 0x6E, 0x30, 0x6F, 0x55, 0x73, 0x66, 0x5A, 0x6B, 0x0A, 0x76, 0x4C, 0x74, 0x6F, 0x55, 0x52, 0x4D, 0x4D, 0x41, 0x2F, 0x63, 0x56, 0x69, 0x34, 0x52, 0x67, 0x75, 0x59, 0x76, 0x2F, 0x55, 0x6F, 0x37, 0x6E, 0x6A, 0x4C, ++ 0x77, 0x63, 0x41, 0x6A, 0x41, 0x38, 0x2B, 0x52, 0x48, 0x55, 0x6A, 0x45, 0x37, 0x41, 0x77, 0x57, 0x48, 0x43, 0x46, 0x55, 0x79, 0x71, 0x71, 0x78, 0x30, 0x4C, 0x4D, 0x56, 0x38, 0x37, 0x48, 0x4F, 0x49, 0x41, 0x6C, 0x30, 0x51, 0x78, 0x35, 0x76, ++ 0x35, 0x7A, 0x6C, 0x69, 0x2F, 0x61, 0x6C, 0x74, 0x50, 0x2B, 0x0A, 0x43, 0x41, 0x65, 0x7A, 0x4E, 0x49, 0x6D, 0x38, 0x42, 0x5A, 0x2F, 0x33, 0x48, 0x6F, 0x62, 0x75, 0x69, 0x33, 0x41, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, ++ 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x47, 0x4C, 0x4F, 0x42, 0x41, 0x4C, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x32, 0x30, 0x32, 0x30, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x67, 0x6A, 0x43, 0x43, 0x41, 0x32, 0x71, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x4C, 0x57, 0x6B, 0x75, 0x39, 0x57, 0x76, 0x74, 0x50, 0x69, 0x6C, 0x76, 0x36, 0x5A, 0x65, 0x55, 0x77, 0x44, 0x51, 0x59, ++ 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x77, 0x54, 0x54, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x51, 0x56, 0x51, 0x78, 0x0A, 0x49, 0x7A, ++ 0x41, 0x68, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x47, 0x6D, 0x55, 0x74, 0x59, 0x32, 0x39, 0x74, 0x62, 0x57, 0x56, 0x79, 0x59, 0x32, 0x55, 0x67, 0x62, 0x57, 0x39, 0x75, 0x61, 0x58, 0x52, 0x76, 0x63, 0x6D, 0x6C, 0x75, 0x5A, 0x79, ++ 0x42, 0x48, 0x62, 0x57, 0x4A, 0x49, 0x4D, 0x52, 0x6B, 0x77, 0x46, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x42, 0x48, 0x54, 0x45, 0x39, 0x43, 0x51, 0x55, 0x78, 0x55, 0x55, 0x6C, 0x56, 0x54, 0x0A, 0x56, 0x43, 0x41, 0x79, 0x4D, ++ 0x44, 0x49, 0x77, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x49, 0x77, 0x4D, 0x44, 0x49, 0x78, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x46, 0x6F, 0x58, 0x44, 0x54, 0x51, 0x77, 0x4D, 0x44, 0x59, 0x78, 0x4D, 0x44, 0x41, 0x77, 0x4D, ++ 0x44, 0x41, 0x77, 0x4D, 0x46, 0x6F, 0x77, 0x54, 0x54, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x51, 0x56, 0x51, 0x78, 0x49, 0x7A, 0x41, 0x68, 0x0A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, ++ 0x47, 0x6D, 0x55, 0x74, 0x59, 0x32, 0x39, 0x74, 0x62, 0x57, 0x56, 0x79, 0x59, 0x32, 0x55, 0x67, 0x62, 0x57, 0x39, 0x75, 0x61, 0x58, 0x52, 0x76, 0x63, 0x6D, 0x6C, 0x75, 0x5A, 0x79, 0x42, 0x48, 0x62, 0x57, 0x4A, 0x49, 0x4D, 0x52, 0x6B, 0x77, ++ 0x46, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x42, 0x48, 0x54, 0x45, 0x39, 0x43, 0x51, 0x55, 0x78, 0x55, 0x55, 0x6C, 0x56, 0x54, 0x56, 0x43, 0x41, 0x79, 0x0A, 0x4D, 0x44, 0x49, 0x77, 0x4D, 0x49, 0x49, 0x43, 0x49, 0x6A, 0x41, ++ 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x67, 0x38, 0x41, 0x4D, 0x49, 0x49, 0x43, 0x43, 0x67, 0x4B, 0x43, 0x41, 0x67, 0x45, 0x41, 0x72, 0x69, 0x35, ++ 0x57, 0x72, 0x52, 0x73, 0x63, 0x37, 0x2F, 0x61, 0x56, 0x6A, 0x36, 0x42, 0x33, 0x47, 0x79, 0x76, 0x54, 0x59, 0x34, 0x2B, 0x45, 0x54, 0x55, 0x57, 0x69, 0x0A, 0x44, 0x35, 0x39, 0x62, 0x52, 0x61, 0x74, 0x5A, 0x65, 0x31, 0x45, 0x30, 0x2B, 0x65, ++ 0x79, 0x4C, 0x69, 0x6E, 0x6A, 0x46, 0x33, 0x57, 0x75, 0x76, 0x76, 0x63, 0x54, 0x66, 0x6B, 0x30, 0x55, 0x65, 0x76, 0x35, 0x45, 0x34, 0x43, 0x36, 0x34, 0x4F, 0x46, 0x75, 0x64, 0x42, 0x63, 0x2F, 0x6A, 0x62, 0x75, 0x39, 0x47, 0x34, 0x55, 0x65, ++ 0x44, 0x4C, 0x67, 0x7A, 0x74, 0x7A, 0x4F, 0x47, 0x35, 0x33, 0x69, 0x67, 0x39, 0x5A, 0x59, 0x79, 0x62, 0x4E, 0x70, 0x79, 0x72, 0x4F, 0x0A, 0x56, 0x50, 0x75, 0x34, 0x34, 0x73, 0x42, 0x38, 0x52, 0x38, 0x35, 0x67, 0x66, 0x44, 0x2B, 0x79, 0x63, ++ 0x2F, 0x4C, 0x41, 0x47, 0x62, 0x61, 0x4B, 0x6B, 0x6F, 0x63, 0x31, 0x44, 0x5A, 0x41, 0x6F, 0x6F, 0x75, 0x51, 0x56, 0x42, 0x47, 0x4D, 0x2B, 0x75, 0x71, 0x2F, 0x75, 0x66, 0x46, 0x37, 0x4D, 0x70, 0x6F, 0x74, 0x51, 0x73, 0x6A, 0x6A, 0x33, 0x51, ++ 0x57, 0x50, 0x4B, 0x7A, 0x76, 0x39, 0x70, 0x6A, 0x32, 0x67, 0x4F, 0x6C, 0x54, 0x62, 0x6C, 0x7A, 0x4C, 0x6D, 0x4D, 0x0A, 0x43, 0x63, 0x70, 0x4C, 0x33, 0x54, 0x47, 0x51, 0x6C, 0x73, 0x6A, 0x4D, 0x48, 0x2F, 0x31, 0x57, 0x6C, 0x6A, 0x54, 0x62, ++ 0x6A, 0x68, 0x7A, 0x71, 0x4C, 0x4C, 0x36, 0x46, 0x4C, 0x6D, 0x50, 0x64, 0x71, 0x71, 0x6D, 0x56, 0x30, 0x2F, 0x30, 0x70, 0x6C, 0x52, 0x50, 0x77, 0x79, 0x4A, 0x69, 0x54, 0x32, 0x53, 0x30, 0x57, 0x52, 0x35, 0x41, 0x52, 0x67, 0x36, 0x49, 0x36, ++ 0x49, 0x71, 0x49, 0x6F, 0x56, 0x36, 0x4C, 0x72, 0x2F, 0x73, 0x43, 0x4D, 0x4B, 0x4B, 0x43, 0x6D, 0x0A, 0x66, 0x65, 0x63, 0x71, 0x51, 0x6A, 0x75, 0x43, 0x67, 0x47, 0x4F, 0x6C, 0x59, 0x78, 0x38, 0x5A, 0x7A, 0x48, 0x79, 0x79, 0x5A, 0x71, 0x6A, ++ 0x43, 0x30, 0x32, 0x30, 0x33, 0x62, 0x2B, 0x4A, 0x2B, 0x42, 0x6C, 0x48, 0x5A, 0x52, 0x59, 0x51, 0x66, 0x45, 0x73, 0x34, 0x6B, 0x55, 0x6D, 0x53, 0x46, 0x43, 0x30, 0x69, 0x41, 0x54, 0x6F, 0x65, 0x78, 0x49, 0x69, 0x49, 0x77, 0x71, 0x75, 0x75, ++ 0x75, 0x76, 0x75, 0x41, 0x43, 0x34, 0x45, 0x44, 0x6F, 0x73, 0x45, 0x4B, 0x41, 0x0A, 0x41, 0x31, 0x47, 0x71, 0x74, 0x48, 0x36, 0x71, 0x52, 0x4E, 0x64, 0x44, 0x59, 0x66, 0x4F, 0x69, 0x61, 0x78, 0x61, 0x4A, 0x53, 0x61, 0x53, 0x6A, 0x70, 0x43, ++ 0x75, 0x4B, 0x41, 0x73, 0x52, 0x34, 0x39, 0x47, 0x69, 0x4B, 0x77, 0x65, 0x52, 0x36, 0x4E, 0x72, 0x46, 0x76, 0x47, 0x35, 0x59, 0x62, 0x64, 0x30, 0x6D, 0x4E, 0x31, 0x4D, 0x6B, 0x47, 0x63, 0x6F, 0x2F, 0x50, 0x55, 0x2B, 0x50, 0x63, 0x46, 0x34, ++ 0x55, 0x67, 0x53, 0x74, 0x79, 0x59, 0x4A, 0x39, 0x4F, 0x52, 0x0A, 0x4A, 0x69, 0x74, 0x48, 0x48, 0x6D, 0x6B, 0x48, 0x72, 0x39, 0x36, 0x69, 0x35, 0x4F, 0x54, 0x55, 0x61, 0x77, 0x75, 0x7A, 0x58, 0x6E, 0x7A, 0x55, 0x4A, 0x49, 0x42, 0x48, 0x4B, ++ 0x57, 0x6B, 0x37, 0x62, 0x75, 0x69, 0x73, 0x2F, 0x55, 0x44, 0x72, 0x32, 0x4F, 0x31, 0x78, 0x63, 0x53, 0x76, 0x79, 0x36, 0x46, 0x67, 0x64, 0x36, 0x30, 0x47, 0x58, 0x49, 0x73, 0x55, 0x66, 0x31, 0x44, 0x6E, 0x51, 0x4A, 0x34, 0x2B, 0x48, 0x34, ++ 0x78, 0x6A, 0x30, 0x34, 0x4B, 0x6C, 0x47, 0x0A, 0x44, 0x66, 0x56, 0x30, 0x4F, 0x6F, 0x49, 0x75, 0x30, 0x47, 0x34, 0x73, 0x6B, 0x61, 0x4D, 0x78, 0x58, 0x44, 0x74, 0x47, 0x36, 0x6E, 0x73, 0x45, 0x45, 0x46, 0x5A, 0x65, 0x67, 0x42, 0x33, 0x31, ++ 0x70, 0x57, 0x58, 0x6F, 0x67, 0x76, 0x7A, 0x69, 0x42, 0x34, 0x78, 0x69, 0x52, 0x66, 0x55, 0x67, 0x33, 0x6B, 0x5A, 0x77, 0x68, 0x71, 0x47, 0x38, 0x6B, 0x39, 0x4D, 0x65, 0x64, 0x4B, 0x5A, 0x73, 0x73, 0x43, 0x7A, 0x33, 0x41, 0x77, 0x79, 0x49, ++ 0x44, 0x4D, 0x76, 0x55, 0x0A, 0x63, 0x6C, 0x4F, 0x47, 0x76, 0x47, 0x42, 0x47, 0x38, 0x35, 0x68, 0x71, 0x77, 0x76, 0x47, 0x2F, 0x51, 0x2F, 0x6C, 0x77, 0x49, 0x48, 0x66, 0x4B, 0x4E, 0x30, 0x46, 0x35, 0x56, 0x56, 0x4A, 0x6A, 0x6A, 0x56, 0x73, ++ 0x53, 0x6E, 0x38, 0x56, 0x6F, 0x78, 0x49, 0x69, 0x64, 0x72, 0x50, 0x49, 0x77, 0x71, 0x37, 0x65, 0x6A, 0x4D, 0x5A, 0x64, 0x6E, 0x72, 0x59, 0x38, 0x58, 0x44, 0x32, 0x7A, 0x48, 0x63, 0x2B, 0x30, 0x6B, 0x6C, 0x47, 0x76, 0x49, 0x67, 0x35, 0x72, ++ 0x51, 0x0A, 0x6D, 0x6A, 0x64, 0x4A, 0x42, 0x4B, 0x75, 0x78, 0x46, 0x73, 0x68, 0x73, 0x53, 0x55, 0x6B, 0x74, 0x71, 0x36, 0x48, 0x51, 0x6A, 0x4A, 0x4C, 0x79, 0x51, 0x55, 0x70, 0x35, 0x49, 0x53, 0x58, 0x62, 0x59, 0x39, 0x65, 0x32, 0x6E, 0x4B, ++ 0x64, 0x2B, 0x51, 0x6D, 0x6E, 0x37, 0x4F, 0x6D, 0x4D, 0x43, 0x41, 0x77, 0x45, 0x41, 0x41, 0x61, 0x4E, 0x6A, 0x4D, 0x47, 0x45, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x0A, 0x41, ++ 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x51, 0x59, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x46, ++ 0x4E, 0x77, 0x75, 0x48, 0x39, 0x46, 0x68, 0x4E, 0x33, 0x6E, 0x6B, 0x71, 0x39, 0x58, 0x56, 0x73, 0x78, 0x4A, 0x78, 0x61, 0x44, 0x31, 0x71, 0x61, 0x4A, 0x77, 0x69, 0x4D, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x0A, 0x49, 0x77, 0x51, 0x59, ++ 0x4D, 0x42, 0x61, 0x41, 0x46, 0x4E, 0x77, 0x75, 0x48, 0x39, 0x46, 0x68, 0x4E, 0x33, 0x6E, 0x6B, 0x71, 0x39, 0x58, 0x56, 0x73, 0x78, 0x4A, 0x78, 0x61, 0x44, 0x31, 0x71, 0x61, 0x4A, 0x77, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, ++ 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43, 0x77, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x41, 0x51, 0x43, 0x52, 0x38, 0x45, 0x49, 0x43, 0x61, 0x45, 0x44, 0x75, 0x77, 0x32, 0x6A, 0x41, 0x0A, 0x56, 0x43, 0x2F, 0x66, 0x37, 0x47, 0x4C, ++ 0x44, 0x77, 0x35, 0x36, 0x4B, 0x6F, 0x44, 0x45, 0x6F, 0x71, 0x6F, 0x4F, 0x4F, 0x70, 0x46, 0x61, 0x57, 0x45, 0x68, 0x43, 0x47, 0x56, 0x72, 0x71, 0x58, 0x63, 0x74, 0x4A, 0x55, 0x4D, 0x48, 0x79, 0x74, 0x47, 0x64, 0x55, 0x64, 0x61, 0x47, 0x2F, ++ 0x37, 0x46, 0x45, 0x4C, 0x59, 0x6A, 0x51, 0x37, 0x7A, 0x74, 0x64, 0x47, 0x6C, 0x34, 0x77, 0x4A, 0x43, 0x58, 0x74, 0x7A, 0x6F, 0x52, 0x6C, 0x67, 0x48, 0x4E, 0x51, 0x49, 0x77, 0x0A, 0x34, 0x4C, 0x78, 0x30, 0x53, 0x73, 0x46, 0x44, 0x4B, 0x76, ++ 0x2F, 0x62, 0x47, 0x74, 0x43, 0x77, 0x72, 0x32, 0x7A, 0x44, 0x2F, 0x63, 0x75, 0x7A, 0x39, 0x58, 0x39, 0x74, 0x41, 0x79, 0x35, 0x5A, 0x56, 0x70, 0x30, 0x74, 0x4C, 0x54, 0x57, 0x4D, 0x73, 0x74, 0x5A, 0x44, 0x46, 0x79, 0x79, 0x53, 0x43, 0x73, ++ 0x74, 0x64, 0x36, 0x49, 0x77, 0x50, 0x53, 0x33, 0x42, 0x44, 0x30, 0x49, 0x4C, 0x2F, 0x71, 0x4D, 0x79, 0x2F, 0x70, 0x4A, 0x54, 0x41, 0x76, 0x6F, 0x65, 0x39, 0x0A, 0x69, 0x75, 0x4F, 0x54, 0x65, 0x38, 0x61, 0x50, 0x6D, 0x78, 0x61, 0x64, 0x4A, ++ 0x32, 0x57, 0x38, 0x65, 0x73, 0x56, 0x43, 0x67, 0x6D, 0x78, 0x63, 0x42, 0x39, 0x43, 0x70, 0x77, 0x59, 0x68, 0x67, 0x52, 0x4F, 0x6D, 0x59, 0x68, 0x52, 0x5A, 0x66, 0x2B, 0x49, 0x2F, 0x4B, 0x41, 0x52, 0x44, 0x4F, 0x4A, 0x63, 0x50, 0x35, 0x59, ++ 0x42, 0x75, 0x67, 0x78, 0x5A, 0x66, 0x44, 0x30, 0x79, 0x79, 0x49, 0x4D, 0x61, 0x4B, 0x39, 0x4D, 0x4F, 0x7A, 0x51, 0x30, 0x4D, 0x41, 0x53, 0x0A, 0x38, 0x63, 0x45, 0x35, 0x34, 0x2B, 0x58, 0x31, 0x2B, 0x4E, 0x5A, 0x4B, 0x33, 0x54, 0x54, 0x4E, ++ 0x2B, 0x32, 0x2F, 0x42, 0x54, 0x2B, 0x4D, 0x41, 0x69, 0x31, 0x62, 0x69, 0x6B, 0x76, 0x63, 0x6F, 0x73, 0x6B, 0x4A, 0x33, 0x63, 0x69, 0x4E, 0x6E, 0x78, 0x7A, 0x38, 0x52, 0x46, 0x62, 0x4C, 0x45, 0x41, 0x77, 0x57, 0x2B, 0x75, 0x78, 0x46, 0x37, ++ 0x43, 0x72, 0x2B, 0x6F, 0x62, 0x75, 0x66, 0x2F, 0x57, 0x45, 0x50, 0x50, 0x6D, 0x32, 0x65, 0x67, 0x67, 0x41, 0x65, 0x32, 0x0A, 0x48, 0x63, 0x71, 0x74, 0x62, 0x65, 0x70, 0x42, 0x45, 0x58, 0x34, 0x74, 0x64, 0x4A, 0x50, 0x37, 0x77, 0x72, 0x79, ++ 0x2B, 0x55, 0x55, 0x54, 0x46, 0x37, 0x32, 0x67, 0x6C, 0x4A, 0x34, 0x44, 0x6A, 0x79, 0x4B, 0x44, 0x55, 0x45, 0x75, 0x7A, 0x5A, 0x70, 0x54, 0x63, 0x64, 0x4E, 0x33, 0x79, 0x30, 0x6B, 0x63, 0x72, 0x61, 0x31, 0x4C, 0x47, 0x57, 0x67, 0x65, 0x39, ++ 0x6F, 0x58, 0x48, 0x59, 0x51, 0x53, 0x61, 0x39, 0x2B, 0x70, 0x54, 0x65, 0x41, 0x73, 0x52, 0x78, 0x53, 0x0A, 0x76, 0x54, 0x4F, 0x42, 0x54, 0x49, 0x2F, 0x35, 0x33, 0x57, 0x58, 0x5A, 0x46, 0x4D, 0x32, 0x4B, 0x4A, 0x56, 0x6A, 0x30, 0x34, 0x73, ++ 0x57, 0x44, 0x70, 0x51, 0x6D, 0x51, 0x31, 0x47, 0x77, 0x55, 0x59, 0x37, 0x56, 0x41, 0x33, 0x2B, 0x76, 0x41, 0x2F, 0x4D, 0x52, 0x59, 0x66, 0x67, 0x30, 0x55, 0x46, 0x6F, 0x64, 0x55, 0x4A, 0x32, 0x35, 0x57, 0x35, 0x48, 0x43, 0x45, 0x75, 0x47, ++ 0x77, 0x79, 0x45, 0x6E, 0x36, 0x43, 0x4D, 0x55, 0x4F, 0x2B, 0x31, 0x39, 0x31, 0x38, 0x0A, 0x6F, 0x61, 0x32, 0x75, 0x31, 0x71, 0x73, 0x67, 0x45, 0x75, 0x38, 0x4B, 0x77, 0x78, 0x43, 0x4D, 0x53, 0x5A, 0x59, 0x31, 0x33, 0x41, 0x74, 0x31, 0x58, ++ 0x72, 0x46, 0x50, 0x31, 0x55, 0x38, 0x30, 0x44, 0x68, 0x45, 0x67, 0x42, 0x33, 0x56, 0x44, 0x52, 0x65, 0x6D, 0x6A, 0x45, 0x64, 0x71, 0x73, 0x6F, 0x35, 0x6E, 0x43, 0x74, 0x6E, 0x6B, 0x6E, 0x34, 0x72, 0x6E, 0x76, 0x79, 0x4F, 0x4C, 0x32, 0x4E, ++ 0x53, 0x6C, 0x36, 0x64, 0x50, 0x72, 0x46, 0x66, 0x34, 0x49, 0x46, 0x0A, 0x59, 0x71, 0x59, 0x4B, 0x36, 0x6D, 0x69, 0x79, 0x65, 0x55, 0x63, 0x47, 0x62, 0x76, 0x4A, 0x58, 0x71, 0x42, 0x55, 0x7A, 0x78, 0x76, 0x64, 0x34, 0x53, 0x6A, 0x31, 0x43, ++ 0x65, 0x32, 0x74, 0x2B, 0x2F, 0x76, 0x64, 0x47, 0x36, 0x74, 0x48, 0x72, 0x6A, 0x75, 0x2B, 0x49, 0x61, 0x46, 0x76, 0x6F, 0x77, 0x64, 0x6C, 0x78, 0x66, 0x76, 0x31, 0x6B, 0x37, 0x2F, 0x39, 0x6E, 0x52, 0x34, 0x68, 0x59, 0x4A, 0x53, 0x38, 0x2B, ++ 0x68, 0x67, 0x65, 0x39, 0x2B, 0x36, 0x6A, 0x6C, 0x0A, 0x67, 0x71, 0x69, 0x73, 0x70, 0x64, 0x4E, 0x70, 0x51, 0x38, 0x30, 0x78, 0x69, 0x45, 0x6D, 0x45, 0x55, 0x35, 0x4C, 0x41, 0x73, 0x54, 0x6B, 0x62, 0x4F, 0x59, 0x4D, 0x42, 0x4D, 0x4D, 0x54, ++ 0x79, 0x71, 0x66, 0x72, 0x51, 0x41, 0x37, 0x31, 0x79, 0x4E, 0x32, 0x42, 0x57, 0x48, 0x7A, 0x5A, 0x38, 0x76, 0x54, 0x6D, 0x52, 0x39, 0x57, 0x30, 0x4E, 0x76, 0x33, 0x76, 0x58, 0x6B, 0x67, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, ++ 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x41, 0x4E, 0x46, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x52, ++ 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, ++ 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x37, 0x7A, 0x43, 0x43, 0x41, 0x39, 0x65, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, ++ 0x49, 0x44, 0x64, 0x50, 0x6A, 0x76, 0x47, 0x7A, 0x35, 0x61, 0x37, 0x45, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x77, 0x67, 0x59, 0x51, 0x78, 0x45, 0x6A, 0x41, ++ 0x51, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x55, 0x54, 0x43, 0x55, 0x63, 0x32, 0x4D, 0x7A, 0x49, 0x34, 0x0A, 0x4E, 0x7A, 0x55, 0x78, 0x4D, 0x44, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x52, 0x56, ++ 0x4D, 0x78, 0x4A, 0x7A, 0x41, 0x6C, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x48, 0x6B, 0x46, 0x4F, 0x52, 0x69, 0x42, 0x42, 0x64, 0x58, 0x52, 0x76, 0x63, 0x6D, 0x6C, 0x6B, 0x59, 0x57, 0x51, 0x67, 0x5A, 0x47, 0x55, 0x67, 0x51, 0x32, ++ 0x56, 0x79, 0x64, 0x47, 0x6C, 0x6D, 0x61, 0x57, 0x4E, 0x68, 0x59, 0x32, 0x6C, 0x76, 0x0A, 0x62, 0x6A, 0x45, 0x55, 0x4D, 0x42, 0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4D, 0x4C, 0x51, 0x55, 0x35, 0x47, 0x49, 0x45, 0x4E, 0x42, 0x49, ++ 0x46, 0x4A, 0x68, 0x61, 0x58, 0x6F, 0x78, 0x49, 0x6A, 0x41, 0x67, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x47, 0x55, 0x46, 0x4F, 0x52, 0x69, 0x42, 0x54, 0x5A, 0x57, 0x4E, 0x31, 0x63, 0x6D, 0x55, 0x67, 0x55, 0x32, 0x56, 0x79, 0x64, ++ 0x6D, 0x56, 0x79, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x0A, 0x51, 0x30, 0x45, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x54, 0x6B, 0x77, 0x4F, 0x54, 0x41, 0x30, 0x4D, 0x54, 0x41, 0x77, 0x4D, 0x44, 0x4D, 0x34, 0x57, 0x68, 0x63, 0x4E, ++ 0x4D, 0x7A, 0x6B, 0x77, 0x4F, 0x44, 0x4D, 0x77, 0x4D, 0x54, 0x41, 0x77, 0x4D, 0x44, 0x4D, 0x34, 0x57, 0x6A, 0x43, 0x42, 0x68, 0x44, 0x45, 0x53, 0x4D, 0x42, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x52, 0x4D, 0x4A, 0x52, 0x7A, 0x59, 0x7A, ++ 0x4D, 0x6A, 0x67, 0x33, 0x4E, 0x54, 0x45, 0x77, 0x0A, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x46, 0x55, 0x7A, 0x45, 0x6E, 0x4D, 0x43, 0x55, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, ++ 0x65, 0x51, 0x55, 0x35, 0x47, 0x49, 0x45, 0x46, 0x31, 0x64, 0x47, 0x39, 0x79, 0x61, 0x57, 0x52, 0x68, 0x5A, 0x43, 0x42, 0x6B, 0x5A, 0x53, 0x42, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x61, 0x57, 0x5A, 0x70, 0x59, 0x32, 0x46, 0x6A, 0x61, 0x57, 0x39, ++ 0x75, 0x4D, 0x52, 0x51, 0x77, 0x0A, 0x45, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, 0x45, 0x77, 0x74, 0x42, 0x54, 0x6B, 0x59, 0x67, 0x51, 0x30, 0x45, 0x67, 0x55, 0x6D, 0x46, 0x70, 0x65, 0x6A, 0x45, 0x69, 0x4D, 0x43, 0x41, 0x47, 0x41, 0x31, ++ 0x55, 0x45, 0x41, 0x78, 0x4D, 0x5A, 0x51, 0x55, 0x35, 0x47, 0x49, 0x46, 0x4E, 0x6C, 0x59, 0x33, 0x56, 0x79, 0x5A, 0x53, 0x42, 0x54, 0x5A, 0x58, 0x4A, 0x32, 0x5A, 0x58, 0x49, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x54, ++ 0x43, 0x43, 0x0A, 0x41, 0x69, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x67, 0x6F, 0x43, 0x67, ++ 0x67, 0x49, 0x42, 0x41, 0x4E, 0x76, 0x72, 0x61, 0x79, 0x76, 0x6D, 0x5A, 0x46, 0x53, 0x56, 0x67, 0x70, 0x43, 0x6A, 0x63, 0x71, 0x51, 0x5A, 0x41, 0x5A, 0x32, 0x63, 0x43, 0x34, 0x46, 0x66, 0x63, 0x30, 0x6D, 0x36, 0x70, 0x36, 0x7A, 0x7A, 0x0A, ++ 0x42, 0x45, 0x35, 0x37, 0x6C, 0x67, 0x76, 0x73, 0x45, 0x65, 0x42, 0x62, 0x70, 0x68, 0x7A, 0x4F, 0x47, 0x39, 0x49, 0x4E, 0x67, 0x78, 0x77, 0x72, 0x75, 0x4A, 0x34, 0x64, 0x66, 0x6B, 0x55, 0x79, 0x59, 0x41, 0x38, 0x48, 0x36, 0x58, 0x64, 0x59, ++ 0x66, 0x70, 0x39, 0x71, 0x79, 0x47, 0x46, 0x4F, 0x74, 0x69, 0x62, 0x42, 0x54, 0x49, 0x33, 0x2F, 0x54, 0x4F, 0x38, 0x30, 0x73, 0x68, 0x39, 0x6C, 0x32, 0x4C, 0x6C, 0x34, 0x39, 0x61, 0x32, 0x70, 0x63, 0x62, 0x6E, 0x76, 0x0A, 0x54, 0x31, 0x67, ++ 0x64, 0x70, 0x64, 0x35, 0x30, 0x49, 0x4A, 0x65, 0x68, 0x37, 0x57, 0x68, 0x4D, 0x33, 0x70, 0x49, 0x58, 0x53, 0x37, 0x79, 0x72, 0x2F, 0x32, 0x57, 0x61, 0x6E, 0x76, 0x74, 0x48, 0x32, 0x56, 0x64, 0x79, 0x38, 0x77, 0x6D, 0x68, 0x72, 0x6E, 0x5A, ++ 0x45, 0x45, 0x32, 0x36, 0x63, 0x4C, 0x55, 0x51, 0x35, 0x76, 0x50, 0x6E, 0x48, 0x4F, 0x36, 0x52, 0x59, 0x50, 0x55, 0x47, 0x39, 0x74, 0x4D, 0x4A, 0x4A, 0x6F, 0x38, 0x67, 0x4E, 0x30, 0x70, 0x63, 0x76, 0x0A, 0x42, 0x32, 0x56, 0x53, 0x41, 0x4B, ++ 0x64, 0x75, 0x79, 0x4B, 0x39, 0x6F, 0x37, 0x50, 0x51, 0x55, 0x6C, 0x72, 0x5A, 0x58, 0x48, 0x31, 0x62, 0x44, 0x4F, 0x5A, 0x38, 0x72, 0x62, 0x65, 0x54, 0x7A, 0x50, 0x76, 0x59, 0x31, 0x5A, 0x4E, 0x6F, 0x4D, 0x48, 0x4B, 0x47, 0x45, 0x53, 0x79, ++ 0x39, 0x4C, 0x53, 0x2B, 0x49, 0x73, 0x4A, 0x4A, 0x31, 0x74, 0x6B, 0x30, 0x44, 0x72, 0x74, 0x53, 0x4F, 0x4F, 0x4D, 0x73, 0x70, 0x76, 0x52, 0x64, 0x4F, 0x6F, 0x69, 0x58, 0x73, 0x65, 0x0A, 0x7A, 0x78, 0x37, 0x36, 0x57, 0x30, 0x4F, 0x4C, 0x7A, ++ 0x63, 0x32, 0x6F, 0x44, 0x32, 0x72, 0x4B, 0x44, 0x46, 0x36, 0x35, 0x6E, 0x6B, 0x65, 0x50, 0x38, 0x4E, 0x6D, 0x32, 0x43, 0x67, 0x74, 0x59, 0x5A, 0x52, 0x63, 0x7A, 0x75, 0x53, 0x50, 0x6B, 0x64, 0x78, 0x6C, 0x39, 0x79, 0x30, 0x6F, 0x75, 0x6B, ++ 0x6E, 0x74, 0x50, 0x4C, 0x78, 0x42, 0x33, 0x73, 0x59, 0x30, 0x76, 0x61, 0x4A, 0x78, 0x69, 0x7A, 0x4F, 0x42, 0x51, 0x2B, 0x4F, 0x79, 0x52, 0x70, 0x31, 0x52, 0x4D, 0x0A, 0x56, 0x77, 0x6E, 0x56, 0x64, 0x6D, 0x50, 0x46, 0x36, 0x47, 0x55, 0x65, ++ 0x37, 0x6D, 0x31, 0x71, 0x7A, 0x77, 0x6D, 0x64, 0x2B, 0x6E, 0x78, 0x50, 0x72, 0x57, 0x41, 0x49, 0x2F, 0x56, 0x61, 0x5A, 0x44, 0x78, 0x55, 0x73, 0x65, 0x36, 0x6D, 0x41, 0x71, 0x34, 0x78, 0x68, 0x6A, 0x30, 0x6F, 0x48, 0x64, 0x6B, 0x4C, 0x65, ++ 0x50, 0x66, 0x54, 0x64, 0x73, 0x69, 0x51, 0x7A, 0x57, 0x37, 0x69, 0x31, 0x6F, 0x30, 0x54, 0x4A, 0x72, 0x48, 0x39, 0x33, 0x50, 0x42, 0x30, 0x6A, 0x0A, 0x37, 0x49, 0x4B, 0x70, 0x70, 0x75, 0x4C, 0x49, 0x42, 0x6B, 0x77, 0x43, 0x2F, 0x71, 0x78, ++ 0x63, 0x6D, 0x5A, 0x6B, 0x4C, 0x4C, 0x78, 0x43, 0x4B, 0x70, 0x76, 0x52, 0x2F, 0x31, 0x59, 0x64, 0x30, 0x44, 0x56, 0x6C, 0x4A, 0x52, 0x66, 0x62, 0x77, 0x63, 0x56, 0x77, 0x35, 0x4B, 0x64, 0x61, 0x2F, 0x53, 0x69, 0x4F, 0x4C, 0x39, 0x56, 0x38, ++ 0x42, 0x59, 0x39, 0x4B, 0x48, 0x63, 0x79, 0x69, 0x31, 0x53, 0x77, 0x72, 0x31, 0x2B, 0x4B, 0x75, 0x43, 0x4C, 0x48, 0x35, 0x7A, 0x0A, 0x4A, 0x54, 0x49, 0x64, 0x43, 0x32, 0x4D, 0x4B, 0x46, 0x34, 0x45, 0x41, 0x2F, 0x37, 0x5A, 0x32, 0x58, 0x75, ++ 0x65, 0x30, 0x73, 0x55, 0x44, 0x4B, 0x49, 0x62, 0x76, 0x56, 0x67, 0x46, 0x48, 0x6C, 0x53, 0x46, 0x4A, 0x6E, 0x4C, 0x4E, 0x4A, 0x68, 0x69, 0x51, 0x63, 0x4E, 0x44, 0x38, 0x35, 0x43, 0x64, 0x38, 0x42, 0x45, 0x63, 0x35, 0x78, 0x45, 0x55, 0x4B, ++ 0x44, 0x62, 0x45, 0x41, 0x6F, 0x74, 0x6C, 0x52, 0x79, 0x42, 0x72, 0x2B, 0x51, 0x63, 0x35, 0x52, 0x51, 0x65, 0x0A, 0x38, 0x54, 0x5A, 0x42, 0x41, 0x51, 0x49, 0x76, 0x66, 0x58, 0x4F, 0x6E, 0x33, 0x6B, 0x4C, 0x4D, 0x54, 0x4F, 0x6D, 0x4A, 0x44, ++ 0x56, 0x62, 0x33, 0x6E, 0x35, 0x48, 0x55, 0x41, 0x38, 0x5A, 0x73, 0x79, 0x59, 0x2F, 0x62, 0x32, 0x42, 0x7A, 0x67, 0x51, 0x4A, 0x68, 0x64, 0x5A, 0x70, 0x6D, 0x59, 0x67, 0x47, 0x34, 0x74, 0x2F, 0x77, 0x48, 0x46, 0x7A, 0x73, 0x74, 0x47, 0x48, ++ 0x36, 0x77, 0x43, 0x78, 0x6B, 0x50, 0x6D, 0x72, 0x71, 0x4B, 0x45, 0x50, 0x4D, 0x56, 0x4F, 0x0A, 0x48, 0x6A, 0x31, 0x74, 0x79, 0x52, 0x52, 0x4D, 0x34, 0x79, 0x35, 0x42, 0x75, 0x38, 0x6F, 0x35, 0x76, 0x7A, 0x59, 0x38, 0x4B, 0x68, 0x6D, 0x71, ++ 0x51, 0x59, 0x64, 0x4F, 0x70, 0x63, 0x35, 0x4C, 0x4D, 0x6E, 0x6E, 0x64, 0x6B, 0x45, 0x6C, 0x2F, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, 0x59, 0x7A, 0x42, 0x68, 0x4D, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x49, 0x77, 0x51, 0x59, ++ 0x4D, 0x42, 0x61, 0x41, 0x46, 0x4A, 0x78, 0x66, 0x30, 0x47, 0x78, 0x6A, 0x0A, 0x6F, 0x31, 0x2B, 0x54, 0x79, 0x70, 0x4F, 0x59, 0x43, 0x4B, 0x32, 0x4D, 0x68, 0x36, 0x55, 0x73, 0x58, 0x4D, 0x45, 0x33, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, ++ 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x53, 0x63, 0x58, 0x39, 0x42, 0x73, 0x59, 0x36, 0x4E, 0x66, 0x6B, 0x38, 0x71, 0x54, 0x6D, 0x41, 0x69, 0x74, 0x6A, 0x49, 0x65, 0x6C, 0x4C, 0x46, 0x7A, 0x42, 0x4E, 0x7A, 0x41, 0x4F, 0x42, 0x67, 0x4E, ++ 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x0A, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x59, 0x59, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, ++ 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x67, 0x45, 0x41, 0x54, 0x68, 0x36, 0x35, 0x69, 0x73, 0x61, 0x67, 0x6D, 0x44, 0x39, 0x75, 0x77, 0x32, ++ 0x6E, 0x41, 0x61, 0x6C, 0x78, 0x4A, 0x0A, 0x55, 0x71, 0x7A, 0x4C, 0x4B, 0x31, 0x31, 0x34, 0x4F, 0x4D, 0x48, 0x56, 0x56, 0x49, 0x53, 0x66, 0x6B, 0x2F, 0x43, 0x48, 0x47, 0x54, 0x30, 0x73, 0x5A, 0x6F, 0x6E, 0x72, 0x44, 0x55, 0x4C, 0x38, 0x7A, ++ 0x50, 0x42, 0x31, 0x68, 0x54, 0x2B, 0x4C, 0x39, 0x49, 0x42, 0x64, 0x65, 0x65, 0x55, 0x58, 0x5A, 0x37, 0x30, 0x31, 0x67, 0x75, 0x4C, 0x79, 0x50, 0x49, 0x35, 0x39, 0x57, 0x7A, 0x62, 0x4C, 0x57, 0x6F, 0x41, 0x41, 0x4B, 0x66, 0x4C, 0x4F, 0x4B, ++ 0x79, 0x7A, 0x78, 0x0A, 0x6A, 0x36, 0x70, 0x74, 0x42, 0x5A, 0x4E, 0x73, 0x63, 0x73, 0x64, 0x57, 0x36, 0x39, 0x39, 0x51, 0x49, 0x79, 0x6A, 0x6C, 0x52, 0x52, 0x41, 0x39, 0x36, 0x47, 0x65, 0x6A, 0x72, 0x77, 0x35, 0x56, 0x44, 0x35, 0x41, 0x4A, ++ 0x59, 0x75, 0x39, 0x4C, 0x57, 0x61, 0x4C, 0x32, 0x55, 0x2F, 0x48, 0x41, 0x4E, 0x65, 0x51, 0x76, 0x77, 0x53, 0x53, 0x39, 0x65, 0x53, 0x39, 0x4F, 0x49, 0x43, 0x49, 0x37, 0x2F, 0x52, 0x6F, 0x67, 0x73, 0x4B, 0x51, 0x4F, 0x4C, 0x48, 0x44, 0x74, ++ 0x0A, 0x64, 0x44, 0x2B, 0x34, 0x45, 0x35, 0x55, 0x47, 0x55, 0x63, 0x6A, 0x6F, 0x68, 0x79, 0x62, 0x4B, 0x70, 0x46, 0x74, 0x71, 0x46, 0x69, 0x47, 0x53, 0x33, 0x58, 0x4E, 0x67, 0x6E, 0x68, 0x41, 0x59, 0x33, 0x6A, 0x79, 0x42, 0x36, 0x75, 0x67, ++ 0x59, 0x77, 0x33, 0x79, 0x4A, 0x38, 0x6F, 0x74, 0x51, 0x50, 0x72, 0x30, 0x52, 0x34, 0x68, 0x55, 0x44, 0x71, 0x44, 0x5A, 0x39, 0x4D, 0x77, 0x46, 0x73, 0x53, 0x42, 0x58, 0x58, 0x69, 0x4A, 0x43, 0x5A, 0x42, 0x4D, 0x58, 0x4D, 0x0A, 0x35, 0x67, ++ 0x66, 0x30, 0x76, 0x50, 0x53, 0x51, 0x37, 0x52, 0x50, 0x69, 0x36, 0x6F, 0x76, 0x44, 0x6A, 0x36, 0x4D, 0x7A, 0x44, 0x38, 0x45, 0x70, 0x54, 0x42, 0x4E, 0x4F, 0x32, 0x68, 0x56, 0x57, 0x63, 0x58, 0x4E, 0x79, 0x67, 0x6C, 0x44, 0x32, 0x6D, 0x6A, ++ 0x4E, 0x38, 0x6F, 0x72, 0x47, 0x6F, 0x47, 0x6A, 0x52, 0x30, 0x5A, 0x56, 0x7A, 0x4F, 0x30, 0x65, 0x75, 0x72, 0x55, 0x2B, 0x41, 0x61, 0x67, 0x4E, 0x6A, 0x71, 0x4F, 0x6B, 0x6E, 0x6B, 0x4A, 0x6A, 0x43, 0x62, 0x0A, 0x35, 0x52, 0x79, 0x4B, 0x71, ++ 0x4B, 0x6B, 0x56, 0x4D, 0x6F, 0x61, 0x5A, 0x6B, 0x67, 0x6F, 0x51, 0x49, 0x31, 0x59, 0x53, 0x34, 0x50, 0x62, 0x4F, 0x54, 0x4F, 0x4B, 0x37, 0x76, 0x74, 0x75, 0x4E, 0x6B, 0x6E, 0x4D, 0x42, 0x5A, 0x69, 0x39, 0x69, 0x50, 0x72, 0x4A, 0x79, 0x4A, ++ 0x30, 0x55, 0x32, 0x37, 0x55, 0x31, 0x57, 0x34, 0x35, 0x65, 0x5A, 0x2F, 0x7A, 0x6F, 0x31, 0x50, 0x71, 0x56, 0x55, 0x53, 0x6C, 0x4A, 0x5A, 0x53, 0x32, 0x44, 0x62, 0x37, 0x76, 0x35, 0x34, 0x0A, 0x45, 0x58, 0x39, 0x4B, 0x33, 0x42, 0x52, 0x35, ++ 0x59, 0x4C, 0x5A, 0x72, 0x5A, 0x41, 0x50, 0x62, 0x46, 0x59, 0x50, 0x68, 0x6F, 0x72, 0x37, 0x32, 0x49, 0x35, 0x64, 0x51, 0x38, 0x41, 0x6B, 0x7A, 0x4E, 0x71, 0x64, 0x78, 0x6C, 0x69, 0x58, 0x7A, 0x75, 0x55, 0x4A, 0x39, 0x32, 0x7A, 0x67, 0x2F, ++ 0x4C, 0x46, 0x69, 0x73, 0x36, 0x45, 0x4C, 0x68, 0x44, 0x74, 0x6A, 0x54, 0x4F, 0x30, 0x77, 0x75, 0x67, 0x75, 0x6D, 0x44, 0x4C, 0x6D, 0x73, 0x78, 0x32, 0x64, 0x31, 0x48, 0x0A, 0x68, 0x6B, 0x39, 0x74, 0x6C, 0x35, 0x45, 0x75, 0x54, 0x2B, 0x49, ++ 0x6F, 0x63, 0x54, 0x55, 0x57, 0x30, 0x66, 0x4A, 0x7A, 0x2F, 0x69, 0x55, 0x72, 0x42, 0x30, 0x63, 0x6B, 0x59, 0x79, 0x66, 0x49, 0x2B, 0x50, 0x62, 0x5A, 0x61, 0x2F, 0x77, 0x53, 0x4D, 0x56, 0x59, 0x49, 0x77, 0x46, 0x4E, 0x43, 0x72, 0x35, 0x7A, ++ 0x51, 0x4D, 0x33, 0x37, 0x38, 0x42, 0x76, 0x41, 0x78, 0x52, 0x41, 0x4D, 0x55, 0x38, 0x56, 0x6A, 0x71, 0x38, 0x6D, 0x6F, 0x4E, 0x71, 0x52, 0x47, 0x79, 0x0A, 0x67, 0x37, 0x37, 0x46, 0x47, 0x72, 0x38, 0x48, 0x36, 0x6C, 0x6E, 0x63, 0x6F, 0x34, ++ 0x67, 0x31, 0x37, 0x35, 0x78, 0x32, 0x4D, 0x6A, 0x78, 0x4E, 0x42, 0x69, 0x4C, 0x4F, 0x46, 0x65, 0x58, 0x64, 0x6E, 0x74, 0x69, 0x50, 0x32, 0x74, 0x37, 0x53, 0x78, 0x44, 0x6E, 0x6C, 0x46, 0x34, 0x48, 0x50, 0x4F, 0x45, 0x66, 0x72, 0x66, 0x34, ++ 0x68, 0x74, 0x57, 0x52, 0x76, 0x66, 0x6E, 0x30, 0x49, 0x55, 0x72, 0x6E, 0x37, 0x50, 0x71, 0x4C, 0x42, 0x6D, 0x5A, 0x64, 0x6F, 0x33, 0x0A, 0x72, 0x35, 0x2B, 0x71, 0x50, 0x65, 0x6F, 0x6F, 0x74, 0x74, 0x37, 0x56, 0x4D, 0x56, 0x67, 0x57, 0x67, ++ 0x6C, 0x76, 0x71, 0x75, 0x78, 0x6C, 0x31, 0x41, 0x6E, 0x4D, 0x61, 0x79, 0x6B, 0x67, 0x61, 0x49, 0x5A, 0x4F, 0x51, 0x43, 0x6F, 0x36, 0x54, 0x68, 0x4B, 0x64, 0x39, 0x4F, 0x79, 0x4D, 0x59, 0x6B, 0x6F, 0x6D, 0x67, 0x6A, 0x61, 0x77, 0x3D, 0x0A, ++ 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x45, 0x43, 0x2D, 0x33, 0x38, 0x34, ++ 0x20, 0x43, 0x41, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, ++ 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x5A, 0x54, 0x43, 0x43, 0x41, 0x65, 0x75, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x65, 0x49, 0x38, 0x6E, 0x58, 0x49, 0x45, 0x53, 0x55, 0x69, 0x43, ++ 0x6C, 0x42, 0x4E, 0x41, 0x74, 0x33, 0x62, 0x70, 0x7A, 0x39, 0x44, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x7A, 0x42, 0x30, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, ++ 0x47, 0x45, 0x77, 0x4A, 0x51, 0x0A, 0x54, 0x44, 0x45, 0x68, 0x4D, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x59, 0x51, 0x58, 0x4E, 0x7A, 0x5A, 0x57, 0x4E, 0x76, 0x49, 0x45, 0x52, 0x68, 0x64, 0x47, 0x45, 0x67, 0x55, 0x33, ++ 0x6C, 0x7A, 0x64, 0x47, 0x56, 0x74, 0x63, 0x79, 0x42, 0x54, 0x4C, 0x6B, 0x45, 0x75, 0x4D, 0x53, 0x63, 0x77, 0x4A, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, 0x45, 0x78, 0x35, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x64, 0x57, 0x30, 0x67, 0x51, 0x32, ++ 0x56, 0x79, 0x0A, 0x64, 0x47, 0x6C, 0x6D, 0x61, 0x57, 0x4E, 0x68, 0x64, 0x47, 0x6C, 0x76, 0x62, 0x69, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6F, 0x62, 0x33, 0x4A, 0x70, 0x64, 0x48, 0x6B, 0x78, 0x47, 0x54, 0x41, 0x58, 0x42, 0x67, 0x4E, 0x56, 0x42, ++ 0x41, 0x4D, 0x54, 0x45, 0x45, 0x4E, 0x6C, 0x63, 0x6E, 0x52, 0x31, 0x62, 0x53, 0x42, 0x46, 0x51, 0x79, 0x30, 0x7A, 0x4F, 0x44, 0x51, 0x67, 0x51, 0x30, 0x45, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x54, 0x67, 0x77, 0x4D, 0x7A, 0x49, 0x32, 0x0A, ++ 0x4D, 0x44, 0x63, 0x79, 0x4E, 0x44, 0x55, 0x30, 0x57, 0x68, 0x63, 0x4E, 0x4E, 0x44, 0x4D, 0x77, 0x4D, 0x7A, 0x49, 0x32, 0x4D, 0x44, 0x63, 0x79, 0x4E, 0x44, 0x55, 0x30, 0x57, 0x6A, 0x42, 0x30, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, ++ 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x51, 0x54, 0x44, 0x45, 0x68, 0x4D, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x59, 0x51, 0x58, 0x4E, 0x7A, 0x5A, 0x57, 0x4E, 0x76, 0x49, 0x45, 0x52, 0x68, 0x0A, 0x64, 0x47, 0x45, ++ 0x67, 0x55, 0x33, 0x6C, 0x7A, 0x64, 0x47, 0x56, 0x74, 0x63, 0x79, 0x42, 0x54, 0x4C, 0x6B, 0x45, 0x75, 0x4D, 0x53, 0x63, 0x77, 0x4A, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, 0x45, 0x78, 0x35, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x64, 0x57, 0x30, ++ 0x67, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6C, 0x6D, 0x61, 0x57, 0x4E, 0x68, 0x64, 0x47, 0x6C, 0x76, 0x62, 0x69, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6F, 0x62, 0x33, 0x4A, 0x70, 0x64, 0x48, 0x6B, 0x78, 0x0A, 0x47, 0x54, 0x41, 0x58, 0x42, 0x67, ++ 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x45, 0x45, 0x4E, 0x6C, 0x63, 0x6E, 0x52, 0x31, 0x62, 0x53, 0x42, 0x46, 0x51, 0x79, 0x30, 0x7A, 0x4F, 0x44, 0x51, 0x67, 0x51, 0x30, 0x45, 0x77, 0x64, 0x6A, 0x41, 0x51, 0x42, 0x67, 0x63, 0x71, 0x68, 0x6B, ++ 0x6A, 0x4F, 0x50, 0x51, 0x49, 0x42, 0x42, 0x67, 0x55, 0x72, 0x67, 0x51, 0x51, 0x41, 0x49, 0x67, 0x4E, 0x69, 0x41, 0x41, 0x54, 0x45, 0x4B, 0x49, 0x36, 0x72, 0x47, 0x46, 0x74, 0x71, 0x0A, 0x76, 0x6D, 0x35, 0x6B, 0x4E, 0x32, 0x50, 0x6B, 0x7A, ++ 0x65, 0x79, 0x72, 0x4F, 0x76, 0x66, 0x4D, 0x6F, 0x62, 0x67, 0x4F, 0x67, 0x6B, 0x6E, 0x58, 0x68, 0x69, 0x6D, 0x66, 0x6F, 0x5A, 0x54, 0x79, 0x34, 0x32, 0x42, 0x34, 0x6D, 0x49, 0x46, 0x34, 0x42, 0x6B, 0x33, 0x79, 0x37, 0x4A, 0x6F, 0x4F, 0x56, ++ 0x32, 0x43, 0x44, 0x6E, 0x37, 0x54, 0x6D, 0x46, 0x79, 0x38, 0x61, 0x73, 0x31, 0x30, 0x43, 0x57, 0x34, 0x6B, 0x6A, 0x50, 0x4D, 0x49, 0x52, 0x42, 0x53, 0x71, 0x6E, 0x0A, 0x69, 0x42, 0x4D, 0x59, 0x38, 0x31, 0x43, 0x45, 0x31, 0x37, 0x30, 0x30, ++ 0x4C, 0x43, 0x65, 0x4A, 0x56, 0x66, 0x2F, 0x4F, 0x54, 0x4F, 0x66, 0x66, 0x70, 0x68, 0x38, 0x6F, 0x78, 0x50, 0x42, 0x55, 0x77, 0x37, 0x6C, 0x38, 0x74, 0x31, 0x4F, 0x74, 0x36, 0x38, 0x4B, 0x6A, 0x51, 0x6A, 0x42, 0x41, 0x4D, 0x41, 0x38, 0x47, ++ 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x48, 0x51, 0x59, 0x44, 0x0A, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x46, 0x49, 0x30, 0x47, 0x5A, 0x6E, 0x51, ++ 0x6B, 0x64, 0x6A, 0x72, 0x7A, 0x69, 0x66, 0x65, 0x38, 0x31, 0x72, 0x31, 0x48, 0x66, 0x53, 0x2B, 0x38, 0x45, 0x46, 0x39, 0x4C, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, ++ 0x42, 0x42, 0x6A, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x77, 0x4E, 0x6F, 0x0A, 0x41, 0x44, 0x42, 0x6C, 0x41, 0x6A, 0x41, 0x44, 0x56, 0x53, 0x32, 0x6D, 0x35, 0x68, 0x6A, 0x45, 0x66, 0x4F, ++ 0x2F, 0x4A, 0x55, 0x47, 0x37, 0x42, 0x4A, 0x77, 0x2B, 0x63, 0x68, 0x36, 0x39, 0x75, 0x31, 0x52, 0x73, 0x49, 0x47, 0x4C, 0x32, 0x53, 0x4B, 0x63, 0x48, 0x76, 0x6C, 0x4A, 0x46, 0x34, 0x30, 0x6A, 0x6F, 0x63, 0x56, 0x59, 0x6C, 0x69, 0x35, 0x52, ++ 0x73, 0x4A, 0x48, 0x72, 0x70, 0x6B, 0x61, 0x2F, 0x46, 0x32, 0x74, 0x4E, 0x51, 0x43, 0x4D, 0x51, 0x43, 0x30, 0x0A, 0x51, 0x6F, 0x53, 0x5A, 0x2F, 0x36, 0x76, 0x6E, 0x6E, 0x76, 0x75, 0x52, 0x6C, 0x79, 0x64, 0x64, 0x33, 0x4C, 0x42, 0x62, 0x4D, ++ 0x48, 0x48, 0x4F, 0x58, 0x6A, 0x67, 0x61, 0x61, 0x74, 0x6B, 0x6C, 0x35, 0x2B, 0x72, 0x33, 0x59, 0x5A, 0x4A, 0x57, 0x2B, 0x4F, 0x72, 0x61, 0x4E, 0x73, 0x4B, 0x48, 0x5A, 0x5A, 0x59, 0x75, 0x63, 0x69, 0x55, 0x76, 0x66, 0x39, 0x2F, 0x44, 0x45, ++ 0x38, 0x6B, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x54, 0x72, ++ 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, ++ 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x77, 0x44, 0x43, 0x43, 0x41, 0x36, 0x69, 0x67, 0x41, 0x77, 0x49, ++ 0x42, 0x41, 0x67, 0x49, 0x51, 0x48, 0x72, 0x39, 0x5A, 0x55, 0x4C, 0x6A, 0x4A, 0x67, 0x44, 0x64, 0x4D, 0x42, 0x76, 0x66, 0x72, 0x56, 0x55, 0x2B, 0x31, 0x37, 0x54, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, ++ 0x42, 0x41, 0x51, 0x30, 0x46, 0x41, 0x44, 0x42, 0x36, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0A, 0x45, 0x77, 0x4A, 0x51, 0x54, 0x44, 0x45, 0x68, 0x4D, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, ++ 0x4D, 0x59, 0x51, 0x58, 0x4E, 0x7A, 0x5A, 0x57, 0x4E, 0x76, 0x49, 0x45, 0x52, 0x68, 0x64, 0x47, 0x45, 0x67, 0x55, 0x33, 0x6C, 0x7A, 0x64, 0x47, 0x56, 0x74, 0x63, 0x79, 0x42, 0x54, 0x4C, 0x6B, 0x45, 0x75, 0x4D, 0x53, 0x63, 0x77, 0x4A, 0x51, ++ 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, 0x45, 0x78, 0x35, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x64, 0x57, 0x30, 0x67, 0x0A, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6C, 0x6D, 0x61, 0x57, 0x4E, 0x68, 0x64, 0x47, 0x6C, 0x76, 0x62, 0x69, 0x42, 0x42, 0x64, ++ 0x58, 0x52, 0x6F, 0x62, 0x33, 0x4A, 0x70, 0x64, 0x48, 0x6B, 0x78, 0x48, 0x7A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x46, 0x6B, 0x4E, 0x6C, 0x63, 0x6E, 0x52, 0x31, 0x62, 0x53, 0x42, 0x55, 0x63, 0x6E, 0x56, 0x7A, 0x64, ++ 0x47, 0x56, 0x6B, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x77, 0x0A, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x54, 0x67, 0x77, 0x4D, 0x7A, 0x45, 0x32, 0x4D, 0x54, 0x49, 0x78, 0x4D, 0x44, 0x45, 0x7A, 0x57, 0x68, 0x63, 0x4E, ++ 0x4E, 0x44, 0x4D, 0x77, 0x4D, 0x7A, 0x45, 0x32, 0x4D, 0x54, 0x49, 0x78, 0x4D, 0x44, 0x45, 0x7A, 0x57, 0x6A, 0x42, 0x36, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x51, 0x54, 0x44, 0x45, 0x68, ++ 0x4D, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x59, 0x0A, 0x51, 0x58, 0x4E, 0x7A, 0x5A, 0x57, 0x4E, 0x76, 0x49, 0x45, 0x52, 0x68, 0x64, 0x47, 0x45, 0x67, 0x55, 0x33, 0x6C, 0x7A, 0x64, 0x47, 0x56, 0x74, 0x63, 0x79, 0x42, ++ 0x54, 0x4C, 0x6B, 0x45, 0x75, 0x4D, 0x53, 0x63, 0x77, 0x4A, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, 0x45, 0x78, 0x35, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x64, 0x57, 0x30, 0x67, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6C, 0x6D, 0x61, 0x57, 0x4E, ++ 0x68, 0x64, 0x47, 0x6C, 0x76, 0x62, 0x69, 0x42, 0x42, 0x0A, 0x64, 0x58, 0x52, 0x6F, 0x62, 0x33, 0x4A, 0x70, 0x64, 0x48, 0x6B, 0x78, 0x48, 0x7A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x46, 0x6B, 0x4E, 0x6C, 0x63, 0x6E, ++ 0x52, 0x31, 0x62, 0x53, 0x42, 0x55, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x47, 0x56, 0x6B, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x77, 0x67, 0x67, 0x49, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, ++ 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x0A, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x44, 0x52, 0x4C, 0x59, 0x36, 0x37, 0x74, 0x7A, 0x62, 0x71, 0x62, ++ 0x54, 0x65, 0x52, 0x6E, 0x30, 0x36, 0x54, 0x70, 0x77, 0x58, 0x6B, 0x4B, 0x51, 0x4D, 0x6C, 0x7A, 0x68, 0x79, 0x43, 0x39, 0x33, 0x79, 0x5A, 0x6E, 0x30, 0x45, 0x47, 0x7A, 0x65, 0x32, 0x6A, 0x75, 0x73, 0x44, 0x62, 0x43, 0x53, 0x7A, 0x42, 0x66, ++ 0x4E, 0x38, 0x70, 0x0A, 0x66, 0x6B, 0x74, 0x6C, 0x4C, 0x35, 0x4F, 0x6E, 0x31, 0x41, 0x46, 0x72, 0x41, 0x79, 0x67, 0x59, 0x6F, 0x39, 0x69, 0x64, 0x42, 0x63, 0x45, 0x71, 0x32, 0x45, 0x58, 0x78, 0x6B, 0x64, 0x37, 0x66, 0x4F, 0x39, 0x43, 0x41, ++ 0x41, 0x6F, 0x7A, 0x50, 0x4F, 0x41, 0x2F, 0x71, 0x70, 0x31, 0x78, 0x34, 0x45, 0x61, 0x54, 0x42, 0x79, 0x49, 0x56, 0x63, 0x4A, 0x64, 0x50, 0x54, 0x73, 0x75, 0x63, 0x6C, 0x7A, 0x78, 0x46, 0x55, 0x6C, 0x36, 0x73, 0x31, 0x77, 0x42, 0x35, 0x32, ++ 0x0A, 0x48, 0x4F, 0x38, 0x41, 0x55, 0x35, 0x38, 0x35, 0x33, 0x42, 0x53, 0x6C, 0x4C, 0x43, 0x49, 0x6C, 0x73, 0x33, 0x4A, 0x79, 0x2F, 0x49, 0x32, 0x7A, 0x35, 0x54, 0x34, 0x49, 0x48, 0x68, 0x51, 0x71, 0x4E, 0x77, 0x75, 0x49, 0x50, 0x4D, 0x71, ++ 0x77, 0x39, 0x4D, 0x6A, 0x43, 0x6F, 0x61, 0x36, 0x38, 0x77, 0x62, 0x34, 0x70, 0x5A, 0x31, 0x58, 0x69, 0x2F, 0x4B, 0x31, 0x5A, 0x58, 0x50, 0x36, 0x39, 0x56, 0x79, 0x79, 0x77, 0x6B, 0x49, 0x33, 0x43, 0x37, 0x54, 0x65, 0x32, 0x0A, 0x66, 0x4A, ++ 0x6D, 0x49, 0x74, 0x64, 0x55, 0x44, 0x6D, 0x6A, 0x30, 0x56, 0x44, 0x54, 0x30, 0x36, 0x71, 0x4B, 0x68, 0x46, 0x38, 0x4A, 0x56, 0x4F, 0x4A, 0x56, 0x6B, 0x64, 0x7A, 0x5A, 0x68, 0x70, 0x75, 0x39, 0x50, 0x4D, 0x4D, 0x73, 0x6D, 0x4E, 0x37, 0x34, ++ 0x48, 0x2B, 0x72, 0x58, 0x32, 0x4A, 0x75, 0x37, 0x70, 0x67, 0x45, 0x38, 0x70, 0x6C, 0x6C, 0x57, 0x65, 0x67, 0x38, 0x78, 0x6E, 0x32, 0x41, 0x31, 0x62, 0x55, 0x61, 0x74, 0x4D, 0x6E, 0x34, 0x71, 0x47, 0x74, 0x0A, 0x67, 0x2F, 0x42, 0x4B, 0x45, ++ 0x69, 0x4A, 0x33, 0x48, 0x41, 0x56, 0x7A, 0x34, 0x68, 0x6C, 0x78, 0x51, 0x73, 0x44, 0x73, 0x64, 0x55, 0x61, 0x61, 0x6B, 0x46, 0x6A, 0x67, 0x61, 0x6F, 0x34, 0x72, 0x70, 0x55, 0x59, 0x77, 0x42, 0x49, 0x34, 0x5A, 0x73, 0x68, 0x66, 0x6A, 0x76, ++ 0x71, 0x6D, 0x36, 0x66, 0x31, 0x62, 0x78, 0x4A, 0x41, 0x50, 0x58, 0x73, 0x69, 0x45, 0x6F, 0x64, 0x67, 0x34, 0x32, 0x4D, 0x45, 0x78, 0x35, 0x31, 0x55, 0x47, 0x61, 0x6D, 0x71, 0x69, 0x34, 0x0A, 0x4E, 0x62, 0x6F, 0x4D, 0x4F, 0x76, 0x4A, 0x45, ++ 0x47, 0x79, 0x43, 0x49, 0x39, 0x38, 0x55, 0x6C, 0x31, 0x7A, 0x33, 0x47, 0x34, 0x7A, 0x35, 0x44, 0x33, 0x59, 0x66, 0x2B, 0x78, 0x4F, 0x72, 0x31, 0x55, 0x7A, 0x35, 0x4D, 0x5A, 0x66, 0x38, 0x37, 0x53, 0x73, 0x74, 0x34, 0x57, 0x6D, 0x73, 0x58, ++ 0x58, 0x77, 0x33, 0x48, 0x77, 0x30, 0x39, 0x4F, 0x6D, 0x69, 0x71, 0x69, 0x37, 0x56, 0x64, 0x4E, 0x49, 0x75, 0x4A, 0x47, 0x6D, 0x6A, 0x38, 0x50, 0x6B, 0x54, 0x51, 0x6B, 0x0A, 0x66, 0x56, 0x58, 0x6A, 0x6A, 0x4A, 0x55, 0x33, 0x30, 0x78, 0x72, ++ 0x77, 0x43, 0x53, 0x73, 0x73, 0x30, 0x73, 0x6D, 0x4E, 0x74, 0x41, 0x30, 0x41, 0x71, 0x32, 0x63, 0x70, 0x4B, 0x4E, 0x67, 0x42, 0x39, 0x52, 0x6B, 0x45, 0x74, 0x68, 0x32, 0x2B, 0x64, 0x76, 0x35, 0x79, 0x58, 0x4D, 0x53, 0x46, 0x79, 0x74, 0x4B, ++ 0x41, 0x51, 0x64, 0x38, 0x46, 0x71, 0x4B, 0x50, 0x56, 0x68, 0x4A, 0x42, 0x50, 0x43, 0x2F, 0x50, 0x67, 0x50, 0x35, 0x73, 0x5A, 0x30, 0x6A, 0x65, 0x4A, 0x0A, 0x50, 0x2F, 0x4A, 0x37, 0x55, 0x68, 0x79, 0x4D, 0x39, 0x75, 0x48, 0x33, 0x50, 0x41, ++ 0x65, 0x58, 0x6A, 0x41, 0x36, 0x69, 0x57, 0x59, 0x45, 0x4D, 0x73, 0x70, 0x41, 0x39, 0x30, 0x2B, 0x4E, 0x5A, 0x52, 0x75, 0x30, 0x50, 0x71, 0x61, 0x66, 0x65, 0x67, 0x47, 0x74, 0x61, 0x71, 0x67, 0x65, 0x32, 0x47, 0x63, 0x75, 0x38, 0x56, 0x2F, ++ 0x4F, 0x58, 0x49, 0x58, 0x6F, 0x4D, 0x73, 0x53, 0x74, 0x30, 0x50, 0x75, 0x76, 0x61, 0x70, 0x32, 0x63, 0x74, 0x54, 0x4D, 0x53, 0x59, 0x0A, 0x6E, 0x6A, 0x59, 0x4A, 0x64, 0x6D, 0x5A, 0x6D, 0x2F, 0x42, 0x6F, 0x2F, 0x36, 0x6B, 0x68, 0x55, 0x48, ++ 0x4C, 0x34, 0x77, 0x76, 0x59, 0x42, 0x51, 0x76, 0x33, 0x79, 0x31, 0x7A, 0x67, 0x44, 0x32, 0x44, 0x47, 0x48, 0x5A, 0x35, 0x79, 0x51, 0x44, 0x34, 0x4F, 0x4D, 0x42, 0x67, 0x51, 0x36, 0x39, 0x32, 0x49, 0x55, 0x30, 0x69, 0x4C, 0x32, 0x79, 0x4E, ++ 0x71, 0x68, 0x37, 0x58, 0x41, 0x6A, 0x6C, 0x52, 0x49, 0x43, 0x4D, 0x62, 0x2F, 0x67, 0x76, 0x31, 0x53, 0x48, 0x4B, 0x0A, 0x48, 0x52, 0x7A, 0x51, 0x2B, 0x38, 0x53, 0x31, 0x68, 0x39, 0x45, 0x36, 0x54, 0x73, 0x64, 0x32, 0x74, 0x54, 0x56, 0x49, ++ 0x74, 0x51, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6F, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x42, 0x30, 0x47, ++ 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x53, 0x4D, 0x2B, 0x78, 0x78, 0x31, 0x0A, 0x76, 0x41, 0x4C, 0x54, 0x6E, 0x30, 0x34, 0x75, 0x53, 0x4E, 0x6E, 0x35, 0x59, 0x46, 0x53, 0x71, 0x78, 0x4C, 0x4E, 0x50, 0x2B, 0x6A, 0x41, ++ 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x51, 0x59, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4E, 0x42, 0x51, 0x41, ++ 0x44, 0x67, 0x67, 0x49, 0x42, 0x41, 0x45, 0x69, 0x69, 0x31, 0x51, 0x41, 0x4C, 0x0A, 0x4C, 0x74, 0x41, 0x2F, 0x76, 0x42, 0x7A, 0x56, 0x74, 0x56, 0x52, 0x4A, 0x48, 0x6C, 0x70, 0x72, 0x39, 0x4F, 0x54, 0x79, 0x34, 0x45, 0x41, 0x33, 0x34, 0x4D, ++ 0x77, 0x55, 0x65, 0x37, 0x6E, 0x4A, 0x2B, 0x6A, 0x57, 0x31, 0x64, 0x52, 0x65, 0x54, 0x61, 0x67, 0x56, 0x70, 0x68, 0x5A, 0x7A, 0x4E, 0x54, 0x78, 0x6C, 0x34, 0x57, 0x78, 0x6D, 0x42, 0x38, 0x32, 0x4D, 0x2B, 0x77, 0x38, 0x35, 0x62, 0x6A, 0x2F, ++ 0x55, 0x76, 0x58, 0x67, 0x46, 0x32, 0x45, 0x7A, 0x38, 0x73, 0x0A, 0x41, 0x4C, 0x6E, 0x4E, 0x6C, 0x6C, 0x49, 0x35, 0x53, 0x57, 0x30, 0x45, 0x54, 0x73, 0x58, 0x70, 0x44, 0x34, 0x59, 0x4E, 0x34, 0x66, 0x71, 0x7A, 0x58, 0x34, 0x49, 0x53, 0x38, ++ 0x54, 0x72, 0x4F, 0x5A, 0x67, 0x59, 0x6B, 0x4E, 0x43, 0x76, 0x6F, 0x7A, 0x4D, 0x72, 0x6E, 0x61, 0x64, 0x79, 0x48, 0x6E, 0x63, 0x49, 0x30, 0x31, 0x33, 0x6E, 0x52, 0x30, 0x33, 0x65, 0x34, 0x71, 0x6C, 0x6C, 0x59, 0x2F, 0x70, 0x30, 0x6D, 0x2B, ++ 0x6A, 0x69, 0x47, 0x50, 0x70, 0x32, 0x4B, 0x0A, 0x68, 0x32, 0x52, 0x58, 0x35, 0x52, 0x63, 0x36, 0x34, 0x76, 0x6D, 0x4E, 0x75, 0x65, 0x4D, 0x7A, 0x65, 0x4D, 0x47, 0x51, 0x32, 0x4C, 0x6A, 0x64, 0x74, 0x34, 0x4E, 0x52, 0x35, 0x4D, 0x54, 0x4D, ++ 0x49, 0x39, 0x55, 0x47, 0x66, 0x4F, 0x5A, 0x52, 0x30, 0x38, 0x30, 0x30, 0x4D, 0x63, 0x44, 0x32, 0x52, 0x72, 0x73, 0x4C, 0x72, 0x66, 0x77, 0x39, 0x45, 0x41, 0x55, 0x71, 0x4F, 0x30, 0x71, 0x52, 0x4A, 0x65, 0x36, 0x4D, 0x31, 0x49, 0x53, 0x48, ++ 0x67, 0x43, 0x71, 0x38, 0x0A, 0x43, 0x59, 0x79, 0x71, 0x4F, 0x68, 0x4E, 0x66, 0x36, 0x44, 0x52, 0x35, 0x55, 0x4D, 0x45, 0x51, 0x47, 0x66, 0x6E, 0x54, 0x4B, 0x42, 0x37, 0x55, 0x30, 0x56, 0x45, 0x77, 0x4B, 0x62, 0x4F, 0x75, 0x6B, 0x47, 0x66, ++ 0x57, 0x48, 0x77, 0x70, 0x6A, 0x73, 0x63, 0x57, 0x70, 0x78, 0x6B, 0x49, 0x78, 0x59, 0x78, 0x65, 0x55, 0x37, 0x32, 0x6E, 0x4C, 0x4C, 0x2F, 0x71, 0x4D, 0x46, 0x48, 0x33, 0x45, 0x51, 0x78, 0x69, 0x4A, 0x32, 0x66, 0x41, 0x79, 0x51, 0x4F, 0x61, ++ 0x41, 0x0A, 0x34, 0x6B, 0x5A, 0x66, 0x35, 0x65, 0x50, 0x42, 0x41, 0x46, 0x6D, 0x6F, 0x2B, 0x65, 0x67, 0x67, 0x76, 0x49, 0x6B, 0x73, 0x44, 0x6B, 0x63, 0x30, 0x43, 0x2B, 0x70, 0x58, 0x77, 0x6C, 0x4D, 0x32, 0x2F, 0x4B, 0x66, 0x55, 0x72, 0x7A, ++ 0x48, 0x4E, 0x2F, 0x67, 0x4C, 0x6C, 0x64, 0x66, 0x71, 0x35, 0x4A, 0x77, 0x6E, 0x35, 0x38, 0x2F, 0x55, 0x37, 0x79, 0x6E, 0x32, 0x66, 0x71, 0x53, 0x4C, 0x4C, 0x69, 0x4D, 0x6D, 0x71, 0x30, 0x55, 0x63, 0x39, 0x4E, 0x6E, 0x65, 0x6F, 0x0A, 0x57, ++ 0x57, 0x52, 0x72, 0x4A, 0x38, 0x2F, 0x76, 0x4A, 0x38, 0x48, 0x6A, 0x4A, 0x4C, 0x57, 0x47, 0x39, 0x36, 0x35, 0x2B, 0x4D, 0x6B, 0x32, 0x77, 0x65, 0x57, 0x6A, 0x52, 0x4F, 0x65, 0x69, 0x51, 0x57, 0x4D, 0x4F, 0x44, 0x76, 0x41, 0x38, 0x73, 0x31, ++ 0x70, 0x66, 0x72, 0x7A, 0x67, 0x7A, 0x68, 0x49, 0x4D, 0x66, 0x61, 0x74, 0x7A, 0x37, 0x44, 0x50, 0x37, 0x38, 0x76, 0x33, 0x44, 0x53, 0x6B, 0x2B, 0x79, 0x73, 0x68, 0x7A, 0x57, 0x65, 0x50, 0x53, 0x2F, 0x54, 0x6A, 0x0A, 0x36, 0x74, 0x51, 0x2F, ++ 0x35, 0x30, 0x2B, 0x36, 0x75, 0x61, 0x57, 0x54, 0x52, 0x52, 0x78, 0x6D, 0x48, 0x79, 0x48, 0x36, 0x5A, 0x46, 0x35, 0x76, 0x34, 0x48, 0x61, 0x55, 0x4D, 0x73, 0x74, 0x31, 0x39, 0x57, 0x37, 0x6C, 0x39, 0x6F, 0x2F, 0x48, 0x75, 0x4B, 0x54, 0x4D, ++ 0x71, 0x4A, 0x5A, 0x39, 0x5A, 0x50, 0x73, 0x6B, 0x57, 0x6B, 0x6F, 0x44, 0x62, 0x47, 0x73, 0x34, 0x78, 0x75, 0x67, 0x44, 0x51, 0x35, 0x72, 0x33, 0x56, 0x37, 0x6D, 0x7A, 0x4B, 0x57, 0x6D, 0x54, 0x0A, 0x4F, 0x50, 0x51, 0x44, 0x38, 0x72, 0x76, ++ 0x37, 0x67, 0x6D, 0x73, 0x48, 0x49, 0x4E, 0x46, 0x53, 0x48, 0x35, 0x70, 0x6B, 0x41, 0x6E, 0x75, 0x59, 0x5A, 0x74, 0x74, 0x63, 0x54, 0x56, 0x6F, 0x50, 0x30, 0x49, 0x53, 0x56, 0x6F, 0x44, 0x77, 0x55, 0x51, 0x77, 0x62, 0x4B, 0x79, 0x74, 0x75, ++ 0x34, 0x51, 0x54, 0x62, 0x61, 0x61, 0x6B, 0x52, 0x6E, 0x68, 0x36, 0x2B, 0x76, 0x34, 0x30, 0x55, 0x52, 0x46, 0x57, 0x6B, 0x49, 0x73, 0x72, 0x34, 0x57, 0x4F, 0x5A, 0x63, 0x6B, 0x0A, 0x62, 0x78, 0x4A, 0x46, 0x30, 0x57, 0x64, 0x64, 0x43, 0x61, ++ 0x6A, 0x4A, 0x46, 0x64, 0x72, 0x36, 0x30, 0x71, 0x5A, 0x66, 0x45, 0x32, 0x45, 0x66, 0x76, 0x34, 0x57, 0x73, 0x74, 0x4B, 0x32, 0x74, 0x42, 0x5A, 0x51, 0x49, 0x67, 0x78, 0x35, 0x31, 0x46, 0x39, 0x4E, 0x78, 0x4F, 0x35, 0x4E, 0x51, 0x49, 0x31, ++ 0x6D, 0x67, 0x37, 0x54, 0x79, 0x52, 0x56, 0x4A, 0x31, 0x32, 0x41, 0x4D, 0x58, 0x44, 0x75, 0x44, 0x6A, 0x62, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, ++ 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x54, 0x75, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, ++ 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x73, 0x7A, 0x43, 0x43, 0x41, 0x35, 0x75, 0x67, ++ 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x55, 0x45, 0x77, 0x4C, 0x56, 0x34, 0x6B, 0x42, 0x4D, 0x6B, 0x6B, 0x61, 0x47, 0x46, 0x6D, 0x64, 0x64, 0x74, 0x4C, 0x75, 0x37, 0x73, 0x6D, 0x73, 0x2B, 0x2F, 0x42, 0x4D, 0x77, 0x44, 0x51, 0x59, 0x4A, ++ 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x77, 0x59, 0x54, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x0A, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x56, 0x45, 0x34, 0x78, 0x4E, 0x7A, 0x41, ++ 0x31, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x4C, 0x6B, 0x46, 0x6E, 0x5A, 0x57, 0x35, 0x6A, 0x5A, 0x53, 0x42, 0x4F, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x35, 0x68, 0x62, 0x47, 0x55, 0x67, 0x5A, 0x47, 0x55, 0x67, 0x51, 0x32, 0x56, ++ 0x79, 0x64, 0x47, 0x6C, 0x6D, 0x61, 0x57, 0x4E, 0x68, 0x64, 0x47, 0x6C, 0x76, 0x62, 0x69, 0x42, 0x46, 0x62, 0x47, 0x56, 0x6A, 0x0A, 0x64, 0x48, 0x4A, 0x76, 0x62, 0x6D, 0x6C, 0x78, 0x64, 0x57, 0x55, 0x78, 0x47, 0x54, 0x41, 0x58, 0x42, 0x67, ++ 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x45, 0x46, 0x52, 0x31, 0x62, 0x6C, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x54, 0x6B, 0x77, 0x4E, 0x44, ++ 0x49, 0x32, 0x4D, 0x44, 0x67, 0x31, 0x4E, 0x7A, 0x55, 0x32, 0x57, 0x68, 0x63, 0x4E, 0x4E, 0x44, 0x51, 0x77, 0x0A, 0x4E, 0x44, 0x49, 0x32, 0x4D, 0x44, 0x67, 0x31, 0x4E, 0x7A, 0x55, 0x32, 0x57, 0x6A, 0x42, 0x68, 0x4D, 0x51, 0x73, 0x77, 0x43, ++ 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x55, 0x54, 0x6A, 0x45, 0x33, 0x4D, 0x44, 0x55, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x75, 0x51, 0x57, 0x64, 0x6C, 0x62, 0x6D, 0x4E, 0x6C, 0x49, 0x45, 0x35, 0x68, 0x64, ++ 0x47, 0x6C, 0x76, 0x62, 0x6D, 0x46, 0x73, 0x5A, 0x53, 0x42, 0x6B, 0x5A, 0x53, 0x42, 0x44, 0x0A, 0x5A, 0x58, 0x4A, 0x30, 0x61, 0x57, 0x5A, 0x70, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x49, 0x45, 0x56, 0x73, 0x5A, 0x57, 0x4E, 0x30, ++ 0x63, 0x6D, 0x39, 0x75, 0x61, 0x58, 0x46, 0x31, 0x5A, 0x54, 0x45, 0x5A, 0x4D, 0x42, 0x63, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x51, 0x56, 0x48, 0x56, 0x75, 0x56, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x67, 0x55, 0x6D, 0x39, 0x76, ++ 0x64, 0x43, 0x42, 0x44, 0x51, 0x54, 0x43, 0x43, 0x41, 0x69, 0x49, 0x77, 0x0A, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x50, 0x41, 0x44, 0x43, ++ 0x43, 0x41, 0x67, 0x6F, 0x43, 0x67, 0x67, 0x49, 0x42, 0x41, 0x4D, 0x50, 0x4E, 0x30, 0x2F, 0x79, 0x39, 0x42, 0x46, 0x50, 0x64, 0x44, 0x43, 0x41, 0x36, 0x31, 0x59, 0x67, 0x75, 0x42, 0x55, 0x74, 0x42, 0x39, 0x59, 0x4F, 0x43, 0x66, 0x76, 0x64, ++ 0x5A, 0x6E, 0x35, 0x36, 0x65, 0x59, 0x2B, 0x68, 0x7A, 0x0A, 0x32, 0x76, 0x59, 0x47, 0x71, 0x55, 0x38, 0x66, 0x74, 0x50, 0x6B, 0x4C, 0x48, 0x7A, 0x6D, 0x4D, 0x6D, 0x69, 0x44, 0x51, 0x66, 0x67, 0x62, 0x55, 0x37, 0x44, 0x54, 0x5A, 0x68, 0x72, ++ 0x78, 0x31, 0x57, 0x34, 0x65, 0x49, 0x38, 0x4E, 0x4C, 0x5A, 0x31, 0x4B, 0x4D, 0x4B, 0x73, 0x6D, 0x77, 0x62, 0x36, 0x30, 0x6B, 0x73, 0x50, 0x71, 0x78, 0x64, 0x32, 0x4A, 0x51, 0x44, 0x6F, 0x4F, 0x77, 0x30, 0x35, 0x54, 0x44, 0x45, 0x4E, 0x58, ++ 0x33, 0x37, 0x4A, 0x6B, 0x30, 0x62, 0x0A, 0x62, 0x6A, 0x42, 0x55, 0x32, 0x50, 0x57, 0x41, 0x52, 0x5A, 0x77, 0x35, 0x72, 0x5A, 0x7A, 0x4A, 0x4A, 0x51, 0x52, 0x4E, 0x6D, 0x70, 0x41, 0x2B, 0x54, 0x6B, 0x42, 0x75, 0x69, 0x6D, 0x76, 0x4E, 0x4B, ++ 0x57, 0x66, 0x47, 0x7A, 0x43, 0x33, 0x67, 0x64, 0x4F, 0x67, 0x46, 0x56, 0x77, 0x70, 0x49, 0x55, 0x50, 0x70, 0x36, 0x51, 0x39, 0x70, 0x2B, 0x37, 0x46, 0x75, 0x61, 0x44, 0x6D, 0x4A, 0x32, 0x2F, 0x75, 0x71, 0x64, 0x48, 0x59, 0x56, 0x79, 0x37, ++ 0x42, 0x47, 0x37, 0x0A, 0x4E, 0x65, 0x67, 0x66, 0x4A, 0x37, 0x2F, 0x42, 0x6F, 0x63, 0x65, 0x37, 0x53, 0x42, 0x62, 0x64, 0x56, 0x74, 0x66, 0x4D, 0x54, 0x71, 0x44, 0x68, 0x75, 0x61, 0x7A, 0x62, 0x31, 0x59, 0x4D, 0x5A, 0x47, 0x6F, 0x58, 0x52, ++ 0x6C, 0x4A, 0x66, 0x58, 0x79, 0x71, 0x4E, 0x6C, 0x43, 0x2F, 0x4D, 0x34, 0x2B, 0x51, 0x4B, 0x75, 0x33, 0x66, 0x5A, 0x6E, 0x7A, 0x38, 0x6B, 0x2F, 0x39, 0x59, 0x6F, 0x73, 0x52, 0x78, 0x71, 0x5A, 0x62, 0x77, 0x55, 0x4E, 0x2F, 0x64, 0x41, 0x64, ++ 0x0A, 0x67, 0x6A, 0x48, 0x38, 0x4B, 0x63, 0x77, 0x41, 0x57, 0x4A, 0x65, 0x52, 0x54, 0x49, 0x41, 0x41, 0x48, 0x44, 0x4F, 0x46, 0x6C, 0x69, 0x2F, 0x4C, 0x51, 0x63, 0x4B, 0x4C, 0x45, 0x49, 0x54, 0x44, 0x43, 0x53, 0x53, 0x4A, 0x48, 0x37, 0x55, ++ 0x50, 0x32, 0x64, 0x6C, 0x33, 0x52, 0x78, 0x69, 0x53, 0x6C, 0x47, 0x42, 0x63, 0x78, 0x35, 0x6B, 0x44, 0x50, 0x50, 0x37, 0x33, 0x6C, 0x61, 0x64, 0x39, 0x55, 0x4B, 0x47, 0x41, 0x77, 0x71, 0x6D, 0x44, 0x72, 0x56, 0x69, 0x57, 0x0A, 0x56, 0x53, ++ 0x48, 0x62, 0x68, 0x6C, 0x6E, 0x55, 0x72, 0x38, 0x61, 0x38, 0x33, 0x59, 0x46, 0x75, 0x42, 0x39, 0x74, 0x67, 0x59, 0x76, 0x37, 0x73, 0x45, 0x47, 0x37, 0x61, 0x61, 0x41, 0x48, 0x30, 0x67, 0x78, 0x75, 0x70, 0x50, 0x71, 0x4A, 0x62, 0x49, 0x39, ++ 0x64, 0x6B, 0x78, 0x74, 0x2F, 0x63, 0x6F, 0x6E, 0x33, 0x59, 0x53, 0x37, 0x71, 0x43, 0x30, 0x6C, 0x48, 0x34, 0x5A, 0x72, 0x38, 0x47, 0x52, 0x75, 0x52, 0x35, 0x4B, 0x69, 0x59, 0x32, 0x65, 0x59, 0x38, 0x66, 0x0A, 0x54, 0x70, 0x6B, 0x64, 0x73, ++ 0x6F, 0x38, 0x4D, 0x44, 0x68, 0x7A, 0x2F, 0x79, 0x56, 0x33, 0x41, 0x2F, 0x5A, 0x41, 0x51, 0x70, 0x72, 0x45, 0x33, 0x38, 0x38, 0x30, 0x36, 0x4A, 0x47, 0x36, 0x30, 0x68, 0x5A, 0x43, 0x2F, 0x67, 0x4C, 0x6B, 0x4D, 0x6A, 0x4E, 0x57, 0x62, 0x31, ++ 0x73, 0x6A, 0x78, 0x56, 0x6A, 0x38, 0x61, 0x67, 0x49, 0x6C, 0x36, 0x71, 0x65, 0x49, 0x62, 0x4D, 0x6C, 0x45, 0x73, 0x50, 0x76, 0x4C, 0x66, 0x65, 0x2F, 0x5A, 0x64, 0x65, 0x69, 0x6B, 0x5A, 0x0A, 0x6A, 0x75, 0x58, 0x49, 0x76, 0x54, 0x5A, 0x78, ++ 0x69, 0x31, 0x31, 0x4D, 0x77, 0x68, 0x30, 0x2F, 0x72, 0x56, 0x69, 0x69, 0x7A, 0x7A, 0x31, 0x77, 0x54, 0x61, 0x5A, 0x51, 0x6D, 0x43, 0x58, 0x63, 0x49, 0x2F, 0x6D, 0x34, 0x57, 0x45, 0x45, 0x49, 0x63, 0x62, 0x39, 0x50, 0x75, 0x49, 0x53, 0x67, ++ 0x6A, 0x77, 0x42, 0x55, 0x46, 0x66, 0x79, 0x52, 0x62, 0x56, 0x69, 0x6E, 0x6C, 0x6A, 0x76, 0x72, 0x53, 0x35, 0x59, 0x6E, 0x7A, 0x57, 0x75, 0x69, 0x6F, 0x59, 0x61, 0x73, 0x0A, 0x44, 0x58, 0x78, 0x55, 0x35, 0x6D, 0x5A, 0x4D, 0x5A, 0x6C, 0x2B, ++ 0x51, 0x76, 0x69, 0x47, 0x61, 0x41, 0x6B, 0x59, 0x74, 0x35, 0x49, 0x50, 0x43, 0x67, 0x4C, 0x6E, 0x50, 0x53, 0x7A, 0x37, 0x6F, 0x66, 0x7A, 0x77, 0x42, 0x37, 0x49, 0x39, 0x65, 0x7A, 0x58, 0x2F, 0x53, 0x4B, 0x45, 0x49, 0x42, 0x6C, 0x59, 0x72, ++ 0x69, 0x6C, 0x7A, 0x30, 0x51, 0x49, 0x58, 0x33, 0x32, 0x6E, 0x52, 0x7A, 0x46, 0x4E, 0x4B, 0x48, 0x73, 0x4C, 0x41, 0x34, 0x4B, 0x55, 0x69, 0x77, 0x53, 0x0A, 0x56, 0x58, 0x41, 0x6B, 0x50, 0x63, 0x76, 0x43, 0x46, 0x44, 0x56, 0x44, 0x58, 0x53, ++ 0x64, 0x4F, 0x76, 0x73, 0x43, 0x39, 0x71, 0x6E, 0x79, 0x57, 0x35, 0x2F, 0x79, 0x65, 0x59, 0x61, 0x31, 0x45, 0x30, 0x77, 0x43, 0x58, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, 0x59, 0x7A, 0x42, 0x68, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, ++ 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x51, 0x47, 0x6D, 0x70, 0x73, 0x66, 0x55, 0x33, 0x33, 0x78, 0x39, 0x61, 0x54, 0x49, 0x0A, 0x30, 0x34, 0x59, 0x2B, 0x6F, 0x58, 0x4E, 0x5A, 0x74, 0x50, 0x64, 0x45, 0x49, 0x54, 0x41, 0x50, 0x42, ++ 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x49, 0x77, 0x51, 0x59, 0x4D, 0x42, 0x61, 0x41, 0x46, 0x41, 0x61, 0x61, 0x6D, ++ 0x78, 0x39, 0x54, 0x66, 0x66, 0x48, 0x31, 0x70, 0x4D, 0x6A, 0x54, 0x68, 0x6A, 0x36, 0x68, 0x63, 0x31, 0x6D, 0x30, 0x0A, 0x39, 0x30, 0x51, 0x68, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, ++ 0x41, 0x77, 0x49, 0x42, 0x42, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x67, 0x45, 0x41, 0x71, 0x67, 0x56, 0x75, 0x74, 0x74, 0x30, 0x56, ++ 0x79, 0x62, 0x2B, 0x7A, 0x78, 0x69, 0x44, 0x32, 0x42, 0x6B, 0x65, 0x77, 0x68, 0x70, 0x4D, 0x6C, 0x0A, 0x30, 0x34, 0x32, 0x35, 0x79, 0x41, 0x41, 0x2F, 0x6C, 0x2F, 0x56, 0x53, 0x4A, 0x34, 0x68, 0x78, 0x79, 0x58, 0x54, 0x39, 0x36, 0x38, 0x70, ++ 0x6B, 0x32, 0x31, 0x76, 0x76, 0x48, 0x6C, 0x32, 0x36, 0x76, 0x39, 0x48, 0x72, 0x37, 0x6C, 0x78, 0x70, 0x75, 0x68, 0x62, 0x49, 0x38, 0x37, 0x6D, 0x50, 0x30, 0x7A, 0x59, 0x75, 0x51, 0x45, 0x6B, 0x48, 0x44, 0x56, 0x6E, 0x65, 0x69, 0x78, 0x43, ++ 0x77, 0x53, 0x51, 0x58, 0x69, 0x2F, 0x35, 0x45, 0x2F, 0x53, 0x37, 0x66, 0x64, 0x0A, 0x41, 0x6F, 0x37, 0x34, 0x67, 0x53, 0x68, 0x63, 0x7A, 0x4E, 0x78, 0x74, 0x72, 0x31, 0x38, 0x55, 0x6E, 0x48, 0x31, 0x59, 0x65, 0x41, 0x33, 0x32, 0x67, 0x41, ++ 0x6D, 0x35, 0x36, 0x51, 0x36, 0x58, 0x4B, 0x52, 0x6D, 0x34, 0x74, 0x2B, 0x76, 0x34, 0x46, 0x73, 0x74, 0x56, 0x45, 0x75, 0x54, 0x47, 0x66, 0x62, 0x76, 0x45, 0x37, 0x50, 0x69, 0x31, 0x48, 0x45, 0x34, 0x2B, 0x5A, 0x37, 0x2F, 0x46, 0x58, 0x78, ++ 0x74, 0x74, 0x62, 0x55, 0x63, 0x6F, 0x71, 0x67, 0x52, 0x59, 0x0A, 0x59, 0x64, 0x5A, 0x32, 0x76, 0x79, 0x4A, 0x2F, 0x30, 0x41, 0x64, 0x71, 0x70, 0x32, 0x52, 0x54, 0x38, 0x4A, 0x65, 0x4E, 0x6E, 0x59, 0x41, 0x2F, 0x75, 0x38, 0x45, 0x48, 0x32, ++ 0x32, 0x57, 0x76, 0x35, 0x70, 0x73, 0x79, 0x6D, 0x73, 0x4E, 0x55, 0x6B, 0x38, 0x51, 0x63, 0x43, 0x4D, 0x4E, 0x45, 0x2B, 0x33, 0x74, 0x6A, 0x45, 0x55, 0x50, 0x52, 0x61, 0x68, 0x70, 0x68, 0x61, 0x6E, 0x6C, 0x74, 0x6B, 0x45, 0x38, 0x70, 0x6A, ++ 0x6B, 0x63, 0x46, 0x77, 0x52, 0x4A, 0x70, 0x0A, 0x61, 0x64, 0x62, 0x47, 0x4E, 0x6A, 0x48, 0x68, 0x2F, 0x50, 0x71, 0x41, 0x75, 0x6C, 0x78, 0x50, 0x78, 0x4F, 0x75, 0x33, 0x4D, 0x71, 0x7A, 0x34, 0x64, 0x57, 0x45, 0x58, 0x31, 0x78, 0x41, 0x5A, ++ 0x75, 0x66, 0x48, 0x53, 0x43, 0x65, 0x39, 0x36, 0x51, 0x70, 0x31, 0x62, 0x57, 0x67, 0x76, 0x55, 0x78, 0x70, 0x56, 0x4F, 0x4B, 0x73, 0x37, 0x2F, 0x42, 0x39, 0x64, 0x50, 0x66, 0x68, 0x67, 0x47, 0x69, 0x50, 0x45, 0x5A, 0x74, 0x64, 0x6D, 0x59, ++ 0x75, 0x36, 0x35, 0x78, 0x0A, 0x78, 0x42, 0x7A, 0x6E, 0x64, 0x46, 0x6C, 0x59, 0x37, 0x77, 0x79, 0x4A, 0x7A, 0x34, 0x73, 0x66, 0x64, 0x5A, 0x4D, 0x61, 0x42, 0x42, 0x53, 0x53, 0x53, 0x46, 0x43, 0x70, 0x36, 0x31, 0x63, 0x70, 0x41, 0x42, 0x62, ++ 0x6A, 0x4E, 0x68, 0x7A, 0x49, 0x2B, 0x4C, 0x2F, 0x77, 0x4D, 0x39, 0x56, 0x42, 0x44, 0x38, 0x54, 0x4D, 0x50, 0x4E, 0x33, 0x70, 0x4D, 0x30, 0x4D, 0x42, 0x6B, 0x52, 0x41, 0x72, 0x48, 0x74, 0x47, 0x35, 0x58, 0x63, 0x30, 0x79, 0x47, 0x59, 0x75, ++ 0x50, 0x0A, 0x6A, 0x43, 0x42, 0x33, 0x31, 0x79, 0x4C, 0x45, 0x51, 0x74, 0x79, 0x45, 0x46, 0x70, 0x73, 0x6C, 0x62, 0x65, 0x69, 0x30, 0x56, 0x58, 0x46, 0x2F, 0x73, 0x48, 0x79, 0x7A, 0x30, 0x33, 0x46, 0x4A, 0x75, 0x63, 0x39, 0x53, 0x70, 0x41, ++ 0x51, 0x2F, 0x33, 0x44, 0x32, 0x67, 0x75, 0x36, 0x38, 0x7A, 0x6E, 0x67, 0x6F, 0x77, 0x59, 0x49, 0x37, 0x62, 0x6E, 0x56, 0x32, 0x55, 0x71, 0x4C, 0x31, 0x67, 0x35, 0x32, 0x4B, 0x41, 0x64, 0x6F, 0x47, 0x44, 0x44, 0x49, 0x7A, 0x4D, 0x0A, 0x4D, ++ 0x45, 0x5A, 0x4A, 0x34, 0x67, 0x7A, 0x53, 0x71, 0x4B, 0x2F, 0x72, 0x59, 0x58, 0x48, 0x76, 0x35, 0x79, 0x4A, 0x69, 0x71, 0x66, 0x64, 0x63, 0x5A, 0x47, 0x79, 0x66, 0x46, 0x6F, 0x78, 0x6E, 0x4E, 0x69, 0x64, 0x46, 0x39, 0x51, 0x6C, 0x37, 0x76, ++ 0x2F, 0x59, 0x51, 0x43, 0x76, 0x47, 0x77, 0x6A, 0x56, 0x52, 0x44, 0x6A, 0x41, 0x53, 0x36, 0x6F, 0x7A, 0x2F, 0x76, 0x34, 0x6A, 0x58, 0x48, 0x2B, 0x58, 0x54, 0x67, 0x62, 0x7A, 0x52, 0x42, 0x30, 0x4C, 0x39, 0x7A, 0x0A, 0x5A, 0x56, 0x63, 0x67, ++ 0x2B, 0x5A, 0x74, 0x6E, 0x65, 0x6D, 0x5A, 0x6F, 0x4A, 0x45, 0x36, 0x41, 0x5A, 0x62, 0x30, 0x51, 0x6D, 0x51, 0x5A, 0x5A, 0x38, 0x6D, 0x57, 0x76, 0x75, 0x4D, 0x5A, 0x48, 0x75, 0x2F, 0x32, 0x51, 0x65, 0x49, 0x74, 0x42, 0x63, 0x79, 0x36, 0x76, ++ 0x56, 0x52, 0x2F, 0x63, 0x4F, 0x35, 0x4A, 0x79, 0x62, 0x6F, 0x54, 0x54, 0x30, 0x47, 0x46, 0x4D, 0x44, 0x63, 0x78, 0x32, 0x56, 0x2B, 0x49, 0x74, 0x68, 0x53, 0x49, 0x56, 0x4E, 0x67, 0x33, 0x72, 0x0A, 0x41, 0x5A, 0x33, 0x72, 0x32, 0x4F, 0x76, ++ 0x45, 0x68, 0x4A, 0x6E, 0x37, 0x77, 0x41, 0x7A, 0x4D, 0x4D, 0x75, 0x6A, 0x6A, 0x64, 0x39, 0x71, 0x44, 0x52, 0x49, 0x75, 0x65, 0x56, 0x53, 0x6A, 0x41, 0x69, 0x31, 0x6A, 0x54, 0x6B, 0x44, 0x35, 0x4F, 0x47, 0x77, 0x44, 0x78, 0x46, 0x61, 0x32, ++ 0x44, 0x4B, 0x35, 0x6F, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x48, 0x41, 0x52, 0x49, 0x43, 0x41, 0x20, ++ 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x32, 0x31, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, ++ 0x46, 0x70, 0x44, 0x43, 0x43, 0x41, 0x34, 0x79, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x4F, 0x63, 0x71, 0x54, 0x48, 0x4F, 0x39, 0x44, 0x38, 0x38, 0x61, 0x4F, 0x6B, 0x38, 0x66, 0x30, 0x5A, 0x49, 0x6B, 0x34, 0x66, 0x6A, 0x41, ++ 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x42, 0x73, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0A, 0x45, 0x77, 0x4A, 0x48, 0x55, 0x6A, ++ 0x45, 0x33, 0x4D, 0x44, 0x55, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x75, 0x53, 0x47, 0x56, 0x73, 0x62, 0x47, 0x56, 0x75, 0x61, 0x57, 0x4D, 0x67, 0x51, 0x57, 0x4E, 0x68, 0x5A, 0x47, 0x56, 0x74, 0x61, 0x57, 0x4D, 0x67, 0x59, 0x57, ++ 0x35, 0x6B, 0x49, 0x46, 0x4A, 0x6C, 0x63, 0x32, 0x56, 0x68, 0x63, 0x6D, 0x4E, 0x6F, 0x49, 0x45, 0x6C, 0x75, 0x63, 0x33, 0x52, 0x70, 0x64, 0x48, 0x56, 0x30, 0x61, 0x57, 0x39, 0x75, 0x0A, 0x63, 0x79, 0x42, 0x44, 0x51, 0x54, 0x45, 0x6B, 0x4D, ++ 0x43, 0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x62, 0x53, 0x45, 0x46, 0x53, 0x53, 0x55, 0x4E, 0x42, 0x49, 0x46, 0x52, 0x4D, 0x55, 0x79, 0x42, 0x53, 0x55, 0x30, 0x45, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, ++ 0x53, 0x41, 0x79, 0x4D, 0x44, 0x49, 0x78, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x49, 0x78, 0x4D, 0x44, 0x49, 0x78, 0x4F, 0x54, 0x45, 0x77, 0x4E, 0x54, 0x55, 0x7A, 0x0A, 0x4F, 0x46, 0x6F, 0x58, 0x44, 0x54, 0x51, 0x31, 0x4D, 0x44, 0x49, 0x78, ++ 0x4D, 0x7A, 0x45, 0x77, 0x4E, 0x54, 0x55, 0x7A, 0x4E, 0x31, 0x6F, 0x77, 0x62, 0x44, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x52, 0x31, 0x49, 0x78, 0x4E, 0x7A, 0x41, 0x31, 0x42, 0x67, 0x4E, 0x56, ++ 0x42, 0x41, 0x6F, 0x4D, 0x4C, 0x6B, 0x68, 0x6C, 0x62, 0x47, 0x78, 0x6C, 0x62, 0x6D, 0x6C, 0x6A, 0x49, 0x45, 0x46, 0x6A, 0x59, 0x57, 0x52, 0x6C, 0x0A, 0x62, 0x57, 0x6C, 0x6A, 0x49, 0x47, 0x46, 0x75, 0x5A, 0x43, 0x42, 0x53, 0x5A, 0x58, 0x4E, ++ 0x6C, 0x59, 0x58, 0x4A, 0x6A, 0x61, 0x43, 0x42, 0x4A, 0x62, 0x6E, 0x4E, 0x30, 0x61, 0x58, 0x52, 0x31, 0x64, 0x47, 0x6C, 0x76, 0x62, 0x6E, 0x4D, 0x67, 0x51, 0x30, 0x45, 0x78, 0x4A, 0x44, 0x41, 0x69, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, ++ 0x4D, 0x47, 0x30, 0x68, 0x42, 0x55, 0x6B, 0x6C, 0x44, 0x51, 0x53, 0x42, 0x55, 0x54, 0x46, 0x4D, 0x67, 0x55, 0x6C, 0x4E, 0x42, 0x0A, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x4D, 0x6A, 0x41, 0x79, 0x4D, 0x54, ++ 0x43, 0x43, 0x41, 0x69, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x67, 0x6F, 0x43, 0x67, 0x67, ++ 0x49, 0x42, 0x41, 0x49, 0x76, 0x43, 0x35, 0x36, 0x39, 0x6C, 0x6D, 0x77, 0x56, 0x6E, 0x6C, 0x73, 0x6B, 0x4E, 0x0A, 0x4A, 0x4C, 0x6E, 0x51, 0x44, 0x6D, 0x54, 0x38, 0x7A, 0x75, 0x49, 0x6B, 0x47, 0x43, 0x79, 0x45, 0x66, 0x33, 0x64, 0x52, 0x79, ++ 0x77, 0x51, 0x52, 0x4E, 0x72, 0x68, 0x65, 0x37, 0x57, 0x6C, 0x78, 0x70, 0x35, 0x37, 0x6B, 0x4A, 0x51, 0x6D, 0x58, 0x5A, 0x38, 0x46, 0x48, 0x77, 0x73, 0x2B, 0x52, 0x46, 0x6A, 0x5A, 0x69, 0x50, 0x54, 0x67, 0x45, 0x34, 0x56, 0x47, 0x43, 0x2F, ++ 0x36, 0x7A, 0x53, 0x74, 0x47, 0x6E, 0x64, 0x4C, 0x75, 0x77, 0x52, 0x6F, 0x30, 0x58, 0x75, 0x0A, 0x61, 0x32, 0x73, 0x37, 0x54, 0x4C, 0x2B, 0x4D, 0x6A, 0x61, 0x51, 0x65, 0x6E, 0x52, 0x47, 0x35, 0x36, 0x54, 0x6A, 0x35, 0x65, 0x67, 0x34, 0x4D, ++ 0x6D, 0x4F, 0x49, 0x6A, 0x48, 0x64, 0x46, 0x4F, 0x59, 0x39, 0x54, 0x6E, 0x75, 0x45, 0x46, 0x45, 0x2B, 0x32, 0x75, 0x76, 0x61, 0x39, 0x6F, 0x66, 0x30, 0x38, 0x57, 0x52, 0x69, 0x46, 0x75, 0x6B, 0x69, 0x5A, 0x4C, 0x52, 0x67, 0x65, 0x61, 0x4D, ++ 0x4F, 0x56, 0x69, 0x67, 0x31, 0x6D, 0x6C, 0x44, 0x71, 0x61, 0x32, 0x59, 0x0A, 0x55, 0x6C, 0x68, 0x75, 0x32, 0x77, 0x72, 0x37, 0x61, 0x38, 0x39, 0x6F, 0x2B, 0x75, 0x4F, 0x6B, 0x58, 0x6A, 0x70, 0x46, 0x63, 0x35, 0x67, 0x48, 0x36, 0x6C, 0x38, ++ 0x43, 0x63, 0x74, 0x34, 0x4D, 0x70, 0x62, 0x4F, 0x66, 0x72, 0x71, 0x6B, 0x64, 0x74, 0x78, 0x32, 0x7A, 0x2F, 0x49, 0x70, 0x5A, 0x35, 0x32, 0x35, 0x79, 0x5A, 0x61, 0x33, 0x31, 0x4D, 0x4A, 0x51, 0x6A, 0x42, 0x2F, 0x4F, 0x43, 0x46, 0x6B, 0x73, ++ 0x31, 0x6D, 0x4A, 0x78, 0x54, 0x75, 0x79, 0x2F, 0x4B, 0x0A, 0x35, 0x46, 0x72, 0x5A, 0x78, 0x34, 0x30, 0x64, 0x2F, 0x4A, 0x69, 0x5A, 0x2B, 0x79, 0x79, 0x6B, 0x67, 0x6D, 0x76, 0x77, 0x4B, 0x68, 0x2B, 0x4F, 0x43, 0x31, 0x39, 0x78, 0x58, 0x46, ++ 0x79, 0x75, 0x51, 0x6E, 0x73, 0x70, 0x69, 0x59, 0x48, 0x4C, 0x41, 0x36, 0x4F, 0x5A, 0x79, 0x6F, 0x69, 0x65, 0x43, 0x30, 0x41, 0x4A, 0x51, 0x54, 0x50, 0x62, 0x35, 0x6C, 0x68, 0x36, 0x2F, 0x61, 0x36, 0x5A, 0x63, 0x4D, 0x42, 0x61, 0x44, 0x39, ++ 0x59, 0x54, 0x68, 0x6E, 0x45, 0x76, 0x0A, 0x64, 0x6D, 0x6E, 0x38, 0x6B, 0x4E, 0x33, 0x62, 0x4C, 0x57, 0x37, 0x52, 0x38, 0x70, 0x76, 0x31, 0x47, 0x6D, 0x75, 0x65, 0x62, 0x78, 0x57, 0x4D, 0x65, 0x76, 0x42, 0x4C, 0x4B, 0x4B, 0x41, 0x69, 0x4F, ++ 0x49, 0x41, 0x6B, 0x62, 0x44, 0x61, 0x6B, 0x4F, 0x2F, 0x49, 0x77, 0x6B, 0x66, 0x4E, 0x34, 0x45, 0x38, 0x2F, 0x42, 0x50, 0x7A, 0x57, 0x72, 0x38, 0x52, 0x30, 0x52, 0x49, 0x37, 0x56, 0x44, 0x49, 0x70, 0x34, 0x42, 0x6B, 0x72, 0x63, 0x59, 0x41, ++ 0x75, 0x55, 0x52, 0x0A, 0x30, 0x59, 0x4C, 0x62, 0x46, 0x51, 0x44, 0x4D, 0x59, 0x54, 0x66, 0x42, 0x4B, 0x6E, 0x79, 0x61, 0x34, 0x64, 0x43, 0x36, 0x73, 0x31, 0x42, 0x47, 0x37, 0x6F, 0x4B, 0x73, 0x6E, 0x54, 0x48, 0x34, 0x2B, 0x79, 0x50, 0x69, ++ 0x41, 0x77, 0x42, 0x49, 0x63, 0x4B, 0x4D, 0x4A, 0x4A, 0x6E, 0x6B, 0x56, 0x55, 0x32, 0x44, 0x7A, 0x4F, 0x46, 0x79, 0x74, 0x4F, 0x4F, 0x71, 0x42, 0x41, 0x47, 0x4D, 0x55, 0x75, 0x54, 0x4E, 0x65, 0x33, 0x51, 0x76, 0x62, 0x6F, 0x45, 0x55, 0x48, ++ 0x0A, 0x47, 0x6A, 0x4D, 0x4A, 0x2B, 0x45, 0x32, 0x30, 0x70, 0x77, 0x4B, 0x6D, 0x61, 0x66, 0x54, 0x43, 0x57, 0x51, 0x57, 0x49, 0x5A, 0x59, 0x56, 0x57, 0x72, 0x6B, 0x76, 0x4C, 0x34, 0x4E, 0x34, 0x38, 0x66, 0x53, 0x30, 0x61, 0x79, 0x4F, 0x6E, ++ 0x37, 0x48, 0x36, 0x4E, 0x68, 0x53, 0x74, 0x59, 0x71, 0x45, 0x36, 0x31, 0x33, 0x54, 0x42, 0x6F, 0x59, 0x6D, 0x35, 0x45, 0x50, 0x57, 0x4E, 0x67, 0x47, 0x56, 0x4D, 0x57, 0x58, 0x2B, 0x4B, 0x6F, 0x2F, 0x49, 0x49, 0x71, 0x6D, 0x0A, 0x68, 0x61, ++ 0x5A, 0x33, 0x39, 0x71, 0x62, 0x38, 0x48, 0x4F, 0x4C, 0x75, 0x62, 0x70, 0x51, 0x7A, 0x4B, 0x6F, 0x4E, 0x51, 0x68, 0x41, 0x72, 0x6C, 0x54, 0x34, 0x62, 0x34, 0x55, 0x45, 0x56, 0x34, 0x41, 0x49, 0x48, 0x72, 0x57, 0x32, 0x6A, 0x6A, 0x4A, 0x6F, ++ 0x33, 0x4D, 0x65, 0x31, 0x78, 0x52, 0x39, 0x42, 0x51, 0x73, 0x51, 0x4C, 0x34, 0x61, 0x59, 0x42, 0x31, 0x36, 0x63, 0x6D, 0x45, 0x64, 0x48, 0x32, 0x4D, 0x74, 0x69, 0x4B, 0x72, 0x4F, 0x6F, 0x6B, 0x57, 0x51, 0x0A, 0x43, 0x50, 0x78, 0x72, 0x76, ++ 0x72, 0x4E, 0x51, 0x4B, 0x6C, 0x72, 0x39, 0x71, 0x45, 0x67, 0x59, 0x52, 0x74, 0x61, 0x51, 0x51, 0x4A, 0x4B, 0x51, 0x43, 0x6F, 0x52, 0x65, 0x61, 0x44, 0x48, 0x34, 0x36, 0x2B, 0x30, 0x4E, 0x30, 0x78, 0x33, 0x47, 0x66, 0x5A, 0x6B, 0x59, 0x56, ++ 0x56, 0x59, 0x6E, 0x5A, 0x53, 0x36, 0x4E, 0x52, 0x63, 0x55, 0x6B, 0x37, 0x4D, 0x37, 0x6A, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, 0x51, 0x6A, 0x42, 0x41, 0x4D, 0x41, 0x38, 0x47, 0x0A, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, ++ 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x46, 0x41, 0x70, 0x49, 0x49, 0x36, 0x5A, 0x67, 0x70, 0x4A, 0x49, 0x4B, 0x4D, 0x2B, 0x71, 0x54, ++ 0x57, 0x38, 0x56, 0x58, 0x36, 0x69, 0x56, 0x4E, 0x76, 0x52, 0x4C, 0x75, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x0A, 0x41, 0x77, 0x49, 0x42, 0x68, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, ++ 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x67, 0x45, 0x41, 0x50, 0x70, 0x42, 0x49, 0x71, 0x6D, 0x35, 0x69, 0x46, 0x53, 0x56, 0x6D, 0x65, 0x77, 0x7A, 0x56, 0x6A, 0x49, 0x75, ++ 0x4A, 0x6E, 0x64, 0x66, 0x74, 0x54, 0x67, 0x66, 0x76, 0x6E, 0x4E, 0x41, 0x55, 0x58, 0x31, 0x35, 0x51, 0x76, 0x57, 0x69, 0x57, 0x6B, 0x4B, 0x51, 0x55, 0x0A, 0x45, 0x61, 0x70, 0x6F, 0x62, 0x51, 0x6B, 0x31, 0x4F, 0x55, 0x41, 0x4A, 0x32, 0x76, ++ 0x51, 0x4A, 0x4C, 0x44, 0x53, 0x6C, 0x65, 0x31, 0x6D, 0x45, 0x53, 0x53, 0x6D, 0x58, 0x64, 0x4D, 0x67, 0x48, 0x48, 0x6B, 0x64, 0x74, 0x38, 0x73, 0x34, 0x63, 0x55, 0x43, 0x62, 0x6A, 0x6E, 0x6A, 0x31, 0x41, 0x55, 0x7A, 0x2F, 0x33, 0x66, 0x35, ++ 0x5A, 0x32, 0x45, 0x4D, 0x56, 0x47, 0x70, 0x64, 0x41, 0x67, 0x53, 0x31, 0x44, 0x30, 0x4E, 0x54, 0x73, 0x59, 0x39, 0x46, 0x56, 0x71, 0x0A, 0x51, 0x52, 0x74, 0x48, 0x42, 0x6D, 0x67, 0x38, 0x75, 0x77, 0x6B, 0x49, 0x59, 0x74, 0x6C, 0x66, 0x56, ++ 0x55, 0x4B, 0x71, 0x72, 0x46, 0x4F, 0x46, 0x72, 0x4A, 0x56, 0x57, 0x4E, 0x6C, 0x61, 0x72, 0x35, 0x41, 0x57, 0x4D, 0x78, 0x61, 0x6A, 0x61, 0x48, 0x36, 0x4E, 0x70, 0x76, 0x56, 0x4D, 0x50, 0x78, 0x50, 0x2F, 0x63, 0x79, 0x75, 0x4E, 0x2B, 0x38, ++ 0x6B, 0x79, 0x49, 0x68, 0x6B, 0x64, 0x47, 0x47, 0x76, 0x4D, 0x41, 0x39, 0x59, 0x43, 0x52, 0x6F, 0x74, 0x78, 0x44, 0x0A, 0x51, 0x70, 0x53, 0x62, 0x49, 0x50, 0x44, 0x52, 0x7A, 0x62, 0x4C, 0x72, 0x4C, 0x46, 0x50, 0x43, 0x55, 0x33, 0x68, 0x4B, ++ 0x54, 0x77, 0x53, 0x55, 0x51, 0x5A, 0x71, 0x50, 0x4A, 0x7A, 0x4C, 0x42, 0x35, 0x55, 0x6B, 0x5A, 0x76, 0x2F, 0x48, 0x79, 0x77, 0x6F, 0x75, 0x6F, 0x43, 0x6A, 0x6B, 0x78, 0x4B, 0x4C, 0x52, 0x39, 0x59, 0x6A, 0x59, 0x73, 0x54, 0x65, 0x77, 0x66, ++ 0x4D, 0x37, 0x5A, 0x2B, 0x64, 0x32, 0x31, 0x2B, 0x55, 0x50, 0x43, 0x66, 0x44, 0x74, 0x63, 0x52, 0x0A, 0x6A, 0x38, 0x38, 0x59, 0x78, 0x65, 0x4D, 0x6E, 0x2F, 0x69, 0x62, 0x76, 0x42, 0x5A, 0x33, 0x50, 0x7A, 0x7A, 0x66, 0x46, 0x30, 0x48, 0x76, ++ 0x61, 0x4F, 0x37, 0x41, 0x57, 0x68, 0x41, 0x77, 0x36, 0x6B, 0x39, 0x61, 0x2B, 0x46, 0x39, 0x73, 0x50, 0x50, 0x67, 0x34, 0x5A, 0x65, 0x41, 0x6E, 0x48, 0x71, 0x51, 0x4A, 0x79, 0x49, 0x6B, 0x76, 0x33, 0x4E, 0x33, 0x61, 0x36, 0x64, 0x63, 0x53, ++ 0x46, 0x41, 0x31, 0x70, 0x6A, 0x31, 0x62, 0x46, 0x31, 0x42, 0x63, 0x4B, 0x35, 0x0A, 0x76, 0x5A, 0x53, 0x74, 0x6A, 0x42, 0x57, 0x5A, 0x70, 0x35, 0x4E, 0x39, 0x39, 0x73, 0x58, 0x7A, 0x71, 0x6E, 0x54, 0x50, 0x42, 0x49, 0x57, 0x55, 0x6D, 0x41, ++ 0x44, 0x30, 0x34, 0x76, 0x6E, 0x4B, 0x4A, 0x47, 0x57, 0x2F, 0x34, 0x47, 0x4B, 0x76, 0x79, 0x4D, 0x58, 0x36, 0x73, 0x73, 0x6D, 0x65, 0x56, 0x6B, 0x6A, 0x61, 0x65, 0x66, 0x32, 0x57, 0x64, 0x68, 0x57, 0x2B, 0x6F, 0x34, 0x35, 0x57, 0x78, 0x4C, ++ 0x4D, 0x30, 0x2F, 0x4C, 0x35, 0x48, 0x39, 0x4D, 0x47, 0x30, 0x0A, 0x71, 0x50, 0x7A, 0x56, 0x4D, 0x49, 0x68, 0x6F, 0x37, 0x73, 0x75, 0x75, 0x79, 0x57, 0x50, 0x45, 0x64, 0x72, 0x36, 0x73, 0x4F, 0x42, 0x6A, 0x68, 0x58, 0x6C, 0x7A, 0x50, 0x72, ++ 0x6A, 0x6F, 0x69, 0x55, 0x65, 0x76, 0x52, 0x69, 0x37, 0x50, 0x7A, 0x4B, 0x7A, 0x4D, 0x48, 0x56, 0x49, 0x66, 0x36, 0x74, 0x4C, 0x49, 0x54, 0x65, 0x37, 0x70, 0x54, 0x42, 0x47, 0x49, 0x42, 0x6E, 0x66, 0x48, 0x41, 0x54, 0x2B, 0x37, 0x68, 0x4F, ++ 0x74, 0x53, 0x4C, 0x49, 0x42, 0x44, 0x36, 0x0A, 0x41, 0x6C, 0x66, 0x6D, 0x37, 0x38, 0x45, 0x4C, 0x74, 0x35, 0x42, 0x47, 0x6E, 0x42, 0x6B, 0x70, 0x6A, 0x4E, 0x78, 0x76, 0x6F, 0x45, 0x70, 0x70, 0x61, 0x5A, 0x53, 0x33, 0x4A, 0x47, 0x57, 0x67, ++ 0x2F, 0x36, 0x77, 0x2F, 0x7A, 0x67, 0x48, 0x37, 0x49, 0x53, 0x37, 0x39, 0x61, 0x50, 0x69, 0x62, 0x38, 0x71, 0x58, 0x50, 0x4D, 0x54, 0x68, 0x63, 0x46, 0x61, 0x72, 0x6D, 0x6C, 0x77, 0x44, 0x42, 0x33, 0x31, 0x71, 0x6C, 0x70, 0x7A, 0x6D, 0x71, ++ 0x36, 0x59, 0x52, 0x2F, 0x0A, 0x50, 0x46, 0x47, 0x6F, 0x4F, 0x74, 0x6D, 0x55, 0x57, 0x34, 0x79, 0x2F, 0x54, 0x77, 0x68, 0x78, 0x35, 0x64, 0x75, 0x6F, 0x58, 0x4E, 0x54, 0x53, 0x70, 0x76, 0x34, 0x41, 0x6F, 0x38, 0x59, 0x57, 0x78, 0x77, 0x2F, ++ 0x6F, 0x67, 0x4D, 0x34, 0x63, 0x4B, 0x47, 0x52, 0x30, 0x47, 0x51, 0x6A, 0x54, 0x51, 0x75, 0x50, 0x4F, 0x41, 0x46, 0x31, 0x2F, 0x73, 0x64, 0x77, 0x54, 0x73, 0x4F, 0x45, 0x46, 0x79, 0x39, 0x45, 0x67, 0x71, 0x6F, 0x5A, 0x30, 0x6E, 0x6A, 0x6E, ++ 0x6E, 0x0A, 0x6B, 0x66, 0x33, 0x2F, 0x57, 0x39, 0x62, 0x33, 0x72, 0x61, 0x59, 0x76, 0x41, 0x77, 0x74, 0x74, 0x34, 0x31, 0x64, 0x55, 0x36, 0x33, 0x5A, 0x54, 0x47, 0x49, 0x30, 0x52, 0x6D, 0x4C, 0x6F, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x48, 0x41, 0x52, 0x49, 0x43, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, ++ 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x32, 0x31, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, ++ 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x56, 0x44, 0x43, 0x43, 0x41, 0x64, 0x75, 0x67, 0x41, 0x77, ++ 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x5A, 0x33, 0x53, 0x64, 0x6A, 0x58, 0x66, 0x59, 0x4F, 0x32, 0x72, 0x62, 0x49, 0x76, 0x54, 0x2F, 0x57, 0x65, 0x4B, 0x2F, 0x7A, 0x6A, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, ++ 0x51, 0x44, 0x41, 0x7A, 0x42, 0x73, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x48, 0x0A, 0x55, 0x6A, 0x45, 0x33, 0x4D, 0x44, 0x55, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x75, 0x53, ++ 0x47, 0x56, 0x73, 0x62, 0x47, 0x56, 0x75, 0x61, 0x57, 0x4D, 0x67, 0x51, 0x57, 0x4E, 0x68, 0x5A, 0x47, 0x56, 0x74, 0x61, 0x57, 0x4D, 0x67, 0x59, 0x57, 0x35, 0x6B, 0x49, 0x46, 0x4A, 0x6C, 0x63, 0x32, 0x56, 0x68, 0x63, 0x6D, 0x4E, 0x6F, 0x49, ++ 0x45, 0x6C, 0x75, 0x63, 0x33, 0x52, 0x70, 0x64, 0x48, 0x56, 0x30, 0x61, 0x57, 0x39, 0x75, 0x63, 0x79, 0x42, 0x44, 0x0A, 0x51, 0x54, 0x45, 0x6B, 0x4D, 0x43, 0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x62, 0x53, 0x45, 0x46, 0x53, ++ 0x53, 0x55, 0x4E, 0x42, 0x49, 0x46, 0x52, 0x4D, 0x55, 0x79, 0x42, 0x46, 0x51, 0x30, 0x4D, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x53, 0x41, 0x79, 0x4D, 0x44, 0x49, 0x78, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x49, 0x78, ++ 0x4D, 0x44, 0x49, 0x78, 0x4F, 0x54, 0x45, 0x78, 0x4D, 0x44, 0x45, 0x78, 0x4D, 0x46, 0x6F, 0x58, 0x0A, 0x44, 0x54, 0x51, 0x31, 0x4D, 0x44, 0x49, 0x78, 0x4D, 0x7A, 0x45, 0x78, 0x4D, 0x44, 0x45, 0x77, 0x4F, 0x56, 0x6F, 0x77, 0x62, 0x44, 0x45, ++ 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x52, 0x31, 0x49, 0x78, 0x4E, 0x7A, 0x41, 0x31, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x4C, 0x6B, 0x68, 0x6C, 0x62, 0x47, 0x78, 0x6C, 0x62, 0x6D, 0x6C, ++ 0x6A, 0x49, 0x45, 0x46, 0x6A, 0x59, 0x57, 0x52, 0x6C, 0x62, 0x57, 0x6C, 0x6A, 0x0A, 0x49, 0x47, 0x46, 0x75, 0x5A, 0x43, 0x42, 0x53, 0x5A, 0x58, 0x4E, 0x6C, 0x59, 0x58, 0x4A, 0x6A, 0x61, 0x43, 0x42, 0x4A, 0x62, 0x6E, 0x4E, 0x30, 0x61, 0x58, ++ 0x52, 0x31, 0x64, 0x47, 0x6C, 0x76, 0x62, 0x6E, 0x4D, 0x67, 0x51, 0x30, 0x45, 0x78, 0x4A, 0x44, 0x41, 0x69, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x47, 0x30, 0x68, 0x42, 0x55, 0x6B, 0x6C, 0x44, 0x51, 0x53, 0x42, 0x55, 0x54, 0x46, ++ 0x4D, 0x67, 0x52, 0x55, 0x4E, 0x44, 0x49, 0x46, 0x4A, 0x76, 0x0A, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x4D, 0x6A, 0x41, 0x79, 0x4D, 0x54, 0x42, 0x32, 0x4D, 0x42, 0x41, 0x47, 0x42, 0x79, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x41, ++ 0x67, 0x45, 0x47, 0x42, 0x53, 0x75, 0x42, 0x42, 0x41, 0x41, 0x69, 0x41, 0x32, 0x49, 0x41, 0x42, 0x44, 0x67, 0x49, 0x2F, 0x72, 0x47, 0x67, 0x6C, 0x74, 0x4A, 0x36, 0x72, 0x4B, 0x39, 0x4A, 0x4F, 0x74, 0x44, 0x41, 0x34, 0x4D, 0x4D, 0x37, 0x4B, ++ 0x4B, 0x72, 0x78, 0x63, 0x6D, 0x31, 0x6C, 0x0A, 0x41, 0x45, 0x65, 0x49, 0x68, 0x50, 0x79, 0x61, 0x4A, 0x6D, 0x75, 0x71, 0x53, 0x37, 0x70, 0x73, 0x42, 0x41, 0x71, 0x49, 0x58, 0x68, 0x66, 0x79, 0x56, 0x59, 0x66, 0x38, 0x4D, 0x4C, 0x41, 0x30, ++ 0x34, 0x6A, 0x52, 0x59, 0x56, 0x78, 0x71, 0x45, 0x55, 0x2B, 0x6B, 0x77, 0x32, 0x61, 0x6E, 0x79, 0x6C, 0x6E, 0x54, 0x44, 0x55, 0x52, 0x39, 0x59, 0x53, 0x54, 0x48, 0x4D, 0x6D, 0x45, 0x35, 0x67, 0x45, 0x59, 0x64, 0x31, 0x30, 0x33, 0x4B, 0x55, ++ 0x6B, 0x45, 0x2B, 0x62, 0x0A, 0x45, 0x43, 0x55, 0x71, 0x71, 0x48, 0x67, 0x74, 0x76, 0x70, 0x42, 0x42, 0x57, 0x4A, 0x41, 0x56, 0x63, 0x71, 0x65, 0x68, 0x74, 0x36, 0x4E, 0x43, 0x4D, 0x45, 0x41, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, ++ 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x79, 0x52, 0x74, 0x54, 0x67, 0x52, 0x4C, 0x2B, 0x42, 0x4E, 0x55, ++ 0x57, 0x0A, 0x30, 0x61, 0x71, 0x38, 0x6D, 0x6D, 0x2B, 0x33, 0x6F, 0x4A, 0x55, 0x5A, 0x62, 0x73, 0x6F, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x47, 0x47, 0x4D, 0x41, ++ 0x6F, 0x47, 0x43, 0x43, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x42, 0x41, 0x4D, 0x44, 0x41, 0x32, 0x63, 0x41, 0x4D, 0x47, 0x51, 0x43, 0x4D, 0x42, 0x48, 0x65, 0x72, 0x76, 0x6A, 0x63, 0x54, 0x6F, 0x69, 0x77, 0x71, 0x66, 0x41, 0x69, 0x0A, 0x72, ++ 0x63, 0x4A, 0x52, 0x51, 0x4F, 0x39, 0x67, 0x63, 0x53, 0x33, 0x75, 0x6A, 0x77, 0x4C, 0x45, 0x58, 0x51, 0x4E, 0x77, 0x53, 0x61, 0x53, 0x53, 0x36, 0x73, 0x55, 0x55, 0x69, 0x48, 0x43, 0x6D, 0x30, 0x77, 0x32, 0x77, 0x71, 0x73, 0x6F, 0x73, 0x51, ++ 0x4A, 0x7A, 0x37, 0x36, 0x59, 0x4A, 0x75, 0x6D, 0x67, 0x49, 0x77, 0x4B, 0x30, 0x65, 0x61, 0x42, 0x38, 0x62, 0x52, 0x77, 0x6F, 0x46, 0x38, 0x79, 0x67, 0x75, 0x57, 0x47, 0x45, 0x45, 0x62, 0x6F, 0x2F, 0x51, 0x77, 0x0A, 0x43, 0x5A, 0x36, 0x31, ++ 0x49, 0x79, 0x67, 0x4E, 0x6E, 0x78, 0x53, 0x32, 0x50, 0x46, 0x4F, 0x69, 0x54, 0x41, 0x5A, 0x70, 0x66, 0x66, 0x70, 0x73, 0x6B, 0x63, 0x59, 0x71, 0x53, 0x55, 0x58, 0x6D, 0x37, 0x4C, 0x63, 0x54, 0x34, 0x54, 0x70, 0x73, 0x0A, 0x2D, 0x2D, 0x2D, ++ 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x41, 0x75, 0x74, 0x6F, 0x72, 0x69, 0x64, 0x61, 0x64, 0x20, 0x64, 0x65, 0x20, 0x43, 0x65, 0x72, ++ 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x63, 0x69, 0x6F, 0x6E, 0x20, 0x46, 0x69, 0x72, 0x6D, 0x61, 0x70, 0x72, 0x6F, 0x66, 0x65, 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x43, 0x49, 0x46, 0x20, 0x41, 0x36, 0x32, 0x36, 0x33, 0x34, 0x30, 0x36, ++ 0x38, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, ++ 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x47, 0x46, 0x44, 0x43, 0x43, 0x41, 0x2F, 0x79, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x49, 0x47, 0x33, 0x44, 0x70, 0x30, 0x76, 0x2B, 0x75, 0x62, 0x48, 0x45, 0x77, ++ 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x77, 0x55, 0x54, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x52, 0x56, 0x4D, 0x78, ++ 0x51, 0x6A, 0x42, 0x41, 0x0A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x4F, 0x55, 0x46, 0x31, 0x64, 0x47, 0x39, 0x79, 0x61, 0x57, 0x52, 0x68, 0x5A, 0x43, 0x42, 0x6B, 0x5A, 0x53, 0x42, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x61, 0x57, 0x5A, ++ 0x70, 0x59, 0x32, 0x46, 0x6A, 0x61, 0x57, 0x39, 0x75, 0x49, 0x45, 0x5A, 0x70, 0x63, 0x6D, 0x31, 0x68, 0x63, 0x48, 0x4A, 0x76, 0x5A, 0x6D, 0x56, 0x7A, 0x61, 0x57, 0x39, 0x75, 0x59, 0x57, 0x77, 0x67, 0x51, 0x30, 0x6C, 0x47, 0x49, 0x45, 0x45, ++ 0x32, 0x0A, 0x4D, 0x6A, 0x59, 0x7A, 0x4E, 0x44, 0x41, 0x32, 0x4F, 0x44, 0x41, 0x65, 0x46, 0x77, 0x30, 0x78, 0x4E, 0x44, 0x41, 0x35, 0x4D, 0x6A, 0x4D, 0x78, 0x4E, 0x54, 0x49, 0x79, 0x4D, 0x44, 0x64, 0x61, 0x46, 0x77, 0x30, 0x7A, 0x4E, 0x6A, ++ 0x41, 0x31, 0x4D, 0x44, 0x55, 0x78, 0x4E, 0x54, 0x49, 0x79, 0x4D, 0x44, 0x64, 0x61, 0x4D, 0x46, 0x45, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x56, 0x54, 0x4D, 0x55, 0x49, 0x77, 0x0A, 0x51, ++ 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x44, 0x6C, 0x42, 0x64, 0x58, 0x52, 0x76, 0x63, 0x6D, 0x6C, 0x6B, 0x59, 0x57, 0x51, 0x67, 0x5A, 0x47, 0x55, 0x67, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6C, 0x6D, 0x61, 0x57, 0x4E, 0x68, 0x59, ++ 0x32, 0x6C, 0x76, 0x62, 0x69, 0x42, 0x47, 0x61, 0x58, 0x4A, 0x74, 0x59, 0x58, 0x42, 0x79, 0x62, 0x32, 0x5A, 0x6C, 0x63, 0x32, 0x6C, 0x76, 0x62, 0x6D, 0x46, 0x73, 0x49, 0x45, 0x4E, 0x4A, 0x52, 0x69, 0x42, 0x42, 0x0A, 0x4E, 0x6A, 0x49, 0x32, ++ 0x4D, 0x7A, 0x51, 0x77, 0x4E, 0x6A, 0x67, 0x77, 0x67, 0x67, 0x49, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x44, 0x77, 0x41, 0x77, ++ 0x67, 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x44, 0x4B, 0x6C, 0x6D, 0x75, 0x4F, 0x36, 0x76, 0x6A, 0x37, 0x38, 0x61, 0x49, 0x31, 0x34, 0x48, 0x39, 0x4D, 0x32, 0x75, 0x44, 0x44, 0x0A, 0x55, 0x74, 0x64, 0x39, 0x74, 0x68, 0x44, ++ 0x49, 0x41, 0x6C, 0x36, 0x7A, 0x51, 0x79, 0x72, 0x45, 0x54, 0x32, 0x71, 0x79, 0x79, 0x68, 0x78, 0x64, 0x4B, 0x4A, 0x70, 0x34, 0x45, 0x52, 0x70, 0x70, 0x57, 0x56, 0x65, 0x76, 0x74, 0x53, 0x42, 0x43, 0x35, 0x49, 0x73, 0x50, 0x35, 0x74, 0x39, ++ 0x62, 0x70, 0x67, 0x4F, 0x53, 0x4C, 0x2F, 0x55, 0x52, 0x35, 0x47, 0x4C, 0x58, 0x4D, 0x6E, 0x45, 0x34, 0x32, 0x51, 0x51, 0x4D, 0x63, 0x61, 0x73, 0x39, 0x55, 0x58, 0x34, 0x50, 0x0A, 0x42, 0x39, 0x39, 0x6A, 0x42, 0x56, 0x7A, 0x70, 0x76, 0x35, ++ 0x52, 0x76, 0x77, 0x53, 0x6D, 0x43, 0x77, 0x4C, 0x54, 0x61, 0x55, 0x62, 0x44, 0x42, 0x50, 0x4C, 0x75, 0x74, 0x4E, 0x30, 0x70, 0x63, 0x79, 0x76, 0x46, 0x4C, 0x4E, 0x67, 0x34, 0x6B, 0x71, 0x37, 0x2F, 0x44, 0x68, 0x48, 0x66, 0x39, 0x71, 0x46, ++ 0x44, 0x30, 0x73, 0x65, 0x66, 0x47, 0x4C, 0x39, 0x49, 0x74, 0x57, 0x59, 0x31, 0x36, 0x43, 0x6B, 0x36, 0x57, 0x61, 0x56, 0x49, 0x43, 0x71, 0x6A, 0x61, 0x59, 0x0A, 0x37, 0x50, 0x7A, 0x36, 0x46, 0x49, 0x4D, 0x4D, 0x4E, 0x78, 0x2F, 0x4A, 0x6B, ++ 0x6A, 0x64, 0x2F, 0x31, 0x34, 0x45, 0x74, 0x35, 0x63, 0x53, 0x35, 0x34, 0x44, 0x34, 0x30, 0x2F, 0x6D, 0x66, 0x30, 0x50, 0x6D, 0x62, 0x52, 0x30, 0x2F, 0x52, 0x41, 0x7A, 0x31, 0x35, 0x69, 0x4E, 0x41, 0x39, 0x77, 0x42, 0x6A, 0x34, 0x67, 0x47, ++ 0x46, 0x72, 0x4F, 0x39, 0x33, 0x49, 0x62, 0x4A, 0x57, 0x79, 0x54, 0x64, 0x42, 0x53, 0x54, 0x6F, 0x33, 0x4F, 0x78, 0x44, 0x71, 0x71, 0x48, 0x0A, 0x45, 0x43, 0x4E, 0x5A, 0x58, 0x79, 0x41, 0x46, 0x47, 0x55, 0x66, 0x74, 0x61, 0x49, 0x36, 0x53, ++ 0x45, 0x73, 0x70, 0x64, 0x2F, 0x4E, 0x59, 0x72, 0x73, 0x70, 0x49, 0x38, 0x49, 0x4D, 0x2F, 0x68, 0x58, 0x36, 0x38, 0x67, 0x76, 0x71, 0x42, 0x32, 0x66, 0x33, 0x62, 0x6C, 0x37, 0x42, 0x71, 0x47, 0x59, 0x54, 0x4D, 0x2B, 0x35, 0x33, 0x75, 0x30, ++ 0x50, 0x36, 0x41, 0x50, 0x6A, 0x71, 0x4B, 0x35, 0x61, 0x6D, 0x2B, 0x35, 0x68, 0x79, 0x5A, 0x76, 0x51, 0x57, 0x79, 0x49, 0x0A, 0x70, 0x6C, 0x44, 0x39, 0x61, 0x6D, 0x4D, 0x4C, 0x39, 0x5A, 0x4D, 0x57, 0x47, 0x78, 0x6D, 0x50, 0x73, 0x75, 0x32, ++ 0x62, 0x6D, 0x38, 0x6D, 0x51, 0x39, 0x51, 0x45, 0x4D, 0x33, 0x78, 0x6B, 0x39, 0x44, 0x7A, 0x34, 0x34, 0x49, 0x38, 0x6B, 0x76, 0x6A, 0x77, 0x7A, 0x52, 0x41, 0x76, 0x34, 0x62, 0x56, 0x64, 0x5A, 0x4F, 0x30, 0x49, 0x30, 0x38, 0x72, 0x30, 0x2B, ++ 0x6B, 0x38, 0x2F, 0x36, 0x76, 0x4B, 0x74, 0x4D, 0x46, 0x6E, 0x58, 0x6B, 0x49, 0x6F, 0x63, 0x74, 0x58, 0x0A, 0x4D, 0x62, 0x53, 0x63, 0x79, 0x4A, 0x43, 0x79, 0x5A, 0x2F, 0x51, 0x59, 0x46, 0x70, 0x4D, 0x36, 0x2F, 0x45, 0x66, 0x59, 0x30, 0x58, ++ 0x69, 0x57, 0x4D, 0x52, 0x2B, 0x36, 0x4B, 0x77, 0x78, 0x66, 0x58, 0x5A, 0x6D, 0x74, 0x59, 0x34, 0x6C, 0x61, 0x4A, 0x43, 0x42, 0x32, 0x32, 0x4E, 0x2F, 0x39, 0x71, 0x30, 0x36, 0x6D, 0x49, 0x71, 0x71, 0x64, 0x58, 0x75, 0x59, 0x6E, 0x69, 0x6E, ++ 0x31, 0x6F, 0x4B, 0x61, 0x50, 0x6E, 0x69, 0x72, 0x6A, 0x61, 0x45, 0x62, 0x73, 0x58, 0x0A, 0x4C, 0x5A, 0x6D, 0x64, 0x45, 0x79, 0x52, 0x47, 0x39, 0x38, 0x58, 0x69, 0x32, 0x4A, 0x2B, 0x4F, 0x66, 0x38, 0x65, 0x50, 0x64, 0x47, 0x31, 0x61, 0x73, ++ 0x75, 0x68, 0x79, 0x39, 0x61, 0x7A, 0x75, 0x4A, 0x42, 0x43, 0x74, 0x4C, 0x78, 0x54, 0x61, 0x2F, 0x79, 0x32, 0x61, 0x52, 0x6E, 0x46, 0x48, 0x76, 0x6B, 0x4C, 0x66, 0x75, 0x77, 0x48, 0x62, 0x39, 0x48, 0x2F, 0x54, 0x4B, 0x49, 0x38, 0x78, 0x57, ++ 0x56, 0x76, 0x54, 0x79, 0x51, 0x4B, 0x6D, 0x74, 0x46, 0x4C, 0x4B, 0x0A, 0x62, 0x70, 0x66, 0x37, 0x51, 0x38, 0x55, 0x49, 0x4A, 0x6D, 0x2B, 0x4B, 0x39, 0x4C, 0x76, 0x39, 0x6E, 0x79, 0x69, 0x71, 0x44, 0x64, 0x56, 0x46, 0x38, 0x78, 0x4D, 0x36, ++ 0x48, 0x64, 0x6A, 0x41, 0x65, 0x49, 0x39, 0x42, 0x5A, 0x7A, 0x77, 0x65, 0x6C, 0x47, 0x53, 0x75, 0x65, 0x77, 0x76, 0x46, 0x36, 0x4E, 0x6B, 0x42, 0x69, 0x44, 0x6B, 0x61, 0x6C, 0x34, 0x5A, 0x6B, 0x51, 0x64, 0x55, 0x37, 0x68, 0x77, 0x78, 0x75, ++ 0x2B, 0x67, 0x2F, 0x47, 0x76, 0x55, 0x67, 0x55, 0x0A, 0x76, 0x7A, 0x6C, 0x4E, 0x31, 0x4A, 0x35, 0x42, 0x74, 0x6F, 0x2B, 0x57, 0x48, 0x57, 0x4F, 0x57, 0x6B, 0x39, 0x6D, 0x56, 0x42, 0x6E, 0x67, 0x78, 0x61, 0x4A, 0x34, 0x33, 0x42, 0x6A, 0x75, ++ 0x41, 0x69, 0x55, 0x56, 0x68, 0x4F, 0x53, 0x50, 0x48, 0x47, 0x30, 0x53, 0x6A, 0x46, 0x65, 0x55, 0x63, 0x2B, 0x4A, 0x49, 0x77, 0x75, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6F, 0x34, 0x48, 0x76, 0x4D, 0x49, 0x48, 0x73, 0x4D, 0x42, 0x30, ++ 0x47, 0x41, 0x31, 0x55, 0x64, 0x0A, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x52, 0x6C, 0x7A, 0x65, 0x75, 0x72, 0x4E, 0x52, 0x34, 0x41, 0x50, 0x6E, 0x37, 0x56, 0x64, 0x4D, 0x41, 0x63, 0x74, 0x48, 0x4E, 0x48, 0x44, 0x68, 0x70, 0x6B, 0x4C, 0x7A, ++ 0x41, 0x53, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x43, 0x44, 0x41, 0x47, 0x41, 0x51, 0x48, 0x2F, 0x41, 0x67, 0x45, 0x42, 0x4D, 0x49, 0x47, 0x6D, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x53, 0x41, 0x45, 0x67, 0x5A, ++ 0x34, 0x77, 0x0A, 0x67, 0x5A, 0x73, 0x77, 0x67, 0x5A, 0x67, 0x47, 0x42, 0x46, 0x55, 0x64, 0x49, 0x41, 0x41, 0x77, 0x67, 0x59, 0x38, 0x77, 0x4C, 0x77, 0x59, 0x49, 0x4B, 0x77, 0x59, 0x42, 0x42, 0x51, 0x55, 0x48, 0x41, 0x67, 0x45, 0x57, 0x49, ++ 0x32, 0x68, 0x30, 0x64, 0x48, 0x41, 0x36, 0x4C, 0x79, 0x39, 0x33, 0x64, 0x33, 0x63, 0x75, 0x5A, 0x6D, 0x6C, 0x79, 0x62, 0x57, 0x46, 0x77, 0x63, 0x6D, 0x39, 0x6D, 0x5A, 0x58, 0x4E, 0x70, 0x62, 0x32, 0x35, 0x68, 0x62, 0x43, 0x35, 0x6A, 0x0A, ++ 0x62, 0x32, 0x30, 0x76, 0x59, 0x33, 0x42, 0x7A, 0x4D, 0x46, 0x77, 0x47, 0x43, 0x43, 0x73, 0x47, 0x41, 0x51, 0x55, 0x46, 0x42, 0x77, 0x49, 0x43, 0x4D, 0x46, 0x41, 0x65, 0x54, 0x67, 0x42, 0x51, 0x41, 0x47, 0x45, 0x41, 0x63, 0x77, 0x42, 0x6C, ++ 0x41, 0x47, 0x38, 0x41, 0x49, 0x41, 0x42, 0x6B, 0x41, 0x47, 0x55, 0x41, 0x49, 0x41, 0x42, 0x73, 0x41, 0x47, 0x45, 0x41, 0x49, 0x41, 0x42, 0x43, 0x41, 0x47, 0x38, 0x41, 0x62, 0x67, 0x42, 0x68, 0x41, 0x47, 0x34, 0x41, 0x0A, 0x62, 0x77, 0x42, ++ 0x32, 0x41, 0x47, 0x45, 0x41, 0x49, 0x41, 0x41, 0x30, 0x41, 0x44, 0x63, 0x41, 0x49, 0x41, 0x42, 0x43, 0x41, 0x47, 0x45, 0x41, 0x63, 0x67, 0x42, 0x6A, 0x41, 0x47, 0x55, 0x41, 0x62, 0x41, 0x42, 0x76, 0x41, 0x47, 0x34, 0x41, 0x59, 0x51, 0x41, ++ 0x67, 0x41, 0x44, 0x41, 0x41, 0x4F, 0x41, 0x41, 0x77, 0x41, 0x44, 0x45, 0x41, 0x4E, 0x7A, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x0A, 0x41, 0x51, 0x59, 0x77, 0x44, 0x51, ++ 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x42, 0x41, 0x48, 0x53, 0x48, 0x4B, 0x41, 0x49, 0x72, 0x64, 0x78, 0x39, 0x6D, 0x69, 0x57, 0x54, 0x74, 0x6A, 0x33, ++ 0x51, 0x75, 0x52, 0x68, 0x79, 0x37, 0x71, 0x50, 0x6A, 0x34, 0x43, 0x78, 0x32, 0x44, 0x74, 0x6A, 0x71, 0x6E, 0x36, 0x45, 0x57, 0x4B, 0x42, 0x37, 0x66, 0x67, 0x50, 0x69, 0x44, 0x4C, 0x0A, 0x34, 0x51, 0x6A, 0x62, 0x45, 0x77, 0x6A, 0x34, 0x4B, ++ 0x4B, 0x45, 0x31, 0x73, 0x6F, 0x43, 0x7A, 0x43, 0x31, 0x48, 0x41, 0x30, 0x31, 0x61, 0x61, 0x6A, 0x54, 0x4E, 0x46, 0x53, 0x61, 0x39, 0x4A, 0x38, 0x4F, 0x41, 0x39, 0x42, 0x33, 0x70, 0x46, 0x45, 0x31, 0x72, 0x2F, 0x79, 0x4A, 0x66, 0x59, 0x30, ++ 0x78, 0x67, 0x73, 0x66, 0x5A, 0x62, 0x34, 0x33, 0x61, 0x4A, 0x6C, 0x51, 0x33, 0x43, 0x54, 0x6B, 0x42, 0x57, 0x36, 0x6B, 0x4E, 0x2F, 0x6F, 0x47, 0x62, 0x44, 0x62, 0x0A, 0x4C, 0x49, 0x70, 0x67, 0x44, 0x37, 0x64, 0x76, 0x6C, 0x41, 0x63, 0x65, ++ 0x48, 0x61, 0x62, 0x4A, 0x68, 0x66, 0x61, 0x39, 0x4E, 0x50, 0x68, 0x41, 0x65, 0x47, 0x49, 0x51, 0x63, 0x44, 0x71, 0x2B, 0x66, 0x55, 0x73, 0x35, 0x67, 0x61, 0x6B, 0x51, 0x31, 0x4A, 0x5A, 0x42, 0x75, 0x2F, 0x68, 0x66, 0x48, 0x41, 0x73, 0x64, ++ 0x43, 0x50, 0x4B, 0x78, 0x73, 0x49, 0x6C, 0x36, 0x38, 0x76, 0x65, 0x67, 0x34, 0x4D, 0x53, 0x50, 0x69, 0x33, 0x69, 0x31, 0x4F, 0x31, 0x69, 0x6C, 0x0A, 0x49, 0x34, 0x35, 0x50, 0x56, 0x66, 0x34, 0x32, 0x4F, 0x2B, 0x41, 0x4D, 0x74, 0x38, 0x6F, ++ 0x71, 0x4D, 0x45, 0x45, 0x67, 0x74, 0x49, 0x44, 0x4E, 0x72, 0x76, 0x78, 0x32, 0x5A, 0x6E, 0x4F, 0x6F, 0x72, 0x6D, 0x37, 0x68, 0x66, 0x4E, 0x6F, 0x44, 0x36, 0x4A, 0x51, 0x67, 0x35, 0x69, 0x4B, 0x6A, 0x30, 0x42, 0x2B, 0x51, 0x58, 0x53, 0x42, ++ 0x54, 0x46, 0x43, 0x5A, 0x58, 0x32, 0x6C, 0x53, 0x58, 0x33, 0x78, 0x5A, 0x45, 0x45, 0x41, 0x45, 0x65, 0x69, 0x47, 0x61, 0x50, 0x0A, 0x63, 0x6A, 0x69, 0x54, 0x33, 0x53, 0x43, 0x33, 0x4E, 0x4C, 0x37, 0x58, 0x38, 0x65, 0x35, 0x6A, 0x6A, 0x6B, ++ 0x64, 0x35, 0x4B, 0x41, 0x62, 0x38, 0x38, 0x31, 0x6C, 0x46, 0x4A, 0x57, 0x41, 0x69, 0x4D, 0x78, 0x75, 0x6A, 0x58, 0x36, 0x69, 0x36, 0x4B, 0x74, 0x6F, 0x61, 0x50, 0x63, 0x31, 0x41, 0x36, 0x6F, 0x7A, 0x75, 0x42, 0x52, 0x57, 0x56, 0x31, 0x61, ++ 0x55, 0x73, 0x49, 0x43, 0x2B, 0x6E, 0x6D, 0x43, 0x6A, 0x75, 0x52, 0x66, 0x7A, 0x78, 0x75, 0x49, 0x67, 0x41, 0x0A, 0x4C, 0x49, 0x39, 0x43, 0x32, 0x6C, 0x48, 0x56, 0x6E, 0x4F, 0x55, 0x54, 0x61, 0x48, 0x46, 0x46, 0x51, 0x34, 0x75, 0x65, 0x43, ++ 0x79, 0x45, 0x38, 0x53, 0x31, 0x77, 0x46, 0x33, 0x42, 0x71, 0x66, 0x6D, 0x49, 0x37, 0x61, 0x76, 0x53, 0x4B, 0x65, 0x63, 0x73, 0x32, 0x74, 0x43, 0x73, 0x76, 0x4D, 0x6F, 0x32, 0x65, 0x62, 0x4B, 0x48, 0x54, 0x45, 0x6D, 0x39, 0x63, 0x61, 0x50, ++ 0x41, 0x52, 0x59, 0x70, 0x6F, 0x4B, 0x64, 0x72, 0x63, 0x64, 0x37, 0x62, 0x2F, 0x2B, 0x41, 0x0A, 0x6C, 0x75, 0x6E, 0x34, 0x6A, 0x57, 0x71, 0x39, 0x47, 0x4A, 0x41, 0x64, 0x2F, 0x30, 0x6B, 0x61, 0x6B, 0x46, 0x49, 0x33, 0x6B, 0x79, 0x38, 0x38, ++ 0x41, 0x6C, 0x32, 0x43, 0x64, 0x67, 0x74, 0x52, 0x35, 0x78, 0x62, 0x48, 0x56, 0x2F, 0x67, 0x34, 0x2B, 0x61, 0x66, 0x4E, 0x6D, 0x79, 0x4A, 0x55, 0x37, 0x32, 0x4F, 0x77, 0x46, 0x57, 0x31, 0x54, 0x5A, 0x51, 0x4E, 0x4B, 0x58, 0x6B, 0x71, 0x67, ++ 0x73, 0x71, 0x65, 0x4F, 0x53, 0x51, 0x42, 0x5A, 0x4F, 0x4E, 0x58, 0x48, 0x0A, 0x39, 0x49, 0x42, 0x6B, 0x39, 0x57, 0x36, 0x56, 0x55, 0x4C, 0x67, 0x52, 0x66, 0x68, 0x56, 0x77, 0x4F, 0x45, 0x71, 0x77, 0x66, 0x39, 0x44, 0x45, 0x4D, 0x6E, 0x44, ++ 0x41, 0x47, 0x66, 0x2F, 0x4A, 0x4F, 0x43, 0x30, 0x55, 0x4C, 0x47, 0x62, 0x30, 0x51, 0x6B, 0x54, 0x6D, 0x56, 0x58, 0x59, 0x62, 0x67, 0x42, 0x56, 0x58, 0x2F, 0x38, 0x43, 0x6E, 0x70, 0x36, 0x6F, 0x35, 0x71, 0x74, 0x6A, 0x54, 0x63, 0x4E, 0x41, ++ 0x75, 0x75, 0x75, 0x75, 0x55, 0x61, 0x76, 0x70, 0x66, 0x0A, 0x4E, 0x49, 0x62, 0x6E, 0x59, 0x72, 0x58, 0x39, 0x69, 0x76, 0x41, 0x77, 0x68, 0x5A, 0x54, 0x4A, 0x72, 0x79, 0x51, 0x43, 0x4C, 0x32, 0x2F, 0x57, 0x33, 0x57, 0x66, 0x2B, 0x34, 0x37, ++ 0x42, 0x56, 0x54, 0x77, 0x53, 0x59, 0x54, 0x36, 0x52, 0x42, 0x56, 0x75, 0x4B, 0x54, 0x30, 0x47, 0x72, 0x6F, 0x31, 0x76, 0x50, 0x37, 0x5A, 0x65, 0x44, 0x4F, 0x64, 0x63, 0x51, 0x78, 0x57, 0x51, 0x7A, 0x75, 0x67, 0x73, 0x67, 0x4D, 0x59, 0x44, ++ 0x4E, 0x4B, 0x47, 0x62, 0x71, 0x45, 0x0A, 0x5A, 0x79, 0x63, 0x50, 0x76, 0x45, 0x4A, 0x64, 0x76, 0x53, 0x52, 0x55, 0x44, 0x65, 0x77, 0x64, 0x63, 0x41, 0x5A, 0x66, 0x70, 0x4C, 0x7A, 0x36, 0x49, 0x48, 0x78, 0x56, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x76, 0x54, 0x72, 0x75, 0x73, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, ++ 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, ++ 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x44, 0x7A, 0x43, 0x43, 0x41, 0x5A, 0x57, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x55, 0x62, 0x6D, 0x71, 0x38, 0x57, 0x61, 0x70, 0x54, 0x76, 0x70, 0x67, 0x35, 0x5A, ++ 0x36, 0x4C, 0x53, 0x61, 0x36, 0x51, 0x37, 0x35, 0x6D, 0x30, 0x63, 0x31, 0x74, 0x6F, 0x77, 0x43, 0x67, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x45, 0x41, 0x77, 0x4D, 0x77, 0x52, 0x7A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, ++ 0x31, 0x55, 0x45, 0x0A, 0x42, 0x68, 0x4D, 0x43, 0x51, 0x30, 0x34, 0x78, 0x48, 0x44, 0x41, 0x61, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x45, 0x32, 0x6C, 0x55, 0x63, 0x6E, 0x56, 0x7A, 0x51, 0x32, 0x68, 0x70, 0x62, 0x6D, 0x45, 0x67, ++ 0x51, 0x32, 0x38, 0x75, 0x4C, 0x45, 0x78, 0x30, 0x5A, 0x43, 0x34, 0x78, 0x47, 0x6A, 0x41, 0x59, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x45, 0x58, 0x5A, 0x55, 0x63, 0x6E, 0x56, 0x7A, 0x49, 0x45, 0x56, 0x44, 0x51, 0x79, 0x42, 0x53, ++ 0x0A, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x45, 0x34, 0x4D, 0x44, 0x63, 0x7A, 0x4D, 0x54, 0x41, 0x33, 0x4D, 0x6A, 0x59, 0x30, 0x4E, 0x46, 0x6F, 0x58, 0x44, 0x54, 0x51, 0x7A, 0x4D, 0x44, 0x63, ++ 0x7A, 0x4D, 0x54, 0x41, 0x33, 0x4D, 0x6A, 0x59, 0x30, 0x4E, 0x46, 0x6F, 0x77, 0x52, 0x7A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x51, 0x30, 0x34, 0x78, 0x48, 0x44, 0x41, 0x61, 0x0A, 0x42, 0x67, ++ 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x45, 0x32, 0x6C, 0x55, 0x63, 0x6E, 0x56, 0x7A, 0x51, 0x32, 0x68, 0x70, 0x62, 0x6D, 0x45, 0x67, 0x51, 0x32, 0x38, 0x75, 0x4C, 0x45, 0x78, 0x30, 0x5A, 0x43, 0x34, 0x78, 0x47, 0x6A, 0x41, 0x59, 0x42, 0x67, ++ 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x45, 0x58, 0x5A, 0x55, 0x63, 0x6E, 0x56, 0x7A, 0x49, 0x45, 0x56, 0x44, 0x51, 0x79, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x4D, 0x48, 0x59, 0x77, 0x0A, 0x45, 0x41, 0x59, 0x48, 0x4B, ++ 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x46, 0x4B, 0x34, 0x45, 0x45, 0x41, 0x43, 0x49, 0x44, 0x59, 0x67, 0x41, 0x45, 0x5A, 0x56, 0x42, 0x4B, 0x72, 0x6F, 0x78, 0x35, 0x6C, 0x6B, 0x71, 0x71, 0x48, 0x41, 0x6A, 0x44, 0x6F, ++ 0x36, 0x4C, 0x4E, 0x2F, 0x6C, 0x6C, 0x57, 0x51, 0x58, 0x66, 0x39, 0x4A, 0x70, 0x52, 0x43, 0x75, 0x78, 0x33, 0x4E, 0x43, 0x4E, 0x74, 0x7A, 0x73, 0x6C, 0x74, 0x31, 0x38, 0x38, 0x2B, 0x63, 0x0A, 0x54, 0x6F, 0x4C, 0x30, 0x76, 0x2F, 0x68, 0x68, ++ 0x4A, 0x6F, 0x56, 0x73, 0x31, 0x6F, 0x56, 0x62, 0x63, 0x6E, 0x44, 0x53, 0x2F, 0x64, 0x74, 0x69, 0x74, 0x4E, 0x39, 0x54, 0x69, 0x37, 0x32, 0x78, 0x52, 0x46, 0x68, 0x69, 0x51, 0x67, 0x6E, 0x48, 0x2B, 0x6E, 0x39, 0x62, 0x45, 0x4F, 0x66, 0x2B, ++ 0x51, 0x50, 0x33, 0x41, 0x32, 0x4D, 0x4D, 0x72, 0x4D, 0x75, 0x64, 0x77, 0x70, 0x72, 0x65, 0x6D, 0x49, 0x46, 0x55, 0x64, 0x65, 0x34, 0x42, 0x64, 0x53, 0x34, 0x39, 0x6E, 0x0A, 0x54, 0x50, 0x45, 0x51, 0x6F, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, ++ 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x6D, 0x44, 0x6E, 0x4E, 0x76, 0x74, 0x69, 0x79, 0x6A, 0x50, 0x65, 0x79, 0x71, 0x2B, 0x47, 0x74, 0x4A, 0x4B, 0x39, 0x37, 0x66, 0x4B, 0x48, 0x62, 0x48, 0x38, 0x38, ++ 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x4F, 0x0A, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, ++ 0x4D, 0x43, 0x41, 0x51, 0x59, 0x77, 0x43, 0x67, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x45, 0x41, 0x77, 0x4D, 0x44, 0x61, 0x41, 0x41, 0x77, 0x5A, 0x51, 0x49, 0x77, 0x56, 0x35, 0x33, 0x64, 0x56, 0x76, 0x48, 0x48, 0x34, 0x2B, ++ 0x6D, 0x34, 0x53, 0x56, 0x42, 0x72, 0x6D, 0x32, 0x6E, 0x44, 0x62, 0x2B, 0x7A, 0x44, 0x66, 0x53, 0x58, 0x6B, 0x56, 0x35, 0x55, 0x54, 0x0A, 0x51, 0x4A, 0x74, 0x53, 0x30, 0x7A, 0x76, 0x7A, 0x51, 0x42, 0x6D, 0x38, 0x4A, 0x73, 0x63, 0x74, 0x42, ++ 0x70, 0x36, 0x31, 0x65, 0x7A, 0x61, 0x66, 0x39, 0x53, 0x58, 0x55, 0x59, 0x32, 0x73, 0x41, 0x41, 0x6A, 0x45, 0x41, 0x36, 0x64, 0x50, 0x47, 0x6E, 0x6C, 0x61, 0x61, 0x4B, 0x73, 0x79, 0x68, 0x32, 0x6A, 0x2F, 0x49, 0x5A, 0x69, 0x76, 0x54, 0x57, ++ 0x4A, 0x77, 0x67, 0x68, 0x66, 0x71, 0x72, 0x6B, 0x59, 0x70, 0x77, 0x63, 0x42, 0x45, 0x34, 0x59, 0x47, 0x51, 0x4C, 0x0A, 0x59, 0x67, 0x6D, 0x52, 0x57, 0x41, 0x44, 0x35, 0x54, 0x66, 0x73, 0x30, 0x61, 0x4E, 0x6F, 0x4A, 0x72, 0x53, 0x45, 0x47, ++ 0x47, 0x4A, 0x54, 0x4F, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x76, 0x54, 0x72, 0x75, 0x73, 0x20, 0x52, 0x6F, ++ 0x6F, 0x74, 0x20, 0x43, 0x41, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, ++ 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x56, 0x6A, 0x43, 0x43, 0x41, 0x7A, 0x36, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x55, 0x51, 0x2B, 0x4E, 0x78, 0x45, 0x39, 0x69, 0x7A, 0x57, 0x52, 0x52, 0x64, ++ 0x74, 0x38, 0x36, 0x4D, 0x2F, 0x54, 0x58, 0x39, 0x62, 0x37, 0x77, 0x46, 0x6A, 0x55, 0x55, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x77, 0x51, 0x7A, 0x45, 0x4C, ++ 0x4D, 0x41, 0x6B, 0x47, 0x0A, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x51, 0x30, 0x34, 0x78, 0x48, 0x44, 0x41, 0x61, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x45, 0x32, 0x6C, 0x55, 0x63, 0x6E, 0x56, 0x7A, 0x51, 0x32, 0x68, ++ 0x70, 0x62, 0x6D, 0x45, 0x67, 0x51, 0x32, 0x38, 0x75, 0x4C, 0x45, 0x78, 0x30, 0x5A, 0x43, 0x34, 0x78, 0x46, 0x6A, 0x41, 0x55, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x44, 0x58, 0x5A, 0x55, 0x63, 0x6E, 0x56, 0x7A, 0x49, 0x46, 0x4A, ++ 0x76, 0x0A, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x54, 0x67, 0x77, 0x4E, 0x7A, 0x4D, 0x78, 0x4D, 0x44, 0x63, 0x79, 0x4E, 0x44, 0x41, 0x31, 0x57, 0x68, 0x63, 0x4E, 0x4E, 0x44, 0x4D, 0x77, 0x4E, 0x7A, ++ 0x4D, 0x78, 0x4D, 0x44, 0x63, 0x79, 0x4E, 0x44, 0x41, 0x31, 0x57, 0x6A, 0x42, 0x44, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x44, 0x54, 0x6A, 0x45, 0x63, 0x4D, 0x42, 0x6F, 0x47, 0x0A, 0x41, ++ 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x54, 0x61, 0x56, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x44, 0x61, 0x47, 0x6C, 0x75, 0x59, 0x53, 0x42, 0x44, 0x62, 0x79, 0x34, 0x73, 0x54, 0x48, 0x52, 0x6B, 0x4C, 0x6A, 0x45, 0x57, 0x4D, 0x42, 0x51, 0x47, 0x41, ++ 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x4E, 0x64, 0x6C, 0x52, 0x79, 0x64, 0x58, 0x4D, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x54, 0x43, 0x43, 0x41, 0x69, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x0A, 0x4B, 0x6F, 0x5A, 0x49, ++ 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x67, 0x6F, 0x43, 0x67, 0x67, 0x49, 0x42, 0x41, 0x4C, 0x31, 0x56, 0x66, 0x47, 0x48, 0x54, 0x75, 0x42, 0x30, 0x45, ++ 0x59, 0x67, 0x57, 0x67, 0x72, 0x6D, 0x79, 0x33, 0x63, 0x4C, 0x52, 0x42, 0x36, 0x6B, 0x73, 0x44, 0x58, 0x68, 0x41, 0x2F, 0x6B, 0x46, 0x6F, 0x63, 0x69, 0x7A, 0x75, 0x77, 0x5A, 0x6F, 0x74, 0x73, 0x0A, 0x53, 0x4B, 0x59, 0x63, 0x49, 0x72, 0x72, ++ 0x56, 0x51, 0x4A, 0x4C, 0x75, 0x4D, 0x37, 0x49, 0x6A, 0x57, 0x63, 0x6D, 0x4F, 0x76, 0x46, 0x6A, 0x61, 0x69, 0x35, 0x37, 0x51, 0x47, 0x66, 0x49, 0x76, 0x57, 0x63, 0x61, 0x4D, 0x59, 0x31, 0x71, 0x36, 0x6E, 0x36, 0x4D, 0x4C, 0x73, 0x4C, 0x4F, ++ 0x61, 0x58, 0x4C, 0x6F, 0x52, 0x75, 0x42, 0x4C, 0x70, 0x44, 0x4C, 0x76, 0x50, 0x62, 0x6D, 0x79, 0x41, 0x68, 0x79, 0x6B, 0x55, 0x41, 0x79, 0x79, 0x4E, 0x4A, 0x4A, 0x72, 0x49, 0x0A, 0x5A, 0x49, 0x4F, 0x31, 0x61, 0x71, 0x77, 0x54, 0x4C, 0x44, ++ 0x50, 0x78, 0x6E, 0x39, 0x77, 0x73, 0x59, 0x54, 0x77, 0x61, 0x50, 0x33, 0x42, 0x56, 0x6D, 0x36, 0x30, 0x41, 0x55, 0x6E, 0x2F, 0x50, 0x42, 0x4C, 0x6E, 0x2B, 0x4E, 0x76, 0x71, 0x63, 0x77, 0x42, 0x61, 0x75, 0x59, 0x76, 0x36, 0x57, 0x54, 0x45, ++ 0x4E, 0x2B, 0x56, 0x52, 0x53, 0x2B, 0x47, 0x72, 0x50, 0x53, 0x62, 0x63, 0x4B, 0x76, 0x64, 0x6D, 0x61, 0x56, 0x61, 0x79, 0x71, 0x77, 0x6C, 0x48, 0x65, 0x46, 0x0A, 0x58, 0x67, 0x51, 0x50, 0x59, 0x68, 0x31, 0x6A, 0x64, 0x66, 0x64, 0x72, 0x35, ++ 0x38, 0x74, 0x62, 0x6D, 0x6E, 0x44, 0x73, 0x50, 0x6D, 0x63, 0x46, 0x38, 0x50, 0x34, 0x48, 0x43, 0x49, 0x44, 0x50, 0x4B, 0x4E, 0x73, 0x46, 0x78, 0x68, 0x51, 0x6E, 0x4C, 0x34, 0x5A, 0x39, 0x38, 0x43, 0x66, 0x65, 0x2F, 0x2B, 0x5A, 0x2B, 0x4D, ++ 0x30, 0x6A, 0x6E, 0x43, 0x78, 0x35, 0x59, 0x30, 0x53, 0x63, 0x72, 0x55, 0x77, 0x35, 0x58, 0x53, 0x6D, 0x58, 0x58, 0x2B, 0x36, 0x4B, 0x41, 0x0A, 0x59, 0x50, 0x78, 0x4D, 0x76, 0x44, 0x56, 0x54, 0x41, 0x57, 0x71, 0x58, 0x63, 0x6F, 0x4B, 0x76, ++ 0x38, 0x52, 0x31, 0x77, 0x36, 0x4A, 0x7A, 0x31, 0x37, 0x31, 0x37, 0x43, 0x62, 0x4D, 0x64, 0x48, 0x66, 0x6C, 0x71, 0x55, 0x68, 0x53, 0x5A, 0x4E, 0x4F, 0x37, 0x72, 0x72, 0x54, 0x4F, 0x69, 0x77, 0x43, 0x63, 0x4A, 0x6C, 0x77, 0x70, 0x32, 0x64, ++ 0x43, 0x5A, 0x74, 0x4F, 0x74, 0x5A, 0x63, 0x46, 0x72, 0x50, 0x55, 0x47, 0x6F, 0x50, 0x63, 0x32, 0x42, 0x58, 0x37, 0x30, 0x0A, 0x6B, 0x4C, 0x4A, 0x72, 0x78, 0x4C, 0x54, 0x35, 0x5A, 0x4F, 0x72, 0x70, 0x47, 0x67, 0x72, 0x49, 0x44, 0x61, 0x6A, ++ 0x74, 0x4A, 0x38, 0x6E, 0x55, 0x35, 0x37, 0x4F, 0x35, 0x71, 0x34, 0x49, 0x69, 0x6B, 0x43, 0x63, 0x39, 0x4B, 0x75, 0x68, 0x38, 0x6B, 0x4F, 0x2B, 0x38, 0x54, 0x2F, 0x33, 0x69, 0x43, 0x69, 0x53, 0x6E, 0x33, 0x6D, 0x55, 0x6B, 0x70, 0x46, 0x33, ++ 0x71, 0x77, 0x48, 0x59, 0x77, 0x30, 0x33, 0x64, 0x51, 0x2B, 0x41, 0x30, 0x45, 0x6D, 0x35, 0x51, 0x32, 0x0A, 0x41, 0x58, 0x50, 0x4B, 0x42, 0x6C, 0x69, 0x6D, 0x30, 0x7A, 0x76, 0x63, 0x2B, 0x67, 0x52, 0x47, 0x45, 0x31, 0x57, 0x4B, 0x79, 0x55, ++ 0x52, 0x48, 0x75, 0x46, 0x45, 0x35, 0x47, 0x69, 0x37, 0x6F, 0x4E, 0x4F, 0x4A, 0x35, 0x79, 0x31, 0x6C, 0x4B, 0x43, 0x6E, 0x2B, 0x38, 0x70, 0x75, 0x38, 0x66, 0x41, 0x32, 0x64, 0x71, 0x57, 0x53, 0x73, 0x6C, 0x59, 0x70, 0x50, 0x5A, 0x55, 0x78, ++ 0x6C, 0x6D, 0x50, 0x43, 0x64, 0x69, 0x4B, 0x59, 0x5A, 0x4E, 0x70, 0x47, 0x76, 0x75, 0x0A, 0x2F, 0x39, 0x52, 0x4F, 0x75, 0x74, 0x57, 0x30, 0x34, 0x6F, 0x35, 0x49, 0x57, 0x67, 0x41, 0x5A, 0x43, 0x66, 0x45, 0x46, 0x32, 0x63, 0x36, 0x52, 0x73, ++ 0x66, 0x66, 0x72, 0x36, 0x54, 0x6C, 0x50, 0x39, 0x6D, 0x38, 0x45, 0x51, 0x35, 0x70, 0x56, 0x39, 0x54, 0x34, 0x46, 0x46, 0x4C, 0x32, 0x2F, 0x73, 0x31, 0x6D, 0x30, 0x32, 0x49, 0x34, 0x7A, 0x68, 0x4B, 0x4F, 0x51, 0x55, 0x71, 0x71, 0x7A, 0x41, ++ 0x70, 0x56, 0x67, 0x2B, 0x51, 0x78, 0x4D, 0x61, 0x50, 0x6E, 0x75, 0x0A, 0x31, 0x52, 0x63, 0x4E, 0x2B, 0x48, 0x46, 0x58, 0x74, 0x53, 0x58, 0x6B, 0x4B, 0x65, 0x35, 0x6C, 0x58, 0x61, 0x2F, 0x52, 0x37, 0x6A, 0x77, 0x58, 0x43, 0x31, 0x70, 0x44, ++ 0x78, 0x61, 0x57, 0x47, 0x36, 0x69, 0x53, 0x65, 0x34, 0x67, 0x55, 0x48, 0x33, 0x44, 0x52, 0x43, 0x45, 0x70, 0x48, 0x57, 0x4F, 0x58, 0x53, 0x75, 0x54, 0x45, 0x47, 0x43, 0x32, 0x2F, 0x4B, 0x6D, 0x53, 0x4E, 0x47, 0x7A, 0x6D, 0x2F, 0x4D, 0x7A, ++ 0x71, 0x76, 0x4F, 0x6D, 0x77, 0x4D, 0x56, 0x4F, 0x0A, 0x39, 0x66, 0x53, 0x64, 0x64, 0x6D, 0x50, 0x6D, 0x41, 0x73, 0x59, 0x69, 0x53, 0x38, 0x47, 0x56, 0x50, 0x31, 0x42, 0x6B, 0x4C, 0x46, 0x54, 0x6C, 0x74, 0x76, 0x41, 0x38, 0x4B, 0x63, 0x39, ++ 0x58, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, 0x51, 0x6A, 0x42, 0x41, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x52, 0x55, 0x59, 0x6E, 0x42, 0x6A, 0x38, 0x58, 0x57, 0x45, 0x51, 0x31, 0x69, ++ 0x4F, 0x30, 0x52, 0x59, 0x67, 0x0A, 0x73, 0x63, 0x61, 0x73, 0x47, 0x72, 0x7A, 0x32, 0x69, 0x54, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x41, ++ 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x41, ++ 0x4F, 0x43, 0x0A, 0x41, 0x67, 0x45, 0x41, 0x4B, 0x62, 0x71, 0x53, 0x53, 0x61, 0x65, 0x74, 0x38, 0x50, 0x46, 0x77, 0x77, 0x2B, 0x53, 0x58, 0x38, 0x4A, 0x2B, 0x70, 0x4A, 0x64, 0x56, 0x72, 0x6E, 0x6A, 0x54, 0x2B, 0x35, 0x68, 0x70, 0x6B, 0x39, ++ 0x6A, 0x70, 0x72, 0x55, 0x72, 0x49, 0x51, 0x65, 0x42, 0x71, 0x66, 0x54, 0x4E, 0x71, 0x4B, 0x32, 0x75, 0x77, 0x63, 0x4E, 0x31, 0x4C, 0x67, 0x51, 0x6B, 0x76, 0x37, 0x62, 0x48, 0x62, 0x4B, 0x4A, 0x41, 0x73, 0x35, 0x45, 0x68, 0x57, 0x64, 0x0A, ++ 0x6E, 0x78, 0x45, 0x74, 0x2F, 0x48, 0x6C, 0x6B, 0x33, 0x4F, 0x44, 0x67, 0x39, 0x64, 0x33, 0x67, 0x56, 0x38, 0x6D, 0x6C, 0x73, 0x6E, 0x5A, 0x77, 0x55, 0x4B, 0x54, 0x2B, 0x74, 0x77, 0x70, 0x77, 0x31, 0x61, 0x41, 0x30, 0x38, 0x58, 0x58, 0x58, ++ 0x54, 0x55, 0x6D, 0x36, 0x45, 0x64, 0x47, 0x7A, 0x32, 0x4F, 0x79, 0x43, 0x2F, 0x2B, 0x73, 0x4F, 0x78, 0x4C, 0x39, 0x6B, 0x4C, 0x58, 0x31, 0x6A, 0x62, 0x68, 0x64, 0x34, 0x37, 0x46, 0x31, 0x38, 0x69, 0x4D, 0x6A, 0x72, 0x0A, 0x6A, 0x6C, 0x64, ++ 0x32, 0x32, 0x56, 0x6B, 0x45, 0x2B, 0x72, 0x78, 0x53, 0x48, 0x30, 0x57, 0x73, 0x38, 0x48, 0x71, 0x41, 0x37, 0x4F, 0x78, 0x76, 0x64, 0x71, 0x36, 0x52, 0x32, 0x78, 0x43, 0x4F, 0x42, 0x4E, 0x79, 0x53, 0x33, 0x36, 0x44, 0x32, 0x35, 0x71, 0x35, ++ 0x4A, 0x30, 0x38, 0x46, 0x73, 0x45, 0x68, 0x76, 0x4D, 0x4B, 0x61, 0x72, 0x35, 0x43, 0x4B, 0x58, 0x69, 0x4E, 0x78, 0x54, 0x4B, 0x73, 0x62, 0x68, 0x6D, 0x37, 0x78, 0x71, 0x43, 0x35, 0x50, 0x44, 0x34, 0x0A, 0x38, 0x61, 0x63, 0x57, 0x61, 0x62, ++ 0x66, 0x62, 0x71, 0x57, 0x45, 0x38, 0x6E, 0x2F, 0x55, 0x78, 0x79, 0x2B, 0x51, 0x41, 0x52, 0x73, 0x49, 0x76, 0x64, 0x4C, 0x47, 0x78, 0x31, 0x34, 0x48, 0x75, 0x71, 0x43, 0x61, 0x56, 0x76, 0x49, 0x69, 0x76, 0x54, 0x44, 0x55, 0x48, 0x4B, 0x67, ++ 0x4C, 0x4B, 0x65, 0x42, 0x52, 0x74, 0x52, 0x79, 0x74, 0x41, 0x56, 0x75, 0x6E, 0x4C, 0x4B, 0x6D, 0x43, 0x68, 0x5A, 0x77, 0x4F, 0x67, 0x7A, 0x6F, 0x79, 0x38, 0x73, 0x48, 0x4A, 0x6E, 0x0A, 0x78, 0x44, 0x48, 0x4F, 0x32, 0x7A, 0x54, 0x6C, 0x4A, ++ 0x51, 0x4E, 0x67, 0x4A, 0x58, 0x74, 0x78, 0x6D, 0x4F, 0x54, 0x41, 0x47, 0x79, 0x74, 0x66, 0x64, 0x45, 0x4C, 0x53, 0x53, 0x38, 0x56, 0x5A, 0x43, 0x41, 0x65, 0x48, 0x76, 0x73, 0x58, 0x44, 0x66, 0x2B, 0x65, 0x57, 0x32, 0x65, 0x48, 0x63, 0x4B, ++ 0x4A, 0x66, 0x57, 0x6A, 0x77, 0x58, 0x6A, 0x39, 0x5A, 0x74, 0x4F, 0x79, 0x68, 0x31, 0x51, 0x52, 0x77, 0x56, 0x54, 0x73, 0x4D, 0x6F, 0x35, 0x35, 0x34, 0x57, 0x67, 0x0A, 0x69, 0x63, 0x45, 0x46, 0x4F, 0x77, 0x45, 0x33, 0x30, 0x7A, 0x39, 0x4A, ++ 0x34, 0x6E, 0x66, 0x72, 0x49, 0x38, 0x69, 0x49, 0x5A, 0x6A, 0x73, 0x39, 0x4F, 0x58, 0x59, 0x68, 0x52, 0x76, 0x48, 0x73, 0x58, 0x79, 0x4F, 0x34, 0x36, 0x36, 0x4A, 0x6D, 0x64, 0x58, 0x54, 0x42, 0x51, 0x50, 0x66, 0x59, 0x61, 0x4A, 0x71, 0x54, ++ 0x34, 0x69, 0x32, 0x70, 0x4C, 0x72, 0x30, 0x63, 0x6F, 0x78, 0x37, 0x49, 0x64, 0x4D, 0x61, 0x6B, 0x4C, 0x58, 0x6F, 0x67, 0x71, 0x7A, 0x75, 0x34, 0x0A, 0x73, 0x45, 0x62, 0x39, 0x62, 0x39, 0x31, 0x66, 0x55, 0x6C, 0x56, 0x31, 0x59, 0x76, 0x43, ++ 0x58, 0x6F, 0x48, 0x7A, 0x58, 0x4F, 0x50, 0x30, 0x6C, 0x33, 0x38, 0x32, 0x67, 0x6D, 0x78, 0x44, 0x50, 0x69, 0x37, 0x67, 0x34, 0x58, 0x6C, 0x37, 0x46, 0x74, 0x4B, 0x59, 0x43, 0x4E, 0x71, 0x45, 0x65, 0x58, 0x78, 0x7A, 0x50, 0x34, 0x70, 0x61, ++ 0x64, 0x4B, 0x61, 0x72, 0x39, 0x6D, 0x4B, 0x35, 0x53, 0x34, 0x66, 0x4E, 0x42, 0x55, 0x76, 0x75, 0x70, 0x4C, 0x6E, 0x4B, 0x57, 0x0A, 0x6E, 0x79, 0x66, 0x6A, 0x71, 0x6E, 0x4E, 0x39, 0x2B, 0x42, 0x6F, 0x6A, 0x5A, 0x6E, 0x73, 0x37, 0x71, 0x32, ++ 0x57, 0x77, 0x4D, 0x67, 0x46, 0x4C, 0x46, 0x54, 0x34, 0x39, 0x6F, 0x6B, 0x38, 0x4D, 0x4B, 0x7A, 0x57, 0x69, 0x78, 0x74, 0x6C, 0x6E, 0x45, 0x6A, 0x55, 0x77, 0x7A, 0x58, 0x59, 0x75, 0x46, 0x72, 0x4F, 0x5A, 0x6E, 0x6B, 0x31, 0x50, 0x54, 0x69, ++ 0x30, 0x37, 0x4E, 0x45, 0x50, 0x68, 0x6D, 0x67, 0x34, 0x4E, 0x70, 0x47, 0x61, 0x58, 0x75, 0x74, 0x49, 0x63, 0x0A, 0x53, 0x6B, 0x77, 0x73, 0x4B, 0x6F, 0x75, 0x4C, 0x67, 0x55, 0x39, 0x78, 0x47, 0x71, 0x6E, 0x64, 0x58, 0x48, 0x74, 0x37, 0x43, ++ 0x4D, 0x55, 0x41, 0x44, 0x54, 0x64, 0x41, 0x34, 0x33, 0x78, 0x37, 0x56, 0x46, 0x38, 0x76, 0x68, 0x56, 0x39, 0x32, 0x39, 0x76, 0x65, 0x6E, 0x73, 0x42, 0x78, 0x58, 0x56, 0x73, 0x46, 0x79, 0x36, 0x4B, 0x32, 0x69, 0x72, 0x34, 0x30, 0x7A, 0x53, ++ 0x62, 0x6F, 0x66, 0x69, 0x74, 0x7A, 0x6D, 0x64, 0x48, 0x78, 0x67, 0x68, 0x6D, 0x2B, 0x48, 0x0A, 0x6C, 0x33, 0x73, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, ++ 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x49, 0x53, 0x52, 0x47, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x58, 0x32, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, ++ 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x47, 0x7A, 0x43, 0x43, 0x41, 0x61, 0x47, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, ++ 0x49, 0x51, 0x51, 0x64, 0x4B, 0x64, 0x30, 0x58, 0x4C, 0x71, 0x37, 0x71, 0x65, 0x41, 0x77, 0x53, 0x78, 0x73, 0x36, 0x53, 0x2B, 0x48, 0x55, 0x6A, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x7A, ++ 0x42, 0x50, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, 0x0A, 0x55, 0x7A, 0x45, 0x70, 0x4D, 0x43, 0x63, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x67, 0x53, 0x57, 0x35, 0x30, 0x5A, ++ 0x58, 0x4A, 0x75, 0x5A, 0x58, 0x51, 0x67, 0x55, 0x32, 0x56, 0x6A, 0x64, 0x58, 0x4A, 0x70, 0x64, 0x48, 0x6B, 0x67, 0x55, 0x6D, 0x56, 0x7A, 0x5A, 0x57, 0x46, 0x79, 0x59, 0x32, 0x67, 0x67, 0x52, 0x33, 0x4A, 0x76, 0x64, 0x58, 0x41, 0x78, 0x46, ++ 0x54, 0x41, 0x54, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x44, 0x45, 0x6C, 0x54, 0x0A, 0x55, 0x6B, 0x63, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x59, 0x4D, 0x6A, 0x41, 0x65, 0x46, 0x77, 0x30, 0x79, 0x4D, 0x44, 0x41, 0x35, ++ 0x4D, 0x44, 0x51, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x42, 0x61, 0x46, 0x77, 0x30, 0x30, 0x4D, 0x44, 0x41, 0x35, 0x4D, 0x54, 0x63, 0x78, 0x4E, 0x6A, 0x41, 0x77, 0x4D, 0x44, 0x42, 0x61, 0x4D, 0x45, 0x38, 0x78, 0x43, 0x7A, 0x41, 0x4A, ++ 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6C, 0x56, 0x54, 0x0A, 0x4D, 0x53, 0x6B, 0x77, 0x4A, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x79, 0x42, 0x4A, 0x62, 0x6E, 0x52, 0x6C, 0x63, 0x6D, 0x35, 0x6C, 0x64, 0x43, 0x42, ++ 0x54, 0x5A, 0x57, 0x4E, 0x31, 0x63, 0x6D, 0x6C, 0x30, 0x65, 0x53, 0x42, 0x53, 0x5A, 0x58, 0x4E, 0x6C, 0x59, 0x58, 0x4A, 0x6A, 0x61, 0x43, 0x42, 0x48, 0x63, 0x6D, 0x39, 0x31, 0x63, 0x44, 0x45, 0x56, 0x4D, 0x42, 0x4D, 0x47, 0x41, 0x31, 0x55, ++ 0x45, 0x41, 0x78, 0x4D, 0x4D, 0x53, 0x56, 0x4E, 0x53, 0x0A, 0x52, 0x79, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x46, 0x67, 0x79, 0x4D, 0x48, 0x59, 0x77, 0x45, 0x41, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, ++ 0x59, 0x46, 0x4B, 0x34, 0x45, 0x45, 0x41, 0x43, 0x49, 0x44, 0x59, 0x67, 0x41, 0x45, 0x7A, 0x5A, 0x76, 0x56, 0x6E, 0x34, 0x43, 0x44, 0x43, 0x75, 0x77, 0x4A, 0x53, 0x76, 0x4D, 0x57, 0x53, 0x6A, 0x35, 0x63, 0x7A, 0x33, 0x65, 0x73, 0x33, 0x6D, ++ 0x63, 0x46, 0x44, 0x52, 0x30, 0x48, 0x0A, 0x74, 0x74, 0x77, 0x57, 0x2B, 0x31, 0x71, 0x4C, 0x46, 0x4E, 0x76, 0x69, 0x63, 0x57, 0x44, 0x45, 0x75, 0x6B, 0x57, 0x56, 0x45, 0x59, 0x6D, 0x4F, 0x36, 0x67, 0x62, 0x66, 0x39, 0x79, 0x6F, 0x57, 0x48, ++ 0x4B, 0x53, 0x35, 0x78, 0x63, 0x55, 0x79, 0x34, 0x41, 0x50, 0x67, 0x48, 0x6F, 0x49, 0x59, 0x4F, 0x49, 0x76, 0x58, 0x52, 0x64, 0x67, 0x4B, 0x61, 0x6D, 0x37, 0x6D, 0x41, 0x48, 0x66, 0x37, 0x41, 0x6C, 0x46, 0x39, 0x49, 0x74, 0x67, 0x4B, 0x62, ++ 0x70, 0x70, 0x62, 0x0A, 0x64, 0x39, 0x2F, 0x77, 0x2B, 0x6B, 0x48, 0x73, 0x4F, 0x64, 0x78, 0x31, 0x79, 0x6D, 0x67, 0x48, 0x44, 0x42, 0x2F, 0x71, 0x6F, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, ++ 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x51, 0x59, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, ++ 0x0A, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x66, 0x45, 0x4B, 0x57, 0x72, 0x74, 0x35, 0x4C, 0x53, 0x44, 0x76, 0x36, 0x6B, 0x76, 0x69, 0x65, 0x6A, 0x4D, 0x39, 0x74, 0x69, 0x36, 0x6C, 0x79, 0x4E, 0x35, 0x55, 0x77, 0x43, 0x67, 0x59, ++ 0x49, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x45, 0x41, 0x77, 0x4D, 0x44, 0x61, 0x41, 0x41, 0x77, 0x5A, 0x51, 0x49, 0x77, 0x65, 0x33, 0x6C, 0x4F, 0x52, 0x6C, 0x43, 0x45, 0x77, 0x6B, 0x53, 0x48, 0x52, 0x68, 0x74, 0x46, 0x0A, 0x63, 0x50, ++ 0x39, 0x59, 0x6D, 0x64, 0x37, 0x30, 0x2F, 0x61, 0x54, 0x53, 0x56, 0x61, 0x59, 0x67, 0x4C, 0x58, 0x54, 0x57, 0x4E, 0x4C, 0x78, 0x42, 0x6F, 0x31, 0x42, 0x66, 0x41, 0x53, 0x64, 0x57, 0x74, 0x4C, 0x34, 0x6E, 0x64, 0x51, 0x61, 0x76, 0x45, 0x69, ++ 0x35, 0x31, 0x6D, 0x49, 0x33, 0x38, 0x41, 0x6A, 0x45, 0x41, 0x69, 0x2F, 0x56, 0x33, 0x62, 0x4E, 0x54, 0x49, 0x5A, 0x61, 0x72, 0x67, 0x43, 0x79, 0x7A, 0x75, 0x46, 0x4A, 0x30, 0x6E, 0x4E, 0x36, 0x54, 0x35, 0x0A, 0x55, 0x36, 0x56, 0x52, 0x35, ++ 0x43, 0x6D, 0x44, 0x31, 0x2F, 0x69, 0x51, 0x4D, 0x56, 0x74, 0x43, 0x6E, 0x77, 0x72, 0x31, 0x2F, 0x71, 0x34, 0x41, 0x61, 0x4F, 0x65, 0x4D, 0x53, 0x51, 0x2B, 0x32, 0x62, 0x31, 0x74, 0x62, 0x46, 0x66, 0x4C, 0x6E, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x48, 0x69, 0x50, 0x4B, 0x49, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, ++ 0x31, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, ++ 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x61, 0x6A, 0x43, 0x43, 0x41, 0x31, 0x4B, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x4C, 0x64, 0x32, 0x73, 0x7A, 0x6D, 0x4B, 0x58, 0x6C, 0x4B, 0x46, ++ 0x44, 0x36, 0x4C, 0x44, 0x4E, 0x64, 0x6D, 0x70, 0x65, 0x59, 0x44, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x42, 0x50, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, ++ 0x44, 0x56, 0x51, 0x51, 0x47, 0x0A, 0x45, 0x77, 0x4A, 0x55, 0x56, 0x7A, 0x45, 0x6A, 0x4D, 0x43, 0x45, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x61, 0x51, 0x32, 0x68, 0x31, 0x62, 0x6D, 0x64, 0x6F, 0x64, 0x32, 0x45, 0x67, 0x56, 0x47, ++ 0x56, 0x73, 0x5A, 0x57, 0x4E, 0x76, 0x62, 0x53, 0x42, 0x44, 0x62, 0x79, 0x34, 0x73, 0x49, 0x45, 0x78, 0x30, 0x5A, 0x43, 0x34, 0x78, 0x47, 0x7A, 0x41, 0x5A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x45, 0x6B, 0x68, 0x70, 0x55, 0x45, ++ 0x74, 0x4A, 0x0A, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x4C, 0x53, 0x42, 0x48, 0x4D, 0x54, 0x41, 0x65, 0x46, 0x77, 0x30, 0x78, 0x4F, 0x54, 0x41, 0x79, 0x4D, 0x6A, 0x49, 0x77, 0x4F, 0x54, 0x51, 0x32, 0x4D, ++ 0x44, 0x52, 0x61, 0x46, 0x77, 0x30, 0x7A, 0x4E, 0x7A, 0x45, 0x79, 0x4D, 0x7A, 0x45, 0x78, 0x4E, 0x54, 0x55, 0x35, 0x4E, 0x54, 0x6C, 0x61, 0x4D, 0x45, 0x38, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x0A, ++ 0x41, 0x6C, 0x52, 0x58, 0x4D, 0x53, 0x4D, 0x77, 0x49, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x44, 0x42, 0x70, 0x44, 0x61, 0x48, 0x56, 0x75, 0x5A, 0x32, 0x68, 0x33, 0x59, 0x53, 0x42, 0x55, 0x5A, 0x57, 0x78, 0x6C, 0x59, 0x32, 0x39, 0x74, ++ 0x49, 0x45, 0x4E, 0x76, 0x4C, 0x69, 0x77, 0x67, 0x54, 0x48, 0x52, 0x6B, 0x4C, 0x6A, 0x45, 0x62, 0x4D, 0x42, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x53, 0x53, 0x47, 0x6C, 0x51, 0x53, 0x30, 0x6B, 0x67, 0x0A, 0x55, 0x6D, 0x39, ++ 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x53, 0x41, 0x74, 0x49, 0x45, 0x63, 0x78, 0x4D, 0x49, 0x49, 0x43, 0x49, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x4F, ++ 0x43, 0x41, 0x67, 0x38, 0x41, 0x4D, 0x49, 0x49, 0x43, 0x43, 0x67, 0x4B, 0x43, 0x41, 0x67, 0x45, 0x41, 0x39, 0x42, 0x35, 0x2F, 0x55, 0x6E, 0x4D, 0x79, 0x44, 0x48, 0x50, 0x6B, 0x76, 0x52, 0x4E, 0x30, 0x0A, 0x6F, 0x39, 0x51, 0x77, 0x71, 0x4E, ++ 0x43, 0x75, 0x53, 0x39, 0x69, 0x32, 0x33, 0x33, 0x56, 0x48, 0x5A, 0x76, 0x52, 0x38, 0x35, 0x7A, 0x6B, 0x45, 0x48, 0x6D, 0x70, 0x77, 0x49, 0x4E, 0x4A, 0x61, 0x52, 0x33, 0x4A, 0x6E, 0x56, 0x66, 0x53, 0x6C, 0x36, 0x4A, 0x33, 0x56, 0x48, 0x69, ++ 0x47, 0x68, 0x38, 0x47, 0x65, 0x36, 0x7A, 0x43, 0x46, 0x6F, 0x76, 0x6B, 0x52, 0x54, 0x76, 0x34, 0x33, 0x35, 0x34, 0x74, 0x77, 0x76, 0x56, 0x63, 0x67, 0x33, 0x50, 0x78, 0x2B, 0x6B, 0x0A, 0x77, 0x4A, 0x79, 0x7A, 0x35, 0x48, 0x64, 0x63, 0x6F, ++ 0x45, 0x62, 0x2B, 0x64, 0x2F, 0x6F, 0x61, 0x6F, 0x44, 0x6A, 0x71, 0x37, 0x5A, 0x70, 0x79, 0x33, 0x69, 0x75, 0x39, 0x6C, 0x46, 0x63, 0x36, 0x75, 0x75, 0x78, 0x35, 0x35, 0x31, 0x39, 0x39, 0x51, 0x6D, 0x51, 0x35, 0x65, 0x69, 0x59, 0x32, 0x39, ++ 0x79, 0x54, 0x77, 0x31, 0x53, 0x2B, 0x36, 0x6C, 0x5A, 0x67, 0x52, 0x5A, 0x71, 0x32, 0x58, 0x4E, 0x64, 0x5A, 0x31, 0x41, 0x59, 0x44, 0x67, 0x72, 0x2F, 0x53, 0x45, 0x0A, 0x59, 0x59, 0x77, 0x4E, 0x48, 0x6C, 0x39, 0x38, 0x68, 0x35, 0x5A, 0x65, ++ 0x51, 0x61, 0x2F, 0x72, 0x68, 0x2B, 0x72, 0x34, 0x58, 0x66, 0x45, 0x75, 0x69, 0x41, 0x55, 0x2B, 0x54, 0x43, 0x4B, 0x37, 0x32, 0x68, 0x38, 0x71, 0x33, 0x56, 0x4A, 0x47, 0x5A, 0x44, 0x6E, 0x7A, 0x51, 0x73, 0x37, 0x5A, 0x6E, 0x67, 0x79, 0x7A, ++ 0x73, 0x48, 0x65, 0x58, 0x5A, 0x4A, 0x7A, 0x41, 0x39, 0x4B, 0x4D, 0x75, 0x48, 0x35, 0x55, 0x48, 0x73, 0x42, 0x66, 0x66, 0x4D, 0x4E, 0x73, 0x41, 0x0A, 0x47, 0x4A, 0x5A, 0x4D, 0x6F, 0x59, 0x46, 0x4C, 0x33, 0x51, 0x52, 0x74, 0x55, 0x36, 0x4D, ++ 0x39, 0x2F, 0x41, 0x65, 0x73, 0x31, 0x4D, 0x55, 0x33, 0x67, 0x75, 0x76, 0x6B, 0x6C, 0x51, 0x67, 0x5A, 0x4B, 0x49, 0x4C, 0x53, 0x51, 0x6A, 0x71, 0x6A, 0x32, 0x46, 0x50, 0x73, 0x65, 0x59, 0x6C, 0x67, 0x53, 0x47, 0x44, 0x49, 0x63, 0x70, 0x4A, ++ 0x51, 0x33, 0x41, 0x4F, 0x50, 0x67, 0x7A, 0x2B, 0x79, 0x51, 0x6C, 0x64, 0x61, 0x32, 0x32, 0x72, 0x70, 0x45, 0x5A, 0x66, 0x64, 0x0A, 0x68, 0x53, 0x69, 0x38, 0x4D, 0x45, 0x79, 0x72, 0x34, 0x38, 0x4B, 0x78, 0x52, 0x55, 0x52, 0x48, 0x48, 0x2B, ++ 0x43, 0x4B, 0x46, 0x67, 0x65, 0x57, 0x30, 0x69, 0x45, 0x50, 0x55, 0x38, 0x44, 0x74, 0x71, 0x58, 0x37, 0x55, 0x54, 0x75, 0x79, 0x62, 0x43, 0x65, 0x79, 0x76, 0x51, 0x71, 0x77, 0x77, 0x31, 0x72, 0x2F, 0x52, 0x45, 0x45, 0x58, 0x67, 0x70, 0x68, ++ 0x61, 0x79, 0x70, 0x63, 0x58, 0x54, 0x54, 0x33, 0x4F, 0x55, 0x4D, 0x33, 0x45, 0x43, 0x6F, 0x57, 0x71, 0x6A, 0x0A, 0x31, 0x6A, 0x4F, 0x58, 0x54, 0x79, 0x46, 0x6A, 0x48, 0x6C, 0x75, 0x50, 0x32, 0x63, 0x46, 0x65, 0x52, 0x58, 0x46, 0x33, 0x44, ++ 0x34, 0x46, 0x64, 0x58, 0x79, 0x47, 0x61, 0x72, 0x59, 0x50, 0x4D, 0x2B, 0x6C, 0x37, 0x57, 0x6A, 0x53, 0x4E, 0x66, 0x47, 0x7A, 0x31, 0x42, 0x72, 0x79, 0x42, 0x31, 0x5A, 0x6C, 0x70, 0x4B, 0x39, 0x70, 0x2F, 0x37, 0x71, 0x78, 0x6A, 0x33, 0x63, ++ 0x63, 0x43, 0x32, 0x48, 0x54, 0x48, 0x73, 0x4F, 0x79, 0x44, 0x72, 0x79, 0x2B, 0x4B, 0x34, 0x0A, 0x39, 0x61, 0x36, 0x53, 0x73, 0x76, 0x66, 0x68, 0x68, 0x45, 0x76, 0x79, 0x6F, 0x76, 0x4B, 0x54, 0x6D, 0x69, 0x4B, 0x65, 0x30, 0x78, 0x52, 0x76, ++ 0x4E, 0x6C, 0x53, 0x39, 0x48, 0x31, 0x35, 0x5A, 0x46, 0x62, 0x6C, 0x7A, 0x71, 0x4D, 0x46, 0x38, 0x62, 0x33, 0x74, 0x69, 0x36, 0x52, 0x5A, 0x73, 0x52, 0x31, 0x70, 0x6C, 0x38, 0x77, 0x34, 0x52, 0x6D, 0x30, 0x62, 0x5A, 0x2F, 0x57, 0x33, 0x63, ++ 0x31, 0x70, 0x7A, 0x41, 0x74, 0x48, 0x32, 0x6C, 0x73, 0x4E, 0x30, 0x2F, 0x0A, 0x56, 0x6D, 0x2B, 0x68, 0x2B, 0x66, 0x62, 0x6B, 0x45, 0x6B, 0x6A, 0x39, 0x42, 0x6E, 0x38, 0x53, 0x56, 0x37, 0x61, 0x70, 0x49, 0x30, 0x39, 0x62, 0x41, 0x38, 0x50, ++ 0x67, 0x63, 0x53, 0x6F, 0x6A, 0x74, 0x2F, 0x65, 0x77, 0x73, 0x54, 0x75, 0x38, 0x6D, 0x4C, 0x33, 0x57, 0x6D, 0x4B, 0x67, 0x4D, 0x61, 0x2F, 0x61, 0x4F, 0x45, 0x6D, 0x65, 0x6D, 0x38, 0x72, 0x4A, 0x59, 0x35, 0x41, 0x49, 0x4A, 0x45, 0x7A, 0x79, ++ 0x70, 0x75, 0x78, 0x43, 0x30, 0x30, 0x6A, 0x42, 0x46, 0x0A, 0x38, 0x65, 0x7A, 0x33, 0x41, 0x42, 0x48, 0x66, 0x5A, 0x66, 0x6A, 0x63, 0x4B, 0x30, 0x4E, 0x56, 0x76, 0x78, 0x61, 0x58, 0x78, 0x41, 0x2F, 0x56, 0x4C, 0x47, 0x47, 0x45, 0x71, 0x6E, ++ 0x4B, 0x47, 0x2F, 0x75, 0x59, 0x36, 0x66, 0x73, 0x49, 0x2F, 0x66, 0x65, 0x37, 0x38, 0x4C, 0x78, 0x51, 0x2B, 0x35, 0x6F, 0x58, 0x64, 0x55, 0x47, 0x2B, 0x33, 0x53, 0x65, 0x30, 0x43, 0x41, 0x77, 0x45, 0x41, 0x41, 0x61, 0x4E, 0x43, 0x4D, 0x45, ++ 0x41, 0x77, 0x44, 0x77, 0x59, 0x44, 0x0A, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x38, ++ 0x6E, 0x63, 0x58, 0x2B, 0x6C, 0x36, 0x6F, 0x2F, 0x76, 0x59, 0x39, 0x63, 0x64, 0x56, 0x6F, 0x75, 0x73, 0x6C, 0x47, 0x44, 0x44, 0x6A, 0x59, 0x72, 0x37, 0x41, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, ++ 0x41, 0x51, 0x44, 0x0A, 0x41, 0x67, 0x47, 0x47, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43, 0x77, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x41, 0x51, 0x42, 0x51, 0x55, 0x66, 0x42, 0x31, ++ 0x33, 0x48, 0x41, 0x45, 0x34, 0x2F, 0x2B, 0x71, 0x64, 0x64, 0x52, 0x78, 0x6F, 0x73, 0x75, 0x65, 0x6A, 0x36, 0x69, 0x70, 0x30, 0x36, 0x39, 0x31, 0x78, 0x31, 0x54, 0x50, 0x4F, 0x68, 0x77, 0x45, 0x6D, 0x53, 0x4B, 0x73, 0x78, 0x42, 0x48, 0x69, ++ 0x0A, 0x37, 0x7A, 0x4E, 0x4B, 0x70, 0x69, 0x4D, 0x64, 0x44, 0x67, 0x31, 0x48, 0x32, 0x44, 0x66, 0x48, 0x62, 0x36, 0x38, 0x30, 0x66, 0x30, 0x2B, 0x42, 0x61, 0x7A, 0x56, 0x50, 0x36, 0x58, 0x4B, 0x6C, 0x4D, 0x65, 0x4A, 0x34, 0x35, 0x2F, 0x64, ++ 0x4F, 0x6C, 0x42, 0x68, 0x62, 0x51, 0x48, 0x33, 0x50, 0x61, 0x79, 0x46, 0x55, 0x68, 0x75, 0x61, 0x56, 0x65, 0x76, 0x76, 0x47, 0x79, 0x75, 0x71, 0x63, 0x53, 0x45, 0x35, 0x58, 0x43, 0x56, 0x30, 0x76, 0x72, 0x50, 0x53, 0x6C, 0x0A, 0x74, 0x4A, ++ 0x63, 0x7A, 0x57, 0x4E, 0x57, 0x73, 0x65, 0x61, 0x6E, 0x4D, 0x58, 0x2F, 0x6D, 0x46, 0x2B, 0x6C, 0x4C, 0x46, 0x6A, 0x66, 0x69, 0x52, 0x46, 0x4F, 0x73, 0x36, 0x44, 0x52, 0x66, 0x51, 0x55, 0x73, 0x4A, 0x37, 0x34, 0x38, 0x4A, 0x7A, 0x6A, 0x6B, ++ 0x5A, 0x34, 0x42, 0x6A, 0x67, 0x73, 0x36, 0x46, 0x7A, 0x61, 0x5A, 0x73, 0x54, 0x30, 0x70, 0x50, 0x42, 0x57, 0x47, 0x54, 0x4D, 0x70, 0x57, 0x6D, 0x57, 0x53, 0x42, 0x55, 0x64, 0x47, 0x53, 0x71, 0x75, 0x45, 0x0A, 0x77, 0x78, 0x34, 0x6E, 0x6F, ++ 0x52, 0x38, 0x52, 0x6B, 0x70, 0x6B, 0x6E, 0x64, 0x5A, 0x4D, 0x50, 0x76, 0x44, 0x59, 0x37, 0x6C, 0x31, 0x65, 0x50, 0x4A, 0x6C, 0x73, 0x4D, 0x75, 0x35, 0x77, 0x50, 0x31, 0x47, 0x34, 0x77, 0x42, 0x39, 0x54, 0x63, 0x58, 0x7A, 0x5A, 0x6F, 0x5A, ++ 0x6A, 0x6D, 0x44, 0x6C, 0x69, 0x63, 0x6D, 0x69, 0x73, 0x6A, 0x45, 0x4F, 0x66, 0x36, 0x61, 0x49, 0x57, 0x2F, 0x56, 0x63, 0x6F, 0x62, 0x70, 0x66, 0x32, 0x4C, 0x6C, 0x6C, 0x30, 0x37, 0x51, 0x0A, 0x4A, 0x4E, 0x42, 0x41, 0x73, 0x4E, 0x42, 0x31, ++ 0x43, 0x49, 0x36, 0x39, 0x61, 0x4F, 0x34, 0x49, 0x31, 0x32, 0x35, 0x38, 0x45, 0x48, 0x42, 0x47, 0x47, 0x33, 0x7A, 0x67, 0x69, 0x4C, 0x4B, 0x65, 0x63, 0x6F, 0x61, 0x5A, 0x41, 0x65, 0x4F, 0x2F, 0x6E, 0x30, 0x6B, 0x5A, 0x74, 0x43, 0x57, 0x2B, ++ 0x56, 0x6D, 0x57, 0x75, 0x46, 0x32, 0x50, 0x6C, 0x48, 0x74, 0x2F, 0x6F, 0x2F, 0x30, 0x65, 0x6C, 0x76, 0x2B, 0x45, 0x6D, 0x42, 0x59, 0x54, 0x6B, 0x73, 0x4D, 0x43, 0x76, 0x0A, 0x35, 0x77, 0x69, 0x5A, 0x71, 0x41, 0x78, 0x65, 0x4A, 0x6F, 0x42, ++ 0x46, 0x31, 0x50, 0x68, 0x6F, 0x4C, 0x35, 0x61, 0x50, 0x72, 0x75, 0x4A, 0x4B, 0x48, 0x4A, 0x77, 0x57, 0x44, 0x42, 0x4E, 0x76, 0x4F, 0x49, 0x66, 0x32, 0x75, 0x38, 0x67, 0x30, 0x58, 0x35, 0x49, 0x44, 0x55, 0x58, 0x6C, 0x77, 0x70, 0x74, 0x2F, ++ 0x4C, 0x39, 0x5A, 0x6C, 0x4E, 0x65, 0x63, 0x31, 0x4F, 0x76, 0x46, 0x65, 0x66, 0x51, 0x30, 0x35, 0x72, 0x4C, 0x69, 0x73, 0x59, 0x2B, 0x47, 0x70, 0x7A, 0x0A, 0x6A, 0x4C, 0x72, 0x46, 0x4E, 0x65, 0x38, 0x35, 0x61, 0x6B, 0x45, 0x65, 0x7A, 0x33, ++ 0x47, 0x6F, 0x6F, 0x72, 0x4B, 0x47, 0x42, 0x31, 0x73, 0x36, 0x79, 0x65, 0x48, 0x76, 0x50, 0x32, 0x55, 0x45, 0x67, 0x45, 0x63, 0x79, 0x52, 0x48, 0x43, 0x56, 0x54, 0x6A, 0x46, 0x6E, 0x61, 0x6E, 0x52, 0x62, 0x45, 0x45, 0x56, 0x31, 0x36, 0x72, ++ 0x43, 0x66, 0x30, 0x4F, 0x59, 0x31, 0x2F, 0x6B, 0x36, 0x66, 0x69, 0x38, 0x77, 0x72, 0x6B, 0x6B, 0x56, 0x62, 0x62, 0x69, 0x56, 0x67, 0x0A, 0x68, 0x55, 0x62, 0x4E, 0x30, 0x61, 0x71, 0x77, 0x64, 0x6D, 0x61, 0x54, 0x64, 0x35, 0x61, 0x2B, 0x67, ++ 0x37, 0x34, 0x34, 0x74, 0x69, 0x52, 0x4F, 0x4A, 0x67, 0x76, 0x4D, 0x37, 0x58, 0x70, 0x57, 0x47, 0x75, 0x44, 0x70, 0x57, 0x73, 0x5A, 0x6B, 0x72, 0x55, 0x78, 0x36, 0x41, 0x45, 0x68, 0x45, 0x4C, 0x37, 0x6C, 0x41, 0x75, 0x78, 0x4D, 0x2B, 0x76, ++ 0x68, 0x56, 0x34, 0x6E, 0x59, 0x57, 0x42, 0x53, 0x69, 0x70, 0x58, 0x33, 0x74, 0x55, 0x5A, 0x51, 0x39, 0x72, 0x62, 0x0A, 0x79, 0x6C, 0x74, 0x48, 0x68, 0x6F, 0x4D, 0x4C, 0x50, 0x37, 0x59, 0x4E, 0x64, 0x6E, 0x68, 0x7A, 0x65, 0x53, 0x4A, 0x65, ++ 0x73, 0x59, 0x41, 0x66, 0x7A, 0x37, 0x37, 0x52, 0x50, 0x31, 0x59, 0x51, 0x6D, 0x43, 0x75, 0x56, 0x68, 0x36, 0x45, 0x66, 0x6E, 0x57, 0x51, 0x55, 0x59, 0x44, 0x6B, 0x73, 0x73, 0x77, 0x42, 0x56, 0x4C, 0x75, 0x54, 0x31, 0x73, 0x77, 0x35, 0x58, ++ 0x78, 0x4A, 0x46, 0x42, 0x41, 0x4A, 0x77, 0x2F, 0x36, 0x4B, 0x58, 0x66, 0x36, 0x76, 0x62, 0x2F, 0x0A, 0x79, 0x50, 0x43, 0x74, 0x62, 0x56, 0x4B, 0x6F, 0x46, 0x36, 0x75, 0x62, 0x59, 0x66, 0x77, 0x53, 0x55, 0x54, 0x58, 0x6B, 0x4A, 0x66, 0x32, ++ 0x76, 0x71, 0x6D, 0x71, 0x47, 0x4F, 0x51, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x47, 0x6C, 0x6F, ++ 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x52, 0x34, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x0A, 0x4D, 0x49, 0x49, 0x42, 0x33, 0x44, 0x43, 0x43, 0x41, 0x59, 0x4F, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x4E, 0x41, 0x67, 0x50, 0x6C, 0x66, 0x76, 0x55, 0x2F, 0x6B, 0x2F, 0x32, 0x6C, 0x43, 0x53, 0x47, 0x79, 0x70, 0x6A, 0x41, ++ 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x6A, 0x42, 0x51, 0x4D, 0x53, 0x51, 0x77, 0x49, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, 0x45, 0x78, 0x74, 0x48, 0x62, 0x47, 0x39, 0x69, 0x0A, 0x59, 0x57, ++ 0x78, 0x54, 0x61, 0x57, 0x64, 0x75, 0x49, 0x45, 0x56, 0x44, 0x51, 0x79, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x49, 0x43, 0x30, 0x67, 0x55, 0x6A, 0x51, 0x78, 0x45, 0x7A, 0x41, 0x52, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, ++ 0x6F, 0x54, 0x43, 0x6B, 0x64, 0x73, 0x62, 0x32, 0x4A, 0x68, 0x62, 0x46, 0x4E, 0x70, 0x5A, 0x32, 0x34, 0x78, 0x45, 0x7A, 0x41, 0x52, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x43, 0x6B, 0x64, 0x73, 0x0A, 0x62, 0x32, 0x4A, 0x68, 0x62, ++ 0x46, 0x4E, 0x70, 0x5A, 0x32, 0x34, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x54, 0x49, 0x78, 0x4D, 0x54, 0x45, 0x7A, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x57, 0x68, 0x63, 0x4E, 0x4D, 0x7A, 0x67, 0x77, 0x4D, 0x54, 0x45, 0x35, 0x4D, ++ 0x44, 0x4D, 0x78, 0x4E, 0x44, 0x41, 0x33, 0x57, 0x6A, 0x42, 0x51, 0x4D, 0x53, 0x51, 0x77, 0x49, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, 0x45, 0x78, 0x74, 0x48, 0x62, 0x47, 0x39, 0x69, 0x0A, 0x59, 0x57, 0x78, 0x54, 0x61, 0x57, 0x64, 0x75, ++ 0x49, 0x45, 0x56, 0x44, 0x51, 0x79, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x49, 0x43, 0x30, 0x67, 0x55, 0x6A, 0x51, 0x78, 0x45, 0x7A, 0x41, 0x52, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x43, 0x6B, 0x64, 0x73, ++ 0x62, 0x32, 0x4A, 0x68, 0x62, 0x46, 0x4E, 0x70, 0x5A, 0x32, 0x34, 0x78, 0x45, 0x7A, 0x41, 0x52, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x43, 0x6B, 0x64, 0x73, 0x0A, 0x62, 0x32, 0x4A, 0x68, 0x62, 0x46, 0x4E, 0x70, 0x5A, 0x32, 0x34, ++ 0x77, 0x57, 0x54, 0x41, 0x54, 0x42, 0x67, 0x63, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x49, 0x42, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x4D, 0x42, 0x42, 0x77, 0x4E, 0x43, 0x41, 0x41, 0x53, 0x34, 0x78, 0x6E, 0x6E, ++ 0x54, 0x6A, 0x32, 0x77, 0x6C, 0x44, 0x70, 0x38, 0x75, 0x4F, 0x52, 0x6B, 0x63, 0x41, 0x36, 0x53, 0x75, 0x6D, 0x75, 0x55, 0x35, 0x42, 0x77, 0x6B, 0x57, 0x0A, 0x79, 0x6D, 0x4F, 0x78, 0x75, 0x59, 0x62, 0x34, 0x69, 0x6C, 0x66, 0x42, 0x56, 0x38, ++ 0x35, 0x43, 0x2B, 0x6E, 0x4F, 0x68, 0x39, 0x32, 0x56, 0x43, 0x2F, 0x78, 0x37, 0x42, 0x41, 0x4C, 0x4A, 0x75, 0x63, 0x77, 0x37, 0x2F, 0x78, 0x79, 0x48, 0x6C, 0x47, 0x4B, 0x53, 0x71, 0x32, 0x58, 0x45, 0x2F, 0x71, 0x4E, 0x53, 0x35, 0x7A, 0x6F, ++ 0x77, 0x64, 0x6F, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x0A, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x59, 0x59, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, ++ 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x56, 0x4C, 0x42, 0x37, 0x72, 0x55, 0x57, 0x34, 0x34, 0x6B, 0x42, 0x2F, 0x2B, ++ 0x77, 0x70, 0x75, 0x2B, 0x37, 0x34, 0x7A, 0x79, 0x54, 0x79, 0x6A, 0x68, 0x4E, 0x55, 0x77, 0x43, 0x67, 0x59, 0x49, 0x0A, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x45, 0x41, 0x77, 0x49, 0x44, 0x52, 0x77, 0x41, 0x77, 0x52, 0x41, 0x49, 0x67, ++ 0x49, 0x6B, 0x39, 0x30, 0x63, 0x72, 0x6C, 0x67, 0x72, 0x2F, 0x48, 0x6D, 0x6E, 0x4B, 0x41, 0x57, 0x42, 0x56, 0x42, 0x66, 0x77, 0x31, 0x34, 0x37, 0x62, 0x6D, 0x46, 0x30, 0x37, 0x37, 0x34, 0x42, 0x78, 0x4C, 0x34, 0x59, 0x53, 0x46, 0x6C, 0x68, ++ 0x67, 0x6A, 0x49, 0x43, 0x49, 0x43, 0x61, 0x64, 0x56, 0x47, 0x4E, 0x41, 0x33, 0x6A, 0x64, 0x67, 0x0A, 0x55, 0x4D, 0x2F, 0x49, 0x32, 0x4F, 0x32, 0x64, 0x67, 0x71, 0x34, 0x33, 0x6D, 0x4C, 0x79, 0x6A, 0x6A, 0x30, 0x78, 0x4D, 0x71, 0x54, 0x51, ++ 0x72, 0x62, 0x4F, 0x2F, 0x37, 0x6C, 0x5A, 0x73, 0x6D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x47, 0x54, 0x53, ++ 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x31, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, ++ 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x56, 0x7A, 0x43, 0x43, 0x41, 0x7A, 0x2B, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x4E, 0x41, 0x67, 0x50, 0x6C, 0x6B, 0x32, 0x38, 0x78, 0x73, 0x42, 0x4E, ++ 0x4A, 0x69, 0x47, 0x75, 0x69, 0x46, 0x7A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x77, 0x46, 0x41, 0x44, 0x42, 0x48, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, ++ 0x47, 0x45, 0x77, 0x4A, 0x56, 0x0A, 0x55, 0x7A, 0x45, 0x69, 0x4D, 0x43, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x5A, 0x52, 0x32, 0x39, 0x76, 0x5A, 0x32, 0x78, 0x6C, 0x49, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x49, 0x46, ++ 0x4E, 0x6C, 0x63, 0x6E, 0x5A, 0x70, 0x59, 0x32, 0x56, 0x7A, 0x49, 0x45, 0x78, 0x4D, 0x51, 0x7A, 0x45, 0x55, 0x4D, 0x42, 0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x4C, 0x52, 0x31, 0x52, 0x54, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, ++ 0x51, 0x67, 0x0A, 0x55, 0x6A, 0x45, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x54, 0x59, 0x77, 0x4E, 0x6A, 0x49, 0x79, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x57, 0x68, 0x63, 0x4E, 0x4D, 0x7A, 0x59, 0x77, 0x4E, 0x6A, 0x49, 0x79, 0x4D, ++ 0x44, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x57, 0x6A, 0x42, 0x48, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x69, 0x4D, 0x43, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0A, ++ 0x43, 0x68, 0x4D, 0x5A, 0x52, 0x32, 0x39, 0x76, 0x5A, 0x32, 0x78, 0x6C, 0x49, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x49, 0x46, 0x4E, 0x6C, 0x63, 0x6E, 0x5A, 0x70, 0x59, 0x32, 0x56, 0x7A, 0x49, 0x45, 0x78, 0x4D, 0x51, 0x7A, 0x45, 0x55, ++ 0x4D, 0x42, 0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x4C, 0x52, 0x31, 0x52, 0x54, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x55, 0x6A, 0x45, 0x77, 0x67, 0x67, 0x49, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x0A, 0x43, 0x53, 0x71, ++ 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x43, 0x32, 0x45, 0x51, 0x4B, 0x4C, 0x48, 0x75, 0x4F, ++ 0x68, 0x64, 0x35, 0x73, 0x37, 0x33, 0x4C, 0x2B, 0x55, 0x50, 0x72, 0x65, 0x56, 0x70, 0x30, 0x41, 0x38, 0x6F, 0x66, 0x32, 0x43, 0x2B, 0x58, 0x30, 0x79, 0x42, 0x6F, 0x4A, 0x78, 0x39, 0x76, 0x61, 0x4D, 0x0A, 0x66, 0x2F, 0x76, 0x6F, 0x32, 0x37, ++ 0x78, 0x71, 0x4C, 0x70, 0x65, 0x58, 0x6F, 0x34, 0x78, 0x4C, 0x2B, 0x53, 0x76, 0x32, 0x73, 0x66, 0x6E, 0x4F, 0x68, 0x42, 0x32, 0x78, 0x2B, 0x63, 0x57, 0x58, 0x33, 0x75, 0x2B, 0x35, 0x38, 0x71, 0x50, 0x70, 0x76, 0x42, 0x4B, 0x4A, 0x58, 0x71, ++ 0x65, 0x71, 0x55, 0x71, 0x76, 0x34, 0x49, 0x79, 0x66, 0x4C, 0x70, 0x4C, 0x47, 0x63, 0x59, 0x39, 0x76, 0x58, 0x6D, 0x58, 0x37, 0x77, 0x43, 0x6C, 0x37, 0x72, 0x61, 0x4B, 0x62, 0x30, 0x0A, 0x78, 0x6C, 0x70, 0x48, 0x44, 0x55, 0x30, 0x51, 0x4D, ++ 0x2B, 0x4E, 0x4F, 0x73, 0x52, 0x4F, 0x6A, 0x79, 0x42, 0x68, 0x73, 0x53, 0x2B, 0x7A, 0x38, 0x43, 0x5A, 0x44, 0x66, 0x6E, 0x57, 0x51, 0x70, 0x4A, 0x53, 0x4D, 0x48, 0x6F, 0x62, 0x54, 0x53, 0x50, 0x53, 0x35, 0x67, 0x34, 0x4D, 0x2F, 0x53, 0x43, ++ 0x59, 0x65, 0x37, 0x7A, 0x55, 0x6A, 0x77, 0x54, 0x63, 0x4C, 0x43, 0x65, 0x6F, 0x69, 0x4B, 0x75, 0x37, 0x72, 0x50, 0x57, 0x52, 0x6E, 0x57, 0x72, 0x34, 0x2B, 0x77, 0x0A, 0x42, 0x37, 0x43, 0x65, 0x4D, 0x66, 0x47, 0x43, 0x77, 0x63, 0x44, 0x66, ++ 0x4C, 0x71, 0x5A, 0x74, 0x62, 0x42, 0x6B, 0x4F, 0x74, 0x64, 0x68, 0x2B, 0x4A, 0x68, 0x70, 0x46, 0x41, 0x7A, 0x32, 0x77, 0x65, 0x61, 0x53, 0x55, 0x4B, 0x4B, 0x30, 0x50, 0x66, 0x79, 0x62, 0x6C, 0x71, 0x41, 0x6A, 0x2B, 0x6C, 0x75, 0x67, 0x38, ++ 0x61, 0x4A, 0x52, 0x54, 0x37, 0x6F, 0x4D, 0x36, 0x69, 0x43, 0x73, 0x56, 0x6C, 0x67, 0x6D, 0x79, 0x34, 0x48, 0x71, 0x4D, 0x4C, 0x6E, 0x58, 0x57, 0x0A, 0x6E, 0x4F, 0x75, 0x6E, 0x56, 0x6D, 0x53, 0x50, 0x6C, 0x6B, 0x39, 0x6F, 0x72, 0x6A, 0x32, ++ 0x58, 0x77, 0x6F, 0x53, 0x50, 0x77, 0x4C, 0x78, 0x41, 0x77, 0x41, 0x74, 0x63, 0x76, 0x66, 0x61, 0x48, 0x73, 0x7A, 0x56, 0x73, 0x72, 0x42, 0x68, 0x51, 0x66, 0x34, 0x54, 0x67, 0x54, 0x4D, 0x32, 0x53, 0x30, 0x79, 0x44, 0x70, 0x4D, 0x37, 0x78, ++ 0x53, 0x6D, 0x61, 0x38, 0x79, 0x74, 0x53, 0x6D, 0x7A, 0x4A, 0x53, 0x71, 0x30, 0x53, 0x50, 0x6C, 0x79, 0x34, 0x63, 0x70, 0x6B, 0x0A, 0x39, 0x2B, 0x61, 0x43, 0x45, 0x49, 0x33, 0x6F, 0x6E, 0x63, 0x4B, 0x4B, 0x69, 0x50, 0x6F, 0x34, 0x5A, 0x6F, ++ 0x72, 0x38, 0x59, 0x2F, 0x6B, 0x42, 0x2B, 0x58, 0x6A, 0x39, 0x65, 0x31, 0x78, 0x33, 0x2B, 0x6E, 0x61, 0x48, 0x2B, 0x75, 0x7A, 0x66, 0x73, 0x51, 0x35, 0x35, 0x6C, 0x56, 0x65, 0x30, 0x76, 0x53, 0x62, 0x76, 0x31, 0x67, 0x48, 0x52, 0x36, 0x78, ++ 0x59, 0x4B, 0x75, 0x34, 0x34, 0x4C, 0x74, 0x63, 0x58, 0x46, 0x69, 0x6C, 0x57, 0x72, 0x30, 0x36, 0x7A, 0x71, 0x0A, 0x6B, 0x55, 0x73, 0x70, 0x7A, 0x42, 0x6D, 0x6B, 0x4D, 0x69, 0x56, 0x4F, 0x4B, 0x76, 0x46, 0x6C, 0x52, 0x4E, 0x41, 0x43, 0x7A, ++ 0x71, 0x72, 0x4F, 0x53, 0x62, 0x54, 0x71, 0x6E, 0x33, 0x79, 0x44, 0x73, 0x45, 0x42, 0x37, 0x35, 0x30, 0x4F, 0x72, 0x70, 0x32, 0x79, 0x6A, 0x6A, 0x33, 0x32, 0x4A, 0x67, 0x66, 0x70, 0x4D, 0x70, 0x66, 0x2F, 0x56, 0x6A, 0x73, 0x50, 0x4F, 0x53, ++ 0x2B, 0x43, 0x31, 0x32, 0x4C, 0x4F, 0x4F, 0x52, 0x63, 0x39, 0x32, 0x77, 0x4F, 0x31, 0x41, 0x0A, 0x4B, 0x2F, 0x31, 0x54, 0x44, 0x37, 0x43, 0x6E, 0x31, 0x54, 0x73, 0x4E, 0x73, 0x59, 0x71, 0x69, 0x41, 0x39, 0x34, 0x78, 0x72, 0x63, 0x78, 0x33, ++ 0x36, 0x6D, 0x39, 0x37, 0x50, 0x74, 0x62, 0x66, 0x6B, 0x53, 0x49, 0x53, 0x35, 0x72, 0x37, 0x36, 0x32, 0x44, 0x4C, 0x38, 0x45, 0x47, 0x4D, 0x55, 0x55, 0x58, 0x4C, 0x65, 0x58, 0x64, 0x59, 0x57, 0x6B, 0x37, 0x30, 0x70, 0x61, 0x44, 0x50, 0x76, ++ 0x4F, 0x6D, 0x62, 0x73, 0x42, 0x34, 0x6F, 0x6D, 0x33, 0x78, 0x50, 0x58, 0x0A, 0x56, 0x32, 0x56, 0x34, 0x4A, 0x39, 0x35, 0x65, 0x53, 0x52, 0x51, 0x41, 0x6F, 0x67, 0x42, 0x2F, 0x6D, 0x71, 0x67, 0x68, 0x74, 0x71, 0x6D, 0x78, 0x6C, 0x62, 0x43, ++ 0x6C, 0x75, 0x51, 0x30, 0x57, 0x45, 0x64, 0x72, 0x48, 0x62, 0x45, 0x67, 0x38, 0x51, 0x4F, 0x42, 0x2B, 0x44, 0x56, 0x72, 0x4E, 0x56, 0x6A, 0x7A, 0x52, 0x6C, 0x77, 0x57, 0x35, 0x79, 0x30, 0x76, 0x74, 0x4F, 0x55, 0x75, 0x63, 0x78, 0x44, 0x2F, ++ 0x53, 0x56, 0x52, 0x4E, 0x75, 0x4A, 0x4C, 0x44, 0x57, 0x0A, 0x63, 0x66, 0x72, 0x30, 0x77, 0x62, 0x72, 0x4D, 0x37, 0x52, 0x76, 0x31, 0x2F, 0x6F, 0x46, 0x42, 0x32, 0x41, 0x43, 0x59, 0x50, 0x54, 0x72, 0x49, 0x72, 0x6E, 0x71, 0x59, 0x4E, 0x78, ++ 0x67, 0x46, 0x6C, 0x51, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6F, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x59, 0x59, 0x77, 0x44, 0x77, ++ 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x0A, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x35, 0x4B, 0x38, 0x72, 0x4A, ++ 0x6E, 0x45, 0x61, 0x4B, 0x30, 0x67, 0x6E, 0x68, 0x53, 0x39, 0x53, 0x5A, 0x69, 0x7A, 0x76, 0x38, 0x49, 0x6B, 0x54, 0x63, 0x54, 0x34, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4D, 0x42, ++ 0x51, 0x41, 0x44, 0x0A, 0x67, 0x67, 0x49, 0x42, 0x41, 0x4A, 0x2B, 0x71, 0x51, 0x69, 0x62, 0x62, 0x43, 0x35, 0x75, 0x2B, 0x2F, 0x78, 0x36, 0x57, 0x6B, 0x69, 0x34, 0x2B, 0x6F, 0x6D, 0x56, 0x4B, 0x61, 0x70, 0x69, 0x36, 0x49, 0x73, 0x74, 0x39, ++ 0x77, 0x54, 0x72, 0x59, 0x67, 0x67, 0x6F, 0x47, 0x78, 0x76, 0x61, 0x6C, 0x33, 0x73, 0x42, 0x4F, 0x68, 0x32, 0x5A, 0x35, 0x6F, 0x66, 0x6D, 0x6D, 0x57, 0x4A, 0x79, 0x71, 0x2B, 0x62, 0x58, 0x6D, 0x59, 0x4F, 0x66, 0x67, 0x36, 0x4C, 0x45, 0x65, ++ 0x0A, 0x51, 0x6B, 0x45, 0x7A, 0x43, 0x7A, 0x63, 0x39, 0x7A, 0x6F, 0x6C, 0x77, 0x46, 0x63, 0x71, 0x31, 0x4A, 0x4B, 0x6A, 0x50, 0x61, 0x37, 0x58, 0x53, 0x51, 0x43, 0x47, 0x59, 0x7A, 0x79, 0x49, 0x30, 0x7A, 0x7A, 0x76, 0x46, 0x49, 0x6F, 0x54, ++ 0x67, 0x78, 0x51, 0x36, 0x4B, 0x66, 0x46, 0x32, 0x49, 0x35, 0x44, 0x55, 0x6B, 0x7A, 0x70, 0x73, 0x2B, 0x47, 0x6C, 0x51, 0x65, 0x62, 0x74, 0x75, 0x79, 0x68, 0x36, 0x66, 0x38, 0x38, 0x2F, 0x71, 0x42, 0x56, 0x52, 0x52, 0x69, 0x0A, 0x43, 0x6C, ++ 0x6D, 0x70, 0x49, 0x67, 0x55, 0x78, 0x50, 0x6F, 0x4C, 0x57, 0x37, 0x74, 0x74, 0x58, 0x4E, 0x4C, 0x77, 0x7A, 0x6C, 0x64, 0x4D, 0x58, 0x47, 0x2B, 0x67, 0x6E, 0x6F, 0x6F, 0x74, 0x37, 0x54, 0x69, 0x59, 0x61, 0x65, 0x6C, 0x70, 0x6B, 0x74, 0x74, ++ 0x47, 0x73, 0x4E, 0x2F, 0x48, 0x39, 0x6F, 0x50, 0x4D, 0x34, 0x37, 0x48, 0x4C, 0x77, 0x45, 0x58, 0x57, 0x64, 0x79, 0x7A, 0x52, 0x53, 0x6A, 0x65, 0x5A, 0x32, 0x61, 0x78, 0x66, 0x47, 0x33, 0x34, 0x61, 0x72, 0x0A, 0x4A, 0x34, 0x35, 0x4A, 0x4B, ++ 0x33, 0x56, 0x6D, 0x67, 0x52, 0x41, 0x68, 0x70, 0x75, 0x6F, 0x2B, 0x39, 0x4B, 0x34, 0x6C, 0x2F, 0x33, 0x77, 0x56, 0x33, 0x73, 0x36, 0x4D, 0x4A, 0x54, 0x2F, 0x4B, 0x59, 0x6E, 0x41, 0x4B, 0x39, 0x79, 0x38, 0x4A, 0x5A, 0x67, 0x66, 0x49, 0x50, ++ 0x78, 0x7A, 0x38, 0x38, 0x4E, 0x74, 0x46, 0x4D, 0x4E, 0x39, 0x69, 0x69, 0x4D, 0x47, 0x31, 0x44, 0x35, 0x33, 0x44, 0x6E, 0x30, 0x72, 0x65, 0x57, 0x56, 0x6C, 0x48, 0x78, 0x59, 0x63, 0x69, 0x0A, 0x4E, 0x75, 0x61, 0x43, 0x70, 0x2B, 0x30, 0x4B, ++ 0x75, 0x65, 0x49, 0x48, 0x6F, 0x49, 0x31, 0x37, 0x65, 0x6B, 0x6F, 0x38, 0x63, 0x64, 0x4C, 0x69, 0x41, 0x36, 0x45, 0x66, 0x4D, 0x67, 0x66, 0x64, 0x47, 0x2B, 0x52, 0x43, 0x7A, 0x67, 0x77, 0x41, 0x52, 0x57, 0x47, 0x41, 0x74, 0x51, 0x73, 0x67, ++ 0x57, 0x53, 0x6C, 0x34, 0x76, 0x66, 0x6C, 0x56, 0x79, 0x32, 0x50, 0x46, 0x50, 0x45, 0x7A, 0x30, 0x74, 0x76, 0x2F, 0x62, 0x61, 0x6C, 0x38, 0x78, 0x61, 0x35, 0x6D, 0x65, 0x0A, 0x4C, 0x4D, 0x46, 0x72, 0x55, 0x4B, 0x54, 0x58, 0x35, 0x68, 0x67, ++ 0x55, 0x76, 0x59, 0x55, 0x2F, 0x5A, 0x36, 0x74, 0x47, 0x6E, 0x36, 0x44, 0x2F, 0x51, 0x71, 0x63, 0x36, 0x66, 0x31, 0x7A, 0x4C, 0x58, 0x62, 0x42, 0x77, 0x48, 0x53, 0x73, 0x30, 0x39, 0x64, 0x52, 0x32, 0x43, 0x51, 0x7A, 0x72, 0x65, 0x45, 0x78, ++ 0x5A, 0x42, 0x66, 0x4D, 0x7A, 0x51, 0x73, 0x4E, 0x68, 0x46, 0x52, 0x41, 0x62, 0x64, 0x30, 0x33, 0x4F, 0x49, 0x6F, 0x7A, 0x55, 0x68, 0x66, 0x4A, 0x46, 0x0A, 0x66, 0x62, 0x64, 0x54, 0x36, 0x75, 0x39, 0x41, 0x57, 0x70, 0x51, 0x4B, 0x58, 0x43, ++ 0x42, 0x66, 0x54, 0x6B, 0x42, 0x64, 0x59, 0x69, 0x4A, 0x32, 0x33, 0x2F, 0x2F, 0x4F, 0x59, 0x62, 0x32, 0x4D, 0x49, 0x33, 0x6A, 0x53, 0x4E, 0x77, 0x4C, 0x67, 0x6A, 0x74, 0x37, 0x52, 0x45, 0x54, 0x65, 0x4A, 0x39, 0x72, 0x2F, 0x74, 0x53, 0x51, ++ 0x64, 0x69, 0x72, 0x70, 0x4C, 0x73, 0x51, 0x42, 0x71, 0x76, 0x46, 0x41, 0x6E, 0x5A, 0x30, 0x45, 0x36, 0x79, 0x6F, 0x76, 0x65, 0x2B, 0x0A, 0x37, 0x75, 0x37, 0x59, 0x2F, 0x39, 0x77, 0x61, 0x4C, 0x64, 0x36, 0x34, 0x4E, 0x6E, 0x48, 0x69, 0x2F, ++ 0x48, 0x6D, 0x33, 0x6C, 0x43, 0x58, 0x52, 0x53, 0x48, 0x4E, 0x62, 0x6F, 0x54, 0x58, 0x6E, 0x73, 0x35, 0x6C, 0x6E, 0x64, 0x63, 0x45, 0x5A, 0x4F, 0x69, 0x74, 0x48, 0x54, 0x74, 0x4E, 0x43, 0x6A, 0x76, 0x30, 0x78, 0x79, 0x42, 0x5A, 0x6D, 0x32, ++ 0x74, 0x49, 0x4D, 0x50, 0x4E, 0x75, 0x7A, 0x6A, 0x73, 0x6D, 0x68, 0x44, 0x59, 0x41, 0x50, 0x65, 0x78, 0x5A, 0x33, 0x0A, 0x46, 0x4C, 0x2F, 0x2F, 0x32, 0x77, 0x6D, 0x55, 0x73, 0x70, 0x4F, 0x38, 0x49, 0x46, 0x67, 0x56, 0x36, 0x64, 0x74, 0x78, ++ 0x51, 0x2F, 0x50, 0x65, 0x45, 0x4D, 0x4D, 0x41, 0x33, 0x4B, 0x67, 0x71, 0x6C, 0x62, 0x62, 0x43, 0x31, 0x6A, 0x2B, 0x51, 0x61, 0x33, 0x62, 0x62, 0x62, 0x50, 0x36, 0x4D, 0x76, 0x50, 0x4A, 0x77, 0x4E, 0x51, 0x7A, 0x63, 0x6D, 0x52, 0x6B, 0x31, ++ 0x33, 0x4E, 0x66, 0x49, 0x52, 0x6D, 0x50, 0x56, 0x4E, 0x6E, 0x47, 0x75, 0x56, 0x2F, 0x75, 0x33, 0x0A, 0x67, 0x6D, 0x33, 0x63, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, ++ 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x32, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, ++ 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x56, 0x7A, 0x43, 0x43, 0x41, 0x7A, 0x2B, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, ++ 0x4E, 0x41, 0x67, 0x50, 0x6C, 0x72, 0x73, 0x57, 0x4E, 0x42, 0x43, 0x55, 0x61, 0x71, 0x78, 0x45, 0x6C, 0x71, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x77, 0x46, 0x41, 0x44, 0x42, ++ 0x48, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, 0x0A, 0x55, 0x7A, 0x45, 0x69, 0x4D, 0x43, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x5A, 0x52, 0x32, 0x39, 0x76, 0x5A, 0x32, ++ 0x78, 0x6C, 0x49, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x49, 0x46, 0x4E, 0x6C, 0x63, 0x6E, 0x5A, 0x70, 0x59, 0x32, 0x56, 0x7A, 0x49, 0x45, 0x78, 0x4D, 0x51, 0x7A, 0x45, 0x55, 0x4D, 0x42, 0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, ++ 0x4D, 0x4C, 0x52, 0x31, 0x52, 0x54, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x0A, 0x55, 0x6A, 0x49, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x54, 0x59, 0x77, 0x4E, 0x6A, 0x49, 0x79, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x57, ++ 0x68, 0x63, 0x4E, 0x4D, 0x7A, 0x59, 0x77, 0x4E, 0x6A, 0x49, 0x79, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x57, 0x6A, 0x42, 0x48, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, 0x55, ++ 0x7A, 0x45, 0x69, 0x4D, 0x43, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0A, 0x43, 0x68, 0x4D, 0x5A, 0x52, 0x32, 0x39, 0x76, 0x5A, 0x32, 0x78, 0x6C, 0x49, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x49, 0x46, 0x4E, 0x6C, 0x63, 0x6E, 0x5A, 0x70, ++ 0x59, 0x32, 0x56, 0x7A, 0x49, 0x45, 0x78, 0x4D, 0x51, 0x7A, 0x45, 0x55, 0x4D, 0x42, 0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x4C, 0x52, 0x31, 0x52, 0x54, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x55, 0x6A, 0x49, 0x77, ++ 0x67, 0x67, 0x49, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x0A, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, ++ 0x43, 0x41, 0x51, 0x44, 0x4F, 0x33, 0x76, 0x32, 0x6D, 0x2B, 0x2B, 0x7A, 0x73, 0x46, 0x44, 0x51, 0x38, 0x42, 0x77, 0x5A, 0x61, 0x62, 0x46, 0x6E, 0x33, 0x47, 0x54, 0x58, 0x64, 0x39, 0x38, 0x47, 0x64, 0x56, 0x61, 0x72, 0x54, 0x7A, 0x54, 0x75, ++ 0x6B, 0x6B, 0x33, 0x4C, 0x76, 0x0A, 0x43, 0x76, 0x70, 0x74, 0x6E, 0x66, 0x62, 0x77, 0x68, 0x59, 0x42, 0x62, 0x6F, 0x55, 0x68, 0x53, 0x6E, 0x7A, 0x6E, 0x46, 0x74, 0x2B, 0x34, 0x6F, 0x72, 0x4F, 0x2F, 0x4C, 0x64, 0x6D, 0x67, 0x55, 0x75, 0x64, ++ 0x2B, 0x74, 0x41, 0x57, 0x79, 0x5A, 0x48, 0x38, 0x51, 0x69, 0x48, 0x5A, 0x2F, 0x2B, 0x63, 0x6E, 0x66, 0x67, 0x4C, 0x46, 0x75, 0x76, 0x35, 0x41, 0x53, 0x2F, 0x54, 0x33, 0x4B, 0x67, 0x47, 0x6A, 0x53, 0x59, 0x36, 0x44, 0x6C, 0x6F, 0x37, 0x4A, ++ 0x55, 0x6C, 0x0A, 0x65, 0x33, 0x61, 0x68, 0x35, 0x6D, 0x6D, 0x35, 0x68, 0x52, 0x6D, 0x39, 0x69, 0x59, 0x7A, 0x2B, 0x72, 0x65, 0x30, 0x32, 0x36, 0x6E, 0x4F, 0x38, 0x2F, 0x34, 0x50, 0x69, 0x79, 0x33, 0x33, 0x42, 0x30, 0x73, 0x35, 0x4B, 0x73, ++ 0x34, 0x30, 0x46, 0x6E, 0x6F, 0x74, 0x4A, 0x6B, 0x39, 0x2F, 0x42, 0x57, 0x39, 0x42, 0x75, 0x58, 0x76, 0x41, 0x75, 0x4D, 0x43, 0x36, 0x43, 0x2F, 0x50, 0x71, 0x38, 0x74, 0x42, 0x63, 0x4B, 0x53, 0x4F, 0x57, 0x49, 0x6D, 0x38, 0x57, 0x62, 0x0A, ++ 0x61, 0x39, 0x36, 0x77, 0x79, 0x72, 0x51, 0x44, 0x38, 0x4E, 0x72, 0x30, 0x6B, 0x4C, 0x68, 0x6C, 0x5A, 0x50, 0x64, 0x63, 0x54, 0x4B, 0x33, 0x6F, 0x66, 0x6D, 0x5A, 0x65, 0x6D, 0x64, 0x65, 0x34, 0x77, 0x6A, 0x37, 0x49, 0x30, 0x42, 0x4F, 0x64, ++ 0x72, 0x65, 0x37, 0x6B, 0x52, 0x58, 0x75, 0x4A, 0x56, 0x66, 0x65, 0x4B, 0x48, 0x32, 0x4A, 0x53, 0x68, 0x42, 0x4B, 0x7A, 0x77, 0x6B, 0x43, 0x58, 0x34, 0x34, 0x6F, 0x66, 0x52, 0x35, 0x47, 0x6D, 0x64, 0x46, 0x72, 0x53, 0x0A, 0x2B, 0x4C, 0x46, ++ 0x6A, 0x4B, 0x42, 0x43, 0x34, 0x73, 0x77, 0x6D, 0x34, 0x56, 0x6E, 0x64, 0x41, 0x6F, 0x69, 0x61, 0x59, 0x65, 0x63, 0x62, 0x2B, 0x33, 0x79, 0x58, 0x75, 0x50, 0x75, 0x57, 0x67, 0x66, 0x39, 0x52, 0x68, 0x44, 0x31, 0x46, 0x4C, 0x50, 0x44, 0x2B, ++ 0x4D, 0x32, 0x75, 0x46, 0x77, 0x64, 0x4E, 0x6A, 0x43, 0x61, 0x4B, 0x48, 0x35, 0x77, 0x51, 0x7A, 0x70, 0x6F, 0x65, 0x4A, 0x2F, 0x75, 0x31, 0x55, 0x38, 0x64, 0x67, 0x62, 0x75, 0x61, 0x6B, 0x37, 0x4D, 0x0A, 0x6B, 0x6F, 0x67, 0x77, 0x54, 0x5A, ++ 0x71, 0x39, 0x54, 0x77, 0x74, 0x49, 0x6D, 0x6F, 0x53, 0x31, 0x6D, 0x4B, 0x50, 0x56, 0x2B, 0x33, 0x50, 0x42, 0x56, 0x32, 0x48, 0x64, 0x4B, 0x46, 0x5A, 0x31, 0x45, 0x36, 0x36, 0x48, 0x6A, 0x75, 0x63, 0x4D, 0x55, 0x51, 0x6B, 0x51, 0x64, 0x59, ++ 0x68, 0x4D, 0x76, 0x49, 0x33, 0x35, 0x65, 0x7A, 0x7A, 0x55, 0x49, 0x6B, 0x67, 0x66, 0x4B, 0x74, 0x7A, 0x72, 0x61, 0x37, 0x74, 0x45, 0x73, 0x63, 0x73, 0x7A, 0x63, 0x54, 0x4A, 0x47, 0x0A, 0x72, 0x36, 0x31, 0x4B, 0x38, 0x59, 0x7A, 0x6F, 0x64, ++ 0x44, 0x71, 0x73, 0x35, 0x78, 0x6F, 0x69, 0x63, 0x34, 0x44, 0x53, 0x4D, 0x50, 0x63, 0x6C, 0x51, 0x73, 0x63, 0x69, 0x4F, 0x7A, 0x73, 0x53, 0x72, 0x5A, 0x59, 0x75, 0x78, 0x73, 0x4E, 0x32, 0x42, 0x36, 0x6F, 0x67, 0x74, 0x7A, 0x56, 0x4A, 0x56, ++ 0x2B, 0x6D, 0x53, 0x53, 0x65, 0x68, 0x32, 0x46, 0x6E, 0x49, 0x78, 0x5A, 0x79, 0x75, 0x57, 0x66, 0x6F, 0x71, 0x6A, 0x78, 0x35, 0x52, 0x57, 0x49, 0x72, 0x39, 0x71, 0x0A, 0x53, 0x33, 0x34, 0x42, 0x49, 0x62, 0x49, 0x6A, 0x4D, 0x74, 0x2F, 0x6B, ++ 0x6D, 0x6B, 0x52, 0x74, 0x57, 0x56, 0x74, 0x64, 0x39, 0x51, 0x43, 0x67, 0x48, 0x4A, 0x76, 0x47, 0x65, 0x4A, 0x65, 0x4E, 0x6B, 0x50, 0x2B, 0x62, 0x79, 0x4B, 0x71, 0x30, 0x72, 0x78, 0x46, 0x52, 0x4F, 0x56, 0x37, 0x5A, 0x2B, 0x32, 0x65, 0x74, ++ 0x31, 0x56, 0x73, 0x52, 0x6E, 0x54, 0x4B, 0x61, 0x47, 0x37, 0x33, 0x56, 0x75, 0x6C, 0x75, 0x6C, 0x79, 0x63, 0x73, 0x6C, 0x61, 0x56, 0x4E, 0x56, 0x0A, 0x4A, 0x31, 0x7A, 0x67, 0x79, 0x6A, 0x62, 0x4C, 0x69, 0x47, 0x48, 0x37, 0x48, 0x72, 0x66, ++ 0x51, 0x79, 0x2B, 0x34, 0x57, 0x2B, 0x39, 0x4F, 0x6D, 0x54, 0x4E, 0x36, 0x53, 0x70, 0x64, 0x54, 0x69, 0x33, 0x2F, 0x55, 0x47, 0x56, 0x4E, 0x34, 0x75, 0x6E, 0x55, 0x75, 0x30, 0x6B, 0x7A, 0x43, 0x71, 0x67, 0x63, 0x37, 0x64, 0x47, 0x74, 0x78, ++ 0x52, 0x63, 0x77, 0x31, 0x50, 0x63, 0x4F, 0x6E, 0x6C, 0x74, 0x68, 0x59, 0x68, 0x47, 0x58, 0x6D, 0x79, 0x35, 0x6F, 0x6B, 0x4C, 0x0A, 0x64, 0x57, 0x54, 0x4B, 0x31, 0x61, 0x75, 0x38, 0x43, 0x63, 0x45, 0x59, 0x6F, 0x66, 0x2F, 0x55, 0x56, 0x4B, ++ 0x47, 0x46, 0x50, 0x50, 0x30, 0x55, 0x4A, 0x41, 0x4F, 0x79, 0x68, 0x39, 0x4F, 0x6B, 0x74, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6F, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, ++ 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x59, 0x59, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x0A, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, ++ 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x75, 0x2F, 0x2F, 0x4B, 0x6A, 0x69, 0x4F, 0x66, 0x54, 0x35, 0x6E, 0x4B, 0x32, 0x2B, 0x4A, 0x6F, 0x70, 0x71, 0x55, 0x56, 0x4A, 0x78, 0x63, 0x65, 0x32, 0x51, 0x34, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, ++ 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4D, 0x42, 0x51, 0x41, 0x44, 0x0A, 0x67, 0x67, 0x49, 0x42, 0x41, 0x42, 0x2F, 0x4B, 0x7A, 0x74, 0x33, 0x48, 0x76, 0x71, 0x47, 0x66, 0x32, 0x53, 0x64, 0x4D, 0x43, 0x39, 0x77, 0x58, ++ 0x6D, 0x42, 0x46, 0x71, 0x69, 0x4E, 0x34, 0x39, 0x35, 0x6E, 0x46, 0x57, 0x63, 0x72, 0x4B, 0x65, 0x47, 0x6B, 0x36, 0x63, 0x31, 0x53, 0x75, 0x59, 0x4A, 0x46, 0x32, 0x62, 0x61, 0x33, 0x75, 0x77, 0x4D, 0x34, 0x49, 0x4A, 0x76, 0x64, 0x38, 0x6C, ++ 0x52, 0x75, 0x71, 0x59, 0x6E, 0x72, 0x59, 0x62, 0x2F, 0x6F, 0x4D, 0x38, 0x0A, 0x30, 0x6D, 0x4A, 0x68, 0x77, 0x51, 0x54, 0x74, 0x7A, 0x75, 0x44, 0x46, 0x79, 0x63, 0x67, 0x54, 0x45, 0x31, 0x58, 0x6E, 0x71, 0x47, 0x4F, 0x74, 0x6A, 0x48, 0x73, ++ 0x42, 0x2F, 0x6E, 0x63, 0x77, 0x34, 0x63, 0x35, 0x6F, 0x6D, 0x77, 0x58, 0x34, 0x45, 0x75, 0x35, 0x35, 0x4D, 0x61, 0x42, 0x42, 0x52, 0x54, 0x55, 0x6F, 0x43, 0x6E, 0x47, 0x6B, 0x4A, 0x45, 0x2B, 0x4D, 0x33, 0x44, 0x79, 0x43, 0x42, 0x31, 0x39, ++ 0x6D, 0x33, 0x48, 0x30, 0x51, 0x2F, 0x67, 0x78, 0x68, 0x0A, 0x73, 0x77, 0x57, 0x56, 0x37, 0x75, 0x47, 0x75, 0x67, 0x51, 0x2B, 0x6F, 0x2B, 0x4D, 0x65, 0x50, 0x54, 0x61, 0x67, 0x6A, 0x41, 0x69, 0x5A, 0x72, 0x48, 0x59, 0x4E, 0x53, 0x56, 0x63, ++ 0x36, 0x31, 0x4C, 0x77, 0x44, 0x4B, 0x67, 0x45, 0x44, 0x67, 0x34, 0x58, 0x53, 0x73, 0x59, 0x50, 0x57, 0x48, 0x67, 0x4A, 0x32, 0x75, 0x4E, 0x6D, 0x53, 0x52, 0x58, 0x62, 0x42, 0x6F, 0x47, 0x4F, 0x71, 0x4B, 0x59, 0x63, 0x6C, 0x33, 0x71, 0x4A, ++ 0x66, 0x45, 0x79, 0x63, 0x65, 0x6C, 0x0A, 0x2F, 0x46, 0x56, 0x4C, 0x38, 0x2F, 0x42, 0x2F, 0x75, 0x57, 0x55, 0x39, 0x4A, 0x32, 0x6A, 0x51, 0x7A, 0x47, 0x76, 0x36, 0x55, 0x35, 0x33, 0x68, 0x6B, 0x52, 0x72, 0x4A, 0x58, 0x52, 0x71, 0x57, 0x62, ++ 0x54, 0x4B, 0x48, 0x37, 0x51, 0x4D, 0x67, 0x79, 0x41, 0x4C, 0x4F, 0x57, 0x72, 0x37, 0x5A, 0x36, 0x76, 0x32, 0x79, 0x54, 0x63, 0x51, 0x76, 0x47, 0x39, 0x39, 0x66, 0x65, 0x76, 0x58, 0x34, 0x69, 0x38, 0x62, 0x75, 0x4D, 0x54, 0x6F, 0x6C, 0x55, ++ 0x56, 0x56, 0x6E, 0x0A, 0x6A, 0x57, 0x51, 0x79, 0x65, 0x2B, 0x6D, 0x65, 0x77, 0x34, 0x4B, 0x36, 0x4B, 0x69, 0x33, 0x70, 0x48, 0x72, 0x54, 0x67, 0x53, 0x41, 0x61, 0x69, 0x2F, 0x47, 0x65, 0x76, 0x48, 0x79, 0x49, 0x43, 0x63, 0x2F, 0x73, 0x67, ++ 0x43, 0x71, 0x2B, 0x64, 0x56, 0x45, 0x75, 0x68, 0x7A, 0x66, 0x39, 0x67, 0x52, 0x37, 0x41, 0x2F, 0x58, 0x65, 0x38, 0x62, 0x56, 0x72, 0x32, 0x58, 0x49, 0x5A, 0x59, 0x74, 0x43, 0x74, 0x46, 0x65, 0x6E, 0x54, 0x67, 0x43, 0x52, 0x32, 0x79, 0x35, ++ 0x0A, 0x39, 0x50, 0x59, 0x6A, 0x4A, 0x62, 0x69, 0x67, 0x61, 0x70, 0x6F, 0x72, 0x64, 0x77, 0x6A, 0x36, 0x78, 0x4C, 0x45, 0x6F, 0x6B, 0x43, 0x5A, 0x59, 0x43, 0x44, 0x7A, 0x69, 0x66, 0x71, 0x72, 0x58, 0x50, 0x57, 0x2B, 0x36, 0x4D, 0x59, 0x67, ++ 0x4B, 0x42, 0x65, 0x73, 0x6E, 0x74, 0x61, 0x46, 0x4A, 0x37, 0x71, 0x42, 0x46, 0x56, 0x48, 0x76, 0x6D, 0x4A, 0x32, 0x57, 0x5A, 0x49, 0x43, 0x47, 0x6F, 0x6F, 0x37, 0x7A, 0x37, 0x47, 0x4A, 0x61, 0x37, 0x55, 0x6D, 0x38, 0x4D, 0x0A, 0x37, 0x59, ++ 0x4E, 0x52, 0x54, 0x4F, 0x6C, 0x5A, 0x34, 0x69, 0x42, 0x67, 0x78, 0x63, 0x4A, 0x6C, 0x6B, 0x6F, 0x4B, 0x4D, 0x38, 0x78, 0x41, 0x66, 0x44, 0x6F, 0x71, 0x58, 0x76, 0x6E, 0x65, 0x43, 0x62, 0x54, 0x2B, 0x50, 0x48, 0x56, 0x32, 0x38, 0x53, 0x53, ++ 0x65, 0x39, 0x7A, 0x45, 0x38, 0x50, 0x34, 0x63, 0x35, 0x32, 0x68, 0x67, 0x51, 0x6A, 0x78, 0x63, 0x43, 0x4D, 0x45, 0x6C, 0x76, 0x39, 0x32, 0x34, 0x53, 0x67, 0x4A, 0x50, 0x46, 0x49, 0x2F, 0x32, 0x52, 0x38, 0x0A, 0x30, 0x4C, 0x35, 0x63, 0x46, ++ 0x74, 0x48, 0x76, 0x6D, 0x61, 0x33, 0x41, 0x48, 0x2F, 0x76, 0x4C, 0x72, 0x72, 0x77, 0x34, 0x49, 0x67, 0x59, 0x6D, 0x5A, 0x4E, 0x72, 0x61, 0x6C, 0x77, 0x34, 0x2F, 0x4B, 0x42, 0x56, 0x45, 0x71, 0x45, 0x38, 0x41, 0x79, 0x76, 0x43, 0x61, 0x7A, ++ 0x4D, 0x39, 0x30, 0x61, 0x72, 0x51, 0x2B, 0x50, 0x4F, 0x75, 0x56, 0x37, 0x4C, 0x58, 0x54, 0x57, 0x74, 0x69, 0x42, 0x6D, 0x65, 0x6C, 0x44, 0x47, 0x44, 0x66, 0x72, 0x73, 0x37, 0x76, 0x52, 0x0A, 0x57, 0x47, 0x4A, 0x42, 0x38, 0x32, 0x62, 0x53, ++ 0x6A, 0x36, 0x70, 0x34, 0x6C, 0x56, 0x51, 0x67, 0x77, 0x31, 0x6F, 0x75, 0x64, 0x43, 0x76, 0x56, 0x30, 0x62, 0x34, 0x59, 0x61, 0x63, 0x43, 0x73, 0x31, 0x61, 0x54, 0x50, 0x4F, 0x62, 0x70, 0x52, 0x68, 0x41, 0x4E, 0x6C, 0x36, 0x57, 0x4C, 0x41, ++ 0x59, 0x76, 0x37, 0x59, 0x54, 0x56, 0x57, 0x57, 0x34, 0x74, 0x41, 0x52, 0x2B, 0x6B, 0x67, 0x30, 0x45, 0x65, 0x79, 0x65, 0x37, 0x51, 0x55, 0x64, 0x35, 0x4D, 0x6A, 0x57, 0x0A, 0x48, 0x59, 0x62, 0x4C, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, ++ 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x33, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x43, 0x54, 0x43, ++ 0x43, 0x41, 0x59, 0x36, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x4E, 0x41, 0x67, 0x50, 0x6C, 0x75, 0x49, 0x4C, 0x72, 0x49, 0x50, 0x67, 0x6C, 0x4A, 0x32, 0x30, 0x39, 0x5A, 0x6A, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, ++ 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x7A, 0x42, 0x48, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x69, 0x0A, 0x4D, 0x43, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, ++ 0x4D, 0x5A, 0x52, 0x32, 0x39, 0x76, 0x5A, 0x32, 0x78, 0x6C, 0x49, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x49, 0x46, 0x4E, 0x6C, 0x63, 0x6E, 0x5A, 0x70, 0x59, 0x32, 0x56, 0x7A, 0x49, 0x45, 0x78, 0x4D, 0x51, 0x7A, 0x45, 0x55, 0x4D, 0x42, ++ 0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x4C, 0x52, 0x31, 0x52, 0x54, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x55, 0x6A, 0x4D, 0x77, 0x0A, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x54, 0x59, 0x77, 0x4E, 0x6A, 0x49, 0x79, 0x4D, ++ 0x44, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x57, 0x68, 0x63, 0x4E, 0x4D, 0x7A, 0x59, 0x77, 0x4E, 0x6A, 0x49, 0x79, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x57, 0x6A, 0x42, 0x48, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, ++ 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x69, 0x4D, 0x43, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x5A, 0x0A, 0x52, 0x32, 0x39, 0x76, 0x5A, 0x32, 0x78, 0x6C, 0x49, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, ++ 0x49, 0x46, 0x4E, 0x6C, 0x63, 0x6E, 0x5A, 0x70, 0x59, 0x32, 0x56, 0x7A, 0x49, 0x45, 0x78, 0x4D, 0x51, 0x7A, 0x45, 0x55, 0x4D, 0x42, 0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x4C, 0x52, 0x31, 0x52, 0x54, 0x49, 0x46, 0x4A, 0x76, ++ 0x62, 0x33, 0x51, 0x67, 0x55, 0x6A, 0x4D, 0x77, 0x64, 0x6A, 0x41, 0x51, 0x42, 0x67, 0x63, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x0A, 0x50, 0x51, 0x49, 0x42, 0x42, 0x67, 0x55, 0x72, 0x67, 0x51, 0x51, 0x41, 0x49, 0x67, 0x4E, 0x69, 0x41, 0x41, 0x51, ++ 0x66, 0x54, 0x7A, 0x4F, 0x48, 0x4D, 0x79, 0x6D, 0x4B, 0x6F, 0x59, 0x54, 0x65, 0x79, 0x38, 0x63, 0x68, 0x57, 0x45, 0x47, 0x4A, 0x36, 0x6C, 0x61, 0x64, 0x4B, 0x30, 0x75, 0x46, 0x78, 0x68, 0x31, 0x4D, 0x4A, 0x37, 0x78, 0x2F, 0x4A, 0x6C, 0x46, ++ 0x79, 0x62, 0x2B, 0x4B, 0x66, 0x31, 0x71, 0x50, 0x4B, 0x7A, 0x45, 0x55, 0x55, 0x52, 0x6F, 0x75, 0x74, 0x0A, 0x37, 0x33, 0x36, 0x47, 0x6A, 0x4F, 0x79, 0x78, 0x66, 0x69, 0x2F, 0x2F, 0x71, 0x58, 0x47, 0x64, 0x47, 0x49, 0x52, 0x46, 0x42, 0x45, ++ 0x46, 0x56, 0x62, 0x69, 0x76, 0x71, 0x4A, 0x6E, 0x2B, 0x37, 0x6B, 0x41, 0x48, 0x6A, 0x53, 0x78, 0x6D, 0x36, 0x35, 0x46, 0x53, 0x57, 0x52, 0x51, 0x6D, 0x78, 0x31, 0x57, 0x79, 0x52, 0x52, 0x4B, 0x32, 0x45, 0x45, 0x34, 0x36, 0x61, 0x6A, 0x41, ++ 0x32, 0x41, 0x44, 0x44, 0x4C, 0x32, 0x34, 0x43, 0x65, 0x6A, 0x51, 0x6A, 0x42, 0x41, 0x0A, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x68, 0x6A, 0x41, 0x50, 0x42, ++ 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x54, 0x42, 0x38, 0x53, 0x61, 0x36, 0x6F, ++ 0x43, 0x32, 0x75, 0x68, 0x59, 0x48, 0x50, 0x30, 0x2F, 0x45, 0x71, 0x0A, 0x45, 0x72, 0x32, 0x34, 0x43, 0x6D, 0x66, 0x39, 0x76, 0x44, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x77, 0x4E, 0x70, ++ 0x41, 0x44, 0x42, 0x6D, 0x41, 0x6A, 0x45, 0x41, 0x39, 0x75, 0x45, 0x67, 0x6C, 0x52, 0x52, 0x37, 0x56, 0x4B, 0x4F, 0x51, 0x46, 0x68, 0x47, 0x2F, 0x68, 0x4D, 0x6A, 0x71, 0x62, 0x32, 0x73, 0x58, 0x6E, 0x68, 0x35, 0x47, 0x6D, 0x43, 0x43, 0x62, ++ 0x6E, 0x39, 0x4D, 0x4E, 0x32, 0x61, 0x7A, 0x54, 0x0A, 0x4C, 0x38, 0x31, 0x38, 0x2B, 0x46, 0x73, 0x75, 0x56, 0x62, 0x75, 0x2F, 0x33, 0x5A, 0x4C, 0x33, 0x70, 0x41, 0x7A, 0x63, 0x4D, 0x65, 0x47, 0x69, 0x41, 0x6A, 0x45, 0x41, 0x2F, 0x4A, 0x64, ++ 0x6D, 0x5A, 0x75, 0x56, 0x44, 0x46, 0x68, 0x4F, 0x44, 0x33, 0x63, 0x66, 0x66, 0x4C, 0x37, 0x34, 0x55, 0x4F, 0x4F, 0x30, 0x42, 0x7A, 0x72, 0x45, 0x58, 0x47, 0x68, 0x46, 0x31, 0x36, 0x62, 0x30, 0x44, 0x6A, 0x79, 0x5A, 0x2B, 0x68, 0x4F, 0x58, ++ 0x4A, 0x59, 0x4B, 0x61, 0x56, 0x0A, 0x31, 0x31, 0x52, 0x5A, 0x74, 0x2B, 0x63, 0x52, 0x4C, 0x49, 0x6E, 0x55, 0x75, 0x65, 0x34, 0x58, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, ++ 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x34, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, ++ 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x43, 0x54, 0x43, 0x43, 0x41, 0x59, 0x36, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, ++ 0x49, 0x4E, 0x41, 0x67, 0x50, 0x6C, 0x77, 0x47, 0x6A, 0x76, 0x59, 0x78, 0x71, 0x63, 0x63, 0x70, 0x42, 0x51, 0x55, 0x6A, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x7A, 0x42, 0x48, 0x4D, 0x51, ++ 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x69, 0x0A, 0x4D, 0x43, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x5A, 0x52, 0x32, 0x39, 0x76, 0x5A, 0x32, 0x78, 0x6C, 0x49, ++ 0x46, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x49, 0x46, 0x4E, 0x6C, 0x63, 0x6E, 0x5A, 0x70, 0x59, 0x32, 0x56, 0x7A, 0x49, 0x45, 0x78, 0x4D, 0x51, 0x7A, 0x45, 0x55, 0x4D, 0x42, 0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x4C, 0x52, ++ 0x31, 0x52, 0x54, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x55, 0x6A, 0x51, 0x77, 0x0A, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x54, 0x59, 0x77, 0x4E, 0x6A, 0x49, 0x79, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x57, 0x68, 0x63, 0x4E, ++ 0x4D, 0x7A, 0x59, 0x77, 0x4E, 0x6A, 0x49, 0x79, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x57, 0x6A, 0x42, 0x48, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x69, ++ 0x4D, 0x43, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x5A, 0x0A, 0x52, 0x32, 0x39, 0x76, 0x5A, 0x32, 0x78, 0x6C, 0x49, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x49, 0x46, 0x4E, 0x6C, 0x63, 0x6E, 0x5A, 0x70, 0x59, 0x32, 0x56, ++ 0x7A, 0x49, 0x45, 0x78, 0x4D, 0x51, 0x7A, 0x45, 0x55, 0x4D, 0x42, 0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x4C, 0x52, 0x31, 0x52, 0x54, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x55, 0x6A, 0x51, 0x77, 0x64, 0x6A, 0x41, ++ 0x51, 0x42, 0x67, 0x63, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x0A, 0x50, 0x51, 0x49, 0x42, 0x42, 0x67, 0x55, 0x72, 0x67, 0x51, 0x51, 0x41, 0x49, 0x67, 0x4E, 0x69, 0x41, 0x41, 0x54, 0x7A, 0x64, 0x48, 0x4F, 0x6E, 0x61, 0x49, 0x74, 0x67, 0x72, 0x6B, ++ 0x4F, 0x34, 0x4E, 0x63, 0x57, 0x42, 0x4D, 0x48, 0x74, 0x4C, 0x53, 0x5A, 0x33, 0x37, 0x77, 0x57, 0x48, 0x4F, 0x35, 0x74, 0x35, 0x47, 0x76, 0x57, 0x76, 0x56, 0x59, 0x52, 0x67, 0x31, 0x72, 0x6B, 0x44, 0x64, 0x63, 0x2F, 0x65, 0x4A, 0x6B, 0x54, ++ 0x42, 0x61, 0x36, 0x7A, 0x7A, 0x75, 0x0A, 0x68, 0x58, 0x79, 0x69, 0x51, 0x48, 0x59, 0x37, 0x71, 0x63, 0x61, 0x34, 0x52, 0x39, 0x67, 0x71, 0x35, 0x35, 0x4B, 0x52, 0x61, 0x6E, 0x50, 0x70, 0x73, 0x58, 0x49, 0x35, 0x6E, 0x79, 0x6D, 0x66, 0x6F, ++ 0x70, 0x6A, 0x54, 0x58, 0x31, 0x35, 0x59, 0x68, 0x6D, 0x55, 0x50, 0x6F, 0x59, 0x52, 0x6C, 0x42, 0x74, 0x48, 0x63, 0x69, 0x38, 0x6E, 0x48, 0x63, 0x38, 0x69, 0x4D, 0x61, 0x69, 0x2F, 0x6C, 0x78, 0x4B, 0x76, 0x52, 0x48, 0x59, 0x71, 0x6A, 0x51, ++ 0x6A, 0x42, 0x41, 0x0A, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x68, 0x6A, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, ++ 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x53, 0x41, 0x54, 0x4E, 0x62, 0x72, 0x64, 0x50, 0x39, 0x4A, 0x4E, 0x71, 0x50, 0x56, 0x32, 0x50, 0x79, 0x31, ++ 0x0A, 0x50, 0x73, 0x56, 0x71, 0x38, 0x4A, 0x51, 0x64, 0x6A, 0x44, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x77, 0x4E, 0x70, 0x41, 0x44, 0x42, 0x6D, 0x41, 0x6A, 0x45, 0x41, 0x36, 0x45, 0x44, ++ 0x2F, 0x67, 0x39, 0x34, 0x44, 0x39, 0x4A, 0x2B, 0x75, 0x48, 0x58, 0x71, 0x6E, 0x4C, 0x72, 0x6D, 0x76, 0x54, 0x2F, 0x61, 0x44, 0x48, 0x51, 0x34, 0x74, 0x68, 0x51, 0x45, 0x64, 0x30, 0x64, 0x6C, 0x71, 0x37, 0x41, 0x2F, 0x43, 0x0A, 0x72, 0x38, ++ 0x64, 0x65, 0x56, 0x6C, 0x35, 0x63, 0x31, 0x52, 0x78, 0x59, 0x49, 0x69, 0x67, 0x4C, 0x39, 0x7A, 0x43, 0x32, 0x4C, 0x37, 0x46, 0x38, 0x41, 0x6A, 0x45, 0x41, 0x38, 0x47, 0x45, 0x38, 0x70, 0x2F, 0x53, 0x67, 0x67, 0x75, 0x4D, 0x68, 0x31, 0x59, ++ 0x51, 0x64, 0x63, 0x34, 0x61, 0x63, 0x4C, 0x61, 0x2F, 0x4B, 0x4E, 0x4A, 0x76, 0x78, 0x6E, 0x37, 0x6B, 0x6A, 0x4E, 0x75, 0x4B, 0x38, 0x59, 0x41, 0x4F, 0x64, 0x67, 0x4C, 0x4F, 0x61, 0x56, 0x73, 0x6A, 0x68, 0x0A, 0x34, 0x72, 0x73, 0x55, 0x65, ++ 0x63, 0x72, 0x4E, 0x49, 0x64, 0x53, 0x55, 0x74, 0x55, 0x6C, 0x44, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x54, ++ 0x65, 0x6C, 0x69, 0x61, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x76, 0x32, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, ++ 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x64, 0x44, 0x43, 0x43, 0x41, 0x31, 0x79, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, ++ 0x50, 0x41, 0x57, 0x64, 0x66, 0x4A, 0x39, 0x62, 0x2B, 0x65, 0x75, 0x50, 0x6B, 0x72, 0x4C, 0x34, 0x4A, 0x57, 0x77, 0x57, 0x65, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43, 0x77, 0x55, ++ 0x41, 0x4D, 0x45, 0x51, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x0A, 0x41, 0x6B, 0x5A, 0x4A, 0x4D, 0x52, 0x6F, 0x77, 0x47, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x44, 0x42, 0x46, 0x55, 0x5A, 0x57, ++ 0x78, 0x70, 0x59, 0x53, 0x42, 0x47, 0x61, 0x57, 0x35, 0x73, 0x59, 0x57, 0x35, 0x6B, 0x49, 0x45, 0x39, 0x35, 0x61, 0x6A, 0x45, 0x5A, 0x4D, 0x42, 0x63, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x51, 0x56, 0x47, 0x56, 0x73, 0x61, 0x57, ++ 0x45, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x53, 0x42, 0x32, 0x0A, 0x4D, 0x6A, 0x41, 0x65, 0x46, 0x77, 0x30, 0x78, 0x4F, 0x44, 0x45, 0x78, 0x4D, 0x6A, 0x6B, 0x78, 0x4D, 0x54, 0x55, 0x31, 0x4E, 0x54, 0x52, 0x61, 0x46, ++ 0x77, 0x30, 0x30, 0x4D, 0x7A, 0x45, 0x78, 0x4D, 0x6A, 0x6B, 0x78, 0x4D, 0x54, 0x55, 0x31, 0x4E, 0x54, 0x52, 0x61, 0x4D, 0x45, 0x51, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x5A, 0x4A, 0x4D, ++ 0x52, 0x6F, 0x77, 0x47, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x0A, 0x44, 0x42, 0x46, 0x55, 0x5A, 0x57, 0x78, 0x70, 0x59, 0x53, 0x42, 0x47, 0x61, 0x57, 0x35, 0x73, 0x59, 0x57, 0x35, 0x6B, 0x49, 0x45, 0x39, 0x35, 0x61, 0x6A, 0x45, 0x5A, ++ 0x4D, 0x42, 0x63, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x51, 0x56, 0x47, 0x56, 0x73, 0x61, 0x57, 0x45, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x53, 0x42, 0x32, 0x4D, 0x6A, 0x43, 0x43, 0x41, 0x69, 0x49, 0x77, ++ 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x0A, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x67, 0x6F, 0x43, 0x67, 0x67, 0x49, 0x42, 0x41, 0x4C, 0x4C, ++ 0x51, 0x50, 0x77, 0x65, 0x38, 0x34, 0x6E, 0x76, 0x51, 0x61, 0x35, 0x6E, 0x34, 0x34, 0x6E, 0x64, 0x70, 0x35, 0x38, 0x36, 0x64, 0x70, 0x41, 0x4F, 0x38, 0x67, 0x6D, 0x32, 0x68, 0x2F, 0x6F, 0x46, 0x6C, 0x48, 0x30, 0x77, 0x6E, 0x72, 0x49, 0x34, ++ 0x41, 0x75, 0x68, 0x5A, 0x37, 0x0A, 0x36, 0x7A, 0x42, 0x71, 0x41, 0x4D, 0x43, 0x7A, 0x64, 0x47, 0x68, 0x2B, 0x73, 0x71, 0x2F, 0x48, 0x31, 0x57, 0x4B, 0x7A, 0x65, 0x6A, 0x39, 0x51, 0x79, 0x6F, 0x77, 0x32, 0x52, 0x43, 0x52, 0x6A, 0x30, 0x6A, ++ 0x62, 0x70, 0x44, 0x49, 0x58, 0x32, 0x51, 0x33, 0x62, 0x56, 0x54, 0x4B, 0x46, 0x67, 0x63, 0x6D, 0x66, 0x69, 0x4B, 0x44, 0x4F, 0x6C, 0x79, 0x7A, 0x47, 0x34, 0x4F, 0x69, 0x49, 0x6A, 0x4E, 0x4C, 0x68, 0x39, 0x76, 0x56, 0x59, 0x69, 0x51, 0x4A, ++ 0x33, 0x71, 0x0A, 0x39, 0x48, 0x73, 0x44, 0x72, 0x57, 0x6A, 0x38, 0x73, 0x6F, 0x46, 0x50, 0x6D, 0x4E, 0x42, 0x30, 0x36, 0x6F, 0x33, 0x6C, 0x66, 0x63, 0x31, 0x6A, 0x77, 0x36, 0x50, 0x32, 0x33, 0x70, 0x4C, 0x43, 0x57, 0x42, 0x6E, 0x67, 0x6C, ++ 0x72, 0x76, 0x46, 0x78, 0x4B, 0x6B, 0x39, 0x70, 0x58, 0x53, 0x57, 0x2F, 0x71, 0x2F, 0x35, 0x69, 0x61, 0x71, 0x39, 0x6C, 0x52, 0x64, 0x55, 0x32, 0x48, 0x68, 0x45, 0x38, 0x51, 0x78, 0x33, 0x46, 0x5A, 0x4C, 0x67, 0x6D, 0x45, 0x4B, 0x6E, 0x0A, ++ 0x70, 0x4E, 0x61, 0x71, 0x49, 0x4A, 0x4C, 0x4E, 0x77, 0x61, 0x43, 0x7A, 0x6C, 0x72, 0x49, 0x36, 0x68, 0x45, 0x4B, 0x4E, 0x66, 0x64, 0x57, 0x56, 0x35, 0x4E, 0x62, 0x62, 0x36, 0x57, 0x4C, 0x45, 0x57, 0x4C, 0x4E, 0x35, 0x78, 0x59, 0x7A, 0x54, ++ 0x4E, 0x54, 0x4F, 0x44, 0x6E, 0x33, 0x57, 0x68, 0x55, 0x69, 0x64, 0x68, 0x4F, 0x50, 0x46, 0x5A, 0x50, 0x59, 0x35, 0x51, 0x34, 0x4C, 0x31, 0x35, 0x50, 0x4F, 0x64, 0x73, 0x6C, 0x76, 0x35, 0x65, 0x32, 0x51, 0x4A, 0x6C, 0x0A, 0x74, 0x49, 0x35, ++ 0x63, 0x30, 0x42, 0x45, 0x30, 0x33, 0x31, 0x32, 0x2F, 0x55, 0x71, 0x65, 0x42, 0x41, 0x4D, 0x4E, 0x2F, 0x6D, 0x55, 0x57, 0x5A, 0x46, 0x64, 0x55, 0x58, 0x79, 0x41, 0x70, 0x54, 0x37, 0x47, 0x50, 0x7A, 0x6D, 0x58, 0x33, 0x4D, 0x61, 0x52, 0x4B, ++ 0x47, 0x77, 0x68, 0x66, 0x77, 0x41, 0x5A, 0x36, 0x2F, 0x68, 0x4C, 0x7A, 0x52, 0x55, 0x73, 0x73, 0x62, 0x6B, 0x6D, 0x62, 0x4F, 0x70, 0x46, 0x50, 0x6C, 0x6F, 0x62, 0x2F, 0x45, 0x32, 0x77, 0x6E, 0x57, 0x0A, 0x35, 0x6F, 0x6C, 0x57, 0x4B, 0x38, ++ 0x6A, 0x6A, 0x66, 0x4E, 0x37, 0x6A, 0x2F, 0x34, 0x6E, 0x6C, 0x4E, 0x57, 0x34, 0x6F, 0x36, 0x47, 0x77, 0x4C, 0x49, 0x31, 0x47, 0x70, 0x4A, 0x51, 0x58, 0x72, 0x53, 0x50, 0x6A, 0x64, 0x73, 0x63, 0x72, 0x36, 0x62, 0x41, 0x68, 0x52, 0x37, 0x37, ++ 0x63, 0x59, 0x62, 0x45, 0x54, 0x4B, 0x4A, 0x75, 0x46, 0x7A, 0x78, 0x6F, 0x6B, 0x47, 0x67, 0x65, 0x57, 0x4B, 0x72, 0x4C, 0x44, 0x69, 0x4B, 0x63, 0x61, 0x35, 0x4A, 0x4C, 0x4E, 0x72, 0x0A, 0x52, 0x42, 0x48, 0x30, 0x70, 0x55, 0x50, 0x43, 0x54, ++ 0x45, 0x50, 0x6C, 0x63, 0x44, 0x61, 0x4D, 0x74, 0x6A, 0x4E, 0x58, 0x65, 0x70, 0x55, 0x75, 0x67, 0x71, 0x44, 0x30, 0x58, 0x42, 0x43, 0x7A, 0x59, 0x59, 0x50, 0x32, 0x41, 0x67, 0x57, 0x47, 0x4C, 0x6E, 0x77, 0x74, 0x62, 0x4E, 0x77, 0x44, 0x52, ++ 0x6D, 0x34, 0x31, 0x6B, 0x39, 0x56, 0x36, 0x6C, 0x53, 0x2F, 0x65, 0x49, 0x4E, 0x68, 0x62, 0x66, 0x70, 0x53, 0x51, 0x42, 0x47, 0x71, 0x36, 0x57, 0x54, 0x30, 0x45, 0x0A, 0x42, 0x58, 0x57, 0x64, 0x4E, 0x36, 0x49, 0x4F, 0x4C, 0x6A, 0x33, 0x72, ++ 0x77, 0x61, 0x52, 0x53, 0x67, 0x2F, 0x37, 0x51, 0x61, 0x39, 0x52, 0x6D, 0x6A, 0x74, 0x7A, 0x47, 0x36, 0x52, 0x4A, 0x4F, 0x48, 0x53, 0x70, 0x58, 0x71, 0x68, 0x43, 0x38, 0x66, 0x46, 0x36, 0x43, 0x66, 0x61, 0x61, 0x6D, 0x79, 0x66, 0x49, 0x74, ++ 0x75, 0x66, 0x55, 0x58, 0x4A, 0x36, 0x33, 0x52, 0x44, 0x6F, 0x6C, 0x55, 0x4B, 0x35, 0x58, 0x36, 0x77, 0x4B, 0x30, 0x64, 0x6D, 0x42, 0x52, 0x34, 0x0A, 0x4D, 0x30, 0x4B, 0x47, 0x43, 0x71, 0x6C, 0x7A, 0x74, 0x66, 0x74, 0x30, 0x44, 0x62, 0x63, ++ 0x62, 0x4D, 0x42, 0x6E, 0x45, 0x57, 0x67, 0x34, 0x63, 0x4A, 0x37, 0x66, 0x61, 0x47, 0x4E, 0x44, 0x2F, 0x69, 0x73, 0x67, 0x46, 0x75, 0x76, 0x47, 0x71, 0x48, 0x4B, 0x49, 0x33, 0x74, 0x2B, 0x5A, 0x49, 0x70, 0x45, 0x59, 0x73, 0x6C, 0x4F, 0x71, ++ 0x6F, 0x64, 0x6D, 0x4A, 0x48, 0x69, 0x78, 0x42, 0x54, 0x42, 0x30, 0x68, 0x58, 0x62, 0x4F, 0x4B, 0x53, 0x54, 0x62, 0x61, 0x75, 0x0A, 0x42, 0x63, 0x76, 0x63, 0x77, 0x55, 0x70, 0x65, 0x6A, 0x36, 0x77, 0x39, 0x47, 0x55, 0x37, 0x43, 0x37, 0x57, ++ 0x42, 0x31, 0x4B, 0x39, 0x76, 0x42, 0x79, 0x6B, 0x4C, 0x56, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, 0x59, 0x7A, 0x42, 0x68, 0x4D, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x49, 0x77, 0x51, 0x59, 0x4D, 0x42, 0x61, 0x41, 0x46, 0x48, ++ 0x4B, 0x73, 0x35, 0x44, 0x4E, 0x35, 0x71, 0x6B, 0x57, 0x48, 0x39, 0x76, 0x32, 0x73, 0x48, 0x5A, 0x37, 0x57, 0x0A, 0x78, 0x79, 0x2B, 0x47, 0x32, 0x43, 0x51, 0x35, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, ++ 0x42, 0x52, 0x79, 0x72, 0x4F, 0x51, 0x7A, 0x65, 0x61, 0x70, 0x46, 0x68, 0x2F, 0x62, 0x39, 0x72, 0x42, 0x32, 0x65, 0x31, 0x73, 0x63, 0x76, 0x68, 0x74, 0x67, 0x6B, 0x4F, 0x54, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, ++ 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x51, 0x59, 0x77, 0x44, 0x77, 0x59, 0x44, 0x0A, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, ++ 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x67, 0x45, 0x41, 0x6F, 0x44, 0x74, 0x5A, 0x70, 0x77, 0x6D, 0x55, 0x50, 0x6A, 0x61, 0x45, 0x30, 0x6E, 0x34, 0x76, 0x4F, 0x61, 0x57, 0x57, ++ 0x6C, 0x2F, 0x6F, 0x52, 0x72, 0x66, 0x78, 0x6E, 0x38, 0x33, 0x45, 0x4A, 0x0A, 0x38, 0x72, 0x4B, 0x4A, 0x68, 0x47, 0x64, 0x45, 0x72, 0x37, 0x6E, 0x76, 0x37, 0x5A, 0x62, 0x73, 0x6E, 0x47, 0x54, 0x62, 0x4D, 0x6A, 0x42, 0x76, 0x5A, 0x35, 0x71, ++ 0x73, 0x66, 0x6C, 0x2B, 0x79, 0x71, 0x77, 0x45, 0x32, 0x66, 0x6F, 0x48, 0x36, 0x35, 0x49, 0x52, 0x65, 0x30, 0x71, 0x77, 0x32, 0x34, 0x47, 0x74, 0x69, 0x78, 0x58, 0x31, 0x4C, 0x44, 0x6F, 0x4A, 0x74, 0x30, 0x6E, 0x5A, 0x69, 0x30, 0x66, 0x36, ++ 0x58, 0x2B, 0x4A, 0x38, 0x77, 0x66, 0x42, 0x6A, 0x35, 0x0A, 0x74, 0x46, 0x4A, 0x33, 0x67, 0x68, 0x31, 0x32, 0x32, 0x39, 0x4D, 0x64, 0x71, 0x66, 0x44, 0x42, 0x6D, 0x67, 0x43, 0x39, 0x62, 0x58, 0x58, 0x59, 0x66, 0x65, 0x66, 0x36, 0x78, 0x7A, ++ 0x69, 0x6A, 0x6E, 0x48, 0x44, 0x6F, 0x52, 0x6E, 0x6B, 0x44, 0x72, 0x79, 0x35, 0x30, 0x32, 0x33, 0x58, 0x34, 0x62, 0x6C, 0x4D, 0x4D, 0x41, 0x38, 0x69, 0x5A, 0x47, 0x6F, 0x6B, 0x31, 0x47, 0x54, 0x7A, 0x54, 0x79, 0x56, 0x52, 0x38, 0x71, 0x50, ++ 0x41, 0x73, 0x35, 0x6D, 0x34, 0x48, 0x0A, 0x65, 0x57, 0x39, 0x71, 0x34, 0x65, 0x62, 0x71, 0x6B, 0x59, 0x4A, 0x70, 0x43, 0x68, 0x33, 0x44, 0x66, 0x6C, 0x6D, 0x69, 0x6E, 0x6D, 0x74, 0x47, 0x46, 0x5A, 0x68, 0x62, 0x30, 0x36, 0x39, 0x47, 0x48, ++ 0x57, 0x4C, 0x49, 0x7A, 0x6F, 0x42, 0x53, 0x53, 0x52, 0x45, 0x2F, 0x79, 0x51, 0x51, 0x53, 0x77, 0x78, 0x4E, 0x38, 0x50, 0x7A, 0x75, 0x4B, 0x6C, 0x74, 0x73, 0x38, 0x6F, 0x42, 0x34, 0x4B, 0x74, 0x49, 0x74, 0x55, 0x73, 0x69, 0x52, 0x6E, 0x44, ++ 0x65, 0x2B, 0x43, 0x0A, 0x79, 0x37, 0x34, 0x38, 0x66, 0x64, 0x48, 0x69, 0x66, 0x36, 0x34, 0x57, 0x31, 0x6C, 0x5A, 0x59, 0x75, 0x64, 0x6F, 0x67, 0x73, 0x59, 0x4D, 0x56, 0x6F, 0x65, 0x2B, 0x4B, 0x54, 0x54, 0x4A, 0x76, 0x51, 0x53, 0x38, 0x54, ++ 0x55, 0x6F, 0x4B, 0x55, 0x31, 0x78, 0x72, 0x42, 0x65, 0x4B, 0x4A, 0x52, 0x33, 0x53, 0x74, 0x77, 0x62, 0x62, 0x63, 0x61, 0x2B, 0x66, 0x65, 0x77, 0x34, 0x47, 0x65, 0x58, 0x56, 0x74, 0x74, 0x38, 0x59, 0x56, 0x4D, 0x4A, 0x41, 0x79, 0x67, 0x43, ++ 0x0A, 0x51, 0x4D, 0x65, 0x7A, 0x32, 0x50, 0x32, 0x63, 0x63, 0x47, 0x72, 0x47, 0x4B, 0x4D, 0x4F, 0x46, 0x36, 0x65, 0x4C, 0x74, 0x47, 0x70, 0x4F, 0x67, 0x33, 0x6B, 0x75, 0x59, 0x6F, 0x6F, 0x51, 0x2B, 0x42, 0x58, 0x63, 0x42, 0x6C, 0x6A, 0x33, ++ 0x37, 0x74, 0x43, 0x41, 0x50, 0x6E, 0x48, 0x49, 0x43, 0x65, 0x68, 0x49, 0x76, 0x31, 0x61, 0x4F, 0x36, 0x55, 0x58, 0x69, 0x76, 0x4B, 0x69, 0x74, 0x45, 0x5A, 0x55, 0x36, 0x31, 0x2F, 0x51, 0x72, 0x6F, 0x77, 0x63, 0x31, 0x35, 0x0A, 0x68, 0x32, ++ 0x45, 0x72, 0x33, 0x6F, 0x42, 0x58, 0x52, 0x62, 0x39, 0x6E, 0x38, 0x5A, 0x75, 0x52, 0x58, 0x71, 0x57, 0x6B, 0x37, 0x46, 0x6C, 0x49, 0x45, 0x41, 0x30, 0x34, 0x78, 0x37, 0x44, 0x36, 0x77, 0x30, 0x52, 0x74, 0x42, 0x50, 0x56, 0x34, 0x55, 0x42, ++ 0x79, 0x53, 0x6C, 0x6C, 0x76, 0x61, 0x39, 0x62, 0x67, 0x75, 0x75, 0x6C, 0x76, 0x50, 0x35, 0x66, 0x42, 0x71, 0x6E, 0x55, 0x73, 0x76, 0x57, 0x48, 0x4D, 0x74, 0x54, 0x79, 0x33, 0x45, 0x48, 0x44, 0x37, 0x30, 0x0A, 0x73, 0x7A, 0x2B, 0x72, 0x46, ++ 0x51, 0x34, 0x37, 0x47, 0x55, 0x47, 0x4B, 0x70, 0x4D, 0x46, 0x58, 0x45, 0x6D, 0x5A, 0x78, 0x54, 0x50, 0x70, 0x54, 0x34, 0x31, 0x66, 0x72, 0x59, 0x70, 0x55, 0x4A, 0x6E, 0x6C, 0x54, 0x64, 0x30, 0x63, 0x49, 0x38, 0x56, 0x7A, 0x79, 0x39, 0x4F, ++ 0x4B, 0x32, 0x59, 0x5A, 0x4C, 0x65, 0x34, 0x41, 0x35, 0x70, 0x54, 0x56, 0x6D, 0x42, 0x64, 0x73, 0x39, 0x68, 0x43, 0x47, 0x31, 0x78, 0x4C, 0x45, 0x6F, 0x6F, 0x63, 0x36, 0x2B, 0x74, 0x39, 0x0A, 0x78, 0x6E, 0x70, 0x70, 0x78, 0x79, 0x64, 0x2F, ++ 0x70, 0x50, 0x69, 0x4C, 0x38, 0x75, 0x53, 0x55, 0x5A, 0x6F, 0x64, 0x4C, 0x36, 0x5A, 0x51, 0x48, 0x43, 0x52, 0x4A, 0x35, 0x69, 0x72, 0x4C, 0x72, 0x64, 0x41, 0x54, 0x63, 0x7A, 0x76, 0x52, 0x45, 0x57, 0x65, 0x41, 0x57, 0x79, 0x73, 0x55, 0x73, ++ 0x57, 0x4E, 0x63, 0x38, 0x65, 0x38, 0x39, 0x69, 0x68, 0x6D, 0x70, 0x51, 0x66, 0x54, 0x55, 0x32, 0x5A, 0x71, 0x66, 0x37, 0x4E, 0x2B, 0x63, 0x6F, 0x78, 0x39, 0x6A, 0x51, 0x0A, 0x72, 0x61, 0x56, 0x70, 0x6C, 0x49, 0x2F, 0x6F, 0x77, 0x64, 0x38, ++ 0x6B, 0x2B, 0x42, 0x73, 0x48, 0x4D, 0x59, 0x65, 0x42, 0x32, 0x46, 0x33, 0x32, 0x36, 0x43, 0x6A, 0x59, 0x53, 0x6C, 0x4B, 0x41, 0x72, 0x42, 0x50, 0x75, 0x55, 0x42, 0x51, 0x65, 0x6D, 0x4D, 0x63, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, ++ 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x42, 0x52, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, ++ 0x31, 0x20, 0x32, 0x30, 0x32, 0x30, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, ++ 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x32, 0x7A, 0x43, 0x43, 0x41, 0x6D, 0x43, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, ++ 0x51, 0x66, 0x4D, 0x6D, 0x50, 0x4B, 0x34, 0x54, 0x58, 0x33, 0x2B, 0x6F, 0x50, 0x79, 0x57, 0x57, 0x61, 0x30, 0x30, 0x74, 0x4E, 0x6C, 0x6A, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x7A, 0x42, ++ 0x49, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x45, 0x0A, 0x52, 0x54, 0x45, 0x56, 0x4D, 0x42, 0x4D, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x4D, 0x52, 0x43, 0x31, 0x55, 0x63, 0x6E, ++ 0x56, 0x7A, 0x64, 0x43, 0x42, 0x48, 0x62, 0x57, 0x4A, 0x49, 0x4D, 0x53, 0x49, 0x77, 0x49, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x6C, 0x45, 0x4C, 0x56, 0x52, 0x53, 0x56, 0x56, 0x4E, 0x55, 0x49, 0x45, 0x4A, 0x53, 0x49, 0x46, ++ 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x4D, 0x53, 0x41, 0x79, 0x0A, 0x4D, 0x44, 0x49, 0x77, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x49, 0x77, 0x4D, 0x44, 0x49, 0x78, 0x4D, 0x54, 0x41, 0x35, 0x4E, 0x44, 0x55, 0x77, 0x4D, ++ 0x46, 0x6F, 0x58, 0x44, 0x54, 0x4D, 0x31, 0x4D, 0x44, 0x49, 0x78, 0x4D, 0x54, 0x41, 0x35, 0x4E, 0x44, 0x51, 0x31, 0x4F, 0x56, 0x6F, 0x77, 0x53, 0x44, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x52, ++ 0x45, 0x55, 0x78, 0x46, 0x54, 0x41, 0x54, 0x42, 0x67, 0x4E, 0x56, 0x0A, 0x42, 0x41, 0x6F, 0x54, 0x44, 0x45, 0x51, 0x74, 0x56, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x67, 0x52, 0x32, 0x31, 0x69, 0x53, 0x44, 0x45, 0x69, 0x4D, 0x43, 0x41, 0x47, ++ 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x5A, 0x52, 0x43, 0x31, 0x55, 0x55, 0x6C, 0x56, 0x54, 0x56, 0x43, 0x42, 0x43, 0x55, 0x69, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x49, 0x44, 0x45, 0x67, 0x4D, 0x6A, 0x41, 0x79, ++ 0x4D, 0x44, 0x42, 0x32, 0x4D, 0x42, 0x41, 0x47, 0x0A, 0x42, 0x79, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x41, 0x67, 0x45, 0x47, 0x42, 0x53, 0x75, 0x42, 0x42, 0x41, 0x41, 0x69, 0x41, 0x32, 0x49, 0x41, 0x42, 0x4D, 0x62, 0x4C, 0x78, 0x79, 0x6A, ++ 0x52, 0x2B, 0x34, 0x54, 0x31, 0x6D, 0x75, 0x39, 0x43, 0x46, 0x43, 0x44, 0x68, 0x51, 0x32, 0x74, 0x75, 0x64, 0x61, 0x33, 0x38, 0x4B, 0x77, 0x4F, 0x45, 0x31, 0x48, 0x61, 0x54, 0x4A, 0x64, 0x64, 0x5A, 0x4F, 0x30, 0x46, 0x6C, 0x61, 0x78, 0x37, ++ 0x6D, 0x4E, 0x43, 0x71, 0x37, 0x0A, 0x64, 0x50, 0x59, 0x53, 0x7A, 0x75, 0x68, 0x74, 0x35, 0x36, 0x76, 0x6B, 0x50, 0x45, 0x34, 0x2F, 0x52, 0x41, 0x69, 0x4C, 0x7A, 0x52, 0x5A, 0x78, 0x79, 0x37, 0x2B, 0x53, 0x6D, 0x66, 0x53, 0x6B, 0x31, 0x7A, ++ 0x78, 0x51, 0x56, 0x46, 0x4B, 0x51, 0x68, 0x59, 0x4E, 0x34, 0x6C, 0x47, 0x64, 0x6E, 0x6F, 0x78, 0x77, 0x4A, 0x47, 0x54, 0x31, 0x31, 0x4E, 0x49, 0x58, 0x65, 0x37, 0x57, 0x42, 0x39, 0x78, 0x77, 0x79, 0x30, 0x51, 0x56, 0x4B, 0x35, 0x62, 0x75, ++ 0x58, 0x75, 0x0A, 0x51, 0x71, 0x4F, 0x43, 0x41, 0x51, 0x30, 0x77, 0x67, 0x67, 0x45, 0x4A, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x48, ++ 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x46, 0x48, 0x4F, 0x52, 0x45, 0x4B, 0x76, 0x2F, 0x56, 0x62, 0x4E, 0x61, 0x66, 0x41, 0x6B, 0x6C, 0x31, 0x62, 0x4B, 0x36, 0x43, 0x4B, 0x42, 0x72, 0x71, 0x78, 0x39, 0x74, 0x0A, ++ 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6A, 0x43, 0x42, 0x78, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x66, 0x42, 0x49, 0x47, 0x2B, 0x4D, 0x49, 0x47, 0x37, ++ 0x4D, 0x44, 0x36, 0x67, 0x50, 0x4B, 0x41, 0x36, 0x68, 0x6A, 0x68, 0x6F, 0x64, 0x48, 0x52, 0x77, 0x4F, 0x69, 0x38, 0x76, 0x59, 0x33, 0x4A, 0x73, 0x4C, 0x6D, 0x51, 0x74, 0x64, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x75, 0x0A, 0x62, 0x6D, 0x56, ++ 0x30, 0x4C, 0x32, 0x4E, 0x79, 0x62, 0x43, 0x39, 0x6B, 0x4C, 0x58, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x58, 0x32, 0x4A, 0x79, 0x58, 0x33, 0x4A, 0x76, 0x62, 0x33, 0x52, 0x66, 0x59, 0x32, 0x46, 0x66, 0x4D, 0x56, 0x38, 0x79, 0x4D, 0x44, 0x49, ++ 0x77, 0x4C, 0x6D, 0x4E, 0x79, 0x62, 0x44, 0x42, 0x35, 0x6F, 0x48, 0x65, 0x67, 0x64, 0x59, 0x5A, 0x7A, 0x62, 0x47, 0x52, 0x68, 0x63, 0x44, 0x6F, 0x76, 0x4C, 0x32, 0x52, 0x70, 0x63, 0x6D, 0x56, 0x6A, 0x0A, 0x64, 0x47, 0x39, 0x79, 0x65, 0x53, ++ 0x35, 0x6B, 0x4C, 0x58, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x4C, 0x6D, 0x35, 0x6C, 0x64, 0x43, 0x39, 0x44, 0x54, 0x6A, 0x31, 0x45, 0x4C, 0x56, 0x52, 0x53, 0x56, 0x56, 0x4E, 0x55, 0x4A, 0x54, 0x49, 0x77, 0x51, 0x6C, 0x49, 0x6C, 0x4D, 0x6A, ++ 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x4A, 0x54, 0x49, 0x77, 0x51, 0x30, 0x45, 0x6C, 0x4D, 0x6A, 0x41, 0x78, 0x4A, 0x54, 0x49, 0x77, 0x4D, 0x6A, 0x41, 0x79, 0x4D, 0x43, 0x78, 0x50, 0x0A, 0x50, 0x55, 0x51, 0x74, 0x56, 0x48, 0x4A, 0x31, 0x63, ++ 0x33, 0x51, 0x6C, 0x4D, 0x6A, 0x42, 0x48, 0x62, 0x57, 0x4A, 0x49, 0x4C, 0x45, 0x4D, 0x39, 0x52, 0x45, 0x55, 0x2F, 0x59, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6C, 0x6D, 0x61, 0x57, 0x4E, 0x68, 0x64, 0x47, 0x56, 0x79, 0x5A, 0x58, 0x5A, 0x76, 0x59, ++ 0x32, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x62, 0x47, 0x6C, 0x7A, 0x64, 0x44, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x0A, 0x41, 0x77, 0x4E, 0x70, 0x41, 0x44, 0x42, 0x6D, 0x41, 0x6A, 0x45, 0x41, ++ 0x6C, 0x4A, 0x41, 0x74, 0x45, 0x2F, 0x72, 0x68, 0x59, 0x2F, 0x68, 0x68, 0x59, 0x2B, 0x69, 0x74, 0x68, 0x58, 0x68, 0x55, 0x6B, 0x5A, 0x79, 0x34, 0x6B, 0x7A, 0x67, 0x2B, 0x47, 0x6B, 0x48, 0x61, 0x51, 0x42, 0x5A, 0x54, 0x51, 0x67, 0x6A, 0x4B, ++ 0x4C, 0x34, 0x37, 0x78, 0x50, 0x6F, 0x46, 0x57, 0x77, 0x4B, 0x72, 0x59, 0x37, 0x52, 0x6A, 0x45, 0x73, 0x4B, 0x37, 0x30, 0x50, 0x76, 0x6F, 0x6D, 0x0A, 0x41, 0x6A, 0x45, 0x41, 0x38, 0x79, 0x6A, 0x69, 0x78, 0x74, 0x73, 0x72, 0x6D, 0x66, 0x75, ++ 0x33, 0x55, 0x62, 0x67, 0x6B, 0x6F, 0x36, 0x53, 0x55, 0x65, 0x68, 0x6F, 0x2F, 0x35, 0x6A, 0x62, 0x69, 0x41, 0x31, 0x63, 0x7A, 0x69, 0x6A, 0x44, 0x4C, 0x67, 0x73, 0x66, 0x57, 0x46, 0x42, 0x48, 0x56, 0x64, 0x57, 0x4E, 0x62, 0x46, 0x4A, 0x57, ++ 0x63, 0x48, 0x77, 0x48, 0x50, 0x32, 0x4E, 0x56, 0x79, 0x70, 0x77, 0x38, 0x37, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, ++ 0x0A, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, 0x32, 0x30, 0x32, 0x30, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x32, 0x7A, 0x43, 0x43, 0x41, 0x6D, 0x43, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x58, 0x77, 0x4A, 0x42, 0x31, 0x33, 0x71, 0x48, 0x66, 0x45, 0x77, 0x44, 0x6F, 0x36, 0x79, 0x57, 0x6A, 0x66, 0x76, ++ 0x2F, 0x30, 0x44, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x7A, 0x42, 0x49, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x45, 0x0A, 0x52, 0x54, ++ 0x45, 0x56, 0x4D, 0x42, 0x4D, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x4D, 0x52, 0x43, 0x31, 0x55, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x43, 0x42, 0x48, 0x62, 0x57, 0x4A, 0x49, 0x4D, 0x53, 0x49, 0x77, 0x49, 0x41, 0x59, 0x44, 0x56, 0x51, ++ 0x51, 0x44, 0x45, 0x78, 0x6C, 0x45, 0x4C, 0x56, 0x52, 0x53, 0x56, 0x56, 0x4E, 0x55, 0x49, 0x45, 0x56, 0x57, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x4D, 0x53, 0x41, 0x79, 0x0A, 0x4D, 0x44, 0x49, 0x77, 0x4D, ++ 0x42, 0x34, 0x58, 0x44, 0x54, 0x49, 0x77, 0x4D, 0x44, 0x49, 0x78, 0x4D, 0x54, 0x45, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x46, 0x6F, 0x58, 0x44, 0x54, 0x4D, 0x31, 0x4D, 0x44, 0x49, 0x78, 0x4D, 0x54, 0x41, 0x35, 0x4E, 0x54, 0x6B, 0x31, 0x4F, ++ 0x56, 0x6F, 0x77, 0x53, 0x44, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x52, 0x45, 0x55, 0x78, 0x46, 0x54, 0x41, 0x54, 0x42, 0x67, 0x4E, 0x56, 0x0A, 0x42, 0x41, 0x6F, 0x54, 0x44, 0x45, 0x51, 0x74, ++ 0x56, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x67, 0x52, 0x32, 0x31, 0x69, 0x53, 0x44, 0x45, 0x69, 0x4D, 0x43, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x5A, 0x52, 0x43, 0x31, 0x55, 0x55, 0x6C, 0x56, 0x54, 0x56, 0x43, 0x42, 0x46, ++ 0x56, 0x69, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x49, 0x44, 0x45, 0x67, 0x4D, 0x6A, 0x41, 0x79, 0x4D, 0x44, 0x42, 0x32, 0x4D, 0x42, 0x41, 0x47, 0x0A, 0x42, 0x79, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x41, 0x67, 0x45, ++ 0x47, 0x42, 0x53, 0x75, 0x42, 0x42, 0x41, 0x41, 0x69, 0x41, 0x32, 0x49, 0x41, 0x42, 0x50, 0x45, 0x4C, 0x33, 0x59, 0x5A, 0x44, 0x49, 0x42, 0x6E, 0x66, 0x6C, 0x34, 0x58, 0x6F, 0x49, 0x6B, 0x71, 0x62, 0x7A, 0x35, 0x32, 0x59, 0x76, 0x37, 0x51, ++ 0x46, 0x4A, 0x73, 0x6E, 0x4C, 0x34, 0x36, 0x62, 0x53, 0x6A, 0x38, 0x57, 0x65, 0x65, 0x48, 0x73, 0x78, 0x69, 0x61, 0x6D, 0x4A, 0x72, 0x53, 0x63, 0x38, 0x0A, 0x5A, 0x52, 0x43, 0x43, 0x2F, 0x4E, 0x2F, 0x44, 0x6E, 0x55, 0x37, 0x77, 0x4D, 0x79, ++ 0x50, 0x45, 0x30, 0x6A, 0x4C, 0x31, 0x48, 0x4C, 0x44, 0x66, 0x4D, 0x78, 0x64, 0x64, 0x78, 0x66, 0x43, 0x78, 0x69, 0x76, 0x6E, 0x76, 0x75, 0x62, 0x63, 0x55, 0x79, 0x69, 0x6C, 0x4B, 0x77, 0x67, 0x2B, 0x70, 0x66, 0x33, 0x56, 0x6C, 0x53, 0x53, ++ 0x6F, 0x77, 0x5A, 0x2F, 0x52, 0x6B, 0x39, 0x39, 0x59, 0x61, 0x64, 0x39, 0x72, 0x44, 0x77, 0x70, 0x64, 0x68, 0x51, 0x6E, 0x74, 0x4A, 0x0A, 0x72, 0x61, 0x4F, 0x43, 0x41, 0x51, 0x30, 0x77, 0x67, 0x67, 0x45, 0x4A, 0x4D, 0x41, 0x38, 0x47, 0x41, ++ 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x46, 0x48, 0x38, 0x51, 0x41, 0x52, 0x59, 0x33, 0x4F, ++ 0x71, 0x51, 0x6F, 0x35, 0x46, 0x44, 0x34, 0x70, 0x50, 0x66, 0x73, 0x61, 0x7A, 0x4B, 0x32, 0x2F, 0x75, 0x6D, 0x4C, 0x0A, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, ++ 0x42, 0x6A, 0x43, 0x42, 0x78, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x66, 0x42, 0x49, 0x47, 0x2B, 0x4D, 0x49, 0x47, 0x37, 0x4D, 0x44, 0x36, 0x67, 0x50, 0x4B, 0x41, 0x36, 0x68, 0x6A, 0x68, 0x6F, 0x64, 0x48, 0x52, 0x77, 0x4F, 0x69, 0x38, 0x76, ++ 0x59, 0x33, 0x4A, 0x73, 0x4C, 0x6D, 0x51, 0x74, 0x64, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x75, 0x0A, 0x62, 0x6D, 0x56, 0x30, 0x4C, 0x32, 0x4E, 0x79, 0x62, 0x43, 0x39, 0x6B, 0x4C, 0x58, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x58, 0x32, 0x56, ++ 0x32, 0x58, 0x33, 0x4A, 0x76, 0x62, 0x33, 0x52, 0x66, 0x59, 0x32, 0x46, 0x66, 0x4D, 0x56, 0x38, 0x79, 0x4D, 0x44, 0x49, 0x77, 0x4C, 0x6D, 0x4E, 0x79, 0x62, 0x44, 0x42, 0x35, 0x6F, 0x48, 0x65, 0x67, 0x64, 0x59, 0x5A, 0x7A, 0x62, 0x47, 0x52, ++ 0x68, 0x63, 0x44, 0x6F, 0x76, 0x4C, 0x32, 0x52, 0x70, 0x63, 0x6D, 0x56, 0x6A, 0x0A, 0x64, 0x47, 0x39, 0x79, 0x65, 0x53, 0x35, 0x6B, 0x4C, 0x58, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x4C, 0x6D, 0x35, 0x6C, 0x64, 0x43, 0x39, 0x44, 0x54, 0x6A, ++ 0x31, 0x45, 0x4C, 0x56, 0x52, 0x53, 0x56, 0x56, 0x4E, 0x55, 0x4A, 0x54, 0x49, 0x77, 0x52, 0x56, 0x59, 0x6C, 0x4D, 0x6A, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x4A, 0x54, 0x49, 0x77, 0x51, 0x30, 0x45, 0x6C, 0x4D, 0x6A, 0x41, 0x78, 0x4A, 0x54, ++ 0x49, 0x77, 0x4D, 0x6A, 0x41, 0x79, 0x4D, 0x43, 0x78, 0x50, 0x0A, 0x50, 0x55, 0x51, 0x74, 0x56, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x6C, 0x4D, 0x6A, 0x42, 0x48, 0x62, 0x57, 0x4A, 0x49, 0x4C, 0x45, 0x4D, 0x39, 0x52, 0x45, 0x55, 0x2F, 0x59, ++ 0x32, 0x56, 0x79, 0x64, 0x47, 0x6C, 0x6D, 0x61, 0x57, 0x4E, 0x68, 0x64, 0x47, 0x56, 0x79, 0x5A, 0x58, 0x5A, 0x76, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x62, 0x47, 0x6C, 0x7A, 0x64, 0x44, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, ++ 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x0A, 0x41, 0x77, 0x4E, 0x70, 0x41, 0x44, 0x42, 0x6D, 0x41, 0x6A, 0x45, 0x41, 0x79, 0x6A, 0x7A, 0x47, 0x4B, 0x6E, 0x58, 0x43, 0x58, 0x6E, 0x56, 0x69, 0x4F, 0x54, 0x59, 0x41, 0x59, 0x46, 0x71, 0x4C, ++ 0x77, 0x5A, 0x4F, 0x5A, 0x7A, 0x4E, 0x6E, 0x62, 0x51, 0x54, 0x73, 0x37, 0x68, 0x35, 0x6B, 0x58, 0x4F, 0x39, 0x58, 0x4D, 0x54, 0x38, 0x6F, 0x69, 0x39, 0x36, 0x43, 0x41, 0x79, 0x2F, 0x6D, 0x30, 0x73, 0x52, 0x74, 0x57, 0x39, 0x58, 0x4C, 0x53, ++ 0x2F, 0x42, 0x6E, 0x52, 0x0A, 0x41, 0x6A, 0x45, 0x41, 0x6B, 0x66, 0x63, 0x77, 0x6B, 0x7A, 0x38, 0x51, 0x52, 0x69, 0x74, 0x78, 0x70, 0x4E, 0x41, 0x37, 0x52, 0x4A, 0x76, 0x41, 0x4B, 0x51, 0x49, 0x46, 0x73, 0x6B, 0x46, 0x33, 0x55, 0x66, 0x4E, ++ 0x35, 0x57, 0x70, 0x36, 0x4F, 0x46, 0x4B, 0x42, 0x4F, 0x51, 0x74, 0x4A, 0x62, 0x67, 0x66, 0x4D, 0x30, 0x61, 0x67, 0x50, 0x6E, 0x49, 0x6A, 0x68, 0x51, 0x57, 0x2B, 0x30, 0x5A, 0x54, 0x30, 0x4D, 0x57, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, ++ 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x50, 0x33, ++ 0x38, 0x34, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x35, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x47, 0x54, 0x43, 0x43, 0x41, 0x5A, 0x2B, ++ 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x43, 0x65, 0x43, 0x54, 0x5A, 0x61, 0x7A, 0x33, 0x32, 0x63, 0x69, 0x35, 0x50, 0x68, 0x77, 0x4C, 0x42, 0x43, 0x6F, 0x75, 0x38, 0x7A, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, ++ 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x7A, 0x42, 0x4F, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, 0x0A, 0x55, 0x7A, 0x45, 0x58, 0x4D, 0x42, 0x55, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, ++ 0x4D, 0x4F, 0x52, 0x47, 0x6C, 0x6E, 0x61, 0x55, 0x4E, 0x6C, 0x63, 0x6E, 0x51, 0x73, 0x49, 0x45, 0x6C, 0x75, 0x59, 0x79, 0x34, 0x78, 0x4A, 0x6A, 0x41, 0x6B, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x48, 0x55, 0x52, 0x70, 0x5A, 0x32, ++ 0x6C, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x49, 0x46, 0x52, 0x4D, 0x55, 0x79, 0x42, 0x46, 0x51, 0x30, 0x4D, 0x67, 0x55, 0x44, 0x4D, 0x34, 0x0A, 0x4E, 0x43, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x63, 0x31, 0x4D, 0x42, 0x34, 0x58, 0x44, ++ 0x54, 0x49, 0x78, 0x4D, 0x44, 0x45, 0x78, 0x4E, 0x54, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x46, 0x6F, 0x58, 0x44, 0x54, 0x51, 0x32, 0x4D, 0x44, 0x45, 0x78, 0x4E, 0x44, 0x49, 0x7A, 0x4E, 0x54, 0x6B, 0x31, 0x4F, 0x56, 0x6F, 0x77, 0x54, ++ 0x6A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x56, 0x56, 0x4D, 0x78, 0x0A, 0x46, 0x7A, 0x41, 0x56, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x44, 0x6B, 0x52, 0x70, 0x5A, 0x32, 0x6C, 0x44, ++ 0x5A, 0x58, 0x4A, 0x30, 0x4C, 0x43, 0x42, 0x4A, 0x62, 0x6D, 0x4D, 0x75, 0x4D, 0x53, 0x59, 0x77, 0x4A, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x31, 0x45, 0x61, 0x57, 0x64, 0x70, 0x51, 0x32, 0x56, 0x79, 0x64, 0x43, 0x42, 0x55, ++ 0x54, 0x46, 0x4D, 0x67, 0x52, 0x55, 0x4E, 0x44, 0x49, 0x46, 0x41, 0x7A, 0x4F, 0x44, 0x51, 0x67, 0x0A, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x48, 0x4E, 0x54, 0x42, 0x32, 0x4D, 0x42, 0x41, 0x47, 0x42, 0x79, 0x71, 0x47, 0x53, 0x4D, 0x34, ++ 0x39, 0x41, 0x67, 0x45, 0x47, 0x42, 0x53, 0x75, 0x42, 0x42, 0x41, 0x41, 0x69, 0x41, 0x32, 0x49, 0x41, 0x42, 0x4D, 0x46, 0x45, 0x6F, 0x63, 0x38, 0x52, 0x6C, 0x31, 0x43, 0x61, 0x33, 0x69, 0x4F, 0x43, 0x4E, 0x51, 0x66, 0x4E, 0x30, 0x4D, 0x73, ++ 0x59, 0x6E, 0x64, 0x4C, 0x78, 0x66, 0x33, 0x63, 0x31, 0x54, 0x7A, 0x76, 0x64, 0x0A, 0x6C, 0x48, 0x4A, 0x53, 0x37, 0x63, 0x49, 0x37, 0x2B, 0x4F, 0x7A, 0x36, 0x65, 0x32, 0x74, 0x59, 0x49, 0x4F, 0x79, 0x5A, 0x72, 0x73, 0x6E, 0x38, 0x61, 0x4C, ++ 0x4E, 0x31, 0x75, 0x64, 0x73, 0x4A, 0x37, 0x4D, 0x67, 0x54, 0x39, 0x55, 0x37, 0x47, 0x43, 0x68, 0x31, 0x6D, 0x4D, 0x45, 0x79, 0x37, 0x48, 0x30, 0x63, 0x4B, 0x50, 0x47, 0x45, 0x51, 0x51, 0x69, 0x6C, 0x38, 0x70, 0x51, 0x67, 0x4F, 0x34, 0x43, ++ 0x4C, 0x70, 0x30, 0x7A, 0x56, 0x6F, 0x7A, 0x70, 0x74, 0x6A, 0x0A, 0x6E, 0x34, 0x53, 0x31, 0x6D, 0x55, 0x31, 0x59, 0x6F, 0x49, 0x37, 0x31, 0x56, 0x4F, 0x65, 0x56, 0x79, 0x61, 0x4E, 0x43, 0x4D, 0x45, 0x41, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, ++ 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x46, 0x4D, 0x46, 0x52, 0x52, 0x56, 0x42, 0x5A, 0x71, 0x7A, 0x37, 0x6E, 0x4C, 0x46, 0x72, 0x36, 0x49, 0x43, 0x49, 0x53, 0x42, 0x34, 0x43, 0x49, 0x66, 0x42, 0x46, 0x71, 0x4D, 0x41, 0x34, 0x47, 0x41, ++ 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x0A, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x68, 0x6A, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2F, ++ 0x4D, 0x41, 0x6F, 0x47, 0x43, 0x43, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x42, 0x41, 0x4D, 0x44, 0x41, 0x32, 0x67, 0x41, 0x4D, 0x47, 0x55, 0x43, 0x4D, 0x51, 0x43, 0x4A, 0x61, 0x6F, 0x31, 0x48, 0x35, 0x2B, 0x7A, 0x38, 0x62, 0x6C, 0x55, 0x44, ++ 0x32, 0x57, 0x64, 0x73, 0x0A, 0x4A, 0x6B, 0x36, 0x44, 0x78, 0x76, 0x33, 0x4A, 0x2B, 0x79, 0x73, 0x54, 0x76, 0x4C, 0x64, 0x36, 0x6A, 0x4C, 0x52, 0x6C, 0x30, 0x6D, 0x6C, 0x70, 0x59, 0x78, 0x4E, 0x6A, 0x4F, 0x79, 0x5A, 0x51, 0x4C, 0x67, 0x47, ++ 0x68, 0x65, 0x51, 0x61, 0x52, 0x6E, 0x55, 0x69, 0x2F, 0x77, 0x72, 0x34, 0x43, 0x4D, 0x45, 0x66, 0x44, 0x46, 0x58, 0x75, 0x78, 0x6F, 0x4A, 0x47, 0x5A, 0x53, 0x5A, 0x4F, 0x6F, 0x50, 0x48, 0x7A, 0x6F, 0x52, 0x67, 0x61, 0x4C, 0x4C, 0x50, 0x49, ++ 0x78, 0x0A, 0x41, 0x4A, 0x53, 0x64, 0x59, 0x73, 0x69, 0x4A, 0x76, 0x52, 0x6D, 0x45, 0x46, 0x4F, 0x6D, 0x6C, 0x2B, 0x77, 0x47, 0x34, 0x44, 0x58, 0x5A, 0x44, 0x6A, 0x43, 0x35, 0x54, 0x79, 0x33, 0x7A, 0x66, 0x44, 0x42, 0x65, 0x57, 0x55, 0x41, ++ 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x54, ++ 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x34, 0x30, 0x39, 0x36, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x35, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, ++ 0x5A, 0x6A, 0x43, 0x43, 0x41, 0x30, 0x36, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x43, 0x50, 0x6D, 0x30, 0x65, 0x4B, 0x6A, 0x36, 0x66, 0x74, 0x70, 0x71, 0x4D, 0x7A, 0x65, 0x4A, 0x33, 0x6E, 0x7A, 0x50, 0x69, 0x6A, 0x41, 0x4E, ++ 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x77, 0x46, 0x41, 0x44, 0x42, 0x4E, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0A, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, ++ 0x58, 0x4D, 0x42, 0x55, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x4F, 0x52, 0x47, 0x6C, 0x6E, 0x61, 0x55, 0x4E, 0x6C, 0x63, 0x6E, 0x51, 0x73, 0x49, 0x45, 0x6C, 0x75, 0x59, 0x79, 0x34, 0x78, 0x4A, 0x54, 0x41, 0x6A, 0x42, 0x67, 0x4E, ++ 0x56, 0x42, 0x41, 0x4D, 0x54, 0x48, 0x45, 0x52, 0x70, 0x5A, 0x32, 0x6C, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x49, 0x46, 0x52, 0x4D, 0x55, 0x79, 0x42, 0x53, 0x55, 0x30, 0x45, 0x30, 0x0A, 0x4D, 0x44, 0x6B, 0x32, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, ++ 0x51, 0x67, 0x52, 0x7A, 0x55, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x6A, 0x45, 0x77, 0x4D, 0x54, 0x45, 0x31, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x57, 0x68, 0x63, 0x4E, 0x4E, 0x44, 0x59, 0x77, 0x4D, 0x54, 0x45, 0x30, 0x4D, 0x6A, ++ 0x4D, 0x31, 0x4F, 0x54, 0x55, 0x35, 0x57, 0x6A, 0x42, 0x4E, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, 0x0A, 0x55, 0x7A, 0x45, 0x58, 0x4D, 0x42, 0x55, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, ++ 0x68, 0x4D, 0x4F, 0x52, 0x47, 0x6C, 0x6E, 0x61, 0x55, 0x4E, 0x6C, 0x63, 0x6E, 0x51, 0x73, 0x49, 0x45, 0x6C, 0x75, 0x59, 0x79, 0x34, 0x78, 0x4A, 0x54, 0x41, 0x6A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x48, 0x45, 0x52, 0x70, 0x5A, ++ 0x32, 0x6C, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x49, 0x46, 0x52, 0x4D, 0x55, 0x79, 0x42, 0x53, 0x55, 0x30, 0x45, 0x30, 0x4D, 0x44, 0x6B, 0x32, 0x0A, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x52, 0x7A, 0x55, 0x77, 0x67, 0x67, 0x49, 0x69, ++ 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x43, 0x7A, ++ 0x30, 0x50, 0x54, 0x4A, 0x65, 0x52, 0x47, 0x64, 0x2F, 0x66, 0x78, 0x6D, 0x67, 0x65, 0x66, 0x4D, 0x31, 0x65, 0x53, 0x38, 0x0A, 0x37, 0x49, 0x45, 0x2B, 0x61, 0x6A, 0x57, 0x4F, 0x4C, 0x72, 0x66, 0x6E, 0x33, 0x71, 0x2F, 0x35, 0x42, 0x30, 0x33, ++ 0x50, 0x4D, 0x4A, 0x33, 0x71, 0x43, 0x51, 0x75, 0x5A, 0x76, 0x57, 0x78, 0x58, 0x32, 0x68, 0x68, 0x4B, 0x75, 0x48, 0x69, 0x73, 0x4F, 0x6A, 0x6D, 0x6F, 0x70, 0x6B, 0x69, 0x73, 0x4C, 0x6E, 0x4C, 0x6C, 0x76, 0x65, 0x76, 0x78, 0x47, 0x73, 0x33, ++ 0x6E, 0x70, 0x41, 0x4F, 0x70, 0x50, 0x78, 0x47, 0x30, 0x32, 0x43, 0x2B, 0x4A, 0x46, 0x76, 0x75, 0x55, 0x0A, 0x41, 0x54, 0x32, 0x37, 0x4C, 0x2F, 0x67, 0x54, 0x42, 0x61, 0x46, 0x34, 0x48, 0x49, 0x34, 0x6F, 0x34, 0x45, 0x58, 0x67, 0x67, 0x2F, ++ 0x52, 0x5A, 0x47, 0x35, 0x57, 0x7A, 0x72, 0x6E, 0x34, 0x44, 0x52, 0x65, 0x57, 0x2B, 0x77, 0x6B, 0x4C, 0x2B, 0x37, 0x76, 0x49, 0x38, 0x74, 0x6F, 0x55, 0x54, 0x6D, 0x44, 0x4B, 0x64, 0x46, 0x71, 0x67, 0x70, 0x77, 0x67, 0x73, 0x63, 0x4F, 0x4E, ++ 0x79, 0x66, 0x4D, 0x58, 0x64, 0x63, 0x76, 0x79, 0x65, 0x6A, 0x2F, 0x43, 0x65, 0x73, 0x0A, 0x74, 0x79, 0x75, 0x39, 0x64, 0x4A, 0x73, 0x58, 0x4C, 0x66, 0x4B, 0x42, 0x32, 0x6C, 0x32, 0x77, 0x34, 0x53, 0x4D, 0x58, 0x50, 0x6F, 0x68, 0x4B, 0x45, ++ 0x69, 0x50, 0x51, 0x36, 0x73, 0x2B, 0x64, 0x33, 0x67, 0x4D, 0x58, 0x73, 0x55, 0x4A, 0x4B, 0x6F, 0x42, 0x5A, 0x4D, 0x70, 0x47, 0x32, 0x54, 0x36, 0x54, 0x38, 0x36, 0x37, 0x6A, 0x70, 0x38, 0x6E, 0x56, 0x69, 0x64, 0x39, 0x45, 0x36, 0x50, 0x2F, ++ 0x44, 0x73, 0x6A, 0x79, 0x47, 0x32, 0x34, 0x34, 0x67, 0x58, 0x61, 0x0A, 0x7A, 0x4F, 0x76, 0x73, 0x77, 0x7A, 0x48, 0x30, 0x31, 0x36, 0x63, 0x70, 0x56, 0x49, 0x44, 0x50, 0x52, 0x46, 0x74, 0x4D, 0x62, 0x7A, 0x43, 0x65, 0x38, 0x38, 0x7A, 0x64, ++ 0x48, 0x35, 0x52, 0x44, 0x6E, 0x55, 0x31, 0x2F, 0x63, 0x48, 0x41, 0x4E, 0x31, 0x44, 0x72, 0x52, 0x4E, 0x2F, 0x42, 0x73, 0x6E, 0x5A, 0x76, 0x41, 0x46, 0x4A, 0x4E, 0x59, 0x37, 0x38, 0x31, 0x42, 0x4F, 0x48, 0x57, 0x38, 0x45, 0x77, 0x4F, 0x56, ++ 0x66, 0x48, 0x2F, 0x6A, 0x58, 0x4F, 0x6E, 0x56, 0x0A, 0x44, 0x64, 0x58, 0x69, 0x66, 0x42, 0x42, 0x69, 0x71, 0x6D, 0x76, 0x77, 0x50, 0x58, 0x62, 0x7A, 0x50, 0x36, 0x50, 0x6F, 0x73, 0x4D, 0x48, 0x39, 0x37, 0x36, 0x70, 0x58, 0x54, 0x61, 0x79, ++ 0x47, 0x70, 0x78, 0x69, 0x30, 0x4B, 0x63, 0x45, 0x73, 0x44, 0x72, 0x39, 0x6B, 0x76, 0x69, 0x6D, 0x4D, 0x32, 0x41, 0x49, 0x74, 0x7A, 0x56, 0x77, 0x76, 0x38, 0x6E, 0x2F, 0x76, 0x46, 0x66, 0x51, 0x4D, 0x46, 0x61, 0x77, 0x4B, 0x73, 0x50, 0x48, ++ 0x54, 0x44, 0x55, 0x39, 0x71, 0x0A, 0x54, 0x58, 0x65, 0x58, 0x41, 0x61, 0x44, 0x78, 0x5A, 0x72, 0x65, 0x33, 0x7A, 0x75, 0x2F, 0x4F, 0x37, 0x4F, 0x79, 0x6C, 0x64, 0x63, 0x71, 0x73, 0x34, 0x2B, 0x46, 0x6A, 0x39, 0x37, 0x69, 0x68, 0x42, 0x4D, ++ 0x69, 0x38, 0x65, 0x7A, 0x39, 0x64, 0x4C, 0x52, 0x59, 0x69, 0x56, 0x75, 0x31, 0x49, 0x53, 0x66, 0x36, 0x6E, 0x4C, 0x33, 0x6B, 0x77, 0x4A, 0x5A, 0x75, 0x36, 0x61, 0x79, 0x30, 0x2F, 0x6E, 0x54, 0x76, 0x45, 0x46, 0x2B, 0x63, 0x64, 0x4C, 0x76, ++ 0x76, 0x79, 0x0A, 0x7A, 0x36, 0x62, 0x38, 0x34, 0x78, 0x51, 0x73, 0x6C, 0x70, 0x67, 0x68, 0x6A, 0x4C, 0x53, 0x52, 0x36, 0x52, 0x6C, 0x67, 0x67, 0x2F, 0x49, 0x77, 0x4B, 0x77, 0x5A, 0x7A, 0x55, 0x4E, 0x57, 0x59, 0x4F, 0x77, 0x62, 0x70, 0x78, ++ 0x34, 0x6F, 0x4D, 0x59, 0x49, 0x77, 0x6F, 0x2B, 0x46, 0x4B, 0x62, 0x62, 0x75, 0x48, 0x32, 0x54, 0x62, 0x73, 0x47, 0x4A, 0x4A, 0x76, 0x58, 0x4B, 0x79, 0x59, 0x2F, 0x2F, 0x53, 0x6F, 0x76, 0x63, 0x66, 0x58, 0x57, 0x4A, 0x4C, 0x35, 0x2F, 0x0A, ++ 0x4D, 0x5A, 0x34, 0x50, 0x62, 0x65, 0x69, 0x50, 0x54, 0x30, 0x32, 0x6A, 0x50, 0x2F, 0x38, 0x31, 0x36, 0x74, 0x39, 0x4A, 0x58, 0x6B, 0x47, 0x50, 0x68, 0x76, 0x6E, 0x78, 0x64, 0x33, 0x6C, 0x4C, 0x47, 0x37, 0x53, 0x6A, 0x58, 0x69, 0x2F, 0x37, ++ 0x52, 0x67, 0x4C, 0x51, 0x5A, 0x68, 0x4E, 0x65, 0x58, 0x6F, 0x56, 0x50, 0x7A, 0x74, 0x68, 0x77, 0x69, 0x48, 0x76, 0x4F, 0x41, 0x62, 0x57, 0x57, 0x6C, 0x39, 0x66, 0x4E, 0x66, 0x66, 0x32, 0x43, 0x2B, 0x4D, 0x49, 0x6B, 0x0A, 0x77, 0x63, 0x6F, ++ 0x42, 0x4F, 0x55, 0x2B, 0x4E, 0x6F, 0x73, 0x45, 0x55, 0x51, 0x42, 0x2B, 0x63, 0x5A, 0x74, 0x55, 0x4D, 0x43, 0x55, 0x62, 0x57, 0x38, 0x74, 0x44, 0x52, 0x53, 0x48, 0x5A, 0x57, 0x4F, 0x6B, 0x50, 0x4C, 0x74, 0x67, 0x6F, 0x52, 0x4F, 0x62, 0x71, ++ 0x4D, 0x45, 0x32, 0x77, 0x47, 0x74, 0x5A, 0x37, 0x50, 0x36, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6F, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x0A, 0x46, 0x67, 0x51, 0x55, 0x55, 0x54, ++ 0x4D, 0x63, 0x37, 0x54, 0x5A, 0x41, 0x72, 0x78, 0x66, 0x54, 0x4A, 0x63, 0x31, 0x70, 0x61, 0x50, 0x4B, 0x76, 0x54, 0x69, 0x4D, 0x2B, 0x73, 0x30, 0x45, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, ++ 0x51, 0x44, 0x41, 0x67, 0x47, 0x47, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x0A, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, ++ 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4D, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x42, 0x41, 0x47, 0x43, 0x6D, 0x72, 0x31, 0x74, 0x66, 0x56, 0x39, 0x71, 0x4A, 0x32, 0x30, 0x74, 0x51, 0x71, 0x63, 0x51, 0x6A, 0x4E, 0x53, 0x48, 0x2F, 0x30, ++ 0x47, 0x45, 0x77, 0x68, 0x4A, 0x47, 0x33, 0x50, 0x78, 0x44, 0x50, 0x4A, 0x59, 0x37, 0x4A, 0x76, 0x30, 0x59, 0x30, 0x32, 0x63, 0x45, 0x68, 0x4A, 0x68, 0x78, 0x77, 0x0A, 0x47, 0x58, 0x49, 0x65, 0x6F, 0x38, 0x6D, 0x48, 0x2F, 0x71, 0x6C, 0x44, ++ 0x5A, 0x4A, 0x59, 0x36, 0x79, 0x46, 0x4D, 0x45, 0x43, 0x72, 0x5A, 0x42, 0x75, 0x38, 0x52, 0x48, 0x41, 0x4E, 0x6D, 0x66, 0x47, 0x42, 0x67, 0x37, 0x73, 0x67, 0x37, 0x7A, 0x4E, 0x4F, 0x6F, 0x6B, 0x39, 0x39, 0x32, 0x76, 0x49, 0x47, 0x43, 0x75, ++ 0x6B, 0x69, 0x68, 0x66, 0x4E, 0x75, 0x64, 0x64, 0x35, 0x4E, 0x37, 0x48, 0x50, 0x4E, 0x74, 0x51, 0x4F, 0x61, 0x32, 0x37, 0x50, 0x53, 0x68, 0x4E, 0x0A, 0x6C, 0x6E, 0x78, 0x32, 0x78, 0x6C, 0x76, 0x30, 0x77, 0x64, 0x73, 0x55, 0x70, 0x61, 0x73, ++ 0x5A, 0x59, 0x67, 0x63, 0x59, 0x51, 0x46, 0x2B, 0x58, 0x6B, 0x64, 0x79, 0x63, 0x78, 0x36, 0x75, 0x31, 0x55, 0x51, 0x33, 0x6D, 0x61, 0x56, 0x4E, 0x56, 0x7A, 0x44, 0x6C, 0x39, 0x32, 0x73, 0x55, 0x52, 0x56, 0x58, 0x4C, 0x46, 0x4F, 0x34, 0x75, ++ 0x4A, 0x2B, 0x44, 0x51, 0x74, 0x70, 0x42, 0x66, 0x6C, 0x46, 0x2B, 0x61, 0x5A, 0x66, 0x54, 0x43, 0x49, 0x49, 0x54, 0x66, 0x4E, 0x0A, 0x4D, 0x42, 0x63, 0x39, 0x75, 0x50, 0x4B, 0x38, 0x71, 0x48, 0x57, 0x67, 0x51, 0x39, 0x77, 0x2B, 0x69, 0x55, ++ 0x75, 0x51, 0x72, 0x6D, 0x30, 0x44, 0x34, 0x42, 0x79, 0x6A, 0x6F, 0x4A, 0x59, 0x4A, 0x75, 0x33, 0x32, 0x6A, 0x74, 0x79, 0x6F, 0x51, 0x52, 0x45, 0x74, 0x47, 0x42, 0x7A, 0x52, 0x6A, 0x37, 0x54, 0x47, 0x35, 0x42, 0x4F, 0x36, 0x6A, 0x6D, 0x35, ++ 0x71, 0x75, 0x35, 0x6A, 0x46, 0x34, 0x39, 0x4F, 0x6F, 0x6B, 0x59, 0x54, 0x75, 0x72, 0x57, 0x47, 0x54, 0x2F, 0x0A, 0x75, 0x34, 0x63, 0x6E, 0x59, 0x69, 0x57, 0x42, 0x33, 0x39, 0x79, 0x68, 0x4C, 0x2F, 0x62, 0x74, 0x70, 0x2F, 0x39, 0x36, 0x6A, ++ 0x31, 0x45, 0x75, 0x4D, 0x50, 0x69, 0x6B, 0x41, 0x64, 0x4B, 0x46, 0x4F, 0x56, 0x38, 0x42, 0x6D, 0x5A, 0x5A, 0x76, 0x57, 0x6C, 0x74, 0x77, 0x47, 0x55, 0x62, 0x2B, 0x68, 0x6D, 0x41, 0x2B, 0x72, 0x59, 0x41, 0x51, 0x43, 0x64, 0x30, 0x35, 0x4A, ++ 0x53, 0x39, 0x59, 0x66, 0x37, 0x76, 0x53, 0x64, 0x50, 0x44, 0x33, 0x52, 0x68, 0x39, 0x47, 0x0A, 0x4F, 0x55, 0x72, 0x59, 0x55, 0x39, 0x44, 0x7A, 0x4C, 0x6A, 0x74, 0x78, 0x70, 0x64, 0x52, 0x76, 0x2F, 0x50, 0x4E, 0x6E, 0x35, 0x41, 0x65, 0x50, ++ 0x33, 0x53, 0x59, 0x5A, 0x34, 0x59, 0x31, 0x62, 0x2B, 0x71, 0x4F, 0x54, 0x45, 0x5A, 0x76, 0x70, 0x79, 0x44, 0x72, 0x44, 0x56, 0x57, 0x69, 0x61, 0x6B, 0x75, 0x46, 0x53, 0x64, 0x6A, 0x6A, 0x6F, 0x34, 0x62, 0x71, 0x39, 0x2B, 0x30, 0x2F, 0x56, ++ 0x37, 0x37, 0x50, 0x6E, 0x53, 0x49, 0x4D, 0x78, 0x38, 0x49, 0x49, 0x68, 0x0A, 0x34, 0x37, 0x61, 0x2B, 0x70, 0x36, 0x74, 0x76, 0x37, 0x35, 0x2F, 0x66, 0x54, 0x4D, 0x38, 0x42, 0x75, 0x47, 0x4A, 0x71, 0x49, 0x7A, 0x33, 0x6E, 0x43, 0x55, 0x32, ++ 0x41, 0x47, 0x33, 0x73, 0x77, 0x70, 0x4D, 0x50, 0x64, 0x42, 0x33, 0x38, 0x30, 0x76, 0x71, 0x51, 0x6D, 0x73, 0x76, 0x5A, 0x42, 0x36, 0x41, 0x6B, 0x64, 0x34, 0x79, 0x43, 0x59, 0x71, 0x6A, 0x64, 0x50, 0x2F, 0x2F, 0x66, 0x78, 0x34, 0x69, 0x6C, ++ 0x77, 0x4D, 0x55, 0x63, 0x2F, 0x64, 0x4E, 0x41, 0x55, 0x0A, 0x46, 0x76, 0x6F, 0x68, 0x69, 0x67, 0x4C, 0x56, 0x69, 0x67, 0x6D, 0x55, 0x64, 0x79, 0x37, 0x79, 0x57, 0x53, 0x69, 0x4C, 0x66, 0x46, 0x43, 0x53, 0x43, 0x6D, 0x5A, 0x34, 0x4F, 0x49, ++ 0x4E, 0x31, 0x78, 0x4C, 0x56, 0x61, 0x71, 0x42, 0x48, 0x47, 0x35, 0x63, 0x47, 0x64, 0x5A, 0x6C, 0x58, 0x50, 0x55, 0x38, 0x53, 0x76, 0x31, 0x33, 0x57, 0x46, 0x71, 0x55, 0x49, 0x54, 0x56, 0x75, 0x77, 0x68, 0x64, 0x34, 0x47, 0x54, 0x57, 0x67, ++ 0x7A, 0x71, 0x6C, 0x74, 0x6C, 0x4A, 0x0A, 0x79, 0x71, 0x45, 0x49, 0x38, 0x70, 0x63, 0x37, 0x62, 0x5A, 0x73, 0x45, 0x47, 0x43, 0x52, 0x45, 0x6A, 0x6E, 0x77, 0x42, 0x38, 0x74, 0x77, 0x6C, 0x32, 0x46, 0x36, 0x47, 0x6D, 0x72, 0x45, 0x35, 0x32, ++ 0x2F, 0x57, 0x52, 0x4D, 0x6D, 0x72, 0x52, 0x70, 0x6E, 0x43, 0x4B, 0x6F, 0x76, 0x66, 0x65, 0x70, 0x45, 0x57, 0x46, 0x4A, 0x71, 0x67, 0x65, 0x6A, 0x46, 0x30, 0x70, 0x57, 0x38, 0x68, 0x4C, 0x32, 0x4A, 0x70, 0x71, 0x41, 0x31, 0x35, 0x77, 0x38, ++ 0x6F, 0x56, 0x50, 0x0A, 0x62, 0x45, 0x74, 0x6F, 0x4C, 0x38, 0x70, 0x55, 0x39, 0x6F, 0x7A, 0x61, 0x4D, 0x76, 0x37, 0x44, 0x61, 0x34, 0x4D, 0x2F, 0x4F, 0x4D, 0x5A, 0x2B, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, ++ 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x43, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x31, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, ++ 0x4D, 0x49, 0x49, 0x46, 0x52, 0x7A, 0x43, 0x43, 0x41, 0x79, 0x2B, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x52, 0x41, 0x49, 0x34, 0x50, 0x2B, 0x55, 0x75, 0x51, 0x63, 0x57, 0x68, 0x6C, 0x4D, 0x31, 0x54, 0x30, 0x31, 0x45, 0x51, 0x35, ++ 0x74, 0x2B, 0x41, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x77, 0x50, 0x54, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0A, 0x42, 0x68, 0x4D, ++ 0x43, 0x56, 0x56, 0x4D, 0x78, 0x45, 0x6A, 0x41, 0x51, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x43, 0x55, 0x4E, 0x6C, 0x63, 0x6E, 0x52, 0x68, 0x61, 0x57, 0x35, 0x73, 0x65, 0x54, 0x45, 0x61, 0x4D, 0x42, 0x67, 0x47, 0x41, 0x31, 0x55, ++ 0x45, 0x41, 0x78, 0x4D, 0x52, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x46, 0x70, 0x62, 0x6D, 0x78, 0x35, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x55, 0x6A, 0x45, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x0A, 0x4D, 0x6A, 0x45, 0x77, 0x4E, 0x44, ++ 0x41, 0x78, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x57, 0x68, 0x63, 0x4E, 0x4E, 0x44, 0x59, 0x77, 0x4E, 0x44, 0x41, 0x78, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x57, 0x6A, 0x41, 0x39, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, ++ 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x53, 0x4D, 0x42, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x4A, 0x51, 0x32, 0x56, 0x79, 0x0A, 0x64, 0x47, 0x46, 0x70, 0x62, 0x6D, 0x78, 0x35, 0x4D, ++ 0x52, 0x6F, 0x77, 0x47, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x46, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x59, 0x57, 0x6C, 0x75, 0x62, 0x48, 0x6B, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x53, 0x4D, 0x54, 0x43, 0x43, 0x41, ++ 0x69, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x50, 0x0A, 0x41, 0x44, 0x43, 0x43, 0x41, 0x67, 0x6F, 0x43, 0x67, 0x67, 0x49, 0x42, ++ 0x41, 0x4E, 0x41, 0x32, 0x31, 0x42, 0x2F, 0x71, 0x33, 0x61, 0x76, 0x6B, 0x30, 0x62, 0x62, 0x6D, 0x2B, 0x79, 0x4C, 0x41, 0x33, 0x52, 0x4D, 0x4E, 0x61, 0x6E, 0x73, 0x69, 0x45, 0x78, 0x79, 0x58, 0x50, 0x47, 0x68, 0x6A, 0x5A, 0x6A, 0x4B, 0x63, ++ 0x41, 0x37, 0x57, 0x4E, 0x70, 0x49, 0x47, 0x44, 0x32, 0x6E, 0x67, 0x77, 0x45, 0x63, 0x2F, 0x63, 0x73, 0x69, 0x75, 0x2B, 0x6B, 0x72, 0x2B, 0x4F, 0x0A, 0x35, 0x4D, 0x51, 0x54, 0x76, 0x71, 0x52, 0x6F, 0x54, 0x4E, 0x6F, 0x43, 0x61, 0x42, 0x5A, ++ 0x30, 0x76, 0x72, 0x4C, 0x64, 0x42, 0x4F, 0x52, 0x72, 0x4B, 0x74, 0x30, 0x33, 0x48, 0x32, 0x41, 0x73, 0x32, 0x2F, 0x58, 0x33, 0x6F, 0x58, 0x79, 0x56, 0x74, 0x77, 0x78, 0x77, 0x68, 0x69, 0x37, 0x78, 0x4F, 0x75, 0x39, 0x53, 0x39, 0x38, 0x7A, ++ 0x54, 0x6D, 0x2F, 0x6D, 0x4C, 0x76, 0x67, 0x37, 0x66, 0x4D, 0x62, 0x65, 0x64, 0x61, 0x46, 0x79, 0x53, 0x70, 0x76, 0x58, 0x6C, 0x0A, 0x38, 0x77, 0x6F, 0x30, 0x74, 0x66, 0x39, 0x37, 0x6F, 0x75, 0x53, 0x48, 0x6F, 0x63, 0x61, 0x76, 0x46, 0x77, ++ 0x44, 0x76, 0x41, 0x35, 0x48, 0x74, 0x71, 0x52, 0x78, 0x4F, 0x63, 0x54, 0x33, 0x53, 0x69, 0x32, 0x79, 0x4A, 0x39, 0x48, 0x69, 0x47, 0x35, 0x6D, 0x70, 0x4A, 0x6F, 0x4D, 0x36, 0x31, 0x30, 0x72, 0x43, 0x72, 0x6D, 0x2F, 0x62, 0x30, 0x31, 0x43, ++ 0x37, 0x6A, 0x63, 0x76, 0x6B, 0x32, 0x78, 0x75, 0x73, 0x56, 0x74, 0x79, 0x57, 0x4D, 0x4F, 0x76, 0x77, 0x6C, 0x0A, 0x44, 0x62, 0x4D, 0x69, 0x63, 0x79, 0x46, 0x30, 0x79, 0x45, 0x71, 0x57, 0x59, 0x5A, 0x4C, 0x31, 0x4C, 0x77, 0x73, 0x59, 0x70, ++ 0x66, 0x53, 0x74, 0x34, 0x75, 0x35, 0x42, 0x76, 0x51, 0x46, 0x35, 0x2B, 0x70, 0x61, 0x4D, 0x6A, 0x52, 0x63, 0x43, 0x4D, 0x4C, 0x54, 0x35, 0x72, 0x33, 0x67, 0x61, 0x6A, 0x4C, 0x51, 0x32, 0x45, 0x42, 0x41, 0x48, 0x42, 0x58, 0x44, 0x51, 0x39, ++ 0x44, 0x47, 0x51, 0x69, 0x6C, 0x48, 0x46, 0x68, 0x69, 0x5A, 0x35, 0x73, 0x68, 0x47, 0x49, 0x0A, 0x58, 0x73, 0x58, 0x77, 0x43, 0x6C, 0x54, 0x4E, 0x53, 0x61, 0x61, 0x2F, 0x41, 0x70, 0x7A, 0x53, 0x52, 0x4B, 0x66, 0x74, 0x34, 0x33, 0x6A, 0x76, ++ 0x52, 0x6C, 0x35, 0x74, 0x63, 0x64, 0x46, 0x35, 0x63, 0x42, 0x78, 0x47, 0x58, 0x31, 0x48, 0x70, 0x79, 0x54, 0x66, 0x63, 0x58, 0x33, 0x35, 0x70, 0x65, 0x30, 0x48, 0x66, 0x4E, 0x45, 0x58, 0x67, 0x4F, 0x34, 0x54, 0x30, 0x6F, 0x59, 0x6F, 0x4B, ++ 0x4E, 0x70, 0x34, 0x33, 0x7A, 0x47, 0x4A, 0x53, 0x34, 0x59, 0x6B, 0x4E, 0x0A, 0x4B, 0x50, 0x6C, 0x36, 0x49, 0x37, 0x45, 0x4E, 0x50, 0x54, 0x32, 0x61, 0x2F, 0x5A, 0x32, 0x42, 0x37, 0x79, 0x79, 0x51, 0x77, 0x48, 0x74, 0x45, 0x54, 0x72, 0x74, ++ 0x4A, 0x34, 0x41, 0x35, 0x4B, 0x56, 0x70, 0x4B, 0x38, 0x79, 0x37, 0x58, 0x64, 0x65, 0x52, 0x65, 0x4A, 0x6B, 0x64, 0x35, 0x68, 0x69, 0x58, 0x53, 0x53, 0x71, 0x4F, 0x4D, 0x79, 0x68, 0x62, 0x35, 0x4F, 0x68, 0x61, 0x52, 0x4C, 0x57, 0x63, 0x73, ++ 0x72, 0x78, 0x58, 0x69, 0x4F, 0x63, 0x56, 0x54, 0x51, 0x0A, 0x41, 0x6A, 0x65, 0x5A, 0x6A, 0x4F, 0x56, 0x4A, 0x36, 0x75, 0x42, 0x55, 0x63, 0x71, 0x51, 0x52, 0x42, 0x69, 0x38, 0x4C, 0x6A, 0x4D, 0x46, 0x62, 0x76, 0x72, 0x57, 0x68, 0x73, 0x46, ++ 0x4E, 0x75, 0x6E, 0x4C, 0x68, 0x67, 0x6B, 0x52, 0x39, 0x5A, 0x61, 0x2F, 0x6B, 0x74, 0x39, 0x4A, 0x51, 0x4B, 0x6C, 0x37, 0x58, 0x73, 0x78, 0x58, 0x59, 0x44, 0x56, 0x42, 0x74, 0x6C, 0x55, 0x72, 0x70, 0x4D, 0x6B, 0x6C, 0x5A, 0x52, 0x4E, 0x61, ++ 0x42, 0x41, 0x32, 0x43, 0x6E, 0x62, 0x0A, 0x72, 0x6C, 0x4A, 0x32, 0x4F, 0x79, 0x30, 0x77, 0x51, 0x4A, 0x75, 0x4B, 0x30, 0x45, 0x4A, 0x57, 0x74, 0x4C, 0x65, 0x49, 0x41, 0x61, 0x53, 0x48, 0x4F, 0x31, 0x4F, 0x57, 0x7A, 0x61, 0x4D, 0x57, 0x6A, ++ 0x2F, 0x4E, 0x6D, 0x71, 0x68, 0x65, 0x78, 0x78, 0x32, 0x44, 0x67, 0x77, 0x55, 0x4D, 0x46, 0x44, 0x4F, 0x36, 0x62, 0x57, 0x32, 0x42, 0x76, 0x42, 0x6C, 0x79, 0x48, 0x57, 0x79, 0x66, 0x35, 0x51, 0x42, 0x47, 0x65, 0x6E, 0x44, 0x50, 0x42, 0x74, ++ 0x2B, 0x55, 0x31, 0x0A, 0x56, 0x77, 0x56, 0x2F, 0x4A, 0x38, 0x34, 0x58, 0x49, 0x49, 0x77, 0x63, 0x2F, 0x50, 0x48, 0x37, 0x32, 0x6A, 0x45, 0x70, 0x53, 0x65, 0x33, 0x31, 0x43, 0x34, 0x53, 0x6E, 0x54, 0x38, 0x48, 0x32, 0x54, 0x73, 0x49, 0x6F, ++ 0x6E, 0x50, 0x72, 0x75, 0x34, 0x4B, 0x38, 0x48, 0x2B, 0x7A, 0x4D, 0x52, 0x65, 0x69, 0x46, 0x50, 0x43, 0x79, 0x45, 0x51, 0x74, 0x6B, 0x41, 0x36, 0x71, 0x79, 0x49, 0x36, 0x42, 0x4A, 0x79, 0x4C, 0x6D, 0x34, 0x53, 0x47, 0x63, 0x70, 0x72, 0x53, ++ 0x0A, 0x70, 0x36, 0x58, 0x45, 0x74, 0x48, 0x57, 0x52, 0x71, 0x53, 0x73, 0x6A, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, 0x51, 0x6A, 0x42, 0x41, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, ++ 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6A, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x0A, 0x44, 0x67, ++ 0x51, 0x57, 0x42, 0x42, 0x54, 0x67, 0x71, 0x6A, 0x38, 0x6C, 0x6A, 0x5A, 0x39, 0x45, 0x58, 0x4D, 0x45, 0x36, 0x36, 0x43, 0x36, 0x75, 0x64, 0x30, 0x79, 0x45, 0x50, 0x6D, 0x63, 0x4D, 0x39, 0x44, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, ++ 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x67, 0x45, 0x41, 0x75, 0x56, 0x65, 0x76, 0x75, 0x42, 0x4C, 0x61, 0x56, 0x34, 0x4F, 0x50, 0x61, 0x41, 0x73, 0x7A, 0x0A, 0x48, 0x51, 0x4E, 0x54, 0x56, ++ 0x66, 0x53, 0x56, 0x63, 0x4F, 0x51, 0x72, 0x50, 0x62, 0x41, 0x35, 0x36, 0x2F, 0x71, 0x4A, 0x59, 0x76, 0x33, 0x33, 0x31, 0x68, 0x67, 0x45, 0x4C, 0x79, 0x45, 0x30, 0x33, 0x66, 0x46, 0x6F, 0x38, 0x4E, 0x57, 0x57, 0x57, 0x74, 0x37, 0x43, 0x67, ++ 0x4B, 0x50, 0x42, 0x6A, 0x63, 0x5A, 0x71, 0x39, 0x31, 0x6C, 0x33, 0x72, 0x68, 0x56, 0x6B, 0x7A, 0x31, 0x74, 0x35, 0x42, 0x58, 0x64, 0x6D, 0x36, 0x6F, 0x7A, 0x54, 0x61, 0x77, 0x33, 0x64, 0x0A, 0x38, 0x56, 0x6B, 0x73, 0x77, 0x54, 0x4F, 0x6C, ++ 0x4D, 0x49, 0x41, 0x56, 0x52, 0x51, 0x64, 0x46, 0x47, 0x6A, 0x45, 0x69, 0x74, 0x70, 0x49, 0x41, 0x71, 0x35, 0x6C, 0x4E, 0x4F, 0x6F, 0x39, 0x33, 0x72, 0x36, 0x6B, 0x69, 0x79, 0x69, 0x39, 0x6A, 0x79, 0x68, 0x58, 0x57, 0x78, 0x38, 0x62, 0x77, ++ 0x50, 0x57, 0x7A, 0x38, 0x48, 0x41, 0x32, 0x59, 0x45, 0x47, 0x47, 0x65, 0x45, 0x61, 0x49, 0x69, 0x31, 0x77, 0x72, 0x79, 0x6B, 0x58, 0x70, 0x72, 0x4F, 0x51, 0x34, 0x76, 0x0A, 0x4D, 0x4D, 0x4D, 0x32, 0x53, 0x5A, 0x2F, 0x67, 0x36, 0x51, 0x38, ++ 0x43, 0x52, 0x46, 0x41, 0x33, 0x6C, 0x46, 0x56, 0x39, 0x36, 0x70, 0x2F, 0x32, 0x4F, 0x37, 0x71, 0x55, 0x70, 0x55, 0x7A, 0x70, 0x76, 0x44, 0x35, 0x52, 0x74, 0x4F, 0x6A, 0x4B, 0x6B, 0x6A, 0x5A, 0x55, 0x62, 0x56, 0x77, 0x6C, 0x4B, 0x4E, 0x72, ++ 0x64, 0x72, 0x52, 0x54, 0x39, 0x30, 0x2B, 0x37, 0x69, 0x49, 0x67, 0x58, 0x72, 0x30, 0x50, 0x4B, 0x33, 0x61, 0x42, 0x4C, 0x58, 0x57, 0x6F, 0x70, 0x42, 0x0A, 0x47, 0x73, 0x61, 0x53, 0x70, 0x56, 0x6F, 0x37, 0x59, 0x30, 0x56, 0x50, 0x76, 0x2B, ++ 0x45, 0x36, 0x64, 0x79, 0x49, 0x76, 0x58, 0x4C, 0x39, 0x47, 0x2B, 0x56, 0x6F, 0x44, 0x68, 0x52, 0x4E, 0x43, 0x58, 0x38, 0x72, 0x65, 0x55, 0x39, 0x64, 0x69, 0x74, 0x61, 0x59, 0x31, 0x42, 0x4D, 0x4A, 0x48, 0x2F, 0x35, 0x6E, 0x39, 0x68, 0x4E, ++ 0x39, 0x63, 0x7A, 0x75, 0x6C, 0x65, 0x67, 0x43, 0x68, 0x42, 0x38, 0x6E, 0x33, 0x6E, 0x48, 0x70, 0x44, 0x59, 0x54, 0x33, 0x59, 0x2B, 0x0A, 0x67, 0x6A, 0x77, 0x4E, 0x2F, 0x4B, 0x55, 0x44, 0x2B, 0x6E, 0x73, 0x61, 0x32, 0x55, 0x55, 0x65, 0x59, ++ 0x4E, 0x72, 0x45, 0x6A, 0x76, 0x6E, 0x38, 0x4B, 0x38, 0x6C, 0x37, 0x6C, 0x63, 0x55, 0x71, 0x2F, 0x36, 0x71, 0x4A, 0x33, 0x34, 0x49, 0x78, 0x44, 0x33, 0x4C, 0x2F, 0x44, 0x43, 0x66, 0x58, 0x43, 0x68, 0x35, 0x57, 0x41, 0x46, 0x41, 0x65, 0x44, ++ 0x4A, 0x44, 0x42, 0x6C, 0x72, 0x58, 0x59, 0x46, 0x49, 0x57, 0x37, 0x70, 0x77, 0x30, 0x57, 0x77, 0x66, 0x67, 0x48, 0x0A, 0x4A, 0x42, 0x75, 0x36, 0x68, 0x61, 0x45, 0x61, 0x42, 0x51, 0x6D, 0x41, 0x75, 0x70, 0x56, 0x6A, 0x79, 0x54, 0x72, 0x73, ++ 0x4A, 0x5A, 0x39, 0x2F, 0x6E, 0x62, 0x71, 0x6B, 0x52, 0x78, 0x57, 0x62, 0x52, 0x48, 0x44, 0x78, 0x61, 0x6B, 0x76, 0x57, 0x4F, 0x46, 0x35, 0x44, 0x38, 0x78, 0x68, 0x2B, 0x55, 0x47, 0x37, 0x70, 0x57, 0x69, 0x6A, 0x6D, 0x5A, 0x65, 0x5A, 0x33, ++ 0x47, 0x7A, 0x72, 0x39, 0x48, 0x62, 0x34, 0x44, 0x4A, 0x71, 0x50, 0x62, 0x31, 0x4F, 0x47, 0x37, 0x0A, 0x66, 0x70, 0x59, 0x6E, 0x4B, 0x78, 0x33, 0x75, 0x70, 0x50, 0x76, 0x61, 0x4A, 0x56, 0x51, 0x54, 0x41, 0x39, 0x34, 0x35, 0x78, 0x73, 0x4D, ++ 0x66, 0x54, 0x5A, 0x44, 0x73, 0x6A, 0x78, 0x74, 0x4B, 0x30, 0x68, 0x7A, 0x74, 0x68, 0x5A, 0x55, 0x34, 0x55, 0x48, 0x6C, 0x47, 0x31, 0x73, 0x47, 0x51, 0x55, 0x44, 0x47, 0x70, 0x58, 0x4A, 0x70, 0x75, 0x48, 0x66, 0x55, 0x7A, 0x56, 0x6F, 0x75, ++ 0x6E, 0x6D, 0x64, 0x4C, 0x79, 0x79, 0x43, 0x77, 0x7A, 0x6B, 0x35, 0x49, 0x77, 0x0A, 0x78, 0x30, 0x36, 0x4D, 0x5A, 0x54, 0x4D, 0x51, 0x5A, 0x42, 0x66, 0x39, 0x4A, 0x42, 0x65, 0x57, 0x30, 0x59, 0x33, 0x43, 0x4F, 0x6D, 0x6F, 0x72, 0x36, 0x78, ++ 0x4F, 0x4C, 0x52, 0x50, 0x49, 0x68, 0x38, 0x30, 0x6F, 0x61, 0x74, 0x33, 0x64, 0x66, 0x31, 0x2B, 0x32, 0x49, 0x70, 0x48, 0x4C, 0x6C, 0x4F, 0x52, 0x2B, 0x56, 0x6E, 0x62, 0x35, 0x6E, 0x77, 0x58, 0x41, 0x52, 0x50, 0x62, 0x76, 0x30, 0x2B, 0x45, ++ 0x6D, 0x33, 0x34, 0x79, 0x61, 0x58, 0x4F, 0x70, 0x2F, 0x53, 0x0A, 0x58, 0x33, 0x7A, 0x37, 0x77, 0x4A, 0x6C, 0x38, 0x4F, 0x53, 0x6E, 0x67, 0x65, 0x78, 0x32, 0x2F, 0x44, 0x61, 0x65, 0x50, 0x30, 0x69, 0x6B, 0x30, 0x62, 0x69, 0x51, 0x56, 0x79, ++ 0x39, 0x36, 0x51, 0x58, 0x72, 0x38, 0x61, 0x78, 0x47, 0x62, 0x71, 0x77, 0x75, 0x61, 0x36, 0x4F, 0x56, 0x2B, 0x4B, 0x6D, 0x61, 0x6C, 0x42, 0x57, 0x51, 0x65, 0x77, 0x4C, 0x4B, 0x38, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, ++ 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x43, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x45, 0x31, 0x0A, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, ++ 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x42, 0x39, 0x7A, 0x43, 0x43, 0x41, 0x58, 0x32, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x42, 0x69, 0x55, 0x7A, 0x73, 0x55, 0x63, 0x44, 0x4D, 0x79, 0x64, 0x63, 0x2B, 0x59, 0x32, 0x61, 0x75, ++ 0x62, 0x2F, 0x4D, 0x2B, 0x44, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x7A, 0x41, 0x39, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x56, 0x0A, ++ 0x55, 0x7A, 0x45, 0x53, 0x4D, 0x42, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x4A, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x46, 0x70, 0x62, 0x6D, 0x78, 0x35, 0x4D, 0x52, 0x6F, 0x77, 0x47, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, ++ 0x45, 0x78, 0x46, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x59, 0x57, 0x6C, 0x75, 0x62, 0x48, 0x6B, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x46, 0x4D, 0x54, 0x41, 0x65, 0x46, 0x77, 0x30, 0x79, 0x4D, 0x54, 0x41, 0x30, 0x0A, 0x4D, 0x44, 0x45, ++ 0x77, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x42, 0x61, 0x46, 0x77, 0x30, 0x30, 0x4E, 0x6A, 0x41, 0x30, 0x4D, 0x44, 0x45, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x42, 0x61, 0x4D, 0x44, 0x30, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, ++ 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6C, 0x56, 0x54, 0x4D, 0x52, 0x49, 0x77, 0x45, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x77, 0x6C, 0x44, 0x5A, 0x58, 0x4A, 0x30, 0x59, 0x57, 0x6C, 0x75, 0x0A, 0x62, 0x48, 0x6B, 0x78, 0x47, 0x6A, ++ 0x41, 0x59, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x45, 0x55, 0x4E, 0x6C, 0x63, 0x6E, 0x52, 0x68, 0x61, 0x57, 0x35, 0x73, 0x65, 0x53, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x55, 0x78, 0x4D, 0x48, 0x59, 0x77, 0x45, 0x41, ++ 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x46, 0x4B, 0x34, 0x45, 0x45, 0x41, 0x43, 0x49, 0x44, 0x59, 0x67, 0x41, 0x45, 0x33, 0x6D, 0x2F, 0x34, 0x0A, 0x66, 0x78, 0x7A, 0x66, 0x37, 0x66, 0x6C, 0x48, 0x68, ++ 0x34, 0x61, 0x78, 0x70, 0x4D, 0x43, 0x4B, 0x2B, 0x49, 0x4B, 0x58, 0x67, 0x4F, 0x71, 0x50, 0x79, 0x45, 0x70, 0x65, 0x4B, 0x6E, 0x32, 0x49, 0x61, 0x4B, 0x63, 0x42, 0x59, 0x68, 0x53, 0x52, 0x4A, 0x48, 0x70, 0x63, 0x6E, 0x71, 0x4D, 0x58, 0x66, ++ 0x59, 0x71, 0x47, 0x49, 0x54, 0x51, 0x59, 0x55, 0x42, 0x73, 0x51, 0x33, 0x74, 0x41, 0x33, 0x53, 0x79, 0x62, 0x48, 0x47, 0x57, 0x43, 0x41, 0x36, 0x54, 0x53, 0x39, 0x0A, 0x59, 0x42, 0x6B, 0x32, 0x51, 0x4E, 0x59, 0x70, 0x68, 0x77, 0x6B, 0x38, ++ 0x6B, 0x58, 0x72, 0x32, 0x76, 0x42, 0x4D, 0x6A, 0x33, 0x56, 0x6C, 0x4F, 0x42, 0x46, 0x37, 0x50, 0x79, 0x41, 0x49, 0x63, 0x47, 0x46, 0x50, 0x42, 0x4D, 0x64, 0x6A, 0x61, 0x49, 0x4F, 0x6C, 0x45, 0x6A, 0x65, 0x52, 0x32, 0x6F, 0x30, 0x49, 0x77, ++ 0x51, 0x44, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x51, 0x59, 0x77, 0x0A, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, ++ 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x38, 0x79, 0x67, 0x59, 0x79, 0x32, 0x52, 0x31, 0x37, 0x69, 0x6B, 0x71, 0x36, 0x2B, 0x32, 0x75, 0x49, 0x31, 0x67, ++ 0x34, 0x68, 0x65, 0x76, 0x49, 0x49, 0x67, 0x63, 0x77, 0x43, 0x67, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x45, 0x0A, 0x41, 0x77, 0x4D, 0x44, 0x61, 0x41, 0x41, 0x77, 0x5A, 0x51, 0x49, 0x78, 0x41, 0x4C, 0x47, 0x4F, 0x57, 0x69, ++ 0x44, 0x44, 0x73, 0x68, 0x6C, 0x69, 0x54, 0x64, 0x36, 0x77, 0x54, 0x39, 0x39, 0x75, 0x30, 0x6E, 0x43, 0x4B, 0x38, 0x5A, 0x39, 0x2B, 0x61, 0x6F, 0x7A, 0x6D, 0x75, 0x74, 0x36, 0x44, 0x61, 0x63, 0x70, 0x70, 0x73, 0x36, 0x6B, 0x46, 0x74, 0x5A, ++ 0x61, 0x53, 0x46, 0x34, 0x66, 0x43, 0x30, 0x75, 0x72, 0x51, 0x65, 0x38, 0x37, 0x59, 0x51, 0x56, 0x74, 0x38, 0x0A, 0x72, 0x67, 0x49, 0x77, 0x52, 0x74, 0x37, 0x71, 0x79, 0x31, 0x32, 0x61, 0x37, 0x44, 0x4C, 0x43, 0x5A, 0x52, 0x61, 0x77, 0x54, ++ 0x44, 0x42, 0x63, 0x4D, 0x50, 0x50, 0x61, 0x54, 0x6E, 0x4F, 0x47, 0x42, 0x74, 0x6A, 0x4F, 0x69, 0x51, 0x52, 0x49, 0x4E, 0x7A, 0x66, 0x34, 0x33, 0x54, 0x4E, 0x52, 0x6E, 0x58, 0x43, 0x76, 0x65, 0x31, 0x58, 0x59, 0x41, 0x53, 0x35, 0x39, 0x42, ++ 0x57, 0x51, 0x4F, 0x68, 0x72, 0x69, 0x52, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x53, 0x65, 0x63, 0x75, 0x72, ++ 0x69, 0x74, 0x79, 0x20, 0x43, 0x6F, 0x6D, 0x6D, 0x75, 0x6E, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, 0x31, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, ++ 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x4F, 0x44, 0x43, 0x43, 0x41, 0x62, 0x36, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x4A, 0x41, 0x4E, 0x5A, 0x64, 0x6D, 0x37, 0x4E, ++ 0x34, 0x67, 0x53, 0x37, 0x72, 0x4D, 0x41, 0x6F, 0x47, 0x43, 0x43, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x42, 0x41, 0x4D, 0x44, 0x4D, 0x47, 0x45, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x70, ++ 0x51, 0x4D, 0x53, 0x55, 0x77, 0x49, 0x77, 0x59, 0x44, 0x0A, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x78, 0x78, 0x54, 0x52, 0x55, 0x4E, 0x50, 0x54, 0x53, 0x42, 0x55, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x43, 0x42, 0x54, 0x65, 0x58, 0x4E, 0x30, 0x5A, 0x57, ++ 0x31, 0x7A, 0x49, 0x45, 0x4E, 0x50, 0x4C, 0x69, 0x78, 0x4D, 0x56, 0x45, 0x51, 0x75, 0x4D, 0x53, 0x73, 0x77, 0x4B, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x79, 0x4A, 0x54, 0x5A, 0x57, 0x4E, 0x31, 0x63, 0x6D, 0x6C, 0x30, 0x65, 0x53, ++ 0x42, 0x44, 0x62, 0x32, 0x31, 0x74, 0x0A, 0x64, 0x57, 0x35, 0x70, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x49, 0x45, 0x56, 0x44, 0x51, 0x79, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x51, 0x30, 0x45, 0x78, 0x4D, 0x42, 0x34, 0x58, 0x44, ++ 0x54, 0x45, 0x32, 0x4D, 0x44, 0x59, 0x78, 0x4E, 0x6A, 0x41, 0x31, 0x4D, 0x54, 0x55, 0x79, 0x4F, 0x46, 0x6F, 0x58, 0x44, 0x54, 0x4D, 0x34, 0x4D, 0x44, 0x45, 0x78, 0x4F, 0x44, 0x41, 0x31, 0x4D, 0x54, 0x55, 0x79, 0x4F, 0x46, 0x6F, 0x77, 0x59, ++ 0x54, 0x45, 0x4C, 0x0A, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x53, 0x6C, 0x41, 0x78, 0x4A, 0x54, 0x41, 0x6A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x48, 0x46, 0x4E, 0x46, 0x51, 0x30, 0x39, 0x4E, ++ 0x49, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x49, 0x46, 0x4E, 0x35, 0x63, 0x33, 0x52, 0x6C, 0x62, 0x58, 0x4D, 0x67, 0x51, 0x30, 0x38, 0x75, 0x4C, 0x45, 0x78, 0x55, 0x52, 0x43, 0x34, 0x78, 0x4B, 0x7A, 0x41, 0x70, 0x42, 0x67, 0x4E, 0x56, ++ 0x0A, 0x42, 0x41, 0x4D, 0x54, 0x49, 0x6C, 0x4E, 0x6C, 0x59, 0x33, 0x56, 0x79, 0x61, 0x58, 0x52, 0x35, 0x49, 0x45, 0x4E, 0x76, 0x62, 0x57, 0x31, 0x31, 0x62, 0x6D, 0x6C, 0x6A, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x67, 0x52, 0x55, 0x4E, ++ 0x44, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x52, 0x44, 0x51, 0x54, 0x45, 0x77, 0x64, 0x6A, 0x41, 0x51, 0x42, 0x67, 0x63, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x49, 0x42, 0x42, 0x67, 0x55, 0x72, 0x67, 0x51, 0x51, 0x41, 0x0A, 0x49, 0x67, ++ 0x4E, 0x69, 0x41, 0x41, 0x53, 0x6B, 0x70, 0x57, 0x39, 0x67, 0x41, 0x77, 0x50, 0x44, 0x76, 0x54, 0x48, 0x30, 0x30, 0x78, 0x65, 0x63, 0x4B, 0x34, 0x52, 0x31, 0x72, 0x4F, 0x58, 0x39, 0x50, 0x56, 0x64, 0x75, 0x31, 0x32, 0x4F, 0x2F, 0x35, 0x67, ++ 0x53, 0x4A, 0x6B, 0x6F, 0x36, 0x42, 0x6E, 0x4F, 0x50, 0x70, 0x52, 0x32, 0x37, 0x4B, 0x6B, 0x42, 0x4C, 0x49, 0x45, 0x2B, 0x43, 0x6E, 0x6E, 0x66, 0x64, 0x6C, 0x64, 0x42, 0x39, 0x73, 0x45, 0x4C, 0x4C, 0x6F, 0x0A, 0x35, 0x4F, 0x6E, 0x76, 0x62, ++ 0x59, 0x55, 0x79, 0x6D, 0x55, 0x53, 0x78, 0x58, 0x76, 0x33, 0x4D, 0x64, 0x68, 0x44, 0x59, 0x57, 0x37, 0x32, 0x69, 0x78, 0x76, 0x6E, 0x57, 0x51, 0x75, 0x52, 0x58, 0x64, 0x74, 0x79, 0x51, 0x77, 0x6A, 0x57, 0x70, 0x53, 0x34, 0x67, 0x38, 0x45, ++ 0x6B, 0x64, 0x74, 0x58, 0x50, 0x39, 0x4A, 0x54, 0x78, 0x70, 0x4B, 0x55, 0x4C, 0x47, 0x6A, 0x51, 0x6A, 0x42, 0x41, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x0A, 0x42, 0x42, 0x53, 0x47, 0x48, 0x4F, 0x66, 0x2B, ++ 0x4C, 0x61, 0x56, 0x4B, 0x69, 0x77, 0x6A, 0x2B, 0x4B, 0x42, 0x48, 0x36, 0x76, 0x71, 0x4E, 0x6D, 0x2B, 0x47, 0x42, 0x5A, 0x4C, 0x7A, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, ++ 0x41, 0x51, 0x59, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x4B, 0x0A, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, ++ 0x44, 0x41, 0x77, 0x4E, 0x6F, 0x41, 0x44, 0x42, 0x6C, 0x41, 0x6A, 0x41, 0x56, 0x58, 0x55, 0x49, 0x39, 0x2F, 0x4C, 0x62, 0x75, 0x39, 0x7A, 0x75, 0x78, 0x4E, 0x75, 0x69, 0x65, 0x39, 0x73, 0x52, 0x47, 0x4B, 0x45, 0x6B, 0x7A, 0x30, 0x46, 0x68, ++ 0x44, 0x4B, 0x6D, 0x4D, 0x70, 0x7A, 0x45, 0x32, 0x78, 0x74, 0x48, 0x71, 0x69, 0x75, 0x51, 0x30, 0x34, 0x70, 0x56, 0x31, 0x49, 0x4B, 0x76, 0x33, 0x4C, 0x0A, 0x73, 0x6E, 0x4E, 0x64, 0x6F, 0x34, 0x67, 0x49, 0x78, 0x77, 0x77, 0x43, 0x4D, 0x51, ++ 0x44, 0x41, 0x71, 0x79, 0x30, 0x4F, 0x62, 0x65, 0x30, 0x59, 0x6F, 0x74, 0x74, 0x54, 0x36, 0x53, 0x58, 0x62, 0x56, 0x51, 0x6A, 0x67, 0x55, 0x4D, 0x7A, 0x66, 0x52, 0x47, 0x45, 0x57, 0x67, 0x71, 0x74, 0x4A, 0x73, 0x4C, 0x4B, 0x42, 0x37, 0x48, ++ 0x4F, 0x48, 0x65, 0x4C, 0x52, 0x4D, 0x73, 0x6D, 0x49, 0x62, 0x45, 0x76, 0x6F, 0x57, 0x54, 0x53, 0x56, 0x4C, 0x59, 0x37, 0x30, 0x65, 0x0A, 0x4E, 0x39, 0x6B, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, ++ 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x42, 0x4A, 0x43, 0x41, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, ++ 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x64, 0x44, 0x43, 0x43, 0x41, 0x31, 0x79, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x56, 0x57, 0x39, 0x6C, 0x34, 0x37, 0x54, 0x5A, 0x6B, 0x47, 0x6F, 0x62, 0x43, 0x64, 0x46, ++ 0x73, 0x50, 0x73, 0x42, 0x73, 0x49, 0x44, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x42, 0x55, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, ++ 0x47, 0x0A, 0x45, 0x77, 0x4A, 0x44, 0x54, 0x6A, 0x45, 0x6D, 0x4D, 0x43, 0x51, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x64, 0x51, 0x6B, 0x56, 0x4A, 0x53, 0x6B, 0x6C, 0x4F, 0x52, 0x79, 0x42, 0x44, 0x52, 0x56, 0x4A, 0x55, 0x53, 0x55, ++ 0x5A, 0x4A, 0x51, 0x30, 0x46, 0x55, 0x52, 0x53, 0x42, 0x42, 0x56, 0x56, 0x52, 0x49, 0x54, 0x31, 0x4A, 0x4A, 0x56, 0x46, 0x6B, 0x78, 0x48, 0x54, 0x41, 0x62, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x46, 0x45, 0x4A, 0x4B, 0x0A, 0x51, ++ 0x30, 0x45, 0x67, 0x52, 0x32, 0x78, 0x76, 0x59, 0x6D, 0x46, 0x73, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x78, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x45, 0x35, 0x4D, 0x54, 0x49, 0x78, 0x4F, 0x54, 0x41, 0x7A, 0x4D, ++ 0x54, 0x59, 0x78, 0x4E, 0x31, 0x6F, 0x58, 0x44, 0x54, 0x51, 0x30, 0x4D, 0x54, 0x49, 0x78, 0x4D, 0x6A, 0x41, 0x7A, 0x4D, 0x54, 0x59, 0x78, 0x4E, 0x31, 0x6F, 0x77, 0x56, 0x44, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x0A, 0x41, 0x31, 0x55, 0x45, ++ 0x42, 0x68, 0x4D, 0x43, 0x51, 0x30, 0x34, 0x78, 0x4A, 0x6A, 0x41, 0x6B, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x48, 0x55, 0x4A, 0x46, 0x53, 0x55, 0x70, 0x4A, 0x54, 0x6B, 0x63, 0x67, 0x51, 0x30, 0x56, 0x53, 0x56, 0x45, 0x6C, 0x47, ++ 0x53, 0x55, 0x4E, 0x42, 0x56, 0x45, 0x55, 0x67, 0x51, 0x56, 0x56, 0x55, 0x53, 0x45, 0x39, 0x53, 0x53, 0x56, 0x52, 0x5A, 0x4D, 0x52, 0x30, 0x77, 0x47, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x0A, 0x44, 0x42, 0x52, 0x43, 0x53, 0x6B, 0x4E, ++ 0x42, 0x49, 0x45, 0x64, 0x73, 0x62, 0x32, 0x4A, 0x68, 0x62, 0x43, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x4D, 0x54, 0x43, 0x43, 0x41, 0x69, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, ++ 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x67, 0x6F, 0x43, 0x67, 0x67, 0x49, 0x42, 0x41, 0x50, 0x46, 0x6D, 0x0A, 0x43, 0x4C, 0x33, 0x5A, 0x78, 0x52, 0x56, 0x68, 0x79, 0x34, ++ 0x51, 0x45, 0x51, 0x61, 0x56, 0x70, 0x4E, 0x33, 0x63, 0x64, 0x77, 0x62, 0x42, 0x37, 0x2B, 0x73, 0x4E, 0x33, 0x53, 0x4A, 0x41, 0x54, 0x63, 0x6D, 0x54, 0x52, 0x75, 0x48, 0x79, 0x51, 0x4E, 0x5A, 0x30, 0x59, 0x65, 0x59, 0x6A, 0x6A, 0x6C, 0x77, ++ 0x45, 0x38, 0x52, 0x34, 0x48, 0x79, 0x44, 0x71, 0x4B, 0x59, 0x44, 0x5A, 0x34, 0x2F, 0x4E, 0x2B, 0x41, 0x5A, 0x73, 0x70, 0x44, 0x79, 0x52, 0x68, 0x79, 0x53, 0x0A, 0x73, 0x54, 0x70, 0x68, 0x7A, 0x76, 0x71, 0x33, 0x52, 0x70, 0x34, 0x44, 0x68, ++ 0x74, 0x63, 0x7A, 0x62, 0x75, 0x33, 0x33, 0x52, 0x59, 0x78, 0x32, 0x4E, 0x39, 0x35, 0x75, 0x6C, 0x70, 0x48, 0x33, 0x31, 0x33, 0x34, 0x72, 0x68, 0x78, 0x66, 0x56, 0x69, 0x7A, 0x58, 0x75, 0x68, 0x4A, 0x46, 0x79, 0x56, 0x39, 0x78, 0x67, 0x77, ++ 0x38, 0x4F, 0x35, 0x35, 0x38, 0x64, 0x6E, 0x4A, 0x43, 0x4E, 0x50, 0x59, 0x77, 0x70, 0x6A, 0x39, 0x6D, 0x5A, 0x39, 0x53, 0x31, 0x57, 0x6E, 0x0A, 0x50, 0x33, 0x68, 0x6B, 0x53, 0x57, 0x6B, 0x53, 0x6C, 0x2B, 0x42, 0x4D, 0x44, 0x64, 0x4D, 0x4A, ++ 0x6F, 0x44, 0x49, 0x77, 0x4F, 0x76, 0x71, 0x66, 0x77, 0x50, 0x4B, 0x63, 0x78, 0x52, 0x49, 0x71, 0x4C, 0x68, 0x79, 0x31, 0x42, 0x44, 0x50, 0x61, 0x70, 0x44, 0x67, 0x52, 0x61, 0x74, 0x37, 0x47, 0x47, 0x50, 0x5A, 0x48, 0x4F, 0x69, 0x4A, 0x42, ++ 0x68, 0x79, 0x4C, 0x38, 0x78, 0x49, 0x6B, 0x6F, 0x56, 0x4E, 0x69, 0x4D, 0x70, 0x54, 0x41, 0x4B, 0x2B, 0x42, 0x63, 0x57, 0x0A, 0x79, 0x71, 0x77, 0x33, 0x2F, 0x58, 0x6D, 0x6E, 0x6B, 0x52, 0x64, 0x34, 0x4F, 0x4A, 0x6D, 0x74, 0x57, 0x4F, 0x32, ++ 0x79, 0x33, 0x73, 0x79, 0x4A, 0x66, 0x51, 0x4F, 0x63, 0x73, 0x34, 0x6C, 0x6C, 0x35, 0x2B, 0x4D, 0x37, 0x73, 0x53, 0x4B, 0x47, 0x6A, 0x77, 0x5A, 0x74, 0x65, 0x41, 0x66, 0x39, 0x6B, 0x52, 0x4A, 0x2F, 0x73, 0x47, 0x73, 0x63, 0x69, 0x51, 0x33, ++ 0x35, 0x75, 0x4D, 0x74, 0x30, 0x57, 0x77, 0x66, 0x43, 0x79, 0x50, 0x51, 0x31, 0x30, 0x57, 0x52, 0x6A, 0x0A, 0x65, 0x75, 0x6C, 0x75, 0x6D, 0x69, 0x6A, 0x57, 0x4D, 0x4C, 0x33, 0x6D, 0x47, 0x39, 0x30, 0x56, 0x72, 0x34, 0x54, 0x71, 0x6E, 0x4D, ++ 0x66, 0x4B, 0x39, 0x51, 0x37, 0x71, 0x38, 0x6C, 0x30, 0x70, 0x68, 0x34, 0x39, 0x70, 0x63, 0x7A, 0x6D, 0x2B, 0x4C, 0x69, 0x52, 0x76, 0x52, 0x53, 0x47, 0x73, 0x78, 0x64, 0x52, 0x70, 0x4A, 0x51, 0x61, 0x44, 0x72, 0x58, 0x70, 0x49, 0x68, 0x52, ++ 0x4D, 0x73, 0x44, 0x51, 0x61, 0x34, 0x62, 0x48, 0x6C, 0x57, 0x2F, 0x4B, 0x4E, 0x6E, 0x0A, 0x4D, 0x6F, 0x48, 0x31, 0x56, 0x36, 0x58, 0x4B, 0x56, 0x30, 0x4A, 0x70, 0x36, 0x56, 0x77, 0x6B, 0x59, 0x65, 0x2F, 0x69, 0x4D, 0x42, 0x68, 0x4F, 0x52, ++ 0x4A, 0x68, 0x56, 0x62, 0x33, 0x72, 0x43, 0x6B, 0x39, 0x67, 0x5A, 0x74, 0x74, 0x35, 0x38, 0x52, 0x34, 0x6F, 0x52, 0x54, 0x6B, 0x6C, 0x48, 0x32, 0x79, 0x69, 0x55, 0x41, 0x67, 0x75, 0x55, 0x53, 0x69, 0x7A, 0x35, 0x45, 0x74, 0x42, 0x50, 0x36, ++ 0x44, 0x46, 0x2B, 0x62, 0x48, 0x71, 0x2F, 0x70, 0x6A, 0x2B, 0x62, 0x0A, 0x4F, 0x54, 0x30, 0x43, 0x46, 0x71, 0x4D, 0x59, 0x73, 0x32, 0x65, 0x73, 0x57, 0x7A, 0x38, 0x73, 0x67, 0x79, 0x74, 0x6E, 0x4F, 0x59, 0x46, 0x63, 0x75, 0x58, 0x36, 0x55, ++ 0x31, 0x57, 0x54, 0x64, 0x6E, 0x6F, 0x39, 0x75, 0x72, 0x75, 0x68, 0x38, 0x57, 0x37, 0x54, 0x58, 0x61, 0x6B, 0x64, 0x49, 0x31, 0x33, 0x36, 0x7A, 0x31, 0x43, 0x32, 0x4F, 0x56, 0x6E, 0x5A, 0x4F, 0x7A, 0x32, 0x6E, 0x78, 0x62, 0x6B, 0x52, 0x73, ++ 0x31, 0x43, 0x54, 0x71, 0x6A, 0x53, 0x53, 0x68, 0x0A, 0x47, 0x4C, 0x2B, 0x39, 0x56, 0x2F, 0x36, 0x70, 0x6D, 0x54, 0x57, 0x31, 0x32, 0x78, 0x42, 0x33, 0x75, 0x44, 0x31, 0x49, 0x75, 0x74, 0x62, 0x42, 0x35, 0x2F, 0x45, 0x6A, 0x50, 0x74, 0x66, ++ 0x66, 0x68, 0x5A, 0x30, 0x6E, 0x50, 0x4E, 0x52, 0x41, 0x76, 0x51, 0x6F, 0x4D, 0x76, 0x66, 0x58, 0x6E, 0x6A, 0x53, 0x58, 0x57, 0x67, 0x58, 0x53, 0x48, 0x52, 0x74, 0x51, 0x70, 0x64, 0x61, 0x4A, 0x43, 0x62, 0x50, 0x64, 0x7A, 0x69, 0x65, 0x64, ++ 0x39, 0x76, 0x33, 0x70, 0x4B, 0x0A, 0x48, 0x39, 0x4D, 0x69, 0x79, 0x52, 0x56, 0x56, 0x7A, 0x39, 0x39, 0x76, 0x66, 0x46, 0x58, 0x51, 0x70, 0x49, 0x73, 0x48, 0x45, 0x54, 0x64, 0x66, 0x67, 0x36, 0x59, 0x6D, 0x56, 0x36, 0x59, 0x42, 0x57, 0x33, ++ 0x37, 0x2B, 0x57, 0x47, 0x67, 0x48, 0x71, 0x65, 0x6C, 0x36, 0x32, 0x62, 0x6E, 0x6F, 0x2F, 0x31, 0x41, 0x66, 0x71, 0x38, 0x4B, 0x30, 0x77, 0x4D, 0x37, 0x6F, 0x36, 0x76, 0x30, 0x50, 0x76, 0x59, 0x31, 0x4E, 0x75, 0x4C, 0x78, 0x78, 0x41, 0x67, ++ 0x4D, 0x42, 0x0A, 0x41, 0x41, 0x47, 0x6A, 0x51, 0x6A, 0x42, 0x41, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x54, 0x46, 0x37, 0x2B, 0x33, 0x4D, 0x32, 0x49, 0x30, 0x68, 0x78, 0x6B, 0x6A, 0x6B, 0x34, ++ 0x39, 0x63, 0x55, 0x4C, 0x71, 0x63, 0x57, 0x6B, 0x2B, 0x57, 0x59, 0x41, 0x54, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x41, 0x34, 0x47, 0x0A, ++ 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x41, 0x4F, 0x43, ++ 0x41, 0x67, 0x45, 0x41, 0x55, 0x6F, 0x4B, 0x73, 0x49, 0x54, 0x51, 0x66, 0x49, 0x2F, 0x4B, 0x69, 0x32, 0x50, 0x6D, 0x34, 0x72, 0x7A, 0x63, 0x32, 0x49, 0x49, 0x6E, 0x52, 0x4E, 0x77, 0x50, 0x57, 0x61, 0x5A, 0x2B, 0x34, 0x0A, 0x59, 0x52, 0x43, ++ 0x36, 0x6F, 0x6A, 0x47, 0x59, 0x57, 0x55, 0x66, 0x6F, 0x30, 0x51, 0x30, 0x6C, 0x48, 0x68, 0x56, 0x42, 0x44, 0x4F, 0x41, 0x71, 0x56, 0x64, 0x56, 0x58, 0x55, 0x73, 0x76, 0x34, 0x35, 0x4D, 0x64, 0x70, 0x6F, 0x78, 0x31, 0x4E, 0x63, 0x51, 0x4A, ++ 0x65, 0x58, 0x79, 0x46, 0x46, 0x59, 0x45, 0x68, 0x63, 0x43, 0x59, 0x35, 0x4A, 0x45, 0x4D, 0x45, 0x45, 0x33, 0x4B, 0x6C, 0x69, 0x61, 0x77, 0x4C, 0x77, 0x51, 0x38, 0x68, 0x4F, 0x6E, 0x54, 0x68, 0x4A, 0x0A, 0x64, 0x4D, 0x6B, 0x79, 0x63, 0x46, ++ 0x52, 0x74, 0x77, 0x55, 0x66, 0x38, 0x6A, 0x72, 0x51, 0x32, 0x6E, 0x74, 0x53, 0x63, 0x76, 0x64, 0x30, 0x67, 0x31, 0x6C, 0x50, 0x4A, 0x47, 0x4B, 0x6D, 0x31, 0x56, 0x72, 0x6C, 0x32, 0x69, 0x35, 0x56, 0x6E, 0x5A, 0x75, 0x36, 0x39, 0x6D, 0x50, ++ 0x36, 0x75, 0x37, 0x37, 0x35, 0x75, 0x2B, 0x32, 0x44, 0x32, 0x2F, 0x56, 0x6E, 0x47, 0x4B, 0x68, 0x73, 0x2F, 0x49, 0x30, 0x71, 0x55, 0x4A, 0x44, 0x41, 0x6E, 0x79, 0x49, 0x6D, 0x38, 0x0A, 0x36, 0x30, 0x51, 0x6B, 0x6D, 0x73, 0x73, 0x39, 0x76, ++ 0x6B, 0x2F, 0x56, 0x65, 0x73, 0x36, 0x4F, 0x46, 0x38, 0x74, 0x69, 0x77, 0x64, 0x6E, 0x65, 0x48, 0x67, 0x35, 0x36, 0x2F, 0x30, 0x4F, 0x47, 0x4E, 0x46, 0x4B, 0x38, 0x59, 0x54, 0x38, 0x38, 0x58, 0x37, 0x76, 0x5A, 0x64, 0x72, 0x52, 0x54, 0x76, ++ 0x4A, 0x65, 0x7A, 0x2F, 0x6F, 0x70, 0x4D, 0x45, 0x69, 0x34, 0x72, 0x38, 0x39, 0x66, 0x4F, 0x34, 0x61, 0x4C, 0x2F, 0x33, 0x58, 0x74, 0x77, 0x2B, 0x7A, 0x75, 0x68, 0x0A, 0x54, 0x61, 0x52, 0x6A, 0x41, 0x76, 0x30, 0x34, 0x6C, 0x35, 0x55, 0x2F, ++ 0x42, 0x58, 0x43, 0x67, 0x61, 0x39, 0x39, 0x69, 0x67, 0x55, 0x4F, 0x4C, 0x74, 0x46, 0x6B, 0x4E, 0x53, 0x6F, 0x78, 0x55, 0x6E, 0x4D, 0x57, 0x37, 0x67, 0x5A, 0x2F, 0x4E, 0x66, 0x61, 0x58, 0x76, 0x43, 0x79, 0x55, 0x65, 0x4F, 0x69, 0x44, 0x62, ++ 0x48, 0x50, 0x77, 0x66, 0x6D, 0x47, 0x63, 0x43, 0x43, 0x74, 0x52, 0x7A, 0x52, 0x42, 0x50, 0x62, 0x55, 0x59, 0x51, 0x61, 0x56, 0x51, 0x4E, 0x57, 0x0A, 0x34, 0x41, 0x42, 0x2B, 0x64, 0x41, 0x62, 0x2F, 0x4F, 0x4D, 0x52, 0x79, 0x48, 0x64, 0x4F, ++ 0x6F, 0x50, 0x32, 0x67, 0x78, 0x58, 0x64, 0x4D, 0x4A, 0x78, 0x79, 0x36, 0x4D, 0x57, 0x32, 0x50, 0x67, 0x36, 0x4E, 0x77, 0x65, 0x30, 0x75, 0x78, 0x68, 0x48, 0x76, 0x4C, 0x65, 0x35, 0x65, 0x2F, 0x32, 0x6D, 0x58, 0x5A, 0x67, 0x4C, 0x52, 0x36, ++ 0x55, 0x63, 0x6E, 0x48, 0x47, 0x43, 0x79, 0x6F, 0x79, 0x78, 0x35, 0x4A, 0x4F, 0x31, 0x55, 0x62, 0x58, 0x48, 0x66, 0x6D, 0x70, 0x0A, 0x47, 0x51, 0x72, 0x49, 0x2B, 0x70, 0x58, 0x4F, 0x62, 0x53, 0x4F, 0x59, 0x71, 0x67, 0x73, 0x34, 0x72, 0x5A, ++ 0x70, 0x57, 0x44, 0x57, 0x2B, 0x4E, 0x38, 0x54, 0x45, 0x41, 0x69, 0x4D, 0x45, 0x58, 0x6E, 0x4D, 0x30, 0x5A, 0x4E, 0x6A, 0x58, 0x2B, 0x56, 0x56, 0x4F, 0x67, 0x34, 0x44, 0x77, 0x7A, 0x58, 0x35, 0x5A, 0x65, 0x34, 0x6A, 0x4C, 0x70, 0x33, 0x7A, ++ 0x4F, 0x37, 0x42, 0x6B, 0x71, 0x70, 0x32, 0x49, 0x52, 0x7A, 0x7A, 0x6E, 0x66, 0x53, 0x78, 0x71, 0x78, 0x78, 0x0A, 0x34, 0x56, 0x79, 0x6A, 0x48, 0x51, 0x79, 0x37, 0x43, 0x74, 0x39, 0x66, 0x34, 0x71, 0x4E, 0x78, 0x32, 0x4E, 0x6F, 0x33, 0x57, ++ 0x71, 0x42, 0x34, 0x4B, 0x2F, 0x54, 0x55, 0x66, 0x65, 0x74, 0x32, 0x37, 0x66, 0x4A, 0x68, 0x63, 0x4B, 0x56, 0x6C, 0x6D, 0x74, 0x4F, 0x4A, 0x4E, 0x42, 0x69, 0x72, 0x2B, 0x33, 0x49, 0x2B, 0x31, 0x37, 0x51, 0x39, 0x65, 0x56, 0x7A, 0x59, 0x48, ++ 0x36, 0x45, 0x7A, 0x65, 0x39, 0x6D, 0x43, 0x55, 0x41, 0x79, 0x54, 0x46, 0x36, 0x70, 0x73, 0x0A, 0x33, 0x4D, 0x4B, 0x43, 0x75, 0x77, 0x4A, 0x58, 0x4E, 0x71, 0x2B, 0x59, 0x4A, 0x79, 0x6F, 0x35, 0x55, 0x4F, 0x47, 0x77, 0x69, 0x66, 0x55, 0x6C, ++ 0x6C, 0x33, 0x35, 0x48, 0x61, 0x42, 0x43, 0x30, 0x37, 0x48, 0x50, 0x4B, 0x73, 0x35, 0x66, 0x52, 0x4A, 0x4E, 0x7A, 0x32, 0x59, 0x71, 0x41, 0x6F, 0x30, 0x37, 0x57, 0x6A, 0x75, 0x47, 0x53, 0x33, 0x69, 0x47, 0x4A, 0x43, 0x7A, 0x35, 0x31, 0x54, ++ 0x7A, 0x5A, 0x6D, 0x2B, 0x5A, 0x47, 0x69, 0x50, 0x54, 0x78, 0x34, 0x53, 0x0A, 0x53, 0x50, 0x66, 0x53, 0x4B, 0x63, 0x4F, 0x59, 0x4B, 0x4D, 0x72, 0x79, 0x4D, 0x67, 0x75, 0x54, 0x6A, 0x43, 0x6C, 0x50, 0x50, 0x47, 0x41, 0x79, 0x7A, 0x51, 0x57, ++ 0x57, 0x59, 0x65, 0x7A, 0x79, 0x72, 0x2F, 0x36, 0x7A, 0x63, 0x43, 0x77, 0x75, 0x70, 0x76, 0x49, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, ++ 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x42, 0x4A, 0x43, 0x41, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x32, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x4A, ++ 0x54, 0x43, 0x43, 0x41, 0x61, 0x75, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x4C, 0x42, 0x63, 0x49, 0x66, 0x57, 0x51, 0x71, 0x77, 0x50, 0x36, 0x46, 0x47, 0x46, 0x6B, 0x47, 0x7A, 0x37, 0x52, 0x4B, 0x36, 0x7A, 0x41, 0x4B, 0x42, ++ 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x7A, 0x42, 0x55, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x44, 0x0A, 0x54, 0x6A, 0x45, 0x6D, 0x4D, 0x43, 0x51, 0x47, ++ 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x64, 0x51, 0x6B, 0x56, 0x4A, 0x53, 0x6B, 0x6C, 0x4F, 0x52, 0x79, 0x42, 0x44, 0x52, 0x56, 0x4A, 0x55, 0x53, 0x55, 0x5A, 0x4A, 0x51, 0x30, 0x46, 0x55, 0x52, 0x53, 0x42, 0x42, 0x56, 0x56, 0x52, 0x49, ++ 0x54, 0x31, 0x4A, 0x4A, 0x56, 0x46, 0x6B, 0x78, 0x48, 0x54, 0x41, 0x62, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x46, 0x45, 0x4A, 0x4B, 0x51, 0x30, 0x45, 0x67, 0x0A, 0x52, 0x32, 0x78, 0x76, 0x59, 0x6D, 0x46, 0x73, 0x49, 0x46, 0x4A, ++ 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x79, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x45, 0x35, 0x4D, 0x54, 0x49, 0x78, 0x4F, 0x54, 0x41, 0x7A, 0x4D, 0x54, 0x67, 0x79, 0x4D, 0x56, 0x6F, 0x58, 0x44, 0x54, 0x51, 0x30, 0x4D, 0x54, 0x49, ++ 0x78, 0x4D, 0x6A, 0x41, 0x7A, 0x4D, 0x54, 0x67, 0x79, 0x4D, 0x56, 0x6F, 0x77, 0x56, 0x44, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0A, 0x42, 0x68, 0x4D, 0x43, 0x51, 0x30, 0x34, 0x78, 0x4A, 0x6A, 0x41, 0x6B, 0x42, 0x67, ++ 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x48, 0x55, 0x4A, 0x46, 0x53, 0x55, 0x70, 0x4A, 0x54, 0x6B, 0x63, 0x67, 0x51, 0x30, 0x56, 0x53, 0x56, 0x45, 0x6C, 0x47, 0x53, 0x55, 0x4E, 0x42, 0x56, 0x45, 0x55, 0x67, 0x51, 0x56, 0x56, 0x55, 0x53, 0x45, ++ 0x39, 0x53, 0x53, 0x56, 0x52, 0x5A, 0x4D, 0x52, 0x30, 0x77, 0x47, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x42, 0x52, 0x43, 0x0A, 0x53, 0x6B, 0x4E, 0x42, 0x49, 0x45, 0x64, 0x73, 0x62, 0x32, 0x4A, 0x68, 0x62, 0x43, 0x42, 0x53, 0x62, ++ 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x4D, 0x6A, 0x42, 0x32, 0x4D, 0x42, 0x41, 0x47, 0x42, 0x79, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x41, 0x67, 0x45, 0x47, 0x42, 0x53, 0x75, 0x42, 0x42, 0x41, 0x41, 0x69, 0x41, 0x32, 0x49, 0x41, 0x42, ++ 0x4A, 0x33, 0x4C, 0x67, 0x4A, 0x47, 0x4E, 0x55, 0x32, 0x65, 0x31, 0x75, 0x56, 0x43, 0x78, 0x41, 0x2F, 0x6A, 0x6C, 0x0A, 0x53, 0x52, 0x39, 0x42, 0x49, 0x67, 0x6D, 0x77, 0x55, 0x56, 0x4A, 0x59, 0x31, 0x69, 0x73, 0x30, 0x6A, 0x38, 0x55, 0x53, ++ 0x52, 0x68, 0x54, 0x46, 0x69, 0x79, 0x38, 0x73, 0x68, 0x50, 0x38, 0x73, 0x62, 0x71, 0x6A, 0x56, 0x38, 0x51, 0x6E, 0x6A, 0x41, 0x79, 0x45, 0x55, 0x78, 0x45, 0x4D, 0x39, 0x66, 0x4D, 0x45, 0x73, 0x78, 0x45, 0x74, 0x71, 0x53, 0x73, 0x33, 0x70, ++ 0x68, 0x2B, 0x42, 0x39, 0x39, 0x69, 0x4B, 0x2B, 0x2B, 0x6B, 0x70, 0x52, 0x75, 0x44, 0x43, 0x4B, 0x0A, 0x2F, 0x65, 0x48, 0x65, 0x47, 0x42, 0x49, 0x4B, 0x39, 0x6B, 0x65, 0x33, 0x35, 0x78, 0x65, 0x2F, 0x4A, 0x34, 0x72, 0x55, 0x51, 0x55, 0x79, ++ 0x57, 0x50, 0x47, 0x43, 0x57, 0x77, 0x66, 0x30, 0x56, 0x48, 0x4B, 0x4E, 0x43, 0x4D, 0x45, 0x41, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x46, 0x4E, 0x4A, 0x4B, 0x73, 0x56, 0x46, 0x2F, 0x42, 0x76, 0x44, ++ 0x52, 0x67, 0x68, 0x39, 0x4F, 0x62, 0x6C, 0x2B, 0x72, 0x67, 0x2F, 0x78, 0x49, 0x0A, 0x31, 0x4C, 0x43, 0x52, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, ++ 0x38, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4D, 0x41, 0x6F, 0x47, 0x43, 0x43, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x42, 0x41, 0x4D, 0x44, 0x41, 0x32, ++ 0x67, 0x41, 0x4D, 0x47, 0x55, 0x43, 0x4D, 0x42, 0x71, 0x38, 0x0A, 0x57, 0x39, 0x66, 0x2B, 0x71, 0x64, 0x4A, 0x55, 0x44, 0x6B, 0x70, 0x64, 0x30, 0x6D, 0x32, 0x78, 0x51, 0x4E, 0x7A, 0x30, 0x51, 0x39, 0x58, 0x53, 0x53, 0x70, 0x6B, 0x5A, 0x45, ++ 0x6C, 0x61, 0x41, 0x39, 0x34, 0x4D, 0x30, 0x34, 0x54, 0x56, 0x4F, 0x53, 0x47, 0x30, 0x45, 0x44, 0x31, 0x63, 0x78, 0x4D, 0x44, 0x41, 0x74, 0x73, 0x61, 0x71, 0x64, 0x41, 0x7A, 0x6A, 0x62, 0x42, 0x67, 0x49, 0x78, 0x41, 0x4D, 0x76, 0x4D, 0x68, ++ 0x31, 0x50, 0x4C, 0x65, 0x74, 0x38, 0x67, 0x0A, 0x55, 0x58, 0x4F, 0x51, 0x77, 0x4B, 0x68, 0x62, 0x59, 0x64, 0x44, 0x46, 0x55, 0x44, 0x6E, 0x39, 0x68, 0x66, 0x37, 0x42, 0x34, 0x33, 0x6A, 0x34, 0x70, 0x74, 0x5A, 0x4C, 0x76, 0x5A, 0x75, 0x48, ++ 0x6A, 0x77, 0x2F, 0x6C, 0x31, 0x6C, 0x4F, 0x57, 0x71, 0x7A, 0x7A, 0x49, 0x51, 0x4E, 0x70, 0x68, 0x39, 0x31, 0x4F, 0x6A, 0x39, 0x77, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, ++ 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, ++ 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x45, 0x34, 0x36, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, ++ 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x4F, 0x6A, 0x43, 0x43, 0x41, 0x63, 0x47, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x51, 0x76, 0x4C, 0x4D, 0x32, 0x68, 0x74, 0x70, ++ 0x4E, 0x30, 0x52, 0x66, 0x46, 0x66, 0x35, 0x31, 0x4B, 0x42, 0x43, 0x34, 0x39, 0x44, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x7A, 0x42, 0x66, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, ++ 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x48, 0x0A, 0x51, 0x6A, 0x45, 0x59, 0x4D, 0x42, 0x59, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x50, 0x55, 0x32, 0x56, 0x6A, 0x64, 0x47, 0x6C, 0x6E, 0x62, 0x79, 0x42, 0x4D, 0x61, 0x57, 0x31, ++ 0x70, 0x64, 0x47, 0x56, 0x6B, 0x4D, 0x54, 0x59, 0x77, 0x4E, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x79, 0x31, 0x54, 0x5A, 0x57, 0x4E, 0x30, 0x61, 0x57, 0x64, 0x76, 0x49, 0x46, 0x42, 0x31, 0x59, 0x6D, 0x78, 0x70, 0x59, 0x79, 0x42, ++ 0x54, 0x5A, 0x58, 0x4A, 0x32, 0x0A, 0x5A, 0x58, 0x49, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x56, 0x75, 0x64, 0x47, 0x6C, 0x6A, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x46, 0x4E, 0x44, ++ 0x59, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x6A, 0x45, 0x77, 0x4D, 0x7A, 0x49, 0x79, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x57, 0x68, 0x63, 0x4E, 0x4E, 0x44, 0x59, 0x77, 0x4D, 0x7A, 0x49, 0x78, 0x4D, 0x6A, 0x4D, 0x31, 0x4F, 0x54, ++ 0x55, 0x35, 0x0A, 0x57, 0x6A, 0x42, 0x66, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x48, 0x51, 0x6A, 0x45, 0x59, 0x4D, 0x42, 0x59, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x50, 0x55, ++ 0x32, 0x56, 0x6A, 0x64, 0x47, 0x6C, 0x6E, 0x62, 0x79, 0x42, 0x4D, 0x61, 0x57, 0x31, 0x70, 0x64, 0x47, 0x56, 0x6B, 0x4D, 0x54, 0x59, 0x77, 0x4E, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x79, 0x31, 0x54, 0x5A, 0x57, 0x4E, 0x30, 0x0A, ++ 0x61, 0x57, 0x64, 0x76, 0x49, 0x46, 0x42, 0x31, 0x59, 0x6D, 0x78, 0x70, 0x59, 0x79, 0x42, 0x54, 0x5A, 0x58, 0x4A, 0x32, 0x5A, 0x58, 0x49, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x56, 0x75, 0x64, 0x47, 0x6C, 0x6A, 0x59, 0x58, 0x52, 0x70, ++ 0x62, 0x32, 0x34, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x46, 0x4E, 0x44, 0x59, 0x77, 0x64, 0x6A, 0x41, 0x51, 0x42, 0x67, 0x63, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x49, 0x42, 0x42, 0x67, 0x55, 0x72, 0x0A, 0x67, 0x51, 0x51, ++ 0x41, 0x49, 0x67, 0x4E, 0x69, 0x41, 0x41, 0x52, 0x32, 0x2B, 0x70, 0x6D, 0x70, 0x62, 0x69, 0x44, 0x74, 0x2B, 0x64, 0x64, 0x33, 0x34, 0x77, 0x63, 0x37, 0x71, 0x4E, 0x73, 0x39, 0x58, 0x7A, 0x6A, 0x6F, 0x71, 0x31, 0x57, 0x6D, 0x56, 0x6B, 0x2F, ++ 0x57, 0x53, 0x4F, 0x72, 0x73, 0x66, 0x79, 0x32, 0x71, 0x77, 0x37, 0x4C, 0x46, 0x65, 0x65, 0x79, 0x5A, 0x59, 0x58, 0x38, 0x51, 0x65, 0x63, 0x63, 0x43, 0x57, 0x76, 0x6B, 0x45, 0x4E, 0x2F, 0x55, 0x30, 0x0A, 0x4E, 0x53, 0x74, 0x33, 0x7A, 0x6E, ++ 0x38, 0x67, 0x6A, 0x31, 0x4B, 0x6A, 0x41, 0x49, 0x6E, 0x73, 0x31, 0x61, 0x65, 0x69, 0x62, 0x56, 0x76, 0x6A, 0x53, 0x35, 0x4B, 0x54, 0x6F, 0x49, 0x44, 0x31, 0x41, 0x5A, 0x54, 0x63, 0x38, 0x47, 0x67, 0x48, 0x48, 0x73, 0x33, 0x75, 0x2F, 0x69, ++ 0x56, 0x53, 0x74, 0x53, 0x42, 0x44, 0x48, 0x42, 0x76, 0x2B, 0x36, 0x78, 0x6E, 0x4F, 0x51, 0x36, 0x4F, 0x6A, 0x51, 0x6A, 0x42, 0x41, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x0A, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x54, 0x52, 0x49, ++ 0x74, 0x70, 0x4D, 0x57, 0x66, 0x46, 0x4C, 0x58, 0x79, 0x59, 0x34, 0x71, 0x70, 0x33, 0x57, 0x37, 0x75, 0x73, 0x4E, 0x77, 0x2F, 0x75, 0x70, 0x59, 0x54, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, ++ 0x41, 0x4D, 0x43, 0x41, 0x59, 0x59, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x0A, 0x2F, 0x7A, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, ++ 0x50, 0x51, 0x51, 0x44, 0x41, 0x77, 0x4E, 0x6E, 0x41, 0x44, 0x42, 0x6B, 0x41, 0x6A, 0x41, 0x6E, 0x37, 0x71, 0x52, 0x61, 0x71, 0x43, 0x47, 0x37, 0x36, 0x55, 0x65, 0x58, 0x6C, 0x49, 0x6D, 0x6C, 0x64, 0x43, 0x42, 0x74, 0x65, 0x55, 0x2F, 0x49, ++ 0x76, 0x5A, 0x4E, 0x65, 0x57, 0x42, 0x6A, 0x37, 0x4C, 0x52, 0x6F, 0x41, 0x61, 0x73, 0x6D, 0x34, 0x50, 0x64, 0x43, 0x6B, 0x54, 0x30, 0x52, 0x48, 0x0A, 0x6C, 0x41, 0x46, 0x57, 0x6F, 0x76, 0x67, 0x7A, 0x4A, 0x51, 0x78, 0x43, 0x33, 0x36, 0x6F, ++ 0x43, 0x4D, 0x42, 0x33, 0x71, 0x34, 0x53, 0x36, 0x49, 0x4C, 0x75, 0x48, 0x35, 0x70, 0x78, 0x30, 0x43, 0x4D, 0x6B, 0x37, 0x79, 0x6E, 0x32, 0x78, 0x56, 0x64, 0x4F, 0x4F, 0x75, 0x72, 0x76, 0x75, 0x6C, 0x47, 0x75, 0x37, 0x74, 0x30, 0x76, 0x7A, ++ 0x43, 0x41, 0x78, 0x48, 0x72, 0x52, 0x56, 0x78, 0x67, 0x45, 0x44, 0x31, 0x63, 0x66, 0x35, 0x6B, 0x44, 0x57, 0x32, 0x31, 0x55, 0x0A, 0x53, 0x41, 0x47, 0x4B, 0x63, 0x77, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, ++ 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, ++ 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x34, 0x36, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, ++ 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x69, 0x6A, 0x43, 0x43, 0x41, 0x33, 0x4B, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x64, 0x59, ++ 0x33, 0x39, 0x69, 0x36, 0x35, 0x38, 0x42, 0x77, 0x44, 0x36, 0x71, 0x53, 0x57, 0x6E, 0x34, 0x63, 0x65, 0x74, 0x46, 0x44, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x77, 0x46, 0x41, 0x44, ++ 0x42, 0x66, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0A, 0x45, 0x77, 0x4A, 0x48, 0x51, 0x6A, 0x45, 0x59, 0x4D, 0x42, 0x59, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x50, 0x55, 0x32, 0x56, 0x6A, 0x64, ++ 0x47, 0x6C, 0x6E, 0x62, 0x79, 0x42, 0x4D, 0x61, 0x57, 0x31, 0x70, 0x64, 0x47, 0x56, 0x6B, 0x4D, 0x54, 0x59, 0x77, 0x4E, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x79, 0x31, 0x54, 0x5A, 0x57, 0x4E, 0x30, 0x61, 0x57, 0x64, 0x76, 0x49, ++ 0x46, 0x42, 0x31, 0x59, 0x6D, 0x78, 0x70, 0x59, 0x79, 0x42, 0x54, 0x0A, 0x5A, 0x58, 0x4A, 0x32, 0x5A, 0x58, 0x49, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x56, 0x75, 0x64, 0x47, 0x6C, 0x6A, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x67, ++ 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x53, 0x4E, 0x44, 0x59, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x6A, 0x45, 0x77, 0x4D, 0x7A, 0x49, 0x79, 0x4D, 0x44, 0x41, 0x77, 0x4D, 0x44, 0x41, 0x77, 0x57, 0x68, 0x63, 0x4E, 0x4E, 0x44, 0x59, 0x77, ++ 0x4D, 0x7A, 0x49, 0x78, 0x4D, 0x6A, 0x4D, 0x31, 0x0A, 0x4F, 0x54, 0x55, 0x35, 0x57, 0x6A, 0x42, 0x66, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x48, 0x51, 0x6A, 0x45, 0x59, 0x4D, 0x42, 0x59, ++ 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x50, 0x55, 0x32, 0x56, 0x6A, 0x64, 0x47, 0x6C, 0x6E, 0x62, 0x79, 0x42, 0x4D, 0x61, 0x57, 0x31, 0x70, 0x64, 0x47, 0x56, 0x6B, 0x4D, 0x54, 0x59, 0x77, 0x4E, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, ++ 0x44, 0x45, 0x79, 0x31, 0x54, 0x0A, 0x5A, 0x57, 0x4E, 0x30, 0x61, 0x57, 0x64, 0x76, 0x49, 0x46, 0x42, 0x31, 0x59, 0x6D, 0x78, 0x70, 0x59, 0x79, 0x42, 0x54, 0x5A, 0x58, 0x4A, 0x32, 0x5A, 0x58, 0x49, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, ++ 0x56, 0x75, 0x64, 0x47, 0x6C, 0x6A, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x53, 0x4E, 0x44, 0x59, 0x77, 0x67, 0x67, 0x49, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, ++ 0x62, 0x33, 0x0A, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x43, 0x54, 0x76, 0x74, 0x55, 0x32, 0x55, 0x6E, 0x58, 0x59, 0x41, ++ 0x53, 0x4F, 0x67, 0x48, 0x45, 0x64, 0x43, 0x53, 0x65, 0x35, 0x6A, 0x74, 0x72, 0x63, 0x68, 0x2F, 0x63, 0x53, 0x56, 0x31, 0x55, 0x67, 0x72, 0x4A, 0x6E, 0x77, 0x55, 0x55, 0x78, 0x44, 0x61, 0x65, 0x66, 0x30, 0x72, 0x74, 0x79, 0x32, 0x6B, 0x0A, ++ 0x31, 0x43, 0x7A, 0x36, 0x36, 0x6A, 0x4C, 0x64, 0x53, 0x63, 0x4B, 0x35, 0x76, 0x51, 0x39, 0x49, 0x50, 0x58, 0x74, 0x61, 0x6D, 0x46, 0x53, 0x76, 0x6E, 0x6C, 0x30, 0x78, 0x64, 0x45, 0x38, 0x48, 0x2F, 0x46, 0x41, 0x68, 0x33, 0x61, 0x54, 0x50, ++ 0x61, 0x45, 0x38, 0x62, 0x45, 0x6D, 0x4E, 0x74, 0x4A, 0x5A, 0x6C, 0x4D, 0x4B, 0x70, 0x6E, 0x7A, 0x53, 0x44, 0x42, 0x68, 0x2B, 0x6F, 0x46, 0x38, 0x48, 0x71, 0x63, 0x49, 0x53, 0x74, 0x77, 0x2B, 0x4B, 0x78, 0x77, 0x66, 0x0A, 0x47, 0x45, 0x78, ++ 0x78, 0x71, 0x6A, 0x57, 0x4D, 0x72, 0x66, 0x68, 0x75, 0x36, 0x44, 0x74, 0x4B, 0x32, 0x65, 0x57, 0x55, 0x41, 0x74, 0x61, 0x4A, 0x68, 0x42, 0x4F, 0x71, 0x62, 0x63, 0x68, 0x50, 0x4D, 0x38, 0x78, 0x51, 0x6C, 0x6A, 0x65, 0x53, 0x4D, 0x39, 0x78, ++ 0x66, 0x69, 0x4F, 0x65, 0x66, 0x56, 0x4E, 0x6C, 0x49, 0x38, 0x4A, 0x68, 0x44, 0x31, 0x6D, 0x62, 0x39, 0x6E, 0x78, 0x63, 0x34, 0x51, 0x38, 0x55, 0x42, 0x55, 0x51, 0x76, 0x58, 0x34, 0x79, 0x4D, 0x50, 0x0A, 0x46, 0x46, 0x31, 0x62, 0x46, 0x4F, ++ 0x64, 0x4C, 0x76, 0x74, 0x33, 0x30, 0x79, 0x4E, 0x6F, 0x44, 0x4E, 0x39, 0x48, 0x57, 0x4F, 0x61, 0x45, 0x68, 0x55, 0x54, 0x43, 0x44, 0x73, 0x47, 0x33, 0x58, 0x4D, 0x45, 0x36, 0x57, 0x57, 0x35, 0x48, 0x77, 0x63, 0x43, 0x53, 0x72, 0x76, 0x30, ++ 0x57, 0x42, 0x5A, 0x45, 0x4D, 0x4E, 0x76, 0x53, 0x45, 0x36, 0x4C, 0x7A, 0x7A, 0x70, 0x6E, 0x67, 0x33, 0x4C, 0x49, 0x4C, 0x56, 0x43, 0x4A, 0x38, 0x7A, 0x61, 0x62, 0x35, 0x76, 0x75, 0x0A, 0x5A, 0x44, 0x43, 0x51, 0x4F, 0x63, 0x32, 0x54, 0x5A, ++ 0x59, 0x45, 0x68, 0x4D, 0x62, 0x55, 0x6A, 0x55, 0x44, 0x4D, 0x33, 0x49, 0x75, 0x4D, 0x34, 0x37, 0x66, 0x67, 0x78, 0x4D, 0x4D, 0x78, 0x46, 0x2F, 0x6D, 0x4C, 0x35, 0x30, 0x56, 0x30, 0x79, 0x65, 0x55, 0x4B, 0x48, 0x33, 0x32, 0x72, 0x4D, 0x56, ++ 0x68, 0x6C, 0x41, 0x54, 0x63, 0x36, 0x71, 0x75, 0x2F, 0x6D, 0x31, 0x64, 0x6B, 0x6D, 0x55, 0x38, 0x53, 0x66, 0x34, 0x6B, 0x61, 0x57, 0x44, 0x35, 0x51, 0x61, 0x7A, 0x0A, 0x59, 0x77, 0x36, 0x41, 0x33, 0x4F, 0x41, 0x53, 0x56, 0x59, 0x43, 0x6D, ++ 0x4F, 0x32, 0x61, 0x30, 0x4F, 0x59, 0x63, 0x74, 0x79, 0x50, 0x44, 0x51, 0x30, 0x52, 0x54, 0x70, 0x35, 0x41, 0x31, 0x4E, 0x44, 0x76, 0x5A, 0x64, 0x56, 0x33, 0x4C, 0x46, 0x4F, 0x78, 0x78, 0x48, 0x56, 0x70, 0x33, 0x69, 0x31, 0x66, 0x75, 0x42, ++ 0x59, 0x59, 0x7A, 0x4D, 0x54, 0x59, 0x43, 0x51, 0x4E, 0x46, 0x75, 0x33, 0x31, 0x78, 0x52, 0x31, 0x33, 0x4E, 0x67, 0x45, 0x53, 0x4A, 0x2F, 0x41, 0x0A, 0x77, 0x53, 0x69, 0x49, 0x74, 0x4F, 0x6B, 0x63, 0x79, 0x71, 0x65, 0x78, 0x38, 0x56, 0x61, ++ 0x33, 0x65, 0x30, 0x6C, 0x4D, 0x57, 0x65, 0x55, 0x67, 0x46, 0x61, 0x69, 0x45, 0x41, 0x69, 0x6E, 0x36, 0x4F, 0x4A, 0x52, 0x70, 0x6D, 0x6B, 0x6B, 0x47, 0x6A, 0x38, 0x30, 0x66, 0x65, 0x52, 0x51, 0x58, 0x45, 0x67, 0x79, 0x44, 0x65, 0x74, 0x34, ++ 0x66, 0x73, 0x5A, 0x66, 0x75, 0x2B, 0x5A, 0x64, 0x34, 0x4B, 0x4B, 0x54, 0x49, 0x52, 0x4A, 0x4C, 0x70, 0x66, 0x53, 0x59, 0x46, 0x0A, 0x70, 0x6C, 0x68, 0x79, 0x6D, 0x33, 0x6B, 0x54, 0x32, 0x42, 0x46, 0x66, 0x72, 0x73, 0x55, 0x34, 0x59, 0x6A, ++ 0x52, 0x6F, 0x73, 0x6F, 0x59, 0x77, 0x6A, 0x76, 0x69, 0x51, 0x59, 0x5A, 0x34, 0x79, 0x62, 0x50, 0x55, 0x48, 0x4E, 0x73, 0x32, 0x69, 0x54, 0x47, 0x37, 0x73, 0x69, 0x6A, 0x62, 0x74, 0x38, 0x75, 0x61, 0x5A, 0x46, 0x55, 0x52, 0x77, 0x77, 0x33, ++ 0x79, 0x38, 0x6E, 0x44, 0x6E, 0x41, 0x74, 0x4F, 0x46, 0x72, 0x39, 0x34, 0x4D, 0x6C, 0x49, 0x31, 0x66, 0x5A, 0x0A, 0x45, 0x6F, 0x44, 0x6C, 0x53, 0x66, 0x42, 0x31, 0x44, 0x2B, 0x2B, 0x4E, 0x36, 0x78, 0x79, 0x62, 0x56, 0x43, 0x69, 0x30, 0x49, ++ 0x54, 0x7A, 0x38, 0x66, 0x41, 0x72, 0x2F, 0x37, 0x33, 0x74, 0x72, 0x64, 0x66, 0x2B, 0x4C, 0x48, 0x61, 0x41, 0x5A, 0x42, 0x61, 0x76, 0x36, 0x2B, 0x43, 0x75, 0x42, 0x51, 0x75, 0x67, 0x34, 0x75, 0x72, 0x76, 0x37, 0x71, 0x76, 0x30, 0x39, 0x34, ++ 0x50, 0x50, 0x4B, 0x33, 0x30, 0x36, 0x58, 0x6C, 0x79, 0x6E, 0x74, 0x38, 0x78, 0x68, 0x57, 0x0A, 0x36, 0x61, 0x57, 0x57, 0x72, 0x4C, 0x33, 0x44, 0x6B, 0x4A, 0x69, 0x79, 0x34, 0x50, 0x6D, 0x69, 0x31, 0x4B, 0x5A, 0x48, 0x51, 0x33, 0x78, 0x74, ++ 0x7A, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6F, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x56, 0x6E, 0x4E, 0x59, 0x5A, 0x4A, 0x58, 0x35, 0x6B, 0x68, 0x71, 0x77, ++ 0x45, 0x69, 0x6F, 0x45, 0x59, 0x6E, 0x6D, 0x68, 0x51, 0x42, 0x57, 0x49, 0x0A, 0x49, 0x55, 0x6B, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x47, 0x47, 0x4D, 0x41, 0x38, ++ 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4D, 0x42, 0x51, 0x41, ++ 0x44, 0x67, 0x67, 0x49, 0x42, 0x41, 0x43, 0x39, 0x63, 0x0A, 0x6D, 0x54, 0x7A, 0x38, 0x42, 0x6C, 0x36, 0x4D, 0x6C, 0x43, 0x35, 0x77, 0x36, 0x74, 0x49, 0x79, 0x4D, 0x59, 0x32, 0x30, 0x38, 0x46, 0x48, 0x56, 0x76, 0x41, 0x72, 0x7A, 0x5A, 0x4A, ++ 0x38, 0x48, 0x58, 0x74, 0x58, 0x42, 0x63, 0x32, 0x68, 0x6B, 0x65, 0x71, 0x4B, 0x35, 0x44, 0x75, 0x6A, 0x35, 0x58, 0x59, 0x55, 0x74, 0x71, 0x44, 0x64, 0x46, 0x71, 0x69, 0x6A, 0x30, 0x6C, 0x67, 0x56, 0x51, 0x59, 0x4B, 0x6C, 0x4A, 0x66, 0x70, ++ 0x2F, 0x69, 0x6D, 0x54, 0x59, 0x70, 0x0A, 0x45, 0x30, 0x52, 0x48, 0x61, 0x70, 0x31, 0x56, 0x49, 0x44, 0x7A, 0x59, 0x6D, 0x2F, 0x45, 0x44, 0x4D, 0x72, 0x72, 0x61, 0x51, 0x4B, 0x46, 0x7A, 0x36, 0x6F, 0x4F, 0x68, 0x74, 0x30, 0x53, 0x6D, 0x44, ++ 0x70, 0x6B, 0x42, 0x6D, 0x2B, 0x53, 0x38, 0x66, 0x37, 0x34, 0x54, 0x6C, 0x48, 0x37, 0x4B, 0x70, 0x68, 0x35, 0x32, 0x67, 0x44, 0x59, 0x39, 0x68, 0x41, 0x61, 0x4C, 0x4D, 0x79, 0x5A, 0x6C, 0x62, 0x63, 0x70, 0x2B, 0x6E, 0x76, 0x34, 0x66, 0x6A, ++ 0x46, 0x67, 0x34, 0x0A, 0x65, 0x78, 0x71, 0x44, 0x73, 0x51, 0x2B, 0x38, 0x46, 0x78, 0x47, 0x37, 0x35, 0x67, 0x62, 0x4D, 0x59, 0x2F, 0x71, 0x42, 0x38, 0x6F, 0x46, 0x4D, 0x32, 0x67, 0x73, 0x51, 0x61, 0x36, 0x48, 0x36, 0x31, 0x53, 0x69, 0x6C, ++ 0x7A, 0x77, 0x5A, 0x41, 0x46, 0x76, 0x39, 0x37, 0x66, 0x52, 0x68, 0x65, 0x4F, 0x52, 0x4B, 0x6B, 0x55, 0x35, 0x35, 0x2B, 0x4D, 0x6B, 0x49, 0x51, 0x70, 0x69, 0x47, 0x52, 0x71, 0x52, 0x78, 0x4F, 0x46, 0x33, 0x79, 0x45, 0x76, 0x4A, 0x2B, 0x4D, ++ 0x0A, 0x30, 0x65, 0x6A, 0x66, 0x35, 0x6C, 0x47, 0x35, 0x4E, 0x6B, 0x63, 0x2F, 0x6B, 0x4C, 0x6E, 0x48, 0x76, 0x41, 0x4C, 0x63, 0x57, 0x78, 0x78, 0x50, 0x44, 0x6B, 0x6A, 0x42, 0x4A, 0x59, 0x4F, 0x63, 0x43, 0x6A, 0x2B, 0x65, 0x73, 0x51, 0x4D, ++ 0x7A, 0x45, 0x68, 0x6F, 0x6E, 0x72, 0x50, 0x63, 0x69, 0x62, 0x43, 0x54, 0x52, 0x41, 0x55, 0x48, 0x34, 0x57, 0x41, 0x50, 0x2B, 0x4A, 0x57, 0x67, 0x69, 0x48, 0x35, 0x70, 0x61, 0x50, 0x48, 0x78, 0x73, 0x6E, 0x6E, 0x56, 0x49, 0x0A, 0x38, 0x34, ++ 0x48, 0x78, 0x5A, 0x6D, 0x64, 0x75, 0x54, 0x49, 0x4C, 0x41, 0x37, 0x72, 0x70, 0x58, 0x44, 0x68, 0x6A, 0x76, 0x4C, 0x70, 0x72, 0x33, 0x45, 0x74, 0x69, 0x67, 0x61, 0x2B, 0x6B, 0x46, 0x70, 0x61, 0x48, 0x70, 0x61, 0x50, 0x69, 0x38, 0x54, 0x44, ++ 0x38, 0x53, 0x48, 0x6B, 0x58, 0x6F, 0x55, 0x73, 0x43, 0x6A, 0x76, 0x78, 0x49, 0x6E, 0x65, 0x62, 0x6E, 0x4D, 0x4D, 0x54, 0x7A, 0x44, 0x39, 0x6A, 0x6F, 0x69, 0x46, 0x67, 0x4F, 0x67, 0x79, 0x59, 0x39, 0x6D, 0x0A, 0x70, 0x46, 0x75, 0x69, 0x54, ++ 0x64, 0x61, 0x42, 0x4A, 0x51, 0x62, 0x70, 0x64, 0x71, 0x51, 0x41, 0x43, 0x6A, 0x37, 0x4C, 0x7A, 0x54, 0x57, 0x62, 0x34, 0x4F, 0x45, 0x34, 0x79, 0x32, 0x42, 0x54, 0x68, 0x69, 0x68, 0x43, 0x51, 0x52, 0x78, 0x45, 0x56, 0x2B, 0x69, 0x6F, 0x72, ++ 0x61, 0x74, 0x46, 0x34, 0x79, 0x55, 0x51, 0x76, 0x4E, 0x73, 0x2B, 0x5A, 0x55, 0x48, 0x37, 0x47, 0x36, 0x61, 0x58, 0x44, 0x2B, 0x75, 0x35, 0x64, 0x48, 0x6E, 0x35, 0x48, 0x72, 0x77, 0x64, 0x0A, 0x56, 0x77, 0x31, 0x48, 0x72, 0x38, 0x4D, 0x76, ++ 0x6E, 0x34, 0x64, 0x47, 0x70, 0x2B, 0x73, 0x6D, 0x57, 0x67, 0x39, 0x57, 0x59, 0x37, 0x56, 0x69, 0x59, 0x47, 0x34, 0x41, 0x2B, 0x2B, 0x4D, 0x6E, 0x45, 0x53, 0x4C, 0x6E, 0x2F, 0x70, 0x6D, 0x50, 0x4E, 0x50, 0x57, 0x35, 0x36, 0x4D, 0x4F, 0x52, ++ 0x63, 0x72, 0x33, 0x59, 0x77, 0x78, 0x36, 0x35, 0x4C, 0x76, 0x4B, 0x52, 0x52, 0x46, 0x48, 0x51, 0x56, 0x38, 0x30, 0x4D, 0x4E, 0x4E, 0x56, 0x49, 0x49, 0x62, 0x2F, 0x62, 0x0A, 0x45, 0x2F, 0x46, 0x6D, 0x4A, 0x55, 0x4E, 0x53, 0x30, 0x6E, 0x41, ++ 0x69, 0x4E, 0x73, 0x32, 0x66, 0x78, 0x42, 0x78, 0x31, 0x49, 0x4B, 0x31, 0x6A, 0x63, 0x6D, 0x4D, 0x47, 0x44, 0x77, 0x34, 0x6E, 0x7A, 0x74, 0x4A, 0x71, 0x44, 0x62, 0x79, 0x31, 0x4F, 0x52, 0x72, 0x70, 0x30, 0x58, 0x5A, 0x36, 0x30, 0x56, 0x7A, ++ 0x6B, 0x35, 0x30, 0x6C, 0x4A, 0x4C, 0x56, 0x55, 0x33, 0x61, 0x50, 0x41, 0x61, 0x4F, 0x70, 0x67, 0x2B, 0x56, 0x42, 0x65, 0x48, 0x56, 0x4F, 0x6D, 0x6D, 0x0A, 0x4A, 0x31, 0x43, 0x4A, 0x65, 0x79, 0x41, 0x76, 0x50, 0x2F, 0x2B, 0x2F, 0x6F, 0x59, ++ 0x74, 0x4B, 0x52, 0x35, 0x6A, 0x2F, 0x4B, 0x33, 0x74, 0x4A, 0x50, 0x73, 0x4D, 0x70, 0x52, 0x6D, 0x41, 0x59, 0x51, 0x71, 0x73, 0x7A, 0x4B, 0x62, 0x72, 0x41, 0x4B, 0x62, 0x6B, 0x54, 0x69, 0x64, 0x4F, 0x49, 0x69, 0x6A, 0x6C, 0x42, 0x4F, 0x38, ++ 0x6E, 0x39, 0x70, 0x75, 0x30, 0x66, 0x39, 0x47, 0x42, 0x6A, 0x33, 0x39, 0x49, 0x74, 0x56, 0x51, 0x47, 0x4C, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, ++ 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x32, 0x32, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, ++ 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x69, 0x54, 0x43, 0x43, 0x41, 0x33, 0x47, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x62, 0x37, 0x37, 0x61, 0x72, 0x58, 0x4F, 0x39, ++ 0x43, 0x45, 0x44, 0x69, 0x69, 0x30, 0x32, 0x2B, 0x31, 0x50, 0x64, 0x62, 0x6B, 0x54, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x42, 0x4F, 0x4D, 0x51, 0x73, 0x77, ++ 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0A, 0x45, 0x77, 0x4A, 0x56, 0x55, 0x7A, 0x45, 0x59, 0x4D, 0x42, 0x59, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x50, 0x55, 0x31, 0x4E, 0x4D, 0x49, 0x45, 0x4E, 0x76, 0x63, 0x6E, 0x42, ++ 0x76, 0x63, 0x6D, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x4D, 0x53, 0x55, 0x77, 0x49, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x42, 0x78, 0x54, 0x55, 0x30, 0x77, 0x75, 0x59, 0x32, 0x39, 0x74, 0x49, 0x46, 0x52, 0x4D, 0x55, 0x79, 0x42, ++ 0x53, 0x55, 0x30, 0x45, 0x67, 0x0A, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x53, 0x41, 0x79, 0x4D, 0x44, 0x49, 0x79, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x49, 0x79, 0x4D, 0x44, 0x67, 0x79, 0x4E, 0x54, 0x45, 0x32, 0x4D, 0x7A, ++ 0x51, 0x79, 0x4D, 0x6C, 0x6F, 0x58, 0x44, 0x54, 0x51, 0x32, 0x4D, 0x44, 0x67, 0x78, 0x4F, 0x54, 0x45, 0x32, 0x4D, 0x7A, 0x51, 0x79, 0x4D, 0x56, 0x6F, 0x77, 0x54, 0x6A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, ++ 0x4D, 0x43, 0x0A, 0x56, 0x56, 0x4D, 0x78, 0x47, 0x44, 0x41, 0x57, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x44, 0x31, 0x4E, 0x54, 0x54, 0x43, 0x42, 0x44, 0x62, 0x33, 0x4A, 0x77, 0x62, 0x33, 0x4A, 0x68, 0x64, 0x47, 0x6C, 0x76, 0x62, ++ 0x6A, 0x45, 0x6C, 0x4D, 0x43, 0x4D, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x63, 0x55, 0x31, 0x4E, 0x4D, 0x4C, 0x6D, 0x4E, 0x76, 0x62, 0x53, 0x42, 0x55, 0x54, 0x46, 0x4D, 0x67, 0x55, 0x6C, 0x4E, 0x42, 0x49, 0x46, 0x4A, 0x76, 0x0A, ++ 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x4D, 0x6A, 0x41, 0x79, 0x4D, 0x6A, 0x43, 0x43, 0x41, 0x69, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, ++ 0x67, 0x67, 0x49, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x67, 0x6F, 0x43, 0x67, 0x67, 0x49, 0x42, 0x41, 0x4E, 0x43, 0x6B, 0x43, 0x58, 0x4A, 0x50, 0x51, 0x49, 0x67, 0x53, 0x59, 0x54, 0x34, 0x31, 0x49, 0x35, 0x37, 0x75, 0x0A, 0x39, 0x6E, 0x54, ++ 0x50, 0x4C, 0x33, 0x74, 0x59, 0x50, 0x63, 0x34, 0x38, 0x44, 0x52, 0x41, 0x6F, 0x6B, 0x43, 0x2B, 0x58, 0x39, 0x34, 0x78, 0x49, 0x32, 0x4B, 0x44, 0x59, 0x4A, 0x62, 0x46, 0x4D, 0x73, 0x42, 0x46, 0x4D, 0x46, 0x33, 0x4E, 0x51, 0x30, 0x43, 0x4A, ++ 0x4B, 0x59, 0x37, 0x75, 0x42, 0x30, 0x79, 0x6C, 0x75, 0x31, 0x62, 0x55, 0x4A, 0x50, 0x69, 0x59, 0x59, 0x66, 0x37, 0x49, 0x53, 0x66, 0x35, 0x4F, 0x59, 0x74, 0x36, 0x2F, 0x77, 0x4E, 0x72, 0x2F, 0x79, 0x0A, 0x37, 0x68, 0x69, 0x65, 0x6E, 0x44, ++ 0x74, 0x53, 0x78, 0x55, 0x63, 0x5A, 0x58, 0x58, 0x54, 0x7A, 0x5A, 0x47, 0x62, 0x56, 0x58, 0x63, 0x64, 0x6F, 0x74, 0x4C, 0x38, 0x62, 0x48, 0x41, 0x61, 0x6A, 0x76, 0x49, 0x39, 0x41, 0x49, 0x37, 0x59, 0x65, 0x78, 0x6F, 0x53, 0x39, 0x55, 0x63, ++ 0x51, 0x62, 0x4F, 0x63, 0x47, 0x56, 0x30, 0x69, 0x6E, 0x73, 0x53, 0x36, 0x35, 0x37, 0x4C, 0x62, 0x38, 0x35, 0x2F, 0x62, 0x52, 0x69, 0x33, 0x70, 0x5A, 0x37, 0x51, 0x63, 0x61, 0x63, 0x0A, 0x6F, 0x4F, 0x41, 0x47, 0x63, 0x76, 0x76, 0x77, 0x42, ++ 0x35, 0x63, 0x4A, 0x4F, 0x59, 0x46, 0x30, 0x72, 0x2F, 0x63, 0x30, 0x57, 0x52, 0x46, 0x58, 0x43, 0x73, 0x4A, 0x62, 0x77, 0x53, 0x54, 0x30, 0x4D, 0x58, 0x4D, 0x77, 0x67, 0x73, 0x61, 0x64, 0x75, 0x67, 0x4C, 0x33, 0x50, 0x6E, 0x78, 0x45, 0x58, ++ 0x34, 0x4D, 0x4E, 0x38, 0x2F, 0x48, 0x64, 0x49, 0x47, 0x6B, 0x57, 0x43, 0x56, 0x44, 0x69, 0x31, 0x46, 0x57, 0x32, 0x34, 0x49, 0x42, 0x79, 0x64, 0x6D, 0x35, 0x4D, 0x0A, 0x52, 0x37, 0x64, 0x31, 0x56, 0x56, 0x6D, 0x30, 0x55, 0x33, 0x54, 0x5A, ++ 0x6C, 0x4D, 0x5A, 0x42, 0x72, 0x56, 0x69, 0x4B, 0x4D, 0x57, 0x59, 0x50, 0x48, 0x71, 0x49, 0x62, 0x4B, 0x55, 0x42, 0x4F, 0x4C, 0x39, 0x39, 0x37, 0x35, 0x68, 0x59, 0x73, 0x4C, 0x66, 0x79, 0x2F, 0x37, 0x50, 0x4F, 0x30, 0x2B, 0x72, 0x34, 0x59, ++ 0x39, 0x70, 0x74, 0x4A, 0x31, 0x4F, 0x34, 0x46, 0x62, 0x74, 0x6B, 0x30, 0x38, 0x35, 0x7A, 0x78, 0x37, 0x41, 0x47, 0x4C, 0x30, 0x53, 0x44, 0x47, 0x0A, 0x44, 0x36, 0x43, 0x31, 0x76, 0x42, 0x64, 0x4F, 0x53, 0x48, 0x74, 0x52, 0x77, 0x76, 0x7A, ++ 0x70, 0x58, 0x47, 0x6B, 0x33, 0x52, 0x32, 0x61, 0x7A, 0x61, 0x50, 0x67, 0x56, 0x4B, 0x50, 0x43, 0x35, 0x30, 0x36, 0x51, 0x56, 0x7A, 0x46, 0x70, 0x50, 0x75, 0x6C, 0x4A, 0x77, 0x6F, 0x78, 0x4A, 0x46, 0x33, 0x63, 0x61, 0x36, 0x54, 0x76, 0x76, ++ 0x43, 0x30, 0x50, 0x65, 0x6F, 0x55, 0x69, 0x64, 0x74, 0x62, 0x6E, 0x6D, 0x31, 0x6A, 0x50, 0x78, 0x37, 0x6A, 0x4D, 0x45, 0x57, 0x0A, 0x54, 0x4F, 0x36, 0x41, 0x66, 0x37, 0x37, 0x77, 0x64, 0x72, 0x35, 0x42, 0x55, 0x78, 0x49, 0x7A, 0x72, 0x6C, ++ 0x6F, 0x34, 0x51, 0x71, 0x76, 0x58, 0x44, 0x7A, 0x35, 0x42, 0x6A, 0x58, 0x59, 0x48, 0x4D, 0x74, 0x57, 0x72, 0x69, 0x66, 0x5A, 0x4F, 0x5A, 0x39, 0x6D, 0x78, 0x51, 0x6E, 0x55, 0x6A, 0x62, 0x76, 0x50, 0x4E, 0x51, 0x72, 0x4C, 0x38, 0x56, 0x66, ++ 0x56, 0x54, 0x68, 0x78, 0x63, 0x37, 0x77, 0x44, 0x4E, 0x59, 0x38, 0x56, 0x4C, 0x53, 0x2B, 0x59, 0x43, 0x6B, 0x0A, 0x38, 0x4F, 0x6A, 0x77, 0x4F, 0x34, 0x73, 0x34, 0x7A, 0x4B, 0x54, 0x47, 0x6B, 0x48, 0x38, 0x50, 0x6E, 0x50, 0x32, 0x4C, 0x30, ++ 0x61, 0x50, 0x50, 0x32, 0x6F, 0x4F, 0x6E, 0x61, 0x63, 0x6C, 0x51, 0x4E, 0x74, 0x56, 0x63, 0x42, 0x64, 0x49, 0x4B, 0x51, 0x58, 0x54, 0x62, 0x59, 0x78, 0x45, 0x33, 0x77, 0x61, 0x57, 0x67, 0x6C, 0x6B, 0x73, 0x65, 0x6A, 0x42, 0x59, 0x53, 0x64, ++ 0x36, 0x36, 0x55, 0x4E, 0x48, 0x73, 0x65, 0x66, 0x38, 0x4A, 0x6D, 0x41, 0x4F, 0x53, 0x71, 0x0A, 0x67, 0x2B, 0x71, 0x4B, 0x6B, 0x4B, 0x33, 0x4F, 0x4E, 0x6B, 0x52, 0x4E, 0x30, 0x56, 0x48, 0x70, 0x76, 0x42, 0x2F, 0x7A, 0x61, 0x67, 0x58, 0x39, ++ 0x77, 0x48, 0x51, 0x66, 0x4A, 0x52, 0x6C, 0x41, 0x55, 0x57, 0x37, 0x71, 0x67, 0x6C, 0x46, 0x41, 0x33, 0x35, 0x75, 0x35, 0x43, 0x43, 0x6F, 0x47, 0x41, 0x74, 0x55, 0x6A, 0x48, 0x42, 0x50, 0x57, 0x36, 0x64, 0x76, 0x62, 0x78, 0x72, 0x42, 0x36, ++ 0x79, 0x33, 0x73, 0x6E, 0x6D, 0x2F, 0x76, 0x67, 0x31, 0x55, 0x59, 0x6B, 0x0A, 0x37, 0x52, 0x42, 0x4C, 0x59, 0x30, 0x75, 0x6C, 0x42, 0x59, 0x2B, 0x36, 0x75, 0x42, 0x30, 0x72, 0x70, 0x76, 0x71, 0x52, 0x34, 0x70, 0x4A, 0x53, 0x76, 0x65, 0x7A, ++ 0x72, 0x5A, 0x35, 0x64, 0x74, 0x6D, 0x69, 0x32, 0x66, 0x67, 0x54, 0x49, 0x46, 0x5A, 0x7A, 0x4C, 0x37, 0x53, 0x41, 0x67, 0x2F, 0x32, 0x53, 0x57, 0x34, 0x42, 0x43, 0x55, 0x76, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, 0x59, 0x7A, 0x42, ++ 0x68, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x0A, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x48, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x6A, 0x42, 0x42, 0x67, 0x77, 0x46, 0x6F, ++ 0x41, 0x55, 0x2B, 0x79, 0x34, 0x33, 0x37, 0x75, 0x4F, 0x45, 0x65, 0x69, 0x63, 0x75, 0x7A, 0x52, 0x6B, 0x31, 0x73, 0x54, 0x4E, 0x38, 0x2F, 0x39, 0x52, 0x45, 0x51, 0x72, 0x6B, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, ++ 0x59, 0x45, 0x46, 0x50, 0x73, 0x75, 0x0A, 0x4E, 0x2B, 0x37, 0x6A, 0x68, 0x48, 0x6F, 0x6E, 0x4C, 0x73, 0x30, 0x5A, 0x4E, 0x62, 0x45, 0x7A, 0x66, 0x50, 0x2F, 0x55, 0x52, 0x45, 0x4B, 0x35, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, ++ 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x68, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x67, 0x45, 0x41, 0x6A, ++ 0x59, 0x6C, 0x74, 0x0A, 0x68, 0x45, 0x55, 0x59, 0x38, 0x55, 0x2B, 0x7A, 0x6F, 0x4F, 0x39, 0x6F, 0x70, 0x4D, 0x41, 0x64, 0x72, 0x44, 0x43, 0x38, 0x5A, 0x32, 0x61, 0x77, 0x6D, 0x73, 0x32, 0x32, 0x71, 0x79, 0x49, 0x5A, 0x5A, 0x74, 0x4D, 0x37, ++ 0x51, 0x62, 0x55, 0x51, 0x6E, 0x52, 0x43, 0x36, 0x63, 0x6D, 0x34, 0x70, 0x4A, 0x43, 0x41, 0x63, 0x41, 0x5A, 0x6C, 0x69, 0x30, 0x35, 0x62, 0x67, 0x34, 0x76, 0x73, 0x4D, 0x51, 0x74, 0x66, 0x68, 0x57, 0x73, 0x53, 0x57, 0x54, 0x56, 0x54, 0x4E, ++ 0x0A, 0x6A, 0x38, 0x70, 0x44, 0x55, 0x2F, 0x30, 0x71, 0x75, 0x4F, 0x72, 0x34, 0x5A, 0x63, 0x6F, 0x42, 0x77, 0x71, 0x31, 0x67, 0x61, 0x41, 0x61, 0x66, 0x4F, 0x52, 0x70, 0x52, 0x32, 0x65, 0x43, 0x4E, 0x4A, 0x76, 0x6B, 0x4C, 0x54, 0x71, 0x56, ++ 0x54, 0x4A, 0x58, 0x6F, 0x6A, 0x70, 0x42, 0x7A, 0x4F, 0x43, 0x42, 0x76, 0x66, 0x52, 0x34, 0x69, 0x79, 0x72, 0x54, 0x37, 0x67, 0x4A, 0x34, 0x65, 0x4C, 0x53, 0x59, 0x77, 0x66, 0x71, 0x55, 0x64, 0x59, 0x65, 0x35, 0x62, 0x79, 0x0A, 0x69, 0x42, ++ 0x30, 0x59, 0x72, 0x72, 0x50, 0x52, 0x70, 0x67, 0x71, 0x55, 0x2B, 0x74, 0x76, 0x54, 0x35, 0x54, 0x67, 0x4B, 0x61, 0x33, 0x6B, 0x53, 0x4D, 0x2F, 0x74, 0x4B, 0x57, 0x54, 0x63, 0x57, 0x51, 0x41, 0x36, 0x37, 0x33, 0x76, 0x57, 0x4A, 0x44, 0x50, ++ 0x46, 0x73, 0x30, 0x2F, 0x64, 0x52, 0x61, 0x31, 0x34, 0x31, 0x39, 0x64, 0x76, 0x41, 0x4A, 0x75, 0x6F, 0x53, 0x63, 0x30, 0x36, 0x70, 0x6B, 0x5A, 0x43, 0x6D, 0x46, 0x38, 0x4E, 0x73, 0x4C, 0x7A, 0x6A, 0x55, 0x0A, 0x6F, 0x33, 0x4B, 0x55, 0x51, ++ 0x79, 0x78, 0x69, 0x34, 0x55, 0x35, 0x63, 0x4D, 0x6A, 0x32, 0x39, 0x54, 0x48, 0x30, 0x5A, 0x52, 0x36, 0x4C, 0x44, 0x53, 0x65, 0x65, 0x57, 0x50, 0x34, 0x2B, 0x61, 0x30, 0x7A, 0x76, 0x6B, 0x45, 0x64, 0x69, 0x4C, 0x41, 0x39, 0x7A, 0x32, 0x74, ++ 0x6D, 0x42, 0x56, 0x47, 0x4B, 0x61, 0x42, 0x55, 0x66, 0x50, 0x68, 0x71, 0x42, 0x56, 0x71, 0x36, 0x2B, 0x41, 0x4C, 0x38, 0x42, 0x51, 0x78, 0x31, 0x72, 0x6D, 0x4D, 0x52, 0x54, 0x71, 0x6F, 0x0A, 0x45, 0x4E, 0x6A, 0x77, 0x75, 0x53, 0x66, 0x72, ++ 0x39, 0x38, 0x74, 0x36, 0x37, 0x77, 0x56, 0x79, 0x6C, 0x72, 0x58, 0x45, 0x6A, 0x35, 0x5A, 0x7A, 0x78, 0x4F, 0x68, 0x57, 0x63, 0x35, 0x79, 0x38, 0x61, 0x56, 0x46, 0x6A, 0x76, 0x4F, 0x39, 0x6E, 0x48, 0x45, 0x4D, 0x61, 0x58, 0x33, 0x63, 0x5A, ++ 0x48, 0x78, 0x6A, 0x34, 0x48, 0x43, 0x55, 0x70, 0x2B, 0x55, 0x6D, 0x5A, 0x4B, 0x62, 0x61, 0x53, 0x50, 0x61, 0x4B, 0x44, 0x4E, 0x37, 0x45, 0x67, 0x6B, 0x61, 0x69, 0x62, 0x0A, 0x4D, 0x4F, 0x6C, 0x71, 0x62, 0x4C, 0x51, 0x6A, 0x6B, 0x32, 0x55, ++ 0x45, 0x71, 0x78, 0x48, 0x7A, 0x44, 0x68, 0x31, 0x54, 0x4A, 0x45, 0x6C, 0x54, 0x48, 0x61, 0x45, 0x2F, 0x6E, 0x55, 0x69, 0x53, 0x45, 0x65, 0x4A, 0x39, 0x44, 0x55, 0x2F, 0x31, 0x31, 0x37, 0x32, 0x69, 0x57, 0x44, 0x35, 0x34, 0x6E, 0x52, 0x34, ++ 0x66, 0x4B, 0x2F, 0x34, 0x68, 0x75, 0x78, 0x6F, 0x54, 0x74, 0x72, 0x45, 0x6F, 0x5A, 0x50, 0x32, 0x77, 0x41, 0x67, 0x44, 0x48, 0x62, 0x49, 0x43, 0x69, 0x0A, 0x76, 0x52, 0x5A, 0x51, 0x49, 0x41, 0x39, 0x79, 0x67, 0x56, 0x2F, 0x4D, 0x6C, 0x50, ++ 0x2B, 0x37, 0x6D, 0x65, 0x61, 0x36, 0x6B, 0x4D, 0x76, 0x71, 0x2B, 0x63, 0x59, 0x4D, 0x77, 0x71, 0x37, 0x46, 0x47, 0x63, 0x34, 0x7A, 0x6F, 0x57, 0x74, 0x63, 0x75, 0x33, 0x35, 0x38, 0x4E, 0x46, 0x63, 0x58, 0x72, 0x66, 0x41, 0x2F, 0x72, 0x73, ++ 0x33, 0x71, 0x72, 0x35, 0x6E, 0x73, 0x4C, 0x46, 0x52, 0x2B, 0x6A, 0x4D, 0x34, 0x75, 0x45, 0x6C, 0x5A, 0x49, 0x37, 0x78, 0x63, 0x37, 0x0A, 0x50, 0x30, 0x70, 0x65, 0x59, 0x4E, 0x4C, 0x63, 0x64, 0x44, 0x61, 0x38, 0x70, 0x55, 0x4E, 0x6A, 0x79, ++ 0x77, 0x39, 0x62, 0x6F, 0x77, 0x4A, 0x57, 0x43, 0x5A, 0x34, 0x6B, 0x4C, 0x4F, 0x47, 0x47, 0x67, 0x59, 0x7A, 0x2B, 0x71, 0x78, 0x63, 0x73, 0x2B, 0x73, 0x6A, 0x69, 0x4D, 0x68, 0x6F, 0x36, 0x2F, 0x34, 0x55, 0x49, 0x79, 0x59, 0x4F, 0x66, 0x38, ++ 0x6B, 0x70, 0x49, 0x45, 0x46, 0x52, 0x33, 0x4E, 0x2B, 0x32, 0x69, 0x76, 0x45, 0x43, 0x2B, 0x35, 0x42, 0x42, 0x30, 0x0A, 0x39, 0x2B, 0x52, 0x62, 0x75, 0x37, 0x6E, 0x7A, 0x69, 0x66, 0x6D, 0x50, 0x51, 0x64, 0x6A, 0x48, 0x35, 0x46, 0x43, 0x51, ++ 0x4E, 0x59, 0x41, 0x2B, 0x48, 0x4C, 0x68, 0x4E, 0x6B, 0x4E, 0x50, 0x55, 0x39, 0x38, 0x4F, 0x77, 0x6F, 0x58, 0x36, 0x45, 0x79, 0x6E, 0x65, 0x53, 0x4D, 0x53, 0x79, 0x34, 0x6B, 0x4C, 0x47, 0x43, 0x65, 0x6E, 0x52, 0x4F, 0x6D, 0x78, 0x4D, 0x6D, ++ 0x74, 0x4E, 0x56, 0x51, 0x5A, 0x6C, 0x52, 0x34, 0x72, 0x6D, 0x41, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, ++ 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x32, 0x32, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, ++ 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x4F, 0x6A, 0x43, 0x43, 0x41, 0x63, 0x43, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x46, 0x41, 0x50, 0x31, 0x71, 0x2F, 0x73, 0x33, 0x69, 0x78, 0x64, 0x41, 0x57, 0x2B, ++ 0x4A, 0x44, 0x73, 0x71, 0x58, 0x52, 0x78, 0x44, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x7A, 0x42, 0x4F, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, ++ 0x4A, 0x56, 0x0A, 0x55, 0x7A, 0x45, 0x59, 0x4D, 0x42, 0x59, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x50, 0x55, 0x31, 0x4E, 0x4D, 0x49, 0x45, 0x4E, 0x76, 0x63, 0x6E, 0x42, 0x76, 0x63, 0x6D, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x4D, ++ 0x53, 0x55, 0x77, 0x49, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x42, 0x78, 0x54, 0x55, 0x30, 0x77, 0x75, 0x59, 0x32, 0x39, 0x74, 0x49, 0x46, 0x52, 0x4D, 0x55, 0x79, 0x42, 0x46, 0x51, 0x30, 0x4D, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x0A, ++ 0x64, 0x43, 0x42, 0x44, 0x51, 0x53, 0x41, 0x79, 0x4D, 0x44, 0x49, 0x79, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x49, 0x79, 0x4D, 0x44, 0x67, 0x79, 0x4E, 0x54, 0x45, 0x32, 0x4D, 0x7A, 0x4D, 0x30, 0x4F, 0x46, 0x6F, 0x58, 0x44, 0x54, 0x51, 0x32, ++ 0x4D, 0x44, 0x67, 0x78, 0x4F, 0x54, 0x45, 0x32, 0x4D, 0x7A, 0x4D, 0x30, 0x4E, 0x31, 0x6F, 0x77, 0x54, 0x6A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x56, 0x56, 0x4D, 0x78, 0x0A, 0x47, 0x44, 0x41, ++ 0x57, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x44, 0x31, 0x4E, 0x54, 0x54, 0x43, 0x42, 0x44, 0x62, 0x33, 0x4A, 0x77, 0x62, 0x33, 0x4A, 0x68, 0x64, 0x47, 0x6C, 0x76, 0x62, 0x6A, 0x45, 0x6C, 0x4D, 0x43, 0x4D, 0x47, 0x41, 0x31, 0x55, ++ 0x45, 0x41, 0x77, 0x77, 0x63, 0x55, 0x31, 0x4E, 0x4D, 0x4C, 0x6D, 0x4E, 0x76, 0x62, 0x53, 0x42, 0x55, 0x54, 0x46, 0x4D, 0x67, 0x52, 0x55, 0x4E, 0x44, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x0A, 0x51, 0x30, 0x45, 0x67, 0x4D, 0x6A, ++ 0x41, 0x79, 0x4D, 0x6A, 0x42, 0x32, 0x4D, 0x42, 0x41, 0x47, 0x42, 0x79, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x41, 0x67, 0x45, 0x47, 0x42, 0x53, 0x75, 0x42, 0x42, 0x41, 0x41, 0x69, 0x41, 0x32, 0x49, 0x41, 0x42, 0x45, 0x55, 0x70, 0x4E, 0x58, ++ 0x50, 0x36, 0x77, 0x72, 0x67, 0x6A, 0x7A, 0x68, 0x52, 0x39, 0x71, 0x4C, 0x46, 0x4E, 0x6F, 0x46, 0x73, 0x32, 0x37, 0x69, 0x6F, 0x73, 0x55, 0x38, 0x4E, 0x67, 0x43, 0x54, 0x57, 0x79, 0x0A, 0x4A, 0x47, 0x59, 0x6D, 0x61, 0x63, 0x43, 0x7A, 0x6C, ++ 0x64, 0x5A, 0x64, 0x6B, 0x6B, 0x41, 0x5A, 0x44, 0x73, 0x61, 0x6C, 0x45, 0x33, 0x44, 0x30, 0x37, 0x78, 0x4A, 0x52, 0x4B, 0x46, 0x33, 0x6E, 0x7A, 0x4C, 0x33, 0x35, 0x50, 0x49, 0x58, 0x42, 0x7A, 0x35, 0x53, 0x51, 0x79, 0x53, 0x76, 0x4F, 0x6B, ++ 0x6B, 0x4A, 0x59, 0x57, 0x57, 0x66, 0x39, 0x6C, 0x43, 0x63, 0x51, 0x5A, 0x49, 0x78, 0x50, 0x42, 0x4C, 0x46, 0x4E, 0x53, 0x65, 0x52, 0x37, 0x54, 0x35, 0x76, 0x31, 0x0A, 0x35, 0x77, 0x6A, 0x34, 0x41, 0x34, 0x6A, 0x33, 0x70, 0x38, 0x4F, 0x53, ++ 0x53, 0x78, 0x6C, 0x55, 0x67, 0x61, 0x4E, 0x6A, 0x4D, 0x47, 0x45, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x66, 0x42, 0x67, 0x4E, 0x56, ++ 0x48, 0x53, 0x4D, 0x45, 0x47, 0x44, 0x41, 0x57, 0x67, 0x42, 0x53, 0x4A, 0x6A, 0x79, 0x2B, 0x6A, 0x36, 0x43, 0x75, 0x67, 0x46, 0x46, 0x52, 0x37, 0x0A, 0x38, 0x31, 0x61, 0x34, 0x4A, 0x6C, 0x39, 0x6E, 0x4F, 0x41, 0x75, 0x63, 0x30, 0x44, 0x41, ++ 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x69, 0x59, 0x38, 0x76, 0x6F, 0x2B, 0x67, 0x72, 0x6F, 0x42, 0x52, 0x55, 0x65, 0x2F, 0x4E, 0x57, 0x75, 0x43, 0x5A, 0x66, 0x5A, 0x7A, 0x67, 0x4C, 0x6E, 0x4E, 0x41, ++ 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x47, 0x47, 0x0A, 0x4D, 0x41, 0x6F, 0x47, 0x43, 0x43, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x42, 0x41, 0x4D, 0x44, 0x41, 0x32, ++ 0x67, 0x41, 0x4D, 0x47, 0x55, 0x43, 0x4D, 0x46, 0x58, 0x6A, 0x49, 0x6C, 0x62, 0x70, 0x31, 0x35, 0x49, 0x6B, 0x57, 0x45, 0x38, 0x65, 0x6C, 0x44, 0x49, 0x50, 0x44, 0x41, 0x49, 0x32, 0x77, 0x76, 0x32, 0x73, 0x64, 0x44, 0x4A, 0x4F, 0x34, 0x66, ++ 0x73, 0x63, 0x67, 0x49, 0x69, 0x6A, 0x7A, 0x50, 0x76, 0x58, 0x36, 0x79, 0x76, 0x2F, 0x4E, 0x33, 0x33, 0x77, 0x0A, 0x37, 0x64, 0x65, 0x65, 0x64, 0x57, 0x6F, 0x31, 0x64, 0x6C, 0x4A, 0x46, 0x34, 0x41, 0x49, 0x78, 0x41, 0x4D, 0x65, 0x4E, 0x62, ++ 0x30, 0x49, 0x67, 0x6A, 0x37, 0x36, 0x32, 0x54, 0x56, 0x6E, 0x74, 0x64, 0x30, 0x30, 0x70, 0x78, 0x43, 0x41, 0x67, 0x52, 0x57, 0x53, 0x47, 0x4F, 0x6C, 0x44, 0x47, 0x78, 0x4B, 0x30, 0x74, 0x6B, 0x2F, 0x55, 0x59, 0x66, 0x58, 0x4C, 0x74, 0x71, ++ 0x63, 0x2F, 0x45, 0x72, 0x46, 0x63, 0x32, 0x4B, 0x41, 0x68, 0x6C, 0x33, 0x7A, 0x78, 0x35, 0x0A, 0x5A, 0x6E, 0x36, 0x67, 0x36, 0x67, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, ++ 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x45, 0x43, 0x43, ++ 0x20, 0x54, 0x4C, 0x53, 0x20, 0x32, 0x30, 0x32, 0x31, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, ++ 0x46, 0x54, 0x43, 0x43, 0x41, 0x5A, 0x75, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x50, 0x5A, 0x67, 0x37, 0x70, 0x6D, 0x59, 0x39, 0x6B, 0x47, 0x50, 0x33, 0x66, 0x69, 0x5A, 0x58, 0x4F, 0x41, 0x54, 0x76, 0x41, 0x44, 0x41, 0x4B, ++ 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x7A, 0x42, 0x4D, 0x4D, 0x53, 0x34, 0x77, 0x4C, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x43, 0x56, 0x42, 0x0A, 0x64, 0x47, 0x39, 0x7A, 0x49, 0x46, 0x52, ++ 0x79, 0x64, 0x58, 0x4E, 0x30, 0x5A, 0x57, 0x52, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x52, 0x55, 0x4E, 0x44, 0x49, 0x46, 0x52, 0x4D, 0x55, 0x79, 0x41, 0x79, 0x4D, 0x44, 0x49, ++ 0x78, 0x4D, 0x51, 0x30, 0x77, 0x43, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x44, 0x41, 0x52, 0x42, 0x64, 0x47, 0x39, 0x7A, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x0A, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x45, 0x52, 0x54, ++ 0x41, 0x65, 0x46, 0x77, 0x30, 0x79, 0x4D, 0x54, 0x41, 0x30, 0x4D, 0x6A, 0x49, 0x77, 0x4F, 0x54, 0x49, 0x32, 0x4D, 0x6A, 0x4E, 0x61, 0x46, 0x77, 0x30, 0x30, 0x4D, 0x54, 0x41, 0x30, 0x4D, 0x54, 0x63, 0x77, 0x4F, 0x54, 0x49, 0x32, 0x4D, 0x6A, ++ 0x4A, 0x61, 0x4D, 0x45, 0x77, 0x78, 0x4C, 0x6A, 0x41, 0x73, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x4A, 0x55, 0x46, 0x30, 0x62, 0x33, 0x4D, 0x67, 0x0A, 0x56, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x52, 0x6C, 0x5A, 0x46, 0x4A, 0x76, 0x62, ++ 0x33, 0x51, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x53, 0x42, 0x46, 0x51, 0x30, 0x4D, 0x67, 0x56, 0x45, 0x78, 0x54, 0x49, 0x44, 0x49, 0x77, 0x4D, 0x6A, 0x45, 0x78, 0x44, 0x54, 0x41, 0x4C, 0x42, 0x67, 0x4E, 0x56, 0x42, ++ 0x41, 0x6F, 0x4D, 0x42, 0x45, 0x46, 0x30, 0x62, 0x33, 0x4D, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x0A, 0x41, 0x6B, 0x52, 0x46, 0x4D, 0x48, 0x59, 0x77, 0x45, 0x41, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, ++ 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x46, 0x4B, 0x34, 0x45, 0x45, 0x41, 0x43, 0x49, 0x44, 0x59, 0x67, 0x41, 0x45, 0x6C, 0x6F, 0x5A, 0x59, 0x4B, 0x44, 0x63, 0x4B, 0x5A, 0x39, 0x43, 0x67, 0x33, 0x69, 0x51, 0x5A, 0x47, 0x65, 0x48, 0x6B, ++ 0x42, 0x51, 0x63, 0x66, 0x6C, 0x2B, 0x33, 0x6F, 0x5A, 0x49, 0x4B, 0x35, 0x39, 0x73, 0x52, 0x78, 0x55, 0x4D, 0x36, 0x4B, 0x0A, 0x44, 0x50, 0x2F, 0x58, 0x74, 0x58, 0x61, 0x37, 0x6F, 0x57, 0x79, 0x54, 0x62, 0x49, 0x4F, 0x69, 0x61, 0x47, 0x36, ++ 0x6C, 0x32, 0x62, 0x34, 0x73, 0x69, 0x4A, 0x56, 0x42, 0x7A, 0x56, 0x33, 0x64, 0x73, 0x63, 0x71, 0x44, 0x59, 0x34, 0x50, 0x4D, 0x77, 0x4C, 0x35, 0x30, 0x32, 0x65, 0x43, 0x64, 0x70, 0x4F, 0x35, 0x4B, 0x54, 0x6C, 0x62, 0x67, 0x6D, 0x43, 0x6C, ++ 0x42, 0x6B, 0x31, 0x49, 0x51, 0x31, 0x53, 0x51, 0x34, 0x41, 0x6A, 0x4A, 0x6E, 0x38, 0x5A, 0x51, 0x53, 0x0A, 0x62, 0x2B, 0x2F, 0x58, 0x78, 0x64, 0x34, 0x75, 0x2F, 0x52, 0x6D, 0x41, 0x6F, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, 0x50, 0x42, 0x67, ++ 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x52, 0x32, 0x4B, 0x43, 0x58, 0x57, 0x66, 0x65, ++ 0x42, 0x6D, 0x6D, 0x6E, 0x6F, 0x4A, 0x73, 0x6D, 0x6F, 0x37, 0x6A, 0x6A, 0x50, 0x58, 0x0A, 0x4E, 0x74, 0x4E, 0x50, 0x6F, 0x6A, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x41, ++ 0x59, 0x59, 0x77, 0x43, 0x67, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x45, 0x41, 0x77, 0x4D, 0x44, 0x61, 0x41, 0x41, 0x77, 0x5A, 0x51, 0x49, 0x77, 0x57, 0x35, 0x6B, 0x70, 0x38, 0x35, 0x77, 0x78, 0x74, 0x6F, 0x6C, 0x72, 0x62, ++ 0x4E, 0x61, 0x39, 0x64, 0x2B, 0x46, 0x38, 0x35, 0x31, 0x46, 0x2B, 0x0A, 0x75, 0x44, 0x72, 0x4E, 0x6F, 0x7A, 0x5A, 0x66, 0x66, 0x50, 0x63, 0x38, 0x64, 0x7A, 0x37, 0x6B, 0x55, 0x4B, 0x32, 0x6F, 0x35, 0x39, 0x4A, 0x5A, 0x44, 0x43, 0x61, 0x4F, ++ 0x4D, 0x44, 0x74, 0x75, 0x43, 0x43, 0x72, 0x43, 0x70, 0x31, 0x72, 0x49, 0x41, 0x6A, 0x45, 0x41, 0x6D, 0x65, 0x4D, 0x4D, 0x35, 0x36, 0x50, 0x44, 0x72, 0x39, 0x4E, 0x4A, 0x4C, 0x6B, 0x61, 0x43, 0x49, 0x32, 0x5A, 0x64, 0x79, 0x51, 0x41, 0x55, ++ 0x45, 0x76, 0x30, 0x34, 0x39, 0x4F, 0x47, 0x59, 0x0A, 0x61, 0x33, 0x63, 0x70, 0x65, 0x74, 0x73, 0x6B, 0x7A, 0x32, 0x56, 0x41, 0x76, 0x39, 0x4C, 0x63, 0x6A, 0x42, 0x48, 0x6F, 0x39, 0x48, 0x31, 0x2F, 0x49, 0x49, 0x53, 0x70, 0x51, 0x75, 0x51, ++ 0x6F, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, ++ 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x52, 0x53, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x32, 0x30, 0x32, 0x31, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, ++ 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x5A, 0x44, 0x43, 0x43, 0x41, 0x30, 0x79, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x55, 0x39, 0x58, 0x50, 0x35, 0x68, 0x6D, ++ 0x54, 0x43, 0x2F, 0x73, 0x72, 0x42, 0x52, 0x4C, 0x59, 0x77, 0x69, 0x71, 0x69, 0x70, 0x44, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x77, 0x46, 0x41, 0x44, 0x42, 0x4D, 0x4D, 0x53, 0x34, ++ 0x77, 0x4C, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x0A, 0x44, 0x43, 0x56, 0x42, 0x64, 0x47, 0x39, 0x7A, 0x49, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x5A, 0x57, 0x52, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, ++ 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x55, 0x6C, 0x4E, 0x42, 0x49, 0x46, 0x52, 0x4D, 0x55, 0x79, 0x41, 0x79, 0x4D, 0x44, 0x49, 0x78, 0x4D, 0x51, 0x30, 0x77, 0x43, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x44, 0x41, 0x52, 0x42, 0x64, 0x47, ++ 0x39, 0x7A, 0x4D, 0x51, 0x73, 0x77, 0x0A, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x45, 0x52, 0x54, 0x41, 0x65, 0x46, 0x77, 0x30, 0x79, 0x4D, 0x54, 0x41, 0x30, 0x4D, 0x6A, 0x49, 0x77, 0x4F, 0x54, 0x49, 0x78, 0x4D, ++ 0x54, 0x42, 0x61, 0x46, 0x77, 0x30, 0x30, 0x4D, 0x54, 0x41, 0x30, 0x4D, 0x54, 0x63, 0x77, 0x4F, 0x54, 0x49, 0x78, 0x4D, 0x44, 0x6C, 0x61, 0x4D, 0x45, 0x77, 0x78, 0x4C, 0x6A, 0x41, 0x73, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x4A, ++ 0x55, 0x46, 0x30, 0x0A, 0x62, 0x33, 0x4D, 0x67, 0x56, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x52, 0x6C, 0x5A, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x53, 0x42, 0x53, 0x55, 0x30, 0x45, 0x67, ++ 0x56, 0x45, 0x78, 0x54, 0x49, 0x44, 0x49, 0x77, 0x4D, 0x6A, 0x45, 0x78, 0x44, 0x54, 0x41, 0x4C, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x42, 0x45, 0x46, 0x30, 0x62, 0x33, 0x4D, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, ++ 0x0A, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x52, 0x46, 0x4D, 0x49, 0x49, 0x43, 0x49, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x67, 0x38, ++ 0x41, 0x4D, 0x49, 0x49, 0x43, 0x43, 0x67, 0x4B, 0x43, 0x41, 0x67, 0x45, 0x41, 0x74, 0x6F, 0x41, 0x4F, 0x78, 0x48, 0x6D, 0x39, 0x42, 0x59, 0x78, 0x39, 0x73, 0x4B, 0x4F, 0x64, 0x54, 0x53, 0x4A, 0x4E, 0x79, 0x2F, 0x42, 0x42, 0x0A, 0x6C, 0x30, ++ 0x31, 0x5A, 0x34, 0x4E, 0x48, 0x2B, 0x56, 0x6F, 0x79, 0x58, 0x38, 0x74, 0x65, 0x39, 0x6A, 0x32, 0x79, 0x33, 0x49, 0x34, 0x39, 0x66, 0x31, 0x63, 0x54, 0x59, 0x51, 0x63, 0x76, 0x79, 0x41, 0x68, 0x35, 0x78, 0x35, 0x65, 0x6E, 0x32, 0x58, 0x73, ++ 0x73, 0x49, 0x4B, 0x6C, 0x34, 0x77, 0x38, 0x69, 0x31, 0x6D, 0x78, 0x34, 0x51, 0x62, 0x5A, 0x46, 0x63, 0x34, 0x6E, 0x58, 0x55, 0x74, 0x56, 0x73, 0x59, 0x76, 0x59, 0x65, 0x2B, 0x57, 0x2F, 0x43, 0x42, 0x47, 0x0A, 0x76, 0x65, 0x76, 0x55, 0x65, ++ 0x7A, 0x38, 0x2F, 0x66, 0x45, 0x63, 0x34, 0x42, 0x4B, 0x6B, 0x62, 0x71, 0x6C, 0x4C, 0x66, 0x45, 0x7A, 0x66, 0x54, 0x46, 0x52, 0x56, 0x4F, 0x76, 0x56, 0x39, 0x38, 0x72, 0x36, 0x31, 0x6A, 0x78, 0x33, 0x6E, 0x63, 0x43, 0x48, 0x76, 0x56, 0x6F, ++ 0x4F, 0x58, 0x33, 0x57, 0x33, 0x57, 0x73, 0x67, 0x46, 0x57, 0x5A, 0x6B, 0x6D, 0x47, 0x62, 0x7A, 0x53, 0x6F, 0x58, 0x66, 0x64, 0x75, 0x50, 0x39, 0x4C, 0x56, 0x71, 0x36, 0x68, 0x64, 0x4B, 0x0A, 0x5A, 0x43, 0x68, 0x6D, 0x46, 0x53, 0x6C, 0x73, ++ 0x41, 0x76, 0x46, 0x72, 0x31, 0x62, 0x71, 0x6A, 0x4D, 0x39, 0x78, 0x61, 0x5A, 0x36, 0x63, 0x46, 0x34, 0x72, 0x39, 0x6C, 0x74, 0x68, 0x61, 0x77, 0x45, 0x4F, 0x33, 0x4E, 0x55, 0x44, 0x50, 0x4A, 0x63, 0x46, 0x44, 0x73, 0x47, 0x59, 0x36, 0x77, ++ 0x78, 0x2F, 0x4A, 0x30, 0x57, 0x32, 0x74, 0x45, 0x78, 0x6E, 0x32, 0x57, 0x75, 0x5A, 0x67, 0x49, 0x57, 0x57, 0x62, 0x65, 0x4B, 0x51, 0x47, 0x62, 0x39, 0x43, 0x70, 0x74, 0x0A, 0x30, 0x78, 0x55, 0x36, 0x6B, 0x47, 0x70, 0x6E, 0x38, 0x62, 0x52, ++ 0x72, 0x5A, 0x74, 0x6B, 0x68, 0x36, 0x38, 0x72, 0x5A, 0x59, 0x6E, 0x78, 0x47, 0x45, 0x46, 0x7A, 0x65, 0x64, 0x55, 0x6C, 0x6E, 0x6E, 0x6B, 0x4C, 0x35, 0x2F, 0x6E, 0x57, 0x70, 0x6F, 0x36, 0x33, 0x2F, 0x64, 0x67, 0x70, 0x6E, 0x51, 0x4F, 0x50, ++ 0x46, 0x39, 0x34, 0x33, 0x48, 0x68, 0x5A, 0x70, 0x5A, 0x6E, 0x6D, 0x4B, 0x61, 0x61, 0x75, 0x31, 0x46, 0x68, 0x35, 0x68, 0x6E, 0x73, 0x74, 0x56, 0x4B, 0x0A, 0x50, 0x4E, 0x65, 0x30, 0x4F, 0x77, 0x41, 0x4E, 0x77, 0x49, 0x38, 0x66, 0x34, 0x55, ++ 0x44, 0x45, 0x72, 0x6D, 0x77, 0x68, 0x33, 0x45, 0x6C, 0x2B, 0x66, 0x73, 0x71, 0x79, 0x6A, 0x57, 0x32, 0x32, 0x76, 0x35, 0x4D, 0x76, 0x6F, 0x56, 0x77, 0x2B, 0x6A, 0x38, 0x72, 0x74, 0x67, 0x49, 0x35, 0x59, 0x34, 0x64, 0x74, 0x58, 0x7A, 0x34, ++ 0x55, 0x32, 0x4F, 0x4C, 0x4A, 0x78, 0x70, 0x41, 0x6D, 0x4D, 0x6B, 0x6F, 0x6B, 0x49, 0x69, 0x45, 0x6A, 0x78, 0x51, 0x47, 0x4D, 0x59, 0x0A, 0x73, 0x6C, 0x75, 0x4D, 0x57, 0x75, 0x50, 0x44, 0x30, 0x78, 0x65, 0x71, 0x71, 0x78, 0x6D, 0x6A, 0x4C, ++ 0x42, 0x76, 0x6B, 0x31, 0x63, 0x62, 0x69, 0x5A, 0x6E, 0x72, 0x58, 0x67, 0x68, 0x6D, 0x6D, 0x4F, 0x78, 0x59, 0x73, 0x4C, 0x33, 0x47, 0x48, 0x58, 0x30, 0x57, 0x65, 0x6C, 0x58, 0x4F, 0x54, 0x77, 0x6B, 0x4B, 0x42, 0x49, 0x52, 0x4F, 0x57, 0x31, ++ 0x35, 0x32, 0x37, 0x6B, 0x32, 0x67, 0x56, 0x2B, 0x70, 0x32, 0x6B, 0x48, 0x59, 0x7A, 0x79, 0x67, 0x65, 0x42, 0x59, 0x0A, 0x42, 0x72, 0x33, 0x4A, 0x74, 0x75, 0x50, 0x32, 0x69, 0x56, 0x32, 0x4A, 0x2B, 0x61, 0x78, 0x45, 0x6F, 0x63, 0x74, 0x72, ++ 0x2B, 0x68, 0x62, 0x78, 0x78, 0x31, 0x41, 0x39, 0x4A, 0x4E, 0x72, 0x33, 0x77, 0x2B, 0x53, 0x48, 0x31, 0x56, 0x62, 0x78, 0x54, 0x35, 0x41, 0x77, 0x2B, 0x6B, 0x55, 0x4A, 0x57, 0x64, 0x6F, 0x30, 0x7A, 0x75, 0x41, 0x54, 0x48, 0x41, 0x52, 0x38, ++ 0x41, 0x4E, 0x53, 0x62, 0x68, 0x71, 0x52, 0x41, 0x76, 0x4E, 0x6E, 0x63, 0x54, 0x46, 0x64, 0x2B, 0x0A, 0x72, 0x72, 0x63, 0x7A, 0x74, 0x6C, 0x35, 0x32, 0x34, 0x57, 0x57, 0x4C, 0x5A, 0x74, 0x2B, 0x4E, 0x79, 0x74, 0x65, 0x59, 0x72, 0x38, 0x34, ++ 0x32, 0x6D, 0x49, 0x79, 0x63, 0x67, 0x35, 0x6B, 0x44, 0x63, 0x50, 0x4F, 0x76, 0x64, 0x4F, 0x33, 0x47, 0x44, 0x6A, 0x62, 0x6E, 0x76, 0x65, 0x7A, 0x42, 0x63, 0x36, 0x65, 0x55, 0x57, 0x73, 0x75, 0x53, 0x5A, 0x49, 0x4B, 0x6D, 0x41, 0x4D, 0x46, ++ 0x77, 0x6F, 0x57, 0x34, 0x73, 0x4B, 0x65, 0x46, 0x59, 0x56, 0x2B, 0x78, 0x61, 0x0A, 0x66, 0x4A, 0x6C, 0x72, 0x4A, 0x61, 0x53, 0x51, 0x4F, 0x6F, 0x44, 0x30, 0x49, 0x4A, 0x32, 0x61, 0x7A, 0x73, 0x63, 0x74, 0x2B, 0x62, 0x4A, 0x4C, 0x4B, 0x5A, ++ 0x57, 0x44, 0x36, 0x54, 0x57, 0x4E, 0x70, 0x30, 0x6C, 0x49, 0x70, 0x77, 0x39, 0x4D, 0x47, 0x5A, 0x48, 0x51, 0x39, 0x62, 0x38, 0x51, 0x34, 0x48, 0x45, 0x43, 0x41, 0x77, 0x45, 0x41, 0x41, 0x61, 0x4E, 0x43, 0x4D, 0x45, 0x41, 0x77, 0x44, 0x77, ++ 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x0A, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x64, 0x45, 0x6D, 0x5A, 0x30, ++ 0x66, 0x2B, 0x30, 0x65, 0x6D, 0x68, 0x46, 0x64, 0x63, 0x4E, 0x2B, 0x74, 0x4E, 0x7A, 0x4D, 0x7A, 0x6A, 0x6B, 0x7A, 0x32, 0x67, 0x67, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, ++ 0x67, 0x47, 0x47, 0x4D, 0x41, 0x30, 0x47, 0x0A, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x44, 0x41, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x41, 0x51, 0x41, 0x6A, 0x51, 0x31, 0x4D, 0x6B, 0x59, 0x6C, 0x78, 0x74, ++ 0x2F, 0x54, 0x37, 0x43, 0x7A, 0x31, 0x55, 0x41, 0x62, 0x4D, 0x56, 0x57, 0x69, 0x4C, 0x6B, 0x4F, 0x33, 0x54, 0x72, 0x69, 0x4A, 0x51, 0x32, 0x56, 0x53, 0x70, 0x66, 0x4B, 0x67, 0x49, 0x6E, 0x75, 0x4B, 0x73, 0x31, 0x6C, 0x2B, 0x4E, 0x73, 0x57, ++ 0x34, 0x41, 0x6D, 0x53, 0x0A, 0x34, 0x42, 0x6A, 0x48, 0x65, 0x4A, 0x69, 0x37, 0x38, 0x2B, 0x78, 0x43, 0x55, 0x76, 0x75, 0x70, 0x70, 0x49, 0x4C, 0x58, 0x54, 0x64, 0x69, 0x4B, 0x2F, 0x4F, 0x52, 0x4F, 0x2F, 0x61, 0x75, 0x51, 0x78, 0x44, 0x68, ++ 0x31, 0x4D, 0x6F, 0x53, 0x66, 0x2F, 0x37, 0x4F, 0x77, 0x4B, 0x77, 0x49, 0x7A, 0x4E, 0x73, 0x41, 0x51, 0x6B, 0x47, 0x38, 0x64, 0x6E, 0x4B, 0x2F, 0x68, 0x61, 0x5A, 0x50, 0x73, 0x6F, 0x30, 0x55, 0x76, 0x46, 0x4A, 0x2F, 0x31, 0x54, 0x43, 0x70, ++ 0x6C, 0x0A, 0x51, 0x33, 0x49, 0x4D, 0x39, 0x38, 0x50, 0x34, 0x6C, 0x59, 0x73, 0x55, 0x38, 0x34, 0x55, 0x67, 0x59, 0x74, 0x31, 0x55, 0x55, 0x39, 0x30, 0x73, 0x33, 0x42, 0x69, 0x56, 0x61, 0x55, 0x2B, 0x44, 0x52, 0x33, 0x42, 0x41, 0x4D, 0x31, ++ 0x68, 0x33, 0x45, 0x67, 0x79, 0x69, 0x36, 0x31, 0x49, 0x78, 0x48, 0x6B, 0x7A, 0x4A, 0x71, 0x4D, 0x37, 0x46, 0x37, 0x38, 0x50, 0x52, 0x72, 0x65, 0x42, 0x72, 0x41, 0x77, 0x41, 0x30, 0x4A, 0x72, 0x52, 0x55, 0x49, 0x54, 0x57, 0x58, 0x0A, 0x41, ++ 0x64, 0x78, 0x66, 0x47, 0x2F, 0x46, 0x38, 0x35, 0x31, 0x58, 0x36, 0x4C, 0x57, 0x68, 0x33, 0x65, 0x39, 0x4E, 0x70, 0x7A, 0x4E, 0x4D, 0x4F, 0x61, 0x37, 0x70, 0x4E, 0x64, 0x6B, 0x54, 0x57, 0x77, 0x68, 0x57, 0x61, 0x4A, 0x75, 0x79, 0x77, 0x78, ++ 0x66, 0x57, 0x37, 0x30, 0x58, 0x70, 0x30, 0x77, 0x6D, 0x7A, 0x4E, 0x78, 0x62, 0x56, 0x65, 0x39, 0x6B, 0x7A, 0x6D, 0x57, 0x79, 0x32, 0x42, 0x32, 0x37, 0x4F, 0x33, 0x4F, 0x70, 0x65, 0x65, 0x37, 0x63, 0x39, 0x47, 0x0A, 0x73, 0x6C, 0x41, 0x39, ++ 0x68, 0x47, 0x43, 0x5A, 0x63, 0x62, 0x55, 0x7A, 0x74, 0x56, 0x64, 0x46, 0x35, 0x6B, 0x4A, 0x48, 0x64, 0x57, 0x6F, 0x4F, 0x73, 0x41, 0x67, 0x4D, 0x72, 0x72, 0x33, 0x65, 0x39, 0x37, 0x73, 0x50, 0x57, 0x44, 0x32, 0x50, 0x41, 0x7A, 0x48, 0x6F, ++ 0x50, 0x59, 0x4A, 0x51, 0x79, 0x69, 0x39, 0x65, 0x44, 0x46, 0x32, 0x30, 0x6C, 0x37, 0x34, 0x67, 0x4E, 0x41, 0x66, 0x30, 0x78, 0x42, 0x4C, 0x68, 0x37, 0x74, 0x65, 0x77, 0x32, 0x56, 0x6B, 0x74, 0x0A, 0x61, 0x66, 0x63, 0x78, 0x42, 0x50, 0x54, ++ 0x79, 0x2B, 0x61, 0x76, 0x35, 0x45, 0x7A, 0x48, 0x34, 0x41, 0x58, 0x63, 0x4F, 0x50, 0x55, 0x49, 0x6A, 0x4A, 0x73, 0x79, 0x61, 0x63, 0x6D, 0x64, 0x52, 0x49, 0x58, 0x72, 0x4D, 0x50, 0x49, 0x57, 0x6F, 0x36, 0x69, 0x46, 0x71, 0x4F, 0x39, 0x74, ++ 0x61, 0x50, 0x4B, 0x55, 0x30, 0x6E, 0x70, 0x72, 0x41, 0x4C, 0x4E, 0x2B, 0x41, 0x6E, 0x43, 0x6E, 0x67, 0x33, 0x33, 0x65, 0x55, 0x30, 0x61, 0x4B, 0x41, 0x51, 0x76, 0x39, 0x71, 0x0A, 0x54, 0x46, 0x73, 0x52, 0x30, 0x50, 0x58, 0x4E, 0x6F, 0x72, ++ 0x36, 0x75, 0x7A, 0x46, 0x46, 0x63, 0x77, 0x39, 0x56, 0x55, 0x65, 0x77, 0x79, 0x75, 0x31, 0x72, 0x6B, 0x47, 0x64, 0x34, 0x44, 0x69, 0x37, 0x77, 0x63, 0x61, 0x61, 0x4D, 0x78, 0x5A, 0x55, 0x61, 0x31, 0x2B, 0x58, 0x47, 0x64, 0x72, 0x75, 0x64, ++ 0x76, 0x69, 0x42, 0x30, 0x4A, 0x62, 0x75, 0x41, 0x45, 0x46, 0x57, 0x44, 0x6C, 0x4E, 0x35, 0x4C, 0x75, 0x59, 0x6F, 0x37, 0x45, 0x79, 0x37, 0x4E, 0x6D, 0x6A, 0x0A, 0x31, 0x6D, 0x2B, 0x55, 0x49, 0x2F, 0x38, 0x37, 0x74, 0x79, 0x6C, 0x6C, 0x35, ++ 0x67, 0x66, 0x70, 0x37, 0x37, 0x59, 0x5A, 0x36, 0x75, 0x66, 0x43, 0x4F, 0x42, 0x30, 0x79, 0x69, 0x4A, 0x41, 0x38, 0x45, 0x79, 0x74, 0x75, 0x7A, 0x4F, 0x2B, 0x72, 0x64, 0x77, 0x59, 0x30, 0x64, 0x34, 0x52, 0x50, 0x63, 0x75, 0x53, 0x42, 0x68, ++ 0x50, 0x6D, 0x35, 0x64, 0x44, 0x54, 0x65, 0x64, 0x6B, 0x2B, 0x53, 0x4B, 0x6C, 0x4F, 0x78, 0x4A, 0x54, 0x6E, 0x62, 0x50, 0x50, 0x2F, 0x6C, 0x0A, 0x50, 0x71, 0x59, 0x4F, 0x35, 0x57, 0x75, 0x65, 0x2F, 0x39, 0x76, 0x73, 0x4C, 0x33, 0x53, 0x44, ++ 0x33, 0x34, 0x36, 0x30, 0x73, 0x36, 0x6E, 0x65, 0x46, 0x45, 0x33, 0x2F, 0x4D, 0x61, 0x4E, 0x46, 0x63, 0x79, 0x54, 0x36, 0x6C, 0x53, 0x6E, 0x4D, 0x45, 0x70, 0x63, 0x45, 0x6F, 0x6A, 0x69, 0x32, 0x6A, 0x62, 0x44, 0x77, 0x4E, 0x2F, 0x7A, 0x49, ++ 0x49, 0x58, 0x38, 0x2F, 0x73, 0x79, 0x51, 0x62, 0x50, 0x59, 0x74, 0x75, 0x7A, 0x45, 0x32, 0x77, 0x46, 0x67, 0x32, 0x57, 0x0A, 0x48, 0x59, 0x4D, 0x66, 0x52, 0x73, 0x43, 0x62, 0x76, 0x55, 0x4F, 0x5A, 0x35, 0x38, 0x53, 0x57, 0x4C, 0x73, 0x35, ++ 0x66, 0x79, 0x51, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, ++ 0x69, 0x61, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x47, 0x33, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, ++ 0x46, 0x70, 0x54, 0x43, 0x43, 0x41, 0x34, 0x32, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x55, 0x5A, 0x50, 0x59, 0x4F, 0x5A, 0x58, 0x64, 0x68, 0x61, 0x71, 0x73, 0x37, 0x74, 0x4F, 0x71, 0x46, 0x68, 0x4C, 0x75, 0x78, 0x69, 0x62, 0x68, ++ 0x78, 0x6B, 0x77, 0x38, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4D, 0x42, 0x51, 0x41, 0x77, 0x57, 0x6A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x0A, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, ++ 0x4D, 0x43, 0x51, 0x30, 0x34, 0x78, 0x4A, 0x54, 0x41, 0x6A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x48, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x51, 0x58, 0x4E, 0x70, 0x59, 0x53, 0x42, 0x55, 0x5A, 0x57, 0x4E, 0x6F, 0x62, 0x6D, ++ 0x39, 0x73, 0x62, 0x32, 0x64, 0x70, 0x5A, 0x58, 0x4D, 0x73, 0x49, 0x45, 0x6C, 0x75, 0x59, 0x79, 0x34, 0x78, 0x4A, 0x44, 0x41, 0x69, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x0A, 0x47, 0x31, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x51, ++ 0x58, 0x4E, 0x70, 0x59, 0x53, 0x42, 0x48, 0x62, 0x47, 0x39, 0x69, 0x59, 0x57, 0x77, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x53, 0x42, 0x48, 0x4D, 0x7A, 0x41, 0x65, 0x46, 0x77, 0x30, 0x79, 0x4D, 0x54, 0x41, 0x31, 0x4D, ++ 0x6A, 0x41, 0x77, 0x4D, 0x6A, 0x45, 0x77, 0x4D, 0x54, 0x6C, 0x61, 0x46, 0x77, 0x30, 0x30, 0x4E, 0x6A, 0x41, 0x31, 0x4D, 0x54, 0x6B, 0x77, 0x4D, 0x6A, 0x45, 0x77, 0x0A, 0x4D, 0x54, 0x6C, 0x61, 0x4D, 0x46, 0x6F, 0x78, 0x43, 0x7A, 0x41, 0x4A, ++ 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x4E, 0x4F, 0x4D, 0x53, 0x55, 0x77, 0x49, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x44, 0x42, 0x78, 0x55, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x45, 0x46, 0x7A, 0x61, 0x57, 0x45, 0x67, ++ 0x56, 0x47, 0x56, 0x6A, 0x61, 0x47, 0x35, 0x76, 0x62, 0x47, 0x39, 0x6E, 0x61, 0x57, 0x56, 0x7A, 0x4C, 0x43, 0x42, 0x4A, 0x62, 0x6D, 0x4D, 0x75, 0x0A, 0x4D, 0x53, 0x51, 0x77, 0x49, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x42, 0x74, ++ 0x55, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x45, 0x46, 0x7A, 0x61, 0x57, 0x45, 0x67, 0x52, 0x32, 0x78, 0x76, 0x59, 0x6D, 0x46, 0x73, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x52, 0x7A, 0x4D, 0x77, 0x67, 0x67, 0x49, ++ 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x0A, 0x41, 0x34, 0x49, 0x43, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, ++ 0x44, 0x41, 0x4D, 0x59, 0x4A, 0x68, 0x6B, 0x75, 0x53, 0x55, 0x47, 0x77, 0x6F, 0x71, 0x5A, 0x64, 0x43, 0x2B, 0x42, 0x71, 0x6D, 0x48, 0x4F, 0x31, 0x45, 0x53, 0x36, 0x6E, 0x42, 0x42, 0x72, 0x75, 0x4C, 0x37, 0x64, 0x4F, 0x6F, 0x4B, 0x6A, 0x62, ++ 0x6D, 0x7A, 0x54, 0x4E, 0x79, 0x50, 0x74, 0x78, 0x4E, 0x53, 0x54, 0x31, 0x51, 0x59, 0x34, 0x53, 0x78, 0x7A, 0x0A, 0x6C, 0x5A, 0x48, 0x46, 0x5A, 0x6A, 0x74, 0x71, 0x7A, 0x36, 0x78, 0x6A, 0x62, 0x59, 0x64, 0x54, 0x38, 0x50, 0x66, 0x78, 0x4F, ++ 0x62, 0x65, 0x67, 0x51, 0x32, 0x4F, 0x77, 0x78, 0x41, 0x4E, 0x64, 0x56, 0x36, 0x6E, 0x6E, 0x52, 0x4D, 0x37, 0x45, 0x6F, 0x59, 0x4E, 0x6C, 0x39, 0x6C, 0x41, 0x2B, 0x73, 0x58, 0x34, 0x57, 0x75, 0x44, 0x71, 0x4B, 0x41, 0x74, 0x43, 0x57, 0x48, ++ 0x77, 0x44, 0x4E, 0x42, 0x53, 0x48, 0x76, 0x42, 0x6D, 0x33, 0x64, 0x49, 0x5A, 0x77, 0x5A, 0x0A, 0x51, 0x30, 0x57, 0x68, 0x78, 0x65, 0x69, 0x41, 0x79, 0x73, 0x4B, 0x74, 0x51, 0x47, 0x49, 0x58, 0x42, 0x73, 0x61, 0x71, 0x76, 0x50, 0x50, 0x57, ++ 0x35, 0x76, 0x78, 0x51, 0x66, 0x6D, 0x5A, 0x43, 0x48, 0x7A, 0x79, 0x4C, 0x70, 0x6E, 0x6C, 0x35, 0x68, 0x6B, 0x41, 0x31, 0x6E, 0x79, 0x44, 0x76, 0x50, 0x2B, 0x75, 0x4C, 0x52, 0x78, 0x2B, 0x50, 0x6A, 0x73, 0x58, 0x55, 0x6A, 0x72, 0x59, 0x73, ++ 0x79, 0x55, 0x51, 0x45, 0x34, 0x39, 0x52, 0x44, 0x64, 0x54, 0x2F, 0x56, 0x0A, 0x50, 0x36, 0x38, 0x63, 0x7A, 0x48, 0x35, 0x47, 0x58, 0x36, 0x7A, 0x66, 0x5A, 0x42, 0x43, 0x4B, 0x37, 0x30, 0x62, 0x77, 0x6B, 0x50, 0x41, 0x50, 0x4C, 0x66, 0x53, ++ 0x49, 0x43, 0x37, 0x45, 0x70, 0x71, 0x71, 0x2B, 0x46, 0x71, 0x6B, 0x6C, 0x59, 0x71, 0x4C, 0x39, 0x6A, 0x6F, 0x44, 0x69, 0x52, 0x35, 0x72, 0x50, 0x6D, 0x64, 0x32, 0x6A, 0x45, 0x2B, 0x53, 0x6F, 0x5A, 0x68, 0x4C, 0x73, 0x4F, 0x34, 0x66, 0x57, ++ 0x76, 0x69, 0x65, 0x79, 0x6C, 0x4C, 0x31, 0x41, 0x67, 0x0A, 0x64, 0x42, 0x34, 0x53, 0x51, 0x58, 0x4D, 0x65, 0x4A, 0x4E, 0x6E, 0x4B, 0x7A, 0x69, 0x79, 0x68, 0x57, 0x54, 0x58, 0x41, 0x79, 0x42, 0x31, 0x47, 0x4A, 0x32, 0x46, 0x61, 0x6A, 0x2F, ++ 0x6C, 0x4E, 0x30, 0x33, 0x4A, 0x35, 0x5A, 0x68, 0x36, 0x66, 0x46, 0x5A, 0x41, 0x68, 0x4C, 0x66, 0x33, 0x74, 0x69, 0x31, 0x5A, 0x77, 0x41, 0x30, 0x70, 0x4A, 0x50, 0x6E, 0x39, 0x70, 0x4D, 0x52, 0x4A, 0x70, 0x78, 0x78, 0x35, 0x63, 0x79, 0x6E, ++ 0x6F, 0x54, 0x69, 0x2B, 0x6A, 0x6D, 0x0A, 0x39, 0x57, 0x41, 0x50, 0x7A, 0x4A, 0x4D, 0x73, 0x68, 0x48, 0x2F, 0x78, 0x2F, 0x47, 0x72, 0x38, 0x6D, 0x30, 0x65, 0x64, 0x32, 0x36, 0x32, 0x49, 0x50, 0x66, 0x4E, 0x32, 0x64, 0x54, 0x50, 0x58, 0x53, ++ 0x36, 0x54, 0x49, 0x69, 0x2F, 0x6E, 0x31, 0x51, 0x31, 0x68, 0x50, 0x79, 0x38, 0x67, 0x44, 0x56, 0x49, 0x2B, 0x6C, 0x68, 0x58, 0x67, 0x45, 0x47, 0x76, 0x4E, 0x7A, 0x38, 0x74, 0x65, 0x48, 0x48, 0x55, 0x47, 0x66, 0x35, 0x39, 0x67, 0x58, 0x7A, ++ 0x68, 0x71, 0x63, 0x0A, 0x44, 0x30, 0x72, 0x38, 0x33, 0x45, 0x52, 0x6F, 0x56, 0x47, 0x6A, 0x69, 0x51, 0x54, 0x7A, 0x2B, 0x4C, 0x49, 0x53, 0x47, 0x4E, 0x7A, 0x7A, 0x4E, 0x50, 0x79, 0x2B, 0x69, 0x32, 0x2B, 0x66, 0x33, 0x56, 0x41, 0x4E, 0x66, ++ 0x57, 0x64, 0x50, 0x33, 0x6B, 0x58, 0x6A, 0x48, 0x69, 0x33, 0x64, 0x71, 0x46, 0x75, 0x56, 0x4A, 0x68, 0x5A, 0x42, 0x46, 0x63, 0x6E, 0x41, 0x76, 0x6B, 0x56, 0x33, 0x34, 0x50, 0x6D, 0x56, 0x41, 0x43, 0x78, 0x6D, 0x5A, 0x79, 0x53, 0x59, 0x67, ++ 0x0A, 0x57, 0x6D, 0x6A, 0x42, 0x4E, 0x62, 0x39, 0x50, 0x70, 0x31, 0x48, 0x78, 0x32, 0x42, 0x45, 0x72, 0x57, 0x2B, 0x43, 0x61, 0x6E, 0x69, 0x67, 0x37, 0x43, 0x6A, 0x6F, 0x4B, 0x48, 0x38, 0x47, 0x42, 0x35, 0x53, 0x37, 0x77, 0x70, 0x72, 0x6C, ++ 0x70, 0x70, 0x59, 0x69, 0x55, 0x35, 0x6D, 0x73, 0x54, 0x66, 0x39, 0x46, 0x6B, 0x50, 0x7A, 0x32, 0x63, 0x63, 0x45, 0x62, 0x6C, 0x6F, 0x6F, 0x56, 0x37, 0x57, 0x49, 0x51, 0x6E, 0x33, 0x4D, 0x53, 0x41, 0x50, 0x6D, 0x65, 0x61, 0x0A, 0x6D, 0x73, ++ 0x65, 0x61, 0x4D, 0x51, 0x34, 0x77, 0x37, 0x4F, 0x59, 0x58, 0x51, 0x4A, 0x58, 0x5A, 0x52, 0x65, 0x30, 0x42, 0x6C, 0x71, 0x71, 0x2F, 0x44, 0x50, 0x4E, 0x4C, 0x30, 0x57, 0x50, 0x33, 0x45, 0x31, 0x6A, 0x41, 0x75, 0x50, 0x50, 0x36, 0x5A, 0x39, ++ 0x32, 0x62, 0x66, 0x57, 0x31, 0x4B, 0x2F, 0x7A, 0x4A, 0x4D, 0x74, 0x53, 0x55, 0x37, 0x2F, 0x78, 0x78, 0x6E, 0x44, 0x34, 0x55, 0x69, 0x57, 0x51, 0x57, 0x52, 0x6B, 0x55, 0x46, 0x33, 0x67, 0x64, 0x43, 0x46, 0x0A, 0x54, 0x49, 0x63, 0x51, 0x63, ++ 0x66, 0x2B, 0x65, 0x51, 0x78, 0x75, 0x75, 0x6C, 0x58, 0x55, 0x74, 0x67, 0x51, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6F, 0x32, 0x4D, 0x77, 0x59, 0x54, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, ++ 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x49, 0x77, 0x51, 0x59, 0x4D, 0x42, 0x61, 0x41, 0x46, 0x45, 0x44, 0x6B, 0x35, 0x50, 0x49, 0x6A, 0x0A, 0x37, 0x7A, 0x6A, 0x4B, 0x73, 0x4B, 0x35, 0x58, ++ 0x66, 0x2F, 0x49, 0x68, 0x4D, 0x42, 0x59, 0x30, 0x32, 0x37, 0x79, 0x53, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x52, 0x41, 0x35, 0x4F, 0x54, 0x79, 0x49, 0x2B, 0x38, 0x34, 0x79, 0x72, 0x43, 0x75, ++ 0x56, 0x33, 0x2F, 0x79, 0x49, 0x54, 0x41, 0x57, 0x4E, 0x4E, 0x75, 0x38, 0x6B, 0x6A, 0x41, 0x4F, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x0A, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x51, 0x59, 0x77, 0x44, 0x51, 0x59, ++ 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4D, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x42, 0x41, 0x43, 0x59, 0x37, 0x55, 0x65, 0x46, 0x4E, 0x4F, 0x50, 0x4D, 0x79, 0x47, 0x4C, 0x53, 0x30, 0x58, 0x75, 0x46, ++ 0x6C, 0x58, 0x73, 0x53, 0x55, 0x54, 0x39, 0x53, 0x6E, 0x59, 0x61, 0x50, 0x34, 0x77, 0x4D, 0x38, 0x7A, 0x41, 0x51, 0x4C, 0x70, 0x77, 0x36, 0x6F, 0x31, 0x0A, 0x44, 0x2F, 0x47, 0x55, 0x45, 0x33, 0x64, 0x33, 0x4E, 0x5A, 0x34, 0x74, 0x56, 0x6C, ++ 0x46, 0x45, 0x62, 0x75, 0x48, 0x47, 0x4C, 0x69, 0x67, 0x65, 0x2F, 0x39, 0x72, 0x73, 0x52, 0x38, 0x32, 0x58, 0x52, 0x42, 0x66, 0x33, 0x34, 0x45, 0x7A, 0x43, 0x34, 0x58, 0x78, 0x38, 0x4D, 0x6E, 0x70, 0x6D, 0x79, 0x46, 0x71, 0x32, 0x58, 0x46, ++ 0x4E, 0x46, 0x56, 0x31, 0x70, 0x46, 0x31, 0x41, 0x57, 0x5A, 0x4C, 0x79, 0x34, 0x6A, 0x56, 0x65, 0x35, 0x6A, 0x61, 0x4E, 0x2F, 0x54, 0x0A, 0x47, 0x33, 0x69, 0x6E, 0x45, 0x70, 0x51, 0x47, 0x41, 0x48, 0x55, 0x4E, 0x63, 0x6F, 0x54, 0x70, 0x4C, ++ 0x72, 0x78, 0x61, 0x61, 0x74, 0x58, 0x65, 0x4C, 0x31, 0x6E, 0x48, 0x6F, 0x2B, 0x7A, 0x53, 0x68, 0x32, 0x62, 0x62, 0x74, 0x31, 0x53, 0x31, 0x4A, 0x4B, 0x76, 0x30, 0x51, 0x33, 0x6A, 0x62, 0x53, 0x77, 0x54, 0x45, 0x62, 0x39, 0x33, 0x6D, 0x50, ++ 0x6D, 0x59, 0x2B, 0x4B, 0x66, 0x4A, 0x4C, 0x61, 0x48, 0x45, 0x69, 0x68, 0x36, 0x44, 0x34, 0x73, 0x54, 0x4E, 0x6A, 0x0A, 0x64, 0x75, 0x4D, 0x4E, 0x68, 0x58, 0x4A, 0x45, 0x49, 0x6C, 0x55, 0x2F, 0x48, 0x48, 0x7A, 0x70, 0x2F, 0x4C, 0x67, 0x56, ++ 0x36, 0x46, 0x4C, 0x36, 0x71, 0x6A, 0x36, 0x6A, 0x49, 0x54, 0x6B, 0x31, 0x64, 0x49, 0x6D, 0x6D, 0x61, 0x73, 0x49, 0x35, 0x2B, 0x6E, 0x6A, 0x50, 0x74, 0x71, 0x7A, 0x6E, 0x35, 0x39, 0x5A, 0x57, 0x2F, 0x79, 0x4F, 0x53, 0x4C, 0x6C, 0x41, 0x4C, ++ 0x71, 0x62, 0x55, 0x48, 0x4D, 0x2F, 0x51, 0x34, 0x58, 0x36, 0x52, 0x4A, 0x70, 0x73, 0x74, 0x6C, 0x0A, 0x63, 0x48, 0x62, 0x6F, 0x43, 0x6F, 0x57, 0x41, 0x53, 0x7A, 0x59, 0x39, 0x4D, 0x2F, 0x65, 0x56, 0x56, 0x48, 0x55, 0x6C, 0x32, 0x71, 0x7A, ++ 0x45, 0x63, 0x34, 0x4A, 0x6C, 0x36, 0x56, 0x4C, 0x31, 0x58, 0x50, 0x30, 0x34, 0x6C, 0x51, 0x4A, 0x71, 0x61, 0x54, 0x44, 0x46, 0x48, 0x41, 0x70, 0x58, 0x42, 0x36, 0x34, 0x69, 0x70, 0x43, 0x7A, 0x35, 0x78, 0x55, 0x47, 0x33, 0x75, 0x4F, 0x79, ++ 0x66, 0x54, 0x30, 0x67, 0x41, 0x2B, 0x51, 0x45, 0x45, 0x56, 0x63, 0x79, 0x73, 0x0A, 0x2B, 0x54, 0x49, 0x78, 0x78, 0x48, 0x57, 0x56, 0x42, 0x71, 0x42, 0x2F, 0x30, 0x59, 0x30, 0x6E, 0x33, 0x62, 0x4F, 0x70, 0x70, 0x48, 0x4B, 0x48, 0x2F, 0x6C, ++ 0x6D, 0x4C, 0x6D, 0x6E, 0x70, 0x30, 0x46, 0x74, 0x30, 0x57, 0x70, 0x57, 0x49, 0x70, 0x36, 0x7A, 0x71, 0x57, 0x33, 0x49, 0x75, 0x6E, 0x61, 0x46, 0x6E, 0x54, 0x36, 0x33, 0x65, 0x52, 0x4F, 0x66, 0x6A, 0x58, 0x79, 0x39, 0x6D, 0x50, 0x58, 0x31, ++ 0x6F, 0x6E, 0x41, 0x58, 0x31, 0x64, 0x61, 0x42, 0x6C, 0x69, 0x0A, 0x32, 0x4D, 0x6A, 0x4E, 0x39, 0x4C, 0x64, 0x79, 0x52, 0x37, 0x35, 0x62, 0x6C, 0x38, 0x37, 0x79, 0x72, 0x61, 0x4B, 0x5A, 0x6B, 0x36, 0x32, 0x55, 0x79, 0x35, 0x50, 0x32, 0x45, ++ 0x67, 0x6D, 0x56, 0x74, 0x71, 0x76, 0x58, 0x4F, 0x39, 0x41, 0x2F, 0x45, 0x63, 0x73, 0x77, 0x46, 0x69, 0x35, 0x35, 0x67, 0x4F, 0x52, 0x6E, 0x67, 0x53, 0x31, 0x64, 0x37, 0x58, 0x42, 0x34, 0x74, 0x6D, 0x42, 0x5A, 0x72, 0x4F, 0x46, 0x64, 0x52, ++ 0x57, 0x4F, 0x50, 0x79, 0x4E, 0x39, 0x79, 0x0A, 0x61, 0x46, 0x76, 0x71, 0x48, 0x62, 0x67, 0x42, 0x38, 0x58, 0x37, 0x37, 0x35, 0x34, 0x71, 0x7A, 0x34, 0x31, 0x53, 0x67, 0x4F, 0x41, 0x6E, 0x67, 0x50, 0x4E, 0x35, 0x43, 0x38, 0x73, 0x4C, 0x74, ++ 0x4C, 0x70, 0x76, 0x7A, 0x48, 0x7A, 0x57, 0x32, 0x4E, 0x74, 0x6A, 0x6A, 0x67, 0x4B, 0x47, 0x4C, 0x7A, 0x5A, 0x6C, 0x6B, 0x44, 0x38, 0x4B, 0x71, 0x71, 0x37, 0x48, 0x4B, 0x39, 0x57, 0x2B, 0x65, 0x51, 0x34, 0x32, 0x45, 0x56, 0x4A, 0x6D, 0x7A, ++ 0x62, 0x73, 0x41, 0x53, 0x0A, 0x5A, 0x74, 0x68, 0x77, 0x45, 0x50, 0x45, 0x47, 0x4E, 0x54, 0x4E, 0x44, 0x71, 0x4A, 0x77, 0x75, 0x75, 0x68, 0x51, 0x78, 0x7A, 0x68, 0x42, 0x2F, 0x48, 0x49, 0x62, 0x6A, 0x6A, 0x39, 0x4C, 0x56, 0x2B, 0x48, 0x66, ++ 0x73, 0x6D, 0x36, 0x76, 0x78, 0x4C, 0x32, 0x50, 0x5A, 0x51, 0x6C, 0x2F, 0x67, 0x5A, 0x34, 0x46, 0x6B, 0x6B, 0x66, 0x47, 0x58, 0x4C, 0x2F, 0x78, 0x75, 0x4A, 0x76, 0x59, 0x7A, 0x2B, 0x4E, 0x4F, 0x31, 0x2B, 0x4D, 0x52, 0x69, 0x71, 0x7A, 0x46, ++ 0x52, 0x0A, 0x4A, 0x51, 0x4A, 0x36, 0x2B, 0x4E, 0x31, 0x72, 0x5A, 0x64, 0x56, 0x74, 0x54, 0x54, 0x44, 0x49, 0x5A, 0x62, 0x70, 0x6F, 0x46, 0x47, 0x57, 0x73, 0x4A, 0x77, 0x74, 0x30, 0x69, 0x76, 0x4B, 0x48, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, 0x69, 0x61, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, ++ 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x47, 0x34, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, ++ 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x56, 0x54, 0x43, 0x43, 0x41, 0x64, 0x79, 0x67, 0x41, 0x77, ++ 0x49, 0x42, 0x41, 0x67, 0x49, 0x55, 0x54, 0x79, 0x4E, 0x6B, 0x75, 0x49, 0x36, 0x58, 0x59, 0x35, 0x37, 0x47, 0x55, 0x34, 0x48, 0x42, 0x64, 0x6B, 0x37, 0x4C, 0x4B, 0x6E, 0x51, 0x56, 0x31, 0x74, 0x63, 0x77, 0x43, 0x67, 0x59, 0x49, 0x4B, 0x6F, ++ 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x45, 0x41, 0x77, 0x4D, 0x77, 0x57, 0x6A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0A, 0x42, 0x68, 0x4D, 0x43, 0x51, 0x30, 0x34, 0x78, 0x4A, 0x54, 0x41, 0x6A, 0x42, 0x67, 0x4E, 0x56, 0x42, ++ 0x41, 0x6F, 0x4D, 0x48, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x51, 0x58, 0x4E, 0x70, 0x59, 0x53, 0x42, 0x55, 0x5A, 0x57, 0x4E, 0x6F, 0x62, 0x6D, 0x39, 0x73, 0x62, 0x32, 0x64, 0x70, 0x5A, 0x58, 0x4D, 0x73, 0x49, 0x45, 0x6C, 0x75, 0x59, ++ 0x79, 0x34, 0x78, 0x4A, 0x44, 0x41, 0x69, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x47, 0x31, 0x52, 0x79, 0x0A, 0x64, 0x58, 0x4E, 0x30, 0x51, 0x58, 0x4E, 0x70, 0x59, 0x53, 0x42, 0x48, 0x62, 0x47, 0x39, 0x69, 0x59, 0x57, 0x77, 0x67, ++ 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x53, 0x42, 0x48, 0x4E, 0x44, 0x41, 0x65, 0x46, 0x77, 0x30, 0x79, 0x4D, 0x54, 0x41, 0x31, 0x4D, 0x6A, 0x41, 0x77, 0x4D, 0x6A, 0x45, 0x77, 0x4D, 0x6A, 0x4A, 0x61, 0x46, 0x77, 0x30, 0x30, ++ 0x4E, 0x6A, 0x41, 0x31, 0x4D, 0x54, 0x6B, 0x77, 0x4D, 0x6A, 0x45, 0x77, 0x4D, 0x6A, 0x4A, 0x61, 0x0A, 0x4D, 0x46, 0x6F, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x4E, 0x4F, 0x4D, 0x53, 0x55, ++ 0x77, 0x49, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x44, 0x42, 0x78, 0x55, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x45, 0x46, 0x7A, 0x61, 0x57, 0x45, 0x67, 0x56, 0x47, 0x56, 0x6A, 0x61, 0x47, 0x35, 0x76, 0x62, 0x47, 0x39, 0x6E, 0x61, 0x57, 0x56, ++ 0x7A, 0x4C, 0x43, 0x42, 0x4A, 0x62, 0x6D, 0x4D, 0x75, 0x4D, 0x53, 0x51, 0x77, 0x0A, 0x49, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x42, 0x74, 0x55, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x45, 0x46, 0x7A, 0x61, 0x57, 0x45, 0x67, 0x52, 0x32, ++ 0x78, 0x76, 0x59, 0x6D, 0x46, 0x73, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x52, 0x7A, 0x51, 0x77, 0x64, 0x6A, 0x41, 0x51, 0x42, 0x67, 0x63, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x49, 0x42, 0x42, 0x67, ++ 0x55, 0x72, 0x67, 0x51, 0x51, 0x41, 0x49, 0x67, 0x4E, 0x69, 0x0A, 0x41, 0x41, 0x54, 0x78, 0x73, 0x38, 0x30, 0x34, 0x35, 0x43, 0x56, 0x44, 0x35, 0x64, 0x34, 0x5A, 0x43, 0x62, 0x75, 0x42, 0x65, 0x61, 0x49, 0x56, 0x58, 0x78, 0x56, 0x6A, 0x41, ++ 0x64, 0x37, 0x43, 0x71, 0x39, 0x32, 0x7A, 0x70, 0x68, 0x74, 0x6E, 0x53, 0x34, 0x43, 0x44, 0x72, 0x35, 0x6E, 0x4C, 0x72, 0x42, 0x66, 0x62, 0x4B, 0x35, 0x62, 0x4B, 0x66, 0x46, 0x4A, 0x56, 0x34, 0x68, 0x72, 0x68, 0x50, 0x56, 0x62, 0x77, 0x4C, ++ 0x78, 0x59, 0x49, 0x2B, 0x68, 0x57, 0x38, 0x0A, 0x6D, 0x37, 0x74, 0x48, 0x35, 0x6A, 0x2F, 0x75, 0x71, 0x4F, 0x46, 0x4D, 0x6A, 0x50, 0x58, 0x54, 0x4E, 0x76, 0x6B, 0x34, 0x58, 0x61, 0x74, 0x77, 0x6D, 0x6B, 0x63, 0x4E, 0x34, 0x6F, 0x46, 0x42, ++ 0x42, 0x75, 0x74, 0x4A, 0x2B, 0x62, 0x41, 0x70, 0x33, 0x54, 0x50, 0x73, 0x55, 0x4B, 0x56, 0x2F, 0x65, 0x53, 0x6D, 0x34, 0x49, 0x4A, 0x69, 0x6A, 0x59, 0x7A, 0x42, 0x68, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, ++ 0x2F, 0x77, 0x51, 0x46, 0x0A, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x48, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x6A, 0x42, 0x42, 0x67, 0x77, 0x46, 0x6F, 0x41, 0x55, 0x70, 0x62, 0x74, 0x4B, 0x6C, 0x38, 0x36, 0x7A, 0x4B, 0x33, 0x2B, ++ 0x6B, 0x4D, 0x64, 0x36, 0x58, 0x67, 0x31, 0x6D, 0x44, 0x70, 0x6D, 0x39, 0x78, 0x79, 0x39, 0x34, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x46, 0x4B, 0x57, 0x37, 0x53, 0x70, 0x66, 0x4F, 0x73, 0x79, 0x74, ++ 0x2F, 0x0A, 0x70, 0x44, 0x48, 0x65, 0x6C, 0x34, 0x4E, 0x5A, 0x67, 0x36, 0x5A, 0x76, 0x63, 0x63, 0x76, 0x65, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6A, ++ 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x77, 0x4E, 0x6E, 0x41, 0x44, 0x42, 0x6B, 0x41, 0x6A, 0x42, 0x65, 0x38, 0x75, 0x73, 0x47, 0x7A, 0x45, 0x6B, 0x78, 0x6E, 0x30, 0x41, 0x41, 0x0A, 0x62, ++ 0x62, 0x64, 0x2B, 0x4E, 0x76, 0x42, 0x4E, 0x45, 0x55, 0x2F, 0x7A, 0x79, 0x34, 0x6B, 0x36, 0x4C, 0x48, 0x69, 0x52, 0x55, 0x4B, 0x4E, 0x62, 0x77, 0x4D, 0x70, 0x31, 0x4A, 0x76, 0x4B, 0x2F, 0x6B, 0x46, 0x30, 0x4C, 0x67, 0x6F, 0x78, 0x67, 0x4B, ++ 0x4A, 0x2F, 0x47, 0x63, 0x4A, 0x70, 0x6F, 0x35, 0x50, 0x45, 0x43, 0x4D, 0x46, 0x78, 0x59, 0x44, 0x6C, 0x5A, 0x32, 0x7A, 0x31, 0x6A, 0x44, 0x31, 0x78, 0x43, 0x4D, 0x75, 0x6F, 0x36, 0x75, 0x34, 0x37, 0x78, 0x6B, 0x0A, 0x64, 0x55, 0x66, 0x46, ++ 0x56, 0x5A, 0x44, 0x6A, 0x2F, 0x62, 0x70, 0x56, 0x36, 0x77, 0x66, 0x45, 0x55, 0x36, 0x73, 0x33, 0x71, 0x65, 0x34, 0x68, 0x73, 0x69, 0x46, 0x62, 0x59, 0x49, 0x38, 0x39, 0x4D, 0x76, 0x48, 0x56, 0x49, 0x35, 0x54, 0x57, 0x57, 0x41, 0x3D, 0x3D, ++ 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x54, 0x65, 0x6C, 0x65, 0x6B, 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, ++ 0x72, 0x69, 0x74, 0x79, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x32, 0x30, 0x32, 0x30, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, ++ 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x51, 0x6A, 0x43, 0x43, 0x41, 0x63, 0x6D, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x4E, 0x6A, 0x71, 0x57, 0x6A, 0x4D, 0x6C, 0x63, 0x73, 0x6C, 0x6A, 0x4E, 0x30, 0x41, ++ 0x46, 0x64, 0x78, 0x65, 0x56, 0x58, 0x41, 0x44, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x7A, 0x42, 0x6A, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, ++ 0x4A, 0x45, 0x0A, 0x52, 0x54, 0x45, 0x6E, 0x4D, 0x43, 0x55, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x65, 0x52, 0x47, 0x56, 0x31, 0x64, 0x48, 0x4E, 0x6A, 0x61, 0x47, 0x55, 0x67, 0x56, 0x47, 0x56, 0x73, 0x5A, 0x57, 0x74, 0x76, 0x62, ++ 0x53, 0x42, 0x54, 0x5A, 0x57, 0x4E, 0x31, 0x63, 0x6D, 0x6C, 0x30, 0x65, 0x53, 0x42, 0x48, 0x62, 0x57, 0x4A, 0x49, 0x4D, 0x53, 0x73, 0x77, 0x4B, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x43, 0x4A, 0x55, 0x5A, 0x57, 0x78, 0x6C, 0x0A, ++ 0x61, 0x32, 0x39, 0x74, 0x49, 0x46, 0x4E, 0x6C, 0x59, 0x33, 0x56, 0x79, 0x61, 0x58, 0x52, 0x35, 0x49, 0x46, 0x52, 0x4D, 0x55, 0x79, 0x42, 0x46, 0x51, 0x30, 0x4D, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x41, 0x79, 0x4D, 0x44, 0x49, 0x77, ++ 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x49, 0x77, 0x4D, 0x44, 0x67, 0x79, 0x4E, 0x54, 0x41, 0x33, 0x4E, 0x44, 0x67, 0x79, 0x4D, 0x46, 0x6F, 0x58, 0x44, 0x54, 0x51, 0x31, 0x4D, 0x44, 0x67, 0x79, 0x4E, 0x54, 0x49, 0x7A, 0x0A, 0x4E, 0x54, 0x6B, ++ 0x31, 0x4F, 0x56, 0x6F, 0x77, 0x59, 0x7A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x52, 0x45, 0x55, 0x78, 0x4A, 0x7A, 0x41, 0x6C, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x48, 0x6B, 0x52, ++ 0x6C, 0x64, 0x58, 0x52, 0x7A, 0x59, 0x32, 0x68, 0x6C, 0x49, 0x46, 0x52, 0x6C, 0x62, 0x47, 0x56, 0x72, 0x62, 0x32, 0x30, 0x67, 0x55, 0x32, 0x56, 0x6A, 0x64, 0x58, 0x4A, 0x70, 0x64, 0x48, 0x6B, 0x67, 0x0A, 0x52, 0x32, 0x31, 0x69, 0x53, 0x44, ++ 0x45, 0x72, 0x4D, 0x43, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x69, 0x56, 0x47, 0x56, 0x73, 0x5A, 0x57, 0x74, 0x76, 0x62, 0x53, 0x42, 0x54, 0x5A, 0x57, 0x4E, 0x31, 0x63, 0x6D, 0x6C, 0x30, 0x65, 0x53, 0x42, 0x55, 0x54, 0x46, ++ 0x4D, 0x67, 0x52, 0x55, 0x4E, 0x44, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x4D, 0x6A, 0x41, 0x79, 0x4D, 0x44, 0x42, 0x32, 0x4D, 0x42, 0x41, 0x47, 0x42, 0x79, 0x71, 0x47, 0x0A, 0x53, 0x4D, 0x34, 0x39, 0x41, 0x67, 0x45, 0x47, 0x42, ++ 0x53, 0x75, 0x42, 0x42, 0x41, 0x41, 0x69, 0x41, 0x32, 0x49, 0x41, 0x42, 0x4D, 0x36, 0x2F, 0x2F, 0x6C, 0x65, 0x6F, 0x76, 0x39, 0x57, 0x71, 0x39, 0x78, 0x43, 0x61, 0x7A, 0x62, 0x7A, 0x52, 0x45, 0x61, 0x4B, 0x39, 0x5A, 0x30, 0x4C, 0x4D, 0x6B, ++ 0x4F, 0x73, 0x56, 0x47, 0x4A, 0x44, 0x5A, 0x6F, 0x73, 0x30, 0x4D, 0x4B, 0x69, 0x58, 0x72, 0x50, 0x6B, 0x2F, 0x4F, 0x74, 0x64, 0x4B, 0x50, 0x44, 0x2F, 0x4D, 0x31, 0x0A, 0x32, 0x6B, 0x4F, 0x4C, 0x41, 0x6F, 0x43, 0x2B, 0x62, 0x31, 0x45, 0x6B, ++ 0x48, 0x51, 0x39, 0x72, 0x4B, 0x38, 0x71, 0x66, 0x77, 0x6D, 0x39, 0x51, 0x4D, 0x75, 0x55, 0x33, 0x49, 0x4C, 0x59, 0x67, 0x2F, 0x34, 0x67, 0x4E, 0x44, 0x32, 0x31, 0x4A, 0x75, 0x39, 0x73, 0x47, 0x70, 0x49, 0x65, 0x51, 0x6B, 0x70, 0x54, 0x30, ++ 0x43, 0x64, 0x44, 0x50, 0x66, 0x38, 0x69, 0x41, 0x43, 0x38, 0x47, 0x58, 0x73, 0x37, 0x73, 0x31, 0x4A, 0x38, 0x6E, 0x43, 0x47, 0x36, 0x4E, 0x43, 0x0A, 0x4D, 0x45, 0x41, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, ++ 0x45, 0x46, 0x4F, 0x4E, 0x79, 0x7A, 0x47, 0x36, 0x56, 0x6D, 0x55, 0x65, 0x78, 0x35, 0x72, 0x4E, 0x68, 0x54, 0x4E, 0x48, 0x4C, 0x71, 0x2B, 0x4F, 0x36, 0x7A, 0x64, 0x36, 0x66, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, ++ 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x0A, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4D, 0x41, 0x6F, 0x47, 0x43, 0x43, ++ 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x42, 0x41, 0x4D, 0x44, 0x41, 0x32, 0x63, 0x41, 0x4D, 0x47, 0x51, 0x43, 0x4D, 0x48, 0x56, 0x53, 0x69, 0x37, 0x65, 0x6B, 0x45, 0x45, 0x2B, 0x75, 0x53, 0x68, 0x43, 0x4C, 0x73, 0x6F, 0x52, 0x62, 0x51, 0x75, ++ 0x48, 0x6D, 0x4B, 0x6A, 0x59, 0x43, 0x32, 0x71, 0x42, 0x75, 0x47, 0x54, 0x38, 0x6C, 0x76, 0x39, 0x70, 0x5A, 0x0A, 0x4D, 0x6F, 0x37, 0x6B, 0x2B, 0x35, 0x44, 0x63, 0x6B, 0x32, 0x54, 0x4F, 0x72, 0x62, 0x52, 0x42, 0x52, 0x32, 0x44, 0x69, 0x7A, ++ 0x36, 0x66, 0x4C, 0x48, 0x67, 0x49, 0x77, 0x4E, 0x30, 0x47, 0x4D, 0x5A, 0x74, 0x39, 0x42, 0x61, 0x39, 0x61, 0x44, 0x41, 0x45, 0x48, 0x39, 0x4C, 0x31, 0x72, 0x33, 0x55, 0x4C, 0x52, 0x6E, 0x30, 0x53, 0x79, 0x6F, 0x63, 0x64, 0x64, 0x44, 0x79, ++ 0x70, 0x77, 0x6E, 0x4A, 0x4A, 0x47, 0x44, 0x53, 0x41, 0x33, 0x50, 0x7A, 0x66, 0x64, 0x55, 0x0A, 0x67, 0x61, 0x2F, 0x73, 0x66, 0x2B, 0x52, 0x6E, 0x32, 0x37, 0x69, 0x51, 0x37, 0x74, 0x30, 0x6C, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, ++ 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x54, 0x65, 0x6C, 0x65, 0x6B, 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x54, 0x4C, 0x53, ++ 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x32, 0x30, 0x32, 0x33, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, ++ 0x49, 0x46, 0x73, 0x7A, 0x43, 0x43, 0x41, 0x35, 0x75, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x49, 0x5A, 0x78, 0x55, 0x4C, 0x65, 0x6A, 0x32, 0x37, 0x48, 0x46, 0x33, 0x2B, 0x6B, 0x37, 0x6F, 0x77, 0x33, 0x42, 0x58, 0x6C, 0x7A, ++ 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x77, 0x46, 0x41, 0x44, 0x42, 0x6A, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0A, 0x45, 0x77, 0x4A, 0x45, 0x52, ++ 0x54, 0x45, 0x6E, 0x4D, 0x43, 0x55, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x65, 0x52, 0x47, 0x56, 0x31, 0x64, 0x48, 0x4E, 0x6A, 0x61, 0x47, 0x55, 0x67, 0x56, 0x47, 0x56, 0x73, 0x5A, 0x57, 0x74, 0x76, 0x62, 0x53, 0x42, 0x54, 0x5A, ++ 0x57, 0x4E, 0x31, 0x63, 0x6D, 0x6C, 0x30, 0x65, 0x53, 0x42, 0x48, 0x62, 0x57, 0x4A, 0x49, 0x4D, 0x53, 0x73, 0x77, 0x4B, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x43, 0x4A, 0x55, 0x0A, 0x5A, 0x57, 0x78, 0x6C, 0x61, 0x32, 0x39, 0x74, ++ 0x49, 0x46, 0x4E, 0x6C, 0x59, 0x33, 0x56, 0x79, 0x61, 0x58, 0x52, 0x35, 0x49, 0x46, 0x52, 0x4D, 0x55, 0x79, 0x42, 0x53, 0x55, 0x30, 0x45, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x41, 0x79, 0x4D, 0x44, 0x49, 0x7A, 0x4D, 0x42, 0x34, 0x58, ++ 0x44, 0x54, 0x49, 0x7A, 0x4D, 0x44, 0x4D, 0x79, 0x4F, 0x44, 0x45, 0x79, 0x4D, 0x54, 0x59, 0x30, 0x4E, 0x56, 0x6F, 0x58, 0x44, 0x54, 0x51, 0x34, 0x4D, 0x44, 0x4D, 0x79, 0x0A, 0x4E, 0x7A, 0x49, 0x7A, 0x4E, 0x54, 0x6B, 0x31, 0x4F, 0x56, 0x6F, ++ 0x77, 0x59, 0x7A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x52, 0x45, 0x55, 0x78, 0x4A, 0x7A, 0x41, 0x6C, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x48, 0x6B, 0x52, 0x6C, 0x64, 0x58, 0x52, ++ 0x7A, 0x59, 0x32, 0x68, 0x6C, 0x49, 0x46, 0x52, 0x6C, 0x62, 0x47, 0x56, 0x72, 0x62, 0x32, 0x30, 0x67, 0x55, 0x32, 0x56, 0x6A, 0x64, 0x58, 0x4A, 0x70, 0x0A, 0x64, 0x48, 0x6B, 0x67, 0x52, 0x32, 0x31, 0x69, 0x53, 0x44, 0x45, 0x72, 0x4D, 0x43, ++ 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x69, 0x56, 0x47, 0x56, 0x73, 0x5A, 0x57, 0x74, 0x76, 0x62, 0x53, 0x42, 0x54, 0x5A, 0x57, 0x4E, 0x31, 0x63, 0x6D, 0x6C, 0x30, 0x65, 0x53, 0x42, 0x55, 0x54, 0x46, 0x4D, 0x67, 0x55, 0x6C, ++ 0x4E, 0x42, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x4D, 0x6A, 0x41, 0x79, 0x4D, 0x7A, 0x43, 0x43, 0x41, 0x69, 0x49, 0x77, 0x0A, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, ++ 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x67, 0x6F, 0x43, 0x67, 0x67, 0x49, 0x42, 0x41, 0x4F, 0x30, 0x31, 0x6F, 0x59, 0x47, 0x41, 0x38, 0x38, 0x74, 0x4B, 0x61, 0x56, 0x76, 0x43, 0x2B, 0x31, 0x47, 0x44, 0x72, ++ 0x69, 0x62, 0x39, 0x34, 0x57, 0x37, 0x7A, 0x67, 0x52, 0x4A, 0x39, 0x63, 0x55, 0x44, 0x2F, 0x68, 0x33, 0x56, 0x43, 0x0A, 0x4B, 0x53, 0x48, 0x74, 0x67, 0x56, 0x49, 0x73, 0x33, 0x78, 0x4C, 0x42, 0x47, 0x59, 0x53, 0x4A, 0x77, 0x62, 0x33, 0x46, ++ 0x4B, 0x4E, 0x58, 0x56, 0x53, 0x32, 0x78, 0x45, 0x31, 0x6B, 0x7A, 0x62, 0x42, 0x35, 0x5A, 0x4B, 0x56, 0x58, 0x72, 0x4B, 0x4E, 0x6F, 0x49, 0x45, 0x4E, 0x71, 0x69, 0x6C, 0x2F, 0x43, 0x66, 0x32, 0x53, 0x66, 0x48, 0x56, 0x63, 0x70, 0x36, 0x52, ++ 0x2B, 0x53, 0x50, 0x57, 0x63, 0x48, 0x75, 0x37, 0x39, 0x5A, 0x76, 0x42, 0x37, 0x4A, 0x50, 0x50, 0x0A, 0x47, 0x65, 0x70, 0x6C, 0x66, 0x6F, 0x68, 0x77, 0x6F, 0x48, 0x50, 0x38, 0x39, 0x76, 0x2B, 0x31, 0x56, 0x6D, 0x4C, 0x68, 0x63, 0x32, 0x6F, ++ 0x30, 0x6D, 0x44, 0x36, 0x43, 0x75, 0x4B, 0x79, 0x56, 0x55, 0x2F, 0x51, 0x42, 0x6F, 0x43, 0x63, 0x48, 0x63, 0x71, 0x4D, 0x41, 0x55, 0x36, 0x44, 0x6B, 0x73, 0x71, 0x75, 0x44, 0x4F, 0x46, 0x63, 0x7A, 0x4A, 0x5A, 0x53, 0x66, 0x76, 0x6B, 0x67, ++ 0x64, 0x6D, 0x4F, 0x47, 0x6A, 0x75, 0x70, 0x35, 0x63, 0x7A, 0x51, 0x52, 0x78, 0x0A, 0x55, 0x58, 0x31, 0x31, 0x65, 0x4B, 0x76, 0x7A, 0x57, 0x61, 0x72, 0x45, 0x34, 0x47, 0x43, 0x2B, 0x6A, 0x34, 0x4E, 0x53, 0x75, 0x48, 0x55, 0x61, 0x51, 0x54, ++ 0x58, 0x74, 0x76, 0x50, 0x4D, 0x36, 0x59, 0x2B, 0x6D, 0x70, 0x46, 0x45, 0x58, 0x58, 0x35, 0x6C, 0x4C, 0x52, 0x62, 0x74, 0x4C, 0x65, 0x76, 0x4F, 0x50, 0x31, 0x43, 0x7A, 0x76, 0x6D, 0x34, 0x4D, 0x53, 0x39, 0x51, 0x32, 0x51, 0x54, 0x70, 0x73, ++ 0x37, 0x30, 0x6D, 0x44, 0x64, 0x73, 0x69, 0x70, 0x57, 0x6F, 0x0A, 0x6C, 0x38, 0x68, 0x48, 0x44, 0x2F, 0x42, 0x65, 0x45, 0x49, 0x76, 0x6E, 0x48, 0x52, 0x7A, 0x2B, 0x73, 0x54, 0x75, 0x67, 0x42, 0x54, 0x4E, 0x6F, 0x42, 0x55, 0x47, 0x43, 0x77, ++ 0x51, 0x4D, 0x72, 0x41, 0x63, 0x6A, 0x6E, 0x6A, 0x30, 0x32, 0x72, 0x36, 0x4C, 0x58, 0x32, 0x7A, 0x57, 0x74, 0x45, 0x74, 0x65, 0x66, 0x64, 0x69, 0x2B, 0x7A, 0x71, 0x4A, 0x62, 0x51, 0x41, 0x49, 0x6C, 0x64, 0x4E, 0x73, 0x4C, 0x47, 0x79, 0x4D, ++ 0x63, 0x45, 0x57, 0x7A, 0x76, 0x2F, 0x39, 0x0A, 0x46, 0x49, 0x53, 0x33, 0x52, 0x2F, 0x71, 0x79, 0x38, 0x58, 0x44, 0x65, 0x32, 0x34, 0x74, 0x73, 0x4E, 0x6C, 0x69, 0x6B, 0x66, 0x4C, 0x4D, 0x52, 0x30, 0x63, 0x4E, 0x33, 0x66, 0x31, 0x2B, 0x32, ++ 0x4A, 0x65, 0x41, 0x4E, 0x78, 0x64, 0x4B, 0x7A, 0x2B, 0x62, 0x69, 0x34, 0x64, 0x39, 0x73, 0x33, 0x63, 0x58, 0x46, 0x48, 0x34, 0x32, 0x41, 0x59, 0x54, 0x79, 0x53, 0x32, 0x64, 0x54, 0x64, 0x34, 0x75, 0x61, 0x4E, 0x69, 0x72, 0x37, 0x33, 0x4A, ++ 0x63, 0x6F, 0x34, 0x76, 0x0A, 0x7A, 0x4C, 0x75, 0x75, 0x32, 0x2B, 0x51, 0x56, 0x55, 0x68, 0x6B, 0x48, 0x4D, 0x2F, 0x74, 0x71, 0x74, 0x79, 0x31, 0x4C, 0x6B, 0x43, 0x69, 0x43, 0x63, 0x2F, 0x34, 0x59, 0x69, 0x7A, 0x57, 0x4E, 0x32, 0x36, 0x63, ++ 0x45, 0x61, 0x72, 0x37, 0x71, 0x77, 0x55, 0x30, 0x32, 0x4F, 0x78, 0x59, 0x32, 0x6B, 0x54, 0x4C, 0x76, 0x74, 0x6B, 0x43, 0x4A, 0x6B, 0x55, 0x50, 0x67, 0x38, 0x71, 0x4B, 0x72, 0x42, 0x43, 0x37, 0x6D, 0x38, 0x6B, 0x77, 0x4F, 0x46, 0x6A, 0x51, ++ 0x67, 0x0A, 0x72, 0x49, 0x66, 0x42, 0x4C, 0x58, 0x37, 0x4A, 0x5A, 0x6B, 0x63, 0x58, 0x46, 0x42, 0x47, 0x6B, 0x38, 0x2F, 0x65, 0x68, 0x4A, 0x49, 0x6D, 0x72, 0x32, 0x42, 0x72, 0x49, 0x6F, 0x56, 0x79, 0x78, 0x6F, 0x2F, 0x65, 0x4D, 0x62, 0x63, ++ 0x67, 0x42, 0x79, 0x55, 0x2F, 0x4A, 0x37, 0x4D, 0x54, 0x38, 0x72, 0x46, 0x45, 0x7A, 0x30, 0x63, 0x69, 0x44, 0x30, 0x63, 0x6D, 0x66, 0x48, 0x64, 0x52, 0x48, 0x4E, 0x43, 0x6B, 0x2B, 0x79, 0x37, 0x41, 0x4F, 0x2B, 0x6F, 0x4D, 0x4C, 0x0A, 0x4B, ++ 0x46, 0x6A, 0x6C, 0x4B, 0x64, 0x77, 0x2F, 0x66, 0x4B, 0x69, 0x66, 0x79, 0x62, 0x59, 0x4B, 0x75, 0x36, 0x62, 0x6F, 0x52, 0x68, 0x59, 0x50, 0x6C, 0x75, 0x56, 0x37, 0x35, 0x47, 0x70, 0x36, 0x53, 0x47, 0x31, 0x32, 0x6D, 0x41, 0x57, 0x6C, 0x33, ++ 0x47, 0x30, 0x65, 0x51, 0x68, 0x35, 0x43, 0x32, 0x68, 0x72, 0x67, 0x55, 0x76, 0x65, 0x31, 0x67, 0x38, 0x41, 0x61, 0x65, 0x33, 0x67, 0x31, 0x4C, 0x44, 0x6A, 0x31, 0x48, 0x2F, 0x31, 0x4A, 0x6F, 0x79, 0x37, 0x53, 0x0A, 0x57, 0x57, 0x4F, 0x2F, ++ 0x67, 0x4C, 0x43, 0x4D, 0x6B, 0x33, 0x50, 0x4C, 0x4E, 0x61, 0x61, 0x5A, 0x6C, 0x53, 0x4A, 0x68, 0x5A, 0x51, 0x4E, 0x67, 0x2B, 0x79, 0x2B, 0x54, 0x53, 0x2F, 0x71, 0x61, 0x6E, 0x49, 0x41, 0x37, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, ++ 0x59, 0x7A, 0x42, 0x68, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x0A, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, ++ 0x55, 0x74, 0x71, 0x65, 0x58, 0x67, 0x6A, 0x31, 0x30, 0x68, 0x5A, 0x76, 0x33, 0x50, 0x4A, 0x2B, 0x54, 0x6D, 0x70, 0x56, 0x35, 0x64, 0x56, 0x4B, 0x4D, 0x62, 0x55, 0x63, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, ++ 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x66, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x53, 0x4D, 0x45, 0x47, 0x44, 0x41, 0x57, 0x67, 0x42, 0x53, 0x32, 0x0A, 0x70, 0x35, 0x65, 0x43, 0x50, 0x58, 0x53, 0x46, 0x6D, 0x2F, ++ 0x63, 0x38, 0x6E, 0x35, 0x4F, 0x61, 0x6C, 0x58, 0x6C, 0x31, 0x55, 0x6F, 0x78, 0x74, 0x52, 0x7A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x77, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x67, ++ 0x45, 0x41, 0x71, 0x4D, 0x78, 0x68, 0x70, 0x72, 0x35, 0x31, 0x6E, 0x68, 0x56, 0x51, 0x70, 0x47, 0x76, 0x37, 0x71, 0x48, 0x42, 0x46, 0x66, 0x4C, 0x70, 0x2B, 0x0A, 0x73, 0x56, 0x72, 0x38, 0x57, 0x79, 0x50, 0x36, 0x43, 0x6E, 0x66, 0x34, 0x6D, ++ 0x48, 0x47, 0x43, 0x44, 0x47, 0x33, 0x67, 0x58, 0x6B, 0x61, 0x71, 0x6B, 0x2F, 0x51, 0x65, 0x6F, 0x4D, 0x50, 0x68, 0x6B, 0x39, 0x74, 0x4C, 0x72, 0x62, 0x4B, 0x6D, 0x58, 0x61, 0x75, 0x77, 0x31, 0x47, 0x4C, 0x4C, 0x58, 0x72, 0x74, 0x6D, 0x39, ++ 0x53, 0x33, 0x75, 0x6C, 0x30, 0x41, 0x38, 0x59, 0x75, 0x74, 0x65, 0x31, 0x68, 0x54, 0x57, 0x6A, 0x4F, 0x4B, 0x57, 0x69, 0x30, 0x46, 0x70, 0x0A, 0x6B, 0x7A, 0x58, 0x6D, 0x75, 0x5A, 0x6C, 0x72, 0x59, 0x72, 0x53, 0x68, 0x46, 0x32, 0x59, 0x30, ++ 0x70, 0x6D, 0x74, 0x6A, 0x78, 0x72, 0x6C, 0x4F, 0x38, 0x69, 0x4C, 0x70, 0x57, 0x41, 0x31, 0x57, 0x51, 0x64, 0x48, 0x36, 0x44, 0x45, 0x72, 0x77, 0x4D, 0x38, 0x30, 0x37, 0x75, 0x32, 0x30, 0x68, 0x4F, 0x71, 0x36, 0x4F, 0x63, 0x72, 0x58, 0x44, ++ 0x53, 0x76, 0x76, 0x70, 0x66, 0x65, 0x57, 0x78, 0x6D, 0x34, 0x62, 0x75, 0x34, 0x75, 0x42, 0x39, 0x74, 0x50, 0x63, 0x79, 0x0A, 0x2F, 0x53, 0x4B, 0x45, 0x38, 0x59, 0x58, 0x4A, 0x4E, 0x33, 0x6E, 0x70, 0x74, 0x54, 0x2B, 0x2F, 0x58, 0x4F, 0x52, ++ 0x30, 0x73, 0x6F, 0x38, 0x52, 0x59, 0x67, 0x44, 0x64, 0x47, 0x47, 0x61, 0x68, 0x32, 0x58, 0x73, 0x6A, 0x58, 0x2F, 0x47, 0x4F, 0x31, 0x57, 0x66, 0x6F, 0x56, 0x4E, 0x70, 0x62, 0x4F, 0x6D, 0x73, 0x32, 0x62, 0x2F, 0x6D, 0x42, 0x73, 0x54, 0x4E, ++ 0x48, 0x4D, 0x33, 0x64, 0x41, 0x2B, 0x56, 0x4B, 0x71, 0x33, 0x64, 0x53, 0x44, 0x7A, 0x34, 0x56, 0x34, 0x0A, 0x6D, 0x5A, 0x71, 0x54, 0x75, 0x58, 0x4E, 0x6E, 0x51, 0x6B, 0x59, 0x52, 0x49, 0x65, 0x72, 0x2B, 0x43, 0x71, 0x6B, 0x62, 0x47, 0x6D, ++ 0x56, 0x70, 0x73, 0x34, 0x2B, 0x75, 0x46, 0x72, 0x62, 0x32, 0x53, 0x31, 0x61, 0x79, 0x4C, 0x66, 0x6D, 0x6C, 0x79, 0x4F, 0x77, 0x37, 0x59, 0x71, 0x50, 0x74, 0x61, 0x39, 0x42, 0x4F, 0x31, 0x55, 0x41, 0x4A, 0x70, 0x42, 0x2B, 0x59, 0x31, 0x7A, ++ 0x71, 0x6C, 0x6B, 0x6C, 0x6B, 0x67, 0x35, 0x4C, 0x42, 0x39, 0x7A, 0x56, 0x74, 0x7A, 0x0A, 0x61, 0x4C, 0x31, 0x74, 0x78, 0x4B, 0x49, 0x54, 0x44, 0x6D, 0x63, 0x5A, 0x75, 0x49, 0x31, 0x43, 0x66, 0x6D, 0x77, 0x4D, 0x6D, 0x6D, 0x36, 0x67, 0x4A, ++ 0x43, 0x33, 0x56, 0x52, 0x52, 0x76, 0x63, 0x78, 0x41, 0x49, 0x55, 0x2F, 0x6F, 0x56, 0x62, 0x5A, 0x5A, 0x66, 0x4B, 0x54, 0x70, 0x42, 0x51, 0x43, 0x48, 0x70, 0x43, 0x4E, 0x66, 0x6E, 0x71, 0x77, 0x6D, 0x62, 0x55, 0x2B, 0x41, 0x47, 0x75, 0x48, ++ 0x72, 0x53, 0x2B, 0x77, 0x36, 0x6A, 0x76, 0x2F, 0x6E, 0x61, 0x61, 0x0A, 0x6F, 0x71, 0x59, 0x66, 0x52, 0x76, 0x61, 0x45, 0x37, 0x66, 0x7A, 0x62, 0x7A, 0x73, 0x51, 0x43, 0x7A, 0x6E, 0x64, 0x49, 0x4C, 0x49, 0x79, 0x79, 0x37, 0x4D, 0x4D, 0x41, ++ 0x6F, 0x2B, 0x77, 0x73, 0x56, 0x52, 0x6A, 0x42, 0x66, 0x68, 0x6E, 0x75, 0x34, 0x53, 0x2F, 0x79, 0x72, 0x59, 0x4F, 0x62, 0x6E, 0x71, 0x73, 0x5A, 0x33, 0x38, 0x61, 0x4B, 0x4C, 0x34, 0x78, 0x33, 0x35, 0x62, 0x63, 0x46, 0x37, 0x44, 0x76, 0x42, ++ 0x37, 0x4C, 0x36, 0x47, 0x73, 0x34, 0x61, 0x38, 0x0A, 0x77, 0x50, 0x66, 0x63, 0x35, 0x2B, 0x70, 0x62, 0x72, 0x72, 0x4C, 0x4D, 0x74, 0x54, 0x57, 0x47, 0x53, 0x39, 0x44, 0x69, 0x50, 0x37, 0x62, 0x59, 0x2B, 0x41, 0x34, 0x41, 0x37, 0x6C, 0x33, ++ 0x6A, 0x39, 0x34, 0x31, 0x59, 0x2F, 0x38, 0x2B, 0x4C, 0x4E, 0x2B, 0x6C, 0x6A, 0x58, 0x32, 0x37, 0x33, 0x43, 0x58, 0x45, 0x32, 0x77, 0x68, 0x4A, 0x64, 0x56, 0x2F, 0x4C, 0x49, 0x74, 0x4D, 0x33, 0x7A, 0x37, 0x67, 0x4C, 0x66, 0x45, 0x64, 0x78, ++ 0x71, 0x75, 0x56, 0x65, 0x45, 0x0A, 0x48, 0x56, 0x6C, 0x4E, 0x6A, 0x4D, 0x37, 0x49, 0x44, 0x69, 0x50, 0x43, 0x74, 0x79, 0x61, 0x61, 0x45, 0x42, 0x52, 0x78, 0x2F, 0x70, 0x4F, 0x79, 0x69, 0x72, 0x69, 0x41, 0x38, 0x41, 0x34, 0x51, 0x6E, 0x74, ++ 0x4F, 0x6F, 0x55, 0x41, 0x77, 0x33, 0x67, 0x69, 0x2F, 0x71, 0x34, 0x49, 0x71, 0x64, 0x34, 0x53, 0x77, 0x35, 0x2F, 0x37, 0x57, 0x30, 0x63, 0x77, 0x44, 0x6B, 0x39, 0x30, 0x69, 0x6D, 0x63, 0x36, 0x79, 0x2F, 0x73, 0x74, 0x35, 0x33, 0x42, 0x49, ++ 0x65, 0x30, 0x0A, 0x6F, 0x38, 0x32, 0x62, 0x4E, 0x53, 0x51, 0x33, 0x2B, 0x70, 0x43, 0x54, 0x45, 0x34, 0x46, 0x43, 0x78, 0x70, 0x67, 0x6D, 0x64, 0x54, 0x64, 0x6D, 0x51, 0x52, 0x43, 0x73, 0x75, 0x2F, 0x57, 0x55, 0x34, 0x38, 0x49, 0x78, 0x4B, ++ 0x36, 0x33, 0x6E, 0x49, 0x31, 0x62, 0x4D, 0x4E, 0x53, 0x57, 0x53, 0x73, 0x31, 0x41, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x2D, 0x0A, 0x0A, 0x46, 0x49, 0x52, 0x4D, 0x41, 0x50, 0x52, 0x4F, 0x46, 0x45, 0x53, 0x49, 0x4F, 0x4E, 0x41, 0x4C, 0x20, 0x43, 0x41, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x2D, 0x41, 0x20, 0x57, 0x45, 0x42, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, ++ 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x65, 0x6A, 0x43, 0x43, 0x41, 0x67, 0x43, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x4D, 0x5A, 0x63, 0x68, 0x37, 0x61, 0x2B, ++ 0x4A, 0x51, 0x6E, 0x38, 0x31, 0x51, 0x59, 0x65, 0x68, 0x5A, 0x31, 0x5A, 0x4D, 0x62, 0x54, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x7A, 0x42, 0x75, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, ++ 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x46, 0x0A, 0x55, 0x7A, 0x45, 0x63, 0x4D, 0x42, 0x6F, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x54, 0x52, 0x6D, 0x6C, 0x79, 0x62, 0x57, 0x46, 0x77, 0x63, 0x6D, 0x39, 0x6D, 0x5A, 0x58, ++ 0x4E, 0x70, 0x62, 0x32, 0x35, 0x68, 0x62, 0x43, 0x42, 0x54, 0x51, 0x54, 0x45, 0x59, 0x4D, 0x42, 0x59, 0x47, 0x41, 0x31, 0x55, 0x45, 0x59, 0x51, 0x77, 0x50, 0x56, 0x6B, 0x46, 0x55, 0x52, 0x56, 0x4D, 0x74, 0x51, 0x54, 0x59, 0x79, 0x4E, 0x6A, ++ 0x4D, 0x30, 0x4D, 0x44, 0x59, 0x34, 0x0A, 0x4D, 0x53, 0x63, 0x77, 0x4A, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x42, 0x35, 0x47, 0x53, 0x56, 0x4A, 0x4E, 0x51, 0x56, 0x42, 0x53, 0x54, 0x30, 0x5A, 0x46, 0x55, 0x30, 0x6C, 0x50, 0x54, ++ 0x6B, 0x46, 0x4D, 0x49, 0x45, 0x4E, 0x42, 0x49, 0x46, 0x4A, 0x50, 0x54, 0x31, 0x51, 0x74, 0x51, 0x53, 0x42, 0x58, 0x52, 0x55, 0x49, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x6A, 0x49, 0x77, 0x4E, 0x44, 0x41, 0x32, 0x4D, 0x44, 0x6B, 0x77, 0x4D, ++ 0x54, 0x4D, 0x32, 0x0A, 0x57, 0x68, 0x63, 0x4E, 0x4E, 0x44, 0x63, 0x77, 0x4D, 0x7A, 0x4D, 0x78, 0x4D, 0x44, 0x6B, 0x77, 0x4D, 0x54, 0x4D, 0x32, 0x57, 0x6A, 0x42, 0x75, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, ++ 0x45, 0x77, 0x4A, 0x46, 0x55, 0x7A, 0x45, 0x63, 0x4D, 0x42, 0x6F, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x54, 0x52, 0x6D, 0x6C, 0x79, 0x62, 0x57, 0x46, 0x77, 0x63, 0x6D, 0x39, 0x6D, 0x5A, 0x58, 0x4E, 0x70, 0x62, 0x32, 0x35, 0x68, ++ 0x0A, 0x62, 0x43, 0x42, 0x54, 0x51, 0x54, 0x45, 0x59, 0x4D, 0x42, 0x59, 0x47, 0x41, 0x31, 0x55, 0x45, 0x59, 0x51, 0x77, 0x50, 0x56, 0x6B, 0x46, 0x55, 0x52, 0x56, 0x4D, 0x74, 0x51, 0x54, 0x59, 0x79, 0x4E, 0x6A, 0x4D, 0x30, 0x4D, 0x44, 0x59, ++ 0x34, 0x4D, 0x53, 0x63, 0x77, 0x4A, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x42, 0x35, 0x47, 0x53, 0x56, 0x4A, 0x4E, 0x51, 0x56, 0x42, 0x53, 0x54, 0x30, 0x5A, 0x46, 0x55, 0x30, 0x6C, 0x50, 0x54, 0x6B, 0x46, 0x4D, 0x0A, 0x49, 0x45, ++ 0x4E, 0x42, 0x49, 0x46, 0x4A, 0x50, 0x54, 0x31, 0x51, 0x74, 0x51, 0x53, 0x42, 0x58, 0x52, 0x55, 0x49, 0x77, 0x64, 0x6A, 0x41, 0x51, 0x42, 0x67, 0x63, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x49, 0x42, 0x42, 0x67, 0x55, 0x72, 0x67, 0x51, ++ 0x51, 0x41, 0x49, 0x67, 0x4E, 0x69, 0x41, 0x41, 0x52, 0x48, 0x55, 0x2B, 0x6F, 0x73, 0x45, 0x61, 0x52, 0x33, 0x78, 0x79, 0x72, 0x71, 0x38, 0x39, 0x5A, 0x66, 0x65, 0x39, 0x4D, 0x45, 0x6B, 0x56, 0x7A, 0x36, 0x0A, 0x69, 0x4D, 0x59, 0x69, 0x75, ++ 0x59, 0x4D, 0x51, 0x59, 0x6E, 0x65, 0x45, 0x4D, 0x79, 0x33, 0x70, 0x41, 0x34, 0x6A, 0x55, 0x34, 0x44, 0x50, 0x33, 0x37, 0x58, 0x63, 0x73, 0x53, 0x6D, 0x44, 0x71, 0x35, 0x47, 0x2B, 0x74, 0x62, 0x62, 0x54, 0x34, 0x54, 0x49, 0x71, 0x6B, 0x35, ++ 0x42, 0x2F, 0x4B, 0x36, 0x6B, 0x38, 0x34, 0x53, 0x69, 0x36, 0x43, 0x63, 0x79, 0x76, 0x48, 0x5A, 0x70, 0x73, 0x4B, 0x6A, 0x45, 0x43, 0x63, 0x66, 0x49, 0x72, 0x32, 0x38, 0x6A, 0x6C, 0x67, 0x0A, 0x73, 0x74, 0x37, 0x4C, 0x37, 0x4C, 0x6A, 0x6B, ++ 0x62, 0x2B, 0x71, 0x62, 0x58, 0x62, 0x64, 0x54, 0x6B, 0x42, 0x67, 0x79, 0x56, 0x63, 0x55, 0x67, 0x74, 0x35, 0x53, 0x6A, 0x59, 0x7A, 0x42, 0x68, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, ++ 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x48, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x6A, 0x42, 0x42, 0x67, 0x77, 0x46, 0x6F, 0x41, 0x55, 0x6B, 0x2B, 0x46, 0x44, 0x0A, 0x59, 0x31, 0x77, 0x38, 0x6E, 0x64, 0x59, 0x6E, 0x38, 0x31, 0x4C, ++ 0x73, 0x46, 0x37, 0x4B, 0x70, 0x72, 0x79, 0x7A, 0x33, 0x64, 0x76, 0x67, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x46, 0x4A, 0x50, 0x68, 0x51, 0x32, 0x4E, 0x63, 0x50, 0x4A, 0x33, 0x57, 0x4A, 0x2F, 0x4E, ++ 0x53, 0x37, 0x42, 0x65, 0x79, 0x71, 0x61, 0x38, 0x73, 0x39, 0x33, 0x62, 0x34, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x0A, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6A, 0x41, 0x4B, 0x42, 0x67, ++ 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x77, 0x4E, 0x6F, 0x41, 0x44, 0x42, 0x6C, 0x41, 0x6A, 0x41, 0x64, 0x66, 0x4B, 0x52, 0x37, 0x77, 0x34, 0x6C, 0x31, 0x4D, 0x2B, 0x45, 0x37, 0x71, 0x55, 0x57, 0x2F, 0x52, 0x75, ++ 0x6E, 0x70, 0x6F, 0x64, 0x33, 0x4A, 0x49, 0x68, 0x61, 0x33, 0x52, 0x78, 0x45, 0x4C, 0x32, 0x4A, 0x71, 0x36, 0x38, 0x63, 0x67, 0x4C, 0x0A, 0x63, 0x46, 0x42, 0x54, 0x41, 0x70, 0x46, 0x77, 0x68, 0x56, 0x6D, 0x70, 0x48, 0x71, 0x54, 0x6D, 0x36, ++ 0x69, 0x4D, 0x78, 0x6F, 0x41, 0x41, 0x43, 0x4D, 0x51, 0x44, 0x39, 0x34, 0x76, 0x69, 0x7A, 0x72, 0x78, 0x61, 0x35, 0x48, 0x6E, 0x50, 0x45, 0x6C, 0x75, 0x50, 0x42, 0x4D, 0x42, 0x6E, 0x59, 0x66, 0x75, 0x62, 0x44, 0x6C, 0x39, 0x34, 0x63, 0x54, ++ 0x37, 0x69, 0x4A, 0x4C, 0x7A, 0x50, 0x72, 0x53, 0x41, 0x38, 0x5A, 0x39, 0x34, 0x64, 0x47, 0x58, 0x53, 0x61, 0x51, 0x0A, 0x70, 0x59, 0x58, 0x46, 0x75, 0x58, 0x71, 0x55, 0x50, 0x6F, 0x65, 0x6F, 0x76, 0x51, 0x41, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, ++ 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x54, 0x57, 0x43, 0x41, 0x20, 0x43, 0x59, 0x42, 0x45, 0x52, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, ++ 0x43, 0x41, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, ++ 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x6A, 0x54, 0x43, 0x43, 0x41, 0x33, 0x57, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x51, 0x41, 0x45, 0x30, 0x6A, 0x4D, 0x49, 0x41, 0x41, 0x41, ++ 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x54, 0x7A, 0x79, 0x78, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x77, 0x46, 0x41, 0x44, 0x42, 0x51, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, ++ 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0A, 0x45, 0x77, 0x4A, 0x55, 0x56, 0x7A, 0x45, 0x53, 0x4D, 0x42, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x4A, 0x56, 0x45, 0x46, 0x4A, 0x56, 0x30, 0x46, 0x4F, 0x4C, 0x55, 0x4E, 0x42, 0x4D, ++ 0x52, 0x41, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4C, 0x45, 0x77, 0x64, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x4D, 0x52, 0x73, 0x77, 0x47, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x4A, 0x55, 0x56, ++ 0x30, 0x4E, 0x42, 0x0A, 0x49, 0x45, 0x4E, 0x5A, 0x51, 0x6B, 0x56, 0x53, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x6A, 0x49, 0x78, 0x4D, 0x54, 0x49, 0x79, 0x4D, 0x44, 0x59, 0x31, ++ 0x4E, 0x44, 0x49, 0x35, 0x57, 0x68, 0x63, 0x4E, 0x4E, 0x44, 0x63, 0x78, 0x4D, 0x54, 0x49, 0x79, 0x4D, 0x54, 0x55, 0x31, 0x4F, 0x54, 0x55, 0x35, 0x57, 0x6A, 0x42, 0x51, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, ++ 0x0A, 0x45, 0x77, 0x4A, 0x55, 0x56, 0x7A, 0x45, 0x53, 0x4D, 0x42, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x4A, 0x56, 0x45, 0x46, 0x4A, 0x56, 0x30, 0x46, 0x4F, 0x4C, 0x55, 0x4E, 0x42, 0x4D, 0x52, 0x41, 0x77, 0x44, 0x67, 0x59, ++ 0x44, 0x56, 0x51, 0x51, 0x4C, 0x45, 0x77, 0x64, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x4D, 0x52, 0x73, 0x77, 0x47, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x4A, 0x55, 0x56, 0x30, 0x4E, 0x42, 0x0A, 0x49, 0x45, ++ 0x4E, 0x5A, 0x51, 0x6B, 0x56, 0x53, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x77, 0x67, 0x67, 0x49, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, ++ 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x44, 0x47, 0x2B, 0x4D, 0x6F, 0x65, 0x32, 0x51, 0x6B, 0x67, 0x66, 0x68, 0x31, 0x73, 0x0A, 0x54, 0x73, 0x36, 0x50, 0x34, ++ 0x30, 0x63, 0x7A, 0x52, 0x4A, 0x7A, 0x48, 0x79, 0x57, 0x6D, 0x71, 0x4F, 0x6C, 0x74, 0x34, 0x37, 0x6E, 0x44, 0x53, 0x6B, 0x76, 0x67, 0x45, 0x73, 0x31, 0x4A, 0x53, 0x48, 0x57, 0x64, 0x79, 0x4B, 0x4B, 0x48, 0x66, 0x69, 0x31, 0x32, 0x56, 0x43, ++ 0x76, 0x37, 0x71, 0x7A, 0x65, 0x33, 0x33, 0x4B, 0x63, 0x37, 0x77, 0x62, 0x33, 0x2B, 0x73, 0x7A, 0x54, 0x33, 0x76, 0x73, 0x78, 0x78, 0x46, 0x61, 0x76, 0x63, 0x6F, 0x6B, 0x50, 0x46, 0x68, 0x0A, 0x56, 0x38, 0x55, 0x4D, 0x78, 0x4B, 0x4E, 0x51, ++ 0x58, 0x64, 0x37, 0x55, 0x74, 0x63, 0x73, 0x5A, 0x79, 0x6F, 0x43, 0x35, 0x64, 0x63, 0x34, 0x70, 0x7A, 0x74, 0x4B, 0x46, 0x49, 0x75, 0x77, 0x43, 0x59, 0x38, 0x78, 0x45, 0x4D, 0x43, 0x44, 0x61, 0x36, 0x70, 0x46, 0x62, 0x56, 0x75, 0x59, 0x64, ++ 0x48, 0x4E, 0x57, 0x64, 0x5A, 0x73, 0x63, 0x2F, 0x33, 0x34, 0x62, 0x4B, 0x53, 0x31, 0x50, 0x45, 0x32, 0x59, 0x32, 0x79, 0x48, 0x65, 0x72, 0x34, 0x33, 0x43, 0x64, 0x54, 0x0A, 0x6F, 0x30, 0x66, 0x68, 0x59, 0x63, 0x78, 0x39, 0x74, 0x62, 0x44, ++ 0x34, 0x37, 0x6E, 0x4F, 0x52, 0x78, 0x63, 0x35, 0x7A, 0x62, 0x38, 0x37, 0x75, 0x45, 0x42, 0x38, 0x61, 0x42, 0x73, 0x2F, 0x70, 0x4A, 0x32, 0x44, 0x46, 0x54, 0x78, 0x6E, 0x6B, 0x36, 0x38, 0x34, 0x69, 0x4A, 0x6B, 0x58, 0x58, 0x59, 0x4A, 0x6E, ++ 0x64, 0x7A, 0x6B, 0x38, 0x33, 0x34, 0x48, 0x2F, 0x6E, 0x59, 0x36, 0x32, 0x77, 0x75, 0x46, 0x6D, 0x34, 0x30, 0x41, 0x5A, 0x6F, 0x4E, 0x57, 0x44, 0x54, 0x0A, 0x4E, 0x71, 0x35, 0x78, 0x51, 0x77, 0x54, 0x78, 0x61, 0x57, 0x56, 0x34, 0x66, 0x50, ++ 0x4D, 0x66, 0x38, 0x38, 0x6F, 0x6F, 0x6E, 0x31, 0x6F, 0x67, 0x6C, 0x57, 0x61, 0x30, 0x7A, 0x62, 0x66, 0x75, 0x6A, 0x33, 0x69, 0x6B, 0x52, 0x52, 0x6A, 0x70, 0x4A, 0x69, 0x2B, 0x4E, 0x6D, 0x79, 0x6B, 0x6F, 0x73, 0x61, 0x53, 0x33, 0x4F, 0x6D, ++ 0x32, 0x35, 0x31, 0x42, 0x77, 0x34, 0x63, 0x6B, 0x56, 0x59, 0x73, 0x56, 0x37, 0x72, 0x38, 0x43, 0x69, 0x62, 0x74, 0x34, 0x4C, 0x4B, 0x0A, 0x2F, 0x63, 0x2F, 0x57, 0x4D, 0x77, 0x2B, 0x66, 0x2B, 0x35, 0x65, 0x65, 0x73, 0x52, 0x79, 0x63, 0x6E, ++ 0x75, 0x70, 0x66, 0x58, 0x74, 0x75, 0x71, 0x33, 0x56, 0x54, 0x70, 0x4D, 0x43, 0x45, 0x6F, 0x62, 0x59, 0x35, 0x35, 0x38, 0x33, 0x57, 0x53, 0x6A, 0x43, 0x62, 0x2B, 0x33, 0x4D, 0x58, 0x32, 0x77, 0x37, 0x44, 0x66, 0x52, 0x46, 0x6C, 0x44, 0x6F, ++ 0x37, 0x59, 0x44, 0x4B, 0x50, 0x59, 0x49, 0x4D, 0x4B, 0x6F, 0x4E, 0x4D, 0x2B, 0x48, 0x76, 0x6E, 0x4B, 0x6B, 0x48, 0x0A, 0x49, 0x75, 0x4E, 0x5A, 0x57, 0x30, 0x43, 0x50, 0x32, 0x6F, 0x69, 0x33, 0x61, 0x51, 0x69, 0x6F, 0x74, 0x79, 0x4D, 0x75, ++ 0x52, 0x41, 0x6C, 0x5A, 0x4E, 0x31, 0x76, 0x48, 0x34, 0x78, 0x66, 0x79, 0x49, 0x75, 0x74, 0x75, 0x4F, 0x56, 0x4C, 0x46, 0x33, 0x6C, 0x53, 0x6E, 0x6D, 0x4D, 0x6C, 0x4C, 0x49, 0x4A, 0x58, 0x63, 0x52, 0x6F, 0x6C, 0x66, 0x74, 0x42, 0x4C, 0x35, ++ 0x68, 0x53, 0x6D, 0x4F, 0x36, 0x38, 0x67, 0x6E, 0x46, 0x53, 0x44, 0x41, 0x53, 0x39, 0x54, 0x4D, 0x0A, 0x66, 0x41, 0x78, 0x73, 0x4E, 0x41, 0x77, 0x6D, 0x6D, 0x79, 0x59, 0x78, 0x70, 0x6A, 0x79, 0x6E, 0x39, 0x74, 0x6E, 0x51, 0x53, 0x36, 0x4A, ++ 0x6B, 0x2F, 0x7A, 0x75, 0x5A, 0x51, 0x58, 0x4C, 0x42, 0x34, 0x48, 0x43, 0x58, 0x38, 0x53, 0x53, 0x37, 0x4B, 0x38, 0x52, 0x30, 0x49, 0x72, 0x47, 0x73, 0x61, 0x79, 0x49, 0x79, 0x4A, 0x4E, 0x4E, 0x34, 0x4B, 0x73, 0x44, 0x41, 0x6F, 0x53, 0x2F, ++ 0x78, 0x55, 0x67, 0x58, 0x4A, 0x50, 0x2B, 0x39, 0x32, 0x5A, 0x75, 0x4A, 0x46, 0x0A, 0x32, 0x41, 0x30, 0x39, 0x72, 0x5A, 0x58, 0x49, 0x78, 0x34, 0x6B, 0x6D, 0x79, 0x41, 0x2B, 0x75, 0x70, 0x77, 0x4D, 0x75, 0x2B, 0x38, 0x46, 0x66, 0x2B, 0x69, ++ 0x44, 0x68, 0x63, 0x4B, 0x32, 0x77, 0x5A, 0x53, 0x41, 0x33, 0x4D, 0x32, 0x43, 0x77, 0x31, 0x61, 0x2F, 0x58, 0x44, 0x42, 0x7A, 0x43, 0x6B, 0x48, 0x44, 0x58, 0x53, 0x68, 0x69, 0x38, 0x66, 0x67, 0x47, 0x77, 0x73, 0x4F, 0x73, 0x56, 0x48, 0x6B, ++ 0x51, 0x47, 0x7A, 0x61, 0x52, 0x50, 0x36, 0x41, 0x7A, 0x52, 0x0A, 0x77, 0x79, 0x41, 0x51, 0x34, 0x56, 0x52, 0x6C, 0x6E, 0x72, 0x5A, 0x52, 0x30, 0x42, 0x70, 0x32, 0x61, 0x30, 0x4A, 0x61, 0x57, 0x48, 0x59, 0x30, 0x36, 0x72, 0x63, 0x33, 0x47, ++ 0x61, 0x34, 0x75, 0x64, 0x66, 0x6D, 0x57, 0x35, 0x63, 0x46, 0x5A, 0x39, 0x35, 0x52, 0x58, 0x4B, 0x53, 0x57, 0x4E, 0x4F, 0x6B, 0x79, 0x72, 0x54, 0x5A, 0x70, 0x42, 0x30, 0x46, 0x38, 0x6D, 0x41, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6F, ++ 0x32, 0x4D, 0x77, 0x59, 0x54, 0x41, 0x4F, 0x0A, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4D, 0x43, 0x41, 0x51, 0x59, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, ++ 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, 0x41, 0x66, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x53, 0x4D, 0x45, 0x47, 0x44, 0x41, 0x57, 0x67, 0x42, 0x53, 0x64, 0x68, 0x57, 0x45, 0x55, 0x66, 0x4D, 0x46, 0x69, 0x62, 0x35, 0x64, 0x6F, ++ 0x35, 0x45, 0x38, 0x33, 0x0A, 0x51, 0x4F, 0x47, 0x74, 0x34, 0x41, 0x31, 0x57, 0x4E, 0x7A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x6E, 0x59, 0x56, 0x68, 0x46, 0x48, 0x7A, 0x42, 0x59, 0x6D, 0x2B, ++ 0x58, 0x61, 0x4F, 0x52, 0x50, 0x4E, 0x30, 0x44, 0x68, 0x72, 0x65, 0x41, 0x4E, 0x56, 0x6A, 0x63, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4D, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, ++ 0x42, 0x0A, 0x41, 0x47, 0x53, 0x50, 0x65, 0x73, 0x52, 0x69, 0x44, 0x72, 0x57, 0x49, 0x7A, 0x4C, 0x6A, 0x48, 0x68, 0x67, 0x36, 0x68, 0x53, 0x68, 0x62, 0x4E, 0x63, 0x41, 0x75, 0x33, 0x70, 0x34, 0x55, 0x4C, 0x73, 0x33, 0x61, 0x32, 0x44, 0x36, ++ 0x66, 0x2F, 0x43, 0x49, 0x73, 0x4C, 0x4A, 0x63, 0x2B, 0x6F, 0x31, 0x49, 0x4E, 0x31, 0x4B, 0x72, 0x69, 0x57, 0x69, 0x4C, 0x62, 0x37, 0x33, 0x79, 0x30, 0x74, 0x74, 0x47, 0x6C, 0x54, 0x49, 0x54, 0x56, 0x58, 0x31, 0x6F, 0x6C, 0x4E, 0x0A, 0x63, ++ 0x37, 0x39, 0x70, 0x6A, 0x33, 0x43, 0x6A, 0x59, 0x63, 0x79, 0x61, 0x32, 0x78, 0x36, 0x61, 0x34, 0x43, 0x44, 0x34, 0x62, 0x4C, 0x75, 0x62, 0x49, 0x70, 0x31, 0x64, 0x68, 0x44, 0x47, 0x61, 0x4C, 0x49, 0x72, 0x64, 0x61, 0x71, 0x48, 0x58, 0x4B, ++ 0x47, 0x6E, 0x4B, 0x2F, 0x6E, 0x5A, 0x56, 0x65, 0x6B, 0x5A, 0x6E, 0x36, 0x38, 0x78, 0x44, 0x69, 0x42, 0x61, 0x69, 0x41, 0x39, 0x61, 0x35, 0x46, 0x2F, 0x67, 0x5A, 0x62, 0x47, 0x30, 0x6A, 0x41, 0x6E, 0x2F, 0x78, 0x0A, 0x58, 0x39, 0x41, 0x4B, ++ 0x4B, 0x53, 0x4D, 0x37, 0x30, 0x61, 0x6F, 0x4B, 0x37, 0x61, 0x6B, 0x58, 0x4A, 0x6C, 0x51, 0x4B, 0x54, 0x63, 0x4B, 0x6C, 0x54, 0x66, 0x6A, 0x46, 0x2F, 0x62, 0x69, 0x42, 0x7A, 0x79, 0x73, 0x73, 0x65, 0x4B, 0x4E, 0x6E, 0x54, 0x4B, 0x6B, 0x48, ++ 0x6D, 0x76, 0x50, 0x66, 0x58, 0x76, 0x74, 0x38, 0x39, 0x59, 0x6E, 0x4E, 0x64, 0x4A, 0x64, 0x68, 0x45, 0x47, 0x6F, 0x48, 0x4B, 0x34, 0x46, 0x61, 0x30, 0x6F, 0x36, 0x33, 0x35, 0x79, 0x44, 0x52, 0x0A, 0x49, 0x47, 0x34, 0x6B, 0x71, 0x49, 0x51, ++ 0x6E, 0x6F, 0x56, 0x65, 0x73, 0x71, 0x6C, 0x56, 0x59, 0x4C, 0x39, 0x7A, 0x5A, 0x79, 0x76, 0x70, 0x6F, 0x42, 0x4A, 0x37, 0x74, 0x52, 0x43, 0x54, 0x35, 0x64, 0x45, 0x41, 0x37, 0x49, 0x7A, 0x4F, 0x72, 0x67, 0x31, 0x6F, 0x59, 0x4A, 0x6B, 0x4B, ++ 0x32, 0x62, 0x56, 0x53, 0x31, 0x46, 0x6D, 0x41, 0x77, 0x62, 0x4C, 0x47, 0x67, 0x2B, 0x4C, 0x68, 0x42, 0x6F, 0x46, 0x31, 0x4A, 0x53, 0x64, 0x4A, 0x6C, 0x42, 0x54, 0x72, 0x71, 0x0A, 0x2F, 0x70, 0x31, 0x68, 0x76, 0x49, 0x62, 0x5A, 0x76, 0x39, ++ 0x37, 0x54, 0x75, 0x6A, 0x71, 0x78, 0x66, 0x33, 0x36, 0x53, 0x4E, 0x49, 0x37, 0x4A, 0x41, 0x47, 0x37, 0x63, 0x6D, 0x4C, 0x33, 0x63, 0x37, 0x49, 0x41, 0x46, 0x72, 0x51, 0x49, 0x39, 0x33, 0x32, 0x58, 0x74, 0x43, 0x77, 0x50, 0x33, 0x39, 0x78, ++ 0x61, 0x45, 0x42, 0x44, 0x47, 0x36, 0x6B, 0x35, 0x54, 0x59, 0x38, 0x68, 0x4C, 0x34, 0x69, 0x75, 0x4F, 0x2F, 0x51, 0x71, 0x2B, 0x6E, 0x31, 0x4D, 0x30, 0x52, 0x0A, 0x46, 0x78, 0x62, 0x49, 0x51, 0x68, 0x30, 0x55, 0x71, 0x45, 0x4C, 0x32, 0x30, ++ 0x6B, 0x43, 0x47, 0x6F, 0x45, 0x38, 0x6A, 0x79, 0x70, 0x5A, 0x46, 0x56, 0x6D, 0x41, 0x47, 0x7A, 0x62, 0x64, 0x56, 0x41, 0x61, 0x59, 0x42, 0x6C, 0x47, 0x58, 0x2B, 0x62, 0x67, 0x55, 0x4A, 0x75, 0x72, 0x53, 0x6B, 0x71, 0x75, 0x4C, 0x76, 0x57, ++ 0x4C, 0x36, 0x39, 0x4A, 0x31, 0x62, 0x59, 0x37, 0x33, 0x4E, 0x78, 0x57, 0x30, 0x51, 0x7A, 0x38, 0x70, 0x70, 0x79, 0x36, 0x72, 0x42, 0x65, 0x0A, 0x50, 0x6D, 0x36, 0x70, 0x55, 0x6C, 0x76, 0x73, 0x63, 0x47, 0x32, 0x31, 0x68, 0x34, 0x38, 0x33, ++ 0x58, 0x6A, 0x79, 0x4D, 0x6E, 0x4D, 0x37, 0x6B, 0x38, 0x4D, 0x34, 0x4D, 0x5A, 0x30, 0x48, 0x4D, 0x7A, 0x76, 0x61, 0x41, 0x71, 0x30, 0x37, 0x4D, 0x54, 0x46, 0x62, 0x31, 0x77, 0x57, 0x46, 0x5A, 0x6B, 0x37, 0x51, 0x2B, 0x70, 0x74, 0x71, 0x34, ++ 0x4E, 0x78, 0x4B, 0x66, 0x4B, 0x6A, 0x4C, 0x6A, 0x69, 0x37, 0x67, 0x68, 0x37, 0x4D, 0x4D, 0x72, 0x5A, 0x51, 0x7A, 0x76, 0x0A, 0x49, 0x74, 0x36, 0x49, 0x4B, 0x54, 0x74, 0x4D, 0x31, 0x2F, 0x72, 0x2B, 0x74, 0x2B, 0x46, 0x48, 0x76, 0x70, 0x77, ++ 0x2B, 0x50, 0x6F, 0x50, 0x37, 0x55, 0x56, 0x33, 0x31, 0x61, 0x50, 0x63, 0x75, 0x49, 0x59, 0x58, 0x63, 0x76, 0x2F, 0x46, 0x61, 0x34, 0x6E, 0x7A, 0x58, 0x78, 0x65, 0x53, 0x44, 0x77, 0x57, 0x72, 0x72, 0x75, 0x6F, 0x42, 0x61, 0x33, 0x6C, 0x77, ++ 0x74, 0x63, 0x48, 0x62, 0x34, 0x79, 0x4F, 0x57, 0x48, 0x68, 0x38, 0x71, 0x67, 0x6E, 0x61, 0x48, 0x6C, 0x0A, 0x49, 0x68, 0x49, 0x6E, 0x44, 0x30, 0x51, 0x39, 0x48, 0x57, 0x7A, 0x71, 0x31, 0x4D, 0x4B, 0x4C, 0x4C, 0x32, 0x39, 0x35, 0x71, 0x33, ++ 0x39, 0x51, 0x70, 0x73, 0x51, 0x5A, 0x70, 0x36, 0x46, 0x36, 0x74, 0x35, 0x62, 0x35, 0x77, 0x52, 0x39, 0x69, 0x57, 0x71, 0x4A, 0x44, 0x42, 0x30, 0x42, 0x65, 0x4A, 0x73, 0x61, 0x73, 0x37, 0x61, 0x35, 0x77, 0x46, 0x73, 0x57, 0x71, 0x79, 0x6E, ++ 0x4B, 0x4B, 0x54, 0x62, 0x44, 0x50, 0x41, 0x59, 0x73, 0x44, 0x50, 0x32, 0x37, 0x58, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x0A, 0x0A, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x32, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x44, 0x63, 0x6A, 0x43, 0x43, ++ 0x41, 0x6C, 0x71, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x55, 0x5A, 0x76, 0x6E, 0x48, 0x77, 0x61, 0x2F, 0x73, 0x77, 0x6C, 0x47, 0x30, 0x37, 0x56, 0x4F, 0x58, 0x35, 0x75, 0x61, 0x43, 0x77, 0x79, 0x73, 0x63, 0x6B, 0x42, 0x59, 0x77, ++ 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x77, 0x55, 0x54, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x0A, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x53, 0x6C, 0x41, ++ 0x78, 0x49, 0x7A, 0x41, 0x68, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x47, 0x6B, 0x4E, 0x35, 0x59, 0x6D, 0x56, 0x79, 0x64, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x67, 0x53, 0x6D, 0x46, 0x77, 0x59, 0x57, 0x34, 0x67, 0x51, 0x32, 0x38, ++ 0x75, 0x4C, 0x43, 0x42, 0x4D, 0x64, 0x47, 0x51, 0x75, 0x4D, 0x52, 0x30, 0x77, 0x47, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x52, 0x54, 0x0A, 0x5A, 0x57, 0x4E, 0x31, 0x63, 0x6D, 0x56, 0x54, 0x61, 0x57, 0x64, 0x75, 0x49, 0x46, ++ 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x78, 0x4D, 0x6A, 0x41, 0x65, 0x46, 0x77, 0x30, 0x79, 0x4D, 0x44, 0x41, 0x30, 0x4D, 0x44, 0x67, 0x77, 0x4E, 0x54, 0x4D, 0x32, 0x4E, 0x44, 0x5A, 0x61, 0x46, 0x77, 0x30, 0x30, 0x4D, 0x44, ++ 0x41, 0x30, 0x4D, 0x44, 0x67, 0x77, 0x4E, 0x54, 0x4D, 0x32, 0x4E, 0x44, 0x5A, 0x61, 0x4D, 0x46, 0x45, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x0A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x70, 0x51, 0x4D, 0x53, 0x4D, 0x77, 0x49, ++ 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x78, 0x70, 0x44, 0x65, 0x57, 0x4A, 0x6C, 0x63, 0x6E, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x49, 0x45, 0x70, 0x68, 0x63, 0x47, 0x46, 0x75, 0x49, 0x45, 0x4E, 0x76, 0x4C, 0x69, 0x77, 0x67, 0x54, ++ 0x48, 0x52, 0x6B, 0x4C, 0x6A, 0x45, 0x64, 0x4D, 0x42, 0x73, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x55, 0x0A, 0x55, 0x32, 0x56, 0x6A, 0x64, 0x58, 0x4A, 0x6C, 0x55, 0x32, 0x6C, 0x6E, 0x62, 0x69, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, ++ 0x49, 0x45, 0x4E, 0x42, 0x4D, 0x54, 0x49, 0x77, 0x67, 0x67, 0x45, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x44, 0x77, 0x41, 0x77, ++ 0x67, 0x67, 0x45, 0x4B, 0x41, 0x6F, 0x49, 0x42, 0x41, 0x51, 0x43, 0x36, 0x4F, 0x63, 0x45, 0x33, 0x0A, 0x65, 0x6D, 0x68, 0x46, 0x4B, 0x78, 0x53, 0x30, 0x36, 0x2B, 0x51, 0x54, 0x36, 0x31, 0x64, 0x31, 0x49, 0x30, 0x32, 0x50, 0x4A, 0x43, 0x30, ++ 0x57, 0x36, 0x4B, 0x36, 0x4F, 0x79, 0x58, 0x32, 0x6B, 0x56, 0x7A, 0x73, 0x71, 0x64, 0x69, 0x55, 0x7A, 0x67, 0x32, 0x7A, 0x71, 0x4D, 0x6F, 0x71, 0x55, 0x6D, 0x30, 0x34, 0x38, 0x6C, 0x75, 0x54, 0x39, 0x55, 0x62, 0x2B, 0x5A, 0x79, 0x5A, 0x4E, ++ 0x2B, 0x76, 0x2F, 0x6D, 0x74, 0x70, 0x37, 0x4A, 0x49, 0x4B, 0x77, 0x63, 0x63, 0x0A, 0x4A, 0x2F, 0x56, 0x4D, 0x76, 0x48, 0x41, 0x53, 0x64, 0x36, 0x53, 0x46, 0x56, 0x4C, 0x58, 0x39, 0x6B, 0x48, 0x72, 0x6B, 0x6F, 0x2B, 0x52, 0x52, 0x57, 0x41, ++ 0x50, 0x4E, 0x45, 0x48, 0x6C, 0x35, 0x37, 0x6D, 0x75, 0x54, 0x48, 0x32, 0x53, 0x4F, 0x61, 0x32, 0x53, 0x72, 0x6F, 0x78, 0x50, 0x6A, 0x63, 0x66, 0x35, 0x39, 0x71, 0x35, 0x7A, 0x64, 0x4A, 0x31, 0x4D, 0x33, 0x73, 0x36, 0x6F, 0x59, 0x77, 0x6C, ++ 0x6B, 0x6D, 0x37, 0x46, 0x73, 0x66, 0x30, 0x75, 0x5A, 0x6C, 0x0A, 0x66, 0x4F, 0x2B, 0x54, 0x76, 0x64, 0x68, 0x59, 0x58, 0x41, 0x76, 0x41, 0x34, 0x32, 0x56, 0x76, 0x50, 0x4D, 0x66, 0x4B, 0x57, 0x65, 0x50, 0x2B, 0x62, 0x6C, 0x2B, 0x73, 0x67, ++ 0x37, 0x37, 0x39, 0x58, 0x53, 0x56, 0x4F, 0x4B, 0x69, 0x6B, 0x37, 0x31, 0x67, 0x75, 0x72, 0x46, 0x7A, 0x4A, 0x34, 0x70, 0x4F, 0x45, 0x2B, 0x6C, 0x45, 0x61, 0x2B, 0x59, 0x6D, 0x36, 0x62, 0x33, 0x6B, 0x61, 0x6F, 0x73, 0x52, 0x62, 0x6E, 0x68, ++ 0x57, 0x37, 0x30, 0x43, 0x45, 0x42, 0x46, 0x0A, 0x45, 0x61, 0x43, 0x65, 0x56, 0x45, 0x53, 0x45, 0x39, 0x39, 0x67, 0x32, 0x7A, 0x76, 0x56, 0x51, 0x52, 0x39, 0x77, 0x73, 0x4D, 0x4A, 0x76, 0x75, 0x77, 0x50, 0x57, 0x57, 0x30, 0x76, 0x34, 0x4A, ++ 0x68, 0x73, 0x63, 0x47, 0x57, 0x61, 0x35, 0x50, 0x72, 0x6F, 0x34, 0x52, 0x6D, 0x48, 0x76, 0x7A, 0x43, 0x31, 0x4B, 0x71, 0x59, 0x69, 0x61, 0x71, 0x49, 0x64, 0x2B, 0x4F, 0x4A, 0x54, 0x4E, 0x35, 0x6C, 0x78, 0x5A, 0x4A, 0x6A, 0x66, 0x55, 0x2B, ++ 0x31, 0x55, 0x65, 0x66, 0x0A, 0x4E, 0x7A, 0x46, 0x4A, 0x4D, 0x33, 0x49, 0x46, 0x54, 0x51, 0x79, 0x32, 0x56, 0x59, 0x7A, 0x78, 0x56, 0x34, 0x2B, 0x4B, 0x68, 0x39, 0x47, 0x74, 0x78, 0x52, 0x45, 0x53, 0x4F, 0x61, 0x43, 0x74, 0x41, 0x67, 0x4D, ++ 0x42, 0x41, 0x41, 0x47, 0x6A, 0x51, 0x6A, 0x42, 0x41, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, ++ 0x50, 0x0A, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x52, 0x58, 0x4E, 0x50, 0x4E, 0x30, 0x7A, 0x77, 0x52, 0x4C, 0x31, 0x53, ++ 0x58, 0x6D, 0x38, 0x55, 0x43, 0x32, 0x4C, 0x45, 0x7A, 0x5A, 0x4C, 0x65, 0x6D, 0x67, 0x72, 0x54, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x0A, 0x41, ++ 0x51, 0x45, 0x41, 0x50, 0x72, 0x76, 0x62, 0x46, 0x78, 0x62, 0x53, 0x38, 0x68, 0x51, 0x42, 0x49, 0x43, 0x77, 0x34, 0x67, 0x30, 0x75, 0x74, 0x76, 0x73, 0x71, 0x46, 0x65, 0x70, 0x71, 0x32, 0x6D, 0x32, 0x75, 0x6D, 0x34, 0x66, 0x79, 0x6C, 0x4F, ++ 0x71, 0x79, 0x74, 0x74, 0x43, 0x67, 0x36, 0x72, 0x39, 0x63, 0x42, 0x67, 0x30, 0x6B, 0x72, 0x59, 0x36, 0x4C, 0x64, 0x6D, 0x6D, 0x51, 0x4F, 0x6D, 0x46, 0x78, 0x76, 0x33, 0x59, 0x36, 0x37, 0x69, 0x6C, 0x51, 0x69, 0x0A, 0x4C, 0x55, 0x6F, 0x54, ++ 0x38, 0x36, 0x35, 0x41, 0x51, 0x39, 0x74, 0x50, 0x6B, 0x62, 0x65, 0x47, 0x47, 0x75, 0x77, 0x41, 0x74, 0x45, 0x47, 0x42, 0x70, 0x45, 0x2F, 0x36, 0x61, 0x6F, 0x75, 0x49, 0x73, 0x33, 0x59, 0x49, 0x63, 0x69, 0x70, 0x4A, 0x51, 0x4D, 0x50, 0x54, ++ 0x77, 0x34, 0x57, 0x4A, 0x6D, 0x42, 0x43, 0x6C, 0x6E, 0x57, 0x38, 0x5A, 0x74, 0x37, 0x76, 0x50, 0x65, 0x6D, 0x56, 0x56, 0x32, 0x7A, 0x66, 0x72, 0x50, 0x49, 0x70, 0x79, 0x4D, 0x70, 0x63, 0x65, 0x0A, 0x6D, 0x69, 0x6B, 0x2B, 0x72, 0x59, 0x33, ++ 0x6D, 0x6F, 0x78, 0x74, 0x74, 0x39, 0x58, 0x55, 0x61, 0x35, 0x72, 0x42, 0x6F, 0x75, 0x56, 0x75, 0x69, 0x37, 0x6D, 0x6C, 0x48, 0x4A, 0x7A, 0x57, 0x68, 0x68, 0x70, 0x6D, 0x41, 0x38, 0x7A, 0x4E, 0x4C, 0x34, 0x57, 0x75, 0x6B, 0x4A, 0x73, 0x50, ++ 0x76, 0x64, 0x46, 0x6C, 0x73, 0x65, 0x71, 0x4A, 0x6B, 0x74, 0x68, 0x35, 0x45, 0x77, 0x31, 0x44, 0x67, 0x44, 0x7A, 0x6B, 0x39, 0x71, 0x54, 0x50, 0x78, 0x70, 0x66, 0x50, 0x53, 0x0A, 0x76, 0x57, 0x4B, 0x45, 0x72, 0x49, 0x34, 0x63, 0x71, 0x63, ++ 0x31, 0x61, 0x76, 0x54, 0x63, 0x37, 0x62, 0x67, 0x6F, 0x69, 0x74, 0x50, 0x51, 0x56, 0x35, 0x35, 0x46, 0x59, 0x78, 0x54, 0x70, 0x45, 0x30, 0x35, 0x55, 0x6F, 0x32, 0x63, 0x42, 0x6C, 0x36, 0x58, 0x4C, 0x4B, 0x30, 0x41, 0x2B, 0x39, 0x48, 0x37, ++ 0x4D, 0x56, 0x32, 0x61, 0x6E, 0x6A, 0x70, 0x45, 0x63, 0x4A, 0x6E, 0x75, 0x44, 0x4C, 0x4E, 0x2F, 0x76, 0x39, 0x76, 0x5A, 0x66, 0x56, 0x76, 0x68, 0x67, 0x61, 0x0A, 0x61, 0x61, 0x49, 0x35, 0x67, 0x64, 0x6B, 0x61, 0x39, 0x61, 0x74, 0x2F, 0x79, ++ 0x4F, 0x50, 0x69, 0x5A, 0x77, 0x75, 0x64, 0x39, 0x41, 0x7A, 0x71, 0x56, 0x4E, 0x2F, 0x53, 0x73, 0x71, 0x2B, 0x78, 0x49, 0x76, 0x45, 0x67, 0x33, 0x37, 0x78, 0x45, 0x48, 0x41, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, ++ 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x34, 0x0A, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, ++ 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x63, 0x6A, 0x43, 0x43, 0x41, 0x31, 0x71, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x55, 0x5A, 0x4E, 0x74, 0x61, 0x44, 0x43, 0x42, 0x4F, 0x36, 0x4E, 0x63, ++ 0x70, 0x64, 0x38, 0x68, 0x51, 0x4A, 0x36, 0x4A, 0x61, 0x4A, 0x39, 0x30, 0x74, 0x38, 0x73, 0x73, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4D, 0x42, 0x51, 0x41, 0x77, 0x55, 0x54, 0x45, ++ 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x0A, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x53, 0x6C, 0x41, 0x78, 0x49, 0x7A, 0x41, 0x68, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x47, 0x6B, 0x4E, 0x35, 0x59, 0x6D, 0x56, 0x79, 0x64, 0x48, ++ 0x4A, 0x31, 0x63, 0x33, 0x51, 0x67, 0x53, 0x6D, 0x46, 0x77, 0x59, 0x57, 0x34, 0x67, 0x51, 0x32, 0x38, 0x75, 0x4C, 0x43, 0x42, 0x4D, 0x64, 0x47, 0x51, 0x75, 0x4D, 0x52, 0x30, 0x77, 0x47, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, ++ 0x52, 0x54, 0x0A, 0x5A, 0x57, 0x4E, 0x31, 0x63, 0x6D, 0x56, 0x54, 0x61, 0x57, 0x64, 0x75, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x78, 0x4E, 0x44, 0x41, 0x65, 0x46, 0x77, 0x30, 0x79, 0x4D, 0x44, 0x41, 0x30, 0x4D, ++ 0x44, 0x67, 0x77, 0x4E, 0x7A, 0x41, 0x32, 0x4D, 0x54, 0x6C, 0x61, 0x46, 0x77, 0x30, 0x30, 0x4E, 0x54, 0x41, 0x30, 0x4D, 0x44, 0x67, 0x77, 0x4E, 0x7A, 0x41, 0x32, 0x4D, 0x54, 0x6C, 0x61, 0x4D, 0x46, 0x45, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x0A, ++ 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x70, 0x51, 0x4D, 0x53, 0x4D, 0x77, 0x49, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x78, 0x70, 0x44, 0x65, 0x57, 0x4A, 0x6C, 0x63, 0x6E, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, ++ 0x49, 0x45, 0x70, 0x68, 0x63, 0x47, 0x46, 0x75, 0x49, 0x45, 0x4E, 0x76, 0x4C, 0x69, 0x77, 0x67, 0x54, 0x48, 0x52, 0x6B, 0x4C, 0x6A, 0x45, 0x64, 0x4D, 0x42, 0x73, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x55, 0x0A, 0x55, 0x32, 0x56, ++ 0x6A, 0x64, 0x58, 0x4A, 0x6C, 0x55, 0x32, 0x6C, 0x6E, 0x62, 0x69, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x4D, 0x54, 0x51, 0x77, 0x67, 0x67, 0x49, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, ++ 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x44, 0x46, 0x30, 0x6E, 0x71, 0x68, 0x0A, 0x31, 0x6F, 0x71, 0x2F, 0x46, 0x6A, ++ 0x48, 0x51, 0x6D, 0x4E, 0x45, 0x36, 0x6C, 0x50, 0x78, 0x61, 0x75, 0x47, 0x34, 0x69, 0x77, 0x57, 0x4C, 0x33, 0x70, 0x77, 0x6F, 0x6E, 0x37, 0x31, 0x44, 0x32, 0x4C, 0x72, 0x47, 0x65, 0x61, 0x42, 0x4C, 0x77, 0x62, 0x43, 0x52, 0x6A, 0x4F, 0x66, ++ 0x48, 0x77, 0x33, 0x78, 0x44, 0x47, 0x33, 0x72, 0x64, 0x53, 0x49, 0x4E, 0x56, 0x53, 0x57, 0x30, 0x4B, 0x5A, 0x6E, 0x76, 0x4F, 0x67, 0x76, 0x6C, 0x49, 0x66, 0x58, 0x38, 0x78, 0x6E, 0x0A, 0x62, 0x61, 0x63, 0x75, 0x55, 0x4B, 0x4C, 0x42, 0x6C, ++ 0x34, 0x32, 0x32, 0x2B, 0x4A, 0x58, 0x31, 0x73, 0x4C, 0x72, 0x63, 0x6E, 0x65, 0x43, 0x2B, 0x79, 0x39, 0x2F, 0x33, 0x4F, 0x50, 0x4A, 0x48, 0x39, 0x61, 0x61, 0x61, 0x6B, 0x70, 0x55, 0x71, 0x59, 0x6C, 0x6C, 0x51, 0x43, 0x36, 0x4B, 0x78, 0x4E, ++ 0x65, 0x64, 0x6C, 0x73, 0x6D, 0x47, 0x79, 0x36, 0x70, 0x4A, 0x78, 0x61, 0x65, 0x51, 0x70, 0x38, 0x45, 0x2B, 0x42, 0x67, 0x51, 0x51, 0x38, 0x73, 0x71, 0x56, 0x62, 0x0A, 0x31, 0x4D, 0x57, 0x6F, 0x57, 0x57, 0x64, 0x37, 0x56, 0x52, 0x78, 0x4A, ++ 0x71, 0x33, 0x71, 0x64, 0x77, 0x75, 0x64, 0x7A, 0x54, 0x65, 0x2F, 0x4E, 0x43, 0x63, 0x4C, 0x45, 0x56, 0x78, 0x4C, 0x62, 0x41, 0x51, 0x34, 0x6A, 0x65, 0x51, 0x6B, 0x48, 0x4F, 0x36, 0x4C, 0x6F, 0x2F, 0x49, 0x72, 0x50, 0x6A, 0x38, 0x42, 0x47, ++ 0x4A, 0x4A, 0x77, 0x34, 0x4A, 0x2B, 0x43, 0x44, 0x6E, 0x52, 0x75, 0x67, 0x76, 0x33, 0x67, 0x56, 0x45, 0x4F, 0x75, 0x47, 0x54, 0x67, 0x70, 0x61, 0x0A, 0x2F, 0x64, 0x2F, 0x61, 0x4C, 0x49, 0x4A, 0x2B, 0x37, 0x73, 0x72, 0x32, 0x4B, 0x65, 0x48, ++ 0x36, 0x63, 0x61, 0x48, 0x33, 0x69, 0x47, 0x69, 0x63, 0x6E, 0x50, 0x43, 0x4E, 0x76, 0x67, 0x39, 0x4A, 0x6B, 0x64, 0x6A, 0x71, 0x4F, 0x76, 0x6E, 0x39, 0x30, 0x47, 0x68, 0x78, 0x32, 0x2B, 0x6D, 0x31, 0x4B, 0x30, 0x36, 0x43, 0x6B, 0x6D, 0x39, ++ 0x6D, 0x48, 0x2B, 0x44, 0x77, 0x33, 0x45, 0x7A, 0x73, 0x79, 0x74, 0x48, 0x71, 0x75, 0x6E, 0x51, 0x47, 0x2B, 0x62, 0x4F, 0x45, 0x0A, 0x6B, 0x4A, 0x54, 0x52, 0x58, 0x34, 0x35, 0x7A, 0x47, 0x52, 0x42, 0x64, 0x41, 0x75, 0x56, 0x77, 0x70, 0x63, ++ 0x41, 0x51, 0x30, 0x42, 0x42, 0x38, 0x62, 0x38, 0x56, 0x59, 0x53, 0x62, 0x53, 0x77, 0x62, 0x70, 0x72, 0x61, 0x66, 0x5A, 0x58, 0x31, 0x7A, 0x4E, 0x6F, 0x43, 0x72, 0x37, 0x67, 0x73, 0x66, 0x58, 0x6D, 0x50, 0x76, 0x6B, 0x50, 0x78, 0x2B, 0x53, ++ 0x67, 0x6F, 0x6A, 0x51, 0x6C, 0x44, 0x2B, 0x41, 0x6A, 0x64, 0x61, 0x38, 0x69, 0x4C, 0x4C, 0x43, 0x53, 0x78, 0x0A, 0x6A, 0x56, 0x49, 0x48, 0x76, 0x58, 0x69, 0x62, 0x79, 0x38, 0x70, 0x6F, 0x73, 0x71, 0x54, 0x64, 0x44, 0x45, 0x78, 0x35, 0x59, ++ 0x4D, 0x61, 0x5A, 0x30, 0x5A, 0x50, 0x78, 0x4D, 0x42, 0x6F, 0x48, 0x30, 0x36, 0x34, 0x69, 0x77, 0x75, 0x72, 0x4F, 0x38, 0x59, 0x51, 0x4A, 0x7A, 0x4F, 0x41, 0x55, 0x62, 0x6E, 0x38, 0x2F, 0x66, 0x74, 0x4B, 0x43, 0x68, 0x61, 0x7A, 0x63, 0x71, ++ 0x52, 0x5A, 0x4F, 0x68, 0x61, 0x42, 0x67, 0x79, 0x2F, 0x61, 0x63, 0x31, 0x38, 0x69, 0x7A, 0x0A, 0x6A, 0x75, 0x33, 0x47, 0x6D, 0x35, 0x68, 0x31, 0x44, 0x56, 0x58, 0x6F, 0x58, 0x2B, 0x57, 0x56, 0x69, 0x77, 0x4B, 0x6B, 0x72, 0x6B, 0x4D, 0x70, ++ 0x4B, 0x42, 0x47, 0x6B, 0x35, 0x68, 0x49, 0x77, 0x41, 0x55, 0x74, 0x31, 0x61, 0x78, 0x35, 0x6D, 0x6E, 0x58, 0x6B, 0x76, 0x70, 0x58, 0x59, 0x76, 0x48, 0x55, 0x43, 0x30, 0x62, 0x63, 0x6C, 0x39, 0x65, 0x51, 0x6A, 0x73, 0x30, 0x57, 0x71, 0x32, ++ 0x58, 0x53, 0x71, 0x79, 0x70, 0x57, 0x61, 0x39, 0x61, 0x34, 0x58, 0x30, 0x0A, 0x64, 0x46, 0x62, 0x44, 0x39, 0x65, 0x64, 0x31, 0x55, 0x69, 0x67, 0x73, 0x70, 0x66, 0x39, 0x6D, 0x52, 0x36, 0x58, 0x55, 0x2F, 0x76, 0x36, 0x65, 0x56, 0x4C, 0x39, ++ 0x6C, 0x66, 0x67, 0x48, 0x57, 0x4D, 0x49, 0x2B, 0x6C, 0x4E, 0x70, 0x79, 0x69, 0x55, 0x42, 0x7A, 0x75, 0x4F, 0x49, 0x41, 0x42, 0x53, 0x4D, 0x62, 0x48, 0x64, 0x50, 0x54, 0x47, 0x72, 0x4D, 0x4E, 0x41, 0x53, 0x52, 0x5A, 0x68, 0x64, 0x43, 0x79, ++ 0x76, 0x6A, 0x47, 0x38, 0x31, 0x37, 0x58, 0x73, 0x59, 0x0A, 0x41, 0x46, 0x73, 0x32, 0x50, 0x4A, 0x78, 0x51, 0x44, 0x63, 0x71, 0x53, 0x4D, 0x78, 0x44, 0x78, 0x4A, 0x6B, 0x6C, 0x74, 0x33, 0x33, 0x55, 0x6B, 0x4E, 0x34, 0x49, 0x69, 0x31, 0x2B, ++ 0x69, 0x57, 0x2F, 0x52, 0x56, 0x4C, 0x41, 0x70, 0x59, 0x2B, 0x42, 0x33, 0x4B, 0x56, 0x66, 0x71, 0x73, 0x39, 0x54, 0x43, 0x37, 0x58, 0x79, 0x76, 0x44, 0x66, 0x34, 0x46, 0x67, 0x2F, 0x4C, 0x53, 0x38, 0x45, 0x6D, 0x6A, 0x69, 0x6A, 0x41, 0x51, ++ 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x0A, 0x6F, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x41, 0x34, 0x47, 0x41, ++ 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x42, 0x70, 0x4F, 0x6A, 0x43, 0x6C, 0x34, 0x6F, 0x61, ++ 0x54, 0x65, 0x71, 0x0A, 0x59, 0x52, 0x33, 0x72, 0x36, 0x2F, 0x77, 0x74, 0x62, 0x79, 0x50, 0x6B, 0x38, 0x36, 0x41, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4D, 0x42, 0x51, 0x41, 0x44, ++ 0x67, 0x67, 0x49, 0x42, 0x41, 0x4A, 0x61, 0x41, 0x63, 0x67, 0x6B, 0x47, 0x66, 0x70, 0x7A, 0x4D, 0x6B, 0x77, 0x51, 0x57, 0x75, 0x36, 0x41, 0x36, 0x6A, 0x5A, 0x4A, 0x4F, 0x74, 0x78, 0x45, 0x61, 0x43, 0x6E, 0x46, 0x78, 0x45, 0x4D, 0x30, 0x45, ++ 0x0A, 0x72, 0x58, 0x2B, 0x6C, 0x52, 0x56, 0x41, 0x51, 0x5A, 0x6B, 0x35, 0x4B, 0x51, 0x61, 0x49, 0x44, 0x32, 0x52, 0x46, 0x50, 0x65, 0x6A, 0x65, 0x35, 0x53, 0x2B, 0x4C, 0x47, 0x6A, 0x7A, 0x4A, 0x6D, 0x64, 0x53, 0x58, 0x37, 0x36, 0x38, 0x34, ++ 0x2F, 0x41, 0x79, 0x6B, 0x6D, 0x6A, 0x62, 0x67, 0x57, 0x48, 0x66, 0x59, 0x66, 0x4D, 0x32, 0x35, 0x49, 0x35, 0x75, 0x6A, 0x34, 0x56, 0x37, 0x49, 0x62, 0x65, 0x64, 0x38, 0x37, 0x68, 0x77, 0x72, 0x69, 0x5A, 0x4C, 0x6F, 0x41, 0x0A, 0x79, 0x6D, ++ 0x7A, 0x76, 0x66, 0x74, 0x41, 0x6A, 0x36, 0x33, 0x69, 0x50, 0x2F, 0x32, 0x53, 0x62, 0x4E, 0x44, 0x65, 0x66, 0x4E, 0x57, 0x57, 0x69, 0x70, 0x41, 0x41, 0x39, 0x45, 0x69, 0x4F, 0x57, 0x57, 0x46, 0x33, 0x4B, 0x59, 0x34, 0x66, 0x47, 0x6F, 0x77, ++ 0x65, 0x49, 0x54, 0x65, 0x64, 0x70, 0x64, 0x6F, 0x70, 0x54, 0x7A, 0x66, 0x46, 0x50, 0x37, 0x45, 0x4C, 0x79, 0x6B, 0x2B, 0x4F, 0x5A, 0x70, 0x44, 0x63, 0x38, 0x68, 0x37, 0x68, 0x69, 0x32, 0x2F, 0x44, 0x73, 0x0A, 0x48, 0x7A, 0x63, 0x2F, 0x4E, ++ 0x31, 0x39, 0x44, 0x7A, 0x46, 0x47, 0x64, 0x74, 0x66, 0x43, 0x58, 0x77, 0x72, 0x65, 0x46, 0x61, 0x6D, 0x67, 0x4C, 0x52, 0x42, 0x37, 0x6C, 0x55, 0x65, 0x36, 0x54, 0x7A, 0x6B, 0x74, 0x75, 0x68, 0x73, 0x48, 0x53, 0x44, 0x43, 0x52, 0x5A, 0x4E, ++ 0x68, 0x71, 0x66, 0x4C, 0x4A, 0x47, 0x50, 0x34, 0x78, 0x6A, 0x62, 0x6C, 0x4A, 0x55, 0x4B, 0x37, 0x5A, 0x47, 0x71, 0x44, 0x70, 0x6E, 0x63, 0x6C, 0x6C, 0x50, 0x6A, 0x59, 0x59, 0x50, 0x47, 0x0A, 0x46, 0x72, 0x6F, 0x6A, 0x75, 0x74, 0x7A, 0x64, ++ 0x66, 0x68, 0x72, 0x47, 0x65, 0x30, 0x4B, 0x32, 0x32, 0x56, 0x6F, 0x46, 0x33, 0x4A, 0x70, 0x66, 0x31, 0x64, 0x2B, 0x34, 0x32, 0x6B, 0x64, 0x39, 0x32, 0x6A, 0x6A, 0x62, 0x72, 0x44, 0x6E, 0x56, 0x48, 0x6D, 0x74, 0x73, 0x4B, 0x68, 0x65, 0x4D, ++ 0x59, 0x63, 0x32, 0x78, 0x62, 0x58, 0x49, 0x42, 0x77, 0x38, 0x4D, 0x67, 0x41, 0x47, 0x4A, 0x6F, 0x46, 0x6A, 0x48, 0x56, 0x64, 0x71, 0x71, 0x47, 0x75, 0x77, 0x36, 0x71, 0x0A, 0x6E, 0x73, 0x62, 0x35, 0x38, 0x4E, 0x6E, 0x34, 0x44, 0x53, 0x45, ++ 0x43, 0x35, 0x4D, 0x55, 0x6F, 0x46, 0x6C, 0x6B, 0x52, 0x75, 0x64, 0x6C, 0x70, 0x63, 0x79, 0x71, 0x53, 0x65, 0x4C, 0x69, 0x53, 0x56, 0x35, 0x73, 0x49, 0x38, 0x6A, 0x72, 0x6C, 0x4C, 0x35, 0x57, 0x77, 0x57, 0x4C, 0x64, 0x72, 0x49, 0x42, 0x52, ++ 0x74, 0x46, 0x4F, 0x38, 0x4B, 0x76, 0x48, 0x37, 0x59, 0x56, 0x64, 0x69, 0x49, 0x32, 0x69, 0x2F, 0x36, 0x47, 0x61, 0x58, 0x37, 0x69, 0x2B, 0x42, 0x2F, 0x0A, 0x4F, 0x66, 0x56, 0x79, 0x4B, 0x34, 0x58, 0x45, 0x4C, 0x4B, 0x7A, 0x76, 0x47, 0x55, ++ 0x57, 0x53, 0x54, 0x4C, 0x4E, 0x68, 0x42, 0x39, 0x78, 0x4E, 0x48, 0x32, 0x37, 0x53, 0x67, 0x52, 0x4E, 0x63, 0x6D, 0x76, 0x4D, 0x53, 0x5A, 0x34, 0x50, 0x50, 0x6D, 0x7A, 0x2B, 0x4C, 0x6E, 0x35, 0x32, 0x6B, 0x75, 0x61, 0x69, 0x57, 0x41, 0x33, ++ 0x72, 0x46, 0x37, 0x69, 0x44, 0x65, 0x4D, 0x39, 0x6F, 0x76, 0x6E, 0x68, 0x70, 0x36, 0x64, 0x42, 0x37, 0x68, 0x37, 0x73, 0x78, 0x61, 0x0A, 0x4F, 0x67, 0x54, 0x64, 0x73, 0x78, 0x6F, 0x45, 0x71, 0x42, 0x52, 0x6A, 0x72, 0x4C, 0x64, 0x48, 0x45, ++ 0x6F, 0x4F, 0x61, 0x62, 0x50, 0x58, 0x6D, 0x36, 0x52, 0x55, 0x56, 0x6B, 0x52, 0x71, 0x45, 0x47, 0x51, 0x36, 0x55, 0x52, 0x4F, 0x63, 0x53, 0x6A, 0x69, 0x56, 0x62, 0x67, 0x47, 0x63, 0x5A, 0x33, 0x47, 0x4F, 0x54, 0x45, 0x41, 0x74, 0x6C, 0x4C, ++ 0x6F, 0x72, 0x36, 0x43, 0x5A, 0x70, 0x4F, 0x32, 0x6F, 0x59, 0x6F, 0x66, 0x61, 0x70, 0x68, 0x4E, 0x64, 0x67, 0x4F, 0x0A, 0x70, 0x79, 0x67, 0x61, 0x75, 0x31, 0x4C, 0x67, 0x65, 0x50, 0x68, 0x73, 0x75, 0x6D, 0x79, 0x77, 0x62, 0x72, 0x6D, 0x48, ++ 0x58, 0x75, 0x6D, 0x5A, 0x4E, 0x54, 0x66, 0x78, 0x50, 0x57, 0x51, 0x72, 0x71, 0x61, 0x41, 0x30, 0x6B, 0x38, 0x39, 0x6A, 0x4C, 0x39, 0x57, 0x42, 0x33, 0x36, 0x35, 0x6A, 0x4A, 0x36, 0x55, 0x65, 0x54, 0x6F, 0x33, 0x63, 0x4B, 0x58, 0x68, 0x5A, ++ 0x2B, 0x50, 0x6D, 0x68, 0x49, 0x49, 0x79, 0x6E, 0x4A, 0x6B, 0x42, 0x75, 0x67, 0x6E, 0x4C, 0x4E, 0x0A, 0x65, 0x4C, 0x4C, 0x49, 0x6A, 0x7A, 0x77, 0x65, 0x63, 0x2B, 0x66, 0x42, 0x48, 0x37, 0x2F, 0x50, 0x7A, 0x71, 0x55, 0x71, 0x6D, 0x39, 0x74, ++ 0x45, 0x5A, 0x44, 0x4B, 0x67, 0x75, 0x33, 0x39, 0x63, 0x4A, 0x52, 0x4E, 0x49, 0x74, 0x58, 0x2B, 0x53, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, ++ 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x35, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x49, ++ 0x7A, 0x43, 0x43, 0x41, 0x61, 0x6D, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x55, 0x46, 0x68, 0x58, 0x48, 0x77, 0x39, 0x68, 0x4A, 0x70, 0x37, 0x35, 0x70, 0x44, 0x49, 0x71, 0x49, 0x37, 0x66, 0x42, 0x77, 0x2B, 0x64, 0x32, 0x33, 0x50, ++ 0x6F, 0x63, 0x77, 0x43, 0x67, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x45, 0x41, 0x77, 0x4D, 0x77, 0x55, 0x54, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0A, 0x42, 0x68, 0x4D, 0x43, 0x53, 0x6C, 0x41, 0x78, ++ 0x49, 0x7A, 0x41, 0x68, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x47, 0x6B, 0x4E, 0x35, 0x59, 0x6D, 0x56, 0x79, 0x64, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x67, 0x53, 0x6D, 0x46, 0x77, 0x59, 0x57, 0x34, 0x67, 0x51, 0x32, 0x38, 0x75, ++ 0x4C, 0x43, 0x42, 0x4D, 0x64, 0x47, 0x51, 0x75, 0x4D, 0x52, 0x30, 0x77, 0x47, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x52, 0x54, 0x5A, 0x57, 0x4E, 0x31, 0x0A, 0x63, 0x6D, 0x56, 0x54, 0x61, 0x57, 0x64, 0x75, 0x49, 0x46, 0x4A, ++ 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x78, 0x4E, 0x54, 0x41, 0x65, 0x46, 0x77, 0x30, 0x79, 0x4D, 0x44, 0x41, 0x30, 0x4D, 0x44, 0x67, 0x77, 0x4F, 0x44, 0x4D, 0x79, 0x4E, 0x54, 0x5A, 0x61, 0x46, 0x77, 0x30, 0x30, 0x4E, 0x54, 0x41, ++ 0x30, 0x4D, 0x44, 0x67, 0x77, 0x4F, 0x44, 0x4D, 0x79, 0x4E, 0x54, 0x5A, 0x61, 0x4D, 0x46, 0x45, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x0A, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x70, 0x51, 0x4D, 0x53, 0x4D, 0x77, 0x49, 0x51, ++ 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x78, 0x70, 0x44, 0x65, 0x57, 0x4A, 0x6C, 0x63, 0x6E, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x49, 0x45, 0x70, 0x68, 0x63, 0x47, 0x46, 0x75, 0x49, 0x45, 0x4E, 0x76, 0x4C, 0x69, 0x77, 0x67, 0x54, 0x48, ++ 0x52, 0x6B, 0x4C, 0x6A, 0x45, 0x64, 0x4D, 0x42, 0x73, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x55, 0x55, 0x32, 0x56, 0x6A, 0x0A, 0x64, 0x58, 0x4A, 0x6C, 0x55, 0x32, 0x6C, 0x6E, 0x62, 0x69, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, ++ 0x45, 0x4E, 0x42, 0x4D, 0x54, 0x55, 0x77, 0x64, 0x6A, 0x41, 0x51, 0x42, 0x67, 0x63, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x49, 0x42, 0x42, 0x67, 0x55, 0x72, 0x67, 0x51, 0x51, 0x41, 0x49, 0x67, 0x4E, 0x69, 0x41, 0x41, 0x51, 0x4C, 0x55, ++ 0x48, 0x53, 0x4E, 0x5A, 0x44, 0x4B, 0x5A, 0x6D, 0x62, 0x50, 0x53, 0x59, 0x41, 0x69, 0x34, 0x49, 0x6F, 0x35, 0x47, 0x0A, 0x64, 0x43, 0x78, 0x34, 0x77, 0x43, 0x74, 0x45, 0x4C, 0x57, 0x31, 0x66, 0x48, 0x63, 0x6D, 0x75, 0x53, 0x31, 0x49, 0x67, ++ 0x67, 0x7A, 0x32, 0x34, 0x46, 0x47, 0x31, 0x54, 0x68, 0x32, 0x43, 0x65, 0x58, 0x32, 0x79, 0x46, 0x32, 0x77, 0x59, 0x55, 0x6C, 0x65, 0x44, 0x48, 0x4B, 0x50, 0x2B, 0x64, 0x58, 0x2B, 0x53, 0x71, 0x38, 0x62, 0x4F, 0x4C, 0x62, 0x65, 0x31, 0x50, ++ 0x4C, 0x30, 0x76, 0x4A, 0x53, 0x70, 0x53, 0x52, 0x5A, 0x48, 0x58, 0x2B, 0x41, 0x65, 0x7A, 0x42, 0x0A, 0x32, 0x4F, 0x74, 0x36, 0x6C, 0x48, 0x68, 0x57, 0x47, 0x45, 0x4E, 0x66, 0x61, 0x34, 0x48, 0x4C, 0x39, 0x72, 0x7A, 0x61, 0x74, 0x41, 0x79, ++ 0x32, 0x4B, 0x5A, 0x4D, 0x49, 0x61, 0x59, 0x2B, 0x6A, 0x51, 0x6A, 0x42, 0x41, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x44, 0x67, 0x59, ++ 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x0A, 0x41, 0x67, 0x45, 0x47, 0x4D, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x54, 0x72, 0x51, 0x63, 0x69, 0x75, 0x2F, 0x4E, ++ 0x57, 0x65, 0x55, 0x55, 0x6A, 0x31, 0x76, 0x59, 0x76, 0x30, 0x68, 0x79, 0x43, 0x54, 0x51, 0x53, 0x76, 0x54, 0x39, 0x44, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x77, 0x4E, 0x6F, 0x41, 0x44, ++ 0x42, 0x6C, 0x41, 0x6A, 0x45, 0x41, 0x32, 0x53, 0x36, 0x4A, 0x0A, 0x66, 0x6C, 0x35, 0x4F, 0x70, 0x42, 0x45, 0x48, 0x76, 0x56, 0x6E, 0x43, 0x42, 0x39, 0x36, 0x72, 0x4D, 0x6A, 0x68, 0x54, 0x4B, 0x6B, 0x5A, 0x45, 0x42, 0x68, 0x64, 0x36, 0x7A, ++ 0x6C, 0x48, 0x70, 0x34, 0x50, 0x39, 0x6D, 0x4C, 0x51, 0x6C, 0x4F, 0x34, 0x45, 0x2F, 0x30, 0x42, 0x64, 0x47, 0x46, 0x39, 0x6A, 0x56, 0x67, 0x33, 0x50, 0x56, 0x79, 0x73, 0x30, 0x5A, 0x39, 0x41, 0x6A, 0x42, 0x45, 0x6D, 0x45, 0x59, 0x61, 0x67, ++ 0x6F, 0x55, 0x65, 0x59, 0x57, 0x6D, 0x4A, 0x0A, 0x53, 0x77, 0x64, 0x4C, 0x5A, 0x72, 0x57, 0x65, 0x71, 0x72, 0x71, 0x67, 0x48, 0x6B, 0x48, 0x5A, 0x41, 0x58, 0x51, 0x36, 0x62, 0x6B, 0x55, 0x36, 0x69, 0x59, 0x41, 0x5A, 0x65, 0x7A, 0x4B, 0x59, ++ 0x56, 0x57, 0x4F, 0x72, 0x36, 0x32, 0x4E, 0x75, 0x6B, 0x32, 0x32, 0x72, 0x47, 0x77, 0x6C, 0x67, 0x4D, 0x55, 0x34, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, ++ 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x42, 0x52, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, 0x32, 0x30, 0x32, 0x33, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, ++ 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x71, 0x54, 0x43, 0x43, 0x41, 0x35, 0x47, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x63, 0x7A, 0x73, 0x77, 0x42, 0x45, 0x68, 0x62, 0x32, 0x55, 0x31, 0x34, ++ 0x4C, 0x6E, 0x4E, 0x4C, 0x79, 0x61, 0x48, 0x63, 0x5A, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x30, 0x46, 0x41, 0x44, 0x42, 0x49, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, ++ 0x56, 0x51, 0x51, 0x47, 0x0A, 0x45, 0x77, 0x4A, 0x45, 0x52, 0x54, 0x45, 0x56, 0x4D, 0x42, 0x4D, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x4D, 0x52, 0x43, 0x31, 0x55, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x43, 0x42, 0x48, 0x62, 0x57, 0x4A, ++ 0x49, 0x4D, 0x53, 0x49, 0x77, 0x49, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x6C, 0x45, 0x4C, 0x56, 0x52, 0x53, 0x56, 0x56, 0x4E, 0x55, 0x49, 0x45, 0x4A, 0x53, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, ++ 0x67, 0x0A, 0x4D, 0x69, 0x41, 0x79, 0x4D, 0x44, 0x49, 0x7A, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x49, 0x7A, 0x4D, 0x44, 0x55, 0x77, 0x4F, 0x54, 0x41, 0x34, 0x4E, 0x54, 0x59, 0x7A, 0x4D, 0x56, 0x6F, 0x58, 0x44, 0x54, 0x4D, 0x34, 0x4D, 0x44, ++ 0x55, 0x77, 0x4F, 0x54, 0x41, 0x34, 0x4E, 0x54, 0x59, 0x7A, 0x4D, 0x46, 0x6F, 0x77, 0x53, 0x44, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x52, 0x45, 0x55, 0x78, 0x46, 0x54, 0x41, 0x54, 0x0A, 0x42, ++ 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x44, 0x45, 0x51, 0x74, 0x56, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x67, 0x52, 0x32, 0x31, 0x69, 0x53, 0x44, 0x45, 0x69, 0x4D, 0x43, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x5A, 0x52, ++ 0x43, 0x31, 0x55, 0x55, 0x6C, 0x56, 0x54, 0x56, 0x43, 0x42, 0x43, 0x55, 0x69, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x49, 0x44, 0x49, 0x67, 0x4D, 0x6A, 0x41, 0x79, 0x4D, 0x7A, 0x43, 0x43, 0x0A, 0x41, 0x69, 0x49, 0x77, ++ 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x67, 0x6F, 0x43, 0x67, 0x67, 0x49, 0x42, 0x41, 0x4B, 0x37, 0x2F, ++ 0x43, 0x56, 0x6D, 0x52, 0x67, 0x41, 0x70, 0x4B, 0x61, 0x4F, 0x59, 0x6B, 0x50, 0x37, 0x69, 0x6E, 0x35, 0x4D, 0x67, 0x36, 0x43, 0x6A, 0x6F, 0x57, 0x7A, 0x63, 0x6B, 0x6A, 0x59, 0x61, 0x43, 0x54, 0x0A, 0x63, 0x66, 0x4B, 0x72, 0x69, 0x33, 0x4F, ++ 0x50, 0x6F, 0x47, 0x64, 0x6C, 0x59, 0x4E, 0x4A, 0x55, 0x61, 0x32, 0x4E, 0x52, 0x62, 0x30, 0x6B, 0x7A, 0x34, 0x48, 0x49, 0x48, 0x45, 0x33, 0x30, 0x34, 0x7A, 0x51, 0x61, 0x53, 0x42, 0x79, 0x6C, 0x53, 0x61, 0x30, 0x35, 0x33, 0x62, 0x41, 0x54, ++ 0x54, 0x6C, 0x66, 0x72, 0x64, 0x54, 0x49, 0x7A, 0x5A, 0x58, 0x63, 0x46, 0x68, 0x66, 0x55, 0x76, 0x6E, 0x4B, 0x4C, 0x4E, 0x45, 0x67, 0x58, 0x74, 0x52, 0x72, 0x39, 0x30, 0x7A, 0x0A, 0x73, 0x57, 0x68, 0x38, 0x31, 0x6B, 0x35, 0x4D, 0x2F, 0x69, ++ 0x74, 0x6F, 0x75, 0x63, 0x70, 0x6D, 0x61, 0x63, 0x54, 0x73, 0x58, 0x6C, 0x64, 0x2F, 0x39, 0x77, 0x33, 0x48, 0x6E, 0x44, 0x59, 0x32, 0x35, 0x51, 0x64, 0x67, 0x72, 0x4D, 0x42, 0x4D, 0x36, 0x67, 0x68, 0x73, 0x37, 0x77, 0x5A, 0x38, 0x54, 0x31, ++ 0x73, 0x6F, 0x65, 0x67, 0x6A, 0x38, 0x6B, 0x31, 0x32, 0x62, 0x39, 0x70, 0x79, 0x30, 0x69, 0x34, 0x61, 0x36, 0x49, 0x62, 0x6E, 0x30, 0x38, 0x4F, 0x68, 0x5A, 0x0A, 0x57, 0x69, 0x69, 0x68, 0x4E, 0x49, 0x51, 0x61, 0x4A, 0x5A, 0x47, 0x32, 0x74, ++ 0x59, 0x2F, 0x76, 0x73, 0x76, 0x6D, 0x41, 0x2B, 0x76, 0x6B, 0x39, 0x50, 0x42, 0x46, 0x79, 0x32, 0x4F, 0x4D, 0x76, 0x68, 0x6E, 0x62, 0x46, 0x65, 0x53, 0x7A, 0x42, 0x71, 0x5A, 0x43, 0x54, 0x52, 0x70, 0x68, 0x6E, 0x79, 0x34, 0x4E, 0x71, 0x6F, ++ 0x46, 0x41, 0x6A, 0x70, 0x7A, 0x76, 0x32, 0x67, 0x54, 0x6E, 0x67, 0x37, 0x66, 0x43, 0x35, 0x76, 0x32, 0x58, 0x78, 0x32, 0x4D, 0x74, 0x36, 0x0A, 0x2B, 0x2B, 0x39, 0x7A, 0x41, 0x38, 0x34, 0x41, 0x39, 0x48, 0x33, 0x58, 0x34, 0x46, 0x30, 0x37, ++ 0x5A, 0x72, 0x6A, 0x63, 0x6A, 0x72, 0x71, 0x44, 0x79, 0x34, 0x64, 0x32, 0x41, 0x2F, 0x77, 0x6C, 0x32, 0x65, 0x63, 0x6A, 0x62, 0x77, 0x62, 0x39, 0x5A, 0x2F, 0x50, 0x67, 0x2F, 0x34, 0x53, 0x38, 0x52, 0x37, 0x2B, 0x31, 0x46, 0x68, 0x68, 0x47, ++ 0x61, 0x52, 0x54, 0x4D, 0x42, 0x66, 0x66, 0x62, 0x30, 0x30, 0x6D, 0x73, 0x61, 0x38, 0x79, 0x72, 0x35, 0x4C, 0x55, 0x4C, 0x0A, 0x51, 0x79, 0x52, 0x65, 0x53, 0x32, 0x74, 0x4E, 0x5A, 0x39, 0x2F, 0x57, 0x74, 0x54, 0x35, 0x50, 0x65, 0x42, 0x2B, ++ 0x55, 0x63, 0x53, 0x54, 0x71, 0x33, 0x6E, 0x44, 0x38, 0x38, 0x5A, 0x50, 0x2B, 0x6E, 0x70, 0x4E, 0x61, 0x35, 0x4A, 0x52, 0x61, 0x6C, 0x31, 0x51, 0x4D, 0x4E, 0x58, 0x74, 0x66, 0x62, 0x4F, 0x34, 0x41, 0x48, 0x79, 0x54, 0x73, 0x41, 0x37, 0x6F, ++ 0x43, 0x39, 0x58, 0x62, 0x30, 0x6E, 0x39, 0x53, 0x61, 0x37, 0x59, 0x55, 0x73, 0x4F, 0x43, 0x49, 0x76, 0x0A, 0x78, 0x39, 0x67, 0x76, 0x64, 0x68, 0x46, 0x50, 0x2F, 0x57, 0x78, 0x63, 0x36, 0x50, 0x57, 0x4F, 0x4A, 0x34, 0x64, 0x2F, 0x47, 0x55, ++ 0x6F, 0x68, 0x52, 0x35, 0x41, 0x64, 0x65, 0x59, 0x30, 0x63, 0x57, 0x2F, 0x6A, 0x50, 0x53, 0x6F, 0x58, 0x6B, 0x37, 0x62, 0x4E, 0x62, 0x6A, 0x62, 0x37, 0x45, 0x5A, 0x43, 0x68, 0x64, 0x51, 0x63, 0x52, 0x75, 0x72, 0x44, 0x68, 0x61, 0x54, 0x79, ++ 0x4E, 0x30, 0x64, 0x4B, 0x6B, 0x53, 0x77, 0x2F, 0x62, 0x53, 0x75, 0x52, 0x45, 0x56, 0x0A, 0x4D, 0x77, 0x65, 0x52, 0x32, 0x44, 0x73, 0x33, 0x4F, 0x6D, 0x4D, 0x77, 0x42, 0x74, 0x48, 0x46, 0x49, 0x6A, 0x59, 0x6F, 0x59, 0x69, 0x4D, 0x51, 0x34, ++ 0x45, 0x62, 0x4D, 0x6C, 0x36, 0x7A, 0x57, 0x4B, 0x31, 0x31, 0x6B, 0x4A, 0x4E, 0x58, 0x75, 0x48, 0x41, 0x37, 0x65, 0x2B, 0x77, 0x68, 0x61, 0x64, 0x53, 0x72, 0x32, 0x59, 0x32, 0x33, 0x4F, 0x43, 0x30, 0x4B, 0x2B, 0x30, 0x62, 0x70, 0x77, 0x48, ++ 0x4A, 0x77, 0x68, 0x35, 0x51, 0x38, 0x78, 0x61, 0x52, 0x66, 0x58, 0x0A, 0x2F, 0x41, 0x71, 0x30, 0x33, 0x75, 0x32, 0x41, 0x6E, 0x4D, 0x75, 0x53, 0x74, 0x49, 0x76, 0x31, 0x33, 0x6C, 0x6D, 0x69, 0x57, 0x41, 0x6D, 0x6C, 0x59, 0x30, 0x63, 0x4C, ++ 0x34, 0x55, 0x45, 0x79, 0x4E, 0x45, 0x48, 0x5A, 0x6D, 0x72, 0x48, 0x5A, 0x71, 0x4C, 0x41, 0x62, 0x57, 0x74, 0x34, 0x4E, 0x44, 0x66, 0x54, 0x69, 0x73, 0x6C, 0x30, 0x31, 0x67, 0x4C, 0x6D, 0x42, 0x31, 0x49, 0x52, 0x70, 0x6B, 0x51, 0x4C, 0x4C, ++ 0x64, 0x64, 0x43, 0x4E, 0x78, 0x62, 0x55, 0x39, 0x0A, 0x43, 0x5A, 0x45, 0x4A, 0x6A, 0x78, 0x53, 0x68, 0x46, 0x48, 0x52, 0x35, 0x50, 0x74, 0x62, 0x4A, 0x46, 0x52, 0x32, 0x6B, 0x57, 0x56, 0x6B, 0x69, 0x33, 0x50, 0x61, 0x4B, 0x52, 0x54, 0x30, ++ 0x38, 0x45, 0x74, 0x59, 0x2B, 0x58, 0x54, 0x49, 0x76, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, 0x67, 0x59, 0x34, 0x77, 0x67, 0x59, 0x73, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, ++ 0x77, 0x41, 0x77, 0x45, 0x42, 0x0A, 0x2F, 0x7A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x5A, 0x35, 0x44, 0x77, 0x31, 0x74, 0x36, 0x31, 0x47, 0x4E, 0x56, 0x47, 0x4B, 0x58, 0x35, 0x63, 0x71, 0x2F, ++ 0x69, 0x65, 0x43, 0x4C, 0x78, 0x6B, 0x6C, 0x52, 0x41, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4D, 0x45, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x64, 0x48, 0x77, ++ 0x52, 0x43, 0x0A, 0x4D, 0x45, 0x41, 0x77, 0x50, 0x71, 0x41, 0x38, 0x6F, 0x44, 0x71, 0x47, 0x4F, 0x47, 0x68, 0x30, 0x64, 0x48, 0x41, 0x36, 0x4C, 0x79, 0x39, 0x6A, 0x63, 0x6D, 0x77, 0x75, 0x5A, 0x43, 0x31, 0x30, 0x63, 0x6E, 0x56, 0x7A, 0x64, ++ 0x43, 0x35, 0x75, 0x5A, 0x58, 0x51, 0x76, 0x59, 0x33, 0x4A, 0x73, 0x4C, 0x32, 0x51, 0x74, 0x64, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x52, 0x66, 0x59, 0x6E, 0x4A, 0x66, 0x63, 0x6D, 0x39, 0x76, 0x64, 0x46, 0x39, 0x6A, 0x59, 0x56, 0x38, 0x79, 0x0A, ++ 0x58, 0x7A, 0x49, 0x77, 0x4D, 0x6A, 0x4D, 0x75, 0x59, 0x33, 0x4A, 0x73, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x44, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x41, 0x51, 0x41, 0x30, ++ 0x39, 0x37, 0x4E, 0x33, 0x55, 0x39, 0x73, 0x77, 0x46, 0x72, 0x6B, 0x74, 0x70, 0x53, 0x48, 0x78, 0x51, 0x43, 0x46, 0x31, 0x36, 0x2B, 0x74, 0x49, 0x46, 0x6F, 0x45, 0x39, 0x63, 0x2B, 0x43, 0x65, 0x4A, 0x79, 0x72, 0x72, 0x0A, 0x64, 0x36, 0x6B, ++ 0x54, 0x70, 0x47, 0x6F, 0x4B, 0x57, 0x6C, 0x6F, 0x55, 0x4D, 0x7A, 0x31, 0x6F, 0x48, 0x34, 0x47, 0x75, 0x61, 0x66, 0x32, 0x4D, 0x6E, 0x32, 0x56, 0x73, 0x4E, 0x45, 0x4C, 0x5A, 0x4C, 0x64, 0x42, 0x2F, 0x65, 0x42, 0x61, 0x78, 0x4F, 0x71, 0x77, ++ 0x6A, 0x4D, 0x61, 0x31, 0x65, 0x66, 0x36, 0x37, 0x6E, 0x72, 0x69, 0x76, 0x36, 0x75, 0x76, 0x77, 0x38, 0x6C, 0x35, 0x56, 0x41, 0x6B, 0x31, 0x2F, 0x44, 0x4C, 0x51, 0x4F, 0x6A, 0x37, 0x61, 0x52, 0x76, 0x0A, 0x55, 0x39, 0x66, 0x36, 0x51, 0x41, ++ 0x34, 0x77, 0x39, 0x51, 0x41, 0x67, 0x4C, 0x41, 0x42, 0x4D, 0x6A, 0x44, 0x75, 0x30, 0x6F, 0x78, 0x2B, 0x32, 0x76, 0x35, 0x45, 0x79, 0x71, 0x36, 0x2B, 0x53, 0x6D, 0x4E, 0x4D, 0x57, 0x35, 0x74, 0x54, 0x52, 0x56, 0x46, 0x78, 0x44, 0x57, 0x79, ++ 0x36, 0x75, 0x37, 0x31, 0x63, 0x71, 0x71, 0x4C, 0x52, 0x76, 0x70, 0x4F, 0x38, 0x4E, 0x56, 0x68, 0x54, 0x61, 0x49, 0x61, 0x73, 0x67, 0x64, 0x70, 0x34, 0x44, 0x2F, 0x43, 0x61, 0x34, 0x0A, 0x6E, 0x6A, 0x38, 0x2B, 0x41, 0x79, 0x62, 0x6D, 0x54, ++ 0x4E, 0x75, 0x64, 0x58, 0x30, 0x4B, 0x45, 0x50, 0x55, 0x55, 0x44, 0x41, 0x78, 0x78, 0x5A, 0x69, 0x4D, 0x72, 0x63, 0x4C, 0x6D, 0x45, 0x6B, 0x57, 0x71, 0x54, 0x71, 0x4A, 0x77, 0x74, 0x7A, 0x45, 0x72, 0x35, 0x53, 0x73, 0x77, 0x72, 0x50, 0x4D, ++ 0x68, 0x66, 0x69, 0x48, 0x6F, 0x63, 0x61, 0x46, 0x70, 0x56, 0x49, 0x62, 0x56, 0x72, 0x67, 0x30, 0x4D, 0x38, 0x4A, 0x6B, 0x69, 0x5A, 0x6D, 0x6B, 0x64, 0x69, 0x6A, 0x0A, 0x59, 0x51, 0x36, 0x71, 0x67, 0x59, 0x46, 0x2F, 0x36, 0x46, 0x4B, 0x43, ++ 0x30, 0x55, 0x4C, 0x6E, 0x34, 0x42, 0x30, 0x59, 0x2B, 0x71, 0x53, 0x46, 0x4E, 0x75, 0x65, 0x47, 0x34, 0x41, 0x33, 0x72, 0x76, 0x4E, 0x54, 0x4A, 0x31, 0x6A, 0x78, 0x44, 0x38, 0x56, 0x31, 0x4A, 0x62, 0x6E, 0x36, 0x42, 0x6D, 0x32, 0x6D, 0x31, ++ 0x69, 0x57, 0x4B, 0x50, 0x69, 0x46, 0x4C, 0x59, 0x31, 0x2F, 0x34, 0x6E, 0x77, 0x53, 0x50, 0x46, 0x79, 0x79, 0x73, 0x43, 0x75, 0x37, 0x46, 0x66, 0x0A, 0x2F, 0x76, 0x74, 0x44, 0x68, 0x51, 0x4E, 0x47, 0x76, 0x6C, 0x33, 0x47, 0x79, 0x69, 0x45, ++ 0x6D, 0x2F, 0x39, 0x63, 0x43, 0x6E, 0x6E, 0x52, 0x4B, 0x33, 0x50, 0x67, 0x54, 0x46, 0x62, 0x47, 0x42, 0x56, 0x7A, 0x62, 0x4C, 0x5A, 0x56, 0x7A, 0x52, 0x48, 0x54, 0x46, 0x33, 0x36, 0x53, 0x58, 0x44, 0x77, 0x37, 0x49, 0x79, 0x4E, 0x39, 0x58, ++ 0x78, 0x6D, 0x41, 0x6E, 0x6B, 0x62, 0x57, 0x4F, 0x41, 0x43, 0x4B, 0x73, 0x47, 0x6B, 0x6F, 0x48, 0x55, 0x36, 0x58, 0x43, 0x50, 0x0A, 0x70, 0x7A, 0x2B, 0x79, 0x37, 0x59, 0x61, 0x4D, 0x67, 0x6D, 0x6F, 0x31, 0x79, 0x45, 0x4A, 0x61, 0x67, 0x74, ++ 0x46, 0x53, 0x47, 0x6B, 0x55, 0x50, 0x46, 0x61, 0x55, 0x41, 0x38, 0x4A, 0x52, 0x37, 0x5A, 0x53, 0x64, 0x58, 0x4F, 0x55, 0x50, 0x50, 0x66, 0x48, 0x2F, 0x6D, 0x76, 0x54, 0x57, 0x7A, 0x65, 0x2F, 0x45, 0x5A, 0x54, 0x4E, 0x34, 0x36, 0x6C, 0x73, ++ 0x2F, 0x70, 0x64, 0x75, 0x34, 0x44, 0x35, 0x38, 0x4A, 0x44, 0x55, 0x6A, 0x78, 0x71, 0x67, 0x65, 0x6A, 0x42, 0x0A, 0x57, 0x6F, 0x43, 0x39, 0x45, 0x56, 0x32, 0x54, 0x61, 0x2F, 0x76, 0x48, 0x35, 0x6D, 0x51, 0x2F, 0x75, 0x32, 0x6B, 0x63, 0x36, ++ 0x64, 0x30, 0x6C, 0x69, 0x36, 0x39, 0x30, 0x79, 0x56, 0x52, 0x41, 0x79, 0x73, 0x75, 0x54, 0x45, 0x77, 0x72, 0x74, 0x2B, 0x32, 0x61, 0x53, 0x45, 0x63, 0x72, 0x31, 0x77, 0x50, 0x72, 0x59, 0x67, 0x31, 0x55, 0x44, 0x66, 0x4E, 0x50, 0x46, 0x49, ++ 0x6B, 0x5A, 0x31, 0x63, 0x47, 0x74, 0x35, 0x53, 0x41, 0x59, 0x71, 0x67, 0x70, 0x71, 0x2F, 0x0A, 0x35, 0x75, 0x73, 0x57, 0x44, 0x69, 0x4A, 0x46, 0x41, 0x62, 0x7A, 0x64, 0x4E, 0x70, 0x51, 0x30, 0x71, 0x54, 0x55, 0x6D, 0x69, 0x74, 0x65, 0x58, ++ 0x75, 0x65, 0x34, 0x49, 0x63, 0x72, 0x38, 0x30, 0x6B, 0x6E, 0x43, 0x44, 0x67, 0x4B, 0x73, 0x34, 0x71, 0x6C, 0x6C, 0x6F, 0x33, 0x55, 0x43, 0x6B, 0x47, 0x4A, 0x43, 0x79, 0x38, 0x39, 0x55, 0x44, 0x79, 0x69, 0x62, 0x4B, 0x37, 0x39, 0x58, 0x48, ++ 0x34, 0x49, 0x39, 0x54, 0x6A, 0x76, 0x41, 0x41, 0x34, 0x36, 0x6A, 0x74, 0x0A, 0x6E, 0x2F, 0x6D, 0x74, 0x64, 0x2B, 0x41, 0x72, 0x59, 0x30, 0x2B, 0x65, 0x77, 0x2B, 0x34, 0x33, 0x75, 0x33, 0x67, 0x4A, 0x68, 0x4A, 0x36, 0x35, 0x62, 0x76, 0x73, ++ 0x70, 0x6D, 0x5A, 0x44, 0x6F, 0x67, 0x4E, 0x4F, 0x66, 0x4A, 0x41, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, ++ 0x0A, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, 0x69, 0x61, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x4D, 0x54, 0x43, 0x43, 0x41, 0x62, 0x65, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x55, 0x4E, 0x6E, 0x54, 0x68, 0x54, 0x58, 0x78, 0x6C, 0x45, 0x38, 0x6D, 0x73, 0x67, 0x31, 0x55, 0x6C, 0x6F, 0x44, 0x35, ++ 0x53, 0x66, 0x69, 0x39, 0x51, 0x61, 0x4D, 0x63, 0x77, 0x43, 0x67, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x45, 0x41, 0x77, 0x4D, 0x77, 0x57, 0x44, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0A, 0x42, 0x68, ++ 0x4D, 0x43, 0x51, 0x30, 0x34, 0x78, 0x4A, 0x54, 0x41, 0x6A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x48, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x51, 0x58, 0x4E, 0x70, 0x59, 0x53, 0x42, 0x55, 0x5A, 0x57, 0x4E, 0x6F, 0x62, 0x6D, ++ 0x39, 0x73, 0x62, 0x32, 0x64, 0x70, 0x5A, 0x58, 0x4D, 0x73, 0x49, 0x45, 0x6C, 0x75, 0x59, 0x79, 0x34, 0x78, 0x49, 0x6A, 0x41, 0x67, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x47, 0x56, 0x52, 0x79, 0x0A, 0x64, 0x58, 0x4E, 0x30, 0x51, ++ 0x58, 0x4E, 0x70, 0x59, 0x53, 0x42, 0x55, 0x54, 0x46, 0x4D, 0x67, 0x52, 0x55, 0x4E, 0x44, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x6A, 0x51, 0x77, 0x4E, 0x54, 0x45, 0x31, 0x4D, ++ 0x44, 0x55, 0x30, 0x4D, 0x54, 0x55, 0x32, 0x57, 0x68, 0x63, 0x4E, 0x4E, 0x44, 0x51, 0x77, 0x4E, 0x54, 0x45, 0x31, 0x4D, 0x44, 0x55, 0x30, 0x4D, 0x54, 0x55, 0x31, 0x57, 0x6A, 0x42, 0x59, 0x0A, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, ++ 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x44, 0x54, 0x6A, 0x45, 0x6C, 0x4D, 0x43, 0x4D, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x63, 0x56, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x52, 0x42, 0x63, 0x32, 0x6C, 0x68, 0x49, 0x46, 0x52, 0x6C, ++ 0x59, 0x32, 0x68, 0x75, 0x62, 0x32, 0x78, 0x76, 0x5A, 0x32, 0x6C, 0x6C, 0x63, 0x79, 0x77, 0x67, 0x53, 0x57, 0x35, 0x6A, 0x4C, 0x6A, 0x45, 0x69, 0x4D, 0x43, 0x41, 0x47, 0x0A, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x5A, 0x56, 0x48, 0x4A, ++ 0x31, 0x63, 0x33, 0x52, 0x42, 0x63, 0x32, 0x6C, 0x68, 0x49, 0x46, 0x52, 0x4D, 0x55, 0x79, 0x42, 0x46, 0x51, 0x30, 0x4D, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x54, 0x42, 0x32, 0x4D, 0x42, 0x41, 0x47, 0x42, 0x79, 0x71, ++ 0x47, 0x53, 0x4D, 0x34, 0x39, 0x41, 0x67, 0x45, 0x47, 0x42, 0x53, 0x75, 0x42, 0x42, 0x41, 0x41, 0x69, 0x41, 0x32, 0x49, 0x41, 0x42, 0x4C, 0x68, 0x2F, 0x0A, 0x70, 0x56, 0x73, 0x2F, 0x41, 0x54, 0x35, 0x39, 0x38, 0x49, 0x68, 0x74, 0x72, 0x69, ++ 0x6D, 0x59, 0x34, 0x5A, 0x74, 0x63, 0x55, 0x35, 0x6E, 0x62, 0x39, 0x77, 0x6A, 0x2F, 0x31, 0x57, 0x72, 0x67, 0x6A, 0x73, 0x74, 0x45, 0x70, 0x76, 0x44, 0x42, 0x6A, 0x4C, 0x31, 0x50, 0x31, 0x4D, 0x37, 0x55, 0x69, 0x46, 0x50, 0x6F, 0x58, 0x6C, ++ 0x66, 0x58, 0x54, 0x72, 0x34, 0x73, 0x50, 0x2F, 0x4D, 0x53, 0x70, 0x77, 0x44, 0x70, 0x67, 0x75, 0x4D, 0x71, 0x57, 0x7A, 0x4A, 0x38, 0x0A, 0x53, 0x35, 0x73, 0x55, 0x4B, 0x5A, 0x37, 0x34, 0x4C, 0x59, 0x4F, 0x31, 0x36, 0x34, 0x34, 0x78, 0x53, ++ 0x54, 0x30, 0x6D, 0x59, 0x65, 0x6B, 0x64, 0x63, 0x6F, 0x75, 0x4A, 0x74, 0x67, 0x71, 0x37, 0x6E, 0x44, 0x4D, 0x31, 0x44, 0x39, 0x72, 0x73, 0x33, 0x71, 0x6C, 0x4B, 0x48, 0x38, 0x6B, 0x7A, 0x73, 0x61, 0x4E, 0x43, 0x4D, 0x45, 0x41, 0x77, 0x44, ++ 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x0A, 0x2F, 0x7A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x4C, 0x49, 0x56, 0x54, ++ 0x75, 0x37, 0x46, 0x44, 0x7A, 0x54, 0x4C, 0x71, 0x6E, 0x71, 0x4F, 0x48, 0x2F, 0x71, 0x4B, 0x59, 0x71, 0x4B, 0x61, 0x54, 0x36, 0x52, 0x41, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, ++ 0x41, 0x67, 0x45, 0x47, 0x4D, 0x41, 0x6F, 0x47, 0x43, 0x43, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x0A, 0x42, 0x41, 0x4D, 0x44, 0x41, 0x32, 0x67, 0x41, 0x4D, 0x47, 0x55, 0x43, 0x4D, 0x46, 0x52, 0x48, 0x31, 0x38, 0x4D, 0x74, 0x59, 0x59, 0x5A, ++ 0x49, 0x39, 0x48, 0x6C, 0x61, 0x56, 0x51, 0x30, 0x31, 0x4C, 0x31, 0x38, 0x4E, 0x39, 0x6D, 0x64, 0x73, 0x64, 0x30, 0x41, 0x61, 0x52, 0x75, 0x66, 0x34, 0x61, 0x46, 0x74, 0x4F, 0x4A, 0x78, 0x32, 0x34, 0x6D, 0x48, 0x31, 0x2F, 0x6B, 0x37, 0x38, ++ 0x49, 0x54, 0x63, 0x54, 0x61, 0x52, 0x54, 0x43, 0x68, 0x44, 0x31, 0x35, 0x4B, 0x0A, 0x65, 0x41, 0x49, 0x78, 0x41, 0x4B, 0x4F, 0x52, 0x68, 0x2F, 0x49, 0x52, 0x4D, 0x34, 0x50, 0x44, 0x77, 0x59, 0x71, 0x52, 0x4F, 0x6B, 0x77, 0x72, 0x55, 0x4C, ++ 0x47, 0x39, 0x49, 0x70, 0x52, 0x64, 0x4E, 0x59, 0x6C, 0x7A, 0x67, 0x38, 0x57, 0x62, 0x47, 0x66, 0x36, 0x30, 0x6F, 0x65, 0x6E, 0x55, 0x6F, 0x57, 0x61, 0x32, 0x41, 0x61, 0x55, 0x32, 0x2B, 0x64, 0x68, 0x6F, 0x59, 0x53, 0x69, 0x33, 0x64, 0x4F, ++ 0x47, 0x69, 0x4D, 0x51, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, ++ 0x73, 0x69, 0x61, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x67, 0x44, ++ 0x43, 0x43, 0x41, 0x32, 0x69, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x55, 0x48, 0x42, 0x6A, 0x59, 0x7A, 0x2B, 0x56, 0x54, 0x50, 0x79, 0x49, 0x31, 0x52, 0x6C, 0x4E, 0x55, 0x4A, 0x44, 0x78, 0x73, 0x52, 0x39, 0x46, 0x63, 0x53, 0x70, ++ 0x77, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4D, 0x42, 0x51, 0x41, 0x77, 0x57, 0x44, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x0A, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x51, ++ 0x30, 0x34, 0x78, 0x4A, 0x54, 0x41, 0x6A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x48, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x51, 0x58, 0x4E, 0x70, 0x59, 0x53, 0x42, 0x55, 0x5A, 0x57, 0x4E, 0x6F, 0x62, 0x6D, 0x39, 0x73, 0x62, ++ 0x32, 0x64, 0x70, 0x5A, 0x58, 0x4D, 0x73, 0x49, 0x45, 0x6C, 0x75, 0x59, 0x79, 0x34, 0x78, 0x49, 0x6A, 0x41, 0x67, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x0A, 0x47, 0x56, 0x52, 0x79, 0x64, 0x58, 0x4E, 0x30, 0x51, 0x58, 0x4E, 0x70, ++ 0x59, 0x53, 0x42, 0x55, 0x54, 0x46, 0x4D, 0x67, 0x55, 0x6C, 0x4E, 0x42, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x6A, 0x51, 0x77, 0x4E, 0x54, 0x45, 0x31, 0x4D, 0x44, 0x55, 0x30, ++ 0x4D, 0x54, 0x55, 0x33, 0x57, 0x68, 0x63, 0x4E, 0x4E, 0x44, 0x51, 0x77, 0x4E, 0x54, 0x45, 0x31, 0x4D, 0x44, 0x55, 0x30, 0x4D, 0x54, 0x55, 0x32, 0x0A, 0x57, 0x6A, 0x42, 0x59, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, ++ 0x47, 0x45, 0x77, 0x4A, 0x44, 0x54, 0x6A, 0x45, 0x6C, 0x4D, 0x43, 0x4D, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x63, 0x56, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x52, 0x42, 0x63, 0x32, 0x6C, 0x68, 0x49, 0x46, 0x52, 0x6C, 0x59, 0x32, 0x68, ++ 0x75, 0x62, 0x32, 0x78, 0x76, 0x5A, 0x32, 0x6C, 0x6C, 0x63, 0x79, 0x77, 0x67, 0x53, 0x57, 0x35, 0x6A, 0x4C, 0x6A, 0x45, 0x69, 0x0A, 0x4D, 0x43, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x5A, 0x56, 0x48, 0x4A, 0x31, 0x63, 0x33, ++ 0x52, 0x42, 0x63, 0x32, 0x6C, 0x68, 0x49, 0x46, 0x52, 0x4D, 0x55, 0x79, 0x42, 0x53, 0x55, 0x30, 0x45, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x54, 0x43, 0x43, 0x41, 0x69, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, ++ 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x50, 0x0A, 0x41, 0x44, 0x43, 0x43, 0x41, 0x67, 0x6F, 0x43, 0x67, 0x67, 0x49, 0x42, 0x41, 0x4D, 0x4D, 0x57, 0x75, 0x42, 0x74, 0x71, 0x70, ++ 0x45, 0x52, 0x7A, 0x35, 0x64, 0x5A, 0x4F, 0x39, 0x4C, 0x6E, 0x50, 0x57, 0x77, 0x76, 0x42, 0x30, 0x5A, 0x71, 0x42, 0x39, 0x57, 0x4F, 0x77, 0x6A, 0x30, 0x50, 0x42, 0x75, 0x77, 0x68, 0x61, 0x47, 0x6E, 0x72, 0x68, 0x42, 0x33, 0x59, 0x6D, 0x48, ++ 0x34, 0x39, 0x70, 0x56, 0x72, 0x37, 0x2B, 0x4E, 0x6D, 0x44, 0x51, 0x44, 0x49, 0x50, 0x4E, 0x0A, 0x6C, 0x4F, 0x72, 0x6E, 0x78, 0x53, 0x31, 0x63, 0x4C, 0x77, 0x55, 0x57, 0x41, 0x70, 0x34, 0x4B, 0x71, 0x43, 0x2F, 0x6C, 0x59, 0x43, 0x5A, 0x55, ++ 0x6C, 0x76, 0x69, 0x59, 0x51, 0x42, 0x32, 0x73, 0x72, 0x70, 0x31, 0x30, 0x5A, 0x79, 0x39, 0x55, 0x2B, 0x35, 0x52, 0x6A, 0x6D, 0x4F, 0x4D, 0x6D, 0x53, 0x6F, 0x50, 0x47, 0x6C, 0x62, 0x59, 0x4A, 0x51, 0x31, 0x44, 0x4E, 0x44, 0x58, 0x33, 0x65, ++ 0x52, 0x41, 0x35, 0x67, 0x45, 0x6B, 0x39, 0x62, 0x4E, 0x62, 0x32, 0x2F, 0x0A, 0x6D, 0x54, 0x68, 0x74, 0x66, 0x57, 0x7A, 0x61, 0x34, 0x6D, 0x68, 0x7A, 0x48, 0x2F, 0x6B, 0x78, 0x70, 0x52, 0x6B, 0x51, 0x63, 0x77, 0x55, 0x71, 0x77, 0x7A, 0x49, ++ 0x5A, 0x68, 0x65, 0x6F, 0x30, 0x71, 0x74, 0x31, 0x43, 0x48, 0x6A, 0x43, 0x4E, 0x50, 0x35, 0x36, 0x31, 0x48, 0x6D, 0x48, 0x56, 0x62, 0x37, 0x30, 0x41, 0x63, 0x6E, 0x4B, 0x74, 0x45, 0x6A, 0x2B, 0x71, 0x70, 0x6B, 0x6C, 0x7A, 0x38, 0x6F, 0x59, ++ 0x56, 0x6C, 0x51, 0x77, 0x51, 0x58, 0x31, 0x46, 0x6B, 0x0A, 0x7A, 0x76, 0x39, 0x33, 0x75, 0x4D, 0x6C, 0x74, 0x72, 0x4F, 0x58, 0x56, 0x6D, 0x50, 0x47, 0x5A, 0x4C, 0x6D, 0x7A, 0x6A, 0x79, 0x55, 0x54, 0x35, 0x74, 0x55, 0x4D, 0x6E, 0x43, 0x45, ++ 0x33, 0x32, 0x66, 0x74, 0x35, 0x45, 0x65, 0x62, 0x75, 0x79, 0x6A, 0x42, 0x7A, 0x61, 0x30, 0x30, 0x74, 0x73, 0x4C, 0x74, 0x62, 0x44, 0x65, 0x4C, 0x64, 0x4D, 0x31, 0x61, 0x54, 0x6B, 0x32, 0x74, 0x79, 0x4B, 0x6A, 0x67, 0x37, 0x2F, 0x44, 0x38, ++ 0x4F, 0x6D, 0x59, 0x43, 0x59, 0x6F, 0x0A, 0x7A, 0x7A, 0x61, 0x2F, 0x2B, 0x6C, 0x63, 0x4B, 0x37, 0x46, 0x73, 0x2F, 0x36, 0x54, 0x41, 0x57, 0x65, 0x38, 0x54, 0x62, 0x78, 0x4E, 0x52, 0x6B, 0x6F, 0x44, 0x44, 0x37, 0x35, 0x66, 0x30, 0x64, 0x63, ++ 0x5A, 0x4C, 0x64, 0x4B, 0x59, 0x39, 0x42, 0x57, 0x4E, 0x34, 0x41, 0x72, 0x54, 0x72, 0x39, 0x50, 0x58, 0x77, 0x61, 0x71, 0x4C, 0x45, 0x58, 0x38, 0x45, 0x34, 0x30, 0x65, 0x46, 0x67, 0x6C, 0x31, 0x6F, 0x55, 0x68, 0x36, 0x33, 0x6B, 0x64, 0x30, ++ 0x4E, 0x79, 0x72, 0x0A, 0x7A, 0x32, 0x49, 0x38, 0x73, 0x4D, 0x65, 0x58, 0x69, 0x39, 0x62, 0x51, 0x6E, 0x39, 0x50, 0x2B, 0x50, 0x4E, 0x37, 0x46, 0x34, 0x2F, 0x77, 0x36, 0x67, 0x33, 0x43, 0x45, 0x49, 0x52, 0x30, 0x4A, 0x77, 0x71, 0x48, 0x38, ++ 0x75, 0x79, 0x67, 0x68, 0x5A, 0x56, 0x4E, 0x67, 0x65, 0x70, 0x42, 0x74, 0x6C, 0x6A, 0x68, 0x62, 0x2F, 0x2F, 0x48, 0x58, 0x65, 0x6C, 0x74, 0x74, 0x30, 0x38, 0x6C, 0x77, 0x53, 0x55, 0x71, 0x36, 0x48, 0x54, 0x72, 0x51, 0x55, 0x4E, 0x6F, 0x79, ++ 0x0A, 0x49, 0x42, 0x6E, 0x6B, 0x69, 0x7A, 0x2F, 0x72, 0x31, 0x52, 0x59, 0x6D, 0x4E, 0x7A, 0x7A, 0x37, 0x64, 0x5A, 0x36, 0x77, 0x42, 0x33, 0x43, 0x34, 0x46, 0x47, 0x42, 0x33, 0x33, 0x50, 0x59, 0x50, 0x58, 0x46, 0x49, 0x4B, 0x76, 0x46, 0x31, ++ 0x74, 0x6A, 0x56, 0x45, 0x4B, 0x32, 0x73, 0x55, 0x59, 0x79, 0x4A, 0x74, 0x74, 0x33, 0x4C, 0x43, 0x44, 0x73, 0x33, 0x2B, 0x6A, 0x54, 0x6E, 0x68, 0x4D, 0x6D, 0x43, 0x57, 0x72, 0x38, 0x6E, 0x34, 0x75, 0x49, 0x46, 0x36, 0x43, 0x0A, 0x46, 0x61, ++ 0x62, 0x57, 0x32, 0x49, 0x2B, 0x73, 0x35, 0x63, 0x30, 0x79, 0x68, 0x73, 0x6A, 0x35, 0x35, 0x4E, 0x71, 0x4A, 0x34, 0x6A, 0x73, 0x2B, 0x6B, 0x38, 0x55, 0x54, 0x61, 0x76, 0x2F, 0x48, 0x39, 0x78, 0x6A, 0x38, 0x5A, 0x37, 0x58, 0x76, 0x47, 0x43, ++ 0x78, 0x55, 0x71, 0x30, 0x44, 0x54, 0x62, 0x45, 0x33, 0x74, 0x78, 0x63, 0x69, 0x33, 0x4F, 0x45, 0x39, 0x6B, 0x78, 0x4A, 0x52, 0x4D, 0x54, 0x36, 0x44, 0x4E, 0x72, 0x71, 0x58, 0x47, 0x4A, 0x79, 0x56, 0x31, 0x0A, 0x4A, 0x32, 0x33, 0x47, 0x32, ++ 0x70, 0x79, 0x4F, 0x73, 0x41, 0x57, 0x5A, 0x31, 0x53, 0x67, 0x52, 0x78, 0x53, 0x48, 0x55, 0x75, 0x50, 0x7A, 0x48, 0x6C, 0x71, 0x74, 0x4B, 0x5A, 0x46, 0x6C, 0x68, 0x61, 0x78, 0x50, 0x38, 0x53, 0x38, 0x79, 0x53, 0x70, 0x67, 0x2B, 0x6B, 0x55, ++ 0x62, 0x38, 0x4F, 0x57, 0x4A, 0x44, 0x5A, 0x67, 0x6F, 0x4D, 0x35, 0x70, 0x6C, 0x2B, 0x7A, 0x2B, 0x6D, 0x36, 0x53, 0x73, 0x38, 0x30, 0x7A, 0x44, 0x6F, 0x57, 0x6F, 0x38, 0x53, 0x6E, 0x54, 0x0A, 0x71, 0x31, 0x6D, 0x74, 0x31, 0x74, 0x76, 0x65, ++ 0x31, 0x43, 0x75, 0x42, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, 0x51, 0x6A, 0x42, 0x41, 0x4D, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, ++ 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x46, 0x4C, 0x67, 0x48, 0x6B, 0x58, 0x6C, 0x63, 0x42, 0x76, 0x52, 0x47, 0x2F, 0x58, 0x74, 0x5A, 0x0A, 0x79, 0x6C, 0x6F, 0x6D, 0x6B, 0x61, 0x64, 0x46, 0x4B, 0x2F, 0x68, ++ 0x54, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x77, ++ 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x67, 0x45, 0x41, 0x49, 0x5A, 0x74, 0x71, 0x42, 0x53, 0x42, 0x64, 0x47, 0x42, 0x61, 0x6E, 0x45, 0x71, 0x54, 0x33, 0x0A, 0x52, 0x7A, 0x2F, 0x4E, 0x79, 0x6A, 0x75, 0x75, 0x6A, 0x73, 0x43, 0x43, 0x7A, 0x74, ++ 0x78, 0x49, 0x4A, 0x58, 0x67, 0x58, 0x62, 0x4F, 0x44, 0x67, 0x63, 0x4D, 0x54, 0x57, 0x6C, 0x74, 0x6E, 0x5A, 0x39, 0x72, 0x39, 0x36, 0x6E, 0x42, 0x4F, 0x37, 0x55, 0x35, 0x57, 0x53, 0x2F, 0x38, 0x2B, 0x53, 0x34, 0x50, 0x50, 0x46, 0x4A, 0x7A, ++ 0x56, 0x58, 0x71, 0x44, 0x75, 0x69, 0x47, 0x65, 0x76, 0x34, 0x69, 0x71, 0x4D, 0x45, 0x33, 0x6D, 0x6D, 0x4C, 0x35, 0x44, 0x77, 0x38, 0x0A, 0x76, 0x65, 0x57, 0x76, 0x30, 0x42, 0x49, 0x62, 0x35, 0x59, 0x6C, 0x72, 0x63, 0x35, 0x74, 0x76, 0x4A, ++ 0x51, 0x4A, 0x4C, 0x6B, 0x49, 0x4B, 0x76, 0x51, 0x4D, 0x4B, 0x74, 0x75, 0x70, 0x70, 0x67, 0x4A, 0x46, 0x71, 0x42, 0x54, 0x51, 0x55, 0x59, 0x6F, 0x2B, 0x49, 0x7A, 0x65, 0x58, 0x6F, 0x4C, 0x48, 0x35, 0x50, 0x74, 0x37, 0x44, 0x6C, 0x4B, 0x39, ++ 0x52, 0x4D, 0x45, 0x37, 0x49, 0x31, 0x30, 0x6E, 0x59, 0x45, 0x4B, 0x71, 0x47, 0x2F, 0x6F, 0x64, 0x76, 0x36, 0x4C, 0x0A, 0x54, 0x79, 0x74, 0x70, 0x45, 0x6F, 0x59, 0x4B, 0x4E, 0x44, 0x62, 0x64, 0x67, 0x70, 0x74, 0x76, 0x54, 0x2B, 0x42, 0x7A, ++ 0x33, 0x55, 0x6C, 0x2F, 0x4B, 0x44, 0x37, 0x4A, 0x4F, 0x36, 0x4E, 0x58, 0x42, 0x4E, 0x69, 0x54, 0x32, 0x54, 0x77, 0x70, 0x32, 0x78, 0x49, 0x51, 0x61, 0x4F, 0x48, 0x45, 0x69, 0x62, 0x67, 0x47, 0x49, 0x4F, 0x63, 0x62, 0x65, 0x72, 0x79, 0x78, ++ 0x6B, 0x32, 0x47, 0x61, 0x47, 0x55, 0x41, 0x52, 0x74, 0x57, 0x71, 0x46, 0x56, 0x77, 0x48, 0x78, 0x0A, 0x74, 0x6C, 0x6F, 0x74, 0x4A, 0x6E, 0x4D, 0x6E, 0x6C, 0x76, 0x6D, 0x35, 0x50, 0x31, 0x76, 0x51, 0x69, 0x4A, 0x33, 0x6B, 0x6F, 0x50, 0x32, ++ 0x36, 0x54, 0x70, 0x55, 0x4A, 0x67, 0x33, 0x39, 0x33, 0x33, 0x46, 0x45, 0x46, 0x6C, 0x4A, 0x30, 0x67, 0x63, 0x58, 0x61, 0x78, 0x37, 0x50, 0x71, 0x4A, 0x74, 0x5A, 0x77, 0x75, 0x68, 0x66, 0x47, 0x35, 0x57, 0x79, 0x52, 0x61, 0x73, 0x51, 0x6D, ++ 0x72, 0x32, 0x73, 0x6F, 0x61, 0x42, 0x38, 0x32, 0x47, 0x33, 0x39, 0x74, 0x70, 0x0A, 0x32, 0x37, 0x52, 0x49, 0x47, 0x41, 0x41, 0x74, 0x76, 0x4B, 0x4C, 0x45, 0x69, 0x55, 0x55, 0x6A, 0x70, 0x51, 0x37, 0x68, 0x52, 0x47, 0x55, 0x2B, 0x69, 0x73, ++ 0x46, 0x71, 0x4D, 0x42, 0x33, 0x69, 0x59, 0x50, 0x67, 0x36, 0x71, 0x6F, 0x63, 0x4A, 0x51, 0x72, 0x6D, 0x42, 0x6B, 0x74, 0x77, 0x6C, 0x69, 0x4A, 0x69, 0x4A, 0x38, 0x58, 0x77, 0x31, 0x38, 0x57, 0x4C, 0x4B, 0x37, 0x6E, 0x6E, 0x34, 0x47, 0x53, ++ 0x2F, 0x2B, 0x58, 0x2F, 0x6A, 0x62, 0x68, 0x38, 0x37, 0x71, 0x0A, 0x71, 0x41, 0x38, 0x4D, 0x70, 0x75, 0x67, 0x4C, 0x6F, 0x44, 0x7A, 0x67, 0x61, 0x35, 0x53, 0x59, 0x6E, 0x48, 0x2B, 0x74, 0x42, 0x75, 0x59, 0x63, 0x36, 0x6B, 0x49, 0x51, 0x58, ++ 0x2B, 0x49, 0x6D, 0x46, 0x54, 0x77, 0x33, 0x4F, 0x66, 0x66, 0x58, 0x76, 0x4F, 0x36, 0x34, 0x35, 0x65, 0x38, 0x44, 0x37, 0x72, 0x30, 0x69, 0x2B, 0x79, 0x69, 0x47, 0x4E, 0x46, 0x6A, 0x45, 0x57, 0x6E, 0x39, 0x68, 0x6F, 0x6E, 0x67, 0x50, 0x58, ++ 0x76, 0x50, 0x4B, 0x6E, 0x62, 0x77, 0x62, 0x0A, 0x50, 0x4B, 0x66, 0x49, 0x4C, 0x66, 0x61, 0x6E, 0x49, 0x68, 0x48, 0x4B, 0x41, 0x39, 0x6A, 0x6E, 0x5A, 0x77, 0x71, 0x4B, 0x44, 0x73, 0x73, 0x31, 0x6A, 0x6A, 0x51, 0x35, 0x32, 0x4D, 0x6A, 0x71, ++ 0x6A, 0x5A, 0x39, 0x6B, 0x34, 0x44, 0x65, 0x77, 0x62, 0x4E, 0x66, 0x46, 0x6A, 0x38, 0x47, 0x51, 0x59, 0x53, 0x62, 0x62, 0x4A, 0x49, 0x77, 0x65, 0x53, 0x73, 0x43, 0x49, 0x33, 0x7A, 0x57, 0x51, 0x7A, 0x6A, 0x38, 0x43, 0x39, 0x47, 0x52, 0x68, ++ 0x33, 0x73, 0x66, 0x49, 0x0A, 0x42, 0x35, 0x58, 0x65, 0x4D, 0x68, 0x67, 0x36, 0x6A, 0x36, 0x4A, 0x43, 0x51, 0x43, 0x54, 0x6C, 0x31, 0x6A, 0x4E, 0x64, 0x66, 0x4B, 0x37, 0x76, 0x73, 0x55, 0x31, 0x50, 0x31, 0x46, 0x65, 0x51, 0x4E, 0x57, 0x72, ++ 0x63, 0x72, 0x67, 0x53, 0x58, 0x53, 0x59, 0x6B, 0x30, 0x6C, 0x79, 0x34, 0x77, 0x42, 0x4F, 0x65, 0x59, 0x39, 0x39, 0x73, 0x4C, 0x41, 0x5A, 0x44, 0x42, 0x48, 0x77, 0x6F, 0x2F, 0x2B, 0x4D, 0x4C, 0x2B, 0x54, 0x76, 0x72, 0x62, 0x6D, 0x6E, 0x4E, ++ 0x7A, 0x0A, 0x46, 0x72, 0x77, 0x46, 0x75, 0x48, 0x6E, 0x59, 0x57, 0x61, 0x38, 0x47, 0x35, 0x7A, 0x39, 0x6E, 0x4F, 0x44, 0x6D, 0x78, 0x66, 0x4B, 0x75, 0x55, 0x34, 0x43, 0x6B, 0x55, 0x70, 0x69, 0x6A, 0x79, 0x33, 0x32, 0x33, 0x69, 0x6D, 0x74, ++ 0x74, 0x55, 0x51, 0x2F, 0x68, 0x48, 0x57, 0x4B, 0x4E, 0x64, 0x64, 0x42, 0x57, 0x63, 0x77, 0x61, 0x75, 0x77, 0x78, 0x7A, 0x51, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, ++ 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, 0x32, 0x30, 0x32, 0x33, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, ++ 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x71, 0x54, 0x43, 0x43, 0x41, 0x35, 0x47, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x61, 0x53, 0x59, 0x4A, 0x66, 0x6F, 0x42, 0x4C, 0x54, 0x4B, ++ 0x43, 0x6E, 0x6A, 0x48, 0x68, 0x69, 0x55, 0x31, 0x39, 0x61, 0x62, 0x7A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x30, 0x46, 0x41, 0x44, 0x42, 0x49, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, ++ 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0A, 0x45, 0x77, 0x4A, 0x45, 0x52, 0x54, 0x45, 0x56, 0x4D, 0x42, 0x4D, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4D, 0x4D, 0x52, 0x43, 0x31, 0x55, 0x63, 0x6E, 0x56, 0x7A, 0x64, 0x43, 0x42, 0x48, 0x62, ++ 0x57, 0x4A, 0x49, 0x4D, 0x53, 0x49, 0x77, 0x49, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x6C, 0x45, 0x4C, 0x56, 0x52, 0x53, 0x56, 0x56, 0x4E, 0x55, 0x49, 0x45, 0x56, 0x57, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, ++ 0x30, 0x45, 0x67, 0x0A, 0x4D, 0x69, 0x41, 0x79, 0x4D, 0x44, 0x49, 0x7A, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x49, 0x7A, 0x4D, 0x44, 0x55, 0x77, 0x4F, 0x54, 0x41, 0x35, 0x4D, 0x54, 0x41, 0x7A, 0x4D, 0x31, 0x6F, 0x58, 0x44, 0x54, 0x4D, 0x34, ++ 0x4D, 0x44, 0x55, 0x77, 0x4F, 0x54, 0x41, 0x35, 0x4D, 0x54, 0x41, 0x7A, 0x4D, 0x6C, 0x6F, 0x77, 0x53, 0x44, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x52, 0x45, 0x55, 0x78, 0x46, 0x54, 0x41, 0x54, ++ 0x0A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x54, 0x44, 0x45, 0x51, 0x74, 0x56, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x51, 0x67, 0x52, 0x32, 0x31, 0x69, 0x53, 0x44, 0x45, 0x69, 0x4D, 0x43, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, ++ 0x5A, 0x52, 0x43, 0x31, 0x55, 0x55, 0x6C, 0x56, 0x54, 0x56, 0x43, 0x42, 0x46, 0x56, 0x69, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4E, 0x42, 0x49, 0x44, 0x49, 0x67, 0x4D, 0x6A, 0x41, 0x79, 0x4D, 0x7A, 0x43, 0x43, 0x0A, 0x41, 0x69, ++ 0x49, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x67, 0x6F, 0x43, 0x67, 0x67, 0x49, 0x42, 0x41, 0x4E, ++ 0x69, 0x4F, 0x6F, 0x34, 0x6D, 0x41, 0x43, 0x37, 0x4A, 0x58, 0x55, 0x74, 0x79, 0x70, 0x55, 0x30, 0x77, 0x33, 0x75, 0x58, 0x39, 0x6A, 0x46, 0x78, 0x50, 0x76, 0x70, 0x31, 0x73, 0x6A, 0x57, 0x32, 0x6C, 0x31, 0x0A, 0x73, 0x4A, 0x6B, 0x4B, 0x46, ++ 0x38, 0x47, 0x4C, 0x78, 0x4E, 0x75, 0x6F, 0x34, 0x4D, 0x77, 0x78, 0x75, 0x73, 0x4C, 0x79, 0x7A, 0x56, 0x33, 0x70, 0x74, 0x2F, 0x67, 0x64, 0x72, 0x32, 0x72, 0x45, 0x6C, 0x59, 0x66, 0x58, 0x52, 0x38, 0x6D, 0x56, 0x32, 0x49, 0x49, 0x45, 0x55, ++ 0x44, 0x32, 0x42, 0x43, 0x50, 0x2F, 0x6B, 0x50, 0x62, 0x4F, 0x78, 0x31, 0x73, 0x57, 0x79, 0x2F, 0x59, 0x67, 0x4A, 0x32, 0x35, 0x79, 0x45, 0x37, 0x43, 0x55, 0x58, 0x46, 0x49, 0x64, 0x2F, 0x0A, 0x4D, 0x48, 0x69, 0x62, 0x61, 0x6C, 0x6A, 0x4A, ++ 0x74, 0x6E, 0x4D, 0x6F, 0x50, 0x44, 0x54, 0x33, 0x6D, 0x66, 0x64, 0x2F, 0x30, 0x36, 0x62, 0x34, 0x48, 0x45, 0x56, 0x38, 0x72, 0x53, 0x79, 0x4D, 0x6C, 0x44, 0x2F, 0x59, 0x5A, 0x78, 0x42, 0x54, 0x66, 0x69, 0x4C, 0x4E, 0x54, 0x69, 0x56, 0x52, ++ 0x38, 0x43, 0x55, 0x6B, 0x4E, 0x52, 0x46, 0x65, 0x45, 0x4D, 0x62, 0x73, 0x68, 0x32, 0x61, 0x4A, 0x67, 0x57, 0x69, 0x36, 0x7A, 0x43, 0x75, 0x64, 0x52, 0x33, 0x4D, 0x66, 0x0A, 0x76, 0x63, 0x32, 0x52, 0x70, 0x48, 0x4A, 0x71, 0x6E, 0x4B, 0x49, ++ 0x62, 0x47, 0x4B, 0x42, 0x76, 0x37, 0x46, 0x44, 0x30, 0x66, 0x55, 0x44, 0x43, 0x71, 0x44, 0x44, 0x50, 0x76, 0x58, 0x50, 0x49, 0x45, 0x79, 0x73, 0x51, 0x45, 0x78, 0x36, 0x4C, 0x6D, 0x71, 0x67, 0x36, 0x6C, 0x48, 0x50, 0x54, 0x47, 0x47, 0x6B, ++ 0x4B, 0x53, 0x76, 0x2F, 0x42, 0x41, 0x51, 0x50, 0x2F, 0x65, 0x58, 0x2B, 0x31, 0x53, 0x48, 0x39, 0x37, 0x37, 0x75, 0x67, 0x70, 0x62, 0x7A, 0x5A, 0x4D, 0x0A, 0x6C, 0x57, 0x47, 0x47, 0x32, 0x50, 0x6D, 0x69, 0x63, 0x34, 0x72, 0x75, 0x72, 0x69, ++ 0x2B, 0x57, 0x37, 0x6D, 0x6A, 0x4E, 0x50, 0x55, 0x30, 0x6F, 0x51, 0x76, 0x6C, 0x46, 0x4B, 0x7A, 0x49, 0x62, 0x52, 0x6C, 0x55, 0x57, 0x61, 0x71, 0x5A, 0x4C, 0x4B, 0x66, 0x6D, 0x37, 0x6C, 0x56, 0x61, 0x2F, 0x52, 0x68, 0x33, 0x73, 0x48, 0x5A, ++ 0x4D, 0x64, 0x77, 0x47, 0x57, 0x79, 0x48, 0x36, 0x46, 0x44, 0x72, 0x6C, 0x61, 0x65, 0x6F, 0x4C, 0x47, 0x50, 0x61, 0x78, 0x4B, 0x33, 0x0A, 0x59, 0x47, 0x31, 0x34, 0x43, 0x38, 0x71, 0x4B, 0x58, 0x4F, 0x30, 0x65, 0x6C, 0x67, 0x36, 0x44, 0x70, ++ 0x6B, 0x69, 0x56, 0x6A, 0x54, 0x75, 0x6A, 0x49, 0x63, 0x53, 0x75, 0x57, 0x4D, 0x59, 0x41, 0x73, 0x6F, 0x53, 0x30, 0x49, 0x36, 0x53, 0x57, 0x68, 0x6A, 0x57, 0x34, 0x32, 0x4A, 0x37, 0x59, 0x72, 0x44, 0x52, 0x4A, 0x6D, 0x47, 0x4F, 0x56, 0x78, ++ 0x63, 0x74, 0x74, 0x53, 0x45, 0x66, 0x69, 0x38, 0x69, 0x34, 0x59, 0x48, 0x74, 0x41, 0x78, 0x71, 0x39, 0x31, 0x30, 0x0A, 0x37, 0x50, 0x6E, 0x63, 0x6A, 0x4C, 0x67, 0x63, 0x6A, 0x6D, 0x67, 0x6A, 0x75, 0x74, 0x44, 0x7A, 0x55, 0x4E, 0x7A, 0x50, ++ 0x5A, 0x59, 0x39, 0x7A, 0x4F, 0x6A, 0x4C, 0x48, 0x66, 0x50, 0x37, 0x4B, 0x67, 0x69, 0x4A, 0x50, 0x76, 0x6F, 0x35, 0x69, 0x52, 0x32, 0x62, 0x6C, 0x7A, 0x59, 0x66, 0x69, 0x36, 0x4E, 0x55, 0x50, 0x47, 0x4A, 0x2F, 0x6C, 0x42, 0x48, 0x4A, 0x4C, ++ 0x52, 0x6A, 0x77, 0x51, 0x38, 0x6B, 0x54, 0x43, 0x5A, 0x46, 0x5A, 0x78, 0x54, 0x6E, 0x58, 0x6F, 0x0A, 0x6E, 0x4D, 0x6B, 0x6D, 0x64, 0x4D, 0x56, 0x39, 0x57, 0x64, 0x45, 0x4B, 0x57, 0x77, 0x39, 0x74, 0x2F, 0x70, 0x35, 0x31, 0x48, 0x42, 0x6A, ++ 0x47, 0x47, 0x6A, 0x70, 0x38, 0x32, 0x41, 0x30, 0x45, 0x7A, 0x4D, 0x32, 0x33, 0x52, 0x57, 0x56, 0x36, 0x73, 0x59, 0x2B, 0x34, 0x72, 0x6F, 0x52, 0x49, 0x50, 0x72, 0x4E, 0x36, 0x54, 0x61, 0x67, 0x44, 0x34, 0x75, 0x4A, 0x2B, 0x41, 0x52, 0x5A, ++ 0x5A, 0x61, 0x42, 0x68, 0x44, 0x4D, 0x37, 0x44, 0x53, 0x33, 0x4C, 0x41, 0x61, 0x0A, 0x51, 0x7A, 0x58, 0x75, 0x70, 0x64, 0x71, 0x70, 0x52, 0x6C, 0x79, 0x75, 0x68, 0x6F, 0x46, 0x42, 0x41, 0x55, 0x70, 0x30, 0x4A, 0x75, 0x79, 0x66, 0x42, 0x72, ++ 0x2F, 0x43, 0x42, 0x54, 0x64, 0x6B, 0x64, 0x58, 0x67, 0x70, 0x61, 0x50, 0x33, 0x46, 0x39, 0x65, 0x76, 0x2B, 0x52, 0x2F, 0x6E, 0x6B, 0x68, 0x62, 0x44, 0x68, 0x65, 0x7A, 0x47, 0x64, 0x70, 0x6E, 0x39, 0x79, 0x6F, 0x37, 0x6E, 0x45, 0x4C, 0x43, ++ 0x37, 0x4D, 0x6D, 0x56, 0x63, 0x4F, 0x49, 0x51, 0x78, 0x46, 0x0A, 0x41, 0x5A, 0x52, 0x6C, 0x36, 0x32, 0x55, 0x4A, 0x78, 0x6D, 0x4D, 0x69, 0x43, 0x7A, 0x4E, 0x4A, 0x6B, 0x6B, 0x67, 0x38, 0x2F, 0x4D, 0x33, 0x4F, 0x73, 0x44, 0x36, 0x4F, 0x6E, ++ 0x6F, 0x76, 0x34, 0x2F, 0x6B, 0x6E, 0x46, 0x4E, 0x58, 0x4A, 0x48, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, 0x67, 0x59, 0x34, 0x77, 0x67, 0x59, 0x73, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, ++ 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x0A, 0x2F, 0x7A, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x71, 0x76, 0x79, 0x52, 0x45, 0x42, 0x75, 0x48, 0x6B, 0x56, 0x38, 0x57, 0x75, 0x62, 0x39, 0x50, ++ 0x53, 0x35, 0x46, 0x65, 0x41, 0x42, 0x79, 0x78, 0x4D, 0x6F, 0x41, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4D, 0x45, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x64, ++ 0x48, 0x77, 0x52, 0x43, 0x0A, 0x4D, 0x45, 0x41, 0x77, 0x50, 0x71, 0x41, 0x38, 0x6F, 0x44, 0x71, 0x47, 0x4F, 0x47, 0x68, 0x30, 0x64, 0x48, 0x41, 0x36, 0x4C, 0x79, 0x39, 0x6A, 0x63, 0x6D, 0x77, 0x75, 0x5A, 0x43, 0x31, 0x30, 0x63, 0x6E, 0x56, ++ 0x7A, 0x64, 0x43, 0x35, 0x75, 0x5A, 0x58, 0x51, 0x76, 0x59, 0x33, 0x4A, 0x73, 0x4C, 0x32, 0x51, 0x74, 0x64, 0x48, 0x4A, 0x31, 0x63, 0x33, 0x52, 0x66, 0x5A, 0x58, 0x5A, 0x66, 0x63, 0x6D, 0x39, 0x76, 0x64, 0x46, 0x39, 0x6A, 0x59, 0x56, 0x38, ++ 0x79, 0x0A, 0x58, 0x7A, 0x49, 0x77, 0x4D, 0x6A, 0x4D, 0x75, 0x59, 0x33, 0x4A, 0x73, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x44, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x41, 0x51, ++ 0x43, 0x54, 0x79, 0x36, 0x55, 0x66, 0x6D, 0x52, 0x48, 0x73, 0x6D, 0x67, 0x31, 0x66, 0x4C, 0x42, 0x57, 0x54, 0x78, 0x6A, 0x2B, 0x2B, 0x45, 0x49, 0x31, 0x34, 0x51, 0x76, 0x42, 0x75, 0x6B, 0x45, 0x64, 0x48, 0x6A, 0x71, 0x4F, 0x53, 0x0A, 0x4D, ++ 0x6F, 0x31, 0x77, 0x6A, 0x2F, 0x5A, 0x62, 0x6A, 0x62, 0x36, 0x4A, 0x7A, 0x6B, 0x63, 0x42, 0x61, 0x68, 0x73, 0x67, 0x49, 0x49, 0x6C, 0x62, 0x79, 0x49, 0x49, 0x51, 0x62, 0x4F, 0x44, 0x6E, 0x6D, 0x61, 0x70, 0x72, 0x78, 0x69, 0x71, 0x67, 0x59, ++ 0x7A, 0x57, 0x52, 0x61, 0x6F, 0x55, 0x6C, 0x72, 0x52, 0x63, 0x34, 0x70, 0x5A, 0x74, 0x2B, 0x55, 0x50, 0x4A, 0x32, 0x36, 0x6F, 0x55, 0x46, 0x4B, 0x69, 0x64, 0x42, 0x4B, 0x37, 0x47, 0x42, 0x30, 0x61, 0x4C, 0x32, 0x0A, 0x51, 0x48, 0x57, 0x70, ++ 0x44, 0x73, 0x76, 0x78, 0x56, 0x55, 0x6A, 0x59, 0x37, 0x4E, 0x48, 0x73, 0x73, 0x2B, 0x6A, 0x4F, 0x46, 0x4B, 0x45, 0x31, 0x37, 0x4D, 0x4A, 0x65, 0x4E, 0x52, 0x71, 0x72, 0x70, 0x68, 0x59, 0x42, 0x42, 0x6F, 0x37, 0x71, 0x33, 0x43, 0x2B, 0x6A, ++ 0x69, 0x73, 0x6F, 0x73, 0x6B, 0x65, 0x74, 0x53, 0x6A, 0x6C, 0x38, 0x4D, 0x6D, 0x78, 0x66, 0x50, 0x79, 0x33, 0x4D, 0x48, 0x47, 0x63, 0x52, 0x71, 0x77, 0x6E, 0x4E, 0x55, 0x37, 0x33, 0x78, 0x44, 0x0A, 0x55, 0x6D, 0x50, 0x42, 0x45, 0x63, 0x72, ++ 0x43, 0x52, 0x62, 0x48, 0x30, 0x4F, 0x31, 0x50, 0x31, 0x61, 0x61, 0x34, 0x38, 0x34, 0x36, 0x58, 0x65, 0x72, 0x4F, 0x68, 0x55, 0x74, 0x37, 0x4B, 0x52, 0x2F, 0x61, 0x79, 0x70, 0x48, 0x2F, 0x4B, 0x48, 0x35, 0x42, 0x66, 0x47, 0x53, 0x61, 0x68, ++ 0x38, 0x32, 0x41, 0x70, 0x42, 0x39, 0x50, 0x49, 0x2B, 0x35, 0x33, 0x63, 0x30, 0x42, 0x46, 0x4C, 0x64, 0x36, 0x49, 0x48, 0x79, 0x54, 0x53, 0x39, 0x55, 0x52, 0x5A, 0x30, 0x56, 0x0A, 0x34, 0x55, 0x2F, 0x4D, 0x35, 0x64, 0x34, 0x30, 0x56, 0x78, ++ 0x44, 0x4A, 0x49, 0x33, 0x49, 0x58, 0x63, 0x49, 0x31, 0x51, 0x63, 0x42, 0x39, 0x57, 0x62, 0x4D, 0x79, 0x35, 0x2F, 0x7A, 0x70, 0x61, 0x54, 0x32, 0x4E, 0x36, 0x77, 0x32, 0x35, 0x6C, 0x42, 0x78, 0x32, 0x45, 0x6F, 0x66, 0x2B, 0x70, 0x44, 0x47, ++ 0x4F, 0x4A, 0x62, 0x62, 0x4A, 0x41, 0x69, 0x44, 0x6E, 0x58, 0x48, 0x33, 0x64, 0x6F, 0x74, 0x66, 0x79, 0x63, 0x31, 0x64, 0x5A, 0x6E, 0x61, 0x56, 0x75, 0x6F, 0x0A, 0x64, 0x4E, 0x76, 0x38, 0x69, 0x66, 0x59, 0x62, 0x4D, 0x76, 0x65, 0x6B, 0x4A, ++ 0x4B, 0x5A, 0x32, 0x74, 0x30, 0x64, 0x54, 0x37, 0x34, 0x31, 0x4A, 0x6A, 0x36, 0x6D, 0x32, 0x67, 0x31, 0x71, 0x6C, 0x6C, 0x70, 0x42, 0x46, 0x59, 0x66, 0x58, 0x65, 0x41, 0x30, 0x38, 0x6D, 0x44, 0x36, 0x69, 0x4C, 0x38, 0x41, 0x4F, 0x57, 0x73, ++ 0x4B, 0x77, 0x56, 0x30, 0x48, 0x46, 0x61, 0x61, 0x6E, 0x75, 0x55, 0x35, 0x6E, 0x43, 0x54, 0x32, 0x76, 0x46, 0x70, 0x34, 0x4C, 0x4A, 0x69, 0x0A, 0x54, 0x5A, 0x36, 0x50, 0x2F, 0x34, 0x6D, 0x64, 0x6D, 0x31, 0x33, 0x4E, 0x52, 0x65, 0x6D, 0x55, ++ 0x41, 0x69, 0x4B, 0x4E, 0x34, 0x44, 0x56, 0x2F, 0x36, 0x50, 0x45, 0x45, 0x65, 0x58, 0x46, 0x73, 0x56, 0x49, 0x50, 0x34, 0x4D, 0x37, 0x6B, 0x46, 0x4D, 0x68, 0x74, 0x59, 0x56, 0x52, 0x46, 0x50, 0x30, 0x4F, 0x55, 0x6E, 0x52, 0x33, 0x48, 0x73, ++ 0x37, 0x64, 0x70, 0x6E, 0x31, 0x6D, 0x4B, 0x6D, 0x53, 0x30, 0x30, 0x50, 0x61, 0x61, 0x4C, 0x4A, 0x76, 0x4F, 0x77, 0x69, 0x0A, 0x53, 0x35, 0x54, 0x48, 0x61, 0x4A, 0x51, 0x58, 0x66, 0x75, 0x4B, 0x4F, 0x4B, 0x44, 0x36, 0x32, 0x78, 0x75, 0x72, ++ 0x31, 0x4E, 0x47, 0x79, 0x66, 0x4E, 0x34, 0x67, 0x48, 0x4F, 0x4E, 0x75, 0x47, 0x63, 0x66, 0x72, 0x4E, 0x6C, 0x55, 0x68, 0x44, 0x62, 0x71, 0x4E, 0x50, 0x67, 0x6F, 0x66, 0x58, 0x4E, 0x4A, 0x68, 0x75, 0x53, 0x35, 0x4E, 0x35, 0x59, 0x48, 0x56, ++ 0x70, 0x44, 0x2F, 0x41, 0x61, 0x31, 0x56, 0x50, 0x36, 0x49, 0x51, 0x7A, 0x43, 0x50, 0x2B, 0x6B, 0x2F, 0x0A, 0x48, 0x78, 0x69, 0x4D, 0x6B, 0x6C, 0x31, 0x34, 0x70, 0x33, 0x5A, 0x6E, 0x47, 0x62, 0x75, 0x79, 0x36, 0x6E, 0x2F, 0x70, 0x63, 0x41, ++ 0x6C, 0x57, 0x56, 0x71, 0x4F, 0x77, 0x44, 0x41, 0x73, 0x74, 0x4E, 0x6C, 0x37, 0x46, 0x36, 0x63, 0x54, 0x56, 0x67, 0x38, 0x75, 0x47, 0x46, 0x35, 0x63, 0x73, 0x62, 0x42, 0x4E, 0x76, 0x68, 0x31, 0x71, 0x76, 0x53, 0x61, 0x59, 0x64, 0x32, 0x38, ++ 0x30, 0x34, 0x42, 0x43, 0x35, 0x66, 0x34, 0x6B, 0x6F, 0x31, 0x44, 0x69, 0x31, 0x4C, 0x0A, 0x2B, 0x4B, 0x49, 0x6B, 0x42, 0x49, 0x33, 0x59, 0x34, 0x57, 0x4E, 0x65, 0x41, 0x70, 0x49, 0x30, 0x32, 0x70, 0x68, 0x68, 0x58, 0x42, 0x78, 0x76, 0x57, ++ 0x48, 0x5A, 0x6B, 0x73, 0x2F, 0x77, 0x43, 0x75, 0x50, 0x57, 0x64, 0x43, 0x67, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x2D, 0x0A, 0x0A, 0x53, 0x77, 0x69, 0x73, 0x73, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x52, 0x53, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x32, 0x32, 0x20, 0x2D, 0x20, 0x31, 0x0A, 0x3D, 0x3D, ++ 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, ++ 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x6B, 0x7A, 0x43, 0x43, 0x41, 0x33, 0x75, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, ++ 0x55, 0x51, 0x2F, 0x6F, 0x4D, 0x58, 0x30, 0x34, 0x62, 0x67, 0x42, 0x68, 0x45, 0x37, 0x39, 0x47, 0x30, 0x54, 0x7A, 0x55, 0x66, 0x52, 0x50, 0x53, 0x41, 0x37, 0x63, 0x73, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, ++ 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x42, 0x51, 0x41, 0x77, 0x55, 0x54, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x0A, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4D, 0x43, 0x51, 0x30, 0x67, 0x78, 0x46, 0x54, 0x41, 0x54, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, ++ 0x6F, 0x54, 0x44, 0x46, 0x4E, 0x33, 0x61, 0x58, 0x4E, 0x7A, 0x55, 0x32, 0x6C, 0x6E, 0x62, 0x69, 0x42, 0x42, 0x52, 0x7A, 0x45, 0x72, 0x4D, 0x43, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x69, 0x55, 0x33, 0x64, 0x70, 0x63, 0x33, ++ 0x4E, 0x54, 0x61, 0x57, 0x64, 0x75, 0x49, 0x46, 0x4A, 0x54, 0x51, 0x53, 0x42, 0x55, 0x0A, 0x54, 0x46, 0x4D, 0x67, 0x55, 0x6D, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x53, 0x41, 0x79, 0x4D, 0x44, 0x49, 0x79, 0x49, 0x43, 0x30, 0x67, 0x4D, ++ 0x54, 0x41, 0x65, 0x46, 0x77, 0x30, 0x79, 0x4D, 0x6A, 0x41, 0x32, 0x4D, 0x44, 0x67, 0x78, 0x4D, 0x54, 0x41, 0x34, 0x4D, 0x6A, 0x4A, 0x61, 0x46, 0x77, 0x30, 0x30, 0x4E, 0x7A, 0x41, 0x32, 0x4D, 0x44, 0x67, 0x78, 0x4D, 0x54, 0x41, 0x34, 0x4D, ++ 0x6A, 0x4A, 0x61, 0x4D, 0x46, 0x45, 0x78, 0x43, 0x7A, 0x41, 0x4A, 0x0A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x4E, 0x49, 0x4D, 0x52, 0x55, 0x77, 0x45, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x77, 0x78, 0x54, ++ 0x64, 0x32, 0x6C, 0x7A, 0x63, 0x31, 0x4E, 0x70, 0x5A, 0x32, 0x34, 0x67, 0x51, 0x55, 0x63, 0x78, 0x4B, 0x7A, 0x41, 0x70, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x54, 0x49, 0x6C, 0x4E, 0x33, 0x61, 0x58, 0x4E, 0x7A, 0x55, 0x32, 0x6C, 0x6E, ++ 0x62, 0x69, 0x42, 0x53, 0x55, 0x30, 0x45, 0x67, 0x0A, 0x56, 0x45, 0x78, 0x54, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x4D, 0x6A, 0x41, 0x79, 0x4D, 0x69, 0x41, 0x74, 0x49, 0x44, 0x45, 0x77, 0x67, 0x67, 0x49, ++ 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4B, 0x41, 0x6F, 0x49, 0x43, 0x41, 0x51, 0x44, ++ 0x4C, 0x4B, 0x6D, 0x6A, 0x69, 0x0A, 0x43, 0x38, 0x4E, 0x58, 0x76, 0x44, 0x56, 0x6A, 0x76, 0x48, 0x43, 0x6C, 0x4F, 0x2F, 0x4F, 0x4D, 0x50, 0x45, 0x35, 0x58, 0x6C, 0x6D, 0x37, 0x44, 0x54, 0x6A, 0x61, 0x6B, 0x39, 0x67, 0x4C, 0x4B, 0x48, 0x71, ++ 0x71, 0x75, 0x75, 0x4E, 0x36, 0x6F, 0x72, 0x78, 0x31, 0x32, 0x32, 0x72, 0x6F, 0x31, 0x30, 0x4A, 0x46, 0x77, 0x42, 0x39, 0x2B, 0x7A, 0x42, 0x76, 0x4B, 0x4B, 0x38, 0x69, 0x35, 0x56, 0x55, 0x58, 0x75, 0x37, 0x4C, 0x43, 0x54, 0x4C, 0x66, 0x35, ++ 0x49, 0x6D, 0x0A, 0x67, 0x4B, 0x4F, 0x30, 0x6C, 0x50, 0x61, 0x43, 0x6F, 0x61, 0x54, 0x6F, 0x2B, 0x6E, 0x55, 0x64, 0x57, 0x66, 0x4D, 0x48, 0x61, 0x6D, 0x46, 0x6B, 0x34, 0x73, 0x61, 0x4D, 0x6C, 0x61, 0x2B, 0x6A, 0x75, 0x34, 0x35, 0x76, 0x56, ++ 0x73, 0x39, 0x78, 0x7A, 0x46, 0x36, 0x42, 0x59, 0x51, 0x31, 0x74, 0x38, 0x71, 0x73, 0x43, 0x4C, 0x71, 0x53, 0x58, 0x35, 0x58, 0x48, 0x38, 0x69, 0x72, 0x43, 0x52, 0x49, 0x46, 0x75, 0x63, 0x64, 0x46, 0x4A, 0x74, 0x72, 0x68, 0x55, 0x6E, 0x0A, ++ 0x57, 0x58, 0x6A, 0x79, 0x43, 0x63, 0x70, 0x6C, 0x44, 0x6E, 0x2F, 0x4C, 0x39, 0x4F, 0x76, 0x6E, 0x33, 0x4B, 0x6C, 0x4D, 0x64, 0x2F, 0x59, 0x72, 0x46, 0x67, 0x53, 0x56, 0x72, 0x70, 0x78, 0x78, 0x70, 0x54, 0x38, 0x71, 0x32, 0x6B, 0x46, 0x43, ++ 0x35, 0x7A, 0x79, 0x45, 0x45, 0x50, 0x54, 0x68, 0x50, 0x59, 0x78, 0x72, 0x34, 0x69, 0x75, 0x52, 0x52, 0x31, 0x56, 0x50, 0x75, 0x46, 0x61, 0x2B, 0x52, 0x64, 0x34, 0x69, 0x55, 0x55, 0x31, 0x4F, 0x4B, 0x4E, 0x6C, 0x66, 0x0A, 0x47, 0x55, 0x45, ++ 0x47, 0x6A, 0x77, 0x35, 0x4E, 0x42, 0x75, 0x42, 0x77, 0x51, 0x43, 0x4D, 0x42, 0x61, 0x75, 0x54, 0x4C, 0x45, 0x35, 0x74, 0x7A, 0x72, 0x45, 0x30, 0x55, 0x53, 0x4A, 0x49, 0x74, 0x2F, 0x6D, 0x32, 0x6E, 0x2B, 0x49, 0x64, 0x72, 0x65, 0x58, 0x58, ++ 0x68, 0x76, 0x68, 0x43, 0x78, 0x71, 0x6F, 0x68, 0x41, 0x57, 0x56, 0x54, 0x58, 0x7A, 0x38, 0x54, 0x51, 0x6D, 0x30, 0x53, 0x7A, 0x4F, 0x47, 0x6C, 0x6B, 0x6A, 0x49, 0x48, 0x52, 0x49, 0x33, 0x36, 0x71, 0x0A, 0x4F, 0x54, 0x77, 0x37, 0x44, 0x35, ++ 0x39, 0x4B, 0x65, 0x34, 0x4C, 0x4B, 0x61, 0x32, 0x2F, 0x4B, 0x49, 0x6A, 0x34, 0x78, 0x30, 0x4C, 0x44, 0x51, 0x4B, 0x68, 0x79, 0x53, 0x69, 0x6F, 0x2F, 0x59, 0x47, 0x5A, 0x78, 0x48, 0x35, 0x44, 0x34, 0x4D, 0x75, 0x63, 0x4C, 0x4E, 0x76, 0x6B, ++ 0x45, 0x4D, 0x2B, 0x4B, 0x52, 0x48, 0x42, 0x64, 0x76, 0x42, 0x46, 0x7A, 0x41, 0x34, 0x4F, 0x6D, 0x6E, 0x63, 0x7A, 0x63, 0x4E, 0x70, 0x49, 0x2F, 0x32, 0x61, 0x44, 0x77, 0x4C, 0x4F, 0x0A, 0x45, 0x47, 0x72, 0x4F, 0x79, 0x76, 0x69, 0x35, 0x4B, ++ 0x61, 0x4D, 0x32, 0x69, 0x59, 0x61, 0x75, 0x43, 0x38, 0x42, 0x50, 0x59, 0x37, 0x6B, 0x47, 0x57, 0x55, 0x6C, 0x65, 0x44, 0x73, 0x46, 0x70, 0x73, 0x77, 0x72, 0x7A, 0x64, 0x33, 0x34, 0x75, 0x6E, 0x59, 0x79, 0x7A, 0x4A, 0x35, 0x6A, 0x53, 0x6D, ++ 0x59, 0x30, 0x6C, 0x70, 0x78, 0x2B, 0x47, 0x73, 0x36, 0x5A, 0x55, 0x63, 0x44, 0x6A, 0x38, 0x66, 0x56, 0x33, 0x6F, 0x54, 0x34, 0x4D, 0x4D, 0x30, 0x5A, 0x50, 0x6C, 0x0A, 0x45, 0x75, 0x52, 0x55, 0x32, 0x6A, 0x37, 0x79, 0x72, 0x54, 0x72, 0x65, ++ 0x50, 0x6A, 0x78, 0x46, 0x38, 0x43, 0x67, 0x50, 0x42, 0x72, 0x6E, 0x68, 0x32, 0x35, 0x64, 0x37, 0x6D, 0x55, 0x57, 0x65, 0x33, 0x66, 0x36, 0x56, 0x57, 0x51, 0x51, 0x76, 0x64, 0x54, 0x2F, 0x54, 0x72, 0x6F, 0x6D, 0x5A, 0x68, 0x71, 0x77, 0x55, ++ 0x74, 0x4B, 0x69, 0x45, 0x2B, 0x73, 0x68, 0x64, 0x4F, 0x78, 0x74, 0x59, 0x6B, 0x38, 0x45, 0x58, 0x6C, 0x46, 0x58, 0x49, 0x43, 0x2B, 0x4F, 0x43, 0x0A, 0x65, 0x59, 0x53, 0x66, 0x38, 0x77, 0x43, 0x45, 0x4E, 0x4F, 0x37, 0x63, 0x4D, 0x64, 0x57, ++ 0x50, 0x38, 0x76, 0x70, 0x50, 0x6C, 0x6B, 0x77, 0x47, 0x71, 0x6E, 0x6A, 0x37, 0x33, 0x6D, 0x53, 0x69, 0x49, 0x38, 0x30, 0x66, 0x50, 0x73, 0x57, 0x4D, 0x76, 0x44, 0x64, 0x55, 0x44, 0x72, 0x74, 0x61, 0x63, 0x6C, 0x58, 0x76, 0x79, 0x46, 0x75, ++ 0x31, 0x63, 0x76, 0x68, 0x34, 0x33, 0x7A, 0x63, 0x67, 0x54, 0x46, 0x65, 0x52, 0x63, 0x35, 0x4A, 0x7A, 0x72, 0x42, 0x68, 0x33, 0x0A, 0x51, 0x34, 0x49, 0x67, 0x61, 0x65, 0x7A, 0x70, 0x72, 0x43, 0x6C, 0x47, 0x35, 0x51, 0x74, 0x4F, 0x2B, 0x44, ++ 0x64, 0x7A, 0x69, 0x5A, 0x61, 0x4B, 0x48, 0x47, 0x32, 0x39, 0x37, 0x37, 0x37, 0x59, 0x74, 0x76, 0x54, 0x4B, 0x77, 0x50, 0x31, 0x48, 0x38, 0x4B, 0x34, 0x4C, 0x57, 0x43, 0x44, 0x46, 0x79, 0x42, 0x30, 0x32, 0x72, 0x70, 0x65, 0x4E, 0x55, 0x49, ++ 0x4D, 0x6D, 0x4A, 0x43, 0x6E, 0x33, 0x6E, 0x54, 0x73, 0x50, 0x42, 0x51, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x0A, 0x6F, 0x32, 0x4D, 0x77, 0x59, 0x54, 0x41, 0x50, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x52, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, ++ 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2F, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6A, 0x41, 0x66, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x53, 0x4D, 0x45, 0x47, ++ 0x44, 0x41, 0x57, 0x67, 0x42, 0x52, 0x76, 0x6A, 0x6D, 0x4B, 0x4C, 0x6B, 0x30, 0x4F, 0x77, 0x0A, 0x34, 0x55, 0x44, 0x32, 0x70, 0x38, 0x50, 0x39, 0x38, 0x51, 0x2B, 0x34, 0x44, 0x78, 0x55, 0x34, 0x70, 0x54, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, ++ 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x62, 0x34, 0x35, 0x69, 0x69, 0x35, 0x4E, 0x44, 0x73, 0x4F, 0x46, 0x41, 0x39, 0x71, 0x66, 0x44, 0x2F, 0x66, 0x45, 0x50, 0x75, 0x41, 0x38, 0x56, 0x4F, 0x4B, 0x55, 0x77, 0x44, 0x51, 0x59, 0x4A, ++ 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x4C, 0x0A, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x42, 0x41, 0x4B, 0x77, 0x73, 0x4B, 0x55, 0x46, 0x39, 0x2B, 0x6C, 0x7A, 0x31, 0x47, 0x70, 0x55, 0x59, 0x76, 0x79, 0x79, ++ 0x70, 0x69, 0x71, 0x6B, 0x6B, 0x56, 0x48, 0x58, 0x31, 0x75, 0x45, 0x43, 0x72, 0x79, 0x36, 0x67, 0x6B, 0x55, 0x53, 0x73, 0x59, 0x50, 0x32, 0x4F, 0x70, 0x72, 0x70, 0x68, 0x57, 0x4B, 0x77, 0x56, 0x44, 0x49, 0x71, 0x4F, 0x33, 0x31, 0x30, 0x61, ++ 0x65, 0x77, 0x43, 0x6F, 0x53, 0x50, 0x59, 0x36, 0x57, 0x0A, 0x6C, 0x6B, 0x44, 0x66, 0x44, 0x44, 0x4F, 0x4C, 0x61, 0x7A, 0x65, 0x52, 0x4F, 0x70, 0x57, 0x37, 0x4F, 0x53, 0x6C, 0x74, 0x77, 0x41, 0x4A, 0x73, 0x69, 0x70, 0x51, 0x4C, 0x42, 0x77, ++ 0x4A, 0x4E, 0x47, 0x44, 0x37, 0x37, 0x2B, 0x33, 0x76, 0x31, 0x64, 0x6A, 0x32, 0x62, 0x39, 0x6C, 0x34, 0x77, 0x42, 0x6C, 0x67, 0x7A, 0x48, 0x71, 0x70, 0x34, 0x31, 0x65, 0x5A, 0x55, 0x42, 0x44, 0x71, 0x79, 0x67, 0x67, 0x6D, 0x4E, 0x7A, 0x68, ++ 0x59, 0x7A, 0x57, 0x55, 0x55, 0x6F, 0x0A, 0x38, 0x61, 0x57, 0x6A, 0x6C, 0x77, 0x35, 0x44, 0x49, 0x2F, 0x30, 0x4C, 0x49, 0x49, 0x43, 0x51, 0x2F, 0x2B, 0x4D, 0x6D, 0x7A, 0x37, 0x68, 0x6B, 0x6B, 0x65, 0x55, 0x46, 0x6A, 0x78, 0x4F, 0x67, 0x64, ++ 0x67, 0x33, 0x58, 0x4E, 0x77, 0x77, 0x51, 0x69, 0x4A, 0x62, 0x30, 0x50, 0x72, 0x36, 0x56, 0x76, 0x66, 0x48, 0x44, 0x66, 0x66, 0x43, 0x6A, 0x77, 0x33, 0x6C, 0x48, 0x43, 0x31, 0x79, 0x53, 0x46, 0x57, 0x50, 0x74, 0x55, 0x6E, 0x57, 0x4B, 0x35, ++ 0x30, 0x5A, 0x70, 0x0A, 0x79, 0x31, 0x46, 0x56, 0x43, 0x79, 0x70, 0x4D, 0x39, 0x66, 0x4A, 0x6B, 0x54, 0x36, 0x6C, 0x63, 0x2F, 0x32, 0x63, 0x79, 0x6A, 0x6C, 0x55, 0x74, 0x4D, 0x6F, 0x49, 0x63, 0x67, 0x43, 0x39, 0x71, 0x6B, 0x66, 0x6A, 0x4C, ++ 0x76, 0x48, 0x34, 0x59, 0x6F, 0x69, 0x61, 0x6F, 0x4C, 0x71, 0x4E, 0x54, 0x4B, 0x49, 0x66, 0x74, 0x56, 0x2B, 0x56, 0x6C, 0x65, 0x6B, 0x34, 0x41, 0x53, 0x6C, 0x74, 0x4F, 0x55, 0x38, 0x6C, 0x69, 0x4E, 0x72, 0x33, 0x43, 0x6A, 0x6C, 0x76, 0x72, ++ 0x0A, 0x7A, 0x47, 0x34, 0x6E, 0x67, 0x52, 0x68, 0x5A, 0x69, 0x30, 0x52, 0x6A, 0x6E, 0x39, 0x55, 0x4D, 0x5A, 0x66, 0x51, 0x70, 0x5A, 0x58, 0x2B, 0x52, 0x4C, 0x4F, 0x56, 0x2F, 0x66, 0x75, 0x69, 0x4A, 0x7A, 0x34, 0x38, 0x67, 0x79, 0x32, 0x30, ++ 0x48, 0x51, 0x68, 0x46, 0x52, 0x4A, 0x6A, 0x4B, 0x4B, 0x4C, 0x6A, 0x70, 0x48, 0x45, 0x37, 0x69, 0x4E, 0x76, 0x55, 0x63, 0x4E, 0x43, 0x66, 0x41, 0x57, 0x70, 0x4F, 0x32, 0x57, 0x68, 0x69, 0x34, 0x5A, 0x32, 0x4C, 0x36, 0x4D, 0x0A, 0x4F, 0x75, ++ 0x68, 0x46, 0x4C, 0x68, 0x47, 0x36, 0x72, 0x6C, 0x72, 0x6E, 0x75, 0x62, 0x2B, 0x78, 0x7A, 0x49, 0x2F, 0x67, 0x6F, 0x50, 0x2B, 0x34, 0x73, 0x39, 0x47, 0x46, 0x65, 0x33, 0x6C, 0x6D, 0x6F, 0x7A, 0x6D, 0x31, 0x4F, 0x32, 0x62, 0x59, 0x51, 0x4C, ++ 0x37, 0x50, 0x74, 0x32, 0x65, 0x4C, 0x53, 0x4D, 0x6B, 0x5A, 0x4A, 0x56, 0x58, 0x38, 0x76, 0x59, 0x33, 0x50, 0x58, 0x74, 0x70, 0x4F, 0x70, 0x76, 0x4A, 0x70, 0x7A, 0x76, 0x31, 0x2F, 0x54, 0x48, 0x66, 0x51, 0x0A, 0x77, 0x55, 0x59, 0x31, 0x6D, ++ 0x46, 0x77, 0x6A, 0x6D, 0x77, 0x4A, 0x46, 0x51, 0x35, 0x52, 0x61, 0x33, 0x62, 0x78, 0x48, 0x72, 0x53, 0x4C, 0x2B, 0x75, 0x6C, 0x34, 0x76, 0x6B, 0x53, 0x6B, 0x70, 0x68, 0x6E, 0x73, 0x68, 0x33, 0x6D, 0x35, 0x6B, 0x74, 0x38, 0x73, 0x4E, 0x6A, ++ 0x7A, 0x64, 0x62, 0x6F, 0x77, 0x68, 0x71, 0x36, 0x2F, 0x54, 0x64, 0x41, 0x6F, 0x39, 0x51, 0x41, 0x77, 0x4B, 0x78, 0x75, 0x44, 0x64, 0x6F, 0x6C, 0x6C, 0x44, 0x72, 0x75, 0x46, 0x2F, 0x55, 0x0A, 0x4B, 0x49, 0x71, 0x6C, 0x49, 0x67, 0x79, 0x4B, ++ 0x68, 0x50, 0x42, 0x5A, 0x4C, 0x74, 0x55, 0x33, 0x30, 0x57, 0x48, 0x6C, 0x51, 0x6E, 0x4E, 0x59, 0x4B, 0x6F, 0x48, 0x33, 0x64, 0x74, 0x76, 0x69, 0x34, 0x6B, 0x30, 0x4E, 0x58, 0x2F, 0x61, 0x33, 0x76, 0x67, 0x57, 0x30, 0x72, 0x6B, 0x34, 0x4E, ++ 0x33, 0x68, 0x59, 0x39, 0x41, 0x34, 0x47, 0x7A, 0x4A, 0x6C, 0x35, 0x4C, 0x75, 0x45, 0x73, 0x41, 0x7A, 0x2F, 0x2B, 0x4D, 0x46, 0x37, 0x70, 0x73, 0x59, 0x43, 0x30, 0x6E, 0x0A, 0x68, 0x7A, 0x63, 0x6B, 0x35, 0x6E, 0x70, 0x67, 0x4C, 0x37, 0x58, ++ 0x54, 0x67, 0x77, 0x53, 0x71, 0x54, 0x30, 0x4E, 0x31, 0x6F, 0x73, 0x47, 0x44, 0x73, 0x69, 0x65, 0x59, 0x4B, 0x37, 0x45, 0x4F, 0x67, 0x4C, 0x72, 0x41, 0x68, 0x56, 0x35, 0x43, 0x75, 0x64, 0x2B, 0x78, 0x59, 0x4A, 0x48, 0x54, 0x36, 0x78, 0x68, ++ 0x2B, 0x63, 0x48, 0x69, 0x75, 0x64, 0x6F, 0x4F, 0x2B, 0x63, 0x56, 0x72, 0x51, 0x6B, 0x4F, 0x50, 0x4B, 0x77, 0x52, 0x59, 0x6C, 0x5A, 0x30, 0x72, 0x77, 0x0A, 0x74, 0x6E, 0x75, 0x36, 0x34, 0x5A, 0x7A, 0x5A, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, ++ 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x4F, 0x49, 0x53, 0x54, 0x45, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, ++ 0x45, 0x43, 0x43, 0x20, 0x47, 0x31, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, ++ 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x4E, 0x54, 0x43, 0x43, 0x41, 0x62, 0x71, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, ++ 0x49, 0x2F, 0x6E, 0x44, 0x31, 0x6A, 0x57, 0x76, 0x6A, 0x79, 0x68, 0x4C, 0x48, 0x2F, 0x42, 0x55, 0x36, 0x6E, 0x36, 0x58, 0x6E, 0x54, 0x41, 0x4B, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x51, 0x44, 0x41, 0x7A, 0x42, 0x4C, ++ 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4A, 0x44, 0x0A, 0x53, 0x44, 0x45, 0x5A, 0x4D, 0x42, 0x63, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x51, 0x54, 0x30, 0x6C, 0x54, 0x56, 0x45, 0x55, ++ 0x67, 0x52, 0x6D, 0x39, 0x31, 0x62, 0x6D, 0x52, 0x68, 0x64, 0x47, 0x6C, 0x76, 0x62, 0x6A, 0x45, 0x68, 0x4D, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x59, 0x54, 0x30, 0x6C, 0x54, 0x56, 0x45, 0x55, 0x67, 0x55, 0x32, 0x56, ++ 0x79, 0x64, 0x6D, 0x56, 0x79, 0x49, 0x46, 0x4A, 0x76, 0x62, 0x33, 0x51, 0x67, 0x0A, 0x52, 0x55, 0x4E, 0x44, 0x49, 0x45, 0x63, 0x78, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x49, 0x7A, 0x4D, 0x44, 0x55, 0x7A, 0x4D, 0x54, 0x45, 0x30, 0x4E, 0x44, ++ 0x49, 0x79, 0x4F, 0x46, 0x6F, 0x58, 0x44, 0x54, 0x51, 0x34, 0x4D, 0x44, 0x55, 0x79, 0x4E, 0x44, 0x45, 0x30, 0x4E, 0x44, 0x49, 0x79, 0x4E, 0x31, 0x6F, 0x77, 0x53, 0x7A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, ++ 0x4D, 0x43, 0x51, 0x30, 0x67, 0x78, 0x47, 0x54, 0x41, 0x58, 0x0A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x45, 0x45, 0x39, 0x4A, 0x55, 0x31, 0x52, 0x46, 0x49, 0x45, 0x5A, 0x76, 0x64, 0x57, 0x35, 0x6B, 0x59, 0x58, 0x52, 0x70, 0x62, ++ 0x32, 0x34, 0x78, 0x49, 0x54, 0x41, 0x66, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x47, 0x45, 0x39, 0x4A, 0x55, 0x31, 0x52, 0x46, 0x49, 0x46, 0x4E, 0x6C, 0x63, 0x6E, 0x5A, 0x6C, 0x63, 0x69, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, ++ 0x45, 0x56, 0x44, 0x51, 0x79, 0x42, 0x48, 0x0A, 0x4D, 0x54, 0x42, 0x32, 0x4D, 0x42, 0x41, 0x47, 0x42, 0x79, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x41, 0x67, 0x45, 0x47, 0x42, 0x53, 0x75, 0x42, 0x42, 0x41, 0x41, 0x69, 0x41, 0x32, 0x49, 0x41, ++ 0x42, 0x42, 0x63, 0x76, 0x2B, 0x68, 0x4B, 0x38, 0x72, 0x42, 0x6A, 0x7A, 0x43, 0x76, 0x52, 0x45, 0x31, 0x6E, 0x5A, 0x43, 0x6E, 0x72, 0x50, 0x6F, 0x48, 0x37, 0x64, 0x35, 0x71, 0x56, 0x69, 0x32, 0x2B, 0x47, 0x58, 0x52, 0x4F, 0x69, 0x46, 0x50, ++ 0x71, 0x4F, 0x75, 0x6A, 0x0A, 0x76, 0x71, 0x51, 0x79, 0x63, 0x76, 0x4F, 0x32, 0x41, 0x63, 0x6B, 0x72, 0x2F, 0x58, 0x65, 0x46, 0x62, 0x6C, 0x50, 0x64, 0x72, 0x65, 0x71, 0x71, 0x4C, 0x69, 0x57, 0x53, 0x74, 0x75, 0x6B, 0x68, 0x45, 0x61, 0x69, ++ 0x76, 0x74, 0x55, 0x77, 0x4C, 0x38, 0x35, 0x5A, 0x67, 0x6D, 0x6A, 0x76, 0x6E, 0x36, 0x68, 0x70, 0x34, 0x4C, 0x72, 0x51, 0x39, 0x35, 0x53, 0x6A, 0x65, 0x48, 0x49, 0x43, 0x36, 0x58, 0x47, 0x34, 0x4E, 0x32, 0x78, 0x6D, 0x6C, 0x34, 0x7A, 0x2B, ++ 0x63, 0x0A, 0x4B, 0x72, 0x68, 0x41, 0x53, 0x39, 0x33, 0x6D, 0x54, 0x36, 0x4E, 0x6A, 0x4D, 0x47, 0x45, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2F, 0x7A, ++ 0x41, 0x66, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x53, 0x4D, 0x45, 0x47, 0x44, 0x41, 0x57, 0x67, 0x42, 0x51, 0x33, 0x54, 0x59, 0x68, 0x6C, 0x7A, 0x2F, 0x77, 0x39, 0x69, 0x74, 0x57, 0x6A, 0x38, 0x55, 0x6E, 0x41, 0x54, 0x67, 0x77, 0x51, 0x0A, 0x62, ++ 0x30, 0x4B, 0x30, 0x6E, 0x44, 0x41, 0x64, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x4E, 0x30, 0x32, 0x49, 0x5A, 0x63, 0x2F, 0x38, 0x50, 0x59, 0x72, 0x56, 0x6F, 0x2F, 0x46, 0x4A, 0x77, 0x45, 0x34, 0x4D, 0x45, ++ 0x47, 0x39, 0x43, 0x74, 0x4A, 0x77, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2F, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x47, 0x47, 0x4D, 0x41, 0x6F, 0x47, 0x43, 0x43, 0x71, 0x47, 0x0A, 0x53, 0x4D, 0x34, 0x39, ++ 0x42, 0x41, 0x4D, 0x44, 0x41, 0x32, 0x6B, 0x41, 0x4D, 0x47, 0x59, 0x43, 0x4D, 0x51, 0x43, 0x70, 0x4B, 0x6A, 0x41, 0x64, 0x30, 0x4D, 0x4B, 0x66, 0x6B, 0x46, 0x46, 0x52, 0x51, 0x44, 0x36, 0x56, 0x56, 0x43, 0x48, 0x4E, 0x46, 0x6D, 0x62, 0x33, ++ 0x55, 0x32, 0x77, 0x49, 0x46, 0x6A, 0x6E, 0x51, 0x45, 0x6E, 0x78, 0x2F, 0x59, 0x78, 0x76, 0x66, 0x34, 0x7A, 0x67, 0x41, 0x4F, 0x64, 0x6B, 0x74, 0x55, 0x79, 0x42, 0x46, 0x43, 0x78, 0x78, 0x67, 0x0A, 0x5A, 0x7A, 0x46, 0x44, 0x4A, 0x65, 0x30, ++ 0x43, 0x4D, 0x51, 0x43, 0x53, 0x69, 0x61, 0x37, 0x70, 0x58, 0x47, 0x4B, 0x44, 0x59, 0x6D, 0x48, 0x35, 0x4C, 0x56, 0x65, 0x72, 0x56, 0x72, 0x6B, 0x52, 0x33, 0x53, 0x57, 0x2B, 0x61, 0x6B, 0x35, 0x4B, 0x47, 0x6F, 0x4A, 0x72, 0x33, 0x4D, 0x2F, ++ 0x54, 0x76, 0x45, 0x71, 0x7A, 0x50, 0x4E, 0x63, 0x75, 0x6D, 0x39, 0x76, 0x34, 0x4B, 0x47, 0x6D, 0x38, 0x61, 0x79, 0x33, 0x73, 0x4D, 0x61, 0x45, 0x36, 0x34, 0x31, 0x63, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, ++ 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x0A, 0x20, 0x4F, 0x49, 0x53, 0x54, 0x45, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, ++ 0x47, 0x31, 0x0A, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, ++ 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x46, 0x67, 0x7A, 0x43, 0x43, 0x41, 0x32, 0x75, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x56, 0x61, 0x58, ++ 0x5A, 0x5A, 0x35, 0x51, 0x6F, 0x78, 0x75, 0x30, 0x4D, 0x2B, 0x69, 0x66, 0x64, 0x57, 0x77, 0x46, 0x4E, 0x47, 0x44, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x77, 0x46, 0x41, 0x44, 0x42, ++ 0x4C, 0x4D, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0A, 0x45, 0x77, 0x4A, 0x44, 0x53, 0x44, 0x45, 0x5A, 0x4D, 0x42, 0x63, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x51, 0x54, 0x30, 0x6C, 0x54, 0x56, 0x45, ++ 0x55, 0x67, 0x52, 0x6D, 0x39, 0x31, 0x62, 0x6D, 0x52, 0x68, 0x64, 0x47, 0x6C, 0x76, 0x62, 0x6A, 0x45, 0x68, 0x4D, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x59, 0x54, 0x30, 0x6C, 0x54, 0x56, 0x45, 0x55, 0x67, 0x55, 0x32, ++ 0x56, 0x79, 0x64, 0x6D, 0x56, 0x79, 0x49, 0x46, 0x4A, 0x76, 0x0A, 0x62, 0x33, 0x51, 0x67, 0x55, 0x6C, 0x4E, 0x42, 0x49, 0x45, 0x63, 0x78, 0x4D, 0x42, 0x34, 0x58, 0x44, 0x54, 0x49, 0x7A, 0x4D, 0x44, 0x55, 0x7A, 0x4D, 0x54, 0x45, 0x30, 0x4D, ++ 0x7A, 0x63, 0x78, 0x4E, 0x6C, 0x6F, 0x58, 0x44, 0x54, 0x51, 0x34, 0x4D, 0x44, 0x55, 0x79, 0x4E, 0x44, 0x45, 0x30, 0x4D, 0x7A, 0x63, 0x78, 0x4E, 0x56, 0x6F, 0x77, 0x53, 0x7A, 0x45, 0x4C, 0x4D, 0x41, 0x6B, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, ++ 0x68, 0x4D, 0x43, 0x51, 0x30, 0x67, 0x78, 0x0A, 0x47, 0x54, 0x41, 0x58, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x6F, 0x4D, 0x45, 0x45, 0x39, 0x4A, 0x55, 0x31, 0x52, 0x46, 0x49, 0x45, 0x5A, 0x76, 0x64, 0x57, 0x35, 0x6B, 0x59, 0x58, 0x52, 0x70, ++ 0x62, 0x32, 0x34, 0x78, 0x49, 0x54, 0x41, 0x66, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x4D, 0x4D, 0x47, 0x45, 0x39, 0x4A, 0x55, 0x31, 0x52, 0x46, 0x49, 0x46, 0x4E, 0x6C, 0x63, 0x6E, 0x5A, 0x6C, 0x63, 0x69, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, ++ 0x49, 0x46, 0x4A, 0x54, 0x0A, 0x51, 0x53, 0x42, 0x48, 0x4D, 0x54, 0x43, 0x43, 0x41, 0x69, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, ++ 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x67, 0x6F, 0x43, 0x67, 0x67, 0x49, 0x42, 0x41, 0x4B, 0x71, 0x75, 0x39, 0x4B, 0x75, 0x43, 0x7A, 0x2F, 0x76, 0x6C, 0x4E, 0x77, 0x76, 0x6E, 0x31, 0x5A, 0x61, 0x74, 0x6B, 0x4F, 0x68, 0x4C, 0x4B, 0x64, 0x78, ++ 0x56, 0x0A, 0x59, 0x4F, 0x50, 0x4D, 0x76, 0x4C, 0x4F, 0x38, 0x4C, 0x5A, 0x4B, 0x35, 0x35, 0x4B, 0x4E, 0x36, 0x38, 0x59, 0x47, 0x30, 0x6E, 0x6E, 0x4A, 0x79, 0x51, 0x39, 0x38, 0x2F, 0x71, 0x77, 0x73, 0x6D, 0x74, 0x4F, 0x35, 0x37, 0x47, 0x6D, ++ 0x6E, 0x37, 0x4B, 0x4E, 0x42, 0x79, 0x58, 0x45, 0x70, 0x74, 0x61, 0x5A, 0x6E, 0x77, 0x59, 0x78, 0x34, 0x4D, 0x30, 0x72, 0x48, 0x2F, 0x31, 0x6F, 0x77, 0x30, 0x30, 0x4F, 0x37, 0x62, 0x72, 0x45, 0x69, 0x35, 0x36, 0x72, 0x41, 0x55, 0x0A, 0x6A, ++ 0x74, 0x67, 0x48, 0x71, 0x53, 0x53, 0x59, 0x33, 0x65, 0x6B, 0x4A, 0x76, 0x71, 0x67, 0x69, 0x47, 0x31, 0x6B, 0x35, 0x30, 0x53, 0x65, 0x48, 0x33, 0x42, 0x7A, 0x4E, 0x2B, 0x50, 0x75, 0x7A, 0x36, 0x2B, 0x6D, 0x54, 0x65, 0x4F, 0x30, 0x50, 0x7A, ++ 0x6A, 0x64, 0x38, 0x4A, 0x6E, 0x64, 0x75, 0x6F, 0x64, 0x67, 0x73, 0x49, 0x55, 0x7A, 0x6B, 0x69, 0x6B, 0x2F, 0x48, 0x45, 0x7A, 0x78, 0x75, 0x78, 0x39, 0x55, 0x54, 0x6C, 0x37, 0x4B, 0x6F, 0x32, 0x79, 0x52, 0x70, 0x0A, 0x67, 0x31, 0x62, 0x54, ++ 0x61, 0x63, 0x75, 0x43, 0x45, 0x72, 0x75, 0x64, 0x47, 0x2F, 0x4C, 0x34, 0x4E, 0x50, 0x4B, 0x59, 0x4B, 0x79, 0x71, 0x4F, 0x42, 0x47, 0x66, 0x32, 0x34, 0x34, 0x65, 0x68, 0x48, 0x61, 0x31, 0x75, 0x7A, 0x6A, 0x5A, 0x30, 0x44, 0x6C, 0x34, 0x7A, ++ 0x4F, 0x38, 0x76, 0x62, 0x55, 0x5A, 0x65, 0x55, 0x61, 0x70, 0x55, 0x38, 0x7A, 0x68, 0x68, 0x61, 0x62, 0x6B, 0x76, 0x47, 0x2F, 0x41, 0x65, 0x50, 0x4C, 0x68, 0x71, 0x35, 0x53, 0x76, 0x64, 0x6B, 0x0A, 0x4E, 0x43, 0x6E, 0x63, 0x70, 0x6F, 0x31, ++ 0x51, 0x34, 0x59, 0x32, 0x4C, 0x53, 0x2B, 0x56, 0x49, 0x47, 0x32, 0x34, 0x75, 0x67, 0x42, 0x41, 0x2F, 0x35, 0x4A, 0x38, 0x62, 0x5A, 0x54, 0x38, 0x52, 0x74, 0x4F, 0x70, 0x58, 0x61, 0x5A, 0x2B, 0x30, 0x41, 0x4F, 0x75, 0x46, 0x4A, 0x4A, 0x6B, ++ 0x6B, 0x39, 0x53, 0x47, 0x64, 0x6C, 0x36, 0x72, 0x37, 0x4E, 0x48, 0x38, 0x43, 0x61, 0x78, 0x57, 0x51, 0x72, 0x62, 0x75, 0x65, 0x57, 0x68, 0x6C, 0x2F, 0x70, 0x49, 0x7A, 0x59, 0x0A, 0x2B, 0x6D, 0x30, 0x6F, 0x2F, 0x44, 0x6A, 0x48, 0x34, 0x30, ++ 0x79, 0x74, 0x61, 0x73, 0x37, 0x5A, 0x54, 0x70, 0x4F, 0x53, 0x6A, 0x73, 0x77, 0x4D, 0x5A, 0x37, 0x38, 0x4C, 0x53, 0x35, 0x62, 0x4F, 0x5A, 0x6D, 0x64, 0x54, 0x61, 0x4D, 0x73, 0x58, 0x45, 0x59, 0x35, 0x5A, 0x39, 0x36, 0x79, 0x63, 0x47, 0x37, ++ 0x6D, 0x4F, 0x61, 0x45, 0x53, 0x33, 0x47, 0x4B, 0x2F, 0x6D, 0x35, 0x51, 0x39, 0x6C, 0x33, 0x4A, 0x55, 0x4A, 0x73, 0x4A, 0x4D, 0x53, 0x74, 0x52, 0x38, 0x2B, 0x0A, 0x6C, 0x4B, 0x58, 0x48, 0x69, 0x48, 0x55, 0x68, 0x73, 0x64, 0x34, 0x4A, 0x4A, ++ 0x43, 0x70, 0x4D, 0x34, 0x72, 0x7A, 0x73, 0x54, 0x47, 0x64, 0x48, 0x77, 0x69, 0x6D, 0x49, 0x75, 0x51, 0x71, 0x36, 0x2B, 0x63, 0x46, 0x30, 0x7A, 0x6F, 0x77, 0x59, 0x4A, 0x6D, 0x58, 0x61, 0x39, 0x32, 0x2F, 0x47, 0x6A, 0x48, 0x74, 0x6F, 0x58, ++ 0x41, 0x76, 0x75, 0x59, 0x38, 0x42, 0x65, 0x53, 0x2F, 0x46, 0x4F, 0x7A, 0x4A, 0x38, 0x76, 0x44, 0x2B, 0x48, 0x6F, 0x6D, 0x6E, 0x71, 0x54, 0x0A, 0x38, 0x65, 0x44, 0x49, 0x32, 0x37, 0x38, 0x6E, 0x35, 0x6D, 0x55, 0x70, 0x65, 0x7A, 0x62, 0x67, ++ 0x4D, 0x78, 0x56, 0x7A, 0x38, 0x70, 0x31, 0x72, 0x68, 0x41, 0x68, 0x6F, 0x4B, 0x7A, 0x59, 0x48, 0x4B, 0x79, 0x66, 0x4D, 0x65, 0x4E, 0x68, 0x71, 0x68, 0x77, 0x35, 0x48, 0x64, 0x50, 0x53, 0x71, 0x6F, 0x42, 0x4E, 0x64, 0x5A, 0x48, 0x37, 0x30, ++ 0x32, 0x78, 0x53, 0x75, 0x2B, 0x7A, 0x72, 0x6B, 0x4C, 0x38, 0x46, 0x6C, 0x34, 0x37, 0x6C, 0x36, 0x51, 0x47, 0x7A, 0x77, 0x0A, 0x42, 0x72, 0x64, 0x37, 0x4B, 0x4A, 0x76, 0x58, 0x34, 0x56, 0x38, 0x34, 0x63, 0x35, 0x53, 0x73, 0x32, 0x58, 0x43, ++ 0x54, 0x4C, 0x64, 0x79, 0x45, 0x72, 0x30, 0x59, 0x63, 0x6F, 0x6E, 0x6F, 0x73, 0x50, 0x34, 0x45, 0x6D, 0x51, 0x75, 0x66, 0x55, 0x32, 0x4D, 0x56, 0x73, 0x68, 0x47, 0x59, 0x52, 0x69, 0x33, 0x64, 0x72, 0x56, 0x42, 0x79, 0x6A, 0x74, 0x64, 0x67, ++ 0x51, 0x38, 0x4B, 0x34, 0x70, 0x39, 0x32, 0x63, 0x49, 0x69, 0x42, 0x64, 0x63, 0x75, 0x4A, 0x64, 0x35, 0x0A, 0x7A, 0x2B, 0x6F, 0x72, 0x4B, 0x75, 0x35, 0x59, 0x4D, 0x2B, 0x56, 0x74, 0x36, 0x53, 0x6D, 0x71, 0x5A, 0x51, 0x45, 0x4E, 0x67, 0x68, ++ 0x50, 0x73, 0x4A, 0x51, 0x74, 0x64, 0x4C, 0x45, 0x42, 0x79, 0x46, 0x53, 0x6E, 0x54, 0x6B, 0x43, 0x7A, 0x33, 0x47, 0x6B, 0x50, 0x56, 0x61, 0x76, 0x42, 0x70, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, 0x59, 0x7A, 0x42, 0x68, 0x4D, 0x41, ++ 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x46, 0x0A, 0x4D, 0x41, 0x4D, 0x42, 0x41, 0x66, 0x38, 0x77, 0x48, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x6A, 0x42, 0x42, 0x67, 0x77, 0x46, 0x6F, 0x41, 0x55, 0x38, ++ 0x73, 0x6E, 0x42, 0x44, 0x77, 0x31, 0x6A, 0x41, 0x4C, 0x76, 0x73, 0x52, 0x51, 0x35, 0x4B, 0x48, 0x37, 0x57, 0x78, 0x73, 0x7A, 0x62, 0x4E, 0x44, 0x6F, 0x30, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4F, 0x42, 0x42, 0x59, 0x45, 0x46, ++ 0x50, 0x4C, 0x4A, 0x77, 0x51, 0x38, 0x4E, 0x59, 0x77, 0x43, 0x37, 0x0A, 0x37, 0x45, 0x55, 0x4F, 0x53, 0x68, 0x2B, 0x31, 0x73, 0x62, 0x4D, 0x32, 0x7A, 0x51, 0x36, 0x4E, 0x4D, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, ++ 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x68, 0x6A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x77, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x67, 0x45, 0x41, 0x4E, 0x47, 0x64, 0x35, ++ 0x73, 0x6A, 0x72, 0x47, 0x35, 0x54, 0x33, 0x33, 0x0A, 0x49, 0x33, 0x4B, 0x35, 0x43, 0x65, 0x2B, 0x53, 0x72, 0x53, 0x63, 0x66, 0x6F, 0x45, 0x34, 0x4B, 0x73, 0x76, 0x58, 0x61, 0x46, 0x77, 0x79, 0x69, 0x68, 0x64, 0x4A, 0x2B, 0x6B, 0x6C, 0x48, ++ 0x39, 0x46, 0x57, 0x58, 0x58, 0x58, 0x47, 0x74, 0x6B, 0x46, 0x75, 0x36, 0x4B, 0x52, 0x63, 0x6F, 0x4D, 0x51, 0x7A, 0x5A, 0x45, 0x4E, 0x64, 0x6C, 0x2F, 0x2F, 0x6E, 0x6B, 0x36, 0x48, 0x4F, 0x6A, 0x47, 0x35, 0x44, 0x31, 0x72, 0x64, 0x39, 0x51, ++ 0x68, 0x45, 0x4F, 0x50, 0x32, 0x0A, 0x38, 0x79, 0x42, 0x4F, 0x71, 0x62, 0x36, 0x4A, 0x38, 0x78, 0x79, 0x63, 0x71, 0x64, 0x2B, 0x38, 0x4D, 0x44, 0x6F, 0x58, 0x30, 0x54, 0x4A, 0x44, 0x30, 0x4B, 0x71, 0x4B, 0x63, 0x68, 0x78, 0x52, 0x4B, 0x45, ++ 0x7A, 0x64, 0x4E, 0x73, 0x6A, 0x6B, 0x4C, 0x57, 0x64, 0x39, 0x6B, 0x59, 0x63, 0x63, 0x6E, 0x62, 0x7A, 0x38, 0x71, 0x79, 0x69, 0x57, 0x58, 0x6D, 0x46, 0x63, 0x75, 0x43, 0x49, 0x7A, 0x47, 0x45, 0x67, 0x57, 0x55, 0x4F, 0x72, 0x4B, 0x4C, 0x2B, ++ 0x6D, 0x6C, 0x0A, 0x53, 0x64, 0x78, 0x2F, 0x50, 0x4B, 0x51, 0x5A, 0x76, 0x44, 0x61, 0x74, 0x6B, 0x75, 0x4B, 0x35, 0x39, 0x45, 0x76, 0x56, 0x36, 0x77, 0x69, 0x74, 0x35, 0x33, 0x6A, 0x2B, 0x46, 0x38, 0x42, 0x64, 0x68, 0x33, 0x66, 0x6F, 0x5A, ++ 0x33, 0x64, 0x50, 0x41, 0x47, 0x61, 0x76, 0x39, 0x4C, 0x45, 0x44, 0x4F, 0x72, 0x34, 0x53, 0x66, 0x45, 0x45, 0x31, 0x35, 0x66, 0x53, 0x6D, 0x47, 0x30, 0x65, 0x4C, 0x79, 0x33, 0x6E, 0x33, 0x31, 0x72, 0x38, 0x58, 0x62, 0x6B, 0x35, 0x6C, 0x0A, ++ 0x38, 0x50, 0x6A, 0x61, 0x56, 0x38, 0x47, 0x55, 0x67, 0x65, 0x56, 0x36, 0x56, 0x67, 0x32, 0x37, 0x52, 0x6E, 0x39, 0x76, 0x6B, 0x66, 0x31, 0x39, 0x35, 0x68, 0x66, 0x6B, 0x67, 0x53, 0x65, 0x37, 0x42, 0x59, 0x68, 0x57, 0x33, 0x53, 0x43, 0x6C, ++ 0x39, 0x35, 0x67, 0x74, 0x6B, 0x52, 0x6C, 0x70, 0x4D, 0x56, 0x2B, 0x62, 0x4D, 0x50, 0x4B, 0x5A, 0x72, 0x58, 0x4A, 0x41, 0x6C, 0x73, 0x7A, 0x59, 0x64, 0x32, 0x61, 0x62, 0x74, 0x4E, 0x55, 0x4F, 0x73, 0x68, 0x44, 0x2B, 0x0A, 0x46, 0x4B, 0x72, ++ 0x44, 0x67, 0x48, 0x47, 0x64, 0x50, 0x59, 0x33, 0x6F, 0x66, 0x52, 0x52, 0x73, 0x59, 0x57, 0x53, 0x47, 0x52, 0x71, 0x62, 0x58, 0x56, 0x4D, 0x57, 0x32, 0x31, 0x35, 0x41, 0x57, 0x52, 0x71, 0x57, 0x46, 0x79, 0x70, 0x34, 0x36, 0x34, 0x2B, 0x59, ++ 0x54, 0x46, 0x72, 0x59, 0x56, 0x49, 0x38, 0x79, 0x70, 0x4B, 0x56, 0x4C, 0x39, 0x41, 0x4D, 0x62, 0x32, 0x6B, 0x49, 0x35, 0x57, 0x6A, 0x34, 0x6B, 0x49, 0x33, 0x5A, 0x61, 0x71, 0x35, 0x74, 0x4E, 0x71, 0x0A, 0x71, 0x59, 0x59, 0x31, 0x39, 0x74, ++ 0x56, 0x46, 0x65, 0x45, 0x4A, 0x4B, 0x52, 0x76, 0x77, 0x44, 0x79, 0x46, 0x37, 0x59, 0x5A, 0x76, 0x5A, 0x46, 0x5A, 0x53, 0x53, 0x30, 0x76, 0x6F, 0x64, 0x37, 0x56, 0x53, 0x43, 0x64, 0x39, 0x35, 0x32, 0x31, 0x4B, 0x76, 0x79, 0x35, 0x59, 0x68, ++ 0x6E, 0x4C, 0x62, 0x44, 0x75, 0x76, 0x30, 0x32, 0x30, 0x34, 0x62, 0x4B, 0x74, 0x37, 0x70, 0x68, 0x36, 0x4E, 0x2F, 0x4F, 0x6D, 0x65, 0x2F, 0x6D, 0x73, 0x56, 0x75, 0x64, 0x75, 0x43, 0x0A, 0x6D, 0x73, 0x75, 0x59, 0x33, 0x33, 0x4F, 0x68, 0x6B, ++ 0x4B, 0x43, 0x67, 0x78, 0x65, 0x44, 0x6F, 0x41, 0x61, 0x69, 0x6A, 0x46, 0x4A, 0x7A, 0x49, 0x77, 0x5A, 0x71, 0x73, 0x46, 0x56, 0x41, 0x7A, 0x6A, 0x65, 0x31, 0x38, 0x4B, 0x6F, 0x74, 0x7A, 0x6C, 0x55, 0x42, 0x44, 0x4A, 0x76, 0x79, 0x42, 0x70, ++ 0x43, 0x70, 0x66, 0x4F, 0x5A, 0x43, 0x33, 0x4A, 0x38, 0x74, 0x52, 0x64, 0x2F, 0x69, 0x57, 0x6B, 0x78, 0x37, 0x50, 0x38, 0x6E, 0x64, 0x39, 0x48, 0x30, 0x61, 0x54, 0x0A, 0x6F, 0x6C, 0x6B, 0x65, 0x6C, 0x55, 0x54, 0x46, 0x4C, 0x58, 0x56, 0x6B, ++ 0x73, 0x4E, 0x62, 0x35, 0x34, 0x44, 0x78, 0x70, 0x36, 0x67, 0x53, 0x31, 0x48, 0x41, 0x76, 0x69, 0x52, 0x6B, 0x52, 0x4E, 0x51, 0x7A, 0x75, 0x58, 0x53, 0x58, 0x45, 0x52, 0x76, 0x53, 0x53, 0x32, 0x77, 0x71, 0x31, 0x79, 0x56, 0x41, 0x62, 0x2B, ++ 0x61, 0x78, 0x6A, 0x35, 0x64, 0x39, 0x73, 0x70, 0x4C, 0x46, 0x4B, 0x65, 0x62, 0x58, 0x64, 0x37, 0x59, 0x76, 0x30, 0x50, 0x54, 0x59, 0x36, 0x59, 0x0A, 0x4D, 0x6A, 0x41, 0x77, 0x63, 0x52, 0x4C, 0x57, 0x4A, 0x54, 0x58, 0x6A, 0x6E, 0x2F, 0x68, ++ 0x76, 0x6E, 0x4C, 0x58, 0x72, 0x61, 0x68, 0x75, 0x74, 0x36, 0x68, 0x44, 0x54, 0x6C, 0x68, 0x5A, 0x79, 0x42, 0x69, 0x45, 0x6C, 0x78, 0x6B, 0x79, 0x38, 0x6A, 0x33, 0x43, 0x37, 0x44, 0x4F, 0x52, 0x65, 0x49, 0x6F, 0x4D, 0x74, 0x30, 0x72, 0x37, ++ 0x2B, 0x68, 0x56, 0x75, 0x30, 0x35, 0x4C, 0x30, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x00 ++}; ++const size_t _accacert_len = sizeof(_accacert); ++/*************************** End of file ****************************/ +diff -rupbN melonDS.orig/src/frontend/qt_sdl/AchievementItemWidget.cpp melonDS.ra/src/frontend/qt_sdl/AchievementItemWidget.cpp +--- melonDS.orig/src/frontend/qt_sdl/AchievementItemWidget.cpp 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/frontend/qt_sdl/AchievementItemWidget.cpp 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,125 @@ ++#include "AchievementItemWidget.h" ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++AchievementItemWidget::AchievementItemWidget( ++ const QString& title, ++ const QString& description, ++ bool unlocked, ++ bool measured, ++ const QString& progressText, ++ float progressPercent, ++ float uiScale, ++ QWidget* parent ++) : QWidget(parent) ++{ ++ uiScale = std::clamp(uiScale, 0.65f, 1.0f); ++ setAttribute(Qt::WA_StyledBackground, true); ++ setFocusPolicy(Qt::StrongFocus); ++ ++ setStyleSheet(R"( ++ AchievementItemWidget { ++ background: transparent; ++ border-bottom: 1px solid rgba(255, 255, 255, 15); ++ } ++ AchievementItemWidget:focus { ++ background: rgba(255, 255, 255, 25); ++ border: 1px solid rgba(255, 255, 255, 50); ++ } ++ )"); ++ ++ iconLabel = new QLabel(this); ++ int iconSize = int(64 * uiScale); ++ iconLabel->setFixedSize(iconSize, iconSize); ++ iconLabel->setScaledContents(true); ++ iconLabel->setStyleSheet("background: transparent; border: none;"); ++ iconLabel->setPixmap(QPixmap(unlocked ? ":/ra/unlocked.png" : ":/ra/locked.png")); ++ ++ auto* rightLayout = new QVBoxLayout(); ++ rightLayout->setSpacing(int(4 * uiScale)); ++ rightLayout->setContentsMargins(0, int(5 * uiScale), 0, int(5 * uiScale)); ++ ++ titleLabel = new QLabel(title, this); ++ titleLabel->setStyleSheet(QString( ++ "font-weight: bold; color: white; font-size: %1px; background: transparent; border: none;" ++ ).arg(int(15 * uiScale))); ++ titleLabel->setWordWrap(true); ++ rightLayout->addWidget(titleLabel); ++ ++ descLabel = new QLabel(description, this); ++ descLabel->setStyleSheet(QString( ++ "color: #ccc; font-size: %1px; background: transparent; border: none;" ++ ).arg(int(13 * uiScale))); ++ descLabel->setWordWrap(true); ++ rightLayout->addWidget(descLabel); ++ ++ progressBar = new QProgressBar(this); ++ int barHeight = int(14 * uiScale); ++ int barFont = int(10 * uiScale); ++ ++ progressBar->setStyleSheet(QString(R"( ++ QProgressBar { ++ border: none; ++ background: rgba(0, 0, 0, 100); ++ height: %1px; ++ border-radius: %2px; ++ color: white; ++ font-weight: bold; ++ font-size: %3px; ++ text-align: center; ++ } ++ QProgressBar::chunk { ++ background: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop:0 #005c99, stop:1 #0099ff); ++ border-radius: %2px; ++ } ++ )").arg(barHeight).arg(barHeight / 2).arg(barFont)); ++ ++ bool showBar = measured || !progressText.isEmpty(); ++ progressBar->setVisible(showBar); ++ ++ if (showBar) { ++ progressBar->setRange(0, 100); ++ progressBar->setValue(static_cast(progressPercent)); ++ ++ if (progressText.isEmpty()) { ++ progressBar->setFormat("%p%"); ++ } else { ++ progressBar->setFormat(progressText); ++ } ++ } ++ ++ rightLayout->addWidget(progressBar); ++ ++ auto* mainLayout = new QHBoxLayout(this); ++ mainLayout->setContentsMargins( ++ int(10 * uiScale), ++ int(5 * uiScale), ++ int(10 * uiScale), ++ int(5 * uiScale) ++ ); ++ mainLayout->addWidget(iconLabel); ++ mainLayout->addLayout(rightLayout); ++} ++ ++void AchievementItemWidget::paintEvent(QPaintEvent* event) ++{ ++ QStyleOption opt; ++ opt.initFrom(this); ++ QPainter p(this); ++ style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); ++} ++ ++void AchievementItemWidget::updateIcon(const QPixmap& pix) { ++ if (!pix.isNull()) { ++ iconLabel->setPixmap(pix.scaled( ++ iconSize, iconSize, ++ Qt::KeepAspectRatio, ++ Qt::SmoothTransformation ++ )); ++ } ++} +diff -rupbN melonDS.orig/src/frontend/qt_sdl/AchievementItemWidget.h melonDS.ra/src/frontend/qt_sdl/AchievementItemWidget.h +--- melonDS.orig/src/frontend/qt_sdl/AchievementItemWidget.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/frontend/qt_sdl/AchievementItemWidget.h 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,34 @@ ++#pragma once ++#include ++#include ++ ++class QLabel; ++class QProgressBar; ++class QPaintEvent; ++ ++class AchievementItemWidget : public QWidget ++{ ++ Q_OBJECT ++public: ++ void updateIcon(const QPixmap& pix); ++ explicit AchievementItemWidget( ++ const QString& title, ++ const QString& description, ++ bool unlocked, ++ bool measured, ++ const QString& progressText, ++ float progressPercent, ++ float uiScale, ++ QWidget* parent = nullptr ++ ); ++ ++protected: ++ void paintEvent(QPaintEvent* event) override; ++ ++private: ++ int iconSize = 64; ++ QLabel* titleLabel; ++ QLabel* descLabel; ++ QLabel* iconLabel; ++ QProgressBar* progressBar; ++}; +\ No newline at end of file +diff -rupbN melonDS.orig/src/frontend/qt_sdl/CMakeLists.txt melonDS.ra/src/frontend/qt_sdl/CMakeLists.txt +--- melonDS.orig/src/frontend/qt_sdl/CMakeLists.txt 2026-03-06 21:36:14.554057405 +0000 ++++ melonDS.ra/src/frontend/qt_sdl/CMakeLists.txt 2026-03-06 21:37:07.046799886 +0000 +@@ -62,6 +62,22 @@ set(SOURCES_QT_SDL + NetplayDialog.cpp + ) + ++if (ENABLE_RETROACHIEVEMENTS) ++ list(APPEND SOURCES_QT_SDL ++ toast/ToastManager.cpp ++ toast/ToastManager.h ++ toast/ToastOverlay.cpp ++ toast/ToastOverlay.h ++ toast/BadgeCache.h ++ toast/BadgeCache.cpp ++ retroachievements/resources/ra.qrc ++ RASettingsDialog.cpp ++ RAOverlayWidget.cpp ++ AchievementItemWidget.cpp ++ ) ++ add_compile_definitions(RETROACHIEVEMENTS_ENABLED) ++endif() ++ + option(USE_QT6 "Use Qt 6 instead of Qt 5" ON) + + if (USE_QT6) +diff -rupbN melonDS.orig/src/frontend/qt_sdl/Config.cpp melonDS.ra/src/frontend/qt_sdl/Config.cpp +--- melonDS.orig/src/frontend/qt_sdl/Config.cpp 2026-03-06 21:36:14.558057462 +0000 ++++ melonDS.ra/src/frontend/qt_sdl/Config.cpp 2026-03-06 21:37:07.046799886 +0000 +@@ -103,6 +103,10 @@ DefaultList DefaultBools = + {"Emu.DirectBoot", true}, + {"Instance*.DS.Battery.LevelOkay", true}, + {"Instance*.DSi.Battery.Charging", true}, ++//#ifdef RETROACHIEVEMENTS_ENABLED ++// {"Instance*.RetroAchievements.Enabled", true}, ++// {"Instance*.RetroAchievements.HardcoreMode", false}, ++//#endif + #ifdef JIT_ENABLED + {"JIT.BranchOptimisations", true}, + {"JIT.LiteralOptimisations", true}, +@@ -117,6 +121,11 @@ DefaultList DefaultStrings + { + {"DLDI.ImagePath", "dldi.bin"}, + {"DSi.SD.ImagePath", "dsisd.bin"}, ++ //#ifdef RETROACHIEVEMENTS_ENABLED ++ //{"Instance*.RetroAchievements.Username", ""}, ++ //{"Instance*.RetroAchievements.Password", ""}, ++ //{"Instance*.RetroAchievements.Token", ""}, ++ //#endif + {"Instance*.Firmware.Username", "melonDS"} + }; + +@@ -162,6 +171,9 @@ LegacyEntry LegacyFile[] = + {"HKKey_FastForward", 0, "Keyboard.HK_FastForward", true}, + {"HKKey_FastForwardToggle", 0, "Keyboard.HK_FrameLimitToggle", true}, + {"HKKey_FullscreenToggle", 0, "Keyboard.HK_FullscreenToggle", true}, ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ {"HKKey_RAOverlayToggle", 0, "Keyboard.HK_RAOverlayToggle", true}, ++ #endif + {"HKKey_SwapScreens", 0, "Keyboard.HK_SwapScreens", true}, + {"HKKey_SwapScreenEmphasis", 0, "Keyboard.HK_SwapScreenEmphasis", true}, + {"HKKey_SolarSensorDecrease", 0, "Keyboard.HK_SolarSensorDecrease", true}, +@@ -182,6 +194,9 @@ LegacyEntry LegacyFile[] = + {"HKJoy_FastForward", 0, "Joystick.HK_FastForward", true}, + {"HKJoy_FastForwardToggle", 0, "Joystick.HK_FrameLimitToggle", true}, + {"HKJoy_FullscreenToggle", 0, "Joystick.HK_FullscreenToggle", true}, ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ {"HKJoy_RAOverlayToggle", 0, "Joystick.HK_RAOverlayToggle", true}, ++ #endif + {"HKJoy_SwapScreens", 0, "Joystick.HK_SwapScreens", true}, + {"HKJoy_SwapScreenEmphasis", 0, "Joystick.HK_SwapScreenEmphasis", true}, + {"HKJoy_SolarSensorDecrease", 0, "Joystick.HK_SolarSensorDecrease", true}, +@@ -332,7 +347,19 @@ LegacyEntry LegacyFile[] = + {"Camera1_ImagePath", 2, "DSi.Camera1.ImagePath", false}, + {"Camera1_CamDeviceName", 2, "DSi.Camera1.DeviceName", false}, + {"Camera1_XFlip", 1, "DSi.Camera1.XFlip", false}, +- ++#ifdef RETROACHIEVEMENTS_ENABLED ++ {"RA_Enabled", 1, "RetroAchievements.Enabled", true}, ++ {"RA_Username", 2, "RetroAchievements.Username", true}, ++ {"RA_Password", 2, "RetroAchievements.Password", true}, ++ {"RA_Token", 2, "RetroAchievements.Token", true}, ++ {"RA_HardcoreMode", 1, "RetroAchievements.HardcoreMode", true}, ++ {"RA_EncoreMode", 1, "RetroAchievements.EncoreMode", true}, ++ {"RA_Unofficial", 1, "RetroAchievements.Unofficial", true}, ++ {"RA_HideLeaderboardToasts", 1, "RetroAchievements.HideLeaderboardToasts", true}, ++ {"RA_HideChallengeIndicators", 1, "RetroAchievements.HideChallengeIndicators", true}, ++ {"RA_HideToasts", 1, "RetroAchievements.HideToasts", true}, ++ {"RA_HideLeaderboardCounter", 1, "RetroAchievements.HideLeaderboardCounter", true}, ++#endif + {"", -1, "", false} + }; + +@@ -831,4 +858,17 @@ Table GetLocalTable(int instance) + return Table(tbl, key); + } + ++#ifdef RETROACHIEVEMENTS_ENABLED ++Table GetRAPlaytimeTable() ++{ ++ std::string key = "RetroAchievements.Playtime"; ++ toml::value& tbl = RootTable["RetroAchievements"]["Playtime"]; ++ ++ if (!tbl.is_table()) ++ tbl = toml::table(); ++ ++ return Table(tbl, key); ++} ++#endif ++ + } +diff -rupbN melonDS.orig/src/frontend/qt_sdl/Config.h melonDS.ra/src/frontend/qt_sdl/Config.h +--- melonDS.orig/src/frontend/qt_sdl/Config.h 2026-03-06 21:36:14.558057462 +0000 ++++ melonDS.ra/src/frontend/qt_sdl/Config.h 2026-03-06 21:37:07.046799886 +0000 +@@ -92,6 +92,13 @@ public: + Table(toml::value& data, const std::string& path); + ~Table() {} + ++ //#ifdef RETROACHIEVEMENTS_ENABLED ++ //bool RA_Enabled = false; ++ //bool RA_HardcoreMode = false; ++ //std::string RA_Username; ++ //std::string RA_Password; ++ //#endif ++ + Table& operator=(const Table& b); + + Array GetArray(const std::string& path); +@@ -134,6 +141,9 @@ bool Load(); + void Save(); + + Table GetLocalTable(int instance); ++#ifdef RETROACHIEVEMENTS_ENABLED ++Table GetRAPlaytimeTable(); ++#endif + inline Table GetGlobalTable() { return GetLocalTable(-1); } + + } +diff -rupbN melonDS.orig/src/frontend/qt_sdl/EmuInstance.cpp melonDS.ra/src/frontend/qt_sdl/EmuInstance.cpp +--- melonDS.orig/src/frontend/qt_sdl/EmuInstance.cpp 2026-03-06 21:36:14.558057462 +0000 ++++ melonDS.ra/src/frontend/qt_sdl/EmuInstance.cpp 2026-03-06 21:37:07.046799886 +0000 +@@ -48,6 +48,10 @@ + #include "FreeBIOS.h" + #include "main.h" + ++#ifdef RETROACHIEVEMENTS_ENABLED ++#include "../../RetroAchievements/RAClient.h" ++#endif ++ + using std::make_unique; + using std::pair; + using std::string; +@@ -136,6 +140,10 @@ EmuInstance::EmuInstance(int inst) : del + for (int i = 0; i < kMaxWindows; i++) + windowList[i] = nullptr; + ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ ra = std::make_unique(); ++ #endif ++ + if (inst == 0) topWindow = nullptr; + createWindow(); + +@@ -158,6 +166,10 @@ EmuInstance::~EmuInstance() + + emuThread->emuExit(); + emuThread->wait(); ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ RAContext* ra = getRA(); ++ ra->Shutdown(); ++ #endif + delete emuThread; + + net.UnregisterInstance(instanceID); +@@ -222,6 +234,12 @@ void EmuInstance::createWindow(int id) + { + win->actNewWindow->setEnabled(enable); + }); ++ if (id == 0) ++ { ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ SyncRetroAchievementsFromConfig(); ++ #endif ++ } + } + + void EmuInstance::deleteWindow(int id, bool close) +@@ -1335,6 +1353,13 @@ bool EmuInstance::updateConsole() noexce + else + nds = new NDS(std::move(ndsargs), this); + ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ if (ra) ++ { ++ nds->SetRAContext(ra.get()); ++ } ++ #endif ++ + nds->Reset(); + loadRTCData(); + emuThread->updateVideoRenderer(); +@@ -2256,3 +2281,30 @@ void EmuInstance::animatedROMIcon(const + animatedSequenceRef.push_back(i); + } + } ++#ifdef RETROACHIEVEMENTS_ENABLED ++ ++void EmuInstance::SyncRetroAchievementsFromConfig() ++{ ++ auto& cfg = getLocalConfig(); ++ ++ if (!ra) ++ return; ++ ++ if (!cfg.GetBool("RetroAchievements.Enabled")) ++ { ++ ra->Disable(); ++ return; ++ } ++ ++ ra->SetCredentials( ++ cfg.GetString("RetroAchievements.Username").c_str(), ++ cfg.GetString("RetroAchievements.Password").c_str(), ++ cfg.GetBool("RetroAchievements.HardcoreMode") ++ ); ++ ++ ra->SetEncoreMode(cfg.GetBool("RetroAchievements.EncoreMode")); ++ ra->SetUnofficialEnabled(cfg.GetBool("RetroAchievements.Unofficial")); ++ ++ ra->Enable(); ++} ++#endif +\ No newline at end of file +diff -rupbN melonDS.orig/src/frontend/qt_sdl/EmuInstance.h melonDS.ra/src/frontend/qt_sdl/EmuInstance.h +--- melonDS.orig/src/frontend/qt_sdl/EmuInstance.h 2026-03-06 21:36:14.558057462 +0000 ++++ melonDS.ra/src/frontend/qt_sdl/EmuInstance.h 2026-03-06 21:37:07.046799886 +0000 +@@ -29,6 +29,10 @@ + #include "Config.h" + #include "SaveManager.h" + ++#ifdef RETROACHIEVEMENTS_ENABLED ++#include "../../RetroAchievements/RAClient.h" ++#endif ++ + const int kMaxWindows = 4; + + enum +@@ -56,6 +60,9 @@ enum + HK_GuitarGripRed, + HK_GuitarGripYellow, + HK_GuitarGripBlue, ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ HK_RAOverlayToggle, ++ #endif + HK_MAX + }; + +@@ -84,6 +91,17 @@ int getEventKeyVal(QKeyEvent* event); + class EmuInstance + { + public: ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ bool isOverlayActive() const { return overlayActive; } ++ void setOverlayActive(bool v) { overlayActive = v; } ++ void setRAOverlay(RAOverlayWidget* overlay) { raOverlay = overlay; } ++ RAOverlayWidget* getRAOverlay() const { return raOverlay; } ++ RAContext* getRA() const { return ra.get(); } ++ std::unique_ptr ra; ++ void SyncRetroAchievementsFromConfig(); ++ bool overlayActive = false; ++ RAOverlayWidget* raOverlay = nullptr; ++ #endif + EmuInstance(int inst); + ~EmuInstance(); + +@@ -379,6 +397,9 @@ private: + + friend class EmuThread; + friend class MainWindow; ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ friend class RAOverlayWidget; ++ #endif + }; + + #endif //EMUINSTANCE_H +diff -rupbN melonDS.orig/src/frontend/qt_sdl/EmuInstanceInput.cpp melonDS.ra/src/frontend/qt_sdl/EmuInstanceInput.cpp +--- melonDS.orig/src/frontend/qt_sdl/EmuInstanceInput.cpp 2026-03-06 21:36:14.558057462 +0000 ++++ melonDS.ra/src/frontend/qt_sdl/EmuInstanceInput.cpp 2026-03-06 21:37:07.046799886 +0000 +@@ -52,6 +52,9 @@ const char* EmuInstance::hotkeyNames[HK_ + "HK_FastForward", + "HK_FrameLimitToggle", + "HK_FullscreenToggle", ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ "HK_RAOverlayToggle", ++ #endif + "HK_SwapScreens", + "HK_SwapScreenEmphasis", + "HK_SolarSensorDecrease", +@@ -439,6 +442,22 @@ void EmuInstance::inputProcess() + joyInputMask &= ~(1 << i); + } + ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ static u32 lastJoyInputMask = 0xFFF; ++ u32 joyPress = lastJoyInputMask & ~joyInputMask; ++ lastJoyInputMask = joyInputMask; ++ ++ if (overlayActive && raOverlay && raOverlay->isVisible()) ++ { ++ uint32_t padState = ~joyInputMask & 0xFFF; ++ raOverlay->updateJoystick(padState); ++ ++ inputMask = 0xFFF; ++ keyInputMask = 0xFFF; ++ joyInputMask = 0xFFF; ++ } ++ #endif ++ + inputMask = keyInputMask & joyInputMask; + + joyHotkeyMask = 0; +diff -rupbN melonDS.orig/src/frontend/qt_sdl/EmuThread.cpp melonDS.ra/src/frontend/qt_sdl/EmuThread.cpp +--- melonDS.orig/src/frontend/qt_sdl/EmuThread.cpp 2026-03-06 21:36:14.558057462 +0000 ++++ melonDS.ra/src/frontend/qt_sdl/EmuThread.cpp 2026-03-06 21:37:07.046799886 +0000 +@@ -51,6 +51,10 @@ + #include "GPU_Soft.h" + #include "GPU_OpenGL.h" + ++#ifdef RETROACHIEVEMENTS_ENABLED ++#include "../../RetroAchievements/RAClient.h" ++#endif ++ + #include "Savestate.h" + + #include "EmuInstance.h" +@@ -76,6 +80,9 @@ void EmuThread::attachWindow(MainWindow* + connect(this, SIGNAL(windowEmuReset()), window, SLOT(onEmuReset())); + connect(this, SIGNAL(autoScreenSizingChange(int)), window->panel, SLOT(onAutoScreenSizingChanged(int))); + connect(this, SIGNAL(windowFullscreenToggle()), window, SLOT(onFullscreenToggled())); ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ connect(this, SIGNAL(RAOverlayToggle()), window, SLOT(onRAOverlayToggled())); ++ #endif + connect(this, SIGNAL(screenEmphasisToggle()), window, SLOT(onScreenEmphasisToggled())); + + if (window->winHasMenu()) +@@ -94,6 +101,9 @@ void EmuThread::detachWindow(MainWindow* + disconnect(this, SIGNAL(windowEmuReset()), window, SLOT(onEmuReset())); + disconnect(this, SIGNAL(autoScreenSizingChange(int)), window->panel, SLOT(onAutoScreenSizingChanged(int))); + disconnect(this, SIGNAL(windowFullscreenToggle()), window, SLOT(onFullscreenToggled())); ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ disconnect(this, SIGNAL(RAOverlayToggle()), window, SLOT(onRAOverlayToggled())); ++ #endif + disconnect(this, SIGNAL(screenEmphasisToggle()), window, SLOT(onScreenEmphasisToggled())); + + if (window->winHasMenu()) +@@ -165,6 +175,9 @@ void EmuThread::run() + + if (emuInstance->hotkeyPressed(HK_FullscreenToggle)) emit windowFullscreenToggle(); + ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ if (emuInstance->hotkeyPressed(HK_RAOverlayToggle)) emit RAOverlayToggle(); ++ #endif + if (emuInstance->hotkeyPressed(HK_SwapScreens)) emit swapScreensToggle(); + if (emuInstance->hotkeyPressed(HK_SwapScreenEmphasis)) emit screenEmphasisToggle(); + +@@ -330,6 +343,18 @@ void EmuThread::run() + winUpdateCount = 0; + } + ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ if (Config::GetGlobalTable().GetBool("RetroAchievements.Enabled") && ++ Config::GetGlobalTable().GetBool("RetroAchievements.HardcoreMode")) { ++ if (emuInstance->hotkeyPressed(HK_FastForwardToggle) || emuInstance->hotkeyPressed(HK_FastForward)) { ++ emuInstance->osdAddMessage(0xFFA0A0, "HARDCORE: Fast Forward is blocked!"); ++ } ++ if (emuInstance->hotkeyPressed(HK_SlowMoToggle) || emuInstance->hotkeyPressed(HK_SlowMo)) { ++ emuInstance->osdAddMessage(0xFFA0A0, "HARDCORE: Slow-mo is blocked!"); ++ } ++ } ++ #endif ++ + if (emuInstance->hotkeyPressed(HK_FastForwardToggle)) emuInstance->fastForwardToggled = !emuInstance->fastForwardToggled; + if (emuInstance->hotkeyPressed(HK_SlowMoToggle)) emuInstance->slowmoToggled = !emuInstance->slowmoToggled; + +@@ -338,6 +363,16 @@ void EmuThread::run() + bool enablefastforward = emuInstance->hotkeyDown(HK_FastForward) | emuInstance->fastForwardToggled; + bool enableslowmo = emuInstance->hotkeyDown(HK_SlowMo) | emuInstance->slowmoToggled; + ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ if (Config::GetGlobalTable().GetBool("RetroAchievements.Enabled") && ++ Config::GetGlobalTable().GetBool("RetroAchievements.HardcoreMode")) { ++ enablefastforward = false; ++ enableslowmo = false; ++ emuInstance->fastForwardToggled = false; ++ emuInstance->slowmoToggled = false; ++ } ++ #endif ++ + if (useOpenGL) + { + // when using OpenGL: when toggling fast-forward or slowmo, change the vsync interval +@@ -614,19 +649,51 @@ void EmuThread::handleMessages() + break; + + case msg_SaveState: ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ if (Config::GetGlobalTable().GetBool("RetroAchievements.Enabled") && ++ Config::GetGlobalTable().GetBool("RetroAchievements.HardcoreMode")) ++ { ++ emuInstance->osdAddMessage(0xFFA0A0, "Hardcore: Save states are disabled"); ++ break; ++ } ++ #endif + msgResult = emuInstance->saveState(msg.param.value().toStdString()); + break; + + case msg_LoadState: ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ if (Config::GetGlobalTable().GetBool("RetroAchievements.Enabled") && ++ Config::GetGlobalTable().GetBool("RetroAchievements.HardcoreMode")) ++ { ++ emuInstance->osdAddMessage(0xFFA0A0, "Hardcore: Load states are disabled"); ++ break; ++ } ++ #endif + msgResult = emuInstance->loadState(msg.param.value().toStdString()); + break; + + case msg_UndoStateLoad: ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ if (Config::GetGlobalTable().GetBool("RetroAchievements.Enabled") && ++ Config::GetGlobalTable().GetBool("RetroAchievements.HardcoreMode")) ++ { ++ emuInstance->osdAddMessage(0xFFA0A0, "Hardcore: Undo load is disabled"); ++ break; ++ } ++ #endif + emuInstance->undoStateLoad(); + msgResult = 1; + break; + + case msg_ImportSavefile: ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ if (Config::GetGlobalTable().GetBool("RetroAchievements.Enabled") && ++ Config::GetGlobalTable().GetBool("RetroAchievements.HardcoreMode")) ++ { ++ emuInstance->osdAddMessage(0xFFA0A0, "Hardcore: Importing savefiles is disabled"); ++ break; ++ } ++ #endif + { + msgResult = 0; + auto f = Platform::OpenFile(msg.param.value().toStdString(), Platform::FileMode::Read); +@@ -647,6 +714,14 @@ void EmuThread::handleMessages() + break; + + case msg_EnableCheats: ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ if (Config::GetGlobalTable().GetBool("RetroAchievements.Enabled") && ++ Config::GetGlobalTable().GetBool("RetroAchievements.HardcoreMode")) ++ { ++ emuInstance->osdAddMessage(0xFFA0A0, "HARDCORE: Cheats are forbidden!"); ++ break; ++ } ++ #endif + emuInstance->enableCheats(msg.param.value()); + break; + } +@@ -701,6 +776,26 @@ void EmuThread::emuRun() + + void EmuThread::emuPause(bool broadcast) + { ++#ifdef RETROACHIEVEMENTS_ENABLED ++ RAContext* ra = emuInstance->getRA(); ++ if (ra && ra->IsHardcoreEnabled()) ++ { ++ uint32_t frames_left = 0; ++ if (!ra->CanPause(&frames_left)) ++ { ++ if (frames_left > 0) ++ { ++ float seconds = frames_left / 60.0f; ++ emuInstance->osdAddMessage( ++ 0xFFA0A0, ++ "Hardcore: Wait %.1f seconds to pause", ++ seconds ++ ); ++ } ++ return; ++ } ++ } ++#endif + sendMessage(msg_EmuPause); + waitMessage(); + +@@ -739,6 +834,14 @@ void EmuThread::emuExit() + + void EmuThread::emuFrameStep() + { ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ RAContext* ra = emuInstance->getRA(); ++ if (ra->IsHardcoreEnabled()) ++ { ++ emuInstance->osdAddMessage(0xFFA0A0, "Frame step is disabled in Hardcore Mode"); ++ return; ++ } ++ #endif + if (emuPauseStack < emuPauseStackPauseThreshold) + sendMessage(msg_EmuPause); + sendMessage(msg_EmuFrameStep); +diff -rupbN melonDS.orig/src/frontend/qt_sdl/EmuThread.h melonDS.ra/src/frontend/qt_sdl/EmuThread.h +--- melonDS.orig/src/frontend/qt_sdl/EmuThread.h 2026-03-06 21:36:14.558057462 +0000 ++++ melonDS.ra/src/frontend/qt_sdl/EmuThread.h 2026-03-06 21:37:07.046799886 +0000 +@@ -155,6 +155,9 @@ signals: + + void windowFullscreenToggle(); + ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ void RAOverlayToggle(); ++ #endif + void swapScreensToggle(); + void screenEmphasisToggle(); + +diff -rupbN melonDS.orig/src/frontend/qt_sdl/InputConfig/InputConfigDialog.h melonDS.ra/src/frontend/qt_sdl/InputConfig/InputConfigDialog.h +--- melonDS.orig/src/frontend/qt_sdl/InputConfig/InputConfigDialog.h 2026-03-06 21:36:14.558057462 +0000 ++++ melonDS.ra/src/frontend/qt_sdl/InputConfig/InputConfigDialog.h 2026-03-06 21:37:07.046799886 +0000 +@@ -61,6 +61,9 @@ static constexpr std::initializer_list ++#include "RetroAchievements/RAClient.h" ++#include "EmuInstance.h" ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "Config.h" ++#include ++#include ++#include ++#include ++#include ++ ++QWidget* RAOverlayWidget::CreateCollapsibleSection(const QString& title, int count, QVBoxLayout** innerLayout) { ++ QPushButton* btn = new QPushButton(); ++ btn->setCheckable(true); ++ ++ btn->setStyleSheet( ++ "QPushButton {" ++ " background-color: #333;" ++ " color: #eee;" ++ " border: 1px solid #444;" ++ " border-radius: 4px;" ++ " padding: 5px;" ++ " text-align: left;" ++ " font-weight: bold;" ++ "}" ++ "QPushButton:hover {" ++ " background-color: #444;" ++ " border: 1px solid #666;" ++ "}" ++ "QPushButton:focus {" ++ " background-color: #555;" ++ " border: 2px solid #0078d7;" ++ "}" ++ ); ++ ++ bool isCollapsed = collapsedSections.count(title) > 0; ++ btn->setChecked(isCollapsed); ++ ++ QWidget* container = new QWidget(); ++ *innerLayout = new QVBoxLayout(container); ++ (*innerLayout)->setContentsMargins(10, 0, 0, 5); ++ (*innerLayout)->setSpacing(2); ++ ++ auto updateBtnText = [btn, title, count](bool collapsed) { ++ btn->setText(QString("%1 %2 (%3)").arg(collapsed ? "▶" : "▼").arg(title).arg(count)); ++ }; ++ ++ container->setVisible(!isCollapsed); ++ updateBtnText(isCollapsed); ++ ++ listLayout->addWidget(btn); ++ listLayout->addWidget(container); ++ ++ connect(btn, &QPushButton::toggled, [this, title, container, updateBtnText, count](bool checked) { ++ container->setVisible(!checked); ++ updateBtnText(checked); ++ ++ if (checked) collapsedSections.insert(title); ++ else collapsedSections.erase(title); ++ }); ++ ++ return container; ++} ++ ++RAOverlayWidget::RAOverlayWidget(EmuInstance* emu, QWidget* parent) ++ : QGraphicsView(parent), emuInstance(emu) ++{ ++ netManager = new QNetworkAccessManager(this); ++ setWindowFlags(Qt::FramelessWindowHint | Qt::SubWindow); ++ setAttribute(Qt::WA_TranslucentBackground); ++ setStyleSheet("background: rgba(0, 0, 0, 150); border: none;"); ++ setFrameShape(QFrame::NoFrame); ++ setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); ++ setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); ++ setFocusPolicy(Qt::StrongFocus); ++ ++ scene = new QGraphicsScene(this); ++ setScene(scene); ++ ++ scene->setBackgroundBrush(QColor(0, 0, 0, 150)); ++ ++ contentWidget = new QWidget(); ++ contentWidget->setAttribute(Qt::WA_TranslucentBackground); ++ contentWidget->setStyleSheet("background: rgba(0, 0, 0, 160); border: 1px solid rgba(255, 255, 255, 30); color: white;"); ++ ++ if (parent && parent->window()) ++ parent->window()->installEventFilter(this); ++ ++ auto* root = new QVBoxLayout(contentWidget); ++ root->setContentsMargins(20, 20, 20, 20); ++ root->setSpacing(15); ++ ++ auto* headerBar = new QHBoxLayout(); ++ headerBar->setSpacing(10); ++ ++ avatarLabel = new QLabel(); ++ avatarLabel->setFixedSize(48, 48); ++ avatarLabel->setStyleSheet("background: #555; border-radius: 24px; border: 2px solid #ffcc00;"); ++ avatarLabel->setScaledContents(true); ++ ++ usernameLabel = new QLabel("Not Logged In"); ++ usernameLabel->setStyleSheet("color: white; font-size: 16px; font-weight: bold; background: transparent; border: none;"); ++ ++ gameTitleLabel = new QLabel("No Game"); ++ gameTitleLabel->setStyleSheet("color: #ddd; font-size: 16px; background: transparent; border: none;"); ++ gameTitleLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); ++ ++ gameImgLabel = new QLabel(); ++ gameImgLabel->setFixedSize(48, 48); ++ gameImgLabel->setStyleSheet("background: #333; border-radius: 4px;"); ++ gameImgLabel->setScaledContents(true); ++ ++ timeLabel = new QLabel("--:--"); ++ timeLabel->setStyleSheet("color: #ffffff; font-size: 14px; font-family: monospace; background: transparent; border: none;"); ++ ++ playtimeLabel = new QLabel(""); ++ playtimeLabel->setStyleSheet("color: #ffffff; font-size: 11px; background: transparent; border: none;"); ++ playtimeLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); ++ ++ headerBar->addWidget(playtimeLabel); ++ headerBar->addSpacing(10); ++ headerBar->addWidget(avatarLabel); ++ headerBar->addWidget(usernameLabel); ++ headerBar->addStretch(); ++ headerBar->addWidget(gameTitleLabel); ++ headerBar->addSpacing(10); ++ headerBar->addWidget(gameImgLabel); ++ headerBar->addSpacing(20); ++ headerBar->addWidget(timeLabel); ++ root->addLayout(headerBar); ++ ++ QLabel* title = new QLabel("Achievements"); ++ title->setAlignment(Qt::AlignCenter); ++ title->setStyleSheet("font-size: 28px; font-weight: bold; color: #ffffff; margin-top: 5px; margin-bottom: 10px; background: transparent; border: none;"); ++ root->addWidget(title); ++ ++ QScrollArea* scroll = new QScrollArea; ++ scroll->setWidgetResizable(true); ++ scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); ++ scroll->setFrameShape(QFrame::NoFrame); ++ ++ float scale = 1.0f; ++ if (parent && parent->window()) { ++ constexpr float refShortSide = 384.0f; ++ float shortSide = std::min(parent->window()->width(), parent->window()->height()); ++ scale = std::clamp(shortSide / refShortSide, 0.65f, 1.25f); ++ } ++ ++ int scrollWidth = std::clamp(int(10 * scale), 8, 14); ++ int radius = scrollWidth / 2; ++ ++ scroll->setStyleSheet(QString( ++ "QScrollArea { background: transparent; border: none; }" ++ "QScrollBar:vertical {" ++ " background: #2d2d2d;" ++ " width: %1px;" ++ " border-radius: %2px;" ++ " margin: 0px;" ++ "}" ++ "QScrollBar::handle:vertical {" ++ " background: #555;" ++ " border-radius: %2px;" ++ " min-height: 25px;" ++ "}" ++ "QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical { height: 0px; }" ++ ).arg(scrollWidth).arg(radius)); ++ ++ listContainer = new QWidget; ++ listLayout = new QVBoxLayout(listContainer); ++ listLayout->setSpacing(5); ++ listLayout->setContentsMargins(0, 0, 0, 0); ++ listLayout->setAlignment(Qt::AlignTop); ++ ++ scroll->setWidget(listContainer); ++ root->addWidget(scroll, 1); ++ ++ proxy = scene->addWidget(contentWidget); ++ ++ if (auto* ra = emuInstance->getRA()) { ++ ra->SetOnMeasuredProgress([this](unsigned, unsigned, unsigned, const char*) { ++ QMetaObject::invokeMethod(this, [this]() { if (isVisible()) refresh(); }); ++ }); ++ } ++ ++ clockTimer = new QTimer(this); ++ connect(clockTimer, &QTimer::timeout, this, &RAOverlayWidget::updateClock); ++ clockTimer->start(1000); ++ updateClock(); ++} ++ ++RAOverlayWidget::~RAOverlayWidget() { ++ if (clockTimer) clockTimer->stop(); ++ if (emuInstance && emuInstance->getRA()) emuInstance->getRA()->SetOnMeasuredProgress(nullptr); ++} ++ ++void RAOverlayWidget::toggle() { ++ m_isOpen = !m_isOpen; ++ if (isVisible()) { ++ hide(); ++ emuInstance->overlayActive = false; ++ if (parentWidget()) parentWidget()->setFocus(Qt::OtherFocusReason); ++ } else { ++ int instanceID = emuInstance->getInstanceID(); ++ Config::Table cfg = Config::GetLocalTable(instanceID); ++ int rotMode = cfg.GetInt("Window0.ScreenRotation"); ++ m_currentRotation = rotMode * 90; ++ ++ if (parentWidget()) { ++ QRect pRect = parentWidget()->rect(); ++ setGeometry(pRect); ++ scene->setSceneRect(0, 0, pRect.width(), pRect.height()); ++ proxy->setRotation(0); ++ proxy->setPos(0, 0); ++ ++ if (rotMode == 1 || rotMode == 3) { ++ contentWidget->setFixedSize(pRect.height(), pRect.width()); ++ proxy->setRotation(m_currentRotation); ++ if (rotMode == 1) proxy->setPos(pRect.width(), 0); ++ else if (rotMode == 3) proxy->setPos(0, pRect.height()); ++ } else { ++ contentWidget->setFixedSize(pRect.size()); ++ if (rotMode == 2) { proxy->setRotation(180); proxy->setPos(pRect.width(), pRect.height()); } ++ } ++ } ++ ApplyRotationAndResize(); ++ refresh(); ++ show(); ++ raise(); ++ setFocus(); ++ emuInstance->overlayActive = true; ++ } ++} ++ ++void RAOverlayWidget::refresh() { ++ RAContext* ra = emuInstance->getRA(); ++ if (!ra) return; ++ ++ QRect r = contentWidget->rect(); ++ int shortSide = std::min(r.width(), r.height()); ++ ++ float uiScale = shortSide / 600.0f; ++ uiScale = std::clamp(uiScale, 0.65f, 1.0f); ++ ++ if (ra->IsLoggedIn()) { ++ usernameLabel->setText(QString::fromStdString(ra->GetUser())); ++ const char* picUrl = ra->GetUserPicURL(); ++ if (picUrl) LoadHeaderImage(avatarLabel, picUrl, QSize(48, 48)); ++ } ++ ++ if (ra->IsGameLoaded()) { ++ QString titleStr = QString::fromUtf8(ra->GetGameTitle()); ++ if (titleStr.length() > 30) titleStr = titleStr.left(27) + "..."; ++ gameTitleLabel->setText(titleStr); ++ const char* iconUrl = ra->GetGameIconURL(); ++ if (iconUrl) LoadHeaderImage(gameImgLabel, iconUrl, QSize(48, 48)); ++ } ++ ++ int hours = 0; ++ int mins = 0; ++ ++ if (ra->IsGameLoaded()) { ++ auto* gameInfo = ra->GetCurrentGameInfo(); ++ uint32_t gameID = gameInfo ? gameInfo->id : 0; ++ ++ if (gameID != 0) { ++ std::string gameKey = std::to_string(gameID); ++ int totalSeconds = Config::GetRAPlaytimeTable().GetInt(gameKey); ++ ++ hours = totalSeconds / 3600; ++ mins = (totalSeconds % 3600) / 60; ++ } ++ } ++ ++ QString playtimeStr; ++ if (hours > 0) { ++ playtimeStr = QString("Playtime: %1h %2m").arg(hours).arg(mins); ++ } else { ++ playtimeStr = QString("Playtime: %1m").arg(mins); ++ } ++ ++ playtimeLabel->setText(playtimeStr); ++ playtimeLabel->show(); ++ ++ if (contentWidget) { ++ contentWidget->setFocus(); ++ } ++ ++ QLayoutItem* child; ++ while ((child = listLayout->takeAt(0)) != nullptr) { ++ if (QWidget* w = child->widget()) { ++ w->hide(); ++ w->setFocusPolicy(Qt::NoFocus); ++ w->deleteLater(); ++ } ++ delete child; ++ } ++ ++ if (!ra->IsGameLoaded()) { ++ QLabel* info = new QLabel("Load a game with RetroAchievements support."); ++ info->setStyleSheet("color: #aaa; background: transparent; border: none;"); ++ info->setAlignment(Qt::AlignCenter); ++ listLayout->addWidget(info); ++ } else { ++ const auto& achievements = ra->GetAllAchievements(); ++ if (!achievements.empty()) { ++ QVector unlockedList; ++ QVector inProgressList; ++ QVector lockedList; ++ ++ for (const auto& ach : achievements) { ++ if (ach.unlocked) { ++ unlockedList.append(&ach); ++ } else { ++ bool hasProgress = ach.measured || !ach.progressText.empty(); ++ if (hasProgress) inProgressList.append(&ach); ++ else lockedList.append(&ach); ++ } ++ } ++ ++ if (!unlockedList.isEmpty()) { ++ QVBoxLayout* uLayout = nullptr; ++ CreateCollapsibleSection("Unlocked", unlockedList.size(), &uLayout); ++ for (const auto* ach : unlockedList) { ++ auto* item = new AchievementItemWidget(QString::fromUtf8(ach->title.c_str()), QString::fromUtf8(ach->description.c_str()), true, false, "", 0.0f, uiScale, listContainer); ++ uLayout->addWidget(item); ++ if (ach->badge_url && ach->badge_url[0] != '\0') SetBadgeImage(item, ach->badge_url); ++ } ++ } ++ ++ if (!inProgressList.isEmpty()) { ++ QVBoxLayout* pLayout = nullptr; ++ CreateCollapsibleSection("In Progress", inProgressList.size(), &pLayout); ++ for (const auto* ach : inProgressList) { ++ auto* item = new AchievementItemWidget(QString::fromUtf8(ach->title.c_str()), QString::fromUtf8(ach->description.c_str()), false, true, QString::fromStdString(ach->progressText), ach->measured_percent, uiScale, listContainer); ++ pLayout->addWidget(item); ++ if (ach->badge_locked_url && ach->badge_locked_url[0] != '\0') SetBadgeImage(item, ach->badge_locked_url); ++ } ++ } ++ ++ if (!lockedList.isEmpty()) { ++ QVBoxLayout* lLayout = nullptr; ++ CreateCollapsibleSection("Locked", lockedList.size(), &lLayout); ++ for (const auto* ach : lockedList) { ++ auto* item = new AchievementItemWidget(QString::fromUtf8(ach->title.c_str()), QString::fromUtf8(ach->description.c_str()), false, false, "", 0.0f, uiScale, listContainer); ++ lLayout->addWidget(item); ++ if (ach->badge_locked_url && ach->badge_locked_url[0] != '\0') SetBadgeImage(item, ach->badge_locked_url); ++ } ++ } ++ } ++ } ++ listLayout->addStretch(); ++} ++ ++void RAOverlayWidget::updateJoystick(uint32_t joyState) { ++ if (!isVisible()) return; ++ ++ constexpr int BIT_UP = 6, BIT_DOWN = 7, BIT_A = 0; ++ ++ uint32_t navMask = joyState & ((1 << BIT_UP) | (1 << BIT_DOWN)); ++ if ((navMask & ~heldMask) != 0) { repeatTimer.restart(); repeating = false; } ++ heldMask = navMask; ++ ++ bool doRepeat = false; ++ if (heldMask != 0) { ++ if (!repeating && repeatTimer.elapsed() >= 200) { repeating = true; repeatTimer.restart(); doRepeat = true; } ++ else if (repeating && repeatTimer.elapsed() >= 60) { repeatTimer.restart(); doRepeat = true; } ++ } ++ ++ if (navMask != 0 || doRepeat) { ++ Qt::Key key = (heldMask & (1 << BIT_UP)) ? Qt::Key_Backtab : Qt::Key_Tab; ++ QKeyEvent event(QEvent::KeyPress, key, Qt::NoModifier); ++ QCoreApplication::sendEvent(scene, &event); ++ } ++ ++ bool isAPressed = (joyState & (1 << BIT_A)); ++ bool wasAPressed = (lastJoyState & (1 << BIT_A)); ++ ++ if (isAPressed && !wasAPressed) { ++ if (auto* btn = qobject_cast(contentWidget->focusWidget())) { ++ btn->click(); ++ } ++ } ++ ++ if (auto* next = contentWidget->focusWidget()) { ++ if (auto* scroll = contentWidget->findChild()) { ++ scroll->ensureWidgetVisible(next, 20, 20); ++ } ++ } ++ ++ if (navMask == 0) { heldMask = 0; repeating = false; } ++ ++ lastJoyState = joyState; ++} ++ ++bool RAOverlayWidget::event(QEvent* e) { ++ if (e->type() == QEvent::KeyPress) { ++ QKeyEvent* ke = static_cast(e); ++ Config::Table cfg = Config::GetLocalTable(emuInstance->getInstanceID()); ++ ++ int cfgUp = cfg.GetInt("Keyboard.Up"); ++ int cfgDown = cfg.GetInt("Keyboard.Down"); ++ int cfgA = cfg.GetInt("Keyboard.A"); ++ ++ bool isUp = (ke->key() == cfgUp || ke->key() == Qt::Key_Up); ++ bool isDown = (ke->key() == cfgDown || ke->key() == Qt::Key_Down); ++ ++ bool isConfirm = (ke->key() == cfgA || ke->key() == Qt::Key_Return || ke->key() == Qt::Key_Enter); ++ ++ if (isUp || isDown) { ++ Qt::Key key = isDown ? Qt::Key_Tab : Qt::Key_Backtab; ++ QKeyEvent event(QEvent::KeyPress, key, Qt::NoModifier); ++ QCoreApplication::sendEvent(scene, &event); ++ return true; ++ } ++ ++ if (isConfirm) { ++ if (!ke->isAutoRepeat()) { ++ if (auto* btn = qobject_cast(contentWidget->focusWidget())) { ++ btn->click(); ++ return true; ++ } ++ } ++ return true; ++ } ++ ++ if (parentWidget()) { ++ return QCoreApplication::sendEvent(parentWidget(), e); ++ } ++ } ++ return QGraphicsView::event(e); ++} ++ ++void RAOverlayWidget::updateClock() { ++ timeLabel->setText(QDateTime::currentDateTime().toString("HH:mm")); ++ ++ if (isVisible()) { ++ RAContext* ra = emuInstance->getRA(); ++ if (ra && ra->IsGameLoaded()) { ++ ++ auto* gameInfo = ra->GetCurrentGameInfo(); ++ uint32_t gameID = gameInfo ? gameInfo->id : 0; ++ ++ int totalSeconds = 0; ++ if (gameID != 0) { ++ std::string gameKey = std::to_string(gameID); ++ totalSeconds = Config::GetRAPlaytimeTable().GetInt(gameKey); ++ } ++ ++ int hours = totalSeconds / 3600; ++ int mins = (totalSeconds % 3600) / 60; ++ ++ QString playtimeStr; ++ if (hours > 0) { ++ playtimeStr = QString("Playtime: %1h %2m").arg(hours).arg(mins); ++ } else { ++ playtimeStr = QString("Playtime: %1m").arg(mins); ++ } ++ ++ playtimeLabel->setText(playtimeStr); ++ if (playtimeLabel->isHidden()) playtimeLabel->show(); ++ } else { ++ playtimeLabel->hide(); ++ } ++ } ++} ++ ++bool RAOverlayWidget::eventFilter(QObject* obj, QEvent* event) { ++ if (obj == parentWidget()->window() && ++ (event->type() == QEvent::Resize || ++ event->type() == QEvent::Move || ++ event->type() == QEvent::WindowStateChange)) ++ { ++ if (isVisible()) { ++ ApplyRotationAndResize(); ++ } ++ } ++ return QGraphicsView::eventFilter(obj, event); ++} ++ ++void RAOverlayWidget::SetBadgeImage(AchievementItemWidget* item, const char* url) { ++ if (!url || !*url) return; ++ QString qurl = QString::fromUtf8(url); ++ if (badgeCache.contains(qurl)) { item->updateIcon(badgeCache[qurl]); return; } ++ QPointer safeItem(item); ++ QNetworkReply* reply = netManager->get(QNetworkRequest(QUrl(qurl))); ++ connect(reply, &QNetworkReply::finished, this, [this, reply, safeItem, qurl]() { ++ reply->deleteLater(); ++ if (safeItem && reply->error() == QNetworkReply::NoError) { ++ QPixmap pix; if (pix.loadFromData(reply->readAll())) { badgeCache.insert(qurl, pix); safeItem->updateIcon(pix); } ++ } ++ }); ++} ++ ++void RAOverlayWidget::LoadHeaderImage(QLabel* targetLabel, const char* url, QSize size) { ++ if (!url || !*url || !targetLabel) return; ++ QString qurl = QString::fromUtf8(url); ++ if (headerImageCache.contains(qurl)) { targetLabel->setPixmap(headerImageCache[qurl]); targetLabel->setStyleSheet("background: transparent; border: none;"); return; } ++ QPointer safeLabel(targetLabel); ++ QNetworkReply* reply = netManager->get(QNetworkRequest(QUrl(qurl))); ++ connect(reply, &QNetworkReply::finished, this, [this, reply, safeLabel, qurl, size]() { ++ reply->deleteLater(); ++ if (safeLabel && reply->error() == QNetworkReply::NoError) { ++ QPixmap pix; if (pix.loadFromData(reply->readAll())) { ++ QPixmap scaled = pix.scaled(size, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); ++ headerImageCache.insert(qurl, scaled); safeLabel->setPixmap(scaled); safeLabel->setStyleSheet("background: transparent; border: none;"); ++ } ++ } ++ }); ++} ++void RAOverlayWidget::ApplyRotationAndResize() ++{ ++ if (!parentWidget()) return; ++ ++ int instanceID = emuInstance->getInstanceID(); ++ Config::Table cfg = Config::GetLocalTable(instanceID); ++ int rotMode = cfg.GetInt("Window0.ScreenRotation"); ++ m_currentRotation = rotMode * 90; ++ ++ QRect pRect = parentWidget()->rect(); ++ setGeometry(pRect); ++ scene->setSceneRect(0, 0, pRect.width(), pRect.height()); ++ ++ proxy->setRotation(0); ++ proxy->setPos(0, 0); ++ ++ if (rotMode == 1 || rotMode == 3) { ++ contentWidget->setFixedSize(pRect.height(), pRect.width()); ++ proxy->setRotation(m_currentRotation); ++ if (rotMode == 1) proxy->setPos(pRect.width(), 0); ++ else proxy->setPos(0, pRect.height()); ++ } else { ++ contentWidget->setFixedSize(pRect.size()); ++ if (rotMode == 2) { ++ proxy->setRotation(180); ++ proxy->setPos(pRect.width(), pRect.height()); ++ } ++ } ++ ++ int shortSide = std::min(contentWidget->width(), contentWidget->height()); ++ bool mini = (shortSide < 420); ++ ++ avatarLabel->setVisible(!mini); ++ usernameLabel->setVisible(!mini); ++ timeLabel->setVisible(!mini); ++ gameTitleLabel->setVisible(!mini); ++ ++ if (auto* root = qobject_cast(contentWidget->layout())) { ++ if (mini) { ++ root->setContentsMargins(10, 5, 10, 10); ++ root->setSpacing(5); ++ } else { ++ root->setContentsMargins(20, 20, 20, 20); ++ root->setSpacing(15); ++ } ++ } ++} +\ No newline at end of file +diff -rupbN melonDS.orig/src/frontend/qt_sdl/RAOverlayWidget.h melonDS.ra/src/frontend/qt_sdl/RAOverlayWidget.h +--- melonDS.orig/src/frontend/qt_sdl/RAOverlayWidget.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/frontend/qt_sdl/RAOverlayWidget.h 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,74 @@ ++#pragma once ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++class EmuInstance; ++class AchievementItemWidget; ++ ++class RAOverlayWidget : public QGraphicsView ++{ ++ Q_OBJECT ++public: ++ bool isOpen() const { return m_isOpen; } ++ explicit RAOverlayWidget(EmuInstance* emu, QWidget* parent); ++ ~RAOverlayWidget(); ++ ++ void updateJoystick(uint32_t joyState); ++ void refresh(); ++ void toggle(); ++ ++protected: ++ bool eventFilter(QObject* obj, QEvent* event) override; ++ bool event(QEvent* e) override; ++ ++private: ++ void ApplyRotationAndResize(); ++ std::set collapsedSections; ++ uint32_t lastJoyState = 0; ++ bool m_isOpen = false; ++ void updateClock(); ++ void SetBadgeImage(AchievementItemWidget* item, const char* url); ++ void LoadHeaderImage(QLabel* targetLabel, const char* url, QSize size); ++ ++ QWidget* CreateCollapsibleSection(const QString& title, int count, QVBoxLayout** innerLayout); ++ ++ EmuInstance* emuInstance; ++ QNetworkAccessManager* netManager; ++ ++ QGraphicsScene* scene; ++ QGraphicsProxyWidget* proxy; ++ QWidget* contentWidget; ++ ++ QLabel* avatarLabel; ++ QLabel* usernameLabel; ++ QLabel* gameTitleLabel; ++ QLabel* gameImgLabel; ++ QLabel* timeLabel; ++ QLabel* playtimeLabel; ++ QWidget* listContainer; ++ QVBoxLayout* listLayout; ++ ++ QHash badgeCache; ++ QHash headerImageCache; ++ QTimer* clockTimer; ++ ++ int m_currentRotation = 0; ++ ++ static constexpr int INITIAL_DELAY_MS = 400; ++ static constexpr int REPEAT_DELAY_MS = 80; ++ QElapsedTimer repeatTimer; ++ uint32_t heldMask = 0; ++ bool repeating = false; ++}; +\ No newline at end of file +diff -rupbN melonDS.orig/src/frontend/qt_sdl/RASettingsDialog.cpp melonDS.ra/src/frontend/qt_sdl/RASettingsDialog.cpp +--- melonDS.orig/src/frontend/qt_sdl/RASettingsDialog.cpp 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/frontend/qt_sdl/RASettingsDialog.cpp 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,214 @@ ++#include "RASettingsDialog.h" ++#include "ui_RASettingsDialog.h" ++ ++#include "Config.h" ++#include "main.h" ++#include "RetroAchievements/RAClient.h" ++ ++#include ++#include ++#include ++#include ++#include ++ ++bool RASettingsDialog::needsReset = false; ++RASettingsDialog::RASettingsDialog(EmuInstance* inst, QWidget* parent) ++ : QDialog(parent) ++ , ui(new Ui::RASettingsDialog) ++ , emuInstance(inst) ++{ ++ ui->setupUi(this); ++ ++ connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &RASettingsDialog::accept); ++ connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &RASettingsDialog::reject); ++ ++ setAttribute(Qt::WA_DeleteOnClose); ++ ++ auto& instcfg = emuInstance->getLocalConfig(); ++ ui->cbRAEnabled->setChecked(instcfg.GetBool("RetroAchievements.Enabled")); ++ ui->cbRAHardcore->setChecked(instcfg.GetBool("RetroAchievements.HardcoreMode")); ++ ui->leRAUsername->setText(QString::fromStdString(instcfg.GetString("RetroAchievements.Username"))); ++ ui->leRAPassword->setText(QString::fromStdString(instcfg.GetString("RetroAchievements.Password"))); ++ ui->cbRAAchievementToasts->setChecked(instcfg.GetBool("RetroAchievements.HideToasts")); ++ ui->cbRAChallengeIndicators->setChecked(instcfg.GetBool("RetroAchievements.HideChallengeIndicators")); ++ ui->cbRAEncoreMode->setChecked(instcfg.GetBool("RetroAchievements.EncoreMode")); ++ ui->cbRAUnofficialMode->setChecked(instcfg.GetBool("RetroAchievements.Unofficial")); ++ ui->cbRALeaderboardCounter->setChecked(instcfg.GetBool("RetroAchievements.HideLeaderboardCounter")); ++ ui->cbRALeaderboardToasts->setChecked(instcfg.GetBool("RetroAchievements.HideLeaderboardToasts")); ++ ++ auto UpdateRAUI = [this]() { ++ RAContext* ra = emuInstance->getRA(); ++ if (!ra) return; ++ ++ bool loggedIn = ra->IsLoggedIn(); ++ bool emuRunning = emuInstance->emuIsActive(); ++ ++ ui->cbRAEnabled->setEnabled(!loggedIn); ++ ui->cbRAHardcore->setEnabled(!loggedIn); ++ ui->leRAUsername->setEnabled(!loggedIn); ++ ui->leRAPassword->setEnabled(!loggedIn); ++ ui->btnRALogin->setEnabled(!emuRunning); ++ ++ if (emuRunning) { ++ ui->btnRALogin->setToolTip( ++ "Stop the emulation before logging in or out of RetroAchievements." ++ ); ++ } else { ++ ui->btnRALogin->setToolTip(QString()); ++ } ++ ++ if (loggedIn) { ++ ui->btnRALogin->setText("Logout"); ++ ++ const rc_client_user_t* user = rc_client_get_user_info(ra->client); ++ if (user && user->display_name) ++ ui->lblRAStatus->setText(QString("Logged in as: %1").arg(user->display_name)); ++ else ++ ui->lblRAStatus->setText("Logged in"); ++ ++ ui->lblRAStatus->setStyleSheet("font-weight: bold; color: #2ecc71;"); ++ } else { ++ ui->btnRALogin->setText("Login Now"); ++ ui->lblRAStatus->setText("Not logged in"); ++ ui->lblRAStatus->setStyleSheet("color: gray;"); ++ } ++ }; ++ ++ UpdateRAUI(); ++ ++ connect(ui->btnRALogin, &QPushButton::clicked, this, [this, UpdateRAUI]() { ++ RAContext* ra = emuInstance->getRA(); ++ if (!ra) return; ++ ++ if (ra->IsLoggedIn()) { ++ ra->SetLoggedIn(false); ++ ra->SetToken(""); ++ UpdateRAUI(); ++ ++ ui->cbRAEnabled->setProperty("user_originalValue", !ui->cbRAEnabled->isChecked()); ++ ui->cbRAHardcore->setProperty("user_originalValue", !ui->cbRAHardcore->isChecked()); ++ ui->leRAUsername->setProperty("user_originalValue", ""); ++ ui->leRAPassword->setProperty("user_originalValue", ""); ++ ++ if (emuInstance && emuInstance->emuIsActive()) { ++ done(QDialog::Accepted); ++ } ++ ++ } else { ++ std::string user = ui->leRAUsername->text().toStdString(); ++ std::string pass = ui->leRAPassword->text().toStdString(); ++ if (user.empty() || pass.empty()) return; ++ ++ ra->LoginWithPassword(user.c_str(), pass.c_str(), ui->cbRAHardcore->isChecked()); ++ ++ ui->cbRAEnabled->setProperty("user_originalValue", !ui->cbRAEnabled->isChecked()); ++ ui->cbRAHardcore->setProperty("user_originalValue", !ui->cbRAHardcore->isChecked()); ++ ui->leRAUsername->setProperty("user_originalValue", ""); ++ ui->leRAPassword->setProperty("user_originalValue", ""); ++ ++ if (emuInstance && emuInstance->emuIsActive()) { ++ done(QDialog::Accepted); ++ } ++ } ++ }); ++ ++ RAContext* raTmp = emuInstance->getRA(); ++ if (raTmp) { ++ auto mainWin = emuInstance->getMainWindow(); ++ raTmp->onLoginResponse = [this, UpdateRAUI, mainWin](bool success, const std::string& msg) { ++ QMetaObject::invokeMethod(this, [this, UpdateRAUI, mainWin, success, msg]() { ++ UpdateRAUI(); ++ if (mainWin) { ++ mainWin->ShowRALoginToast(success, msg); ++ } ++ }); ++ }; ++ } ++ ++#define SET_ORIGVAL(type, val) \ ++ for (type* w : findChildren(nullptr)) \ ++ w->setProperty("user_originalValue", w->val()); ++ ++ SET_ORIGVAL(QLineEdit, text); ++ SET_ORIGVAL(QCheckBox, isChecked); ++ ++#undef SET_ORIGVAL ++} ++ ++RASettingsDialog::~RASettingsDialog() ++{ ++ if (emuInstance) { ++ if (auto* ra = emuInstance->getRA()) { ++ ra->onLoginResponse = nullptr; ++ } ++ } ++ delete ui; ++} ++ ++void RASettingsDialog::done(int r) ++{ ++ if (!emuInstance) ++ { ++ QDialog::done(r); ++ return; ++ } ++ ++ needsReset = false; ++ ++#ifdef RETROACHIEVEMENTS_ENABLED ++ if (r == QDialog::Accepted) ++ { ++ bool modified = false; ++ ++#define CHECK_ORIGVAL(type, val) \ ++ if (!modified) for (type* w : findChildren(nullptr)) \ ++ { \ ++ QVariant v = w->val(); \ ++ if (v != w->property("user_originalValue")) \ ++ { \ ++ modified = true; \ ++ break; \ ++ } \ ++ } ++ ++ CHECK_ORIGVAL(QLineEdit, text); ++ CHECK_ORIGVAL(QCheckBox, isChecked); ++ ++#undef CHECK_ORIGVAL ++ ++ if (modified) ++ { ++ if (emuInstance->emuIsActive() ++ && QMessageBox::warning( ++ this, ++ "Reset necessary to apply changes", ++ "The emulation will be reset for the changes to take place.", ++ QMessageBox::Ok, ++ QMessageBox::Cancel) != QMessageBox::Ok) ++ { ++ return; ++ } ++ ++ auto& instcfg = emuInstance->getLocalConfig(); ++ ++ instcfg.SetBool("RetroAchievements.Enabled", ui->cbRAEnabled->isChecked()); ++ instcfg.SetBool("RetroAchievements.HardcoreMode", ui->cbRAHardcore->isChecked()); ++ instcfg.SetString("RetroAchievements.Username", ui->leRAUsername->text().toStdString()); ++ instcfg.SetString("RetroAchievements.Password", ui->leRAPassword->text().toStdString()); ++ instcfg.SetBool("RetroAchievements.HideToasts", ui->cbRAAchievementToasts->isChecked()); ++ instcfg.SetBool("RetroAchievements.HideChallengeIndicators", ui->cbRAChallengeIndicators->isChecked()); ++ instcfg.SetBool("RetroAchievements.EncoreMode", ui->cbRAEncoreMode->isChecked()); ++ instcfg.SetBool("RetroAchievements.Unofficial", ui->cbRAUnofficialMode->isChecked()); ++ instcfg.SetBool("RetroAchievements.HideLeaderboardCounter", ui->cbRALeaderboardCounter->isChecked()); ++ instcfg.SetBool("RetroAchievements.HideLeaderboardToasts", ui->cbRALeaderboardToasts->isChecked()); ++ ++ emuInstance->SyncRetroAchievementsFromConfig(); ++ Config::Save(); ++ ++ needsReset = true; ++ } ++ } ++#endif ++ ++ QDialog::done(r); ++} +\ No newline at end of file +diff -rupbN melonDS.orig/src/frontend/qt_sdl/RASettingsDialog.h melonDS.ra/src/frontend/qt_sdl/RASettingsDialog.h +--- melonDS.orig/src/frontend/qt_sdl/RASettingsDialog.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/frontend/qt_sdl/RASettingsDialog.h 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,42 @@ ++#pragma once ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++class EmuInstance; ++ ++namespace Ui { ++class RASettingsDialog; ++} ++ ++class RASettingsDialog : public QDialog ++{ ++ Q_OBJECT ++ ++public: ++ static bool needsReset; ++ explicit RASettingsDialog(EmuInstance* inst, QWidget* parent = nullptr); ++ ~RASettingsDialog() override; ++ ++ void done(int r) override; ++ ++private: ++ Ui::RASettingsDialog* ui; ++ ++ QGroupBox* groupRA; ++ QCheckBox* cbRAEnabled; ++ QCheckBox* cbRAHardcore; ++ QLineEdit* leRAUsername; ++ QLineEdit* leRAPassword; ++ QPushButton* btnRALogin; ++ QLabel* lblRAStatus; ++ ++ EmuInstance* emuInstance; ++}; +\ No newline at end of file +diff -rupbN melonDS.orig/src/frontend/qt_sdl/RASettingsDialog.ui melonDS.ra/src/frontend/qt_sdl/RASettingsDialog.ui +--- melonDS.orig/src/frontend/qt_sdl/RASettingsDialog.ui 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/frontend/qt_sdl/RASettingsDialog.ui 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,187 @@ ++ ++ ++ RASettingsDialog ++ ++ ++ ++ 0 ++ 0 ++ 420 ++ 300 ++ ++ ++ ++ RetroAchievements Settings ++ ++ ++ ++ ++ ++ ++ Login ++ ++ ++ ++ ++ ++ RetroAchievements – Login ++ ++ ++ ++ ++ ++ Enable RetroAchievements ++ ++ ++ ++ ++ ++ ++ Hardcore Mode (No Savestates) ++ ++ ++ ++ ++ ++ ++ Username: ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Password: ++ ++ ++ ++ ++ ++ ++ QLineEdit::Password ++ ++ ++ ++ ++ ++ ++ Login Now ++ ++ ++ ++ ++ ++ ++ Not logged in ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Qt::Vertical ++ ++ ++ ++ 20 ++ 40 ++ ++ ++ ++ ++ ++ ++ ++ ++Options ++ ++ ++ ++ ++ ++ RetroAchievements – Options ++ ++ ++ ++ ++ ++ Disable achievement toasts ++ ++ ++ ++ ++ ++ ++ Hide challenge indicators ++ ++ ++ ++ ++ ++ ++ Enable Encore Mode ++ ++ ++ ++ ++ ++ ++ Allow unofficial achievements ++ ++ ++ ++ ++ ++ ++ Hide leaderboard counter ++ ++ ++ ++ ++ ++ ++ Disable leaderboard toasts ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Qt::Vertical ++ ++ ++ ++ 20 ++ 40 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Qt::Horizontal ++ ++ ++ QDialogButtonBox::Ok|QDialogButtonBox::Cancel ++ ++ ++ ++ ++ ++ ++ ++ +\ No newline at end of file +diff -rupbN melonDS.orig/src/frontend/qt_sdl/Window.cpp melonDS.ra/src/frontend/qt_sdl/Window.cpp +--- melonDS.orig/src/frontend/qt_sdl/Window.cpp 2026-03-06 21:36:14.566057575 +0000 ++++ melonDS.ra/src/frontend/qt_sdl/Window.cpp 2026-03-06 21:37:07.046799886 +0000 +@@ -82,6 +82,14 @@ + #include "Window.h" + #include "AboutDialog.h" + ++#ifdef RETROACHIEVEMENTS_ENABLED ++#include "RASettingsDialog.h" ++#include "RetroAchievements/RAClient.h" ++#include "toast/BadgeCache.h" ++#include "RAOverlayWidget.h" ++#include ++#endif ++ + using namespace melonDS; + + +@@ -234,6 +242,10 @@ MainWindow::MainWindow(int id, EmuInstan + windowCfg(localCfg.GetTable("Window"+std::to_string(id), "Window0")), + emuThread(inst->getEmuThread()), + enabledSaved(false), ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ m_badgeCache(this), ++ m_toastManager(this), ++ #endif + focused(true) + { + #ifndef _WIN32 +@@ -640,6 +652,11 @@ MainWindow::MainWindow(int id, EmuInstan + actMPSettings = menu->addAction("Multiplayer settings"); + connect(actMPSettings, &QAction::triggered, this, &MainWindow::onOpenMPSettings); + ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ actRASettings = menu->addAction("RA settings"); ++ connect(actRASettings, &QAction::triggered, this, &MainWindow::onOpenRASettings); ++ #endif ++ + actWifiSettings = menu->addAction("Wifi settings"); + connect(actWifiSettings, &QAction::triggered, this, &MainWindow::onOpenWifiSettings); + +@@ -784,6 +801,132 @@ MainWindow::MainWindow(int id, EmuInstan + #endif // __APPLE__ + } + ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ m_oldRAEnabled = Config::GetLocalTable(emuInstance->instanceID).GetBool("Instance*.RetroAchievements.Enabled"); ++ m_toastManager.Init(this); ++ if (auto* ra = inst->getRA()) ++ { ++ ra->SetOnGameLoadedCallback([this]() { ++ QMetaObject::invokeMethod(this, [this]() { ++ ShowGameLoadToast(); ++ }, Qt::QueuedConnection); ++ }); ++ ++ ra->onLoginResponse = [this](bool success, const std::string& message) { ++ ShowRALoginToast(success, message); ++ }; ++ ++ ra->SetOnAchievementUnlocked( ++ [this](const char* title, ++ const char* desc, ++ const char* badgeUrl) ++ { ++ QMetaObject::invokeMethod( ++ this, ++ [this, ++ t = QString::fromUtf8(title), ++ d = QString::fromUtf8(desc), ++ b = QString::fromUtf8(badgeUrl)]() ++ { ++ OnAchievementUnlocked(t, d, b); ++ }, ++ Qt::QueuedConnection ++ ); ++ }); ++ ra->SetOnAchievementProgress( ++ [this](const char* title, ++ const char* progress, ++ const char* badgeUrl) ++ { ++ QMetaObject::invokeMethod( ++ this, ++ [this, ++ t = QString::fromUtf8(title), ++ p = QString::fromUtf8(progress), ++ b = QString::fromUtf8(badgeUrl)]() ++ { ++ OnAchievementProgress(t, p, b); ++ }, ++ Qt::QueuedConnection ++ ); ++ }); ++ ra->SetOnChallenge([this](const char* badgeUrl) { ++ if (!badgeUrl) return; ++ QString b = QString::fromUtf8(badgeUrl); ++ ++ QMetaObject::invokeMethod(this, [this, b]() { ++ OnChallengeShow(b); ++ }, Qt::QueuedConnection); ++ }); ++ ++ ra->SetOnChallengeHide([this]() { ++ QMetaObject::invokeMethod(this, [this]() { ++ m_toastManager.HideChallengeIndicator(""); ++ }, Qt::QueuedConnection); ++ }); ++ ++ ra->SetOnLeaderboardTrackerUpdate([this](const char* display) { ++ QString d = QString::fromUtf8(display); ++ QMetaObject::invokeMethod(this, [this, d]() { ++ this->OnLeaderboardTrackerUpdate(d); // Dodaj this-> dla jasności ++ }, Qt::QueuedConnection); ++ }); ++ ++ ra->SetOnLeaderboardSubmitted([this](const char* title, const char* score, unsigned rank) { ++ QString t = QString::fromUtf8(title); ++ QString s = QString::fromUtf8(score); ++ QMetaObject::invokeMethod(this, [this, t, s, rank]() { ++ OnLeaderboardSubmitted(t, s, rank); ++ }, Qt::QueuedConnection); ++ }); ++ ++ QPointer self(this); ++ ++ ra->SetOnRADisconnected([self]() { ++ if (!self) return; ++ QMetaObject::invokeMethod(self, [self]() { ++ if (!self) return; ++ self->OnRADisconnected(); ++ }, Qt::QueuedConnection); ++ }); ++ ++ ra->SetOnRAReconnected([self]() { ++ if (!self) return; ++ QMetaObject::invokeMethod(self, [self]() { ++ if (!self) return; ++ self->OnRAReconnected(); ++ }, Qt::QueuedConnection); ++ }); ++ ++ ra->SetOnRAPendingSent([self](int count) { ++ if (!self) return; ++ QMetaObject::invokeMethod(self, [self, count]() { ++ if (!self) return; ++ self->OnRAPendingSent(count); ++ }, Qt::QueuedConnection); ++ }); ++ ++ ra->SetOnGameMastered( ++ [this, ra](const std::string& title, const std::string& /*rp_text*/) ++ { ++ QString gameBadgeUrl; ++ const rc_client_game_t* gameInfo = ra->GetCurrentGameInfo(); ++ if (gameInfo && gameInfo->badge_url) { ++ gameBadgeUrl = QString::fromUtf8(gameInfo->badge_url); ++ } ++ ++ QMetaObject::invokeMethod(this, [this, ++ t = QString::fromStdString(title), ++ b = gameBadgeUrl]() ++ { ++ OnGameMastered(t, b); ++ }, Qt::QueuedConnection); ++ }); ++ } ++ raOverlay = new RAOverlayWidget(emuInstance, this); ++ raOverlay->setGeometry(rect()); ++ emuInstance->setRAOverlay(raOverlay); ++ #endif + if (emuThread->emuIsActive()) + onEmuStart(); + } +@@ -1554,6 +1697,17 @@ void MainWindow::onEjectGBACart() + + void MainWindow::onSaveState() + { ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ RAContext* ra = emuInstance->getRA(); ++ auto cfg = Config::GetLocalTable(emuInstance->instanceID); ++ if (cfg.GetBool("Instance*.RetroAchievements.Enabled") && ++ cfg.GetBool("Instance*.RetroAchievements.HardcoreMode") && ++ ra->IsLoggedIn()) ++ { ++ emuInstance->osdAddMessage(0xFFA0A0, "Savestates states is disabled in Hardcore Mode"); ++ return; ++ } ++ #endif + int slot = ((QAction*)sender())->data().toInt(); + + QString filename; +@@ -1589,6 +1743,17 @@ void MainWindow::onSaveState() + + void MainWindow::onLoadState() + { ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ RAContext* ra = emuInstance->getRA(); ++ auto cfg = Config::GetLocalTable(emuInstance->instanceID); ++ if (cfg.GetBool("Instance*.RetroAchievements.Enabled") && ++ cfg.GetBool("Instance*.RetroAchievements.HardcoreMode") && ++ ra->IsLoggedIn()) ++ { ++ emuInstance->osdAddMessage(0xFFA0A0, "Savestates disabled in Hardcore Mode"); ++ return; ++ } ++ #endif + int slot = ((QAction*)sender())->data().toInt(); + + QString filename; +@@ -1639,6 +1804,17 @@ void MainWindow::onUndoStateLoad() + + void MainWindow::onImportSavefile() + { ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ RAContext* ra = emuInstance->getRA(); ++ auto cfg = Config::GetLocalTable(emuInstance->instanceID); ++ if (cfg.GetBool("Instance*.RetroAchievements.Enabled") && ++ cfg.GetBool("Instance*.RetroAchievements.HardcoreMode") && ++ ra->IsLoggedIn()) ++ { ++ QMessageBox::critical(this, "melonDS", "Importing savefiles is disabled in Hardcore Mode."); ++ return; ++ } ++ #endif + QString path = QFileDialog::getOpenFileName(this, + "Select savefile", + globalCfg.GetQString("LastROMFolder"), +@@ -1699,6 +1875,9 @@ void MainWindow::onPause(bool checked) + + void MainWindow::onReset() + { ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ m_toastManager.HideChallengeIndicator(""); ++ #endif + if (!emuThread->emuIsActive()) return; + + emuThread->emuReset(); +@@ -1706,6 +1885,9 @@ void MainWindow::onReset() + + void MainWindow::onStop() + { ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ m_toastManager.HideChallengeIndicator(""); ++ #endif + if (!emuThread->emuIsActive()) return; + + emuThread->emuStop(true); +@@ -1730,6 +1912,18 @@ void MainWindow::onOpenPowerManagement() + + void MainWindow::onEnableCheats(bool checked) + { ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ RAContext* ra = emuInstance->getRA(); ++ auto cfg = Config::GetLocalTable(emuInstance->instanceID); ++ if (checked && cfg.GetBool("Instance*.RetroAchievements.Enabled") && ++ cfg.GetBool("Instance*.RetroAchievements.HardcoreMode") && ++ ra->IsLoggedIn()) ++ { ++ emuInstance->osdAddMessage(0xFFA0A0, "Cheats are disabled in Hardcore Mode"); ++ actEnableCheats->setChecked(false); ++ return; ++ } ++ #endif + localCfg.SetBool("EnableCheats", checked); + emuThread->enableCheats(checked); + +@@ -1741,6 +1935,17 @@ void MainWindow::onEnableCheats(bool che + + void MainWindow::onSetupCheats() + { ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ RAContext* ra = emuInstance->getRA(); ++ auto cfg = Config::GetLocalTable(emuInstance->instanceID); ++ if (cfg.GetBool("Instance*.RetroAchievements.Enabled") && ++ cfg.GetBool("Instance*.RetroAchievements.HardcoreMode") && ++ ra->IsLoggedIn()) ++ { ++ emuInstance->osdAddMessage(0xFFA0A0, "Cheat menu is disabled in Hardcore Mode"); ++ return; ++ } ++ #endif + emuThread->emuPause(); + + CheatsDialog* dlg = CheatsDialog::openDlg(this); +@@ -1870,6 +2075,52 @@ void MainWindow::onEmuSettingsDialogFini + if (!emuThread->emuIsActive()) + actTitleManager->setEnabled(!globalCfg.GetString("DSi.NANDPath").empty()); + ++#ifdef RETROACHIEVEMENTS_ENABLED ++if (auto* ra = emuInstance->getRA()) ++{ ++ const bool newRAEnabled = ++ localCfg.GetBool("Instance*.RetroAchievements.Enabled"); ++ if (m_oldRAEnabled != newRAEnabled) ++ { ++ if (newRAEnabled) ++ { ++ std::string user = ++ localCfg.GetString("Instance*.RetroAchievements.Username"); ++ std::string pass = ++ localCfg.GetString("Instance*.RetroAchievements.Password"); ++ bool hardcore = ++ localCfg.GetBool("Instance*.RetroAchievements.Hardcore"); ++ ++ ra->SetCredentials( ++ user.c_str(), ++ pass.c_str(), ++ hardcore ++ ); ++ ++ ra->Enable(); ++ ++ m_toastManager.ShowAchievement( ++ "RetroAchievements", ++ "Enabled", ++ QPixmap(":/ra/icons/ra-icon.png") ++ ); ++ } ++ else ++ { ++ ra->Disable(); ++ ++ m_toastManager.ShowAchievement( ++ "RetroAchievements", ++ "Disabled", ++ QPixmap(":/ra/icons/ra-icon.png") ++ ); ++ } ++ ++ m_oldRAEnabled = newRAEnabled; ++ } ++} ++#endif ++ + emuThread->emuUnpause(); + } + +@@ -1997,6 +2248,35 @@ void MainWindow::onMPSettingsFinished(in + + emuThread->emuUnpause(); + } ++#ifdef RETROACHIEVEMENTS_ENABLED ++void MainWindow::onOpenRASettings() ++{ ++ emuThread->emuPause(); ++ if (!emuInstance) ++ return; ++ ++ RASettingsDialog* dlg = new RASettingsDialog(emuInstance, this); ++ connect(dlg, &QDialog::finished, ++ this, &MainWindow::onRASettingsFinished); ++ ++ dlg->show(); ++} ++ ++void MainWindow::onRASettingsFinished(int res) ++{ ++ if (!emuInstance) ++ return; ++ ++ if (res == QDialog::Accepted) ++ { ++ emuInstance->SyncRetroAchievementsFromConfig(); ++ } ++ ++ if (RASettingsDialog::needsReset) ++ onReset(); ++ emuThread->emuUnpause(); ++} ++#endif + + void MainWindow::onOpenWifiSettings() + { +@@ -2160,6 +2440,13 @@ void MainWindow::onChangeAudioSync(bool + + void MainWindow::onTitleUpdate(QString title) + { ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ if (emuInstance) { ++ if (RAContext* ra = emuInstance->getRA()) { ++ ra->ProcessAsyncCallbacks(); ++ } ++ } ++ #endif + if (!emuInstance) return; + + int numinst = numEmuInstances(); +@@ -2210,6 +2497,38 @@ void MainWindow::onFullscreenToggled() + toggleFullscreen(); + } + ++#ifdef RETROACHIEVEMENTS_ENABLED ++void MainWindow::onRAOverlayToggled() ++{ ++ if (!emuInstance || !this->isActiveWindow()) ++ return; ++ ++ RAOverlayWidget* currentOverlay = emuInstance->getRAOverlay(); ++ ++ if (!currentOverlay) { ++ currentOverlay = new RAOverlayWidget(emuInstance, this->centralWidget()); ++ emuInstance->setRAOverlay(currentOverlay); ++ raOverlay = currentOverlay; ++ } ++ ++ if (currentOverlay->isOpen()) { ++ currentOverlay->toggle(); ++ emuThread->emuUnpause(); ++ this->centralWidget()->setFocus(); ++ } else { ++ if (currentOverlay->parentWidget() != this->centralWidget()) { ++ currentOverlay->setParent(this->centralWidget()); ++ } ++ ++ currentOverlay->setGeometry(this->centralWidget()->rect()); ++ currentOverlay->toggle(); ++ ++ emuThread->emuPause(); ++ currentOverlay->setFocus(); ++ } ++} ++#endif ++ + void MainWindow::onScreenEmphasisToggled() + { + int currentSizing = windowCfg.GetInt("ScreenSizing"); +@@ -2293,6 +2612,229 @@ void MainWindow::onEmuReset() + actUndoStateLoad->setEnabled(false); + } + ++#ifdef RETROACHIEVEMENTS_ENABLED ++void MainWindow::OnChallengeShow(const QString& badgeName) ++{ ++ QString fullUrl = QString("https://media.retroachievements.org/Badge/%1.png").arg(badgeName); ++ ++ m_badgeCache.DownloadBadge(fullUrl, [this, badgeName](const QPixmap& pix) { ++ if (pix.isNull()) return; ++ ++ QMetaObject::invokeMethod(this, [this, pix, badgeName]() { ++ m_toastManager.ShowChallengeIndicator(pix, badgeName); ++ }); ++ }); ++} ++ ++void MainWindow::OnChallengeHide(const QString& badgeName) ++{ ++ QMetaObject::invokeMethod(this, [this, badgeName]() { ++ m_toastManager.HideChallengeIndicator(badgeName); ++ }); ++} ++ ++void MainWindow::OnLeaderboardTrackerUpdate(const QString& display) ++{ ++ m_toastManager.UpdateLeaderboardTracker(display); ++} ++ ++void MainWindow::OnLeaderboardSubmitted(const QString& title, const QString& score, unsigned rank) ++{ ++ QString msg = QString("Wynik: %1 (Miejsce: %2)").arg(score).arg(rank); ++ m_toastManager.ShowLeaderboardToast(title, msg, QPixmap(":/ra/icons/ra-icon.png")); ++} ++ ++void MainWindow::OnRADisconnected() ++{ ++ m_toastManager.ShowAchievement( ++ tr("RetroAchievements"), ++ tr("There is no connection with the internet"), ++ QPixmap(":/ra/icons/ra-icon.png") ++ ); ++ m_toastManager.UpdateNetworkStatus("~RA~"); ++} ++ ++void MainWindow::OnRAReconnected() ++{ ++ m_toastManager.ShowAchievement( ++ tr("RetroAchievements"), ++ tr("Connection restored"), ++ QPixmap(":/ra/icons/ra-icon.png") ++ ); ++ m_toastManager.UpdateNetworkStatus(""); ++} ++ ++void MainWindow::OnRAPendingSent(int count) // Upewnij się, że jest tu "int count" ++{ ++ if (count <= 0) return; ++ ++ // Tutaj Twoja logika wyświetlania tosta ++ QString message = tr("Sent %1 pending achievements").arg(count); ++ ++ m_toastManager.ShowAchievement( ++ tr("RetroAchievements"), ++ message, ++ QPixmap(":/ra/icons/ra-icon.png") ++ ); ++} ++ ++void MainWindow::OnGameMastered(const QString& title, const QString& gameBadge) ++{ ++ m_badgeCache.DownloadBadge(gameBadge, [this, title](const QPixmap& pix) ++ { ++ QString msg = QString("Mastered %1!").arg(title); ++ ++ m_toastManager.ShowAchievement("MASTERED!", msg, pix); ++ }); ++} ++ ++void MainWindow::OnAchievementProgress( ++ const QString& title, ++ const QString& progress, ++ const QString& badgeUrl) ++{ ++ m_badgeCache.DownloadBadge(badgeUrl, ++ [this, title, progress](const QPixmap& pix) ++ { ++ m_toastManager.ShowProgress( ++ title, ++ progress, ++ pix); ++ }); ++} ++ ++void MainWindow::OnAchievementUnlocked( ++ const QString& title, ++ const QString& desc, ++ const QString& badgeUrl) ++{ ++ m_badgeCache.DownloadBadge(badgeUrl, ++ [this, title, desc](const QPixmap& pix) ++ { ++ m_toastManager.ShowAchievement(title, desc, pix); ++ }); ++} ++ ++void MainWindow::ShowRALoginToast(bool success, const std::string& message) ++{ ++ QString title = "RetroAchievements"; ++ QString toastMsg; ++ QPixmap pixmap(":/ra/icons/ra-icon.png"); ++ ++ if (success && emuInstance) ++ { ++ RAContext* ra = emuInstance->getRA(); ++ const rc_client_user_t* user = ++ (ra && ra->client) ? rc_client_get_user_info(ra->client) : nullptr; ++ ++ if (user && user->display_name) ++ { ++ toastMsg = QString("Logged in as %1").arg(user->display_name); ++ ++ if (user->avatar_url && !QString(user->avatar_url).isEmpty()) ++ { ++ QString avatarUrl = QString::fromUtf8(user->avatar_url); ++ ++ m_badgeCache.DownloadBadge(avatarUrl, [this, title, toastMsg](const QPixmap& avatarPix) ++ { ++ QMetaObject::invokeMethod(this, [this, title, toastMsg, avatarPix]() { ++ m_toastManager.ShowAchievement(title, toastMsg, avatarPix); ++ }); ++ }); ++ ++ return; ++ } ++ } ++ else ++ { ++ toastMsg = "Logged in!"; ++ } ++ } ++ else ++ { ++ toastMsg = QString("Login Error: %1") ++ .arg(QString::fromStdString(message)); ++ } ++ ++ QMetaObject::invokeMethod(this, [this, title, toastMsg, pixmap]() { ++ m_toastManager.ShowAchievement(title, toastMsg, pixmap); ++ }); ++} ++ ++void MainWindow::ShowGameLoadToast() ++{ ++ RAContext* ra = emuInstance->getRA(); ++ if (ra->pendingLoadFailed) ++ { ++ QString errorMsg = QString::fromStdString(ra->pendingLoadError); ++ ++ QTimer::singleShot(100, this, [this, errorMsg]() ++ { ++ QMetaObject::invokeMethod(QApplication::instance(), [this, errorMsg]() ++ { ++ m_toastManager.ShowAchievement( ++ "RetroAchievements", ++ QString("ERROR: %1").arg(errorMsg), ++ QPixmap(":/ra/icons/ra-icon.png") ++ ); ++ }); ++ }); ++ ++ return; ++ } ++ ++ const rc_client_game_t* game = ra->GetCurrentGameInfo(); ++ if (!game) ++ return; ++ ++ QString title = QString::fromUtf8(game->title); ++ QString badgeUrl = QString::fromUtf8(game->badge_url); ++ ++ int totalAchievements = 0; ++ int unlockedAchievements = 0; ++ ++ rc_client_achievement_list_t* achList = ++ rc_client_create_achievement_list( ++ ra->client, ++ RC_CLIENT_ACHIEVEMENT_CATEGORY_CORE_AND_UNOFFICIAL, ++ RC_CLIENT_ACHIEVEMENT_LIST_GROUPING_LOCK_STATE); ++ ++ if (achList) ++ { ++ for (uint32_t b = 0; b < achList->num_buckets; ++b) ++ { ++ const rc_client_achievement_bucket_t* bucket = ++ &achList->buckets[b]; ++ ++ for (uint32_t i = 0; i < bucket->num_achievements; ++i) ++ { ++ const rc_client_achievement_t* ach = ++ bucket->achievements[i]; ++ ++ ++totalAchievements; ++ ++ if (ach && ach->unlocked) ++ ++unlockedAchievements; ++ } ++ } ++ ++ rc_client_destroy_achievement_list(achList); ++ } ++ ++ //stupid function to subtract 1 from achiv because they are showing up incorectly because of hardcore achievement ++ if (totalAchievements > 0) totalAchievements -= 1; ++ if (unlockedAchievements > 0) unlockedAchievements -= 1; ++ ++ QString desc = QString("Game loaded! (%1/%2 Achievements)") ++ .arg(unlockedAchievements) ++ .arg(totalAchievements); ++ ++ QTimer::singleShot(100, this, [this, title, desc]() ++ { ++ m_toastManager.ShowAchievement(title, desc, QPixmap(":/ra/icons/ra-icon.png")); ++ }); ++} ++#endif + void MainWindow::onUpdateVideoSettings(bool glchange) + { + if (!emuInstance) return; +diff -rupbN melonDS.orig/src/frontend/qt_sdl/Window.h melonDS.ra/src/frontend/qt_sdl/Window.h +--- melonDS.orig/src/frontend/qt_sdl/Window.h 2026-03-06 21:36:14.566057575 +0000 ++++ melonDS.ra/src/frontend/qt_sdl/Window.h 2026-03-06 21:37:07.046799886 +0000 +@@ -37,6 +37,13 @@ + #include "Config.h" + #include "MPInterface.h" + ++#ifdef RETROACHIEVEMENTS_ENABLED ++#include "../../RetroAchievements/RAClient.h" ++#include "toast/ToastManager.h" ++#include "toast/BadgeCache.h" ++#include "RAOverlayWidget.h" ++#endif ++ + + class EmuInstance; + class EmuThread; +@@ -48,6 +55,26 @@ class MainWindow : public QMainWindow + Q_OBJECT + + public: ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ void OnLeaderboardTrackerUpdate(const QString& display); ++ void OnLeaderboardSubmitted(const QString& title, const QString& score, unsigned rank); ++ RAOverlayWidget* raOverlay = nullptr; ++ ToastManager m_toastManager; ++ BadgeCache m_badgeCache; ++ void ShowRALoginToast(bool success, const std::string& message); ++ bool m_oldRAEnabled; ++ void showRALoginToast(); ++ void ShowGameLoadToast(); ++ void OnAchievementUnlocked(const QString& title, const QString& desc, const QString& badgeUrl); ++ void OnAchievementProgress(const QString& title, const QString& progress, const QString& badge); ++ void OnChallengeShow(const QString& badgeName); ++ void OnChallengeHide(const QString& badgeName); ++ void OnGameMastered(const QString& title, const QString& gameBadge); ++ void OnRADisconnected(); ++ void OnRAReconnected(); ++ void OnRAPendingSent(int count); ++ #endif ++ + explicit MainWindow(int id, EmuInstance* inst, QWidget* parent = nullptr); + ~MainWindow(); + +@@ -149,6 +176,10 @@ private slots: + void onAudioSettingsFinished(int res); + void onOpenMPSettings(); + void onMPSettingsFinished(int res); ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ void onOpenRASettings(); ++ void onRASettingsFinished(int res); ++ #endif + void onOpenWifiSettings(); + void onWifiSettingsFinished(int res); + void onOpenFirmwareSettings(); +@@ -182,6 +213,9 @@ private slots: + void onUpdateVideoSettings(bool glchange); + + void onFullscreenToggled(); ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ void onRAOverlayToggled(); ++ #endif + void onScreenEmphasisToggled(); + + private: +@@ -269,6 +303,9 @@ public: + QAction* actCameraSettings; + QAction* actAudioSettings; + QAction* actMPSettings; ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ QAction* actRASettings; ++ #endif + QAction* actWifiSettings; + QAction* actFirmwareSettings; + QAction* actPathSettings; +diff -rupbN melonDS.orig/src/frontend/qt_sdl/main.cpp melonDS.ra/src/frontend/qt_sdl/main.cpp +--- melonDS.orig/src/frontend/qt_sdl/main.cpp 2026-03-06 21:36:14.566057575 +0000 ++++ melonDS.ra/src/frontend/qt_sdl/main.cpp 2026-03-06 21:37:07.046799886 +0000 +@@ -65,6 +65,11 @@ + #include "Net_PCap.h" + #include "Net_Slirp.h" + ++#ifdef RETROACHIEVEMENTS_ENABLED ++#include "RetroAchievements/RAClient.h" ++#include ++#endif ++ + using namespace melonDS; + + QString* systemThemeName; +@@ -266,6 +271,38 @@ bool MelonApplication::event(QEvent *eve + return QApplication::event(event); + } + ++#ifdef RETROACHIEVEMENTS_ENABLED ++u32 currentRASeconds = 0; ++QTimer* raPlaytimeTimer = nullptr; ++ ++ ++void updateRAPlaytime() ++{ ++ if (emuInstances[0]) ++ { ++ auto& raCtx = emuInstances[0]->ra; ++ ++ if (raCtx && raCtx->IsGameLoaded()) ++ { ++ auto* gameInfo = raCtx->GetCurrentGameInfo(); ++ uint32_t gameID = gameInfo ? gameInfo->id : 0; ++ ++ if (gameID != 0) ++ { ++ currentRASeconds++; ++ if (currentRASeconds % 60 == 0) ++ { ++ std::string gameKey = std::to_string(gameID); ++ int totalTime = Config::GetRAPlaytimeTable().GetInt(gameKey); ++ Config::GetRAPlaytimeTable().SetInt(gameKey, totalTime + 60); ++ Config::Save(); ++ } ++ } ++ } ++ } ++} ++#endif ++ + int main(int argc, char** argv) + { + sysTimer.start(); +@@ -366,6 +403,13 @@ int main(int argc, char** argv) + + createEmuInstance(); + ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ if (emuInstances[0]) ++ { ++ emuInstances[0]->SyncRetroAchievementsFromConfig(); ++ } ++ #endif ++ + { + MainWindow* win = emuInstances[0]->getMainWindow(); + bool memberSyntaxUsed = false; +@@ -394,6 +438,14 @@ int main(int argc, char** argv) + win->toggleFullscreen(); + } + ++ #ifdef RETROACHIEVEMENTS_ENABLED ++ raPlaytimeTimer = new QTimer(&melon); ++ QObject::connect(raPlaytimeTimer, &QTimer::timeout, []() { ++ updateRAPlaytime(); ++ }); ++ raPlaytimeTimer->start(1000); ++ #endif ++ + int ret = melon.exec(); + + delete options; +diff -rupbN melonDS.orig/src/frontend/qt_sdl/retroachievements/resources/ra.qrc melonDS.ra/src/frontend/qt_sdl/retroachievements/resources/ra.qrc +--- melonDS.orig/src/frontend/qt_sdl/retroachievements/resources/ra.qrc 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/frontend/qt_sdl/retroachievements/resources/ra.qrc 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,10 @@ ++ ++ ++ ++ icons/placeholder.png ++ icons/ra-icon.png ++ ++ ++ sounds/unlock.wav ++ ++ +\ No newline at end of file +diff -rupbN melonDS.orig/src/frontend/qt_sdl/toast/BadgeCache.cpp melonDS.ra/src/frontend/qt_sdl/toast/BadgeCache.cpp +--- melonDS.orig/src/frontend/qt_sdl/toast/BadgeCache.cpp 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/frontend/qt_sdl/toast/BadgeCache.cpp 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,50 @@ ++#include "BadgeCache.h" ++#include ++#include ++ ++BadgeCache::BadgeCache(QObject* parent) ++ : QObject(parent) ++{} ++ ++QPixmap BadgeCache::GetBadge(const QString& url) ++{ ++ if (m_cache.contains(url)) ++ return m_cache[url]; ++ ++ DownloadBadge(url, [](const QPixmap&){}); ++ ++ return QPixmap(":/ra/placeholder.png"); ++} ++ ++void BadgeCache::DownloadBadge(const QString& url, std::function callback) ++{ ++ if (QThread::currentThread() != thread()) ++ { ++ QMetaObject::invokeMethod(this, [this, url, callback]() { ++ DownloadBadge(url, callback); ++ }, Qt::QueuedConnection); ++ return; ++ } ++ ++ if (m_cache.contains(url)) { ++ callback(m_cache[url]); ++ return; ++ } ++ ++ QNetworkRequest req{ QUrl(url) }; ++ auto* reply = m_net.get(req); ++ ++ QObject::connect(reply, &QNetworkReply::finished, [this, reply, url, callback]() { ++ QPixmap pix; ++ if (reply->error() == QNetworkReply::NoError) ++ pix.loadFromData(reply->readAll()); ++ ++ if (pix.isNull()) ++ pix = QPixmap(":/ra/placeholder.png"); ++ ++ m_cache[url] = pix; ++ emit BadgeReady(url, pix); ++ callback(pix); ++ reply->deleteLater(); ++ }); ++} +diff -rupbN melonDS.orig/src/frontend/qt_sdl/toast/BadgeCache.h melonDS.ra/src/frontend/qt_sdl/toast/BadgeCache.h +--- melonDS.orig/src/frontend/qt_sdl/toast/BadgeCache.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/frontend/qt_sdl/toast/BadgeCache.h 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,21 @@ ++#pragma once ++#include ++#include ++ ++class BadgeCache : public QObject ++{ ++ Q_OBJECT ++public: ++ explicit BadgeCache(QObject* parent = nullptr); ++ ++ QPixmap GetBadge(const QString& url); ++ void DownloadBadge(const QString& url, ++ std::function callback); ++ ++signals: ++ void BadgeReady(const QString& url, const QPixmap& pix); ++ ++private: ++ QNetworkAccessManager m_net; ++ QHash m_cache; ++}; +\ No newline at end of file +diff -rupbN melonDS.orig/src/frontend/qt_sdl/toast/ToastManager.cpp melonDS.ra/src/frontend/qt_sdl/toast/ToastManager.cpp +--- melonDS.orig/src/frontend/qt_sdl/toast/ToastManager.cpp 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/frontend/qt_sdl/toast/ToastManager.cpp 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,149 @@ ++#include "ToastManager.h" ++#include "toast/ToastOverlay.h" ++#include ++#include "Config.h" ++#include "Window.h" ++#include "EmuInstance.h" ++ ++ToastManager::ToastManager(QObject* parent) ++ : QObject(parent) ++{ ++} ++ ++void ToastManager::Init(QWidget* widget) ++{ ++ if (m_overlay) return; ++ m_overlay = new ToastOverlay(widget); ++ ++ m_overlay->setGeometry(widget->rect()); ++ widget->installEventFilter(m_overlay); ++ m_overlay->show(); ++ m_overlay->raise(); ++} ++ ++void ToastManager::EnsureOnTop() ++{ ++ if (!m_overlay) return; ++ m_overlay->raise(); ++ if (m_leaderboardLabel) m_leaderboardLabel->raise(); ++ if (m_networkLabel) m_networkLabel->raise(); ++} ++ ++void ToastManager::ShowAchievement(const QString& title, const QString& description, const QPixmap& icon) ++{ ++ if (!m_overlay) return; ++ EnsureOnTop(); ++ m_overlay->ShowToast(title, description, icon); ++} ++ ++void ToastManager::ShowLeaderboardToast(const QString& title, const QString& description, const QPixmap& icon, bool playSound) ++{ ++ if (!m_overlay) return; ++ EnsureOnTop(); ++ m_overlay->ShowLeaderboardToast(title, description, icon, false); ++} ++ ++void ToastManager::ShowProgress(const QString& title, const QString& description, const QPixmap& icon) ++{ ++ if (!m_overlay) return; ++ EnsureOnTop(); ++ m_overlay->ShowToast(title, description, icon, false); ++} ++ ++void ToastManager::ShowChallengeIndicator(const QPixmap& icon, const QString& badgeName) ++{ ++ if (!m_overlay) return; ++ EnsureOnTop(); ++ m_overlay->ShowChallenge(icon, badgeName); ++} ++ ++void ToastManager::HideChallengeIndicator(const QString& badgeName) ++{ ++ if (m_overlay) ++ m_overlay->HideChallenge(badgeName); ++} ++ ++void ToastManager::UpdateLeaderboardTracker(const QString& display) ++{ ++ MainWindow* mainWin = qobject_cast(this->parent()); ++ ++ if (mainWin) { ++ if (mainWin->getEmuInstance()->getLocalConfig().GetBool("RetroAchievements.HideLeaderboardCounter")) { ++ if (m_leaderboardLabel) m_leaderboardLabel->hide(); ++ return; ++ } ++ } ++ ++ QWidget* parent = qobject_cast(this->parent()); ++ if (!parent) return; ++ ++ if (display.isEmpty()) { ++ if (m_leaderboardLabel) m_leaderboardLabel->hide(); ++ return; ++ } ++ ++ if (!m_leaderboardLabel) { ++ m_leaderboardLabel = new QLabel(parent); ++ m_leaderboardLabel->setStyleSheet( ++ "background-color: rgba(0, 0, 0, 160);" ++ "color: white;" ++ "padding: 4px 8px;" ++ "border-radius: 4px;" ++ "font-family: 'Consolas', 'Monospace';" ++ "font-weight: bold;" ++ "font-size: 13px;" ++ ); ++ m_leaderboardLabel->setAttribute(Qt::WA_TransparentForMouseEvents); ++ } ++ ++ m_leaderboardLabel->setText(display); ++ m_leaderboardLabel->adjustSize(); ++ ++ int x = parent->width() - m_leaderboardLabel->width() - 10; ++ int y = parent->height() - m_leaderboardLabel->height() - 10; ++ ++ m_leaderboardLabel->move(x, y); ++ m_leaderboardLabel->show(); ++ m_leaderboardLabel->raise(); ++} ++ ++void ToastManager::UpdateNetworkStatus(const QString& display) ++{ ++ QWidget* parent = qobject_cast(this->parent()); ++ if (!parent) return; ++ ++ if (display.isEmpty()) { ++ if (m_networkLabel) m_networkLabel->hide(); ++ return; ++ } ++ ++ if (!m_networkLabel) { ++ m_networkLabel = new QLabel(parent); ++ m_networkLabel->setStyleSheet( ++ "background-color: rgba(0, 0, 0, 180);" ++ "color: white;" ++ "padding: 4px 8px;" ++ "font-family: 'Consolas', 'Monospace';" ++ "font-weight: bold;" ++ ); ++ m_networkLabel->setAttribute(Qt::WA_TransparentForMouseEvents); ++ } ++ ++ m_networkLabel->setText(display); ++ m_networkLabel->adjustSize(); ++ ++ int offset = (m_leaderboardLabel && m_leaderboardLabel->isVisible()) ++ ? m_leaderboardLabel->height() + 15 : 10; ++ int x = parent->width() - m_networkLabel->width() - 10; ++ int y = parent->height() - m_networkLabel->height() - offset; ++ ++ m_networkLabel->move(x, y); ++ m_networkLabel->show(); ++ m_networkLabel->raise(); ++} ++ ++void ToastManager::ClearAll() ++{ ++ if (m_overlay) ++ m_overlay->HideChallenge(""); ++} +diff -rupbN melonDS.orig/src/frontend/qt_sdl/toast/ToastManager.h melonDS.ra/src/frontend/qt_sdl/toast/ToastManager.h +--- melonDS.orig/src/frontend/qt_sdl/toast/ToastManager.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/frontend/qt_sdl/toast/ToastManager.h 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,26 @@ ++#pragma once ++#include ++#include ++class ToastOverlay; ++class ToastManager : public QObject ++{ ++ Q_OBJECT ++public: ++ void UpdateNetworkStatus(const QString& display); ++ void UpdateLeaderboardTracker(const QString& display); ++ explicit ToastManager(QObject* parent = nullptr); ++ void Init(QWidget* screenWidget); ++ void ShowAchievement(const QString& title, ++ const QString& desc, ++ const QPixmap& icon); ++ void ShowLeaderboardToast(const QString& title, const QString& description, const QPixmap& icon, bool playSound = true); ++ void ShowProgress(const QString& title, const QString& description, const QPixmap& icon); ++ void ShowChallengeIndicator(const QPixmap& icon, const QString& badgeName); ++ void HideChallengeIndicator(const QString& badgeName = ""); ++ void ClearAll(); ++private: ++ void EnsureOnTop(); ++ QLabel* m_leaderboardLabel = nullptr; ++ QLabel* m_networkLabel = nullptr; ++ ToastOverlay* m_overlay = nullptr; ++}; +diff -rupbN melonDS.orig/src/frontend/qt_sdl/toast/ToastOverlay.cpp melonDS.ra/src/frontend/qt_sdl/toast/ToastOverlay.cpp +--- melonDS.orig/src/frontend/qt_sdl/toast/ToastOverlay.cpp 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/frontend/qt_sdl/toast/ToastOverlay.cpp 2026-03-06 21:38:33.640023242 +0000 +@@ -0,0 +1,377 @@ ++#include "ToastOverlay.h" ++#include ++#include ++#include ++#include ++#include ++#include "Config.h" ++#include "EmuInstance.h" ++#include "Window.h" ++ ++static float ComputeToastScale(const QSize& size) ++{ ++ constexpr float refShortSide = 384.0f; ++ float shortSide = std::min(size.width(), size.height()); ++ float scale = shortSide / refShortSide; ++ return std::clamp(scale, 0.975f, 1.875f); ++} ++ ++static int ConfigureLabelAutoFit(QLabel* label, const QString& text, int maxWidth) ++{ ++ if (text.isEmpty()) return 0; ++ ++ label->setText(text); ++ QFont font = label->font(); ++ QFontMetrics fm(font); ++ int textWidth = fm.horizontalAdvance(text); ++ ++ if (textWidth <= maxWidth) { ++ label->setFont(font); ++ label->setWordWrap(false); ++ return textWidth; ++ } ++ ++ float originalSize = font.pointSizeF(); ++ if (originalSize <= 0) originalSize = 10.0f; ++ ++ QFont smallerFont = font; ++ smallerFont.setPointSizeF(originalSize * 0.85f); ++ QFontMetrics fmSmall(smallerFont); ++ ++ if (fmSmall.horizontalAdvance(text) <= maxWidth) { ++ label->setFont(smallerFont); ++ label->setWordWrap(false); ++ return fmSmall.horizontalAdvance(text); ++ } ++ ++ label->setFont(font); ++ label->setWordWrap(true); ++ label->setMinimumWidth(maxWidth); ++ return maxWidth; ++} ++ ++ToastWidget::ToastWidget( ++ const QString& title, ++ const QString& description, ++ const QPixmap& icon, ++ float scale, ++ int maxWidth, ++ QWidget* parent ++) : QWidget(parent) ++{ ++ const int iconSize = int(66 * scale); ++ const int marginsH = int(10 * scale) + int(12 * scale) + int(8 * scale); ++ const int maxTextWidth = maxWidth - iconSize - marginsH; ++ ++ auto* layout = new QHBoxLayout(this); ++ layout->setSpacing(int(8 * scale)); ++ layout->setContentsMargins(int(10 * scale), int(8 * scale), int(12 * scale), int(8 * scale)); ++ ++ auto* iconLabel = new QLabel; ++ iconLabel->setPixmap(icon.scaled(iconSize, iconSize, Qt::KeepAspectRatio, Qt::SmoothTransformation)); ++ iconLabel->setFixedSize(iconSize, iconSize); ++ iconLabel->setAlignment(Qt::AlignCenter); ++ layout->addWidget(iconLabel); ++ ++ float basePt = font().pointSizeF(); ++ if (basePt <= 0) basePt = 10.0f; ++ int titlePt = qRound(basePt * scale); ++ int descPt = qRound(basePt * scale * 0.85f); ++ ++ if (!title.isEmpty() || !description.isEmpty()) { ++ auto* textLayout = new QVBoxLayout(); ++ textLayout->setSpacing(int(0 * scale)); ++ textLayout->setContentsMargins(0, 0, 0, 0); ++ ++ int actualTitleW = 0; ++ int actualDescW = 0; ++ ++ if (!title.isEmpty()) { ++ auto* titleLabel = new QLabel; ++ titleLabel->setStyleSheet(QString("font-weight: bold; color: white; background: transparent; padding-left: 2px; font-size: %1pt;").arg(titlePt)); ++ actualTitleW = ConfigureLabelAutoFit(titleLabel, title, maxTextWidth); ++ titleLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); ++ titleLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); ++ textLayout->addWidget(titleLabel); ++ } ++ ++ if (!description.isEmpty()) { ++ auto* descLabel = new QLabel; ++ descLabel->setStyleSheet(QString("color: #bbb; background: transparent; padding-left: 2px; font-size: %1pt;").arg(descPt)); ++ actualDescW = ConfigureLabelAutoFit(descLabel, description, maxTextWidth); ++ descLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); ++ descLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); ++ textLayout->addWidget(descLabel); ++ } ++ ++ layout->addLayout(textLayout); ++ ++ setMinimumWidth(int(120 * scale)); ++ setMaximumWidth(maxWidth); ++ adjustSize(); ++ } ++ else { ++ setFixedWidth(iconSize + marginsH); ++ } ++ ++ setAttribute(Qt::WA_StyledBackground, false); ++ setAttribute(Qt::WA_TranslucentBackground); ++ setStyleSheet("background: transparent;"); ++} ++ ++QSize ToastWidget::sizeHint() const ++{ ++ return layout()->sizeHint(); ++} ++ ++void ToastWidget::paintEvent(QPaintEvent*) ++{ ++ QPainter p(this); ++ p.setRenderHint(QPainter::Antialiasing); ++ QRect r = rect().adjusted(1, 1, -1, -1); ++ p.setBrush(QColor(40, 40, 40, 230)); ++ p.setPen(Qt::NoPen); ++ p.drawRoundedRect(r, 8, 8); ++} ++ ++ToastOverlay::ToastOverlay(QWidget* parent) ++ : QGraphicsView(static_cast(nullptr)) ++ , m_anchor(parent) ++{ ++ m_scene = new QGraphicsScene(this); ++ setScene(m_scene); ++ setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | ++ Qt::WindowStaysOnTopHint | Qt::WindowDoesNotAcceptFocus | ++ Qt::WindowTransparentForInput); ++ setAttribute(Qt::WA_ShowWithoutActivating); ++ setAttribute(Qt::WA_NoSystemBackground); ++ setWindowFlag(Qt::X11BypassWindowManagerHint); ++ setFrameShape(QFrame::NoFrame); ++ setBackgroundRole(QPalette::NoRole); ++ setStyleSheet("background: transparent; border: none;"); ++ setAttribute(Qt::WA_TransparentForMouseEvents); ++ setAttribute(Qt::WA_TranslucentBackground); ++ setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); ++ setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); ++ setRenderHint(QPainter::Antialiasing); ++ ++ m_soundEffect.setSource(QUrl("qrc:/ra/sounds/unlock.wav")); ++ m_soundEffect.setVolume(0.7f); ++} ++ ++void ToastOverlay::ShowToast(const QString& title, const QString& description, const QPixmap& icon, bool playSound) ++{ ++ MainWindow* mainWin = qobject_cast(m_anchor); ++ if (mainWin) { ++ if (mainWin->getEmuInstance()->getLocalConfig().GetBool("RetroAchievements.HideToasts")) { ++ return; ++ } ++ } ++ if (!m_anchor) return; ++ float scale = ComputeToastScale(m_anchor->size()); ++ const int maxToastWidth = int(m_anchor->width() * 0.825f); ++ ++ auto* toast = new ToastWidget(title, description, icon, scale, maxToastWidth); ++ QGraphicsProxyWidget* proxy = m_scene->addWidget(toast); ++ m_toastProxies.append(proxy); ++ if (playSound) { ++ m_soundEffect.play(); ++ } ++ ++ RepositionToasts(); ++ ++ QTimer::singleShot(3000, this, [this, proxy]() { ++ m_toastProxies.removeOne(proxy); ++ m_scene->removeItem(proxy); ++ if (proxy->widget()) proxy->widget()->deleteLater(); ++ delete proxy; ++ RepositionToasts(); ++ }); ++} ++ ++void ToastOverlay::ShowChallenge(const QPixmap& icon, const QString& badgeName) ++{ ++ MainWindow* mainWin = qobject_cast(m_anchor); ++ if (mainWin) { ++ if (mainWin->getEmuInstance()->getLocalConfig().GetBool("RetroAchievements.HideChallengeIndicators")) { ++ return; ++ } ++ } ++ ++ if (!m_anchor || icon.isNull()) return; ++ ++ float scale = ComputeToastScale(m_anchor->size()); ++ int scaledSize = int(48 * scale); ++ ++ QLabel* label = new QLabel(); ++ label->setPixmap(icon.scaled(scaledSize, scaledSize, Qt::KeepAspectRatio, Qt::SmoothTransformation)); ++ label->setStyleSheet("background: transparent; border: none; padding: 0px;"); ++ label->setAttribute(Qt::WA_TransparentForMouseEvents); ++ label->adjustSize(); ++ ++ QGraphicsProxyWidget* proxy = m_scene->addWidget(label); ++ proxy->setProperty("badgeName", badgeName); ++ ++ m_challengeProxies.append(proxy); ++ RepositionChallenge(); ++} ++ ++void ToastOverlay::ShowLeaderboardToast( ++ const QString& title, ++ const QString& description, ++ const QPixmap& icon, ++ bool playSound ++) ++{ ++ MainWindow* mainWin = qobject_cast(m_anchor); ++ if (mainWin) ++ { ++ if (mainWin->getEmuInstance()->getLocalConfig().GetBool("RetroAchievements.HideLeaderboardToasts")) { ++ return; ++ } ++ } ++ ++ ShowToast(title, description, icon, playSound); ++} ++ ++void ToastOverlay::HideChallenge(const QString& badgeName) ++{ ++ if (badgeName.isEmpty()) { ++ for (auto* proxy : m_challengeProxies) { ++ m_scene->removeItem(proxy); ++ if (proxy->widget()) proxy->widget()->deleteLater(); ++ delete proxy; ++ } ++ m_challengeProxies.clear(); ++ } else { ++ for (int i = 0; i < m_challengeProxies.size(); ++i) { ++ if (m_challengeProxies[i]->property("badgeName").toString() == badgeName) { ++ auto* proxy = m_challengeProxies.takeAt(i); ++ m_scene->removeItem(proxy); ++ if (proxy->widget()) proxy->widget()->deleteLater(); ++ delete proxy; ++ break; ++ } ++ } ++ } ++ RepositionChallenge(); ++} ++ ++void ToastOverlay::RepositionToasts() ++{ ++ if (!m_anchor) return; ++ int rotMode = Config::GetLocalTable(0).GetInt("Window0.ScreenRotation"); ++ int angle = rotMode * 90; ++ QRect pRect = m_anchor->rect(); ++ m_scene->setSceneRect(0, 0, pRect.width(), pRect.height()); ++ ++ const int margin = 20; ++ int offset = 60; ++ ++ for (auto* proxy : m_toastProxies) ++ { ++ proxy->widget()->adjustSize(); ++ QSize s = proxy->widget()->size(); ++ proxy->setTransformOriginPoint(s.width() / 2.0, s.height() / 2.0); ++ proxy->setRotation(angle); ++ ++ int finalW = (rotMode % 2 == 0) ? s.width() : s.height(); ++ int finalH = (rotMode % 2 == 0) ? s.height() : s.width(); ++ int centerX, centerY; ++ ++ if (rotMode == 0) { ++ centerX = margin + finalW / 2; ++ centerY = offset + finalH / 2; ++ } else if (rotMode == 1) { ++ centerX = pRect.width() - offset - finalW / 2; ++ centerY = pRect.height() - margin - finalH / 2; ++ } else if (rotMode == 2) { ++ centerX = margin + finalW / 2; ++ centerY = pRect.height() - offset - finalH / 2; ++ } else { ++ centerX = offset + finalW / 2; ++ centerY = margin + finalH / 2; ++ } ++ ++ proxy->setPos(centerX - s.width() / 2.0, centerY - s.height() / 2.0); ++ offset += finalH + 10; ++ } ++} ++ ++void ToastOverlay::RepositionChallenge() ++{ ++ if (m_challengeProxies.isEmpty() || !m_anchor) return; ++ ++ int rotMode = Config::GetLocalTable(0).GetInt("Window0.ScreenRotation"); ++ int angle = rotMode * 90; ++ QRect pRect = m_anchor->rect(); ++ ++ const int margin = 20; ++ const int spacing = 8; ++ int currentOffset = 0; ++ ++ for (auto* proxy : m_challengeProxies) { ++ proxy->widget()->adjustSize(); ++ QSize s = proxy->widget()->size(); ++ ++ proxy->setTransformOriginPoint(s.width() / 2.0, s.height() / 2.0); ++ proxy->setRotation(angle); ++ ++ int finalW = (rotMode % 2 == 0) ? s.width() : s.height(); ++ int finalH = (rotMode % 2 == 0) ? s.height() : s.width(); ++ ++ int centerX, centerY; ++ ++ if (rotMode == 0) { ++ centerX = pRect.width() - margin - (finalW / 2) - currentOffset; ++ centerY = pRect.height() - margin - (finalH / 2); ++ } else if (rotMode == 1) { ++ centerX = margin + (finalW / 2); ++ centerY = pRect.height() - margin - (finalH / 2) - currentOffset; ++ } else if (rotMode == 2) { ++ centerX = margin + (finalW / 2) + currentOffset; ++ centerY = margin + (finalH / 2); ++ } else { ++ centerX = pRect.width() - margin - (finalW / 2); ++ centerY = margin + (finalH / 2) + currentOffset; ++ } ++ ++ proxy->setPos(centerX - s.width() / 2.0, centerY - s.height() / 2.0); ++ currentOffset += (rotMode % 2 == 0 ? finalW : finalH) + spacing; ++ } ++} ++ ++void ToastOverlay::resizeEvent(QResizeEvent* event) ++{ ++ if (m_anchor) ++ { ++ QPoint globalPos = m_anchor->mapToGlobal(QPoint(0, 0)); ++ setGeometry(globalPos.x(), globalPos.y(), m_anchor->width(), m_anchor->height()); ++ } ++ RepositionToasts(); ++ RepositionChallenge(); ++ QGraphicsView::resizeEvent(event); ++} ++ ++bool ToastOverlay::eventFilter(QObject* obj, QEvent* event) ++{ ++ if (obj == m_anchor || obj == m_anchor->window()) ++ { ++ if (event->type() == QEvent::Resize || ++ event->type() == QEvent::Move || ++ event->type() == QEvent::WindowStateChange) ++ { ++ if (m_anchor) ++ { ++ if (!m_anchor->window()->isMinimized()) ++ { ++ QPoint globalPos = m_anchor->mapToGlobal(QPoint(0, 0)); ++ setGeometry(globalPos.x(), globalPos.y(), m_anchor->width(), m_anchor->height()); ++ RepositionToasts(); ++ RepositionChallenge(); ++ } ++ } ++ } ++ } ++ return QGraphicsView::eventFilter(obj, event); ++} +diff -rupbN melonDS.orig/src/frontend/qt_sdl/toast/ToastOverlay.h melonDS.ra/src/frontend/qt_sdl/toast/ToastOverlay.h +--- melonDS.orig/src/frontend/qt_sdl/toast/ToastOverlay.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/frontend/qt_sdl/toast/ToastOverlay.h 2026-03-06 21:39:48.805083859 +0000 +@@ -0,0 +1,52 @@ ++#pragma once ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++class ToastWidget : public QWidget ++{ ++ Q_OBJECT ++public: ++ ToastWidget(const QString& title, ++ const QString& description, ++ const QPixmap& icon, ++ float scale, ++ int maxWidth, ++ QWidget* parent = nullptr); ++ QSize sizeHint() const override; ++ ++protected: ++ void paintEvent(QPaintEvent* event) override; ++}; ++ ++class ToastOverlay : public QGraphicsView ++{ ++ Q_OBJECT ++public: ++ explicit ToastOverlay(QWidget* parent = nullptr); ++ void ShowToast(const QString& title, const QString& description, const QPixmap& icon, bool playSound = true); ++ void ShowLeaderboardToast(const QString& title, const QString& description, const QPixmap& icon, bool playSound = true); ++ void ShowChallenge(const QPixmap& icon, const QString& badgeName); ++ void HideChallenge(const QString& badgeName = ""); ++ ++protected: ++ bool eventFilter(QObject* obj, QEvent* event) override; ++ void resizeEvent(QResizeEvent* event) override; ++ ++private: ++ void RepositionToasts(); ++ void RepositionChallenge(); ++ QGraphicsScene* m_scene = nullptr; ++ QList m_toastProxies; ++ QList m_challengeProxies; ++ QSoundEffect m_soundEffect; ++ QWidget* m_anchor = nullptr; ++}; +diff -rupbN melonDS.orig/src/rcheevos/include/rc_api_editor.h melonDS.ra/src/rcheevos/include/rc_api_editor.h +--- melonDS.orig/src/rcheevos/include/rc_api_editor.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/include/rc_api_editor.h 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,296 @@ ++#ifndef RC_API_EDITOR_H ++#define RC_API_EDITOR_H ++ ++#include "rc_api_request.h" ++ ++#include ++ ++RC_BEGIN_C_DECLS ++ ++/* --- Fetch Code Notes --- */ ++ ++/** ++ * API parameters for a fetch code notes request. ++ */ ++typedef struct rc_api_fetch_code_notes_request_t { ++ /* The unique identifier of the game */ ++ uint32_t game_id; ++} ++rc_api_fetch_code_notes_request_t; ++ ++/* A code note definiton */ ++typedef struct rc_api_code_note_t { ++ /* The address the note is associated to */ ++ uint32_t address; ++ /* The name of the use who last updated the note */ ++ const char* author; ++ /* The contents of the note */ ++ const char* note; ++} rc_api_code_note_t; ++ ++/** ++ * Response data for a fetch code notes request. ++ */ ++typedef struct rc_api_fetch_code_notes_response_t { ++ /* An array of code notes for the game */ ++ rc_api_code_note_t* notes; ++ /* The number of items in the notes array */ ++ uint32_t num_notes; ++ ++ /* Common server-provided response information */ ++ rc_api_response_t response; ++} ++rc_api_fetch_code_notes_response_t; ++ ++RC_EXPORT int RC_CCONV rc_api_init_fetch_code_notes_request(rc_api_request_t* request, const rc_api_fetch_code_notes_request_t* api_params); ++RC_EXPORT int RC_CCONV rc_api_init_fetch_code_notes_request_hosted(rc_api_request_t* request, const rc_api_fetch_code_notes_request_t* api_params, const rc_api_host_t* host); ++/* [deprecated] use rc_api_process_fetch_code_notes_server_response instead */ ++RC_EXPORT int RC_CCONV rc_api_process_fetch_code_notes_response(rc_api_fetch_code_notes_response_t* response, const char* server_response); ++RC_EXPORT int RC_CCONV rc_api_process_fetch_code_notes_server_response(rc_api_fetch_code_notes_response_t* response, const rc_api_server_response_t* server_response); ++RC_EXPORT void RC_CCONV rc_api_destroy_fetch_code_notes_response(rc_api_fetch_code_notes_response_t* response); ++ ++/* --- Update Code Note --- */ ++ ++/** ++ * API parameters for an update code note request. ++ */ ++typedef struct rc_api_update_code_note_request_t { ++ /* The username of the developer */ ++ const char* username; ++ /* The API token from the login request */ ++ const char* api_token; ++ /* The unique identifier of the game */ ++ uint32_t game_id; ++ /* The address the note is associated to */ ++ uint32_t address; ++ /* The contents of the note (NULL or empty to delete a note) */ ++ const char* note; ++} ++rc_api_update_code_note_request_t; ++ ++/** ++ * Response data for an update code note request. ++ */ ++typedef struct rc_api_update_code_note_response_t { ++ /* Common server-provided response information */ ++ rc_api_response_t response; ++} ++rc_api_update_code_note_response_t; ++ ++RC_EXPORT int RC_CCONV rc_api_init_update_code_note_request(rc_api_request_t* request, const rc_api_update_code_note_request_t* api_params); ++RC_EXPORT int RC_CCONV rc_api_init_update_code_note_request_hosted(rc_api_request_t* request, const rc_api_update_code_note_request_t* api_params, const rc_api_host_t* host); ++/* [deprecated] use rc_api_process_update_code_note_server_response instead */ ++RC_EXPORT int RC_CCONV rc_api_process_update_code_note_response(rc_api_update_code_note_response_t* response, const char* server_response); ++RC_EXPORT int RC_CCONV rc_api_process_update_code_note_server_response(rc_api_update_code_note_response_t* response, const rc_api_server_response_t* server_response); ++RC_EXPORT void RC_CCONV rc_api_destroy_update_code_note_response(rc_api_update_code_note_response_t* response); ++ ++/* --- Update Achievement --- */ ++ ++/** ++ * API parameters for an update achievement request. ++ */ ++typedef struct rc_api_update_achievement_request_t { ++ /* The username of the developer */ ++ const char* username; ++ /* The API token from the login request */ ++ const char* api_token; ++ /* The unique identifier of the achievement (0 to create a new achievement) */ ++ uint32_t achievement_id; ++ /* The unique identifier of the game */ ++ uint32_t game_id; ++ /* The name of the achievement */ ++ const char* title; ++ /* The description of the achievement */ ++ const char* description; ++ /* The badge name for the achievement */ ++ const char* badge; ++ /* The serialized trigger for the achievement */ ++ const char* trigger; ++ /* The number of points the achievement is worth */ ++ uint32_t points; ++ /* The category of the achievement */ ++ uint32_t category; ++ /* The type of the achievement */ ++ uint32_t type; ++} ++rc_api_update_achievement_request_t; ++ ++/** ++ * Response data for an update achievement request. ++ */ ++typedef struct rc_api_update_achievement_response_t { ++ /* The unique identifier of the achievement */ ++ uint32_t achievement_id; ++ ++ /* Common server-provided response information */ ++ rc_api_response_t response; ++} ++rc_api_update_achievement_response_t; ++ ++RC_EXPORT int RC_CCONV rc_api_init_update_achievement_request(rc_api_request_t* request, const rc_api_update_achievement_request_t* api_params); ++RC_EXPORT int RC_CCONV rc_api_init_update_achievement_request_hosted(rc_api_request_t* request, const rc_api_update_achievement_request_t* api_params, const rc_api_host_t* host); ++/* [deprecated] use rc_api_process_update_achievement_server_response instead */ ++RC_EXPORT int RC_CCONV rc_api_process_update_achievement_response(rc_api_update_achievement_response_t* response, const char* server_response); ++RC_EXPORT int RC_CCONV rc_api_process_update_achievement_server_response(rc_api_update_achievement_response_t* response, const rc_api_server_response_t* server_response); ++RC_EXPORT void RC_CCONV rc_api_destroy_update_achievement_response(rc_api_update_achievement_response_t* response); ++ ++/* --- Update Leaderboard --- */ ++ ++/** ++ * API parameters for an update leaderboard request. ++ */ ++typedef struct rc_api_update_leaderboard_request_t { ++ /* The username of the developer */ ++ const char* username; ++ /* The API token from the login request */ ++ const char* api_token; ++ /* The unique identifier of the leaderboard (0 to create a new leaderboard) */ ++ uint32_t leaderboard_id; ++ /* The unique identifier of the game */ ++ uint32_t game_id; ++ /* The name of the leaderboard */ ++ const char* title; ++ /* The description of the leaderboard */ ++ const char* description; ++ /* The start trigger for the leaderboard */ ++ const char* start_trigger; ++ /* The submit trigger for the leaderboard */ ++ const char* submit_trigger; ++ /* The cancel trigger for the leaderboard */ ++ const char* cancel_trigger; ++ /* The value definition for the leaderboard */ ++ const char* value_definition; ++ /* The format of leaderboard values */ ++ const char* format; ++ /* Whether or not lower scores are better for the leaderboard */ ++ uint32_t lower_is_better; ++} ++rc_api_update_leaderboard_request_t; ++ ++/** ++ * Response data for an update leaderboard request. ++ */ ++typedef struct rc_api_update_leaderboard_response_t { ++ /* The unique identifier of the leaderboard */ ++ uint32_t leaderboard_id; ++ ++ /* Common server-provided response information */ ++ rc_api_response_t response; ++} ++rc_api_update_leaderboard_response_t; ++ ++RC_EXPORT int RC_CCONV rc_api_init_update_leaderboard_request(rc_api_request_t* request, const rc_api_update_leaderboard_request_t* api_params); ++RC_EXPORT int RC_CCONV rc_api_init_update_leaderboard_request_hosted(rc_api_request_t* request, const rc_api_update_leaderboard_request_t* api_params, const rc_api_host_t* host); ++/* [deprecated] use rc_api_process_update_leaderboard_server_response instead */ ++RC_EXPORT int RC_CCONV rc_api_process_update_leaderboard_response(rc_api_update_leaderboard_response_t* response, const char* server_response); ++RC_EXPORT int RC_CCONV rc_api_process_update_leaderboard_server_response(rc_api_update_leaderboard_response_t* response, const rc_api_server_response_t* server_response); ++RC_EXPORT void RC_CCONV rc_api_destroy_update_leaderboard_response(rc_api_update_leaderboard_response_t* response); ++ ++/* --- Update Rich Presence --- */ ++ ++/** ++ * API parameters for an update rich presence request. ++ */ ++typedef struct rc_api_update_rich_presence_request_t { ++ /* The username of the developer */ ++ const char* username; ++ /* The API token from the login request */ ++ const char* api_token; ++ /* The unique identifier of the game */ ++ uint32_t game_id; ++ /* The script for the rich_presence */ ++ const char* script; ++} ++rc_api_update_rich_presence_request_t; ++ ++/** ++ * Response data for an update rich presence request. ++ */ ++typedef struct rc_api_update_rich_presence_response_t { ++ /* Common server-provided response information */ ++ rc_api_response_t response; ++} ++rc_api_update_rich_presence_response_t; ++ ++RC_EXPORT int RC_CCONV rc_api_init_update_rich_presence_request(rc_api_request_t* request, const rc_api_update_rich_presence_request_t* api_params); ++RC_EXPORT int RC_CCONV rc_api_init_update_rich_presence_request_hosted(rc_api_request_t* request, const rc_api_update_rich_presence_request_t* api_params, const rc_api_host_t* host); ++RC_EXPORT int RC_CCONV rc_api_process_update_rich_presence_server_response(rc_api_update_rich_presence_response_t* response, const rc_api_server_response_t* server_response); ++RC_EXPORT void RC_CCONV rc_api_destroy_update_rich_presence_response(rc_api_update_rich_presence_response_t* response); ++ ++/* --- Fetch Badge Range --- */ ++ ++/** ++ * API parameters for a fetch badge range request. ++ */ ++typedef struct rc_api_fetch_badge_range_request_t { ++ /* Unused */ ++ uint32_t unused; ++} ++rc_api_fetch_badge_range_request_t; ++ ++/** ++ * Response data for a fetch badge range request. ++ */ ++typedef struct rc_api_fetch_badge_range_response_t { ++ /* The numeric identifier of the first valid badge ID */ ++ uint32_t first_badge_id; ++ /* The numeric identifier of the first unassigned badge ID */ ++ uint32_t next_badge_id; ++ ++ /* Common server-provided response information */ ++ rc_api_response_t response; ++} ++rc_api_fetch_badge_range_response_t; ++ ++RC_EXPORT int RC_CCONV rc_api_init_fetch_badge_range_request(rc_api_request_t* request, const rc_api_fetch_badge_range_request_t* api_params); ++RC_EXPORT int RC_CCONV rc_api_init_fetch_badge_range_request_hosted(rc_api_request_t* request, const rc_api_fetch_badge_range_request_t* api_params, const rc_api_host_t* host); ++/* [deprecated] use rc_api_process_fetch_badge_range_server_response instead */ ++RC_EXPORT int RC_CCONV rc_api_process_fetch_badge_range_response(rc_api_fetch_badge_range_response_t* response, const char* server_response); ++RC_EXPORT int RC_CCONV rc_api_process_fetch_badge_range_server_response(rc_api_fetch_badge_range_response_t* response, const rc_api_server_response_t* server_response); ++RC_EXPORT void RC_CCONV rc_api_destroy_fetch_badge_range_response(rc_api_fetch_badge_range_response_t* response); ++ ++/* --- Add Game Hash --- */ ++ ++/** ++ * API parameters for an add game hash request. ++ */ ++typedef struct rc_api_add_game_hash_request_t { ++ /* The username of the developer */ ++ const char* username; ++ /* The API token from the login request */ ++ const char* api_token; ++ /* The unique identifier of the game (0 to create a new game entry) */ ++ uint32_t game_id; ++ /* The unique identifier of the console for the game */ ++ uint32_t console_id; ++ /* The title of the game */ ++ const char* title; ++ /* The hash being added */ ++ const char* hash; ++ /* A description of the hash being added (usually the normalized ROM name) */ ++ const char* hash_description; ++} ++rc_api_add_game_hash_request_t; ++ ++/** ++ * Response data for an update code note request. ++ */ ++typedef struct rc_api_add_game_hash_response_t { ++ /* The unique identifier of the game */ ++ uint32_t game_id; ++ ++ /* Common server-provided response information */ ++ rc_api_response_t response; ++} ++rc_api_add_game_hash_response_t; ++ ++RC_EXPORT int RC_CCONV rc_api_init_add_game_hash_request(rc_api_request_t* request, const rc_api_add_game_hash_request_t* api_params); ++RC_EXPORT int RC_CCONV rc_api_init_add_game_hash_request_hosted(rc_api_request_t* request, const rc_api_add_game_hash_request_t* api_params, const rc_api_host_t* host); ++/* [deprecated] use rc_api_process_add_game_hash_server_response instead */ ++RC_EXPORT int RC_CCONV rc_api_process_add_game_hash_response(rc_api_add_game_hash_response_t* response, const char* server_response); ++RC_EXPORT int RC_CCONV rc_api_process_add_game_hash_server_response(rc_api_add_game_hash_response_t* response, const rc_api_server_response_t* server_response); ++RC_EXPORT void RC_CCONV rc_api_destroy_add_game_hash_response(rc_api_add_game_hash_response_t* response); ++ ++RC_END_C_DECLS ++ ++#endif /* RC_EDITOR_H */ +diff -rupbN melonDS.orig/src/rcheevos/include/rc_api_info.h melonDS.ra/src/rcheevos/include/rc_api_info.h +--- melonDS.orig/src/rcheevos/include/rc_api_info.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/include/rc_api_info.h 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,278 @@ ++#ifndef RC_API_INFO_H ++#define RC_API_INFO_H ++ ++#include "rc_api_request.h" ++ ++#include ++#include ++ ++RC_BEGIN_C_DECLS ++ ++/* --- Fetch Achievement Info --- */ ++ ++/** ++ * API parameters for a fetch achievement info request. ++ */ ++typedef struct rc_api_fetch_achievement_info_request_t { ++ /* The username of the player */ ++ const char* username; ++ /* The API token from the login request */ ++ const char* api_token; ++ /* The unique identifier of the achievement */ ++ uint32_t achievement_id; ++ /* The 1-based index of the first entry to retrieve */ ++ uint32_t first_entry; ++ /* The number of entries to retrieve */ ++ uint32_t count; ++ /* Non-zero to only return unlocks earned by the user's friends */ ++ uint32_t friends_only; ++} ++rc_api_fetch_achievement_info_request_t; ++ ++/* An achievement awarded entry */ ++typedef struct rc_api_achievement_awarded_entry_t { ++ /* The user associated to the entry */ ++ const char* username; ++ /* A URL to the user's avatar image */ ++ const char* avatar_url; ++ /* When the achievement was awarded */ ++ time_t awarded; ++} ++rc_api_achievement_awarded_entry_t; ++ ++/** ++ * Response data for a fetch achievement info request. ++ */ ++typedef struct rc_api_fetch_achievement_info_response_t { ++ /* The unique identifier of the achievement */ ++ uint32_t id; ++ /* The unique identifier of the game to which the leaderboard is associated */ ++ uint32_t game_id; ++ /* The number of times the achievement has been awarded */ ++ uint32_t num_awarded; ++ /* The number of players that have earned at least one achievement for the game */ ++ uint32_t num_players; ++ ++ /* An array of recently rewarded entries */ ++ rc_api_achievement_awarded_entry_t* recently_awarded; ++ /* The number of items in the recently_awarded array */ ++ uint32_t num_recently_awarded; ++ ++ /* Common server-provided response information */ ++ rc_api_response_t response; ++} ++rc_api_fetch_achievement_info_response_t; ++ ++RC_EXPORT int RC_CCONV rc_api_init_fetch_achievement_info_request(rc_api_request_t* request, const rc_api_fetch_achievement_info_request_t* api_params); ++RC_EXPORT int RC_CCONV rc_api_init_fetch_achievement_info_request_hosted(rc_api_request_t* request, const rc_api_fetch_achievement_info_request_t* api_params, const rc_api_host_t* host); ++/* [deprecated] use rc_api_process_fetch_achievement_info_server_response instead */ ++RC_EXPORT int RC_CCONV rc_api_process_fetch_achievement_info_response(rc_api_fetch_achievement_info_response_t* response, const char* server_response); ++RC_EXPORT int RC_CCONV rc_api_process_fetch_achievement_info_server_response(rc_api_fetch_achievement_info_response_t* response, const rc_api_server_response_t* server_response); ++RC_EXPORT void RC_CCONV rc_api_destroy_fetch_achievement_info_response(rc_api_fetch_achievement_info_response_t* response); ++ ++/* --- Fetch Leaderboard Info --- */ ++ ++/** ++ * API parameters for a fetch leaderboard info request. ++ */ ++typedef struct rc_api_fetch_leaderboard_info_request_t { ++ /* The unique identifier of the leaderboard */ ++ uint32_t leaderboard_id; ++ /* The number of entries to retrieve */ ++ uint32_t count; ++ /* The 1-based index of the first entry to retrieve */ ++ uint32_t first_entry; ++ /* The username of the player around whom the entries should be returned */ ++ const char* username; ++} ++rc_api_fetch_leaderboard_info_request_t; ++ ++/* A leaderboard info entry */ ++typedef struct rc_api_lboard_info_entry_t { ++ /* The user associated to the entry */ ++ const char* username; ++ /* A URL to the user's avatar image */ ++ const char* avatar_url; ++ /* The rank of the entry */ ++ uint32_t rank; ++ /* The index of the entry */ ++ uint32_t index; ++ /* The value of the entry */ ++ int32_t score; ++ /* When the entry was submitted */ ++ time_t submitted; ++} ++rc_api_lboard_info_entry_t; ++ ++/** ++ * Response data for a fetch leaderboard info request. ++ */ ++typedef struct rc_api_fetch_leaderboard_info_response_t { ++ /* The unique identifier of the leaderboard */ ++ uint32_t id; ++ /* The format to pass to rc_format_value to format the leaderboard value */ ++ int format; ++ /* If non-zero, indicates that lower scores appear first */ ++ uint32_t lower_is_better; ++ /* The title of the leaderboard */ ++ const char* title; ++ /* The description of the leaderboard */ ++ const char* description; ++ /* The definition of the leaderboard to be passed to rc_runtime_activate_lboard */ ++ const char* definition; ++ /* The unique identifier of the game to which the leaderboard is associated */ ++ uint32_t game_id; ++ /* The author of the leaderboard */ ++ const char* author; ++ /* When the leaderboard was first uploaded to the server */ ++ time_t created; ++ /* When the leaderboard was last modified on the server */ ++ time_t updated; ++ ++ /* An array of requested entries */ ++ rc_api_lboard_info_entry_t* entries; ++ /* The number of items in the entries array */ ++ uint32_t num_entries; ++ ++ /* The total number of entries on the server */ ++ uint32_t total_entries; ++ ++ /* Common server-provided response information */ ++ rc_api_response_t response; ++} ++rc_api_fetch_leaderboard_info_response_t; ++ ++RC_EXPORT int RC_CCONV rc_api_init_fetch_leaderboard_info_request(rc_api_request_t* request, const rc_api_fetch_leaderboard_info_request_t* api_params); ++RC_EXPORT int RC_CCONV rc_api_init_fetch_leaderboard_info_request_hosted(rc_api_request_t* request, const rc_api_fetch_leaderboard_info_request_t* api_params, const rc_api_host_t* host); ++/* [deprecated] use rc_api_process_fetch_leaderboard_info_server_response instead */ ++RC_EXPORT int RC_CCONV rc_api_process_fetch_leaderboard_info_response(rc_api_fetch_leaderboard_info_response_t* response, const char* server_response); ++RC_EXPORT int RC_CCONV rc_api_process_fetch_leaderboard_info_server_response(rc_api_fetch_leaderboard_info_response_t* response, const rc_api_server_response_t* server_response); ++RC_EXPORT void RC_CCONV rc_api_destroy_fetch_leaderboard_info_response(rc_api_fetch_leaderboard_info_response_t* response); ++ ++/* --- Fetch Games List --- */ ++ ++/** ++ * API parameters for a fetch games list request. ++ */ ++typedef struct rc_api_fetch_games_list_request_t { ++ /* The unique identifier of the console to query */ ++ uint32_t console_id; ++} ++rc_api_fetch_games_list_request_t; ++ ++/* A game list entry */ ++typedef struct rc_api_game_list_entry_t { ++ /* The unique identifier of the game */ ++ uint32_t id; ++ /* The name of the game */ ++ const char* name; ++} ++rc_api_game_list_entry_t; ++ ++/** ++ * Response data for a fetch games list request. ++ */ ++typedef struct rc_api_fetch_games_list_response_t { ++ /* An array of requested entries */ ++ rc_api_game_list_entry_t* entries; ++ /* The number of items in the entries array */ ++ uint32_t num_entries; ++ ++ /* Common server-provided response information */ ++ rc_api_response_t response; ++} ++rc_api_fetch_games_list_response_t; ++ ++RC_EXPORT int RC_CCONV rc_api_init_fetch_games_list_request(rc_api_request_t* request, const rc_api_fetch_games_list_request_t* api_params); ++RC_EXPORT int RC_CCONV rc_api_init_fetch_games_list_request_hosted(rc_api_request_t* request, const rc_api_fetch_games_list_request_t* api_params, const rc_api_host_t* host); ++/* [deprecated] use rc_api_process_fetch_games_list_server_response instead */ ++RC_EXPORT int RC_CCONV rc_api_process_fetch_games_list_response(rc_api_fetch_games_list_response_t* response, const char* server_response); ++RC_EXPORT int RC_CCONV rc_api_process_fetch_games_list_server_response(rc_api_fetch_games_list_response_t* response, const rc_api_server_response_t* server_response); ++RC_EXPORT void RC_CCONV rc_api_destroy_fetch_games_list_response(rc_api_fetch_games_list_response_t* response); ++ ++/* --- Fetch Game Titles --- */ ++ ++/** ++ * API parameters for a fetch games list request. ++ */ ++typedef struct rc_api_fetch_game_titles_request_t { ++ /* An array of game ids to fetch titles for */ ++ const uint32_t* game_ids; ++ /* The number of items in the game_ids array */ ++ uint32_t num_game_ids; ++} ++rc_api_fetch_game_titles_request_t; ++ ++/* A game title entry */ ++typedef struct rc_api_game_title_entry_t { ++ /* The unique identifier of the game */ ++ uint32_t id; ++ /* The title of the game */ ++ const char* title; ++ /* The image name for the game badge */ ++ const char* image_name; ++} ++rc_api_game_title_entry_t; ++ ++/** ++ * Response data for a fetch games title request. ++ */ ++typedef struct rc_api_fetch_game_titles_response_t { ++ /* An array of requested entries */ ++ rc_api_game_title_entry_t* entries; ++ /* The number of items in the entries array */ ++ uint32_t num_entries; ++ ++ /* Common server-provided response information */ ++ rc_api_response_t response; ++} ++rc_api_fetch_game_titles_response_t; ++ ++RC_EXPORT int RC_CCONV rc_api_init_fetch_game_titles_request(rc_api_request_t* request, const rc_api_fetch_game_titles_request_t* api_params); ++RC_EXPORT int RC_CCONV rc_api_init_fetch_game_titles_request_hosted(rc_api_request_t* request, const rc_api_fetch_game_titles_request_t* api_params, const rc_api_host_t* host); ++RC_EXPORT int RC_CCONV rc_api_process_fetch_game_titles_server_response(rc_api_fetch_game_titles_response_t* response, const rc_api_server_response_t* server_response); ++RC_EXPORT void RC_CCONV rc_api_destroy_fetch_game_titles_response(rc_api_fetch_game_titles_response_t* response); ++ ++/* --- Fetch Game Hashes --- */ ++ ++/** ++ * API parameters for a fetch games list request. ++ */ ++typedef struct rc_api_fetch_hash_library_request_t { ++ /** ++ * The unique identifier of the console to query. ++ * Passing RC_CONSOLE_UNKNOWN will return hashes for all consoles. ++ */ ++ uint32_t console_id; ++} rc_api_fetch_hash_library_request_t; ++ ++/* A hash library entry */ ++typedef struct rc_api_hash_library_entry_t { ++ /* The hash for the game */ ++ const char* hash; ++ /* The unique identifier of the game */ ++ uint32_t game_id; ++} rc_api_hash_library_entry_t; ++ ++/** ++ * Response data for a fetch hash library request. ++ */ ++typedef struct rc_api_fetch_hash_library_response_t { ++ /* An array of entries, one per game */ ++ rc_api_hash_library_entry_t* entries; ++ /* The number of items in the entries array */ ++ uint32_t num_entries; ++ ++ /* Common server-provided response information */ ++ rc_api_response_t response; ++} ++rc_api_fetch_hash_library_response_t; ++ ++RC_EXPORT int RC_CCONV rc_api_init_fetch_hash_library_request(rc_api_request_t* request, const rc_api_fetch_hash_library_request_t* api_params); ++RC_EXPORT int RC_CCONV rc_api_init_fetch_hash_library_request_hosted(rc_api_request_t* request, const rc_api_fetch_hash_library_request_t* api_params, const rc_api_host_t* host); ++RC_EXPORT int RC_CCONV rc_api_process_fetch_hash_library_server_response(rc_api_fetch_hash_library_response_t* response, const rc_api_server_response_t* server_response); ++RC_EXPORT void RC_CCONV rc_api_destroy_fetch_hash_library_response(rc_api_fetch_hash_library_response_t* response); ++ ++RC_END_C_DECLS ++ ++#endif /* RC_API_INFO_H */ +diff -rupbN melonDS.orig/src/rcheevos/include/rc_api_request.h melonDS.ra/src/rcheevos/include/rc_api_request.h +--- melonDS.orig/src/rcheevos/include/rc_api_request.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/include/rc_api_request.h 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,77 @@ ++#ifndef RC_API_REQUEST_H ++#define RC_API_REQUEST_H ++ ++#include "rc_error.h" ++#include "rc_util.h" ++ ++#include ++ ++RC_BEGIN_C_DECLS ++ ++/** ++ * Information about the server being connected to. ++ */ ++typedef struct rc_api_host_t { ++ /* The host name for the API calls (retroachievements.org) */ ++ const char* host; ++ /* The host name for media URLs (media.retroachievements.org) */ ++ const char* media_host; ++} ++rc_api_host_t; ++ ++/** ++ * A constructed request to send to the retroachievements server. ++ */ ++typedef struct rc_api_request_t { ++ /* The URL to send the request to (contains protocol, host, path, and query args) */ ++ const char* url; ++ /* Additional query args that should be sent via a POST command. If null, GET may be used */ ++ const char* post_data; ++ /* The HTTP Content-Type of the POST data. */ ++ const char* content_type; ++ ++ /* Storage for the url and post_data */ ++ rc_buffer_t buffer; ++} ++rc_api_request_t; ++ ++/** ++ * Common attributes for all server responses. ++ */ ++typedef struct rc_api_response_t { ++ /* Server-provided success indicator (non-zero on success, zero on failure) */ ++ int succeeded; ++ /* Server-provided message associated to the failure */ ++ const char* error_message; ++ /* Server-provided error code associated to the failure */ ++ const char* error_code; ++ ++ /* Storage for the response data */ ++ rc_buffer_t buffer; ++} ++rc_api_response_t; ++ ++RC_EXPORT void RC_CCONV rc_api_destroy_request(rc_api_request_t* request); ++ ++/* [deprecated] use rc_api_init_*_hosted instead */ ++RC_EXPORT void RC_CCONV rc_api_set_host(const char* hostname); ++/* [deprecated] use rc_api_init_*_hosted instead */ ++RC_EXPORT void RC_CCONV rc_api_set_image_host(const char* hostname); ++ ++typedef struct rc_api_server_response_t { ++ /* Pointer to the data returned from the server */ ++ const char* body; ++ /* Length of data returned from the server (Content-Length) */ ++ size_t body_length; ++ /* HTTP status code returned from the server */ ++ int http_status_code; ++} rc_api_server_response_t; ++ ++enum { ++ RC_API_SERVER_RESPONSE_CLIENT_ERROR = -1, ++ RC_API_SERVER_RESPONSE_RETRYABLE_CLIENT_ERROR = -2 ++}; ++ ++RC_END_C_DECLS ++ ++#endif /* RC_API_REQUEST_H */ +diff -rupbN melonDS.orig/src/rcheevos/include/rc_api_runtime.h melonDS.ra/src/rcheevos/include/rc_api_runtime.h +--- melonDS.orig/src/rcheevos/include/rc_api_runtime.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/include/rc_api_runtime.h 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,417 @@ ++#ifndef RC_API_RUNTIME_H ++#define RC_API_RUNTIME_H ++ ++#include "rc_api_request.h" ++ ++#include ++#include ++ ++RC_BEGIN_C_DECLS ++ ++/* --- Fetch Image --- */ ++ ++/** ++ * API parameters for a fetch image request. ++ * NOTE: fetch image server response is the raw image data. There is no rc_api_process_fetch_image_response function. ++ */ ++typedef struct rc_api_fetch_image_request_t { ++ /* The name of the image to fetch */ ++ const char* image_name; ++ /* The type of image to fetch */ ++ uint32_t image_type; ++} ++rc_api_fetch_image_request_t; ++ ++#define RC_IMAGE_TYPE_GAME 1 ++#define RC_IMAGE_TYPE_ACHIEVEMENT 2 ++#define RC_IMAGE_TYPE_ACHIEVEMENT_LOCKED 3 ++#define RC_IMAGE_TYPE_USER 4 ++ ++RC_EXPORT int RC_CCONV rc_api_init_fetch_image_request(rc_api_request_t* request, const rc_api_fetch_image_request_t* api_params); ++RC_EXPORT int RC_CCONV rc_api_init_fetch_image_request_hosted(rc_api_request_t* request, const rc_api_fetch_image_request_t* api_params, const rc_api_host_t* host); ++ ++/* --- Resolve Hash --- */ ++ ++/** ++ * API parameters for a resolve hash request. ++ */ ++typedef struct rc_api_resolve_hash_request_t { ++ /* Unused - hash lookup does not require credentials */ ++ const char* username; ++ /* Unused - hash lookup does not require credentials */ ++ const char* api_token; ++ /* The generated hash of the game to be identified */ ++ const char* game_hash; ++} ++rc_api_resolve_hash_request_t; ++ ++/** ++ * Response data for a resolve hash request. ++ */ ++typedef struct rc_api_resolve_hash_response_t { ++ /* The unique identifier of the game, 0 if no match was found */ ++ uint32_t game_id; ++ ++ /* Common server-provided response information */ ++ rc_api_response_t response; ++} ++rc_api_resolve_hash_response_t; ++ ++RC_EXPORT int RC_CCONV rc_api_init_resolve_hash_request(rc_api_request_t* request, const rc_api_resolve_hash_request_t* api_params); ++RC_EXPORT int RC_CCONV rc_api_init_resolve_hash_request_hosted(rc_api_request_t* request, const rc_api_resolve_hash_request_t* api_params, const rc_api_host_t* host); ++/* [deprecated] use rc_api_process_resolve_hash_server_response instead */ ++RC_EXPORT int RC_CCONV rc_api_process_resolve_hash_response(rc_api_resolve_hash_response_t* response, const char* server_response); ++RC_EXPORT int RC_CCONV rc_api_process_resolve_hash_server_response(rc_api_resolve_hash_response_t* response, const rc_api_server_response_t* server_response); ++RC_EXPORT void RC_CCONV rc_api_destroy_resolve_hash_response(rc_api_resolve_hash_response_t* response); ++ ++/* --- Fetch Game Data --- */ ++ ++/** ++ * API parameters for a fetch game data request. ++ */ ++typedef struct rc_api_fetch_game_data_request_t { ++ /* The username of the player */ ++ const char* username; ++ /* The API token from the login request */ ++ const char* api_token; ++ /* The unique identifier of the game */ ++ uint32_t game_id; ++ /* The generated hash of the game to be identified (ignored if game_id is not 0) */ ++ const char* game_hash; ++} ++rc_api_fetch_game_data_request_t; ++ ++/* A leaderboard definition */ ++typedef struct rc_api_leaderboard_definition_t { ++ /* The unique identifier of the leaderboard */ ++ uint32_t id; ++ /* The format to pass to rc_format_value to format the leaderboard value */ ++ int format; ++ /* The title of the leaderboard */ ++ const char* title; ++ /* The description of the leaderboard */ ++ const char* description; ++ /* The definition of the leaderboard to be passed to rc_runtime_activate_lboard */ ++ const char* definition; ++ /* Non-zero if lower values are better for this leaderboard */ ++ uint8_t lower_is_better; ++ /* Non-zero if the leaderboard should not be displayed in a list of leaderboards */ ++ uint8_t hidden; ++} ++rc_api_leaderboard_definition_t; ++ ++/* An achievement definition */ ++typedef struct rc_api_achievement_definition_t { ++ /* The unique identifier of the achievement */ ++ uint32_t id; ++ /* The number of points the achievement is worth */ ++ uint32_t points; ++ /* The achievement category (core, unofficial) */ ++ uint32_t category; ++ /* The title of the achievement */ ++ const char* title; ++ /* The description of the achievement */ ++ const char* description; ++ /* The definition of the achievement to be passed to rc_runtime_activate_achievement */ ++ const char* definition; ++ /* The author of the achievment */ ++ const char* author; ++ /* The image name for the achievement badge */ ++ const char* badge_name; ++ /* When the achievement was first uploaded to the server */ ++ time_t created; ++ /* When the achievement was last modified on the server */ ++ time_t updated; ++ /* The achievement type (win/progression/missable) */ ++ uint32_t type; ++ /* The approximate rarity of the achievement (X% of users have earned the achievement) */ ++ float rarity; ++ /* The approximate rarity of the achievement in hardcore (X% of users have earned the achievement in hardcore) */ ++ float rarity_hardcore; ++ /* The URL for the achievement badge */ ++ const char* badge_url; ++ /* The URL for the locked achievement badge */ ++ const char* badge_locked_url; ++} ++rc_api_achievement_definition_t; ++ ++#define RC_ACHIEVEMENT_CATEGORY_CORE 3 ++#define RC_ACHIEVEMENT_CATEGORY_UNOFFICIAL 5 ++ ++#define RC_ACHIEVEMENT_TYPE_STANDARD 0 ++#define RC_ACHIEVEMENT_TYPE_MISSABLE 1 ++#define RC_ACHIEVEMENT_TYPE_PROGRESSION 2 ++#define RC_ACHIEVEMENT_TYPE_WIN 3 ++ ++/** ++ * Response data for a fetch game data request. ++ */ ++typedef struct rc_api_fetch_game_data_response_t { ++ /* The unique identifier of the game */ ++ uint32_t id; ++ /* The console associated to the game */ ++ uint32_t console_id; ++ /* The title of the game */ ++ const char* title; ++ /* The image name for the game badge */ ++ const char* image_name; ++ /* The URL for the game badge */ ++ const char* image_url; ++ /* The rich presence script for the game to be passed to rc_runtime_activate_richpresence */ ++ const char* rich_presence_script; ++ ++ /* An array of achievements for the game */ ++ rc_api_achievement_definition_t* achievements; ++ /* The number of items in the achievements array */ ++ uint32_t num_achievements; ++ ++ /* An array of leaderboards for the game */ ++ rc_api_leaderboard_definition_t* leaderboards; ++ /* The number of items in the leaderboards array */ ++ uint32_t num_leaderboards; ++ ++ /* Common server-provided response information */ ++ rc_api_response_t response; ++} ++rc_api_fetch_game_data_response_t; ++ ++RC_EXPORT int RC_CCONV rc_api_init_fetch_game_data_request(rc_api_request_t* request, const rc_api_fetch_game_data_request_t* api_params); ++RC_EXPORT int RC_CCONV rc_api_init_fetch_game_data_request_hosted(rc_api_request_t* request, const rc_api_fetch_game_data_request_t* api_params, const rc_api_host_t* host); ++/* [deprecated] use rc_api_process_fetch_game_data_server_response instead */ ++RC_EXPORT int RC_CCONV rc_api_process_fetch_game_data_response(rc_api_fetch_game_data_response_t* response, const char* server_response); ++RC_EXPORT int RC_CCONV rc_api_process_fetch_game_data_server_response(rc_api_fetch_game_data_response_t* response, const rc_api_server_response_t* server_response); ++RC_EXPORT void RC_CCONV rc_api_destroy_fetch_game_data_response(rc_api_fetch_game_data_response_t* response); ++ ++/* --- Fetch Game Sets --- */ ++ ++/** ++ * API parameters for a fetch game data request. ++ */ ++typedef struct rc_api_fetch_game_sets_request_t { ++ /* The username of the player */ ++ const char* username; ++ /* The API token from the login request */ ++ const char* api_token; ++ /* The unique identifier of the game */ ++ uint32_t game_id; ++ /* The generated hash of the game to be identified (ignored if game_id is not 0) */ ++ const char* game_hash; ++} ++rc_api_fetch_game_sets_request_t; ++ ++#define RC_ACHIEVEMENT_SET_TYPE_CORE 0 ++#define RC_ACHIEVEMENT_SET_TYPE_BONUS 1 ++#define RC_ACHIEVEMENT_SET_TYPE_SPECIALTY 2 ++#define RC_ACHIEVEMENT_SET_TYPE_EXCLUSIVE 3 ++ ++/* A game subset definition */ ++typedef struct rc_api_achievement_set_definition_t { ++ /* The unique identifier of the achievement set */ ++ uint32_t id; ++ /* The legacy game_id of the achievement set (used for editor API calls) */ ++ uint32_t game_id; ++ /* The title of the achievement set */ ++ const char* title; ++ /* The image name for the achievement set badge */ ++ const char* image_name; ++ /* The URL for the achievement set badge */ ++ const char* image_url; ++ ++ /* An array of achievements for the achievement set */ ++ rc_api_achievement_definition_t* achievements; ++ /* The number of items in the achievements array */ ++ uint32_t num_achievements; ++ ++ /* An array of leaderboards for the achievement set */ ++ rc_api_leaderboard_definition_t* leaderboards; ++ /* The number of items in the leaderboards array */ ++ uint32_t num_leaderboards; ++ ++ /* The type of the achievement set */ ++ uint8_t type; ++} ++rc_api_achievement_set_definition_t; ++ ++/** ++ * Response data for a fetch game sets request. ++ */ ++typedef struct rc_api_fetch_game_sets_response_t { ++ /* The unique identifier of the game */ ++ uint32_t id; ++ /* The console associated to the game */ ++ uint32_t console_id; ++ /* The title of the game */ ++ const char* title; ++ /* The image name for the game badge */ ++ const char* image_name; ++ /* The URL for the game badge */ ++ const char* image_url; ++ /* The rich presence script for the game to be passed to rc_runtime_activate_richpresence */ ++ const char* rich_presence_script; ++ /* The unique identifier of the game to use for session requests (startsession/ping/etc) */ ++ uint32_t session_game_id; ++ ++ /* An array of sets for the game */ ++ rc_api_achievement_set_definition_t* sets; ++ /* The number of items in the sets array */ ++ uint32_t num_sets; ++ ++ /* Common server-provided response information */ ++ rc_api_response_t response; ++} ++rc_api_fetch_game_sets_response_t; ++ ++RC_EXPORT int RC_CCONV rc_api_init_fetch_game_sets_request(rc_api_request_t* request, const rc_api_fetch_game_sets_request_t* api_params); ++RC_EXPORT int RC_CCONV rc_api_init_fetch_game_sets_request_hosted(rc_api_request_t* request, const rc_api_fetch_game_sets_request_t* api_params, const rc_api_host_t* host); ++RC_EXPORT int RC_CCONV rc_api_process_fetch_game_sets_server_response(rc_api_fetch_game_sets_response_t* response, const rc_api_server_response_t* server_response); ++RC_EXPORT void RC_CCONV rc_api_destroy_fetch_game_sets_response(rc_api_fetch_game_sets_response_t* response); ++ ++/* --- Ping --- */ ++ ++/** ++ * API parameters for a ping request. ++ */ ++typedef struct rc_api_ping_request_t { ++ /* The username of the player */ ++ const char* username; ++ /* The API token from the login request */ ++ const char* api_token; ++ /* The unique identifier of the game */ ++ uint32_t game_id; ++ /* (optional) The current rich presence evaluation for the user */ ++ const char* rich_presence; ++ /* (recommended) The hash associated to the game being played */ ++ const char* game_hash; ++ /* Non-zero if hardcore is currently enabled (ignored if game_hash is null) */ ++ uint32_t hardcore; ++} ++rc_api_ping_request_t; ++ ++/** ++ * Response data for a ping request. ++ */ ++typedef struct rc_api_ping_response_t { ++ /* Common server-provided response information */ ++ rc_api_response_t response; ++} ++rc_api_ping_response_t; ++ ++RC_EXPORT int RC_CCONV rc_api_init_ping_request(rc_api_request_t* request, const rc_api_ping_request_t* api_params); ++RC_EXPORT int RC_CCONV rc_api_init_ping_request_hosted(rc_api_request_t* request, const rc_api_ping_request_t* api_params, const rc_api_host_t* host); ++/* [deprecated] use rc_api_process_ping_server_response instead */ ++RC_EXPORT int RC_CCONV rc_api_process_ping_response(rc_api_ping_response_t* response, const char* server_response); ++RC_EXPORT int RC_CCONV rc_api_process_ping_server_response(rc_api_ping_response_t* response, const rc_api_server_response_t* server_response); ++RC_EXPORT void RC_CCONV rc_api_destroy_ping_response(rc_api_ping_response_t* response); ++ ++/* --- Award Achievement --- */ ++ ++/** ++ * API parameters for an award achievement request. ++ */ ++typedef struct rc_api_award_achievement_request_t { ++ /* The username of the player */ ++ const char* username; ++ /* The API token from the login request */ ++ const char* api_token; ++ /* The unique identifier of the achievement */ ++ uint32_t achievement_id; ++ /* Non-zero if the achievement was earned in hardcore */ ++ uint32_t hardcore; ++ /* The hash associated to the game being played */ ++ const char* game_hash; ++ /* The number of seconds since the achievement was unlocked */ ++ uint32_t seconds_since_unlock; ++} ++rc_api_award_achievement_request_t; ++ ++/** ++ * Response data for an award achievement request. ++ */ ++typedef struct rc_api_award_achievement_response_t { ++ /* The unique identifier of the achievement that was awarded */ ++ uint32_t awarded_achievement_id; ++ /* The updated player score */ ++ uint32_t new_player_score; ++ /* The updated player softcore score */ ++ uint32_t new_player_score_softcore; ++ /* The number of achievements the user has not yet unlocked for this game ++ * (in hardcore/non-hardcore per hardcore flag in request) */ ++ uint32_t achievements_remaining; ++ ++ /* Common server-provided response information */ ++ rc_api_response_t response; ++} ++rc_api_award_achievement_response_t; ++ ++RC_EXPORT int RC_CCONV rc_api_init_award_achievement_request(rc_api_request_t* request, const rc_api_award_achievement_request_t* api_params); ++RC_EXPORT int RC_CCONV rc_api_init_award_achievement_request_hosted(rc_api_request_t* request, const rc_api_award_achievement_request_t* api_params, const rc_api_host_t* host); ++/* [deprecated] use rc_api_process_award_achievement_server_response instead */ ++RC_EXPORT int RC_CCONV rc_api_process_award_achievement_response(rc_api_award_achievement_response_t* response, const char* server_response); ++RC_EXPORT int RC_CCONV rc_api_process_award_achievement_server_response(rc_api_award_achievement_response_t* response, const rc_api_server_response_t* server_response); ++RC_EXPORT void RC_CCONV rc_api_destroy_award_achievement_response(rc_api_award_achievement_response_t* response); ++ ++/* --- Submit Leaderboard Entry --- */ ++ ++/** ++ * API parameters for a submit lboard entry request. ++ */ ++typedef struct rc_api_submit_lboard_entry_request_t { ++ /* The username of the player */ ++ const char* username; ++ /* The API token from the login request */ ++ const char* api_token; ++ /* The unique identifier of the leaderboard */ ++ uint32_t leaderboard_id; ++ /* The value being submitted */ ++ int32_t score; ++ /* The hash associated to the game being played */ ++ const char* game_hash; ++ /* The number of seconds since the leaderboard attempt was completed */ ++ uint32_t seconds_since_completion; ++} ++rc_api_submit_lboard_entry_request_t; ++ ++/* A leaderboard entry */ ++typedef struct rc_api_lboard_entry_t { ++ /* The user associated to the entry */ ++ const char* username; ++ /* The rank of the entry */ ++ uint32_t rank; ++ /* The value of the entry */ ++ int32_t score; ++} ++rc_api_lboard_entry_t; ++ ++/** ++ * Response data for a submit lboard entry request. ++ */ ++typedef struct rc_api_submit_lboard_entry_response_t { ++ /* The value that was submitted */ ++ int32_t submitted_score; ++ /* The player's best submitted value */ ++ int32_t best_score; ++ /* The player's new rank within the leaderboard */ ++ uint32_t new_rank; ++ /* The total number of entries in the leaderboard */ ++ uint32_t num_entries; ++ ++ /* An array of the top entries for the leaderboard */ ++ rc_api_lboard_entry_t* top_entries; ++ /* The number of items in the top_entries array */ ++ uint32_t num_top_entries; ++ ++ /* Common server-provided response information */ ++ rc_api_response_t response; ++} ++rc_api_submit_lboard_entry_response_t; ++ ++RC_EXPORT int RC_CCONV rc_api_init_submit_lboard_entry_request(rc_api_request_t* request, const rc_api_submit_lboard_entry_request_t* api_params); ++RC_EXPORT int RC_CCONV rc_api_init_submit_lboard_entry_request_hosted(rc_api_request_t* request, const rc_api_submit_lboard_entry_request_t* api_params, const rc_api_host_t* host); ++/* [deprecated] use rc_api_process_submit_lboard_entry_server_response instead */ ++RC_EXPORT int RC_CCONV rc_api_process_submit_lboard_entry_response(rc_api_submit_lboard_entry_response_t* response, const char* server_response); ++RC_EXPORT int RC_CCONV rc_api_process_submit_lboard_entry_server_response(rc_api_submit_lboard_entry_response_t* response, const rc_api_server_response_t* server_response); ++RC_EXPORT void RC_CCONV rc_api_destroy_submit_lboard_entry_response(rc_api_submit_lboard_entry_response_t* response); ++ ++RC_END_C_DECLS ++ ++#endif /* RC_API_RUNTIME_H */ +diff -rupbN melonDS.orig/src/rcheevos/include/rc_api_user.h melonDS.ra/src/rcheevos/include/rc_api_user.h +--- melonDS.orig/src/rcheevos/include/rc_api_user.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/include/rc_api_user.h 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,262 @@ ++#ifndef RC_API_USER_H ++#define RC_API_USER_H ++ ++#include "rc_api_request.h" ++ ++#include ++#include ++ ++RC_BEGIN_C_DECLS ++ ++/* --- Login --- */ ++ ++/** ++ * API parameters for a login request. ++ * If both password and api_token are provided, api_token will be ignored. ++ */ ++typedef struct rc_api_login_request_t { ++ /* The username of the player being logged in */ ++ const char* username; ++ /* The API token from a previous login */ ++ const char* api_token; ++ /* The player's password */ ++ const char* password; ++} ++rc_api_login_request_t; ++ ++/** ++ * Response data for a login request. ++ */ ++typedef struct rc_api_login_response_t { ++ /* The case-corrected username of the player */ ++ const char* username; ++ /* The API token to use for all future requests */ ++ const char* api_token; ++ /* The current score of the player */ ++ uint32_t score; ++ /* The current softcore score of the player */ ++ uint32_t score_softcore; ++ /* The number of unread messages waiting for the player on the web site */ ++ uint32_t num_unread_messages; ++ /* The preferred name to display for the player */ ++ const char* display_name; ++ /* A URL to the user's avatar image */ ++ const char* avatar_url; ++ ++ /* Common server-provided response information */ ++ rc_api_response_t response; ++} ++rc_api_login_response_t; ++ ++RC_EXPORT int RC_CCONV rc_api_init_login_request(rc_api_request_t* request, const rc_api_login_request_t* api_params); ++RC_EXPORT int RC_CCONV rc_api_init_login_request_hosted(rc_api_request_t* request, const rc_api_login_request_t* api_params, const rc_api_host_t* host); ++/* [deprecated] use rc_api_process_login_server_response instead */ ++RC_EXPORT int RC_CCONV rc_api_process_login_response(rc_api_login_response_t* response, const char* server_response); ++RC_EXPORT int RC_CCONV rc_api_process_login_server_response(rc_api_login_response_t* response, const rc_api_server_response_t* server_response); ++RC_EXPORT void RC_CCONV rc_api_destroy_login_response(rc_api_login_response_t* response); ++ ++/* --- Start Session --- */ ++ ++/** ++ * API parameters for a start session request. ++ */ ++typedef struct rc_api_start_session_request_t { ++ /* The username of the player */ ++ const char* username; ++ /* The API token from the login request */ ++ const char* api_token; ++ /* The unique identifier of the game */ ++ uint32_t game_id; ++ /* (recommended) The hash associated to the game being played */ ++ const char* game_hash; ++ /* Non-zero if hardcore is currently enabled (ignored if game_hash is null) */ ++ uint32_t hardcore; ++} ++rc_api_start_session_request_t; ++ ++/** ++ * Response data for an achievement unlock. ++ */ ++typedef struct rc_api_unlock_entry_t { ++ /* The unique identifier of the unlocked achievement */ ++ uint32_t achievement_id; ++ /* When the achievement was unlocked */ ++ time_t when; ++} ++rc_api_unlock_entry_t; ++ ++/** ++ * Response data for a start session request. ++ */ ++typedef struct rc_api_start_session_response_t { ++ /* An array of hardcore user unlocks */ ++ rc_api_unlock_entry_t* hardcore_unlocks; ++ /* An array of user unlocks */ ++ rc_api_unlock_entry_t* unlocks; ++ ++ /* The number of items in the hardcore_unlocks array */ ++ uint32_t num_hardcore_unlocks; ++ /* The number of items in the unlocks array */ ++ uint32_t num_unlocks; ++ ++ /* The server timestamp when the response was generated */ ++ time_t server_now; ++ ++ /* Common server-provided response information */ ++ rc_api_response_t response; ++} ++rc_api_start_session_response_t; ++ ++RC_EXPORT int RC_CCONV rc_api_init_start_session_request(rc_api_request_t* request, const rc_api_start_session_request_t* api_params); ++RC_EXPORT int RC_CCONV rc_api_init_start_session_request_hosted(rc_api_request_t* request, const rc_api_start_session_request_t* api_params, const rc_api_host_t* host); ++/* [deprecated] use rc_api_process_start_session_server_response instead */ ++RC_EXPORT int RC_CCONV rc_api_process_start_session_response(rc_api_start_session_response_t* response, const char* server_response); ++RC_EXPORT int RC_CCONV rc_api_process_start_session_server_response(rc_api_start_session_response_t* response, const rc_api_server_response_t* server_response); ++RC_EXPORT void RC_CCONV rc_api_destroy_start_session_response(rc_api_start_session_response_t* response); ++ ++/* --- Fetch User Unlocks --- */ ++ ++/** ++ * API parameters for a fetch user unlocks request. ++ */ ++typedef struct rc_api_fetch_user_unlocks_request_t { ++ /* The username of the player */ ++ const char* username; ++ /* The API token from the login request */ ++ const char* api_token; ++ /* The unique identifier of the game */ ++ uint32_t game_id; ++ /* Non-zero to fetch hardcore unlocks, 0 to fetch non-hardcore unlocks */ ++ uint32_t hardcore; ++} ++rc_api_fetch_user_unlocks_request_t; ++ ++/** ++ * Response data for a fetch user unlocks request. ++ */ ++typedef struct rc_api_fetch_user_unlocks_response_t { ++ /* An array of achievement IDs previously unlocked by the user */ ++ uint32_t* achievement_ids; ++ /* The number of items in the achievement_ids array */ ++ uint32_t num_achievement_ids; ++ ++ /* Common server-provided response information */ ++ rc_api_response_t response; ++} ++rc_api_fetch_user_unlocks_response_t; ++ ++RC_EXPORT int RC_CCONV rc_api_init_fetch_user_unlocks_request(rc_api_request_t* request, const rc_api_fetch_user_unlocks_request_t* api_params); ++RC_EXPORT int RC_CCONV rc_api_init_fetch_user_unlocks_request_hosted(rc_api_request_t* request, const rc_api_fetch_user_unlocks_request_t* api_params, const rc_api_host_t* host); ++/* [deprecated] use rc_api_process_fetch_user_unlocks_server_response instead */ ++RC_EXPORT int RC_CCONV rc_api_process_fetch_user_unlocks_response(rc_api_fetch_user_unlocks_response_t* response, const char* server_response); ++RC_EXPORT int RC_CCONV rc_api_process_fetch_user_unlocks_server_response(rc_api_fetch_user_unlocks_response_t* response, const rc_api_server_response_t* server_response); ++RC_EXPORT void RC_CCONV rc_api_destroy_fetch_user_unlocks_response(rc_api_fetch_user_unlocks_response_t* response); ++ ++/* --- Fetch Followed Users --- */ ++ ++/** ++ * API parameters for a fetch followed users request. ++ */ ++typedef struct rc_api_fetch_followed_users_request_t { ++ /* The username of the player */ ++ const char* username; ++ /* The API token from the login request */ ++ const char* api_token; ++} ++rc_api_fetch_followed_users_request_t; ++ ++typedef struct rc_api_followed_user_activity_t { ++ /* The record associated to the activity */ ++ const char* context; ++ /* The image of the record associated to the activity */ ++ const char* context_image_url; ++ /* The description of the activity */ ++ const char* description; ++ /* The time of the activity */ ++ time_t when; ++ /* The unique identifier of the record associated to the activity */ ++ uint32_t context_id; ++} ++rc_api_followed_user_activity_t; ++ ++/** ++ * Response data for a followed user. ++ */ ++typedef struct rc_api_followed_user_t { ++ /* The preferred name to display for the player */ ++ const char* display_name; ++ /* A URL to the user's avatar image */ ++ const char* avatar_url; ++ /* The player's last registered activity */ ++ rc_api_followed_user_activity_t recent_activity; ++ /* The current score of the player */ ++ uint32_t score; ++} ++rc_api_followed_user_t; ++ ++/** ++ * Response data for a fetch followed users request. ++ */ ++typedef struct rc_api_fetch_followed_users_response_t { ++ /* An array of followed user information */ ++ rc_api_followed_user_t* users; ++ /* The number of items in the users array */ ++ uint32_t num_users; ++ ++ /* Common server-provided response information */ ++ rc_api_response_t response; ++} ++rc_api_fetch_followed_users_response_t; ++ ++RC_EXPORT int RC_CCONV rc_api_init_fetch_followed_users_request(rc_api_request_t* request, const rc_api_fetch_followed_users_request_t* api_params); ++RC_EXPORT int RC_CCONV rc_api_init_fetch_followed_users_request_hosted(rc_api_request_t* request, const rc_api_fetch_followed_users_request_t* api_params, const rc_api_host_t* host); ++RC_EXPORT int RC_CCONV rc_api_process_fetch_followed_users_server_response(rc_api_fetch_followed_users_response_t* response, const rc_api_server_response_t* server_response); ++RC_EXPORT void RC_CCONV rc_api_destroy_fetch_followed_users_response(rc_api_fetch_followed_users_response_t* response); ++ ++/* --- Fetch All Progress --- */ ++ ++/** ++ * API parameters for a fetch all user progress request. ++ */ ++typedef struct rc_api_fetch_all_user_progress_request_t { ++ /* The username of the player */ ++ const char* username; ++ /* The API token from the login request */ ++ const char* api_token; ++ /* The unique identifier of the console to query */ ++ uint32_t console_id; ++} rc_api_fetch_all_user_progress_request_t; ++ ++/* An all-user-progress entry */ ++typedef struct rc_api_all_user_progress_entry_t { ++ /* The unique identifier of the game */ ++ uint32_t game_id; ++ /* The total number of achievements for this game */ ++ uint32_t num_achievements; ++ /* The total number of unlocked achievements for this game in softcore mode */ ++ uint32_t num_unlocked_achievements; ++ /* The total number of unlocked achievements for this game in hardcore mode */ ++ uint32_t num_unlocked_achievements_hardcore; ++} rc_api_all_user_progress_entry_t; ++ ++/** ++ * Response data for a fetch all user progress request. ++ */ ++typedef struct rc_api_fetch_all_user_progress_response_t { ++ /* An array of entries, one per game */ ++ rc_api_all_user_progress_entry_t* entries; ++ /* The number of items in the entries array */ ++ uint32_t num_entries; ++ ++ /* Common server-provided response information */ ++ rc_api_response_t response; ++} rc_api_fetch_all_user_progress_response_t; ++ ++RC_EXPORT int RC_CCONV rc_api_init_fetch_all_user_progress_request(rc_api_request_t* request, const rc_api_fetch_all_user_progress_request_t* api_params); ++RC_EXPORT int RC_CCONV rc_api_init_fetch_all_user_progress_request_hosted(rc_api_request_t* request, const rc_api_fetch_all_user_progress_request_t* api_params, const rc_api_host_t* host); ++RC_EXPORT int RC_CCONV rc_api_process_fetch_all_user_progress_server_response(rc_api_fetch_all_user_progress_response_t* response, const rc_api_server_response_t* server_response); ++RC_EXPORT void RC_CCONV rc_api_destroy_fetch_all_user_progress_response(rc_api_fetch_all_user_progress_response_t* response); ++ ++RC_END_C_DECLS ++ ++#endif /* RC_API_H */ +diff -rupbN melonDS.orig/src/rcheevos/include/rc_client.h melonDS.ra/src/rcheevos/include/rc_client.h +--- melonDS.orig/src/rcheevos/include/rc_client.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/include/rc_client.h 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,871 @@ ++#ifndef RC_CLIENT_H ++#define RC_CLIENT_H ++ ++#include "rc_api_request.h" ++#include "rc_error.h" ++ ++#include ++#include ++#include ++ ++RC_BEGIN_C_DECLS ++ ++/* implementation abstracted in rc_client_internal.h */ ++typedef struct rc_client_t rc_client_t; ++typedef struct rc_client_async_handle_t rc_client_async_handle_t; ++ ++/*****************************************************************************\ ++| Callbacks | ++\*****************************************************************************/ ++ ++/** ++ * Callback used to read num_bytes bytes from memory starting at address into buffer. ++ * Returns the number of bytes read. A return value of 0 indicates the address was invalid. ++ */ ++typedef uint32_t (RC_CCONV *rc_client_read_memory_func_t)(uint32_t address, uint8_t* buffer, uint32_t num_bytes, rc_client_t* client); ++ ++/** ++ * Internal method passed to rc_client_server_call_t to process the server response. ++ */ ++typedef void (RC_CCONV *rc_client_server_callback_t)(const rc_api_server_response_t* server_response, void* callback_data); ++ ++/** ++ * Callback used to issue a request to the server. ++ */ ++typedef void (RC_CCONV *rc_client_server_call_t)(const rc_api_request_t* request, rc_client_server_callback_t callback, void* callback_data, rc_client_t* client); ++ ++/** ++ * Generic callback for asynchronous eventing. ++ */ ++typedef void (RC_CCONV *rc_client_callback_t)(int result, const char* error_message, rc_client_t* client, void* userdata); ++ ++/** ++ * Callback for logging or displaying a message. ++ */ ++typedef void (RC_CCONV *rc_client_message_callback_t)(const char* message, const rc_client_t* client); ++ ++/*****************************************************************************\ ++| Runtime | ++\*****************************************************************************/ ++ ++/** ++ * Creates a new rc_client_t object. ++ */ ++RC_EXPORT rc_client_t* RC_CCONV rc_client_create(rc_client_read_memory_func_t read_memory_function, rc_client_server_call_t server_call_function); ++ ++/** ++ * Releases resources associated to a rc_client_t object. ++ * Pointer will no longer be valid after making this call. ++ */ ++RC_EXPORT void RC_CCONV rc_client_destroy(rc_client_t* client); ++ ++/** ++ * Sets whether hardcore is enabled (on by default). ++ * Can be called with a game loaded. ++ * Enabling hardcore with a game loaded will raise an RC_CLIENT_EVENT_RESET ++ * event. Processing will be disabled until rc_client_reset is called. ++ */ ++RC_EXPORT void RC_CCONV rc_client_set_hardcore_enabled(rc_client_t* client, int enabled); ++ ++/** ++ * Gets whether hardcore is enabled (on by default). ++ */ ++RC_EXPORT int RC_CCONV rc_client_get_hardcore_enabled(const rc_client_t* client); ++ ++/** ++ * Sets whether encore mode is enabled (off by default). ++ * Evaluated when loading a game. Has no effect while a game is loaded. ++ */ ++RC_EXPORT void RC_CCONV rc_client_set_encore_mode_enabled(rc_client_t* client, int enabled); ++ ++/** ++ * Gets whether encore mode is enabled (off by default). ++ */ ++RC_EXPORT int RC_CCONV rc_client_get_encore_mode_enabled(const rc_client_t* client); ++ ++/** ++ * Sets whether unofficial achievements should be loaded. ++ * Evaluated when loading a game. Has no effect while a game is loaded. ++ */ ++RC_EXPORT void RC_CCONV rc_client_set_unofficial_enabled(rc_client_t* client, int enabled); ++ ++/** ++ * Gets whether unofficial achievements should be loaded. ++ */ ++RC_EXPORT int RC_CCONV rc_client_get_unofficial_enabled(const rc_client_t* client); ++ ++/** ++ * Sets whether spectator mode is enabled (off by default). ++ * If enabled, events for achievement unlocks and leaderboard submissions will be ++ * raised, but server calls to actually perform the unlock/submit will not occur. ++ * Can be modified while a game is loaded. Evaluated at unlock/submit time. ++ * Cannot be modified if disabled before a game is loaded. ++ */ ++RC_EXPORT void RC_CCONV rc_client_set_spectator_mode_enabled(rc_client_t* client, int enabled); ++ ++/** ++ * Gets whether spectator mode is enabled (off by default). ++ */ ++RC_EXPORT int RC_CCONV rc_client_get_spectator_mode_enabled(const rc_client_t* client); ++ ++/** ++ * Attaches client-specific data to the runtime. ++ */ ++RC_EXPORT void RC_CCONV rc_client_set_userdata(rc_client_t* client, void* userdata); ++ ++/** ++ * Gets the client-specific data attached to the runtime. ++ */ ++RC_EXPORT void* RC_CCONV rc_client_get_userdata(const rc_client_t* client); ++ ++/** ++ * Sets the name of the server to use. ++ */ ++RC_EXPORT void RC_CCONV rc_client_set_host(rc_client_t* client, const char* hostname); ++ ++typedef uint64_t rc_clock_t; ++typedef rc_clock_t (RC_CCONV *rc_get_time_millisecs_func_t)(const rc_client_t* client); ++ ++/** ++ * Specifies a function that returns a value that increases once per millisecond. ++ */ ++RC_EXPORT void RC_CCONV rc_client_set_get_time_millisecs_function(rc_client_t* client, rc_get_time_millisecs_func_t handler); ++ ++/** ++ * Marks an async process as aborted. The associated callback will not be called. ++ */ ++RC_EXPORT void RC_CCONV rc_client_abort_async(rc_client_t* client, rc_client_async_handle_t* async_handle); ++ ++/** ++ * Gets a clause that can be added to the User-Agent to identify the version of rcheevos being used. ++ */ ++RC_EXPORT size_t RC_CCONV rc_client_get_user_agent_clause(rc_client_t* client, char buffer[], size_t buffer_size); ++ ++/*****************************************************************************\ ++| Logging | ++\*****************************************************************************/ ++ ++/** ++ * Sets the logging level and provides a callback to be called to do the logging. ++ */ ++RC_EXPORT void RC_CCONV rc_client_enable_logging(rc_client_t* client, int level, rc_client_message_callback_t callback); ++enum { ++ RC_CLIENT_LOG_LEVEL_NONE = 0, ++ RC_CLIENT_LOG_LEVEL_ERROR = 1, ++ RC_CLIENT_LOG_LEVEL_WARN = 2, ++ RC_CLIENT_LOG_LEVEL_INFO = 3, ++ RC_CLIENT_LOG_LEVEL_VERBOSE = 4, ++ NUM_RC_CLIENT_LOG_LEVELS = 5 ++}; ++ ++/*****************************************************************************\ ++| User | ++\*****************************************************************************/ ++ ++/** ++ * Attempt to login a user. ++ */ ++RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_login_with_password(rc_client_t* client, ++ const char* username, const char* password, ++ rc_client_callback_t callback, void* callback_userdata); ++ ++/** ++ * Attempt to login a user. ++ */ ++RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_login_with_token(rc_client_t* client, ++ const char* username, const char* token, ++ rc_client_callback_t callback, void* callback_userdata); ++ ++/** ++ * Logout the user. ++ */ ++RC_EXPORT void RC_CCONV rc_client_logout(rc_client_t* client); ++ ++typedef struct rc_client_user_t { ++ const char* display_name; ++ const char* username; ++ const char* token; ++ uint32_t score; ++ uint32_t score_softcore; ++ uint32_t num_unread_messages; ++ /* minimum version: 12.0 */ ++ const char* avatar_url; ++} rc_client_user_t; ++ ++/** ++ * Gets information about the logged in user. Will return NULL if the user is not logged in. ++ */ ++RC_EXPORT const rc_client_user_t* RC_CCONV rc_client_get_user_info(const rc_client_t* client); ++ ++/** ++ * Gets the URL for the user's profile picture. ++ * Returns RC_OK on success. ++ */ ++RC_EXPORT int RC_CCONV rc_client_user_get_image_url(const rc_client_user_t* user, char buffer[], size_t buffer_size); ++ ++typedef struct rc_client_user_game_summary_t { ++ uint32_t num_core_achievements; ++ uint32_t num_unofficial_achievements; ++ uint32_t num_unlocked_achievements; ++ uint32_t num_unsupported_achievements; ++ ++ uint32_t points_core; ++ uint32_t points_unlocked; ++ ++ /* minimum version: 12.1 */ ++ time_t beaten_time; ++ time_t completed_time; ++} rc_client_user_game_summary_t; ++ ++/** ++ * Gets a breakdown of the number of achievements in the game, and how many the user has unlocked. ++ * Used for the "You have unlocked X of Y achievements" message shown when the game starts. ++ */ ++RC_EXPORT void RC_CCONV rc_client_get_user_game_summary(const rc_client_t* client, rc_client_user_game_summary_t* summary); ++ ++typedef struct rc_client_all_user_progress_entry_t { ++ uint32_t game_id; ++ uint32_t num_achievements; ++ uint32_t num_unlocked_achievements; ++ uint32_t num_unlocked_achievements_hardcore; ++} rc_client_all_user_progress_entry_t; ++ ++typedef struct rc_client_all_user_progress_t { ++ rc_client_all_user_progress_entry_t* entries; ++ uint32_t num_entries; ++} rc_client_all_user_progress_t; ++ ++/** ++ * Callback that is fired when an all progress query completes. list may be null if the query failed. ++ */ ++typedef void(RC_CCONV* rc_client_fetch_all_user_progress_callback_t)(int result, const char* error_message, ++ rc_client_all_user_progress_t* list, ++ rc_client_t* client, void* callback_userdata); ++ ++/** ++ * Starts an asynchronous request for all progress for the given console. ++ * This query returns the total number of achievements for all games tracked by this console, as well as ++ * the user's achievement unlock count for both softcore and hardcore modes. ++ */ ++RC_EXPORT rc_client_async_handle_t* RC_CCONV ++rc_client_begin_fetch_all_user_progress(rc_client_t* client, uint32_t console_id, ++ rc_client_fetch_all_user_progress_callback_t callback, void* callback_userdata); ++ ++/** ++ * Destroys a previously-allocated result from the rc_client_begin_fetch_all_progress_list() callback. ++ */ ++RC_EXPORT void RC_CCONV rc_client_destroy_all_user_progress(rc_client_all_user_progress_t* list); ++ ++/*****************************************************************************\ ++| Game | ++\*****************************************************************************/ ++ ++#ifdef RC_CLIENT_SUPPORTS_HASH ++/** ++ * Start loading an unidentified game. ++ */ ++RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_identify_and_load_game(rc_client_t* client, ++ uint32_t console_id, const char* file_path, ++ const uint8_t* data, size_t data_size, ++ rc_client_callback_t callback, void* callback_userdata); ++ ++struct rc_hash_callbacks; ++/** ++ * Provide callback functions for interacting with the file system and processing disc-based files when generating hashes. ++ */ ++RC_EXPORT void rc_client_set_hash_callbacks(rc_client_t* client, const struct rc_hash_callbacks* callbacks); ++#endif ++ ++/** ++ * Start loading a game. ++ */ ++RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_load_game(rc_client_t* client, const char* hash, ++ rc_client_callback_t callback, void* callback_userdata); ++ ++/** ++ * Gets the current progress of the asynchronous load game process. ++ */ ++RC_EXPORT int RC_CCONV rc_client_get_load_game_state(const rc_client_t* client); ++enum { ++ RC_CLIENT_LOAD_GAME_STATE_NONE, ++ RC_CLIENT_LOAD_GAME_STATE_AWAIT_LOGIN, ++ RC_CLIENT_LOAD_GAME_STATE_IDENTIFYING_GAME, ++ RC_CLIENT_LOAD_GAME_STATE_FETCHING_GAME_DATA, /* [deprecated] - game data is now returned by identify call */ ++ RC_CLIENT_LOAD_GAME_STATE_STARTING_SESSION, ++ RC_CLIENT_LOAD_GAME_STATE_DONE, ++ RC_CLIENT_LOAD_GAME_STATE_ABORTED ++}; ++ ++/** ++ * Determines if a game was successfully identified and loaded. ++ */ ++RC_EXPORT int RC_CCONV rc_client_is_game_loaded(const rc_client_t* client); ++ ++/** ++ * Unloads the current game. ++ */ ++RC_EXPORT void RC_CCONV rc_client_unload_game(rc_client_t* client); ++ ++typedef struct rc_client_game_t { ++ uint32_t id; ++ uint32_t console_id; ++ const char* title; ++ const char* hash; ++ const char* badge_name; ++ /* minimum version: 12.0 */ ++ const char* badge_url; ++} rc_client_game_t; ++ ++/** ++ * Get information about the current game. Returns NULL if no game is loaded. ++ * NOTE: returns a dummy game record if an unidentified game is loaded. ++ */ ++RC_EXPORT const rc_client_game_t* RC_CCONV rc_client_get_game_info(const rc_client_t* client); ++ ++/** ++ * Gets the URL for the game image. ++ * Returns RC_OK on success. ++ */ ++RC_EXPORT int RC_CCONV rc_client_game_get_image_url(const rc_client_game_t* game, char buffer[], size_t buffer_size); ++ ++#ifdef RC_CLIENT_SUPPORTS_HASH ++/** ++ * Changes the active disc in a multi-disc game. ++ */ ++RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_identify_and_change_media(rc_client_t* client, const char* file_path, ++ const uint8_t* data, size_t data_size, rc_client_callback_t callback, void* callback_userdata); ++#endif ++ ++/** ++ * Changes the active disc in a multi-disc game. ++ */ ++RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_change_media(rc_client_t* client, const char* hash, ++ rc_client_callback_t callback, void* callback_userdata); ++/* this function was renamed in rcheevos 12.0 */ ++#define rc_client_begin_change_media_from_hash rc_client_begin_change_media ++ ++/*****************************************************************************\ ++| Subsets | ++\*****************************************************************************/ ++ ++typedef struct rc_client_subset_t { ++ uint32_t id; ++ const char* title; ++ char badge_name[16]; ++ ++ uint32_t num_achievements; ++ uint32_t num_leaderboards; ++ ++ /* minimum version: 12.0 */ ++ const char* badge_url; ++} rc_client_subset_t; ++ ++RC_EXPORT const rc_client_subset_t* RC_CCONV rc_client_get_subset_info(rc_client_t* client, uint32_t subset_id); ++ ++RC_EXPORT void RC_CCONV rc_client_get_user_subset_summary(const rc_client_t* client, uint32_t subset_id, rc_client_user_game_summary_t* summary); ++ ++typedef struct rc_client_subset_list_t { ++ const rc_client_subset_t** subsets; ++ uint32_t num_subsets; ++} rc_client_subset_list_t; ++ ++/** ++ * Creates a list of subsets for the currently loaded game. ++ * Returns an allocated list that must be free'd by calling rc_client_destroy_subset_list. ++ */ ++RC_EXPORT rc_client_subset_list_t* RC_CCONV rc_client_create_subset_list(rc_client_t* client); ++ ++/** ++ * Destroys a list allocated by rc_client_create_subset_list_list. ++ */ ++RC_EXPORT void RC_CCONV rc_client_destroy_subset_list(rc_client_subset_list_t* list); ++ ++/*****************************************************************************\ ++| Fetch Game Hashes | ++\*****************************************************************************/ ++ ++typedef struct rc_client_hash_library_entry_t { ++ char hash[33]; ++ uint32_t game_id; ++} rc_client_hash_library_entry_t; ++ ++typedef struct rc_client_hash_library_t { ++ rc_client_hash_library_entry_t* entries; ++ uint32_t num_entries; ++} rc_client_hash_library_t; ++ ++/** ++ * Callback that is fired when a hash library request completes. list may be null if the query failed. ++ */ ++typedef void(RC_CCONV* rc_client_fetch_hash_library_callback_t)(int result, const char* error_message, ++ rc_client_hash_library_t* list, rc_client_t* client, ++ void* callback_userdata); ++ ++/** ++ * Starts an asynchronous request for all hashes for the given console. ++ * This request returns a mapping from hashes to the game's unique identifier. A single game may have multiple ++ * hashes in the case of multi-disc games, or variants that are still compatible with the same achievement set. ++ */ ++RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_fetch_hash_library( ++ rc_client_t* client, uint32_t console_id, rc_client_fetch_hash_library_callback_t callback, void* callback_userdata); ++ ++/** ++ * Destroys a previously-allocated result from the rc_client_destroy_hash_library() callback. ++ */ ++RC_EXPORT void RC_CCONV rc_client_destroy_hash_library(rc_client_hash_library_t* list); ++ ++/*****************************************************************************\ ++| Fetch Game Titles | ++\*****************************************************************************/ ++ ++typedef struct rc_client_game_title_entry_t { ++ uint32_t game_id; ++ const char* title; ++ char badge_name[16]; ++} rc_client_game_title_entry_t; ++ ++typedef struct rc_client_game_title_list_t { ++ rc_client_game_title_entry_t* entries; ++ uint32_t num_entries; ++} rc_client_game_title_list_t; ++ ++/** ++ * Callback that is fired when a game titles request completes. list may be null if the query failed. ++ */ ++typedef void(RC_CCONV* rc_client_fetch_game_titles_callback_t)(int result, const char* error_message, ++ rc_client_game_title_list_t* list, rc_client_t* client, ++ void* callback_userdata); ++ ++/** ++ * Starts an asynchronous request for titles and badge names for the specified games. ++ * The caller must provide an array of game IDs and the number of IDs in the array. ++ */ ++RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_fetch_game_titles( ++ rc_client_t* client, const uint32_t* game_ids, uint32_t num_game_ids, ++ rc_client_fetch_game_titles_callback_t callback, void* callback_userdata); ++ ++/** ++ * Destroys a previously-allocated result from the rc_client_begin_fetch_game_titles() callback. ++ */ ++RC_EXPORT void RC_CCONV rc_client_destroy_game_title_list(rc_client_game_title_list_t* list); ++ ++/*****************************************************************************\ ++| Achievements | ++\*****************************************************************************/ ++ ++enum { ++ RC_CLIENT_ACHIEVEMENT_STATE_INACTIVE = 0, /* unprocessed */ ++ RC_CLIENT_ACHIEVEMENT_STATE_ACTIVE = 1, /* eligible to trigger */ ++ RC_CLIENT_ACHIEVEMENT_STATE_UNLOCKED = 2, /* earned by user */ ++ RC_CLIENT_ACHIEVEMENT_STATE_DISABLED = 3, /* not supported by this version of the runtime */ ++ NUM_RC_CLIENT_ACHIEVEMENT_STATES = 4 ++}; ++ ++enum { ++ RC_CLIENT_ACHIEVEMENT_CATEGORY_NONE = 0, ++ RC_CLIENT_ACHIEVEMENT_CATEGORY_CORE = (1 << 0), ++ RC_CLIENT_ACHIEVEMENT_CATEGORY_UNOFFICIAL = (1 << 1), ++ RC_CLIENT_ACHIEVEMENT_CATEGORY_CORE_AND_UNOFFICIAL = RC_CLIENT_ACHIEVEMENT_CATEGORY_CORE | RC_CLIENT_ACHIEVEMENT_CATEGORY_UNOFFICIAL ++}; ++ ++enum { ++ RC_CLIENT_ACHIEVEMENT_TYPE_STANDARD = 0, ++ RC_CLIENT_ACHIEVEMENT_TYPE_MISSABLE = 1, ++ RC_CLIENT_ACHIEVEMENT_TYPE_PROGRESSION = 2, ++ RC_CLIENT_ACHIEVEMENT_TYPE_WIN = 3 ++}; ++ ++enum { ++ RC_CLIENT_ACHIEVEMENT_BUCKET_UNKNOWN = 0, ++ RC_CLIENT_ACHIEVEMENT_BUCKET_LOCKED = 1, ++ RC_CLIENT_ACHIEVEMENT_BUCKET_UNLOCKED = 2, ++ RC_CLIENT_ACHIEVEMENT_BUCKET_UNSUPPORTED = 3, ++ RC_CLIENT_ACHIEVEMENT_BUCKET_UNOFFICIAL = 4, ++ RC_CLIENT_ACHIEVEMENT_BUCKET_RECENTLY_UNLOCKED = 5, ++ RC_CLIENT_ACHIEVEMENT_BUCKET_ACTIVE_CHALLENGE = 6, ++ RC_CLIENT_ACHIEVEMENT_BUCKET_ALMOST_THERE = 7, ++ RC_CLIENT_ACHIEVEMENT_BUCKET_UNSYNCED = 8, ++ NUM_RC_CLIENT_ACHIEVEMENT_BUCKETS = 9 ++}; ++ ++enum { ++ RC_CLIENT_ACHIEVEMENT_UNLOCKED_NONE = 0, ++ RC_CLIENT_ACHIEVEMENT_UNLOCKED_SOFTCORE = (1 << 0), ++ RC_CLIENT_ACHIEVEMENT_UNLOCKED_HARDCORE = (1 << 1), ++ RC_CLIENT_ACHIEVEMENT_UNLOCKED_BOTH = RC_CLIENT_ACHIEVEMENT_UNLOCKED_SOFTCORE | RC_CLIENT_ACHIEVEMENT_UNLOCKED_HARDCORE ++}; ++ ++typedef struct rc_client_achievement_t { ++ const char* title; ++ const char* description; ++ char badge_name[8]; ++ char measured_progress[24]; ++ float measured_percent; ++ uint32_t id; ++ uint32_t points; ++ time_t unlock_time; ++ uint8_t state; ++ uint8_t category; ++ uint8_t bucket; ++ uint8_t unlocked; ++ /* minimum version: 11.1 */ ++ float rarity; ++ float rarity_hardcore; ++ uint8_t type; ++ /* minimum version: 12.0 */ ++ const char* badge_url; ++ const char* badge_locked_url; ++} rc_client_achievement_t; ++ ++/** ++ * Get information about an achievement. Returns NULL if not found. ++ */ ++RC_EXPORT const rc_client_achievement_t* RC_CCONV rc_client_get_achievement_info(rc_client_t* client, uint32_t id); ++ ++/** ++ * Gets the URL for the achievement image. ++ * Returns RC_OK on success. ++ */ ++RC_EXPORT int RC_CCONV rc_client_achievement_get_image_url(const rc_client_achievement_t* achievement, int state, char buffer[], size_t buffer_size); ++ ++typedef struct rc_client_achievement_bucket_t { ++ const rc_client_achievement_t** achievements; ++ uint32_t num_achievements; ++ ++ const char* label; ++ uint32_t subset_id; ++ uint8_t bucket_type; ++} rc_client_achievement_bucket_t; ++ ++typedef struct rc_client_achievement_list_t { ++ const rc_client_achievement_bucket_t* buckets; ++ uint32_t num_buckets; ++} rc_client_achievement_list_t; ++ ++enum { ++ RC_CLIENT_ACHIEVEMENT_LIST_GROUPING_LOCK_STATE = 0, ++ RC_CLIENT_ACHIEVEMENT_LIST_GROUPING_PROGRESS = 1 ++}; ++ ++/** ++ * Creates a list of achievements matching the specified category and grouping. ++ * Returns an allocated list that must be free'd by calling rc_client_destroy_achievement_list. ++ */ ++RC_EXPORT rc_client_achievement_list_t* RC_CCONV rc_client_create_achievement_list(rc_client_t* client, int category, int grouping); ++ ++/** ++ * Destroys a list allocated by rc_client_create_achievement_list. ++ */ ++RC_EXPORT void RC_CCONV rc_client_destroy_achievement_list(rc_client_achievement_list_t* list); ++ ++/** ++ * Returns non-zero if there are any achievements that can be queried through rc_client_create_achievement_list(). ++ */ ++RC_EXPORT int RC_CCONV rc_client_has_achievements(rc_client_t* client); ++ ++/*****************************************************************************\ ++| Leaderboards | ++\*****************************************************************************/ ++ ++enum { ++ RC_CLIENT_LEADERBOARD_STATE_INACTIVE = 0, ++ RC_CLIENT_LEADERBOARD_STATE_ACTIVE = 1, ++ RC_CLIENT_LEADERBOARD_STATE_TRACKING = 2, ++ RC_CLIENT_LEADERBOARD_STATE_DISABLED = 3, ++ NUM_RC_CLIENT_LEADERBOARD_STATES = 4 ++}; ++ ++enum { ++ RC_CLIENT_LEADERBOARD_FORMAT_TIME = 0, ++ RC_CLIENT_LEADERBOARD_FORMAT_SCORE = 1, ++ RC_CLIENT_LEADERBOARD_FORMAT_VALUE = 2, ++ NUM_RC_CLIENT_LEADERBOARD_FORMATS = 3 ++}; ++ ++#define RC_CLIENT_LEADERBOARD_DISPLAY_SIZE 24 ++ ++typedef struct rc_client_leaderboard_t { ++ const char* title; ++ const char* description; ++ const char* tracker_value; ++ uint32_t id; ++ uint8_t state; ++ uint8_t format; ++ uint8_t lower_is_better; ++} rc_client_leaderboard_t; ++ ++/** ++ * Get information about a leaderboard. Returns NULL if not found. ++ */ ++RC_EXPORT const rc_client_leaderboard_t* RC_CCONV rc_client_get_leaderboard_info(const rc_client_t* client, uint32_t id); ++ ++typedef struct rc_client_leaderboard_tracker_t { ++ char display[RC_CLIENT_LEADERBOARD_DISPLAY_SIZE]; ++ uint32_t id; ++} rc_client_leaderboard_tracker_t; ++ ++typedef struct rc_client_leaderboard_bucket_t { ++ const rc_client_leaderboard_t** leaderboards; ++ uint32_t num_leaderboards; ++ ++ const char* label; ++ uint32_t subset_id; ++ uint8_t bucket_type; ++} rc_client_leaderboard_bucket_t; ++ ++typedef struct rc_client_leaderboard_list_t { ++ const rc_client_leaderboard_bucket_t* buckets; ++ uint32_t num_buckets; ++} rc_client_leaderboard_list_t; ++ ++enum { ++ RC_CLIENT_LEADERBOARD_BUCKET_UNKNOWN = 0, ++ RC_CLIENT_LEADERBOARD_BUCKET_INACTIVE = 1, ++ RC_CLIENT_LEADERBOARD_BUCKET_ACTIVE = 2, ++ RC_CLIENT_LEADERBOARD_BUCKET_UNSUPPORTED = 3, ++ RC_CLIENT_LEADERBOARD_BUCKET_ALL = 4, ++ NUM_RC_CLIENT_LEADERBOARD_BUCKETS = 5 ++}; ++ ++enum { ++ RC_CLIENT_LEADERBOARD_LIST_GROUPING_NONE = 0, ++ RC_CLIENT_LEADERBOARD_LIST_GROUPING_TRACKING = 1 ++}; ++ ++/** ++ * Creates a list of leaderboards matching the specified grouping. ++ * Returns an allocated list that must be free'd by calling rc_client_destroy_leaderboard_list. ++ */ ++RC_EXPORT rc_client_leaderboard_list_t* RC_CCONV rc_client_create_leaderboard_list(rc_client_t* client, int grouping); ++ ++/** ++ * Destroys a list allocated by rc_client_create_leaderboard_list. ++ */ ++RC_EXPORT void RC_CCONV rc_client_destroy_leaderboard_list(rc_client_leaderboard_list_t* list); ++ ++/** ++ * Returns non-zero if the current game has any leaderboards. ++ */ ++RC_EXPORT int RC_CCONV rc_client_has_leaderboards(rc_client_t* client); ++ ++typedef struct rc_client_leaderboard_entry_t { ++ const char* user; ++ char display[RC_CLIENT_LEADERBOARD_DISPLAY_SIZE]; ++ time_t submitted; ++ uint32_t rank; ++ uint32_t index; ++} rc_client_leaderboard_entry_t; ++ ++typedef struct rc_client_leaderboard_entry_list_t { ++ rc_client_leaderboard_entry_t* entries; ++ uint32_t num_entries; ++ uint32_t total_entries; ++ int32_t user_index; ++} rc_client_leaderboard_entry_list_t; ++ ++typedef void (RC_CCONV *rc_client_fetch_leaderboard_entries_callback_t)(int result, const char* error_message, ++ rc_client_leaderboard_entry_list_t* list, rc_client_t* client, void* callback_userdata); ++ ++/** ++ * Fetches a list of leaderboard entries from the server. ++ * Callback receives an allocated list that must be free'd by calling rc_client_destroy_leaderboard_entry_list. ++ */ ++RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_fetch_leaderboard_entries(rc_client_t* client, uint32_t leaderboard_id, ++ uint32_t first_entry, uint32_t count, rc_client_fetch_leaderboard_entries_callback_t callback, void* callback_userdata); ++ ++/** ++ * Fetches a list of leaderboard entries from the server containing the logged-in user. ++ * Callback receives an allocated list that must be free'd by calling rc_client_destroy_leaderboard_entry_list. ++ */ ++RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_fetch_leaderboard_entries_around_user(rc_client_t* client, uint32_t leaderboard_id, ++ uint32_t count, rc_client_fetch_leaderboard_entries_callback_t callback, void* callback_userdata); ++ ++/** ++ * Gets the URL for the profile picture of the user associated to a leaderboard entry. ++ * Returns RC_OK on success. ++ */ ++RC_EXPORT int RC_CCONV rc_client_leaderboard_entry_get_user_image_url(const rc_client_leaderboard_entry_t* entry, char buffer[], size_t buffer_size); ++ ++/** ++ * Destroys a list allocated by rc_client_begin_fetch_leaderboard_entries or rc_client_begin_fetch_leaderboard_entries_around_user. ++ */ ++RC_EXPORT void RC_CCONV rc_client_destroy_leaderboard_entry_list(rc_client_leaderboard_entry_list_t* list); ++ ++/** ++ * Used for scoreboard events. Contains the response from the server when a leaderboard entry is submitted. ++ * NOTE: This structure is only valid within the event callback. If you want to make use of the data outside ++ * of the callback, you should create copies of both the top entries and usernames within. ++ */ ++typedef struct rc_client_leaderboard_scoreboard_entry_t { ++ /* The user associated to the entry */ ++ const char* username; ++ /* The rank of the entry */ ++ uint32_t rank; ++ /* The value of the entry */ ++ char score[RC_CLIENT_LEADERBOARD_DISPLAY_SIZE]; ++} rc_client_leaderboard_scoreboard_entry_t; ++ ++typedef struct rc_client_leaderboard_scoreboard_t { ++ /* The ID of the leaderboard which was submitted */ ++ uint32_t leaderboard_id; ++ /* The value that was submitted */ ++ char submitted_score[RC_CLIENT_LEADERBOARD_DISPLAY_SIZE]; ++ /* The player's best submitted value */ ++ char best_score[RC_CLIENT_LEADERBOARD_DISPLAY_SIZE]; ++ /* The player's new rank within the leaderboard */ ++ uint32_t new_rank; ++ /* The total number of entries in the leaderboard */ ++ uint32_t num_entries; ++ ++ /* An array of the top entries for the leaderboard */ ++ rc_client_leaderboard_scoreboard_entry_t* top_entries; ++ /* The number of items in the top_entries array */ ++ uint32_t num_top_entries; ++} rc_client_leaderboard_scoreboard_t; ++ ++/*****************************************************************************\ ++| Rich Presence | ++\*****************************************************************************/ ++ ++/** ++ * Returns non-zero if the current game supports rich presence. ++ */ ++RC_EXPORT int RC_CCONV rc_client_has_rich_presence(rc_client_t* client); ++ ++/** ++ * Gets the current rich presence message. ++ * Returns the number of characters written to buffer. ++ */ ++RC_EXPORT size_t RC_CCONV rc_client_get_rich_presence_message(rc_client_t* client, char buffer[], size_t buffer_size); ++ ++/*****************************************************************************\ ++| Processing | ++\*****************************************************************************/ ++ ++enum { ++ RC_CLIENT_EVENT_TYPE_NONE = 0, ++ RC_CLIENT_EVENT_ACHIEVEMENT_TRIGGERED = 1, /* [achievement] was earned by the player */ ++ RC_CLIENT_EVENT_LEADERBOARD_STARTED = 2, /* [leaderboard] attempt has started */ ++ RC_CLIENT_EVENT_LEADERBOARD_FAILED = 3, /* [leaderboard] attempt failed */ ++ RC_CLIENT_EVENT_LEADERBOARD_SUBMITTED = 4, /* [leaderboard] attempt submitted */ ++ RC_CLIENT_EVENT_ACHIEVEMENT_CHALLENGE_INDICATOR_SHOW = 5, /* [achievement] challenge indicator should be shown */ ++ RC_CLIENT_EVENT_ACHIEVEMENT_CHALLENGE_INDICATOR_HIDE = 6, /* [achievement] challenge indicator should be hidden */ ++ RC_CLIENT_EVENT_ACHIEVEMENT_PROGRESS_INDICATOR_SHOW = 7, /* progress indicator should be shown for [achievement] */ ++ RC_CLIENT_EVENT_ACHIEVEMENT_PROGRESS_INDICATOR_HIDE = 8, /* progress indicator should be hidden */ ++ RC_CLIENT_EVENT_ACHIEVEMENT_PROGRESS_INDICATOR_UPDATE = 9, /* progress indicator should be updated to reflect new badge/progress for [achievement] */ ++ RC_CLIENT_EVENT_LEADERBOARD_TRACKER_SHOW = 10, /* [leaderboard_tracker] should be shown */ ++ RC_CLIENT_EVENT_LEADERBOARD_TRACKER_HIDE = 11, /* [leaderboard_tracker] should be hidden */ ++ RC_CLIENT_EVENT_LEADERBOARD_TRACKER_UPDATE = 12, /* [leaderboard_tracker] updated */ ++ RC_CLIENT_EVENT_LEADERBOARD_SCOREBOARD = 13, /* [leaderboard_scoreboard] possibly-new ranking received for [leaderboard] */ ++ RC_CLIENT_EVENT_RESET = 14, /* emulated system should be reset (as the result of enabling hardcore) */ ++ RC_CLIENT_EVENT_GAME_COMPLETED = 15, /* all achievements for the game have been earned */ ++ RC_CLIENT_EVENT_SERVER_ERROR = 16, /* an API response returned a [server_error] and will not be retried */ ++ RC_CLIENT_EVENT_DISCONNECTED = 17, /* an unlock request could not be completed and is pending */ ++ RC_CLIENT_EVENT_RECONNECTED = 18, /* all pending unlocks have been completed */ ++ RC_CLIENT_EVENT_SUBSET_COMPLETED = 19 /* all achievements for the subset have been earned */ ++}; ++ ++typedef struct rc_client_server_error_t { ++ const char* error_message; ++ const char* api; ++ int result; ++ uint32_t related_id; ++} rc_client_server_error_t; ++ ++typedef struct rc_client_event_t { ++ uint32_t type; ++ ++ rc_client_achievement_t* achievement; ++ rc_client_leaderboard_t* leaderboard; ++ rc_client_leaderboard_tracker_t* leaderboard_tracker; ++ rc_client_leaderboard_scoreboard_t* leaderboard_scoreboard; ++ rc_client_server_error_t* server_error; ++ rc_client_subset_t* subset; ++ ++} rc_client_event_t; ++ ++/** ++ * Callback used to notify the client when certain events occur. ++ */ ++typedef void (RC_CCONV *rc_client_event_handler_t)(const rc_client_event_t* event, rc_client_t* client); ++ ++/** ++ * Provides a callback for event handling. ++ */ ++RC_EXPORT void RC_CCONV rc_client_set_event_handler(rc_client_t* client, rc_client_event_handler_t handler); ++ ++/** ++ * Provides a callback for reading memory. ++ */ ++RC_EXPORT void RC_CCONV rc_client_set_read_memory_function(rc_client_t* client, rc_client_read_memory_func_t handler); ++ ++/** ++ * Specifies whether rc_client is allowed to read memory outside of rc_client_do_frame/rc_client_idle. ++ */ ++RC_EXPORT void RC_CCONV rc_client_set_allow_background_memory_reads(rc_client_t* client, int allowed); ++ ++/** ++ * Determines if there are any active achievements/leaderboards/rich presence that need processing. ++ */ ++RC_EXPORT int RC_CCONV rc_client_is_processing_required(rc_client_t* client); ++ ++/** ++ * Processes achievements for the current frame. ++ */ ++RC_EXPORT void RC_CCONV rc_client_do_frame(rc_client_t* client); ++ ++/** ++ * Processes the periodic queue. ++ * Called internally by rc_client_do_frame. ++ * Should be explicitly called if rc_client_do_frame is not being called because emulation is paused. ++ */ ++RC_EXPORT void RC_CCONV rc_client_idle(rc_client_t* client); ++ ++/** ++ * Determines if a sufficient amount of frames have been processed since the last call to rc_client_can_pause. ++ * Should not be called unless the client is trying to pause. ++ * If false is returned, and frames_remaining is not NULL, frames_remaining will be set to the number of frames ++ * still required before pause is allowed, which can be converted to a time in seconds for displaying to the user. ++ */ ++RC_EXPORT int RC_CCONV rc_client_can_pause(rc_client_t* client, uint32_t* frames_remaining); ++ ++/** ++ * Informs the runtime that the emulator has been reset. Will reset all achievements and leaderboards ++ * to their initial state (includes hiding indicators/trackers). ++ */ ++RC_EXPORT void RC_CCONV rc_client_reset(rc_client_t* client); ++ ++/** ++ * Gets the number of bytes needed to serialized the runtime state. ++ */ ++RC_EXPORT size_t RC_CCONV rc_client_progress_size(rc_client_t* client); ++ ++/** ++ * Serializes the runtime state into a buffer. ++ * Returns RC_OK on success, or an error indicator. ++ * [deprecated] use rc_client_serialize_progress_sized instead ++ */ ++RC_EXPORT int RC_CCONV rc_client_serialize_progress(rc_client_t* client, uint8_t* buffer); ++ ++/** ++ * Serializes the runtime state into a buffer. ++ * Returns RC_OK on success, or an error indicator. ++ */ ++RC_EXPORT int RC_CCONV rc_client_serialize_progress_sized(rc_client_t* client, uint8_t* buffer, size_t buffer_size); ++ ++/** ++ * Deserializes the runtime state from a buffer. ++ * Returns RC_OK on success, or an error indicator. ++ * [deprecated] use rc_client_deserialize_progress_sized instead ++ */ ++RC_EXPORT int RC_CCONV rc_client_deserialize_progress(rc_client_t* client, const uint8_t* serialized); ++ ++/** ++ * Serializes the runtime state into a buffer. ++ * Returns RC_OK on success, or an error indicator. ++ */ ++RC_EXPORT int RC_CCONV rc_client_deserialize_progress_sized(rc_client_t* client, const uint8_t* serialized, size_t serialized_size); ++ ++RC_END_C_DECLS ++ ++#endif /* RC_RUNTIME_H */ +diff -rupbN melonDS.orig/src/rcheevos/include/rc_client_raintegration.h melonDS.ra/src/rcheevos/include/rc_client_raintegration.h +--- melonDS.orig/src/rcheevos/include/rc_client_raintegration.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/include/rc_client_raintegration.h 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,101 @@ ++#ifndef RC_CLIENT_RAINTEGRATION_H ++#define RC_CLIENT_RAINTEGRATION_H ++ ++#ifndef _WIN32 ++ #undef RC_CLIENT_SUPPORTS_RAINTEGRATION /* Windows required for RAIntegration */ ++#endif ++ ++#include ++ ++#include "rc_export.h" ++ ++RC_BEGIN_C_DECLS ++ ++typedef struct rc_client_t rc_client_t; /* forward reference; in rc_client.h */ ++ ++/* types needed to implement raintegration */ ++ ++typedef struct rc_client_raintegration_menu_item_t { ++ const char* label; ++ uint32_t id; ++ uint8_t checked; ++ uint8_t enabled; ++} rc_client_raintegration_menu_item_t; ++ ++typedef struct rc_client_raintegration_menu_t { ++ rc_client_raintegration_menu_item_t* items; ++ uint32_t num_items; ++} rc_client_raintegration_menu_t; ++ ++enum { ++ RC_CLIENT_RAINTEGRATION_ACHIEVEMENT_STATE_NONE = 0, ++ RC_CLIENT_RAINTEGRATION_ACHIEVEMENT_STATE_PUBLISHED = 1, ++ RC_CLIENT_RAINTEGRATION_ACHIEVEMENT_STATE_LOCAL = 2, ++ RC_CLIENT_RAINTEGRATION_ACHIEVEMENT_STATE_MODIFIED = 3, ++ RC_CLIENT_RAINTEGRATION_ACHIEVEMENT_STATE_INSECURE = 4, ++}; ++ ++enum { ++ RC_CLIENT_RAINTEGRATION_EVENT_TYPE_NONE = 0, ++ RC_CLIENT_RAINTEGRATION_EVENT_MENUITEM_CHECKED_CHANGED = 1, /* [menu_item] checked changed */ ++ RC_CLIENT_RAINTEGRATION_EVENT_HARDCORE_CHANGED = 2, /* hardcore was enabled or disabled */ ++ RC_CLIENT_RAINTEGRATION_EVENT_PAUSE = 3, /* emulated system should be paused */ ++ RC_CLIENT_RAINTEGRATION_EVENT_MENU_CHANGED = 4 /* one or more items were added/removed from the menu and it should be rebuilt */ ++}; ++ ++typedef struct rc_client_raintegration_event_t { ++ uint32_t type; ++ ++ const rc_client_raintegration_menu_item_t* menu_item; ++} rc_client_raintegration_event_t; ++ ++typedef void (RC_CCONV *rc_client_raintegration_event_handler_t)(const rc_client_raintegration_event_t* event, ++ rc_client_t* client); ++ ++typedef void (RC_CCONV *rc_client_raintegration_write_memory_func_t)(uint32_t address, uint8_t* buffer, ++ uint32_t num_bytes, rc_client_t* client); ++ ++typedef void (RC_CCONV* rc_client_raintegration_get_game_name_func_t)(char* buffer, uint32_t buffer_size, rc_client_t* client); ++ ++/* types needed to integrate raintegration */ ++ ++#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION ++ ++#ifndef RC_CLIENT_SUPPORTS_EXTERNAL ++ #define RC_CLIENT_SUPPORTS_EXTERNAL /* external rc_client required for RAIntegration */ ++#endif ++ ++#include /* HWND */ ++ ++#include "rc_client.h" ++ ++RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_load_raintegration(rc_client_t* client, ++ const wchar_t* search_directory, HWND main_window_handle, ++ const char* client_name, const char* client_version, ++ rc_client_callback_t callback, void* callback_userdata); ++ ++RC_EXPORT void RC_CCONV rc_client_unload_raintegration(rc_client_t* client); ++ ++RC_EXPORT void RC_CCONV rc_client_raintegration_update_main_window_handle(rc_client_t* client, HWND main_window_handle); ++ ++RC_EXPORT const rc_client_raintegration_menu_t* RC_CCONV rc_client_raintegration_get_menu(const rc_client_t* client); ++ ++RC_EXPORT void RC_CCONV rc_client_raintegration_rebuild_submenu(rc_client_t* client, HMENU hMenu); ++RC_EXPORT void RC_CCONV rc_client_raintegration_update_menu_item(const rc_client_t* client, const rc_client_raintegration_menu_item_t* menu_item); ++RC_EXPORT int RC_CCONV rc_client_raintegration_activate_menu_item(const rc_client_t* client, uint32_t menu_item_id); ++ ++RC_EXPORT void RC_CCONV rc_client_raintegration_set_write_memory_function(rc_client_t* client, rc_client_raintegration_write_memory_func_t handler); ++RC_EXPORT void RC_CCONV rc_client_raintegration_set_get_game_name_function(rc_client_t* client, rc_client_raintegration_get_game_name_func_t handler); ++RC_EXPORT void RC_CCONV rc_client_raintegration_set_console_id(rc_client_t* client, uint32_t console_id); ++RC_EXPORT int RC_CCONV rc_client_raintegration_has_modifications(const rc_client_t* client); ++ ++RC_EXPORT void RC_CCONV rc_client_raintegration_set_event_handler(rc_client_t* client, ++ rc_client_raintegration_event_handler_t handler); ++ ++RC_EXPORT int RC_CCONV rc_client_raintegration_get_achievement_state(const rc_client_t* client, uint32_t achievement_id); ++ ++#endif /* RC_CLIENT_SUPPORTS_RAINTEGRATION */ ++ ++RC_END_C_DECLS ++ ++#endif /* RC_CLIENT_RAINTEGRATION_H */ +diff -rupbN melonDS.orig/src/rcheevos/include/rc_consoles.h melonDS.ra/src/rcheevos/include/rc_consoles.h +--- melonDS.orig/src/rcheevos/include/rc_consoles.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/include/rc_consoles.h 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,138 @@ ++#ifndef RC_CONSOLES_H ++#define RC_CONSOLES_H ++ ++#include "rc_export.h" ++ ++#include ++ ++RC_BEGIN_C_DECLS ++ ++/*****************************************************************************\ ++| Console identifiers | ++\*****************************************************************************/ ++ ++enum { ++ RC_CONSOLE_UNKNOWN = 0, ++ RC_CONSOLE_MEGA_DRIVE = 1, ++ RC_CONSOLE_NINTENDO_64 = 2, ++ RC_CONSOLE_SUPER_NINTENDO = 3, ++ RC_CONSOLE_GAMEBOY = 4, ++ RC_CONSOLE_GAMEBOY_ADVANCE = 5, ++ RC_CONSOLE_GAMEBOY_COLOR = 6, ++ RC_CONSOLE_NINTENDO = 7, ++ RC_CONSOLE_PC_ENGINE = 8, ++ RC_CONSOLE_SEGA_CD = 9, ++ RC_CONSOLE_SEGA_32X = 10, ++ RC_CONSOLE_MASTER_SYSTEM = 11, ++ RC_CONSOLE_PLAYSTATION = 12, ++ RC_CONSOLE_ATARI_LYNX = 13, ++ RC_CONSOLE_NEOGEO_POCKET = 14, ++ RC_CONSOLE_GAME_GEAR = 15, ++ RC_CONSOLE_GAMECUBE = 16, ++ RC_CONSOLE_ATARI_JAGUAR = 17, ++ RC_CONSOLE_NINTENDO_DS = 18, ++ RC_CONSOLE_WII = 19, ++ RC_CONSOLE_WII_U = 20, ++ RC_CONSOLE_PLAYSTATION_2 = 21, ++ RC_CONSOLE_XBOX = 22, ++ RC_CONSOLE_MAGNAVOX_ODYSSEY2 = 23, ++ RC_CONSOLE_POKEMON_MINI = 24, ++ RC_CONSOLE_ATARI_2600 = 25, ++ RC_CONSOLE_MS_DOS = 26, ++ RC_CONSOLE_ARCADE = 27, ++ RC_CONSOLE_VIRTUAL_BOY = 28, ++ RC_CONSOLE_MSX = 29, ++ RC_CONSOLE_COMMODORE_64 = 30, ++ RC_CONSOLE_ZX81 = 31, ++ RC_CONSOLE_ORIC = 32, ++ RC_CONSOLE_SG1000 = 33, ++ RC_CONSOLE_VIC20 = 34, ++ RC_CONSOLE_AMIGA = 35, ++ RC_CONSOLE_ATARI_ST = 36, ++ RC_CONSOLE_AMSTRAD_PC = 37, ++ RC_CONSOLE_APPLE_II = 38, ++ RC_CONSOLE_SATURN = 39, ++ RC_CONSOLE_DREAMCAST = 40, ++ RC_CONSOLE_PSP = 41, ++ RC_CONSOLE_CDI = 42, ++ RC_CONSOLE_3DO = 43, ++ RC_CONSOLE_COLECOVISION = 44, ++ RC_CONSOLE_INTELLIVISION = 45, ++ RC_CONSOLE_VECTREX = 46, ++ RC_CONSOLE_PC8800 = 47, ++ RC_CONSOLE_PC9800 = 48, ++ RC_CONSOLE_PCFX = 49, ++ RC_CONSOLE_ATARI_5200 = 50, ++ RC_CONSOLE_ATARI_7800 = 51, ++ RC_CONSOLE_X68K = 52, ++ RC_CONSOLE_WONDERSWAN = 53, ++ RC_CONSOLE_CASSETTEVISION = 54, ++ RC_CONSOLE_SUPER_CASSETTEVISION = 55, ++ RC_CONSOLE_NEO_GEO_CD = 56, ++ RC_CONSOLE_FAIRCHILD_CHANNEL_F = 57, ++ RC_CONSOLE_FM_TOWNS = 58, ++ RC_CONSOLE_ZX_SPECTRUM = 59, ++ RC_CONSOLE_GAME_AND_WATCH = 60, ++ RC_CONSOLE_NOKIA_NGAGE = 61, ++ RC_CONSOLE_NINTENDO_3DS = 62, ++ RC_CONSOLE_SUPERVISION = 63, ++ RC_CONSOLE_SHARPX1 = 64, ++ RC_CONSOLE_TIC80 = 65, ++ RC_CONSOLE_THOMSONTO8 = 66, ++ RC_CONSOLE_PC6000 = 67, ++ RC_CONSOLE_PICO = 68, ++ RC_CONSOLE_MEGADUCK = 69, ++ RC_CONSOLE_ZEEBO = 70, ++ RC_CONSOLE_ARDUBOY = 71, ++ RC_CONSOLE_WASM4 = 72, ++ RC_CONSOLE_ARCADIA_2001 = 73, ++ RC_CONSOLE_INTERTON_VC_4000 = 74, ++ RC_CONSOLE_ELEKTOR_TV_GAMES_COMPUTER = 75, ++ RC_CONSOLE_PC_ENGINE_CD = 76, ++ RC_CONSOLE_ATARI_JAGUAR_CD = 77, ++ RC_CONSOLE_NINTENDO_DSI = 78, ++ RC_CONSOLE_TI83 = 79, ++ RC_CONSOLE_UZEBOX = 80, ++ RC_CONSOLE_FAMICOM_DISK_SYSTEM = 81, ++ ++ RC_CONSOLE_HUBS = 100, ++ RC_CONSOLE_EVENTS = 101, ++ RC_CONSOLE_STANDALONE = 102 ++}; ++ ++RC_EXPORT const char* RC_CCONV rc_console_name(uint32_t console_id); ++ ++/*****************************************************************************\ ++| Memory mapping | ++\*****************************************************************************/ ++ ++enum { ++ RC_MEMORY_TYPE_SYSTEM_RAM, /* normal system memory */ ++ RC_MEMORY_TYPE_SAVE_RAM, /* memory that persists between sessions */ ++ RC_MEMORY_TYPE_VIDEO_RAM, /* memory reserved for graphical processing */ ++ RC_MEMORY_TYPE_READONLY, /* memory that maps to read only data */ ++ RC_MEMORY_TYPE_HARDWARE_CONTROLLER, /* memory for interacting with system components */ ++ RC_MEMORY_TYPE_VIRTUAL_RAM, /* secondary address space that maps to real memory in system RAM */ ++ RC_MEMORY_TYPE_UNUSED /* these addresses don't really exist */ ++}; ++ ++typedef struct rc_memory_region_t { ++ uint32_t start_address; /* first address of block as queried by RetroAchievements */ ++ uint32_t end_address; /* last address of block as queried by RetroAchievements */ ++ uint32_t real_address; /* real address for first address of block */ ++ uint8_t type; /* RC_MEMORY_TYPE_ for block */ ++ const char* description; /* short description of block */ ++} ++rc_memory_region_t; ++ ++typedef struct rc_memory_regions_t { ++ const rc_memory_region_t* region; ++ uint32_t num_regions; ++} ++rc_memory_regions_t; ++ ++RC_EXPORT const rc_memory_regions_t* RC_CCONV rc_console_memory_regions(uint32_t console_id); ++ ++RC_END_C_DECLS ++ ++#endif /* RC_CONSOLES_H */ +diff -rupbN melonDS.orig/src/rcheevos/include/rc_error.h melonDS.ra/src/rcheevos/include/rc_error.h +--- melonDS.orig/src/rcheevos/include/rc_error.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/include/rc_error.h 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,59 @@ ++#ifndef RC_ERROR_H ++#define RC_ERROR_H ++ ++#include "rc_export.h" ++ ++RC_BEGIN_C_DECLS ++ ++/*****************************************************************************\ ++| Return values | ++\*****************************************************************************/ ++ ++enum { ++ RC_OK = 0, ++ RC_INVALID_FUNC_OPERAND = -1, ++ RC_INVALID_MEMORY_OPERAND = -2, ++ RC_INVALID_CONST_OPERAND = -3, ++ RC_INVALID_FP_OPERAND = -4, ++ RC_INVALID_CONDITION_TYPE = -5, ++ RC_INVALID_OPERATOR = -6, ++ RC_INVALID_REQUIRED_HITS = -7, ++ RC_DUPLICATED_START = -8, ++ RC_DUPLICATED_CANCEL = -9, ++ RC_DUPLICATED_SUBMIT = -10, ++ RC_DUPLICATED_VALUE = -11, ++ RC_DUPLICATED_PROGRESS = -12, ++ RC_MISSING_START = -13, ++ RC_MISSING_CANCEL = -14, ++ RC_MISSING_SUBMIT = -15, ++ RC_MISSING_VALUE = -16, ++ RC_INVALID_LBOARD_FIELD = -17, ++ RC_MISSING_DISPLAY_STRING = -18, ++ RC_OUT_OF_MEMORY = -19, ++ RC_INVALID_VALUE_FLAG = -20, ++ RC_MISSING_VALUE_MEASURED = -21, ++ RC_MULTIPLE_MEASURED = -22, ++ RC_INVALID_MEASURED_TARGET = -23, ++ RC_INVALID_COMPARISON = -24, ++ RC_INVALID_STATE = -25, ++ RC_INVALID_JSON = -26, ++ RC_API_FAILURE = -27, ++ RC_LOGIN_REQUIRED = -28, ++ RC_NO_GAME_LOADED = -29, ++ RC_HARDCORE_DISABLED = -30, ++ RC_ABORTED = -31, ++ RC_NO_RESPONSE = -32, ++ RC_ACCESS_DENIED = -33, ++ RC_INVALID_CREDENTIALS = -34, ++ RC_EXPIRED_TOKEN = -35, ++ RC_INSUFFICIENT_BUFFER = -36, ++ RC_INVALID_VARIABLE_NAME = -37, ++ RC_UNKNOWN_VARIABLE_NAME = -38, ++ RC_NOT_FOUND = -39 ++}; ++ ++RC_EXPORT const char* RC_CCONV rc_error_str(int ret); ++ ++RC_END_C_DECLS ++ ++#endif /* RC_ERROR_H */ +diff -rupbN melonDS.orig/src/rcheevos/include/rc_export.h melonDS.ra/src/rcheevos/include/rc_export.h +--- melonDS.orig/src/rcheevos/include/rc_export.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/include/rc_export.h 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,100 @@ ++#ifndef RC_EXPORT_H ++#define RC_EXPORT_H ++ ++/* These macros control how callbacks and public functions are defined */ ++ ++/* RC_SHARED should be defined when building rcheevos as a shared library (e.g. dll/dylib/so). External code should not define this macro. */ ++/* RC_STATIC should be defined when building rcheevos as a static library. External code should also define this macro. */ ++/* RC_IMPORT should be defined for external code using rcheevos as a shared library. */ ++ ++/* For compatibility, if none of these three macros are defined, then the build is assumed to be RC_STATIC */ ++ ++#if !defined(RC_SHARED) && !defined(RC_STATIC) && !defined(RC_IMPORT) ++ #define RC_STATIC ++#endif ++ ++#if (defined(RC_SHARED) && defined(RC_STATIC)) || (defined(RC_SHARED) && defined(RC_IMPORT)) || (defined(RC_STATIC) && defined(RC_IMPORT)) ++ #error RC_SHARED, RC_STATIC, and RC_IMPORT are mutually exclusive ++#endif ++ ++/* RC_BEGIN_C_DECLS and RC_END_C_DECLS should be used for all headers, to enforce C linkage and the C calling convention */ ++/* RC_BEGIN_C_DECLS should be placed after #include's and before header declarations */ ++/* RC_END_C_DECLS should be placed after header declarations */ ++ ++/* example usage ++ * ++ * #ifndef RC_HEADER_H ++ * #define RC_HEADER_H ++ * ++ * #include ++ * ++ * RC_BEGIN_C_DECLS ++ * ++ * uint8_t rc_function(void); ++ * ++ * RC_END_C_DECLS ++ * ++ * #endif ++ */ ++ ++#if defined(__cplusplus) && !defined(CXX_BUILD) ++ #define RC_BEGIN_C_DECLS extern "C" { ++ #define RC_END_C_DECLS } ++#else ++ #define RC_BEGIN_C_DECLS ++ #define RC_END_C_DECLS ++#endif ++ ++/* RC_CCONV should be used for public functions and callbacks, to enforce the cdecl calling convention, if applicable */ ++/* RC_CCONV should be placed after the return type, and between the ( and * for callbacks */ ++ ++/* example usage */ ++/* void RC_CCONV rc_function(void) */ ++/* void (RC_CCONV *rc_callback)(void) */ ++ ++#if defined(_WIN32) ++ /* Windows compilers will ignore __cdecl when not applicable */ ++ #define RC_CCONV __cdecl ++#elif defined(__GNUC__) && defined(__i386__) ++ /* GNU C compilers will warn if cdecl is defined on an unsupported platform */ ++ #define RC_CCONV __attribute__((cdecl)) ++#else ++ #define RC_CCONV ++#endif ++ ++/* RC_EXPORT should be used for public functions */ ++/* RC_EXPORT will provide necessary hints for shared library usage, if applicable */ ++/* RC_EXPORT should be placed before the return type */ ++ ++/* example usage */ ++/* RC_EXPORT void rc_function(void) */ ++ ++#ifdef RC_SHARED ++ #if defined(_WIN32) ++ #define RC_EXPORT __declspec(dllexport) ++ #elif defined(__GNUC__) && __GNUC__ >= 4 ++ #define RC_EXPORT __attribute__((visibility("default"))) ++ #else ++ #define RC_EXPORT ++ #endif ++#endif ++ ++#ifdef RC_IMPORT ++ #if defined(_WIN32) ++ #define RC_EXPORT __declspec(dllimport) ++ #elif defined(__GNUC__) && __GNUC__ >= 4 ++ #define RC_EXPORT __attribute__((visibility("default"))) ++ #else ++ #define RC_EXPORT ++ #endif ++#endif ++ ++#ifdef RC_STATIC ++ #if defined(__GNUC__) && __GNUC__ >= 4 ++ #define RC_EXPORT __attribute__((visibility("default"))) ++ #else ++ #define RC_EXPORT ++ #endif ++#endif ++ ++#endif /* RC_EXPORT_H */ +diff -rupbN melonDS.orig/src/rcheevos/include/rc_hash.h melonDS.ra/src/rcheevos/include/rc_hash.h +--- melonDS.orig/src/rcheevos/include/rc_hash.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/include/rc_hash.h 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,200 @@ ++#ifndef RC_HASH_H ++#define RC_HASH_H ++ ++#include ++#include ++#include ++ ++#include "rc_consoles.h" ++ ++RC_BEGIN_C_DECLS ++ ++ struct rc_hash_iterator; ++ ++ /* ===================================================== */ ++ ++ typedef void (RC_CCONV *rc_hash_message_callback_deprecated)(const char*); ++ ++ /* specifies a function to call when an error occurs to display the error message */ ++ /* [deprecated] set callbacks in rc_hash_iterator_t */ ++ RC_EXPORT void RC_CCONV rc_hash_init_error_message_callback(rc_hash_message_callback_deprecated callback); ++ ++ /* specifies a function to call for verbose logging */ ++ /* [deprecated] set callbacks in rc_hash_iterator_t */ ++ RC_EXPORT void rc_hash_init_verbose_message_callback(rc_hash_message_callback_deprecated callback); ++ ++ /* ===================================================== */ ++ ++ /* opens a file */ ++ typedef void* (RC_CCONV *rc_hash_filereader_open_file_handler)(const char* path_utf8); ++ ++ /* moves the file pointer - standard fseek parameters */ ++ typedef void (RC_CCONV *rc_hash_filereader_seek_handler)(void* file_handle, int64_t offset, int origin); ++ ++ /* locates the file pointer */ ++ typedef int64_t (RC_CCONV *rc_hash_filereader_tell_handler)(void* file_handle); ++ ++ /* reads the specified number of bytes from the file starting at the read pointer. ++ * returns the number of bytes actually read. ++ */ ++ typedef size_t (RC_CCONV *rc_hash_filereader_read_handler)(void* file_handle, void* buffer, size_t requested_bytes); ++ ++ /* closes the file */ ++ typedef void (RC_CCONV *rc_hash_filereader_close_file_handler)(void* file_handle); ++ ++ typedef struct rc_hash_filereader ++ { ++ rc_hash_filereader_open_file_handler open; ++ rc_hash_filereader_seek_handler seek; ++ rc_hash_filereader_tell_handler tell; ++ rc_hash_filereader_read_handler read; ++ rc_hash_filereader_close_file_handler close; ++ } rc_hash_filereader_t; ++ ++ /* [deprecated] set callbacks in rc_hash_iterator_t */ ++ RC_EXPORT void RC_CCONV rc_hash_init_custom_filereader(struct rc_hash_filereader* reader); ++ ++ /* ===================================================== */ ++ ++#ifndef RC_HASH_NO_DISC ++ ++ #define RC_HASH_CDTRACK_FIRST_DATA ((uint32_t)-1) /* the first data track (skip audio tracks) */ ++ #define RC_HASH_CDTRACK_LAST ((uint32_t)-2) /* the last data/audio track */ ++ #define RC_HASH_CDTRACK_LARGEST ((uint32_t)-3) /* the largest data/audio track */ ++ #define RC_HASH_CDTRACK_FIRST_OF_SECOND_SESSION ((uint32_t)-4) /* the first data/audio track of the second session */ ++ ++ /* opens a track from the specified file. see the RC_HASH_CDTRACK_ defines for special tracks. ++ * returns a handle to be passed to the other functions, or NULL if the track could not be opened. ++ */ ++ typedef void* (RC_CCONV *rc_hash_cdreader_open_track_handler)(const char* path, uint32_t track); ++ typedef void* (RC_CCONV* rc_hash_cdreader_open_track_iterator_handler)(const char* path, uint32_t track, const struct rc_hash_iterator* iterator); ++ ++ /* attempts to read the specified number of bytes from the file starting at the specified absolute sector. ++ * returns the number of bytes actually read. ++ */ ++ typedef size_t (RC_CCONV *rc_hash_cdreader_read_sector_handler)(void* track_handle, uint32_t sector, void* buffer, size_t requested_bytes); ++ ++ /* closes the track handle */ ++ typedef void (RC_CCONV *rc_hash_cdreader_close_track_handler)(void* track_handle); ++ ++ /* gets the absolute sector index for the first sector of a track */ ++ typedef uint32_t(RC_CCONV *rc_hash_cdreader_first_track_sector_handler)(void* track_handle); ++ ++ typedef struct rc_hash_cdreader ++ { ++ rc_hash_cdreader_open_track_handler open_track; ++ rc_hash_cdreader_read_sector_handler read_sector; ++ rc_hash_cdreader_close_track_handler close_track; ++ rc_hash_cdreader_first_track_sector_handler first_track_sector; ++ rc_hash_cdreader_open_track_iterator_handler open_track_iterator; ++ } rc_hash_cdreader_t; ++ ++ RC_EXPORT void RC_CCONV rc_hash_get_default_cdreader(struct rc_hash_cdreader* cdreader); ++ /* [deprecated] don't set callbacks in rc_hash_iterator_t */ ++ RC_EXPORT void RC_CCONV rc_hash_init_default_cdreader(void); ++ /* [deprecated] set callbacks in rc_hash_iterator_t */ ++ RC_EXPORT void RC_CCONV rc_hash_init_custom_cdreader(struct rc_hash_cdreader* reader); ++ ++#endif /* RC_HASH_NO_DISC */ ++ ++#ifndef RC_HASH_NO_ENCRYPTED ++ ++ /* specifies a function called to obtain a 3DS CIA decryption normal key. ++ * this key would be derived from slot0x3DKeyX and the common key specified by the passed index. ++ * the normal key should be written in big endian format ++ * returns non-zero on success, or zero on failure. ++ */ ++ typedef int (RC_CCONV *rc_hash_3ds_get_cia_normal_key_func)(uint8_t common_key_index, uint8_t out_normal_key[16]); ++ /* [deprecated] set callbacks in rc_hash_iterator_t */ ++ RC_EXPORT void RC_CCONV rc_hash_init_3ds_get_cia_normal_key_func(rc_hash_3ds_get_cia_normal_key_func func); ++ ++ /* specifies a function called to obtain 3DS NCCH decryption normal keys. ++ * the primary key will always use slot0x2CKeyX and the passed primary KeyY. ++ * the secondary key will use the KeyX slot passed ++ * the secondary KeyY will be identical to the primary keyY if the passed program id is NULL ++ * if the program id is not null, then the secondary KeyY will be obtained with "seed crypto" ++ * with "seed crypto" the 8 byte program id can be used to obtain a 16 byte "seed" within the seeddb.bin firmware file ++ * the primary KeyY then the seed will then be hashed with SHA256, and the upper 16 bytes of the digest will be the secondary KeyY used ++ * the normal keys should be written in big endian format ++ * returns non-zero on success, or zero on failure. ++ */ ++ typedef int (RC_CCONV *rc_hash_3ds_get_ncch_normal_keys_func)(uint8_t primary_key_y[16], uint8_t secondary_key_x_slot, uint8_t* optional_program_id, ++ uint8_t out_primary_key[16], uint8_t out_secondary_key[16]); ++ /* [deprecated] set callbacks in rc_hash_iterator_t */ ++ RC_EXPORT void RC_CCONV rc_hash_init_3ds_get_ncch_normal_keys_func(rc_hash_3ds_get_ncch_normal_keys_func func); ++ ++#endif /* RC_HASH_NO_ENCRYPTED */ ++ ++/* ===================================================== */ ++ ++typedef void (RC_CCONV* rc_hash_message_callback_func)(const char*, const struct rc_hash_iterator* iterator); ++ ++typedef struct rc_hash_callbacks { ++ rc_hash_message_callback_func verbose_message; ++ rc_hash_message_callback_func error_message; ++ ++ rc_hash_filereader_t filereader; ++#ifndef RC_HASH_NO_DISC ++ rc_hash_cdreader_t cdreader; ++#endif ++ ++#ifndef RC_HASH_NO_ENCRYPTED ++ struct rc_hash_encryption_callbacks { ++ rc_hash_3ds_get_cia_normal_key_func get_3ds_cia_normal_key; ++ rc_hash_3ds_get_ncch_normal_keys_func get_3ds_ncch_normal_keys; ++ } encryption; ++#endif ++} rc_hash_callbacks_t; ++ ++/* data for rc_hash_iterate ++ */ ++typedef struct rc_hash_iterator { ++ const uint8_t* buffer; ++ size_t buffer_size; ++ uint8_t consoles[12]; ++ int index; ++ const char* path; ++ void* userdata; ++ ++ rc_hash_callbacks_t callbacks; ++} rc_hash_iterator_t; ++ ++/* initializes a rc_hash_iterator ++ * - path must be provided ++ * - if buffer and buffer_size are provided, path may be a filename (i.e. for something extracted from a zip file) ++ */ ++RC_EXPORT void RC_CCONV rc_hash_initialize_iterator(rc_hash_iterator_t* iterator, const char* path, const uint8_t* buffer, size_t buffer_size); ++ ++/* releases resources associated to a rc_hash_iterator ++ */ ++RC_EXPORT void RC_CCONV rc_hash_destroy_iterator(rc_hash_iterator_t* iterator); ++ ++/* generates the next hash for the data in the rc_hash_iterator. ++ * returns non-zero if a hash was generated, or zero if no more hashes can be generated for the data. ++ */ ++RC_EXPORT int RC_CCONV rc_hash_iterate(char hash[33], rc_hash_iterator_t* iterator); ++ ++/* generates a hash for the data in the rc_hash_iterator. ++ * returns non-zero if a hash was generated. ++ */ ++RC_EXPORT int RC_CCONV rc_hash_generate(char hash[33], uint32_t console_id, const rc_hash_iterator_t* iterator); ++ ++/* ===================================================== */ ++ ++/* generates a hash from a block of memory. ++ * returns non-zero on success, or zero on failure. ++ */ ++/* [deprecated] use rc_hash_generate instead */ ++RC_EXPORT int RC_CCONV rc_hash_generate_from_buffer(char hash[33], uint32_t console_id, const uint8_t* buffer, size_t buffer_size); ++ ++/* generates a hash from a file. ++ * returns non-zero on success, or zero on failure. ++ */ ++/* [deprecated] use rc_hash_generate instead */ ++RC_EXPORT int RC_CCONV rc_hash_generate_from_file(char hash[33], uint32_t console_id, const char* path); ++ ++/* ===================================================== */ ++ ++RC_END_C_DECLS ++ ++#endif /* RC_HASH_H */ +diff -rupbN melonDS.orig/src/rcheevos/include/rc_runtime.h melonDS.ra/src/rcheevos/include/rc_runtime.h +--- melonDS.orig/src/rcheevos/include/rc_runtime.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/include/rc_runtime.h 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,148 @@ ++#ifndef RC_RUNTIME_H ++#define RC_RUNTIME_H ++ ++#include "rc_error.h" ++ ++#include ++#include ++ ++RC_BEGIN_C_DECLS ++ ++/*****************************************************************************\ ++| Forward Declarations (defined in rc_runtime_types.h) | ++\*****************************************************************************/ ++ ++#ifndef RC_RUNTIME_TYPES_H /* prevents pedantic redefinition error */ ++ ++typedef struct rc_trigger_t rc_trigger_t; ++typedef struct rc_lboard_t rc_lboard_t; ++typedef struct rc_richpresence_t rc_richpresence_t; ++typedef struct rc_memref_t rc_memref_t; ++typedef struct rc_value_t rc_value_t; ++ ++#endif ++ ++/*****************************************************************************\ ++| Callbacks | ++\*****************************************************************************/ ++ ++/** ++ * Callback used to read num_bytes bytes from memory starting at address. If ++ * num_bytes is greater than 1, the value is read in little-endian from ++ * memory. ++ */ ++typedef uint32_t(RC_CCONV *rc_runtime_peek_t)(uint32_t address, uint32_t num_bytes, void* ud); ++ ++/*****************************************************************************\ ++| Runtime | ++\*****************************************************************************/ ++ ++typedef struct rc_runtime_trigger_t { ++ uint32_t id; ++ rc_trigger_t* trigger; ++ void* buffer; ++ rc_memref_t* invalid_memref; ++ uint8_t md5[16]; ++ int32_t serialized_size; ++} ++rc_runtime_trigger_t; ++ ++typedef struct rc_runtime_lboard_t { ++ uint32_t id; ++ int32_t value; ++ rc_lboard_t* lboard; ++ void* buffer; ++ rc_memref_t* invalid_memref; ++ uint8_t md5[16]; ++ uint32_t serialized_size; ++} ++rc_runtime_lboard_t; ++ ++typedef struct rc_runtime_richpresence_t { ++ rc_richpresence_t* richpresence; ++ void* buffer; ++ uint8_t md5[16]; ++} ++rc_runtime_richpresence_t; ++ ++typedef struct rc_runtime_t { ++ rc_runtime_trigger_t* triggers; ++ uint32_t trigger_count; ++ uint32_t trigger_capacity; ++ ++ rc_runtime_lboard_t* lboards; ++ uint32_t lboard_count; ++ uint32_t lboard_capacity; ++ ++ rc_runtime_richpresence_t* richpresence; ++ ++ struct rc_memrefs_t* memrefs; ++ ++ uint8_t owns_self; ++} ++rc_runtime_t; ++ ++RC_EXPORT rc_runtime_t* RC_CCONV rc_runtime_alloc(void); ++RC_EXPORT void RC_CCONV rc_runtime_init(rc_runtime_t* runtime); ++RC_EXPORT void RC_CCONV rc_runtime_destroy(rc_runtime_t* runtime); ++ ++RC_EXPORT int RC_CCONV rc_runtime_activate_achievement(rc_runtime_t* runtime, uint32_t id, const char* memaddr, void* unused_L, int unused_funcs_idx); ++RC_EXPORT void RC_CCONV rc_runtime_deactivate_achievement(rc_runtime_t* runtime, uint32_t id); ++RC_EXPORT rc_trigger_t* RC_CCONV rc_runtime_get_achievement(const rc_runtime_t* runtime, uint32_t id); ++RC_EXPORT int RC_CCONV rc_runtime_get_achievement_measured(const rc_runtime_t* runtime, uint32_t id, unsigned* measured_value, unsigned* measured_target); ++RC_EXPORT int RC_CCONV rc_runtime_format_achievement_measured(const rc_runtime_t* runtime, uint32_t id, char *buffer, size_t buffer_size); ++ ++RC_EXPORT int RC_CCONV rc_runtime_activate_lboard(rc_runtime_t* runtime, uint32_t id, const char* memaddr, void* unused_L, int unused_funcs_idx); ++RC_EXPORT void RC_CCONV rc_runtime_deactivate_lboard(rc_runtime_t* runtime, uint32_t id); ++RC_EXPORT rc_lboard_t* RC_CCONV rc_runtime_get_lboard(const rc_runtime_t* runtime, uint32_t id); ++RC_EXPORT int RC_CCONV rc_runtime_format_lboard_value(char* buffer, int size, int32_t value, int format); ++ ++ ++RC_EXPORT int RC_CCONV rc_runtime_activate_richpresence(rc_runtime_t* runtime, const char* script, void* unused_L, int unused_funcs_idx); ++RC_EXPORT int RC_CCONV rc_runtime_get_richpresence(const rc_runtime_t* runtime, char* buffer, size_t buffersize, rc_runtime_peek_t peek, void* peek_ud, void* unused_L); ++ ++enum { ++ RC_RUNTIME_EVENT_ACHIEVEMENT_ACTIVATED, /* from WAITING, PAUSED, or PRIMED to ACTIVE */ ++ RC_RUNTIME_EVENT_ACHIEVEMENT_PAUSED, ++ RC_RUNTIME_EVENT_ACHIEVEMENT_RESET, ++ RC_RUNTIME_EVENT_ACHIEVEMENT_TRIGGERED, ++ RC_RUNTIME_EVENT_ACHIEVEMENT_PRIMED, ++ RC_RUNTIME_EVENT_LBOARD_STARTED, ++ RC_RUNTIME_EVENT_LBOARD_CANCELED, ++ RC_RUNTIME_EVENT_LBOARD_UPDATED, ++ RC_RUNTIME_EVENT_LBOARD_TRIGGERED, ++ RC_RUNTIME_EVENT_ACHIEVEMENT_DISABLED, ++ RC_RUNTIME_EVENT_LBOARD_DISABLED, ++ RC_RUNTIME_EVENT_ACHIEVEMENT_UNPRIMED, ++ RC_RUNTIME_EVENT_ACHIEVEMENT_PROGRESS_UPDATED ++}; ++ ++typedef struct rc_runtime_event_t { ++ uint32_t id; ++ int32_t value; ++ uint8_t type; ++} ++rc_runtime_event_t; ++ ++typedef void (RC_CCONV *rc_runtime_event_handler_t)(const rc_runtime_event_t* runtime_event); ++ ++RC_EXPORT void RC_CCONV rc_runtime_do_frame(rc_runtime_t* runtime, rc_runtime_event_handler_t event_handler, rc_runtime_peek_t peek, void* ud, void* unused_L); ++RC_EXPORT void RC_CCONV rc_runtime_reset(rc_runtime_t* runtime); ++ ++typedef int (RC_CCONV *rc_runtime_validate_address_t)(uint32_t address); ++RC_EXPORT void RC_CCONV rc_runtime_validate_addresses(rc_runtime_t* runtime, rc_runtime_event_handler_t event_handler, rc_runtime_validate_address_t validate_handler); ++RC_EXPORT void RC_CCONV rc_runtime_invalidate_address(rc_runtime_t* runtime, uint32_t address); ++ ++RC_EXPORT uint32_t RC_CCONV rc_runtime_progress_size(const rc_runtime_t* runtime, void* unused_L); ++ ++/* [deprecated] use rc_runtime_serialize_progress_sized instead */ ++RC_EXPORT int RC_CCONV rc_runtime_serialize_progress(void* buffer, const rc_runtime_t* runtime, void* unused_L); ++RC_EXPORT int RC_CCONV rc_runtime_serialize_progress_sized(uint8_t* buffer, uint32_t buffer_size, const rc_runtime_t* runtime, void* unused_L); ++ ++/* [deprecated] use rc_runtime_deserialize_progress_sized instead */ ++RC_EXPORT int RC_CCONV rc_runtime_deserialize_progress(rc_runtime_t* runtime, const uint8_t* serialized, void* unused_L); ++RC_EXPORT int RC_CCONV rc_runtime_deserialize_progress_sized(rc_runtime_t* runtime, const uint8_t* serialized, uint32_t serialized_size, void* unused_L); ++ ++RC_END_C_DECLS ++ ++#endif /* RC_RUNTIME_H */ +diff -rupbN melonDS.orig/src/rcheevos/include/rc_runtime_types.h melonDS.ra/src/rcheevos/include/rc_runtime_types.h +--- melonDS.orig/src/rcheevos/include/rc_runtime_types.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/include/rc_runtime_types.h 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,452 @@ ++#ifndef RC_RUNTIME_TYPES_H ++#define RC_RUNTIME_TYPES_H ++ ++#include "rc_error.h" ++ ++#include ++#include ++ ++RC_BEGIN_C_DECLS ++ ++#ifndef RC_RUNTIME_H /* prevents pedantic redefiniton error */ ++ ++typedef struct rc_trigger_t rc_trigger_t; ++typedef struct rc_lboard_t rc_lboard_t; ++typedef struct rc_richpresence_t rc_richpresence_t; ++typedef struct rc_memref_t rc_memref_t; ++typedef struct rc_value_t rc_value_t; ++ ++#endif ++ ++/*****************************************************************************\ ++| Callbacks | ++\*****************************************************************************/ ++ ++/** ++ * Callback used to read num_bytes bytes from memory starting at address. If ++ * num_bytes is greater than 1, the value is read in little-endian from ++ * memory. ++ */ ++typedef uint32_t(RC_CCONV* rc_peek_t)(uint32_t address, uint32_t num_bytes, void* ud); ++ ++/*****************************************************************************\ ++| Memory References | ++\*****************************************************************************/ ++ ++/* Sizes. */ ++enum { ++ RC_MEMSIZE_8_BITS, ++ RC_MEMSIZE_16_BITS, ++ RC_MEMSIZE_24_BITS, ++ RC_MEMSIZE_32_BITS, ++ RC_MEMSIZE_LOW, ++ RC_MEMSIZE_HIGH, ++ RC_MEMSIZE_BIT_0, ++ RC_MEMSIZE_BIT_1, ++ RC_MEMSIZE_BIT_2, ++ RC_MEMSIZE_BIT_3, ++ RC_MEMSIZE_BIT_4, ++ RC_MEMSIZE_BIT_5, ++ RC_MEMSIZE_BIT_6, ++ RC_MEMSIZE_BIT_7, ++ RC_MEMSIZE_BITCOUNT, ++ RC_MEMSIZE_16_BITS_BE, ++ RC_MEMSIZE_24_BITS_BE, ++ RC_MEMSIZE_32_BITS_BE, ++ RC_MEMSIZE_FLOAT, ++ RC_MEMSIZE_MBF32, ++ RC_MEMSIZE_MBF32_LE, ++ RC_MEMSIZE_FLOAT_BE, ++ RC_MEMSIZE_DOUBLE32, ++ RC_MEMSIZE_DOUBLE32_BE, ++ RC_MEMSIZE_VARIABLE ++}; ++ ++typedef struct rc_memref_value_t { ++ /* The current value of this memory reference. */ ++ uint32_t value; ++ /* The last differing value of this memory reference. */ ++ uint32_t prior; ++ ++ /* The size of the value. (RC_MEMSIZE_*) */ ++ uint8_t size; ++ /* True if the value changed this frame. */ ++ uint8_t changed; ++ /* The value type of the value. (RC_VALUE_TYPE_*) */ ++ uint8_t type; ++ /* The type of memref (RC_MEMREF_TYPE_*) */ ++ uint8_t memref_type; ++} ++rc_memref_value_t; ++ ++struct rc_memref_t { ++ /* The current value at the specified memory address. */ ++ rc_memref_value_t value; ++ ++ /* The memory address of this variable. */ ++ uint32_t address; ++}; ++ ++/*****************************************************************************\ ++| Operands | ++\*****************************************************************************/ ++ ++/* types */ ++enum { ++ RC_OPERAND_ADDRESS, /* The value of a live address in RAM. */ ++ RC_OPERAND_DELTA, /* The value last known at this address. */ ++ RC_OPERAND_CONST, /* A 32-bit unsigned integer. */ ++ RC_OPERAND_FP, /* A floating point value. */ ++ RC_OPERAND_FUNC, /* A function that provides the value. */ ++ RC_OPERAND_PRIOR, /* The last differing value at this address. */ ++ RC_OPERAND_BCD, /* The BCD-decoded value of a live address in RAM. */ ++ RC_OPERAND_INVERTED, /* The twos-complement value of a live address in RAM. */ ++ RC_OPERAND_RECALL /* The value captured by the last RC_CONDITION_REMEMBER condition */ ++}; ++ ++typedef struct rc_operand_t { ++ union { ++ /* A value read from memory. */ ++ rc_memref_t* memref; ++ ++ /* An integer value. */ ++ uint32_t num; ++ ++ /* A floating point value. */ ++ double dbl; ++ } value; ++ ++ /* specifies which member of the value union is being used (RC_OPERAND_*) */ ++ uint8_t type; ++ ++ /* the RC_MEMSIZE of the operand specified in the condition definition - memref.size may differ */ ++ uint8_t size; ++ ++ /* specifies how to read the memref for some types (RC_OPERAND_*) */ ++ uint8_t memref_access_type; ++ ++ /* if set, this operand is combining the current condition with the previous one */ ++ uint8_t is_combining; ++} ++rc_operand_t; ++ ++RC_EXPORT int RC_CCONV rc_operand_is_memref(const rc_operand_t* operand); ++ ++/*****************************************************************************\ ++| Conditions | ++\*****************************************************************************/ ++ ++/* types */ ++enum { ++ RC_CONDITION_STANDARD, /* this should always be 0 */ ++ RC_CONDITION_PAUSE_IF, ++ RC_CONDITION_RESET_IF, ++ RC_CONDITION_MEASURED_IF, ++ RC_CONDITION_TRIGGER, ++ RC_CONDITION_MEASURED, ++ RC_CONDITION_ADD_SOURCE, ++ RC_CONDITION_SUB_SOURCE, ++ RC_CONDITION_ADD_ADDRESS, ++ RC_CONDITION_REMEMBER, ++ RC_CONDITION_ADD_HITS, ++ RC_CONDITION_SUB_HITS, ++ RC_CONDITION_RESET_NEXT_IF, ++ RC_CONDITION_AND_NEXT, ++ RC_CONDITION_OR_NEXT ++}; ++ ++/* operators */ ++enum { ++ RC_OPERATOR_EQ, ++ RC_OPERATOR_LT, ++ RC_OPERATOR_LE, ++ RC_OPERATOR_GT, ++ RC_OPERATOR_GE, ++ RC_OPERATOR_NE, ++ RC_OPERATOR_NONE, ++ RC_OPERATOR_MULT, ++ RC_OPERATOR_DIV, ++ RC_OPERATOR_AND, ++ RC_OPERATOR_XOR, ++ RC_OPERATOR_MOD, ++ RC_OPERATOR_ADD, ++ RC_OPERATOR_SUB, ++ ++ RC_OPERATOR_SUB_PARENT, /* internal use */ ++ RC_OPERATOR_ADD_ACCUMULATOR, /* internal use */ ++ RC_OPERATOR_SUB_ACCUMULATOR, /* internal use */ ++ RC_OPERATOR_INDIRECT_READ /* internal use */ ++}; ++ ++typedef struct rc_condition_t rc_condition_t; ++ ++struct rc_condition_t { ++ /* The condition's operands. */ ++ rc_operand_t operand1; ++ rc_operand_t operand2; ++ ++ /* Required hits to fire this condition. */ ++ uint32_t required_hits; ++ /* Number of hits so far. */ ++ uint32_t current_hits; ++ ++ /* The next condition in the chain. */ ++ rc_condition_t* next; ++ ++ /* The type of the condition. (RC_CONDITION_*) */ ++ uint8_t type; ++ ++ /* The comparison operator to use. (RC_OPERATOR_*) */ ++ uint8_t oper; /* operator is a reserved word in C++. */ ++ ++ /* Will be non-zero if the condition evaluated true on the last check. ++ * - The lowest bit indicates whether the condition itself was true. ++ * - The second lowest bit will only ever be set on ResetIf conditions. ++ * If set, it indicates that the condition was responsible for resetting the ++ * trigger. A reset clears all hit counts, so the condition may not appear to ++ * be true just from looking at it (in which case the lower bit will be 0). ++ * Also, the condition might have only met its required_hits target though ++ * an AddHits chain which will have also been reset. ++ */ ++ uint8_t is_true; ++ ++ /* Unique identifier of optimized comparator to use. (RC_PROCESSING_COMPARE_*) */ ++ uint8_t optimized_comparator; ++}; ++ ++/*****************************************************************************\ ++| Condition sets | ++\*****************************************************************************/ ++ ++typedef struct rc_condset_t rc_condset_t; ++ ++struct rc_condset_t { ++ /* The next condition set in the chain. */ ++ rc_condset_t* next; ++ ++ /* The first condition in this condition set. Then follow ->next chain. */ ++ rc_condition_t* conditions; ++ ++ /* The number of pause conditions in this condition set. */ ++ /* The first pause condition is at "this + RC_ALIGN(sizeof(this)). */ ++ uint16_t num_pause_conditions; ++ ++ /* The number of reset conditions in this condition set. */ ++ uint16_t num_reset_conditions; ++ ++ /* The number of hittarget conditions in this condition set. */ ++ uint16_t num_hittarget_conditions; ++ ++ /* The number of non-hittarget measured conditions in this condition set. */ ++ uint16_t num_measured_conditions; ++ ++ /* The number of other conditions in this condition set. */ ++ uint16_t num_other_conditions; ++ ++ /* The number of indirect conditions in this condition set. */ ++ uint16_t num_indirect_conditions; ++ ++ /* True if any condition in the set is a pause condition. */ ++ uint8_t has_pause; /* DEPRECATED - just check num_pause_conditions != 0 */ ++ /* True if the set is currently paused. */ ++ uint8_t is_paused; ++}; ++ ++/*****************************************************************************\ ++| Trigger | ++\*****************************************************************************/ ++ ++enum { ++ RC_TRIGGER_STATE_INACTIVE, /* achievement is not being processed */ ++ RC_TRIGGER_STATE_WAITING, /* achievement cannot trigger until it has been false for at least one frame */ ++ RC_TRIGGER_STATE_ACTIVE, /* achievement is active and may trigger */ ++ RC_TRIGGER_STATE_PAUSED, /* achievement is currently paused and will not trigger */ ++ RC_TRIGGER_STATE_RESET, /* achievement hit counts were reset */ ++ RC_TRIGGER_STATE_TRIGGERED, /* achievement has triggered */ ++ RC_TRIGGER_STATE_PRIMED, /* all non-Trigger conditions are true */ ++ RC_TRIGGER_STATE_DISABLED /* achievement cannot be processed at this time */ ++}; ++ ++struct rc_trigger_t { ++ /* The main condition set. */ ++ rc_condset_t* requirement; ++ ++ /* The list of sub condition sets in this test. */ ++ rc_condset_t* alternative; ++ ++ /* The current state of the MEASURED condition. */ ++ uint32_t measured_value; ++ ++ /* The target state of the MEASURED condition */ ++ uint32_t measured_target; ++ ++ /* The current state of the trigger */ ++ uint8_t state; ++ ++ /* True if at least one condition has a non-zero hit count */ ++ uint8_t has_hits; ++ ++ /* True if the measured value should be displayed as a percentage */ ++ uint8_t measured_as_percent; ++ ++ /* True if the trigger has its own rc_memrefs_t */ ++ uint8_t has_memrefs; ++}; ++ ++RC_EXPORT int RC_CCONV rc_trigger_size(const char* memaddr); ++RC_EXPORT rc_trigger_t* RC_CCONV rc_parse_trigger(void* buffer, const char* memaddr, void* unused_L, int unused_funcs_idx); ++RC_EXPORT int RC_CCONV rc_evaluate_trigger(rc_trigger_t* trigger, rc_peek_t peek, void* ud, void* unused_L); ++RC_EXPORT int RC_CCONV rc_test_trigger(rc_trigger_t* trigger, rc_peek_t peek, void* ud, void* unused_L); ++RC_EXPORT void RC_CCONV rc_reset_trigger(rc_trigger_t* self); ++ ++/*****************************************************************************\ ++| Values | ++\*****************************************************************************/ ++ ++#define RC_VALUE_MAX_NAME_LENGTH 15 ++ ++struct rc_value_t { ++ /* The current value of the variable. */ ++ rc_memref_value_t value; ++ ++ /* True if the value has its own rc_memrefs_t */ ++ uint8_t has_memrefs; ++ ++ /* The list of possible values (traverse next chain, pick max). */ ++ rc_condset_t* conditions; ++ ++ /* The name of the variable. */ ++ const char* name; ++ ++ /* The next variable in the chain. */ ++ rc_value_t* next; ++}; ++ ++RC_EXPORT int RC_CCONV rc_value_size(const char* memaddr); ++RC_EXPORT rc_value_t* RC_CCONV rc_parse_value(void* buffer, const char* memaddr, void* unused_L, int unused_funcs_idx); ++RC_EXPORT int32_t RC_CCONV rc_evaluate_value(rc_value_t* value, rc_peek_t peek, void* ud, void* unused_L); ++ ++/*****************************************************************************\ ++| Leaderboards | ++\*****************************************************************************/ ++ ++/* Return values for rc_evaluate_lboard. */ ++enum { ++ RC_LBOARD_STATE_INACTIVE, /* leaderboard is not being processed */ ++ RC_LBOARD_STATE_WAITING, /* leaderboard cannot activate until the start condition has been false for at least one frame */ ++ RC_LBOARD_STATE_ACTIVE, /* leaderboard is active and may start */ ++ RC_LBOARD_STATE_STARTED, /* leaderboard attempt in progress */ ++ RC_LBOARD_STATE_CANCELED, /* leaderboard attempt canceled */ ++ RC_LBOARD_STATE_TRIGGERED, /* leaderboard attempt complete, value should be submitted */ ++ RC_LBOARD_STATE_DISABLED /* leaderboard cannot be processed at this time */ ++}; ++ ++struct rc_lboard_t { ++ rc_trigger_t start; ++ rc_trigger_t submit; ++ rc_trigger_t cancel; ++ rc_value_t value; ++ rc_value_t* progress; ++ ++ uint8_t state; ++ uint8_t has_memrefs; ++}; ++ ++RC_EXPORT int RC_CCONV rc_lboard_size(const char* memaddr); ++RC_EXPORT rc_lboard_t* RC_CCONV rc_parse_lboard(void* buffer, const char* memaddr, void* unused_L, int unused_funcs_idx); ++RC_EXPORT int RC_CCONV rc_evaluate_lboard(rc_lboard_t* lboard, int32_t* value, rc_peek_t peek, void* peek_ud, void* unused_L); ++RC_EXPORT void RC_CCONV rc_reset_lboard(rc_lboard_t* lboard); ++ ++/*****************************************************************************\ ++| Value formatting | ++\*****************************************************************************/ ++ ++/* Supported formats. */ ++enum { ++ RC_FORMAT_FRAMES, ++ RC_FORMAT_SECONDS, ++ RC_FORMAT_CENTISECS, ++ RC_FORMAT_SCORE, ++ RC_FORMAT_VALUE, ++ RC_FORMAT_MINUTES, ++ RC_FORMAT_SECONDS_AS_MINUTES, ++ RC_FORMAT_FLOAT1, ++ RC_FORMAT_FLOAT2, ++ RC_FORMAT_FLOAT3, ++ RC_FORMAT_FLOAT4, ++ RC_FORMAT_FLOAT5, ++ RC_FORMAT_FLOAT6, ++ RC_FORMAT_FIXED1, ++ RC_FORMAT_FIXED2, ++ RC_FORMAT_FIXED3, ++ RC_FORMAT_TENS, ++ RC_FORMAT_HUNDREDS, ++ RC_FORMAT_THOUSANDS, ++ RC_FORMAT_UNSIGNED_VALUE, ++ RC_FORMAT_UNFORMATTED ++}; ++ ++RC_EXPORT int RC_CCONV rc_parse_format(const char* format_str); ++RC_EXPORT int RC_CCONV rc_format_value(char* buffer, int size, int32_t value, int format); ++ ++/*****************************************************************************\ ++| Rich Presence | ++\*****************************************************************************/ ++ ++typedef struct rc_richpresence_lookup_item_t rc_richpresence_lookup_item_t; ++ ++struct rc_richpresence_lookup_item_t { ++ uint32_t first; ++ uint32_t last; ++ rc_richpresence_lookup_item_t* left; ++ rc_richpresence_lookup_item_t* right; ++ const char* label; ++}; ++ ++typedef struct rc_richpresence_lookup_t rc_richpresence_lookup_t; ++ ++struct rc_richpresence_lookup_t { ++ rc_richpresence_lookup_item_t* root; ++ rc_richpresence_lookup_t* next; ++ const char* name; ++ const char* default_label; ++ uint8_t format; ++}; ++ ++typedef struct rc_richpresence_display_part_t rc_richpresence_display_part_t; ++ ++struct rc_richpresence_display_part_t { ++ rc_richpresence_display_part_t* next; ++ const char* text; ++ rc_richpresence_lookup_t* lookup; ++ rc_operand_t value; ++ uint8_t display_type; ++}; ++ ++typedef struct rc_richpresence_display_t rc_richpresence_display_t; ++ ++struct rc_richpresence_display_t { ++ rc_trigger_t trigger; ++ rc_richpresence_display_t* next; ++ rc_richpresence_display_part_t* display; ++ uint8_t has_required_hits; ++}; ++ ++struct rc_richpresence_t { ++ rc_richpresence_display_t* first_display; ++ rc_richpresence_lookup_t* first_lookup; ++ rc_value_t* values; ++ uint8_t has_memrefs; ++}; ++ ++RC_EXPORT int RC_CCONV rc_richpresence_size(const char* script); ++RC_EXPORT int RC_CCONV rc_richpresence_size_lines(const char* script, int* lines_read); ++RC_EXPORT rc_richpresence_t* RC_CCONV rc_parse_richpresence(void* buffer, const char* script, void* unused_L, int unused_funcs_idx); ++RC_EXPORT int RC_CCONV rc_evaluate_richpresence(rc_richpresence_t* richpresence, char* buffer, size_t buffersize, rc_peek_t peek, void* peek_ud, void* unused_L); ++RC_EXPORT void RC_CCONV rc_update_richpresence(rc_richpresence_t* richpresence, rc_peek_t peek, void* peek_ud, void* unused_L); ++RC_EXPORT int RC_CCONV rc_get_richpresence_display_string(rc_richpresence_t* richpresence, char* buffer, size_t buffersize, rc_peek_t peek, void* peek_ud, void* unused_L); ++RC_EXPORT void RC_CCONV rc_reset_richpresence(rc_richpresence_t* self); ++ ++RC_END_C_DECLS ++ ++#endif /* RC_RUNTIME_TYPES_H */ +diff -rupbN melonDS.orig/src/rcheevos/include/rc_util.h melonDS.ra/src/rcheevos/include/rc_util.h +--- melonDS.orig/src/rcheevos/include/rc_util.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/include/rc_util.h 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,51 @@ ++#ifndef RC_UTIL_H ++#define RC_UTIL_H ++ ++#include "rc_export.h" ++ ++#include ++#include ++ ++RC_BEGIN_C_DECLS ++ ++/** ++ * A block of memory for variable length data (like strings and arrays). ++ */ ++typedef struct rc_buffer_chunk_t { ++ /* The current location where data is being written */ ++ uint8_t* write; ++ /* The first byte past the end of data where writing cannot occur */ ++ uint8_t* end; ++ /* The first byte of the data */ ++ uint8_t* start; ++ /* The next block in the allocated memory chain */ ++ struct rc_buffer_chunk_t* next; ++} ++rc_buffer_chunk_t; ++ ++/** ++ * A preallocated block of memory for variable length data (like strings and arrays). ++ */ ++typedef struct rc_buffer_t { ++ /* The chunk data (will point at the local data member) */ ++ struct rc_buffer_chunk_t chunk; ++ /* Small chunk of memory pre-allocated for the chunk */ ++ uint8_t data[256]; ++} ++rc_buffer_t; ++ ++void rc_buffer_init(rc_buffer_t* buffer); ++void rc_buffer_destroy(rc_buffer_t* buffer); ++uint8_t* rc_buffer_reserve(rc_buffer_t* buffer, size_t amount); ++void rc_buffer_consume(rc_buffer_t* buffer, const uint8_t* start, uint8_t* end); ++void* rc_buffer_alloc(rc_buffer_t* buffer, size_t amount); ++char* rc_buffer_strcpy(rc_buffer_t* buffer, const char* src); ++char* rc_buffer_strncpy(rc_buffer_t* buffer, const char* src, size_t len); ++ ++uint32_t rc_djb2(const char* input); ++ ++void rc_format_md5(char checksum[33], const uint8_t digest[16]); ++ ++RC_END_C_DECLS ++ ++#endif /* RC_UTIL_H */ +diff -rupbN melonDS.orig/src/rcheevos/include/rcheevos.h melonDS.ra/src/rcheevos/include/rcheevos.h +--- melonDS.orig/src/rcheevos/include/rcheevos.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/include/rcheevos.h 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,8 @@ ++#ifndef RCHEEVOS_H ++#define RCHEEVOS_H ++ ++#include "rc_runtime.h" ++#include "rc_runtime_types.h" ++#include "rc_consoles.h" ++ ++#endif /* RCHEEVOS_H */ +diff -rupbN melonDS.orig/src/rcheevos/src/rapi/rc_api_common.c melonDS.ra/src/rcheevos/src/rapi/rc_api_common.c +--- melonDS.orig/src/rcheevos/src/rapi/rc_api_common.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rapi/rc_api_common.c 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,1379 @@ ++#include "rc_api_common.h" ++#include "rc_api_request.h" ++#include "rc_api_runtime.h" ++ ++#include "../rc_compat.h" ++ ++#include ++#include ++#include ++#include ++ ++#define RETROACHIEVEMENTS_HOST "https://retroachievements.org" ++#define RETROACHIEVEMENTS_IMAGE_HOST "https://media.retroachievements.org" ++#define RETROACHIEVEMENTS_HOST_NONSSL "http://retroachievements.org" ++#define RETROACHIEVEMENTS_IMAGE_HOST_NONSSL "http://media.retroachievements.org" ++rc_api_host_t g_host = { NULL, NULL }; ++ ++/* --- rc_json --- */ ++ ++static int rc_json_parse_object(rc_json_iterator_t* iterator, rc_json_field_t* fields, size_t field_count, uint32_t* fields_seen); ++static int rc_json_parse_array(rc_json_iterator_t* iterator, rc_json_field_t* field); ++ ++static int rc_json_match_char(rc_json_iterator_t* iterator, char c) ++{ ++ if (iterator->json < iterator->end && *iterator->json == c) { ++ ++iterator->json; ++ return 1; ++ } ++ ++ return 0; ++} ++ ++static void rc_json_skip_whitespace(rc_json_iterator_t* iterator) ++{ ++ while (iterator->json < iterator->end && isspace((unsigned char)*iterator->json)) ++ ++iterator->json; ++} ++ ++static int rc_json_find_substring(rc_json_iterator_t* iterator, const char* substring) ++{ ++ const char first = *substring; ++ const size_t substring_len = strlen(substring); ++ const char* end = iterator->end - substring_len; ++ ++ while (iterator->json <= end) { ++ if (*iterator->json == first) { ++ if (memcmp(iterator->json, substring, substring_len) == 0) ++ return 1; ++ } ++ ++ ++iterator->json; ++ } ++ ++ return 0; ++} ++ ++static int rc_json_find_closing_quote(rc_json_iterator_t* iterator) ++{ ++ while (iterator->json < iterator->end) { ++ if (*iterator->json == '"') ++ return 1; ++ ++ if (*iterator->json == '\\') { ++ ++iterator->json; ++ if (iterator->json == iterator->end) ++ return 0; ++ } ++ ++ if (*iterator->json == '\0') ++ return 0; ++ ++ ++iterator->json; ++ } ++ ++ return 0; ++} ++ ++static int rc_json_parse_field(rc_json_iterator_t* iterator, rc_json_field_t* field) { ++ int result; ++ ++ if (iterator->json >= iterator->end) ++ return RC_INVALID_JSON; ++ ++ field->value_start = iterator->json; ++ ++ switch (*iterator->json) ++ { ++ case '"': /* quoted string */ ++ ++iterator->json; ++ if (!rc_json_find_closing_quote(iterator)) ++ return RC_INVALID_JSON; ++ ++iterator->json; ++ break; ++ ++ case '-': ++ case '+': /* signed number */ ++ ++iterator->json; ++ /* fallthrough to number */ ++ case '0': case '1': case '2': case '3': case '4': ++ case '5': case '6': case '7': case '8': case '9': /* number */ ++ while (iterator->json < iterator->end && *iterator->json >= '0' && *iterator->json <= '9') ++ ++iterator->json; ++ ++ if (rc_json_match_char(iterator, '.')) { ++ while (iterator->json < iterator->end && *iterator->json >= '0' && *iterator->json <= '9') ++ ++iterator->json; ++ } ++ break; ++ ++ case '[': /* array */ ++ result = rc_json_parse_array(iterator, field); ++ if (result != RC_OK) ++ return result; ++ ++ break; ++ ++ case '{': /* object */ ++ result = rc_json_parse_object(iterator, NULL, 0, &field->array_size); ++ if (result != RC_OK) ++ return result; ++ ++ break; ++ ++ default: /* non-quoted text [true,false,null] */ ++ if (!isalpha((unsigned char)*iterator->json)) ++ return RC_INVALID_JSON; ++ ++ while (iterator->json < iterator->end && isalnum((unsigned char)*iterator->json)) ++ ++iterator->json; ++ break; ++ } ++ ++ field->value_end = iterator->json; ++ return RC_OK; ++} ++ ++static int rc_json_parse_array(rc_json_iterator_t* iterator, rc_json_field_t* field) { ++ rc_json_field_t unused_field; ++ int result; ++ ++ if (!rc_json_match_char(iterator, '[')) ++ return RC_INVALID_JSON; ++ ++ field->array_size = 0; ++ ++ if (rc_json_match_char(iterator, ']')) /* empty array */ ++ return RC_OK; ++ ++ do ++ { ++ rc_json_skip_whitespace(iterator); ++ ++ result = rc_json_parse_field(iterator, &unused_field); ++ if (result != RC_OK) ++ return result; ++ ++ ++field->array_size; ++ ++ rc_json_skip_whitespace(iterator); ++ } while (rc_json_match_char(iterator, ',')); ++ ++ if (!rc_json_match_char(iterator, ']')) ++ return RC_INVALID_JSON; ++ ++ return RC_OK; ++} ++ ++static int rc_json_get_next_field(rc_json_iterator_t* iterator, rc_json_field_t* field) { ++ rc_json_skip_whitespace(iterator); ++ ++ if (!rc_json_match_char(iterator, '"')) ++ return RC_INVALID_JSON; ++ ++ field->name = iterator->json; ++ while (iterator->json < iterator->end && *iterator->json != '"') { ++ if (!*iterator->json) ++ return RC_INVALID_JSON; ++ ++iterator->json; ++ } ++ ++ if (iterator->json == iterator->end) ++ return RC_INVALID_JSON; ++ ++ field->name_len = iterator->json - field->name; ++ ++iterator->json; ++ ++ rc_json_skip_whitespace(iterator); ++ ++ if (!rc_json_match_char(iterator, ':')) ++ return RC_INVALID_JSON; ++ ++ rc_json_skip_whitespace(iterator); ++ ++ if (rc_json_parse_field(iterator, field) < 0) ++ return RC_INVALID_JSON; ++ ++ rc_json_skip_whitespace(iterator); ++ ++ return RC_OK; ++} ++ ++static int rc_json_parse_object(rc_json_iterator_t* iterator, rc_json_field_t* fields, size_t field_count, uint32_t* fields_seen) { ++ size_t i; ++ uint32_t num_fields = 0; ++ rc_json_field_t field; ++ int result; ++ ++ if (fields_seen) ++ *fields_seen = 0; ++ ++ for (i = 0; i < field_count; ++i) ++ fields[i].value_start = fields[i].value_end = NULL; ++ ++ if (!rc_json_match_char(iterator, '{')) ++ return RC_INVALID_JSON; ++ ++ if (rc_json_match_char(iterator, '}')) /* empty object */ ++ return RC_OK; ++ ++ do ++ { ++ result = rc_json_get_next_field(iterator, &field); ++ if (result != RC_OK) ++ return result; ++ ++ for (i = 0; i < field_count; ++i) { ++ if (!fields[i].value_start && fields[i].name_len == field.name_len && ++ memcmp(fields[i].name, field.name, field.name_len) == 0) { ++ fields[i].value_start = field.value_start; ++ fields[i].value_end = field.value_end; ++ fields[i].array_size = field.array_size; ++ break; ++ } ++ } ++ ++ ++num_fields; ++ ++ } while (rc_json_match_char(iterator, ',')); ++ ++ if (!rc_json_match_char(iterator, '}')) ++ return RC_INVALID_JSON; ++ ++ if (fields_seen) ++ *fields_seen = num_fields; ++ ++ return RC_OK; ++} ++ ++int rc_json_get_next_object_field(rc_json_iterator_t* iterator, rc_json_field_t* field) { ++ if (!rc_json_match_char(iterator, ',') && !rc_json_match_char(iterator, '{')) ++ return 0; ++ ++ return (rc_json_get_next_field(iterator, field) == RC_OK); ++} ++ ++int rc_json_get_object_string_length(const char* json) { ++ rc_json_iterator_t iterator; ++ memset(&iterator, 0, sizeof(iterator)); ++ iterator.json = json; ++ iterator.end = json + (1024 * 1024 * 1024); /* arbitrary 1GB limit on JSON response */ ++ ++ rc_json_parse_object(&iterator, NULL, 0, NULL); ++ ++ if (iterator.json == json) /* not JSON */ ++ return (int)strlen(json); ++ ++ return (int)(iterator.json - json); ++} ++ ++static int rc_json_extract_html_error(rc_api_response_t* response, const rc_api_server_response_t* server_response) { ++ rc_json_iterator_t iterator; ++ memset(&iterator, 0, sizeof(iterator)); ++ iterator.json = server_response->body; ++ iterator.end = server_response->body + server_response->body_length; ++ ++ /* assume the title contains the most appropriate message to display to the user */ ++ if (rc_json_find_substring(&iterator, "")) { ++ const char* title_start = iterator.json + 7; ++ if (rc_json_find_substring(&iterator, "")) { ++ response->error_message = rc_buffer_strncpy(&response->buffer, title_start, iterator.json - title_start); ++ response->succeeded = 0; ++ return RC_INVALID_JSON; ++ } ++ } ++ ++ /* title not found, return the first line of the response (up to 200 characters) */ ++ iterator.json = server_response->body; ++ ++ while (iterator.json < iterator.end && *iterator.json != '\n' && ++ iterator.json - server_response->body < 200) { ++ ++iterator.json; ++ } ++ ++ if (iterator.json > server_response->body && iterator.json[-1] == '\r') ++ --iterator.json; ++ ++ if (iterator.json > server_response->body) ++ response->error_message = rc_buffer_strncpy(&response->buffer, server_response->body, iterator.json - server_response->body); ++ ++ response->succeeded = 0; ++ return RC_INVALID_JSON; ++} ++ ++static int rc_json_convert_error_code(const char* server_error_code) ++{ ++ switch (server_error_code[0]) { ++ case 'a': ++ if (strcmp(server_error_code, "access_denied") == 0) ++ return RC_ACCESS_DENIED; ++ break; ++ ++ case 'e': ++ if (strcmp(server_error_code, "expired_token") == 0) ++ return RC_EXPIRED_TOKEN; ++ break; ++ ++ case 'i': ++ if (strcmp(server_error_code, "invalid_credentials") == 0) ++ return RC_INVALID_CREDENTIALS; ++ if (strcmp(server_error_code, "invalid_parameter") == 0) ++ return RC_INVALID_STATE; ++ break; ++ ++ case 'm': ++ if (strcmp(server_error_code, "missing_parameter") == 0) ++ return RC_INVALID_STATE; ++ break; ++ ++ case 'n': ++ if (strcmp(server_error_code, "not_found") == 0) ++ return RC_NOT_FOUND; ++ break; ++ ++ default: ++ break; ++ } ++ ++ return RC_API_FAILURE; ++} ++ ++int rc_json_parse_server_response(rc_api_response_t* response, const rc_api_server_response_t* server_response, rc_json_field_t* fields, size_t field_count) { ++ int result; ++ ++#ifndef NDEBUG ++ if (field_count < 2) ++ return RC_INVALID_STATE; ++ if (strcmp(fields[0].name, "Success") != 0) ++ return RC_INVALID_STATE; ++ if (strcmp(fields[1].name, "Error") != 0) ++ return RC_INVALID_STATE; ++#endif ++ ++ response->error_message = NULL; ++ ++ if (!server_response) { ++ response->succeeded = 0; ++ return RC_NO_RESPONSE; ++ } ++ ++ if (server_response->http_status_code == RC_API_SERVER_RESPONSE_CLIENT_ERROR || ++ server_response->http_status_code == RC_API_SERVER_RESPONSE_RETRYABLE_CLIENT_ERROR) { ++ /* client provided error message is passed as the response body */ ++ response->error_message = server_response->body; ++ response->succeeded = 0; ++ return RC_NO_RESPONSE; ++ } ++ ++ if (!server_response->body || !*server_response->body) { ++ /* expect valid HTTP status codes to have bodies that we can extract the message from, ++ * but provide some default messages in case they don't. */ ++ switch (server_response->http_status_code) { ++ case 504: /* 504 Gateway Timeout */ ++ case 522: /* 522 Connection Timed Out */ ++ case 524: /* 524 A Timeout Occurred */ ++ response->error_message = "Request has timed out."; ++ break; ++ ++ case 521: /* 521 Web Server is Down */ ++ case 523: /* 523 Origin is Unreachable */ ++ response->error_message = "Could not connect to server."; ++ break; ++ ++ default: ++ break; ++ } ++ ++ response->succeeded = 0; ++ return RC_NO_RESPONSE; ++ } ++ ++ if (*server_response->body != '{') { ++ result = rc_json_extract_html_error(response, server_response); ++ } ++ else { ++ rc_json_iterator_t iterator; ++ memset(&iterator, 0, sizeof(iterator)); ++ iterator.json = server_response->body; ++ iterator.end = server_response->body + server_response->body_length; ++ result = rc_json_parse_object(&iterator, fields, field_count, NULL); ++ ++ rc_json_get_optional_string(&response->error_message, response, &fields[1], "Error", NULL); ++ rc_json_get_optional_bool(&response->succeeded, &fields[0], "Success", 1); ++ ++ /* Code will be the third field in the fields array, but may not always be present */ ++ if (field_count > 2 && strcmp(fields[2].name, "Code") == 0) { ++ rc_json_get_optional_string(&response->error_code, response, &fields[2], "Code", NULL); ++ if (response->error_code != NULL) ++ result = rc_json_convert_error_code(response->error_code); ++ } ++ } ++ ++ return result; ++} ++ ++static int rc_json_missing_field(rc_api_response_t* response, const rc_json_field_t* field) { ++ const char* not_found = " not found in response"; ++ const size_t not_found_len = strlen(not_found); ++ const size_t field_len = strlen(field->name); ++ ++ uint8_t* write = rc_buffer_reserve(&response->buffer, field_len + not_found_len + 1); ++ if (write) { ++ response->error_message = (char*)write; ++ memcpy(write, field->name, field_len); ++ write += field_len; ++ memcpy(write, not_found, not_found_len + 1); ++ write += not_found_len + 1; ++ rc_buffer_consume(&response->buffer, (uint8_t*)response->error_message, write); ++ } ++ ++ response->succeeded = 0; ++ return 0; ++} ++ ++int rc_json_get_required_object(rc_json_field_t* fields, size_t field_count, rc_api_response_t* response, rc_json_field_t* field, const char* field_name) { ++ rc_json_iterator_t iterator; ++ ++#ifndef NDEBUG ++ if (strcmp(field->name, field_name) != 0) ++ return 0; ++#else ++ (void)field_name; ++#endif ++ ++ if (!field->value_start) ++ return rc_json_missing_field(response, field); ++ ++ memset(&iterator, 0, sizeof(iterator)); ++ iterator.json = field->value_start; ++ iterator.end = field->value_end; ++ return (rc_json_parse_object(&iterator, fields, field_count, &field->array_size) == RC_OK); ++} ++ ++static int rc_json_get_array_entry_value(rc_json_field_t* field, rc_json_iterator_t* iterator) { ++ rc_json_skip_whitespace(iterator); ++ ++ if (iterator->json >= iterator->end) ++ return 0; ++ ++ if (rc_json_parse_field(iterator, field) != RC_OK) ++ return 0; ++ ++ rc_json_skip_whitespace(iterator); ++ ++ if (!rc_json_match_char(iterator, ',')) ++ rc_json_match_char(iterator, ']'); ++ ++ return 1; ++} ++ ++int rc_json_get_required_unum_array(uint32_t** entries, uint32_t* num_entries, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name) { ++ rc_json_iterator_t iterator; ++ rc_json_field_t array; ++ rc_json_field_t value; ++ uint32_t* entry; ++ ++ memset(&array, 0, sizeof(array)); ++ if (!rc_json_get_required_array(num_entries, &array, response, field, field_name)) ++ return RC_MISSING_VALUE; ++ ++ if (*num_entries) { ++ *entries = (uint32_t*)rc_buffer_alloc(&response->buffer, *num_entries * sizeof(uint32_t)); ++ if (!*entries) ++ return RC_OUT_OF_MEMORY; ++ ++ value.name = field_name; ++ ++ memset(&iterator, 0, sizeof(iterator)); ++ iterator.json = array.value_start; ++ iterator.end = array.value_end; ++ ++ entry = *entries; ++ while (rc_json_get_array_entry_value(&value, &iterator)) { ++ if (!rc_json_get_unum(entry, &value, field_name)) ++ return RC_MISSING_VALUE; ++ ++ ++entry; ++ } ++ } ++ else { ++ *entries = NULL; ++ } ++ ++ return RC_OK; ++} ++ ++int rc_json_get_required_array(uint32_t* num_entries, rc_json_field_t* array_field, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name) { ++#ifndef NDEBUG ++ if (strcmp(field->name, field_name) != 0) ++ return 0; ++#endif ++ ++ if (!rc_json_get_optional_array(num_entries, array_field, field, field_name)) ++ return rc_json_missing_field(response, field); ++ ++ return 1; ++} ++ ++int rc_json_get_optional_array(uint32_t* num_entries, rc_json_field_t* array_field, const rc_json_field_t* field, const char* field_name) { ++#ifndef NDEBUG ++ if (strcmp(field->name, field_name) != 0) ++ return 0; ++#else ++ (void)field_name; ++#endif ++ ++ if (!field->value_start || *field->value_start != '[') { ++ *num_entries = 0; ++ return 0; ++ } ++ ++ memcpy(array_field, field, sizeof(*array_field)); ++ ++array_field->value_start; /* skip [ */ ++ ++ *num_entries = field->array_size; ++ return 1; ++} ++ ++int rc_json_get_array_entry_object(rc_json_field_t* fields, size_t field_count, rc_json_iterator_t* iterator) { ++ rc_json_skip_whitespace(iterator); ++ ++ if (iterator->json >= iterator->end) ++ return 0; ++ ++ if (rc_json_parse_object(iterator, fields, field_count, NULL) != RC_OK) ++ return 0; ++ ++ rc_json_skip_whitespace(iterator); ++ ++ if (!rc_json_match_char(iterator, ',')) ++ rc_json_match_char(iterator, ']'); ++ ++ return 1; ++} ++ ++static uint32_t rc_json_decode_hex4(const char* input) { ++ char hex[5]; ++ ++ memcpy(hex, input, 4); ++ hex[4] = '\0'; ++ ++ return (uint32_t)strtoul(hex, NULL, 16); ++} ++ ++static int rc_json_ucs32_to_utf8(uint8_t* dst, uint32_t ucs32_char) { ++ if (ucs32_char < 0x80) { ++ dst[0] = (ucs32_char & 0x7F); ++ return 1; ++ } ++ ++ if (ucs32_char < 0x0800) { ++ dst[1] = 0x80 | (ucs32_char & 0x3F); ucs32_char >>= 6; ++ dst[0] = 0xC0 | (ucs32_char & 0x1F); ++ return 2; ++ } ++ ++ if (ucs32_char < 0x010000) { ++ dst[2] = 0x80 | (ucs32_char & 0x3F); ucs32_char >>= 6; ++ dst[1] = 0x80 | (ucs32_char & 0x3F); ucs32_char >>= 6; ++ dst[0] = 0xE0 | (ucs32_char & 0x0F); ++ return 3; ++ } ++ ++ if (ucs32_char < 0x200000) { ++ dst[3] = 0x80 | (ucs32_char & 0x3F); ucs32_char >>= 6; ++ dst[2] = 0x80 | (ucs32_char & 0x3F); ucs32_char >>= 6; ++ dst[1] = 0x80 | (ucs32_char & 0x3F); ucs32_char >>= 6; ++ dst[0] = 0xF0 | (ucs32_char & 0x07); ++ return 4; ++ } ++ ++ if (ucs32_char < 0x04000000) { ++ dst[4] = 0x80 | (ucs32_char & 0x3F); ucs32_char >>= 6; ++ dst[3] = 0x80 | (ucs32_char & 0x3F); ucs32_char >>= 6; ++ dst[2] = 0x80 | (ucs32_char & 0x3F); ucs32_char >>= 6; ++ dst[1] = 0x80 | (ucs32_char & 0x3F); ucs32_char >>= 6; ++ dst[0] = 0xF8 | (ucs32_char & 0x03); ++ return 5; ++ } ++ ++ dst[5] = 0x80 | (ucs32_char & 0x3F); ucs32_char >>= 6; ++ dst[4] = 0x80 | (ucs32_char & 0x3F); ucs32_char >>= 6; ++ dst[3] = 0x80 | (ucs32_char & 0x3F); ucs32_char >>= 6; ++ dst[2] = 0x80 | (ucs32_char & 0x3F); ucs32_char >>= 6; ++ dst[1] = 0x80 | (ucs32_char & 0x3F); ucs32_char >>= 6; ++ dst[0] = 0xFC | (ucs32_char & 0x01); ++ return 6; ++} ++ ++int rc_json_get_string(const char** out, rc_buffer_t* buffer, const rc_json_field_t* field, const char* field_name) { ++ const char* src = field->value_start; ++ size_t len = field->value_end - field->value_start; ++ char* dst; ++ ++#ifndef NDEBUG ++ if (strcmp(field->name, field_name) != 0) ++ return 0; ++#else ++ (void)field_name; ++#endif ++ ++ if (!src) { ++ *out = NULL; ++ return 0; ++ } ++ ++ if (len == 4 && memcmp(field->value_start, "null", 4) == 0) { ++ *out = NULL; ++ return 1; ++ } ++ ++ if (*src == '\"') { ++ ++src; ++ ++ if (*src == '\"') { ++ /* simple optimization for empty string - don't allocate space */ ++ *out = ""; ++ return 1; ++ } ++ ++ *out = dst = (char*)rc_buffer_reserve(buffer, len - 1); /* -2 for quotes, +1 for null terminator */ ++ ++ do { ++ if (*src == '\\') { ++ ++src; ++ if (*src == 'n') { ++ /* newline */ ++ ++src; ++ *dst++ = '\n'; ++ continue; ++ } ++ ++ if (*src == 'r') { ++ /* carriage return */ ++ ++src; ++ *dst++ = '\r'; ++ continue; ++ } ++ ++ if (*src == 'u') { ++ /* unicode character */ ++ uint32_t ucs32_char = rc_json_decode_hex4(src + 1); ++ src += 5; ++ ++ if (ucs32_char >= 0xD800 && ucs32_char < 0xE000) { ++ /* surrogate lead - look for surrogate tail */ ++ if (ucs32_char < 0xDC00 && src[0] == '\\' && src[1] == 'u') { ++ const uint32_t surrogate = rc_json_decode_hex4(src + 2); ++ src += 6; ++ ++ if (surrogate >= 0xDC00 && surrogate < 0xE000) { ++ /* found a surrogate tail, merge them */ ++ ucs32_char = (((ucs32_char - 0xD800) << 10) | (surrogate - 0xDC00)) + 0x10000; ++ } ++ } ++ ++ if (!(ucs32_char & 0xFFFF0000)) { ++ /* invalid surrogate pair, fallback to replacement char */ ++ ucs32_char = 0xFFFD; ++ } ++ } ++ ++ dst += rc_json_ucs32_to_utf8((unsigned char*)dst, ucs32_char); ++ continue; ++ } ++ ++ if (*src == 't') { ++ /* tab */ ++ ++src; ++ *dst++ = '\t'; ++ continue; ++ } ++ ++ /* just an escaped character, fallthrough to normal copy */ ++ } ++ ++ *dst++ = *src++; ++ } while (*src != '\"'); ++ ++ } else { ++ *out = dst = (char*)rc_buffer_reserve(buffer, len + 1); /* +1 for null terminator */ ++ memcpy(dst, src, len); ++ dst += len; ++ } ++ ++ *dst++ = '\0'; ++ rc_buffer_consume(buffer, (uint8_t*)(*out), (uint8_t*)dst); ++ return 1; ++} ++ ++int rc_json_field_string_matches(const rc_json_field_t* field, const char* text) { ++ int is_quoted = 0; ++ const char* ptr = field->value_start; ++ if (!ptr) ++ return 0; ++ ++ if (*ptr == '"') { ++ is_quoted = 1; ++ ++ptr; ++ } ++ ++ while (ptr < field->value_end) { ++ if (*ptr != *text) { ++ if (*ptr != '\\') { ++ if (*ptr == '"' && is_quoted && (*text == '\0')) { ++ is_quoted = 0; ++ ++ptr; ++ continue; ++ } ++ ++ return 0; ++ } ++ ++ ++ptr; ++ switch (*ptr) { ++ case 'n': ++ if (*text != '\n') ++ return 0; ++ break; ++ case 'r': ++ if (*text != '\r') ++ return 0; ++ break; ++ case 't': ++ if (*text != '\t') ++ return 0; ++ break; ++ default: ++ if (*text != *ptr) ++ return 0; ++ break; ++ } ++ } ++ ++ ++text; ++ ++ptr; ++ } ++ ++ return !is_quoted && (*text == '\0'); ++} ++ ++void rc_json_get_optional_string(const char** out, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name, const char* default_value) { ++ if (!rc_json_get_string(out, &response->buffer, field, field_name)) ++ *out = default_value; ++} ++ ++int rc_json_get_required_string(const char** out, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name) { ++ if (rc_json_get_string(out, &response->buffer, field, field_name)) ++ return 1; ++ ++ return rc_json_missing_field(response, field); ++} ++ ++int rc_json_get_num(int32_t* out, const rc_json_field_t* field, const char* field_name) { ++ const char* src = field->value_start; ++ int32_t value = 0; ++ int negative = 0; ++ ++#ifndef NDEBUG ++ if (strcmp(field->name, field_name) != 0) ++ return 0; ++#else ++ (void)field_name; ++#endif ++ ++ if (!src) { ++ *out = 0; ++ return 0; ++ } ++ ++ /* assert: string contains only numerals and an optional sign per rc_json_parse_field */ ++ if (*src == '-') { ++ negative = 1; ++ ++src; ++ } else if (*src == '+') { ++ ++src; ++ } else if (*src < '0' || *src > '9') { ++ *out = 0; ++ return 0; ++ } ++ ++ while (src < field->value_end && *src != '.') { ++ value *= 10; ++ value += *src - '0'; ++ ++src; ++ } ++ ++ if (negative) ++ *out = -value; ++ else ++ *out = value; ++ ++ return 1; ++} ++ ++void rc_json_get_optional_num(int32_t* out, const rc_json_field_t* field, const char* field_name, int default_value) { ++ if (!rc_json_get_num(out, field, field_name)) ++ *out = default_value; ++} ++ ++int rc_json_get_required_num(int32_t* out, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name) { ++ if (rc_json_get_num(out, field, field_name)) ++ return 1; ++ ++ return rc_json_missing_field(response, field); ++} ++ ++int rc_json_get_unum(uint32_t* out, const rc_json_field_t* field, const char* field_name) { ++ const char* src = field->value_start; ++ uint32_t value = 0; ++ ++#ifndef NDEBUG ++ if (strcmp(field->name, field_name) != 0) ++ return 0; ++#else ++ (void)field_name; ++#endif ++ ++ if (!src) { ++ *out = 0; ++ return 0; ++ } ++ ++ if (*src < '0' || *src > '9') { ++ *out = 0; ++ return 0; ++ } ++ ++ /* assert: string contains only numerals per rc_json_parse_field */ ++ while (src < field->value_end && *src != '.') { ++ value *= 10; ++ value += *src - '0'; ++ ++src; ++ } ++ ++ *out = value; ++ return 1; ++} ++ ++void rc_json_get_optional_unum(uint32_t* out, const rc_json_field_t* field, const char* field_name, uint32_t default_value) { ++ if (!rc_json_get_unum(out, field, field_name)) ++ *out = default_value; ++} ++ ++int rc_json_get_required_unum(uint32_t* out, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name) { ++ if (rc_json_get_unum(out, field, field_name)) ++ return 1; ++ ++ return rc_json_missing_field(response, field); ++} ++ ++int rc_json_get_float(float* out, const rc_json_field_t* field, const char* field_name) { ++ int32_t whole, fraction, fraction_denominator; ++ const char* decimal = field->value_start; ++ ++ if (!decimal) { ++ *out = 0.0f; ++ return 0; ++ } ++ ++ if (!rc_json_get_num(&whole, field, field_name)) ++ return 0; ++ ++ while (decimal < field->value_end && *decimal != '.') ++ ++decimal; ++ ++ fraction = 0; ++ fraction_denominator = 1; ++ if (decimal) { ++ ++decimal; ++ while (decimal < field->value_end && *decimal >= '0' && *decimal <= '9') { ++ fraction *= 10; ++ fraction += *decimal - '0'; ++ fraction_denominator *= 10; ++ ++decimal; ++ } ++ } ++ ++ if (whole < 0) ++ fraction = -fraction; ++ ++ *out = (float)whole + ((float)fraction / (float)fraction_denominator); ++ return 1; ++} ++ ++void rc_json_get_optional_float(float* out, const rc_json_field_t* field, const char* field_name, float default_value) { ++ if (!rc_json_get_float(out, field, field_name)) ++ *out = default_value; ++} ++ ++int rc_json_get_required_float(float* out, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name) { ++ if (rc_json_get_float(out, field, field_name)) ++ return 1; ++ ++ return rc_json_missing_field(response, field); ++} ++ ++int rc_json_get_datetime(time_t* out, const rc_json_field_t* field, const char* field_name) { ++ struct tm tm; ++ ++#ifndef NDEBUG ++ if (strcmp(field->name, field_name) != 0) ++ return 0; ++#else ++ (void)field_name; ++#endif ++ ++ if (*field->value_start == '\"') { ++ memset(&tm, 0, sizeof(tm)); ++ if (sscanf_s(field->value_start + 1, "%d-%d-%d %d:%d:%d", /* DB format "2013-10-20 22:12:21" */ ++ &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) == 6 || ++ /* NOTE: relies on sscanf stopping when it sees a non-digit after the seconds. could be 'Z', '.', '+', or '-' */ ++ sscanf_s(field->value_start + 1, "%d-%d-%dT%d:%d:%d", /* ISO format "2013-10-20T22:12:21.000000Z */ ++ &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) == 6) { ++ tm.tm_mon--; /* 0-based */ ++ tm.tm_year -= 1900; /* 1900 based */ ++ ++ /* mktime converts a struct tm to a time_t using the local timezone. ++ * the input string is UTC. since timegm is not universally cross-platform, ++ * figure out the offset between UTC and local time by applying the ++ * timezone conversion twice and manually removing the difference */ ++ { ++ time_t local_timet = mktime(&tm); ++ time_t skewed_timet, tz_offset; ++ struct tm gmt_tm; ++ gmtime_s(&gmt_tm, &local_timet); ++ skewed_timet = mktime(&gmt_tm); /* applies local time adjustment second time */ ++ tz_offset = skewed_timet - local_timet; ++ *out = local_timet - tz_offset; ++ } ++ ++ return 1; ++ } ++ } ++ ++ *out = 0; ++ return 0; ++} ++ ++int rc_json_get_required_datetime(time_t* out, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name) { ++ if (rc_json_get_datetime(out, field, field_name)) ++ return 1; ++ ++ return rc_json_missing_field(response, field); ++} ++ ++int rc_json_get_bool(int* out, const rc_json_field_t* field, const char* field_name) { ++ const char* src = field->value_start; ++ ++#ifndef NDEBUG ++ if (strcmp(field->name, field_name) != 0) ++ return 0; ++#else ++ (void)field_name; ++#endif ++ ++ if (src) { ++ const size_t len = field->value_end - field->value_start; ++ if (len == 4 && strncasecmp(src, "true", 4) == 0) { ++ *out = 1; ++ return 1; ++ } else if (len == 5 && strncasecmp(src, "false", 5) == 0) { ++ *out = 0; ++ return 1; ++ } else if (len == 1) { ++ *out = (*src != '0'); ++ return 1; ++ } ++ } ++ ++ *out = 0; ++ return 0; ++} ++ ++void rc_json_get_optional_bool(int* out, const rc_json_field_t* field, const char* field_name, int default_value) { ++ if (!rc_json_get_bool(out, field, field_name)) ++ *out = default_value; ++} ++ ++int rc_json_get_required_bool(int* out, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name) { ++ if (rc_json_get_bool(out, field, field_name)) ++ return 1; ++ ++ return rc_json_missing_field(response, field); ++} ++ ++void rc_json_extract_filename(rc_json_field_t* field) { ++ if (field->value_end) { ++ const char* str = field->value_end; ++ ++ /* remove the extension */ ++ while (str > field->value_start && str[-1] != '/') { ++ --str; ++ if (*str == '.') { ++ field->value_end = str; ++ break; ++ } ++ } ++ ++ /* find the path separator */ ++ while (str > field->value_start && str[-1] != '/') ++ --str; ++ ++ field->value_start = str; ++ } ++} ++ ++/* --- rc_api_request --- */ ++ ++void rc_api_destroy_request(rc_api_request_t* request) ++{ ++ rc_buffer_destroy(&request->buffer); ++} ++ ++/* --- rc_url_builder --- */ ++ ++void rc_url_builder_init(rc_api_url_builder_t* builder, rc_buffer_t* buffer, size_t estimated_size) { ++ rc_buffer_chunk_t* used_buffer; ++ ++ memset(builder, 0, sizeof(*builder)); ++ builder->buffer = buffer; ++ builder->write = builder->start = (char*)rc_buffer_reserve(buffer, estimated_size); ++ ++ used_buffer = &buffer->chunk; ++ while (used_buffer && used_buffer->write != (uint8_t*)builder->write) ++ used_buffer = used_buffer->next; ++ ++ builder->end = (used_buffer) ? (char*)used_buffer->end : builder->start + estimated_size; ++} ++ ++const char* rc_url_builder_finalize(rc_api_url_builder_t* builder) { ++ rc_url_builder_append(builder, "", 1); ++ ++ if (builder->result != RC_OK) ++ return NULL; ++ ++ rc_buffer_consume(builder->buffer, (uint8_t*)builder->start, (uint8_t*)builder->write); ++ return builder->start; ++} ++ ++static int rc_url_builder_reserve(rc_api_url_builder_t* builder, size_t amount) { ++ if (builder->result == RC_OK) { ++ size_t remaining = builder->end - builder->write; ++ if (remaining < amount) { ++ const size_t used = builder->write - builder->start; ++ const size_t current_size = builder->end - builder->start; ++ const size_t buffer_prefix_size = sizeof(rc_buffer_chunk_t); ++ char* new_start; ++ size_t new_size = (current_size < 256) ? 256 : current_size * 2; ++ do { ++ remaining = new_size - used; ++ if (remaining >= amount) ++ break; ++ ++ new_size *= 2; ++ } while (1); ++ ++ /* rc_buffer_reserve will align to 256 bytes after including the buffer prefix. attempt to account for that */ ++ if ((remaining - amount) > buffer_prefix_size) ++ new_size -= buffer_prefix_size; ++ ++ new_start = (char*)rc_buffer_reserve(builder->buffer, new_size); ++ if (!new_start) { ++ builder->result = RC_OUT_OF_MEMORY; ++ return RC_OUT_OF_MEMORY; ++ } ++ ++ if (new_start != builder->start) { ++ memcpy(new_start, builder->start, used); ++ builder->start = new_start; ++ builder->write = new_start + used; ++ } ++ ++ builder->end = builder->start + new_size; ++ } ++ } ++ ++ return builder->result; ++} ++ ++void rc_url_builder_append_encoded_str(rc_api_url_builder_t* builder, const char* str) { ++ static const char hex[] = "0123456789abcdef"; ++ const char* start = str; ++ size_t len = 0; ++ for (;;) { ++ const char c = *str++; ++ switch (c) { ++ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': ++ case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': ++ case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': ++ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': ++ case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': ++ case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': ++ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': ++ case '-': case '_': case '.': case '~': ++ len++; ++ continue; ++ ++ case '\0': ++ if (len) ++ rc_url_builder_append(builder, start, len); ++ ++ return; ++ ++ default: ++ if (rc_url_builder_reserve(builder, len + 3) != RC_OK) ++ return; ++ ++ if (len) { ++ memcpy(builder->write, start, len); ++ builder->write += len; ++ } ++ ++ if (c == ' ') { ++ *builder->write++ = '+'; ++ } else { ++ *builder->write++ = '%'; ++ *builder->write++ = hex[((unsigned char)c) >> 4]; ++ *builder->write++ = hex[c & 0x0F]; ++ } ++ break; ++ } ++ ++ start = str; ++ len = 0; ++ } ++} ++ ++void rc_url_builder_append(rc_api_url_builder_t* builder, const char* data, size_t len) { ++ if (rc_url_builder_reserve(builder, len) == RC_OK) { ++ memcpy(builder->write, data, len); ++ builder->write += len; ++ } ++} ++ ++static int rc_url_builder_append_param_equals(rc_api_url_builder_t* builder, const char* param) { ++ size_t param_len = strlen(param); ++ ++ if (rc_url_builder_reserve(builder, param_len + 2) == RC_OK) { ++ if (builder->write > builder->start) { ++ if (builder->write[-1] != '?') ++ *builder->write++ = '&'; ++ } ++ ++ memcpy(builder->write, param, param_len); ++ builder->write += param_len; ++ *builder->write++ = '='; ++ } ++ ++ return builder->result; ++} ++ ++void rc_url_builder_append_unum_param(rc_api_url_builder_t* builder, const char* param, uint32_t value) { ++ if (rc_url_builder_append_param_equals(builder, param) == RC_OK) { ++ char num[16]; ++ int chars = snprintf(num, sizeof(num), "%u", value); ++ rc_url_builder_append(builder, num, chars); ++ } ++} ++ ++void rc_url_builder_append_num_param(rc_api_url_builder_t* builder, const char* param, int32_t value) { ++ if (rc_url_builder_append_param_equals(builder, param) == RC_OK) { ++ char num[16]; ++ int chars = snprintf(num, sizeof(num), "%d", value); ++ rc_url_builder_append(builder, num, chars); ++ } ++} ++ ++void rc_url_builder_append_str_param(rc_api_url_builder_t* builder, const char* param, const char* value) { ++ rc_url_builder_append_param_equals(builder, param); ++ rc_url_builder_append_encoded_str(builder, value); ++} ++ ++void rc_api_url_build_dorequest_url(rc_api_request_t* request, const rc_api_host_t* host) { ++ #define DOREQUEST_ENDPOINT "/dorequest.php" ++ rc_buffer_init(&request->buffer); ++ ++ if (!host || !host->host) { ++ request->url = RETROACHIEVEMENTS_HOST DOREQUEST_ENDPOINT; ++ } ++ else { ++ const size_t endpoint_len = sizeof(DOREQUEST_ENDPOINT); ++ const size_t host_len = strlen(host->host); ++ const size_t protocol_len = (strstr(host->host, "://")) ? 0 : 7; ++ const size_t url_len = protocol_len + host_len + endpoint_len; ++ uint8_t* url = rc_buffer_reserve(&request->buffer, url_len); ++ ++ if (protocol_len) ++ memcpy(url, "http://", protocol_len); ++ ++ memcpy(url + protocol_len, host->host, host_len); ++ memcpy(url + protocol_len + host_len, DOREQUEST_ENDPOINT, endpoint_len); ++ rc_buffer_consume(&request->buffer, url, url + url_len); ++ ++ request->url = (char*)url; ++ } ++ #undef DOREQUEST_ENDPOINT ++} ++ ++int rc_api_url_build_dorequest(rc_api_url_builder_t* builder, const char* api, const char* username, const char* api_token) { ++ if (!username || !*username || !api_token || !*api_token) { ++ builder->result = RC_INVALID_STATE; ++ return 0; ++ } ++ ++ rc_url_builder_append_str_param(builder, "r", api); ++ rc_url_builder_append_str_param(builder, "u", username); ++ rc_url_builder_append_str_param(builder, "t", api_token); ++ ++ return (builder->result == RC_OK); ++} ++ ++/* --- Set Host --- */ ++ ++static void rc_api_update_host(const char** host, const char* hostname) { ++ if (*host != NULL) ++ free((void*)*host); ++ ++ if (hostname != NULL) { ++ if (strstr(hostname, "://")) { ++ *host = strdup(hostname); ++ } ++ else { ++ const size_t hostname_len = strlen(hostname); ++ if (hostname_len == 0) { ++ *host = NULL; ++ } ++ else { ++ char* newhost = (char*)malloc(hostname_len + 7 + 1); ++ if (newhost) { ++ memcpy(newhost, "http://", 7); ++ memcpy(&newhost[7], hostname, hostname_len + 1); ++ *host = newhost; ++ } ++ else { ++ *host = NULL; ++ } ++ } ++ } ++ } ++ else { ++ *host = NULL; ++ } ++} ++ ++const char* rc_api_default_host(void) { ++ return RETROACHIEVEMENTS_HOST; ++} ++ ++void rc_api_set_host(const char* hostname) { ++ if (hostname && strcmp(hostname, RETROACHIEVEMENTS_HOST) == 0) ++ hostname = NULL; ++ ++ rc_api_update_host(&g_host.host, hostname); ++ ++ if (!hostname) { ++ /* also clear out the image hostname */ ++ rc_api_set_image_host(NULL); ++ } ++ else if (strcmp(hostname, RETROACHIEVEMENTS_HOST_NONSSL) == 0) { ++ /* if just pointing at the non-HTTPS host, explicitly use the default image host ++ * so it doesn't try to use the web host directly */ ++ rc_api_set_image_host(RETROACHIEVEMENTS_IMAGE_HOST_NONSSL); ++ } ++} ++ ++void rc_api_set_image_host(const char* hostname) { ++ rc_api_update_host(&g_host.media_host, hostname); ++} ++ ++/* --- Fetch Image --- */ ++ ++int rc_api_init_fetch_image_request(rc_api_request_t* request, const rc_api_fetch_image_request_t* api_params) { ++ return rc_api_init_fetch_image_request_hosted(request, api_params, &g_host); ++} ++ ++int rc_api_init_fetch_image_request_hosted(rc_api_request_t* request, const rc_api_fetch_image_request_t* api_params, const rc_api_host_t* host) { ++ rc_api_url_builder_t builder; ++ ++ rc_buffer_init(&request->buffer); ++ rc_url_builder_init(&builder, &request->buffer, 64); ++ ++ if (host && host->media_host) { ++ /* custom media host provided */ ++ if (!strstr(host->host, "://")) ++ rc_url_builder_append(&builder, "http://", 7); ++ rc_url_builder_append(&builder, host->media_host, strlen(host->media_host)); ++ } ++ else if (host && host->host) { ++ if (strcmp(host->host, RETROACHIEVEMENTS_HOST_NONSSL) == 0) { ++ /* if host specifically set to non-ssl host, and no media host provided, use non-ssl media host */ ++ rc_url_builder_append(&builder, RETROACHIEVEMENTS_IMAGE_HOST_NONSSL, sizeof(RETROACHIEVEMENTS_IMAGE_HOST_NONSSL) - 1); ++ } ++ else if (strcmp(host->host, RETROACHIEVEMENTS_HOST) == 0) { ++ /* if host specifically set to ssl host, and no media host provided, use media host */ ++ rc_url_builder_append(&builder, RETROACHIEVEMENTS_IMAGE_HOST, sizeof(RETROACHIEVEMENTS_IMAGE_HOST) - 1); ++ } ++ else { ++ /* custom host and no media host provided. assume custom host is also media host */ ++ if (!strstr(host->host, "://")) ++ rc_url_builder_append(&builder, "http://", 7); ++ rc_url_builder_append(&builder, host->host, strlen(host->host)); ++ } ++ } ++ else { ++ /* no custom host provided */ ++ rc_url_builder_append(&builder, RETROACHIEVEMENTS_IMAGE_HOST, sizeof(RETROACHIEVEMENTS_IMAGE_HOST) - 1); ++ } ++ ++ switch (api_params->image_type) ++ { ++ case RC_IMAGE_TYPE_GAME: ++ rc_url_builder_append(&builder, "/Images/", 8); ++ rc_url_builder_append(&builder, api_params->image_name, strlen(api_params->image_name)); ++ rc_url_builder_append(&builder, ".png", 4); ++ break; ++ ++ case RC_IMAGE_TYPE_ACHIEVEMENT: ++ rc_url_builder_append(&builder, "/Badge/", 7); ++ rc_url_builder_append(&builder, api_params->image_name, strlen(api_params->image_name)); ++ rc_url_builder_append(&builder, ".png", 4); ++ break; ++ ++ case RC_IMAGE_TYPE_ACHIEVEMENT_LOCKED: ++ rc_url_builder_append(&builder, "/Badge/", 7); ++ rc_url_builder_append(&builder, api_params->image_name, strlen(api_params->image_name)); ++ rc_url_builder_append(&builder, "_lock.png", 9); ++ break; ++ ++ case RC_IMAGE_TYPE_USER: ++ rc_url_builder_append(&builder, "/UserPic/", 9); ++ rc_url_builder_append(&builder, api_params->image_name, strlen(api_params->image_name)); ++ rc_url_builder_append(&builder, ".png", 4); ++ break; ++ ++ default: ++ return RC_INVALID_STATE; ++ } ++ ++ request->url = rc_url_builder_finalize(&builder); ++ request->post_data = NULL; ++ ++ return builder.result; ++} ++ ++const char* rc_api_build_avatar_url(rc_buffer_t* buffer, uint32_t image_type, const char* image_name) { ++ rc_api_fetch_image_request_t image_request; ++ rc_api_request_t request; ++ int result; ++ ++ memset(&image_request, 0, sizeof(image_request)); ++ image_request.image_type = image_type; ++ image_request.image_name = image_name; ++ ++ result = rc_api_init_fetch_image_request(&request, &image_request); ++ if (result == RC_OK) ++ return rc_buffer_strcpy(buffer, request.url); ++ ++ return NULL; ++} +diff -rupbN melonDS.orig/src/rcheevos/src/rapi/rc_api_common.h melonDS.ra/src/rcheevos/src/rapi/rc_api_common.h +--- melonDS.orig/src/rcheevos/src/rapi/rc_api_common.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rapi/rc_api_common.h 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,88 @@ ++#ifndef RC_API_COMMON_H ++#define RC_API_COMMON_H ++ ++#include "rc_api_request.h" ++ ++#include ++#include ++ ++RC_BEGIN_C_DECLS ++ ++#define RC_CONTENT_TYPE_URLENCODED "application/x-www-form-urlencoded" ++ ++typedef struct rc_api_url_builder_t { ++ char* write; ++ char* start; ++ char* end; ++ /* pointer to a preallocated rc_buffer_t */ ++ rc_buffer_t* buffer; ++ int result; ++} ++rc_api_url_builder_t; ++ ++void rc_url_builder_init(rc_api_url_builder_t* builder, rc_buffer_t* buffer, size_t estimated_size); ++void rc_url_builder_append(rc_api_url_builder_t* builder, const char* data, size_t len); ++const char* rc_url_builder_finalize(rc_api_url_builder_t* builder); ++ ++extern rc_api_host_t g_host; ++ ++#define RC_JSON_NEW_FIELD(n) {NULL,NULL,n,sizeof(n)-1,0} ++ ++typedef struct rc_json_field_t { ++ const char* value_start; ++ const char* value_end; ++ const char* name; ++ size_t name_len; ++ uint32_t array_size; ++} ++rc_json_field_t; ++ ++typedef struct rc_json_iterator_t { ++ const char* json; ++ const char* end; ++} ++rc_json_iterator_t; ++ ++int rc_json_parse_server_response(rc_api_response_t* response, const rc_api_server_response_t* server_response, rc_json_field_t* fields, size_t field_count); ++int rc_json_get_string(const char** out, rc_buffer_t* buffer, const rc_json_field_t* field, const char* field_name); ++int rc_json_get_num(int32_t* out, const rc_json_field_t* field, const char* field_name); ++int rc_json_get_unum(uint32_t* out, const rc_json_field_t* field, const char* field_name); ++int rc_json_get_float(float* out, const rc_json_field_t* field, const char* field_name); ++int rc_json_get_bool(int* out, const rc_json_field_t* field, const char* field_name); ++int rc_json_get_datetime(time_t* out, const rc_json_field_t* field, const char* field_name); ++void rc_json_get_optional_string(const char** out, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name, const char* default_value); ++void rc_json_get_optional_num(int32_t* out, const rc_json_field_t* field, const char* field_name, int default_value); ++void rc_json_get_optional_unum(uint32_t* out, const rc_json_field_t* field, const char* field_name, uint32_t default_value); ++void rc_json_get_optional_float(float* out, const rc_json_field_t* field, const char* field_name, float default_value); ++void rc_json_get_optional_bool(int* out, const rc_json_field_t* field, const char* field_name, int default_value); ++int rc_json_get_optional_array(uint32_t* num_entries, rc_json_field_t* iterator, const rc_json_field_t* field, const char* field_name); ++int rc_json_get_required_string(const char** out, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name); ++int rc_json_get_required_num(int32_t* out, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name); ++int rc_json_get_required_unum(uint32_t* out, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name); ++int rc_json_get_required_float(float* out, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name); ++int rc_json_get_required_bool(int* out, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name); ++int rc_json_get_required_datetime(time_t* out, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name); ++int rc_json_get_required_object(rc_json_field_t* fields, size_t field_count, rc_api_response_t* response, rc_json_field_t* field, const char* field_name); ++int rc_json_get_required_unum_array(uint32_t** entries, uint32_t* num_entries, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name); ++int rc_json_get_required_array(uint32_t* num_entries, rc_json_field_t* array_field, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name); ++int rc_json_get_array_entry_object(rc_json_field_t* fields, size_t field_count, rc_json_iterator_t* iterator); ++int rc_json_get_next_object_field(rc_json_iterator_t* iterator, rc_json_field_t* field); ++int rc_json_get_object_string_length(const char* json); ++int rc_json_field_string_matches(const rc_json_field_t* field, const char* text); ++ ++void rc_json_extract_filename(rc_json_field_t* field); ++ ++void rc_url_builder_append_encoded_str(rc_api_url_builder_t* builder, const char* str); ++void rc_url_builder_append_num_param(rc_api_url_builder_t* builder, const char* param, int32_t value); ++void rc_url_builder_append_unum_param(rc_api_url_builder_t* builder, const char* param, uint32_t value); ++void rc_url_builder_append_str_param(rc_api_url_builder_t* builder, const char* param, const char* value); ++ ++const char* rc_api_default_host(void); ++void rc_api_url_build_dorequest_url(rc_api_request_t* request, const rc_api_host_t* host); ++int rc_api_url_build_dorequest(rc_api_url_builder_t* builder, const char* api, const char* username, const char* api_token); ++ ++const char* rc_api_build_avatar_url(rc_buffer_t* buffer, uint32_t image_type, const char* image_name); ++ ++RC_END_C_DECLS ++ ++#endif /* RC_API_COMMON_H */ +diff -rupbN melonDS.orig/src/rcheevos/src/rapi/rc_api_editor.c melonDS.ra/src/rcheevos/src/rapi/rc_api_editor.c +--- melonDS.orig/src/rcheevos/src/rapi/rc_api_editor.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rapi/rc_api_editor.c 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,625 @@ ++#include "rc_api_editor.h" ++#include "rc_api_common.h" ++#include "rc_api_runtime.h" ++ ++#include "../rc_compat.h" ++#include "../rhash/md5.h" ++ ++#include ++#include ++ ++/* --- Fetch Code Notes --- */ ++ ++int rc_api_init_fetch_code_notes_request(rc_api_request_t* request, const rc_api_fetch_code_notes_request_t* api_params) { ++ return rc_api_init_fetch_code_notes_request_hosted(request, api_params, &g_host); ++} ++ ++int rc_api_init_fetch_code_notes_request_hosted(rc_api_request_t* request, ++ const rc_api_fetch_code_notes_request_t* api_params, ++ const rc_api_host_t* host) { ++ rc_api_url_builder_t builder; ++ ++ rc_api_url_build_dorequest_url(request, host); ++ ++ if (api_params->game_id == 0) ++ return RC_INVALID_STATE; ++ ++ rc_url_builder_init(&builder, &request->buffer, 48); ++ rc_url_builder_append_str_param(&builder, "r", "codenotes2"); ++ rc_url_builder_append_unum_param(&builder, "g", api_params->game_id); ++ ++ request->post_data = rc_url_builder_finalize(&builder); ++ request->content_type = RC_CONTENT_TYPE_URLENCODED; ++ ++ return builder.result; ++} ++ ++int rc_api_process_fetch_code_notes_response(rc_api_fetch_code_notes_response_t* response, const char* server_response) { ++ rc_api_server_response_t response_obj; ++ ++ memset(&response_obj, 0, sizeof(response_obj)); ++ response_obj.body = server_response; ++ response_obj.body_length = rc_json_get_object_string_length(server_response); ++ ++ return rc_api_process_fetch_code_notes_server_response(response, &response_obj); ++} ++ ++int rc_api_process_fetch_code_notes_server_response(rc_api_fetch_code_notes_response_t* response, const rc_api_server_response_t* server_response) { ++ rc_json_field_t array_field; ++ rc_json_iterator_t iterator; ++ rc_api_code_note_t* note; ++ const char* address_str; ++ const char* last_author = ""; ++ size_t last_author_len = 0; ++ size_t len; ++ int result; ++ ++ rc_json_field_t fields[] = { ++ RC_JSON_NEW_FIELD("Success"), ++ RC_JSON_NEW_FIELD("Error"), ++ RC_JSON_NEW_FIELD("CodeNotes") ++ }; ++ ++ rc_json_field_t note_fields[] = { ++ RC_JSON_NEW_FIELD("Address"), ++ RC_JSON_NEW_FIELD("User"), ++ RC_JSON_NEW_FIELD("Note") ++ }; ++ ++ memset(response, 0, sizeof(*response)); ++ rc_buffer_init(&response->response.buffer); ++ ++ result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0])); ++ if (result != RC_OK || !response->response.succeeded) ++ return result; ++ ++ if (!rc_json_get_required_array(&response->num_notes, &array_field, &response->response, &fields[2], "CodeNotes")) ++ return RC_MISSING_VALUE; ++ ++ if (response->num_notes) { ++ response->notes = (rc_api_code_note_t*)rc_buffer_alloc(&response->response.buffer, response->num_notes * sizeof(rc_api_code_note_t)); ++ if (!response->notes) ++ return RC_OUT_OF_MEMORY; ++ ++ memset(&iterator, 0, sizeof(iterator)); ++ iterator.json = array_field.value_start; ++ iterator.end = array_field.value_end; ++ ++ note = response->notes; ++ while (rc_json_get_array_entry_object(note_fields, sizeof(note_fields) / sizeof(note_fields[0]), &iterator)) { ++ /* an empty note represents a record that was deleted on the server */ ++ /* a note set to '' also represents a deleted note (remnant of a bug) */ ++ /* NOTE: len will include the quotes */ ++ if (note_fields[2].value_start) { ++ len = note_fields[2].value_end - note_fields[2].value_start; ++ if (len == 2 || (len == 4 && note_fields[2].value_start[1] == '\'' && note_fields[2].value_start[2] == '\'')) { ++ --response->num_notes; ++ continue; ++ } ++ } ++ ++ if (!rc_json_get_required_string(&address_str, &response->response, ¬e_fields[0], "Address")) ++ return RC_MISSING_VALUE; ++ note->address = (uint32_t)strtoul(address_str, NULL, 16); ++ if (!rc_json_get_required_string(¬e->note, &response->response, ¬e_fields[2], "Note")) ++ return RC_MISSING_VALUE; ++ ++ len = note_fields[1].value_end - note_fields[1].value_start; ++ if (len == last_author_len && memcmp(note_fields[1].value_start, last_author, len) == 0) { ++ note->author = last_author; ++ } ++ else { ++ if (!rc_json_get_required_string(¬e->author, &response->response, ¬e_fields[1], "User")) ++ return RC_MISSING_VALUE; ++ ++ if (note->author == NULL) { ++ /* ensure we don't pass NULL out to client */ ++ last_author = note->author = ""; ++ last_author_len = 0; ++ } else { ++ last_author = note->author; ++ last_author_len = len; ++ } ++ } ++ ++ ++note; ++ } ++ } ++ ++ return RC_OK; ++} ++ ++void rc_api_destroy_fetch_code_notes_response(rc_api_fetch_code_notes_response_t* response) { ++ rc_buffer_destroy(&response->response.buffer); ++} ++ ++/* --- Update Code Note --- */ ++ ++int rc_api_init_update_code_note_request(rc_api_request_t* request, const rc_api_update_code_note_request_t* api_params) { ++ return rc_api_init_update_code_note_request_hosted(request, api_params, &g_host); ++} ++ ++int rc_api_init_update_code_note_request_hosted(rc_api_request_t* request, ++ const rc_api_update_code_note_request_t* api_params, ++ const rc_api_host_t* host) { ++ rc_api_url_builder_t builder; ++ ++ rc_api_url_build_dorequest_url(request, host); ++ ++ if (api_params->game_id == 0) ++ return RC_INVALID_STATE; ++ ++ rc_url_builder_init(&builder, &request->buffer, 128); ++ if (!rc_api_url_build_dorequest(&builder, "submitcodenote", api_params->username, api_params->api_token)) ++ return builder.result; ++ ++ rc_url_builder_append_unum_param(&builder, "g", api_params->game_id); ++ rc_url_builder_append_unum_param(&builder, "m", api_params->address); ++ ++ if (api_params->note && *api_params->note) ++ rc_url_builder_append_str_param(&builder, "n", api_params->note); ++ ++ request->post_data = rc_url_builder_finalize(&builder); ++ request->content_type = RC_CONTENT_TYPE_URLENCODED; ++ ++ return builder.result; ++} ++ ++int rc_api_process_update_code_note_response(rc_api_update_code_note_response_t* response, const char* server_response) { ++ rc_api_server_response_t response_obj; ++ ++ memset(&response_obj, 0, sizeof(response_obj)); ++ response_obj.body = server_response; ++ response_obj.body_length = rc_json_get_object_string_length(server_response); ++ ++ return rc_api_process_update_code_note_server_response(response, &response_obj); ++} ++ ++int rc_api_process_update_code_note_server_response(rc_api_update_code_note_response_t* response, const rc_api_server_response_t* server_response) { ++ int result; ++ ++ rc_json_field_t fields[] = { ++ RC_JSON_NEW_FIELD("Success"), ++ RC_JSON_NEW_FIELD("Error") ++ /* unused fields ++ RC_JSON_NEW_FIELD("GameID"), ++ RC_JSON_NEW_FIELD("Address"), ++ RC_JSON_NEW_FIELD("Note") ++ */ ++ }; ++ ++ memset(response, 0, sizeof(*response)); ++ rc_buffer_init(&response->response.buffer); ++ ++ result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0])); ++ if (result != RC_OK || !response->response.succeeded) ++ return result; ++ ++ return RC_OK; ++} ++ ++void rc_api_destroy_update_code_note_response(rc_api_update_code_note_response_t* response) { ++ rc_buffer_destroy(&response->response.buffer); ++} ++ ++/* --- Update Achievement --- */ ++ ++static const char* rc_type_string(uint32_t type) { ++ switch (type) { ++ case RC_ACHIEVEMENT_TYPE_MISSABLE: return "missable"; ++ case RC_ACHIEVEMENT_TYPE_PROGRESSION: return "progression"; ++ case RC_ACHIEVEMENT_TYPE_WIN: return "win_condition"; ++ default: return ""; ++ } ++} ++ ++int rc_api_init_update_achievement_request(rc_api_request_t* request, const rc_api_update_achievement_request_t* api_params) { ++ return rc_api_init_update_achievement_request_hosted(request, api_params, &g_host); ++} ++ ++int rc_api_init_update_achievement_request_hosted(rc_api_request_t* request, ++ const rc_api_update_achievement_request_t* api_params, ++ const rc_api_host_t* host) { ++ rc_api_url_builder_t builder; ++ char buffer[33]; ++ md5_state_t md5; ++ md5_byte_t hash[16]; ++ ++ rc_api_url_build_dorequest_url(request, host); ++ ++ if (api_params->game_id == 0 || api_params->category == 0) ++ return RC_INVALID_STATE; ++ if (!api_params->title || !*api_params->title) ++ return RC_INVALID_STATE; ++ if (!api_params->description || !*api_params->description) ++ return RC_INVALID_STATE; ++ if (!api_params->trigger || !*api_params->trigger) ++ return RC_INVALID_STATE; ++ ++ rc_url_builder_init(&builder, &request->buffer, 128); ++ if (!rc_api_url_build_dorequest(&builder, "uploadachievement", api_params->username, api_params->api_token)) ++ return builder.result; ++ ++ if (api_params->achievement_id) ++ rc_url_builder_append_unum_param(&builder, "a", api_params->achievement_id); ++ rc_url_builder_append_unum_param(&builder, "g", api_params->game_id); ++ rc_url_builder_append_str_param(&builder, "n", api_params->title); ++ rc_url_builder_append_str_param(&builder, "d", api_params->description); ++ rc_url_builder_append_str_param(&builder, "m", api_params->trigger); ++ rc_url_builder_append_unum_param(&builder, "z", api_params->points); ++ rc_url_builder_append_unum_param(&builder, "f", api_params->category); ++ if (api_params->badge) ++ rc_url_builder_append_str_param(&builder, "b", api_params->badge); ++ rc_url_builder_append_str_param(&builder, "x", rc_type_string(api_params->type)); ++ ++ /* Evaluate the signature. */ ++ md5_init(&md5); ++ md5_append(&md5, (md5_byte_t*)api_params->username, (int)strlen(api_params->username)); ++ md5_append(&md5, (md5_byte_t*)"SECRET", 6); ++ snprintf(buffer, sizeof(buffer), "%u", api_params->achievement_id); ++ md5_append(&md5, (md5_byte_t*)buffer, (int)strlen(buffer)); ++ md5_append(&md5, (md5_byte_t*)"SEC", 3); ++ md5_append(&md5, (md5_byte_t*)api_params->trigger, (int)strlen(api_params->trigger)); ++ snprintf(buffer, sizeof(buffer), "%u", api_params->points); ++ md5_append(&md5, (md5_byte_t*)buffer, (int)strlen(buffer)); ++ md5_append(&md5, (md5_byte_t*)"RE2", 3); ++ snprintf(buffer, sizeof(buffer), "%u", api_params->points * 3); ++ md5_append(&md5, (md5_byte_t*)buffer, (int)strlen(buffer)); ++ md5_finish(&md5, hash); ++ rc_format_md5(buffer, hash); ++ rc_url_builder_append_str_param(&builder, "h", buffer); ++ ++ request->post_data = rc_url_builder_finalize(&builder); ++ request->content_type = RC_CONTENT_TYPE_URLENCODED; ++ ++ return builder.result; ++} ++ ++int rc_api_process_update_achievement_response(rc_api_update_achievement_response_t* response, const char* server_response) { ++ rc_api_server_response_t response_obj; ++ ++ memset(&response_obj, 0, sizeof(response_obj)); ++ response_obj.body = server_response; ++ response_obj.body_length = rc_json_get_object_string_length(server_response); ++ ++ return rc_api_process_update_achievement_server_response(response, &response_obj); ++} ++ ++int rc_api_process_update_achievement_server_response(rc_api_update_achievement_response_t* response, const rc_api_server_response_t* server_response) { ++ int result; ++ ++ rc_json_field_t fields[] = { ++ RC_JSON_NEW_FIELD("Success"), ++ RC_JSON_NEW_FIELD("Error"), ++ RC_JSON_NEW_FIELD("AchievementID") ++ }; ++ ++ memset(response, 0, sizeof(*response)); ++ rc_buffer_init(&response->response.buffer); ++ ++ result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0])); ++ if (result != RC_OK || !response->response.succeeded) ++ return result; ++ ++ if (!rc_json_get_required_unum(&response->achievement_id, &response->response, &fields[2], "AchievementID")) ++ return RC_MISSING_VALUE; ++ ++ return RC_OK; ++} ++ ++void rc_api_destroy_update_achievement_response(rc_api_update_achievement_response_t* response) { ++ rc_buffer_destroy(&response->response.buffer); ++} ++ ++/* --- Update Leaderboard --- */ ++ ++int rc_api_init_update_leaderboard_request(rc_api_request_t* request, const rc_api_update_leaderboard_request_t* api_params) { ++ return rc_api_init_update_leaderboard_request_hosted(request, api_params, &g_host); ++} ++ ++int rc_api_init_update_leaderboard_request_hosted(rc_api_request_t* request, ++ const rc_api_update_leaderboard_request_t* api_params, ++ const rc_api_host_t* host) { ++ rc_api_url_builder_t builder; ++ char buffer[33]; ++ md5_state_t md5; ++ md5_byte_t hash[16]; ++ ++ rc_api_url_build_dorequest_url(request, host); ++ ++ if (api_params->game_id == 0) ++ return RC_INVALID_STATE; ++ if (!api_params->title || !*api_params->title) ++ return RC_INVALID_STATE; ++ if (!api_params->description) ++ return RC_INVALID_STATE; ++ if (!api_params->start_trigger || !*api_params->start_trigger) ++ return RC_INVALID_STATE; ++ if (!api_params->submit_trigger || !*api_params->submit_trigger) ++ return RC_INVALID_STATE; ++ if (!api_params->cancel_trigger || !*api_params->cancel_trigger) ++ return RC_INVALID_STATE; ++ if (!api_params->value_definition || !*api_params->value_definition) ++ return RC_INVALID_STATE; ++ if (!api_params->format || !*api_params->format) ++ return RC_INVALID_STATE; ++ ++ rc_url_builder_init(&builder, &request->buffer, 128); ++ if (!rc_api_url_build_dorequest(&builder, "uploadleaderboard", api_params->username, api_params->api_token)) ++ return builder.result; ++ ++ if (api_params->leaderboard_id) ++ rc_url_builder_append_unum_param(&builder, "i", api_params->leaderboard_id); ++ rc_url_builder_append_unum_param(&builder, "g", api_params->game_id); ++ rc_url_builder_append_str_param(&builder, "n", api_params->title); ++ rc_url_builder_append_str_param(&builder, "d", api_params->description); ++ rc_url_builder_append_str_param(&builder, "s", api_params->start_trigger); ++ rc_url_builder_append_str_param(&builder, "b", api_params->submit_trigger); ++ rc_url_builder_append_str_param(&builder, "c", api_params->cancel_trigger); ++ rc_url_builder_append_str_param(&builder, "l", api_params->value_definition); ++ rc_url_builder_append_num_param(&builder, "w", api_params->lower_is_better); ++ rc_url_builder_append_str_param(&builder, "f", api_params->format); ++ ++ /* Evaluate the signature. */ ++ md5_init(&md5); ++ md5_append(&md5, (md5_byte_t*)api_params->username, (int)strlen(api_params->username)); ++ md5_append(&md5, (md5_byte_t*)"SECRET", 6); ++ snprintf(buffer, sizeof(buffer), "%u", api_params->leaderboard_id); ++ md5_append(&md5, (md5_byte_t*)buffer, (int)strlen(buffer)); ++ md5_append(&md5, (md5_byte_t*)"SEC", 3); ++ md5_append(&md5, (md5_byte_t*)api_params->start_trigger, (int)strlen(api_params->start_trigger)); ++ md5_append(&md5, (md5_byte_t*)api_params->submit_trigger, (int)strlen(api_params->submit_trigger)); ++ md5_append(&md5, (md5_byte_t*)api_params->cancel_trigger, (int)strlen(api_params->cancel_trigger)); ++ md5_append(&md5, (md5_byte_t*)api_params->value_definition, (int)strlen(api_params->value_definition)); ++ md5_append(&md5, (md5_byte_t*)"RE2", 3); ++ md5_append(&md5, (md5_byte_t*)api_params->format, (int)strlen(api_params->format)); ++ md5_finish(&md5, hash); ++ rc_format_md5(buffer, hash); ++ rc_url_builder_append_str_param(&builder, "h", buffer); ++ ++ request->post_data = rc_url_builder_finalize(&builder); ++ request->content_type = RC_CONTENT_TYPE_URLENCODED; ++ ++ return builder.result; ++} ++ ++int rc_api_process_update_leaderboard_response(rc_api_update_leaderboard_response_t* response, const char* server_response) { ++ rc_api_server_response_t response_obj; ++ ++ memset(&response_obj, 0, sizeof(response_obj)); ++ response_obj.body = server_response; ++ response_obj.body_length = rc_json_get_object_string_length(server_response); ++ ++ return rc_api_process_update_leaderboard_server_response(response, &response_obj); ++} ++ ++int rc_api_process_update_leaderboard_server_response(rc_api_update_leaderboard_response_t* response, const rc_api_server_response_t* server_response) { ++ int result; ++ ++ rc_json_field_t fields[] = { ++ RC_JSON_NEW_FIELD("Success"), ++ RC_JSON_NEW_FIELD("Error"), ++ RC_JSON_NEW_FIELD("LeaderboardID") ++ }; ++ ++ memset(response, 0, sizeof(*response)); ++ rc_buffer_init(&response->response.buffer); ++ ++ result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0])); ++ if (result != RC_OK || !response->response.succeeded) ++ return result; ++ ++ if (!rc_json_get_required_unum(&response->leaderboard_id, &response->response, &fields[2], "LeaderboardID")) ++ return RC_MISSING_VALUE; ++ ++ return RC_OK; ++} ++ ++void rc_api_destroy_update_leaderboard_response(rc_api_update_leaderboard_response_t* response) { ++ rc_buffer_destroy(&response->response.buffer); ++} ++ ++/* --- Update Rich Presence --- */ ++ ++int rc_api_init_update_rich_presence_request(rc_api_request_t* request, const rc_api_update_rich_presence_request_t* api_params) { ++ return rc_api_init_update_rich_presence_request_hosted(request, api_params, &g_host); ++} ++ ++int rc_api_init_update_rich_presence_request_hosted(rc_api_request_t* request, ++ const rc_api_update_rich_presence_request_t* api_params, ++ const rc_api_host_t* host) { ++ rc_api_url_builder_t builder; ++ ++ rc_api_url_build_dorequest_url(request, host); ++ ++ if (api_params->game_id == 0) ++ return RC_INVALID_STATE; ++ if (!api_params->script) ++ return RC_INVALID_STATE; ++ ++ rc_url_builder_init(&builder, &request->buffer, 128); ++ if (!rc_api_url_build_dorequest(&builder, "submitrichpresence", api_params->username, api_params->api_token)) ++ return builder.result; ++ ++ rc_url_builder_append_unum_param(&builder, "g", api_params->game_id); ++ rc_url_builder_append_str_param(&builder, "d", api_params->script); ++ ++ request->post_data = rc_url_builder_finalize(&builder); ++ request->content_type = RC_CONTENT_TYPE_URLENCODED; ++ ++ return builder.result; ++} ++ ++int rc_api_process_update_rich_presence_server_response(rc_api_update_rich_presence_response_t* response, const rc_api_server_response_t* server_response) { ++ int result; ++ ++ rc_json_field_t fields[] = { ++ RC_JSON_NEW_FIELD("Success"), ++ RC_JSON_NEW_FIELD("Error"), ++ RC_JSON_NEW_FIELD("Code"), ++ }; ++ ++ memset(response, 0, sizeof(*response)); ++ rc_buffer_init(&response->response.buffer); ++ ++ result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0])); ++ if (result != RC_OK || !response->response.succeeded) ++ return result; ++ ++ return RC_OK; ++} ++ ++void rc_api_destroy_update_rich_presence_response(rc_api_update_rich_presence_response_t* response) { ++ rc_buffer_destroy(&response->response.buffer); ++} ++ ++/* --- Fetch Badge Range --- */ ++ ++int rc_api_init_fetch_badge_range_request(rc_api_request_t* request, const rc_api_fetch_badge_range_request_t* api_params) { ++ return rc_api_init_fetch_badge_range_request_hosted(request, api_params, &g_host); ++} ++ ++int rc_api_init_fetch_badge_range_request_hosted(rc_api_request_t* request, ++ const rc_api_fetch_badge_range_request_t* api_params, ++ const rc_api_host_t* host) { ++ rc_api_url_builder_t builder; ++ ++ rc_api_url_build_dorequest_url(request, host); ++ ++ rc_url_builder_init(&builder, &request->buffer, 48); ++ rc_url_builder_append_str_param(&builder, "r", "badgeiter"); ++ ++ request->post_data = rc_url_builder_finalize(&builder); ++ request->content_type = RC_CONTENT_TYPE_URLENCODED; ++ ++ (void)api_params; ++ ++ return builder.result; ++} ++ ++int rc_api_process_fetch_badge_range_response(rc_api_fetch_badge_range_response_t* response, const char* server_response) { ++ rc_api_server_response_t response_obj; ++ ++ memset(&response_obj, 0, sizeof(response_obj)); ++ response_obj.body = server_response; ++ response_obj.body_length = rc_json_get_object_string_length(server_response); ++ ++ return rc_api_process_fetch_badge_range_server_response(response, &response_obj); ++} ++ ++int rc_api_process_fetch_badge_range_server_response(rc_api_fetch_badge_range_response_t* response, const rc_api_server_response_t* server_response) { ++ int result; ++ ++ rc_json_field_t fields[] = { ++ RC_JSON_NEW_FIELD("Success"), ++ RC_JSON_NEW_FIELD("Error"), ++ RC_JSON_NEW_FIELD("FirstBadge"), ++ RC_JSON_NEW_FIELD("NextBadge") ++ }; ++ ++ memset(response, 0, sizeof(*response)); ++ rc_buffer_init(&response->response.buffer); ++ ++ result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0])); ++ if (result != RC_OK || !response->response.succeeded) ++ return result; ++ ++ if (!rc_json_get_required_unum(&response->first_badge_id, &response->response, &fields[2], "FirstBadge")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_unum(&response->next_badge_id, &response->response, &fields[3], "NextBadge")) ++ return RC_MISSING_VALUE; ++ ++ return RC_OK; ++} ++ ++void rc_api_destroy_fetch_badge_range_response(rc_api_fetch_badge_range_response_t* response) { ++ rc_buffer_destroy(&response->response.buffer); ++} ++ ++/* --- Add Game Hash --- */ ++ ++int rc_api_init_add_game_hash_request(rc_api_request_t* request, const rc_api_add_game_hash_request_t* api_params) { ++ return rc_api_init_add_game_hash_request_hosted(request, api_params, &g_host); ++} ++ ++int rc_api_init_add_game_hash_request_hosted(rc_api_request_t* request, ++ const rc_api_add_game_hash_request_t* api_params, ++ const rc_api_host_t* host) { ++ rc_api_url_builder_t builder; ++ ++ rc_api_url_build_dorequest_url(request, host); ++ ++ if (api_params->console_id == 0) ++ return RC_INVALID_STATE; ++ if (!api_params->hash || !*api_params->hash) ++ return RC_INVALID_STATE; ++ if (api_params->game_id == 0 && (!api_params->title || !*api_params->title)) ++ return RC_INVALID_STATE; ++ ++ rc_url_builder_init(&builder, &request->buffer, 128); ++ if (!rc_api_url_build_dorequest(&builder, "submitgametitle", api_params->username, api_params->api_token)) ++ return builder.result; ++ ++ rc_url_builder_append_unum_param(&builder, "c", api_params->console_id); ++ rc_url_builder_append_str_param(&builder, "m", api_params->hash); ++ if (api_params->title) ++ rc_url_builder_append_str_param(&builder, "i", api_params->title); ++ if (api_params->game_id) ++ rc_url_builder_append_unum_param(&builder, "g", api_params->game_id); ++ if (api_params->hash_description && *api_params->hash_description) ++ rc_url_builder_append_str_param(&builder, "d", api_params->hash_description); ++ ++ request->post_data = rc_url_builder_finalize(&builder); ++ request->content_type = RC_CONTENT_TYPE_URLENCODED; ++ ++ return builder.result; ++} ++ ++int rc_api_process_add_game_hash_response(rc_api_add_game_hash_response_t* response, const char* server_response) { ++ rc_api_server_response_t response_obj; ++ ++ memset(&response_obj, 0, sizeof(response_obj)); ++ response_obj.body = server_response; ++ response_obj.body_length = rc_json_get_object_string_length(server_response); ++ ++ return rc_api_process_add_game_hash_server_response(response, &response_obj); ++} ++ ++int rc_api_process_add_game_hash_server_response(rc_api_add_game_hash_response_t* response, const rc_api_server_response_t* server_response) { ++ int result; ++ ++ rc_json_field_t fields[] = { ++ RC_JSON_NEW_FIELD("Success"), ++ RC_JSON_NEW_FIELD("Error"), ++ RC_JSON_NEW_FIELD("Response") ++ }; ++ ++ rc_json_field_t response_fields[] = { ++ RC_JSON_NEW_FIELD("GameID") ++ /* unused fields ++ RC_JSON_NEW_FIELD("MD5"), ++ RC_JSON_NEW_FIELD("ConsoleID"), ++ RC_JSON_NEW_FIELD("GameTitle"), ++ RC_JSON_NEW_FIELD("Success") ++ */ ++ }; ++ ++ memset(response, 0, sizeof(*response)); ++ rc_buffer_init(&response->response.buffer); ++ ++ result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0])); ++ if (result != RC_OK || !response->response.succeeded) ++ return result; ++ ++ if (!rc_json_get_required_object(response_fields, sizeof(response_fields) / sizeof(response_fields[0]), &response->response, &fields[2], "Response")) ++ return RC_MISSING_VALUE; ++ ++ if (!rc_json_get_required_unum(&response->game_id, &response->response, &response_fields[0], "GameID")) ++ return RC_MISSING_VALUE; ++ ++ return RC_OK; ++} ++ ++void rc_api_destroy_add_game_hash_response(rc_api_add_game_hash_response_t* response) { ++ rc_buffer_destroy(&response->response.buffer); ++} +diff -rupbN melonDS.orig/src/rcheevos/src/rapi/rc_api_info.c melonDS.ra/src/rcheevos/src/rapi/rc_api_info.c +--- melonDS.orig/src/rcheevos/src/rapi/rc_api_info.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rapi/rc_api_info.c 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,582 @@ ++#include "rc_api_info.h" ++#include "rc_api_common.h" ++#include "rc_api_runtime.h" ++ ++#include "rc_runtime_types.h" ++ ++#include "../rc_compat.h" ++ ++#include ++#include ++ ++/* --- Fetch Achievement Info --- */ ++ ++int rc_api_init_fetch_achievement_info_request(rc_api_request_t* request, const rc_api_fetch_achievement_info_request_t* api_params) { ++ return rc_api_init_fetch_achievement_info_request_hosted(request, api_params, &g_host); ++} ++ ++int rc_api_init_fetch_achievement_info_request_hosted(rc_api_request_t* request, ++ const rc_api_fetch_achievement_info_request_t* api_params, ++ const rc_api_host_t* host) { ++ rc_api_url_builder_t builder; ++ ++ rc_api_url_build_dorequest_url(request, host); ++ ++ if (api_params->achievement_id == 0) ++ return RC_INVALID_STATE; ++ ++ rc_url_builder_init(&builder, &request->buffer, 48); ++ if (rc_api_url_build_dorequest(&builder, "achievementwondata", api_params->username, api_params->api_token)) { ++ rc_url_builder_append_unum_param(&builder, "a", api_params->achievement_id); ++ ++ if (api_params->friends_only) ++ rc_url_builder_append_unum_param(&builder, "f", 1); ++ if (api_params->first_entry > 1) ++ rc_url_builder_append_unum_param(&builder, "o", api_params->first_entry - 1); /* number of entries to skip */ ++ rc_url_builder_append_unum_param(&builder, "c", api_params->count); ++ ++ request->post_data = rc_url_builder_finalize(&builder); ++ request->content_type = RC_CONTENT_TYPE_URLENCODED; ++ } ++ ++ return builder.result; ++} ++ ++int rc_api_process_fetch_achievement_info_response(rc_api_fetch_achievement_info_response_t* response, const char* server_response) { ++ rc_api_server_response_t response_obj; ++ ++ memset(&response_obj, 0, sizeof(response_obj)); ++ response_obj.body = server_response; ++ response_obj.body_length = rc_json_get_object_string_length(server_response); ++ ++ return rc_api_process_fetch_achievement_info_server_response(response, &response_obj); ++} ++ ++int rc_api_process_fetch_achievement_info_server_response(rc_api_fetch_achievement_info_response_t* response, const rc_api_server_response_t* server_response) { ++ rc_api_achievement_awarded_entry_t* entry; ++ rc_json_field_t array_field; ++ rc_json_iterator_t iterator; ++ uint32_t timet; ++ int result; ++ ++ rc_json_field_t fields[] = { ++ RC_JSON_NEW_FIELD("Success"), ++ RC_JSON_NEW_FIELD("Error"), ++ RC_JSON_NEW_FIELD("AchievementID"), ++ RC_JSON_NEW_FIELD("Response") ++ /* unused fields ++ RC_JSON_NEW_FIELD("Offset"), ++ RC_JSON_NEW_FIELD("Count"), ++ RC_JSON_NEW_FIELD("FriendsOnly") ++ * unused fields */ ++ }; ++ ++ rc_json_field_t response_fields[] = { ++ RC_JSON_NEW_FIELD("NumEarned"), ++ RC_JSON_NEW_FIELD("TotalPlayers"), ++ RC_JSON_NEW_FIELD("GameID"), ++ RC_JSON_NEW_FIELD("RecentWinner") /* array */ ++ }; ++ ++ rc_json_field_t entry_fields[] = { ++ RC_JSON_NEW_FIELD("User"), ++ RC_JSON_NEW_FIELD("DateAwarded"), ++ RC_JSON_NEW_FIELD("AvatarUrl") ++ }; ++ ++ memset(response, 0, sizeof(*response)); ++ rc_buffer_init(&response->response.buffer); ++ ++ result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0])); ++ if (result != RC_OK) ++ return result; ++ ++ if (!rc_json_get_required_unum(&response->id, &response->response, &fields[2], "AchievementID")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_object(response_fields, sizeof(response_fields) / sizeof(response_fields[0]), &response->response, &fields[3], "Response")) ++ return RC_MISSING_VALUE; ++ ++ if (!rc_json_get_required_unum(&response->num_awarded, &response->response, &response_fields[0], "NumEarned")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_unum(&response->num_players, &response->response, &response_fields[1], "TotalPlayers")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_unum(&response->game_id, &response->response, &response_fields[2], "GameID")) ++ return RC_MISSING_VALUE; ++ ++ if (!rc_json_get_required_array(&response->num_recently_awarded, &array_field, &response->response, &response_fields[3], "RecentWinner")) ++ return RC_MISSING_VALUE; ++ ++ if (response->num_recently_awarded) { ++ response->recently_awarded = (rc_api_achievement_awarded_entry_t*)rc_buffer_alloc(&response->response.buffer, response->num_recently_awarded * sizeof(rc_api_achievement_awarded_entry_t)); ++ if (!response->recently_awarded) ++ return RC_OUT_OF_MEMORY; ++ ++ memset(&iterator, 0, sizeof(iterator)); ++ iterator.json = array_field.value_start; ++ iterator.end = array_field.value_end; ++ ++ entry = response->recently_awarded; ++ while (rc_json_get_array_entry_object(entry_fields, sizeof(entry_fields) / sizeof(entry_fields[0]), &iterator)) { ++ if (!rc_json_get_required_string(&entry->username, &response->response, &entry_fields[0], "User")) ++ return RC_MISSING_VALUE; ++ ++ if (!rc_json_get_required_unum(&timet, &response->response, &entry_fields[1], "DateAwarded")) ++ return RC_MISSING_VALUE; ++ entry->awarded = (time_t)timet; ++ ++ rc_json_get_optional_string(&entry->avatar_url, &response->response, &entry_fields[2], "AvatarUrl", NULL); ++ if (!entry->avatar_url) ++ entry->avatar_url = rc_api_build_avatar_url(&response->response.buffer, RC_IMAGE_TYPE_USER, entry->username); ++ ++ ++entry; ++ } ++ } ++ ++ return RC_OK; ++} ++ ++void rc_api_destroy_fetch_achievement_info_response(rc_api_fetch_achievement_info_response_t* response) { ++ rc_buffer_destroy(&response->response.buffer); ++} ++ ++/* --- Fetch Leaderboard Info --- */ ++ ++int rc_api_init_fetch_leaderboard_info_request(rc_api_request_t* request, const rc_api_fetch_leaderboard_info_request_t* api_params) { ++ return rc_api_init_fetch_leaderboard_info_request_hosted(request, api_params, &g_host); ++} ++ ++int rc_api_init_fetch_leaderboard_info_request_hosted(rc_api_request_t* request, ++ const rc_api_fetch_leaderboard_info_request_t* api_params, ++ const rc_api_host_t* host) { ++ rc_api_url_builder_t builder; ++ ++ rc_api_url_build_dorequest_url(request, host); ++ ++ if (api_params->leaderboard_id == 0) ++ return RC_INVALID_STATE; ++ ++ rc_url_builder_init(&builder, &request->buffer, 48); ++ rc_url_builder_append_str_param(&builder, "r", "lbinfo"); ++ rc_url_builder_append_unum_param(&builder, "i", api_params->leaderboard_id); ++ ++ if (api_params->username) ++ rc_url_builder_append_str_param(&builder, "u", api_params->username); ++ else if (api_params->first_entry > 1) ++ rc_url_builder_append_unum_param(&builder, "o", api_params->first_entry - 1); /* number of entries to skip */ ++ ++ rc_url_builder_append_unum_param(&builder, "c", api_params->count); ++ request->post_data = rc_url_builder_finalize(&builder); ++ request->content_type = RC_CONTENT_TYPE_URLENCODED; ++ ++ return builder.result; ++} ++ ++int rc_api_process_fetch_leaderboard_info_response(rc_api_fetch_leaderboard_info_response_t* response, const char* server_response) { ++ rc_api_server_response_t response_obj; ++ ++ memset(&response_obj, 0, sizeof(response_obj)); ++ response_obj.body = server_response; ++ response_obj.body_length = rc_json_get_object_string_length(server_response); ++ ++ return rc_api_process_fetch_leaderboard_info_server_response(response, &response_obj); ++} ++ ++int rc_api_process_fetch_leaderboard_info_server_response(rc_api_fetch_leaderboard_info_response_t* response, const rc_api_server_response_t* server_response) { ++ rc_api_lboard_info_entry_t* entry; ++ rc_json_field_t array_field; ++ rc_json_iterator_t iterator; ++ uint32_t timet; ++ int result; ++ size_t len; ++ char format[16]; ++ ++ rc_json_field_t fields[] = { ++ RC_JSON_NEW_FIELD("Success"), ++ RC_JSON_NEW_FIELD("Error"), ++ RC_JSON_NEW_FIELD("LeaderboardData") ++ }; ++ ++ rc_json_field_t leaderboarddata_fields[] = { ++ RC_JSON_NEW_FIELD("LBID"), ++ RC_JSON_NEW_FIELD("LBFormat"), ++ RC_JSON_NEW_FIELD("LowerIsBetter"), ++ RC_JSON_NEW_FIELD("LBTitle"), ++ RC_JSON_NEW_FIELD("LBDesc"), ++ RC_JSON_NEW_FIELD("LBMem"), ++ RC_JSON_NEW_FIELD("GameID"), ++ RC_JSON_NEW_FIELD("LBAuthor"), ++ RC_JSON_NEW_FIELD("LBCreated"), ++ RC_JSON_NEW_FIELD("LBUpdated"), ++ RC_JSON_NEW_FIELD("Entries"), /* array */ ++ RC_JSON_NEW_FIELD("TotalEntries") ++ }; ++ ++ rc_json_field_t entry_fields[] = { ++ RC_JSON_NEW_FIELD("User"), ++ RC_JSON_NEW_FIELD("Rank"), ++ RC_JSON_NEW_FIELD("Index"), ++ RC_JSON_NEW_FIELD("Score"), ++ RC_JSON_NEW_FIELD("DateSubmitted"), ++ RC_JSON_NEW_FIELD("AvatarUrl") ++ }; ++ ++ memset(response, 0, sizeof(*response)); ++ rc_buffer_init(&response->response.buffer); ++ ++ result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0])); ++ if (result != RC_OK) ++ return result; ++ ++ if (!rc_json_get_required_object(leaderboarddata_fields, sizeof(leaderboarddata_fields) / sizeof(leaderboarddata_fields[0]), &response->response, &fields[2], "LeaderboardData")) ++ return RC_MISSING_VALUE; ++ ++ if (!rc_json_get_required_unum(&response->id, &response->response, &leaderboarddata_fields[0], "LBID")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_unum(&response->lower_is_better, &response->response, &leaderboarddata_fields[2], "LowerIsBetter")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_string(&response->title, &response->response, &leaderboarddata_fields[3], "LBTitle")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_string(&response->description, &response->response, &leaderboarddata_fields[4], "LBDesc")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_string(&response->definition, &response->response, &leaderboarddata_fields[5], "LBMem")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_unum(&response->game_id, &response->response, &leaderboarddata_fields[6], "GameID")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_string(&response->author, &response->response, &leaderboarddata_fields[7], "LBAuthor")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_datetime(&response->created, &response->response, &leaderboarddata_fields[8], "LBCreated")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_datetime(&response->updated, &response->response, &leaderboarddata_fields[9], "LBUpdated")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_unum(&response->total_entries, &response->response, &leaderboarddata_fields[11], "TotalEntries")) ++ return RC_MISSING_VALUE; ++ ++ if (!leaderboarddata_fields[1].value_end) ++ return RC_MISSING_VALUE; ++ len = leaderboarddata_fields[1].value_end - leaderboarddata_fields[1].value_start - 2; ++ if (len < sizeof(format) - 1) { ++ memcpy(format, leaderboarddata_fields[1].value_start + 1, len); ++ format[len] = '\0'; ++ response->format = rc_parse_format(format); ++ } ++ else { ++ response->format = RC_FORMAT_VALUE; ++ } ++ ++ if (!rc_json_get_required_array(&response->num_entries, &array_field, &response->response, &leaderboarddata_fields[10], "Entries")) ++ return RC_MISSING_VALUE; ++ ++ if (response->num_entries) { ++ response->entries = (rc_api_lboard_info_entry_t*)rc_buffer_alloc(&response->response.buffer, response->num_entries * sizeof(rc_api_lboard_info_entry_t)); ++ if (!response->entries) ++ return RC_OUT_OF_MEMORY; ++ ++ memset(&iterator, 0, sizeof(iterator)); ++ iterator.json = array_field.value_start; ++ iterator.end = array_field.value_end; ++ ++ entry = response->entries; ++ while (rc_json_get_array_entry_object(entry_fields, sizeof(entry_fields) / sizeof(entry_fields[0]), &iterator)) { ++ if (!rc_json_get_required_string(&entry->username, &response->response, &entry_fields[0], "User")) ++ return RC_MISSING_VALUE; ++ ++ if (!rc_json_get_required_unum(&entry->rank, &response->response, &entry_fields[1], "Rank")) ++ return RC_MISSING_VALUE; ++ ++ if (!rc_json_get_required_unum(&entry->index, &response->response, &entry_fields[2], "Index")) ++ return RC_MISSING_VALUE; ++ ++ if (!rc_json_get_required_num(&entry->score, &response->response, &entry_fields[3], "Score")) ++ return RC_MISSING_VALUE; ++ ++ if (!rc_json_get_required_unum(&timet, &response->response, &entry_fields[4], "DateSubmitted")) ++ return RC_MISSING_VALUE; ++ entry->submitted = (time_t)timet; ++ ++ rc_json_get_optional_string(&entry->avatar_url, &response->response, &entry_fields[5], "AvatarUrl", NULL); ++ if (!entry->avatar_url) ++ entry->avatar_url = rc_api_build_avatar_url(&response->response.buffer, RC_IMAGE_TYPE_USER, entry->username); ++ ++ ++entry; ++ } ++ } ++ ++ return RC_OK; ++} ++ ++void rc_api_destroy_fetch_leaderboard_info_response(rc_api_fetch_leaderboard_info_response_t* response) { ++ rc_buffer_destroy(&response->response.buffer); ++} ++ ++/* --- Fetch Games List --- */ ++ ++int rc_api_init_fetch_games_list_request(rc_api_request_t* request, const rc_api_fetch_games_list_request_t* api_params) { ++ return rc_api_init_fetch_games_list_request_hosted(request, api_params, &g_host); ++} ++ ++int rc_api_init_fetch_games_list_request_hosted(rc_api_request_t* request, ++ const rc_api_fetch_games_list_request_t* api_params, ++ const rc_api_host_t* host) { ++ rc_api_url_builder_t builder; ++ ++ rc_api_url_build_dorequest_url(request, host); ++ ++ if (api_params->console_id == 0) ++ return RC_INVALID_STATE; ++ ++ rc_url_builder_init(&builder, &request->buffer, 48); ++ rc_url_builder_append_str_param(&builder, "r", "gameslist"); ++ rc_url_builder_append_unum_param(&builder, "c", api_params->console_id); ++ ++ request->post_data = rc_url_builder_finalize(&builder); ++ request->content_type = RC_CONTENT_TYPE_URLENCODED; ++ ++ return builder.result; ++} ++ ++int rc_api_process_fetch_games_list_response(rc_api_fetch_games_list_response_t* response, const char* server_response) { ++ rc_api_server_response_t response_obj; ++ ++ memset(&response_obj, 0, sizeof(response_obj)); ++ response_obj.body = server_response; ++ response_obj.body_length = rc_json_get_object_string_length(server_response); ++ ++ return rc_api_process_fetch_games_list_server_response(response, &response_obj); ++} ++ ++int rc_api_process_fetch_games_list_server_response(rc_api_fetch_games_list_response_t* response, const rc_api_server_response_t* server_response) { ++ rc_api_game_list_entry_t* entry; ++ rc_json_iterator_t iterator; ++ rc_json_field_t field; ++ int result; ++ char* end; ++ ++ rc_json_field_t fields[] = { ++ RC_JSON_NEW_FIELD("Success"), ++ RC_JSON_NEW_FIELD("Error"), ++ RC_JSON_NEW_FIELD("Response") ++ }; ++ ++ memset(response, 0, sizeof(*response)); ++ rc_buffer_init(&response->response.buffer); ++ ++ result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0])); ++ if (result != RC_OK) ++ return result; ++ ++ if (!fields[2].value_start) { ++ /* call rc_json_get_required_object to generate the error message */ ++ rc_json_get_required_object(NULL, 0, &response->response, &fields[2], "Response"); ++ return RC_MISSING_VALUE; ++ } ++ ++ response->num_entries = fields[2].array_size; ++ rc_buffer_reserve(&response->response.buffer, response->num_entries * (32 + sizeof(rc_api_game_list_entry_t))); ++ ++ response->entries = (rc_api_game_list_entry_t*)rc_buffer_alloc(&response->response.buffer, response->num_entries * sizeof(rc_api_game_list_entry_t)); ++ if (!response->entries) ++ return RC_OUT_OF_MEMORY; ++ ++ memset(&iterator, 0, sizeof(iterator)); ++ iterator.json = fields[2].value_start; ++ iterator.end = fields[2].value_end; ++ ++ entry = response->entries; ++ while (rc_json_get_next_object_field(&iterator, &field)) { ++ entry->id = strtol(field.name, &end, 10); ++ ++ field.name = ""; ++ if (!rc_json_get_string(&entry->name, &response->response.buffer, &field, "")) ++ return RC_MISSING_VALUE; ++ ++ ++entry; ++ } ++ ++ return RC_OK; ++} ++ ++void rc_api_destroy_fetch_games_list_response(rc_api_fetch_games_list_response_t* response) { ++ rc_buffer_destroy(&response->response.buffer); ++} ++ ++/* --- Fetch Game Titles --- */ ++ ++int rc_api_init_fetch_game_titles_request(rc_api_request_t* request, const rc_api_fetch_game_titles_request_t* api_params) { ++ return rc_api_init_fetch_game_titles_request_hosted(request, api_params, &g_host); ++} ++ ++int rc_api_init_fetch_game_titles_request_hosted(rc_api_request_t* request, ++ const rc_api_fetch_game_titles_request_t* api_params, ++ const rc_api_host_t* host) { ++ rc_api_url_builder_t builder; ++ char num[16]; ++ uint32_t i; ++ ++ rc_api_url_build_dorequest_url(request, host); ++ ++ if (api_params->num_game_ids == 0) ++ return RC_INVALID_STATE; ++ ++ rc_url_builder_init(&builder, &request->buffer, 48); ++ rc_url_builder_append_str_param(&builder, "r", "gameinfolist"); ++ rc_url_builder_append_unum_param(&builder, "g", api_params->game_ids[0]); ++ ++ for (i = 1; i < api_params->num_game_ids; i++) { ++ int chars = snprintf(num, sizeof(num), "%u", api_params->game_ids[i]); ++ rc_url_builder_append(&builder, ",", 1); ++ rc_url_builder_append(&builder, num, chars); ++ } ++ ++ request->post_data = rc_url_builder_finalize(&builder); ++ request->content_type = RC_CONTENT_TYPE_URLENCODED; ++ ++ return builder.result; ++} ++ ++int rc_api_process_fetch_game_titles_server_response(rc_api_fetch_game_titles_response_t* response, const rc_api_server_response_t* server_response) { ++ rc_api_game_title_entry_t* entry; ++ rc_json_iterator_t iterator; ++ rc_json_field_t array_field; ++ int result; ++ ++ rc_json_field_t fields[] = { ++ RC_JSON_NEW_FIELD("Success"), ++ RC_JSON_NEW_FIELD("Error"), ++ RC_JSON_NEW_FIELD("Response") ++ }; ++ ++ rc_json_field_t entry_fields[] = { ++ RC_JSON_NEW_FIELD("ID"), ++ RC_JSON_NEW_FIELD("Title"), ++ RC_JSON_NEW_FIELD("ImageIcon") ++ }; ++ ++ memset(response, 0, sizeof(*response)); ++ rc_buffer_init(&response->response.buffer); ++ ++ result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0])); ++ if (result != RC_OK) ++ return result; ++ ++ if (!rc_json_get_required_array(&response->num_entries, &array_field, &response->response, &fields[2], "Response")) ++ return RC_MISSING_VALUE; ++ ++ if (response->num_entries) { ++ response->entries = (rc_api_game_title_entry_t*)rc_buffer_alloc(&response->response.buffer, response->num_entries * sizeof(rc_api_game_title_entry_t)); ++ if (!response->entries) ++ return RC_OUT_OF_MEMORY; ++ ++ memset(&iterator, 0, sizeof(iterator)); ++ iterator.json = array_field.value_start; ++ iterator.end = array_field.value_end; ++ ++ entry = response->entries; ++ while (rc_json_get_array_entry_object(entry_fields, sizeof(entry_fields) / sizeof(entry_fields[0]), &iterator)) { ++ if (!rc_json_get_required_unum(&entry->id, &response->response, &entry_fields[0], "ID")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_string(&entry->title, &response->response, &entry_fields[1], "Title")) ++ return RC_MISSING_VALUE; ++ ++ /* ImageIcon will be '/Images/0123456.png' - only return the '0123456' */ ++ rc_json_extract_filename(&entry_fields[2]); ++ if (!rc_json_get_required_string(&entry->image_name, &response->response, &entry_fields[2], "ImageIcon")) ++ return RC_MISSING_VALUE; ++ ++ ++entry; ++ } ++ } ++ ++ return RC_OK; ++} ++ ++void rc_api_destroy_fetch_game_titles_response(rc_api_fetch_game_titles_response_t* response) { ++ rc_buffer_destroy(&response->response.buffer); ++} ++ ++/* --- Fetch Game Hashes --- */ ++ ++int rc_api_init_fetch_hash_library_request(rc_api_request_t* request, ++ const rc_api_fetch_hash_library_request_t* api_params) ++{ ++ return rc_api_init_fetch_hash_library_request_hosted(request, api_params, &g_host); ++} ++ ++int rc_api_init_fetch_hash_library_request_hosted(rc_api_request_t* request, ++ const rc_api_fetch_hash_library_request_t* api_params, ++ const rc_api_host_t* host) ++{ ++ rc_api_url_builder_t builder; ++ rc_api_url_build_dorequest_url(request, host); ++ ++ /* note: unauthenticated request */ ++ rc_url_builder_init(&builder, &request->buffer, 48); ++ rc_url_builder_append_str_param(&builder, "r", "hashlibrary"); ++ if (api_params->console_id != 0) ++ rc_url_builder_append_unum_param(&builder, "c", api_params->console_id); ++ ++ request->post_data = rc_url_builder_finalize(&builder); ++ request->content_type = RC_CONTENT_TYPE_URLENCODED; ++ ++ return builder.result; ++} ++ ++int rc_api_process_fetch_hash_library_server_response(rc_api_fetch_hash_library_response_t* response, ++ const rc_api_server_response_t* server_response) ++{ ++ rc_api_hash_library_entry_t* entry; ++ rc_json_iterator_t iterator; ++ rc_json_field_t field; ++ int result; ++ ++ rc_json_field_t fields[] = { ++ RC_JSON_NEW_FIELD("Success"), ++ RC_JSON_NEW_FIELD("Error"), ++ RC_JSON_NEW_FIELD("MD5List"), ++ }; ++ ++ memset(response, 0, sizeof(*response)); ++ rc_buffer_init(&response->response.buffer); ++ ++ result = ++ rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0])); ++ if (result != RC_OK) ++ return result; ++ ++ if (!fields[2].value_start) { ++ /* call rc_json_get_required_object to generate the error message */ ++ rc_json_get_required_object(NULL, 0, &response->response, &fields[2], "MD5List"); ++ return RC_MISSING_VALUE; ++ } ++ ++ response->num_entries = fields[2].array_size; ++ if (response->num_entries > 0) { ++ rc_buffer_reserve(&response->response.buffer, response->num_entries * (33 + sizeof(rc_api_hash_library_entry_t))); ++ ++ response->entries = (rc_api_hash_library_entry_t*)rc_buffer_alloc( ++ &response->response.buffer, response->num_entries * sizeof(rc_api_hash_library_entry_t)); ++ if (!response->entries) ++ return RC_OUT_OF_MEMORY; ++ ++ memset(&iterator, 0, sizeof(iterator)); ++ iterator.json = fields[2].value_start; ++ iterator.end = fields[2].value_end; ++ ++ entry = response->entries; ++ while (rc_json_get_next_object_field(&iterator, &field)) { ++ entry->hash = rc_buffer_strncpy(&response->response.buffer, field.name, field.name_len); ++ ++ field.name = ""; ++ if (!rc_json_get_unum(&entry->game_id, &field, "")) ++ return RC_MISSING_VALUE; ++ ++ ++entry; ++ } ++ } ++ ++ return RC_OK; ++} ++ ++void rc_api_destroy_fetch_hash_library_response(rc_api_fetch_hash_library_response_t* response) ++{ ++ rc_buffer_destroy(&response->response.buffer); ++} +diff -rupbN melonDS.orig/src/rcheevos/src/rapi/rc_api_runtime.c melonDS.ra/src/rcheevos/src/rapi/rc_api_runtime.c +--- melonDS.orig/src/rcheevos/src/rapi/rc_api_runtime.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rapi/rc_api_runtime.c 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,901 @@ ++#include "rc_api_runtime.h" ++#include "rc_api_common.h" ++ ++#include "rc_runtime.h" ++#include "rc_runtime_types.h" ++#include "../rc_compat.h" ++#include "../rhash/md5.h" ++ ++#include ++#include ++#include ++ ++/* --- Resolve Hash --- */ ++ ++int rc_api_init_resolve_hash_request(rc_api_request_t* request, const rc_api_resolve_hash_request_t* api_params) { ++ return rc_api_init_resolve_hash_request_hosted(request, api_params, &g_host); ++} ++ ++int rc_api_init_resolve_hash_request_hosted(rc_api_request_t* request, ++ const rc_api_resolve_hash_request_t* api_params, ++ const rc_api_host_t* host) { ++ rc_api_url_builder_t builder; ++ ++ rc_api_url_build_dorequest_url(request, host); ++ ++ if (!api_params->game_hash || !*api_params->game_hash) ++ return RC_INVALID_STATE; ++ ++ rc_url_builder_init(&builder, &request->buffer, 48); ++ rc_url_builder_append_str_param(&builder, "r", "gameid"); ++ rc_url_builder_append_str_param(&builder, "m", api_params->game_hash); ++ request->post_data = rc_url_builder_finalize(&builder); ++ request->content_type = RC_CONTENT_TYPE_URLENCODED; ++ ++ return builder.result; ++} ++ ++int rc_api_process_resolve_hash_response(rc_api_resolve_hash_response_t* response, const char* server_response) { ++ rc_api_server_response_t response_obj; ++ ++ memset(&response_obj, 0, sizeof(response_obj)); ++ response_obj.body = server_response; ++ response_obj.body_length = rc_json_get_object_string_length(server_response); ++ ++ return rc_api_process_resolve_hash_server_response(response, &response_obj); ++} ++ ++int rc_api_process_resolve_hash_server_response(rc_api_resolve_hash_response_t* response, const rc_api_server_response_t* server_response) { ++ int result; ++ rc_json_field_t fields[] = { ++ RC_JSON_NEW_FIELD("Success"), ++ RC_JSON_NEW_FIELD("Error"), ++ RC_JSON_NEW_FIELD("GameID") ++ }; ++ ++ memset(response, 0, sizeof(*response)); ++ rc_buffer_init(&response->response.buffer); ++ ++ result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0])); ++ if (result != RC_OK) ++ return result; ++ ++ rc_json_get_required_unum(&response->game_id, &response->response, &fields[2], "GameID"); ++ return RC_OK; ++} ++ ++void rc_api_destroy_resolve_hash_response(rc_api_resolve_hash_response_t* response) { ++ rc_buffer_destroy(&response->response.buffer); ++} ++ ++/* --- Fetch Game Data --- */ ++ ++int rc_api_init_fetch_game_data_request(rc_api_request_t* request, const rc_api_fetch_game_data_request_t* api_params) { ++ return rc_api_init_fetch_game_data_request_hosted(request, api_params, &g_host); ++} ++ ++int rc_api_init_fetch_game_data_request_hosted(rc_api_request_t* request, ++ const rc_api_fetch_game_data_request_t* api_params, ++ const rc_api_host_t* host) { ++ rc_api_url_builder_t builder; ++ ++ rc_api_url_build_dorequest_url(request, host); ++ ++ if (api_params->game_id == 0 && (!api_params->game_hash || !api_params->game_hash[0])) ++ return RC_INVALID_STATE; ++ ++ rc_url_builder_init(&builder, &request->buffer, 48); ++ if (rc_api_url_build_dorequest(&builder, "patch", api_params->username, api_params->api_token)) { ++ if (api_params->game_id) ++ rc_url_builder_append_unum_param(&builder, "g", api_params->game_id); ++ else ++ rc_url_builder_append_str_param(&builder, "m", api_params->game_hash); ++ ++ request->post_data = rc_url_builder_finalize(&builder); ++ request->content_type = RC_CONTENT_TYPE_URLENCODED; ++ } ++ ++ return builder.result; ++} ++ ++int rc_api_process_fetch_game_data_response(rc_api_fetch_game_data_response_t* response, const char* server_response) { ++ rc_api_server_response_t response_obj; ++ ++ memset(&response_obj, 0, sizeof(response_obj)); ++ response_obj.body = server_response; ++ response_obj.body_length = rc_json_get_object_string_length(server_response); ++ ++ return rc_api_process_fetch_game_data_server_response(response, &response_obj); ++} ++ ++static int rc_api_process_fetch_game_data_achievements(rc_api_response_t* response, rc_api_achievement_definition_t* achievement, rc_json_field_t* array_field) { ++ rc_json_iterator_t iterator; ++ const char* last_author = ""; ++ const char* last_author_field = ""; ++ size_t last_author_len = 0; ++ uint32_t timet; ++ size_t len; ++ ++ rc_json_field_t achievement_fields[] = { ++ RC_JSON_NEW_FIELD("ID"), ++ RC_JSON_NEW_FIELD("Title"), ++ RC_JSON_NEW_FIELD("Description"), ++ RC_JSON_NEW_FIELD("Flags"), ++ RC_JSON_NEW_FIELD("Points"), ++ RC_JSON_NEW_FIELD("MemAddr"), ++ RC_JSON_NEW_FIELD("Author"), ++ RC_JSON_NEW_FIELD("BadgeName"), ++ RC_JSON_NEW_FIELD("Created"), ++ RC_JSON_NEW_FIELD("Modified"), ++ RC_JSON_NEW_FIELD("Type"), ++ RC_JSON_NEW_FIELD("Rarity"), ++ RC_JSON_NEW_FIELD("RarityHardcore"), ++ RC_JSON_NEW_FIELD("BadgeURL"), ++ RC_JSON_NEW_FIELD("BadgeLockedURL") ++ }; ++ ++ memset(&iterator, 0, sizeof(iterator)); ++ iterator.json = array_field->value_start; ++ iterator.end = array_field->value_end; ++ ++ while (rc_json_get_array_entry_object(achievement_fields, sizeof(achievement_fields) / sizeof(achievement_fields[0]), &iterator)) { ++ if (!rc_json_get_required_unum(&achievement->id, response, &achievement_fields[0], "ID")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_string(&achievement->title, response, &achievement_fields[1], "Title")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_string(&achievement->description, response, &achievement_fields[2], "Description")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_unum(&achievement->category, response, &achievement_fields[3], "Flags")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_unum(&achievement->points, response, &achievement_fields[4], "Points")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_string(&achievement->definition, response, &achievement_fields[5], "MemAddr")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_string(&achievement->badge_name, response, &achievement_fields[7], "BadgeName")) ++ return RC_MISSING_VALUE; ++ ++ rc_json_get_optional_string(&achievement->badge_url, response, &achievement_fields[13], "BadgeURL", ""); ++ if (!achievement->badge_url[0]) ++ achievement->badge_url = rc_api_build_avatar_url(&response->buffer, RC_IMAGE_TYPE_ACHIEVEMENT, achievement->badge_name); ++ ++ rc_json_get_optional_string(&achievement->badge_locked_url, response, &achievement_fields[14], "BadgeLockedURL", ""); ++ if (!achievement->badge_locked_url[0]) ++ achievement->badge_locked_url = rc_api_build_avatar_url(&response->buffer, RC_IMAGE_TYPE_ACHIEVEMENT_LOCKED, achievement->badge_name); ++ ++ len = achievement_fields[6].value_end - achievement_fields[6].value_start; ++ if (len == last_author_len && memcmp(achievement_fields[6].value_start, last_author_field, len) == 0) { ++ achievement->author = last_author; ++ } ++ else { ++ if (!rc_json_get_required_string(&achievement->author, response, &achievement_fields[6], "Author")) ++ return RC_MISSING_VALUE; ++ ++ if (achievement->author == NULL) { ++ /* ensure we don't pass NULL out to client */ ++ last_author = achievement->author = ""; ++ last_author_len = 0; ++ } else { ++ last_author = achievement->author; ++ last_author_field = achievement_fields[6].value_start; ++ last_author_len = len; ++ } ++ } ++ ++ if (!rc_json_get_required_unum(&timet, response, &achievement_fields[8], "Created")) ++ return RC_MISSING_VALUE; ++ achievement->created = (time_t)timet; ++ if (!rc_json_get_required_unum(&timet, response, &achievement_fields[9], "Modified")) ++ return RC_MISSING_VALUE; ++ achievement->updated = (time_t)timet; ++ ++ if (rc_json_field_string_matches(&achievement_fields[10], "")) ++ achievement->type = RC_ACHIEVEMENT_TYPE_STANDARD; ++ else if (rc_json_field_string_matches(&achievement_fields[10], "progression")) ++ achievement->type = RC_ACHIEVEMENT_TYPE_PROGRESSION; ++ else if (rc_json_field_string_matches(&achievement_fields[10], "missable")) ++ achievement->type = RC_ACHIEVEMENT_TYPE_MISSABLE; ++ else if (rc_json_field_string_matches(&achievement_fields[10], "win_condition")) ++ achievement->type = RC_ACHIEVEMENT_TYPE_WIN; ++ else ++ achievement->type = RC_ACHIEVEMENT_TYPE_STANDARD; ++ ++ /* legacy support : if title contains[m], change type to missable and remove[m] from title */ ++ if (memcmp(achievement->title, "[m]", 3) == 0) { ++ len = 3; ++ while (achievement->title[len] == ' ') ++ ++len; ++ achievement->title += len; ++ achievement->type = RC_ACHIEVEMENT_TYPE_MISSABLE; ++ } ++ else if (achievement_fields[1].value_end && memcmp(achievement_fields[1].value_end - 4, "[m]", 3) == 0) { ++ len = strlen(achievement->title) - 3; ++ while (achievement->title[len - 1] == ' ') ++ --len; ++ ((char*)achievement->title)[len] = '\0'; ++ achievement->type = RC_ACHIEVEMENT_TYPE_MISSABLE; ++ } ++ ++ rc_json_get_optional_float(&achievement->rarity, &achievement_fields[11], "Rarity", 100.0); ++ rc_json_get_optional_float(&achievement->rarity_hardcore, &achievement_fields[12], "RarityHardcore", 100.0); ++ ++ ++achievement; ++ } ++ ++ return RC_OK; ++} ++ ++static int rc_api_process_fetch_game_data_leaderboards(rc_api_response_t* response, rc_api_leaderboard_definition_t* leaderboard, rc_json_field_t* array_field) { ++ rc_json_iterator_t iterator; ++ size_t len; ++ int result; ++ char format[16]; ++ ++ rc_json_field_t leaderboard_fields[] = { ++ RC_JSON_NEW_FIELD("ID"), ++ RC_JSON_NEW_FIELD("Title"), ++ RC_JSON_NEW_FIELD("Description"), ++ RC_JSON_NEW_FIELD("Mem"), ++ RC_JSON_NEW_FIELD("Format"), ++ RC_JSON_NEW_FIELD("LowerIsBetter"), ++ RC_JSON_NEW_FIELD("Hidden") ++ }; ++ ++ memset(&iterator, 0, sizeof(iterator)); ++ iterator.json = array_field->value_start; ++ iterator.end = array_field->value_end; ++ ++ while (rc_json_get_array_entry_object(leaderboard_fields, sizeof(leaderboard_fields) / sizeof(leaderboard_fields[0]), &iterator)) { ++ if (!rc_json_get_required_unum(&leaderboard->id, response, &leaderboard_fields[0], "ID")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_string(&leaderboard->title, response, &leaderboard_fields[1], "Title")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_string(&leaderboard->description, response, &leaderboard_fields[2], "Description")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_string(&leaderboard->definition, response, &leaderboard_fields[3], "Mem")) ++ return RC_MISSING_VALUE; ++ rc_json_get_optional_bool(&result, &leaderboard_fields[5], "LowerIsBetter", 0); ++ leaderboard->lower_is_better = (uint8_t)result; ++ rc_json_get_optional_bool(&result, &leaderboard_fields[6], "Hidden", 0); ++ leaderboard->hidden = (uint8_t)result; ++ ++ if (!leaderboard_fields[4].value_end) ++ return RC_MISSING_VALUE; ++ len = leaderboard_fields[4].value_end - leaderboard_fields[4].value_start - 2; ++ if (len < sizeof(format) - 1) { ++ memcpy(format, leaderboard_fields[4].value_start + 1, len); ++ format[len] = '\0'; ++ leaderboard->format = rc_parse_format(format); ++ } ++ else { ++ leaderboard->format = RC_FORMAT_VALUE; ++ } ++ ++ ++leaderboard; ++ } ++ ++ return RC_OK; ++} ++ ++int rc_api_process_fetch_game_data_server_response(rc_api_fetch_game_data_response_t* response, const rc_api_server_response_t* server_response) { ++ rc_json_field_t array_field; ++ size_t len; ++ int result; ++ ++ rc_json_field_t fields[] = { ++ RC_JSON_NEW_FIELD("Success"), ++ RC_JSON_NEW_FIELD("Error"), ++ RC_JSON_NEW_FIELD("Code"), ++ RC_JSON_NEW_FIELD("PatchData") /* nested object */ ++ }; ++ ++ rc_json_field_t patchdata_fields[] = { ++ RC_JSON_NEW_FIELD("ID"), ++ RC_JSON_NEW_FIELD("Title"), ++ RC_JSON_NEW_FIELD("ConsoleID"), ++ RC_JSON_NEW_FIELD("ImageIcon"), ++ RC_JSON_NEW_FIELD("ImageIconURL"), ++ RC_JSON_NEW_FIELD("RichPresencePatch"), ++ RC_JSON_NEW_FIELD("Achievements"), /* array */ ++ RC_JSON_NEW_FIELD("Leaderboards"), /* array */ ++ }; ++ ++ memset(response, 0, sizeof(*response)); ++ rc_buffer_init(&response->response.buffer); ++ ++ result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0])); ++ if (result != RC_OK || !response->response.succeeded) ++ return result; ++ ++ if (!rc_json_get_required_object(patchdata_fields, sizeof(patchdata_fields) / sizeof(patchdata_fields[0]), &response->response, &fields[3], "PatchData")) ++ return RC_MISSING_VALUE; ++ ++ if (!rc_json_get_required_unum(&response->id, &response->response, &patchdata_fields[0], "ID")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_string(&response->title, &response->response, &patchdata_fields[1], "Title")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_unum(&response->console_id, &response->response, &patchdata_fields[2], "ConsoleID")) ++ return RC_MISSING_VALUE; ++ ++ /* ImageIcon will be '/Images/0123456.png' - only return the '0123456' */ ++ rc_json_extract_filename(&patchdata_fields[3]); ++ rc_json_get_optional_string(&response->image_name, &response->response, &patchdata_fields[3], "ImageIcon", ""); ++ rc_json_get_optional_string(&response->image_url, &response->response, &patchdata_fields[4], "ImageIconURL", ""); ++ if (!response->image_url[0]) ++ response->image_url = rc_api_build_avatar_url(&response->response.buffer, RC_IMAGE_TYPE_GAME, response->image_name); ++ ++ /* estimate the amount of space necessary to store the rich presence script, achievements, and leaderboards. ++ determine how much space each takes as a string in the JSON, then subtract out the non-data (field names, punctuation) ++ and add space for the structures. */ ++ len = patchdata_fields[5].value_end - patchdata_fields[5].value_start; /* rich presence */ ++ ++ len += (patchdata_fields[6].value_end - patchdata_fields[6].value_start) - /* achievements */ ++ patchdata_fields[6].array_size * (80 - sizeof(rc_api_achievement_definition_t)); ++ ++ len += (patchdata_fields[7].value_end - patchdata_fields[7].value_start) - /* leaderboards */ ++ patchdata_fields[7].array_size * (60 - sizeof(rc_api_leaderboard_definition_t)); ++ ++ rc_buffer_reserve(&response->response.buffer, len); ++ /* end estimation */ ++ ++ rc_json_get_optional_string(&response->rich_presence_script, &response->response, &patchdata_fields[5], "RichPresencePatch", ""); ++ if (!response->rich_presence_script) ++ response->rich_presence_script = ""; ++ ++ if (!rc_json_get_required_array(&response->num_achievements, &array_field, &response->response, &patchdata_fields[6], "Achievements")) ++ return RC_MISSING_VALUE; ++ ++ if (response->num_achievements) { ++ response->achievements = (rc_api_achievement_definition_t*)rc_buffer_alloc(&response->response.buffer, response->num_achievements * sizeof(rc_api_achievement_definition_t)); ++ if (!response->achievements) ++ return RC_OUT_OF_MEMORY; ++ ++ result = rc_api_process_fetch_game_data_achievements(&response->response, response->achievements, &array_field); ++ if (result != RC_OK) ++ return result; ++ } ++ ++ if (!rc_json_get_required_array(&response->num_leaderboards, &array_field, &response->response, &patchdata_fields[7], "Leaderboards")) ++ return RC_MISSING_VALUE; ++ ++ if (response->num_leaderboards) { ++ response->leaderboards = (rc_api_leaderboard_definition_t*)rc_buffer_alloc(&response->response.buffer, response->num_leaderboards * sizeof(rc_api_leaderboard_definition_t)); ++ if (!response->leaderboards) ++ return RC_OUT_OF_MEMORY; ++ ++ result = rc_api_process_fetch_game_data_leaderboards(&response->response, response->leaderboards, &array_field); ++ if (result != RC_OK) ++ return result; ++ } ++ ++ return RC_OK; ++} ++ ++void rc_api_destroy_fetch_game_data_response(rc_api_fetch_game_data_response_t* response) { ++ rc_buffer_destroy(&response->response.buffer); ++} ++ ++/* --- Fetch Game Sets --- */ ++ ++int rc_api_init_fetch_game_sets_request(rc_api_request_t* request, const rc_api_fetch_game_sets_request_t* api_params) { ++ return rc_api_init_fetch_game_sets_request_hosted(request, api_params, &g_host); ++} ++ ++int rc_api_init_fetch_game_sets_request_hosted(rc_api_request_t* request, ++ const rc_api_fetch_game_sets_request_t* api_params, ++ const rc_api_host_t* host) { ++ rc_api_url_builder_t builder; ++ ++ rc_api_url_build_dorequest_url(request, host); ++ ++ if (!api_params->game_id && (!api_params->game_hash || !api_params->game_hash[0])) ++ return RC_INVALID_STATE; ++ ++ rc_url_builder_init(&builder, &request->buffer, 48); ++ if (rc_api_url_build_dorequest(&builder, "achievementsets", api_params->username, api_params->api_token)) { ++ if (api_params->game_id) ++ rc_url_builder_append_unum_param(&builder, "g", api_params->game_id); ++ else ++ rc_url_builder_append_str_param(&builder, "m", api_params->game_hash); ++ ++ request->post_data = rc_url_builder_finalize(&builder); ++ request->content_type = RC_CONTENT_TYPE_URLENCODED; ++ } ++ ++ return builder.result; ++} ++ ++static int rc_api_process_fetch_game_sets_achievement_sets(rc_api_fetch_game_sets_response_t* response, ++ rc_api_achievement_set_definition_t* subset, ++ rc_json_field_t* subset_array_field) { ++ rc_json_iterator_t iterator; ++ rc_json_field_t array_field; ++ size_t len; ++ int result; ++ ++ rc_json_field_t subset_fields[] = { ++ RC_JSON_NEW_FIELD("AchievementSetId"), ++ RC_JSON_NEW_FIELD("GameId"), ++ RC_JSON_NEW_FIELD("Title"), ++ RC_JSON_NEW_FIELD("Type"), ++ RC_JSON_NEW_FIELD("ImageIconUrl"), ++ RC_JSON_NEW_FIELD("Achievements"), /* array */ ++ RC_JSON_NEW_FIELD("Leaderboards") /* array */ ++ }; ++ ++ memset(&iterator, 0, sizeof(iterator)); ++ iterator.json = subset_array_field->value_start; ++ iterator.end = subset_array_field->value_end; ++ ++ while (rc_json_get_array_entry_object(subset_fields, sizeof(subset_fields) / sizeof(subset_fields[0]), &iterator)) { ++ if (!rc_json_get_required_unum(&subset->id, &response->response, &subset_fields[0], "AchievementSetId")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_unum(&subset->game_id, &response->response, &subset_fields[1], "GameId")) ++ return RC_MISSING_VALUE; ++ ++ if (!rc_json_get_required_string(&subset->title, &response->response, &subset_fields[2], "Title")) ++ return RC_MISSING_VALUE; ++ if (!subset->title || !subset->title[0]) ++ subset->title = response->title; ++ ++ if (rc_json_field_string_matches(&subset_fields[3], "core")) ++ subset->type = RC_ACHIEVEMENT_SET_TYPE_CORE; ++ else if (rc_json_field_string_matches(&subset_fields[3], "bonus")) ++ subset->type = RC_ACHIEVEMENT_SET_TYPE_BONUS; ++ else if (rc_json_field_string_matches(&subset_fields[3], "specialty")) ++ subset->type = RC_ACHIEVEMENT_SET_TYPE_SPECIALTY; ++ else if (rc_json_field_string_matches(&subset_fields[3], "exclusive")) ++ subset->type = RC_ACHIEVEMENT_SET_TYPE_EXCLUSIVE; ++ else ++ subset->type = RC_ACHIEVEMENT_SET_TYPE_BONUS; ++ ++ if (rc_json_field_string_matches(&subset_fields[4], response->image_url)) { ++ subset->image_url = response->image_url; ++ subset->image_name = response->image_name; ++ } ++ else { ++ if (!rc_json_get_required_string(&subset->image_url, &response->response, &subset_fields[4], "ImageIconUrl")) ++ return RC_MISSING_VALUE; ++ rc_json_extract_filename(&subset_fields[4]); ++ rc_json_get_optional_string(&subset->image_name, &response->response, &subset_fields[4], "ImageIconUrl", ""); ++ } ++ ++ /* estimate the amount of space necessary to store the achievements, and leaderboards. ++ determine how much space each takes as a string in the JSON, then subtract out the non-data (field names, punctuation) ++ and add space for the structures. */ ++ len = (subset_fields[5].value_end - subset_fields[5].value_start) - /* achievements */ ++ subset_fields[5].array_size * (80 - sizeof(rc_api_achievement_definition_t)); ++ len += (subset_fields[6].value_end - subset_fields[6].value_start) - /* leaderboards */ ++ subset_fields[6].array_size * (60 - sizeof(rc_api_leaderboard_definition_t)); ++ ++ rc_buffer_reserve(&response->response.buffer, len); ++ /* end estimation */ ++ ++ if (!rc_json_get_required_array(&subset->num_achievements, &array_field, &response->response, &subset_fields[5], "Achievements")) ++ return RC_MISSING_VALUE; ++ ++ if (subset->num_achievements) { ++ subset->achievements = (rc_api_achievement_definition_t*)rc_buffer_alloc(&response->response.buffer, subset->num_achievements * sizeof(rc_api_achievement_definition_t)); ++ if (!subset->achievements) ++ return RC_OUT_OF_MEMORY; ++ ++ result = rc_api_process_fetch_game_data_achievements(&response->response, subset->achievements, &array_field); ++ if (result != RC_OK) ++ return result; ++ } ++ ++ if (!rc_json_get_required_array(&subset->num_leaderboards, &array_field, &response->response, &subset_fields[6], "Leaderboards")) ++ return RC_MISSING_VALUE; ++ ++ if (subset->num_leaderboards) { ++ subset->leaderboards = (rc_api_leaderboard_definition_t*)rc_buffer_alloc(&response->response.buffer, subset->num_leaderboards * sizeof(rc_api_leaderboard_definition_t)); ++ if (!subset->leaderboards) ++ return RC_OUT_OF_MEMORY; ++ ++ result = rc_api_process_fetch_game_data_leaderboards(&response->response, subset->leaderboards, &array_field); ++ if (result != RC_OK) ++ return result; ++ } ++ ++ ++subset; ++ } ++ ++ return RC_OK; ++} ++ ++int rc_api_process_fetch_game_sets_server_response(rc_api_fetch_game_sets_response_t* response, const rc_api_server_response_t* server_response) { ++ rc_json_field_t array_field; ++ int result; ++ ++ rc_json_field_t fields[] = { ++ RC_JSON_NEW_FIELD("Success"), ++ RC_JSON_NEW_FIELD("Error"), ++ RC_JSON_NEW_FIELD("Code"), ++ RC_JSON_NEW_FIELD("GameId"), ++ RC_JSON_NEW_FIELD("Title"), ++ RC_JSON_NEW_FIELD("ConsoleId"), ++ RC_JSON_NEW_FIELD("ImageIconUrl"), ++ RC_JSON_NEW_FIELD("RichPresenceGameId"), ++ RC_JSON_NEW_FIELD("RichPresencePatch"), ++ RC_JSON_NEW_FIELD("Sets") /* array */ ++ }; ++ ++ memset(response, 0, sizeof(*response)); ++ rc_buffer_init(&response->response.buffer); ++ ++ result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0])); ++ if (result != RC_OK || !response->response.succeeded) ++ return result; ++ ++ if (!rc_json_get_required_unum(&response->id, &response->response, &fields[3], "GameId")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_string(&response->title, &response->response, &fields[4], "Title")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_unum(&response->console_id, &response->response, &fields[5], "ConsoleId")) ++ return RC_MISSING_VALUE; ++ ++ rc_json_get_required_string(&response->image_url, &response->response, &fields[6], "ImageIconUrl"); ++ rc_json_extract_filename(&fields[6]); ++ rc_json_get_required_string(&response->image_name, &response->response, &fields[6], "ImageIconUrl"); ++ ++ rc_json_get_optional_unum(&response->session_game_id, &fields[7], "RichPresenceGameId", response->id); ++ ++ rc_json_get_optional_string(&response->rich_presence_script, &response->response, &fields[8], "RichPresencePatch", ""); ++ if (!response->rich_presence_script) ++ response->rich_presence_script = ""; ++ ++ rc_json_get_optional_array(&response->num_sets, &array_field, &fields[9], "Sets"); ++ if (response->num_sets) { ++ response->sets = (rc_api_achievement_set_definition_t*)rc_buffer_alloc(&response->response.buffer, response->num_sets * sizeof(rc_api_achievement_set_definition_t)); ++ if (!response->sets) ++ return RC_OUT_OF_MEMORY; ++ ++ result = rc_api_process_fetch_game_sets_achievement_sets(response, response->sets, &array_field); ++ if (result != RC_OK) ++ return result; ++ } ++ ++ return RC_OK; ++} ++ ++void rc_api_destroy_fetch_game_sets_response(rc_api_fetch_game_sets_response_t* response) { ++ rc_buffer_destroy(&response->response.buffer); ++} ++ ++/* --- Ping --- */ ++ ++int rc_api_init_ping_request(rc_api_request_t* request, const rc_api_ping_request_t* api_params) { ++ return rc_api_init_ping_request_hosted(request, api_params, &g_host); ++} ++ ++int rc_api_init_ping_request_hosted(rc_api_request_t* request, ++ const rc_api_ping_request_t* api_params, ++ const rc_api_host_t* host) { ++ rc_api_url_builder_t builder; ++ ++ rc_api_url_build_dorequest_url(request, host); ++ ++ if (api_params->game_id == 0) ++ return RC_INVALID_STATE; ++ ++ rc_url_builder_init(&builder, &request->buffer, 48); ++ if (rc_api_url_build_dorequest(&builder, "ping", api_params->username, api_params->api_token)) { ++ rc_url_builder_append_unum_param(&builder, "g", api_params->game_id); ++ ++ if (api_params->rich_presence && *api_params->rich_presence) ++ rc_url_builder_append_str_param(&builder, "m", api_params->rich_presence); ++ ++ if (api_params->game_hash && *api_params->game_hash) { ++ rc_url_builder_append_unum_param(&builder, "h", api_params->hardcore); ++ rc_url_builder_append_str_param(&builder, "x", api_params->game_hash); ++ } ++ ++ request->post_data = rc_url_builder_finalize(&builder); ++ request->content_type = RC_CONTENT_TYPE_URLENCODED; ++ } ++ ++ return builder.result; ++} ++ ++int rc_api_process_ping_response(rc_api_ping_response_t* response, const char* server_response) { ++ rc_api_server_response_t response_obj; ++ ++ memset(&response_obj, 0, sizeof(response_obj)); ++ response_obj.body = server_response; ++ response_obj.body_length = rc_json_get_object_string_length(server_response); ++ ++ return rc_api_process_ping_server_response(response, &response_obj); ++} ++ ++int rc_api_process_ping_server_response(rc_api_ping_response_t* response, const rc_api_server_response_t* server_response) { ++ rc_json_field_t fields[] = { ++ RC_JSON_NEW_FIELD("Success"), ++ RC_JSON_NEW_FIELD("Error") ++ }; ++ ++ memset(response, 0, sizeof(*response)); ++ rc_buffer_init(&response->response.buffer); ++ ++ return rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0])); ++} ++ ++void rc_api_destroy_ping_response(rc_api_ping_response_t* response) { ++ rc_buffer_destroy(&response->response.buffer); ++} ++ ++/* --- Award Achievement --- */ ++ ++int rc_api_init_award_achievement_request(rc_api_request_t* request, const rc_api_award_achievement_request_t* api_params) { ++ return rc_api_init_award_achievement_request_hosted(request, api_params, &g_host); ++} ++ ++int rc_api_init_award_achievement_request_hosted(rc_api_request_t* request, ++ const rc_api_award_achievement_request_t* api_params, ++ const rc_api_host_t* host) { ++ rc_api_url_builder_t builder; ++ char buffer[33]; ++ md5_state_t md5; ++ md5_byte_t digest[16]; ++ ++ rc_api_url_build_dorequest_url(request, host); ++ ++ if (api_params->achievement_id == 0) ++ return RC_INVALID_STATE; ++ ++ rc_url_builder_init(&builder, &request->buffer, 96); ++ if (rc_api_url_build_dorequest(&builder, "awardachievement", api_params->username, api_params->api_token)) { ++ rc_url_builder_append_unum_param(&builder, "a", api_params->achievement_id); ++ rc_url_builder_append_unum_param(&builder, "h", api_params->hardcore ? 1 : 0); ++ if (api_params->game_hash && *api_params->game_hash) ++ rc_url_builder_append_str_param(&builder, "m", api_params->game_hash); ++ if (api_params->seconds_since_unlock) ++ rc_url_builder_append_unum_param(&builder, "o", api_params->seconds_since_unlock); ++ ++ /* Evaluate the signature. */ ++ md5_init(&md5); ++ snprintf(buffer, sizeof(buffer), "%u", api_params->achievement_id); ++ md5_append(&md5, (md5_byte_t*)buffer, (int)strlen(buffer)); ++ md5_append(&md5, (md5_byte_t*)api_params->username, (int)strlen(api_params->username)); ++ snprintf(buffer, sizeof(buffer), "%d", api_params->hardcore ? 1 : 0); ++ md5_append(&md5, (md5_byte_t*)buffer, (int)strlen(buffer)); ++ if (api_params->seconds_since_unlock) { ++ /* second achievement id is needed by delegated unlock. including it here allows overloading ++ * the hash generating code on the server */ ++ snprintf(buffer, sizeof(buffer), "%u", api_params->achievement_id); ++ md5_append(&md5, (md5_byte_t*)buffer, (int)strlen(buffer)); ++ snprintf(buffer, sizeof(buffer), "%u", api_params->seconds_since_unlock); ++ md5_append(&md5, (md5_byte_t*)buffer, (int)strlen(buffer)); ++ } ++ md5_finish(&md5, digest); ++ rc_format_md5(buffer, digest); ++ rc_url_builder_append_str_param(&builder, "v", buffer); ++ ++ request->post_data = rc_url_builder_finalize(&builder); ++ request->content_type = RC_CONTENT_TYPE_URLENCODED; ++ } ++ ++ return builder.result; ++} ++ ++int rc_api_process_award_achievement_response(rc_api_award_achievement_response_t* response, const char* server_response) { ++ rc_api_server_response_t response_obj; ++ ++ memset(&response_obj, 0, sizeof(response_obj)); ++ response_obj.body = server_response; ++ response_obj.body_length = rc_json_get_object_string_length(server_response); ++ ++ return rc_api_process_award_achievement_server_response(response, &response_obj); ++} ++ ++int rc_api_process_award_achievement_server_response(rc_api_award_achievement_response_t* response, const rc_api_server_response_t* server_response) { ++ int result; ++ rc_json_field_t fields[] = { ++ RC_JSON_NEW_FIELD("Success"), ++ RC_JSON_NEW_FIELD("Error"), ++ RC_JSON_NEW_FIELD("Score"), ++ RC_JSON_NEW_FIELD("SoftcoreScore"), ++ RC_JSON_NEW_FIELD("AchievementID"), ++ RC_JSON_NEW_FIELD("AchievementsRemaining") ++ }; ++ ++ memset(response, 0, sizeof(*response)); ++ rc_buffer_init(&response->response.buffer); ++ ++ result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0])); ++ if (result != RC_OK) ++ return result; ++ ++ if (!response->response.succeeded) { ++ if (response->response.error_message && ++ memcmp(response->response.error_message, "User already has", 16) == 0) { ++ /* not really an error, the achievement is unlocked, just not by the current call. ++ * hardcore: User already has hardcore and regular achievements awarded. ++ * non-hardcore: User already has this achievement awarded. ++ */ ++ response->response.succeeded = 1; ++ } else { ++ return result; ++ } ++ } ++ ++ rc_json_get_optional_unum(&response->new_player_score, &fields[2], "Score", 0); ++ rc_json_get_optional_unum(&response->new_player_score_softcore, &fields[3], "SoftcoreScore", 0); ++ rc_json_get_optional_unum(&response->awarded_achievement_id, &fields[4], "AchievementID", 0); ++ rc_json_get_optional_unum(&response->achievements_remaining, &fields[5], "AchievementsRemaining", (unsigned)-1); ++ ++ return RC_OK; ++} ++ ++void rc_api_destroy_award_achievement_response(rc_api_award_achievement_response_t* response) { ++ rc_buffer_destroy(&response->response.buffer); ++} ++ ++/* --- Submit Leaderboard Entry --- */ ++ ++int rc_api_init_submit_lboard_entry_request(rc_api_request_t* request, const rc_api_submit_lboard_entry_request_t* api_params) { ++ return rc_api_init_submit_lboard_entry_request_hosted(request, api_params, &g_host); ++} ++ ++int rc_api_init_submit_lboard_entry_request_hosted(rc_api_request_t* request, ++ const rc_api_submit_lboard_entry_request_t* api_params, ++ const rc_api_host_t* host) { ++ rc_api_url_builder_t builder; ++ char buffer[33]; ++ md5_state_t md5; ++ md5_byte_t digest[16]; ++ ++ rc_api_url_build_dorequest_url(request, host); ++ ++ if (api_params->leaderboard_id == 0) ++ return RC_INVALID_STATE; ++ ++ rc_url_builder_init(&builder, &request->buffer, 96); ++ if (rc_api_url_build_dorequest(&builder, "submitlbentry", api_params->username, api_params->api_token)) { ++ rc_url_builder_append_unum_param(&builder, "i", api_params->leaderboard_id); ++ rc_url_builder_append_num_param(&builder, "s", api_params->score); ++ ++ if (api_params->game_hash && *api_params->game_hash) ++ rc_url_builder_append_str_param(&builder, "m", api_params->game_hash); ++ ++ if (api_params->seconds_since_completion) ++ rc_url_builder_append_unum_param(&builder, "o", api_params->seconds_since_completion); ++ ++ /* Evaluate the signature. */ ++ md5_init(&md5); ++ snprintf(buffer, sizeof(buffer), "%u", api_params->leaderboard_id); ++ md5_append(&md5, (md5_byte_t*)buffer, (int)strlen(buffer)); ++ md5_append(&md5, (md5_byte_t*)api_params->username, (int)strlen(api_params->username)); ++ snprintf(buffer, sizeof(buffer), "%d", api_params->score); ++ md5_append(&md5, (md5_byte_t*)buffer, (int)strlen(buffer)); ++ if (api_params->seconds_since_completion) { ++ snprintf(buffer, sizeof(buffer), "%u", api_params->seconds_since_completion); ++ md5_append(&md5, (md5_byte_t*)buffer, (int)strlen(buffer)); ++ } ++ md5_finish(&md5, digest); ++ rc_format_md5(buffer, digest); ++ rc_url_builder_append_str_param(&builder, "v", buffer); ++ ++ request->post_data = rc_url_builder_finalize(&builder); ++ request->content_type = RC_CONTENT_TYPE_URLENCODED; ++ } ++ ++ return builder.result; ++} ++ ++int rc_api_process_submit_lboard_entry_response(rc_api_submit_lboard_entry_response_t* response, const char* server_response) { ++ rc_api_server_response_t response_obj; ++ ++ memset(&response_obj, 0, sizeof(response_obj)); ++ response_obj.body = server_response; ++ response_obj.body_length = rc_json_get_object_string_length(server_response); ++ ++ return rc_api_process_submit_lboard_entry_server_response(response, &response_obj); ++} ++ ++int rc_api_process_submit_lboard_entry_server_response(rc_api_submit_lboard_entry_response_t* response, const rc_api_server_response_t* server_response) { ++ rc_api_lboard_entry_t* entry; ++ rc_json_field_t array_field; ++ rc_json_iterator_t iterator; ++ const char* str; ++ int result; ++ ++ rc_json_field_t fields[] = { ++ RC_JSON_NEW_FIELD("Success"), ++ RC_JSON_NEW_FIELD("Error"), ++ RC_JSON_NEW_FIELD("Response") /* nested object */ ++ }; ++ ++ rc_json_field_t response_fields[] = { ++ RC_JSON_NEW_FIELD("Score"), ++ RC_JSON_NEW_FIELD("BestScore"), ++ RC_JSON_NEW_FIELD("RankInfo"), /* nested object */ ++ RC_JSON_NEW_FIELD("TopEntries") /* array */ ++ /* unused fields ++ RC_JSON_NEW_FIELD("LBData"), / * array * / ++ RC_JSON_NEW_FIELD("ScoreFormatted"), ++ RC_JSON_NEW_FIELD("TopEntriesFriends") / * array * / ++ * unused fields */ ++ }; ++ ++ /* unused fields ++ rc_json_field_t lbdata_fields[] = { ++ RC_JSON_NEW_FIELD("Format"), ++ RC_JSON_NEW_FIELD("LeaderboardID"), ++ RC_JSON_NEW_FIELD("GameID"), ++ RC_JSON_NEW_FIELD("Title"), ++ RC_JSON_NEW_FIELD("LowerIsBetter") ++ }; ++ * unused fields */ ++ ++ rc_json_field_t entry_fields[] = { ++ RC_JSON_NEW_FIELD("User"), ++ RC_JSON_NEW_FIELD("Rank"), ++ RC_JSON_NEW_FIELD("Score") ++ /* unused fields ++ RC_JSON_NEW_FIELD("DateSubmitted") ++ * unused fields */ ++ }; ++ ++ rc_json_field_t rank_info_fields[] = { ++ RC_JSON_NEW_FIELD("Rank"), ++ RC_JSON_NEW_FIELD("NumEntries") ++ /* unused fields ++ RC_JSON_NEW_FIELD("LowerIsBetter"), ++ RC_JSON_NEW_FIELD("UserRank") ++ * unused fields */ ++ }; ++ ++ memset(response, 0, sizeof(*response)); ++ rc_buffer_init(&response->response.buffer); ++ ++ result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0])); ++ if (result != RC_OK || !response->response.succeeded) ++ return result; ++ ++ if (!rc_json_get_required_object(response_fields, sizeof(response_fields) / sizeof(response_fields[0]), &response->response, &fields[2], "Response")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_num(&response->submitted_score, &response->response, &response_fields[0], "Score")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_num(&response->best_score, &response->response, &response_fields[1], "BestScore")) ++ return RC_MISSING_VALUE; ++ ++ if (!rc_json_get_required_object(rank_info_fields, sizeof(rank_info_fields) / sizeof(rank_info_fields[0]), &response->response, &response_fields[2], "RankInfo")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_unum(&response->new_rank, &response->response, &rank_info_fields[0], "Rank")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_string(&str, &response->response, &rank_info_fields[1], "NumEntries")) ++ return RC_MISSING_VALUE; ++ response->num_entries = (unsigned)atoi(str); ++ ++ if (!rc_json_get_required_array(&response->num_top_entries, &array_field, &response->response, &response_fields[3], "TopEntries")) ++ return RC_MISSING_VALUE; ++ ++ if (response->num_top_entries) { ++ response->top_entries = (rc_api_lboard_entry_t*)rc_buffer_alloc(&response->response.buffer, response->num_top_entries * sizeof(rc_api_lboard_entry_t)); ++ if (!response->top_entries) ++ return RC_OUT_OF_MEMORY; ++ ++ memset(&iterator, 0, sizeof(iterator)); ++ iterator.json = array_field.value_start; ++ iterator.end = array_field.value_end; ++ ++ entry = response->top_entries; ++ while (rc_json_get_array_entry_object(entry_fields, sizeof(entry_fields) / sizeof(entry_fields[0]), &iterator)) { ++ if (!rc_json_get_required_string(&entry->username, &response->response, &entry_fields[0], "User")) ++ return RC_MISSING_VALUE; ++ ++ if (!rc_json_get_required_unum(&entry->rank, &response->response, &entry_fields[1], "Rank")) ++ return RC_MISSING_VALUE; ++ ++ if (!rc_json_get_required_num(&entry->score, &response->response, &entry_fields[2], "Score")) ++ return RC_MISSING_VALUE; ++ ++ ++entry; ++ } ++ } ++ ++ return RC_OK; ++} ++ ++void rc_api_destroy_submit_lboard_entry_response(rc_api_submit_lboard_entry_response_t* response) { ++ rc_buffer_destroy(&response->response.buffer); ++} +diff -rupbN melonDS.orig/src/rcheevos/src/rapi/rc_api_user.c melonDS.ra/src/rcheevos/src/rapi/rc_api_user.c +--- melonDS.orig/src/rcheevos/src/rapi/rc_api_user.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rapi/rc_api_user.c 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,483 @@ ++#include "rc_api_user.h" ++#include "rc_api_common.h" ++#include "rc_api_runtime.h" ++#include "rc_consoles.h" ++ ++#include "../rc_version.h" ++ ++#include ++#include ++ ++/* --- Login --- */ ++ ++int rc_api_init_login_request(rc_api_request_t* request, const rc_api_login_request_t* api_params) { ++ return rc_api_init_login_request_hosted(request, api_params, &g_host); ++} ++ ++int rc_api_init_login_request_hosted(rc_api_request_t* request, ++ const rc_api_login_request_t* api_params, ++ const rc_api_host_t* host) { ++ rc_api_url_builder_t builder; ++ ++ rc_api_url_build_dorequest_url(request, host); ++ ++ if (!api_params->username || !*api_params->username) ++ return RC_INVALID_STATE; ++ ++ rc_url_builder_init(&builder, &request->buffer, 48); ++ rc_url_builder_append_str_param(&builder, "r", "login2"); ++ rc_url_builder_append_str_param(&builder, "u", api_params->username); ++ ++ if (api_params->password && api_params->password[0]) ++ rc_url_builder_append_str_param(&builder, "p", api_params->password); ++ else if (api_params->api_token && api_params->api_token[0]) ++ rc_url_builder_append_str_param(&builder, "t", api_params->api_token); ++ else ++ return RC_INVALID_STATE; ++ ++ request->post_data = rc_url_builder_finalize(&builder); ++ request->content_type = RC_CONTENT_TYPE_URLENCODED; ++ ++ return builder.result; ++} ++ ++int rc_api_process_login_response(rc_api_login_response_t* response, const char* server_response) { ++ rc_api_server_response_t response_obj; ++ ++ memset(&response_obj, 0, sizeof(response_obj)); ++ response_obj.body = server_response; ++ response_obj.body_length = rc_json_get_object_string_length(server_response); ++ ++ return rc_api_process_login_server_response(response, &response_obj); ++} ++ ++int rc_api_process_login_server_response(rc_api_login_response_t* response, const rc_api_server_response_t* server_response) { ++ int result; ++ rc_json_field_t fields[] = { ++ RC_JSON_NEW_FIELD("Success"), ++ RC_JSON_NEW_FIELD("Error"), ++ RC_JSON_NEW_FIELD("Code"), ++ RC_JSON_NEW_FIELD("User"), ++ RC_JSON_NEW_FIELD("Token"), ++ RC_JSON_NEW_FIELD("Score"), ++ RC_JSON_NEW_FIELD("SoftcoreScore"), ++ RC_JSON_NEW_FIELD("Messages"), ++ RC_JSON_NEW_FIELD("AvatarUrl") ++ }; ++ ++ memset(response, 0, sizeof(*response)); ++ rc_buffer_init(&response->response.buffer); ++ ++ result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0])); ++ if (result != RC_OK || !response->response.succeeded) ++ return result; ++ ++ if (!rc_json_get_required_string(&response->username, &response->response, &fields[3], "User")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_string(&response->api_token, &response->response, &fields[4], "Token")) ++ return RC_MISSING_VALUE; ++ ++ rc_json_get_optional_unum(&response->score, &fields[5], "Score", 0); ++ rc_json_get_optional_unum(&response->score_softcore, &fields[6], "SoftcoreScore", 0); ++ rc_json_get_optional_unum(&response->num_unread_messages, &fields[7], "Messages", 0); ++ ++ /* For the highest level of backwards compatibility, we have decided to just send the ++ * display_name back to the client as the "case-corrected username", and allow it to ++ * be used as the Username field for the other APIs. */ ++ response->display_name = response->username; ++ ++ rc_json_get_optional_string(&response->avatar_url, &response->response, &fields[8], "AvatarUrl", NULL); ++ if (!response->avatar_url) ++ response->avatar_url = rc_api_build_avatar_url(&response->response.buffer, RC_IMAGE_TYPE_USER, response->username); ++ ++ return RC_OK; ++} ++ ++void rc_api_destroy_login_response(rc_api_login_response_t* response) { ++ rc_buffer_destroy(&response->response.buffer); ++} ++ ++/* --- Start Session --- */ ++ ++int rc_api_init_start_session_request(rc_api_request_t* request, const rc_api_start_session_request_t* api_params) { ++ return rc_api_init_start_session_request_hosted(request, api_params, &g_host); ++} ++ ++int rc_api_init_start_session_request_hosted(rc_api_request_t* request, ++ const rc_api_start_session_request_t* api_params, ++ const rc_api_host_t* host) { ++ rc_api_url_builder_t builder; ++ ++ rc_api_url_build_dorequest_url(request, host); ++ ++ if (api_params->game_id == 0) ++ return RC_INVALID_STATE; ++ ++ rc_url_builder_init(&builder, &request->buffer, 48); ++ if (rc_api_url_build_dorequest(&builder, "startsession", api_params->username, api_params->api_token)) { ++ rc_url_builder_append_unum_param(&builder, "g", api_params->game_id); ++ ++ if (api_params->game_hash && *api_params->game_hash) { ++ rc_url_builder_append_unum_param(&builder, "h", api_params->hardcore); ++ rc_url_builder_append_str_param(&builder, "m", api_params->game_hash); ++ } ++ ++ rc_url_builder_append_str_param(&builder, "l", RCHEEVOS_VERSION_STRING); ++ ++ request->post_data = rc_url_builder_finalize(&builder); ++ request->content_type = RC_CONTENT_TYPE_URLENCODED; ++ } ++ ++ return builder.result; ++} ++ ++int rc_api_process_start_session_response(rc_api_start_session_response_t* response, const char* server_response) { ++ rc_api_server_response_t response_obj; ++ ++ memset(&response_obj, 0, sizeof(response_obj)); ++ response_obj.body = server_response; ++ response_obj.body_length = rc_json_get_object_string_length(server_response); ++ ++ return rc_api_process_start_session_server_response(response, &response_obj); ++} ++ ++int rc_api_process_start_session_server_response(rc_api_start_session_response_t* response, const rc_api_server_response_t* server_response) { ++ rc_api_unlock_entry_t* unlock; ++ rc_json_field_t array_field; ++ rc_json_iterator_t iterator; ++ uint32_t timet; ++ int result; ++ ++ rc_json_field_t fields[] = { ++ RC_JSON_NEW_FIELD("Success"), ++ RC_JSON_NEW_FIELD("Error"), ++ RC_JSON_NEW_FIELD("Unlocks"), ++ RC_JSON_NEW_FIELD("HardcoreUnlocks"), ++ RC_JSON_NEW_FIELD("ServerNow") ++ }; ++ ++ rc_json_field_t unlock_entry_fields[] = { ++ RC_JSON_NEW_FIELD("ID"), ++ RC_JSON_NEW_FIELD("When") ++ }; ++ ++ memset(response, 0, sizeof(*response)); ++ rc_buffer_init(&response->response.buffer); ++ ++ result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0])); ++ if (result != RC_OK || !response->response.succeeded) ++ return result; ++ ++ if (rc_json_get_optional_array(&response->num_unlocks, &array_field, &fields[2], "Unlocks") && response->num_unlocks) { ++ response->unlocks = (rc_api_unlock_entry_t*)rc_buffer_alloc(&response->response.buffer, response->num_unlocks * sizeof(rc_api_unlock_entry_t)); ++ if (!response->unlocks) ++ return RC_OUT_OF_MEMORY; ++ ++ memset(&iterator, 0, sizeof(iterator)); ++ iterator.json = array_field.value_start; ++ iterator.end = array_field.value_end; ++ ++ unlock = response->unlocks; ++ while (rc_json_get_array_entry_object(unlock_entry_fields, sizeof(unlock_entry_fields) / sizeof(unlock_entry_fields[0]), &iterator)) { ++ if (!rc_json_get_required_unum(&unlock->achievement_id, &response->response, &unlock_entry_fields[0], "ID")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_unum(&timet, &response->response, &unlock_entry_fields[1], "When")) ++ return RC_MISSING_VALUE; ++ unlock->when = (time_t)timet; ++ ++ ++unlock; ++ } ++ } ++ ++ if (rc_json_get_optional_array(&response->num_hardcore_unlocks, &array_field, &fields[3], "HardcoreUnlocks") && response->num_hardcore_unlocks) { ++ response->hardcore_unlocks = (rc_api_unlock_entry_t*)rc_buffer_alloc(&response->response.buffer, response->num_hardcore_unlocks * sizeof(rc_api_unlock_entry_t)); ++ if (!response->hardcore_unlocks) ++ return RC_OUT_OF_MEMORY; ++ ++ memset(&iterator, 0, sizeof(iterator)); ++ iterator.json = array_field.value_start; ++ iterator.end = array_field.value_end; ++ ++ unlock = response->hardcore_unlocks; ++ while (rc_json_get_array_entry_object(unlock_entry_fields, sizeof(unlock_entry_fields) / sizeof(unlock_entry_fields[0]), &iterator)) { ++ if (!rc_json_get_required_unum(&unlock->achievement_id, &response->response, &unlock_entry_fields[0], "ID")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_unum(&timet, &response->response, &unlock_entry_fields[1], "When")) ++ return RC_MISSING_VALUE; ++ unlock->when = (time_t)timet; ++ ++ ++unlock; ++ } ++ } ++ ++ rc_json_get_optional_unum(&timet, &fields[4], "ServerNow", 0); ++ response->server_now = (time_t)timet; ++ ++ return RC_OK; ++} ++ ++void rc_api_destroy_start_session_response(rc_api_start_session_response_t* response) { ++ rc_buffer_destroy(&response->response.buffer); ++} ++ ++/* --- Fetch User Unlocks --- */ ++ ++int rc_api_init_fetch_user_unlocks_request(rc_api_request_t* request, const rc_api_fetch_user_unlocks_request_t* api_params) { ++ return rc_api_init_fetch_user_unlocks_request_hosted(request, api_params, &g_host); ++} ++ ++int rc_api_init_fetch_user_unlocks_request_hosted(rc_api_request_t* request, ++ const rc_api_fetch_user_unlocks_request_t* api_params, ++ const rc_api_host_t* host) { ++ rc_api_url_builder_t builder; ++ ++ rc_api_url_build_dorequest_url(request, host); ++ ++ rc_url_builder_init(&builder, &request->buffer, 48); ++ if (rc_api_url_build_dorequest(&builder, "unlocks", api_params->username, api_params->api_token)) { ++ rc_url_builder_append_unum_param(&builder, "g", api_params->game_id); ++ rc_url_builder_append_unum_param(&builder, "h", api_params->hardcore ? 1 : 0); ++ request->post_data = rc_url_builder_finalize(&builder); ++ request->content_type = RC_CONTENT_TYPE_URLENCODED; ++ } ++ ++ return builder.result; ++} ++ ++int rc_api_process_fetch_user_unlocks_response(rc_api_fetch_user_unlocks_response_t* response, const char* server_response) { ++ rc_api_server_response_t response_obj; ++ ++ memset(&response_obj, 0, sizeof(response_obj)); ++ response_obj.body = server_response; ++ response_obj.body_length = rc_json_get_object_string_length(server_response); ++ ++ return rc_api_process_fetch_user_unlocks_server_response(response, &response_obj); ++} ++ ++int rc_api_process_fetch_user_unlocks_server_response(rc_api_fetch_user_unlocks_response_t* response, const rc_api_server_response_t* server_response) { ++ int result; ++ rc_json_field_t fields[] = { ++ RC_JSON_NEW_FIELD("Success"), ++ RC_JSON_NEW_FIELD("Error"), ++ RC_JSON_NEW_FIELD("UserUnlocks") ++ /* unused fields ++ RC_JSON_NEW_FIELD("GameID"), ++ RC_JSON_NEW_FIELD("HardcoreMode") ++ * unused fields */ ++ }; ++ ++ memset(response, 0, sizeof(*response)); ++ rc_buffer_init(&response->response.buffer); ++ ++ result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0])); ++ if (result != RC_OK || !response->response.succeeded) ++ return result; ++ ++ result = rc_json_get_required_unum_array(&response->achievement_ids, &response->num_achievement_ids, &response->response, &fields[2], "UserUnlocks"); ++ return result; ++} ++ ++void rc_api_destroy_fetch_user_unlocks_response(rc_api_fetch_user_unlocks_response_t* response) { ++ rc_buffer_destroy(&response->response.buffer); ++} ++ ++/* --- Fetch Followed Users --- */ ++ ++int rc_api_init_fetch_followed_users_request(rc_api_request_t* request, const rc_api_fetch_followed_users_request_t* api_params) { ++ return rc_api_init_fetch_followed_users_request_hosted(request, api_params, &g_host); ++} ++ ++int rc_api_init_fetch_followed_users_request_hosted(rc_api_request_t* request, ++ const rc_api_fetch_followed_users_request_t* api_params, ++ const rc_api_host_t* host) { ++ rc_api_url_builder_t builder; ++ ++ rc_api_url_build_dorequest_url(request, host); ++ ++ rc_url_builder_init(&builder, &request->buffer, 48); ++ if (rc_api_url_build_dorequest(&builder, "getfriendlist", api_params->username, api_params->api_token)) { ++ request->post_data = rc_url_builder_finalize(&builder); ++ request->content_type = RC_CONTENT_TYPE_URLENCODED; ++ } ++ ++ return builder.result; ++} ++ ++int rc_api_process_fetch_followed_users_server_response(rc_api_fetch_followed_users_response_t* response, const rc_api_server_response_t* server_response) { ++ rc_json_field_t array_field; ++ rc_json_iterator_t iterator; ++ rc_api_followed_user_t* user; ++ uint32_t timet; ++ int result; ++ rc_json_field_t fields[] = { ++ RC_JSON_NEW_FIELD("Success"), ++ RC_JSON_NEW_FIELD("Error"), ++ RC_JSON_NEW_FIELD("Friends") ++ }; ++ ++ rc_json_field_t followed_user_entry_fields[] = { ++ RC_JSON_NEW_FIELD("Friend"), ++ RC_JSON_NEW_FIELD("AvatarUrl"), ++ RC_JSON_NEW_FIELD("RAPoints"), ++ RC_JSON_NEW_FIELD("LastSeen"), ++ RC_JSON_NEW_FIELD("LastSeenTime"), ++ RC_JSON_NEW_FIELD("LastGameId"), ++ RC_JSON_NEW_FIELD("LastGameTitle"), ++ RC_JSON_NEW_FIELD("LastGameIconUrl"), ++ }; ++ ++ memset(response, 0, sizeof(*response)); ++ rc_buffer_init(&response->response.buffer); ++ ++ result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0])); ++ if (result != RC_OK || !response->response.succeeded) ++ return result; ++ ++ if (!rc_json_get_required_array(&response->num_users, &array_field, &response->response, &fields[2], "Friends")) ++ return RC_MISSING_VALUE; ++ ++ if (response->num_users) { ++ response->users = (rc_api_followed_user_t*)rc_buffer_alloc(&response->response.buffer, response->num_users * sizeof(rc_api_followed_user_t)); ++ if (!response->users) ++ return RC_OUT_OF_MEMORY; ++ ++ memset(&iterator, 0, sizeof(iterator)); ++ iterator.json = array_field.value_start; ++ iterator.end = array_field.value_end; ++ ++ user = response->users; ++ while (rc_json_get_array_entry_object(followed_user_entry_fields, sizeof(followed_user_entry_fields) / sizeof(followed_user_entry_fields[0]), &iterator)) { ++ if (!rc_json_get_required_string(&user->display_name, &response->response, &followed_user_entry_fields[0], "Friend")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_string(&user->avatar_url, &response->response, &followed_user_entry_fields[1], "AvatarUrl")) ++ return RC_MISSING_VALUE; ++ if (!rc_json_get_required_unum(&user->score, &response->response, &followed_user_entry_fields[2], "RAPoints")) ++ return RC_MISSING_VALUE; ++ ++ rc_json_get_optional_string(&user->recent_activity.description, &response->response, &followed_user_entry_fields[3], "LastSeen", NULL); ++ ++ rc_json_get_optional_unum(&timet, &followed_user_entry_fields[4], "LastSeenTime", 0); ++ user->recent_activity.when = (time_t)timet; ++ ++ rc_json_get_optional_unum(&user->recent_activity.context_id, &followed_user_entry_fields[5], "LastGameId", 0); ++ rc_json_get_optional_string(&user->recent_activity.context, &response->response, &followed_user_entry_fields[6], "LastGameTitle", NULL); ++ rc_json_get_optional_string(&user->recent_activity.context_image_url, &response->response, &followed_user_entry_fields[7], "LastGameIconUrl", NULL); ++ ++ ++user; ++ } ++ } ++ ++ return RC_OK; ++} ++ ++void rc_api_destroy_fetch_followed_users_response(rc_api_fetch_followed_users_response_t* response) { ++ rc_buffer_destroy(&response->response.buffer); ++} ++ ++/* --- Fetch All Progress --- */ ++ ++int rc_api_init_fetch_all_user_progress_request(rc_api_request_t* request, ++ const rc_api_fetch_all_user_progress_request_t* api_params) ++{ ++ return rc_api_init_fetch_all_user_progress_request_hosted(request, api_params, &g_host); ++} ++ ++int rc_api_init_fetch_all_user_progress_request_hosted(rc_api_request_t* request, ++ const rc_api_fetch_all_user_progress_request_t* api_params, ++ const rc_api_host_t* host) ++{ ++ rc_api_url_builder_t builder; ++ ++ rc_api_url_build_dorequest_url(request, host); ++ ++ if (api_params->console_id == RC_CONSOLE_UNKNOWN) ++ return RC_INVALID_STATE; ++ ++ rc_url_builder_init(&builder, &request->buffer, 48); ++ if (rc_api_url_build_dorequest(&builder, "allprogress", api_params->username, api_params->api_token)) ++ { ++ rc_url_builder_append_unum_param(&builder, "c", api_params->console_id); ++ request->post_data = rc_url_builder_finalize(&builder); ++ request->content_type = RC_CONTENT_TYPE_URLENCODED; ++ } ++ ++ return builder.result; ++} ++ ++int rc_api_process_fetch_all_user_progress_server_response(rc_api_fetch_all_user_progress_response_t* response, ++ const rc_api_server_response_t* server_response) ++{ ++ rc_api_all_user_progress_entry_t* entry; ++ int result; ++ ++ rc_json_field_t fields[] = { ++ RC_JSON_NEW_FIELD("Success"), ++ RC_JSON_NEW_FIELD("Error"), ++ RC_JSON_NEW_FIELD("Response"), ++ }; ++ ++ rc_json_field_t entry_fields[] = { ++ RC_JSON_NEW_FIELD("Achievements"), ++ RC_JSON_NEW_FIELD("Unlocked"), ++ RC_JSON_NEW_FIELD("UnlockedHardcore"), ++ }; ++ ++ memset(response, 0, sizeof(*response)); ++ rc_buffer_init(&response->response.buffer); ++ ++ result = ++ rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0])); ++ if (result != RC_OK || !response->response.succeeded) ++ return result; ++ ++ if (!fields[2].value_start) { ++ /* call rc_json_get_required_object to generate the error message */ ++ rc_json_get_required_object(NULL, 0, &response->response, &fields[2], "Response"); ++ return RC_MISSING_VALUE; ++ } ++ ++ response->num_entries = fields[2].array_size; ++ ++ if (response->num_entries > 0) { ++ rc_json_iterator_t iterator; ++ rc_json_field_t field; ++ char* end; ++ ++ rc_buffer_reserve(&response->response.buffer, response->num_entries * sizeof(rc_api_all_user_progress_entry_t)); ++ ++ response->entries = (rc_api_all_user_progress_entry_t*)rc_buffer_alloc( ++ &response->response.buffer, response->num_entries * sizeof(rc_api_all_user_progress_entry_t)); ++ if (!response->entries) ++ return RC_OUT_OF_MEMORY; ++ ++ memset(&iterator, 0, sizeof(iterator)); ++ iterator.json = fields[2].value_start; ++ iterator.end = fields[2].value_end; ++ ++ entry = response->entries; ++ while (rc_json_get_next_object_field(&iterator, &field)) ++ { ++ entry->game_id = strtol(field.name, &end, 10); ++ ++ field.name = ""; ++ if (!rc_json_get_required_object(entry_fields, sizeof(entry_fields) / sizeof(entry_fields[0]), ++ &response->response, &field, "")) ++ { ++ return RC_MISSING_VALUE; ++ } ++ ++ rc_json_get_optional_unum(&entry->num_achievements, &entry_fields[0], "Achievements", 0); ++ rc_json_get_optional_unum(&entry->num_unlocked_achievements, &entry_fields[1], "Unlocked", 0); ++ rc_json_get_optional_unum(&entry->num_unlocked_achievements_hardcore, &entry_fields[2], "UnlockedHardcore", 0); ++ ++ ++entry; ++ } ++ } ++ ++ return RC_OK; ++} ++ ++void rc_api_destroy_fetch_all_user_progress_response(rc_api_fetch_all_user_progress_response_t* response) ++{ ++ rc_buffer_destroy(&response->response.buffer); ++} +diff -rupbN melonDS.orig/src/rcheevos/src/rc_client.c melonDS.ra/src/rcheevos/src/rc_client.c +--- melonDS.orig/src/rcheevos/src/rc_client.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rc_client.c 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,6775 @@ ++#include "rc_client_internal.h" ++ ++#include "rc_api_info.h" ++#include "rc_api_runtime.h" ++#include "rc_api_user.h" ++#include "rc_consoles.h" ++#include "rc_hash.h" ++#include "rc_version.h" ++ ++#include "rapi/rc_api_common.h" ++ ++#include "rcheevos/rc_internal.h" ++ ++#include ++ ++#ifdef _WIN32 ++#define WIN32_LEAN_AND_MEAN ++#include ++#include ++#else ++#include ++#endif ++ ++#define RC_CLIENT_UNKNOWN_GAME_ID (uint32_t)-1 ++#define RC_CLIENT_RECENT_UNLOCK_DELAY_SECONDS (10 * 60) /* ten minutes */ ++ ++#define RC_MINIMUM_UNPAUSED_FRAMES 20 ++#define RC_PAUSE_DECAY_MULTIPLIER 4 ++ ++enum { ++ RC_CLIENT_ASYNC_NOT_ABORTED = 0, ++ RC_CLIENT_ASYNC_ABORTED = 1, ++ RC_CLIENT_ASYNC_DESTROYED = 2 ++}; ++ ++typedef struct rc_client_generic_callback_data_t { ++ rc_client_t* client; ++ rc_client_callback_t callback; ++ void* callback_userdata; ++ rc_client_async_handle_t async_handle; ++} rc_client_generic_callback_data_t; ++ ++typedef struct rc_client_pending_media_t ++{ ++#ifdef RC_CLIENT_SUPPORTS_HASH ++ const char* file_path; ++ uint8_t* data; ++ size_t data_size; ++#endif ++ const char* hash; ++ rc_client_callback_t callback; ++ void* callback_userdata; ++} rc_client_pending_media_t; ++ ++typedef struct rc_client_load_state_t ++{ ++ rc_client_t* client; ++ rc_client_callback_t callback; ++ void* callback_userdata; ++ ++ rc_client_game_info_t* game; ++ rc_client_subset_info_t* subset; ++ rc_client_game_hash_t* hash; ++ ++#ifdef RC_CLIENT_SUPPORTS_HASH ++ rc_hash_iterator_t hash_iterator; ++ rc_client_game_hash_t* tried_hashes[4]; ++#endif ++ rc_client_pending_media_t* pending_media; ++ ++ rc_api_start_session_response_t *start_session_response; ++ ++ rc_client_async_handle_t async_handle; ++ ++ uint8_t progress; ++ uint8_t outstanding_requests; ++#ifdef RC_CLIENT_SUPPORTS_HASH ++ uint8_t hash_console_id; ++#endif ++} rc_client_load_state_t; ++ ++static void rc_client_process_resolved_hash(rc_client_load_state_t* load_state); ++static void rc_client_begin_fetch_game_sets(rc_client_load_state_t* callback_data); ++static void rc_client_hide_progress_tracker(rc_client_t* client, rc_client_game_info_t* game); ++static void rc_client_load_error(rc_client_load_state_t* load_state, int result, const char* error_message); ++static rc_client_async_handle_t* rc_client_load_game(rc_client_load_state_t* load_state, const char* hash, const char* file_path); ++static void rc_client_ping(rc_client_scheduled_callback_data_t* callback_data, rc_client_t* client, rc_clock_t now); ++static void rc_client_raise_leaderboard_events(rc_client_t* client, rc_client_subset_info_t* subset); ++static void rc_client_raise_pending_events(rc_client_t* client, rc_client_game_info_t* game); ++static void rc_client_reschedule_callback(rc_client_t* client, rc_client_scheduled_callback_data_t* callback, rc_clock_t when); ++static void rc_client_award_achievement_retry(rc_client_scheduled_callback_data_t* callback_data, rc_client_t* client, rc_clock_t now); ++static int rc_client_is_award_achievement_pending(const rc_client_t* client, uint32_t achievement_id); ++static void rc_client_submit_leaderboard_entry_retry(rc_client_scheduled_callback_data_t* callback_data, rc_client_t* client, rc_clock_t now); ++ ++/* ===== natvis extensions ===== */ ++ ++typedef struct __rc_client_achievement_state_enum_t { uint8_t value; } __rc_client_achievement_state_enum_t; ++typedef struct __rc_client_achievement_category_enum_t { uint8_t value; } __rc_client_achievement_category_enum_t; ++typedef struct __rc_client_achievement_type_enum_t { uint8_t value; } __rc_client_achievement_type_enum_t; ++typedef struct __rc_client_achievement_bucket_enum_t { uint8_t value; } __rc_client_achievement_bucket_enum_t; ++typedef struct __rc_client_achievement_unlocked_enum_t { uint8_t value; } __rc_client_achievement_unlocked_enum_t; ++typedef struct __rc_client_leaderboard_state_enum_t { uint8_t value; } __rc_client_leaderboard_state_enum_t; ++typedef struct __rc_client_leaderboard_format_enum_t { uint8_t value; } __rc_client_leaderboard_format_enum_t; ++typedef struct __rc_client_log_level_enum_t { uint8_t value; } __rc_client_log_level_enum_t; ++typedef struct __rc_client_event_type_enum_t { uint8_t value; } __rc_client_event_type_enum_t; ++typedef struct __rc_client_load_game_state_enum_t { uint8_t value; } __rc_client_load_game_state_enum_t; ++typedef struct __rc_client_user_state_enum_t { uint8_t value; } __rc_client_user_state_enum_t; ++typedef struct __rc_client_mastery_state_enum_t { uint8_t value; } __rc_client_mastery_state_enum_t; ++typedef struct __rc_client_spectator_mode_enum_t { uint8_t value; } __rc_client_spectator_mode_enum_t; ++typedef struct __rc_client_disconnect_enum_t { uint8_t value; } __rc_client_disconnect_enum_t; ++typedef struct __rc_client_leaderboard_tracker_list_t { rc_client_leaderboard_tracker_info_t* first; } __rc_client_leaderboard_tracker_list_t; ++typedef struct __rc_client_subset_info_list_t { rc_client_subset_info_t* first; } __rc_client_subset_info_list_t; ++typedef struct __rc_client_media_hash_list_t { rc_client_media_hash_t* first; } __rc_client_media_hash_list_t; ++typedef struct __rc_client_subset_info_achievements_list_t { rc_client_subset_info_t info; } __rc_client_subset_info_achievements_list_t; ++typedef struct __rc_client_subset_info_leaderboards_list_t { rc_client_subset_info_t info; } __rc_client_subset_info_leaderboards_list_t; ++typedef struct __rc_client_scheduled_callback_list_t { rc_client_state_t state; } __rc_client_scheduled_callback_list_t; ++typedef struct __rc_client_game_hash_list_t { rc_client_t client; } __rc_client_game_hash_list_t; ++ ++static void rc_client_natvis_helper(const rc_client_event_t* event, rc_client_t* client) ++{ ++ struct natvis_extensions { ++ __rc_client_achievement_state_enum_t achievement_state; ++ __rc_client_achievement_category_enum_t achievement_category; ++ __rc_client_achievement_type_enum_t achievement_type; ++ __rc_client_achievement_bucket_enum_t achievement_bucket; ++ __rc_client_achievement_unlocked_enum_t achievement_unlocked; ++ __rc_client_leaderboard_state_enum_t leaderboard_state; ++ __rc_client_leaderboard_format_enum_t leaderboard_format; ++ __rc_client_log_level_enum_t log_level; ++ __rc_client_event_type_enum_t event_type; ++ __rc_client_load_game_state_enum_t load_game_state; ++ __rc_client_user_state_enum_t user_state; ++ __rc_client_mastery_state_enum_t mastery_state; ++ __rc_client_spectator_mode_enum_t spectator_mode; ++ __rc_client_disconnect_enum_t disconnect; ++ __rc_client_leaderboard_tracker_list_t leaderboard_tracker_list; ++ __rc_client_subset_info_list_t subset_info_list; ++ __rc_client_media_hash_list_t media_hash_list; ++ __rc_client_subset_info_achievements_list_t subset_info_achievements_list; ++ __rc_client_subset_info_leaderboards_list_t subset_info_leaderboards_list; ++ __rc_client_scheduled_callback_list_t scheduled_callback_list; ++ __rc_client_game_hash_list_t client_game_hash_list; ++ } natvis; ++ ++ memset(&natvis, 0, sizeof(natvis)); ++ (void)event; ++ (void)client; ++ ++ /* this code should never be executed. it just ensures these constants get defined for ++ * the natvis VisualStudio extension as they're not used directly in the code. */ ++ natvis.achievement_type.value = RC_CLIENT_ACHIEVEMENT_TYPE_STANDARD; ++ natvis.achievement_type.value = RC_CLIENT_ACHIEVEMENT_TYPE_MISSABLE; ++ natvis.achievement_type.value = RC_CLIENT_ACHIEVEMENT_TYPE_PROGRESSION; ++ natvis.achievement_type.value = RC_CLIENT_ACHIEVEMENT_TYPE_WIN; ++ natvis.achievement_category.value = RC_CLIENT_ACHIEVEMENT_CATEGORY_NONE; ++ natvis.event_type.value = RC_CLIENT_EVENT_TYPE_NONE; ++} ++ ++/* ===== Construction/Destruction ===== */ ++ ++static void rc_client_dummy_event_handler(const rc_client_event_t* event, rc_client_t* client) ++{ ++ (void)event; ++ (void)client; ++} ++ ++rc_client_t* rc_client_create(rc_client_read_memory_func_t read_memory_function, rc_client_server_call_t server_call_function) ++{ ++ rc_client_t* client = (rc_client_t*)calloc(1, sizeof(rc_client_t)); ++ if (!client) ++ return NULL; ++ ++ client->state.hardcore = 1; ++ client->state.required_unpaused_frames = RC_MINIMUM_UNPAUSED_FRAMES; ++ client->state.allow_background_memory_reads = 1; ++ ++ client->callbacks.read_memory = read_memory_function; ++ client->callbacks.server_call = server_call_function; ++ client->callbacks.event_handler = rc_client_natvis_helper; ++ client->callbacks.event_handler = rc_client_dummy_event_handler; ++ rc_client_set_legacy_peek(client, RC_CLIENT_LEGACY_PEEK_AUTO); ++ rc_client_set_get_time_millisecs_function(client, NULL); ++ ++ rc_mutex_init(&client->state.mutex); ++ ++ rc_buffer_init(&client->state.buffer); ++ ++ return client; ++} ++ ++void rc_client_destroy(rc_client_t* client) ++{ ++ if (!client) ++ return; ++ ++ rc_mutex_lock(&client->state.mutex); ++ { ++ size_t i; ++ for (i = 0; i < sizeof(client->state.async_handles) / sizeof(client->state.async_handles[0]); ++i) { ++ if (client->state.async_handles[i]) ++ client->state.async_handles[i]->aborted = RC_CLIENT_ASYNC_DESTROYED; ++ } ++ ++ if (client->state.load) { ++ client->state.load->async_handle.aborted = RC_CLIENT_ASYNC_DESTROYED; ++ client->state.load = NULL; ++ } ++ } ++ rc_mutex_unlock(&client->state.mutex); ++ ++ rc_client_unload_game(client); ++ ++#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION ++ rc_client_unload_raintegration(client); ++#endif ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->destroy) ++ client->state.external_client->destroy(); ++#endif ++ ++ rc_buffer_destroy(&client->state.buffer); ++ ++ rc_mutex_destroy(&client->state.mutex); ++ ++ free(client); ++} ++ ++/* ===== Logging ===== */ ++ ++void rc_client_log_message(const rc_client_t* client, const char* message) ++{ ++ if (client->callbacks.log_call) ++ client->callbacks.log_call(message, client); ++} ++ ++static void rc_client_log_message_va(const rc_client_t* client, const char* format, va_list args) ++{ ++ if (client->callbacks.log_call) { ++ char buffer[2048]; ++ ++#ifdef __STDC_SECURE_LIB__ ++ vsprintf_s(buffer, sizeof(buffer), format, args); ++#elif __STDC_VERSION__ >= 199901L /* vsnprintf requires c99 */ ++ vsnprintf(buffer, sizeof(buffer), format, args); ++#else /* c89 doesn't have a size-limited vsprintf function - assume the buffer is large enough */ ++ vsprintf(buffer, format, args); ++#endif ++ ++ client->callbacks.log_call(buffer, client); ++ } ++} ++ ++#ifdef RC_NO_VARIADIC_MACROS ++ ++void RC_CLIENT_LOG_ERR_FORMATTED(const rc_client_t* client, const char* format, ...) ++{ ++ if (client->state.log_level >= RC_CLIENT_LOG_LEVEL_ERROR) { ++ va_list args; ++ va_start(args, format); ++ rc_client_log_message_va(client, format, args); ++ va_end(args); ++ } ++} ++ ++void RC_CLIENT_LOG_WARN_FORMATTED(const rc_client_t* client, const char* format, ...) ++{ ++ if (client->state.log_level >= RC_CLIENT_LOG_LEVEL_WARN) { ++ va_list args; ++ va_start(args, format); ++ rc_client_log_message_va(client, format, args); ++ va_end(args); ++ } ++} ++ ++void RC_CLIENT_LOG_INFO_FORMATTED(const rc_client_t* client, const char* format, ...) ++{ ++ if (client->state.log_level >= RC_CLIENT_LOG_LEVEL_INFO) { ++ va_list args; ++ va_start(args, format); ++ rc_client_log_message_va(client, format, args); ++ va_end(args); ++ } ++} ++ ++void RC_CLIENT_LOG_VERBOSE_FORMATTED(const rc_client_t* client, const char* format, ...) ++{ ++ if (client->state.log_level >= RC_CLIENT_LOG_LEVEL_VERBOSE) { ++ va_list args; ++ va_start(args, format); ++ rc_client_log_message_va(client, format, args); ++ va_end(args); ++ } ++} ++ ++#else ++ ++void rc_client_log_message_formatted(const rc_client_t* client, const char* format, ...) ++{ ++ va_list args; ++ va_start(args, format); ++ rc_client_log_message_va(client, format, args); ++ va_end(args); ++} ++ ++#endif /* RC_NO_VARIADIC_MACROS */ ++ ++void rc_client_enable_logging(rc_client_t* client, int level, rc_client_message_callback_t callback) ++{ ++ client->callbacks.log_call = callback; ++ client->state.log_level = callback ? level : RC_CLIENT_LOG_LEVEL_NONE; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->enable_logging) ++ client->state.external_client->enable_logging(client, level, callback); ++#endif ++} ++ ++/* ===== Common ===== */ ++ ++static rc_clock_t rc_client_clock_get_now_millisecs(const rc_client_t* client) ++{ ++#if defined(CLOCK_MONOTONIC) ++ struct timespec now; ++ (void)client; ++ ++ if (clock_gettime(CLOCK_MONOTONIC, &now) < 0) ++ return 0; ++ ++ /* round nanoseconds to nearest millisecond and add to seconds */ ++ return ((rc_clock_t)now.tv_sec * 1000 + ((rc_clock_t)now.tv_nsec / 1000000)); ++#elif defined(_WIN32) ++ static LARGE_INTEGER freq; ++ LARGE_INTEGER ticks; ++ ++ (void)client; ++ ++ /* Frequency is the number of ticks per second and is guaranteed to not change. */ ++ if (!freq.QuadPart) { ++ if (!QueryPerformanceFrequency(&freq)) ++ return 0; ++ ++ /* convert to number of ticks per millisecond to simplify later calculations */ ++ freq.QuadPart /= 1000; ++ } ++ ++ if (!QueryPerformanceCounter(&ticks)) ++ return 0; ++ ++ return (rc_clock_t)(ticks.QuadPart / freq.QuadPart); ++#else ++ const clock_t clock_now = clock(); ++ ++ (void)client; ++ ++ if (sizeof(clock_t) == 4) { ++ static uint32_t clock_wraps = 0; ++ static clock_t last_clock = 0; ++ static time_t last_timet = 0; ++ const time_t time_now = time(NULL); ++ ++ if (last_timet != 0) { ++ const time_t seconds_per_clock_t = (time_t)(((uint64_t)1 << 32) / CLOCKS_PER_SEC); ++ if (clock_now < last_clock) { ++ /* clock() has wrapped */ ++ ++clock_wraps; ++ } ++ else if (time_now - last_timet > seconds_per_clock_t) { ++ /* it's been long enough that clock() has wrapped and is higher than the last time it was read */ ++ ++clock_wraps; ++ } ++ } ++ ++ last_timet = time_now; ++ last_clock = clock_now; ++ ++ return (rc_clock_t)((((uint64_t)clock_wraps << 32) | clock_now) / (CLOCKS_PER_SEC / 1000)); ++ } ++ else { ++ return (rc_clock_t)(clock_now / (CLOCKS_PER_SEC / 1000)); ++ } ++#endif ++} ++ ++void rc_client_set_get_time_millisecs_function(rc_client_t* client, rc_get_time_millisecs_func_t handler) ++{ ++ client->callbacks.get_time_millisecs = handler ? handler : rc_client_clock_get_now_millisecs; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->set_get_time_millisecs) ++ client->state.external_client->set_get_time_millisecs(client, handler); ++#endif ++} ++ ++int rc_client_async_handle_aborted(rc_client_t* client, rc_client_async_handle_t* async_handle) ++{ ++ int aborted; ++ ++ rc_mutex_lock(&client->state.mutex); ++ aborted = async_handle->aborted; ++ rc_mutex_unlock(&client->state.mutex); ++ ++ return aborted; ++} ++ ++static void rc_client_begin_async(rc_client_t* client, rc_client_async_handle_t* async_handle) ++{ ++ size_t i; ++ ++ rc_mutex_lock(&client->state.mutex); ++ for (i = 0; i < sizeof(client->state.async_handles) / sizeof(client->state.async_handles[0]); ++i) { ++ if (!client->state.async_handles[i]) { ++ client->state.async_handles[i] = async_handle; ++ break; ++ } ++ } ++ rc_mutex_unlock(&client->state.mutex); ++} ++ ++static int rc_client_end_async(rc_client_t* client, rc_client_async_handle_t* async_handle) ++{ ++ int aborted = async_handle->aborted; ++ ++ /* if client was destroyed, mutex doesn't exist and we don't need to remove the handle from the collection */ ++ if (aborted != RC_CLIENT_ASYNC_DESTROYED) { ++ size_t i; ++ ++ rc_mutex_lock(&client->state.mutex); ++ for (i = 0; i < sizeof(client->state.async_handles) / sizeof(client->state.async_handles[0]); ++i) { ++ if (client->state.async_handles[i] == async_handle) { ++ client->state.async_handles[i] = NULL; ++ break; ++ } ++ } ++ aborted = async_handle->aborted; ++ ++ rc_mutex_unlock(&client->state.mutex); ++ } ++ ++ return aborted; ++} ++ ++void rc_client_abort_async(rc_client_t* client, rc_client_async_handle_t* async_handle) ++{ ++ if (async_handle && client) { ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->abort_async) { ++ client->state.external_client->abort_async(async_handle); ++ return; ++ } ++#endif ++ ++ rc_mutex_lock(&client->state.mutex); ++ async_handle->aborted = RC_CLIENT_ASYNC_ABORTED; ++ rc_mutex_unlock(&client->state.mutex); ++ } ++} ++ ++static int rc_client_async_handle_valid(rc_client_t* client, rc_client_async_handle_t* async_handle) ++{ ++ int valid = 0; ++ size_t i; ++ ++ /* there is a small window of opportunity where the client could have been destroyed before calling ++ * this function, but this function assumes the possibility that the handle has been destroyed, so ++ * we can't check it for RC_CLIENT_ASYNC_DESTROYED before attempting to scan the client data */ ++ rc_mutex_lock(&client->state.mutex); ++ ++ for (i = 0; i < sizeof(client->state.async_handles) / sizeof(client->state.async_handles[0]); ++i) { ++ if (client->state.async_handles[i] == async_handle) { ++ valid = 1; ++ break; ++ } ++ } ++ ++ rc_mutex_unlock(&client->state.mutex); ++ ++ return valid; ++} ++ ++static const char* rc_client_server_error_message(int* result, int http_status_code, const rc_api_response_t* response) ++{ ++ if (!response->succeeded) { ++ if (*result == RC_OK) { ++ *result = RC_API_FAILURE; ++ if (!response->error_message) ++ return "Unexpected API failure with no error message"; ++ } ++ ++ if (response->error_message) ++ return response->error_message; ++ } ++ ++ (void)http_status_code; ++ ++ if (*result != RC_OK) ++ return rc_error_str(*result); ++ ++ return NULL; ++} ++ ++static void rc_client_raise_server_error_event(rc_client_t* client, ++ const char* api, uint32_t related_id, int result, const char* error_message) ++{ ++ rc_client_server_error_t server_error; ++ rc_client_event_t client_event; ++ ++ server_error.api = api; ++ server_error.error_message = error_message; ++ server_error.result = result; ++ server_error.related_id = related_id; ++ ++ memset(&client_event, 0, sizeof(client_event)); ++ client_event.type = RC_CLIENT_EVENT_SERVER_ERROR; ++ client_event.server_error = &server_error; ++ ++ client->callbacks.event_handler(&client_event, client); ++} ++ ++static void rc_client_update_disconnect_state(rc_client_t* client) ++{ ++ rc_client_scheduled_callback_data_t* scheduled_callback; ++ uint8_t new_state = RC_CLIENT_DISCONNECT_HIDDEN; ++ ++ rc_mutex_lock(&client->state.mutex); ++ ++ scheduled_callback = client->state.scheduled_callbacks; ++ for (; scheduled_callback; scheduled_callback = scheduled_callback->next) { ++ if (scheduled_callback->callback == rc_client_award_achievement_retry || ++ scheduled_callback->callback == rc_client_submit_leaderboard_entry_retry) { ++ new_state = RC_CLIENT_DISCONNECT_VISIBLE; ++ break; ++ } ++ } ++ ++ if ((client->state.disconnect & RC_CLIENT_DISCONNECT_VISIBLE) != new_state) { ++ if (new_state == RC_CLIENT_DISCONNECT_VISIBLE) ++ client->state.disconnect = RC_CLIENT_DISCONNECT_HIDDEN | RC_CLIENT_DISCONNECT_SHOW_PENDING; ++ else ++ client->state.disconnect = RC_CLIENT_DISCONNECT_VISIBLE | RC_CLIENT_DISCONNECT_HIDE_PENDING; ++ } ++ else { ++ client->state.disconnect = new_state; ++ } ++ ++ rc_mutex_unlock(&client->state.mutex); ++} ++ ++static void rc_client_raise_disconnect_events(rc_client_t* client) ++{ ++ rc_client_event_t client_event; ++ uint8_t new_state; ++ ++ rc_mutex_lock(&client->state.mutex); ++ ++ if (client->state.disconnect & RC_CLIENT_DISCONNECT_SHOW_PENDING) ++ new_state = RC_CLIENT_DISCONNECT_VISIBLE; ++ else ++ new_state = RC_CLIENT_DISCONNECT_HIDDEN; ++ client->state.disconnect = new_state; ++ ++ rc_mutex_unlock(&client->state.mutex); ++ ++ memset(&client_event, 0, sizeof(client_event)); ++ client_event.type = (new_state == RC_CLIENT_DISCONNECT_VISIBLE) ? ++ RC_CLIENT_EVENT_DISCONNECTED : RC_CLIENT_EVENT_RECONNECTED; ++ client->callbacks.event_handler(&client_event, client); ++} ++ ++static int rc_client_should_retry(const rc_api_server_response_t* server_response) ++{ ++ switch (server_response->http_status_code) { ++ case 502: /* 502 Bad Gateway */ ++ /* nginx connection pool full */ ++ return 1; ++ ++ case 503: /* 503 Service Temporarily Unavailable */ ++ /* site is in maintenance mode */ ++ return 1; ++ ++ case 504: /* 504 Gateway Timeout */ ++ /* timeout between web server and database server */ ++ return 1; ++ ++ case 429: /* 429 Too Many Requests */ ++ /* too many unlocks occurred at the same time */ ++ return 1; ++ ++ case 521: /* 521 Web Server is Down */ ++ /* cloudfare could not find the server */ ++ return 1; ++ ++ case 522: /* 522 Connection Timed Out */ ++ /* timeout connecting to server from cloudfare */ ++ return 1; ++ ++ case 523: /* 523 Origin is Unreachable */ ++ /* cloudfare cannot find server */ ++ return 1; ++ ++ case 524: /* 524 A Timeout Occurred */ ++ /* connection to server from cloudfare was dropped before request was completed */ ++ return 1; ++ ++ case 525: /* 525 SSL Handshake Failed */ ++ /* web server worker connection pool is exhausted */ ++ return 1; ++ ++ case RC_API_SERVER_RESPONSE_RETRYABLE_CLIENT_ERROR: ++ /* client provided non-HTTP error (explicitly retryable) */ ++ return 1; ++ ++ case RC_API_SERVER_RESPONSE_CLIENT_ERROR: ++ /* client provided non-HTTP error (implicitly non-retryable) */ ++ return 0; ++ ++ default: ++ /* assume any error not handled above where no response was received should be retried */ ++ if (server_response->body_length == 0 || !server_response->body || !server_response->body[0]) ++ return 1; ++ ++ return 0; ++ } ++} ++ ++static int rc_client_get_image_url(char buffer[], size_t buffer_size, int image_type, const char* image_name) ++{ ++ rc_api_fetch_image_request_t image_request; ++ rc_api_request_t request; ++ int result; ++ ++ if (!buffer) ++ return RC_INVALID_STATE; ++ ++ memset(&image_request, 0, sizeof(image_request)); ++ image_request.image_type = image_type; ++ image_request.image_name = image_name; ++ result = rc_api_init_fetch_image_request_hosted(&request, &image_request, NULL); ++ if (result == RC_OK) ++ snprintf(buffer, buffer_size, "%s", request.url); ++ ++ rc_api_destroy_request(&request); ++ return result; ++} ++ ++/* ===== User ===== */ ++ ++static void rc_client_login_callback(const rc_api_server_response_t* server_response, void* callback_data) ++{ ++ rc_client_generic_callback_data_t* login_callback_data = (rc_client_generic_callback_data_t*)callback_data; ++ rc_client_t* client = login_callback_data->client; ++ rc_api_login_response_t login_response; ++ rc_client_load_state_t* load_state; ++ const char* error_message; ++ int result; ++ ++ result = rc_client_end_async(client, &login_callback_data->async_handle); ++ if (result) { ++ if (result != RC_CLIENT_ASYNC_DESTROYED) ++ rc_client_logout(client); /* logout will reset the user state and call the load game callback */ ++ ++ free(login_callback_data); ++ return; ++ } ++ ++ if (client->state.user == RC_CLIENT_USER_STATE_NONE) { ++ /* logout was called */ ++ if (login_callback_data->callback) ++ login_callback_data->callback(RC_ABORTED, "Login aborted", client, login_callback_data->callback_userdata); ++ ++ free(login_callback_data); ++ /* logout call will immediately abort load game before this callback gets called */ ++ return; ++ } ++ ++ result = rc_api_process_login_server_response(&login_response, server_response); ++ error_message = rc_client_server_error_message(&result, server_response->http_status_code, &login_response.response); ++ if (error_message) { ++ rc_mutex_lock(&client->state.mutex); ++ client->state.user = RC_CLIENT_USER_STATE_NONE; ++ load_state = client->state.load; ++ rc_mutex_unlock(&client->state.mutex); ++ ++ RC_CLIENT_LOG_ERR_FORMATTED(client, "Login failed: %s", error_message); ++ if (login_callback_data->callback) ++ login_callback_data->callback(result, error_message, client, login_callback_data->callback_userdata); ++ ++ if (load_state && load_state->progress == RC_CLIENT_LOAD_GAME_STATE_AWAIT_LOGIN) ++ rc_client_begin_fetch_game_sets(load_state); ++ } ++ else { ++ client->user.username = rc_buffer_strcpy(&client->state.buffer, login_response.username); ++ ++ if (strcmp(login_response.username, login_response.display_name) == 0) ++ client->user.display_name = client->user.username; ++ else ++ client->user.display_name = rc_buffer_strcpy(&client->state.buffer, login_response.display_name); ++ ++ client->user.avatar_url = rc_buffer_strcpy(&client->state.buffer, login_response.avatar_url); ++ client->user.token = rc_buffer_strcpy(&client->state.buffer, login_response.api_token); ++ client->user.score = login_response.score; ++ client->user.score_softcore = login_response.score_softcore; ++ client->user.num_unread_messages = login_response.num_unread_messages; ++ ++ rc_mutex_lock(&client->state.mutex); ++ client->state.user = RC_CLIENT_USER_STATE_LOGGED_IN; ++ load_state = client->state.load; ++ rc_mutex_unlock(&client->state.mutex); ++ ++ RC_CLIENT_LOG_INFO_FORMATTED(client, "%s logged in successfully", login_response.display_name); ++ ++ if (load_state && load_state->progress == RC_CLIENT_LOAD_GAME_STATE_AWAIT_LOGIN) ++ rc_client_begin_fetch_game_sets(load_state); ++ ++ if (login_callback_data->callback) ++ login_callback_data->callback(RC_OK, NULL, client, login_callback_data->callback_userdata); ++ } ++ ++ rc_api_destroy_login_response(&login_response); ++ free(login_callback_data); ++} ++ ++static rc_client_async_handle_t* rc_client_begin_login(rc_client_t* client, ++ const rc_api_login_request_t* login_request, rc_client_callback_t callback, void* callback_userdata) ++{ ++ rc_client_generic_callback_data_t* callback_data; ++ rc_api_request_t request; ++ int result = rc_api_init_login_request_hosted(&request, login_request, &client->state.host); ++ const char* error_message = rc_error_str(result); ++ ++ if (result == RC_OK) { ++ rc_mutex_lock(&client->state.mutex); ++ ++ if (client->state.user == RC_CLIENT_USER_STATE_LOGIN_REQUESTED) { ++ error_message = "Login already in progress"; ++ result = RC_INVALID_STATE; ++ } ++ client->state.user = RC_CLIENT_USER_STATE_LOGIN_REQUESTED; ++ ++ rc_mutex_unlock(&client->state.mutex); ++ } ++ ++ if (result != RC_OK) { ++ callback(result, error_message, client, callback_userdata); ++ return NULL; ++ } ++ ++ callback_data = (rc_client_generic_callback_data_t*)calloc(1, sizeof(*callback_data)); ++ if (!callback_data) { ++ callback(RC_OUT_OF_MEMORY, rc_error_str(RC_OUT_OF_MEMORY), client, callback_userdata); ++ return NULL; ++ } ++ ++ callback_data->client = client; ++ callback_data->callback = callback; ++ callback_data->callback_userdata = callback_userdata; ++ ++ rc_client_begin_async(client, &callback_data->async_handle); ++ client->callbacks.server_call(&request, rc_client_login_callback, callback_data, client); ++ ++ rc_api_destroy_request(&request); ++ ++ /* if the user state has changed, the async operation completed synchronously */ ++ rc_mutex_lock(&client->state.mutex); ++ if (client->state.user != RC_CLIENT_USER_STATE_LOGIN_REQUESTED) ++ callback_data = NULL; ++ rc_mutex_unlock(&client->state.mutex); ++ ++ return callback_data ? &callback_data->async_handle : NULL; ++} ++ ++rc_client_async_handle_t* rc_client_begin_login_with_password(rc_client_t* client, ++ const char* username, const char* password, rc_client_callback_t callback, void* callback_userdata) ++{ ++ rc_api_login_request_t login_request; ++ ++ if (!client) { ++ callback(RC_INVALID_STATE, "client is required", client, callback_userdata); ++ return NULL; ++ } ++ ++ if (!username || !username[0]) { ++ callback(RC_INVALID_STATE, "username is required", client, callback_userdata); ++ return NULL; ++ } ++ ++ if (!password || !password[0]) { ++ callback(RC_INVALID_STATE, "password is required", client, callback_userdata); ++ return NULL; ++ } ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->begin_login_with_password) ++ return client->state.external_client->begin_login_with_password(client, username, password, callback, callback_userdata); ++#endif ++ ++ memset(&login_request, 0, sizeof(login_request)); ++ login_request.username = username; ++ login_request.password = password; ++ ++ RC_CLIENT_LOG_INFO_FORMATTED(client, "Attempting to log in %s (with password)", username); ++ return rc_client_begin_login(client, &login_request, callback, callback_userdata); ++} ++ ++rc_client_async_handle_t* rc_client_begin_login_with_token(rc_client_t* client, ++ const char* username, const char* token, rc_client_callback_t callback, void* callback_userdata) ++{ ++ rc_api_login_request_t login_request; ++ ++ if (!client) { ++ callback(RC_INVALID_STATE, "client is required", client, callback_userdata); ++ return NULL; ++ } ++ ++ if (!username || !username[0]) { ++ callback(RC_INVALID_STATE, "username is required", client, callback_userdata); ++ return NULL; ++ } ++ ++ if (!token || !token[0]) { ++ callback(RC_INVALID_STATE, "token is required", client, callback_userdata); ++ return NULL; ++ } ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->begin_login_with_token) ++ return client->state.external_client->begin_login_with_token(client, username, token, callback, callback_userdata); ++#endif ++ ++ memset(&login_request, 0, sizeof(login_request)); ++ login_request.username = username; ++ login_request.api_token = token; ++ ++ RC_CLIENT_LOG_INFO_FORMATTED(client, "Attempting to log in %s (with token)", username); ++ return rc_client_begin_login(client, &login_request, callback, callback_userdata); ++} ++ ++void rc_client_logout(rc_client_t* client) ++{ ++ rc_client_load_state_t* load_state; ++ ++ if (!client) ++ return; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->logout) { ++ client->state.external_client->logout(); ++ return; ++ } ++#endif ++ ++ switch (client->state.user) { ++ case RC_CLIENT_USER_STATE_LOGGED_IN: ++ RC_CLIENT_LOG_INFO_FORMATTED(client, "Logging %s out", client->user.display_name); ++ break; ++ ++ case RC_CLIENT_USER_STATE_LOGIN_REQUESTED: ++ RC_CLIENT_LOG_INFO(client, "Aborting login"); ++ break; ++ } ++ ++ rc_mutex_lock(&client->state.mutex); ++ ++ client->state.user = RC_CLIENT_USER_STATE_NONE; ++ memset(&client->user, 0, sizeof(client->user)); ++ ++ load_state = client->state.load; ++ ++ rc_mutex_unlock(&client->state.mutex); ++ ++ rc_client_unload_game(client); ++ ++ if (load_state && load_state->progress == RC_CLIENT_LOAD_GAME_STATE_AWAIT_LOGIN) ++ rc_client_load_error(load_state, RC_ABORTED, "Login aborted"); ++} ++ ++const rc_client_user_t* rc_client_get_user_info(const rc_client_t* client) ++{ ++ if (!client) ++ return NULL; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client) { ++ if (client->state.external_client->get_user_info_v3) ++ return client->state.external_client->get_user_info_v3(); ++ ++ if (client->state.external_client->get_user_info) ++ return rc_client_external_convert_v1_user(client, client->state.external_client->get_user_info()); ++ } ++#endif ++ ++ return (client->state.user == RC_CLIENT_USER_STATE_LOGGED_IN) ? &client->user : NULL; ++} ++ ++int rc_client_user_get_image_url(const rc_client_user_t* user, char buffer[], size_t buffer_size) ++{ ++ if (!user) ++ return RC_INVALID_STATE; ++ ++ if (user->avatar_url) { ++ snprintf(buffer, buffer_size, "%s", user->avatar_url); ++ return RC_OK; ++ } ++ ++ return rc_client_get_image_url(buffer, buffer_size, RC_IMAGE_TYPE_USER, user->display_name); ++} ++ ++static void rc_client_subset_get_user_game_summary(const rc_client_t* client, ++ const rc_client_subset_info_t* subset, rc_client_user_game_summary_t* summary) ++{ ++ rc_client_achievement_info_t* achievement = subset->achievements; ++ rc_client_achievement_info_t* stop = achievement + subset->public_.num_achievements; ++ time_t last_unlock_time = 0; ++ time_t last_progression_time = 0; ++ time_t first_win_time = 0; ++ int num_progression_achievements = 0; ++ int num_win_achievements = 0; ++ int num_unlocked_progression_achievements = 0; ++ const uint8_t unlock_bit = (client->state.hardcore) ? ++ RC_CLIENT_ACHIEVEMENT_UNLOCKED_HARDCORE : RC_CLIENT_ACHIEVEMENT_UNLOCKED_SOFTCORE; ++ ++ rc_mutex_lock((rc_mutex_t*)&client->state.mutex); /* remove const cast for mutex access */ ++ ++ for (; achievement < stop; ++achievement) { ++ switch (achievement->public_.category) { ++ case RC_CLIENT_ACHIEVEMENT_CATEGORY_CORE: ++ ++summary->num_core_achievements; ++ summary->points_core += achievement->public_.points; ++ ++ if (achievement->public_.unlocked & unlock_bit) { ++ ++summary->num_unlocked_achievements; ++ summary->points_unlocked += achievement->public_.points; ++ ++ if (achievement->public_.unlock_time > last_unlock_time) ++ last_unlock_time = achievement->public_.unlock_time; ++ ++ if (achievement->public_.type == RC_CLIENT_ACHIEVEMENT_TYPE_PROGRESSION) { ++ ++num_unlocked_progression_achievements; ++ if (achievement->public_.unlock_time > last_progression_time) ++ last_progression_time = achievement->public_.unlock_time; ++ } ++ else if (achievement->public_.type == RC_CLIENT_ACHIEVEMENT_TYPE_WIN) { ++ if (first_win_time == 0 || achievement->public_.unlock_time < first_win_time) ++ first_win_time = achievement->public_.unlock_time; ++ } ++ } ++ ++ if (achievement->public_.type == RC_CLIENT_ACHIEVEMENT_TYPE_PROGRESSION) ++ ++num_progression_achievements; ++ else if (achievement->public_.type == RC_CLIENT_ACHIEVEMENT_TYPE_WIN) ++ ++num_win_achievements; ++ ++ if (achievement->public_.bucket == RC_CLIENT_ACHIEVEMENT_BUCKET_UNSUPPORTED) ++ ++summary->num_unsupported_achievements; ++ ++ break; ++ ++ case RC_CLIENT_ACHIEVEMENT_CATEGORY_UNOFFICIAL: ++ ++summary->num_unofficial_achievements; ++ break; ++ ++ default: ++ continue; ++ } ++ } ++ ++ rc_mutex_unlock((rc_mutex_t*)&client->state.mutex); /* remove const cast for mutex access */ ++ ++ if (summary->num_unlocked_achievements == summary->num_core_achievements) ++ summary->completed_time = last_unlock_time; ++ ++ if ((first_win_time || num_win_achievements == 0) && num_unlocked_progression_achievements == num_progression_achievements) ++ summary->beaten_time = (first_win_time > last_progression_time) ? first_win_time : last_progression_time; ++} ++ ++void rc_client_get_user_game_summary(const rc_client_t* client, rc_client_user_game_summary_t* summary) ++{ ++ if (!summary) ++ return; ++ ++ memset(summary, 0, sizeof(*summary)); ++ if (!client) ++ return; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client) { ++ if (client->state.external_client->get_user_game_summary_v5) { ++ client->state.external_client->get_user_game_summary_v5(summary); ++ return; ++ } ++ if (client->state.external_client->get_user_game_summary) { ++ client->state.external_client->get_user_game_summary(summary); ++ return; ++ } ++ } ++#endif ++ ++ if (rc_client_is_game_loaded(client)) ++ rc_client_subset_get_user_game_summary(client, client->game->subsets, summary); ++} ++ ++void rc_client_get_user_subset_summary(const rc_client_t* client, uint32_t subset_id, rc_client_user_game_summary_t* summary) ++{ ++ if (!summary) ++ return; ++ ++ memset(summary, 0, sizeof(*summary)); ++ if (!client || !subset_id) ++ return; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->get_user_subset_summary) { ++ client->state.external_client->get_user_subset_summary(subset_id, summary); ++ return; ++ } ++#endif ++ ++ if (rc_client_is_game_loaded(client)) { ++ const rc_client_subset_info_t* subset = client->game->subsets; ++ for (; subset; subset = subset->next) { ++ if (subset->public_.id == subset_id) { ++ rc_client_subset_get_user_game_summary(client, subset, summary); ++ break; ++ } ++ } ++ } ++} ++ ++typedef struct rc_client_fetch_all_user_progress_callback_data_t { ++ rc_client_t* client; ++ rc_client_fetch_all_user_progress_callback_t callback; ++ void* callback_userdata; ++ uint32_t console_id; ++ rc_client_async_handle_t async_handle; ++} rc_client_fetch_all_user_progress_callback_data_t; ++ ++static void rc_client_fetch_all_user_progress_callback(const rc_api_server_response_t* server_response, ++ void* callback_data) ++{ ++ rc_client_fetch_all_user_progress_callback_data_t* ap_callback_data = ++ (rc_client_fetch_all_user_progress_callback_data_t*)callback_data; ++ rc_client_t* client = ap_callback_data->client; ++ rc_api_fetch_all_user_progress_response_t ap_response; ++ const char* error_message; ++ int result; ++ ++ result = rc_client_end_async(client, &ap_callback_data->async_handle); ++ if (result) { ++ if (result != RC_CLIENT_ASYNC_DESTROYED) ++ RC_CLIENT_LOG_VERBOSE(client, "Fetch all progress aborted"); ++ ++ free(ap_callback_data); ++ return; ++ } ++ ++ result = rc_api_process_fetch_all_user_progress_server_response(&ap_response, server_response); ++ error_message = rc_client_server_error_message(&result, server_response->http_status_code, &ap_response.response); ++ if (error_message) { ++ RC_CLIENT_LOG_ERR_FORMATTED(client, "Fetch all progress for console %u failed: %s", ap_callback_data->console_id, ++ error_message); ++ ap_callback_data->callback(result, error_message, NULL, client, ap_callback_data->callback_userdata); ++ } else { ++ rc_client_all_user_progress_t* list; ++ const size_t list_size = sizeof(*list) + sizeof(rc_client_all_user_progress_entry_t) * ap_response.num_entries; ++ ++ list = (rc_client_all_user_progress_t*)malloc(list_size); ++ if (!list) { ++ ap_callback_data->callback(RC_OUT_OF_MEMORY, rc_error_str(RC_OUT_OF_MEMORY), NULL, client, ++ ap_callback_data->callback_userdata); ++ } else { ++ rc_client_all_user_progress_entry_t* entry = list->entries = ++ (rc_client_all_user_progress_entry_t*)((uint8_t*)list + sizeof(*list)); ++ const rc_api_all_user_progress_entry_t* hlentry = ap_response.entries; ++ const rc_api_all_user_progress_entry_t* stop = hlentry + ap_response.num_entries; ++ ++ for (; hlentry < stop; ++hlentry, ++entry) ++ { ++ entry->game_id = hlentry->game_id; ++ entry->num_achievements = hlentry->num_achievements; ++ entry->num_unlocked_achievements = hlentry->num_unlocked_achievements; ++ entry->num_unlocked_achievements_hardcore = hlentry->num_unlocked_achievements_hardcore; ++ } ++ ++ list->num_entries = ap_response.num_entries; ++ ++ ap_callback_data->callback(RC_OK, NULL, list, client, ap_callback_data->callback_userdata); ++ } ++ } ++ ++ rc_api_destroy_fetch_all_user_progress_response(&ap_response); ++ free(ap_callback_data); ++} ++ ++rc_client_async_handle_t* rc_client_begin_fetch_all_user_progress(rc_client_t* client, uint32_t console_id, ++ rc_client_fetch_all_user_progress_callback_t callback, ++ void* callback_userdata) ++{ ++ rc_api_fetch_all_user_progress_request_t api_params; ++ rc_client_fetch_all_user_progress_callback_data_t* callback_data; ++ rc_client_async_handle_t* async_handle; ++ rc_api_request_t request; ++ int result; ++ const char* error_message; ++ ++ if (!client) { ++ callback(RC_INVALID_STATE, "client is required", NULL, client, callback_userdata); ++ return NULL; ++ } else if (client->state.user != RC_CLIENT_USER_STATE_LOGGED_IN) { ++ callback(RC_INVALID_STATE, "client must be logged in", NULL, client, callback_userdata); ++ return NULL; ++ } ++ ++ api_params.username = client->user.username; ++ api_params.api_token = client->user.token; ++ api_params.console_id = console_id; ++ ++ result = rc_api_init_fetch_all_user_progress_request_hosted(&request, &api_params, &client->state.host); ++ ++ if (result != RC_OK) { ++ error_message = rc_error_str(result); ++ callback(result, error_message, NULL, client, callback_userdata); ++ return NULL; ++ } ++ ++ callback_data = (rc_client_fetch_all_user_progress_callback_data_t*)calloc(1, sizeof(*callback_data)); ++ if (!callback_data) { ++ callback(RC_OUT_OF_MEMORY, rc_error_str(RC_OUT_OF_MEMORY), NULL, client, callback_userdata); ++ return NULL; ++ } ++ ++ callback_data->client = client; ++ callback_data->callback = callback; ++ callback_data->callback_userdata = callback_userdata; ++ callback_data->console_id = console_id; ++ ++ async_handle = &callback_data->async_handle; ++ rc_client_begin_async(client, async_handle); ++ client->callbacks.server_call(&request, rc_client_fetch_all_user_progress_callback, callback_data, client); ++ rc_api_destroy_request(&request); ++ ++ return rc_client_async_handle_valid(client, async_handle) ? async_handle : NULL; ++} ++ ++void rc_client_destroy_all_user_progress(rc_client_all_user_progress_t* list) ++{ ++ free(list); ++} ++ ++/* ===== Game ===== */ ++ ++static void rc_client_free_game(rc_client_game_info_t* game) ++{ ++ rc_runtime_destroy(&game->runtime); ++ ++ rc_buffer_destroy(&game->buffer); ++ ++ free(game); ++} ++ ++static void rc_client_free_load_state(rc_client_load_state_t* load_state) ++{ ++ if (load_state->game) ++ rc_client_free_game(load_state->game); ++ ++ if (load_state->start_session_response) { ++ rc_api_destroy_start_session_response(load_state->start_session_response); ++ free(load_state->start_session_response); ++ } ++ ++#ifdef RC_CLIENT_SUPPORTS_HASH ++ rc_hash_destroy_iterator(&load_state->hash_iterator); ++#endif ++ ++ free(load_state); ++} ++ ++static void rc_client_begin_load_state(rc_client_load_state_t* load_state, uint8_t state, uint8_t num_requests) ++{ ++ rc_mutex_lock(&load_state->client->state.mutex); ++ ++ load_state->progress = state; ++ load_state->outstanding_requests += num_requests; ++ ++ rc_mutex_unlock(&load_state->client->state.mutex); ++} ++ ++static int rc_client_end_load_state(rc_client_load_state_t* load_state) ++{ ++ int remaining_requests = 0; ++ int aborted = 0; ++ ++ rc_mutex_lock(&load_state->client->state.mutex); ++ ++ if (load_state->outstanding_requests > 0) ++ --load_state->outstanding_requests; ++ remaining_requests = load_state->outstanding_requests; ++ ++ if (load_state->client->state.load != load_state) ++ aborted = 1; ++ ++ rc_mutex_unlock(&load_state->client->state.mutex); ++ ++ if (aborted) { ++ /* we can't actually free the load_state itself if there are any outstanding requests ++ * or their callbacks will try to use the free'd memory. As they call end_load_state, ++ * the outstanding_requests count will reach zero and the memory will be free'd then. */ ++ if (remaining_requests == 0) { ++ /* if one of the callbacks called rc_client_load_error, progress will be set to ++ * RC_CLIENT_LOAD_STATE_ABORTED. There's no need to call the callback with RC_ABORTED ++ * in that case, as it will have already been called with something more appropriate. */ ++ if (load_state->progress != RC_CLIENT_LOAD_GAME_STATE_ABORTED && load_state->callback) ++ load_state->callback(RC_ABORTED, "The requested game is no longer active", load_state->client, load_state->callback_userdata); ++ ++ rc_client_free_load_state(load_state); ++ } ++ ++ return -1; ++ } ++ ++ return remaining_requests; ++} ++ ++static void rc_client_load_error(rc_client_load_state_t* load_state, int result, const char* error_message) ++{ ++ int remaining_requests = 0; ++ ++ rc_mutex_lock(&load_state->client->state.mutex); ++ ++ load_state->progress = RC_CLIENT_LOAD_GAME_STATE_ABORTED; ++ if (load_state->client->state.load == load_state) ++ load_state->client->state.load = NULL; ++ ++ remaining_requests = load_state->outstanding_requests; ++ ++ rc_mutex_unlock(&load_state->client->state.mutex); ++ ++ RC_CLIENT_LOG_ERR_FORMATTED(load_state->client, "Load failed (%d): %s", result, error_message); ++ ++ if (load_state->callback) ++ load_state->callback(result, error_message, load_state->client, load_state->callback_userdata); ++ ++ /* we can't actually free the load_state itself if there are any outstanding requests ++ * or their callbacks will try to use the free'd memory. as they call end_load_state, ++ * the outstanding_requests count will reach zero and the memory will be free'd then. */ ++ if (remaining_requests == 0) ++ rc_client_free_load_state(load_state); ++} ++ ++static void rc_client_load_aborted(rc_client_load_state_t* load_state) ++{ ++ /* prevent callback from being called when manually aborted */ ++ load_state->callback = NULL; ++ ++ /* mark the game as no longer being loaded */ ++ rc_client_load_error(load_state, RC_ABORTED, NULL); ++ ++ /* decrement the async counter and potentially free the load_state object */ ++ rc_client_end_load_state(load_state); ++} ++ ++static void rc_client_invalidate_memref_achievements(rc_client_game_info_t* game, rc_client_t* client, rc_memref_t* memref) ++{ ++ rc_client_subset_info_t* subset = game->subsets; ++ for (; subset; subset = subset->next) { ++ rc_client_achievement_info_t* achievement = subset->achievements; ++ rc_client_achievement_info_t* stop = achievement + subset->public_.num_achievements; ++ for (; achievement < stop; ++achievement) { ++ if (achievement->public_.state == RC_CLIENT_ACHIEVEMENT_STATE_DISABLED) ++ continue; ++ ++ if (rc_trigger_contains_memref(achievement->trigger, memref)) { ++ achievement->public_.state = RC_CLIENT_ACHIEVEMENT_STATE_DISABLED; ++ achievement->public_.bucket = RC_CLIENT_ACHIEVEMENT_BUCKET_UNSUPPORTED; ++ ++ if (achievement->trigger) ++ achievement->trigger->state = RC_TRIGGER_STATE_DISABLED; ++ ++ RC_CLIENT_LOG_WARN_FORMATTED(client, "Disabled achievement %u. Invalid address %06X", achievement->public_.id, memref->address); ++ } ++ } ++ } ++} ++ ++static void rc_client_invalidate_memref_leaderboards(rc_client_game_info_t* game, rc_client_t* client, rc_memref_t* memref) ++{ ++ rc_client_subset_info_t* subset = game->subsets; ++ for (; subset; subset = subset->next) { ++ rc_client_leaderboard_info_t* leaderboard = subset->leaderboards; ++ rc_client_leaderboard_info_t* stop = leaderboard + subset->public_.num_leaderboards; ++ for (; leaderboard < stop; ++leaderboard) { ++ if (leaderboard->public_.state == RC_CLIENT_LEADERBOARD_STATE_DISABLED) ++ continue; ++ if (!leaderboard->lboard) ++ continue; ++ ++ if (rc_trigger_contains_memref(&leaderboard->lboard->start, memref)) ++ leaderboard->public_.state = RC_CLIENT_LEADERBOARD_STATE_DISABLED; ++ else if (rc_trigger_contains_memref(&leaderboard->lboard->cancel, memref)) ++ leaderboard->public_.state = RC_CLIENT_LEADERBOARD_STATE_DISABLED; ++ else if (rc_trigger_contains_memref(&leaderboard->lboard->submit, memref)) ++ leaderboard->public_.state = RC_CLIENT_LEADERBOARD_STATE_DISABLED; ++ else if (rc_value_contains_memref(&leaderboard->lboard->value, memref)) ++ leaderboard->public_.state = RC_CLIENT_LEADERBOARD_STATE_DISABLED; ++ else ++ continue; ++ ++ leaderboard->lboard->state = RC_LBOARD_STATE_DISABLED; ++ ++ RC_CLIENT_LOG_WARN_FORMATTED(client, "Disabled leaderboard %u. Invalid address %06X", leaderboard->public_.id, memref->address); ++ } ++ } ++} ++ ++static void rc_client_validate_addresses(rc_client_game_info_t* game, rc_client_t* client) ++{ ++ const rc_memory_regions_t* regions = rc_console_memory_regions(game->public_.console_id); ++ const uint32_t max_address = (regions && regions->num_regions > 0) ? ++ regions->region[regions->num_regions - 1].end_address : 0xFFFFFFFF; ++ uint8_t buffer[8]; ++ uint32_t total_count = 0; ++ uint32_t invalid_count = 0; ++ ++ rc_memref_list_t* memref_list = &game->runtime.memrefs->memrefs; ++ for (; memref_list; memref_list = memref_list->next) { ++ rc_memref_t* memref = memref_list->items; ++ const rc_memref_t* memref_end = memref + memref_list->count; ++ total_count += memref_list->count; ++ ++ for (; memref < memref_end; ++memref) { ++ if (memref->address > max_address || ++ client->callbacks.read_memory(memref->address, buffer, 1, client) == 0) { ++ memref->value.type = RC_VALUE_TYPE_NONE; ++ ++ rc_client_invalidate_memref_achievements(game, client, memref); ++ rc_client_invalidate_memref_leaderboards(game, client, memref); ++ ++ invalid_count++; ++ } ++ } ++ } ++ ++ game->max_valid_address = max_address; ++ RC_CLIENT_LOG_VERBOSE_FORMATTED(client, "%u/%u memory addresses valid", total_count - invalid_count, total_count); ++} ++ ++static void rc_client_update_legacy_runtime_achievements(rc_client_game_info_t* game, uint32_t active_count) ++{ ++ if (active_count > 0) { ++ rc_client_achievement_info_t* achievement; ++ rc_client_achievement_info_t* stop; ++ rc_runtime_trigger_t* trigger; ++ rc_client_subset_info_t* subset; ++ ++ if (active_count <= game->runtime.trigger_capacity) { ++ if (active_count != 0) ++ memset(game->runtime.triggers, 0, active_count * sizeof(rc_runtime_trigger_t)); ++ } else { ++ if (game->runtime.triggers) ++ free(game->runtime.triggers); ++ ++ game->runtime.trigger_capacity = active_count; ++ game->runtime.triggers = (rc_runtime_trigger_t*)calloc(1, active_count * sizeof(rc_runtime_trigger_t)); ++ } ++ ++ trigger = game->runtime.triggers; ++ if (!trigger) { ++ /* malloc failed, no way to report error, just bail */ ++ game->runtime.trigger_count = 0; ++ return; ++ } ++ ++ for (subset = game->subsets; subset; subset = subset->next) { ++ if (!subset->active) ++ continue; ++ ++ achievement = subset->achievements; ++ stop = achievement + subset->public_.num_achievements; ++ ++ for (; achievement < stop; ++achievement) { ++ if (achievement->public_.state == RC_CLIENT_ACHIEVEMENT_STATE_ACTIVE) { ++ trigger->id = achievement->public_.id; ++ memcpy(trigger->md5, achievement->md5, 16); ++ trigger->trigger = achievement->trigger; ++ ++trigger; ++ } ++ } ++ } ++ } ++ ++ game->runtime.trigger_count = active_count; ++} ++ ++static uint32_t rc_client_subset_count_active_achievements(const rc_client_subset_info_t* subset) ++{ ++ rc_client_achievement_info_t* achievement = subset->achievements; ++ rc_client_achievement_info_t* stop = achievement + subset->public_.num_achievements; ++ uint32_t active_count = 0; ++ ++ for (; achievement < stop; ++achievement) { ++ if (achievement->public_.state == RC_CLIENT_ACHIEVEMENT_STATE_ACTIVE) ++ ++active_count; ++ } ++ ++ return active_count; ++} ++ ++void rc_client_update_active_achievements(rc_client_game_info_t* game) ++{ ++ uint32_t active_count = 0; ++ rc_client_subset_info_t* subset = game->subsets; ++ for (; subset; subset = subset->next) { ++ if (subset->active) ++ active_count += rc_client_subset_count_active_achievements(subset); ++ } ++ ++ rc_client_update_legacy_runtime_achievements(game, active_count); ++} ++ ++static uint32_t rc_client_subset_toggle_hardcore_achievements(rc_client_subset_info_t* subset, rc_client_t* client, uint8_t active_bit) ++{ ++ rc_client_achievement_info_t* achievement = subset->achievements; ++ rc_client_achievement_info_t* stop = achievement + subset->public_.num_achievements; ++ uint32_t active_count = 0; ++ ++ for (; achievement < stop; ++achievement) { ++ if ((achievement->public_.unlocked & active_bit) == 0) { ++ switch (achievement->public_.state) { ++ case RC_CLIENT_ACHIEVEMENT_STATE_UNLOCKED: ++ case RC_CLIENT_ACHIEVEMENT_STATE_INACTIVE: ++ rc_reset_trigger(achievement->trigger); ++ achievement->public_.state = RC_CLIENT_ACHIEVEMENT_STATE_ACTIVE; ++ ++active_count; ++ break; ++ ++ case RC_CLIENT_ACHIEVEMENT_STATE_ACTIVE: ++ ++active_count; ++ break; ++ } ++ } ++ else { ++ achievement->public_.unlock_time = (active_bit == RC_CLIENT_ACHIEVEMENT_UNLOCKED_HARDCORE) ? ++ achievement->unlock_time_hardcore : achievement->unlock_time_softcore; ++ ++ if (achievement->public_.state == RC_CLIENT_ACHIEVEMENT_STATE_ACTIVE || ++ achievement->public_.state == RC_CLIENT_ACHIEVEMENT_STATE_INACTIVE) { ++ /* if it's active despite being unlocked, and we're in encore mode, leave it active */ ++ if (client->state.encore_mode) { ++ ++active_count; ++ continue; ++ } ++ ++ /* switch to inactive */ ++ achievement->public_.state = RC_CLIENT_ACHIEVEMENT_STATE_UNLOCKED; ++ ++ if (achievement->trigger && rc_trigger_state_active(achievement->trigger->state)) { ++ /* hide any active challenge indicators */ ++ if (achievement->trigger->state == RC_TRIGGER_STATE_PRIMED) { ++ rc_client_event_t client_event; ++ memset(&client_event, 0, sizeof(client_event)); ++ client_event.type = RC_CLIENT_EVENT_ACHIEVEMENT_CHALLENGE_INDICATOR_HIDE; ++ client_event.achievement = &achievement->public_; ++ client->callbacks.event_handler(&client_event, client); ++ } ++ ++ achievement->trigger->state = RC_TRIGGER_STATE_TRIGGERED; ++ } ++ } ++ } ++ } ++ ++ return active_count; ++} ++ ++static void rc_client_toggle_hardcore_achievements(rc_client_game_info_t* game, rc_client_t* client, uint8_t active_bit) ++{ ++ uint32_t active_count = 0; ++ rc_client_subset_info_t* subset = game->subsets; ++ for (; subset; subset = subset->next) { ++ if (subset->active) ++ active_count += rc_client_subset_toggle_hardcore_achievements(subset, client, active_bit); ++ } ++ ++ rc_client_update_legacy_runtime_achievements(game, active_count); ++} ++ ++static void rc_client_activate_achievements(rc_client_game_info_t* game, rc_client_t* client) ++{ ++ const uint8_t active_bit = (client->state.encore_mode) ? ++ RC_CLIENT_ACHIEVEMENT_UNLOCKED_NONE : (client->state.hardcore) ? ++ RC_CLIENT_ACHIEVEMENT_UNLOCKED_HARDCORE : RC_CLIENT_ACHIEVEMENT_UNLOCKED_SOFTCORE; ++ ++ rc_client_toggle_hardcore_achievements(game, client, active_bit); ++} ++ ++static void rc_client_update_legacy_runtime_leaderboards(rc_client_game_info_t* game, uint32_t active_count) ++{ ++ if (active_count > 0) { ++ rc_client_leaderboard_info_t* leaderboard; ++ rc_client_leaderboard_info_t* stop; ++ rc_client_subset_info_t* subset; ++ rc_runtime_lboard_t* lboard; ++ ++ if (active_count <= game->runtime.lboard_capacity) { ++ if (active_count != 0) ++ memset(game->runtime.lboards, 0, active_count * sizeof(rc_runtime_lboard_t)); ++ } else { ++ if (game->runtime.lboards) ++ free(game->runtime.lboards); ++ ++ game->runtime.lboard_capacity = active_count; ++ game->runtime.lboards = (rc_runtime_lboard_t*)calloc(1, active_count * sizeof(rc_runtime_lboard_t)); ++ } ++ ++ lboard = game->runtime.lboards; ++ if (!lboard) { ++ /* malloc failed. no way to report error, just bail */ ++ game->runtime.lboard_count = 0; ++ return; ++ } ++ ++ for (subset = game->subsets; subset; subset = subset->next) { ++ if (!subset->active) ++ continue; ++ ++ leaderboard = subset->leaderboards; ++ stop = leaderboard + subset->public_.num_leaderboards; ++ for (; leaderboard < stop; ++leaderboard) { ++ if (leaderboard->public_.state == RC_CLIENT_LEADERBOARD_STATE_ACTIVE || ++ leaderboard->public_.state == RC_CLIENT_LEADERBOARD_STATE_TRACKING) { ++ lboard->id = leaderboard->public_.id; ++ memcpy(lboard->md5, leaderboard->md5, 16); ++ lboard->lboard = leaderboard->lboard; ++ ++lboard; ++ } ++ } ++ } ++ } ++ ++ game->runtime.lboard_count = active_count; ++} ++ ++void rc_client_update_active_leaderboards(rc_client_game_info_t* game) ++{ ++ rc_client_leaderboard_info_t* leaderboard; ++ rc_client_leaderboard_info_t* stop; ++ ++ uint32_t active_count = 0; ++ rc_client_subset_info_t* subset = game->subsets; ++ for (; subset; subset = subset->next) ++ { ++ if (!subset->active) ++ continue; ++ ++ leaderboard = subset->leaderboards; ++ stop = leaderboard + subset->public_.num_leaderboards; ++ ++ for (; leaderboard < stop; ++leaderboard) ++ { ++ switch (leaderboard->public_.state) ++ { ++ case RC_CLIENT_LEADERBOARD_STATE_ACTIVE: ++ case RC_CLIENT_LEADERBOARD_STATE_TRACKING: ++ ++active_count; ++ break; ++ } ++ } ++ } ++ ++ rc_client_update_legacy_runtime_leaderboards(game, active_count); ++} ++ ++static void rc_client_activate_leaderboards(rc_client_game_info_t* game, rc_client_t* client) ++{ ++ rc_client_leaderboard_info_t* leaderboard; ++ rc_client_leaderboard_info_t* stop; ++ const uint8_t leaderboards_allowed = ++ client->state.hardcore || client->state.allow_leaderboards_in_softcore; ++ ++ uint32_t active_count = 0; ++ rc_client_subset_info_t* subset = game->subsets; ++ for (; subset; subset = subset->next) { ++ if (!subset->active) ++ continue; ++ ++ leaderboard = subset->leaderboards; ++ stop = leaderboard + subset->public_.num_leaderboards; ++ ++ for (; leaderboard < stop; ++leaderboard) { ++ switch (leaderboard->public_.state) { ++ case RC_CLIENT_LEADERBOARD_STATE_DISABLED: ++ continue; ++ ++ case RC_CLIENT_LEADERBOARD_STATE_INACTIVE: ++ if (leaderboards_allowed) { ++ rc_reset_lboard(leaderboard->lboard); ++ leaderboard->public_.state = RC_CLIENT_LEADERBOARD_STATE_ACTIVE; ++ ++active_count; ++ } ++ break; ++ ++ default: ++ if (leaderboards_allowed) ++ ++active_count; ++ else ++ leaderboard->public_.state = RC_CLIENT_LEADERBOARD_STATE_INACTIVE; ++ break; ++ } ++ } ++ } ++ ++ rc_client_update_legacy_runtime_leaderboards(game, active_count); ++} ++ ++static void rc_client_deactivate_leaderboards(rc_client_game_info_t* game, rc_client_t* client) ++{ ++ rc_client_leaderboard_info_t* leaderboard; ++ rc_client_leaderboard_info_t* stop; ++ ++ rc_client_subset_info_t* subset = game->subsets; ++ for (; subset; subset = subset->next) { ++ if (!subset->active) ++ continue; ++ ++ leaderboard = subset->leaderboards; ++ stop = leaderboard + subset->public_.num_leaderboards; ++ ++ for (; leaderboard < stop; ++leaderboard) { ++ switch (leaderboard->public_.state) { ++ case RC_CLIENT_LEADERBOARD_STATE_DISABLED: ++ case RC_CLIENT_LEADERBOARD_STATE_INACTIVE: ++ continue; ++ ++ case RC_CLIENT_LEADERBOARD_STATE_TRACKING: ++ rc_client_release_leaderboard_tracker(client->game, leaderboard); ++ /* fallthrough */ /* to default */ ++ default: ++ leaderboard->public_.state = RC_CLIENT_LEADERBOARD_STATE_INACTIVE; ++ break; ++ } ++ } ++ } ++ ++ game->runtime.lboard_count = 0; ++} ++ ++static void rc_client_apply_unlocks(rc_client_subset_info_t* subset, rc_api_unlock_entry_t* unlocks, uint32_t num_unlocks, uint8_t mode) ++{ ++ rc_client_achievement_info_t* start = subset->achievements; ++ rc_client_achievement_info_t* stop = start + subset->public_.num_achievements; ++ rc_client_achievement_info_t* scan; ++ rc_api_unlock_entry_t* unlock = unlocks; ++ rc_api_unlock_entry_t* unlock_stop = unlocks + num_unlocks; ++ ++ for (; unlock < unlock_stop; ++unlock) { ++ for (scan = start; scan < stop; ++scan) { ++ if (scan->public_.id == unlock->achievement_id) { ++ scan->public_.unlocked |= mode; ++ ++ if (mode & RC_CLIENT_ACHIEVEMENT_UNLOCKED_HARDCORE) ++ scan->unlock_time_hardcore = unlock->when; ++ if (mode & RC_CLIENT_ACHIEVEMENT_UNLOCKED_SOFTCORE) ++ scan->unlock_time_softcore = unlock->when; ++ ++ if (scan == start) ++ ++start; ++ else if (scan + 1 == stop) ++ --stop; ++ break; ++ } ++ } ++ } ++ ++ if (subset->next) ++ rc_client_apply_unlocks(subset->next, unlocks, num_unlocks, mode); ++} ++ ++static void rc_client_free_pending_media(rc_client_pending_media_t* pending_media) ++{ ++ if (pending_media->hash) ++ free((void*)pending_media->hash); ++#ifdef RC_CLIENT_SUPPORTS_HASH ++ if (pending_media->data) ++ free(pending_media->data); ++ free((void*)pending_media->file_path); ++#endif ++ free(pending_media); ++} ++ ++/* NOTE: address validation uses the read_memory callback to make sure the client ++ * will return data for the requested address. As such, this function must ++ * respect the `client->state.allow_background_memory_reads setting. Use ++ * rc_client_queue_activate_game to dispatch this function to the do_frame loop/ ++ */ ++static void rc_client_activate_game(rc_client_load_state_t* load_state, rc_api_start_session_response_t *start_session_response) ++{ ++ rc_client_t* client = load_state->client; ++ ++ rc_mutex_lock(&client->state.mutex); ++ load_state->progress = (client->state.load == load_state) ? ++ RC_CLIENT_LOAD_GAME_STATE_DONE : RC_CLIENT_LOAD_GAME_STATE_ABORTED; ++ rc_mutex_unlock(&client->state.mutex); ++ ++ if (load_state->progress != RC_CLIENT_LOAD_GAME_STATE_DONE) { ++ /* previous load state was aborted */ ++ if (load_state->callback) ++ load_state->callback(RC_ABORTED, "The requested game is no longer active", client, load_state->callback_userdata); ++ } ++ else if (!start_session_response && client->state.spectator_mode == RC_CLIENT_SPECTATOR_MODE_OFF) { ++ /* unlocks not available - assume malloc failed */ ++ if (load_state->callback) ++ load_state->callback(RC_INVALID_STATE, "Unlock arrays were not allocated", client, load_state->callback_userdata); ++ } ++ else { ++ if (client->state.spectator_mode == RC_CLIENT_SPECTATOR_MODE_OFF) { ++ rc_client_apply_unlocks(load_state->subset, start_session_response->hardcore_unlocks, ++ start_session_response->num_hardcore_unlocks, RC_CLIENT_ACHIEVEMENT_UNLOCKED_BOTH); ++ rc_client_apply_unlocks(load_state->subset, start_session_response->unlocks, ++ start_session_response->num_unlocks, RC_CLIENT_ACHIEVEMENT_UNLOCKED_SOFTCORE); ++ } ++ ++ /* make the loaded game active if another game is not aleady being loaded. */ ++ rc_mutex_lock(&client->state.mutex); ++ if (client->state.load == load_state) { ++ client->game = load_state->game; ++ client->state.frames_processed = client->state.frames_at_last_ping = 0; ++ } ++ else { ++ load_state->progress = RC_CLIENT_LOAD_GAME_STATE_ABORTED; ++ } ++ rc_mutex_unlock(&client->state.mutex); ++ ++ if (load_state->progress != RC_CLIENT_LOAD_GAME_STATE_ABORTED) { ++ /* if a change media request is pending, kick it off */ ++ rc_client_pending_media_t* pending_media; ++ ++ rc_mutex_lock(&load_state->client->state.mutex); ++ pending_media = load_state->pending_media; ++ load_state->pending_media = NULL; ++ rc_mutex_unlock(&load_state->client->state.mutex); ++ ++ if (pending_media) { ++ /* rc_client_check_pending_media will fail if it can't find the game in client->game or ++ * client->state.load->game. since we've detached the load_state, this has to occur after ++ * we've made the game active. */ ++ if (pending_media->hash) { ++ rc_client_begin_change_media(client, pending_media->hash, ++ pending_media->callback, pending_media->callback_userdata); ++ } else { ++#ifdef RC_CLIENT_SUPPORTS_HASH ++ rc_client_begin_identify_and_change_media(client, pending_media->file_path, ++ pending_media->data, pending_media->data_size, ++ pending_media->callback, pending_media->callback_userdata); ++#endif ++ } ++ rc_client_free_pending_media(pending_media); ++ } ++ ++ rc_mutex_lock(&client->state.mutex); ++ if (client->state.load != load_state) ++ load_state->progress = RC_CLIENT_LOAD_GAME_STATE_ABORTED; ++ rc_mutex_unlock(&client->state.mutex); ++ } ++ ++ /* if the game is still being loaded, make sure all the required memory addresses are accessible ++ * so we can mark achievements as unsupported before loading them into the runtime. */ ++ if (load_state->progress != RC_CLIENT_LOAD_GAME_STATE_ABORTED) { ++ /* ASSERT: client->game must be set before calling this function so the read_memory callback can query the console_id */ ++ rc_client_validate_addresses(load_state->game, client); ++ ++ rc_mutex_lock(&client->state.mutex); ++ if (client->state.load != load_state) ++ load_state->progress = RC_CLIENT_LOAD_GAME_STATE_ABORTED; ++ rc_mutex_unlock(&client->state.mutex); ++ } ++ ++ /* if the game is still being loaded, load any active acheivements/leaderboards into the runtime */ ++ if (load_state->progress != RC_CLIENT_LOAD_GAME_STATE_ABORTED) { ++ rc_client_activate_achievements(load_state->game, client); ++ rc_client_activate_leaderboards(load_state->game, client); ++ ++ /* detach the load state to indicate that loading is fully complete */ ++ rc_mutex_lock(&client->state.mutex); ++ if (client->state.load == load_state) ++ client->state.load = NULL; ++ else ++ load_state->progress = RC_CLIENT_LOAD_GAME_STATE_ABORTED; ++ rc_mutex_unlock(&client->state.mutex); ++ } ++ ++ /* one last sanity check to make sure the game is still being loaded. */ ++ if (load_state->progress == RC_CLIENT_LOAD_GAME_STATE_ABORTED) { ++ /* game has been unloaded, or another game is being loaded over the top of this game */ ++ if (load_state->callback) ++ load_state->callback(RC_ABORTED, "The requested game is no longer active", client, load_state->callback_userdata); ++ } ++ else { ++ if (load_state->hash->hash[0] != '[') { ++ if (load_state->client->state.spectator_mode != RC_CLIENT_SPECTATOR_MODE_LOCKED) { ++ /* schedule the periodic ping */ ++ rc_client_scheduled_callback_data_t* callback_data = (rc_client_scheduled_callback_data_t*) ++ rc_buffer_alloc(&load_state->game->buffer, sizeof(rc_client_scheduled_callback_data_t)); ++ ++ memset(callback_data, 0, sizeof(*callback_data)); ++ callback_data->callback = rc_client_ping; ++ callback_data->related_id = load_state->game->public_.id; ++ callback_data->when = client->callbacks.get_time_millisecs(client) + 30 * 1000; ++ rc_client_schedule_callback(client, callback_data); ++ } ++ ++ RC_CLIENT_LOG_INFO_FORMATTED(client, "Game %u loaded, hardcore %s%s", load_state->game->public_.id, ++ client->state.hardcore ? "enabled" : "disabled", ++ (client->state.spectator_mode != RC_CLIENT_SPECTATOR_MODE_OFF) ? ", spectating" : ""); ++ } ++ else { ++ RC_CLIENT_LOG_INFO_FORMATTED(client, "Subset %u loaded", load_state->subset->public_.id); ++ } ++ ++ if (load_state->callback) ++ load_state->callback(RC_OK, NULL, client, load_state->callback_userdata); ++ ++ /* detach the game object so it doesn't get freed by free_load_state */ ++ load_state->game = NULL; ++ } ++ } ++ ++ rc_client_free_load_state(load_state); ++} ++ ++static void rc_client_dispatch_activate_game(struct rc_client_scheduled_callback_data_t* callback_data, rc_client_t* client, rc_clock_t now) ++{ ++ rc_client_load_state_t* load_state = (rc_client_load_state_t*)callback_data->data; ++ free(callback_data); ++ ++ (void)client; ++ (void)now; ++ ++ rc_client_activate_game(load_state, load_state->start_session_response); ++} ++ ++static void rc_client_queue_activate_game(rc_client_load_state_t* load_state) ++{ ++ rc_client_scheduled_callback_data_t* scheduled_callback_data = ++ (rc_client_scheduled_callback_data_t*)calloc(1, sizeof(rc_client_scheduled_callback_data_t)); ++ ++ if (!scheduled_callback_data) { ++ rc_client_load_error(load_state, RC_OUT_OF_MEMORY, rc_error_str(RC_OUT_OF_MEMORY)); ++ return; ++ } ++ ++ scheduled_callback_data->callback = rc_client_dispatch_activate_game; ++ scheduled_callback_data->data = load_state; ++ ++ rc_client_schedule_callback(load_state->client, scheduled_callback_data); ++} ++ ++static void rc_client_start_session_callback(const rc_api_server_response_t* server_response, void* callback_data) ++{ ++ rc_client_load_state_t* load_state = (rc_client_load_state_t*)callback_data; ++ rc_api_start_session_response_t start_session_response; ++ int outstanding_requests; ++ const char* error_message; ++ int result; ++ ++ result = rc_client_end_async(load_state->client, &load_state->async_handle); ++ if (result) { ++ if (result != RC_CLIENT_ASYNC_DESTROYED) { ++ rc_client_t* client = load_state->client; ++ rc_client_load_aborted(load_state); ++ RC_CLIENT_LOG_VERBOSE(client, "Load aborted while starting session"); ++ } else { ++ rc_client_free_load_state(load_state); ++ } ++ return; ++ } ++ ++ result = rc_api_process_start_session_server_response(&start_session_response, server_response); ++ error_message = rc_client_server_error_message(&result, server_response->http_status_code, &start_session_response.response); ++ outstanding_requests = rc_client_end_load_state(load_state); ++ ++ if (error_message) { ++ rc_client_load_error(load_state, result, error_message); ++ } ++ else if (outstanding_requests < 0) { ++ /* previous load state was aborted, load_state was free'd */ ++ } ++ else if (outstanding_requests == 0 && load_state->client->state.allow_background_memory_reads) { ++ rc_client_activate_game(load_state, &start_session_response); ++ } ++ else { ++ load_state->start_session_response = ++ (rc_api_start_session_response_t*)malloc(sizeof(rc_api_start_session_response_t)); ++ ++ if (!load_state->start_session_response) { ++ rc_client_load_error(load_state, RC_OUT_OF_MEMORY, rc_error_str(RC_OUT_OF_MEMORY)); ++ } ++ else { ++ /* safer to parse the response again than to try to copy it */ ++ rc_api_process_start_session_response(load_state->start_session_response, server_response->body); ++ } ++ ++ if (outstanding_requests == 0) { ++ if (load_state->client->state.allow_background_memory_reads) ++ rc_client_activate_game(load_state, load_state->start_session_response); ++ else ++ rc_client_queue_activate_game(load_state); ++ } ++ } ++ ++ rc_api_destroy_start_session_response(&start_session_response); ++} ++ ++static void rc_client_begin_start_session(rc_client_load_state_t* load_state) ++{ ++ rc_api_start_session_request_t start_session_params; ++ rc_client_t* client = load_state->client; ++ rc_api_request_t start_session_request; ++ int result; ++ ++ memset(&start_session_params, 0, sizeof(start_session_params)); ++ start_session_params.username = client->user.username; ++ start_session_params.api_token = client->user.token; ++ start_session_params.game_id = load_state->hash->game_id; ++ start_session_params.game_hash = load_state->hash->hash; ++ start_session_params.hardcore = client->state.hardcore; ++ ++ result = rc_api_init_start_session_request_hosted(&start_session_request, &start_session_params, &client->state.host); ++ if (result != RC_OK) { ++ rc_client_load_error(load_state, result, rc_error_str(result)); ++ } ++ else { ++ rc_client_begin_load_state(load_state, RC_CLIENT_LOAD_GAME_STATE_STARTING_SESSION, 1); ++ RC_CLIENT_LOG_VERBOSE_FORMATTED(client, "Starting session for game %u", start_session_params.game_id); ++ rc_client_begin_async(client, &load_state->async_handle); ++ client->callbacks.server_call(&start_session_request, rc_client_start_session_callback, load_state, client); ++ rc_api_destroy_request(&start_session_request); ++ } ++} ++ ++static void rc_client_copy_achievements(rc_client_load_state_t* load_state, ++ rc_client_subset_info_t* subset, ++ const rc_api_achievement_definition_t* achievement_definitions, uint32_t num_achievements) ++{ ++ const rc_api_achievement_definition_t* read; ++ const rc_api_achievement_definition_t* stop; ++ rc_client_achievement_info_t* achievements; ++ rc_client_achievement_info_t* achievement; ++ rc_client_achievement_info_t* scan; ++ rc_buffer_t* buffer; ++ rc_preparse_state_t preparse; ++ const char* memaddr; ++ size_t size; ++ rc_trigger_t* trigger; ++ int trigger_size; ++ ++ subset->achievements = NULL; ++ subset->public_.num_achievements = num_achievements; ++ ++ if (num_achievements == 0) ++ return; ++ ++ stop = achievement_definitions + num_achievements; ++ ++ /* if not testing unofficial, filter them out */ ++ if (!load_state->client->state.unofficial_enabled) { ++ for (read = achievement_definitions; read < stop; ++read) { ++ if (read->category != RC_ACHIEVEMENT_CATEGORY_CORE) ++ --num_achievements; ++ } ++ ++ subset->public_.num_achievements = num_achievements; ++ ++ if (num_achievements == 0) ++ return; ++ } ++ ++ /* preallocate space for achievements */ ++ size = 24 /* assume average title length of 24 */ ++ + 48 /* assume average description length of 48 */ ++ + sizeof(rc_trigger_t) + sizeof(rc_condset_t) * 2 /* trigger container */ ++ + sizeof(rc_condition_t) * 8 /* assume average trigger length of 8 conditions */ ++ + sizeof(rc_client_achievement_info_t); ++ buffer = &load_state->game->buffer; ++ rc_buffer_reserve(buffer, size * num_achievements); ++ ++ /* allocate the achievement array */ ++ size = sizeof(rc_client_achievement_info_t) * num_achievements; ++ achievement = achievements = (rc_client_achievement_info_t*)rc_buffer_alloc(buffer, size); ++ memset(achievements, 0, size); ++ ++ /* copy the achievement data */ ++ for (read = achievement_definitions; read < stop; ++read) { ++ if (read->category != RC_ACHIEVEMENT_CATEGORY_CORE && !load_state->client->state.unofficial_enabled) ++ continue; ++ ++ achievement->public_.title = rc_buffer_strcpy(buffer, read->title); ++ achievement->public_.description = rc_buffer_strcpy(buffer, read->description); ++ snprintf(achievement->public_.badge_name, sizeof(achievement->public_.badge_name), "%s", read->badge_name); ++ achievement->public_.id = read->id; ++ achievement->public_.points = read->points; ++ achievement->public_.category = (read->category != RC_ACHIEVEMENT_CATEGORY_CORE) ? ++ RC_CLIENT_ACHIEVEMENT_CATEGORY_UNOFFICIAL : RC_CLIENT_ACHIEVEMENT_CATEGORY_CORE; ++ achievement->public_.rarity = read->rarity; ++ achievement->public_.rarity_hardcore = read->rarity_hardcore; ++ achievement->public_.type = read->type; /* assert: mapping is 1:1 */ ++ achievement->public_.badge_url = rc_buffer_strcpy(buffer, read->badge_url); ++ achievement->public_.badge_locked_url = rc_buffer_strcpy(buffer, read->badge_locked_url); ++ ++ memaddr = read->definition; ++ rc_runtime_checksum(memaddr, achievement->md5); ++ ++ rc_init_preparse_state(&preparse); ++ preparse.parse.existing_memrefs = load_state->game->runtime.memrefs; ++ trigger = RC_ALLOC(rc_trigger_t, &preparse.parse); ++ rc_parse_trigger_internal(trigger, &memaddr, &preparse.parse); ++ ++ trigger_size = preparse.parse.offset; ++ if (trigger_size < 0) { ++ RC_CLIENT_LOG_WARN_FORMATTED(load_state->client, "Parse error %d processing achievement %u", trigger_size, read->id); ++ achievement->public_.state = RC_CLIENT_ACHIEVEMENT_STATE_DISABLED; ++ achievement->public_.bucket = RC_CLIENT_ACHIEVEMENT_BUCKET_UNSUPPORTED; ++ } ++ else { ++ /* populate the item, using the communal memrefs pool */ ++ rc_reset_parse_state(&preparse.parse, rc_buffer_reserve(buffer, trigger_size)); ++ rc_preparse_reserve_memrefs(&preparse, load_state->game->runtime.memrefs); ++ achievement->trigger = RC_ALLOC(rc_trigger_t, &preparse.parse); ++ memaddr = read->definition; ++ rc_parse_trigger_internal(achievement->trigger, &memaddr, &preparse.parse); ++ ++ if (preparse.parse.offset < 0) { ++ RC_CLIENT_LOG_WARN_FORMATTED(load_state->client, "Parse error %d processing achievement %u", preparse.parse.offset, read->id); ++ achievement->public_.state = RC_CLIENT_ACHIEVEMENT_STATE_DISABLED; ++ achievement->public_.bucket = RC_CLIENT_ACHIEVEMENT_BUCKET_UNSUPPORTED; ++ } ++ else { ++ rc_buffer_consume(buffer, (const uint8_t*)preparse.parse.buffer, (uint8_t*)preparse.parse.buffer + preparse.parse.offset); ++ } ++ ++ rc_destroy_preparse_state(&preparse); ++ } ++ ++ achievement->created_time = read->created; ++ achievement->updated_time = read->updated; ++ ++ scan = achievement; ++ while (scan > achievements) { ++ --scan; ++ if (strcmp(scan->author, read->author) == 0) { ++ achievement->author = scan->author; ++ break; ++ } ++ } ++ if (!achievement->author) ++ achievement->author = rc_buffer_strcpy(buffer, read->author); ++ ++ ++achievement; ++ } ++ ++ subset->achievements = achievements; ++} ++ ++uint8_t rc_client_map_leaderboard_format(int format) ++{ ++ switch (format) { ++ case RC_FORMAT_SECONDS: ++ case RC_FORMAT_CENTISECS: ++ case RC_FORMAT_MINUTES: ++ case RC_FORMAT_SECONDS_AS_MINUTES: ++ case RC_FORMAT_FRAMES: ++ return RC_CLIENT_LEADERBOARD_FORMAT_TIME; ++ ++ case RC_FORMAT_SCORE: ++ return RC_CLIENT_LEADERBOARD_FORMAT_SCORE; ++ ++ case RC_FORMAT_VALUE: ++ case RC_FORMAT_FLOAT1: ++ case RC_FORMAT_FLOAT2: ++ case RC_FORMAT_FLOAT3: ++ case RC_FORMAT_FLOAT4: ++ case RC_FORMAT_FLOAT5: ++ case RC_FORMAT_FLOAT6: ++ case RC_FORMAT_FIXED1: ++ case RC_FORMAT_FIXED2: ++ case RC_FORMAT_FIXED3: ++ case RC_FORMAT_TENS: ++ case RC_FORMAT_HUNDREDS: ++ case RC_FORMAT_THOUSANDS: ++ case RC_FORMAT_UNSIGNED_VALUE: ++ default: ++ return RC_CLIENT_LEADERBOARD_FORMAT_VALUE; ++ } ++} ++ ++static void rc_client_copy_leaderboards(rc_client_load_state_t* load_state, ++ rc_client_subset_info_t* subset, ++ const rc_api_leaderboard_definition_t* leaderboard_definitions, uint32_t num_leaderboards) ++{ ++ const rc_api_leaderboard_definition_t* read; ++ const rc_api_leaderboard_definition_t* stop; ++ rc_client_leaderboard_info_t* leaderboards; ++ rc_client_leaderboard_info_t* leaderboard; ++ rc_buffer_t* buffer; ++ rc_preparse_state_t preparse; ++ const char* memaddr; ++ const char* ptr; ++ size_t size; ++ rc_lboard_t* lboard; ++ int lboard_size; ++ ++ subset->leaderboards = NULL; ++ subset->public_.num_leaderboards = num_leaderboards; ++ ++ if (num_leaderboards == 0) ++ return; ++ ++ /* preallocate space for achievements */ ++ size = 24 /* assume average title length of 24 */ ++ + 48 /* assume average description length of 48 */ ++ + sizeof(rc_lboard_t) /* lboard container */ ++ + (sizeof(rc_trigger_t) + sizeof(rc_condset_t) * 2) * 3 /* start/submit/cancel */ ++ + (sizeof(rc_value_t) + sizeof(rc_condset_t)) /* value */ ++ + sizeof(rc_condition_t) * 4 * 4 /* assume average of 4 conditions in each start/submit/cancel/value */ ++ + sizeof(rc_client_leaderboard_info_t); ++ rc_buffer_reserve(&load_state->game->buffer, size * num_leaderboards); ++ ++ /* allocate the achievement array */ ++ size = sizeof(rc_client_leaderboard_info_t) * num_leaderboards; ++ buffer = &load_state->game->buffer; ++ leaderboard = leaderboards = (rc_client_leaderboard_info_t*)rc_buffer_alloc(buffer, size); ++ memset(leaderboards, 0, size); ++ ++ /* copy the achievement data */ ++ read = leaderboard_definitions; ++ stop = read + num_leaderboards; ++ do { ++ leaderboard->public_.title = rc_buffer_strcpy(buffer, read->title); ++ leaderboard->public_.description = rc_buffer_strcpy(buffer, read->description); ++ leaderboard->public_.id = read->id; ++ leaderboard->public_.format = rc_client_map_leaderboard_format(read->format); ++ leaderboard->public_.lower_is_better = read->lower_is_better; ++ leaderboard->format = (uint8_t)read->format; ++ leaderboard->hidden = (uint8_t)read->hidden; ++ ++ memaddr = read->definition; ++ rc_runtime_checksum(memaddr, leaderboard->md5); ++ ++ ptr = strstr(memaddr, "VAL:"); ++ if (ptr != NULL) { ++ /* calculate the DJB2 hash of the VAL portion of the string*/ ++ uint32_t hash = 5381; ++ ptr += 4; /* skip 'VAL:' */ ++ while (*ptr && (ptr[0] != ':' || ptr[1] != ':')) ++ hash = (hash << 5) + hash + *ptr++; ++ leaderboard->value_djb2 = hash; ++ } ++ ++ rc_init_preparse_state(&preparse); ++ preparse.parse.existing_memrefs = load_state->game->runtime.memrefs; ++ lboard = RC_ALLOC(rc_lboard_t, &preparse.parse); ++ rc_parse_lboard_internal(lboard, memaddr, &preparse.parse); ++ ++ lboard_size = preparse.parse.offset; ++ if (lboard_size < 0) { ++ RC_CLIENT_LOG_WARN_FORMATTED(load_state->client, "Parse error %d processing leaderboard %u", lboard_size, read->id); ++ leaderboard->public_.state = RC_CLIENT_LEADERBOARD_STATE_DISABLED; ++ } ++ else { ++ /* populate the item, using the communal memrefs pool */ ++ rc_reset_parse_state(&preparse.parse, rc_buffer_reserve(buffer, lboard_size)); ++ rc_preparse_reserve_memrefs(&preparse, load_state->game->runtime.memrefs); ++ leaderboard->lboard = RC_ALLOC(rc_lboard_t, &preparse.parse); ++ rc_parse_lboard_internal(leaderboard->lboard, memaddr, &preparse.parse); ++ ++ if (preparse.parse.offset < 0) { ++ RC_CLIENT_LOG_WARN_FORMATTED(load_state->client, "Parse error %d processing leaderboard %u", preparse.parse.offset, read->id); ++ leaderboard->public_.state = RC_CLIENT_LEADERBOARD_STATE_DISABLED; ++ } ++ else { ++ rc_buffer_consume(buffer, (const uint8_t*)preparse.parse.buffer, (uint8_t*)preparse.parse.buffer + preparse.parse.offset); ++ } ++ ++ rc_destroy_preparse_state(&preparse); ++ } ++ ++ ++leaderboard; ++ ++read; ++ } while (read < stop); ++ ++ subset->leaderboards = leaderboards; ++} ++ ++static void rc_client_fetch_game_sets_callback(const rc_api_server_response_t* server_response, void* callback_data) ++{ ++ rc_client_load_state_t* load_state = (rc_client_load_state_t*)callback_data; ++ rc_api_fetch_game_sets_response_t fetch_game_sets_response; ++ int outstanding_requests; ++ const char* error_message; ++ int result; ++ ++ result = rc_client_end_async(load_state->client, &load_state->async_handle); ++ if (result) { ++ if (result != RC_CLIENT_ASYNC_DESTROYED) { ++ rc_client_t* client = load_state->client; ++ rc_client_load_aborted(load_state); ++ RC_CLIENT_LOG_VERBOSE(client, "Load aborted while fetching game data"); ++ } else { ++ rc_client_free_load_state(load_state); ++ } ++ return; ++ } ++ ++ result = rc_api_process_fetch_game_sets_server_response(&fetch_game_sets_response, server_response); ++ error_message = rc_client_server_error_message(&result, server_response->http_status_code, &fetch_game_sets_response.response); ++ ++ outstanding_requests = rc_client_end_load_state(load_state); ++ ++ if (error_message && result != RC_NOT_FOUND) { ++ rc_client_load_error(load_state, result, error_message); ++ } ++ else if (outstanding_requests < 0) { ++ /* previous load state was aborted, load_state was free'd */ ++ } ++ else if (fetch_game_sets_response.id == 0) { ++ load_state->hash->game_id = 0; ++ rc_client_process_resolved_hash(load_state); ++ } ++ else { ++ rc_client_subset_info_t** next_subset; ++ rc_client_subset_info_t* first_subset = NULL; ++ uint32_t set_index; ++ ++ /* hash exists outside the load state - always update it */ ++ load_state->hash->game_id = fetch_game_sets_response.id; ++ RC_CLIENT_LOG_INFO_FORMATTED(load_state->client, "Identified game: %u \"%s\" (%s)", load_state->hash->game_id, fetch_game_sets_response.title, load_state->hash->hash); ++ ++ if (load_state->hash->hash[0] != '[') { ++ /* not [NO HASH] or [SUBSETxx] */ ++ load_state->game->public_.id = load_state->hash->game_id; ++ load_state->game->public_.hash = load_state->hash->hash; ++ } ++ ++ if (load_state->game->public_.console_id != RC_CONSOLE_UNKNOWN && ++ fetch_game_sets_response.console_id != load_state->game->public_.console_id) { ++ RC_CLIENT_LOG_WARN_FORMATTED(load_state->client, "Data for game %u is for console %u, expecting console %u", ++ fetch_game_sets_response.id, fetch_game_sets_response.console_id, load_state->game->public_.console_id); ++ } ++ ++ /* kick off the start session request while we process the game data */ ++ rc_client_begin_load_state(load_state, RC_CLIENT_LOAD_GAME_STATE_STARTING_SESSION, 1); ++ if (load_state->client->state.spectator_mode != RC_CLIENT_SPECTATOR_MODE_OFF) { ++ /* we can't unlock achievements without a session, lock spectator mode for the game */ ++ load_state->client->state.spectator_mode = RC_CLIENT_SPECTATOR_MODE_LOCKED; ++ } ++ else { ++ rc_client_begin_start_session(load_state); ++ } ++ ++ /* process the game data */ ++ next_subset = &first_subset; ++ for (set_index = 0; set_index < fetch_game_sets_response.num_sets; ++set_index) { ++ rc_api_achievement_set_definition_t* set = &fetch_game_sets_response.sets[set_index]; ++ rc_client_subset_info_t* subset; ++ ++ subset = (rc_client_subset_info_t*)rc_buffer_alloc(&load_state->game->buffer, sizeof(rc_client_subset_info_t)); ++ memset(subset, 0, sizeof(*subset)); ++ subset->public_.id = set->id; ++ subset->active = 1; ++ snprintf(subset->public_.badge_name, sizeof(subset->public_.badge_name), "%s", set->image_name); ++ subset->public_.badge_url = rc_buffer_strcpy(&load_state->game->buffer, set->image_url); ++ subset->public_.title = rc_buffer_strcpy(&load_state->game->buffer, set->title); ++ ++ rc_client_copy_achievements(load_state, subset, set->achievements, set->num_achievements); ++ rc_client_copy_leaderboards(load_state, subset, set->leaderboards, set->num_leaderboards); ++ ++ if (set->type == RC_ACHIEVEMENT_SET_TYPE_CORE) { ++ if (!first_subset) ++ next_subset = &subset->next; ++ subset->next = first_subset; ++ first_subset = subset; ++ } ++ else { ++ *next_subset = subset; ++ next_subset = &subset->next; ++ } ++ } ++ ++ if (!first_subset) { ++ rc_client_load_error(load_state, RC_NOT_FOUND, "Response contained no sets"); ++ } else { ++ load_state->subset = first_subset; ++ ++ /* core set */ ++ rc_mutex_lock(&load_state->client->state.mutex); ++ load_state->game->public_.title = rc_buffer_strcpy(&load_state->game->buffer, fetch_game_sets_response.title); ++ load_state->game->subsets = first_subset; ++ load_state->game->public_.badge_name = first_subset->public_.badge_name; ++ load_state->game->public_.badge_url = first_subset->public_.badge_url; ++ load_state->game->public_.console_id = fetch_game_sets_response.console_id; ++ rc_mutex_unlock(&load_state->client->state.mutex); ++ ++ if (fetch_game_sets_response.rich_presence_script && fetch_game_sets_response.rich_presence_script[0]) { ++ result = rc_runtime_activate_richpresence(&load_state->game->runtime, fetch_game_sets_response.rich_presence_script, NULL, 0); ++ if (result != RC_OK) { ++ RC_CLIENT_LOG_WARN_FORMATTED(load_state->client, "Parse error %d processing rich presence", result); ++ } ++ } ++ ++ if (load_state->client->callbacks.post_process_game_sets_response) { ++ load_state->client->callbacks.post_process_game_sets_response(server_response, ++ &fetch_game_sets_response, load_state->client, load_state->callback_userdata); ++ } ++ } ++ ++ outstanding_requests = rc_client_end_load_state(load_state); ++ if (outstanding_requests < 0) { ++ /* previous load state was aborted, load_state was free'd */ ++ } ++ else if (outstanding_requests == 0) { ++ if (load_state->client->state.allow_background_memory_reads) ++ rc_client_activate_game(load_state, load_state->start_session_response); ++ else ++ rc_client_queue_activate_game(load_state); ++ } ++ } ++ ++ rc_api_destroy_fetch_game_sets_response(&fetch_game_sets_response); ++} ++ ++static rc_client_game_info_t* rc_client_allocate_game(void) ++{ ++ rc_client_game_info_t* game = (rc_client_game_info_t*)calloc(1, sizeof(*game)); ++ if (!game) ++ return NULL; ++ ++ rc_buffer_init(&game->buffer); ++ rc_runtime_init(&game->runtime); ++ ++ return game; ++} ++ ++static int rc_client_attach_load_state(rc_client_t* client, rc_client_load_state_t* load_state) ++{ ++ if (client->state.load == NULL) { ++ rc_client_unload_game(client); ++ ++ if (load_state->game == NULL) { ++ load_state->game = rc_client_allocate_game(); ++ if (!load_state->game) { ++ if (load_state->callback) ++ load_state->callback(RC_OUT_OF_MEMORY, rc_error_str(RC_OUT_OF_MEMORY), client, load_state->callback_userdata); ++ ++ return 0; ++ } ++ } ++ ++ rc_mutex_lock(&client->state.mutex); ++ client->state.load = load_state; ++ client->state.frames_processed = client->state.frames_at_last_ping = 0; ++ rc_mutex_unlock(&client->state.mutex); ++ } ++ else if (client->state.load != load_state) { ++ /* previous load was aborted */ ++ if (load_state->callback) ++ load_state->callback(RC_ABORTED, "The requested game is no longer active", client, load_state->callback_userdata); ++ ++ return 0; ++ } ++ ++ return 1; ++} ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ ++static void rc_client_external_load_state_callback(int result, const char* error_message, rc_client_t* client, void* userdata) ++{ ++ rc_client_load_state_t* load_state = (rc_client_load_state_t*)userdata; ++ int async_aborted; ++ ++ client = load_state->client; ++ async_aborted = rc_client_end_async(client, &load_state->async_handle); ++ if (async_aborted) { ++ if (async_aborted != RC_CLIENT_ASYNC_DESTROYED) { ++ RC_CLIENT_LOG_VERBOSE(client, "Load aborted during external loading"); ++ } ++ ++ rc_client_unload_game(client); /* unload the game from the external client */ ++ rc_client_free_load_state(load_state); ++ return; ++ } ++ ++ if (result != RC_OK) { ++ rc_client_load_error(load_state, result, error_message); ++ return; ++ } ++ ++ rc_mutex_lock(&client->state.mutex); ++ load_state->progress = (client->state.load == load_state) ? ++ RC_CLIENT_LOAD_GAME_STATE_DONE : RC_CLIENT_LOAD_GAME_STATE_ABORTED; ++ client->state.load = NULL; ++ rc_mutex_unlock(&client->state.mutex); ++ ++ if (load_state->progress != RC_CLIENT_LOAD_GAME_STATE_DONE) { ++ /* previous load state was aborted */ ++ if (load_state->callback) ++ load_state->callback(RC_ABORTED, "The requested game is no longer active", client, load_state->callback_userdata); ++ } ++ else { ++ /* keep partial game object for media_hash management */ ++ if (client->state.external_client) { ++ const rc_client_game_t* info = rc_client_get_game_info(client); ++ load_state->game->public_.console_id = info->console_id; ++ client->game = load_state->game; ++ load_state->game = NULL; ++ } ++ ++ if (load_state->callback) ++ load_state->callback(RC_OK, NULL, client, load_state->callback_userdata); ++ } ++ ++ rc_client_free_load_state(load_state); ++} ++ ++#endif ++ ++static void rc_client_initialize_unknown_game(rc_client_game_info_t* game) ++{ ++ rc_client_subset_info_t* subset; ++ char buffer[64]; ++ ++ subset = (rc_client_subset_info_t*)rc_buffer_alloc(&game->buffer, sizeof(rc_client_subset_info_t)); ++ memset(subset, 0, sizeof(*subset)); ++ subset->public_.title = ""; ++ game->subsets = subset; ++ ++ game->public_.title = "Unknown Game"; ++ game->public_.badge_name = ""; ++ ++ rc_client_get_image_url(buffer, sizeof(buffer), RC_IMAGE_TYPE_GAME, "000001"); ++ game->public_.badge_url = rc_buffer_strcpy(&game->buffer, buffer); ++} ++ ++static void rc_client_process_resolved_hash(rc_client_load_state_t* load_state) ++{ ++ rc_client_t* client = load_state->client; ++ ++ if (load_state->hash->game_id == 0) { ++#ifdef RC_CLIENT_SUPPORTS_HASH ++ char hash[33]; ++ ++ if (rc_hash_iterate(hash, &load_state->hash_iterator)) { ++ /* found another hash to try */ ++ load_state->hash_console_id = load_state->hash_iterator.consoles[load_state->hash_iterator.index - 1]; ++ rc_client_load_game(load_state, hash, NULL); ++ return; ++ } ++ ++ if (load_state->tried_hashes[1]) { ++ /* multiple hashes were tried, create a CSV */ ++ size_t i; ++ size_t count = 0; ++ char* ptr; ++ size_t size = 0; ++ ++ for (i = 0; i < sizeof(load_state->tried_hashes) / sizeof(load_state->tried_hashes[0]); ++i) { ++ if (!load_state->tried_hashes[i]) ++ break; ++ ++ size += strlen(load_state->tried_hashes[i]->hash) + 1; ++ count++; ++ } ++ ++ ptr = (char*)rc_buffer_alloc(&load_state->game->buffer, size); ++ load_state->game->public_.hash = ptr; ++ for (i = 0; i < count; i++) { ++ const size_t hash_len = strlen(load_state->tried_hashes[i]->hash); ++ memcpy(ptr, load_state->tried_hashes[i]->hash, hash_len); ++ ptr += hash_len; ++ *ptr++ = ','; ++ } ++ *(ptr - 1) = '\0'; ++ ++ load_state->game->public_.console_id = RC_CONSOLE_UNKNOWN; ++ } else { ++ /* only a single hash was tried, capture it */ ++ load_state->game->public_.console_id = load_state->hash_console_id; ++ load_state->game->public_.hash = load_state->hash->hash; ++ ++ if (client->callbacks.identify_unknown_hash) { ++ load_state->hash->game_id = client->callbacks.identify_unknown_hash( ++ load_state->hash_console_id, load_state->hash->hash, client, load_state->callback_userdata); ++ ++ if (load_state->hash->game_id != 0) { ++ load_state->hash->is_unknown = 1; ++ RC_CLIENT_LOG_INFO_FORMATTED(load_state->client, "Client says to load game %u for unidentified hash %s", ++ load_state->hash->game_id, load_state->hash->hash); ++ } ++ } ++ } ++ ++ rc_hash_destroy_iterator(&load_state->hash_iterator); /* done with this now */ ++#else ++ load_state->game->public_.console_id = RC_CONSOLE_UNKNOWN; ++ load_state->game->public_.hash = load_state->hash->hash; ++#endif /* RC_CLIENT_SUPPORTS_HASH */ ++ ++ if (load_state->hash->game_id == 0) { ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ #ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION ++ if (client->state.raintegration && client->state.raintegration->set_console_id) { ++ if (load_state->game->public_.console_id != RC_CONSOLE_UNKNOWN) ++ client->state.raintegration->set_console_id(load_state->game->public_.console_id); ++ } ++ #endif ++ if (client->state.external_client) { ++ if (client->state.external_client->load_unknown_game) { ++ client->state.external_client->load_unknown_game(load_state->game->public_.hash); ++ rc_client_load_error(load_state, RC_NO_GAME_LOADED, "Unknown game"); ++ return; ++ } ++ /* no external method specifically for unknown game, just pass the hash through to begin_load_game below */ ++ } ++ else { ++#endif ++ rc_client_initialize_unknown_game(load_state->game); ++ ++ client->game = load_state->game; ++ load_state->game = NULL; ++ ++ rc_client_load_error(load_state, RC_NO_GAME_LOADED, "Unknown game"); ++ return; ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ } ++#endif ++ } ++ } ++ ++ if (load_state->hash->hash[0] != '[') { /* not [NO HASH] or [SUBSETxx] */ ++ load_state->game->public_.id = load_state->hash->game_id; ++ load_state->game->public_.hash = load_state->hash->hash; ++ } ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client) { ++ if (client->state.external_client->add_game_hash) ++ client->state.external_client->add_game_hash(load_state->hash->hash, load_state->hash->game_id); ++ ++ if (client->state.external_client->begin_load_game) { ++ rc_client_begin_async(client, &load_state->async_handle); ++ client->state.external_client->begin_load_game(client, load_state->hash->hash, rc_client_external_load_state_callback, load_state); ++ } ++ return; ++ } ++#endif ++ ++ rc_client_begin_fetch_game_sets(load_state); ++} ++ ++void rc_client_load_unknown_game(rc_client_t* client, const char* tried_hashes) ++{ ++ rc_client_game_info_t* game; ++ ++ game = rc_client_allocate_game(); ++ if (!game) ++ return; ++ ++ rc_client_initialize_unknown_game(game); ++ game->public_.console_id = RC_CONSOLE_UNKNOWN; ++ ++ if (strlen(tried_hashes) == 32) { /* only one hash tried, add it to the list */ ++ rc_client_game_hash_t* game_hash = rc_client_find_game_hash(client, tried_hashes); ++ game_hash->game_id = 0; ++ game->public_.hash = game_hash->hash; ++ } ++ else { ++ game->public_.hash = rc_buffer_strcpy(&game->buffer, tried_hashes); ++ } ++ ++ rc_client_unload_game(client); ++ client->game = game; ++} ++ ++static void rc_client_begin_fetch_game_sets(rc_client_load_state_t* load_state) ++{ ++ rc_api_fetch_game_sets_request_t fetch_game_sets_request; ++ rc_client_t* client = load_state->client; ++ rc_api_request_t request; ++ int result; ++ ++ rc_mutex_lock(&client->state.mutex); ++ result = client->state.user; ++ if (result == RC_CLIENT_USER_STATE_LOGIN_REQUESTED) ++ load_state->progress = RC_CLIENT_LOAD_GAME_STATE_AWAIT_LOGIN; ++ else ++ load_state->progress = RC_CLIENT_LOAD_GAME_STATE_FETCHING_GAME_DATA; ++ rc_mutex_unlock(&client->state.mutex); ++ ++ switch (result) { ++ case RC_CLIENT_USER_STATE_LOGGED_IN: ++ break; ++ ++ case RC_CLIENT_USER_STATE_LOGIN_REQUESTED: ++ /* do nothing, this function will be called again after login completes */ ++ return; ++ ++ default: ++ rc_client_load_error(load_state, RC_LOGIN_REQUIRED, rc_error_str(RC_LOGIN_REQUIRED)); ++ return; ++ } ++ ++ memset(&fetch_game_sets_request, 0, sizeof(fetch_game_sets_request)); ++ fetch_game_sets_request.username = client->user.username; ++ fetch_game_sets_request.api_token = client->user.token; ++ ++ if (load_state->hash->is_unknown) /* lookup failed, but client provided a mapping */ ++ fetch_game_sets_request.game_id = load_state->hash->game_id; ++ else ++ fetch_game_sets_request.game_hash = load_state->hash->hash; ++ ++ result = rc_api_init_fetch_game_sets_request_hosted(&request, &fetch_game_sets_request, &client->state.host); ++ if (result != RC_OK) { ++ rc_client_load_error(load_state, result, rc_error_str(result)); ++ return; ++ } ++ ++ rc_client_begin_load_state(load_state, RC_CLIENT_LOAD_GAME_STATE_IDENTIFYING_GAME, 1); ++ RC_CLIENT_LOG_VERBOSE_FORMATTED(client, "Fetching data for hash %s", fetch_game_sets_request.game_hash); ++ ++ rc_client_begin_async(client, &load_state->async_handle); ++ client->callbacks.server_call(&request, rc_client_fetch_game_sets_callback, load_state, client); ++ ++ rc_api_destroy_request(&request); ++} ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++static void rc_client_identify_game_callback(const rc_api_server_response_t* server_response, void* callback_data) ++{ ++ rc_client_load_state_t* load_state = (rc_client_load_state_t*)callback_data; ++ rc_client_t* client = load_state->client; ++ rc_api_resolve_hash_response_t resolve_hash_response; ++ int outstanding_requests; ++ const char* error_message; ++ int result; ++ ++ result = rc_client_end_async(client, &load_state->async_handle); ++ if (result) { ++ if (result != RC_CLIENT_ASYNC_DESTROYED) { ++ rc_client_load_aborted(load_state); ++ RC_CLIENT_LOG_VERBOSE(client, "Load aborted during game identification"); ++ } else { ++ rc_client_free_load_state(load_state); ++ } ++ return; ++ } ++ ++ result = rc_api_process_resolve_hash_server_response(&resolve_hash_response, server_response); ++ error_message = rc_client_server_error_message(&result, server_response->http_status_code, &resolve_hash_response.response); ++ ++ if (error_message) { ++ rc_client_end_load_state(load_state); ++ rc_client_load_error(load_state, result, error_message); ++ } ++ else { ++ /* hash exists outside the load state - always update it */ ++ load_state->hash->game_id = resolve_hash_response.game_id; ++ RC_CLIENT_LOG_INFO_FORMATTED(client, "Identified game: %u (%s)", load_state->hash->game_id, load_state->hash->hash); ++ ++ /* have to call end_load_state after updating hash in case the load_state gets free'd */ ++ outstanding_requests = rc_client_end_load_state(load_state); ++ if (outstanding_requests < 0) { ++ /* previous load state was aborted, load_state was free'd */ ++ } ++ else { ++ rc_client_process_resolved_hash(load_state); ++ } ++ } ++ ++ rc_api_destroy_resolve_hash_response(&resolve_hash_response); ++} ++#endif ++ ++rc_client_game_hash_t* rc_client_find_game_hash(rc_client_t* client, const char* hash) ++{ ++ rc_client_game_hash_t* game_hash; ++ ++ rc_mutex_lock(&client->state.mutex); ++ game_hash = client->hashes; ++ while (game_hash) { ++ if (strcasecmp(game_hash->hash, hash) == 0) ++ break; ++ ++ game_hash = game_hash->next; ++ } ++ ++ if (!game_hash) { ++ game_hash = (rc_client_game_hash_t*)rc_buffer_alloc(&client->state.buffer, sizeof(rc_client_game_hash_t)); ++ memset(game_hash, 0, sizeof(*game_hash)); ++ snprintf(game_hash->hash, sizeof(game_hash->hash), "%s", hash); ++ game_hash->game_id = RC_CLIENT_UNKNOWN_GAME_ID; ++ game_hash->next = client->hashes; ++ client->hashes = game_hash; ++ } ++ rc_mutex_unlock(&client->state.mutex); ++ ++ return game_hash; ++} ++ ++void rc_client_add_game_hash(rc_client_t* client, const char* hash, uint32_t game_id) ++{ ++ /* store locally, even if passing to external client */ ++ rc_client_game_hash_t* game_hash = rc_client_find_game_hash(client, hash); ++ game_hash->game_id = game_id; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->add_game_hash) ++ client->state.external_client->add_game_hash(hash, game_id); ++#endif ++} ++ ++static rc_client_async_handle_t* rc_client_load_game(rc_client_load_state_t* load_state, ++ const char* hash, const char* file_path) ++{ ++ rc_client_t* client = load_state->client; ++ rc_client_game_hash_t* old_hash; ++#ifdef RC_CLIENT_SUPPORTS_HASH ++ size_t i; ++#endif ++ ++ if (!rc_client_attach_load_state(client, load_state)) { ++ rc_client_free_load_state(load_state); ++ return NULL; ++ } ++ ++ old_hash = load_state->hash; ++ load_state->hash = rc_client_find_game_hash(client, hash); ++ ++#ifdef RC_CLIENT_SUPPORTS_HASH ++ i = 0; ++ do { ++ if (!load_state->tried_hashes[i]) { ++ load_state->tried_hashes[i] = load_state->hash; ++ break; ++ } ++ ++ if (load_state->tried_hashes[i] == load_state->hash) ++ break; ++ ++ if (++i == sizeof(load_state->tried_hashes) / sizeof(load_state->tried_hashes[0])) { ++ RC_CLIENT_LOG_VERBOSE(client, "tried_hashes buffer is full"); ++ break; ++ } ++ } while (1); ++#endif ++ ++ if (file_path) { ++ rc_client_media_hash_t* media_hash = ++ (rc_client_media_hash_t*)rc_buffer_alloc(&load_state->game->buffer, sizeof(*media_hash)); ++ media_hash->game_hash = load_state->hash; ++ media_hash->path_djb2 = rc_djb2(file_path); ++ media_hash->next = load_state->game->media_hash; ++ load_state->game->media_hash = media_hash; ++ } ++ else if (load_state->game->media_hash && load_state->game->media_hash->game_hash == old_hash) { ++ load_state->game->media_hash->game_hash = load_state->hash; ++ } ++ ++ if (load_state->hash->game_id == 0) { ++ rc_client_process_resolved_hash(load_state); ++ } ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ else if (load_state->hash->game_id == RC_CLIENT_UNKNOWN_GAME_ID && ++ client->state.external_client && client->state.external_client->add_game_hash) { ++ /* if an add_game_hash external handler exists, do the identification locally, then ++ * pass the resulting game_id/hash to the external client */ ++ rc_api_resolve_hash_request_t resolve_hash_request; ++ rc_api_request_t request; ++ int result; ++ ++ memset(&resolve_hash_request, 0, sizeof(resolve_hash_request)); ++ resolve_hash_request.game_hash = hash; ++ ++ result = rc_api_init_resolve_hash_request_hosted(&request, &resolve_hash_request, &client->state.host); ++ if (result != RC_OK) { ++ rc_client_load_error(load_state, result, rc_error_str(result)); ++ return NULL; ++ } ++ ++ rc_client_begin_load_state(load_state, RC_CLIENT_LOAD_GAME_STATE_IDENTIFYING_GAME, 1); ++ ++ rc_client_begin_async(client, &load_state->async_handle); ++ client->callbacks.server_call(&request, rc_client_identify_game_callback, load_state, client); ++ ++ rc_api_destroy_request(&request); ++ } ++ else if (load_state->hash->game_id != RC_CLIENT_UNKNOWN_GAME_ID && ++ client->state.external_client && client->state.external_client->begin_load_game) { ++ rc_client_begin_async(client, &load_state->async_handle); ++ client->state.external_client->begin_load_game(client, load_state->hash->hash, rc_client_external_load_state_callback, load_state); ++ } ++#endif ++ else { ++ rc_client_begin_fetch_game_sets(load_state); ++ } ++ ++ return (client->state.load == load_state) ? &load_state->async_handle : NULL; ++} ++ ++static void rc_client_abort_load_in_progress(rc_client_t* client) ++{ ++ rc_client_load_state_t* load_state; ++ ++ rc_mutex_lock(&client->state.mutex); ++ ++ load_state = client->state.load; ++ if (load_state) { ++ /* this mimics rc_client_abort_async without nesting the lock */ ++ load_state->async_handle.aborted = RC_CLIENT_ASYNC_ABORTED; ++ ++ client->state.load = NULL; ++ } ++ ++ rc_mutex_unlock(&client->state.mutex); ++ ++ if (load_state && load_state->callback) ++ load_state->callback(RC_ABORTED, "The requested game is no longer active", load_state->client, load_state->callback_userdata); ++} ++ ++rc_client_async_handle_t* rc_client_begin_load_game(rc_client_t* client, const char* hash, rc_client_callback_t callback, void* callback_userdata) ++{ ++ rc_client_load_state_t* load_state; ++ ++ if (!client) { ++ callback(RC_INVALID_STATE, "client is required", client, callback_userdata); ++ return NULL; ++ } ++ ++ if (!hash || !hash[0]) { ++ callback(RC_INVALID_STATE, "hash is required", client, callback_userdata); ++ return NULL; ++ } ++ ++ rc_client_abort_load_in_progress(client); ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->begin_load_game) ++ return client->state.external_client->begin_load_game(client, hash, callback, callback_userdata); ++#endif ++ ++ load_state = (rc_client_load_state_t*)calloc(1, sizeof(*load_state)); ++ if (!load_state) { ++ callback(RC_OUT_OF_MEMORY, rc_error_str(RC_OUT_OF_MEMORY), client, callback_userdata); ++ return NULL; ++ } ++ ++ load_state->client = client; ++ load_state->callback = callback; ++ load_state->callback_userdata = callback_userdata; ++ ++ return rc_client_load_game(load_state, hash, NULL); ++} ++ ++#ifdef RC_CLIENT_SUPPORTS_HASH ++ ++rc_hash_iterator_t* rc_client_get_load_state_hash_iterator(rc_client_t* client) ++{ ++ if (client && client->state.load) ++ return &client->state.load->hash_iterator; ++ ++ return NULL; ++} ++ ++static void rc_client_log_hash_message_verbose(const char* message, const rc_hash_iterator_t* iterator) ++{ ++ const rc_client_load_state_t* load_state = (const rc_client_load_state_t*)iterator->userdata; ++ if (load_state->client->state.log_level >= RC_CLIENT_LOG_LEVEL_INFO) ++ rc_client_log_message(load_state->client, message); ++} ++ ++static void rc_client_log_hash_message_error(const char* message, const rc_hash_iterator_t* iterator) ++{ ++ const rc_client_load_state_t* load_state = (const rc_client_load_state_t*)iterator->userdata; ++ if (load_state->client->state.log_level >= RC_CLIENT_LOG_LEVEL_ERROR) ++ rc_client_log_message(load_state->client, message); ++} ++ ++void rc_client_set_hash_callbacks(rc_client_t* client, const struct rc_hash_callbacks* callbacks) ++{ ++ memcpy(&client->callbacks.hash, callbacks, sizeof(*callbacks)); ++ ++ if (!callbacks->verbose_message) ++ client->callbacks.hash.verbose_message = rc_client_log_hash_message_verbose; ++ if (!callbacks->error_message) ++ client->callbacks.hash.error_message = rc_client_log_hash_message_error; ++} ++ ++rc_client_async_handle_t* rc_client_begin_identify_and_load_game(rc_client_t* client, ++ uint32_t console_id, const char* file_path, ++ const uint8_t* data, size_t data_size, ++ rc_client_callback_t callback, void* callback_userdata) ++{ ++ rc_client_load_state_t* load_state; ++ char hash[33]; ++ ++ if (!client) { ++ callback(RC_INVALID_STATE, "client is required", client, callback_userdata); ++ return NULL; ++ } ++ ++ rc_client_abort_load_in_progress(client); ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ /* if a add_game_hash handler exists, do the identification locally, then pass the ++ * resulting game_id/hash to the external client */ ++ if (client->state.external_client && !client->state.external_client->add_game_hash) { ++ if (client->state.external_client->begin_identify_and_load_game) ++ return client->state.external_client->begin_identify_and_load_game(client, console_id, file_path, data, data_size, callback, callback_userdata); ++ } ++#endif ++ ++ if (data) { ++ if (file_path) { ++ RC_CLIENT_LOG_INFO_FORMATTED(client, "Identifying game: %zu bytes at %p (%s)", data_size, data, file_path); ++ } ++ else { ++ RC_CLIENT_LOG_INFO_FORMATTED(client, "Identifying game: %zu bytes at %p", data_size, data); ++ } ++ } ++ else if (file_path) { ++ RC_CLIENT_LOG_INFO_FORMATTED(client, "Identifying game: %s", file_path); ++ } ++ else { ++ callback(RC_INVALID_STATE, "either data or file_path is required", client, callback_userdata); ++ return NULL; ++ } ++ ++ if (!file_path) ++ file_path = "?"; ++ ++ load_state = (rc_client_load_state_t*)calloc(1, sizeof(*load_state)); ++ if (!load_state) { ++ callback(RC_OUT_OF_MEMORY, rc_error_str(RC_OUT_OF_MEMORY), client, callback_userdata); ++ return NULL; ++ } ++ load_state->client = client; ++ load_state->callback = callback; ++ load_state->callback_userdata = callback_userdata; ++ ++ /* initialize the iterator */ ++ rc_hash_initialize_iterator(&load_state->hash_iterator, file_path, data, data_size); ++ rc_hash_merge_callbacks(&load_state->hash_iterator, &client->callbacks.hash); ++ load_state->hash_iterator.userdata = load_state; ++ ++ if (!load_state->hash_iterator.callbacks.verbose_message) ++ load_state->hash_iterator.callbacks.verbose_message = rc_client_log_hash_message_verbose; ++ if (!load_state->hash_iterator.callbacks.error_message) ++ load_state->hash_iterator.callbacks.error_message = rc_client_log_hash_message_error; ++ ++ /* calculate the hash */ ++ if (console_id == RC_CONSOLE_UNKNOWN) { ++ if (!rc_hash_iterate(hash, &load_state->hash_iterator)) { ++ rc_client_load_error(load_state, RC_INVALID_STATE, "hash generation failed"); ++ return NULL; ++ } ++ ++ load_state->hash_console_id = load_state->hash_iterator.consoles[load_state->hash_iterator.index - 1]; ++ } ++ else { ++ /* ASSERT: hash_iterator->index and hash_iterator->consoles[0] will be 0 from calloc */ ++ load_state->hash_console_id = console_id; ++ ++ /* prevent initializing the iterator so it won't try other consoles in rc_client_process_resolved_hash */ ++ load_state->hash_iterator.index = 0; ++ ++ if (!rc_hash_generate(hash, console_id, &load_state->hash_iterator)) { ++ rc_client_load_error(load_state, RC_INVALID_STATE, "hash generation failed"); ++ return NULL; ++ } ++ } ++ ++ return rc_client_load_game(load_state, hash, file_path); ++} ++ ++#endif /* RC_CLIENT_SUPPORTS_HASH */ ++ ++int rc_client_get_load_game_state(const rc_client_t* client) ++{ ++ int state = RC_CLIENT_LOAD_GAME_STATE_NONE; ++ if (client) { ++ const rc_client_load_state_t* load_state = client->state.load; ++ if (load_state) ++ state = load_state->progress; ++ else if (client->game) ++ state = RC_CLIENT_LOAD_GAME_STATE_DONE; ++ } ++ ++ return state; ++} ++ ++int rc_client_is_game_loaded(const rc_client_t* client) ++{ ++ if (!client) ++ return 0; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client) { ++ const rc_client_game_t* game = rc_client_get_game_info(client); ++ return (game && game->id != 0); ++ } ++#endif ++ ++ return (client->game && client->game->public_.id != 0); ++} ++ ++static void rc_client_game_mark_ui_to_be_hidden(rc_client_t* client, rc_client_game_info_t* game) ++{ ++ rc_client_achievement_info_t* achievement; ++ rc_client_achievement_info_t* achievement_stop; ++ rc_client_leaderboard_info_t* leaderboard; ++ rc_client_leaderboard_info_t* leaderboard_stop; ++ rc_client_subset_info_t* subset; ++ ++ for (subset = game->subsets; subset; subset = subset->next) { ++ achievement = subset->achievements; ++ achievement_stop = achievement + subset->public_.num_achievements; ++ for (; achievement < achievement_stop; ++achievement) { ++ if (achievement->public_.state == RC_CLIENT_ACHIEVEMENT_STATE_ACTIVE && ++ achievement->trigger && achievement->trigger->state == RC_TRIGGER_STATE_PRIMED) { ++ achievement->pending_events |= RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_CHALLENGE_INDICATOR_HIDE; ++ subset->pending_events |= RC_CLIENT_SUBSET_PENDING_EVENT_ACHIEVEMENT; ++ } ++ } ++ ++ leaderboard = subset->leaderboards; ++ leaderboard_stop = leaderboard + subset->public_.num_leaderboards; ++ for (; leaderboard < leaderboard_stop; ++leaderboard) { ++ if (leaderboard->public_.state == RC_CLIENT_LEADERBOARD_STATE_TRACKING) ++ rc_client_release_leaderboard_tracker(game, leaderboard); ++ } ++ } ++ ++ rc_client_hide_progress_tracker(client, game); ++} ++ ++void rc_client_unload_game(rc_client_t* client) ++{ ++ rc_client_game_info_t* game; ++ ++ if (!client) ++ return; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->unload_game) { ++ client->state.external_client->unload_game(); ++ ++ /* a game object may have been allocated to manage hashes */ ++ game = client->game; ++ client->game = NULL; ++ if (game != NULL) ++ rc_client_free_game(game); ++ ++ return; ++ } ++#endif ++ ++ rc_mutex_lock(&client->state.mutex); ++ ++ game = client->game; ++ client->game = NULL; ++ ++ if (client->state.load) { ++ /* this mimics rc_client_abort_async without nesting the lock */ ++ client->state.load->async_handle.aborted = RC_CLIENT_ASYNC_ABORTED; ++ ++ /* if the game is still being loaded, let the load process clean it up */ ++ if (client->state.load->game == game) ++ game = NULL; ++ ++ client->state.load = NULL; ++ } ++ ++ if (client->state.spectator_mode == RC_CLIENT_SPECTATOR_MODE_LOCKED) ++ client->state.spectator_mode = RC_CLIENT_SPECTATOR_MODE_ON; ++ ++ if (game != NULL) { ++ rc_client_scheduled_callback_data_t** last; ++ rc_client_scheduled_callback_data_t* next; ++ ++ rc_client_game_mark_ui_to_be_hidden(client, game); ++ ++ last = &client->state.scheduled_callbacks; ++ do { ++ next = *last; ++ if (!next) ++ break; ++ ++ /* remove rich presence ping scheduled event for game */ ++ if (next->callback == rc_client_ping && next->related_id == game->public_.id) { ++ *last = next->next; ++ continue; ++ } ++ ++ last = &next->next; ++ } while (1); ++ } ++ ++ rc_mutex_unlock(&client->state.mutex); ++ ++ if (game != NULL) { ++ rc_client_raise_pending_events(client, game); ++ ++ RC_CLIENT_LOG_INFO_FORMATTED(client, "Unloading game %u", game->public_.id); ++ rc_client_free_game(game); ++ } ++} ++ ++static void rc_client_change_media_internal(rc_client_t* client, const rc_client_game_hash_t* game_hash, rc_client_callback_t callback, void* callback_userdata) ++{ ++ client->game->public_.hash = game_hash->hash; ++ ++ if (game_hash->game_id == client->game->public_.id) { ++ RC_CLIENT_LOG_INFO_FORMATTED(client, "Switching to valid media for game %u: %s", game_hash->game_id, game_hash->hash); ++ } ++ else if (game_hash->game_id == RC_CLIENT_UNKNOWN_GAME_ID) { ++ RC_CLIENT_LOG_INFO(client, "Switching to unknown media"); ++ } ++ else if (game_hash->game_id == 0) { ++ if (client->state.hardcore) { ++ RC_CLIENT_LOG_WARN_FORMATTED(client, "Disabling hardcore for unidentified media: %s", game_hash->hash); ++ rc_client_set_hardcore_enabled(client, 0); ++ callback(RC_HARDCORE_DISABLED, "Hardcore disabled. Unidentified media inserted.", client, callback_userdata); ++ return; ++ } ++ ++ RC_CLIENT_LOG_INFO_FORMATTED(client, "Switching to unrecognized media: %s", game_hash->hash); ++ } ++ else { ++ RC_CLIENT_LOG_INFO_FORMATTED(client, "Switching to known media for game %u: %s", game_hash->game_id, game_hash->hash); ++ } ++ ++ callback(RC_OK, NULL, client, callback_userdata); ++} ++ ++static void rc_client_identify_changed_media_callback(const rc_api_server_response_t* server_response, void* callback_data) ++{ ++ rc_client_load_state_t* load_state = (rc_client_load_state_t*)callback_data; ++ rc_client_t* client = load_state->client; ++ rc_api_resolve_hash_response_t resolve_hash_response; ++ ++ int result = rc_api_process_resolve_hash_server_response(&resolve_hash_response, server_response); ++ const char* error_message = rc_client_server_error_message(&result, server_response->http_status_code, &resolve_hash_response.response); ++ ++ const int async_aborted = rc_client_end_async(client, &load_state->async_handle); ++ if (async_aborted) { ++ if (async_aborted != RC_CLIENT_ASYNC_DESTROYED) { ++ RC_CLIENT_LOG_VERBOSE(client, "Media change aborted"); ++ /* if lookup succeeded, still capture the new hash */ ++ if (result == RC_OK) ++ load_state->hash->game_id = resolve_hash_response.game_id; ++ } ++ } ++ else if (client->game != load_state->game) { ++ /* loaded game changed. return success regardless of result */ ++ load_state->callback(RC_ABORTED, "The requested game is no longer active", client, load_state->callback_userdata); ++ } ++ else if (error_message) { ++ load_state->callback(result, error_message, client, load_state->callback_userdata); ++ } ++ else { ++ load_state->hash->game_id = resolve_hash_response.game_id; ++ ++ if (resolve_hash_response.game_id != 0) { ++ RC_CLIENT_LOG_INFO_FORMATTED(client, "Identified game: %u (%s)", load_state->hash->game_id, load_state->hash->hash); ++ } ++ ++ rc_client_change_media_internal(client, load_state->hash, load_state->callback, load_state->callback_userdata); ++ } ++ ++ free(load_state); ++ rc_api_destroy_resolve_hash_response(&resolve_hash_response); ++} ++ ++static rc_client_async_handle_t* rc_client_begin_change_media_internal(rc_client_t* client, ++ rc_client_game_info_t* game, rc_client_game_hash_t* game_hash, rc_client_callback_t callback, void* callback_userdata) ++{ ++ rc_client_load_state_t* callback_data; ++ rc_client_async_handle_t* async_handle; ++ rc_api_resolve_hash_request_t resolve_hash_request; ++ rc_api_request_t request; ++ int result; ++ ++ if (game_hash->game_id != RC_CLIENT_UNKNOWN_GAME_ID || /* previously looked up */ ++ game_hash->hash[0] == '[') { /* internal use - don't try to look up */ ++ rc_client_change_media_internal(client, game_hash, callback, callback_userdata); ++ return NULL; ++ } ++ ++ /* call the server to make sure the hash is valid for the loaded game */ ++ memset(&resolve_hash_request, 0, sizeof(resolve_hash_request)); ++ resolve_hash_request.game_hash = game_hash->hash; ++ ++ result = rc_api_init_resolve_hash_request_hosted(&request, &resolve_hash_request, &client->state.host); ++ if (result != RC_OK) { ++ callback(result, rc_error_str(result), client, callback_userdata); ++ return NULL; ++ } ++ ++ callback_data = (rc_client_load_state_t*)calloc(1, sizeof(rc_client_load_state_t)); ++ if (!callback_data) { ++ callback(RC_OUT_OF_MEMORY, rc_error_str(RC_OUT_OF_MEMORY), client, callback_userdata); ++ return NULL; ++ } ++ ++ callback_data->callback = callback; ++ callback_data->callback_userdata = callback_userdata; ++ callback_data->client = client; ++ callback_data->hash = game_hash; ++ callback_data->game = game; ++ ++ async_handle = &callback_data->async_handle; ++ rc_client_begin_async(client, async_handle); ++ client->callbacks.server_call(&request, rc_client_identify_changed_media_callback, callback_data, client); ++ ++ rc_api_destroy_request(&request); ++ ++ /* if handle is no longer valid, the async operation completed synchronously */ ++ return rc_client_async_handle_valid(client, async_handle) ? async_handle : NULL; ++} ++ ++static rc_client_game_info_t* rc_client_check_pending_media(rc_client_t* client, const rc_client_pending_media_t* media) ++{ ++ rc_client_game_info_t* game; ++ rc_client_pending_media_t* pending_media = NULL; ++ ++ rc_mutex_lock(&client->state.mutex); ++ if (client->state.load) { ++ game = client->state.load->game; ++ if (!game || game->public_.console_id == 0) { ++ /* still waiting for game data */ ++ pending_media = client->state.load->pending_media; ++ if (pending_media) ++ rc_client_free_pending_media(pending_media); ++ ++ pending_media = (rc_client_pending_media_t*)malloc(sizeof(*pending_media)); ++ if (!pending_media) { ++ rc_mutex_unlock(&client->state.mutex); ++ media->callback(RC_OUT_OF_MEMORY, rc_error_str(RC_OUT_OF_MEMORY), client, media->callback_userdata); ++ return NULL; ++ } ++ ++ memcpy(pending_media, media, sizeof(*pending_media)); ++ if (media->hash) ++ pending_media->hash = strdup(media->hash); ++ ++#ifdef RC_CLIENT_SUPPORTS_HASH ++ if (media->file_path) ++ pending_media->file_path = strdup(media->file_path); ++ ++ if (media->data && media->data_size) { ++ pending_media->data = (uint8_t*)malloc(media->data_size); ++ if (!pending_media->data) { ++ rc_mutex_unlock(&client->state.mutex); ++ media->callback(RC_OUT_OF_MEMORY, rc_error_str(RC_OUT_OF_MEMORY), client, media->callback_userdata); ++ return NULL; ++ } ++ memcpy(pending_media->data, media->data, media->data_size); ++ } else { ++ pending_media->data = NULL; ++ } ++#endif ++ ++ client->state.load->pending_media = pending_media; ++ } ++ } ++ else { ++ game = client->game; ++ } ++ rc_mutex_unlock(&client->state.mutex); ++ ++ if (!game) { ++ media->callback(RC_NO_GAME_LOADED, rc_error_str(RC_NO_GAME_LOADED), client, media->callback_userdata); ++ return NULL; ++ } ++ ++ /* still waiting for game data - don't call callback - it's queued */ ++ if (pending_media) ++ return NULL; ++ ++ return game; ++} ++ ++#ifdef RC_CLIENT_SUPPORTS_HASH ++ ++rc_client_async_handle_t* rc_client_begin_identify_and_change_media(rc_client_t* client, const char* file_path, ++ const uint8_t* data, size_t data_size, rc_client_callback_t callback, void* callback_userdata) ++{ ++ rc_client_pending_media_t media; ++ rc_client_game_hash_t* game_hash = NULL; ++ rc_client_game_info_t* game; ++ rc_client_media_hash_t* media_hash; ++ uint32_t path_djb2; ++ ++ if (!client) { ++ callback(RC_INVALID_STATE, "client is required", client, callback_userdata); ++ return NULL; ++ } ++ ++ if (!data && !file_path) { ++ callback(RC_INVALID_STATE, "either data or file_path is required", client, callback_userdata); ++ return NULL; ++ } ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && !client->state.external_client->begin_change_media) { ++ if (client->state.external_client->begin_identify_and_change_media) ++ return client->state.external_client->begin_identify_and_change_media(client, file_path, data, data_size, callback, callback_userdata); ++ } ++#endif ++ ++ memset(&media, 0, sizeof(media)); ++ media.file_path = file_path; ++ media.data = (uint8_t*)data; ++ media.data_size = data_size; ++ media.callback = callback; ++ media.callback_userdata = callback_userdata; ++ ++ game = rc_client_check_pending_media(client, &media); ++ if (game == NULL) ++ return NULL; ++ ++ /* check to see if we've already hashed this file */ ++ path_djb2 = rc_djb2(file_path); ++ rc_mutex_lock(&client->state.mutex); ++ for (media_hash = game->media_hash; media_hash; media_hash = media_hash->next) { ++ if (media_hash->path_djb2 == path_djb2) { ++ game_hash = media_hash->game_hash; ++ break; ++ } ++ } ++ rc_mutex_unlock(&client->state.mutex); ++ ++ if (!game_hash) { ++ char hash[33]; ++ int result; ++ ++ if (data != NULL) ++ result = rc_hash_generate_from_buffer(hash, game->public_.console_id, data, data_size); ++ else ++ result = rc_hash_generate_from_file(hash, game->public_.console_id, file_path); ++ ++ if (!result) { ++ /* when changing discs, if the disc is not supported by the system, allow it. this is ++ * primarily for games that support user-provided audio CDs, but does allow using discs ++ * from other systems for games that leverage user-provided discs. */ ++ strcpy_s(hash, sizeof(hash), "[NO HASH]"); ++ } ++ ++ game_hash = rc_client_find_game_hash(client, hash); ++ ++ media_hash = (rc_client_media_hash_t*)rc_buffer_alloc(&game->buffer, sizeof(*media_hash)); ++ media_hash->game_hash = game_hash; ++ media_hash->path_djb2 = path_djb2; ++ ++ rc_mutex_lock(&client->state.mutex); ++ media_hash->next = game->media_hash; ++ game->media_hash = media_hash; ++ rc_mutex_unlock(&client->state.mutex); ++ ++ if (!result) { ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->begin_change_media) ++ return client->state.external_client->begin_change_media(client, game_hash->hash, callback, callback_userdata); ++#endif ++ ++ rc_client_change_media_internal(client, game_hash, callback, callback_userdata); ++ return NULL; ++ } ++ } ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client) { ++ if (client->state.external_client->add_game_hash) ++ client->state.external_client->add_game_hash(game_hash->hash, game_hash->game_id); ++ if (client->state.external_client->begin_change_media) ++ return client->state.external_client->begin_change_media(client, game_hash->hash, callback, callback_userdata); ++ } ++#endif ++ ++ return rc_client_begin_change_media_internal(client, game, game_hash, callback, callback_userdata); ++} ++ ++#endif /* RC_CLIENT_SUPPORTS_HASH */ ++ ++rc_client_async_handle_t* rc_client_begin_change_media(rc_client_t* client, const char* hash, ++ rc_client_callback_t callback, void* callback_userdata) ++{ ++ rc_client_pending_media_t media; ++ rc_client_game_hash_t* game_hash; ++ rc_client_game_info_t* game; ++ ++ if (!client) { ++ callback(RC_INVALID_STATE, "client is required", client, callback_userdata); ++ return NULL; ++ } ++ ++ if (!hash || !hash[0]) { ++ callback(RC_INVALID_STATE, "hash is required", client, callback_userdata); ++ return NULL; ++ } ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->begin_change_media) { ++ return client->state.external_client->begin_change_media(client, hash, callback, callback_userdata); ++ } ++#endif ++ ++ memset(&media, 0, sizeof(media)); ++ media.hash = hash; ++ media.callback = callback; ++ media.callback_userdata = callback_userdata; ++ ++ game = rc_client_check_pending_media(client, &media); ++ if (game == NULL) ++ return NULL; ++ ++ /* check to see if we've already hashed this file. */ ++ game_hash = rc_client_find_game_hash(client, hash); ++ return rc_client_begin_change_media_internal(client, game, game_hash, callback, callback_userdata); ++} ++ ++const rc_client_game_t* rc_client_get_game_info(const rc_client_t* client) ++{ ++ if (!client) ++ return NULL; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client) { ++ if (client->state.external_client->get_game_info_v3) ++ return client->state.external_client->get_game_info_v3(); ++ ++ if (client->state.external_client->get_game_info) ++ return rc_client_external_convert_v1_game(client, client->state.external_client->get_game_info()); ++ } ++#endif ++ ++ return client->game ? &client->game->public_ : NULL; ++} ++ ++int rc_client_game_get_image_url(const rc_client_game_t* game, char buffer[], size_t buffer_size) ++{ ++ if (!game) ++ return RC_INVALID_STATE; ++ ++ if (game->badge_url) { ++ snprintf(buffer, buffer_size, "%s", game->badge_url); ++ return RC_OK; ++ } ++ ++ return rc_client_get_image_url(buffer, buffer_size, RC_IMAGE_TYPE_GAME, game->badge_name); ++} ++ ++/* ===== Subsets ===== */ ++ ++const rc_client_subset_t* rc_client_get_subset_info(rc_client_t* client, uint32_t subset_id) ++{ ++ rc_client_subset_info_t* subset; ++ ++ if (!client) ++ return NULL; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client) { ++ if (client->state.external_client->get_subset_info_v3) ++ return client->state.external_client->get_subset_info_v3(subset_id); ++ ++ if (client->state.external_client->get_subset_info) ++ return rc_client_external_convert_v1_subset(client, client->state.external_client->get_subset_info(subset_id)); ++ } ++#endif ++ ++ if (!client->game) ++ return NULL; ++ ++ for (subset = client->game->subsets; subset; subset = subset->next) { ++ if (subset->public_.id == subset_id) ++ return &subset->public_; ++ } ++ ++ return NULL; ++} ++ ++rc_client_subset_list_t* rc_client_create_subset_list(rc_client_t* client) ++{ ++ rc_client_subset_list_info_t* list; ++ const rc_client_subset_info_t* subset; ++ const rc_client_subset_t** subset_ptr; ++ const uint32_t list_size = RC_ALIGN(sizeof(*list)); ++ uint32_t num_subsets = 0; ++ ++ if (!client) ++ return (rc_client_subset_list_t*)calloc(1, list_size); ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->create_subset_list) ++ return (rc_client_subset_list_t*)client->state.external_client->create_subset_list(); ++#endif ++ ++ if (!client->game) ++ return (rc_client_subset_list_t*)calloc(1, list_size); ++ ++ rc_mutex_lock(&client->state.mutex); ++ ++ subset = client->game->subsets; ++ for (; subset; subset = subset->next) { ++ if (subset->active) ++ num_subsets++; ++ } ++ ++ list = (rc_client_subset_list_info_t*)malloc(list_size + num_subsets * sizeof(rc_client_subset_t*)); ++ list->public_.subsets = subset_ptr = (const rc_client_subset_t**)((uint8_t*)list + list_size); ++ ++ subset = client->game->subsets; ++ for (; subset; subset = subset->next) { ++ if (subset->active) ++ *subset_ptr++ = &subset->public_; ++ } ++ ++ rc_mutex_unlock(&client->state.mutex); ++ ++ list->destroy_func = NULL; ++ list->public_.num_subsets = (uint32_t)(subset_ptr - list->public_.subsets); ++ return &list->public_; ++} ++ ++void rc_client_destroy_subset_list(rc_client_subset_list_t* list) ++{ ++ rc_client_subset_list_info_t* info = (rc_client_subset_list_info_t*)list; ++ if (info->destroy_func) ++ info->destroy_func(info); ++ else ++ free(list); ++} ++ ++/* ===== Fetch Game Hashes ===== */ ++ ++typedef struct rc_client_fetch_hash_library_callback_data_t { ++ rc_client_t* client; ++ rc_client_fetch_hash_library_callback_t callback; ++ void* callback_userdata; ++ uint32_t console_id; ++ rc_client_async_handle_t async_handle; ++} rc_client_fetch_hash_library_callback_data_t; ++ ++static void rc_client_fetch_hash_library_callback(const rc_api_server_response_t* server_response, void* callback_data) ++{ ++ rc_client_fetch_hash_library_callback_data_t* hashlib_callback_data = ++ (rc_client_fetch_hash_library_callback_data_t*)callback_data; ++ rc_client_t* client = hashlib_callback_data->client; ++ rc_api_fetch_hash_library_response_t hashlib_response; ++ const char* error_message; ++ int result; ++ ++ result = rc_client_end_async(client, &hashlib_callback_data->async_handle); ++ if (result) { ++ if (result != RC_CLIENT_ASYNC_DESTROYED) ++ RC_CLIENT_LOG_VERBOSE(client, "Fetch hash library aborted"); ++ ++ free(hashlib_callback_data); ++ return; ++ } ++ ++ result = rc_api_process_fetch_hash_library_server_response(&hashlib_response, server_response); ++ error_message = ++ rc_client_server_error_message(&result, server_response->http_status_code, &hashlib_response.response); ++ if (error_message) { ++ RC_CLIENT_LOG_ERR_FORMATTED(client, "Fetch hash library for console %u failed: %s", ++ hashlib_callback_data->console_id, error_message); ++ hashlib_callback_data->callback(result, error_message, NULL, client, hashlib_callback_data->callback_userdata); ++ } else { ++ rc_client_hash_library_t* list; ++ const size_t list_size = sizeof(*list) + sizeof(rc_client_hash_library_entry_t) * hashlib_response.num_entries; ++ list = (rc_client_hash_library_t*)malloc(list_size); ++ if (!list) { ++ hashlib_callback_data->callback(RC_OUT_OF_MEMORY, rc_error_str(RC_OUT_OF_MEMORY), NULL, client, ++ hashlib_callback_data->callback_userdata); ++ } else { ++ rc_client_hash_library_entry_t* entry = list->entries = ++ (rc_client_hash_library_entry_t*)((uint8_t*)list + sizeof(*list)); ++ const rc_api_hash_library_entry_t* hlentry = hashlib_response.entries; ++ const rc_api_hash_library_entry_t* stop = hlentry + hashlib_response.num_entries; ++ ++ for (; hlentry < stop; ++hlentry, ++entry) { ++ snprintf(entry->hash, sizeof(entry->hash), "%s", hlentry->hash); ++ entry->game_id = hlentry->game_id; ++ } ++ ++ list->num_entries = hashlib_response.num_entries; ++ ++ hashlib_callback_data->callback(RC_OK, NULL, list, client, hashlib_callback_data->callback_userdata); ++ } ++ } ++ ++ rc_api_destroy_fetch_hash_library_response(&hashlib_response); ++ free(hashlib_callback_data); ++} ++ ++rc_client_async_handle_t* rc_client_begin_fetch_hash_library(rc_client_t* client, uint32_t console_id, ++ rc_client_fetch_hash_library_callback_t callback, ++ void* callback_userdata) ++{ ++ rc_api_fetch_hash_library_request_t api_params; ++ rc_client_fetch_hash_library_callback_data_t* callback_data; ++ rc_client_async_handle_t* async_handle; ++ rc_api_request_t request; ++ int result; ++ const char* error_message; ++ ++ if (!client) { ++ callback(RC_INVALID_STATE, "client is required", NULL, client, callback_userdata); ++ return NULL; ++ } ++ ++ api_params.console_id = console_id; ++ result = rc_api_init_fetch_hash_library_request_hosted(&request, &api_params, &client->state.host); ++ ++ if (result != RC_OK) { ++ error_message = rc_error_str(result); ++ callback(result, error_message, NULL, client, callback_userdata); ++ return NULL; ++ } ++ ++ callback_data = (rc_client_fetch_hash_library_callback_data_t*)calloc(1, sizeof(*callback_data)); ++ if (!callback_data) { ++ callback(RC_OUT_OF_MEMORY, rc_error_str(RC_OUT_OF_MEMORY), NULL, client, callback_userdata); ++ return NULL; ++ } ++ ++ callback_data->client = client; ++ callback_data->callback = callback; ++ callback_data->callback_userdata = callback_userdata; ++ callback_data->console_id = console_id; ++ ++ async_handle = &callback_data->async_handle; ++ rc_client_begin_async(client, async_handle); ++ client->callbacks.server_call(&request, rc_client_fetch_hash_library_callback, callback_data, client); ++ rc_api_destroy_request(&request); ++ ++ return rc_client_async_handle_valid(client, async_handle) ? async_handle : NULL; ++} ++ ++void rc_client_destroy_hash_library(rc_client_hash_library_t* list) ++{ ++ free(list); ++} ++ ++/* ===== Fetch Game Titles ===== */ ++ ++typedef struct rc_client_fetch_game_titles_callback_data_t { ++ rc_client_t* client; ++ rc_client_fetch_game_titles_callback_t callback; ++ void* callback_userdata; ++ rc_client_async_handle_t async_handle; ++} rc_client_fetch_game_titles_callback_data_t; ++ ++static void rc_client_fetch_game_titles_callback(const rc_api_server_response_t* server_response, void* callback_data) ++{ ++ rc_client_fetch_game_titles_callback_data_t* titles_callback_data = ++ (rc_client_fetch_game_titles_callback_data_t*)callback_data; ++ rc_client_t* client = titles_callback_data->client; ++ rc_api_fetch_game_titles_response_t titles_response; ++ const char* error_message; ++ int result; ++ ++ result = rc_client_end_async(client, &titles_callback_data->async_handle); ++ if (result) { ++ if (result != RC_CLIENT_ASYNC_DESTROYED) ++ RC_CLIENT_LOG_VERBOSE(client, "Fetch game titles aborted"); ++ ++ free(titles_callback_data); ++ return; ++ } ++ ++ result = rc_api_process_fetch_game_titles_server_response(&titles_response, server_response); ++ error_message = ++ rc_client_server_error_message(&result, server_response->http_status_code, &titles_response.response); ++ if (error_message) { ++ RC_CLIENT_LOG_ERR_FORMATTED(client, "Fetch game titles failed: %s", error_message); ++ titles_callback_data->callback(result, error_message, NULL, client, titles_callback_data->callback_userdata); ++ } else { ++ rc_client_game_title_list_t* list; ++ size_t strings_size = 0; ++ const rc_api_game_title_entry_t* src; ++ const rc_api_game_title_entry_t* stop; ++ size_t list_size; ++ ++ /* calculate string buffer size */ ++ for (src = titles_response.entries, stop = src + titles_response.num_entries; src < stop; ++src) { ++ if (src->title) ++ strings_size += strlen(src->title) + 1; ++ } ++ ++ list_size = sizeof(*list) + sizeof(rc_client_game_title_entry_t) * titles_response.num_entries + strings_size; ++ list = (rc_client_game_title_list_t*)malloc(list_size); ++ if (!list) { ++ titles_callback_data->callback(RC_OUT_OF_MEMORY, rc_error_str(RC_OUT_OF_MEMORY), NULL, client, ++ titles_callback_data->callback_userdata); ++ } else { ++ rc_client_game_title_entry_t* entry = list->entries = ++ (rc_client_game_title_entry_t*)((uint8_t*)list + sizeof(*list)); ++ char* strings = (char*)((uint8_t*)list + sizeof(*list) + ++ sizeof(rc_client_game_title_entry_t) * titles_response.num_entries); ++ ++ for (src = titles_response.entries, stop = src + titles_response.num_entries; src < stop; ++src, ++entry) { ++ entry->game_id = src->id; ++ ++ if (src->title) { ++ const size_t len = strlen(src->title) + 1; ++ entry->title = strings; ++ memcpy(strings, src->title, len); ++ strings += len; ++ } else { ++ entry->title = NULL; ++ } ++ ++ if (src->image_name) ++ snprintf(entry->badge_name, sizeof(entry->badge_name), "%s", src->image_name); ++ else ++ entry->badge_name[0] = '\0'; ++ } ++ ++ list->num_entries = titles_response.num_entries; ++ ++ titles_callback_data->callback(RC_OK, NULL, list, client, titles_callback_data->callback_userdata); ++ } ++ } ++ ++ rc_api_destroy_fetch_game_titles_response(&titles_response); ++ free(titles_callback_data); ++} ++ ++rc_client_async_handle_t* rc_client_begin_fetch_game_titles(rc_client_t* client, const uint32_t* game_ids, ++ uint32_t num_game_ids, ++ rc_client_fetch_game_titles_callback_t callback, ++ void* callback_userdata) ++{ ++ rc_api_fetch_game_titles_request_t api_params; ++ rc_client_fetch_game_titles_callback_data_t* callback_data; ++ rc_client_async_handle_t* async_handle; ++ rc_api_request_t request; ++ int result; ++ const char* error_message; ++ ++ if (!client) { ++ callback(RC_INVALID_STATE, "client is required", NULL, client, callback_userdata); ++ return NULL; ++ } ++ ++ if (!game_ids || num_game_ids == 0) { ++ callback(RC_INVALID_STATE, "game_ids is required", NULL, client, callback_userdata); ++ return NULL; ++ } ++ ++ api_params.game_ids = game_ids; ++ api_params.num_game_ids = num_game_ids; ++ result = rc_api_init_fetch_game_titles_request_hosted(&request, &api_params, &client->state.host); ++ ++ if (result != RC_OK) { ++ error_message = rc_error_str(result); ++ callback(result, error_message, NULL, client, callback_userdata); ++ return NULL; ++ } ++ ++ callback_data = (rc_client_fetch_game_titles_callback_data_t*)calloc(1, sizeof(*callback_data)); ++ if (!callback_data) { ++ callback(RC_OUT_OF_MEMORY, rc_error_str(RC_OUT_OF_MEMORY), NULL, client, callback_userdata); ++ return NULL; ++ } ++ ++ callback_data->client = client; ++ callback_data->callback = callback; ++ callback_data->callback_userdata = callback_userdata; ++ ++ async_handle = &callback_data->async_handle; ++ rc_client_begin_async(client, async_handle); ++ client->callbacks.server_call(&request, rc_client_fetch_game_titles_callback, callback_data, client); ++ rc_api_destroy_request(&request); ++ ++ return rc_client_async_handle_valid(client, async_handle) ? async_handle : NULL; ++} ++ ++void rc_client_destroy_game_title_list(rc_client_game_title_list_t* list) ++{ ++ free(list); ++} ++ ++/* ===== Achievements ===== */ ++ ++static void rc_client_update_achievement_display_information(rc_client_t* client, rc_client_achievement_info_t* achievement, time_t recent_unlock_time) ++{ ++ uint8_t new_bucket = RC_CLIENT_ACHIEVEMENT_BUCKET_UNKNOWN; ++ uint32_t new_measured_value = 0; ++ ++ if (achievement->public_.bucket == RC_CLIENT_ACHIEVEMENT_BUCKET_UNSUPPORTED) ++ return; ++ ++ achievement->public_.measured_progress[0] = '\0'; ++ ++ if (achievement->public_.state == RC_CLIENT_ACHIEVEMENT_STATE_UNLOCKED) { ++ /* achievement unlocked */ ++ if (achievement->public_.unlock_time >= recent_unlock_time) { ++ new_bucket = RC_CLIENT_ACHIEVEMENT_BUCKET_RECENTLY_UNLOCKED; ++ } else { ++ new_bucket = RC_CLIENT_ACHIEVEMENT_BUCKET_UNLOCKED; ++ ++ if (client->state.disconnect && rc_client_is_award_achievement_pending(client, achievement->public_.id)) ++ new_bucket = RC_CLIENT_ACHIEVEMENT_BUCKET_UNSYNCED; ++ } ++ } ++ else { ++ /* active achievement */ ++ new_bucket = (achievement->public_.category == RC_CLIENT_ACHIEVEMENT_CATEGORY_UNOFFICIAL) ? ++ RC_CLIENT_ACHIEVEMENT_BUCKET_UNOFFICIAL : RC_CLIENT_ACHIEVEMENT_BUCKET_LOCKED; ++ ++ if (achievement->trigger) { ++ if (achievement->trigger->measured_target) { ++ if (achievement->trigger->measured_value == RC_MEASURED_UNKNOWN) { ++ /* value hasn't been initialized yet, leave progress string empty */ ++ } ++ else if (achievement->trigger->measured_value == 0) { ++ /* value is 0, leave progress string empty. update progress to 0.0 */ ++ achievement->public_.measured_percent = 0.0; ++ } ++ else { ++ /* clamp measured value at target (can't get more than 100%) */ ++ new_measured_value = (achievement->trigger->measured_value > achievement->trigger->measured_target) ? ++ achievement->trigger->measured_target : achievement->trigger->measured_value; ++ ++ achievement->public_.measured_percent = ((float)new_measured_value * 100) / (float)achievement->trigger->measured_target; ++ ++ if (!achievement->trigger->measured_as_percent) { ++ char* ptr = achievement->public_.measured_progress; ++ const int buffer_size = (int)sizeof(achievement->public_.measured_progress); ++ const int chars = rc_format_value(ptr, buffer_size, (int32_t)new_measured_value, RC_FORMAT_UNSIGNED_VALUE); ++ ptr[chars] = '/'; ++ rc_format_value(ptr + chars + 1, buffer_size - chars - 1, (int32_t)achievement->trigger->measured_target, RC_FORMAT_UNSIGNED_VALUE); ++ } ++ else if (achievement->public_.measured_percent >= 1.0) { ++ snprintf(achievement->public_.measured_progress, sizeof(achievement->public_.measured_progress), ++ "%lu%%", (unsigned long)achievement->public_.measured_percent); ++ } ++ } ++ } ++ ++ if (achievement->trigger->state == RC_TRIGGER_STATE_PRIMED) ++ new_bucket = RC_CLIENT_ACHIEVEMENT_BUCKET_ACTIVE_CHALLENGE; ++ else if (achievement->public_.measured_percent >= 80.0) ++ new_bucket = RC_CLIENT_ACHIEVEMENT_BUCKET_ALMOST_THERE; ++ } ++ } ++ ++ achievement->public_.bucket = new_bucket; ++} ++ ++static const char* rc_client_get_achievement_bucket_label(uint8_t bucket_type) ++{ ++ switch (bucket_type) { ++ case RC_CLIENT_ACHIEVEMENT_BUCKET_LOCKED: return "Locked"; ++ case RC_CLIENT_ACHIEVEMENT_BUCKET_UNLOCKED: return "Unlocked"; ++ case RC_CLIENT_ACHIEVEMENT_BUCKET_UNSUPPORTED: return "Unsupported"; ++ case RC_CLIENT_ACHIEVEMENT_BUCKET_UNOFFICIAL: return "Unofficial"; ++ case RC_CLIENT_ACHIEVEMENT_BUCKET_RECENTLY_UNLOCKED: return "Recently Unlocked"; ++ case RC_CLIENT_ACHIEVEMENT_BUCKET_ACTIVE_CHALLENGE: return "Active Challenges"; ++ case RC_CLIENT_ACHIEVEMENT_BUCKET_ALMOST_THERE: return "Almost There"; ++ case RC_CLIENT_ACHIEVEMENT_BUCKET_UNSYNCED: return "Unlocks Not Synced to Server"; ++ default: return "Unknown"; ++ } ++} ++ ++static const char* rc_client_get_subset_achievement_bucket_label(uint8_t bucket_type, rc_client_game_info_t* game, rc_client_subset_info_t* subset) ++{ ++ const char** ptr; ++ const char* label; ++ char* new_label; ++ size_t new_label_len; ++ ++ switch (bucket_type) { ++ case RC_CLIENT_ACHIEVEMENT_BUCKET_LOCKED: ptr = &subset->locked_label; break; ++ case RC_CLIENT_ACHIEVEMENT_BUCKET_UNLOCKED: ptr = &subset->unlocked_label; break; ++ case RC_CLIENT_ACHIEVEMENT_BUCKET_UNSUPPORTED: ptr = &subset->unsupported_label; break; ++ case RC_CLIENT_ACHIEVEMENT_BUCKET_UNOFFICIAL: ptr = &subset->unofficial_label; break; ++ default: return rc_client_get_achievement_bucket_label(bucket_type); ++ } ++ ++ if (*ptr) ++ return *ptr; ++ ++ label = rc_client_get_achievement_bucket_label(bucket_type); ++ new_label_len = strlen(subset->public_.title) + strlen(label) + 4; ++ new_label = (char*)rc_buffer_alloc(&game->buffer, new_label_len); ++ snprintf(new_label, new_label_len, "%s - %s", subset->public_.title, label); ++ ++ *ptr = new_label; ++ return new_label; ++} ++ ++static int rc_client_compare_achievement_unlock_times(const void* a, const void* b) ++{ ++ const rc_client_achievement_t* unlock_a = *(const rc_client_achievement_t**)a; ++ const rc_client_achievement_t* unlock_b = *(const rc_client_achievement_t**)b; ++ if (unlock_b->unlock_time == unlock_a->unlock_time) ++ return 0; ++ return (unlock_b->unlock_time < unlock_a->unlock_time) ? -1 : 1; ++} ++ ++static int rc_client_compare_achievement_progress(const void* a, const void* b) ++{ ++ const rc_client_achievement_t* unlock_a = *(const rc_client_achievement_t**)a; ++ const rc_client_achievement_t* unlock_b = *(const rc_client_achievement_t**)b; ++ if (unlock_b->measured_percent == unlock_a->measured_percent) { ++ if (unlock_a->id == unlock_b->id) ++ return 0; ++ return (unlock_a->id < unlock_b->id) ? -1 : 1; ++ } ++ return (unlock_b->measured_percent < unlock_a->measured_percent) ? -1 : 1; ++} ++ ++static uint8_t rc_client_map_bucket(uint8_t bucket, int grouping) ++{ ++ if (grouping == RC_CLIENT_ACHIEVEMENT_LIST_GROUPING_LOCK_STATE) { ++ switch (bucket) { ++ case RC_CLIENT_ACHIEVEMENT_BUCKET_RECENTLY_UNLOCKED: ++ case RC_CLIENT_ACHIEVEMENT_BUCKET_UNSYNCED: ++ return RC_CLIENT_ACHIEVEMENT_BUCKET_UNLOCKED; ++ ++ case RC_CLIENT_ACHIEVEMENT_BUCKET_ACTIVE_CHALLENGE: ++ case RC_CLIENT_ACHIEVEMENT_BUCKET_ALMOST_THERE: ++ return RC_CLIENT_ACHIEVEMENT_BUCKET_LOCKED; ++ ++ default: ++ return bucket; ++ } ++ } ++ ++ return bucket; ++} ++ ++rc_client_achievement_list_t* rc_client_create_achievement_list(rc_client_t* client, int category, int grouping) ++{ ++ rc_client_achievement_info_t* achievement; ++ rc_client_achievement_info_t* stop; ++ const rc_client_achievement_t** bucket_achievements; ++ const rc_client_achievement_t** achievement_ptr; ++ rc_client_achievement_bucket_t* bucket_ptr; ++ rc_client_achievement_list_info_t* list; ++ rc_client_subset_info_t* subset; ++ const uint32_t list_size = RC_ALIGN(sizeof(*list)); ++ uint32_t bucket_counts[NUM_RC_CLIENT_ACHIEVEMENT_BUCKETS]; ++ uint32_t num_buckets; ++ uint32_t num_achievements; ++ size_t buckets_size; ++ uint8_t bucket_type; ++ uint32_t num_subsets = 0; ++ uint32_t i, j; ++ const uint8_t shared_bucket_order[] = { ++ RC_CLIENT_ACHIEVEMENT_BUCKET_ACTIVE_CHALLENGE, ++ RC_CLIENT_ACHIEVEMENT_BUCKET_RECENTLY_UNLOCKED, ++ RC_CLIENT_ACHIEVEMENT_BUCKET_ALMOST_THERE, ++ RC_CLIENT_ACHIEVEMENT_BUCKET_UNSYNCED, ++ }; ++ const uint8_t subset_bucket_order[] = { ++ RC_CLIENT_ACHIEVEMENT_BUCKET_LOCKED, ++ RC_CLIENT_ACHIEVEMENT_BUCKET_UNOFFICIAL, ++ RC_CLIENT_ACHIEVEMENT_BUCKET_UNSUPPORTED, ++ RC_CLIENT_ACHIEVEMENT_BUCKET_UNLOCKED ++ }; ++ const time_t recent_unlock_time = time(NULL) - RC_CLIENT_RECENT_UNLOCK_DELAY_SECONDS; ++ ++ if (!client) ++ return (rc_client_achievement_list_t*)calloc(1, sizeof(rc_client_achievement_list_info_t)); ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client) { ++ if (client->state.external_client->create_achievement_list_v3) ++ return (rc_client_achievement_list_t*)client->state.external_client->create_achievement_list_v3(category, grouping); ++ ++ if (client->state.external_client->create_achievement_list) ++ return rc_client_external_convert_v1_achievement_list(client, ++ (rc_client_achievement_list_t*)client->state.external_client->create_achievement_list(category, grouping)); ++ } ++#endif ++ ++ if (!client->game) ++ return (rc_client_achievement_list_t*)calloc(1, sizeof(rc_client_achievement_list_info_t)); ++ ++ memset(&bucket_counts, 0, sizeof(bucket_counts)); ++ ++ rc_mutex_lock(&client->state.mutex); ++ ++ subset = client->game->subsets; ++ for (; subset; subset = subset->next) { ++ if (!subset->active) ++ continue; ++ ++ num_subsets++; ++ achievement = subset->achievements; ++ stop = achievement + subset->public_.num_achievements; ++ for (; achievement < stop; ++achievement) { ++ if (achievement->public_.category & category) { ++ rc_client_update_achievement_display_information(client, achievement, recent_unlock_time); ++ bucket_counts[rc_client_map_bucket(achievement->public_.bucket, grouping)]++; ++ } ++ } ++ } ++ ++ num_buckets = 0; ++ num_achievements = 0; ++ for (i = 0; i < sizeof(bucket_counts) / sizeof(bucket_counts[0]); ++i) { ++ if (bucket_counts[i]) { ++ int needs_split = 0; ++ ++ num_achievements += bucket_counts[i]; ++ ++ if (num_subsets > 1) { ++ for (j = 0; j < sizeof(subset_bucket_order) / sizeof(subset_bucket_order[0]); ++j) { ++ if (subset_bucket_order[j] == i) { ++ needs_split = 1; ++ break; ++ } ++ } ++ } ++ ++ if (!needs_split) { ++ ++num_buckets; ++ continue; ++ } ++ ++ subset = client->game->subsets; ++ for (; subset; subset = subset->next) { ++ if (!subset->active) ++ continue; ++ ++ achievement = subset->achievements; ++ stop = achievement + subset->public_.num_achievements; ++ for (; achievement < stop; ++achievement) { ++ if (achievement->public_.category & category) { ++ if (rc_client_map_bucket(achievement->public_.bucket, grouping) == i) { ++ ++num_buckets; ++ break; ++ } ++ } ++ } ++ } ++ } ++ } ++ ++ buckets_size = RC_ALIGN(num_buckets * sizeof(rc_client_achievement_bucket_t)); ++ ++ list = (rc_client_achievement_list_info_t*)malloc(list_size + buckets_size + num_achievements * sizeof(rc_client_achievement_t*)); ++ list->public_.buckets = bucket_ptr = (rc_client_achievement_bucket_t*)((uint8_t*)list + list_size); ++ achievement_ptr = (const rc_client_achievement_t**)((uint8_t*)bucket_ptr + buckets_size); ++ ++ if (grouping == RC_CLIENT_ACHIEVEMENT_LIST_GROUPING_PROGRESS) { ++ for (i = 0; i < sizeof(shared_bucket_order) / sizeof(shared_bucket_order[0]); ++i) { ++ bucket_type = shared_bucket_order[i]; ++ if (!bucket_counts[bucket_type]) ++ continue; ++ ++ bucket_achievements = achievement_ptr; ++ for (subset = client->game->subsets; subset; subset = subset->next) { ++ if (!subset->active) ++ continue; ++ ++ achievement = subset->achievements; ++ stop = achievement + subset->public_.num_achievements; ++ for (; achievement < stop; ++achievement) { ++ if (achievement->public_.category & category && ++ rc_client_map_bucket(achievement->public_.bucket, grouping) == bucket_type) { ++ *achievement_ptr++ = &achievement->public_; ++ } ++ } ++ } ++ ++ if (achievement_ptr > bucket_achievements) { ++ bucket_ptr->achievements = bucket_achievements; ++ bucket_ptr->num_achievements = (uint32_t)(achievement_ptr - bucket_achievements); ++ bucket_ptr->subset_id = 0; ++ bucket_ptr->label = rc_client_get_achievement_bucket_label(bucket_type); ++ bucket_ptr->bucket_type = bucket_type; ++ ++ if (bucket_type == RC_CLIENT_ACHIEVEMENT_BUCKET_RECENTLY_UNLOCKED) ++ qsort((void*)bucket_ptr->achievements, bucket_ptr->num_achievements, sizeof(rc_client_achievement_t*), rc_client_compare_achievement_unlock_times); ++ else if (bucket_type == RC_CLIENT_ACHIEVEMENT_BUCKET_ALMOST_THERE) ++ qsort((void*)bucket_ptr->achievements, bucket_ptr->num_achievements, sizeof(rc_client_achievement_t*), rc_client_compare_achievement_progress); ++ ++ ++bucket_ptr; ++ } ++ } ++ } ++ ++ for (subset = client->game->subsets; subset; subset = subset->next) { ++ if (!subset->active) ++ continue; ++ ++ for (i = 0; i < sizeof(subset_bucket_order) / sizeof(subset_bucket_order[0]); ++i) { ++ bucket_type = subset_bucket_order[i]; ++ if (!bucket_counts[bucket_type]) ++ continue; ++ ++ bucket_achievements = achievement_ptr; ++ ++ achievement = subset->achievements; ++ stop = achievement + subset->public_.num_achievements; ++ for (; achievement < stop; ++achievement) { ++ if (achievement->public_.category & category && ++ rc_client_map_bucket(achievement->public_.bucket, grouping) == bucket_type) { ++ *achievement_ptr++ = &achievement->public_; ++ } ++ } ++ ++ if (achievement_ptr > bucket_achievements) { ++ bucket_ptr->achievements = bucket_achievements; ++ bucket_ptr->num_achievements = (uint32_t)(achievement_ptr - bucket_achievements); ++ bucket_ptr->subset_id = (num_subsets > 1) ? subset->public_.id : 0; ++ bucket_ptr->bucket_type = bucket_type; ++ ++ if (num_subsets > 1) ++ bucket_ptr->label = rc_client_get_subset_achievement_bucket_label(bucket_type, client->game, subset); ++ else ++ bucket_ptr->label = rc_client_get_achievement_bucket_label(bucket_type); ++ ++ ++bucket_ptr; ++ } ++ } ++ } ++ ++ rc_mutex_unlock(&client->state.mutex); ++ ++ list->destroy_func = NULL; ++ list->public_.num_buckets = (uint32_t)(bucket_ptr - list->public_.buckets); ++ return &list->public_; ++} ++ ++void rc_client_destroy_achievement_list(rc_client_achievement_list_t* list) ++{ ++ rc_client_achievement_list_info_t* info = (rc_client_achievement_list_info_t*)list; ++ if (info->destroy_func) ++ info->destroy_func(info); ++ else ++ free(list); ++} ++ ++int rc_client_has_achievements(rc_client_t* client) ++{ ++ rc_client_subset_info_t* subset; ++ int result; ++ ++ if (!client) ++ return 0; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->has_achievements) ++ return client->state.external_client->has_achievements(); ++#endif ++ ++ if (!client->game) ++ return 0; ++ ++ rc_mutex_lock(&client->state.mutex); ++ ++ subset = client->game->subsets; ++ result = 0; ++ for (; subset; subset = subset->next) ++ { ++ if (!subset->active) ++ continue; ++ ++ if (subset->public_.num_achievements > 0) { ++ result = 1; ++ break; ++ } ++ } ++ ++ rc_mutex_unlock(&client->state.mutex); ++ ++ return result; ++} ++ ++static const rc_client_achievement_t* rc_client_subset_get_achievement_info( ++ rc_client_t* client, rc_client_subset_info_t* subset, uint32_t id) ++{ ++ rc_client_achievement_info_t* achievement = subset->achievements; ++ rc_client_achievement_info_t* stop = achievement + subset->public_.num_achievements; ++ ++ for (; achievement < stop; ++achievement) { ++ if (achievement->public_.id == id) { ++ const time_t recent_unlock_time = time(NULL) - RC_CLIENT_RECENT_UNLOCK_DELAY_SECONDS; ++ rc_mutex_lock((rc_mutex_t*)(&client->state.mutex)); ++ rc_client_update_achievement_display_information(client, achievement, recent_unlock_time); ++ rc_mutex_unlock((rc_mutex_t*)(&client->state.mutex)); ++ return &achievement->public_; ++ } ++ } ++ ++ return NULL; ++} ++ ++const rc_client_achievement_t* rc_client_get_achievement_info(rc_client_t* client, uint32_t id) ++{ ++ rc_client_subset_info_t* subset; ++ ++ if (!client) ++ return NULL; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client) { ++ if (client->state.external_client->get_achievement_info_v3) ++ return client->state.external_client->get_achievement_info_v3(id); ++ ++ if (client->state.external_client->get_achievement_info) ++ return rc_client_external_convert_v1_achievement(client, client->state.external_client->get_achievement_info(id)); ++ } ++#endif ++ ++ if (!client->game) ++ return NULL; ++ ++ for (subset = client->game->subsets; subset; subset = subset->next) { ++ const rc_client_achievement_t* achievement = rc_client_subset_get_achievement_info(client, subset, id); ++ if (achievement != NULL) ++ return achievement; ++ } ++ ++ return NULL; ++} ++ ++int rc_client_achievement_get_image_url(const rc_client_achievement_t* achievement, int state, char buffer[], size_t buffer_size) ++{ ++ const int image_type = (state == RC_CLIENT_ACHIEVEMENT_STATE_UNLOCKED) ? ++ RC_IMAGE_TYPE_ACHIEVEMENT : RC_IMAGE_TYPE_ACHIEVEMENT_LOCKED; ++ ++ if (!achievement || !achievement->badge_name[0]) ++ return rc_client_get_image_url(buffer, buffer_size, image_type, "00000"); ++ ++ if (image_type == RC_IMAGE_TYPE_ACHIEVEMENT && achievement->badge_url) { ++ snprintf(buffer, buffer_size, "%s", achievement->badge_url); ++ return RC_OK; ++ } ++ ++ if (image_type == RC_IMAGE_TYPE_ACHIEVEMENT_LOCKED && achievement->badge_locked_url) { ++ snprintf(buffer, buffer_size, "%s", achievement->badge_locked_url); ++ return RC_OK; ++ } ++ ++ return rc_client_get_image_url(buffer, buffer_size, image_type, achievement->badge_name); ++} ++ ++typedef struct rc_client_award_achievement_callback_data_t ++{ ++ uint32_t id; ++ uint32_t retry_count; ++ uint8_t hardcore; ++ const char* game_hash; ++ rc_clock_t unlock_time; ++ rc_client_t* client; ++ rc_client_scheduled_callback_data_t* scheduled_callback_data; ++} rc_client_award_achievement_callback_data_t; ++ ++static int rc_client_is_award_achievement_pending(const rc_client_t* client, uint32_t achievement_id) ++{ ++ /* assume lock already held */ ++ rc_client_scheduled_callback_data_t* scheduled_callback = client->state.scheduled_callbacks; ++ for (; scheduled_callback; scheduled_callback = scheduled_callback->next) ++ { ++ if (scheduled_callback->callback == rc_client_award_achievement_retry) ++ { ++ rc_client_award_achievement_callback_data_t* ach_data = ++ (rc_client_award_achievement_callback_data_t*)scheduled_callback->data; ++ if (ach_data->id == achievement_id) ++ return 1; ++ } ++ } ++ ++ return 0; ++} ++ ++static void rc_client_award_achievement_server_call(rc_client_award_achievement_callback_data_t* ach_data); ++ ++static void rc_client_award_achievement_retry(rc_client_scheduled_callback_data_t* callback_data, rc_client_t* client, rc_clock_t now) ++{ ++ rc_client_award_achievement_callback_data_t* ach_data = ++ (rc_client_award_achievement_callback_data_t*)callback_data->data; ++ ++ (void)client; ++ (void)now; ++ ++ rc_client_award_achievement_server_call(ach_data); ++} ++ ++static void rc_client_award_achievement_callback(const rc_api_server_response_t* server_response, void* callback_data) ++{ ++ rc_client_award_achievement_callback_data_t* ach_data = ++ (rc_client_award_achievement_callback_data_t*)callback_data; ++ rc_api_award_achievement_response_t award_achievement_response; ++ ++ int result = rc_api_process_award_achievement_server_response(&award_achievement_response, server_response); ++ const char* error_message = rc_client_server_error_message(&result, server_response->http_status_code, &award_achievement_response.response); ++ ++ if (error_message) { ++ if (award_achievement_response.response.error_message && !rc_client_should_retry(server_response)) { ++ /* actual error from server */ ++ RC_CLIENT_LOG_ERR_FORMATTED(ach_data->client, "Error awarding achievement %u: %s", ach_data->id, error_message); ++ rc_client_raise_server_error_event(ach_data->client, "award_achievement", ach_data->id, result, award_achievement_response.response.error_message); ++ } ++ else if (ach_data->retry_count++ == 0) { ++ /* first retry is immediate */ ++ RC_CLIENT_LOG_ERR_FORMATTED(ach_data->client, "Error awarding achievement %u: %s, retrying immediately", ach_data->id, error_message); ++ rc_client_award_achievement_server_call(ach_data); ++ return; ++ } ++ else { ++ /* double wait time between each attempt until we hit a maximum delay of two minutes */ ++ /* 1s -> 2s -> 4s -> 8s -> 16s -> 32s -> 64s -> 120s -> 120s -> 120s ...*/ ++ const uint32_t delay = (ach_data->retry_count > 8) ? 120 : (1 << (ach_data->retry_count - 2)); ++ RC_CLIENT_LOG_ERR_FORMATTED(ach_data->client, "Error awarding achievement %u: %s, retrying in %u seconds", ach_data->id, error_message, delay); ++ ++ if (!ach_data->scheduled_callback_data) { ++ ach_data->scheduled_callback_data = (rc_client_scheduled_callback_data_t*)calloc(1, sizeof(*ach_data->scheduled_callback_data)); ++ if (!ach_data->scheduled_callback_data) { ++ RC_CLIENT_LOG_ERR_FORMATTED(ach_data->client, "Failed to allocate scheduled callback data for reattempt to unlock achievement %u", ach_data->id); ++ rc_client_raise_server_error_event(ach_data->client, "award_achievement", ach_data->id, RC_OUT_OF_MEMORY, rc_error_str(RC_OUT_OF_MEMORY)); ++ return; ++ } ++ ach_data->scheduled_callback_data->callback = rc_client_award_achievement_retry; ++ ach_data->scheduled_callback_data->data = ach_data; ++ ach_data->scheduled_callback_data->related_id = ach_data->id; ++ } ++ ++ ach_data->scheduled_callback_data->when = ++ ach_data->client->callbacks.get_time_millisecs(ach_data->client) + delay * 1000; ++ ++ rc_client_schedule_callback(ach_data->client, ach_data->scheduled_callback_data); ++ ++ rc_client_update_disconnect_state(ach_data->client); ++ return; ++ } ++ } ++ else { ++ ach_data->client->user.score = award_achievement_response.new_player_score; ++ ach_data->client->user.score_softcore = award_achievement_response.new_player_score_softcore; ++ ++ if (award_achievement_response.awarded_achievement_id != ach_data->id) { ++ RC_CLIENT_LOG_ERR_FORMATTED(ach_data->client, "Awarded achievement %u instead of %u", award_achievement_response.awarded_achievement_id, error_message); ++ } ++ else { ++ if (award_achievement_response.response.error_message) { ++ /* previously unlocked achievements are returned as a success with an error message */ ++ RC_CLIENT_LOG_INFO_FORMATTED(ach_data->client, "Achievement %u: %s", ach_data->id, award_achievement_response.response.error_message); ++ } ++ else if (ach_data->retry_count) { ++ RC_CLIENT_LOG_INFO_FORMATTED(ach_data->client, "Achievement %u awarded after %u attempts, new score: %u", ++ ach_data->id, ach_data->retry_count + 1, ++ ach_data->hardcore ? award_achievement_response.new_player_score : award_achievement_response.new_player_score_softcore); ++ } ++ else { ++ RC_CLIENT_LOG_INFO_FORMATTED(ach_data->client, "Achievement %u awarded, new score: %u", ++ ach_data->id, ++ ach_data->hardcore ? award_achievement_response.new_player_score : award_achievement_response.new_player_score_softcore); ++ } ++ ++ if (award_achievement_response.achievements_remaining == 0) { ++ rc_client_subset_info_t* subset; ++ for (subset = ach_data->client->game->subsets; subset; subset = subset->next) { ++ if (subset->mastery == RC_CLIENT_MASTERY_STATE_NONE && ++ rc_client_subset_get_achievement_info(ach_data->client, subset, ach_data->id)) { ++ if (subset->public_.id == ach_data->client->game->public_.id) { ++ RC_CLIENT_LOG_INFO_FORMATTED(ach_data->client, "Game %u %s", ach_data->client->game->public_.id, ++ ach_data->client->state.hardcore ? "mastered" : "completed"); ++ subset->mastery = RC_CLIENT_MASTERY_STATE_PENDING; ++ } ++ else { ++ RC_CLIENT_LOG_INFO_FORMATTED(ach_data->client, "Subset %u %s", ach_data->client->game->public_.id, ++ ach_data->client->state.hardcore ? "mastered" : "completed"); ++ ++ subset->mastery = RC_CLIENT_MASTERY_STATE_PENDING; ++ } ++ } ++ } ++ } ++ } ++ } ++ ++ if (ach_data->retry_count) ++ rc_client_update_disconnect_state(ach_data->client); ++ ++ if (ach_data->scheduled_callback_data) ++ free(ach_data->scheduled_callback_data); ++ free(ach_data); ++} ++ ++static void rc_client_award_achievement_server_call(rc_client_award_achievement_callback_data_t* ach_data) ++{ ++ rc_api_award_achievement_request_t api_params; ++ rc_api_request_t request; ++ int result; ++ ++ memset(&api_params, 0, sizeof(api_params)); ++ api_params.username = ach_data->client->user.username; ++ api_params.api_token = ach_data->client->user.token; ++ api_params.achievement_id = ach_data->id; ++ api_params.hardcore = ach_data->hardcore; ++ api_params.game_hash = ach_data->game_hash; ++ ++ if (ach_data->retry_count) { ++ const rc_clock_t now = ach_data->client->callbacks.get_time_millisecs(ach_data->client); ++ api_params.seconds_since_unlock = (uint32_t)((now - ach_data->unlock_time) / 1000); ++ } ++ ++ result = rc_api_init_award_achievement_request_hosted(&request, &api_params, &ach_data->client->state.host); ++ if (result != RC_OK) { ++ RC_CLIENT_LOG_ERR_FORMATTED(ach_data->client, "Error constructing unlock request for achievement %u: %s", ach_data->id, rc_error_str(result)); ++ free(ach_data); ++ return; ++ } ++ ++ ach_data->client->callbacks.server_call(&request, rc_client_award_achievement_callback, ach_data, ach_data->client); ++ ++ rc_api_destroy_request(&request); ++} ++ ++static void rc_client_award_achievement(rc_client_t* client, rc_client_achievement_info_t* achievement) ++{ ++ rc_client_award_achievement_callback_data_t* callback_data; ++ ++ rc_mutex_lock(&client->state.mutex); ++ ++ if (client->state.hardcore) { ++ achievement->public_.unlock_time = achievement->unlock_time_hardcore = time(NULL); ++ if (achievement->unlock_time_softcore == 0) ++ achievement->unlock_time_softcore = achievement->unlock_time_hardcore; ++ ++ /* adjust score now - will get accurate score back from server */ ++ client->user.score += achievement->public_.points; ++ } ++ else { ++ achievement->public_.unlock_time = achievement->unlock_time_softcore = time(NULL); ++ ++ /* adjust score now - will get accurate score back from server */ ++ client->user.score_softcore += achievement->public_.points; ++ } ++ ++ achievement->public_.state = RC_CLIENT_ACHIEVEMENT_STATE_UNLOCKED; ++ achievement->public_.unlocked |= (client->state.hardcore) ? ++ RC_CLIENT_ACHIEVEMENT_UNLOCKED_BOTH : RC_CLIENT_ACHIEVEMENT_UNLOCKED_SOFTCORE; ++ ++ rc_mutex_unlock(&client->state.mutex); ++ ++ if (client->callbacks.can_submit_achievement_unlock && ++ !client->callbacks.can_submit_achievement_unlock(achievement->public_.id, client)) { ++ RC_CLIENT_LOG_INFO_FORMATTED(client, "Achievement %u unlock blocked by client", achievement->public_.id); ++ return; ++ } ++ ++ /* can't unlock unofficial achievements on the server */ ++ if (achievement->public_.category != RC_CLIENT_ACHIEVEMENT_CATEGORY_CORE) { ++ RC_CLIENT_LOG_INFO_FORMATTED(client, "Unlocked unofficial achievement %u: %s", achievement->public_.id, achievement->public_.title); ++ return; ++ } ++ ++ /* don't actually unlock achievements when spectating */ ++ if (client->state.spectator_mode != RC_CLIENT_SPECTATOR_MODE_OFF) { ++ RC_CLIENT_LOG_INFO_FORMATTED(client, "Spectated achievement %u: %s", achievement->public_.id, achievement->public_.title); ++ return; ++ } ++ ++ callback_data = (rc_client_award_achievement_callback_data_t*)calloc(1, sizeof(*callback_data)); ++ if (!callback_data) { ++ RC_CLIENT_LOG_ERR_FORMATTED(client, "Failed to allocate callback data for unlocking achievement %u", achievement->public_.id); ++ rc_client_raise_server_error_event(client, "award_achievement", achievement->public_.id, RC_OUT_OF_MEMORY, rc_error_str(RC_OUT_OF_MEMORY)); ++ return; ++ } ++ callback_data->client = client; ++ callback_data->id = achievement->public_.id; ++ callback_data->hardcore = client->state.hardcore; ++ callback_data->game_hash = client->game->public_.hash; ++ callback_data->unlock_time = client->callbacks.get_time_millisecs(client); ++ ++ if (client->game) /* may be NULL if this gets called while unloading the game (from another thread - events are raised outside the lock) */ ++ callback_data->game_hash = client->game->public_.hash; ++ ++ RC_CLIENT_LOG_INFO_FORMATTED(client, "Awarding achievement %u: %s", achievement->public_.id, achievement->public_.title); ++ rc_client_award_achievement_server_call(callback_data); ++} ++ ++static void rc_client_subset_reset_achievements(rc_client_subset_info_t* subset) ++{ ++ rc_client_achievement_info_t* achievement = subset->achievements; ++ rc_client_achievement_info_t* stop = achievement + subset->public_.num_achievements; ++ ++ for (; achievement < stop; ++achievement) { ++ rc_trigger_t* trigger = achievement->trigger; ++ if (!trigger || achievement->public_.state != RC_CLIENT_ACHIEVEMENT_STATE_ACTIVE) ++ continue; ++ ++ if (trigger->state == RC_TRIGGER_STATE_PRIMED) { ++ achievement->pending_events |= RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_CHALLENGE_INDICATOR_HIDE; ++ subset->pending_events |= RC_CLIENT_SUBSET_PENDING_EVENT_ACHIEVEMENT; ++ } ++ ++ rc_reset_trigger(trigger); ++ } ++} ++ ++static void rc_client_reset_achievements(rc_client_t* client) ++{ ++ rc_client_subset_info_t* subset; ++ for (subset = client->game->subsets; subset; subset = subset->next) ++ rc_client_subset_reset_achievements(subset); ++} ++ ++/* ===== Leaderboards ===== */ ++ ++static rc_client_leaderboard_info_t* rc_client_subset_get_leaderboard_info(const rc_client_subset_info_t* subset, uint32_t id) ++{ ++ rc_client_leaderboard_info_t* leaderboard = subset->leaderboards; ++ rc_client_leaderboard_info_t* stop = leaderboard + subset->public_.num_leaderboards; ++ ++ for (; leaderboard < stop; ++leaderboard) { ++ if (leaderboard->public_.id == id) ++ return leaderboard; ++ } ++ ++ return NULL; ++} ++ ++const rc_client_leaderboard_t* rc_client_get_leaderboard_info(const rc_client_t* client, uint32_t id) ++{ ++ rc_client_subset_info_t* subset; ++ ++ if (!client) ++ return NULL; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->get_leaderboard_info) ++ return client->state.external_client->get_leaderboard_info(id); ++#endif ++ ++ if (!client->game) ++ return NULL; ++ ++ for (subset = client->game->subsets; subset; subset = subset->next) { ++ const rc_client_leaderboard_info_t* leaderboard = rc_client_subset_get_leaderboard_info(subset, id); ++ if (leaderboard != NULL) ++ return &leaderboard->public_; ++ } ++ ++ return NULL; ++} ++ ++static const char* rc_client_get_leaderboard_bucket_label(uint8_t bucket_type) ++{ ++ switch (bucket_type) { ++ case RC_CLIENT_LEADERBOARD_BUCKET_INACTIVE: return "Inactive"; ++ case RC_CLIENT_LEADERBOARD_BUCKET_ACTIVE: return "Active"; ++ case RC_CLIENT_LEADERBOARD_BUCKET_UNSUPPORTED: return "Unsupported"; ++ case RC_CLIENT_LEADERBOARD_BUCKET_ALL: return "All"; ++ default: return "Unknown"; ++ } ++} ++ ++static const char* rc_client_get_subset_leaderboard_bucket_label(uint8_t bucket_type, rc_client_game_info_t* game, rc_client_subset_info_t* subset) ++{ ++ const char** ptr; ++ const char* label; ++ char* new_label; ++ size_t new_label_len; ++ ++ switch (bucket_type) { ++ case RC_CLIENT_LEADERBOARD_BUCKET_INACTIVE: ptr = &subset->inactive_label; break; ++ case RC_CLIENT_LEADERBOARD_BUCKET_UNSUPPORTED: ptr = &subset->unsupported_label; break; ++ case RC_CLIENT_LEADERBOARD_BUCKET_ALL: ptr = &subset->all_label; break; ++ default: return rc_client_get_achievement_bucket_label(bucket_type); ++ } ++ ++ if (*ptr) ++ return *ptr; ++ ++ label = rc_client_get_leaderboard_bucket_label(bucket_type); ++ new_label_len = strlen(subset->public_.title) + strlen(label) + 4; ++ new_label = (char*)rc_buffer_alloc(&game->buffer, new_label_len); ++ snprintf(new_label, new_label_len, "%s - %s", subset->public_.title, label); ++ ++ *ptr = new_label; ++ return new_label; ++} ++ ++static uint8_t rc_client_get_leaderboard_bucket(const rc_client_leaderboard_info_t* leaderboard, int grouping) ++{ ++ switch (leaderboard->public_.state) { ++ case RC_CLIENT_LEADERBOARD_STATE_TRACKING: ++ return (grouping == RC_CLIENT_LEADERBOARD_LIST_GROUPING_NONE) ? ++ RC_CLIENT_LEADERBOARD_BUCKET_ALL : RC_CLIENT_LEADERBOARD_BUCKET_ACTIVE; ++ ++ case RC_CLIENT_LEADERBOARD_STATE_DISABLED: ++ return RC_CLIENT_LEADERBOARD_BUCKET_UNSUPPORTED; ++ ++ default: ++ return (grouping == RC_CLIENT_LEADERBOARD_LIST_GROUPING_NONE) ? ++ RC_CLIENT_LEADERBOARD_BUCKET_ALL : RC_CLIENT_LEADERBOARD_BUCKET_INACTIVE; ++ } ++} ++ ++rc_client_leaderboard_list_t* rc_client_create_leaderboard_list(rc_client_t* client, int grouping) ++{ ++ rc_client_leaderboard_info_t* leaderboard; ++ rc_client_leaderboard_info_t* stop; ++ const rc_client_leaderboard_t** bucket_leaderboards; ++ const rc_client_leaderboard_t** leaderboard_ptr; ++ rc_client_leaderboard_bucket_t* bucket_ptr; ++ rc_client_leaderboard_list_info_t* list; ++ rc_client_subset_info_t* subset; ++ const uint32_t list_size = RC_ALIGN(sizeof(*list)); ++ uint32_t bucket_counts[8]; ++ uint32_t num_buckets; ++ uint32_t num_leaderboards; ++ size_t buckets_size; ++ uint8_t bucket_type; ++ uint32_t num_subsets = 0; ++ uint32_t i, j; ++ const uint8_t shared_bucket_order[] = { ++ RC_CLIENT_LEADERBOARD_BUCKET_ACTIVE ++ }; ++ const uint8_t subset_bucket_order[] = { ++ RC_CLIENT_LEADERBOARD_BUCKET_ALL, ++ RC_CLIENT_LEADERBOARD_BUCKET_INACTIVE, ++ RC_CLIENT_LEADERBOARD_BUCKET_UNSUPPORTED ++ }; ++ ++ if (!client) ++ return (rc_client_leaderboard_list_t*)calloc(1, list_size); ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->create_leaderboard_list) ++ return (rc_client_leaderboard_list_t*)client->state.external_client->create_leaderboard_list(grouping); ++#endif ++ ++ if (!client->game) ++ return (rc_client_leaderboard_list_t*)calloc(1, list_size); ++ ++ memset(&bucket_counts, 0, sizeof(bucket_counts)); ++ ++ rc_mutex_lock(&client->state.mutex); ++ ++ subset = client->game->subsets; ++ for (; subset; subset = subset->next) { ++ if (!subset->active) ++ continue; ++ ++ num_subsets++; ++ leaderboard = subset->leaderboards; ++ stop = leaderboard + subset->public_.num_leaderboards; ++ for (; leaderboard < stop; ++leaderboard) { ++ if (leaderboard->hidden) ++ continue; ++ ++ leaderboard->bucket = rc_client_get_leaderboard_bucket(leaderboard, grouping); ++ bucket_counts[leaderboard->bucket]++; ++ } ++ } ++ ++ num_buckets = 0; ++ num_leaderboards = 0; ++ for (i = 0; i < sizeof(bucket_counts) / sizeof(bucket_counts[0]); ++i) { ++ if (bucket_counts[i]) { ++ int needs_split = 0; ++ ++ num_leaderboards += bucket_counts[i]; ++ ++ if (num_subsets > 1) { ++ for (j = 0; j < sizeof(subset_bucket_order) / sizeof(subset_bucket_order[0]); ++j) { ++ if (subset_bucket_order[j] == i) { ++ needs_split = 1; ++ break; ++ } ++ } ++ } ++ ++ if (!needs_split) { ++ ++num_buckets; ++ continue; ++ } ++ ++ subset = client->game->subsets; ++ for (; subset; subset = subset->next) { ++ if (!subset->active) ++ continue; ++ ++ leaderboard = subset->leaderboards; ++ stop = leaderboard + subset->public_.num_leaderboards; ++ for (; leaderboard < stop; ++leaderboard) { ++ if (leaderboard->bucket == i) { ++ ++num_buckets; ++ break; ++ } ++ } ++ } ++ } ++ } ++ ++ buckets_size = RC_ALIGN(num_buckets * sizeof(rc_client_leaderboard_bucket_t)); ++ ++ list = (rc_client_leaderboard_list_info_t*)malloc(list_size + buckets_size + num_leaderboards * sizeof(rc_client_leaderboard_t*)); ++ list->public_.buckets = bucket_ptr = (rc_client_leaderboard_bucket_t*)((uint8_t*)list + list_size); ++ leaderboard_ptr = (const rc_client_leaderboard_t**)((uint8_t*)bucket_ptr + buckets_size); ++ ++ if (grouping == RC_CLIENT_LEADERBOARD_LIST_GROUPING_TRACKING) { ++ for (i = 0; i < sizeof(shared_bucket_order) / sizeof(shared_bucket_order[0]); ++i) { ++ bucket_type = shared_bucket_order[i]; ++ if (!bucket_counts[bucket_type]) ++ continue; ++ ++ bucket_leaderboards = leaderboard_ptr; ++ for (subset = client->game->subsets; subset; subset = subset->next) { ++ if (!subset->active) ++ continue; ++ ++ leaderboard = subset->leaderboards; ++ stop = leaderboard + subset->public_.num_leaderboards; ++ for (; leaderboard < stop; ++leaderboard) { ++ if (leaderboard->bucket == bucket_type && !leaderboard->hidden) ++ *leaderboard_ptr++ = &leaderboard->public_; ++ } ++ } ++ ++ if (leaderboard_ptr > bucket_leaderboards) { ++ bucket_ptr->leaderboards = bucket_leaderboards; ++ bucket_ptr->num_leaderboards = (uint32_t)(leaderboard_ptr - bucket_leaderboards); ++ bucket_ptr->subset_id = 0; ++ bucket_ptr->label = rc_client_get_leaderboard_bucket_label(bucket_type); ++ bucket_ptr->bucket_type = bucket_type; ++ ++bucket_ptr; ++ } ++ } ++ } ++ ++ for (subset = client->game->subsets; subset; subset = subset->next) { ++ if (!subset->active) ++ continue; ++ ++ for (i = 0; i < sizeof(subset_bucket_order) / sizeof(subset_bucket_order[0]); ++i) { ++ bucket_type = subset_bucket_order[i]; ++ if (!bucket_counts[bucket_type]) ++ continue; ++ ++ bucket_leaderboards = leaderboard_ptr; ++ ++ leaderboard = subset->leaderboards; ++ stop = leaderboard + subset->public_.num_leaderboards; ++ for (; leaderboard < stop; ++leaderboard) { ++ if (leaderboard->bucket == bucket_type && !leaderboard->hidden) ++ *leaderboard_ptr++ = &leaderboard->public_; ++ } ++ ++ if (leaderboard_ptr > bucket_leaderboards) { ++ bucket_ptr->leaderboards = bucket_leaderboards; ++ bucket_ptr->num_leaderboards = (uint32_t)(leaderboard_ptr - bucket_leaderboards); ++ bucket_ptr->subset_id = (num_subsets > 1) ? subset->public_.id : 0; ++ bucket_ptr->bucket_type = bucket_type; ++ ++ if (num_subsets > 1) ++ bucket_ptr->label = rc_client_get_subset_leaderboard_bucket_label(bucket_type, client->game, subset); ++ else ++ bucket_ptr->label = rc_client_get_leaderboard_bucket_label(bucket_type); ++ ++ ++bucket_ptr; ++ } ++ } ++ } ++ ++ rc_mutex_unlock(&client->state.mutex); ++ ++ list->destroy_func = NULL; ++ list->public_.num_buckets = (uint32_t)(bucket_ptr - list->public_.buckets); ++ return &list->public_; ++} ++ ++void rc_client_destroy_leaderboard_list(rc_client_leaderboard_list_t* list) ++{ ++ rc_client_leaderboard_list_info_t* info = (rc_client_leaderboard_list_info_t*)list; ++ if (info->destroy_func) ++ info->destroy_func(info); ++ else ++ free(list); ++} ++ ++int rc_client_has_leaderboards(rc_client_t* client) ++{ ++ rc_client_subset_info_t* subset; ++ int result; ++ ++ if (!client) ++ return 0; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->has_leaderboards) ++ return client->state.external_client->has_leaderboards(); ++#endif ++ ++ if (!client->game) ++ return 0; ++ ++ rc_mutex_lock(&client->state.mutex); ++ ++ subset = client->game->subsets; ++ result = 0; ++ for (; subset; subset = subset->next) ++ { ++ if (!subset->active) ++ continue; ++ ++ if (subset->public_.num_leaderboards > 0) { ++ result = 1; ++ break; ++ } ++ } ++ ++ rc_mutex_unlock(&client->state.mutex); ++ ++ return result; ++} ++ ++void rc_client_allocate_leaderboard_tracker(rc_client_game_info_t* game, rc_client_leaderboard_info_t* leaderboard) ++{ ++ rc_client_leaderboard_tracker_info_t* tracker; ++ rc_client_leaderboard_tracker_info_t* available_tracker = NULL; ++ ++ for (tracker = game->leaderboard_trackers; tracker; tracker = tracker->next) { ++ if (tracker->reference_count == 0) { ++ if (available_tracker == NULL && tracker->pending_events == RC_CLIENT_LEADERBOARD_TRACKER_PENDING_EVENT_NONE) ++ available_tracker = tracker; ++ ++ continue; ++ } ++ ++ if (tracker->value_djb2 != leaderboard->value_djb2 || tracker->format != leaderboard->format) ++ continue; ++ ++ if (tracker->raw_value != leaderboard->value) { ++ /* if the value comes from tracking hits, we can't assume the trackers started in the ++ * same frame, so we can't share the tracker */ ++ if (tracker->value_from_hits) ++ continue; ++ ++ /* value has changed. prepare an update event */ ++ tracker->raw_value = leaderboard->value; ++ tracker->pending_events |= RC_CLIENT_LEADERBOARD_TRACKER_PENDING_EVENT_UPDATE; ++ game->pending_events |= RC_CLIENT_GAME_PENDING_EVENT_LEADERBOARD_TRACKER; ++ } ++ ++ /* attach to the existing tracker */ ++ ++tracker->reference_count; ++ tracker->pending_events &= ~RC_CLIENT_LEADERBOARD_TRACKER_PENDING_EVENT_HIDE; ++ leaderboard->tracker = tracker; ++ leaderboard->public_.tracker_value = tracker->public_.display; ++ return; ++ } ++ ++ if (!available_tracker) { ++ rc_client_leaderboard_tracker_info_t** next = &game->leaderboard_trackers; ++ ++ available_tracker = (rc_client_leaderboard_tracker_info_t*)rc_buffer_alloc(&game->buffer, sizeof(*available_tracker)); ++ memset(available_tracker, 0, sizeof(*available_tracker)); ++ available_tracker->public_.id = 1; ++ ++ for (tracker = *next; tracker; next = &tracker->next, tracker = *next) ++ available_tracker->public_.id++; ++ ++ *next = available_tracker; ++ } ++ ++ /* update the claimed tracker */ ++ available_tracker->reference_count = 1; ++ available_tracker->value_djb2 = leaderboard->value_djb2; ++ available_tracker->format = leaderboard->format; ++ available_tracker->raw_value = leaderboard->value; ++ available_tracker->pending_events = RC_CLIENT_LEADERBOARD_TRACKER_PENDING_EVENT_SHOW; ++ available_tracker->value_from_hits = rc_value_from_hits(&leaderboard->lboard->value); ++ leaderboard->tracker = available_tracker; ++ leaderboard->public_.tracker_value = available_tracker->public_.display; ++ game->pending_events |= RC_CLIENT_GAME_PENDING_EVENT_LEADERBOARD_TRACKER; ++} ++ ++void rc_client_release_leaderboard_tracker(rc_client_game_info_t* game, rc_client_leaderboard_info_t* leaderboard) ++{ ++ rc_client_leaderboard_tracker_info_t* tracker = leaderboard->tracker; ++ leaderboard->tracker = NULL; ++ ++ if (tracker && --tracker->reference_count == 0) { ++ tracker->pending_events |= RC_CLIENT_LEADERBOARD_TRACKER_PENDING_EVENT_HIDE; ++ game->pending_events |= RC_CLIENT_GAME_PENDING_EVENT_LEADERBOARD_TRACKER; ++ } ++} ++ ++static void rc_client_update_leaderboard_tracker(rc_client_game_info_t* game, rc_client_leaderboard_info_t* leaderboard) ++{ ++ rc_client_leaderboard_tracker_info_t* tracker = leaderboard->tracker; ++ if (tracker && tracker->raw_value != leaderboard->value) { ++ tracker->raw_value = leaderboard->value; ++ tracker->pending_events |= RC_CLIENT_LEADERBOARD_TRACKER_PENDING_EVENT_UPDATE; ++ game->pending_events |= RC_CLIENT_GAME_PENDING_EVENT_LEADERBOARD_TRACKER; ++ } ++} ++ ++typedef struct rc_client_submit_leaderboard_entry_callback_data_t ++{ ++ uint32_t id; ++ int32_t score; ++ uint32_t retry_count; ++ const char* game_hash; ++ rc_clock_t submit_time; ++ rc_client_t* client; ++ rc_client_scheduled_callback_data_t* scheduled_callback_data; ++} rc_client_submit_leaderboard_entry_callback_data_t; ++ ++static void rc_client_submit_leaderboard_entry_server_call(rc_client_submit_leaderboard_entry_callback_data_t* lboard_data); ++ ++static void rc_client_submit_leaderboard_entry_retry(rc_client_scheduled_callback_data_t* callback_data, rc_client_t* client, rc_clock_t now) ++{ ++ rc_client_submit_leaderboard_entry_callback_data_t* lboard_data = ++ (rc_client_submit_leaderboard_entry_callback_data_t*)callback_data->data; ++ ++ (void)client; ++ (void)now; ++ ++ rc_client_submit_leaderboard_entry_server_call(lboard_data); ++} ++ ++static void rc_client_raise_scoreboard_event(rc_client_submit_leaderboard_entry_callback_data_t* lboard_data, ++ const rc_api_submit_lboard_entry_response_t* response) ++{ ++ rc_client_leaderboard_scoreboard_t sboard; ++ rc_client_event_t client_event; ++ rc_client_subset_info_t* subset; ++ rc_client_t* client = lboard_data->client; ++ rc_client_leaderboard_info_t* leaderboard = NULL; ++ ++ if (!client || !client->game) ++ return; ++ ++ for (subset = client->game->subsets; subset; subset = subset->next) { ++ leaderboard = rc_client_subset_get_leaderboard_info(subset, lboard_data->id); ++ if (leaderboard != NULL) ++ break; ++ } ++ if (leaderboard == NULL) { ++ RC_CLIENT_LOG_ERR_FORMATTED(client, "Trying to raise scoreboard for unknown leaderboard %u", lboard_data->id); ++ return; ++ } ++ ++ memset(&sboard, 0, sizeof(sboard)); ++ sboard.leaderboard_id = lboard_data->id; ++ rc_format_value(sboard.submitted_score, sizeof(sboard.submitted_score), response->submitted_score, leaderboard->format); ++ rc_format_value(sboard.best_score, sizeof(sboard.best_score), response->best_score, leaderboard->format); ++ sboard.new_rank = response->new_rank; ++ sboard.num_entries = response->num_entries; ++ sboard.num_top_entries = response->num_top_entries; ++ if (sboard.num_top_entries > 0) { ++ sboard.top_entries = (rc_client_leaderboard_scoreboard_entry_t*)calloc( ++ response->num_top_entries, sizeof(rc_client_leaderboard_scoreboard_entry_t)); ++ if (sboard.top_entries != NULL) { ++ uint32_t i; ++ for (i = 0; i < response->num_top_entries; i++) { ++ sboard.top_entries[i].username = response->top_entries[i].username; ++ sboard.top_entries[i].rank = response->top_entries[i].rank; ++ rc_format_value(sboard.top_entries[i].score, sizeof(sboard.top_entries[i].score), response->top_entries[i].score, ++ leaderboard->format); ++ } ++ } ++ } ++ ++ memset(&client_event, 0, sizeof(client_event)); ++ client_event.type = RC_CLIENT_EVENT_LEADERBOARD_SCOREBOARD; ++ client_event.leaderboard = &leaderboard->public_; ++ client_event.leaderboard_scoreboard = &sboard; ++ ++ lboard_data->client->callbacks.event_handler(&client_event, lboard_data->client); ++ ++ if (sboard.top_entries != NULL) { ++ free(sboard.top_entries); ++ } ++} ++ ++static void rc_client_submit_leaderboard_entry_callback(const rc_api_server_response_t* server_response, void* callback_data) ++{ ++ rc_client_submit_leaderboard_entry_callback_data_t* lboard_data = ++ (rc_client_submit_leaderboard_entry_callback_data_t*)callback_data; ++ rc_api_submit_lboard_entry_response_t submit_lboard_entry_response; ++ ++ int result = rc_api_process_submit_lboard_entry_server_response(&submit_lboard_entry_response, server_response); ++ const char* error_message = rc_client_server_error_message(&result, server_response->http_status_code, &submit_lboard_entry_response.response); ++ ++ if (error_message) { ++ if (submit_lboard_entry_response.response.error_message && !rc_client_should_retry(server_response)) { ++ /* actual error from server */ ++ RC_CLIENT_LOG_ERR_FORMATTED(lboard_data->client, "Error submitting leaderboard entry %u: %s", lboard_data->id, error_message); ++ rc_client_raise_server_error_event(lboard_data->client, "submit_lboard_entry", lboard_data->id, result, submit_lboard_entry_response.response.error_message); ++ } ++ else if (lboard_data->retry_count++ == 0) { ++ /* first retry is immediate */ ++ RC_CLIENT_LOG_ERR_FORMATTED(lboard_data->client, "Error submitting leaderboard entry %u: %s, retrying immediately", lboard_data->id, error_message); ++ rc_client_submit_leaderboard_entry_server_call(lboard_data); ++ return; ++ } ++ else { ++ /* double wait time between each attempt until we hit a maximum delay of two minutes */ ++ /* 1s -> 2s -> 4s -> 8s -> 16s -> 32s -> 64s -> 120s -> 120s -> 120s ...*/ ++ const uint32_t delay = (lboard_data->retry_count > 8) ? 120 : (1 << (lboard_data->retry_count - 2)); ++ RC_CLIENT_LOG_ERR_FORMATTED(lboard_data->client, "Error submitting leaderboard entry %u: %s, retrying in %u seconds", lboard_data->id, error_message, delay); ++ ++ if (!lboard_data->scheduled_callback_data) { ++ lboard_data->scheduled_callback_data = (rc_client_scheduled_callback_data_t*)calloc(1, sizeof(*lboard_data->scheduled_callback_data)); ++ if (!lboard_data->scheduled_callback_data) { ++ RC_CLIENT_LOG_ERR_FORMATTED(lboard_data->client, "Failed to allocate scheduled callback data for reattempt to submit entry for leaderboard %u", lboard_data->id); ++ rc_client_raise_server_error_event(lboard_data->client, "submit_lboard_entry", lboard_data->id, RC_OUT_OF_MEMORY, rc_error_str(RC_OUT_OF_MEMORY)); ++ return; ++ } ++ lboard_data->scheduled_callback_data->callback = rc_client_submit_leaderboard_entry_retry; ++ lboard_data->scheduled_callback_data->data = lboard_data; ++ lboard_data->scheduled_callback_data->related_id = lboard_data->id; ++ } ++ ++ lboard_data->scheduled_callback_data->when = ++ lboard_data->client->callbacks.get_time_millisecs(lboard_data->client) + delay * 1000; ++ ++ rc_client_schedule_callback(lboard_data->client, lboard_data->scheduled_callback_data); ++ ++ rc_client_update_disconnect_state(lboard_data->client); ++ return; ++ } ++ } ++ else { ++ /* raise event for scoreboard */ ++ if (lboard_data->retry_count < 2) { ++ rc_client_raise_scoreboard_event(lboard_data, &submit_lboard_entry_response); ++ } ++ ++ /* not currently doing anything with the response */ ++ if (lboard_data->retry_count) { ++ RC_CLIENT_LOG_INFO_FORMATTED(lboard_data->client, "Leaderboard %u submission %d completed after %u attempts", ++ lboard_data->id, lboard_data->score, lboard_data->retry_count); ++ } ++ } ++ ++ if (lboard_data->retry_count) ++ rc_client_update_disconnect_state(lboard_data->client); ++ ++ if (lboard_data->scheduled_callback_data) ++ free(lboard_data->scheduled_callback_data); ++ free(lboard_data); ++} ++ ++static void rc_client_submit_leaderboard_entry_server_call(rc_client_submit_leaderboard_entry_callback_data_t* lboard_data) ++{ ++ rc_api_submit_lboard_entry_request_t api_params; ++ rc_api_request_t request; ++ int result; ++ ++ memset(&api_params, 0, sizeof(api_params)); ++ api_params.username = lboard_data->client->user.username; ++ api_params.api_token = lboard_data->client->user.token; ++ api_params.leaderboard_id = lboard_data->id; ++ api_params.score = lboard_data->score; ++ api_params.game_hash = lboard_data->game_hash; ++ ++ if (lboard_data->retry_count) { ++ const rc_clock_t now = lboard_data->client->callbacks.get_time_millisecs(lboard_data->client); ++ api_params.seconds_since_completion = (uint32_t)((now - lboard_data->submit_time) / 1000); ++ } ++ ++ result = rc_api_init_submit_lboard_entry_request_hosted(&request, &api_params, &lboard_data->client->state.host); ++ if (result != RC_OK) { ++ RC_CLIENT_LOG_ERR_FORMATTED(lboard_data->client, "Error constructing submit leaderboard entry for leaderboard %u: %s", lboard_data->id, rc_error_str(result)); ++ return; ++ } ++ ++ lboard_data->client->callbacks.server_call(&request, rc_client_submit_leaderboard_entry_callback, lboard_data, lboard_data->client); ++ ++ rc_api_destroy_request(&request); ++} ++ ++static void rc_client_submit_leaderboard_entry(rc_client_t* client, rc_client_leaderboard_info_t* leaderboard) ++{ ++ rc_client_submit_leaderboard_entry_callback_data_t* callback_data; ++ ++ if (!client->state.hardcore) { ++ RC_CLIENT_LOG_INFO_FORMATTED(client, "Leaderboard %u entry submission not allowed in softcore", leaderboard->public_.id); ++ return; ++ } ++ ++ if (client->callbacks.can_submit_leaderboard_entry && ++ !client->callbacks.can_submit_leaderboard_entry(leaderboard->public_.id, client)) { ++ RC_CLIENT_LOG_INFO_FORMATTED(client, "Leaderboard %u entry submission blocked by client", leaderboard->public_.id); ++ return; ++ } ++ ++ /* don't actually submit leaderboard entries when spectating */ ++ if (client->state.spectator_mode != RC_CLIENT_SPECTATOR_MODE_OFF) { ++ RC_CLIENT_LOG_INFO_FORMATTED(client, "Spectated %s (%d) for leaderboard %u: %s", ++ leaderboard->public_.tracker_value, leaderboard->value, leaderboard->public_.id, leaderboard->public_.title); ++ return; ++ } ++ ++ callback_data = (rc_client_submit_leaderboard_entry_callback_data_t*)calloc(1, sizeof(*callback_data)); ++ if (!callback_data) { ++ RC_CLIENT_LOG_ERR_FORMATTED(client, "Failed to allocate callback data for submitting entry for leaderboard %u", leaderboard->public_.id); ++ rc_client_raise_server_error_event(client, "submit_lboard_entry", leaderboard->public_.id, RC_OUT_OF_MEMORY, rc_error_str(RC_OUT_OF_MEMORY)); ++ return; ++ } ++ callback_data->client = client; ++ callback_data->id = leaderboard->public_.id; ++ callback_data->score = leaderboard->value; ++ callback_data->game_hash = client->game->public_.hash; ++ callback_data->submit_time = client->callbacks.get_time_millisecs(client); ++ ++ RC_CLIENT_LOG_INFO_FORMATTED(client, "Submitting %s (%d) for leaderboard %u: %s", ++ leaderboard->public_.tracker_value, leaderboard->value, leaderboard->public_.id, leaderboard->public_.title); ++ rc_client_submit_leaderboard_entry_server_call(callback_data); ++} ++ ++static void rc_client_subset_reset_leaderboards(rc_client_game_info_t* game, rc_client_subset_info_t* subset) ++{ ++ rc_client_leaderboard_info_t* leaderboard = subset->leaderboards; ++ rc_client_leaderboard_info_t* stop = leaderboard + subset->public_.num_leaderboards; ++ ++ for (; leaderboard < stop; ++leaderboard) { ++ rc_lboard_t* lboard = leaderboard->lboard; ++ if (!lboard) ++ continue; ++ ++ switch (leaderboard->public_.state) { ++ case RC_CLIENT_LEADERBOARD_STATE_INACTIVE: ++ case RC_CLIENT_LEADERBOARD_STATE_DISABLED: ++ continue; ++ ++ case RC_CLIENT_LEADERBOARD_STATE_TRACKING: ++ rc_client_release_leaderboard_tracker(game, leaderboard); ++ /* fallthrough */ /* to default */ ++ default: ++ leaderboard->public_.state = RC_CLIENT_LEADERBOARD_STATE_ACTIVE; ++ rc_reset_lboard(lboard); ++ break; ++ } ++ } ++} ++ ++static void rc_client_reset_leaderboards(rc_client_t* client) ++{ ++ rc_client_subset_info_t* subset; ++ for (subset = client->game->subsets; subset; subset = subset->next) ++ rc_client_subset_reset_leaderboards(client->game, subset); ++} ++ ++typedef struct rc_client_fetch_leaderboard_entries_callback_data_t { ++ rc_client_t* client; ++ rc_client_fetch_leaderboard_entries_callback_t callback; ++ void* callback_userdata; ++ uint32_t leaderboard_id; ++ rc_client_async_handle_t async_handle; ++} rc_client_fetch_leaderboard_entries_callback_data_t; ++ ++static void rc_client_fetch_leaderboard_entries_callback(const rc_api_server_response_t* server_response, void* callback_data) ++{ ++ rc_client_fetch_leaderboard_entries_callback_data_t* lbinfo_callback_data = (rc_client_fetch_leaderboard_entries_callback_data_t*)callback_data; ++ rc_client_t* client = lbinfo_callback_data->client; ++ rc_api_fetch_leaderboard_info_response_t lbinfo_response; ++ const char* error_message; ++ int result; ++ ++ result = rc_client_end_async(client, &lbinfo_callback_data->async_handle); ++ if (result) { ++ if (result != RC_CLIENT_ASYNC_DESTROYED) { ++ RC_CLIENT_LOG_VERBOSE(client, "Fetch leaderbord entries aborted"); ++ } ++ free(lbinfo_callback_data); ++ return; ++ } ++ ++ result = rc_api_process_fetch_leaderboard_info_server_response(&lbinfo_response, server_response); ++ error_message = rc_client_server_error_message(&result, server_response->http_status_code, &lbinfo_response.response); ++ if (error_message) { ++ RC_CLIENT_LOG_ERR_FORMATTED(client, "Fetch leaderboard %u info failed: %s", lbinfo_callback_data->leaderboard_id, error_message); ++ lbinfo_callback_data->callback(result, error_message, NULL, client, lbinfo_callback_data->callback_userdata); ++ } ++ else { ++ rc_client_leaderboard_entry_list_info_t* info; ++ const size_t list_size = sizeof(*info) + sizeof(rc_client_leaderboard_entry_t) * lbinfo_response.num_entries; ++ size_t needed_size = list_size; ++ uint32_t i; ++ ++ for (i = 0; i < lbinfo_response.num_entries; i++) ++ needed_size += strlen(lbinfo_response.entries[i].username) + 1; ++ ++ info = (rc_client_leaderboard_entry_list_info_t*)malloc(needed_size); ++ if (!info) { ++ lbinfo_callback_data->callback(RC_OUT_OF_MEMORY, rc_error_str(RC_OUT_OF_MEMORY), NULL, client, lbinfo_callback_data->callback_userdata); ++ } ++ else { ++ rc_client_leaderboard_entry_list_t* list = &info->public_; ++ rc_client_leaderboard_entry_t* entry = list->entries = (rc_client_leaderboard_entry_t*)((uint8_t*)info + sizeof(*info)); ++ char* user = (char*)((uint8_t*)list + list_size); ++ const rc_api_lboard_info_entry_t* lbentry = lbinfo_response.entries; ++ const rc_api_lboard_info_entry_t* stop = lbentry + lbinfo_response.num_entries; ++ const size_t logged_in_user_len = strlen(client->user.display_name) + 1; ++ info->destroy_func = NULL; ++ list->user_index = -1; ++ ++ for (; lbentry < stop; ++lbentry, ++entry) { ++ const size_t len = strlen(lbentry->username) + 1; ++ entry->user = user; ++ memcpy(user, lbentry->username, len); ++ user += len; ++ ++ if (len == logged_in_user_len && memcmp(entry->user, client->user.display_name, len) == 0) ++ list->user_index = (int)(entry - list->entries); ++ ++ entry->index = lbentry->index; ++ entry->rank = lbentry->rank; ++ entry->submitted = lbentry->submitted; ++ ++ rc_format_value(entry->display, sizeof(entry->display), lbentry->score, lbinfo_response.format); ++ } ++ ++ list->num_entries = lbinfo_response.num_entries; ++ list->total_entries = lbinfo_response.total_entries; ++ ++ lbinfo_callback_data->callback(RC_OK, NULL, list, client, lbinfo_callback_data->callback_userdata); ++ } ++ } ++ ++ rc_api_destroy_fetch_leaderboard_info_response(&lbinfo_response); ++ free(lbinfo_callback_data); ++} ++ ++static rc_client_async_handle_t* rc_client_begin_fetch_leaderboard_info(rc_client_t* client, ++ const rc_api_fetch_leaderboard_info_request_t* lbinfo_request, ++ rc_client_fetch_leaderboard_entries_callback_t callback, void* callback_userdata) ++{ ++ rc_client_fetch_leaderboard_entries_callback_data_t* callback_data; ++ rc_client_async_handle_t* async_handle; ++ rc_api_request_t request; ++ int result; ++ const char* error_message; ++ ++ result = rc_api_init_fetch_leaderboard_info_request_hosted(&request, lbinfo_request, &client->state.host); ++ ++ if (result != RC_OK) { ++ error_message = rc_error_str(result); ++ callback(result, error_message, NULL, client, callback_userdata); ++ return NULL; ++ } ++ ++ callback_data = (rc_client_fetch_leaderboard_entries_callback_data_t*)calloc(1, sizeof(*callback_data)); ++ if (!callback_data) { ++ callback(RC_OUT_OF_MEMORY, rc_error_str(RC_OUT_OF_MEMORY), NULL, client, callback_userdata); ++ return NULL; ++ } ++ ++ callback_data->client = client; ++ callback_data->callback = callback; ++ callback_data->callback_userdata = callback_userdata; ++ callback_data->leaderboard_id = lbinfo_request->leaderboard_id; ++ ++ async_handle = &callback_data->async_handle; ++ rc_client_begin_async(client, async_handle); ++ client->callbacks.server_call(&request, rc_client_fetch_leaderboard_entries_callback, callback_data, client); ++ rc_api_destroy_request(&request); ++ ++ return rc_client_async_handle_valid(client, async_handle) ? async_handle : NULL; ++} ++ ++rc_client_async_handle_t* rc_client_begin_fetch_leaderboard_entries(rc_client_t* client, uint32_t leaderboard_id, ++ uint32_t first_entry, uint32_t count, rc_client_fetch_leaderboard_entries_callback_t callback, void* callback_userdata) ++{ ++ rc_api_fetch_leaderboard_info_request_t lbinfo_request; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->begin_fetch_leaderboard_entries) ++ return client->state.external_client->begin_fetch_leaderboard_entries(client, leaderboard_id, first_entry, count, callback, callback_userdata); ++#endif ++ ++ memset(&lbinfo_request, 0, sizeof(lbinfo_request)); ++ lbinfo_request.leaderboard_id = leaderboard_id; ++ lbinfo_request.first_entry = first_entry; ++ lbinfo_request.count = count; ++ ++ return rc_client_begin_fetch_leaderboard_info(client, &lbinfo_request, callback, callback_userdata); ++} ++ ++rc_client_async_handle_t* rc_client_begin_fetch_leaderboard_entries_around_user(rc_client_t* client, uint32_t leaderboard_id, ++ uint32_t count, rc_client_fetch_leaderboard_entries_callback_t callback, void* callback_userdata) ++{ ++ rc_api_fetch_leaderboard_info_request_t lbinfo_request; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->begin_fetch_leaderboard_entries_around_user) ++ return client->state.external_client->begin_fetch_leaderboard_entries_around_user(client, leaderboard_id, count, callback, callback_userdata); ++#endif ++ ++ memset(&lbinfo_request, 0, sizeof(lbinfo_request)); ++ lbinfo_request.leaderboard_id = leaderboard_id; ++ lbinfo_request.username = client->user.username; ++ lbinfo_request.count = count; ++ ++ if (!lbinfo_request.username) { ++ callback(RC_LOGIN_REQUIRED, rc_error_str(RC_LOGIN_REQUIRED), NULL, client, callback_userdata); ++ return NULL; ++ } ++ ++ return rc_client_begin_fetch_leaderboard_info(client, &lbinfo_request, callback, callback_userdata); ++} ++ ++void rc_client_destroy_leaderboard_entry_list(rc_client_leaderboard_entry_list_t* list) ++{ ++ rc_client_leaderboard_entry_list_info_t* info = (rc_client_leaderboard_entry_list_info_t*)list; ++ if (info->destroy_func) ++ info->destroy_func(info); ++ else ++ free(list); ++} ++ ++int rc_client_leaderboard_entry_get_user_image_url(const rc_client_leaderboard_entry_t* entry, char buffer[], size_t buffer_size) ++{ ++ if (!entry) ++ return RC_INVALID_STATE; ++ ++ return rc_client_get_image_url(buffer, buffer_size, RC_IMAGE_TYPE_USER, entry->user); ++} ++ ++/* ===== Rich Presence ===== */ ++ ++static void rc_client_ping_callback(const rc_api_server_response_t* server_response, void* callback_data) ++{ ++ rc_client_t* client = (rc_client_t*)callback_data; ++ rc_api_ping_response_t response; ++ ++ int result = rc_api_process_ping_server_response(&response, server_response); ++ const char* error_message = rc_client_server_error_message(&result, server_response->http_status_code, &response.response); ++ if (error_message) { ++ RC_CLIENT_LOG_WARN_FORMATTED(client, "Ping response error: %s", error_message); ++ } ++ ++ rc_api_destroy_ping_response(&response); ++} ++ ++static void rc_client_ping(rc_client_scheduled_callback_data_t* callback_data, rc_client_t* client, rc_clock_t now) ++{ ++ rc_api_ping_request_t api_params; ++ rc_api_request_t request; ++ char buffer[256]; ++ int result; ++ ++ /* if no frames have been processed since the last ping, the emulator is idle. let the ++ * server session expire. it will be resumed/restarted once frames start getting ++ * processed again. */ ++ if (client->state.frames_processed != client->state.frames_at_last_ping) { ++ client->state.frames_at_last_ping = client->state.frames_processed; ++ ++ if (!client->callbacks.rich_presence_override || ++ !client->callbacks.rich_presence_override(client, buffer, sizeof(buffer))) { ++ rc_mutex_lock(&client->state.mutex); ++ ++ rc_runtime_get_richpresence(&client->game->runtime, buffer, sizeof(buffer), ++ client->state.legacy_peek, client, NULL); ++ ++ rc_mutex_unlock(&client->state.mutex); ++ } ++ ++ memset(&api_params, 0, sizeof(api_params)); ++ api_params.username = client->user.username; ++ api_params.api_token = client->user.token; ++ api_params.game_id = client->game->public_.id; ++ api_params.rich_presence = buffer; ++ api_params.game_hash = client->game->public_.hash; ++ api_params.hardcore = client->state.hardcore; ++ ++ result = rc_api_init_ping_request_hosted(&request, &api_params, &client->state.host); ++ if (result != RC_OK) { ++ RC_CLIENT_LOG_WARN_FORMATTED(client, "Error generating ping request: %s", rc_error_str(result)); ++ } ++ else { ++ client->callbacks.server_call(&request, rc_client_ping_callback, client, client); ++ } ++ } ++ ++ callback_data->when = now + 120 * 1000; ++ rc_client_schedule_callback(client, callback_data); ++} ++ ++int rc_client_has_rich_presence(rc_client_t* client) ++{ ++ if (!client) ++ return 0; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->has_rich_presence) ++ return client->state.external_client->has_rich_presence(); ++#endif ++ ++ if (!client->game || !client->game->runtime.richpresence || !client->game->runtime.richpresence->richpresence) ++ return 0; ++ ++ return 1; ++} ++ ++size_t rc_client_get_rich_presence_message(rc_client_t* client, char buffer[], size_t buffer_size) ++{ ++ int result; ++ ++ if (!client || !buffer) ++ return 0; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->get_rich_presence_message) ++ return client->state.external_client->get_rich_presence_message(buffer, buffer_size); ++#endif ++ ++ if (!client->game) ++ return 0; ++ ++ rc_mutex_lock(&client->state.mutex); ++ ++ result = rc_runtime_get_richpresence(&client->game->runtime, buffer, (unsigned)buffer_size, ++ client->state.legacy_peek, client, NULL); ++ ++ rc_mutex_unlock(&client->state.mutex); ++ ++ if (result == 0) { ++ result = snprintf(buffer, buffer_size, "Playing %s", client->game->public_.title); ++ /* snprintf will return the amount of space needed, we want to return the number of chars written */ ++ if ((size_t)result >= buffer_size) ++ return (buffer_size - 1); ++ } ++ ++ return result; ++} ++ ++/* ===== Processing ===== */ ++ ++void rc_client_set_event_handler(rc_client_t* client, rc_client_event_handler_t handler) ++{ ++ if (!client) ++ return; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->set_event_handler) ++ client->state.external_client->set_event_handler(client, handler); ++#endif ++ ++ client->callbacks.event_handler = handler; ++} ++ ++void rc_client_set_read_memory_function(rc_client_t* client, rc_client_read_memory_func_t handler) ++{ ++ if (!client) ++ return; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->set_read_memory) ++ client->state.external_client->set_read_memory(client, handler); ++#endif ++ ++ client->callbacks.read_memory = handler; ++} ++ ++void rc_client_set_allow_background_memory_reads(rc_client_t* client, int allowed) ++{ ++ if (!client) ++ return; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->set_allow_background_memory_reads) ++ client->state.external_client->set_allow_background_memory_reads(allowed); ++#endif ++ ++ client->state.allow_background_memory_reads = allowed; ++} ++ ++static void rc_client_invalidate_processing_memref(rc_client_t* client) ++{ ++ /* if processing_memref is not set, this occurred following a pointer chain. ignore it. */ ++ if (!client->state.processing_memref) ++ return; ++ ++ client->state.processing_memref->value.type = RC_VALUE_TYPE_NONE; ++ ++ rc_client_invalidate_memref_achievements(client->game, client, client->state.processing_memref); ++ rc_client_invalidate_memref_leaderboards(client->game, client, client->state.processing_memref); ++ ++ client->state.processing_memref = NULL; ++} ++ ++static uint32_t rc_client_peek_le(uint32_t address, uint32_t num_bytes, void* ud) ++{ ++ rc_client_t* client = (rc_client_t*)ud; ++ uint32_t value = 0; ++ uint32_t num_read = 0; ++ ++ /* if we know the address is out of range, and it's part of a pointer chain ++ * (processing_memref is null), don't bother processing it. */ ++ if (address > client->game->max_valid_address && !client->state.processing_memref) ++ return 0; ++ ++ if (num_bytes <= sizeof(value)) { ++ num_read = client->callbacks.read_memory(address, (uint8_t*)&value, num_bytes, client); ++ if (num_read == num_bytes) ++ return value; ++ } ++ ++ if (num_read < num_bytes) ++ rc_client_invalidate_processing_memref(client); ++ ++ return 0; ++} ++ ++static uint32_t rc_client_peek(uint32_t address, uint32_t num_bytes, void* ud) ++{ ++ rc_client_t* client = (rc_client_t*)ud; ++ uint8_t buffer[4]; ++ uint32_t num_read = 0; ++ ++ /* if we know the address is out of range, and it's part of a pointer chain ++ * (processing_memref is null), don't bother processing it. */ ++ if (address > client->game->max_valid_address && !client->state.processing_memref) ++ return 0; ++ ++ switch (num_bytes) { ++ case 1: ++ num_read = client->callbacks.read_memory(address, buffer, 1, client); ++ if (num_read == 1) ++ return buffer[0]; ++ break; ++ case 2: ++ num_read = client->callbacks.read_memory(address, buffer, 2, client); ++ if (num_read == 2) ++ return buffer[0] | (buffer[1] << 8); ++ break; ++ case 3: ++ num_read = client->callbacks.read_memory(address, buffer, 3, client); ++ if (num_read == 3) ++ return buffer[0] | (buffer[1] << 8) | (buffer[2] << 16); ++ break; ++ case 4: ++ num_read = client->callbacks.read_memory(address, buffer, 4, client); ++ if (num_read == 4) ++ return buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); ++ break; ++ default: ++ break; ++ } ++ ++ if (num_read < num_bytes) ++ rc_client_invalidate_processing_memref(client); ++ ++ return 0; ++} ++ ++void rc_client_set_legacy_peek(rc_client_t* client, int method) ++{ ++ if (method == RC_CLIENT_LEGACY_PEEK_AUTO) { ++ union { ++ uint32_t whole; ++ uint8_t parts[4]; ++ } u; ++ u.whole = 1; ++ method = (u.parts[0] == 1) ? ++ RC_CLIENT_LEGACY_PEEK_LITTLE_ENDIAN_READS : RC_CLIENT_LEGACY_PEEK_CONSTRUCTED; ++ } ++ ++ client->state.legacy_peek = (method == RC_CLIENT_LEGACY_PEEK_LITTLE_ENDIAN_READS) ? ++ rc_client_peek_le : rc_client_peek; ++} ++ ++int rc_client_is_processing_required(rc_client_t* client) ++{ ++ if (!client) ++ return 0; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->is_processing_required) ++ return client->state.external_client->is_processing_required(); ++#endif ++ ++ if (!client->game) ++ return 0; ++ ++ if (client->game->runtime.trigger_count || client->game->runtime.lboard_count) ++ return 1; ++ ++ return (client->game->runtime.richpresence && client->game->runtime.richpresence->richpresence); ++} ++ ++static void rc_client_update_memref_values(rc_client_t* client) { ++ rc_memrefs_t* memrefs = client->game->runtime.memrefs; ++ rc_memref_list_t* memref_list; ++ rc_modified_memref_list_t* modified_memref_list; ++ int invalidated_memref = 0; ++ ++ memref_list = &memrefs->memrefs; ++ do { ++ rc_memref_t* memref = memref_list->items; ++ const rc_memref_t* memref_stop = memref + memref_list->count; ++ uint32_t value; ++ ++ for (; memref < memref_stop; ++memref) { ++ if (memref->value.type == RC_VALUE_TYPE_NONE) ++ continue; ++ ++ /* if processing_memref is set, and the memory read fails, all dependent achievements will be disabled */ ++ client->state.processing_memref = memref; ++ ++ value = rc_peek_value(memref->address, memref->value.size, client->state.legacy_peek, client); ++ ++ if (client->state.processing_memref) { ++ rc_update_memref_value(&memref->value, value); ++ } ++ else { ++ /* if the peek function cleared the processing_memref, the memref was invalidated */ ++ invalidated_memref = 1; ++ } ++ } ++ ++ memref_list = memref_list->next; ++ } while (memref_list); ++ ++ client->state.processing_memref = NULL; ++ ++ modified_memref_list = &memrefs->modified_memrefs; ++ if (modified_memref_list->count) { ++ do { ++ rc_modified_memref_t* modified_memref = modified_memref_list->items; ++ const rc_modified_memref_t* modified_memref_stop = modified_memref + modified_memref_list->count; ++ ++ for (; modified_memref < modified_memref_stop; ++modified_memref) ++ rc_update_memref_value(&modified_memref->memref.value, rc_get_modified_memref_value(modified_memref, client->state.legacy_peek, client)); ++ ++ modified_memref_list = modified_memref_list->next; ++ } while (modified_memref_list); ++ } ++ ++ if (client->game->runtime.richpresence && client->game->runtime.richpresence->richpresence) ++ rc_update_values(client->game->runtime.richpresence->richpresence->values, client->state.legacy_peek, client); ++ ++ if (invalidated_memref) ++ rc_client_update_active_achievements(client->game); ++} ++ ++static void rc_client_do_frame_process_achievements(rc_client_t* client, rc_client_subset_info_t* subset) ++{ ++ rc_client_achievement_info_t* achievement = subset->achievements; ++ rc_client_achievement_info_t* stop = achievement + subset->public_.num_achievements; ++ ++ for (; achievement < stop; ++achievement) { ++ rc_trigger_t* trigger = achievement->trigger; ++ int old_state, new_state; ++ uint32_t old_measured_value; ++ ++ if (!trigger || achievement->public_.state != RC_CLIENT_ACHIEVEMENT_STATE_ACTIVE) ++ continue; ++ ++ old_measured_value = trigger->measured_value; ++ old_state = trigger->state; ++ new_state = rc_evaluate_trigger(trigger, client->state.legacy_peek, client, NULL); ++ ++ /* trigger->state doesn't actually change to RESET - RESET just serves as a notification. ++ * we don't care about that particular notification, so look at the actual state. */ ++ if (new_state == RC_TRIGGER_STATE_RESET) ++ new_state = trigger->state; ++ ++ /* if the measured value changed and the achievement hasn't triggered, show a progress indicator */ ++ if (trigger->measured_value != old_measured_value && old_measured_value != RC_MEASURED_UNKNOWN && ++ trigger->measured_value <= trigger->measured_target && ++ rc_trigger_state_active(new_state) && new_state != RC_TRIGGER_STATE_WAITING) { ++ ++ /* only show a popup for the achievement closest to triggering */ ++ float progress = (float)trigger->measured_value / (float)trigger->measured_target; ++ ++ if (trigger->measured_as_percent) { ++ /* if reporting the measured value as a percentage, only show the popup if the percentage changes */ ++ const uint32_t old_percent = (uint32_t)(((unsigned long long)old_measured_value * 100) / trigger->measured_target); ++ const uint32_t new_percent = (uint32_t)(((unsigned long long)trigger->measured_value * 100) / trigger->measured_target); ++ if (old_percent == new_percent) ++ progress = -1.0; ++ } ++ ++ if (progress > client->game->progress_tracker.progress) { ++ client->game->progress_tracker.progress = progress; ++ client->game->progress_tracker.achievement = achievement; ++ client->game->pending_events |= RC_CLIENT_GAME_PENDING_EVENT_PROGRESS_TRACKER; ++ subset->pending_events |= RC_CLIENT_SUBSET_PENDING_EVENT_ACHIEVEMENT; ++ achievement->pending_events |= RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_UPDATE; ++ } ++ } ++ ++ /* if the state hasn't changed, there won't be any events raised */ ++ if (new_state == old_state) ++ continue; ++ ++ /* raise a CHALLENGE_INDICATOR_HIDE event when changing from PRIMED to anything else */ ++ if (old_state == RC_TRIGGER_STATE_PRIMED) ++ achievement->pending_events |= RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_CHALLENGE_INDICATOR_HIDE; ++ ++ /* raise events for each of the possible new states */ ++ if (new_state == RC_TRIGGER_STATE_TRIGGERED) ++ achievement->pending_events |= RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_TRIGGERED; ++ else if (new_state == RC_TRIGGER_STATE_PRIMED) ++ achievement->pending_events |= RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_CHALLENGE_INDICATOR_SHOW; ++ ++ subset->pending_events |= RC_CLIENT_SUBSET_PENDING_EVENT_ACHIEVEMENT; ++ } ++} ++ ++static void rc_client_hide_progress_tracker(rc_client_t* client, rc_client_game_info_t* game) ++{ ++ /* ASSERT: this should only be called if the mutex is held */ ++ ++ if (game->progress_tracker.hide_callback && ++ game->progress_tracker.hide_callback->when && ++ game->progress_tracker.action == RC_CLIENT_PROGRESS_TRACKER_ACTION_NONE) { ++ rc_client_reschedule_callback(client, game->progress_tracker.hide_callback, 0); ++ game->progress_tracker.action = RC_CLIENT_PROGRESS_TRACKER_ACTION_HIDE; ++ game->pending_events |= RC_CLIENT_GAME_PENDING_EVENT_PROGRESS_TRACKER; ++ } ++} ++ ++static void rc_client_progress_tracker_timer_elapsed(rc_client_scheduled_callback_data_t* callback_data, rc_client_t* client, rc_clock_t now) ++{ ++ rc_client_event_t client_event; ++ memset(&client_event, 0, sizeof(client_event)); ++ ++ (void)callback_data; ++ (void)now; ++ ++ rc_mutex_lock(&client->state.mutex); ++ if (client->game->progress_tracker.action == RC_CLIENT_PROGRESS_TRACKER_ACTION_NONE) { ++ client->game->progress_tracker.hide_callback->when = 0; ++ client_event.type = RC_CLIENT_EVENT_ACHIEVEMENT_PROGRESS_INDICATOR_HIDE; ++ } ++ rc_mutex_unlock(&client->state.mutex); ++ ++ if (client_event.type) ++ client->callbacks.event_handler(&client_event, client); ++} ++ ++static void rc_client_do_frame_update_progress_tracker(rc_client_t* client, rc_client_game_info_t* game) ++{ ++ /* ASSERT: this should only be called if the mutex is held */ ++ ++ if (!game->progress_tracker.hide_callback) { ++ game->progress_tracker.hide_callback = (rc_client_scheduled_callback_data_t*) ++ rc_buffer_alloc(&game->buffer, sizeof(rc_client_scheduled_callback_data_t)); ++ memset(game->progress_tracker.hide_callback, 0, sizeof(rc_client_scheduled_callback_data_t)); ++ game->progress_tracker.hide_callback->callback = rc_client_progress_tracker_timer_elapsed; ++ } ++ ++ if (game->progress_tracker.hide_callback->when == 0) ++ game->progress_tracker.action = RC_CLIENT_PROGRESS_TRACKER_ACTION_SHOW; ++ else ++ game->progress_tracker.action = RC_CLIENT_PROGRESS_TRACKER_ACTION_UPDATE; ++ ++ rc_client_reschedule_callback(client, game->progress_tracker.hide_callback, ++ client->callbacks.get_time_millisecs(client) + 2 * 1000); ++} ++ ++static void rc_client_raise_progress_tracker_events(rc_client_t* client, rc_client_game_info_t* game) ++{ ++ rc_client_event_t client_event; ++ ++ memset(&client_event, 0, sizeof(client_event)); ++ ++ switch (game->progress_tracker.action) { ++ case RC_CLIENT_PROGRESS_TRACKER_ACTION_SHOW: ++ client_event.type = RC_CLIENT_EVENT_ACHIEVEMENT_PROGRESS_INDICATOR_SHOW; ++ break; ++ case RC_CLIENT_PROGRESS_TRACKER_ACTION_HIDE: ++ client_event.type = RC_CLIENT_EVENT_ACHIEVEMENT_PROGRESS_INDICATOR_HIDE; ++ break; ++ default: ++ client_event.type = RC_CLIENT_EVENT_ACHIEVEMENT_PROGRESS_INDICATOR_UPDATE; ++ break; ++ } ++ game->progress_tracker.action = RC_CLIENT_PROGRESS_TRACKER_ACTION_NONE; ++ ++ client_event.achievement = &game->progress_tracker.achievement->public_; ++ client->callbacks.event_handler(&client_event, client); ++} ++ ++static void rc_client_raise_achievement_events(rc_client_t* client, rc_client_subset_info_t* subset) ++{ ++ rc_client_achievement_info_t* achievement = subset->achievements; ++ rc_client_achievement_info_t* stop = achievement + subset->public_.num_achievements; ++ rc_client_event_t client_event; ++ time_t recent_unlock_time = 0; ++ ++ memset(&client_event, 0, sizeof(client_event)); ++ ++ for (; achievement < stop; ++achievement) { ++ if (achievement->pending_events == RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_NONE) ++ continue; ++ ++ /* kick off award achievement request first */ ++ if (achievement->pending_events & RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_TRIGGERED) { ++ rc_client_award_achievement(client, achievement); ++ client->game->pending_events |= RC_CLIENT_GAME_PENDING_EVENT_UPDATE_ACTIVE_ACHIEVEMENTS; ++ } ++ ++ /* update display state */ ++ if (recent_unlock_time == 0) ++ recent_unlock_time = time(NULL) - RC_CLIENT_RECENT_UNLOCK_DELAY_SECONDS; ++ rc_client_update_achievement_display_information(client, achievement, recent_unlock_time); ++ ++ /* raise events */ ++ client_event.achievement = &achievement->public_; ++ ++ if (achievement->pending_events & RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_CHALLENGE_INDICATOR_HIDE) { ++ client_event.type = RC_CLIENT_EVENT_ACHIEVEMENT_CHALLENGE_INDICATOR_HIDE; ++ client->callbacks.event_handler(&client_event, client); ++ } ++ else if (achievement->pending_events & RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_CHALLENGE_INDICATOR_SHOW) { ++ client_event.type = RC_CLIENT_EVENT_ACHIEVEMENT_CHALLENGE_INDICATOR_SHOW; ++ client->callbacks.event_handler(&client_event, client); ++ } ++ ++ if (achievement->pending_events & RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_TRIGGERED) { ++ client_event.type = RC_CLIENT_EVENT_ACHIEVEMENT_TRIGGERED; ++ client->callbacks.event_handler(&client_event, client); ++ } ++ ++ /* clear pending flags */ ++ achievement->pending_events = RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_NONE; ++ } ++} ++ ++static void rc_client_raise_mastery_event(rc_client_t* client, rc_client_subset_info_t* subset) ++{ ++ rc_client_event_t client_event; ++ ++ memset(&client_event, 0, sizeof(client_event)); ++ client_event.subset = &subset->public_; ++ ++ if (subset == client->game->subsets) ++ client_event.type = RC_CLIENT_EVENT_GAME_COMPLETED; ++ else ++ client_event.type = RC_CLIENT_EVENT_SUBSET_COMPLETED; ++ ++ subset->mastery = RC_CLIENT_MASTERY_STATE_SHOWN; ++ ++ client->callbacks.event_handler(&client_event, client); ++} ++ ++static void rc_client_do_frame_process_leaderboards(rc_client_t* client, rc_client_subset_info_t* subset) ++{ ++ rc_client_leaderboard_info_t* leaderboard = subset->leaderboards; ++ rc_client_leaderboard_info_t* stop = leaderboard + subset->public_.num_leaderboards; ++ ++ for (; leaderboard < stop; ++leaderboard) { ++ rc_lboard_t* lboard = leaderboard->lboard; ++ int old_state, new_state; ++ ++ switch (leaderboard->public_.state) { ++ case RC_CLIENT_LEADERBOARD_STATE_INACTIVE: ++ case RC_CLIENT_LEADERBOARD_STATE_DISABLED: ++ continue; ++ ++ default: ++ if (!lboard) ++ continue; ++ ++ break; ++ } ++ ++ old_state = lboard->state; ++ new_state = rc_evaluate_lboard(lboard, &leaderboard->value, client->state.legacy_peek, client, NULL); ++ ++ switch (new_state) { ++ case RC_LBOARD_STATE_STARTED: /* leaderboard is running */ ++ if (old_state != RC_LBOARD_STATE_STARTED) { ++ leaderboard->public_.state = RC_CLIENT_LEADERBOARD_STATE_TRACKING; ++ leaderboard->pending_events |= RC_CLIENT_LEADERBOARD_PENDING_EVENT_STARTED; ++ rc_client_allocate_leaderboard_tracker(client->game, leaderboard); ++ } ++ else { ++ rc_client_update_leaderboard_tracker(client->game, leaderboard); ++ } ++ break; ++ ++ case RC_LBOARD_STATE_CANCELED: ++ if (old_state != RC_LBOARD_STATE_CANCELED) { ++ leaderboard->public_.state = RC_CLIENT_LEADERBOARD_STATE_ACTIVE; ++ leaderboard->pending_events |= RC_CLIENT_LEADERBOARD_PENDING_EVENT_FAILED; ++ rc_client_release_leaderboard_tracker(client->game, leaderboard); ++ } ++ break; ++ ++ case RC_LBOARD_STATE_TRIGGERED: ++ if (old_state != RC_RUNTIME_EVENT_LBOARD_TRIGGERED) { ++ leaderboard->public_.state = RC_CLIENT_LEADERBOARD_STATE_ACTIVE; ++ leaderboard->pending_events |= RC_CLIENT_LEADERBOARD_PENDING_EVENT_SUBMITTED; ++ ++ if (old_state != RC_LBOARD_STATE_STARTED) ++ rc_client_allocate_leaderboard_tracker(client->game, leaderboard); ++ else ++ rc_client_update_leaderboard_tracker(client->game, leaderboard); ++ ++ rc_client_release_leaderboard_tracker(client->game, leaderboard); ++ } ++ break; ++ } ++ ++ if (leaderboard->pending_events) ++ subset->pending_events |= RC_CLIENT_SUBSET_PENDING_EVENT_LEADERBOARD; ++ } ++} ++ ++static void rc_client_raise_leaderboard_tracker_events(rc_client_t* client, rc_client_game_info_t* game) ++{ ++ rc_client_leaderboard_tracker_info_t* tracker = game->leaderboard_trackers; ++ rc_client_event_t client_event; ++ ++ memset(&client_event, 0, sizeof(client_event)); ++ ++ tracker = game->leaderboard_trackers; ++ for (; tracker; tracker = tracker->next) { ++ if (tracker->pending_events == RC_CLIENT_LEADERBOARD_TRACKER_PENDING_EVENT_NONE) ++ continue; ++ ++ client_event.leaderboard_tracker = &tracker->public_; ++ ++ /* update display text for new trackers or updated trackers */ ++ if (tracker->pending_events & (RC_CLIENT_LEADERBOARD_TRACKER_PENDING_EVENT_SHOW | RC_CLIENT_LEADERBOARD_TRACKER_PENDING_EVENT_UPDATE)) ++ rc_format_value(tracker->public_.display, sizeof(tracker->public_.display), tracker->raw_value, tracker->format); ++ ++ if (tracker->pending_events & RC_CLIENT_LEADERBOARD_TRACKER_PENDING_EVENT_HIDE) { ++ if (tracker->pending_events & RC_CLIENT_LEADERBOARD_TRACKER_PENDING_EVENT_SHOW) { ++ /* request to show and hide in the same frame - ignore the event */ ++ } ++ else { ++ client_event.type = RC_CLIENT_EVENT_LEADERBOARD_TRACKER_HIDE; ++ client->callbacks.event_handler(&client_event, client); ++ } ++ } ++ else if (tracker->pending_events & RC_CLIENT_LEADERBOARD_TRACKER_PENDING_EVENT_SHOW) { ++ client_event.type = RC_CLIENT_EVENT_LEADERBOARD_TRACKER_SHOW; ++ client->callbacks.event_handler(&client_event, client); ++ } ++ else if (tracker->pending_events & RC_CLIENT_LEADERBOARD_TRACKER_PENDING_EVENT_UPDATE) { ++ client_event.type = RC_CLIENT_EVENT_LEADERBOARD_TRACKER_UPDATE; ++ client->callbacks.event_handler(&client_event, client); ++ } ++ ++ tracker->pending_events = RC_CLIENT_LEADERBOARD_TRACKER_PENDING_EVENT_NONE; ++ } ++} ++ ++static void rc_client_raise_leaderboard_events(rc_client_t* client, rc_client_subset_info_t* subset) ++{ ++ rc_client_leaderboard_info_t* leaderboard = subset->leaderboards; ++ rc_client_leaderboard_info_t* leaderboard_stop = leaderboard + subset->public_.num_leaderboards; ++ rc_client_event_t client_event; ++ ++ memset(&client_event, 0, sizeof(client_event)); ++ ++ for (; leaderboard < leaderboard_stop; ++leaderboard) { ++ if (leaderboard->pending_events == RC_CLIENT_LEADERBOARD_PENDING_EVENT_NONE) ++ continue; ++ ++ client_event.leaderboard = &leaderboard->public_; ++ ++ if (leaderboard->pending_events & RC_CLIENT_LEADERBOARD_PENDING_EVENT_FAILED) { ++ RC_CLIENT_LOG_VERBOSE_FORMATTED(client, "Leaderboard %u canceled: %s", leaderboard->public_.id, leaderboard->public_.title); ++ client_event.type = RC_CLIENT_EVENT_LEADERBOARD_FAILED; ++ client->callbacks.event_handler(&client_event, client); ++ } ++ else if (leaderboard->pending_events & RC_CLIENT_LEADERBOARD_PENDING_EVENT_SUBMITTED) { ++ /* kick off submission request before raising event */ ++ rc_client_submit_leaderboard_entry(client, leaderboard); ++ ++ client_event.type = RC_CLIENT_EVENT_LEADERBOARD_SUBMITTED; ++ client->callbacks.event_handler(&client_event, client); ++ } ++ else if (leaderboard->pending_events & RC_CLIENT_LEADERBOARD_PENDING_EVENT_STARTED) { ++ RC_CLIENT_LOG_VERBOSE_FORMATTED(client, "Leaderboard %u started: %s", leaderboard->public_.id, leaderboard->public_.title); ++ client_event.type = RC_CLIENT_EVENT_LEADERBOARD_STARTED; ++ client->callbacks.event_handler(&client_event, client); ++ } ++ ++ leaderboard->pending_events = RC_CLIENT_LEADERBOARD_PENDING_EVENT_NONE; ++ } ++} ++ ++static void rc_client_reset_pending_events(rc_client_t* client) ++{ ++ rc_client_subset_info_t* subset; ++ ++ client->game->pending_events = RC_CLIENT_GAME_PENDING_EVENT_NONE; ++ ++ for (subset = client->game->subsets; subset; subset = subset->next) ++ subset->pending_events = RC_CLIENT_SUBSET_PENDING_EVENT_NONE; ++} ++ ++static void rc_client_subset_raise_pending_events(rc_client_t* client, rc_client_subset_info_t* subset) ++{ ++ /* raise any pending achievement events */ ++ if (subset->pending_events & RC_CLIENT_SUBSET_PENDING_EVENT_ACHIEVEMENT) ++ rc_client_raise_achievement_events(client, subset); ++ ++ /* raise any pending leaderboard events */ ++ if (subset->pending_events & RC_CLIENT_SUBSET_PENDING_EVENT_LEADERBOARD) ++ rc_client_raise_leaderboard_events(client, subset); ++ ++ /* raise mastery event if pending */ ++ if (subset->mastery == RC_CLIENT_MASTERY_STATE_PENDING) ++ rc_client_raise_mastery_event(client, subset); ++} ++ ++static void rc_client_raise_pending_events(rc_client_t* client, rc_client_game_info_t* game) ++{ ++ rc_client_subset_info_t* subset; ++ ++ /* raise tracker events before leaderboard events so formatted values are updated for leaderboard events */ ++ if (game->pending_events & RC_CLIENT_GAME_PENDING_EVENT_LEADERBOARD_TRACKER) ++ rc_client_raise_leaderboard_tracker_events(client, game); ++ ++ for (subset = game->subsets; subset; subset = subset->next) ++ rc_client_subset_raise_pending_events(client, subset); ++ ++ /* raise progress tracker events after achievement events so formatted values are updated for tracker event */ ++ if (game->pending_events & RC_CLIENT_GAME_PENDING_EVENT_PROGRESS_TRACKER) ++ rc_client_raise_progress_tracker_events(client, game); ++ ++ /* if any achievements were unlocked, resync the active achievements list */ ++ if (game->pending_events & RC_CLIENT_GAME_PENDING_EVENT_UPDATE_ACTIVE_ACHIEVEMENTS) { ++ rc_mutex_lock(&client->state.mutex); ++ rc_client_update_active_achievements(game); ++ rc_mutex_unlock(&client->state.mutex); ++ } ++ ++ game->pending_events = RC_CLIENT_GAME_PENDING_EVENT_NONE; ++} ++ ++void rc_client_do_frame(rc_client_t* client) ++{ ++ if (!client) ++ return; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->do_frame) { ++ client->state.external_client->do_frame(); ++ return; ++ } ++#endif ++ ++ if (client->game && !client->game->waiting_for_reset) { ++ rc_runtime_richpresence_t* richpresence; ++ rc_client_subset_info_t* subset; ++ ++ rc_mutex_lock(&client->state.mutex); ++ ++ rc_client_reset_pending_events(client); ++ ++ rc_client_update_memref_values(client); ++ ++ client->game->progress_tracker.progress = 0.0; ++ for (subset = client->game->subsets; subset; subset = subset->next) { ++ if (subset->active) ++ rc_client_do_frame_process_achievements(client, subset); ++ } ++ if (client->game->pending_events & RC_CLIENT_GAME_PENDING_EVENT_PROGRESS_TRACKER) ++ rc_client_do_frame_update_progress_tracker(client, client->game); ++ ++ if (client->state.hardcore || client->state.allow_leaderboards_in_softcore) { ++ for (subset = client->game->subsets; subset; subset = subset->next) { ++ if (subset->active) ++ rc_client_do_frame_process_leaderboards(client, subset); ++ } ++ } ++ ++ richpresence = client->game->runtime.richpresence; ++ if (richpresence && richpresence->richpresence) ++ rc_update_richpresence_internal(richpresence->richpresence, client->state.legacy_peek, client); ++ ++ rc_mutex_unlock(&client->state.mutex); ++ ++ rc_client_raise_pending_events(client, client->game); ++ ++ ++client->state.frames_processed; ++ } ++ ++ /* we've processed a frame. if there's a pause delay in effect, process it */ ++ if (client->state.unpaused_frame_decay > 0) { ++ client->state.unpaused_frame_decay--; ++ ++ if (client->state.unpaused_frame_decay == 0 && ++ client->state.required_unpaused_frames > RC_MINIMUM_UNPAUSED_FRAMES) { ++ /* the full decay has elapsed and a penalty still exists. ++ * lower the penalty and reset the decay counter */ ++ client->state.required_unpaused_frames >>= 1; ++ ++ if (client->state.required_unpaused_frames <= RC_MINIMUM_UNPAUSED_FRAMES) ++ client->state.required_unpaused_frames = RC_MINIMUM_UNPAUSED_FRAMES; ++ ++ client->state.unpaused_frame_decay = ++ client->state.required_unpaused_frames * (RC_PAUSE_DECAY_MULTIPLIER - 1) - 1; ++ } ++ } ++ ++ rc_client_idle(client); ++} ++ ++void rc_client_idle(rc_client_t* client) ++{ ++ rc_client_scheduled_callback_data_t* scheduled_callback; ++ ++ if (!client) ++ return; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->idle) { ++ client->state.external_client->idle(); ++ return; ++ } ++#endif ++ ++ scheduled_callback = client->state.scheduled_callbacks; ++ if (scheduled_callback) { ++ const rc_clock_t now = client->callbacks.get_time_millisecs(client); ++ ++ do { ++ rc_mutex_lock(&client->state.mutex); ++ scheduled_callback = client->state.scheduled_callbacks; ++ if (scheduled_callback) { ++ if (scheduled_callback->when > now) { ++ /* not time for next callback yet, ignore it */ ++ scheduled_callback = NULL; ++ } ++ else { ++ /* remove the callback from the queue while we process it. callback can requeue if desired */ ++ client->state.scheduled_callbacks = scheduled_callback->next; ++ scheduled_callback->next = NULL; ++ } ++ } ++ rc_mutex_unlock(&client->state.mutex); ++ ++ if (!scheduled_callback) ++ break; ++ ++ scheduled_callback->callback(scheduled_callback, client, now); ++ } while (1); ++ } ++ ++ if (client->state.disconnect & ~RC_CLIENT_DISCONNECT_VISIBLE) ++ rc_client_raise_disconnect_events(client); ++} ++ ++void rc_client_schedule_callback(rc_client_t* client, rc_client_scheduled_callback_data_t* scheduled_callback) ++{ ++ rc_client_scheduled_callback_data_t** last; ++ rc_client_scheduled_callback_data_t* next; ++ ++ rc_mutex_lock(&client->state.mutex); ++ ++ last = &client->state.scheduled_callbacks; ++ do { ++ next = *last; ++ if (!next || scheduled_callback->when < next->when) { ++ scheduled_callback->next = next; ++ *last = scheduled_callback; ++ break; ++ } ++ ++ last = &next->next; ++ } while (1); ++ ++ rc_mutex_unlock(&client->state.mutex); ++} ++ ++static void rc_client_reschedule_callback(rc_client_t* client, ++ rc_client_scheduled_callback_data_t* callback, rc_clock_t when) ++{ ++ rc_client_scheduled_callback_data_t** last; ++ rc_client_scheduled_callback_data_t* next; ++ ++ /* ASSERT: this should only be called if the mutex is held */ ++ ++ callback->when = when; ++ ++ last = &client->state.scheduled_callbacks; ++ do { ++ next = *last; ++ ++ if (next == callback) { ++ if (when == 0) { ++ /* request to unschedule the callback */ ++ *last = next->next; ++ next->next = NULL; ++ break; ++ } ++ ++ if (!next->next) { ++ /* end of list, just append it */ ++ break; ++ } ++ ++ if (when < next->next->when) { ++ /* already in the correct place */ ++ break; ++ } ++ ++ /* remove from current position - will insert later */ ++ *last = next->next; ++ next->next = NULL; ++ continue; ++ } ++ ++ if (!next || (when < next->when && when != 0)) { ++ /* insert here */ ++ callback->next = next; ++ *last = callback; ++ break; ++ } ++ ++ last = &next->next; ++ } while (1); ++} ++ ++static void rc_client_reset_richpresence(rc_client_t* client) ++{ ++ rc_runtime_richpresence_t* richpresence = client->game->runtime.richpresence; ++ if (richpresence && richpresence->richpresence) ++ rc_reset_richpresence(richpresence->richpresence); ++} ++ ++static void rc_client_reset_variables(rc_client_t* client) ++{ ++ if (client->game->runtime.richpresence && client->game->runtime.richpresence->richpresence) ++ rc_reset_values(client->game->runtime.richpresence->richpresence->values); ++} ++ ++static void rc_client_reset_all(rc_client_t* client) ++{ ++ rc_client_reset_achievements(client); ++ rc_client_reset_leaderboards(client); ++ rc_client_reset_richpresence(client); ++ rc_client_reset_variables(client); ++} ++ ++void rc_client_reset(rc_client_t* client) ++{ ++ rc_client_game_hash_t* game_hash; ++ if (!client) ++ return; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->reset) { ++ client->state.external_client->reset(); ++ return; ++ } ++#endif ++ ++ if (!client->game) ++ return; ++ ++ game_hash = rc_client_find_game_hash(client, client->game->public_.hash); ++ if (game_hash && game_hash->game_id != client->game->public_.id) { ++ /* current media is not for loaded game. unload game */ ++ RC_CLIENT_LOG_WARN_FORMATTED(client, "Disabling runtime. Reset with non-game media loaded: %u (%s)", ++ (game_hash->game_id == RC_CLIENT_UNKNOWN_GAME_ID) ? 0 : game_hash->game_id, game_hash->hash); ++ rc_client_unload_game(client); ++ return; ++ } ++ ++ RC_CLIENT_LOG_INFO(client, "Resetting runtime"); ++ ++ rc_mutex_lock(&client->state.mutex); ++ ++ client->game->waiting_for_reset = 0; ++ rc_client_reset_pending_events(client); ++ ++ rc_client_hide_progress_tracker(client, client->game); ++ rc_client_reset_all(client); ++ ++ rc_mutex_unlock(&client->state.mutex); ++ ++ rc_client_raise_pending_events(client, client->game); ++} ++ ++int rc_client_can_pause(rc_client_t* client, uint32_t* frames_remaining) ++{ ++ if (!client) ++ return 1; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->can_pause) ++ return client->state.external_client->can_pause(frames_remaining); ++#endif ++ ++ if (frames_remaining) ++ *frames_remaining = 0; ++ ++ /* pause is always allowed in softcore */ ++ if (!rc_client_get_hardcore_enabled(client)) ++ return 1; ++ ++ /* a full decay means we haven't processed any frames since the last time this was called. */ ++ if (client->state.unpaused_frame_decay == client->state.required_unpaused_frames * RC_PAUSE_DECAY_MULTIPLIER) ++ return 1; ++ ++ /* if less than RC_MINIMUM_UNPAUSED_FRAMES have been processed, don't allow the pause */ ++ if (client->state.unpaused_frame_decay > client->state.required_unpaused_frames * (RC_PAUSE_DECAY_MULTIPLIER - 1)) { ++ if (frames_remaining) { ++ *frames_remaining = client->state.unpaused_frame_decay - ++ client->state.required_unpaused_frames * (RC_PAUSE_DECAY_MULTIPLIER - 1); ++ } ++ return 0; ++ } ++ ++ /* we're going to allow the emulator to pause. calculate how many frames are needed before the next ++ * pause will be allowed. */ ++ ++ if (client->state.unpaused_frame_decay > 0) { ++ /* The user has paused within the decay window. Require a longer ++ * run of unpaused frames before allowing the next pause */ ++ if (client->state.required_unpaused_frames < 5 * 60) /* don't make delay longer then 5 seconds */ ++ client->state.required_unpaused_frames += RC_MINIMUM_UNPAUSED_FRAMES; ++ } ++ ++ /* require multiple unpaused_frames windows to decay the penalty */ ++ client->state.unpaused_frame_decay = client->state.required_unpaused_frames * RC_PAUSE_DECAY_MULTIPLIER; ++ ++ return 1; ++} ++ ++size_t rc_client_progress_size(rc_client_t* client) ++{ ++ size_t result; ++ ++ if (!client) ++ return 0; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->progress_size) ++ return client->state.external_client->progress_size(); ++#endif ++ ++ if (!rc_client_is_game_loaded(client)) ++ return 0; ++ ++ rc_mutex_lock(&client->state.mutex); ++ result = rc_runtime_progress_size(&client->game->runtime, NULL); ++ rc_mutex_unlock(&client->state.mutex); ++ ++ return result; ++} ++ ++int rc_client_serialize_progress(rc_client_t* client, uint8_t* buffer) ++{ ++ return rc_client_serialize_progress_sized(client, buffer, 0xFFFFFFFF); ++} ++ ++int rc_client_serialize_progress_sized(rc_client_t* client, uint8_t* buffer, size_t buffer_size) ++{ ++ int result; ++ ++ if (!client) ++ return RC_NO_GAME_LOADED; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->serialize_progress) ++ return client->state.external_client->serialize_progress(buffer, buffer_size); ++#endif ++ ++ if (!rc_client_is_game_loaded(client)) ++ return RC_NO_GAME_LOADED; ++ ++ if (!buffer) ++ return RC_INVALID_STATE; ++ ++ rc_mutex_lock(&client->state.mutex); ++ result = rc_runtime_serialize_progress_sized(buffer, (uint32_t)buffer_size, &client->game->runtime, NULL); ++ rc_mutex_unlock(&client->state.mutex); ++ ++ return result; ++} ++ ++static void rc_client_subset_before_deserialize_progress(rc_client_subset_info_t* subset) ++{ ++ rc_client_achievement_info_t* achievement; ++ rc_client_achievement_info_t* achievement_stop; ++ rc_client_leaderboard_info_t* leaderboard; ++ rc_client_leaderboard_info_t* leaderboard_stop; ++ ++ /* flag any visible challenge indicators to be hidden */ ++ achievement = subset->achievements; ++ achievement_stop = achievement + subset->public_.num_achievements; ++ for (; achievement < achievement_stop; ++achievement) { ++ rc_trigger_t* trigger = achievement->trigger; ++ if (trigger && trigger->state == RC_TRIGGER_STATE_PRIMED && ++ achievement->public_.state == RC_CLIENT_ACHIEVEMENT_STATE_ACTIVE) { ++ achievement->pending_events |= RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_CHALLENGE_INDICATOR_HIDE; ++ subset->pending_events |= RC_CLIENT_SUBSET_PENDING_EVENT_ACHIEVEMENT; ++ } ++ } ++ ++ /* flag any visible trackers to be hidden */ ++ leaderboard = subset->leaderboards; ++ leaderboard_stop = leaderboard + subset->public_.num_leaderboards; ++ for (; leaderboard < leaderboard_stop; ++leaderboard) { ++ rc_lboard_t* lboard = leaderboard->lboard; ++ if (lboard && lboard->state == RC_LBOARD_STATE_STARTED && ++ leaderboard->public_.state == RC_CLIENT_LEADERBOARD_STATE_TRACKING) { ++ leaderboard->pending_events |= RC_CLIENT_LEADERBOARD_PENDING_EVENT_FAILED; ++ subset->pending_events |= RC_CLIENT_SUBSET_PENDING_EVENT_LEADERBOARD; ++ } ++ } ++} ++ ++static void rc_client_subset_after_deserialize_progress(rc_client_game_info_t* game, rc_client_subset_info_t* subset) ++{ ++ rc_client_achievement_info_t* achievement; ++ rc_client_achievement_info_t* achievement_stop; ++ rc_client_leaderboard_info_t* leaderboard; ++ rc_client_leaderboard_info_t* leaderboard_stop; ++ ++ /* flag any challenge indicators that should be shown */ ++ achievement = subset->achievements; ++ achievement_stop = achievement + subset->public_.num_achievements; ++ for (; achievement < achievement_stop; ++achievement) { ++ rc_trigger_t* trigger = achievement->trigger; ++ if (!trigger || achievement->public_.state != RC_CLIENT_ACHIEVEMENT_STATE_ACTIVE) ++ continue; ++ ++ if (trigger->state == RC_TRIGGER_STATE_PRIMED) { ++ /* if it's already shown, just keep it. otherwise flag it to be shown */ ++ if (achievement->pending_events & RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_CHALLENGE_INDICATOR_HIDE) { ++ achievement->pending_events &= ~RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_CHALLENGE_INDICATOR_HIDE; ++ } ++ else { ++ achievement->pending_events |= RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_CHALLENGE_INDICATOR_SHOW; ++ subset->pending_events |= RC_CLIENT_SUBSET_PENDING_EVENT_ACHIEVEMENT; ++ } ++ } ++ /* ASSERT: only active achievements are serialized, so we don't have to worry about ++ * deserialization deactiving them. */ ++ } ++ ++ /* flag any trackers that need to be shown */ ++ leaderboard = subset->leaderboards; ++ leaderboard_stop = leaderboard + subset->public_.num_leaderboards; ++ for (; leaderboard < leaderboard_stop; ++leaderboard) { ++ rc_lboard_t* lboard = leaderboard->lboard; ++ if (!lboard || ++ leaderboard->public_.state == RC_CLIENT_LEADERBOARD_STATE_INACTIVE || ++ leaderboard->public_.state == RC_CLIENT_LEADERBOARD_STATE_DISABLED) ++ continue; ++ ++ if (lboard->state == RC_LBOARD_STATE_STARTED) { ++ leaderboard->value = (int)lboard->value.value.value; ++ leaderboard->public_.state = RC_CLIENT_LEADERBOARD_STATE_TRACKING; ++ ++ /* if it's already being tracked, just update tracker. otherwise, allocate one */ ++ if (leaderboard->pending_events & RC_CLIENT_LEADERBOARD_PENDING_EVENT_FAILED) { ++ leaderboard->pending_events &= ~RC_CLIENT_LEADERBOARD_PENDING_EVENT_FAILED; ++ rc_client_update_leaderboard_tracker(game, leaderboard); ++ } ++ else { ++ rc_client_allocate_leaderboard_tracker(game, leaderboard); ++ } ++ } ++ else if (leaderboard->pending_events & RC_CLIENT_LEADERBOARD_PENDING_EVENT_FAILED) { ++ /* deallocate the tracker (don't actually raise the failed event) */ ++ leaderboard->pending_events &= ~RC_CLIENT_LEADERBOARD_PENDING_EVENT_FAILED; ++ leaderboard->public_.state = RC_CLIENT_LEADERBOARD_STATE_ACTIVE; ++ rc_client_release_leaderboard_tracker(game, leaderboard); ++ } ++ } ++} ++ ++int rc_client_deserialize_progress(rc_client_t* client, const uint8_t* serialized) ++{ ++ return rc_client_deserialize_progress_sized(client, serialized, 0xFFFFFFFF); ++} ++ ++int rc_client_deserialize_progress_sized(rc_client_t* client, const uint8_t* serialized, size_t serialized_size) ++{ ++ rc_client_subset_info_t* subset; ++ int result; ++ ++ if (!client) ++ return RC_NO_GAME_LOADED; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->deserialize_progress) ++ return client->state.external_client->deserialize_progress(serialized, serialized_size); ++#endif ++ ++ if (!rc_client_is_game_loaded(client)) ++ return RC_NO_GAME_LOADED; ++ ++ rc_mutex_lock(&client->state.mutex); ++ ++ rc_client_reset_pending_events(client); ++ ++ for (subset = client->game->subsets; subset; subset = subset->next) ++ rc_client_subset_before_deserialize_progress(subset); ++ ++ rc_client_hide_progress_tracker(client, client->game); ++ ++ if (!serialized) { ++ rc_client_reset_all(client); ++ result = RC_OK; ++ } ++ else { ++ result = rc_runtime_deserialize_progress_sized(&client->game->runtime, serialized, (uint32_t)serialized_size, NULL); ++ } ++ ++ for (subset = client->game->subsets; subset; subset = subset->next) ++ rc_client_subset_after_deserialize_progress(client->game, subset); ++ ++ rc_mutex_unlock(&client->state.mutex); ++ ++ rc_client_raise_pending_events(client, client->game); ++ ++ return result; ++} ++ ++/* ===== Toggles ===== */ ++ ++static void rc_client_enable_hardcore(rc_client_t* client) ++{ ++ client->state.hardcore = 1; ++ ++ if (client->game) { ++ rc_client_toggle_hardcore_achievements(client->game, client, RC_CLIENT_ACHIEVEMENT_UNLOCKED_HARDCORE); ++ rc_client_activate_leaderboards(client->game, client); ++ ++ /* disable processing until the client acknowledges the reset event by calling rc_runtime_reset() */ ++ RC_CLIENT_LOG_INFO(client, "Hardcore enabled, waiting for reset"); ++ client->game->waiting_for_reset = 1; ++ } ++ else { ++ RC_CLIENT_LOG_INFO(client, "Hardcore enabled"); ++ } ++} ++ ++static void rc_client_disable_hardcore(rc_client_t* client) ++{ ++ client->state.hardcore = 0; ++ RC_CLIENT_LOG_INFO(client, "Hardcore disabled"); ++ ++ if (client->game) { ++ rc_client_toggle_hardcore_achievements(client->game, client, RC_CLIENT_ACHIEVEMENT_UNLOCKED_SOFTCORE); ++ ++ if (!client->state.allow_leaderboards_in_softcore) ++ rc_client_deactivate_leaderboards(client->game, client); ++ } ++} ++ ++void rc_client_set_hardcore_enabled(rc_client_t* client, int enabled) ++{ ++ int changed = 0; ++ ++ if (!client) ++ return; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->get_hardcore_enabled) { ++ client->state.external_client->set_hardcore_enabled(enabled); ++ return; ++ } ++#endif ++ ++ rc_mutex_lock(&client->state.mutex); ++ ++ enabled = enabled ? 1 : 0; ++ if (client->state.hardcore != enabled) { ++ if (enabled) ++ rc_client_enable_hardcore(client); ++ else ++ rc_client_disable_hardcore(client); ++ ++ changed = 1; ++ } ++ ++ rc_mutex_unlock(&client->state.mutex); ++ ++ /* events must be raised outside of lock */ ++ if (changed && client->game) { ++ if (enabled) { ++ /* if enabling hardcore, notify client that a reset is requested */ ++ if (client->game->waiting_for_reset) { ++ rc_client_event_t client_event; ++ memset(&client_event, 0, sizeof(client_event)); ++ client_event.type = RC_CLIENT_EVENT_RESET; ++ client->callbacks.event_handler(&client_event, client); ++ } ++ } ++ else { ++ /* if disabling hardcore, leaderboards will be deactivated. raise events for hiding trackers */ ++ rc_client_raise_pending_events(client, client->game); ++ } ++ } ++} ++ ++int rc_client_get_hardcore_enabled(const rc_client_t* client) ++{ ++ if (!client) ++ return 0; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->get_hardcore_enabled) ++ return client->state.external_client->get_hardcore_enabled(); ++#endif ++ ++ return client->state.hardcore; ++} ++ ++void rc_client_set_unofficial_enabled(rc_client_t* client, int enabled) ++{ ++ if (!client) ++ return; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->set_unofficial_enabled) { ++ client->state.external_client->set_unofficial_enabled(enabled); ++ return; ++ } ++#endif ++ ++ RC_CLIENT_LOG_INFO_FORMATTED(client, "Unofficial %s", enabled ? "enabled" : "disabled"); ++ client->state.unofficial_enabled = enabled ? 1 : 0; ++} ++ ++int rc_client_get_unofficial_enabled(const rc_client_t* client) ++{ ++ if (!client) ++ return 0; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->get_unofficial_enabled) ++ return client->state.external_client->get_unofficial_enabled(); ++#endif ++ ++ return client->state.unofficial_enabled; ++} ++ ++void rc_client_set_encore_mode_enabled(rc_client_t* client, int enabled) ++{ ++ if (!client) ++ return; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->set_encore_mode_enabled) { ++ client->state.external_client->set_encore_mode_enabled(enabled); ++ return; ++ } ++#endif ++ ++ RC_CLIENT_LOG_INFO_FORMATTED(client, "Encore mode %s", enabled ? "enabled" : "disabled"); ++ client->state.encore_mode = enabled ? 1 : 0; ++} ++ ++int rc_client_get_encore_mode_enabled(const rc_client_t* client) ++{ ++ if (!client) ++ return 0; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->get_encore_mode_enabled) ++ return client->state.external_client->get_encore_mode_enabled(); ++#endif ++ ++ return client->state.encore_mode; ++} ++ ++void rc_client_set_spectator_mode_enabled(rc_client_t* client, int enabled) ++{ ++ if (!client) ++ return; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->set_spectator_mode_enabled) { ++ client->state.external_client->set_spectator_mode_enabled(enabled); ++ return; ++ } ++#endif ++ ++ if (!enabled && client->state.spectator_mode == RC_CLIENT_SPECTATOR_MODE_LOCKED) { ++ RC_CLIENT_LOG_WARN(client, "Spectator mode cannot be disabled if it was enabled prior to loading game."); ++ return; ++ } ++ ++ RC_CLIENT_LOG_INFO_FORMATTED(client, "Spectator mode %s", enabled ? "enabled" : "disabled"); ++ client->state.spectator_mode = enabled ? RC_CLIENT_SPECTATOR_MODE_ON : RC_CLIENT_SPECTATOR_MODE_OFF; ++} ++ ++int rc_client_get_spectator_mode_enabled(const rc_client_t* client) ++{ ++ if (!client) ++ return 0; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->get_spectator_mode_enabled) ++ return client->state.external_client->get_spectator_mode_enabled(); ++#endif ++ ++ return (client->state.spectator_mode == RC_CLIENT_SPECTATOR_MODE_OFF) ? 0 : 1; ++} ++ ++void rc_client_set_userdata(rc_client_t* client, void* userdata) ++{ ++ if (client) ++ client->callbacks.client_data = userdata; ++} ++ ++void* rc_client_get_userdata(const rc_client_t* client) ++{ ++ return client ? client->callbacks.client_data : NULL; ++} ++ ++void rc_client_set_host(rc_client_t* client, const char* hostname) ++{ ++ if (!client) ++ return; ++ ++ if (client->state.host.host && hostname && strcmp(hostname, client->state.host.host) == 0) ++ return; ++ ++ /* clear out any previously specified host information */ ++ memset(&client->state.host, 0, sizeof(client->state.host)); ++ ++ if (hostname && (!hostname[0] || strcmp(hostname, rc_api_default_host()) == 0)) { ++ RC_CLIENT_LOG_VERBOSE_FORMATTED(client, "Using host: %s", rc_api_default_host()); ++ hostname = rc_api_default_host(); ++ } ++ else { ++ RC_CLIENT_LOG_VERBOSE_FORMATTED(client, "Using host: %s", hostname); ++ client->state.host.host = rc_buffer_strcpy(&client->state.buffer, hostname); ++ } ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client->state.external_client && client->state.external_client->set_host) ++ client->state.external_client->set_host(hostname); ++#endif ++} ++ ++size_t rc_client_get_user_agent_clause(rc_client_t* client, char buffer[], size_t buffer_size) ++{ ++ size_t result; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ if (client && client->state.external_client && client->state.external_client->get_user_agent_clause) { ++ result = client->state.external_client->get_user_agent_clause(buffer, buffer_size); ++ if (result > 0) { ++ result += snprintf(buffer + result, buffer_size - result, " rc_client/" RCHEEVOS_VERSION_STRING); ++ buffer[buffer_size - 1] = '\0'; ++ return result; ++ } ++ } ++#else ++ (void)client; ++#endif ++ ++ result = snprintf(buffer, buffer_size, "rcheevos/" RCHEEVOS_VERSION_STRING); ++ ++ /* some implementations of snprintf will fill the buffer without null terminating. ++ * make sure the buffer is null terminated */ ++ buffer[buffer_size - 1] = '\0'; ++ return result; ++} +diff -rupbN melonDS.orig/src/rcheevos/src/rc_client_internal.h melonDS.ra/src/rcheevos/src/rc_client_internal.h +--- melonDS.orig/src/rcheevos/src/rc_client_internal.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rc_client_internal.h 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,409 @@ ++#ifndef RC_CLIENT_INTERNAL_H ++#define RC_CLIENT_INTERNAL_H ++ ++#include "rc_client.h" ++ ++#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION ++ #include "rc_client_raintegration_internal.h" ++#endif ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ #include "rc_client_external.h" ++#endif ++#ifdef RC_CLIENT_SUPPORTS_HASH ++ #include "rhash/rc_hash_internal.h" ++#endif ++ ++#include "rc_compat.h" ++#include "rc_runtime.h" ++#include "rc_runtime_types.h" ++ ++RC_BEGIN_C_DECLS ++ ++/*****************************************************************************\ ++| Callbacks | ++\*****************************************************************************/ ++ ++struct rc_api_fetch_game_sets_response_t; ++typedef void (RC_CCONV *rc_client_post_process_game_sets_response_t)(const rc_api_server_response_t* server_response, ++ struct rc_api_fetch_game_sets_response_t* game_sets_response, rc_client_t* client, void* userdata); ++typedef int (RC_CCONV *rc_client_can_submit_achievement_unlock_t)(uint32_t achievement_id, rc_client_t* client); ++typedef int (RC_CCONV *rc_client_can_submit_leaderboard_entry_t)(uint32_t leaderboard_id, rc_client_t* client); ++typedef int (RC_CCONV *rc_client_rich_presence_override_t)(rc_client_t* client, char buffer[], size_t buffersize); ++typedef uint32_t (RC_CCONV* rc_client_identify_hash_func_t)(uint32_t console_id, const char* hash, ++ rc_client_t* client, void* callback_userdata); ++ ++typedef struct rc_client_callbacks_t { ++ rc_client_read_memory_func_t read_memory; ++ rc_client_event_handler_t event_handler; ++ rc_client_server_call_t server_call; ++ rc_client_message_callback_t log_call; ++ rc_get_time_millisecs_func_t get_time_millisecs; ++ rc_client_identify_hash_func_t identify_unknown_hash; ++ rc_client_post_process_game_sets_response_t post_process_game_sets_response; ++ rc_client_can_submit_achievement_unlock_t can_submit_achievement_unlock; ++ rc_client_can_submit_leaderboard_entry_t can_submit_leaderboard_entry; ++ rc_client_rich_presence_override_t rich_presence_override; ++ ++#ifdef RC_CLIENT_SUPPORTS_HASH ++ rc_hash_callbacks_t hash; ++#endif ++ ++ void* client_data; ++} rc_client_callbacks_t; ++ ++struct rc_client_scheduled_callback_data_t; ++typedef void (RC_CCONV *rc_client_scheduled_callback_t)(struct rc_client_scheduled_callback_data_t* callback_data, rc_client_t* client, rc_clock_t now); ++ ++typedef struct rc_client_scheduled_callback_data_t ++{ ++ rc_clock_t when; ++ uint32_t related_id; ++ rc_client_scheduled_callback_t callback; ++ void* data; ++ struct rc_client_scheduled_callback_data_t* next; ++} rc_client_scheduled_callback_data_t; ++ ++void rc_client_schedule_callback(rc_client_t* client, rc_client_scheduled_callback_data_t* scheduled_callback); ++ ++struct rc_client_async_handle_t { ++ uint8_t aborted; ++}; ++ ++int rc_client_async_handle_aborted(rc_client_t* client, rc_client_async_handle_t* async_handle); ++ ++/*****************************************************************************\ ++| Achievements | ++\*****************************************************************************/ ++ ++enum { ++ RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_NONE = 0, ++ RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_TRIGGERED = (1 << 1), ++ RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_CHALLENGE_INDICATOR_SHOW = (1 << 2), ++ RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_CHALLENGE_INDICATOR_HIDE = (1 << 3), ++ RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_UPDATE = (1 << 4) /* not a real event, just triggers update */ ++}; ++ ++typedef struct rc_client_achievement_info_t { ++ rc_client_achievement_t public_; ++ ++ rc_trigger_t* trigger; ++ uint8_t md5[16]; ++ ++ time_t unlock_time_hardcore; ++ time_t unlock_time_softcore; ++ ++ uint8_t pending_events; ++ ++ const char* author; ++ time_t created_time; ++ time_t updated_time; ++} rc_client_achievement_info_t; ++ ++struct rc_client_achievement_list_info_t; ++typedef void (RC_CCONV *rc_client_destroy_achievement_list_func_t)(struct rc_client_achievement_list_info_t* list); ++ ++typedef struct rc_client_achievement_list_info_t { ++ rc_client_achievement_list_t public_; ++ rc_client_destroy_achievement_list_func_t destroy_func; ++} rc_client_achievement_list_info_t; ++ ++enum { ++ RC_CLIENT_PROGRESS_TRACKER_ACTION_NONE, ++ RC_CLIENT_PROGRESS_TRACKER_ACTION_SHOW, ++ RC_CLIENT_PROGRESS_TRACKER_ACTION_UPDATE, ++ RC_CLIENT_PROGRESS_TRACKER_ACTION_HIDE ++}; ++ ++typedef struct rc_client_progress_tracker_t { ++ rc_client_achievement_info_t* achievement; ++ float progress; ++ ++ rc_client_scheduled_callback_data_t* hide_callback; ++ uint8_t action; ++} rc_client_progress_tracker_t; ++ ++/*****************************************************************************\ ++| Leaderboard Trackers | ++\*****************************************************************************/ ++ ++enum { ++ RC_CLIENT_LEADERBOARD_TRACKER_PENDING_EVENT_NONE = 0, ++ RC_CLIENT_LEADERBOARD_TRACKER_PENDING_EVENT_UPDATE = (1 << 1), ++ RC_CLIENT_LEADERBOARD_TRACKER_PENDING_EVENT_SHOW = (1 << 2), ++ RC_CLIENT_LEADERBOARD_TRACKER_PENDING_EVENT_HIDE = (1 << 3) ++}; ++ ++typedef struct rc_client_leaderboard_tracker_info_t { ++ rc_client_leaderboard_tracker_t public_; ++ struct rc_client_leaderboard_tracker_info_t* next; ++ int32_t raw_value; ++ ++ uint32_t value_djb2; ++ ++ uint8_t format; ++ uint8_t pending_events; ++ uint8_t reference_count; ++ uint8_t value_from_hits; ++} rc_client_leaderboard_tracker_info_t; ++ ++/*****************************************************************************\ ++| Leaderboards | ++\*****************************************************************************/ ++ ++enum { ++ RC_CLIENT_LEADERBOARD_PENDING_EVENT_NONE = 0, ++ RC_CLIENT_LEADERBOARD_PENDING_EVENT_STARTED = (1 << 1), ++ RC_CLIENT_LEADERBOARD_PENDING_EVENT_FAILED = (1 << 2), ++ RC_CLIENT_LEADERBOARD_PENDING_EVENT_SUBMITTED = (1 << 3) ++}; ++ ++typedef struct rc_client_leaderboard_info_t { ++ rc_client_leaderboard_t public_; ++ ++ rc_lboard_t* lboard; ++ uint8_t md5[16]; ++ ++ rc_client_leaderboard_tracker_info_t* tracker; ++ ++ uint32_t value_djb2; ++ int32_t value; ++ ++ uint8_t format; ++ uint8_t pending_events; ++ uint8_t bucket; ++ uint8_t hidden; ++} rc_client_leaderboard_info_t; ++ ++struct rc_client_leaderboard_list_info_t; ++typedef void (RC_CCONV *rc_client_destroy_leaderboard_list_func_t)(struct rc_client_leaderboard_list_info_t* list); ++ ++typedef struct rc_client_leaderboard_list_info_t { ++ rc_client_leaderboard_list_t public_; ++ rc_client_destroy_leaderboard_list_func_t destroy_func; ++} rc_client_leaderboard_list_info_t; ++ ++struct rc_client_leaderboard_entry_list_info_t; ++typedef void (RC_CCONV *rc_client_destroy_leaderboard_entry_list_func_t)(struct rc_client_leaderboard_entry_list_info_t* list); ++ ++typedef struct rc_client_leaderboard_entry_list_info_t { ++ rc_client_leaderboard_entry_list_t public_; ++ rc_client_destroy_leaderboard_entry_list_func_t destroy_func; ++} rc_client_leaderboard_entry_list_info_t; ++ ++uint8_t rc_client_map_leaderboard_format(int format); ++ ++/*****************************************************************************\ ++| Subsets | ++\*****************************************************************************/ ++ ++enum { ++ RC_CLIENT_SUBSET_PENDING_EVENT_NONE = 0, ++ RC_CLIENT_SUBSET_PENDING_EVENT_ACHIEVEMENT = (1 << 1), ++ RC_CLIENT_SUBSET_PENDING_EVENT_LEADERBOARD = (1 << 2) ++}; ++ ++typedef struct rc_client_subset_info_t { ++ rc_client_subset_t public_; ++ ++ rc_client_achievement_info_t* achievements; ++ rc_client_leaderboard_info_t* leaderboards; ++ ++ struct rc_client_subset_info_t* next; ++ ++ const char* all_label; ++ const char* inactive_label; ++ const char* locked_label; ++ const char* unlocked_label; ++ const char* unofficial_label; ++ const char* unsupported_label; ++ ++ uint8_t active; ++ uint8_t mastery; ++ uint8_t pending_events; ++} rc_client_subset_info_t; ++ ++struct rc_client_subset_list_info_t; ++typedef void (RC_CCONV* rc_client_destroy_subset_list_func_t)(struct rc_client_subset_list_info_t* list); ++ ++typedef struct rc_client_subset_list_info_t { ++ rc_client_subset_list_t public_; ++ rc_client_destroy_subset_list_func_t destroy_func; ++} rc_client_subset_list_info_t; ++ ++/*****************************************************************************\ ++| Game | ++\*****************************************************************************/ ++ ++typedef struct rc_client_game_hash_t { ++ char hash[33]; ++ uint8_t is_unknown; ++ uint32_t game_id; ++ struct rc_client_game_hash_t* next; ++} rc_client_game_hash_t; ++ ++rc_client_game_hash_t* rc_client_find_game_hash(rc_client_t* client, const char* hash); ++ ++typedef struct rc_client_media_hash_t { ++ rc_client_game_hash_t* game_hash; ++ struct rc_client_media_hash_t* next; ++ uint32_t path_djb2; ++} rc_client_media_hash_t; ++ ++enum { ++ RC_CLIENT_GAME_PENDING_EVENT_NONE = 0, ++ RC_CLIENT_GAME_PENDING_EVENT_LEADERBOARD_TRACKER = (1 << 1), ++ RC_CLIENT_GAME_PENDING_EVENT_UPDATE_ACTIVE_ACHIEVEMENTS = (1 << 2), ++ RC_CLIENT_GAME_PENDING_EVENT_PROGRESS_TRACKER = (1 << 3) ++}; ++ ++typedef struct rc_client_game_info_t { ++ rc_client_game_t public_; ++ rc_client_leaderboard_tracker_info_t* leaderboard_trackers; ++ rc_client_progress_tracker_t progress_tracker; ++ ++ rc_client_subset_info_t* subsets; ++ ++ rc_client_media_hash_t* media_hash; ++ ++ rc_runtime_t runtime; ++ ++ uint32_t max_valid_address; ++ ++ uint8_t waiting_for_reset; ++ uint8_t pending_events; ++ ++ rc_buffer_t buffer; ++} rc_client_game_info_t; ++ ++void rc_client_update_active_achievements(rc_client_game_info_t* game); ++void rc_client_update_active_leaderboards(rc_client_game_info_t* game); ++ ++/*****************************************************************************\ ++| Client | ++\*****************************************************************************/ ++ ++enum { ++ RC_CLIENT_USER_STATE_NONE, ++ RC_CLIENT_USER_STATE_LOGIN_REQUESTED, ++ RC_CLIENT_USER_STATE_LOGGED_IN ++}; ++ ++enum { ++ RC_CLIENT_MASTERY_STATE_NONE, ++ RC_CLIENT_MASTERY_STATE_PENDING, ++ RC_CLIENT_MASTERY_STATE_SHOWN ++}; ++ ++enum { ++ RC_CLIENT_SPECTATOR_MODE_OFF, ++ RC_CLIENT_SPECTATOR_MODE_ON, ++ RC_CLIENT_SPECTATOR_MODE_LOCKED ++}; ++ ++enum { ++ RC_CLIENT_DISCONNECT_HIDDEN = 0, ++ RC_CLIENT_DISCONNECT_VISIBLE = (1 << 0), ++ RC_CLIENT_DISCONNECT_SHOW_PENDING = (1 << 1), ++ RC_CLIENT_DISCONNECT_HIDE_PENDING = (1 << 2) ++}; ++ ++struct rc_client_load_state_t; ++ ++typedef struct rc_client_state_t { ++ rc_mutex_t mutex; ++ rc_buffer_t buffer; ++ ++ rc_client_scheduled_callback_data_t* scheduled_callbacks; ++ rc_api_host_t host; ++ ++#ifdef RC_CLIENT_SUPPORTS_EXTERNAL ++ rc_client_external_t* external_client; ++ struct rc_client_external_conversions_t* external_client_conversions; ++#endif ++#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION ++ rc_client_raintegration_t* raintegration; ++#endif ++ ++ uint32_t frames_processed; ++ uint32_t frames_at_last_ping; ++ uint16_t unpaused_frame_decay; ++ uint16_t required_unpaused_frames; ++ ++ uint8_t hardcore; ++ uint8_t encore_mode; ++ uint8_t spectator_mode; ++ uint8_t unofficial_enabled; ++ uint8_t log_level; ++ uint8_t user; ++ uint8_t disconnect; ++ uint8_t allow_leaderboards_in_softcore; ++ uint8_t allow_background_memory_reads; ++ ++ struct rc_client_load_state_t* load; ++ struct rc_client_async_handle_t* async_handles[4]; ++ rc_memref_t* processing_memref; ++ ++ rc_peek_t legacy_peek; ++} rc_client_state_t; ++ ++struct rc_client_t { ++ rc_client_game_info_t* game; ++ rc_client_game_hash_t* hashes; ++ ++ rc_client_user_t user; ++ ++ rc_client_callbacks_t callbacks; ++ ++ rc_client_state_t state; ++}; ++ ++/*****************************************************************************\ ++| Helpers | ++\*****************************************************************************/ ++ ++#ifdef RC_NO_VARIADIC_MACROS ++ void RC_CLIENT_LOG_ERR_FORMATTED(const rc_client_t* client, const char* format, ...); ++ void RC_CLIENT_LOG_WARN_FORMATTED(const rc_client_t* client, const char* format, ...); ++ void RC_CLIENT_LOG_INFO_FORMATTED(const rc_client_t* client, const char* format, ...); ++ void RC_CLIENT_LOG_VERBOSE_FORMATTED(const rc_client_t* client, const char* format, ...); ++#else ++ void rc_client_log_message_formatted(const rc_client_t* client, const char* format, ...); ++ #define RC_CLIENT_LOG_ERR_FORMATTED(client, format, ...) { if (client->state.log_level >= RC_CLIENT_LOG_LEVEL_ERROR) rc_client_log_message_formatted(client, format, __VA_ARGS__); } ++ #define RC_CLIENT_LOG_WARN_FORMATTED(client, format, ...) { if (client->state.log_level >= RC_CLIENT_LOG_LEVEL_WARN) rc_client_log_message_formatted(client, format, __VA_ARGS__); } ++ #define RC_CLIENT_LOG_INFO_FORMATTED(client, format, ...) { if (client->state.log_level >= RC_CLIENT_LOG_LEVEL_INFO) rc_client_log_message_formatted(client, format, __VA_ARGS__); } ++ #define RC_CLIENT_LOG_VERBOSE_FORMATTED(client, format, ...) { if (client->state.log_level >= RC_CLIENT_LOG_LEVEL_VERBOSE) rc_client_log_message_formatted(client, format, __VA_ARGS__); } ++#endif ++ ++void rc_client_log_message(const rc_client_t* client, const char* message); ++#define RC_CLIENT_LOG_ERR(client, message) { if (client->state.log_level >= RC_CLIENT_LOG_LEVEL_ERROR) rc_client_log_message(client, message); } ++#define RC_CLIENT_LOG_WARN(client, message) { if (client->state.log_level >= RC_CLIENT_LOG_LEVEL_WARN) rc_client_log_message(client, message); } ++#define RC_CLIENT_LOG_INFO(client, message) { if (client->state.log_level >= RC_CLIENT_LOG_LEVEL_INFO) rc_client_log_message(client, message); } ++#define RC_CLIENT_LOG_VERBOSE(client, message) { if (client->state.log_level >= RC_CLIENT_LOG_LEVEL_VERBOSE) rc_client_log_message(client, message); } ++ ++/* internals pulled from runtime.c */ ++void rc_runtime_checksum(const char* memaddr, uint8_t* md5); ++int rc_trigger_contains_memref(const rc_trigger_t* trigger, const rc_memref_t* memref); ++int rc_value_contains_memref(const rc_value_t* value, const rc_memref_t* memref); ++/* end runtime.c internals */ ++ ++/* helper functions for unit tests */ ++#ifdef RC_CLIENT_SUPPORTS_HASH ++struct rc_hash_iterator; ++struct rc_hash_iterator* rc_client_get_load_state_hash_iterator(rc_client_t* client); ++#endif ++/* end helper functions for unit tests */ ++ ++enum { ++ RC_CLIENT_LEGACY_PEEK_AUTO, ++ RC_CLIENT_LEGACY_PEEK_CONSTRUCTED, ++ RC_CLIENT_LEGACY_PEEK_LITTLE_ENDIAN_READS ++}; ++ ++void rc_client_set_legacy_peek(rc_client_t* client, int method); ++ ++void rc_client_allocate_leaderboard_tracker(rc_client_game_info_t* game, rc_client_leaderboard_info_t* leaderboard); ++void rc_client_release_leaderboard_tracker(rc_client_game_info_t* game, rc_client_leaderboard_info_t* leaderboard); ++ ++RC_END_C_DECLS ++ ++#endif /* RC_CLIENT_INTERNAL_H */ +diff -rupbN melonDS.orig/src/rcheevos/src/rc_compat.c melonDS.ra/src/rcheevos/src/rc_compat.c +--- melonDS.orig/src/rcheevos/src/rc_compat.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rc_compat.c 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,251 @@ ++#if !defined(RC_NO_THREADS) && !defined(_WIN32) && !defined(GEKKO) && !defined(_3DS) && (!defined(_XOPEN_SOURCE) || (_XOPEN_SOURCE - 0) < 500) ++/* We'll want to use pthread_mutexattr_settype/PTHREAD_MUTEX_RECURSIVE, but glibc only conditionally exposes pthread_mutexattr_settype and PTHREAD_MUTEX_RECURSIVE depending on feature flags ++ * Defining _XOPEN_SOURCE must be done at the top of the source file, before including any headers ++ * pthread_mutexattr_settype/PTHREAD_MUTEX_RECURSIVE are specified the Single UNIX Specification (Version 2, 1997), along with POSIX later on (IEEE Standard 1003.1-2008), so should cover practically any pthread implementation ++ */ ++#undef _XOPEN_SOURCE ++#define _XOPEN_SOURCE 500 ++#endif ++ ++#include "rc_compat.h" ++ ++#include ++#include ++#include ++ ++#ifdef RC_C89_HELPERS ++ ++int rc_strncasecmp(const char* left, const char* right, size_t length) ++{ ++ while (length) ++ { ++ if (*left != *right) ++ { ++ const int diff = tolower(*left) - tolower(*right); ++ if (diff != 0) ++ return diff; ++ } ++ ++ ++left; ++ ++right; ++ --length; ++ } ++ ++ return 0; ++} ++ ++int rc_strcasecmp(const char* left, const char* right) ++{ ++ while (*left || *right) ++ { ++ if (*left != *right) ++ { ++ const int diff = tolower(*left) - tolower(*right); ++ if (diff != 0) ++ return diff; ++ } ++ ++ ++left; ++ ++right; ++ } ++ ++ return 0; ++} ++ ++char* rc_strdup(const char* str) ++{ ++ const size_t length = strlen(str); ++ char* buffer = (char*)malloc(length + 1); ++ if (buffer) ++ memcpy(buffer, str, length + 1); ++ return buffer; ++} ++ ++int rc_snprintf(char* buffer, size_t size, const char* format, ...) ++{ ++ int result; ++ va_list args; ++ ++ va_start(args, format); ++ ++#ifdef __STDC_SECURE_LIB__ ++ result = vsprintf_s(buffer, size, format, args); ++#else ++ /* assume buffer is large enough and ignore size */ ++ (void)size; ++ result = vsprintf(buffer, format, args); ++#endif ++ ++ va_end(args); ++ ++ return result; ++} ++ ++#endif ++ ++#ifndef __STDC_SECURE_LIB__ ++ ++struct tm* rc_gmtime_s(struct tm* buf, const time_t* timer) ++{ ++ struct tm* tm = gmtime(timer); ++ memcpy(buf, tm, sizeof(*tm)); ++ return buf; ++} ++ ++#endif ++ ++#ifndef RC_NO_THREADS ++ ++#if defined(_WIN32) ++ ++/* https://learn.microsoft.com/en-us/archive/msdn-magazine/2012/november/windows-with-c-the-evolution-of-synchronization-in-windows-and-c */ ++/* implementation largely taken from https://github.com/libsdl-org/SDL/blob/0fc3574/src/thread/windows/SDL_sysmutex.c */ ++ ++#if defined(WINVER) && WINVER >= 0x0600 ++ ++void rc_mutex_init(rc_mutex_t* mutex) ++{ ++ InitializeSRWLock(&mutex->srw_lock); ++ /* https://learn.microsoft.com/en-us/windows/win32/procthread/thread-handles-and-identifiers */ ++ /* thread ids are never 0 */ ++ mutex->owner = 0; ++ mutex->count = 0; ++} ++ ++void rc_mutex_destroy(rc_mutex_t* mutex) ++{ ++ /* Nothing to do here */ ++ (void)mutex; ++} ++ ++void rc_mutex_lock(rc_mutex_t* mutex) ++{ ++ DWORD current_thread = GetCurrentThreadId(); ++ if (mutex->owner == current_thread) { ++ ++mutex->count; ++ assert(mutex->count > 0); ++ } ++ else { ++ AcquireSRWLockExclusive(&mutex->srw_lock); ++ assert(mutex->owner == 0 && mutex->count == 0); ++ mutex->owner = current_thread; ++ mutex->count = 1; ++ } ++} ++ ++void rc_mutex_unlock(rc_mutex_t* mutex) ++{ ++ if (mutex->owner == GetCurrentThreadId()) { ++ assert(mutex->count > 0); ++ if (--mutex->count == 0) { ++ mutex->owner = 0; ++ ReleaseSRWLockExclusive(&mutex->srw_lock); ++ } ++ } ++ else { ++ assert(!"Tried to unlock unowned mutex"); ++ } ++} ++ ++#else ++ ++void rc_mutex_init(rc_mutex_t* mutex) ++{ ++ InitializeCriticalSection(&mutex->critical_section); ++} ++ ++void rc_mutex_destroy(rc_mutex_t* mutex) ++{ ++ DeleteCriticalSection(&mutex->critical_section); ++} ++ ++void rc_mutex_lock(rc_mutex_t* mutex) ++{ ++ EnterCriticalSection(&mutex->critical_section); ++} ++ ++void rc_mutex_unlock(rc_mutex_t* mutex) ++{ ++ LeaveCriticalSection(&mutex->critical_section); ++} ++ ++#endif ++ ++#elif defined(GEKKO) ++ ++/* https://github.com/libretro/RetroArch/pull/16116 */ ++ ++void rc_mutex_init(rc_mutex_t* mutex) ++{ ++ /* LWP_MutexInit has the handle passed by reference */ ++ /* Other LWP_Mutex* calls have the handle passed by value */ ++ LWP_MutexInit(&mutex->handle, 1); ++} ++ ++void rc_mutex_destroy(rc_mutex_t* mutex) ++{ ++ LWP_MutexDestroy(mutex->handle); ++} ++ ++void rc_mutex_lock(rc_mutex_t* mutex) ++{ ++ LWP_MutexLock(mutex->handle); ++} ++ ++void rc_mutex_unlock(rc_mutex_t* mutex) ++{ ++ LWP_MutexUnlock(mutex->handle); ++} ++ ++#elif defined(_3DS) ++ ++void rc_mutex_init(rc_mutex_t* mutex) ++{ ++ RecursiveLock_Init(mutex); ++} ++ ++void rc_mutex_destroy(rc_mutex_t* mutex) ++{ ++ /* Nothing to do here */ ++ (void)mutex; ++} ++ ++void rc_mutex_lock(rc_mutex_t* mutex) ++{ ++ RecursiveLock_Lock(mutex); ++} ++ ++void rc_mutex_unlock(rc_mutex_t* mutex) ++{ ++ RecursiveLock_Unlock(mutex); ++} ++ ++#else ++ ++void rc_mutex_init(rc_mutex_t* mutex) ++{ ++ /* Define the mutex as recursive, for consistent semantics against other rc_mutex_t implementations */ ++ pthread_mutexattr_t attr; ++ pthread_mutexattr_init(&attr); ++ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); ++ pthread_mutex_init(mutex, &attr); ++ pthread_mutexattr_destroy(&attr); ++} ++ ++void rc_mutex_destroy(rc_mutex_t* mutex) ++{ ++ pthread_mutex_destroy(mutex); ++} ++ ++void rc_mutex_lock(rc_mutex_t* mutex) ++{ ++ pthread_mutex_lock(mutex); ++} ++ ++void rc_mutex_unlock(rc_mutex_t* mutex) ++{ ++ pthread_mutex_unlock(mutex); ++} ++ ++#endif ++#endif /* RC_NO_THREADS */ +diff -rupbN melonDS.orig/src/rcheevos/src/rc_compat.h melonDS.ra/src/rcheevos/src/rc_compat.h +--- melonDS.orig/src/rcheevos/src/rc_compat.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rc_compat.h 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,121 @@ ++#ifndef RC_COMPAT_H ++#define RC_COMPAT_H ++ ++#ifdef _WIN32 ++ #ifndef WIN32_LEAN_AND_MEAN ++ #define WIN32_LEAN_AND_MEAN ++ #endif ++ #include ++#endif ++ ++#include "rc_export.h" ++ ++#include ++#include ++#include ++ ++RC_BEGIN_C_DECLS ++ ++#if defined(MINGW) || defined(__MINGW32__) || defined(__MINGW64__) ++ ++/* MinGW redefinitions */ ++ ++#define RC_NO_VARIADIC_MACROS 1 ++ ++#elif defined(_MSC_VER) ++ ++/* Visual Studio redefinitions */ ++ ++#ifndef strcasecmp ++ #define strcasecmp _stricmp ++#endif ++#ifndef strncasecmp ++ #define strncasecmp _strnicmp ++#endif ++#ifndef strdup ++ #define strdup _strdup ++#endif ++ ++#elif __STDC_VERSION__ < 199901L ++ ++/* C89 redefinitions */ ++#define RC_C89_HELPERS 1 ++ ++#define RC_NO_VARIADIC_MACROS 1 ++ ++#ifndef snprintf ++ extern int rc_snprintf(char* buffer, size_t size, const char* format, ...); ++ #define snprintf rc_snprintf ++#endif ++ ++#ifndef strncasecmp ++ extern int rc_strncasecmp(const char* left, const char* right, size_t length); ++ #define strncasecmp rc_strncasecmp ++#endif ++ ++#ifndef strcasecmp ++ extern int rc_strcasecmp(const char* left, const char* right); ++ #define strcasecmp rc_strcasecmp ++#endif ++ ++#ifndef strdup ++ extern char* rc_strdup(const char* str); ++ #define strdup rc_strdup ++#endif ++ ++#endif /* __STDC_VERSION__ < 199901L */ ++ ++#ifndef __STDC_SECURE_LIB__ ++ /* _CRT_SECURE_NO_WARNINGS redefinitions */ ++ #define strcpy_s(dest, sz, src) strcpy(dest, src) ++ #define sscanf_s sscanf ++ ++ /* NOTE: Microsoft secure gmtime_s parameter order differs from C11 standard */ ++ #include ++ extern struct tm* rc_gmtime_s(struct tm* buf, const time_t* timer); ++ #define gmtime_s rc_gmtime_s ++#endif ++ ++#ifdef RC_NO_THREADS ++ typedef int rc_mutex_t; ++ ++ #define rc_mutex_init(mutex) ++ #define rc_mutex_destroy(mutex) ++ #define rc_mutex_lock(mutex) ++ #define rc_mutex_unlock(mutex) ++#else ++ #if defined(_WIN32) ++ typedef struct rc_mutex_t { ++ #if defined(WINVER) && WINVER >= 0x0600 ++ /* Windows Vista and later can use a slim reader/writer (SRW) lock */ ++ SRWLOCK srw_lock; ++ /* Current thread owner needs to be tracked (for recursive mutex usage) */ ++ DWORD owner; ++ DWORD count; ++ #else ++ /* Pre-Vista must use a critical section */ ++ CRITICAL_SECTION critical_section; ++ #endif ++ } rc_mutex_t; ++ #elif defined(GEKKO) ++ #include ++ typedef struct rc_mutex_t { ++ mutex_t handle; ++ } rc_mutex_t; ++ #elif defined(_3DS) ++ #include <3ds/synchronization.h> ++ typedef RecursiveLock rc_mutex_t; ++ #else ++ #include ++ typedef pthread_mutex_t rc_mutex_t; ++ #endif ++ ++ void rc_mutex_init(rc_mutex_t* mutex); ++ void rc_mutex_destroy(rc_mutex_t* mutex); ++ void rc_mutex_lock(rc_mutex_t* mutex); ++ void rc_mutex_unlock(rc_mutex_t* mutex); ++#endif ++ ++RC_END_C_DECLS ++ ++#endif /* RC_COMPAT_H */ +diff -rupbN melonDS.orig/src/rcheevos/src/rc_util.c melonDS.ra/src/rcheevos/src/rc_util.c +--- melonDS.orig/src/rcheevos/src/rc_util.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rc_util.c 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,199 @@ ++#include "rc_util.h" ++ ++#include "rc_compat.h" ++#include "rc_error.h" ++ ++#include ++#include ++ ++#undef DEBUG_BUFFERS ++ ++/* --- rc_buffer --- */ ++ ++void rc_buffer_init(rc_buffer_t* buffer) ++{ ++ buffer->chunk.write = buffer->chunk.start = &buffer->data[0]; ++ buffer->chunk.end = &buffer->data[sizeof(buffer->data)]; ++ buffer->chunk.next = NULL; ++ /* leave buffer->data uninitialized */ ++} ++ ++void rc_buffer_destroy(rc_buffer_t* buffer) ++{ ++ rc_buffer_chunk_t* chunk; ++#ifdef DEBUG_BUFFERS ++ int count = 0; ++ int wasted = 0; ++ int total = 0; ++#endif ++ ++ /* first chunk is not allocated. skip it. */ ++ chunk = buffer->chunk.next; ++ ++ /* deallocate any additional buffers */ ++ while (chunk) ++ { ++ rc_buffer_chunk_t* next = chunk->next; ++#ifdef DEBUG_BUFFERS ++ total += (int)(chunk->end - chunk->start); ++ wasted += (int)(chunk->end - chunk->write); ++ ++count; ++#endif ++#ifdef DEBUG_BUFFERS ++ printf("< free %p.%p\n", (void*)buffer, (void*)chunk); ++#endif ++ free(chunk); ++ chunk = next; ++ } ++ ++#ifdef DEBUG_BUFFERS ++ printf("-- %d allocated buffers (%d/%d used, %d wasted, %0.2f%% efficiency)\n", count, ++ total - wasted, total, wasted, (float)(100.0 - (wasted * 100.0) / total)); ++#endif ++} ++ ++uint8_t* rc_buffer_reserve(rc_buffer_t* buffer, size_t amount) ++{ ++ rc_buffer_chunk_t* chunk = &buffer->chunk; ++ size_t remaining; ++ while (chunk) ++ { ++ remaining = chunk->end - chunk->write; ++ if (remaining >= amount) ++ return chunk->write; ++ ++ if (!chunk->next) ++ { ++ /* allocate a chunk of memory that is a multiple of 256-bytes. the first 32 bytes will be associated ++ * to the chunk header, and the remaining will be used for data. ++ */ ++ const size_t chunk_header_size = sizeof(rc_buffer_chunk_t); ++ const size_t alloc_size = (chunk_header_size + amount + 0xFF) & ~0xFF; ++ chunk->next = (rc_buffer_chunk_t*)malloc(alloc_size); ++ if (!chunk->next) ++ break; ++ ++#ifdef DEBUG_BUFFERS ++ printf("> alloc %p.%p\n", (void*)buffer, (void*)chunk->next); ++#endif ++ ++ chunk->next->start = (uint8_t*)chunk->next + chunk_header_size; ++ chunk->next->write = chunk->next->start; ++ chunk->next->end = (uint8_t*)chunk->next + alloc_size; ++ chunk->next->next = NULL; ++ } ++ ++ chunk = chunk->next; ++ } ++ ++ return NULL; ++} ++ ++void rc_buffer_consume(rc_buffer_t* buffer, const uint8_t* start, uint8_t* end) ++{ ++ rc_buffer_chunk_t* chunk = &buffer->chunk; ++ do ++ { ++ if (chunk->write == start) ++ { ++ size_t offset = (end - chunk->start); ++ offset = (offset + 7) & ~7; ++ chunk->write = &chunk->start[offset]; ++ ++ if (chunk->write > chunk->end) ++ chunk->write = chunk->end; ++ break; ++ } ++ ++ chunk = chunk->next; ++ } while (chunk); ++} ++ ++void* rc_buffer_alloc(rc_buffer_t* buffer, size_t amount) ++{ ++ uint8_t* ptr = rc_buffer_reserve(buffer, amount); ++ rc_buffer_consume(buffer, ptr, ptr + amount); ++ return (void*)ptr; ++} ++ ++char* rc_buffer_strncpy(rc_buffer_t* buffer, const char* src, size_t len) ++{ ++ uint8_t* dst = rc_buffer_reserve(buffer, len + 1); ++ memcpy(dst, src, len); ++ dst[len] = '\0'; ++ rc_buffer_consume(buffer, dst, dst + len + 2); ++ return (char*)dst; ++} ++ ++char* rc_buffer_strcpy(rc_buffer_t* buffer, const char* src) ++{ ++ return rc_buffer_strncpy(buffer, src, strlen(src)); ++} ++ ++/* --- other --- */ ++ ++void rc_format_md5(char checksum[33], const uint8_t digest[16]) ++{ ++ snprintf(checksum, 33, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", ++ digest[0], digest[1], digest[2], digest[3], digest[4], digest[5], digest[6], digest[7], ++ digest[8], digest[9], digest[10], digest[11], digest[12], digest[13], digest[14], digest[15] ++ ); ++} ++ ++uint32_t rc_djb2(const char* input) ++{ ++ uint32_t result = 5381; ++ char c; ++ ++ while ((c = *input++) != '\0') ++ result = ((result << 5) + result) + c; /* result = result * 33 + c */ ++ ++ return result; ++} ++ ++const char* rc_error_str(int ret) ++{ ++ switch (ret) { ++ case RC_OK: return "OK"; ++ case RC_INVALID_FUNC_OPERAND: return "Invalid function operand"; ++ case RC_INVALID_MEMORY_OPERAND: return "Invalid memory operand"; ++ case RC_INVALID_CONST_OPERAND: return "Invalid constant operand"; ++ case RC_INVALID_FP_OPERAND: return "Invalid floating-point operand"; ++ case RC_INVALID_CONDITION_TYPE: return "Invalid condition type"; ++ case RC_INVALID_OPERATOR: return "Invalid operator"; ++ case RC_INVALID_REQUIRED_HITS: return "Invalid required hits"; ++ case RC_DUPLICATED_START: return "Duplicated start condition"; ++ case RC_DUPLICATED_CANCEL: return "Duplicated cancel condition"; ++ case RC_DUPLICATED_SUBMIT: return "Duplicated submit condition"; ++ case RC_DUPLICATED_VALUE: return "Duplicated value expression"; ++ case RC_DUPLICATED_PROGRESS: return "Duplicated progress expression"; ++ case RC_MISSING_START: return "Missing start condition"; ++ case RC_MISSING_CANCEL: return "Missing cancel condition"; ++ case RC_MISSING_SUBMIT: return "Missing submit condition"; ++ case RC_MISSING_VALUE: return "Missing value expression"; ++ case RC_INVALID_LBOARD_FIELD: return "Invalid field in leaderboard"; ++ case RC_MISSING_DISPLAY_STRING: return "Missing display string"; ++ case RC_OUT_OF_MEMORY: return "Out of memory"; ++ case RC_INVALID_VALUE_FLAG: return "Invalid flag in value expression"; ++ case RC_MISSING_VALUE_MEASURED: return "Missing measured flag in value expression"; ++ case RC_MULTIPLE_MEASURED: return "Multiple measured targets"; ++ case RC_INVALID_MEASURED_TARGET: return "Invalid measured target"; ++ case RC_INVALID_COMPARISON: return "Invalid comparison"; ++ case RC_INVALID_STATE: return "Invalid state"; ++ case RC_INVALID_JSON: return "Invalid JSON"; ++ case RC_API_FAILURE: return "API call failed"; ++ case RC_LOGIN_REQUIRED: return "Login required"; ++ case RC_NO_GAME_LOADED: return "No game loaded"; ++ case RC_HARDCORE_DISABLED: return "Hardcore disabled"; ++ case RC_ABORTED: return "Aborted"; ++ case RC_NO_RESPONSE: return "No response"; ++ case RC_ACCESS_DENIED: return "Access denied"; ++ case RC_INVALID_CREDENTIALS: return "Invalid credentials"; ++ case RC_EXPIRED_TOKEN: return "Expired token"; ++ case RC_INSUFFICIENT_BUFFER: return "Buffer not large enough"; ++ case RC_INVALID_VARIABLE_NAME: return "Invalid variable name"; ++ case RC_UNKNOWN_VARIABLE_NAME: return "Unknown variable name"; ++ case RC_NOT_FOUND: return "Not found"; ++ default: return "Unknown error"; ++ } ++} +diff -rupbN melonDS.orig/src/rcheevos/src/rc_version.c melonDS.ra/src/rcheevos/src/rc_version.c +--- melonDS.orig/src/rcheevos/src/rc_version.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rc_version.c 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,11 @@ ++#include "rc_version.h" ++ ++uint32_t rc_version(void) ++{ ++ return RCHEEVOS_VERSION; ++} ++ ++const char* rc_version_string(void) ++{ ++ return RCHEEVOS_VERSION_STRING; ++} +diff -rupbN melonDS.orig/src/rcheevos/src/rc_version.h melonDS.ra/src/rcheevos/src/rc_version.h +--- melonDS.orig/src/rcheevos/src/rc_version.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rc_version.h 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,32 @@ ++#ifndef RC_VERSION_H ++#define RC_VERSION_H ++ ++#include "rc_export.h" ++ ++#include ++ ++RC_BEGIN_C_DECLS ++ ++#define RCHEEVOS_VERSION_MAJOR 12 ++#define RCHEEVOS_VERSION_MINOR 1 ++#define RCHEEVOS_VERSION_PATCH 0 ++ ++#define RCHEEVOS_MAKE_VERSION(major, minor, patch) (major * 1000000 + minor * 1000 + patch) ++#define RCHEEVOS_VERSION RCHEEVOS_MAKE_VERSION(RCHEEVOS_VERSION_MAJOR, RCHEEVOS_VERSION_MINOR, RCHEEVOS_VERSION_PATCH) ++ ++#define RCHEEVOS_MAKE_STRING(num) #num ++#define RCHEEVOS_MAKE_VERSION_STRING(major, minor, patch) RCHEEVOS_MAKE_STRING(major) "." RCHEEVOS_MAKE_STRING(minor) "." RCHEEVOS_MAKE_STRING(patch) ++#define RCHEEVOS_MAKE_VERSION_STRING_SHORT(major, minor) RCHEEVOS_MAKE_STRING(major) "." RCHEEVOS_MAKE_STRING(minor) ++ ++#if RCHEEVOS_VERSION_PATCH > 0 ++ #define RCHEEVOS_VERSION_STRING RCHEEVOS_MAKE_VERSION_STRING(RCHEEVOS_VERSION_MAJOR, RCHEEVOS_VERSION_MINOR, RCHEEVOS_VERSION_PATCH) ++#else ++ #define RCHEEVOS_VERSION_STRING RCHEEVOS_MAKE_VERSION_STRING_SHORT(RCHEEVOS_VERSION_MAJOR, RCHEEVOS_VERSION_MINOR) ++#endif ++ ++RC_EXPORT uint32_t rc_version(void); ++RC_EXPORT const char* rc_version_string(void); ++ ++RC_END_C_DECLS ++ ++#endif /* RC_VERSION_H */ +diff -rupbN melonDS.orig/src/rcheevos/src/rcheevos/alloc.c melonDS.ra/src/rcheevos/src/rcheevos/alloc.c +--- melonDS.orig/src/rcheevos/src/rcheevos/alloc.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rcheevos/alloc.c 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,312 @@ ++#include "rc_internal.h" ++ ++#include ++#include ++ ++void* rc_alloc_scratch(void* pointer, int32_t* offset, uint32_t size, uint32_t alignment, rc_scratch_t* scratch, uint32_t scratch_object_pointer_offset) ++{ ++ void* data; ++ ++ /* if we have a real buffer, then allocate the data there */ ++ if (pointer) ++ return rc_alloc(pointer, offset, size, alignment, NULL, scratch_object_pointer_offset); ++ ++ /* update how much space will be required in the real buffer */ ++ { ++ const int32_t aligned_offset = (*offset + alignment - 1) & ~(alignment - 1); ++ *offset += (aligned_offset - *offset); ++ *offset += size; ++ } ++ ++ /* find a scratch buffer to hold the temporary data */ ++ data = rc_buffer_alloc(&scratch->buffer, size); ++ if (!data) { ++ *offset = RC_OUT_OF_MEMORY; ++ return NULL; ++ } ++ ++ return data; ++} ++ ++void* rc_alloc(void* pointer, int32_t* offset, uint32_t size, uint32_t alignment, rc_scratch_t* scratch, uint32_t scratch_object_pointer_offset) { ++ void* ptr; ++ ++ *offset = (*offset + alignment - 1) & ~(alignment - 1); ++ ++ if (pointer != 0) { ++ /* valid buffer, grab the next chunk */ ++ ptr = (void*)((uint8_t*)pointer + *offset); ++ } ++ else if (scratch != 0 && scratch_object_pointer_offset < sizeof(scratch->objs)) { ++ /* only allocate one instance of each object type (indentified by scratch_object_pointer_offset) */ ++ void** scratch_object_pointer = (void**)((uint8_t*)&scratch->objs + scratch_object_pointer_offset); ++ ptr = *scratch_object_pointer; ++ if (!ptr) { ++ int32_t used; ++ ptr = *scratch_object_pointer = rc_alloc_scratch(NULL, &used, size, alignment, scratch, -1); ++ } ++ } ++ else { ++ /* nowhere to get memory from, return NULL */ ++ ptr = NULL; ++ } ++ ++ *offset += size; ++ return ptr; ++} ++ ++char* rc_alloc_str(rc_parse_state_t* parse, const char* text, size_t length) { ++ int32_t used = 0; ++ char* ptr; ++ ++ rc_scratch_string_t** next = &parse->scratch.strings; ++ while (*next) { ++ int diff = strncmp(text, (*next)->value, length); ++ if (diff == 0) { ++ diff = (*next)->value[length]; ++ if (diff == 0) ++ return (*next)->value; ++ } ++ ++ if (diff < 0) ++ next = &(*next)->left; ++ else ++ next = &(*next)->right; ++ } ++ ++ *next = (rc_scratch_string_t*)rc_alloc_scratch(NULL, &used, sizeof(rc_scratch_string_t), RC_ALIGNOF(rc_scratch_string_t), &parse->scratch, RC_OFFSETOF(parse->scratch.objs, __rc_scratch_string_t)); ++ ptr = (char*)rc_alloc_scratch(parse->buffer, &parse->offset, (uint32_t)length + 1, RC_ALIGNOF(char), &parse->scratch, -1); ++ ++ if (!ptr || !*next) { ++ if (parse->offset >= 0) ++ parse->offset = RC_OUT_OF_MEMORY; ++ ++ return NULL; ++ } ++ ++ memcpy(ptr, text, length); ++ ptr[length] = '\0'; ++ ++ (*next)->left = NULL; ++ (*next)->right = NULL; ++ (*next)->value = ptr; ++ ++ return ptr; ++} ++ ++void rc_init_preparse_state(rc_preparse_state_t* preparse) ++{ ++ rc_init_parse_state(&preparse->parse, NULL); ++ rc_init_parse_state_memrefs(&preparse->parse, &preparse->memrefs); ++} ++ ++void rc_destroy_preparse_state(rc_preparse_state_t* preparse) ++{ ++ rc_destroy_parse_state(&preparse->parse); ++} ++ ++void rc_preparse_alloc_memrefs(rc_memrefs_t* memrefs, rc_preparse_state_t* preparse) ++{ ++ const uint32_t num_memrefs = rc_memrefs_count_memrefs(&preparse->memrefs); ++ const uint32_t num_modified_memrefs = rc_memrefs_count_modified_memrefs(&preparse->memrefs); ++ ++ if (preparse->parse.offset < 0) ++ return; ++ ++ if (memrefs) { ++ memset(memrefs, 0, sizeof(*memrefs)); ++ preparse->parse.memrefs = memrefs; ++ } ++ ++ if (num_memrefs) { ++ rc_memref_t* memref_items = RC_ALLOC_ARRAY(rc_memref_t, num_memrefs, &preparse->parse); ++ ++ if (memrefs) { ++ memrefs->memrefs.capacity = num_memrefs; ++ memrefs->memrefs.items = memref_items; ++ } ++ } ++ ++ if (num_modified_memrefs) { ++ rc_modified_memref_t* modified_memref_items = ++ RC_ALLOC_ARRAY(rc_modified_memref_t, num_modified_memrefs, &preparse->parse); ++ ++ if (memrefs) { ++ memrefs->modified_memrefs.capacity = num_modified_memrefs; ++ memrefs->modified_memrefs.items = modified_memref_items; ++ } ++ } ++ ++ /* when preparsing, this structure will be allocated at the end. when it's allocated earlier ++ * in the buffer, it could be followed by something aligned at 8 bytes. force the offset to ++ * an 8-byte boundary */ ++ if (!memrefs) { ++ rc_alloc(preparse->parse.buffer, &preparse->parse.offset, 0, 8, &preparse->parse.scratch, 0); ++ } ++} ++ ++static uint32_t rc_preparse_array_size(uint32_t needed, uint32_t minimum) ++{ ++ while (minimum < needed) ++ minimum <<= 1; ++ ++ return minimum; ++} ++ ++void rc_preparse_reserve_memrefs(rc_preparse_state_t* preparse, rc_memrefs_t* memrefs) ++{ ++ uint32_t num_memrefs = rc_memrefs_count_memrefs(&preparse->memrefs); ++ uint32_t num_modified_memrefs = rc_memrefs_count_modified_memrefs(&preparse->memrefs); ++ uint32_t available; ++ ++ if (preparse->parse.offset < 0) ++ return; ++ ++ if (num_memrefs) { ++ rc_memref_list_t* memref_list = &memrefs->memrefs; ++ while (memref_list->count == memref_list->capacity) { ++ if (!memref_list->next) ++ break; ++ ++ memref_list = memref_list->next; ++ } ++ ++ available = memref_list->capacity - memref_list->count; ++ if (available < num_memrefs) { ++ rc_memref_list_t* new_memref_list = (rc_memref_list_t*)calloc(1, sizeof(rc_memref_list_t)); ++ if (!new_memref_list) ++ return; ++ ++ new_memref_list->capacity = rc_preparse_array_size(num_memrefs - available, 16); ++ new_memref_list->items = (rc_memref_t*)malloc(new_memref_list->capacity * sizeof(rc_memref_t)); ++ new_memref_list->allocated = 1; ++ memref_list->next = new_memref_list; ++ } ++ } ++ ++ if (num_modified_memrefs) { ++ rc_modified_memref_list_t* modified_memref_list = &memrefs->modified_memrefs; ++ while (modified_memref_list->count == modified_memref_list->capacity) { ++ if (!modified_memref_list->next) ++ break; ++ ++ modified_memref_list = modified_memref_list->next; ++ } ++ ++ available = modified_memref_list->capacity - modified_memref_list->count; ++ if (available < num_modified_memrefs) { ++ rc_modified_memref_list_t* new_modified_memref_list = (rc_modified_memref_list_t*)calloc(1, sizeof(rc_modified_memref_list_t)); ++ if (!new_modified_memref_list) ++ return; ++ ++ new_modified_memref_list->capacity = rc_preparse_array_size(num_modified_memrefs - available, 8); ++ new_modified_memref_list->items = (rc_modified_memref_t*)malloc(new_modified_memref_list->capacity * sizeof(rc_modified_memref_t)); ++ new_modified_memref_list->allocated = 1; ++ modified_memref_list->next = new_modified_memref_list; ++ } ++ } ++ ++ preparse->parse.memrefs = memrefs; ++} ++ ++static void rc_preparse_sync_operand(rc_operand_t* operand, rc_parse_state_t* parse, const rc_memrefs_t* memrefs) ++{ ++ if (rc_operand_is_memref(operand) || rc_operand_is_recall(operand)) { ++ const rc_memref_t* src_memref = operand->value.memref; ++ ++ if (src_memref->value.memref_type == RC_MEMREF_TYPE_MODIFIED_MEMREF) { ++ const rc_modified_memref_list_t* modified_memref_list = &memrefs->modified_memrefs; ++ for (; modified_memref_list; modified_memref_list = modified_memref_list->next) { ++ const rc_modified_memref_t* modified_memref = modified_memref_list->items; ++ const rc_modified_memref_t* modified_memref_end = modified_memref + modified_memref_list->count; ++ ++ for (; modified_memref < modified_memref_end; ++modified_memref) { ++ if ((const rc_modified_memref_t*)src_memref == modified_memref) { ++ rc_modified_memref_t* dst_modified_memref = rc_alloc_modified_memref(parse, modified_memref->memref.value.size, ++ &modified_memref->parent, modified_memref->modifier_type, &modified_memref->modifier); ++ ++ operand->value.memref = &dst_modified_memref->memref; ++ return; ++ } ++ } ++ } ++ } ++ else { ++ const rc_memref_list_t* memref_list = &memrefs->memrefs; ++ for (; memref_list; memref_list = memref_list->next) { ++ const rc_memref_t* memref = memref_list->items; ++ const rc_memref_t* memref_end = memref + memref_list->count; ++ ++ for (; memref < memref_end; ++memref) { ++ if (src_memref == memref) { ++ operand->value.memref = rc_alloc_memref(parse, memref->address, memref->value.size); ++ return; ++ } ++ } ++ } ++ } ++ } ++} ++ ++void rc_preparse_copy_memrefs(rc_parse_state_t* parse, rc_memrefs_t* memrefs) ++{ ++ const rc_memref_list_t* memref_list = &memrefs->memrefs; ++ const rc_modified_memref_list_t* modified_memref_list = &memrefs->modified_memrefs; ++ ++ for (; memref_list; memref_list = memref_list->next) { ++ const rc_memref_t* memref = memref_list->items; ++ const rc_memref_t* memref_end = memref + memref_list->count; ++ ++ for (; memref < memref_end; ++memref) ++ rc_alloc_memref(parse, memref->address, memref->value.size); ++ } ++ ++ for (; modified_memref_list; modified_memref_list = modified_memref_list->next) { ++ rc_modified_memref_t* modified_memref = modified_memref_list->items; ++ const rc_modified_memref_t* modified_memref_end = modified_memref + modified_memref_list->count; ++ ++ for (; modified_memref < modified_memref_end; ++modified_memref) { ++ rc_preparse_sync_operand(&modified_memref->parent, parse, memrefs); ++ rc_preparse_sync_operand(&modified_memref->modifier, parse, memrefs); ++ ++ rc_alloc_modified_memref(parse, modified_memref->memref.value.size, ++ &modified_memref->parent, modified_memref->modifier_type, &modified_memref->modifier); ++ } ++ } ++} ++ ++void rc_reset_parse_state(rc_parse_state_t* parse, void* buffer) ++{ ++ parse->buffer = buffer; ++ ++ parse->offset = 0; ++ parse->memrefs = NULL; ++ parse->existing_memrefs = NULL; ++ parse->variables = NULL; ++ parse->measured_target = 0; ++ parse->lines_read = 0; ++ parse->addsource_oper = RC_OPERATOR_NONE; ++ parse->addsource_parent.type = RC_OPERAND_NONE; ++ parse->indirect_parent.type = RC_OPERAND_NONE; ++ parse->remember.type = RC_OPERAND_NONE; ++ parse->is_value = 0; ++ parse->has_required_hits = 0; ++ parse->measured_as_percent = 0; ++ parse->ignore_non_parse_errors = 0; ++ ++ parse->scratch.strings = NULL; ++} ++ ++void rc_init_parse_state(rc_parse_state_t* parse, void* buffer) ++{ ++ /* could use memset here, but rc_parse_state_t contains a 512 byte buffer that doesn't need to be initialized */ ++ rc_buffer_init(&parse->scratch.buffer); ++ memset(&parse->scratch.objs, 0, sizeof(parse->scratch.objs)); ++ ++ rc_reset_parse_state(parse, buffer); ++} ++ ++void rc_destroy_parse_state(rc_parse_state_t* parse) ++{ ++ rc_buffer_destroy(&parse->scratch.buffer); ++} +diff -rupbN melonDS.orig/src/rcheevos/src/rcheevos/condition.c melonDS.ra/src/rcheevos/src/rcheevos/condition.c +--- melonDS.orig/src/rcheevos/src/rcheevos/condition.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rcheevos/condition.c 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,754 @@ ++#include "rc_internal.h" ++ ++#include ++#include ++#include ++ ++static int rc_test_condition_compare(uint32_t value1, uint32_t value2, uint8_t oper) { ++ switch (oper) { ++ case RC_OPERATOR_EQ: return value1 == value2; ++ case RC_OPERATOR_NE: return value1 != value2; ++ case RC_OPERATOR_LT: return value1 < value2; ++ case RC_OPERATOR_LE: return value1 <= value2; ++ case RC_OPERATOR_GT: return value1 > value2; ++ case RC_OPERATOR_GE: return value1 >= value2; ++ default: return 1; ++ } ++} ++ ++static uint8_t rc_condition_determine_comparator(const rc_condition_t* self) { ++ switch (self->oper) { ++ case RC_OPERATOR_EQ: ++ case RC_OPERATOR_NE: ++ case RC_OPERATOR_LT: ++ case RC_OPERATOR_LE: ++ case RC_OPERATOR_GT: ++ case RC_OPERATOR_GE: ++ break; ++ ++ default: ++ /* not a comparison. should not be getting compared. but if it is, legacy behavior was to return 1 */ ++ return RC_PROCESSING_COMPARE_ALWAYS_TRUE; ++ } ++ ++ if ((self->operand1.type == RC_OPERAND_ADDRESS || self->operand1.type == RC_OPERAND_DELTA) && ++ /* TODO: allow modified memref comparisons */ ++ self->operand1.value.memref->value.memref_type == RC_MEMREF_TYPE_MEMREF && !rc_operand_is_float(&self->operand1)) { ++ /* left side is an integer memory reference */ ++ int needs_translate = (self->operand1.size != self->operand1.value.memref->value.size); ++ ++ if (self->operand2.type == RC_OPERAND_CONST) { ++ /* right side is a constant */ ++ if (self->operand1.type == RC_OPERAND_ADDRESS) ++ return needs_translate ? RC_PROCESSING_COMPARE_MEMREF_TO_CONST_TRANSFORMED : RC_PROCESSING_COMPARE_MEMREF_TO_CONST; ++ ++ return needs_translate ? RC_PROCESSING_COMPARE_DELTA_TO_CONST_TRANSFORMED : RC_PROCESSING_COMPARE_DELTA_TO_CONST; ++ } ++ else if ((self->operand2.type == RC_OPERAND_ADDRESS || self->operand2.type == RC_OPERAND_DELTA) && ++ self->operand2.value.memref->value.memref_type == RC_MEMREF_TYPE_MEMREF && !rc_operand_is_float(&self->operand2)) { ++ /* right side is an integer memory reference */ ++ const int is_same_memref = (self->operand1.value.memref == self->operand2.value.memref); ++ needs_translate |= (self->operand2.size != self->operand2.value.memref->value.size); ++ ++ if (self->operand1.type == RC_OPERAND_ADDRESS) { ++ if (self->operand2.type == RC_OPERAND_ADDRESS) { ++ if (is_same_memref && !needs_translate) { ++ /* comparing a memref to itself, will evaluate to a constant */ ++ return rc_test_condition_compare(0, 0, self->oper) ? RC_PROCESSING_COMPARE_ALWAYS_TRUE : RC_PROCESSING_COMPARE_ALWAYS_FALSE; ++ } ++ ++ return needs_translate ? RC_PROCESSING_COMPARE_MEMREF_TO_MEMREF_TRANSFORMED : RC_PROCESSING_COMPARE_MEMREF_TO_MEMREF; ++ } ++ ++ assert(self->operand2.type == RC_OPERAND_DELTA); ++ ++ if (is_same_memref) { ++ /* delta comparison is optimized to compare with itself (for detecting change) */ ++ return needs_translate ? RC_PROCESSING_COMPARE_MEMREF_TO_DELTA_TRANSFORMED : RC_PROCESSING_COMPARE_MEMREF_TO_DELTA; ++ } ++ } ++ else { ++ assert(self->operand1.type == RC_OPERAND_DELTA); ++ ++ if (self->operand2.type == RC_OPERAND_ADDRESS) { ++ if (is_same_memref) { ++ /* delta comparison is optimized to compare with itself (for detecting change) */ ++ return needs_translate ? RC_PROCESSING_COMPARE_DELTA_TO_MEMREF_TRANSFORMED : RC_PROCESSING_COMPARE_DELTA_TO_MEMREF; ++ } ++ } ++ } ++ } ++ } ++ ++ if (self->operand1.type == RC_OPERAND_CONST && self->operand2.type == RC_OPERAND_CONST) { ++ /* comparing constants will always generate a constant result */ ++ return rc_test_condition_compare(self->operand1.value.num, self->operand2.value.num, self->oper) ? ++ RC_PROCESSING_COMPARE_ALWAYS_TRUE : RC_PROCESSING_COMPARE_ALWAYS_FALSE; ++ } ++ ++ return RC_PROCESSING_COMPARE_DEFAULT; ++} ++ ++static int rc_parse_operator(const char** memaddr) { ++ const char* oper = *memaddr; ++ ++ switch (*oper) { ++ case '=': ++ ++(*memaddr); ++ (*memaddr) += (**memaddr == '='); ++ return RC_OPERATOR_EQ; ++ ++ case '!': ++ if (oper[1] == '=') { ++ (*memaddr) += 2; ++ return RC_OPERATOR_NE; ++ } ++ /* fall through */ ++ default: ++ return RC_INVALID_OPERATOR; ++ ++ case '<': ++ if (oper[1] == '=') { ++ (*memaddr) += 2; ++ return RC_OPERATOR_LE; ++ } ++ ++ ++(*memaddr); ++ return RC_OPERATOR_LT; ++ ++ case '>': ++ if (oper[1] == '=') { ++ (*memaddr) += 2; ++ return RC_OPERATOR_GE; ++ } ++ ++ ++(*memaddr); ++ return RC_OPERATOR_GT; ++ ++ case '*': ++ ++(*memaddr); ++ return RC_OPERATOR_MULT; ++ ++ case '/': ++ ++(*memaddr); ++ return RC_OPERATOR_DIV; ++ ++ case '&': ++ ++(*memaddr); ++ return RC_OPERATOR_AND; ++ ++ case '^': ++ ++(*memaddr); ++ return RC_OPERATOR_XOR; ++ ++ case '%': ++ ++(*memaddr); ++ return RC_OPERATOR_MOD; ++ ++ case '+': ++ ++(*memaddr); ++ return RC_OPERATOR_ADD; ++ ++ case '-': ++ ++(*memaddr); ++ return RC_OPERATOR_SUB; ++ ++ case '\0':/* end of string */ ++ case '_': /* next condition */ ++ case 'S': /* next condset */ ++ case ')': /* end of macro */ ++ case '$': /* maximum of values */ ++ /* valid condition separator, condition may not have an operator */ ++ return RC_OPERATOR_NONE; ++ } ++} ++ ++void rc_condition_convert_to_operand(const rc_condition_t* condition, rc_operand_t* operand, rc_parse_state_t* parse) { ++ if (condition->oper == RC_OPERATOR_NONE) { ++ if (operand != &condition->operand1) ++ memcpy(operand, &condition->operand1, sizeof(*operand)); ++ } ++ else { ++ uint8_t new_size = RC_MEMSIZE_32_BITS; ++ if (rc_operand_is_float(&condition->operand1) || rc_operand_is_float(&condition->operand2)) ++ new_size = RC_MEMSIZE_FLOAT; ++ ++ /* NOTE: this makes the operand include the modification, but we have to also ++ * leave the modification in the condition so the condition reflects the actual ++ * definition. This doesn't affect the evaluation logic since this method is only ++ * called for combining conditions and Measured, and the Measured handling function ++ * ignores the operator assuming it's been handled by a modified memref chain */ ++ operand->value.memref = (rc_memref_t*)rc_alloc_modified_memref(parse, ++ new_size, &condition->operand1, condition->oper, &condition->operand2); ++ ++ /* not actually an address, just a non-delta memref read */ ++ operand->type = operand->memref_access_type = RC_OPERAND_ADDRESS; ++ ++ operand->size = new_size; ++ } ++} ++ ++rc_condition_t* rc_parse_condition(const char** memaddr, rc_parse_state_t* parse) { ++ rc_condition_t * self = RC_ALLOC(rc_condition_t, parse); ++ rc_parse_condition_internal(self, memaddr, parse); ++ return (parse->offset < 0) ? NULL : self; ++} ++ ++void rc_parse_condition_internal(rc_condition_t* self, const char** memaddr, rc_parse_state_t* parse) { ++ const char* aux; ++ int result; ++ int can_modify = 0; ++ ++ aux = *memaddr; ++ self->current_hits = 0; ++ self->is_true = 0; ++ self->optimized_comparator = RC_PROCESSING_COMPARE_DEFAULT; ++ ++ if (*aux != 0 && aux[1] == ':') { ++ switch (*aux) { ++ case 'p': case 'P': self->type = RC_CONDITION_PAUSE_IF; break; ++ case 'r': case 'R': self->type = RC_CONDITION_RESET_IF; break; ++ case 'a': case 'A': self->type = RC_CONDITION_ADD_SOURCE; can_modify = 1; break; ++ case 'b': case 'B': self->type = RC_CONDITION_SUB_SOURCE; can_modify = 1; break; ++ case 'c': case 'C': self->type = RC_CONDITION_ADD_HITS; break; ++ case 'd': case 'D': self->type = RC_CONDITION_SUB_HITS; break; ++ case 'n': case 'N': self->type = RC_CONDITION_AND_NEXT; break; ++ case 'o': case 'O': self->type = RC_CONDITION_OR_NEXT; break; ++ case 'm': case 'M': self->type = RC_CONDITION_MEASURED; break; ++ case 'q': case 'Q': self->type = RC_CONDITION_MEASURED_IF; break; ++ case 'i': case 'I': self->type = RC_CONDITION_ADD_ADDRESS; can_modify = 1; break; ++ case 't': case 'T': self->type = RC_CONDITION_TRIGGER; break; ++ case 'k': case 'K': self->type = RC_CONDITION_REMEMBER; can_modify = 1; break; ++ case 'z': case 'Z': self->type = RC_CONDITION_RESET_NEXT_IF; break; ++ case 'g': case 'G': ++ parse->measured_as_percent = 1; ++ self->type = RC_CONDITION_MEASURED; ++ break; ++ ++ /* e f h j l s u v w x y */ ++ default: ++ parse->offset = RC_INVALID_CONDITION_TYPE; ++ return; ++ } ++ ++ aux += 2; ++ } ++ else { ++ self->type = RC_CONDITION_STANDARD; ++ } ++ ++ result = rc_parse_operand(&self->operand1, &aux, parse); ++ if (result < 0) { ++ parse->offset = result; ++ return; ++ } ++ ++ result = rc_parse_operator(&aux); ++ if (result < 0) { ++ parse->offset = result; ++ return; ++ } ++ ++ self->oper = (uint8_t)result; ++ ++ if (self->oper == RC_OPERATOR_NONE) { ++ /* non-modifying statements must have a second operand */ ++ if (!can_modify) { ++ /* measured does not require a second operand when used in a value */ ++ if (self->type != RC_CONDITION_MEASURED && !parse->ignore_non_parse_errors) { ++ parse->offset = RC_INVALID_OPERATOR; ++ return; ++ } ++ } ++ ++ /* provide dummy operand of '1' and no required hits */ ++ rc_operand_set_const(&self->operand2, 1); ++ self->required_hits = 0; ++ *memaddr = aux; ++ return; ++ } ++ ++ if (can_modify && !rc_operator_is_modifying(self->oper)) { ++ /* comparison operators are not valid on modifying statements */ ++ switch (self->type) { ++ case RC_CONDITION_ADD_SOURCE: ++ case RC_CONDITION_SUB_SOURCE: ++ case RC_CONDITION_ADD_ADDRESS: ++ /* prevent parse errors on legacy achievements where a condition was present before changing the type */ ++ self->oper = RC_OPERATOR_NONE; ++ break; ++ ++ default: ++ if (!parse->ignore_non_parse_errors) { ++ parse->offset = RC_INVALID_OPERATOR; ++ return; ++ } ++ break; ++ } ++ } ++ ++ result = rc_parse_operand(&self->operand2, &aux, parse); ++ if (result < 0) { ++ parse->offset = result; ++ return; ++ } ++ ++ if (self->oper == RC_OPERATOR_NONE) { ++ /* if operator is none, explicitly clear out the right side */ ++ rc_operand_set_const(&self->operand2, 0); ++ } ++ ++ if (*aux == '(') { ++ char* end; ++ self->required_hits = (unsigned)strtoul(++aux, &end, 10); ++ ++ if (end == aux || *end != ')') { ++ parse->offset = RC_INVALID_REQUIRED_HITS; ++ return; ++ } ++ ++ /* if operator is none, explicitly clear out the required hits */ ++ if (self->oper == RC_OPERATOR_NONE) ++ self->required_hits = 0; ++ else ++ parse->has_required_hits = 1; ++ ++ aux = end + 1; ++ } ++ else if (*aux == '.') { ++ char* end; ++ self->required_hits = (unsigned)strtoul(++aux, &end, 10); ++ ++ if (end == aux || *end != '.') { ++ parse->offset = RC_INVALID_REQUIRED_HITS; ++ return; ++ } ++ ++ /* if operator is none, explicitly clear out the required hits */ ++ if (self->oper == RC_OPERATOR_NONE) ++ self->required_hits = 0; ++ else ++ parse->has_required_hits = 1; ++ ++ aux = end + 1; ++ } ++ else { ++ self->required_hits = 0; ++ } ++ ++ if (parse->buffer != 0) ++ self->optimized_comparator = rc_condition_determine_comparator(self); ++ ++ *memaddr = aux; ++} ++ ++void rc_condition_update_parse_state(rc_condition_t* condition, rc_parse_state_t* parse) { ++ /* type of values in the chain are determined by the parent. ++ * the last element of a chain is determined by the operand ++ * ++ * 1 + 1.5 + 1.75 + 1.0 => (int)1 + (int)1 + (int)1 + (float)1 = (float)4.0 ++ * 1.0 + 1.5 + 1.75 + 1.0 => (float)1.0 + (float)1.5 + (float)1.75 + (float)1.0 = (float)5.25 ++ * 1.0 + 1.5 + 1.75 + 1 => (float)1.0 + (float)1.5 + (float)1.75 + (int)1 = (int)5 ++ */ ++ ++ switch (condition->type) { ++ case RC_CONDITION_ADD_ADDRESS: ++ if (condition->oper != RC_OPERAND_NONE) ++ rc_condition_convert_to_operand(condition, &parse->indirect_parent, parse); ++ else ++ memcpy(&parse->indirect_parent, &condition->operand1, sizeof(parse->indirect_parent)); ++ ++ break; ++ ++ case RC_CONDITION_ADD_SOURCE: ++ if (parse->addsource_parent.type == RC_OPERAND_NONE) { ++ rc_condition_convert_to_operand(condition, &parse->addsource_parent, parse); ++ } ++ else { ++ rc_operand_t cond_operand; ++ /* type determined by parent */ ++ const uint8_t new_size = rc_operand_is_float(&parse->addsource_parent) ? RC_MEMSIZE_FLOAT : RC_MEMSIZE_32_BITS; ++ ++ rc_condition_convert_to_operand(condition, &cond_operand, parse); ++ rc_operand_addsource(&cond_operand, parse, new_size); ++ memcpy(&parse->addsource_parent, &cond_operand, sizeof(cond_operand)); ++ } ++ ++ parse->addsource_oper = RC_OPERATOR_ADD_ACCUMULATOR; ++ parse->indirect_parent.type = RC_OPERAND_NONE; ++ break; ++ ++ case RC_CONDITION_SUB_SOURCE: ++ if (parse->addsource_parent.type == RC_OPERAND_NONE) { ++ rc_condition_convert_to_operand(condition, &parse->addsource_parent, parse); ++ parse->addsource_oper = RC_OPERATOR_SUB_PARENT; ++ } ++ else { ++ rc_operand_t cond_operand; ++ /* type determined by parent */ ++ const uint8_t new_size = rc_operand_is_float(&parse->addsource_parent) ? RC_MEMSIZE_FLOAT : RC_MEMSIZE_32_BITS; ++ ++ if (parse->addsource_oper == RC_OPERATOR_ADD_ACCUMULATOR && !rc_operand_is_memref(&parse->addsource_parent)) { ++ /* if the previous element was a constant we have to turn it into a memref by adding zero */ ++ rc_modified_memref_t* memref; ++ rc_operand_t zero; ++ rc_operand_set_const(&zero, 0); ++ memref = rc_alloc_modified_memref(parse, ++ parse->addsource_parent.size, &parse->addsource_parent, RC_OPERATOR_ADD_ACCUMULATOR, &zero); ++ parse->addsource_parent.value.memref = (rc_memref_t*)memref; ++ parse->addsource_parent.type = RC_OPERAND_ADDRESS; ++ } ++ else if (parse->addsource_oper == RC_OPERATOR_SUB_PARENT) { ++ /* if the previous element was also a SubSource, we have to insert a 0 and start subtracting from there */ ++ rc_modified_memref_t* negate; ++ rc_operand_t zero; ++ ++ if (rc_operand_is_float(&parse->addsource_parent)) ++ rc_operand_set_float_const(&zero, 0.0); ++ else ++ rc_operand_set_const(&zero, 0); ++ ++ negate = rc_alloc_modified_memref(parse, new_size, &parse->addsource_parent, RC_OPERATOR_SUB_PARENT, &zero); ++ parse->addsource_parent.value.memref = (rc_memref_t*)negate; ++ parse->addsource_parent.size = zero.size; ++ } ++ ++ /* subtract the condition from the chain */ ++ parse->addsource_oper = rc_operand_is_memref(&parse->addsource_parent) ? RC_OPERATOR_SUB_ACCUMULATOR : RC_OPERATOR_SUB_PARENT; ++ rc_condition_convert_to_operand(condition, &cond_operand, parse); ++ rc_operand_addsource(&cond_operand, parse, new_size); ++ memcpy(&parse->addsource_parent, &cond_operand, sizeof(cond_operand)); ++ ++ /* indicate the next value can be added to the chain */ ++ parse->addsource_oper = RC_OPERATOR_ADD_ACCUMULATOR; ++ } ++ ++ parse->indirect_parent.type = RC_OPERAND_NONE; ++ break; ++ ++ case RC_CONDITION_REMEMBER: ++ if (condition->operand1.type == RC_OPERAND_RECALL && ++ condition->oper == RC_OPERATOR_NONE && ++ parse->addsource_parent.type == RC_OPERAND_NONE && ++ parse->indirect_parent.type == RC_OPERAND_NONE) { ++ /* Remembering {recall} without any modifications is a no-op */ ++ break; ++ } ++ ++ rc_condition_convert_to_operand(condition, &condition->operand1, parse); ++ ++ if (parse->addsource_parent.type != RC_OPERAND_NONE) { ++ /* type determined by leaf */ ++ rc_operand_addsource(&condition->operand1, parse, condition->operand1.size); ++ condition->operand1.is_combining = 1; ++ } ++ ++ memcpy(&parse->remember, &condition->operand1, sizeof(parse->remember)); ++ ++ parse->addsource_parent.type = RC_OPERAND_NONE; ++ parse->indirect_parent.type = RC_OPERAND_NONE; ++ break; ++ ++ case RC_CONDITION_MEASURED: ++ /* Measured condition can have modifiers in values */ ++ if (parse->is_value) { ++ switch (condition->oper) { ++ case RC_OPERATOR_AND: ++ case RC_OPERATOR_XOR: ++ case RC_OPERATOR_DIV: ++ case RC_OPERATOR_MULT: ++ case RC_OPERATOR_MOD: ++ case RC_OPERATOR_ADD: ++ case RC_OPERATOR_SUB: ++ rc_condition_convert_to_operand(condition, &condition->operand1, parse); ++ break; ++ ++ default: ++ break; ++ } ++ } ++ ++ /* fallthrough */ /* to default */ ++ ++ default: ++ if (parse->addsource_parent.type != RC_OPERAND_NONE) { ++ /* type determined by leaf */ ++ if (parse->addsource_oper == RC_OPERATOR_ADD_ACCUMULATOR) ++ parse->addsource_oper = RC_OPERATOR_ADD; ++ ++ rc_operand_addsource(&condition->operand1, parse, condition->operand1.size); ++ condition->operand1.is_combining = 1; ++ ++ if (parse->buffer) ++ condition->optimized_comparator = rc_condition_determine_comparator(condition); ++ } ++ ++ parse->addsource_parent.type = RC_OPERAND_NONE; ++ parse->indirect_parent.type = RC_OPERAND_NONE; ++ break; ++ } ++} ++ ++static const rc_modified_memref_t* rc_operand_get_modified_memref(const rc_operand_t* operand) { ++ if (!rc_operand_is_memref(operand)) ++ return NULL; ++ ++ if (operand->value.memref->value.memref_type != RC_MEMREF_TYPE_MODIFIED_MEMREF) ++ return NULL; ++ ++ return (rc_modified_memref_t*)operand->value.memref; ++} ++ ++/* rc_condition_update_parse_state will mutate the operand1 to point at the modified memref ++ * containing the accumulated result up until that point. this function returns the original ++ * unmodified operand1 from parsing the definition. ++ */ ++const rc_operand_t* rc_condition_get_real_operand1(const rc_condition_t* self) { ++ const rc_operand_t* operand = &self->operand1; ++ const rc_modified_memref_t* modified_memref; ++ ++ if (operand->is_combining) { ++ /* operand = "previous + current" - extract current */ ++ const rc_modified_memref_t* combining_modified_memref = rc_operand_get_modified_memref(operand); ++ if (combining_modified_memref) ++ operand = &combining_modified_memref->modifier; ++ } ++ ++ /* modifying operators are merged into an rc_modified_memref_t ++ * if operand1 is a modified memref, assume it's been merged with the right side and ++ * extract the parent which is the actual operand1. */ ++ modified_memref = rc_operand_get_modified_memref(operand); ++ if (modified_memref) { ++ if (modified_memref->modifier_type == RC_OPERATOR_INDIRECT_READ) { ++ /* if the modified memref is an indirect read, the parent is the indirect ++ * address and the modifier is the offset. the actual size and address are ++ * stored in the modified memref - use it */ ++ } else if (rc_operator_is_modifying(self->oper) && self->oper != RC_OPERATOR_NONE) { ++ /* operand = "parent*modifier" - extract parent.modifier will already be in operand2 */ ++ operand = &modified_memref->parent; ++ } ++ } ++ ++ return operand; ++} ++ ++int rc_condition_is_combining(const rc_condition_t* self) { ++ switch (self->type) { ++ case RC_CONDITION_STANDARD: ++ case RC_CONDITION_PAUSE_IF: ++ case RC_CONDITION_RESET_IF: ++ case RC_CONDITION_MEASURED_IF: ++ case RC_CONDITION_TRIGGER: ++ case RC_CONDITION_MEASURED: ++ return 0; ++ ++ default: ++ return 1; ++ } ++} ++ ++static int rc_test_condition_compare_memref_to_const(rc_condition_t* self) { ++ const uint32_t value1 = self->operand1.value.memref->value.value; ++ const uint32_t value2 = self->operand2.value.num; ++ assert(self->operand1.size == self->operand1.value.memref->value.size); ++ return rc_test_condition_compare(value1, value2, self->oper); ++} ++ ++static int rc_test_condition_compare_delta_to_const(rc_condition_t* self) { ++ const rc_memref_value_t* memref1 = &self->operand1.value.memref->value; ++ const uint32_t value1 = (memref1->changed) ? memref1->prior : memref1->value; ++ const uint32_t value2 = self->operand2.value.num; ++ assert(self->operand1.size == self->operand1.value.memref->value.size); ++ return rc_test_condition_compare(value1, value2, self->oper); ++} ++ ++static int rc_test_condition_compare_memref_to_memref(rc_condition_t* self) { ++ const uint32_t value1 = self->operand1.value.memref->value.value; ++ const uint32_t value2 = self->operand2.value.memref->value.value; ++ assert(self->operand1.size == self->operand1.value.memref->value.size); ++ assert(self->operand2.size == self->operand2.value.memref->value.size); ++ return rc_test_condition_compare(value1, value2, self->oper); ++} ++ ++static int rc_test_condition_compare_memref_to_delta(rc_condition_t* self) { ++ const rc_memref_value_t* memref = &self->operand1.value.memref->value; ++ assert(self->operand1.value.memref == self->operand2.value.memref); ++ assert(self->operand1.size == self->operand1.value.memref->value.size); ++ assert(self->operand2.size == self->operand2.value.memref->value.size); ++ ++ if (memref->changed) ++ return rc_test_condition_compare(memref->value, memref->prior, self->oper); ++ ++ switch (self->oper) { ++ case RC_OPERATOR_EQ: ++ case RC_OPERATOR_GE: ++ case RC_OPERATOR_LE: ++ return 1; ++ ++ default: ++ return 0; ++ } ++} ++ ++static int rc_test_condition_compare_delta_to_memref(rc_condition_t* self) { ++ const rc_memref_value_t* memref = &self->operand1.value.memref->value; ++ assert(self->operand1.value.memref == self->operand2.value.memref); ++ assert(self->operand1.size == self->operand1.value.memref->value.size); ++ assert(self->operand2.size == self->operand2.value.memref->value.size); ++ ++ if (memref->changed) ++ return rc_test_condition_compare(memref->prior, memref->value, self->oper); ++ ++ switch (self->oper) { ++ case RC_OPERATOR_EQ: ++ case RC_OPERATOR_GE: ++ case RC_OPERATOR_LE: ++ return 1; ++ ++ default: ++ return 0; ++ } ++} ++ ++static int rc_test_condition_compare_memref_to_const_transformed(rc_condition_t* self) { ++ rc_typed_value_t value1; ++ const uint32_t value2 = self->operand2.value.num; ++ ++ value1.type = RC_VALUE_TYPE_UNSIGNED; ++ value1.value.u32 = self->operand1.value.memref->value.value; ++ rc_transform_memref_value(&value1, self->operand1.size); ++ ++ return rc_test_condition_compare(value1.value.u32, value2, self->oper); ++} ++ ++static int rc_test_condition_compare_delta_to_const_transformed(rc_condition_t* self) { ++ rc_typed_value_t value1; ++ const rc_memref_value_t* memref1 = &self->operand1.value.memref->value; ++ const uint32_t value2 = self->operand2.value.num; ++ ++ value1.type = RC_VALUE_TYPE_UNSIGNED; ++ value1.value.u32 = (memref1->changed) ? memref1->prior : memref1->value; ++ rc_transform_memref_value(&value1, self->operand1.size); ++ ++ return rc_test_condition_compare(value1.value.u32, value2, self->oper); ++} ++ ++static int rc_test_condition_compare_memref_to_memref_transformed(rc_condition_t* self) { ++ rc_typed_value_t value1, value2; ++ ++ value1.type = RC_VALUE_TYPE_UNSIGNED; ++ value1.value.u32 = self->operand1.value.memref->value.value; ++ rc_transform_memref_value(&value1, self->operand1.size); ++ ++ value2.type = RC_VALUE_TYPE_UNSIGNED; ++ value2.value.u32 = self->operand2.value.memref->value.value; ++ rc_transform_memref_value(&value2, self->operand2.size); ++ ++ return rc_test_condition_compare(value1.value.u32, value2.value.u32, self->oper); ++} ++ ++static int rc_test_condition_compare_memref_to_delta_transformed(rc_condition_t* self) { ++ const rc_memref_value_t* memref = &self->operand1.value.memref->value; ++ assert(self->operand1.value.memref == self->operand2.value.memref); ++ ++ if (memref->changed) { ++ rc_typed_value_t value1, value2; ++ ++ value1.type = RC_VALUE_TYPE_UNSIGNED; ++ value1.value.u32 = memref->value; ++ rc_transform_memref_value(&value1, self->operand1.size); ++ ++ value2.type = RC_VALUE_TYPE_UNSIGNED; ++ value2.value.u32 = memref->prior; ++ rc_transform_memref_value(&value2, self->operand2.size); ++ ++ return rc_test_condition_compare(value1.value.u32, value2.value.u32, self->oper); ++ } ++ ++ switch (self->oper) { ++ case RC_OPERATOR_EQ: ++ case RC_OPERATOR_GE: ++ case RC_OPERATOR_LE: ++ return 1; ++ ++ default: ++ return 0; ++ } ++} ++ ++static int rc_test_condition_compare_delta_to_memref_transformed(rc_condition_t* self) { ++ const rc_memref_value_t* memref = &self->operand1.value.memref->value; ++ assert(self->operand1.value.memref == self->operand2.value.memref); ++ ++ if (memref->changed) { ++ rc_typed_value_t value1, value2; ++ ++ value1.type = RC_VALUE_TYPE_UNSIGNED; ++ value1.value.u32 = memref->prior; ++ rc_transform_memref_value(&value1, self->operand1.size); ++ ++ value2.type = RC_VALUE_TYPE_UNSIGNED; ++ value2.value.u32 = memref->value; ++ rc_transform_memref_value(&value2, self->operand2.size); ++ ++ return rc_test_condition_compare(value1.value.u32, value2.value.u32, self->oper); ++ } ++ ++ switch (self->oper) { ++ case RC_OPERATOR_EQ: ++ case RC_OPERATOR_GE: ++ case RC_OPERATOR_LE: ++ return 1; ++ ++ default: ++ return 0; ++ } ++} ++ ++int rc_test_condition(rc_condition_t* self, rc_eval_state_t* eval_state) { ++ rc_typed_value_t value1, value2; ++ ++ /* use an optimized comparator whenever possible */ ++ switch (self->optimized_comparator) { ++ case RC_PROCESSING_COMPARE_MEMREF_TO_CONST: ++ return rc_test_condition_compare_memref_to_const(self); ++ case RC_PROCESSING_COMPARE_MEMREF_TO_DELTA: ++ return rc_test_condition_compare_memref_to_delta(self); ++ case RC_PROCESSING_COMPARE_MEMREF_TO_MEMREF: ++ return rc_test_condition_compare_memref_to_memref(self); ++ case RC_PROCESSING_COMPARE_DELTA_TO_CONST: ++ return rc_test_condition_compare_delta_to_const(self); ++ case RC_PROCESSING_COMPARE_DELTA_TO_MEMREF: ++ return rc_test_condition_compare_delta_to_memref(self); ++ case RC_PROCESSING_COMPARE_MEMREF_TO_CONST_TRANSFORMED: ++ return rc_test_condition_compare_memref_to_const_transformed(self); ++ case RC_PROCESSING_COMPARE_MEMREF_TO_DELTA_TRANSFORMED: ++ return rc_test_condition_compare_memref_to_delta_transformed(self); ++ case RC_PROCESSING_COMPARE_MEMREF_TO_MEMREF_TRANSFORMED: ++ return rc_test_condition_compare_memref_to_memref_transformed(self); ++ case RC_PROCESSING_COMPARE_DELTA_TO_CONST_TRANSFORMED: ++ return rc_test_condition_compare_delta_to_const_transformed(self); ++ case RC_PROCESSING_COMPARE_DELTA_TO_MEMREF_TRANSFORMED: ++ return rc_test_condition_compare_delta_to_memref_transformed(self); ++ case RC_PROCESSING_COMPARE_ALWAYS_TRUE: ++ return 1; ++ case RC_PROCESSING_COMPARE_ALWAYS_FALSE: ++ return 0; ++ default: ++ rc_evaluate_operand(&value1, &self->operand1, eval_state); ++ break; ++ } ++ ++ rc_evaluate_operand(&value2, &self->operand2, eval_state); ++ ++ return rc_typed_value_compare(&value1, &value2, self->oper); ++} ++ ++void rc_evaluate_condition_value(rc_typed_value_t* value, rc_condition_t* self, rc_eval_state_t* eval_state) { ++ rc_typed_value_t amount; ++ ++ rc_evaluate_operand(value, &self->operand1, eval_state); ++ rc_evaluate_operand(&amount, &self->operand2, eval_state); ++ ++ rc_typed_value_combine(value, &amount, self->oper); ++} +diff -rupbN melonDS.orig/src/rcheevos/src/rcheevos/condset.c melonDS.ra/src/rcheevos/src/rcheevos/condset.c +--- melonDS.orig/src/rcheevos/src/rcheevos/condset.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rcheevos/condset.c 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,770 @@ ++#include "rc_internal.h" ++ ++#include /* memcpy */ ++ ++enum { ++ RC_CONDITION_CLASSIFICATION_COMBINING, ++ RC_CONDITION_CLASSIFICATION_PAUSE, ++ RC_CONDITION_CLASSIFICATION_RESET, ++ RC_CONDITION_CLASSIFICATION_HITTARGET, ++ RC_CONDITION_CLASSIFICATION_MEASURED, ++ RC_CONDITION_CLASSIFICATION_OTHER, ++ RC_CONDITION_CLASSIFICATION_INDIRECT ++}; ++ ++static int rc_classify_condition(const rc_condition_t* cond) { ++ switch (cond->type) { ++ case RC_CONDITION_PAUSE_IF: ++ return RC_CONDITION_CLASSIFICATION_PAUSE; ++ ++ case RC_CONDITION_RESET_IF: ++ return RC_CONDITION_CLASSIFICATION_RESET; ++ ++ case RC_CONDITION_ADD_ADDRESS: ++ case RC_CONDITION_ADD_SOURCE: ++ case RC_CONDITION_SUB_SOURCE: ++ /* these are handled by rc_modified_memref_t */ ++ return RC_CONDITION_CLASSIFICATION_INDIRECT; ++ ++ case RC_CONDITION_ADD_HITS: ++ case RC_CONDITION_AND_NEXT: ++ case RC_CONDITION_OR_NEXT: ++ case RC_CONDITION_REMEMBER: ++ case RC_CONDITION_RESET_NEXT_IF: ++ case RC_CONDITION_SUB_HITS: ++ return RC_CONDITION_CLASSIFICATION_COMBINING; ++ ++ case RC_CONDITION_MEASURED: ++ case RC_CONDITION_MEASURED_IF: ++ /* even if not measuring a hit target, we still want to evaluate it every frame */ ++ return RC_CONDITION_CLASSIFICATION_MEASURED; ++ ++ default: ++ if (cond->required_hits != 0) ++ return RC_CONDITION_CLASSIFICATION_HITTARGET; ++ ++ return RC_CONDITION_CLASSIFICATION_OTHER; ++ } ++} ++ ++static int32_t rc_classify_conditions(rc_condset_t* self, const char* memaddr, const rc_parse_state_t* parent_parse) { ++ rc_parse_state_t parse; ++ rc_memrefs_t memrefs; ++ rc_condition_t condition; ++ int classification; ++ uint32_t index = 0; ++ uint32_t chain_length = 1; ++ ++ rc_init_parse_state(&parse, NULL); ++ rc_init_parse_state_memrefs(&parse, &memrefs); ++ parse.ignore_non_parse_errors = parent_parse->ignore_non_parse_errors; ++ ++ do { ++ rc_parse_condition_internal(&condition, &memaddr, &parse); ++ ++ if (parse.offset < 0) { ++ rc_destroy_parse_state(&parse); ++ return parse.offset; ++ } ++ ++ ++index; ++ ++ classification = rc_classify_condition(&condition); ++ switch (classification) { ++ case RC_CONDITION_CLASSIFICATION_COMBINING: ++ ++chain_length; ++ continue; ++ ++ case RC_CONDITION_CLASSIFICATION_INDIRECT: ++ ++self->num_indirect_conditions; ++ continue; ++ ++ case RC_CONDITION_CLASSIFICATION_PAUSE: ++ self->num_pause_conditions += chain_length; ++ break; ++ ++ case RC_CONDITION_CLASSIFICATION_RESET: ++ self->num_reset_conditions += chain_length; ++ break; ++ ++ case RC_CONDITION_CLASSIFICATION_HITTARGET: ++ self->num_hittarget_conditions += chain_length; ++ break; ++ ++ case RC_CONDITION_CLASSIFICATION_MEASURED: ++ self->num_measured_conditions += chain_length; ++ break; ++ ++ default: ++ self->num_other_conditions += chain_length; ++ break; ++ } ++ ++ chain_length = 1; ++ } while (*memaddr++ == '_'); ++ ++ /* any combining conditions that don't actually feed into a non-combining condition ++ * need to still have space allocated for them. put them in "other" to match the ++ * logic in rc_find_next_classification */ ++ self->num_other_conditions += chain_length - 1; ++ ++ rc_destroy_parse_state(&parse); ++ ++ return (int32_t)index; ++} ++ ++static int rc_find_next_classification(const char* memaddr) { ++ rc_parse_state_t parse; ++ rc_memrefs_t memrefs; ++ rc_condition_t condition; ++ int classification; ++ ++ rc_init_parse_state(&parse, NULL); ++ rc_init_parse_state_memrefs(&parse, &memrefs); ++ ++ do { ++ rc_parse_condition_internal(&condition, &memaddr, &parse); ++ if (parse.offset < 0) ++ break; ++ ++ classification = rc_classify_condition(&condition); ++ switch (classification) { ++ case RC_CONDITION_CLASSIFICATION_COMBINING: ++ case RC_CONDITION_CLASSIFICATION_INDIRECT: ++ break; ++ ++ default: ++ return classification; ++ } ++ } while (*memaddr++ == '_'); ++ ++ return RC_CONDITION_CLASSIFICATION_OTHER; ++} ++ ++static void rc_condition_update_recall_operand(rc_operand_t* operand, const rc_operand_t* remember) ++{ ++ if (operand->type == RC_OPERAND_RECALL) { ++ if (rc_operand_type_is_memref(operand->memref_access_type) && operand->value.memref == NULL) { ++ memcpy(operand, remember, sizeof(*remember)); ++ operand->memref_access_type = operand->type; ++ operand->type = RC_OPERAND_RECALL; ++ } ++ } ++ else if (rc_operand_is_memref(operand) && operand->value.memref->value.memref_type == RC_MEMREF_TYPE_MODIFIED_MEMREF) { ++ rc_modified_memref_t* modified_memref = (rc_modified_memref_t*)operand->value.memref; ++ rc_condition_update_recall_operand(&modified_memref->parent, remember); ++ rc_condition_update_recall_operand(&modified_memref->modifier, remember); ++ } ++} ++ ++static void rc_update_condition_pause_remember(rc_condset_t* self) { ++ rc_operand_t* pause_remember = NULL; ++ rc_condition_t* condition; ++ rc_condition_t* pause_conditions; ++ const rc_condition_t* end_pause_condition; ++ ++ /* ASSERT: pause conditions are first conditions */ ++ pause_conditions = rc_condset_get_conditions(self); ++ end_pause_condition = pause_conditions + self->num_pause_conditions; ++ ++ for (condition = pause_conditions; condition < end_pause_condition; ++condition) { ++ if (condition->type == RC_CONDITION_REMEMBER) { ++ pause_remember = &condition->operand1; ++ } ++ else if (pause_remember == NULL) { ++ /* if we picked up a non-pause remember, discard it */ ++ if (condition->operand1.type == RC_OPERAND_RECALL && ++ rc_operand_type_is_memref(condition->operand1.memref_access_type)) { ++ condition->operand1.value.memref = NULL; ++ } ++ ++ if (condition->operand2.type == RC_OPERAND_RECALL && ++ rc_operand_type_is_memref(condition->operand2.memref_access_type)) { ++ condition->operand2.value.memref = NULL; ++ } ++ } ++ } ++ ++ if (pause_remember) { ++ for (condition = self->conditions; condition; condition = condition->next) { ++ if (condition >= end_pause_condition) { ++ /* if we didn't find a remember for a non-pause condition, use the last pause remember */ ++ rc_condition_update_recall_operand(&condition->operand1, pause_remember); ++ rc_condition_update_recall_operand(&condition->operand2, pause_remember); ++ } ++ ++ /* Anything after this point will have already been handled */ ++ if (condition->type == RC_CONDITION_REMEMBER) ++ break; ++ } ++ } ++} ++ ++rc_condset_t* rc_parse_condset(const char** memaddr, rc_parse_state_t* parse) { ++ rc_condset_with_trailing_conditions_t* condset_with_conditions; ++ rc_condset_t local_condset; ++ rc_condset_t* self; ++ rc_condition_t condition; ++ rc_condition_t* conditions; ++ rc_condition_t** next; ++ rc_condition_t* pause_conditions = NULL; ++ rc_condition_t* reset_conditions = NULL; ++ rc_condition_t* hittarget_conditions = NULL; ++ rc_condition_t* measured_conditions = NULL; ++ rc_condition_t* other_conditions = NULL; ++ rc_condition_t* indirect_conditions = NULL; ++ int classification, combining_classification = RC_CONDITION_CLASSIFICATION_COMBINING; ++ uint32_t measured_target = 0; ++ int32_t result; ++ ++ if (**memaddr == 'S' || **memaddr == 's' || !**memaddr) { ++ /* empty group - editor allows it, so we have to support it */ ++ self = RC_ALLOC(rc_condset_t, parse); ++ memset(self, 0, sizeof(*self)); ++ return self; ++ } ++ ++ memset(&local_condset, 0, sizeof(local_condset)); ++ result = rc_classify_conditions(&local_condset, *memaddr, parse); ++ if (result < 0) { ++ parse->offset = result; ++ return NULL; ++ } ++ ++ condset_with_conditions = RC_ALLOC_WITH_TRAILING(rc_condset_with_trailing_conditions_t, ++ rc_condition_t, conditions, result, parse); ++ if (parse->offset < 0) ++ return NULL; ++ ++ self = (rc_condset_t*)condset_with_conditions; ++ memcpy(self, &local_condset, sizeof(local_condset)); ++ conditions = &condset_with_conditions->conditions[0]; ++ ++ if (parse->buffer) { ++ pause_conditions = conditions; ++ conditions += self->num_pause_conditions; ++ ++ reset_conditions = conditions; ++ conditions += self->num_reset_conditions; ++ ++ hittarget_conditions = conditions; ++ conditions += self->num_hittarget_conditions; ++ ++ measured_conditions = conditions; ++ conditions += self->num_measured_conditions; ++ ++ other_conditions = conditions; ++ conditions += self->num_other_conditions; ++ ++ indirect_conditions = conditions; ++ } ++ ++ next = &self->conditions; ++ ++ /* each condition set has a functionally new recall accumulator */ ++ parse->remember.type = RC_OPERAND_NONE; ++ ++ for (;;) { ++ rc_parse_condition_internal(&condition, memaddr, parse); ++ ++ if (parse->offset < 0) ++ return NULL; ++ ++ if (condition.oper == RC_OPERATOR_NONE && !parse->ignore_non_parse_errors) { ++ switch (condition.type) { ++ case RC_CONDITION_ADD_ADDRESS: ++ case RC_CONDITION_ADD_SOURCE: ++ case RC_CONDITION_SUB_SOURCE: ++ case RC_CONDITION_REMEMBER: ++ /* these conditions don't require a right hand side (implied *1) */ ++ break; ++ ++ case RC_CONDITION_MEASURED: ++ /* right hand side is not required when Measured is used in a value */ ++ if (parse->is_value) ++ break; ++ /* fallthrough */ /* to default */ ++ ++ default: ++ parse->offset = RC_INVALID_OPERATOR; ++ return NULL; ++ } ++ } ++ ++ switch (condition.type) { ++ case RC_CONDITION_MEASURED: ++ if (measured_target != 0) { ++ /* multiple Measured flags cannot exist in the same group */ ++ if (!parse->ignore_non_parse_errors) { ++ parse->offset = RC_MULTIPLE_MEASURED; ++ return NULL; ++ } ++ } ++ else if (parse->is_value) { ++ measured_target = (uint32_t)-1; ++ if (!rc_operator_is_modifying(condition.oper)) { ++ /* measuring comparison in a value results in a tally (hit count). set target to MAX_INT */ ++ condition.required_hits = measured_target; ++ } ++ } ++ else if (condition.required_hits != 0) { ++ measured_target = condition.required_hits; ++ } ++ else if (condition.operand2.type == RC_OPERAND_CONST) { ++ measured_target = condition.operand2.value.num; ++ } ++ else if (condition.operand2.type == RC_OPERAND_FP) { ++ measured_target = (unsigned)condition.operand2.value.dbl; ++ } ++ else if (!parse->ignore_non_parse_errors) { ++ parse->offset = RC_INVALID_MEASURED_TARGET; ++ return NULL; ++ } ++ ++ if (parse->measured_target && measured_target != parse->measured_target) { ++ /* multiple Measured flags in separate groups must have the same target */ ++ if (!parse->ignore_non_parse_errors) { ++ parse->offset = RC_MULTIPLE_MEASURED; ++ return NULL; ++ } ++ } ++ ++ parse->measured_target = measured_target; ++ break; ++ ++ case RC_CONDITION_STANDARD: ++ case RC_CONDITION_TRIGGER: ++ /* these flags are not allowed in value expressions */ ++ if (parse->is_value && !parse->ignore_non_parse_errors) { ++ parse->offset = RC_INVALID_VALUE_FLAG; ++ return NULL; ++ } ++ break; ++ } ++ ++ rc_condition_update_parse_state(&condition, parse); ++ ++ if (parse->buffer) { ++ classification = rc_classify_condition(&condition); ++ if (classification == RC_CONDITION_CLASSIFICATION_COMBINING) { ++ if (combining_classification == RC_CONDITION_CLASSIFICATION_COMBINING) { ++ if (**memaddr == '_') ++ combining_classification = rc_find_next_classification(&(*memaddr)[1]); /* skip over '_' */ ++ else ++ combining_classification = RC_CONDITION_CLASSIFICATION_OTHER; ++ } ++ ++ classification = combining_classification; ++ } ++ else { ++ combining_classification = RC_CONDITION_CLASSIFICATION_COMBINING; ++ } ++ ++ switch (classification) { ++ case RC_CONDITION_CLASSIFICATION_PAUSE: ++ memcpy(pause_conditions, &condition, sizeof(condition)); ++ *next = pause_conditions++; ++ break; ++ ++ case RC_CONDITION_CLASSIFICATION_RESET: ++ memcpy(reset_conditions, &condition, sizeof(condition)); ++ *next = reset_conditions++; ++ break; ++ ++ case RC_CONDITION_CLASSIFICATION_HITTARGET: ++ memcpy(hittarget_conditions, &condition, sizeof(condition)); ++ *next = hittarget_conditions++; ++ break; ++ ++ case RC_CONDITION_CLASSIFICATION_MEASURED: ++ memcpy(measured_conditions, &condition, sizeof(condition)); ++ *next = measured_conditions++; ++ break; ++ ++ case RC_CONDITION_CLASSIFICATION_INDIRECT: ++ memcpy(indirect_conditions, &condition, sizeof(condition)); ++ *next = indirect_conditions++; ++ break; ++ ++ default: ++ memcpy(other_conditions, &condition, sizeof(condition)); ++ *next = other_conditions++; ++ break; ++ } ++ ++ next = &(*next)->next; ++ } ++ ++ if (**memaddr != '_') ++ break; ++ ++ (*memaddr)++; ++ } ++ ++ *next = NULL; ++ ++ self->has_pause = self->num_pause_conditions > 0; ++ if (self->has_pause && parse->buffer && parse->remember.type != RC_OPERAND_NONE) ++ rc_update_condition_pause_remember(self); ++ ++ return self; ++} ++ ++static uint8_t rc_condset_evaluate_condition_no_add_hits(rc_condition_t* condition, rc_eval_state_t* eval_state) { ++ /* evaluate the current condition */ ++ uint8_t cond_valid = (uint8_t)rc_test_condition(condition, eval_state); ++ condition->is_true = cond_valid; ++ ++ if (eval_state->reset_next) { ++ /* previous ResetNextIf resets the hit count on this condition and prevents it from being true */ ++ eval_state->was_cond_reset |= (condition->current_hits != 0); ++ ++ condition->current_hits = 0; ++ cond_valid = 0; ++ } ++ else { ++ /* apply chained logic flags */ ++ cond_valid &= eval_state->and_next; ++ cond_valid |= eval_state->or_next; ++ ++ if (cond_valid) { ++ /* true conditions should update their hit count */ ++ eval_state->has_hits = 1; ++ ++ if (condition->required_hits == 0) { ++ /* no target hit count, just keep tallying */ ++ ++condition->current_hits; ++ } ++ else if (condition->current_hits < condition->required_hits) { ++ /* target hit count hasn't been met, tally and revalidate - only true if hit count becomes met */ ++ ++condition->current_hits; ++ cond_valid = (condition->current_hits == condition->required_hits); ++ } ++ else { ++ /* target hit count has been met, do nothing */ ++ } ++ } ++ else if (condition->current_hits > 0) { ++ /* target has been true in the past, if the hit target is met, consider it true now */ ++ eval_state->has_hits = 1; ++ cond_valid = (condition->current_hits == condition->required_hits); ++ } ++ } ++ ++ /* reset chained logic flags for the next condition */ ++ eval_state->and_next = 1; ++ eval_state->or_next = 0; ++ ++ return cond_valid; ++} ++ ++static uint32_t rc_condset_evaluate_total_hits(rc_condition_t* condition, rc_eval_state_t* eval_state) { ++ uint32_t total_hits = condition->current_hits; ++ ++ if (condition->required_hits != 0) { ++ /* if the condition has a target hit count, we have to recalculate cond_valid including the AddHits counter */ ++ const int32_t signed_hits = (int32_t)condition->current_hits + eval_state->add_hits; ++ total_hits = (signed_hits >= 0) ? (uint32_t)signed_hits : 0; ++ } ++ else { ++ /* no target hit count. we can't tell if the add_hits value is from this frame or not, so ignore it. ++ complex condition will only be true if the current condition is true */ ++ } ++ ++ eval_state->add_hits = 0; ++ ++ return total_hits; ++} ++ ++static uint8_t rc_condset_evaluate_condition(rc_condition_t* condition, rc_eval_state_t* eval_state) { ++ uint8_t cond_valid = rc_condset_evaluate_condition_no_add_hits(condition, eval_state); ++ ++ if (eval_state->add_hits != 0 && condition->required_hits != 0) { ++ uint32_t total_hits = rc_condset_evaluate_total_hits(condition, eval_state); ++ cond_valid = (total_hits >= condition->required_hits); ++ } ++ ++ /* reset logic flags for the next condition */ ++ eval_state->reset_next = 0; ++ ++ return cond_valid; ++} ++ ++static void rc_condset_evaluate_standard(rc_condition_t* condition, rc_eval_state_t* eval_state) { ++ const uint8_t cond_valid = rc_condset_evaluate_condition(condition, eval_state); ++ ++ eval_state->is_true &= cond_valid; ++ eval_state->is_primed &= cond_valid; ++ ++ if (!cond_valid && eval_state->can_short_curcuit) ++ eval_state->stop_processing = 1; ++} ++ ++static void rc_condset_evaluate_pause_if(rc_condition_t* condition, rc_eval_state_t* eval_state) { ++ const uint8_t cond_valid = rc_condset_evaluate_condition(condition, eval_state); ++ ++ if (cond_valid) { ++ eval_state->is_paused = 1; ++ ++ /* set cannot be valid if it's paused */ ++ eval_state->is_true = eval_state->is_primed = 0; ++ ++ /* as soon as we find a PauseIf that evaluates to true, stop processing the rest of the group */ ++ eval_state->stop_processing = 1; ++ } ++ else if (condition->required_hits == 0) { ++ /* PauseIf didn't evaluate true, and doesn't have a HitCount, reset the HitCount to indicate the condition didn't match */ ++ condition->current_hits = 0; ++ } ++ else { ++ /* PauseIf has a HitCount that hasn't been met, ignore it for now. */ ++ } ++} ++ ++static void rc_condset_evaluate_reset_if(rc_condition_t* condition, rc_eval_state_t* eval_state) { ++ const uint8_t cond_valid = rc_condset_evaluate_condition(condition, eval_state); ++ ++ if (cond_valid) { ++ /* flag the condition as being responsible for the reset */ ++ /* make sure not to modify bit0, as we use bitwise-and operators to combine truthiness */ ++ condition->is_true |= 0x02; ++ ++ /* set cannot be valid if we've hit a reset condition */ ++ eval_state->is_true = eval_state->is_primed = 0; ++ ++ /* let caller know to reset all hit counts */ ++ eval_state->was_reset = 1; ++ ++ /* can stop processing once an active ResetIf is encountered */ ++ eval_state->stop_processing = 1; ++ } ++} ++ ++static void rc_condset_evaluate_trigger(rc_condition_t* condition, rc_eval_state_t* eval_state) { ++ const uint8_t cond_valid = rc_condset_evaluate_condition(condition, eval_state); ++ ++ eval_state->is_true &= cond_valid; ++} ++ ++static void rc_condset_evaluate_measured(rc_condition_t* condition, rc_eval_state_t* eval_state) { ++ if (condition->required_hits == 0) { ++ rc_condset_evaluate_standard(condition, eval_state); ++ ++ /* Measured condition without a hit target measures the value of the left operand */ ++ rc_evaluate_operand(&eval_state->measured_value, &condition->operand1, eval_state); ++ eval_state->measured_from_hits = 0; ++ } ++ else { ++ /* this largely mimicks rc_condset_evaluate_condition, but captures the total_hits */ ++ uint8_t cond_valid = rc_condset_evaluate_condition_no_add_hits(condition, eval_state); ++ const uint32_t total_hits = rc_condset_evaluate_total_hits(condition, eval_state); ++ ++ cond_valid = (total_hits >= condition->required_hits); ++ eval_state->is_true &= cond_valid; ++ eval_state->is_primed &= cond_valid; ++ ++ /* if there is a hit target, capture the current hits */ ++ eval_state->measured_value.value.u32 = total_hits; ++ eval_state->measured_value.type = RC_VALUE_TYPE_UNSIGNED; ++ eval_state->measured_from_hits = 1; ++ ++ /* reset logic flags for the next condition */ ++ eval_state->reset_next = 0; ++ } ++} ++ ++static void rc_condset_evaluate_measured_if(rc_condition_t* condition, rc_eval_state_t* eval_state) { ++ const uint8_t cond_valid = rc_condset_evaluate_condition(condition, eval_state); ++ ++ eval_state->is_true &= cond_valid; ++ eval_state->is_primed &= cond_valid; ++ eval_state->can_measure &= cond_valid; ++} ++ ++static void rc_condset_evaluate_add_hits(rc_condition_t* condition, rc_eval_state_t* eval_state) { ++ rc_condset_evaluate_condition_no_add_hits(condition, eval_state); ++ ++ eval_state->add_hits += (int32_t)condition->current_hits; ++ ++ /* ResetNextIf was applied to this AddHits condition; don't apply it to future conditions */ ++ eval_state->reset_next = 0; ++} ++ ++static void rc_condset_evaluate_sub_hits(rc_condition_t* condition, rc_eval_state_t* eval_state) { ++ rc_condset_evaluate_condition_no_add_hits(condition, eval_state); ++ ++ eval_state->add_hits -= (int32_t)condition->current_hits; ++ ++ /* ResetNextIf was applied to this AddHits condition; don't apply it to future conditions */ ++ eval_state->reset_next = 0; ++} ++ ++static void rc_condset_evaluate_reset_next_if(rc_condition_t* condition, rc_eval_state_t* eval_state) { ++ eval_state->reset_next = rc_condset_evaluate_condition_no_add_hits(condition, eval_state); ++} ++ ++static void rc_condset_evaluate_and_next(rc_condition_t* condition, rc_eval_state_t* eval_state) { ++ eval_state->and_next = rc_condset_evaluate_condition_no_add_hits(condition, eval_state); ++} ++ ++static void rc_condset_evaluate_or_next(rc_condition_t* condition, rc_eval_state_t* eval_state) { ++ eval_state->or_next = rc_condset_evaluate_condition_no_add_hits(condition, eval_state); ++} ++ ++void rc_test_condset_internal(rc_condition_t* condition, uint32_t num_conditions, ++ rc_eval_state_t* eval_state, int can_short_circuit) { ++ const rc_condition_t* condition_end = condition + num_conditions; ++ for (; condition < condition_end; ++condition) { ++ switch (condition->type) { ++ case RC_CONDITION_STANDARD: ++ rc_condset_evaluate_standard(condition, eval_state); ++ break; ++ case RC_CONDITION_PAUSE_IF: ++ rc_condset_evaluate_pause_if(condition, eval_state); ++ break; ++ case RC_CONDITION_RESET_IF: ++ rc_condset_evaluate_reset_if(condition, eval_state); ++ break; ++ case RC_CONDITION_TRIGGER: ++ rc_condset_evaluate_trigger(condition, eval_state); ++ break; ++ case RC_CONDITION_MEASURED: ++ rc_condset_evaluate_measured(condition, eval_state); ++ break; ++ case RC_CONDITION_MEASURED_IF: ++ rc_condset_evaluate_measured_if(condition, eval_state); ++ break; ++ case RC_CONDITION_ADD_SOURCE: ++ case RC_CONDITION_SUB_SOURCE: ++ case RC_CONDITION_ADD_ADDRESS: ++ case RC_CONDITION_REMEMBER: ++ /* these are handled by rc_modified_memref_t */ ++ break; ++ case RC_CONDITION_ADD_HITS: ++ rc_condset_evaluate_add_hits(condition, eval_state); ++ break; ++ case RC_CONDITION_SUB_HITS: ++ rc_condset_evaluate_sub_hits(condition, eval_state); ++ break; ++ case RC_CONDITION_RESET_NEXT_IF: ++ rc_condset_evaluate_reset_next_if(condition, eval_state); ++ break; ++ case RC_CONDITION_AND_NEXT: ++ rc_condset_evaluate_and_next(condition, eval_state); ++ break; ++ case RC_CONDITION_OR_NEXT: ++ rc_condset_evaluate_or_next(condition, eval_state); ++ break; ++ default: ++ eval_state->stop_processing = 1; ++ eval_state->is_true = eval_state->is_primed = 0; ++ break; ++ } ++ ++ if (eval_state->stop_processing && can_short_circuit) ++ break; ++ } ++} ++ ++rc_condition_t* rc_condset_get_conditions(rc_condset_t* self) { ++ if (self->conditions) ++ return RC_GET_TRAILING(self, rc_condset_with_trailing_conditions_t, rc_condition_t, conditions); ++ ++ return NULL; ++} ++ ++int rc_test_condset(rc_condset_t* self, rc_eval_state_t* eval_state) { ++ rc_condition_t* conditions; ++ ++ /* reset the processing state before processing each condset. do not reset the result state. */ ++ eval_state->measured_value.type = RC_VALUE_TYPE_NONE; ++ eval_state->add_hits = 0; ++ eval_state->is_true = 1; ++ eval_state->is_primed = 1; ++ eval_state->is_paused = 0; ++ eval_state->can_measure = 1; ++ eval_state->measured_from_hits = 0; ++ eval_state->and_next = 1; ++ eval_state->or_next = 0; ++ eval_state->reset_next = 0; ++ eval_state->stop_processing = 0; ++ ++ /* the conditions array is allocated immediately after the rc_condset_t, without a separate pointer */ ++ conditions = rc_condset_get_conditions(self); ++ ++ if (self->num_pause_conditions) { ++ /* one or more Pause conditions exist. if any of them are true (eval_state->is_paused), ++ * stop processing this group */ ++ rc_test_condset_internal(conditions, self->num_pause_conditions, eval_state, 1); ++ ++ self->is_paused = eval_state->is_paused; ++ if (self->is_paused) { ++ /* condset is paused. stop processing immediately. */ ++ return 0; ++ } ++ ++ conditions += self->num_pause_conditions; ++ } ++ ++ if (self->num_reset_conditions) { ++ /* one or more Reset conditions exists. if any of them are true (eval_state->was_reset), ++ * we'll skip some of the later steps */ ++ rc_test_condset_internal(conditions, self->num_reset_conditions, eval_state, eval_state->can_short_curcuit); ++ conditions += self->num_reset_conditions; ++ } ++ ++ if (self->num_hittarget_conditions) { ++ /* one or more hit target conditions exists. these must be processed every frame, ++ * unless their hit count is going to be reset */ ++ if (!eval_state->was_reset) ++ rc_test_condset_internal(conditions, self->num_hittarget_conditions, eval_state, 0); ++ ++ conditions += self->num_hittarget_conditions; ++ } ++ ++ if (self->num_measured_conditions) { ++ /* IMPORTANT: reset hit counts on these conditions before processing them so ++ * the MeasuredIf logic and Measured value are correct. ++ * NOTE: a ResetIf in a later alt group may not have been processed yet. ++ * Accept that as a weird edge case, and just recommend the user ++ * move the ResetIf if it becomes a problem. */ ++ if (eval_state->was_reset) { ++ int i; ++ for (i = 0; i < self->num_measured_conditions; ++i) ++ conditions[i].current_hits = 0; ++ } ++ ++ /* the measured value must be calculated every frame, even if hit counts will be reset */ ++ rc_test_condset_internal(conditions, self->num_measured_conditions, eval_state, 0); ++ conditions += self->num_measured_conditions; ++ ++ if (eval_state->measured_value.type != RC_VALUE_TYPE_NONE) { ++ /* if a MeasuredIf was false (!eval_state->can_measure), or the measured ++ * value is a hitcount and a ResetIf is true, zero out the measured value */ ++ if (!eval_state->can_measure || ++ (eval_state->measured_from_hits && eval_state->was_reset)) { ++ eval_state->measured_value.type = RC_VALUE_TYPE_UNSIGNED; ++ eval_state->measured_value.value.u32 = 0; ++ } ++ } ++ } ++ ++ if (self->num_other_conditions) { ++ /* the remaining conditions only need to be evaluated if the rest of the condset is true */ ++ if (eval_state->is_true) ++ rc_test_condset_internal(conditions, self->num_other_conditions, eval_state, eval_state->can_short_curcuit); ++ /* something else is false. if we can't short circuit, and there wasn't a reset, we still need to evaluate these */ ++ else if (!eval_state->can_short_curcuit && !eval_state->was_reset) ++ rc_test_condset_internal(conditions, self->num_other_conditions, eval_state, eval_state->can_short_curcuit); ++ } ++ ++ return eval_state->is_true; ++} ++ ++void rc_reset_condset(rc_condset_t* self) { ++ rc_condition_t* condition; ++ ++ for (condition = self->conditions; condition != 0; condition = condition->next) { ++ condition->current_hits = 0; ++ } ++} +diff -rupbN melonDS.orig/src/rcheevos/src/rcheevos/consoleinfo.c melonDS.ra/src/rcheevos/src/rcheevos/consoleinfo.c +--- melonDS.orig/src/rcheevos/src/rcheevos/consoleinfo.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rcheevos/consoleinfo.c 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,1215 @@ ++#include "rc_consoles.h" ++ ++#include ++ ++const char* rc_console_name(uint32_t console_id) ++{ ++ switch (console_id) ++ { ++ case RC_CONSOLE_3DO: ++ return "3DO"; ++ ++ case RC_CONSOLE_AMIGA: ++ return "Amiga"; ++ ++ case RC_CONSOLE_AMSTRAD_PC: ++ return "Amstrad CPC"; ++ ++ case RC_CONSOLE_APPLE_II: ++ return "Apple II"; ++ ++ case RC_CONSOLE_ARCADE: ++ return "Arcade"; ++ ++ case RC_CONSOLE_ARCADIA_2001: ++ return "Arcadia 2001"; ++ ++ case RC_CONSOLE_ARDUBOY: ++ return "Arduboy"; ++ ++ case RC_CONSOLE_ATARI_2600: ++ return "Atari 2600"; ++ ++ case RC_CONSOLE_ATARI_5200: ++ return "Atari 5200"; ++ ++ case RC_CONSOLE_ATARI_7800: ++ return "Atari 7800"; ++ ++ case RC_CONSOLE_ATARI_JAGUAR: ++ return "Atari Jaguar"; ++ ++ case RC_CONSOLE_ATARI_JAGUAR_CD: ++ return "Atari Jaguar CD"; ++ ++ case RC_CONSOLE_ATARI_LYNX: ++ return "Atari Lynx"; ++ ++ case RC_CONSOLE_ATARI_ST: ++ return "Atari ST"; ++ ++ case RC_CONSOLE_CASSETTEVISION: ++ return "CassetteVision"; ++ ++ case RC_CONSOLE_CDI: ++ return "CD-I"; ++ ++ case RC_CONSOLE_COLECOVISION: ++ return "ColecoVision"; ++ ++ case RC_CONSOLE_COMMODORE_64: ++ return "Commodore 64"; ++ ++ case RC_CONSOLE_DREAMCAST: ++ return "Dreamcast"; ++ ++ case RC_CONSOLE_ELEKTOR_TV_GAMES_COMPUTER: ++ return "Elektor TV Games Computer"; ++ ++ case RC_CONSOLE_EVENTS: ++ return "Events"; ++ ++ case RC_CONSOLE_FAIRCHILD_CHANNEL_F: ++ return "Fairchild Channel F"; ++ ++ case RC_CONSOLE_FAMICOM_DISK_SYSTEM: ++ return "Famicom Disk System"; ++ ++ case RC_CONSOLE_FM_TOWNS: ++ return "FM Towns"; ++ ++ case RC_CONSOLE_GAME_AND_WATCH: ++ return "Game & Watch"; ++ ++ case RC_CONSOLE_GAMEBOY: ++ return "GameBoy"; ++ ++ case RC_CONSOLE_GAMEBOY_ADVANCE: ++ return "GameBoy Advance"; ++ ++ case RC_CONSOLE_GAMEBOY_COLOR: ++ return "GameBoy Color"; ++ ++ case RC_CONSOLE_GAMECUBE: ++ return "GameCube"; ++ ++ case RC_CONSOLE_GAME_GEAR: ++ return "Game Gear"; ++ ++ case RC_CONSOLE_HUBS: ++ return "Hubs"; ++ ++ case RC_CONSOLE_INTELLIVISION: ++ return "Intellivision"; ++ ++ case RC_CONSOLE_INTERTON_VC_4000: ++ return "Interton VC 4000"; ++ ++ case RC_CONSOLE_MAGNAVOX_ODYSSEY2: ++ return "Magnavox Odyssey 2"; ++ ++ case RC_CONSOLE_MASTER_SYSTEM: ++ return "Master System"; ++ ++ case RC_CONSOLE_MEGA_DRIVE: ++ return "Sega Genesis"; ++ ++ case RC_CONSOLE_MEGADUCK: ++ return "Mega Duck"; ++ ++ case RC_CONSOLE_MS_DOS: ++ return "MS-DOS"; ++ ++ case RC_CONSOLE_MSX: ++ return "MSX"; ++ ++ case RC_CONSOLE_NEO_GEO_CD: ++ return "Neo Geo CD"; ++ ++ case RC_CONSOLE_NEOGEO_POCKET: ++ return "Neo Geo Pocket"; ++ ++ case RC_CONSOLE_NINTENDO: ++ return "Nintendo Entertainment System"; ++ ++ case RC_CONSOLE_NINTENDO_64: ++ return "Nintendo 64"; ++ ++ case RC_CONSOLE_NINTENDO_DS: ++ return "Nintendo DS"; ++ ++ case RC_CONSOLE_NINTENDO_DSI: ++ return "Nintendo DSi"; ++ ++ case RC_CONSOLE_NINTENDO_3DS: ++ return "Nintendo 3DS"; ++ ++ case RC_CONSOLE_NOKIA_NGAGE: ++ return "Nokia N-Gage"; ++ ++ case RC_CONSOLE_ORIC: ++ return "Oric"; ++ ++ case RC_CONSOLE_PC6000: ++ return "PC-6000"; ++ ++ case RC_CONSOLE_PC8800: ++ return "PC-8000/8800"; ++ ++ case RC_CONSOLE_PC9800: ++ return "PC-9800"; ++ ++ case RC_CONSOLE_PCFX: ++ return "PC-FX"; ++ ++ case RC_CONSOLE_PC_ENGINE: ++ return "PC Engine"; ++ ++ case RC_CONSOLE_PC_ENGINE_CD: ++ return "PC Engine CD"; ++ ++ case RC_CONSOLE_PLAYSTATION: ++ return "PlayStation"; ++ ++ case RC_CONSOLE_PLAYSTATION_2: ++ return "PlayStation 2"; ++ ++ case RC_CONSOLE_PSP: ++ return "PlayStation Portable"; ++ ++ case RC_CONSOLE_POKEMON_MINI: ++ return "Pokemon Mini"; ++ ++ case RC_CONSOLE_SEGA_32X: ++ return "Sega 32X"; ++ ++ case RC_CONSOLE_SEGA_CD: ++ return "Sega CD"; ++ ++ case RC_CONSOLE_PICO: ++ return "Sega Pico"; ++ ++ case RC_CONSOLE_SATURN: ++ return "Sega Saturn"; ++ ++ case RC_CONSOLE_SG1000: ++ return "SG-1000"; ++ ++ case RC_CONSOLE_SHARPX1: ++ return "Sharp X1"; ++ ++ case RC_CONSOLE_STANDALONE: ++ return "Standalone"; ++ ++ case RC_CONSOLE_SUPER_NINTENDO: ++ return "Super Nintendo Entertainment System"; ++ ++ case RC_CONSOLE_SUPER_CASSETTEVISION: ++ return "Super CassetteVision"; ++ ++ case RC_CONSOLE_SUPERVISION: ++ return "Watara Supervision"; ++ ++ case RC_CONSOLE_THOMSONTO8: ++ return "Thomson TO8"; ++ ++ case RC_CONSOLE_TI83: ++ return "TI-83"; ++ ++ case RC_CONSOLE_TIC80: ++ return "TIC-80"; ++ ++ case RC_CONSOLE_UZEBOX: ++ return "Uzebox"; ++ ++ case RC_CONSOLE_VECTREX: ++ return "Vectrex"; ++ ++ case RC_CONSOLE_VIC20: ++ return "VIC-20"; ++ ++ case RC_CONSOLE_VIRTUAL_BOY: ++ return "Virtual Boy"; ++ ++ case RC_CONSOLE_WASM4: ++ return "WASM-4"; ++ ++ case RC_CONSOLE_WII: ++ return "Wii"; ++ ++ case RC_CONSOLE_WII_U: ++ return "Wii-U"; ++ ++ case RC_CONSOLE_WONDERSWAN: ++ return "WonderSwan"; ++ ++ case RC_CONSOLE_X68K: ++ return "X68K"; ++ ++ case RC_CONSOLE_XBOX: ++ return "XBOX"; ++ ++ case RC_CONSOLE_ZEEBO: ++ return "Zeebo"; ++ ++ case RC_CONSOLE_ZX81: ++ return "ZX-81"; ++ ++ case RC_CONSOLE_ZX_SPECTRUM: ++ return "ZX Spectrum"; ++ ++ default: ++ return "Unknown"; ++ } ++} ++ ++/* ===== 3DO ===== */ ++/* http://www.arcaderestoration.com/memorymap/48/3DO+Bios.aspx */ ++/* NOTE: the Opera core attempts to expose the NVRAM as RETRO_SAVE_RAM, but the 3DO documentation ++ * says that applications should only access NVRAM through API calls as it's shared across mulitple ++ * games. This suggests that even if the core does expose it, it may change depending on which other ++ * games the user has played - so ignore it. ++ */ ++static const rc_memory_region_t _rc_memory_regions_3do[] = { ++ { 0x000000U, 0x1FFFFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Main RAM" }, ++}; ++static const rc_memory_regions_t rc_memory_regions_3do = { _rc_memory_regions_3do, 1 }; ++ ++/* ===== Amiga ===== */ ++/* http://amigadev.elowar.com/read/ADCD_2.1/Hardware_Manual_guide/node00D3.html */ ++static const rc_memory_region_t _rc_memory_regions_amiga[] = { ++ { 0x000000U, 0x07FFFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Main RAM" }, /* 512KB main RAM */ ++ { 0x080000U, 0x0FFFFFU, 0x080000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Extended RAM" }, /* 512KB extended RAM */ ++}; ++static const rc_memory_regions_t rc_memory_regions_amiga = { _rc_memory_regions_amiga, 2 }; ++ ++/* ===== Amstrad CPC ===== */ ++/* http://www.cpcalive.com/docs/amstrad_cpc_6128_memory_map.html */ ++/* https://www.cpcwiki.eu/index.php/File:AWMG_page151.jpg */ ++/* The original CPC only had 64KB of memory, but the newer model has 128KB (expandable to 576KB) */ ++/* https://www.grimware.org/doku.php/documentations/devices/gatearraydo=export_xhtml#mmr */ ++static const rc_memory_region_t _rc_memory_regions_amstrad_pc[] = { ++ { 0x000000U, 0x00003FU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Firmware" }, ++ { 0x000040U, 0x00B0FFU, 0x000040U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++ { 0x00B100U, 0x00BFFFU, 0x00B100U, RC_MEMORY_TYPE_SYSTEM_RAM, "Stack and Firmware Data" }, ++ { 0x00C000U, 0x00FFFFU, 0x00C000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Screen Memory" }, ++ { 0x010000U, 0x08FFFFU, 0x010000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Extended RAM" }, ++}; ++static const rc_memory_regions_t rc_memory_regions_amstrad_pc = { _rc_memory_regions_amstrad_pc, 5 }; ++ ++/* ===== Apple II ===== */ ++static const rc_memory_region_t _rc_memory_regions_appleii[] = { ++ { 0x000000U, 0x00FFFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Main RAM" }, ++ { 0x010000U, 0x01FFFFU, 0x010000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Auxillary RAM" } ++}; ++static const rc_memory_regions_t rc_memory_regions_appleii = { _rc_memory_regions_appleii, 2 }; ++ ++/* ===== Arcadia 2001 ===== */ ++/* https://amigan.yatho.com/a-coding.txt */ ++/* RAM banks 1 and 2 only exist on some variant models - no game actually uses them */ ++static const rc_memory_region_t _rc_memory_regions_arcadia_2001[] = { ++ { 0x000000U, 0x0000FFU, 0x001800U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RAM bank 3 */ ++ { 0x000100U, 0x0001FFU, 0x001900U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "I/O Area" }, ++ { 0x000200U, 0x0002FFU, 0x001A00U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RAM bank 4 */ ++}; ++static const rc_memory_regions_t rc_memory_regions_arcadia_2001 = { _rc_memory_regions_arcadia_2001, 3 }; ++ ++/* ===== Arduboy ===== */ ++/* https://scienceprog.com/avr-microcontroller-memory-map/ (Atmega32) */ ++static const rc_memory_region_t _rc_memory_regions_arduboy[] = { ++ { 0x000000U, 0x0000FFU, 0x00000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Registers" }, ++ /* https://www.dailydot.com/debug/arduboy-kickstarter/ 2.5KB of RAM */ ++ /* https://github.com/buserror/simavr/blob/1d227277b3d0039f9faef9ea62880ca3051b14f8/simavr/cores/avr/iom32u4.h#L1444-L1445 */ ++ { 0x000100U, 0x000AFFU, 0x00000100U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++ /* 1KB of EEPROM https://github.com/libretro/arduous/blob/93e1a6289b42ef48de1fcfb96443981725955ad0/src/arduous/arduous.cpp#L453-L455 ++ * https://github.com/buserror/simavr/blob/1d227277b3d0039f9faef9ea62880ca3051b14f8/simavr/cores/avr/iom32u4.h#L1450 */ ++ /* EEPROM has it's own addressing scheme starting at $0000. I've chosen to virtualize the address ++ * at $80000000 to avoid a conflict */ ++ { 0x000B00U, 0x000EFFU, 0x80000000U, RC_MEMORY_TYPE_SAVE_RAM, "EEPROM" } ++}; ++static const rc_memory_regions_t rc_memory_regions_arduboy = { _rc_memory_regions_arduboy, 3 }; ++ ++/* ===== Atari 2600 ===== */ ++static const rc_memory_region_t _rc_memory_regions_atari2600[] = { ++ { 0x000000U, 0x00007FU, 0x000080U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" } ++}; ++static const rc_memory_regions_t rc_memory_regions_atari2600 = { _rc_memory_regions_atari2600, 1 }; ++ ++/* ===== Atari 7800 ===== */ ++/* http://www.atarihq.com/danb/files/78map.txt */ ++/* http://pdf.textfiles.com/technical/7800_devkit.pdf */ ++static const rc_memory_region_t _rc_memory_regions_atari7800[] = { ++ { 0x000000U, 0x0017FFU, 0x000000U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Hardware Interface" }, ++ { 0x001800U, 0x0027FFU, 0x001800U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++ { 0x002800U, 0x002FFFU, 0x002800U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Mirrored RAM" }, ++ { 0x003000U, 0x0037FFU, 0x003000U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Mirrored RAM" }, ++ { 0x003800U, 0x003FFFU, 0x003800U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Mirrored RAM" }, ++ { 0x004000U, 0x007FFFU, 0x004000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM" }, ++ { 0x008000U, 0x00FFFFU, 0x008000U, RC_MEMORY_TYPE_READONLY, "Cartridge ROM" } ++}; ++static const rc_memory_regions_t rc_memory_regions_atari7800 = { _rc_memory_regions_atari7800, 7 }; ++ ++/* ===== Atari Jaguar ===== */ ++/* https://www.mulle-kybernetik.com/jagdox/memorymap.html */ ++static const rc_memory_region_t _rc_memory_regions_atari_jaguar[] = { ++ { 0x000000U, 0x1FFFFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" } ++}; ++static const rc_memory_regions_t rc_memory_regions_atari_jaguar = { _rc_memory_regions_atari_jaguar, 1 }; ++ ++/* ===== Atari Lynx ===== */ ++/* http://www.retroisle.com/atari/lynx/Technical/Programming/lynxprgdumm.php */ ++static const rc_memory_region_t _rc_memory_regions_atari_lynx[] = { ++ { 0x000000U, 0x0000FFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Zero Page" }, ++ { 0x000100U, 0x0001FFU, 0x000100U, RC_MEMORY_TYPE_SYSTEM_RAM, "Stack" }, ++ { 0x000200U, 0x00FBFFU, 0x000200U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++ { 0x00FC00U, 0x00FCFFU, 0x00FC00U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "SUZY hardware access" }, ++ { 0x00FD00U, 0x00FDFFU, 0x00FD00U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "MIKEY hardware access" }, ++ { 0x00FE00U, 0x00FFF7U, 0x00FE00U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Boot ROM" }, ++ { 0x00FFF8U, 0x00FFFFU, 0x00FFF8U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Hardware vectors" } ++}; ++static const rc_memory_regions_t rc_memory_regions_atari_lynx = { _rc_memory_regions_atari_lynx, 7 }; ++ ++/* ===== ColecoVision ===== */ ++static const rc_memory_region_t _rc_memory_regions_colecovision[] = { ++ /* "System RAM" refers to the main RAM at 0x6000-0x63FF. However, this RAM might not always be visible. ++ * If the Super Game Module (SGM) is active, then it might overlay its own RAM at 0x0000-0x1FFF and 0x2000-0x7FFF. ++ * These positions overlap the BIOS and System RAM, therefore we use virtual addresses for these memory spaces. */ ++ { 0x000000U, 0x0003FFU, 0x006000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++ { 0x000400U, 0x0023FFU, 0x010000U, RC_MEMORY_TYPE_SYSTEM_RAM, "SGM Low RAM" }, /* Normally situated at 0x0000-0x1FFF, which overlaps the BIOS */ ++ { 0x002400U, 0x0083FFU, 0x012000U, RC_MEMORY_TYPE_SYSTEM_RAM, "SGM High RAM" } /* Normally situated at 0x2000-0x7FFF, which overlaps System RAM */ ++}; ++static const rc_memory_regions_t rc_memory_regions_colecovision = { _rc_memory_regions_colecovision, 3 }; ++ ++/* ===== Commodore 64 ===== */ ++/* https://www.c64-wiki.com/wiki/Memory_Map */ ++/* https://sta.c64.org/cbm64mem.html */ ++/* NOTE: Several blocks of C64 memory can be bank-switched for ROM data (see https://www.c64-wiki.com/wiki/Bank_Switching). ++ * Achievement triggers rely on values changing, so we don't really need to look at the ROM data. ++ * The achievement logic assumes the RAM data is always present in the bankable blocks. As such, ++ * clients providing memory to achievements should always return the RAM values at the queried address. */ ++static const rc_memory_region_t _rc_memory_regions_c64[] = { ++ { 0x000000U, 0x0003FFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Kernel RAM" }, ++ { 0x000400U, 0x0007FFU, 0x000400U, RC_MEMORY_TYPE_VIDEO_RAM, "Screen RAM" }, ++ { 0x000800U, 0x009FFFU, 0x000800U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* BASIC area. $8000-$9FFF can bank to cartridge ROM */ ++ { 0x00A000U, 0x00BFFFU, 0x00A000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* can bank to BASIC ROM or cartridge ROM */ ++ { 0x00C000U, 0x00CFFFU, 0x00C000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++ { 0x00D000U, 0x00DFFFU, 0x00D000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* can bank to I/O Area or character ROM */ ++ { 0x00E000U, 0x00FFFFU, 0x00E000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* can bank to kernel ROM */ ++}; ++static const rc_memory_regions_t rc_memory_regions_c64 = { _rc_memory_regions_c64, 7 }; ++ ++/* ===== Dreamcast ===== */ ++/* http://archiv.sega-dc.de/munkeechuff/hardware/Memory.html */ ++static const rc_memory_region_t _rc_memory_regions_dreamcast[] = { ++ { 0x00000000U, 0x00FFFFFFU, 0x0C000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" } ++}; ++static const rc_memory_regions_t rc_memory_regions_dreamcast = { _rc_memory_regions_dreamcast, 1 }; ++ ++/* ===== Elektor TV Games Computer ===== */ ++/* https://amigan.yatho.com/e-coding.txt */ ++static const rc_memory_region_t _rc_memory_regions_elektor_tv_games[] = { ++ { 0x000000U, 0x0013FFU, 0x000800U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++ { 0x001400U, 0x0014FFU, 0x001C00U, RC_MEMORY_TYPE_UNUSED, "Unused" }, /* mirror of $1D00-$1DFF */ ++ { 0x001500U, 0x0016FFU, 0x001D00U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "I/O Area" }, /* two 256-byte I/O areas */ ++ { 0x001700U, 0x0017FFU, 0x001F00U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++}; ++static const rc_memory_regions_t rc_memory_regions_elektor_tv_games = { _rc_memory_regions_elektor_tv_games, 4 }; ++ ++/* ===== Fairchild Channel F ===== */ ++static const rc_memory_region_t _rc_memory_regions_fairchild_channel_f[] = { ++ /* "System RAM" is actually just a bunch of registers internal to CPU so all carts have it. ++ * "Video RAM" is part of the console so it's always available but it is write-only by the ROMs. ++ * "Cartridge RAM" is the cart BUS. Most carts only have ROMs on this bus. Exception are ++ * German Schach and homebrew carts that have 2K of RAM there in addition to ROM. ++ * "F2102 RAM" is used by Maze for 1K of RAM. ++ * https://discord.com/channels/310192285306454017/645777658319208448/967001438087708714 */ ++ { 0x00000000U, 0x0000003FU, 0x00100000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++ { 0x00000040U, 0x0000083FU, 0x00300000U, RC_MEMORY_TYPE_VIDEO_RAM, "Video RAM" }, ++ { 0x00000840U, 0x0001083FU, 0x00000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Cartridge RAM" }, ++ { 0x00010840U, 0x00010C3FU, 0x00200000U, RC_MEMORY_TYPE_SYSTEM_RAM, "F2102 RAM" } ++}; ++static const rc_memory_regions_t rc_memory_regions_fairchild_channel_f = { _rc_memory_regions_fairchild_channel_f, 4 }; ++ ++/* ===== Famicon Disk System ===== */ ++/* https://fms.komkon.org/EMUL8/NES.html */ ++static const rc_memory_region_t _rc_memory_regions_famicom_disk_system[] = { ++ { 0x0000U, 0x07FFU, 0x0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++ { 0x0800U, 0x0FFFU, 0x0000U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Mirror RAM" }, /* duplicates memory from $0000-$07FF */ ++ { 0x1000U, 0x17FFU, 0x0000U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Mirror RAM" }, /* duplicates memory from $0000-$07FF */ ++ { 0x1800U, 0x1FFFU, 0x0000U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Mirror RAM" }, /* duplicates memory from $0000-$07FF */ ++ { 0x2000U, 0x2007U, 0x2000U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "PPU Register" }, ++ { 0x2008U, 0x3FFFU, 0x2008U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Mirrored PPU Register" }, /* repeats every 8 bytes */ ++ { 0x4000U, 0x4017U, 0x4000U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "APU and I/O register" }, ++ { 0x4018U, 0x401FU, 0x4018U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "APU and I/O test register" }, ++ { 0x4020U, 0x40FFU, 0x4020U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "FDS I/O registers"}, ++ { 0x4100U, 0x5FFFU, 0x4100U, RC_MEMORY_TYPE_READONLY, "Cartridge data"}, /* varies by mapper */ ++ { 0x6000U, 0xDFFFU, 0x6000U, RC_MEMORY_TYPE_SYSTEM_RAM, "FDS RAM"}, ++ { 0xE000U, 0xFFFFU, 0xE000U, RC_MEMORY_TYPE_READONLY, "FDS BIOS ROM"}, ++}; ++static const rc_memory_regions_t rc_memory_regions_famicom_disk_system = { _rc_memory_regions_famicom_disk_system, 12 }; ++ ++/* ===== GameBoy / MegaDuck ===== */ ++static const rc_memory_region_t _rc_memory_regions_gameboy[] = { ++ { 0x000000U, 0x0000FFU, 0x000000U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Interrupt vector" }, ++ { 0x000100U, 0x00014FU, 0x000100U, RC_MEMORY_TYPE_READONLY, "Cartridge header" }, ++ { 0x000150U, 0x003FFFU, 0x000150U, RC_MEMORY_TYPE_READONLY, "Cartridge ROM (fixed)" }, /* bank 0 */ ++ { 0x004000U, 0x007FFFU, 0x004000U, RC_MEMORY_TYPE_READONLY, "Cartridge ROM (paged)" }, /* bank 1-XX (switchable) */ ++ { 0x008000U, 0x0097FFU, 0x008000U, RC_MEMORY_TYPE_VIDEO_RAM, "Tile RAM" }, ++ { 0x009800U, 0x009BFFU, 0x009800U, RC_MEMORY_TYPE_VIDEO_RAM, "BG1 map data" }, ++ { 0x009C00U, 0x009FFFU, 0x009C00U, RC_MEMORY_TYPE_VIDEO_RAM, "BG2 map data" }, ++ { 0x00A000U, 0x00BFFFU, 0x00A000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM (bank 0)"}, ++ { 0x00C000U, 0x00CFFFU, 0x00C000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM (fixed)" }, ++ { 0x00D000U, 0x00DFFFU, 0x00D000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM (fixed)" }, ++ { 0x00E000U, 0x00FDFFU, 0x00C000U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Echo RAM" }, ++ { 0x00FE00U, 0x00FE9FU, 0x00FE00U, RC_MEMORY_TYPE_VIDEO_RAM, "Sprite RAM"}, ++ { 0x00FEA0U, 0x00FEFFU, 0x00FEA0U, RC_MEMORY_TYPE_UNUSED, ""}, ++ { 0x00FF00U, 0x00FF7FU, 0x00FF00U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Hardware I/O"}, ++ { 0x00FF80U, 0x00FFFEU, 0x00FF80U, RC_MEMORY_TYPE_SYSTEM_RAM, "Quick RAM"}, ++ { 0x00FFFFU, 0x00FFFFU, 0x00FFFFU, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Interrupt enable"}, ++ ++ /* GameBoy's cartridge RAM may have a total of up to 16 banks that can be paged through $A000-$BFFF. ++ * It is desirable to always have access to these extra banks. We do this by expecting the extra banks ++ * to be addressable at addresses not supported by the native system. 0x10000-0x16000 is reserved ++ * for the extra banks of system memory that are exclusive to the GameBoy Color. */ ++ { 0x010000U, 0x015FFFU, 0x010000U, RC_MEMORY_TYPE_UNUSED, "Unused (GameBoy Color exclusive)" }, ++ { 0x016000U, 0x033FFFU, 0x016000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM (banks 1-15)" }, ++}; ++static const rc_memory_regions_t rc_memory_regions_megaduck = { _rc_memory_regions_gameboy, 16 }; ++static const rc_memory_regions_t rc_memory_regions_gameboy = { _rc_memory_regions_gameboy, 18 }; ++ ++/* ===== GameBoy Color ===== */ ++static const rc_memory_region_t _rc_memory_regions_gameboy_color[] = { ++ { 0x000000U, 0x0000FFU, 0x000000U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Interrupt vector" }, ++ { 0x000100U, 0x00014FU, 0x000100U, RC_MEMORY_TYPE_READONLY, "Cartridge header" }, ++ { 0x000150U, 0x003FFFU, 0x000150U, RC_MEMORY_TYPE_READONLY, "Cartridge ROM (fixed)" }, /* bank 0 */ ++ { 0x004000U, 0x007FFFU, 0x004000U, RC_MEMORY_TYPE_READONLY, "Cartridge ROM (paged)" }, /* bank 1-XX (switchable) */ ++ { 0x008000U, 0x0097FFU, 0x008000U, RC_MEMORY_TYPE_VIDEO_RAM, "Tile RAM" }, ++ { 0x009800U, 0x009BFFU, 0x009800U, RC_MEMORY_TYPE_VIDEO_RAM, "BG1 map data" }, ++ { 0x009C00U, 0x009FFFU, 0x009C00U, RC_MEMORY_TYPE_VIDEO_RAM, "BG2 map data" }, ++ { 0x00A000U, 0x00BFFFU, 0x00A000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM (bank 0)"}, ++ { 0x00C000U, 0x00CFFFU, 0x00C000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM (bank 0)" }, ++ { 0x00D000U, 0x00DFFFU, 0x00D000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM (bank 1)" }, ++ { 0x00E000U, 0x00FDFFU, 0x00C000U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Echo RAM" }, ++ { 0x00FE00U, 0x00FE9FU, 0x00FE00U, RC_MEMORY_TYPE_VIDEO_RAM, "Sprite RAM"}, ++ { 0x00FEA0U, 0x00FEFFU, 0x00FEA0U, RC_MEMORY_TYPE_UNUSED, ""}, ++ { 0x00FF00U, 0x00FF7FU, 0x00FF00U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Hardware I/O"}, ++ { 0x00FF80U, 0x00FFFEU, 0x00FF80U, RC_MEMORY_TYPE_SYSTEM_RAM, "Quick RAM"}, ++ { 0x00FFFFU, 0x00FFFFU, 0x00FFFFU, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Interrupt enable"}, ++ ++ /* GameBoy Color provides 6 extra banks of system memory that can be paged out through the $D000-$DFFF, ++ * and the cartridge RAM may have a total of up to 16 banks page through $A000-$BFFF. ++ * It is desirable to always have access to these extra banks. We do this by expecting the extra banks ++ * to be addressable at addresses not supported by the native system. */ ++ { 0x010000U, 0x015FFFU, 0x010000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM (banks 2-7)" }, ++ { 0x016000U, 0x033FFFU, 0x016000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM (banks 1-15)" }, ++}; ++static const rc_memory_regions_t rc_memory_regions_gameboy_color = { _rc_memory_regions_gameboy_color, 18 }; ++ ++/* ===== GameBoy Advance ===== */ ++/* http://problemkaputt.de/gbatek-gba-memory-map.htm */ ++static const rc_memory_region_t _rc_memory_regions_gameboy_advance[] = { ++ { 0x000000U, 0x007FFFU, 0x03000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* 32KB Internal Work RAM */ ++ { 0x008000U, 0x047FFFU, 0x02000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* 256KB External Work RAM */ ++ { 0x048000U, 0x057FFFU, 0x0E000000U, RC_MEMORY_TYPE_SAVE_RAM, "Save RAM" } /* 64KB Game Pak SRAM */ ++}; ++static const rc_memory_regions_t rc_memory_regions_gameboy_advance = { _rc_memory_regions_gameboy_advance, 3 }; ++ ++/* ===== GameCube ===== */ ++/* https://wiibrew.org/wiki/Memory_map */ ++static const rc_memory_region_t _rc_memory_regions_gamecube[] = { ++ { 0x00000000U, 0x017FFFFF, 0x80000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" } ++}; ++static const rc_memory_regions_t rc_memory_regions_gamecube = { _rc_memory_regions_gamecube, 1 }; ++ ++/* ===== Game Gear ===== */ ++/* https://www.smspower.org/Development/MemoryMap */ ++/* https://www.smspower.org/Development/Mappers */ ++static const rc_memory_region_t _rc_memory_regions_game_gear[] = { ++ { 0x000000U, 0x001FFFU, 0x00C000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++ /* GG/SMS have various possible mappings for cartridge memory depending on the mapper used. ++ * However, these ultimately do not map all of their memory at once, typically requiring banking. ++ * Thus, the "real address" used is just a virtual address mapping all cartridge memory in one contiguous block. ++ * Note that this may possibly refer to non-battery backed "extended RAM" so this isn't strictly RC_MEMORY_TYPE_SAVE_RAM. ++ * libretro cores expose "extended RAM" as RETRO_MEMORY_SAVE_RAM regardless however. ++ */ ++ { 0x002000U, 0x009FFFU, 0x010000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM" } ++}; ++static const rc_memory_regions_t rc_memory_regions_game_gear = { _rc_memory_regions_game_gear, 2 }; ++ ++/* ===== Intellivision ===== */ ++/* http://wiki.intellivision.us/index.php/Memory_Map */ ++/* NOTE: Intellivision memory addresses point at 16-bit values. FreeIntv exposes them as little-endian ++ * 32-bit values. As such, the addresses are off by a factor of 4 _and_ the data is only where we ++ * expect it on little-endian systems. ++ */ ++static const rc_memory_region_t _rc_memory_regions_intellivision[] = { ++ /* For backwards compatibility, register a 128-byte chunk of video RAM so the system memory ++ * will start at $0080. $0000-$007F previously tried to map to the STIC video registers as ++ * RETRO_MEMORY_VIDEO_RAM, and FreeIntv didn't expose any RETRO_MEMORY_VIDEO_RAM, so the first ++ * byte of RETRO_MEMORY_SYSTEM_RAM was registered at $0080. The data at $0080 is actually the ++ * STIC registers (4 bytes each), so we need to provide an arbitrary 128-byte padding that ++ * claims to be video RAM to ensure the system RAM ends up at the right address. ++ */ ++ { 0x000000U, 0x00007FU, 0xFFFFFFU, RC_MEMORY_TYPE_VIDEO_RAM, "" }, ++ ++ /* RetroAchievements address = real address x4 + 0x80. ++ * These all have to map to RETRO_MEMORY_SYSTEM_RAM (even the video-related fields) as the ++ * entire block is exposed as a single entity by FreeIntv */ ++ ++ /* $0000-$007F: STIC registers, $0040-$007F are readonly */ ++ { 0x000080U, 0x00027FU, 0x000000U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "STIC Registers" }, ++ /* $0080-$00FF: unused */ ++ { 0x000280U, 0x00047FU, 0x000080U, RC_MEMORY_TYPE_UNUSED, "" }, ++ /* $0100-$035F: system RAM, $0100-$01EF is scratch memory and only 8-bits per address */ ++ { 0x000480U, 0x000DFFU, 0x000100U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++ /* $0360-$03FF: unused */ ++ { 0x000E00U, 0x00107FU, 0x000360U, RC_MEMORY_TYPE_UNUSED, "" }, ++ /* $0400-$0FFF: cartridge RAM */ ++ { 0x001080U, 0x00407FU, 0x000400U, RC_MEMORY_TYPE_SYSTEM_RAM, "Cartridge RAM" }, ++ /* $1000-$1FFF: unused */ ++ { 0x004080U, 0x00807FU, 0x001000U, RC_MEMORY_TYPE_UNUSED, "" }, ++ /* $2000-$2FFF: cartridge RAM */ ++ { 0x008080U, 0x00C07FU, 0x002000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Cartridge RAM" }, ++ /* $3000-$3FFF: video RAM */ ++ { 0x00C080U, 0x01007FU, 0x003000U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Video RAM" }, ++ /* $4000-$FFFF: cartridge RAM */ ++ { 0x010080U, 0x04007FU, 0x004000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Cartridge RAM" }, ++}; ++static const rc_memory_regions_t rc_memory_regions_intellivision = { _rc_memory_regions_intellivision, 10 }; ++ ++/* ===== Interton VC 4000 ===== */ ++/* https://amigan.yatho.com/i-coding.txt */ ++/* Cartridge RAM is not persisted, it's just expanded storage */ ++static const rc_memory_region_t _rc_memory_regions_interton_vc_4000[] = { ++ { 0x000000U, 0x0003FFU, 0x001800U, RC_MEMORY_TYPE_SYSTEM_RAM, "Cartridge RAM" }, ++ { 0x000400U, 0x0004FFU, 0x001E00U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "I/O Area" }, ++ { 0x000500U, 0x0005FFU, 0x001F00U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++}; ++static const rc_memory_regions_t rc_memory_regions_interton_vc_4000 = { _rc_memory_regions_interton_vc_4000, 3 }; ++ ++/* ===== Magnavox Odyssey 2 ===== */ ++/* https://sudonull.com/post/76885-Architecture-and-programming-Philips-Videopac-Magnavox-Odyssey-2 */ ++static const rc_memory_region_t _rc_memory_regions_magnavox_odyssey_2[] = { ++ /* Internal and external RAMs are reachable using unique instructions. ++ * The real addresses provided are virtual and for mapping purposes only. */ ++ { 0x000000U, 0x00003FU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Internal RAM" }, ++ { 0x000040U, 0x00013FU, 0x000040U, RC_MEMORY_TYPE_SYSTEM_RAM, "External RAM" } ++}; ++static const rc_memory_regions_t rc_memory_regions_magnavox_odyssey_2 = { _rc_memory_regions_magnavox_odyssey_2, 2 }; ++ ++/* ===== Master System ===== */ ++/* https://www.smspower.org/Development/MemoryMap */ ++/* https://www.smspower.org/Development/Mappers */ ++static const rc_memory_region_t _rc_memory_regions_master_system[] = { ++ { 0x000000U, 0x001FFFU, 0x00C000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++ /* GG/SMS have various possible mappings for cartridge memory depending on the mapper used. ++ * However, these ultimately do not map all of their memory at once, typically requiring banking. ++ * Thus, the "real address" used is just a virtual address mapping all cartridge memory in one contiguous block. ++ * Note that this may possibly refer to non-battery backed "extended RAM" so this isn't strictly RC_MEMORY_TYPE_SAVE_RAM. ++ * libretro cores expose "extended RAM" as RETRO_MEMORY_SAVE_RAM regardless however. ++ */ ++ { 0x002000U, 0x009FFFU, 0x010000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM" } ++}; ++static const rc_memory_regions_t rc_memory_regions_master_system = { _rc_memory_regions_master_system, 2 }; ++ ++/* ===== MegaDrive (Genesis) ===== */ ++/* https://www.smspower.org/Development/MemoryMap */ ++static const rc_memory_region_t _rc_memory_regions_megadrive[] = { ++ { 0x000000U, 0x00FFFFU, 0xFF0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++ { 0x010000U, 0x01FFFFU, 0x000000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM" } ++}; ++static const rc_memory_regions_t rc_memory_regions_megadrive = { _rc_memory_regions_megadrive, 2 }; ++ ++/* ===== MegaDrive 32X (Genesis 32X) ===== */ ++/* http://devster.monkeeh.com/sega/32xguide1.txt */ ++static const rc_memory_region_t _rc_memory_regions_megadrive_32x[] = { ++ { 0x000000U, 0x00FFFFU, 0x00FF0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* Main MegaDrive RAM */ ++ { 0x010000U, 0x04FFFFU, 0x06000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "32X RAM"}, /* Additional 32X RAM */ ++ { 0x050000U, 0x05FFFFU, 0x00000000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM" } ++}; ++static const rc_memory_regions_t rc_memory_regions_megadrive_32x = { _rc_memory_regions_megadrive_32x, 3 }; ++ ++/* ===== MSX ===== */ ++/* https://www.msx.org/wiki/The_Memory */ ++/* MSX only has 64KB of addressable RAM, of which 32KB is reserved for the system/BIOS. ++ * However, the system has up to 512KB of RAM, which is paged into the addressable RAM ++ * We expect the raw RAM to be exposed, rather than force the devs to worry about the ++ * paging system. The entire RAM is expected to appear starting at $10000, which is not ++ * addressable by the system itself. ++ */ ++static const rc_memory_region_t _rc_memory_regions_msx[] = { ++ { 0x000000U, 0x07FFFFU, 0x010000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++}; ++static const rc_memory_regions_t rc_memory_regions_msx = { _rc_memory_regions_msx, 1 }; ++ ++/* ===== MS DOS ===== */ ++static const rc_memory_region_t _rc_memory_regions_ms_dos[] = { ++ /* DOS emulators split the 640 KB conventional memory into two regions. ++ * First the part of the conventional memory given to the running game at $000000. ++ * The part of the conventional memory containing DOS and BIOS controlled memory ++ * is at $100000. The length of these can vary depending on the hardware ++ * and DOS version (or emulated DOS shell). ++ * These first two regions will only ever total to 640 KB but the regions map ++ * to 1 MB bounds to make resulting memory addresses more readable. ++ * When emulating a game not under DOS (so called 'PC Booter' games), the entirety ++ * of the 640 KB conventional memory block will be at $000000. ++ */ ++ { 0x00000000U, 0x0009FFFFU, 0x00000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Game Conventional Memory" }, ++ { 0x000A0000U, 0x000FFFFFU, 0x000A0000U, RC_MEMORY_TYPE_UNUSED, "Padding to align OS Conventional Memory" }, ++ { 0x00100000U, 0x0019FFFFU, 0x00100000U, RC_MEMORY_TYPE_SYSTEM_RAM, "OS Conventional Memory" }, ++ { 0x001A0000U, 0x001FFFFFU, 0x001A0000U, RC_MEMORY_TYPE_UNUSED, "Padding to align Expanded Memory" }, ++ /* Last is all the expanded memory which for now we map up to 64 MB which should be ++ * enough for the games we want to cover. An emulator might emulate more than that. ++ */ ++ { 0x00200000U, 0x041FFFFFU, 0x00200000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Expanded Memory" } ++}; ++static const rc_memory_regions_t rc_memory_regions_ms_dos = { _rc_memory_regions_ms_dos, 5 }; ++ ++/* ===== Neo Geo Pocket ===== */ ++/* http://neopocott.emuunlim.com/docs/tech-11.txt */ ++static const rc_memory_region_t _rc_memory_regions_neo_geo_pocket[] = { ++ /* The docs suggest there's Work RAM exposed from $0000-$6FFF, Sound RAM from $7000-$7FFF, and Video ++ * RAM from $8000-$BFFF, but both MednafenNGP and FBNeo only expose system RAM from $4000-$7FFF */ ++ { 0x000000U, 0x003FFFU, 0x004000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" } ++}; ++static const rc_memory_regions_t rc_memory_regions_neo_geo_pocket = { _rc_memory_regions_neo_geo_pocket, 1 }; ++ ++/* ===== Neo Geo CD ===== */ ++/* https://wiki.neogeodev.org/index.php?title=68k_memory_map */ ++/* NeoCD exposes $000000-$1FFFFF as System RAM, but it seems like only the WORKRAM section is used. ++ * This is consistent with http://www.hardmvs.fr/manuals/NeoGeoProgrammersGuide.pdf (page25), which says: ++ * ++ * Furthermore, the NEO-GEO provides addresses 100000H-10FFFFH as a work area, out of which the ++ * addresses 10F300H-10FFFFH are reserved exclusively for use by the system program. Therefore, ++ * every game is to use addresses 100000H-10F2FFH. ++ * ++ * Also note that PRG files (game ROM) can be loaded anywhere else in the $000000-$1FFFFF range. ++ * AoF3 illustrates this pretty clearly: https://wiki.neogeodev.org/index.php?title=IPL_file ++ * ++ * PROG_CD.PRG,0,0 ++ * PROG_CDX.PRG,0,058000 ++ * CNV_NM.PRG,0,0C0000 ++ * FIX_DATA.PRG,0,0FD000 ++ * OBJACTLK.PRG,0,130000 ++ * SSEL_CNV.PRG,0,15A000 ++ * SSEL_BAK.PRG,0,16F000 ++ * HITMSG.PRG,0,170000 ++ * SSEL_SPR.PRG,0,19D000 ++ */ ++static const rc_memory_region_t _rc_memory_regions_neo_geo_cd[] = { ++ { 0x000000U, 0x00F2FFU, 0x00100000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++ /* NOTE: some BIOS settings are exposed through the reserved RAM: https://wiki.neogeodev.org/index.php?title=68k_ASM_defines */ ++ { 0x00F300U, 0x00FFFFU, 0x0010F300U, RC_MEMORY_TYPE_SYSTEM_RAM, "Reserved RAM" }, ++}; ++static const rc_memory_regions_t rc_memory_regions_neo_geo_cd = { _rc_memory_regions_neo_geo_cd, 2 }; ++ ++/* ===== Nintendo Entertainment System ===== */ ++/* https://wiki.nesdev.com/w/index.php/CPU_memory_map */ ++static const rc_memory_region_t _rc_memory_regions_nes[] = { ++ { 0x0000U, 0x07FFU, 0x0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++ { 0x0800U, 0x0FFFU, 0x0000U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Mirror RAM" }, /* duplicates memory from $0000-$07FF */ ++ { 0x1000U, 0x17FFU, 0x0000U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Mirror RAM" }, /* duplicates memory from $0000-$07FF */ ++ { 0x1800U, 0x1FFFU, 0x0000U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Mirror RAM" }, /* duplicates memory from $0000-$07FF */ ++ { 0x2000U, 0x2007U, 0x2000U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "PPU Register" }, ++ { 0x2008U, 0x3FFFU, 0x2008U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Mirrored PPU Register" }, /* repeats every 8 bytes */ ++ { 0x4000U, 0x4017U, 0x4000U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "APU and I/O register" }, ++ { 0x4018U, 0x401FU, 0x4018U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "APU and I/O test register" }, ++ ++ /* NOTE: these are for the original NES/Famicom */ ++ { 0x4020U, 0x5FFFU, 0x4020U, RC_MEMORY_TYPE_READONLY, "Cartridge data"}, /* varies by mapper */ ++ { 0x6000U, 0x7FFFU, 0x6000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM"}, ++ { 0x8000U, 0xFFFFU, 0x8000U, RC_MEMORY_TYPE_READONLY, "Cartridge ROM"}, ++}; ++static const rc_memory_regions_t rc_memory_regions_nes = { _rc_memory_regions_nes, 11 }; ++ ++/* ===== Nintendo 64 ===== */ ++/* https://raw.githubusercontent.com/mikeryan/n64dev/master/docs/n64ops/n64ops%23h.txt */ ++/* https://n64brew.dev/wiki/Memory_map#Virtual_Memory_Map */ ++static const rc_memory_region_t _rc_memory_regions_n64[] = { ++ { 0x000000U, 0x1FFFFFU, 0x80000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RDRAM 1 */ ++ { 0x200000U, 0x3FFFFFU, 0x80200000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RDRAM 2 */ ++ { 0x400000U, 0x7FFFFFU, 0x80400000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" } /* expansion pak */ ++}; ++static const rc_memory_regions_t rc_memory_regions_n64 = { _rc_memory_regions_n64, 3 }; ++ ++/* ===== Nintendo DS ===== */ ++/* https://www.akkit.org/info/gbatek.htm#dsmemorymaps */ ++static const rc_memory_region_t _rc_memory_regions_nintendo_ds[] = { ++ { 0x0000000U, 0x03FFFFFU, 0x02000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++ /* To keep DS/DSi memory maps aligned, padding is set here for the DSi's extra RAM */ ++ { 0x0400000U, 0x0FFFFFFU, 0x02400000U, RC_MEMORY_TYPE_UNUSED, "Unused (DSi exclusive)" }, ++ /* The DS/DSi have "tightly coupled memory": very fast memory directly connected to the CPU. ++ * This memory has an instruction variant (ITCM) and a data variant (DTCM). ++ * For achievement purposes it is useful to be able to access the data variant. ++ * This memory does not have a fixed address on console, being able to be moved to any $0xxxx000 region. ++ * While normally this kind of memory is addressed outside of the possible native addressing space, this is simply not possible, ++ * as the DS/DSi's address space covers all possible uint32_t values. ++ * $0E000000 is used here as a "pseudo-end," as this is nearly the end of all the memory actually mapped to addresses ++ * This means that (with the exception of $FFFF0000 onwards, which has the ARM9 BIOS mapped) $0E000000 onwards has nothing mapped to it ++ */ ++ { 0x1000000U, 0x1003FFFU, 0x0E000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Data TCM" } ++}; ++static const rc_memory_regions_t rc_memory_regions_nintendo_ds = { _rc_memory_regions_nintendo_ds, 3 }; ++ ++/* ===== Nintendo DSi ===== */ ++/* https://problemkaputt.de/gbatek.htm#dsiiomap */ ++static const rc_memory_region_t _rc_memory_regions_nintendo_dsi[] = { ++ { 0x0000000U, 0x0FFFFFFU, 0x02000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++ { 0x1000000U, 0x1003FFFU, 0x0E000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Data TCM" } ++}; ++static const rc_memory_regions_t rc_memory_regions_nintendo_dsi = { _rc_memory_regions_nintendo_dsi, 2 }; ++ ++/* ===== Oric ===== */ ++static const rc_memory_region_t _rc_memory_regions_oric[] = { ++ /* actual size depends on machine type - up to 64KB */ ++ { 0x000000U, 0x00FFFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" } ++}; ++static const rc_memory_regions_t rc_memory_regions_oric = { _rc_memory_regions_oric, 1 }; ++ ++/* ===== PC-8800 ===== */ ++static const rc_memory_region_t _rc_memory_regions_pc8800[] = { ++ { 0x000000U, 0x00FFFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Main RAM" }, ++ { 0x010000U, 0x010FFFU, 0x010000U, RC_MEMORY_TYPE_VIDEO_RAM, "Text VRAM" } /* technically VRAM, but often used as system RAM */ ++}; ++static const rc_memory_regions_t rc_memory_regions_pc8800 = { _rc_memory_regions_pc8800, 2 }; ++ ++/* ===== PC Engine ===== */ ++/* http://www.archaicpixels.com/Memory_Map */ ++static const rc_memory_region_t _rc_memory_regions_pc_engine[] = { ++ { 0x000000U, 0x001FFFU, 0x1F0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++}; ++static const rc_memory_regions_t rc_memory_regions_pc_engine = { _rc_memory_regions_pc_engine, 1 }; ++ ++/* ===== PC Engine CD===== */ ++/* http://www.archaicpixels.com/Memory_Map */ ++static const rc_memory_region_t _rc_memory_regions_pc_engine_cd[] = { ++ { 0x000000U, 0x001FFFU, 0x1F0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++ { 0x002000U, 0x011FFFU, 0x100000U, RC_MEMORY_TYPE_SYSTEM_RAM, "CD RAM" }, ++ { 0x012000U, 0x041FFFU, 0x0D0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Super System Card RAM" }, ++ { 0x042000U, 0x0427FFU, 0x1EE000U, RC_MEMORY_TYPE_SAVE_RAM, "CD Battery-backed RAM" } ++}; ++static const rc_memory_regions_t rc_memory_regions_pc_engine_cd = { _rc_memory_regions_pc_engine_cd, 4 }; ++ ++/* ===== PC-FX ===== */ ++/* http://daifukkat.su/pcfx/data/memmap.html */ ++static const rc_memory_region_t _rc_memory_regions_pcfx[] = { ++ { 0x000000U, 0x1FFFFFU, 0x00000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++ { 0x200000U, 0x207FFFU, 0xE0000000U, RC_MEMORY_TYPE_SAVE_RAM, "Internal Backup Memory" }, ++ { 0x208000U, 0x20FFFFU, 0xE8000000U, RC_MEMORY_TYPE_SAVE_RAM, "External Backup Memory" }, ++}; ++static const rc_memory_regions_t rc_memory_regions_pcfx = { _rc_memory_regions_pcfx, 3 }; ++ ++/* ===== PlayStation ===== */ ++/* http://www.raphnet.net/electronique/psx_adaptor/Playstation.txt */ ++static const rc_memory_region_t _rc_memory_regions_playstation[] = { ++ { 0x000000U, 0x00FFFFU, 0x00000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Kernel RAM" }, ++ { 0x010000U, 0x1FFFFFU, 0x00010000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++ { 0x200000U, 0x2003FFU, 0x1F800000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Scratchpad RAM" } ++}; ++static const rc_memory_regions_t rc_memory_regions_playstation = { _rc_memory_regions_playstation, 3 }; ++ ++/* ===== PlayStation 2 ===== */ ++/* https://psi-rockin.github.io/ps2tek/ */ ++static const rc_memory_region_t _rc_memory_regions_playstation2[] = { ++ { 0x00000000U, 0x000FFFFFU, 0x00000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Kernel RAM" }, ++ { 0x00100000U, 0x01FFFFFFU, 0x00100000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++ { 0x02000000U, 0x02003FFFU, 0x70000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Scratchpad RAM" }, ++}; ++static const rc_memory_regions_t rc_memory_regions_playstation2 = { _rc_memory_regions_playstation2, 3 }; ++ ++/* ===== PlayStation Portable ===== */ ++/* https://github.com/uofw/upspd/wiki/Memory-map */ ++static const rc_memory_region_t _rc_memory_regions_psp[] = { ++ { 0x00000000U, 0x007FFFFFU, 0x08000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Kernel RAM" }, ++ { 0x00800000U, 0x01FFFFFFU, 0x08800000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++}; ++static const rc_memory_regions_t rc_memory_regions_psp = { _rc_memory_regions_psp, 2 }; ++ ++/* ===== Pokemon Mini ===== */ ++/* https://www.pokemon-mini.net/documentation/memory-map/ */ ++static const rc_memory_region_t _rc_memory_regions_pokemini[] = { ++ { 0x000000U, 0x000FFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "BIOS RAM" }, ++ { 0x001000U, 0x001FFFU, 0x001000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" } ++}; ++static const rc_memory_regions_t rc_memory_regions_pokemini = { _rc_memory_regions_pokemini, 2 }; ++ ++/* ===== Sega CD ===== */ ++/* https://en.wikibooks.org/wiki/Genesis_Programming/68K_Memory_map/ */ ++static const rc_memory_region_t _rc_memory_regions_segacd[] = { ++ { 0x000000U, 0x00FFFFU, 0x00FF0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "68000 RAM" }, ++ { 0x010000U, 0x08FFFFU, 0x80020000U, RC_MEMORY_TYPE_SYSTEM_RAM, "CD PRG RAM" }, /* normally banked into $020000-$03FFFF */ ++ { 0x090000U, 0x0AFFFFU, 0x00200000U, RC_MEMORY_TYPE_SYSTEM_RAM, "CD WORD RAM" } ++}; ++static const rc_memory_regions_t rc_memory_regions_segacd = { _rc_memory_regions_segacd, 3 }; ++ ++/* ===== Sega Saturn ===== */ ++/* https://segaretro.org/Sega_Saturn_hardware_notes_(2004-04-27) */ ++static const rc_memory_region_t _rc_memory_regions_saturn[] = { ++ { 0x000000U, 0x0FFFFFU, 0x00200000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Work RAM Low" }, ++ { 0x100000U, 0x1FFFFFU, 0x06000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Work RAM High" } ++}; ++static const rc_memory_regions_t rc_memory_regions_saturn = { _rc_memory_regions_saturn, 2 }; ++ ++/* ===== SG-1000 ===== */ ++/* https://www.smspower.org/Development/MemoryMap */ ++static const rc_memory_region_t _rc_memory_regions_sg1000[] = { ++ { 0x000000U, 0x0003FFU, 0xC000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++ /* https://github.com/libretro/FBNeo/blob/697801c6262be6ca91615cf905444d3e039bc06f/src/burn/drv/sg1000/d_sg1000.cpp#L210-L237 */ ++ /* Expansion mode B exposes 8KB at $C000. The first 2KB hides the System RAM, but since the address matches, ++ we'll leverage that definition and expand it another 6KB */ ++ { 0x000400U, 0x001FFFU, 0xC400U, RC_MEMORY_TYPE_SYSTEM_RAM, "Extended RAM" }, ++ /* Expansion mode A exposes 8KB at $2000 */ ++ { 0x002000U, 0x003FFFU, 0x2000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Extended RAM" }, ++ /* Othello exposes 2KB at $8000, and The Castle exposes 8KB at $8000 */ ++ { 0x004000U, 0x005FFFU, 0x8000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Extended RAM" } ++}; ++static const rc_memory_regions_t rc_memory_regions_sg1000 = { _rc_memory_regions_sg1000, 4 }; ++ ++/* ===== Super Cassette Vision ===== */ ++/* https://github.com/mamedev/mame/blob/f32bb79e8541ba96d3a8144b220c48fb7536ba4b/src/mame/epoch/scv.cpp#L78-L86 */ ++/* SCV only has 128 bytes of system RAM, any additional memory is provided on the individual carts and is ++ * not backed up by battery. */ ++/* http://www.videogameconsolelibrary.com/pg80-super_cass_vis.htm#page=specs */ ++static const rc_memory_region_t _rc_memory_regions_scv[] = { ++ { 0x000000U, 0x000FFFU, 0x000000U, RC_MEMORY_TYPE_READONLY, "System ROM" }, /* BIOS */ ++ { 0x001000U, 0x001FFFU, 0x001000U, RC_MEMORY_TYPE_UNUSED, "" }, ++ { 0x002000U, 0x003FFFU, 0x002000U, RC_MEMORY_TYPE_VIDEO_RAM, "Video RAM" }, /* only really goes to $33FF? */ ++ { 0x004000U, 0x007FFFU, 0x004000U, RC_MEMORY_TYPE_UNUSED, "" }, ++ { 0x008000U, 0x00FF7FU, 0x008000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Cartridge RAM" }, ++ { 0x00FF80U, 0x00FFFFU, 0x00FF80U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" } ++}; ++static const rc_memory_regions_t rc_memory_regions_scv = { _rc_memory_regions_scv, 6 }; ++ ++/* ===== Super Nintendo ===== */ ++/* https://en.wikibooks.org/wiki/Super_NES_Programming/SNES_memory_map#LoROM */ ++static const rc_memory_region_t _rc_memory_regions_snes[] = { ++ { 0x000000U, 0x01FFFFU, 0x07E0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++ /* Cartridge RAM here could be in a variety of places in SNES memory, depending on the ROM type. ++ * Due to this, we place Cartridge RAM outside of the possible native addressing space. ++ * Note that this also covers SA-1 BW-RAM (which is exposed as RETRO_MEMORY_SAVE_RAM for libretro). ++ */ ++ { 0x020000U, 0x09FFFFU, 0x1000000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM" }, ++ /* I-RAM on the SA-1 is normally at 0x003000. However, this address typically just has a mirror of System RAM for other ROM types. ++ * To avoid conflicts, don't use 0x003000, instead map it outside of the possible native addressing space. ++ */ ++ { 0x0A0000U, 0x0A07FFU, 0x1080000U, RC_MEMORY_TYPE_SYSTEM_RAM, "I-RAM (SA-1)" } ++}; ++static const rc_memory_regions_t rc_memory_regions_snes = { _rc_memory_regions_snes, 3 }; ++ ++/* ===== Thomson TO8 ===== */ ++/* https://github.com/mamedev/mame/blob/master/src/mame/drivers/thomson.cpp#L1617 */ ++static const rc_memory_region_t _rc_memory_regions_thomson_to8[] = { ++ { 0x000000U, 0x07FFFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" } ++}; ++static const rc_memory_regions_t rc_memory_regions_thomson_to8 = { _rc_memory_regions_thomson_to8, 1 }; ++ ++/* ===== TI-83 ===== */ ++/* https://tutorials.eeems.ca/ASMin28Days/lesson/day03.html#mem */ ++static const rc_memory_region_t _rc_memory_regions_ti83[] = { ++ { 0x000000U, 0x007FFFU, 0x008000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++}; ++static const rc_memory_regions_t rc_memory_regions_ti83 = { _rc_memory_regions_ti83, 1 }; ++ ++/* ===== TIC-80 ===== */ ++/* https://github.com/nesbox/TIC-80/wiki/RAM */ ++static const rc_memory_region_t _rc_memory_regions_tic80[] = { ++ { 0x000000U, 0x003FFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Video RAM" }, /* have to classify this as system RAM because the core exposes it as part of the RETRO_MEMORY_SYSTEM_RAM */ ++ { 0x004000U, 0x005FFFU, 0x004000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Tile RAM" }, ++ { 0x006000U, 0x007FFFU, 0x006000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Sprite RAM" }, ++ { 0x008000U, 0x00FF7FU, 0x008000U, RC_MEMORY_TYPE_SYSTEM_RAM, "MAP RAM" }, ++ { 0x00FF80U, 0x00FF8BU, 0x00FF80U, RC_MEMORY_TYPE_SYSTEM_RAM, "Input State" }, ++ { 0x00FF8CU, 0x014003U, 0x00FF8CU, RC_MEMORY_TYPE_SYSTEM_RAM, "Sound RAM" }, ++ { 0x014004U, 0x014403U, 0x014004U, RC_MEMORY_TYPE_SAVE_RAM, "Persistent Memory" }, /* this is also returned as part of RETRO_MEMORY_SYSTEM_RAM, but can be extrapolated correctly because the pointer starts at the first SYSTEM_RAM region */ ++ { 0x014404U, 0x014603U, 0x014404U, RC_MEMORY_TYPE_SYSTEM_RAM, "Sprite Flags" }, ++ { 0x014604U, 0x014E03U, 0x014604U, RC_MEMORY_TYPE_SYSTEM_RAM, "System Font" }, ++ { 0x014E04U, 0x017FFFU, 0x014E04U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM"} ++}; ++static const rc_memory_regions_t rc_memory_regions_tic80 = { _rc_memory_regions_tic80, 10 }; ++ ++/* ===== Uzebox ===== */ ++/* https://uzebox.org/index.php */ ++static const rc_memory_region_t _rc_memory_regions_uzebox[] = { ++ { 0x000000U, 0x000FFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" } ++}; ++static const rc_memory_regions_t rc_memory_regions_uzebox = { _rc_memory_regions_uzebox, 1 }; ++ ++/* ===== Vectrex ===== */ ++/* https://roadsidethoughts.com/vectrex/vectrex-memory-map.htm */ ++static const rc_memory_region_t _rc_memory_regions_vectrex[] = { ++ { 0x000000U, 0x0003FFU, 0x00C800U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" } ++}; ++static const rc_memory_regions_t rc_memory_regions_vectrex = { _rc_memory_regions_vectrex, 1 }; ++ ++/* ===== Virtual Boy ===== */ ++static const rc_memory_region_t _rc_memory_regions_virtualboy[] = { ++ { 0x000000U, 0x00FFFFU, 0x05000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++ { 0x010000U, 0x01FFFFU, 0x06000000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM" } ++}; ++static const rc_memory_regions_t rc_memory_regions_virtualboy = { _rc_memory_regions_virtualboy, 2 }; ++ ++/* ===== Watara Supervision ===== */ ++/* https://github.com/libretro/potator/blob/b5e5ba02914fcdf4a8128072dbc709da28e08832/common/memorymap.c#L231-L259 */ ++static const rc_memory_region_t _rc_memory_regions_watara_supervision[] = { ++ { 0x0000U, 0x001FFFU, 0x0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++ { 0x2000U, 0x003FFFU, 0x2000U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Registers" }, ++ { 0x4000U, 0x005FFFU, 0x4000U, RC_MEMORY_TYPE_VIDEO_RAM, "Video RAM" } ++}; ++static const rc_memory_regions_t rc_memory_regions_watara_supervision = { _rc_memory_regions_watara_supervision, 3 }; ++ ++/* ===== WASM-4 ===== */ ++/* fantasy console that runs specifically designed WebAssembly games */ ++/* https://github.com/aduros/wasm4/blob/main/site/docs/intro.md#hardware-specs */ ++static const rc_memory_region_t _rc_memory_regions_wasm4[] = { ++ { 0x000000U, 0x00FFFFU, 0x00000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++ /* Persistent storage is not directly accessible from the game. It has to be loaded into System RAM first ++ { 0x010000U, 0x0103FFU, 0x80000000U, RC_MEMORY_TYPE_SAVE_RAM, "Disk Storage"} ++ */ ++}; ++static const rc_memory_regions_t rc_memory_regions_wasm4 = { _rc_memory_regions_wasm4, 1 }; ++ ++/* ===== Wii ===== */ ++/* https://wiibrew.org/wiki/Memory_map */ ++static const rc_memory_region_t _rc_memory_regions_wii[] = { ++ { 0x00000000U, 0x017FFFFF, 0x80000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++ { 0x01800000U, 0x0FFFFFFF, 0x81800000U, RC_MEMORY_TYPE_UNUSED, "Unused" }, ++ { 0x10000000U, 0x13FFFFFF, 0x90000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" } ++}; ++static const rc_memory_regions_t rc_memory_regions_wii = { _rc_memory_regions_wii, 3 }; ++ ++/* ===== WonderSwan ===== */ ++/* http://daifukkat.su/docs/wsman/#ovr_memmap */ ++static const rc_memory_region_t _rc_memory_regions_wonderswan[] = { ++ /* RAM ends at 0x3FFF for WonderSwan, WonderSwan color uses all 64KB */ ++ { 0x000000U, 0x00FFFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, ++ /* Only 64KB of SRAM is accessible via the addressing scheme, but the cartridge ++ * may have up to 512KB of SRAM. http://daifukkat.su/docs/wsman/#cart_meta ++ * Since beetle_wswan exposes it as a contiguous block, assume its contiguous ++ * even though the documentation says $20000-$FFFFF is ROM data. If this causes ++ * a conflict in the future, we can revisit. A new region with a virtual address ++ * could be added to pick up the additional SRAM data. As long as it immediately ++ * follows the 64KB at $10000, all existing achievements should be unaffected. ++ */ ++ { 0x010000U, 0x08FFFFU, 0x010000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM" } ++}; ++static const rc_memory_regions_t rc_memory_regions_wonderswan = { _rc_memory_regions_wonderswan, 2 }; ++ ++/* ===== ZX Spectrum ===== */ ++/* https://github.com/TASEmulators/BizHawk/blob/3a3b22c/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum16K/ZX16.cs ++ * https://github.com/TASEmulators/BizHawk/blob/3a3b22c/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum48K/ZX48.Memory.cs ++ * https://worldofspectrum.org/faq/reference/128kreference.htm */ ++static const rc_memory_region_t _rc_memory_regions_zx_spectrum[] = { ++ /* ZX Spectrum is complicated as multiple models exist with varying amounts of memory. ++ * In practice, this can be reduced to two categories: 16K/48K units, and 128K units. ++ * 16K/48K units have RAM starting at $4000 onwards, 16K ending at $7FFF, 48K ending at $FFFF. ++ * 128K units have banked memory, with $4000-$7FFF normally having RAM bank 5, and $8000-$BFFF normally having RAM bank 2. ++ * $C000-$FFFF is normally reserved for banked RAM, having any of banks 0-7. ++ * For the purposes of the RAM map, $C000-$FFFF is assumed to be bank 0, and $10000 onwards has the other banks in order (1, 3, 4, 6, 7) ++ * Doing it this way always for 16K/48K games to have the same memory map on the 128K, and thus avoid issues due to the model selected. ++ * Later 128K units also have a special banking mode that changes up banking completely, but for 16K/48K compatibility purposes this doesn't matter, and so is irrelevant. ++ */ ++ { 0x00000U, 0x03FFFU, 0x04000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Screen RAM" }, /* RAM bank 5 on 128K units */ ++ { 0x04000U, 0x07FFFU, 0x08000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RAM bank 2 on 128K units */ ++ { 0x08000U, 0x0BFFFU, 0x0C000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RAM bank 0-7 on 128K units, assumed to be bank 0 here */ ++ { 0x0C000U, 0x0FFFFU, 0x10000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RAM bank 1 on 128K units */ ++ { 0x10000U, 0x13FFFU, 0x14000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RAM bank 3 on 128K units */ ++ { 0x14000U, 0x17FFFU, 0x18000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RAM bank 4 on 128K units */ ++ { 0x18000U, 0x1BFFFU, 0x1C000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RAM bank 6 on 128K units */ ++ { 0x1C000U, 0x1FFFFU, 0x20000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Screen RAM" } /* RAM bank 7 on 128K units */ ++}; ++static const rc_memory_regions_t rc_memory_regions_zx_spectrum = { _rc_memory_regions_zx_spectrum, 8 }; ++ ++/* ===== default ===== */ ++static const rc_memory_regions_t rc_memory_regions_none = { 0, 0 }; ++ ++const rc_memory_regions_t* rc_console_memory_regions(uint32_t console_id) ++{ ++ switch (console_id) ++ { ++ case RC_CONSOLE_3DO: ++ return &rc_memory_regions_3do; ++ ++ case RC_CONSOLE_AMIGA: ++ return &rc_memory_regions_amiga; ++ ++ case RC_CONSOLE_AMSTRAD_PC: ++ return &rc_memory_regions_amstrad_pc; ++ ++ case RC_CONSOLE_APPLE_II: ++ return &rc_memory_regions_appleii; ++ ++ case RC_CONSOLE_ARCADIA_2001: ++ return &rc_memory_regions_arcadia_2001; ++ ++ case RC_CONSOLE_ARDUBOY: ++ return &rc_memory_regions_arduboy; ++ ++ case RC_CONSOLE_ATARI_2600: ++ return &rc_memory_regions_atari2600; ++ ++ case RC_CONSOLE_ATARI_7800: ++ return &rc_memory_regions_atari7800; ++ ++ case RC_CONSOLE_ATARI_JAGUAR: ++ case RC_CONSOLE_ATARI_JAGUAR_CD: ++ return &rc_memory_regions_atari_jaguar; ++ ++ case RC_CONSOLE_ATARI_LYNX: ++ return &rc_memory_regions_atari_lynx; ++ ++ case RC_CONSOLE_COLECOVISION: ++ return &rc_memory_regions_colecovision; ++ ++ case RC_CONSOLE_COMMODORE_64: ++ return &rc_memory_regions_c64; ++ ++ case RC_CONSOLE_DREAMCAST: ++ return &rc_memory_regions_dreamcast; ++ ++ case RC_CONSOLE_ELEKTOR_TV_GAMES_COMPUTER: ++ return &rc_memory_regions_elektor_tv_games; ++ ++ case RC_CONSOLE_FAIRCHILD_CHANNEL_F: ++ return &rc_memory_regions_fairchild_channel_f; ++ ++ case RC_CONSOLE_FAMICOM_DISK_SYSTEM: ++ return &rc_memory_regions_famicom_disk_system; ++ ++ case RC_CONSOLE_GAMEBOY: ++ return &rc_memory_regions_gameboy; ++ ++ case RC_CONSOLE_GAMEBOY_COLOR: ++ return &rc_memory_regions_gameboy_color; ++ ++ case RC_CONSOLE_GAMEBOY_ADVANCE: ++ return &rc_memory_regions_gameboy_advance; ++ ++ case RC_CONSOLE_GAMECUBE: ++ return &rc_memory_regions_gamecube; ++ ++ case RC_CONSOLE_GAME_GEAR: ++ return &rc_memory_regions_game_gear; ++ ++ case RC_CONSOLE_INTELLIVISION: ++ return &rc_memory_regions_intellivision; ++ ++ case RC_CONSOLE_INTERTON_VC_4000: ++ return &rc_memory_regions_interton_vc_4000; ++ ++ case RC_CONSOLE_MAGNAVOX_ODYSSEY2: ++ return &rc_memory_regions_magnavox_odyssey_2; ++ ++ case RC_CONSOLE_MASTER_SYSTEM: ++ return &rc_memory_regions_master_system; ++ ++ case RC_CONSOLE_MEGA_DRIVE: ++ return &rc_memory_regions_megadrive; ++ ++ case RC_CONSOLE_MEGADUCK: ++ return &rc_memory_regions_megaduck; ++ ++ case RC_CONSOLE_SEGA_32X: ++ return &rc_memory_regions_megadrive_32x; ++ ++ case RC_CONSOLE_MSX: ++ return &rc_memory_regions_msx; ++ ++ case RC_CONSOLE_MS_DOS: ++ return &rc_memory_regions_ms_dos; ++ ++ case RC_CONSOLE_NEOGEO_POCKET: ++ return &rc_memory_regions_neo_geo_pocket; ++ ++ case RC_CONSOLE_NEO_GEO_CD: ++ return &rc_memory_regions_neo_geo_cd; ++ ++ case RC_CONSOLE_NINTENDO: ++ return &rc_memory_regions_nes; ++ ++ case RC_CONSOLE_NINTENDO_64: ++ return &rc_memory_regions_n64; ++ ++ case RC_CONSOLE_NINTENDO_DS: ++ return &rc_memory_regions_nintendo_ds; ++ ++ case RC_CONSOLE_NINTENDO_DSI: ++ return &rc_memory_regions_nintendo_dsi; ++ ++ case RC_CONSOLE_ORIC: ++ return &rc_memory_regions_oric; ++ ++ case RC_CONSOLE_PC8800: ++ return &rc_memory_regions_pc8800; ++ ++ case RC_CONSOLE_PC_ENGINE: ++ return &rc_memory_regions_pc_engine; ++ ++ case RC_CONSOLE_PC_ENGINE_CD: ++ return &rc_memory_regions_pc_engine_cd; ++ ++ case RC_CONSOLE_PCFX: ++ return &rc_memory_regions_pcfx; ++ ++ case RC_CONSOLE_PLAYSTATION: ++ return &rc_memory_regions_playstation; ++ ++ case RC_CONSOLE_PLAYSTATION_2: ++ return &rc_memory_regions_playstation2; ++ ++ case RC_CONSOLE_PSP: ++ return &rc_memory_regions_psp; ++ ++ case RC_CONSOLE_POKEMON_MINI: ++ return &rc_memory_regions_pokemini; ++ ++ case RC_CONSOLE_SATURN: ++ return &rc_memory_regions_saturn; ++ ++ case RC_CONSOLE_SEGA_CD: ++ return &rc_memory_regions_segacd; ++ ++ case RC_CONSOLE_SG1000: ++ return &rc_memory_regions_sg1000; ++ ++ case RC_CONSOLE_SUPER_CASSETTEVISION: ++ return &rc_memory_regions_scv; ++ ++ case RC_CONSOLE_SUPER_NINTENDO: ++ return &rc_memory_regions_snes; ++ ++ case RC_CONSOLE_SUPERVISION: ++ return &rc_memory_regions_watara_supervision; ++ ++ case RC_CONSOLE_THOMSONTO8: ++ return &rc_memory_regions_thomson_to8; ++ ++ case RC_CONSOLE_TI83: ++ return &rc_memory_regions_ti83; ++ ++ case RC_CONSOLE_TIC80: ++ return &rc_memory_regions_tic80; ++ ++ case RC_CONSOLE_UZEBOX: ++ return &rc_memory_regions_uzebox; ++ ++ case RC_CONSOLE_VECTREX: ++ return &rc_memory_regions_vectrex; ++ ++ case RC_CONSOLE_VIRTUAL_BOY: ++ return &rc_memory_regions_virtualboy; ++ ++ case RC_CONSOLE_WASM4: ++ return &rc_memory_regions_wasm4; ++ ++ case RC_CONSOLE_WII: ++ return &rc_memory_regions_wii; ++ ++ case RC_CONSOLE_WONDERSWAN: ++ return &rc_memory_regions_wonderswan; ++ ++ case RC_CONSOLE_ZX_SPECTRUM: ++ return &rc_memory_regions_zx_spectrum; ++ ++ default: ++ return &rc_memory_regions_none; ++ } ++} +diff -rupbN melonDS.orig/src/rcheevos/src/rcheevos/format.c melonDS.ra/src/rcheevos/src/rcheevos/format.c +--- melonDS.orig/src/rcheevos/src/rcheevos/format.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rcheevos/format.c 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,330 @@ ++#include "rc_internal.h" ++ ++#include "../rc_compat.h" ++ ++#include ++#include ++#include ++ ++int rc_parse_format(const char* format_str) { ++ switch (*format_str++) { ++ case 'F': ++ if (!strcmp(format_str, "RAMES")) { ++ return RC_FORMAT_FRAMES; ++ } ++ if (!strncmp(format_str, "LOAT", 4) && format_str[4] >= '1' && format_str[4] <= '6' && format_str[5] == '\0') { ++ return RC_FORMAT_FLOAT1 + (format_str[4] - '1'); ++ } ++ if (!strncmp(format_str, "IXED", 4) && format_str[4] >= '1' && format_str[4] <= '3' && format_str[5] == '\0') { ++ return RC_FORMAT_FIXED1 + (format_str[4] - '1'); ++ } ++ ++ break; ++ ++ case 'T': ++ if (!strcmp(format_str, "IME")) { ++ return RC_FORMAT_FRAMES; ++ } ++ if (!strcmp(format_str, "IMESECS")) { ++ return RC_FORMAT_SECONDS; ++ } ++ if (!strcmp(format_str, "HOUSANDS")) { ++ return RC_FORMAT_THOUSANDS; ++ } ++ if (!strcmp(format_str, "ENS")) { ++ return RC_FORMAT_TENS; ++ } ++ ++ break; ++ ++ case 'S': ++ if (!strcmp(format_str, "ECS")) { ++ return RC_FORMAT_SECONDS; ++ } ++ if (!strcmp(format_str, "CORE")) { ++ return RC_FORMAT_SCORE; ++ } ++ if (!strcmp(format_str, "ECS_AS_MINS")) { ++ return RC_FORMAT_SECONDS_AS_MINUTES; ++ } ++ ++ break; ++ ++ case 'M': ++ if (!strcmp(format_str, "ILLISECS")) { ++ return RC_FORMAT_CENTISECS; ++ } ++ if (!strcmp(format_str, "INUTES")) { ++ return RC_FORMAT_MINUTES; ++ } ++ ++ break; ++ ++ case 'P': ++ if (!strcmp(format_str, "OINTS")) { ++ return RC_FORMAT_SCORE; ++ } ++ ++ break; ++ ++ case 'V': ++ if (!strcmp(format_str, "ALUE")) { ++ return RC_FORMAT_VALUE; ++ } ++ ++ break; ++ ++ case 'U': ++ if (!strcmp(format_str, "NSIGNED")) { ++ return RC_FORMAT_UNSIGNED_VALUE; ++ } ++ ++ break; ++ ++ case 'O': ++ if (!strcmp(format_str, "THER")) { ++ return RC_FORMAT_SCORE; ++ } ++ ++ break; ++ ++ case 'H': ++ if (!strcmp(format_str, "UNDREDS")) { ++ return RC_FORMAT_HUNDREDS; ++ } ++ ++ break; ++ } ++ ++ return RC_FORMAT_VALUE; ++} ++ ++static int rc_format_value_minutes(char* buffer, size_t size, uint32_t minutes) { ++ uint32_t hours; ++ ++ hours = minutes / 60; ++ minutes -= hours * 60; ++ return snprintf(buffer, size, "%uh%02u", hours, minutes); ++} ++ ++static int rc_format_value_seconds(char* buffer, size_t size, uint32_t seconds) { ++ uint32_t hours, minutes; ++ ++ /* apply modulus math to split the seconds into hours/minutes/seconds */ ++ minutes = seconds / 60; ++ seconds -= minutes * 60; ++ if (minutes < 60) { ++ return snprintf(buffer, size, "%u:%02u", minutes, seconds); ++ } ++ ++ hours = minutes / 60; ++ minutes -= hours * 60; ++ return snprintf(buffer, size, "%uh%02u:%02u", hours, minutes, seconds); ++} ++ ++static int rc_format_value_centiseconds(char* buffer, size_t size, uint32_t centiseconds) { ++ uint32_t seconds; ++ int chars, chars2; ++ ++ /* modulus off the centiseconds */ ++ seconds = centiseconds / 100; ++ centiseconds -= seconds * 100; ++ ++ chars = rc_format_value_seconds(buffer, size, seconds); ++ if (chars > 0) { ++ chars2 = snprintf(buffer + chars, size - chars, ".%02u", centiseconds); ++ if (chars2 > 0) { ++ chars += chars2; ++ } else { ++ chars = chars2; ++ } ++ } ++ ++ return chars; ++} ++ ++static int rc_format_value_fixed(char* buffer, size_t size, const char* format, int32_t value, int32_t factor) ++{ ++ if (value >= 0) ++ return snprintf(buffer, size, format, value / factor, value % factor); ++ ++ return snprintf(buffer, size, format, value / factor, (-value) % factor); ++} ++ ++static int rc_format_value_padded(char* buffer, size_t size, const char* format, int32_t value) ++{ ++ if (value == 0) ++ return snprintf(buffer, size, "0"); ++ ++ return snprintf(buffer, size, format, value); ++} ++ ++static int rc_format_insert_commas(int chars, char* buffer, size_t size) ++{ ++ int to_insert; ++ char* src = buffer; ++ char* ptr; ++ char* dst = &buffer[chars]; ++ if (chars == 0) ++ return 0; ++ ++ /* ignore leading negative sign */ ++ if (*src == '-') ++ src++; ++ ++ /* determine how many digits are present in the leading number */ ++ ptr = src; ++ while (ptr < dst && isdigit((int)*ptr)) ++ ++ptr; ++ ++ /* determine how many commas are needed */ ++ to_insert = (int)((ptr - src - 1) / 3); ++ if (to_insert == 0) /* no commas needed */ ++ return chars; ++ ++ /* if there's not enough room to insert the commas, leave string as-is, but return wanted space */ ++ chars += to_insert; ++ if (chars >= (int)size) ++ return chars; ++ ++ /* move the trailing part of the string */ ++ memmove(ptr + to_insert, ptr, dst - ptr + 1); ++ ++ /* shift blocks of three digits at a time, inserting commas in front of them */ ++ src = ptr - 1; ++ dst = src + to_insert; ++ while (to_insert > 0) { ++ *dst-- = *src--; ++ *dst-- = *src--; ++ *dst-- = *src--; ++ *dst-- = ','; ++ ++ --to_insert; ++ } ++ ++ return chars; ++} ++ ++int rc_format_typed_value(char* buffer, size_t size, const rc_typed_value_t* value, int format) { ++ int chars; ++ rc_typed_value_t converted_value; ++ ++ memcpy(&converted_value, value, sizeof(converted_value)); ++ ++ switch (format) { ++ default: ++ case RC_FORMAT_VALUE: ++ rc_typed_value_convert(&converted_value, RC_VALUE_TYPE_SIGNED); ++ chars = snprintf(buffer, size, "%d", converted_value.value.i32); ++ break; ++ ++ case RC_FORMAT_FRAMES: ++ /* 60 frames per second = 100 centiseconds / 60 frames; multiply frames by 100 / 60 */ ++ rc_typed_value_convert(&converted_value, RC_VALUE_TYPE_UNSIGNED); ++ chars = rc_format_value_centiseconds(buffer, size, converted_value.value.u32 * 10 / 6); ++ break; ++ ++ case RC_FORMAT_CENTISECS: ++ rc_typed_value_convert(&converted_value, RC_VALUE_TYPE_UNSIGNED); ++ chars = rc_format_value_centiseconds(buffer, size, converted_value.value.u32); ++ break; ++ ++ case RC_FORMAT_SECONDS: ++ rc_typed_value_convert(&converted_value, RC_VALUE_TYPE_UNSIGNED); ++ chars = rc_format_value_seconds(buffer, size, converted_value.value.u32); ++ break; ++ ++ case RC_FORMAT_SECONDS_AS_MINUTES: ++ rc_typed_value_convert(&converted_value, RC_VALUE_TYPE_UNSIGNED); ++ chars = rc_format_value_minutes(buffer, size, converted_value.value.u32 / 60); ++ break; ++ ++ case RC_FORMAT_MINUTES: ++ rc_typed_value_convert(&converted_value, RC_VALUE_TYPE_UNSIGNED); ++ chars = rc_format_value_minutes(buffer, size, converted_value.value.u32); ++ break; ++ ++ case RC_FORMAT_SCORE: ++ rc_typed_value_convert(&converted_value, RC_VALUE_TYPE_SIGNED); ++ return snprintf(buffer, size, "%06d", converted_value.value.i32); ++ ++ case RC_FORMAT_FLOAT1: ++ rc_typed_value_convert(&converted_value, RC_VALUE_TYPE_FLOAT); ++ chars = snprintf(buffer, size, "%.1f", converted_value.value.f32); ++ break; ++ ++ case RC_FORMAT_FLOAT2: ++ rc_typed_value_convert(&converted_value, RC_VALUE_TYPE_FLOAT); ++ chars = snprintf(buffer, size, "%.2f", converted_value.value.f32); ++ break; ++ ++ case RC_FORMAT_FLOAT3: ++ rc_typed_value_convert(&converted_value, RC_VALUE_TYPE_FLOAT); ++ chars = snprintf(buffer, size, "%.3f", converted_value.value.f32); ++ break; ++ ++ case RC_FORMAT_FLOAT4: ++ rc_typed_value_convert(&converted_value, RC_VALUE_TYPE_FLOAT); ++ chars = snprintf(buffer, size, "%.4f", converted_value.value.f32); ++ break; ++ ++ case RC_FORMAT_FLOAT5: ++ rc_typed_value_convert(&converted_value, RC_VALUE_TYPE_FLOAT); ++ chars = snprintf(buffer, size, "%.5f", converted_value.value.f32); ++ break; ++ ++ case RC_FORMAT_FLOAT6: ++ rc_typed_value_convert(&converted_value, RC_VALUE_TYPE_FLOAT); ++ chars = snprintf(buffer, size, "%.6f", converted_value.value.f32); ++ break; ++ ++ case RC_FORMAT_FIXED1: ++ rc_typed_value_convert(&converted_value, RC_VALUE_TYPE_SIGNED); ++ chars = rc_format_value_fixed(buffer, size, "%d.%u", converted_value.value.i32, 10); ++ break; ++ ++ case RC_FORMAT_FIXED2: ++ rc_typed_value_convert(&converted_value, RC_VALUE_TYPE_SIGNED); ++ chars = rc_format_value_fixed(buffer, size, "%d.%02u", converted_value.value.i32, 100); ++ break; ++ ++ case RC_FORMAT_FIXED3: ++ rc_typed_value_convert(&converted_value, RC_VALUE_TYPE_SIGNED); ++ chars = rc_format_value_fixed(buffer, size, "%d.%03u", converted_value.value.i32, 1000); ++ break; ++ ++ case RC_FORMAT_TENS: ++ rc_typed_value_convert(&converted_value, RC_VALUE_TYPE_SIGNED); ++ chars = rc_format_value_padded(buffer, size, "%d0", converted_value.value.i32); ++ break; ++ ++ case RC_FORMAT_HUNDREDS: ++ rc_typed_value_convert(&converted_value, RC_VALUE_TYPE_SIGNED); ++ chars = rc_format_value_padded(buffer, size, "%d00", converted_value.value.i32); ++ break; ++ ++ case RC_FORMAT_THOUSANDS: ++ rc_typed_value_convert(&converted_value, RC_VALUE_TYPE_SIGNED); ++ chars = rc_format_value_padded(buffer, size, "%d000", converted_value.value.i32); ++ break; ++ ++ case RC_FORMAT_UNSIGNED_VALUE: ++ rc_typed_value_convert(&converted_value, RC_VALUE_TYPE_UNSIGNED); ++ chars = snprintf(buffer, size, "%u", converted_value.value.u32); ++ break; ++ ++ case RC_FORMAT_UNFORMATTED: ++ rc_typed_value_convert(&converted_value, RC_VALUE_TYPE_UNSIGNED); ++ return snprintf(buffer, size, "%u", converted_value.value.u32); ++ } ++ ++ return rc_format_insert_commas(chars, buffer, size); ++} ++ ++int rc_format_value(char* buffer, int size, int32_t value, int format) { ++ rc_typed_value_t typed_value; ++ ++ typed_value.value.i32 = value; ++ typed_value.type = RC_VALUE_TYPE_SIGNED; ++ return rc_format_typed_value(buffer, size, &typed_value, format); ++} +diff -rupbN melonDS.orig/src/rcheevos/src/rcheevos/lboard.c melonDS.ra/src/rcheevos/src/rcheevos/lboard.c +--- melonDS.orig/src/rcheevos/src/rcheevos/lboard.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rcheevos/lboard.c 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,287 @@ ++#include "rc_internal.h" ++ ++enum { ++ RC_LBOARD_START = 1 << 0, ++ RC_LBOARD_CANCEL = 1 << 1, ++ RC_LBOARD_SUBMIT = 1 << 2, ++ RC_LBOARD_VALUE = 1 << 3, ++ RC_LBOARD_PROGRESS = 1 << 4, ++ RC_LBOARD_COMPLETE = RC_LBOARD_START | RC_LBOARD_CANCEL | RC_LBOARD_SUBMIT | RC_LBOARD_VALUE ++}; ++ ++void rc_parse_lboard_internal(rc_lboard_t* self, const char* memaddr, rc_parse_state_t* parse) { ++ int found; ++ ++ self->progress = 0; ++ found = 0; ++ ++ for (;;) ++ { ++ if ((memaddr[0] == 's' || memaddr[0] == 'S') && ++ (memaddr[1] == 't' || memaddr[1] == 'T') && ++ (memaddr[2] == 'a' || memaddr[2] == 'A') && memaddr[3] == ':') { ++ if ((found & RC_LBOARD_START) != 0) { ++ parse->offset = RC_DUPLICATED_START; ++ return; ++ } ++ ++ memaddr += 4; ++ if (*memaddr && *memaddr != ':') { ++ found |= RC_LBOARD_START; ++ rc_parse_trigger_internal(&self->start, &memaddr, parse); ++ } ++ } ++ else if ((memaddr[0] == 'c' || memaddr[0] == 'C') && ++ (memaddr[1] == 'a' || memaddr[1] == 'A') && ++ (memaddr[2] == 'n' || memaddr[2] == 'N') && memaddr[3] == ':') { ++ if ((found & RC_LBOARD_CANCEL) != 0) { ++ parse->offset = RC_DUPLICATED_CANCEL; ++ return; ++ } ++ ++ memaddr += 4; ++ if (*memaddr && *memaddr != ':') { ++ found |= RC_LBOARD_CANCEL; ++ rc_parse_trigger_internal(&self->cancel, &memaddr, parse); ++ } ++ } ++ else if ((memaddr[0] == 's' || memaddr[0] == 'S') && ++ (memaddr[1] == 'u' || memaddr[1] == 'U') && ++ (memaddr[2] == 'b' || memaddr[2] == 'B') && memaddr[3] == ':') { ++ if ((found & RC_LBOARD_SUBMIT) != 0) { ++ parse->offset = RC_DUPLICATED_SUBMIT; ++ return; ++ } ++ ++ memaddr += 4; ++ if (*memaddr && *memaddr != ':') { ++ found |= RC_LBOARD_SUBMIT; ++ rc_parse_trigger_internal(&self->submit, &memaddr, parse); ++ } ++ } ++ else if ((memaddr[0] == 'v' || memaddr[0] == 'V') && ++ (memaddr[1] == 'a' || memaddr[1] == 'A') && ++ (memaddr[2] == 'l' || memaddr[2] == 'L') && memaddr[3] == ':') { ++ if ((found & RC_LBOARD_VALUE) != 0) { ++ parse->offset = RC_DUPLICATED_VALUE; ++ return; ++ } ++ ++ memaddr += 4; ++ if (*memaddr && *memaddr != ':') { ++ found |= RC_LBOARD_VALUE; ++ rc_parse_value_internal(&self->value, &memaddr, parse); ++ } ++ } ++ else if ((memaddr[0] == 'p' || memaddr[0] == 'P') && ++ (memaddr[1] == 'r' || memaddr[1] == 'R') && ++ (memaddr[2] == 'o' || memaddr[2] == 'O') && memaddr[3] == ':') { ++ if ((found & RC_LBOARD_PROGRESS) != 0) { ++ parse->offset = RC_DUPLICATED_PROGRESS; ++ return; ++ } ++ ++ memaddr += 4; ++ if (*memaddr && *memaddr != ':') { ++ found |= RC_LBOARD_PROGRESS; ++ ++ self->progress = RC_ALLOC(rc_value_t, parse); ++ rc_parse_value_internal(self->progress, &memaddr, parse); ++ } ++ } ++ ++ /* encountered an error parsing one of the parts */ ++ if (parse->offset < 0) ++ return; ++ ++ /* end of string, or end of quoted string - stop processing */ ++ if (memaddr[0] == '\0' || memaddr[0] == '\"') ++ break; ++ ++ /* expect two colons between fields */ ++ if (memaddr[0] != ':' || memaddr[1] != ':') { ++ parse->offset = RC_INVALID_LBOARD_FIELD; ++ return; ++ } ++ ++ memaddr += 2; ++ } ++ ++ if ((found & RC_LBOARD_COMPLETE) != RC_LBOARD_COMPLETE) { ++ if ((found & RC_LBOARD_START) == 0) { ++ parse->offset = RC_MISSING_START; ++ } ++ else if ((found & RC_LBOARD_CANCEL) == 0) { ++ parse->offset = RC_MISSING_CANCEL; ++ } ++ else if ((found & RC_LBOARD_SUBMIT) == 0) { ++ parse->offset = RC_MISSING_SUBMIT; ++ } ++ else if ((found & RC_LBOARD_VALUE) == 0) { ++ parse->offset = RC_MISSING_VALUE; ++ } ++ ++ return; ++ } ++ ++ self->state = RC_LBOARD_STATE_WAITING; ++ self->has_memrefs = 0; ++} ++ ++int rc_lboard_size(const char* memaddr) { ++ rc_lboard_with_memrefs_t* lboard; ++ rc_preparse_state_t preparse; ++ rc_init_preparse_state(&preparse); ++ ++ lboard = RC_ALLOC(rc_lboard_with_memrefs_t, &preparse.parse); ++ rc_parse_lboard_internal(&lboard->lboard, memaddr, &preparse.parse); ++ rc_preparse_alloc_memrefs(NULL, &preparse); ++ ++ rc_destroy_preparse_state(&preparse); ++ return preparse.parse.offset; ++} ++ ++rc_lboard_t* rc_parse_lboard(void* buffer, const char* memaddr, void* unused_L, int unused_funcs_idx) { ++ rc_lboard_with_memrefs_t* lboard; ++ rc_preparse_state_t preparse; ++ ++ (void)unused_L; ++ (void)unused_funcs_idx; ++ ++ if (!buffer || !memaddr) ++ return 0; ++ ++ rc_init_preparse_state(&preparse); ++ lboard = RC_ALLOC(rc_lboard_with_memrefs_t, &preparse.parse); ++ rc_parse_lboard_internal(&lboard->lboard, memaddr, &preparse.parse); ++ ++ rc_reset_parse_state(&preparse.parse, buffer); ++ lboard = RC_ALLOC(rc_lboard_with_memrefs_t, &preparse.parse); ++ rc_preparse_alloc_memrefs(&lboard->memrefs, &preparse); ++ ++ rc_parse_lboard_internal(&lboard->lboard, memaddr, &preparse.parse); ++ lboard->lboard.has_memrefs = 1; ++ ++ rc_destroy_preparse_state(&preparse); ++ return (preparse.parse.offset >= 0) ? &lboard->lboard : NULL; ++} ++ ++static void rc_update_lboard_memrefs(rc_lboard_t* self, rc_peek_t peek, void* ud) { ++ if (self->has_memrefs) { ++ rc_lboard_with_memrefs_t* lboard = (rc_lboard_with_memrefs_t*)self; ++ rc_update_memref_values(&lboard->memrefs, peek, ud); ++ } ++} ++ ++int rc_evaluate_lboard(rc_lboard_t* self, int32_t* value, rc_peek_t peek, void* peek_ud, void* unused_L) { ++ int start_ok, cancel_ok, submit_ok; ++ ++ rc_update_lboard_memrefs(self, peek, peek_ud); ++ ++ if (self->state == RC_LBOARD_STATE_INACTIVE || self->state == RC_LBOARD_STATE_DISABLED) ++ return RC_LBOARD_STATE_INACTIVE; ++ ++ /* these are always tested once every frame, to ensure hit counts work properly */ ++ start_ok = rc_test_trigger(&self->start, peek, peek_ud, unused_L); ++ cancel_ok = rc_test_trigger(&self->cancel, peek, peek_ud, unused_L); ++ submit_ok = rc_test_trigger(&self->submit, peek, peek_ud, unused_L); ++ ++ switch (self->state) ++ { ++ case RC_LBOARD_STATE_WAITING: ++ case RC_LBOARD_STATE_TRIGGERED: ++ case RC_LBOARD_STATE_CANCELED: ++ /* don't activate/reactivate until the start condition becomes false */ ++ if (start_ok) { ++ *value = 0; ++ return RC_LBOARD_STATE_INACTIVE; /* just return inactive for all of these */ ++ } ++ ++ /* start condition is false, allow the leaderboard to start on future frames */ ++ self->state = RC_LBOARD_STATE_ACTIVE; ++ break; ++ ++ case RC_LBOARD_STATE_ACTIVE: ++ /* leaderboard attempt is not in progress. if the start condition is true and the cancel condition is not, start the attempt */ ++ if (start_ok && !cancel_ok) { ++ if (submit_ok) { ++ /* start and submit are both true in the same frame, just submit without announcing the leaderboard is available */ ++ self->state = RC_LBOARD_STATE_TRIGGERED; ++ } ++ else if (!self->start.requirement && !self->start.alternative) { ++ /* start trigger is empty. assume the leaderboard is in development and ignore */ ++ } ++ else { ++ /* start the leaderboard attempt */ ++ self->state = RC_LBOARD_STATE_STARTED; ++ } ++ ++ /* reset any hit counts in the value */ ++ if (self->progress) ++ rc_reset_value(self->progress); ++ ++ rc_reset_value(&self->value); ++ } ++ break; ++ ++ case RC_LBOARD_STATE_STARTED: ++ /* leaderboard attempt in progress */ ++ if (cancel_ok) { ++ /* cancel condition is true, abort the attempt */ ++ self->state = RC_LBOARD_STATE_CANCELED; ++ } ++ else if (submit_ok) { ++ /* submit condition is true, submit the current value */ ++ self->state = RC_LBOARD_STATE_TRIGGERED; ++ } ++ break; ++ } ++ ++ /* Calculate the value */ ++ switch (self->state) { ++ case RC_LBOARD_STATE_STARTED: ++ if (self->progress) { ++ *value = rc_evaluate_value(self->progress, peek, peek_ud, unused_L); ++ break; ++ } ++ /* fallthrough */ /* to RC_LBOARD_STATE_TRIGGERED */ ++ ++ case RC_LBOARD_STATE_TRIGGERED: ++ *value = rc_evaluate_value(&self->value, peek, peek_ud, unused_L); ++ break; ++ ++ default: ++ *value = 0; ++ break; ++ } ++ ++ return self->state; ++} ++ ++int rc_lboard_state_active(int state) { ++ switch (state) ++ { ++ case RC_LBOARD_STATE_DISABLED: ++ case RC_LBOARD_STATE_INACTIVE: ++ return 0; ++ ++ default: ++ return 1; ++ } ++} ++ ++void rc_reset_lboard(rc_lboard_t* self) { ++ if (!self) ++ return; ++ ++ self->state = RC_LBOARD_STATE_WAITING; ++ ++ rc_reset_trigger(&self->start); ++ rc_reset_trigger(&self->submit); ++ rc_reset_trigger(&self->cancel); ++ ++ if (self->progress) ++ rc_reset_value(self->progress); ++ ++ rc_reset_value(&self->value); ++} +diff -rupbN melonDS.orig/src/rcheevos/src/rcheevos/memref.c melonDS.ra/src/rcheevos/src/rcheevos/memref.c +--- melonDS.orig/src/rcheevos/src/rcheevos/memref.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rcheevos/memref.c 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,805 @@ ++#include "rc_internal.h" ++ ++#include /* malloc/realloc */ ++#include /* memcpy */ ++#include /* INFINITY/NAN */ ++ ++#define MEMREF_PLACEHOLDER_ADDRESS 0xFFFFFFFF ++ ++rc_memref_t* rc_alloc_memref(rc_parse_state_t* parse, uint32_t address, uint8_t size) { ++ rc_memref_list_t* memref_list = NULL; ++ rc_memref_t* memref = NULL; ++ int i; ++ ++ for (i = 0; i < 2; i++) { ++ if (i == 0) { ++ if (!parse->existing_memrefs) ++ continue; ++ ++ memref_list = &parse->existing_memrefs->memrefs; ++ } ++ else { ++ memref_list = &parse->memrefs->memrefs; ++ } ++ ++ do ++ { ++ const rc_memref_t* memref_stop; ++ ++ memref = memref_list->items; ++ memref_stop = memref + memref_list->count; ++ ++ for (; memref < memref_stop; ++memref) { ++ if (memref->address == address && memref->value.size == size) ++ return memref; ++ } ++ ++ if (!memref_list->next) ++ break; ++ ++ memref_list = memref_list->next; ++ } while (1); ++ } ++ ++ /* no match found, find a place to put the new entry */ ++ memref_list = &parse->memrefs->memrefs; ++ while (memref_list->count == memref_list->capacity && memref_list->next) ++ memref_list = memref_list->next; ++ ++ /* create a new entry */ ++ if (memref_list->count < memref_list->capacity) { ++ memref = &memref_list->items[memref_list->count++]; ++ } else { ++ const int32_t old_offset = parse->offset; ++ ++ if (memref_list->capacity != 0) { ++ memref_list = memref_list->next = RC_ALLOC_SCRATCH(rc_memref_list_t, parse); ++ memref_list->next = NULL; ++ } ++ ++ memref_list->items = RC_ALLOC_ARRAY_SCRATCH(rc_memref_t, 8, parse); ++ memref_list->count = 1; ++ memref_list->capacity = 8; ++ memref_list->allocated = 0; ++ ++ memref = memref_list->items; ++ ++ /* in preparse mode, don't count this memory, we'll do a single allocation once we have ++ * the final total */ ++ if (!parse->buffer) ++ parse->offset = old_offset; ++ } ++ ++ memset(memref, 0, sizeof(*memref)); ++ memref->value.memref_type = RC_MEMREF_TYPE_MEMREF; ++ memref->value.type = RC_VALUE_TYPE_UNSIGNED; ++ memref->value.size = size; ++ memref->address = address; ++ ++ return memref; ++} ++ ++rc_modified_memref_t* rc_alloc_modified_memref(rc_parse_state_t* parse, uint8_t size, const rc_operand_t* parent, ++ uint8_t modifier_type, const rc_operand_t* modifier) { ++ rc_modified_memref_list_t* modified_memref_list = NULL; ++ rc_modified_memref_t* modified_memref = NULL; ++ int i = 0; ++ ++ for (i = 0; i < 2; i++) { ++ if (i == 0) { ++ if (!parse->existing_memrefs) ++ continue; ++ ++ modified_memref_list = &parse->existing_memrefs->modified_memrefs; ++ } ++ else { ++ modified_memref_list = &parse->memrefs->modified_memrefs; ++ } ++ ++ do { ++ const rc_modified_memref_t* memref_stop; ++ ++ modified_memref = modified_memref_list->items; ++ memref_stop = modified_memref + modified_memref_list->count; ++ ++ for (; modified_memref < memref_stop; ++modified_memref) { ++ if (modified_memref->memref.value.size == size && ++ modified_memref->modifier_type == modifier_type && ++ rc_operands_are_equal(&modified_memref->parent, parent) && ++ rc_operands_are_equal(&modified_memref->modifier, modifier)) { ++ return modified_memref; ++ } ++ } ++ ++ if (!modified_memref_list->next) ++ break; ++ ++ modified_memref_list = modified_memref_list->next; ++ } while (1); ++ } ++ ++ /* no match found, find a place to put the new entry */ ++ modified_memref_list = &parse->memrefs->modified_memrefs; ++ while (modified_memref_list->count == modified_memref_list->capacity && modified_memref_list->next) ++ modified_memref_list = modified_memref_list->next; ++ ++ /* create a new entry */ ++ if (modified_memref_list->count < modified_memref_list->capacity) { ++ modified_memref = &modified_memref_list->items[modified_memref_list->count++]; ++ } else { ++ const int32_t old_offset = parse->offset; ++ ++ if (modified_memref_list->capacity != 0) { ++ modified_memref_list = modified_memref_list->next = RC_ALLOC_SCRATCH(rc_modified_memref_list_t, parse); ++ modified_memref_list->next = NULL; ++ } ++ ++ modified_memref_list->items = RC_ALLOC_ARRAY_SCRATCH(rc_modified_memref_t, 8, parse); ++ modified_memref_list->count = 1; ++ modified_memref_list->capacity = 8; ++ modified_memref_list->allocated = 0; ++ ++ modified_memref = modified_memref_list->items; ++ ++ /* in preparse mode, don't count this memory, we'll do a single allocation once we have ++ * the final total */ ++ if (!parse->buffer) ++ parse->offset = old_offset; ++ } ++ ++ memset(modified_memref, 0, sizeof(*modified_memref)); ++ modified_memref->memref.value.memref_type = RC_MEMREF_TYPE_MODIFIED_MEMREF; ++ modified_memref->memref.value.size = size; ++ modified_memref->memref.value.type = rc_memsize_is_float(size) ? RC_VALUE_TYPE_FLOAT : RC_VALUE_TYPE_UNSIGNED; ++ memcpy(&modified_memref->parent, parent, sizeof(modified_memref->parent)); ++ memcpy(&modified_memref->modifier, modifier, sizeof(modified_memref->modifier)); ++ modified_memref->modifier_type = modifier_type; ++ modified_memref->depth = 0; ++ modified_memref->memref.address = rc_operand_is_memref(modifier) ? modifier->value.memref->address : modifier->value.num; ++ ++ if (rc_operand_is_memref(parent) && parent->value.memref->value.memref_type == RC_MEMREF_TYPE_MODIFIED_MEMREF) { ++ const rc_modified_memref_t* parent_modified_memref = (rc_modified_memref_t*)parent->value.memref; ++ modified_memref->depth = parent_modified_memref->depth + 1; ++ } ++ ++ return modified_memref; ++} ++ ++void rc_memrefs_init(rc_memrefs_t* memrefs) ++{ ++ memset(memrefs, 0, sizeof(*memrefs)); ++ ++ memrefs->memrefs.capacity = 32; ++ memrefs->memrefs.items = ++ (rc_memref_t*)malloc(memrefs->memrefs.capacity * sizeof(rc_memref_t)); ++ memrefs->memrefs.allocated = 1; ++ ++ memrefs->modified_memrefs.capacity = 16; ++ memrefs->modified_memrefs.items = ++ (rc_modified_memref_t*)malloc(memrefs->modified_memrefs.capacity * sizeof(rc_modified_memref_t)); ++ memrefs->modified_memrefs.allocated = 1; ++} ++ ++void rc_memrefs_destroy(rc_memrefs_t* memrefs) ++{ ++ rc_memref_list_t* memref_list = &memrefs->memrefs; ++ rc_modified_memref_list_t* modified_memref_list = &memrefs->modified_memrefs; ++ ++ do { ++ rc_memref_list_t* current_memref_list = memref_list; ++ memref_list = memref_list->next; ++ ++ if (current_memref_list->allocated) { ++ if (current_memref_list->items) ++ free(current_memref_list->items); ++ ++ if (current_memref_list != &memrefs->memrefs) ++ free(current_memref_list); ++ } ++ } while (memref_list); ++ ++ do { ++ rc_modified_memref_list_t* current_modified_memref_list = modified_memref_list; ++ modified_memref_list = modified_memref_list->next; ++ ++ if (current_modified_memref_list->allocated) { ++ if (current_modified_memref_list->items) ++ free(current_modified_memref_list->items); ++ ++ if (current_modified_memref_list != &memrefs->modified_memrefs) ++ free(current_modified_memref_list); ++ } ++ } while (modified_memref_list); ++ ++ free(memrefs); ++} ++ ++uint32_t rc_memrefs_count_memrefs(const rc_memrefs_t* memrefs) ++{ ++ uint32_t count = 0; ++ const rc_memref_list_t* memref_list = &memrefs->memrefs; ++ while (memref_list) { ++ count += memref_list->count; ++ memref_list = memref_list->next; ++ } ++ ++ return count; ++} ++ ++uint32_t rc_memrefs_count_modified_memrefs(const rc_memrefs_t* memrefs) ++{ ++ uint32_t count = 0; ++ const rc_modified_memref_list_t* modified_memref_list = &memrefs->modified_memrefs; ++ while (modified_memref_list) { ++ count += modified_memref_list->count; ++ modified_memref_list = modified_memref_list->next; ++ } ++ ++ return count; ++} ++ ++int rc_parse_memref(const char** memaddr, uint8_t* size, uint32_t* address) { ++ const char* aux = *memaddr; ++ char* end; ++ unsigned long value; ++ ++ if (aux[0] == '0') { ++ if (aux[1] != 'x' && aux[1] != 'X') ++ return RC_INVALID_MEMORY_OPERAND; ++ ++ aux += 2; ++ switch (*aux++) { ++ /* ordered by estimated frequency in case compiler doesn't build a jump table */ ++ case 'h': case 'H': *size = RC_MEMSIZE_8_BITS; break; ++ case ' ': *size = RC_MEMSIZE_16_BITS; break; ++ case 'x': case 'X': *size = RC_MEMSIZE_32_BITS; break; ++ ++ case 'm': case 'M': *size = RC_MEMSIZE_BIT_0; break; ++ case 'n': case 'N': *size = RC_MEMSIZE_BIT_1; break; ++ case 'o': case 'O': *size = RC_MEMSIZE_BIT_2; break; ++ case 'p': case 'P': *size = RC_MEMSIZE_BIT_3; break; ++ case 'q': case 'Q': *size = RC_MEMSIZE_BIT_4; break; ++ case 'r': case 'R': *size = RC_MEMSIZE_BIT_5; break; ++ case 's': case 'S': *size = RC_MEMSIZE_BIT_6; break; ++ case 't': case 'T': *size = RC_MEMSIZE_BIT_7; break; ++ case 'l': case 'L': *size = RC_MEMSIZE_LOW; break; ++ case 'u': case 'U': *size = RC_MEMSIZE_HIGH; break; ++ case 'k': case 'K': *size = RC_MEMSIZE_BITCOUNT; break; ++ case 'w': case 'W': *size = RC_MEMSIZE_24_BITS; break; ++ case 'g': case 'G': *size = RC_MEMSIZE_32_BITS_BE; break; ++ case 'i': case 'I': *size = RC_MEMSIZE_16_BITS_BE; break; ++ case 'j': case 'J': *size = RC_MEMSIZE_24_BITS_BE; break; ++ ++ /* case 'v': case 'V': */ ++ /* case 'y': case 'Y': 64 bit? */ ++ /* case 'z': case 'Z': 128 bit? */ ++ ++ case '0': ++ if (*aux == 'x') /* user mistyped an extra 0x: 0x0xabcd */ ++ return RC_INVALID_MEMORY_OPERAND; ++ /* fallthrough */ ++ ++ case '1': case '2': case '3': case '4': ++ case '5': case '6': case '7': case '8': case '9': ++ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': ++ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': ++ /* legacy support - addresses without a size prefix are assumed to be 16-bit */ ++ aux--; ++ *size = RC_MEMSIZE_16_BITS; ++ break; ++ ++ default: ++ return RC_INVALID_MEMORY_OPERAND; ++ } ++ } ++ else if (aux[0] == 'f' || aux[0] == 'F') { ++ ++aux; ++ switch (*aux++) { ++ case 'f': case 'F': *size = RC_MEMSIZE_FLOAT; break; ++ case 'b': case 'B': *size = RC_MEMSIZE_FLOAT_BE; break; ++ case 'h': case 'H': *size = RC_MEMSIZE_DOUBLE32; break; ++ case 'i': case 'I': *size = RC_MEMSIZE_DOUBLE32_BE; break; ++ case 'm': case 'M': *size = RC_MEMSIZE_MBF32; break; ++ case 'l': case 'L': *size = RC_MEMSIZE_MBF32_LE; break; ++ ++ default: ++ return RC_INVALID_FP_OPERAND; ++ } ++ } ++ else { ++ return RC_INVALID_MEMORY_OPERAND; ++ } ++ ++ value = strtoul(aux, &end, 16); ++ ++ if (end == aux) ++ return RC_INVALID_MEMORY_OPERAND; ++ ++ if (value > 0xffffffffU) ++ value = 0xffffffffU; ++ ++ *address = (uint32_t)value; ++ *memaddr = end; ++ return RC_OK; ++} ++ ++static float rc_build_float(uint32_t mantissa_bits, int32_t exponent, int sign) { ++ /* 32-bit float has a 23-bit mantissa and 8-bit exponent */ ++ const uint32_t implied_bit = 1 << 23; ++ const uint32_t mantissa = mantissa_bits | implied_bit; ++ double dbl = ((double)mantissa) / ((double)implied_bit); ++ ++ if (exponent > 127) { ++ /* exponent above 127 is a special number */ ++ if (mantissa_bits == 0) { ++ /* infinity */ ++#ifdef INFINITY /* INFINITY and NAN #defines require C99 */ ++ dbl = (double)INFINITY; ++#else ++ dbl = -log(0.0); ++#endif ++ } ++ else { ++ /* NaN */ ++#ifdef NAN ++ dbl = NAN; ++#else ++ dbl = -sqrt(-1); ++#endif ++ } ++ } ++ else if (exponent > 0) { ++ /* exponent from 1 to 127 is a number greater than 1 */ ++ while (exponent > 30) { ++ dbl *= (double)(1 << 30); ++ exponent -= 30; ++ } ++ dbl *= (double)((long long)1 << exponent); ++ } ++ else if (exponent < 0) { ++ /* exponent from -1 to -127 is a number less than 1 */ ++ ++ if (exponent == -127) { ++ /* exponent -127 (all exponent bits were zero) is a denormalized value ++ * (no implied leading bit) with exponent -126 */ ++ dbl = ((double)mantissa_bits) / ((double)implied_bit); ++ exponent = 126; ++ } else { ++ exponent = -exponent; ++ } ++ ++ while (exponent > 30) { ++ dbl /= (double)(1 << 30); ++ exponent -= 30; ++ } ++ dbl /= (double)((long long)1 << exponent); ++ } ++ else { ++ /* exponent of 0 requires no adjustment */ ++ } ++ ++ return (sign) ? (float)-dbl : (float)dbl; ++} ++ ++static void rc_transform_memref_float(rc_typed_value_t* value) { ++ /* decodes an IEEE 754 float */ ++ const uint32_t mantissa = (value->value.u32 & 0x7FFFFF); ++ const int32_t exponent = (int32_t)((value->value.u32 >> 23) & 0xFF) - 127; ++ const int sign = (value->value.u32 & 0x80000000); ++ value->value.f32 = rc_build_float(mantissa, exponent, sign); ++ value->type = RC_VALUE_TYPE_FLOAT; ++} ++ ++static void rc_transform_memref_float_be(rc_typed_value_t* value) { ++ /* decodes an IEEE 754 float in big endian format */ ++ const uint32_t mantissa = ((value->value.u32 & 0xFF000000) >> 24) | ++ ((value->value.u32 & 0x00FF0000) >> 8) | ++ ((value->value.u32 & 0x00007F00) << 8); ++ const int32_t exponent = (int32_t)(((value->value.u32 & 0x0000007F) << 1) | ++ ((value->value.u32 & 0x00008000) >> 15)) - 127; ++ const int sign = (value->value.u32 & 0x00000080); ++ value->value.f32 = rc_build_float(mantissa, exponent, sign); ++ value->type = RC_VALUE_TYPE_FLOAT; ++} ++ ++static void rc_transform_memref_double32(rc_typed_value_t* value) ++{ ++ /* decodes the four most significant bytes of an IEEE 754 double into a float */ ++ const uint32_t mantissa = (value->value.u32 & 0x000FFFFF) << 3; ++ const int32_t exponent = (int32_t)((value->value.u32 >> 20) & 0x7FF) - 1023; ++ const int sign = (value->value.u32 & 0x80000000); ++ value->value.f32 = rc_build_float(mantissa, exponent, sign); ++ value->type = RC_VALUE_TYPE_FLOAT; ++} ++ ++static void rc_transform_memref_double32_be(rc_typed_value_t* value) ++{ ++ /* decodes the four most significant bytes of an IEEE 754 double in big endian format into a float */ ++ const uint32_t mantissa = (((value->value.u32 & 0xFF000000) >> 24) | ++ ((value->value.u32 & 0x00FF0000) >> 8) | ++ ((value->value.u32 & 0x00000F00) << 8)) << 3; ++ const int32_t exponent = (int32_t)(((value->value.u32 & 0x0000007F) << 4) | ++ ((value->value.u32 & 0x0000F000) >> 12)) - 1023; ++ const int sign = (value->value.u32 & 0x00000080); ++ value->value.f32 = rc_build_float(mantissa, exponent, sign); ++ value->type = RC_VALUE_TYPE_FLOAT; ++} ++ ++static void rc_transform_memref_mbf32(rc_typed_value_t* value) { ++ /* decodes a Microsoft Binary Format float */ ++ /* NOTE: 32-bit MBF is stored in memory as big endian (at least for Apple II) */ ++ const uint32_t mantissa = ((value->value.u32 & 0xFF000000) >> 24) | ++ ((value->value.u32 & 0x00FF0000) >> 8) | ++ ((value->value.u32 & 0x00007F00) << 8); ++ const int32_t exponent = (int32_t)(value->value.u32 & 0xFF) - 129; ++ const int sign = (value->value.u32 & 0x00008000); ++ ++ if (mantissa == 0 && exponent == -129) ++ value->value.f32 = (sign) ? -0.0f : 0.0f; ++ else ++ value->value.f32 = rc_build_float(mantissa, exponent, sign); ++ ++ value->type = RC_VALUE_TYPE_FLOAT; ++} ++ ++static void rc_transform_memref_mbf32_le(rc_typed_value_t* value) { ++ /* decodes a Microsoft Binary Format float */ ++ /* Locomotive BASIC (CPC) uses MBF40, but in little endian format */ ++ const uint32_t mantissa = value->value.u32 & 0x007FFFFF; ++ const int32_t exponent = (int32_t)(value->value.u32 >> 24) - 129; ++ const int sign = (value->value.u32 & 0x00800000); ++ ++ if (mantissa == 0 && exponent == -129) ++ value->value.f32 = (sign) ? -0.0f : 0.0f; ++ else ++ value->value.f32 = rc_build_float(mantissa, exponent, sign); ++ ++ value->type = RC_VALUE_TYPE_FLOAT; ++} ++ ++static const uint8_t rc_bits_set[16] = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 }; ++ ++void rc_transform_memref_value(rc_typed_value_t* value, uint8_t size) { ++ /* ASSERT: value->type == RC_VALUE_TYPE_UNSIGNED */ ++ switch (size) ++ { ++ case RC_MEMSIZE_8_BITS: ++ value->value.u32 = (value->value.u32 & 0x000000ff); ++ break; ++ ++ case RC_MEMSIZE_16_BITS: ++ value->value.u32 = (value->value.u32 & 0x0000ffff); ++ break; ++ ++ case RC_MEMSIZE_24_BITS: ++ value->value.u32 = (value->value.u32 & 0x00ffffff); ++ break; ++ ++ case RC_MEMSIZE_32_BITS: ++ break; ++ ++ case RC_MEMSIZE_BIT_0: ++ value->value.u32 = (value->value.u32 >> 0) & 1; ++ break; ++ ++ case RC_MEMSIZE_BIT_1: ++ value->value.u32 = (value->value.u32 >> 1) & 1; ++ break; ++ ++ case RC_MEMSIZE_BIT_2: ++ value->value.u32 = (value->value.u32 >> 2) & 1; ++ break; ++ ++ case RC_MEMSIZE_BIT_3: ++ value->value.u32 = (value->value.u32 >> 3) & 1; ++ break; ++ ++ case RC_MEMSIZE_BIT_4: ++ value->value.u32 = (value->value.u32 >> 4) & 1; ++ break; ++ ++ case RC_MEMSIZE_BIT_5: ++ value->value.u32 = (value->value.u32 >> 5) & 1; ++ break; ++ ++ case RC_MEMSIZE_BIT_6: ++ value->value.u32 = (value->value.u32 >> 6) & 1; ++ break; ++ ++ case RC_MEMSIZE_BIT_7: ++ value->value.u32 = (value->value.u32 >> 7) & 1; ++ break; ++ ++ case RC_MEMSIZE_LOW: ++ value->value.u32 = value->value.u32 & 0x0f; ++ break; ++ ++ case RC_MEMSIZE_HIGH: ++ value->value.u32 = (value->value.u32 >> 4) & 0x0f; ++ break; ++ ++ case RC_MEMSIZE_BITCOUNT: ++ value->value.u32 = rc_bits_set[(value->value.u32 & 0x0F)] ++ + rc_bits_set[((value->value.u32 >> 4) & 0x0F)]; ++ break; ++ ++ case RC_MEMSIZE_16_BITS_BE: ++ value->value.u32 = ((value->value.u32 & 0xFF00) >> 8) | ++ ((value->value.u32 & 0x00FF) << 8); ++ break; ++ ++ case RC_MEMSIZE_24_BITS_BE: ++ value->value.u32 = ((value->value.u32 & 0xFF0000) >> 16) | ++ (value->value.u32 & 0x00FF00) | ++ ((value->value.u32 & 0x0000FF) << 16); ++ break; ++ ++ case RC_MEMSIZE_32_BITS_BE: ++ value->value.u32 = ((value->value.u32 & 0xFF000000) >> 24) | ++ ((value->value.u32 & 0x00FF0000) >> 8) | ++ ((value->value.u32 & 0x0000FF00) << 8) | ++ ((value->value.u32 & 0x000000FF) << 24); ++ break; ++ ++ case RC_MEMSIZE_FLOAT: ++ rc_transform_memref_float(value); ++ break; ++ ++ case RC_MEMSIZE_FLOAT_BE: ++ rc_transform_memref_float_be(value); ++ break; ++ ++ case RC_MEMSIZE_DOUBLE32: ++ rc_transform_memref_double32(value); ++ break; ++ ++ case RC_MEMSIZE_DOUBLE32_BE: ++ rc_transform_memref_double32_be(value); ++ break; ++ ++ case RC_MEMSIZE_MBF32: ++ rc_transform_memref_mbf32(value); ++ break; ++ ++ case RC_MEMSIZE_MBF32_LE: ++ rc_transform_memref_mbf32_le(value); ++ break; ++ ++ default: ++ break; ++ } ++} ++ ++static const uint32_t rc_memref_masks[] = { ++ 0x000000ff, /* RC_MEMSIZE_8_BITS */ ++ 0x0000ffff, /* RC_MEMSIZE_16_BITS */ ++ 0x00ffffff, /* RC_MEMSIZE_24_BITS */ ++ 0xffffffff, /* RC_MEMSIZE_32_BITS */ ++ 0x0000000f, /* RC_MEMSIZE_LOW */ ++ 0x000000f0, /* RC_MEMSIZE_HIGH */ ++ 0x00000001, /* RC_MEMSIZE_BIT_0 */ ++ 0x00000002, /* RC_MEMSIZE_BIT_1 */ ++ 0x00000004, /* RC_MEMSIZE_BIT_2 */ ++ 0x00000008, /* RC_MEMSIZE_BIT_3 */ ++ 0x00000010, /* RC_MEMSIZE_BIT_4 */ ++ 0x00000020, /* RC_MEMSIZE_BIT_5 */ ++ 0x00000040, /* RC_MEMSIZE_BIT_6 */ ++ 0x00000080, /* RC_MEMSIZE_BIT_7 */ ++ 0x000000ff, /* RC_MEMSIZE_BITCOUNT */ ++ 0x0000ffff, /* RC_MEMSIZE_16_BITS_BE */ ++ 0x00ffffff, /* RC_MEMSIZE_24_BITS_BE */ ++ 0xffffffff, /* RC_MEMSIZE_32_BITS_BE */ ++ 0xffffffff, /* RC_MEMSIZE_FLOAT */ ++ 0xffffffff, /* RC_MEMSIZE_MBF32 */ ++ 0xffffffff, /* RC_MEMSIZE_MBF32_LE */ ++ 0xffffffff, /* RC_MEMSIZE_FLOAT_BE */ ++ 0xffffffff, /* RC_MEMSIZE_DOUBLE32 */ ++ 0xffffffff, /* RC_MEMSIZE_DOUBLE32_BE*/ ++ 0xffffffff /* RC_MEMSIZE_VARIABLE */ ++}; ++ ++uint32_t rc_memref_mask(uint8_t size) { ++ const size_t index = (size_t)size; ++ if (index >= sizeof(rc_memref_masks) / sizeof(rc_memref_masks[0])) ++ return 0xffffffff; ++ ++ return rc_memref_masks[index]; ++} ++ ++/* all sizes less than 8-bits (1 byte) are mapped to 8-bits. 24-bit is mapped to 32-bit ++ * as we don't expect the client to understand a request for 3 bytes. all other reads are ++ * mapped to the little-endian read of the same size. */ ++static const uint8_t rc_memref_shared_sizes[] = { ++ RC_MEMSIZE_8_BITS, /* RC_MEMSIZE_8_BITS */ ++ RC_MEMSIZE_16_BITS, /* RC_MEMSIZE_16_BITS */ ++ RC_MEMSIZE_32_BITS, /* RC_MEMSIZE_24_BITS */ ++ RC_MEMSIZE_32_BITS, /* RC_MEMSIZE_32_BITS */ ++ RC_MEMSIZE_8_BITS, /* RC_MEMSIZE_LOW */ ++ RC_MEMSIZE_8_BITS, /* RC_MEMSIZE_HIGH */ ++ RC_MEMSIZE_8_BITS, /* RC_MEMSIZE_BIT_0 */ ++ RC_MEMSIZE_8_BITS, /* RC_MEMSIZE_BIT_1 */ ++ RC_MEMSIZE_8_BITS, /* RC_MEMSIZE_BIT_2 */ ++ RC_MEMSIZE_8_BITS, /* RC_MEMSIZE_BIT_3 */ ++ RC_MEMSIZE_8_BITS, /* RC_MEMSIZE_BIT_4 */ ++ RC_MEMSIZE_8_BITS, /* RC_MEMSIZE_BIT_5 */ ++ RC_MEMSIZE_8_BITS, /* RC_MEMSIZE_BIT_6 */ ++ RC_MEMSIZE_8_BITS, /* RC_MEMSIZE_BIT_7 */ ++ RC_MEMSIZE_8_BITS, /* RC_MEMSIZE_BITCOUNT */ ++ RC_MEMSIZE_16_BITS, /* RC_MEMSIZE_16_BITS_BE */ ++ RC_MEMSIZE_32_BITS, /* RC_MEMSIZE_24_BITS_BE */ ++ RC_MEMSIZE_32_BITS, /* RC_MEMSIZE_32_BITS_BE */ ++ RC_MEMSIZE_32_BITS, /* RC_MEMSIZE_FLOAT */ ++ RC_MEMSIZE_32_BITS, /* RC_MEMSIZE_MBF32 */ ++ RC_MEMSIZE_32_BITS, /* RC_MEMSIZE_MBF32_LE */ ++ RC_MEMSIZE_32_BITS, /* RC_MEMSIZE_FLOAT_BE */ ++ RC_MEMSIZE_32_BITS, /* RC_MEMSIZE_DOUBLE32 */ ++ RC_MEMSIZE_32_BITS, /* RC_MEMSIZE_DOUBLE32_BE*/ ++ RC_MEMSIZE_32_BITS /* RC_MEMSIZE_VARIABLE */ ++}; ++ ++uint8_t rc_memref_shared_size(uint8_t size) { ++ const size_t index = (size_t)size; ++ if (index >= sizeof(rc_memref_shared_sizes) / sizeof(rc_memref_shared_sizes[0])) ++ return size; ++ ++ return rc_memref_shared_sizes[index]; ++} ++ ++uint32_t rc_peek_value(uint32_t address, uint8_t size, rc_peek_t peek, void* ud) { ++ if (!peek) ++ return 0; ++ ++ switch (size) ++ { ++ case RC_MEMSIZE_8_BITS: ++ return peek(address, 1, ud); ++ ++ case RC_MEMSIZE_16_BITS: ++ return peek(address, 2, ud); ++ ++ case RC_MEMSIZE_32_BITS: ++ return peek(address, 4, ud); ++ ++ default: ++ { ++ uint32_t value; ++ const size_t index = (size_t)size; ++ if (index >= sizeof(rc_memref_shared_sizes) / sizeof(rc_memref_shared_sizes[0])) ++ return 0; ++ ++ /* fetch the larger value and mask off the bits associated to the specified size ++ * for correct deduction of prior value. non-prior memrefs should already be using ++ * shared size memrefs to minimize the total number of memory reads required. */ ++ value = rc_peek_value(address, rc_memref_shared_sizes[index], peek, ud); ++ return value & rc_memref_masks[index]; ++ } ++ } ++} ++ ++void rc_update_memref_value(rc_memref_value_t* memref, uint32_t new_value) { ++ if (memref->value == new_value) { ++ memref->changed = 0; ++ } ++ else { ++ memref->prior = memref->value; ++ memref->value = new_value; ++ memref->changed = 1; ++ } ++} ++ ++void rc_init_parse_state_memrefs(rc_parse_state_t* parse, rc_memrefs_t* memrefs) ++{ ++ if (memrefs) ++ memset(memrefs, 0, sizeof(*memrefs)); ++ ++ parse->memrefs = memrefs; ++} ++ ++static uint32_t rc_get_memref_value_value(const rc_memref_value_t* memref, int operand_type) { ++ switch (operand_type) ++ { ++ /* most common case explicitly first, even though it could be handled by default case. ++ * this helps the compiler to optimize if it turns the switch into a series of if/elses */ ++ case RC_OPERAND_ADDRESS: ++ return memref->value; ++ ++ case RC_OPERAND_DELTA: ++ if (!memref->changed) { ++ /* fallthrough */ ++ default: ++ return memref->value; ++ } ++ /* fallthrough */ ++ case RC_OPERAND_PRIOR: ++ return memref->prior; ++ } ++} ++ ++void rc_get_memref_value(rc_typed_value_t* value, rc_memref_t* memref, int operand_type) { ++ value->type = memref->value.type; ++ value->value.u32 = rc_get_memref_value_value(&memref->value, operand_type); ++} ++ ++uint32_t rc_get_modified_memref_value(const rc_modified_memref_t* memref, rc_peek_t peek, void* ud) { ++ rc_typed_value_t value, modifier; ++ ++ rc_evaluate_operand(&value, &memref->parent, NULL); ++ rc_evaluate_operand(&modifier, &memref->modifier, NULL); ++ ++ switch (memref->modifier_type) { ++ case RC_OPERATOR_INDIRECT_READ: ++ rc_typed_value_add(&value, &modifier); ++ rc_typed_value_convert(&value, RC_VALUE_TYPE_UNSIGNED); ++ value.value.u32 = rc_peek_value(value.value.u32, memref->memref.value.size, peek, ud); ++ value.type = memref->memref.value.type; ++ break; ++ ++ case RC_OPERATOR_SUB_PARENT: ++ /* sub parent is "-parent + modifier" */ ++ rc_typed_value_negate(&value); ++ rc_typed_value_add(&value, &modifier); ++ rc_typed_value_convert(&value, memref->memref.value.type); ++ break; ++ ++ case RC_OPERATOR_SUB_ACCUMULATOR: ++ rc_typed_value_negate(&modifier); ++ /* fallthrough */ /* to case RC_OPERATOR_SUB_ACCUMULATOR */ ++ ++ case RC_OPERATOR_ADD_ACCUMULATOR: ++ /* when modifying the accumulator, force the modifier to match the accumulator ++ * type instead of promoting them both to the less restrictive type. ++ * ++ * 18 - 17.5 will result in an integer. should it be 0 or 1? ++ * ++ * default: float is less restrictive, convert both to float for combine, ++ * then convert to the memref type. ++ * (int)((float)18 - 17.5) -> (int)(0.5) -> 0 ++ * ++ * accumulator is integer: force modifier to be integer before combining ++ * (int)(18 - (int)17.5) -> (int)(18 - 17) -> 1 ++ */ ++ rc_typed_value_convert(&modifier, value.type); ++ rc_typed_value_add(&value, &modifier); ++ rc_typed_value_convert(&value, memref->memref.value.type); ++ break; ++ ++ default: ++ rc_typed_value_combine(&value, &modifier, memref->modifier_type); ++ rc_typed_value_convert(&value, memref->memref.value.type); ++ break; ++ } ++ ++ return value.value.u32; ++} ++ ++void rc_update_memref_values(rc_memrefs_t* memrefs, rc_peek_t peek, void* ud) { ++ rc_memref_list_t* memref_list; ++ rc_modified_memref_list_t* modified_memref_list; ++ ++ memref_list = &memrefs->memrefs; ++ do ++ { ++ rc_memref_t* memref = memref_list->items; ++ const rc_memref_t* memref_stop = memref + memref_list->count; ++ ++ for (; memref < memref_stop; ++memref) { ++ if (memref->value.type != RC_VALUE_TYPE_NONE) ++ rc_update_memref_value(&memref->value, rc_peek_value(memref->address, memref->value.size, peek, ud)); ++ } ++ ++ memref_list = memref_list->next; ++ } while (memref_list); ++ ++ modified_memref_list = &memrefs->modified_memrefs; ++ if (modified_memref_list->count) { ++ do { ++ rc_modified_memref_t* modified_memref = modified_memref_list->items; ++ const rc_modified_memref_t* modified_memref_stop = modified_memref + modified_memref_list->count; ++ ++ for (; modified_memref < modified_memref_stop; ++modified_memref) ++ rc_update_memref_value(&modified_memref->memref.value, rc_get_modified_memref_value(modified_memref, peek, ud)); ++ ++ modified_memref_list = modified_memref_list->next; ++ } while (modified_memref_list); ++ } ++} +diff -rupbN melonDS.orig/src/rcheevos/src/rcheevos/operand.c melonDS.ra/src/rcheevos/src/rcheevos/operand.c +--- melonDS.orig/src/rcheevos/src/rcheevos/operand.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rcheevos/operand.c 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,607 @@ ++#include "rc_internal.h" ++ ++#include ++#include ++#include ++#include ++ ++static int rc_parse_operand_func_call(rc_operand_t* self, const char** memaddr) { ++ const char* aux = *memaddr; ++ ++ if (*aux++ != '@') { ++ return RC_INVALID_FUNC_OPERAND; ++ } ++ ++ if (!isalpha((unsigned char)*aux)) { ++ return RC_INVALID_FUNC_OPERAND; ++ } ++ ++ while (isalnum((unsigned char)*aux) || *aux == '_') { ++ aux++; ++ } ++ ++ self->type = RC_OPERAND_FUNC; ++ self->size = RC_MEMSIZE_32_BITS; ++ self->memref_access_type = RC_OPERAND_ADDRESS; ++ *memaddr = aux; ++ return RC_OK; ++} ++ ++static int rc_parse_operand_variable(rc_operand_t* self, const char** memaddr, rc_parse_state_t* parse) { ++ const char* aux = *memaddr; ++ size_t i; ++ char varName[RC_VALUE_MAX_NAME_LENGTH + 1] = { 0 }; ++ ++ for (i = 0; i < RC_VALUE_MAX_NAME_LENGTH && *aux != '}'; i++) { ++ if (!rc_is_valid_variable_character(*aux, i == 0)) ++ return RC_INVALID_VARIABLE_NAME; ++ ++ varName[i] = *aux++; ++ } ++ ++ if (i == 0) ++ return RC_INVALID_VARIABLE_NAME; ++ ++ if (*aux != '}') ++ return RC_INVALID_VARIABLE_NAME; ++ ++ ++aux; ++ ++ if (strcmp(varName, "recall") == 0) { ++ if (parse->remember.type == RC_OPERAND_NONE) { ++ self->value.memref = NULL; ++ self->size = RC_MEMSIZE_32_BITS; ++ self->memref_access_type = RC_OPERAND_ADDRESS; ++ } ++ else { ++ memcpy(self, &parse->remember, sizeof(*self)); ++ self->is_combining = 0; ++ self->memref_access_type = self->type; ++ } ++ self->type = RC_OPERAND_RECALL; ++ } ++ else { /* process named variable when feature is available.*/ ++ return RC_UNKNOWN_VARIABLE_NAME; ++ } ++ ++ *memaddr = aux; ++ return RC_OK; ++} ++ ++static int rc_parse_operand_memory(rc_operand_t* self, const char** memaddr, rc_parse_state_t* parse) { ++ const char* aux = *memaddr; ++ uint32_t address; ++ uint8_t size; ++ int ret; ++ ++ switch (*aux) { ++ case 'd': case 'D': ++ self->type = RC_OPERAND_DELTA; ++ ++aux; ++ break; ++ ++ case 'p': case 'P': ++ self->type = RC_OPERAND_PRIOR; ++ ++aux; ++ break; ++ ++ case 'b': case 'B': ++ self->type = RC_OPERAND_BCD; ++ ++aux; ++ break; ++ ++ case '~': ++ self->type = RC_OPERAND_INVERTED; ++ ++aux; ++ break; ++ ++ default: ++ self->type = RC_OPERAND_ADDRESS; ++ break; ++ } ++ ++ self->memref_access_type = self->type; ++ ++ ret = rc_parse_memref(&aux, &self->size, &address); ++ if (ret != RC_OK) ++ return ret; ++ ++ size = rc_memref_shared_size(self->size); ++ if (size != self->size && self->type == RC_OPERAND_PRIOR) { ++ /* if the shared size differs from the requested size and it's a prior operation, we ++ * have to check to make sure both sizes use the same mask, or the prior value may be ++ * updated when bits outside the mask are modified, which would make it look like the ++ * current value once the mask is applied. if the mask differs, create a new ++ * non-shared record for tracking the prior data. */ ++ if (rc_memref_mask(size) != rc_memref_mask(self->size)) ++ size = self->size; ++ } ++ ++ if (parse->indirect_parent.type != RC_OPERAND_NONE) { ++ rc_operand_t offset; ++ rc_operand_set_const(&offset, address); ++ ++ self->value.memref = (rc_memref_t*)rc_alloc_modified_memref(parse, ++ size, &parse->indirect_parent, RC_OPERATOR_INDIRECT_READ, &offset); ++ } ++ else { ++ self->value.memref = rc_alloc_memref(parse, address, size); ++ } ++ ++ if (parse->offset < 0) ++ return parse->offset; ++ ++ *memaddr = aux; ++ return RC_OK; ++} ++ ++int rc_parse_operand(rc_operand_t* self, const char** memaddr, rc_parse_state_t* parse) { ++ const char* aux = *memaddr; ++ char* end; ++ int ret; ++ unsigned long value; ++ int negative; ++ int allow_decimal = 0; ++ ++ self->is_combining = 0; ++ ++ switch (*aux) { ++ case 'h': case 'H': /* hex constant */ ++ if (aux[2] == 'x' || aux[2] == 'X') { ++ /* H0x1234 is a typo - either H1234 or 0xH1234 was probably meant */ ++ return RC_INVALID_CONST_OPERAND; ++ } ++ ++ value = strtoul(++aux, &end, 16); ++ if (end == aux) ++ return RC_INVALID_CONST_OPERAND; ++ ++ if (value > 0xffffffffU) ++ value = 0xffffffffU; ++ ++ rc_operand_set_const(self, (unsigned)value); ++ ++ aux = end; ++ break; ++ ++ case 'f': case 'F': /* floating point constant */ ++ if (isalpha((unsigned char)aux[1])) { ++ ret = rc_parse_operand_memory(self, &aux, parse); ++ ++ if (ret < 0) ++ return ret; ++ ++ break; ++ } ++ allow_decimal = 1; ++ /* fall through */ ++ case 'v': case 'V': /* signed integer constant */ ++ ++aux; ++ /* fall through */ ++ case '+': case '-': /* signed integer constant */ ++ negative = 0; ++ if (*aux == '-') { ++ negative = 1; ++ ++aux; ++ } ++ else if (*aux == '+') { ++ ++aux; ++ } ++ ++ value = strtoul(aux, &end, 10); ++ ++ if (*end == '.' && allow_decimal) { ++ /* custom parser for decimal values to ignore locale */ ++ unsigned long shift = 1; ++ unsigned long fraction = 0; ++ double dbl_val; ++ ++ aux = end + 1; ++ if (*aux < '0' || *aux > '9') ++ return RC_INVALID_FP_OPERAND; ++ ++ do { ++ /* only keep as many digits as will fit in a 32-bit value to prevent overflow. ++ * float only has around 7 digits of precision anyway. */ ++ if (shift < 1000000000) { ++ fraction *= 10; ++ fraction += (*aux - '0'); ++ shift *= 10; ++ } ++ ++aux; ++ } while (*aux >= '0' && *aux <= '9'); ++ ++ if (fraction != 0) { ++ /* non-zero fractional part, convert to double and merge in integer portion */ ++ const double dbl_fraction = ((double)fraction) / ((double)shift); ++ if (negative) ++ dbl_val = ((double)(-((long)value))) - dbl_fraction; ++ else ++ dbl_val = (double)value + dbl_fraction; ++ } ++ else { ++ /* fractional part is 0, just convert the integer portion */ ++ if (negative) ++ dbl_val = (double)(-((long)value)); ++ else ++ dbl_val = (double)value; ++ } ++ ++ rc_operand_set_float_const(self, dbl_val); ++ } ++ else { ++ /* not a floating point value, make sure something was read and advance the read pointer */ ++ if (end == aux) ++ return allow_decimal ? RC_INVALID_FP_OPERAND : RC_INVALID_CONST_OPERAND; ++ ++ aux = end; ++ ++ if (value > 0x7fffffffU) ++ value = 0x7fffffffU; ++ ++ if (negative) ++ rc_operand_set_const(self, (unsigned)(-((long)value))); ++ else ++ rc_operand_set_const(self, (unsigned)value); ++ } ++ break; ++ case '{': /* variable */ ++ ++aux; ++ ret = rc_parse_operand_variable(self, &aux, parse); ++ if (ret < 0) ++ return ret; ++ ++ break; ++ ++ case '0': ++ if (aux[1] == 'x' || aux[1] == 'X') { /* hex integer constant */ ++ /* fallthrough */ /* to default */ ++ default: ++ ret = rc_parse_operand_memory(self, &aux, parse); ++ ++ if (ret < 0) ++ return ret; ++ ++ break; ++ } ++ /* fallthrough */ /* to case '1' for case '0' where not '0x' */ ++ case '1': case '2': case '3': case '4': case '5': /* unsigned integer constant */ ++ case '6': case '7': case '8': case '9': ++ value = strtoul(aux, &end, 10); ++ if (end == aux) ++ return RC_INVALID_CONST_OPERAND; ++ ++ if (value > 0xffffffffU) ++ value = 0xffffffffU; ++ ++ rc_operand_set_const(self, (unsigned)value); ++ ++ aux = end; ++ break; ++ ++ case '@': ++ ret = rc_parse_operand_func_call(self, &aux); ++ ++ if (ret < 0) ++ return ret; ++ ++ break; ++ } ++ ++ *memaddr = aux; ++ return RC_OK; ++} ++ ++void rc_operand_set_const(rc_operand_t* self, uint32_t value) { ++ self->size = RC_MEMSIZE_32_BITS; ++ self->type = RC_OPERAND_CONST; ++ self->memref_access_type = RC_OPERAND_NONE; ++ self->value.num = value; ++} ++ ++void rc_operand_set_float_const(rc_operand_t* self, double value) { ++ self->size = RC_MEMSIZE_FLOAT; ++ self->type = RC_OPERAND_FP; ++ self->memref_access_type = RC_OPERAND_NONE; ++ self->value.dbl = value; ++} ++ ++int rc_operands_are_equal(const rc_operand_t* left, const rc_operand_t* right) { ++ if (left == right) ++ return 1; ++ ++ if (left->type != right->type) ++ return 0; ++ ++ switch (left->type) { ++ case RC_OPERAND_CONST: ++ return (left->value.num == right->value.num); ++ case RC_OPERAND_FP: ++ return (left->value.dbl == right->value.dbl); ++ case RC_OPERAND_RECALL: ++ return (left->value.memref == right->value.memref); ++ default: ++ break; ++ } ++ ++ /* comparing two memrefs - look for exact matches on type and size */ ++ if (left->size != right->size || left->value.memref->value.memref_type != right->value.memref->value.memref_type) ++ return 0; ++ ++ switch (left->value.memref->value.memref_type) { ++ case RC_MEMREF_TYPE_MODIFIED_MEMREF: ++ { ++ const rc_modified_memref_t* left_memref = (const rc_modified_memref_t*)left->value.memref; ++ const rc_modified_memref_t* right_memref = (const rc_modified_memref_t*)right->value.memref; ++ return (left_memref->modifier_type == right_memref->modifier_type && ++ left_memref->depth == right_memref->depth && ++ rc_operands_are_equal(&left_memref->modifier, &right_memref->modifier) && ++ rc_operands_are_equal(&left_memref->parent, &right_memref->parent) && ++ 1 == 1 ++ ); ++ } ++ ++ default: ++ return (left->value.memref->address == right->value.memref->address && ++ left->value.memref->value.size == right->value.memref->value.size); ++ } ++} ++ ++int rc_operator_is_modifying(int oper) { ++ switch (oper) { ++ case RC_OPERATOR_AND: ++ case RC_OPERATOR_XOR: ++ case RC_OPERATOR_DIV: ++ case RC_OPERATOR_MULT: ++ case RC_OPERATOR_MOD: ++ case RC_OPERATOR_ADD: ++ case RC_OPERATOR_SUB: ++ case RC_OPERATOR_NONE: /* NONE operator implies "* 1" */ ++ return 1; ++ ++ default: ++ return 0; ++ } ++} ++ ++int rc_memsize_is_float(uint8_t size) { ++ switch (size) { ++ case RC_MEMSIZE_FLOAT: ++ case RC_MEMSIZE_FLOAT_BE: ++ case RC_MEMSIZE_DOUBLE32: ++ case RC_MEMSIZE_DOUBLE32_BE: ++ case RC_MEMSIZE_MBF32: ++ case RC_MEMSIZE_MBF32_LE: ++ return 1; ++ ++ default: ++ return 0; ++ } ++} ++ ++int rc_operand_is_float_memref(const rc_operand_t* self) { ++ if (!rc_operand_is_memref(self)) ++ return 0; ++ ++ if (self->value.memref->value.memref_type == RC_MEMREF_TYPE_MODIFIED_MEMREF) { ++ const rc_modified_memref_t* memref = (const rc_modified_memref_t*)self->value.memref; ++ if (memref->modifier_type != RC_OPERATOR_INDIRECT_READ) ++ return rc_memsize_is_float(self->value.memref->value.size); ++ } ++ ++ return rc_memsize_is_float(self->size); ++} ++ ++int rc_operand_type_is_memref(uint8_t type) { ++ switch (type) { ++ case RC_OPERAND_CONST: ++ case RC_OPERAND_FP: ++ case RC_OPERAND_FUNC: ++ case RC_OPERAND_RECALL: ++ return 0; ++ ++ default: ++ return 1; ++ } ++} ++ ++int rc_operand_type_is_transform(uint8_t type) { ++ switch (type) { ++ case RC_OPERAND_BCD: ++ case RC_OPERAND_INVERTED: ++ return 1; ++ ++ default: ++ return 0; ++ } ++} ++ ++int rc_operand_is_memref(const rc_operand_t* self) { ++ return rc_operand_type_is_memref(self->type); ++} ++ ++int rc_operand_is_recall(const rc_operand_t* self) { ++ switch (self->type) { ++ case RC_OPERAND_RECALL: ++ return 1; ++ ++ default: ++ return 0; ++ } ++} ++ ++int rc_operand_is_float(const rc_operand_t* self) { ++ if (self->type == RC_OPERAND_FP) ++ return 1; ++ ++ if (self->type == RC_OPERAND_RECALL) ++ return rc_memsize_is_float(self->size); ++ ++ return rc_operand_is_float_memref(self); ++} ++ ++static uint32_t rc_transform_operand_value(uint32_t value, const rc_operand_t* self) { ++ switch (self->type) ++ { ++ case RC_OPERAND_BCD: ++ switch (self->size) ++ { ++ case RC_MEMSIZE_8_BITS: ++ value = ((value >> 4) & 0x0f) * 10 ++ + ((value ) & 0x0f); ++ break; ++ ++ case RC_MEMSIZE_16_BITS: ++ case RC_MEMSIZE_16_BITS_BE: ++ value = ((value >> 12) & 0x0f) * 1000 ++ + ((value >> 8) & 0x0f) * 100 ++ + ((value >> 4) & 0x0f) * 10 ++ + ((value ) & 0x0f); ++ break; ++ ++ case RC_MEMSIZE_24_BITS: ++ case RC_MEMSIZE_24_BITS_BE: ++ value = ((value >> 20) & 0x0f) * 100000 ++ + ((value >> 16) & 0x0f) * 10000 ++ + ((value >> 12) & 0x0f) * 1000 ++ + ((value >> 8) & 0x0f) * 100 ++ + ((value >> 4) & 0x0f) * 10 ++ + ((value ) & 0x0f); ++ break; ++ ++ case RC_MEMSIZE_32_BITS: ++ case RC_MEMSIZE_32_BITS_BE: ++ case RC_MEMSIZE_VARIABLE: ++ value = ((value >> 28) & 0x0f) * 10000000 ++ + ((value >> 24) & 0x0f) * 1000000 ++ + ((value >> 20) & 0x0f) * 100000 ++ + ((value >> 16) & 0x0f) * 10000 ++ + ((value >> 12) & 0x0f) * 1000 ++ + ((value >> 8) & 0x0f) * 100 ++ + ((value >> 4) & 0x0f) * 10 ++ + ((value ) & 0x0f); ++ break; ++ ++ default: ++ break; ++ } ++ break; ++ ++ case RC_OPERAND_INVERTED: ++ switch (self->size) ++ { ++ case RC_MEMSIZE_LOW: ++ case RC_MEMSIZE_HIGH: ++ value ^= 0x0f; ++ break; ++ ++ case RC_MEMSIZE_8_BITS: ++ value ^= 0xff; ++ break; ++ ++ case RC_MEMSIZE_16_BITS: ++ case RC_MEMSIZE_16_BITS_BE: ++ value ^= 0xffff; ++ break; ++ ++ case RC_MEMSIZE_24_BITS: ++ case RC_MEMSIZE_24_BITS_BE: ++ value ^= 0xffffff; ++ break; ++ ++ case RC_MEMSIZE_32_BITS: ++ case RC_MEMSIZE_32_BITS_BE: ++ case RC_MEMSIZE_VARIABLE: ++ value ^= 0xffffffff; ++ break; ++ ++ default: ++ value ^= 0x01; ++ break; ++ } ++ break; ++ ++ default: ++ break; ++ } ++ ++ return value; ++} ++ ++void rc_operand_addsource(rc_operand_t* self, rc_parse_state_t* parse, uint8_t new_size) { ++ rc_modified_memref_t* modified_memref; ++ ++ if ((self->type == RC_OPERAND_DELTA || self->type == RC_OPERAND_PRIOR) && ++ self->type == parse->addsource_parent.type) { ++ /* if adding prev(x) and prev(y), just add x and y and take the prev of that. ++ * same for adding prior(x) and prior(y). */ ++ rc_operand_t modifier; ++ memcpy(&modifier, self, sizeof(modifier)); ++ modifier.type = parse->addsource_parent.type = RC_OPERAND_ADDRESS; ++ ++ modified_memref = rc_alloc_modified_memref(parse, ++ new_size, &parse->addsource_parent, parse->addsource_oper, &modifier); ++ } ++ else { ++ modified_memref = rc_alloc_modified_memref(parse, ++ new_size, &parse->addsource_parent, parse->addsource_oper, self); ++ ++ /* the modified memref will contain the combination of modified values, take the current value from that */ ++ self->type = self->memref_access_type = RC_OPERAND_ADDRESS; ++ } ++ ++ self->value.memref = (rc_memref_t*)modified_memref; ++ ++ /* result of an AddSource operation is always a 32-bit integer (even if parent or modifier is a float) */ ++ self->size = RC_MEMSIZE_32_BITS; ++} ++ ++void rc_evaluate_operand(rc_typed_value_t* result, const rc_operand_t* self, rc_eval_state_t* eval_state) { ++ /* step 1: read memory */ ++ switch (self->type) { ++ case RC_OPERAND_CONST: ++ result->type = RC_VALUE_TYPE_UNSIGNED; ++ result->value.u32 = self->value.num; ++ return; ++ ++ case RC_OPERAND_FP: ++ result->type = RC_VALUE_TYPE_FLOAT; ++ result->value.f32 = (float)self->value.dbl; ++ return; ++ ++ case RC_OPERAND_FUNC: ++ /* this feature was never actualized */ ++ result->type = RC_VALUE_TYPE_UNSIGNED; ++ result->value.u32 = 0; ++ return; ++ ++ case RC_OPERAND_RECALL: ++ if (!rc_operand_type_is_memref(self->memref_access_type)) { ++ rc_operand_t recall; ++ memcpy(&recall, self, sizeof(recall)); ++ recall.type = self->memref_access_type; ++ rc_evaluate_operand(result, &recall, eval_state); ++ return; ++ } ++ ++ if (!self->value.memref) { ++ result->type = RC_VALUE_TYPE_UNSIGNED; ++ result->value.u32 = 0; ++ return; ++ } ++ ++ rc_get_memref_value(result, self->value.memref, self->memref_access_type); ++ break; ++ ++ default: ++ rc_get_memref_value(result, self->value.memref, self->type); ++ break; ++ } ++ ++ /* step 2: convert read memory to desired format */ ++ rc_transform_memref_value(result, self->size); ++ ++ /* step 3: apply logic (BCD/invert) */ ++ if (result->type == RC_VALUE_TYPE_UNSIGNED) ++ result->value.u32 = rc_transform_operand_value(result->value.u32, self); ++} +diff -rupbN melonDS.orig/src/rcheevos/src/rcheevos/rc_internal.h melonDS.ra/src/rcheevos/src/rcheevos/rc_internal.h +--- melonDS.orig/src/rcheevos/src/rcheevos/rc_internal.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rcheevos/rc_internal.h 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,390 @@ ++#ifndef RC_INTERNAL_H ++#define RC_INTERNAL_H ++ ++#include "rc_runtime_types.h" ++#include "rc_util.h" ++ ++RC_BEGIN_C_DECLS ++ ++typedef struct rc_scratch_string { ++ char* value; ++ struct rc_scratch_string* left; ++ struct rc_scratch_string* right; ++} ++rc_scratch_string_t; ++ ++typedef struct rc_modified_memref_t { ++ rc_memref_t memref; /* For compatibility with rc_operand_t.value.memref */ ++ rc_operand_t parent; /* The parent memref this memref is derived from (type will always be a memref type) */ ++ rc_operand_t modifier; /* The modifier to apply to the parent. */ ++ uint8_t modifier_type; /* How to apply the modifier to the parent. (RC_OPERATOR_*) */ ++ uint16_t depth; /* The number of parents this memref has. */ ++} ++rc_modified_memref_t; ++ ++typedef struct rc_memref_list_t { ++ rc_memref_t* items; ++ struct rc_memref_list_t* next; ++ uint16_t count; ++ uint16_t capacity; ++ uint8_t allocated; ++} rc_memref_list_t; ++ ++typedef struct rc_modified_memref_list_t { ++ rc_modified_memref_t* items; ++ struct rc_modified_memref_list_t* next; ++ uint16_t count; ++ uint16_t capacity; ++ uint8_t allocated; ++} rc_modified_memref_list_t; ++ ++typedef struct rc_memrefs_t { ++ rc_memref_list_t memrefs; ++ rc_modified_memref_list_t modified_memrefs; ++} rc_memrefs_t; ++ ++typedef struct rc_trigger_with_memrefs_t { ++ rc_trigger_t trigger; ++ rc_memrefs_t memrefs; ++} rc_trigger_with_memrefs_t; ++ ++typedef struct rc_lboard_with_memrefs_t { ++ rc_lboard_t lboard; ++ rc_memrefs_t memrefs; ++} rc_lboard_with_memrefs_t; ++ ++typedef struct rc_richpresence_with_memrefs_t { ++ rc_richpresence_t richpresence; ++ rc_memrefs_t memrefs; ++} rc_richpresence_with_memrefs_t; ++ ++typedef struct rc_value_with_memrefs_t { ++ rc_value_t value; ++ rc_memrefs_t memrefs; ++} rc_value_with_memrefs_t; ++ ++/* enum helpers for natvis expansion. Have to use a struct to define the mapping, ++ * and a single field to allow the conditional logic to switch on the value */ ++typedef struct __rc_bool_enum_t { uint8_t value; } __rc_bool_enum_t; ++typedef struct __rc_memsize_enum_t { uint8_t value; } __rc_memsize_enum_t; ++typedef struct __rc_memsize_enum_func_t { uint8_t value; } __rc_memsize_enum_func_t; ++typedef struct __rc_operand_enum_t { uint8_t value; } __rc_operand_enum_t; ++typedef struct __rc_value_type_enum_t { uint8_t value; } __rc_value_type_enum_t; ++typedef struct __rc_memref_type_enum_t { uint8_t value; } __rc_memref_type_enum_t; ++typedef struct __rc_condition_enum_t { uint8_t value; } __rc_condition_enum_t; ++typedef struct __rc_condition_enum_str_t { uint8_t value; } __rc_condition_enum_str_t; ++typedef struct __rc_condset_list_t { rc_condset_t* first_condset; } __rc_condset_list_t; ++typedef struct __rc_operator_enum_t { uint8_t value; } __rc_operator_enum_t; ++typedef struct __rc_operator_enum_str_t { uint8_t value; } __rc_operator_enum_str_t; ++typedef struct __rc_operand_memref_t { rc_operand_t operand; } __rc_operand_memref_t; /* requires &rc_operand_t to be the same as &rc_operand_t.value.memref */ ++typedef struct __rc_value_list_t { rc_value_t* first_value; } __rc_value_list_t; ++typedef struct __rc_trigger_state_enum_t { uint8_t value; } __rc_trigger_state_enum_t; ++typedef struct __rc_lboard_state_enum_t { uint8_t value; } __rc_lboard_state_enum_t; ++typedef struct __rc_richpresence_display_list_t { rc_richpresence_display_t* first_display; } __rc_richpresence_display_list_t; ++typedef struct __rc_richpresence_display_part_list_t { rc_richpresence_display_part_t* display; } __rc_richpresence_display_part_list_t; ++typedef struct __rc_richpresence_lookup_list_t { rc_richpresence_lookup_t* first_lookup; } __rc_richpresence_lookup_list_t; ++typedef struct __rc_format_enum_t { uint8_t value; } __rc_format_enum_t; ++ ++#define RC_ALLOW_ALIGN(T) struct __align_ ## T { uint8_t ch; T t; }; ++ ++RC_ALLOW_ALIGN(rc_condition_t) ++RC_ALLOW_ALIGN(rc_condset_t) ++RC_ALLOW_ALIGN(rc_modified_memref_t) ++RC_ALLOW_ALIGN(rc_lboard_t) ++RC_ALLOW_ALIGN(rc_lboard_with_memrefs_t) ++RC_ALLOW_ALIGN(rc_memref_t) ++RC_ALLOW_ALIGN(rc_memref_list_t) ++RC_ALLOW_ALIGN(rc_memrefs_t) ++RC_ALLOW_ALIGN(rc_modified_memref_list_t) ++RC_ALLOW_ALIGN(rc_operand_t) ++RC_ALLOW_ALIGN(rc_richpresence_t) ++RC_ALLOW_ALIGN(rc_richpresence_display_t) ++RC_ALLOW_ALIGN(rc_richpresence_display_part_t) ++RC_ALLOW_ALIGN(rc_richpresence_lookup_t) ++RC_ALLOW_ALIGN(rc_richpresence_lookup_item_t) ++RC_ALLOW_ALIGN(rc_richpresence_with_memrefs_t) ++RC_ALLOW_ALIGN(rc_scratch_string_t) ++RC_ALLOW_ALIGN(rc_trigger_t) ++RC_ALLOW_ALIGN(rc_trigger_with_memrefs_t) ++RC_ALLOW_ALIGN(rc_value_t) ++RC_ALLOW_ALIGN(rc_value_with_memrefs_t) ++RC_ALLOW_ALIGN(char) ++ ++#define RC_ALIGNOF(T) (sizeof(struct __align_ ## T) - sizeof(T)) ++#define RC_OFFSETOF(o, t) (int)((uint8_t*)&(o.t) - (uint8_t*)&(o)) ++ ++#define RC_ALLOC(t, p) ((t*)rc_alloc((p)->buffer, &(p)->offset, sizeof(t), RC_ALIGNOF(t), &(p)->scratch, RC_OFFSETOF((p)->scratch.objs, __ ## t))) ++#define RC_ALLOC_SCRATCH(t, p) ((t*)rc_alloc_scratch((p)->buffer, &(p)->offset, sizeof(t), RC_ALIGNOF(t), &(p)->scratch, RC_OFFSETOF((p)->scratch.objs, __ ## t))) ++#define RC_ALLOC_ARRAY(t, n, p) ((t*)rc_alloc((p)->buffer, &(p)->offset, (n) * sizeof(t), RC_ALIGNOF(t), &(p)->scratch, RC_OFFSETOF((p)->scratch.objs, __ ## t))) ++#define RC_ALLOC_ARRAY_SCRATCH(t, n, p) ((t*)rc_alloc_scratch((p)->buffer, &(p)->offset, (n) * sizeof(t), RC_ALIGNOF(t), &(p)->scratch, RC_OFFSETOF((p)->scratch.objs, __ ## t))) ++ ++#define RC_ALLOC_WITH_TRAILING(container_type, trailing_type, trailing_field, trailing_count, parse) ((container_type*)rc_alloc(\ ++ (parse)->buffer, &(parse)->offset, \ ++ RC_OFFSETOF((*(container_type*)NULL),trailing_field) + trailing_count * sizeof(trailing_type), \ ++ RC_ALIGNOF(container_type), &(parse)->scratch, 0)) ++#define RC_GET_TRAILING(container_pointer, container_type, trailing_type, trailing_field) (trailing_type*)(&((container_type*)(container_pointer))->trailing_field) ++ ++/* force alignment to 4 bytes on 32-bit systems, or 8 bytes on 64-bit systems */ ++#define RC_ALIGN(n) (((n) + (sizeof(void*)-1)) & ~(sizeof(void*)-1)) ++ ++typedef struct { ++ rc_buffer_t buffer; ++ rc_scratch_string_t* strings; ++ ++ struct objs { ++ rc_condition_t* __rc_condition_t; ++ rc_condset_t* __rc_condset_t; ++ rc_modified_memref_t* __rc_modified_memref_t; ++ rc_lboard_t* __rc_lboard_t; ++ rc_lboard_with_memrefs_t* __rc_lboard_with_memrefs_t; ++ rc_memref_t* __rc_memref_t; ++ rc_memref_list_t* __rc_memref_list_t; ++ rc_memrefs_t* __rc_memrefs_t; ++ rc_modified_memref_list_t* __rc_modified_memref_list_t; ++ rc_operand_t* __rc_operand_t; ++ rc_richpresence_t* __rc_richpresence_t; ++ rc_richpresence_display_t* __rc_richpresence_display_t; ++ rc_richpresence_display_part_t* __rc_richpresence_display_part_t; ++ rc_richpresence_lookup_t* __rc_richpresence_lookup_t; ++ rc_richpresence_lookup_item_t* __rc_richpresence_lookup_item_t; ++ rc_richpresence_with_memrefs_t* __rc_richpresence_with_memrefs_t; ++ rc_scratch_string_t __rc_scratch_string_t; ++ rc_trigger_t* __rc_trigger_t; ++ rc_trigger_with_memrefs_t* __rc_trigger_with_memrefs_t; ++ rc_value_t* __rc_value_t; ++ rc_value_with_memrefs_t* __rc_value_with_memrefs_t; ++ ++ /* these fields aren't actually used by the code, but they force the ++ * virtual enum wrapper types to exist so natvis can use them */ ++ union { ++ __rc_bool_enum_t boolean; ++ __rc_memsize_enum_t memsize; ++ __rc_memsize_enum_func_t memsize_func; ++ __rc_operand_enum_t operand; ++ __rc_value_type_enum_t value_type; ++ __rc_memref_type_enum_t memref_type; ++ __rc_condition_enum_t condition; ++ __rc_condition_enum_str_t condition_str; ++ __rc_condset_list_t condset_list; ++ __rc_operator_enum_t oper; ++ __rc_operator_enum_str_t oper_str; ++ __rc_operand_memref_t operand_memref; ++ __rc_value_list_t value_list; ++ __rc_trigger_state_enum_t trigger_state; ++ __rc_lboard_state_enum_t lboard_state; ++ __rc_richpresence_display_list_t richpresence_display_list; ++ __rc_richpresence_display_part_list_t richpresence_display_part_list; ++ __rc_richpresence_lookup_list_t richpresence_lookup_list; ++ __rc_format_enum_t format; ++ } natvis_extension; ++ } objs; ++} ++rc_scratch_t; ++ ++enum { ++ RC_VALUE_TYPE_NONE, ++ RC_VALUE_TYPE_UNSIGNED, ++ RC_VALUE_TYPE_SIGNED, ++ RC_VALUE_TYPE_FLOAT ++}; ++ ++typedef struct { ++ union { ++ uint32_t u32; ++ int32_t i32; ++ float f32; ++ } value; ++ ++ char type; ++} ++rc_typed_value_t; ++ ++enum { ++ RC_MEMREF_TYPE_MEMREF, /* rc_memref_t */ ++ RC_MEMREF_TYPE_MODIFIED_MEMREF, /* rc_modified_memref_t */ ++ RC_MEMREF_TYPE_VALUE /* rc_value_t */ ++}; ++ ++#define RC_MEASURED_UNKNOWN 0xFFFFFFFF ++#define RC_OPERAND_NONE 0xFF ++ ++typedef struct { ++ /* memory accessors */ ++ rc_peek_t peek; ++ void* peek_userdata; ++ ++ /* processing state */ ++ rc_typed_value_t measured_value; /* captured Measured value */ ++ int32_t add_hits; /* AddHits/SubHits accumulator */ ++ uint8_t is_true; /* true if all conditions are true */ ++ uint8_t is_primed; /* true if all non-Trigger conditions are true */ ++ uint8_t is_paused; /* true if one or more PauseIf conditions is true */ ++ uint8_t can_measure; /* false if the measured value should be ignored */ ++ uint8_t measured_from_hits; /* true if the measured_value came from a condition's hit count */ ++ uint8_t and_next; /* true if the previous condition was AndNext true */ ++ uint8_t or_next; /* true if the previous condition was OrNext true */ ++ uint8_t reset_next; /* true if the previous condition was ResetNextIf true */ ++ uint8_t stop_processing; /* true to abort the processing loop */ ++ ++ /* result state */ ++ uint8_t has_hits; /* true if one of more hit counts is non-zero */ ++ uint8_t was_reset; /* true if one or more ResetIf conditions is true */ ++ uint8_t was_cond_reset; /* true if one or more ResetNextIf conditions is true */ ++ ++ /* control settings */ ++ uint8_t can_short_curcuit; /* allows logic processing to stop as soon as a false condition is encountered */ ++} ++rc_eval_state_t; ++ ++typedef struct { ++ int32_t offset; ++ ++ void* buffer; ++ rc_scratch_t scratch; ++ ++ rc_memrefs_t* memrefs; ++ rc_memrefs_t* existing_memrefs; ++ rc_value_t** variables; ++ ++ uint32_t measured_target; ++ int lines_read; ++ ++ rc_operand_t addsource_parent; ++ rc_operand_t indirect_parent; ++ rc_operand_t remember; ++ uint8_t addsource_oper; ++ ++ uint8_t is_value; ++ uint8_t has_required_hits; ++ uint8_t measured_as_percent; ++ uint8_t ignore_non_parse_errors; ++} ++rc_parse_state_t; ++ ++typedef struct rc_preparse_state_t { ++ rc_parse_state_t parse; ++ rc_memrefs_t memrefs; ++} rc_preparse_state_t; ++ ++void rc_init_parse_state(rc_parse_state_t* parse, void* buffer); ++void rc_init_parse_state_memrefs(rc_parse_state_t* parse, rc_memrefs_t* memrefs); ++void rc_reset_parse_state(rc_parse_state_t* parse, void* buffer); ++void rc_destroy_parse_state(rc_parse_state_t* parse); ++void rc_init_preparse_state(rc_preparse_state_t* preparse); ++void rc_preparse_alloc_memrefs(rc_memrefs_t* memrefs, rc_preparse_state_t* preparse); ++void rc_preparse_reserve_memrefs(rc_preparse_state_t* preparse, rc_memrefs_t* memrefs); ++void rc_preparse_copy_memrefs(rc_parse_state_t* parse, rc_memrefs_t* memrefs); ++void rc_destroy_preparse_state(rc_preparse_state_t *preparse); ++ ++void* rc_alloc(void* pointer, int32_t* offset, uint32_t size, uint32_t alignment, rc_scratch_t* scratch, uint32_t scratch_object_pointer_offset); ++void* rc_alloc_scratch(void* pointer, int32_t* offset, uint32_t size, uint32_t alignment, rc_scratch_t* scratch, uint32_t scratch_object_pointer_offset); ++char* rc_alloc_str(rc_parse_state_t* parse, const char* text, size_t length); ++ ++rc_memref_t* rc_alloc_memref(rc_parse_state_t* parse, uint32_t address, uint8_t size); ++rc_modified_memref_t* rc_alloc_modified_memref(rc_parse_state_t* parse, uint8_t size, const rc_operand_t* parent, ++ uint8_t modifier_type, const rc_operand_t* modifier); ++int rc_parse_memref(const char** memaddr, uint8_t* size, uint32_t* address); ++void rc_update_memref_values(rc_memrefs_t* memrefs, rc_peek_t peek, void* ud); ++void rc_update_memref_value(rc_memref_value_t* memref, uint32_t value); ++void rc_get_memref_value(rc_typed_value_t* value, rc_memref_t* memref, int operand_type); ++uint32_t rc_get_modified_memref_value(const rc_modified_memref_t* memref, rc_peek_t peek, void* ud); ++uint8_t rc_memref_shared_size(uint8_t size); ++uint32_t rc_memref_mask(uint8_t size); ++void rc_transform_memref_value(rc_typed_value_t* value, uint8_t size); ++uint32_t rc_peek_value(uint32_t address, uint8_t size, rc_peek_t peek, void* ud); ++ ++void rc_memrefs_init(rc_memrefs_t* memrefs); ++void rc_memrefs_destroy(rc_memrefs_t* memrefs); ++uint32_t rc_memrefs_count_memrefs(const rc_memrefs_t* memrefs); ++uint32_t rc_memrefs_count_modified_memrefs(const rc_memrefs_t* memrefs); ++ ++void rc_parse_trigger_internal(rc_trigger_t* self, const char** memaddr, rc_parse_state_t* parse); ++int rc_trigger_state_active(int state); ++rc_memrefs_t* rc_trigger_get_memrefs(rc_trigger_t* self); ++ ++typedef struct rc_condset_with_trailing_conditions_t { ++ rc_condset_t condset; ++ rc_condition_t conditions[2]; ++} rc_condset_with_trailing_conditions_t; ++RC_ALLOW_ALIGN(rc_condset_with_trailing_conditions_t) ++ ++rc_condset_t* rc_parse_condset(const char** memaddr, rc_parse_state_t* parse); ++int rc_test_condset(rc_condset_t* self, rc_eval_state_t* eval_state); ++void rc_reset_condset(rc_condset_t* self); ++rc_condition_t* rc_condset_get_conditions(rc_condset_t* self); ++void rc_test_condset_internal(rc_condition_t* condition, uint32_t num_conditions, rc_eval_state_t* eval_state, int can_short_circuit); ++ ++enum { ++ RC_PROCESSING_COMPARE_DEFAULT = 0, ++ RC_PROCESSING_COMPARE_MEMREF_TO_CONST, ++ RC_PROCESSING_COMPARE_MEMREF_TO_DELTA, ++ RC_PROCESSING_COMPARE_MEMREF_TO_MEMREF, ++ RC_PROCESSING_COMPARE_DELTA_TO_MEMREF, ++ RC_PROCESSING_COMPARE_DELTA_TO_CONST, ++ RC_PROCESSING_COMPARE_MEMREF_TO_CONST_TRANSFORMED, ++ RC_PROCESSING_COMPARE_MEMREF_TO_DELTA_TRANSFORMED, ++ RC_PROCESSING_COMPARE_MEMREF_TO_MEMREF_TRANSFORMED, ++ RC_PROCESSING_COMPARE_DELTA_TO_MEMREF_TRANSFORMED, ++ RC_PROCESSING_COMPARE_DELTA_TO_CONST_TRANSFORMED, ++ RC_PROCESSING_COMPARE_ALWAYS_TRUE, ++ RC_PROCESSING_COMPARE_ALWAYS_FALSE ++}; ++ ++rc_condition_t* rc_parse_condition(const char** memaddr, rc_parse_state_t* parse); ++void rc_parse_condition_internal(rc_condition_t* self, const char** memaddr, rc_parse_state_t* parse); ++void rc_condition_update_parse_state(rc_condition_t* condition, rc_parse_state_t* parse); ++int rc_test_condition(rc_condition_t* self, rc_eval_state_t* eval_state); ++void rc_evaluate_condition_value(rc_typed_value_t* value, rc_condition_t* self, rc_eval_state_t* eval_state); ++int rc_condition_is_combining(const rc_condition_t* self); ++void rc_condition_convert_to_operand(const rc_condition_t* condition, rc_operand_t* operand, rc_parse_state_t* parse); ++const rc_operand_t* rc_condition_get_real_operand1(const rc_condition_t* self); ++ ++int rc_parse_operand(rc_operand_t* self, const char** memaddr, rc_parse_state_t* parse); ++void rc_evaluate_operand(rc_typed_value_t* value, const rc_operand_t* self, rc_eval_state_t* eval_state); ++int rc_operator_is_modifying(int oper); ++int rc_memsize_is_float(uint8_t size); ++int rc_operand_is_float_memref(const rc_operand_t* self); ++int rc_operand_is_float(const rc_operand_t* self); ++int rc_operand_is_recall(const rc_operand_t* self); ++int rc_operand_type_is_memref(uint8_t type); ++int rc_operand_type_is_transform(uint8_t type); ++int rc_operands_are_equal(const rc_operand_t* left, const rc_operand_t* right); ++void rc_operand_addsource(rc_operand_t* self, rc_parse_state_t* parse, uint8_t new_size); ++void rc_operand_set_const(rc_operand_t* self, uint32_t value); ++void rc_operand_set_float_const(rc_operand_t* self, double value); ++ ++int rc_is_valid_variable_character(char ch, int is_first); ++void rc_parse_value_internal(rc_value_t* self, const char** memaddr, rc_parse_state_t* parse); ++int rc_evaluate_value_typed(rc_value_t* self, rc_typed_value_t* value, rc_peek_t peek, void* ud); ++void rc_reset_value(rc_value_t* self); ++int rc_value_from_hits(rc_value_t* self); ++rc_value_t* rc_alloc_variable(const char* memaddr, size_t memaddr_len, rc_parse_state_t* parse); ++uint32_t rc_count_values(const rc_value_t* values); ++void rc_update_values(rc_value_t* values, rc_peek_t peek, void* ud); ++void rc_reset_values(rc_value_t* values); ++ ++void rc_typed_value_convert(rc_typed_value_t* value, char new_type); ++void rc_typed_value_add(rc_typed_value_t* value, const rc_typed_value_t* amount); ++void rc_typed_value_multiply(rc_typed_value_t* value, const rc_typed_value_t* amount); ++void rc_typed_value_divide(rc_typed_value_t* value, const rc_typed_value_t* amount); ++void rc_typed_value_modulus(rc_typed_value_t* value, const rc_typed_value_t* amount); ++void rc_typed_value_negate(rc_typed_value_t* value); ++int rc_typed_value_compare(const rc_typed_value_t* value1, const rc_typed_value_t* value2, char oper); ++void rc_typed_value_combine(rc_typed_value_t* value, rc_typed_value_t* amount, uint8_t oper); ++void rc_typed_value_from_memref_value(rc_typed_value_t* value, const rc_memref_value_t* memref); ++ ++int rc_format_typed_value(char* buffer, size_t size, const rc_typed_value_t* value, int format); ++ ++void rc_parse_lboard_internal(rc_lboard_t* self, const char* memaddr, rc_parse_state_t* parse); ++int rc_lboard_state_active(int state); ++ ++void rc_parse_richpresence_internal(rc_richpresence_t* self, const char* script, rc_parse_state_t* parse); ++rc_memrefs_t* rc_richpresence_get_memrefs(rc_richpresence_t* self); ++void rc_reset_richpresence_triggers(rc_richpresence_t* self); ++void rc_update_richpresence_internal(rc_richpresence_t* richpresence, rc_peek_t peek, void* peek_ud); ++ ++int rc_validate_memrefs_for_console(const rc_memrefs_t* memrefs, char result[], const size_t result_size, uint32_t console_id); ++ ++RC_END_C_DECLS ++ ++#endif /* RC_INTERNAL_H */ +diff -rupbN melonDS.orig/src/rcheevos/src/rcheevos/rc_validate.c melonDS.ra/src/rcheevos/src/rcheevos/rc_validate.c +--- melonDS.orig/src/rcheevos/src/rcheevos/rc_validate.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rcheevos/rc_validate.c 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,1370 @@ ++#include "rc_validate.h" ++ ++#include "rc_consoles.h" ++#include "rc_internal.h" ++ ++#include "../rc_compat.h" ++ ++#include ++#include ++ ++enum ++{ ++ RC_VALIDATION_ERR_NONE, ++ ++ /* sorted by severity - most severe first */ ++ ++ /* errors that prevent the achievement from functioning */ ++ RC_VALIDATION_ERR_ADDRESS_OUT_OF_RANGE, ++ RC_VALIDATION_ERR_RECALL_BEFORE_REMEMBER, ++ RC_VALIDATION_ERR_COMPARISON_NEVER_TRUE_WITH_MAX, ++ RC_VALIDATION_ERR_COMPARISON_NEVER_TRUE_INTEGER_TO_FLOAT, ++ RC_VALIDATION_ERR_COMPARISON_NEVER_TRUE, ++ RC_VALIDATION_ERR_CONFLICTING_CONDITION, ++ ++ /* warnings about logic that does nothing */ ++ RC_VALIDATION_ERR_COMPARISON_ALWAYS_TRUE_INTEGER_TO_FLOAT, ++ RC_VALIDATION_ERR_COMPARISON_ALWAYS_TRUE_WITH_MAX, ++ RC_VALIDATION_ERR_TRAILING_CHAINING_CONDITION, ++ RC_VALIDATION_ERR_MEASUREDIF_WITHOUT_MEASURED, ++ RC_VALIDATION_ERR_ADDHITS_WITHOUT_TARGET, ++ ++ /* warnings about pointer math */ ++ RC_VALIDATION_ERR_POINTER_FROM_PREVIOUS_FRAME, ++ RC_VALIDATION_ERR_POINTER_NON_INTEGER_OFFSET, ++ RC_VALIDATION_ERR_POINTER_TRANSFORMED_OFFSET, ++ ++ /* warnings about potential logic errors */ ++ RC_VALIDATION_ERR_COMPARING_DIFFERENT_MEMORY_SIZES, ++ RC_VALIDATION_ERR_MASK_RESULT_ALWAYS_ZERO, ++ ++ /* warnings that some areas of memory should be avoided */ ++ RC_VALIDATION_ERR_KERNAL_RAM_REQUIRES_BIOS, ++ RC_VALIDATION_ERR_VIRTUAL_RAM_MAY_NOT_BE_EXPOSED, ++ ++ /* warnings about redundant logic */ ++ RC_VALIDATION_ERR_REDUNDANT_CONDITION, ++ RC_VALIDATION_ERR_NO_HITS_TO_RESET, ++ RC_VALIDATION_ERR_RESET_HIT_TARGET_OF_ONE, ++ RC_VALIDATION_ERR_MASK_TOO_LARGE, ++ ++ RC_VALIDATION_ERR_COUNT ++}; ++ ++enum ++{ ++ RC_VALIDATION_VIRTUAL_RAM_OTHER, ++ RC_VALIDATION_VIRTUAL_RAM_MIRROR, ++ RC_VALIDATION_VIRTUAL_RAM_ECHO ++}; ++ ++typedef struct rc_validation_error_t ++{ ++ uint32_t err; ++ uint16_t group_index; ++ uint16_t cond_index; ++ uint32_t data1; ++ uint32_t data2; ++} rc_validation_error_t; ++ ++typedef struct rc_validation_state_t ++{ ++ rc_validation_error_t errors[64]; ++ uint32_t error_count; ++ uint16_t group_index; ++ uint16_t cond_index; ++ uint32_t console_id; ++ uint32_t max_address; ++ uint8_t has_alt_groups; ++ uint8_t has_hit_targets; ++} rc_validation_state_t; ++ ++/* this returns a negative value if err1 is more severe than err2, or ++ * a positive value is err2 is more severe than err1. */ ++static int rc_validation_compare_severity(const rc_validation_error_t* err1, const rc_validation_error_t* err2) ++{ ++ /* lower err value is more severe */ ++ int diff = (err1->err - err2->err); ++ if (diff != 0) ++ return diff; ++ ++ /* lower group index is more severe */ ++ diff = (err1->group_index - err2->group_index); ++ if (diff != 0) ++ return diff; ++ ++ /* lower condition value is more severe */ ++ return (err1->cond_index - err2->cond_index); ++} ++ ++static const rc_validation_error_t* rc_validate_find_most_severe_error(const rc_validation_state_t* state) ++{ ++ const rc_validation_error_t* error = &state->errors[0]; ++ const rc_validation_error_t* most_severe_error = error; ++ const rc_validation_error_t* stop = &state->errors[state->error_count]; ++ ++ while (++error < stop) { ++ if (rc_validation_compare_severity(error, most_severe_error) < 0) ++ most_severe_error = error; ++ } ++ ++ return most_severe_error; ++} ++ ++static rc_validation_error_t* rc_validate_find_least_severe_error(rc_validation_state_t* state) ++{ ++ rc_validation_error_t* error = &state->errors[0]; ++ rc_validation_error_t* least_severe_error = error; ++ rc_validation_error_t* stop = &state->errors[state->error_count]; ++ ++ while (++error < stop) { ++ if (rc_validation_compare_severity(error, least_severe_error) > 0) ++ least_severe_error = error; ++ } ++ ++ return least_severe_error; ++} ++ ++static size_t rc_validate_format_cond_index(char buffer[], size_t buffer_size, const rc_validation_state_t* state, uint32_t group_index, uint32_t cond_index) ++{ ++ int written = 0; ++ ++ if (cond_index == 0) ++ return 0; ++ ++ if (state->has_alt_groups) { ++ if (group_index == 0) ++ written = snprintf(buffer, buffer_size, "Core "); ++ else ++ written = snprintf(buffer, buffer_size, "Alt%u ", group_index); ++ ++ buffer += written; ++ buffer_size -= written; ++ } ++ ++ written += snprintf(buffer, buffer_size, "Condition %u", cond_index); ++ return written; ++} ++ ++static const char* rc_validate_get_condition_type_string(uint32_t type) ++{ ++ switch (type) { ++ case RC_CONDITION_ADD_ADDRESS: return "AddAddress"; ++ case RC_CONDITION_ADD_HITS: return "AddHits"; ++ case RC_CONDITION_ADD_SOURCE: return "AddSource"; ++ case RC_CONDITION_AND_NEXT: return "AndNext"; ++ case RC_CONDITION_MEASURED: return "Measured"; ++ case RC_CONDITION_MEASURED_IF: return "MeasuredIf"; ++ case RC_CONDITION_OR_NEXT: return "OrNext"; ++ case RC_CONDITION_PAUSE_IF: return "PauseIf"; ++ case RC_CONDITION_REMEMBER: return "Remember"; ++ case RC_CONDITION_RESET_IF: return "ResetIf"; ++ case RC_CONDITION_RESET_NEXT_IF: return "ResetNextIf"; ++ case RC_CONDITION_SUB_HITS: return "SubHits"; ++ case RC_CONDITION_SUB_SOURCE: return "SubSource"; ++ case RC_CONDITION_TRIGGER: return "Trigger"; ++ default: return "???"; ++ } ++} ++ ++static void rc_validate_format_error_compare_int_to_float(char buffer[], size_t buffer_size, uint32_t encoded_data, const char* limiter) ++{ ++ int written; ++ rc_typed_value_t value; ++ value.value.u32 = encoded_data; ++ ++ written = snprintf(buffer, buffer_size, "Comparison is %s true (integer can never be %.06f", limiter, value.value.f32); ++ while (buffer[written - 1] == '0') ++ written--; ++ if (buffer[written] == '.') ++ written++; ++ buffer[written] = ')'; ++ buffer[written + 1] = '\0'; ++} ++ ++static int rc_validate_format_error(char buffer[], size_t buffer_size, const rc_validation_state_t* state, const rc_validation_error_t* error) ++{ ++ size_t written = rc_validate_format_cond_index(buffer, buffer_size, state, error->group_index, error->cond_index); ++ buffer += written; ++ buffer_size -= written; ++ ++ if (buffer_size < 2) ++ return 0; ++ ++ buffer_size -= 2; ++ *buffer++ = ':'; ++ *buffer++ = ' '; ++ ++ switch (error->err) { ++ case RC_VALIDATION_ERR_ADDHITS_WITHOUT_TARGET: ++ snprintf(buffer, buffer_size, "Final condition in AddHits chain must have a hit target"); ++ break; ++ ++ case RC_VALIDATION_ERR_ADDRESS_OUT_OF_RANGE: ++ snprintf(buffer, buffer_size, "Address %04X out of range (max %04X)", error->data1, error->data2); ++ break; ++ ++ case RC_VALIDATION_ERR_COMPARING_DIFFERENT_MEMORY_SIZES: ++ snprintf(buffer, buffer_size, "Comparing different memory sizes"); ++ break; ++ ++ case RC_VALIDATION_ERR_COMPARISON_ALWAYS_TRUE_INTEGER_TO_FLOAT: ++ rc_validate_format_error_compare_int_to_float(buffer, buffer_size, error->data1, "always"); ++ break; ++ ++ case RC_VALIDATION_ERR_COMPARISON_ALWAYS_TRUE_WITH_MAX: ++ snprintf(buffer, buffer_size, "Comparison is always true (max %u)", error->data1); ++ break; ++ ++ case RC_VALIDATION_ERR_COMPARISON_NEVER_TRUE: ++ snprintf(buffer, buffer_size, "Comparison is never true"); ++ break; ++ ++ case RC_VALIDATION_ERR_COMPARISON_NEVER_TRUE_INTEGER_TO_FLOAT: ++ rc_validate_format_error_compare_int_to_float(buffer, buffer_size, error->data1, "never"); ++ break; ++ ++ case RC_VALIDATION_ERR_COMPARISON_NEVER_TRUE_WITH_MAX: ++ snprintf(buffer, buffer_size, "Comparison is never true (max %u)", error->data1); ++ break; ++ ++ case RC_VALIDATION_ERR_CONFLICTING_CONDITION: ++ written = snprintf(buffer, buffer_size, "Conflicts with "); ++ buffer += written; ++ buffer_size -= written; ++ rc_validate_format_cond_index(buffer, buffer_size, state, error->data1, error->data2); ++ break; ++ ++ case RC_VALIDATION_ERR_KERNAL_RAM_REQUIRES_BIOS: ++ snprintf(buffer, buffer_size, "Kernel RAM may not be initialized without real BIOS (address %04X)", error->data1); ++ break; ++ ++ case RC_VALIDATION_ERR_MASK_RESULT_ALWAYS_ZERO: ++ snprintf(buffer, buffer_size, "Result of mask is always 0"); ++ break; ++ ++ case RC_VALIDATION_ERR_MASK_TOO_LARGE: ++ snprintf(buffer, buffer_size, "Mask has more bits than source"); ++ break; ++ ++ case RC_VALIDATION_ERR_MEASUREDIF_WITHOUT_MEASURED: ++ snprintf(buffer, buffer_size, "MeasuredIf without Measured"); ++ break; ++ ++ case RC_VALIDATION_ERR_NO_HITS_TO_RESET: ++ snprintf(buffer, buffer_size, "No captured hits to reset"); ++ break; ++ ++ case RC_VALIDATION_ERR_POINTER_FROM_PREVIOUS_FRAME: ++ snprintf(buffer, buffer_size, "Using pointer from previous frame"); ++ break; ++ ++ case RC_VALIDATION_ERR_POINTER_NON_INTEGER_OFFSET: ++ snprintf(buffer, buffer_size, "Using non-integer value in AddAddress calculation"); ++ break; ++ ++ case RC_VALIDATION_ERR_POINTER_TRANSFORMED_OFFSET: ++ snprintf(buffer, buffer_size, "Using transformed value in AddAddress calculation"); ++ break; ++ ++ case RC_VALIDATION_ERR_RECALL_BEFORE_REMEMBER: ++ snprintf(buffer, buffer_size, "Recall used before Remember"); ++ break; ++ ++ case RC_VALIDATION_ERR_RESET_HIT_TARGET_OF_ONE: ++ snprintf(buffer, buffer_size, "Hit target of 1 is redundant on ResetIf"); ++ break; ++ ++ case RC_VALIDATION_ERR_REDUNDANT_CONDITION: ++ written = snprintf(buffer, buffer_size, "Redundant with "); ++ buffer += written; ++ buffer_size -= written; ++ rc_validate_format_cond_index(buffer, buffer_size, state, error->data1, error->data2); ++ break; ++ ++ case RC_VALIDATION_ERR_TRAILING_CHAINING_CONDITION: ++ snprintf(buffer, buffer_size, "%s condition type expects another condition to follow", rc_validate_get_condition_type_string(error->data1)); ++ break; ++ ++ case RC_VALIDATION_ERR_VIRTUAL_RAM_MAY_NOT_BE_EXPOSED: ++ snprintf(buffer, buffer_size, "%s RAM may not be exposed by emulator (address %04X)", ++ error->data2 == RC_VALIDATION_VIRTUAL_RAM_MIRROR ? "Mirror" : ++ error->data2 == RC_VALIDATION_VIRTUAL_RAM_ECHO ? "Echo" : "Virtual", ++ error->data1); ++ break; ++ } ++ ++ return 0; ++} ++ ++static void rc_validate_add_error(rc_validation_state_t* state, uint32_t error_code, uint32_t data1, uint32_t data2) ++{ ++ rc_validation_error_t* error; ++ if (state->error_count == sizeof(state->errors) / sizeof(state->errors[0])) ++ error = rc_validate_find_least_severe_error(state); ++ else ++ error = &state->errors[state->error_count++]; ++ ++ error->err = error_code; ++ error->group_index = state->group_index; ++ error->cond_index = state->cond_index; ++ error->data1 = data1; ++ error->data2 = data2; ++} ++ ++static void rc_validate_memref(const rc_memref_t* memref, rc_validation_state_t* state) ++{ ++ if (memref->address > state->max_address) { ++ rc_validate_add_error(state, RC_VALIDATION_ERR_ADDRESS_OUT_OF_RANGE, memref->address, state->max_address); ++ return; ++ } ++ ++ switch (state->console_id) { ++ case RC_CONSOLE_NINTENDO: ++ case RC_CONSOLE_FAMICOM_DISK_SYSTEM: ++ if (memref->address >= 0x0800 && memref->address <= 0x1FFF) ++ rc_validate_add_error(state, RC_VALIDATION_ERR_VIRTUAL_RAM_MAY_NOT_BE_EXPOSED, memref->address, RC_VALIDATION_VIRTUAL_RAM_MIRROR); ++ break; ++ ++ case RC_CONSOLE_GAMEBOY: ++ case RC_CONSOLE_GAMEBOY_COLOR: ++ if (memref->address >= 0xE000 && memref->address <= 0xFDFF) ++ rc_validate_add_error(state, RC_VALIDATION_ERR_VIRTUAL_RAM_MAY_NOT_BE_EXPOSED, memref->address, RC_VALIDATION_VIRTUAL_RAM_ECHO); ++ break; ++ ++ case RC_CONSOLE_PLAYSTATION: ++ if (memref->address <= 0xFFFF) ++ rc_validate_add_error(state, RC_VALIDATION_ERR_KERNAL_RAM_REQUIRES_BIOS, memref->address, 0); ++ break; ++ } ++} ++ ++static uint32_t rc_console_max_address(uint32_t console_id) ++{ ++ const rc_memory_regions_t* memory_regions; ++ memory_regions = rc_console_memory_regions(console_id); ++ if (memory_regions && memory_regions->num_regions > 0) ++ return memory_regions->region[memory_regions->num_regions - 1].end_address; ++ ++ return 0xFFFFFFFF; ++} ++ ++int rc_validate_memrefs_for_console(const rc_memrefs_t* memrefs, char result[], const size_t result_size, uint32_t console_id) ++{ ++ const rc_memref_list_t* memref_list = &memrefs->memrefs; ++ ++ rc_validation_state_t state; ++ memset(&state, 0, sizeof(state)); ++ state.console_id = console_id; ++ state.max_address = rc_console_max_address(console_id); ++ ++ result[0] = '\0'; ++ do ++ { ++ const rc_memref_t* memref = memref_list->items; ++ const rc_memref_t* memref_stop = memref + memref_list->count; ++ for (; memref < memref_stop; ++memref) ++ { ++ rc_validate_memref(memref, &state); ++ if (state.error_count) { ++ rc_validate_format_error(result, result_size, &state, &state.errors[0]); ++ return 0; ++ } ++ } ++ ++ memref_list = memref_list->next; ++ } while (memref_list); ++ ++ return 1; ++} ++ ++static uint32_t rc_max_value(const rc_operand_t* operand) ++{ ++ if (operand->type == RC_OPERAND_CONST) ++ return operand->value.num; ++ ++ if (!rc_operand_is_memref(operand)) ++ return 0xFFFFFFFF; ++ ++ switch (operand->size) { ++ case RC_MEMSIZE_BIT_0: ++ case RC_MEMSIZE_BIT_1: ++ case RC_MEMSIZE_BIT_2: ++ case RC_MEMSIZE_BIT_3: ++ case RC_MEMSIZE_BIT_4: ++ case RC_MEMSIZE_BIT_5: ++ case RC_MEMSIZE_BIT_6: ++ case RC_MEMSIZE_BIT_7: ++ return 1; ++ ++ case RC_MEMSIZE_LOW: ++ case RC_MEMSIZE_HIGH: ++ return 0xF; ++ ++ case RC_MEMSIZE_BITCOUNT: ++ return 8; ++ ++ case RC_MEMSIZE_8_BITS: ++ /* NOTE: BCD should max out at 0x99, but because each digit can be 15, it actually maxes at 15*10 + 15 */ ++ return (operand->type == RC_OPERAND_BCD) ? 165 : 0xFF; ++ ++ case RC_MEMSIZE_16_BITS: ++ case RC_MEMSIZE_16_BITS_BE: ++ return (operand->type == RC_OPERAND_BCD) ? 16665 : 0xFFFF; ++ ++ case RC_MEMSIZE_24_BITS: ++ case RC_MEMSIZE_24_BITS_BE: ++ return (operand->type == RC_OPERAND_BCD) ? 1666665 : 0xFFFFFF; ++ ++ default: ++ return (operand->type == RC_OPERAND_BCD) ? 166666665 : 0xFFFFFFFF; ++ } ++} ++ ++static void rc_combine_ranges(uint32_t* min_val, uint32_t* max_val, uint8_t oper, uint32_t oper_min_val, uint32_t oper_max_val) ++{ ++ switch (oper) { ++ case RC_OPERATOR_MULT: ++ { ++ unsigned long long scaled = ((unsigned long long)*min_val) * oper_min_val; ++ *min_val = (scaled > 0xFFFFFFFF) ? 0xFFFFFFFF : (uint32_t)scaled; ++ ++ scaled = ((unsigned long long)*max_val) * oper_max_val; ++ *max_val = (scaled > 0xFFFFFFFF) ? 0xFFFFFFFF : (uint32_t)scaled; ++ break; ++ } ++ ++ case RC_OPERATOR_DIV: ++ *min_val = (oper_max_val == 0) ? *min_val : (*min_val / oper_max_val); ++ *max_val = (oper_min_val == 0) ? *max_val : (*max_val / oper_min_val); ++ break; ++ ++ case RC_OPERATOR_AND: ++ *min_val = 0; ++ *max_val &= oper_max_val; ++ break; ++ ++ case RC_OPERATOR_XOR: ++ *min_val = 0; ++ *max_val |= oper_max_val; ++ break; ++ ++ case RC_OPERATOR_MOD: ++ *min_val = 0; ++ *max_val = (*max_val >= oper_max_val) ? oper_max_val - 1 : *max_val; ++ break; ++ ++ case RC_OPERATOR_ADD: ++ if (*min_val > *max_val) { /* underflow occurred */ ++ *max_val += oper_max_val; ++ } ++ else { ++ unsigned long long scaled = ((unsigned long long)*max_val) + oper_max_val; ++ *max_val = (scaled > 0xFFFFFFFF) ? 0xFFFFFFFF : (uint32_t)scaled; ++ } ++ ++ *min_val += oper_min_val; ++ break; ++ ++ case RC_OPERATOR_SUB: ++ *min_val -= oper_max_val; ++ *max_val -= oper_min_val; ++ break; ++ ++ case RC_OPERATOR_SUB_PARENT: ++ { ++ uint32_t temp = oper_min_val - *max_val; ++ *max_val = oper_max_val - *min_val; ++ *min_val = temp; ++ break; ++ } ++ ++ default: ++ break; ++ } ++} ++ ++static void rc_chain_get_value_range(const rc_operand_t* operand, uint32_t* min_val, uint32_t* max_val) ++{ ++ if (rc_operand_is_memref(operand) && operand->value.memref->value.memref_type == RC_MEMREF_TYPE_MODIFIED_MEMREF) { ++ const rc_modified_memref_t* modified_memref = (const rc_modified_memref_t*)operand->value.memref; ++ if (modified_memref->modifier_type != RC_OPERATOR_INDIRECT_READ) { ++ if (modified_memref->modifier_type == RC_OPERATOR_DIV && ++ rc_operand_is_memref(&modified_memref->modifier) && ++ rc_operands_are_equal(&modified_memref->modifier, &modified_memref->parent)) { ++ /* division by self can only return 0 or 1. */ ++ *min_val = 0; ++ *max_val = 1; ++ } ++ else { ++ uint32_t modifier_min_val, modifier_max_val; ++ rc_chain_get_value_range(&modified_memref->parent, min_val, max_val); ++ rc_chain_get_value_range(&modified_memref->modifier, &modifier_min_val, &modifier_max_val); ++ rc_combine_ranges(min_val, max_val, modified_memref->modifier_type, modifier_min_val, modifier_max_val); ++ } ++ return; ++ } ++ } ++ ++ *min_val = (operand->type == RC_OPERAND_CONST) ? operand->value.num : 0; ++ *max_val = rc_max_value(operand); ++} ++ ++static int rc_validate_get_condition_index(const rc_condset_t* condset, const rc_condition_t* condition) ++{ ++ int index = 1; ++ const rc_condition_t* scan; ++ for (scan = condset->conditions; scan != NULL; scan = scan->next) ++ { ++ if (scan == condition) ++ return index; ++ ++ ++index; ++ } ++ ++ return 0; ++} ++ ++static void rc_validate_range(uint32_t min_val, uint32_t max_val, char oper, uint32_t max, rc_validation_state_t* state) ++{ ++ switch (oper) { ++ case RC_OPERATOR_AND: ++ if (min_val > max) ++ rc_validate_add_error(state, RC_VALIDATION_ERR_MASK_TOO_LARGE, 0, 0); ++ else if (min_val == 0 && max_val == 0) ++ rc_validate_add_error(state, RC_VALIDATION_ERR_MASK_RESULT_ALWAYS_ZERO, 0, 0); ++ break; ++ ++ case RC_OPERATOR_EQ: ++ if (min_val > max) ++ rc_validate_add_error(state, RC_VALIDATION_ERR_COMPARISON_NEVER_TRUE_WITH_MAX, max, 0); ++ break; ++ ++ case RC_OPERATOR_NE: ++ if (min_val > max) ++ rc_validate_add_error(state, RC_VALIDATION_ERR_COMPARISON_ALWAYS_TRUE_WITH_MAX, max, 0); ++ break; ++ ++ case RC_OPERATOR_GE: ++ if (min_val > max) ++ rc_validate_add_error(state, RC_VALIDATION_ERR_COMPARISON_NEVER_TRUE_WITH_MAX, max, 0); ++ else if (max_val == 0) ++ rc_validate_add_error(state, RC_VALIDATION_ERR_COMPARISON_ALWAYS_TRUE_WITH_MAX, max, 0); ++ break; ++ ++ case RC_OPERATOR_GT: ++ if (min_val >= max) ++ rc_validate_add_error(state, RC_VALIDATION_ERR_COMPARISON_NEVER_TRUE_WITH_MAX, max, 0); ++ break; ++ ++ case RC_OPERATOR_LE: ++ if (min_val >= max) ++ rc_validate_add_error(state, RC_VALIDATION_ERR_COMPARISON_ALWAYS_TRUE_WITH_MAX, max, 0); ++ break; ++ ++ case RC_OPERATOR_LT: ++ if (min_val > max) ++ rc_validate_add_error(state, RC_VALIDATION_ERR_COMPARISON_ALWAYS_TRUE_WITH_MAX, max, 0); ++ else if (max_val == 0) ++ rc_validate_add_error(state, RC_VALIDATION_ERR_COMPARISON_NEVER_TRUE, 0, 0); ++ break; ++ } ++} ++ ++static int rc_validate_condset_internal(const rc_condset_t* condset, rc_validation_state_t* state) ++{ ++ const rc_condition_t* cond; ++ int in_add_hits = 0; ++ int in_add_address = 0; ++ int is_combining = 0; ++ int has_measured = 0; ++ int measuredif_index = -1; ++ uint32_t errors_before = state->error_count; ++ ++ if (!condset) ++ return 1; ++ ++ state->cond_index = 1; ++ ++ for (cond = condset->conditions; cond; cond = cond->next, ++state->cond_index) { ++ /* validate the original operands first */ ++ const rc_operand_t* operand1 = rc_condition_get_real_operand1(cond); ++ int is_memref1 = rc_operand_is_memref(operand1); ++ const int is_memref2 = rc_operand_is_memref(&cond->operand2); ++ ++ if (!in_add_address) { ++ if (is_memref1) ++ rc_validate_memref(operand1->value.memref, state); ++ if (is_memref2) ++ rc_validate_memref(cond->operand2.value.memref, state); ++ } ++ else { ++ in_add_address = 0; ++ } ++ ++ /* if operand is {recall}, but memref is null, that means the Remember wasn't found */ ++ if (rc_operand_is_recall(operand1) && ++ rc_operand_type_is_memref(operand1->memref_access_type) && ++ !operand1->value.memref) { ++ rc_validate_add_error(state, RC_VALIDATION_ERR_RECALL_BEFORE_REMEMBER, 0, 0); ++ } ++ if (rc_operand_is_recall(&cond->operand2) && ++ rc_operand_type_is_memref(cond->operand2.memref_access_type) && ++ !cond->operand2.value.memref) { ++ rc_validate_add_error(state, RC_VALIDATION_ERR_RECALL_BEFORE_REMEMBER, 0, 0); ++ } ++ ++ switch (cond->type) { ++ case RC_CONDITION_ADD_SOURCE: ++ case RC_CONDITION_SUB_SOURCE: ++ case RC_CONDITION_REMEMBER: ++ is_combining = 1; ++ continue; ++ ++ case RC_CONDITION_ADD_ADDRESS: ++ if (operand1->type == RC_OPERAND_DELTA || operand1->type == RC_OPERAND_PRIOR) ++ rc_validate_add_error(state, RC_VALIDATION_ERR_POINTER_FROM_PREVIOUS_FRAME, 0, 0); ++ else if (rc_operand_is_float(operand1) || rc_operand_is_float(&cond->operand2)) ++ rc_validate_add_error(state, RC_VALIDATION_ERR_POINTER_NON_INTEGER_OFFSET, 0, 0); ++ else if (rc_operand_type_is_transform(operand1->type) && cond->oper != RC_OPERATOR_MULT) ++ rc_validate_add_error(state, RC_VALIDATION_ERR_POINTER_TRANSFORMED_OFFSET, 0, 0); ++ ++ in_add_address = 1; ++ is_combining = 1; ++ continue; ++ ++ case RC_CONDITION_ADD_HITS: ++ case RC_CONDITION_SUB_HITS: ++ in_add_hits = 1; ++ is_combining = 1; ++ break; ++ ++ case RC_CONDITION_AND_NEXT: ++ case RC_CONDITION_OR_NEXT: ++ case RC_CONDITION_RESET_NEXT_IF: ++ is_combining = 1; ++ break; ++ ++ case RC_CONDITION_RESET_IF: ++ if (in_add_hits) { ++ /* ResetIf at the end of a hit chain does not require a hit target. ++ * It's meant to reset things if some subset of conditions have been true. */ ++ in_add_hits = 0; ++ is_combining = 0; ++ break; ++ } ++ if (!state->has_hit_targets) ++ rc_validate_add_error(state, RC_VALIDATION_ERR_NO_HITS_TO_RESET, 0, 0); ++ else if (cond->required_hits == 1) ++ rc_validate_add_error(state, RC_VALIDATION_ERR_RESET_HIT_TARGET_OF_ONE, 0, 0); ++ /* fallthrough */ /* to default */ ++ default: ++ if (in_add_hits) { ++ if (cond->required_hits == 0) ++ rc_validate_add_error(state, RC_VALIDATION_ERR_ADDHITS_WITHOUT_TARGET, 0, 0); ++ ++ in_add_hits = 0; ++ } ++ ++ has_measured |= (cond->type == RC_CONDITION_MEASURED); ++ if (cond->type == RC_CONDITION_MEASURED_IF && measuredif_index == -1) ++ measuredif_index = state->cond_index; ++ ++ is_combining = 0; ++ break; ++ } ++ ++ /* original operands are valid. now switch to the derived operands for logic ++ * combining/comparing them */ ++ operand1 = &cond->operand1; ++ is_memref1 = rc_operand_is_memref(operand1); ++ ++ /* check for comparing two differently sized memrefs */ ++ if (is_memref1 && is_memref2 && ++ operand1->value.memref->value.memref_type == RC_MEMREF_TYPE_MEMREF && ++ cond->operand2.value.memref->value.memref_type == RC_MEMREF_TYPE_MEMREF && ++ rc_max_value(operand1) != rc_max_value(&cond->operand2)) { ++ rc_validate_add_error(state, RC_VALIDATION_ERR_COMPARING_DIFFERENT_MEMORY_SIZES, 0, 0); ++ } ++ ++ if (is_memref1 && rc_operand_is_float(operand1)) { ++ /* if left side is a float, right side will be converted to a float, so don't do range validation */ ++ } ++ else if (is_memref1 || is_memref2) { ++ /* if either side is a memref, check for impossible comparisons */ ++ const rc_operand_t* operand2 = &cond->operand2; ++ uint8_t oper = cond->oper; ++ uint32_t min, max; ++ uint32_t max_val = rc_max_value(operand2); ++ uint32_t min_val; ++ rc_typed_value_t typed_value; ++ ++ rc_chain_get_value_range(operand1, &min, &max); ++ if (min > max) { /* underflow */ ++ min = 0; ++ max = 0xFFFFFFFF; ++ } ++ ++ if (!is_memref1) { ++ /* pretend constant was on right side */ ++ operand2 = operand1; ++ operand1 = &cond->operand2; ++ max_val = max; ++ max = rc_max_value(&cond->operand2); ++ ++ switch (oper) { ++ case RC_OPERATOR_LT: oper = RC_OPERATOR_GT; break; ++ case RC_OPERATOR_LE: oper = RC_OPERATOR_GE; break; ++ case RC_OPERATOR_GT: oper = RC_OPERATOR_LT; break; ++ case RC_OPERATOR_GE: oper = RC_OPERATOR_LE; break; ++ } ++ } ++ ++ switch (operand2->type) { ++ case RC_OPERAND_CONST: ++ min_val = operand2->value.num; ++ break; ++ ++ case RC_OPERAND_FP: ++ min_val = (int)operand2->value.dbl; ++ ++ /* cannot compare an integer memory reference to a non-integral floating point value */ ++ if (!rc_operand_is_float_memref(operand1) && (float)min_val != operand2->value.dbl) { ++ switch (oper) { ++ case RC_OPERATOR_EQ: ++ typed_value.value.f32 = (float)operand2->value.dbl; ++ rc_validate_add_error(state, RC_VALIDATION_ERR_COMPARISON_NEVER_TRUE_INTEGER_TO_FLOAT, typed_value.value.u32, 0); ++ break; ++ ++ case RC_OPERATOR_NE: ++ typed_value.value.f32 = (float)operand2->value.dbl; ++ rc_validate_add_error(state, RC_VALIDATION_ERR_COMPARISON_ALWAYS_TRUE_INTEGER_TO_FLOAT, typed_value.value.u32, 0); ++ break; ++ ++ case RC_OPERATOR_GT: /* value could be greater than floor(float) */ ++ case RC_OPERATOR_LE: /* value could be less than or equal to floor(float) */ ++ break; ++ ++ case RC_OPERATOR_GE: /* value could be greater than or equal to ceil(float) */ ++ case RC_OPERATOR_LT: /* value could be less than ceil(float) */ ++ ++min_val; ++ break; ++ } ++ } ++ ++ break; ++ ++ default: /* right side is memref or add source chain */ ++ min_val = 0; ++ break; ++ } ++ ++ /* min_val and max_val are the range allowed by operand2. max is the upper value from operand1. */ ++ rc_validate_range(min_val, max_val, oper, max, state); ++ } ++ } ++ ++ if (is_combining) { ++ /* find the final condition so we can extract the type */ ++ state->cond_index--; ++ cond = condset->conditions; ++ while (cond->next) ++ cond = cond->next; ++ ++ rc_validate_add_error(state, RC_VALIDATION_ERR_TRAILING_CHAINING_CONDITION, cond->type, 0); ++ } ++ ++ if (measuredif_index != -1 && !has_measured) { ++ state->cond_index = measuredif_index; ++ rc_validate_add_error(state, RC_VALIDATION_ERR_MEASUREDIF_WITHOUT_MEASURED, 0, 0); ++ } ++ ++ return (state->error_count == errors_before); ++} ++ ++static int rc_condset_has_hittargets(const rc_condset_t* condset) ++{ ++ if (condset->num_hittarget_conditions > 0) ++ return 1; ++ ++ /* pause and reset conditions may have hittargets and won't be classified as hittarget conditions. ++ * measured conditions may also have hittargets. ++ * other conditions may have hittarget conditions in an AndNext/OrNext chain. ++ * basically, check everything other than hittarget (explicitly known) and indirect (cannot have). ++ */ ++ if (condset->num_pause_conditions || condset->num_reset_conditions || condset->num_measured_conditions || condset->num_other_conditions) { ++ const rc_condition_t* condition = rc_condset_get_conditions((rc_condset_t*)condset); ++ /* ASSERT: don't need to add num_hittarget_conditions because it must be 0 per earlier check */ ++ const rc_condition_t* stop = condition + condset->num_pause_conditions ++ + condset->num_reset_conditions + condset->num_measured_conditions ++ + condset->num_other_conditions; ++ for (; condition < stop; ++condition) { ++ if (condition->required_hits) ++ return 1; ++ } ++ } ++ ++ return 0; ++} ++ ++int rc_validate_condset(const rc_condset_t* condset, char result[], const size_t result_size, uint32_t max_address) ++{ ++ rc_validation_state_t state; ++ memset(&state, 0, sizeof(state)); ++ state.has_hit_targets = rc_condset_has_hittargets(condset); ++ state.max_address = max_address; ++ ++ result[0] = '\0'; ++ if (rc_validate_condset_internal(condset, &state)) { ++ const rc_validation_error_t* most_severe_error = rc_validate_find_most_severe_error(&state); ++ return rc_validate_format_error(result, result_size, &state, most_severe_error); ++ } ++ ++ return 1; ++} ++ ++int rc_validate_condset_for_console(const rc_condset_t* condset, char result[], const size_t result_size, uint32_t console_id) ++{ ++ rc_validation_state_t state; ++ memset(&state, 0, sizeof(state)); ++ state.console_id = console_id; ++ state.max_address = rc_console_max_address(console_id); ++ state.has_hit_targets = rc_condset_has_hittargets(condset); ++ ++ result[0] = '\0'; ++ if (rc_validate_condset_internal(condset, &state)) { ++ const rc_validation_error_t* most_severe_error = rc_validate_find_most_severe_error(&state); ++ return rc_validate_format_error(result, result_size, &state, most_severe_error); ++ } ++ ++ return 1; ++} ++ ++/* rc_condition_is_combining doesn't look at conditions that build a memref (like AddSource) */ ++static int rc_validate_is_combining_condition(const rc_condition_t* condition) ++{ ++ switch (condition->type) ++ { ++ case RC_CONDITION_ADD_ADDRESS: ++ case RC_CONDITION_ADD_HITS: ++ case RC_CONDITION_ADD_SOURCE: ++ case RC_CONDITION_AND_NEXT: ++ case RC_CONDITION_OR_NEXT: ++ case RC_CONDITION_RESET_NEXT_IF: ++ case RC_CONDITION_SUB_HITS: ++ case RC_CONDITION_SUB_SOURCE: ++ case RC_CONDITION_REMEMBER: ++ return 1; ++ ++ default: ++ return 0; ++ } ++} ++ ++static int rc_validate_get_opposite_comparison(int oper) ++{ ++ switch (oper) ++ { ++ case RC_OPERATOR_EQ: return RC_OPERATOR_NE; ++ case RC_OPERATOR_NE: return RC_OPERATOR_EQ; ++ case RC_OPERATOR_LT: return RC_OPERATOR_GE; ++ case RC_OPERATOR_LE: return RC_OPERATOR_GT; ++ case RC_OPERATOR_GT: return RC_OPERATOR_LE; ++ case RC_OPERATOR_GE: return RC_OPERATOR_LT; ++ default: return oper; ++ } ++} ++ ++static const rc_operand_t* rc_validate_get_comparison(const rc_condition_t* condition, int* comparison, unsigned* value) ++{ ++ if (rc_operand_is_memref(&condition->operand1)) ++ { ++ if (condition->operand2.type != RC_OPERAND_CONST) ++ return NULL; ++ ++ *comparison = condition->oper; ++ *value = condition->operand2.value.num; ++ return &condition->operand1; ++ } ++ ++ if (condition->operand1.type != RC_OPERAND_CONST) ++ return NULL; ++ ++ if (!rc_operand_is_memref(&condition->operand2)) ++ return NULL; ++ ++ *comparison = rc_validate_get_opposite_comparison(condition->oper); ++ *value = condition->operand1.value.num; ++ return &condition->operand2; ++} ++ ++enum { ++ RC_OVERLAP_NONE = 0, ++ RC_OVERLAP_CONFLICTING, ++ RC_OVERLAP_REDUNDANT, ++ RC_OVERLAP_DEFER ++}; ++ ++static int rc_validate_comparison_overlap(int comparison1, uint32_t value1, int comparison2, uint32_t value2) ++{ ++ /* NOTE: this only cares if comp2 conflicts with comp1. ++ * If comp1 conflicts with comp2, we'll catch that later (return RC_OVERLAP_NONE for now) */ ++ switch (comparison2) ++ { ++ case RC_OPERATOR_EQ: ++ switch (comparison1) /* comp1 comp2 comp1 comp2 comp1 comp2 */ ++ { /* value1 = value2 value1 < value2 value1 > value2 */ ++ case RC_OPERATOR_EQ: /* a == 1 && a == 1 | a == 1 && a == 2 | a == 2 && a == 1 */ ++ /* redundant conflict conflict */ ++ return (value1 == value2) ? RC_OVERLAP_REDUNDANT : RC_OVERLAP_CONFLICTING; ++ case RC_OPERATOR_LE: /* a <= 1 && a == 1 | a <= 1 && a == 2 | a <= 2 && a == 1 */ ++ /* defer conflict defer */ ++ return (value1 < value2) ? RC_OVERLAP_CONFLICTING : RC_OVERLAP_DEFER; ++ case RC_OPERATOR_GE: /* a >= 1 && a == 1 | a >= 1 && a == 2 | a >= 2 && a == 1 */ ++ /* defer defer conflict */ ++ return (value1 > value2) ? RC_OVERLAP_CONFLICTING : RC_OVERLAP_DEFER; ++ case RC_OPERATOR_NE: /* a != 1 && a == 1 | a != 1 && a == 2 | a != 2 && a == 1 */ ++ /* conflict defer defer */ ++ return (value1 == value2) ? RC_OVERLAP_CONFLICTING : RC_OVERLAP_DEFER; ++ case RC_OPERATOR_LT: /* a < 1 && a == 1 | a < 1 && a == 2 | a < 2 && a == 1 */ ++ /* conflict conflict defer */ ++ return (value1 <= value2) ? RC_OVERLAP_CONFLICTING : RC_OVERLAP_DEFER; ++ case RC_OPERATOR_GT: /* a > 1 && a == 1 | a > 1 && a == 2 | a > 2 && a == 1 */ ++ /* conflict defer conflict */ ++ return (value1 >= value2) ? RC_OVERLAP_CONFLICTING : RC_OVERLAP_DEFER; ++ } ++ break; ++ ++ case RC_OPERATOR_NE: ++ switch (comparison1) /* comp1 comp2 comp1 comp2 comp1 comp2 */ ++ { /* value1 = value2 value1 < value2 value1 > value2 */ ++ case RC_OPERATOR_EQ: /* a == 1 && a != 1 | a == 1 && a != 2 | a == 2 && a != 1 */ ++ /* conflict redundant redundant */ ++ return (value1 == value2) ? RC_OVERLAP_CONFLICTING : RC_OVERLAP_REDUNDANT; ++ case RC_OPERATOR_LE: /* a <= 1 && a != 1 | a <= 1 && a != 2 | a <= 2 && a != 1 */ ++ /* none redundant none */ ++ return (value1 < value2) ? RC_OVERLAP_REDUNDANT : RC_OVERLAP_NONE; ++ case RC_OPERATOR_GE: /* a >= 1 && a != 1 | a >= 1 && a != 2 | a >= 2 && a != 1 */ ++ /* none none redundant */ ++ return (value1 > value2) ? RC_OVERLAP_REDUNDANT : RC_OVERLAP_NONE; ++ case RC_OPERATOR_NE: /* a != 1 && a != 1 | a != 1 && a != 2 | a != 2 && a != 1 */ ++ /* redundant none none */ ++ return (value1 == value2) ? RC_OVERLAP_REDUNDANT : RC_OVERLAP_NONE; ++ case RC_OPERATOR_LT: /* a < 1 && a != 1 | a < 1 && a != 2 | a < 2 && a != 1 */ ++ /* redundant redundant none */ ++ return (value1 <= value2) ? RC_OVERLAP_REDUNDANT : RC_OVERLAP_NONE; ++ case RC_OPERATOR_GT: /* a > 1 && a != 1 | a > 1 && a != 2 | a > 2 && a != 1 */ ++ /* redundant none redundant */ ++ return (value1 >= value2) ? RC_OVERLAP_REDUNDANT : RC_OVERLAP_NONE; ++ } ++ break; ++ ++ case RC_OPERATOR_LT: ++ switch (comparison1) /* comp1 comp2 comp1 comp2 comp1 comp2 */ ++ { /* value1 = value2 value1 < value2 value1 > value2 */ ++ case RC_OPERATOR_EQ: /* a == 1 && a < 1 | a == 1 && a < 2 | a == 2 && a < 1 */ ++ /* conflict redundant conflict */ ++ return (value1 < value2) ? RC_OVERLAP_REDUNDANT : RC_OVERLAP_CONFLICTING; ++ case RC_OPERATOR_LE: /* a <= 1 && a < 1 | a <= 1 && a < 2 | a <= 2 && a < 1 */ ++ /* defer redundant defer */ ++ return (value1 < value2) ? RC_OVERLAP_REDUNDANT : RC_OVERLAP_DEFER; ++ case RC_OPERATOR_GE: /* a >= 1 && a < 1 | a >= 1 && a < 2 | a >= 2 && a < 1 */ ++ /* conflict none conflict */ ++ return (value1 >= value2) ? RC_OVERLAP_CONFLICTING : RC_OVERLAP_NONE; ++ case RC_OPERATOR_NE: /* a != 1 && a < 1 | a != 1 && a < 2 | a != 2 && a < 1 */ ++ /* defer none defer */ ++ return (value1 >= value2) ? RC_OVERLAP_DEFER : RC_OVERLAP_NONE; ++ case RC_OPERATOR_LT: /* a < 1 && a < 1 | a < 1 && a < 2 | a < 2 && a < 1 */ ++ /* redundant redundant defer */ ++ return (value1 <= value2) ? RC_OVERLAP_REDUNDANT : RC_OVERLAP_DEFER; ++ case RC_OPERATOR_GT: /* a > 1 && a < 1 | a > 1 && a < 2 | a > 2 && a < 1 */ ++ /* conflict none conflict */ ++ return (value1 >= value2) ? RC_OVERLAP_CONFLICTING : RC_OVERLAP_NONE; ++ } ++ break; ++ ++ case RC_OPERATOR_LE: ++ switch (comparison1) /* comp1 comp2 comp1 comp2 comp1 comp2 */ ++ { /* value1 = value2 value1 < value2 value1 > value2 */ ++ case RC_OPERATOR_EQ: /* a == 1 && a <= 1 | a == 1 && a <= 2 | a == 2 && a <= 1 */ ++ /* redundant redundant conflict */ ++ return (value1 <= value2) ? RC_OVERLAP_REDUNDANT : RC_OVERLAP_CONFLICTING; ++ case RC_OPERATOR_LE: /* a <= 1 && a <= 1 | a <= 1 && a <= 2 | a <= 2 && a <= 1 */ ++ /* redundant redundant defer */ ++ return (value1 <= value2) ? RC_OVERLAP_REDUNDANT : RC_OVERLAP_DEFER; ++ case RC_OPERATOR_GE: /* a >= 1 && a <= 1 | a >= 1 && a <= 2 | a >= 2 && a <= 1 */ ++ /* none none conflict */ ++ return (value1 > value2) ? RC_OVERLAP_CONFLICTING : RC_OVERLAP_NONE; ++ case RC_OPERATOR_NE: /* a != 1 && a <= 1 | a != 1 && a <= 2 | a != 2 && a <= 1 */ ++ /* none none defer */ ++ return (value1 > value2) ? RC_OVERLAP_DEFER : RC_OVERLAP_NONE; ++ case RC_OPERATOR_LT: /* a < 1 && a <= 1 | a < 1 && a <= 2 | a < 2 && a <= 1 */ ++ /* redundant redundant defer */ ++ return (value1 <= value2) ? RC_OVERLAP_REDUNDANT : RC_OVERLAP_DEFER; ++ case RC_OPERATOR_GT: /* a > 1 && a <= 1 | a > 1 && a <= 2 | a > 2 && a <= 1 */ ++ /* conflict none conflict */ ++ return (value1 >= value2) ? RC_OVERLAP_CONFLICTING : RC_OVERLAP_NONE; ++ } ++ break; ++ ++ case RC_OPERATOR_GT: ++ switch (comparison1) /* comp1 comp2 comp1 comp2 comp1 comp2 */ ++ { /* value1 = value2 value1 < value2 value1 > value2 */ ++ case RC_OPERATOR_EQ: /* a == 1 && a > 1 | a == 1 && a > 2 | a == 2 && a > 1 */ ++ /* conflict conflict redundant */ ++ return (value1 > value2) ? RC_OVERLAP_REDUNDANT : RC_OVERLAP_CONFLICTING; ++ case RC_OPERATOR_LE: /* a <= 1 && a > 1 | a <= 1 && a > 2 | a <= 2 && a > 1 */ ++ /* conflict conflict defer */ ++ return (value1 <= value2) ? RC_OVERLAP_CONFLICTING : RC_OVERLAP_DEFER; ++ case RC_OPERATOR_GE: /* a >= 1 && a > 1 | a >= 1 && a > 2 | a >= 2 && a > 1 */ ++ /* defer defer redundant */ ++ return (value1 > value2) ? RC_OVERLAP_REDUNDANT : RC_OVERLAP_DEFER; ++ case RC_OPERATOR_NE: /* a != 1 && a > 1 | a != 1 && a > 2 | a != 2 && a > 1 */ ++ /* defer defer none */ ++ return (value1 <= value2) ? RC_OVERLAP_DEFER : RC_OVERLAP_NONE; ++ case RC_OPERATOR_LT: /* a < 1 && a > 1 | a < 1 && a > 2 | a < 2 && a > 1 */ ++ /* conflict conflict none */ ++ return (value1 <= value2) ? RC_OVERLAP_CONFLICTING : RC_OVERLAP_NONE; ++ case RC_OPERATOR_GT: /* a > 1 && a > 1 | a > 1 && a > 2 | a > 2 && a > 1 */ ++ /* redundant defer redundant */ ++ return (value1 >= value2) ? RC_OVERLAP_REDUNDANT : RC_OVERLAP_DEFER; ++ } ++ break; ++ ++ case RC_OPERATOR_GE: ++ switch (comparison1) /* comp1 comp2 comp1 comp2 comp1 comp2 */ ++ { /* value1 = value2 value1 < value2 value1 > value2 */ ++ case RC_OPERATOR_EQ: /* a == 1 && a >= 1 | a == 1 && a >= 2 | a == 2 && a >= 1 */ ++ /* redundant conflict redundant */ ++ return (value1 >= value2) ? RC_OVERLAP_REDUNDANT : RC_OVERLAP_CONFLICTING; ++ case RC_OPERATOR_LE: /* a <= 1 && a >= 1 | a <= 1 && a >= 2 | a <= 2 && a >= 1 */ ++ /* none conflict none */ ++ return (value1 < value2) ? RC_OVERLAP_CONFLICTING : RC_OVERLAP_NONE; ++ case RC_OPERATOR_GE: /* a >= 1 && a >= 1 | a >= 1 && a >= 2 | a >= 2 && a >= 1 */ ++ /* redundant redundant defer */ ++ return (value1 <= value2) ? RC_OVERLAP_REDUNDANT : RC_OVERLAP_DEFER; ++ case RC_OPERATOR_NE: /* a != 1 && a >= 1 | a != 1 && a >= 2 | a != 2 && a >= 1 */ ++ /* none defer none */ ++ return (value1 < value2) ? RC_OVERLAP_DEFER : RC_OVERLAP_NONE; ++ case RC_OPERATOR_LT: /* a < 1 && a >= 1 | a < 1 && a >= 2 | a < 2 && a >= 1 */ ++ /* conflict conflict none */ ++ return (value1 <= value2) ? RC_OVERLAP_CONFLICTING : RC_OVERLAP_NONE; ++ case RC_OPERATOR_GT: /* a > 1 && a >= 1 | a > 1 && a >= 2 | a > 2 && a >= 1 */ ++ /* redundant defer redundant */ ++ return (value1 >= value2) ? RC_OVERLAP_REDUNDANT : RC_OVERLAP_DEFER; ++ } ++ break; ++ } ++ ++ return RC_OVERLAP_NONE; ++} ++ ++static int rc_validate_conflicting_conditions(const rc_condset_t* conditions, const rc_condset_t* compare_conditions, ++ uint32_t group_index, rc_validation_state_t* state) ++{ ++ int comparison1, comparison2; ++ uint32_t value1, value2; ++ const rc_operand_t* operand1; ++ const rc_operand_t* operand2; ++ const rc_condition_t* compare_condition; ++ const rc_condition_t* condition; ++ const rc_condition_t* condition_chain_start; ++ uint32_t errors_before = state->error_count; ++ int overlap; ++ int chain_matches; ++ ++ /* empty group */ ++ if (conditions == NULL || compare_conditions == NULL) ++ return 1; ++ ++ /* outer loop is the source conditions */ ++ for (condition = conditions->conditions; condition != NULL; condition = condition->next, ++state->cond_index) { ++ condition_chain_start = condition; ++ while (condition && rc_condition_is_combining(condition)) { ++ condition = condition->next; ++ } ++ if (!condition) ++ break; ++ ++ /* hits can be captured at any time, so any potential conflict will not be conflicting at another time */ ++ if (condition->required_hits) ++ continue; ++ ++ operand1 = rc_validate_get_comparison(condition, &comparison1, &value1); ++ if (!operand1) ++ continue; ++ ++ switch (condition->type) { ++ case RC_CONDITION_PAUSE_IF: ++ if (conditions != compare_conditions) ++ break; ++ /* fallthrough */ ++ case RC_CONDITION_RESET_IF: ++ comparison1 = rc_validate_get_opposite_comparison(comparison1); ++ break; ++ default: ++ if (rc_validate_is_combining_condition(condition)) ++ continue; ++ break; ++ } ++ ++ /* inner loop is the potentially conflicting conditions */ ++ state->cond_index = 1; ++ for (compare_condition = compare_conditions->conditions; compare_condition != NULL; compare_condition = compare_condition->next, ++state->cond_index) { ++ if (compare_condition == condition_chain_start) { ++ /* skip condition we're already looking at */ ++ while (compare_condition != condition) { ++ ++state->cond_index; ++ compare_condition = compare_condition->next; ++ } ++ ++ continue; ++ } ++ ++ /* if combining conditions exist, make sure the same combining conditions exist in the ++ * compare logic. conflicts can only occur if the combinining conditions match. */ ++ chain_matches = 1; ++ if (condition_chain_start != condition) { ++ const rc_condition_t* condition_chain_iter = condition_chain_start; ++ while (condition_chain_iter != condition) { ++ if (compare_condition->type != condition_chain_iter->type || ++ compare_condition->oper != condition_chain_iter->oper || ++ compare_condition->required_hits != condition_chain_iter->required_hits || ++ !rc_operands_are_equal(&compare_condition->operand1, &condition_chain_iter->operand1)) ++ { ++ chain_matches = 0; ++ break; ++ } ++ ++ if (compare_condition->oper != RC_OPERATOR_NONE && ++ !rc_operands_are_equal(&compare_condition->operand2, &condition_chain_iter->operand2)) ++ { ++ chain_matches = 0; ++ break; ++ } ++ ++ if (!compare_condition->next) { ++ chain_matches = 0; ++ break; ++ } ++ ++ if (compare_condition->type != RC_CONDITION_ADD_ADDRESS && ++ compare_condition->type != RC_CONDITION_ADD_SOURCE && ++ compare_condition->type != RC_CONDITION_SUB_SOURCE && ++ compare_condition->type != RC_CONDITION_AND_NEXT) ++ { ++ /* things like AddHits and OrNext are hard to definitively detect conflicts. ignore them. */ ++ chain_matches = 0; ++ break; ++ } ++ ++ ++state->cond_index; ++ compare_condition = compare_condition->next; ++ condition_chain_iter = condition_chain_iter->next; ++ } ++ } ++ ++ /* combining field didn't match, or there's more unmatched combining fields. ignore this condition */ ++ if (!chain_matches || rc_validate_is_combining_condition(compare_condition)) { ++ while (compare_condition->next && rc_validate_is_combining_condition(compare_condition)) ++ compare_condition = compare_condition->next; ++ continue; ++ } ++ ++ if (compare_condition->required_hits) ++ continue; ++ ++ operand2 = rc_validate_get_comparison(compare_condition, &comparison2, &value2); ++ if (!operand2 || !rc_operands_are_equal(operand1, operand2)) ++ continue; ++ ++ switch (compare_condition->type) { ++ case RC_CONDITION_PAUSE_IF: ++ if (conditions != compare_conditions) /* PauseIf only affects conditions in same group */ ++ break; ++ /* fallthrough */ ++ case RC_CONDITION_RESET_IF: ++ comparison2 = rc_validate_get_opposite_comparison(comparison2); ++ break; ++ default: ++ if (rc_validate_is_combining_condition(compare_condition)) ++ continue; ++ break; ++ } ++ ++ overlap = rc_validate_comparison_overlap(comparison1, value1, comparison2, value2); ++ switch (overlap) ++ { ++ case RC_OVERLAP_CONFLICTING: ++ if (compare_condition->type == RC_CONDITION_PAUSE_IF || condition->type == RC_CONDITION_PAUSE_IF) ++ { ++ /* ignore PauseIf conflicts between groups, unless both conditions are PauseIfs */ ++ if (conditions != compare_conditions && compare_condition->type != condition->type) ++ continue; ++ } ++ break; ++ ++ case RC_OVERLAP_REDUNDANT: ++ if (group_index != state->group_index && state->group_index == 0) ++ { ++ /* if the alt condition is more restrictive than the core condition, ignore it */ ++ if (rc_validate_comparison_overlap(comparison2, value2, comparison1, value1) != RC_OVERLAP_REDUNDANT) ++ continue; ++ } ++ ++ if (compare_condition->type == RC_CONDITION_PAUSE_IF || condition->type == RC_CONDITION_PAUSE_IF) ++ { ++ /* ignore PauseIf redundancies between groups */ ++ if (conditions != compare_conditions) ++ continue; ++ ++ /* if the PauseIf is less restrictive than the other condition, it's just a guard. ignore it */ ++ if (rc_validate_comparison_overlap(comparison2, value2, comparison1, value1) != RC_OVERLAP_REDUNDANT) ++ continue; ++ ++ /* PauseIf redundant with ResetIf is a conflict (both are inverted comparisons) */ ++ if (compare_condition->type == RC_CONDITION_RESET_IF || condition->type == RC_CONDITION_RESET_IF) ++ overlap = RC_OVERLAP_CONFLICTING; ++ } ++ else if (compare_condition->type == RC_CONDITION_RESET_IF && condition->type != RC_CONDITION_RESET_IF) ++ { ++ /* only ever report the redundancy on the non-ResetIf condition. The ResetIf is allowed to ++ * fire when the non-ResetIf condition is not true. */ ++ if (state->has_hit_targets) ++ continue; ++ } ++ else if (condition->type == RC_CONDITION_RESET_IF && compare_condition->type != RC_CONDITION_RESET_IF) ++ { ++ /* if the ResetIf condition is more restrictive than the non-ResetIf condition, ++ and there aren't any hits to clear, ignore it */ ++ if (state->has_hit_targets) ++ continue; ++ } ++ else if (compare_condition->type == RC_CONDITION_MEASURED_IF || condition->type == RC_CONDITION_MEASURED_IF) ++ { ++ /* ignore MeasuredIf redundancies between groups */ ++ if (conditions != compare_conditions) ++ continue; ++ ++ if (compare_condition->type == RC_CONDITION_MEASURED_IF && condition->type != RC_CONDITION_MEASURED_IF) ++ { ++ /* only ever report the redundancy on the non-MeasuredIf condition. The MeasuredIf provides ++ * additional functionality. */ ++ continue; ++ } ++ } ++ else if (condition->type == RC_CONDITION_TRIGGER && compare_condition->type != RC_CONDITION_TRIGGER) ++ { ++ /* Trigger is allowed to be redundant with non-trigger conditions as there may be limits that start a ++ * challenge that are further reduced for the completion of the challenge */ ++ continue; ++ } ++ break; ++ ++ default: ++ continue; ++ } ++ ++ /* if condition A conflicts with condition B, condition B will also conflict with ++ * condition A. don't report both. */ ++ { ++ int already_reported = 0; ++ const rc_validation_error_t* error = state->errors; ++ const rc_validation_error_t* stop = state->errors + state->error_count; ++ for (; error < stop; ++error) { ++ if (error->data2 == state->cond_index && error->data1 == state->group_index) { ++ if (error->err == RC_VALIDATION_ERR_REDUNDANT_CONDITION || ++ error->err == RC_VALIDATION_ERR_CONFLICTING_CONDITION) { ++ already_reported = 1; ++ } ++ } ++ } ++ ++ if (already_reported) ++ continue; ++ } ++ ++ rc_validate_add_error(state, (overlap == RC_OVERLAP_REDUNDANT) ? ++ RC_VALIDATION_ERR_REDUNDANT_CONDITION : RC_VALIDATION_ERR_CONFLICTING_CONDITION, ++ group_index, rc_validate_get_condition_index(conditions, condition)); ++ } ++ } ++ ++ return (state->error_count == errors_before); ++} ++ ++static int rc_validate_trigger_internal(const rc_trigger_t* trigger, rc_validation_state_t* state) ++{ ++ rc_condset_t* alt; ++ uint32_t index; ++ ++ state->has_alt_groups = (trigger->alternative != NULL); ++ ++ state->has_hit_targets = trigger->requirement && rc_condset_has_hittargets(trigger->requirement); ++ if (!state->has_hit_targets) { ++ for (alt = trigger->alternative; alt; alt = alt->next) { ++ if (rc_condset_has_hittargets(alt)) { ++ state->has_hit_targets = 1; ++ break; ++ } ++ } ++ } ++ ++ state->group_index = 0; ++ if (rc_validate_condset_internal(trigger->requirement, state)) { ++ /* compare core to itself */ ++ rc_validate_conflicting_conditions(trigger->requirement, trigger->requirement, 0, state); ++ } ++ ++ index = 1; ++ for (alt = trigger->alternative; alt; alt = alt->next, ++index) { ++ state->group_index = index; ++ if (rc_validate_condset_internal(alt, state)) { ++ /* compare alt to itself */ ++ if (!rc_validate_conflicting_conditions(alt, alt, index, state)) ++ continue; ++ ++ /* compare alt to core */ ++ if (!rc_validate_conflicting_conditions(trigger->requirement, alt, 0, state)) ++ continue; ++ ++ /* compare core to alt */ ++ state->group_index = 0; ++ if (!rc_validate_conflicting_conditions(alt, trigger->requirement, index, state)) ++ continue; ++ } ++ } ++ ++ return (state->error_count == 0); ++} ++ ++int rc_validate_trigger(const rc_trigger_t* trigger, char result[], const size_t result_size, uint32_t max_address) ++{ ++ rc_validation_state_t state; ++ memset(&state, 0, sizeof(state)); ++ state.max_address = max_address; ++ ++ result[0] = '\0'; ++ if (!rc_validate_trigger_internal(trigger, &state)) { ++ const rc_validation_error_t* most_severe_error = rc_validate_find_most_severe_error(&state); ++ return rc_validate_format_error(result, result_size, &state, most_severe_error); ++ } ++ ++ return 1; ++} ++ ++int rc_validate_trigger_for_console(const rc_trigger_t* trigger, char result[], const size_t result_size, uint32_t console_id) ++{ ++ rc_validation_state_t state; ++ memset(&state, 0, sizeof(state)); ++ state.console_id = console_id; ++ state.max_address = rc_console_max_address(console_id); ++ ++ result[0] = '\0'; ++ if (!rc_validate_trigger_internal(trigger, &state)) { ++ const rc_validation_error_t* most_severe_error = rc_validate_find_most_severe_error(&state); ++ return rc_validate_format_error(result, result_size, &state, most_severe_error); ++ } ++ ++ return 1; ++} +diff -rupbN melonDS.orig/src/rcheevos/src/rcheevos/rc_validate.h melonDS.ra/src/rcheevos/src/rcheevos/rc_validate.h +--- melonDS.orig/src/rcheevos/src/rcheevos/rc_validate.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rcheevos/rc_validate.h 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,18 @@ ++#ifndef RC_VALIDATE_H ++#define RC_VALIDATE_H ++ ++#include "rc_runtime_types.h" ++ ++#include ++ ++RC_BEGIN_C_DECLS ++ ++int rc_validate_condset(const rc_condset_t* condset, char result[], const size_t result_size, uint32_t max_address); ++int rc_validate_trigger(const rc_trigger_t* trigger, char result[], const size_t result_size, uint32_t max_address); ++ ++int rc_validate_condset_for_console(const rc_condset_t* condset, char result[], const size_t result_size, uint32_t console_id); ++int rc_validate_trigger_for_console(const rc_trigger_t* trigger, char result[], const size_t result_size, uint32_t console_id); ++ ++RC_END_C_DECLS ++ ++#endif /* RC_VALIDATE_H */ +diff -rupbN melonDS.orig/src/rcheevos/src/rcheevos/richpresence.c melonDS.ra/src/rcheevos/src/rcheevos/richpresence.c +--- melonDS.orig/src/rcheevos/src/rcheevos/richpresence.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rcheevos/richpresence.c 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,922 @@ ++#include "rc_internal.h" ++ ++#include "../rc_compat.h" ++ ++#include ++ ++/* special formats only used by rc_richpresence_display_part_t.display_type. must not overlap other RC_FORMAT values */ ++enum { ++ RC_FORMAT_STRING = 101, ++ RC_FORMAT_LOOKUP = 102, ++ RC_FORMAT_UNKNOWN_MACRO = 103, ++ RC_FORMAT_ASCIICHAR = 104, ++ RC_FORMAT_UNICODECHAR = 105 ++}; ++ ++static void rc_alloc_helper_variable_memref_value(rc_richpresence_display_part_t* part, const char* memaddr, int memaddr_len, rc_parse_state_t* parse) { ++ rc_preparse_state_t preparse; ++ const char* test_memaddr = memaddr; ++ rc_condset_t* condset; ++ rc_value_t* value; ++ int32_t size; ++ ++ part->value.type = RC_OPERAND_NONE; ++ ++ /* if the expression can be represented as just a memory reference, do so */ ++ rc_init_preparse_state(&preparse); ++ preparse.parse.existing_memrefs = parse->memrefs; ++ value = RC_ALLOC(rc_value_t, &preparse.parse); ++ rc_parse_value_internal(value, &test_memaddr, &preparse.parse); ++ ++ size = preparse.parse.offset; ++ if (size < 0) { ++ parse->offset = size; ++ rc_destroy_preparse_state(&preparse); ++ return; ++ } ++ ++ /* ensure new needed memrefs are allocated in the primary buffer */ ++ rc_preparse_copy_memrefs(parse, &preparse.memrefs); ++ ++ /* parse the value into the scratch buffer so we can look at it */ ++ rc_reset_parse_state(&preparse.parse, rc_buffer_alloc(&preparse.parse.scratch.buffer, (size_t)size)); ++ preparse.parse.memrefs = parse->memrefs; ++ preparse.parse.existing_memrefs = parse->existing_memrefs; ++ value = RC_ALLOC(rc_value_t, &preparse.parse); ++ test_memaddr = memaddr; ++ rc_parse_value_internal(value, &test_memaddr, &preparse.parse); ++ ++ condset = value->conditions; ++ if (condset && !condset->next) { ++ /* single value - if it's a single Measured clause (including any AddSource/AddAddress helpers), we can ++ * simplify to a memref. If there are supporting clauses like MeasuredIf or ResetIf, we can't */ ++ if (condset->num_measured_conditions == 1 && ++ !condset->num_pause_conditions && !condset->num_reset_conditions && ++ !condset->num_other_conditions && !condset->num_hittarget_conditions) { ++ rc_condition_t* condition = condset->conditions; ++ for (; condition; condition = condition->next) { ++ if (condition->type == RC_CONDITION_MEASURED && condition->required_hits == 0) { ++ memcpy(&part->value, &condition->operand1, sizeof(condition->operand1)); ++ break; ++ } ++ } ++ } ++ } ++ ++ rc_destroy_preparse_state(&preparse); ++ ++ /* could not express value with just a memory reference, create a helper variable */ ++ if (part->value.type == RC_OPERAND_NONE) { ++ value = rc_alloc_variable(memaddr, memaddr_len, parse); ++ if (value) { ++ part->value.value.memref = (rc_memref_t*)&value->value; ++ part->value.type = RC_OPERAND_ADDRESS; ++ part->value.size = RC_MEMSIZE_32_BITS; ++ part->value.memref_access_type = RC_OPERAND_ADDRESS; ++ } ++ } ++} ++ ++static const char* rc_parse_line(const char* line, const char** end, rc_parse_state_t* parse) { ++ const char* nextline; ++ const char* endline; ++ ++ /* get a single line */ ++ nextline = line; ++ while (*nextline && *nextline != '\n') ++ ++nextline; ++ ++ /* if a trailing comment marker (//) exists, the line stops there */ ++ endline = line; ++ while (endline < nextline && (endline[0] != '/' || endline[1] != '/' || (endline > line && endline[-1] == '\\'))) ++ ++endline; ++ ++ if (endline == nextline) { ++ /* trailing whitespace on a line without a comment marker may be significant, just remove the line ending */ ++ if (endline > line && endline[-1] == '\r') ++ --endline; ++ } else { ++ /* remove trailing whitespace before the comment marker */ ++ while (endline > line && isspace((int)((unsigned char*)endline)[-1])) ++ --endline; ++ } ++ ++ /* point end at the first character to ignore, it makes subtraction for length easier */ ++ *end = endline; ++ ++ /* tally the line */ ++ ++parse->lines_read; ++ ++ /* skip the newline character so we're pointing at the next line */ ++ if (*nextline == '\n') ++ ++nextline; ++ ++ return nextline; ++} ++ ++typedef struct rc_richpresence_builtin_macro_t { ++ const char* name; ++ size_t name_len; ++ uint8_t display_type; ++} rc_richpresence_builtin_macro_t; ++ ++static rc_richpresence_display_t* rc_parse_richpresence_display_internal(const char* line, const char* endline, rc_parse_state_t* parse, rc_richpresence_lookup_t* first_lookup) { ++ rc_richpresence_display_t* self; ++ rc_richpresence_display_part_t* part; ++ rc_richpresence_display_part_t** next; ++ rc_richpresence_lookup_t* lookup; ++ const char* ptr; ++ const char* in; ++ char* out; ++ ++ if (endline - line < 1) { ++ parse->offset = RC_MISSING_DISPLAY_STRING; ++ return 0; ++ } ++ ++ { ++ self = RC_ALLOC(rc_richpresence_display_t, parse); ++ memset(self, 0, sizeof(rc_richpresence_display_t)); ++ next = &self->display; ++ } ++ ++ /* break the string up on macros: text @macro() moretext */ ++ do { ++ ptr = line; ++ while (ptr < endline) { ++ if (*ptr == '@' && (ptr == line || ptr[-1] != '\\')) /* ignore escaped @s */ ++ break; ++ ++ ++ptr; ++ } ++ ++ if (ptr > line) { ++ part = RC_ALLOC(rc_richpresence_display_part_t, parse); ++ memset(part, 0, sizeof(rc_richpresence_display_part_t)); ++ *next = part; ++ next = &part->next; ++ ++ /* handle string part */ ++ part->display_type = RC_FORMAT_STRING; ++ part->text = rc_alloc_str(parse, line, (int)(ptr - line)); ++ if (part->text) { ++ /* remove backslashes used for escaping */ ++ in = part->text; ++ while (*in && *in != '\\') ++ ++in; ++ ++ if (*in == '\\') { ++ out = (char*)in++; ++ while (*in) { ++ *out++ = *in++; ++ if (*in == '\\') ++ ++in; ++ } ++ *out = '\0'; ++ } ++ } ++ } ++ ++ if (*ptr == '@') { ++ /* handle macro part */ ++ size_t macro_len; ++ ++ line = ++ptr; ++ while (ptr < endline && *ptr != '(') ++ ++ptr; ++ ++ if (ptr == endline) { ++ parse->offset = RC_MISSING_VALUE; ++ return 0; ++ } ++ ++ macro_len = ptr - line; ++ ++ part = RC_ALLOC(rc_richpresence_display_part_t, parse); ++ memset(part, 0, sizeof(rc_richpresence_display_part_t)); ++ *next = part; ++ next = &part->next; ++ ++ part->display_type = RC_FORMAT_UNKNOWN_MACRO; ++ ++ /* find the lookup and hook it up */ ++ lookup = first_lookup; ++ while (lookup) { ++ if (strncmp(lookup->name, line, macro_len) == 0 && lookup->name[macro_len] == '\0') { ++ part->text = lookup->name; ++ part->lookup = lookup; ++ part->display_type = lookup->format; ++ break; ++ } ++ ++ lookup = lookup->next; ++ } ++ ++ if (!lookup) { ++ static const rc_richpresence_builtin_macro_t builtin_macros[] = { ++ {"Number", 6, RC_FORMAT_VALUE}, ++ {"Score", 5, RC_FORMAT_SCORE}, ++ {"Centiseconds", 12, RC_FORMAT_CENTISECS}, ++ {"Seconds", 7, RC_FORMAT_SECONDS}, ++ {"Minutes", 7, RC_FORMAT_MINUTES}, ++ {"SecondsAsMinutes", 16, RC_FORMAT_SECONDS_AS_MINUTES}, ++ {"ASCIIChar", 9, RC_FORMAT_ASCIICHAR}, ++ {"UnicodeChar", 11, RC_FORMAT_UNICODECHAR}, ++ {"Float1", 6, RC_FORMAT_FLOAT1}, ++ {"Float2", 6, RC_FORMAT_FLOAT2}, ++ {"Float3", 6, RC_FORMAT_FLOAT3}, ++ {"Float4", 6, RC_FORMAT_FLOAT4}, ++ {"Float5", 6, RC_FORMAT_FLOAT5}, ++ {"Float6", 6, RC_FORMAT_FLOAT6}, ++ {"Fixed1", 6, RC_FORMAT_FIXED1}, ++ {"Fixed2", 6, RC_FORMAT_FIXED2}, ++ {"Fixed3", 6, RC_FORMAT_FIXED3}, ++ {"Unsigned", 8, RC_FORMAT_UNSIGNED_VALUE}, ++ {"Unformatted", 11, RC_FORMAT_UNFORMATTED} ++ }; ++ size_t i; ++ ++ for (i = 0; i < sizeof(builtin_macros) / sizeof(builtin_macros[0]); ++i) { ++ if (macro_len == builtin_macros[i].name_len && ++ memcmp(builtin_macros[i].name, line, builtin_macros[i].name_len) == 0) { ++ part->text = builtin_macros[i].name; ++ part->lookup = NULL; ++ part->display_type = builtin_macros[i].display_type; ++ break; ++ } ++ } ++ } ++ ++ /* find the closing parenthesis */ ++ in = line; ++ line = ++ptr; ++ while (ptr < endline && *ptr != ')') ++ ++ptr; ++ ++ if (*ptr != ')') { ++ /* non-terminated macro, dump the macro and the remaining portion of the line */ ++ --in; /* already skipped over @ */ ++ part->display_type = RC_FORMAT_STRING; ++ part->text = rc_alloc_str(parse, in, (int)(ptr - in)); ++ } ++ else if (part->display_type != RC_FORMAT_UNKNOWN_MACRO) { ++ rc_alloc_helper_variable_memref_value(part, line, (int)(ptr - line), parse); ++ if (parse->offset < 0) ++ return 0; ++ ++ ++ptr; ++ } ++ else { ++ /* assert: the allocated string is going to be smaller than the memory used for the parameter of the macro */ ++ ++ptr; ++ part->text = rc_alloc_str(parse, in, (int)(ptr - in)); ++ } ++ } ++ ++ line = ptr; ++ } while (line < endline); ++ ++ *next = 0; ++ ++ return self; ++} ++ ++static int rc_richpresence_lookup_item_count(rc_richpresence_lookup_item_t* item) ++{ ++ if (item == NULL) ++ return 0; ++ ++ return (rc_richpresence_lookup_item_count(item->left) + rc_richpresence_lookup_item_count(item->right) + 1); ++} ++ ++static void rc_rebalance_richpresence_lookup_get_items(rc_richpresence_lookup_item_t* root, ++ rc_richpresence_lookup_item_t** items, int* index) ++{ ++ if (root->left != NULL) ++ rc_rebalance_richpresence_lookup_get_items(root->left, items, index); ++ ++ items[*index] = root; ++ ++(*index); ++ ++ if (root->right != NULL) ++ rc_rebalance_richpresence_lookup_get_items(root->right, items, index); ++} ++ ++static void rc_rebalance_richpresence_lookup_rebuild(rc_richpresence_lookup_item_t** root, ++ rc_richpresence_lookup_item_t** items, int first, int last) ++{ ++ int mid = (first + last) / 2; ++ rc_richpresence_lookup_item_t* item = items[mid]; ++ *root = item; ++ ++ if (mid == first) ++ item->left = NULL; ++ else ++ rc_rebalance_richpresence_lookup_rebuild(&item->left, items, first, mid - 1); ++ ++ if (mid == last) ++ item->right = NULL; ++ else ++ rc_rebalance_richpresence_lookup_rebuild(&item->right, items, mid + 1, last); ++} ++ ++static void rc_rebalance_richpresence_lookup(rc_richpresence_lookup_item_t** root, rc_parse_state_t* parse) ++{ ++ rc_richpresence_lookup_item_t** items; ++ int index; ++ int size; ++ ++ /* don't bother rebalancing one or two items */ ++ int count = rc_richpresence_lookup_item_count(*root); ++ if (count < 3) ++ return; ++ ++ /* allocate space for the flattened list in scratch memory */ ++ size = count * sizeof(rc_richpresence_lookup_item_t*); ++ items = (rc_richpresence_lookup_item_t**)rc_buffer_alloc(&parse->scratch.buffer, size); ++ ++ /* if allocation fails, we can still use the unbalanced tree, so just bail out */ ++ if (items == NULL) ++ return; ++ ++ /* flatten the list */ ++ index = 0; ++ rc_rebalance_richpresence_lookup_get_items(*root, items, &index); ++ ++ /* and rebuild it as a balanced tree */ ++ rc_rebalance_richpresence_lookup_rebuild(root, items, 0, count - 1); ++} ++ ++static void rc_insert_richpresence_lookup_item(rc_richpresence_lookup_t* lookup, ++ uint32_t first, uint32_t last, const char* label, size_t label_len, rc_parse_state_t* parse) ++{ ++ rc_richpresence_lookup_item_t** next; ++ rc_richpresence_lookup_item_t* item; ++ ++ next = &lookup->root; ++ while ((item = *next) != NULL) { ++ if (first > item->last) { ++ if (first == item->last + 1 && ++ strncmp(label, item->label, label_len) == 0 && item->label[label_len] == '\0') { ++ item->last = last; ++ return; ++ } ++ ++ next = &item->right; ++ } ++ else if (last < item->first) { ++ if (last == item->first - 1 && ++ strncmp(label, item->label, label_len) == 0 && item->label[label_len] == '\0') { ++ item->first = first; ++ return; ++ } ++ ++ next = &item->left; ++ } ++ else { ++ parse->offset = RC_DUPLICATED_VALUE; ++ return; ++ } ++ } ++ ++ item = RC_ALLOC_SCRATCH(rc_richpresence_lookup_item_t, parse); ++ item->first = first; ++ item->last = last; ++ item->label = rc_alloc_str(parse, label, label_len); ++ item->left = item->right = NULL; ++ ++ *next = item; ++} ++ ++static const char* rc_parse_richpresence_lookup(rc_richpresence_lookup_t* lookup, const char* nextline, rc_parse_state_t* parse) ++{ ++ const char* line; ++ const char* endline; ++ const char* label; ++ char* endptr = 0; ++ uint32_t first, last; ++ int base; ++ ++ do ++ { ++ line = nextline; ++ if (line == NULL) ++ break; ++ ++ nextline = rc_parse_line(line, &endline, parse); ++ ++ if (endline - line < 2) { ++ /* ignore full line comments inside a lookup */ ++ if (line[0] == '/' && line[1] == '/') ++ continue; ++ ++ /* empty line indicates end of lookup */ ++ if (lookup->root) ++ rc_rebalance_richpresence_lookup(&lookup->root, parse); ++ break; ++ } ++ ++ /* "*=XXX" specifies default label if lookup does not provide a mapping for the value */ ++ if (line[0] == '*' && line[1] == '=') { ++ line += 2; ++ lookup->default_label = rc_alloc_str(parse, line, (int)(endline - line)); ++ continue; ++ } ++ ++ label = line; ++ while (label < endline && *label != '=') ++ ++label; ++ ++ if (label == endline) { ++ parse->offset = RC_MISSING_VALUE; ++ break; ++ } ++ ++label; ++ ++ do { ++ /* get the value for the mapping */ ++ if (line[0] == '0' && line[1] == 'x') { ++ line += 2; ++ base = 16; ++ } else { ++ base = 10; ++ } ++ ++ first = (unsigned)strtoul(line, &endptr, base); ++ ++ /* check for a range */ ++ if (*endptr != '-') { ++ /* no range, just set last to first */ ++ last = first; ++ } ++ else { ++ /* range, get last value */ ++ line = endptr + 1; ++ ++ if (line[0] == '0' && line[1] == 'x') { ++ line += 2; ++ base = 16; ++ } else { ++ base = 10; ++ } ++ ++ last = (unsigned)strtoul(line, &endptr, base); ++ } ++ ++ /* ignore spaces after the number - was previously ignored as string was split on equals */ ++ while (*endptr == ' ') ++ ++endptr; ++ ++ /* if we've found the equal sign, this is the last item */ ++ if (*endptr == '=') { ++ rc_insert_richpresence_lookup_item(lookup, first, last, label, (int)(endline - label), parse); ++ break; ++ } ++ ++ /* otherwise, if it's not a comma, it's an error */ ++ if (*endptr != ',') { ++ parse->offset = RC_INVALID_CONST_OPERAND; ++ break; ++ } ++ ++ /* insert the current item and continue scanning the next one */ ++ rc_insert_richpresence_lookup_item(lookup, first, last, label, (int)(endline - label), parse); ++ if (parse->offset < 0) ++ break; ++ ++ line = endptr + 1; ++ } while (line < endline); ++ ++ } while (parse->offset > 0); ++ ++ return nextline; ++} ++ ++void rc_parse_richpresence_internal(rc_richpresence_t* self, const char* script, rc_parse_state_t* parse) { ++ rc_richpresence_display_t** nextdisplay; ++ rc_richpresence_lookup_t* firstlookup = NULL; ++ rc_richpresence_lookup_t** nextlookup = &firstlookup; ++ rc_richpresence_lookup_t* lookup; ++ rc_trigger_t* trigger; ++ char format[64]; ++ const char* display = 0; ++ const char* line; ++ const char* nextline; ++ const char* endline; ++ const char* ptr; ++ int hasdisplay = 0; ++ int display_line = 0; ++ int chars; ++ ++ self->values = NULL; ++ ++ /* special case for empty script to return 1 line read */ ++ if (!*script) { ++ parse->lines_read = 1; ++ parse->offset = RC_MISSING_DISPLAY_STRING; ++ return; ++ } ++ ++ /* first pass: process macro initializers */ ++ line = script; ++ while (*line) { ++ nextline = rc_parse_line(line, &endline, parse); ++ if (strncmp(line, "Lookup:", 7) == 0) { ++ line += 7; ++ ++ lookup = RC_ALLOC_SCRATCH(rc_richpresence_lookup_t, parse); ++ lookup->name = rc_alloc_str(parse, line, (int)(endline - line)); ++ lookup->format = RC_FORMAT_LOOKUP; ++ lookup->root = NULL; ++ lookup->default_label = ""; ++ *nextlookup = lookup; ++ nextlookup = &lookup->next; ++ ++ nextline = rc_parse_richpresence_lookup(lookup, nextline, parse); ++ if (parse->offset < 0) ++ return; ++ ++ } else if (strncmp(line, "Format:", 7) == 0) { ++ line += 7; ++ if (endline - line == 11 && memcmp(line, "Unformatted", 11) == 0) { ++ /* for backwards compatibility with the comma rollout, we allow old scripts ++ * to define an Unformatted type mapped to VALUE, and new versions will ignore ++ * the definition and use the built-in macro. skip the next line (FormatType=) */ ++ line = rc_parse_line(nextline, &endline, parse); ++ continue; ++ } ++ ++ lookup = RC_ALLOC_SCRATCH(rc_richpresence_lookup_t, parse); ++ lookup->name = rc_alloc_str(parse, line, (int)(endline - line)); ++ lookup->root = NULL; ++ lookup->default_label = ""; ++ *nextlookup = lookup; ++ nextlookup = &lookup->next; ++ ++ line = nextline; ++ nextline = rc_parse_line(line, &endline, parse); ++ if (parse->buffer && strncmp(line, "FormatType=", 11) == 0) { ++ line += 11; ++ ++ chars = (int)(endline - line); ++ if (chars > 63) ++ chars = 63; ++ memcpy(format, line, chars); ++ format[chars] = '\0'; ++ ++ lookup->format = (uint8_t)rc_parse_format(format); ++ } else { ++ lookup->format = RC_FORMAT_VALUE; ++ } ++ } else if (strncmp(line, "Display:", 8) == 0) { ++ display = nextline; ++ display_line = parse->lines_read; ++ ++ /* scan as long as we find conditional lines or full line comments */ ++ do { ++ line = nextline; ++ nextline = rc_parse_line(line, &endline, parse); ++ } while (*line == '?' || (line[0] == '/' && line[1] == '/')); ++ } ++ ++ line = nextline; ++ } ++ ++ *nextlookup = 0; ++ self->first_lookup = firstlookup; ++ ++ nextdisplay = &self->first_display; ++ ++ /* second pass, process display string*/ ++ if (display) { ++ /* point the parser back at the display strings */ ++ int lines_read = parse->lines_read; ++ parse->lines_read = display_line; ++ line = display; ++ ++ nextline = rc_parse_line(line, &endline, parse); ++ ++ do { ++ if (line[0] == '?') { ++ /* conditional display: ?trigger?string */ ++ ptr = ++line; ++ while (ptr < endline && *ptr != '?') ++ ++ptr; ++ ++ if (ptr < endline) { ++ *nextdisplay = rc_parse_richpresence_display_internal(ptr + 1, endline, parse, firstlookup); ++ if (parse->offset < 0) ++ return; ++ ++ trigger = &((*nextdisplay)->trigger); ++ rc_parse_trigger_internal(trigger, &line, parse); ++ if (parse->offset < 0) ++ return; ++ ++ if (line != ptr) { ++ /* incomplete read */ ++ parse->offset = RC_INVALID_OPERATOR; ++ return; ++ } ++ ++ (*nextdisplay)->has_required_hits = parse->has_required_hits; ++ ++ if (parse->buffer) ++ nextdisplay = &((*nextdisplay)->next); ++ } ++ } ++ else if (line[0] != '/' || line[1] != '/') { ++ break; ++ } ++ ++ line = nextline; ++ nextline = rc_parse_line(line, &endline, parse); ++ } while (1); ++ ++ /* non-conditional display: string */ ++ *nextdisplay = rc_parse_richpresence_display_internal(line, endline, parse, firstlookup); ++ if (*nextdisplay) { ++ hasdisplay = 1; ++ nextdisplay = &((*nextdisplay)->next); ++ ++ /* restore the parser state */ ++ parse->lines_read = lines_read; ++ } ++ else { ++ /* this should only happen if the line is blank. ++ * expect parse->offset to be RC_MISSING_DISPLAY_STRING and leave parse->lines_read ++ * on the current line for error tracking. */ ++ } ++ } ++ ++ /* finalize */ ++ *nextdisplay = 0; ++ self->has_memrefs = 0; ++ ++ if (!hasdisplay && parse->offset > 0) { ++ parse->offset = RC_MISSING_DISPLAY_STRING; ++ } ++} ++ ++int rc_richpresence_size_lines(const char* script, int* lines_read) { ++ rc_richpresence_with_memrefs_t* richpresence; ++ rc_preparse_state_t preparse; ++ rc_init_preparse_state(&preparse); ++ ++ richpresence = RC_ALLOC(rc_richpresence_with_memrefs_t, &preparse.parse); ++ preparse.parse.variables = &richpresence->richpresence.values; ++ rc_parse_richpresence_internal(&richpresence->richpresence, script, &preparse.parse); ++ rc_preparse_alloc_memrefs(NULL, &preparse); ++ ++ if (lines_read) ++ *lines_read = preparse.parse.lines_read; ++ ++ rc_destroy_preparse_state(&preparse); ++ return preparse.parse.offset; ++} ++ ++int rc_richpresence_size(const char* script) { ++ return rc_richpresence_size_lines(script, NULL); ++} ++ ++rc_richpresence_t* rc_parse_richpresence(void* buffer, const char* script, void* unused_L, int unused_funcs_idx) { ++ rc_richpresence_with_memrefs_t* richpresence; ++ rc_preparse_state_t preparse; ++ ++ (void)unused_L; ++ (void)unused_funcs_idx; ++ ++ if (!buffer || !script) ++ return NULL; ++ ++ rc_init_preparse_state(&preparse); ++ richpresence = RC_ALLOC(rc_richpresence_with_memrefs_t, &preparse.parse); ++ preparse.parse.variables = &richpresence->richpresence.values; ++ rc_parse_richpresence_internal(&richpresence->richpresence, script, &preparse.parse); ++ ++ rc_reset_parse_state(&preparse.parse, buffer); ++ richpresence = RC_ALLOC(rc_richpresence_with_memrefs_t, &preparse.parse); ++ preparse.parse.variables = &richpresence->richpresence.values; ++ rc_preparse_alloc_memrefs(&richpresence->memrefs, &preparse); ++ ++ rc_parse_richpresence_internal(&richpresence->richpresence, script, &preparse.parse); ++ richpresence->richpresence.has_memrefs = 1; ++ ++ rc_destroy_preparse_state(&preparse); ++ return (preparse.parse.offset >= 0) ? &richpresence->richpresence : NULL; ++} ++ ++static void rc_update_richpresence_memrefs(rc_richpresence_t* self, rc_peek_t peek, void* ud) { ++ if (self->has_memrefs) { ++ rc_richpresence_with_memrefs_t* richpresence = (rc_richpresence_with_memrefs_t*)self; ++ rc_update_memref_values(&richpresence->memrefs, peek, ud); ++ } ++} ++ ++rc_memrefs_t* rc_richpresence_get_memrefs(rc_richpresence_t* self) { ++ if (self->has_memrefs) { ++ rc_richpresence_with_memrefs_t* richpresence = (rc_richpresence_with_memrefs_t*)self; ++ return &richpresence->memrefs; ++ } ++ ++ return NULL; ++} ++ ++void rc_update_richpresence(rc_richpresence_t* richpresence, rc_peek_t peek, void* peek_ud, void* unused_L) { ++ (void)unused_L; ++ ++ rc_update_richpresence_memrefs(richpresence, peek, peek_ud); ++ rc_update_values(richpresence->values, peek, peek_ud); ++ rc_update_richpresence_internal(richpresence, peek, peek_ud); ++} ++ ++void rc_update_richpresence_internal(rc_richpresence_t* richpresence, rc_peek_t peek, void* peek_ud) { ++ rc_richpresence_display_t* display; ++ ++ for (display = richpresence->first_display; display; display = display->next) { ++ if (display->has_required_hits) ++ rc_test_trigger(&display->trigger, peek, peek_ud, NULL); ++ } ++} ++ ++static int rc_evaluate_richpresence_display(rc_richpresence_display_part_t* part, char* buffer, size_t buffersize) ++{ ++ rc_richpresence_lookup_item_t* item; ++ rc_typed_value_t value; ++ char tmp[256]; ++ char* ptr = buffer; ++ const char* text; ++ size_t chars; ++ ++ *ptr = '\0'; ++ while (part) { ++ switch (part->display_type) { ++ case RC_FORMAT_STRING: ++ text = part->text; ++ chars = strlen(text); ++ break; ++ ++ case RC_FORMAT_LOOKUP: ++ rc_evaluate_operand(&value, &part->value, NULL); ++ rc_typed_value_convert(&value, RC_VALUE_TYPE_UNSIGNED); ++ ++ text = part->lookup->default_label; ++ item = part->lookup->root; ++ while (item) { ++ if (value.value.u32 > item->last) { ++ item = item->right; ++ } ++ else if (value.value.u32 < item->first) { ++ item = item->left; ++ } ++ else { ++ text = item->label; ++ break; ++ } ++ } ++ ++ chars = strlen(text); ++ break; ++ ++ case RC_FORMAT_ASCIICHAR: ++ chars = 0; ++ text = tmp; ++ value.type = RC_VALUE_TYPE_UNSIGNED; ++ ++ do { ++ rc_evaluate_operand(&value, &part->value, NULL); ++ if (value.value.u32 == 0) { ++ /* null terminator - skip over remaining character macros */ ++ while (part->next && part->next->display_type == RC_FORMAT_ASCIICHAR) ++ part = part->next; ++ break; ++ } ++ ++ if (value.value.u32 < 32 || value.value.u32 >= 127) ++ value.value.u32 = '?'; ++ ++ tmp[chars++] = (char)value.value.u32; ++ if (chars == sizeof(tmp) || !part->next || part->next->display_type != RC_FORMAT_ASCIICHAR) ++ break; ++ ++ part = part->next; ++ } while (1); ++ ++ tmp[chars] = '\0'; ++ break; ++ ++ case RC_FORMAT_UNICODECHAR: ++ chars = 0; ++ text = tmp; ++ value.type = RC_VALUE_TYPE_UNSIGNED; ++ ++ do { ++ rc_evaluate_operand(&value, &part->value, NULL); ++ if (value.value.u32 == 0) { ++ /* null terminator - skip over remaining character macros */ ++ while (part->next && part->next->display_type == RC_FORMAT_UNICODECHAR) ++ part = part->next; ++ break; ++ } ++ ++ if (value.value.u32 < 32 || value.value.u32 > 65535) ++ value.value.u32 = 0xFFFD; /* unicode replacement char */ ++ ++ if (value.value.u32 < 0x80) { ++ tmp[chars++] = (char)value.value.u32; ++ } ++ else if (value.value.u32 < 0x0800) { ++ tmp[chars + 1] = (char)(0x80 | (value.value.u32 & 0x3F)); value.value.u32 >>= 6; ++ tmp[chars] = (char)(0xC0 | (value.value.u32 & 0x1F)); ++ chars += 2; ++ } ++ else { ++ /* surrogate pair not supported, convert to replacement char */ ++ if (value.value.u32 >= 0xD800 && value.value.u32 < 0xE000) ++ value.value.u32 = 0xFFFD; ++ ++ tmp[chars + 2] = (char)(0x80 | (value.value.u32 & 0x3F)); value.value.u32 >>= 6; ++ tmp[chars + 1] = (char)(0x80 | (value.value.u32 & 0x3F)); value.value.u32 >>= 6; ++ tmp[chars] = (char)(0xE0 | (value.value.u32 & 0x1F)); ++ chars += 3; ++ } ++ ++ if (chars >= sizeof(tmp) - 3 || !part->next || part->next->display_type != RC_FORMAT_UNICODECHAR) ++ break; ++ ++ part = part->next; ++ } while (1); ++ ++ tmp[chars] = '\0'; ++ break; ++ ++ case RC_FORMAT_UNKNOWN_MACRO: ++ chars = snprintf(tmp, sizeof(tmp), "[Unknown macro]%s", part->text); ++ text = tmp; ++ break; ++ ++ default: ++ rc_evaluate_operand(&value, &part->value, NULL); ++ chars = rc_format_typed_value(tmp, sizeof(tmp), &value, part->display_type); ++ text = tmp; ++ break; ++ } ++ ++ if (chars > 0 && buffersize > 0) { ++ if ((unsigned)chars >= buffersize) { ++ /* prevent write past end of buffer */ ++ memcpy(ptr, text, buffersize - 1); ++ ptr[buffersize - 1] = '\0'; ++ buffersize = 0; ++ } ++ else { ++ memcpy(ptr, text, chars); ++ ptr[chars] = '\0'; ++ buffersize -= (unsigned)chars; ++ } ++ } ++ ++ ptr += chars; ++ part = part->next; ++ } ++ ++ return (int)(ptr - buffer); ++} ++ ++int rc_get_richpresence_display_string(rc_richpresence_t* richpresence, char* buffer, size_t buffersize, rc_peek_t peek, void* peek_ud, void* unused_L) { ++ rc_richpresence_display_t* display; ++ ++ for (display = richpresence->first_display; display; display = display->next) { ++ /* if we've reached the end of the condition list, process it */ ++ if (!display->next) ++ return rc_evaluate_richpresence_display(display->display, buffer, buffersize); ++ ++ /* triggers with required hits will be updated in rc_update_richpresence */ ++ if (!display->has_required_hits) ++ rc_test_trigger(&display->trigger, peek, peek_ud, unused_L); ++ ++ /* if we've found a valid condition, process it */ ++ if (display->trigger.state == RC_TRIGGER_STATE_TRIGGERED) ++ return rc_evaluate_richpresence_display(display->display, buffer, buffersize); ++ } ++ ++ buffer[0] = '\0'; ++ return 0; ++} ++ ++int rc_evaluate_richpresence(rc_richpresence_t* richpresence, char* buffer, size_t buffersize, rc_peek_t peek, void* peek_ud, void* unused_L) { ++ rc_update_richpresence(richpresence, peek, peek_ud, unused_L); ++ return rc_get_richpresence_display_string(richpresence, buffer, buffersize, peek, peek_ud, unused_L); ++} ++ ++void rc_reset_richpresence_triggers(rc_richpresence_t* self) { ++ rc_richpresence_display_t* display; ++ ++ for (display = self->first_display; display; display = display->next) ++ rc_reset_trigger(&display->trigger); ++} ++ ++void rc_reset_richpresence(rc_richpresence_t* self) { ++ rc_reset_richpresence_triggers(self); ++ rc_reset_values(self->values); ++} +diff -rupbN melonDS.orig/src/rcheevos/src/rcheevos/runtime.c melonDS.ra/src/rcheevos/src/rcheevos/runtime.c +--- melonDS.orig/src/rcheevos/src/rcheevos/runtime.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rcheevos/runtime.c 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,852 @@ ++#include "rc_runtime.h" ++#include "rc_internal.h" ++ ++#include "../rc_compat.h" ++#include "../rhash/md5.h" ++ ++#include ++#include ++ ++#define RC_RICHPRESENCE_DISPLAY_BUFFER_SIZE 256 ++ ++/* ===== natvis extensions ===== */ ++ ++typedef struct __rc_runtime_trigger_list_t { rc_runtime_t runtime; } __rc_runtime_trigger_list_t; ++typedef struct __rc_runtime_lboard_list_t { rc_runtime_t runtime; } __rc_runtime_lboard_list_t; ++ ++static void rc_runtime_natvis_helper(const rc_runtime_event_t* runtime_event) ++{ ++ struct natvis_extensions { ++ __rc_runtime_trigger_list_t trigger_list; ++ __rc_runtime_lboard_list_t lboard_list; ++ } natvis; ++ ++ memset(&natvis, 0, sizeof(natvis)); ++ (void)runtime_event; ++ ++ natvis.lboard_list.runtime.lboard_count = 0; ++} ++ ++/* ============================= */ ++ ++rc_runtime_t* rc_runtime_alloc(void) { ++ rc_runtime_t* self; ++ ++ /* create a reference to rc_runtime_natvis_helper so the extensions get compiled in. */ ++ rc_runtime_event_handler_t unused = &rc_runtime_natvis_helper; ++ (void)unused; ++ ++ self = (rc_runtime_t*)malloc(sizeof(rc_runtime_t)); ++ ++ if (self) { ++ rc_runtime_init(self); ++ self->owns_self = 1; ++ } ++ ++ return self; ++} ++ ++void rc_runtime_init(rc_runtime_t* self) { ++ memset(self, 0, sizeof(rc_runtime_t)); ++ ++ self->memrefs = (rc_memrefs_t*)malloc(sizeof(*self->memrefs)); ++ rc_memrefs_init(self->memrefs); ++} ++ ++void rc_runtime_destroy(rc_runtime_t* self) { ++ uint32_t i; ++ ++ if (self->triggers) { ++ for (i = 0; i < self->trigger_count; ++i) { ++ if (self->triggers[i].buffer) ++ free(self->triggers[i].buffer); ++ } ++ ++ free(self->triggers); ++ self->triggers = NULL; ++ ++ self->trigger_count = self->trigger_capacity = 0; ++ } ++ ++ if (self->lboards) { ++ for (i = 0; i < self->lboard_count; ++i) { ++ if (self->lboards[i].buffer) ++ free(self->lboards[i].buffer); ++ } ++ ++ free(self->lboards); ++ self->lboards = NULL; ++ ++ self->lboard_count = self->lboard_capacity = 0; ++ } ++ ++ if (self->richpresence) { ++ if (self->richpresence->buffer) ++ free(self->richpresence->buffer); ++ free(self->richpresence); ++ } ++ ++ if (self->memrefs) ++ rc_memrefs_destroy(self->memrefs); ++ ++ if (self->owns_self) ++ free(self); ++} ++ ++void rc_runtime_checksum(const char* memaddr, uint8_t* md5) { ++ md5_state_t state; ++ md5_init(&state); ++ md5_append(&state, (unsigned char*)memaddr, (int)strlen(memaddr)); ++ md5_finish(&state, md5); ++} ++ ++static void rc_runtime_deactivate_trigger_by_index(rc_runtime_t* self, uint32_t index) { ++ /* free the trigger, then replace it with the last trigger */ ++ free(self->triggers[index].buffer); ++ ++ if (--self->trigger_count > index) ++ memcpy(&self->triggers[index], &self->triggers[self->trigger_count], sizeof(rc_runtime_trigger_t)); ++} ++ ++void rc_runtime_deactivate_achievement(rc_runtime_t* self, uint32_t id) { ++ uint32_t i; ++ ++ for (i = 0; i < self->trigger_count; ++i) { ++ if (self->triggers[i].id == id && self->triggers[i].trigger != NULL) ++ rc_runtime_deactivate_trigger_by_index(self, i); ++ } ++} ++ ++int rc_runtime_activate_achievement(rc_runtime_t* self, uint32_t id, const char* memaddr, void* unused_L, int unused_funcs_idx) { ++ void* trigger_buffer; ++ rc_trigger_t* trigger; ++ rc_runtime_trigger_t* runtime_trigger; ++ rc_preparse_state_t preparse; ++ const char* preparse_memaddr = memaddr; ++ uint8_t md5[16]; ++ int32_t size; ++ uint32_t i; ++ ++ (void)unused_L; ++ (void)unused_funcs_idx; ++ ++ if (memaddr == NULL) ++ return RC_INVALID_MEMORY_OPERAND; ++ ++ rc_runtime_checksum(memaddr, md5); ++ ++ /* check to see if the id is already registered with an active trigger */ ++ for (i = 0; i < self->trigger_count; ++i) { ++ if (self->triggers[i].id == id && self->triggers[i].trigger != NULL) { ++ if (memcmp(self->triggers[i].md5, md5, 16) == 0) { ++ /* if the checksum hasn't changed, we can reuse the existing item */ ++ rc_reset_trigger(self->triggers[i].trigger); ++ return RC_OK; ++ } ++ ++ /* checksum has changed, deactivate the the item */ ++ rc_runtime_deactivate_trigger_by_index(self, i); ++ ++ /* deactivate may reorder the list so we should continue from the current index. however, we ++ * assume that only one trigger is active per id, so having found that, just stop scanning. ++ */ ++ break; ++ } ++ } ++ ++ /* check to see if a disabled trigger for the specific id matches the trigger being registered */ ++ for (i = 0; i < self->trigger_count; ++i) { ++ if (self->triggers[i].id == id && memcmp(self->triggers[i].md5, md5, 16) == 0) { ++ /* retrieve the trigger pointer from the buffer */ ++ size = 0; ++ trigger = (rc_trigger_t*)rc_alloc(self->triggers[i].buffer, &size, sizeof(rc_trigger_t), RC_ALIGNOF(rc_trigger_t), NULL, -1); ++ self->triggers[i].trigger = trigger; ++ ++ rc_reset_trigger(trigger); ++ return RC_OK; ++ } ++ } ++ ++ /* item has not been previously registered, determine how much space we need for it, and allocate it */ ++ rc_init_preparse_state(&preparse); ++ preparse.parse.existing_memrefs = self->memrefs; ++ trigger = RC_ALLOC(rc_trigger_t, &preparse.parse); ++ rc_parse_trigger_internal(trigger, &preparse_memaddr, &preparse.parse); ++ ++ size = preparse.parse.offset; ++ if (size < 0) ++ return size; ++ ++ trigger_buffer = malloc(size); ++ if (!trigger_buffer) ++ return RC_OUT_OF_MEMORY; ++ ++ /* populate the item, using the communal memrefs pool */ ++ rc_reset_parse_state(&preparse.parse, trigger_buffer); ++ rc_preparse_reserve_memrefs(&preparse, self->memrefs); ++ trigger = RC_ALLOC(rc_trigger_t, &preparse.parse); ++ rc_parse_trigger_internal(trigger, &memaddr, &preparse.parse); ++ rc_destroy_preparse_state(&preparse); ++ ++ if (preparse.parse.offset < 0) { ++ free(trigger_buffer); ++ return preparse.parse.offset; ++ } ++ ++ /* grow the trigger buffer if necessary */ ++ if (self->trigger_count == self->trigger_capacity) { ++ self->trigger_capacity += 32; ++ if (!self->triggers) ++ self->triggers = (rc_runtime_trigger_t*)malloc(self->trigger_capacity * sizeof(rc_runtime_trigger_t)); ++ else ++ self->triggers = (rc_runtime_trigger_t*)realloc(self->triggers, self->trigger_capacity * sizeof(rc_runtime_trigger_t)); ++ ++ if (!self->triggers) { ++ free(trigger_buffer); ++ return RC_OUT_OF_MEMORY; ++ } ++ } ++ ++ /* assign the new trigger */ ++ runtime_trigger = &self->triggers[self->trigger_count]; ++ runtime_trigger->id = id; ++ runtime_trigger->trigger = trigger; ++ runtime_trigger->buffer = trigger_buffer; ++ runtime_trigger->invalid_memref = NULL; ++ memcpy(runtime_trigger->md5, md5, 16); ++ runtime_trigger->serialized_size = 0; ++ ++self->trigger_count; ++ ++ /* reset it, and return it */ ++ rc_reset_trigger(trigger); ++ return RC_OK; ++} ++ ++rc_trigger_t* rc_runtime_get_achievement(const rc_runtime_t* self, uint32_t id) ++{ ++ uint32_t i; ++ ++ for (i = 0; i < self->trigger_count; ++i) { ++ if (self->triggers[i].id == id && self->triggers[i].trigger != NULL) ++ return self->triggers[i].trigger; ++ } ++ ++ return NULL; ++} ++ ++int rc_runtime_get_achievement_measured(const rc_runtime_t* runtime, uint32_t id, unsigned* measured_value, unsigned* measured_target) ++{ ++ const rc_trigger_t* trigger = rc_runtime_get_achievement(runtime, id); ++ if (!measured_value || !measured_target) ++ return 0; ++ ++ if (!trigger) { ++ *measured_value = *measured_target = 0; ++ return 0; ++ } ++ ++ if (rc_trigger_state_active(trigger->state)) { ++ *measured_value = (trigger->measured_value == RC_MEASURED_UNKNOWN) ? 0 : trigger->measured_value; ++ *measured_target = trigger->measured_target; ++ } ++ else { ++ /* don't report measured information for inactive triggers */ ++ *measured_value = *measured_target = 0; ++ } ++ ++ return 1; ++} ++ ++int rc_runtime_format_achievement_measured(const rc_runtime_t* runtime, uint32_t id, char* buffer, size_t buffer_size) ++{ ++ const rc_trigger_t* trigger = rc_runtime_get_achievement(runtime, id); ++ uint32_t value; ++ if (!buffer || !buffer_size) ++ return 0; ++ ++ if (!trigger || /* no trigger */ ++ trigger->measured_target == 0 || /* not measured */ ++ !rc_trigger_state_active(trigger->state)) { /* don't report measured value for inactive triggers */ ++ *buffer = '\0'; ++ return 0; ++ } ++ ++ /* cap the value at the target so we can count past the target: "107 >= 100" */ ++ value = (trigger->measured_value == RC_MEASURED_UNKNOWN) ? 0 : trigger->measured_value; ++ if (value > trigger->measured_target) ++ value = trigger->measured_target; ++ ++ if (trigger->measured_as_percent) { ++ const uint32_t percent = (uint32_t)(((unsigned long long)value * 100) / trigger->measured_target); ++ return snprintf(buffer, buffer_size, "%u%%", percent); ++ } ++ ++ return snprintf(buffer, buffer_size, "%u/%u", value, trigger->measured_target); ++} ++ ++static void rc_runtime_deactivate_lboard_by_index(rc_runtime_t* self, uint32_t index) { ++ /* free the lboard, then replace it with the last lboard */ ++ free(self->lboards[index].buffer); ++ ++ if (--self->lboard_count > index) ++ memcpy(&self->lboards[index], &self->lboards[self->lboard_count], sizeof(rc_runtime_lboard_t)); ++} ++ ++void rc_runtime_deactivate_lboard(rc_runtime_t* self, uint32_t id) { ++ uint32_t i; ++ ++ for (i = 0; i < self->lboard_count; ++i) { ++ if (self->lboards[i].id == id && self->lboards[i].lboard != NULL) ++ rc_runtime_deactivate_lboard_by_index(self, i); ++ } ++} ++ ++int rc_runtime_activate_lboard(rc_runtime_t* self, uint32_t id, const char* memaddr, void* unused_L, int unused_funcs_idx) { ++ void* lboard_buffer; ++ uint8_t md5[16]; ++ rc_lboard_t* lboard; ++ rc_preparse_state_t preparse; ++ rc_runtime_lboard_t* runtime_lboard; ++ int32_t size; ++ uint32_t i; ++ ++ (void)unused_L; ++ (void)unused_funcs_idx; ++ ++ if (memaddr == 0) ++ return RC_INVALID_MEMORY_OPERAND; ++ ++ rc_runtime_checksum(memaddr, md5); ++ ++ /* check to see if the id is already registered with an active lboard */ ++ for (i = 0; i < self->lboard_count; ++i) { ++ if (self->lboards[i].id == id && self->lboards[i].lboard != NULL) { ++ if (memcmp(self->lboards[i].md5, md5, 16) == 0) { ++ /* if the checksum hasn't changed, we can reuse the existing item */ ++ rc_reset_lboard(self->lboards[i].lboard); ++ return RC_OK; ++ } ++ ++ /* checksum has changed, deactivate the the item */ ++ rc_runtime_deactivate_lboard_by_index(self, i); ++ ++ /* deactivate may reorder the list so we should continue from the current index. however, we ++ * assume that only one trigger is active per id, so having found that, just stop scanning. ++ */ ++ break; ++ } ++ } ++ ++ /* check to see if a disabled lboard for the specific id matches the lboard being registered */ ++ for (i = 0; i < self->lboard_count; ++i) { ++ if (self->lboards[i].id == id && memcmp(self->lboards[i].md5, md5, 16) == 0) { ++ /* retrieve the lboard pointer from the buffer */ ++ size = 0; ++ lboard = (rc_lboard_t*)rc_alloc(self->lboards[i].buffer, &size, sizeof(rc_lboard_t), RC_ALIGNOF(rc_lboard_t), NULL, -1); ++ self->lboards[i].lboard = lboard; ++ ++ rc_reset_lboard(lboard); ++ return RC_OK; ++ } ++ } ++ ++ /* item has not been previously registered, determine how much space we need for it, and allocate it */ ++ rc_init_preparse_state(&preparse); ++ preparse.parse.existing_memrefs = self->memrefs; ++ lboard = RC_ALLOC(rc_lboard_t, &preparse.parse); ++ rc_parse_lboard_internal(lboard, memaddr, &preparse.parse); ++ ++ size = preparse.parse.offset; ++ if (size < 0) ++ return size; ++ ++ lboard_buffer = malloc(size); ++ if (!lboard_buffer) ++ return RC_OUT_OF_MEMORY; ++ ++ /* populate the item, using the communal memrefs pool */ ++ rc_reset_parse_state(&preparse.parse, lboard_buffer); ++ rc_preparse_reserve_memrefs(&preparse, self->memrefs); ++ lboard = RC_ALLOC(rc_lboard_t, &preparse.parse); ++ rc_parse_lboard_internal(lboard, memaddr, &preparse.parse); ++ rc_destroy_preparse_state(&preparse); ++ ++ if (preparse.parse.offset < 0) { ++ free(lboard_buffer); ++ return preparse.parse.offset; ++ } ++ ++ /* grow the lboard buffer if necessary */ ++ if (self->lboard_count == self->lboard_capacity) { ++ self->lboard_capacity += 16; ++ if (!self->lboards) ++ self->lboards = (rc_runtime_lboard_t*)malloc(self->lboard_capacity * sizeof(rc_runtime_lboard_t)); ++ else ++ self->lboards = (rc_runtime_lboard_t*)realloc(self->lboards, self->lboard_capacity * sizeof(rc_runtime_lboard_t)); ++ ++ if (!self->lboards) { ++ free(lboard_buffer); ++ return RC_OUT_OF_MEMORY; ++ } ++ } ++ ++ /* assign the new lboard */ ++ runtime_lboard = &self->lboards[self->lboard_count++]; ++ runtime_lboard->id = id; ++ runtime_lboard->value = 0; ++ runtime_lboard->lboard = lboard; ++ runtime_lboard->buffer = lboard_buffer; ++ runtime_lboard->invalid_memref = NULL; ++ memcpy(runtime_lboard->md5, md5, 16); ++ runtime_lboard->serialized_size = 0; ++ ++ /* reset it, and return it */ ++ rc_reset_lboard(lboard); ++ return RC_OK; ++} ++ ++rc_lboard_t* rc_runtime_get_lboard(const rc_runtime_t* self, uint32_t id) ++{ ++ uint32_t i; ++ ++ for (i = 0; i < self->lboard_count; ++i) { ++ if (self->lboards[i].id == id && self->lboards[i].lboard != NULL) ++ return self->lboards[i].lboard; ++ } ++ ++ return NULL; ++} ++ ++int rc_runtime_format_lboard_value(char* buffer, int size, int32_t value, int format) ++{ ++ return rc_format_value(buffer, size, value, format); ++} ++ ++int rc_runtime_activate_richpresence(rc_runtime_t* self, const char* script, void* unused_L, int unused_funcs_idx) { ++ rc_richpresence_t* richpresence; ++ rc_preparse_state_t preparse; ++ uint8_t md5[16]; ++ int size; ++ ++ (void)unused_L; ++ (void)unused_funcs_idx; ++ ++ if (script == NULL) ++ return RC_MISSING_DISPLAY_STRING; ++ ++ rc_runtime_checksum(script, md5); ++ ++ /* look for existing match */ ++ if (self->richpresence && self->richpresence->richpresence && memcmp(self->richpresence->md5, md5, 16) == 0) { ++ /* unchanged. reset all of the conditions */ ++ rc_reset_richpresence(self->richpresence->richpresence); ++ ++ /* return success*/ ++ return RC_OK; ++ } ++ ++ /* no existing match found, parse script */ ++ rc_init_preparse_state(&preparse); ++ preparse.parse.existing_memrefs = self->memrefs; ++ richpresence = RC_ALLOC(rc_richpresence_t, &preparse.parse); ++ preparse.parse.variables = &richpresence->values; ++ rc_parse_richpresence_internal(richpresence, script, &preparse.parse); ++ ++ size = preparse.parse.offset; ++ if (size < 0) ++ return size; ++ ++ /* if there's a previous script, free it */ ++ if (self->richpresence) { ++ free(self->richpresence->buffer); ++ free(self->richpresence); ++ } ++ ++ /* allocate and process the new script */ ++ self->richpresence = (rc_runtime_richpresence_t*)malloc(sizeof(rc_runtime_richpresence_t)); ++ if (!self->richpresence) ++ return RC_OUT_OF_MEMORY; ++ ++ memcpy(self->richpresence->md5, md5, sizeof(md5)); ++ ++ self->richpresence->buffer = malloc(size); ++ if (!self->richpresence->buffer) ++ return RC_OUT_OF_MEMORY; ++ ++ rc_reset_parse_state(&preparse.parse, self->richpresence->buffer); ++ rc_preparse_reserve_memrefs(&preparse, self->memrefs); ++ richpresence = RC_ALLOC(rc_richpresence_t, &preparse.parse); ++ preparse.parse.variables = &richpresence->values; ++ rc_parse_richpresence_internal(richpresence, script, &preparse.parse); ++ rc_destroy_preparse_state(&preparse); ++ ++ if (preparse.parse.offset < 0) { ++ free(self->richpresence->buffer); ++ free(self->richpresence); ++ self->richpresence = NULL; ++ return preparse.parse.offset; ++ } ++ ++ if (!richpresence->first_display || !richpresence->first_display->display) { ++ /* non-existant rich presence */ ++ self->richpresence->richpresence = NULL; ++ } ++ else { ++ /* reset all of the conditions */ ++ rc_reset_richpresence(richpresence); ++ self->richpresence->richpresence = richpresence; ++ } ++ ++ return RC_OK; ++} ++ ++int rc_runtime_get_richpresence(const rc_runtime_t* self, char* buffer, size_t buffersize, rc_runtime_peek_t peek, void* peek_ud, void* unused_L) { ++ if (self->richpresence && self->richpresence->richpresence) ++ return rc_get_richpresence_display_string(self->richpresence->richpresence, buffer, buffersize, peek, peek_ud, unused_L); ++ ++ *buffer = '\0'; ++ return 0; ++} ++ ++void rc_runtime_do_frame(rc_runtime_t* self, rc_runtime_event_handler_t event_handler, rc_runtime_peek_t peek, void* ud, void* unused_L) { ++ rc_runtime_event_t runtime_event; ++ int i; ++ ++ runtime_event.value = 0; ++ ++ rc_update_memref_values(self->memrefs, peek, ud); ++ ++ for (i = self->trigger_count - 1; i >= 0; --i) { ++ rc_trigger_t* trigger = self->triggers[i].trigger; ++ int old_state, new_state; ++ uint32_t old_measured_value; ++ ++ if (!trigger) ++ continue; ++ ++ if (self->triggers[i].invalid_memref) { ++ runtime_event.type = RC_RUNTIME_EVENT_ACHIEVEMENT_DISABLED; ++ runtime_event.id = self->triggers[i].id; ++ runtime_event.value = self->triggers[i].invalid_memref->address; ++ ++ trigger->state = RC_TRIGGER_STATE_DISABLED; ++ self->triggers[i].invalid_memref = NULL; ++ ++ event_handler(&runtime_event); ++ ++ runtime_event.value = 0; /* achievement loop expects this to stay at 0 */ ++ continue; ++ } ++ ++ old_measured_value = trigger->measured_value; ++ old_state = trigger->state; ++ new_state = rc_evaluate_trigger(trigger, peek, ud, unused_L); ++ ++ /* trigger->state doesn't actually change to RESET, RESET just serves as a notification. ++ * handle the notification, then look at the actual state */ ++ if (new_state == RC_TRIGGER_STATE_RESET) { ++ runtime_event.type = RC_RUNTIME_EVENT_ACHIEVEMENT_RESET; ++ runtime_event.id = self->triggers[i].id; ++ event_handler(&runtime_event); ++ ++ new_state = trigger->state; ++ } ++ ++ /* if the measured value changed and the achievement hasn't triggered, send a notification */ ++ if (trigger->measured_value != old_measured_value && old_measured_value != RC_MEASURED_UNKNOWN && ++ trigger->measured_target != 0 && trigger->measured_value <= trigger->measured_target && ++ new_state != RC_TRIGGER_STATE_TRIGGERED && ++ new_state != RC_TRIGGER_STATE_INACTIVE && new_state != RC_TRIGGER_STATE_WAITING) { ++ ++ runtime_event.type = RC_RUNTIME_EVENT_ACHIEVEMENT_PROGRESS_UPDATED; ++ runtime_event.id = self->triggers[i].id; ++ ++ if (trigger->measured_as_percent) { ++ /* if reporting measured value as a percentage, only send the notification if the percentage changes */ ++ const int32_t old_percent = (int32_t)(((unsigned long long)old_measured_value * 100) / trigger->measured_target); ++ const int32_t new_percent = (int32_t)(((unsigned long long)trigger->measured_value * 100) / trigger->measured_target); ++ if (old_percent != new_percent) { ++ runtime_event.value = new_percent; ++ event_handler(&runtime_event); ++ } ++ } ++ else { ++ runtime_event.value = trigger->measured_value; ++ event_handler(&runtime_event); ++ } ++ ++ runtime_event.value = 0; /* achievement loop expects this to stay at 0 */ ++ } ++ ++ /* if the state hasn't changed, there won't be any events raised */ ++ if (new_state == old_state) ++ continue; ++ ++ /* raise an UNPRIMED event when changing from PRIMED to anything else */ ++ if (old_state == RC_TRIGGER_STATE_PRIMED) { ++ runtime_event.type = RC_RUNTIME_EVENT_ACHIEVEMENT_UNPRIMED; ++ runtime_event.id = self->triggers[i].id; ++ event_handler(&runtime_event); ++ } ++ ++ /* raise events for each of the possible new states */ ++ switch (new_state) ++ { ++ case RC_TRIGGER_STATE_TRIGGERED: ++ runtime_event.type = RC_RUNTIME_EVENT_ACHIEVEMENT_TRIGGERED; ++ runtime_event.id = self->triggers[i].id; ++ event_handler(&runtime_event); ++ break; ++ ++ case RC_TRIGGER_STATE_PAUSED: ++ runtime_event.type = RC_RUNTIME_EVENT_ACHIEVEMENT_PAUSED; ++ runtime_event.id = self->triggers[i].id; ++ event_handler(&runtime_event); ++ break; ++ ++ case RC_TRIGGER_STATE_PRIMED: ++ runtime_event.type = RC_RUNTIME_EVENT_ACHIEVEMENT_PRIMED; ++ runtime_event.id = self->triggers[i].id; ++ event_handler(&runtime_event); ++ break; ++ ++ case RC_TRIGGER_STATE_ACTIVE: ++ /* only raise ACTIVATED event when transitioning from an inactive state. ++ * note that inactive in this case means active but cannot trigger. */ ++ if (old_state == RC_TRIGGER_STATE_WAITING || old_state == RC_TRIGGER_STATE_PAUSED) { ++ runtime_event.type = RC_RUNTIME_EVENT_ACHIEVEMENT_ACTIVATED; ++ runtime_event.id = self->triggers[i].id; ++ event_handler(&runtime_event); ++ } ++ break; ++ } ++ } ++ ++ for (i = self->lboard_count - 1; i >= 0; --i) { ++ rc_lboard_t* lboard = self->lboards[i].lboard; ++ int lboard_state; ++ ++ if (!lboard) ++ continue; ++ ++ if (self->lboards[i].invalid_memref) { ++ runtime_event.type = RC_RUNTIME_EVENT_LBOARD_DISABLED; ++ runtime_event.id = self->lboards[i].id; ++ runtime_event.value = self->lboards[i].invalid_memref->address; ++ ++ lboard->state = RC_LBOARD_STATE_DISABLED; ++ self->lboards[i].invalid_memref = NULL; ++ ++ event_handler(&runtime_event); ++ continue; ++ } ++ ++ lboard_state = lboard->state; ++ switch (rc_evaluate_lboard(lboard, &runtime_event.value, peek, ud, unused_L)) ++ { ++ case RC_LBOARD_STATE_STARTED: /* leaderboard is running */ ++ if (lboard_state != RC_LBOARD_STATE_STARTED) { ++ self->lboards[i].value = runtime_event.value; ++ ++ runtime_event.type = RC_RUNTIME_EVENT_LBOARD_STARTED; ++ runtime_event.id = self->lboards[i].id; ++ event_handler(&runtime_event); ++ } ++ else if (runtime_event.value != self->lboards[i].value) { ++ self->lboards[i].value = runtime_event.value; ++ ++ runtime_event.type = RC_RUNTIME_EVENT_LBOARD_UPDATED; ++ runtime_event.id = self->lboards[i].id; ++ event_handler(&runtime_event); ++ } ++ break; ++ ++ case RC_LBOARD_STATE_CANCELED: ++ if (lboard_state != RC_LBOARD_STATE_CANCELED) { ++ runtime_event.type = RC_RUNTIME_EVENT_LBOARD_CANCELED; ++ runtime_event.id = self->lboards[i].id; ++ event_handler(&runtime_event); ++ } ++ break; ++ ++ case RC_LBOARD_STATE_TRIGGERED: ++ if (lboard_state != RC_RUNTIME_EVENT_LBOARD_TRIGGERED) { ++ runtime_event.type = RC_RUNTIME_EVENT_LBOARD_TRIGGERED; ++ runtime_event.id = self->lboards[i].id; ++ event_handler(&runtime_event); ++ } ++ break; ++ } ++ } ++ ++ if (self->richpresence && self->richpresence->richpresence) ++ rc_update_richpresence(self->richpresence->richpresence, peek, ud, unused_L); ++} ++ ++void rc_runtime_reset(rc_runtime_t* self) { ++ uint32_t i; ++ ++ for (i = 0; i < self->trigger_count; ++i) { ++ if (self->triggers[i].trigger) ++ rc_reset_trigger(self->triggers[i].trigger); ++ } ++ ++ for (i = 0; i < self->lboard_count; ++i) { ++ if (self->lboards[i].lboard) ++ rc_reset_lboard(self->lboards[i].lboard); ++ } ++ ++ if (self->richpresence && self->richpresence->richpresence) ++ rc_reset_richpresence(self->richpresence->richpresence); ++} ++ ++static int rc_condset_contains_memref(const rc_condset_t* condset, const rc_memref_t* memref) { ++ rc_condition_t* cond; ++ if (!condset) ++ return 0; ++ ++ for (cond = condset->conditions; cond; cond = cond->next) { ++ if (rc_operand_is_memref(&cond->operand1) && cond->operand1.value.memref == memref) ++ return 1; ++ if (rc_operand_is_memref(&cond->operand2) && cond->operand2.value.memref == memref) ++ return 1; ++ } ++ ++ return 0; ++} ++ ++int rc_value_contains_memref(const rc_value_t* value, const rc_memref_t* memref) { ++ rc_condset_t* condset; ++ if (!value) ++ return 0; ++ ++ for (condset = value->conditions; condset; condset = condset->next) { ++ if (rc_condset_contains_memref(condset, memref)) ++ return 1; ++ } ++ ++ return 0; ++} ++ ++int rc_trigger_contains_memref(const rc_trigger_t* trigger, const rc_memref_t* memref) { ++ rc_condset_t* condset; ++ if (!trigger) ++ return 0; ++ ++ if (rc_condset_contains_memref(trigger->requirement, memref)) ++ return 1; ++ ++ for (condset = trigger->alternative; condset; condset = condset->next) { ++ if (rc_condset_contains_memref(condset, memref)) ++ return 1; ++ } ++ ++ return 0; ++} ++ ++static void rc_runtime_invalidate_memref(rc_runtime_t* self, rc_memref_t* memref) { ++ uint32_t i; ++ ++ /* disable any achievements dependent on the address */ ++ for (i = 0; i < self->trigger_count; ++i) { ++ if (!self->triggers[i].invalid_memref && rc_trigger_contains_memref(self->triggers[i].trigger, memref)) ++ self->triggers[i].invalid_memref = memref; ++ } ++ ++ /* disable any leaderboards dependent on the address */ ++ for (i = 0; i < self->lboard_count; ++i) { ++ if (!self->lboards[i].invalid_memref) { ++ rc_lboard_t* lboard = self->lboards[i].lboard; ++ if (lboard) { ++ if (rc_trigger_contains_memref(&lboard->start, memref)) { ++ lboard->start.state = RC_TRIGGER_STATE_DISABLED; ++ self->lboards[i].invalid_memref = memref; ++ } ++ ++ if (rc_trigger_contains_memref(&lboard->cancel, memref)) { ++ lboard->cancel.state = RC_TRIGGER_STATE_DISABLED; ++ self->lboards[i].invalid_memref = memref; ++ } ++ ++ if (rc_trigger_contains_memref(&lboard->submit, memref)) { ++ lboard->submit.state = RC_TRIGGER_STATE_DISABLED; ++ self->lboards[i].invalid_memref = memref; ++ } ++ ++ if (rc_value_contains_memref(&lboard->value, memref)) ++ self->lboards[i].invalid_memref = memref; ++ } ++ } ++ } ++} ++ ++void rc_runtime_invalidate_address(rc_runtime_t* self, uint32_t address) { ++ rc_memref_list_t* memref_list = &self->memrefs->memrefs; ++ do { ++ rc_memref_t* memref = memref_list->items; ++ const rc_memref_t* memref_stop = memref + memref_list->count; ++ ++ for (; memref < memref_stop; ++memref) { ++ if (memref->address == address) { ++ memref->value.type = RC_VALUE_TYPE_NONE; ++ rc_runtime_invalidate_memref(self, memref); ++ } ++ } ++ ++ memref_list = memref_list->next; ++ } while (memref_list); ++} ++ ++void rc_runtime_validate_addresses(rc_runtime_t* self, rc_runtime_event_handler_t event_handler, ++ rc_runtime_validate_address_t validate_handler) { ++ int num_invalid = 0; ++ rc_memref_list_t* memref_list = &self->memrefs->memrefs; ++ do { ++ rc_memref_t* memref = memref_list->items; ++ const rc_memref_t* memref_stop = memref + memref_list->count; ++ ++ for (; memref < memref_stop; ++memref) { ++ if (!validate_handler(memref->address)) { ++ memref->value.type = RC_VALUE_TYPE_NONE; ++ rc_runtime_invalidate_memref(self, memref); ++ ++ ++num_invalid; ++ } ++ } ++ ++ memref_list = memref_list->next; ++ } while (memref_list); ++ ++ if (num_invalid) { ++ rc_runtime_event_t runtime_event; ++ int i; ++ ++ for (i = self->trigger_count - 1; i >= 0; --i) { ++ rc_trigger_t* trigger = self->triggers[i].trigger; ++ if (trigger && self->triggers[i].invalid_memref) { ++ runtime_event.type = RC_RUNTIME_EVENT_ACHIEVEMENT_DISABLED; ++ runtime_event.id = self->triggers[i].id; ++ runtime_event.value = self->triggers[i].invalid_memref->address; ++ ++ trigger->state = RC_TRIGGER_STATE_DISABLED; ++ self->triggers[i].invalid_memref = NULL; ++ ++ event_handler(&runtime_event); ++ } ++ } ++ ++ for (i = self->lboard_count - 1; i >= 0; --i) { ++ rc_lboard_t* lboard = self->lboards[i].lboard; ++ if (lboard && self->lboards[i].invalid_memref) { ++ runtime_event.type = RC_RUNTIME_EVENT_LBOARD_DISABLED; ++ runtime_event.id = self->lboards[i].id; ++ runtime_event.value = self->lboards[i].invalid_memref->address; ++ ++ lboard->state = RC_LBOARD_STATE_DISABLED; ++ self->lboards[i].invalid_memref = NULL; ++ ++ event_handler(&runtime_event); ++ } ++ } ++ } ++} +diff -rupbN melonDS.orig/src/rcheevos/src/rcheevos/runtime_progress.c melonDS.ra/src/rcheevos/src/rcheevos/runtime_progress.c +--- melonDS.orig/src/rcheevos/src/rcheevos/runtime_progress.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rcheevos/runtime_progress.c 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,1073 @@ ++#include "rc_runtime.h" ++#include "rc_internal.h" ++ ++#include "rc_util.h" ++#include "../rhash/md5.h" ++ ++#include ++#include ++#include ++ ++#define RC_RUNTIME_MARKER 0x0A504152 /* RAP\n */ ++ ++#define RC_RUNTIME_CHUNK_MEMREFS 0x4645524D /* MREF */ ++#define RC_RUNTIME_CHUNK_VARIABLES 0x53524156 /* VARS */ ++#define RC_RUNTIME_CHUNK_ACHIEVEMENT 0x56484341 /* ACHV */ ++#define RC_RUNTIME_CHUNK_LEADERBOARD 0x4452424C /* LBRD */ ++#define RC_RUNTIME_CHUNK_RICHPRESENCE 0x48434952 /* RICH */ ++ ++#define RC_RUNTIME_CHUNK_DONE 0x454E4F44 /* DONE */ ++ ++#define RC_RUNTIME_MIN_BUFFER_SIZE 4 + 8 + 16 /* RUNTIME_MARKER, CHUNK_DONE, MD5 */ ++ ++typedef struct rc_runtime_progress_t { ++ const rc_runtime_t* runtime; ++ ++ uint32_t offset; ++ uint8_t* buffer; ++ uint32_t buffer_size; ++ ++ uint32_t chunk_size_offset; ++} rc_runtime_progress_t; ++ ++#define assert_chunk_size(expected_size) assert((uint32_t)(progress->offset - progress->chunk_size_offset - 4) == (uint32_t)(expected_size)) ++ ++#define RC_TRIGGER_STATE_UNUPDATED 0x7F ++ ++#define RC_MEMREF_FLAG_CHANGED_THIS_FRAME 0x00010000 ++ ++#define RC_VAR_FLAG_HAS_COND_DATA 0x01000000 ++ ++#define RC_COND_FLAG_IS_TRUE_MASK 0x00000003 ++#define RC_COND_FLAG_OPERAND1_IS_INDIRECT_MEMREF 0x00010000 ++#define RC_COND_FLAG_OPERAND1_MEMREF_CHANGED_THIS_FRAME 0x00020000 ++#define RC_COND_FLAG_OPERAND2_IS_INDIRECT_MEMREF 0x00100000 ++#define RC_COND_FLAG_OPERAND2_MEMREF_CHANGED_THIS_FRAME 0x00200000 ++ ++static void rc_runtime_progress_write_uint(rc_runtime_progress_t* progress, uint32_t value) ++{ ++ if (progress->buffer) { ++ progress->buffer[progress->offset + 0] = value & 0xFF; value >>= 8; ++ progress->buffer[progress->offset + 1] = value & 0xFF; value >>= 8; ++ progress->buffer[progress->offset + 2] = value & 0xFF; value >>= 8; ++ progress->buffer[progress->offset + 3] = value & 0xFF; ++ } ++ ++ progress->offset += 4; ++} ++ ++static uint32_t rc_runtime_progress_read_uint(rc_runtime_progress_t* progress) ++{ ++ uint32_t value = progress->buffer[progress->offset + 0] | ++ (progress->buffer[progress->offset + 1] << 8) | ++ (progress->buffer[progress->offset + 2] << 16) | ++ (progress->buffer[progress->offset + 3] << 24); ++ ++ progress->offset += 4; ++ return value; ++} ++ ++static void rc_runtime_progress_write_md5(rc_runtime_progress_t* progress, uint8_t* md5) ++{ ++ if (progress->buffer) ++ memcpy(&progress->buffer[progress->offset], md5, 16); ++ ++ progress->offset += 16; ++} ++ ++static int rc_runtime_progress_match_md5(rc_runtime_progress_t* progress, uint8_t* md5) ++{ ++ int result = 0; ++ if (progress->buffer) ++ result = (memcmp(&progress->buffer[progress->offset], md5, 16) == 0); ++ ++ progress->offset += 16; ++ ++ return result; ++} ++ ++static void rc_runtime_progress_start_chunk(rc_runtime_progress_t* progress, uint32_t chunk_id) ++{ ++ rc_runtime_progress_write_uint(progress, chunk_id); ++ ++ progress->chunk_size_offset = progress->offset; ++ ++ progress->offset += 4; ++} ++ ++static void rc_runtime_progress_end_chunk(rc_runtime_progress_t* progress) ++{ ++ uint32_t length; ++ uint32_t offset; ++ ++ progress->offset = (progress->offset + 3) & ~0x03; /* align to 4 byte boundary */ ++ ++ if (progress->buffer) { ++ /* ignore chunk size field when calculating chunk size */ ++ length = (uint32_t)(progress->offset - progress->chunk_size_offset - 4); ++ ++ /* temporarily update the write pointer to write the chunk size field */ ++ offset = progress->offset; ++ progress->offset = progress->chunk_size_offset; ++ rc_runtime_progress_write_uint(progress, length); ++ progress->offset = offset; ++ } ++} ++ ++static void rc_runtime_progress_init(rc_runtime_progress_t* progress, const rc_runtime_t* runtime) ++{ ++ memset(progress, 0, sizeof(rc_runtime_progress_t)); ++ progress->runtime = runtime; ++} ++ ++#define RC_RUNTIME_SERIALIZED_MEMREF_SIZE 16 /* 4x uint: address, flags, value, prior */ ++ ++static int rc_runtime_progress_write_memrefs(rc_runtime_progress_t* progress) ++{ ++ uint32_t count = rc_memrefs_count_memrefs(progress->runtime->memrefs); ++ if (count == 0) ++ return RC_OK; ++ ++ if (progress->offset + 8 + count * RC_RUNTIME_SERIALIZED_MEMREF_SIZE > progress->buffer_size) ++ return RC_INSUFFICIENT_BUFFER; ++ ++ rc_runtime_progress_start_chunk(progress, RC_RUNTIME_CHUNK_MEMREFS); ++ ++ if (!progress->buffer) { ++ progress->offset += count * RC_RUNTIME_SERIALIZED_MEMREF_SIZE; ++ } ++ else { ++ uint32_t flags = 0; ++ const rc_memref_list_t* memref_list = &progress->runtime->memrefs->memrefs; ++ const rc_memref_t* memref; ++ ++ for (; memref_list; memref_list = memref_list->next) { ++ const rc_memref_t* memref_end; ++ ++ memref = memref_list->items; ++ memref_end = memref + memref_list->count; ++ for (; memref < memref_end; ++memref) { ++ flags = memref->value.size; ++ if (memref->value.changed) ++ flags |= RC_MEMREF_FLAG_CHANGED_THIS_FRAME; ++ ++ rc_runtime_progress_write_uint(progress, memref->address); ++ rc_runtime_progress_write_uint(progress, flags); ++ rc_runtime_progress_write_uint(progress, memref->value.value); ++ rc_runtime_progress_write_uint(progress, memref->value.prior); ++ } ++ } ++ } ++ ++ assert_chunk_size(count * RC_RUNTIME_SERIALIZED_MEMREF_SIZE); ++ rc_runtime_progress_end_chunk(progress); ++ return RC_OK; ++} ++ ++static void rc_runtime_progress_update_modified_memrefs(rc_runtime_progress_t* progress) ++{ ++ rc_typed_value_t value, prior_value, modifier, prior_modifier; ++ rc_modified_memref_list_t* modified_memref_list; ++ rc_modified_memref_t* modified_memref; ++ rc_operand_t prior_parent_operand, prior_modifier_operand; ++ rc_memref_t prior_parent_memref, prior_modifier_memref; ++ ++ modified_memref_list = &progress->runtime->memrefs->modified_memrefs; ++ for (; modified_memref_list; modified_memref_list = modified_memref_list->next) { ++ const rc_modified_memref_t* modified_memref_end; ++ modified_memref = modified_memref_list->items; ++ modified_memref_end = modified_memref + modified_memref_list->count; ++ for (; modified_memref < modified_memref_end; ++modified_memref) { ++ modified_memref->memref.value.changed = 0; ++ ++ /* indirect memref values are stored in conditions */ ++ if (modified_memref->modifier_type == RC_OPERATOR_INDIRECT_READ) ++ continue; ++ ++ /* non-indirect memref values can be reconstructed from the parents */ ++ memcpy(&prior_parent_operand, &modified_memref->parent, sizeof(prior_parent_operand)); ++ if (rc_operand_is_memref(&prior_parent_operand)) { ++ memcpy(&prior_parent_memref, modified_memref->parent.value.memref, sizeof(prior_parent_memref)); ++ prior_parent_memref.value.value = prior_parent_memref.value.prior; ++ modified_memref->memref.value.changed |= prior_parent_memref.value.changed; ++ prior_parent_operand.value.memref = &prior_parent_memref; ++ } ++ ++ memcpy(&prior_modifier_operand, &modified_memref->modifier, sizeof(prior_modifier_operand)); ++ if (rc_operand_is_memref(&prior_modifier_operand)) { ++ memcpy(&prior_modifier_memref, modified_memref->modifier.value.memref, sizeof(prior_modifier_memref)); ++ prior_modifier_memref.value.value = prior_modifier_memref.value.prior; ++ modified_memref->memref.value.changed |= prior_modifier_memref.value.changed; ++ prior_modifier_operand.value.memref = &prior_modifier_memref; ++ } ++ ++ rc_evaluate_operand(&value, &modified_memref->parent, NULL); ++ rc_evaluate_operand(&modifier, &modified_memref->modifier, NULL); ++ rc_evaluate_operand(&prior_value, &prior_parent_operand, NULL); ++ rc_evaluate_operand(&prior_modifier, &prior_modifier_operand, NULL); ++ ++ if (modified_memref->modifier_type == RC_OPERATOR_SUB_PARENT) { ++ rc_typed_value_negate(&value); ++ rc_typed_value_add(&value, &modifier); ++ ++ rc_typed_value_negate(&prior_value); ++ rc_typed_value_add(&prior_value, &prior_modifier); ++ } ++ else { ++ rc_typed_value_combine(&value, &modifier, modified_memref->modifier_type); ++ rc_typed_value_combine(&prior_value, &prior_modifier, modified_memref->modifier_type); ++ } ++ ++ rc_typed_value_convert(&value, modified_memref->memref.value.type); ++ modified_memref->memref.value.value = value.value.u32; ++ ++ rc_typed_value_convert(&prior_value, modified_memref->memref.value.type); ++ modified_memref->memref.value.prior = prior_value.value.u32; ++ } ++ } ++} ++ ++static int rc_runtime_progress_read_memrefs(rc_runtime_progress_t* progress) ++{ ++ uint32_t entries; ++ uint32_t address, flags, value, prior; ++ uint8_t size; ++ rc_memref_list_t* unmatched_memref_list = &progress->runtime->memrefs->memrefs; ++ rc_memref_t* first_unmatched_memref = unmatched_memref_list->items; ++ rc_memref_t* memref; ++ ++ /* re-read the chunk size to determine how many memrefs are present */ ++ progress->offset -= 4; ++ entries = rc_runtime_progress_read_uint(progress) / RC_RUNTIME_SERIALIZED_MEMREF_SIZE; ++ ++ while (entries != 0) { ++ address = rc_runtime_progress_read_uint(progress); ++ flags = rc_runtime_progress_read_uint(progress); ++ value = rc_runtime_progress_read_uint(progress); ++ prior = rc_runtime_progress_read_uint(progress); ++ ++ size = flags & 0xFF; ++ ++ memref = first_unmatched_memref; ++ if (memref->address == address && memref->value.size == size) { ++ memref->value.value = value; ++ memref->value.changed = (flags & RC_MEMREF_FLAG_CHANGED_THIS_FRAME) ? 1 : 0; ++ memref->value.prior = prior; ++ ++ first_unmatched_memref++; ++ if (first_unmatched_memref >= unmatched_memref_list->items + unmatched_memref_list->count) { ++ unmatched_memref_list = unmatched_memref_list->next; ++ if (!unmatched_memref_list) ++ break; ++ first_unmatched_memref = unmatched_memref_list->items; ++ } ++ } ++ else { ++ rc_memref_list_t* memref_list = unmatched_memref_list; ++ do { ++ ++memref; ++ if (memref >= memref_list->items + memref_list->count) { ++ memref_list = memref_list->next; ++ if (!memref_list) ++ break; ++ ++ memref = memref_list->items; ++ } ++ ++ if (memref->address == address && memref->value.size == size) { ++ memref->value.value = value; ++ memref->value.changed = (flags & RC_MEMREF_FLAG_CHANGED_THIS_FRAME) ? 1 : 0; ++ memref->value.prior = prior; ++ break; ++ } ++ ++ } while (1); ++ } ++ ++ --entries; ++ } ++ ++ rc_runtime_progress_update_modified_memrefs(progress); ++ ++ return RC_OK; ++} ++ ++static int rc_runtime_progress_is_indirect_memref(rc_operand_t* oper) ++{ ++ switch (oper->type) ++ { ++ case RC_OPERAND_CONST: ++ case RC_OPERAND_FP: ++ case RC_OPERAND_RECALL: ++ case RC_OPERAND_FUNC: ++ return 0; ++ ++ default: ++ if (oper->value.memref->value.memref_type != RC_MEMREF_TYPE_MODIFIED_MEMREF) ++ return 0; ++ ++ return ((const rc_modified_memref_t*)oper->value.memref)->modifier_type == RC_OPERATOR_INDIRECT_READ; ++ } ++} ++ ++static int rc_runtime_progress_write_condset(rc_runtime_progress_t* progress, rc_condset_t* condset) ++{ ++ rc_condition_t* cond; ++ uint32_t flags; ++ ++ if (progress->offset + 4 > progress->buffer_size) ++ return RC_INSUFFICIENT_BUFFER; ++ ++ rc_runtime_progress_write_uint(progress, condset->is_paused); ++ ++ cond = condset->conditions; ++ while (cond) { ++ flags = (cond->is_true & RC_COND_FLAG_IS_TRUE_MASK); ++ ++ if (rc_runtime_progress_is_indirect_memref(&cond->operand1)) { ++ flags |= RC_COND_FLAG_OPERAND1_IS_INDIRECT_MEMREF; ++ if (cond->operand1.value.memref->value.changed) ++ flags |= RC_COND_FLAG_OPERAND1_MEMREF_CHANGED_THIS_FRAME; ++ } ++ ++ if (rc_runtime_progress_is_indirect_memref(&cond->operand2)) { ++ flags |= RC_COND_FLAG_OPERAND2_IS_INDIRECT_MEMREF; ++ if (cond->operand2.value.memref->value.changed) ++ flags |= RC_COND_FLAG_OPERAND2_MEMREF_CHANGED_THIS_FRAME; ++ } ++ ++ if (progress->offset + 8 > progress->buffer_size) ++ return RC_INSUFFICIENT_BUFFER; ++ ++ rc_runtime_progress_write_uint(progress, cond->current_hits); ++ rc_runtime_progress_write_uint(progress, flags); ++ ++ if (flags & RC_COND_FLAG_OPERAND1_IS_INDIRECT_MEMREF) { ++ if (progress->offset + 8 > progress->buffer_size) ++ return RC_INSUFFICIENT_BUFFER; ++ ++ rc_runtime_progress_write_uint(progress, cond->operand1.value.memref->value.value); ++ rc_runtime_progress_write_uint(progress, cond->operand1.value.memref->value.prior); ++ } ++ ++ if (flags & RC_COND_FLAG_OPERAND2_IS_INDIRECT_MEMREF) { ++ if (progress->offset + 8 > progress->buffer_size) ++ return RC_INSUFFICIENT_BUFFER; ++ ++ rc_runtime_progress_write_uint(progress, cond->operand2.value.memref->value.value); ++ rc_runtime_progress_write_uint(progress, cond->operand2.value.memref->value.prior); ++ } ++ ++ cond = cond->next; ++ } ++ ++ return RC_OK; ++} ++ ++static int rc_runtime_progress_read_condset(rc_runtime_progress_t* progress, rc_condset_t* condset) ++{ ++ rc_condition_t* cond; ++ uint32_t flags; ++ ++ condset->is_paused = (char)rc_runtime_progress_read_uint(progress); ++ ++ cond = condset->conditions; ++ while (cond) { ++ cond->current_hits = rc_runtime_progress_read_uint(progress); ++ flags = rc_runtime_progress_read_uint(progress); ++ ++ cond->is_true = (flags & RC_COND_FLAG_IS_TRUE_MASK); ++ ++ if (flags & RC_COND_FLAG_OPERAND1_IS_INDIRECT_MEMREF) { ++ if (!rc_operand_is_memref(&cond->operand1)) /* this should never happen, but better safe than sorry */ ++ return RC_INVALID_STATE; ++ ++ cond->operand1.value.memref->value.value = rc_runtime_progress_read_uint(progress); ++ cond->operand1.value.memref->value.prior = rc_runtime_progress_read_uint(progress); ++ cond->operand1.value.memref->value.changed = (flags & RC_COND_FLAG_OPERAND1_MEMREF_CHANGED_THIS_FRAME) ? 1 : 0; ++ } ++ ++ if (flags & RC_COND_FLAG_OPERAND2_IS_INDIRECT_MEMREF) { ++ if (!rc_operand_is_memref(&cond->operand2)) /* this should never happen, but better safe than sorry */ ++ return RC_INVALID_STATE; ++ ++ cond->operand2.value.memref->value.value = rc_runtime_progress_read_uint(progress); ++ cond->operand2.value.memref->value.prior = rc_runtime_progress_read_uint(progress); ++ cond->operand2.value.memref->value.changed = (flags & RC_COND_FLAG_OPERAND2_MEMREF_CHANGED_THIS_FRAME) ? 1 : 0; ++ } ++ ++ cond = cond->next; ++ } ++ ++ return RC_OK; ++} ++ ++static uint32_t rc_runtime_progress_should_serialize_variable_condset(const rc_condset_t* conditions) ++{ ++ const rc_condition_t* condition; ++ ++ /* predetermined presence of pause flag - must serialize */ ++ if (conditions->has_pause) ++ return RC_VAR_FLAG_HAS_COND_DATA; ++ ++ /* if any conditions has required hits, must serialize */ ++ /* ASSERT: Measured with comparison and no explicit target will set hit target to 0xFFFFFFFF */ ++ for (condition = conditions->conditions; condition; condition = condition->next) { ++ if (condition->required_hits > 0) ++ return RC_VAR_FLAG_HAS_COND_DATA; ++ } ++ ++ /* can safely be reset without affecting behavior */ ++ return 0; ++} ++ ++static int rc_runtime_progress_write_variable(rc_runtime_progress_t* progress, const rc_value_t* variable) ++{ ++ uint32_t flags; ++ ++ if (progress->offset + 12 > progress->buffer_size) ++ return RC_INSUFFICIENT_BUFFER; ++ ++ flags = rc_runtime_progress_should_serialize_variable_condset(variable->conditions); ++ if (variable->value.changed) ++ flags |= RC_MEMREF_FLAG_CHANGED_THIS_FRAME; ++ ++ rc_runtime_progress_write_uint(progress, flags); ++ rc_runtime_progress_write_uint(progress, variable->value.value); ++ rc_runtime_progress_write_uint(progress, variable->value.prior); ++ ++ if (flags & RC_VAR_FLAG_HAS_COND_DATA) { ++ int result = rc_runtime_progress_write_condset(progress, variable->conditions); ++ if (result != RC_OK) ++ return result; ++ } ++ ++ return RC_OK; ++} ++ ++static int rc_runtime_progress_write_variables(rc_runtime_progress_t* progress) ++{ ++ uint32_t count; ++ const rc_value_t* value; ++ int result; ++ ++ if (!progress->runtime->richpresence || !progress->runtime->richpresence->richpresence) ++ return RC_OK; ++ ++ value = progress->runtime->richpresence->richpresence->values; ++ count = rc_count_values(value); ++ if (count == 0) ++ return RC_OK; ++ ++ /* header + count + count(djb2,flags,value,prior,?cond) */ ++ if (progress->offset + 8 + 4 + count * 16 > progress->buffer_size) ++ return RC_INSUFFICIENT_BUFFER; ++ ++ rc_runtime_progress_start_chunk(progress, RC_RUNTIME_CHUNK_VARIABLES); ++ rc_runtime_progress_write_uint(progress, count); ++ ++ for (; value; value = value->next) { ++ const uint32_t djb2 = rc_djb2(value->name); ++ if (progress->offset + 16 > progress->buffer_size) ++ return RC_INSUFFICIENT_BUFFER; ++ ++ rc_runtime_progress_write_uint(progress, djb2); ++ ++ result = rc_runtime_progress_write_variable(progress, value); ++ if (result != RC_OK) ++ return result; ++ } ++ ++ rc_runtime_progress_end_chunk(progress); ++ return RC_OK; ++} ++ ++static int rc_runtime_progress_read_variable(rc_runtime_progress_t* progress, rc_value_t* variable) ++{ ++ uint32_t flags = rc_runtime_progress_read_uint(progress); ++ variable->value.changed = (flags & RC_MEMREF_FLAG_CHANGED_THIS_FRAME) ? 1 : 0; ++ variable->value.value = rc_runtime_progress_read_uint(progress); ++ variable->value.prior = rc_runtime_progress_read_uint(progress); ++ ++ if (flags & RC_VAR_FLAG_HAS_COND_DATA) { ++ int result = rc_runtime_progress_read_condset(progress, variable->conditions); ++ if (result != RC_OK) ++ return result; ++ } ++ else { ++ rc_reset_condset(variable->conditions); ++ } ++ ++ return RC_OK; ++} ++ ++static int rc_runtime_progress_read_variables(rc_runtime_progress_t* progress) ++{ ++ struct rc_pending_value_t ++ { ++ rc_value_t* variable; ++ uint32_t djb2; ++ }; ++ struct rc_pending_value_t local_pending_variables[32]; ++ struct rc_pending_value_t* pending_variables; ++ rc_value_t* value; ++ uint32_t count, serialized_count; ++ int result; ++ int32_t i; ++ ++ serialized_count = rc_runtime_progress_read_uint(progress); ++ if (serialized_count == 0) ++ return RC_OK; ++ ++ if (!progress->runtime->richpresence || !progress->runtime->richpresence->richpresence) ++ return RC_OK; ++ ++ value = progress->runtime->richpresence->richpresence->values; ++ count = rc_count_values(value); ++ if (count == 0) ++ return RC_OK; ++ ++ if (count <= sizeof(local_pending_variables) / sizeof(local_pending_variables[0])) { ++ pending_variables = local_pending_variables; ++ } ++ else { ++ pending_variables = (struct rc_pending_value_t*)malloc(count * sizeof(struct rc_pending_value_t)); ++ if (pending_variables == NULL) ++ return RC_OUT_OF_MEMORY; ++ } ++ ++ i = (int32_t)count; ++ for (; value; value = value->next) { ++ --i; ++ pending_variables[i].variable = value; ++ pending_variables[i].djb2 = rc_djb2(value->name); ++ } ++ ++ result = RC_OK; ++ for (; serialized_count > 0 && result == RC_OK; --serialized_count) { ++ uint32_t djb2 = rc_runtime_progress_read_uint(progress); ++ for (i = (int32_t)count - 1; i >= 0; --i) { ++ if (pending_variables[i].djb2 == djb2) { ++ value = pending_variables[i].variable; ++ result = rc_runtime_progress_read_variable(progress, value); ++ if (result == RC_OK) { ++ if (i < (int32_t)count - 1) ++ memcpy(&pending_variables[i], &pending_variables[count - 1], sizeof(struct rc_pending_value_t)); ++ count--; ++ } ++ break; ++ } ++ } ++ } ++ ++ /* VS raises a C6385 warning here because it thinks count can exceed the size of the local_pending_variables array. ++ * When count is larger, pending_variables points to allocated memory, so the warning is wrong. */ ++#if defined (_MSC_VER) ++ #pragma warning(push) ++ #pragma warning(disable:6385) ++#endif ++ while (count > 0) ++ rc_reset_value(pending_variables[--count].variable); ++#if defined (_MSC_VER) ++ #pragma warning(pop) ++#endif ++ ++ if (pending_variables != local_pending_variables) ++ free(pending_variables); ++ ++ return result; ++} ++ ++static int rc_runtime_progress_write_trigger(rc_runtime_progress_t* progress, const rc_trigger_t* trigger) ++{ ++ rc_condset_t* condset; ++ int result; ++ ++ rc_runtime_progress_write_uint(progress, trigger->state); ++ rc_runtime_progress_write_uint(progress, trigger->measured_value); ++ ++ if (trigger->requirement) { ++ result = rc_runtime_progress_write_condset(progress, trigger->requirement); ++ if (result != RC_OK) ++ return result; ++ } ++ ++ condset = trigger->alternative; ++ while (condset) { ++ result = rc_runtime_progress_write_condset(progress, condset); ++ if (result != RC_OK) ++ return result; ++ ++ condset = condset->next; ++ } ++ ++ return RC_OK; ++} ++ ++static int rc_runtime_progress_read_trigger(rc_runtime_progress_t* progress, rc_trigger_t* trigger) ++{ ++ rc_condset_t* condset; ++ int result; ++ ++ trigger->state = (char)rc_runtime_progress_read_uint(progress); ++ trigger->measured_value = rc_runtime_progress_read_uint(progress); ++ ++ if (trigger->requirement) { ++ result = rc_runtime_progress_read_condset(progress, trigger->requirement); ++ if (result != RC_OK) ++ return result; ++ } ++ ++ condset = trigger->alternative; ++ while (condset) { ++ result = rc_runtime_progress_read_condset(progress, condset); ++ if (result != RC_OK) ++ return result; ++ ++ condset = condset->next; ++ } ++ ++ return RC_OK; ++} ++ ++static int rc_runtime_progress_write_achievements(rc_runtime_progress_t* progress) ++{ ++ uint32_t i; ++ int initial_offset = 0; ++ int result; ++ ++ for (i = 0; i < progress->runtime->trigger_count; ++i) { ++ rc_runtime_trigger_t* runtime_trigger = &progress->runtime->triggers[i]; ++ if (!runtime_trigger->trigger) ++ continue; ++ ++ /* don't store state for inactive or triggered achievements */ ++ if (!rc_trigger_state_active(runtime_trigger->trigger->state)) ++ continue; ++ ++ if (!progress->buffer) { ++ if (runtime_trigger->serialized_size) { ++ progress->offset += runtime_trigger->serialized_size; ++ continue; ++ } ++ ++ initial_offset = progress->offset; ++ } else { ++ if (progress->offset + runtime_trigger->serialized_size > progress->buffer_size) ++ return RC_INSUFFICIENT_BUFFER; ++ } ++ ++ rc_runtime_progress_start_chunk(progress, RC_RUNTIME_CHUNK_ACHIEVEMENT); ++ rc_runtime_progress_write_uint(progress, runtime_trigger->id); ++ rc_runtime_progress_write_md5(progress, runtime_trigger->md5); ++ ++ result = rc_runtime_progress_write_trigger(progress, runtime_trigger->trigger); ++ if (result != RC_OK) ++ return result; ++ ++ if (runtime_trigger->serialized_size) { ++ /* runtime_trigger->serialized_size includes the header */ ++ assert_chunk_size(runtime_trigger->serialized_size - 8); ++ } ++ ++ rc_runtime_progress_end_chunk(progress); ++ ++ if (!progress->buffer) ++ runtime_trigger->serialized_size = progress->offset - initial_offset; ++ } ++ ++ return RC_OK; ++} ++ ++static int rc_runtime_progress_read_achievement(rc_runtime_progress_t* progress) ++{ ++ uint32_t id = rc_runtime_progress_read_uint(progress); ++ uint32_t i; ++ ++ for (i = 0; i < progress->runtime->trigger_count; ++i) { ++ rc_runtime_trigger_t* runtime_trigger = &progress->runtime->triggers[i]; ++ if (runtime_trigger->id == id && runtime_trigger->trigger != NULL) { ++ /* ignore triggered and waiting achievements */ ++ if (runtime_trigger->trigger->state == RC_TRIGGER_STATE_UNUPDATED) { ++ /* only update state if definition hasn't changed (md5 matches) */ ++ if (rc_runtime_progress_match_md5(progress, runtime_trigger->md5)) ++ return rc_runtime_progress_read_trigger(progress, runtime_trigger->trigger); ++ break; ++ } ++ } ++ } ++ ++ return RC_OK; ++} ++ ++static int rc_runtime_progress_write_leaderboards(rc_runtime_progress_t* progress) ++{ ++ uint32_t i; ++ uint32_t flags; ++ int initial_offset = 0; ++ int result; ++ ++ for (i = 0; i < progress->runtime->lboard_count; ++i) { ++ rc_runtime_lboard_t* runtime_lboard = &progress->runtime->lboards[i]; ++ if (!runtime_lboard->lboard) ++ continue; ++ ++ /* don't store state for inactive leaderboards */ ++ if (!rc_lboard_state_active(runtime_lboard->lboard->state)) ++ continue; ++ ++ if (!progress->buffer) { ++ if (runtime_lboard->serialized_size) { ++ progress->offset += runtime_lboard->serialized_size; ++ continue; ++ } ++ ++ initial_offset = progress->offset; ++ } else { ++ if (progress->offset + runtime_lboard->serialized_size > progress->buffer_size) ++ return RC_INSUFFICIENT_BUFFER; ++ } ++ ++ rc_runtime_progress_start_chunk(progress, RC_RUNTIME_CHUNK_LEADERBOARD); ++ rc_runtime_progress_write_uint(progress, runtime_lboard->id); ++ rc_runtime_progress_write_md5(progress, runtime_lboard->md5); ++ ++ flags = runtime_lboard->lboard->state; ++ rc_runtime_progress_write_uint(progress, flags); ++ ++ result = rc_runtime_progress_write_trigger(progress, &runtime_lboard->lboard->start); ++ if (result != RC_OK) ++ return result; ++ ++ result = rc_runtime_progress_write_trigger(progress, &runtime_lboard->lboard->submit); ++ if (result != RC_OK) ++ return result; ++ ++ result = rc_runtime_progress_write_trigger(progress, &runtime_lboard->lboard->cancel); ++ if (result != RC_OK) ++ return result; ++ ++ result = rc_runtime_progress_write_variable(progress, &runtime_lboard->lboard->value); ++ if (result != RC_OK) ++ return result; ++ ++ if (runtime_lboard->serialized_size) { ++ /* runtime_lboard->serialized_size includes the header */ ++ assert_chunk_size(runtime_lboard->serialized_size - 8); ++ } ++ ++ rc_runtime_progress_end_chunk(progress); ++ ++ if (!progress->buffer) ++ runtime_lboard->serialized_size = progress->offset - initial_offset; ++ } ++ ++ return RC_OK; ++} ++ ++static int rc_runtime_progress_read_leaderboard(rc_runtime_progress_t* progress) ++{ ++ uint32_t id = rc_runtime_progress_read_uint(progress); ++ uint32_t i; ++ int result; ++ ++ for (i = 0; i < progress->runtime->lboard_count; ++i) { ++ rc_runtime_lboard_t* runtime_lboard = &progress->runtime->lboards[i]; ++ if (runtime_lboard->id == id && runtime_lboard->lboard != NULL) { ++ /* ignore triggered and waiting achievements */ ++ if (runtime_lboard->lboard->state == RC_TRIGGER_STATE_UNUPDATED) { ++ /* only update state if definition hasn't changed (md5 matches) */ ++ if (rc_runtime_progress_match_md5(progress, runtime_lboard->md5)) { ++ uint32_t flags = rc_runtime_progress_read_uint(progress); ++ ++ result = rc_runtime_progress_read_trigger(progress, &runtime_lboard->lboard->start); ++ if (result != RC_OK) ++ return result; ++ ++ result = rc_runtime_progress_read_trigger(progress, &runtime_lboard->lboard->submit); ++ if (result != RC_OK) ++ return result; ++ ++ result = rc_runtime_progress_read_trigger(progress, &runtime_lboard->lboard->cancel); ++ if (result != RC_OK) ++ return result; ++ ++ result = rc_runtime_progress_read_variable(progress, &runtime_lboard->lboard->value); ++ if (result != RC_OK) ++ return result; ++ ++ runtime_lboard->lboard->state = (char)(flags & 0x7F); ++ } ++ break; ++ } ++ } ++ } ++ ++ return RC_OK; ++} ++ ++static int rc_runtime_progress_write_rich_presence(rc_runtime_progress_t* progress) ++{ ++ const rc_richpresence_display_t* display; ++ int result; ++ ++ if (!progress->runtime->richpresence || !progress->runtime->richpresence->richpresence) ++ return RC_OK; ++ ++ /* if there are no conditional display strings, there's nothing to capture */ ++ display = progress->runtime->richpresence->richpresence->first_display; ++ if (!display->next) ++ return RC_OK; ++ ++ if (progress->offset + 8 + 16 > progress->buffer_size) ++ return RC_INSUFFICIENT_BUFFER; ++ ++ rc_runtime_progress_start_chunk(progress, RC_RUNTIME_CHUNK_RICHPRESENCE); ++ rc_runtime_progress_write_md5(progress, progress->runtime->richpresence->md5); ++ ++ for (; display->next; display = display->next) { ++ result = rc_runtime_progress_write_trigger(progress, &display->trigger); ++ if (result != RC_OK) ++ return result; ++ } ++ ++ rc_runtime_progress_end_chunk(progress); ++ return RC_OK; ++} ++ ++static int rc_runtime_progress_read_rich_presence(rc_runtime_progress_t* progress) ++{ ++ rc_richpresence_display_t* display; ++ int result; ++ ++ if (!progress->runtime->richpresence || !progress->runtime->richpresence->richpresence) ++ return RC_OK; ++ ++ if (!rc_runtime_progress_match_md5(progress, progress->runtime->richpresence->md5)) { ++ rc_reset_richpresence_triggers(progress->runtime->richpresence->richpresence); ++ return RC_OK; ++ } ++ ++ display = progress->runtime->richpresence->richpresence->first_display; ++ for (; display->next; display = display->next) { ++ result = rc_runtime_progress_read_trigger(progress, &display->trigger); ++ if (result != RC_OK) ++ return result; ++ } ++ ++ return RC_OK; ++} ++ ++static int rc_runtime_progress_serialize_internal(rc_runtime_progress_t* progress) ++{ ++ md5_state_t state; ++ uint8_t md5[16]; ++ int result; ++ ++ if (progress->buffer_size < RC_RUNTIME_MIN_BUFFER_SIZE) ++ return RC_INSUFFICIENT_BUFFER; ++ ++ rc_runtime_progress_write_uint(progress, RC_RUNTIME_MARKER); ++ ++ if ((result = rc_runtime_progress_write_memrefs(progress)) != RC_OK) ++ return result; ++ ++ if ((result = rc_runtime_progress_write_variables(progress)) != RC_OK) ++ return result; ++ ++ if ((result = rc_runtime_progress_write_achievements(progress)) != RC_OK) ++ return result; ++ ++ if ((result = rc_runtime_progress_write_leaderboards(progress)) != RC_OK) ++ return result; ++ ++ if ((result = rc_runtime_progress_write_rich_presence(progress)) != RC_OK) ++ return result; ++ ++ if (progress->offset + 8 + 16 > progress->buffer_size) ++ return RC_INSUFFICIENT_BUFFER; ++ ++ rc_runtime_progress_write_uint(progress, RC_RUNTIME_CHUNK_DONE); ++ rc_runtime_progress_write_uint(progress, 16); ++ ++ if (progress->buffer) { ++ md5_init(&state); ++ md5_append(&state, progress->buffer, progress->offset); ++ md5_finish(&state, md5); ++ } ++ ++ rc_runtime_progress_write_md5(progress, md5); ++ ++ return RC_OK; ++} ++ ++uint32_t rc_runtime_progress_size(const rc_runtime_t* runtime, void* unused_L) ++{ ++ rc_runtime_progress_t progress; ++ int result; ++ ++ (void)unused_L; ++ ++ rc_runtime_progress_init(&progress, runtime); ++ progress.buffer_size = 0xFFFFFFFF; ++ ++ result = rc_runtime_progress_serialize_internal(&progress); ++ if (result != RC_OK) ++ return result; ++ ++ return progress.offset; ++} ++ ++int rc_runtime_serialize_progress(void* buffer, const rc_runtime_t* runtime, void* unused_L) ++{ ++ return rc_runtime_serialize_progress_sized((uint8_t*)buffer, 0xFFFFFFFF, runtime, unused_L); ++} ++ ++int rc_runtime_serialize_progress_sized(uint8_t* buffer, uint32_t buffer_size, const rc_runtime_t* runtime, void* unused_L) ++{ ++ rc_runtime_progress_t progress; ++ ++ (void)unused_L; ++ ++ if (!buffer) ++ return RC_INVALID_STATE; ++ ++ rc_runtime_progress_init(&progress, runtime); ++ progress.buffer = (uint8_t*)buffer; ++ progress.buffer_size = buffer_size; ++ ++ return rc_runtime_progress_serialize_internal(&progress); ++} ++ ++int rc_runtime_deserialize_progress(rc_runtime_t* runtime, const uint8_t* serialized, void* unused_L) ++{ ++ return rc_runtime_deserialize_progress_sized(runtime, serialized, 0xFFFFFFFF, unused_L); ++} ++ ++int rc_runtime_deserialize_progress_sized(rc_runtime_t* runtime, const uint8_t* serialized, uint32_t serialized_size, void* unused_L) ++{ ++ rc_runtime_progress_t progress; ++ md5_state_t state; ++ uint8_t md5[16]; ++ uint32_t chunk_id; ++ uint32_t chunk_size; ++ uint32_t next_chunk_offset; ++ uint32_t i; ++ int seen_rich_presence = 0; ++ int result = RC_OK; ++ ++ (void)unused_L; ++ ++ if (!serialized || serialized_size < RC_RUNTIME_MIN_BUFFER_SIZE) { ++ rc_runtime_reset(runtime); ++ return RC_INSUFFICIENT_BUFFER; ++ } ++ ++ rc_runtime_progress_init(&progress, runtime); ++ progress.buffer = (uint8_t*)serialized; ++ ++ if (rc_runtime_progress_read_uint(&progress) != RC_RUNTIME_MARKER) { ++ rc_runtime_reset(runtime); ++ return RC_INVALID_STATE; ++ } ++ ++ for (i = 0; i < runtime->trigger_count; ++i) { ++ rc_runtime_trigger_t* runtime_trigger = &runtime->triggers[i]; ++ if (runtime_trigger->trigger) { ++ /* don't update state for inactive or triggered achievements */ ++ if (rc_trigger_state_active(runtime_trigger->trigger->state)) { ++ /* mark active achievements as unupdated. anything that's still unupdated ++ * after deserializing the progress will be reset to waiting */ ++ runtime_trigger->trigger->state = RC_TRIGGER_STATE_UNUPDATED; ++ } ++ } ++ } ++ ++ for (i = 0; i < runtime->lboard_count; ++i) { ++ rc_runtime_lboard_t* runtime_lboard = &runtime->lboards[i]; ++ if (runtime_lboard->lboard) { ++ /* don't update state for inactive or triggered achievements */ ++ if (rc_lboard_state_active(runtime_lboard->lboard->state)) { ++ /* mark active achievements as unupdated. anything that's still unupdated ++ * after deserializing the progress will be reset to waiting */ ++ runtime_lboard->lboard->state = RC_TRIGGER_STATE_UNUPDATED; ++ } ++ } ++ } ++ ++ do { ++ if (progress.offset + 8 >= serialized_size) { ++ result = RC_INSUFFICIENT_BUFFER; ++ break; ++ } ++ ++ chunk_id = rc_runtime_progress_read_uint(&progress); ++ chunk_size = rc_runtime_progress_read_uint(&progress); ++ next_chunk_offset = progress.offset + chunk_size; ++ ++ if (next_chunk_offset > serialized_size) { ++ result = RC_INSUFFICIENT_BUFFER; ++ break; ++ } ++ ++ switch (chunk_id) { ++ case RC_RUNTIME_CHUNK_MEMREFS: ++ result = rc_runtime_progress_read_memrefs(&progress); ++ break; ++ ++ case RC_RUNTIME_CHUNK_VARIABLES: ++ result = rc_runtime_progress_read_variables(&progress); ++ break; ++ ++ case RC_RUNTIME_CHUNK_ACHIEVEMENT: ++ result = rc_runtime_progress_read_achievement(&progress); ++ break; ++ ++ case RC_RUNTIME_CHUNK_LEADERBOARD: ++ result = rc_runtime_progress_read_leaderboard(&progress); ++ break; ++ ++ case RC_RUNTIME_CHUNK_RICHPRESENCE: ++ seen_rich_presence = 1; ++ result = rc_runtime_progress_read_rich_presence(&progress); ++ break; ++ ++ case RC_RUNTIME_CHUNK_DONE: ++ md5_init(&state); ++ md5_append(&state, progress.buffer, progress.offset); ++ md5_finish(&state, md5); ++ if (!rc_runtime_progress_match_md5(&progress, md5)) ++ result = RC_INVALID_STATE; ++ break; ++ ++ default: ++ if (chunk_size & 0xFFFF0000) ++ result = RC_INVALID_STATE; /* assume unknown chunk > 64KB is invalid */ ++ break; ++ } ++ ++ progress.offset = next_chunk_offset; ++ } while (result == RC_OK && chunk_id != RC_RUNTIME_CHUNK_DONE); ++ ++ if (result != RC_OK) { ++ rc_runtime_reset(runtime); ++ } ++ else { ++ for (i = 0; i < runtime->trigger_count; ++i) { ++ rc_trigger_t* trigger = runtime->triggers[i].trigger; ++ if (trigger && trigger->state == RC_TRIGGER_STATE_UNUPDATED) ++ rc_reset_trigger(trigger); ++ } ++ ++ for (i = 0; i < runtime->lboard_count; ++i) { ++ rc_lboard_t* lboard = runtime->lboards[i].lboard; ++ if (lboard && lboard->state == RC_TRIGGER_STATE_UNUPDATED) ++ rc_reset_lboard(lboard); ++ } ++ ++ if (!seen_rich_presence && runtime->richpresence && runtime->richpresence->richpresence) ++ rc_reset_richpresence_triggers(runtime->richpresence->richpresence); ++ } ++ ++ return result; ++} +diff -rupbN melonDS.orig/src/rcheevos/src/rcheevos/trigger.c melonDS.ra/src/rcheevos/src/rcheevos/trigger.c +--- melonDS.orig/src/rcheevos/src/rcheevos/trigger.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rcheevos/trigger.c 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,344 @@ ++#include "rc_internal.h" ++ ++#include ++#include /* memset */ ++ ++void rc_parse_trigger_internal(rc_trigger_t* self, const char** memaddr, rc_parse_state_t* parse) { ++ rc_condset_t** next; ++ const char* aux; ++ ++ aux = *memaddr; ++ next = &self->alternative; ++ ++ /* reset in case multiple triggers are parsed by the same parse_state */ ++ parse->measured_target = 0; ++ parse->has_required_hits = 0; ++ parse->measured_as_percent = 0; ++ ++ if (*aux == 's' || *aux == 'S') { ++ self->requirement = NULL; ++ } ++ else { ++ self->requirement = rc_parse_condset(&aux, parse); ++ ++ if (parse->offset < 0) ++ return; ++ ++ self->requirement->next = NULL; ++ } ++ ++ while (*aux == 's' || *aux == 'S') { ++ aux++; ++ *next = rc_parse_condset(&aux, parse); ++ ++ if (parse->offset < 0) { ++ return; ++ } ++ ++ next = &(*next)->next; ++ } ++ ++ *next = NULL; ++ *memaddr = aux; ++ ++ self->measured_target = parse->measured_target; ++ self->measured_value = parse->measured_target ? RC_MEASURED_UNKNOWN : 0; ++ self->measured_as_percent = parse->measured_as_percent; ++ self->state = RC_TRIGGER_STATE_WAITING; ++ self->has_hits = 0; ++ self->has_memrefs = 0; ++} ++ ++int rc_trigger_size(const char* memaddr) { ++ rc_trigger_with_memrefs_t* trigger; ++ rc_preparse_state_t preparse; ++ rc_init_preparse_state(&preparse); ++ ++ trigger = RC_ALLOC(rc_trigger_with_memrefs_t, &preparse.parse); ++ rc_parse_trigger_internal(&trigger->trigger, &memaddr, &preparse.parse); ++ rc_preparse_alloc_memrefs(NULL, &preparse); ++ ++ rc_destroy_preparse_state(&preparse); ++ return preparse.parse.offset; ++} ++ ++rc_trigger_t* rc_parse_trigger(void* buffer, const char* memaddr, void* unused_L, int unused_funcs_idx) { ++ rc_trigger_with_memrefs_t* trigger; ++ rc_preparse_state_t preparse; ++ const char* preparse_memaddr = memaddr; ++ ++ (void)unused_L; ++ (void)unused_funcs_idx; ++ ++ if (!buffer || !memaddr) ++ return NULL; ++ ++ /* first pass : determine how many memrefs are needed */ ++ rc_init_preparse_state(&preparse); ++ trigger = RC_ALLOC(rc_trigger_with_memrefs_t, &preparse.parse); ++ rc_parse_trigger_internal(&trigger->trigger, &preparse_memaddr, &preparse.parse); ++ ++ /* allocate the trigger and memrefs */ ++ rc_reset_parse_state(&preparse.parse, buffer); ++ trigger = RC_ALLOC(rc_trigger_with_memrefs_t, &preparse.parse); ++ rc_preparse_alloc_memrefs(&trigger->memrefs, &preparse); ++ ++ /* parse the trigger */ ++ rc_parse_trigger_internal(&trigger->trigger, &memaddr, &preparse.parse); ++ trigger->trigger.has_memrefs = 1; ++ ++ rc_destroy_preparse_state(&preparse); ++ return (preparse.parse.offset >= 0) ? &trigger->trigger : NULL; ++} ++ ++int rc_trigger_state_active(int state) ++{ ++ switch (state) ++ { ++ case RC_TRIGGER_STATE_DISABLED: ++ case RC_TRIGGER_STATE_INACTIVE: ++ case RC_TRIGGER_STATE_TRIGGERED: ++ return 0; ++ ++ default: ++ return 1; ++ } ++} ++ ++static int rc_condset_is_measured_from_hitcount(const rc_condset_t* condset, uint32_t measured_value) ++{ ++ const rc_condition_t* condition; ++ for (condition = condset->conditions; condition; condition = condition->next) { ++ if (condition->type == RC_CONDITION_MEASURED && condition->required_hits && ++ condition->current_hits == measured_value) { ++ return 1; ++ } ++ } ++ ++ return 0; ++} ++ ++static void rc_reset_trigger_hitcounts(rc_trigger_t* self) { ++ rc_condset_t* condset; ++ ++ if (self->requirement) { ++ rc_reset_condset(self->requirement); ++ } ++ ++ condset = self->alternative; ++ ++ while (condset) { ++ rc_reset_condset(condset); ++ condset = condset->next; ++ } ++} ++ ++static void rc_update_trigger_memrefs(rc_trigger_t* self, rc_peek_t peek, void* ud) { ++ if (self->has_memrefs) { ++ rc_trigger_with_memrefs_t* trigger = (rc_trigger_with_memrefs_t*)self; ++ rc_update_memref_values(&trigger->memrefs, peek, ud); ++ } ++} ++ ++rc_memrefs_t* rc_trigger_get_memrefs(rc_trigger_t* self) { ++ if (self->has_memrefs) { ++ rc_trigger_with_memrefs_t* trigger = (rc_trigger_with_memrefs_t*)self; ++ return &trigger->memrefs; ++ } ++ ++ return NULL; ++} ++ ++int rc_evaluate_trigger(rc_trigger_t* self, rc_peek_t peek, void* ud, void* unused_L) { ++ rc_eval_state_t eval_state; ++ rc_condset_t* condset; ++ rc_typed_value_t measured_value; ++ int measured_from_hits = 0; ++ int ret; ++ char is_paused; ++ char is_primed; ++ ++ (void)unused_L; ++ ++ switch (self->state) ++ { ++ case RC_TRIGGER_STATE_TRIGGERED: ++ /* previously triggered. do nothing - return INACTIVE so caller doesn't think it triggered again */ ++ return RC_TRIGGER_STATE_INACTIVE; ++ ++ case RC_TRIGGER_STATE_DISABLED: ++ /* unsupported. do nothing - return INACTIVE */ ++ return RC_TRIGGER_STATE_INACTIVE; ++ ++ case RC_TRIGGER_STATE_INACTIVE: ++ /* not yet active. update the memrefs so deltas are correct when it becomes active, then return INACTIVE */ ++ rc_update_trigger_memrefs(self, peek, ud); ++ return RC_TRIGGER_STATE_INACTIVE; ++ ++ default: ++ break; ++ } ++ ++ /* update the memory references */ ++ rc_update_trigger_memrefs(self, peek, ud); ++ ++ /* process the trigger */ ++ memset(&eval_state, 0, sizeof(eval_state)); ++ eval_state.peek = peek; ++ eval_state.peek_userdata = ud; ++ ++ measured_value.type = RC_VALUE_TYPE_NONE; ++ ++ if (self->requirement != NULL) { ++ ret = rc_test_condset(self->requirement, &eval_state); ++ is_paused = eval_state.is_paused; ++ is_primed = eval_state.is_primed; ++ ++ if (eval_state.measured_value.type != RC_VALUE_TYPE_NONE) { ++ memcpy(&measured_value, &eval_state.measured_value, sizeof(measured_value)); ++ measured_from_hits = eval_state.measured_from_hits; ++ } ++ } else { ++ ret = 1; ++ is_paused = 0; ++ is_primed = 1; ++ } ++ ++ condset = self->alternative; ++ if (condset) { ++ int sub = 0; ++ char sub_paused = 1; ++ char sub_primed = 0; ++ ++ do { ++ sub |= rc_test_condset(condset, &eval_state); ++ sub_paused &= eval_state.is_paused; ++ sub_primed |= eval_state.is_primed; ++ ++ if (eval_state.measured_value.type != RC_VALUE_TYPE_NONE) { ++ /* if no previous Measured value was captured, or the new one is greater, keep the new one */ ++ if (measured_value.type == RC_VALUE_TYPE_NONE || ++ rc_typed_value_compare(&eval_state.measured_value, &measured_value, RC_OPERATOR_GT)) { ++ memcpy(&measured_value, &eval_state.measured_value, sizeof(measured_value)); ++ measured_from_hits = eval_state.measured_from_hits; ++ } ++ } ++ ++ condset = condset->next; ++ } while (condset); ++ ++ /* to trigger, the core must be true and at least one alt must be true */ ++ ret &= sub; ++ is_primed &= sub_primed; ++ ++ /* if the core is not paused, all alts must be paused to count as a paused trigger */ ++ is_paused |= sub_paused; ++ } ++ ++ if (is_paused) { ++ /* if the trigger is fully paused, ignore any updates to the measured value */ ++ } ++ else if (measured_value.type == RC_VALUE_TYPE_NONE) { ++ /* if a measured value was not captured, keep the old value (it's possible to pause ++ * an alt that is generating the measured value without fully pausing the trigger) */ ++ } ++ else { ++ rc_typed_value_convert(&measured_value, RC_VALUE_TYPE_UNSIGNED); ++ self->measured_value = measured_value.value.u32; ++ } ++ ++ /* if any ResetIf condition was true, reset the hit counts */ ++ if (eval_state.was_reset) { ++ /* if the measured value came from a hit count, reset it. do this before calling ++ * rc_reset_trigger_hitcounts in case we need to call rc_condset_is_measured_from_hitcount */ ++ if (measured_from_hits) { ++ self->measured_value = 0; ++ } ++ else if (is_paused && self->measured_value) { ++ /* if the measured value is in a paused group, measured_from_hits won't have been set. ++ * attempt to determine if it should have been */ ++ if (self->requirement && self->requirement->is_paused && ++ rc_condset_is_measured_from_hitcount(self->requirement, self->measured_value)) { ++ self->measured_value = 0; ++ } ++ else { ++ for (condset = self->alternative; condset; condset = condset->next) { ++ if (condset->is_paused && rc_condset_is_measured_from_hitcount(condset, self->measured_value)) { ++ self->measured_value = 0; ++ break; ++ } ++ } ++ } ++ } ++ ++ rc_reset_trigger_hitcounts(self); ++ ++ /* if there were hit counts to clear, return RESET, but don't change the state */ ++ if (self->has_hits) { ++ self->has_hits = 0; ++ ++ /* cannot be PRIMED while ResetIf is true */ ++ if (self->state == RC_TRIGGER_STATE_PRIMED) ++ self->state = RC_TRIGGER_STATE_ACTIVE; ++ ++ return RC_TRIGGER_STATE_RESET; ++ } ++ ++ /* any hits that were tallied were just reset */ ++ eval_state.has_hits = 0; ++ is_primed = 0; ++ } ++ else if (ret) { ++ /* if the state is WAITING and the trigger is ready to fire, ignore it and reset the hit counts */ ++ if (self->state == RC_TRIGGER_STATE_WAITING) { ++ rc_reset_trigger(self); ++ self->has_hits = 0; ++ return RC_TRIGGER_STATE_WAITING; ++ } ++ ++ /* trigger was triggered */ ++ self->state = RC_TRIGGER_STATE_TRIGGERED; ++ return RC_TRIGGER_STATE_TRIGGERED; ++ } ++ ++ /* did not trigger this frame - update the information we'll need for next time */ ++ self->has_hits = eval_state.has_hits; ++ ++ if (is_paused) { ++ self->state = RC_TRIGGER_STATE_PAUSED; ++ } ++ else if (is_primed) { ++ self->state = RC_TRIGGER_STATE_PRIMED; ++ } ++ else { ++ self->state = RC_TRIGGER_STATE_ACTIVE; ++ } ++ ++ /* if an individual condition was reset, notify the caller */ ++ if (eval_state.was_cond_reset) ++ return RC_TRIGGER_STATE_RESET; ++ ++ /* otherwise, just return the current state */ ++ return self->state; ++} ++ ++int rc_test_trigger(rc_trigger_t* self, rc_peek_t peek, void* ud, void* unused_L) { ++ /* for backwards compatibilty, rc_test_trigger always assumes the achievement is active */ ++ self->state = RC_TRIGGER_STATE_ACTIVE; ++ ++ return (rc_evaluate_trigger(self, peek, ud, unused_L) == RC_TRIGGER_STATE_TRIGGERED); ++} ++ ++void rc_reset_trigger(rc_trigger_t* self) { ++ if (!self) ++ return; ++ ++ rc_reset_trigger_hitcounts(self); ++ ++ self->state = RC_TRIGGER_STATE_WAITING; ++ ++ if (self->measured_target) ++ self->measured_value = RC_MEASURED_UNKNOWN; ++ ++ self->has_hits = 0; ++} +diff -rupbN melonDS.orig/src/rcheevos/src/rcheevos/value.c melonDS.ra/src/rcheevos/src/rcheevos/value.c +--- melonDS.orig/src/rcheevos/src/rcheevos/value.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rcheevos/value.c 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,933 @@ ++#include "rc_internal.h" ++ ++#include /* memset */ ++#include /* isdigit */ ++#include /* FLT_EPSILON */ ++#include /* fmod */ ++ ++int rc_is_valid_variable_character(char ch, int is_first) { ++ if (is_first) { ++ if (!isalpha((unsigned char)ch)) ++ return 0; ++ } ++ else { ++ if (!isalnum((unsigned char)ch)) ++ return 0; ++ } ++ return 1; ++} ++ ++static void rc_parse_cond_value(rc_value_t* self, const char** memaddr, rc_parse_state_t* parse) { ++ rc_condset_t** next_clause; ++ ++ next_clause = &self->conditions; ++ ++ do ++ { ++ parse->measured_target = 0; /* passing is_value=1 should prevent any conflicts, but clear it out anyway */ ++ *next_clause = rc_parse_condset(memaddr, parse); ++ if (parse->offset < 0) { ++ return; ++ } ++ ++ if (**memaddr == 'S' || **memaddr == 's') { ++ /* alt groups not supported */ ++ parse->offset = RC_INVALID_VALUE_FLAG; ++ } ++ else if (parse->measured_target == 0) { ++ parse->offset = RC_MISSING_VALUE_MEASURED; ++ } ++ else if (**memaddr == '$') { ++ /* maximum of */ ++ ++(*memaddr); ++ next_clause = &(*next_clause)->next; ++ continue; ++ } ++ ++ break; ++ } while (1); ++ ++ (*next_clause)->next = 0; ++} ++ ++static void rc_parse_legacy_value(rc_value_t* self, const char** memaddr, rc_parse_state_t* parse) { ++ rc_condset_with_trailing_conditions_t* condset_with_conditions; ++ rc_condition_t** next; ++ rc_condset_t** next_clause; ++ rc_condset_t* condset; ++ rc_condition_t local_cond; ++ rc_condition_t* cond; ++ uint32_t num_measured_conditions; ++ char buffer[64] = "A:"; ++ const char* buffer_ptr; ++ char* ptr; ++ int done; ++ ++ /* convert legacy format into condset */ ++ next_clause = &self->conditions; ++ do { ++ /* count the number of joiners and add one to determine the number of clauses. */ ++ buffer[0] = 'A'; /* reset to AddSource */ ++ done = 0; ++ num_measured_conditions = 1; ++ buffer_ptr = *memaddr; ++ do { ++ switch (*buffer_ptr++) { ++ case '_': /* add next */ ++ ++num_measured_conditions; ++ buffer[0] = 'A'; /* reset to AddSource */ ++ break; ++ ++ case '*': /* multiply */ ++ if (*buffer_ptr == '-') { ++ /* multiplication by a negative number will convert to SubSource */ ++ ++buffer_ptr; ++ buffer[0] = 'B'; ++ } ++ break; ++ ++ case '\0': /* end of string */ ++ case '$': /* maximum of */ ++ case ':': /* end of leaderboard clause */ ++ case ')': /* end of rich presence macro */ ++ done = 1; ++ break; ++ ++ default: /* assume everything else is valid - bad stuff will be filtered out later */ ++ break; ++ } ++ } while (!done); ++ ++ /* if last condition is not AddSource, we'll need to add a dummy condition for the Measured */ ++ if (buffer[0] != 'A') ++ ++num_measured_conditions; ++ ++ condset_with_conditions = RC_ALLOC_WITH_TRAILING(rc_condset_with_trailing_conditions_t, ++ rc_condition_t, conditions, num_measured_conditions, parse); ++ if (parse->offset < 0) ++ return; ++ ++ condset = (rc_condset_t*)condset_with_conditions; ++ memset(condset, 0, sizeof(*condset)); ++ condset->num_measured_conditions = num_measured_conditions; ++ cond = &condset_with_conditions->conditions[0]; ++ ++ next = &condset->conditions; ++ ++ for (;; ++(*memaddr)) { ++ buffer[0] = 'A'; /* reset to AddSource */ ++ ptr = &buffer[2]; ++ ++ /* extract the next clause */ ++ for (;; ++(*memaddr)) { ++ switch (**memaddr) { ++ case '_': /* add next */ ++ *ptr = '\0'; ++ break; ++ ++ case '$': /* maximum of */ ++ case '\0': /* end of string */ ++ case ':': /* end of leaderboard clause */ ++ case ')': /* end of rich presence macro */ ++ /* the last condition needs to be Measured - AddSource can be changed here, ++ * SubSource will be handled later */ ++ if (buffer[0] == 'A') ++ buffer[0] = 'M'; ++ ++ *ptr = '\0'; ++ break; ++ ++ case '*': ++ *ptr++ = '*'; ++ ++ buffer_ptr = *memaddr + 1; ++ if (*buffer_ptr == '-') { ++ buffer[0] = 'B'; /* change to SubSource */ ++ ++(*memaddr); /* don't copy sign */ ++ ++buffer_ptr; /* ignore sign when doing floating point check */ ++ } ++ else if (*buffer_ptr == '+') { ++ ++buffer_ptr; /* ignore sign when doing floating point check */ ++ } ++ ++ /* if it looks like a floating point number, add the 'f' prefix */ ++ while (isdigit((unsigned char)*buffer_ptr)) ++ ++buffer_ptr; ++ if (*buffer_ptr == '.') ++ *ptr++ = 'f'; ++ continue; ++ ++ default: ++ *ptr++ = **memaddr; ++ continue; ++ } ++ ++ break; ++ } ++ ++ /* process the clause */ ++ if (!parse->buffer) ++ cond = &local_cond; ++ ++ buffer_ptr = buffer; ++ rc_parse_condition_internal(cond, &buffer_ptr, parse); ++ if (parse->offset < 0) ++ return; ++ ++ if (*buffer_ptr) { ++ /* whatever we copied as a single condition was not fully consumed */ ++ parse->offset = RC_INVALID_COMPARISON; ++ return; ++ } ++ ++ if (!rc_operator_is_modifying(cond->oper)) { ++ parse->offset = RC_INVALID_OPERATOR; ++ return; ++ } ++ ++ rc_condition_update_parse_state(cond, parse); ++ ++ *next = cond; ++ next = &cond->next; ++ ++ if (**memaddr != '_') /* add next */ ++ break; ++ ++ ++cond; ++ } ++ ++ /* -- end of clause -- */ ++ ++ /* clause must end in a Measured. if it doesn't, append one */ ++ if (cond->type != RC_CONDITION_MEASURED) { ++ if (!parse->buffer) ++ cond = &local_cond; ++ else ++ ++cond; ++ ++ buffer_ptr = "M:0"; ++ rc_parse_condition_internal(cond, &buffer_ptr, parse); ++ *next = cond; ++ next = &cond->next; ++ rc_condition_update_parse_state(cond, parse); ++ } ++ ++ *next = NULL; ++ ++ /* finalize clause */ ++ *next_clause = condset; ++ next_clause = &condset->next; ++ ++ if (**memaddr != '$') { ++ /* end of valid string */ ++ *next_clause = NULL; ++ break; ++ } ++ ++ /* max of ($), start a new clause */ ++ ++(*memaddr); ++ } while (1); ++} ++ ++void rc_parse_value_internal(rc_value_t* self, const char** memaddr, rc_parse_state_t* parse) { ++ const uint8_t was_value = parse->is_value; ++ const rc_condition_t* condition; ++ parse->is_value = 1; ++ ++ /* if it starts with a condition flag (M: A: B: C:), parse the conditions */ ++ if ((*memaddr)[1] == ':') ++ rc_parse_cond_value(self, memaddr, parse); ++ else ++ rc_parse_legacy_value(self, memaddr, parse); ++ ++ if (parse->offset >= 0 && parse->buffer) { ++ self->name = "(unnamed)"; ++ self->value.value = self->value.prior = 0; ++ self->value.memref_type = RC_MEMREF_TYPE_VALUE; ++ self->value.changed = 0; ++ self->has_memrefs = 0; ++ ++ for (condition = self->conditions->conditions; condition; condition = condition->next) { ++ if (condition->type == RC_CONDITION_MEASURED) { ++ if (rc_operand_is_float(&condition->operand1)) { ++ self->value.size = RC_MEMSIZE_FLOAT; ++ self->value.type = RC_VALUE_TYPE_FLOAT; ++ } ++ else { ++ self->value.size = RC_MEMSIZE_32_BITS; ++ self->value.type = RC_VALUE_TYPE_UNSIGNED; ++ } ++ break; ++ } ++ } ++ } ++ ++ parse->is_value = was_value; ++} ++ ++int rc_value_size(const char* memaddr) { ++ rc_value_with_memrefs_t* value; ++ rc_preparse_state_t preparse; ++ rc_init_preparse_state(&preparse); ++ ++ value = RC_ALLOC(rc_value_with_memrefs_t, &preparse.parse); ++ rc_parse_value_internal(&value->value, &memaddr, &preparse.parse); ++ rc_preparse_alloc_memrefs(NULL, &preparse); ++ ++ rc_destroy_preparse_state(&preparse); ++ return preparse.parse.offset; ++} ++ ++rc_value_t* rc_parse_value(void* buffer, const char* memaddr, void* unused_L, int unused_funcs_idx) { ++ rc_value_with_memrefs_t* value; ++ rc_preparse_state_t preparse; ++ const char* preparse_memaddr = memaddr; ++ ++ (void)unused_L; ++ (void)unused_funcs_idx; ++ ++ if (!buffer || !memaddr) ++ return NULL; ++ ++ rc_init_preparse_state(&preparse); ++ value = RC_ALLOC(rc_value_with_memrefs_t, &preparse.parse); ++ rc_parse_value_internal(&value->value, &preparse_memaddr, &preparse.parse); ++ ++ rc_reset_parse_state(&preparse.parse, buffer); ++ value = RC_ALLOC(rc_value_with_memrefs_t, &preparse.parse); ++ rc_preparse_alloc_memrefs(&value->memrefs, &preparse); ++ ++ rc_parse_value_internal(&value->value, &memaddr, &preparse.parse); ++ value->value.has_memrefs = 1; ++ ++ rc_destroy_preparse_state(&preparse); ++ return (preparse.parse.offset >= 0) ? &value->value : NULL; ++} ++ ++static void rc_update_value_memrefs(rc_value_t* self, rc_peek_t peek, void* ud) { ++ if (self->has_memrefs) { ++ rc_value_with_memrefs_t* value = (rc_value_with_memrefs_t*)self; ++ rc_update_memref_values(&value->memrefs, peek, ud); ++ } ++} ++ ++int rc_evaluate_value_typed(rc_value_t* self, rc_typed_value_t* value, rc_peek_t peek, void* ud) { ++ rc_eval_state_t eval_state; ++ rc_condset_t* condset; ++ int valid = 0; ++ ++ rc_update_value_memrefs(self, peek, ud); ++ ++ value->value.i32 = 0; ++ value->type = RC_VALUE_TYPE_SIGNED; ++ ++ for (condset = self->conditions; condset != NULL; condset = condset->next) { ++ memset(&eval_state, 0, sizeof(eval_state)); ++ eval_state.peek = peek; ++ eval_state.peek_userdata = ud; ++ ++ rc_test_condset(condset, &eval_state); ++ ++ if (condset->is_paused) ++ continue; ++ ++ if (eval_state.was_reset) { ++ /* if any ResetIf condition was true, reset the hit counts ++ * NOTE: ResetIf only affects the current condset when used in values! ++ */ ++ rc_reset_condset(condset); ++ } ++ ++ if (eval_state.measured_value.type != RC_VALUE_TYPE_NONE) { ++ if (!valid) { ++ /* capture the first valid measurement, which may be negative */ ++ memcpy(value, &eval_state.measured_value, sizeof(*value)); ++ valid = 1; ++ } ++ else { ++ /* multiple condsets are currently only used for the MAX_OF operation. ++ * only keep the condset's value if it's higher than the current highest value. ++ */ ++ if (rc_typed_value_compare(&eval_state.measured_value, value, RC_OPERATOR_GT)) ++ memcpy(value, &eval_state.measured_value, sizeof(*value)); ++ } ++ } ++ } ++ ++ return valid; ++} ++ ++int32_t rc_evaluate_value(rc_value_t* self, rc_peek_t peek, void* ud, void* unused_L) { ++ rc_typed_value_t result; ++ int valid = rc_evaluate_value_typed(self, &result, peek, ud); ++ ++ (void)unused_L; ++ ++ if (valid) { ++ /* if not paused, store the value so that it's available when paused. */ ++ rc_typed_value_convert(&result, RC_VALUE_TYPE_UNSIGNED); ++ rc_update_memref_value(&self->value, result.value.u32); ++ } ++ else { ++ /* when paused, the Measured value will not be captured, use the last captured value. */ ++ result.value.u32 = self->value.value; ++ result.type = RC_VALUE_TYPE_UNSIGNED; ++ } ++ ++ rc_typed_value_convert(&result, RC_VALUE_TYPE_SIGNED); ++ return result.value.i32; ++} ++ ++void rc_reset_value(rc_value_t* self) { ++ rc_condset_t* condset = self->conditions; ++ while (condset != NULL) { ++ rc_reset_condset(condset); ++ condset = condset->next; ++ } ++ ++ self->value.value = self->value.prior = 0; ++ self->value.changed = 0; ++} ++ ++int rc_value_from_hits(rc_value_t* self) ++{ ++ rc_condset_t* condset = self->conditions; ++ for (; condset != NULL; condset = condset->next) { ++ rc_condition_t* condition = condset->conditions; ++ for (; condition != NULL; condition = condition->next) { ++ if (condition->type == RC_CONDITION_MEASURED) ++ return (condition->required_hits != 0); ++ } ++ } ++ ++ return 0; ++} ++ ++rc_value_t* rc_alloc_variable(const char* memaddr, size_t memaddr_len, rc_parse_state_t* parse) { ++ rc_value_t** value_ptr = parse->variables; ++ rc_value_t* value; ++ const char* name; ++ uint32_t measured_target; ++ ++ if (!value_ptr) ++ return NULL; ++ ++ while (*value_ptr) { ++ value = *value_ptr; ++ if (strncmp(value->name, memaddr, memaddr_len) == 0 && value->name[memaddr_len] == 0) ++ return value; ++ ++ value_ptr = &value->next; ++ } ++ ++ /* capture name before calling parse as parse will update memaddr pointer */ ++ name = rc_alloc_str(parse, memaddr, memaddr_len); ++ if (!name) ++ return NULL; ++ ++ /* no match found, create a new entry */ ++ value = RC_ALLOC_SCRATCH(rc_value_t, parse); ++ memset(value, 0, sizeof(value->value)); ++ value->value.size = RC_MEMSIZE_VARIABLE; ++ value->next = NULL; ++ ++ /* the helper variable likely has a Measured condition. capture the current measured_target so we can restore it ++ * after generating the variable so the variable's Measured target doesn't conflict with the rest of the trigger. */ ++ measured_target = parse->measured_target; ++ rc_parse_value_internal(value, &memaddr, parse); ++ parse->measured_target = measured_target; ++ ++ /* store name after calling parse as parse will set name to (unnamed) */ ++ value->name = name; ++ ++ *value_ptr = value; ++ return value; ++} ++ ++uint32_t rc_count_values(const rc_value_t* values) { ++ uint32_t count = 0; ++ while (values) { ++ ++count; ++ values = values->next; ++ } ++ ++ return count; ++} ++ ++void rc_update_values(rc_value_t* values, rc_peek_t peek, void* ud) { ++ rc_typed_value_t result; ++ ++ rc_value_t* value = values; ++ for (; value; value = value->next) { ++ if (rc_evaluate_value_typed(value, &result, peek, ud)) { ++ /* store the raw bytes and type to be restored by rc_typed_value_from_memref_value */ ++ rc_update_memref_value(&value->value, result.value.u32); ++ value->value.type = result.type; ++ } ++ } ++} ++ ++void rc_reset_values(rc_value_t* values) { ++ rc_value_t* value = values; ++ ++ for (; value; value = value->next) ++ rc_reset_value(value); ++} ++ ++void rc_typed_value_from_memref_value(rc_typed_value_t* value, const rc_memref_value_t* memref) { ++ /* raw value is always u32, type can mark it as something else */ ++ value->value.u32 = memref->value; ++ value->type = memref->type; ++} ++ ++void rc_typed_value_convert(rc_typed_value_t* value, char new_type) { ++ switch (new_type) { ++ case RC_VALUE_TYPE_UNSIGNED: ++ switch (value->type) { ++ case RC_VALUE_TYPE_UNSIGNED: ++ return; ++ case RC_VALUE_TYPE_SIGNED: ++ value->value.u32 = (unsigned)value->value.i32; ++ break; ++ case RC_VALUE_TYPE_FLOAT: ++ value->value.u32 = (unsigned)value->value.f32; ++ break; ++ default: ++ value->value.u32 = 0; ++ break; ++ } ++ break; ++ ++ case RC_VALUE_TYPE_SIGNED: ++ switch (value->type) { ++ case RC_VALUE_TYPE_SIGNED: ++ return; ++ case RC_VALUE_TYPE_UNSIGNED: ++ value->value.i32 = (int)value->value.u32; ++ break; ++ case RC_VALUE_TYPE_FLOAT: ++ value->value.i32 = (int)value->value.f32; ++ break; ++ default: ++ value->value.i32 = 0; ++ break; ++ } ++ break; ++ ++ case RC_VALUE_TYPE_FLOAT: ++ switch (value->type) { ++ case RC_VALUE_TYPE_FLOAT: ++ return; ++ case RC_VALUE_TYPE_UNSIGNED: ++ value->value.f32 = (float)value->value.u32; ++ break; ++ case RC_VALUE_TYPE_SIGNED: ++ value->value.f32 = (float)value->value.i32; ++ break; ++ default: ++ value->value.f32 = 0.0; ++ break; ++ } ++ break; ++ ++ default: ++ break; ++ } ++ ++ value->type = new_type; ++} ++ ++static rc_typed_value_t* rc_typed_value_convert_into(rc_typed_value_t* dest, const rc_typed_value_t* source, char new_type) { ++ memcpy(dest, source, sizeof(rc_typed_value_t)); ++ rc_typed_value_convert(dest, new_type); ++ return dest; ++} ++ ++void rc_typed_value_negate(rc_typed_value_t* value) { ++ switch (value->type) ++ { ++ case RC_VALUE_TYPE_UNSIGNED: ++ rc_typed_value_convert(value, RC_VALUE_TYPE_SIGNED); ++ /* fallthrough */ /* to RC_VALUE_TYPE_SIGNED */ ++ ++ case RC_VALUE_TYPE_SIGNED: ++ value->value.i32 = -(value->value.i32); ++ break; ++ ++ case RC_VALUE_TYPE_FLOAT: ++ value->value.f32 = -(value->value.f32); ++ break; ++ ++ default: ++ break; ++ } ++} ++ ++void rc_typed_value_add(rc_typed_value_t* value, const rc_typed_value_t* amount) { ++ rc_typed_value_t converted; ++ ++ if (amount->type != value->type && value->type != RC_VALUE_TYPE_NONE) { ++ if (amount->type == RC_VALUE_TYPE_FLOAT) ++ rc_typed_value_convert(value, RC_VALUE_TYPE_FLOAT); ++ else ++ amount = rc_typed_value_convert_into(&converted, amount, value->type); ++ } ++ ++ switch (value->type) ++ { ++ case RC_VALUE_TYPE_UNSIGNED: ++ value->value.u32 += amount->value.u32; ++ break; ++ ++ case RC_VALUE_TYPE_SIGNED: ++ value->value.i32 += amount->value.i32; ++ break; ++ ++ case RC_VALUE_TYPE_FLOAT: ++ value->value.f32 += amount->value.f32; ++ break; ++ ++ case RC_VALUE_TYPE_NONE: ++ memcpy(value, amount, sizeof(rc_typed_value_t)); ++ break; ++ ++ default: ++ break; ++ } ++} ++ ++void rc_typed_value_multiply(rc_typed_value_t* value, const rc_typed_value_t* amount) { ++ rc_typed_value_t converted; ++ ++ switch (value->type) ++ { ++ case RC_VALUE_TYPE_UNSIGNED: ++ switch (amount->type) ++ { ++ case RC_VALUE_TYPE_UNSIGNED: ++ /* the c standard for unsigned multiplication is well defined as non-overflowing truncation ++ * to the type's size. this allows negative multiplication through twos-complements. i.e. ++ * 1 * -1 (0xFFFFFFFF) = 0xFFFFFFFF = -1 ++ * 3 * -2 (0xFFFFFFFE) = 0x2FFFFFFFA & 0xFFFFFFFF = 0xFFFFFFFA = -6 ++ * 10 * -5 (0xFFFFFFFB) = 0x9FFFFFFCE & 0xFFFFFFFF = 0xFFFFFFCE = -50 ++ */ ++ value->value.u32 *= amount->value.u32; ++ break; ++ ++ case RC_VALUE_TYPE_SIGNED: ++ value->value.u32 *= (unsigned)amount->value.i32; ++ break; ++ ++ case RC_VALUE_TYPE_FLOAT: ++ rc_typed_value_convert(value, RC_VALUE_TYPE_FLOAT); ++ value->value.f32 *= amount->value.f32; ++ break; ++ ++ default: ++ value->type = RC_VALUE_TYPE_NONE; ++ break; ++ } ++ break; ++ ++ case RC_VALUE_TYPE_SIGNED: ++ switch (amount->type) ++ { ++ case RC_VALUE_TYPE_SIGNED: ++ value->value.i32 *= amount->value.i32; ++ break; ++ ++ case RC_VALUE_TYPE_UNSIGNED: ++ value->value.i32 *= (int)amount->value.u32; ++ break; ++ ++ case RC_VALUE_TYPE_FLOAT: ++ rc_typed_value_convert(value, RC_VALUE_TYPE_FLOAT); ++ value->value.f32 *= amount->value.f32; ++ break; ++ ++ default: ++ value->type = RC_VALUE_TYPE_NONE; ++ break; ++ } ++ break; ++ ++ case RC_VALUE_TYPE_FLOAT: ++ if (amount->type == RC_VALUE_TYPE_NONE) { ++ value->type = RC_VALUE_TYPE_NONE; ++ } ++ else { ++ amount = rc_typed_value_convert_into(&converted, amount, RC_VALUE_TYPE_FLOAT); ++ value->value.f32 *= amount->value.f32; ++ } ++ break; ++ ++ default: ++ value->type = RC_VALUE_TYPE_NONE; ++ break; ++ } ++} ++ ++void rc_typed_value_divide(rc_typed_value_t* value, const rc_typed_value_t* amount) { ++ rc_typed_value_t converted; ++ ++ switch (amount->type) ++ { ++ case RC_VALUE_TYPE_UNSIGNED: ++ if (amount->value.u32 == 0) { /* divide by zero */ ++ value->type = RC_VALUE_TYPE_NONE; ++ return; ++ } ++ ++ switch (value->type) { ++ case RC_VALUE_TYPE_UNSIGNED: /* integer math */ ++ value->value.u32 /= amount->value.u32; ++ return; ++ case RC_VALUE_TYPE_SIGNED: /* integer math */ ++ value->value.i32 /= (int)amount->value.u32; ++ return; ++ case RC_VALUE_TYPE_FLOAT: ++ amount = rc_typed_value_convert_into(&converted, amount, RC_VALUE_TYPE_FLOAT); ++ break; ++ default: ++ value->type = RC_VALUE_TYPE_NONE; ++ return; ++ } ++ break; ++ ++ case RC_VALUE_TYPE_SIGNED: ++ if (amount->value.i32 == 0) { /* divide by zero */ ++ value->type = RC_VALUE_TYPE_NONE; ++ return; ++ } ++ ++ switch (value->type) { ++ case RC_VALUE_TYPE_SIGNED: /* integer math */ ++ value->value.i32 /= amount->value.i32; ++ return; ++ case RC_VALUE_TYPE_UNSIGNED: /* integer math */ ++ value->value.u32 /= (unsigned)amount->value.i32; ++ return; ++ case RC_VALUE_TYPE_FLOAT: ++ amount = rc_typed_value_convert_into(&converted, amount, RC_VALUE_TYPE_FLOAT); ++ break; ++ default: ++ value->type = RC_VALUE_TYPE_NONE; ++ return; ++ } ++ break; ++ ++ case RC_VALUE_TYPE_FLOAT: ++ break; ++ ++ default: ++ value->type = RC_VALUE_TYPE_NONE; ++ return; ++ } ++ ++ if (amount->value.f32 == 0.0) { /* divide by zero */ ++ value->type = RC_VALUE_TYPE_NONE; ++ return; ++ } ++ ++ rc_typed_value_convert(value, RC_VALUE_TYPE_FLOAT); ++ value->value.f32 /= amount->value.f32; ++} ++ ++void rc_typed_value_modulus(rc_typed_value_t* value, const rc_typed_value_t* amount) { ++ rc_typed_value_t converted; ++ ++ switch (amount->type) ++ { ++ case RC_VALUE_TYPE_UNSIGNED: ++ if (amount->value.u32 == 0) { /* divide by zero */ ++ value->type = RC_VALUE_TYPE_NONE; ++ return; ++ } ++ ++ switch (value->type) { ++ case RC_VALUE_TYPE_UNSIGNED: /* integer math */ ++ value->value.u32 %= amount->value.u32; ++ return; ++ case RC_VALUE_TYPE_SIGNED: /* integer math */ ++ value->value.i32 %= (int)amount->value.u32; ++ return; ++ case RC_VALUE_TYPE_FLOAT: ++ amount = rc_typed_value_convert_into(&converted, amount, RC_VALUE_TYPE_FLOAT); ++ break; ++ default: ++ value->type = RC_VALUE_TYPE_NONE; ++ return; ++ } ++ break; ++ ++ case RC_VALUE_TYPE_SIGNED: ++ if (amount->value.i32 == 0) { /* divide by zero */ ++ value->type = RC_VALUE_TYPE_NONE; ++ return; ++ } ++ ++ switch (value->type) { ++ case RC_VALUE_TYPE_SIGNED: /* integer math */ ++ value->value.i32 %= amount->value.i32; ++ return; ++ case RC_VALUE_TYPE_UNSIGNED: /* integer math */ ++ value->value.u32 %= (unsigned)amount->value.i32; ++ return; ++ case RC_VALUE_TYPE_FLOAT: ++ amount = rc_typed_value_convert_into(&converted, amount, RC_VALUE_TYPE_FLOAT); ++ break; ++ default: ++ value->type = RC_VALUE_TYPE_NONE; ++ return; ++ } ++ break; ++ ++ case RC_VALUE_TYPE_FLOAT: ++ break; ++ ++ default: ++ value->type = RC_VALUE_TYPE_NONE; ++ return; ++ } ++ ++ if (amount->value.f32 == 0.0) { /* divide by zero */ ++ value->type = RC_VALUE_TYPE_NONE; ++ return; ++ } ++ ++ rc_typed_value_convert(value, RC_VALUE_TYPE_FLOAT); ++ value->value.f32 = (float)fmod(value->value.f32, amount->value.f32); ++} ++ ++void rc_typed_value_combine(rc_typed_value_t* value, rc_typed_value_t* amount, uint8_t oper) { ++ switch (oper) { ++ case RC_OPERATOR_MULT: ++ rc_typed_value_multiply(value, amount); ++ break; ++ ++ case RC_OPERATOR_DIV: ++ rc_typed_value_divide(value, amount); ++ break; ++ ++ case RC_OPERATOR_AND: ++ rc_typed_value_convert(value, RC_VALUE_TYPE_UNSIGNED); ++ rc_typed_value_convert(amount, RC_VALUE_TYPE_UNSIGNED); ++ value->value.u32 &= amount->value.u32; ++ break; ++ ++ case RC_OPERATOR_XOR: ++ rc_typed_value_convert(value, RC_VALUE_TYPE_UNSIGNED); ++ rc_typed_value_convert(amount, RC_VALUE_TYPE_UNSIGNED); ++ value->value.u32 ^= amount->value.u32; ++ break; ++ ++ case RC_OPERATOR_MOD: ++ rc_typed_value_modulus(value, amount); ++ break; ++ ++ case RC_OPERATOR_ADD: ++ rc_typed_value_add(value, amount); ++ break; ++ ++ case RC_OPERATOR_SUB: ++ rc_typed_value_negate(amount); ++ rc_typed_value_add(value, amount); ++ break; ++ } ++} ++ ++ ++static int rc_typed_value_compare_floats(float f1, float f2, char oper) { ++ if (f1 == f2) { ++ /* exactly equal */ ++ } ++ else { ++ /* attempt to match 7 significant digits (24-bit mantissa supports just over 7 significant decimal digits) */ ++ /* https://stackoverflow.com/questions/17333/what-is-the-most-effective-way-for-float-and-double-comparison */ ++ const float abs1 = (f1 < 0) ? -f1 : f1; ++ const float abs2 = (f2 < 0) ? -f2 : f2; ++ const float threshold = ((abs1 < abs2) ? abs1 : abs2) * FLT_EPSILON; ++ const float diff = f1 - f2; ++ const float abs_diff = (diff < 0) ? -diff : diff; ++ ++ if (abs_diff <= threshold) { ++ /* approximately equal */ ++ } ++ else if (diff > threshold) { ++ /* greater */ ++ switch (oper) { ++ case RC_OPERATOR_NE: ++ case RC_OPERATOR_GT: ++ case RC_OPERATOR_GE: ++ return 1; ++ ++ default: ++ return 0; ++ } ++ } ++ else { ++ /* lesser */ ++ switch (oper) { ++ case RC_OPERATOR_NE: ++ case RC_OPERATOR_LT: ++ case RC_OPERATOR_LE: ++ return 1; ++ ++ default: ++ return 0; ++ } ++ } ++ } ++ ++ /* exactly or approximately equal */ ++ switch (oper) { ++ case RC_OPERATOR_EQ: ++ case RC_OPERATOR_GE: ++ case RC_OPERATOR_LE: ++ return 1; ++ ++ default: ++ return 0; ++ } ++} ++ ++int rc_typed_value_compare(const rc_typed_value_t* value1, const rc_typed_value_t* value2, char oper) { ++ rc_typed_value_t converted_value; ++ if (value2->type != value1->type) { ++ /* if either side is a float, convert both sides to float. otherwise, assume the signed-ness of the left side. */ ++ if (value2->type == RC_VALUE_TYPE_FLOAT) ++ value1 = rc_typed_value_convert_into(&converted_value, value1, value2->type); ++ else ++ value2 = rc_typed_value_convert_into(&converted_value, value2, value1->type); ++ } ++ ++ switch (value1->type) { ++ case RC_VALUE_TYPE_UNSIGNED: ++ switch (oper) { ++ case RC_OPERATOR_EQ: return value1->value.u32 == value2->value.u32; ++ case RC_OPERATOR_NE: return value1->value.u32 != value2->value.u32; ++ case RC_OPERATOR_LT: return value1->value.u32 < value2->value.u32; ++ case RC_OPERATOR_LE: return value1->value.u32 <= value2->value.u32; ++ case RC_OPERATOR_GT: return value1->value.u32 > value2->value.u32; ++ case RC_OPERATOR_GE: return value1->value.u32 >= value2->value.u32; ++ default: return 1; ++ } ++ ++ case RC_VALUE_TYPE_SIGNED: ++ switch (oper) { ++ case RC_OPERATOR_EQ: return value1->value.i32 == value2->value.i32; ++ case RC_OPERATOR_NE: return value1->value.i32 != value2->value.i32; ++ case RC_OPERATOR_LT: return value1->value.i32 < value2->value.i32; ++ case RC_OPERATOR_LE: return value1->value.i32 <= value2->value.i32; ++ case RC_OPERATOR_GT: return value1->value.i32 > value2->value.i32; ++ case RC_OPERATOR_GE: return value1->value.i32 >= value2->value.i32; ++ default: return 1; ++ } ++ ++ case RC_VALUE_TYPE_FLOAT: ++ return rc_typed_value_compare_floats(value1->value.f32, value2->value.f32, oper); ++ ++ default: ++ return 1; ++ } ++} +diff -rupbN melonDS.orig/src/rcheevos/src/rhash/aes.h melonDS.ra/src/rcheevos/src/rhash/aes.h +--- melonDS.orig/src/rcheevos/src/rhash/aes.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rhash/aes.h 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,49 @@ ++#ifndef AES_H ++#define AES_H ++ ++/* This file is sourced from https://github.com/kokke/tiny-AES-c, with unused code excised. ++ * This code is licensed under the Unlicense license, effectively public domain. ++ * https://github.com/kokke/tiny-AES-c/blob/f06ac37/unlicense.txt ++ */ ++ ++#include ++#include ++ ++#define AES_BLOCKLEN 16 /* Block length in bytes - AES is 128b block only */ ++#define AES_KEYLEN 16 /* Key length in bytes */ ++#define AES_keyExpSize 176 ++ ++struct AES_ctx ++{ ++ uint8_t RoundKey[AES_keyExpSize]; ++ uint8_t Iv[AES_BLOCKLEN]; ++}; ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++void AES_init_ctx(struct AES_ctx* ctx, const uint8_t key[AES_KEYLEN]); ++void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t key[AES_KEYLEN], const uint8_t iv[AES_BLOCKLEN]); ++void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t iv[AES_BLOCKLEN]); ++ ++/* buffer size MUST be mutile of AES_BLOCKLEN; ++ * Suggest https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme ++ * NOTES: you need to set IV in ctx via AES_init_ctx_iv() or AES_ctx_set_iv() ++ * no IV should ever be reused with the same key ++ */ ++void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length); ++ ++/* Same function for encrypting as for decrypting. ++ * IV is incremented for every block, and used after encryption as XOR-compliment for output ++ * Suggesting https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme ++ * NOTES: you need to set IV in ctx with AES_init_ctx_iv() or AES_ctx_set_iv() ++ * no IV should ever be reused with the same key ++ */ ++void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* AES_H */ +diff -rupbN melonDS.orig/src/rcheevos/src/rhash/cdreader.c melonDS.ra/src/rcheevos/src/rhash/cdreader.c +--- melonDS.orig/src/rcheevos/src/rhash/cdreader.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rhash/cdreader.c 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,838 @@ ++#include "rc_hash_internal.h" ++ ++#include "../rc_compat.h" ++ ++#include ++#include ++#include ++ ++static int cdreader_get_sector(uint8_t header[16]) ++{ ++ int minutes = (header[12] >> 4) * 10 + (header[12] & 0x0F); ++ int seconds = (header[13] >> 4) * 10 + (header[13] & 0x0F); ++ int frames = (header[14] >> 4) * 10 + (header[14] & 0x0F); ++ ++ /* convert the MSF value to a sector index, and subtract 150 (2 seconds) per: ++ * For data and mixed mode media (those conforming to ISO/IEC 10149), logical block address ++ * zero shall be assigned to the block at MSF address 00/02/00 */ ++ return ((minutes * 60) + seconds) * 75 + frames - 150; ++} ++ ++static void cdreader_determine_sector_size(rc_hash_cdrom_track_t* cdrom) ++{ ++ /* Attempt to determine the sector and header sizes. The CUE file may be lying. ++ * Look for the sync pattern using each of the supported sector sizes. ++ * Then check for the presence of "CD001", which is gauranteed to be in either the ++ * boot record or primary volume descriptor, one of which is always at sector 16. ++ */ ++ const uint8_t sync_pattern[] = { ++ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 ++ }; ++ ++ uint8_t header[32]; ++ const int64_t toc_sector = 16 + cdrom->track_pregap_sectors; ++ ++ cdrom->sector_size = 0; ++ cdrom->sector_header_size = 0; ++ cdrom->raw_data_size = 2048; ++ ++ cdrom->file_reader->seek(cdrom->file_handle, toc_sector * 2352 + cdrom->file_track_offset, SEEK_SET); ++ if (cdrom->file_reader->read(cdrom->file_handle, header, sizeof(header)) < sizeof(header)) ++ return; ++ ++ if (memcmp(header, sync_pattern, 12) == 0) ++ { ++ cdrom->sector_size = 2352; ++ ++ if (memcmp(&header[25], "CD001", 5) == 0) ++ cdrom->sector_header_size = 24; ++ else ++ cdrom->sector_header_size = 16; ++ ++ cdrom->track_first_sector = cdreader_get_sector(header) - (int)toc_sector; ++ } ++ else ++ { ++ cdrom->file_reader->seek(cdrom->file_handle, toc_sector * 2336 + cdrom->file_track_offset, SEEK_SET); ++ cdrom->file_reader->read(cdrom->file_handle, header, sizeof(header)); ++ ++ if (memcmp(header, sync_pattern, 12) == 0) ++ { ++ cdrom->sector_size = 2336; ++ ++ if (memcmp(&header[25], "CD001", 5) == 0) ++ cdrom->sector_header_size = 24; ++ else ++ cdrom->sector_header_size = 16; ++ ++ cdrom->track_first_sector = cdreader_get_sector(header) - (int)toc_sector; ++ } ++ else ++ { ++ cdrom->file_reader->seek(cdrom->file_handle, toc_sector * 2048 + cdrom->file_track_offset, SEEK_SET); ++ cdrom->file_reader->read(cdrom->file_handle, header, sizeof(header)); ++ ++ if (memcmp(&header[1], "CD001", 5) == 0) ++ { ++ cdrom->sector_size = 2048; ++ cdrom->sector_header_size = 0; ++ } ++ } ++ } ++} ++ ++static void* cdreader_open_bin_track(const char* path, uint32_t track, const rc_hash_iterator_t* iterator) ++{ ++ void* file_handle; ++ rc_hash_cdrom_track_t* cdrom; ++ ++ if (track > 1) { ++ rc_hash_iterator_verbose(iterator, "Cannot locate secondary tracks without a cue sheet"); ++ return NULL; ++ } ++ ++ file_handle = iterator->callbacks.filereader.open(path); ++ if (!file_handle) ++ return NULL; ++ ++ cdrom = (rc_hash_cdrom_track_t*)calloc(1, sizeof(*cdrom)); ++ if (!cdrom) ++ return NULL; ++ cdrom->file_reader = &iterator->callbacks.filereader; ++ cdrom->file_handle = file_handle; ++#ifndef NDEBUG ++ cdrom->track_id = track; ++#endif ++ ++ cdreader_determine_sector_size(cdrom); ++ ++ if (cdrom->sector_size == 0) ++ { ++ int64_t size; ++ ++ iterator->callbacks.filereader.seek(file_handle, 0, SEEK_END); ++ size = iterator->callbacks.filereader.tell(file_handle); ++ ++ if ((size % 2352) == 0) ++ { ++ /* raw tracks use all 2352 bytes and have a 24 byte header */ ++ cdrom->sector_size = 2352; ++ cdrom->sector_header_size = 24; ++ } ++ else if ((size % 2048) == 0) ++ { ++ /* cooked tracks eliminate all header/footer data */ ++ cdrom->sector_size = 2048; ++ cdrom->sector_header_size = 0; ++ } ++ else if ((size % 2336) == 0) ++ { ++ /* MODE 2 format without 16-byte sync data */ ++ cdrom->sector_size = 2336; ++ cdrom->sector_header_size = 8; ++ } ++ else ++ { ++ if (iterator->callbacks.filereader.close) ++ iterator->callbacks.filereader.close(file_handle); ++ free(cdrom); ++ ++ rc_hash_iterator_verbose(iterator, "Could not determine sector size"); ++ ++ return NULL; ++ } ++ } ++ ++ return cdrom; ++} ++ ++static int cdreader_open_bin(rc_hash_cdrom_track_t* cdrom, const char* path, const char* mode) ++{ ++ cdrom->file_handle = cdrom->file_reader->open(path); ++ if (!cdrom->file_handle) ++ return 0; ++ ++ /* determine sector size */ ++ cdreader_determine_sector_size(cdrom); ++ ++ /* could not determine, which means we'll probably have more issues later ++ * but use the CUE provided information anyway ++ */ ++ if (cdrom->sector_size == 0) ++ { ++ /* All of these modes have 2048 byte payloads. In MODE1/2352 and MODE2/2352 ++ * modes, the mode can actually be specified per sector to change the payload ++ * size, but that reduces the ability to recover from errors when the disc ++ * is damaged, so it's seldomly used, and when it is, it's mostly for audio ++ * or video data where a blip or two probably won't be noticed by the user. ++ * So, while we techincally support all of the following modes, we only do ++ * so with 2048 byte payloads. ++ * http://totalsonicmastering.com/cuesheetsyntax.htm ++ * MODE1/2048 ? CDROM Mode1 Data (cooked) [no header, no footer] ++ * MODE1/2352 ? CDROM Mode1 Data (raw) [16 byte header, 288 byte footer] ++ * MODE2/2336 ? CDROM-XA Mode2 Data [8 byte header, 280 byte footer] ++ * MODE2/2352 ? CDROM-XA Mode2 Data [24 byte header, 280 byte footer] ++ */ ++ if (memcmp(mode, "MODE2/2352", 10) == 0) ++ { ++ cdrom->sector_size = 2352; ++ cdrom->sector_header_size = 24; ++ } ++ else if (memcmp(mode, "MODE1/2048", 10) == 0) ++ { ++ cdrom->sector_size = 2048; ++ cdrom->sector_header_size = 0; ++ } ++ else if (memcmp(mode, "MODE2/2336", 10) == 0) ++ { ++ cdrom->sector_size = 2336; ++ cdrom->sector_header_size = 8; ++ } ++ else if (memcmp(mode, "MODE1/2352", 10) == 0) ++ { ++ cdrom->sector_size = 2352; ++ cdrom->sector_header_size = 16; ++ } ++ else if (memcmp(mode, "AUDIO", 5) == 0) ++ { ++ cdrom->sector_size = 2352; ++ cdrom->sector_header_size = 0; ++ cdrom->raw_data_size = 2352; /* no header or footer data on audio tracks */ ++ } ++ } ++ ++ return (cdrom->sector_size != 0); ++} ++ ++static char* cdreader_get_bin_path(const char* cue_path, const char* bin_name, const rc_hash_iterator_t* iterator) ++{ ++ const char* filename = rc_path_get_filename(cue_path); ++ const size_t bin_name_len = strlen(bin_name); ++ const size_t cue_path_len = filename - cue_path; ++ const size_t needed = cue_path_len + bin_name_len + 1; ++ ++ char* bin_filename = (char*)malloc(needed); ++ if (!bin_filename) ++ { ++ rc_hash_iterator_error_formatted(iterator, "Failed to allocate %u bytes", (unsigned)needed); ++ } ++ else ++ { ++ memcpy(bin_filename, cue_path, cue_path_len); ++ memcpy(bin_filename + cue_path_len, bin_name, bin_name_len + 1); ++ } ++ ++ return bin_filename; ++} ++ ++static int64_t cdreader_get_bin_size(const char* cue_path, const char* bin_name, const rc_hash_iterator_t* iterator) ++{ ++ int64_t size = 0; ++ char* bin_filename = cdreader_get_bin_path(cue_path, bin_name, iterator); ++ if (bin_filename) ++ { ++ void* handle = iterator->callbacks.filereader.open(bin_filename); ++ if (handle) ++ { ++ iterator->callbacks.filereader.seek(handle, 0, SEEK_END); ++ size = iterator->callbacks.filereader.tell(handle); ++ ++ if (iterator->callbacks.filereader.close) ++ iterator->callbacks.filereader.close(handle); ++ } ++ ++ free(bin_filename); ++ } ++ ++ return size; ++} ++ ++static void* cdreader_open_cue_track(const char* path, uint32_t track, const rc_hash_iterator_t* iterator) ++{ ++ void* cue_handle; ++ int64_t cue_offset = 0; ++ char buffer[1024]; ++ char* bin_filename = NULL; ++ char *ptr, *ptr2, *end; ++ int done = 0; ++ int session = 1; ++ size_t num_read = 0; ++ rc_hash_cdrom_track_t* cdrom = NULL; ++ ++ struct track_t ++ { ++ uint32_t id; ++ int sector_size; ++ int sector_count; ++ int first_sector; ++ int pregap_sectors; ++ int is_data; ++ int file_track_offset; ++ int file_first_sector; ++ char mode[16]; ++ char filename[256]; ++ } current_track, previous_track, largest_track; ++ ++ cue_handle = iterator->callbacks.filereader.open(path); ++ if (!cue_handle) ++ return NULL; ++ ++ memset(¤t_track, 0, sizeof(current_track)); ++ memset(&previous_track, 0, sizeof(previous_track)); ++ memset(&largest_track, 0, sizeof(largest_track)); ++ ++ do ++ { ++ num_read = iterator->callbacks.filereader.read(cue_handle, buffer, sizeof(buffer) - 1); ++ if (num_read == 0) ++ break; ++ ++ buffer[num_read] = 0; ++ if (num_read == sizeof(buffer) - 1) ++ end = buffer + sizeof(buffer) * 3 / 4; ++ else ++ end = buffer + num_read; ++ ++ for (ptr = buffer; ptr < end; ++ptr) ++ { ++ while (*ptr == ' ') ++ ++ptr; ++ ++ if (strncasecmp(ptr, "INDEX ", 6) == 0) ++ { ++ int m = 0, s = 0, f = 0; ++ int index; ++ int sector_offset; ++ ++ ptr += 6; ++ index = atoi(ptr); ++ ++ while (*ptr != ' ' && *ptr != '\n') ++ ++ptr; ++ while (*ptr == ' ') ++ ++ptr; ++ ++ /* convert mm:ss:ff to sector count */ ++ sscanf_s(ptr, "%d:%d:%d", &m, &s, &f); ++ sector_offset = ((m * 60) + s) * 75 + f; ++ ++ if (current_track.first_sector == -1) ++ { ++ current_track.first_sector = sector_offset; ++ if (strcmp(current_track.filename, previous_track.filename) == 0) ++ { ++ previous_track.sector_count = current_track.first_sector - previous_track.first_sector; ++ current_track.file_track_offset += previous_track.sector_count * previous_track.sector_size; ++ } ++ ++ /* if looking for the largest data track, determine previous track size */ ++ if (track == RC_HASH_CDTRACK_LARGEST && previous_track.sector_count > largest_track.sector_count && ++ previous_track.is_data) ++ { ++ memcpy(&largest_track, &previous_track, sizeof(largest_track)); ++ } ++ } ++ ++ if (index == 1) ++ { ++ current_track.pregap_sectors = (sector_offset - current_track.first_sector); ++ ++ { ++ char* scan = current_track.mode; ++ while (*scan && !isspace((unsigned char)*scan)) ++ ++scan; ++ *scan = '\0'; ++ ++ /* it's undesirable to truncate offset to 32-bits, but %lld isn't defined in c89. */ ++ rc_hash_iterator_verbose_formatted(iterator, "Found %s track %d (first sector %d, sector size %d, %d pregap sectors)", ++ current_track.mode, current_track.id, current_track.first_sector, current_track.sector_size, current_track.pregap_sectors); ++ } ++ ++ if (current_track.id == track) ++ { ++ done = 1; ++ break; ++ } ++ ++ if (track == RC_HASH_CDTRACK_FIRST_DATA && current_track.is_data) ++ { ++ track = current_track.id; ++ done = 1; ++ break; ++ } ++ ++ if (track == RC_HASH_CDTRACK_FIRST_OF_SECOND_SESSION && session == 2) ++ { ++ track = current_track.id; ++ done = 1; ++ break; ++ } ++ } ++ } ++ else if (strncasecmp(ptr, "TRACK ", 6) == 0) ++ { ++ if (current_track.sector_size) ++ memcpy(&previous_track, ¤t_track, sizeof(current_track)); ++ ++ ptr += 6; ++ current_track.id = atoi(ptr); ++ ++ current_track.pregap_sectors = -1; ++ current_track.first_sector = -1; ++ ++ while (*ptr != ' ') ++ ++ptr; ++ while (*ptr == ' ') ++ ++ptr; ++ memcpy(current_track.mode, ptr, sizeof(current_track.mode)); ++ current_track.is_data = (memcmp(current_track.mode, "MODE", 4) == 0); ++ ++ if (current_track.is_data) ++ { ++ current_track.sector_size = atoi(ptr + 6); ++ } ++ else ++ { ++ /* assume AUDIO */ ++ current_track.sector_size = 2352; ++ } ++ } ++ else if (strncasecmp(ptr, "FILE ", 5) == 0) ++ { ++ if (current_track.sector_size) ++ { ++ memcpy(&previous_track, ¤t_track, sizeof(previous_track)); ++ ++ if (previous_track.sector_count == 0) ++ { ++ const int64_t bin_size = cdreader_get_bin_size(path, previous_track.filename, iterator); ++ const uint32_t file_sector_count = (uint32_t)bin_size / previous_track.sector_size; ++ previous_track.sector_count = file_sector_count - previous_track.first_sector; ++ } ++ ++ /* if looking for the largest data track, check to see if this one is larger */ ++ if (track == RC_HASH_CDTRACK_LARGEST && previous_track.is_data && ++ previous_track.sector_count > largest_track.sector_count) ++ { ++ memcpy(&largest_track, &previous_track, sizeof(largest_track)); ++ } ++ } ++ ++ memset(¤t_track, 0, sizeof(current_track)); ++ ++ current_track.file_first_sector = previous_track.file_first_sector + ++ previous_track.first_sector + previous_track.sector_count; ++ ++ ptr += 5; ++ ptr2 = ptr; ++ if (*ptr == '"') ++ { ++ ++ptr; ++ do ++ { ++ ++ptr2; ++ } while (*ptr2 && *ptr2 != '\n' && *ptr2 != '"'); ++ } ++ else ++ { ++ do ++ { ++ ++ptr2; ++ } while (*ptr2 && *ptr2 != '\n' && *ptr2 != ' '); ++ } ++ ++ if (ptr2 - ptr < (int)sizeof(current_track.filename)) ++ memcpy(current_track.filename, ptr, ptr2 - ptr); ++ } ++ else if (strncasecmp(ptr, "REM ", 4) == 0) ++ { ++ ptr += 4; ++ while (*ptr == ' ') ++ ++ptr; ++ ++ if (strncasecmp(ptr, "SESSION ", 8) == 0) ++ { ++ ptr += 8; ++ while (*ptr == ' ') ++ ++ptr; ++ session = atoi(ptr); ++ } ++ } ++ ++ while (*ptr && *ptr != '\n') ++ ++ptr; ++ } ++ ++ if (done) ++ break; ++ ++ cue_offset += (ptr - buffer); ++ iterator->callbacks.filereader.seek(cue_handle, cue_offset, SEEK_SET); ++ ++ } while (1); ++ ++ if (iterator->callbacks.filereader.close) ++ iterator->callbacks.filereader.close(cue_handle); ++ ++ if (track == RC_HASH_CDTRACK_LARGEST) ++ { ++ if (current_track.sector_size && current_track.is_data) ++ { ++ const int64_t bin_size = cdreader_get_bin_size(path, current_track.filename, iterator); ++ const uint32_t file_sector_count = (uint32_t)bin_size / current_track.sector_size; ++ current_track.sector_count = file_sector_count - current_track.first_sector; ++ ++ if (largest_track.sector_count > current_track.sector_count) ++ memcpy(¤t_track, &largest_track, sizeof(current_track)); ++ } ++ else ++ { ++ memcpy(¤t_track, &largest_track, sizeof(current_track)); ++ } ++ ++ track = current_track.id; ++ } ++ else if (track == RC_HASH_CDTRACK_LAST && !done) ++ { ++ track = current_track.id; ++ } ++ ++ if (current_track.id == track) ++ { ++ cdrom = (rc_hash_cdrom_track_t*)calloc(1, sizeof(*cdrom)); ++ if (!cdrom) ++ { ++ rc_hash_iterator_error_formatted(iterator, "Failed to allocate %u bytes", (unsigned)sizeof(*cdrom)); ++ return NULL; ++ } ++ ++ cdrom->file_reader = &iterator->callbacks.filereader; ++ cdrom->file_track_offset = current_track.file_track_offset; ++ cdrom->track_pregap_sectors = current_track.pregap_sectors; ++ cdrom->track_first_sector = current_track.file_first_sector + current_track.first_sector; ++#ifndef NDEBUG ++ cdrom->track_id = current_track.id; ++#endif ++ ++ /* verify existance of bin file */ ++ bin_filename = cdreader_get_bin_path(path, current_track.filename, iterator); ++ if (bin_filename) ++ { ++ if (cdreader_open_bin(cdrom, bin_filename, current_track.mode)) ++ { ++ if (cdrom->track_pregap_sectors) ++ rc_hash_iterator_verbose_formatted(iterator, "Opened track %d (sector size %d, %d pregap sectors)", ++ track, cdrom->sector_size, cdrom->track_pregap_sectors); ++ else ++ rc_hash_iterator_verbose_formatted(iterator, "Opened track %d (sector size %d)", track, cdrom->sector_size); ++ } ++ else ++ { ++ if (cdrom->file_handle) ++ { ++ cdrom->file_reader->close(cdrom->file_handle); ++ rc_hash_iterator_error_formatted(iterator, "Could not determine sector size for %s track", current_track.mode); ++ } ++ else ++ { ++ rc_hash_iterator_error_formatted(iterator, "Could not open %s", bin_filename); ++ } ++ ++ free(cdrom); ++ cdrom = NULL; ++ } ++ ++ free(bin_filename); ++ } ++ } ++ ++ return cdrom; ++} ++ ++static void* cdreader_open_gdi_track(const char* path, uint32_t track, const rc_hash_iterator_t* iterator) ++{ ++ void* file_handle; ++ char buffer[1024]; ++ char mode[16] = "MODE1/"; ++ char sector_size[16]; ++ char file[256]; ++ int64_t track_size; ++ int track_type; ++ char* bin_path = NULL; ++ uint32_t current_track = 0; ++ char* ptr, *ptr2, *end; ++ int lba = 0; ++ ++ uint32_t largest_track = 0; ++ int64_t largest_track_size = 0; ++ char largest_track_file[256]; ++ char largest_track_sector_size[16]; ++ int largest_track_lba = 0; ++ ++ int found = 0; ++ size_t num_read = 0; ++ int64_t file_offset = 0; ++ rc_hash_cdrom_track_t* cdrom = NULL; ++ ++ file_handle = iterator->callbacks.filereader.open(path); ++ if (!file_handle) ++ return NULL; ++ ++ file[0] = '\0'; ++ do ++ { ++ num_read = iterator->callbacks.filereader.read(file_handle, buffer, sizeof(buffer) - 1); ++ if (num_read == 0) ++ break; ++ ++ buffer[num_read] = 0; ++ if (num_read == sizeof(buffer) - 1) ++ end = buffer + sizeof(buffer) * 3 / 4; ++ else ++ end = buffer + num_read; ++ ++ ptr = buffer; ++ ++ /* the first line contains the number of tracks, so we can get the last track index from it */ ++ if (track == RC_HASH_CDTRACK_LAST) ++ track = atoi(ptr); ++ ++ /* first line contains the number of tracks and will be skipped */ ++ while (ptr < end) ++ { ++ /* skip until next newline */ ++ while (*ptr != '\n' && ptr < end) ++ ++ptr; ++ ++ /* skip newlines */ ++ while ((*ptr == '\n' || *ptr == '\r') && ptr < end) ++ ++ptr; ++ ++ /* line format: [trackid] [lba] [type] [sectorsize] [file] [?] */ ++ while (isspace((unsigned char)*ptr)) ++ ++ptr; ++ ++ current_track = (uint32_t)atoi(ptr); ++ if (track && current_track != track && track != RC_HASH_CDTRACK_FIRST_DATA) ++ continue; ++ ++ while (isdigit((unsigned char)*ptr)) ++ ++ptr; ++ ++ptr; ++ ++ while (isspace((unsigned char)*ptr)) ++ ++ptr; ++ ++ lba = atoi(ptr); ++ while (isdigit((unsigned char)*ptr)) ++ ++ptr; ++ ++ptr; ++ ++ while (isspace((unsigned char)*ptr)) ++ ++ptr; ++ ++ track_type = atoi(ptr); ++ while (isdigit((unsigned char)*ptr)) ++ ++ptr; ++ ++ptr; ++ ++ while (isspace((unsigned char)*ptr)) ++ ++ptr; ++ ++ ptr2 = sector_size; ++ while (isdigit((unsigned char)*ptr)) ++ *ptr2++ = *ptr++; ++ *ptr2 = '\0'; ++ ++ptr; ++ ++ while (isspace((unsigned char)*ptr)) ++ ++ptr; ++ ++ ptr2 = file; ++ if (*ptr == '\"') ++ { ++ ++ptr; ++ while (*ptr != '\"') ++ *ptr2++ = *ptr++; ++ ++ptr; ++ } ++ else ++ { ++ while (*ptr != ' ') ++ *ptr2++ = *ptr++; ++ } ++ *ptr2 = '\0'; ++ ++ if (track == current_track) ++ { ++ found = 1; ++ break; ++ } ++ else if (track == RC_HASH_CDTRACK_FIRST_DATA && track_type == 4) ++ { ++ track = current_track; ++ found = 1; ++ break; ++ } ++ else if (track == RC_HASH_CDTRACK_LARGEST && track_type == 4) ++ { ++ track_size = cdreader_get_bin_size(path, file, iterator); ++ if (track_size > largest_track_size) ++ { ++ largest_track_size = track_size; ++ largest_track = current_track; ++ largest_track_lba = lba; ++ strcpy_s(largest_track_file, sizeof(largest_track_file), file); ++ strcpy_s(largest_track_sector_size, sizeof(largest_track_sector_size), sector_size); ++ } ++ } ++ } ++ ++ if (found) ++ break; ++ ++ file_offset += (ptr - buffer); ++ iterator->callbacks.filereader.seek(file_handle, file_offset, SEEK_SET); ++ ++ } while (1); ++ ++ if (iterator->callbacks.filereader.close) ++ iterator->callbacks.filereader.close(file_handle); ++ ++ cdrom = (rc_hash_cdrom_track_t*)calloc(1, sizeof(*cdrom)); ++ if (!cdrom) ++ { ++ rc_hash_iterator_error_formatted(iterator, "Failed to allocate %u bytes", (unsigned)sizeof(*cdrom)); ++ return NULL; ++ } ++ ++ cdrom->file_reader = &iterator->callbacks.filereader; ++ ++ /* if we were tracking the largest track, make it the current track. ++ * otherwise, current_track will be the requested track, or last track. */ ++ if (largest_track != 0 && largest_track != current_track) ++ { ++ current_track = largest_track; ++ strcpy_s(file, sizeof(file), largest_track_file); ++ strcpy_s(sector_size, sizeof(sector_size), largest_track_sector_size); ++ lba = largest_track_lba; ++ } ++ ++ /* open the bin file for the track - construct mode parameter from sector_size */ ++ ptr = &mode[6]; ++ ptr2 = sector_size; ++ while (*ptr2 && *ptr2 != '\"') ++ *ptr++ = *ptr2++; ++ *ptr = '\0'; ++ ++ bin_path = cdreader_get_bin_path(path, file, iterator); ++ if (cdreader_open_bin(cdrom, bin_path, mode)) ++ { ++ cdrom->track_pregap_sectors = 0; ++ cdrom->track_first_sector = lba; ++#ifndef NDEBUG ++ cdrom->track_id = current_track; ++#endif ++ ++ rc_hash_iterator_verbose_formatted(iterator, "Opened track %d (sector size %d)", current_track, cdrom->sector_size); ++ } ++ else ++ { ++ rc_hash_iterator_error_formatted(iterator, "Could not open %s", bin_path); ++ ++ free(cdrom); ++ cdrom = NULL; ++ } ++ ++ free(bin_path); ++ ++ return cdrom; ++} ++ ++static void* cdreader_open_track_iterator(const char* path, uint32_t track, const rc_hash_iterator_t* iterator) ++{ ++ /* backwards compatibility - 0 used to mean largest */ ++ if (track == 0) ++ track = RC_HASH_CDTRACK_LARGEST; ++ ++ if (rc_path_compare_extension(path, "cue")) ++ return cdreader_open_cue_track(path, track, iterator); ++ if (rc_path_compare_extension(path, "gdi")) ++ return cdreader_open_gdi_track(path, track, iterator); ++ ++ return cdreader_open_bin_track(path, track, iterator); ++} ++ ++static size_t cdreader_read_sector(void* track_handle, uint32_t sector, void* buffer, size_t requested_bytes) ++{ ++ int64_t sector_start; ++ size_t num_read, total_read = 0; ++ uint8_t* buffer_ptr = (uint8_t*)buffer; ++ ++ rc_hash_cdrom_track_t* cdrom = (rc_hash_cdrom_track_t*)track_handle; ++ if (!cdrom) ++ return 0; ++ ++ if (sector < (uint32_t)cdrom->track_first_sector) ++ return 0; ++ ++ sector_start = (int64_t)(sector - cdrom->track_first_sector) * cdrom->sector_size + ++ cdrom->sector_header_size + cdrom->file_track_offset; ++ ++ while (requested_bytes > (size_t)cdrom->raw_data_size) ++ { ++ cdrom->file_reader->seek(cdrom->file_handle, sector_start, SEEK_SET); ++ num_read = cdrom->file_reader->read(cdrom->file_handle, buffer_ptr, cdrom->raw_data_size); ++ total_read += num_read; ++ ++ if (num_read < (size_t)cdrom->raw_data_size) ++ return total_read; ++ ++ buffer_ptr += cdrom->raw_data_size; ++ sector_start += cdrom->sector_size; ++ requested_bytes -= cdrom->raw_data_size; ++ } ++ ++ cdrom->file_reader->seek(cdrom->file_handle, sector_start, SEEK_SET); ++ num_read = cdrom->file_reader->read(cdrom->file_handle, buffer_ptr, (int)requested_bytes); ++ total_read += num_read; ++ ++ return total_read; ++} ++ ++static void cdreader_close_track(void* track_handle) ++{ ++ rc_hash_cdrom_track_t* cdrom = (rc_hash_cdrom_track_t*)track_handle; ++ if (cdrom) ++ { ++ if (cdrom->file_handle && cdrom->file_reader->close) ++ cdrom->file_reader->close(cdrom->file_handle); ++ ++ free(track_handle); ++ } ++} ++ ++static uint32_t cdreader_first_track_sector(void* track_handle) ++{ ++ rc_hash_cdrom_track_t* cdrom = (rc_hash_cdrom_track_t*)track_handle; ++ if (cdrom) ++ return cdrom->track_first_sector + cdrom->track_pregap_sectors; ++ ++ return 0; ++} ++ ++void rc_hash_get_default_cdreader(struct rc_hash_cdreader* cdreader) ++{ ++ cdreader->open_track = NULL; ++ cdreader->read_sector = cdreader_read_sector; ++ cdreader->close_track = cdreader_close_track; ++ cdreader->first_track_sector = cdreader_first_track_sector; ++ cdreader->open_track_iterator = cdreader_open_track_iterator; ++} ++ ++void rc_hash_init_default_cdreader(void) ++{ ++ struct rc_hash_cdreader cdreader; ++ rc_hash_get_default_cdreader(&cdreader); ++ rc_hash_init_custom_cdreader(&cdreader); ++} +diff -rupbN melonDS.orig/src/rcheevos/src/rhash/hash.c melonDS.ra/src/rcheevos/src/rhash/hash.c +--- melonDS.orig/src/rcheevos/src/rhash/hash.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rhash/hash.c 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,1402 @@ ++#include "rc_hash.h" ++ ++#include "rc_hash_internal.h" ++ ++#include "../rc_compat.h" ++ ++#if defined(_WIN32) ++#define WIN32_LEAN_AND_MEAN ++#include ++#include ++#endif ++ ++#include ++#include ++ ++const char* rc_path_get_filename(const char* path); ++static int rc_hash_from_file(char hash[33], uint32_t console_id, const rc_hash_iterator_t* iterator); ++ ++/* ===================================================== */ ++ ++static rc_hash_message_callback_deprecated g_error_message_callback = NULL; ++static rc_hash_message_callback_deprecated g_verbose_message_callback = NULL; ++ ++static void rc_hash_call_g_error_message_callback(const char* message, const rc_hash_iterator_t* iterator) ++{ ++ (void)iterator; ++ g_error_message_callback(message); ++} ++ ++static void rc_hash_call_g_verbose_message_callback(const char* message, const rc_hash_iterator_t* iterator) ++{ ++ (void)iterator; ++ g_verbose_message_callback(message); ++} ++ ++static void rc_hash_dispatch_message_va(const rc_hash_message_callback_func callback, ++ const rc_hash_iterator_t* iterator, const char* format, va_list args) ++{ ++ char buffer[1024]; ++ ++#ifdef __STDC_SECURE_LIB__ ++ vsprintf_s(buffer, sizeof(buffer), format, args); ++#elif __STDC_VERSION__ >= 199901L /* vsnprintf requires c99 */ ++ vsnprintf(buffer, sizeof(buffer), format, args); ++#else /* c89 doesn't have a size-limited vsprintf function - assume the buffer is large enough */ ++ vsprintf(buffer, format, args); ++#endif ++ ++ callback(buffer, iterator); ++} ++ ++void rc_hash_init_error_message_callback(rc_hash_message_callback_deprecated callback) ++{ ++ g_error_message_callback = callback; ++} ++ ++static rc_hash_message_callback_func rc_hash_get_error_message_callback(const rc_hash_callbacks_t* callbacks) ++{ ++ if (callbacks && callbacks->error_message) ++ return callbacks->error_message; ++ ++ if (g_error_message_callback) ++ return rc_hash_call_g_error_message_callback; ++ ++ if (callbacks && callbacks->verbose_message) ++ return callbacks->verbose_message; ++ ++ if (g_verbose_message_callback) ++ return rc_hash_call_g_verbose_message_callback; ++ ++ return NULL; ++} ++ ++int rc_hash_iterator_error(const rc_hash_iterator_t* iterator, const char* message) ++{ ++ rc_hash_message_callback_func message_callback = rc_hash_get_error_message_callback(&iterator->callbacks); ++ ++ if (message_callback) ++ message_callback(message, iterator); ++ ++ return 0; ++} ++ ++int rc_hash_iterator_error_formatted(const rc_hash_iterator_t* iterator, const char* format, ...) ++{ ++ rc_hash_message_callback_func message_callback = rc_hash_get_error_message_callback(&iterator->callbacks); ++ ++ if (message_callback) { ++ va_list args; ++ va_start(args, format); ++ rc_hash_dispatch_message_va(message_callback, iterator, format, args); ++ va_end(args); ++ } ++ ++ return 0; ++} ++ ++void rc_hash_init_verbose_message_callback(rc_hash_message_callback_deprecated callback) ++{ ++ g_verbose_message_callback = callback; ++} ++ ++void rc_hash_iterator_verbose(const rc_hash_iterator_t* iterator, const char* message) ++{ ++ if (iterator->callbacks.verbose_message) ++ iterator->callbacks.verbose_message(message, iterator); ++ else if (g_verbose_message_callback) ++ g_verbose_message_callback(message); ++} ++ ++void rc_hash_iterator_verbose_formatted(const rc_hash_iterator_t* iterator, const char* format, ...) ++{ ++ if (iterator->callbacks.verbose_message) { ++ va_list args; ++ va_start(args, format); ++ rc_hash_dispatch_message_va(iterator->callbacks.verbose_message, iterator, format, args); ++ va_end(args); ++ } ++ else if (g_verbose_message_callback) { ++ va_list args; ++ va_start(args, format); ++ rc_hash_dispatch_message_va(rc_hash_call_g_verbose_message_callback, iterator, format, args); ++ va_end(args); ++ } ++} ++ ++/* ===================================================== */ ++ ++static struct rc_hash_filereader g_filereader_funcs; ++static struct rc_hash_filereader* g_filereader = NULL; ++ ++#if defined(WINVER) && WINVER >= 0x0500 ++static void* filereader_open(const char* path) ++{ ++ /* Windows requires using wchar APIs for Unicode paths */ ++ /* Note that MultiByteToWideChar will only be defined for >= Windows 2000 */ ++ wchar_t* wpath; ++ int wpath_length; ++ FILE* fp; ++ ++ /* Calculate wpath length from path */ ++ wpath_length = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, path, -1, NULL, 0); ++ if (wpath_length == 0) /* 0 indicates error (this is likely from invalid UTF-8) */ ++ return NULL; ++ ++ wpath = (wchar_t*)malloc(wpath_length * sizeof(wchar_t)); ++ if (!wpath) ++ return NULL; ++ ++ if (MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, wpath_length) == 0) { ++ free(wpath); ++ return NULL; ++ } ++ ++ #if defined(__STDC_SECURE_LIB__) ++ /* have to use _SH_DENYNO because some cores lock the file while its loaded */ ++ fp = _wfsopen(wpath, L"rb", _SH_DENYNO); ++ #else ++ fp = _wfopen(wpath, L"rb"); ++ #endif ++ ++ free(wpath); ++ return fp; ++} ++#else /* !WINVER >= 0x0500 */ ++static void* filereader_open(const char* path) ++{ ++ #if defined(__STDC_SECURE_LIB__) ++ #if defined(WINVER) ++ /* have to use _SH_DENYNO because some cores lock the file while its loaded */ ++ return _fsopen(path, "rb", _SH_DENYNO); ++ #else /* !WINVER */ ++ FILE *fp; ++ fopen_s(&fp, path, "rb"); ++ return fp; ++ #endif ++ #else /* !__STDC_SECURE_LIB__ */ ++ return fopen(path, "rb"); ++ #endif ++} ++#endif /* WINVER >= 0x0500 */ ++ ++static void filereader_seek(void* file_handle, int64_t offset, int origin) ++{ ++#if defined(_WIN32) ++ _fseeki64((FILE*)file_handle, offset, origin); ++#elif defined(_LARGEFILE64_SOURCE) ++ fseeko64((FILE*)file_handle, offset, origin); ++#else ++ fseek((FILE*)file_handle, offset, origin); ++#endif ++} ++ ++static int64_t filereader_tell(void* file_handle) ++{ ++#if defined(_WIN32) ++ return _ftelli64((FILE*)file_handle); ++#elif defined(_LARGEFILE64_SOURCE) ++ return ftello64((FILE*)file_handle); ++#else ++ return ftell((FILE*)file_handle); ++#endif ++} ++ ++static size_t filereader_read(void* file_handle, void* buffer, size_t requested_bytes) ++{ ++ return fread(buffer, 1, requested_bytes, (FILE*)file_handle); ++} ++ ++static void filereader_close(void* file_handle) ++{ ++ fclose((FILE*)file_handle); ++} ++ ++/* for unit tests - normally would call rc_hash_init_custom_filereader(NULL) */ ++void rc_hash_reset_filereader(void) ++{ ++ g_filereader = NULL; ++} ++ ++void rc_hash_init_custom_filereader(struct rc_hash_filereader* reader) ++{ ++ /* initialize with defaults first */ ++ g_filereader_funcs.open = filereader_open; ++ g_filereader_funcs.seek = filereader_seek; ++ g_filereader_funcs.tell = filereader_tell; ++ g_filereader_funcs.read = filereader_read; ++ g_filereader_funcs.close = filereader_close; ++ ++ /* hook up any provided custom handlers */ ++ if (reader) { ++ if (reader->open) ++ g_filereader_funcs.open = reader->open; ++ ++ if (reader->seek) ++ g_filereader_funcs.seek = reader->seek; ++ ++ if (reader->tell) ++ g_filereader_funcs.tell = reader->tell; ++ ++ if (reader->read) ++ g_filereader_funcs.read = reader->read; ++ ++ if (reader->close) ++ g_filereader_funcs.close = reader->close; ++ } ++ ++ g_filereader = &g_filereader_funcs; ++} ++ ++void* rc_file_open(const rc_hash_iterator_t* iterator, const char* path) ++{ ++ void* handle = NULL; ++ ++ if (!iterator->callbacks.filereader.open) { ++ rc_hash_iterator_error(iterator, "No callback registered for opening files"); ++ } else { ++ handle = iterator->callbacks.filereader.open(path); ++ if (handle) ++ rc_hash_iterator_verbose_formatted(iterator, "Opened %s", rc_path_get_filename(path)); ++ } ++ ++ return handle; ++} ++ ++void rc_file_seek(const rc_hash_iterator_t* iterator, void* file_handle, int64_t offset, int origin) ++{ ++ if (iterator->callbacks.filereader.seek) ++ iterator->callbacks.filereader.seek(file_handle, offset, origin); ++} ++ ++int64_t rc_file_tell(const rc_hash_iterator_t* iterator, void* file_handle) ++{ ++ return iterator->callbacks.filereader.tell ? iterator->callbacks.filereader.tell(file_handle) : 0; ++} ++ ++size_t rc_file_read(const rc_hash_iterator_t* iterator, void* file_handle, void* buffer, int requested_bytes) ++{ ++ return iterator->callbacks.filereader.read ? iterator->callbacks.filereader.read(file_handle, buffer, requested_bytes) : 0; ++} ++ ++void rc_file_close(const rc_hash_iterator_t* iterator, void* file_handle) ++{ ++ if (iterator->callbacks.filereader.close) ++ iterator->callbacks.filereader.close(file_handle); ++} ++ ++int64_t rc_file_size(const rc_hash_iterator_t* iterator, const char* path) ++{ ++ int64_t size = 0; ++ ++ /* don't use rc_file_open to avoid log statements */ ++ if (!iterator->callbacks.filereader.open) { ++ rc_hash_iterator_error(iterator, "No callback registered for opening files"); ++ } else { ++ void* handle = iterator->callbacks.filereader.open(path); ++ if (handle) { ++ rc_file_seek(iterator, handle, 0, SEEK_END); ++ size = rc_file_tell(iterator, handle); ++ rc_file_close(iterator, handle); ++ } ++ } ++ ++ return size; ++} ++ ++/* ===================================================== */ ++ ++const char* rc_path_get_filename(const char* path) ++{ ++ const char* ptr = path + strlen(path); ++ do { ++ if (ptr[-1] == '/' || ptr[-1] == '\\') ++ break; ++ ++ --ptr; ++ } while (ptr > path); ++ ++ return ptr; ++} ++ ++const char* rc_path_get_extension(const char* path) ++{ ++ const char* ptr = path + strlen(path); ++ do { ++ if (ptr[-1] == '.') ++ return ptr; ++ ++ --ptr; ++ } while (ptr > path); ++ ++ return path + strlen(path); ++} ++ ++int rc_path_compare_extension(const char* path, const char* ext) ++{ ++ size_t path_len = strlen(path); ++ size_t ext_len = strlen(ext); ++ const char* ptr = path + path_len - ext_len; ++ if (ptr[-1] != '.') ++ return 0; ++ ++ if (memcmp(ptr, ext, ext_len) == 0) ++ return 1; ++ ++ do { ++ if (tolower(*ptr) != *ext) ++ return 0; ++ ++ ++ext; ++ ++ptr; ++ } while (*ptr); ++ ++ return 1; ++} ++ ++/* ===================================================== */ ++ ++void rc_hash_byteswap16(uint8_t* buffer, const uint8_t* stop) ++{ ++ uint32_t* ptr = (uint32_t*)buffer; ++ const uint32_t* stop32 = (const uint32_t*)stop; ++ while (ptr < stop32) { ++ uint32_t temp = *ptr; ++ temp = (temp & 0xFF00FF00) >> 8 | ++ (temp & 0x00FF00FF) << 8; ++ *ptr++ = temp; ++ } ++} ++ ++void rc_hash_byteswap32(uint8_t* buffer, const uint8_t* stop) ++{ ++ uint32_t* ptr = (uint32_t*)buffer; ++ const uint32_t* stop32 = (const uint32_t*)stop; ++ while (ptr < stop32) { ++ uint32_t temp = *ptr; ++ temp = (temp & 0xFF000000) >> 24 | ++ (temp & 0x00FF0000) >> 8 | ++ (temp & 0x0000FF00) << 8 | ++ (temp & 0x000000FF) << 24; ++ *ptr++ = temp; ++ } ++} ++ ++int rc_hash_finalize(const rc_hash_iterator_t* iterator, md5_state_t* md5, char hash[33]) ++{ ++ md5_byte_t digest[16]; ++ ++ md5_finish(md5, digest); ++ ++ /* NOTE: sizeof(hash) is 4 because it's still treated like a pointer, despite specifying a size */ ++ snprintf(hash, 33, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", ++ digest[0], digest[1], digest[2], digest[3], digest[4], digest[5], digest[6], digest[7], ++ digest[8], digest[9], digest[10], digest[11], digest[12], digest[13], digest[14], digest[15] ++ ); ++ ++ rc_hash_iterator_verbose_formatted(iterator, "Generated hash %s", hash); ++ ++ return 1; ++} ++ ++int rc_hash_buffer(char hash[33], const uint8_t* buffer, size_t buffer_size, const rc_hash_iterator_t* iterator) ++{ ++ md5_state_t md5; ++ ++ if (buffer_size > MAX_BUFFER_SIZE) ++ buffer_size = MAX_BUFFER_SIZE; ++ ++ md5_init(&md5); ++ ++ md5_append(&md5, buffer, (int)buffer_size); ++ ++ rc_hash_iterator_verbose_formatted(iterator, "Hashing %u byte buffer", (unsigned)buffer_size); ++ ++ return rc_hash_finalize(iterator, &md5, hash); ++} ++ ++struct rc_buffered_file ++{ ++ const uint8_t* read_ptr; ++ const uint8_t* data; ++ size_t data_size; ++}; ++ ++static struct rc_buffered_file rc_buffered_file; ++ ++static void* rc_file_open_buffered_file(const char* path) ++{ ++ struct rc_buffered_file* handle = (struct rc_buffered_file*)malloc(sizeof(struct rc_buffered_file)); ++ (void)path; ++ ++ if (handle) ++ memcpy(handle, &rc_buffered_file, sizeof(rc_buffered_file)); ++ ++ return handle; ++} ++ ++static void rc_file_seek_buffered_file(void* file_handle, int64_t offset, int origin) ++{ ++ struct rc_buffered_file* buffered_file = (struct rc_buffered_file*)file_handle; ++ switch (origin) { ++ case SEEK_SET: buffered_file->read_ptr = buffered_file->data + offset; break; ++ case SEEK_CUR: buffered_file->read_ptr += offset; break; ++ case SEEK_END: buffered_file->read_ptr = buffered_file->data + buffered_file->data_size + offset; break; ++ } ++ ++ if (buffered_file->read_ptr < buffered_file->data) ++ buffered_file->read_ptr = buffered_file->data; ++ else if (buffered_file->read_ptr > buffered_file->data + buffered_file->data_size) ++ buffered_file->read_ptr = buffered_file->data + buffered_file->data_size; ++} ++ ++static int64_t rc_file_tell_buffered_file(void* file_handle) ++{ ++ struct rc_buffered_file* buffered_file = (struct rc_buffered_file*)file_handle; ++ return (buffered_file->read_ptr - buffered_file->data); ++} ++ ++static size_t rc_file_read_buffered_file(void* file_handle, void* buffer, size_t requested_bytes) ++{ ++ struct rc_buffered_file* buffered_file = (struct rc_buffered_file*)file_handle; ++ const int64_t remaining = buffered_file->data_size - (buffered_file->read_ptr - buffered_file->data); ++ if ((int)requested_bytes > remaining) ++ requested_bytes = (int)remaining; ++ ++ memcpy(buffer, buffered_file->read_ptr, requested_bytes); ++ buffered_file->read_ptr += requested_bytes; ++ return requested_bytes; ++} ++ ++static void rc_file_close_buffered_file(void* file_handle) ++{ ++ free(file_handle); ++} ++ ++static int rc_hash_file_from_buffer(char hash[33], uint32_t console_id, const rc_hash_iterator_t* iterator) ++{ ++ int result; ++ ++ rc_hash_iterator_t buffered_file_iterator; ++ memset(&buffered_file_iterator, 0, sizeof(buffered_file_iterator)); ++ memcpy(&buffered_file_iterator.callbacks, &iterator->callbacks, sizeof(iterator->callbacks)); ++ buffered_file_iterator.userdata = iterator->userdata; ++ ++ buffered_file_iterator.callbacks.filereader.open = rc_file_open_buffered_file; ++ buffered_file_iterator.callbacks.filereader.close = rc_file_close_buffered_file; ++ buffered_file_iterator.callbacks.filereader.read = rc_file_read_buffered_file; ++ buffered_file_iterator.callbacks.filereader.seek = rc_file_seek_buffered_file; ++ buffered_file_iterator.callbacks.filereader.tell = rc_file_tell_buffered_file; ++ buffered_file_iterator.path = "memory stream"; ++ ++ rc_buffered_file.data = rc_buffered_file.read_ptr = iterator->buffer; ++ rc_buffered_file.data_size = iterator->buffer_size; ++ ++ result = rc_hash_from_file(hash, console_id, &buffered_file_iterator); ++ ++ buffered_file_iterator.path = NULL; ++ rc_hash_destroy_iterator(&buffered_file_iterator); ++ return result; ++} ++ ++static int rc_hash_from_buffer(char hash[33], uint32_t console_id, const rc_hash_iterator_t* iterator) ++{ ++ switch (console_id) { ++ default: ++ return rc_hash_iterator_error_formatted(iterator, "Unsupported console for buffer hash: %d", console_id); ++ ++ case RC_CONSOLE_AMSTRAD_PC: ++ case RC_CONSOLE_APPLE_II: ++ case RC_CONSOLE_ARCADIA_2001: ++ case RC_CONSOLE_ATARI_2600: ++ case RC_CONSOLE_ATARI_JAGUAR: ++ case RC_CONSOLE_COLECOVISION: ++ case RC_CONSOLE_COMMODORE_64: ++ case RC_CONSOLE_ELEKTOR_TV_GAMES_COMPUTER: ++ case RC_CONSOLE_FAIRCHILD_CHANNEL_F: ++ case RC_CONSOLE_GAMEBOY: ++ case RC_CONSOLE_GAMEBOY_ADVANCE: ++ case RC_CONSOLE_GAMEBOY_COLOR: ++ case RC_CONSOLE_GAME_GEAR: ++ case RC_CONSOLE_INTELLIVISION: ++ case RC_CONSOLE_INTERTON_VC_4000: ++ case RC_CONSOLE_MAGNAVOX_ODYSSEY2: ++ case RC_CONSOLE_MASTER_SYSTEM: ++ case RC_CONSOLE_MEGA_DRIVE: ++ case RC_CONSOLE_MEGADUCK: ++ case RC_CONSOLE_MSX: ++ case RC_CONSOLE_NEOGEO_POCKET: ++ case RC_CONSOLE_ORIC: ++ case RC_CONSOLE_PC8800: ++ case RC_CONSOLE_POKEMON_MINI: ++ case RC_CONSOLE_SEGA_32X: ++ case RC_CONSOLE_SG1000: ++ case RC_CONSOLE_SUPERVISION: ++ case RC_CONSOLE_TI83: ++ case RC_CONSOLE_TIC80: ++ case RC_CONSOLE_UZEBOX: ++ case RC_CONSOLE_VECTREX: ++ case RC_CONSOLE_VIRTUAL_BOY: ++ case RC_CONSOLE_WASM4: ++ case RC_CONSOLE_WONDERSWAN: ++ case RC_CONSOLE_ZX_SPECTRUM: ++ return rc_hash_buffer(hash, iterator->buffer, iterator->buffer_size, iterator); ++ ++#ifndef RC_HASH_NO_ROM ++ case RC_CONSOLE_ARDUBOY: ++ return rc_hash_arduboy(hash, iterator); ++ ++ case RC_CONSOLE_ATARI_7800: ++ return rc_hash_7800(hash, iterator); ++ ++ case RC_CONSOLE_ATARI_LYNX: ++ return rc_hash_lynx(hash, iterator); ++ ++ case RC_CONSOLE_FAMICOM_DISK_SYSTEM: ++ case RC_CONSOLE_NINTENDO: ++ return rc_hash_nes(hash, iterator); ++ ++ case RC_CONSOLE_PC_ENGINE: /* NOTE: does not support PCEngine CD */ ++ return rc_hash_pce(hash, iterator); ++ ++ case RC_CONSOLE_SUPER_CASSETTEVISION: ++ return rc_hash_scv(hash, iterator); ++ ++ case RC_CONSOLE_SUPER_NINTENDO: ++ return rc_hash_snes(hash, iterator); ++#endif ++ ++ case RC_CONSOLE_NINTENDO_64: ++ case RC_CONSOLE_NINTENDO_3DS: ++ case RC_CONSOLE_NINTENDO_DS: ++ case RC_CONSOLE_NINTENDO_DSI: ++ return rc_hash_file_from_buffer(hash, console_id, iterator); ++ } ++} ++ ++int rc_hash_whole_file(char hash[33], const rc_hash_iterator_t* iterator) ++{ ++ md5_state_t md5; ++ uint8_t* buffer; ++ int64_t size; ++ const size_t buffer_size = 65536; ++ void* file_handle; ++ size_t remaining; ++ int result = 0; ++ ++ file_handle = rc_file_open(iterator, iterator->path); ++ if (!file_handle) ++ return rc_hash_iterator_error(iterator, "Could not open file"); ++ ++ rc_file_seek(iterator, file_handle, 0, SEEK_END); ++ size = rc_file_tell(iterator, file_handle); ++ ++ if (size > MAX_BUFFER_SIZE) { ++ rc_hash_iterator_verbose_formatted(iterator, "Hashing first %u bytes (of %u bytes) of %s", MAX_BUFFER_SIZE, (unsigned)size, rc_path_get_filename(iterator->path)); ++ remaining = MAX_BUFFER_SIZE; ++ } ++ else { ++ rc_hash_iterator_verbose_formatted(iterator, "Hashing %s (%u bytes)", rc_path_get_filename(iterator->path), (unsigned)size); ++ remaining = (size_t)size; ++ } ++ ++ md5_init(&md5); ++ ++ buffer = (uint8_t*)malloc(buffer_size); ++ if (buffer) { ++ rc_file_seek(iterator, file_handle, 0, SEEK_SET); ++ while (remaining >= buffer_size) { ++ rc_file_read(iterator, file_handle, buffer, (int)buffer_size); ++ md5_append(&md5, buffer, (int)buffer_size); ++ remaining -= buffer_size; ++ } ++ ++ if (remaining > 0) { ++ rc_file_read(iterator, file_handle, buffer, (int)remaining); ++ md5_append(&md5, buffer, (int)remaining); ++ } ++ ++ free(buffer); ++ result = rc_hash_finalize(iterator, &md5, hash); ++ } ++ ++ rc_file_close(iterator, file_handle); ++ return result; ++} ++ ++int rc_hash_buffered_file(char hash[33], uint32_t console_id, const rc_hash_iterator_t* iterator) ++{ ++ uint8_t* buffer; ++ int64_t size; ++ int result = 0; ++ void* file_handle; ++ ++ file_handle = rc_file_open(iterator, iterator->path); ++ if (!file_handle) ++ return rc_hash_iterator_error(iterator, "Could not open file"); ++ ++ rc_file_seek(iterator, file_handle, 0, SEEK_END); ++ size = rc_file_tell(iterator, file_handle); ++ ++ if (size > MAX_BUFFER_SIZE) { ++ rc_hash_iterator_verbose_formatted(iterator, "Buffering first %u bytes (of %d bytes) of %s", MAX_BUFFER_SIZE, (unsigned)size, rc_path_get_filename(iterator->path)); ++ size = MAX_BUFFER_SIZE; ++ } ++ else { ++ rc_hash_iterator_verbose_formatted(iterator, "Buffering %s (%d bytes)", rc_path_get_filename(iterator->path), (unsigned)size); ++ } ++ ++ buffer = (uint8_t*)malloc((size_t)size); ++ if (buffer) { ++ rc_hash_iterator_t buffer_iterator; ++ memset(&buffer_iterator, 0, sizeof(buffer_iterator)); ++ memcpy(&buffer_iterator.callbacks, &iterator->callbacks, sizeof(iterator->callbacks)); ++ buffer_iterator.userdata = iterator->userdata; ++ buffer_iterator.path = iterator->path; ++ buffer_iterator.buffer = buffer; ++ buffer_iterator.buffer_size = (size_t)size; ++ ++ rc_file_seek(iterator, file_handle, 0, SEEK_SET); ++ rc_file_read(iterator, file_handle, buffer, (int)size); ++ ++ result = rc_hash_from_buffer(hash, console_id, &buffer_iterator); ++ ++ free(buffer); ++ } ++ ++ rc_file_close(iterator, file_handle); ++ return result; ++} ++ ++static int rc_hash_path_is_absolute(const char* path) ++{ ++ if (!path[0]) ++ return 0; ++ ++ /* "/path/to/file" or "\path\to\file" */ ++ if (path[0] == '/' || path[0] == '\\') ++ return 1; ++ ++ /* "C:\path\to\file" */ ++ if (path[1] == ':' && path[2] == '\\') ++ return 1; ++ ++ /* "scheme:/path/to/file" */ ++ while (*path) { ++ if (path[0] == ':' && path[1] == '/') ++ return 1; ++ ++ ++path; ++ } ++ ++ return 0; ++} ++ ++static const char* rc_hash_get_first_item_from_playlist(const rc_hash_iterator_t* iterator) { ++ char buffer[1024]; ++ char* disc_path; ++ char* ptr, *start, *next; ++ size_t num_read, path_len, file_len; ++ void* file_handle; ++ ++ file_handle = rc_file_open(iterator, iterator->path); ++ if (!file_handle) { ++ rc_hash_iterator_error(iterator, "Could not open playlist"); ++ return NULL; ++ } ++ ++ num_read = rc_file_read(iterator, file_handle, buffer, sizeof(buffer) - 1); ++ buffer[num_read] = '\0'; ++ ++ rc_file_close(iterator, file_handle); ++ ++ ptr = start = buffer; ++ do { ++ /* ignore empty and commented lines */ ++ while (*ptr == '#' || *ptr == '\r' || *ptr == '\n') { ++ while (*ptr && *ptr != '\n') ++ ++ptr; ++ if (*ptr) ++ ++ptr; ++ } ++ ++ /* find and extract the current line */ ++ start = ptr; ++ while (*ptr && *ptr != '\n') ++ ++ptr; ++ next = ptr; ++ ++ /* remove trailing whitespace - especially '\r' */ ++ while (ptr > start && isspace((unsigned char)ptr[-1])) ++ --ptr; ++ ++ /* if we found a non-empty line, break out of the loop to process it */ ++ file_len = ptr - start; ++ if (file_len) ++ break; ++ ++ /* did we reach the end of the file? */ ++ if (!*next) ++ return NULL; ++ ++ /* if the line only contained whitespace, keep searching */ ++ ptr = next + 1; ++ } while (1); ++ ++ rc_hash_iterator_verbose_formatted(iterator, "Extracted %.*s from playlist", (int)file_len, start); ++ ++ start[file_len++] = '\0'; ++ if (rc_hash_path_is_absolute(start)) ++ path_len = 0; ++ else ++ path_len = rc_path_get_filename(iterator->path) - iterator->path; ++ ++ disc_path = (char*)malloc(path_len + file_len + 1); ++ if (!disc_path) ++ return NULL; ++ ++ if (path_len) ++ memcpy(disc_path, iterator->path, path_len); ++ ++ memcpy(&disc_path[path_len], start, file_len); ++ return disc_path; ++} ++ ++static int rc_hash_generate_from_playlist(char hash[33], uint32_t console_id, const rc_hash_iterator_t* iterator) { ++ rc_hash_iterator_t first_file_iterator; ++ const char* disc_path; ++ int result; ++ ++ rc_hash_iterator_verbose_formatted(iterator, "Processing playlist: %s", rc_path_get_filename(iterator->path)); ++ ++ disc_path = rc_hash_get_first_item_from_playlist(iterator); ++ if (!disc_path) ++ return rc_hash_iterator_error(iterator, "Failed to get first item from playlist"); ++ ++ memset(&first_file_iterator, 0, sizeof(first_file_iterator)); ++ memcpy(&first_file_iterator.callbacks, &iterator->callbacks, sizeof(iterator->callbacks)); ++ first_file_iterator.userdata = iterator->userdata; ++ first_file_iterator.path = disc_path; /* rc_hash_destory_iterator will free */ ++ ++ result = rc_hash_from_file(hash, console_id, &first_file_iterator); ++ ++ rc_hash_destroy_iterator(&first_file_iterator); ++ return result; ++} ++ ++static int rc_hash_from_file(char hash[33], uint32_t console_id, const rc_hash_iterator_t* iterator) ++{ ++ const char* path = iterator->path; ++ ++ switch (console_id) { ++ default: ++ return rc_hash_iterator_error_formatted(iterator, "Unsupported console for file hash: %d", console_id); ++ ++ case RC_CONSOLE_ARCADIA_2001: ++ case RC_CONSOLE_ATARI_2600: ++ case RC_CONSOLE_ATARI_JAGUAR: ++ case RC_CONSOLE_COLECOVISION: ++ case RC_CONSOLE_ELEKTOR_TV_GAMES_COMPUTER: ++ case RC_CONSOLE_FAIRCHILD_CHANNEL_F: ++ case RC_CONSOLE_GAMEBOY: ++ case RC_CONSOLE_GAMEBOY_ADVANCE: ++ case RC_CONSOLE_GAMEBOY_COLOR: ++ case RC_CONSOLE_GAME_GEAR: ++ case RC_CONSOLE_INTELLIVISION: ++ case RC_CONSOLE_INTERTON_VC_4000: ++ case RC_CONSOLE_MAGNAVOX_ODYSSEY2: ++ case RC_CONSOLE_MASTER_SYSTEM: ++ case RC_CONSOLE_MEGADUCK: ++ case RC_CONSOLE_NEOGEO_POCKET: ++ case RC_CONSOLE_ORIC: ++ case RC_CONSOLE_POKEMON_MINI: ++ case RC_CONSOLE_SEGA_32X: ++ case RC_CONSOLE_SG1000: ++ case RC_CONSOLE_SUPERVISION: ++ case RC_CONSOLE_TI83: ++ case RC_CONSOLE_TIC80: ++ case RC_CONSOLE_UZEBOX: ++ case RC_CONSOLE_VECTREX: ++ case RC_CONSOLE_VIRTUAL_BOY: ++ case RC_CONSOLE_WASM4: ++ case RC_CONSOLE_WONDERSWAN: ++ case RC_CONSOLE_ZX_SPECTRUM: ++ /* generic whole-file hash - don't buffer */ ++ return rc_hash_whole_file(hash, iterator); ++ ++ case RC_CONSOLE_MEGA_DRIVE: ++ /* generic whole-file hash with m3u support - don't buffer */ ++ if (rc_path_compare_extension(path, "m3u")) ++ return rc_hash_generate_from_playlist(hash, console_id, iterator); ++ ++ return rc_hash_whole_file(hash, iterator); ++ ++ case RC_CONSOLE_ATARI_7800: ++ case RC_CONSOLE_ATARI_LYNX: ++ case RC_CONSOLE_FAMICOM_DISK_SYSTEM: ++ case RC_CONSOLE_NINTENDO: ++ case RC_CONSOLE_PC_ENGINE: ++ case RC_CONSOLE_SUPER_CASSETTEVISION: ++ case RC_CONSOLE_SUPER_NINTENDO: ++ /* additional logic whole-file hash - buffer then call rc_hash_generate_from_buffer */ ++ return rc_hash_buffered_file(hash, console_id, iterator); ++ ++ case RC_CONSOLE_AMSTRAD_PC: ++ case RC_CONSOLE_APPLE_II: ++ case RC_CONSOLE_COMMODORE_64: ++ case RC_CONSOLE_MSX: ++ case RC_CONSOLE_PC8800: ++ /* generic whole-file hash with m3u support - don't buffer */ ++ if (rc_path_compare_extension(path, "m3u")) ++ return rc_hash_generate_from_playlist(hash, console_id, iterator); ++ ++ return rc_hash_whole_file(hash, iterator); ++ ++#ifndef RC_HASH_NO_DISC ++ case RC_CONSOLE_3DO: ++ if (rc_path_compare_extension(path, "m3u")) ++ return rc_hash_generate_from_playlist(hash, console_id, iterator); ++ ++ return rc_hash_3do(hash, iterator); ++#endif ++ ++#ifndef RC_HASH_NO_ROM ++ case RC_CONSOLE_ARCADE: ++ return rc_hash_arcade(hash, iterator); ++ ++ case RC_CONSOLE_ARDUBOY: ++ return rc_hash_arduboy(hash, iterator); ++#endif ++ ++#ifndef RC_HASH_NO_DISC ++ case RC_CONSOLE_ATARI_JAGUAR_CD: ++ return rc_hash_jaguar_cd(hash, iterator); ++ ++ case RC_CONSOLE_DREAMCAST: ++ if (rc_path_compare_extension(path, "m3u")) ++ return rc_hash_generate_from_playlist(hash, console_id, iterator); ++ ++ return rc_hash_dreamcast(hash, iterator); ++ ++ case RC_CONSOLE_GAMECUBE: ++ return rc_hash_gamecube(hash, iterator); ++#endif ++ ++#ifndef RC_HASH_NO_ZIP ++ case RC_CONSOLE_MS_DOS: ++ return rc_hash_ms_dos(hash, iterator); ++#endif ++ ++#ifndef RC_HASH_NO_DISC ++ case RC_CONSOLE_NEO_GEO_CD: ++ return rc_hash_neogeo_cd(hash, iterator); ++#endif ++ ++#ifndef RC_HASH_NO_ROM ++ case RC_CONSOLE_NINTENDO_64: ++ return rc_hash_n64(hash, iterator); ++#endif ++ ++#ifndef RC_HASH_NO_ENCRYPTED ++ case RC_CONSOLE_NINTENDO_3DS: ++ return rc_hash_nintendo_3ds(hash, iterator); ++#endif ++ ++#ifndef RC_HASH_NO_ROM ++ case RC_CONSOLE_NINTENDO_DS: ++ case RC_CONSOLE_NINTENDO_DSI: ++ return rc_hash_nintendo_ds(hash, iterator); ++#endif ++ ++#ifndef RC_HASH_NO_DISC ++ case RC_CONSOLE_PC_ENGINE_CD: ++ if (rc_path_compare_extension(path, "cue") || rc_path_compare_extension(path, "chd")) ++ return rc_hash_pce_cd(hash, iterator); ++ ++ if (rc_path_compare_extension(path, "m3u")) ++ return rc_hash_generate_from_playlist(hash, console_id, iterator); ++ ++ return rc_hash_buffered_file(hash, console_id, iterator); ++ ++ case RC_CONSOLE_PCFX: ++ if (rc_path_compare_extension(path, "m3u")) ++ return rc_hash_generate_from_playlist(hash, console_id, iterator); ++ ++ return rc_hash_pcfx_cd(hash, iterator); ++ ++ case RC_CONSOLE_PLAYSTATION: ++ if (rc_path_compare_extension(path, "m3u")) ++ return rc_hash_generate_from_playlist(hash, console_id, iterator); ++ ++ return rc_hash_psx(hash, iterator); ++ ++ case RC_CONSOLE_PLAYSTATION_2: ++ if (rc_path_compare_extension(path, "m3u")) ++ return rc_hash_generate_from_playlist(hash, console_id, iterator); ++ ++ return rc_hash_ps2(hash, iterator); ++ ++ case RC_CONSOLE_PSP: ++ return rc_hash_psp(hash, iterator); ++ ++ case RC_CONSOLE_SEGA_CD: ++ case RC_CONSOLE_SATURN: ++ if (rc_path_compare_extension(path, "m3u")) ++ return rc_hash_generate_from_playlist(hash, console_id, iterator); ++ ++ return rc_hash_sega_cd(hash, iterator); ++ ++ case RC_CONSOLE_WII: ++ return rc_hash_wii(hash, iterator); ++#endif ++ } ++} ++ ++static void rc_hash_initialize_iterator_from_path(rc_hash_iterator_t* iterator, const char* path); ++ ++static void rc_hash_iterator_append_console(struct rc_hash_iterator* iterator, uint8_t console_id) { ++ int i = 0; ++ while (iterator->consoles[i] != 0) { ++ if (iterator->consoles[i] == console_id) ++ return; ++ ++ ++i; ++ } ++ ++ iterator->consoles[i] = console_id; ++} ++ ++void rc_hash_merge_callbacks(rc_hash_iterator_t* iterator, const rc_hash_callbacks_t* callbacks) ++{ ++ if (callbacks->verbose_message) ++ iterator->callbacks.verbose_message = callbacks->verbose_message; ++ if (callbacks->error_message) ++ iterator->callbacks.verbose_message = callbacks->error_message; ++ ++ if (callbacks->filereader.open) ++ memcpy(&iterator->callbacks.filereader, &callbacks->filereader, sizeof(callbacks->filereader)); ++ ++#ifndef RC_HASH_NO_DISC ++ if (callbacks->cdreader.open_track) ++ memcpy(&iterator->callbacks.cdreader, &callbacks->cdreader, sizeof(callbacks->cdreader)); ++#endif ++ ++#ifndef RC_HASH_NO_ENCRYPTED ++ if (callbacks->encryption.get_3ds_cia_normal_key) ++ iterator->callbacks.encryption.get_3ds_cia_normal_key = callbacks->encryption.get_3ds_cia_normal_key; ++ if (callbacks->encryption.get_3ds_ncch_normal_keys) ++ iterator->callbacks.encryption.get_3ds_ncch_normal_keys = callbacks->encryption.get_3ds_ncch_normal_keys; ++#endif ++} ++ ++ ++static void rc_hash_reset_iterator(rc_hash_iterator_t* iterator) { ++ memset(iterator, 0, sizeof(*iterator)); ++ iterator->index = -1; ++ ++ if (g_verbose_message_callback) ++ iterator->callbacks.verbose_message = rc_hash_call_g_verbose_message_callback; ++ if (g_error_message_callback) ++ iterator->callbacks.error_message = rc_hash_call_g_error_message_callback; ++ ++ if (g_filereader) { ++ memcpy(&iterator->callbacks.filereader, g_filereader, sizeof(*g_filereader)); ++ } else if (!iterator->callbacks.filereader.open) { ++ iterator->callbacks.filereader.open = filereader_open; ++ iterator->callbacks.filereader.close = filereader_close; ++ iterator->callbacks.filereader.seek = filereader_seek; ++ iterator->callbacks.filereader.tell = filereader_tell; ++ iterator->callbacks.filereader.read = filereader_read; ++ } ++ ++#ifndef RC_HASH_NO_DISC ++ rc_hash_reset_iterator_disc(iterator); ++#endif ++ ++#ifndef RC_HASH_NO_ENCRYPTED ++ rc_hash_reset_iterator_encrypted(iterator); ++#endif ++} ++ ++static void rc_hash_initialize_iterator_single(rc_hash_iterator_t* iterator, int data) { ++ iterator->consoles[0] = (uint8_t)data; ++} ++ ++static void rc_hash_initialize_iterator_bin(rc_hash_iterator_t* iterator, int data) { ++ (void)data; ++ ++ if (iterator->buffer_size == 0) { ++ /* raw bin file may be a CD track. if it's more than 32MB, try a CD hash. */ ++ const int64_t size = rc_file_size(iterator, iterator->path); ++ if (size > 32 * 1024 * 1024) { ++ iterator->consoles[0] = RC_CONSOLE_3DO; /* 4DO supports directly opening the bin file */ ++ iterator->consoles[1] = RC_CONSOLE_PLAYSTATION; /* PCSX ReARMed supports directly opening the bin file*/ ++ iterator->consoles[2] = RC_CONSOLE_PLAYSTATION_2; /* PCSX2 supports directly opening the bin file*/ ++ iterator->consoles[3] = RC_CONSOLE_SEGA_CD; /* Genesis Plus GX supports directly opening the bin file*/ ++ ++ /* fallback to megadrive which just does a full hash. */ ++ iterator->consoles[4] = RC_CONSOLE_MEGA_DRIVE; ++ return; ++ } ++ } ++ ++ /* bin is associated with MegaDrive, Sega32X, Atari 2600, Watara Supervision, MegaDuck, ++ * Fairchild Channel F, Arcadia 2001, Interton VC 4000, and Super Cassette Vision. ++ * Since they all use the same hashing algorithm, only specify one of them */ ++ iterator->consoles[0] = RC_CONSOLE_MEGA_DRIVE; ++} ++ ++static void rc_hash_initialize_iterator_chd(rc_hash_iterator_t* iterator, int data) { ++ (void)data; ++ ++ iterator->consoles[0] = RC_CONSOLE_PLAYSTATION; ++ iterator->consoles[1] = RC_CONSOLE_PLAYSTATION_2; ++ iterator->consoles[2] = RC_CONSOLE_DREAMCAST; ++ iterator->consoles[3] = RC_CONSOLE_SEGA_CD; /* ASSERT: handles both Sega CD and Saturn */ ++ iterator->consoles[4] = RC_CONSOLE_PSP; ++ iterator->consoles[5] = RC_CONSOLE_PC_ENGINE_CD; ++ iterator->consoles[6] = RC_CONSOLE_3DO; ++ iterator->consoles[7] = RC_CONSOLE_NEO_GEO_CD; ++ iterator->consoles[8] = RC_CONSOLE_PCFX; ++} ++ ++static void rc_hash_initialize_iterator_cue(rc_hash_iterator_t* iterator, int data) { ++ (void)data; ++ ++ iterator->consoles[0] = RC_CONSOLE_PLAYSTATION; ++ iterator->consoles[1] = RC_CONSOLE_PLAYSTATION_2; ++ iterator->consoles[2] = RC_CONSOLE_DREAMCAST; ++ iterator->consoles[3] = RC_CONSOLE_SEGA_CD; /* ASSERT: handles both Sega CD and Saturn */ ++ iterator->consoles[4] = RC_CONSOLE_PC_ENGINE_CD; ++ iterator->consoles[5] = RC_CONSOLE_3DO; ++ iterator->consoles[6] = RC_CONSOLE_PCFX; ++ iterator->consoles[7] = RC_CONSOLE_NEO_GEO_CD; ++ iterator->consoles[8] = RC_CONSOLE_ATARI_JAGUAR_CD; ++} ++ ++static void rc_hash_initialize_iterator_d88(rc_hash_iterator_t* iterator, int data) { ++ (void)data; ++ ++ iterator->consoles[0] = RC_CONSOLE_PC8800; ++ iterator->consoles[1] = RC_CONSOLE_SHARPX1; ++} ++ ++static void rc_hash_initialize_iterator_dsk(rc_hash_iterator_t* iterator, int data) { ++ size_t size = iterator->buffer_size; ++ if (size == 0) ++ size = (size_t)rc_file_size(iterator, iterator->path); ++ ++ (void)data; ++ ++ if (size == 512 * 9 * 80) { /* 360KB */ ++ /* FAT-12 3.5" DD (512 byte sectors, 9 sectors per track, 80 tracks per side */ ++ /* FAT-12 5.25" DD double-sided (512 byte sectors, 9 sectors per track, 80 tracks per side */ ++ iterator->consoles[0] = RC_CONSOLE_MSX; ++ } ++ else if (size == 512 * 9 * 80 * 2) { /* 720KB */ ++ /* FAT-12 3.5" DD double-sided (512 byte sectors, 9 sectors per track, 80 tracks per side */ ++ iterator->consoles[0] = RC_CONSOLE_MSX; ++ } ++ else if (size == 512 * 9 * 40) { /* 180KB */ ++ /* FAT-12 5.25" DD (512 byte sectors, 9 sectors per track, 40 tracks per side */ ++ iterator->consoles[0] = RC_CONSOLE_MSX; ++ ++ /* AMSDOS 3" - 40 tracks */ ++ iterator->consoles[1] = RC_CONSOLE_AMSTRAD_PC; ++ } ++ else if (size == 256 * 16 * 35) { /* 140KB */ ++ /* Apple II new format - 256 byte sectors, 16 sectors per track, 35 tracks per side */ ++ iterator->consoles[0] = RC_CONSOLE_APPLE_II; ++ } ++ else if (size == 256 * 13 * 35) { /* 113.75KB */ ++ /* Apple II old format - 256 byte sectors, 13 sectors per track, 35 tracks per side */ ++ iterator->consoles[0] = RC_CONSOLE_APPLE_II; ++ } ++ ++ /* once a best guess has been identified, make sure the others are added as fallbacks */ ++ ++ /* check MSX first, as Apple II isn't supported by RetroArch, and RAppleWin won't use the iterator */ ++ rc_hash_iterator_append_console(iterator, RC_CONSOLE_MSX); ++ rc_hash_iterator_append_console(iterator, RC_CONSOLE_AMSTRAD_PC); ++ rc_hash_iterator_append_console(iterator, RC_CONSOLE_ZX_SPECTRUM); ++ rc_hash_iterator_append_console(iterator, RC_CONSOLE_APPLE_II); ++} ++ ++static void rc_hash_initialize_iterator_iso(rc_hash_iterator_t* iterator, int data) { ++ (void)data; ++ ++ iterator->consoles[0] = RC_CONSOLE_PLAYSTATION_2; ++ iterator->consoles[1] = RC_CONSOLE_PSP; ++ iterator->consoles[2] = RC_CONSOLE_3DO; ++ iterator->consoles[3] = RC_CONSOLE_SEGA_CD; /* ASSERT: handles both Sega CD and Saturn */ ++ iterator->consoles[4] = RC_CONSOLE_GAMECUBE; ++ iterator->consoles[5] = RC_CONSOLE_WII; ++} ++ ++static void rc_hash_initialize_iterator_m3u(rc_hash_iterator_t* iterator, int data) { ++ const char* first_file_path; ++ ++ (void)data; ++ ++ /* temporarily set the iterator path to the m3u file so we can extract the ++ * path of the first disc. rc_hash_get_first_item_from_playlist will return ++ * an allocated string or NULL, so rc_hash_destroy_iterator won't get tripped ++ * up by the non-allocted value we're about to assign. ++ */ ++ first_file_path = rc_hash_get_first_item_from_playlist(iterator); ++ if (!first_file_path) /* did not find a disc */ ++ return; ++ ++ /* release the m3u path and replace with the first file path */ ++ free((void*)iterator->path); ++ iterator->path = first_file_path; /* assert: already malloc'd; don't need to strdup */ ++ ++ iterator->buffer = NULL; /* ignore buffer; assume it's the m3u contents */ ++ ++ rc_hash_initialize_iterator_from_path(iterator, iterator->path); ++} ++ ++static void rc_hash_initialize_iterator_nib(rc_hash_iterator_t* iterator, int data) { ++ (void)data; ++ ++ iterator->consoles[0] = RC_CONSOLE_APPLE_II; ++ iterator->consoles[1] = RC_CONSOLE_COMMODORE_64; ++} ++ ++static void rc_hash_initialize_iterator_rom(rc_hash_iterator_t* iterator, int data) { ++ (void)data; ++ ++ /* rom is associated with MSX, Thomson TO-8, and Fairchild Channel F. ++ * Since they all use the same hashing algorithm, only specify one of them */ ++ iterator->consoles[0] = RC_CONSOLE_MSX; ++} ++ ++static void rc_hash_initialize_iterator_tap(rc_hash_iterator_t* iterator, int data) { ++ (void)data; ++ ++ /* also Oric and ZX Spectrum, but all are full file hashes */ ++ iterator->consoles[0] = RC_CONSOLE_COMMODORE_64; ++} ++ ++static const rc_hash_iterator_ext_handler_entry_t rc_hash_iterator_ext_handlers[] = { ++ { "2d", rc_hash_initialize_iterator_single, RC_CONSOLE_SHARPX1 }, ++ { "3ds", rc_hash_initialize_iterator_single, RC_CONSOLE_NINTENDO_3DS }, ++ { "3dsx", rc_hash_initialize_iterator_single, RC_CONSOLE_NINTENDO_3DS }, ++ { "7z", rc_hash_initialize_iterator_single, RC_CONSOLE_ARCADE }, ++ { "83g", rc_hash_initialize_iterator_single, RC_CONSOLE_TI83 }, /* http://tibasicdev.wikidot.com/file-extensions */ ++ { "83p", rc_hash_initialize_iterator_single, RC_CONSOLE_TI83 }, ++ { "a26", rc_hash_initialize_iterator_single, RC_CONSOLE_ATARI_2600 }, ++ { "a78", rc_hash_initialize_iterator_single, RC_CONSOLE_ATARI_7800 }, ++ { "app", rc_hash_initialize_iterator_single, RC_CONSOLE_NINTENDO_3DS }, ++ { "arduboy", rc_hash_initialize_iterator_single, RC_CONSOLE_ARDUBOY }, ++ { "axf", rc_hash_initialize_iterator_single, RC_CONSOLE_NINTENDO_3DS }, ++ { "bin", rc_hash_initialize_iterator_bin, 0 }, ++ { "bs", rc_hash_initialize_iterator_single, RC_CONSOLE_SUPER_NINTENDO }, ++ { "cart", rc_hash_initialize_iterator_single, RC_CONSOLE_SUPER_CASSETTEVISION }, ++ { "cas", rc_hash_initialize_iterator_single, RC_CONSOLE_MSX }, ++ { "cci", rc_hash_initialize_iterator_single, RC_CONSOLE_NINTENDO_3DS }, ++ { "chd", rc_hash_initialize_iterator_chd, 0 }, ++ { "chf", rc_hash_initialize_iterator_single, RC_CONSOLE_FAIRCHILD_CHANNEL_F }, ++ { "cia", rc_hash_initialize_iterator_single, RC_CONSOLE_NINTENDO_3DS }, ++ { "col", rc_hash_initialize_iterator_single, RC_CONSOLE_COLECOVISION }, ++ { "csw", rc_hash_initialize_iterator_single, RC_CONSOLE_ZX_SPECTRUM }, ++ { "cue", rc_hash_initialize_iterator_cue, 0 }, ++ { "cxi", rc_hash_initialize_iterator_single, RC_CONSOLE_NINTENDO_3DS }, ++ { "d64", rc_hash_initialize_iterator_single, RC_CONSOLE_COMMODORE_64 }, ++ { "d88", rc_hash_initialize_iterator_d88, 0 }, ++ { "dosz", rc_hash_initialize_iterator_single, RC_CONSOLE_MS_DOS }, ++ { "dsk", rc_hash_initialize_iterator_dsk, 0 }, ++ { "elf", rc_hash_initialize_iterator_single, RC_CONSOLE_NINTENDO_3DS }, ++ { "fd", rc_hash_initialize_iterator_single, RC_CONSOLE_THOMSONTO8 }, ++ { "fds", rc_hash_initialize_iterator_single, RC_CONSOLE_NINTENDO }, ++ { "fig", rc_hash_initialize_iterator_single, RC_CONSOLE_SUPER_NINTENDO }, ++ { "gb", rc_hash_initialize_iterator_single, RC_CONSOLE_GAMEBOY }, ++ { "gba", rc_hash_initialize_iterator_single, RC_CONSOLE_GAMEBOY_ADVANCE }, ++ { "gbc", rc_hash_initialize_iterator_single, RC_CONSOLE_GAMEBOY_COLOR }, ++ { "gdi", rc_hash_initialize_iterator_single, RC_CONSOLE_DREAMCAST }, ++ { "gg", rc_hash_initialize_iterator_single, RC_CONSOLE_GAME_GEAR }, ++ { "hex", rc_hash_initialize_iterator_single, RC_CONSOLE_ARDUBOY }, ++ { "iso", rc_hash_initialize_iterator_iso, 0 }, ++ { "jag", rc_hash_initialize_iterator_single, RC_CONSOLE_ATARI_JAGUAR }, ++ { "k7", rc_hash_initialize_iterator_single, RC_CONSOLE_THOMSONTO8 }, /* tape */ ++ { "lnx", rc_hash_initialize_iterator_single, RC_CONSOLE_ATARI_LYNX }, ++ { "m3u", rc_hash_initialize_iterator_m3u, 0 }, ++ { "m5", rc_hash_initialize_iterator_single, RC_CONSOLE_THOMSONTO8 }, /* cartridge */ ++ { "m7", rc_hash_initialize_iterator_single, RC_CONSOLE_THOMSONTO8 }, /* cartridge */ ++ { "md", rc_hash_initialize_iterator_single, RC_CONSOLE_MEGA_DRIVE }, ++ { "min", rc_hash_initialize_iterator_single, RC_CONSOLE_POKEMON_MINI }, ++ { "mx1", rc_hash_initialize_iterator_single, RC_CONSOLE_MSX }, ++ { "mx2", rc_hash_initialize_iterator_single, RC_CONSOLE_MSX }, ++ { "n64", rc_hash_initialize_iterator_single, RC_CONSOLE_NINTENDO_64 }, ++ { "ndd", rc_hash_initialize_iterator_single, RC_CONSOLE_NINTENDO_64 }, ++ { "nds", rc_hash_initialize_iterator_single, RC_CONSOLE_NINTENDO_DS }, /* handles both DS and DSi */ ++ { "nes", rc_hash_initialize_iterator_single, RC_CONSOLE_NINTENDO }, ++ { "ngc", rc_hash_initialize_iterator_single, RC_CONSOLE_NEOGEO_POCKET }, ++ { "nib", rc_hash_initialize_iterator_nib, 0 }, ++ { "pbp", rc_hash_initialize_iterator_single, RC_CONSOLE_PSP }, ++ { "pce", rc_hash_initialize_iterator_single, RC_CONSOLE_PC_ENGINE }, ++ { "pgm", rc_hash_initialize_iterator_single, RC_CONSOLE_ELEKTOR_TV_GAMES_COMPUTER }, ++ { "pzx", rc_hash_initialize_iterator_single, RC_CONSOLE_ZX_SPECTRUM }, ++ { "ri", rc_hash_initialize_iterator_single, RC_CONSOLE_MSX }, ++ { "rom", rc_hash_initialize_iterator_rom, 0 }, ++ { "sap", rc_hash_initialize_iterator_single, RC_CONSOLE_THOMSONTO8 }, /* disk */ ++ { "scl", rc_hash_initialize_iterator_single, RC_CONSOLE_ZX_SPECTRUM }, ++ { "sfc", rc_hash_initialize_iterator_single, RC_CONSOLE_SUPER_NINTENDO }, ++ { "sg", rc_hash_initialize_iterator_single, RC_CONSOLE_SG1000 }, ++ { "sgx", rc_hash_initialize_iterator_single, RC_CONSOLE_PC_ENGINE }, ++ { "smc", rc_hash_initialize_iterator_single, RC_CONSOLE_SUPER_NINTENDO }, ++ { "sv", rc_hash_initialize_iterator_single, RC_CONSOLE_SUPERVISION }, ++ { "swc", rc_hash_initialize_iterator_single, RC_CONSOLE_SUPER_NINTENDO }, ++ { "tap", rc_hash_initialize_iterator_tap, 0 }, ++ { "tic", rc_hash_initialize_iterator_single, RC_CONSOLE_TIC80 }, ++ { "trd", rc_hash_initialize_iterator_single, RC_CONSOLE_ZX_SPECTRUM }, ++ { "tvc", rc_hash_initialize_iterator_single, RC_CONSOLE_ELEKTOR_TV_GAMES_COMPUTER }, ++ { "tzx", rc_hash_initialize_iterator_single, RC_CONSOLE_ZX_SPECTRUM }, ++ { "uze", rc_hash_initialize_iterator_single, RC_CONSOLE_UZEBOX }, ++ { "v64", rc_hash_initialize_iterator_single, RC_CONSOLE_NINTENDO_64 }, ++ { "vb", rc_hash_initialize_iterator_single, RC_CONSOLE_VIRTUAL_BOY }, ++ { "wad", rc_hash_initialize_iterator_single, RC_CONSOLE_WII }, ++ { "wasm", rc_hash_initialize_iterator_single, RC_CONSOLE_WASM4 }, ++ { "woz", rc_hash_initialize_iterator_single, RC_CONSOLE_APPLE_II }, ++ { "wsc", rc_hash_initialize_iterator_single, RC_CONSOLE_WONDERSWAN }, ++ { "z64", rc_hash_initialize_iterator_single, RC_CONSOLE_NINTENDO_64 }, ++ { "zip", rc_hash_initialize_iterator_single, RC_CONSOLE_ARCADE } ++}; ++ ++const rc_hash_iterator_ext_handler_entry_t* rc_hash_get_iterator_ext_handlers(size_t* num_handlers) { ++ *num_handlers = sizeof(rc_hash_iterator_ext_handlers) / sizeof(rc_hash_iterator_ext_handlers[0]); ++ return rc_hash_iterator_ext_handlers; ++} ++ ++static int rc_hash_iterator_find_handler(const void* left, const void* right) { ++ const rc_hash_iterator_ext_handler_entry_t* left_handler = ++ (const rc_hash_iterator_ext_handler_entry_t*)left; ++ const rc_hash_iterator_ext_handler_entry_t* right_handler = ++ (const rc_hash_iterator_ext_handler_entry_t*)right; ++ ++ return strcmp(left_handler->ext, right_handler->ext); ++} ++ ++static void rc_hash_initialize_iterator_from_path(rc_hash_iterator_t* iterator, const char* path) { ++ size_t num_handlers; ++ const rc_hash_iterator_ext_handler_entry_t* handlers = rc_hash_get_iterator_ext_handlers(&num_handlers); ++ const rc_hash_iterator_ext_handler_entry_t* handler; ++ rc_hash_iterator_ext_handler_entry_t search; ++ const char* ext = rc_path_get_extension(path); ++ size_t index; ++ ++ /* lowercase the extension as we copy it into the search object */ ++ memset(&search, 0, sizeof(search)); ++ for (index = 0; index < sizeof(search.ext) - 1; ++index) { ++ const int c = (int)ext[index]; ++ if (!c) ++ break; ++ ++ search.ext[index] = tolower(c); ++ } ++ ++ /* find the handler for the extension */ ++ handler = (const rc_hash_iterator_ext_handler_entry_t*) ++ bsearch(&search, handlers, num_handlers, sizeof(*handler), rc_hash_iterator_find_handler); ++ if (handler) { ++ handler->handler(iterator, handler->data); ++ ++ if (iterator->callbacks.verbose_message) { ++ int count = 0; ++ while (iterator->consoles[count]) ++ ++count; ++ ++ rc_hash_iterator_verbose_formatted(iterator, "Found %d potential consoles for %s file extension", count, ext); ++ } ++ } ++ else { ++ rc_hash_iterator_error_formatted(iterator, "No console mapping specified for %s file extension - trying full file hash", ext); ++ ++ /* if we didn't match the extension, default to something that does a whole file hash */ ++ if (!iterator->consoles[0]) ++ iterator->consoles[0] = RC_CONSOLE_GAMEBOY; ++ } ++} ++ ++void rc_hash_initialize_iterator(rc_hash_iterator_t* iterator, const char* path, const uint8_t* buffer, size_t buffer_size) ++{ ++ rc_hash_reset_iterator(iterator); ++ iterator->buffer = buffer; ++ iterator->buffer_size = buffer_size; ++ ++ if (path) ++ iterator->path = strdup(path); ++} ++ ++void rc_hash_destroy_iterator(rc_hash_iterator_t* iterator) { ++ if (iterator->path) { ++ free((void*)iterator->path); ++ iterator->path = NULL; ++ } ++ ++ iterator->buffer = NULL; ++} ++ ++int rc_hash_iterate(char hash[33], rc_hash_iterator_t* iterator) { ++ int next_console; ++ int result = 0; ++ ++ if (iterator->index == -1) { ++ rc_hash_initialize_iterator_from_path(iterator, iterator->path); ++ iterator->index = 0; ++ } ++ ++ do { ++ next_console = iterator->consoles[iterator->index]; ++ if (next_console == 0) { ++ hash[0] = '\0'; ++ break; ++ } ++ ++ ++iterator->index; ++ ++ rc_hash_iterator_verbose_formatted(iterator, "Trying console %d", next_console); ++ ++ result = rc_hash_generate(hash, next_console, iterator); ++ } while (!result); ++ ++ return result; ++} ++ ++int rc_hash_generate(char hash[33], uint32_t console_id, const rc_hash_iterator_t* iterator) { ++ if (iterator->buffer) ++ return rc_hash_from_buffer(hash, console_id, iterator); ++ ++ return rc_hash_from_file(hash, console_id, iterator); ++} ++ ++int rc_hash_generate_from_buffer(char hash[33], uint32_t console_id, const uint8_t* buffer, size_t buffer_size) { ++ rc_hash_iterator_t iterator; ++ int result; ++ ++ rc_hash_reset_iterator(&iterator); ++ iterator.buffer = buffer; ++ iterator.buffer_size = buffer_size; ++ ++ result = rc_hash_from_buffer(hash, console_id, &iterator); ++ ++ rc_hash_destroy_iterator(&iterator); ++ ++ return result; ++} ++ ++int rc_hash_generate_from_file(char hash[33], uint32_t console_id, const char* path){ ++ rc_hash_iterator_t iterator; ++ int result; ++ ++ rc_hash_reset_iterator(&iterator); ++ iterator.path = path; ++ ++ result = rc_hash_from_file(hash, console_id, &iterator); ++ ++ iterator.path = NULL; /* prevent free. we didn't strdup */ ++ ++ rc_hash_destroy_iterator(&iterator); ++ ++ return result; ++} +diff -rupbN melonDS.orig/src/rcheevos/src/rhash/hash_disc.c melonDS.ra/src/rcheevos/src/rhash/hash_disc.c +--- melonDS.orig/src/rcheevos/src/rhash/hash_disc.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rhash/hash_disc.c 2026-03-06 21:37:07.046799886 +0000 +@@ -0,0 +1,1340 @@ ++#include "rc_hash.h" ++ ++#include "rc_hash_internal.h" ++ ++#include "../rc_compat.h" ++ ++#include ++ ++/* ===================================================== */ ++ ++static struct rc_hash_cdreader g_cdreader_funcs; ++static struct rc_hash_cdreader* g_cdreader = NULL; ++ ++void rc_hash_reset_iterator_disc(rc_hash_iterator_t* iterator) ++{ ++ if (g_cdreader) ++ memcpy(&iterator->callbacks.cdreader, g_cdreader, sizeof(*g_cdreader)); ++ else ++ rc_hash_get_default_cdreader(&iterator->callbacks.cdreader); ++} ++ ++void rc_hash_init_custom_cdreader(struct rc_hash_cdreader* reader) ++{ ++ if (reader) { ++ memcpy(&g_cdreader_funcs, reader, sizeof(g_cdreader_funcs)); ++ g_cdreader = &g_cdreader_funcs; ++ } ++ else { ++ g_cdreader = NULL; ++ } ++} ++ ++static void* rc_cd_open_track(const rc_hash_iterator_t* iterator, uint32_t track) ++{ ++ if (iterator->callbacks.cdreader.open_track_iterator) ++ return iterator->callbacks.cdreader.open_track_iterator(iterator->path, track, iterator); ++ ++ if (iterator->callbacks.cdreader.open_track) ++ return iterator->callbacks.cdreader.open_track(iterator->path, track); ++ ++ if (g_cdreader && g_cdreader->open_track) ++ return g_cdreader->open_track(iterator->path, track); ++ ++ rc_hash_iterator_error(iterator, "no hook registered for cdreader_open_track"); ++ return NULL; ++} ++ ++static size_t rc_cd_read_sector(const rc_hash_iterator_t* iterator, void* track_handle, uint32_t sector, void* buffer, size_t requested_bytes) ++{ ++ if (iterator->callbacks.cdreader.read_sector) ++ return iterator->callbacks.cdreader.read_sector(track_handle, sector, buffer, requested_bytes); ++ ++ if (g_cdreader && g_cdreader->read_sector) ++ return g_cdreader->read_sector(track_handle, sector, buffer, requested_bytes); ++ ++ rc_hash_iterator_error(iterator, "no hook registered for cdreader_read_sector"); ++ return 0; ++} ++ ++static uint32_t rc_cd_first_track_sector(const rc_hash_iterator_t* iterator, void* track_handle) ++{ ++ if (iterator->callbacks.cdreader.first_track_sector) ++ return iterator->callbacks.cdreader.first_track_sector(track_handle); ++ ++ if (g_cdreader && g_cdreader->first_track_sector) ++ return g_cdreader->first_track_sector(track_handle); ++ ++ rc_hash_iterator_error(iterator, "no hook registered for cdreader_first_track_sector"); ++ return 0; ++} ++ ++static void rc_cd_close_track(const rc_hash_iterator_t* iterator, void* track_handle) ++{ ++ if (iterator->callbacks.cdreader.close_track) ++ iterator->callbacks.cdreader.close_track(track_handle); ++ else if (g_cdreader && g_cdreader->close_track) ++ g_cdreader->close_track(track_handle); ++ else ++ rc_hash_iterator_error(iterator, "no hook registered for cdreader_close_track"); ++} ++ ++static uint32_t rc_cd_find_file_sector(const rc_hash_iterator_t* iterator, void* track_handle, const char* path, uint32_t* size) ++{ ++ uint8_t buffer[2048], *tmp; ++ int sector; ++ uint32_t num_sectors = 0; ++ size_t filename_length; ++ const char* slash; ++ ++ if (!track_handle) ++ return 0; ++ ++ /* we start at the root. don't need to explicitly find it */ ++ if (*path == '\\') ++ ++path; ++ ++ filename_length = strlen(path); ++ slash = strrchr(path, '\\'); ++ if (slash) { ++ /* find the directory record for the first part of the path */ ++ memcpy(buffer, path, slash - path); ++ buffer[slash - path] = '\0'; ++ ++ sector = rc_cd_find_file_sector(iterator, track_handle, (const char *)buffer, NULL); ++ if (!sector) ++ return 0; ++ ++ ++slash; ++ filename_length -= (slash - path); ++ path = slash; ++ } ++ else { ++ uint32_t logical_block_size; ++ ++ /* find the cd information */ ++ if (!rc_cd_read_sector(iterator, track_handle, rc_cd_first_track_sector(iterator, track_handle) + 16, buffer, 256)) ++ return 0; ++ ++ /* the directory_record starts at 156, the sector containing the table of contents is 2 bytes into that. ++ * https://www.cdroller.com/htm/readdata.html ++ */ ++ sector = buffer[156 + 2] | (buffer[156 + 3] << 8) | (buffer[156 + 4] << 16); ++ ++ /* if the table of contents spans more than one sector, it's length of section will exceed it's logical block size */ ++ logical_block_size = (buffer[128] | (buffer[128 + 1] << 8)); /* logical block size */ ++ if (logical_block_size == 0) { ++ num_sectors = 1; ++ } else { ++ num_sectors = (buffer[156 + 10] | (buffer[156 + 11] << 8) | (buffer[156 + 12] << 16) | (buffer[156 + 13] << 24)); /* length of section */ ++ num_sectors /= logical_block_size; ++ } ++ } ++ ++ /* fetch and process the directory record */ ++ if (!rc_cd_read_sector(iterator, track_handle, sector, buffer, sizeof(buffer))) ++ return 0; ++ ++ tmp = buffer; ++ do { ++ if (tmp >= buffer + sizeof(buffer) || !*tmp) { ++ /* end of this path table block. if the path table spans multiple sectors, keep scanning */ ++ if (num_sectors > 1) { ++ --num_sectors; ++ if (rc_cd_read_sector(iterator, track_handle, ++sector, buffer, sizeof(buffer))) { ++ tmp = buffer; ++ continue; ++ } ++ } ++ break; ++ } ++ ++ /* filename is 33 bytes into the record and the format is "FILENAME;version" or "DIRECTORY" */ ++ if ((tmp[32] == filename_length || tmp[33 + filename_length] == ';') && ++ strncasecmp((const char*)(tmp + 33), path, filename_length) == 0) { ++ sector = tmp[2] | (tmp[3] << 8) | (tmp[4] << 16); ++ ++ rc_hash_iterator_verbose_formatted(iterator, "Found %s at sector %d", path, sector); ++ ++ if (size) ++ *size = tmp[10] | (tmp[11] << 8) | (tmp[12] << 16) | (tmp[13] << 24); ++ ++ return sector; ++ } ++ ++ /* the first byte of the record is the length of the record */ ++ tmp += *tmp; ++ } while (1); ++ ++ return 0; ++} ++ ++/* ===================================================== */ ++ ++static int rc_hash_cd_file(md5_state_t* md5, const rc_hash_iterator_t* iterator, void* track_handle, uint32_t sector, const char* name, uint32_t size, const char* description) ++{ ++ uint8_t buffer[2048]; ++ size_t num_read; ++ ++ if ((num_read = rc_cd_read_sector(iterator, track_handle, sector, buffer, sizeof(buffer))) < sizeof(buffer)) ++ return rc_hash_iterator_error_formatted(iterator, "Could not read %s", description); ++ ++ if (size > MAX_BUFFER_SIZE) ++ size = MAX_BUFFER_SIZE; ++ ++ if (name) ++ rc_hash_iterator_verbose_formatted(iterator, "Hashing %s title (%u bytes) and contents (%u bytes) ", name, (unsigned)strlen(name), size); ++ else ++ rc_hash_iterator_verbose_formatted(iterator, "Hashing %s contents (%u bytes @ sector %u)", description, size, sector); ++ ++ if (size < (unsigned)num_read) /* we read a whole sector - only hash the part containing file data */ ++ num_read = (size_t)size; ++ ++ do { ++ md5_append(md5, buffer, (int)num_read); ++ ++ if (size <= (unsigned)num_read) ++ break; ++ size -= (unsigned)num_read; ++ ++ ++sector; ++ if (size >= sizeof(buffer)) ++ num_read = rc_cd_read_sector(iterator, track_handle, sector, buffer, sizeof(buffer)); ++ else ++ num_read = rc_cd_read_sector(iterator, track_handle, sector, buffer, size); ++ } while (num_read > 0); ++ ++ return 1; ++} ++ ++/* ===================================================== */ ++ ++int rc_hash_3do(char hash[33], const rc_hash_iterator_t* iterator) ++{ ++ uint8_t buffer[2048]; ++ const uint8_t operafs_identifier[7] = { 0x01, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x01 }; ++ void* track_handle; ++ md5_state_t md5; ++ int sector; ++ int block_size, block_location; ++ int offset, stop; ++ size_t size = 0; ++ ++ track_handle = rc_cd_open_track(iterator, 1); ++ if (!track_handle) ++ return rc_hash_iterator_error(iterator, "Could not open track"); ++ ++ /* the Opera filesystem stores the volume information in the first 132 bytes of sector 0 ++ * https://github.com/barbeque/3dodump/blob/master/OperaFS-Format.md ++ */ ++ rc_cd_read_sector(iterator, track_handle, 0, buffer, 132); ++ ++ if (memcmp(buffer, operafs_identifier, sizeof(operafs_identifier)) == 0) { ++ rc_hash_iterator_verbose_formatted(iterator, "Found 3DO CD, title=%.32s", &buffer[0x28]); ++ ++ /* include the volume header in the hash */ ++ md5_init(&md5); ++ md5_append(&md5, buffer, 132); ++ ++ /* the block size is at offset 0x4C (assume 0x4C is always 0) */ ++ block_size = buffer[0x4D] * 65536 + buffer[0x4E] * 256 + buffer[0x4F]; ++ ++ /* the root directory block location is at offset 0x64 (and duplicated several ++ * times, but we just look at the primary record) (assume 0x64 is always 0)*/ ++ block_location = buffer[0x65] * 65536 + buffer[0x66] * 256 + buffer[0x67]; ++ ++ /* multiply the block index by the block size to get the real address */ ++ block_location *= block_size; ++ ++ /* convert that to a sector and read it */ ++ sector = block_location / 2048; ++ ++ do { ++ rc_cd_read_sector(iterator, track_handle, sector, buffer, sizeof(buffer)); ++ ++ /* offset to start of entries is at offset 0x10 (assume 0x10 and 0x11 are always 0) */ ++ offset = buffer[0x12] * 256 + buffer[0x13]; ++ ++ /* offset to end of entries is at offset 0x0C (assume 0x0C is always 0) */ ++ stop = buffer[0x0D] * 65536 + buffer[0x0E] * 256 + buffer[0x0F]; ++ ++ while (offset < stop) { ++ if (buffer[offset + 0x03] == 0x02) { /* file */ ++ if (strcasecmp((const char*)&buffer[offset + 0x20], "LaunchMe") == 0) { ++ /* the block size is at offset 0x0C (assume 0x0C is always 0) */ ++ block_size = buffer[offset + 0x0D] * 65536 + buffer[offset + 0x0E] * 256 + buffer[offset + 0x0F]; ++ ++ /* the block location is at offset 0x44 (assume 0x44 is always 0) */ ++ block_location = buffer[offset + 0x45] * 65536 + buffer[offset + 0x46] * 256 + buffer[offset + 0x47]; ++ block_location *= block_size; ++ ++ /* the file size is at offset 0x10 (assume 0x10 is always 0) */ ++ size = (size_t)buffer[offset + 0x11] * 65536 + buffer[offset + 0x12] * 256 + buffer[offset + 0x13]; ++ ++ rc_hash_iterator_verbose_formatted(iterator, "Hashing header (%u bytes) and %.32s (%u bytes) ", 132, &buffer[offset + 0x20], (unsigned)size); ++ ++ break; ++ } ++ } ++ ++ /* the number of extra copies of the file is at offset 0x40 (assume 0x40-0x42 are always 0) */ ++ offset += 0x48 + buffer[offset + 0x43] * 4; ++ } ++ ++ if (size != 0) ++ break; ++ ++ /* did not find the file, see if the directory listing is continued in another sector */ ++ offset = buffer[0x02] * 256 + buffer[0x03]; ++ ++ /* no more sectors to search*/ ++ if (offset == 0xFFFF) ++ break; ++ ++ /* get next sector */ ++ offset *= block_size; ++ sector = (block_location + offset) / 2048; ++ } while (1); ++ ++ if (size == 0) { ++ rc_cd_close_track(iterator, track_handle); ++ return rc_hash_iterator_error(iterator, "Could not find LaunchMe"); ++ } ++ ++ sector = block_location / 2048; ++ ++ while (size > 2048) { ++ rc_cd_read_sector(iterator, track_handle, sector, buffer, sizeof(buffer)); ++ md5_append(&md5, buffer, sizeof(buffer)); ++ ++ ++sector; ++ size -= 2048; ++ } ++ ++ rc_cd_read_sector(iterator, track_handle, sector, buffer, size); ++ md5_append(&md5, buffer, (int)size); ++ } ++ else { ++ rc_cd_close_track(iterator, track_handle); ++ return rc_hash_iterator_error(iterator, "Not a 3DO CD"); ++ } ++ ++ rc_cd_close_track(iterator, track_handle); ++ ++ return rc_hash_finalize(iterator, &md5, hash); ++} ++ ++int rc_hash_dreamcast(char hash[33], const rc_hash_iterator_t* iterator) ++{ ++ uint8_t buffer[256] = ""; ++ void* track_handle; ++ char exe_file[32] = ""; ++ uint32_t size; ++ uint32_t sector; ++ int result = 0; ++ md5_state_t md5; ++ int i = 0; ++ ++ /* track 03 is the data track that contains the TOC and IP.BIN */ ++ track_handle = rc_cd_open_track(iterator, 3); ++ if (track_handle) { ++ /* first 256 bytes from first sector should have IP.BIN structure that stores game meta information ++ * https://mc.pp.se/dc/ip.bin.html */ ++ rc_cd_read_sector(iterator, track_handle, rc_cd_first_track_sector(iterator, track_handle), buffer, sizeof(buffer)); ++ } ++ ++ if (memcmp(&buffer[0], "SEGA SEGAKATANA ", 16) != 0) { ++ if (track_handle) ++ rc_cd_close_track(iterator, track_handle); ++ ++ /* not a gd-rom dreamcast file. check for mil-cd by looking for the marker in the first data track */ ++ track_handle = rc_cd_open_track(iterator, RC_HASH_CDTRACK_FIRST_DATA); ++ if (!track_handle) ++ return rc_hash_iterator_error(iterator, "Could not open track"); ++ ++ rc_cd_read_sector(iterator, track_handle, rc_cd_first_track_sector(iterator, track_handle), buffer, sizeof(buffer)); ++ if (memcmp(&buffer[0], "SEGA SEGAKATANA ", 16) != 0) { ++ /* did not find marker on track 3 or first data track */ ++ rc_cd_close_track(iterator, track_handle); ++ return rc_hash_iterator_error(iterator, "Not a Dreamcast CD"); ++ } ++ } ++ ++ /* start the hash with the game meta information */ ++ md5_init(&md5); ++ md5_append(&md5, (md5_byte_t*)buffer, 256); ++ ++ if (iterator->callbacks.verbose_message) { ++ uint8_t* ptr = &buffer[0xFF]; ++ while (ptr > &buffer[0x80] && ptr[-1] == ' ') ++ --ptr; ++ *ptr = '\0'; ++ ++ rc_hash_iterator_verbose_formatted(iterator, "Found Dreamcast CD: %.128s (%.16s)", (const char*)&buffer[0x80], (const char*)&buffer[0x40]); ++ } ++ ++ /* the boot filename is 96 bytes into the meta information (https://mc.pp.se/dc/ip0000.bin.html) */ ++ /* remove whitespace from bootfile */ ++ i = 0; ++ while (!isspace((unsigned char)buffer[96 + i]) && i < 16) ++ ++i; ++ ++ /* sometimes boot file isn't present on meta information. ++ * nothing can be done, as even the core doesn't run the game in this case. */ ++ if (i == 0) { ++ rc_cd_close_track(iterator, track_handle); ++ return rc_hash_iterator_error(iterator, "Boot executable not specified on IP.BIN"); ++ } ++ ++ memcpy(exe_file, &buffer[96], i); ++ exe_file[i] = '\0'; ++ ++ sector = rc_cd_find_file_sector(iterator, track_handle, exe_file, &size); ++ if (sector == 0) { ++ rc_cd_close_track(iterator, track_handle); ++ return rc_hash_iterator_error(iterator, "Could not locate boot executable"); ++ } ++ ++ if (rc_cd_read_sector(iterator, track_handle, sector, buffer, 1)) { ++ /* the boot executable is in the primary data track */ ++ } ++ else { ++ rc_cd_close_track(iterator, track_handle); ++ ++ /* the boot executable is normally in the last track */ ++ track_handle = rc_cd_open_track(iterator, RC_HASH_CDTRACK_LAST); ++ } ++ ++ result = rc_hash_cd_file(&md5, iterator, track_handle, sector, NULL, size, "boot executable"); ++ rc_cd_close_track(iterator, track_handle); ++ ++ rc_hash_finalize(iterator, &md5, hash); ++ return result; ++} ++ ++static int rc_hash_nintendo_disc_partition(md5_state_t* md5, const rc_hash_iterator_t* iterator, ++ void* file_handle, const uint32_t part_offset, uint8_t wii_shift) ++{ ++ const uint32_t BASE_HEADER_SIZE = 0x2440; ++ const uint32_t MAX_HEADER_SIZE = 1024 * 1024; ++ ++ uint32_t apploader_header_size, apploader_body_size, apploader_trailer_size, header_size; ++ ++ uint8_t quad_buffer[4]; ++ uint8_t addr_buffer[0xD8]; ++ uint8_t* buffer; ++ ++ uint64_t dol_offset; ++ uint64_t dol_offsets[18]; ++ uint64_t dol_sizes[18]; ++ ++ uint8_t ix; ++ uint64_t remaining_size; ++ const uint32_t MAX_CHUNK_SIZE = 1024 * 1024; ++ ++ /* GetApploaderSize */ ++ rc_file_seek(iterator, file_handle, part_offset + BASE_HEADER_SIZE + 0x14, SEEK_SET); ++ apploader_header_size = 0x20; ++ rc_file_read(iterator, file_handle, quad_buffer, 4); ++ apploader_body_size = ++ (quad_buffer[0] << 24) | (quad_buffer[1] << 16) | (quad_buffer[2] << 8) | quad_buffer[3]; ++ rc_file_read(iterator, file_handle, quad_buffer, 4); ++ apploader_trailer_size = ++ (quad_buffer[0] << 24) | (quad_buffer[1] << 16) | (quad_buffer[2] << 8) | quad_buffer[3]; ++ header_size = BASE_HEADER_SIZE + apploader_header_size + apploader_body_size + apploader_trailer_size; ++ if (header_size > MAX_HEADER_SIZE) header_size = MAX_HEADER_SIZE; ++ ++ /* Hash headers */ ++ buffer = (uint8_t*)malloc(header_size); ++ if (!buffer) { ++ rc_file_close(iterator, file_handle); ++ return rc_hash_iterator_error(iterator, "Could not allocate temporary buffer"); ++ } ++ rc_file_seek(iterator, file_handle, part_offset, SEEK_SET); ++ rc_file_read(iterator, file_handle, buffer, header_size); ++ rc_hash_iterator_verbose_formatted(iterator, "Hashing %u byte partition header", header_size); ++ md5_append(md5, buffer, header_size); ++ ++ /* GetBootDOLOffset ++ * Base header size is guaranteed larger than 0x423 therefore buffer contains dol_offset right now ++ */ ++ dol_offset = (((uint64_t)buffer[0x420] << 24) | ++ ((uint64_t)buffer[0x421] << 16) | ++ ((uint64_t)buffer[0x422] << 8) | ++ (uint64_t)buffer[0x423]) << wii_shift; ++ free(buffer); ++ ++ /* Find offsets and sizes for the 7 main.dol code segments and 11 main.dol data segments */ ++ rc_file_seek(iterator, file_handle, part_offset + dol_offset, SEEK_SET); ++ rc_file_read(iterator, file_handle, addr_buffer, 0xD8); ++ for (ix = 0; ix < 18; ix++) { ++ dol_offsets[ix] = (((uint64_t)addr_buffer[0x0 + ix * 4] << 24) | ++ ((uint64_t)addr_buffer[0x1 + ix * 4] << 16) | ++ ((uint64_t)addr_buffer[0x2 + ix * 4] << 8) | ++ (uint64_t)addr_buffer[0x3 + ix * 4]) << wii_shift; ++ dol_sizes[ix] = (((uint64_t)addr_buffer[0x90 + ix * 4] << 24) | ++ ((uint64_t)addr_buffer[0x91 + ix * 4] << 16) | ++ ((uint64_t)addr_buffer[0x92 + ix * 4] << 8) | ++ (uint64_t)addr_buffer[0x93 + ix * 4]) << wii_shift; ++ } ++ ++ /* Iterate through the 18 main.dol segments and hash each */ ++ buffer = (uint8_t*)malloc(MAX_CHUNK_SIZE); ++ if (!buffer) { ++ rc_file_close(iterator, file_handle); ++ return rc_hash_iterator_error(iterator, "Could not allocate temporary buffer"); ++ } ++ ++ for (ix = 0; ix < 18; ix++) { ++ if (dol_sizes[ix] == 0) ++ continue; ++ ++ rc_file_seek(iterator, file_handle, part_offset + dol_offsets[ix], SEEK_SET); ++ if (ix < 7) ++ rc_hash_iterator_verbose_formatted(iterator, "Hashing %u byte main.dol code segment %u", dol_sizes[ix], ix); ++ else ++ rc_hash_iterator_verbose_formatted(iterator, "Hashing %u byte main.dol data segment %u", dol_sizes[ix], ix - 7); ++ ++ remaining_size = dol_sizes[ix]; ++ while (remaining_size > MAX_CHUNK_SIZE) { ++ rc_file_read(iterator, file_handle, buffer, MAX_CHUNK_SIZE); ++ md5_append(md5, buffer, MAX_CHUNK_SIZE); ++ remaining_size -= MAX_CHUNK_SIZE; ++ } ++ rc_file_read(iterator, file_handle, buffer, (int32_t)remaining_size); ++ md5_append(md5, buffer, (int32_t)remaining_size); ++ } ++ ++ free(buffer); ++ return 1; ++} ++ ++int rc_hash_gamecube(char hash[33], const rc_hash_iterator_t* iterator) ++{ ++ md5_state_t md5; ++ void* file_handle; ++ ++ uint8_t quad_buffer[4]; ++ uint8_t success; ++ ++ file_handle = rc_file_open(iterator, iterator->path); ++ if (!file_handle) ++ return rc_hash_iterator_error(iterator, "Could not open file"); ++ ++ md5_init(&md5); ++ /* Check Magic Word */ ++ rc_file_seek(iterator, file_handle, 0x1c, SEEK_SET); ++ rc_file_read(iterator, file_handle, quad_buffer, 4); ++ if (quad_buffer[0] == 0xC2 && quad_buffer[1] == 0x33 && quad_buffer[2] == 0x9F && quad_buffer[3] == 0x3D) ++ success = rc_hash_nintendo_disc_partition(&md5, iterator, file_handle, 0, 0); ++ else ++ success = rc_hash_iterator_error(iterator, "Not a Gamecube disc"); ++ ++ /* Finalize */ ++ rc_file_close(iterator, file_handle); ++ ++ if (success) ++ return rc_hash_finalize(iterator, &md5, hash); ++ ++ return 0; ++} ++ ++/* helper variable only used for testing */ ++const char* _rc_hash_jaguar_cd_homebrew_hash = NULL; ++ ++int rc_hash_jaguar_cd(char hash[33], const rc_hash_iterator_t* iterator) ++{ ++ uint8_t buffer[2352]; ++ void* track_handle; ++ md5_state_t md5; ++ int byteswapped = 0; ++ uint32_t size = 0; ++ uint32_t offset = 0; ++ uint32_t sector = 0; ++ uint32_t remaining; ++ uint32_t i; ++ ++ /* Jaguar CD header is in the first sector of the first data track OF THE SECOND SESSION. ++ * The first track must be an audio track, but may be a warning message or actual game audio */ ++ track_handle = rc_cd_open_track(iterator, RC_HASH_CDTRACK_FIRST_OF_SECOND_SESSION); ++ if (!track_handle) ++ return rc_hash_iterator_error(iterator, "Could not open track"); ++ ++ /* The header is an unspecified distance into the first sector, but usually two bytes in. ++ * It consists of 64 bytes of "TAIR" or "ATRI" repeating, depending on whether or not the data ++ * is byteswapped. Then another 32 byte that reads "ATARI APPROVED DATA HEADER ATRI " ++ * (possibly byteswapped). Then a big-endian 32-bit value for the address where the boot code ++ * should be loaded, and a second big-endian 32-bit value for the size of the boot code. */ ++ sector = rc_cd_first_track_sector(iterator, track_handle); ++ rc_cd_read_sector(iterator, track_handle, sector, buffer, sizeof(buffer)); ++ ++ for (i = 64; i < sizeof(buffer) - 32 - 4 * 3; i++) { ++ if (memcmp(&buffer[i], "TARA IPARPVODED TA AEHDAREA RT I", 32) == 0) { ++ byteswapped = 1; ++ offset = i + 32 + 4; ++ size = (buffer[offset] << 16) | (buffer[offset + 1] << 24) | (buffer[offset + 2]) | (buffer[offset + 3] << 8); ++ break; ++ } ++ else if (memcmp(&buffer[i], "ATARI APPROVED DATA HEADER ATRI ", 32) == 0) { ++ byteswapped = 0; ++ offset = i + 32 + 4; ++ size = (buffer[offset] << 24) | (buffer[offset + 1] << 16) | (buffer[offset + 2] << 8) | (buffer[offset + 3]); ++ break; ++ } ++ } ++ ++ if (size == 0) { /* did not see ATARI APPROVED DATA HEADER */ ++ rc_cd_close_track(iterator, track_handle); ++ return rc_hash_iterator_error(iterator, "Not a Jaguar CD"); ++ } ++ ++ i = 0; /* only loop once */ ++ do { ++ md5_init(&md5); ++ ++ offset += 4; ++ ++ rc_hash_iterator_verbose_formatted(iterator, "Hashing boot executable (%u bytes starting at %u bytes into sector %u)", size, offset, sector); ++ ++ if (size > MAX_BUFFER_SIZE) ++ size = MAX_BUFFER_SIZE; ++ ++ do { ++ if (byteswapped) ++ rc_hash_byteswap16(buffer, &buffer[sizeof(buffer)]); ++ ++ remaining = sizeof(buffer) - offset; ++ if (remaining >= size) { ++ md5_append(&md5, &buffer[offset], size); ++ size = 0; ++ break; ++ } ++ ++ md5_append(&md5, &buffer[offset], remaining); ++ size -= remaining; ++ offset = 0; ++ } while (rc_cd_read_sector(iterator, track_handle, ++sector, buffer, sizeof(buffer)) == sizeof(buffer)); ++ ++ rc_cd_close_track(iterator, track_handle); ++ ++ if (size > 0) ++ return rc_hash_iterator_error(iterator, "Not enough data"); ++ ++ rc_hash_finalize(iterator, &md5, hash); ++ ++ /* homebrew games all seem to have the same boot executable and store the actual game code in track 2. ++ * if we generated something other than the homebrew hash, return it. assume all homebrews are byteswapped. */ ++ if (strcmp(hash, "254487b59ab21bc005338e85cbf9fd2f") != 0 || !byteswapped) { ++ if (_rc_hash_jaguar_cd_homebrew_hash == NULL || strcmp(hash, _rc_hash_jaguar_cd_homebrew_hash) != 0) ++ return 1; ++ } ++ ++ /* if we've already been through the loop a second time, just return the hash */ ++ if (i == 1) ++ return 1; ++ ++i; ++ ++ rc_hash_iterator_verbose_formatted(iterator, "Potential homebrew at sector %u, checking for KART data in track 2", sector); ++ ++ track_handle = rc_cd_open_track(iterator, 2); ++ if (!track_handle) ++ return rc_hash_iterator_error(iterator, "Could not open track"); ++ ++ /* track 2 of the homebrew code has the 64 bytes or ATRI followed by 32 bytes of "ATARI APPROVED DATA HEADER ATRI!", ++ * then 64 bytes of KART repeating. */ ++ sector = rc_cd_first_track_sector(iterator, track_handle); ++ rc_cd_read_sector(iterator, track_handle, sector, buffer, sizeof(buffer)); ++ if (memcmp(&buffer[0x5E], "RT!IRTKA", 8) != 0) ++ return rc_hash_iterator_error(iterator, "Homebrew executable not found in track 2"); ++ ++ /* found KART data*/ ++ rc_hash_iterator_verbose(iterator, "Found KART data in track 2"); ++ ++ offset = 0xA6; ++ size = (buffer[offset] << 16) | (buffer[offset + 1] << 24) | (buffer[offset + 2]) | (buffer[offset + 3] << 8); ++ } while (1); ++} ++ ++int rc_hash_neogeo_cd(char hash[33], const rc_hash_iterator_t* iterator) ++{ ++ char buffer[1024], *ptr; ++ void* track_handle; ++ uint32_t sector; ++ uint32_t size; ++ md5_state_t md5; ++ ++ track_handle = rc_cd_open_track(iterator, 1); ++ if (!track_handle) ++ return rc_hash_iterator_error(iterator, "Could not open track"); ++ ++ /* https://wiki.neogeodev.org/index.php?title=IPL_file, https://wiki.neogeodev.org/index.php?title=PRG_file ++ * IPL file specifies data to be loaded before the game starts. PRG files are the executable code ++ */ ++ sector = rc_cd_find_file_sector(iterator, track_handle, "IPL.TXT", &size); ++ if (!sector) { ++ rc_cd_close_track(iterator, track_handle); ++ return rc_hash_iterator_error(iterator, "Not a NeoGeo CD game disc"); ++ } ++ ++ if (rc_cd_read_sector(iterator, track_handle, sector, buffer, sizeof(buffer)) == 0) { ++ rc_cd_close_track(iterator, track_handle); ++ return 0; ++ } ++ ++ md5_init(&md5); ++ ++ buffer[sizeof(buffer) - 1] = '\0'; ++ ptr = &buffer[0]; ++ do { ++ char* start = ptr; ++ while (*ptr && *ptr != '.') ++ ++ptr; ++ ++ if (strncasecmp(ptr, ".PRG", 4) == 0) { ++ ptr += 4; ++ *ptr++ = '\0'; ++ ++ sector = rc_cd_find_file_sector(iterator, track_handle, start, &size); ++ if (!sector || !rc_hash_cd_file(&md5, iterator, track_handle, sector, NULL, size, start)) { ++ rc_cd_close_track(iterator, track_handle); ++ return rc_hash_iterator_error_formatted(iterator, "Could not read %.16s", start); ++ } ++ } ++ ++ while (*ptr && *ptr != '\n') ++ ++ptr; ++ if (*ptr != '\n') ++ break; ++ ++ptr; ++ } while (*ptr != '\0' && *ptr != '\x1a'); ++ ++ rc_cd_close_track(iterator, track_handle); ++ return rc_hash_finalize(iterator, &md5, hash); ++} ++ ++static int rc_hash_pce_track(char hash[33], void* track_handle, const rc_hash_iterator_t* iterator) ++{ ++ uint8_t buffer[2048]; ++ md5_state_t md5; ++ uint32_t sector, num_sectors; ++ uint32_t size; ++ ++ /* the PC-Engine uses the second sector to specify boot information and program name. ++ * the string "PC Engine CD-ROM SYSTEM" should exist at 32 bytes into the sector ++ * http://shu.sheldows.com/shu/download/pcedocs/pce_cdrom.html ++ */ ++ if (rc_cd_read_sector(iterator, track_handle, rc_cd_first_track_sector(iterator, track_handle) + 1, buffer, 128) < 128) ++ return rc_hash_iterator_error(iterator, "Not a PC Engine CD"); ++ ++ /* normal PC Engine CD will have a header block in sector 1 */ ++ if (memcmp("PC Engine CD-ROM SYSTEM", &buffer[32], 23) == 0) { ++ /* the title of the disc is the last 22 bytes of the header */ ++ md5_init(&md5); ++ md5_append(&md5, &buffer[106], 22); ++ ++ buffer[128] = '\0'; ++ rc_hash_iterator_verbose_formatted(iterator, "Found PC Engine CD, title=%.22s", &buffer[106]); ++ ++ /* the first three bytes specify the sector of the program data, and the fourth byte ++ * is the number of sectors. ++ */ ++ sector = (buffer[0] << 16) + (buffer[1] << 8) + buffer[2]; ++ num_sectors = buffer[3]; ++ ++ rc_hash_iterator_verbose_formatted(iterator, "Hashing %d sectors starting at sector %d", num_sectors, sector); ++ ++ sector += rc_cd_first_track_sector(iterator, track_handle); ++ while (num_sectors > 0) { ++ rc_cd_read_sector(iterator, track_handle, sector, buffer, sizeof(buffer)); ++ md5_append(&md5, buffer, sizeof(buffer)); ++ ++ ++sector; ++ --num_sectors; ++ } ++ } ++ /* GameExpress CDs use a standard Joliet filesystem - locate and hash the BOOT.BIN */ ++ else if ((sector = rc_cd_find_file_sector(iterator, track_handle, "BOOT.BIN", &size)) != 0 && size < MAX_BUFFER_SIZE) { ++ md5_init(&md5); ++ while (size > sizeof(buffer)) { ++ rc_cd_read_sector(iterator, track_handle, sector, buffer, sizeof(buffer)); ++ md5_append(&md5, buffer, sizeof(buffer)); ++ ++ ++sector; ++ size -= sizeof(buffer); ++ } ++ ++ if (size > 0) { ++ rc_cd_read_sector(iterator, track_handle, sector, buffer, size); ++ md5_append(&md5, buffer, size); ++ } ++ } ++ else { ++ return rc_hash_iterator_error(iterator, "Not a PC Engine CD"); ++ } ++ ++ return rc_hash_finalize(iterator, &md5, hash); ++} ++ ++int rc_hash_pce_cd(char hash[33], const rc_hash_iterator_t* iterator) ++{ ++ int result; ++ void* track_handle = rc_cd_open_track(iterator, RC_HASH_CDTRACK_FIRST_DATA); ++ if (!track_handle) ++ return rc_hash_iterator_error(iterator, "Could not open track"); ++ ++ result = rc_hash_pce_track(hash, track_handle, iterator); ++ ++ rc_cd_close_track(iterator, track_handle); ++ ++ return result; ++} ++ ++int rc_hash_pcfx_cd(char hash[33], const rc_hash_iterator_t* iterator) ++{ ++ uint8_t buffer[2048]; ++ void* track_handle; ++ md5_state_t md5; ++ int sector, num_sectors; ++ ++ /* PC-FX executable can be in any track. Assume it's in the largest data track and check there first */ ++ track_handle = rc_cd_open_track(iterator, RC_HASH_CDTRACK_LARGEST); ++ if (!track_handle) ++ return rc_hash_iterator_error(iterator, "Could not open track"); ++ ++ /* PC-FX CD will have a header marker in sector 0 */ ++ sector = rc_cd_first_track_sector(iterator, track_handle); ++ rc_cd_read_sector(iterator, track_handle, sector, buffer, 32); ++ if (memcmp("PC-FX:Hu_CD-ROM", &buffer[0], 15) != 0) { ++ rc_cd_close_track(iterator, track_handle); ++ ++ /* not found in the largest data track, check track 2 */ ++ track_handle = rc_cd_open_track(iterator, 2); ++ if (!track_handle) ++ return rc_hash_iterator_error(iterator, "Could not open track"); ++ ++ sector = rc_cd_first_track_sector(iterator, track_handle); ++ rc_cd_read_sector(iterator, track_handle, sector, buffer, 32); ++ } ++ ++ if (memcmp("PC-FX:Hu_CD-ROM", &buffer[0], 15) == 0) { ++ /* PC-FX boot header fills the first two sectors of the disc ++ * https://bitbucket.org/trap15/pcfxtools/src/master/pcfx-cdlink.c ++ * the important stuff is the first 128 bytes of the second sector (title being the first 32) */ ++ rc_cd_read_sector(iterator, track_handle, sector + 1, buffer, 128); ++ ++ md5_init(&md5); ++ md5_append(&md5, buffer, 128); ++ ++ rc_hash_iterator_verbose_formatted(iterator, "Found PC-FX CD, title=%.32s", &buffer[0]); ++ ++ /* the program sector is in bytes 33-36 (assume byte 36 is 0) */ ++ sector = (buffer[34] << 16) + (buffer[33] << 8) + buffer[32]; ++ ++ /* the number of sectors the program occupies is in bytes 37-40 (assume byte 40 is 0) */ ++ num_sectors = (buffer[38] << 16) + (buffer[37] << 8) + buffer[36]; ++ ++ rc_hash_iterator_verbose_formatted(iterator, "Hashing %d sectors starting at sector %d", num_sectors, sector); ++ ++ sector += rc_cd_first_track_sector(iterator, track_handle); ++ while (num_sectors > 0) { ++ rc_cd_read_sector(iterator, track_handle, sector, buffer, sizeof(buffer)); ++ md5_append(&md5, buffer, sizeof(buffer)); ++ ++ ++sector; ++ --num_sectors; ++ } ++ } ++ else { ++ int result = 0; ++ rc_cd_read_sector(iterator, track_handle, sector + 1, buffer, 128); ++ ++ /* some PC-FX CDs still identify as PCE CDs */ ++ if (memcmp("PC Engine CD-ROM SYSTEM", &buffer[32], 23) == 0) ++ result = rc_hash_pce_track(hash, track_handle, iterator); ++ ++ rc_cd_close_track(iterator, track_handle); ++ if (result) ++ return result; ++ ++ return rc_hash_iterator_error(iterator, "Not a PC-FX CD"); ++ } ++ ++ rc_cd_close_track(iterator, track_handle); ++ ++ return rc_hash_finalize(iterator, &md5, hash); ++} ++ ++static int rc_hash_find_playstation_executable(const rc_hash_iterator_t* iterator, void* track_handle, ++ const char* boot_key, const char* cdrom_prefix, ++ char exe_name[], uint32_t exe_name_size, uint32_t* exe_size) ++{ ++ uint8_t buffer[2048]; ++ uint32_t size; ++ char* ptr; ++ char* start; ++ const size_t boot_key_len = strlen(boot_key); ++ const size_t cdrom_prefix_len = strlen(cdrom_prefix); ++ int sector; ++ ++ sector = rc_cd_find_file_sector(iterator, track_handle, "SYSTEM.CNF", NULL); ++ if (!sector) ++ return 0; ++ ++ size = (uint32_t)rc_cd_read_sector(iterator, track_handle, sector, buffer, sizeof(buffer) - 1); ++ buffer[size] = '\0'; ++ ++ sector = 0; ++ for (ptr = (char*)buffer; *ptr; ++ptr) { ++ if (strncmp(ptr, boot_key, boot_key_len) == 0) { ++ ptr += boot_key_len; ++ while (isspace((unsigned char)*ptr)) ++ ++ptr; ++ ++ if (*ptr == '=') { ++ ++ptr; ++ while (isspace((unsigned char)*ptr)) ++ ++ptr; ++ ++ if (strncmp(ptr, cdrom_prefix, cdrom_prefix_len) == 0) ++ ptr += cdrom_prefix_len; ++ while (*ptr == '\\') ++ ++ptr; ++ ++ start = ptr; ++ while (!isspace((unsigned char)*ptr) && *ptr != ';') ++ ++ptr; ++ ++ size = (uint32_t)(ptr - start); ++ if (size >= exe_name_size) ++ size = exe_name_size - 1; ++ ++ memcpy(exe_name, start, size); ++ exe_name[size] = '\0'; ++ ++ rc_hash_iterator_verbose_formatted(iterator, "Looking for boot executable: %s", exe_name); ++ ++ sector = rc_cd_find_file_sector(iterator, track_handle, exe_name, exe_size); ++ break; ++ } ++ } ++ ++ /* advance to end of line */ ++ while (*ptr && *ptr != '\n') ++ ++ptr; ++ } ++ ++ return sector; ++} ++ ++int rc_hash_psx(char hash[33], const rc_hash_iterator_t* iterator) ++{ ++ uint8_t buffer[32]; ++ char exe_name[64] = ""; ++ void* track_handle; ++ uint32_t sector; ++ uint32_t size; ++ int result = 0; ++ md5_state_t md5; ++ ++ track_handle = rc_cd_open_track(iterator, 1); ++ if (!track_handle) ++ return rc_hash_iterator_error(iterator, "Could not open track"); ++ ++ sector = rc_hash_find_playstation_executable(iterator, track_handle, "BOOT", "cdrom:", exe_name, sizeof(exe_name), &size); ++ if (!sector) { ++ sector = rc_cd_find_file_sector(iterator, track_handle, "PSX.EXE", &size); ++ if (sector) ++ memcpy(exe_name, "PSX.EXE", 8); ++ } ++ ++ if (!sector) { ++ rc_hash_iterator_error(iterator, "Could not locate primary executable"); ++ } ++ else if (rc_cd_read_sector(iterator, track_handle, sector, buffer, sizeof(buffer)) < sizeof(buffer)) { ++ rc_hash_iterator_error(iterator, "Could not read primary executable"); ++ } ++ else { ++ if (memcmp(buffer, "PS-X EXE", 7) != 0) { ++ rc_hash_iterator_verbose_formatted(iterator, "%s did not contain PS-X EXE marker", exe_name); ++ } ++ else { ++ /* the PS-X EXE header specifies the executable size as a 4-byte value 28 bytes into the header, which doesn't ++ * include the header itself. We want to include the header in the hash, so append another 2048 to that value. ++ */ ++ size = (((uint8_t)buffer[31] << 24) | ((uint8_t)buffer[30] << 16) | ((uint8_t)buffer[29] << 8) | (uint8_t)buffer[28]) + 2048; ++ } ++ ++ /* there's a few games that use a singular engine and only differ via their data files. luckily, they have unique ++ * serial numbers, and use the serial number as the boot file in the standard way. include the boot file name in the hash. ++ */ ++ md5_init(&md5); ++ md5_append(&md5, (md5_byte_t*)exe_name, (int)strlen(exe_name)); ++ ++ result = rc_hash_cd_file(&md5, iterator, track_handle, sector, exe_name, size, "primary executable"); ++ rc_hash_finalize(iterator, &md5, hash); ++ } ++ ++ rc_cd_close_track(iterator, track_handle); ++ ++ return result; ++} ++ ++int rc_hash_ps2(char hash[33], const rc_hash_iterator_t* iterator) ++{ ++ uint8_t buffer[4]; ++ char exe_name[64] = ""; ++ void* track_handle; ++ uint32_t sector; ++ uint32_t size; ++ int result = 0; ++ md5_state_t md5; ++ ++ track_handle = rc_cd_open_track(iterator, 1); ++ if (!track_handle) ++ return rc_hash_iterator_error(iterator, "Could not open track"); ++ ++ sector = rc_hash_find_playstation_executable(iterator, track_handle, "BOOT2", "cdrom0:", exe_name, sizeof(exe_name), &size); ++ if (!sector) { ++ rc_hash_iterator_error(iterator, "Could not locate primary executable"); ++ } ++ else if (rc_cd_read_sector(iterator, track_handle, sector, buffer, sizeof(buffer)) < sizeof(buffer)) { ++ rc_hash_iterator_error(iterator, "Could not read primary executable"); ++ } ++ else { ++ if (memcmp(buffer, "\x7f\x45\x4c\x46", 4) != 0) ++ rc_hash_iterator_verbose_formatted(iterator, "%s did not contain ELF marker", exe_name); ++ ++ /* there's a few games that use a singular engine and only differ via their data files. luckily, they have unique ++ * serial numbers, and use the serial number as the boot file in the standard way. include the boot file name in the hash. ++ */ ++ md5_init(&md5); ++ md5_append(&md5, (md5_byte_t*)exe_name, (int)strlen(exe_name)); ++ ++ result = rc_hash_cd_file(&md5, iterator, track_handle, sector, exe_name, size, "primary executable"); ++ rc_hash_finalize(iterator, &md5, hash); ++ } ++ ++ rc_cd_close_track(iterator, track_handle); ++ ++ return result; ++} ++ ++int rc_hash_psp(char hash[33], const rc_hash_iterator_t* iterator) ++{ ++ void* track_handle; ++ uint32_t sector; ++ uint32_t size; ++ md5_state_t md5; ++ ++ /* https://www.psdevwiki.com/psp/PBP ++ * A PBP file is an archive containing the PARAM.SFO, primary executable, and a bunch of metadata. ++ * While we could extract the PARAM.SFO and primary executable to mimic the normal PSP hashing logic, ++ * it's easier to just hash the entire file. This also helps alleviate issues where the primary ++ * executable is just a game engine and the only differentiating data would be the metadata. */ ++ if (rc_path_compare_extension(iterator->path, "pbp")) ++ return rc_hash_whole_file(hash, iterator); ++ ++ track_handle = rc_cd_open_track(iterator, 1); ++ if (!track_handle) ++ return rc_hash_iterator_error(iterator, "Could not open track"); ++ ++ /* http://www.romhacking.net/forum/index.php?topic=30899.0 ++ * PSP_GAME/PARAM.SFO contains key/value pairs identifying the game for the system (i.e. serial number, ++ * name, version). PSP_GAME/SYSDIR/EBOOT.BIN is the encrypted primary executable. ++ */ ++ sector = rc_cd_find_file_sector(iterator, track_handle, "PSP_GAME\\PARAM.SFO", &size); ++ if (!sector) { ++ rc_cd_close_track(iterator, track_handle); ++ return rc_hash_iterator_error(iterator, "Not a PSP game disc"); ++ } ++ ++ md5_init(&md5); ++ if (!rc_hash_cd_file(&md5, iterator, track_handle, sector, NULL, size, "PSP_GAME\\PARAM.SFO")) { ++ rc_cd_close_track(iterator, track_handle); ++ return 0; ++ } ++ ++ sector = rc_cd_find_file_sector(iterator, track_handle, "PSP_GAME\\SYSDIR\\EBOOT.BIN", &size); ++ if (!sector) { ++ rc_cd_close_track(iterator, track_handle); ++ return rc_hash_iterator_error(iterator, "Could not find primary executable"); ++ } ++ ++ if (!rc_hash_cd_file(&md5, iterator, track_handle, sector, NULL, size, "PSP_GAME\\SYSDIR\\EBOOT.BIN")) { ++ rc_cd_close_track(iterator, track_handle); ++ return 0; ++ } ++ ++ rc_cd_close_track(iterator, track_handle); ++ return rc_hash_finalize(iterator, &md5, hash); ++} ++ ++int rc_hash_sega_cd(char hash[33], const rc_hash_iterator_t* iterator) ++{ ++ uint8_t buffer[512]; ++ void* track_handle; ++ ++ track_handle = rc_cd_open_track(iterator, 1); ++ if (!track_handle) ++ return rc_hash_iterator_error(iterator, "Could not open track"); ++ ++ /* the first 512 bytes of sector 0 are a volume header and ROM header that uniquely identify the game. ++ * After that is an arbitrary amount of code that ensures the game is being run in the correct region. ++ * Then more arbitrary code follows that actually starts the boot process. Somewhere in there, the ++ * primary executable is loaded. In many cases, a single game will have multiple executables, so even ++ * if we could determine the primary one, it's just the tip of the iceberg. As such, we've decided that ++ * hashing the volume and ROM headers is sufficient for identifying the game, and we'll have to trust ++ * that our players aren't modifying anything else on the disc. ++ */ ++ rc_cd_read_sector(iterator, track_handle, 0, buffer, sizeof(buffer)); ++ rc_cd_close_track(iterator, track_handle); ++ ++ if (memcmp(buffer, "SEGADISCSYSTEM ", 16) != 0 && /* Sega CD */ ++ memcmp(buffer, "SEGA SEGASATURN ", 16) != 0) { /* Sega Saturn */ ++ return rc_hash_iterator_error(iterator, "Not a Sega CD"); ++ } ++ ++ return rc_hash_buffer(hash, buffer, sizeof(buffer), iterator); ++} ++ ++static int rc_hash_wii_disc(md5_state_t* md5, const rc_hash_iterator_t* iterator, void* file_handle) ++{ ++ const uint32_t MAIN_HEADER_SIZE = 0x80; ++ const uint64_t REGION_CODE_ADDRESS = 0x4E000; ++ const uint32_t CLUSTER_SIZE = 0x7C00; ++ const uint32_t MAX_CLUSTER_COUNT = 1024; ++ ++ uint32_t partition_info_table[8]; ++ uint32_t total_partition_count = 0; ++ uint32_t* partition_table; ++ uint64_t tmd_offset; ++ uint32_t tmd_size; ++ uint64_t part_offset; ++ uint64_t part_size; ++ uint32_t cluster_count; ++ ++ uint8_t quad_buffer[4]; ++ uint8_t* buffer; ++ ++ uint32_t ix, jx, kx; ++ uint8_t encrypted; ++ ++ /* Check encryption byte - if 0x61 is 0, disc is encrypted */ ++ rc_file_seek(iterator, file_handle, 0x61, SEEK_SET); ++ rc_file_read(iterator, file_handle, quad_buffer, 1); ++ encrypted = (quad_buffer[0] == 0); ++ ++ /* Hash main headers */ ++ buffer = (uint8_t*)malloc(CLUSTER_SIZE); ++ if (!buffer) { ++ rc_file_close(iterator, file_handle); ++ return rc_hash_iterator_error(iterator, "Could not allocate temporary buffer"); ++ } ++ ++ rc_hash_iterator_verbose_formatted(iterator, "Hashing %u byte main header for [%c%c%c%c%c%c]", ++ MAIN_HEADER_SIZE, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]); ++ rc_file_seek(iterator, file_handle, 0, SEEK_SET); ++ rc_file_read(iterator, file_handle, buffer, MAIN_HEADER_SIZE); ++ md5_append(md5, buffer, MAIN_HEADER_SIZE); ++ ++ /* Hash region code */ ++ rc_file_seek(iterator, file_handle, REGION_CODE_ADDRESS, SEEK_SET); ++ rc_file_read(iterator, file_handle, quad_buffer, 4); ++ md5_append(md5, quad_buffer, 4); ++ ++ /* Scan partition table */ ++ rc_file_seek(iterator, file_handle, 0x40000, SEEK_SET); ++ for (ix = 0; ix < 8; ix++) { ++ rc_file_read(iterator, file_handle, quad_buffer, 4); ++ partition_info_table[ix] = ++ (quad_buffer[0] << 24) | (quad_buffer[1] << 16) | (quad_buffer[2] << 8) | quad_buffer[3]; ++ if (ix % 2 == 0) ++ total_partition_count += partition_info_table[ix]; ++ } ++ ++ if (total_partition_count == 0) { ++ free(buffer); ++ rc_file_close(iterator, file_handle); ++ return rc_hash_iterator_error(iterator, "No partitions found"); ++ } ++ ++ partition_table = (uint32_t*)malloc(total_partition_count * 4 * 2); ++ kx = 0; ++ for (jx = 0; jx < 8; jx += 2) { ++ rc_file_seek(iterator, file_handle, ((uint64_t)partition_info_table[jx + 1]) << 2, SEEK_SET); ++ for (ix = 0; ix < partition_info_table[jx]; ix++) { ++ rc_file_read(iterator, file_handle, quad_buffer, 4); ++ partition_table[kx++] = ++ (quad_buffer[0] << 24) | (quad_buffer[1] << 16) | (quad_buffer[2] << 8) | quad_buffer[3]; ++ rc_file_read(iterator, file_handle, quad_buffer, 4); ++ partition_table[kx++] = ++ (quad_buffer[0] << 24) | (quad_buffer[1] << 16) | (quad_buffer[2] << 8) | quad_buffer[3]; ++ } ++ } ++ ++ /* Read each partition */ ++ for (jx = 0; jx < total_partition_count * 2; jx += 2) { ++ /* Don't hash Update partition*/ ++ if (partition_table[jx + 1] == 1) ++ continue; ++ ++ /* Hash title metadata */ ++ rc_file_seek(iterator, file_handle, ((uint64_t)partition_table[jx] << 2) + 0x2A4, SEEK_SET); ++ rc_file_read(iterator, file_handle, quad_buffer, 4); ++ tmd_size = ++ (quad_buffer[0] << 24) | (quad_buffer[1] << 16) | (quad_buffer[2] << 8) | quad_buffer[3]; ++ rc_file_read(iterator, file_handle, quad_buffer, 4); ++ tmd_offset = ++ ((uint64_t)((quad_buffer[0] << 24) | (quad_buffer[1] << 16) | (quad_buffer[2] << 8) | quad_buffer[3])) << 2; ++ ++ if (tmd_size > CLUSTER_SIZE) ++ tmd_size = CLUSTER_SIZE; ++ ++ rc_file_seek(iterator, file_handle, ((uint64_t)partition_table[jx] << 2) + tmd_offset, SEEK_SET); ++ rc_file_read(iterator, file_handle, buffer, tmd_size); ++ rc_hash_iterator_verbose_formatted(iterator, "Hashing %u byte title metadata (partition type %u)", ++ tmd_size, partition_table[jx + 1]); ++ md5_append(md5, buffer, tmd_size); ++ ++ /* Hash partition */ ++ rc_file_seek(iterator, file_handle, ((uint64_t)partition_table[jx] << 2) + 0x2B8, SEEK_SET); ++ rc_file_read(iterator, file_handle, quad_buffer, 4); ++ part_offset = ++ ((uint64_t)((quad_buffer[0] << 24) | (quad_buffer[1] << 16) | (quad_buffer[2] << 8) | quad_buffer[3])) << 2; ++ rc_file_read(iterator, file_handle, quad_buffer, 4); ++ part_size = ++ ((uint64_t)((quad_buffer[0] << 24) | (quad_buffer[1] << 16) | (quad_buffer[2] << 8) | quad_buffer[3])) << 2; ++ ++ if (encrypted) { ++ cluster_count = (part_size / 0x8000 > MAX_CLUSTER_COUNT) ? MAX_CLUSTER_COUNT : (uint32_t)(part_size / 0x8000); ++ rc_hash_iterator_verbose_formatted(iterator, "Hashing %u encrypted clusters (%u bytes)", ++ cluster_count, cluster_count * CLUSTER_SIZE); ++ for (ix = 0; ix < cluster_count; ix++) { ++ rc_file_seek(iterator, file_handle, part_offset + (ix * 0x8000) + 0x400, SEEK_SET); ++ rc_file_read(iterator, file_handle, buffer, CLUSTER_SIZE); ++ md5_append(md5, buffer, CLUSTER_SIZE); ++ } ++ } ++ else { /* Decrypted */ ++ if (rc_hash_nintendo_disc_partition(md5, iterator, file_handle, (uint32_t)part_offset, 2) == 0) { ++ free(partition_table); ++ free(buffer); ++ return rc_hash_iterator_error(iterator, "Failed to hash Wii partition"); ++ } ++ } ++ } ++ free(partition_table); ++ free(buffer); ++ return 1; ++} ++ ++static int rc_hash_wiiware(md5_state_t* md5, const rc_hash_iterator_t* iterator, void* file_handle) ++{ ++ uint32_t cert_chain_size, ticket_size, tmd_size; ++ uint32_t tmd_start_addr, content_count, content_addr, content_size, buffer_size; ++ uint32_t ix; ++ ++ uint8_t quad_buffer[4]; ++ uint8_t* buffer; ++ ++ rc_file_seek(iterator, file_handle, 0x08, SEEK_SET); ++ rc_file_read(iterator, file_handle, quad_buffer, 4); ++ cert_chain_size = ++ (quad_buffer[0] << 24) | (quad_buffer[1] << 16) | (quad_buffer[2] << 8) | quad_buffer[3]; ++ /* Each content is individually aligned to a 0x40-byte boundary. */ ++ cert_chain_size = (cert_chain_size + 0x3F) & ~0x3F; ++ rc_file_seek(iterator, file_handle, 0x10, SEEK_SET); ++ rc_file_read(iterator, file_handle, quad_buffer, 4); ++ ticket_size = ++ (quad_buffer[0] << 24) | (quad_buffer[1] << 16) | (quad_buffer[2] << 8) | quad_buffer[3]; ++ ticket_size = (ticket_size + 0x3F) & ~0x3F; ++ rc_file_read(iterator, file_handle, quad_buffer, 4); ++ tmd_size = ++ (quad_buffer[0] << 24) | (quad_buffer[1] << 16) | (quad_buffer[2] << 8) | quad_buffer[3]; ++ tmd_size = (tmd_size + 0x3F) & ~0x3F; ++ if (tmd_size > MAX_BUFFER_SIZE) ++ tmd_size = MAX_BUFFER_SIZE; ++ ++ tmd_start_addr = 0x40 + cert_chain_size + ticket_size; ++ ++ /* Hash TMD */ ++ buffer = (uint8_t*)malloc(tmd_size); ++ rc_file_seek(iterator, file_handle, tmd_start_addr, SEEK_SET); ++ rc_file_read(iterator, file_handle, buffer, tmd_size); ++ rc_hash_iterator_verbose_formatted(iterator, "Hashing %u byte TMD", tmd_size); ++ md5_append(md5, buffer, tmd_size); ++ free(buffer); ++ ++ /* Get count of content sections */ ++ rc_file_seek(iterator, file_handle, (uint64_t)tmd_start_addr + 0x1de, SEEK_SET); ++ rc_file_read(iterator, file_handle, quad_buffer, 2); ++ content_count = (quad_buffer[0] << 8) | quad_buffer[1]; ++ rc_hash_iterator_verbose_formatted(iterator, "Hashing %u content sections", content_count); ++ content_addr = tmd_start_addr + tmd_size; ++ for (ix = 0; ix < content_count; ix++) { ++ /* Get content section size */ ++ rc_file_seek(iterator, file_handle, (uint64_t)tmd_start_addr + 0x1e4 + 8 + ix * 0x24, SEEK_SET); ++ rc_file_read(iterator, file_handle, quad_buffer, 4); ++ if (quad_buffer[0] == 0x00 && quad_buffer[1] == 0x00 && quad_buffer[2] == 0x00 && quad_buffer[3] == 0x00) { ++ rc_file_read(iterator, file_handle, quad_buffer, 4); ++ content_size = ++ (quad_buffer[0] << 24) | (quad_buffer[1] << 16) | (quad_buffer[2] << 8) | quad_buffer[3]; ++ /* Padding between content should be ignored. But because the content data is encrypted, ++ the size to hash for each content should be rounded up to the size of an AES block (16 bytes). */ ++ content_size = (content_size + 0x0F) & ~0x0F; ++ } ++ else { ++ /* size > 4GB, just assume MAX_BUFFER_SIZE */ ++ content_size = MAX_BUFFER_SIZE; ++ } ++ buffer_size = (content_size > MAX_BUFFER_SIZE) ? MAX_BUFFER_SIZE : content_size; ++ ++ /* Hash content */ ++ buffer = (uint8_t*)malloc(buffer_size); ++ rc_file_seek(iterator, file_handle, content_addr, SEEK_SET); ++ rc_file_read(iterator, file_handle, buffer, buffer_size); ++ md5_append(md5, buffer, buffer_size); ++ content_addr += content_size; ++ content_addr = (content_addr + 0x3F) & ~0x3F; ++ free(buffer); ++ } ++ ++ return 1; ++} ++ ++int rc_hash_wii(char hash[33], const rc_hash_iterator_t* iterator) ++{ ++ md5_state_t md5; ++ void* file_handle; ++ ++ uint8_t quad_buffer[4]; ++ uint8_t success; ++ ++ file_handle = rc_file_open(iterator, iterator->path); ++ if (!file_handle) ++ return rc_hash_iterator_error(iterator, "Could not open file"); ++ ++ md5_init(&md5); ++ /* Check Magic Words */ ++ rc_file_seek(iterator, file_handle, 0x18, SEEK_SET); ++ rc_file_read(iterator, file_handle, quad_buffer, 4); ++ if (quad_buffer[0] == 0x5D && quad_buffer[1] == 0x1C && quad_buffer[2] == 0x9E && quad_buffer[3] == 0xA3) { ++ success = rc_hash_wii_disc(&md5, iterator, file_handle); ++ } ++ else { ++ rc_file_seek(iterator, file_handle, 0x04, SEEK_SET); ++ rc_file_read(iterator, file_handle, quad_buffer, 4); ++ if (quad_buffer[0] == 'I' && quad_buffer[1] == 's' && quad_buffer[2] == 0x00 && quad_buffer[3] == 0x00) ++ success = rc_hash_wiiware(&md5, iterator, file_handle); ++ else ++ success = rc_hash_iterator_error(iterator, "Not a supported Wii file"); ++ } ++ ++ /* Finalize */ ++ rc_file_close(iterator, file_handle); ++ ++ if (success) ++ return rc_hash_finalize(iterator, &md5, hash); ++ ++ return 0; ++} +diff -rupbN melonDS.orig/src/rcheevos/src/rhash/hash_encrypted.c melonDS.ra/src/rcheevos/src/rhash/hash_encrypted.c +--- melonDS.orig/src/rcheevos/src/rhash/hash_encrypted.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rhash/hash_encrypted.c 2026-03-06 21:37:07.050799942 +0000 +@@ -0,0 +1,566 @@ ++#include "rc_hash_internal.h" ++ ++#include "../rc_compat.h" ++ ++#include "aes.h" ++ ++/* ===================================================== */ ++ ++static rc_hash_3ds_get_cia_normal_key_func _3ds_get_cia_normal_key_func = NULL; ++static rc_hash_3ds_get_ncch_normal_keys_func _3ds_get_ncch_normal_keys_func = NULL; ++ ++void rc_hash_reset_iterator_encrypted(rc_hash_iterator_t* iterator) ++{ ++ iterator->callbacks.encryption.get_3ds_cia_normal_key = _3ds_get_cia_normal_key_func; ++ iterator->callbacks.encryption.get_3ds_ncch_normal_keys = _3ds_get_ncch_normal_keys_func; ++} ++ ++void rc_hash_init_3ds_get_cia_normal_key_func(rc_hash_3ds_get_cia_normal_key_func func) ++{ ++ _3ds_get_cia_normal_key_func = func; ++} ++ ++void rc_hash_init_3ds_get_ncch_normal_keys_func(rc_hash_3ds_get_ncch_normal_keys_func func) ++{ ++ _3ds_get_ncch_normal_keys_func = func; ++} ++ ++/* ===================================================== */ ++ ++static int rc_hash_nintendo_3ds_ncch(md5_state_t* md5, void* file_handle, uint8_t header[0x200], ++ struct AES_ctx* cia_aes, const rc_hash_iterator_t* iterator) ++{ ++ struct AES_ctx ncch_aes; ++ uint8_t* hash_buffer; ++ uint64_t exefs_offset, exefs_real_size; ++ uint32_t exefs_buffer_size; ++ uint8_t primary_key[AES_KEYLEN], secondary_key[AES_KEYLEN]; ++ uint8_t fixed_key_flag, no_crypto_flag, seed_crypto_flag; ++ uint8_t crypto_method, secondary_key_x_slot; ++ uint16_t ncch_version; ++ uint32_t i; ++ uint8_t primary_key_y[AES_KEYLEN], program_id[sizeof(uint64_t)]; ++ uint8_t iv[AES_BLOCKLEN], cia_iv[AES_BLOCKLEN]; ++ uint8_t exefs_section_name[8]; ++ uint64_t exefs_section_offset, exefs_section_size; ++ ++ exefs_offset = ((uint32_t)header[0x1A3] << 24) | (header[0x1A2] << 16) | (header[0x1A1] << 8) | header[0x1A0]; ++ exefs_real_size = ((uint32_t)header[0x1A7] << 24) | (header[0x1A6] << 16) | (header[0x1A5] << 8) | header[0x1A4]; ++ ++ /* Offset and size are in "media units" (1 media unit = 0x200 bytes) */ ++ exefs_offset *= 0x200; ++ exefs_real_size *= 0x200; ++ ++ if (exefs_real_size > MAX_BUFFER_SIZE) ++ exefs_buffer_size = MAX_BUFFER_SIZE; ++ else ++ exefs_buffer_size = (uint32_t)exefs_real_size; ++ ++ /* This region is technically optional, but it should always be present for executable content (i.e. games) */ ++ if (exefs_offset == 0 || exefs_real_size == 0) ++ return rc_hash_iterator_error(iterator, "ExeFS was not available"); ++ ++ /* NCCH flag 7 is a bitfield of various crypto related flags */ ++ fixed_key_flag = header[0x188 + 7] & 0x01; ++ no_crypto_flag = header[0x188 + 7] & 0x04; ++ seed_crypto_flag = header[0x188 + 7] & 0x20; ++ ++ ncch_version = (header[0x113] << 8) | header[0x112]; ++ ++ if (no_crypto_flag == 0) { ++ rc_hash_iterator_verbose(iterator, "Encrypted NCCH detected"); ++ ++ if (fixed_key_flag != 0) { ++ /* Fixed crypto key means all 0s for both keys */ ++ memset(primary_key, 0, sizeof(primary_key)); ++ memset(secondary_key, 0, sizeof(secondary_key)); ++ rc_hash_iterator_verbose(iterator, "Using fixed key crypto"); ++ } ++ else { ++ if (iterator->callbacks.encryption.get_3ds_ncch_normal_keys == NULL) ++ return rc_hash_iterator_error(iterator, "An encrypted NCCH was detected, but the NCCH normal keys callback was not set"); ++ ++ /* Primary key y is just the first 16 bytes of the header */ ++ memcpy(primary_key_y, header, sizeof(primary_key_y)); ++ ++ /* NCCH flag 3 indicates which secondary key x slot is used */ ++ crypto_method = header[0x188 + 3]; ++ ++ switch (crypto_method) { ++ case 0x00: ++ rc_hash_iterator_verbose(iterator, "Using NCCH crypto method v1"); ++ secondary_key_x_slot = 0x2C; ++ break; ++ case 0x01: ++ rc_hash_iterator_verbose(iterator, "Using NCCH crypto method v2"); ++ secondary_key_x_slot = 0x25; ++ break; ++ case 0x0A: ++ rc_hash_iterator_verbose(iterator, "Using NCCH crypto method v3"); ++ secondary_key_x_slot = 0x18; ++ break; ++ case 0x0B: ++ rc_hash_iterator_verbose(iterator, "Using NCCH crypto method v4"); ++ secondary_key_x_slot = 0x1B; ++ break; ++ default: ++ return rc_hash_iterator_error_formatted(iterator, "Invalid crypto method %02X", (unsigned)crypto_method); ++ } ++ ++ /* We only need the program id if we're doing seed crypto */ ++ if (seed_crypto_flag != 0) { ++ rc_hash_iterator_verbose(iterator, "Using seed crypto"); ++ memcpy(program_id, &header[0x118], sizeof(program_id)); ++ } ++ ++ if (iterator->callbacks.encryption.get_3ds_ncch_normal_keys(primary_key_y, secondary_key_x_slot, seed_crypto_flag != 0 ? program_id : NULL, primary_key, secondary_key) == 0) ++ return rc_hash_iterator_error(iterator, "Could not obtain NCCH normal keys"); ++ } ++ ++ switch (ncch_version) { ++ case 0: ++ case 2: ++ rc_hash_iterator_verbose(iterator, "Detected NCCH version 0/2"); ++ for (i = 0; i < 8; i++) { ++ /* First 8 bytes is the partition id in reverse byte order */ ++ iv[7 - i] = header[0x108 + i]; ++ } ++ ++ /* Magic number for ExeFS */ ++ iv[8] = 2; ++ ++ /* Rest of the bytes are 0 */ ++ memset(&iv[9], 0, sizeof(iv) - 9); ++ break; ++ ++ case 1: ++ rc_hash_iterator_verbose(iterator, "Detected NCCH version 1"); ++ for (i = 0; i < 8; i++) { ++ /* First 8 bytes is the partition id in normal byte order */ ++ iv[i] = header[0x108 + i]; ++ } ++ ++ /* Next 4 bytes are 0 */ ++ memset(&iv[8], 0, 4); ++ ++ /* Last 4 bytes is the ExeFS byte offset in big endian */ ++ iv[12] = (exefs_offset >> 24) & 0xFF; ++ iv[13] = (exefs_offset >> 16) & 0xFF; ++ iv[14] = (exefs_offset >> 8) & 0xFF; ++ iv[15] = exefs_offset & 0xFF; ++ break; ++ ++ default: ++ return rc_hash_iterator_error_formatted(iterator, "Invalid NCCH version %04X", (unsigned)ncch_version); ++ } ++ } ++ ++ /* ASSERT: file position must be +0x200 from start of NCCH (i.e. end of header) */ ++ exefs_offset -= 0x200; ++ ++ if (cia_aes) { ++ /* CBC decryption works by setting the IV to the encrypted previous block. ++ * Normally this means we would need to decrypt the data between the header and the ExeFS so the CIA AES state is correct. ++ * However, we can abuse how CBC decryption works and just set the IV to last block we would otherwise decrypt. ++ * We don't care about the data betweeen the header and ExeFS, so this works fine. */ ++ ++ rc_file_seek(iterator, file_handle, (int64_t)exefs_offset - AES_BLOCKLEN, SEEK_CUR); ++ if (rc_file_read(iterator, file_handle, cia_iv, AES_BLOCKLEN) != AES_BLOCKLEN) ++ return rc_hash_iterator_error(iterator, "Could not read NCCH data"); ++ ++ AES_ctx_set_iv(cia_aes, cia_iv); ++ } ++ else { ++ /* No encryption present, just skip over the in-between data */ ++ rc_file_seek(iterator, file_handle, (int64_t)exefs_offset, SEEK_CUR); ++ } ++ ++ hash_buffer = (uint8_t*)malloc(exefs_buffer_size); ++ if (!hash_buffer) ++ return rc_hash_iterator_error_formatted(iterator, "Failed to allocate %u bytes", (unsigned)exefs_buffer_size); ++ ++ /* Clear out crypto flags to ensure we get the same hash for decrypted and encrypted ROMs */ ++ memset(&header[0x114], 0, 4); ++ header[0x188 + 3] = 0; ++ header[0x188 + 7] &= ~(0x20 | 0x04 | 0x01); ++ ++ rc_hash_iterator_verbose(iterator, "Hashing 512 byte NCCH header"); ++ md5_append(md5, header, 0x200); ++ ++ rc_hash_iterator_verbose_formatted(iterator, "Hashing %u bytes for ExeFS (at NCCH offset %08X%08X)", ++ (unsigned)exefs_buffer_size, (unsigned)(exefs_offset >> 32), (unsigned)exefs_offset); ++ ++ if (rc_file_read(iterator, file_handle, hash_buffer, exefs_buffer_size) != exefs_buffer_size) { ++ free(hash_buffer); ++ return rc_hash_iterator_error(iterator, "Could not read ExeFS data"); ++ } ++ ++ if (cia_aes) { ++ rc_hash_iterator_verbose(iterator, "Performing CIA decryption for ExeFS"); ++ AES_CBC_decrypt_buffer(cia_aes, hash_buffer, exefs_buffer_size); ++ } ++ ++ if (no_crypto_flag == 0) { ++ rc_hash_iterator_verbose(iterator, "Performing NCCH decryption for ExeFS"); ++ ++ AES_init_ctx_iv(&ncch_aes, primary_key, iv); ++ AES_CTR_xcrypt_buffer(&ncch_aes, hash_buffer, 0x200); ++ ++ for (i = 0; i < 8; i++) { ++ memcpy(exefs_section_name, &hash_buffer[i * 16], sizeof(exefs_section_name)); ++ exefs_section_offset = ((uint32_t)hash_buffer[i * 16 + 11] << 24) | (hash_buffer[i * 16 + 10] << 16) | (hash_buffer[i * 16 + 9] << 8) | hash_buffer[i * 16 + 8]; ++ exefs_section_size = ((uint32_t)hash_buffer[i * 16 + 15] << 24) | (hash_buffer[i * 16 + 14] << 16) | (hash_buffer[i * 16 + 13] << 8) | hash_buffer[i * 16 + 12]; ++ ++ /* 0 size indicates an unused section */ ++ if (exefs_section_size == 0) ++ continue; ++ ++ /* Offsets must be aligned by a media unit */ ++ if (exefs_section_offset & 0x1FF) ++ return rc_hash_iterator_error(iterator, "ExeFS section offset is misaligned"); ++ ++ /* Offset is relative to the end of the header */ ++ exefs_section_offset += 0x200; ++ ++ /* Check against malformed sections */ ++ if (exefs_section_offset + ((exefs_section_size + 0x1FF) & ~(uint64_t)0x1FF) > (uint64_t)exefs_real_size) ++ return rc_hash_iterator_error(iterator, "ExeFS section would overflow"); ++ ++ if (memcmp(exefs_section_name, "icon", 4) == 0 || ++ memcmp(exefs_section_name, "banner", 6) == 0) { ++ /* Align size up by a media unit */ ++ exefs_section_size = (exefs_section_size + 0x1FF) & ~(uint64_t)0x1FF; ++ AES_init_ctx(&ncch_aes, primary_key); ++ } ++ else { ++ /* We don't align size up here, as the padding bytes will use the primary key rather than the secondary key */ ++ AES_init_ctx(&ncch_aes, secondary_key); ++ } ++ ++ /* In theory, the section offset + size could be greater than the buffer size */ ++ /* In practice, this likely never occurs, but just in case it does, ignore the section or constrict the size */ ++ if (exefs_section_offset + exefs_section_size > exefs_buffer_size) { ++ if (exefs_section_offset >= exefs_buffer_size) ++ continue; ++ ++ exefs_section_size = exefs_buffer_size - exefs_section_offset; ++ } ++ ++ exefs_section_name[7] = '\0'; ++ rc_hash_iterator_verbose_formatted(iterator, "Decrypting ExeFS file %s at ExeFS offset %08X with size %08X", ++ (const char*)exefs_section_name, (unsigned)exefs_section_offset, (unsigned)exefs_section_size); ++ ++ AES_CTR_xcrypt_buffer(&ncch_aes, &hash_buffer[exefs_section_offset], exefs_section_size & ~(uint64_t)0xF); ++ ++ if (exefs_section_size & 0x1FF) { ++ /* Handle padding bytes, these always use the primary key */ ++ exefs_section_offset += exefs_section_size; ++ exefs_section_size = 0x200 - (exefs_section_size & 0x1FF); ++ ++ rc_hash_iterator_verbose_formatted(iterator, "Decrypting ExeFS padding at ExeFS offset %08X with size %08X", ++ (unsigned)exefs_section_offset, (unsigned)exefs_section_size); ++ ++ /* Align our decryption start to an AES block boundary */ ++ if (exefs_section_size & 0xF) { ++ /* We're a little evil here re-using the IV like this, but this seems to be the best way to deal with this... */ ++ memcpy(iv, ncch_aes.Iv, sizeof(iv)); ++ exefs_section_offset &= ~(uint64_t)0xF; ++ ++ /* First decrypt these last bytes using the secondary key */ ++ AES_CTR_xcrypt_buffer(&ncch_aes, &hash_buffer[exefs_section_offset], 0x10 - (exefs_section_size & 0xF)); ++ ++ /* Now re-encrypt these bytes using the primary key */ ++ AES_init_ctx_iv(&ncch_aes, primary_key, iv); ++ AES_CTR_xcrypt_buffer(&ncch_aes, &hash_buffer[exefs_section_offset], 0x10 - (exefs_section_size & 0xF)); ++ ++ /* All of the padding can now be decrypted using the primary key */ ++ AES_ctx_set_iv(&ncch_aes, iv); ++ exefs_section_size += 0x10 - (exefs_section_size & 0xF); ++ } ++ ++ AES_init_ctx(&ncch_aes, primary_key); ++ AES_CTR_xcrypt_buffer(&ncch_aes, &hash_buffer[exefs_section_offset], (size_t)exefs_section_size); ++ } ++ } ++ } ++ ++ md5_append(md5, hash_buffer, exefs_buffer_size); ++ ++ free(hash_buffer); ++ return 1; ++} ++ ++static uint32_t rc_hash_nintendo_3ds_cia_signature_size(uint8_t header[0x200], const rc_hash_iterator_t* iterator) ++{ ++ uint32_t signature_type; ++ ++ signature_type = ((uint32_t)header[0] << 24) | (header[1] << 16) | (header[2] << 8) | header[3]; ++ switch (signature_type) { ++ case 0x010000: ++ case 0x010003: ++ return 0x200 + 0x3C; ++ ++ case 0x010001: ++ case 0x010004: ++ return 0x100 + 0x3C; ++ ++ case 0x010002: ++ case 0x010005: ++ return 0x3C + 0x40; ++ ++ default: ++ return rc_hash_iterator_error_formatted(iterator, "Invalid signature type %08X", (unsigned)signature_type); ++ } ++} ++ ++static int rc_hash_nintendo_3ds_cia(md5_state_t* md5, void* file_handle, uint8_t header[0x200], ++ const rc_hash_iterator_t* iterator) ++{ ++ const uint32_t CIA_HEADER_SIZE = 0x2020; /* Yes, this is larger than the header[0x200], but we only use the beginning of the header */ ++ const uint64_t CIA_ALIGNMENT_MASK = 64 - 1; /* sizes are aligned by 64 bytes */ ++ struct AES_ctx aes; ++ uint8_t iv[AES_BLOCKLEN], normal_key[AES_KEYLEN], title_key[AES_KEYLEN], title_id[sizeof(uint64_t)]; ++ uint32_t cert_size, tik_size, tmd_size; ++ int64_t cert_offset, tik_offset, tmd_offset, content_offset; ++ uint32_t signature_size, i; ++ uint16_t content_count; ++ uint8_t common_key_index; ++ ++ cert_size = ((uint32_t)header[0x0B] << 24) | (header[0x0A] << 16) | (header[0x09] << 8) | header[0x08]; ++ tik_size = ((uint32_t)header[0x0F] << 24) | (header[0x0E] << 16) | (header[0x0D] << 8) | header[0x0C]; ++ tmd_size = ((uint32_t)header[0x13] << 24) | (header[0x12] << 16) | (header[0x11] << 8) | header[0x10]; ++ ++ cert_offset = (CIA_HEADER_SIZE + CIA_ALIGNMENT_MASK) & ~CIA_ALIGNMENT_MASK; ++ tik_offset = (cert_offset + cert_size + CIA_ALIGNMENT_MASK) & ~CIA_ALIGNMENT_MASK; ++ tmd_offset = (tik_offset + tik_size + CIA_ALIGNMENT_MASK) & ~CIA_ALIGNMENT_MASK; ++ content_offset = (tmd_offset + tmd_size + CIA_ALIGNMENT_MASK) & ~CIA_ALIGNMENT_MASK; ++ ++ /* Check if this CIA is encrypted, if it isn't, we can hash it right away */ ++ ++ rc_file_seek(iterator, file_handle, tmd_offset, SEEK_SET); ++ if (rc_file_read(iterator, file_handle, header, 4) != 4) ++ return rc_hash_iterator_error(iterator, "Could not read TMD signature type"); ++ ++ signature_size = rc_hash_nintendo_3ds_cia_signature_size(header, iterator); ++ if (signature_size == 0) ++ return 0; /* rc_hash_nintendo_3ds_cia_signature_size will call rc_hash_error, so we don't need to do so here */ ++ ++ rc_file_seek(iterator, file_handle, signature_size + 0x9E, SEEK_CUR); ++ if (rc_file_read(iterator, file_handle, header, 2) != 2) ++ return rc_hash_iterator_error(iterator, "Could not read TMD content count"); ++ ++ content_count = (header[0] << 8) | header[1]; ++ ++ rc_file_seek(iterator, file_handle, 0x9C4 - 0x9E - 2, SEEK_CUR); ++ for (i = 0; i < content_count; i++) { ++ if (rc_file_read(iterator, file_handle, header, 0x30) != 0x30) ++ return rc_hash_iterator_error(iterator, "Could not read TMD content chunk"); ++ ++ /* Content index 0 is the main content (i.e. the 3DS executable) */ ++ if (((header[4] << 8) | header[5]) == 0) ++ break; ++ ++ content_offset += ((uint32_t)header[0xC] << 24) | (header[0xD] << 16) | (header[0xE] << 8) | header[0xF]; ++ } ++ ++ if (i == content_count) ++ return rc_hash_iterator_error(iterator, "Could not find main content chunk in TMD"); ++ ++ if ((header[7] & 1) == 0) { ++ /* Not encrypted, we can hash the NCCH immediately */ ++ rc_file_seek(iterator, file_handle, content_offset, SEEK_SET); ++ if (rc_file_read(iterator, file_handle, header, 0x200) != 0x200) ++ return rc_hash_iterator_error(iterator, "Could not read NCCH header"); ++ ++ if (memcmp(&header[0x100], "NCCH", 4) != 0) ++ return rc_hash_iterator_error_formatted(iterator, "NCCH header was not at %08X%08X", (unsigned)(content_offset >> 32), (unsigned)content_offset); ++ ++ return rc_hash_nintendo_3ds_ncch(md5, file_handle, header, NULL, iterator); ++ } ++ ++ if (iterator->callbacks.encryption.get_3ds_cia_normal_key == NULL) ++ return rc_hash_iterator_error(iterator, "An encrypted CIA was detected, but the CIA normal key callback was not set"); ++ ++ /* Acquire the encrypted title key, title id, and common key index from the ticket */ ++ /* These will be needed to decrypt the title key, and that will be needed to decrypt the CIA */ ++ ++ rc_file_seek(iterator, file_handle, tik_offset, SEEK_SET); ++ if (rc_file_read(iterator, file_handle, header, 4) != 4) ++ return rc_hash_iterator_error(iterator, "Could not read ticket signature type"); ++ ++ signature_size = rc_hash_nintendo_3ds_cia_signature_size(header, iterator); ++ if (signature_size == 0) ++ return 0; ++ ++ rc_file_seek(iterator, file_handle, signature_size, SEEK_CUR); ++ if (rc_file_read(iterator, file_handle, header, 0xB2) != 0xB2) ++ return rc_hash_iterator_error(iterator, "Could not read ticket data"); ++ ++ memcpy(title_key, &header[0x7F], sizeof(title_key)); ++ memcpy(title_id, &header[0x9C], sizeof(title_id)); ++ common_key_index = header[0xB1]; ++ ++ if (common_key_index > 5) ++ return rc_hash_iterator_error_formatted(iterator, "Invalid common key index %02X", (unsigned)common_key_index); ++ ++ if (iterator->callbacks.encryption.get_3ds_cia_normal_key(common_key_index, normal_key) == 0) ++ return rc_hash_iterator_error_formatted(iterator, "Could not obtain common key %02X", (unsigned)common_key_index); ++ ++ memset(iv, 0, sizeof(iv)); ++ memcpy(iv, title_id, sizeof(title_id)); ++ AES_init_ctx_iv(&aes, normal_key, iv); ++ ++ /* Finally, decrypt the title key */ ++ AES_CBC_decrypt_buffer(&aes, title_key, sizeof(title_key)); ++ ++ /* Now we can hash the NCCH */ ++ ++ rc_file_seek(iterator, file_handle, content_offset, SEEK_SET); ++ if (rc_file_read(iterator, file_handle, header, 0x200) != 0x200) ++ return rc_hash_iterator_error(iterator, "Could not read NCCH header"); ++ ++ memset(iv, 0, sizeof(iv)); /* Content index is iv (which is always 0 for main content) */ ++ AES_init_ctx_iv(&aes, title_key, iv); ++ AES_CBC_decrypt_buffer(&aes, header, 0x200); ++ ++ if (memcmp(&header[0x100], "NCCH", 4) != 0) ++ return rc_hash_iterator_error_formatted(iterator, "NCCH header was not at %08X%08X", (unsigned)(content_offset >> 32), (unsigned)content_offset); ++ ++ return rc_hash_nintendo_3ds_ncch(md5, file_handle, header, &aes, iterator); ++} ++ ++static int rc_hash_nintendo_3ds_3dsx(md5_state_t* md5, void* file_handle, uint8_t header[0x200], const rc_hash_iterator_t* iterator) ++{ ++ uint8_t* hash_buffer; ++ uint32_t header_size, reloc_header_size, code_size; ++ int64_t code_offset; ++ ++ header_size = (header[5] << 8) | header[4]; ++ reloc_header_size = (header[7] << 8) | header[6]; ++ code_size = ((uint32_t)header[0x13] << 24) | (header[0x12] << 16) | (header[0x11] << 8) | header[0x10]; ++ ++ /* 3 relocation headers are in-between the 3DSX header and code segment */ ++ code_offset = header_size + reloc_header_size * 3; ++ ++ if (code_size > MAX_BUFFER_SIZE) ++ code_size = MAX_BUFFER_SIZE; ++ ++ hash_buffer = (uint8_t*)malloc(code_size); ++ if (!hash_buffer) ++ return rc_hash_iterator_error_formatted(iterator, "Failed to allocate %u bytes", (unsigned)code_size); ++ ++ rc_file_seek(iterator, file_handle, code_offset, SEEK_SET); ++ ++ rc_hash_iterator_verbose_formatted(iterator, "Hashing %u bytes for 3DSX (at %08X)", (unsigned)code_size, (unsigned)code_offset); ++ ++ if (rc_file_read(iterator, file_handle, hash_buffer, code_size) != code_size) { ++ free(hash_buffer); ++ return rc_hash_iterator_error(iterator, "Could not read 3DSX code segment"); ++ } ++ ++ md5_append(md5, hash_buffer, code_size); ++ ++ free(hash_buffer); ++ return 1; ++} ++ ++int rc_hash_nintendo_3ds(char hash[33], const rc_hash_iterator_t* iterator) ++{ ++ md5_state_t md5; ++ void* file_handle; ++ uint8_t header[0x200]; /* NCCH and NCSD headers are both 0x200 bytes */ ++ int64_t header_offset; ++ ++ file_handle = rc_file_open(iterator, iterator->path); ++ if (!file_handle) ++ return rc_hash_iterator_error(iterator, "Could not open file"); ++ ++ rc_file_seek(iterator, file_handle, 0, SEEK_SET); ++ ++ /* If we don't have a full header, this is probably not a 3DS ROM */ ++ if (rc_file_read(iterator, file_handle, header, sizeof(header)) != sizeof(header)) { ++ rc_file_close(iterator, file_handle); ++ return rc_hash_iterator_error(iterator, "Could not read 3DS ROM header"); ++ } ++ ++ md5_init(&md5); ++ ++ if (memcmp(&header[0x100], "NCSD", 4) == 0) { ++ /* A NCSD container contains 1-8 NCCH partitions */ ++ /* The first partition (index 0) is reserved for executable content */ ++ header_offset = ((uint32_t)header[0x123] << 24) | (header[0x122] << 16) | (header[0x121] << 8) | header[0x120]; ++ /* Offset is in "media units" (1 media unit = 0x200 bytes) */ ++ header_offset *= 0x200; ++ ++ /* We include the NCSD header in the hash, as that will ensure different versions of a game result in a different hash ++ * This is due to some revisions / languages only ever changing other NCCH paritions (e.g. the game manual) ++ */ ++ rc_hash_iterator_verbose(iterator, "Hashing 512 byte NCSD header"); ++ md5_append(&md5, header, sizeof(header)); ++ ++ rc_hash_iterator_verbose_formatted(iterator, ++ "Detected NCSD header, seeking to NCCH partition at %08X%08X", ++ (unsigned)(header_offset >> 32), (unsigned)header_offset); ++ ++ rc_file_seek(iterator, file_handle, header_offset, SEEK_SET); ++ if (rc_file_read(iterator, file_handle, header, sizeof(header)) != sizeof(header)) { ++ rc_file_close(iterator, file_handle); ++ return rc_hash_iterator_error(iterator, "Could not read 3DS NCCH header"); ++ } ++ ++ if (memcmp(&header[0x100], "NCCH", 4) != 0) { ++ rc_file_close(iterator, file_handle); ++ return rc_hash_iterator_error_formatted(iterator, "3DS NCCH header was not at %08X%08X", (unsigned)(header_offset >> 32), (unsigned)header_offset); ++ } ++ } ++ ++ if (memcmp(&header[0x100], "NCCH", 4) == 0) { ++ if (rc_hash_nintendo_3ds_ncch(&md5, file_handle, header, NULL, iterator)) { ++ rc_file_close(iterator, file_handle); ++ return rc_hash_finalize(iterator, &md5, hash); ++ } ++ ++ rc_file_close(iterator, file_handle); ++ return rc_hash_iterator_error(iterator, "Failed to hash 3DS NCCH container"); ++ } ++ ++ /* Couldn't identify either an NCSD or NCCH */ ++ ++ /* Try to identify this as a CIA */ ++ if (header[0] == 0x20 && header[1] == 0x20 && header[2] == 0x00 && header[3] == 0x00) { ++ rc_hash_iterator_verbose(iterator, "Detected CIA, attempting to find executable NCCH"); ++ ++ if (rc_hash_nintendo_3ds_cia(&md5, file_handle, header, iterator)) { ++ rc_file_close(iterator, file_handle); ++ return rc_hash_finalize(iterator, &md5, hash); ++ } ++ ++ rc_file_close(iterator, file_handle); ++ return rc_hash_iterator_error(iterator, "Failed to hash 3DS CIA container"); ++ } ++ ++ /* This might be a homebrew game, try to detect that */ ++ if (memcmp(&header[0], "3DSX", 4) == 0) { ++ rc_hash_iterator_verbose(iterator, "Detected 3DSX"); ++ ++ if (rc_hash_nintendo_3ds_3dsx(&md5, file_handle, header, iterator)) { ++ rc_file_close(iterator, file_handle); ++ return rc_hash_finalize(iterator, &md5, hash); ++ } ++ ++ rc_file_close(iterator, file_handle); ++ return rc_hash_iterator_error(iterator, "Failed to hash 3DS 3DSX container"); ++ } ++ ++ /* Raw ELF marker (AXF/ELF files) */ ++ if (memcmp(&header[0], "\x7f\x45\x4c\x46", 4) == 0) { ++ rc_hash_iterator_verbose(iterator, "Detected AXF/ELF file, hashing entire file"); ++ ++ /* Don't bother doing anything fancy here, just hash entire file */ ++ rc_file_close(iterator, file_handle); ++ return rc_hash_whole_file(hash, iterator); ++ } ++ ++ rc_file_close(iterator, file_handle); ++ return rc_hash_iterator_error(iterator, "Not a 3DS ROM"); ++} +diff -rupbN melonDS.orig/src/rcheevos/src/rhash/hash_rom.c melonDS.ra/src/rcheevos/src/rhash/hash_rom.c +--- melonDS.orig/src/rcheevos/src/rhash/hash_rom.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rhash/hash_rom.c 2026-03-06 21:37:07.050799942 +0000 +@@ -0,0 +1,426 @@ ++#include "rc_hash_internal.h" ++ ++#include "../rc_compat.h" ++ ++#include ++ ++/* ===================================================== */ ++ ++static int rc_hash_unheadered_iterator_buffer(char hash[33], const rc_hash_iterator_t* iterator, size_t header_size) ++{ ++ return rc_hash_buffer(hash, iterator->buffer + header_size, iterator->buffer_size - header_size, iterator); ++} ++ ++static int rc_hash_iterator_buffer(char hash[33], const rc_hash_iterator_t* iterator) ++{ ++ return rc_hash_buffer(hash, iterator->buffer, iterator->buffer_size, iterator); ++} ++ ++/* ===================================================== */ ++ ++int rc_hash_7800(char hash[33], const rc_hash_iterator_t* iterator) ++{ ++ /* if the file contains a header, ignore it */ ++ if (memcmp(&iterator->buffer[1], "ATARI7800", 9) == 0) { ++ rc_hash_iterator_verbose(iterator, "Ignoring 7800 header"); ++ return rc_hash_unheadered_iterator_buffer(hash, iterator, 128); ++ } ++ ++ return rc_hash_iterator_buffer(hash, iterator); ++} ++ ++int rc_hash_arcade(char hash[33], const rc_hash_iterator_t* iterator) ++{ ++ /* arcade hash is just the hash of the filename (no extension) - the cores are pretty stringent about having the right ROM data */ ++ const char* filename = rc_path_get_filename(iterator->path); ++ const char* ext = rc_path_get_extension(filename); ++ char buffer[128]; /* realistically, this should never need more than ~32 characters */ ++ size_t filename_length = ext - filename - 1; ++ ++ /* fbneo supports loading subsystems by using specific folder names. ++ * if one is found, include it in the hash. ++ * https://github.com/libretro/FBNeo/blob/master/src/burner/libretro/README.md#emulating-consoles-and-computers ++ */ ++ if (filename > iterator->path + 1) { ++ int include_folder = 0; ++ const char* folder = filename - 1; ++ size_t parent_folder_length = 0; ++ ++ do { ++ if (folder[-1] == '/' || folder[-1] == '\\') ++ break; ++ ++ --folder; ++ } while (folder > iterator->path); ++ ++ parent_folder_length = filename - folder - 1; ++ if (parent_folder_length < 16) { ++ char* ptr = buffer; ++ while (folder < filename - 1) ++ *ptr++ = tolower(*folder++); ++ *ptr = '\0'; ++ ++ folder = buffer; ++ } ++ ++ switch (parent_folder_length) { ++ case 3: ++ if (memcmp(folder, "nes", 3) == 0 || /* NES */ ++ memcmp(folder, "fds", 3) == 0 || /* FDS */ ++ memcmp(folder, "sms", 3) == 0 || /* Master System */ ++ memcmp(folder, "msx", 3) == 0 || /* MSX */ ++ memcmp(folder, "ngp", 3) == 0 || /* NeoGeo Pocket */ ++ memcmp(folder, "pce", 3) == 0 || /* PCEngine */ ++ memcmp(folder, "chf", 3) == 0 || /* ChannelF */ ++ memcmp(folder, "sgx", 3) == 0) /* SuperGrafX */ ++ include_folder = 1; ++ break; ++ case 4: ++ if (memcmp(folder, "tg16", 4) == 0 || /* TurboGrafx-16 */ ++ memcmp(folder, "msx1", 4) == 0) /* MSX */ ++ include_folder = 1; ++ break; ++ case 5: ++ if (memcmp(folder, "neocd", 5) == 0) /* NeoGeo CD */ ++ include_folder = 1; ++ break; ++ case 6: ++ if (memcmp(folder, "coleco", 6) == 0 || /* Colecovision */ ++ memcmp(folder, "sg1000", 6) == 0) /* SG-1000 */ ++ include_folder = 1; ++ break; ++ case 7: ++ if (memcmp(folder, "genesis", 7) == 0) /* Megadrive (Genesis) */ ++ include_folder = 1; ++ break; ++ case 8: ++ if (memcmp(folder, "gamegear", 8) == 0 || /* Game Gear */ ++ memcmp(folder, "megadriv", 8) == 0 || /* Megadrive */ ++ memcmp(folder, "pcengine", 8) == 0 || /* PCEngine */ ++ memcmp(folder, "channelf", 8) == 0 || /* ChannelF */ ++ memcmp(folder, "spectrum", 8) == 0) /* ZX Spectrum */ ++ include_folder = 1; ++ break; ++ case 9: ++ if (memcmp(folder, "megadrive", 9) == 0) /* Megadrive */ ++ include_folder = 1; ++ break; ++ case 10: ++ if (memcmp(folder, "supergrafx", 10) == 0 || /* SuperGrafX */ ++ memcmp(folder, "zxspectrum", 10) == 0) /* ZX Spectrum */ ++ include_folder = 1; ++ break; ++ case 12: ++ if (memcmp(folder, "mastersystem", 12) == 0 || /* Master System */ ++ memcmp(folder, "colecovision", 12) == 0) /* Colecovision */ ++ include_folder = 1; ++ break; ++ default: ++ break; ++ } ++ ++ if (include_folder) { ++ if (parent_folder_length + filename_length + 1 < sizeof(buffer)) { ++ buffer[parent_folder_length] = '_'; ++ memcpy(&buffer[parent_folder_length + 1], filename, filename_length); ++ return rc_hash_buffer(hash, (uint8_t*)&buffer[0], parent_folder_length + filename_length + 1, iterator); ++ } ++ } ++ } ++ ++ return rc_hash_buffer(hash, (uint8_t*)filename, filename_length, iterator); ++} ++ ++static int rc_hash_text(char hash[33], const rc_hash_iterator_t* iterator) ++{ ++ md5_state_t md5; ++ const uint8_t* scan = iterator->buffer; ++ const uint8_t* stop = iterator->buffer + iterator->buffer_size; ++ ++ md5_init(&md5); ++ ++ do { ++ const uint8_t* line = scan; ++ ++ /* find end of line */ ++ while (scan < stop && *scan != '\r' && *scan != '\n') ++ ++scan; ++ ++ md5_append(&md5, line, (int)(scan - line)); ++ ++ /* include a normalized line ending */ ++ /* NOTE: this causes a line ending to be hashed at the end of the file, even if one was not present */ ++ md5_append(&md5, (const uint8_t*)"\n", 1); ++ ++ /* skip newline */ ++ if (scan < stop && *scan == '\r') ++ ++scan; ++ if (scan < stop && *scan == '\n') ++ ++scan; ++ ++ } while (scan < stop); ++ ++ return rc_hash_finalize(iterator, &md5, hash); ++} ++ ++int rc_hash_arduboy(char hash[33], const rc_hash_iterator_t* iterator) ++{ ++ if (iterator->path && rc_path_compare_extension(iterator->path, "arduboy")) { ++#ifndef RC_HASH_NO_ZIP ++ return rc_hash_arduboyfx(hash, iterator); ++#else ++ rc_hash_iterator_verbose(iterator, ".arduboy file processing not enabled"); ++ return 0; ++#endif ++ } ++ ++ if (!iterator->buffer) ++ return rc_hash_buffered_file(hash, RC_CONSOLE_ARDUBOY, iterator); ++ ++ /* https://en.wikipedia.org/wiki/Intel_HEX */ ++ return rc_hash_text(hash, iterator); ++} ++ ++int rc_hash_lynx(char hash[33], const rc_hash_iterator_t* iterator) ++{ ++ /* if the file contains a header, ignore it */ ++ if (memcmp(&iterator->buffer[0], "LYNX", 5) == 0) { ++ rc_hash_iterator_verbose(iterator, "Ignoring LYNX header"); ++ return rc_hash_unheadered_iterator_buffer(hash, iterator, 64); ++ } ++ ++ return rc_hash_iterator_buffer(hash, iterator); ++} ++ ++int rc_hash_nes(char hash[33], const rc_hash_iterator_t* iterator) ++{ ++ /* if the file contains a header, ignore it */ ++ if (memcmp(&iterator->buffer[0], "NES\x1a", 4) == 0) { ++ rc_hash_iterator_verbose(iterator, "Ignoring NES header"); ++ return rc_hash_unheadered_iterator_buffer(hash, iterator, 16); ++ } ++ ++ if (memcmp(&iterator->buffer[0], "FDS\x1a", 4) == 0) { ++ rc_hash_iterator_verbose(iterator, "Ignoring FDS header"); ++ return rc_hash_unheadered_iterator_buffer(hash, iterator, 16); ++ } ++ ++ return rc_hash_iterator_buffer(hash, iterator); ++} ++ ++int rc_hash_n64(char hash[33], const rc_hash_iterator_t* iterator) ++{ ++ uint8_t* buffer; ++ uint8_t* stop; ++ const size_t buffer_size = 65536; ++ md5_state_t md5; ++ size_t remaining; ++ void* file_handle; ++ int is_v64 = 0; ++ int is_n64 = 0; ++ ++ file_handle = rc_file_open(iterator, iterator->path); ++ if (!file_handle) ++ return rc_hash_iterator_error(iterator, "Could not open file"); ++ ++ buffer = (uint8_t*)malloc(buffer_size); ++ if (!buffer) { ++ rc_file_close(iterator, file_handle); ++ return rc_hash_iterator_error(iterator, "Could not allocate temporary buffer"); ++ } ++ stop = buffer + buffer_size; ++ ++ /* read first byte so we can detect endianness */ ++ rc_file_seek(iterator, file_handle, 0, SEEK_SET); ++ rc_file_read(iterator, file_handle, buffer, 1); ++ ++ if (buffer[0] == 0x80) { /* z64 format (big endian [native]) */ ++ } ++ else if (buffer[0] == 0x37) { /* v64 format (byteswapped) */ ++ rc_hash_iterator_verbose(iterator, "converting v64 to z64"); ++ is_v64 = 1; ++ } ++ else if (buffer[0] == 0x40) { /* n64 format (little endian) */ ++ rc_hash_iterator_verbose(iterator, "converting n64 to z64"); ++ is_n64 = 1; ++ } ++ else if (buffer[0] == 0xE8 || buffer[0] == 0x22) { /* ndd format (don't byteswap) */ ++ } ++ else { ++ free(buffer); ++ rc_file_close(iterator, file_handle); ++ ++ rc_hash_iterator_verbose(iterator, "Not a Nintendo 64 ROM"); ++ return 0; ++ } ++ ++ /* calculate total file size */ ++ rc_file_seek(iterator, file_handle, 0, SEEK_END); ++ remaining = (size_t)rc_file_tell(iterator, file_handle); ++ if (remaining > MAX_BUFFER_SIZE) ++ remaining = MAX_BUFFER_SIZE; ++ ++ rc_hash_iterator_verbose_formatted(iterator, "Hashing %u bytes", (unsigned)remaining); ++ ++ /* begin hashing */ ++ md5_init(&md5); ++ ++ rc_file_seek(iterator, file_handle, 0, SEEK_SET); ++ while (remaining >= buffer_size) { ++ rc_file_read(iterator, file_handle, buffer, (int)buffer_size); ++ ++ if (is_v64) ++ rc_hash_byteswap16(buffer, stop); ++ else if (is_n64) ++ rc_hash_byteswap32(buffer, stop); ++ ++ md5_append(&md5, buffer, (int)buffer_size); ++ remaining -= buffer_size; ++ } ++ ++ if (remaining > 0) { ++ rc_file_read(iterator, file_handle, buffer, (int)remaining); ++ ++ stop = buffer + remaining; ++ if (is_v64) ++ rc_hash_byteswap16(buffer, stop); ++ else if (is_n64) ++ rc_hash_byteswap32(buffer, stop); ++ ++ md5_append(&md5, buffer, (int)remaining); ++ } ++ ++ /* cleanup */ ++ rc_file_close(iterator, file_handle); ++ free(buffer); ++ ++ return rc_hash_finalize(iterator, &md5, hash); ++} ++ ++int rc_hash_nintendo_ds(char hash[33], const rc_hash_iterator_t* iterator) ++{ ++ uint8_t header[512]; ++ uint8_t* hash_buffer; ++ uint32_t hash_size, arm9_size, arm9_addr, arm7_size, arm7_addr, icon_addr; ++ size_t num_read; ++ int64_t offset = 0; ++ md5_state_t md5; ++ void* file_handle; ++ ++ file_handle = rc_file_open(iterator, iterator->path); ++ if (!file_handle) ++ return rc_hash_iterator_error(iterator, "Could not open file"); ++ ++ rc_file_seek(iterator, file_handle, 0, SEEK_SET); ++ if (rc_file_read(iterator, file_handle, header, sizeof(header)) != 512) ++ return rc_hash_iterator_error(iterator, "Failed to read header"); ++ ++ if (header[0] == 0x2E && header[1] == 0x00 && header[2] == 0x00 && header[3] == 0xEA && ++ header[0xB0] == 0x44 && header[0xB1] == 0x46 && header[0xB2] == 0x96 && header[0xB3] == 0) { ++ /* SuperCard header detected, ignore it */ ++ rc_hash_iterator_verbose(iterator, "Ignoring SuperCard header"); ++ ++ offset = 512; ++ rc_file_seek(iterator, file_handle, offset, SEEK_SET); ++ rc_file_read(iterator, file_handle, header, sizeof(header)); ++ } ++ ++ arm9_addr = header[0x20] | (header[0x21] << 8) | (header[0x22] << 16) | (header[0x23] << 24); ++ arm9_size = header[0x2C] | (header[0x2D] << 8) | (header[0x2E] << 16) | (header[0x2F] << 24); ++ arm7_addr = header[0x30] | (header[0x31] << 8) | (header[0x32] << 16) | (header[0x33] << 24); ++ arm7_size = header[0x3C] | (header[0x3D] << 8) | (header[0x3E] << 16) | (header[0x3F] << 24); ++ icon_addr = header[0x68] | (header[0x69] << 8) | (header[0x6A] << 16) | (header[0x6B] << 24); ++ ++ if (arm9_size + arm7_size > 16 * 1024 * 1024) { ++ /* sanity check - code blocks are typically less than 1MB each - assume not a DS ROM */ ++ return rc_hash_iterator_error_formatted(iterator, "arm9 code size (%u) + arm7 code size (%u) exceeds 16MB", arm9_size, arm7_size); ++ } ++ ++ hash_size = 0xA00; ++ if (arm9_size > hash_size) ++ hash_size = arm9_size; ++ if (arm7_size > hash_size) ++ hash_size = arm7_size; ++ ++ hash_buffer = (uint8_t*)malloc(hash_size); ++ if (!hash_buffer) { ++ rc_file_close(iterator, file_handle); ++ return rc_hash_iterator_error_formatted(iterator, "Failed to allocate %u bytes", hash_size); ++ } ++ ++ md5_init(&md5); ++ ++ rc_hash_iterator_verbose(iterator, "Hashing 352 byte header"); ++ md5_append(&md5, header, 0x160); ++ ++ rc_hash_iterator_verbose_formatted(iterator, "Hashing %u byte arm9 code (at %08X)", arm9_size, arm9_addr); ++ ++ rc_file_seek(iterator, file_handle, arm9_addr + offset, SEEK_SET); ++ rc_file_read(iterator, file_handle, hash_buffer, arm9_size); ++ md5_append(&md5, hash_buffer, arm9_size); ++ ++ rc_hash_iterator_verbose_formatted(iterator, "Hashing %u byte arm7 code (at %08X)", arm7_size, arm7_addr); ++ ++ rc_file_seek(iterator, file_handle, arm7_addr + offset, SEEK_SET); ++ rc_file_read(iterator, file_handle, hash_buffer, arm7_size); ++ md5_append(&md5, hash_buffer, arm7_size); ++ ++ rc_hash_iterator_verbose_formatted(iterator, "Hashing 2560 byte icon and labels data (at %08X)", icon_addr); ++ ++ rc_file_seek(iterator, file_handle, icon_addr + offset, SEEK_SET); ++ num_read = rc_file_read(iterator, file_handle, hash_buffer, 0xA00); ++ if (num_read < 0xA00) { ++ /* some homebrew games don't provide a full icon block, and no data after the icon block. ++ * if we didn't get a full icon block, fill the remaining portion with 0s ++ */ ++ rc_hash_iterator_verbose_formatted(iterator, ++ "Warning: only got %u bytes for icon and labels data, 0-padding to 2560 bytes", (unsigned)num_read); ++ ++ memset(&hash_buffer[num_read], 0, 0xA00 - num_read); ++ } ++ md5_append(&md5, hash_buffer, 0xA00); ++ ++ free(hash_buffer); ++ rc_file_close(iterator, file_handle); ++ ++ return rc_hash_finalize(iterator, &md5, hash); ++} ++ ++int rc_hash_pce(char hash[33], const rc_hash_iterator_t* iterator) ++{ ++ /* The PCE header doesn't bear any distinguishable marks, so we have to detect ++ * it by looking at the file size. The core looks for anything that's 512 bytes ++ * more than a multiple of 8KB, so we'll do that too. ++ * https://github.com/libretro/beetle-pce-libretro/blob/af28fb0385d00e0292c4703b3aa7e72762b564d2/mednafen/pce/huc.cpp#L196-L202 ++ */ ++ if (iterator->buffer_size & 512) { ++ rc_hash_iterator_verbose(iterator, "Ignoring PCE header"); ++ return rc_hash_unheadered_iterator_buffer(hash, iterator, 512); ++ } ++ ++ return rc_hash_iterator_buffer(hash, iterator); ++} ++ ++int rc_hash_scv(char hash[33], const rc_hash_iterator_t* iterator) ++{ ++ /* if the file contains a header, ignore it */ ++ /* https://gitlab.com/MaaaX-EmuSCV/libretro-emuscv/-/blob/master/readme.txt#L211 */ ++ if (memcmp(iterator->buffer, "EmuSCV", 6) == 0) { ++ rc_hash_iterator_verbose(iterator, "Ignoring SCV header"); ++ return rc_hash_unheadered_iterator_buffer(hash, iterator, 32); ++ } ++ ++ return rc_hash_iterator_buffer(hash, iterator); ++} ++ ++int rc_hash_snes(char hash[33], const rc_hash_iterator_t* iterator) ++{ ++ /* if the file contains a header, ignore it */ ++ uint32_t calc_size = ((uint32_t)iterator->buffer_size / 0x2000) * 0x2000; ++ if (iterator->buffer_size - calc_size == 512) { ++ rc_hash_iterator_verbose(iterator, "Ignoring SNES header"); ++ return rc_hash_unheadered_iterator_buffer(hash, iterator, 512); ++ } ++ ++ return rc_hash_iterator_buffer(hash, iterator); ++} +diff -rupbN melonDS.orig/src/rcheevos/src/rhash/hash_zip.c melonDS.ra/src/rcheevos/src/rhash/hash_zip.c +--- melonDS.orig/src/rcheevos/src/rhash/hash_zip.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rhash/hash_zip.c 2026-03-06 21:37:07.050799942 +0000 +@@ -0,0 +1,460 @@ ++#include "rc_hash_internal.h" ++ ++#include "../rc_compat.h" ++ ++struct rc_hash_zip_idx ++{ ++ size_t length; ++ uint8_t* data; ++}; ++ ++static int rc_hash_zip_idx_sort(const void* a, const void* b) ++{ ++ struct rc_hash_zip_idx* A = (struct rc_hash_zip_idx*)a, * B = (struct rc_hash_zip_idx*)b; ++ size_t len = (A->length < B->length ? A->length : B->length); ++ return memcmp(A->data, B->data, len); ++} ++ ++typedef int (RC_CCONV* rc_hash_zip_filter_t)(const char* filename, uint32_t filename_len, uint64_t decomp_size, void* userdata); ++ ++static int rc_hash_zip_file(md5_state_t* md5, void* file_handle, ++ const rc_hash_iterator_t* iterator, ++ rc_hash_zip_filter_t filter_func, void* filter_userdata) ++{ ++ uint8_t buf[2048], *alloc_buf, *cdir_start, *cdir_max, *cdir, *hashdata, eocdirhdr_size, cdirhdr_size, nparents; ++ uint32_t cdir_entry_len; ++ size_t sizeof_idx, indices_offset, alloc_size; ++ int64_t i_file, archive_size, ecdh_ofs, total_files, cdir_size, cdir_ofs; ++ struct rc_hash_zip_idx* hashindices, *hashindex; ++ ++ rc_file_seek(iterator, file_handle, 0, SEEK_END); ++ archive_size = rc_file_tell(iterator, file_handle); ++ ++ /* Basic sanity checks - reject files which are too small */ ++ eocdirhdr_size = 22; /* the 'end of central directory header' is 22 bytes */ ++ if (archive_size < eocdirhdr_size) ++ return rc_hash_iterator_error(iterator, "ZIP is too small"); ++ ++ /* Macros used for reading ZIP and writing to a buffer for hashing (undefined again at the end of the function) */ ++ #define RC_ZIP_READ_LE16(p) ((uint16_t)(((const uint8_t*)(p))[0]) | ((uint16_t)(((const uint8_t*)(p))[1]) << 8U)) ++ #define RC_ZIP_READ_LE32(p) ((uint32_t)(((const uint8_t*)(p))[0]) | ((uint32_t)(((const uint8_t*)(p))[1]) << 8U) | ((uint32_t)(((const uint8_t*)(p))[2]) << 16U) | ((uint32_t)(((const uint8_t*)(p))[3]) << 24U)) ++ #define RC_ZIP_READ_LE64(p) ((uint64_t)(((const uint8_t*)(p))[0]) | ((uint64_t)(((const uint8_t*)(p))[1]) << 8U) | ((uint64_t)(((const uint8_t*)(p))[2]) << 16U) | ((uint64_t)(((const uint8_t*)(p))[3]) << 24U) | ((uint64_t)(((const uint8_t*)(p))[4]) << 32U) | ((uint64_t)(((const uint8_t*)(p))[5]) << 40U) | ((uint64_t)(((const uint8_t*)(p))[6]) << 48U) | ((uint64_t)(((const uint8_t*)(p))[7]) << 56U)) ++ #define RC_ZIP_WRITE_LE32(p,v) { ((uint8_t*)(p))[0] = (uint8_t)((uint32_t)(v) & 0xFF); ((uint8_t*)(p))[1] = (uint8_t)(((uint32_t)(v) >> 8) & 0xFF); ((uint8_t*)(p))[2] = (uint8_t)(((uint32_t)(v) >> 16) & 0xFF); ((uint8_t*)(p))[3] = (uint8_t)((uint32_t)(v) >> 24); } ++ #define RC_ZIP_WRITE_LE64(p,v) { ((uint8_t*)(p))[0] = (uint8_t)((uint64_t)(v) & 0xFF); ((uint8_t*)(p))[1] = (uint8_t)(((uint64_t)(v) >> 8) & 0xFF); ((uint8_t*)(p))[2] = (uint8_t)(((uint64_t)(v) >> 16) & 0xFF); ((uint8_t*)(p))[3] = (uint8_t)(((uint64_t)(v) >> 24) & 0xFF); ((uint8_t*)(p))[4] = (uint8_t)(((uint64_t)(v) >> 32) & 0xFF); ((uint8_t*)(p))[5] = (uint8_t)(((uint64_t)(v) >> 40) & 0xFF); ((uint8_t*)(p))[6] = (uint8_t)(((uint64_t)(v) >> 48) & 0xFF); ((uint8_t*)(p))[7] = (uint8_t)((uint64_t)(v) >> 56); } ++ ++ /* Find the end of central directory record by scanning the file from the end towards the beginning */ ++ for (ecdh_ofs = archive_size - sizeof(buf); ; ecdh_ofs -= (sizeof(buf) - 3)) { ++ int i, n = sizeof(buf); ++ if (ecdh_ofs < 0) ++ ecdh_ofs = 0; ++ if (n > archive_size) ++ n = (int)archive_size; ++ ++ rc_file_seek(iterator, file_handle, ecdh_ofs, SEEK_SET); ++ if (rc_file_read(iterator, file_handle, buf, n) != (size_t)n) ++ return rc_hash_iterator_error(iterator, "ZIP read error"); ++ ++ for (i = n - 4; i >= 0; --i) { ++ if (buf[i] == 'P' && RC_ZIP_READ_LE32(buf + i) == 0x06054b50) /* end of central directory header signature */ ++ break; ++ } ++ ++ if (i >= 0) { ++ ecdh_ofs += i; ++ break; ++ } ++ ++ if (!ecdh_ofs || (archive_size - ecdh_ofs) >= (0xFFFF + eocdirhdr_size)) ++ return rc_hash_iterator_error(iterator, "Failed to find ZIP central directory"); ++ } ++ ++ /* Read and verify the end of central directory record. */ ++ rc_file_seek(iterator, file_handle, ecdh_ofs, SEEK_SET); ++ if (rc_file_read(iterator, file_handle, buf, eocdirhdr_size) != eocdirhdr_size) ++ return rc_hash_iterator_error(iterator, "Failed to read ZIP central directory"); ++ ++ /* Read central dir information from end of central directory header */ ++ total_files = RC_ZIP_READ_LE16(buf + 0x0A); ++ cdir_size = RC_ZIP_READ_LE32(buf + 0x0C); ++ cdir_ofs = RC_ZIP_READ_LE32(buf + 0x10); ++ ++ /* Check if this is a Zip64 file. In the block of code below: ++ * - 20 is the size of the ZIP64 end of central directory locator ++ * - 56 is the size of the ZIP64 end of central directory header ++ */ ++ if ((cdir_ofs == 0xFFFFFFFF || cdir_size == 0xFFFFFFFF || total_files == 0xFFFF) && ecdh_ofs >= (20 + 56)) { ++ /* Read the ZIP64 end of central directory locator if it actually exists */ ++ rc_file_seek(iterator, file_handle, ecdh_ofs - 20, SEEK_SET); ++ if (rc_file_read(iterator, file_handle, buf, 20) == 20 && RC_ZIP_READ_LE32(buf) == 0x07064b50) { /* locator signature */ ++ /* Found the locator, now read the actual ZIP64 end of central directory header */ ++ int64_t ecdh64_ofs = (int64_t)RC_ZIP_READ_LE64(buf + 0x08); ++ if (ecdh64_ofs <= (archive_size - 56)) { ++ rc_file_seek(iterator, file_handle, ecdh64_ofs, SEEK_SET); ++ if (rc_file_read(iterator, file_handle, buf, 56) == 56 && RC_ZIP_READ_LE32(buf) == 0x06064b50) { /* header signature */ ++ total_files = RC_ZIP_READ_LE64(buf + 0x20); ++ cdir_size = RC_ZIP_READ_LE64(buf + 0x28); ++ cdir_ofs = RC_ZIP_READ_LE64(buf + 0x30); ++ } ++ } ++ } ++ } ++ ++ /* Basic verificaton of central directory (limit to a 256MB content directory) */ ++ cdirhdr_size = 46; /* the 'central directory header' is 46 bytes */ ++ if ((cdir_size >= 0x10000000) || (cdir_size < total_files * cdirhdr_size) || ((cdir_ofs + cdir_size) > archive_size)) ++ return rc_hash_iterator_error(iterator, "Central directory of ZIP file is invalid"); ++ ++ /* Allocate once for both directory and our temporary sort index (memory aligned to sizeof(rc_hash_zip_idx)) */ ++ sizeof_idx = sizeof(struct rc_hash_zip_idx); ++ indices_offset = (size_t)((cdir_size + sizeof_idx - 1) / sizeof_idx * sizeof_idx); ++ alloc_size = (size_t)(indices_offset + total_files * sizeof_idx); ++ alloc_buf = (uint8_t*)malloc(alloc_size); ++ ++ /* Read entire central directory to a buffer */ ++ if (!alloc_buf) ++ return rc_hash_iterator_error(iterator, "Could not allocate temporary buffer"); ++ ++ rc_file_seek(iterator, file_handle, cdir_ofs, SEEK_SET); ++ if ((int64_t)rc_file_read(iterator, file_handle, alloc_buf, (int)cdir_size) != cdir_size) { ++ free(alloc_buf); ++ return rc_hash_iterator_error(iterator, "Failed to read central directory of ZIP file"); ++ } ++ ++ cdir_start = alloc_buf; ++ cdir_max = cdir_start + cdir_size - cdirhdr_size; ++ cdir = cdir_start; ++ ++ /* Write our temporary hash data to the same buffer we read the central directory from. ++ * We can do that because the amount of data we keep for each file is guaranteed to be less than the file record. ++ */ ++ hashdata = alloc_buf; ++ hashindices = (struct rc_hash_zip_idx*)(alloc_buf + indices_offset); ++ hashindex = hashindices; ++ ++ /* Now process the central directory file records */ ++ for (i_file = nparents = 0, cdir = cdir_start; i_file < total_files && cdir >= cdir_start && cdir <= cdir_max; i_file++, cdir += cdir_entry_len) { ++ const uint8_t* name, * name_end; ++ uint32_t signature = RC_ZIP_READ_LE32(cdir + 0x00); ++ uint32_t method = RC_ZIP_READ_LE16(cdir + 0x0A); ++ uint32_t crc32 = RC_ZIP_READ_LE32(cdir + 0x10); ++ uint64_t comp_size = RC_ZIP_READ_LE32(cdir + 0x14); ++ uint64_t decomp_size = RC_ZIP_READ_LE32(cdir + 0x18); ++ uint32_t filename_len = RC_ZIP_READ_LE16(cdir + 0x1C); ++ int32_t extra_len = RC_ZIP_READ_LE16(cdir + 0x1E); ++ int32_t comment_len = RC_ZIP_READ_LE16(cdir + 0x20); ++ int32_t external_attr = RC_ZIP_READ_LE16(cdir + 0x26); ++ uint64_t local_hdr_ofs = RC_ZIP_READ_LE32(cdir + 0x2A); ++ cdir_entry_len = cdirhdr_size + filename_len + extra_len + comment_len; ++ ++ if (signature != 0x02014b50) /* expected central directory entry signature */ ++ break; ++ ++ /* Ignore records describing a directory (we only hash file records) */ ++ name = (cdir + cdirhdr_size); ++ if (name[filename_len - 1] == '/' || name[filename_len - 1] == '\\' || (external_attr & 0x10)) ++ continue; ++ ++ /* Handle Zip64 fields */ ++ if (decomp_size == 0xFFFFFFFF || comp_size == 0xFFFFFFFF || local_hdr_ofs == 0xFFFFFFFF) { ++ int invalid = 0; ++ const uint8_t* x = cdir + cdirhdr_size + filename_len, * xEnd, * field, * fieldEnd; ++ for (xEnd = x + extra_len; (x + (sizeof(uint16_t) * 2)) < xEnd; x = fieldEnd) { ++ field = x + (sizeof(uint16_t) * 2); ++ fieldEnd = field + RC_ZIP_READ_LE16(x + 2); ++ if (RC_ZIP_READ_LE16(x) != 0x0001 || fieldEnd > xEnd) ++ continue; /* Not the Zip64 extended information extra field */ ++ ++ if (decomp_size == 0xFFFFFFFF) { ++ if ((unsigned)(fieldEnd - field) < sizeof(uint64_t)) { ++ invalid = 1; ++ break; ++ } ++ ++ decomp_size = RC_ZIP_READ_LE64(field); ++ field += sizeof(uint64_t); ++ } ++ ++ if (comp_size == 0xFFFFFFFF) { ++ if ((unsigned)(fieldEnd - field) < sizeof(uint64_t)) { ++ invalid = 1; ++ break; ++ } ++ ++ comp_size = RC_ZIP_READ_LE64(field); ++ field += sizeof(uint64_t); ++ } ++ ++ if (local_hdr_ofs == 0xFFFFFFFF) { ++ if ((unsigned)(fieldEnd - field) < sizeof(uint64_t)) { ++ invalid = 1; ++ break; ++ } ++ ++ local_hdr_ofs = RC_ZIP_READ_LE64(field); ++ field += sizeof(uint64_t); ++ } ++ ++ break; ++ } ++ ++ if (invalid) { ++ free(alloc_buf); ++ return rc_hash_iterator_error(iterator, "Encountered invalid Zip64 file"); ++ } ++ } ++ ++ /* Basic sanity check on file record */ ++ /* 30 is the length of the local directory header preceeding the compressed data */ ++ if ((!method && decomp_size != comp_size) || (decomp_size && !comp_size) || ++ ((local_hdr_ofs + 30 + comp_size) > (uint64_t)archive_size)) { ++ free(alloc_buf); ++ return rc_hash_iterator_error(iterator, "Encountered invalid entry in ZIP central directory"); ++ } ++ ++ if (filter_func) { ++ int filtered = filter_func((const char*)name, filename_len, decomp_size, filter_userdata); ++ if (filtered < 0) { ++ free(alloc_buf); ++ return 0; ++ } ++ ++ if (filtered) /* this file shouldn't be hashed */ ++ continue; ++ } ++ ++ /* Write the pointer and length of the data we record about this file */ ++ hashindex->data = hashdata; ++ hashindex->length = filename_len + 1 + 4 + 8; ++ hashindex++; ++ ++ rc_hash_iterator_verbose_formatted(iterator, "File in ZIP: %.*s (%u bytes, CRC32 = %08X)", filename_len, (const char*)name, (unsigned)decomp_size, crc32); ++ ++ /* Convert and store the file name in the hash data buffer */ ++ for (name_end = name + filename_len; name != name_end; name++) { ++ *(hashdata++) = ++ (*name == '\\' ? '/' : /* convert back-slashes to regular slashes */ ++ (*name >= 'A' && *name <= 'Z') ? (*name | 0x20) : /* convert upper case letters to lower case */ ++ *name); /* else use the byte as-is */ ++ } ++ ++ /* Add zero terminator, CRC32 and decompressed size to the hash data buffer */ ++ *(hashdata++) = '\0'; ++ RC_ZIP_WRITE_LE32(hashdata, crc32); ++ hashdata += 4; ++ RC_ZIP_WRITE_LE64(hashdata, decomp_size); ++ hashdata += 8; ++ } ++ ++ rc_hash_iterator_verbose_formatted(iterator, "Hashing %u files in ZIP archive", (unsigned)(hashindex - hashindices)); ++ ++ /* Sort the file list indices */ ++ qsort(hashindices, (hashindex - hashindices), sizeof(struct rc_hash_zip_idx), rc_hash_zip_idx_sort); ++ ++ /* Hash the data in the order of the now sorted indices */ ++ for (; hashindices != hashindex; hashindices++) ++ md5_append(md5, hashindices->data, (int)hashindices->length); ++ ++ free(alloc_buf); ++ ++ return 1; ++ ++ #undef RC_ZIP_READ_LE16 ++ #undef RC_ZIP_READ_LE32 ++ #undef RC_ZIP_READ_LE64 ++ #undef RC_ZIP_WRITE_LE32 ++ #undef RC_ZIP_WRITE_LE64 ++} ++ ++/* ===================================================== */ ++ ++static int rc_hash_arduboyfx_filter(const char* filename, uint32_t filename_len, uint64_t decomp_size, void* userdata) ++{ ++ (void)decomp_size; ++ (void)userdata; ++ ++ /* An .arduboy file is a zip file containing an info.json pointing at one or more bin ++ * and hex files. It can also contain a bunch of screenshots, but we don't care about ++ * those. As they're also referenced in the info.json, we have to ignore that too. ++ * Instead of ignoring the info.json and all image files, only process any bin/hex files */ ++ if (filename_len > 4) { ++ const char* ext = &filename[filename_len - 4]; ++ if (strncasecmp(ext, ".hex", 4) == 0 || strncasecmp(ext, ".bin", 4) == 0) ++ return 0; /* keep hex and bin */ ++ } ++ ++ return 1; /* filter everything else */ ++} ++ ++int rc_hash_arduboyfx(char hash[33], const rc_hash_iterator_t* iterator) ++{ ++ md5_state_t md5; ++ int res; ++ ++ void* file_handle = rc_file_open(iterator, iterator->path); ++ if (!file_handle) ++ return rc_hash_iterator_error(iterator, "Could not open file"); ++ ++ md5_init(&md5); ++ res = rc_hash_zip_file(&md5, file_handle, iterator, rc_hash_arduboyfx_filter, NULL); ++ rc_file_close(iterator, file_handle); ++ ++ if (!res) ++ return 0; ++ ++ return rc_hash_finalize(iterator, &md5, hash); ++} ++ ++/* ===================================================== */ ++ ++struct rc_hash_ms_dos_dosz_state { ++ const char* path; ++ const struct rc_hash_ms_dos_dosz_state* child; ++ ++ md5_state_t* md5; ++ const rc_hash_iterator_t* iterator; ++ void* file_handle; ++ uint32_t nparents; ++}; ++ ++static int rc_hash_dosz(struct rc_hash_ms_dos_dosz_state* dosz); ++ ++static int rc_hash_ms_dos_parent(const struct rc_hash_ms_dos_dosz_state* child, ++ const char* parentname, uint32_t parentname_len) ++{ ++ const char* lastfslash = strrchr(child->path, '/'); ++ const char* lastbslash = strrchr(child->path, '\\'); ++ const char* lastslash = (lastbslash > lastfslash ? lastbslash : lastfslash); ++ size_t dir_len = (lastslash ? (lastslash + 1 - child->path) : 0); ++ char* parent_path = (char*)malloc(dir_len + parentname_len + 1); ++ struct rc_hash_ms_dos_dosz_state parent; ++ const struct rc_hash_ms_dos_dosz_state* check; ++ void* parent_handle; ++ int parent_res; ++ ++ /* Build the path of the parent by combining the directory of the current file with the name */ ++ if (!parent_path) ++ return rc_hash_iterator_error(child->iterator, "Could not allocate temporary buffer"); ++ ++ memcpy(parent_path, child->path, dir_len); ++ memcpy(parent_path + dir_len, parentname, parentname_len); ++ parent_path[dir_len + parentname_len] = '\0'; ++ ++ /* Make sure there is no recursion where a parent DOSZ is an already seen child DOSZ */ ++ for (check = child->child; check; check = check->child) { ++ if (!strcmp(check->path, parent_path)) { ++ free(parent_path); ++ return rc_hash_iterator_error(child->iterator, "Invalid DOSZ file with recursive parents"); ++ } ++ } ++ ++ /* Try to open the parent DOSZ file */ ++ parent_handle = rc_file_open(child->iterator, parent_path); ++ if (!parent_handle) { ++ rc_hash_iterator_error_formatted(child->iterator, "DOSZ parent file '%s' does not exist", parent_path); ++ free(parent_path); ++ return 0; ++ } ++ ++ /* Fully hash the parent DOSZ ahead of the child */ ++ memcpy(&parent, child, sizeof(parent)); ++ parent.path = parent_path; ++ parent.child = child; ++ parent.file_handle = parent_handle; ++ parent_res = rc_hash_dosz(&parent); ++ rc_file_close(child->iterator, parent_handle); ++ free(parent_path); ++ return parent_res; ++} ++ ++static int rc_hash_ms_dos_dosc(const struct rc_hash_ms_dos_dosz_state* dosz) ++{ ++ size_t path_len = strlen(dosz->path); ++ if (dosz->path[path_len - 1] == 'z' || dosz->path[path_len - 1] == 'Z') { ++ void* file_handle; ++ char* dosc_path = strdup(dosz->path); ++ if (!dosc_path) ++ return rc_hash_iterator_error(dosz->iterator, "Could not allocate temporary buffer"); ++ ++ /* Swap the z to c and use the same capitalization, hash the file if it exists */ ++ dosc_path[path_len - 1] = (dosz->path[path_len - 1] == 'z' ? 'c' : 'C'); ++ file_handle = rc_file_open(dosz->iterator, dosc_path); ++ free(dosc_path); ++ ++ if (file_handle) { ++ /* Hash the entire contents of the DOSC file */ ++ int res = rc_hash_zip_file(dosz->md5, file_handle, dosz->iterator, NULL, NULL); ++ rc_file_close(dosz->iterator, file_handle); ++ if (!res) ++ return 0; ++ } ++ } ++ ++ return 1; ++} ++ ++static int rc_hash_dosz_filter(const char* filename, uint32_t filename_len, uint64_t decomp_size, void* userdata) ++{ ++ struct rc_hash_ms_dos_dosz_state* dosz = (struct rc_hash_ms_dos_dosz_state*)userdata; ++ ++ /* A DOSZ file can contain a special empty .dosz.parent file in its root which means a parent dosz file is used */ ++ if (decomp_size == 0 && filename_len > 7 && ++ strncasecmp(&filename[filename_len - 7], ".parent", 7) == 0 && ++ !memchr(filename, '/', filename_len) && ++ !memchr(filename, '\\', filename_len)) ++ { ++ /* A DOSZ file can only have one parent file */ ++ if (dosz->nparents++) ++ return -1; ++ ++ /* process the parent. if it fails, stop */ ++ if (!rc_hash_ms_dos_parent(dosz, filename, (filename_len - 7))) ++ return -1; ++ ++ /* We don't hash this meta file so a user is free to rename it and the parent file */ ++ return 1; ++ } ++ ++ return 0; ++} ++ ++static int rc_hash_dosz(struct rc_hash_ms_dos_dosz_state* dosz) ++{ ++ if (!rc_hash_zip_file(dosz->md5, dosz->file_handle, dosz->iterator, rc_hash_dosz_filter, dosz)) ++ return 0; ++ ++ /* A DOSZ file can only have one parent file */ ++ if (dosz->nparents > 1) ++ return rc_hash_iterator_error(dosz->iterator, "Invalid DOSZ file with multiple parents"); ++ ++ /* Check if an associated .dosc file exists */ ++ if (!rc_hash_ms_dos_dosc(dosz)) ++ return 0; ++ ++ return 1; ++} ++ ++int rc_hash_ms_dos(char hash[33], const rc_hash_iterator_t* iterator) ++{ ++ struct rc_hash_ms_dos_dosz_state dosz; ++ md5_state_t md5; ++ int res; ++ ++ void* file_handle = rc_file_open(iterator, iterator->path); ++ if (!file_handle) ++ return rc_hash_iterator_error(iterator, "Could not open file"); ++ ++ memset(&dosz, 0, sizeof(dosz)); ++ dosz.path = iterator->path; ++ dosz.file_handle = file_handle; ++ dosz.iterator = iterator; ++ dosz.md5 = &md5; ++ ++ md5_init(&md5); ++ res = rc_hash_dosz(&dosz); ++ rc_file_close(iterator, file_handle); ++ ++ if (!res) ++ return 0; ++ ++ return rc_hash_finalize(iterator, &md5, hash); ++} +diff -rupbN melonDS.orig/src/rcheevos/src/rhash/md5.c melonDS.ra/src/rcheevos/src/rhash/md5.c +--- melonDS.orig/src/rcheevos/src/rhash/md5.c 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rhash/md5.c 2026-03-06 21:37:07.050799942 +0000 +@@ -0,0 +1,382 @@ ++/* ++ Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. ++ ++ This software is provided 'as-is', without any express or implied ++ warranty. In no event will the authors be held liable for any damages ++ arising from the use of this software. ++ ++ Permission is granted to anyone to use this software for any purpose, ++ including commercial applications, and to alter it and redistribute it ++ freely, subject to the following restrictions: ++ ++ 1. The origin of this software must not be misrepresented; you must not ++ claim that you wrote the original software. If you use this software ++ in a product, an acknowledgment in the product documentation would be ++ appreciated but is not required. ++ 2. Altered source versions must be plainly marked as such, and must not be ++ misrepresented as being the original software. ++ 3. This notice may not be removed or altered from any source distribution. ++ ++ L. Peter Deutsch ++ ghost@aladdin.com ++ ++ */ ++/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */ ++/* ++ Independent implementation of MD5 (RFC 1321). ++ ++ This code implements the MD5 Algorithm defined in RFC 1321, whose ++ text is available at ++ http://www.ietf.org/rfc/rfc1321.txt ++ The code is derived from the text of the RFC, including the test suite ++ (section A.5) but excluding the rest of Appendix A. It does not include ++ any code or documentation that is identified in the RFC as being ++ copyrighted. ++ ++ The original and principal author of md5.c is L. Peter Deutsch ++ . Other authors are noted in the change history ++ that follows (in reverse chronological order): ++ ++ 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order ++ either statically or dynamically; added missing #include ++ in library. ++ 2002-03-11 lpd Corrected argument list for main(), and added int return ++ type, in test program and T value program. ++ 2002-02-21 lpd Added missing #include in test program. ++ 2000-07-03 lpd Patched to eliminate warnings about "constant is ++ unsigned in ANSI C, signed in traditional"; made test program ++ self-checking. ++ 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. ++ 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). ++ 1999-05-03 lpd Original version. ++ */ ++ ++#include "md5.h" ++#include ++#include ++ ++#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ ++#ifdef ARCH_IS_BIG_ENDIAN ++# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) ++#else ++# define BYTE_ORDER 0 ++#endif ++ ++#define T_MASK ((md5_word_t)~0) ++#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) ++#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) ++#define T3 0x242070db ++#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) ++#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) ++#define T6 0x4787c62a ++#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) ++#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) ++#define T9 0x698098d8 ++#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) ++#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) ++#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) ++#define T13 0x6b901122 ++#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) ++#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) ++#define T16 0x49b40821 ++#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) ++#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) ++#define T19 0x265e5a51 ++#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) ++#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) ++#define T22 0x02441453 ++#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) ++#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) ++#define T25 0x21e1cde6 ++#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) ++#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) ++#define T28 0x455a14ed ++#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) ++#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) ++#define T31 0x676f02d9 ++#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) ++#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) ++#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) ++#define T35 0x6d9d6122 ++#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) ++#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) ++#define T38 0x4bdecfa9 ++#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) ++#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) ++#define T41 0x289b7ec6 ++#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) ++#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) ++#define T44 0x04881d05 ++#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) ++#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) ++#define T47 0x1fa27cf8 ++#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) ++#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) ++#define T50 0x432aff97 ++#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) ++#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) ++#define T53 0x655b59c3 ++#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) ++#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) ++#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) ++#define T57 0x6fa87e4f ++#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) ++#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) ++#define T60 0x4e0811a1 ++#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) ++#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) ++#define T63 0x2ad7d2bb ++#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) ++ ++ ++static void ++md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) ++{ ++ md5_word_t ++ a = pms->abcd[0], b = pms->abcd[1], ++ c = pms->abcd[2], d = pms->abcd[3]; ++ md5_word_t t; ++#if BYTE_ORDER > 0 ++ /* Define storage only for big-endian CPUs. */ ++ md5_word_t X[16]; ++#else ++ /* Define storage for little-endian or both types of CPUs. */ ++ md5_word_t xbuf[16]; ++ const md5_word_t *X; ++#endif ++ ++ { ++#if BYTE_ORDER == 0 ++ /* ++ * Determine dynamically whether this is a big-endian or ++ * little-endian machine, since we can use a more efficient ++ * algorithm on the latter. ++ */ ++ static const int w = 1; ++ ++ if (*((const md5_byte_t *)&w)) /* dynamic little-endian */ ++#endif ++#if BYTE_ORDER <= 0 /* little-endian */ ++ { ++ /* ++ * On little-endian machines, we can process properly aligned ++ * data without copying it. ++ */ ++ if (!((ptrdiff_t)data & 3)) { ++ /* data are properly aligned */ ++ X = (const md5_word_t *)data; ++ } else { ++ /* not aligned */ ++ memcpy(xbuf, data, 64); ++ X = xbuf; ++ } ++ } ++#endif ++#if BYTE_ORDER == 0 ++ else /* dynamic big-endian */ ++#endif ++#if BYTE_ORDER >= 0 /* big-endian */ ++ { ++ /* ++ * On big-endian machines, we must arrange the bytes in the ++ * right order. ++ */ ++ const md5_byte_t *xp = data; ++ int i; ++ ++# if BYTE_ORDER == 0 ++ X = xbuf; /* (dynamic only) */ ++# else ++# define xbuf X /* (static only) */ ++# endif ++ for (i = 0; i < 16; ++i, xp += 4) ++ xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); ++ } ++#endif ++ } ++ ++#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) ++ ++ /* Round 1. */ ++ /* Let [abcd k s i] denote the operation ++ a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ ++#define F(x, y, z) (((x) & (y)) | (~(x) & (z))) ++#define SET(a, b, c, d, k, s, Ti)\ ++ t = a + F(b,c,d) + X[k] + Ti;\ ++ a = ROTATE_LEFT(t, s) + b ++ /* Do the following 16 operations. */ ++ SET(a, b, c, d, 0, 7, T1); ++ SET(d, a, b, c, 1, 12, T2); ++ SET(c, d, a, b, 2, 17, T3); ++ SET(b, c, d, a, 3, 22, T4); ++ SET(a, b, c, d, 4, 7, T5); ++ SET(d, a, b, c, 5, 12, T6); ++ SET(c, d, a, b, 6, 17, T7); ++ SET(b, c, d, a, 7, 22, T8); ++ SET(a, b, c, d, 8, 7, T9); ++ SET(d, a, b, c, 9, 12, T10); ++ SET(c, d, a, b, 10, 17, T11); ++ SET(b, c, d, a, 11, 22, T12); ++ SET(a, b, c, d, 12, 7, T13); ++ SET(d, a, b, c, 13, 12, T14); ++ SET(c, d, a, b, 14, 17, T15); ++ SET(b, c, d, a, 15, 22, T16); ++#undef SET ++ ++ /* Round 2. */ ++ /* Let [abcd k s i] denote the operation ++ a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ ++#define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) ++#define SET(a, b, c, d, k, s, Ti)\ ++ t = a + G(b,c,d) + X[k] + Ti;\ ++ a = ROTATE_LEFT(t, s) + b ++ /* Do the following 16 operations. */ ++ SET(a, b, c, d, 1, 5, T17); ++ SET(d, a, b, c, 6, 9, T18); ++ SET(c, d, a, b, 11, 14, T19); ++ SET(b, c, d, a, 0, 20, T20); ++ SET(a, b, c, d, 5, 5, T21); ++ SET(d, a, b, c, 10, 9, T22); ++ SET(c, d, a, b, 15, 14, T23); ++ SET(b, c, d, a, 4, 20, T24); ++ SET(a, b, c, d, 9, 5, T25); ++ SET(d, a, b, c, 14, 9, T26); ++ SET(c, d, a, b, 3, 14, T27); ++ SET(b, c, d, a, 8, 20, T28); ++ SET(a, b, c, d, 13, 5, T29); ++ SET(d, a, b, c, 2, 9, T30); ++ SET(c, d, a, b, 7, 14, T31); ++ SET(b, c, d, a, 12, 20, T32); ++#undef SET ++ ++ /* Round 3. */ ++ /* Let [abcd k s t] denote the operation ++ a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ ++#define H(x, y, z) ((x) ^ (y) ^ (z)) ++#define SET(a, b, c, d, k, s, Ti)\ ++ t = a + H(b,c,d) + X[k] + Ti;\ ++ a = ROTATE_LEFT(t, s) + b ++ /* Do the following 16 operations. */ ++ SET(a, b, c, d, 5, 4, T33); ++ SET(d, a, b, c, 8, 11, T34); ++ SET(c, d, a, b, 11, 16, T35); ++ SET(b, c, d, a, 14, 23, T36); ++ SET(a, b, c, d, 1, 4, T37); ++ SET(d, a, b, c, 4, 11, T38); ++ SET(c, d, a, b, 7, 16, T39); ++ SET(b, c, d, a, 10, 23, T40); ++ SET(a, b, c, d, 13, 4, T41); ++ SET(d, a, b, c, 0, 11, T42); ++ SET(c, d, a, b, 3, 16, T43); ++ SET(b, c, d, a, 6, 23, T44); ++ SET(a, b, c, d, 9, 4, T45); ++ SET(d, a, b, c, 12, 11, T46); ++ SET(c, d, a, b, 15, 16, T47); ++ SET(b, c, d, a, 2, 23, T48); ++#undef SET ++ ++ /* Round 4. */ ++ /* Let [abcd k s t] denote the operation ++ a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ ++#define I(x, y, z) ((y) ^ ((x) | ~(z))) ++#define SET(a, b, c, d, k, s, Ti)\ ++ t = a + I(b,c,d) + X[k] + Ti;\ ++ a = ROTATE_LEFT(t, s) + b ++ /* Do the following 16 operations. */ ++ SET(a, b, c, d, 0, 6, T49); ++ SET(d, a, b, c, 7, 10, T50); ++ SET(c, d, a, b, 14, 15, T51); ++ SET(b, c, d, a, 5, 21, T52); ++ SET(a, b, c, d, 12, 6, T53); ++ SET(d, a, b, c, 3, 10, T54); ++ SET(c, d, a, b, 10, 15, T55); ++ SET(b, c, d, a, 1, 21, T56); ++ SET(a, b, c, d, 8, 6, T57); ++ SET(d, a, b, c, 15, 10, T58); ++ SET(c, d, a, b, 6, 15, T59); ++ SET(b, c, d, a, 13, 21, T60); ++ SET(a, b, c, d, 4, 6, T61); ++ SET(d, a, b, c, 11, 10, T62); ++ SET(c, d, a, b, 2, 15, T63); ++ SET(b, c, d, a, 9, 21, T64); ++#undef SET ++ ++ /* Then perform the following additions. (That is increment each ++ of the four registers by the value it had before this block ++ was started.) */ ++ pms->abcd[0] += a; ++ pms->abcd[1] += b; ++ pms->abcd[2] += c; ++ pms->abcd[3] += d; ++} ++ ++void ++md5_init(md5_state_t *pms) ++{ ++ pms->count[0] = pms->count[1] = 0; ++ pms->abcd[0] = 0x67452301; ++ pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; ++ pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; ++ pms->abcd[3] = 0x10325476; ++} ++ ++void ++md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes) ++{ ++ const md5_byte_t *p = data; ++ int left = nbytes; ++ int offset = (pms->count[0] >> 3) & 63; ++ md5_word_t nbits = (md5_word_t)(nbytes << 3); ++ ++ if (nbytes <= 0) ++ return; ++ ++ /* Update the message length. */ ++ pms->count[1] += nbytes >> 29; ++ pms->count[0] += nbits; ++ if (pms->count[0] < nbits) ++ pms->count[1]++; ++ ++ /* Process an initial partial block. */ ++ if (offset) { ++ int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); ++ ++ memcpy(pms->buf + offset, p, copy); ++ if (offset + copy < 64) ++ return; ++ p += copy; ++ left -= copy; ++ md5_process(pms, pms->buf); ++ } ++ ++ /* Process full blocks. */ ++ for (; left >= 64; p += 64, left -= 64) ++ md5_process(pms, p); ++ ++ /* Process a final partial block. */ ++ if (left) ++ memcpy(pms->buf, p, left); ++} ++ ++void ++md5_finish(md5_state_t *pms, md5_byte_t digest[16]) ++{ ++ static const md5_byte_t pad[64] = { ++ 0x80, 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 ++ }; ++ md5_byte_t data[8]; ++ int i; ++ ++ /* Save the length before padding. */ ++ for (i = 0; i < 8; ++i) ++ data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); ++ /* Pad to 56 bytes mod 64. */ ++ md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); ++ /* Append the length. */ ++ md5_append(pms, data, 8); ++ for (i = 0; i < 16; ++i) ++ digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); ++} +diff -rupbN melonDS.orig/src/rcheevos/src/rhash/md5.h melonDS.ra/src/rcheevos/src/rhash/md5.h +--- melonDS.orig/src/rcheevos/src/rhash/md5.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rhash/md5.h 2026-03-06 21:37:07.050799942 +0000 +@@ -0,0 +1,91 @@ ++/* ++ Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved. ++ ++ This software is provided 'as-is', without any express or implied ++ warranty. In no event will the authors be held liable for any damages ++ arising from the use of this software. ++ ++ Permission is granted to anyone to use this software for any purpose, ++ including commercial applications, and to alter it and redistribute it ++ freely, subject to the following restrictions: ++ ++ 1. The origin of this software must not be misrepresented; you must not ++ claim that you wrote the original software. If you use this software ++ in a product, an acknowledgment in the product documentation would be ++ appreciated but is not required. ++ 2. Altered source versions must be plainly marked as such, and must not be ++ misrepresented as being the original software. ++ 3. This notice may not be removed or altered from any source distribution. ++ ++ L. Peter Deutsch ++ ghost@aladdin.com ++ ++ */ ++/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */ ++/* ++ Independent implementation of MD5 (RFC 1321). ++ ++ This code implements the MD5 Algorithm defined in RFC 1321, whose ++ text is available at ++ http://www.ietf.org/rfc/rfc1321.txt ++ The code is derived from the text of the RFC, including the test suite ++ (section A.5) but excluding the rest of Appendix A. It does not include ++ any code or documentation that is identified in the RFC as being ++ copyrighted. ++ ++ The original and principal author of md5.h is L. Peter Deutsch ++ . Other authors are noted in the change history ++ that follows (in reverse chronological order): ++ ++ 2002-04-13 lpd Removed support for non-ANSI compilers; removed ++ references to Ghostscript; clarified derivation from RFC 1321; ++ now handles byte order either statically or dynamically. ++ 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. ++ 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); ++ added conditionalization for C++ compilation from Martin ++ Purschke . ++ 1999-05-03 lpd Original version. ++ */ ++ ++#ifndef md5_INCLUDED ++# define md5_INCLUDED ++ ++/* ++ * This package supports both compile-time and run-time determination of CPU ++ * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be ++ * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is ++ * defined as non-zero, the code will be compiled to run only on big-endian ++ * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to ++ * run on either big- or little-endian CPUs, but will run slightly less ++ * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. ++ */ ++ ++typedef unsigned char md5_byte_t; /* 8-bit byte */ ++typedef unsigned int md5_word_t; /* 32-bit word */ ++ ++/* Define the state of the MD5 Algorithm. */ ++typedef struct md5_state_s { ++ md5_word_t count[2]; /* message length in bits, lsw first */ ++ md5_word_t abcd[4]; /* digest buffer */ ++ md5_byte_t buf[64]; /* accumulate block */ ++} md5_state_t; ++ ++#ifdef __cplusplus ++extern "C" ++{ ++#endif ++ ++/* Initialize the algorithm. */ ++void md5_init(md5_state_t *pms); ++ ++/* Append a string to the message. */ ++void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); ++ ++/* Finish the message and return the digest. */ ++void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); ++ ++#ifdef __cplusplus ++} /* end extern "C" */ ++#endif ++ ++#endif /* md5_INCLUDED */ +diff -rupbN melonDS.orig/src/rcheevos/src/rhash/rc_hash_internal.h melonDS.ra/src/rcheevos/src/rhash/rc_hash_internal.h +--- melonDS.orig/src/rcheevos/src/rhash/rc_hash_internal.h 1970-01-01 00:00:00.000000000 +0000 ++++ melonDS.ra/src/rcheevos/src/rhash/rc_hash_internal.h 2026-03-06 21:37:07.050799942 +0000 +@@ -0,0 +1,116 @@ ++#ifndef RC_HASH_INTERNAL_H ++#define RC_HASH_INTERNAL_H ++ ++#include "rc_hash.h" ++#include "md5.h" ++ ++RC_BEGIN_C_DECLS ++ ++/* hash.c */ ++ ++void* rc_file_open(const rc_hash_iterator_t* iterator, const char* path); ++void rc_file_seek(const rc_hash_iterator_t* iterator, void* file_handle, int64_t offset, int origin); ++int64_t rc_file_tell(const rc_hash_iterator_t* iterator, void* file_handle); ++size_t rc_file_read(const rc_hash_iterator_t* iterator, void* file_handle, void* buffer, int requested_bytes); ++void rc_file_close(const rc_hash_iterator_t* iterator, void* file_handle); ++int64_t rc_file_size(const rc_hash_iterator_t* iterator, const char* path); ++ ++ ++void rc_hash_iterator_verbose(const rc_hash_iterator_t* iterator, const char* message); ++void rc_hash_iterator_verbose_formatted(const rc_hash_iterator_t* iterator, const char* format, ...); ++int rc_hash_iterator_error(const rc_hash_iterator_t* iterator, const char* message); ++int rc_hash_iterator_error_formatted(const rc_hash_iterator_t* iterator, const char* format, ...); ++ ++ ++/* arbitrary limit to prevent allocating and hashing large files */ ++#define MAX_BUFFER_SIZE 64 * 1024 * 1024 ++ ++void rc_hash_merge_callbacks(rc_hash_iterator_t* iterator, const rc_hash_callbacks_t* callbacks); ++int rc_hash_finalize(const rc_hash_iterator_t* iterator, md5_state_t* md5, char hash[33]); ++ ++int rc_hash_buffer(char hash[33], const uint8_t* buffer, size_t buffer_size, const rc_hash_iterator_t* iterator); ++void rc_hash_byteswap16(uint8_t* buffer, const uint8_t* stop); ++void rc_hash_byteswap32(uint8_t* buffer, const uint8_t* stop); ++ ++ ++const char* rc_path_get_filename(const char* path); ++const char* rc_path_get_extension(const char* path); ++int rc_path_compare_extension(const char* path, const char* ext); ++ ++ ++typedef void (RC_CCONV* rc_hash_iterator_ext_handler_t)(rc_hash_iterator_t* iterator, int data); ++typedef struct rc_hash_iterator_ext_handler_entry_t { ++ char ext[8]; ++ rc_hash_iterator_ext_handler_t handler; ++ int data; ++} rc_hash_iterator_ext_handler_entry_t; ++ ++const rc_hash_iterator_ext_handler_entry_t* rc_hash_get_iterator_ext_handlers(size_t* num_handlers); ++ ++ ++typedef struct rc_hash_cdrom_track_t { ++ void* file_handle; /* the file handle for reading the track data */ ++ const rc_hash_filereader_t* file_reader; /* functions to perform raw file I/O */ ++ int64_t file_track_offset;/* the offset of the track data within the file */ ++ int sector_size; /* the size of each sector in the track data */ ++ int sector_header_size; /* the offset to the raw data within a sector block */ ++ int raw_data_size; /* the amount of raw data within a sector block */ ++ int track_first_sector; /* the first absolute sector associated to the track (includes pregap) */ ++ int track_pregap_sectors; /* the number of pregap sectors */ ++#ifndef NDEBUG ++ uint32_t track_id; /* the index of the track */ ++#endif ++} rc_hash_cdrom_track_t; ++ ++ ++int rc_hash_whole_file(char hash[33], const rc_hash_iterator_t* iterator); ++int rc_hash_buffered_file(char hash[33], uint32_t console_id, const rc_hash_iterator_t* iterator); ++ ++#ifndef RC_HASH_NO_ROM ++ /* hash_rom.c */ ++ int rc_hash_7800(char hash[33], const rc_hash_iterator_t* iterator); ++ int rc_hash_arcade(char hash[33], const rc_hash_iterator_t* iterator); ++ int rc_hash_arduboy(char hash[33], const rc_hash_iterator_t* iterator); ++ int rc_hash_lynx(char hash[33], const rc_hash_iterator_t* iterator); ++ int rc_hash_nes(char hash[33], const rc_hash_iterator_t* iterator); ++ int rc_hash_n64(char hash[33], const rc_hash_iterator_t* iterator); ++ int rc_hash_nintendo_ds(char hash[33], const rc_hash_iterator_t* iterator); ++ int rc_hash_pce(char hash[33], const rc_hash_iterator_t* iterator); ++ int rc_hash_scv(char hash[33], const rc_hash_iterator_t* iterator); ++ int rc_hash_snes(char hash[33], const rc_hash_iterator_t* iterator); ++#endif ++ ++#ifndef RC_HASH_NO_DISC ++ /* hash_disc.c */ ++ void rc_hash_reset_iterator_disc(rc_hash_iterator_t* iterator); ++ ++ int rc_hash_3do(char hash[33], const rc_hash_iterator_t* iterator); ++ int rc_hash_dreamcast(char hash[33], const rc_hash_iterator_t* iterator); ++ int rc_hash_gamecube(char hash[33], const rc_hash_iterator_t* iterator); ++ int rc_hash_jaguar_cd(char hash[33], const rc_hash_iterator_t* iterator); ++ int rc_hash_neogeo_cd(char hash[33], const rc_hash_iterator_t* iterator); ++ int rc_hash_pce_cd(char hash[33], const rc_hash_iterator_t* iterator); ++ int rc_hash_pcfx_cd(char hash[33], const rc_hash_iterator_t* iterator); ++ int rc_hash_psx(char hash[33], const rc_hash_iterator_t* iterator); ++ int rc_hash_ps2(char hash[33], const rc_hash_iterator_t* iterator); ++ int rc_hash_psp(char hash[33], const rc_hash_iterator_t* iterator); ++ int rc_hash_sega_cd(char hash[33], const rc_hash_iterator_t* iterator); ++ int rc_hash_wii(char hash[33], const rc_hash_iterator_t* iterator); ++#endif ++ ++#ifndef RC_HASH_NO_ENCRYPTED ++ /* hash_encrypted.c */ ++ void rc_hash_reset_iterator_encrypted(rc_hash_iterator_t* iterator); ++ ++ int rc_hash_nintendo_3ds(char hash[33], const rc_hash_iterator_t* iterator); ++#endif ++ ++#ifndef RC_HASH_NO_ZIP ++ /* hash_zip.c */ ++ int rc_hash_ms_dos(char hash[33], const rc_hash_iterator_t* iterator); ++ int rc_hash_arduboyfx(char hash[33], const rc_hash_iterator_t* iterator); ++#endif ++ ++RC_END_C_DECLS ++ ++#endif /* RC_HASH_INTERNAL_H */ diff --git a/projects/ArchR/packages/emulators/standalone/melonds-sa/patches/001-default-config.patch b/projects/ArchR/packages/emulators/standalone/melonds-sa/patches/001-default-config.patch new file mode 100644 index 0000000000..0ac79d4a6c --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/melonds-sa/patches/001-default-config.patch @@ -0,0 +1,44 @@ +diff --git a/src/frontend/qt_sdl/Config.cpp b/src/frontend/qt_sdl/Config.cpp +index f767fcc9..86981f1f 100644 +--- a/src/frontend/qt_sdl/Config.cpp ++++ b/src/frontend/qt_sdl/Config.cpp +@@ -39,10 +39,9 @@ namespace Config + using namespace melonDS; + + +-const char* kConfigFile = "melonDS.toml"; ++const char* kConfigFile = "/storage/.config/melonDS/melonDS.toml"; + +-const char* kLegacyConfigFile = "melonDS.ini"; +-const char* kLegacyUniqueConfigFile = "melonDS.%d.ini"; ++const char* kLegacyConfigFile = "/storage/.config/melonDS/melonDS.ini"; + + toml::value RootTable; + +@@ -682,16 +681,7 @@ template T Table::FindDefault(const std::string& path, T def, Defaul + bool LoadLegacyFile(int inst) + { + Platform::FileHandle* f; +- if (inst > 0) +- { +- char name[100] = {0}; +- snprintf(name, 99, kLegacyUniqueConfigFile, inst+1); +- f = Platform::OpenLocalFile(name, Platform::FileMode::ReadText); +- } +- else +- { +- f = Platform::OpenLocalFile(kLegacyConfigFile, Platform::FileMode::ReadText); +- } ++ f = Platform::OpenLocalFile(kLegacyConfigFile, Platform::FileMode::ReadText); + + if (!f) return true; + +@@ -717,8 +707,6 @@ bool LoadLegacyFile(int inst) + { + if (!strncmp(entry->Name, entryname, 32)) + { +- if (!(entry->InstanceUnique ^ (inst == -1))) +- break; + + std::string path = entry->TOMLPath; + toml::value* table = root; diff --git a/projects/ArchR/packages/emulators/standalone/melonds-sa/patches/002-enable-dual-screen-fullscreen.patch b/projects/ArchR/packages/emulators/standalone/melonds-sa/patches/002-enable-dual-screen-fullscreen.patch new file mode 100644 index 0000000000..7c46523df0 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/melonds-sa/patches/002-enable-dual-screen-fullscreen.patch @@ -0,0 +1,33 @@ +diff --git a/src/frontend/qt_sdl/Config.cpp b/src/frontend/qt_sdl/Config.cpp +index 156d539..67978c0 100644 +--- a/src/frontend/qt_sdl/Config.cpp ++++ b/src/frontend/qt_sdl/Config.cpp +@@ -208,6 +208,10 @@ LegacyEntry LegacyFile[] = + {"IntegerScaling", 1, "Window0.IntegerScaling", true}, + {"ScreenAspectTop",0, "Window0.ScreenAspectTop", true}, + {"ScreenAspectBot",0, "Window0.ScreenAspectBot", true}, ++ {"Screen1Layout", 0, "Window1.ScreenLayout", true}, ++ {"Screen1Enabled", 1, "Window1.Enabled", true}, ++ {"Screen1Sizing", 0, "Window1.ScreenSizing", true}, ++ + + {"ScreenFilter", 1, "Screen.Filter", false}, + {"ScreenUseGL", 1, "Screen.UseGL", false}, +diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp +index 6514266..cc1b892 100644 +--- a/src/frontend/qt_sdl/main.cpp ++++ b/src/frontend/qt_sdl/main.cpp +@@ -380,9 +380,12 @@ int main(int argc, char** argv) + if (memberSyntaxUsed) printf("Warning: use the a.zip|b.nds format at your own risk!\n"); + + win->preloadROMs(dsfile, gbafile, options->boot); +- + if (options->fullscreen) ++ QTimer::singleShot(500, [=]() { ++ emuInstances[0]->doOnAllWindows([](MainWindow* win){ + win->toggleFullscreen(); ++ }); ++ }); + } + + int ret = melon.exec(); diff --git a/projects/ArchR/packages/emulators/standalone/melonds-sa/patches/003-hotkey-savestates.patch b/projects/ArchR/packages/emulators/standalone/melonds-sa/patches/003-hotkey-savestates.patch new file mode 100644 index 0000000000..4bf7c16721 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/melonds-sa/patches/003-hotkey-savestates.patch @@ -0,0 +1,106 @@ +diff -rupbN melonDS.orig/src/frontend/qt_sdl/Config.cpp melonDS/src/frontend/qt_sdl/Config.cpp +--- melonDS.orig/src/frontend/qt_sdl/Config.cpp 2026-02-20 05:47:47.879009667 +0000 ++++ melonDS/src/frontend/qt_sdl/Config.cpp 2026-02-20 05:53:32.362245865 +0000 +@@ -186,6 +186,8 @@ LegacyEntry LegacyFile[] = + {"HKKey_GuitarGripRed", 0, "Keyboard.HK_GuitarGripRed", true}, + {"HKKey_GuitarGripYellow", 0, "Keyboard.HK_GuitarGripYellow", true}, + {"HKKey_GuitarGripBlue", 0, "Keyboard.HK_GuitarGripBlue", true}, ++ {"HKKey_SaveState", 0, "Keyboard.HK_SaveState", true}, ++ {"HKKey_LoadState", 0, "Keyboard.HK_LoadState", true}, + + {"HKJoy_Lid", 0, "Joystick.HK_Lid", true}, + {"HKJoy_Mic", 0, "Joystick.HK_Mic", true}, +@@ -209,6 +211,8 @@ LegacyEntry LegacyFile[] = + {"HKJoy_GuitarGripRed", 0, "Joystick.HK_GuitarGripRed", true}, + {"HKJoy_GuitarGripYellow", 0, "Joystick.HK_GuitarGripYellow", true}, + {"HKJoy_GuitarGripBlue", 0, "Joystick.HK_GuitarGripBlue", true}, ++ {"HKJoy_SaveState", 0, "Joystick.HK_SaveState", true}, ++ {"HKJoy_LoadState", 0, "Joystick.HK_LoadState", true}, + + {"JoystickID", 0, "JoystickID", true}, + +diff -rupbN melonDS.orig/src/frontend/qt_sdl/EmuInstance.h melonDS/src/frontend/qt_sdl/EmuInstance.h +--- melonDS.orig/src/frontend/qt_sdl/EmuInstance.h 2026-02-20 05:47:47.879009667 +0000 ++++ melonDS/src/frontend/qt_sdl/EmuInstance.h 2026-02-20 05:57:07.948569265 +0000 +@@ -63,6 +63,8 @@ enum + #ifdef RETROACHIEVEMENTS_ENABLED + HK_RAOverlayToggle, + #endif ++ HK_SaveState, ++ HK_LoadState, + HK_MAX + }; + +diff -rupbN melonDS.orig/src/frontend/qt_sdl/EmuInstanceInput.cpp melonDS/src/frontend/qt_sdl/EmuInstanceInput.cpp +--- melonDS.orig/src/frontend/qt_sdl/EmuInstanceInput.cpp 2026-02-20 05:47:47.879009667 +0000 ++++ melonDS/src/frontend/qt_sdl/EmuInstanceInput.cpp 2026-02-20 05:53:32.362245865 +0000 +@@ -70,7 +70,9 @@ const char* EmuInstance::hotkeyNames[HK_ + "HK_GuitarGripGreen", + "HK_GuitarGripRed", + "HK_GuitarGripYellow", +- "HK_GuitarGripBlue" ++ "HK_GuitarGripBlue", ++ "HK_SaveState", ++ "HK_LoadState" + }; + + std::shared_ptr EmuInstance::joyMutexGlobal = nullptr; +diff -rupbN melonDS.orig/src/frontend/qt_sdl/EmuThread.cpp melonDS/src/frontend/qt_sdl/EmuThread.cpp +--- melonDS.orig/src/frontend/qt_sdl/EmuThread.cpp 2026-02-20 05:47:47.879009667 +0000 ++++ melonDS/src/frontend/qt_sdl/EmuThread.cpp 2026-02-20 05:55:13.083310458 +0000 +@@ -84,6 +84,8 @@ void EmuThread::attachWindow(MainWindow* + connect(this, SIGNAL(RAOverlayToggle()), window, SLOT(onRAOverlayToggled())); + #endif + connect(this, SIGNAL(screenEmphasisToggle()), window, SLOT(onScreenEmphasisToggled())); ++ connect(this, SIGNAL(SaveState()), window->actSaveState[1], SLOT(trigger())); ++ connect(this, SIGNAL(LoadState()), window->actLoadState[1], SLOT(trigger())); + + if (window->winHasMenu()) + { +@@ -180,6 +182,8 @@ void EmuThread::run() + #endif + if (emuInstance->hotkeyPressed(HK_SwapScreens)) emit swapScreensToggle(); + if (emuInstance->hotkeyPressed(HK_SwapScreenEmphasis)) emit screenEmphasisToggle(); ++ if (emuInstance->hotkeyPressed(HK_SaveState)) emit SaveState(); ++ if (emuInstance->hotkeyPressed(HK_LoadState)) emit LoadState(); + + if (emuStatus == emuStatus_Running || emuStatus == emuStatus_FrameStep) + { +diff -rupbN melonDS.orig/src/frontend/qt_sdl/EmuThread.h melonDS/src/frontend/qt_sdl/EmuThread.h +--- melonDS.orig/src/frontend/qt_sdl/EmuThread.h 2026-02-20 05:47:47.879009667 +0000 ++++ melonDS/src/frontend/qt_sdl/EmuThread.h 2026-02-20 05:53:32.362245865 +0000 +@@ -161,6 +161,9 @@ signals: + void swapScreensToggle(); + void screenEmphasisToggle(); + ++ void SaveState(); ++ void LoadState(); ++ + void syncVolumeLevel(); + + private: +diff -rupbN melonDS.orig/src/frontend/qt_sdl/InputConfig/InputConfigDialog.h melonDS/src/frontend/qt_sdl/InputConfig/InputConfigDialog.h +--- melonDS.orig/src/frontend/qt_sdl/InputConfig/InputConfigDialog.h 2026-02-20 05:47:47.879009667 +0000 ++++ melonDS/src/frontend/qt_sdl/InputConfig/InputConfigDialog.h 2026-02-20 05:56:25.112094849 +0000 +@@ -71,7 +71,9 @@ static constexpr std::initializer_list hk_general_labels = +@@ -95,7 +97,9 @@ static constexpr std::initializer_list "${LOG_FILE}" + +log() { + printf '%s - %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >> "${LOG_FILE}" +} + +# Extract username, password, token, if enabled, and hardcore mode from system.cfg +username=$(get_setting "global.retroachievements.username") +password=$(get_setting "global.retroachievements.password") +token=$(get_setting "global.retroachievements.token") +enabled=$(get_setting "global.retroachievements") +hardcore=$(get_setting "global.retroachievements.hardcore") +encore=$(get_setting "global.retroachievements.encore") +unofficial=$(get_setting "global.retroachievements.testunofficial") + +# Check if RetroAchievements are enabled in Emulation Station +if [ "${enabled}" = 1 ]; then + enabled="1" +else + log "RetroAchievements are not enabled, please turn them on in Emulation Station." + enabled="0" +fi + +# Check if username is present in system.cfg +if [ -z "${username}" ]; then + log "RetroAchievements username is empty, please log in with your RetroAchievements credentials in Emulation Station." + enabled="0" + username="null" +fi + +# Check if password is present in system.cfg +if [ -z "${password}" ]; then + log "RetroAchievements password is empty, please log in with your RetroAchievements credentials in Emulation Station." + enabled="0" + password="null" +fi + +# Check if api token is present in system.cfg +if [ -z "${token}" ]; then + log "RetroAchievements token is empty, please log in with your RetroAchievements credentials in Emulation Station." + enabled="0" + token="null" +fi + +# Set hardcore mode +if [ "${hardcore}" = 1 ]; then + hardcore="1" +else + hardcore="0" +fi + +# Set encore mode +if [ "${encore}" = 1 ]; then + encore="1" +else + encore="0" +fi + +# Set unofficial mode +if [ "${unofficial}" = 1 ]; then + unofficial="1" +else + unofficial="0" +fi + +# Clean up any special characters +escape_sed() { + printf '%s\n' "$1" | sed 's/[\/&]/\\&/g' +} + +username_esc=$(escape_sed "${username}") +password_esc=$(escape_sed "${password}") +token_esc=$(escape_sed "${token}") + +# Update emulator config with RetroAchievements settings +set_key() { + key="$1" + value="$2" + + if grep -q "^[[:space:]]*${key}[[:space:]]*=" "${MELONDS_CFG}"; then + sed -i "s|^[[:space:]]*${key}[[:space:]]*=.*|${key}=${value}|g" "${MELONDS_CFG}" + else + printf '%s=%s\n' "${key}" "${value}" >> "${MELONDS_CFG}" + fi +} + +set_key RA_Enabled "${enabled}" +set_key RA_Username "${username_esc}" +set_key RA_Password "${password_esc}" +set_key RA_Token "${token_esc}" +set_key RA_HardcoreMode "${hardcore}" +set_key RA_EncoreMode "${encore}" +set_key RA_Unofficial "${unofficial}" diff --git a/projects/ArchR/packages/emulators/standalone/melonds-sa/scripts/start_melonds.sh b/projects/ArchR/packages/emulators/standalone/melonds-sa/scripts/start_melonds.sh new file mode 100644 index 0000000000..ae083161d9 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/melonds-sa/scripts/start_melonds.sh @@ -0,0 +1,190 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +set_kill set "-9 melonDS" + +#load gptokeyb support files +control-gen_init.sh +source /storage/.config/gptokeyb/control.ini +get_controls + +CONF_DIR="/storage/.config/melonDS" +MELONDS_INI="melonDS.ini" +SWAY_CONFIG="/storage/.config/sway/config" + +if [ ! -d "${CONF_DIR}" ]; then + cp -r "/usr/config/melonDS" "/storage/.config/" +fi + +if [ ! -d "/storage/roms/savestates/nds" ]; then + mkdir -p "/storage/roms/savestates/nds" +fi + +#Make sure melonDS gptk config exists +if [ ! -f "${CONF_DIR}/melonDS.gptk" ]; then + cp -r "/usr/config/melonDS/melonDS.gptk" "${CONF_DIR}/melonDS.gptk" +fi + +#Make sure melonDS config exists +if [ ! -f "${CONF_DIR}/${MELONDS_INI}" ]; then + cp -r "/usr/config/melonDS/melonDS.ini" "${CONF_DIR}/${MELONDS_INI}" +fi + +#Emulation Station Features +GAME=$(echo "${1}" | sed "s#^/.*/##") +PLATFORM=$(echo "${2}"| sed "s#^/.*/##") +CONTYPE=$(get_setting console_type "${PLATFORM}" "${GAME}") +DBOOT=$(get_setting direct_boot "${PLATFORM}" "${GAME}") +GRENDERER=$(get_setting graphics_backend "${PLATFORM}" "${GAME}") +IRES=$(get_setting internal_resolution "${PLATFORM}" "${GAME}") +SORIENTATION=$(get_setting screen_orientation "${PLATFORM}" "${GAME}") +SLAYOUT=$(get_setting screen_layout "${PLATFORM}" "${GAME}") +SWAP=$(get_setting screen_swap "${PLATFORM}" "${GAME}") +SROTATION=$(get_setting screen_rotation "${PLATFORM}" "${GAME}") +VSYNC=$(get_setting vsync "${PLATFORM}" "${GAME}") + +#Set the cores to use +CORES=$(get_setting "cores" "${PLATFORM}" "${GAME}") +unset EMUPERF +[ "${CORES}" = "little" ] && EMUPERF="${SLOW_CORES}" +[ "${CORES}" = "big" ] && EMUPERF="${FAST_CORES}" + +#Console Type +if [ "$PLATFORM" = "ndsiware" ]; then + sed -i '/^ConsoleType=/c\ConsoleType=1' /storage/.config/melonDS/melonDS.ini +else + if [ "$CONTYPE" = "1" ]; then + sed -i '/^ConsoleType=/c\ConsoleType=1' /storage/.config/melonDS/melonDS.ini + else + sed -i '/^ConsoleType=/c\ConsoleType=0' /storage/.config/melonDS/melonDS.ini + fi +fi + +#Direct Boot +if [ "$PLATFORM" = "ndsiware" ]; then + sed -i '/^DirectBoot=/c\DirectBoot=0' /storage/.config/melonDS/melonDS.ini +else + if [ "$DBOOT" = "0" ]; then + sed -i '/^DirectBoot=/c\DirectBoot=0' /storage/.config/melonDS/melonDS.ini + sed -i '/^ExternalBIOSEnable=/c\ExternalBIOSEnable=1' /storage/.config/melonDS/melonDS.ini + else + sed -i '/^DirectBoot=/c\DirectBoot=1' /storage/.config/melonDS/melonDS.ini + sed -i '/^ExternalBIOSEnable=/c\ExternalBIOSEnable=0' /storage/.config/melonDS/melonDS.ini + fi +fi + +#Graphics Backend +case "$GRENDERER" in + "1"|"2") + sed -i "/^ScreenUseGL=/c\ScreenUseGL=1" "${CONF_DIR}/${MELONDS_INI}" + sed -i "/^3DRenderer=/c\3DRenderer=$GRENDERER" "${CONF_DIR}/${MELONDS_INI}" + ;; + *) + sed -i '/^ScreenUseGL=/c\ScreenUseGL=0' "${CONF_DIR}/${MELONDS_INI}" + sed -i '/^3DRenderer=/c\3DRenderer=0' "${CONF_DIR}/${MELONDS_INI}" + ;; +esac + +#Internal Resolution +if [ "$IRES" > "0" ]; then + sed -i "/^GL_ScaleFactor=/c\GL_ScaleFactor=$IRES" "${CONF_DIR}/${MELONDS_INI}" +else + sed -i '/^GL_ScaleFactor=/c\GL_ScaleFactor=1' "${CONF_DIR}/${MELONDS_INI}" +fi + +#Screen Orientation +if [ "$SORIENTATION" > "0" ]; then + sed -i "/^ScreenLayout=/c\ScreenLayout=$SORIENTATION" "${CONF_DIR}/${MELONDS_INI}" +else + sed -i '/^ScreenLayout=/c\ScreenLayout=2' "${CONF_DIR}/${MELONDS_INI}" +fi + +#Screen Layout +# Screen Layout +sed -i '/^Screen1Enabled=/c\Screen1Enabled=0' "${CONF_DIR}/${MELONDS_INI}" + +enable_second_screen() { + sed -i '/^ScreenSizing=/c\ScreenSizing=4' "${CONF_DIR}/${MELONDS_INI}" + sed -i '/^Screen1Enabled=/d$ a Screen1Enabled=1' "${CONF_DIR}/${MELONDS_INI}" + sed -i '/^Screen1Layout=/d$ a Screen1Layout=2' "${CONF_DIR}/${MELONDS_INI}" +} + +if [ "$SLAYOUT" = "6" ]; then + enable_second_screen +elif [ -n "$SLAYOUT" ] && [ "$SLAYOUT" != "0" ]; then + sed -i "/^ScreenSizing=/c\ScreenSizing=$SLAYOUT" "${CONF_DIR}/${MELONDS_INI}" +elif [ "${DEVICE_HAS_DUAL_SCREEN}" = "true" ]; then + enable_second_screen +else + sed -i '/^ScreenSizing=/c\ScreenSizing=0' "${CONF_DIR}/${MELONDS_INI}" +fi + +# Screen Swap +if [[ "${DEVICE_HAS_DUAL_SCREEN}" = "true" && ( -z "$SLAYOUT" || "$SLAYOUT" = "6" ) ]]; then + if [ "$SWAP" = "1" ]; then + sed -i '/^ScreenSizing=/c\ScreenSizing=5' "${CONF_DIR}/${MELONDS_INI}" + sed -i '/^Screen1Sizing=/d$ a Screen1Sizing=4' "${CONF_DIR}/${MELONDS_INI}" + else + sed -i '/^ScreenSizing=/c\ScreenSizing=4' "${CONF_DIR}/${MELONDS_INI}" + sed -i '/^Screen1Sizing=/d$ a Screen1Sizing=5' "${CONF_DIR}/${MELONDS_INI}" + fi +else + sed -i "/^ScreenSwap=/c\ScreenSwap=${SWAP:-0}" "${CONF_DIR}/${MELONDS_INI}" +fi + +#Screen Rotation +if [ "$SROTATION" ] >"0"; then + sed -i "/^ScreenRotation=/c\ScreenRotation=$SROTATION" "${CONF_DIR}/${MELONDS_INI}" +else + sed -i '/^ScreenRotation=/c\ScreenRotation=0' "${CONF_DIR}/${MELONDS_INI}" +fi + +#Vsync +if [ "$VSYNC" = "1" ]; then + sed -i '/^ScreenVSync=/c\ScreenVSync=1' "${CONF_DIR}/${MELONDS_INI}" +else + sed -i '/^ScreenVSync=/c\ScreenVSync=1' "${CONF_DIR}/${MELONDS_INI}" +fi + +# Extract archive to /tmp/melonds +TEMP="/tmp/melonds" +rm -rf "${TEMP}" +mkdir -p "${TEMP}" +if [[ "${1}" == *.zip ]]; then + unzip -o "${1}" -d "${TEMP}" + ROM=$(find "${TEMP}" -maxdepth 1 -type f -name "*.nds" | head -n 1) +elif [[ "${1}" == *.7z ]]; then + 7z x -y -o"${TEMP}" "${1}" + ROM=$(find "${TEMP}" -maxdepth 1 -type f -name "*.nds" | head -n 1) +else + ROM="${1}" +fi + +# QT platform - default to xcb +export QT_QPA_PLATFORM=xcb + +# QT platform - some device / driver combinations need wayland +case ${HW_DEVICE} in + RK3566|RK3588|S922X) + [[ $(/usr/bin/gpudriver) == "libmali" ]] && export QT_QPA_PLATFORM=wayland + ;; +esac + +@PANFROST@ +@HOTKEY@ +@LIBMALI@ + +#Generate a new MelonDS.toml each run (temporary hack) +rm -rf "${CONF_DIR}/melonDS.toml" + +#Retroachievements +/usr/bin/cheevos_melonds.sh + +#Run MelonDS emulator +$GPTOKEYB "melonDS" -c "${CONF_DIR}/melonDS.gptk" & +${EMUPERF} /usr/bin/melonDS -f "${ROM}" +kill -9 "$(pidof gptokeyb)" diff --git a/projects/ArchR/packages/emulators/standalone/minivmacsa/package.mk b/projects/ArchR/packages/emulators/standalone/minivmacsa/package.mk new file mode 100644 index 0000000000..d0100d2751 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/minivmacsa/package.mk @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="minivmacsa" +PKG_VERSION="37.03" +PKG_LICENSE="GPLv2" +PKG_SITE="https://www.gryphel.com/c/minivmac/" +PKG_URL="https://www.gryphel.com/d/minivmac/minivmac-${PKG_VERSION}/minivmac-${PKG_VERSION}.src.tgz" +PKG_DEPENDS_TARGET="toolchain libX11" +PKG_LONGDESC="Virtual Macintosh Plus" +PKG_TOOLCHAIN="make" + +pre_make_target() { + cd ${PKG_BUILD} + ${TOOLCHAIN}/bin/host-gcc setup/tool.c -o setup_t + ./setup_t -t lx64 -fullscreen 1 > setup.sh + . setup.sh + sed -i "s|gcc|${TARGET_PREFIX}gcc|" ${PKG_BUILD}/Makefile +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp ${PKG_BUILD}/minivmac ${INSTALL}/usr/bin + chmod 0755 ${INSTALL}/usr/bin/* +} diff --git a/projects/ArchR/packages/emulators/standalone/minivmacsa/sources/start_minivmac.sh b/projects/ArchR/packages/emulators/standalone/minivmacsa/sources/start_minivmac.sh new file mode 100644 index 0000000000..7279cb1977 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/minivmacsa/sources/start_minivmac.sh @@ -0,0 +1,9 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +ARG=${1//[\\]/} +echo "[${ARG}]" +minivmac diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-audio-sdl/package.mk b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-audio-sdl/package.mk new file mode 100644 index 0000000000..cbe61652b0 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-audio-sdl/package.mk @@ -0,0 +1,77 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2019-present Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2023 Nicholas Ricciuti (rishooty@gmail.com) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="mupen64plus-sa-audio-sdl" +PKG_VERSION="cec70e42b4535ce5bd1be24e7d816c54b3e75673" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/mupen64plus/mupen64plus-audio-sdl" +PKG_URL="https://github.com/mupen64plus/mupen64plus-audio-sdl/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain libpng SDL2 SDL2_net zlib freetype nasm:host mupen64plus-sa-core" +PKG_LONGDESC="mupen64plus-audio-sdl" +PKG_LONGDESC="Mupen64Plus Standalone Audio SDL" +PKG_TOOLCHAIN="manual" + +case ${DEVICE} in + RK3588|S922X|RK3399|RK3566*|SM8250|SM8550|SM8650) + PKG_DEPENDS_TARGET+=" mupen64plus-sa-simplecore" + ;; +esac + +case ${OPENGL} in + no) + PKG_DEPENDS_TARGET+=" ${OPENGLES}" + export USE_GLES=1 + ;; + *) + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" + export USE_GLES=0 + ;; +esac + +make_target() { + + export HOST_CPU=${TARGET_ARCH} \ + NEW_DYNAREC=1 \ + VFP_HARD=1 \ + V=1 \ + VC=0 \ + OSD=0 + + export BINUTILS="$(get_build_dir binutils)/.${TARGET_NAME}" + export SDL_CFLAGS="-I${SYSROOT_PREFIX}/usr/include/SDL2 -pthread -D_REENTRANT" + export SDL_LDLIBS="-lSDL2_net -lSDL2" + export CROSS_COMPILE="${TARGET_PREFIX}" + + export APIDIR=$(get_build_dir mupen64plus-sa-core)/src/api + + sed -i 's/\-O[23]/-Ofast/' ${PKG_BUILD}/projects/unix/Makefile + + make -C projects/unix clean + make -C projects/unix all ${PKG_MAKE_OPTS_TARGET} + cp ${PKG_BUILD}/projects/unix/mupen64plus-audio-sdl.so ${PKG_BUILD}/projects/unix/mupen64plus-audio-sdl-base.so + + case ${DEVICE} in + RK3588|S922X|RK3399|RK3566*) + export APIDIR=$(get_build_dir mupen64plus-sa-simplecore)/src/api + make -C projects/unix all ${PKG_MAKE_OPTS_TARGET} + cp ${PKG_BUILD}/projects/unix/mupen64plus-audio-sdl.so ${PKG_BUILD}/projects/unix/mupen64plus-audio-sdl-simple.so + ;; + esac +} + +makeinstall_target() { + UPREFIX=${INSTALL}/usr/local + ULIBDIR=${UPREFIX}/lib + UPLUGINDIR=${ULIBDIR}/mupen64plus + mkdir -p ${UPLUGINDIR} + cp ${PKG_BUILD}/projects/unix/mupen64plus-audio-sdl-base.so ${UPLUGINDIR}/mupen64plus-audio-sdl.so + chmod 0644 ${UPLUGINDIR}/mupen64plus-audio-sdl.so + if [ -e "${PKG_BUILD}/projects/unix/mupen64plus-audio-sdl-simple.so" ] + then + cp ${PKG_BUILD}/projects/unix/mupen64plus-audio-sdl-simple.so ${UPLUGINDIR} + chmod 0644 ${UPLUGINDIR}/mupen64plus-audio-sdl-simple.so + fi +} + diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/H700/mupen64plus.cfg b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/H700/mupen64plus.cfg new file mode 100644 index 0000000000..26abb8e457 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/H700/mupen64plus.cfg @@ -0,0 +1,667 @@ +# Mupen64Plus Configuration File +# This file is automatically read and written by the Mupen64Plus Core library + +[64DD] + +# Filename of the 64DD IPL ROM +IPL-ROM = "" +# Filename of the disk to load into Disk Drive +Disk = "" + + +[Audio-SDL] + +# Mupen64Plus SDL Audio Plugin config parameter version number +Version = 1.000000 +# Frequency which is used if rom doesn't want to change it +DEFAULT_FREQUENCY = 33600 +# Swaps left and right channels +SWAP_CHANNELS = False +# Size of primary buffer in output samples. This is where audio is loaded after it's extracted from n64's memory. +PRIMARY_BUFFER_SIZE = 16384 +# Fullness level target for Primary audio buffer, in equivalent output samples. This value must be larger than the SECONDARY_BUFFER_SIZE. Decreasing this value will reduce audio latency but requires a faster PC to avoid choppiness. Increasing this will increase audio latency but reduce the chance of drop-outs. +PRIMARY_BUFFER_TARGET = 2048 +# Size of secondary buffer in output samples. This is SDL's hardware buffer. The SDL documentation states that this should be a power of two between 512 and 8192. +SECONDARY_BUFFER_SIZE = 1024 +# Audio resampling algorithm. src-sinc-best-quality, src-sinc-medium-quality, src-sinc-fastest, src-zero-order-hold, src-linear, speex-fixed-{10-0}, trivial +RESAMPLE = "trivial" +# Volume control type: 1 = SDL (only affects Mupen64Plus output) 2 = OSS mixer (adjusts master PC volume) +VOLUME_CONTROL_TYPE = 1 +# Percentage change each time the volume is increased or decreased +VOLUME_ADJUST = 5 +# Default volume when a game is started. Only used if VOLUME_CONTROL_TYPE is 1 +VOLUME_DEFAULT = 100 +# Synchronize Video/Audio +AUDIO_SYNC = False + + +[Core] + +# Mupen64Plus Core config parameter set version number. Please don't change this version number. +Version = 1.010000 +# Draw on-screen display if True, otherwise don't draw OSD +OnScreenDisplay = True +# Use Pure Interpreter if 0, Cached Interpreter if 1, or Dynamic Recompiler if 2 or more +R4300Emulator = 2 +# Disable compiled jump commands in dynamic recompiler (should be set to False) +NoCompiledJump = False +# Disable 4MB expansion RAM pack. May be necessary for some games +DisableExtraMem = False +# Increment the save state slot after each save operation +AutoStateSlotIncrement = False +# Activate the R4300 debugger when ROM execution begins, if core was built with Debugger support +EnableDebugger = False +# Save state slot (0-9) to use when saving/loading the emulator state +CurrentStateSlot = 0 +# Path to directory where screenshots are saved. If this is blank, the default value of ${UserDataPath}/screenshot will be used +ScreenshotPath = "/storage/roms/screenshots" +# Path to directory where emulator save states (snapshots) are saved. If this is blank, the default value of ${UserDataPath}/save will be used +SaveStatePath = "/storage/roms/n64" +# Path to directory where SRAM/EEPROM data (in-game saves) are stored. If this is blank, the default value of ${UserDataPath}/save will be used +SaveSRAMPath = "/storage/roms/n64" +# Path to a directory to search when looking for shared data files +SharedDataPath = "/storage/.config/game/configs/mupen64plussa" +# Force number of cycles per emulated instruction +CountPerOp = 0 +# Randomize PI/SI Interrupt Timing +RandomizeInterrupt = True +# Duration of SI DMA (-1: use per game settings) +SiDmaDuration = -1 +# Gameboy Camera Video Capture backend +GbCameraVideoCaptureBackend1 = "" +# Disk Save Format (0: Full Disk Copy (*.ndr/*.d6r), 1: RAM Area Only (*.ram)) +SaveDiskFormat = 1 + + +[CoreEvents] + +# Mupen64Plus CoreEvents config parameter set version number. Please don't change this version number. +Version = 1.000000 +# SDL keysym for stopping the emulator +Kbd Mapping Stop = 27 +# SDL keysym for switching between fullscreen/windowed modes +Kbd Mapping Fullscreen = 0 +# SDL keysym for saving the emulator state +Kbd Mapping Save State = 286 +# SDL keysym for loading the emulator state +Kbd Mapping Load State = 288 +# SDL keysym for advancing the save state slot +Kbd Mapping Increment Slot = 0 +# SDL keysym for resetting the emulator +Kbd Mapping Reset = 290 +# SDL keysym for slowing down the emulator +Kbd Mapping Speed Down = 291 +# SDL keysym for speeding up the emulator +Kbd Mapping Speed Up = 292 +# SDL keysym for taking a screenshot +Kbd Mapping Screenshot = 293 +# SDL keysym for pausing the emulator +Kbd Mapping Pause = 112 +# SDL keysym for muting/unmuting the sound +Kbd Mapping Mute = 109 +# SDL keysym for increasing the volume +Kbd Mapping Increase Volume = 93 +# SDL keysym for decreasing the volume +Kbd Mapping Decrease Volume = 91 +# SDL keysym for temporarily going really fast +Kbd Mapping Fast Forward = 102 +# SDL keysym for advancing by one frame when paused +Kbd Mapping Frame Advance = 47 +# SDL keysym for pressing the game shark button +Kbd Mapping Gameshark = 103 +# Joystick event string for stopping the emulator +Joy Mapping Stop = "J0B8/B9" +# Joystick event string for switching between fullscreen/windowed modes +Joy Mapping Fullscreen = "" +# Joystick event string for saving the emulator state +Joy Mapping Save State = "J0B8/B5" +# Joystick event string for loading the emulator state +Joy Mapping Load State = "J0B8/B4" +# Joystick event string for advancing the save state slot +Joy Mapping Increment Slot = "" +# Joystick event string for resetting the emulator +Joy Mapping Reset = "J0B8/B0" +# Joystick event string for slowing down the emulator +Joy Mapping Speed Down = "" +# Joystick event string for speeding up the emulator +Joy Mapping Speed Up = "" +# Joystick event string for taking a screenshot +Joy Mapping Screenshot = "J0B8/B3" +# Joystick event string for pausing the emulator +Joy Mapping Pause = "J0B12/B1" +# Joystick event string for muting/unmuting the sound +Joy Mapping Mute = "" +# Joystick event string for increasing the volume +Joy Mapping Increase Volume = "" +# Joystick event string for decreasing the volume +Joy Mapping Decrease Volume = "" +# Joystick event string for fast-forward +Joy Mapping Fast Forward = "J0B8/B7" +# Joystick event string for advancing by one frame when paused +Joy Mapping Frame Advance = "" +# Joystick event string for pressing the game shark button +Joy Mapping Gameshark = "J0B8/B2" +# SDL keysym for save slot 0 +Kbd Mapping Slot 0 = 48 +# SDL keysym for save slot 1 +Kbd Mapping Slot 1 = 49 +# SDL keysym for save slot 2 +Kbd Mapping Slot 2 = 50 +# SDL keysym for save slot 3 +Kbd Mapping Slot 3 = 51 +# SDL keysym for save slot 4 +Kbd Mapping Slot 4 = 52 +# SDL keysym for save slot 5 +Kbd Mapping Slot 5 = 53 +# SDL keysym for save slot 6 +Kbd Mapping Slot 6 = 54 +# SDL keysym for save slot 7 +Kbd Mapping Slot 7 = 55 +# SDL keysym for save slot 8 +Kbd Mapping Slot 8 = 56 +# SDL keysym for save slot 9 +Kbd Mapping Slot 9 = 57 + + +[Input-SDL-Control1] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = 0 +# SDL joystick name (or Keyboard) +name = "H700 Gamepad" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = True +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "0,0" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = button(16) +DPad L = button(15) +DPad D = button(14) +DPad U = button(13) +Start = button(9) +Z Trig = button(5) +B Button = button(3) +A Button = button(1) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(7) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + + +[Input-SDL-Control2] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control3] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control4] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Rsp-HLE] + +# Mupen64Plus RSP HLE Plugin config parameter version number +Version = 1.000000 +# Path to a RSP plugin which will be used when encountering an unknown ucode.You can disable this by letting an empty string. +RspFallback = "" +# Send display lists to the graphics plugin +DisplayListToGraphicsPlugin = True +# Send audio lists to the audio plugin +AudioListToAudioPlugin = False + + +[Transferpak] + +# Filename of the GB ROM to load into transferpak 1 +GB-rom-1 = "" +# Filename of the GB RAM to load into transferpak 1 +GB-ram-1 = "" +# Filename of the GB ROM to load into transferpak 2 +GB-rom-2 = "" +# Filename of the GB RAM to load into transferpak 2 +GB-ram-2 = "" +# Filename of the GB ROM to load into transferpak 3 +GB-rom-3 = "" +# Filename of the GB RAM to load into transferpak 3 +GB-ram-3 = "" +# Filename of the GB ROM to load into transferpak 4 +GB-rom-4 = "" +# Filename of the GB RAM to load into transferpak 4 +GB-ram-4 = "" + + +[UI-Console] + +# Mupen64Plus UI-Console config parameter set version number. Please don't change this version number. +Version = 1.000000 +# Directory in which to search for plugins +PluginDir = "/usr/local/lib/mupen64plus" +# Filename of video plugin +VideoPlugin = "mupen64plus-video-rice" +# Filename of audio plugin +AudioPlugin = "mupen64plus-audio-sdl.so" +# Filename of input plugin +InputPlugin = "mupen64plus-input-sdl.so" +# Filename of RSP plugin +RspPlugin = "mupen64plus-rsp-hle.so" + + +[Video-General] + +# Width of output window or fullscreen width +ScreenWidth = 427 +# Height of output window or fullscreen height +ScreenHeight = 320 +# Use fullscreen mode if True, or windowed mode if False +Fullscreen = True +# If true, activate the SDL_GL_SWAP_CONTROL attribute +VerticalSync = True +# Rotate screen contents: 0=0 degree, 1=90 degree, 2 = 180 degree, 3=270 degree +Rotate = 0 + +[Video-GLideN64] + +###### Hardware Compatibility ###### +# Leave enabled unless a mobile gpu doesn't support it. +EnableFragmentDepthWrite = 0 +# Hardware per pixel lighting, supposedly good for GLES3.1 devices or higher. +EnableHWLighting = 0 + +###### Enhancements ####### +# Internal render resoluton rather than output. So 2 x 240p is 480p, etc. +UseNativeResolutionFactor = 1 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Enable/Disable Fast Approximate Anti-Aliasing FXAA +FXAA = 0 +# Max level of Anisotropic Filtering, 0 for off +anisotropy = 0 +# Bilinear filtering mode (0=N64 3point, 1=standard) +# @rishooty: best to use this at 1x native res, any higher turn it off. +bilinearMode = 1 + +###### Compatibility ###### +# Make texrect coordinates continuous to avoid black lines between them. (0=Off/default, 1=Auto, 2=Force) +CorrectTexrectCoords = 1 +# Copy auxiliary buffers to RDRAM (default: 0) +EnableCopyAuxiliaryToRDRAM = 1 +# Render 2D texrects in native resolution to fix misalignment between parts of 2D image. (0=Off/default, 1=Optimized, 2=Unoptimized)") +EnableNativeResTexrects = 1 + +###### Other ###### +# Enable threaded video backend at the cost of input lag +ThreadedVideo = 1 +# Screen aspect ratio (0=stretch, 1=force 4:3, 2=force 16:9, 3=adjust) +AspectRatio = 1 +# Display On-screen FPS +ShowFPS = False + +[Video-Glide64mk2] + +# Enable full-scene anti-aliasing by setting this to a value greater than 1 +wrpAntiAliasing = 0 +# Card ID +card_id = 0 +# If true, use polygon offset values specified below +force_polygon_offset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +polygon_offset_factor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +polygon_offset_units = 0.000000 +# Vertical sync +vsync = True +# TODO:ssformat +ssformat = False +# Display performance stats (add together desired flags): 1=FPS counter, 2=VI/s counter, 4=% speed, 8=FPS transparent +show_fps = 0 +# Clock enabled +clock = False +# Clock is 24-hour +clock_24_hr = True +# Wrapper resolution +wrpResolution = 0 +# Wrapper VRAM +wrpVRAM = 0 +# Wrapper FBO +wrpFBO = True +# Wrapper Anisotropic Filtering +wrpAnisotropic = True +# Texture Enhancement: Smooth/Sharpen Filters +ghq_fltr = 0 +# Texture Compression: 0 for S3TC, 1 for FXT1 +ghq_cmpr = 0 +# Texture Enhancement: More filters +ghq_enht = 0 +# Hi-res texture pack format (0 for none, 1 for Rice) +ghq_hirs = 1 +# Compress texture cache with S3TC or FXT1 +ghq_enht_cmpr = False +# Tile textures (saves memory but could cause issues) +ghq_enht_tile = 0 +# Force 16bpp textures (saves ram but lower quality) +ghq_enht_f16bpp = False +# Compress texture cache +ghq_enht_gz = True +# Don't enhance textures for backgrounds +ghq_enht_nobg = False +# Enable S3TC and FXT1 compression +ghq_hirs_cmpr = False +# Tile hi-res textures (saves memory but could cause issues) +ghq_hirs_tile = False +# Force 16bpp hi-res textures (saves ram but lower quality) +ghq_hirs_f16bpp = False +# Compress hi-res texture cache +ghq_hirs_gz = True +# Alternative CRC calculation -- emulates Rice bug +ghq_hirs_altcrc = True +# Save tex cache to disk +ghq_cache_save = True +# Texture Cache Size (MB) +ghq_cache_size = 128 +# Use full alpha channel -- could cause issues for some tex packs +ghq_hirs_let_texartists_fly = False +# Dump textures +ghq_hirs_dump = False +# Alternate texture size method: -1=Game default, 0=disable. 1=enable +alt_tex_size = -1 +# Use first SETTILESIZE only: -1=Game default, 0=disable. 1=enable +use_sts1_only = -1 +# Use spheric mapping only: -1=Game default, 0=disable. 1=enable +force_calc_sphere = -1 +# Force positive viewport: -1=Game default, 0=disable. 1=enable +correct_viewport = -1 +# Force texrect size to integral value: -1=Game default, 0=disable. 1=enable +increase_texrect_edge = -1 +# Reduce fillrect size by 1: -1=Game default, 0=disable. 1=enable +decrease_fillrect_edge = -1 +# Enable perspective texture correction emulation: -1=Game default, 0=disable. 1=enable +texture_correction = -1 +# Set special scale for PAL games: -1=Game default, 0=disable. 1=enable +pal230 = -1 +# 3DFX Dithered alpha emulation mode: -1=Game default, >=0=dithered alpha emulation mode +stipple_mode = -1 +# 3DFX Dithered alpha pattern: -1=Game default, >=0=pattern used for dithered alpha emulation +stipple_pattern = -1 +# Check microcode each frame: -1=Game default, 0=disable. 1=enable +force_microcheck = -1 +# Force 0xb5 command to be quad, not line 3D: -1=Game default, 0=disable. 1=enable +force_quad3d = -1 +# Enable near z clipping: -1=Game default, 0=disable. 1=enable +clip_zmin = -1 +# Enable far plane clipping: -1=Game default, 0=disable. 1=enable +clip_zmax = -1 +# Use fast CRC algorithm: -1=Game default, 0=disable. 1=enable +fast_crc = -1 +# Adjust screen aspect for wide screen mode: -1=Game default, 0=disable. 1=enable +adjust_aspect = -1 +# Force strict check in Depth buffer test: -1=Game default, 0=disable. 1=enable +zmode_compare_less = -1 +# Apply alpha dither regardless of alpha_dither_mode: -1=Game default, 0=disable. 1=enable +old_style_adither = -1 +# Scale vertex z value before writing to depth buffer: -1=Game default, 0=disable. 1=enable +n64_z_scale = -1 +# Fast texrect rendering with hwfbe: -1=Game default, 0=disable. 1=enable +optimize_texrect = -1 +# Do not copy auxiliary frame buffers: -1=Game default, 0=disable. 1=enable +ignore_aux_copy = -1 +# Clear auxiliary texture frame buffers: -1=Game default, 0=disable. 1=enable +hires_buf_clear = -1 +# Read alpha from framebuffer: -1=Game default, 0=disable. 1=enable +fb_read_alpha = -1 +# Handle unchanged fb: -1=Game default, 0=disable. 1=enable +useless_is_useless = -1 +# Set frambuffer CRC mode: -1=Game default, 0=disable CRC, 1=fast CRC, 2=safe CRC +fb_crc_mode = -1 +# Filtering mode: -1=Game default, 0=automatic, 1=force bilinear, 2=force point sampled +filtering = -1 +# Fog: -1=Game default, 0=disable. 1=enable +fog = -1 +# Buffer clear on every frame: -1=Game default, 0=disable. 1=enable +buff_clear = -1 +# Buffer swapping method: -1=Game default, 0=swap buffers when vertical interrupt has occurred, 1=swap buffers when set of conditions is satisfied. Prevents flicker on some games, 2=mix of first two methods +swapmode = -1 +# Aspect ratio: -1=Game default, 0=Force 4:3, 1=Force 16:9, 2=Stretch, 3=Original +aspect = -1 +# LOD calculation: -1=Game default, 0=disable. 1=fast, 2=precise +lodmode = -1 +# Smart framebuffer: -1=Game default, 0=disable. 1=enable +fb_smart = -1 +# Hardware frame buffer emulation: -1=Game default, 0=disable. 1=enable +fb_hires = -1 +# Read framebuffer every frame (may be slow use only for effects that need it e.g. Banjo Kazooie, DK64 transitions): -1=Game default, 0=disable. 1=enable +fb_read_always = -1 +# Render N64 frame buffer as texture: -1=Game default, 0=disable, 1=mode1, 2=mode2 +read_back_to_screen = -1 +# Show images written directly by CPU: -1=Game default, 0=disable. 1=enable +detect_cpu_write = -1 +# Get frame buffer info: -1=Game default, 0=disable. 1=enable +fb_get_info = -1 +# Enable software depth render: -1=Game default, 0=disable. 1=enable +fb_render = -1 +# If true, skip up to maxframeskip frames to maintain clock schedule; if false, skip exactly maxframeskip frames +autoframeskip = False +# If autoframeskip is true, skip up to this many frames to maintain clock schedule; if autoframeskip is false, skip exactly this many frames +maxframeskip = 0 + + +[Video-Rice] + +# Hack to accomodate widescreen devices +ResolutionWidth = 480 +# Mupen64Plus Rice Video Plugin config parameter version number +Version = 1 +# Frame Buffer Emulation (0=ROM default, 1=disable) +FrameBufferSetting = 0 +# Frequency to write back the frame buffer (0=every frame, 1=every other frame, etc) +FrameBufferWriteBackControl = 0 +# Render-to-texture emulation (0=none, 1=ignore, 2=normal, 3=write back, 4=write back and reload) +RenderToTexture = 0 +# Control when the screen will be updated (0=ROM default, 1=VI origin update, 2=VI origin change, 3=CI change, 4=first CI change, 5=first primitive draw, 6=before screen clear, 7=after screen drawn) +ScreenUpdateSetting = 4 +# Force to use normal alpha blender +NormalAlphaBlender = False +# Use a faster algorithm to speed up texture loading and CRC computation +FastTextureLoading = False +# Use different texture coordinate clamping code +AccurateTextureMapping = True +# Force emulated frame buffers to be in N64 native resolution +InN64Resolution = False +# Try to reduce Video RAM usage (should never be used) +SaveVRAM = False +# Enable this option to have better render-to-texture quality +DoubleSizeForSmallTxtrBuf = False +# Force to use normal color combiner +DefaultCombinerDisable = False +# Enable game-specific settings from INI file +EnableHacks = True +# If enabled, graphics will be drawn in WinFrame mode instead of solid and texture mode +WinFrameMode = False +# N64 Texture Memory Full Emulation (may fix some games, may break others) +FullTMEMEmulation = False +# Enable vertex clipper for fog operations +OpenGLVertexClipper = False +# Enable/Disable SSE optimizations for capable CPUs +EnableSSE = True +# If this option is enabled, the plugin will skip every other frame +SkipFrame = False +# If enabled, texture enhancement will be done only for TxtRect ucode +TexRectOnly = False +# If enabled, texture enhancement will be done only for textures width+height<=128 +SmallTextureOnly = False +# Select hi-resolution textures based only on the CRC and ignore format+size information (Glide64 compatibility) +LoadHiResCRCOnly = True +# Enable hi-resolution texture file loading +LoadHiResTextures = False +# Enable texture dumping +DumpTexturesToFiles = False +# Display On-screen FPS +ShowFPS = False +# Use Mipmapping? 0=no, 1=nearest, 2=bilinear, 3=trilinear +Mipmapping = 2 +# Enable, Disable fog generation (0=Disable, 1=Enable) +FogMethod = 1 +# Force to use texture filtering or not (0=auto: n64 choose, 1=force no filtering, 2=force filtering) +ForceTextureFilter = 0 +# Primary texture enhancement filter (0=None, 1=2X, 2=2XSAI, 3=HQ2X, 4=LQ2X, 5=HQ4X, 6=Sharpen, 7=Sharpen More, 8=External, 9=Mirrored) +TextureEnhancement = 0 +# Secondary texture enhancement filter (0 = none, 1-4 = filtered) +TextureEnhancementControl = 0 +# Color bit depth to use for textures (0=default, 1=32 bits, 2=16 bits) +TextureQuality = 0 +# Z-buffer depth (only 16 or 32) +OpenGLDepthBufferSetting = 16 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Color bit depth for rendering window (0=32 bits, 1=16 bits) +ColorQuality = 1 +# OpenGL level to support (0=auto, 1=OGL_FRAGMENT_PROGRAM) +OpenGLRenderSetting = 0 +# Enable/Disable Anisotropic Filtering for Mipmapping (0=no filtering, 2-16=quality). This is uneffective if Mipmapping is 0. If the given value is to high to be supported by your graphic card, the value will be the highest value your graphic card can support. Better result with Trilinear filtering +AnisotropicFiltering = 0 +# If true, use polygon offset values specified below +ForcePolygonOffset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +PolygonOffsetFactor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +PolygonOffsetUnits = 0.000000 diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3326/mupen64plus.cfg b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3326/mupen64plus.cfg new file mode 100644 index 0000000000..129c254c07 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3326/mupen64plus.cfg @@ -0,0 +1,667 @@ +# Mupen64Plus Configuration File +# This file is automatically read and written by the Mupen64Plus Core library + +[64DD] + +# Filename of the 64DD IPL ROM +IPL-ROM = "" +# Filename of the disk to load into Disk Drive +Disk = "" + + +[Audio-SDL] + +# Mupen64Plus SDL Audio Plugin config parameter version number +Version = 1.000000 +# Frequency which is used if rom doesn't want to change it +DEFAULT_FREQUENCY = 33600 +# Swaps left and right channels +SWAP_CHANNELS = False +# Size of primary buffer in output samples. This is where audio is loaded after it's extracted from n64's memory. +PRIMARY_BUFFER_SIZE = 16384 +# Fullness level target for Primary audio buffer, in equivalent output samples. This value must be larger than the SECONDARY_BUFFER_SIZE. Decreasing this value will reduce audio latency but requires a faster PC to avoid choppiness. Increasing this will increase audio latency but reduce the chance of drop-outs. +PRIMARY_BUFFER_TARGET = 2048 +# Size of secondary buffer in output samples. This is SDL's hardware buffer. The SDL documentation states that this should be a power of two between 512 and 8192. +SECONDARY_BUFFER_SIZE = 1024 +# Audio resampling algorithm. src-sinc-best-quality, src-sinc-medium-quality, src-sinc-fastest, src-zero-order-hold, src-linear, speex-fixed-{10-0}, trivial +RESAMPLE = "trivial" +# Volume control type: 1 = SDL (only affects Mupen64Plus output) 2 = OSS mixer (adjusts master PC volume) +VOLUME_CONTROL_TYPE = 1 +# Percentage change each time the volume is increased or decreased +VOLUME_ADJUST = 5 +# Default volume when a game is started. Only used if VOLUME_CONTROL_TYPE is 1 +VOLUME_DEFAULT = 100 +# Synchronize Video/Audio +AUDIO_SYNC = False + + +[Core] + +# Mupen64Plus Core config parameter set version number. Please don't change this version number. +Version = 1.010000 +# Draw on-screen display if True, otherwise don't draw OSD +OnScreenDisplay = True +# Use Pure Interpreter if 0, Cached Interpreter if 1, or Dynamic Recompiler if 2 or more +R4300Emulator = 2 +# Disable compiled jump commands in dynamic recompiler (should be set to False) +NoCompiledJump = False +# Disable 4MB expansion RAM pack. May be necessary for some games +DisableExtraMem = False +# Increment the save state slot after each save operation +AutoStateSlotIncrement = False +# Activate the R4300 debugger when ROM execution begins, if core was built with Debugger support +EnableDebugger = False +# Save state slot (0-9) to use when saving/loading the emulator state +CurrentStateSlot = 0 +# Path to directory where screenshots are saved. If this is blank, the default value of ${UserDataPath}/screenshot will be used +ScreenshotPath = "/storage/roms/n64" +# Path to directory where emulator save states (snapshots) are saved. If this is blank, the default value of ${UserDataPath}/save will be used +SaveStatePath = "/storage/roms/n64" +# Path to directory where SRAM/EEPROM data (in-game saves) are stored. If this is blank, the default value of ${UserDataPath}/save will be used +SaveSRAMPath = "/storage/roms/n64" +# Path to a directory to search when looking for shared data files +SharedDataPath = "/tmp/mupen64plussa" +# Force number of cycles per emulated instruction +CountPerOp = 0 +# Randomize PI/SI Interrupt Timing +RandomizeInterrupt = True +# Duration of SI DMA (-1: use per game settings) +SiDmaDuration = -1 +# Gameboy Camera Video Capture backend +GbCameraVideoCaptureBackend1 = "" +# Disk Save Format (0: Full Disk Copy (*.ndr/*.d6r), 1: RAM Area Only (*.ram)) +SaveDiskFormat = 1 + + +[CoreEvents] + +# Mupen64Plus CoreEvents config parameter set version number. Please don't change this version number. +Version = 1.000000 +# SDL keysym for stopping the emulator +Kbd Mapping Stop = 27 +# SDL keysym for switching between fullscreen/windowed modes +Kbd Mapping Fullscreen = 0 +# SDL keysym for saving the emulator state +Kbd Mapping Save State = 286 +# SDL keysym for loading the emulator state +Kbd Mapping Load State = 288 +# SDL keysym for advancing the save state slot +Kbd Mapping Increment Slot = 0 +# SDL keysym for resetting the emulator +Kbd Mapping Reset = 290 +# SDL keysym for slowing down the emulator +Kbd Mapping Speed Down = 291 +# SDL keysym for speeding up the emulator +Kbd Mapping Speed Up = 292 +# SDL keysym for taking a screenshot +Kbd Mapping Screenshot = 293 +# SDL keysym for pausing the emulator +Kbd Mapping Pause = 112 +# SDL keysym for muting/unmuting the sound +Kbd Mapping Mute = 109 +# SDL keysym for increasing the volume +Kbd Mapping Increase Volume = 93 +# SDL keysym for decreasing the volume +Kbd Mapping Decrease Volume = 91 +# SDL keysym for temporarily going really fast +Kbd Mapping Fast Forward = 102 +# SDL keysym for advancing by one frame when paused +Kbd Mapping Frame Advance = 47 +# SDL keysym for pressing the game shark button +Kbd Mapping Gameshark = 103 +# Joystick event string for stopping the emulator +Joy Mapping Stop = "J0B7/B6" +# Joystick event string for switching between fullscreen/windowed modes +Joy Mapping Fullscreen = "" +# Joystick event string for saving the emulator state +Joy Mapping Save State = "J0B7/B5" +# Joystick event string for loading the emulator state +Joy Mapping Load State = "J0B7/B4" +# Joystick event string for advancing the save state slot +Joy Mapping Increment Slot = "" +# Joystick event string for resetting the emulator +Joy Mapping Reset = "" +# Joystick event string for slowing down the emulator +Joy Mapping Speed Down = "" +# Joystick event string for speeding up the emulator +Joy Mapping Speed Up = "" +# Joystick event string for taking a screenshot +Joy Mapping Screenshot = "" +# Joystick event string for pausing the emulator +Joy Mapping Pause = "J0B7/B0" +# Joystick event string for muting/unmuting the sound +Joy Mapping Mute = "" +# Joystick event string for increasing the volume +Joy Mapping Increase Volume = "" +# Joystick event string for decreasing the volume +Joy Mapping Decrease Volume = "" +# Joystick event string for fast-forward +Joy Mapping Fast Forward = "J0B8/B11" +# Joystick event string for advancing by one frame when paused +Joy Mapping Frame Advance = "" +# Joystick event string for pressing the game shark button +Joy Mapping Gameshark = "" +# SDL keysym for save slot 0 +Kbd Mapping Slot 0 = 48 +# SDL keysym for save slot 1 +Kbd Mapping Slot 1 = 49 +# SDL keysym for save slot 2 +Kbd Mapping Slot 2 = 50 +# SDL keysym for save slot 3 +Kbd Mapping Slot 3 = 51 +# SDL keysym for save slot 4 +Kbd Mapping Slot 4 = 52 +# SDL keysym for save slot 5 +Kbd Mapping Slot 5 = 53 +# SDL keysym for save slot 6 +Kbd Mapping Slot 6 = 54 +# SDL keysym for save slot 7 +Kbd Mapping Slot 7 = 55 +# SDL keysym for save slot 8 +Kbd Mapping Slot 8 = 56 +# SDL keysym for save slot 9 +Kbd Mapping Slot 9 = 57 + + +[Input-SDL-Control1] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = 0 +# SDL joystick name (or Keyboard) +name = "OpenSimHardware OSH PB Controller" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = True +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "0,0" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "hat(0 Right)" +DPad L = "hat(0 Left)" +DPad D = "hat(0 Down)" +DPad U = "hat(0 Up)" +Start = "button(6)" +Z Trig = "button(9)" +B Button = "button(3)" +A Button = "button(1)" +C Button R = "button(11)" +C Button L = "button(2)" +C Button D = "button(0)" +C Button U = "button(10)" +R Trig = "button(5)" +L Trig = "button(4)" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "axis(0+,0-)" +Y Axis = "axis(1+,1-)" + + +[Input-SDL-Control2] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control3] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control4] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Rsp-HLE] + +# Mupen64Plus RSP HLE Plugin config parameter version number +Version = 1.000000 +# Path to a RSP plugin which will be used when encountering an unknown ucode.You can disable this by letting an empty string. +RspFallback = "" +# Send display lists to the graphics plugin +DisplayListToGraphicsPlugin = True +# Send audio lists to the audio plugin +AudioListToAudioPlugin = False + + +[Transferpak] + +# Filename of the GB ROM to load into transferpak 1 +GB-rom-1 = "" +# Filename of the GB RAM to load into transferpak 1 +GB-ram-1 = "" +# Filename of the GB ROM to load into transferpak 2 +GB-rom-2 = "" +# Filename of the GB RAM to load into transferpak 2 +GB-ram-2 = "" +# Filename of the GB ROM to load into transferpak 3 +GB-rom-3 = "" +# Filename of the GB RAM to load into transferpak 3 +GB-ram-3 = "" +# Filename of the GB ROM to load into transferpak 4 +GB-rom-4 = "" +# Filename of the GB RAM to load into transferpak 4 +GB-ram-4 = "" + + +[UI-Console] + +# Mupen64Plus UI-Console config parameter set version number. Please don't change this version number. +Version = 1.000000 +# Directory in which to search for plugins +PluginDir = "/usr/local/lib/mupen64plus" +# Filename of video plugin +VideoPlugin = "mupen64plus-video-rice" +# Filename of audio plugin +AudioPlugin = "mupen64plus-audio-sdl.so" +# Filename of input plugin +InputPlugin = "mupen64plus-input-sdl.so" +# Filename of RSP plugin +RspPlugin = "mupen64plus-rsp-hle.so" + + +[Video-General] + +# Width of output window or fullscreen width +ScreenWidth = 427 +# Height of output window or fullscreen height +ScreenHeight = 320 +# Use fullscreen mode if True, or windowed mode if False +Fullscreen = True +# If true, activate the SDL_GL_SWAP_CONTROL attribute +VerticalSync = True +# Rotate screen contents: 0=0 degree, 1=90 degree, 2 = 180 degree, 3=270 degree +Rotate = 0 + +[Video-GLideN64] + +###### Hardware Compatibility ###### +# Leave enabled unless a mobile gpu doesn't support it. +EnableFragmentDepthWrite = 0 +# Hardware per pixel lighting, supposedly good for GLES3.1 devices or higher. +EnableHWLighting = 0 + +###### Enhancements ####### +# Internal render resoluton rather than output. So 2 x 240p is 480p, etc. +UseNativeResolutionFactor = 1 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Enable/Disable Fast Approximate Anti-Aliasing FXAA +FXAA = 0 +# Max level of Anisotropic Filtering, 0 for off +anisotropy = 0 +# Bilinear filtering mode (0=N64 3point, 1=standard) +# @rishooty: best to use this at 1x native res, any higher turn it off. +bilinearMode = 1 + +###### Compatibility ###### +# Make texrect coordinates continuous to avoid black lines between them. (0=Off/default, 1=Auto, 2=Force) +CorrectTexrectCoords = 1 +# Copy auxiliary buffers to RDRAM (default: 0) +EnableCopyAuxiliaryToRDRAM = 1 +# Render 2D texrects in native resolution to fix misalignment between parts of 2D image. (0=Off/default, 1=Optimized, 2=Unoptimized)") +EnableNativeResTexrects = 1 + +###### Other ###### +# Enable threaded video backend at the cost of input lag +ThreadedVideo = 1 +# Screen aspect ratio (0=stretch, 1=force 4:3, 2=force 16:9, 3=adjust) +AspectRatio = 1 +# Display On-screen FPS +ShowFPS = False + +[Video-Glide64mk2] + +# Enable full-scene anti-aliasing by setting this to a value greater than 1 +wrpAntiAliasing = 0 +# Card ID +card_id = 0 +# If true, use polygon offset values specified below +force_polygon_offset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +polygon_offset_factor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +polygon_offset_units = 0.000000 +# Vertical sync +vsync = True +# TODO:ssformat +ssformat = False +# Display performance stats (add together desired flags): 1=FPS counter, 2=VI/s counter, 4=% speed, 8=FPS transparent +show_fps = 0 +# Clock enabled +clock = False +# Clock is 24-hour +clock_24_hr = True +# Wrapper resolution +wrpResolution = 0 +# Wrapper VRAM +wrpVRAM = 0 +# Wrapper FBO +wrpFBO = True +# Wrapper Anisotropic Filtering +wrpAnisotropic = True +# Texture Enhancement: Smooth/Sharpen Filters +ghq_fltr = 0 +# Texture Compression: 0 for S3TC, 1 for FXT1 +ghq_cmpr = 0 +# Texture Enhancement: More filters +ghq_enht = 0 +# Hi-res texture pack format (0 for none, 1 for Rice) +ghq_hirs = 1 +# Compress texture cache with S3TC or FXT1 +ghq_enht_cmpr = False +# Tile textures (saves memory but could cause issues) +ghq_enht_tile = 0 +# Force 16bpp textures (saves ram but lower quality) +ghq_enht_f16bpp = False +# Compress texture cache +ghq_enht_gz = True +# Don't enhance textures for backgrounds +ghq_enht_nobg = False +# Enable S3TC and FXT1 compression +ghq_hirs_cmpr = False +# Tile hi-res textures (saves memory but could cause issues) +ghq_hirs_tile = False +# Force 16bpp hi-res textures (saves ram but lower quality) +ghq_hirs_f16bpp = False +# Compress hi-res texture cache +ghq_hirs_gz = True +# Alternative CRC calculation -- emulates Rice bug +ghq_hirs_altcrc = True +# Save tex cache to disk +ghq_cache_save = True +# Texture Cache Size (MB) +ghq_cache_size = 128 +# Use full alpha channel -- could cause issues for some tex packs +ghq_hirs_let_texartists_fly = False +# Dump textures +ghq_hirs_dump = False +# Alternate texture size method: -1=Game default, 0=disable. 1=enable +alt_tex_size = -1 +# Use first SETTILESIZE only: -1=Game default, 0=disable. 1=enable +use_sts1_only = -1 +# Use spheric mapping only: -1=Game default, 0=disable. 1=enable +force_calc_sphere = -1 +# Force positive viewport: -1=Game default, 0=disable. 1=enable +correct_viewport = -1 +# Force texrect size to integral value: -1=Game default, 0=disable. 1=enable +increase_texrect_edge = -1 +# Reduce fillrect size by 1: -1=Game default, 0=disable. 1=enable +decrease_fillrect_edge = -1 +# Enable perspective texture correction emulation: -1=Game default, 0=disable. 1=enable +texture_correction = -1 +# Set special scale for PAL games: -1=Game default, 0=disable. 1=enable +pal230 = -1 +# 3DFX Dithered alpha emulation mode: -1=Game default, >=0=dithered alpha emulation mode +stipple_mode = -1 +# 3DFX Dithered alpha pattern: -1=Game default, >=0=pattern used for dithered alpha emulation +stipple_pattern = -1 +# Check microcode each frame: -1=Game default, 0=disable. 1=enable +force_microcheck = -1 +# Force 0xb5 command to be quad, not line 3D: -1=Game default, 0=disable. 1=enable +force_quad3d = -1 +# Enable near z clipping: -1=Game default, 0=disable. 1=enable +clip_zmin = -1 +# Enable far plane clipping: -1=Game default, 0=disable. 1=enable +clip_zmax = -1 +# Use fast CRC algorithm: -1=Game default, 0=disable. 1=enable +fast_crc = -1 +# Adjust screen aspect for wide screen mode: -1=Game default, 0=disable. 1=enable +adjust_aspect = -1 +# Force strict check in Depth buffer test: -1=Game default, 0=disable. 1=enable +zmode_compare_less = -1 +# Apply alpha dither regardless of alpha_dither_mode: -1=Game default, 0=disable. 1=enable +old_style_adither = -1 +# Scale vertex z value before writing to depth buffer: -1=Game default, 0=disable. 1=enable +n64_z_scale = -1 +# Fast texrect rendering with hwfbe: -1=Game default, 0=disable. 1=enable +optimize_texrect = -1 +# Do not copy auxiliary frame buffers: -1=Game default, 0=disable. 1=enable +ignore_aux_copy = -1 +# Clear auxiliary texture frame buffers: -1=Game default, 0=disable. 1=enable +hires_buf_clear = -1 +# Read alpha from framebuffer: -1=Game default, 0=disable. 1=enable +fb_read_alpha = -1 +# Handle unchanged fb: -1=Game default, 0=disable. 1=enable +useless_is_useless = -1 +# Set frambuffer CRC mode: -1=Game default, 0=disable CRC, 1=fast CRC, 2=safe CRC +fb_crc_mode = -1 +# Filtering mode: -1=Game default, 0=automatic, 1=force bilinear, 2=force point sampled +filtering = -1 +# Fog: -1=Game default, 0=disable. 1=enable +fog = -1 +# Buffer clear on every frame: -1=Game default, 0=disable. 1=enable +buff_clear = -1 +# Buffer swapping method: -1=Game default, 0=swap buffers when vertical interrupt has occurred, 1=swap buffers when set of conditions is satisfied. Prevents flicker on some games, 2=mix of first two methods +swapmode = -1 +# Aspect ratio: -1=Game default, 0=Force 4:3, 1=Force 16:9, 2=Stretch, 3=Original +aspect = -1 +# LOD calculation: -1=Game default, 0=disable. 1=fast, 2=precise +lodmode = -1 +# Smart framebuffer: -1=Game default, 0=disable. 1=enable +fb_smart = -1 +# Hardware frame buffer emulation: -1=Game default, 0=disable. 1=enable +fb_hires = -1 +# Read framebuffer every frame (may be slow use only for effects that need it e.g. Banjo Kazooie, DK64 transitions): -1=Game default, 0=disable. 1=enable +fb_read_always = -1 +# Render N64 frame buffer as texture: -1=Game default, 0=disable, 1=mode1, 2=mode2 +read_back_to_screen = -1 +# Show images written directly by CPU: -1=Game default, 0=disable. 1=enable +detect_cpu_write = -1 +# Get frame buffer info: -1=Game default, 0=disable. 1=enable +fb_get_info = -1 +# Enable software depth render: -1=Game default, 0=disable. 1=enable +fb_render = -1 +# If true, skip up to maxframeskip frames to maintain clock schedule; if false, skip exactly maxframeskip frames +autoframeskip = False +# If autoframeskip is true, skip up to this many frames to maintain clock schedule; if autoframeskip is false, skip exactly this many frames +maxframeskip = 0 + + +[Video-Rice] + +# Hack to accomodate widescreen devices +ResolutionWidth = 480 +# Mupen64Plus Rice Video Plugin config parameter version number +Version = 1 +# Frame Buffer Emulation (0=ROM default, 1=disable) +FrameBufferSetting = 0 +# Frequency to write back the frame buffer (0=every frame, 1=every other frame, etc) +FrameBufferWriteBackControl = 0 +# Render-to-texture emulation (0=none, 1=ignore, 2=normal, 3=write back, 4=write back and reload) +RenderToTexture = 0 +# Control when the screen will be updated (0=ROM default, 1=VI origin update, 2=VI origin change, 3=CI change, 4=first CI change, 5=first primitive draw, 6=before screen clear, 7=after screen drawn) +ScreenUpdateSetting = 4 +# Force to use normal alpha blender +NormalAlphaBlender = False +# Use a faster algorithm to speed up texture loading and CRC computation +FastTextureLoading = False +# Use different texture coordinate clamping code +AccurateTextureMapping = True +# Force emulated frame buffers to be in N64 native resolution +InN64Resolution = False +# Try to reduce Video RAM usage (should never be used) +SaveVRAM = False +# Enable this option to have better render-to-texture quality +DoubleSizeForSmallTxtrBuf = False +# Force to use normal color combiner +DefaultCombinerDisable = False +# Enable game-specific settings from INI file +EnableHacks = True +# If enabled, graphics will be drawn in WinFrame mode instead of solid and texture mode +WinFrameMode = False +# N64 Texture Memory Full Emulation (may fix some games, may break others) +FullTMEMEmulation = False +# Enable vertex clipper for fog operations +OpenGLVertexClipper = False +# Enable/Disable SSE optimizations for capable CPUs +EnableSSE = True +# If this option is enabled, the plugin will skip every other frame +SkipFrame = False +# If enabled, texture enhancement will be done only for TxtRect ucode +TexRectOnly = False +# If enabled, texture enhancement will be done only for textures width+height<=128 +SmallTextureOnly = False +# Select hi-resolution textures based only on the CRC and ignore format+size information (Glide64 compatibility) +LoadHiResCRCOnly = True +# Enable hi-resolution texture file loading +LoadHiResTextures = False +# Enable texture dumping +DumpTexturesToFiles = False +# Display On-screen FPS +ShowFPS = False +# Use Mipmapping? 0=no, 1=nearest, 2=bilinear, 3=trilinear +Mipmapping = 2 +# Enable, Disable fog generation (0=Disable, 1=Enable) +FogMethod = 1 +# Force to use texture filtering or not (0=auto: n64 choose, 1=force no filtering, 2=force filtering) +ForceTextureFilter = 0 +# Primary texture enhancement filter (0=None, 1=2X, 2=2XSAI, 3=HQ2X, 4=LQ2X, 5=HQ4X, 6=Sharpen, 7=Sharpen More, 8=External, 9=Mirrored) +TextureEnhancement = 0 +# Secondary texture enhancement filter (0 = none, 1-4 = filtered) +TextureEnhancementControl = 0 +# Color bit depth to use for textures (0=default, 1=32 bits, 2=16 bits) +TextureQuality = 0 +# Z-buffer depth (only 16 or 32) +OpenGLDepthBufferSetting = 16 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Color bit depth for rendering window (0=32 bits, 1=16 bits) +ColorQuality = 1 +# OpenGL level to support (0=auto, 1=OGL_FRAGMENT_PROGRAM) +OpenGLRenderSetting = 0 +# Enable/Disable Anisotropic Filtering for Mipmapping (0=no filtering, 2-16=quality). This is uneffective if Mipmapping is 0. If the given value is to high to be supported by your graphic card, the value will be the highest value your graphic card can support. Better result with Trilinear filtering +AnisotropicFiltering = 0 +# If true, use polygon offset values specified below +ForcePolygonOffset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +PolygonOffsetFactor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +PolygonOffsetUnits = 0.000000 diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3326/mupen64plus.cfg.oga b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3326/mupen64plus.cfg.oga new file mode 100644 index 0000000000..95e63ce889 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3326/mupen64plus.cfg.oga @@ -0,0 +1,670 @@ +# Mupen64Plus Configuration File +# This file is automatically read and written by the Mupen64Plus Core library + +[64DD] + +# Filename of the 64DD IPL ROM +IPL-ROM = "" +# Filename of the disk to load into Disk Drive +Disk = "" + + +[Audio-SDL] + +# Mupen64Plus SDL Audio Plugin config parameter version number +Version = 1.000000 +# Frequency which is used if rom doesn't want to change it +DEFAULT_FREQUENCY = 33600 +# Swaps left and right channels +SWAP_CHANNELS = False +# Size of primary buffer in output samples. This is where audio is loaded after it's extracted from n64's memory. +PRIMARY_BUFFER_SIZE = 16384 +# Fullness level target for Primary audio buffer, in equivalent output samples. This value must be larger than the SECONDARY_BUFFER_SIZE. Decreasing this value will reduce audio latency but requires a faster PC to avoid choppiness. Increasing this will increase audio latency but reduce the chance of drop-outs. +PRIMARY_BUFFER_TARGET = 2048 +# Size of secondary buffer in output samples. This is SDL's hardware buffer. The SDL documentation states that this should be a power of two between 512 and 8192. +SECONDARY_BUFFER_SIZE = 1024 +# Audio resampling algorithm. src-sinc-best-quality, src-sinc-medium-quality, src-sinc-fastest, src-zero-order-hold, src-linear, speex-fixed-{10-0}, trivial +RESAMPLE = "trivial" +# Volume control type: 1 = SDL (only affects Mupen64Plus output) 2 = OSS mixer (adjusts master PC volume) +VOLUME_CONTROL_TYPE = 1 +# Percentage change each time the volume is increased or decreased +VOLUME_ADJUST = 5 +# Default volume when a game is started. Only used if VOLUME_CONTROL_TYPE is 1 +VOLUME_DEFAULT = 100 +# Synchronize Video/Audio +AUDIO_SYNC = False + + +[Core] + +# Mupen64Plus Core config parameter set version number. Please don't change this version number. +Version = 1.010000 +# Draw on-screen display if True, otherwise don't draw OSD +OnScreenDisplay = True +# Use Pure Interpreter if 0, Cached Interpreter if 1, or Dynamic Recompiler if 2 or more +R4300Emulator = 2 +# Disable compiled jump commands in dynamic recompiler (should be set to False) +NoCompiledJump = False +# Disable 4MB expansion RAM pack. May be necessary for some games +DisableExtraMem = False +# Increment the save state slot after each save operation +AutoStateSlotIncrement = False +# Activate the R4300 debugger when ROM execution begins, if core was built with Debugger support +EnableDebugger = False +# Save state slot (0-9) to use when saving/loading the emulator state +CurrentStateSlot = 0 +# Path to directory where screenshots are saved. If this is blank, the default value of ${UserDataPath}/screenshot will be used +ScreenshotPath = "/storage/roms/n64" +# Path to directory where emulator save states (snapshots) are saved. If this is blank, the default value of ${UserDataPath}/save will be used +SaveStatePath = "/storage/roms/n64" +# Path to directory where SRAM/EEPROM data (in-game saves) are stored. If this is blank, the default value of ${UserDataPath}/save will be used +SaveSRAMPath = "/storage/roms/n64" +# Path to a directory to search when looking for shared data files +SharedDataPath = "/tmp/mupen64plussa" +# Force number of cycles per emulated instruction +CountPerOp = 0 +# Randomize PI/SI Interrupt Timing +RandomizeInterrupt = True +# Duration of SI DMA (-1: use per game settings) +SiDmaDuration = -1 +# Gameboy Camera Video Capture backend +GbCameraVideoCaptureBackend1 = "" +# Disk Save Format (0: Full Disk Copy (*.ndr/*.d6r), 1: RAM Area Only (*.ram)) +SaveDiskFormat = 1 + + +[CoreEvents] + +# Mupen64Plus CoreEvents config parameter set version number. Please don't change this version number. +Version = 1.000000 +# SDL keysym for stopping the emulator +Kbd Mapping Stop = 27 +# SDL keysym for switching between fullscreen/windowed modes +Kbd Mapping Fullscreen = 0 +# SDL keysym for saving the emulator state +Kbd Mapping Save State = 286 +# SDL keysym for loading the emulator state +Kbd Mapping Load State = 288 +# SDL keysym for advancing the save state slot +Kbd Mapping Increment Slot = 0 +# SDL keysym for resetting the emulator +Kbd Mapping Reset = 290 +# SDL keysym for slowing down the emulator +Kbd Mapping Speed Down = 291 +# SDL keysym for speeding up the emulator +Kbd Mapping Speed Up = 292 +# SDL keysym for taking a screenshot +Kbd Mapping Screenshot = 293 +# SDL keysym for pausing the emulator +Kbd Mapping Pause = 112 +# SDL keysym for muting/unmuting the sound +Kbd Mapping Mute = 109 +# SDL keysym for increasing the volume +Kbd Mapping Increase Volume = 93 +# SDL keysym for decreasing the volume +Kbd Mapping Decrease Volume = 91 +# SDL keysym for temporarily going really fast +Kbd Mapping Fast Forward = 102 +# SDL keysym for advancing by one frame when paused +Kbd Mapping Frame Advance = 47 +# SDL keysym for pressing the game shark button +Kbd Mapping Gameshark = 103 +# Joystick event string for stopping the emulator +Joy Mapping Stop = "J0B10/B13" +# Joystick event string for switching between fullscreen/windowed modes +Joy Mapping Fullscreen = "" +# Joystick event string for saving the emulator state +Joy Mapping Save State = "J0B10/B5" +# Joystick event string for loading the emulator state +Joy Mapping Load State = "J0B10/B4" +# Joystick event string for advancing the save state slot +Joy Mapping Increment Slot = "" +# Joystick event string for resetting the emulator +Joy Mapping Reset = "" +# Joystick event string for slowing down the emulator +Joy Mapping Speed Down = "" +# Joystick event string for speeding up the emulator +Joy Mapping Speed Up = "" +# Joystick event string for taking a screenshot +Joy Mapping Screenshot = "" +# Joystick event string for pausing the emulator +Joy Mapping Pause = "J0B10/B0" +# Joystick event string for muting/unmuting the sound +Joy Mapping Mute = "" +# Joystick event string for increasing the volume +Joy Mapping Increase Volume = "" +# Joystick event string for decreasing the volume +Joy Mapping Decrease Volume = "" +# Joystick event string for fast-forward +Joy Mapping Fast Forward = "J0B10/B12" +# Joystick event string for advancing by one frame when paused +Joy Mapping Frame Advance = "" +# Joystick event string for pressing the game shark button +Joy Mapping Gameshark = "" +# SDL keysym for save slot 0 +Kbd Mapping Slot 0 = 48 +# SDL keysym for save slot 1 +Kbd Mapping Slot 1 = 49 +# SDL keysym for save slot 2 +Kbd Mapping Slot 2 = 50 +# SDL keysym for save slot 3 +Kbd Mapping Slot 3 = 51 +# SDL keysym for save slot 4 +Kbd Mapping Slot 4 = 52 +# SDL keysym for save slot 5 +Kbd Mapping Slot 5 = 53 +# SDL keysym for save slot 6 +Kbd Mapping Slot 6 = 54 +# SDL keysym for save slot 7 +Kbd Mapping Slot 7 = 55 +# SDL keysym for save slot 8 +Kbd Mapping Slot 8 = 56 +# SDL keysym for save slot 9 +Kbd Mapping Slot 9 = 57 + + +[Input-SDL-Control1] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = 0 +# SDL joystick name (or Keyboard) +name = "odroidgo2_joypad" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = True +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "0,0" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = button(9) +DPad L = button(8) +DPad D = button(7) +DPad U = button(6) +Start = button(13) +Z Trig = button(4) +B Button = button(3) +A Button = button(0) +C Button R = button(11) +C Button L = button(1) +C Button D = button(12) +C Button U = button(2) +R Trig = button(5) +L Trig = +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Input-SDL-Control2] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control3] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control4] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Rsp-HLE] + +# Mupen64Plus RSP HLE Plugin config parameter version number +Version = 1.000000 +# Path to a RSP plugin which will be used when encountering an unknown ucode.You can disable this by letting an empty string. +RspFallback = "" +# Send display lists to the graphics plugin +DisplayListToGraphicsPlugin = True +# Send audio lists to the audio plugin +AudioListToAudioPlugin = False + + +[Transferpak] + +# Filename of the GB ROM to load into transferpak 1 +GB-rom-1 = "" +# Filename of the GB RAM to load into transferpak 1 +GB-ram-1 = "" +# Filename of the GB ROM to load into transferpak 2 +GB-rom-2 = "" +# Filename of the GB RAM to load into transferpak 2 +GB-ram-2 = "" +# Filename of the GB ROM to load into transferpak 3 +GB-rom-3 = "" +# Filename of the GB RAM to load into transferpak 3 +GB-ram-3 = "" +# Filename of the GB ROM to load into transferpak 4 +GB-rom-4 = "" +# Filename of the GB RAM to load into transferpak 4 +GB-ram-4 = "" + + +[UI-Console] + +# Mupen64Plus UI-Console config parameter set version number. Please don't change this version number. +Version = 1.000000 +# Directory in which to search for plugins +PluginDir = "/usr/local/lib/mupen64plus" +# Filename of video plugin +VideoPlugin = "mupen64plus-video-rice" +# Filename of audio plugin +AudioPlugin = "mupen64plus-audio-sdl.so" +# Filename of input plugin +InputPlugin = "mupen64plus-input-sdl.so" +# Filename of RSP plugin +RspPlugin = "mupen64plus-rsp-hle.so" + + +[Video-General] + +# Width of output window or fullscreen width +ScreenWidth = 427 +# Height of output window or fullscreen height +ScreenHeight = 320 +# Use fullscreen mode if True, or windowed mode if False +Fullscreen = True +# If true, activate the SDL_GL_SWAP_CONTROL attribute +VerticalSync = True +# Rotate screen contents: 0=0 degree, 1=90 degree, 2 = 180 degree, 3=270 degree +Rotate = 0 + +[Video-GLideN64] + +###### Hardware Compatibility ###### +# Leave enabled unless a mobile gpu doesn't support it. +EnableFragmentDepthWrite = 0 +# Hardware per pixel lighting, supposedly good for GLES3.1 devices or higher. +EnableHWLighting = 0 + +###### Enhancements ####### +# Internal render resoluton rather than output. So 2 x 240p is 480p, etc. +UseNativeResolutionFactor = 1 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Enable/Disable Fast Approximate Anti-Aliasing FXAA +FXAA = 0 +# Max level of Anisotropic Filtering, 0 for off +anisotropy = 0 +# Bilinear filtering mode (0=N64 3point, 1=standard) +# @rishooty: best to use this at 1x native res, any higher turn it off. +bilinearMode = 1 + +###### Compatibility ###### +# Make texrect coordinates continuous to avoid black lines between them. (0=Off/default, 1=Auto, 2=Force) +CorrectTexrectCoords = 1 +# Copy auxiliary buffers to RDRAM (default: 0) +EnableCopyAuxiliaryToRDRAM = 1 +# Render 2D texrects in native resolution to fix misalignment between parts of 2D image. (0=Off/default, 1=Optimized, 2=Unoptimized)") +EnableNativeResTexrects = 1 + +###### Other ###### +# Enable threaded video backend at the cost of input lag +ThreadedVideo = 1 +# Screen aspect ratio (0=stretch, 1=force 4:3, 2=force 16:9, 3=adjust) +AspectRatio = 1 +# Display On-screen FPS +ShowFPS = False + +[Video-Glide64mk2] + +# Enable full-scene anti-aliasing by setting this to a value greater than 1 +wrpAntiAliasing = 0 +# Card ID +card_id = 0 +# If true, use polygon offset values specified below +force_polygon_offset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +polygon_offset_factor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +polygon_offset_units = 0.000000 +# Vertical sync +vsync = True +# TODO:ssformat +ssformat = False +# Display performance stats (add together desired flags): 1=FPS counter, 2=VI/s counter, 4=% speed, 8=FPS transparent +show_fps = 0 +# Clock enabled +clock = False +# Clock is 24-hour +clock_24_hr = True +# Wrapper resolution +wrpResolution = 0 +# Wrapper VRAM +wrpVRAM = 0 +# Wrapper FBO +wrpFBO = True +# Wrapper Anisotropic Filtering +wrpAnisotropic = True +# Texture Enhancement: Smooth/Sharpen Filters +ghq_fltr = 0 +# Texture Compression: 0 for S3TC, 1 for FXT1 +ghq_cmpr = 0 +# Texture Enhancement: More filters +ghq_enht = 0 +# Hi-res texture pack format (0 for none, 1 for Rice) +ghq_hirs = 1 +# Compress texture cache with S3TC or FXT1 +ghq_enht_cmpr = False +# Tile textures (saves memory but could cause issues) +ghq_enht_tile = 0 +# Force 16bpp textures (saves ram but lower quality) +ghq_enht_f16bpp = False +# Compress texture cache +ghq_enht_gz = True +# Don't enhance textures for backgrounds +ghq_enht_nobg = False +# Enable S3TC and FXT1 compression +ghq_hirs_cmpr = False +# Tile hi-res textures (saves memory but could cause issues) +ghq_hirs_tile = False +# Force 16bpp hi-res textures (saves ram but lower quality) +ghq_hirs_f16bpp = False +# Compress hi-res texture cache +ghq_hirs_gz = True +# Alternative CRC calculation -- emulates Rice bug +ghq_hirs_altcrc = True +# Save tex cache to disk +ghq_cache_save = True +# Texture Cache Size (MB) +ghq_cache_size = 128 +# Use full alpha channel -- could cause issues for some tex packs +ghq_hirs_let_texartists_fly = False +# Dump textures +ghq_hirs_dump = False +# Alternate texture size method: -1=Game default, 0=disable. 1=enable +alt_tex_size = -1 +# Use first SETTILESIZE only: -1=Game default, 0=disable. 1=enable +use_sts1_only = -1 +# Use spheric mapping only: -1=Game default, 0=disable. 1=enable +force_calc_sphere = -1 +# Force positive viewport: -1=Game default, 0=disable. 1=enable +correct_viewport = -1 +# Force texrect size to integral value: -1=Game default, 0=disable. 1=enable +increase_texrect_edge = -1 +# Reduce fillrect size by 1: -1=Game default, 0=disable. 1=enable +decrease_fillrect_edge = -1 +# Enable perspective texture correction emulation: -1=Game default, 0=disable. 1=enable +texture_correction = -1 +# Set special scale for PAL games: -1=Game default, 0=disable. 1=enable +pal230 = -1 +# 3DFX Dithered alpha emulation mode: -1=Game default, >=0=dithered alpha emulation mode +stipple_mode = -1 +# 3DFX Dithered alpha pattern: -1=Game default, >=0=pattern used for dithered alpha emulation +stipple_pattern = -1 +# Check microcode each frame: -1=Game default, 0=disable. 1=enable +force_microcheck = -1 +# Force 0xb5 command to be quad, not line 3D: -1=Game default, 0=disable. 1=enable +force_quad3d = -1 +# Enable near z clipping: -1=Game default, 0=disable. 1=enable +clip_zmin = -1 +# Enable far plane clipping: -1=Game default, 0=disable. 1=enable +clip_zmax = -1 +# Use fast CRC algorithm: -1=Game default, 0=disable. 1=enable +fast_crc = -1 +# Adjust screen aspect for wide screen mode: -1=Game default, 0=disable. 1=enable +adjust_aspect = -1 +# Force strict check in Depth buffer test: -1=Game default, 0=disable. 1=enable +zmode_compare_less = -1 +# Apply alpha dither regardless of alpha_dither_mode: -1=Game default, 0=disable. 1=enable +old_style_adither = -1 +# Scale vertex z value before writing to depth buffer: -1=Game default, 0=disable. 1=enable +n64_z_scale = -1 +# Fast texrect rendering with hwfbe: -1=Game default, 0=disable. 1=enable +optimize_texrect = -1 +# Do not copy auxiliary frame buffers: -1=Game default, 0=disable. 1=enable +ignore_aux_copy = -1 +# Clear auxiliary texture frame buffers: -1=Game default, 0=disable. 1=enable +hires_buf_clear = -1 +# Read alpha from framebuffer: -1=Game default, 0=disable. 1=enable +fb_read_alpha = -1 +# Handle unchanged fb: -1=Game default, 0=disable. 1=enable +useless_is_useless = -1 +# Set frambuffer CRC mode: -1=Game default, 0=disable CRC, 1=fast CRC, 2=safe CRC +fb_crc_mode = -1 +# Filtering mode: -1=Game default, 0=automatic, 1=force bilinear, 2=force point sampled +filtering = -1 +# Fog: -1=Game default, 0=disable. 1=enable +fog = -1 +# Buffer clear on every frame: -1=Game default, 0=disable. 1=enable +buff_clear = -1 +# Buffer swapping method: -1=Game default, 0=swap buffers when vertical interrupt has occurred, 1=swap buffers when set of conditions is satisfied. Prevents flicker on some games, 2=mix of first two methods +swapmode = -1 +# Aspect ratio: -1=Game default, 0=Force 4:3, 1=Force 16:9, 2=Stretch, 3=Original +aspect = -1 +# LOD calculation: -1=Game default, 0=disable. 1=fast, 2=precise +lodmode = -1 +# Smart framebuffer: -1=Game default, 0=disable. 1=enable +fb_smart = -1 +# Hardware frame buffer emulation: -1=Game default, 0=disable. 1=enable +fb_hires = -1 +# Read framebuffer every frame (may be slow use only for effects that need it e.g. Banjo Kazooie, DK64 transitions): -1=Game default, 0=disable. 1=enable +fb_read_always = -1 +# Render N64 frame buffer as texture: -1=Game default, 0=disable, 1=mode1, 2=mode2 +read_back_to_screen = -1 +# Show images written directly by CPU: -1=Game default, 0=disable. 1=enable +detect_cpu_write = -1 +# Get frame buffer info: -1=Game default, 0=disable. 1=enable +fb_get_info = -1 +# Enable software depth render: -1=Game default, 0=disable. 1=enable +fb_render = -1 +# If true, skip up to maxframeskip frames to maintain clock schedule; if false, skip exactly maxframeskip frames +autoframeskip = False +# If autoframeskip is true, skip up to this many frames to maintain clock schedule; if autoframeskip is false, skip exactly this many frames +maxframeskip = 0 + + +[Video-Rice] + +# Hack to accomodate widescreen devices +ResolutionWidth = 480 +# Mupen64Plus Rice Video Plugin config parameter version number +Version = 1 +# Frame Buffer Emulation (0=ROM default, 1=disable) +FrameBufferSetting = 0 +# Frequency to write back the frame buffer (0=every frame, 1=every other frame, etc) +FrameBufferWriteBackControl = 0 +# Render-to-texture emulation (0=none, 1=ignore, 2=normal, 3=write back, 4=write back and reload) +RenderToTexture = 0 +# Control when the screen will be updated (0=ROM default, 1=VI origin update, 2=VI origin change, 3=CI change, 4=first CI change, 5=first primitive draw, 6=before screen clear, 7=after screen drawn) +ScreenUpdateSetting = 4 +# Force to use normal alpha blender +NormalAlphaBlender = False +# Use a faster algorithm to speed up texture loading and CRC computation +FastTextureLoading = False +# Use different texture coordinate clamping code +AccurateTextureMapping = True +# Force emulated frame buffers to be in N64 native resolution +InN64Resolution = False +# Try to reduce Video RAM usage (should never be used) +SaveVRAM = False +# Enable this option to have better render-to-texture quality +DoubleSizeForSmallTxtrBuf = False +# Force to use normal color combiner +DefaultCombinerDisable = False +# Enable game-specific settings from INI file +EnableHacks = True +# If enabled, graphics will be drawn in WinFrame mode instead of solid and texture mode +WinFrameMode = False +# N64 Texture Memory Full Emulation (may fix some games, may break others) +FullTMEMEmulation = False +# Enable vertex clipper for fog operations +OpenGLVertexClipper = False +# Enable/Disable SSE optimizations for capable CPUs +EnableSSE = True +# If this option is enabled, the plugin will skip every other frame +SkipFrame = False +# If enabled, texture enhancement will be done only for TxtRect ucode +TexRectOnly = False +# If enabled, texture enhancement will be done only for textures width+height<=128 +SmallTextureOnly = False +# Select hi-resolution textures based only on the CRC and ignore format+size information (Glide64 compatibility) +LoadHiResCRCOnly = True +# Enable hi-resolution texture file loading +LoadHiResTextures = False +# Enable texture dumping +DumpTexturesToFiles = False +# Display On-screen FPS +ShowFPS = False +# Use Mipmapping? 0=no, 1=nearest, 2=bilinear, 3=trilinear +Mipmapping = 2 +# Enable, Disable fog generation (0=Disable, 1=Enable) +FogMethod = 1 +# Force to use texture filtering or not (0=auto: n64 choose, 1=force no filtering, 2=force filtering) +ForceTextureFilter = 0 +# Primary texture enhancement filter (0=None, 1=2X, 2=2XSAI, 3=HQ2X, 4=LQ2X, 5=HQ4X, 6=Sharpen, 7=Sharpen More, 8=External, 9=Mirrored) +TextureEnhancement = 0 +# Secondary texture enhancement filter (0 = none, 1-4 = filtered) +TextureEnhancementControl = 0 +# Color bit depth to use for textures (0=default, 1=32 bits, 2=16 bits) +TextureQuality = 0 +# Z-buffer depth (only 16 or 32) +OpenGLDepthBufferSetting = 16 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Color bit depth for rendering window (0=32 bits, 1=16 bits) +ColorQuality = 1 +# OpenGL level to support (0=auto, 1=OGL_FRAGMENT_PROGRAM) +OpenGLRenderSetting = 0 +# Enable/Disable Anisotropic Filtering for Mipmapping (0=no filtering, 2-16=quality). This is uneffective if Mipmapping is 0. If the given value is to high to be supported by your graphic card, the value will be the highest value your graphic card can support. Better result with Trilinear filtering +AnisotropicFiltering = 0 +# If true, use polygon offset values specified below +ForcePolygonOffset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +PolygonOffsetFactor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +PolygonOffsetUnits = 0.000000 diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3326/mupen64plus.cfg.ogabe b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3326/mupen64plus.cfg.ogabe new file mode 100644 index 0000000000..9448465756 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3326/mupen64plus.cfg.ogabe @@ -0,0 +1,670 @@ +# Mupen64Plus Configuration File +# This file is automatically read and written by the Mupen64Plus Core library + +[64DD] + +# Filename of the 64DD IPL ROM +IPL-ROM = "" +# Filename of the disk to load into Disk Drive +Disk = "" + + +[Audio-SDL] + +# Mupen64Plus SDL Audio Plugin config parameter version number +Version = 1.000000 +# Frequency which is used if rom doesn't want to change it +DEFAULT_FREQUENCY = 33600 +# Swaps left and right channels +SWAP_CHANNELS = False +# Size of primary buffer in output samples. This is where audio is loaded after it's extracted from n64's memory. +PRIMARY_BUFFER_SIZE = 16384 +# Fullness level target for Primary audio buffer, in equivalent output samples. This value must be larger than the SECONDARY_BUFFER_SIZE. Decreasing this value will reduce audio latency but requires a faster PC to avoid choppiness. Increasing this will increase audio latency but reduce the chance of drop-outs. +PRIMARY_BUFFER_TARGET = 2048 +# Size of secondary buffer in output samples. This is SDL's hardware buffer. The SDL documentation states that this should be a power of two between 512 and 8192. +SECONDARY_BUFFER_SIZE = 1024 +# Audio resampling algorithm. src-sinc-best-quality, src-sinc-medium-quality, src-sinc-fastest, src-zero-order-hold, src-linear, speex-fixed-{10-0}, trivial +RESAMPLE = "trivial" +# Volume control type: 1 = SDL (only affects Mupen64Plus output) 2 = OSS mixer (adjusts master PC volume) +VOLUME_CONTROL_TYPE = 1 +# Percentage change each time the volume is increased or decreased +VOLUME_ADJUST = 5 +# Default volume when a game is started. Only used if VOLUME_CONTROL_TYPE is 1 +VOLUME_DEFAULT = 100 +# Synchronize Video/Audio +AUDIO_SYNC = False + + +[Core] + +# Mupen64Plus Core config parameter set version number. Please don't change this version number. +Version = 1.010000 +# Draw on-screen display if True, otherwise don't draw OSD +OnScreenDisplay = True +# Use Pure Interpreter if 0, Cached Interpreter if 1, or Dynamic Recompiler if 2 or more +R4300Emulator = 2 +# Disable compiled jump commands in dynamic recompiler (should be set to False) +NoCompiledJump = False +# Disable 4MB expansion RAM pack. May be necessary for some games +DisableExtraMem = False +# Increment the save state slot after each save operation +AutoStateSlotIncrement = False +# Activate the R4300 debugger when ROM execution begins, if core was built with Debugger support +EnableDebugger = False +# Save state slot (0-9) to use when saving/loading the emulator state +CurrentStateSlot = 0 +# Path to directory where screenshots are saved. If this is blank, the default value of ${UserDataPath}/screenshot will be used +ScreenshotPath = "/storage/roms/n64" +# Path to directory where emulator save states (snapshots) are saved. If this is blank, the default value of ${UserDataPath}/save will be used +SaveStatePath = "/storage/roms/n64" +# Path to directory where SRAM/EEPROM data (in-game saves) are stored. If this is blank, the default value of ${UserDataPath}/save will be used +SaveSRAMPath = "/storage/roms/n64" +# Path to a directory to search when looking for shared data files +SharedDataPath = "/tmp/mupen64plussa" +# Force number of cycles per emulated instruction +CountPerOp = 0 +# Randomize PI/SI Interrupt Timing +RandomizeInterrupt = True +# Duration of SI DMA (-1: use per game settings) +SiDmaDuration = -1 +# Gameboy Camera Video Capture backend +GbCameraVideoCaptureBackend1 = "" +# Disk Save Format (0: Full Disk Copy (*.ndr/*.d6r), 1: RAM Area Only (*.ram)) +SaveDiskFormat = 1 + + +[CoreEvents] + +# Mupen64Plus CoreEvents config parameter set version number. Please don't change this version number. +Version = 1.000000 +# SDL keysym for stopping the emulator +Kbd Mapping Stop = 27 +# SDL keysym for switching between fullscreen/windowed modes +Kbd Mapping Fullscreen = 0 +# SDL keysym for saving the emulator state +Kbd Mapping Save State = 286 +# SDL keysym for loading the emulator state +Kbd Mapping Load State = 288 +# SDL keysym for advancing the save state slot +Kbd Mapping Increment Slot = 0 +# SDL keysym for resetting the emulator +Kbd Mapping Reset = 290 +# SDL keysym for slowing down the emulator +Kbd Mapping Speed Down = 291 +# SDL keysym for speeding up the emulator +Kbd Mapping Speed Up = 292 +# SDL keysym for taking a screenshot +Kbd Mapping Screenshot = 293 +# SDL keysym for pausing the emulator +Kbd Mapping Pause = 112 +# SDL keysym for muting/unmuting the sound +Kbd Mapping Mute = 109 +# SDL keysym for increasing the volume +Kbd Mapping Increase Volume = 93 +# SDL keysym for decreasing the volume +Kbd Mapping Decrease Volume = 91 +# SDL keysym for temporarily going really fast +Kbd Mapping Fast Forward = 102 +# SDL keysym for advancing by one frame when paused +Kbd Mapping Frame Advance = 47 +# SDL keysym for pressing the game shark button +Kbd Mapping Gameshark = 103 +# Joystick event string for stopping the emulator +Joy Mapping Stop = "J0B12/B15" +# Joystick event string for switching between fullscreen/windowed modes +Joy Mapping Fullscreen = "" +# Joystick event string for saving the emulator state +Joy Mapping Save State = "J0B12/B5" +# Joystick event string for loading the emulator state +Joy Mapping Load State = "J0B12/B4" +# Joystick event string for advancing the save state slot +Joy Mapping Increment Slot = "" +# Joystick event string for resetting the emulator +Joy Mapping Reset = "" +# Joystick event string for slowing down the emulator +Joy Mapping Speed Down = "" +# Joystick event string for speeding up the emulator +Joy Mapping Speed Up = "" +# Joystick event string for taking a screenshot +Joy Mapping Screenshot = "" +# Joystick event string for pausing the emulator +Joy Mapping Pause = "J0B12/B0" +# Joystick event string for muting/unmuting the sound +Joy Mapping Mute = "" +# Joystick event string for increasing the volume +Joy Mapping Increase Volume = "" +# Joystick event string for decreasing the volume +Joy Mapping Decrease Volume = "" +# Joystick event string for fast-forward +Joy Mapping Fast Forward = "J0B12/B14" +# Joystick event string for advancing by one frame when paused +Joy Mapping Frame Advance = "" +# Joystick event string for pressing the game shark button +Joy Mapping Gameshark = "" +# SDL keysym for save slot 0 +Kbd Mapping Slot 0 = 48 +# SDL keysym for save slot 1 +Kbd Mapping Slot 1 = 49 +# SDL keysym for save slot 2 +Kbd Mapping Slot 2 = 50 +# SDL keysym for save slot 3 +Kbd Mapping Slot 3 = 51 +# SDL keysym for save slot 4 +Kbd Mapping Slot 4 = 52 +# SDL keysym for save slot 5 +Kbd Mapping Slot 5 = 53 +# SDL keysym for save slot 6 +Kbd Mapping Slot 6 = 54 +# SDL keysym for save slot 7 +Kbd Mapping Slot 7 = 55 +# SDL keysym for save slot 8 +Kbd Mapping Slot 8 = 56 +# SDL keysym for save slot 9 +Kbd Mapping Slot 9 = 57 + + +[Input-SDL-Control1] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = 0 +# SDL joystick name (or Keyboard) +name = "odroidgo2_v11_joypad" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = True +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "0,0" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = button(15) +DPad L = button(14) +DPad D = button(13) +DPad U = button(12) +Start = button(8) +Z Trig = button(4) +B Button = button(3) +A Button = button(0) +C Button R = button(9) +C Button L = button(11) +C Button D = button(1) +C Button U = button(2) +R Trig = button(5) +L Trig = button(6) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = axis(1+,1-) +Y Axis = axis(0+,0-) + +[Input-SDL-Control2] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control3] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control4] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Rsp-HLE] + +# Mupen64Plus RSP HLE Plugin config parameter version number +Version = 1.000000 +# Path to a RSP plugin which will be used when encountering an unknown ucode.You can disable this by letting an empty string. +RspFallback = "" +# Send display lists to the graphics plugin +DisplayListToGraphicsPlugin = True +# Send audio lists to the audio plugin +AudioListToAudioPlugin = False + + +[Transferpak] + +# Filename of the GB ROM to load into transferpak 1 +GB-rom-1 = "" +# Filename of the GB RAM to load into transferpak 1 +GB-ram-1 = "" +# Filename of the GB ROM to load into transferpak 2 +GB-rom-2 = "" +# Filename of the GB RAM to load into transferpak 2 +GB-ram-2 = "" +# Filename of the GB ROM to load into transferpak 3 +GB-rom-3 = "" +# Filename of the GB RAM to load into transferpak 3 +GB-ram-3 = "" +# Filename of the GB ROM to load into transferpak 4 +GB-rom-4 = "" +# Filename of the GB RAM to load into transferpak 4 +GB-ram-4 = "" + + +[UI-Console] + +# Mupen64Plus UI-Console config parameter set version number. Please don't change this version number. +Version = 1.000000 +# Directory in which to search for plugins +PluginDir = "/usr/local/lib/mupen64plus" +# Filename of video plugin +VideoPlugin = "mupen64plus-video-rice" +# Filename of audio plugin +AudioPlugin = "mupen64plus-audio-sdl.so" +# Filename of input plugin +InputPlugin = "mupen64plus-input-sdl.so" +# Filename of RSP plugin +RspPlugin = "mupen64plus-rsp-hle.so" + + +[Video-General] + +# Width of output window or fullscreen width +ScreenWidth = 427 +# Height of output window or fullscreen height +ScreenHeight = 320 +# Use fullscreen mode if True, or windowed mode if False +Fullscreen = True +# If true, activate the SDL_GL_SWAP_CONTROL attribute +VerticalSync = True +# Rotate screen contents: 0=0 degree, 1=90 degree, 2 = 180 degree, 3=270 degree +Rotate = 0 + +[Video-GLideN64] + +###### Hardware Compatibility ###### +# Leave enabled unless a mobile gpu doesn't support it. +EnableFragmentDepthWrite = 0 +# Hardware per pixel lighting, supposedly good for GLES3.1 devices or higher. +EnableHWLighting = 0 + +###### Enhancements ####### +# Internal render resoluton rather than output. So 2 x 240p is 480p, etc. +UseNativeResolutionFactor = 1 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Enable/Disable Fast Approximate Anti-Aliasing FXAA +FXAA = 0 +# Max level of Anisotropic Filtering, 0 for off +anisotropy = 0 +# Bilinear filtering mode (0=N64 3point, 1=standard) +# @rishooty: best to use this at 1x native res, any higher turn it off. +bilinearMode = 1 + +###### Compatibility ###### +# Make texrect coordinates continuous to avoid black lines between them. (0=Off/default, 1=Auto, 2=Force) +CorrectTexrectCoords = 1 +# Copy auxiliary buffers to RDRAM (default: 0) +EnableCopyAuxiliaryToRDRAM = 1 +# Render 2D texrects in native resolution to fix misalignment between parts of 2D image. (0=Off/default, 1=Optimized, 2=Unoptimized)") +EnableNativeResTexrects = 1 + +###### Other ###### +# Enable threaded video backend at the cost of input lag +ThreadedVideo = 1 +# Screen aspect ratio (0=stretch, 1=force 4:3, 2=force 16:9, 3=adjust) +AspectRatio = 1 +# Display On-screen FPS +ShowFPS = False + +[Video-Glide64mk2] + +# Enable full-scene anti-aliasing by setting this to a value greater than 1 +wrpAntiAliasing = 0 +# Card ID +card_id = 0 +# If true, use polygon offset values specified below +force_polygon_offset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +polygon_offset_factor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +polygon_offset_units = 0.000000 +# Vertical sync +vsync = True +# TODO:ssformat +ssformat = False +# Display performance stats (add together desired flags): 1=FPS counter, 2=VI/s counter, 4=% speed, 8=FPS transparent +show_fps = 0 +# Clock enabled +clock = False +# Clock is 24-hour +clock_24_hr = True +# Wrapper resolution +wrpResolution = 0 +# Wrapper VRAM +wrpVRAM = 0 +# Wrapper FBO +wrpFBO = True +# Wrapper Anisotropic Filtering +wrpAnisotropic = True +# Texture Enhancement: Smooth/Sharpen Filters +ghq_fltr = 0 +# Texture Compression: 0 for S3TC, 1 for FXT1 +ghq_cmpr = 0 +# Texture Enhancement: More filters +ghq_enht = 0 +# Hi-res texture pack format (0 for none, 1 for Rice) +ghq_hirs = 1 +# Compress texture cache with S3TC or FXT1 +ghq_enht_cmpr = False +# Tile textures (saves memory but could cause issues) +ghq_enht_tile = 0 +# Force 16bpp textures (saves ram but lower quality) +ghq_enht_f16bpp = False +# Compress texture cache +ghq_enht_gz = True +# Don't enhance textures for backgrounds +ghq_enht_nobg = False +# Enable S3TC and FXT1 compression +ghq_hirs_cmpr = False +# Tile hi-res textures (saves memory but could cause issues) +ghq_hirs_tile = False +# Force 16bpp hi-res textures (saves ram but lower quality) +ghq_hirs_f16bpp = False +# Compress hi-res texture cache +ghq_hirs_gz = True +# Alternative CRC calculation -- emulates Rice bug +ghq_hirs_altcrc = True +# Save tex cache to disk +ghq_cache_save = True +# Texture Cache Size (MB) +ghq_cache_size = 128 +# Use full alpha channel -- could cause issues for some tex packs +ghq_hirs_let_texartists_fly = False +# Dump textures +ghq_hirs_dump = False +# Alternate texture size method: -1=Game default, 0=disable. 1=enable +alt_tex_size = -1 +# Use first SETTILESIZE only: -1=Game default, 0=disable. 1=enable +use_sts1_only = -1 +# Use spheric mapping only: -1=Game default, 0=disable. 1=enable +force_calc_sphere = -1 +# Force positive viewport: -1=Game default, 0=disable. 1=enable +correct_viewport = -1 +# Force texrect size to integral value: -1=Game default, 0=disable. 1=enable +increase_texrect_edge = -1 +# Reduce fillrect size by 1: -1=Game default, 0=disable. 1=enable +decrease_fillrect_edge = -1 +# Enable perspective texture correction emulation: -1=Game default, 0=disable. 1=enable +texture_correction = -1 +# Set special scale for PAL games: -1=Game default, 0=disable. 1=enable +pal230 = -1 +# 3DFX Dithered alpha emulation mode: -1=Game default, >=0=dithered alpha emulation mode +stipple_mode = -1 +# 3DFX Dithered alpha pattern: -1=Game default, >=0=pattern used for dithered alpha emulation +stipple_pattern = -1 +# Check microcode each frame: -1=Game default, 0=disable. 1=enable +force_microcheck = -1 +# Force 0xb5 command to be quad, not line 3D: -1=Game default, 0=disable. 1=enable +force_quad3d = -1 +# Enable near z clipping: -1=Game default, 0=disable. 1=enable +clip_zmin = -1 +# Enable far plane clipping: -1=Game default, 0=disable. 1=enable +clip_zmax = -1 +# Use fast CRC algorithm: -1=Game default, 0=disable. 1=enable +fast_crc = -1 +# Adjust screen aspect for wide screen mode: -1=Game default, 0=disable. 1=enable +adjust_aspect = -1 +# Force strict check in Depth buffer test: -1=Game default, 0=disable. 1=enable +zmode_compare_less = -1 +# Apply alpha dither regardless of alpha_dither_mode: -1=Game default, 0=disable. 1=enable +old_style_adither = -1 +# Scale vertex z value before writing to depth buffer: -1=Game default, 0=disable. 1=enable +n64_z_scale = -1 +# Fast texrect rendering with hwfbe: -1=Game default, 0=disable. 1=enable +optimize_texrect = -1 +# Do not copy auxiliary frame buffers: -1=Game default, 0=disable. 1=enable +ignore_aux_copy = -1 +# Clear auxiliary texture frame buffers: -1=Game default, 0=disable. 1=enable +hires_buf_clear = -1 +# Read alpha from framebuffer: -1=Game default, 0=disable. 1=enable +fb_read_alpha = -1 +# Handle unchanged fb: -1=Game default, 0=disable. 1=enable +useless_is_useless = -1 +# Set frambuffer CRC mode: -1=Game default, 0=disable CRC, 1=fast CRC, 2=safe CRC +fb_crc_mode = -1 +# Filtering mode: -1=Game default, 0=automatic, 1=force bilinear, 2=force point sampled +filtering = -1 +# Fog: -1=Game default, 0=disable. 1=enable +fog = -1 +# Buffer clear on every frame: -1=Game default, 0=disable. 1=enable +buff_clear = -1 +# Buffer swapping method: -1=Game default, 0=swap buffers when vertical interrupt has occurred, 1=swap buffers when set of conditions is satisfied. Prevents flicker on some games, 2=mix of first two methods +swapmode = -1 +# Aspect ratio: -1=Game default, 0=Force 4:3, 1=Force 16:9, 2=Stretch, 3=Original +aspect = -1 +# LOD calculation: -1=Game default, 0=disable. 1=fast, 2=precise +lodmode = -1 +# Smart framebuffer: -1=Game default, 0=disable. 1=enable +fb_smart = -1 +# Hardware frame buffer emulation: -1=Game default, 0=disable. 1=enable +fb_hires = -1 +# Read framebuffer every frame (may be slow use only for effects that need it e.g. Banjo Kazooie, DK64 transitions): -1=Game default, 0=disable. 1=enable +fb_read_always = -1 +# Render N64 frame buffer as texture: -1=Game default, 0=disable, 1=mode1, 2=mode2 +read_back_to_screen = -1 +# Show images written directly by CPU: -1=Game default, 0=disable. 1=enable +detect_cpu_write = -1 +# Get frame buffer info: -1=Game default, 0=disable. 1=enable +fb_get_info = -1 +# Enable software depth render: -1=Game default, 0=disable. 1=enable +fb_render = -1 +# If true, skip up to maxframeskip frames to maintain clock schedule; if false, skip exactly maxframeskip frames +autoframeskip = False +# If autoframeskip is true, skip up to this many frames to maintain clock schedule; if autoframeskip is false, skip exactly this many frames +maxframeskip = 0 + + +[Video-Rice] + +# Hack to accomodate widescreen devices +ResolutionWidth = 480 +# Mupen64Plus Rice Video Plugin config parameter version number +Version = 1 +# Frame Buffer Emulation (0=ROM default, 1=disable) +FrameBufferSetting = 0 +# Frequency to write back the frame buffer (0=every frame, 1=every other frame, etc) +FrameBufferWriteBackControl = 0 +# Render-to-texture emulation (0=none, 1=ignore, 2=normal, 3=write back, 4=write back and reload) +RenderToTexture = 0 +# Control when the screen will be updated (0=ROM default, 1=VI origin update, 2=VI origin change, 3=CI change, 4=first CI change, 5=first primitive draw, 6=before screen clear, 7=after screen drawn) +ScreenUpdateSetting = 4 +# Force to use normal alpha blender +NormalAlphaBlender = False +# Use a faster algorithm to speed up texture loading and CRC computation +FastTextureLoading = False +# Use different texture coordinate clamping code +AccurateTextureMapping = True +# Force emulated frame buffers to be in N64 native resolution +InN64Resolution = False +# Try to reduce Video RAM usage (should never be used) +SaveVRAM = False +# Enable this option to have better render-to-texture quality +DoubleSizeForSmallTxtrBuf = False +# Force to use normal color combiner +DefaultCombinerDisable = False +# Enable game-specific settings from INI file +EnableHacks = True +# If enabled, graphics will be drawn in WinFrame mode instead of solid and texture mode +WinFrameMode = False +# N64 Texture Memory Full Emulation (may fix some games, may break others) +FullTMEMEmulation = False +# Enable vertex clipper for fog operations +OpenGLVertexClipper = False +# Enable/Disable SSE optimizations for capable CPUs +EnableSSE = True +# If this option is enabled, the plugin will skip every other frame +SkipFrame = False +# If enabled, texture enhancement will be done only for TxtRect ucode +TexRectOnly = False +# If enabled, texture enhancement will be done only for textures width+height<=128 +SmallTextureOnly = False +# Select hi-resolution textures based only on the CRC and ignore format+size information (Glide64 compatibility) +LoadHiResCRCOnly = True +# Enable hi-resolution texture file loading +LoadHiResTextures = False +# Enable texture dumping +DumpTexturesToFiles = False +# Display On-screen FPS +ShowFPS = False +# Use Mipmapping? 0=no, 1=nearest, 2=bilinear, 3=trilinear +Mipmapping = 2 +# Enable, Disable fog generation (0=Disable, 1=Enable) +FogMethod = 1 +# Force to use texture filtering or not (0=auto: n64 choose, 1=force no filtering, 2=force filtering) +ForceTextureFilter = 0 +# Primary texture enhancement filter (0=None, 1=2X, 2=2XSAI, 3=HQ2X, 4=LQ2X, 5=HQ4X, 6=Sharpen, 7=Sharpen More, 8=External, 9=Mirrored) +TextureEnhancement = 0 +# Secondary texture enhancement filter (0 = none, 1-4 = filtered) +TextureEnhancementControl = 0 +# Color bit depth to use for textures (0=default, 1=32 bits, 2=16 bits) +TextureQuality = 0 +# Z-buffer depth (only 16 or 32) +OpenGLDepthBufferSetting = 16 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Color bit depth for rendering window (0=32 bits, 1=16 bits) +ColorQuality = 1 +# OpenGL level to support (0=auto, 1=OGL_FRAGMENT_PROGRAM) +OpenGLRenderSetting = 0 +# Enable/Disable Anisotropic Filtering for Mipmapping (0=no filtering, 2-16=quality). This is uneffective if Mipmapping is 0. If the given value is to high to be supported by your graphic card, the value will be the highest value your graphic card can support. Better result with Trilinear filtering +AnisotropicFiltering = 0 +# If true, use polygon offset values specified below +ForcePolygonOffset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +PolygonOffsetFactor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +PolygonOffsetUnits = 0.000000 diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3326/mupen64plus.cfg.ogs b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3326/mupen64plus.cfg.ogs new file mode 100644 index 0000000000..6b767fcf3e --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3326/mupen64plus.cfg.ogs @@ -0,0 +1,670 @@ +# Mupen64Plus Configuration File +# This file is automatically read and written by the Mupen64Plus Core library + +[64DD] + +# Filename of the 64DD IPL ROM +IPL-ROM = "" +# Filename of the disk to load into Disk Drive +Disk = "" + + +[Audio-SDL] + +# Mupen64Plus SDL Audio Plugin config parameter version number +Version = 1.000000 +# Frequency which is used if rom doesn't want to change it +DEFAULT_FREQUENCY = 33600 +# Swaps left and right channels +SWAP_CHANNELS = False +# Size of primary buffer in output samples. This is where audio is loaded after it's extracted from n64's memory. +PRIMARY_BUFFER_SIZE = 16384 +# Fullness level target for Primary audio buffer, in equivalent output samples. This value must be larger than the SECONDARY_BUFFER_SIZE. Decreasing this value will reduce audio latency but requires a faster PC to avoid choppiness. Increasing this will increase audio latency but reduce the chance of drop-outs. +PRIMARY_BUFFER_TARGET = 2048 +# Size of secondary buffer in output samples. This is SDL's hardware buffer. The SDL documentation states that this should be a power of two between 512 and 8192. +SECONDARY_BUFFER_SIZE = 1024 +# Audio resampling algorithm. src-sinc-best-quality, src-sinc-medium-quality, src-sinc-fastest, src-zero-order-hold, src-linear, speex-fixed-{10-0}, trivial +RESAMPLE = "trivial" +# Volume control type: 1 = SDL (only affects Mupen64Plus output) 2 = OSS mixer (adjusts master PC volume) +VOLUME_CONTROL_TYPE = 1 +# Percentage change each time the volume is increased or decreased +VOLUME_ADJUST = 5 +# Default volume when a game is started. Only used if VOLUME_CONTROL_TYPE is 1 +VOLUME_DEFAULT = 100 +# Synchronize Video/Audio +AUDIO_SYNC = False + + +[Core] + +# Mupen64Plus Core config parameter set version number. Please don't change this version number. +Version = 1.010000 +# Draw on-screen display if True, otherwise don't draw OSD +OnScreenDisplay = True +# Use Pure Interpreter if 0, Cached Interpreter if 1, or Dynamic Recompiler if 2 or more +R4300Emulator = 2 +# Disable compiled jump commands in dynamic recompiler (should be set to False) +NoCompiledJump = False +# Disable 4MB expansion RAM pack. May be necessary for some games +DisableExtraMem = False +# Increment the save state slot after each save operation +AutoStateSlotIncrement = False +# Activate the R4300 debugger when ROM execution begins, if core was built with Debugger support +EnableDebugger = False +# Save state slot (0-9) to use when saving/loading the emulator state +CurrentStateSlot = 0 +# Path to directory where screenshots are saved. If this is blank, the default value of ${UserDataPath}/screenshot will be used +ScreenshotPath = "/storage/roms/n64" +# Path to directory where emulator save states (snapshots) are saved. If this is blank, the default value of ${UserDataPath}/save will be used +SaveStatePath = "/storage/roms/n64" +# Path to directory where SRAM/EEPROM data (in-game saves) are stored. If this is blank, the default value of ${UserDataPath}/save will be used +SaveSRAMPath = "/storage/roms/n64" +# Path to a directory to search when looking for shared data files +SharedDataPath = "/tmp/mupen64plussa" +# Force number of cycles per emulated instruction +CountPerOp = 0 +# Randomize PI/SI Interrupt Timing +RandomizeInterrupt = True +# Duration of SI DMA (-1: use per game settings) +SiDmaDuration = -1 +# Gameboy Camera Video Capture backend +GbCameraVideoCaptureBackend1 = "" +# Disk Save Format (0: Full Disk Copy (*.ndr/*.d6r), 1: RAM Area Only (*.ram)) +SaveDiskFormat = 1 + + +[CoreEvents] + +# Mupen64Plus CoreEvents config parameter set version number. Please don't change this version number. +Version = 1.000000 +# SDL keysym for stopping the emulator +Kbd Mapping Stop = 27 +# SDL keysym for switching between fullscreen/windowed modes +Kbd Mapping Fullscreen = 0 +# SDL keysym for saving the emulator state +Kbd Mapping Save State = 286 +# SDL keysym for loading the emulator state +Kbd Mapping Load State = 288 +# SDL keysym for advancing the save state slot +Kbd Mapping Increment Slot = 0 +# SDL keysym for resetting the emulator +Kbd Mapping Reset = 290 +# SDL keysym for slowing down the emulator +Kbd Mapping Speed Down = 291 +# SDL keysym for speeding up the emulator +Kbd Mapping Speed Up = 292 +# SDL keysym for taking a screenshot +Kbd Mapping Screenshot = 293 +# SDL keysym for pausing the emulator +Kbd Mapping Pause = 112 +# SDL keysym for muting/unmuting the sound +Kbd Mapping Mute = 109 +# SDL keysym for increasing the volume +Kbd Mapping Increase Volume = 93 +# SDL keysym for decreasing the volume +Kbd Mapping Decrease Volume = 91 +# SDL keysym for temporarily going really fast +Kbd Mapping Fast Forward = 102 +# SDL keysym for advancing by one frame when paused +Kbd Mapping Frame Advance = 47 +# SDL keysym for pressing the game shark button +Kbd Mapping Gameshark = 103 +# Joystick event string for stopping the emulator +Joy Mapping Stop = "J0B12/B13" +# Joystick event string for switching between fullscreen/windowed modes +Joy Mapping Fullscreen = "" +# Joystick event string for saving the emulator state +Joy Mapping Save State = "J0B12/B5" +# Joystick event string for loading the emulator state +Joy Mapping Load State = "J0B12/B4" +# Joystick event string for advancing the save state slot +Joy Mapping Increment Slot = "" +# Joystick event string for resetting the emulator +Joy Mapping Reset = "" +# Joystick event string for slowing down the emulator +Joy Mapping Speed Down = "" +# Joystick event string for speeding up the emulator +Joy Mapping Speed Up = "" +# Joystick event string for taking a screenshot +Joy Mapping Screenshot = "" +# Joystick event string for pausing the emulator +Joy Mapping Pause = "J0B12/B0" +# Joystick event string for muting/unmuting the sound +Joy Mapping Mute = "" +# Joystick event string for increasing the volume +Joy Mapping Increase Volume = "" +# Joystick event string for decreasing the volume +Joy Mapping Decrease Volume = "" +# Joystick event string for fast-forward +Joy Mapping Fast Forward = "J0B12/B14" +# Joystick event string for advancing by one frame when paused +Joy Mapping Frame Advance = "" +# Joystick event string for pressing the game shark button +Joy Mapping Gameshark = "" +# SDL keysym for save slot 0 +Kbd Mapping Slot 0 = 48 +# SDL keysym for save slot 1 +Kbd Mapping Slot 1 = 49 +# SDL keysym for save slot 2 +Kbd Mapping Slot 2 = 50 +# SDL keysym for save slot 3 +Kbd Mapping Slot 3 = 51 +# SDL keysym for save slot 4 +Kbd Mapping Slot 4 = 52 +# SDL keysym for save slot 5 +Kbd Mapping Slot 5 = 53 +# SDL keysym for save slot 6 +Kbd Mapping Slot 6 = 54 +# SDL keysym for save slot 7 +Kbd Mapping Slot 7 = 55 +# SDL keysym for save slot 8 +Kbd Mapping Slot 8 = 56 +# SDL keysym for save slot 9 +Kbd Mapping Slot 9 = 57 + + +[Input-SDL-Control1] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = 0 +# SDL joystick name (or Keyboard) +name = "odroidgo3_joypad" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = True +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "0,0" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = button(11) +DPad L = button(10) +DPad D = button(9) +DPad U = button(8) +Start = button(13) +Z Trig = button(4) +B Button = button(3) +A Button = button(0) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(5) +L Trig = button(6) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Input-SDL-Control2] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control3] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control4] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Rsp-HLE] + +# Mupen64Plus RSP HLE Plugin config parameter version number +Version = 1.000000 +# Path to a RSP plugin which will be used when encountering an unknown ucode.You can disable this by letting an empty string. +RspFallback = "" +# Send display lists to the graphics plugin +DisplayListToGraphicsPlugin = True +# Send audio lists to the audio plugin +AudioListToAudioPlugin = False + + +[Transferpak] + +# Filename of the GB ROM to load into transferpak 1 +GB-rom-1 = "" +# Filename of the GB RAM to load into transferpak 1 +GB-ram-1 = "" +# Filename of the GB ROM to load into transferpak 2 +GB-rom-2 = "" +# Filename of the GB RAM to load into transferpak 2 +GB-ram-2 = "" +# Filename of the GB ROM to load into transferpak 3 +GB-rom-3 = "" +# Filename of the GB RAM to load into transferpak 3 +GB-ram-3 = "" +# Filename of the GB ROM to load into transferpak 4 +GB-rom-4 = "" +# Filename of the GB RAM to load into transferpak 4 +GB-ram-4 = "" + + +[UI-Console] + +# Mupen64Plus UI-Console config parameter set version number. Please don't change this version number. +Version = 1.000000 +# Directory in which to search for plugins +PluginDir = "/usr/local/lib/mupen64plus" +# Filename of video plugin +VideoPlugin = "mupen64plus-video-rice" +# Filename of audio plugin +AudioPlugin = "mupen64plus-audio-sdl.so" +# Filename of input plugin +InputPlugin = "mupen64plus-input-sdl.so" +# Filename of RSP plugin +RspPlugin = "mupen64plus-rsp-hle.so" + + +[Video-General] + +# Width of output window or fullscreen width +ScreenWidth = 427 +# Height of output window or fullscreen height +ScreenHeight = 320 +# Use fullscreen mode if True, or windowed mode if False +Fullscreen = True +# If true, activate the SDL_GL_SWAP_CONTROL attribute +VerticalSync = True +# Rotate screen contents: 0=0 degree, 1=90 degree, 2 = 180 degree, 3=270 degree +Rotate = 0 + +[Video-GLideN64] + +###### Hardware Compatibility ###### +# Leave enabled unless a mobile gpu doesn't support it. +EnableFragmentDepthWrite = 0 +# Hardware per pixel lighting, supposedly good for GLES3.1 devices or higher. +EnableHWLighting = 0 + +###### Enhancements ####### +# Internal render resoluton rather than output. So 2 x 240p is 480p, etc. +UseNativeResolutionFactor = 1 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Enable/Disable Fast Approximate Anti-Aliasing FXAA +FXAA = 0 +# Max level of Anisotropic Filtering, 0 for off +anisotropy = 0 +# Bilinear filtering mode (0=N64 3point, 1=standard) +# @rishooty: best to use this at 1x native res, any higher turn it off. +bilinearMode = 1 + +###### Compatibility ###### +# Make texrect coordinates continuous to avoid black lines between them. (0=Off/default, 1=Auto, 2=Force) +CorrectTexrectCoords = 1 +# Copy auxiliary buffers to RDRAM (default: 0) +EnableCopyAuxiliaryToRDRAM = 1 +# Render 2D texrects in native resolution to fix misalignment between parts of 2D image. (0=Off/default, 1=Optimized, 2=Unoptimized)") +EnableNativeResTexrects = 1 + +###### Other ###### +# Enable threaded video backend at the cost of input lag +ThreadedVideo = 1 +# Screen aspect ratio (0=stretch, 1=force 4:3, 2=force 16:9, 3=adjust) +AspectRatio = 1 +# Display On-screen FPS +ShowFPS = False + +[Video-Glide64mk2] + +# Enable full-scene anti-aliasing by setting this to a value greater than 1 +wrpAntiAliasing = 0 +# Card ID +card_id = 0 +# If true, use polygon offset values specified below +force_polygon_offset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +polygon_offset_factor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +polygon_offset_units = 0.000000 +# Vertical sync +vsync = True +# TODO:ssformat +ssformat = False +# Display performance stats (add together desired flags): 1=FPS counter, 2=VI/s counter, 4=% speed, 8=FPS transparent +show_fps = 0 +# Clock enabled +clock = False +# Clock is 24-hour +clock_24_hr = True +# Wrapper resolution +wrpResolution = 0 +# Wrapper VRAM +wrpVRAM = 0 +# Wrapper FBO +wrpFBO = True +# Wrapper Anisotropic Filtering +wrpAnisotropic = True +# Texture Enhancement: Smooth/Sharpen Filters +ghq_fltr = 0 +# Texture Compression: 0 for S3TC, 1 for FXT1 +ghq_cmpr = 0 +# Texture Enhancement: More filters +ghq_enht = 0 +# Hi-res texture pack format (0 for none, 1 for Rice) +ghq_hirs = 1 +# Compress texture cache with S3TC or FXT1 +ghq_enht_cmpr = False +# Tile textures (saves memory but could cause issues) +ghq_enht_tile = 0 +# Force 16bpp textures (saves ram but lower quality) +ghq_enht_f16bpp = False +# Compress texture cache +ghq_enht_gz = True +# Don't enhance textures for backgrounds +ghq_enht_nobg = False +# Enable S3TC and FXT1 compression +ghq_hirs_cmpr = False +# Tile hi-res textures (saves memory but could cause issues) +ghq_hirs_tile = False +# Force 16bpp hi-res textures (saves ram but lower quality) +ghq_hirs_f16bpp = False +# Compress hi-res texture cache +ghq_hirs_gz = True +# Alternative CRC calculation -- emulates Rice bug +ghq_hirs_altcrc = True +# Save tex cache to disk +ghq_cache_save = True +# Texture Cache Size (MB) +ghq_cache_size = 128 +# Use full alpha channel -- could cause issues for some tex packs +ghq_hirs_let_texartists_fly = False +# Dump textures +ghq_hirs_dump = False +# Alternate texture size method: -1=Game default, 0=disable. 1=enable +alt_tex_size = -1 +# Use first SETTILESIZE only: -1=Game default, 0=disable. 1=enable +use_sts1_only = -1 +# Use spheric mapping only: -1=Game default, 0=disable. 1=enable +force_calc_sphere = -1 +# Force positive viewport: -1=Game default, 0=disable. 1=enable +correct_viewport = -1 +# Force texrect size to integral value: -1=Game default, 0=disable. 1=enable +increase_texrect_edge = -1 +# Reduce fillrect size by 1: -1=Game default, 0=disable. 1=enable +decrease_fillrect_edge = -1 +# Enable perspective texture correction emulation: -1=Game default, 0=disable. 1=enable +texture_correction = -1 +# Set special scale for PAL games: -1=Game default, 0=disable. 1=enable +pal230 = -1 +# 3DFX Dithered alpha emulation mode: -1=Game default, >=0=dithered alpha emulation mode +stipple_mode = -1 +# 3DFX Dithered alpha pattern: -1=Game default, >=0=pattern used for dithered alpha emulation +stipple_pattern = -1 +# Check microcode each frame: -1=Game default, 0=disable. 1=enable +force_microcheck = -1 +# Force 0xb5 command to be quad, not line 3D: -1=Game default, 0=disable. 1=enable +force_quad3d = -1 +# Enable near z clipping: -1=Game default, 0=disable. 1=enable +clip_zmin = -1 +# Enable far plane clipping: -1=Game default, 0=disable. 1=enable +clip_zmax = -1 +# Use fast CRC algorithm: -1=Game default, 0=disable. 1=enable +fast_crc = -1 +# Adjust screen aspect for wide screen mode: -1=Game default, 0=disable. 1=enable +adjust_aspect = -1 +# Force strict check in Depth buffer test: -1=Game default, 0=disable. 1=enable +zmode_compare_less = -1 +# Apply alpha dither regardless of alpha_dither_mode: -1=Game default, 0=disable. 1=enable +old_style_adither = -1 +# Scale vertex z value before writing to depth buffer: -1=Game default, 0=disable. 1=enable +n64_z_scale = -1 +# Fast texrect rendering with hwfbe: -1=Game default, 0=disable. 1=enable +optimize_texrect = -1 +# Do not copy auxiliary frame buffers: -1=Game default, 0=disable. 1=enable +ignore_aux_copy = -1 +# Clear auxiliary texture frame buffers: -1=Game default, 0=disable. 1=enable +hires_buf_clear = -1 +# Read alpha from framebuffer: -1=Game default, 0=disable. 1=enable +fb_read_alpha = -1 +# Handle unchanged fb: -1=Game default, 0=disable. 1=enable +useless_is_useless = -1 +# Set frambuffer CRC mode: -1=Game default, 0=disable CRC, 1=fast CRC, 2=safe CRC +fb_crc_mode = -1 +# Filtering mode: -1=Game default, 0=automatic, 1=force bilinear, 2=force point sampled +filtering = -1 +# Fog: -1=Game default, 0=disable. 1=enable +fog = -1 +# Buffer clear on every frame: -1=Game default, 0=disable. 1=enable +buff_clear = -1 +# Buffer swapping method: -1=Game default, 0=swap buffers when vertical interrupt has occurred, 1=swap buffers when set of conditions is satisfied. Prevents flicker on some games, 2=mix of first two methods +swapmode = -1 +# Aspect ratio: -1=Game default, 0=Force 4:3, 1=Force 16:9, 2=Stretch, 3=Original +aspect = -1 +# LOD calculation: -1=Game default, 0=disable. 1=fast, 2=precise +lodmode = -1 +# Smart framebuffer: -1=Game default, 0=disable. 1=enable +fb_smart = -1 +# Hardware frame buffer emulation: -1=Game default, 0=disable. 1=enable +fb_hires = -1 +# Read framebuffer every frame (may be slow use only for effects that need it e.g. Banjo Kazooie, DK64 transitions): -1=Game default, 0=disable. 1=enable +fb_read_always = -1 +# Render N64 frame buffer as texture: -1=Game default, 0=disable, 1=mode1, 2=mode2 +read_back_to_screen = -1 +# Show images written directly by CPU: -1=Game default, 0=disable. 1=enable +detect_cpu_write = -1 +# Get frame buffer info: -1=Game default, 0=disable. 1=enable +fb_get_info = -1 +# Enable software depth render: -1=Game default, 0=disable. 1=enable +fb_render = -1 +# If true, skip up to maxframeskip frames to maintain clock schedule; if false, skip exactly maxframeskip frames +autoframeskip = False +# If autoframeskip is true, skip up to this many frames to maintain clock schedule; if autoframeskip is false, skip exactly this many frames +maxframeskip = 0 + + +[Video-Rice] + +# Hack to accomodate widescreen devices +ResolutionWidth = 480 +# Mupen64Plus Rice Video Plugin config parameter version number +Version = 1 +# Frame Buffer Emulation (0=ROM default, 1=disable) +FrameBufferSetting = 0 +# Frequency to write back the frame buffer (0=every frame, 1=every other frame, etc) +FrameBufferWriteBackControl = 0 +# Render-to-texture emulation (0=none, 1=ignore, 2=normal, 3=write back, 4=write back and reload) +RenderToTexture = 0 +# Control when the screen will be updated (0=ROM default, 1=VI origin update, 2=VI origin change, 3=CI change, 4=first CI change, 5=first primitive draw, 6=before screen clear, 7=after screen drawn) +ScreenUpdateSetting = 4 +# Force to use normal alpha blender +NormalAlphaBlender = False +# Use a faster algorithm to speed up texture loading and CRC computation +FastTextureLoading = False +# Use different texture coordinate clamping code +AccurateTextureMapping = True +# Force emulated frame buffers to be in N64 native resolution +InN64Resolution = False +# Try to reduce Video RAM usage (should never be used) +SaveVRAM = False +# Enable this option to have better render-to-texture quality +DoubleSizeForSmallTxtrBuf = False +# Force to use normal color combiner +DefaultCombinerDisable = False +# Enable game-specific settings from INI file +EnableHacks = True +# If enabled, graphics will be drawn in WinFrame mode instead of solid and texture mode +WinFrameMode = False +# N64 Texture Memory Full Emulation (may fix some games, may break others) +FullTMEMEmulation = False +# Enable vertex clipper for fog operations +OpenGLVertexClipper = False +# Enable/Disable SSE optimizations for capable CPUs +EnableSSE = True +# If this option is enabled, the plugin will skip every other frame +SkipFrame = False +# If enabled, texture enhancement will be done only for TxtRect ucode +TexRectOnly = False +# If enabled, texture enhancement will be done only for textures width+height<=128 +SmallTextureOnly = False +# Select hi-resolution textures based only on the CRC and ignore format+size information (Glide64 compatibility) +LoadHiResCRCOnly = True +# Enable hi-resolution texture file loading +LoadHiResTextures = False +# Enable texture dumping +DumpTexturesToFiles = False +# Display On-screen FPS +ShowFPS = False +# Use Mipmapping? 0=no, 1=nearest, 2=bilinear, 3=trilinear +Mipmapping = 2 +# Enable, Disable fog generation (0=Disable, 1=Enable) +FogMethod = 1 +# Force to use texture filtering or not (0=auto: n64 choose, 1=force no filtering, 2=force filtering) +ForceTextureFilter = 0 +# Primary texture enhancement filter (0=None, 1=2X, 2=2XSAI, 3=HQ2X, 4=LQ2X, 5=HQ4X, 6=Sharpen, 7=Sharpen More, 8=External, 9=Mirrored) +TextureEnhancement = 0 +# Secondary texture enhancement filter (0 = none, 1-4 = filtered) +TextureEnhancementControl = 0 +# Color bit depth to use for textures (0=default, 1=32 bits, 2=16 bits) +TextureQuality = 0 +# Z-buffer depth (only 16 or 32) +OpenGLDepthBufferSetting = 16 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Color bit depth for rendering window (0=32 bits, 1=16 bits) +ColorQuality = 1 +# OpenGL level to support (0=auto, 1=OGL_FRAGMENT_PROGRAM) +OpenGLRenderSetting = 0 +# Enable/Disable Anisotropic Filtering for Mipmapping (0=no filtering, 2-16=quality). This is uneffective if Mipmapping is 0. If the given value is to high to be supported by your graphic card, the value will be the highest value your graphic card can support. Better result with Trilinear filtering +AnisotropicFiltering = 0 +# If true, use polygon offset values specified below +ForcePolygonOffset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +PolygonOffsetFactor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +PolygonOffsetUnits = 0.000000 diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3326/mupen64plus.cfg.r33s b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3326/mupen64plus.cfg.r33s new file mode 100644 index 0000000000..13f53c3898 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3326/mupen64plus.cfg.r33s @@ -0,0 +1,670 @@ +# Mupen64Plus Configuration File +# This file is automatically read and written by the Mupen64Plus Core library + +[64DD] + +# Filename of the 64DD IPL ROM +IPL-ROM = "" +# Filename of the disk to load into Disk Drive +Disk = "" + + +[Audio-SDL] + +# Mupen64Plus SDL Audio Plugin config parameter version number +Version = 1.000000 +# Frequency which is used if rom doesn't want to change it +DEFAULT_FREQUENCY = 33600 +# Swaps left and right channels +SWAP_CHANNELS = False +# Size of primary buffer in output samples. This is where audio is loaded after it's extracted from n64's memory. +PRIMARY_BUFFER_SIZE = 16384 +# Fullness level target for Primary audio buffer, in equivalent output samples. This value must be larger than the SECONDARY_BUFFER_SIZE. Decreasing this value will reduce audio latency but requires a faster PC to avoid choppiness. Increasing this will increase audio latency but reduce the chance of drop-outs. +PRIMARY_BUFFER_TARGET = 2048 +# Size of secondary buffer in output samples. This is SDL's hardware buffer. The SDL documentation states that this should be a power of two between 512 and 8192. +SECONDARY_BUFFER_SIZE = 1024 +# Audio resampling algorithm. src-sinc-best-quality, src-sinc-medium-quality, src-sinc-fastest, src-zero-order-hold, src-linear, speex-fixed-{10-0}, trivial +RESAMPLE = "trivial" +# Volume control type: 1 = SDL (only affects Mupen64Plus output) 2 = OSS mixer (adjusts master PC volume) +VOLUME_CONTROL_TYPE = 1 +# Percentage change each time the volume is increased or decreased +VOLUME_ADJUST = 5 +# Default volume when a game is started. Only used if VOLUME_CONTROL_TYPE is 1 +VOLUME_DEFAULT = 100 +# Synchronize Video/Audio +AUDIO_SYNC = False + + +[Core] + +# Mupen64Plus Core config parameter set version number. Please don't change this version number. +Version = 1.010000 +# Draw on-screen display if True, otherwise don't draw OSD +OnScreenDisplay = True +# Use Pure Interpreter if 0, Cached Interpreter if 1, or Dynamic Recompiler if 2 or more +R4300Emulator = 2 +# Disable compiled jump commands in dynamic recompiler (should be set to False) +NoCompiledJump = False +# Disable 4MB expansion RAM pack. May be necessary for some games +DisableExtraMem = False +# Increment the save state slot after each save operation +AutoStateSlotIncrement = False +# Activate the R4300 debugger when ROM execution begins, if core was built with Debugger support +EnableDebugger = False +# Save state slot (0-9) to use when saving/loading the emulator state +CurrentStateSlot = 0 +# Path to directory where screenshots are saved. If this is blank, the default value of ${UserDataPath}/screenshot will be used +ScreenshotPath = "/storage/roms/n64" +# Path to directory where emulator save states (snapshots) are saved. If this is blank, the default value of ${UserDataPath}/save will be used +SaveStatePath = "/storage/roms/n64" +# Path to directory where SRAM/EEPROM data (in-game saves) are stored. If this is blank, the default value of ${UserDataPath}/save will be used +SaveSRAMPath = "/storage/roms/n64" +# Path to a directory to search when looking for shared data files +SharedDataPath = "/tmp/mupen64plussa" +# Force number of cycles per emulated instruction +CountPerOp = 0 +# Randomize PI/SI Interrupt Timing +RandomizeInterrupt = True +# Duration of SI DMA (-1: use per game settings) +SiDmaDuration = -1 +# Gameboy Camera Video Capture backend +GbCameraVideoCaptureBackend1 = "" +# Disk Save Format (0: Full Disk Copy (*.ndr/*.d6r), 1: RAM Area Only (*.ram)) +SaveDiskFormat = 1 + + +[CoreEvents] + +# Mupen64Plus CoreEvents config parameter set version number. Please don't change this version number. +Version = 1.000000 +# SDL keysym for stopping the emulator +Kbd Mapping Stop = 27 +# SDL keysym for switching between fullscreen/windowed modes +Kbd Mapping Fullscreen = 0 +# SDL keysym for saving the emulator state +Kbd Mapping Save State = 286 +# SDL keysym for loading the emulator state +Kbd Mapping Load State = 288 +# SDL keysym for advancing the save state slot +Kbd Mapping Increment Slot = 0 +# SDL keysym for resetting the emulator +Kbd Mapping Reset = 290 +# SDL keysym for slowing down the emulator +Kbd Mapping Speed Down = 291 +# SDL keysym for speeding up the emulator +Kbd Mapping Speed Up = 292 +# SDL keysym for taking a screenshot +Kbd Mapping Screenshot = 293 +# SDL keysym for pausing the emulator +Kbd Mapping Pause = 112 +# SDL keysym for muting/unmuting the sound +Kbd Mapping Mute = 109 +# SDL keysym for increasing the volume +Kbd Mapping Increase Volume = 93 +# SDL keysym for decreasing the volume +Kbd Mapping Decrease Volume = 91 +# SDL keysym for temporarily going really fast +Kbd Mapping Fast Forward = 102 +# SDL keysym for advancing by one frame when paused +Kbd Mapping Frame Advance = 47 +# SDL keysym for pressing the game shark button +Kbd Mapping Gameshark = 103 +# Joystick event string for stopping the emulator +Joy Mapping Stop = "J0B8/B9" +# Joystick event string for switching between fullscreen/windowed modes +Joy Mapping Fullscreen = "" +# Joystick event string for saving the emulator state +Joy Mapping Save State = "J0B8/B5" +# Joystick event string for loading the emulator state +Joy Mapping Load State = "J0B8/B4" +# Joystick event string for advancing the save state slot +Joy Mapping Increment Slot = "" +# Joystick event string for resetting the emulator +Joy Mapping Reset = "" +# Joystick event string for slowing down the emulator +Joy Mapping Speed Down = "" +# Joystick event string for speeding up the emulator +Joy Mapping Speed Up = "" +# Joystick event string for taking a screenshot +Joy Mapping Screenshot = "" +# Joystick event string for pausing the emulator +Joy Mapping Pause = "J0B8/B0" +# Joystick event string for muting/unmuting the sound +Joy Mapping Mute = "" +# Joystick event string for increasing the volume +Joy Mapping Increase Volume = "" +# Joystick event string for decreasing the volume +Joy Mapping Decrease Volume = "" +# Joystick event string for fast-forward +Joy Mapping Fast Forward = "J0B8/B7" +# Joystick event string for advancing by one frame when paused +Joy Mapping Frame Advance = "" +# Joystick event string for pressing the game shark button +Joy Mapping Gameshark = "" +# SDL keysym for save slot 0 +Kbd Mapping Slot 0 = 48 +# SDL keysym for save slot 1 +Kbd Mapping Slot 1 = 49 +# SDL keysym for save slot 2 +Kbd Mapping Slot 2 = 50 +# SDL keysym for save slot 3 +Kbd Mapping Slot 3 = 51 +# SDL keysym for save slot 4 +Kbd Mapping Slot 4 = 52 +# SDL keysym for save slot 5 +Kbd Mapping Slot 5 = 53 +# SDL keysym for save slot 6 +Kbd Mapping Slot 6 = 54 +# SDL keysym for save slot 7 +Kbd Mapping Slot 7 = 55 +# SDL keysym for save slot 8 +Kbd Mapping Slot 8 = 56 +# SDL keysym for save slot 9 +Kbd Mapping Slot 9 = 57 + + +[Input-SDL-Control1] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = 0 +# SDL joystick name (or Keyboard) +name = "r33s_joypad" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = True +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "0,0" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = +DPad L = +DPad D = +DPad U = +Start = button(9) +Z Trig = button(4) +B Button = button(3) +A Button = button(0) +C Button R = button(7) +C Button L = button(6) +C Button D = button(1) +C Button U = button(2) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = button(12,13)axis(0-,0+) +Y Axis = butoon(10,11)axis(1-,1+) + +[Input-SDL-Control2] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control3] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control4] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Rsp-HLE] + +# Mupen64Plus RSP HLE Plugin config parameter version number +Version = 1.000000 +# Path to a RSP plugin which will be used when encountering an unknown ucode.You can disable this by letting an empty string. +RspFallback = "" +# Send display lists to the graphics plugin +DisplayListToGraphicsPlugin = True +# Send audio lists to the audio plugin +AudioListToAudioPlugin = False + + +[Transferpak] + +# Filename of the GB ROM to load into transferpak 1 +GB-rom-1 = "" +# Filename of the GB RAM to load into transferpak 1 +GB-ram-1 = "" +# Filename of the GB ROM to load into transferpak 2 +GB-rom-2 = "" +# Filename of the GB RAM to load into transferpak 2 +GB-ram-2 = "" +# Filename of the GB ROM to load into transferpak 3 +GB-rom-3 = "" +# Filename of the GB RAM to load into transferpak 3 +GB-ram-3 = "" +# Filename of the GB ROM to load into transferpak 4 +GB-rom-4 = "" +# Filename of the GB RAM to load into transferpak 4 +GB-ram-4 = "" + + +[UI-Console] + +# Mupen64Plus UI-Console config parameter set version number. Please don't change this version number. +Version = 1.000000 +# Directory in which to search for plugins +PluginDir = "/usr/local/lib/mupen64plus" +# Filename of video plugin +VideoPlugin = "mupen64plus-video-rice" +# Filename of audio plugin +AudioPlugin = "mupen64plus-audio-sdl.so" +# Filename of input plugin +InputPlugin = "mupen64plus-input-sdl.so" +# Filename of RSP plugin +RspPlugin = "mupen64plus-rsp-hle.so" + + +[Video-General] + +# Width of output window or fullscreen width +ScreenWidth = 427 +# Height of output window or fullscreen height +ScreenHeight = 320 +# Use fullscreen mode if True, or windowed mode if False +Fullscreen = True +# If true, activate the SDL_GL_SWAP_CONTROL attribute +VerticalSync = True +# Rotate screen contents: 0=0 degree, 1=90 degree, 2 = 180 degree, 3=270 degree +Rotate = 0 + +[Video-GLideN64] + +###### Hardware Compatibility ###### +# Leave enabled unless a mobile gpu doesn't support it. +EnableFragmentDepthWrite = 0 +# Hardware per pixel lighting, supposedly good for GLES3.1 devices or higher. +EnableHWLighting = 0 + +###### Enhancements ####### +# Internal render resoluton rather than output. So 2 x 240p is 480p, etc. +UseNativeResolutionFactor = 1 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Enable/Disable Fast Approximate Anti-Aliasing FXAA +FXAA = 0 +# Max level of Anisotropic Filtering, 0 for off +anisotropy = 0 +# Bilinear filtering mode (0=N64 3point, 1=standard) +# @rishooty: best to use this at 1x native res, any higher turn it off. +bilinearMode = 1 + +###### Compatibility ###### +# Make texrect coordinates continuous to avoid black lines between them. (0=Off/default, 1=Auto, 2=Force) +CorrectTexrectCoords = 1 +# Copy auxiliary buffers to RDRAM (default: 0) +EnableCopyAuxiliaryToRDRAM = 1 +# Render 2D texrects in native resolution to fix misalignment between parts of 2D image. (0=Off/default, 1=Optimized, 2=Unoptimized)") +EnableNativeResTexrects = 1 + +###### Other ###### +# Enable threaded video backend at the cost of input lag +ThreadedVideo = 1 +# Screen aspect ratio (0=stretch, 1=force 4:3, 2=force 16:9, 3=adjust) +AspectRatio = 1 +# Display On-screen FPS +ShowFPS = False + +[Video-Glide64mk2] + +# Enable full-scene anti-aliasing by setting this to a value greater than 1 +wrpAntiAliasing = 0 +# Card ID +card_id = 0 +# If true, use polygon offset values specified below +force_polygon_offset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +polygon_offset_factor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +polygon_offset_units = 0.000000 +# Vertical sync +vsync = True +# TODO:ssformat +ssformat = False +# Display performance stats (add together desired flags): 1=FPS counter, 2=VI/s counter, 4=% speed, 8=FPS transparent +show_fps = 0 +# Clock enabled +clock = False +# Clock is 24-hour +clock_24_hr = True +# Wrapper resolution +wrpResolution = 0 +# Wrapper VRAM +wrpVRAM = 0 +# Wrapper FBO +wrpFBO = True +# Wrapper Anisotropic Filtering +wrpAnisotropic = True +# Texture Enhancement: Smooth/Sharpen Filters +ghq_fltr = 0 +# Texture Compression: 0 for S3TC, 1 for FXT1 +ghq_cmpr = 0 +# Texture Enhancement: More filters +ghq_enht = 0 +# Hi-res texture pack format (0 for none, 1 for Rice) +ghq_hirs = 1 +# Compress texture cache with S3TC or FXT1 +ghq_enht_cmpr = False +# Tile textures (saves memory but could cause issues) +ghq_enht_tile = 0 +# Force 16bpp textures (saves ram but lower quality) +ghq_enht_f16bpp = False +# Compress texture cache +ghq_enht_gz = True +# Don't enhance textures for backgrounds +ghq_enht_nobg = False +# Enable S3TC and FXT1 compression +ghq_hirs_cmpr = False +# Tile hi-res textures (saves memory but could cause issues) +ghq_hirs_tile = False +# Force 16bpp hi-res textures (saves ram but lower quality) +ghq_hirs_f16bpp = False +# Compress hi-res texture cache +ghq_hirs_gz = True +# Alternative CRC calculation -- emulates Rice bug +ghq_hirs_altcrc = True +# Save tex cache to disk +ghq_cache_save = True +# Texture Cache Size (MB) +ghq_cache_size = 128 +# Use full alpha channel -- could cause issues for some tex packs +ghq_hirs_let_texartists_fly = False +# Dump textures +ghq_hirs_dump = False +# Alternate texture size method: -1=Game default, 0=disable. 1=enable +alt_tex_size = -1 +# Use first SETTILESIZE only: -1=Game default, 0=disable. 1=enable +use_sts1_only = -1 +# Use spheric mapping only: -1=Game default, 0=disable. 1=enable +force_calc_sphere = -1 +# Force positive viewport: -1=Game default, 0=disable. 1=enable +correct_viewport = -1 +# Force texrect size to integral value: -1=Game default, 0=disable. 1=enable +increase_texrect_edge = -1 +# Reduce fillrect size by 1: -1=Game default, 0=disable. 1=enable +decrease_fillrect_edge = -1 +# Enable perspective texture correction emulation: -1=Game default, 0=disable. 1=enable +texture_correction = -1 +# Set special scale for PAL games: -1=Game default, 0=disable. 1=enable +pal230 = -1 +# 3DFX Dithered alpha emulation mode: -1=Game default, >=0=dithered alpha emulation mode +stipple_mode = -1 +# 3DFX Dithered alpha pattern: -1=Game default, >=0=pattern used for dithered alpha emulation +stipple_pattern = -1 +# Check microcode each frame: -1=Game default, 0=disable. 1=enable +force_microcheck = -1 +# Force 0xb5 command to be quad, not line 3D: -1=Game default, 0=disable. 1=enable +force_quad3d = -1 +# Enable near z clipping: -1=Game default, 0=disable. 1=enable +clip_zmin = -1 +# Enable far plane clipping: -1=Game default, 0=disable. 1=enable +clip_zmax = -1 +# Use fast CRC algorithm: -1=Game default, 0=disable. 1=enable +fast_crc = -1 +# Adjust screen aspect for wide screen mode: -1=Game default, 0=disable. 1=enable +adjust_aspect = -1 +# Force strict check in Depth buffer test: -1=Game default, 0=disable. 1=enable +zmode_compare_less = -1 +# Apply alpha dither regardless of alpha_dither_mode: -1=Game default, 0=disable. 1=enable +old_style_adither = -1 +# Scale vertex z value before writing to depth buffer: -1=Game default, 0=disable. 1=enable +n64_z_scale = -1 +# Fast texrect rendering with hwfbe: -1=Game default, 0=disable. 1=enable +optimize_texrect = -1 +# Do not copy auxiliary frame buffers: -1=Game default, 0=disable. 1=enable +ignore_aux_copy = -1 +# Clear auxiliary texture frame buffers: -1=Game default, 0=disable. 1=enable +hires_buf_clear = -1 +# Read alpha from framebuffer: -1=Game default, 0=disable. 1=enable +fb_read_alpha = -1 +# Handle unchanged fb: -1=Game default, 0=disable. 1=enable +useless_is_useless = -1 +# Set frambuffer CRC mode: -1=Game default, 0=disable CRC, 1=fast CRC, 2=safe CRC +fb_crc_mode = -1 +# Filtering mode: -1=Game default, 0=automatic, 1=force bilinear, 2=force point sampled +filtering = -1 +# Fog: -1=Game default, 0=disable. 1=enable +fog = -1 +# Buffer clear on every frame: -1=Game default, 0=disable. 1=enable +buff_clear = -1 +# Buffer swapping method: -1=Game default, 0=swap buffers when vertical interrupt has occurred, 1=swap buffers when set of conditions is satisfied. Prevents flicker on some games, 2=mix of first two methods +swapmode = -1 +# Aspect ratio: -1=Game default, 0=Force 4:3, 1=Force 16:9, 2=Stretch, 3=Original +aspect = -1 +# LOD calculation: -1=Game default, 0=disable. 1=fast, 2=precise +lodmode = -1 +# Smart framebuffer: -1=Game default, 0=disable. 1=enable +fb_smart = -1 +# Hardware frame buffer emulation: -1=Game default, 0=disable. 1=enable +fb_hires = -1 +# Read framebuffer every frame (may be slow use only for effects that need it e.g. Banjo Kazooie, DK64 transitions): -1=Game default, 0=disable. 1=enable +fb_read_always = -1 +# Render N64 frame buffer as texture: -1=Game default, 0=disable, 1=mode1, 2=mode2 +read_back_to_screen = -1 +# Show images written directly by CPU: -1=Game default, 0=disable. 1=enable +detect_cpu_write = -1 +# Get frame buffer info: -1=Game default, 0=disable. 1=enable +fb_get_info = -1 +# Enable software depth render: -1=Game default, 0=disable. 1=enable +fb_render = -1 +# If true, skip up to maxframeskip frames to maintain clock schedule; if false, skip exactly maxframeskip frames +autoframeskip = False +# If autoframeskip is true, skip up to this many frames to maintain clock schedule; if autoframeskip is false, skip exactly this many frames +maxframeskip = 0 + + +[Video-Rice] + +# Hack to accomodate widescreen devices +ResolutionWidth = 480 +# Mupen64Plus Rice Video Plugin config parameter version number +Version = 1 +# Frame Buffer Emulation (0=ROM default, 1=disable) +FrameBufferSetting = 0 +# Frequency to write back the frame buffer (0=every frame, 1=every other frame, etc) +FrameBufferWriteBackControl = 0 +# Render-to-texture emulation (0=none, 1=ignore, 2=normal, 3=write back, 4=write back and reload) +RenderToTexture = 0 +# Control when the screen will be updated (0=ROM default, 1=VI origin update, 2=VI origin change, 3=CI change, 4=first CI change, 5=first primitive draw, 6=before screen clear, 7=after screen drawn) +ScreenUpdateSetting = 4 +# Force to use normal alpha blender +NormalAlphaBlender = False +# Use a faster algorithm to speed up texture loading and CRC computation +FastTextureLoading = False +# Use different texture coordinate clamping code +AccurateTextureMapping = True +# Force emulated frame buffers to be in N64 native resolution +InN64Resolution = False +# Try to reduce Video RAM usage (should never be used) +SaveVRAM = False +# Enable this option to have better render-to-texture quality +DoubleSizeForSmallTxtrBuf = False +# Force to use normal color combiner +DefaultCombinerDisable = False +# Enable game-specific settings from INI file +EnableHacks = True +# If enabled, graphics will be drawn in WinFrame mode instead of solid and texture mode +WinFrameMode = False +# N64 Texture Memory Full Emulation (may fix some games, may break others) +FullTMEMEmulation = False +# Enable vertex clipper for fog operations +OpenGLVertexClipper = False +# Enable/Disable SSE optimizations for capable CPUs +EnableSSE = True +# If this option is enabled, the plugin will skip every other frame +SkipFrame = False +# If enabled, texture enhancement will be done only for TxtRect ucode +TexRectOnly = False +# If enabled, texture enhancement will be done only for textures width+height<=128 +SmallTextureOnly = False +# Select hi-resolution textures based only on the CRC and ignore format+size information (Glide64 compatibility) +LoadHiResCRCOnly = True +# Enable hi-resolution texture file loading +LoadHiResTextures = False +# Enable texture dumping +DumpTexturesToFiles = False +# Display On-screen FPS +ShowFPS = False +# Use Mipmapping? 0=no, 1=nearest, 2=bilinear, 3=trilinear +Mipmapping = 2 +# Enable, Disable fog generation (0=Disable, 1=Enable) +FogMethod = 1 +# Force to use texture filtering or not (0=auto: n64 choose, 1=force no filtering, 2=force filtering) +ForceTextureFilter = 0 +# Primary texture enhancement filter (0=None, 1=2X, 2=2XSAI, 3=HQ2X, 4=LQ2X, 5=HQ4X, 6=Sharpen, 7=Sharpen More, 8=External, 9=Mirrored) +TextureEnhancement = 0 +# Secondary texture enhancement filter (0 = none, 1-4 = filtered) +TextureEnhancementControl = 0 +# Color bit depth to use for textures (0=default, 1=32 bits, 2=16 bits) +TextureQuality = 0 +# Z-buffer depth (only 16 or 32) +OpenGLDepthBufferSetting = 16 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Color bit depth for rendering window (0=32 bits, 1=16 bits) +ColorQuality = 1 +# OpenGL level to support (0=auto, 1=OGL_FRAGMENT_PROGRAM) +OpenGLRenderSetting = 0 +# Enable/Disable Anisotropic Filtering for Mipmapping (0=no filtering, 2-16=quality). This is uneffective if Mipmapping is 0. If the given value is to high to be supported by your graphic card, the value will be the highest value your graphic card can support. Better result with Trilinear filtering +AnisotropicFiltering = 0 +# If true, use polygon offset values specified below +ForcePolygonOffset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +PolygonOffsetFactor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +PolygonOffsetUnits = 0.000000 diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3326/mupen64plus.cfg.s1_f2 b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3326/mupen64plus.cfg.s1_f2 new file mode 100644 index 0000000000..0737ebb4bb --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3326/mupen64plus.cfg.s1_f2 @@ -0,0 +1,670 @@ +# Mupen64Plus Configuration File +# This file is automatically read and written by the Mupen64Plus Core library + +[64DD] + +# Filename of the 64DD IPL ROM +IPL-ROM = "" +# Filename of the disk to load into Disk Drive +Disk = "" + + +[Audio-SDL] + +# Mupen64Plus SDL Audio Plugin config parameter version number +Version = 1.000000 +# Frequency which is used if rom doesn't want to change it +DEFAULT_FREQUENCY = 33600 +# Swaps left and right channels +SWAP_CHANNELS = False +# Size of primary buffer in output samples. This is where audio is loaded after it's extracted from n64's memory. +PRIMARY_BUFFER_SIZE = 16384 +# Fullness level target for Primary audio buffer, in equivalent output samples. This value must be larger than the SECONDARY_BUFFER_SIZE. Decreasing this value will reduce audio latency but requires a faster PC to avoid choppiness. Increasing this will increase audio latency but reduce the chance of drop-outs. +PRIMARY_BUFFER_TARGET = 2048 +# Size of secondary buffer in output samples. This is SDL's hardware buffer. The SDL documentation states that this should be a power of two between 512 and 8192. +SECONDARY_BUFFER_SIZE = 1024 +# Audio resampling algorithm. src-sinc-best-quality, src-sinc-medium-quality, src-sinc-fastest, src-zero-order-hold, src-linear, speex-fixed-{10-0}, trivial +RESAMPLE = "trivial" +# Volume control type: 1 = SDL (only affects Mupen64Plus output) 2 = OSS mixer (adjusts master PC volume) +VOLUME_CONTROL_TYPE = 1 +# Percentage change each time the volume is increased or decreased +VOLUME_ADJUST = 5 +# Default volume when a game is started. Only used if VOLUME_CONTROL_TYPE is 1 +VOLUME_DEFAULT = 100 +# Synchronize Video/Audio +AUDIO_SYNC = False + + +[Core] + +# Mupen64Plus Core config parameter set version number. Please don't change this version number. +Version = 1.010000 +# Draw on-screen display if True, otherwise don't draw OSD +OnScreenDisplay = True +# Use Pure Interpreter if 0, Cached Interpreter if 1, or Dynamic Recompiler if 2 or more +R4300Emulator = 2 +# Disable compiled jump commands in dynamic recompiler (should be set to False) +NoCompiledJump = False +# Disable 4MB expansion RAM pack. May be necessary for some games +DisableExtraMem = False +# Increment the save state slot after each save operation +AutoStateSlotIncrement = False +# Activate the R4300 debugger when ROM execution begins, if core was built with Debugger support +EnableDebugger = False +# Save state slot (0-9) to use when saving/loading the emulator state +CurrentStateSlot = 0 +# Path to directory where screenshots are saved. If this is blank, the default value of ${UserDataPath}/screenshot will be used +ScreenshotPath = "/storage/roms/n64" +# Path to directory where emulator save states (snapshots) are saved. If this is blank, the default value of ${UserDataPath}/save will be used +SaveStatePath = "/storage/roms/n64" +# Path to directory where SRAM/EEPROM data (in-game saves) are stored. If this is blank, the default value of ${UserDataPath}/save will be used +SaveSRAMPath = "/storage/roms/n64" +# Path to a directory to search when looking for shared data files +SharedDataPath = "/tmp/mupen64plussa" +# Force number of cycles per emulated instruction +CountPerOp = 0 +# Randomize PI/SI Interrupt Timing +RandomizeInterrupt = True +# Duration of SI DMA (-1: use per game settings) +SiDmaDuration = -1 +# Gameboy Camera Video Capture backend +GbCameraVideoCaptureBackend1 = "" +# Disk Save Format (0: Full Disk Copy (*.ndr/*.d6r), 1: RAM Area Only (*.ram)) +SaveDiskFormat = 1 + + +[CoreEvents] + +# Mupen64Plus CoreEvents config parameter set version number. Please don't change this version number. +Version = 1.000000 +# SDL keysym for stopping the emulator +Kbd Mapping Stop = 27 +# SDL keysym for switching between fullscreen/windowed modes +Kbd Mapping Fullscreen = 0 +# SDL keysym for saving the emulator state +Kbd Mapping Save State = 286 +# SDL keysym for loading the emulator state +Kbd Mapping Load State = 288 +# SDL keysym for advancing the save state slot +Kbd Mapping Increment Slot = 0 +# SDL keysym for resetting the emulator +Kbd Mapping Reset = 290 +# SDL keysym for slowing down the emulator +Kbd Mapping Speed Down = 291 +# SDL keysym for speeding up the emulator +Kbd Mapping Speed Up = 292 +# SDL keysym for taking a screenshot +Kbd Mapping Screenshot = 293 +# SDL keysym for pausing the emulator +Kbd Mapping Pause = 112 +# SDL keysym for muting/unmuting the sound +Kbd Mapping Mute = 109 +# SDL keysym for increasing the volume +Kbd Mapping Increase Volume = 93 +# SDL keysym for decreasing the volume +Kbd Mapping Decrease Volume = 91 +# SDL keysym for temporarily going really fast +Kbd Mapping Fast Forward = 102 +# SDL keysym for advancing by one frame when paused +Kbd Mapping Frame Advance = 47 +# SDL keysym for pressing the game shark button +Kbd Mapping Gameshark = 103 +# Joystick event string for stopping the emulator +Joy Mapping Stop = "J0B10/B9" +# Joystick event string for switching between fullscreen/windowed modes +Joy Mapping Fullscreen = "" +# Joystick event string for saving the emulator state +Joy Mapping Save State = "J0B10/B5" +# Joystick event string for loading the emulator state +Joy Mapping Load State = "J0B10/B4" +# Joystick event string for advancing the save state slot +Joy Mapping Increment Slot = "" +# Joystick event string for resetting the emulator +Joy Mapping Reset = "J0B10/B0" +# Joystick event string for slowing down the emulator +Joy Mapping Speed Down = "" +# Joystick event string for speeding up the emulator +Joy Mapping Speed Up = "" +# Joystick event string for taking a screenshot +Joy Mapping Screenshot = "J0B10/B3" +# Joystick event string for pausing the emulator +Joy Mapping Pause = "" +# Joystick event string for muting/unmuting the sound +Joy Mapping Mute = "" +# Joystick event string for increasing the volume +Joy Mapping Increase Volume = "" +# Joystick event string for decreasing the volume +Joy Mapping Decrease Volume = "" +# Joystick event string for fast-forward +Joy Mapping Fast Forward = "" +# Joystick event string for advancing by one frame when paused +Joy Mapping Frame Advance = "" +# Joystick event string for pressing the game shark button +Joy Mapping Gameshark = "" +# SDL keysym for save slot 0 +Kbd Mapping Slot 0 = 48 +# SDL keysym for save slot 1 +Kbd Mapping Slot 1 = 49 +# SDL keysym for save slot 2 +Kbd Mapping Slot 2 = 50 +# SDL keysym for save slot 3 +Kbd Mapping Slot 3 = 51 +# SDL keysym for save slot 4 +Kbd Mapping Slot 4 = 52 +# SDL keysym for save slot 5 +Kbd Mapping Slot 5 = 53 +# SDL keysym for save slot 6 +Kbd Mapping Slot 6 = 54 +# SDL keysym for save slot 7 +Kbd Mapping Slot 7 = 55 +# SDL keysym for save slot 8 +Kbd Mapping Slot 8 = 56 +# SDL keysym for save slot 9 +Kbd Mapping Slot 9 = 57 + + +[Input-SDL-Control1] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 0 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = 0 +# SDL joystick name (or Keyboard) +name = "retrogame_joypad_s1_f2" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = True +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "0,0" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = button(16) +DPad L = button(15) +DPad D = button(14) +DPad U = button(13) +Start = button(9) +Z Trig = button(6) +B Button = button(3) +A Button = button(0) +C Button R = button(1) +C Button L = +C Button D = +C Button U = button(2) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Input-SDL-Control2] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control3] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control4] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Rsp-HLE] + +# Mupen64Plus RSP HLE Plugin config parameter version number +Version = 1.000000 +# Path to a RSP plugin which will be used when encountering an unknown ucode.You can disable this by letting an empty string. +RspFallback = "" +# Send display lists to the graphics plugin +DisplayListToGraphicsPlugin = True +# Send audio lists to the audio plugin +AudioListToAudioPlugin = False + + +[Transferpak] + +# Filename of the GB ROM to load into transferpak 1 +GB-rom-1 = "" +# Filename of the GB RAM to load into transferpak 1 +GB-ram-1 = "" +# Filename of the GB ROM to load into transferpak 2 +GB-rom-2 = "" +# Filename of the GB RAM to load into transferpak 2 +GB-ram-2 = "" +# Filename of the GB ROM to load into transferpak 3 +GB-rom-3 = "" +# Filename of the GB RAM to load into transferpak 3 +GB-ram-3 = "" +# Filename of the GB ROM to load into transferpak 4 +GB-rom-4 = "" +# Filename of the GB RAM to load into transferpak 4 +GB-ram-4 = "" + + +[UI-Console] + +# Mupen64Plus UI-Console config parameter set version number. Please don't change this version number. +Version = 1.000000 +# Directory in which to search for plugins +PluginDir = "/usr/local/lib/mupen64plus" +# Filename of video plugin +VideoPlugin = "mupen64plus-video-rice" +# Filename of audio plugin +AudioPlugin = "mupen64plus-audio-sdl.so" +# Filename of input plugin +InputPlugin = "mupen64plus-input-sdl.so" +# Filename of RSP plugin +RspPlugin = "mupen64plus-rsp-hle.so" + + +[Video-General] + +# Width of output window or fullscreen width +ScreenWidth = 427 +# Height of output window or fullscreen height +ScreenHeight = 320 +# Use fullscreen mode if True, or windowed mode if False +Fullscreen = True +# If true, activate the SDL_GL_SWAP_CONTROL attribute +VerticalSync = True +# Rotate screen contents: 0=0 degree, 1=90 degree, 2 = 180 degree, 3=270 degree +Rotate = 0 + +[Video-GLideN64] + +###### Hardware Compatibility ###### +# Leave enabled unless a mobile gpu doesn't support it. +EnableFragmentDepthWrite = 0 +# Hardware per pixel lighting, supposedly good for GLES3.1 devices or higher. +EnableHWLighting = 0 + +###### Enhancements ####### +# Internal render resoluton rather than output. So 2 x 240p is 480p, etc. +UseNativeResolutionFactor = 1 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Enable/Disable Fast Approximate Anti-Aliasing FXAA +FXAA = 0 +# Max level of Anisotropic Filtering, 0 for off +anisotropy = 0 +# Bilinear filtering mode (0=N64 3point, 1=standard) +# @rishooty: best to use this at 1x native res, any higher turn it off. +bilinearMode = 1 + +###### Compatibility ###### +# Make texrect coordinates continuous to avoid black lines between them. (0=Off/default, 1=Auto, 2=Force) +CorrectTexrectCoords = 1 +# Copy auxiliary buffers to RDRAM (default: 0) +EnableCopyAuxiliaryToRDRAM = 1 +# Render 2D texrects in native resolution to fix misalignment between parts of 2D image. (0=Off/default, 1=Optimized, 2=Unoptimized)") +EnableNativeResTexrects = 1 + +###### Other ###### +# Enable threaded video backend at the cost of input lag +ThreadedVideo = 1 +# Screen aspect ratio (0=stretch, 1=force 4:3, 2=force 16:9, 3=adjust) +AspectRatio = 1 +# Display On-screen FPS +ShowFPS = False + +[Video-Glide64mk2] + +# Enable full-scene anti-aliasing by setting this to a value greater than 1 +wrpAntiAliasing = 0 +# Card ID +card_id = 0 +# If true, use polygon offset values specified below +force_polygon_offset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +polygon_offset_factor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +polygon_offset_units = 0.000000 +# Vertical sync +vsync = True +# TODO:ssformat +ssformat = False +# Display performance stats (add together desired flags): 1=FPS counter, 2=VI/s counter, 4=% speed, 8=FPS transparent +show_fps = 0 +# Clock enabled +clock = False +# Clock is 24-hour +clock_24_hr = True +# Wrapper resolution +wrpResolution = 0 +# Wrapper VRAM +wrpVRAM = 0 +# Wrapper FBO +wrpFBO = True +# Wrapper Anisotropic Filtering +wrpAnisotropic = True +# Texture Enhancement: Smooth/Sharpen Filters +ghq_fltr = 0 +# Texture Compression: 0 for S3TC, 1 for FXT1 +ghq_cmpr = 0 +# Texture Enhancement: More filters +ghq_enht = 0 +# Hi-res texture pack format (0 for none, 1 for Rice) +ghq_hirs = 1 +# Compress texture cache with S3TC or FXT1 +ghq_enht_cmpr = False +# Tile textures (saves memory but could cause issues) +ghq_enht_tile = 0 +# Force 16bpp textures (saves ram but lower quality) +ghq_enht_f16bpp = False +# Compress texture cache +ghq_enht_gz = True +# Don't enhance textures for backgrounds +ghq_enht_nobg = False +# Enable S3TC and FXT1 compression +ghq_hirs_cmpr = False +# Tile hi-res textures (saves memory but could cause issues) +ghq_hirs_tile = False +# Force 16bpp hi-res textures (saves ram but lower quality) +ghq_hirs_f16bpp = False +# Compress hi-res texture cache +ghq_hirs_gz = True +# Alternative CRC calculation -- emulates Rice bug +ghq_hirs_altcrc = True +# Save tex cache to disk +ghq_cache_save = True +# Texture Cache Size (MB) +ghq_cache_size = 128 +# Use full alpha channel -- could cause issues for some tex packs +ghq_hirs_let_texartists_fly = False +# Dump textures +ghq_hirs_dump = False +# Alternate texture size method: -1=Game default, 0=disable. 1=enable +alt_tex_size = -1 +# Use first SETTILESIZE only: -1=Game default, 0=disable. 1=enable +use_sts1_only = -1 +# Use spheric mapping only: -1=Game default, 0=disable. 1=enable +force_calc_sphere = -1 +# Force positive viewport: -1=Game default, 0=disable. 1=enable +correct_viewport = -1 +# Force texrect size to integral value: -1=Game default, 0=disable. 1=enable +increase_texrect_edge = -1 +# Reduce fillrect size by 1: -1=Game default, 0=disable. 1=enable +decrease_fillrect_edge = -1 +# Enable perspective texture correction emulation: -1=Game default, 0=disable. 1=enable +texture_correction = -1 +# Set special scale for PAL games: -1=Game default, 0=disable. 1=enable +pal230 = -1 +# 3DFX Dithered alpha emulation mode: -1=Game default, >=0=dithered alpha emulation mode +stipple_mode = -1 +# 3DFX Dithered alpha pattern: -1=Game default, >=0=pattern used for dithered alpha emulation +stipple_pattern = -1 +# Check microcode each frame: -1=Game default, 0=disable. 1=enable +force_microcheck = -1 +# Force 0xb5 command to be quad, not line 3D: -1=Game default, 0=disable. 1=enable +force_quad3d = -1 +# Enable near z clipping: -1=Game default, 0=disable. 1=enable +clip_zmin = -1 +# Enable far plane clipping: -1=Game default, 0=disable. 1=enable +clip_zmax = -1 +# Use fast CRC algorithm: -1=Game default, 0=disable. 1=enable +fast_crc = -1 +# Adjust screen aspect for wide screen mode: -1=Game default, 0=disable. 1=enable +adjust_aspect = -1 +# Force strict check in Depth buffer test: -1=Game default, 0=disable. 1=enable +zmode_compare_less = -1 +# Apply alpha dither regardless of alpha_dither_mode: -1=Game default, 0=disable. 1=enable +old_style_adither = -1 +# Scale vertex z value before writing to depth buffer: -1=Game default, 0=disable. 1=enable +n64_z_scale = -1 +# Fast texrect rendering with hwfbe: -1=Game default, 0=disable. 1=enable +optimize_texrect = -1 +# Do not copy auxiliary frame buffers: -1=Game default, 0=disable. 1=enable +ignore_aux_copy = -1 +# Clear auxiliary texture frame buffers: -1=Game default, 0=disable. 1=enable +hires_buf_clear = -1 +# Read alpha from framebuffer: -1=Game default, 0=disable. 1=enable +fb_read_alpha = -1 +# Handle unchanged fb: -1=Game default, 0=disable. 1=enable +useless_is_useless = -1 +# Set frambuffer CRC mode: -1=Game default, 0=disable CRC, 1=fast CRC, 2=safe CRC +fb_crc_mode = -1 +# Filtering mode: -1=Game default, 0=automatic, 1=force bilinear, 2=force point sampled +filtering = -1 +# Fog: -1=Game default, 0=disable. 1=enable +fog = -1 +# Buffer clear on every frame: -1=Game default, 0=disable. 1=enable +buff_clear = -1 +# Buffer swapping method: -1=Game default, 0=swap buffers when vertical interrupt has occurred, 1=swap buffers when set of conditions is satisfied. Prevents flicker on some games, 2=mix of first two methods +swapmode = -1 +# Aspect ratio: -1=Game default, 0=Force 4:3, 1=Force 16:9, 2=Stretch, 3=Original +aspect = -1 +# LOD calculation: -1=Game default, 0=disable. 1=fast, 2=precise +lodmode = -1 +# Smart framebuffer: -1=Game default, 0=disable. 1=enable +fb_smart = -1 +# Hardware frame buffer emulation: -1=Game default, 0=disable. 1=enable +fb_hires = -1 +# Read framebuffer every frame (may be slow use only for effects that need it e.g. Banjo Kazooie, DK64 transitions): -1=Game default, 0=disable. 1=enable +fb_read_always = -1 +# Render N64 frame buffer as texture: -1=Game default, 0=disable, 1=mode1, 2=mode2 +read_back_to_screen = -1 +# Show images written directly by CPU: -1=Game default, 0=disable. 1=enable +detect_cpu_write = -1 +# Get frame buffer info: -1=Game default, 0=disable. 1=enable +fb_get_info = -1 +# Enable software depth render: -1=Game default, 0=disable. 1=enable +fb_render = -1 +# If true, skip up to maxframeskip frames to maintain clock schedule; if false, skip exactly maxframeskip frames +autoframeskip = False +# If autoframeskip is true, skip up to this many frames to maintain clock schedule; if autoframeskip is false, skip exactly this many frames +maxframeskip = 0 + + +[Video-Rice] + +# Hack to accomodate widescreen devices +ResolutionWidth = 480 +# Mupen64Plus Rice Video Plugin config parameter version number +Version = 1 +# Frame Buffer Emulation (0=ROM default, 1=disable) +FrameBufferSetting = 0 +# Frequency to write back the frame buffer (0=every frame, 1=every other frame, etc) +FrameBufferWriteBackControl = 0 +# Render-to-texture emulation (0=none, 1=ignore, 2=normal, 3=write back, 4=write back and reload) +RenderToTexture = 0 +# Control when the screen will be updated (0=ROM default, 1=VI origin update, 2=VI origin change, 3=CI change, 4=first CI change, 5=first primitive draw, 6=before screen clear, 7=after screen drawn) +ScreenUpdateSetting = 4 +# Force to use normal alpha blender +NormalAlphaBlender = False +# Use a faster algorithm to speed up texture loading and CRC computation +FastTextureLoading = False +# Use different texture coordinate clamping code +AccurateTextureMapping = True +# Force emulated frame buffers to be in N64 native resolution +InN64Resolution = False +# Try to reduce Video RAM usage (should never be used) +SaveVRAM = False +# Enable this option to have better render-to-texture quality +DoubleSizeForSmallTxtrBuf = False +# Force to use normal color combiner +DefaultCombinerDisable = False +# Enable game-specific settings from INI file +EnableHacks = True +# If enabled, graphics will be drawn in WinFrame mode instead of solid and texture mode +WinFrameMode = False +# N64 Texture Memory Full Emulation (may fix some games, may break others) +FullTMEMEmulation = False +# Enable vertex clipper for fog operations +OpenGLVertexClipper = False +# Enable/Disable SSE optimizations for capable CPUs +EnableSSE = True +# If this option is enabled, the plugin will skip every other frame +SkipFrame = False +# If enabled, texture enhancement will be done only for TxtRect ucode +TexRectOnly = False +# If enabled, texture enhancement will be done only for textures width+height<=128 +SmallTextureOnly = False +# Select hi-resolution textures based only on the CRC and ignore format+size information (Glide64 compatibility) +LoadHiResCRCOnly = True +# Enable hi-resolution texture file loading +LoadHiResTextures = False +# Enable texture dumping +DumpTexturesToFiles = False +# Display On-screen FPS +ShowFPS = False +# Use Mipmapping? 0=no, 1=nearest, 2=bilinear, 3=trilinear +Mipmapping = 2 +# Enable, Disable fog generation (0=Disable, 1=Enable) +FogMethod = 1 +# Force to use texture filtering or not (0=auto: n64 choose, 1=force no filtering, 2=force filtering) +ForceTextureFilter = 0 +# Primary texture enhancement filter (0=None, 1=2X, 2=2XSAI, 3=HQ2X, 4=LQ2X, 5=HQ4X, 6=Sharpen, 7=Sharpen More, 8=External, 9=Mirrored) +TextureEnhancement = 0 +# Secondary texture enhancement filter (0 = none, 1-4 = filtered) +TextureEnhancementControl = 0 +# Color bit depth to use for textures (0=default, 1=32 bits, 2=16 bits) +TextureQuality = 0 +# Z-buffer depth (only 16 or 32) +OpenGLDepthBufferSetting = 16 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Color bit depth for rendering window (0=32 bits, 1=16 bits) +ColorQuality = 1 +# OpenGL level to support (0=auto, 1=OGL_FRAGMENT_PROGRAM) +OpenGLRenderSetting = 0 +# Enable/Disable Anisotropic Filtering for Mipmapping (0=no filtering, 2-16=quality). This is uneffective if Mipmapping is 0. If the given value is to high to be supported by your graphic card, the value will be the highest value your graphic card can support. Better result with Trilinear filtering +AnisotropicFiltering = 0 +# If true, use polygon offset values specified below +ForcePolygonOffset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +PolygonOffsetFactor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +PolygonOffsetUnits = 0.000000 diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3326/mupen64plus.cfg.xut b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3326/mupen64plus.cfg.xut new file mode 100644 index 0000000000..32d61c6265 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3326/mupen64plus.cfg.xut @@ -0,0 +1,670 @@ +# Mupen64Plus Configuration File +# This file is automatically read and written by the Mupen64Plus Core library + +[64DD] + +# Filename of the 64DD IPL ROM +IPL-ROM = "" +# Filename of the disk to load into Disk Drive +Disk = "" + + +[Audio-SDL] + +# Mupen64Plus SDL Audio Plugin config parameter version number +Version = 1.000000 +# Frequency which is used if rom doesn't want to change it +DEFAULT_FREQUENCY = 33600 +# Swaps left and right channels +SWAP_CHANNELS = False +# Size of primary buffer in output samples. This is where audio is loaded after it's extracted from n64's memory. +PRIMARY_BUFFER_SIZE = 16384 +# Fullness level target for Primary audio buffer, in equivalent output samples. This value must be larger than the SECONDARY_BUFFER_SIZE. Decreasing this value will reduce audio latency but requires a faster PC to avoid choppiness. Increasing this will increase audio latency but reduce the chance of drop-outs. +PRIMARY_BUFFER_TARGET = 2048 +# Size of secondary buffer in output samples. This is SDL's hardware buffer. The SDL documentation states that this should be a power of two between 512 and 8192. +SECONDARY_BUFFER_SIZE = 1024 +# Audio resampling algorithm. src-sinc-best-quality, src-sinc-medium-quality, src-sinc-fastest, src-zero-order-hold, src-linear, speex-fixed-{10-0}, trivial +RESAMPLE = "trivial" +# Volume control type: 1 = SDL (only affects Mupen64Plus output) 2 = OSS mixer (adjusts master PC volume) +VOLUME_CONTROL_TYPE = 1 +# Percentage change each time the volume is increased or decreased +VOLUME_ADJUST = 5 +# Default volume when a game is started. Only used if VOLUME_CONTROL_TYPE is 1 +VOLUME_DEFAULT = 100 +# Synchronize Video/Audio +AUDIO_SYNC = False + + +[Core] + +# Mupen64Plus Core config parameter set version number. Please don't change this version number. +Version = 1.010000 +# Draw on-screen display if True, otherwise don't draw OSD +OnScreenDisplay = True +# Use Pure Interpreter if 0, Cached Interpreter if 1, or Dynamic Recompiler if 2 or more +R4300Emulator = 2 +# Disable compiled jump commands in dynamic recompiler (should be set to False) +NoCompiledJump = False +# Disable 4MB expansion RAM pack. May be necessary for some games +DisableExtraMem = False +# Increment the save state slot after each save operation +AutoStateSlotIncrement = False +# Activate the R4300 debugger when ROM execution begins, if core was built with Debugger support +EnableDebugger = False +# Save state slot (0-9) to use when saving/loading the emulator state +CurrentStateSlot = 0 +# Path to directory where screenshots are saved. If this is blank, the default value of ${UserDataPath}/screenshot will be used +ScreenshotPath = "/storage/roms/n64" +# Path to directory where emulator save states (snapshots) are saved. If this is blank, the default value of ${UserDataPath}/save will be used +SaveStatePath = "/storage/roms/n64" +# Path to directory where SRAM/EEPROM data (in-game saves) are stored. If this is blank, the default value of ${UserDataPath}/save will be used +SaveSRAMPath = "/storage/roms/n64" +# Path to a directory to search when looking for shared data files +SharedDataPath = "/tmp/mupen64plussa" +# Force number of cycles per emulated instruction +CountPerOp = 0 +# Randomize PI/SI Interrupt Timing +RandomizeInterrupt = True +# Duration of SI DMA (-1: use per game settings) +SiDmaDuration = -1 +# Gameboy Camera Video Capture backend +GbCameraVideoCaptureBackend1 = "" +# Disk Save Format (0: Full Disk Copy (*.ndr/*.d6r), 1: RAM Area Only (*.ram)) +SaveDiskFormat = 1 + + +[CoreEvents] + +# Mupen64Plus CoreEvents config parameter set version number. Please don't change this version number. +Version = 1.000000 +# SDL keysym for stopping the emulator +Kbd Mapping Stop = 27 +# SDL keysym for switching between fullscreen/windowed modes +Kbd Mapping Fullscreen = 0 +# SDL keysym for saving the emulator state +Kbd Mapping Save State = 286 +# SDL keysym for loading the emulator state +Kbd Mapping Load State = 288 +# SDL keysym for advancing the save state slot +Kbd Mapping Increment Slot = 0 +# SDL keysym for resetting the emulator +Kbd Mapping Reset = 290 +# SDL keysym for slowing down the emulator +Kbd Mapping Speed Down = 291 +# SDL keysym for speeding up the emulator +Kbd Mapping Speed Up = 292 +# SDL keysym for taking a screenshot +Kbd Mapping Screenshot = 293 +# SDL keysym for pausing the emulator +Kbd Mapping Pause = 112 +# SDL keysym for muting/unmuting the sound +Kbd Mapping Mute = 109 +# SDL keysym for increasing the volume +Kbd Mapping Increase Volume = 93 +# SDL keysym for decreasing the volume +Kbd Mapping Decrease Volume = 91 +# SDL keysym for temporarily going really fast +Kbd Mapping Fast Forward = 102 +# SDL keysym for advancing by one frame when paused +Kbd Mapping Frame Advance = 47 +# SDL keysym for pressing the game shark button +Kbd Mapping Gameshark = 103 +# Joystick event string for stopping the emulator +Joy Mapping Stop = "J0B16/B9" +# Joystick event string for switching between fullscreen/windowed modes +Joy Mapping Fullscreen = "" +# Joystick event string for saving the emulator state +Joy Mapping Save State = "J0B16/B5" +# Joystick event string for loading the emulator state +Joy Mapping Load State = "J0B16/B4" +# Joystick event string for advancing the save state slot +Joy Mapping Increment Slot = "" +# Joystick event string for resetting the emulator +Joy Mapping Reset = "" +# Joystick event string for slowing down the emulator +Joy Mapping Speed Down = "" +# Joystick event string for speeding up the emulator +Joy Mapping Speed Up = "" +# Joystick event string for taking a screenshot +Joy Mapping Screenshot = "" +# Joystick event string for pausing the emulator +Joy Mapping Pause = "J0B16/B0" +# Joystick event string for muting/unmuting the sound +Joy Mapping Mute = "" +# Joystick event string for increasing the volume +Joy Mapping Increase Volume = "" +# Joystick event string for decreasing the volume +Joy Mapping Decrease Volume = "" +# Joystick event string for fast-forward +Joy Mapping Fast Forward = "J0B16/B15" +# Joystick event string for advancing by one frame when paused +Joy Mapping Frame Advance = "" +# Joystick event string for pressing the game shark button +Joy Mapping Gameshark = "" +# SDL keysym for save slot 0 +Kbd Mapping Slot 0 = 48 +# SDL keysym for save slot 1 +Kbd Mapping Slot 1 = 49 +# SDL keysym for save slot 2 +Kbd Mapping Slot 2 = 50 +# SDL keysym for save slot 3 +Kbd Mapping Slot 3 = 51 +# SDL keysym for save slot 4 +Kbd Mapping Slot 4 = 52 +# SDL keysym for save slot 5 +Kbd Mapping Slot 5 = 53 +# SDL keysym for save slot 6 +Kbd Mapping Slot 6 = 54 +# SDL keysym for save slot 7 +Kbd Mapping Slot 7 = 55 +# SDL keysym for save slot 8 +Kbd Mapping Slot 8 = 56 +# SDL keysym for save slot 9 +Kbd Mapping Slot 9 = 57 + + +[Input-SDL-Control1] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = 0 +# SDL joystick name (or Keyboard) +name = "XU10 Gamepad" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = True +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "0,0" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = button(15) +DPad L = button(14) +DPad D = button(13) +DPad U = button(12) +Start = button(9) +Z Trig = button(7) +B Button = button(0) +A Button = button(1) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Input-SDL-Control2] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control3] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control4] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Rsp-HLE] + +# Mupen64Plus RSP HLE Plugin config parameter version number +Version = 1.000000 +# Path to a RSP plugin which will be used when encountering an unknown ucode.You can disable this by letting an empty string. +RspFallback = "" +# Send display lists to the graphics plugin +DisplayListToGraphicsPlugin = True +# Send audio lists to the audio plugin +AudioListToAudioPlugin = False + + +[Transferpak] + +# Filename of the GB ROM to load into transferpak 1 +GB-rom-1 = "" +# Filename of the GB RAM to load into transferpak 1 +GB-ram-1 = "" +# Filename of the GB ROM to load into transferpak 2 +GB-rom-2 = "" +# Filename of the GB RAM to load into transferpak 2 +GB-ram-2 = "" +# Filename of the GB ROM to load into transferpak 3 +GB-rom-3 = "" +# Filename of the GB RAM to load into transferpak 3 +GB-ram-3 = "" +# Filename of the GB ROM to load into transferpak 4 +GB-rom-4 = "" +# Filename of the GB RAM to load into transferpak 4 +GB-ram-4 = "" + + +[UI-Console] + +# Mupen64Plus UI-Console config parameter set version number. Please don't change this version number. +Version = 1.000000 +# Directory in which to search for plugins +PluginDir = "/usr/local/lib/mupen64plus" +# Filename of video plugin +VideoPlugin = "mupen64plus-video-rice" +# Filename of audio plugin +AudioPlugin = "mupen64plus-audio-sdl.so" +# Filename of input plugin +InputPlugin = "mupen64plus-input-sdl.so" +# Filename of RSP plugin +RspPlugin = "mupen64plus-rsp-hle.so" + + +[Video-General] + +# Width of output window or fullscreen width +ScreenWidth = 427 +# Height of output window or fullscreen height +ScreenHeight = 320 +# Use fullscreen mode if True, or windowed mode if False +Fullscreen = True +# If true, activate the SDL_GL_SWAP_CONTROL attribute +VerticalSync = False +# Rotate screen contents: 0=0 degree, 1=90 degree, 2 = 180 degree, 3=270 degree +Rotate = 0 + +[Video-GLideN64] + +###### Hardware Compatibility ###### +# Leave enabled unless a mobile gpu doesn't support it. +EnableFragmentDepthWrite = 0 +# Hardware per pixel lighting, supposedly good for GLES3.1 devices or higher. +EnableHWLighting = 0 + +###### Enhancements ####### +# Internal render resoluton rather than output. So 2 x 240p is 480p, etc. +UseNativeResolutionFactor = 1 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Enable/Disable Fast Approximate Anti-Aliasing FXAA +FXAA = 0 +# Max level of Anisotropic Filtering, 0 for off +anisotropy = 0 +# Bilinear filtering mode (0=N64 3point, 1=standard) +# @rishooty: best to use this at 1x native res, any higher turn it off. +bilinearMode = 1 + +###### Compatibility ###### +# Make texrect coordinates continuous to avoid black lines between them. (0=Off/default, 1=Auto, 2=Force) +CorrectTexrectCoords = 1 +# Copy auxiliary buffers to RDRAM (default: 0) +EnableCopyAuxiliaryToRDRAM = 1 +# Render 2D texrects in native resolution to fix misalignment between parts of 2D image. (0=Off/default, 1=Optimized, 2=Unoptimized)") +EnableNativeResTexrects = 1 + +###### Other ###### +# Enable threaded video backend at the cost of input lag +ThreadedVideo = 1 +# Screen aspect ratio (0=stretch, 1=force 4:3, 2=force 16:9, 3=adjust) +AspectRatio = 1 +# Display On-screen FPS +ShowFPS = False + +[Video-Glide64mk2] + +# Enable full-scene anti-aliasing by setting this to a value greater than 1 +wrpAntiAliasing = 0 +# Card ID +card_id = 0 +# If true, use polygon offset values specified below +force_polygon_offset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +polygon_offset_factor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +polygon_offset_units = 0.000000 +# Vertical sync +vsync = True +# TODO:ssformat +ssformat = False +# Display performance stats (add together desired flags): 1=FPS counter, 2=VI/s counter, 4=% speed, 8=FPS transparent +show_fps = 0 +# Clock enabled +clock = False +# Clock is 24-hour +clock_24_hr = True +# Wrapper resolution +wrpResolution = 0 +# Wrapper VRAM +wrpVRAM = 0 +# Wrapper FBO +wrpFBO = True +# Wrapper Anisotropic Filtering +wrpAnisotropic = True +# Texture Enhancement: Smooth/Sharpen Filters +ghq_fltr = 0 +# Texture Compression: 0 for S3TC, 1 for FXT1 +ghq_cmpr = 0 +# Texture Enhancement: More filters +ghq_enht = 0 +# Hi-res texture pack format (0 for none, 1 for Rice) +ghq_hirs = 1 +# Compress texture cache with S3TC or FXT1 +ghq_enht_cmpr = False +# Tile textures (saves memory but could cause issues) +ghq_enht_tile = 0 +# Force 16bpp textures (saves ram but lower quality) +ghq_enht_f16bpp = False +# Compress texture cache +ghq_enht_gz = True +# Don't enhance textures for backgrounds +ghq_enht_nobg = False +# Enable S3TC and FXT1 compression +ghq_hirs_cmpr = False +# Tile hi-res textures (saves memory but could cause issues) +ghq_hirs_tile = False +# Force 16bpp hi-res textures (saves ram but lower quality) +ghq_hirs_f16bpp = False +# Compress hi-res texture cache +ghq_hirs_gz = True +# Alternative CRC calculation -- emulates Rice bug +ghq_hirs_altcrc = True +# Save tex cache to disk +ghq_cache_save = True +# Texture Cache Size (MB) +ghq_cache_size = 128 +# Use full alpha channel -- could cause issues for some tex packs +ghq_hirs_let_texartists_fly = False +# Dump textures +ghq_hirs_dump = False +# Alternate texture size method: -1=Game default, 0=disable. 1=enable +alt_tex_size = -1 +# Use first SETTILESIZE only: -1=Game default, 0=disable. 1=enable +use_sts1_only = -1 +# Use spheric mapping only: -1=Game default, 0=disable. 1=enable +force_calc_sphere = -1 +# Force positive viewport: -1=Game default, 0=disable. 1=enable +correct_viewport = -1 +# Force texrect size to integral value: -1=Game default, 0=disable. 1=enable +increase_texrect_edge = -1 +# Reduce fillrect size by 1: -1=Game default, 0=disable. 1=enable +decrease_fillrect_edge = -1 +# Enable perspective texture correction emulation: -1=Game default, 0=disable. 1=enable +texture_correction = -1 +# Set special scale for PAL games: -1=Game default, 0=disable. 1=enable +pal230 = -1 +# 3DFX Dithered alpha emulation mode: -1=Game default, >=0=dithered alpha emulation mode +stipple_mode = -1 +# 3DFX Dithered alpha pattern: -1=Game default, >=0=pattern used for dithered alpha emulation +stipple_pattern = -1 +# Check microcode each frame: -1=Game default, 0=disable. 1=enable +force_microcheck = -1 +# Force 0xb5 command to be quad, not line 3D: -1=Game default, 0=disable. 1=enable +force_quad3d = -1 +# Enable near z clipping: -1=Game default, 0=disable. 1=enable +clip_zmin = -1 +# Enable far plane clipping: -1=Game default, 0=disable. 1=enable +clip_zmax = -1 +# Use fast CRC algorithm: -1=Game default, 0=disable. 1=enable +fast_crc = -1 +# Adjust screen aspect for wide screen mode: -1=Game default, 0=disable. 1=enable +adjust_aspect = -1 +# Force strict check in Depth buffer test: -1=Game default, 0=disable. 1=enable +zmode_compare_less = -1 +# Apply alpha dither regardless of alpha_dither_mode: -1=Game default, 0=disable. 1=enable +old_style_adither = -1 +# Scale vertex z value before writing to depth buffer: -1=Game default, 0=disable. 1=enable +n64_z_scale = -1 +# Fast texrect rendering with hwfbe: -1=Game default, 0=disable. 1=enable +optimize_texrect = -1 +# Do not copy auxiliary frame buffers: -1=Game default, 0=disable. 1=enable +ignore_aux_copy = -1 +# Clear auxiliary texture frame buffers: -1=Game default, 0=disable. 1=enable +hires_buf_clear = -1 +# Read alpha from framebuffer: -1=Game default, 0=disable. 1=enable +fb_read_alpha = -1 +# Handle unchanged fb: -1=Game default, 0=disable. 1=enable +useless_is_useless = -1 +# Set frambuffer CRC mode: -1=Game default, 0=disable CRC, 1=fast CRC, 2=safe CRC +fb_crc_mode = -1 +# Filtering mode: -1=Game default, 0=automatic, 1=force bilinear, 2=force point sampled +filtering = -1 +# Fog: -1=Game default, 0=disable. 1=enable +fog = -1 +# Buffer clear on every frame: -1=Game default, 0=disable. 1=enable +buff_clear = -1 +# Buffer swapping method: -1=Game default, 0=swap buffers when vertical interrupt has occurred, 1=swap buffers when set of conditions is satisfied. Prevents flicker on some games, 2=mix of first two methods +swapmode = -1 +# Aspect ratio: -1=Game default, 0=Force 4:3, 1=Force 16:9, 2=Stretch, 3=Original +aspect = -1 +# LOD calculation: -1=Game default, 0=disable. 1=fast, 2=precise +lodmode = -1 +# Smart framebuffer: -1=Game default, 0=disable. 1=enable +fb_smart = -1 +# Hardware frame buffer emulation: -1=Game default, 0=disable. 1=enable +fb_hires = -1 +# Read framebuffer every frame (may be slow use only for effects that need it e.g. Banjo Kazooie, DK64 transitions): -1=Game default, 0=disable. 1=enable +fb_read_always = -1 +# Render N64 frame buffer as texture: -1=Game default, 0=disable, 1=mode1, 2=mode2 +read_back_to_screen = -1 +# Show images written directly by CPU: -1=Game default, 0=disable. 1=enable +detect_cpu_write = -1 +# Get frame buffer info: -1=Game default, 0=disable. 1=enable +fb_get_info = -1 +# Enable software depth render: -1=Game default, 0=disable. 1=enable +fb_render = -1 +# If true, skip up to maxframeskip frames to maintain clock schedule; if false, skip exactly maxframeskip frames +autoframeskip = False +# If autoframeskip is true, skip up to this many frames to maintain clock schedule; if autoframeskip is false, skip exactly this many frames +maxframeskip = 0 + + +[Video-Rice] + +# Hack to accomodate widescreen devices +ResolutionWidth = 480 +# Mupen64Plus Rice Video Plugin config parameter version number +Version = 1 +# Frame Buffer Emulation (0=ROM default, 1=disable) +FrameBufferSetting = 0 +# Frequency to write back the frame buffer (0=every frame, 1=every other frame, etc) +FrameBufferWriteBackControl = 0 +# Render-to-texture emulation (0=none, 1=ignore, 2=normal, 3=write back, 4=write back and reload) +RenderToTexture = 0 +# Control when the screen will be updated (0=ROM default, 1=VI origin update, 2=VI origin change, 3=CI change, 4=first CI change, 5=first primitive draw, 6=before screen clear, 7=after screen drawn) +ScreenUpdateSetting = 4 +# Force to use normal alpha blender +NormalAlphaBlender = False +# Use a faster algorithm to speed up texture loading and CRC computation +FastTextureLoading = True +# Use different texture coordinate clamping code +AccurateTextureMapping = False +# Force emulated frame buffers to be in N64 native resolution +InN64Resolution = False +# Try to reduce Video RAM usage (should never be used) +SaveVRAM = False +# Enable this option to have better render-to-texture quality +DoubleSizeForSmallTxtrBuf = False +# Force to use normal color combiner +DefaultCombinerDisable = False +# Enable game-specific settings from INI file +EnableHacks = True +# If enabled, graphics will be drawn in WinFrame mode instead of solid and texture mode +WinFrameMode = False +# N64 Texture Memory Full Emulation (may fix some games, may break others) +FullTMEMEmulation = False +# Enable vertex clipper for fog operations +OpenGLVertexClipper = False +# Enable/Disable SSE optimizations for capable CPUs +EnableSSE = True +# If this option is enabled, the plugin will skip every other frame +SkipFrame = False +# If enabled, texture enhancement will be done only for TxtRect ucode +TexRectOnly = False +# If enabled, texture enhancement will be done only for textures width+height<=128 +SmallTextureOnly = False +# Select hi-resolution textures based only on the CRC and ignore format+size information (Glide64 compatibility) +LoadHiResCRCOnly = True +# Enable hi-resolution texture file loading +LoadHiResTextures = False +# Enable texture dumping +DumpTexturesToFiles = False +# Display On-screen FPS +ShowFPS = False +# Use Mipmapping? 0=no, 1=nearest, 2=bilinear, 3=trilinear +Mipmapping = 0 +# Enable, Disable fog generation (0=Disable, 1=Enable) +FogMethod = 1 +# Force to use texture filtering or not (0=auto: n64 choose, 1=force no filtering, 2=force filtering) +ForceTextureFilter = 0 +# Primary texture enhancement filter (0=None, 1=2X, 2=2XSAI, 3=HQ2X, 4=LQ2X, 5=HQ4X, 6=Sharpen, 7=Sharpen More, 8=External, 9=Mirrored) +TextureEnhancement = 0 +# Secondary texture enhancement filter (0 = none, 1-4 = filtered) +TextureEnhancementControl = 0 +# Color bit depth to use for textures (0=default, 1=32 bits, 2=16 bits) +TextureQuality = 0 +# Z-buffer depth (only 16 or 32) +OpenGLDepthBufferSetting = 16 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Color bit depth for rendering window (0=32 bits, 1=16 bits) +ColorQuality = 1 +# OpenGL level to support (0=auto, 1=OGL_FRAGMENT_PROGRAM) +OpenGLRenderSetting = 0 +# Enable/Disable Anisotropic Filtering for Mipmapping (0=no filtering, 2-16=quality). This is uneffective if Mipmapping is 0. If the given value is to high to be supported by your graphic card, the value will be the highest value your graphic card can support. Better result with Trilinear filtering +AnisotropicFiltering = 0 +# If true, use polygon offset values specified below +ForcePolygonOffset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +PolygonOffsetFactor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +PolygonOffsetUnits = 0.000000 diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3399/mupen64plus.cfg b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3399/mupen64plus.cfg new file mode 100644 index 0000000000..c637c1119f --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3399/mupen64plus.cfg @@ -0,0 +1,665 @@ +# Mupen64Plus Configuration File +# This file is automatically read and written by the Mupen64Plus Core library + +[64DD] + +# Filename of the 64DD IPL ROM +IPL-ROM = "" +# Filename of the disk to load into Disk Drive +Disk = "" + + +[Audio-SDL] + +# Mupen64Plus SDL Audio Plugin config parameter version number +Version = 1.000000 +# Frequency which is used if rom doesn't want to change it +DEFAULT_FREQUENCY = 33600 +# Swaps left and right channels +SWAP_CHANNELS = False +# Size of primary buffer in output samples. This is where audio is loaded after it's extracted from n64's memory. +PRIMARY_BUFFER_SIZE = 16384 +# Fullness level target for Primary audio buffer, in equivalent output samples. This value must be larger than the SECONDARY_BUFFER_SIZE. Decreasing this value will reduce audio latency but requires a faster PC to avoid choppiness. Increasing this will increase audio latency but reduce the chance of drop-outs. +PRIMARY_BUFFER_TARGET = 2048 +# Size of secondary buffer in output samples. This is SDL's hardware buffer. The SDL documentation states that this should be a power of two between 512 and 8192. +SECONDARY_BUFFER_SIZE = 1024 +# Audio resampling algorithm. src-sinc-best-quality, src-sinc-medium-quality, src-sinc-fastest, src-zero-order-hold, src-linear, speex-fixed-{10-0}, trivial +RESAMPLE = "trivial" +# Volume control type: 1 = SDL (only affects Mupen64Plus output) 2 = OSS mixer (adjusts master PC volume) +VOLUME_CONTROL_TYPE = 1 +# Percentage change each time the volume is increased or decreased +VOLUME_ADJUST = 5 +# Default volume when a game is started. Only used if VOLUME_CONTROL_TYPE is 1 +VOLUME_DEFAULT = 100 +# Synchronize Video/Audio +AUDIO_SYNC = False + + +[Core] + +# Mupen64Plus Core config parameter set version number. Please don't change this version number. +Version = 1.010000 +# Draw on-screen display if True, otherwise don't draw OSD +OnScreenDisplay = True +# Use Pure Interpreter if 0, Cached Interpreter if 1, or Dynamic Recompiler if 2 or more +R4300Emulator = 2 +# Disable compiled jump commands in dynamic recompiler (should be set to False) +NoCompiledJump = False +# Disable 4MB expansion RAM pack. May be necessary for some games +DisableExtraMem = False +# Increment the save state slot after each save operation +AutoStateSlotIncrement = False +# Activate the R4300 debugger when ROM execution begins, if core was built with Debugger support +EnableDebugger = False +# Save state slot (0-9) to use when saving/loading the emulator state +CurrentStateSlot = 0 +# Path to directory where screenshots are saved. If this is blank, the default value of ${UserDataPath}/screenshot will be used +ScreenshotPath = "/storage/roms/screenshots" +# Path to directory where emulator save states (snapshots) are saved. If this is blank, the default value of ${UserDataPath}/save will be used +SaveStatePath = "/storage/roms/n64" +# Path to directory where SRAM/EEPROM data (in-game saves) are stored. If this is blank, the default value of ${UserDataPath}/save will be used +SaveSRAMPath = "/storage/roms/n64" +# Path to a directory to search when looking for shared data files +SharedDataPath = "/storage/.config/game/configs/mupen64plussa" +# Force number of cycles per emulated instruction +CountPerOp = 0 +# Randomize PI/SI Interrupt Timing +RandomizeInterrupt = True +# Duration of SI DMA (-1: use per game settings) +SiDmaDuration = -1 +# Gameboy Camera Video Capture backend +GbCameraVideoCaptureBackend1 = "" +# Disk Save Format (0: Full Disk Copy (*.ndr/*.d6r), 1: RAM Area Only (*.ram)) +SaveDiskFormat = 1 + + +[CoreEvents] + +# Mupen64Plus CoreEvents config parameter set version number. Please don't change this version number. +Version = 1.000000 +# SDL keysym for stopping the emulator +Kbd Mapping Stop = 27 +# SDL keysym for switching between fullscreen/windowed modes +Kbd Mapping Fullscreen = 0 +# SDL keysym for saving the emulator state +Kbd Mapping Save State = 286 +# SDL keysym for loading the emulator state +Kbd Mapping Load State = 288 +# SDL keysym for advancing the save state slot +Kbd Mapping Increment Slot = 0 +# SDL keysym for resetting the emulator +Kbd Mapping Reset = 290 +# SDL keysym for slowing down the emulator +Kbd Mapping Speed Down = 291 +# SDL keysym for speeding up the emulator +Kbd Mapping Speed Up = 292 +# SDL keysym for taking a screenshot +Kbd Mapping Screenshot = 293 +# SDL keysym for pausing the emulator +Kbd Mapping Pause = 112 +# SDL keysym for muting/unmuting the sound +Kbd Mapping Mute = 109 +# SDL keysym for increasing the volume +Kbd Mapping Increase Volume = 93 +# SDL keysym for decreasing the volume +Kbd Mapping Decrease Volume = 91 +# SDL keysym for temporarily going really fast +Kbd Mapping Fast Forward = 102 +# SDL keysym for advancing by one frame when paused +Kbd Mapping Frame Advance = 47 +# SDL keysym for pressing the game shark button +Kbd Mapping Gameshark = 103 +# Joystick event string for stopping the emulator +Joy Mapping Stop = "J0B8/B9" +# Joystick event string for switching between fullscreen/windowed modes +Joy Mapping Fullscreen = "" +# Joystick event string for saving the emulator state +Joy Mapping Save State = "J0B8/B5" +# Joystick event string for loading the emulator state +Joy Mapping Load State = "J0B8/B4" +# Joystick event string for advancing the save state slot +Joy Mapping Increment Slot = "" +# Joystick event string for resetting the emulator +Joy Mapping Reset = "J0B8/B0" +# Joystick event string for slowing down the emulator +Joy Mapping Speed Down = "" +# Joystick event string for speeding up the emulator +Joy Mapping Speed Up = "" +# Joystick event string for taking a screenshot +Joy Mapping Screenshot = "J0B8/B3" +# Joystick event string for pausing the emulator +Joy Mapping Pause = "J0B12/B1" +# Joystick event string for muting/unmuting the sound +Joy Mapping Mute = "" +# Joystick event string for increasing the volume +Joy Mapping Increase Volume = "" +# Joystick event string for decreasing the volume +Joy Mapping Decrease Volume = "" +# Joystick event string for fast-forward +Joy Mapping Fast Forward = "J0B8/B7" +# Joystick event string for advancing by one frame when paused +Joy Mapping Frame Advance = "" +# Joystick event string for pressing the game shark button +Joy Mapping Gameshark = "J0B8/B2" +# SDL keysym for save slot 0 +Kbd Mapping Slot 0 = 48 +# SDL keysym for save slot 1 +Kbd Mapping Slot 1 = 49 +# SDL keysym for save slot 2 +Kbd Mapping Slot 2 = 50 +# SDL keysym for save slot 3 +Kbd Mapping Slot 3 = 51 +# SDL keysym for save slot 4 +Kbd Mapping Slot 4 = 52 +# SDL keysym for save slot 5 +Kbd Mapping Slot 5 = 53 +# SDL keysym for save slot 6 +Kbd Mapping Slot 6 = 54 +# SDL keysym for save slot 7 +Kbd Mapping Slot 7 = 55 +# SDL keysym for save slot 8 +Kbd Mapping Slot 8 = 56 +# SDL keysym for save slot 9 +Kbd Mapping Slot 9 = 57 + + +[Input-SDL-Control1] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = 0 +# SDL joystick name (or Keyboard) +name = "rg552_joypad" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = True +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "0,0" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = button(16) +DPad L = button(15) +DPad D = button(14) +DPad U = button(13) +Start = button(9) +Z Trig = button(5) +B Button = button(3) +A Button = button(0) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(7) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + + +[Input-SDL-Control2] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control3] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control4] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Rsp-HLE] + +# Mupen64Plus RSP HLE Plugin config parameter version number +Version = 1.000000 +# Path to a RSP plugin which will be used when encountering an unknown ucode.You can disable this by letting an empty string. +RspFallback = "" +# Send display lists to the graphics plugin +DisplayListToGraphicsPlugin = True +# Send audio lists to the audio plugin +AudioListToAudioPlugin = False + + +[Transferpak] + +# Filename of the GB ROM to load into transferpak 1 +GB-rom-1 = "" +# Filename of the GB RAM to load into transferpak 1 +GB-ram-1 = "" +# Filename of the GB ROM to load into transferpak 2 +GB-rom-2 = "" +# Filename of the GB RAM to load into transferpak 2 +GB-ram-2 = "" +# Filename of the GB ROM to load into transferpak 3 +GB-rom-3 = "" +# Filename of the GB RAM to load into transferpak 3 +GB-ram-3 = "" +# Filename of the GB ROM to load into transferpak 4 +GB-rom-4 = "" +# Filename of the GB RAM to load into transferpak 4 +GB-ram-4 = "" + + +[UI-Console] + +# Mupen64Plus UI-Console config parameter set version number. Please don't change this version number. +Version = 1.000000 +# Directory in which to search for plugins +PluginDir = "/usr/local/lib/mupen64plus" +# Filename of video plugin +VideoPlugin = "mupen64plus-video-rice" +# Filename of audio plugin +AudioPlugin = "mupen64plus-audio-sdl.so" +# Filename of input plugin +InputPlugin = "mupen64plus-input-sdl.so" +# Filename of RSP plugin +RspPlugin = "mupen64plus-rsp-hle.so" + + +[Video-General] + +# Width of output window or fullscreen width +ScreenWidth = 640 +# Height of output window or fullscreen height +ScreenHeight = 480 +# Use fullscreen mode if True, or windowed mode if False +Fullscreen = True +# If true, activate the SDL_GL_SWAP_CONTROL attribute +VerticalSync = True +# Rotate screen contents: 0=0 degree, 1=90 degree, 2 = 180 degree, 3=270 degree +Rotate = 0 + +[Video-GLideN64] + +###### Hardware Compatibility ###### +# Leave enabled unless a mobile gpu doesn't support it. +EnableFragmentDepthWrite = 1 +# Hardware per pixel lighting, supposedly good for GLES3.1 devices or higher. +EnableHWLighting = 0 + +###### Enhancements ####### +# Internal render resoluton rather than output. So 2 x 240p is 480p, etc. +UseNativeResolutionFactor = 1 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Enable/Disable Fast Approximate Anti-Aliasing FXAA +FXAA = 0 +# Max level of Anisotropic Filtering, 0 for off +anisotropy = 0 +# Bilinear filtering mode (0=N64 3point, 1=standard) +# @rishooty: best to use this at 1x native res, any higher turn it off. +bilinearMode = 1 + +###### Compatibility ###### +# Make texrect coordinates continuous to avoid black lines between them. (0=Off/default, 1=Auto, 2=Force) +CorrectTexrectCoords = 1 +# Copy auxiliary buffers to RDRAM (default: 0) +EnableCopyAuxiliaryToRDRAM = 1 +# Render 2D texrects in native resolution to fix misalignment between parts of 2D image. (0=Off/default, 1=Optimized, 2=Unoptimized)") +EnableNativeResTexrects = 1 + +###### Other ###### +# Enable threaded video backend at the cost of input lag +ThreadedVideo = 1 +# Screen aspect ratio (0=stretch, 1=force 4:3, 2=force 16:9, 3=adjust) +AspectRatio = 1 +# Display On-screen FPS +ShowFPS = False + +[Video-Glide64mk2] + +# Enable full-scene anti-aliasing by setting this to a value greater than 1 +wrpAntiAliasing = 0 +# Card ID +card_id = 0 +# If true, use polygon offset values specified below +force_polygon_offset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +polygon_offset_factor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +polygon_offset_units = 0.000000 +# Vertical sync +vsync = True +# TODO:ssformat +ssformat = False +# Display performance stats (add together desired flags): 1=FPS counter, 2=VI/s counter, 4=% speed, 8=FPS transparent +show_fps = 0 +# Clock enabled +clock = False +# Clock is 24-hour +clock_24_hr = True +# Wrapper resolution +wrpResolution = 0 +# Wrapper VRAM +wrpVRAM = 0 +# Wrapper FBO +wrpFBO = True +# Wrapper Anisotropic Filtering +wrpAnisotropic = True +# Texture Enhancement: Smooth/Sharpen Filters +ghq_fltr = 0 +# Texture Compression: 0 for S3TC, 1 for FXT1 +ghq_cmpr = 0 +# Texture Enhancement: More filters +ghq_enht = 0 +# Hi-res texture pack format (0 for none, 1 for Rice) +ghq_hirs = 1 +# Compress texture cache with S3TC or FXT1 +ghq_enht_cmpr = False +# Tile textures (saves memory but could cause issues) +ghq_enht_tile = 0 +# Force 16bpp textures (saves ram but lower quality) +ghq_enht_f16bpp = False +# Compress texture cache +ghq_enht_gz = True +# Don't enhance textures for backgrounds +ghq_enht_nobg = False +# Enable S3TC and FXT1 compression +ghq_hirs_cmpr = False +# Tile hi-res textures (saves memory but could cause issues) +ghq_hirs_tile = False +# Force 16bpp hi-res textures (saves ram but lower quality) +ghq_hirs_f16bpp = False +# Compress hi-res texture cache +ghq_hirs_gz = True +# Alternative CRC calculation -- emulates Rice bug +ghq_hirs_altcrc = True +# Save tex cache to disk +ghq_cache_save = True +# Texture Cache Size (MB) +ghq_cache_size = 128 +# Use full alpha channel -- could cause issues for some tex packs +ghq_hirs_let_texartists_fly = False +# Dump textures +ghq_hirs_dump = False +# Alternate texture size method: -1=Game default, 0=disable. 1=enable +alt_tex_size = -1 +# Use first SETTILESIZE only: -1=Game default, 0=disable. 1=enable +use_sts1_only = -1 +# Use spheric mapping only: -1=Game default, 0=disable. 1=enable +force_calc_sphere = -1 +# Force positive viewport: -1=Game default, 0=disable. 1=enable +correct_viewport = -1 +# Force texrect size to integral value: -1=Game default, 0=disable. 1=enable +increase_texrect_edge = -1 +# Reduce fillrect size by 1: -1=Game default, 0=disable. 1=enable +decrease_fillrect_edge = -1 +# Enable perspective texture correction emulation: -1=Game default, 0=disable. 1=enable +texture_correction = -1 +# Set special scale for PAL games: -1=Game default, 0=disable. 1=enable +pal230 = -1 +# 3DFX Dithered alpha emulation mode: -1=Game default, >=0=dithered alpha emulation mode +stipple_mode = -1 +# 3DFX Dithered alpha pattern: -1=Game default, >=0=pattern used for dithered alpha emulation +stipple_pattern = -1 +# Check microcode each frame: -1=Game default, 0=disable. 1=enable +force_microcheck = -1 +# Force 0xb5 command to be quad, not line 3D: -1=Game default, 0=disable. 1=enable +force_quad3d = -1 +# Enable near z clipping: -1=Game default, 0=disable. 1=enable +clip_zmin = -1 +# Enable far plane clipping: -1=Game default, 0=disable. 1=enable +clip_zmax = -1 +# Use fast CRC algorithm: -1=Game default, 0=disable. 1=enable +fast_crc = -1 +# Adjust screen aspect for wide screen mode: -1=Game default, 0=disable. 1=enable +adjust_aspect = -1 +# Force strict check in Depth buffer test: -1=Game default, 0=disable. 1=enable +zmode_compare_less = -1 +# Apply alpha dither regardless of alpha_dither_mode: -1=Game default, 0=disable. 1=enable +old_style_adither = -1 +# Scale vertex z value before writing to depth buffer: -1=Game default, 0=disable. 1=enable +n64_z_scale = -1 +# Fast texrect rendering with hwfbe: -1=Game default, 0=disable. 1=enable +optimize_texrect = -1 +# Do not copy auxiliary frame buffers: -1=Game default, 0=disable. 1=enable +ignore_aux_copy = -1 +# Clear auxiliary texture frame buffers: -1=Game default, 0=disable. 1=enable +hires_buf_clear = -1 +# Read alpha from framebuffer: -1=Game default, 0=disable. 1=enable +fb_read_alpha = -1 +# Handle unchanged fb: -1=Game default, 0=disable. 1=enable +useless_is_useless = -1 +# Set frambuffer CRC mode: -1=Game default, 0=disable CRC, 1=fast CRC, 2=safe CRC +fb_crc_mode = -1 +# Filtering mode: -1=Game default, 0=automatic, 1=force bilinear, 2=force point sampled +filtering = -1 +# Fog: -1=Game default, 0=disable. 1=enable +fog = -1 +# Buffer clear on every frame: -1=Game default, 0=disable. 1=enable +buff_clear = -1 +# Buffer swapping method: -1=Game default, 0=swap buffers when vertical interrupt has occurred, 1=swap buffers when set of conditions is satisfied. Prevents flicker on some games, 2=mix of first two methods +swapmode = -1 +# Aspect ratio: -1=Game default, 0=Force 4:3, 1=Force 16:9, 2=Stretch, 3=Original +aspect = -1 +# LOD calculation: -1=Game default, 0=disable. 1=fast, 2=precise +lodmode = -1 +# Smart framebuffer: -1=Game default, 0=disable. 1=enable +fb_smart = -1 +# Hardware frame buffer emulation: -1=Game default, 0=disable. 1=enable +fb_hires = -1 +# Read framebuffer every frame (may be slow use only for effects that need it e.g. Banjo Kazooie, DK64 transitions): -1=Game default, 0=disable. 1=enable +fb_read_always = -1 +# Render N64 frame buffer as texture: -1=Game default, 0=disable, 1=mode1, 2=mode2 +read_back_to_screen = -1 +# Show images written directly by CPU: -1=Game default, 0=disable. 1=enable +detect_cpu_write = -1 +# Get frame buffer info: -1=Game default, 0=disable. 1=enable +fb_get_info = -1 +# Enable software depth render: -1=Game default, 0=disable. 1=enable +fb_render = -1 +# If true, skip up to maxframeskip frames to maintain clock schedule; if false, skip exactly maxframeskip frames +autoframeskip = False +# If autoframeskip is true, skip up to this many frames to maintain clock schedule; if autoframeskip is false, skip exactly this many frames +maxframeskip = 0 + + +[Video-Rice] + +# Mupen64Plus Rice Video Plugin config parameter version number +Version = 1 +# Frame Buffer Emulation (0=ROM default, 1=disable) +FrameBufferSetting = 0 +# Frequency to write back the frame buffer (0=every frame, 1=every other frame, etc) +FrameBufferWriteBackControl = 0 +# Render-to-texture emulation (0=none, 1=ignore, 2=normal, 3=write back, 4=write back and reload) +RenderToTexture = 0 +# Control when the screen will be updated (0=ROM default, 1=VI origin update, 2=VI origin change, 3=CI change, 4=first CI change, 5=first primitive draw, 6=before screen clear, 7=after screen drawn) +ScreenUpdateSetting = 4 +# Force to use normal alpha blender +NormalAlphaBlender = False +# Use a faster algorithm to speed up texture loading and CRC computation +FastTextureLoading = False +# Use different texture coordinate clamping code +AccurateTextureMapping = True +# Force emulated frame buffers to be in N64 native resolution +InN64Resolution = False +# Try to reduce Video RAM usage (should never be used) +SaveVRAM = False +# Enable this option to have better render-to-texture quality +DoubleSizeForSmallTxtrBuf = False +# Force to use normal color combiner +DefaultCombinerDisable = False +# Enable game-specific settings from INI file +EnableHacks = True +# If enabled, graphics will be drawn in WinFrame mode instead of solid and texture mode +WinFrameMode = False +# N64 Texture Memory Full Emulation (may fix some games, may break others) +FullTMEMEmulation = False +# Enable vertex clipper for fog operations +OpenGLVertexClipper = False +# Enable/Disable SSE optimizations for capable CPUs +EnableSSE = True +# If this option is enabled, the plugin will skip every other frame +SkipFrame = False +# If enabled, texture enhancement will be done only for TxtRect ucode +TexRectOnly = False +# If enabled, texture enhancement will be done only for textures width+height<=128 +SmallTextureOnly = False +# Select hi-resolution textures based only on the CRC and ignore format+size information (Glide64 compatibility) +LoadHiResCRCOnly = True +# Enable hi-resolution texture file loading +LoadHiResTextures = False +# Enable texture dumping +DumpTexturesToFiles = False +# Display On-screen FPS +ShowFPS = False +# Use Mipmapping? 0=no, 1=nearest, 2=bilinear, 3=trilinear +Mipmapping = 2 +# Enable, Disable fog generation (0=Disable, 1=Enable) +FogMethod = 1 +# Force to use texture filtering or not (0=auto: n64 choose, 1=force no filtering, 2=force filtering) +ForceTextureFilter = 0 +# Primary texture enhancement filter (0=None, 1=2X, 2=2XSAI, 3=HQ2X, 4=LQ2X, 5=HQ4X, 6=Sharpen, 7=Sharpen More, 8=External, 9=Mirrored) +TextureEnhancement = 0 +# Secondary texture enhancement filter (0 = none, 1-4 = filtered) +TextureEnhancementControl = 0 +# Color bit depth to use for textures (0=default, 1=32 bits, 2=16 bits) +TextureQuality = 0 +# Z-buffer depth (only 16 or 32) +OpenGLDepthBufferSetting = 16 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Color bit depth for rendering window (0=32 bits, 1=16 bits) +ColorQuality = 1 +# OpenGL level to support (0=auto, 1=OGL_FRAGMENT_PROGRAM) +OpenGLRenderSetting = 0 +# Enable/Disable Anisotropic Filtering for Mipmapping (0=no filtering, 2-16=quality). This is uneffective if Mipmapping is 0. If the given value is to high to be supported by your graphic card, the value will be the highest value your graphic card can support. Better result with Trilinear filtering +AnisotropicFiltering = 0 +# If true, use polygon offset values specified below +ForcePolygonOffset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +PolygonOffsetFactor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +PolygonOffsetUnits = 0.000000 diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3566/mupen64plus.cfg b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3566/mupen64plus.cfg new file mode 100644 index 0000000000..9eb571253b --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3566/mupen64plus.cfg @@ -0,0 +1,665 @@ +# Mupen64Plus Configuration File +# This file is automatically read and written by the Mupen64Plus Core library + +[64DD] + +# Filename of the 64DD IPL ROM +IPL-ROM = "" +# Filename of the disk to load into Disk Drive +Disk = "" + + +[Audio-SDL] + +# Mupen64Plus SDL Audio Plugin config parameter version number +Version = 1.000000 +# Frequency which is used if rom doesn't want to change it +DEFAULT_FREQUENCY = 33600 +# Swaps left and right channels +SWAP_CHANNELS = False +# Size of primary buffer in output samples. This is where audio is loaded after it's extracted from n64's memory. +PRIMARY_BUFFER_SIZE = 16384 +# Fullness level target for Primary audio buffer, in equivalent output samples. This value must be larger than the SECONDARY_BUFFER_SIZE. Decreasing this value will reduce audio latency but requires a faster PC to avoid choppiness. Increasing this will increase audio latency but reduce the chance of drop-outs. +PRIMARY_BUFFER_TARGET = 2048 +# Size of secondary buffer in output samples. This is SDL's hardware buffer. The SDL documentation states that this should be a power of two between 512 and 8192. +SECONDARY_BUFFER_SIZE = 1024 +# Audio resampling algorithm. src-sinc-best-quality, src-sinc-medium-quality, src-sinc-fastest, src-zero-order-hold, src-linear, speex-fixed-{10-0}, trivial +RESAMPLE = "trivial" +# Volume control type: 1 = SDL (only affects Mupen64Plus output) 2 = OSS mixer (adjusts master PC volume) +VOLUME_CONTROL_TYPE = 1 +# Percentage change each time the volume is increased or decreased +VOLUME_ADJUST = 5 +# Default volume when a game is started. Only used if VOLUME_CONTROL_TYPE is 1 +VOLUME_DEFAULT = 100 +# Synchronize Video/Audio +AUDIO_SYNC = False + + +[Core] + +# Mupen64Plus Core config parameter set version number. Please don't change this version number. +Version = 1.010000 +# Draw on-screen display if True, otherwise don't draw OSD +OnScreenDisplay = True +# Use Pure Interpreter if 0, Cached Interpreter if 1, or Dynamic Recompiler if 2 or more +R4300Emulator = 2 +# Disable compiled jump commands in dynamic recompiler (should be set to False) +NoCompiledJump = False +# Disable 4MB expansion RAM pack. May be necessary for some games +DisableExtraMem = False +# Increment the save state slot after each save operation +AutoStateSlotIncrement = False +# Activate the R4300 debugger when ROM execution begins, if core was built with Debugger support +EnableDebugger = False +# Save state slot (0-9) to use when saving/loading the emulator state +CurrentStateSlot = 0 +# Path to directory where screenshots are saved. If this is blank, the default value of ${UserDataPath}/screenshot will be used +ScreenshotPath = "/storage/roms/screenshots" +# Path to directory where emulator save states (snapshots) are saved. If this is blank, the default value of ${UserDataPath}/save will be used +SaveStatePath = "/storage/roms/n64" +# Path to directory where SRAM/EEPROM data (in-game saves) are stored. If this is blank, the default value of ${UserDataPath}/save will be used +SaveSRAMPath = "/storage/roms/n64" +# Path to a directory to search when looking for shared data files +SharedDataPath = "/storage/.config/game/configs/mupen64plussa" +# Force number of cycles per emulated instruction +CountPerOp = 0 +# Randomize PI/SI Interrupt Timing +RandomizeInterrupt = True +# Duration of SI DMA (-1: use per game settings) +SiDmaDuration = -1 +# Gameboy Camera Video Capture backend +GbCameraVideoCaptureBackend1 = "" +# Disk Save Format (0: Full Disk Copy (*.ndr/*.d6r), 1: RAM Area Only (*.ram)) +SaveDiskFormat = 1 + + +[CoreEvents] + +# Mupen64Plus CoreEvents config parameter set version number. Please don't change this version number. +Version = 1.000000 +# SDL keysym for stopping the emulator +Kbd Mapping Stop = 27 +# SDL keysym for switching between fullscreen/windowed modes +Kbd Mapping Fullscreen = 0 +# SDL keysym for saving the emulator state +Kbd Mapping Save State = 286 +# SDL keysym for loading the emulator state +Kbd Mapping Load State = 288 +# SDL keysym for advancing the save state slot +Kbd Mapping Increment Slot = 0 +# SDL keysym for resetting the emulator +Kbd Mapping Reset = 290 +# SDL keysym for slowing down the emulator +Kbd Mapping Speed Down = 291 +# SDL keysym for speeding up the emulator +Kbd Mapping Speed Up = 292 +# SDL keysym for taking a screenshot +Kbd Mapping Screenshot = 293 +# SDL keysym for pausing the emulator +Kbd Mapping Pause = 112 +# SDL keysym for muting/unmuting the sound +Kbd Mapping Mute = 109 +# SDL keysym for increasing the volume +Kbd Mapping Increase Volume = 93 +# SDL keysym for decreasing the volume +Kbd Mapping Decrease Volume = 91 +# SDL keysym for temporarily going really fast +Kbd Mapping Fast Forward = 102 +# SDL keysym for advancing by one frame when paused +Kbd Mapping Frame Advance = 47 +# SDL keysym for pressing the game shark button +Kbd Mapping Gameshark = 103 +# Joystick event string for stopping the emulator +Joy Mapping Stop = "J0B8/B9" +# Joystick event string for switching between fullscreen/windowed modes +Joy Mapping Fullscreen = "" +# Joystick event string for saving the emulator state +Joy Mapping Save State = "J0B8/B5" +# Joystick event string for loading the emulator state +Joy Mapping Load State = "J0B8/B4" +# Joystick event string for advancing the save state slot +Joy Mapping Increment Slot = "" +# Joystick event string for resetting the emulator +Joy Mapping Reset = "J0B8/B0" +# Joystick event string for slowing down the emulator +Joy Mapping Speed Down = "" +# Joystick event string for speeding up the emulator +Joy Mapping Speed Up = "" +# Joystick event string for taking a screenshot +Joy Mapping Screenshot = "J0B8/B3" +# Joystick event string for pausing the emulator +Joy Mapping Pause = "J0B12/B1" +# Joystick event string for muting/unmuting the sound +Joy Mapping Mute = "" +# Joystick event string for increasing the volume +Joy Mapping Increase Volume = "" +# Joystick event string for decreasing the volume +Joy Mapping Decrease Volume = "" +# Joystick event string for fast-forward +Joy Mapping Fast Forward = "J0B8/B7" +# Joystick event string for advancing by one frame when paused +Joy Mapping Frame Advance = "" +# Joystick event string for pressing the game shark button +Joy Mapping Gameshark = "J0B8/B2" +# SDL keysym for save slot 0 +Kbd Mapping Slot 0 = 48 +# SDL keysym for save slot 1 +Kbd Mapping Slot 1 = 49 +# SDL keysym for save slot 2 +Kbd Mapping Slot 2 = 50 +# SDL keysym for save slot 3 +Kbd Mapping Slot 3 = 51 +# SDL keysym for save slot 4 +Kbd Mapping Slot 4 = 52 +# SDL keysym for save slot 5 +Kbd Mapping Slot 5 = 53 +# SDL keysym for save slot 6 +Kbd Mapping Slot 6 = 54 +# SDL keysym for save slot 7 +Kbd Mapping Slot 7 = 55 +# SDL keysym for save slot 8 +Kbd Mapping Slot 8 = 56 +# SDL keysym for save slot 9 +Kbd Mapping Slot 9 = 57 + + +[Input-SDL-Control1] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = 0 +# SDL joystick name (or Keyboard) +name = "retrogame_joypad" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = True +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "0,0" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = button(16) +DPad L = button(15) +DPad D = button(14) +DPad U = button(13) +Start = button(9) +Z Trig = button(5) +B Button = button(3) +A Button = button(0) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(7) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + + +[Input-SDL-Control2] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control3] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control4] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Rsp-HLE] + +# Mupen64Plus RSP HLE Plugin config parameter version number +Version = 1.000000 +# Path to a RSP plugin which will be used when encountering an unknown ucode.You can disable this by letting an empty string. +RspFallback = "" +# Send display lists to the graphics plugin +DisplayListToGraphicsPlugin = True +# Send audio lists to the audio plugin +AudioListToAudioPlugin = False + + +[Transferpak] + +# Filename of the GB ROM to load into transferpak 1 +GB-rom-1 = "" +# Filename of the GB RAM to load into transferpak 1 +GB-ram-1 = "" +# Filename of the GB ROM to load into transferpak 2 +GB-rom-2 = "" +# Filename of the GB RAM to load into transferpak 2 +GB-ram-2 = "" +# Filename of the GB ROM to load into transferpak 3 +GB-rom-3 = "" +# Filename of the GB RAM to load into transferpak 3 +GB-ram-3 = "" +# Filename of the GB ROM to load into transferpak 4 +GB-rom-4 = "" +# Filename of the GB RAM to load into transferpak 4 +GB-ram-4 = "" + + +[UI-Console] + +# Mupen64Plus UI-Console config parameter set version number. Please don't change this version number. +Version = 1.000000 +# Directory in which to search for plugins +PluginDir = "/usr/local/lib/mupen64plus" +# Filename of video plugin +VideoPlugin = "mupen64plus-video-rice" +# Filename of audio plugin +AudioPlugin = "mupen64plus-audio-sdl.so" +# Filename of input plugin +InputPlugin = "mupen64plus-input-sdl.so" +# Filename of RSP plugin +RspPlugin = "mupen64plus-rsp-hle.so" + + +[Video-General] + +# Width of output window or fullscreen width +ScreenWidth = 640 +# Height of output window or fullscreen height +ScreenHeight = 480 +# Use fullscreen mode if True, or windowed mode if False +Fullscreen = True +# If true, activate the SDL_GL_SWAP_CONTROL attribute +VerticalSync = True +# Rotate screen contents: 0=0 degree, 1=90 degree, 2 = 180 degree, 3=270 degree +Rotate = 0 + +[Video-GLideN64] + +###### Hardware Compatibility ###### +# Leave enabled unless a mobile gpu doesn't support it. +EnableFragmentDepthWrite = 0 +# Hardware per pixel lighting, supposedly good for GLES3.1 devices or higher. +EnableHWLighting = 0 + +###### Enhancements ####### +# Internal render resoluton rather than output. So 2 x 240p is 480p, etc. +UseNativeResolutionFactor = 1 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Enable/Disable Fast Approximate Anti-Aliasing FXAA +FXAA = 0 +# Max level of Anisotropic Filtering, 0 for off +anisotropy = 0 +# Bilinear filtering mode (0=N64 3point, 1=standard) +# @rishooty: best to use this at 1x native res, any higher turn it off. +bilinearMode = 1 + +###### Compatibility ###### +# Make texrect coordinates continuous to avoid black lines between them. (0=Off/default, 1=Auto, 2=Force) +CorrectTexrectCoords = 1 +# Copy auxiliary buffers to RDRAM (default: 0) +EnableCopyAuxiliaryToRDRAM = 1 +# Render 2D texrects in native resolution to fix misalignment between parts of 2D image. (0=Off/default, 1=Optimized, 2=Unoptimized)") +EnableNativeResTexrects = 1 + +###### Other ###### +# Enable threaded video backend at the cost of input lag +ThreadedVideo = 1 +# Screen aspect ratio (0=stretch, 1=force 4:3, 2=force 16:9, 3=adjust) +AspectRatio = 1 +# Display On-screen FPS +ShowFPS = False + +[Video-Glide64mk2] + +# Enable full-scene anti-aliasing by setting this to a value greater than 1 +wrpAntiAliasing = 0 +# Card ID +card_id = 0 +# If true, use polygon offset values specified below +force_polygon_offset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +polygon_offset_factor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +polygon_offset_units = 0.000000 +# Vertical sync +vsync = True +# TODO:ssformat +ssformat = False +# Display performance stats (add together desired flags): 1=FPS counter, 2=VI/s counter, 4=% speed, 8=FPS transparent +show_fps = 0 +# Clock enabled +clock = False +# Clock is 24-hour +clock_24_hr = True +# Wrapper resolution +wrpResolution = 0 +# Wrapper VRAM +wrpVRAM = 0 +# Wrapper FBO +wrpFBO = True +# Wrapper Anisotropic Filtering +wrpAnisotropic = True +# Texture Enhancement: Smooth/Sharpen Filters +ghq_fltr = 0 +# Texture Compression: 0 for S3TC, 1 for FXT1 +ghq_cmpr = 0 +# Texture Enhancement: More filters +ghq_enht = 0 +# Hi-res texture pack format (0 for none, 1 for Rice) +ghq_hirs = 1 +# Compress texture cache with S3TC or FXT1 +ghq_enht_cmpr = False +# Tile textures (saves memory but could cause issues) +ghq_enht_tile = 0 +# Force 16bpp textures (saves ram but lower quality) +ghq_enht_f16bpp = False +# Compress texture cache +ghq_enht_gz = True +# Don't enhance textures for backgrounds +ghq_enht_nobg = False +# Enable S3TC and FXT1 compression +ghq_hirs_cmpr = False +# Tile hi-res textures (saves memory but could cause issues) +ghq_hirs_tile = False +# Force 16bpp hi-res textures (saves ram but lower quality) +ghq_hirs_f16bpp = False +# Compress hi-res texture cache +ghq_hirs_gz = True +# Alternative CRC calculation -- emulates Rice bug +ghq_hirs_altcrc = True +# Save tex cache to disk +ghq_cache_save = True +# Texture Cache Size (MB) +ghq_cache_size = 128 +# Use full alpha channel -- could cause issues for some tex packs +ghq_hirs_let_texartists_fly = False +# Dump textures +ghq_hirs_dump = False +# Alternate texture size method: -1=Game default, 0=disable. 1=enable +alt_tex_size = -1 +# Use first SETTILESIZE only: -1=Game default, 0=disable. 1=enable +use_sts1_only = -1 +# Use spheric mapping only: -1=Game default, 0=disable. 1=enable +force_calc_sphere = -1 +# Force positive viewport: -1=Game default, 0=disable. 1=enable +correct_viewport = -1 +# Force texrect size to integral value: -1=Game default, 0=disable. 1=enable +increase_texrect_edge = -1 +# Reduce fillrect size by 1: -1=Game default, 0=disable. 1=enable +decrease_fillrect_edge = -1 +# Enable perspective texture correction emulation: -1=Game default, 0=disable. 1=enable +texture_correction = -1 +# Set special scale for PAL games: -1=Game default, 0=disable. 1=enable +pal230 = -1 +# 3DFX Dithered alpha emulation mode: -1=Game default, >=0=dithered alpha emulation mode +stipple_mode = -1 +# 3DFX Dithered alpha pattern: -1=Game default, >=0=pattern used for dithered alpha emulation +stipple_pattern = -1 +# Check microcode each frame: -1=Game default, 0=disable. 1=enable +force_microcheck = -1 +# Force 0xb5 command to be quad, not line 3D: -1=Game default, 0=disable. 1=enable +force_quad3d = -1 +# Enable near z clipping: -1=Game default, 0=disable. 1=enable +clip_zmin = -1 +# Enable far plane clipping: -1=Game default, 0=disable. 1=enable +clip_zmax = -1 +# Use fast CRC algorithm: -1=Game default, 0=disable. 1=enable +fast_crc = -1 +# Adjust screen aspect for wide screen mode: -1=Game default, 0=disable. 1=enable +adjust_aspect = -1 +# Force strict check in Depth buffer test: -1=Game default, 0=disable. 1=enable +zmode_compare_less = -1 +# Apply alpha dither regardless of alpha_dither_mode: -1=Game default, 0=disable. 1=enable +old_style_adither = -1 +# Scale vertex z value before writing to depth buffer: -1=Game default, 0=disable. 1=enable +n64_z_scale = -1 +# Fast texrect rendering with hwfbe: -1=Game default, 0=disable. 1=enable +optimize_texrect = -1 +# Do not copy auxiliary frame buffers: -1=Game default, 0=disable. 1=enable +ignore_aux_copy = -1 +# Clear auxiliary texture frame buffers: -1=Game default, 0=disable. 1=enable +hires_buf_clear = -1 +# Read alpha from framebuffer: -1=Game default, 0=disable. 1=enable +fb_read_alpha = -1 +# Handle unchanged fb: -1=Game default, 0=disable. 1=enable +useless_is_useless = -1 +# Set frambuffer CRC mode: -1=Game default, 0=disable CRC, 1=fast CRC, 2=safe CRC +fb_crc_mode = -1 +# Filtering mode: -1=Game default, 0=automatic, 1=force bilinear, 2=force point sampled +filtering = -1 +# Fog: -1=Game default, 0=disable. 1=enable +fog = -1 +# Buffer clear on every frame: -1=Game default, 0=disable. 1=enable +buff_clear = -1 +# Buffer swapping method: -1=Game default, 0=swap buffers when vertical interrupt has occurred, 1=swap buffers when set of conditions is satisfied. Prevents flicker on some games, 2=mix of first two methods +swapmode = -1 +# Aspect ratio: -1=Game default, 0=Force 4:3, 1=Force 16:9, 2=Stretch, 3=Original +aspect = -1 +# LOD calculation: -1=Game default, 0=disable. 1=fast, 2=precise +lodmode = -1 +# Smart framebuffer: -1=Game default, 0=disable. 1=enable +fb_smart = -1 +# Hardware frame buffer emulation: -1=Game default, 0=disable. 1=enable +fb_hires = -1 +# Read framebuffer every frame (may be slow use only for effects that need it e.g. Banjo Kazooie, DK64 transitions): -1=Game default, 0=disable. 1=enable +fb_read_always = -1 +# Render N64 frame buffer as texture: -1=Game default, 0=disable, 1=mode1, 2=mode2 +read_back_to_screen = -1 +# Show images written directly by CPU: -1=Game default, 0=disable. 1=enable +detect_cpu_write = -1 +# Get frame buffer info: -1=Game default, 0=disable. 1=enable +fb_get_info = -1 +# Enable software depth render: -1=Game default, 0=disable. 1=enable +fb_render = -1 +# If true, skip up to maxframeskip frames to maintain clock schedule; if false, skip exactly maxframeskip frames +autoframeskip = False +# If autoframeskip is true, skip up to this many frames to maintain clock schedule; if autoframeskip is false, skip exactly this many frames +maxframeskip = 0 + + +[Video-Rice] + +# Mupen64Plus Rice Video Plugin config parameter version number +Version = 1 +# Frame Buffer Emulation (0=ROM default, 1=disable) +FrameBufferSetting = 0 +# Frequency to write back the frame buffer (0=every frame, 1=every other frame, etc) +FrameBufferWriteBackControl = 0 +# Render-to-texture emulation (0=none, 1=ignore, 2=normal, 3=write back, 4=write back and reload) +RenderToTexture = 0 +# Control when the screen will be updated (0=ROM default, 1=VI origin update, 2=VI origin change, 3=CI change, 4=first CI change, 5=first primitive draw, 6=before screen clear, 7=after screen drawn) +ScreenUpdateSetting = 4 +# Force to use normal alpha blender +NormalAlphaBlender = False +# Use a faster algorithm to speed up texture loading and CRC computation +FastTextureLoading = False +# Use different texture coordinate clamping code +AccurateTextureMapping = True +# Force emulated frame buffers to be in N64 native resolution +InN64Resolution = False +# Try to reduce Video RAM usage (should never be used) +SaveVRAM = False +# Enable this option to have better render-to-texture quality +DoubleSizeForSmallTxtrBuf = False +# Force to use normal color combiner +DefaultCombinerDisable = False +# Enable game-specific settings from INI file +EnableHacks = True +# If enabled, graphics will be drawn in WinFrame mode instead of solid and texture mode +WinFrameMode = False +# N64 Texture Memory Full Emulation (may fix some games, may break others) +FullTMEMEmulation = False +# Enable vertex clipper for fog operations +OpenGLVertexClipper = False +# Enable/Disable SSE optimizations for capable CPUs +EnableSSE = True +# If this option is enabled, the plugin will skip every other frame +SkipFrame = False +# If enabled, texture enhancement will be done only for TxtRect ucode +TexRectOnly = False +# If enabled, texture enhancement will be done only for textures width+height<=128 +SmallTextureOnly = False +# Select hi-resolution textures based only on the CRC and ignore format+size information (Glide64 compatibility) +LoadHiResCRCOnly = True +# Enable hi-resolution texture file loading +LoadHiResTextures = False +# Enable texture dumping +DumpTexturesToFiles = False +# Display On-screen FPS +ShowFPS = False +# Use Mipmapping? 0=no, 1=nearest, 2=bilinear, 3=trilinear +Mipmapping = 2 +# Enable, Disable fog generation (0=Disable, 1=Enable) +FogMethod = 1 +# Force to use texture filtering or not (0=auto: n64 choose, 1=force no filtering, 2=force filtering) +ForceTextureFilter = 0 +# Primary texture enhancement filter (0=None, 1=2X, 2=2XSAI, 3=HQ2X, 4=LQ2X, 5=HQ4X, 6=Sharpen, 7=Sharpen More, 8=External, 9=Mirrored) +TextureEnhancement = 0 +# Secondary texture enhancement filter (0 = none, 1-4 = filtered) +TextureEnhancementControl = 0 +# Color bit depth to use for textures (0=default, 1=32 bits, 2=16 bits) +TextureQuality = 0 +# Z-buffer depth (only 16 or 32) +OpenGLDepthBufferSetting = 16 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Color bit depth for rendering window (0=32 bits, 1=16 bits) +ColorQuality = 1 +# OpenGL level to support (0=auto, 1=OGL_FRAGMENT_PROGRAM) +OpenGLRenderSetting = 0 +# Enable/Disable Anisotropic Filtering for Mipmapping (0=no filtering, 2-16=quality). This is uneffective if Mipmapping is 0. If the given value is to high to be supported by your graphic card, the value will be the highest value your graphic card can support. Better result with Trilinear filtering +AnisotropicFiltering = 0 +# If true, use polygon offset values specified below +ForcePolygonOffset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +PolygonOffsetFactor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +PolygonOffsetUnits = 0.000000 diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3566/mupen64plus.cfg.rgarc b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3566/mupen64plus.cfg.rgarc new file mode 100644 index 0000000000..058c75774f --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3566/mupen64plus.cfg.rgarc @@ -0,0 +1,665 @@ +# Mupen64Plus Configuration File +# This file is automatically read and written by the Mupen64Plus Core library + +[64DD] + +# Filename of the 64DD IPL ROM +IPL-ROM = "" +# Filename of the disk to load into Disk Drive +Disk = "" + + +[Audio-SDL] + +# Mupen64Plus SDL Audio Plugin config parameter version number +Version = 1.000000 +# Frequency which is used if rom doesn't want to change it +DEFAULT_FREQUENCY = 33600 +# Swaps left and right channels +SWAP_CHANNELS = False +# Size of primary buffer in output samples. This is where audio is loaded after it's extracted from n64's memory. +PRIMARY_BUFFER_SIZE = 16384 +# Fullness level target for Primary audio buffer, in equivalent output samples. This value must be larger than the SECONDARY_BUFFER_SIZE. Decreasing this value will reduce audio latency but requires a faster PC to avoid choppiness. Increasing this will increase audio latency but reduce the chance of drop-outs. +PRIMARY_BUFFER_TARGET = 2048 +# Size of secondary buffer in output samples. This is SDL's hardware buffer. The SDL documentation states that this should be a power of two between 512 and 8192. +SECONDARY_BUFFER_SIZE = 1024 +# Audio resampling algorithm. src-sinc-best-quality, src-sinc-medium-quality, src-sinc-fastest, src-zero-order-hold, src-linear, speex-fixed-{10-0}, trivial +RESAMPLE = "trivial" +# Volume control type: 1 = SDL (only affects Mupen64Plus output) 2 = OSS mixer (adjusts master PC volume) +VOLUME_CONTROL_TYPE = 1 +# Percentage change each time the volume is increased or decreased +VOLUME_ADJUST = 5 +# Default volume when a game is started. Only used if VOLUME_CONTROL_TYPE is 1 +VOLUME_DEFAULT = 100 +# Synchronize Video/Audio +AUDIO_SYNC = False + + +[Core] + +# Mupen64Plus Core config parameter set version number. Please don't change this version number. +Version = 1.010000 +# Draw on-screen display if True, otherwise don't draw OSD +OnScreenDisplay = True +# Use Pure Interpreter if 0, Cached Interpreter if 1, or Dynamic Recompiler if 2 or more +R4300Emulator = 2 +# Disable compiled jump commands in dynamic recompiler (should be set to False) +NoCompiledJump = False +# Disable 4MB expansion RAM pack. May be necessary for some games +DisableExtraMem = False +# Increment the save state slot after each save operation +AutoStateSlotIncrement = False +# Activate the R4300 debugger when ROM execution begins, if core was built with Debugger support +EnableDebugger = False +# Save state slot (0-9) to use when saving/loading the emulator state +CurrentStateSlot = 0 +# Path to directory where screenshots are saved. If this is blank, the default value of ${UserDataPath}/screenshot will be used +ScreenshotPath = "/storage/roms/screenshots" +# Path to directory where emulator save states (snapshots) are saved. If this is blank, the default value of ${UserDataPath}/save will be used +SaveStatePath = "/storage/roms/n64" +# Path to directory where SRAM/EEPROM data (in-game saves) are stored. If this is blank, the default value of ${UserDataPath}/save will be used +SaveSRAMPath = "/storage/roms/n64" +# Path to a directory to search when looking for shared data files +SharedDataPath = "/storage/.config/game/configs/mupen64plussa" +# Force number of cycles per emulated instruction +CountPerOp = 0 +# Randomize PI/SI Interrupt Timing +RandomizeInterrupt = True +# Duration of SI DMA (-1: use per game settings) +SiDmaDuration = -1 +# Gameboy Camera Video Capture backend +GbCameraVideoCaptureBackend1 = "" +# Disk Save Format (0: Full Disk Copy (*.ndr/*.d6r), 1: RAM Area Only (*.ram)) +SaveDiskFormat = 1 + + +[CoreEvents] + +# Mupen64Plus CoreEvents config parameter set version number. Please don't change this version number. +Version = 1.000000 +# SDL keysym for stopping the emulator +Kbd Mapping Stop = 27 +# SDL keysym for switching between fullscreen/windowed modes +Kbd Mapping Fullscreen = 0 +# SDL keysym for saving the emulator state +Kbd Mapping Save State = 286 +# SDL keysym for loading the emulator state +Kbd Mapping Load State = 288 +# SDL keysym for advancing the save state slot +Kbd Mapping Increment Slot = 0 +# SDL keysym for resetting the emulator +Kbd Mapping Reset = 290 +# SDL keysym for slowing down the emulator +Kbd Mapping Speed Down = 291 +# SDL keysym for speeding up the emulator +Kbd Mapping Speed Up = 292 +# SDL keysym for taking a screenshot +Kbd Mapping Screenshot = 293 +# SDL keysym for pausing the emulator +Kbd Mapping Pause = 112 +# SDL keysym for muting/unmuting the sound +Kbd Mapping Mute = 109 +# SDL keysym for increasing the volume +Kbd Mapping Increase Volume = 93 +# SDL keysym for decreasing the volume +Kbd Mapping Decrease Volume = 91 +# SDL keysym for temporarily going really fast +Kbd Mapping Fast Forward = 102 +# SDL keysym for advancing by one frame when paused +Kbd Mapping Frame Advance = 47 +# SDL keysym for pressing the game shark button +Kbd Mapping Gameshark = 103 +# Joystick event string for stopping the emulator +Joy Mapping Stop = "J0B8/B9" +# Joystick event string for switching between fullscreen/windowed modes +Joy Mapping Fullscreen = "" +# Joystick event string for saving the emulator state +Joy Mapping Save State = "J0B8/B5" +# Joystick event string for loading the emulator state +Joy Mapping Load State = "J0B8/B4" +# Joystick event string for advancing the save state slot +Joy Mapping Increment Slot = "" +# Joystick event string for resetting the emulator +Joy Mapping Reset = "J0B8/B0" +# Joystick event string for slowing down the emulator +Joy Mapping Speed Down = "" +# Joystick event string for speeding up the emulator +Joy Mapping Speed Up = "" +# Joystick event string for taking a screenshot +Joy Mapping Screenshot = "J0B8/B3" +# Joystick event string for pausing the emulator +Joy Mapping Pause = "J0B8/B1" +# Joystick event string for muting/unmuting the sound +Joy Mapping Mute = "" +# Joystick event string for increasing the volume +Joy Mapping Increase Volume = "" +# Joystick event string for decreasing the volume +Joy Mapping Decrease Volume = "" +# Joystick event string for fast-forward +Joy Mapping Fast Forward = "J0B8/B7" +# Joystick event string for advancing by one frame when paused +Joy Mapping Frame Advance = "" +# Joystick event string for pressing the game shark button +Joy Mapping Gameshark = "J0B8/B2" +# SDL keysym for save slot 0 +Kbd Mapping Slot 0 = 48 +# SDL keysym for save slot 1 +Kbd Mapping Slot 1 = 49 +# SDL keysym for save slot 2 +Kbd Mapping Slot 2 = 50 +# SDL keysym for save slot 3 +Kbd Mapping Slot 3 = 51 +# SDL keysym for save slot 4 +Kbd Mapping Slot 4 = 52 +# SDL keysym for save slot 5 +Kbd Mapping Slot 5 = 53 +# SDL keysym for save slot 6 +Kbd Mapping Slot 6 = 54 +# SDL keysym for save slot 7 +Kbd Mapping Slot 7 = 55 +# SDL keysym for save slot 8 +Kbd Mapping Slot 8 = 56 +# SDL keysym for save slot 9 +Kbd Mapping Slot 9 = 57 + + +[Input-SDL-Control1] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = 0 +# SDL joystick name (or Keyboard) +name = "rg_arc_joypad" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = True +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "0,0" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = +DPad L = +DPad D = +DPad U = +Start = button(11) +Z Trig = button(8) +B Button = button(3) +A Button = button(1) +C Button R = button(2) +C Button L = button(4) +C Button D = button(0) +C Button U = button(5) +R Trig = button(7) +L Trig = button(6) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = button(14,15) +Y Axis = button(12,13) + + +[Input-SDL-Control2] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control3] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control4] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Rsp-HLE] + +# Mupen64Plus RSP HLE Plugin config parameter version number +Version = 1.000000 +# Path to a RSP plugin which will be used when encountering an unknown ucode.You can disable this by letting an empty string. +RspFallback = "" +# Send display lists to the graphics plugin +DisplayListToGraphicsPlugin = True +# Send audio lists to the audio plugin +AudioListToAudioPlugin = False + + +[Transferpak] + +# Filename of the GB ROM to load into transferpak 1 +GB-rom-1 = "" +# Filename of the GB RAM to load into transferpak 1 +GB-ram-1 = "" +# Filename of the GB ROM to load into transferpak 2 +GB-rom-2 = "" +# Filename of the GB RAM to load into transferpak 2 +GB-ram-2 = "" +# Filename of the GB ROM to load into transferpak 3 +GB-rom-3 = "" +# Filename of the GB RAM to load into transferpak 3 +GB-ram-3 = "" +# Filename of the GB ROM to load into transferpak 4 +GB-rom-4 = "" +# Filename of the GB RAM to load into transferpak 4 +GB-ram-4 = "" + + +[UI-Console] + +# Mupen64Plus UI-Console config parameter set version number. Please don't change this version number. +Version = 1.000000 +# Directory in which to search for plugins +PluginDir = "/usr/local/lib/mupen64plus" +# Filename of video plugin +VideoPlugin = "mupen64plus-video-rice" +# Filename of audio plugin +AudioPlugin = "mupen64plus-audio-sdl.so" +# Filename of input plugin +InputPlugin = "mupen64plus-input-sdl.so" +# Filename of RSP plugin +RspPlugin = "mupen64plus-rsp-hle.so" + + +[Video-General] + +# Width of output window or fullscreen width +ScreenWidth = 640 +# Height of output window or fullscreen height +ScreenHeight = 480 +# Use fullscreen mode if True, or windowed mode if False +Fullscreen = True +# If true, activate the SDL_GL_SWAP_CONTROL attribute +VerticalSync = True +# Rotate screen contents: 0=0 degree, 1=90 degree, 2 = 180 degree, 3=270 degree +Rotate = 0 + +[Video-GLideN64] + +###### Hardware Compatibility ###### +# Leave enabled unless a mobile gpu doesn't support it. +EnableFragmentDepthWrite = 0 +# Hardware per pixel lighting, supposedly good for GLES3.1 devices or higher. +EnableHWLighting = 0 + +###### Enhancements ####### +# Internal render resoluton rather than output. So 2 x 240p is 480p, etc. +UseNativeResolutionFactor = 1 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Enable/Disable Fast Approximate Anti-Aliasing FXAA +FXAA = 0 +# Max level of Anisotropic Filtering, 0 for off +anisotropy = 0 +# Bilinear filtering mode (0=N64 3point, 1=standard) +# @rishooty: best to use this at 1x native res, any higher turn it off. +bilinearMode = 1 + +###### Compatibility ###### +# Make texrect coordinates continuous to avoid black lines between them. (0=Off/default, 1=Auto, 2=Force) +CorrectTexrectCoords = 1 +# Copy auxiliary buffers to RDRAM (default: 0) +EnableCopyAuxiliaryToRDRAM = 1 +# Render 2D texrects in native resolution to fix misalignment between parts of 2D image. (0=Off/default, 1=Optimized, 2=Unoptimized)") +EnableNativeResTexrects = 1 + +###### Other ###### +# Enable threaded video backend at the cost of input lag +ThreadedVideo = 1 +# Screen aspect ratio (0=stretch, 1=force 4:3, 2=force 16:9, 3=adjust) +AspectRatio = 1 +# Display On-screen FPS +ShowFPS = False + +[Video-Glide64mk2] + +# Enable full-scene anti-aliasing by setting this to a value greater than 1 +wrpAntiAliasing = 0 +# Card ID +card_id = 0 +# If true, use polygon offset values specified below +force_polygon_offset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +polygon_offset_factor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +polygon_offset_units = 0.000000 +# Vertical sync +vsync = True +# TODO:ssformat +ssformat = False +# Display performance stats (add together desired flags): 1=FPS counter, 2=VI/s counter, 4=% speed, 8=FPS transparent +show_fps = 0 +# Clock enabled +clock = False +# Clock is 24-hour +clock_24_hr = True +# Wrapper resolution +wrpResolution = 0 +# Wrapper VRAM +wrpVRAM = 0 +# Wrapper FBO +wrpFBO = True +# Wrapper Anisotropic Filtering +wrpAnisotropic = True +# Texture Enhancement: Smooth/Sharpen Filters +ghq_fltr = 0 +# Texture Compression: 0 for S3TC, 1 for FXT1 +ghq_cmpr = 0 +# Texture Enhancement: More filters +ghq_enht = 0 +# Hi-res texture pack format (0 for none, 1 for Rice) +ghq_hirs = 1 +# Compress texture cache with S3TC or FXT1 +ghq_enht_cmpr = False +# Tile textures (saves memory but could cause issues) +ghq_enht_tile = 0 +# Force 16bpp textures (saves ram but lower quality) +ghq_enht_f16bpp = False +# Compress texture cache +ghq_enht_gz = True +# Don't enhance textures for backgrounds +ghq_enht_nobg = False +# Enable S3TC and FXT1 compression +ghq_hirs_cmpr = False +# Tile hi-res textures (saves memory but could cause issues) +ghq_hirs_tile = False +# Force 16bpp hi-res textures (saves ram but lower quality) +ghq_hirs_f16bpp = False +# Compress hi-res texture cache +ghq_hirs_gz = True +# Alternative CRC calculation -- emulates Rice bug +ghq_hirs_altcrc = True +# Save tex cache to disk +ghq_cache_save = True +# Texture Cache Size (MB) +ghq_cache_size = 128 +# Use full alpha channel -- could cause issues for some tex packs +ghq_hirs_let_texartists_fly = False +# Dump textures +ghq_hirs_dump = False +# Alternate texture size method: -1=Game default, 0=disable. 1=enable +alt_tex_size = -1 +# Use first SETTILESIZE only: -1=Game default, 0=disable. 1=enable +use_sts1_only = -1 +# Use spheric mapping only: -1=Game default, 0=disable. 1=enable +force_calc_sphere = -1 +# Force positive viewport: -1=Game default, 0=disable. 1=enable +correct_viewport = -1 +# Force texrect size to integral value: -1=Game default, 0=disable. 1=enable +increase_texrect_edge = -1 +# Reduce fillrect size by 1: -1=Game default, 0=disable. 1=enable +decrease_fillrect_edge = -1 +# Enable perspective texture correction emulation: -1=Game default, 0=disable. 1=enable +texture_correction = -1 +# Set special scale for PAL games: -1=Game default, 0=disable. 1=enable +pal230 = -1 +# 3DFX Dithered alpha emulation mode: -1=Game default, >=0=dithered alpha emulation mode +stipple_mode = -1 +# 3DFX Dithered alpha pattern: -1=Game default, >=0=pattern used for dithered alpha emulation +stipple_pattern = -1 +# Check microcode each frame: -1=Game default, 0=disable. 1=enable +force_microcheck = -1 +# Force 0xb5 command to be quad, not line 3D: -1=Game default, 0=disable. 1=enable +force_quad3d = -1 +# Enable near z clipping: -1=Game default, 0=disable. 1=enable +clip_zmin = -1 +# Enable far plane clipping: -1=Game default, 0=disable. 1=enable +clip_zmax = -1 +# Use fast CRC algorithm: -1=Game default, 0=disable. 1=enable +fast_crc = -1 +# Adjust screen aspect for wide screen mode: -1=Game default, 0=disable. 1=enable +adjust_aspect = -1 +# Force strict check in Depth buffer test: -1=Game default, 0=disable. 1=enable +zmode_compare_less = -1 +# Apply alpha dither regardless of alpha_dither_mode: -1=Game default, 0=disable. 1=enable +old_style_adither = -1 +# Scale vertex z value before writing to depth buffer: -1=Game default, 0=disable. 1=enable +n64_z_scale = -1 +# Fast texrect rendering with hwfbe: -1=Game default, 0=disable. 1=enable +optimize_texrect = -1 +# Do not copy auxiliary frame buffers: -1=Game default, 0=disable. 1=enable +ignore_aux_copy = -1 +# Clear auxiliary texture frame buffers: -1=Game default, 0=disable. 1=enable +hires_buf_clear = -1 +# Read alpha from framebuffer: -1=Game default, 0=disable. 1=enable +fb_read_alpha = -1 +# Handle unchanged fb: -1=Game default, 0=disable. 1=enable +useless_is_useless = -1 +# Set frambuffer CRC mode: -1=Game default, 0=disable CRC, 1=fast CRC, 2=safe CRC +fb_crc_mode = -1 +# Filtering mode: -1=Game default, 0=automatic, 1=force bilinear, 2=force point sampled +filtering = -1 +# Fog: -1=Game default, 0=disable. 1=enable +fog = -1 +# Buffer clear on every frame: -1=Game default, 0=disable. 1=enable +buff_clear = -1 +# Buffer swapping method: -1=Game default, 0=swap buffers when vertical interrupt has occurred, 1=swap buffers when set of conditions is satisfied. Prevents flicker on some games, 2=mix of first two methods +swapmode = -1 +# Aspect ratio: -1=Game default, 0=Force 4:3, 1=Force 16:9, 2=Stretch, 3=Original +aspect = -1 +# LOD calculation: -1=Game default, 0=disable. 1=fast, 2=precise +lodmode = -1 +# Smart framebuffer: -1=Game default, 0=disable. 1=enable +fb_smart = -1 +# Hardware frame buffer emulation: -1=Game default, 0=disable. 1=enable +fb_hires = -1 +# Read framebuffer every frame (may be slow use only for effects that need it e.g. Banjo Kazooie, DK64 transitions): -1=Game default, 0=disable. 1=enable +fb_read_always = -1 +# Render N64 frame buffer as texture: -1=Game default, 0=disable, 1=mode1, 2=mode2 +read_back_to_screen = -1 +# Show images written directly by CPU: -1=Game default, 0=disable. 1=enable +detect_cpu_write = -1 +# Get frame buffer info: -1=Game default, 0=disable. 1=enable +fb_get_info = -1 +# Enable software depth render: -1=Game default, 0=disable. 1=enable +fb_render = -1 +# If true, skip up to maxframeskip frames to maintain clock schedule; if false, skip exactly maxframeskip frames +autoframeskip = False +# If autoframeskip is true, skip up to this many frames to maintain clock schedule; if autoframeskip is false, skip exactly this many frames +maxframeskip = 0 + + +[Video-Rice] + +# Mupen64Plus Rice Video Plugin config parameter version number +Version = 1 +# Frame Buffer Emulation (0=ROM default, 1=disable) +FrameBufferSetting = 0 +# Frequency to write back the frame buffer (0=every frame, 1=every other frame, etc) +FrameBufferWriteBackControl = 0 +# Render-to-texture emulation (0=none, 1=ignore, 2=normal, 3=write back, 4=write back and reload) +RenderToTexture = 0 +# Control when the screen will be updated (0=ROM default, 1=VI origin update, 2=VI origin change, 3=CI change, 4=first CI change, 5=first primitive draw, 6=before screen clear, 7=after screen drawn) +ScreenUpdateSetting = 4 +# Force to use normal alpha blender +NormalAlphaBlender = False +# Use a faster algorithm to speed up texture loading and CRC computation +FastTextureLoading = False +# Use different texture coordinate clamping code +AccurateTextureMapping = True +# Force emulated frame buffers to be in N64 native resolution +InN64Resolution = False +# Try to reduce Video RAM usage (should never be used) +SaveVRAM = False +# Enable this option to have better render-to-texture quality +DoubleSizeForSmallTxtrBuf = False +# Force to use normal color combiner +DefaultCombinerDisable = False +# Enable game-specific settings from INI file +EnableHacks = True +# If enabled, graphics will be drawn in WinFrame mode instead of solid and texture mode +WinFrameMode = False +# N64 Texture Memory Full Emulation (may fix some games, may break others) +FullTMEMEmulation = False +# Enable vertex clipper for fog operations +OpenGLVertexClipper = False +# Enable/Disable SSE optimizations for capable CPUs +EnableSSE = True +# If this option is enabled, the plugin will skip every other frame +SkipFrame = False +# If enabled, texture enhancement will be done only for TxtRect ucode +TexRectOnly = False +# If enabled, texture enhancement will be done only for textures width+height<=128 +SmallTextureOnly = False +# Select hi-resolution textures based only on the CRC and ignore format+size information (Glide64 compatibility) +LoadHiResCRCOnly = True +# Enable hi-resolution texture file loading +LoadHiResTextures = False +# Enable texture dumping +DumpTexturesToFiles = False +# Display On-screen FPS +ShowFPS = False +# Use Mipmapping? 0=no, 1=nearest, 2=bilinear, 3=trilinear +Mipmapping = 2 +# Enable, Disable fog generation (0=Disable, 1=Enable) +FogMethod = 1 +# Force to use texture filtering or not (0=auto: n64 choose, 1=force no filtering, 2=force filtering) +ForceTextureFilter = 0 +# Primary texture enhancement filter (0=None, 1=2X, 2=2XSAI, 3=HQ2X, 4=LQ2X, 5=HQ4X, 6=Sharpen, 7=Sharpen More, 8=External, 9=Mirrored) +TextureEnhancement = 0 +# Secondary texture enhancement filter (0 = none, 1-4 = filtered) +TextureEnhancementControl = 0 +# Color bit depth to use for textures (0=default, 1=32 bits, 2=16 bits) +TextureQuality = 0 +# Z-buffer depth (only 16 or 32) +OpenGLDepthBufferSetting = 16 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Color bit depth for rendering window (0=32 bits, 1=16 bits) +ColorQuality = 1 +# OpenGL level to support (0=auto, 1=OGL_FRAGMENT_PROGRAM) +OpenGLRenderSetting = 0 +# Enable/Disable Anisotropic Filtering for Mipmapping (0=no filtering, 2-16=quality). This is uneffective if Mipmapping is 0. If the given value is to high to be supported by your graphic card, the value will be the highest value your graphic card can support. Better result with Trilinear filtering +AnisotropicFiltering = 0 +# If true, use polygon offset values specified below +ForcePolygonOffset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +PolygonOffsetFactor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +PolygonOffsetUnits = 0.000000 diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3588/mupen64plus.cfg b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3588/mupen64plus.cfg new file mode 100644 index 0000000000..77a651a3ba --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3588/mupen64plus.cfg @@ -0,0 +1,664 @@ +# Mupen64Plus Configuration File +# This file is automatically read and written by the Mupen64Plus Core library + +[64DD] + +# Filename of the 64DD IPL ROM +IPL-ROM = "" +# Filename of the disk to load into Disk Drive +Disk = "" + + +[Audio-SDL] + +# Mupen64Plus SDL Audio Plugin config parameter version number +Version = 1.000000 +# Frequency which is used if rom doesn't want to change it +DEFAULT_FREQUENCY = 33600 +# Swaps left and right channels +SWAP_CHANNELS = False +# Size of primary buffer in output samples. This is where audio is loaded after it's extracted from n64's memory. +PRIMARY_BUFFER_SIZE = 16384 +# Fullness level target for Primary audio buffer, in equivalent output samples. This value must be larger than the SECONDARY_BUFFER_SIZE. Decreasing this value will reduce audio latency but requires a faster PC to avoid choppiness. Increasing this will increase audio latency but reduce the chance of drop-outs. +PRIMARY_BUFFER_TARGET = 2048 +# Size of secondary buffer in output samples. This is SDL's hardware buffer. The SDL documentation states that this should be a power of two between 512 and 8192. +SECONDARY_BUFFER_SIZE = 1024 +# Audio resampling algorithm. src-sinc-best-quality, src-sinc-medium-quality, src-sinc-fastest, src-zero-order-hold, src-linear, speex-fixed-{10-0}, trivial +RESAMPLE = "trivial" +# Volume control type: 1 = SDL (only affects Mupen64Plus output) 2 = OSS mixer (adjusts master PC volume) +VOLUME_CONTROL_TYPE = 1 +# Percentage change each time the volume is increased or decreased +VOLUME_ADJUST = 5 +# Default volume when a game is started. Only used if VOLUME_CONTROL_TYPE is 1 +VOLUME_DEFAULT = 100 +# Synchronize Video/Audio +AUDIO_SYNC = False + + +[Core] + +# Mupen64Plus Core config parameter set version number. Please don't change this version number. +Version = 1.010000 +# Draw on-screen display if True, otherwise don't draw OSD +OnScreenDisplay = True +# Use Pure Interpreter if 0, Cached Interpreter if 1, or Dynamic Recompiler if 2 or more +R4300Emulator = 2 +# Disable compiled jump commands in dynamic recompiler (should be set to False) +NoCompiledJump = False +# Disable 4MB expansion RAM pack. May be necessary for some games +DisableExtraMem = False +# Increment the save state slot after each save operation +AutoStateSlotIncrement = False +# Activate the R4300 debugger when ROM execution begins, if core was built with Debugger support +EnableDebugger = False +# Save state slot (0-9) to use when saving/loading the emulator state +CurrentStateSlot = 0 +# Path to directory where screenshots are saved. If this is blank, the default value of ${UserDataPath}/screenshot will be used +ScreenshotPath = "/storage/roms/screenshots" +# Path to directory where emulator save states (snapshots) are saved. If this is blank, the default value of ${UserDataPath}/save will be used +SaveStatePath = "/storage/roms/n64" +# Path to directory where SRAM/EEPROM data (in-game saves) are stored. If this is blank, the default value of ${UserDataPath}/save will be used +SaveSRAMPath = "/storage/roms/n64" +# Path to a directory to search when looking for shared data files +SharedDataPath = "/storage/.config/game/configs/mupen64plussa" +# Force number of cycles per emulated instruction +CountPerOp = 0 +# Randomize PI/SI Interrupt Timing +RandomizeInterrupt = True +# Duration of SI DMA (-1: use per game settings) +SiDmaDuration = -1 +# Gameboy Camera Video Capture backend +GbCameraVideoCaptureBackend1 = "" +# Disk Save Format (0: Full Disk Copy (*.ndr/*.d6r), 1: RAM Area Only (*.ram)) +SaveDiskFormat = 1 + + +[CoreEvents] + +# Mupen64Plus CoreEvents config parameter set version number. Please don't change this version number. +Version = 1.000000 +# SDL keysym for stopping the emulator +Kbd Mapping Stop = 27 +# SDL keysym for switching between fullscreen/windowed modes +Kbd Mapping Fullscreen = 0 +# SDL keysym for saving the emulator state +Kbd Mapping Save State = 286 +# SDL keysym for loading the emulator state +Kbd Mapping Load State = 288 +# SDL keysym for advancing the save state slot +Kbd Mapping Increment Slot = 0 +# SDL keysym for resetting the emulator +Kbd Mapping Reset = 290 +# SDL keysym for slowing down the emulator +Kbd Mapping Speed Down = 291 +# SDL keysym for speeding up the emulator +Kbd Mapping Speed Up = 292 +# SDL keysym for taking a screenshot +Kbd Mapping Screenshot = 293 +# SDL keysym for pausing the emulator +Kbd Mapping Pause = 112 +# SDL keysym for muting/unmuting the sound +Kbd Mapping Mute = 109 +# SDL keysym for increasing the volume +Kbd Mapping Increase Volume = 93 +# SDL keysym for decreasing the volume +Kbd Mapping Decrease Volume = 91 +# SDL keysym for temporarily going really fast +Kbd Mapping Fast Forward = 102 +# SDL keysym for advancing by one frame when paused +Kbd Mapping Frame Advance = 47 +# SDL keysym for pressing the game shark button +Kbd Mapping Gameshark = 103 +# Joystick event string for stopping the emulator +Joy Mapping Stop = "J0B9/B8" +# Joystick event string for switching between fullscreen/windowed modes +Joy Mapping Fullscreen = "" +# Joystick event string for saving the emulator state +Joy Mapping Save State = "J0B9/B6" +# Joystick event string for loading the emulator state +Joy Mapping Load State = "J0B9/B5" +# Joystick event string for advancing the save state slot +Joy Mapping Increment Slot = "" +# Joystick event string for resetting the emulator +Joy Mapping Reset = "J0B9/B0" +# Joystick event string for slowing down the emulator +Joy Mapping Speed Down = "" +# Joystick event string for speeding up the emulator +Joy Mapping Speed Up = "" +# Joystick event string for taking a screenshot +Joy Mapping Screenshot = "J0B9/B4" +# Joystick event string for pausing the emulator +Joy Mapping Pause = "" +# Joystick event string for muting/unmuting the sound +Joy Mapping Mute = "" +# Joystick event string for increasing the volume +Joy Mapping Increase Volume = "" +# Joystick event string for decreasing the volume +Joy Mapping Decrease Volume = "" +# Joystick event string for fast-forward +Joy Mapping Fast Forward = "" +# Joystick event string for advancing by one frame when paused +Joy Mapping Frame Advance = "" +# Joystick event string for pressing the game shark button +Joy Mapping Gameshark = "" +# SDL keysym for save slot 0 +Kbd Mapping Slot 0 = 48 +# SDL keysym for save slot 1 +Kbd Mapping Slot 1 = 49 +# SDL keysym for save slot 2 +Kbd Mapping Slot 2 = 50 +# SDL keysym for save slot 3 +Kbd Mapping Slot 3 = 51 +# SDL keysym for save slot 4 +Kbd Mapping Slot 4 = 52 +# SDL keysym for save slot 5 +Kbd Mapping Slot 5 = 53 +# SDL keysym for save slot 6 +Kbd Mapping Slot 6 = 54 +# SDL keysym for save slot 7 +Kbd Mapping Slot 7 = 55 +# SDL keysym for save slot 8 +Kbd Mapping Slot 8 = 56 +# SDL keysym for save slot 9 +Kbd Mapping Slot 9 = 57 + + +[Input-SDL-Control1] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = 0 +# SDL joystick name (or Keyboard) +name = "GameForce ACE Gamepad" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = True +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "0,0" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = button(15) +DPad L = button(14) +DPad D = button(13) +DPad U = button(12) +Start = button(8) +Z Trig = axis(5-) +B Button = button(4) +A Button = button(0) +C Button R = axis(3+) +C Button L = axis(3-) +C Button D = axis(4+) +C Button U = axis(4-) +R Trig = button(6) +L Trig = button(5) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Input-SDL-Control2] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control3] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control4] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Rsp-HLE] + +# Mupen64Plus RSP HLE Plugin config parameter version number +Version = 1.000000 +# Path to a RSP plugin which will be used when encountering an unknown ucode.You can disable this by letting an empty string. +RspFallback = "" +# Send display lists to the graphics plugin +DisplayListToGraphicsPlugin = True +# Send audio lists to the audio plugin +AudioListToAudioPlugin = False + + +[Transferpak] + +# Filename of the GB ROM to load into transferpak 1 +GB-rom-1 = "" +# Filename of the GB RAM to load into transferpak 1 +GB-ram-1 = "" +# Filename of the GB ROM to load into transferpak 2 +GB-rom-2 = "" +# Filename of the GB RAM to load into transferpak 2 +GB-ram-2 = "" +# Filename of the GB ROM to load into transferpak 3 +GB-rom-3 = "" +# Filename of the GB RAM to load into transferpak 3 +GB-ram-3 = "" +# Filename of the GB ROM to load into transferpak 4 +GB-rom-4 = "" +# Filename of the GB RAM to load into transferpak 4 +GB-ram-4 = "" + + +[UI-Console] + +# Mupen64Plus UI-Console config parameter set version number. Please don't change this version number. +Version = 1.000000 +# Directory in which to search for plugins +PluginDir = "/usr/local/lib/mupen64plus" +# Filename of video plugin +VideoPlugin = "mupen64plus-video-rice" +# Filename of audio plugin +AudioPlugin = "mupen64plus-audio-sdl.so" +# Filename of input plugin +InputPlugin = "mupen64plus-input-sdl.so" +# Filename of RSP plugin +RspPlugin = "mupen64plus-rsp-hle.so" + + +[Video-General] + +# Width of output window or fullscreen width +ScreenWidth = 640 +# Height of output window or fullscreen height +ScreenHeight = 480 +# Use fullscreen mode if True, or windowed mode if False +Fullscreen = True +# If true, activate the SDL_GL_SWAP_CONTROL attribute +VerticalSync = True +# Rotate screen contents: 0=0 degree, 1=90 degree, 2 = 180 degree, 3=270 degree +Rotate = 0 + +[Video-GLideN64] + +###### Hardware Compatibility ###### +# Leave enabled unless a mobile gpu doesn't support it. +EnableFragmentDepthWrite = 1 +# Hardware per pixel lighting, supposedly good for GLES3.1 devices or higher. +EnableHWLighting = 0 + +###### Enhancements ####### +# Internal render resoluton rather than output. So 2 x 240p is 480p, etc. +UseNativeResolutionFactor = 1 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Enable/Disable Fast Approximate Anti-Aliasing FXAA +FXAA = 0 +# Max level of Anisotropic Filtering, 0 for off +anisotropy = 0 +# Bilinear filtering mode (0=N64 3point, 1=standard) +# @rishooty: best to use this at 1x native res, any higher turn it off. +bilinearMode = 1 + +###### Compatibility ###### +# Make texrect coordinates continuous to avoid black lines between them. (0=Off/default, 1=Auto, 2=Force) +CorrectTexrectCoords = 1 +# Copy auxiliary buffers to RDRAM (default: 0) +EnableCopyAuxiliaryToRDRAM = 1 +# Render 2D texrects in native resolution to fix misalignment between parts of 2D image. (0=Off/default, 1=Optimized, 2=Unoptimized)") +EnableNativeResTexrects = 1 + +###### Other ###### +# Enable threaded video backend at the cost of input lag +ThreadedVideo = 1 +# Screen aspect ratio (0=stretch, 1=force 4:3, 2=force 16:9, 3=adjust) +AspectRatio = 1 +# Display On-screen FPS +ShowFPS = False + +[Video-Glide64mk2] + +# Enable full-scene anti-aliasing by setting this to a value greater than 1 +wrpAntiAliasing = 0 +# Card ID +card_id = 0 +# If true, use polygon offset values specified below +force_polygon_offset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +polygon_offset_factor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +polygon_offset_units = 0.000000 +# Vertical sync +vsync = True +# TODO:ssformat +ssformat = False +# Display performance stats (add together desired flags): 1=FPS counter, 2=VI/s counter, 4=% speed, 8=FPS transparent +show_fps = 0 +# Clock enabled +clock = False +# Clock is 24-hour +clock_24_hr = True +# Wrapper resolution +wrpResolution = 0 +# Wrapper VRAM +wrpVRAM = 0 +# Wrapper FBO +wrpFBO = True +# Wrapper Anisotropic Filtering +wrpAnisotropic = True +# Texture Enhancement: Smooth/Sharpen Filters +ghq_fltr = 0 +# Texture Compression: 0 for S3TC, 1 for FXT1 +ghq_cmpr = 0 +# Texture Enhancement: More filters +ghq_enht = 0 +# Hi-res texture pack format (0 for none, 1 for Rice) +ghq_hirs = 1 +# Compress texture cache with S3TC or FXT1 +ghq_enht_cmpr = False +# Tile textures (saves memory but could cause issues) +ghq_enht_tile = 0 +# Force 16bpp textures (saves ram but lower quality) +ghq_enht_f16bpp = False +# Compress texture cache +ghq_enht_gz = True +# Don't enhance textures for backgrounds +ghq_enht_nobg = False +# Enable S3TC and FXT1 compression +ghq_hirs_cmpr = False +# Tile hi-res textures (saves memory but could cause issues) +ghq_hirs_tile = False +# Force 16bpp hi-res textures (saves ram but lower quality) +ghq_hirs_f16bpp = False +# Compress hi-res texture cache +ghq_hirs_gz = True +# Alternative CRC calculation -- emulates Rice bug +ghq_hirs_altcrc = True +# Save tex cache to disk +ghq_cache_save = True +# Texture Cache Size (MB) +ghq_cache_size = 128 +# Use full alpha channel -- could cause issues for some tex packs +ghq_hirs_let_texartists_fly = False +# Dump textures +ghq_hirs_dump = False +# Alternate texture size method: -1=Game default, 0=disable. 1=enable +alt_tex_size = -1 +# Use first SETTILESIZE only: -1=Game default, 0=disable. 1=enable +use_sts1_only = -1 +# Use spheric mapping only: -1=Game default, 0=disable. 1=enable +force_calc_sphere = -1 +# Force positive viewport: -1=Game default, 0=disable. 1=enable +correct_viewport = -1 +# Force texrect size to integral value: -1=Game default, 0=disable. 1=enable +increase_texrect_edge = -1 +# Reduce fillrect size by 1: -1=Game default, 0=disable. 1=enable +decrease_fillrect_edge = -1 +# Enable perspective texture correction emulation: -1=Game default, 0=disable. 1=enable +texture_correction = -1 +# Set special scale for PAL games: -1=Game default, 0=disable. 1=enable +pal230 = -1 +# 3DFX Dithered alpha emulation mode: -1=Game default, >=0=dithered alpha emulation mode +stipple_mode = -1 +# 3DFX Dithered alpha pattern: -1=Game default, >=0=pattern used for dithered alpha emulation +stipple_pattern = -1 +# Check microcode each frame: -1=Game default, 0=disable. 1=enable +force_microcheck = -1 +# Force 0xb5 command to be quad, not line 3D: -1=Game default, 0=disable. 1=enable +force_quad3d = -1 +# Enable near z clipping: -1=Game default, 0=disable. 1=enable +clip_zmin = -1 +# Enable far plane clipping: -1=Game default, 0=disable. 1=enable +clip_zmax = -1 +# Use fast CRC algorithm: -1=Game default, 0=disable. 1=enable +fast_crc = -1 +# Adjust screen aspect for wide screen mode: -1=Game default, 0=disable. 1=enable +adjust_aspect = -1 +# Force strict check in Depth buffer test: -1=Game default, 0=disable. 1=enable +zmode_compare_less = -1 +# Apply alpha dither regardless of alpha_dither_mode: -1=Game default, 0=disable. 1=enable +old_style_adither = -1 +# Scale vertex z value before writing to depth buffer: -1=Game default, 0=disable. 1=enable +n64_z_scale = -1 +# Fast texrect rendering with hwfbe: -1=Game default, 0=disable. 1=enable +optimize_texrect = -1 +# Do not copy auxiliary frame buffers: -1=Game default, 0=disable. 1=enable +ignore_aux_copy = -1 +# Clear auxiliary texture frame buffers: -1=Game default, 0=disable. 1=enable +hires_buf_clear = -1 +# Read alpha from framebuffer: -1=Game default, 0=disable. 1=enable +fb_read_alpha = -1 +# Handle unchanged fb: -1=Game default, 0=disable. 1=enable +useless_is_useless = -1 +# Set frambuffer CRC mode: -1=Game default, 0=disable CRC, 1=fast CRC, 2=safe CRC +fb_crc_mode = -1 +# Filtering mode: -1=Game default, 0=automatic, 1=force bilinear, 2=force point sampled +filtering = -1 +# Fog: -1=Game default, 0=disable. 1=enable +fog = -1 +# Buffer clear on every frame: -1=Game default, 0=disable. 1=enable +buff_clear = -1 +# Buffer swapping method: -1=Game default, 0=swap buffers when vertical interrupt has occurred, 1=swap buffers when set of conditions is satisfied. Prevents flicker on some games, 2=mix of first two methods +swapmode = -1 +# Aspect ratio: -1=Game default, 0=Force 4:3, 1=Force 16:9, 2=Stretch, 3=Original +aspect = -1 +# LOD calculation: -1=Game default, 0=disable. 1=fast, 2=precise +lodmode = -1 +# Smart framebuffer: -1=Game default, 0=disable. 1=enable +fb_smart = -1 +# Hardware frame buffer emulation: -1=Game default, 0=disable. 1=enable +fb_hires = -1 +# Read framebuffer every frame (may be slow use only for effects that need it e.g. Banjo Kazooie, DK64 transitions): -1=Game default, 0=disable. 1=enable +fb_read_always = -1 +# Render N64 frame buffer as texture: -1=Game default, 0=disable, 1=mode1, 2=mode2 +read_back_to_screen = -1 +# Show images written directly by CPU: -1=Game default, 0=disable. 1=enable +detect_cpu_write = -1 +# Get frame buffer info: -1=Game default, 0=disable. 1=enable +fb_get_info = -1 +# Enable software depth render: -1=Game default, 0=disable. 1=enable +fb_render = -1 +# If true, skip up to maxframeskip frames to maintain clock schedule; if false, skip exactly maxframeskip frames +autoframeskip = False +# If autoframeskip is true, skip up to this many frames to maintain clock schedule; if autoframeskip is false, skip exactly this many frames +maxframeskip = 0 + + +[Video-Rice] + +# Mupen64Plus Rice Video Plugin config parameter version number +Version = 1 +# Frame Buffer Emulation (0=ROM default, 1=disable) +FrameBufferSetting = 0 +# Frequency to write back the frame buffer (0=every frame, 1=every other frame, etc) +FrameBufferWriteBackControl = 0 +# Render-to-texture emulation (0=none, 1=ignore, 2=normal, 3=write back, 4=write back and reload) +RenderToTexture = 0 +# Control when the screen will be updated (0=ROM default, 1=VI origin update, 2=VI origin change, 3=CI change, 4=first CI change, 5=first primitive draw, 6=before screen clear, 7=after screen drawn) +ScreenUpdateSetting = 4 +# Force to use normal alpha blender +NormalAlphaBlender = False +# Use a faster algorithm to speed up texture loading and CRC computation +FastTextureLoading = False +# Use different texture coordinate clamping code +AccurateTextureMapping = True +# Force emulated frame buffers to be in N64 native resolution +InN64Resolution = False +# Try to reduce Video RAM usage (should never be used) +SaveVRAM = False +# Enable this option to have better render-to-texture quality +DoubleSizeForSmallTxtrBuf = False +# Force to use normal color combiner +DefaultCombinerDisable = False +# Enable game-specific settings from INI file +EnableHacks = True +# If enabled, graphics will be drawn in WinFrame mode instead of solid and texture mode +WinFrameMode = False +# N64 Texture Memory Full Emulation (may fix some games, may break others) +FullTMEMEmulation = False +# Enable vertex clipper for fog operations +OpenGLVertexClipper = False +# Enable/Disable SSE optimizations for capable CPUs +EnableSSE = True +# If this option is enabled, the plugin will skip every other frame +SkipFrame = False +# If enabled, texture enhancement will be done only for TxtRect ucode +TexRectOnly = False +# If enabled, texture enhancement will be done only for textures width+height<=128 +SmallTextureOnly = False +# Select hi-resolution textures based only on the CRC and ignore format+size information (Glide64 compatibility) +LoadHiResCRCOnly = True +# Enable hi-resolution texture file loading +LoadHiResTextures = False +# Enable texture dumping +DumpTexturesToFiles = False +# Display On-screen FPS +ShowFPS = False +# Use Mipmapping? 0=no, 1=nearest, 2=bilinear, 3=trilinear +Mipmapping = 2 +# Enable, Disable fog generation (0=Disable, 1=Enable) +FogMethod = 1 +# Force to use texture filtering or not (0=auto: n64 choose, 1=force no filtering, 2=force filtering) +ForceTextureFilter = 0 +# Primary texture enhancement filter (0=None, 1=2X, 2=2XSAI, 3=HQ2X, 4=LQ2X, 5=HQ4X, 6=Sharpen, 7=Sharpen More, 8=External, 9=Mirrored) +TextureEnhancement = 0 +# Secondary texture enhancement filter (0 = none, 1-4 = filtered) +TextureEnhancementControl = 0 +# Color bit depth to use for textures (0=default, 1=32 bits, 2=16 bits) +TextureQuality = 0 +# Z-buffer depth (only 16 or 32) +OpenGLDepthBufferSetting = 16 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Color bit depth for rendering window (0=32 bits, 1=16 bits) +ColorQuality = 1 +# OpenGL level to support (0=auto, 1=OGL_FRAGMENT_PROGRAM) +OpenGLRenderSetting = 0 +# Enable/Disable Anisotropic Filtering for Mipmapping (0=no filtering, 2-16=quality). This is uneffective if Mipmapping is 0. If the given value is to high to be supported by your graphic card, the value will be the highest value your graphic card can support. Better result with Trilinear filtering +AnisotropicFiltering = 0 +# If true, use polygon offset values specified below +ForcePolygonOffset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +PolygonOffsetFactor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +PolygonOffsetUnits = 0.000000 diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/S922X/mupen64plus.cfg b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/S922X/mupen64plus.cfg new file mode 100644 index 0000000000..9d75f74f35 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/S922X/mupen64plus.cfg @@ -0,0 +1,708 @@ +# Mupen64Plus Configuration File +# This file is automatically read and written by the Mupen64Plus Core library + +[64DD] + +# Filename of the 64DD IPL ROM +IPL-ROM = "" +# Filename of the disk to load into Disk Drive +Disk = "" + + +[Audio-SDL] + +# Mupen64Plus SDL Audio Plugin config parameter version number +Version = 1.000000 +# Frequency which is used if rom doesn't want to change it +DEFAULT_FREQUENCY = 33600 +# Swaps left and right channels +SWAP_CHANNELS = False +# Size of primary buffer in output samples. This is where audio is loaded after it's extracted from n64's memory. +PRIMARY_BUFFER_SIZE = 16384 +# Fullness level target for Primary audio buffer, in equivalent output samples. This value must be larger than the SECONDARY_BUFFER_SIZE. Decreasing this value will reduce audio latency but requires a faster PC to avoid choppiness. Increasing this will increase audio latency but reduce the chance of drop-outs. +PRIMARY_BUFFER_TARGET = 2048 +# Size of secondary buffer in output samples. This is SDL's hardware buffer. The SDL documentation states that this should be a power of two between 512 and 8192. +SECONDARY_BUFFER_SIZE = 1024 +# Audio resampling algorithm. src-sinc-best-quality, src-sinc-medium-quality, src-sinc-fastest, src-zero-order-hold, src-linear, speex-fixed-{10-0}, trivial +RESAMPLE = "trivial" +# Volume control type: 1 = SDL (only affects Mupen64Plus output) 2 = OSS mixer (adjusts master PC volume) +VOLUME_CONTROL_TYPE = 1 +# Percentage change each time the volume is increased or decreased +VOLUME_ADJUST = 5 +# Default volume when a game is started. Only used if VOLUME_CONTROL_TYPE is 1 +VOLUME_DEFAULT = 100 +# Synchronize Video/Audio +AUDIO_SYNC = False + + +[Core] + +# Mupen64Plus Core config parameter set version number. Please don't change this version number. +Version = 1.010000 +# Draw on-screen display if True, otherwise don't draw OSD +OnScreenDisplay = True +# Use Pure Interpreter if 0, Cached Interpreter if 1, or Dynamic Recompiler if 2 or more +R4300Emulator = 2 +# Disable compiled jump commands in dynamic recompiler (should be set to False) +NoCompiledJump = False +# Disable 4MB expansion RAM pack. May be necessary for some games +DisableExtraMem = False +# Increment the save state slot after each save operation +AutoStateSlotIncrement = False +# Activate the R4300 debugger when ROM execution begins, if core was built with Debugger support +EnableDebugger = False +# Save state slot (0-9) to use when saving/loading the emulator state +CurrentStateSlot = 0 +# Path to directory where screenshots are saved. If this is blank, the default value of ${UserDataPath}/screenshot will be used +ScreenshotPath = "/storage/roms/screenshots" +# Path to directory where emulator save states (snapshots) are saved. If this is blank, the default value of ${UserDataPath}/save will be used +SaveStatePath = "/storage/roms/n64" +# Path to directory where SRAM/EEPROM data (in-game saves) are stored. If this is blank, the default value of ${UserDataPath}/save will be used +SaveSRAMPath = "/storage/roms/n64" +# Path to a directory to search when looking for shared data files +SharedDataPath = "/storage/.config/game/configs/mupen64plussa" +# Force number of cycles per emulated instruction +CountPerOp = 0 +# Randomize PI/SI Interrupt Timing +RandomizeInterrupt = True +# Duration of SI DMA (-1: use per game settings) +SiDmaDuration = -1 +# Gameboy Camera Video Capture backend +GbCameraVideoCaptureBackend1 = "" +# Disk Save Format (0: Full Disk Copy (*.ndr/*.d6r), 1: RAM Area Only (*.ram)) +SaveDiskFormat = 1 + + +[CoreEvents] + +# Mupen64Plus CoreEvents config parameter set version number. Please don't change this version number. +Version = 1.000000 +# SDL keysym for stopping the emulator +Kbd Mapping Stop = 27 +# SDL keysym for switching between fullscreen/windowed modes +Kbd Mapping Fullscreen = 0 +# SDL keysym for saving the emulator state +Kbd Mapping Save State = 286 +# SDL keysym for loading the emulator state +Kbd Mapping Load State = 288 +# SDL keysym for advancing the save state slot +Kbd Mapping Increment Slot = 0 +# SDL keysym for resetting the emulator +Kbd Mapping Reset = 290 +# SDL keysym for slowing down the emulator +Kbd Mapping Speed Down = 291 +# SDL keysym for speeding up the emulator +Kbd Mapping Speed Up = 292 +# SDL keysym for taking a screenshot +Kbd Mapping Screenshot = 293 +# SDL keysym for pausing the emulator +Kbd Mapping Pause = 112 +# SDL keysym for muting/unmuting the sound +Kbd Mapping Mute = 109 +# SDL keysym for increasing the volume +Kbd Mapping Increase Volume = 93 +# SDL keysym for decreasing the volume +Kbd Mapping Decrease Volume = 91 +# SDL keysym for temporarily going really fast +Kbd Mapping Fast Forward = 102 +# SDL keysym for advancing by one frame when paused +Kbd Mapping Frame Advance = 47 +# SDL keysym for pressing the game shark button +Kbd Mapping Gameshark = 103 +# Joystick event string for stopping the emulator +Joy Mapping Stop = "J0B11/B10" +# Joystick event string for switching between fullscreen/windowed modes +Joy Mapping Fullscreen = "" +# Joystick event string for saving the emulator state +Joy Mapping Save State = "J0B11/B6" +# Joystick event string for loading the emulator state +Joy Mapping Load State = "J0B11/B5" +# Joystick event string for advancing the save state slot +Joy Mapping Increment Slot = "" +# Joystick event string for resetting the emulator +Joy Mapping Reset = "J0B11/B0" +# Joystick event string for slowing down the emulator +Joy Mapping Speed Down = "" +# Joystick event string for speeding up the emulator +Joy Mapping Speed Up = "" +# Joystick event string for taking a screenshot +Joy Mapping Screenshot = "J0B11/B4" +# Joystick event string for pausing the emulator +Joy Mapping Pause = "" +# Joystick event string for muting/unmuting the sound +Joy Mapping Mute = "" +# Joystick event string for increasing the volume +Joy Mapping Increase Volume = "" +# Joystick event string for decreasing the volume +Joy Mapping Decrease Volume = "" +# Joystick event string for fast-forward +Joy Mapping Fast Forward = "" +# Joystick event string for advancing by one frame when paused +Joy Mapping Frame Advance = "" +# Joystick event string for pressing the game shark button +Joy Mapping Gameshark = "" +# SDL keysym for save slot 0 +Kbd Mapping Slot 0 = 48 +# SDL keysym for save slot 1 +Kbd Mapping Slot 1 = 49 +# SDL keysym for save slot 2 +Kbd Mapping Slot 2 = 50 +# SDL keysym for save slot 3 +Kbd Mapping Slot 3 = 51 +# SDL keysym for save slot 4 +Kbd Mapping Slot 4 = 52 +# SDL keysym for save slot 5 +Kbd Mapping Slot 5 = 53 +# SDL keysym for save slot 6 +Kbd Mapping Slot 6 = 54 +# SDL keysym for save slot 7 +Kbd Mapping Slot 7 = 55 +# SDL keysym for save slot 8 +Kbd Mapping Slot 8 = 56 +# SDL keysym for save slot 9 +Kbd Mapping Slot 9 = 57 + + +[Input-SDL-Control1] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = 0 +# SDL joystick name (or Keyboard) +name = "GO-Ultra Gamepad" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = True +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "0,0" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = button(17) +DPad L = button(16) +DPad D = button(15) +DPad U = button(14) +Start = button(10) +Z Trig = button(5) button(8) +B Button = button(4) +A Button = button(0) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(6) +L Trig = button(7) +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Input-SDL-Control2] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control3] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control4] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Rsp-HLE] + +# Mupen64Plus RSP HLE Plugin config parameter version number +Version = 1.000000 +# Path to a RSP plugin which will be used when encountering an unknown ucode.You can disable this by letting an empty string. +RspFallback = "" +# Send display lists to the graphics plugin +DisplayListToGraphicsPlugin = True +# Send audio lists to the audio plugin +AudioListToAudioPlugin = False + + +[Transferpak] + +# Filename of the GB ROM to load into transferpak 1 +GB-rom-1 = "" +# Filename of the GB RAM to load into transferpak 1 +GB-ram-1 = "" +# Filename of the GB ROM to load into transferpak 2 +GB-rom-2 = "" +# Filename of the GB RAM to load into transferpak 2 +GB-ram-2 = "" +# Filename of the GB ROM to load into transferpak 3 +GB-rom-3 = "" +# Filename of the GB RAM to load into transferpak 3 +GB-ram-3 = "" +# Filename of the GB ROM to load into transferpak 4 +GB-rom-4 = "" +# Filename of the GB RAM to load into transferpak 4 +GB-ram-4 = "" + + +[UI-Console] + +# Mupen64Plus UI-Console config parameter set version number. Please don't change this version number. +Version = 1.000000 +# Directory in which to search for plugins +PluginDir = "/usr/local/lib/mupen64plus" +# Filename of video plugin +VideoPlugin = "mupen64plus-video-rice" +# Filename of audio plugin +AudioPlugin = "mupen64plus-audio-sdl.so" +# Filename of input plugin +InputPlugin = "mupen64plus-input-sdl.so" +# Filename of RSP plugin +RspPlugin = "mupen64plus-rsp-cxd4.so" + + +[Video-General] + +# Width of output window or fullscreen width +ScreenWidth = 854 +# Height of output window or fullscreen height +ScreenHeight = 480 +# Use fullscreen mode if True, or windowed mode if False +Fullscreen = True +# If true, activate the SDL_GL_SWAP_CONTROL attribute +VerticalSync = True +# Rotate screen contents: 0=0 degree, 1=90 degree, 2 = 180 degree, 3=270 degree +Rotate = 0 + +[Video-Parallel] + +# Amount of rescaling: 1=None, 2=2x, 4=4x +Upscaling = 1 +# Enable VSync +VSync = True +# Widescreen mode (stretched) +WidescreenStretch = False +# Deinterlacing method. False=Bob, True=Weave +DeinterlaceWeave = False +# Enable superscaling of readbacks when upsampling +SuperscaledReads = False +# Enable superscaling of dithering when upsampling +SuperscaledDither = True +# Enable synchronizing RDP and CPU +SynchronousRDP = True +# Amount of overscan pixels to crop on all sides +CropOverscan = 0 +# Amount of pixels to stretch by vertically. Can fix PAL ports that didn't fill the PAL resolution of 288p (use value of 24 in that case). +VerticalStretch = 0 +# VI anti-aliasing, smooths polygon edges. +VIAA = True +# Allow VI divot filter, cleans up stray black pixels. +Divot = True +# Allow VI gamma dither +GammaDither = True +# Allow VI bilinear scaling +VIBilerp = True +# Allow VI dedither filter +VIDither = True +# Downsampling factor, downscales output after VI, equivalent to SSAA. 0=disabled, 1=1/2, 2=1/4, 3=1/8 +DownScale = 0 +# Use native texture LOD computation when upscaling, effectively a LOD bias +NativeTextLOD = False +# Native resolution TEX_RECT. TEX_RECT primitives should generally be rendered at native resolution to avoid seams +NativeTextRECT = True +# Use fullscreen mode if True, or windowed mode if False +Fullscreen = True +# Screen width +ScreenWidth = 854 +# Screen height +ScreenHeight = 480 +# Deinterlacing method. False=Bob, True=Weave +DeinterlaceMode = False + +[Video-GLideN64] + +###### Hardware Compatibility ###### +# Leave enabled unless a mobile gpu doesn't support it. +EnableFragmentDepthWrite = 1 +# Hardware per pixel lighting, supposedly good for GLES3.1 devices or higher. +EnableHWLighting = 0 + +###### Enhancements ####### +# Internal render resoluton rather than output. So 2 x 240p is 480p, etc. +UseNativeResolutionFactor = 1 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Enable/Disable Fast Approximate Anti-Aliasing FXAA +FXAA = 0 +# Max level of Anisotropic Filtering, 0 for off +anisotropy = 0 +# Bilinear filtering mode (0=N64 3point, 1=standard) +# @rishooty: best to use this at 1x native res, any higher turn it off. +bilinearMode = 1 + +###### Compatibility ###### +# Make texrect coordinates continuous to avoid black lines between them. (0=Off/default, 1=Auto, 2=Force) +CorrectTexrectCoords = 1 +# Copy auxiliary buffers to RDRAM (default: 0) +EnableCopyAuxiliaryToRDRAM = 1 +# Render 2D texrects in native resolution to fix misalignment between parts of 2D image. (0=Off/default, 1=Optimized, 2=Unoptimized)") +EnableNativeResTexrects = 1 + +###### Other ###### +# Enable threaded video backend at the cost of input lag +ThreadedVideo = 1 +# Screen aspect ratio (0=stretch, 1=force 4:3, 2=force 16:9, 3=adjust) +AspectRatio = 1 +# Display On-screen FPS +ShowFPS = False + +[Video-Glide64mk2] + +# Enable full-scene anti-aliasing by setting this to a value greater than 1 +wrpAntiAliasing = 0 +# Card ID +card_id = 0 +# If true, use polygon offset values specified below +force_polygon_offset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +polygon_offset_factor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +polygon_offset_units = 0.000000 +# Vertical sync +vsync = True +# TODO:ssformat +ssformat = False +# Display performance stats (add together desired flags): 1=FPS counter, 2=VI/s counter, 4=% speed, 8=FPS transparent +show_fps = 0 +# Clock enabled +clock = False +# Clock is 24-hour +clock_24_hr = True +# Wrapper resolution +wrpResolution = 0 +# Wrapper VRAM +wrpVRAM = 0 +# Wrapper FBO +wrpFBO = True +# Wrapper Anisotropic Filtering +wrpAnisotropic = True +# Texture Enhancement: Smooth/Sharpen Filters +ghq_fltr = 0 +# Texture Compression: 0 for S3TC, 1 for FXT1 +ghq_cmpr = 0 +# Texture Enhancement: More filters +ghq_enht = 0 +# Hi-res texture pack format (0 for none, 1 for Rice) +ghq_hirs = 1 +# Compress texture cache with S3TC or FXT1 +ghq_enht_cmpr = False +# Tile textures (saves memory but could cause issues) +ghq_enht_tile = 0 +# Force 16bpp textures (saves ram but lower quality) +ghq_enht_f16bpp = False +# Compress texture cache +ghq_enht_gz = True +# Don't enhance textures for backgrounds +ghq_enht_nobg = False +# Enable S3TC and FXT1 compression +ghq_hirs_cmpr = False +# Tile hi-res textures (saves memory but could cause issues) +ghq_hirs_tile = False +# Force 16bpp hi-res textures (saves ram but lower quality) +ghq_hirs_f16bpp = False +# Compress hi-res texture cache +ghq_hirs_gz = True +# Alternative CRC calculation -- emulates Rice bug +ghq_hirs_altcrc = True +# Save tex cache to disk +ghq_cache_save = True +# Texture Cache Size (MB) +ghq_cache_size = 128 +# Use full alpha channel -- could cause issues for some tex packs +ghq_hirs_let_texartists_fly = False +# Dump textures +ghq_hirs_dump = False +# Alternate texture size method: -1=Game default, 0=disable. 1=enable +alt_tex_size = -1 +# Use first SETTILESIZE only: -1=Game default, 0=disable. 1=enable +use_sts1_only = -1 +# Use spheric mapping only: -1=Game default, 0=disable. 1=enable +force_calc_sphere = -1 +# Force positive viewport: -1=Game default, 0=disable. 1=enable +correct_viewport = -1 +# Force texrect size to integral value: -1=Game default, 0=disable. 1=enable +increase_texrect_edge = -1 +# Reduce fillrect size by 1: -1=Game default, 0=disable. 1=enable +decrease_fillrect_edge = -1 +# Enable perspective texture correction emulation: -1=Game default, 0=disable. 1=enable +texture_correction = -1 +# Set special scale for PAL games: -1=Game default, 0=disable. 1=enable +pal230 = -1 +# 3DFX Dithered alpha emulation mode: -1=Game default, >=0=dithered alpha emulation mode +stipple_mode = -1 +# 3DFX Dithered alpha pattern: -1=Game default, >=0=pattern used for dithered alpha emulation +stipple_pattern = -1 +# Check microcode each frame: -1=Game default, 0=disable. 1=enable +force_microcheck = -1 +# Force 0xb5 command to be quad, not line 3D: -1=Game default, 0=disable. 1=enable +force_quad3d = -1 +# Enable near z clipping: -1=Game default, 0=disable. 1=enable +clip_zmin = -1 +# Enable far plane clipping: -1=Game default, 0=disable. 1=enable +clip_zmax = -1 +# Use fast CRC algorithm: -1=Game default, 0=disable. 1=enable +fast_crc = -1 +# Adjust screen aspect for wide screen mode: -1=Game default, 0=disable. 1=enable +adjust_aspect = -1 +# Force strict check in Depth buffer test: -1=Game default, 0=disable. 1=enable +zmode_compare_less = -1 +# Apply alpha dither regardless of alpha_dither_mode: -1=Game default, 0=disable. 1=enable +old_style_adither = -1 +# Scale vertex z value before writing to depth buffer: -1=Game default, 0=disable. 1=enable +n64_z_scale = -1 +# Fast texrect rendering with hwfbe: -1=Game default, 0=disable. 1=enable +optimize_texrect = -1 +# Do not copy auxiliary frame buffers: -1=Game default, 0=disable. 1=enable +ignore_aux_copy = -1 +# Clear auxiliary texture frame buffers: -1=Game default, 0=disable. 1=enable +hires_buf_clear = -1 +# Read alpha from framebuffer: -1=Game default, 0=disable. 1=enable +fb_read_alpha = -1 +# Handle unchanged fb: -1=Game default, 0=disable. 1=enable +useless_is_useless = -1 +# Set frambuffer CRC mode: -1=Game default, 0=disable CRC, 1=fast CRC, 2=safe CRC +fb_crc_mode = -1 +# Filtering mode: -1=Game default, 0=automatic, 1=force bilinear, 2=force point sampled +filtering = -1 +# Fog: -1=Game default, 0=disable. 1=enable +fog = -1 +# Buffer clear on every frame: -1=Game default, 0=disable. 1=enable +buff_clear = -1 +# Buffer swapping method: -1=Game default, 0=swap buffers when vertical interrupt has occurred, 1=swap buffers when set of conditions is satisfied. Prevents flicker on some games, 2=mix of first two methods +swapmode = -1 +# Aspect ratio: -1=Game default, 0=Force 4:3, 1=Force 16:9, 2=Stretch, 3=Original +aspect = -1 +# LOD calculation: -1=Game default, 0=disable. 1=fast, 2=precise +lodmode = -1 +# Smart framebuffer: -1=Game default, 0=disable. 1=enable +fb_smart = -1 +# Hardware frame buffer emulation: -1=Game default, 0=disable. 1=enable +fb_hires = -1 +# Read framebuffer every frame (may be slow use only for effects that need it e.g. Banjo Kazooie, DK64 transitions): -1=Game default, 0=disable. 1=enable +fb_read_always = -1 +# Render N64 frame buffer as texture: -1=Game default, 0=disable, 1=mode1, 2=mode2 +read_back_to_screen = -1 +# Show images written directly by CPU: -1=Game default, 0=disable. 1=enable +detect_cpu_write = -1 +# Get frame buffer info: -1=Game default, 0=disable. 1=enable +fb_get_info = -1 +# Enable software depth render: -1=Game default, 0=disable. 1=enable +fb_render = -1 +# If true, skip up to maxframeskip frames to maintain clock schedule; if false, skip exactly maxframeskip frames +autoframeskip = False +# If autoframeskip is true, skip up to this many frames to maintain clock schedule; if autoframeskip is false, skip exactly this many frames +maxframeskip = 0 + + +[Video-Rice] + +# Mupen64Plus Rice Video Plugin config parameter version number +Version = 1 +# Frame Buffer Emulation (0=ROM default, 1=disable) +FrameBufferSetting = 0 +# Frequency to write back the frame buffer (0=every frame, 1=every other frame, etc) +FrameBufferWriteBackControl = 0 +# Render-to-texture emulation (0=none, 1=ignore, 2=normal, 3=write back, 4=write back and reload) +RenderToTexture = 0 +# Control when the screen will be updated (0=ROM default, 1=VI origin update, 2=VI origin change, 3=CI change, 4=first CI change, 5=first primitive draw, 6=before screen clear, 7=after screen drawn) +ScreenUpdateSetting = 4 +# Force to use normal alpha blender +NormalAlphaBlender = False +# Use a faster algorithm to speed up texture loading and CRC computation +FastTextureLoading = False +# Use different texture coordinate clamping code +AccurateTextureMapping = True +# Force emulated frame buffers to be in N64 native resolution +InN64Resolution = False +# Try to reduce Video RAM usage (should never be used) +SaveVRAM = False +# Enable this option to have better render-to-texture quality +DoubleSizeForSmallTxtrBuf = False +# Force to use normal color combiner +DefaultCombinerDisable = False +# Enable game-specific settings from INI file +EnableHacks = True +# If enabled, graphics will be drawn in WinFrame mode instead of solid and texture mode +WinFrameMode = False +# N64 Texture Memory Full Emulation (may fix some games, may break others) +FullTMEMEmulation = False +# Enable vertex clipper for fog operations +OpenGLVertexClipper = False +# Enable/Disable SSE optimizations for capable CPUs +EnableSSE = True +# If this option is enabled, the plugin will skip every other frame +SkipFrame = False +# If enabled, texture enhancement will be done only for TxtRect ucode +TexRectOnly = False +# If enabled, texture enhancement will be done only for textures width+height<=128 +SmallTextureOnly = False +# Select hi-resolution textures based only on the CRC and ignore format+size information (Glide64 compatibility) +LoadHiResCRCOnly = True +# Enable hi-resolution texture file loading +LoadHiResTextures = False +# Enable texture dumping +DumpTexturesToFiles = False +# Display On-screen FPS +ShowFPS = False +# Use Mipmapping? 0=no, 1=nearest, 2=bilinear, 3=trilinear +Mipmapping = 2 +# Enable, Disable fog generation (0=Disable, 1=Enable) +FogMethod = 1 +# Force to use texture filtering or not (0=auto: n64 choose, 1=force no filtering, 2=force filtering) +ForceTextureFilter = 0 +# Primary texture enhancement filter (0=None, 1=2X, 2=2XSAI, 3=HQ2X, 4=LQ2X, 5=HQ4X, 6=Sharpen, 7=Sharpen More, 8=External, 9=Mirrored) +TextureEnhancement = 0 +# Secondary texture enhancement filter (0 = none, 1-4 = filtered) +TextureEnhancementControl = 0 +# Color bit depth to use for textures (0=default, 1=32 bits, 2=16 bits) +TextureQuality = 0 +# Z-buffer depth (only 16 or 32) +OpenGLDepthBufferSetting = 16 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Color bit depth for rendering window (0=32 bits, 1=16 bits) +ColorQuality = 1 +# OpenGL level to support (0=auto, 1=OGL_FRAGMENT_PROGRAM) +OpenGLRenderSetting = 0 +# Enable/Disable Anisotropic Filtering for Mipmapping (0=no filtering, 2-16=quality). This is uneffective if Mipmapping is 0. If the given value is to high to be supported by your graphic card, the value will be the highest value your graphic card can support. Better result with Trilinear filtering +AnisotropicFiltering = 0 +# If true, use polygon offset values specified below +ForcePolygonOffset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +PolygonOffsetFactor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +PolygonOffsetUnits = 0.000000 diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/SDM845/mupen64plus.cfg b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/SDM845/mupen64plus.cfg new file mode 100644 index 0000000000..590878aad8 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/SDM845/mupen64plus.cfg @@ -0,0 +1,670 @@ +# Mupen64Plus Configuration File +# This file is automatically read and written by the Mupen64Plus Core library + +[64DD] + +# Filename of the 64DD IPL ROM +IPL-ROM = "" +# Filename of the disk to load into Disk Drive +Disk = "" + + +[Audio-SDL] + +# Mupen64Plus SDL Audio Plugin config parameter version number +Version = 1.000000 +# Frequency which is used if rom doesn't want to change it +DEFAULT_FREQUENCY = 33600 +# Swaps left and right channels +SWAP_CHANNELS = False +# Size of primary buffer in output samples. This is where audio is loaded after it's extracted from n64's memory. +PRIMARY_BUFFER_SIZE = 16384 +# Fullness level target for Primary audio buffer, in equivalent output samples. This value must be larger than the SECONDARY_BUFFER_SIZE. Decreasing this value will reduce audio latency but requires a faster PC to avoid choppiness. Increasing this will increase audio latency but reduce the chance of drop-outs. +PRIMARY_BUFFER_TARGET = 2048 +# Size of secondary buffer in output samples. This is SDL's hardware buffer. The SDL documentation states that this should be a power of two between 512 and 8192. +SECONDARY_BUFFER_SIZE = 1024 +# Audio resampling algorithm. src-sinc-best-quality, src-sinc-medium-quality, src-sinc-fastest, src-zero-order-hold, src-linear, speex-fixed-{10-0}, trivial +RESAMPLE = "trivial" +# Volume control type: 1 = SDL (only affects Mupen64Plus output) 2 = OSS mixer (adjusts master PC volume) +VOLUME_CONTROL_TYPE = 1 +# Percentage change each time the volume is increased or decreased +VOLUME_ADJUST = 5 +# Default volume when a game is started. Only used if VOLUME_CONTROL_TYPE is 1 +VOLUME_DEFAULT = 100 +# Synchronize Video/Audio +AUDIO_SYNC = False + + +[Core] + +# Mupen64Plus Core config parameter set version number. Please don't change this version number. +Version = 1.010000 +# Draw on-screen display if True, otherwise don't draw OSD +OnScreenDisplay = True +# Use Pure Interpreter if 0, Cached Interpreter if 1, or Dynamic Recompiler if 2 or more +R4300Emulator = 2 +# Disable compiled jump commands in dynamic recompiler (should be set to False) +NoCompiledJump = False +# Disable 4MB expansion RAM pack. May be necessary for some games +DisableExtraMem = False +# Increment the save state slot after each save operation +AutoStateSlotIncrement = False +# Activate the R4300 debugger when ROM execution begins, if core was built with Debugger support +EnableDebugger = False +# Save state slot (0-9) to use when saving/loading the emulator state +CurrentStateSlot = 0 +# Path to directory where screenshots are saved. If this is blank, the default value of ${UserDataPath}/screenshot will be used +ScreenshotPath = "/storage/roms/screenshots" +# Path to directory where emulator save states (snapshots) are saved. If this is blank, the default value of ${UserDataPath}/save will be used +SaveStatePath = "/storage/roms/n64" +# Path to directory where SRAM/EEPROM data (in-game saves) are stored. If this is blank, the default value of ${UserDataPath}/save will be used +SaveSRAMPath = "/storage/roms/n64" +# Path to a directory to search when looking for shared data files +SharedDataPath = "/storage/.config/game/configs/mupen64plussa" +# Force number of cycles per emulated instruction +CountPerOp = 0 +# Randomize PI/SI Interrupt Timing +RandomizeInterrupt = True +# Duration of SI DMA (-1: use per game settings) +SiDmaDuration = -1 +# Gameboy Camera Video Capture backend +GbCameraVideoCaptureBackend1 = "" +# Disk Save Format (0: Full Disk Copy (*.ndr/*.d6r), 1: RAM Area Only (*.ram)) +SaveDiskFormat = 1 + + +[CoreEvents] + +# Mupen64Plus CoreEvents config parameter set version number. Please don't change this version number. +Version = 1.000000 +# SDL keysym for stopping the emulator +Kbd Mapping Stop = 27 +# SDL keysym for switching between fullscreen/windowed modes +Kbd Mapping Fullscreen = 0 +# SDL keysym for saving the emulator state +Kbd Mapping Save State = 286 +# SDL keysym for loading the emulator state +Kbd Mapping Load State = 288 +# SDL keysym for advancing the save state slot +Kbd Mapping Increment Slot = 0 +# SDL keysym for resetting the emulator +Kbd Mapping Reset = 290 +# SDL keysym for slowing down the emulator +Kbd Mapping Speed Down = 291 +# SDL keysym for speeding up the emulator +Kbd Mapping Speed Up = 292 +# SDL keysym for taking a screenshot +Kbd Mapping Screenshot = 293 +# SDL keysym for pausing the emulator +Kbd Mapping Pause = 112 +# SDL keysym for muting/unmuting the sound +Kbd Mapping Mute = 109 +# SDL keysym for increasing the volume +Kbd Mapping Increase Volume = 93 +# SDL keysym for decreasing the volume +Kbd Mapping Decrease Volume = 91 +# SDL keysym for temporarily going really fast +Kbd Mapping Fast Forward = 102 +# SDL keysym for advancing by one frame when paused +Kbd Mapping Frame Advance = 47 +# SDL keysym for pressing the game shark button +Kbd Mapping Gameshark = 103 +# Joystick event string for stopping the emulator +Joy Mapping Stop = "J0B7/B8" +# Joystick event string for switching between fullscreen/windowed modes +Joy Mapping Fullscreen = "" +# Joystick event string for saving the emulator state +Joy Mapping Save State = "J0B10/B5" +# Joystick event string for loading the emulator state +Joy Mapping Load State = "J0B10/B4" +# Joystick event string for advancing the save state slot +Joy Mapping Increment Slot = "" +# Joystick event string for resetting the emulator +Joy Mapping Reset = "J0B10/B0" +# Joystick event string for slowing down the emulator +Joy Mapping Speed Down = "" +# Joystick event string for speeding up the emulator +Joy Mapping Speed Up = "" +# Joystick event string for taking a screenshot +Joy Mapping Screenshot = "J0B10/B1" +# Joystick event string for pausing the emulator +Joy Mapping Pause = "" +# Joystick event string for muting/unmuting the sound +Joy Mapping Mute = "" +# Joystick event string for increasing the volume +Joy Mapping Increase Volume = "" +# Joystick event string for decreasing the volume +Joy Mapping Decrease Volume = "" +# Joystick event string for fast-forward +Joy Mapping Fast Forward = "" +# Joystick event string for advancing by one frame when paused +Joy Mapping Frame Advance = "" +# Joystick event string for pressing the game shark button +Joy Mapping Gameshark = "" +# SDL keysym for save slot 0 +Kbd Mapping Slot 0 = 48 +# SDL keysym for save slot 1 +Kbd Mapping Slot 1 = 49 +# SDL keysym for save slot 2 +Kbd Mapping Slot 2 = 50 +# SDL keysym for save slot 3 +Kbd Mapping Slot 3 = 51 +# SDL keysym for save slot 4 +Kbd Mapping Slot 4 = 52 +# SDL keysym for save slot 5 +Kbd Mapping Slot 5 = 53 +# SDL keysym for save slot 6 +Kbd Mapping Slot 6 = 54 +# SDL keysym for save slot 7 +Kbd Mapping Slot 7 = 55 +# SDL keysym for save slot 8 +Kbd Mapping Slot 8 = 56 +# SDL keysym for save slot 9 +Kbd Mapping Slot 9 = 57 + + +[Input-SDL-Control1] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = 0 +# SDL joystick name (or Keyboard) +name = "rg552_joypad" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = True +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "0,0" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +; AYN Odin Gamepad - default.ini +[AYN Odin Gamepad] +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = button(16) +DPad L = button(15) +DPad D = button(14) +DPad U = button(13) +Start = button(9) +Z Trig = axis(5+) +B Button = button(3) +A Button = button(0) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Input-SDL-Control2] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control3] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control4] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Rsp-HLE] + +# Mupen64Plus RSP HLE Plugin config parameter version number +Version = 1.000000 +# Path to a RSP plugin which will be used when encountering an unknown ucode.You can disable this by letting an empty string. +RspFallback = "" +# Send display lists to the graphics plugin +DisplayListToGraphicsPlugin = True +# Send audio lists to the audio plugin +AudioListToAudioPlugin = False + + +[Transferpak] + +# Filename of the GB ROM to load into transferpak 1 +GB-rom-1 = "" +# Filename of the GB RAM to load into transferpak 1 +GB-ram-1 = "" +# Filename of the GB ROM to load into transferpak 2 +GB-rom-2 = "" +# Filename of the GB RAM to load into transferpak 2 +GB-ram-2 = "" +# Filename of the GB ROM to load into transferpak 3 +GB-rom-3 = "" +# Filename of the GB RAM to load into transferpak 3 +GB-ram-3 = "" +# Filename of the GB ROM to load into transferpak 4 +GB-rom-4 = "" +# Filename of the GB RAM to load into transferpak 4 +GB-ram-4 = "" + + +[UI-Console] + +# Mupen64Plus UI-Console config parameter set version number. Please don't change this version number. +Version = 1.000000 +# Directory in which to search for plugins +PluginDir = "/usr/local/lib/mupen64plus" +# Filename of video plugin +VideoPlugin = "mupen64plus-video-rice" +# Filename of audio plugin +AudioPlugin = "mupen64plus-audio-sdl.so" +# Filename of input plugin +InputPlugin = "mupen64plus-input-sdl.so" +# Filename of RSP plugin +RspPlugin = "mupen64plus-rsp-hle.so" + + +[Video-General] + +# Width of output window or fullscreen width +ScreenWidth = 1280 +# Height of output window or fullscreen height +ScreenHeight = 960 +# Use fullscreen mode if True, or windowed mode if False +Fullscreen = True +# If true, activate the SDL_GL_SWAP_CONTROL attribute +VerticalSync = True +# Rotate screen contents: 0=0 degree, 1=90 degree, 2 = 180 degree, 3=270 degree +Rotate = 0 + +[Video-GLideN64] + +###### Hardware Compatibility ###### +# Leave enabled unless a mobile gpu doesn't support it. +EnableFragmentDepthWrite = 1 +# Hardware per pixel lighting, supposedly good for GLES3.1 devices or higher. +EnableHWLighting = 0 + +###### Enhancements ####### +# Internal render resoluton rather than output. So 2 x 240p is 480p, etc. +UseNativeResolutionFactor = 1 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Enable/Disable Fast Approximate Anti-Aliasing FXAA +FXAA = 0 +# Max level of Anisotropic Filtering, 0 for off +anisotropy = 0 +# Bilinear filtering mode (0=N64 3point, 1=standard) +# @rishooty: best to use this at 1x native res, any higher turn it off. +bilinearMode = 1 + +###### Compatibility ###### +# Make texrect coordinates continuous to avoid black lines between them. (0=Off/default, 1=Auto, 2=Force) +CorrectTexrectCoords = 1 +# Copy auxiliary buffers to RDRAM (default: 0) +EnableCopyAuxiliaryToRDRAM = 1 +# Render 2D texrects in native resolution to fix misalignment between parts of 2D image. (0=Off/default, 1=Optimized, 2=Unoptimized)") +EnableNativeResTexrects = 1 + +###### Other ###### +# Enable threaded video backend at the cost of input lag +ThreadedVideo = 1 +# Screen aspect ratio (0=stretch, 1=force 4:3, 2=force 16:9, 3=adjust) +AspectRatio = 1 +# Display On-screen FPS +ShowFPS = False + +[Video-Glide64mk2] + +# Enable full-scene anti-aliasing by setting this to a value greater than 1 +wrpAntiAliasing = 0 +# Card ID +card_id = 0 +# If true, use polygon offset values specified below +force_polygon_offset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +polygon_offset_factor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +polygon_offset_units = 0.000000 +# Vertical sync +vsync = True +# TODO:ssformat +ssformat = False +# Display performance stats (add together desired flags): 1=FPS counter, 2=VI/s counter, 4=% speed, 8=FPS transparent +show_fps = 0 +# Clock enabled +clock = False +# Clock is 24-hour +clock_24_hr = True +# Wrapper resolution +wrpResolution = 0 +# Wrapper VRAM +wrpVRAM = 0 +# Wrapper FBO +wrpFBO = True +# Wrapper Anisotropic Filtering +wrpAnisotropic = True +# Texture Enhancement: Smooth/Sharpen Filters +ghq_fltr = 0 +# Texture Compression: 0 for S3TC, 1 for FXT1 +ghq_cmpr = 0 +# Texture Enhancement: More filters +ghq_enht = 0 +# Hi-res texture pack format (0 for none, 1 for Rice) +ghq_hirs = 1 +# Compress texture cache with S3TC or FXT1 +ghq_enht_cmpr = False +# Tile textures (saves memory but could cause issues) +ghq_enht_tile = 0 +# Force 16bpp textures (saves ram but lower quality) +ghq_enht_f16bpp = False +# Compress texture cache +ghq_enht_gz = True +# Don't enhance textures for backgrounds +ghq_enht_nobg = False +# Enable S3TC and FXT1 compression +ghq_hirs_cmpr = False +# Tile hi-res textures (saves memory but could cause issues) +ghq_hirs_tile = False +# Force 16bpp hi-res textures (saves ram but lower quality) +ghq_hirs_f16bpp = False +# Compress hi-res texture cache +ghq_hirs_gz = True +# Alternative CRC calculation -- emulates Rice bug +ghq_hirs_altcrc = True +# Save tex cache to disk +ghq_cache_save = True +# Texture Cache Size (MB) +ghq_cache_size = 128 +# Use full alpha channel -- could cause issues for some tex packs +ghq_hirs_let_texartists_fly = False +# Dump textures +ghq_hirs_dump = False +# Alternate texture size method: -1=Game default, 0=disable. 1=enable +alt_tex_size = -1 +# Use first SETTILESIZE only: -1=Game default, 0=disable. 1=enable +use_sts1_only = -1 +# Use spheric mapping only: -1=Game default, 0=disable. 1=enable +force_calc_sphere = -1 +# Force positive viewport: -1=Game default, 0=disable. 1=enable +correct_viewport = -1 +# Force texrect size to integral value: -1=Game default, 0=disable. 1=enable +increase_texrect_edge = -1 +# Reduce fillrect size by 1: -1=Game default, 0=disable. 1=enable +decrease_fillrect_edge = -1 +# Enable perspective texture correction emulation: -1=Game default, 0=disable. 1=enable +texture_correction = -1 +# Set special scale for PAL games: -1=Game default, 0=disable. 1=enable +pal230 = -1 +# 3DFX Dithered alpha emulation mode: -1=Game default, >=0=dithered alpha emulation mode +stipple_mode = -1 +# 3DFX Dithered alpha pattern: -1=Game default, >=0=pattern used for dithered alpha emulation +stipple_pattern = -1 +# Check microcode each frame: -1=Game default, 0=disable. 1=enable +force_microcheck = -1 +# Force 0xb5 command to be quad, not line 3D: -1=Game default, 0=disable. 1=enable +force_quad3d = -1 +# Enable near z clipping: -1=Game default, 0=disable. 1=enable +clip_zmin = -1 +# Enable far plane clipping: -1=Game default, 0=disable. 1=enable +clip_zmax = -1 +# Use fast CRC algorithm: -1=Game default, 0=disable. 1=enable +fast_crc = -1 +# Adjust screen aspect for wide screen mode: -1=Game default, 0=disable. 1=enable +adjust_aspect = -1 +# Force strict check in Depth buffer test: -1=Game default, 0=disable. 1=enable +zmode_compare_less = -1 +# Apply alpha dither regardless of alpha_dither_mode: -1=Game default, 0=disable. 1=enable +old_style_adither = -1 +# Scale vertex z value before writing to depth buffer: -1=Game default, 0=disable. 1=enable +n64_z_scale = -1 +# Fast texrect rendering with hwfbe: -1=Game default, 0=disable. 1=enable +optimize_texrect = -1 +# Do not copy auxiliary frame buffers: -1=Game default, 0=disable. 1=enable +ignore_aux_copy = -1 +# Clear auxiliary texture frame buffers: -1=Game default, 0=disable. 1=enable +hires_buf_clear = -1 +# Read alpha from framebuffer: -1=Game default, 0=disable. 1=enable +fb_read_alpha = -1 +# Handle unchanged fb: -1=Game default, 0=disable. 1=enable +useless_is_useless = -1 +# Set frambuffer CRC mode: -1=Game default, 0=disable CRC, 1=fast CRC, 2=safe CRC +fb_crc_mode = -1 +# Filtering mode: -1=Game default, 0=automatic, 1=force bilinear, 2=force point sampled +filtering = -1 +# Fog: -1=Game default, 0=disable. 1=enable +fog = -1 +# Buffer clear on every frame: -1=Game default, 0=disable. 1=enable +buff_clear = -1 +# Buffer swapping method: -1=Game default, 0=swap buffers when vertical interrupt has occurred, 1=swap buffers when set of conditions is satisfied. Prevents flicker on some games, 2=mix of first two methods +swapmode = -1 +# Aspect ratio: -1=Game default, 0=Force 4:3, 1=Force 16:9, 2=Stretch, 3=Original +aspect = -1 +# LOD calculation: -1=Game default, 0=disable. 1=fast, 2=precise +lodmode = -1 +# Smart framebuffer: -1=Game default, 0=disable. 1=enable +fb_smart = -1 +# Hardware frame buffer emulation: -1=Game default, 0=disable. 1=enable +fb_hires = -1 +# Read framebuffer every frame (may be slow use only for effects that need it e.g. Banjo Kazooie, DK64 transitions): -1=Game default, 0=disable. 1=enable +fb_read_always = -1 +# Render N64 frame buffer as texture: -1=Game default, 0=disable, 1=mode1, 2=mode2 +read_back_to_screen = -1 +# Show images written directly by CPU: -1=Game default, 0=disable. 1=enable +detect_cpu_write = -1 +# Get frame buffer info: -1=Game default, 0=disable. 1=enable +fb_get_info = -1 +# Enable software depth render: -1=Game default, 0=disable. 1=enable +fb_render = -1 +# If true, skip up to maxframeskip frames to maintain clock schedule; if false, skip exactly maxframeskip frames +autoframeskip = False +# If autoframeskip is true, skip up to this many frames to maintain clock schedule; if autoframeskip is false, skip exactly this many frames +maxframeskip = 0 + + +[Video-Rice] + +# Mupen64Plus Rice Video Plugin config parameter version number +Version = 1 +# Frame Buffer Emulation (0=ROM default, 1=disable) +FrameBufferSetting = 0 +# Frequency to write back the frame buffer (0=every frame, 1=every other frame, etc) +FrameBufferWriteBackControl = 0 +# Render-to-texture emulation (0=none, 1=ignore, 2=normal, 3=write back, 4=write back and reload) +RenderToTexture = 0 +# Control when the screen will be updated (0=ROM default, 1=VI origin update, 2=VI origin change, 3=CI change, 4=first CI change, 5=first primitive draw, 6=before screen clear, 7=after screen drawn) +ScreenUpdateSetting = 4 +# Force to use normal alpha blender +NormalAlphaBlender = False +# Use a faster algorithm to speed up texture loading and CRC computation +FastTextureLoading = False +# Use different texture coordinate clamping code +AccurateTextureMapping = True +# Force emulated frame buffers to be in N64 native resolution +InN64Resolution = False +# Try to reduce Video RAM usage (should never be used) +SaveVRAM = False +# Enable this option to have better render-to-texture quality +DoubleSizeForSmallTxtrBuf = False +# Force to use normal color combiner +DefaultCombinerDisable = False +# Enable game-specific settings from INI file +EnableHacks = True +# If enabled, graphics will be drawn in WinFrame mode instead of solid and texture mode +WinFrameMode = False +# N64 Texture Memory Full Emulation (may fix some games, may break others) +FullTMEMEmulation = False +# Enable vertex clipper for fog operations +OpenGLVertexClipper = False +# Enable/Disable SSE optimizations for capable CPUs +EnableSSE = True +# If this option is enabled, the plugin will skip every other frame +SkipFrame = False +# If enabled, texture enhancement will be done only for TxtRect ucode +TexRectOnly = False +# If enabled, texture enhancement will be done only for textures width+height<=128 +SmallTextureOnly = False +# Select hi-resolution textures based only on the CRC and ignore format+size information (Glide64 compatibility) +LoadHiResCRCOnly = True +# Enable hi-resolution texture file loading +LoadHiResTextures = False +# Enable texture dumping +DumpTexturesToFiles = False +# Display On-screen FPS +ShowFPS = False +# Use Mipmapping? 0=no, 1=nearest, 2=bilinear, 3=trilinear +Mipmapping = 2 +# Enable, Disable fog generation (0=Disable, 1=Enable) +FogMethod = 1 +# Force to use texture filtering or not (0=auto: n64 choose, 1=force no filtering, 2=force filtering) +ForceTextureFilter = 0 +# Primary texture enhancement filter (0=None, 1=2X, 2=2XSAI, 3=HQ2X, 4=LQ2X, 5=HQ4X, 6=Sharpen, 7=Sharpen More, 8=External, 9=Mirrored) +TextureEnhancement = 0 +# Secondary texture enhancement filter (0 = none, 1-4 = filtered) +TextureEnhancementControl = 0 +# Color bit depth to use for textures (0=default, 1=32 bits, 2=16 bits) +TextureQuality = 0 +# Z-buffer depth (only 16 or 32) +OpenGLDepthBufferSetting = 16 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Color bit depth for rendering window (0=32 bits, 1=16 bits) +ColorQuality = 1 +# OpenGL level to support (0=auto, 1=OGL_FRAGMENT_PROGRAM) +OpenGLRenderSetting = 0 +# Enable/Disable Anisotropic Filtering for Mipmapping (0=no filtering, 2-16=quality). This is uneffective if Mipmapping is 0. If the given value is to high to be supported by your graphic card, the value will be the highest value your graphic card can support. Better result with Trilinear filtering +AnisotropicFiltering = 0 +# If true, use polygon offset values specified below +ForcePolygonOffset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +PolygonOffsetFactor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +PolygonOffsetUnits = 0.000000 diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/SM8250/mupen64plus.cfg b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/SM8250/mupen64plus.cfg new file mode 100644 index 0000000000..80fddb807b --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/SM8250/mupen64plus.cfg @@ -0,0 +1,670 @@ +# Mupen64Plus Configuration File +# This file is automatically read and written by the Mupen64Plus Core library + +[64DD] + +# Filename of the 64DD IPL ROM +IPL-ROM = "" +# Filename of the disk to load into Disk Drive +Disk = "" + + +[Audio-SDL] + +# Mupen64Plus SDL Audio Plugin config parameter version number +Version = 1.000000 +# Frequency which is used if rom doesn't want to change it +DEFAULT_FREQUENCY = 33600 +# Swaps left and right channels +SWAP_CHANNELS = False +# Size of primary buffer in output samples. This is where audio is loaded after it's extracted from n64's memory. +PRIMARY_BUFFER_SIZE = 16384 +# Fullness level target for Primary audio buffer, in equivalent output samples. This value must be larger than the SECONDARY_BUFFER_SIZE. Decreasing this value will reduce audio latency but requires a faster PC to avoid choppiness. Increasing this will increase audio latency but reduce the chance of drop-outs. +PRIMARY_BUFFER_TARGET = 2048 +# Size of secondary buffer in output samples. This is SDL's hardware buffer. The SDL documentation states that this should be a power of two between 512 and 8192. +SECONDARY_BUFFER_SIZE = 1024 +# Audio resampling algorithm. src-sinc-best-quality, src-sinc-medium-quality, src-sinc-fastest, src-zero-order-hold, src-linear, speex-fixed-{10-0}, trivial +RESAMPLE = "trivial" +# Volume control type: 1 = SDL (only affects Mupen64Plus output) 2 = OSS mixer (adjusts master PC volume) +VOLUME_CONTROL_TYPE = 1 +# Percentage change each time the volume is increased or decreased +VOLUME_ADJUST = 5 +# Default volume when a game is started. Only used if VOLUME_CONTROL_TYPE is 1 +VOLUME_DEFAULT = 100 +# Synchronize Video/Audio +AUDIO_SYNC = False + + +[Core] + +# Mupen64Plus Core config parameter set version number. Please don't change this version number. +Version = 1.010000 +# Draw on-screen display if True, otherwise don't draw OSD +OnScreenDisplay = True +# Use Pure Interpreter if 0, Cached Interpreter if 1, or Dynamic Recompiler if 2 or more +R4300Emulator = 2 +# Disable compiled jump commands in dynamic recompiler (should be set to False) +NoCompiledJump = False +# Disable 4MB expansion RAM pack. May be necessary for some games +DisableExtraMem = False +# Increment the save state slot after each save operation +AutoStateSlotIncrement = False +# Activate the R4300 debugger when ROM execution begins, if core was built with Debugger support +EnableDebugger = False +# Save state slot (0-9) to use when saving/loading the emulator state +CurrentStateSlot = 0 +# Path to directory where screenshots are saved. If this is blank, the default value of ${UserDataPath}/screenshot will be used +ScreenshotPath = "/storage/roms/screenshots" +# Path to directory where emulator save states (snapshots) are saved. If this is blank, the default value of ${UserDataPath}/save will be used +SaveStatePath = "/storage/roms/n64" +# Path to directory where SRAM/EEPROM data (in-game saves) are stored. If this is blank, the default value of ${UserDataPath}/save will be used +SaveSRAMPath = "/storage/roms/n64" +# Path to a directory to search when looking for shared data files +SharedDataPath = "/storage/.config/game/configs/mupen64plussa" +# Force number of cycles per emulated instruction +CountPerOp = 0 +# Randomize PI/SI Interrupt Timing +RandomizeInterrupt = True +# Duration of SI DMA (-1: use per game settings) +SiDmaDuration = -1 +# Gameboy Camera Video Capture backend +GbCameraVideoCaptureBackend1 = "" +# Disk Save Format (0: Full Disk Copy (*.ndr/*.d6r), 1: RAM Area Only (*.ram)) +SaveDiskFormat = 1 + + +[CoreEvents] + +# Mupen64Plus CoreEvents config parameter set version number. Please don't change this version number. +Version = 1.000000 +# SDL keysym for stopping the emulator +Kbd Mapping Stop = 27 +# SDL keysym for switching between fullscreen/windowed modes +Kbd Mapping Fullscreen = 0 +# SDL keysym for saving the emulator state +Kbd Mapping Save State = 286 +# SDL keysym for loading the emulator state +Kbd Mapping Load State = 288 +# SDL keysym for advancing the save state slot +Kbd Mapping Increment Slot = 0 +# SDL keysym for resetting the emulator +Kbd Mapping Reset = 290 +# SDL keysym for slowing down the emulator +Kbd Mapping Speed Down = 291 +# SDL keysym for speeding up the emulator +Kbd Mapping Speed Up = 292 +# SDL keysym for taking a screenshot +Kbd Mapping Screenshot = 293 +# SDL keysym for pausing the emulator +Kbd Mapping Pause = 112 +# SDL keysym for muting/unmuting the sound +Kbd Mapping Mute = 109 +# SDL keysym for increasing the volume +Kbd Mapping Increase Volume = 93 +# SDL keysym for decreasing the volume +Kbd Mapping Decrease Volume = 91 +# SDL keysym for temporarily going really fast +Kbd Mapping Fast Forward = 102 +# SDL keysym for advancing by one frame when paused +Kbd Mapping Frame Advance = 47 +# SDL keysym for pressing the game shark button +Kbd Mapping Gameshark = 103 +# Joystick event string for stopping the emulator +Joy Mapping Stop = "J0B7/B8" +# Joystick event string for switching between fullscreen/windowed modes +Joy Mapping Fullscreen = "" +# Joystick event string for saving the emulator state +Joy Mapping Save State = "J0B6/B5" +# Joystick event string for loading the emulator state +Joy Mapping Load State = "J0B6/B4" +# Joystick event string for advancing the save state slot +Joy Mapping Increment Slot = "" +# Joystick event string for resetting the emulator +Joy Mapping Reset = "J0B6/B0" +# Joystick event string for slowing down the emulator +Joy Mapping Speed Down = "" +# Joystick event string for speeding up the emulator +Joy Mapping Speed Up = "" +# Joystick event string for taking a screenshot +Joy Mapping Screenshot = "J0B6/B3" +# Joystick event string for pausing the emulator +Joy Mapping Pause = "J0B12/B1" +# Joystick event string for muting/unmuting the sound +Joy Mapping Mute = "" +# Joystick event string for increasing the volume +Joy Mapping Increase Volume = "" +# Joystick event string for decreasing the volume +Joy Mapping Decrease Volume = "" +# Joystick event string for fast-forward +Joy Mapping Fast Forward = "" +# Joystick event string for advancing by one frame when paused +Joy Mapping Frame Advance = "" +# Joystick event string for pressing the game shark button +Joy Mapping Gameshark = "" +# SDL keysym for save slot 0 +Kbd Mapping Slot 0 = 48 +# SDL keysym for save slot 1 +Kbd Mapping Slot 1 = 49 +# SDL keysym for save slot 2 +Kbd Mapping Slot 2 = 50 +# SDL keysym for save slot 3 +Kbd Mapping Slot 3 = 51 +# SDL keysym for save slot 4 +Kbd Mapping Slot 4 = 52 +# SDL keysym for save slot 5 +Kbd Mapping Slot 5 = 53 +# SDL keysym for save slot 6 +Kbd Mapping Slot 6 = 54 +# SDL keysym for save slot 7 +Kbd Mapping Slot 7 = 55 +# SDL keysym for save slot 8 +Kbd Mapping Slot 8 = 56 +# SDL keysym for save slot 9 +Kbd Mapping Slot 9 = 57 + + +[Input-SDL-Control1] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = 0 +# SDL joystick name (or Keyboard) +name = "rg552_joypad" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = True +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "0,0" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +; Retroid Pocket Gamepad - default.ini +[Retroid Pocket Gamepad] +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = button(14) +DPad L = button(13) +DPad D = button(12) +DPad U = button(11) +Start = button(7) +Z Trig = axis(7+) +B Button = button(3) +A Button = button(0) +C Button R = axis(3+) +C Button L = axis(3-) +C Button D = axis(4+) +C Button U = axis(4-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Input-SDL-Control2] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control3] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control4] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Rsp-HLE] + +# Mupen64Plus RSP HLE Plugin config parameter version number +Version = 1.000000 +# Path to a RSP plugin which will be used when encountering an unknown ucode.You can disable this by letting an empty string. +RspFallback = "" +# Send display lists to the graphics plugin +DisplayListToGraphicsPlugin = True +# Send audio lists to the audio plugin +AudioListToAudioPlugin = False + + +[Transferpak] + +# Filename of the GB ROM to load into transferpak 1 +GB-rom-1 = "" +# Filename of the GB RAM to load into transferpak 1 +GB-ram-1 = "" +# Filename of the GB ROM to load into transferpak 2 +GB-rom-2 = "" +# Filename of the GB RAM to load into transferpak 2 +GB-ram-2 = "" +# Filename of the GB ROM to load into transferpak 3 +GB-rom-3 = "" +# Filename of the GB RAM to load into transferpak 3 +GB-ram-3 = "" +# Filename of the GB ROM to load into transferpak 4 +GB-rom-4 = "" +# Filename of the GB RAM to load into transferpak 4 +GB-ram-4 = "" + + +[UI-Console] + +# Mupen64Plus UI-Console config parameter set version number. Please don't change this version number. +Version = 1.000000 +# Directory in which to search for plugins +PluginDir = "/usr/local/lib/mupen64plus" +# Filename of video plugin +VideoPlugin = "mupen64plus-video-rice" +# Filename of audio plugin +AudioPlugin = "mupen64plus-audio-sdl.so" +# Filename of input plugin +InputPlugin = "mupen64plus-input-sdl.so" +# Filename of RSP plugin +RspPlugin = "mupen64plus-rsp-hle.so" + + +[Video-General] + +# Width of output window or fullscreen width +ScreenWidth = 1280 +# Height of output window or fullscreen height +ScreenHeight = 960 +# Use fullscreen mode if True, or windowed mode if False +Fullscreen = True +# If true, activate the SDL_GL_SWAP_CONTROL attribute +VerticalSync = True +# Rotate screen contents: 0=0 degree, 1=90 degree, 2 = 180 degree, 3=270 degree +Rotate = 0 + +[Video-GLideN64] + +###### Hardware Compatibility ###### +# Leave enabled unless a mobile gpu doesn't support it. +EnableFragmentDepthWrite = 1 +# Hardware per pixel lighting, supposedly good for GLES3.1 devices or higher. +EnableHWLighting = 0 + +###### Enhancements ####### +# Internal render resoluton rather than output. So 2 x 240p is 480p, etc. +UseNativeResolutionFactor = 1 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Enable/Disable Fast Approximate Anti-Aliasing FXAA +FXAA = 0 +# Max level of Anisotropic Filtering, 0 for off +anisotropy = 0 +# Bilinear filtering mode (0=N64 3point, 1=standard) +# @rishooty: best to use this at 1x native res, any higher turn it off. +bilinearMode = 1 + +###### Compatibility ###### +# Make texrect coordinates continuous to avoid black lines between them. (0=Off/default, 1=Auto, 2=Force) +CorrectTexrectCoords = 1 +# Copy auxiliary buffers to RDRAM (default: 0) +EnableCopyAuxiliaryToRDRAM = 1 +# Render 2D texrects in native resolution to fix misalignment between parts of 2D image. (0=Off/default, 1=Optimized, 2=Unoptimized)") +EnableNativeResTexrects = 1 + +###### Other ###### +# Enable threaded video backend at the cost of input lag +ThreadedVideo = 1 +# Screen aspect ratio (0=stretch, 1=force 4:3, 2=force 16:9, 3=adjust) +AspectRatio = 1 +# Display On-screen FPS +ShowFPS = False + +[Video-Glide64mk2] + +# Enable full-scene anti-aliasing by setting this to a value greater than 1 +wrpAntiAliasing = 0 +# Card ID +card_id = 0 +# If true, use polygon offset values specified below +force_polygon_offset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +polygon_offset_factor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +polygon_offset_units = 0.000000 +# Vertical sync +vsync = True +# TODO:ssformat +ssformat = False +# Display performance stats (add together desired flags): 1=FPS counter, 2=VI/s counter, 4=% speed, 8=FPS transparent +show_fps = 0 +# Clock enabled +clock = False +# Clock is 24-hour +clock_24_hr = True +# Wrapper resolution +wrpResolution = 0 +# Wrapper VRAM +wrpVRAM = 0 +# Wrapper FBO +wrpFBO = True +# Wrapper Anisotropic Filtering +wrpAnisotropic = True +# Texture Enhancement: Smooth/Sharpen Filters +ghq_fltr = 0 +# Texture Compression: 0 for S3TC, 1 for FXT1 +ghq_cmpr = 0 +# Texture Enhancement: More filters +ghq_enht = 0 +# Hi-res texture pack format (0 for none, 1 for Rice) +ghq_hirs = 1 +# Compress texture cache with S3TC or FXT1 +ghq_enht_cmpr = False +# Tile textures (saves memory but could cause issues) +ghq_enht_tile = 0 +# Force 16bpp textures (saves ram but lower quality) +ghq_enht_f16bpp = False +# Compress texture cache +ghq_enht_gz = True +# Don't enhance textures for backgrounds +ghq_enht_nobg = False +# Enable S3TC and FXT1 compression +ghq_hirs_cmpr = False +# Tile hi-res textures (saves memory but could cause issues) +ghq_hirs_tile = False +# Force 16bpp hi-res textures (saves ram but lower quality) +ghq_hirs_f16bpp = False +# Compress hi-res texture cache +ghq_hirs_gz = True +# Alternative CRC calculation -- emulates Rice bug +ghq_hirs_altcrc = True +# Save tex cache to disk +ghq_cache_save = True +# Texture Cache Size (MB) +ghq_cache_size = 128 +# Use full alpha channel -- could cause issues for some tex packs +ghq_hirs_let_texartists_fly = False +# Dump textures +ghq_hirs_dump = False +# Alternate texture size method: -1=Game default, 0=disable. 1=enable +alt_tex_size = -1 +# Use first SETTILESIZE only: -1=Game default, 0=disable. 1=enable +use_sts1_only = -1 +# Use spheric mapping only: -1=Game default, 0=disable. 1=enable +force_calc_sphere = -1 +# Force positive viewport: -1=Game default, 0=disable. 1=enable +correct_viewport = -1 +# Force texrect size to integral value: -1=Game default, 0=disable. 1=enable +increase_texrect_edge = -1 +# Reduce fillrect size by 1: -1=Game default, 0=disable. 1=enable +decrease_fillrect_edge = -1 +# Enable perspective texture correction emulation: -1=Game default, 0=disable. 1=enable +texture_correction = -1 +# Set special scale for PAL games: -1=Game default, 0=disable. 1=enable +pal230 = -1 +# 3DFX Dithered alpha emulation mode: -1=Game default, >=0=dithered alpha emulation mode +stipple_mode = -1 +# 3DFX Dithered alpha pattern: -1=Game default, >=0=pattern used for dithered alpha emulation +stipple_pattern = -1 +# Check microcode each frame: -1=Game default, 0=disable. 1=enable +force_microcheck = -1 +# Force 0xb5 command to be quad, not line 3D: -1=Game default, 0=disable. 1=enable +force_quad3d = -1 +# Enable near z clipping: -1=Game default, 0=disable. 1=enable +clip_zmin = -1 +# Enable far plane clipping: -1=Game default, 0=disable. 1=enable +clip_zmax = -1 +# Use fast CRC algorithm: -1=Game default, 0=disable. 1=enable +fast_crc = -1 +# Adjust screen aspect for wide screen mode: -1=Game default, 0=disable. 1=enable +adjust_aspect = -1 +# Force strict check in Depth buffer test: -1=Game default, 0=disable. 1=enable +zmode_compare_less = -1 +# Apply alpha dither regardless of alpha_dither_mode: -1=Game default, 0=disable. 1=enable +old_style_adither = -1 +# Scale vertex z value before writing to depth buffer: -1=Game default, 0=disable. 1=enable +n64_z_scale = -1 +# Fast texrect rendering with hwfbe: -1=Game default, 0=disable. 1=enable +optimize_texrect = -1 +# Do not copy auxiliary frame buffers: -1=Game default, 0=disable. 1=enable +ignore_aux_copy = -1 +# Clear auxiliary texture frame buffers: -1=Game default, 0=disable. 1=enable +hires_buf_clear = -1 +# Read alpha from framebuffer: -1=Game default, 0=disable. 1=enable +fb_read_alpha = -1 +# Handle unchanged fb: -1=Game default, 0=disable. 1=enable +useless_is_useless = -1 +# Set frambuffer CRC mode: -1=Game default, 0=disable CRC, 1=fast CRC, 2=safe CRC +fb_crc_mode = -1 +# Filtering mode: -1=Game default, 0=automatic, 1=force bilinear, 2=force point sampled +filtering = -1 +# Fog: -1=Game default, 0=disable. 1=enable +fog = -1 +# Buffer clear on every frame: -1=Game default, 0=disable. 1=enable +buff_clear = -1 +# Buffer swapping method: -1=Game default, 0=swap buffers when vertical interrupt has occurred, 1=swap buffers when set of conditions is satisfied. Prevents flicker on some games, 2=mix of first two methods +swapmode = -1 +# Aspect ratio: -1=Game default, 0=Force 4:3, 1=Force 16:9, 2=Stretch, 3=Original +aspect = -1 +# LOD calculation: -1=Game default, 0=disable. 1=fast, 2=precise +lodmode = -1 +# Smart framebuffer: -1=Game default, 0=disable. 1=enable +fb_smart = -1 +# Hardware frame buffer emulation: -1=Game default, 0=disable. 1=enable +fb_hires = -1 +# Read framebuffer every frame (may be slow use only for effects that need it e.g. Banjo Kazooie, DK64 transitions): -1=Game default, 0=disable. 1=enable +fb_read_always = -1 +# Render N64 frame buffer as texture: -1=Game default, 0=disable, 1=mode1, 2=mode2 +read_back_to_screen = -1 +# Show images written directly by CPU: -1=Game default, 0=disable. 1=enable +detect_cpu_write = -1 +# Get frame buffer info: -1=Game default, 0=disable. 1=enable +fb_get_info = -1 +# Enable software depth render: -1=Game default, 0=disable. 1=enable +fb_render = -1 +# If true, skip up to maxframeskip frames to maintain clock schedule; if false, skip exactly maxframeskip frames +autoframeskip = False +# If autoframeskip is true, skip up to this many frames to maintain clock schedule; if autoframeskip is false, skip exactly this many frames +maxframeskip = 0 + + +[Video-Rice] + +# Mupen64Plus Rice Video Plugin config parameter version number +Version = 1 +# Frame Buffer Emulation (0=ROM default, 1=disable) +FrameBufferSetting = 0 +# Frequency to write back the frame buffer (0=every frame, 1=every other frame, etc) +FrameBufferWriteBackControl = 0 +# Render-to-texture emulation (0=none, 1=ignore, 2=normal, 3=write back, 4=write back and reload) +RenderToTexture = 0 +# Control when the screen will be updated (0=ROM default, 1=VI origin update, 2=VI origin change, 3=CI change, 4=first CI change, 5=first primitive draw, 6=before screen clear, 7=after screen drawn) +ScreenUpdateSetting = 4 +# Force to use normal alpha blender +NormalAlphaBlender = False +# Use a faster algorithm to speed up texture loading and CRC computation +FastTextureLoading = False +# Use different texture coordinate clamping code +AccurateTextureMapping = True +# Force emulated frame buffers to be in N64 native resolution +InN64Resolution = False +# Try to reduce Video RAM usage (should never be used) +SaveVRAM = False +# Enable this option to have better render-to-texture quality +DoubleSizeForSmallTxtrBuf = False +# Force to use normal color combiner +DefaultCombinerDisable = False +# Enable game-specific settings from INI file +EnableHacks = True +# If enabled, graphics will be drawn in WinFrame mode instead of solid and texture mode +WinFrameMode = False +# N64 Texture Memory Full Emulation (may fix some games, may break others) +FullTMEMEmulation = False +# Enable vertex clipper for fog operations +OpenGLVertexClipper = False +# Enable/Disable SSE optimizations for capable CPUs +EnableSSE = True +# If this option is enabled, the plugin will skip every other frame +SkipFrame = False +# If enabled, texture enhancement will be done only for TxtRect ucode +TexRectOnly = False +# If enabled, texture enhancement will be done only for textures width+height<=128 +SmallTextureOnly = False +# Select hi-resolution textures based only on the CRC and ignore format+size information (Glide64 compatibility) +LoadHiResCRCOnly = True +# Enable hi-resolution texture file loading +LoadHiResTextures = False +# Enable texture dumping +DumpTexturesToFiles = False +# Display On-screen FPS +ShowFPS = False +# Use Mipmapping? 0=no, 1=nearest, 2=bilinear, 3=trilinear +Mipmapping = 2 +# Enable, Disable fog generation (0=Disable, 1=Enable) +FogMethod = 1 +# Force to use texture filtering or not (0=auto: n64 choose, 1=force no filtering, 2=force filtering) +ForceTextureFilter = 0 +# Primary texture enhancement filter (0=None, 1=2X, 2=2XSAI, 3=HQ2X, 4=LQ2X, 5=HQ4X, 6=Sharpen, 7=Sharpen More, 8=External, 9=Mirrored) +TextureEnhancement = 0 +# Secondary texture enhancement filter (0 = none, 1-4 = filtered) +TextureEnhancementControl = 0 +# Color bit depth to use for textures (0=default, 1=32 bits, 2=16 bits) +TextureQuality = 0 +# Z-buffer depth (only 16 or 32) +OpenGLDepthBufferSetting = 16 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Color bit depth for rendering window (0=32 bits, 1=16 bits) +ColorQuality = 1 +# OpenGL level to support (0=auto, 1=OGL_FRAGMENT_PROGRAM) +OpenGLRenderSetting = 0 +# Enable/Disable Anisotropic Filtering for Mipmapping (0=no filtering, 2-16=quality). This is uneffective if Mipmapping is 0. If the given value is to high to be supported by your graphic card, the value will be the highest value your graphic card can support. Better result with Trilinear filtering +AnisotropicFiltering = 0 +# If true, use polygon offset values specified below +ForcePolygonOffset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +PolygonOffsetFactor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +PolygonOffsetUnits = 0.000000 diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/SM8550/mupen64plus.cfg b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/SM8550/mupen64plus.cfg new file mode 100644 index 0000000000..8f707630dd --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/SM8550/mupen64plus.cfg @@ -0,0 +1,665 @@ +# Mupen64Plus Configuration File +# This file is automatically read and written by the Mupen64Plus Core library + +[64DD] + +# Filename of the 64DD IPL ROM +IPL-ROM = "" +# Filename of the disk to load into Disk Drive +Disk = "" + + +[Audio-SDL] + +# Mupen64Plus SDL Audio Plugin config parameter version number +Version = 1.000000 +# Frequency which is used if rom doesn't want to change it +DEFAULT_FREQUENCY = 33600 +# Swaps left and right channels +SWAP_CHANNELS = False +# Size of primary buffer in output samples. This is where audio is loaded after it's extracted from n64's memory. +PRIMARY_BUFFER_SIZE = 16384 +# Fullness level target for Primary audio buffer, in equivalent output samples. This value must be larger than the SECONDARY_BUFFER_SIZE. Decreasing this value will reduce audio latency but requires a faster PC to avoid choppiness. Increasing this will increase audio latency but reduce the chance of drop-outs. +PRIMARY_BUFFER_TARGET = 2048 +# Size of secondary buffer in output samples. This is SDL's hardware buffer. The SDL documentation states that this should be a power of two between 512 and 8192. +SECONDARY_BUFFER_SIZE = 1024 +# Audio resampling algorithm. src-sinc-best-quality, src-sinc-medium-quality, src-sinc-fastest, src-zero-order-hold, src-linear, speex-fixed-{10-0}, trivial +RESAMPLE = "trivial" +# Volume control type: 1 = SDL (only affects Mupen64Plus output) 2 = OSS mixer (adjusts master PC volume) +VOLUME_CONTROL_TYPE = 1 +# Percentage change each time the volume is increased or decreased +VOLUME_ADJUST = 5 +# Default volume when a game is started. Only used if VOLUME_CONTROL_TYPE is 1 +VOLUME_DEFAULT = 100 +# Synchronize Video/Audio +AUDIO_SYNC = False + + +[Core] + +# Mupen64Plus Core config parameter set version number. Please don't change this version number. +Version = 1.010000 +# Draw on-screen display if True, otherwise don't draw OSD +OnScreenDisplay = True +# Use Pure Interpreter if 0, Cached Interpreter if 1, or Dynamic Recompiler if 2 or more +R4300Emulator = 2 +# Disable compiled jump commands in dynamic recompiler (should be set to False) +NoCompiledJump = False +# Disable 4MB expansion RAM pack. May be necessary for some games +DisableExtraMem = False +# Increment the save state slot after each save operation +AutoStateSlotIncrement = False +# Activate the R4300 debugger when ROM execution begins, if core was built with Debugger support +EnableDebugger = False +# Save state slot (0-9) to use when saving/loading the emulator state +CurrentStateSlot = 0 +# Path to directory where screenshots are saved. If this is blank, the default value of ${UserDataPath}/screenshot will be used +ScreenshotPath = "/storage/roms/screenshots" +# Path to directory where emulator save states (snapshots) are saved. If this is blank, the default value of ${UserDataPath}/save will be used +SaveStatePath = "/storage/roms/n64" +# Path to directory where SRAM/EEPROM data (in-game saves) are stored. If this is blank, the default value of ${UserDataPath}/save will be used +SaveSRAMPath = "/storage/roms/n64" +# Path to a directory to search when looking for shared data files +SharedDataPath = "/storage/.config/game/configs/mupen64plussa" +# Force number of cycles per emulated instruction +CountPerOp = 0 +# Randomize PI/SI Interrupt Timing +RandomizeInterrupt = True +# Duration of SI DMA (-1: use per game settings) +SiDmaDuration = -1 +# Gameboy Camera Video Capture backend +GbCameraVideoCaptureBackend1 = "" +# Disk Save Format (0: Full Disk Copy (*.ndr/*.d6r), 1: RAM Area Only (*.ram)) +SaveDiskFormat = 1 + + +[CoreEvents] + +# Mupen64Plus CoreEvents config parameter set version number. Please don't change this version number. +Version = 1.000000 +# SDL keysym for stopping the emulator +Kbd Mapping Stop = 27 +# SDL keysym for switching between fullscreen/windowed modes +Kbd Mapping Fullscreen = 0 +# SDL keysym for saving the emulator state +Kbd Mapping Save State = 286 +# SDL keysym for loading the emulator state +Kbd Mapping Load State = 288 +# SDL keysym for advancing the save state slot +Kbd Mapping Increment Slot = 0 +# SDL keysym for resetting the emulator +Kbd Mapping Reset = 290 +# SDL keysym for slowing down the emulator +Kbd Mapping Speed Down = 291 +# SDL keysym for speeding up the emulator +Kbd Mapping Speed Up = 292 +# SDL keysym for taking a screenshot +Kbd Mapping Screenshot = 293 +# SDL keysym for pausing the emulator +Kbd Mapping Pause = 112 +# SDL keysym for muting/unmuting the sound +Kbd Mapping Mute = 109 +# SDL keysym for increasing the volume +Kbd Mapping Increase Volume = 93 +# SDL keysym for decreasing the volume +Kbd Mapping Decrease Volume = 91 +# SDL keysym for temporarily going really fast +Kbd Mapping Fast Forward = 102 +# SDL keysym for advancing by one frame when paused +Kbd Mapping Frame Advance = 47 +# SDL keysym for pressing the game shark button +Kbd Mapping Gameshark = 103 +# Joystick event string for stopping the emulator +Joy Mapping Stop = "J0B7/B8" +# Joystick event string for switching between fullscreen/windowed modes +Joy Mapping Fullscreen = "" +# Joystick event string for saving the emulator state +Joy Mapping Save State = "J0B6/B5" +# Joystick event string for loading the emulator state +Joy Mapping Load State = "J0B6/B4" +# Joystick event string for advancing the save state slot +Joy Mapping Increment Slot = "" +# Joystick event string for resetting the emulator +Joy Mapping Reset = "J0B6/B0" +# Joystick event string for slowing down the emulator +Joy Mapping Speed Down = "" +# Joystick event string for speeding up the emulator +Joy Mapping Speed Up = "" +# Joystick event string for taking a screenshot +Joy Mapping Screenshot = "J0B6/B3" +# Joystick event string for pausing the emulator +Joy Mapping Pause = "J0B12/B1" +# Joystick event string for muting/unmuting the sound +Joy Mapping Mute = "" +# Joystick event string for increasing the volume +Joy Mapping Increase Volume = "" +# Joystick event string for decreasing the volume +Joy Mapping Decrease Volume = "" +# Joystick event string for fast-forward +Joy Mapping Fast Forward = "" +# Joystick event string for advancing by one frame when paused +Joy Mapping Frame Advance = "" +# Joystick event string for pressing the game shark button +Joy Mapping Gameshark = "" +# SDL keysym for save slot 0 +Kbd Mapping Slot 0 = 48 +# SDL keysym for save slot 1 +Kbd Mapping Slot 1 = 49 +# SDL keysym for save slot 2 +Kbd Mapping Slot 2 = 50 +# SDL keysym for save slot 3 +Kbd Mapping Slot 3 = 51 +# SDL keysym for save slot 4 +Kbd Mapping Slot 4 = 52 +# SDL keysym for save slot 5 +Kbd Mapping Slot 5 = 53 +# SDL keysym for save slot 6 +Kbd Mapping Slot 6 = 54 +# SDL keysym for save slot 7 +Kbd Mapping Slot 7 = 55 +# SDL keysym for save slot 8 +Kbd Mapping Slot 8 = 56 +# SDL keysym for save slot 9 +Kbd Mapping Slot 9 = 57 + + +[Input-SDL-Control1] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = 0 +# SDL joystick name (or Keyboard) +name = "Xbox Series X Controller" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = True +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control2] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control3] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control4] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Rsp-HLE] + +# Mupen64Plus RSP HLE Plugin config parameter version number +Version = 1.000000 +# Path to a RSP plugin which will be used when encountering an unknown ucode.You can disable this by letting an empty string. +RspFallback = "" +# Send display lists to the graphics plugin +DisplayListToGraphicsPlugin = True +# Send audio lists to the audio plugin +AudioListToAudioPlugin = False + + +[Transferpak] + +# Filename of the GB ROM to load into transferpak 1 +GB-rom-1 = "" +# Filename of the GB RAM to load into transferpak 1 +GB-ram-1 = "" +# Filename of the GB ROM to load into transferpak 2 +GB-rom-2 = "" +# Filename of the GB RAM to load into transferpak 2 +GB-ram-2 = "" +# Filename of the GB ROM to load into transferpak 3 +GB-rom-3 = "" +# Filename of the GB RAM to load into transferpak 3 +GB-ram-3 = "" +# Filename of the GB ROM to load into transferpak 4 +GB-rom-4 = "" +# Filename of the GB RAM to load into transferpak 4 +GB-ram-4 = "" + + +[UI-Console] + +# Mupen64Plus UI-Console config parameter set version number. Please don't change this version number. +Version = 1.000000 +# Directory in which to search for plugins +PluginDir = "/usr/local/lib/mupen64plus" +# Filename of video plugin +VideoPlugin = "mupen64plus-video-rice" +# Filename of audio plugin +AudioPlugin = "mupen64plus-audio-sdl.so" +# Filename of input plugin +InputPlugin = "mupen64plus-input-sdl.so" +# Filename of RSP plugin +RspPlugin = "mupen64plus-rsp-hle.so" + + +[Video-General] + +# Width of output window or fullscreen width +ScreenWidth = 1280 +# Height of output window or fullscreen height +ScreenHeight = 960 +# Use fullscreen mode if True, or windowed mode if False +Fullscreen = True +# If true, activate the SDL_GL_SWAP_CONTROL attribute +VerticalSync = True +# Rotate screen contents: 0=0 degree, 1=90 degree, 2 = 180 degree, 3=270 degree +Rotate = 0 + +[Video-GLideN64] + +###### Hardware Compatibility ###### +# Leave enabled unless a mobile gpu doesn't support it. +EnableFragmentDepthWrite = 1 +# Hardware per pixel lighting, supposedly good for GLES3.1 devices or higher. +EnableHWLighting = 0 + +###### Enhancements ####### +# Internal render resoluton rather than output. So 2 x 240p is 480p, etc. +UseNativeResolutionFactor = 1 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Enable/Disable Fast Approximate Anti-Aliasing FXAA +FXAA = 0 +# Max level of Anisotropic Filtering, 0 for off +anisotropy = 0 +# Bilinear filtering mode (0=N64 3point, 1=standard) +# @rishooty: best to use this at 1x native res, any higher turn it off. +bilinearMode = 1 + +###### Compatibility ###### +# Make texrect coordinates continuous to avoid black lines between them. (0=Off/default, 1=Auto, 2=Force) +CorrectTexrectCoords = 1 +# Copy auxiliary buffers to RDRAM (default: 0) +EnableCopyAuxiliaryToRDRAM = 1 +# Render 2D texrects in native resolution to fix misalignment between parts of 2D image. (0=Off/default, 1=Optimized, 2=Unoptimized)") +EnableNativeResTexrects = 1 + +###### Other ###### +# Enable threaded video backend at the cost of input lag +ThreadedVideo = 1 +# Screen aspect ratio (0=stretch, 1=force 4:3, 2=force 16:9, 3=adjust) +AspectRatio = 1 +# Display On-screen FPS +ShowFPS = False + +[Video-Glide64mk2] + +# Enable full-scene anti-aliasing by setting this to a value greater than 1 +wrpAntiAliasing = 0 +# Card ID +card_id = 0 +# If true, use polygon offset values specified below +force_polygon_offset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +polygon_offset_factor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +polygon_offset_units = 0.000000 +# Vertical sync +vsync = True +# TODO:ssformat +ssformat = False +# Display performance stats (add together desired flags): 1=FPS counter, 2=VI/s counter, 4=% speed, 8=FPS transparent +show_fps = 0 +# Clock enabled +clock = False +# Clock is 24-hour +clock_24_hr = True +# Wrapper resolution +wrpResolution = 0 +# Wrapper VRAM +wrpVRAM = 0 +# Wrapper FBO +wrpFBO = True +# Wrapper Anisotropic Filtering +wrpAnisotropic = True +# Texture Enhancement: Smooth/Sharpen Filters +ghq_fltr = 0 +# Texture Compression: 0 for S3TC, 1 for FXT1 +ghq_cmpr = 0 +# Texture Enhancement: More filters +ghq_enht = 0 +# Hi-res texture pack format (0 for none, 1 for Rice) +ghq_hirs = 1 +# Compress texture cache with S3TC or FXT1 +ghq_enht_cmpr = False +# Tile textures (saves memory but could cause issues) +ghq_enht_tile = 0 +# Force 16bpp textures (saves ram but lower quality) +ghq_enht_f16bpp = False +# Compress texture cache +ghq_enht_gz = True +# Don't enhance textures for backgrounds +ghq_enht_nobg = False +# Enable S3TC and FXT1 compression +ghq_hirs_cmpr = False +# Tile hi-res textures (saves memory but could cause issues) +ghq_hirs_tile = False +# Force 16bpp hi-res textures (saves ram but lower quality) +ghq_hirs_f16bpp = False +# Compress hi-res texture cache +ghq_hirs_gz = True +# Alternative CRC calculation -- emulates Rice bug +ghq_hirs_altcrc = True +# Save tex cache to disk +ghq_cache_save = True +# Texture Cache Size (MB) +ghq_cache_size = 128 +# Use full alpha channel -- could cause issues for some tex packs +ghq_hirs_let_texartists_fly = False +# Dump textures +ghq_hirs_dump = False +# Alternate texture size method: -1=Game default, 0=disable. 1=enable +alt_tex_size = -1 +# Use first SETTILESIZE only: -1=Game default, 0=disable. 1=enable +use_sts1_only = -1 +# Use spheric mapping only: -1=Game default, 0=disable. 1=enable +force_calc_sphere = -1 +# Force positive viewport: -1=Game default, 0=disable. 1=enable +correct_viewport = -1 +# Force texrect size to integral value: -1=Game default, 0=disable. 1=enable +increase_texrect_edge = -1 +# Reduce fillrect size by 1: -1=Game default, 0=disable. 1=enable +decrease_fillrect_edge = -1 +# Enable perspective texture correction emulation: -1=Game default, 0=disable. 1=enable +texture_correction = -1 +# Set special scale for PAL games: -1=Game default, 0=disable. 1=enable +pal230 = -1 +# 3DFX Dithered alpha emulation mode: -1=Game default, >=0=dithered alpha emulation mode +stipple_mode = -1 +# 3DFX Dithered alpha pattern: -1=Game default, >=0=pattern used for dithered alpha emulation +stipple_pattern = -1 +# Check microcode each frame: -1=Game default, 0=disable. 1=enable +force_microcheck = -1 +# Force 0xb5 command to be quad, not line 3D: -1=Game default, 0=disable. 1=enable +force_quad3d = -1 +# Enable near z clipping: -1=Game default, 0=disable. 1=enable +clip_zmin = -1 +# Enable far plane clipping: -1=Game default, 0=disable. 1=enable +clip_zmax = -1 +# Use fast CRC algorithm: -1=Game default, 0=disable. 1=enable +fast_crc = -1 +# Adjust screen aspect for wide screen mode: -1=Game default, 0=disable. 1=enable +adjust_aspect = -1 +# Force strict check in Depth buffer test: -1=Game default, 0=disable. 1=enable +zmode_compare_less = -1 +# Apply alpha dither regardless of alpha_dither_mode: -1=Game default, 0=disable. 1=enable +old_style_adither = -1 +# Scale vertex z value before writing to depth buffer: -1=Game default, 0=disable. 1=enable +n64_z_scale = -1 +# Fast texrect rendering with hwfbe: -1=Game default, 0=disable. 1=enable +optimize_texrect = -1 +# Do not copy auxiliary frame buffers: -1=Game default, 0=disable. 1=enable +ignore_aux_copy = -1 +# Clear auxiliary texture frame buffers: -1=Game default, 0=disable. 1=enable +hires_buf_clear = -1 +# Read alpha from framebuffer: -1=Game default, 0=disable. 1=enable +fb_read_alpha = -1 +# Handle unchanged fb: -1=Game default, 0=disable. 1=enable +useless_is_useless = -1 +# Set frambuffer CRC mode: -1=Game default, 0=disable CRC, 1=fast CRC, 2=safe CRC +fb_crc_mode = -1 +# Filtering mode: -1=Game default, 0=automatic, 1=force bilinear, 2=force point sampled +filtering = -1 +# Fog: -1=Game default, 0=disable. 1=enable +fog = -1 +# Buffer clear on every frame: -1=Game default, 0=disable. 1=enable +buff_clear = -1 +# Buffer swapping method: -1=Game default, 0=swap buffers when vertical interrupt has occurred, 1=swap buffers when set of conditions is satisfied. Prevents flicker on some games, 2=mix of first two methods +swapmode = -1 +# Aspect ratio: -1=Game default, 0=Force 4:3, 1=Force 16:9, 2=Stretch, 3=Original +aspect = -1 +# LOD calculation: -1=Game default, 0=disable. 1=fast, 2=precise +lodmode = -1 +# Smart framebuffer: -1=Game default, 0=disable. 1=enable +fb_smart = -1 +# Hardware frame buffer emulation: -1=Game default, 0=disable. 1=enable +fb_hires = -1 +# Read framebuffer every frame (may be slow use only for effects that need it e.g. Banjo Kazooie, DK64 transitions): -1=Game default, 0=disable. 1=enable +fb_read_always = -1 +# Render N64 frame buffer as texture: -1=Game default, 0=disable, 1=mode1, 2=mode2 +read_back_to_screen = -1 +# Show images written directly by CPU: -1=Game default, 0=disable. 1=enable +detect_cpu_write = -1 +# Get frame buffer info: -1=Game default, 0=disable. 1=enable +fb_get_info = -1 +# Enable software depth render: -1=Game default, 0=disable. 1=enable +fb_render = -1 +# If true, skip up to maxframeskip frames to maintain clock schedule; if false, skip exactly maxframeskip frames +autoframeskip = False +# If autoframeskip is true, skip up to this many frames to maintain clock schedule; if autoframeskip is false, skip exactly this many frames +maxframeskip = 0 + + +[Video-Rice] + +# Mupen64Plus Rice Video Plugin config parameter version number +Version = 1 +# Frame Buffer Emulation (0=ROM default, 1=disable) +FrameBufferSetting = 0 +# Frequency to write back the frame buffer (0=every frame, 1=every other frame, etc) +FrameBufferWriteBackControl = 0 +# Render-to-texture emulation (0=none, 1=ignore, 2=normal, 3=write back, 4=write back and reload) +RenderToTexture = 0 +# Control when the screen will be updated (0=ROM default, 1=VI origin update, 2=VI origin change, 3=CI change, 4=first CI change, 5=first primitive draw, 6=before screen clear, 7=after screen drawn) +ScreenUpdateSetting = 4 +# Force to use normal alpha blender +NormalAlphaBlender = False +# Use a faster algorithm to speed up texture loading and CRC computation +FastTextureLoading = False +# Use different texture coordinate clamping code +AccurateTextureMapping = True +# Force emulated frame buffers to be in N64 native resolution +InN64Resolution = False +# Try to reduce Video RAM usage (should never be used) +SaveVRAM = False +# Enable this option to have better render-to-texture quality +DoubleSizeForSmallTxtrBuf = False +# Force to use normal color combiner +DefaultCombinerDisable = False +# Enable game-specific settings from INI file +EnableHacks = True +# If enabled, graphics will be drawn in WinFrame mode instead of solid and texture mode +WinFrameMode = False +# N64 Texture Memory Full Emulation (may fix some games, may break others) +FullTMEMEmulation = False +# Enable vertex clipper for fog operations +OpenGLVertexClipper = False +# Enable/Disable SSE optimizations for capable CPUs +EnableSSE = True +# If this option is enabled, the plugin will skip every other frame +SkipFrame = False +# If enabled, texture enhancement will be done only for TxtRect ucode +TexRectOnly = False +# If enabled, texture enhancement will be done only for textures width+height<=128 +SmallTextureOnly = False +# Select hi-resolution textures based only on the CRC and ignore format+size information (Glide64 compatibility) +LoadHiResCRCOnly = True +# Enable hi-resolution texture file loading +LoadHiResTextures = False +# Enable texture dumping +DumpTexturesToFiles = False +# Display On-screen FPS +ShowFPS = False +# Use Mipmapping? 0=no, 1=nearest, 2=bilinear, 3=trilinear +Mipmapping = 2 +# Enable, Disable fog generation (0=Disable, 1=Enable) +FogMethod = 1 +# Force to use texture filtering or not (0=auto: n64 choose, 1=force no filtering, 2=force filtering) +ForceTextureFilter = 0 +# Primary texture enhancement filter (0=None, 1=2X, 2=2XSAI, 3=HQ2X, 4=LQ2X, 5=HQ4X, 6=Sharpen, 7=Sharpen More, 8=External, 9=Mirrored) +TextureEnhancement = 0 +# Secondary texture enhancement filter (0 = none, 1-4 = filtered) +TextureEnhancementControl = 0 +# Color bit depth to use for textures (0=default, 1=32 bits, 2=16 bits) +TextureQuality = 0 +# Z-buffer depth (only 16 or 32) +OpenGLDepthBufferSetting = 16 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Color bit depth for rendering window (0=32 bits, 1=16 bits) +ColorQuality = 1 +# OpenGL level to support (0=auto, 1=OGL_FRAGMENT_PROGRAM) +OpenGLRenderSetting = 0 +# Enable/Disable Anisotropic Filtering for Mipmapping (0=no filtering, 2-16=quality). This is uneffective if Mipmapping is 0. If the given value is to high to be supported by your graphic card, the value will be the highest value your graphic card can support. Better result with Trilinear filtering +AnisotropicFiltering = 0 +# If true, use polygon offset values specified below +ForcePolygonOffset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +PolygonOffsetFactor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +PolygonOffsetUnits = 0.000000 diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/SM8650/mupen64plus.cfg b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/SM8650/mupen64plus.cfg new file mode 100644 index 0000000000..8f707630dd --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/SM8650/mupen64plus.cfg @@ -0,0 +1,665 @@ +# Mupen64Plus Configuration File +# This file is automatically read and written by the Mupen64Plus Core library + +[64DD] + +# Filename of the 64DD IPL ROM +IPL-ROM = "" +# Filename of the disk to load into Disk Drive +Disk = "" + + +[Audio-SDL] + +# Mupen64Plus SDL Audio Plugin config parameter version number +Version = 1.000000 +# Frequency which is used if rom doesn't want to change it +DEFAULT_FREQUENCY = 33600 +# Swaps left and right channels +SWAP_CHANNELS = False +# Size of primary buffer in output samples. This is where audio is loaded after it's extracted from n64's memory. +PRIMARY_BUFFER_SIZE = 16384 +# Fullness level target for Primary audio buffer, in equivalent output samples. This value must be larger than the SECONDARY_BUFFER_SIZE. Decreasing this value will reduce audio latency but requires a faster PC to avoid choppiness. Increasing this will increase audio latency but reduce the chance of drop-outs. +PRIMARY_BUFFER_TARGET = 2048 +# Size of secondary buffer in output samples. This is SDL's hardware buffer. The SDL documentation states that this should be a power of two between 512 and 8192. +SECONDARY_BUFFER_SIZE = 1024 +# Audio resampling algorithm. src-sinc-best-quality, src-sinc-medium-quality, src-sinc-fastest, src-zero-order-hold, src-linear, speex-fixed-{10-0}, trivial +RESAMPLE = "trivial" +# Volume control type: 1 = SDL (only affects Mupen64Plus output) 2 = OSS mixer (adjusts master PC volume) +VOLUME_CONTROL_TYPE = 1 +# Percentage change each time the volume is increased or decreased +VOLUME_ADJUST = 5 +# Default volume when a game is started. Only used if VOLUME_CONTROL_TYPE is 1 +VOLUME_DEFAULT = 100 +# Synchronize Video/Audio +AUDIO_SYNC = False + + +[Core] + +# Mupen64Plus Core config parameter set version number. Please don't change this version number. +Version = 1.010000 +# Draw on-screen display if True, otherwise don't draw OSD +OnScreenDisplay = True +# Use Pure Interpreter if 0, Cached Interpreter if 1, or Dynamic Recompiler if 2 or more +R4300Emulator = 2 +# Disable compiled jump commands in dynamic recompiler (should be set to False) +NoCompiledJump = False +# Disable 4MB expansion RAM pack. May be necessary for some games +DisableExtraMem = False +# Increment the save state slot after each save operation +AutoStateSlotIncrement = False +# Activate the R4300 debugger when ROM execution begins, if core was built with Debugger support +EnableDebugger = False +# Save state slot (0-9) to use when saving/loading the emulator state +CurrentStateSlot = 0 +# Path to directory where screenshots are saved. If this is blank, the default value of ${UserDataPath}/screenshot will be used +ScreenshotPath = "/storage/roms/screenshots" +# Path to directory where emulator save states (snapshots) are saved. If this is blank, the default value of ${UserDataPath}/save will be used +SaveStatePath = "/storage/roms/n64" +# Path to directory where SRAM/EEPROM data (in-game saves) are stored. If this is blank, the default value of ${UserDataPath}/save will be used +SaveSRAMPath = "/storage/roms/n64" +# Path to a directory to search when looking for shared data files +SharedDataPath = "/storage/.config/game/configs/mupen64plussa" +# Force number of cycles per emulated instruction +CountPerOp = 0 +# Randomize PI/SI Interrupt Timing +RandomizeInterrupt = True +# Duration of SI DMA (-1: use per game settings) +SiDmaDuration = -1 +# Gameboy Camera Video Capture backend +GbCameraVideoCaptureBackend1 = "" +# Disk Save Format (0: Full Disk Copy (*.ndr/*.d6r), 1: RAM Area Only (*.ram)) +SaveDiskFormat = 1 + + +[CoreEvents] + +# Mupen64Plus CoreEvents config parameter set version number. Please don't change this version number. +Version = 1.000000 +# SDL keysym for stopping the emulator +Kbd Mapping Stop = 27 +# SDL keysym for switching between fullscreen/windowed modes +Kbd Mapping Fullscreen = 0 +# SDL keysym for saving the emulator state +Kbd Mapping Save State = 286 +# SDL keysym for loading the emulator state +Kbd Mapping Load State = 288 +# SDL keysym for advancing the save state slot +Kbd Mapping Increment Slot = 0 +# SDL keysym for resetting the emulator +Kbd Mapping Reset = 290 +# SDL keysym for slowing down the emulator +Kbd Mapping Speed Down = 291 +# SDL keysym for speeding up the emulator +Kbd Mapping Speed Up = 292 +# SDL keysym for taking a screenshot +Kbd Mapping Screenshot = 293 +# SDL keysym for pausing the emulator +Kbd Mapping Pause = 112 +# SDL keysym for muting/unmuting the sound +Kbd Mapping Mute = 109 +# SDL keysym for increasing the volume +Kbd Mapping Increase Volume = 93 +# SDL keysym for decreasing the volume +Kbd Mapping Decrease Volume = 91 +# SDL keysym for temporarily going really fast +Kbd Mapping Fast Forward = 102 +# SDL keysym for advancing by one frame when paused +Kbd Mapping Frame Advance = 47 +# SDL keysym for pressing the game shark button +Kbd Mapping Gameshark = 103 +# Joystick event string for stopping the emulator +Joy Mapping Stop = "J0B7/B8" +# Joystick event string for switching between fullscreen/windowed modes +Joy Mapping Fullscreen = "" +# Joystick event string for saving the emulator state +Joy Mapping Save State = "J0B6/B5" +# Joystick event string for loading the emulator state +Joy Mapping Load State = "J0B6/B4" +# Joystick event string for advancing the save state slot +Joy Mapping Increment Slot = "" +# Joystick event string for resetting the emulator +Joy Mapping Reset = "J0B6/B0" +# Joystick event string for slowing down the emulator +Joy Mapping Speed Down = "" +# Joystick event string for speeding up the emulator +Joy Mapping Speed Up = "" +# Joystick event string for taking a screenshot +Joy Mapping Screenshot = "J0B6/B3" +# Joystick event string for pausing the emulator +Joy Mapping Pause = "J0B12/B1" +# Joystick event string for muting/unmuting the sound +Joy Mapping Mute = "" +# Joystick event string for increasing the volume +Joy Mapping Increase Volume = "" +# Joystick event string for decreasing the volume +Joy Mapping Decrease Volume = "" +# Joystick event string for fast-forward +Joy Mapping Fast Forward = "" +# Joystick event string for advancing by one frame when paused +Joy Mapping Frame Advance = "" +# Joystick event string for pressing the game shark button +Joy Mapping Gameshark = "" +# SDL keysym for save slot 0 +Kbd Mapping Slot 0 = 48 +# SDL keysym for save slot 1 +Kbd Mapping Slot 1 = 49 +# SDL keysym for save slot 2 +Kbd Mapping Slot 2 = 50 +# SDL keysym for save slot 3 +Kbd Mapping Slot 3 = 51 +# SDL keysym for save slot 4 +Kbd Mapping Slot 4 = 52 +# SDL keysym for save slot 5 +Kbd Mapping Slot 5 = 53 +# SDL keysym for save slot 6 +Kbd Mapping Slot 6 = 54 +# SDL keysym for save slot 7 +Kbd Mapping Slot 7 = 55 +# SDL keysym for save slot 8 +Kbd Mapping Slot 8 = 56 +# SDL keysym for save slot 9 +Kbd Mapping Slot 9 = 57 + + +[Input-SDL-Control1] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = 0 +# SDL joystick name (or Keyboard) +name = "Xbox Series X Controller" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = True +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control2] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control3] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control4] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Rsp-HLE] + +# Mupen64Plus RSP HLE Plugin config parameter version number +Version = 1.000000 +# Path to a RSP plugin which will be used when encountering an unknown ucode.You can disable this by letting an empty string. +RspFallback = "" +# Send display lists to the graphics plugin +DisplayListToGraphicsPlugin = True +# Send audio lists to the audio plugin +AudioListToAudioPlugin = False + + +[Transferpak] + +# Filename of the GB ROM to load into transferpak 1 +GB-rom-1 = "" +# Filename of the GB RAM to load into transferpak 1 +GB-ram-1 = "" +# Filename of the GB ROM to load into transferpak 2 +GB-rom-2 = "" +# Filename of the GB RAM to load into transferpak 2 +GB-ram-2 = "" +# Filename of the GB ROM to load into transferpak 3 +GB-rom-3 = "" +# Filename of the GB RAM to load into transferpak 3 +GB-ram-3 = "" +# Filename of the GB ROM to load into transferpak 4 +GB-rom-4 = "" +# Filename of the GB RAM to load into transferpak 4 +GB-ram-4 = "" + + +[UI-Console] + +# Mupen64Plus UI-Console config parameter set version number. Please don't change this version number. +Version = 1.000000 +# Directory in which to search for plugins +PluginDir = "/usr/local/lib/mupen64plus" +# Filename of video plugin +VideoPlugin = "mupen64plus-video-rice" +# Filename of audio plugin +AudioPlugin = "mupen64plus-audio-sdl.so" +# Filename of input plugin +InputPlugin = "mupen64plus-input-sdl.so" +# Filename of RSP plugin +RspPlugin = "mupen64plus-rsp-hle.so" + + +[Video-General] + +# Width of output window or fullscreen width +ScreenWidth = 1280 +# Height of output window or fullscreen height +ScreenHeight = 960 +# Use fullscreen mode if True, or windowed mode if False +Fullscreen = True +# If true, activate the SDL_GL_SWAP_CONTROL attribute +VerticalSync = True +# Rotate screen contents: 0=0 degree, 1=90 degree, 2 = 180 degree, 3=270 degree +Rotate = 0 + +[Video-GLideN64] + +###### Hardware Compatibility ###### +# Leave enabled unless a mobile gpu doesn't support it. +EnableFragmentDepthWrite = 1 +# Hardware per pixel lighting, supposedly good for GLES3.1 devices or higher. +EnableHWLighting = 0 + +###### Enhancements ####### +# Internal render resoluton rather than output. So 2 x 240p is 480p, etc. +UseNativeResolutionFactor = 1 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Enable/Disable Fast Approximate Anti-Aliasing FXAA +FXAA = 0 +# Max level of Anisotropic Filtering, 0 for off +anisotropy = 0 +# Bilinear filtering mode (0=N64 3point, 1=standard) +# @rishooty: best to use this at 1x native res, any higher turn it off. +bilinearMode = 1 + +###### Compatibility ###### +# Make texrect coordinates continuous to avoid black lines between them. (0=Off/default, 1=Auto, 2=Force) +CorrectTexrectCoords = 1 +# Copy auxiliary buffers to RDRAM (default: 0) +EnableCopyAuxiliaryToRDRAM = 1 +# Render 2D texrects in native resolution to fix misalignment between parts of 2D image. (0=Off/default, 1=Optimized, 2=Unoptimized)") +EnableNativeResTexrects = 1 + +###### Other ###### +# Enable threaded video backend at the cost of input lag +ThreadedVideo = 1 +# Screen aspect ratio (0=stretch, 1=force 4:3, 2=force 16:9, 3=adjust) +AspectRatio = 1 +# Display On-screen FPS +ShowFPS = False + +[Video-Glide64mk2] + +# Enable full-scene anti-aliasing by setting this to a value greater than 1 +wrpAntiAliasing = 0 +# Card ID +card_id = 0 +# If true, use polygon offset values specified below +force_polygon_offset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +polygon_offset_factor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +polygon_offset_units = 0.000000 +# Vertical sync +vsync = True +# TODO:ssformat +ssformat = False +# Display performance stats (add together desired flags): 1=FPS counter, 2=VI/s counter, 4=% speed, 8=FPS transparent +show_fps = 0 +# Clock enabled +clock = False +# Clock is 24-hour +clock_24_hr = True +# Wrapper resolution +wrpResolution = 0 +# Wrapper VRAM +wrpVRAM = 0 +# Wrapper FBO +wrpFBO = True +# Wrapper Anisotropic Filtering +wrpAnisotropic = True +# Texture Enhancement: Smooth/Sharpen Filters +ghq_fltr = 0 +# Texture Compression: 0 for S3TC, 1 for FXT1 +ghq_cmpr = 0 +# Texture Enhancement: More filters +ghq_enht = 0 +# Hi-res texture pack format (0 for none, 1 for Rice) +ghq_hirs = 1 +# Compress texture cache with S3TC or FXT1 +ghq_enht_cmpr = False +# Tile textures (saves memory but could cause issues) +ghq_enht_tile = 0 +# Force 16bpp textures (saves ram but lower quality) +ghq_enht_f16bpp = False +# Compress texture cache +ghq_enht_gz = True +# Don't enhance textures for backgrounds +ghq_enht_nobg = False +# Enable S3TC and FXT1 compression +ghq_hirs_cmpr = False +# Tile hi-res textures (saves memory but could cause issues) +ghq_hirs_tile = False +# Force 16bpp hi-res textures (saves ram but lower quality) +ghq_hirs_f16bpp = False +# Compress hi-res texture cache +ghq_hirs_gz = True +# Alternative CRC calculation -- emulates Rice bug +ghq_hirs_altcrc = True +# Save tex cache to disk +ghq_cache_save = True +# Texture Cache Size (MB) +ghq_cache_size = 128 +# Use full alpha channel -- could cause issues for some tex packs +ghq_hirs_let_texartists_fly = False +# Dump textures +ghq_hirs_dump = False +# Alternate texture size method: -1=Game default, 0=disable. 1=enable +alt_tex_size = -1 +# Use first SETTILESIZE only: -1=Game default, 0=disable. 1=enable +use_sts1_only = -1 +# Use spheric mapping only: -1=Game default, 0=disable. 1=enable +force_calc_sphere = -1 +# Force positive viewport: -1=Game default, 0=disable. 1=enable +correct_viewport = -1 +# Force texrect size to integral value: -1=Game default, 0=disable. 1=enable +increase_texrect_edge = -1 +# Reduce fillrect size by 1: -1=Game default, 0=disable. 1=enable +decrease_fillrect_edge = -1 +# Enable perspective texture correction emulation: -1=Game default, 0=disable. 1=enable +texture_correction = -1 +# Set special scale for PAL games: -1=Game default, 0=disable. 1=enable +pal230 = -1 +# 3DFX Dithered alpha emulation mode: -1=Game default, >=0=dithered alpha emulation mode +stipple_mode = -1 +# 3DFX Dithered alpha pattern: -1=Game default, >=0=pattern used for dithered alpha emulation +stipple_pattern = -1 +# Check microcode each frame: -1=Game default, 0=disable. 1=enable +force_microcheck = -1 +# Force 0xb5 command to be quad, not line 3D: -1=Game default, 0=disable. 1=enable +force_quad3d = -1 +# Enable near z clipping: -1=Game default, 0=disable. 1=enable +clip_zmin = -1 +# Enable far plane clipping: -1=Game default, 0=disable. 1=enable +clip_zmax = -1 +# Use fast CRC algorithm: -1=Game default, 0=disable. 1=enable +fast_crc = -1 +# Adjust screen aspect for wide screen mode: -1=Game default, 0=disable. 1=enable +adjust_aspect = -1 +# Force strict check in Depth buffer test: -1=Game default, 0=disable. 1=enable +zmode_compare_less = -1 +# Apply alpha dither regardless of alpha_dither_mode: -1=Game default, 0=disable. 1=enable +old_style_adither = -1 +# Scale vertex z value before writing to depth buffer: -1=Game default, 0=disable. 1=enable +n64_z_scale = -1 +# Fast texrect rendering with hwfbe: -1=Game default, 0=disable. 1=enable +optimize_texrect = -1 +# Do not copy auxiliary frame buffers: -1=Game default, 0=disable. 1=enable +ignore_aux_copy = -1 +# Clear auxiliary texture frame buffers: -1=Game default, 0=disable. 1=enable +hires_buf_clear = -1 +# Read alpha from framebuffer: -1=Game default, 0=disable. 1=enable +fb_read_alpha = -1 +# Handle unchanged fb: -1=Game default, 0=disable. 1=enable +useless_is_useless = -1 +# Set frambuffer CRC mode: -1=Game default, 0=disable CRC, 1=fast CRC, 2=safe CRC +fb_crc_mode = -1 +# Filtering mode: -1=Game default, 0=automatic, 1=force bilinear, 2=force point sampled +filtering = -1 +# Fog: -1=Game default, 0=disable. 1=enable +fog = -1 +# Buffer clear on every frame: -1=Game default, 0=disable. 1=enable +buff_clear = -1 +# Buffer swapping method: -1=Game default, 0=swap buffers when vertical interrupt has occurred, 1=swap buffers when set of conditions is satisfied. Prevents flicker on some games, 2=mix of first two methods +swapmode = -1 +# Aspect ratio: -1=Game default, 0=Force 4:3, 1=Force 16:9, 2=Stretch, 3=Original +aspect = -1 +# LOD calculation: -1=Game default, 0=disable. 1=fast, 2=precise +lodmode = -1 +# Smart framebuffer: -1=Game default, 0=disable. 1=enable +fb_smart = -1 +# Hardware frame buffer emulation: -1=Game default, 0=disable. 1=enable +fb_hires = -1 +# Read framebuffer every frame (may be slow use only for effects that need it e.g. Banjo Kazooie, DK64 transitions): -1=Game default, 0=disable. 1=enable +fb_read_always = -1 +# Render N64 frame buffer as texture: -1=Game default, 0=disable, 1=mode1, 2=mode2 +read_back_to_screen = -1 +# Show images written directly by CPU: -1=Game default, 0=disable. 1=enable +detect_cpu_write = -1 +# Get frame buffer info: -1=Game default, 0=disable. 1=enable +fb_get_info = -1 +# Enable software depth render: -1=Game default, 0=disable. 1=enable +fb_render = -1 +# If true, skip up to maxframeskip frames to maintain clock schedule; if false, skip exactly maxframeskip frames +autoframeskip = False +# If autoframeskip is true, skip up to this many frames to maintain clock schedule; if autoframeskip is false, skip exactly this many frames +maxframeskip = 0 + + +[Video-Rice] + +# Mupen64Plus Rice Video Plugin config parameter version number +Version = 1 +# Frame Buffer Emulation (0=ROM default, 1=disable) +FrameBufferSetting = 0 +# Frequency to write back the frame buffer (0=every frame, 1=every other frame, etc) +FrameBufferWriteBackControl = 0 +# Render-to-texture emulation (0=none, 1=ignore, 2=normal, 3=write back, 4=write back and reload) +RenderToTexture = 0 +# Control when the screen will be updated (0=ROM default, 1=VI origin update, 2=VI origin change, 3=CI change, 4=first CI change, 5=first primitive draw, 6=before screen clear, 7=after screen drawn) +ScreenUpdateSetting = 4 +# Force to use normal alpha blender +NormalAlphaBlender = False +# Use a faster algorithm to speed up texture loading and CRC computation +FastTextureLoading = False +# Use different texture coordinate clamping code +AccurateTextureMapping = True +# Force emulated frame buffers to be in N64 native resolution +InN64Resolution = False +# Try to reduce Video RAM usage (should never be used) +SaveVRAM = False +# Enable this option to have better render-to-texture quality +DoubleSizeForSmallTxtrBuf = False +# Force to use normal color combiner +DefaultCombinerDisable = False +# Enable game-specific settings from INI file +EnableHacks = True +# If enabled, graphics will be drawn in WinFrame mode instead of solid and texture mode +WinFrameMode = False +# N64 Texture Memory Full Emulation (may fix some games, may break others) +FullTMEMEmulation = False +# Enable vertex clipper for fog operations +OpenGLVertexClipper = False +# Enable/Disable SSE optimizations for capable CPUs +EnableSSE = True +# If this option is enabled, the plugin will skip every other frame +SkipFrame = False +# If enabled, texture enhancement will be done only for TxtRect ucode +TexRectOnly = False +# If enabled, texture enhancement will be done only for textures width+height<=128 +SmallTextureOnly = False +# Select hi-resolution textures based only on the CRC and ignore format+size information (Glide64 compatibility) +LoadHiResCRCOnly = True +# Enable hi-resolution texture file loading +LoadHiResTextures = False +# Enable texture dumping +DumpTexturesToFiles = False +# Display On-screen FPS +ShowFPS = False +# Use Mipmapping? 0=no, 1=nearest, 2=bilinear, 3=trilinear +Mipmapping = 2 +# Enable, Disable fog generation (0=Disable, 1=Enable) +FogMethod = 1 +# Force to use texture filtering or not (0=auto: n64 choose, 1=force no filtering, 2=force filtering) +ForceTextureFilter = 0 +# Primary texture enhancement filter (0=None, 1=2X, 2=2XSAI, 3=HQ2X, 4=LQ2X, 5=HQ4X, 6=Sharpen, 7=Sharpen More, 8=External, 9=Mirrored) +TextureEnhancement = 0 +# Secondary texture enhancement filter (0 = none, 1-4 = filtered) +TextureEnhancementControl = 0 +# Color bit depth to use for textures (0=default, 1=32 bits, 2=16 bits) +TextureQuality = 0 +# Z-buffer depth (only 16 or 32) +OpenGLDepthBufferSetting = 16 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Color bit depth for rendering window (0=32 bits, 1=16 bits) +ColorQuality = 1 +# OpenGL level to support (0=auto, 1=OGL_FRAGMENT_PROGRAM) +OpenGLRenderSetting = 0 +# Enable/Disable Anisotropic Filtering for Mipmapping (0=no filtering, 2-16=quality). This is uneffective if Mipmapping is 0. If the given value is to high to be supported by your graphic card, the value will be the highest value your graphic card can support. Better result with Trilinear filtering +AnisotropicFiltering = 0 +# If true, use polygon offset values specified below +ForcePolygonOffset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +PolygonOffsetFactor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +PolygonOffsetUnits = 0.000000 diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/package.mk b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/package.mk new file mode 100644 index 0000000000..1305e5a187 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/package.mk @@ -0,0 +1,74 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2019-present Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2023 Nicholas Ricciuti (rishooty@gmail.com) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) +PKG_NAME="mupen64plus-sa-core" +PKG_VERSION="5340dafcc0f5e8284057ab931dd5c66222d3d49e" +#PKG_VERSION="d4f3e12db0609158c7b4e0beef2bb950aad0ccb9" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/mupen64plus/mupen64plus-core" +PKG_URL="https://github.com/mupen64plus/mupen64plus-core/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain boost libpng SDL2 SDL2_net zlib freetype nasm:host" +PKG_LONGDESC="mupen64plus" +PKG_LONGDESC="Mupen64Plus Standalone" +PKG_TOOLCHAIN="manual" + +if [ "${VULKAN_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${VULKAN}" + PKG_MAKE_OPTS_TARGET+=" VULKAN=1" +else + PKG_MAKE_OPTS_TARGET+=" VULKAN=0" +fi + +case ${DEVICE} in + SM8250|SM8550|SM8650) + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" + export USE_GLES=0 + ;; + *) + PKG_DEPENDS_TARGET+=" ${OPENGLES}" + export USE_GLES=1 + ;; +esac + +make_target() { + export HOST_CPU=${TARGET_ARCH} \ + NEW_DYNAREC=1 \ + VFP_HARD=1 \ + V=1 \ + VC=0 \ + OSD=0 + + export BINUTILS="$(get_build_dir binutils)/.${TARGET_NAME}" + export NEW_DYNAREC=1 + export SDL_CFLAGS="-I${SYSROOT_PREFIX}/usr/include/SDL2 -pthread -D_REENTRANT" + export SDL_LDLIBS="-lSDL2_net -lSDL2" + export CROSS_COMPILE="${TARGET_PREFIX}" + + sed -i 's/\-O[23]/-Ofast/' ${PKG_BUILD}/projects/unix/Makefile + + make -C projects/unix clean ${PKG_MAKE_OPTS_TARGET} + make -C projects/unix all ${PKG_MAKE_OPTS_TARGET} +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/local/lib + cp ${PKG_BUILD}/projects/unix/libmupen64plus.so.2.0.0 ${INSTALL}/usr/local/lib + chmod 644 ${INSTALL}/usr/local/lib/libmupen64plus.so.2.0.0 + cp ${PKG_BUILD}/projects/unix/libmupen64plus.so.2 ${INSTALL}/usr/local/lib + + mkdir -p ${INSTALL}/usr/local/share/mupen64plus + cp ${PKG_BUILD}/data/* ${INSTALL}/usr/local/share/mupen64plus + chmod 0644 ${INSTALL}/usr/local/share/mupen64plus/* + + if [ -e "${PKG_DIR}/config/${DEVICE}/mupen64plus.cfg" ] + then + cp ${PKG_DIR}/config/${DEVICE}/* ${INSTALL}/usr/local/share/mupen64plus/ + chmod 644 ${INSTALL}/usr/local/share/mupen64plus/mupen64plus.cfg + fi + + mkdir -p ${INSTALL}/usr/bin + cp ${PKG_DIR}/scripts/start_mupen64plus.sh ${INSTALL}/usr/bin + chmod 755 ${INSTALL}/usr/bin/start_mupen64plus.sh +} + diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/scripts/start_mupen64plus.sh b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/scripts/start_mupen64plus.sh new file mode 100644 index 0000000000..aec4c7e031 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/scripts/start_mupen64plus.sh @@ -0,0 +1,189 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2021-present 351ELEC (https://github.com/351ELEC) +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +set_kill set "-9 mupen64plus" + +# Emulation Station features +GAME=$(echo "${1}"| sed "s#^/.*/##") +PLATFORM=$(echo "${2}"| sed "s#^/.*/##") +SCREENWIDTH=$(fbwidth) +SCREENHEIGHT=$(fbheight) +ASPECT=$(get_setting game_aspect_ratio "${PLATFORM}" "${GAME}") +IRES=$(get_setting internal_resolution "${PLATFORM}" "${GAME}") +RSP=$(get_setting rsp_plugin "${PLATFORM}" "${GAME}") +SIMPLECORE=$(get_setting core_plugin "${PLATFORM}" "${GAME}") +FPS=$(get_setting show_fps "${PLATFORM}" "${GAME}") +PAK=$(get_setting controller_pak "${PLATFORM}" "${GAME}") +CON=$(get_setting input_configuration "${PLATFORM}" "${GAME}") +VPLUGIN=$(get_setting video_plugin "${PLATFORM}" "${GAME}") +CORES=$(get_setting "cores" "${PLATFORM}" "${GAME}") +GLIDEN64CONF=$(get_setting gliden64_profiles "${PLATFORM}" "${GAME}") + +# File locations +SHARE="/usr/local/share/mupen64plus" +GAMEDATA="/storage/.config/mupen64plus" +M64PCONF="${GAMEDATA}/mupen64plus.cfg" +CUSTOMINP="${GAMEDATA}/custominput.ini" +TMP="/tmp/mupen64plus" + +# Clean and create directories +rm -rf ${TMP} +mkdir -p ${TMP} +mkdir -p ${GAMEDATA} + +# Copy files to GAMEDATA +if [[ ! -f "${M64PCONF}" ]]; then + cp ${SHARE}/mupen64plus.cfg* ${GAMEDATA} +fi +if [[ ! -f "${CUSTOMINP}" ]]; then + cp ${SHARE}/default.ini ${CUSTOMINP} +fi + +# Copy files to TMP +cp ${M64PCONF} ${TMP} +if [ "${CON}" = "custom" ]; then + cp ${CUSTOMINP} ${TMP}/InputAutoCfg.ini +elif [ "${CON}" = "standard" ]; then + cp ${SHARE}/default.ini ${TMP}/InputAutoCfg.ini +else + cp ${SHARE}/default.ini ${TMP}/InputAutoCfg.ini +fi +if [ $(echo $1 | grep -i .zip | wc -l) -eq 1 ]; then + # Unzip the game ROM if needed + unzip -q -o "$1" -d ${TMP} + ROM=$(unzip -Zl -1 "$1") +else + cp "$1" ${TMP} + ROM="${GAME}" +fi + +# CPU core settings +if [ "${CORES}" = "little" ]; then + EMUPERF="${SLOW_CORES}" +elif [ "${CORES}" = "big" ]; then + EMUPERF="${FAST_CORES}" +else + unset EMUPERF +fi + +# Configure Mupen64Plus-SA parameters +SET_PARAMS="" + +# Emulator core settings +SET_PARAMS+=" --set Core[SharedDataPath]=${TMP}" +if [ "${SIMPLECORE}" = "simple" ]; then + SIMPLESUFFIX="-simple" + SET_PARAMS+=" --set Core[R4300Emulator]=1" +else + SIMPLESUFFIX="" + SET_PARAMS+=" --set Core[R4300Emulator]=2" +fi + +# Input settings +SET_PARAMS+=" --set Input-SDL-Control1[plugin]=${PAK}" +SET_PARAMS+=" --set Input-SDL-Control2[plugin]=${PAK}" +SET_PARAMS+=" --set Input-SDL-Control3[plugin]=${PAK}" +SET_PARAMS+=" --set Input-SDL-Control4[plugin]=${PAK}" + +# Video settings +SET_PARAMS+=" --set Video-General[ScreenHeight]=${SCREENHEIGHT}" +SET_PARAMS+=" --set Video-Parallel[ScreenWidth]=${SCREENWIDTH}" +SET_PARAMS+=" --set Video-Parallel[ScreenHeight]=${SCREENHEIGHT}" +SET_PARAMS+=" --set Video-Parallel[Upscaling]=${IRES}" +SET_PARAMS+=" --set Video-GLideN64[UseNativeResolutionFactor]=${IRES}" +SET_PARAMS+=" --set Video-Rice[ResolutionWidth]=${SCREENWIDTH}" +if [ "${ASPECT}" = "fullscreen" ]; then + SET_PARAMS+=" --set Video-General[ScreenWidth]=${SCREENWIDTH}" + SET_PARAMS+=" --set Video-Parallel[WidescreenStretch]=False" + SET_PARAMS+=" --set Video-GLideN64[AspectRatio]=3" + SET_PARAMS+=" --set Video-Glide64mk2[aspect]=2" +else + if [ -z "${VPLUGIN}" ] || [ "${VPLUGIN}" = "rice" ]; then + GAMEWIDTH=$(((SCREENHEIGHT * 4) / 3)) + SET_PARAMS+=" --set Video-General[ScreenWidth]=${GAMEWIDTH}" + else + SET_PARAMS+=" --set Video-General[ScreenWidth]=${SCREENWIDTH}" + fi + SET_PARAMS+=" --set Video-Parallel[WidescreenStretch]=False" + SET_PARAMS+=" --set Video-GLideN64[AspectRatio]=1" + SET_PARAMS+=" --set Video-Glide64mk2[aspect]=0" +fi +if [ "${FPS}" = "true" ]; then + export LIBGL_SHOW_FPS="1" + export GALLIUM_HUD="cpu+GPU-load+fps" + SET_PARAMS+=" --set Video-GLideN64[ShowFPS]=True" + SET_PARAMS+=" --set Video-Glide64mk2[show_fps]=1" + SET_PARAMS+=" --set Video-Rice[ShowFPS]=True" +else + export LIBGL_SHOW_FPS="0" + export GALLIUM_HUD="off" + SET_PARAMS+=" --set Video-GLideN64[ShowFPS]=False" + SET_PARAMS+=" --set Video-Glide64mk2[show_fps]=0" + SET_PARAMS+=" --set Video-Rice[ShowFPS]=False" +fi + +# GLideN64 Profiles +if [ "${GLIDEN64CONF}" = "performance" ]; then + SET_PARAMS+=" --set Video-GLideN64[EnableLOD]=False" + SET_PARAMS+=" --set Video-GLideN64[EnableLegacyBlending]=True" + SET_PARAMS+=" --set Video-GLideN64[EnableHybridFilter]=False" + SET_PARAMS+=" --set Video-GLideN64[EnableInaccurateTextureCoordinates]=True" + SET_PARAMS+=" --set Video-GLideN64[EnableCopyColorToRDRAM]=0" + SET_PARAMS+=" --set Video-GLideN64[EnableCopyDepthToRDRAM]=0" + SET_PARAMS+=" --set Video-GLideN64[BackgroundsMode]=0" + SET_PARAMS+=" --set Video-GLideN64[RDRAMImageDitheringMode]=0" + SET_PARAMS+=" --set Video-GLideN64[CorrectTexrectCoords]=0" +else + SET_PARAMS+=" --set Video-GLideN64[EnableLOD]=True" + SET_PARAMS+=" --set Video-GLideN64[EnableLegacyBlending]=False" + SET_PARAMS+=" --set Video-GLideN64[EnableHybridFilter]=False" + SET_PARAMS+=" --set Video-GLideN64[EnableInaccurateTextureCoordinates]=False" + SET_PARAMS+=" --set Video-GLideN64[EnableCopyColorToRDRAM]=2" +fi + +# Set the video plugin +case ${VPLUGIN} in + "rmg_parallel") + SET_PARAMS+=" --gfx mupen64plus-video-parallel${SIMPLESUFFIX}.so" + RSP="parallel" + ;; + "gliden64") + SET_PARAMS+=" --gfx mupen64plus-video-GLideN64${SIMPLESUFFIX}.so" + ;; + "gl64mk2") + SET_PARAMS+=" --gfx mupen64plus-video-glide64mk2${SIMPLESUFFIX}.so" + ;; + "rice") + SET_PARAMS+=" --gfx mupen64plus-video-rice${SIMPLESUFFIX}.so" + ;; + *) + SET_PARAMS+=" --gfx mupen64plus-video-rice${SIMPLESUFFIX}.so" + ;; +esac + +# Set the RSP plugin +case "${RSP}" in + "parallel") + SET_PARAMS+=" --rsp mupen64plus-rsp-parallel${SIMPLESUFFIX}.so" + ;; + "hle") + SET_PARAMS+=" --rsp mupen64plus-rsp-hle${SIMPLESUFFIX}.so" + ;; + *) + SET_PARAMS+=" --rsp mupen64plus-rsp-cxd4${SIMPLESUFFIX}.so" + ;; +esac + +# Set the remaining plugins +SET_PARAMS+=" --input mupen64plus-input-sdl${SIMPLESUFFIX}.so" +SET_PARAMS+=" --audio mupen64plus-audio-sdl${SIMPLESUFFIX}.so" + +# Echo the command line options to the log for debugging +echo ${SET_PARAMS} + +${EMUPERF} /usr/local/bin/mupen64plus${SIMPLESUFFIX} --configdir ${TMP} ${SET_PARAMS} "${TMP}/${ROM}" diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/H700/default.ini b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/H700/default.ini new file mode 100644 index 0000000000..b9c13645ac --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/H700/default.ini @@ -0,0 +1,25 @@ +; H700 analog joypad - default.ini +[H700 Gamepad] +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = button(16) +DPad L = button(15) +DPad D = button(14) +DPad U = button(13) +Start = button(9) +Z Trig = button(6) +B Button = button(2) +A Button = button(0) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/H700/zlswap.ini b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/H700/zlswap.ini new file mode 100644 index 0000000000..d84ef18af8 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/H700/zlswap.ini @@ -0,0 +1,25 @@ +; H700 analog joypad - zlswap.ini +[H700 Gamepad] +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = button(16) +DPad L = button(15) +DPad D = button(14) +DPad U = button(13) +Start = button(9) +Z Trig = button(4) +B Button = button(2) +A Button = button(0) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(5) +L Trig = button(6) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/InputAutoCfg.ini b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/InputAutoCfg.ini new file mode 100644 index 0000000000..e4de820adc --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/InputAutoCfg.ini @@ -0,0 +1,2073 @@ +; InputAutoCfg.ini for Mupen64Plus SDL Input plugin for RGB10 + +[Keyboard] +plugged = True +mouse = False +DPad R = key(100) +DPad L = key(97) +DPad D = key(115) +DPad U = key(119) +Start = key(13) +Z Trig = key(122) +B Button = key(306) +A Button = key(304) +C Button R = key(108) +C Button L = key(106) +C Button D = key(107) +C Button U = key(105) +R Trig = key(99) +L Trig = key(120) +Mempak switch = key(44) +Rumblepak switch = key(46) +X Axis = key(276,275) +Y Axis = key(273,274) + +[Austgame PS to USB convert cable] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(8) +Z Trig = button(4) +B Button = button(3) +A Button = button(2) +C Button R = button(1) +C Button L = button(0) +C Button D = button(5) +C Button U = axis(3-) +R Trig = button(7) +L Trig = button(6) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[BDA Pro Ex] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = axis(4+) +DPad L = axis(4-) +DPad D = axis(5+) +DPad U = axis(5-) +Start = button(9) +Z Trig = button(7) +B Button = button(2) +A Button = button(1) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = key(44) +Rumblepak switch = key(46) +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +; Boom Smart Joy Converter +[HID 6666:0667] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = button(13) +DPad L = button(15) +DPad D = button(14) +DPad U = button(12) +Start = button(11) +Z Trig = button(10) +B Button = button(4) +A Button = button(5) +C Button R = button(1) +C Button L = button(3) +C Button D = button(2) +C Button U = button(0) +R Trig = button(7) +L Trig = button(6) +Mempak switch = key(109) +Rumblepak switch = key(114) +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Cyborg V.3 Rumble Pad] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = axis(4+) +DPad L = axis(4-) +DPad D = axis(5+) +DPad U = axis(5-) +Start = button(12) +Z Trig = button(7) +B Button = button(0) +A Button = button(1) +C Button R = button(8) axis(2+) +C Button L = button(3) axis(2-) +C Button D = button(2) axis(3+) +C Button U = button(9) axis(3-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[DragonRise Inc. Generic USB Joystick] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = key(275) axis(0+) +DPad L = key(276) axis(0-) +DPad D = key(274) axis(1+) +DPad U = key(273) axis(1-) +Start = button(9) +Z Trig = button(4) +B Button = button(3) +A Button = button(2) +C Button R = button(7) axis(3+) +C Button L = button(6) axis(3-) +C Button D = button(1) axis(4+) +C Button U = button(0) axis(4-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +; FuSa is a homebrew program which allows a PSP to be used as a gamepad +[FuSa FuSa GamePad] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = +DPad L = +DPad D = +DPad U = +Start = button(7) +Z Trig = button(4) +B Button = button(2) +A Button = button(0) +C Button R = hat(0 Right) +C Button L = hat(0 Left) +C Button D = hat(0 Down) +C Button U = hat(0 Up) +R Trig = button(5) +L Trig = button(3) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +; "Super Joy Box 13" USB adaptor for a Gamecube controller +[GameCube to USB box 1] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(7) +Z Trig = button(6) +B Button = button(1) +A Button = button(0) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3-) +C Button U = axis(3+) +R Trig = axis(5+) +L Trig = axis(4+) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Gasia Co.,Ltd PS(R) Gamepad] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = key(275) axis(0+) hat(0 Right) +DPad L = key(276) axis(0-) hat(0 Left) +DPad D = key(274) axis(1+) hat(0 Down) +DPad U = key(273) axis(1-) hat(0 Up) +Start = button(9) +Z Trig = button(6) +B Button = button(3) +A Button = button(2) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = button(1) +Rumblepak switch = button(0) +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +; raphnet technologies USB converter (http://www.raphnet-tech.com/) +[GC/N64_USB] +[GC/N64 to USB, v2.9] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = button(13) +DPad L = button(12) +DPad D = button(11) +DPad U = button(10) +Start = button(3) +Z Trig = button(2) +B Button = button(1) +A Button = button(0) +C Button R = button(7) +C Button L = button(6) +C Button D = button(5) +C Button U = button(4) +R Trig = button(9) +L Trig = button(8) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +; raphnet technologies USB converter, v3 series (http://www.raphnet-tech.com/) +[raphnet technologies GC/N64 to USB] +[raphnet technologies N64 to USB] +[raphnet technologies Dual N64 to USB] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = button(13) +DPad L = button(12) +DPad D = button(11) +DPad U = button(10) +Start = button(3) +Z Trig = button(2) +B Button = button(1) +A Button = button(0) +C Button R = button(9) +C Button L = button(8) +C Button D = button(7) +C Button U = button(6) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +; Retrolink N64 USB clone +[Generic USB Joystick] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = axis(5+) +DPad L = axis(5-) +DPad D = axis(6+) +DPad U = axis(6-) +Start = button(9) +Z Trig = button(7) +B Button = button(8) +A Button = button(6) +C Button R = button(1) +C Button L = button(3) +C Button D = button(2) +C Button U = button(0) +R Trig = button(5) +L Trig = button(4) +Mempak switch = key(109) +Rumblepak switch = key(114) +Y Axis = axis(1-,1+) +X Axis = axis(0-,0+) + +; gioteck VX2PS3-21 RF Wireless Controller +[Goodbetterbest Ltd PC USB Controller] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +Mempak switch = button(7) +Rumblepak switch = +C Button D = button(1) axis(3+) +C Button L = axis(2-) +Z Trig = button(6) +Start = button(9) +Y Axis = axis(1-,1+) +DPad U = hat(0 Up) +C Button U = button(0) axis(3-) +A Button = button(2) +DPad D = hat(0 Down) +X Axis = axis(0-,0+) +R Trig = button(5) +DPad R = hat(0 Right) +B Button = button(3) +DPad L = hat(0 Left) +C Button R = axis(2+) +L Trig = button(4) + +[GreenAsia Inc. USB Joystick] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(9) +Z Trig = button(1) +B Button = button(3) +A Button = button(2) +C Button R = axis(3+) +C Button L = axis(3-) +C Button D = axis(2+) +C Button U = axis(2-) +R Trig = button(7) +L Trig = button(6) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[GS gamepad] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(9) +Z Trig = button(7) +B Button = button(2) +A Button = button(0) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Guillemot Corporation DA Leader] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(12) +Z Trig = button(11) +B Button = button(1) +A Button = button(3) +C Button R = button(6) +C Button L = button(4) +C Button D = button(7) +C Button U = button(5) +R Trig = button(2) +L Trig = button(0) +Mempak switch = key(44) +Rumblepak switch = key(46) +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[ipega media gamepad controller] +plugged = True +mouse = False +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(11) +Z Trig = button(6) +B Button = button(3) +A Button = button(0) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = axis(4+) +L Trig = axis(5+) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[ipega gamepad controller] +plugged = True +mouse = False +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(9) +Z Trig = button(2) +B Button = button(0) +A Button = button(1) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Jess Tech Dual Analog Pad] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(9) +Z Trig = button(7) +B Button = button(0) +A Button = button(2) +C Button R = axis(3+) +C Button L = axis(3-) +C Button D = axis(2+) +C Button U = axis(2-) +R Trig = button(6) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Win32: Colour Rumble Pad] +[Jess Tech Colour Rumble Pad] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(9) +Z Trig = button(4) +B Button = button(0) +A Button = button(2) +C Button R = axis(3+) +C Button L = axis(3-) +C Button D = axis(2+) +C Button U = axis(2-) +R Trig = button(7) +L Trig = button(5) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Jess Tech USB 4-Axis 12-Button Gamepad] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(4) +Z Trig = button(5) +B Button = button(8) +A Button = button(9) +C Button R = button(1) +C Button L = button(3) +C Button D = button(2) +C Button U = button(0) +R Trig = button(7) +L Trig = button(6) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Jess Technology Co., Ltd. USB Game Controllers] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = axis(0+) +DPad L = axis(0-) +DPad D = axis(1+) +DPad U = axis(1-) +Start = button(9) +Z Trig = button(3) +B Button = button(0) +A Button = button(2) +C Button R = axis(5+) +C Button L = axis(5-) +C Button D = axis(2+) +C Button U = axis(2-) +R Trig = button(6) +L Trig = button(4) +Mempak switch = button(7) +Rumblepak switch = button(5) +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +; X-box controllers and compatible clones +[Logitech Chillstream Controller] +[Logic3 Controller] +[HORIPAD ONE] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(7) +Z Trig = axis(2+) +B Button = button(2) +A Button = button(0) +C Button R = axis(3+) +C Button L = axis(3-) +C Button D = axis(4+) +C Button U = axis(4-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = button(6) +Rumblepak switch = button(8) +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Logitech Cordless Rumblepad 2] +[Logitech Cordless RumblePad 2] +[Logitech RumblePad 2 USB] +[Logitech Dual Action] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = axis(4+) hat(0 Right) +DPad L = axis(4-) hat(0 Left) +DPad D = axis(5+) hat(0 Down) +DPad U = axis(5-) hat(0 Up) +Start = button(9) +Z Trig = button(6) +B Button = button(0) +A Button = button(1) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = button(8) +Rumblepak switch = button(7) +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Logitech Gamepad F310] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(7) +Z Trig = button(5) +B Button = button(2) +A Button = button(0) +C Button R = axis(3+) +C Button L = axis(3-) +C Button D = axis(4+) +C Button U = axis(4-) +R Trig = axis(5-) +L Trig = axis(2-) +Mempak switch = button(1) +Rumblepak switch = button(3) +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Logitech Gamepad F710] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(7) +Z Trig = axis(2+) +B Button = button(0) +A Button = button(1) +C Button R = axis(3+) +C Button L = axis(3-) +C Button D = axis(4+) +C Button U = axis(4-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = button(6) +Rumblepak switch = axis(5+) +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Logitech Logitech(R) Precision(TM) Gamepad] +[Gravis GamePad Pro USB] +plugged = True +mouse = False +AnalogDeadzone = 100,100 +AnalogPeak = 32768,32768 +DPad R = axis(0+) +DPad L = axis(0-) +DPad D = axis(1+) +Dpad U = axis(1-) +Start = button(9) +Z Trig = button(6) +B Button = button(5) +A Button = button(4) +C Button R = button(2) +C Button L = button(0) +C Button D = button(1) +C Button U = button(3) +R Trig = button(7) +L Trig = button(8) +Mempack switch = +Rumblepak Switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Logitech WingMan Action Pad] +[Logitech Inc WingMan RumblePad] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = button(13) +DPad L = button(15) +DPad D = button(14) +DPad U = button(12) +Start = button(8) +Z Trig = button(6) +B Button = button(3) +A Button = button(0) +C Button R = button(2) +C Button L = button(4) +C Button D = button(1) +C Button U = button(5) +R Trig = button(7) +L Trig = +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Mayflash GC Controller Adapter 4-Port] +; Mayflash Gamecube 4-Port Controller Adapter (for PC & Wii U USB) - With one Gamecube gamepad(s) connected +; this is a 4-port USB device. The ports from left to right are p1, p2, p3, p4. +; This is configured for Toki no Ocarina, therefore the L trig represents the Z trig and vice versa +plugged = True +mouse = False +AnalogDeadzone = 128,128 +AnalogPeak = 28000,28000 +DPad R = hat(4 Right) +DPad L = hat(4 Left) +DPad D = hat(4 Down) +DPad U = hat(4 Up) +Start = button(36) +; L Trig is mapped to Z +Z Trig = axis(12+) +B Button = button(8) +A Button = button(4) +C Button R = axis(20+) +C Button L = axis(20-) +C Button D = axis(8+) +C Button U = axis(8-) +R Trig = axis(16+) +L Trig = button(28) +Mempak switch = +Rumblepak switch = +Y Axis = axis(0-,0+) +X Axis = axis(4-,4+) + +[Mega World Thrustmaster dual analog 3.2] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(9) +Z Trig = button(8) +B Button = button(1) +A Button = button(0) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(6) +L Trig = button(4) +Mempak switch = button(5) +Rumblepak switch = button(7) +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Mega World USB Game Controllers] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(9) +Z Trig = button(7) +B Button = button(0) +A Button = button(2) +C Button R = axis(3+) +C Button L = axis(3-) +C Button D = axis(2+) +C Button U = axis(2-) +R Trig = button(6) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[MP-8866 Dual USB Joypad] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(8) +Z Trig = button(6) +B Button = button(3) +A Button = button(2) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(7) +L Trig = button(4) +Mempak switch = button(10) +Rumblepak switch = button(11) +Y Axis = axis(1-,1+) +X Axis = axis(0-,0+) + +; Nes30 Pro Controller +; NB - this maps Z trigger to button Y +; Select, L2 and R2 are unmapped +[Bluetooth Wireless Controller ] +[8Bitdo NES30 Pro] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = axis(6+) +DPad L = axis(6-) +DPad D = axis(7+) +DPad U = axis(7-) +Start = button(11) +Z Trig = button(4) +B Button = button(1) +A Button = button(0) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(7) +L Trig = button(6) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Linux: Microsoft X-Box 360 pad] +[Linux: Xbox 360 Wireless Receiver (XBOX)] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(7) +Z Trig = axis(2+) +B Button = button(2) +A Button = button(0) +C Button R = axis(3+,24000) +C Button L = axis(3-,24000) button(3) +C Button D = axis(4+,24000) button(1) +C Button U = axis(4-,24000) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +; Multilaser PS2 Generic Controller JS030 +[Linux: Microntek USB Joystick] +[Win32: USB Network Joystick] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(9) +Z Trig = button(6) +B Button = button(3) +A Button = button(2) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Microsoft X-Box 360 pad] +[Microsoft X-Box One pad] +[Win32: Controller (XBOX 360 For Windows)] +[Win32: XBOX 360 For Windows (Controller)] +[Win32: XBOX 360 For Windows] +[Xbox 360 Wireless Receiver] +[Linux: Xbox Gamepad (userspace driver)] +[Afterglow Gamepad for Xbox 360] +[Controller (Xbox One For Windows)] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(7) +Z Trig = axis(2+) +B Button = button(2) +A Button = button(0) +C Button R = axis(4+,24000) +C Button L = axis(4-,24000) +C Button D = axis(3+,24000) +C Button U = axis(3-,24000) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +# mappings for use with the TattieBogle driver under OSX, given in googlecode.com issue #630 +[OSX: Wireless 360 Controller] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = button(3) +DPad L = button(2) +DPad D = button(0) +DPad U = button(1) +Start = button(4) +Z Trig = axis(5+) +B Button = button(13) +A Button = button(11) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(9) +L Trig = button(8) +Mempak switch = "" +Rumblepak switch = "" +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +# For Xbox One controllers in Bluetooth mode +[Xbox Wireless Controller] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(11) +Z Trig = button(7) +B Button = button(1) +A Button = button(0) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = axis(4+) +L Trig = axis(5+) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +# from the Google Group, with the tattiebogle driver 0.15 beta 3 under El Capitan 10.11.1 +[OSX: Xbox 360 Wired Controller] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = button(14) +DPad L = button(13) +DPad D = button(12) +DPad U = button(11) +Start = button(8) +Z Trig = axis(2+) +B Button = button(2) +A Button = button(0) +C Button R = axis(3+) +C Button L = axis(3-) +C Button D = axis(4+) +C Button U = axis(4-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = "" +Rumblepak switch = "" +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +; ACRUX Gamepad (USB ID: 1a34:0802), a Xbox 360 controller clone aviable under +; various brands (e.g. techsolo TG-30) +[USB GAMEPAD 8116] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(9) +Z Trig = axis(4-) +B Button = button(2) +A Button = button(0) +C Button R = axis(3+) +C Button L = axis(3-) button(3) +C Button D = axis(2+) button(1) +C Button U = axis(2-) +R Trig = button(5) axis(4+) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[XInput: Microsoft X-Box 360 pad] +[XInput: Controller (XBOX 360 For Windows)] +[XInput: XBOX 360 For Windows (Controller)] +[XInput: XBOX 360 For Windows] +[XInput: Xbox 360 Wireless Receiver] +[XInput: XInput Controller #] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(7) +Z Trig = axis(2+) +B Button = button(2) +A Button = button(0) +C Button R = axis(3+) +C Button L = axis(3-) button(3) +C Button D = axis(4+) button(1) +C Button U = axis(4-) +R Trig = button(5) axis(5+) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +;Snakebyte PS3-style USB controller +[MY-POWER CO.,LTD. 2In1 USB Joystick] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(9) +Z Trig = button(7) +B Button = button(2) +A Button = button(1) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[N64 controller] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(9) +Z Trig = button(0) +B Button = button(2) +A Button = button(1) +C Button R = button(4) +C Button L = button(5) +C Button D = button(3) +C Button U = button(6) +R Trig = button(8) +L Trig = button(7) +Mempak switch = key(109) +Rumblepak switch = key(114) +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Nintendo Wiimote Classic] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = button(23) +DPad L = button(22) +DPad D = button(21) +DPad U = button(20) +Start = button(17) +Z Trig = button(24) +B Button = button(14) +A Button = button(13) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(25) +L Trig = button(26) +Mempak switch = button(16) +Rumblepak switch = button(15) +X Axis = axis(4-,4+) +Y Axis = axis(5-,5+) + +[Nintendo Wii Remote Pro Controller] +plugged = True +mouse = False +AnalogDeadzone = 2000,2000 +AnalogPeak = 17000,17000 +DPad R = button(16) +DPad L = button(15) +DPad D = button(14) +DPad U = button(13) +Start = button(9) +Z Trig = button(6) +B Button = button(0) +A Button = button(1) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[OUYA Game Controller] +plugged = True +mouse = False +Mempak switch = +Rumblepak switch = +DPad U = button(8) +DPad D = button(9) +DPad L = button(10) +DPad R = button(11) +Start = button(7) +Z Trig = button(12) +A Button = button(0) +B Button = button(1) +C Button U = axis(4-) +C Button D = axis(4+) +C Button L = axis(3-) +C Button R = axis(3+) +L Trig = button(4) +R Trig = button(5) +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[PC Game Controller] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(9) +Z Trig = button(8) +B Button = button(4) +A Button = button(5) +C Button R = button(1) +C Button L = button(3) +C Button D = button(2) +C Button U = button(0) +R Trig = button(7) +L Trig = button(6) +Mempak switch = key(109) +Rumblepak switch = key(114) +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +; Nintendo Switch Pro Controller +[Pro Controller] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = axis(4+) +DPad L = axis(4-) +DPad D = axis(5+) +DPad U = axis(5-) +Start = button(9) +Z Trig = button(6) +B Button = button(0) +A Button = button(1) +C Button R = axis(2-) +C Button L = axis(2+) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(7) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +; Playfect PS3 controller (cheap clone of the Sony DualShock 3 controller) +[PS3/PC WirelessGamePad] +plugged = True +mouse = False +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(9) +Z Trig = button(4) +B Button = button(3) +A Button = button(2) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(5) +L Trig = button(6) +Mempak switch = key(109) +Rumblepak switch = key(114) +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +; this is also the MayFlash / HuiJia adapter +[PS/SS/N64 Joypad to USB BOX] +plugged=True +mouse=False +AnalogDeadzone=1024,1024 +AnalogPeak=11000,11000 +DPad R=hat(0 right) +DPad L=hat(0 left) +DPad U=hat(0 up) +DPad D=hat(0 down) +Start=button(8) +Z Trig=button(9) +B Button=button(2) +A Button=button(1) +C Button R=axis(2-) +C Button L=axis(2+) +C Button U=axis(3-) +C Button D=axis(3+) +R Trig=button(7) +L Trig=button(5) +X Axis=axis(0-,0+) +Y Axis=axis(1-,1+) + +[Rock Candy Gamepad for PS3] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(9) +Z Trig = button(7) +B Button = button(0) +A Button = button(2) +C Button R = axis(3+) +C Button L = axis(3-) +C Button D = axis(2+) +C Button U = axis(2-) +R Trig = button(6) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[PLAYSTATION(R)3 Controller] +[Sony PLAYSTATION(R)3 Controller] +[SHENGHIC 2009/0708ZXW-V1Inc. PLAYSTATION(R)3Conteroller] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = button(5) +DPad L = button(7) +DPad D = button(6) +DPad U = button(4) +Start = button(3) +Z Trig = button(10) +B Button = button(15) +A Button = button(14) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(11) +L Trig = button(8) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Sony Computer Entertainment Wireless Controller] +[Sony Interactive Entertainment Wireless Controller] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(9) +Z Trig = axis(3+) +B Button = button(0) +A Button = button(1) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(5+) +C Button U = axis(5-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +; Sony DS4 connected via Bluetooth advertises itself as "Wireless Controller" +[Wireless Controller] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(9) +; L2, change to 7 for R2 +Z Trig = button(6) +B Button = button(0) +A Button = button(1) +C Button R = axis(3+) +C Button L = axis(3-) +C Button D = axis(4+) +C Button U = axis(4-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[SAITEK P880] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(10) +Z Trig = button(3) +B Button = button(0) +A Button = button(2) +C Button R = button(5) axis(3+) +C Button L = button(1) axis(3-) +C Button D = button(9) axis(2+) +C Button U = button(4) axis(2-) +R Trig = button(7) +L Trig = button(6) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Saitek P990 Dual Analog Pad] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(5) +Z Trig = button(4) +B Button = button(0) +A Button = button(1) +C Button R = button(8) axis(3+) +C Button L = button(3) axis(3-) +C Button D = button(2) axis(2+) +C Button U = button(9) axis(2-) +R Trig = button(7) +L Trig = button(6) +Mempak switch = button(11) +Rumblepak switch = button(10) +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Saitek P2900 Wireless Pad] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = axis(4+) +DPad L = axis(4-) +DPad D = axis(5+) +DPad U = axis(5-) +Start = button(6) +Z Trig = button(7) +B Button = button(0) +A Button = button(1) +C Button R = button(8) axis(3+) +C Button L = button(3) axis(3-) +C Button D = button(2) axis(2+) +C Button U = button(9) axis(2-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = button(11) +Rumblepak switch = axis(10+) +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Saitek PLC Cyborg Force Rumble Pad] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(9) +Z Trig = button(8) +B Button = button(0) +A Button = button(2) +C Button R = button(5) axis(3+) +C Button L = button(1) axis(3-) +C Button D = button(3) axis(2+) +C Button U = button(4) axis(2-) +R Trig = button(7) +L Trig = button(6) +Mempak switch = button(11) +Rumblepak switch = axis(10+) +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[ShanWan USB WirelessGamepad] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = axis(0+) +DPad L = axis(0-) +DPad D = axis(1+) +DPad U = axis(1-) +Start = button(9) +Z Trig = button(8) +B Button = button(3) +A Button = button(2) +C Button R = button(7) +C Button L = button(6) +C Button D = button(1) +C Button U = button(0) +R Trig = button(5) +L Trig = button(4) +Mempak switch = key(109) +Rumblepak switch = key(114) +Y Axis = axis(1-,1+) +X Axis = axis(0-,0+) + +[SZMY-POWER CO.,LTD. GAMEPAD 3 TURBO] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(9) +Z Trig = button(6) +B Button = button(0) +A Button = button(1) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = key(44) +Rumblepak switch = key(46) +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Thrustmaster Dual Trigger 3-in-1] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(9) +Z Trig = button(3) +B Button = button(0) +A Button = button(1) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(5+) +C Button U = axis(5-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = button(6) +Rumblepak switch = button(7) +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[THRUSTMASTER Firestorm Dual Power 2] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(5) +Z Trig = button(8) +B Button = button(1) +A Button = button(0) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(6) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Thrustmaster T Mini Wireless] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat (0 Right) +DPad L = hat (0 Left) +DPad D = hat (0 Down) +DPad U = hat (0 Up) +Start = button(9) +Z Trig = button(5) +B Button = button(0) +A Button = button(1) +C Button R = Axis = axis(2+) +C Button L = Axis = axis(2-) +C Button D = Axis = axis(3+) +C Button U = Axis = axis(3-) +R Trig = button(7) +L Trig = button(6) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Twin USB Joystick] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(9) +Z Trig = button(4) +B Button = button(6) +A Button = button(7) +C Button R = button(1) +C Button L = button(3) +C Button D = button(2) +C Button U = button(0) +R Trig = button(5) +L Trig = button(11) +Mempak switch = +Rumblepak switch = +Y Axis = axis(1-,1+) +X Axis = axis(0-,0+) + +[Twin USB Vibration Gamepad] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(9) +Z Trig = button(7) +B Button = button(0) +A Button = button(2) +C Button R = axis(3+) +C Button L = axis(3-) +C Button D = axis(2+) +C Button U = axis(2-) +R Trig = button(6) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +;Twin USB PS-controller lookalike, branded "POWER PAD". +;The controller closest to the USB-plug is Player 1. +[Twin USB Gamepad] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(9) +Z Trig = button(4) +B Button = button(3) +A Button = button(2) +C Button R = axis(3+) +C Button L = axis(3-) +C Button D = axis(2+) +C Button U = axis(2-) +R Trig = button(7) +L Trig = button(6) +Mempak switch = +Rumblepak switch = +Y Axis = axis(1-,1+) +X Axis = axis(0-,0+) + +[Wii U GameCube Adapter Port 1] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = button(11) +DPad L = button(10) +DPad D = button(9) +DPad U = button(8) +Start = button(7) +Z Trig = button(4) +B Button = button(3) +A Button = button(0) +C Button R = axis(3+) +C Button L = axis(3-) +C Button D = axis(4+) +C Button U = axis(4-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[TigerGame XBOX+PS2+GC Game Controller Adapter] +[WiseGroup.,Ltd TigerGame XBOX+PS2+GC Game Controller Adapter] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = button(9) +DPad L = button(8) +DPad D = button(10) +DPad U = button(11) +Start = button(7) +Z Trig = button(6) +B Button = button(1) +A Button = button(0) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = axis(4+) +L Trig = axis(5+) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Wish Technologies Adaptoid] +[Adaptoid] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = button(13) +DPad L = button(12) +DPad D = button(11) +DPad U = button(10) +Start = button(8) +Z Trig = button(9) +B Button = button(3) +A Button = button(0) +C Button R = button(2) +C Button L = button(4) +C Button D = button(1) +C Button U = button(5) +R Trig = button(7) +L Trig = button(6) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +; X-box controllers and compatible clones +[Microsoft X-Box pad v1 (US)] +[Microsoft X-Box pad v2 (US)] +[Microsoft X-Box pad (Japan)] +[Microsoft Xbox Controller S] +[Thrustmaster, Inc. Controller] +[Logitech Xbox Cordless Controller] +[Logitech Compact Controller for Xbox] +[Mad Catz Controller (unverified)] +[InterAct 'PowerPad Pro' X-Box pad (Germany)] +[Mad Catz Control Pad] +[Mad Catz LumiCON] +[Mad Catz Control Pad Pro] +[Mad Catz MicroCON] +[Mad Catz Lynx Wireless Controller] +[Zeroplus Xbox Controller] +[Pelican Eclipse PL-2023] +[Zeroplus Xbox Controller] +[Radica Gamester Controller] +[Radica Games Jtech Controller] +[Logic3 Freebird wireless Controller] +[Eclipse wireless Controller] +[Edge wireless Controller] +[SmartJoy Frag Xpad/PS2 adaptor] +[Joytech Advanced Controller] +[BigBen XBMiniPad Controller] +[Joytech Wireless Advanced Controller] +[Chinese-made Xbox Controller] +[Generic X-Box pad] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(7) +Z Trig = axis(2+) +B Button = button(2) +A Button = button(0) +C Button R = axis(3+) +C Button L = axis(3-) button(3) +C Button D = axis(4+) button(1) +C Button U = axis(4-) +R Trig = button(5) axis(5+) +L Trig = button(4) +Mempak switch = button(9) +Rumblepak switch = button(10) +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[OSX: USB GamePad] +; this is a 2-port USB device. The Right port is controller #1, the Left port is #2 +; this is the "MayFlash" adapter, aka HuiJia. The OSX driver seems to have a +; different button mapping +plugged = True +mouse = False +AnalogDeadzone = 2500,2500 +AnalogPeak = 20000,20000 +DPad R = button(13) +DPad L = button(15) +DPad D = button(14) +DPad U = button(12) +Start = button(9) +Z Trig = button(8) +B Button = button(2) +A Button = button(1) +C Button R = axis(1-) +C Button L = axis(1+) +C Button D = axis(0+) +C Button U = axis(0-) +R Trig = button(7) +L Trig = button(6) +Mempak switch = key(109) +Rumblepak switch = key(114) +X Axis = axis(2-,2+) +Y Axis = axis(3-,3+) +__NextController: +plugged = True +mouse = False +AnalogDeadzone = 2500,2500 +AnalogPeak = 20000,20000 +DPad R = button(29) +DPad L = button(31) +DPad D = button(30) +DPad U = button(28) +Start = button(25) +Z Trig = button(24) +B Button = button(18) +A Button = button(17) +C Button R = axis(5-) +C Button L = axis(5+) +C Button D = axis(4+) +C Button U = axis(4-) +R Trig = button(23) +L Trig = button(22) +Mempak switch = key(109) +Rumblepak switch = key(114) +X Axis = axis(6-,6+) +Y Axis = axis(7-,7+) + +[Linux: HuiJia USB GamePad] +plugged = True +mouse = False +AnalogDeadzone = 100,100 +AnalogPeak = 20000,20000 +DPad R = button(13) +DPad L = button(15) +DPad D = button(14) +DPad U = button(12) +Start = button(8) +Z Trig = button(9) +B Button = button(2) +A Button = button(1) +C Button R = axis(3-) +C Button L = axis(3+) +C Button D = axis(2+) +C Button U = axis(2-) +R Trig = button(7) +L Trig = button(6) +Mempak switch = key(109) +Rumblepak switch = key(114) +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +; Mayflash N64 Controller Adapter (for PC USB) - With two N64 gamepads connected +; this is a 2-port USB device. The Right port is controller #1, the Left port is #2 +[Win32: USB GamePad] +plugged = True +mouse = False +AnalogDeadzone = 1024,1024 +AnalogPeak = 12288,12288 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(8) +Z Trig = button(9) +B Button = button(2) +A Button = button(1) +C Button R = axis(3-) +C Button L = axis(3+) +C Button D = axis(2+) +C Button U = axis(2-) +R Trig = button(7) +L Trig = button(6) +Mempak switch = key(109) +Rumblepak switch = key(114) +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +; MayFlash PC048 adapter +[PS/SS/N64 Joypad to USB BOX] +plugged = True +mouse = False +AnalogDeadzone = 1024,1024 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(8) +Z Trig = button(9) +B Button = button(2) +A Button = button(1) +C Button R = axis(2-) +C Button L = axis(2+) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(7) +L Trig = button(5) +Mempak switch = +Rumblepak switch = +Y Axis = axis(1-,1+) +X Axis = axis(0-,0+) + +; Asikgame - Super Dual Box (with two PS2 gamepads connected) +; this is a 2-port USB device. The Right port is controller #1, the Left port is #2 +[USB Human(2p) Interface Device] +plugged = True +mouse = False +DPad R= axis(2+) +DPad L= axis(2-) +DPad D= axis(5+) +DPad U= axis(5-) +Start= button(0) +Z Trig= button(1) +B Button= button(3) +A Button= button(2) +C Button R= hat(0 Right) +C Button L= hat(0 Left) +C Button D= hat(0 Down) +C Button U= hat(0 Up) +R Trig= button(5) +L Trig= button(4) +Mempak switch= button(9) +Rumblepak switch= button(8) +Y Axis= axis(1-,1+) +X Axis= axis(0-,0+) +__NextController: +plugged = True +mouse = False +DPad R= axis(6+) +DPad L= axis(6-) +DPad D= axis(7+) +DPad U= axis(7-) +Start= button(12) +Z Trig= button(13) +B Button= button(15) +A Button= button(14) +C Button R= hat(1 Right) +C Button L= hat(1 Left) +C Button D= hat(1 Down) +C Button U= hat(1 Up) +R Trig= button(17) +L Trig= button(16) +Mempak switch= button(21) +Rumblepak switch= button(20) +Y Axis= axis(4-,4+) +X Axis= axis(3-,3+) + +[Microsoft SideWinder Game Pad Pro USB version 1.0] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = key(275) +DPad L = key(276) +DPad D = key(274) +DPad U = key(273) +Start = button(8) +Z Trig = button(6) +B Button = button(0) +A Button = button(3) +C Button R = button(2) +C Button L = button(4) +C Button D = button(1) +C Button U = button(5) +R Trig = button(7) +L Trig = button(6) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[USB,2-axis 8-button gamepad] +[USB Gamepad ] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = axis(0+) +DPad L = axis(0-) +DPad D = axis(1+) +DPad U = axis(1-) +Start = button(7) +Z Trig = button(6) +B Button = button(1) +A Button = button(0) +C Button R = button(2) +C Button L = button(3) +C Button D = button(99) +C Button U = button(99) +R Trig = button(4) +L Trig = button(5) +Mempak switch = key(109) +Rumblepak switch = key(114) +Y Axis = axis(1-,1+) +X Axis = axis(0-,0+) + +; RetroUSB "USB N64 RetroPort" +[N64 ] +plugged = True +mouse = False +AnalogDeadzone = 2048,2048 +AnalogPeak = 18432,18432 +DPad R = button(0) +DPad L = button(1) +DPad D = button(2) +DPad U = button(3) +Start = button(4) +Z Trig = button(5) +B Button = button(6) +A Button = button(7) +C Button R = button(8) +C Button L = button(9) +C Button D = button(10) +C Button U = button(11) +R Trig = button(12) +L Trig = button(13) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[Jess Tech GGE909 PC Recoil Pad] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(9) +Z Trig = button(7) +B Button = button(0) +A Button = button(2) +C Button R = axis(3+) +C Button L = axis(3-) +C Button D = axis(2+) +C Button U = axis(2-) +R Trig = button(6) +L Trig = button(4) +Mempak switch = button(10) +Rumblepak switch = button(11) +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[8BITDO NES30] +plugged = True +mouse = False +DPad R = key(3) +DPad L = key(2) +DPad D = key(5) +DPad U = key(0) +Start = key(22) +Z Trig = key(21) +B Button = key(12) +A Button = key(11) +C Button R = key(3) +C Button L = key(2) +C Button D = key(5) +C Button U = key(0) +R Trig = key(99) +L Trig = key(120) +Mempak switch = key(44) +Rumblepak switch = key(46) +X Axis = key(276,275) +Y Axis = key(273,274) + +; Xiaomi Bluetooth Controller +[小米蓝牙手柄] +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = axis(8+) +DPad L = axis(8-) +DPad D = axis(9+) +DPad U = axis(9-) +Start = button(11) +Z Trig = button(6) +B Button = button(3) +A Button = button(0) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(5+) +C Button U = axis(5-) +R Trig = button(7) +L Trig = button(8) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/InputPlumber/default.ini b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/InputPlumber/default.ini new file mode 100644 index 0000000000..ee081da6c6 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/InputPlumber/default.ini @@ -0,0 +1,23 @@ +[Xbox Series X Controller] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(7) +Z Trig = axis(2+) +B Button = button(2) +A Button = button(0) +C Button R = axis(3+,24000) +C Button L = axis(3-,24000) button(3) +C Button D = axis(4+,24000) button(1) +C Button U = axis(4-,24000) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/InputPlumber/zlswap.ini b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/InputPlumber/zlswap.ini new file mode 100644 index 0000000000..2334eb3a4f --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/InputPlumber/zlswap.ini @@ -0,0 +1,23 @@ +[Xbox Series X Controller] +plugged = True +mouse = False +AnalogDeadzone = 4096,4096 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = hat(0 Down) +DPad U = hat(0 Up) +Start = button(7) +Z Trig = button(4) +B Button = button(2) +A Button = button(0) +C Button R = axis(3+,24000) +C Button L = axis(3-,24000) button(3) +C Button D = axis(4+,24000) button(1) +C Button U = axis(4-,24000) +R Trig = button(5) +L Trig = axis(2+) +Mempak switch = +Rumblepak switch = +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/RK3326/default.ini b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/RK3326/default.ini new file mode 100644 index 0000000000..b62b91ecef --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/RK3326/default.ini @@ -0,0 +1,225 @@ +; RK3326 Gamepad - default.ini +[OpenSimHardware OSH PB Controller] +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = "hat(0 Down) +DPad U = hat(0 Up) +Start = button(6) +Z Trig = button(9) +B Button = button(3) +A Button = button(1) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = axis(0+,0-) +Y Axis = axis(1+,1-) + +[odroidgo2_joypad] +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = button(9) +DPad L = button(8) +DPad D = button(7) +DPad U = button(6) +Start = button(13) +Z Trig = button(4) +B Button = button(3) +A Button = button(0) +C Button R = button(11) +C Button L = button(1) +C Button D = button(12) +C Button U = button(2) +R Trig = button(5) +L Trig = +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[odroidgo2_v11_joypad] +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = button(15) +DPad L = button(14) +DPad D = button(13) +DPad U = button(12) +Start = button(8) +Z Trig = button(4) +B Button = button(3) +A Button = button(0) +C Button R = button(9) +C Button L = button(11) +C Button D = button(1) +C Button U = button(2) +R Trig = button(5) +L Trig = button(6) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[retrogame_joypad_s1_f2] +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = button(16) +DPad L = button(15) +DPad D = button(14) +DPad U = button(13) +Start = button(9) +Z Trig = button(4) +B Button = button(3) +A Button = button(1) +C Button R = button(9) +C Button L = button(11) +C Button D = button(0) +C Button U = button(2) +R Trig = button(5) +L Trig = button(6) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[odroidgo3_joypad] +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = button(11) +DPad L = button(10) +DPad D = button(9) +DPad U = button(8) +Start = button(13) +Z Trig = button(4) +B Button = button(3) +A Button = button(0) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(5) +L Trig = button(6) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[r33s_joypad] +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = +DPad L = +DPad D = +DPad U = +Start = button(9) +Z Trig = button(4) +B Button = button(3) +A Button = button(0) +C Button R = button(7) +C Button L = button(6) +C Button D = button(1) +C Button U = button(2) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = button(12,13)axis(0-,0+) +Y Axis = button(10,11)axis(1-,1+) + +[r36s_Gamepad] +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = button(16) +DPad L = button(15) +DPad D = button(14) +DPad U = button(13) +Start = button(9) +Z Trig = button(6) +B Button = button(3) +A Button = button(0) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[XU10 Gamepad] +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768, 32768 +DPad R = button(15) +DPad L = button(14) +DPad D = button(13) +DPad U = button(12) +Start = button(9) +Z Trig = button(7) +B Button = button(0) +A Button = button(1) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +#Analog axis configuration mappings +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +[XU Mini M Gamepad] +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 28000, 28000 +DPad R = button(15) +DPad L = button(14) +DPad D = button(13) +DPad U = button(12) +Start = button(9) +Z Trig = button(4) +B Button = button(3) +A Button = button(0) +C Button R = axis(3+) +C Button L = axis(3-) +C Button D = axis(2-) +C Button U = axis(2+) +R Trig = button(5) +L Trig = button(6) +Mempak switch = +Rumblepak switch = +#Analog axis configuration mappings +X Axis = axis(1-,1+) +Y Axis = axis(0+,0-) diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/RK3326/zlswap.ini b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/RK3326/zlswap.ini new file mode 100644 index 0000000000..f6edd414f7 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/RK3326/zlswap.ini @@ -0,0 +1,25 @@ +; RG351P Gamepad - zlswap.ini +[OpenSimHardware OSH PB Controller] +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = hat(0 Right) +DPad L = hat(0 Left) +DPad D = "hat(0 Down) +DPad U = hat(0 Up) +Start = button(6) +Z Trig = button(4) +B Button = button(3) +A Button = button(1) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(5) +L Trig = button(9) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = axis(0+,0-) +Y Axis = axis(1+,1-) diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/RK3399/default.ini b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/RK3399/default.ini new file mode 100644 index 0000000000..c062c8c8c4 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/RK3399/default.ini @@ -0,0 +1,25 @@ +; RG552 Gamepad - default.ini +[rg552_joypad] +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = button(16) +DPad L = button(15) +DPad D = button(14) +DPad U = button(13) +Start = button(9) +Z Trig = button(6) +B Button = button(3) +A Button = button(0) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/RK3399/zlswap.ini b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/RK3399/zlswap.ini new file mode 100644 index 0000000000..6735db0daa --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/RK3399/zlswap.ini @@ -0,0 +1,25 @@ +; RG552 Gamepad - zlswap.ini +[rg552_joypad] +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = button(16) +DPad L = button(15) +DPad D = button(14) +DPad U = button(13) +Start = button(9) +Z Trig = button(4) +B Button = button(3) +A Button = button(0) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(5) +L Trig = button(6) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/RK3566/default.ini b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/RK3566/default.ini new file mode 100644 index 0000000000..97ef8f71a6 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/RK3566/default.ini @@ -0,0 +1,51 @@ +; RG552 Gamepad - default.ini +[retrogame_joypad] +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = button(16) +DPad L = button(15) +DPad D = button(14) +DPad U = button(13) +Start = button(9) +Z Trig = button(6) +B Button = button(3) +A Button = button(0) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) + +; RG ARC Gamepad - default.ini +[rg_arc_joypad] +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = +DPad L = +DPad D = +DPad U = +Start = button(11) +Z Trig = button(8) +B Button = button(3) +A Button = button(1) +C Button R = button(2) +C Button L = button(4) +C Button D = button(0) +C Button U = button(5) +R Trig = button(7) +L Trig = button(6) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = button(14,15) +Y Axis = button(12,13) diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/RK3566/zlswap.ini b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/RK3566/zlswap.ini new file mode 100644 index 0000000000..7606cad774 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/RK3566/zlswap.ini @@ -0,0 +1,25 @@ +; RG552 Gamepad - zlswap.ini +[retrogame_joypad] +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = button(16) +DPad L = button(15) +DPad D = button(14) +DPad U = button(13) +Start = button(9) +Z Trig = button(4) +B Button = button(3) +A Button = button(0) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(5) +L Trig = button(6) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/RK3588/default.ini b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/RK3588/default.ini new file mode 100644 index 0000000000..02591396c9 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/RK3588/default.ini @@ -0,0 +1,25 @@ +; GameForce ACE Gamepad - default.ini +[GameForce ACE Gamepad] +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = button(15) +DPad L = button(14) +DPad D = button(13) +DPad U = button(12) +Start = button(8) +Z Trig = axis(5-) +B Button = button(4) +A Button = button(0) +C Button R = axis(3+) +C Button L = axis(3-) +C Button D = axis(4+) +C Button U = axis(4-) +R Trig = button(6) +L Trig = button(5) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/RK3588/zlswap.ini b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/RK3588/zlswap.ini new file mode 100644 index 0000000000..869358f338 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/RK3588/zlswap.ini @@ -0,0 +1,25 @@ +; GameForce ACE Gamepad - default.ini +[GameForce ACE Gamepad] +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = button(15) +DPad L = button(14) +DPad D = button(13) +DPad U = button(12) +Start = button(8) +Z Trig = button(5) +B Button = button(4) +A Button = button(0) +C Button R = axis(3+) +C Button L = axis(3-) +C Button D = axis(4+) +C Button U = axis(4-) +R Trig = button(6) +L Trig = axis(2-) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/S922X/default.ini b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/S922X/default.ini new file mode 100644 index 0000000000..27ad6e29af --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/S922X/default.ini @@ -0,0 +1,21 @@ +[GO-Ultra Gamepad] +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = button(17) +DPad L = button(16) +DPad D = button(15) +DPad U = button(14) +Start = button(10) +Z Trig = button(5) button(8) +B Button = button(4) +A Button = button(0) +C Button R = axis(2+) +C Button L = axis(2-) button (2) +C Button D = axis(3+) button (1) +C Button U = axis(3-) +R Trig = button(6) +L Trig = button(7) +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/SDM845/default.ini b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/SDM845/default.ini new file mode 100644 index 0000000000..348e7a61f3 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/SDM845/default.ini @@ -0,0 +1,25 @@ +; AYN Odin Gamepad - default.ini +[AYN Odin Gamepad] +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = button(16) +DPad L = button(15) +DPad D = button(14) +DPad U = button(13) +Start = button(9) +Z Trig = axis(5+) +B Button = button(3) +A Button = button(0) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/SDM845/zlswap.ini b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/SDM845/zlswap.ini new file mode 100644 index 0000000000..348e7a61f3 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/SDM845/zlswap.ini @@ -0,0 +1,25 @@ +; AYN Odin Gamepad - default.ini +[AYN Odin Gamepad] +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = button(16) +DPad L = button(15) +DPad D = button(14) +DPad U = button(13) +Start = button(9) +Z Trig = axis(5+) +B Button = button(3) +A Button = button(0) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/SM8250/default.ini b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/SM8250/default.ini new file mode 100644 index 0000000000..351da05b4e --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/SM8250/default.ini @@ -0,0 +1,25 @@ +; Retroid Pocket Gamepad - default.ini +[Retroid Pocket Gamepad] +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = button(14) +DPad L = button(13) +DPad D = button(12) +DPad U = button(11) +Start = button(7) +Z Trig = axis(7+) +B Button = button(3) +A Button = button(0) +C Button R = axis(3+) +C Button L = axis(3-) +C Button D = axis(4+) +C Button U = axis(4-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/SM8250/zlswap.ini b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/SM8250/zlswap.ini new file mode 100644 index 0000000000..6735db0daa --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/SM8250/zlswap.ini @@ -0,0 +1,25 @@ +; RG552 Gamepad - zlswap.ini +[rg552_joypad] +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = button(16) +DPad L = button(15) +DPad D = button(14) +DPad U = button(13) +Start = button(9) +Z Trig = button(4) +B Button = button(3) +A Button = button(0) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(5) +L Trig = button(6) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/SM8550 b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/SM8550 new file mode 120000 index 0000000000..72081d3859 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/SM8550 @@ -0,0 +1 @@ +InputPlumber \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/SM8650 b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/SM8650 new file mode 120000 index 0000000000..72081d3859 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/SM8650 @@ -0,0 +1 @@ +InputPlumber \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/package.mk b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/package.mk new file mode 100644 index 0000000000..03f390b427 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/package.mk @@ -0,0 +1,77 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2019-present Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2023 Nicholas Ricciuti (rishooty@gmail.com) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="mupen64plus-sa-input-sdl" +PKG_VERSION="3698a2b12b1dc536801649de2705b4a79ffb8a08" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/mupen64plus/mupen64plus-input-sdl" +PKG_URL="https://github.com/mupen64plus/mupen64plus-input-sdl/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain libpng SDL2 SDL2_net zlib freetype nasm:host mupen64plus-sa-core" +PKG_LONGDESC="mupen64plus-input-sdl" +PKG_LONGDESC="Mupen64Plus Standalone Input SDL" +PKG_TOOLCHAIN="manual" + +case ${DEVICE} in + RK3588|S922X|RK3399|RK3566*|SM8250|SM8550|SM8650) + PKG_DEPENDS_TARGET+=" mupen64plus-sa-simplecore" + ;; +esac + +case ${DEVICE} in + *) + PKG_DEPENDS_TARGET+=" ${OPENGLES}" + export USE_GLES=1 + ;; +esac + +make_target() { + + export HOST_CPU=${TARGET_ARCH} \ + NEW_DYNAREC=1 \ + VFP_HARD=1 \ + V=1 \ + VC=0 \ + OSD=0 + + export BINUTILS="$(get_build_dir binutils)/.${TARGET_NAME}" + export SDL_CFLAGS="-I${SYSROOT_PREFIX}/usr/include/SDL2 -pthread -D_REENTRANT" + export SDL_LDLIBS="-lSDL2_net -lSDL2" + export CROSS_COMPILE="${TARGET_PREFIX}" + + export APIDIR=$(get_build_dir mupen64plus-sa-core)/src/api + + sed -i 's/\-O[23]/-Ofast/' ${PKG_BUILD}/projects/unix/Makefile + + make -C projects/unix clean + make -C projects/unix all ${PKG_MAKE_OPTS_TARGET} + cp ${PKG_BUILD}/projects/unix/mupen64plus-input-sdl.so ${PKG_BUILD}/projects/unix/mupen64plus-input-sdl-base.so + + case ${DEVICE} in + RK3588|S922X|RK3399|RK3566*|SM8250|SM8550|SM8650) + export APIDIR=$(get_build_dir mupen64plus-sa-simplecore)/src/api + make -C projects/unix all ${PKG_MAKE_OPTS_TARGET} + cp ${PKG_BUILD}/projects/unix/mupen64plus-input-sdl.so ${PKG_BUILD}/projects/unix/mupen64plus-input-sdl-simple.so + ;; + esac +} + +makeinstall_target() { + UPREFIX=${INSTALL}/usr/local + ULIBDIR=${UPREFIX}/lib + USHAREDIR=${UPREFIX}/share/mupen64plus + UPLUGINDIR=${ULIBDIR}/mupen64plus + mkdir -p ${UPLUGINDIR} + cp ${PKG_BUILD}/projects/unix/mupen64plus-input-sdl-base.so ${UPLUGINDIR}/mupen64plus-input-sdl.so + chmod 0644 ${UPLUGINDIR}/mupen64plus-input-sdl.so + + if [ -e "${PKG_BUILD}/projects/unix/mupen64plus-input-sdl-simple.so" ] + then + cp ${PKG_BUILD}/projects/unix/mupen64plus-input-sdl-simple.so ${UPLUGINDIR} + chmod 0644 ${UPLUGINDIR}/mupen64plus-input-sdl-simple.so + fi + + mkdir -p ${USHAREDIR} + cp ${PKG_DIR}/config/${DEVICE}/* ${USHAREDIR} +} diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-rsp-cxd4/package.mk b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-rsp-cxd4/package.mk new file mode 100644 index 0000000000..6c15eb0186 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-rsp-cxd4/package.mk @@ -0,0 +1,86 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2019-present Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2023 Nicholas Ricciuti (rishooty@gmail.com) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="mupen64plus-sa-rsp-cxd4" +PKG_VERSION="f6ff3719cb68d3e1c1497fc87a661921671db719" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/mupen64plus/mupen64plus-rsp-cxd4" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain libpng SDL2 SDL2_net zlib freetype nasm:host mupen64plus-sa-core" +PKG_LONGDESC="mupen64plus-rsp-cxd4" +PKG_LONGDESC="Mupen64Plus Standalone RSP CXD4" +PKG_TOOLCHAIN="manual" +PKG_BUILD_FLAGS="-fpic" + +case ${DEVICE} in + RK3588|S922X|RK3399|RK3566*|SM8250|SM8550|SM8650) + PKG_DEPENDS_TARGET+=" mupen64plus-sa-simplecore" + ;; +esac + +case ${DEVICE} in + SM8250|SM8550|SM8650) + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" + export USE_GLES=0 + ;; + *) + PKG_DEPENDS_TARGET+=" ${OPENGLES}" + export USE_GLES=1 + ;; +esac + +make_target() { + + export HOST_CPU=${TARGET_ARCH} \ + NEW_DYNAREC=1 \ + VFP_HARD=1 \ + HLEVIDEO=1 \ + V=1 \ + VC=0 \ + OSD=0 + + case ${TARGET_ARCH} in + x86_64) + export SUFFIX="-sse2" + ;; + esac + + export BINUTILS="$(get_build_dir binutils)/.${TARGET_NAME}" + export APIDIR=$(get_build_dir mupen64plus-sa-core)/src/api + export SDL_CFLAGS="-I${SYSROOT_PREFIX}/usr/include/SDL2 -pthread -D_REENTRANT" + export SDL_LDLIBS="-lSDL2_net -lSDL2" + export CROSS_COMPILE="${TARGET_PREFIX}" + + sed -i 's/\-O[23]/-Ofast/' ${PKG_BUILD}/projects/unix/Makefile + + make -C projects/unix clean + make -C projects/unix all ${PKG_MAKE_OPTS_TARGET} + cp ${PKG_BUILD}/projects/unix/mupen64plus-rsp-cxd4${SUFFIX}.so ${PKG_BUILD}/projects/unix/mupen64plus-rsp-cxd4-base.so + + case ${DEVICE} in + RK3588|S922X|RK3399|RK3566*|SM8250|SM8550|SM8650) + PKG_MAKE_OPTS_TARGET+=" cxd4VIDEO=1" + export APIDIR=$(get_build_dir mupen64plus-sa-simplecore)/src/api + make -C projects/unix all ${PKG_MAKE_OPTS_TARGET} + cp ${PKG_BUILD}/projects/unix/mupen64plus-rsp-cxd4${SUFFIX}.so ${PKG_BUILD}/projects/unix/mupen64plus-rsp-cxd4-simple.so + ;; + esac +} + +makeinstall_target() { + UPREFIX=${INSTALL}/usr/local + ULIBDIR=${UPREFIX}/lib + UPLUGINDIR=${ULIBDIR}/mupen64plus + mkdir -p ${UPLUGINDIR} + cp ${PKG_BUILD}/projects/unix/mupen64plus-rsp-cxd4-base.so ${UPLUGINDIR}/mupen64plus-rsp-cxd4.so + chmod 0644 ${UPLUGINDIR}/mupen64plus-rsp-cxd4.so + + if [ -e "${PKG_BUILD}/projects/unix/mupen64plus-rsp-cxd4-simple.so" ] + then + cp ${PKG_BUILD}/projects/unix/mupen64plus-rsp-cxd4-simple.so ${UPLUGINDIR} + chmod 0644 ${UPLUGINDIR}/mupen64plus-rsp-cxd4-simple.so + fi +} + diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-rsp-hle/package.mk b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-rsp-hle/package.mk new file mode 100644 index 0000000000..30791062a2 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-rsp-hle/package.mk @@ -0,0 +1,73 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2019-present Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2023 Nicholas Ricciuti (rishooty@gmail.com) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="mupen64plus-sa-rsp-hle" +PKG_VERSION="9d13986f764b14bb4fb8eaa5846ff8be5a9fa4f6" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/mupen64plus/mupen64plus-rsp-hle" +PKG_URL="https://github.com/mupen64plus/mupen64plus-rsp-hle/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain libpng SDL2 SDL2_net zlib freetype nasm:host mupen64plus-sa-core" +PKG_LONGDESC="mupen64plus-rsp-hle" +PKG_LONGDESC="Mupen64Plus Standalone RSP HLE" +PKG_TOOLCHAIN="manual" + +case ${DEVICE} in + RK3588|S922X|RK3399|RK3566*) + PKG_DEPENDS_TARGET+=" mupen64plus-sa-simplecore" + ;; +esac + +case ${DEVICE} in + *) + PKG_DEPENDS_TARGET+=" ${OPENGLES}" + export USE_GLES=1 + ;; +esac + +make_target() { + + export HOST_CPU=${TARGET_ARCH} \ + NEW_DYNAREC=1 \ + VFP_HARD=1 \ + V=1 \ + VC=0 \ + OSD=0 + + export BINUTILS="$(get_build_dir binutils)/.${TARGET_NAME}" + export APIDIR=$(get_build_dir mupen64plus-sa-core)/src/api + export SDL_CFLAGS="-I${SYSROOT_PREFIX}/usr/include/SDL2 -pthread -D_REENTRANT" + export SDL_LDLIBS="-lSDL2_net -lSDL2" + export CROSS_COMPILE="${TARGET_PREFIX}" + + sed -i 's/\-O[23]/-Ofast/' ${PKG_BUILD}/projects/unix/Makefile + + make -C projects/unix clean + make -C projects/unix all ${PKG_MAKE_OPTS_TARGET} + cp ${PKG_BUILD}/projects/unix/mupen64plus-rsp-hle.so ${PKG_BUILD}/projects/unix/mupen64plus-rsp-hle-base.so + + case ${DEVICE} in + RK3588|S922X|RK3399|RK3566*) + export APIDIR=$(get_build_dir mupen64plus-sa-simplecore)/src/api + make -C projects/unix all ${PKG_MAKE_OPTS_TARGET} + cp ${PKG_BUILD}/projects/unix/mupen64plus-rsp-hle.so ${PKG_BUILD}/projects/unix/mupen64plus-rsp-hle-simple.so + ;; + esac +} + +makeinstall_target() { + UPREFIX=${INSTALL}/usr/local + ULIBDIR=${UPREFIX}/lib + UPLUGINDIR=${ULIBDIR}/mupen64plus + mkdir -p ${UPLUGINDIR} + cp ${PKG_BUILD}/projects/unix/mupen64plus-rsp-hle-base.so ${UPLUGINDIR}/mupen64plus-rsp-hle.so + chmod 0644 ${UPLUGINDIR}/mupen64plus-rsp-hle.so + + if [ -e "${PKG_BUILD}/projects/unix/mupen64plus-rsp-hle-simple.so" ] + then + cp ${PKG_BUILD}/projects/unix/mupen64plus-rsp-hle-simple.so ${UPLUGINDIR} + chmod 0644 ${UPLUGINDIR}/mupen64plus-rsp-hle-simple.so + fi +} + diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-simplecore/package.mk b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-simplecore/package.mk new file mode 100644 index 0000000000..546e11102e --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-simplecore/package.mk @@ -0,0 +1,61 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2019-present Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2023 Nicholas Ricciuti (rishooty@gmail.com) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="mupen64plus-sa-simplecore" +PKG_VERSION="5340dafcc0f5e8284057ab931dd5c66222d3d49e" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/simple64/mupen64plus-core" +PKG_URL="https://github.com/simple64/mupen64plus-core/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain boost libpng SDL2 SDL2_net zlib freetype nasm:host mupen64plus-sa-core" +PKG_LONGDESC="simple64" +PKG_LONGDESC="Simple64's core" +PKG_TOOLCHAIN="manual" +PKG_GIT_CLONE_BRANCH="simple64" + +case ${DEVICE} in + SM8250|SM8550|SM8650) + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" + export USE_GLES=0 + ;; + *) + PKG_DEPENDS_TARGET+=" ${OPENGLES}" + export USE_GLES=1 + ;; +esac + +make_target() { +# export TARGET_CLFAGS="${TARGET_CFLAGS} -Wno-implicit-function-declaration -Wno-error=incompatible-pointer-types" +# export TARGET_CXXLFAGS="${TARGET_CXXFLAGS} -Wno-implicit-function-declaration -Wno-error=incompatible-pointer-types" + case ${ARCH} in + arm|aarch64) + export HOST_CPU=aarch64 + ARM="-DARM=1" + ;; + x86_64) + export HOST_CPU=x86_64 + unset ARM + ;; + esac + + # Always diable Vulkan + PKG_MAKE_OPTS_TARGET+=" VULKAN=0" + + export BINUTILS="$(get_build_dir binutils)/.${TARGET_NAME}" + export NEW_DYNAREC=1 + export SDL_CFLAGS="-I${SYSROOT_PREFIX}/usr/include/SDL2 -pthread -D_REENTRANT" + export SDL_LDLIBS="-lSDL2_net -lSDL2" + export CROSS_COMPILE="${TARGET_PREFIX}" + + sed -i 's/\-O[23]/-Ofast/' ${PKG_BUILD}/projects/unix/Makefile + + make -C projects/unix clean ${PKG_MAKE_OPTS_TARGET} + make -C projects/unix all ${PKG_MAKE_OPTS_TARGET} +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/local/lib + cp ${PKG_BUILD}/projects/unix/libsimple64.so.2.0.0 ${INSTALL}/usr/local/lib/libsimple64.so.2 + chmod 644 ${INSTALL}/usr/local/lib/libsimple64.so.2 +} diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-simplecore/patches/000-cross-compile.patch b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-simplecore/patches/000-cross-compile.patch new file mode 100644 index 0000000000..b10ab24c59 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-simplecore/patches/000-cross-compile.patch @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2018-present Frank Hartung (supervisedthinking (@) gmail.com) + +--- a/projects/unix/Makefile ++++ b/projects/unix/Makefile +@@ -320,7 +320,7 @@ + + # test for presence of SDL + ifeq ($(origin SDL_CFLAGS) $(origin SDL_LDLIBS), undefined undefined) +- SDL_CONFIG = $(CROSS_COMPILE)sdl2-config ++ SDL_CONFIG = $(SYSROOT_PREFIX)/usr/bin/sdl2-config + ifeq ($(shell which $(SDL_CONFIG) 2>/dev/null),) + SDL_CONFIG = $(CROSS_COMPILE)sdl-config + ifeq ($(shell which $(SDL_CONFIG) 2>/dev/null),) +@@ -403,9 +403,6 @@ + endif + + # set base program pointers and flags +-CC = $(CROSS_COMPILE)gcc +-CXX = $(CROSS_COMPILE)g++ +-STRINGS = $(CROSS_COMPILE)strings + AS = nasm + TR ?= tr + RM ?= rm -f diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-simplecore/patches/001-librename.patch b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-simplecore/patches/001-librename.patch new file mode 100644 index 0000000000..5d8947b772 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-simplecore/patches/001-librename.patch @@ -0,0 +1,15 @@ +diff --git a/projects/unix/Makefile b/projects/unix/Makefile +index 2222fe78..0fec2cbe 100755 +--- a/projects/unix/Makefile ++++ b/projects/unix/Makefile +@@ -209,8 +209,8 @@ ifeq ($(OS), FREEBSD) + endif + endif + ifeq ($(OS), LINUX) +- TARGET = libmupen64plus$(POSTFIX).so.2.0.0 +- SONAME = libmupen64plus$(POSTFIX).so.2 ++ TARGET = libsimple64$(POSTFIX).so.2.0.0 ++ SONAME = libsimple64$(POSTFIX).so.2 + LDFLAGS += -Wl,-Bsymbolic -shared -Wl,-export-dynamic -Wl,-soname,$(SONAME) + LDLIBS += -ldl + # only export api symbols diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-ui-console/package.mk b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-ui-console/package.mk new file mode 100644 index 0000000000..44a33b47d7 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-ui-console/package.mk @@ -0,0 +1,91 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2019-present Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2023 Nicholas Ricciuti (rishooty@gmail.com) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="mupen64plus-sa-ui-console" +PKG_VERSION="1340c4bdfc9ec53d3fccda5e085930dd79eb08b3" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/mupen64plus/mupen64plus-ui-console" +PKG_URL="https://github.com/mupen64plus/mupen64plus-ui-console/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain libpng SDL2 SDL2_net zlib freetype nasm:host mupen64plus-sa-core" +PKG_LONGDESC="mupen64plus-ui-console" +PKG_LONGDESC="Mupen64Plus Standalone Console" +PKG_TOOLCHAIN="manual" + +case ${DEVICE} in + RK3588|S922X|RK3399|RK3566*|SM8250|SM8550|SM8650) + PKG_DEPENDS_TARGET+=" mupen64plus-sa-simplecore" + ;; +esac + +case ${DEVICE} in + SM8250|SM8550|SM8650) + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" + export USE_GLES=0 + ;; + *) + PKG_DEPENDS_TARGET+=" ${OPENGLES}" + export USE_GLES=1 + ;; +esac + +make_target() { + export CFLAGS="${CFLAGS} -Wno-error=incompatible-pointer-types" + + export V=1 \ + VC=0 + + export BINUTILS="$(get_build_dir binutils)/.${TARGET_NAME}" + export APIDIR=$(get_build_dir mupen64plus-sa-core)/src/api + export SDL_CFLAGS="-I${SYSROOT_PREFIX}/usr/include/SDL2 -pthread -D_REENTRANT" + export SDL_LDLIBS="-lSDL2_net -lSDL2" + export CROSS_COMPILE="${TARGET_PREFIX}" + + sed -i 's/\-O[23]/-Ofast/' ${PKG_BUILD}/projects/unix/Makefile + + make -C projects/unix clean + make -C projects/unix all ${PKG_MAKE_OPTS_TARGET} + cp ${PKG_BUILD}/projects/unix/mupen64plus ${PKG_BUILD}/projects/unix/mupen64plus-base + + case ${DEVICE} in + RK3588|S922X|RK3399|RK3566*|SM8250|SM8550|SM8650) + export APIDIR=$(get_build_dir mupen64plus-sa-simplecore)/src/api + export CFLAGS="${CFLAGS} -DSIMPLECORE" + make -C projects/unix all ${PKG_MAKE_OPTS_TARGET} + cp ${PKG_BUILD}/projects/unix/mupen64plus ${PKG_BUILD}/projects/unix/mupen64plus-simple + ;; + esac +} + +makeinstall_target() { + UPREFIX=${INSTALL}/usr/local + ULIBDIR=${UPREFIX}/lib + UBINDIR=${UPREFIX}/bin + UMANDIR=${UPREFIX}/share/man + UAPPSDIR=${UPREFIX}/share/applications + UICONSDIR=${UPREFIX}/share/icons/hicolor + mkdir -p ${UBINDIR} + cp ${PKG_BUILD}/projects/unix/mupen64plus-base ${UBINDIR}/mupen64plus + chmod 0755 ${UBINDIR}/mupen64plus + + if [ -e "${PKG_BUILD}/projects/unix/mupen64plus-simple" ] + then + cp ${PKG_BUILD}/projects/unix/mupen64plus-simple ${UBINDIR} + chmod 0755 ${UBINDIR}/mupen64plus-simple + fi + + mkdir -p ${UMANDIR}/man6 + cp ${PKG_BUILD}/doc/mupen64plus.6 ${UMANDIR}/man6 + chmod 0644 ${UMANDIR}/man6/mupen64plus.6 + mkdir -p ${UAPPSDIR} + cp ${PKG_BUILD}/data/mupen64plus.desktop ${UAPPSDIR} + chmod 0644 ${UAPPSDIR}/mupen64plus.desktop + mkdir -p ${UICONSDIR}/48x48/apps + cp ${PKG_BUILD}/data/icons/48x48/apps/mupen64plus.png ${UICONSDIR}/48x48/apps + chmod 0644 ${UICONSDIR}/48x48/apps/mupen64plus.png + mkdir -p ${UICONSDIR}/scalable/apps + cp ${PKG_BUILD}/data/icons/scalable/apps/mupen64plus.svg ${UICONSDIR}/scalable/apps + chmod 0644 ${UICONSDIR}/scalable/apps/mupen64plus.svg +} + diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-video-glide64mk2/package.mk b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-video-glide64mk2/package.mk new file mode 100644 index 0000000000..093fc8c9d2 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-video-glide64mk2/package.mk @@ -0,0 +1,82 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2019-present Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2023 Nicholas Ricciuti (rishooty@gmail.com) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="mupen64plus-sa-video-glide64mk2" +PKG_VERSION="992b5942078fe77987e8c40bcd396f44be19be2b" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/mupen64plus/mupen64plus-video-glide64mk2" +PKG_URL="https://github.com/mupen64plus/mupen64plus-video-glide64mk2/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain boost libpng SDL2 SDL2_net zlib freetype nasm:host mupen64plus-sa-core" +PKG_LONGDESC="mupen64plus-video-glide64mk2" +PKG_LONGDESC="Mupen64Plus Standalone Glide64 Video Driver" +PKG_TOOLCHAIN="manual" + +case ${DEVICE} in + RK3588|S922X|RK3399|RK3566*|SM8250|SM8550|SM8650) + PKG_DEPENDS_TARGET+=" mupen64plus-sa-simplecore" + ;; +esac + +case ${DEVICE} in + SM8250|SM8550|SM8650) + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" + export USE_GLES=0 + ;; + *) + PKG_DEPENDS_TARGET+=" ${OPENGLES}" + export USE_GLES=1 + ;; +esac + +make_target() { + + export HOST_CPU=${TARGET_ARCH} \ + NEW_DYNAREC=1 \ + VFP_HARD=1 \ + V=1 \ + VC=0 \ + OSD=0 + + export BINUTILS="$(get_build_dir binutils)/.${TARGET_NAME}" + export APIDIR=$(get_build_dir mupen64plus-sa-core)/src/api + export SDL_CFLAGS="-I${SYSROOT_PREFIX}/usr/include/SDL2 -pthread -D_REENTRANT" + export SDL_LDLIBS="-lSDL2_net -lSDL2" + export CROSS_COMPILE="${TARGET_PREFIX}" + + sed -i 's/\-O[23]/-Ofast/' ${PKG_BUILD}/projects/unix/Makefile + + make -C projects/unix clean + make -C projects/unix all ${PKG_MAKE_OPTS_TARGET} + cp ${PKG_BUILD}/projects/unix/mupen64plus-video-glide64mk2.so ${PKG_BUILD}/projects/unix/mupen64plus-video-glide64mk2-base.so + + case ${DEVICE} in + RK3588|S922X|RK3399|RK3566*|SM8250|SM8550|SM8650) + export APIDIR=$(get_build_dir mupen64plus-sa-simplecore)/src/api + make -C projects/unix all ${PKG_MAKE_OPTS_TARGET} + cp ${PKG_BUILD}/projects/unix/mupen64plus-video-glide64mk2.so ${PKG_BUILD}/projects/unix/mupen64plus-video-glide64mk2-simple.so + ;; + esac +} + +makeinstall_target() { + UPREFIX=${INSTALL}/usr/local + ULIBDIR=${UPREFIX}/lib + USHAREDIR=${UPREFIX}/share/mupen64plus + UPLUGINDIR=${ULIBDIR}/mupen64plus + mkdir -p ${UPLUGINDIR} + cp ${PKG_BUILD}/projects/unix/mupen64plus-video-glide64mk2-base.so ${UPLUGINDIR}/mupen64plus-video-glide64mk2.so + chmod 0644 ${UPLUGINDIR}/mupen64plus-video-glide64mk2.so + + if [ -e "${PKG_BUILD}/projects/unix/mupen64plus-video-glide64mk2-simple.so" ] + then + cp ${PKG_BUILD}/projects/unix/mupen64plus-video-glide64mk2-simple.so ${UPLUGINDIR} + chmod 0644 ${UPLUGINDIR}/mupen64plus-video-glide64mk2-simple.so + fi + + mkdir -p ${USHAREDIR} + cp ${PKG_BUILD}/data/Glide64mk2.ini ${USHAREDIR} + chmod 0644 ${USHAREDIR}/Glide64mk2.ini +} + diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-video-gliden64/package.mk b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-video-gliden64/package.mk new file mode 100644 index 0000000000..c93c8b8672 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-video-gliden64/package.mk @@ -0,0 +1,83 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2019-present Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2023 Nicholas Ricciuti (rishooty@gmail.com) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="mupen64plus-sa-video-gliden64" +PKG_VERSION="85bdd452d7090f78a0f76d02121fa59ad079b7f6" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/gonetz/GLideN64" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain boost libpng SDL2 SDL2_net zlib freetype nasm:host mupen64plus-sa-core" +PKG_LONGDESC="mupen64plus-video-gliden64" +PKG_LONGDESC="Mupen64Plus Standalone GLide64 Video Driver" +PKG_TOOLCHAIN="manual" + +case ${DEVICE} in + RK3588|S922X|RK3399|RK3566*|SM8250|SM8550|SM8650) + PKG_DEPENDS_TARGET+=" mupen64plus-sa-simplecore" + ;; +esac + +case ${DEVICE} in + SM8250|SM8550|SM8650) + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" + export USE_GLES=0 + ;; + *) + PKG_DEPENDS_TARGET+=" ${OPENGLES}" + export USE_GLES=1 + ;; +esac + +make_target() { + + export HOST_CPU=${TARGET_ARCH} \ + NEW_DYNAREC=1 \ + VFP_HARD=1 \ + V=1 \ + VC=0 \ + OSD=0 + + case ${TARGET_ARCH} in + arm|aarch64) + PKG_MAKE_OPTS_TARGET+="-DNOHQ=On -DCRC_ARMV8=On -DEGL=On -DNEON_OPT=On" + ;; + esac + + export BINUTILS="$(get_build_dir binutils)/.${TARGET_NAME}" + export APIDIR=$(get_build_dir mupen64plus-sa-core)/src/api + export SDL_CFLAGS="-I${SYSROOT_PREFIX}/usr/include/SDL2 -pthread -D_REENTRANT" + export SDL_LDLIBS="-lSDL2_net -lSDL2" + export CROSS_COMPILE="${TARGET_PREFIX}" + + sed -i 's/\-O[23]/-Ofast/' ${PKG_BUILD}/src/CMakeLists.txt + + ./src/getRevision.sh + cmake ${PKG_MAKE_OPTS_TARGET} -DAPIDIR=${APIDIR} -DMUPENPLUSAPI=On -DGLIDEN64_BUILD_TYPE=Release -DCMAKE_C_COMPILER="${CC}" -DCMAKE_CXX_COMPILER="${CXX}" -DCMAKE_C_FLAGS="${CFLAGS}" -DCMAKE_CXX_FLAGS="${CXXFLAGS} -pthread" -S src -B projects/cmake + make clean -C projects/cmake + make -Wno-unused-variable -C projects/cmake + cp ${PKG_BUILD}/projects/cmake/plugin/Release/mupen64plus-video-GLideN64.so ${PKG_BUILD}/projects/cmake/plugin/Release/mupen64plus-video-GLideN64-base.so + + export APIDIR=$(get_build_dir mupen64plus-sa-simplecore)/src/api + cmake ${PKG_MAKE_OPTS_TARGET} -DAPIDIR=${APIDIR} -DMUPENPLUSAPI=On -DGLIDEN64_BUILD_TYPE=Release -DCMAKE_C_COMPILER="${CC}" -DCMAKE_CXX_COMPILER="${CXX}" -DCMAKE_C_FLAGS="${CFLAGS}" -DCMAKE_CXX_FLAGS="${CXXFLAGS} -pthread" -S src -B projects/cmake + make -Wno-unused-variable -C projects/cmake + cp ${PKG_BUILD}/projects/cmake/plugin/Release/mupen64plus-video-GLideN64.so ${PKG_BUILD}/projects/cmake/plugin/Release/mupen64plus-video-GLideN64-simple.so +} + +makeinstall_target() { + UPREFIX=${INSTALL}/usr/local + ULIBDIR=${UPREFIX}/lib + USHAREDIR=${UPREFIX}/share/mupen64plus + UPLUGINDIR=${ULIBDIR}/mupen64plus + mkdir -p ${UPLUGINDIR} + cp ${PKG_BUILD}/projects/cmake/plugin/Release/mupen64plus-video-GLideN64-base.so ${UPLUGINDIR}/mupen64plus-video-GLideN64.so + chmod 0644 ${UPLUGINDIR}/mupen64plus-video-GLideN64.so + + cp ${PKG_BUILD}/projects/cmake/plugin/Release/mupen64plus-video-GLideN64-simple.so ${UPLUGINDIR} + chmod 0644 ${UPLUGINDIR}/mupen64plus-video-GLideN64-simple.so + + mkdir -p ${USHAREDIR} + cp ${PKG_BUILD}/ini/GLideN64.ini ${USHAREDIR} + chmod 0644 ${USHAREDIR}/GLideN64.ini +} diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-video-gliden64/patches/001-txfilter-stub-fix.patch b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-video-gliden64/patches/001-txfilter-stub-fix.patch new file mode 100644 index 0000000000..513e8201bb --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-video-gliden64/patches/001-txfilter-stub-fix.patch @@ -0,0 +1,30 @@ +diff --git a/src/TxFilterStub.cpp b/src/TxFilterStub.cpp +index fea57bc..fa33356 100644 +--- a/src/TxFilterStub.cpp ++++ b/src/TxFilterStub.cpp +@@ -31,12 +31,25 @@ txfilter_checksum(uint8 *src, int width, int height, int size, int rowStride, ui + return 0U; + } + ++ ++TAPI uint64 TAPIENTRY ++txfilter_checksum_strong(uint8 *src, int width, int height, int size, int rowStride, uint8 *palette) ++{ ++ return 0; ++} ++ + TAPI boolean TAPIENTRY + txfilter_dmptx(uint8 *src, int width, int height, int rowStridePixel, uint16 gfmt, N64FormatSize n64FmtSz, Checksum r_crc64) + { + return 0; + } + ++TAPI boolean TAPIENTRY ++txfilter_dmptx_strong(uint8 *src, int width, int height, int rowStridePixel, uint16 gfmt, N64FormatSize n64FmtSz, Checksum r_crc64) ++{ ++ return 0; ++} ++ + TAPI boolean TAPIENTRY + txfilter_reloadhirestex() + { diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-video-gliden64/patches/002-fix-no-video.patch b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-video-gliden64/patches/002-fix-no-video.patch new file mode 100644 index 0000000000..5b410a6317 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-video-gliden64/patches/002-fix-no-video.patch @@ -0,0 +1,41 @@ +diff --git a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilderCommon.cpp b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilderCommon.cpp +index 901d17ab..5ef84042 100644 +--- a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilderCommon.cpp ++++ b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilderCommon.cpp +@@ -1004,11 +1004,11 @@ public: + ShaderNoise(const opengl::GLInfo & _glinfo) + { + m_part = +- "uniform float uNoiseSeed; \n" ++ "uniform mediump float uNoiseSeed; \n" + "lowp float snoise() \n" + "{ \n" +- " mediump vec2 coord = floor(gl_FragCoord.xy/uScreenScale); \n" +- " mediump vec3 p3 = vec3(uNoiseSeed, coord); \n" ++ " highp vec2 coord = floor(gl_FragCoord.xy/uScreenScale); \n" ++ " highp vec3 p3 = vec3(uNoiseSeed, coord); \n" + // hash13 from https://www.shadertoy.com/view/4djSRW + " p3 = fract(p3 * .1031); \n" + " p3 += dot(p3, p3.zyx + 31.32); \n" +@@ -1068,8 +1068,8 @@ public: + m_part += + " lowp float mult = 1.0; \n"; + m_part += +- " mediump vec2 coord = floor(mult * (gl_FragCoord.xy/uScreenScale)); \n" +- " mediump vec3 p3 = vec3(uNoiseSeed, coord); \n" ++ " highp vec2 coord = floor(mult * (gl_FragCoord.xy/uScreenScale)); \n" ++ " highp vec3 p3 = vec3(uNoiseSeed, coord); \n" + // hash33 from https://www.shadertoy.com/view/4djSRW + " p3 = fract(p3 * vec3(.1031, .1030, .0973)); \n" + " p3 += dot(p3, p3.yxz+33.33); \n" +@@ -1087,8 +1087,8 @@ public: + " lowp float mult = 1.0; \n"; + m_part += + " \n" +- " mediump vec2 coord = floor(mult * (gl_FragCoord.xy/uScreenScale)); \n" +- " mediump vec3 p3 = vec3(uNoiseSeed, coord); \n" ++ " highp vec2 coord = floor(mult * (gl_FragCoord.xy/uScreenScale)); \n" ++ " highp vec3 p3 = vec3(uNoiseSeed, coord); \n" + // hash13 from https://www.shadertoy.com/view/4djSRW + " p3 = fract(p3 * .1031); \n" + " p3 += dot(p3, p3.zyx + 31.32); \n" diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-video-rice/package.mk b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-video-rice/package.mk new file mode 100644 index 0000000000..c2bb165f3d --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-video-rice/package.mk @@ -0,0 +1,82 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2019-present Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2023 Nicholas Ricciuti (rishooty@gmail.com) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="mupen64plus-sa-video-rice" +PKG_VERSION="470865c6c64bdb44645faa88eae59cd87ce561b6" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/mupen64plus/mupen64plus-video-rice" +PKG_URL="https://github.com/mupen64plus/mupen64plus-video-rice/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain libpng SDL2 SDL2_net zlib freetype nasm:host mupen64plus-sa-core" +PKG_LONGDESC="mupen64plus-video-rice" +PKG_LONGDESC="Mupen64Plus Standalone Rice Video Driver" +PKG_TOOLCHAIN="manual" + +case ${DEVICE} in + RK3588|S922X|RK3399|RK3566*|SM8250|SM8550|SM8650) + PKG_DEPENDS_TARGET+=" mupen64plus-sa-simplecore" + ;; +esac + +case ${DEVICE} in + SM8250|SM8550|SM8650) + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" + export USE_GLES=0 + ;; + *) + PKG_DEPENDS_TARGET+=" ${OPENGLES}" + export USE_GLES=1 + ;; +esac + +make_target() { + + export HOST_CPU=${TARGET_ARCH} \ + NEW_DYNAREC=1 \ + VFP_HARD=1 \ + V=1 \ + VC=0 \ + OSD=0 + + export BINUTILS="$(get_build_dir binutils)/.${TARGET_NAME}" + export APIDIR=$(get_build_dir mupen64plus-sa-core)/src/api + export SDL_CFLAGS="-I${SYSROOT_PREFIX}/usr/include/SDL2 -pthread -D_REENTRANT" + export SDL_LDLIBS="-lSDL2_net -lSDL2" + export CROSS_COMPILE="${TARGET_PREFIX}" + + sed -i 's/\-O[23]/-Ofast/' ${PKG_BUILD}/projects/unix/Makefile + + make -C projects/unix clean + make -C projects/unix all ${PKG_MAKE_OPTS_TARGET} + cp ${PKG_BUILD}/projects/unix/mupen64plus-video-rice.so ${PKG_BUILD}/projects/unix/mupen64plus-video-rice-base.so + + case ${DEVICE} in + RK3588|S922X|RK3399|RK3566*|SM8250|SM8550|SM8650) + export APIDIR=$(get_build_dir mupen64plus-sa-simplecore)/src/api + make -C projects/unix all ${PKG_MAKE_OPTS_TARGET} + cp ${PKG_BUILD}/projects/unix/mupen64plus-video-rice.so ${PKG_BUILD}/projects/unix/mupen64plus-video-rice-simple.so + ;; + esac +} + +makeinstall_target() { + UPREFIX=${INSTALL}/usr/local + ULIBDIR=${UPREFIX}/lib + USHAREDIR=${UPREFIX}/share/mupen64plus + UPLUGINDIR=${ULIBDIR}/mupen64plus + mkdir -p ${UPLUGINDIR} + cp ${PKG_BUILD}/projects/unix/mupen64plus-video-rice-base.so ${UPLUGINDIR}/mupen64plus-video-rice.so + chmod 0644 ${UPLUGINDIR}/mupen64plus-video-rice.so + + if [ -e "${PKG_BUILD}/projects/unix/mupen64plus-video-rice-simple.so" ] + then + cp ${PKG_BUILD}/projects/unix/mupen64plus-video-rice-simple.so ${UPLUGINDIR} + chmod 0644 ${UPLUGINDIR}/mupen64plus-video-rice-simple.so + fi + + mkdir -p ${USHAREDIR} + cp ${PKG_BUILD}/data/RiceVideoLinux.ini ${USHAREDIR} + chmod 0644 ${USHAREDIR}/RiceVideoLinux.ini +} + diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-video-rice/patches/mupen-rice.patch b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-video-rice/patches/mupen-rice.patch new file mode 100644 index 0000000000..ad551d7065 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-video-rice/patches/mupen-rice.patch @@ -0,0 +1,76 @@ +diff --git a/src/Config.cpp b/src/Config.cpp +index 961a1c7..1b4ef28 100644 +--- a/src/Config.cpp ++++ b/src/Config.cpp +@@ -425,6 +425,12 @@ static void ReadConfiguration(void) + windowSetting.uDisplayWidth = ConfigGetParamInt(l_ConfigVideoGeneral, "ScreenWidth"); + windowSetting.uDisplayHeight = ConfigGetParamInt(l_ConfigVideoGeneral, "ScreenHeight"); + windowSetting.bVerticalSync = ConfigGetParamBool(l_ConfigVideoGeneral, "VerticalSync"); ++ windowSetting.uResolutionWidth = ConfigGetParamInt(l_ConfigVideoRice, "ResolutionWidth"); ++ if (windowSetting.uResolutionWidth) { ++ windowSetting.uXOffset = (windowSetting.uResolutionWidth - windowSetting.uDisplayWidth)/2; ++ } else { ++ windowSetting.uXOffset = 0; ++ } + + defaultRomOptions.N64FrameBufferEmuType = ConfigGetParamInt(l_ConfigVideoRice, "FrameBufferSetting"); + defaultRomOptions.N64FrameBufferWriteBackControl = ConfigGetParamInt(l_ConfigVideoRice, "FrameBufferWriteBackControl"); +diff --git a/src/OGLRender.cpp b/src/OGLRender.cpp +index 6f9d0e2..6618d21 100644 +--- a/src/OGLRender.cpp ++++ b/src/OGLRender.cpp +@@ -935,7 +935,7 @@ void OGLRender::UpdateScissor() + uint32 height = (gRDP.scissor.right*gRDP.scissor.bottom)/width; + glEnable(GL_SCISSOR_TEST); + OPENGL_CHECK_ERRORS; +- glScissor(0, int(height*windowSetting.fMultY+windowSetting.statusBarHeightToUse), ++ glScissor(windowSetting.uXOffset, int(height*windowSetting.fMultY+windowSetting.statusBarHeightToUse), + int(width*windowSetting.fMultX), int(height*windowSetting.fMultY) ); + OPENGL_CHECK_ERRORS; + } +@@ -956,13 +956,13 @@ void OGLRender::ApplyRDPScissor(bool force) + uint32 height = (gRDP.scissor.right*gRDP.scissor.bottom)/width; + glEnable(GL_SCISSOR_TEST); + OPENGL_CHECK_ERRORS; +- glScissor(0, int(height*windowSetting.fMultY+windowSetting.statusBarHeightToUse), ++ glScissor(windowSetting.uXOffset, int(height*windowSetting.fMultY+windowSetting.statusBarHeightToUse), + int(width*windowSetting.fMultX), int(height*windowSetting.fMultY) ); + OPENGL_CHECK_ERRORS; + } + else + { +- glScissor(int(gRDP.scissor.left*windowSetting.fMultX), int((windowSetting.uViHeight-gRDP.scissor.bottom)*windowSetting.fMultY+windowSetting.statusBarHeightToUse), ++ glScissor(int(gRDP.scissor.left*windowSetting.fMultX + windowSetting.uXOffset), int((windowSetting.uViHeight-gRDP.scissor.bottom)*windowSetting.fMultY+windowSetting.statusBarHeightToUse), + int((gRDP.scissor.right-gRDP.scissor.left)*windowSetting.fMultX), int((gRDP.scissor.bottom-gRDP.scissor.top)*windowSetting.fMultY )); + OPENGL_CHECK_ERRORS; + } +@@ -976,7 +976,7 @@ void OGLRender::ApplyScissorWithClipRatio(bool force) + + glEnable(GL_SCISSOR_TEST); + OPENGL_CHECK_ERRORS; +- glScissor(windowSetting.clipping.left, int((windowSetting.uViHeight-gRSP.real_clip_scissor_bottom)*windowSetting.fMultY)+windowSetting.statusBarHeightToUse, ++ glScissor(windowSetting.clipping.left + windowSetting.uXOffset, int((windowSetting.uViHeight-gRSP.real_clip_scissor_bottom)*windowSetting.fMultY)+windowSetting.statusBarHeightToUse, + windowSetting.clipping.width, windowSetting.clipping.height); + OPENGL_CHECK_ERRORS; + +@@ -1019,7 +1019,7 @@ void OGLRender::glViewportWrapper(GLint x, GLint y, GLsizei width, GLsizei heigh + mflag=flag; + glLoadIdentity(); + OPENGL_CHECK_ERRORS; +- glViewport(x,y,width,height); ++ glViewport(windowSetting.uXOffset + x,y,width,height); + OPENGL_CHECK_ERRORS; + } + } +diff --git a/src/Video.h b/src/Video.h +index 7fbbcaa..25812c9 100644 +--- a/src/Video.h ++++ b/src/Video.h +@@ -37,6 +37,7 @@ typedef struct { + float fViWidth, fViHeight; + unsigned short uViWidth, uViHeight; + unsigned short uDisplayWidth, uDisplayHeight; ++ unsigned short uResolutionWidth, uXOffset; + + BOOL bDisplayFullscreen; + BOOL bVerticalSync; diff --git a/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/package.mk b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/package.mk new file mode 100644 index 0000000000..09c9804c95 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/mupen64plus-sa/package.mk @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2019-present Team LibreELEC (https://libreelec.tv) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="mupen64plus-sa" +PKG_VERSION="f8adbe08805d9fe9171cb2e3078f383631d1331d" +PKG_LICENSE="GPL" +PKG_SITE="https://mupen64plus.org/" +PKG_URL="" +PKG_DEPENDS_TARGET="toolchain mupen64plus-sa-ui-console mupen64plus-sa-audio-sdl mupen64plus-sa-input-sdl mupen64plus-sa-rsp-hle mupen64plus-sa-rsp-cxd4 mupen64plus-sa-video-rice mupen64plus-sa-video-glide64mk2 mupen64plus-sa-video-gliden64" +PKG_SECTION="virtual" +PKG_LONGDESC="Meta package for installing the different Mupen64Plus standalone modules" diff --git a/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/RK3326/keymap.toml b/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/RK3326/keymap.toml new file mode 100644 index 0000000000..8b010d4e05 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/RK3326/keymap.toml @@ -0,0 +1,18 @@ +# See https://wiki.libsdl.org/SDL_Keycode for key names + +[general] +fastforward = "Space" +reset = "F9" +fullscreen = "F10" + +[gba] +a = "A" +b = "S" +l = "D" +r = "F" +start = "Return" +select = "Backspace" +up = "Up" +down = "Down" +left = "Left" +right = "Right" diff --git a/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/RK3326/keympa.toml b/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/RK3326/keympa.toml new file mode 100644 index 0000000000..8b010d4e05 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/RK3326/keympa.toml @@ -0,0 +1,18 @@ +# See https://wiki.libsdl.org/SDL_Keycode for key names + +[general] +fastforward = "Space" +reset = "F9" +fullscreen = "F10" + +[gba] +a = "A" +b = "S" +l = "D" +r = "F" +start = "Return" +select = "Backspace" +up = "Up" +down = "Down" +left = "Left" +right = "Right" diff --git a/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/RK3399/keymap.toml b/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/RK3399/keymap.toml new file mode 100644 index 0000000000..8b010d4e05 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/RK3399/keymap.toml @@ -0,0 +1,18 @@ +# See https://wiki.libsdl.org/SDL_Keycode for key names + +[general] +fastforward = "Space" +reset = "F9" +fullscreen = "F10" + +[gba] +a = "A" +b = "S" +l = "D" +r = "F" +start = "Return" +select = "Backspace" +up = "Up" +down = "Down" +left = "Left" +right = "Right" diff --git a/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/RK3399/keympa.toml b/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/RK3399/keympa.toml new file mode 100644 index 0000000000..8b010d4e05 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/RK3399/keympa.toml @@ -0,0 +1,18 @@ +# See https://wiki.libsdl.org/SDL_Keycode for key names + +[general] +fastforward = "Space" +reset = "F9" +fullscreen = "F10" + +[gba] +a = "A" +b = "S" +l = "D" +r = "F" +start = "Return" +select = "Backspace" +up = "Up" +down = "Down" +left = "Left" +right = "Right" diff --git a/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/RK3588/keymap.toml b/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/RK3588/keymap.toml new file mode 100644 index 0000000000..8b010d4e05 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/RK3588/keymap.toml @@ -0,0 +1,18 @@ +# See https://wiki.libsdl.org/SDL_Keycode for key names + +[general] +fastforward = "Space" +reset = "F9" +fullscreen = "F10" + +[gba] +a = "A" +b = "S" +l = "D" +r = "F" +start = "Return" +select = "Backspace" +up = "Up" +down = "Down" +left = "Left" +right = "Right" diff --git a/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/RK3588/keympa.toml b/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/RK3588/keympa.toml new file mode 100644 index 0000000000..8b010d4e05 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/RK3588/keympa.toml @@ -0,0 +1,18 @@ +# See https://wiki.libsdl.org/SDL_Keycode for key names + +[general] +fastforward = "Space" +reset = "F9" +fullscreen = "F10" + +[gba] +a = "A" +b = "S" +l = "D" +r = "F" +start = "Return" +select = "Backspace" +up = "Up" +down = "Down" +left = "Left" +right = "Right" diff --git a/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/SDM845/keymap.toml b/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/SDM845/keymap.toml new file mode 100644 index 0000000000..8b010d4e05 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/SDM845/keymap.toml @@ -0,0 +1,18 @@ +# See https://wiki.libsdl.org/SDL_Keycode for key names + +[general] +fastforward = "Space" +reset = "F9" +fullscreen = "F10" + +[gba] +a = "A" +b = "S" +l = "D" +r = "F" +start = "Return" +select = "Backspace" +up = "Up" +down = "Down" +left = "Left" +right = "Right" diff --git a/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/SM8250/keymap.toml b/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/SM8250/keymap.toml new file mode 100644 index 0000000000..8b010d4e05 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/SM8250/keymap.toml @@ -0,0 +1,18 @@ +# See https://wiki.libsdl.org/SDL_Keycode for key names + +[general] +fastforward = "Space" +reset = "F9" +fullscreen = "F10" + +[gba] +a = "A" +b = "S" +l = "D" +r = "F" +start = "Return" +select = "Backspace" +up = "Up" +down = "Down" +left = "Left" +right = "Right" diff --git a/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/SM8550/keymap.toml b/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/SM8550/keymap.toml new file mode 100644 index 0000000000..8b010d4e05 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/SM8550/keymap.toml @@ -0,0 +1,18 @@ +# See https://wiki.libsdl.org/SDL_Keycode for key names + +[general] +fastforward = "Space" +reset = "F9" +fullscreen = "F10" + +[gba] +a = "A" +b = "S" +l = "D" +r = "F" +start = "Return" +select = "Backspace" +up = "Up" +down = "Down" +left = "Left" +right = "Right" diff --git a/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/SM8650/keymap.toml b/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/SM8650/keymap.toml new file mode 100644 index 0000000000..8b010d4e05 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/SM8650/keymap.toml @@ -0,0 +1,18 @@ +# See https://wiki.libsdl.org/SDL_Keycode for key names + +[general] +fastforward = "Space" +reset = "F9" +fullscreen = "F10" + +[gba] +a = "A" +b = "S" +l = "D" +r = "F" +start = "Return" +select = "Backspace" +up = "Up" +down = "Down" +left = "Left" +right = "Right" diff --git a/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/config.toml b/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/config.toml new file mode 100644 index 0000000000..95f925d0ea --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/config/config.toml @@ -0,0 +1,29 @@ +[general] +bios_path = "/storage/roms/bios/gba_bios.bin" +bios_skip = false +sync_to_audio = false + +[cartridge] +# Possible values: detect, none, sram, flash64, flash128, eeprom512, eeprom8192 +save_type = "detect" +# Force-enable RTC emulation, otherwise rely on game database. +force_rtc = true + +[video] +fullscreen = false +scale = 2 +# Set empty string for no shader. +shader_vs = "/storage/.config/nanoboyadvance/shader/gba_colors.vs" +shader_fs = "/storage/.config/nanoboyadvance/shader/gba_colors.fs" + +[audio] +# Possible values: cosine, cubic, sinc64, sinc128, sinc256 +resampler = "cubic" +# Filter FIFO audio before passing it to the mixer. +# This will reduce the dity high-frequency aliasing typical to the GBA. +interpolate_fifo = true +# Reimplementation of the popular MP2K/M4A audio mixer with higher quality. +# This is experimental and may still have issues. +mp2k_hle_enable = false +# Use cubic interpolation in the MP2K reimplementation. +mp2k_hle_cubic = false diff --git a/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/package.mk b/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/package.mk new file mode 100644 index 0000000000..433963f5d4 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/package.mk @@ -0,0 +1,37 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="nanoboyadvance-sa" +PKG_VERSION="3bb6f478f977dbfd3106508536e5fbce90d1898b" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/nba-emu/NanoBoyAdvance" +PKG_URL="${PKG_SITE}.git" +PKG_OPEN_SOURCE_BIOS="https://github.com/Nebuleon/ReGBA/raw/master/bios/gba_bios.bin" +PKG_DEPENDS_TARGET="toolchain SDL2 glew" +PKG_LONGDESC="NanoBoyAdvance is a cycle-accurate Game Boy Advance emulator." +PKG_TOOLCHAIN="cmake" +PKG_PATCH_DIRS+="${DEVICE}" + +if [ "${OPENGL_SUPPORT}" = "yes" ] && [ ! "${PREFER_GLES}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" +elif [ "${OPENGLES_SUPPORT}" = yes ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" +fi + +PKG_CMAKE_OPTS_TARGET+=" -DPLATFORM_SDL2=ON \ + -DPLATFORM_QT=OFF \ + -DCMAKE_POLICY_VERSION_MINIMUM=3.5" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp -rf ${PKG_BUILD}/.${TARGET_NAME}/bin/sdl/NanoBoyAdvance ${INSTALL}/usr/bin + cp -rf ${PKG_DIR}/scripts/* ${INSTALL}/usr/bin + chmod 755 ${INSTALL}/usr/bin/* + + mkdir -p ${INSTALL}/usr/config/nanoboyadvance + cp -rf ${PKG_DIR}/config/config.toml ${INSTALL}/usr/config/nanoboyadvance/ + cp -rf ${PKG_DIR}/config/${DEVICE}/keymap.toml ${INSTALL}/usr/config/nanoboyadvance/ + + mkdir -p ${INSTALL}/usr/config/nanoboyadvance/bios + curl -Lo ${INSTALL}/usr/config/nanoboyadvance/bios/gba_bios.bin ${PKG_OPEN_SOURCE_BIOS} +} diff --git a/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/patches/000-config-path.patch b/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/patches/000-config-path.patch new file mode 100644 index 0000000000..dd43f200e3 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/patches/000-config-path.patch @@ -0,0 +1,22 @@ +diff --git a/src/platform/sdl/main.cpp b/src/platform/sdl/main.cpp +index 432d984..96d4848 100644 +--- a/src/platform/sdl/main.cpp ++++ b/src/platform/sdl/main.cpp +@@ -216,7 +216,7 @@ void load_keymap() { + toml::value data; + + try { +- data = toml::parse("keymap.toml"); ++ data = toml::parse("/storage/.config/nanoboyadvance/keymap.toml"); + } catch (std::exception& ex) { + Log("SDL: failed to load keymap configuration."); + return; +@@ -290,7 +290,7 @@ void init(int argc, char** argv) { + if (argc >= 1) { + fs::current_path(fs::absolute(argv[0]).replace_filename(fs::path{ })); + } +- g_config->Load("config.toml"); ++ g_config->Load("/storage/.config/nanoboyadvance/config.toml"); + parse_arguments(argc, argv); + load_keymap(); + SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_GAMECONTROLLER); diff --git a/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/patches/001-rework-dma-interleave.patch b/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/patches/001-rework-dma-interleave.patch new file mode 100644 index 0000000000..4121b652ee --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/patches/001-rework-dma-interleave.patch @@ -0,0 +1,322 @@ +From 5d199dd8742f858b83beb55abd7cd0da45d3721e Mon Sep 17 00:00:00 2001 +From: fleroviux +Date: Mon, 13 Feb 2023 23:11:05 +0100 +Subject: [PATCH] Bus: rework DMA interleave to be more robust and simpler + +--- + src/nba/CMakeLists.txt | 1 + + src/nba/include/nba/common/scope_exit.hpp | 24 +++++++++++++++++++++++ + src/nba/include/nba/save_state.hpp | 7 ++----- + src/nba/src/bus/bus.cpp | 16 +++++++++++++-- + src/nba/src/bus/bus.hpp | 8 +++----- + src/nba/src/bus/io.cpp | 2 +- + src/nba/src/bus/serialization.cpp | 6 ++---- + src/nba/src/bus/timing.cpp | 11 ++--------- + src/nba/src/core.cpp | 4 +++- + src/nba/src/hw/dma/dma.cpp | 16 +++++++-------- + 10 files changed, 60 insertions(+), 35 deletions(-) + create mode 100644 src/nba/include/nba/common/scope_exit.hpp + +diff --git a/src/nba/CMakeLists.txt b/src/nba/CMakeLists.txt +index 9c9c6e8ab..887bcac7a 100644 +--- a/src/nba/CMakeLists.txt ++++ b/src/nba/CMakeLists.txt +@@ -91,6 +91,7 @@ set(HEADERS_PUBLIC + include/nba/common/crc32.hpp + include/nba/common/meta.hpp + include/nba/common/punning.hpp ++ include/nba/common/scope_exit.hpp + include/nba/device/audio_device.hpp + include/nba/device/input_device.hpp + include/nba/device/video_device.hpp +diff --git a/src/nba/include/nba/common/scope_exit.hpp b/src/nba/include/nba/common/scope_exit.hpp +new file mode 100644 +index 000000000..888c3703c +--- /dev/null ++++ b/src/nba/include/nba/common/scope_exit.hpp +@@ -0,0 +1,24 @@ ++/* ++ * Copyright (C) 2023 fleroviux ++ * ++ * Licensed under GPLv3 or any later version. ++ * Refer to the included LICENSE file. ++ */ ++ ++#pragma once ++ ++namespace nba { ++ ++template ++struct ScopeExit { ++ ScopeExit(Functor&& fn) : fn{fn} {} ++ ++ ScopeExit(ScopeExit&& other) = delete; ++ ScopeExit(ScopeExit const& other) = delete; ++ ++ ~ScopeExit() { fn.operator()(); } ++ ++ Functor fn; ++}; ++ ++} // namespace nba +\ No newline at end of file +diff --git a/src/nba/include/nba/save_state.hpp b/src/nba/include/nba/save_state.hpp +index 5e3c1dd00..7e8865dba 100644 +--- a/src/nba/include/nba/save_state.hpp ++++ b/src/nba/include/nba/save_state.hpp +@@ -16,7 +16,7 @@ namespace nba { + + struct SaveState { + static constexpr u32 kMagicNumber = 0x5353424E; // NBSS +- static constexpr u32 kCurrentVersion = 3; ++ static constexpr u32 kCurrentVersion = 4; + + u32 magic; + u32 version; +@@ -76,10 +76,7 @@ struct SaveState { + u8 countdown; + } prefetch; + +- struct DMA { +- bool active; +- bool openbus; +- } dma; ++ int last_access; + } bus; + + // TODO: keep track of IRQ delay: +diff --git a/src/nba/src/bus/bus.cpp b/src/nba/src/bus/bus.cpp +index 2a6b53a86..ef9f50ed4 100644 +--- a/src/nba/src/bus/bus.cpp ++++ b/src/nba/src/bus/bus.cpp +@@ -7,6 +7,7 @@ + + #include + #include ++#include + #include + + #include "arm/arm7tdmi.hpp" +@@ -32,7 +33,7 @@ void Bus::Reset() { + hw.rcnt[1] = 0; + hw.postflg = 0; + prefetch = {}; +- dma = {}; ++ last_access = 0; + UpdateWaitStateTable(); + } + +@@ -77,6 +78,13 @@ auto Bus::Read(u32 address, int access) -> T { + auto page = address >> 24; + auto is_u32 = std::is_same_v; + ++ // Set last_access to access right before returning. ++ auto _ = ScopeExit{[&]() { ++ last_access = access; ++ }}; ++ ++ if(!(access & Dma) && hw.dma.IsRunning()) hw.dma.Run(); ++ + switch (page) { + // BIOS + case 0x00: { +@@ -170,6 +178,8 @@ void Bus::Write(u32 address, int access, T value) { + auto page = address >> 24; + auto is_u32 = std::is_same_v; + ++ if(!(access & Dma) && hw.dma.IsRunning()) hw.dma.Run(); ++ + switch (page) { + // EWRAM (external work RAM) + case 0x02: { +@@ -255,6 +265,8 @@ void Bus::Write(u32 address, int access, T value) { + break; + } + } ++ ++ last_access = access; + } + + auto Bus::ReadBIOS(u32 address) -> u32 { +@@ -279,7 +291,7 @@ auto Bus::ReadOpenBus(u32 address) -> u32 { + + Log("Bus: illegal memory read: 0x{:08X}", address); + +- if (hw.dma.IsRunning() || dma.openbus) { ++ if(last_access & Dma) { + return hw.dma.GetOpenBusValue() >> shift; + } + +diff --git a/src/nba/src/bus/bus.hpp b/src/nba/src/bus/bus.hpp +index 8c1bc64af..472ae5dc6 100644 +--- a/src/nba/src/bus/bus.hpp ++++ b/src/nba/src/bus/bus.hpp +@@ -30,7 +30,8 @@ struct Bus { + enum Access { + Nonsequential = 0, + Sequential = 1, +- Code = 2 ++ Code = 2, ++ Dma = 4 + }; + + void Reset(); +@@ -109,10 +110,7 @@ struct Bus { + int duty; + } prefetch; + +- struct DMA { +- bool active = false; +- bool openbus = false; +- } dma; ++ int last_access; + + template + auto Read(u32 address, int access) -> T; +diff --git a/src/nba/src/bus/io.cpp b/src/nba/src/bus/io.cpp +index ab5175e9e..51a7fcf1a 100644 +--- a/src/nba/src/bus/io.cpp ++++ b/src/nba/src/bus/io.cpp +@@ -551,7 +551,7 @@ void Bus::Hardware::WriteByte(u32 address, u8 value) { + haltcnt = HaltControl::Stop; + } else { + haltcnt = HaltControl::Halt; +- bus->Idle(); ++ bus->Step(1); + } + } + break; +diff --git a/src/nba/src/bus/serialization.cpp b/src/nba/src/bus/serialization.cpp +index 48d31d1ed..50283cad8 100644 +--- a/src/nba/src/bus/serialization.cpp ++++ b/src/nba/src/bus/serialization.cpp +@@ -44,8 +44,7 @@ void Bus::LoadState(SaveState const& state) { + prefetch.duty = wait32[int(Access::Sequential)][prefetch.last_address >> 24]; + } + +- dma.active = state.bus.dma.active; +- dma.openbus = state.bus.dma.openbus; ++ last_access = state.bus.last_access; + } + + void Bus::CopyState(SaveState& state) { +@@ -73,8 +72,7 @@ void Bus::CopyState(SaveState& state) { + state.bus.prefetch.count = prefetch.count; + state.bus.prefetch.countdown = prefetch.countdown; + +- state.bus.dma.active = dma.active; +- state.bus.dma.openbus = dma.openbus; ++ state.bus.last_access = last_access; + } + + } // namespace nba::core +\ No newline at end of file +diff --git a/src/nba/src/bus/timing.cpp b/src/nba/src/bus/timing.cpp +index ecdf105f8..c1e92ae6a 100644 +--- a/src/nba/src/bus/timing.cpp ++++ b/src/nba/src/bus/timing.cpp +@@ -11,6 +11,8 @@ + namespace nba::core { + + void Bus::Idle() { ++ if(hw.dma.IsRunning()) hw.dma.Run(); ++ + Step(1); + } + +@@ -85,15 +87,6 @@ void Bus::StopPrefetch() { + } + + void Bus::Step(int cycles) { +- dma.openbus = false; +- +- if (hw.dma.IsRunning() && !dma.active) { +- dma.active = true; +- hw.dma.Run(); +- dma.active = false; +- dma.openbus = true; +- } +- + scheduler.AddCycles(cycles); + + if (prefetch.active) { +diff --git a/src/nba/src/core.cpp b/src/nba/src/core.cpp +index 3749778cb..6d0257544 100644 +--- a/src/nba/src/core.cpp ++++ b/src/nba/src/core.cpp +@@ -81,7 +81,7 @@ void Core::Run(int cycles) { + + while (scheduler.GetTimestampNow() < limit) { + if (bus.hw.haltcnt == HaltControl::Halt && irq.HasServableIRQ()) { +- bus.Idle(); ++ bus.Step(1); + bus.hw.haltcnt = HaltControl::Run; + } + +@@ -96,6 +96,8 @@ void Core::Run(int cycles) { + } + cpu.Run(); + } else { ++ if(dma.IsRunning()) dma.Run(); ++ + bus.Step(scheduler.GetRemainingCycleCount()); + } + } +diff --git a/src/nba/src/hw/dma/dma.cpp b/src/nba/src/hw/dma/dma.cpp +index 8bb07a3c7..db5bb4b72 100644 +--- a/src/nba/src/hw/dma/dma.cpp ++++ b/src/nba/src/hw/dma/dma.cpp +@@ -151,13 +151,13 @@ bool DMA::HasVideoTransferDMA() { + } + + void DMA::Run() { +- bus.Idle(); ++ bus.Step(1); + + do { + RunChannel(); + } while (IsRunning()); + +- bus.Idle(); ++ bus.Step(1); + } + + void DMA::RunChannel() { +@@ -186,15 +186,15 @@ void DMA::RunChannel() { + auto src_addr = channel.latch.src_addr; + auto dst_addr = channel.latch.dst_addr; + +- auto access_src = Bus::Access::Sequential; +- auto access_dst = Bus::Access::Sequential; ++ auto access_src = Bus::Access::Sequential | Bus::Access::Dma; ++ auto access_dst = Bus::Access::Sequential | Bus::Access::Dma; + + if (!did_access_rom) { + if (src_addr >= 0x08000000) { +- access_src = Bus::Access::Nonsequential; ++ access_src = Bus::Access::Nonsequential | Bus::Access::Dma; + did_access_rom = true; + } else if (dst_addr >= 0x08000000) { +- access_dst = Bus::Access::Nonsequential; ++ access_dst = Bus::Access::Nonsequential | Bus::Access::Dma; + did_access_rom = true; + } + } +@@ -212,7 +212,7 @@ void DMA::RunChannel() { + } else { + value = channel.latch.bus; + } +- bus.Idle(); ++ bus.Step(1); + } + + bus.WriteHalf(dst_addr, value, access_dst); +@@ -221,7 +221,7 @@ void DMA::RunChannel() { + channel.latch.bus = bus.ReadWord(src_addr, access_src); + latch = channel.latch.bus; + } else { +- bus.Idle(); ++ bus.Step(1); + } + + bus.WriteWord(dst_addr, channel.latch.bus, access_dst); diff --git a/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/scripts/start_nanoboyadvance.sh b/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/scripts/start_nanoboyadvance.sh new file mode 100644 index 0000000000..71c0eb5788 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/nanoboyadvance-sa/scripts/start_nanoboyadvance.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile +set_kill set "-9 NanoBoyAdvance" + +#Check if nanoboyadvance exists in .config +if [ ! -d "/storage/.config/nanoboyadvance" ]; then + mkdir -p "/storage/.config/nanoboyadvance" + cp -r "/usr/config/nanoboyadvance" "/storage/.config/" +fi + +#Make nanoboyadvance bios folder +if [ ! -d "/storage/roms/bios/gba" ]; then + mkdir -p "/storage/roms/bios/gba" +fi + +#Copy open source bios if no other bios exists +if [ ! -f "/storage/roms/bios/gba/gba_bios.bin" ]; then + cp -r "/usr/config/nanoboyadvance" "/storage/roms/bios/gba/gba_bios.bin" +fi + +#Set the cores to use +GAME=$(echo "${1}"| sed "s#^/.*/##") +PLATFORM=$(echo "${2}"| sed "s#^/.*/##") +CORES=$(get_setting "cores" "${PLATFORM}" "${GAME}") +if [ "${CORES}" = "little" ] +then + EMUPERF="${SLOW_CORES}" +elif [ "${CORES}" = "big" ] +then + EMUPERF="${FAST_CORES}" +else + ### All.. + unset EMUPERF +fi + +#Run nanoboyadvance emulator +${EMUPERF} /usr/bin/NanoBoyAdvance "${1}" diff --git a/projects/ArchR/packages/emulators/standalone/openbor/config/Saves/default.cfg b/projects/ArchR/packages/emulators/standalone/openbor/config/Saves/default.cfg new file mode 100755 index 0000000000..a5276276eb Binary files /dev/null and b/projects/ArchR/packages/emulators/standalone/openbor/config/Saves/default.cfg differ diff --git a/projects/ArchR/packages/emulators/standalone/openbor/config/master.cfg b/projects/ArchR/packages/emulators/standalone/openbor/config/master.cfg new file mode 100644 index 0000000000..abe3f75ca6 Binary files /dev/null and b/projects/ArchR/packages/emulators/standalone/openbor/config/master.cfg differ diff --git a/projects/ArchR/packages/emulators/standalone/openbor/package.mk b/projects/ArchR/packages/emulators/standalone/openbor/package.mk new file mode 100644 index 0000000000..bd2cbf8be2 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/openbor/package.mk @@ -0,0 +1,35 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2019-present Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2021-present 351ELEC (https://github.com/351ELEC) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="openbor" +PKG_VERSION="b8303cce992a0db93c3a465df3c943942fe322f8" +PKG_SITE="https://github.com/DCurrent/openbor" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain SDL2 libogg libvorbisidec libvpx libpng" +PKG_LONGDESC="OpenBOR is the ultimate 2D side scrolling engine for beat em' ups, shooters, and more!" +PKG_TOOLCHAIN="make" +GET_HANDLER_SUPPORT="git" + +pre_configure_target() { + PKG_MAKE_OPTS_TARGET="BUILD_LINUX_${ARCH}=1 -C ${PKG_BUILD}/engine SDKPATH=${SYSROOT_PREFIX} PREFIX=${TARGET_NAME}" + cd ${PKG_BUILD} + #sed -i "s|device->mappings\[SDID_START\] = SDL_CONTROLLER_BUTTON_START;|device->mappings\[SDID_START\] = SDL_CONTROLLER_BUTTON_BACK;|g" engine/sdl/control.c + #sed -i "s|device->mappings\[SDID_SCREENSHOT\] = SDL_CONTROLLER_BUTTON_BACK;|device->mappings\[SDID_SCREENSHOT\] = SDL_CONTROLLER_BUTTON_START;|g" engine/sdl/control.c + sed -i "s|-Werror||g" engine/Makefile +} + +pre_make_target() { + cd ${PKG_BUILD}/engine + ./version.sh +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp OpenBOR ${INSTALL}/usr/bin/OpenBOR + cp ${PKG_DIR}/sources/start_OpenBOR.sh ${INSTALL}/usr/bin + chmod 0777 ${INSTALL}/usr/bin/* + mkdir -p ${INSTALL}/usr/config/openbor + cp ${PKG_DIR}/config/master.cfg ${INSTALL}/usr/config/openbor/master.cfg +} diff --git a/projects/ArchR/packages/emulators/standalone/openbor/patches/openbor-02-addplatform.patch b/projects/ArchR/packages/emulators/standalone/openbor/patches/openbor-02-addplatform.patch new file mode 100644 index 0000000000..50473bdfaf --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/openbor/patches/openbor-02-addplatform.patch @@ -0,0 +1,75 @@ +From 5d057e7b6b350e2faa75c041d0081fb2963e980d Mon Sep 17 00:00:00 2001 +From: 5schatten +Date: Sat, 12 Oct 2019 19:24:14 +0200 +Subject: [PATCH] engine/Makefile: updated platform + +--- + engine/Makefile | 48 +++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 47 insertions(+), 1 deletion(-) + +diff --git a/engine/Makefile b/engine/Makefile +index 8b0f9a65..6e8198e0 100644 +--- a/engine/Makefile ++++ b/engine/Makefile +@@ -103,6 +103,52 @@ BUILD_DEBUG = 1 + endif + endif + ++ifdef BUILD_LINUX_x86_64 ++TARGET = $(VERSION_NAME).elf ++TARGET_FINAL = $(VERSION_NAME) ++TARGET_PLATFORM = LINUX ++BUILD_SDL = 1 ++BUILD_GFX = 1 ++BUILD_PTHREAD = 1 ++BUILD_SDL_IO = 1 ++BUILD_OPENGL = 1 ++BUILD_LOADGL = 1 ++BUILD_VORBIS = 1 ++BUILD_WEBM = 1 ++BUILDING = 1 ++YASM = nasm ++OBJTYPE = elf ++INCLUDES = $(SDKPATH)/usr/include \ ++ $(SDKPATH)/usr/include/SDL2 ++TARGET_ARCH = amd64 ++BUILD_AMD64 = 1 ++ARCHFLAGS = -m64 ++LIBRARIES = $(SDKPATH)/usr/lib ++CFLAGS += -DAMD64 ++# Workaround for GCC 9 ++CFLAGS += -Wno-error=format-overflow -Wno-error=stringop-truncation ++endif ++ ++ifdef BUILD_LINUX_aarch64 ++TARGET = $(VERSION_NAME).elf ++TARGET_FINAL = $(VERSION_NAME) ++TARGET_PLATFORM = LINUX ++BUILD_LINUX = 1 ++BUILD_SDL = 1 ++BUILD_GFX = 1 ++BUILD_PTHREAD = 1 ++BUILD_SDL_IO = 1 ++BUILD_VORBIS = 1 ++BUILD_WEBM = 1 ++BUILDING = 1 ++INCLUDES = $(SDKPATH)/usr/include \ ++ $(SDKPATH)/usr/include/SDL2 ++OBJTYPE = elf ++LIBRARIES = $(SDKPATH)/usr/lib ++# Workaround for GCC 9 ++CFLAGS += -Wno-error=format-overflow -Wno-error=stringop-truncation -Wno-error=implicit-function-declaration -Wno-error=unused-variable -Wno-error=unused-label ++endif ++ + ifdef BUILD_DARWIN + TARGET = $(VERSION_NAME).elf + TARGET_FINAL = $(VERSION_NAME) +@@ -195,7 +241,7 @@ ifdef BUILD_WIN + STRIP = $(WINDEV)/$(PREFIX)strip$(EXTENSION) $(TARGET) -o $(TARGET_FINAL) + endif + ifdef BUILD_LINUX +-STRIP = $(LNXDEV)/$(PREFIX)strip $(TARGET) -o $(TARGET_FINAL) ++STRIP = $(PREFIX)-strip $(TARGET) -o $(TARGET_FINAL) + endif + ifdef BUILD_DARWIN + STRIP = $(PREFIX)strip $(TARGET) -o $(TARGET_FINAL) diff --git a/projects/ArchR/packages/emulators/standalone/openbor/sources/start_OpenBOR.sh b/projects/ArchR/packages/emulators/standalone/openbor/sources/start_OpenBOR.sh new file mode 100755 index 0000000000..c10fcd12e9 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/openbor/sources/start_OpenBOR.sh @@ -0,0 +1,45 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2019-present Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2021-present 351ELEC (https://github.com/351ELEC) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# OpenBOR only works with Pak files, if you have an extracted game you will need to create a pak first. + +pakname=$(basename "$1") +pakname="${pakname%.*}" + +CONFIGDIR="/storage/openbor" +PAKS="${CONFIGDIR}/Paks" +SAVES="${CONFIGDIR}/Saves" + +# Make sure the folders exists + mkdir -p "${CONFIGDIR}" + mkdir -p "${PAKS}" + mkdir -p "${SAVES}" + +# Check if master.cfg exists + if [ ! -f "${CONFIGDIR}/master.cfg" ]; then + cp -f "/usr/config/openbor/master.cfg" "${CONFIGDIR}/" + fi + +# Clear PAKS folder to avoid getting the launcher on next run + rm -rf ${PAKS}/* + +# make a symlink to the pak + ln -sf "$1" "${PAKS}" + +# only create symlink to master.cfg if its the first time running the pak + if [ ! -f "${SAVES}/${pakname}.cfg" ]; then + ln -sf "${CONFIGDIR}/master.cfg" "${SAVES}/${pakname}.cfg" + fi + +# We start the fake keyboard + gptokeyb openbor & + +# Run OpenBOR in the config folder + cd "${CONFIGDIR}" + OpenBOR + +# We stop the fake keyboard + killall gptokeyb & diff --git a/projects/ArchR/packages/emulators/standalone/pico-8/package.mk b/projects/ArchR/packages/emulators/standalone/pico-8/package.mk new file mode 100644 index 0000000000..742b48a45b --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/pico-8/package.mk @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="pico-8" +PKG_VERSION="95cb4d4f28e1743c6a7f3c0266049f68b2134b60" +PKG_LICENSE="GPLv2" +PKG_SITE="" +PKG_URL="" +PKG_DEPENDS_TARGET="toolchain SDL2" +PKG_LONGDESC="PICO-8 Fantasy Console" +PKG_TOOLCHAIN="manual" + +if [ ! "${OPENGL}" = "no" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" +fi + +if [ "${OPENGLES_SUPPORT}" = yes ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" +fi + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp ${PKG_DIR}/sources/start_pico8.sh ${INSTALL}/usr/bin + chmod 0755 ${INSTALL}/usr/bin/start_pico8.sh + + mkdir -p ${INSTALL}/usr/lib/autostart/common + cp ${PKG_DIR}/sources/autostart/common/* ${INSTALL}/usr/lib/autostart/common + chmod 0755 ${INSTALL}/usr/lib/autostart/common/* +} diff --git a/projects/ArchR/packages/emulators/standalone/pico-8/sources/autostart/common/010-pico8 b/projects/ArchR/packages/emulators/standalone/pico-8/sources/autostart/common/010-pico8 new file mode 100755 index 0000000000..9185251a60 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/pico-8/sources/autostart/common/010-pico8 @@ -0,0 +1,9 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PICO_DIR="/storage/roms/pico-8" +if [ -d "${PICO_DIR}" ] && [ ! -f "${PICO_DIR}/.disable_splore" ] +then + touch "${PICO_DIR}/Splore.png" +fi diff --git a/projects/ArchR/packages/emulators/standalone/pico-8/sources/start_pico8.sh b/projects/ArchR/packages/emulators/standalone/pico-8/sources/start_pico8.sh new file mode 100644 index 0000000000..52159c9207 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/pico-8/sources/start_pico8.sh @@ -0,0 +1,48 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Source predefined functions and variables +. /etc/profile + +GAME_DIR="/storage/roms/pico-8/" + +case ${HW_ARCH} in + aarch64) + STATIC_BIN="pico8_64" + ;; + *) + STATIC_BIN="pico8_dyn" + ;; +esac + +# check if the file being launched contains "Splore" and if so launch Pico-8 Splore otherwise run the game directly +shopt -s nocasematch +if [[ "${1}" == *splore* ]]; then + OPTIONS="-splore" +else + OPTIONS="-run" + CART="${1}" +fi +shopt -u nocasematch + +INTEGER_SCALE=$(get_setting pico-8.integerscale) +if [ "${INTEGER_SCALE}" = "1" ] +then + OPTIONS="${OPTIONS} -pixel_perfect 1" +fi + +if [ -d "${GAME_DIR}/${HW_ARCH}" ] +then + LAUNCH_DIR="${GAME_DIR}/${HW_ARCH}" +else + LAUNCH_DIR="${GAME_DIR}" +fi + +# store sdl_controllers in root directory so its shared across devices - will look to revisit this with controller refactor work +cp -f /usr/config/SDL-GameControllerDB/gamecontrollerdb.txt ${GAME_DIR}/sdl_controllers.txt + +# mark the binary executable to cover cases where the user adding the binaries doesn't know or forgets. +chmod 0755 ${LAUNCH_DIR}/${STATIC_BIN} +set_kill set "-9 ${STATIC_BIN} start_pico8.sh" +${LAUNCH_DIR}/${STATIC_BIN} -home -root_path ${GAME_DIR} -joystick 0 ${OPTIONS} "${CART}" \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/NPEG00023.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/NPEG00023.ini new file mode 100644 index 0000000000..3bb22e2448 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/NPEG00023.ini @@ -0,0 +1,40 @@ +_S NPEG-00023 +_G GoW CoO [EUR-PSN] +_C0 60 FPS [Fixed] +_L 0xE00E003C 0x10003800 +_L 0xE00D166F 0x0001F690//vblank +_L 0x10003800 0x0000003C +_L 0x20003804 0x10800003 +_L 0x20003808 0x00000000 +_L 0x2000380C 0x0E2C166F +_L 0x20003810 0x00000000 +_L 0x20003814 0x0E2C166F +_L 0x20003818 0x00000000 +_L 0x2000381C 0x8FBF0000 +_L 0x20003820 0x03E00008 +_L 0x20003824 0x27BD0010 +_L 0x2001A31C 0x0A200E01//Jump +_L 0x2001A320 0x34040000//FPS +_L 0x2001A324 0x00000000 +_C0 30 FPS [Fixed] +_L 0xE00E001E 0x10003800 +_L 0xE00D166F 0x0001F690//vblank +_L 0x10003800 0x0000001E +_L 0x20003804 0x10800003 +_L 0x20003808 0x00000000 +_L 0x2000380C 0x0E2C166F +_L 0x20003810 0x00000000 +_L 0x20003814 0x0E2C166F +_L 0x20003818 0x00000000 +_L 0x2000381C 0x8FBF0000 +_L 0x20003820 0x03E00008 +_L 0x20003824 0x27BD0010 +_L 0x2001A31C 0x0A200E01//Jump +_L 0x2001A320 0x34040001//FPS +_L 0x2001A324 0x00000000 +_C0 Unlimited FPS [Default] +_L 0xE0040E01 0x0001A31C +_L 0x2001A31C 0x8FBF0000 +_L 0x2001A320 0x03E00008 +_L 0x2001A324 0x27BD0010 +_L 0x10003800 0x00000000 \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/NPEG00044.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/NPEG00044.ini new file mode 100644 index 0000000000..eff298988a --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/NPEG00044.ini @@ -0,0 +1,40 @@ +_S NPEG-00044 +_G GoW GoS [EUR-MULTI5-PSN] +_C0 60 FPS [Fixed] +_L 0xE00E003C 0x10003800 +_L 0xE00DE14D 0x000205DC//vblank +_L 0x10003800 0x0000003C +_L 0x20003804 0x10800003 +_L 0x20003808 0x00000000 +_L 0x2000380C 0x0E2FE14D +_L 0x20003810 0x00000000 +_L 0x20003814 0x0E2FE14D +_L 0x20003818 0x00000000 +_L 0x2000381C 0x8FBF0000 +_L 0x20003820 0x03E00008 +_L 0x20003824 0x27BD0010 +_L 0x2001B10C 0x0A200E01//Jump +_L 0x2001B110 0x34040000//FPS +_L 0x2001B114 0x00000000 +_C0 30 FPS [Fixed] +_L 0xE00E001E 0x10003800 +_L 0xE00DE14D 0x000205DC//vblank +_L 0x10003800 0x0000001E +_L 0x20003804 0x10800003 +_L 0x20003808 0x00000000 +_L 0x2000380C 0x0E2FE14D +_L 0x20003810 0x00000000 +_L 0x20003814 0x0E2FE14D +_L 0x20003818 0x00000000 +_L 0x2000381C 0x8FBF0000 +_L 0x20003820 0x03E00008 +_L 0x20003824 0x27BD0010 +_L 0x2001B10C 0x0A200E01//Jump +_L 0x2001B110 0x34040001//FPS +_L 0x2001B114 0x00000000 +_C0 Unlimited FPS [Default] +_L 0xE0040E01 0x1001B10C +_L 0x2001B10C 0x8FBF0000 +_L 0x2001B110 0x03E00008 +_L 0x2001B114 0x27BD0010 +_L 0x10003800 0x00000000 \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/NPUG80325.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/NPUG80325.ini new file mode 100644 index 0000000000..d7b2640d03 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/NPUG80325.ini @@ -0,0 +1,40 @@ +_S NPUG-80325 +_G GoW CoO [USA-PSN] +_C1 60 FPS [Fixed] +_L 0xE00E003C 0x10003800 +_L 0xE00D1671 0x0001F690//vblank +_L 0x10003800 0x0000003C +_L 0x20003804 0x10800003 +_L 0x20003808 0x00000000 +_L 0x2000380C 0x0E2C1671 +_L 0x20003810 0x00000000 +_L 0x20003814 0x0E2C1671 +_L 0x20003818 0x00000000 +_L 0x2000381C 0x8FBF0000 +_L 0x20003820 0x03E00008 +_L 0x20003824 0x27BD0010 +_L 0x2001A31C 0x0A200E01//Jump +_L 0x2001A320 0x34040000//FPS +_L 0x2001A324 0x00000000 +_C0 30 FPS [Fixed] +_L 0xE00E001E 0x10003800 +_L 0xE00D1671 0x0001F690//vblank +_L 0x10003800 0x0000001E +_L 0x20003804 0x10800003 +_L 0x20003808 0x00000000 +_L 0x2000380C 0x0E2C1671 +_L 0x20003810 0x00000000 +_L 0x20003814 0x0E2C1671 +_L 0x20003818 0x00000000 +_L 0x2000381C 0x8FBF0000 +_L 0x20003820 0x03E00008 +_L 0x20003824 0x27BD0010 +_L 0x2001A31C 0x0A200E01//Jump +_L 0x2001A320 0x34040001//FPS +_L 0x2001A324 0x00000000 +_C0 Unlimited FPS [Default] +_L 0xE0040E01 0x0001A31C +_L 0x2001A31C 0x8FBF0000 +_L 0x2001A320 0x03E00008 +_L 0x2001A324 0x27BD0010 +_L 0x10003800 0x00000000 \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/UCES00019.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/UCES00019.ini new file mode 100644 index 0000000000..645546a3fe --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/UCES00019.ini @@ -0,0 +1,10 @@ +_S UCES-00019 +_G Pursuit Force [EUR] +_C0 60 FPS v2 +_L 0x20188038 0x0A262017//FPS +_L 0x2016F308 0x3C043F00//GAMEPLAYSPEED +_L 0x2016F388 0x3C044270//MENUSPEED +_C0 30 FPS v2 [Default] +_L 0x20188038 0x10800008//FPS +_L 0x2016F308 0x3C043F80//GAMEPLAYSPEED +_L 0x2016F388 0x3C0441F0//MENUSPEED \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/UCES00842.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/UCES00842.ini new file mode 100644 index 0000000000..e7617352c5 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/UCES00842.ini @@ -0,0 +1,40 @@ +_S UCES-00842 +_G GoW CoO [EUR] +_C0 60 FPS [Fixed] +_L 0xE00E003C 0x10003800 +_L 0xE00D0200 0x0001A378//Jump-0x10 +_L 0x10003800 0x0000003C +_L 0x20003804 0x10800003 +_L 0x20003808 0x00000000 +_L 0x2000380C 0x0E2C16F9 +_L 0x20003810 0x00000000 +_L 0x20003814 0x0E2C16F9 +_L 0x20003818 0x00000000 +_L 0x2000381C 0x8FBF0010 +_L 0x20003820 0x03E00008 +_L 0x20003824 0x27BD0020 +_L 0x2001A388 0x0A200E01//Jump +_L 0x2001A38C 0x34040000//FPS +_L 0x2001A390 0x00000000 +_C0 30 FPS [Fixed] +_L 0xE00E001E 0x10003800 +_L 0xE00D0200 0x0001A378//Jump-0x10 +_L 0x10003800 0x0000001E +_L 0x20003804 0x10800003 +_L 0x20003808 0x00000000 +_L 0x2000380C 0x0E2C16F9 +_L 0x20003810 0x00000000 +_L 0x20003814 0x0E2C16F9 +_L 0x20003818 0x00000000 +_L 0x2000381C 0x8FBF0010 +_L 0x20003820 0x03E00008 +_L 0x20003824 0x27BD0020 +_L 0x2001A388 0x0A200E01//Jump +_L 0x2001A38C 0x34040001//FPS +_L 0x2001A390 0x00000000 +_C0 Unlimited FPS [Default] +_L 0xE0040E01 0x0001A388 +_L 0x2001A388 0x8FBF0010 +_L 0x2001A38C 0x03E00008 +_L 0x2001A390 0x27BD0020 +_L 0x10003800 0x00000000 \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/UCES01184.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/UCES01184.ini new file mode 100644 index 0000000000..031e0dfb8f --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/UCES01184.ini @@ -0,0 +1,24 @@ +_S UCES-01184 +_G Resistance: Retribution [EUR] +_C0 60FPS v2 [No Vsync] +_L 0xE0030001 0x10003600 +_L 0xE0020003 0x0047F150 +_L 0x2047F158 0x34020001 +_L 0x20003600 0x00000001 +_C0 60FPS v2 [Default] +_L 0xE0030002 0x10003600 +_L 0xE0020003 0x0047F150 +_L 0x2047F158 0x0E31EDB7 +_L 0x20003600 0x00000002 +_C0 30FPS v2 +_L 0xE00A0003 0x10003600 +_L 0xE0090003 0x0047F150 +_L 0x2047F158 0x0E200D81//Jal +_L 0x20003600 0x00000003 +_L 0x20003604 0x03E0D821 +_L 0x20003608 0x0E3674AD//Vb +_L 0x2000360C 0x00000000 +_L 0x20003610 0x0E3674AD//Vb +_L 0x20003614 0x00000000 +_L 0x20003618 0x03600008 +_L 0x2000361C 0x34020001 \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/UCES01401.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/UCES01401.ini new file mode 100644 index 0000000000..390b942d37 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/UCES01401.ini @@ -0,0 +1,40 @@ +_S UCES-01401 +_G GoW GoS [EUR-MULTI5-UMD] +_C0 60 FPS [Fixed] +_L 0xE00E003C 0x10003800 +_L 0xE00DE13C 0x000205DC//vblank +_L 0x10003800 0x0000003C +_L 0x20003804 0x10800003 +_L 0x20003808 0x00000000 +_L 0x2000380C 0x0E2FE13C +_L 0x20003810 0x00000000 +_L 0x20003814 0x0E2FE13C +_L 0x20003818 0x00000000 +_L 0x2000381C 0x8FBF0000 +_L 0x20003820 0x03E00008 +_L 0x20003824 0x27BD0010 +_L 0x2001B10C 0x0A200E01//Jump +_L 0x2001B110 0x34040000//FPS +_L 0x2001B114 0x00000000 +_C0 30 FPS [Fixed] +_L 0xE00E001E 0x10003800 +_L 0xE00DE13C 0x000205DC//vblank +_L 0x10003800 0x0000001E +_L 0x20003804 0x10800003 +_L 0x20003808 0x00000000 +_L 0x2000380C 0x0E2FE13C +_L 0x20003810 0x00000000 +_L 0x20003814 0x0E2FE13C +_L 0x20003818 0x00000000 +_L 0x2000381C 0x8FBF0000 +_L 0x20003820 0x03E00008 +_L 0x20003824 0x27BD0010 +_L 0x2001B10C 0x0A200E01//Jump +_L 0x2001B110 0x34040001//FPS +_L 0x2001B114 0x00000000 +_C0 Unlimited FPS [Default] +_L 0xE0040E01 0x1001B10C +_L 0x2001B10C 0x8FBF0000 +_L 0x2001B110 0x03E00008 +_L 0x2001B114 0x27BD0010 +_L 0x10003800 0x00000000 \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/UCES01473.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/UCES01473.ini new file mode 100644 index 0000000000..5dc49929e5 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/UCES01473.ini @@ -0,0 +1,40 @@ +_S UCES-01473 +_G GoW GoS [EUR-MULTI3-UMD] +_C0 60 FPS [Fixed] +_L 0xE00E003C 0x10003800 +_L 0xE00DE173 0x000205DC//vblank +_L 0x10003800 0x0000003C +_L 0x20003804 0x10800003 +_L 0x20003808 0x00000000 +_L 0x2000380C 0x0E2FE173 +_L 0x20003810 0x00000000 +_L 0x20003814 0x0E2FE173 +_L 0x20003818 0x00000000 +_L 0x2000381C 0x8FBF0000 +_L 0x20003820 0x03E00008 +_L 0x20003824 0x27BD0010 +_L 0x2001B10C 0x0A200E01//Jump +_L 0x2001B110 0x34040000//FPS +_L 0x2001B114 0x00000000 +_C0 30 FPS [Fixed] +_L 0xE00E001E 0x10003800 +_L 0xE00DE173 0x000205DC//vblank +_L 0x10003800 0x0000001E +_L 0x20003804 0x10800003 +_L 0x20003808 0x00000000 +_L 0x2000380C 0x0E2FE173 +_L 0x20003810 0x00000000 +_L 0x20003814 0x0E2FE173 +_L 0x20003818 0x00000000 +_L 0x2000381C 0x8FBF0000 +_L 0x20003820 0x03E00008 +_L 0x20003824 0x27BD0010 +_L 0x2001B10C 0x0A200E01//Jump +_L 0x2001B110 0x34040001//FPS +_L 0x2001B114 0x00000000 +_C0 Unlimited FPS [Default] +_L 0xE0040E01 0x1001B10C +_L 0x2001B10C 0x8FBF0000 +_L 0x2001B110 0x03E00008 +_L 0x2001B114 0x27BD0010 +_L 0x10003800 0x00000000 \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/UCUS98640.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/UCUS98640.ini new file mode 100644 index 0000000000..76c0eb4d9e --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/UCUS98640.ini @@ -0,0 +1,10 @@ +_S UCUS-98640 +_G Pursuit Force [USA] +_C0 60 FPS v2 +_L 0x201AC008 0x0A26B00B//FPS +_L 0x20193928 0x3C043F00//GAMEPLAYSPEED +_L 0x201939A8 0x3C044270//MENUSPEED +_C0 30 FPS v2 [Default] +_L 0x201AC008 0x10800008//FPS +_L 0x20193928 0x3C043F80//GAMEPLAYSPEED +_L 0x201939A8 0x3C0441F0//MENUSPEED \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/UCUS98653.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/UCUS98653.ini new file mode 100644 index 0000000000..fa614adbad --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/UCUS98653.ini @@ -0,0 +1,40 @@ +_S UCUS-98653 +_G GoW CoO [USA] +_C0 60 FPS [Fixed] +_L 0xE00E003C 0x10003800 +_L 0xE00D0200 0x0001A378//Jump-0x10 +_L 0x10003800 0x0000003C +_L 0x20003804 0x10800003 +_L 0x20003808 0x00000000 +_L 0x2000380C 0x0E2C16F9 +_L 0x20003810 0x00000000 +_L 0x20003814 0x0E2C16F9 +_L 0x20003818 0x00000000 +_L 0x2000381C 0x8FBF0010 +_L 0x20003820 0x03E00008 +_L 0x20003824 0x27BD0020 +_L 0x2001A388 0x0A200E01//Jump +_L 0x2001A38C 0x34040000//FPS +_L 0x2001A390 0x00000000 +_C0 30 FPS [Fixed] +_L 0xE00E001E 0x10003800 +_L 0xE00D0200 0x0001A378//Jump-0x10 +_L 0x10003800 0x0000001E +_L 0x20003804 0x10800003 +_L 0x20003808 0x00000000 +_L 0x2000380C 0x0E2C16F9 +_L 0x20003810 0x00000000 +_L 0x20003814 0x0E2C16F9 +_L 0x20003818 0x00000000 +_L 0x2000381C 0x8FBF0010 +_L 0x20003820 0x03E00008 +_L 0x20003824 0x27BD0020 +_L 0x2001A388 0x0A200E01//Jump +_L 0x2001A38C 0x34040001//FPS +_L 0x2001A390 0x00000000 +_C0 Unlimited FPS [Default] +_L 0xE0040E01 0x0001A388 +_L 0x2001A388 0x8FBF0010 +_L 0x2001A38C 0x03E00008 +_L 0x2001A390 0x27BD0020 +_L 0x10003800 0x00000000 \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/UCUS98668.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/UCUS98668.ini new file mode 100644 index 0000000000..c70649b0c6 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/UCUS98668.ini @@ -0,0 +1,24 @@ +_S UCUS-98668 +_G Resistance: Retribution [USA] +_C0 60FPS v2 [No Vsync] +_L 0xE0030001 0x10003600 +_L 0xE0020003 0x0047F150 +_L 0x2047F158 0x34020001 +_L 0x20003600 0x00000001 +_C0 60FPS v2 [Default] +_L 0xE0030002 0x10003600 +_L 0xE0020003 0x0047F150 +_L 0x2047F158 0x0E31EDB7 +_L 0x20003600 0x00000002 +_C0 30FPS v2 +_L 0xE00A0003 0x10003600 +_L 0xE0090003 0x0047F150 +_L 0x2047F158 0x0E200D81//Jal +_L 0x20003600 0x00000003 +_L 0x20003604 0x03E0D821 +_L 0x20003608 0x0E3674AD//Vb +_L 0x2000360C 0x00000000 +_L 0x20003610 0x0E3674AD//Vb +_L 0x20003614 0x00000000 +_L 0x20003618 0x03600008 +_L 0x2000361C 0x34020001 \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/UCUS98737.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/UCUS98737.ini new file mode 100644 index 0000000000..41a9c38029 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/UCUS98737.ini @@ -0,0 +1,40 @@ +_S UCUS-98737 +_G GoW GoS [USA-UMD] +_C1 60 FPS [Fixed] +_L 0xE00E003C 0x10003800 +_L 0xE00DDC67 0x000205DC//vblank +_L 0x10003800 0x0000003C +_L 0x20003804 0x10800003 +_L 0x20003808 0x00000000 +_L 0x2000380C 0x0E2FDC67 +_L 0x20003810 0x00000000 +_L 0x20003814 0x0E2FDC67 +_L 0x20003818 0x00000000 +_L 0x2000381C 0x8FBF0000 +_L 0x20003820 0x03E00008 +_L 0x20003824 0x27BD0010 +_L 0x2001B10C 0x0A200E01//Jump +_L 0x2001B110 0x34040000//FPS +_L 0x2001B114 0x00000000 +_C0 30 FPS [Fixed] +_L 0xE00E001E 0x10003800 +_L 0xE00DDC67 0x000205DC//vblank +_L 0x10003800 0x0000001E +_L 0x20003804 0x10800003 +_L 0x20003808 0x00000000 +_L 0x2000380C 0x0E2FDC67 +_L 0x20003810 0x00000000 +_L 0x20003814 0x0E2FDC67 +_L 0x20003818 0x00000000 +_L 0x2000381C 0x8FBF0000 +_L 0x20003820 0x03E00008 +_L 0x20003824 0x27BD0010 +_L 0x2001B10C 0x0A200E01//Jump +_L 0x2001B110 0x34040001//FPS +_L 0x2001B114 0x00000000 +_C0 Unlimited FPS [Default] +_L 0xE0040E01 0x1001B10C +_L 0x2001B10C 0x8FBF0000 +_L 0x2001B110 0x03E00008 +_L 0x2001B114 0x27BD0010 +_L 0x10003800 0x00000000 \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00033.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00033.ini new file mode 100644 index 0000000000..f89c600b5f --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00033.ini @@ -0,0 +1,10 @@ +_S ULES-00033 +_G Tony Hawk's Underground 2: Remix [EUR-ENG] +_C0 60 FPS +_L 0xE0021080 0x0005F61A +_L 0x2005F618 0x10000017 +_L 0x2000C190 0x00000000 +_C0 30 FPS [Default] +_L 0xE0021000 0x0005F61A +_L 0x2005F618 0x10800017//Vblank +_L 0x2000C190 0x1480FFEE//CtrlBuff \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00034.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00034.ini new file mode 100644 index 0000000000..4772465789 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00034.ini @@ -0,0 +1,10 @@ +ULES-00034 +_G Tony Hawk's Underground 2: Remix [EUR-FR] +_C0 60 FPS +_L 0xE0021080 0x0005F61A +_L 0x2005F618 0x10000017 +_L 0x2000C190 0x00000000 +_C0 30 FPS [Default] +_L 0xE0021000 0x0005F61A +_L 0x2005F618 0x10800017//Vblank +_L 0x2000C190 0x1480FFEE//CtrlBuff \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00035.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00035.ini new file mode 100644 index 0000000000..66485ec7fd --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00035.ini @@ -0,0 +1,10 @@ +_S ULES-00035 +_G Tony Hawk's Underground 2: Remix [EUR-GER] +_C0 60 FPS +_L 0xE0021080 0x0005F61A +_L 0x2005F618 0x10000017 +_L 0x2000C190 0x00000000 +_C0 30 FPS [Default] +_L 0xE0021000 0x0005F61A +_L 0x2005F618 0x10800017//Vblank +_L 0x2000C190 0x1480FFEE//CtrlBuff \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00125.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00125.ini new file mode 100644 index 0000000000..2fc9333c8f --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00125.ini @@ -0,0 +1,15 @@ +_S ULES-00125 +_G Burnout Legends [EUR-v2.00] +_C1 60 FPS v3 +_L 0xE0020003 0x000555D0//conditional +_L 0x200555D0 0x00000000//FPS,1 +_L 0x2024A7FC 0x3C043F00//Speed,EnableBeforeIngame +_L 0xE0010100 0x10441740//Condit,normalGame +_L 0x2000F380 0x14800003//FPS,2 +_L 0xE0010100 0x00441740//Condit,crashMode +_L 0x2000F380 0x16200003//FPS,2 +_C0 30 FPS v3 [Default] +_L 0xE0030000 0x000555D0//conditional +_L 0x200555D0 0x14A00003//FPS,1 +_L 0x2024A7FC 0x3C043F80//Speed,EnableBeforeIngame +_L 0x2000F380 0x14800003//FPS,2 \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00483.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00483.ini new file mode 100644 index 0000000000..e84e8b3cb4 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00483.ini @@ -0,0 +1,7 @@ +_S ULES-00483 +_G The Warriors [EUR] +_C0 60 FPS +_L 0xE001FFF6 0x003B4D84 +_L 0x203B4D84 0x00000000 +_C0 30 FPS [Default] +_L 0x203B4D84 0x1440FFF6 \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00625.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00625.ini new file mode 100644 index 0000000000..f21d010222 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00625.ini @@ -0,0 +1,10 @@ +_S ULES-00625 +_G Tony Hawk's Project 8 [EUR-ENG] +_C0 60 FPS +_L 0xE0021080 0x00096E16 +_L 0x20096E14 0x10000017 +_L 0x20011C28 0x00000000 +_C0 30 FPS [Default] +_L 0xE0021000 0x00096E16 +_L 0x20096E14 0x10800017//Vblank +_L 0x20011C28 0x1480FFEE//CtrlBuff \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00626.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00626.ini new file mode 100644 index 0000000000..1ddbb82782 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00626.ini @@ -0,0 +1,10 @@ +_S ULES-00626 +_G Tony Hawk's Project 8 [EUR-Multi5] +_C0 60 FPS +_L 0xE0021080 0x00096E16 +_L 0x20096E14 0x10000017 +_L 0x20011C28 0x00000000 +_C0 30 FPS [Default] +_L 0xE0021000 0x00096E16 +_L 0x20096E14 0x10800017//Vblank +_L 0x20011C28 0x1480FFEE//CtrlBuff \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00703.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00703.ini new file mode 100644 index 0000000000..652c66050e --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00703.ini @@ -0,0 +1,14 @@ +_S ULES-00703 +_G Burnout Dominator [EUR][MULTI5] +_C0 60 FPS v2 +_L 0xE004001A 0x0002574C +_L 0x2002574C 0x00000000//FPS +_L 0x201A0360 0x00000000//WritesSpeed1 +_L 0x204F08BC 0x3C888888//Speed1 +_L 0x2019AE98 0x3C043F00//Speed2,EnableBeforeIngameOnly +_C0 30 FPS v2 [Default] +_L 0xE0040000 0x0002574C +_L 0x2002574C 0x14A0001A//FPS +_L 0x201A0360 0x089A0360//WritesSpeed1 +_L 0x204F08BC 0x3D088888//Speed1 +_L 0x2019AE98 0x3C043F80//Speed2,EnableBeforeIngameOnly \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00968.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00968.ini new file mode 100644 index 0000000000..e440020e98 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00968.ini @@ -0,0 +1,6 @@ +_S ULES-00968 +_G FlatOut - Head On [EUR] +_C0 60 FPS +_L 0x006FC1F0 0x00000000 +_C0 30 FPS [Default] +_L 0x006FC1F0 0x00000001 \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00981.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00981.ini new file mode 100644 index 0000000000..994966b1bc --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00981.ini @@ -0,0 +1,30 @@ +_S ULES-00981 +_G Star Wars - The Force Unleashed [EUR-Multi3] +_C0 60FPS [Fixed] +_L 0xE0050002 0x004408B4 +_L 0x204408B4 0x00000000//value +_L 0x202B8B2C 0x00000000 +_L 0x203BB968 0x00000000 +_L 0x202B9130 0x00000000 +_L 0x203BC2F0 0x00000000 +_C0 30FPS [Fixed] +_L 0xE0050000 0x004408B4 +_L 0x204408B4 0x00000002//value +_L 0x202B8B2C 0x00000000 +_L 0x203BB968 0x00000000 +_L 0x202B9130 0x00000000 +_L 0x203BC2F0 0x00000000 +_C0 30/60FPS [Default] +_L 0xE0040000 0x002B8B2C +_L 0x202B8B2C 0xAC9308B4//30 +_L 0x203BB968 0xAC8608B4//30 +_L 0x202B9130 0xAC8008B4//60 +_L 0x203BC2F0 0xAC8008B4//60 +_S ULES-00981 +_G Star Wars - The Force Unleashed [EUR-Multi3] +_C0 Red overlay FIX +_L 0xE001ADAE 0x003E9712 +_L 0x203E9710 0xADA00000 +_C0 Red overlay NO-FIX [Default] +_L 0xE001ADA0 0x003E9712 +_L 0x203E9710 0xADAE0000 \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00982.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00982.ini new file mode 100644 index 0000000000..3d0a33daa3 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES00982.ini @@ -0,0 +1,30 @@ +_S ULES-00982 +_G Star Wars - The Force Unleashed [EUR-Multi2] +_C0 60FPS [Fixed] +_L 0xE0050002 0x00440A84 +_L 0x20440A84 0x00000000//value +_L 0x202B8B2C 0x00000000 +_L 0x203BB964 0x00000000 +_L 0x202B9130 0x00000000 +_L 0x203BC2EC 0x00000000 +_C0 30FPS [Fixed] +_L 0xE0050000 0x00440A84 +_L 0x20440A84 0x00000002//value +_L 0x202B8B2C 0x00000000 +_L 0x203BB964 0x00000000 +_L 0x202B9130 0x00000000 +_L 0x203BC2EC 0x00000000 +_C0 30/60FPS [Default] +_L 0xE0040000 0x002B8B2C +_L 0x202B8B2C 0xAC930A84//30 +_L 0x203BB964 0xAC860A84//30 +_L 0x202B9130 0xAC800A84//60 +_L 0x203BC2EC 0xAC800A84//60 +_S ULES-00982 +_G Star Wars - The Force Unleashed [EUR-Multi2] +_C0 Red overlay FIX +_L 0xE001ADAE 0x003E9882 +_L 0x203E9880 0xADA00000 +_C0 Red overlay NO-FIX [Default] +_L 0xE001ADA0 0x003E9882 +_L 0x203E9880 0xADAE0000 \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES01214.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES01214.ini new file mode 100644 index 0000000000..350b782627 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES01214.ini @@ -0,0 +1,11 @@ +_S ULES-01214 +_G Star Wars Battlefront - Elite Squadron [EUR] +_C0 60 FPS +_L 0x20456718 0x42700000 +_C0 45 FPS +_L 0x20456718 0x42340000 +_C0 40 FPS +_L 0x20456718 0x42200000 +_C0 30 FPS +_L 0x20456718 0x41F00000 +_C0 20 FPS [Default] \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES01402.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES01402.ini new file mode 100644 index 0000000000..95d2f1c697 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES01402.ini @@ -0,0 +1,8 @@ +_S ULES-01402 +_G Split/Second - Velocity [EUR] +_C0 60 FPS +_L 0x0018A790 0x00000001 +_C0 30 FPS [Default] +_L 0x0018A790 0x00000002 +_C0 20 FPS +_L 0x0018A790 0x00000003 \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES01406.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES01406.ini new file mode 100644 index 0000000000..3a93436dad --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULES01406.ini @@ -0,0 +1,6 @@ +_S ULES-01406 +_G Toy Story 3 [EUR][MULTI2] +_C0 60 FPS +_L 0x202E7934 0x00000000 +_C0 30 FPS [Default] +_L 0x202E7934 0x1080FFFB \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULUS00125.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULUS00125.ini new file mode 100644 index 0000000000..fb37e5b8b7 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULUS00125.ini @@ -0,0 +1,15 @@ +_S ULUS-00125 / ULES-00125 +_G Burnout Legends [USA-v2.00] +_C1 60 FPS v3 +_L 0xE0020003 0x000555D0//conditional +_L 0x200555D0 0x00000000//FPS,1 +_L 0x2024A7FC 0x3C043F00//Speed,EnableBeforeIngame +_L 0xE0010100 0x10441740//Condit,normalGame +_L 0x2000F380 0x14800003//FPS,2 +_L 0xE0010100 0x00441740//Condit,crashMode +_L 0x2000F380 0x16200003//FPS,2 +_C0 30 FPS v3 [Default] +_L 0xE0030000 0x000555D0//conditional +_L 0x200555D0 0x14A00003//FPS,1 +_L 0x2024A7FC 0x3C043F80//Speed,EnableBeforeIngame +_L 0x2000F380 0x14800003//FPS,2 \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULUS10014.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULUS10014.ini new file mode 100644 index 0000000000..19434ecf32 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULUS10014.ini @@ -0,0 +1,10 @@ +_S ULUS-10014 +_G Tony Hawk's Underground 2: Remix [USA] +_C1 60 FPS +_L 0xE0021080 0x0005F642 +_L 0x2005F640 0x10000017 +_L 0x2000C190 0x00000000 +_C0 30 FPS [Default] +_L 0xE0021000 0x0005F642 +_L 0x2005F640 0x10800017//Vblank +_L 0x2000C190 0x1480FFEE//CtrlBuff \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULUS10189.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULUS10189.ini new file mode 100644 index 0000000000..56b2311dcf --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULUS10189.ini @@ -0,0 +1,9 @@ +_S ULUS-10189 +_G Snoopy vs the Red Baron [USA] +_C1 60 FPS +_L 0xE0010000 0x1023F394 +_L 0x204C6940 0x3F000000 +_L 0x0023F394 0x00000000 +_C0 30 FPS [Default] +_L 0x204C6940 0x3F800000 +_L 0x0023F394 0x00000001 \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULUS10197.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULUS10197.ini new file mode 100644 index 0000000000..2b62c5435d --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULUS10197.ini @@ -0,0 +1,10 @@ +_S ULUS-10197 +_G Tony Hawk's Project 8 [USA-UMDv1.0] +_C0 60 FPS +_L 0xE0021080 0x00097156 +_L 0x20097154 0x10000017 +_L 0x20011C28 0x00000000 +_C0 30 FPS [Default] +_L 0xE0021000 0x00097156 +_L 0x20097154 0x10800017//Vblank +_L 0x20011C28 0x1480FFEE//CtrlBuff \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULUS10213.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULUS10213.ini new file mode 100644 index 0000000000..7d89a978d6 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULUS10213.ini @@ -0,0 +1,7 @@ +_S ULUS-10213 +_G The Warriors [USA] +_C1 60 FPS +_L 0xE001FFF6 0x003B517C +_L 0x203B517C 0x00000000 +_C0 30 FPS [Default] +_L 0x203B517C 0x1440FFF6 \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULUS10236.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULUS10236.ini new file mode 100644 index 0000000000..64da0ba1cb --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULUS10236.ini @@ -0,0 +1,14 @@ +_S ULUS-10236 +_G Burnout Dominator [USA] +_C0 60 FPS v2 +_L 0xE004001A 0x0002574C +_L 0x2002574C 0x00000000//FPS +_L 0x201A0358 0x00000000//WritesSpeed1 +_L 0x204F08BC 0x3C888888//Speed1 +_L 0x2019AE90 0x3C043F00//Speed2,EnableBeforeIngameOnly +_C0 30 FPS v2 [Default] +_L 0xE0040000 0x0002574C +_L 0x2002574C 0x14A0001A//FPS +_L 0x201A0358 0xE60C0034//WritesSpeed1 +_L 0x204F08BC 0x3D088888//Speed1 +_L 0x2019AE90 0x3C043F80//Speed2,EnableBeforeIngameOnly \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULUS10328.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULUS10328.ini new file mode 100644 index 0000000000..794f4823d6 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULUS10328.ini @@ -0,0 +1,6 @@ +_S ULUS-10328 +_G FlatOut - Head On [USA] +_C0 60 FPS +_L 0x006FC0F0 0x00000000 +_C0 30 FPS [Default] +_L 0x006FC0F0 0x00000001 \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULUS10345.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULUS10345.ini new file mode 100644 index 0000000000..befe16bde8 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULUS10345.ini @@ -0,0 +1,30 @@ +_S ULUS-10345 +_G Star Wars - The Force Unleashed [USA] +_C0 60FPS [Fixed] +_L 0xE0050002 0x00440664 +_L 0x20440664 0x00000000//value +_L 0x202B8A14 0x00000000 +_L 0x203BB714 0x00000000 +_L 0x202B9018 0x00000000 +_L 0x203BC09C 0x00000000 +_C0 30FPS [Fixed] +_L 0xE0050000 0x00440664 +_L 0x20440664 0x00000002//value +_L 0x202B8A14 0x00000000 +_L 0x203BB714 0x00000000 +_L 0x202B9018 0x00000000 +_L 0x203BC09C 0x00000000 +_C0 30/60FPS [Default] +_L 0xE0040000 0x002B8A14 +_L 0x202B8A14 0xAC930664//30 +_L 0x203BB714 0xAC860664//30 +_L 0x202B9018 0xAC800664//60 +_L 0x203BC09C 0xAC800664//60 +_S ULUS-10345 +_G Star Wars - The Force Unleashed [USA] +_C0 Red overlay FIX +_L 0xE001ADAE 0x003E94BE +_L 0x203E94BC 0xADA00000 +_C0 Red overlay NO-FIX [Default] +_L 0xE001ADA0 0x003E94BE +_L 0x203E94BC 0xADAE0000 \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULUS10390.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULUS10390.ini new file mode 100644 index 0000000000..ea9aa6c92b --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULUS10390.ini @@ -0,0 +1,12 @@ +_S ULUS-10390 +_G Star Wars Battlefront - Elite Squadron [USA] +_C0 60 FPS +_L 0x20456598 0x42700000 +_C0 45 FPS +_L 0x20456598 0x42340000 +_C0 40 FPS +_L 0x20456598 0x42200000 +_C0 30 FPS +_L 0x20456598 0x41F00000 +_C0 20 FPS [Default] +_L 0x20456598 0x41A00000 \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULUS10507.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULUS10507.ini new file mode 100644 index 0000000000..30770423e7 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/Cheats/ULUS10507.ini @@ -0,0 +1,6 @@ +_S ULUS-10507 +_G Toy Story 3 [USA] +_C1 60 FPS +_L 0x202E77CC 0x00000000 +_C0 30 FPS [Default] +_L 0x202E77CC 0x1080FFFB \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/SYSTEM/CACHE/UCAS40015.glshadercache b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/SYSTEM/CACHE/UCAS40015.glshadercache new file mode 100644 index 0000000000..af57dc9549 Binary files /dev/null and b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/SYSTEM/CACHE/UCAS40015.glshadercache differ diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/SYSTEM/CACHE/ULJM05600.glshadercache b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/SYSTEM/CACHE/ULJM05600.glshadercache new file mode 100644 index 0000000000..411b76175d Binary files /dev/null and b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/PSP/SYSTEM/CACHE/ULJM05600.glshadercache differ diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/assets/NotoSansJP-Regular.ttf b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/assets/NotoSansJP-Regular.ttf new file mode 100644 index 0000000000..1583096a2d Binary files /dev/null and b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/config/assets/NotoSansJP-Regular.ttf differ diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/package.mk b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/package.mk new file mode 100644 index 0000000000..f62b81a0e1 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/package.mk @@ -0,0 +1,106 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2019-present Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="ppsspp-sa" +PKG_SITE="https://github.com/hrydgard/ppsspp" +PKG_URL="${PKG_SITE}.git" +PKG_VERSION="eb859735feddf88dbe651763f366a7705612113a" # v1.20.1 +CHEAT_DB_VERSION="7c9fe1ae71155626cea767aed53f968de9f4051f" # Update cheat.db (17/01/2026) +PKG_LICENSE="GPLv2" +PKG_DEPENDS_TARGET="toolchain libzip SDL2 zlib zip" +PKG_LONGDESC="PPSSPPDL" +GET_HANDLER_SUPPORT="git" + +### Note: +### This package includes the NotoSansJP-Regular.ttf font. This font is licensed under +### SIL Open Font License, Version 1.1. The license can be found in the licenses +### directory in the root of this project, OFL.txt. +### + +PKG_PATCH_DIRS+="${DEVICE}" + +PKG_CMAKE_OPTS_TARGET=" -DUSE_SYSTEM_FFMPEG=OFF \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_SYSTEM_NAME=Linux \ + -DBUILD_SHARED_LIBS=OFF \ + -DUSE_SYSTEM_LIBPNG=OFF \ + -DANDROID=OFF \ + -DWIN32=OFF \ + -DAPPLE=OFF \ + -DCMAKE_CROSSCOMPILING=ON \ + -DUSING_QT_UI=OFF \ + -DUNITTEST=OFF \ + -DSIMULATOR=OFF \ + -DHEADLESS=OFF \ + -DUSE_DISCORD=OFF" + +if [ "${OPENGL_SUPPORT}" = "yes" ] && [ ! "${PREFER_GLES}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd glew" + PKG_CMAKE_OPTS_TARGET+=" -DUSING_FBDEV=OFF \ + -DUSING_GLES2=OFF" + +elif [ "${OPENGLES_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" + PKG_CMAKE_OPTS_TARGET+=" -DUSING_FBDEV=ON \ + -DUSING_EGL=OFF \ + -DUSING_GLES2=ON" +fi + +if [ "${VULKAN_SUPPORT}" = "yes" ] +then + PKG_DEPENDS_TARGET+=" ${VULKAN}" + PKG_CMAKE_OPTS_TARGET+=" -DUSE_VULKAN_DISPLAY_KHR=ON \ + -DVULKAN=ON \ + -DEGL_NO_X11=1 \ + -DMESA_EGL_NO_X11_HEADERS=1" + GRENDERER="3 (VULKAN)" +else + PKG_CMAKE_OPTS_TARGET+=" -DVULKAN=OFF \ + -DUSE_VULKAN_DISPLAY_KHR=OFF \ + -DUSING_X11_VULKAN=OFF" + GRENDERER="0 (OPENGL)" +fi + +if [ "${DISPLAYSERVER}" = "wl" ]; then + PKG_DEPENDS_TARGET+=" wayland ${WINDOWMANAGER}" + PKG_CMAKE_OPTS_TARGET+=" -DUSE_WAYLAND_WSI=ON" +else + PKG_CMAKE_OPTS_TARGET+=" -DUSE_WAYLAND_WSI=OFF" +fi + +pre_configure_target() { + sed -i 's/\-O[23]//g' ${PKG_BUILD}/CMakeLists.txt + sed -i "s|include_directories(/usr/include/drm)|include_directories(${SYSROOT_PREFIX}/usr/include/drm)|" ${PKG_BUILD}/CMakeLists.txt +} + +pre_make_target() { + export CPPFLAGS="${CPPFLAGS} -Wno-error" + export CFLAGS="${CFLAGS} -Wno-error" + + # fix cross compiling + find ${PKG_BUILD} -name flags.make -exec sed -i "s:isystem :I:g" \{} \; + find ${PKG_BUILD} -name build.ninja -exec sed -i "s:isystem :I:g" \{} \; +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp ${PKG_DIR}/scripts/* ${INSTALL}/usr/bin + cp PPSSPPSDL ${INSTALL}/usr/bin/ppsspp + chmod 0755 ${INSTALL}/usr/bin/* + ln -sf /storage/.config/ppsspp/assets ${INSTALL}/usr/bin/assets + mkdir -p ${INSTALL}/usr/config/ppsspp/PSP/SYSTEM + cp -r `find . -name "assets" | xargs echo` ${INSTALL}/usr/config/ppsspp/ + cp -rf ${PKG_DIR}/config/* ${INSTALL}/usr/config/ppsspp/ + if [ -d "${PKG_DIR}/sources/${DEVICE}" ] + then + cp ${PKG_DIR}/sources/${DEVICE}/* ${INSTALL}/usr/config/ppsspp/PSP/SYSTEM + fi + rm ${INSTALL}/usr/config/ppsspp/assets/gamecontrollerdb.txt + ln -sf NotoSansJP-Regular.ttf ${INSTALL}/usr/config/ppsspp/assets/Roboto-Condensed.ttf + curl -Lo ${INSTALL}/usr/config/ppsspp/PSP/Cheats/cheat.db https://raw.githubusercontent.com/Saramagrean/CWCheat-Database-Plus-/${CHEAT_DB_VERSION}/cheat.db +} + +post_install() { + sed -e "s/@GRENDERER@/${GRENDERER}/g" -i ${INSTALL}/usr/bin/start_ppsspp.sh +} diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/patches/001-do-not-mute.patch b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/patches/001-do-not-mute.patch new file mode 100644 index 0000000000..8a0700bcde --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/patches/001-do-not-mute.patch @@ -0,0 +1,17 @@ +diff --git a/Core/Config.cpp b/Core/Config.cpp +index 4f6ee43dce..e61e3eda4c 100644 +--- a/Core/Config.cpp ++++ b/Core/Config.cpp +@@ -1616,12 +1616,6 @@ void Config::PostLoadCleanup() { + g_Config.bSkipBufferEffects = false; + } + +- // Automatically silence secondary instances. Could be an option I guess, but meh. +- if (PPSSPP_ID > 1) { +- NOTICE_LOG(Log::Audio, "Secondary instance %d - silencing audio", (int)PPSSPP_ID); +- g_Config.iGameVolume = 0; +- } +- + // Automatically switch away from deprecated setting value. + if (iTexScalingLevel <= 0) { + iTexScalingLevel = 1; diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/patches/002-fullscreen-drm.patch b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/patches/002-fullscreen-drm.patch new file mode 100644 index 0000000000..e4be2a1120 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/patches/002-fullscreen-drm.patch @@ -0,0 +1,99 @@ +diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp +index 04c16ca7a0..cecc4b7f0f 100644 +--- a/SDL/SDLMain.cpp ++++ b/SDL/SDLMain.cpp +@@ -824,9 +824,9 @@ void UpdateWindowState(SDL_Window *window) { + + Uint32 window_flags = SDL_GetWindowFlags(window); + if (g_Config.bFullScreen) { +- window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; ++ window_flags |= SDL_WINDOW_FULLSCREEN; + } else { +- window_flags &= ~SDL_WINDOW_FULLSCREEN_DESKTOP; ++ window_flags &= ~SDL_WINDOW_FULLSCREEN; + } + SDL_SetWindowFullscreen(window, window_flags); + } +@@ -956,7 +956,7 @@ static void ProcessSDLEvent(SDL_Window *window, const SDL_Event &event, InputSta + Native_NotifyWindowHidden(false); + + Uint32 window_flags = SDL_GetWindowFlags(window); +- bool fullscreen = (window_flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_FULLSCREEN_DESKTOP)); ++ bool fullscreen = (window_flags & (SDL_WINDOW_FULLSCREEN)); + + // This one calls NativeResized if the size changed. + Native_UpdateScreenScale(new_width_px, new_height_px, UIScaleFactorToMultiplier(g_Config.iUIScaleFactor)); +@@ -986,7 +986,7 @@ static void ProcessSDLEvent(SDL_Window *window, const SDL_Event &event, InputSta + case SDL_WINDOWEVENT_MOVED: + { + Uint32 window_flags = SDL_GetWindowFlags(window); +- bool fullscreen = (window_flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_FULLSCREEN_DESKTOP)); ++ bool fullscreen = (window_flags & (SDL_WINDOW_FULLSCREEN)); + if (!fullscreen) { + g_Config.iWindowX = (int)event.window.data1; + g_Config.iWindowY = (int)event.window.data2; +@@ -1466,7 +1466,7 @@ int main(int argc, char *argv[]) { + Uint32 mode = 0; + for (int i = 1; i < argc; i++) { + if (!strcmp(argv[i], "--fullscreen")) { +- mode |= SDL_WINDOW_FULLSCREEN_DESKTOP; ++ mode |= SDL_WINDOW_FULLSCREEN; + g_Config.DoNotSaveSetting(&g_Config.bFullScreen); + } else if (set_xres == -2) + set_xres = parseInt(argv[i]); +@@ -1559,19 +1559,19 @@ int main(int argc, char *argv[]) { + + // Force fullscreen if the resolution is too low to run windowed. + if (g_DesktopWidth < 480 * 2 && g_DesktopHeight < 272 * 2) { +- mode |= SDL_WINDOW_FULLSCREEN_DESKTOP; ++ mode |= SDL_WINDOW_FULLSCREEN; + } + + // If we're on mobile, don't try for windowed either. + #if defined(MOBILE_DEVICE) && !PPSSPP_PLATFORM(SWITCH) + mode |= SDL_WINDOW_FULLSCREEN; + #elif defined(USING_FBDEV) || PPSSPP_PLATFORM(SWITCH) +- mode |= SDL_WINDOW_FULLSCREEN_DESKTOP; ++ mode |= SDL_WINDOW_FULLSCREEN; + #else + mode |= SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI; + #endif + +- if (mode & SDL_WINDOW_FULLSCREEN_DESKTOP) { ++ if (mode & SDL_WINDOW_FULLSCREEN) { + g_display.pixel_xres = g_DesktopWidth; + g_display.pixel_yres = g_DesktopHeight; + g_Config.bFullScreen = true; +@@ -1634,7 +1634,7 @@ int main(int argc, char *argv[]) { + + // Use the setting from the config when initing the window. + if (g_Config.bFullScreen) { +- mode |= SDL_WINDOW_FULLSCREEN_DESKTOP; ++ mode |= SDL_WINDOW_FULLSCREEN; + g_display.pixel_xres = g_DesktopWidth; + g_display.pixel_yres = g_DesktopHeight; + } +diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp +index d7a97347b1..531997fba0 100644 +--- a/UI/MainScreen.cpp ++++ b/UI/MainScreen.cpp +@@ -1454,19 +1454,6 @@ void MainScreen::CreateViews() { + LinearLayout *rightColumnItems = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)); + rightColumnItems->SetSpacing(0.0f); + ViewGroup *logo = new LogoView(false, new LinearLayoutParams(FILL_PARENT, 80.0f)); +-#if !defined(MOBILE_DEVICE) +- auto gr = GetI18NCategory(I18NCat::GRAPHICS); +- ImageID icon(g_Config.bFullScreen ? "I_RESTORE" : "I_FULLSCREEN"); +- UI::Button *fullscreenButton = logo->Add(new Button("", icon, new AnchorLayoutParams(48, 48, NONE, 0, 0, NONE, Centering::None))); +- fullscreenButton->SetIgnoreText(true); +- fullscreenButton->OnClick.Add([fullscreenButton](UI::EventParams &e) { +- if (fullscreenButton) { +- fullscreenButton->SetImageID(ImageID(!g_Config.bFullScreen ? "I_RESTORE" : "I_FULLSCREEN")); +- } +- g_Config.bFullScreen = !g_Config.bFullScreen; +- System_ApplyFullscreenState(); +- }); +-#endif + rightColumnItems->Add(logo); + + LinearLayout *rightColumnChoices = rightColumnItems; diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/patches/003-disable-mouse.patch b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/patches/003-disable-mouse.patch new file mode 100644 index 0000000000..8bb2544ed3 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/patches/003-disable-mouse.patch @@ -0,0 +1,28 @@ +diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp +index 04c16ca7a0..f2ae555923 100644 +--- a/SDL/SDLMain.cpp ++++ b/SDL/SDLMain.cpp +@@ -974,12 +974,7 @@ static void ProcessSDLEvent(SDL_Window *window, const SDL_Event &event, InputSta + g_Config.iWindowWidth = new_width; + g_Config.iWindowHeight = new_height; + } +- // Hide/Show cursor correctly toggling fullscreen +- if (lastUIState == UISTATE_INGAME && fullscreen && !g_Config.bShowTouchControls) { +- SDL_ShowCursor(SDL_DISABLE); +- } else if (lastUIState != UISTATE_INGAME || !fullscreen) { +- SDL_ShowCursor(SDL_ENABLE); +- } ++ SDL_ShowCursor(SDL_DISABLE); + break; + } + +@@ -1746,9 +1741,7 @@ int main(int argc, char *argv[]) { + // OK, we have a valid graphics backend selected. Let's clear the failures. + g_Config.sFailedGPUBackends.clear(); + +-#ifdef MOBILE_DEVICE + SDL_ShowCursor(SDL_DISABLE); +-#endif + + // Avoid the IME popup when holding keys. This doesn't affect all versions of SDL. + // Note: We re-enable it in text input fields! This is necessary otherwise we don't receive diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/patches/004-set-paths.patch b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/patches/004-set-paths.patch new file mode 100644 index 0000000000..d31dce81b5 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/patches/004-set-paths.patch @@ -0,0 +1,125 @@ +diff --git a/Core/Config.cpp b/Core/Config.cpp +index 4f6ee43dce..188bbca207 100644 +--- a/Core/Config.cpp ++++ b/Core/Config.cpp +@@ -1271,7 +1271,7 @@ void Config::UpdateIniLocation(const char *iniFileName, const char *controllerIn + const bool useIniFilename = iniFileName != nullptr && strlen(iniFileName) > 0; + const char *ppssppIniFilename = IsVREnabled() ? "ppssppvr.ini" : "ppsspp.ini"; + bool exists; +- iniFilename_ = FindConfigFile(searchPath_, useIniFilename ? iniFileName : ppssppIniFilename, &exists); ++ iniFilename_ = Path("/storage/.config/ppsspp/PSP/SYSTEM") / ppssppIniFilename; + const bool useControllerIniFilename = controllerIniFilename != nullptr && strlen(controllerIniFilename) > 0; + const char *controlsIniFilename = IsVREnabled() ? "controlsvr.ini" : "controls.ini"; + controllerIniFilename_ = FindConfigFile(searchPath_, useControllerIniFilename ? controllerIniFilename : controlsIniFilename, &exists); +diff --git a/Core/Util/PathUtil.cpp b/Core/Util/PathUtil.cpp +index a82bc95fe6..4c1a926cd8 100644 +--- a/Core/Util/PathUtil.cpp ++++ b/Core/Util/PathUtil.cpp +@@ -42,14 +42,8 @@ Path FindConfigFile(const Path &searchPath, std::string_view baseFilename, bool + } + + Path GetSysDirectory(PSPDirectories directoryType) { +- const Path &memStickDirectory = g_Config.memStickDirectory; +- Path pspDirectory; +- if (!strcasecmp(memStickDirectory.GetFilename().c_str(), "PSP")) { +- // Let's strip this off, to easily allow choosing a root directory named "PSP" on Android. +- pspDirectory = memStickDirectory; +- } else { +- pspDirectory = memStickDirectory / "PSP"; +- } ++ Path memStickDirectory = Path("/storage/roms/psp/"); ++ Path pspDirectory = Path("/storage/.config/ppsspp/PSP/"); + + switch (directoryType) { + case DIRECTORY_PSP: +@@ -59,9 +53,9 @@ Path GetSysDirectory(PSPDirectories directoryType) { + case DIRECTORY_GAME: + return pspDirectory / "GAME"; + case DIRECTORY_SAVEDATA: +- return pspDirectory / "SAVEDATA"; ++ return Path("/storage/roms/psp/"); + case DIRECTORY_SCREENSHOT: +- return pspDirectory / "SCREENSHOT"; ++ return Path("/storage/roms/screenshots/"); + case DIRECTORY_SYSTEM: + return pspDirectory / "SYSTEM"; + case DIRECTORY_PAUTH: +@@ -71,7 +65,7 @@ Path GetSysDirectory(PSPDirectories directoryType) { + case DIRECTORY_DUMP: + return pspDirectory / "SYSTEM/DUMP"; + case DIRECTORY_SAVESTATE: +- return pspDirectory / "PPSSPP_STATE"; ++ return Path("/storage/roms/savestates/psp/ppsspp-sa"); + case DIRECTORY_CACHE: + return pspDirectory / "SYSTEM/CACHE"; + case DIRECTORY_TEXTURES: +@@ -93,11 +87,11 @@ Path GetSysDirectory(PSPDirectories directoryType) { + return pspDirectory / "themes"; + + case DIRECTORY_MEMSTICK_ROOT: +- return g_Config.memStickDirectory; ++ return memStickDirectory; + // Just return the memory stick root if we run into some sort of problem. + default: + ERROR_LOG(Log::FileSystem, "Unknown directory type."); +- return g_Config.memStickDirectory; ++ return pspDirectory; + } + } + +diff --git a/SDL/SDLJoystick.cpp b/SDL/SDLJoystick.cpp +index 290cf57ce1..5d2e13da4d 100644 +--- a/SDL/SDLJoystick.cpp ++++ b/SDL/SDLJoystick.cpp +@@ -24,7 +24,7 @@ SDLJoystick::SDLJoystick(bool init_SDL ) : registeredAsEventHandler(false) { + SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER); + } + +- const char *dbPath = "gamecontrollerdb.txt"; ++ const char *dbPath = "/storage/.config/SDL-GameControllerDB/gamecontrollerdb.txt"; + INFO_LOG(Log::System, "loading control pad mappings from %s:", dbPath); + + size_t size; +@@ -33,7 +33,7 @@ SDLJoystick::SDLJoystick(bool init_SDL ) : registeredAsEventHandler(false) { + SDL_RWops *rw = SDL_RWFromConstMem(mappingData, size); + // 1 to free the rw after use + if (SDL_GameControllerAddMappingsFromRW(rw, 1) == -1) { +- ERROR_LOG(Log::System, "Failed to read mapping data - corrupt?"); ++ ERROR_LOG(Log::System, "/storage/.config/SDL-GameControllerDB/gamecontrollerdb.txt missing"); + } + delete[] mappingData; + } else { +diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp +index 84596b04ec..8e89a7bb13 100644 +--- a/UI/NativeApp.cpp ++++ b/UI/NativeApp.cpp +@@ -367,7 +367,7 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch + #if !defined(MOBILE_DEVICE) && !defined(_WIN32) && !PPSSPP_PLATFORM(SWITCH) + g_VFS.Register("", new DirectoryReader(File::GetExeDirectory() / "assets")); + g_VFS.Register("", new DirectoryReader(File::GetExeDirectory())); +- g_VFS.Register("", new DirectoryReader(Path("/usr/local/share/ppsspp/assets"))); ++ g_VFS.Register("", new DirectoryReader(Path("/storage/.config/ppsspp/assets"))); + g_VFS.Register("", new DirectoryReader(Path("/usr/local/share/games/ppsspp/assets"))); + g_VFS.Register("", new DirectoryReader(Path("/usr/share/ppsspp/assets"))); + g_VFS.Register("", new DirectoryReader(Path("/usr/share/games/ppsspp/assets"))); +@@ -474,7 +474,7 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch + else // Just in case + config = "./config"; + +- g_Config.memStickDirectory = Path(config) / "ppsspp"; ++ g_Config.memStickDirectory = Path("/storage/roms/psp/"); + g_Config.flash0Directory = File::GetExeDirectory() / "assets/flash0"; + if (getenv("HOME") != nullptr) { + g_Config.defaultCurrentDirectory = Path(getenv("HOME")); +index a8300543d..37c12caa4 100644 +--- a/Core/SaveState.cpp ++++ b/Core/SaveState.cpp +@@ -333,7 +333,7 @@ int g_screenshotFailures; + } + + std::string GetGamePrefix(const ParamSFOData ¶mSFO) { +- return GenerateFullDiscId(paramSFO); ++ return PSP_CoreParameter().fileToStart.WithReplacedExtension("").GetFilename(); + } + + // The prefix is always based on GenerateFullDiscId. So we can find these by scanning, too. diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/patches/SM8250/000-swap-guid-and-misc.patch b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/patches/SM8250/000-swap-guid-and-misc.patch new file mode 100644 index 0000000000..0aa3aee6e1 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/patches/SM8250/000-swap-guid-and-misc.patch @@ -0,0 +1,22 @@ +diff --git a/SDL/SDLJoystick.cpp b/SDL/SDLJoystick.cpp +index 94a6f481ba..977617b77d 100644 +--- a/SDL/SDLJoystick.cpp ++++ b/SDL/SDLJoystick.cpp +@@ -141,7 +141,7 @@ InputKeyCode SDLJoystick::getKeycodeForButton(SDL_GameControllerButton button) { + case SDL_CONTROLLER_BUTTON_BACK: + return NKCODE_BUTTON_9; // select button + case SDL_CONTROLLER_BUTTON_GUIDE: +- return NKCODE_BACK; // pause menu ++ return NKCODE_BUTTON_11; + case SDL_CONTROLLER_BUTTON_LEFTSTICK: + return NKCODE_BUTTON_THUMBL; + case SDL_CONTROLLER_BUTTON_RIGHTSTICK: +@@ -150,7 +150,7 @@ InputKeyCode SDLJoystick::getKeycodeForButton(SDL_GameControllerButton button) { + // Found these limits by checking out the SDL2 branch of the SDL repo, doing git blame, then `git tag --contains (commit)` etc. + #if SDL_VERSION_ATLEAST(2, 0, 16) + case SDL_CONTROLLER_BUTTON_MISC1: +- return NKCODE_BUTTON_11; ++ return NKCODE_BACK; // pause menu + #endif + #if SDL_VERSION_ATLEAST(2, 0, 28) + case SDL_CONTROLLER_BUTTON_PADDLE1: diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/patches/SM8550/000-swap-guid-and-misc.patch b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/patches/SM8550/000-swap-guid-and-misc.patch new file mode 100644 index 0000000000..0aa3aee6e1 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/patches/SM8550/000-swap-guid-and-misc.patch @@ -0,0 +1,22 @@ +diff --git a/SDL/SDLJoystick.cpp b/SDL/SDLJoystick.cpp +index 94a6f481ba..977617b77d 100644 +--- a/SDL/SDLJoystick.cpp ++++ b/SDL/SDLJoystick.cpp +@@ -141,7 +141,7 @@ InputKeyCode SDLJoystick::getKeycodeForButton(SDL_GameControllerButton button) { + case SDL_CONTROLLER_BUTTON_BACK: + return NKCODE_BUTTON_9; // select button + case SDL_CONTROLLER_BUTTON_GUIDE: +- return NKCODE_BACK; // pause menu ++ return NKCODE_BUTTON_11; + case SDL_CONTROLLER_BUTTON_LEFTSTICK: + return NKCODE_BUTTON_THUMBL; + case SDL_CONTROLLER_BUTTON_RIGHTSTICK: +@@ -150,7 +150,7 @@ InputKeyCode SDLJoystick::getKeycodeForButton(SDL_GameControllerButton button) { + // Found these limits by checking out the SDL2 branch of the SDL repo, doing git blame, then `git tag --contains (commit)` etc. + #if SDL_VERSION_ATLEAST(2, 0, 16) + case SDL_CONTROLLER_BUTTON_MISC1: +- return NKCODE_BUTTON_11; ++ return NKCODE_BACK; // pause menu + #endif + #if SDL_VERSION_ATLEAST(2, 0, 28) + case SDL_CONTROLLER_BUTTON_PADDLE1: diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/scripts/cheevos_ppsspp.sh b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/scripts/cheevos_ppsspp.sh new file mode 100644 index 0000000000..736b642fc6 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/scripts/cheevos_ppsspp.sh @@ -0,0 +1,62 @@ +#! /bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present Hector Calvarro (https://github.com/kelvfimer) +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile + +PPSSPP_ACHIEVEMENTS="/storage/.config/ppsspp/PSP/SYSTEM/ppsspp_retroachievements.dat" +PPSSPP_INI="/storage/.config/ppsspp/PSP/SYSTEM/ppsspp.ini" +LOG_FILE="/var/log/cheevos.log" + +# Extract username, password, token, if enabled, and hardcore mode from system.cfg +username=$(get_setting "global.retroachievements.username") +password=$(get_setting "global.retroachievements.password") +token=$(get_setting "global.retroachievements.token") +enabled=$(get_setting "global.retroachievements") +hardcore=$(get_setting "global.retroachievements.hardcore") + +# Check if RetroAchievements are enabled in Emulation Station +if [ ! ${enabled} = 1 ]; then + echo "RetroAchievements are not enabled, please turn them on in Emulation Station." > ${LOG_FILE} + sed -i '/^AchievementsEnable =/c\AchievementsEnable = False' ${PPSSPP_INI} + exit 1 +fi + +# Check if api token is present in system.cfg +if [ -z "${token}" ]; then + echo "RetroAchievements token is empty, please log in with your RetroAchievements credentials in Emulation Station." > ${LOG_FILE} + exit 1 +fi + +echo "${token}" > ${PPSSPP_ACHIEVEMENTS} + +# Set hardcore mode +if [ "${hardcore}" = 1 ]; then + hardcore="True" +else + hardcore="False" +fi + +# Update emulator config with RetroAchievements settings +zcheevos=$(grep -Fx "[Achievements]" ${PPSSPP_INI}) +echo "${token}" > ${PPSSPP_ACHIEVEMENTS} + +if [ -z "${zcheevos}" ] +then + echo -e "[Achievements]\nAchievementsEnable = True\nAchievementsUserName = ${username}\nAchievementsChallengeMode = ${hardcore}" >> ${PPSSPP_INI} +else + sed -i '/^AchievementsEnable =/c\AchievementsEnable = True' ${PPSSPP_INI} + if ! grep -q "^AchievementsUserName = " ${PPSSPP_INI}; then + sed -i "/^\[Achievements\]/a AchievementsUserName = ${username}" ${PPSSPP_INI} + else + sed -i "/^\[Achievements\]/,/^\[/{s/^AchievementsUserName = .*/AchievementsUserName = ${username}/;}" ${PPSSPP_INI} + fi + + if ! grep -q "^AchievementsChallengeMode = " ${PPSSPP_INI}; then + sed -i "/^\[Achievements\]/a AchievementsChallengeMode = ${hardcore}" ${PPSSPP_INI} + else + sed -i "/^\[Achievements\]/,/^\[/{s/^AchievementsChallengeMode = .*/AchievementsChallengeMode = ${hardcore}/;}" ${PPSSPP_INI} + fi +fi diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/scripts/psp_save_mover.sh b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/scripts/psp_save_mover.sh new file mode 100644 index 0000000000..a90e750b65 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/scripts/psp_save_mover.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +#This will copy saves to the correct directory after making changes to PPSSPP +if [ ! -d "/storage/roms/psp/PSP" ]; then + mkdir -p "/storage/roms/psp/PSP" + cp -r /storage/.config/ppsspp/PSP/SAVEDATA /storage/roms/psp/PSP/ +fi + +if [ ! -d "/storage/roms/savestates/psp/ppsspp-sa" ]; then + mkdir -p /storage/roms/savestates/psp/ppsspp-sa + cp -r /storage/.config/ppsspp/PSP/PPSSPP_STATE/* /storage/roms/savestates/psp/ppsspp-sa/ +fi diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/scripts/start_ppsspp.sh b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/scripts/start_ppsspp.sh new file mode 100755 index 0000000000..45df57b934 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/scripts/start_ppsspp.sh @@ -0,0 +1,110 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile +set_kill set "-9 ppsspp" + +SOURCE_DIR="/usr/config/ppsspp" +CONF_DIR="/storage/.config/ppsspp" +PPSSPP_INI="PSP/SYSTEM/ppsspp.ini" + +# Check if conf dir exists +if [ ! -d "${CONF_DIR}" ] +then + cp -rf ${SOURCE_DIR} ${CONF_DIR} +fi + +# Check if savestate dir exists +if [ ! -d "/storage/roms/savestates/psp/ppsspp-sa" ]; then + mkdir -p "/storage/roms/savestates/psp/ppsspp-sa" +fi + +#Emulation Station Features +GAME=$(echo "${1}"| sed "s#^/.*/##") +PLATFORM=$(echo "${2}"| sed "s#^/.*/##") +ASKIP=$(get_setting auto_frame_skip "${PLATFORM}" "${GAME}") +FPS=$(get_setting show_fps "${PLATFORM}" "${GAME}") +IRES=$(get_setting internal_resolution "${PLATFORM}" "${GAME}") +GRENDERER=$(get_setting graphics_backend "${PLATFORM}" "${GAME}") +SKIPB=$(get_setting skip_buffer_effects "${PLATFORM}" "${GAME}") +VSYNC=$(get_setting vsync "${PLATFORM}" "${GAME}") + +#Set the cores to use +CORES=$(get_setting "cores" "${PLATFORM}" "${GAME}") +if [ "${CORES}" = "little" ]; then + EMUPERF="${SLOW_CORES}" +elif [ "${CORES}" = "big" ]; then + EMUPERF="${FAST_CORES}" +else + ### All.. + unset EMUPERF +fi + + #Auto Frame Skip + if [ "${ASKIP}" = "1" ]; then + sed -i '/AutoFrameSkip =/c\AutoFrameSkip = True' ${CONF_DIR}/${PPSSPP_INI} + else + sed -i '/^AutoFrameSkip =/c\AutoFrameSkip = False' ${CONF_DIR}/${PPSSPP_INI} + fi + + #Graphics Backend + if [ "${GRENDERER}" = "opengl" ]; then + sed -i '/^GraphicsBackend =/c\GraphicsBackend = 0 (OPENGL)' ${CONF_DIR}/${PPSSPP_INI} + elif [ "${GRENDERER}" = "vulkan" ]; then + sed -i '/^GraphicsBackend =/c\GraphicsBackend = 3 (VULKAN)' ${CONF_DIR}/${PPSSPP_INI} + else + sed -i '/^GraphicsBackend =/c\GraphicsBackend = @GRENDERER@' ${CONF_DIR}/${PPSSPP_INI} + fi + + #Internal Resolution + if [ "${IRES}" = "2" ]; then + sed -i '/^InternalResolution/c\InternalResolution = 2' ${CONF_DIR}/${PPSSPP_INI} + elif [ "${IRES}" = "3" ]; then + sed -i '/^InternalResolution/c\InternalResolution = 3' ${CONF_DIR}/${PPSSPP_INI} + elif [ "${IRES}" = "4" ]; then + sed -i '/^InternalResolution/c\InternalResolution = 4' ${CONF_DIR}/${PPSSPP_INI} + else + sed -i '/^InternalResolution/c\InternalResolution = 1' ${CONF_DIR}/${PPSSPP_INI} + fi + + #Show FPS + if [ "${FPS}" = "1" ]; then + sed -i '/^iShowStatusFlags =/c\iShowStatusFlags = 2' ${CONF_DIR}/${PPSSPP_INI} + else + sed -i '/^iShowStatusFlags =/c\iShowStatusFlags = 0' ${CONF_DIR}/${PPSSPP_INI} + fi + + #Skip Buffer Effects + if [ "${SKIPB}" = "1" ]; then + sed -i '/^SkipBufferEffects =/c\SkipBufferEffects = True' ${CONF_DIR}/${PPSSPP_INI} + else + sed -i '/^SkipBufferEffects =/c\SkipBufferEffects = False' ${CONF_DIR}/${PPSSPP_INI} + fi + + #VSYNC + if [ "${VSYNC}" = "1" ]; then + sed -i '/^VSyncInterval =/c\VSyncInterval = True' ${CONF_DIR}/${PPSSPP_INI} + else + sed -i '/^VSyncInterval =/c\VSyncInterval = False' ${CONF_DIR}/${PPSSPP_INI} + fi + +#Retroachievements +/usr/bin/cheevos_ppsspp.sh + +ARG=${1//[\\]/} + +# Debugging info: + echo "GAME set to: ${GAME}" + echo "PLATFORM set to: ${PLATFORM}" + echo "CONF DIR: ${CONF_DIR}/${PPSSPP_INI}" + echo "CPU CORES set to: ${EMUPERF}" + echo "AUTO FRAME SKIP set to: ${ASKIP}" + echo "GRAPHICS RENDERER set to: ${GRENDERER}" + echo "INTERNAL RESOLUTION set to: ${IRES}" + echo "FPS set to: ${FPS}" + echo "SKIP BUFFER EFFECTS set to: ${SKIPB}" + echo "VSYNC set to: ${VSYNC}" + echo "Launching /usr/bin/ppsspp ${ARG}" + +${EMUPERF} ppsspp --pause-menu-exit "${ARG}" diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/H700/controls.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/H700/controls.ini new file mode 100755 index 0000000000..ecab3f6cb2 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/H700/controls.ini @@ -0,0 +1,25 @@ +[ControlMapping] +Up = 10-19 +Down = 10-20 +Left = 10-21 +Right = 10-22 +Circle = 10-189 +Cross = 10-190 +Square = 10-188 +Triangle = 10-191 +Start = 10-197 +Select = 10-196 +L = 10-193 +R = 10-192 +An.Up = 10-4003 +An.Down = 10-4002 +An.Left = 10-4001 +An.Right = 10-4000 +Fast-forward = 1-61 +Pause = 10-106 +Save State = 10-4010 +Load State = 10-4008 +RightAn.Up = 10-4007 +RightAn.Down = 10-4006 +RightAn.Left = 10-4005 +RightAn.Right = 10-4004 diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/H700/ppsspp.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/H700/ppsspp.ini new file mode 100755 index 0000000000..8be2d8b3ab --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/H700/ppsspp.ini @@ -0,0 +1,557 @@ +[General] +FirstRun = False +RunCount = 0 +Enable Logging = False +AutoRun = True +Browse = False +IgnoreBadMemAccess = False +CurrentDirectory = /storage/roms/psp +ShowDebuggerOnLoad = False +CheckForNewVersion = False +Language = en_US +ForceLagSync = False +DiscordPresence = False +NumWorkerThreads = 8 +AutoLoadSaveState = 0 +EnableCheats = True +CwCheatRefreshRate = 77 +ScreenshotsAsPNG = False +UseFFV1 = False +DumpFrames = False +DumpAudio = False +SaveLoadResetsAVdumping = False +StateSlot = 0 +EnableStateUndo = True +RewindFlipFrequency = 0 +GridView1 = True +GridView2 = True +GridView3 = False +ComboMode = 0 +ReportingHost = default +AutoSaveSymbolMap = False +CacheFullIsoInRam = False +RemoteISOPort = 0 +LastRemoteISOServer = +LastRemoteISOPort = 0 +RemoteISOManualConfig = False +RemoteShareOnStartup = False +RemoteISOSubdir = / +RemoteDebuggerOnStartup = False +InternalScreenRotation = 1 +PauseWhenMinimized = False +DumpDecryptedEboots = False +MemStickInserted = True +ForceLagSync2 = False +UISound = True +CwCheatScrollPosition = 0 +DumpVideoOutput = False +ShowRegionOnGameIcon = False +ShowIDOnGameIcon = False +GameGridScale = 1.000000 +RightAnalogUp = 0 +RightAnalogDown = 0 +RightAnalogLeft = 0 +RightAnalogRight = 0 +RightAnalogPress = 0 +RightAnalogCustom = False +LoadPlugins = False +GameListScrollPosition = 0.000000 +StateLoadUndoGame = NA +StateUndoLastSaveGame = NA +StateUndoLastSaveSlot = -5 +ShowOnScreenMessage = True +RightAnalogDisableDiagonal = False +SwipeUp = 0 +SwipeDown = 0 +SwipeLeft = 0 +SwipeRight = 0 +SwipeSensitivity = 1.000000 +SwipeSmoothing = 0.300000 +DoubleTapGesture = 0 +GestureControlEnabled = False +BackgroundAnimation = 1 +EnablePlugins = True +[CPU] +CPUCore = 1 +SeparateSASThread = True +SeparateIOThread = True +IOTimingMethod = 0 +FastMemoryAccess = True +FuncReplacements = True +HideSlowWarnings = False +HideStateWarnings = False +PreloadFunctions = False +CPUSpeed = 0 +JitDisableFlags = 0x00000000 +FunctionReplacements = True +[Graphics] +EnableCardboard = False +CardboardScreenSize = 50 +CardboardXShift = 0 +CardboardYShift = 0 +ShowFPSCounter = 3 +GraphicsBackend = 0 (OPENGL) +FailedGraphicsBackends = +VulkanDevice = +RenderingMode = 0 +SoftwareRenderer = False +HardwareTransform = True +SoftwareSkinning = True +TextureFiltering = 1 +BufferFiltering = 1 +InternalResolution = 1 +AndroidHwScale = 1 +HighQualityDepth = 1 +FrameSkip = 3 +FrameSkipType = 0 +AutoFrameSkip = True +FrameRate = -1 +FrameRate2 = -1 +FrameSkipUnthrottle = True +ForceMaxEmulatedFPS = 30 +AnisotropyLevel = 4 +VertexDecCache = True +TextureBackoffCache = True +TextureSecondaryCache = False +FullScreen = True +FullScreenMulti = False +SmallDisplayZoomType = 2 +SmallDisplayOffsetX = 0.500000 +SmallDisplayOffsetY = 0.500000 +SmallDisplayZoomLevel = 1.000000 +ImmersiveMode = False +SustainedPerformanceMode = False +TrueColor = True +ReplaceTextures = True +SaveNewTextures = False +IgnoreTextureFilenames = True +TexScalingLevel = 1 +TexScalingType = 0 +TexDeposterize = False +VSyncInterval = True +DisableStencilTest = False +BloomHack = 2 +TimerHack = False +SplineBezierQuality = 0 +HardwareTessellation = False +PostShader = Off +MemBlockTransferGPU = True +DisableSlowFramebufEffects = True +FragmentTestCache = True +LogFrameDrops = False +EnableCardboardVR = False +DisabledGraphicsBackends = +CameraDevice = +UnthrottleMode = CONTINUOUS +IgnoreScreenInsets = True +TexHardwareScaling = False +TextureShader = Off +InflightFrames = 3 +RenderDuplicateFrames = True +ShaderChainRequires60FPS = False +ClearFramebuffersOnFirstUseHack = False +SoftwareRendererJit = True +UnthrottlingMode = CONTINUOUS +ReplaceTexturesAllowLate = True +iShowStatusFlags = 0 +AndroidFramerateMode = 1 +UseGeometryShader = False +SkipBufferEffects = False +DisableRangeCulling = False +Smart2DTexFiltering = False +StereoRendering = False +StereoToMonoShader = RedBlue +AnalogFrameRate = 240 +MultiSampleLevel = 0 +DisplayOffsetX = 0.500000 +DisplayOffsetY = 0.500000 +DisplayScale = 1.000000 +DisplayIntegerScale = False +DisplayAspectRatio = 1.000000 +DisplayStretch = False +DisplayCropTo16x9 = False +VSync = True +SkipGPUReadbackMode = 1 +MultiThreading = True +GpuLogProfiler = False +UberShaderVertex = True +UberShaderFragment = True +[Sound] +Enable = True +AudioBackend = 0 +AudioLatency = 1 +ExtraAudioBuffering = False +SoundSpeedHack = False +AudioResampler = False +GlobalVolume = 10 +AltSpeedVolume = -1 +AutoAudioDevice = True +ReverbVolume = 10 +AchievementSoundVolume = 6 +AudioDevice = +[Control] +HapticFeedback = False +ShowTouchCross = True +ShowTouchCircle = True +ShowTouchSquare = True +ShowTouchTriangle = True +ComboKey0Mapping = 0 +ComboKey1Mapping = 0 +ComboKey2Mapping = 0 +ComboKey3Mapping = 0 +ComboKey4Mapping = 0 +ShowTouchPause = False +ShowTouchControls = False +DisableDpadDiagonals = False +GamepadOnlyFocused = False +TouchButtonStyle = 1 +TouchButtonOpacity = 65 +TouchButtonHideSeconds = 20 +AutoCenterTouchAnalog = False +ActionButtonSpacing2 = 1.000000 +ActionButtonCenterX = 0.937500 +ActionButtonCenterY = 0.900000 +ActionButtonScale = 1.150000 +DPadX = 0.074479 +DPadY = 0.760000 +DPadScale = 1.150000 +ShowTouchDpad = True +DPadSpacing = 1.000000 +StartKeyX = 0.559896 +StartKeyY = 0.942500 +StartKeyScale = 1.150000 +ShowTouchStart = True +SelectKeyX = 0.500000 +SelectKeyY = 0.942500 +SelectKeyScale = 1.150000 +ShowTouchSelect = True +UnthrottleKeyX = 0.440104 +UnthrottleKeyY = 0.942500 +UnthrottleKeyScale = 1.150000 +ShowTouchUnthrottle = True +LKeyX = 0.035937 +LKeyY = 0.635833 +LKeyScale = 1.150000 +ShowTouchLTrigger = True +RKeyX = 0.964063 +RKeyY = 0.635833 +RKeyScale = 1.150000 +ShowTouchRTrigger = True +AnalogStickX = 0.074479 +AnalogStickY = 0.923333 +AnalogStickScale = 1.150000 +ShowAnalogStick = True +fcombo0X = 0.571875 +fcombo0Y = 0.500000 +comboKeyScale0 = 1.150000 +ShowComboKey0 = False +fcombo1X = 0.631771 +fcombo1Y = 0.500000 +comboKeyScale1 = 1.150000 +ShowComboKey1 = False +fcombo2X = 0.691667 +fcombo2Y = 0.500000 +comboKeyScale2 = 1.150000 +ShowComboKey2 = False +fcombo3X = 0.571875 +fcombo3Y = 0.333333 +comboKeyScale3 = 1.150000 +ShowComboKey3 = False +fcombo4X = 0.631771 +fcombo4Y = 0.333333 +comboKeyScale4 = 1.150000 +ShowComboKey4 = False +Speed1KeyX = 0.440104 +Speed1KeyY = 0.885000 +Speed1KeyScale = 1.150000 +ShowSpeed1Key = False +Speed2KeyX = 0.500000 +Speed2KeyY = 0.885000 +Speed2KeyScale = 1.150000 +ShowSpeed2Key = False +XInputAnalogSensitivity = 1.000000 +AnalogLimiterDeadzone = 0.600000 +UseMouse = False +MapMouse = False +ConfineMap = False +MouseSensitivity = 0.100000 +MouseSmoothing = 0.900000 +ComboKey0Toggle = False +ComboKey1Toggle = False +ComboKey2Toggle = False +ComboKey3Toggle = False +ComboKey4Toggle = False +AnalogAutoRotSpeed = 15.000000 +TouchSnapToGrid = False +TouchSnapGridSize = 64 +RightAnalogStickX = 0.875000 +RightAnalogStickY = 0.856250 +RightAnalogStickScale = 1.150000 +ShowRightAnalogStick = False +RapidFireKeyX = 0.619792 +RapidFireKeyY = 0.784375 +RapidFireKeyScale = 1.150000 +ShowRapidFireKey = False +AnalogRotationCWKeyX = 0.500000 +AnalogRotationKeyCWY = 0.676562 +AnalogRotationKeyCWScale = 1.150000 +ShowAnalogRotationCWKey = False +AnalogRotationCCWKeyX = 0.380208 +AnalogRotationKeyCCWY = 0.676562 +AnalogRotationKeyCCWScale = 1.150000 +ShowAnalogRotationCCWKey = False +Custom0Mapping = 0x0000000000000000 +Custom0Image = 0 +Custom0Shape = 0 +Custom0Toggle = False +Custom1Mapping = 0x0000000000000000 +Custom1Image = 1 +Custom1Shape = 0 +Custom1Toggle = False +Custom2Mapping = 0x0000000000000000 +Custom2Image = 2 +Custom2Shape = 0 +Custom2Toggle = False +Custom3Mapping = 0x0000000000000000 +Custom3Image = 3 +Custom3Shape = 0 +Custom3Toggle = False +Custom4Mapping = 0x0000000000000000 +Custom4Image = 4 +Custom4Shape = 0 +Custom4Toggle = False +Custom5Mapping = 0x0000000000000000 +Custom5Image = 0 +Custom5Shape = 1 +Custom5Toggle = False +Custom6Mapping = 0x0000000000000000 +Custom6Image = 1 +Custom6Shape = 1 +Custom6Toggle = False +Custom7Mapping = 0x0000000000000000 +Custom7Image = 2 +Custom7Shape = 1 +Custom7Toggle = False +Custom8Mapping = 0x0000000000000000 +Custom8Image = 3 +Custom8Shape = 1 +Custom8Toggle = False +Custom9Mapping = 0x0000000000000000 +Custom9Image = 4 +Custom9Shape = 1 +Custom9Toggle = False +fcombo5X = 0.428125 +fcombo5Y = 0.500000 +comboKeyScale5 = 1.150000 +ShowComboKey5 = False +fcombo6X = 0.368229 +fcombo6Y = 0.500000 +comboKeyScale6 = 1.150000 +ShowComboKey6 = False +fcombo7X = 0.308333 +fcombo7Y = 0.500000 +comboKeyScale7 = 1.150000 +ShowComboKey7 = False +fcombo8X = 0.428125 +fcombo8Y = 0.333333 +comboKeyScale8 = 1.150000 +ShowComboKey8 = False +fcombo9X = 0.368229 +fcombo9Y = 0.333333 +comboKeyScale9 = 1.150000 +ShowComboKey9 = False +AnalogDeadzone = 0.150000 +AnalogInverseDeadzone = 0.000000 +AnalogSensitivity = 1.100000 +AnalogIsCircular = False +LeftStickHeadScale = 1.000000 +RightStickHeadScale = 1.000000 +HideStickBackground = False +SystemControls = True +[Network] +EnableWlan = False +EnableAdhocServer = False +proAdhocServer = myneighborsushicat.com +PortOffset = 0 +MinTimeout = 1 +TCPNoDelay = False +EnableUPnP = False +UPnPUseOriginalPort = True +EnableNetworkChat = False +ChatButtonPosition = 0 +ChatScreenPosition = 0 +EnableQuickChat = True +QuickChat1 = Quick Chat 1 +QuickChat2 = Quick Chat 2 +QuickChat3 = Quick Chat 3 +QuickChat4 = Quick Chat 4 +QuickChat5 = Quick Chat 5 +ForcedFirstConnect = False +[SystemParam] +PSPModel = 0 +PSPFirmwareVersion = 660 +NickName = PPSSPP +proAdhocServer = black-seraph.com +MacAddress = 4e:7a:78:d9:49:32 +PortOffset = 0 +Language = 1 +TimeFormat = 1 +DateFormat = 1 +TimeZone = 0 +DayLightSavings = False +ButtonPreference = 1 +LockParentalLevel = 0 +WlanAdhocChannel = 0 +WlanPowerSave = False +EncryptSave = True +SavedataUpgradeVersion = True +ParamTimeFormat = 0 +ParamDateFormat = 0 +MemStickSize = 16 +[Debugger] +DisasmWindowX = -1 +DisasmWindowY = -1 +DisasmWindowW = -1 +DisasmWindowH = -1 +GEWindowX = -1 +GEWindowY = -1 +GEWindowW = -1 +GEWindowH = -1 +ConsoleWindowX = -1 +ConsoleWindowY = -1 +FontWidth = 8 +FontHeight = 12 +DisplayStatusBar = True +ShowBottomTabTitles = True +ShowDeveloperMenu = False +SkipDeadbeefFilling = False +FuncHashMap = False +DrawFrameGraph = False +MemInfoDetailed = False +[Upgrade] +UpgradeMessage = +UpgradeVersion = 1.12.0 +DismissedVersion = +[Theme] +ItemStyleFg = 0xffffffff +ItemStyleBg = 0x55000000 +ItemFocusedStyleFg = 0xffffffff +ItemFocusedStyleBg = 0xffedc24c +ItemDownStyleFg = 0xffffffff +ItemDownStyleBg = 0xffbd9939 +ItemDisabledStyleFg = 0x80eeeeee +ItemDisabledStyleBg = 0x55e0d4af +ItemHighlightedStyleFg = 0xffffffff +ItemHighlightedStyleBg = 0x55bdbb39 +ButtonStyleFg = 0xffffffff +ButtonStyleBg = 0x55000000 +ButtonFocusedStyleFg = 0xffffffff +ButtonFocusedStyleBg = 0xffedc24c +ButtonDownStyleFg = 0xffffffff +ButtonDownStyleBg = 0xffbd9939 +ButtonDisabledStyleFg = 0x80eeeeee +ButtonDisabledStyleBg = 0x55e0d4af +ButtonHighlightedStyleFg = 0xffffffff +ButtonHighlightedStyleBg = 0x55bdbb39 +HeaderStyleFg = 0xffffffff +InfoStyleFg = 0xffffffff +InfoStyleBg = 0x00000000 +PopupTitleStyleFg = 0xffe3be59 +PopupStyleFg = 0xffffffff +PopupStyleBg = 0xff303030 +ThemeName = Default +[Recent] +MaxRecent = 30 +[Log] +SYSTEMEnabled = True +SYSTEMLevel = 4 +BOOTEnabled = True +BOOTLevel = 4 +COMMONEnabled = True +COMMONLevel = 4 +CPUEnabled = True +CPULevel = 4 +FILESYSEnabled = True +FILESYSLevel = 4 +G3DEnabled = True +G3DLevel = 4 +HLEEnabled = True +HLELevel = 4 +JITEnabled = True +JITLevel = 4 +LOADEREnabled = True +LOADERLevel = 4 +MEEnabled = True +MELevel = 4 +MEMMAPEnabled = True +MEMMAPLevel = 4 +SASMIXEnabled = True +SASMIXLevel = 4 +SAVESTATEEnabled = True +SAVESTATELevel = 4 +FRAMEBUFEnabled = True +FRAMEBUFLevel = 4 +SCEAUDIOEnabled = True +SCEAUDIOLevel = 4 +SCECTRLEnabled = True +SCECTRLLevel = 4 +SCEDISPEnabled = True +SCEDISPLevel = 4 +SCEFONTEnabled = True +SCEFONTLevel = 4 +SCEGEEnabled = True +SCEGELevel = 4 +SCEINTCEnabled = True +SCEINTCLevel = 4 +SCEIOEnabled = True +SCEIOLevel = 4 +SCEKERNELEnabled = True +SCEKERNELLevel = 4 +SCEMODULEEnabled = True +SCEMODULELevel = 4 +SCENETEnabled = True +SCENETLevel = 4 +SCERTCEnabled = True +SCERTCLevel = 4 +SCESASEnabled = True +SCESASLevel = 4 +SCEUTILEnabled = True +SCEUTILLevel = 4 +SCEMISCEnabled = True +SCEMISCLevel = 4 +AUDIOEnabled = True +AUDIOLevel = 2 +IOEnabled = True +IOLevel = 2 +[PostShaderSetting] +BloomSettingValue1 = 0.600000 +BloomSettingValue2 = 0.500000 +CRTSettingValue1 = 1.000000 +CartoonSettingValue1 = 0.500000 +ColorCorrectionSettingValue1 = 1.000000 +ColorCorrectionSettingValue2 = 1.000000 +ColorCorrectionSettingValue3 = 1.000000 +ColorCorrectionSettingValue4 = 1.000000 +ScanlinesSettingValue1 = 1.000000 +ScanlinesSettingValue2 = 0.500000 +SharpenSettingValue1 = 1.500000 +[VR] +VREnable = True +VREnable6DoF = True +VREnableStereo = False +VREnableMotions = True +VRForce72Hz = True +VRManualForceVR = False +VRPassthrough = False +VRRescaleHUD = True +VRCameraDistance = 0.000000 +VRCameraHeight = 0.000000 +VRCameraSide = 0.000000 +VRCameraPitch = 0 +VRCanvasDistance = 12.000000 +VRCanvas3DDistance = 3.000000 +VRHeadUpDisplayScale = 0.300000 +VRMotionLength = 0.500000 +VRHeadRotationScale = 5.000000 +VRHeadRotationEnabled = False +VRHeadRotationSmoothing = False diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/InputPlumber/controls.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/InputPlumber/controls.ini new file mode 100644 index 0000000000..a18390fa46 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/InputPlumber/controls.ini @@ -0,0 +1,26 @@ +[ControlMapping] +Up = 10-19 +Down = 10-20 +Left = 10-21 +Right = 10-22 +Circle = 10-190 +Cross = 10-189 +Square = 10-191 +Triangle = 10-188 +Start = 10-197 +Select = 10-196 +L = 10-193 +R = 10-192 +An.Up = 10-4003 +An.Down = 10-4002 +An.Left = 10-4001 +An.Right = 10-4000 +Pause = 10-198:10-188,10-4 +Save State = 10-198:10-192 +Load State = 10-198:10-193 +RightAn.Up = 10-4007 +RightAn.Down = 10-4006 +RightAn.Left = 10-4005 +RightAn.Right = 10-4004 +Fast-forward = 10-198:10-4010 +Exit App = 10-198:10-197 diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/RK3326/controls.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/RK3326/controls.ini new file mode 100755 index 0000000000..213f7119a3 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/RK3326/controls.ini @@ -0,0 +1,25 @@ +[ControlMapping] +Up = 10-19 +Down = 10-20 +Left = 10-21 +Right = 10-22 +Circle = 10-189 +Cross = 10-190 +Square = 10-188 +Triangle = 10-191 +Start = 10-197 +Select = 10-196 +L = 10-193 +R = 10-192 +An.Up = 10-4002 +An.Down = 10-4003 +An.Left = 10-4000 +An.Right = 10-4001 +Fast-forward = 1-61 +Pause = 10-106 +Save State = 10-4010 +Load State = 10-4008 +RightAn.Up = 10-4007 +RightAn.Down = 10-4006 +RightAn.Left = 10-4005 +RightAn.Right = 10-4004 diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/RK3326/ppsspp.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/RK3326/ppsspp.ini new file mode 100755 index 0000000000..8be2d8b3ab --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/RK3326/ppsspp.ini @@ -0,0 +1,557 @@ +[General] +FirstRun = False +RunCount = 0 +Enable Logging = False +AutoRun = True +Browse = False +IgnoreBadMemAccess = False +CurrentDirectory = /storage/roms/psp +ShowDebuggerOnLoad = False +CheckForNewVersion = False +Language = en_US +ForceLagSync = False +DiscordPresence = False +NumWorkerThreads = 8 +AutoLoadSaveState = 0 +EnableCheats = True +CwCheatRefreshRate = 77 +ScreenshotsAsPNG = False +UseFFV1 = False +DumpFrames = False +DumpAudio = False +SaveLoadResetsAVdumping = False +StateSlot = 0 +EnableStateUndo = True +RewindFlipFrequency = 0 +GridView1 = True +GridView2 = True +GridView3 = False +ComboMode = 0 +ReportingHost = default +AutoSaveSymbolMap = False +CacheFullIsoInRam = False +RemoteISOPort = 0 +LastRemoteISOServer = +LastRemoteISOPort = 0 +RemoteISOManualConfig = False +RemoteShareOnStartup = False +RemoteISOSubdir = / +RemoteDebuggerOnStartup = False +InternalScreenRotation = 1 +PauseWhenMinimized = False +DumpDecryptedEboots = False +MemStickInserted = True +ForceLagSync2 = False +UISound = True +CwCheatScrollPosition = 0 +DumpVideoOutput = False +ShowRegionOnGameIcon = False +ShowIDOnGameIcon = False +GameGridScale = 1.000000 +RightAnalogUp = 0 +RightAnalogDown = 0 +RightAnalogLeft = 0 +RightAnalogRight = 0 +RightAnalogPress = 0 +RightAnalogCustom = False +LoadPlugins = False +GameListScrollPosition = 0.000000 +StateLoadUndoGame = NA +StateUndoLastSaveGame = NA +StateUndoLastSaveSlot = -5 +ShowOnScreenMessage = True +RightAnalogDisableDiagonal = False +SwipeUp = 0 +SwipeDown = 0 +SwipeLeft = 0 +SwipeRight = 0 +SwipeSensitivity = 1.000000 +SwipeSmoothing = 0.300000 +DoubleTapGesture = 0 +GestureControlEnabled = False +BackgroundAnimation = 1 +EnablePlugins = True +[CPU] +CPUCore = 1 +SeparateSASThread = True +SeparateIOThread = True +IOTimingMethod = 0 +FastMemoryAccess = True +FuncReplacements = True +HideSlowWarnings = False +HideStateWarnings = False +PreloadFunctions = False +CPUSpeed = 0 +JitDisableFlags = 0x00000000 +FunctionReplacements = True +[Graphics] +EnableCardboard = False +CardboardScreenSize = 50 +CardboardXShift = 0 +CardboardYShift = 0 +ShowFPSCounter = 3 +GraphicsBackend = 0 (OPENGL) +FailedGraphicsBackends = +VulkanDevice = +RenderingMode = 0 +SoftwareRenderer = False +HardwareTransform = True +SoftwareSkinning = True +TextureFiltering = 1 +BufferFiltering = 1 +InternalResolution = 1 +AndroidHwScale = 1 +HighQualityDepth = 1 +FrameSkip = 3 +FrameSkipType = 0 +AutoFrameSkip = True +FrameRate = -1 +FrameRate2 = -1 +FrameSkipUnthrottle = True +ForceMaxEmulatedFPS = 30 +AnisotropyLevel = 4 +VertexDecCache = True +TextureBackoffCache = True +TextureSecondaryCache = False +FullScreen = True +FullScreenMulti = False +SmallDisplayZoomType = 2 +SmallDisplayOffsetX = 0.500000 +SmallDisplayOffsetY = 0.500000 +SmallDisplayZoomLevel = 1.000000 +ImmersiveMode = False +SustainedPerformanceMode = False +TrueColor = True +ReplaceTextures = True +SaveNewTextures = False +IgnoreTextureFilenames = True +TexScalingLevel = 1 +TexScalingType = 0 +TexDeposterize = False +VSyncInterval = True +DisableStencilTest = False +BloomHack = 2 +TimerHack = False +SplineBezierQuality = 0 +HardwareTessellation = False +PostShader = Off +MemBlockTransferGPU = True +DisableSlowFramebufEffects = True +FragmentTestCache = True +LogFrameDrops = False +EnableCardboardVR = False +DisabledGraphicsBackends = +CameraDevice = +UnthrottleMode = CONTINUOUS +IgnoreScreenInsets = True +TexHardwareScaling = False +TextureShader = Off +InflightFrames = 3 +RenderDuplicateFrames = True +ShaderChainRequires60FPS = False +ClearFramebuffersOnFirstUseHack = False +SoftwareRendererJit = True +UnthrottlingMode = CONTINUOUS +ReplaceTexturesAllowLate = True +iShowStatusFlags = 0 +AndroidFramerateMode = 1 +UseGeometryShader = False +SkipBufferEffects = False +DisableRangeCulling = False +Smart2DTexFiltering = False +StereoRendering = False +StereoToMonoShader = RedBlue +AnalogFrameRate = 240 +MultiSampleLevel = 0 +DisplayOffsetX = 0.500000 +DisplayOffsetY = 0.500000 +DisplayScale = 1.000000 +DisplayIntegerScale = False +DisplayAspectRatio = 1.000000 +DisplayStretch = False +DisplayCropTo16x9 = False +VSync = True +SkipGPUReadbackMode = 1 +MultiThreading = True +GpuLogProfiler = False +UberShaderVertex = True +UberShaderFragment = True +[Sound] +Enable = True +AudioBackend = 0 +AudioLatency = 1 +ExtraAudioBuffering = False +SoundSpeedHack = False +AudioResampler = False +GlobalVolume = 10 +AltSpeedVolume = -1 +AutoAudioDevice = True +ReverbVolume = 10 +AchievementSoundVolume = 6 +AudioDevice = +[Control] +HapticFeedback = False +ShowTouchCross = True +ShowTouchCircle = True +ShowTouchSquare = True +ShowTouchTriangle = True +ComboKey0Mapping = 0 +ComboKey1Mapping = 0 +ComboKey2Mapping = 0 +ComboKey3Mapping = 0 +ComboKey4Mapping = 0 +ShowTouchPause = False +ShowTouchControls = False +DisableDpadDiagonals = False +GamepadOnlyFocused = False +TouchButtonStyle = 1 +TouchButtonOpacity = 65 +TouchButtonHideSeconds = 20 +AutoCenterTouchAnalog = False +ActionButtonSpacing2 = 1.000000 +ActionButtonCenterX = 0.937500 +ActionButtonCenterY = 0.900000 +ActionButtonScale = 1.150000 +DPadX = 0.074479 +DPadY = 0.760000 +DPadScale = 1.150000 +ShowTouchDpad = True +DPadSpacing = 1.000000 +StartKeyX = 0.559896 +StartKeyY = 0.942500 +StartKeyScale = 1.150000 +ShowTouchStart = True +SelectKeyX = 0.500000 +SelectKeyY = 0.942500 +SelectKeyScale = 1.150000 +ShowTouchSelect = True +UnthrottleKeyX = 0.440104 +UnthrottleKeyY = 0.942500 +UnthrottleKeyScale = 1.150000 +ShowTouchUnthrottle = True +LKeyX = 0.035937 +LKeyY = 0.635833 +LKeyScale = 1.150000 +ShowTouchLTrigger = True +RKeyX = 0.964063 +RKeyY = 0.635833 +RKeyScale = 1.150000 +ShowTouchRTrigger = True +AnalogStickX = 0.074479 +AnalogStickY = 0.923333 +AnalogStickScale = 1.150000 +ShowAnalogStick = True +fcombo0X = 0.571875 +fcombo0Y = 0.500000 +comboKeyScale0 = 1.150000 +ShowComboKey0 = False +fcombo1X = 0.631771 +fcombo1Y = 0.500000 +comboKeyScale1 = 1.150000 +ShowComboKey1 = False +fcombo2X = 0.691667 +fcombo2Y = 0.500000 +comboKeyScale2 = 1.150000 +ShowComboKey2 = False +fcombo3X = 0.571875 +fcombo3Y = 0.333333 +comboKeyScale3 = 1.150000 +ShowComboKey3 = False +fcombo4X = 0.631771 +fcombo4Y = 0.333333 +comboKeyScale4 = 1.150000 +ShowComboKey4 = False +Speed1KeyX = 0.440104 +Speed1KeyY = 0.885000 +Speed1KeyScale = 1.150000 +ShowSpeed1Key = False +Speed2KeyX = 0.500000 +Speed2KeyY = 0.885000 +Speed2KeyScale = 1.150000 +ShowSpeed2Key = False +XInputAnalogSensitivity = 1.000000 +AnalogLimiterDeadzone = 0.600000 +UseMouse = False +MapMouse = False +ConfineMap = False +MouseSensitivity = 0.100000 +MouseSmoothing = 0.900000 +ComboKey0Toggle = False +ComboKey1Toggle = False +ComboKey2Toggle = False +ComboKey3Toggle = False +ComboKey4Toggle = False +AnalogAutoRotSpeed = 15.000000 +TouchSnapToGrid = False +TouchSnapGridSize = 64 +RightAnalogStickX = 0.875000 +RightAnalogStickY = 0.856250 +RightAnalogStickScale = 1.150000 +ShowRightAnalogStick = False +RapidFireKeyX = 0.619792 +RapidFireKeyY = 0.784375 +RapidFireKeyScale = 1.150000 +ShowRapidFireKey = False +AnalogRotationCWKeyX = 0.500000 +AnalogRotationKeyCWY = 0.676562 +AnalogRotationKeyCWScale = 1.150000 +ShowAnalogRotationCWKey = False +AnalogRotationCCWKeyX = 0.380208 +AnalogRotationKeyCCWY = 0.676562 +AnalogRotationKeyCCWScale = 1.150000 +ShowAnalogRotationCCWKey = False +Custom0Mapping = 0x0000000000000000 +Custom0Image = 0 +Custom0Shape = 0 +Custom0Toggle = False +Custom1Mapping = 0x0000000000000000 +Custom1Image = 1 +Custom1Shape = 0 +Custom1Toggle = False +Custom2Mapping = 0x0000000000000000 +Custom2Image = 2 +Custom2Shape = 0 +Custom2Toggle = False +Custom3Mapping = 0x0000000000000000 +Custom3Image = 3 +Custom3Shape = 0 +Custom3Toggle = False +Custom4Mapping = 0x0000000000000000 +Custom4Image = 4 +Custom4Shape = 0 +Custom4Toggle = False +Custom5Mapping = 0x0000000000000000 +Custom5Image = 0 +Custom5Shape = 1 +Custom5Toggle = False +Custom6Mapping = 0x0000000000000000 +Custom6Image = 1 +Custom6Shape = 1 +Custom6Toggle = False +Custom7Mapping = 0x0000000000000000 +Custom7Image = 2 +Custom7Shape = 1 +Custom7Toggle = False +Custom8Mapping = 0x0000000000000000 +Custom8Image = 3 +Custom8Shape = 1 +Custom8Toggle = False +Custom9Mapping = 0x0000000000000000 +Custom9Image = 4 +Custom9Shape = 1 +Custom9Toggle = False +fcombo5X = 0.428125 +fcombo5Y = 0.500000 +comboKeyScale5 = 1.150000 +ShowComboKey5 = False +fcombo6X = 0.368229 +fcombo6Y = 0.500000 +comboKeyScale6 = 1.150000 +ShowComboKey6 = False +fcombo7X = 0.308333 +fcombo7Y = 0.500000 +comboKeyScale7 = 1.150000 +ShowComboKey7 = False +fcombo8X = 0.428125 +fcombo8Y = 0.333333 +comboKeyScale8 = 1.150000 +ShowComboKey8 = False +fcombo9X = 0.368229 +fcombo9Y = 0.333333 +comboKeyScale9 = 1.150000 +ShowComboKey9 = False +AnalogDeadzone = 0.150000 +AnalogInverseDeadzone = 0.000000 +AnalogSensitivity = 1.100000 +AnalogIsCircular = False +LeftStickHeadScale = 1.000000 +RightStickHeadScale = 1.000000 +HideStickBackground = False +SystemControls = True +[Network] +EnableWlan = False +EnableAdhocServer = False +proAdhocServer = myneighborsushicat.com +PortOffset = 0 +MinTimeout = 1 +TCPNoDelay = False +EnableUPnP = False +UPnPUseOriginalPort = True +EnableNetworkChat = False +ChatButtonPosition = 0 +ChatScreenPosition = 0 +EnableQuickChat = True +QuickChat1 = Quick Chat 1 +QuickChat2 = Quick Chat 2 +QuickChat3 = Quick Chat 3 +QuickChat4 = Quick Chat 4 +QuickChat5 = Quick Chat 5 +ForcedFirstConnect = False +[SystemParam] +PSPModel = 0 +PSPFirmwareVersion = 660 +NickName = PPSSPP +proAdhocServer = black-seraph.com +MacAddress = 4e:7a:78:d9:49:32 +PortOffset = 0 +Language = 1 +TimeFormat = 1 +DateFormat = 1 +TimeZone = 0 +DayLightSavings = False +ButtonPreference = 1 +LockParentalLevel = 0 +WlanAdhocChannel = 0 +WlanPowerSave = False +EncryptSave = True +SavedataUpgradeVersion = True +ParamTimeFormat = 0 +ParamDateFormat = 0 +MemStickSize = 16 +[Debugger] +DisasmWindowX = -1 +DisasmWindowY = -1 +DisasmWindowW = -1 +DisasmWindowH = -1 +GEWindowX = -1 +GEWindowY = -1 +GEWindowW = -1 +GEWindowH = -1 +ConsoleWindowX = -1 +ConsoleWindowY = -1 +FontWidth = 8 +FontHeight = 12 +DisplayStatusBar = True +ShowBottomTabTitles = True +ShowDeveloperMenu = False +SkipDeadbeefFilling = False +FuncHashMap = False +DrawFrameGraph = False +MemInfoDetailed = False +[Upgrade] +UpgradeMessage = +UpgradeVersion = 1.12.0 +DismissedVersion = +[Theme] +ItemStyleFg = 0xffffffff +ItemStyleBg = 0x55000000 +ItemFocusedStyleFg = 0xffffffff +ItemFocusedStyleBg = 0xffedc24c +ItemDownStyleFg = 0xffffffff +ItemDownStyleBg = 0xffbd9939 +ItemDisabledStyleFg = 0x80eeeeee +ItemDisabledStyleBg = 0x55e0d4af +ItemHighlightedStyleFg = 0xffffffff +ItemHighlightedStyleBg = 0x55bdbb39 +ButtonStyleFg = 0xffffffff +ButtonStyleBg = 0x55000000 +ButtonFocusedStyleFg = 0xffffffff +ButtonFocusedStyleBg = 0xffedc24c +ButtonDownStyleFg = 0xffffffff +ButtonDownStyleBg = 0xffbd9939 +ButtonDisabledStyleFg = 0x80eeeeee +ButtonDisabledStyleBg = 0x55e0d4af +ButtonHighlightedStyleFg = 0xffffffff +ButtonHighlightedStyleBg = 0x55bdbb39 +HeaderStyleFg = 0xffffffff +InfoStyleFg = 0xffffffff +InfoStyleBg = 0x00000000 +PopupTitleStyleFg = 0xffe3be59 +PopupStyleFg = 0xffffffff +PopupStyleBg = 0xff303030 +ThemeName = Default +[Recent] +MaxRecent = 30 +[Log] +SYSTEMEnabled = True +SYSTEMLevel = 4 +BOOTEnabled = True +BOOTLevel = 4 +COMMONEnabled = True +COMMONLevel = 4 +CPUEnabled = True +CPULevel = 4 +FILESYSEnabled = True +FILESYSLevel = 4 +G3DEnabled = True +G3DLevel = 4 +HLEEnabled = True +HLELevel = 4 +JITEnabled = True +JITLevel = 4 +LOADEREnabled = True +LOADERLevel = 4 +MEEnabled = True +MELevel = 4 +MEMMAPEnabled = True +MEMMAPLevel = 4 +SASMIXEnabled = True +SASMIXLevel = 4 +SAVESTATEEnabled = True +SAVESTATELevel = 4 +FRAMEBUFEnabled = True +FRAMEBUFLevel = 4 +SCEAUDIOEnabled = True +SCEAUDIOLevel = 4 +SCECTRLEnabled = True +SCECTRLLevel = 4 +SCEDISPEnabled = True +SCEDISPLevel = 4 +SCEFONTEnabled = True +SCEFONTLevel = 4 +SCEGEEnabled = True +SCEGELevel = 4 +SCEINTCEnabled = True +SCEINTCLevel = 4 +SCEIOEnabled = True +SCEIOLevel = 4 +SCEKERNELEnabled = True +SCEKERNELLevel = 4 +SCEMODULEEnabled = True +SCEMODULELevel = 4 +SCENETEnabled = True +SCENETLevel = 4 +SCERTCEnabled = True +SCERTCLevel = 4 +SCESASEnabled = True +SCESASLevel = 4 +SCEUTILEnabled = True +SCEUTILLevel = 4 +SCEMISCEnabled = True +SCEMISCLevel = 4 +AUDIOEnabled = True +AUDIOLevel = 2 +IOEnabled = True +IOLevel = 2 +[PostShaderSetting] +BloomSettingValue1 = 0.600000 +BloomSettingValue2 = 0.500000 +CRTSettingValue1 = 1.000000 +CartoonSettingValue1 = 0.500000 +ColorCorrectionSettingValue1 = 1.000000 +ColorCorrectionSettingValue2 = 1.000000 +ColorCorrectionSettingValue3 = 1.000000 +ColorCorrectionSettingValue4 = 1.000000 +ScanlinesSettingValue1 = 1.000000 +ScanlinesSettingValue2 = 0.500000 +SharpenSettingValue1 = 1.500000 +[VR] +VREnable = True +VREnable6DoF = True +VREnableStereo = False +VREnableMotions = True +VRForce72Hz = True +VRManualForceVR = False +VRPassthrough = False +VRRescaleHUD = True +VRCameraDistance = 0.000000 +VRCameraHeight = 0.000000 +VRCameraSide = 0.000000 +VRCameraPitch = 0 +VRCanvasDistance = 12.000000 +VRCanvas3DDistance = 3.000000 +VRHeadUpDisplayScale = 0.300000 +VRMotionLength = 0.500000 +VRHeadRotationScale = 5.000000 +VRHeadRotationEnabled = False +VRHeadRotationSmoothing = False diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/RK3399/controls.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/RK3399/controls.ini new file mode 100644 index 0000000000..a9ab9b25ea --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/RK3399/controls.ini @@ -0,0 +1,24 @@ +[ControlMapping] +Up = 10-19 +Down = 10-20 +Left = 10-21 +Right = 10-22 +Circle = 10-189 +Cross = 10-190 +Square = 10-188 +Triangle = 10-191 +Start = 10-197 +Select = 10-196 +L = 10-193 +R = 10-192 +An.Up = 10-4003 +An.Down = 10-4002 +An.Left = 10-4001 +An.Right = 10-4000 +Pause = 10-106 +Save State = 10-4010 +Load State = 10-4008 +RightAn.Up = 10-4007 +RightAn.Down = 10-4006 +RightAn.Left = 10-4005 +RightAn.Right = 10-4004 diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/RK3399/ppsspp.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/RK3399/ppsspp.ini new file mode 100644 index 0000000000..90dc514327 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/RK3399/ppsspp.ini @@ -0,0 +1,557 @@ +[General] +FirstRun = False +RunCount = 0 +Enable Logging = False +AutoRun = True +Browse = False +IgnoreBadMemAccess = False +CurrentDirectory = /storage/roms/psp +ShowDebuggerOnLoad = False +CheckForNewVersion = False +Language = en_US +ForceLagSync = False +DiscordPresence = False +NumWorkerThreads = 8 +AutoLoadSaveState = 0 +EnableCheats = True +CwCheatRefreshRate = 77 +ScreenshotsAsPNG = False +UseFFV1 = False +DumpFrames = False +DumpAudio = False +SaveLoadResetsAVdumping = False +StateSlot = 0 +EnableStateUndo = True +RewindFlipFrequency = 0 +GridView1 = True +GridView2 = True +GridView3 = False +ComboMode = 0 +ReportingHost = default +AutoSaveSymbolMap = False +CacheFullIsoInRam = False +RemoteISOPort = 0 +LastRemoteISOServer = +LastRemoteISOPort = 0 +RemoteISOManualConfig = False +RemoteShareOnStartup = False +RemoteISOSubdir = / +RemoteDebuggerOnStartup = False +InternalScreenRotation = 1 +PauseWhenMinimized = False +DumpDecryptedEboots = False +MemStickInserted = True +ForceLagSync2 = False +UISound = True +CwCheatScrollPosition = 0 +DumpVideoOutput = False +ShowRegionOnGameIcon = False +ShowIDOnGameIcon = False +GameGridScale = 1.000000 +RightAnalogUp = 0 +RightAnalogDown = 0 +RightAnalogLeft = 0 +RightAnalogRight = 0 +RightAnalogPress = 0 +RightAnalogCustom = False +LoadPlugins = False +GameListScrollPosition = 0.000000 +StateLoadUndoGame = NA +StateUndoLastSaveGame = NA +StateUndoLastSaveSlot = -5 +ShowOnScreenMessage = True +RightAnalogDisableDiagonal = False +SwipeUp = 0 +SwipeDown = 0 +SwipeLeft = 0 +SwipeRight = 0 +SwipeSensitivity = 1.000000 +SwipeSmoothing = 0.300000 +DoubleTapGesture = 0 +GestureControlEnabled = False +BackgroundAnimation = 1 +EnablePlugins = True +[CPU] +CPUCore = 1 +SeparateSASThread = True +SeparateIOThread = True +IOTimingMethod = 0 +FastMemoryAccess = True +FuncReplacements = True +HideSlowWarnings = False +HideStateWarnings = False +PreloadFunctions = False +CPUSpeed = 0 +JitDisableFlags = 0x00000000 +FunctionReplacements = True +[Graphics] +EnableCardboard = False +CardboardScreenSize = 50 +CardboardXShift = 0 +CardboardYShift = 0 +ShowFPSCounter = 3 +GraphicsBackend = 0 (OPENGL) +FailedGraphicsBackends = +VulkanDevice = +RenderingMode = 0 +SoftwareRenderer = False +HardwareTransform = True +SoftwareSkinning = True +TextureFiltering = 1 +BufferFiltering = 1 +InternalResolution = 1 +AndroidHwScale = 1 +HighQualityDepth = 1 +FrameSkip = 3 +FrameSkipType = 0 +AutoFrameSkip = True +FrameRate = -1 +FrameRate2 = -1 +FrameSkipUnthrottle = True +ForceMaxEmulatedFPS = 30 +AnisotropyLevel = 4 +VertexDecCache = True +TextureBackoffCache = True +TextureSecondaryCache = False +FullScreen = True +FullScreenMulti = False +SmallDisplayZoomType = 2 +SmallDisplayOffsetX = 0.500000 +SmallDisplayOffsetY = 0.500000 +SmallDisplayZoomLevel = 1.000000 +ImmersiveMode = False +SustainedPerformanceMode = False +TrueColor = True +ReplaceTextures = True +SaveNewTextures = False +IgnoreTextureFilenames = True +TexScalingLevel = 1 +TexScalingType = 0 +TexDeposterize = False +VSyncInterval = True +DisableStencilTest = False +BloomHack = 2 +TimerHack = False +SplineBezierQuality = 0 +HardwareTessellation = False +PostShader = Off +MemBlockTransferGPU = True +DisableSlowFramebufEffects = True +FragmentTestCache = True +LogFrameDrops = False +EnableCardboardVR = False +DisabledGraphicsBackends = +CameraDevice = +UnthrottleMode = CONTINUOUS +IgnoreScreenInsets = True +TexHardwareScaling = False +TextureShader = Off +InflightFrames = 3 +RenderDuplicateFrames = True +ShaderChainRequires60FPS = False +ClearFramebuffersOnFirstUseHack = False +SoftwareRendererJit = True +UnthrottlingMode = CONTINUOUS +ReplaceTexturesAllowLate = True +iShowStatusFlags = 0 +AndroidFramerateMode = 1 +UseGeometryShader = False +SkipBufferEffects = False +DisableRangeCulling = False +Smart2DTexFiltering = False +StereoRendering = False +StereoToMonoShader = RedBlue +AnalogFrameRate = 240 +MultiSampleLevel = 0 +DisplayOffsetX = 0.500000 +DisplayOffsetY = 0.500000 +DisplayScale = 1.000000 +DisplayIntegerScale = False +DisplayAspectRatio = 1.000000 +DisplayStretch = False +DisplayCropTo16x9 = False +VSync = True +SkipGPUReadbackMode = 1 +MultiThreading = True +GpuLogProfiler = False +UberShaderVertex = True +UberShaderFragment = True +[Sound] +Enable = True +AudioBackend = 0 +AudioLatency = 1 +ExtraAudioBuffering = False +SoundSpeedHack = False +AudioResampler = False +GlobalVolume = 10 +AltSpeedVolume = -1 +AutoAudioDevice = True +ReverbVolume = 10 +AchievementSoundVolume = 6 +AudioDevice = +[Control] +HapticFeedback = False +ShowTouchCross = True +ShowTouchCircle = True +ShowTouchSquare = True +ShowTouchTriangle = True +ComboKey0Mapping = 0 +ComboKey1Mapping = 0 +ComboKey2Mapping = 0 +ComboKey3Mapping = 0 +ComboKey4Mapping = 0 +ShowTouchPause = False +ShowTouchControls = False +DisableDpadDiagonals = False +GamepadOnlyFocused = False +TouchButtonStyle = 1 +TouchButtonOpacity = 65 +TouchButtonHideSeconds = 20 +AutoCenterTouchAnalog = False +ActionButtonSpacing2 = 1.000000 +ActionButtonCenterX = 0.937500 +ActionButtonCenterY = 0.900000 +ActionButtonScale = 1.150000 +DPadX = 0.074479 +DPadY = 0.760000 +DPadScale = 1.150000 +ShowTouchDpad = True +DPadSpacing = 1.000000 +StartKeyX = 0.559896 +StartKeyY = 0.942500 +StartKeyScale = 1.150000 +ShowTouchStart = True +SelectKeyX = 0.500000 +SelectKeyY = 0.942500 +SelectKeyScale = 1.150000 +ShowTouchSelect = True +UnthrottleKeyX = 0.440104 +UnthrottleKeyY = 0.942500 +UnthrottleKeyScale = 1.150000 +ShowTouchUnthrottle = True +LKeyX = 0.035937 +LKeyY = 0.635833 +LKeyScale = 1.150000 +ShowTouchLTrigger = True +RKeyX = 0.964063 +RKeyY = 0.635833 +RKeyScale = 1.150000 +ShowTouchRTrigger = True +AnalogStickX = 0.074479 +AnalogStickY = 0.923333 +AnalogStickScale = 1.150000 +ShowAnalogStick = True +fcombo0X = 0.571875 +fcombo0Y = 0.500000 +comboKeyScale0 = 1.150000 +ShowComboKey0 = False +fcombo1X = 0.631771 +fcombo1Y = 0.500000 +comboKeyScale1 = 1.150000 +ShowComboKey1 = False +fcombo2X = 0.691667 +fcombo2Y = 0.500000 +comboKeyScale2 = 1.150000 +ShowComboKey2 = False +fcombo3X = 0.571875 +fcombo3Y = 0.333333 +comboKeyScale3 = 1.150000 +ShowComboKey3 = False +fcombo4X = 0.631771 +fcombo4Y = 0.333333 +comboKeyScale4 = 1.150000 +ShowComboKey4 = False +Speed1KeyX = 0.440104 +Speed1KeyY = 0.885000 +Speed1KeyScale = 1.150000 +ShowSpeed1Key = False +Speed2KeyX = 0.500000 +Speed2KeyY = 0.885000 +Speed2KeyScale = 1.150000 +ShowSpeed2Key = False +XInputAnalogSensitivity = 1.000000 +AnalogLimiterDeadzone = 0.600000 +UseMouse = False +MapMouse = False +ConfineMap = False +MouseSensitivity = 0.100000 +MouseSmoothing = 0.900000 +ComboKey0Toggle = False +ComboKey1Toggle = False +ComboKey2Toggle = False +ComboKey3Toggle = False +ComboKey4Toggle = False +AnalogAutoRotSpeed = 15.000000 +TouchSnapToGrid = False +TouchSnapGridSize = 64 +RightAnalogStickX = 0.875000 +RightAnalogStickY = 0.856250 +RightAnalogStickScale = 1.150000 +ShowRightAnalogStick = False +RapidFireKeyX = 0.619792 +RapidFireKeyY = 0.784375 +RapidFireKeyScale = 1.150000 +ShowRapidFireKey = False +AnalogRotationCWKeyX = 0.500000 +AnalogRotationKeyCWY = 0.676562 +AnalogRotationKeyCWScale = 1.150000 +ShowAnalogRotationCWKey = False +AnalogRotationCCWKeyX = 0.380208 +AnalogRotationKeyCCWY = 0.676562 +AnalogRotationKeyCCWScale = 1.150000 +ShowAnalogRotationCCWKey = False +Custom0Mapping = 0x0000000000000000 +Custom0Image = 0 +Custom0Shape = 0 +Custom0Toggle = False +Custom1Mapping = 0x0000000000000000 +Custom1Image = 1 +Custom1Shape = 0 +Custom1Toggle = False +Custom2Mapping = 0x0000000000000000 +Custom2Image = 2 +Custom2Shape = 0 +Custom2Toggle = False +Custom3Mapping = 0x0000000000000000 +Custom3Image = 3 +Custom3Shape = 0 +Custom3Toggle = False +Custom4Mapping = 0x0000000000000000 +Custom4Image = 4 +Custom4Shape = 0 +Custom4Toggle = False +Custom5Mapping = 0x0000000000000000 +Custom5Image = 0 +Custom5Shape = 1 +Custom5Toggle = False +Custom6Mapping = 0x0000000000000000 +Custom6Image = 1 +Custom6Shape = 1 +Custom6Toggle = False +Custom7Mapping = 0x0000000000000000 +Custom7Image = 2 +Custom7Shape = 1 +Custom7Toggle = False +Custom8Mapping = 0x0000000000000000 +Custom8Image = 3 +Custom8Shape = 1 +Custom8Toggle = False +Custom9Mapping = 0x0000000000000000 +Custom9Image = 4 +Custom9Shape = 1 +Custom9Toggle = False +fcombo5X = 0.428125 +fcombo5Y = 0.500000 +comboKeyScale5 = 1.150000 +ShowComboKey5 = False +fcombo6X = 0.368229 +fcombo6Y = 0.500000 +comboKeyScale6 = 1.150000 +ShowComboKey6 = False +fcombo7X = 0.308333 +fcombo7Y = 0.500000 +comboKeyScale7 = 1.150000 +ShowComboKey7 = False +fcombo8X = 0.428125 +fcombo8Y = 0.333333 +comboKeyScale8 = 1.150000 +ShowComboKey8 = False +fcombo9X = 0.368229 +fcombo9Y = 0.333333 +comboKeyScale9 = 1.150000 +ShowComboKey9 = False +AnalogDeadzone = 0.150000 +AnalogInverseDeadzone = 0.000000 +AnalogSensitivity = 1.100000 +AnalogIsCircular = False +LeftStickHeadScale = 1.000000 +RightStickHeadScale = 1.000000 +HideStickBackground = False +SystemControls = True +[Network] +EnableWlan = False +EnableAdhocServer = False +proAdhocServer = myneighborsushicat.com +PortOffset = 0 +MinTimeout = 1 +TCPNoDelay = False +EnableUPnP = False +UPnPUseOriginalPort = True +EnableNetworkChat = False +ChatButtonPosition = 0 +ChatScreenPosition = 0 +EnableQuickChat = True +QuickChat1 = Quick Chat 1 +QuickChat2 = Quick Chat 2 +QuickChat3 = Quick Chat 3 +QuickChat4 = Quick Chat 4 +QuickChat5 = Quick Chat 5 +ForcedFirstConnect = False +[SystemParam] +PSPModel = 0 +PSPFirmwareVersion = 660 +NickName = PPSSPP +proAdhocServer = black-seraph.com +MacAddress = 4e:7a:78:d9:49:32 +PortOffset = 0 +Language = 1 +TimeFormat = 1 +DateFormat = 1 +TimeZone = 0 +DayLightSavings = False +ButtonPreference = 1 +LockParentalLevel = 0 +WlanAdhocChannel = 0 +WlanPowerSave = False +EncryptSave = True +SavedataUpgradeVersion = True +ParamTimeFormat = 0 +ParamDateFormat = 0 +MemStickSize = 16 +[Debugger] +DisasmWindowX = -1 +DisasmWindowY = -1 +DisasmWindowW = -1 +DisasmWindowH = -1 +GEWindowX = -1 +GEWindowY = -1 +GEWindowW = -1 +GEWindowH = -1 +ConsoleWindowX = -1 +ConsoleWindowY = -1 +FontWidth = 8 +FontHeight = 12 +DisplayStatusBar = True +ShowBottomTabTitles = True +ShowDeveloperMenu = False +SkipDeadbeefFilling = False +FuncHashMap = False +DrawFrameGraph = False +MemInfoDetailed = False +[Upgrade] +UpgradeMessage = +UpgradeVersion = 1.12.0 +DismissedVersion = +[Theme] +ItemStyleFg = 0xffffffff +ItemStyleBg = 0x55000000 +ItemFocusedStyleFg = 0xffffffff +ItemFocusedStyleBg = 0xffedc24c +ItemDownStyleFg = 0xffffffff +ItemDownStyleBg = 0xffbd9939 +ItemDisabledStyleFg = 0x80eeeeee +ItemDisabledStyleBg = 0x55e0d4af +ItemHighlightedStyleFg = 0xffffffff +ItemHighlightedStyleBg = 0x55bdbb39 +ButtonStyleFg = 0xffffffff +ButtonStyleBg = 0x55000000 +ButtonFocusedStyleFg = 0xffffffff +ButtonFocusedStyleBg = 0xffedc24c +ButtonDownStyleFg = 0xffffffff +ButtonDownStyleBg = 0xffbd9939 +ButtonDisabledStyleFg = 0x80eeeeee +ButtonDisabledStyleBg = 0x55e0d4af +ButtonHighlightedStyleFg = 0xffffffff +ButtonHighlightedStyleBg = 0x55bdbb39 +HeaderStyleFg = 0xffffffff +InfoStyleFg = 0xffffffff +InfoStyleBg = 0x00000000 +PopupTitleStyleFg = 0xffe3be59 +PopupStyleFg = 0xffffffff +PopupStyleBg = 0xff303030 +ThemeName = Default +[Recent] +MaxRecent = 30 +[Log] +SYSTEMEnabled = True +SYSTEMLevel = 4 +BOOTEnabled = True +BOOTLevel = 4 +COMMONEnabled = True +COMMONLevel = 4 +CPUEnabled = True +CPULevel = 4 +FILESYSEnabled = True +FILESYSLevel = 4 +G3DEnabled = True +G3DLevel = 4 +HLEEnabled = True +HLELevel = 4 +JITEnabled = True +JITLevel = 4 +LOADEREnabled = True +LOADERLevel = 4 +MEEnabled = True +MELevel = 4 +MEMMAPEnabled = True +MEMMAPLevel = 4 +SASMIXEnabled = True +SASMIXLevel = 4 +SAVESTATEEnabled = True +SAVESTATELevel = 4 +FRAMEBUFEnabled = True +FRAMEBUFLevel = 4 +SCEAUDIOEnabled = True +SCEAUDIOLevel = 4 +SCECTRLEnabled = True +SCECTRLLevel = 4 +SCEDISPEnabled = True +SCEDISPLevel = 4 +SCEFONTEnabled = True +SCEFONTLevel = 4 +SCEGEEnabled = True +SCEGELevel = 4 +SCEINTCEnabled = True +SCEINTCLevel = 4 +SCEIOEnabled = True +SCEIOLevel = 4 +SCEKERNELEnabled = True +SCEKERNELLevel = 4 +SCEMODULEEnabled = True +SCEMODULELevel = 4 +SCENETEnabled = True +SCENETLevel = 4 +SCERTCEnabled = True +SCERTCLevel = 4 +SCESASEnabled = True +SCESASLevel = 4 +SCEUTILEnabled = True +SCEUTILLevel = 4 +SCEMISCEnabled = True +SCEMISCLevel = 4 +AUDIOEnabled = True +AUDIOLevel = 2 +IOEnabled = True +IOLevel = 2 +[PostShaderSetting] +BloomSettingValue1 = 0.600000 +BloomSettingValue2 = 0.500000 +CRTSettingValue1 = 1.000000 +CartoonSettingValue1 = 0.500000 +ColorCorrectionSettingValue1 = 1.000000 +ColorCorrectionSettingValue2 = 1.000000 +ColorCorrectionSettingValue3 = 1.000000 +ColorCorrectionSettingValue4 = 1.000000 +ScanlinesSettingValue1 = 1.000000 +ScanlinesSettingValue2 = 0.500000 +SharpenSettingValue1 = 1.500000 +[VR] +VREnable = True +VREnable6DoF = True +VREnableStereo = False +VREnableMotions = True +VRForce72Hz = True +VRManualForceVR = False +VRPassthrough = False +VRRescaleHUD = True +VRCameraDistance = 0.000000 +VRCameraHeight = 0.000000 +VRCameraSide = 0.000000 +VRCameraPitch = 0 +VRCanvasDistance = 12.000000 +VRCanvas3DDistance = 3.000000 +VRHeadUpDisplayScale = 0.300000 +VRMotionLength = 0.500000 +VRHeadRotationScale = 5.000000 +VRHeadRotationEnabled = False +VRHeadRotationSmoothing = False diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/RK3566/controls.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/RK3566/controls.ini new file mode 100644 index 0000000000..aedbae2cf7 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/RK3566/controls.ini @@ -0,0 +1,20 @@ +[ControlMapping] +Up = 10-19 +Down = 10-20 +Left = 10-21 +Right = 10-22 +Circle = 10-190 +Cross = 10-189 +Square = 10-188 +Triangle = 10-191 +Start = 10-197 +Select = 10-196 +L = 10-193 +R = 10-192 +An.Up = 10-4003 +An.Down = 10-4002 +An.Left = 10-4001 +An.Right = 10-4000 +Pause = 10-4,10-106 +Save State = 10-4010 +Load State = 10-4008 diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/RK3566/ppsspp.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/RK3566/ppsspp.ini new file mode 100755 index 0000000000..8be2d8b3ab --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/RK3566/ppsspp.ini @@ -0,0 +1,557 @@ +[General] +FirstRun = False +RunCount = 0 +Enable Logging = False +AutoRun = True +Browse = False +IgnoreBadMemAccess = False +CurrentDirectory = /storage/roms/psp +ShowDebuggerOnLoad = False +CheckForNewVersion = False +Language = en_US +ForceLagSync = False +DiscordPresence = False +NumWorkerThreads = 8 +AutoLoadSaveState = 0 +EnableCheats = True +CwCheatRefreshRate = 77 +ScreenshotsAsPNG = False +UseFFV1 = False +DumpFrames = False +DumpAudio = False +SaveLoadResetsAVdumping = False +StateSlot = 0 +EnableStateUndo = True +RewindFlipFrequency = 0 +GridView1 = True +GridView2 = True +GridView3 = False +ComboMode = 0 +ReportingHost = default +AutoSaveSymbolMap = False +CacheFullIsoInRam = False +RemoteISOPort = 0 +LastRemoteISOServer = +LastRemoteISOPort = 0 +RemoteISOManualConfig = False +RemoteShareOnStartup = False +RemoteISOSubdir = / +RemoteDebuggerOnStartup = False +InternalScreenRotation = 1 +PauseWhenMinimized = False +DumpDecryptedEboots = False +MemStickInserted = True +ForceLagSync2 = False +UISound = True +CwCheatScrollPosition = 0 +DumpVideoOutput = False +ShowRegionOnGameIcon = False +ShowIDOnGameIcon = False +GameGridScale = 1.000000 +RightAnalogUp = 0 +RightAnalogDown = 0 +RightAnalogLeft = 0 +RightAnalogRight = 0 +RightAnalogPress = 0 +RightAnalogCustom = False +LoadPlugins = False +GameListScrollPosition = 0.000000 +StateLoadUndoGame = NA +StateUndoLastSaveGame = NA +StateUndoLastSaveSlot = -5 +ShowOnScreenMessage = True +RightAnalogDisableDiagonal = False +SwipeUp = 0 +SwipeDown = 0 +SwipeLeft = 0 +SwipeRight = 0 +SwipeSensitivity = 1.000000 +SwipeSmoothing = 0.300000 +DoubleTapGesture = 0 +GestureControlEnabled = False +BackgroundAnimation = 1 +EnablePlugins = True +[CPU] +CPUCore = 1 +SeparateSASThread = True +SeparateIOThread = True +IOTimingMethod = 0 +FastMemoryAccess = True +FuncReplacements = True +HideSlowWarnings = False +HideStateWarnings = False +PreloadFunctions = False +CPUSpeed = 0 +JitDisableFlags = 0x00000000 +FunctionReplacements = True +[Graphics] +EnableCardboard = False +CardboardScreenSize = 50 +CardboardXShift = 0 +CardboardYShift = 0 +ShowFPSCounter = 3 +GraphicsBackend = 0 (OPENGL) +FailedGraphicsBackends = +VulkanDevice = +RenderingMode = 0 +SoftwareRenderer = False +HardwareTransform = True +SoftwareSkinning = True +TextureFiltering = 1 +BufferFiltering = 1 +InternalResolution = 1 +AndroidHwScale = 1 +HighQualityDepth = 1 +FrameSkip = 3 +FrameSkipType = 0 +AutoFrameSkip = True +FrameRate = -1 +FrameRate2 = -1 +FrameSkipUnthrottle = True +ForceMaxEmulatedFPS = 30 +AnisotropyLevel = 4 +VertexDecCache = True +TextureBackoffCache = True +TextureSecondaryCache = False +FullScreen = True +FullScreenMulti = False +SmallDisplayZoomType = 2 +SmallDisplayOffsetX = 0.500000 +SmallDisplayOffsetY = 0.500000 +SmallDisplayZoomLevel = 1.000000 +ImmersiveMode = False +SustainedPerformanceMode = False +TrueColor = True +ReplaceTextures = True +SaveNewTextures = False +IgnoreTextureFilenames = True +TexScalingLevel = 1 +TexScalingType = 0 +TexDeposterize = False +VSyncInterval = True +DisableStencilTest = False +BloomHack = 2 +TimerHack = False +SplineBezierQuality = 0 +HardwareTessellation = False +PostShader = Off +MemBlockTransferGPU = True +DisableSlowFramebufEffects = True +FragmentTestCache = True +LogFrameDrops = False +EnableCardboardVR = False +DisabledGraphicsBackends = +CameraDevice = +UnthrottleMode = CONTINUOUS +IgnoreScreenInsets = True +TexHardwareScaling = False +TextureShader = Off +InflightFrames = 3 +RenderDuplicateFrames = True +ShaderChainRequires60FPS = False +ClearFramebuffersOnFirstUseHack = False +SoftwareRendererJit = True +UnthrottlingMode = CONTINUOUS +ReplaceTexturesAllowLate = True +iShowStatusFlags = 0 +AndroidFramerateMode = 1 +UseGeometryShader = False +SkipBufferEffects = False +DisableRangeCulling = False +Smart2DTexFiltering = False +StereoRendering = False +StereoToMonoShader = RedBlue +AnalogFrameRate = 240 +MultiSampleLevel = 0 +DisplayOffsetX = 0.500000 +DisplayOffsetY = 0.500000 +DisplayScale = 1.000000 +DisplayIntegerScale = False +DisplayAspectRatio = 1.000000 +DisplayStretch = False +DisplayCropTo16x9 = False +VSync = True +SkipGPUReadbackMode = 1 +MultiThreading = True +GpuLogProfiler = False +UberShaderVertex = True +UberShaderFragment = True +[Sound] +Enable = True +AudioBackend = 0 +AudioLatency = 1 +ExtraAudioBuffering = False +SoundSpeedHack = False +AudioResampler = False +GlobalVolume = 10 +AltSpeedVolume = -1 +AutoAudioDevice = True +ReverbVolume = 10 +AchievementSoundVolume = 6 +AudioDevice = +[Control] +HapticFeedback = False +ShowTouchCross = True +ShowTouchCircle = True +ShowTouchSquare = True +ShowTouchTriangle = True +ComboKey0Mapping = 0 +ComboKey1Mapping = 0 +ComboKey2Mapping = 0 +ComboKey3Mapping = 0 +ComboKey4Mapping = 0 +ShowTouchPause = False +ShowTouchControls = False +DisableDpadDiagonals = False +GamepadOnlyFocused = False +TouchButtonStyle = 1 +TouchButtonOpacity = 65 +TouchButtonHideSeconds = 20 +AutoCenterTouchAnalog = False +ActionButtonSpacing2 = 1.000000 +ActionButtonCenterX = 0.937500 +ActionButtonCenterY = 0.900000 +ActionButtonScale = 1.150000 +DPadX = 0.074479 +DPadY = 0.760000 +DPadScale = 1.150000 +ShowTouchDpad = True +DPadSpacing = 1.000000 +StartKeyX = 0.559896 +StartKeyY = 0.942500 +StartKeyScale = 1.150000 +ShowTouchStart = True +SelectKeyX = 0.500000 +SelectKeyY = 0.942500 +SelectKeyScale = 1.150000 +ShowTouchSelect = True +UnthrottleKeyX = 0.440104 +UnthrottleKeyY = 0.942500 +UnthrottleKeyScale = 1.150000 +ShowTouchUnthrottle = True +LKeyX = 0.035937 +LKeyY = 0.635833 +LKeyScale = 1.150000 +ShowTouchLTrigger = True +RKeyX = 0.964063 +RKeyY = 0.635833 +RKeyScale = 1.150000 +ShowTouchRTrigger = True +AnalogStickX = 0.074479 +AnalogStickY = 0.923333 +AnalogStickScale = 1.150000 +ShowAnalogStick = True +fcombo0X = 0.571875 +fcombo0Y = 0.500000 +comboKeyScale0 = 1.150000 +ShowComboKey0 = False +fcombo1X = 0.631771 +fcombo1Y = 0.500000 +comboKeyScale1 = 1.150000 +ShowComboKey1 = False +fcombo2X = 0.691667 +fcombo2Y = 0.500000 +comboKeyScale2 = 1.150000 +ShowComboKey2 = False +fcombo3X = 0.571875 +fcombo3Y = 0.333333 +comboKeyScale3 = 1.150000 +ShowComboKey3 = False +fcombo4X = 0.631771 +fcombo4Y = 0.333333 +comboKeyScale4 = 1.150000 +ShowComboKey4 = False +Speed1KeyX = 0.440104 +Speed1KeyY = 0.885000 +Speed1KeyScale = 1.150000 +ShowSpeed1Key = False +Speed2KeyX = 0.500000 +Speed2KeyY = 0.885000 +Speed2KeyScale = 1.150000 +ShowSpeed2Key = False +XInputAnalogSensitivity = 1.000000 +AnalogLimiterDeadzone = 0.600000 +UseMouse = False +MapMouse = False +ConfineMap = False +MouseSensitivity = 0.100000 +MouseSmoothing = 0.900000 +ComboKey0Toggle = False +ComboKey1Toggle = False +ComboKey2Toggle = False +ComboKey3Toggle = False +ComboKey4Toggle = False +AnalogAutoRotSpeed = 15.000000 +TouchSnapToGrid = False +TouchSnapGridSize = 64 +RightAnalogStickX = 0.875000 +RightAnalogStickY = 0.856250 +RightAnalogStickScale = 1.150000 +ShowRightAnalogStick = False +RapidFireKeyX = 0.619792 +RapidFireKeyY = 0.784375 +RapidFireKeyScale = 1.150000 +ShowRapidFireKey = False +AnalogRotationCWKeyX = 0.500000 +AnalogRotationKeyCWY = 0.676562 +AnalogRotationKeyCWScale = 1.150000 +ShowAnalogRotationCWKey = False +AnalogRotationCCWKeyX = 0.380208 +AnalogRotationKeyCCWY = 0.676562 +AnalogRotationKeyCCWScale = 1.150000 +ShowAnalogRotationCCWKey = False +Custom0Mapping = 0x0000000000000000 +Custom0Image = 0 +Custom0Shape = 0 +Custom0Toggle = False +Custom1Mapping = 0x0000000000000000 +Custom1Image = 1 +Custom1Shape = 0 +Custom1Toggle = False +Custom2Mapping = 0x0000000000000000 +Custom2Image = 2 +Custom2Shape = 0 +Custom2Toggle = False +Custom3Mapping = 0x0000000000000000 +Custom3Image = 3 +Custom3Shape = 0 +Custom3Toggle = False +Custom4Mapping = 0x0000000000000000 +Custom4Image = 4 +Custom4Shape = 0 +Custom4Toggle = False +Custom5Mapping = 0x0000000000000000 +Custom5Image = 0 +Custom5Shape = 1 +Custom5Toggle = False +Custom6Mapping = 0x0000000000000000 +Custom6Image = 1 +Custom6Shape = 1 +Custom6Toggle = False +Custom7Mapping = 0x0000000000000000 +Custom7Image = 2 +Custom7Shape = 1 +Custom7Toggle = False +Custom8Mapping = 0x0000000000000000 +Custom8Image = 3 +Custom8Shape = 1 +Custom8Toggle = False +Custom9Mapping = 0x0000000000000000 +Custom9Image = 4 +Custom9Shape = 1 +Custom9Toggle = False +fcombo5X = 0.428125 +fcombo5Y = 0.500000 +comboKeyScale5 = 1.150000 +ShowComboKey5 = False +fcombo6X = 0.368229 +fcombo6Y = 0.500000 +comboKeyScale6 = 1.150000 +ShowComboKey6 = False +fcombo7X = 0.308333 +fcombo7Y = 0.500000 +comboKeyScale7 = 1.150000 +ShowComboKey7 = False +fcombo8X = 0.428125 +fcombo8Y = 0.333333 +comboKeyScale8 = 1.150000 +ShowComboKey8 = False +fcombo9X = 0.368229 +fcombo9Y = 0.333333 +comboKeyScale9 = 1.150000 +ShowComboKey9 = False +AnalogDeadzone = 0.150000 +AnalogInverseDeadzone = 0.000000 +AnalogSensitivity = 1.100000 +AnalogIsCircular = False +LeftStickHeadScale = 1.000000 +RightStickHeadScale = 1.000000 +HideStickBackground = False +SystemControls = True +[Network] +EnableWlan = False +EnableAdhocServer = False +proAdhocServer = myneighborsushicat.com +PortOffset = 0 +MinTimeout = 1 +TCPNoDelay = False +EnableUPnP = False +UPnPUseOriginalPort = True +EnableNetworkChat = False +ChatButtonPosition = 0 +ChatScreenPosition = 0 +EnableQuickChat = True +QuickChat1 = Quick Chat 1 +QuickChat2 = Quick Chat 2 +QuickChat3 = Quick Chat 3 +QuickChat4 = Quick Chat 4 +QuickChat5 = Quick Chat 5 +ForcedFirstConnect = False +[SystemParam] +PSPModel = 0 +PSPFirmwareVersion = 660 +NickName = PPSSPP +proAdhocServer = black-seraph.com +MacAddress = 4e:7a:78:d9:49:32 +PortOffset = 0 +Language = 1 +TimeFormat = 1 +DateFormat = 1 +TimeZone = 0 +DayLightSavings = False +ButtonPreference = 1 +LockParentalLevel = 0 +WlanAdhocChannel = 0 +WlanPowerSave = False +EncryptSave = True +SavedataUpgradeVersion = True +ParamTimeFormat = 0 +ParamDateFormat = 0 +MemStickSize = 16 +[Debugger] +DisasmWindowX = -1 +DisasmWindowY = -1 +DisasmWindowW = -1 +DisasmWindowH = -1 +GEWindowX = -1 +GEWindowY = -1 +GEWindowW = -1 +GEWindowH = -1 +ConsoleWindowX = -1 +ConsoleWindowY = -1 +FontWidth = 8 +FontHeight = 12 +DisplayStatusBar = True +ShowBottomTabTitles = True +ShowDeveloperMenu = False +SkipDeadbeefFilling = False +FuncHashMap = False +DrawFrameGraph = False +MemInfoDetailed = False +[Upgrade] +UpgradeMessage = +UpgradeVersion = 1.12.0 +DismissedVersion = +[Theme] +ItemStyleFg = 0xffffffff +ItemStyleBg = 0x55000000 +ItemFocusedStyleFg = 0xffffffff +ItemFocusedStyleBg = 0xffedc24c +ItemDownStyleFg = 0xffffffff +ItemDownStyleBg = 0xffbd9939 +ItemDisabledStyleFg = 0x80eeeeee +ItemDisabledStyleBg = 0x55e0d4af +ItemHighlightedStyleFg = 0xffffffff +ItemHighlightedStyleBg = 0x55bdbb39 +ButtonStyleFg = 0xffffffff +ButtonStyleBg = 0x55000000 +ButtonFocusedStyleFg = 0xffffffff +ButtonFocusedStyleBg = 0xffedc24c +ButtonDownStyleFg = 0xffffffff +ButtonDownStyleBg = 0xffbd9939 +ButtonDisabledStyleFg = 0x80eeeeee +ButtonDisabledStyleBg = 0x55e0d4af +ButtonHighlightedStyleFg = 0xffffffff +ButtonHighlightedStyleBg = 0x55bdbb39 +HeaderStyleFg = 0xffffffff +InfoStyleFg = 0xffffffff +InfoStyleBg = 0x00000000 +PopupTitleStyleFg = 0xffe3be59 +PopupStyleFg = 0xffffffff +PopupStyleBg = 0xff303030 +ThemeName = Default +[Recent] +MaxRecent = 30 +[Log] +SYSTEMEnabled = True +SYSTEMLevel = 4 +BOOTEnabled = True +BOOTLevel = 4 +COMMONEnabled = True +COMMONLevel = 4 +CPUEnabled = True +CPULevel = 4 +FILESYSEnabled = True +FILESYSLevel = 4 +G3DEnabled = True +G3DLevel = 4 +HLEEnabled = True +HLELevel = 4 +JITEnabled = True +JITLevel = 4 +LOADEREnabled = True +LOADERLevel = 4 +MEEnabled = True +MELevel = 4 +MEMMAPEnabled = True +MEMMAPLevel = 4 +SASMIXEnabled = True +SASMIXLevel = 4 +SAVESTATEEnabled = True +SAVESTATELevel = 4 +FRAMEBUFEnabled = True +FRAMEBUFLevel = 4 +SCEAUDIOEnabled = True +SCEAUDIOLevel = 4 +SCECTRLEnabled = True +SCECTRLLevel = 4 +SCEDISPEnabled = True +SCEDISPLevel = 4 +SCEFONTEnabled = True +SCEFONTLevel = 4 +SCEGEEnabled = True +SCEGELevel = 4 +SCEINTCEnabled = True +SCEINTCLevel = 4 +SCEIOEnabled = True +SCEIOLevel = 4 +SCEKERNELEnabled = True +SCEKERNELLevel = 4 +SCEMODULEEnabled = True +SCEMODULELevel = 4 +SCENETEnabled = True +SCENETLevel = 4 +SCERTCEnabled = True +SCERTCLevel = 4 +SCESASEnabled = True +SCESASLevel = 4 +SCEUTILEnabled = True +SCEUTILLevel = 4 +SCEMISCEnabled = True +SCEMISCLevel = 4 +AUDIOEnabled = True +AUDIOLevel = 2 +IOEnabled = True +IOLevel = 2 +[PostShaderSetting] +BloomSettingValue1 = 0.600000 +BloomSettingValue2 = 0.500000 +CRTSettingValue1 = 1.000000 +CartoonSettingValue1 = 0.500000 +ColorCorrectionSettingValue1 = 1.000000 +ColorCorrectionSettingValue2 = 1.000000 +ColorCorrectionSettingValue3 = 1.000000 +ColorCorrectionSettingValue4 = 1.000000 +ScanlinesSettingValue1 = 1.000000 +ScanlinesSettingValue2 = 0.500000 +SharpenSettingValue1 = 1.500000 +[VR] +VREnable = True +VREnable6DoF = True +VREnableStereo = False +VREnableMotions = True +VRForce72Hz = True +VRManualForceVR = False +VRPassthrough = False +VRRescaleHUD = True +VRCameraDistance = 0.000000 +VRCameraHeight = 0.000000 +VRCameraSide = 0.000000 +VRCameraPitch = 0 +VRCanvasDistance = 12.000000 +VRCanvas3DDistance = 3.000000 +VRHeadUpDisplayScale = 0.300000 +VRMotionLength = 0.500000 +VRHeadRotationScale = 5.000000 +VRHeadRotationEnabled = False +VRHeadRotationSmoothing = False diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/RK3588/controls.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/RK3588/controls.ini new file mode 100644 index 0000000000..83c19ca1b2 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/RK3588/controls.ini @@ -0,0 +1,18 @@ +[ControlMapping] +Up = 10-19 +Down = 10-20 +Left = 10-21 +Right = 10-22 +Circle = 10-189 +Cross = 10-190 +Square = 10-188 +Triangle = 10-191 +Start = 10-197 +Select = 10-196 +L = 10-193 +R = 10-192 +An.Up = 10-4003 +An.Down = 10-4002 +An.Left = 10-4001 +An.Right = 10-4000 +Pause = 10-107 diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/RK3588/ppsspp.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/RK3588/ppsspp.ini new file mode 100755 index 0000000000..52c30f6c78 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/RK3588/ppsspp.ini @@ -0,0 +1,511 @@ +[General] +FirstRun = False +RunCount = 16 +Enable Logging = False +AutoRun = True +Browse = False +IgnoreBadMemAccess = False +CurrentDirectory = /storage/roms/psp +ShowDebuggerOnLoad = False +CheckForNewVersion = True +Language = en_US +ForceLagSync = False +DiscordPresence = False +NumWorkerThreads = 8 +AutoLoadSaveState = 0 +EnableCheats = True +CwCheatRefreshRate = 77 +ScreenshotsAsPNG = False +UseFFV1 = False +DumpFrames = False +DumpAudio = False +SaveLoadResetsAVdumping = False +StateSlot = 0 +EnableStateUndo = True +RewindFlipFrequency = 0 +GridView1 = True +GridView2 = True +GridView3 = False +ComboMode = 0 +ReportingHost = default +AutoSaveSymbolMap = False +CacheFullIsoInRam = False +RemoteISOPort = 0 +LastRemoteISOServer = +LastRemoteISOPort = 0 +RemoteISOManualConfig = False +RemoteShareOnStartup = False +RemoteISOSubdir = / +RemoteDebuggerOnStartup = False +InternalScreenRotation = 1 +PauseWhenMinimized = False +DumpDecryptedEboots = False +MemStickInserted = True +ForceLagSync2 = False +UISound = True +CwCheatScrollPosition = 0.000000 +DumpVideoOutput = False +ShowRegionOnGameIcon = False +ShowIDOnGameIcon = False +GameGridScale = 1.000000 +RightAnalogUp = 0 +RightAnalogDown = 0 +RightAnalogLeft = 0 +RightAnalogRight = 0 +RightAnalogPress = 0 +RightAnalogCustom = False +LoadPlugins = False +GameListScrollPosition = 0.000000 +StateLoadUndoGame = NA +StateUndoLastSaveGame = NA +StateUndoLastSaveSlot = -5 +ShowOnScreenMessage = True +RightAnalogDisableDiagonal = False +SwipeUp = 0 +SwipeDown = 0 +SwipeLeft = 0 +SwipeRight = 0 +SwipeSensitivity = 1.000000 +SwipeSmoothing = 0.300000 +DoubleTapGesture = 0 +GestureControlEnabled = False +BackgroundAnimation = 1 +EnablePlugins = True +[CPU] +CPUCore = 1 +SeparateSASThread = True +SeparateIOThread = True +IOTimingMethod = 0 +FastMemoryAccess = True +FuncReplacements = True +HideSlowWarnings = False +HideStateWarnings = False +PreloadFunctions = False +CPUSpeed = 0 +JitDisableFlags = 0x00000000 +FunctionReplacements = True +[Graphics] +EnableCardboard = False +CardboardScreenSize = 50 +CardboardXShift = 0 +CardboardYShift = 0 +ShowFPSCounter = 3 +GraphicsBackend = 0 (OPENGL) +FailedGraphicsBackends = +VulkanDevice = +RenderingMode = 0 +SoftwareRenderer = False +HardwareTransform = True +SoftwareSkinning = True +TextureFiltering = 1 +BufferFiltering = 1 +InternalResolution = 0 +AndroidHwScale = 1 +HighQualityDepth = 1 +FrameSkip = 0 +FrameSkipType = 0 +AutoFrameSkip = False +FrameRate = 0 +FrameRate2 = -1 +FrameSkipUnthrottle = True +ForceMaxEmulatedFPS = 30 +AnisotropyLevel = 0 +VertexDecCache = True +TextureBackoffCache = True +TextureSecondaryCache = False +FullScreen = True +FullScreenMulti = False +SmallDisplayZoomType = 2 +SmallDisplayOffsetX = 0.500000 +SmallDisplayOffsetY = 0.500000 +SmallDisplayZoomLevel = 1.000000 +ImmersiveMode = False +SustainedPerformanceMode = False +TrueColor = True +ReplaceTextures = True +SaveNewTextures = False +IgnoreTextureFilenames = True +TexScalingLevel = 1 +TexScalingType = 3 +TexDeposterize = False +VSyncInterval = True +DisableStencilTest = False +BloomHack = 2 +TimerHack = False +SplineBezierQuality = 0 +HardwareTessellation = False +PostShader = Off +MemBlockTransferGPU = True +DisableSlowFramebufEffects = True +FragmentTestCache = True +LogFrameDrops = False +EnableCardboardVR = False +DisabledGraphicsBackends = +CameraDevice = +UnthrottleMode = CONTINUOUS +IgnoreScreenInsets = True +TexHardwareScaling = False +TextureShader = Off +InflightFrames = 2 +RenderDuplicateFrames = True +ShaderChainRequires60FPS = False +ClearFramebuffersOnFirstUseHack = False +SoftwareRendererJit = True +UnthrottlingMode = CONTINUOUS +ReplaceTexturesAllowLate = True +[Sound] +Enable = True +AudioBackend = 0 +AudioLatency = 1 +ExtraAudioBuffering = False +SoundSpeedHack = False +AudioResampler = False +GlobalVolume = 10 +AltSpeedVolume = -1 +AutoAudioDevice = True +ReverbVolume = 10 +[Control] +HapticFeedback = False +ShowTouchCross = True +ShowTouchCircle = True +ShowTouchSquare = True +ShowTouchTriangle = True +ComboKey0Mapping = 0 +ComboKey1Mapping = 0 +ComboKey2Mapping = 0 +ComboKey3Mapping = 0 +ComboKey4Mapping = 0 +ShowTouchPause = False +ShowTouchControls = False +DisableDpadDiagonals = False +GamepadOnlyFocused = False +TouchButtonStyle = 1 +TouchButtonOpacity = 65 +TouchButtonHideSeconds = 20 +AutoCenterTouchAnalog = False +ActionButtonSpacing2 = 1.000000 +ActionButtonCenterX = 0.937500 +ActionButtonCenterY = 0.900000 +ActionButtonScale = 1.150000 +DPadX = 0.074479 +DPadY = 0.760000 +DPadScale = 1.150000 +ShowTouchDpad = True +DPadSpacing = 1.000000 +StartKeyX = 0.559896 +StartKeyY = 0.942500 +StartKeyScale = 1.150000 +ShowTouchStart = True +SelectKeyX = 0.500000 +SelectKeyY = 0.942500 +SelectKeyScale = 1.150000 +ShowTouchSelect = True +UnthrottleKeyX = 0.440104 +UnthrottleKeyY = 0.942500 +UnthrottleKeyScale = 1.150000 +ShowTouchUnthrottle = True +LKeyX = 0.035937 +LKeyY = 0.635833 +LKeyScale = 1.150000 +ShowTouchLTrigger = True +RKeyX = 0.964063 +RKeyY = 0.635833 +RKeyScale = 1.150000 +ShowTouchRTrigger = True +AnalogStickX = 0.074479 +AnalogStickY = 0.923333 +AnalogStickScale = 1.150000 +ShowAnalogStick = True +fcombo0X = 0.571875 +fcombo0Y = 0.500000 +comboKeyScale0 = 1.150000 +ShowComboKey0 = False +fcombo1X = 0.631771 +fcombo1Y = 0.500000 +comboKeyScale1 = 1.150000 +ShowComboKey1 = False +fcombo2X = 0.691667 +fcombo2Y = 0.500000 +comboKeyScale2 = 1.150000 +ShowComboKey2 = False +fcombo3X = 0.571875 +fcombo3Y = 0.333333 +comboKeyScale3 = 1.150000 +ShowComboKey3 = False +fcombo4X = 0.631771 +fcombo4Y = 0.333333 +comboKeyScale4 = 1.150000 +ShowComboKey4 = False +Speed1KeyX = 0.440104 +Speed1KeyY = 0.885000 +Speed1KeyScale = 1.150000 +ShowSpeed1Key = False +Speed2KeyX = 0.500000 +Speed2KeyY = 0.885000 +Speed2KeyScale = 1.150000 +ShowSpeed2Key = False +XInputAnalogSensitivity = 1.000000 +AnalogLimiterDeadzone = 0.600000 +UseMouse = False +MapMouse = False +ConfineMap = False +MouseSensitivity = 0.100000 +MouseSmoothing = 0.900000 +ComboKey0Toggle = False +ComboKey1Toggle = False +ComboKey2Toggle = False +ComboKey3Toggle = False +ComboKey4Toggle = False +AnalogAutoRotSpeed = 15.000000 +TouchSnapToGrid = False +TouchSnapGridSize = 64 +RightAnalogStickX = 0.875000 +RightAnalogStickY = 0.856250 +RightAnalogStickScale = 1.150000 +ShowRightAnalogStick = False +RapidFireKeyX = 0.619792 +RapidFireKeyY = 0.784375 +RapidFireKeyScale = 1.150000 +ShowRapidFireKey = False +AnalogRotationCWKeyX = 0.500000 +AnalogRotationKeyCWY = 0.676562 +AnalogRotationKeyCWScale = 1.150000 +ShowAnalogRotationCWKey = False +AnalogRotationCCWKeyX = 0.380208 +AnalogRotationKeyCCWY = 0.676562 +AnalogRotationKeyCCWScale = 1.150000 +ShowAnalogRotationCCWKey = False +Custom0Mapping = 0x0000000000000000 +Custom0Image = 0 +Custom0Shape = 0 +Custom0Toggle = False +Custom1Mapping = 0x0000000000000000 +Custom1Image = 1 +Custom1Shape = 0 +Custom1Toggle = False +Custom2Mapping = 0x0000000000000000 +Custom2Image = 2 +Custom2Shape = 0 +Custom2Toggle = False +Custom3Mapping = 0x0000000000000000 +Custom3Image = 3 +Custom3Shape = 0 +Custom3Toggle = False +Custom4Mapping = 0x0000000000000000 +Custom4Image = 4 +Custom4Shape = 0 +Custom4Toggle = False +Custom5Mapping = 0x0000000000000000 +Custom5Image = 0 +Custom5Shape = 1 +Custom5Toggle = False +Custom6Mapping = 0x0000000000000000 +Custom6Image = 1 +Custom6Shape = 1 +Custom6Toggle = False +Custom7Mapping = 0x0000000000000000 +Custom7Image = 2 +Custom7Shape = 1 +Custom7Toggle = False +Custom8Mapping = 0x0000000000000000 +Custom8Image = 3 +Custom8Shape = 1 +Custom8Toggle = False +Custom9Mapping = 0x0000000000000000 +Custom9Image = 4 +Custom9Shape = 1 +Custom9Toggle = False +fcombo5X = 0.428125 +fcombo5Y = 0.500000 +comboKeyScale5 = 1.150000 +ShowComboKey5 = False +fcombo6X = 0.368229 +fcombo6Y = 0.500000 +comboKeyScale6 = 1.150000 +ShowComboKey6 = False +fcombo7X = 0.308333 +fcombo7Y = 0.500000 +comboKeyScale7 = 1.150000 +ShowComboKey7 = False +fcombo8X = 0.428125 +fcombo8Y = 0.333333 +comboKeyScale8 = 1.150000 +ShowComboKey8 = False +fcombo9X = 0.368229 +fcombo9Y = 0.333333 +comboKeyScale9 = 1.150000 +ShowComboKey9 = False +AnalogDeadzone = 0.150000 +AnalogInverseDeadzone = 0.000000 +AnalogSensitivity = 1.100000 +AnalogIsCircular = False +LeftStickHeadScale = 1.000000 +RightStickHeadScale = 1.000000 +HideStickBackground = False +SystemControls = True +[Network] +EnableWlan = False +EnableAdhocServer = False +proAdhocServer = myneighborsushicat.com +PortOffset = 0 +MinTimeout = 1 +TCPNoDelay = False +EnableUPnP = False +UPnPUseOriginalPort = True +EnableNetworkChat = False +ChatButtonPosition = 0 +ChatScreenPosition = 0 +EnableQuickChat = True +QuickChat1 = Quick Chat 1 +QuickChat2 = Quick Chat 2 +QuickChat3 = Quick Chat 3 +QuickChat4 = Quick Chat 4 +QuickChat5 = Quick Chat 5 +ForcedFirstConnect = False +[SystemParam] +PSPModel = 0 +PSPFirmwareVersion = 660 +NickName = PPSSPP +proAdhocServer = black-seraph.com +MacAddress = 4e:7a:78:d9:49:32 +PortOffset = 0 +Language = 1 +TimeFormat = 1 +DateFormat = 1 +TimeZone = 0 +DayLightSavings = False +ButtonPreference = 1 +LockParentalLevel = 0 +WlanAdhocChannel = 0 +WlanPowerSave = False +EncryptSave = True +SavedataUpgradeVersion = True +ParamTimeFormat = 0 +ParamDateFormat = 0 +MemStickSize = 16 +[Debugger] +DisasmWindowX = -1 +DisasmWindowY = -1 +DisasmWindowW = -1 +DisasmWindowH = -1 +GEWindowX = -1 +GEWindowY = -1 +GEWindowW = -1 +GEWindowH = -1 +ConsoleWindowX = -1 +ConsoleWindowY = -1 +FontWidth = 8 +FontHeight = 12 +DisplayStatusBar = True +ShowBottomTabTitles = True +ShowDeveloperMenu = False +SkipDeadbeefFilling = False +FuncHashMap = False +DrawFrameGraph = False +MemInfoDetailed = False +[Upgrade] +UpgradeMessage = +UpgradeVersion = 1.12.0 +DismissedVersion = +[Theme] +ItemStyleFg = 0xffffffff +ItemStyleBg = 0x55000000 +ItemFocusedStyleFg = 0xffffffff +ItemFocusedStyleBg = 0xffedc24c +ItemDownStyleFg = 0xffffffff +ItemDownStyleBg = 0xffbd9939 +ItemDisabledStyleFg = 0x80eeeeee +ItemDisabledStyleBg = 0x55e0d4af +ItemHighlightedStyleFg = 0xffffffff +ItemHighlightedStyleBg = 0x55bdbb39 +ButtonStyleFg = 0xffffffff +ButtonStyleBg = 0x55000000 +ButtonFocusedStyleFg = 0xffffffff +ButtonFocusedStyleBg = 0xffedc24c +ButtonDownStyleFg = 0xffffffff +ButtonDownStyleBg = 0xffbd9939 +ButtonDisabledStyleFg = 0x80eeeeee +ButtonDisabledStyleBg = 0x55e0d4af +ButtonHighlightedStyleFg = 0xffffffff +ButtonHighlightedStyleBg = 0x55bdbb39 +HeaderStyleFg = 0xffffffff +InfoStyleFg = 0xffffffff +InfoStyleBg = 0x00000000 +PopupTitleStyleFg = 0xffe3be59 +PopupStyleFg = 0xffffffff +PopupStyleBg = 0xff303030 +[Recent] +MaxRecent = 30 +[Log] +SYSTEMEnabled = True +SYSTEMLevel = 4 +BOOTEnabled = True +BOOTLevel = 4 +COMMONEnabled = True +COMMONLevel = 4 +CPUEnabled = True +CPULevel = 4 +FILESYSEnabled = True +FILESYSLevel = 4 +G3DEnabled = True +G3DLevel = 4 +HLEEnabled = True +HLELevel = 4 +JITEnabled = True +JITLevel = 4 +LOADEREnabled = True +LOADERLevel = 4 +MEEnabled = True +MELevel = 4 +MEMMAPEnabled = True +MEMMAPLevel = 4 +SASMIXEnabled = True +SASMIXLevel = 4 +SAVESTATEEnabled = True +SAVESTATELevel = 4 +FRAMEBUFEnabled = True +FRAMEBUFLevel = 4 +SCEAUDIOEnabled = True +SCEAUDIOLevel = 4 +SCECTRLEnabled = True +SCECTRLLevel = 4 +SCEDISPEnabled = True +SCEDISPLevel = 4 +SCEFONTEnabled = True +SCEFONTLevel = 4 +SCEGEEnabled = True +SCEGELevel = 4 +SCEINTCEnabled = True +SCEINTCLevel = 4 +SCEIOEnabled = True +SCEIOLevel = 4 +SCEKERNELEnabled = True +SCEKERNELLevel = 4 +SCEMODULEEnabled = True +SCEMODULELevel = 4 +SCENETEnabled = True +SCENETLevel = 4 +SCERTCEnabled = True +SCERTCLevel = 4 +SCESASEnabled = True +SCESASLevel = 4 +SCEUTILEnabled = True +SCEUTILLevel = 4 +SCEMISCEnabled = True +SCEMISCLevel = 4 +AUDIOEnabled = True +AUDIOLevel = 2 +IOEnabled = True +IOLevel = 2 +[PostShaderSetting] +BloomSettingValue1 = 0.600000 +BloomSettingValue2 = 0.500000 +CRTSettingValue1 = 1.000000 +CartoonSettingValue1 = 0.500000 +ColorCorrectionSettingValue1 = 1.000000 +ColorCorrectionSettingValue2 = 1.000000 +ColorCorrectionSettingValue3 = 1.000000 +ColorCorrectionSettingValue4 = 1.000000 +ScanlinesSettingValue1 = 1.000000 +ScanlinesSettingValue2 = 0.500000 +SharpenSettingValue1 = 1.500000 diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/S922X/controls.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/S922X/controls.ini new file mode 100755 index 0000000000..cfd01a7f7b --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/S922X/controls.ini @@ -0,0 +1,24 @@ +[ControlMapping] +Up = 10-19 +Down = 10-20 +Left = 10-21 +Right = 10-22 +Circle = 10-189 +Cross = 10-190 +Square = 10-188 +Triangle = 10-191 +Start = 10-197 +Select = 10-196 +L = 10-193 +R = 10-192 +An.Up = 10-4003 +An.Down = 10-4002 +An.Left = 10-4001 +An.Right = 10-4000 +Analog limiter = 1-60 +RapidFire = 1-59 +SpeedToggle = 1-68 +Pause = 1-111,10-106,10-104 +Rewind = 1-67 +Save State = 10-4010 +Load State = 10-4008 diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/S922X/ppsspp.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/S922X/ppsspp.ini new file mode 100755 index 0000000000..0ed304c815 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/S922X/ppsspp.ini @@ -0,0 +1,462 @@ +[General] +FirstRun = False +RunCount = 3 +Enable Logging = True +AutoRun = True +Browse = False +IgnoreBadMemAccess = True +CurrentDirectory = /storage +ShowDebuggerOnLoad = False +CheckForNewVersion = True +Language = en_US +ForceLagSync2 = False +DiscordPresence = True +UISound = False +AutoLoadSaveState = 0 +EnableCheats = True +CwCheatRefreshRate = 77 +CwCheatScrollPosition = 0.000000 +GameListScrollPosition = 0.000000 +ScreenshotsAsPNG = False +UseFFV1 = False +DumpFrames = False +DumpVideoOutput = False +DumpAudio = False +SaveLoadResetsAVdumping = False +StateSlot = 0 +EnableStateUndo = True +StateLoadUndoGame = NA +StateUndoLastSaveGame = NA +StateUndoLastSaveSlot = -5 +RewindSnapshotInterval = 0 +ShowOnScreenMessage = True +ShowRegionOnGameIcon = False +ShowIDOnGameIcon = False +GameGridScale = 1.000000 +GridView1 = True +GridView2 = True +GridView3 = False +RightAnalogUp = 0 +RightAnalogDown = 0 +RightAnalogLeft = 0 +RightAnalogRight = 0 +RightAnalogPress = 0 +RightAnalogCustom = False +RightAnalogDisableDiagonal = False +SwipeUp = 0 +SwipeDown = 0 +SwipeLeft = 0 +SwipeRight = 0 +SwipeSensitivity = 1.000000 +SwipeSmoothing = 0.300000 +DoubleTapGesture = 0 +GestureControlEnabled = False +ReportingHost = default +AutoSaveSymbolMap = False +CacheFullIsoInRam = False +RemoteISOPort = 0 +LastRemoteISOServer = +LastRemoteISOPort = 0 +RemoteISOManualConfig = False +RemoteShareOnStartup = False +RemoteISOSubdir = / +RemoteDebuggerOnStartup = False +InternalScreenRotation = 1 +BackgroundAnimation = 1 +TransparentBackground = True +UITint = 0.000000 +UISaturation = 1.000000 +PauseWhenMinimized = False +DumpDecryptedEboots = False +ShowMenuBar = True +MemStickInserted = True +EnablePlugins = True +IgnoreCompatSettings = +[CPU] +CPUCore = 1 +SeparateSASThread = True +IOTimingMethod = 0 +FastMemoryAccess = True +FunctionReplacements = True +HideSlowWarnings = False +HideStateWarnings = False +PreloadFunctions = False +JitDisableFlags = 0x00000000 +CPUSpeed = 0 +[Graphics] +EnableCardboardVR = False +CardboardScreenSize = 50 +CardboardXShift = 0 +CardboardYShift = 0 +iShowStatusFlags = 0 +GraphicsBackend = 3 (VULKAN) +FailedGraphicsBackends = +DisabledGraphicsBackends = +VulkanDevice = +CameraDevice = +UseGeometryShader = False +SkipBufferEffects = False +SoftwareRenderer = False +SoftwareRendererJit = True +HardwareTransform = True +SoftwareSkinning = True +TextureFiltering = 1 +BufferFiltering = 1 +InternalResolution = 1 +HighQualityDepth = 1 +FrameSkip = 0 +FrameSkipType = 0 +AutoFrameSkip = False +StereoRendering = False +StereoToMonoShader = RedBlue +FrameRate = 0 +FrameRate2 = -1 +AnalogFrameRate = 240 +AnalogFrameRateMode = 0 +UnthrottlingMode = CONTINUOUS +AnisotropyLevel = 4 +MultiSampleLevel = 0 +VertexDecCache = False +TextureBackoffCache = False +FullScreen = True +FullScreenMulti = False +DisplayOffsetX = 0.500000 +DisplayOffsetY = 0.500000 +DisplayScale = 1.000000 +DisplayAspectRatio = 1.000000 +DisplayStretch = False +ImmersiveMode = True +SustainedPerformanceMode = False +IgnoreScreenInsets = True +ReplaceTextures = True +SaveNewTextures = False +IgnoreTextureFilenames = False +ReplaceTexturesAllowLate = True +TexScalingLevel = 1 +TexScalingType = 0 +TexDeposterize = False +TexHardwareScaling = False +VSyncInterval = False +BloomHack = 0 +SplineBezierQuality = 2 +HardwareTessellation = False +TextureShader = Off +ShaderChainRequires60FPS = False +SkipGPUReadbacks = False +LogFrameDrops = False +InflightFrames = 3 +RenderDuplicateFrames = False +GpuLogProfiler = False +[Sound] +Enable = True +AudioBackend = 0 +ExtraAudioBuffering = False +GlobalVolume = 10 +ReverbVolume = 10 +AltSpeedVolume = -1 +AudioDevice = +AutoAudioDevice = True +[Control] +HapticFeedback = False +ShowTouchCross = True +ShowTouchCircle = True +ShowTouchSquare = True +ShowTouchTriangle = True +Custom0Mapping = 0x0000000000000000 +Custom0Image = 0 +Custom0Shape = 0 +Custom0Toggle = False +Custom0Repeat = False +Custom1Mapping = 0x0000000000000000 +Custom1Image = 1 +Custom1Shape = 0 +Custom1Toggle = False +Custom1Repeat = False +Custom2Mapping = 0x0000000000000000 +Custom2Image = 2 +Custom2Shape = 0 +Custom2Toggle = False +Custom2Repeat = False +Custom3Mapping = 0x0000000000000000 +Custom3Image = 3 +Custom3Shape = 0 +Custom3Toggle = False +Custom3Repeat = False +Custom4Mapping = 0x0000000000000000 +Custom4Image = 4 +Custom4Shape = 0 +Custom4Toggle = False +Custom4Repeat = False +Custom5Mapping = 0x0000000000000000 +Custom5Image = 0 +Custom5Shape = 1 +Custom5Toggle = False +Custom5Repeat = False +Custom6Mapping = 0x0000000000000000 +Custom6Image = 1 +Custom6Shape = 1 +Custom6Toggle = False +Custom6Repeat = False +Custom7Mapping = 0x0000000000000000 +Custom7Image = 2 +Custom7Shape = 1 +Custom7Toggle = False +Custom7Repeat = False +Custom8Mapping = 0x0000000000000000 +Custom8Image = 3 +Custom8Shape = 1 +Custom8Toggle = False +Custom8Repeat = False +Custom9Mapping = 0x0000000000000000 +Custom9Image = 4 +Custom9Shape = 1 +Custom9Toggle = False +Custom9Repeat = False +ShowTouchPause = False +ShowTouchControls = False +DisableDpadDiagonals = False +GamepadOnlyFocused = False +TouchButtonStyle = 1 +TouchButtonOpacity = 65 +TouchButtonHideSeconds = 20 +AutoCenterTouchAnalog = False +AnalogAutoRotSpeed = 8.000000 +TouchSnapToGrid = False +TouchSnapGridSize = 64 +ActionButtonSpacing2 = 1.000000 +ActionButtonCenterX = 0.859485 +ActionButtonCenterY = 0.750000 +ActionButtonScale = 1.150000 +DPadX = 0.167447 +DPadY = 0.400000 +DPadScale = 1.150000 +ShowTouchDpad = True +DPadSpacing = 1.000000 +StartKeyX = 0.634660 +StartKeyY = 0.856250 +StartKeyScale = 1.150000 +ShowTouchStart = True +SelectKeyX = 0.500000 +SelectKeyY = 0.856250 +SelectKeyScale = 1.150000 +ShowTouchSelect = True +UnthrottleKeyX = 0.365340 +UnthrottleKeyY = 0.856250 +UnthrottleKeyScale = 1.150000 +ShowTouchUnthrottle = True +LKeyX = 0.080796 +LKeyY = 0.089583 +LKeyScale = 1.150000 +ShowTouchLTrigger = True +RKeyX = 0.919204 +RKeyY = 0.089583 +RKeyScale = 1.150000 +ShowTouchRTrigger = True +AnalogStickX = 0.167447 +AnalogStickY = 0.808333 +AnalogStickScale = 1.150000 +ShowAnalogStick = True +RightAnalogStickX = 0.859485 +RightAnalogStickY = 0.808333 +RightAnalogStickScale = 1.150000 +ShowRightAnalogStick = False +fcombo0X = 0.661592 +fcombo0Y = 0.500000 +comboKeyScale0 = 1.150000 +ShowComboKey0 = False +fcombo1X = 0.796253 +fcombo1Y = 0.500000 +comboKeyScale1 = 1.150000 +ShowComboKey1 = False +fcombo2X = 0.930913 +fcombo2Y = 0.500000 +comboKeyScale2 = 1.150000 +ShowComboKey2 = False +fcombo3X = 0.661592 +fcombo3Y = 0.333333 +comboKeyScale3 = 1.150000 +ShowComboKey3 = False +fcombo4X = 0.796253 +fcombo4Y = 0.333333 +comboKeyScale4 = 1.150000 +ShowComboKey4 = False +fcombo5X = 0.338407 +fcombo5Y = 0.500000 +comboKeyScale5 = 1.150000 +ShowComboKey5 = False +fcombo6X = 0.203747 +fcombo6Y = 0.500000 +comboKeyScale6 = 1.150000 +ShowComboKey6 = False +fcombo7X = 0.069087 +fcombo7Y = 0.500000 +comboKeyScale7 = 1.150000 +ShowComboKey7 = False +fcombo8X = 0.338407 +fcombo8Y = 0.333333 +comboKeyScale8 = 1.150000 +ShowComboKey8 = False +fcombo9X = 0.203747 +fcombo9Y = 0.333333 +comboKeyScale9 = 1.150000 +ShowComboKey9 = False +AnalogDeadzone = 0.150000 +AnalogInverseDeadzone = 0.000000 +AnalogSensitivity = 1.100000 +AnalogIsCircular = False +AnalogLimiterDeadzone = 0.600000 +LeftStickHeadScale = 1.000000 +RightStickHeadScale = 1.000000 +HideStickBackground = False +UseMouse = False +MapMouse = False +ConfineMap = False +MouseSensitivity = 0.100000 +MouseSmoothing = 0.900000 +SystemControls = True +[Network] +EnableWlan = False +EnableAdhocServer = False +proAdhocServer = socom.cc +PortOffset = 10000 +MinTimeout = 0 +ForcedFirstConnect = False +EnableUPnP = False +UPnPUseOriginalPort = False +EnableNetworkChat = False +ChatButtonPosition = 0 +ChatScreenPosition = 0 +EnableQuickChat = True +QuickChat1 = Quick Chat 1 +QuickChat2 = Quick Chat 2 +QuickChat3 = Quick Chat 3 +QuickChat4 = Quick Chat 4 +QuickChat5 = Quick Chat 5 +[SystemParam] +PSPModel = 1 +PSPFirmwareVersion = 660 +NickName = PPSSPP +MacAddress = dc:39:74:d2:dd:86 +Language = 1 +ParamTimeFormat = 0 +ParamDateFormat = 0 +TimeZone = 0 +DayLightSavings = False +ButtonPreference = 1 +LockParentalLevel = 0 +WlanAdhocChannel = 0 +WlanPowerSave = False +EncryptSave = True +SavedataUpgradeVersion = True +MemStickSize = 16 +[Debugger] +DisasmWindowX = -1 +DisasmWindowY = -1 +DisasmWindowW = -1 +DisasmWindowH = -1 +GEWindowX = -1 +GEWindowY = -1 +GEWindowW = -1 +GEWindowH = -1 +GEWindowTabsBL = 0x00000000 +GEWindowTabsBR = 0x00000000 +GEWindowTabsTR = 0x00000000 +ConsoleWindowX = -1 +ConsoleWindowY = -1 +FontWidth = 8 +FontHeight = 12 +DisplayStatusBar = True +ShowBottomTabTitles = True +ShowDeveloperMenu = False +SkipDeadbeefFilling = False +FuncHashMap = False +MemInfoDetailed = False +DrawFrameGraph = False +[Upgrade] +UpgradeMessage = +UpgradeVersion = +DismissedVersion = +[Theme] +ThemeName = Default +[VR] +VREnable = True +VREnable6DoF = True +VREnableStereo = False +VREnableMotions = True +VRForce72Hz = True +VRManualForceVR = False +VRCameraDistance = 0.000000 +VRCameraHeight = 0.000000 +VRCameraSide = 0.000000 +VRCanvasDistance = 12.000000 +VRFieldOfView = 100.000000 +VRHeadUpDisplayScale = 0.300000 +VRMotionLength = 0.500000 +VRHeadRotationScale = 5.000000 +VRHeadRotationSmoothing = False +VRHeadRotation = 0 +[Recent] +MaxRecent = 60 +FileName0 = /storage/roms/psp/Final Fantasy III.iso +FileName1 = /storage/roms/psp/Final Fantasy II.iso +[Log] +SYSTEMEnabled = True +SYSTEMLevel = 2 +BOOTEnabled = True +BOOTLevel = 2 +COMMONEnabled = True +COMMONLevel = 2 +CPUEnabled = True +CPULevel = 2 +FILESYSEnabled = True +FILESYSLevel = 2 +G3DEnabled = True +G3DLevel = 2 +HLEEnabled = True +HLELevel = 2 +JITEnabled = True +JITLevel = 2 +LOADEREnabled = True +LOADERLevel = 2 +MEEnabled = True +MELevel = 2 +MEMMAPEnabled = True +MEMMAPLevel = 2 +SASMIXEnabled = True +SASMIXLevel = 2 +SAVESTATEEnabled = True +SAVESTATELevel = 2 +FRAMEBUFEnabled = True +FRAMEBUFLevel = 2 +AUDIOEnabled = True +AUDIOLevel = 2 +IOEnabled = True +IOLevel = 2 +SCEAUDIOEnabled = True +SCEAUDIOLevel = 2 +SCECTRLEnabled = True +SCECTRLLevel = 2 +SCEDISPEnabled = True +SCEDISPLevel = 2 +SCEFONTEnabled = True +SCEFONTLevel = 2 +SCEGEEnabled = True +SCEGELevel = 2 +SCEINTCEnabled = True +SCEINTCLevel = 2 +SCEIOEnabled = True +SCEIOLevel = 2 +SCEKERNELEnabled = True +SCEKERNELLevel = 2 +SCEMODULEEnabled = True +SCEMODULELevel = 2 +SCENETEnabled = True +SCENETLevel = 2 +SCERTCEnabled = True +SCERTCLevel = 2 +SCESASEnabled = True +SCESASLevel = 2 +SCEUTILEnabled = True +SCEUTILLevel = 2 +SCEMISCEnabled = True +SCEMISCLevel = 2 diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/SDM845/controls.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/SDM845/controls.ini new file mode 100644 index 0000000000..64abd2cb80 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/SDM845/controls.ini @@ -0,0 +1,27 @@ +[ControlMapping] +Up = 10-19 +Down = 10-20 +Left = 10-21 +Right = 10-22 +Circle = 10-189 +Cross = 10-190 +Square = 10-188 +Triangle = 10-191 +Start = 10-197 +Select = 10-196 +L = 10-193 +R = 10-192 +An.Up = 10-4003 +An.Down = 10-4002 +An.Left = 10-4001 +An.Right = 10-4000 +Pause = 10-4,10-198:10-191,10-106 +Save State = 10-198:10-192 +Load State = 10-198:10-193 +RightAn.Up = 10-4007 +RightAn.Down = 10-4006 +RightAn.Left = 10-4005 +RightAn.Right = 10-4004 +Fast-forward = 10-198:10-4010 +Reset = 10-198:10-190 +Exit App = 10-4:10-197 diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/SDM845/ppsspp.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/SDM845/ppsspp.ini new file mode 100644 index 0000000000..acc403c601 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/SDM845/ppsspp.ini @@ -0,0 +1,690 @@ +[General] +FirstRun = False +RunCount = 0 +Enable Logging = False +AutoRun = True +Browse = False +IgnoreBadMemAccess = False +CurrentDirectory = /storage/roms/psp +ShowDebuggerOnLoad = False +CheckForNewVersion = True +Language = en_US +ForceLagSync = False +DiscordPresence = False +NumWorkerThreads = 8 +AutoLoadSaveState = 0 +EnableCheats = True +CwCheatRefreshRate = 77 +ScreenshotsAsPNG = False +UseFFV1 = False +DumpFrames = False +DumpAudio = False +SaveLoadResetsAVdumping = False +StateSlot = 0 +EnableStateUndo = True +RewindFlipFrequency = 0 +GridView1 = True +GridView2 = True +GridView3 = False +ComboMode = 0 +ReportingHost = default +AutoSaveSymbolMap = False +CacheFullIsoInRam = False +RemoteISOPort = 0 +LastRemoteISOServer = +LastRemoteISOPort = 0 +RemoteISOManualConfig = False +RemoteShareOnStartup = False +RemoteISOSubdir = / +RemoteDebuggerOnStartup = False +InternalScreenRotation = 1 +PauseWhenMinimized = False +DumpDecryptedEboots = False +MemStickInserted = True +ForceLagSync2 = False +UISound = True +CwCheatScrollPosition = 0.000000 +DumpVideoOutput = False +ShowRegionOnGameIcon = False +ShowIDOnGameIcon = False +GameGridScale = 1.000000 +RightAnalogUp = 0 +RightAnalogDown = 0 +RightAnalogLeft = 0 +RightAnalogRight = 0 +RightAnalogPress = 0 +RightAnalogCustom = False +LoadPlugins = False +GameListScrollPosition = 0.000000 +StateLoadUndoGame = NA +StateUndoLastSaveGame = NA +StateUndoLastSaveSlot = -5 +ShowOnScreenMessage = True +RightAnalogDisableDiagonal = False +SwipeUp = 0 +SwipeDown = 0 +SwipeLeft = 0 +SwipeRight = 0 +SwipeSensitivity = 1.000000 +SwipeSmoothing = 0.300000 +DoubleTapGesture = 0 +GestureControlEnabled = False +BackgroundAnimation = 1 +EnablePlugins = True +RewindSnapshotInterval = 0 +TransparentBackground = True +UITint = 0.000000 +UISaturation = 1.000000 +WindowX = -1 +WindowY = -1 +WindowWidth = 0 +WindowHeight = 0 +ShowMenuBar = True +IgnoreCompatSettings = +DiscordRichPresence = False +RemoteTab = False +RemoteISOSharedDir = +RemoteISOShareType = 0 +RunBehindPauseMenu = False +ShowGPOLEDs = False +[CPU] +CPUCore = 1 +SeparateSASThread = True +SeparateIOThread = True +IOTimingMethod = 0 +FastMemoryAccess = True +FuncReplacements = True +HideSlowWarnings = False +HideStateWarnings = False +PreloadFunctions = False +CPUSpeed = 0 +JitDisableFlags = 0x00000000 +FunctionReplacements = True +[Graphics] +EnableCardboard = False +CardboardScreenSize = 50 +CardboardXShift = 0 +CardboardYShift = 0 +ShowFPSCounter = 3 +GraphicsBackend = 0 (OPENGL) +FailedGraphicsBackends = +VulkanDevice = +RenderingMode = 0 +SoftwareRenderer = False +HardwareTransform = True +SoftwareSkinning = True +TextureFiltering = 1 +BufferFiltering = 1 +InternalResolution = 0 +AndroidHwScale = 1 +HighQualityDepth = 1 +FrameSkip = 0 +FrameSkipType = 0 +AutoFrameSkip = False +FrameRate = 0 +FrameRate2 = -1 +FrameSkipUnthrottle = True +ForceMaxEmulatedFPS = 30 +AnisotropyLevel = 0 +VertexDecCache = True +TextureBackoffCache = True +TextureSecondaryCache = False +FullScreen = True +FullScreenMulti = False +SmallDisplayZoomType = 2 +SmallDisplayOffsetX = 0.500000 +SmallDisplayOffsetY = 0.500000 +SmallDisplayZoomLevel = 1.000000 +ImmersiveMode = False +SustainedPerformanceMode = False +TrueColor = True +ReplaceTextures = True +SaveNewTextures = False +IgnoreTextureFilenames = True +TexScalingLevel = 1 +TexScalingType = 3 +TexDeposterize = False +VSyncInterval = True +DisableStencilTest = False +BloomHack = 2 +TimerHack = False +SplineBezierQuality = 0 +HardwareTessellation = False +PostShader = Off +MemBlockTransferGPU = True +DisableSlowFramebufEffects = True +FragmentTestCache = True +LogFrameDrops = False +EnableCardboardVR = False +DisabledGraphicsBackends = +CameraDevice = +UnthrottleMode = CONTINUOUS +IgnoreScreenInsets = True +TexHardwareScaling = False +TextureShader = Off +InflightFrames = 2 +RenderDuplicateFrames = True +ShaderChainRequires60FPS = False +ClearFramebuffersOnFirstUseHack = False +SoftwareRendererJit = True +UnthrottlingMode = CONTINUOUS +ReplaceTexturesAllowLate = True +iShowStatusFlags = 0 +UseGeometryShader = False +SkipBufferEffects = False +StereoRendering = False +StereoToMonoShader = RedBlue +AnalogFrameRate = 240 +MultiSampleLevel = 0 +DisplayOffsetX = 0.500000 +DisplayOffsetY = 0.500000 +DisplayScale = 1.000000 +DisplayIntegerScale = False +DisplayAspectRatio = 1.000000 +DisplayStretch = False +SkipGPUReadbacks = False +GpuLogProfiler = False +CameraMirrorHorizontal = False +AndroidFramerateMode = 1 +DisableRangeCulling = False +Smart2DTexFiltering = False +DisplayCropTo16x9 = True +VSync = False +SkipGPUReadbackMode = 0 +MultiThreading = True +UberShaderVertex = True +UberShaderFragment = True +DisplayRefreshRate = 60 +[Sound] +Enable = True +AudioBackend = 0 +AudioLatency = 1 +ExtraAudioBuffering = False +SoundSpeedHack = False +AudioResampler = False +GlobalVolume = 10 +AltSpeedVolume = -1 +AutoAudioDevice = True +ReverbVolume = 10 +[Control] +HapticFeedback = False +ShowTouchCross = True +ShowTouchCircle = True +ShowTouchSquare = True +ShowTouchTriangle = True +ComboKey0Mapping = 0 +ComboKey1Mapping = 0 +ComboKey2Mapping = 0 +ComboKey3Mapping = 0 +ComboKey4Mapping = 0 +ShowTouchPause = False +ShowTouchControls = False +DisableDpadDiagonals = False +GamepadOnlyFocused = False +TouchButtonStyle = 1 +TouchButtonOpacity = 65 +TouchButtonHideSeconds = 20 +AutoCenterTouchAnalog = False +ActionButtonSpacing2 = 1.000000 +ActionButtonCenterX = 0.937500 +ActionButtonCenterY = 0.900000 +ActionButtonScale = 1.150000 +DPadX = 0.074479 +DPadY = 0.760000 +DPadScale = 1.150000 +ShowTouchDpad = True +DPadSpacing = 1.000000 +StartKeyX = 0.559896 +StartKeyY = 0.942500 +StartKeyScale = 1.150000 +ShowTouchStart = True +SelectKeyX = 0.500000 +SelectKeyY = 0.942500 +SelectKeyScale = 1.150000 +ShowTouchSelect = True +UnthrottleKeyX = 0.440104 +UnthrottleKeyY = 0.942500 +UnthrottleKeyScale = 1.150000 +ShowTouchUnthrottle = True +LKeyX = 0.035937 +LKeyY = 0.635833 +LKeyScale = 1.150000 +ShowTouchLTrigger = True +RKeyX = 0.964063 +RKeyY = 0.635833 +RKeyScale = 1.150000 +ShowTouchRTrigger = True +AnalogStickX = 0.074479 +AnalogStickY = 0.923333 +AnalogStickScale = 1.150000 +ShowAnalogStick = True +fcombo0X = 0.571875 +fcombo0Y = 0.500000 +comboKeyScale0 = 1.150000 +ShowComboKey0 = False +fcombo1X = 0.631771 +fcombo1Y = 0.500000 +comboKeyScale1 = 1.150000 +ShowComboKey1 = False +fcombo2X = 0.691667 +fcombo2Y = 0.500000 +comboKeyScale2 = 1.150000 +ShowComboKey2 = False +fcombo3X = 0.571875 +fcombo3Y = 0.333333 +comboKeyScale3 = 1.150000 +ShowComboKey3 = False +fcombo4X = 0.631771 +fcombo4Y = 0.333333 +comboKeyScale4 = 1.150000 +ShowComboKey4 = False +Speed1KeyX = 0.440104 +Speed1KeyY = 0.885000 +Speed1KeyScale = 1.150000 +ShowSpeed1Key = False +Speed2KeyX = 0.500000 +Speed2KeyY = 0.885000 +Speed2KeyScale = 1.150000 +ShowSpeed2Key = False +XInputAnalogSensitivity = 1.000000 +AnalogLimiterDeadzone = 0.600000 +UseMouse = False +MapMouse = False +ConfineMap = False +MouseSensitivity = 0.100000 +MouseSmoothing = 0.900000 +ComboKey0Toggle = False +ComboKey1Toggle = False +ComboKey2Toggle = False +ComboKey3Toggle = False +ComboKey4Toggle = False +AnalogAutoRotSpeed = 15.000000 +TouchSnapToGrid = False +TouchSnapGridSize = 64 +RightAnalogStickX = 0.875000 +RightAnalogStickY = 0.856250 +RightAnalogStickScale = 1.150000 +ShowRightAnalogStick = False +RapidFireKeyX = 0.619792 +RapidFireKeyY = 0.784375 +RapidFireKeyScale = 1.150000 +ShowRapidFireKey = False +AnalogRotationCWKeyX = 0.500000 +AnalogRotationKeyCWY = 0.676562 +AnalogRotationKeyCWScale = 1.150000 +ShowAnalogRotationCWKey = False +AnalogRotationCCWKeyX = 0.380208 +AnalogRotationKeyCCWY = 0.676562 +AnalogRotationKeyCCWScale = 1.150000 +ShowAnalogRotationCCWKey = False +Custom0Mapping = 0x0000000000000000 +Custom0Image = 0 +Custom0Shape = 0 +Custom0Toggle = False +Custom1Mapping = 0x0000000000000000 +Custom1Image = 1 +Custom1Shape = 0 +Custom1Toggle = False +Custom2Mapping = 0x0000000000000000 +Custom2Image = 2 +Custom2Shape = 0 +Custom2Toggle = False +Custom3Mapping = 0x0000000000000000 +Custom3Image = 3 +Custom3Shape = 0 +Custom3Toggle = False +Custom4Mapping = 0x0000000000000000 +Custom4Image = 4 +Custom4Shape = 0 +Custom4Toggle = False +Custom5Mapping = 0x0000000000000000 +Custom5Image = 0 +Custom5Shape = 1 +Custom5Toggle = False +Custom6Mapping = 0x0000000000000000 +Custom6Image = 1 +Custom6Shape = 1 +Custom6Toggle = False +Custom7Mapping = 0x0000000000000000 +Custom7Image = 2 +Custom7Shape = 1 +Custom7Toggle = False +Custom8Mapping = 0x0000000000000000 +Custom8Image = 3 +Custom8Shape = 1 +Custom8Toggle = False +Custom9Mapping = 0x0000000000000000 +Custom9Image = 4 +Custom9Shape = 1 +Custom9Toggle = False +fcombo5X = 0.428125 +fcombo5Y = 0.500000 +comboKeyScale5 = 1.150000 +ShowComboKey5 = False +fcombo6X = 0.368229 +fcombo6Y = 0.500000 +comboKeyScale6 = 1.150000 +ShowComboKey6 = False +fcombo7X = 0.308333 +fcombo7Y = 0.500000 +comboKeyScale7 = 1.150000 +ShowComboKey7 = False +fcombo8X = 0.428125 +fcombo8Y = 0.333333 +comboKeyScale8 = 1.150000 +ShowComboKey8 = False +fcombo9X = 0.368229 +fcombo9Y = 0.333333 +comboKeyScale9 = 1.150000 +ShowComboKey9 = False +AnalogDeadzone = 0.150000 +AnalogInverseDeadzone = 0.000000 +AnalogSensitivity = 1.100000 +AnalogIsCircular = False +LeftStickHeadScale = 1.000000 +RightStickHeadScale = 1.000000 +HideStickBackground = False +SystemControls = True +Custom0Repeat = False +Custom1Repeat = False +Custom2Repeat = False +Custom3Repeat = False +Custom4Repeat = False +Custom5Repeat = False +Custom6Repeat = False +Custom7Repeat = False +Custom8Repeat = False +Custom9Repeat = False +Custom10Mapping = 0x0000000000000000 +Custom10Image = 0 +Custom10Shape = 2 +Custom10Toggle = False +Custom10Repeat = False +Custom11Mapping = 0x0000000000000000 +Custom11Image = 1 +Custom11Shape = 2 +Custom11Toggle = False +Custom11Repeat = False +Custom12Mapping = 0x0000000000000000 +Custom12Image = 2 +Custom12Shape = 2 +Custom12Toggle = False +Custom12Repeat = False +Custom13Mapping = 0x0000000000000000 +Custom13Image = 3 +Custom13Shape = 2 +Custom13Toggle = False +Custom13Repeat = False +Custom14Mapping = 0x0000000000000000 +Custom14Image = 4 +Custom14Shape = 2 +Custom14Toggle = False +Custom14Repeat = False +Custom15Mapping = 0x0000000000000000 +Custom15Image = 0 +Custom15Shape = 9 +Custom15Toggle = False +Custom15Repeat = False +Custom16Mapping = 0x0000000000000000 +Custom16Image = 1 +Custom16Shape = 9 +Custom16Toggle = False +Custom16Repeat = False +Custom17Mapping = 0x0000000000000000 +Custom17Image = 2 +Custom17Shape = 9 +Custom17Toggle = False +Custom17Repeat = False +Custom18Mapping = 0x0000000000000000 +Custom18Image = 3 +Custom18Shape = 9 +Custom18Toggle = False +Custom18Repeat = False +Custom19Mapping = 0x0000000000000000 +Custom19Image = 4 +Custom19Shape = 9 +Custom19Toggle = False +Custom19Repeat = False +fcombo10X = 0.571875 +fcombo10Y = 0.582465 +comboKeyScale10 = 1.150000 +ShowComboKey10 = False +fcombo11X = 0.631771 +fcombo11Y = 0.582465 +comboKeyScale11 = 1.150000 +ShowComboKey11 = False +fcombo12X = 0.691667 +fcombo12Y = 0.582465 +comboKeyScale12 = 1.150000 +ShowComboKey12 = False +fcombo13X = 0.571875 +fcombo13Y = 0.415799 +comboKeyScale13 = 1.150000 +ShowComboKey13 = False +fcombo14X = 0.631771 +fcombo14Y = 0.415799 +comboKeyScale14 = 1.150000 +ShowComboKey14 = False +fcombo15X = 0.428125 +fcombo15Y = 0.582465 +comboKeyScale15 = 1.150000 +ShowComboKey15 = False +fcombo16X = 0.368229 +fcombo16Y = 0.582465 +comboKeyScale16 = 1.150000 +ShowComboKey16 = False +fcombo17X = 0.308333 +fcombo17Y = 0.582465 +comboKeyScale17 = 1.150000 +ShowComboKey17 = False +fcombo18X = 0.428125 +fcombo18Y = 0.415799 +comboKeyScale18 = 1.150000 +ShowComboKey18 = False +fcombo19X = 0.368229 +fcombo19Y = 0.415799 +comboKeyScale19 = 1.150000 +ShowComboKey19 = False +StickyTouchDPad = False +AnalogTriggerThreshold = 0.750000 +AllowMappingCombos = True +StrictComboOrder = False +MouseWheelUpDelayMs = 80 +RapidFileInterval = 5 +AnalogGesture = False +AnalogGestureSensibility = 1.000000 +[Network] +EnableWlan = False +EnableAdhocServer = False +proAdhocServer = myneighborsushicat.com +PortOffset = 0 +MinTimeout = 1 +TCPNoDelay = False +EnableUPnP = False +UPnPUseOriginalPort = True +EnableNetworkChat = False +ChatButtonPosition = 0 +ChatScreenPosition = 0 +EnableQuickChat = True +QuickChat1 = Quick Chat 1 +QuickChat2 = Quick Chat 2 +QuickChat3 = Quick Chat 3 +QuickChat4 = Quick Chat 4 +QuickChat5 = Quick Chat 5 +ForcedFirstConnect = False +[SystemParam] +PSPModel = 0 +PSPFirmwareVersion = 660 +NickName = PPSSPP +proAdhocServer = black-seraph.com +MacAddress = 4e:7a:78:d9:49:32 +PortOffset = 0 +Language = 1 +TimeFormat = 1 +DateFormat = 1 +TimeZone = 0 +DayLightSavings = False +ButtonPreference = 1 +LockParentalLevel = 0 +WlanAdhocChannel = 0 +WlanPowerSave = False +EncryptSave = True +SavedataUpgradeVersion = True +ParamTimeFormat = 0 +ParamDateFormat = 0 +MemStickSize = 16 +[Debugger] +DisasmWindowX = -1 +DisasmWindowY = -1 +DisasmWindowW = -1 +DisasmWindowH = -1 +GEWindowX = -1 +GEWindowY = -1 +GEWindowW = -1 +GEWindowH = -1 +ConsoleWindowX = -1 +ConsoleWindowY = -1 +FontWidth = 8 +FontHeight = 12 +DisplayStatusBar = True +ShowBottomTabTitles = True +ShowDeveloperMenu = False +SkipDeadbeefFilling = False +FuncHashMap = False +DrawFrameGraph = False +MemInfoDetailed = False +GEWindowTabsBL = 0x00000000 +GEWindowTabsBR = 0x00000000 +GEWindowTabsTR = 0x00000000 +SkipFuncHashMap = +[Upgrade] +UpgradeMessage = +UpgradeVersion = 1.12.0 +DismissedVersion = +[Theme] +ItemStyleFg = 0xffffffff +ItemStyleBg = 0x55000000 +ItemFocusedStyleFg = 0xffffffff +ItemFocusedStyleBg = 0xffedc24c +ItemDownStyleFg = 0xffffffff +ItemDownStyleBg = 0xffbd9939 +ItemDisabledStyleFg = 0x80eeeeee +ItemDisabledStyleBg = 0x55e0d4af +ItemHighlightedStyleFg = 0xffffffff +ItemHighlightedStyleBg = 0x55bdbb39 +ButtonStyleFg = 0xffffffff +ButtonStyleBg = 0x55000000 +ButtonFocusedStyleFg = 0xffffffff +ButtonFocusedStyleBg = 0xffedc24c +ButtonDownStyleFg = 0xffffffff +ButtonDownStyleBg = 0xffbd9939 +ButtonDisabledStyleFg = 0x80eeeeee +ButtonDisabledStyleBg = 0x55e0d4af +ButtonHighlightedStyleFg = 0xffffffff +ButtonHighlightedStyleBg = 0x55bdbb39 +HeaderStyleFg = 0xffffffff +InfoStyleFg = 0xffffffff +InfoStyleBg = 0x00000000 +PopupTitleStyleFg = 0xffe3be59 +PopupStyleFg = 0xffffffff +PopupStyleBg = 0xff303030 +ThemeName = Default +[Recent] +MaxRecent = 30 +FileName0 = +[Log] +SYSTEMEnabled = True +SYSTEMLevel = 4 +BOOTEnabled = True +BOOTLevel = 4 +COMMONEnabled = True +COMMONLevel = 4 +CPUEnabled = True +CPULevel = 4 +FILESYSEnabled = True +FILESYSLevel = 4 +G3DEnabled = True +G3DLevel = 4 +HLEEnabled = True +HLELevel = 4 +JITEnabled = True +JITLevel = 4 +LOADEREnabled = True +LOADERLevel = 4 +MEEnabled = True +MELevel = 4 +MEMMAPEnabled = True +MEMMAPLevel = 4 +SASMIXEnabled = True +SASMIXLevel = 4 +SAVESTATEEnabled = True +SAVESTATELevel = 4 +FRAMEBUFEnabled = True +FRAMEBUFLevel = 4 +SCEAUDIOEnabled = True +SCEAUDIOLevel = 4 +SCECTRLEnabled = True +SCECTRLLevel = 4 +SCEDISPEnabled = True +SCEDISPLevel = 4 +SCEFONTEnabled = True +SCEFONTLevel = 4 +SCEGEEnabled = True +SCEGELevel = 4 +SCEINTCEnabled = True +SCEINTCLevel = 4 +SCEIOEnabled = True +SCEIOLevel = 4 +SCEKERNELEnabled = True +SCEKERNELLevel = 4 +SCEMODULEEnabled = True +SCEMODULELevel = 4 +SCENETEnabled = True +SCENETLevel = 4 +SCERTCEnabled = True +SCERTCLevel = 4 +SCESASEnabled = True +SCESASLevel = 4 +SCEUTILEnabled = True +SCEUTILLevel = 4 +SCEMISCEnabled = True +SCEMISCLevel = 4 +AUDIOEnabled = True +AUDIOLevel = 2 +IOEnabled = True +IOLevel = 2 +[PostShaderSetting] +BloomSettingValue1 = 0.600000 +BloomSettingValue2 = 0.500000 +CRTSettingValue1 = 1.000000 +CartoonSettingValue1 = 0.500000 +ColorCorrectionSettingValue1 = 1.000000 +ColorCorrectionSettingValue2 = 1.000000 +ColorCorrectionSettingValue3 = 1.000000 +ColorCorrectionSettingValue4 = 1.000000 +ScanlinesSettingValue1 = 1.000000 +ScanlinesSettingValue2 = 0.500000 +SharpenSettingValue1 = 1.500000 +[VR] +VREnable = True +VREnable6DoF = True +VREnableStereo = False +VREnableMotions = True +VRForce72Hz = True +VRManualForceVR = False +VRPassthrough = False +VRRescaleHUD = True +VRCameraDistance = 0.000000 +VRCameraHeight = 0.000000 +VRCameraSide = 0.000000 +VRCameraPitch = 0 +VRCanvasDistance = 12.000000 +VRFieldOfView = 100.000000 +VRHeadUpDisplayScale = 0.300000 +VRMotionLength = 0.500000 +VRHeadRotationScale = 5.000000 +VRHeadRotationEnabled = False +VRHeadRotationSmoothing = False +VRForce = False +VRImmersiveMode = True +VRCanvas3DDistance = 3.000000 diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/SM8250/controls.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/SM8250/controls.ini new file mode 100644 index 0000000000..d8d8a8611a --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/SM8250/controls.ini @@ -0,0 +1,27 @@ +[ControlMapping] +Up = 10-19 +Down = 10-20 +Left = 10-21 +Right = 10-22 +Circle = 10-189 +Cross = 10-190 +Square = 10-188 +Triangle = 10-191 +Start = 10-197 +Select = 10-196 +L = 10-193 +R = 10-192 +An.Up = 10-4003 +An.Down = 10-4002 +An.Left = 10-4001 +An.Right = 10-4000 +Pause = 10-4,10-198:10-191,10-106 +Save State = 10-198:10-192 +Load State = 10-198:10-193 +RightAn.Up = 10-4007 +RightAn.Down = 10-4006 +RightAn.Left = 10-4005 +RightAn.Right = 10-4004 +Fast-forward = 10-198:10-4010 +Reset = 10-198:10-190 +Exit App = 10-198:10-197 diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/SM8250/ppsspp.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/SM8250/ppsspp.ini new file mode 100644 index 0000000000..acc403c601 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/SM8250/ppsspp.ini @@ -0,0 +1,690 @@ +[General] +FirstRun = False +RunCount = 0 +Enable Logging = False +AutoRun = True +Browse = False +IgnoreBadMemAccess = False +CurrentDirectory = /storage/roms/psp +ShowDebuggerOnLoad = False +CheckForNewVersion = True +Language = en_US +ForceLagSync = False +DiscordPresence = False +NumWorkerThreads = 8 +AutoLoadSaveState = 0 +EnableCheats = True +CwCheatRefreshRate = 77 +ScreenshotsAsPNG = False +UseFFV1 = False +DumpFrames = False +DumpAudio = False +SaveLoadResetsAVdumping = False +StateSlot = 0 +EnableStateUndo = True +RewindFlipFrequency = 0 +GridView1 = True +GridView2 = True +GridView3 = False +ComboMode = 0 +ReportingHost = default +AutoSaveSymbolMap = False +CacheFullIsoInRam = False +RemoteISOPort = 0 +LastRemoteISOServer = +LastRemoteISOPort = 0 +RemoteISOManualConfig = False +RemoteShareOnStartup = False +RemoteISOSubdir = / +RemoteDebuggerOnStartup = False +InternalScreenRotation = 1 +PauseWhenMinimized = False +DumpDecryptedEboots = False +MemStickInserted = True +ForceLagSync2 = False +UISound = True +CwCheatScrollPosition = 0.000000 +DumpVideoOutput = False +ShowRegionOnGameIcon = False +ShowIDOnGameIcon = False +GameGridScale = 1.000000 +RightAnalogUp = 0 +RightAnalogDown = 0 +RightAnalogLeft = 0 +RightAnalogRight = 0 +RightAnalogPress = 0 +RightAnalogCustom = False +LoadPlugins = False +GameListScrollPosition = 0.000000 +StateLoadUndoGame = NA +StateUndoLastSaveGame = NA +StateUndoLastSaveSlot = -5 +ShowOnScreenMessage = True +RightAnalogDisableDiagonal = False +SwipeUp = 0 +SwipeDown = 0 +SwipeLeft = 0 +SwipeRight = 0 +SwipeSensitivity = 1.000000 +SwipeSmoothing = 0.300000 +DoubleTapGesture = 0 +GestureControlEnabled = False +BackgroundAnimation = 1 +EnablePlugins = True +RewindSnapshotInterval = 0 +TransparentBackground = True +UITint = 0.000000 +UISaturation = 1.000000 +WindowX = -1 +WindowY = -1 +WindowWidth = 0 +WindowHeight = 0 +ShowMenuBar = True +IgnoreCompatSettings = +DiscordRichPresence = False +RemoteTab = False +RemoteISOSharedDir = +RemoteISOShareType = 0 +RunBehindPauseMenu = False +ShowGPOLEDs = False +[CPU] +CPUCore = 1 +SeparateSASThread = True +SeparateIOThread = True +IOTimingMethod = 0 +FastMemoryAccess = True +FuncReplacements = True +HideSlowWarnings = False +HideStateWarnings = False +PreloadFunctions = False +CPUSpeed = 0 +JitDisableFlags = 0x00000000 +FunctionReplacements = True +[Graphics] +EnableCardboard = False +CardboardScreenSize = 50 +CardboardXShift = 0 +CardboardYShift = 0 +ShowFPSCounter = 3 +GraphicsBackend = 0 (OPENGL) +FailedGraphicsBackends = +VulkanDevice = +RenderingMode = 0 +SoftwareRenderer = False +HardwareTransform = True +SoftwareSkinning = True +TextureFiltering = 1 +BufferFiltering = 1 +InternalResolution = 0 +AndroidHwScale = 1 +HighQualityDepth = 1 +FrameSkip = 0 +FrameSkipType = 0 +AutoFrameSkip = False +FrameRate = 0 +FrameRate2 = -1 +FrameSkipUnthrottle = True +ForceMaxEmulatedFPS = 30 +AnisotropyLevel = 0 +VertexDecCache = True +TextureBackoffCache = True +TextureSecondaryCache = False +FullScreen = True +FullScreenMulti = False +SmallDisplayZoomType = 2 +SmallDisplayOffsetX = 0.500000 +SmallDisplayOffsetY = 0.500000 +SmallDisplayZoomLevel = 1.000000 +ImmersiveMode = False +SustainedPerformanceMode = False +TrueColor = True +ReplaceTextures = True +SaveNewTextures = False +IgnoreTextureFilenames = True +TexScalingLevel = 1 +TexScalingType = 3 +TexDeposterize = False +VSyncInterval = True +DisableStencilTest = False +BloomHack = 2 +TimerHack = False +SplineBezierQuality = 0 +HardwareTessellation = False +PostShader = Off +MemBlockTransferGPU = True +DisableSlowFramebufEffects = True +FragmentTestCache = True +LogFrameDrops = False +EnableCardboardVR = False +DisabledGraphicsBackends = +CameraDevice = +UnthrottleMode = CONTINUOUS +IgnoreScreenInsets = True +TexHardwareScaling = False +TextureShader = Off +InflightFrames = 2 +RenderDuplicateFrames = True +ShaderChainRequires60FPS = False +ClearFramebuffersOnFirstUseHack = False +SoftwareRendererJit = True +UnthrottlingMode = CONTINUOUS +ReplaceTexturesAllowLate = True +iShowStatusFlags = 0 +UseGeometryShader = False +SkipBufferEffects = False +StereoRendering = False +StereoToMonoShader = RedBlue +AnalogFrameRate = 240 +MultiSampleLevel = 0 +DisplayOffsetX = 0.500000 +DisplayOffsetY = 0.500000 +DisplayScale = 1.000000 +DisplayIntegerScale = False +DisplayAspectRatio = 1.000000 +DisplayStretch = False +SkipGPUReadbacks = False +GpuLogProfiler = False +CameraMirrorHorizontal = False +AndroidFramerateMode = 1 +DisableRangeCulling = False +Smart2DTexFiltering = False +DisplayCropTo16x9 = True +VSync = False +SkipGPUReadbackMode = 0 +MultiThreading = True +UberShaderVertex = True +UberShaderFragment = True +DisplayRefreshRate = 60 +[Sound] +Enable = True +AudioBackend = 0 +AudioLatency = 1 +ExtraAudioBuffering = False +SoundSpeedHack = False +AudioResampler = False +GlobalVolume = 10 +AltSpeedVolume = -1 +AutoAudioDevice = True +ReverbVolume = 10 +[Control] +HapticFeedback = False +ShowTouchCross = True +ShowTouchCircle = True +ShowTouchSquare = True +ShowTouchTriangle = True +ComboKey0Mapping = 0 +ComboKey1Mapping = 0 +ComboKey2Mapping = 0 +ComboKey3Mapping = 0 +ComboKey4Mapping = 0 +ShowTouchPause = False +ShowTouchControls = False +DisableDpadDiagonals = False +GamepadOnlyFocused = False +TouchButtonStyle = 1 +TouchButtonOpacity = 65 +TouchButtonHideSeconds = 20 +AutoCenterTouchAnalog = False +ActionButtonSpacing2 = 1.000000 +ActionButtonCenterX = 0.937500 +ActionButtonCenterY = 0.900000 +ActionButtonScale = 1.150000 +DPadX = 0.074479 +DPadY = 0.760000 +DPadScale = 1.150000 +ShowTouchDpad = True +DPadSpacing = 1.000000 +StartKeyX = 0.559896 +StartKeyY = 0.942500 +StartKeyScale = 1.150000 +ShowTouchStart = True +SelectKeyX = 0.500000 +SelectKeyY = 0.942500 +SelectKeyScale = 1.150000 +ShowTouchSelect = True +UnthrottleKeyX = 0.440104 +UnthrottleKeyY = 0.942500 +UnthrottleKeyScale = 1.150000 +ShowTouchUnthrottle = True +LKeyX = 0.035937 +LKeyY = 0.635833 +LKeyScale = 1.150000 +ShowTouchLTrigger = True +RKeyX = 0.964063 +RKeyY = 0.635833 +RKeyScale = 1.150000 +ShowTouchRTrigger = True +AnalogStickX = 0.074479 +AnalogStickY = 0.923333 +AnalogStickScale = 1.150000 +ShowAnalogStick = True +fcombo0X = 0.571875 +fcombo0Y = 0.500000 +comboKeyScale0 = 1.150000 +ShowComboKey0 = False +fcombo1X = 0.631771 +fcombo1Y = 0.500000 +comboKeyScale1 = 1.150000 +ShowComboKey1 = False +fcombo2X = 0.691667 +fcombo2Y = 0.500000 +comboKeyScale2 = 1.150000 +ShowComboKey2 = False +fcombo3X = 0.571875 +fcombo3Y = 0.333333 +comboKeyScale3 = 1.150000 +ShowComboKey3 = False +fcombo4X = 0.631771 +fcombo4Y = 0.333333 +comboKeyScale4 = 1.150000 +ShowComboKey4 = False +Speed1KeyX = 0.440104 +Speed1KeyY = 0.885000 +Speed1KeyScale = 1.150000 +ShowSpeed1Key = False +Speed2KeyX = 0.500000 +Speed2KeyY = 0.885000 +Speed2KeyScale = 1.150000 +ShowSpeed2Key = False +XInputAnalogSensitivity = 1.000000 +AnalogLimiterDeadzone = 0.600000 +UseMouse = False +MapMouse = False +ConfineMap = False +MouseSensitivity = 0.100000 +MouseSmoothing = 0.900000 +ComboKey0Toggle = False +ComboKey1Toggle = False +ComboKey2Toggle = False +ComboKey3Toggle = False +ComboKey4Toggle = False +AnalogAutoRotSpeed = 15.000000 +TouchSnapToGrid = False +TouchSnapGridSize = 64 +RightAnalogStickX = 0.875000 +RightAnalogStickY = 0.856250 +RightAnalogStickScale = 1.150000 +ShowRightAnalogStick = False +RapidFireKeyX = 0.619792 +RapidFireKeyY = 0.784375 +RapidFireKeyScale = 1.150000 +ShowRapidFireKey = False +AnalogRotationCWKeyX = 0.500000 +AnalogRotationKeyCWY = 0.676562 +AnalogRotationKeyCWScale = 1.150000 +ShowAnalogRotationCWKey = False +AnalogRotationCCWKeyX = 0.380208 +AnalogRotationKeyCCWY = 0.676562 +AnalogRotationKeyCCWScale = 1.150000 +ShowAnalogRotationCCWKey = False +Custom0Mapping = 0x0000000000000000 +Custom0Image = 0 +Custom0Shape = 0 +Custom0Toggle = False +Custom1Mapping = 0x0000000000000000 +Custom1Image = 1 +Custom1Shape = 0 +Custom1Toggle = False +Custom2Mapping = 0x0000000000000000 +Custom2Image = 2 +Custom2Shape = 0 +Custom2Toggle = False +Custom3Mapping = 0x0000000000000000 +Custom3Image = 3 +Custom3Shape = 0 +Custom3Toggle = False +Custom4Mapping = 0x0000000000000000 +Custom4Image = 4 +Custom4Shape = 0 +Custom4Toggle = False +Custom5Mapping = 0x0000000000000000 +Custom5Image = 0 +Custom5Shape = 1 +Custom5Toggle = False +Custom6Mapping = 0x0000000000000000 +Custom6Image = 1 +Custom6Shape = 1 +Custom6Toggle = False +Custom7Mapping = 0x0000000000000000 +Custom7Image = 2 +Custom7Shape = 1 +Custom7Toggle = False +Custom8Mapping = 0x0000000000000000 +Custom8Image = 3 +Custom8Shape = 1 +Custom8Toggle = False +Custom9Mapping = 0x0000000000000000 +Custom9Image = 4 +Custom9Shape = 1 +Custom9Toggle = False +fcombo5X = 0.428125 +fcombo5Y = 0.500000 +comboKeyScale5 = 1.150000 +ShowComboKey5 = False +fcombo6X = 0.368229 +fcombo6Y = 0.500000 +comboKeyScale6 = 1.150000 +ShowComboKey6 = False +fcombo7X = 0.308333 +fcombo7Y = 0.500000 +comboKeyScale7 = 1.150000 +ShowComboKey7 = False +fcombo8X = 0.428125 +fcombo8Y = 0.333333 +comboKeyScale8 = 1.150000 +ShowComboKey8 = False +fcombo9X = 0.368229 +fcombo9Y = 0.333333 +comboKeyScale9 = 1.150000 +ShowComboKey9 = False +AnalogDeadzone = 0.150000 +AnalogInverseDeadzone = 0.000000 +AnalogSensitivity = 1.100000 +AnalogIsCircular = False +LeftStickHeadScale = 1.000000 +RightStickHeadScale = 1.000000 +HideStickBackground = False +SystemControls = True +Custom0Repeat = False +Custom1Repeat = False +Custom2Repeat = False +Custom3Repeat = False +Custom4Repeat = False +Custom5Repeat = False +Custom6Repeat = False +Custom7Repeat = False +Custom8Repeat = False +Custom9Repeat = False +Custom10Mapping = 0x0000000000000000 +Custom10Image = 0 +Custom10Shape = 2 +Custom10Toggle = False +Custom10Repeat = False +Custom11Mapping = 0x0000000000000000 +Custom11Image = 1 +Custom11Shape = 2 +Custom11Toggle = False +Custom11Repeat = False +Custom12Mapping = 0x0000000000000000 +Custom12Image = 2 +Custom12Shape = 2 +Custom12Toggle = False +Custom12Repeat = False +Custom13Mapping = 0x0000000000000000 +Custom13Image = 3 +Custom13Shape = 2 +Custom13Toggle = False +Custom13Repeat = False +Custom14Mapping = 0x0000000000000000 +Custom14Image = 4 +Custom14Shape = 2 +Custom14Toggle = False +Custom14Repeat = False +Custom15Mapping = 0x0000000000000000 +Custom15Image = 0 +Custom15Shape = 9 +Custom15Toggle = False +Custom15Repeat = False +Custom16Mapping = 0x0000000000000000 +Custom16Image = 1 +Custom16Shape = 9 +Custom16Toggle = False +Custom16Repeat = False +Custom17Mapping = 0x0000000000000000 +Custom17Image = 2 +Custom17Shape = 9 +Custom17Toggle = False +Custom17Repeat = False +Custom18Mapping = 0x0000000000000000 +Custom18Image = 3 +Custom18Shape = 9 +Custom18Toggle = False +Custom18Repeat = False +Custom19Mapping = 0x0000000000000000 +Custom19Image = 4 +Custom19Shape = 9 +Custom19Toggle = False +Custom19Repeat = False +fcombo10X = 0.571875 +fcombo10Y = 0.582465 +comboKeyScale10 = 1.150000 +ShowComboKey10 = False +fcombo11X = 0.631771 +fcombo11Y = 0.582465 +comboKeyScale11 = 1.150000 +ShowComboKey11 = False +fcombo12X = 0.691667 +fcombo12Y = 0.582465 +comboKeyScale12 = 1.150000 +ShowComboKey12 = False +fcombo13X = 0.571875 +fcombo13Y = 0.415799 +comboKeyScale13 = 1.150000 +ShowComboKey13 = False +fcombo14X = 0.631771 +fcombo14Y = 0.415799 +comboKeyScale14 = 1.150000 +ShowComboKey14 = False +fcombo15X = 0.428125 +fcombo15Y = 0.582465 +comboKeyScale15 = 1.150000 +ShowComboKey15 = False +fcombo16X = 0.368229 +fcombo16Y = 0.582465 +comboKeyScale16 = 1.150000 +ShowComboKey16 = False +fcombo17X = 0.308333 +fcombo17Y = 0.582465 +comboKeyScale17 = 1.150000 +ShowComboKey17 = False +fcombo18X = 0.428125 +fcombo18Y = 0.415799 +comboKeyScale18 = 1.150000 +ShowComboKey18 = False +fcombo19X = 0.368229 +fcombo19Y = 0.415799 +comboKeyScale19 = 1.150000 +ShowComboKey19 = False +StickyTouchDPad = False +AnalogTriggerThreshold = 0.750000 +AllowMappingCombos = True +StrictComboOrder = False +MouseWheelUpDelayMs = 80 +RapidFileInterval = 5 +AnalogGesture = False +AnalogGestureSensibility = 1.000000 +[Network] +EnableWlan = False +EnableAdhocServer = False +proAdhocServer = myneighborsushicat.com +PortOffset = 0 +MinTimeout = 1 +TCPNoDelay = False +EnableUPnP = False +UPnPUseOriginalPort = True +EnableNetworkChat = False +ChatButtonPosition = 0 +ChatScreenPosition = 0 +EnableQuickChat = True +QuickChat1 = Quick Chat 1 +QuickChat2 = Quick Chat 2 +QuickChat3 = Quick Chat 3 +QuickChat4 = Quick Chat 4 +QuickChat5 = Quick Chat 5 +ForcedFirstConnect = False +[SystemParam] +PSPModel = 0 +PSPFirmwareVersion = 660 +NickName = PPSSPP +proAdhocServer = black-seraph.com +MacAddress = 4e:7a:78:d9:49:32 +PortOffset = 0 +Language = 1 +TimeFormat = 1 +DateFormat = 1 +TimeZone = 0 +DayLightSavings = False +ButtonPreference = 1 +LockParentalLevel = 0 +WlanAdhocChannel = 0 +WlanPowerSave = False +EncryptSave = True +SavedataUpgradeVersion = True +ParamTimeFormat = 0 +ParamDateFormat = 0 +MemStickSize = 16 +[Debugger] +DisasmWindowX = -1 +DisasmWindowY = -1 +DisasmWindowW = -1 +DisasmWindowH = -1 +GEWindowX = -1 +GEWindowY = -1 +GEWindowW = -1 +GEWindowH = -1 +ConsoleWindowX = -1 +ConsoleWindowY = -1 +FontWidth = 8 +FontHeight = 12 +DisplayStatusBar = True +ShowBottomTabTitles = True +ShowDeveloperMenu = False +SkipDeadbeefFilling = False +FuncHashMap = False +DrawFrameGraph = False +MemInfoDetailed = False +GEWindowTabsBL = 0x00000000 +GEWindowTabsBR = 0x00000000 +GEWindowTabsTR = 0x00000000 +SkipFuncHashMap = +[Upgrade] +UpgradeMessage = +UpgradeVersion = 1.12.0 +DismissedVersion = +[Theme] +ItemStyleFg = 0xffffffff +ItemStyleBg = 0x55000000 +ItemFocusedStyleFg = 0xffffffff +ItemFocusedStyleBg = 0xffedc24c +ItemDownStyleFg = 0xffffffff +ItemDownStyleBg = 0xffbd9939 +ItemDisabledStyleFg = 0x80eeeeee +ItemDisabledStyleBg = 0x55e0d4af +ItemHighlightedStyleFg = 0xffffffff +ItemHighlightedStyleBg = 0x55bdbb39 +ButtonStyleFg = 0xffffffff +ButtonStyleBg = 0x55000000 +ButtonFocusedStyleFg = 0xffffffff +ButtonFocusedStyleBg = 0xffedc24c +ButtonDownStyleFg = 0xffffffff +ButtonDownStyleBg = 0xffbd9939 +ButtonDisabledStyleFg = 0x80eeeeee +ButtonDisabledStyleBg = 0x55e0d4af +ButtonHighlightedStyleFg = 0xffffffff +ButtonHighlightedStyleBg = 0x55bdbb39 +HeaderStyleFg = 0xffffffff +InfoStyleFg = 0xffffffff +InfoStyleBg = 0x00000000 +PopupTitleStyleFg = 0xffe3be59 +PopupStyleFg = 0xffffffff +PopupStyleBg = 0xff303030 +ThemeName = Default +[Recent] +MaxRecent = 30 +FileName0 = +[Log] +SYSTEMEnabled = True +SYSTEMLevel = 4 +BOOTEnabled = True +BOOTLevel = 4 +COMMONEnabled = True +COMMONLevel = 4 +CPUEnabled = True +CPULevel = 4 +FILESYSEnabled = True +FILESYSLevel = 4 +G3DEnabled = True +G3DLevel = 4 +HLEEnabled = True +HLELevel = 4 +JITEnabled = True +JITLevel = 4 +LOADEREnabled = True +LOADERLevel = 4 +MEEnabled = True +MELevel = 4 +MEMMAPEnabled = True +MEMMAPLevel = 4 +SASMIXEnabled = True +SASMIXLevel = 4 +SAVESTATEEnabled = True +SAVESTATELevel = 4 +FRAMEBUFEnabled = True +FRAMEBUFLevel = 4 +SCEAUDIOEnabled = True +SCEAUDIOLevel = 4 +SCECTRLEnabled = True +SCECTRLLevel = 4 +SCEDISPEnabled = True +SCEDISPLevel = 4 +SCEFONTEnabled = True +SCEFONTLevel = 4 +SCEGEEnabled = True +SCEGELevel = 4 +SCEINTCEnabled = True +SCEINTCLevel = 4 +SCEIOEnabled = True +SCEIOLevel = 4 +SCEKERNELEnabled = True +SCEKERNELLevel = 4 +SCEMODULEEnabled = True +SCEMODULELevel = 4 +SCENETEnabled = True +SCENETLevel = 4 +SCERTCEnabled = True +SCERTCLevel = 4 +SCESASEnabled = True +SCESASLevel = 4 +SCEUTILEnabled = True +SCEUTILLevel = 4 +SCEMISCEnabled = True +SCEMISCLevel = 4 +AUDIOEnabled = True +AUDIOLevel = 2 +IOEnabled = True +IOLevel = 2 +[PostShaderSetting] +BloomSettingValue1 = 0.600000 +BloomSettingValue2 = 0.500000 +CRTSettingValue1 = 1.000000 +CartoonSettingValue1 = 0.500000 +ColorCorrectionSettingValue1 = 1.000000 +ColorCorrectionSettingValue2 = 1.000000 +ColorCorrectionSettingValue3 = 1.000000 +ColorCorrectionSettingValue4 = 1.000000 +ScanlinesSettingValue1 = 1.000000 +ScanlinesSettingValue2 = 0.500000 +SharpenSettingValue1 = 1.500000 +[VR] +VREnable = True +VREnable6DoF = True +VREnableStereo = False +VREnableMotions = True +VRForce72Hz = True +VRManualForceVR = False +VRPassthrough = False +VRRescaleHUD = True +VRCameraDistance = 0.000000 +VRCameraHeight = 0.000000 +VRCameraSide = 0.000000 +VRCameraPitch = 0 +VRCanvasDistance = 12.000000 +VRFieldOfView = 100.000000 +VRHeadUpDisplayScale = 0.300000 +VRMotionLength = 0.500000 +VRHeadRotationScale = 5.000000 +VRHeadRotationEnabled = False +VRHeadRotationSmoothing = False +VRForce = False +VRImmersiveMode = True +VRCanvas3DDistance = 3.000000 diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/SM8550/controls.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/SM8550/controls.ini new file mode 120000 index 0000000000..b7f1ba78bb --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/SM8550/controls.ini @@ -0,0 +1 @@ +../InputPlumber/controls.ini \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/SM8550/ppsspp.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/SM8550/ppsspp.ini new file mode 100644 index 0000000000..acc403c601 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/SM8550/ppsspp.ini @@ -0,0 +1,690 @@ +[General] +FirstRun = False +RunCount = 0 +Enable Logging = False +AutoRun = True +Browse = False +IgnoreBadMemAccess = False +CurrentDirectory = /storage/roms/psp +ShowDebuggerOnLoad = False +CheckForNewVersion = True +Language = en_US +ForceLagSync = False +DiscordPresence = False +NumWorkerThreads = 8 +AutoLoadSaveState = 0 +EnableCheats = True +CwCheatRefreshRate = 77 +ScreenshotsAsPNG = False +UseFFV1 = False +DumpFrames = False +DumpAudio = False +SaveLoadResetsAVdumping = False +StateSlot = 0 +EnableStateUndo = True +RewindFlipFrequency = 0 +GridView1 = True +GridView2 = True +GridView3 = False +ComboMode = 0 +ReportingHost = default +AutoSaveSymbolMap = False +CacheFullIsoInRam = False +RemoteISOPort = 0 +LastRemoteISOServer = +LastRemoteISOPort = 0 +RemoteISOManualConfig = False +RemoteShareOnStartup = False +RemoteISOSubdir = / +RemoteDebuggerOnStartup = False +InternalScreenRotation = 1 +PauseWhenMinimized = False +DumpDecryptedEboots = False +MemStickInserted = True +ForceLagSync2 = False +UISound = True +CwCheatScrollPosition = 0.000000 +DumpVideoOutput = False +ShowRegionOnGameIcon = False +ShowIDOnGameIcon = False +GameGridScale = 1.000000 +RightAnalogUp = 0 +RightAnalogDown = 0 +RightAnalogLeft = 0 +RightAnalogRight = 0 +RightAnalogPress = 0 +RightAnalogCustom = False +LoadPlugins = False +GameListScrollPosition = 0.000000 +StateLoadUndoGame = NA +StateUndoLastSaveGame = NA +StateUndoLastSaveSlot = -5 +ShowOnScreenMessage = True +RightAnalogDisableDiagonal = False +SwipeUp = 0 +SwipeDown = 0 +SwipeLeft = 0 +SwipeRight = 0 +SwipeSensitivity = 1.000000 +SwipeSmoothing = 0.300000 +DoubleTapGesture = 0 +GestureControlEnabled = False +BackgroundAnimation = 1 +EnablePlugins = True +RewindSnapshotInterval = 0 +TransparentBackground = True +UITint = 0.000000 +UISaturation = 1.000000 +WindowX = -1 +WindowY = -1 +WindowWidth = 0 +WindowHeight = 0 +ShowMenuBar = True +IgnoreCompatSettings = +DiscordRichPresence = False +RemoteTab = False +RemoteISOSharedDir = +RemoteISOShareType = 0 +RunBehindPauseMenu = False +ShowGPOLEDs = False +[CPU] +CPUCore = 1 +SeparateSASThread = True +SeparateIOThread = True +IOTimingMethod = 0 +FastMemoryAccess = True +FuncReplacements = True +HideSlowWarnings = False +HideStateWarnings = False +PreloadFunctions = False +CPUSpeed = 0 +JitDisableFlags = 0x00000000 +FunctionReplacements = True +[Graphics] +EnableCardboard = False +CardboardScreenSize = 50 +CardboardXShift = 0 +CardboardYShift = 0 +ShowFPSCounter = 3 +GraphicsBackend = 0 (OPENGL) +FailedGraphicsBackends = +VulkanDevice = +RenderingMode = 0 +SoftwareRenderer = False +HardwareTransform = True +SoftwareSkinning = True +TextureFiltering = 1 +BufferFiltering = 1 +InternalResolution = 0 +AndroidHwScale = 1 +HighQualityDepth = 1 +FrameSkip = 0 +FrameSkipType = 0 +AutoFrameSkip = False +FrameRate = 0 +FrameRate2 = -1 +FrameSkipUnthrottle = True +ForceMaxEmulatedFPS = 30 +AnisotropyLevel = 0 +VertexDecCache = True +TextureBackoffCache = True +TextureSecondaryCache = False +FullScreen = True +FullScreenMulti = False +SmallDisplayZoomType = 2 +SmallDisplayOffsetX = 0.500000 +SmallDisplayOffsetY = 0.500000 +SmallDisplayZoomLevel = 1.000000 +ImmersiveMode = False +SustainedPerformanceMode = False +TrueColor = True +ReplaceTextures = True +SaveNewTextures = False +IgnoreTextureFilenames = True +TexScalingLevel = 1 +TexScalingType = 3 +TexDeposterize = False +VSyncInterval = True +DisableStencilTest = False +BloomHack = 2 +TimerHack = False +SplineBezierQuality = 0 +HardwareTessellation = False +PostShader = Off +MemBlockTransferGPU = True +DisableSlowFramebufEffects = True +FragmentTestCache = True +LogFrameDrops = False +EnableCardboardVR = False +DisabledGraphicsBackends = +CameraDevice = +UnthrottleMode = CONTINUOUS +IgnoreScreenInsets = True +TexHardwareScaling = False +TextureShader = Off +InflightFrames = 2 +RenderDuplicateFrames = True +ShaderChainRequires60FPS = False +ClearFramebuffersOnFirstUseHack = False +SoftwareRendererJit = True +UnthrottlingMode = CONTINUOUS +ReplaceTexturesAllowLate = True +iShowStatusFlags = 0 +UseGeometryShader = False +SkipBufferEffects = False +StereoRendering = False +StereoToMonoShader = RedBlue +AnalogFrameRate = 240 +MultiSampleLevel = 0 +DisplayOffsetX = 0.500000 +DisplayOffsetY = 0.500000 +DisplayScale = 1.000000 +DisplayIntegerScale = False +DisplayAspectRatio = 1.000000 +DisplayStretch = False +SkipGPUReadbacks = False +GpuLogProfiler = False +CameraMirrorHorizontal = False +AndroidFramerateMode = 1 +DisableRangeCulling = False +Smart2DTexFiltering = False +DisplayCropTo16x9 = True +VSync = False +SkipGPUReadbackMode = 0 +MultiThreading = True +UberShaderVertex = True +UberShaderFragment = True +DisplayRefreshRate = 60 +[Sound] +Enable = True +AudioBackend = 0 +AudioLatency = 1 +ExtraAudioBuffering = False +SoundSpeedHack = False +AudioResampler = False +GlobalVolume = 10 +AltSpeedVolume = -1 +AutoAudioDevice = True +ReverbVolume = 10 +[Control] +HapticFeedback = False +ShowTouchCross = True +ShowTouchCircle = True +ShowTouchSquare = True +ShowTouchTriangle = True +ComboKey0Mapping = 0 +ComboKey1Mapping = 0 +ComboKey2Mapping = 0 +ComboKey3Mapping = 0 +ComboKey4Mapping = 0 +ShowTouchPause = False +ShowTouchControls = False +DisableDpadDiagonals = False +GamepadOnlyFocused = False +TouchButtonStyle = 1 +TouchButtonOpacity = 65 +TouchButtonHideSeconds = 20 +AutoCenterTouchAnalog = False +ActionButtonSpacing2 = 1.000000 +ActionButtonCenterX = 0.937500 +ActionButtonCenterY = 0.900000 +ActionButtonScale = 1.150000 +DPadX = 0.074479 +DPadY = 0.760000 +DPadScale = 1.150000 +ShowTouchDpad = True +DPadSpacing = 1.000000 +StartKeyX = 0.559896 +StartKeyY = 0.942500 +StartKeyScale = 1.150000 +ShowTouchStart = True +SelectKeyX = 0.500000 +SelectKeyY = 0.942500 +SelectKeyScale = 1.150000 +ShowTouchSelect = True +UnthrottleKeyX = 0.440104 +UnthrottleKeyY = 0.942500 +UnthrottleKeyScale = 1.150000 +ShowTouchUnthrottle = True +LKeyX = 0.035937 +LKeyY = 0.635833 +LKeyScale = 1.150000 +ShowTouchLTrigger = True +RKeyX = 0.964063 +RKeyY = 0.635833 +RKeyScale = 1.150000 +ShowTouchRTrigger = True +AnalogStickX = 0.074479 +AnalogStickY = 0.923333 +AnalogStickScale = 1.150000 +ShowAnalogStick = True +fcombo0X = 0.571875 +fcombo0Y = 0.500000 +comboKeyScale0 = 1.150000 +ShowComboKey0 = False +fcombo1X = 0.631771 +fcombo1Y = 0.500000 +comboKeyScale1 = 1.150000 +ShowComboKey1 = False +fcombo2X = 0.691667 +fcombo2Y = 0.500000 +comboKeyScale2 = 1.150000 +ShowComboKey2 = False +fcombo3X = 0.571875 +fcombo3Y = 0.333333 +comboKeyScale3 = 1.150000 +ShowComboKey3 = False +fcombo4X = 0.631771 +fcombo4Y = 0.333333 +comboKeyScale4 = 1.150000 +ShowComboKey4 = False +Speed1KeyX = 0.440104 +Speed1KeyY = 0.885000 +Speed1KeyScale = 1.150000 +ShowSpeed1Key = False +Speed2KeyX = 0.500000 +Speed2KeyY = 0.885000 +Speed2KeyScale = 1.150000 +ShowSpeed2Key = False +XInputAnalogSensitivity = 1.000000 +AnalogLimiterDeadzone = 0.600000 +UseMouse = False +MapMouse = False +ConfineMap = False +MouseSensitivity = 0.100000 +MouseSmoothing = 0.900000 +ComboKey0Toggle = False +ComboKey1Toggle = False +ComboKey2Toggle = False +ComboKey3Toggle = False +ComboKey4Toggle = False +AnalogAutoRotSpeed = 15.000000 +TouchSnapToGrid = False +TouchSnapGridSize = 64 +RightAnalogStickX = 0.875000 +RightAnalogStickY = 0.856250 +RightAnalogStickScale = 1.150000 +ShowRightAnalogStick = False +RapidFireKeyX = 0.619792 +RapidFireKeyY = 0.784375 +RapidFireKeyScale = 1.150000 +ShowRapidFireKey = False +AnalogRotationCWKeyX = 0.500000 +AnalogRotationKeyCWY = 0.676562 +AnalogRotationKeyCWScale = 1.150000 +ShowAnalogRotationCWKey = False +AnalogRotationCCWKeyX = 0.380208 +AnalogRotationKeyCCWY = 0.676562 +AnalogRotationKeyCCWScale = 1.150000 +ShowAnalogRotationCCWKey = False +Custom0Mapping = 0x0000000000000000 +Custom0Image = 0 +Custom0Shape = 0 +Custom0Toggle = False +Custom1Mapping = 0x0000000000000000 +Custom1Image = 1 +Custom1Shape = 0 +Custom1Toggle = False +Custom2Mapping = 0x0000000000000000 +Custom2Image = 2 +Custom2Shape = 0 +Custom2Toggle = False +Custom3Mapping = 0x0000000000000000 +Custom3Image = 3 +Custom3Shape = 0 +Custom3Toggle = False +Custom4Mapping = 0x0000000000000000 +Custom4Image = 4 +Custom4Shape = 0 +Custom4Toggle = False +Custom5Mapping = 0x0000000000000000 +Custom5Image = 0 +Custom5Shape = 1 +Custom5Toggle = False +Custom6Mapping = 0x0000000000000000 +Custom6Image = 1 +Custom6Shape = 1 +Custom6Toggle = False +Custom7Mapping = 0x0000000000000000 +Custom7Image = 2 +Custom7Shape = 1 +Custom7Toggle = False +Custom8Mapping = 0x0000000000000000 +Custom8Image = 3 +Custom8Shape = 1 +Custom8Toggle = False +Custom9Mapping = 0x0000000000000000 +Custom9Image = 4 +Custom9Shape = 1 +Custom9Toggle = False +fcombo5X = 0.428125 +fcombo5Y = 0.500000 +comboKeyScale5 = 1.150000 +ShowComboKey5 = False +fcombo6X = 0.368229 +fcombo6Y = 0.500000 +comboKeyScale6 = 1.150000 +ShowComboKey6 = False +fcombo7X = 0.308333 +fcombo7Y = 0.500000 +comboKeyScale7 = 1.150000 +ShowComboKey7 = False +fcombo8X = 0.428125 +fcombo8Y = 0.333333 +comboKeyScale8 = 1.150000 +ShowComboKey8 = False +fcombo9X = 0.368229 +fcombo9Y = 0.333333 +comboKeyScale9 = 1.150000 +ShowComboKey9 = False +AnalogDeadzone = 0.150000 +AnalogInverseDeadzone = 0.000000 +AnalogSensitivity = 1.100000 +AnalogIsCircular = False +LeftStickHeadScale = 1.000000 +RightStickHeadScale = 1.000000 +HideStickBackground = False +SystemControls = True +Custom0Repeat = False +Custom1Repeat = False +Custom2Repeat = False +Custom3Repeat = False +Custom4Repeat = False +Custom5Repeat = False +Custom6Repeat = False +Custom7Repeat = False +Custom8Repeat = False +Custom9Repeat = False +Custom10Mapping = 0x0000000000000000 +Custom10Image = 0 +Custom10Shape = 2 +Custom10Toggle = False +Custom10Repeat = False +Custom11Mapping = 0x0000000000000000 +Custom11Image = 1 +Custom11Shape = 2 +Custom11Toggle = False +Custom11Repeat = False +Custom12Mapping = 0x0000000000000000 +Custom12Image = 2 +Custom12Shape = 2 +Custom12Toggle = False +Custom12Repeat = False +Custom13Mapping = 0x0000000000000000 +Custom13Image = 3 +Custom13Shape = 2 +Custom13Toggle = False +Custom13Repeat = False +Custom14Mapping = 0x0000000000000000 +Custom14Image = 4 +Custom14Shape = 2 +Custom14Toggle = False +Custom14Repeat = False +Custom15Mapping = 0x0000000000000000 +Custom15Image = 0 +Custom15Shape = 9 +Custom15Toggle = False +Custom15Repeat = False +Custom16Mapping = 0x0000000000000000 +Custom16Image = 1 +Custom16Shape = 9 +Custom16Toggle = False +Custom16Repeat = False +Custom17Mapping = 0x0000000000000000 +Custom17Image = 2 +Custom17Shape = 9 +Custom17Toggle = False +Custom17Repeat = False +Custom18Mapping = 0x0000000000000000 +Custom18Image = 3 +Custom18Shape = 9 +Custom18Toggle = False +Custom18Repeat = False +Custom19Mapping = 0x0000000000000000 +Custom19Image = 4 +Custom19Shape = 9 +Custom19Toggle = False +Custom19Repeat = False +fcombo10X = 0.571875 +fcombo10Y = 0.582465 +comboKeyScale10 = 1.150000 +ShowComboKey10 = False +fcombo11X = 0.631771 +fcombo11Y = 0.582465 +comboKeyScale11 = 1.150000 +ShowComboKey11 = False +fcombo12X = 0.691667 +fcombo12Y = 0.582465 +comboKeyScale12 = 1.150000 +ShowComboKey12 = False +fcombo13X = 0.571875 +fcombo13Y = 0.415799 +comboKeyScale13 = 1.150000 +ShowComboKey13 = False +fcombo14X = 0.631771 +fcombo14Y = 0.415799 +comboKeyScale14 = 1.150000 +ShowComboKey14 = False +fcombo15X = 0.428125 +fcombo15Y = 0.582465 +comboKeyScale15 = 1.150000 +ShowComboKey15 = False +fcombo16X = 0.368229 +fcombo16Y = 0.582465 +comboKeyScale16 = 1.150000 +ShowComboKey16 = False +fcombo17X = 0.308333 +fcombo17Y = 0.582465 +comboKeyScale17 = 1.150000 +ShowComboKey17 = False +fcombo18X = 0.428125 +fcombo18Y = 0.415799 +comboKeyScale18 = 1.150000 +ShowComboKey18 = False +fcombo19X = 0.368229 +fcombo19Y = 0.415799 +comboKeyScale19 = 1.150000 +ShowComboKey19 = False +StickyTouchDPad = False +AnalogTriggerThreshold = 0.750000 +AllowMappingCombos = True +StrictComboOrder = False +MouseWheelUpDelayMs = 80 +RapidFileInterval = 5 +AnalogGesture = False +AnalogGestureSensibility = 1.000000 +[Network] +EnableWlan = False +EnableAdhocServer = False +proAdhocServer = myneighborsushicat.com +PortOffset = 0 +MinTimeout = 1 +TCPNoDelay = False +EnableUPnP = False +UPnPUseOriginalPort = True +EnableNetworkChat = False +ChatButtonPosition = 0 +ChatScreenPosition = 0 +EnableQuickChat = True +QuickChat1 = Quick Chat 1 +QuickChat2 = Quick Chat 2 +QuickChat3 = Quick Chat 3 +QuickChat4 = Quick Chat 4 +QuickChat5 = Quick Chat 5 +ForcedFirstConnect = False +[SystemParam] +PSPModel = 0 +PSPFirmwareVersion = 660 +NickName = PPSSPP +proAdhocServer = black-seraph.com +MacAddress = 4e:7a:78:d9:49:32 +PortOffset = 0 +Language = 1 +TimeFormat = 1 +DateFormat = 1 +TimeZone = 0 +DayLightSavings = False +ButtonPreference = 1 +LockParentalLevel = 0 +WlanAdhocChannel = 0 +WlanPowerSave = False +EncryptSave = True +SavedataUpgradeVersion = True +ParamTimeFormat = 0 +ParamDateFormat = 0 +MemStickSize = 16 +[Debugger] +DisasmWindowX = -1 +DisasmWindowY = -1 +DisasmWindowW = -1 +DisasmWindowH = -1 +GEWindowX = -1 +GEWindowY = -1 +GEWindowW = -1 +GEWindowH = -1 +ConsoleWindowX = -1 +ConsoleWindowY = -1 +FontWidth = 8 +FontHeight = 12 +DisplayStatusBar = True +ShowBottomTabTitles = True +ShowDeveloperMenu = False +SkipDeadbeefFilling = False +FuncHashMap = False +DrawFrameGraph = False +MemInfoDetailed = False +GEWindowTabsBL = 0x00000000 +GEWindowTabsBR = 0x00000000 +GEWindowTabsTR = 0x00000000 +SkipFuncHashMap = +[Upgrade] +UpgradeMessage = +UpgradeVersion = 1.12.0 +DismissedVersion = +[Theme] +ItemStyleFg = 0xffffffff +ItemStyleBg = 0x55000000 +ItemFocusedStyleFg = 0xffffffff +ItemFocusedStyleBg = 0xffedc24c +ItemDownStyleFg = 0xffffffff +ItemDownStyleBg = 0xffbd9939 +ItemDisabledStyleFg = 0x80eeeeee +ItemDisabledStyleBg = 0x55e0d4af +ItemHighlightedStyleFg = 0xffffffff +ItemHighlightedStyleBg = 0x55bdbb39 +ButtonStyleFg = 0xffffffff +ButtonStyleBg = 0x55000000 +ButtonFocusedStyleFg = 0xffffffff +ButtonFocusedStyleBg = 0xffedc24c +ButtonDownStyleFg = 0xffffffff +ButtonDownStyleBg = 0xffbd9939 +ButtonDisabledStyleFg = 0x80eeeeee +ButtonDisabledStyleBg = 0x55e0d4af +ButtonHighlightedStyleFg = 0xffffffff +ButtonHighlightedStyleBg = 0x55bdbb39 +HeaderStyleFg = 0xffffffff +InfoStyleFg = 0xffffffff +InfoStyleBg = 0x00000000 +PopupTitleStyleFg = 0xffe3be59 +PopupStyleFg = 0xffffffff +PopupStyleBg = 0xff303030 +ThemeName = Default +[Recent] +MaxRecent = 30 +FileName0 = +[Log] +SYSTEMEnabled = True +SYSTEMLevel = 4 +BOOTEnabled = True +BOOTLevel = 4 +COMMONEnabled = True +COMMONLevel = 4 +CPUEnabled = True +CPULevel = 4 +FILESYSEnabled = True +FILESYSLevel = 4 +G3DEnabled = True +G3DLevel = 4 +HLEEnabled = True +HLELevel = 4 +JITEnabled = True +JITLevel = 4 +LOADEREnabled = True +LOADERLevel = 4 +MEEnabled = True +MELevel = 4 +MEMMAPEnabled = True +MEMMAPLevel = 4 +SASMIXEnabled = True +SASMIXLevel = 4 +SAVESTATEEnabled = True +SAVESTATELevel = 4 +FRAMEBUFEnabled = True +FRAMEBUFLevel = 4 +SCEAUDIOEnabled = True +SCEAUDIOLevel = 4 +SCECTRLEnabled = True +SCECTRLLevel = 4 +SCEDISPEnabled = True +SCEDISPLevel = 4 +SCEFONTEnabled = True +SCEFONTLevel = 4 +SCEGEEnabled = True +SCEGELevel = 4 +SCEINTCEnabled = True +SCEINTCLevel = 4 +SCEIOEnabled = True +SCEIOLevel = 4 +SCEKERNELEnabled = True +SCEKERNELLevel = 4 +SCEMODULEEnabled = True +SCEMODULELevel = 4 +SCENETEnabled = True +SCENETLevel = 4 +SCERTCEnabled = True +SCERTCLevel = 4 +SCESASEnabled = True +SCESASLevel = 4 +SCEUTILEnabled = True +SCEUTILLevel = 4 +SCEMISCEnabled = True +SCEMISCLevel = 4 +AUDIOEnabled = True +AUDIOLevel = 2 +IOEnabled = True +IOLevel = 2 +[PostShaderSetting] +BloomSettingValue1 = 0.600000 +BloomSettingValue2 = 0.500000 +CRTSettingValue1 = 1.000000 +CartoonSettingValue1 = 0.500000 +ColorCorrectionSettingValue1 = 1.000000 +ColorCorrectionSettingValue2 = 1.000000 +ColorCorrectionSettingValue3 = 1.000000 +ColorCorrectionSettingValue4 = 1.000000 +ScanlinesSettingValue1 = 1.000000 +ScanlinesSettingValue2 = 0.500000 +SharpenSettingValue1 = 1.500000 +[VR] +VREnable = True +VREnable6DoF = True +VREnableStereo = False +VREnableMotions = True +VRForce72Hz = True +VRManualForceVR = False +VRPassthrough = False +VRRescaleHUD = True +VRCameraDistance = 0.000000 +VRCameraHeight = 0.000000 +VRCameraSide = 0.000000 +VRCameraPitch = 0 +VRCanvasDistance = 12.000000 +VRFieldOfView = 100.000000 +VRHeadUpDisplayScale = 0.300000 +VRMotionLength = 0.500000 +VRHeadRotationScale = 5.000000 +VRHeadRotationEnabled = False +VRHeadRotationSmoothing = False +VRForce = False +VRImmersiveMode = True +VRCanvas3DDistance = 3.000000 diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/SM8650/controls.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/SM8650/controls.ini new file mode 120000 index 0000000000..b7f1ba78bb --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/SM8650/controls.ini @@ -0,0 +1 @@ +../InputPlumber/controls.ini \ No newline at end of file diff --git a/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/SM8650/ppsspp.ini b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/SM8650/ppsspp.ini new file mode 100644 index 0000000000..acc403c601 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/ppsspp-sa/sources/SM8650/ppsspp.ini @@ -0,0 +1,690 @@ +[General] +FirstRun = False +RunCount = 0 +Enable Logging = False +AutoRun = True +Browse = False +IgnoreBadMemAccess = False +CurrentDirectory = /storage/roms/psp +ShowDebuggerOnLoad = False +CheckForNewVersion = True +Language = en_US +ForceLagSync = False +DiscordPresence = False +NumWorkerThreads = 8 +AutoLoadSaveState = 0 +EnableCheats = True +CwCheatRefreshRate = 77 +ScreenshotsAsPNG = False +UseFFV1 = False +DumpFrames = False +DumpAudio = False +SaveLoadResetsAVdumping = False +StateSlot = 0 +EnableStateUndo = True +RewindFlipFrequency = 0 +GridView1 = True +GridView2 = True +GridView3 = False +ComboMode = 0 +ReportingHost = default +AutoSaveSymbolMap = False +CacheFullIsoInRam = False +RemoteISOPort = 0 +LastRemoteISOServer = +LastRemoteISOPort = 0 +RemoteISOManualConfig = False +RemoteShareOnStartup = False +RemoteISOSubdir = / +RemoteDebuggerOnStartup = False +InternalScreenRotation = 1 +PauseWhenMinimized = False +DumpDecryptedEboots = False +MemStickInserted = True +ForceLagSync2 = False +UISound = True +CwCheatScrollPosition = 0.000000 +DumpVideoOutput = False +ShowRegionOnGameIcon = False +ShowIDOnGameIcon = False +GameGridScale = 1.000000 +RightAnalogUp = 0 +RightAnalogDown = 0 +RightAnalogLeft = 0 +RightAnalogRight = 0 +RightAnalogPress = 0 +RightAnalogCustom = False +LoadPlugins = False +GameListScrollPosition = 0.000000 +StateLoadUndoGame = NA +StateUndoLastSaveGame = NA +StateUndoLastSaveSlot = -5 +ShowOnScreenMessage = True +RightAnalogDisableDiagonal = False +SwipeUp = 0 +SwipeDown = 0 +SwipeLeft = 0 +SwipeRight = 0 +SwipeSensitivity = 1.000000 +SwipeSmoothing = 0.300000 +DoubleTapGesture = 0 +GestureControlEnabled = False +BackgroundAnimation = 1 +EnablePlugins = True +RewindSnapshotInterval = 0 +TransparentBackground = True +UITint = 0.000000 +UISaturation = 1.000000 +WindowX = -1 +WindowY = -1 +WindowWidth = 0 +WindowHeight = 0 +ShowMenuBar = True +IgnoreCompatSettings = +DiscordRichPresence = False +RemoteTab = False +RemoteISOSharedDir = +RemoteISOShareType = 0 +RunBehindPauseMenu = False +ShowGPOLEDs = False +[CPU] +CPUCore = 1 +SeparateSASThread = True +SeparateIOThread = True +IOTimingMethod = 0 +FastMemoryAccess = True +FuncReplacements = True +HideSlowWarnings = False +HideStateWarnings = False +PreloadFunctions = False +CPUSpeed = 0 +JitDisableFlags = 0x00000000 +FunctionReplacements = True +[Graphics] +EnableCardboard = False +CardboardScreenSize = 50 +CardboardXShift = 0 +CardboardYShift = 0 +ShowFPSCounter = 3 +GraphicsBackend = 0 (OPENGL) +FailedGraphicsBackends = +VulkanDevice = +RenderingMode = 0 +SoftwareRenderer = False +HardwareTransform = True +SoftwareSkinning = True +TextureFiltering = 1 +BufferFiltering = 1 +InternalResolution = 0 +AndroidHwScale = 1 +HighQualityDepth = 1 +FrameSkip = 0 +FrameSkipType = 0 +AutoFrameSkip = False +FrameRate = 0 +FrameRate2 = -1 +FrameSkipUnthrottle = True +ForceMaxEmulatedFPS = 30 +AnisotropyLevel = 0 +VertexDecCache = True +TextureBackoffCache = True +TextureSecondaryCache = False +FullScreen = True +FullScreenMulti = False +SmallDisplayZoomType = 2 +SmallDisplayOffsetX = 0.500000 +SmallDisplayOffsetY = 0.500000 +SmallDisplayZoomLevel = 1.000000 +ImmersiveMode = False +SustainedPerformanceMode = False +TrueColor = True +ReplaceTextures = True +SaveNewTextures = False +IgnoreTextureFilenames = True +TexScalingLevel = 1 +TexScalingType = 3 +TexDeposterize = False +VSyncInterval = True +DisableStencilTest = False +BloomHack = 2 +TimerHack = False +SplineBezierQuality = 0 +HardwareTessellation = False +PostShader = Off +MemBlockTransferGPU = True +DisableSlowFramebufEffects = True +FragmentTestCache = True +LogFrameDrops = False +EnableCardboardVR = False +DisabledGraphicsBackends = +CameraDevice = +UnthrottleMode = CONTINUOUS +IgnoreScreenInsets = True +TexHardwareScaling = False +TextureShader = Off +InflightFrames = 2 +RenderDuplicateFrames = True +ShaderChainRequires60FPS = False +ClearFramebuffersOnFirstUseHack = False +SoftwareRendererJit = True +UnthrottlingMode = CONTINUOUS +ReplaceTexturesAllowLate = True +iShowStatusFlags = 0 +UseGeometryShader = False +SkipBufferEffects = False +StereoRendering = False +StereoToMonoShader = RedBlue +AnalogFrameRate = 240 +MultiSampleLevel = 0 +DisplayOffsetX = 0.500000 +DisplayOffsetY = 0.500000 +DisplayScale = 1.000000 +DisplayIntegerScale = False +DisplayAspectRatio = 1.000000 +DisplayStretch = False +SkipGPUReadbacks = False +GpuLogProfiler = False +CameraMirrorHorizontal = False +AndroidFramerateMode = 1 +DisableRangeCulling = False +Smart2DTexFiltering = False +DisplayCropTo16x9 = True +VSync = False +SkipGPUReadbackMode = 0 +MultiThreading = True +UberShaderVertex = True +UberShaderFragment = True +DisplayRefreshRate = 60 +[Sound] +Enable = True +AudioBackend = 0 +AudioLatency = 1 +ExtraAudioBuffering = False +SoundSpeedHack = False +AudioResampler = False +GlobalVolume = 10 +AltSpeedVolume = -1 +AutoAudioDevice = True +ReverbVolume = 10 +[Control] +HapticFeedback = False +ShowTouchCross = True +ShowTouchCircle = True +ShowTouchSquare = True +ShowTouchTriangle = True +ComboKey0Mapping = 0 +ComboKey1Mapping = 0 +ComboKey2Mapping = 0 +ComboKey3Mapping = 0 +ComboKey4Mapping = 0 +ShowTouchPause = False +ShowTouchControls = False +DisableDpadDiagonals = False +GamepadOnlyFocused = False +TouchButtonStyle = 1 +TouchButtonOpacity = 65 +TouchButtonHideSeconds = 20 +AutoCenterTouchAnalog = False +ActionButtonSpacing2 = 1.000000 +ActionButtonCenterX = 0.937500 +ActionButtonCenterY = 0.900000 +ActionButtonScale = 1.150000 +DPadX = 0.074479 +DPadY = 0.760000 +DPadScale = 1.150000 +ShowTouchDpad = True +DPadSpacing = 1.000000 +StartKeyX = 0.559896 +StartKeyY = 0.942500 +StartKeyScale = 1.150000 +ShowTouchStart = True +SelectKeyX = 0.500000 +SelectKeyY = 0.942500 +SelectKeyScale = 1.150000 +ShowTouchSelect = True +UnthrottleKeyX = 0.440104 +UnthrottleKeyY = 0.942500 +UnthrottleKeyScale = 1.150000 +ShowTouchUnthrottle = True +LKeyX = 0.035937 +LKeyY = 0.635833 +LKeyScale = 1.150000 +ShowTouchLTrigger = True +RKeyX = 0.964063 +RKeyY = 0.635833 +RKeyScale = 1.150000 +ShowTouchRTrigger = True +AnalogStickX = 0.074479 +AnalogStickY = 0.923333 +AnalogStickScale = 1.150000 +ShowAnalogStick = True +fcombo0X = 0.571875 +fcombo0Y = 0.500000 +comboKeyScale0 = 1.150000 +ShowComboKey0 = False +fcombo1X = 0.631771 +fcombo1Y = 0.500000 +comboKeyScale1 = 1.150000 +ShowComboKey1 = False +fcombo2X = 0.691667 +fcombo2Y = 0.500000 +comboKeyScale2 = 1.150000 +ShowComboKey2 = False +fcombo3X = 0.571875 +fcombo3Y = 0.333333 +comboKeyScale3 = 1.150000 +ShowComboKey3 = False +fcombo4X = 0.631771 +fcombo4Y = 0.333333 +comboKeyScale4 = 1.150000 +ShowComboKey4 = False +Speed1KeyX = 0.440104 +Speed1KeyY = 0.885000 +Speed1KeyScale = 1.150000 +ShowSpeed1Key = False +Speed2KeyX = 0.500000 +Speed2KeyY = 0.885000 +Speed2KeyScale = 1.150000 +ShowSpeed2Key = False +XInputAnalogSensitivity = 1.000000 +AnalogLimiterDeadzone = 0.600000 +UseMouse = False +MapMouse = False +ConfineMap = False +MouseSensitivity = 0.100000 +MouseSmoothing = 0.900000 +ComboKey0Toggle = False +ComboKey1Toggle = False +ComboKey2Toggle = False +ComboKey3Toggle = False +ComboKey4Toggle = False +AnalogAutoRotSpeed = 15.000000 +TouchSnapToGrid = False +TouchSnapGridSize = 64 +RightAnalogStickX = 0.875000 +RightAnalogStickY = 0.856250 +RightAnalogStickScale = 1.150000 +ShowRightAnalogStick = False +RapidFireKeyX = 0.619792 +RapidFireKeyY = 0.784375 +RapidFireKeyScale = 1.150000 +ShowRapidFireKey = False +AnalogRotationCWKeyX = 0.500000 +AnalogRotationKeyCWY = 0.676562 +AnalogRotationKeyCWScale = 1.150000 +ShowAnalogRotationCWKey = False +AnalogRotationCCWKeyX = 0.380208 +AnalogRotationKeyCCWY = 0.676562 +AnalogRotationKeyCCWScale = 1.150000 +ShowAnalogRotationCCWKey = False +Custom0Mapping = 0x0000000000000000 +Custom0Image = 0 +Custom0Shape = 0 +Custom0Toggle = False +Custom1Mapping = 0x0000000000000000 +Custom1Image = 1 +Custom1Shape = 0 +Custom1Toggle = False +Custom2Mapping = 0x0000000000000000 +Custom2Image = 2 +Custom2Shape = 0 +Custom2Toggle = False +Custom3Mapping = 0x0000000000000000 +Custom3Image = 3 +Custom3Shape = 0 +Custom3Toggle = False +Custom4Mapping = 0x0000000000000000 +Custom4Image = 4 +Custom4Shape = 0 +Custom4Toggle = False +Custom5Mapping = 0x0000000000000000 +Custom5Image = 0 +Custom5Shape = 1 +Custom5Toggle = False +Custom6Mapping = 0x0000000000000000 +Custom6Image = 1 +Custom6Shape = 1 +Custom6Toggle = False +Custom7Mapping = 0x0000000000000000 +Custom7Image = 2 +Custom7Shape = 1 +Custom7Toggle = False +Custom8Mapping = 0x0000000000000000 +Custom8Image = 3 +Custom8Shape = 1 +Custom8Toggle = False +Custom9Mapping = 0x0000000000000000 +Custom9Image = 4 +Custom9Shape = 1 +Custom9Toggle = False +fcombo5X = 0.428125 +fcombo5Y = 0.500000 +comboKeyScale5 = 1.150000 +ShowComboKey5 = False +fcombo6X = 0.368229 +fcombo6Y = 0.500000 +comboKeyScale6 = 1.150000 +ShowComboKey6 = False +fcombo7X = 0.308333 +fcombo7Y = 0.500000 +comboKeyScale7 = 1.150000 +ShowComboKey7 = False +fcombo8X = 0.428125 +fcombo8Y = 0.333333 +comboKeyScale8 = 1.150000 +ShowComboKey8 = False +fcombo9X = 0.368229 +fcombo9Y = 0.333333 +comboKeyScale9 = 1.150000 +ShowComboKey9 = False +AnalogDeadzone = 0.150000 +AnalogInverseDeadzone = 0.000000 +AnalogSensitivity = 1.100000 +AnalogIsCircular = False +LeftStickHeadScale = 1.000000 +RightStickHeadScale = 1.000000 +HideStickBackground = False +SystemControls = True +Custom0Repeat = False +Custom1Repeat = False +Custom2Repeat = False +Custom3Repeat = False +Custom4Repeat = False +Custom5Repeat = False +Custom6Repeat = False +Custom7Repeat = False +Custom8Repeat = False +Custom9Repeat = False +Custom10Mapping = 0x0000000000000000 +Custom10Image = 0 +Custom10Shape = 2 +Custom10Toggle = False +Custom10Repeat = False +Custom11Mapping = 0x0000000000000000 +Custom11Image = 1 +Custom11Shape = 2 +Custom11Toggle = False +Custom11Repeat = False +Custom12Mapping = 0x0000000000000000 +Custom12Image = 2 +Custom12Shape = 2 +Custom12Toggle = False +Custom12Repeat = False +Custom13Mapping = 0x0000000000000000 +Custom13Image = 3 +Custom13Shape = 2 +Custom13Toggle = False +Custom13Repeat = False +Custom14Mapping = 0x0000000000000000 +Custom14Image = 4 +Custom14Shape = 2 +Custom14Toggle = False +Custom14Repeat = False +Custom15Mapping = 0x0000000000000000 +Custom15Image = 0 +Custom15Shape = 9 +Custom15Toggle = False +Custom15Repeat = False +Custom16Mapping = 0x0000000000000000 +Custom16Image = 1 +Custom16Shape = 9 +Custom16Toggle = False +Custom16Repeat = False +Custom17Mapping = 0x0000000000000000 +Custom17Image = 2 +Custom17Shape = 9 +Custom17Toggle = False +Custom17Repeat = False +Custom18Mapping = 0x0000000000000000 +Custom18Image = 3 +Custom18Shape = 9 +Custom18Toggle = False +Custom18Repeat = False +Custom19Mapping = 0x0000000000000000 +Custom19Image = 4 +Custom19Shape = 9 +Custom19Toggle = False +Custom19Repeat = False +fcombo10X = 0.571875 +fcombo10Y = 0.582465 +comboKeyScale10 = 1.150000 +ShowComboKey10 = False +fcombo11X = 0.631771 +fcombo11Y = 0.582465 +comboKeyScale11 = 1.150000 +ShowComboKey11 = False +fcombo12X = 0.691667 +fcombo12Y = 0.582465 +comboKeyScale12 = 1.150000 +ShowComboKey12 = False +fcombo13X = 0.571875 +fcombo13Y = 0.415799 +comboKeyScale13 = 1.150000 +ShowComboKey13 = False +fcombo14X = 0.631771 +fcombo14Y = 0.415799 +comboKeyScale14 = 1.150000 +ShowComboKey14 = False +fcombo15X = 0.428125 +fcombo15Y = 0.582465 +comboKeyScale15 = 1.150000 +ShowComboKey15 = False +fcombo16X = 0.368229 +fcombo16Y = 0.582465 +comboKeyScale16 = 1.150000 +ShowComboKey16 = False +fcombo17X = 0.308333 +fcombo17Y = 0.582465 +comboKeyScale17 = 1.150000 +ShowComboKey17 = False +fcombo18X = 0.428125 +fcombo18Y = 0.415799 +comboKeyScale18 = 1.150000 +ShowComboKey18 = False +fcombo19X = 0.368229 +fcombo19Y = 0.415799 +comboKeyScale19 = 1.150000 +ShowComboKey19 = False +StickyTouchDPad = False +AnalogTriggerThreshold = 0.750000 +AllowMappingCombos = True +StrictComboOrder = False +MouseWheelUpDelayMs = 80 +RapidFileInterval = 5 +AnalogGesture = False +AnalogGestureSensibility = 1.000000 +[Network] +EnableWlan = False +EnableAdhocServer = False +proAdhocServer = myneighborsushicat.com +PortOffset = 0 +MinTimeout = 1 +TCPNoDelay = False +EnableUPnP = False +UPnPUseOriginalPort = True +EnableNetworkChat = False +ChatButtonPosition = 0 +ChatScreenPosition = 0 +EnableQuickChat = True +QuickChat1 = Quick Chat 1 +QuickChat2 = Quick Chat 2 +QuickChat3 = Quick Chat 3 +QuickChat4 = Quick Chat 4 +QuickChat5 = Quick Chat 5 +ForcedFirstConnect = False +[SystemParam] +PSPModel = 0 +PSPFirmwareVersion = 660 +NickName = PPSSPP +proAdhocServer = black-seraph.com +MacAddress = 4e:7a:78:d9:49:32 +PortOffset = 0 +Language = 1 +TimeFormat = 1 +DateFormat = 1 +TimeZone = 0 +DayLightSavings = False +ButtonPreference = 1 +LockParentalLevel = 0 +WlanAdhocChannel = 0 +WlanPowerSave = False +EncryptSave = True +SavedataUpgradeVersion = True +ParamTimeFormat = 0 +ParamDateFormat = 0 +MemStickSize = 16 +[Debugger] +DisasmWindowX = -1 +DisasmWindowY = -1 +DisasmWindowW = -1 +DisasmWindowH = -1 +GEWindowX = -1 +GEWindowY = -1 +GEWindowW = -1 +GEWindowH = -1 +ConsoleWindowX = -1 +ConsoleWindowY = -1 +FontWidth = 8 +FontHeight = 12 +DisplayStatusBar = True +ShowBottomTabTitles = True +ShowDeveloperMenu = False +SkipDeadbeefFilling = False +FuncHashMap = False +DrawFrameGraph = False +MemInfoDetailed = False +GEWindowTabsBL = 0x00000000 +GEWindowTabsBR = 0x00000000 +GEWindowTabsTR = 0x00000000 +SkipFuncHashMap = +[Upgrade] +UpgradeMessage = +UpgradeVersion = 1.12.0 +DismissedVersion = +[Theme] +ItemStyleFg = 0xffffffff +ItemStyleBg = 0x55000000 +ItemFocusedStyleFg = 0xffffffff +ItemFocusedStyleBg = 0xffedc24c +ItemDownStyleFg = 0xffffffff +ItemDownStyleBg = 0xffbd9939 +ItemDisabledStyleFg = 0x80eeeeee +ItemDisabledStyleBg = 0x55e0d4af +ItemHighlightedStyleFg = 0xffffffff +ItemHighlightedStyleBg = 0x55bdbb39 +ButtonStyleFg = 0xffffffff +ButtonStyleBg = 0x55000000 +ButtonFocusedStyleFg = 0xffffffff +ButtonFocusedStyleBg = 0xffedc24c +ButtonDownStyleFg = 0xffffffff +ButtonDownStyleBg = 0xffbd9939 +ButtonDisabledStyleFg = 0x80eeeeee +ButtonDisabledStyleBg = 0x55e0d4af +ButtonHighlightedStyleFg = 0xffffffff +ButtonHighlightedStyleBg = 0x55bdbb39 +HeaderStyleFg = 0xffffffff +InfoStyleFg = 0xffffffff +InfoStyleBg = 0x00000000 +PopupTitleStyleFg = 0xffe3be59 +PopupStyleFg = 0xffffffff +PopupStyleBg = 0xff303030 +ThemeName = Default +[Recent] +MaxRecent = 30 +FileName0 = +[Log] +SYSTEMEnabled = True +SYSTEMLevel = 4 +BOOTEnabled = True +BOOTLevel = 4 +COMMONEnabled = True +COMMONLevel = 4 +CPUEnabled = True +CPULevel = 4 +FILESYSEnabled = True +FILESYSLevel = 4 +G3DEnabled = True +G3DLevel = 4 +HLEEnabled = True +HLELevel = 4 +JITEnabled = True +JITLevel = 4 +LOADEREnabled = True +LOADERLevel = 4 +MEEnabled = True +MELevel = 4 +MEMMAPEnabled = True +MEMMAPLevel = 4 +SASMIXEnabled = True +SASMIXLevel = 4 +SAVESTATEEnabled = True +SAVESTATELevel = 4 +FRAMEBUFEnabled = True +FRAMEBUFLevel = 4 +SCEAUDIOEnabled = True +SCEAUDIOLevel = 4 +SCECTRLEnabled = True +SCECTRLLevel = 4 +SCEDISPEnabled = True +SCEDISPLevel = 4 +SCEFONTEnabled = True +SCEFONTLevel = 4 +SCEGEEnabled = True +SCEGELevel = 4 +SCEINTCEnabled = True +SCEINTCLevel = 4 +SCEIOEnabled = True +SCEIOLevel = 4 +SCEKERNELEnabled = True +SCEKERNELLevel = 4 +SCEMODULEEnabled = True +SCEMODULELevel = 4 +SCENETEnabled = True +SCENETLevel = 4 +SCERTCEnabled = True +SCERTCLevel = 4 +SCESASEnabled = True +SCESASLevel = 4 +SCEUTILEnabled = True +SCEUTILLevel = 4 +SCEMISCEnabled = True +SCEMISCLevel = 4 +AUDIOEnabled = True +AUDIOLevel = 2 +IOEnabled = True +IOLevel = 2 +[PostShaderSetting] +BloomSettingValue1 = 0.600000 +BloomSettingValue2 = 0.500000 +CRTSettingValue1 = 1.000000 +CartoonSettingValue1 = 0.500000 +ColorCorrectionSettingValue1 = 1.000000 +ColorCorrectionSettingValue2 = 1.000000 +ColorCorrectionSettingValue3 = 1.000000 +ColorCorrectionSettingValue4 = 1.000000 +ScanlinesSettingValue1 = 1.000000 +ScanlinesSettingValue2 = 0.500000 +SharpenSettingValue1 = 1.500000 +[VR] +VREnable = True +VREnable6DoF = True +VREnableStereo = False +VREnableMotions = True +VRForce72Hz = True +VRManualForceVR = False +VRPassthrough = False +VRRescaleHUD = True +VRCameraDistance = 0.000000 +VRCameraHeight = 0.000000 +VRCameraSide = 0.000000 +VRCameraPitch = 0 +VRCanvasDistance = 12.000000 +VRFieldOfView = 100.000000 +VRHeadUpDisplayScale = 0.300000 +VRMotionLength = 0.500000 +VRHeadRotationScale = 5.000000 +VRHeadRotationEnabled = False +VRHeadRotationSmoothing = False +VRForce = False +VRImmersiveMode = True +VRCanvas3DDistance = 3.000000 diff --git a/projects/ArchR/packages/emulators/standalone/scummvmsa/config/games/_Scan ScummVM Games.sh b/projects/ArchR/packages/emulators/standalone/scummvmsa/config/games/_Scan ScummVM Games.sh new file mode 100644 index 0000000000..b2977c3e74 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/scummvmsa/config/games/_Scan ScummVM Games.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2019-present Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +clear +echo "Scanning for games..." +bash /usr/bin/start_scummvm.sh add +echo "Adding games..." +bash /usr/bin/start_scummvm.sh create +clear diff --git a/projects/ArchR/packages/emulators/standalone/scummvmsa/config/scummvm.ini b/projects/ArchR/packages/emulators/standalone/scummvmsa/config/scummvm.ini new file mode 100644 index 0000000000..14851019f2 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/scummvmsa/config/scummvm.ini @@ -0,0 +1,45 @@ +[scummvm] +filtering=false +fluidsynth_misc_interpolation=4th +last_fullscreen_mode_width=1920 +multi_midi=false +gui_browser_show_hidden=true +soundfont=/usr/share/soundfonts/GeneralUser.sf2 +fluidsynth_chorus_nr=3 +fluidsynth_chorus_waveform=sine +music_driver=auto +vsync=true +local_server_port=12345 +fluidsynth_chorus_activate=true +last_fullscreen_mode_height=1152 +mt32_device=null +talkspeed=60 +gfx_mode=surfacesdl +gui_scale=100 +subtitles=false +fluidsynth_reverb_level=90 +fluidsynth_reverb_activate=true +browser_lastpath=/storage/roms/scummvm +music_volume=192 +opl_driver=auto +fluidsynth_chorus_level=100 +aspect_ratio=false +autosave_period=300 +fluidsynth_chorus_depth=80 +native_mt32=false +fluidsynth_reverb_roomsize=20 +gui_return_to_launcher_at_exit=false +fullscreen=true +gm_device=fluidsynth +sfx_volume=192 +fluidsynth_chorus_speed=30 +speech_volume=192 +gui_use_game_language=false +mute=false +confirm_exit=false +midi_gain=100 +fluidsynth_reverb_width=1 +fluidsynth_reverb_damping=0 +versioninfo=2.6.0git +speech_mute=false +enable_gs=false diff --git a/projects/ArchR/packages/emulators/standalone/scummvmsa/package.mk b/projects/ArchR/packages/emulators/standalone/scummvmsa/package.mk new file mode 100644 index 0000000000..8c11a72be0 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/scummvmsa/package.mk @@ -0,0 +1,33 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2019-present Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="scummvmsa" +PKG_VERSION="2026.1.0" +PKG_LICENSE="GPL2" +PKG_SITE="https://github.com/scummvm/scummvm" +PKG_URL="${PKG_SITE}/archive/refs/tags/v${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain SDL2 SDL2_net freetype fluidsynth soundfont-generaluser pipewire" +PKG_LONGDESC="Script Creation Utility for Maniac Mansion Virtual Machine" + +pre_configure_target() { + sed -i "s|sdl-config|sdl2-config|g" ${PKG_BUILD}/configure + TARGET_CONFIGURE_OPTS="--host=${TARGET_NAME} --backend=sdl --disable-alsa --with-sdl-prefix=${SYSROOT_PREFIX}/usr/bin --disable-debug --enable-release --enable-vkeybd --opengl-mode=gles2 --enable-optimizations" +} + +post_makeinstall_target() { + mkdir -p ${INSTALL}/usr/config/scummvm/ + cp -rf ${PKG_DIR}/config/* ${INSTALL}/usr/config/scummvm/ + chmod 0755 ${INSTALL}/usr/config/scummvm/games/*sh + + mkdir -p ${INSTALL}/usr/config/scummvm/themes + cp -rf ${PKG_BUILD}/gui/themes ${INSTALL}/usr/config/scummvm/themes + + mv ${INSTALL}/usr/local/bin ${INSTALL}/usr/ + cp -rf ${PKG_DIR}/sources/* ${INSTALL}/usr/bin + chmod 755 ${INSTALL}/usr/bin/* + + for i in appdata applications doc icons man; do + rm -rf "${INSTALL}/usr/local/share/${i}" + done +} diff --git a/projects/ArchR/packages/emulators/standalone/scummvmsa/sources/start_scummvm.sh b/projects/ArchR/packages/emulators/standalone/scummvmsa/sources/start_scummvm.sh new file mode 100644 index 0000000000..1a24beced8 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/scummvmsa/sources/start_scummvm.sh @@ -0,0 +1,73 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2019-present Shanti Gilbert (https://github.com/shantigilbert) + +# Source predefined functions and variables +. /etc/profile + +CONFIG_DIR="/storage/.config/scummvm" +ROMSPATH="/storage/roms" +BIOSPATH="${ROMSPATH}/bios" +RATMPCONF="/storage/.config/retroarch/retroarch.cfg" + +shopt -s extglob +if [[ "$1" =~ ?(add|create|libretro) ]] +then + GAME="$2" +else + GAME="$1" +fi + +if [ ! -d "${CONFIG_DIR}/games" ] +then + mkdir -p "${CONFIG_DIR}/games" +fi + +create_svm(){ + /usr/bin/scummvm --list-targets | tail -n +3 | cut -d " " -f 1 | \ + while read line + do + id=($line); + filename=$(sed -n "/^\[$id\]/,/^\[/{s/^description=//p}" ${CONFIG_DIR}/scummvm.ini | \ + sed -e 's# (.*)# ('${id}')#g' -e "s#'##g" -e "s#: # - #g" \ + ) + + SVMPATH="$(sed -n "/^\[$id\]/,/^\[/{s/^path=//p}" ${CONFIG_DIR}/scummvm.ini)" + echo '--path="'${SVMPATH}'" '${id} >"${CONFIG_DIR}/games/${filename}.scummvm" + done +} + +if [ ! -d "${CONFIG_DIR}" ]; then + mkdir -p ${CONFIG_DIR} + cp -rf /usr/config/scummvm/* ${CONFIG_DIR}/ +fi + +case $1 in + "libretro") + GAME=$(cat "${GAME}" | awk 'BEGIN {FS="\""}; {print $2}') + cd "${GAME}" + /usr/bin/retroarch -L /tmp/cores/scummvm_libretro.so --config ${RATMPCONF} . + ;; + + "add") + if [ ! -d "${ROMSPATH}/scummvm" ]; then + mkdir "${ROMSPATH}/scummvm" + fi + /usr/bin/scummvm --add --path="${ROMSPATH}/scummvm" --recursive + mkdir -p ${BIOSPATH} + cp ${CONFIG_DIR}/scummvm.ini ${BIOSPATH}/scummvm.ini + ;; + + "create") + create_svm + ;; + + *) + set_kill set "-9 scummvm" + GAME=$(cat "${GAME}") + systemctl start fluidsynth + eval /usr/bin/scummvm --fullscreen --joystick=0 --themepath=/usr/config/scummvm/themes "${GAME}" + systemctl stop fluidsynth + ;; +esac diff --git a/projects/ArchR/packages/emulators/standalone/touchhle-sa/package.mk b/projects/ArchR/packages/emulators/standalone/touchhle-sa/package.mk new file mode 100644 index 0000000000..287497a950 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/touchhle-sa/package.mk @@ -0,0 +1,35 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2026-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="touchhle-sa" +PKG_LICENSE="MPLv2" +PKG_VERSION="d7668926268eded91545fa8ffae6590871ecf5b1" +PKG_SITE="https://github.com/touchHLE/touchHLE" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain cargo:host cargo rust SDL2 sndio" +PKG_LONGDESC="touchHLE: high-level emulator for iPhone OS apps" +PKG_TOOLCHAIN="manual" + +make_target() { + unset CMAKE + export RUSTFLAGS="-C link-arg=-lasound" + + cargo build \ + --target ${TARGET_NAME} \ + --release +} + + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp -rf ${PKG_BUILD}/.${TARGET_NAME}/target/${TARGET_NAME}/release/touchHLE ${INSTALL}/usr/bin + cp -rf ${PKG_DIR}/scripts/* ${INSTALL}/usr/bin + mkdir -p ${INSTALL}/usr/lib/touchHLE/touchHLE_dylibs + cp -rf ${PKG_BUILD}/touchHLE_dylibs/lib* ${INSTALL}/usr/lib/touchHLE/touchHLE_dylibs/ + mkdir -p ${INSTALL}/usr/lib/touchHLE/touchHLE_fonts + cp -rf ${PKG_BUILD}/touchHLE_fonts/LiberationSans-* ${INSTALL}/usr/lib/touchHLE/touchHLE_fonts + cp -rf ${PKG_BUILD}/touchHLE_default_options.txt ${INSTALL}/usr/lib/touchHLE/ + mkdir -p ${INSTALL}/usr/config/touchHLE + cp -rf ${PKG_BUILD}/touchHLE_options.txt ${INSTALL}/usr/config/touchHLE/ + chmod +x ${INSTALL}/usr/bin/* +} diff --git a/projects/ArchR/packages/emulators/standalone/touchhle-sa/patches/000-set-paths.patch b/projects/ArchR/packages/emulators/standalone/touchhle-sa/patches/000-set-paths.patch new file mode 100644 index 0000000000..aaac71e595 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/touchhle-sa/patches/000-set-paths.patch @@ -0,0 +1,59 @@ +diff --git a/src/paths.rs b/src/paths.rs +index d0ab20b8..ac14b0de 100644 +--- a/src/paths.rs ++++ b/src/paths.rs +@@ -70,9 +70,15 @@ impl ResourceFile { + // On other OSes, resources are accessed as ordinary files. + #[cfg(not(target_os = "android"))] + file: { +- let base_path = get_macos_bundled_resources_path(); +- // When not in a bundle, look in the current directory. +- let path = base_path.as_deref().unwrap_or(Path::new(".")).join(path); ++ #[cfg(target_os = "linux")] ++ let base_path = Path::new(LINUX_RESOURCE_BASE); ++ ++ #[cfg(not(target_os = "linux"))] ++ let base_path = get_macos_bundled_resources_path() ++ .as_deref() ++ .unwrap_or(Path::new(".")); ++ ++ let path = base_path.join(path); + std::fs::File::open(path).map_err(|e| e.to_string())? + }, + }) +@@ -110,6 +116,12 @@ pub const WALLPAPER_FILES: &[&str] = &[ + /// the `Documents` directory. + pub const SANDBOX_DIR: &str = "touchHLE_sandbox"; + ++#[cfg(target_os = "linux")] ++const LINUX_RESOURCE_BASE: &str = "/usr/lib/touchHLE"; ++ ++#[cfg(target_os = "linux")] ++const LINUX_USER_BASE: &str = "/storage/.config/touchHLE"; ++ + /// Get a platform-specific base path needed for accessing touchHLE's + /// user-modifiable files. This is empty on platforms other than Android. + pub fn user_data_base_path() -> Cow<'static, Path> { +@@ -136,6 +148,11 @@ pub fn user_data_base_path() -> Cow<'static, Path> { + } + #[cfg(not(target_os = "android"))] + { ++ #[cfg(target_os = "linux")] ++ { ++ return Cow::from(PathBuf::from(LINUX_USER_BASE)); ++ } ++ + // When touchHLE is run from a .app bundle on macOS, the user might not + // be able to control the current directory, so user data needs to go in + // a standard location. +@@ -190,6 +207,10 @@ pub fn prepopulate_user_data_dir() { + return; + } + ++ #[cfg(target_os = "linux")] ++ let apps_dir = PathBuf::from("/storage/roms/ios"); ++ ++ #[cfg(not(target_os = "linux"))] + let apps_dir = base_path.join(APPS_DIR); + if !apps_dir.is_dir() { + match std::fs::create_dir(&apps_dir) { diff --git a/projects/ArchR/packages/emulators/standalone/touchhle-sa/patches/001-fix-app-picker.patch b/projects/ArchR/packages/emulators/standalone/touchhle-sa/patches/001-fix-app-picker.patch new file mode 100644 index 0000000000..3c968d7694 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/touchhle-sa/patches/001-fix-app-picker.patch @@ -0,0 +1,20 @@ +diff --git a/src/app_picker.rs b/src/app_picker.rs +index 0b6fd38b..9ff58508 100644 +--- a/src/app_picker.rs ++++ b/src/app_picker.rs +@@ -495,7 +495,6 @@ fn show_app_picker_gui( + app_frame.size, + buttons_row_center, + &[ +- ("File manager", "openFileManager"), + ("Quick options", "quickOptionsShow"), + ], + None, +@@ -508,7 +507,6 @@ fn show_app_picker_gui( + buttons_row2_center, + &[ + ("Copyright info", "copyrightInfoShow"), +- ("touchHLE.org", "visitWebsite"), + ], + None, + ); diff --git a/projects/ArchR/packages/emulators/standalone/touchhle-sa/scripts/start_touchhle.sh b/projects/ArchR/packages/emulators/standalone/touchhle-sa/scripts/start_touchhle.sh new file mode 100644 index 0000000000..76f83f6f33 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/touchhle-sa/scripts/start_touchhle.sh @@ -0,0 +1,77 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2026-present ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile +set_kill set "-9 touchHLE" + +# Conf files vars +SOURCE_DIR="/usr/config/touchHLE" +CONF_DIR="/storage/.config/touchHLE" +TOUCHHLE_CONF="touchHLE_options.txt" + +# Check if touchHLE exists in /storage/.config +if [ ! -d "${CONF_DIR}" ]; then + cp -r "${SOURCE_DIR}" "/storage/.config/" +fi + +# Check if touchHLE_options.txt exists in .config/touchHLE +if [ ! -f "${CONF_DIR}/${TOUCHHLE_CONF}" ]; then + cp -r "${SOURCE_DIR}/${TOUCHHLE_CONF}" "${CONF_DIR}" +fi + +# Check if touchHLE_wallpaper.* exists in .config/touchHLE +if ! compgen -G "${CONF_DIR}/touchHLE_wallpaper.*" > /dev/null; then +printf \ +'\x89PNG\r\n\x1a\n'\ +'\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x02\x00\x00\x00\x90wS\xde'\ +'\x00\x00\x00\x0cIDAT\x08\xd7c\x60\x60\x60\x00\x00\x00\x04\x00\x01\xf6\x17\x38\x55'\ +'\x00\x00\x00\x00IEND\xaeB`\x82' \ +> "${CONF_DIR}/touchHLE_wallpaper.png" +fi + +# Link roms/ios to touchHLE_apps +ln -snf "/storage/roms/ios" "${CONF_DIR}/touchHLE_apps" + +#Emulation Station Features +GAME=$(echo "${1}"| sed "s#^/.*/##") +PLATFORM=$(echo "${2}"| sed "s#^/.*/##") +DEVICE=$(get_setting device_type "${PLATFORM}" "${GAME}") +UPSCALE=$(get_setting upscale "${PLATFORM}" "${GAME}") + +# Set device type +if [ "${DEVICE}" != "ipad" ]; then + DEVICE="iphone" +fi + +# Set upscaling +if [[ "${UPSCALE}" =~ ^[1-4]$ ]]; then + UPSCALE="${UPSCALE}" +else + UPSCALE=1 +fi + +#Set the cores to use +CORES=$(get_setting "cores" "${PLATFORM}" "${GAME}") +if [ "${CORES}" = "little" ] +then + EMUPERF="${SLOW_CORES}" +elif [ "${CORES}" = "big" ] +then + EMUPERF="${FAST_CORES}" +else + ### All.. + unset EMUPERF +fi + +# Debugging info: + echo "GAME set to: ${GAME}" + echo "PLATFORM set to: ${PLATFORM}" + echo "CONF DIR: ${CONF_DIR}/${GOPHER64_JSON}" + echo "CPU CORES set to: ${EMUPERF}" + echo "DEVICE TYPE set to: ${DEVICE}" + echo "Launching /usr/bin/touchHLE --fullscreen=${DEVICE} ${1}" + +# Start touchHLE +${EMUPERF} /usr/bin/touchHLE --fullscreen --scale-hack=${UPSCALE} --device-family=${DEVICE} "${1}" diff --git a/projects/ArchR/packages/emulators/standalone/vice-sa/configs/sdl-vicerc b/projects/ArchR/packages/emulators/standalone/vice-sa/configs/sdl-vicerc new file mode 100644 index 0000000000..06a4a71ffa --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/vice-sa/configs/sdl-vicerc @@ -0,0 +1,26 @@ +[Version] +ConfigVersion=3.7.1 + +[C128] +KeySetEnable=0 +JoyDevice1=4 +JoyDevice2=4 +JoyMenuControl=1 + +[C64SC] +KeySetEnable=0 +JoyDevice1=4 +JoyDevice2=4 +JoyMenuControl=1 + +[PLUS4] +KeySetEnable=0 +JoyDevice1=4 +JoyDevice2=4 +JoyMenuControl=1 + +[VIC-20] +KeySetEnable=0 +JoyDevice1=4 +JoyDevice2=4 +JoyMenuControl=1 diff --git a/projects/ArchR/packages/emulators/standalone/vice-sa/package.mk b/projects/ArchR/packages/emulators/standalone/vice-sa/package.mk new file mode 100644 index 0000000000..f466edfca1 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/vice-sa/package.mk @@ -0,0 +1,39 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="vice-sa" +PKG_VERSION="3.8" +PKG_LICENSE="GPLv2" +PKG_SITE="https://sourceforge.net/projects/vice-emu" +PKG_URL="${PKG_SITE}/files/releases/vice-${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain xa:host SDL2 SDL2_image ncurses readline busybox:host" +PKG_LONGDESC="Commodore 8-bit Emulator" +PKG_CONFIGURE_OPTS_TARGET+=" --disable-pdf-docs --enable-gtk3ui=no --without-alsa --with-pulse --enable-sdl2ui" + +if [ ! "${OPENGL}" = "no" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" +fi + +if [ "${OPENGLES_SUPPORT}" = yes ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" +fi + +pre_configure_target() { + export LDFLAGS="${LDFLAGS} -lreadline -lncursesw -ltinfow" + export CFLAGS="${CFLAGS} -fcommon" +} + +post_makeinstall_target() { + mkdir -p ${INSTALL}/usr/config/vice + if [ -d "${PKG_DIR}/configs" ] + then + cp -f ${PKG_DIR}/configs/* ${INSTALL}/usr/config/vice + fi + + for sc in x128 x64sc xplus4 xvic + do + cp -f ${PKG_DIR}/sources/start_vice.sh ${INSTALL}/usr/bin/start_${sc}.sh + sed -i "s~@EMU@~${sc}~g" ${INSTALL}/usr/bin/start_${sc}.sh + done + chmod 0755 ${INSTALL}/usr/bin/* +} diff --git a/projects/ArchR/packages/emulators/standalone/vice-sa/sources/start_vice.sh b/projects/ArchR/packages/emulators/standalone/vice-sa/sources/start_vice.sh new file mode 100644 index 0000000000..3396f76ec9 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/vice-sa/sources/start_vice.sh @@ -0,0 +1,85 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +set_kill set "-9 @EMU@" + +CONFIG_PATH="/storage/.config/vice" +SOURCE_PATH="/usr/config/vice" + +EMU="@EMU@" + +### Get the game we want to start. +GAME=${1//[\\]/} + +if [ ! -d "/storage/.config/vice" ] +then + mkdir -p /storage/.config/vice +fi + +case ${EMU} in + x128) + EMU="C128" + ;; + x64sc) + EMU="C64SC" + ;; + xplus4) + EMU="PLUS4" + ;; + xvic) + EMU="VIC20" + ;; +esac + +if [ ! -e "${CONFIG_PATH}/sdl-hotkeys-${EMU}.vhk" ] +then + cat <${CONFIG_PATH}/sdl-hotkeys-${EMU}.vhk +!CLEAR +EOF +fi + +if [ ! -e "${CONFIG_PATH}/sdl-joymap-${EMU}.vjm" ] +then + cat <${CONFIG_PATH}/sdl-joymap-${EMU}.vjm +!CLEAR + +0 0 0 0 +0 0 1 0 +0 0 2 0 +0 0 3 0 +0 0 4 0 +0 0 5 0 +0 0 6 0 +0 0 7 0 + +0 1 0 1 0 16 +0 1 1 1 0 32 +0 1 2 1 0 64 +0 1 3 0 +0 1 4 0 +0 1 ${DEVICE_BTN_SELECT} 5 Virtual keyboard +0 1 ${DEVICE_BTN_START} 4 +EOF + + if [[ ! "${DEVICE_BTN_DPAD_UP}" =~ [a-z] ]] + then + cat <>${CONFIG_PATH}/sdl-joymap-${EMU}.vjm +0 1 ${DEVICE_BTN_DPAD_UP} 1 0 1 +0 1 ${DEVICE_BTN_DPAD_DOWN} 1 0 2 +0 1 ${DEVICE_BTN_DPAD_LEFT} 1 0 4 +0 1 ${DEVICE_BTN_DPAD_RIGHT} 1 0 8 +EOF + else + cat <>${CONFIG_PATH}/sdl-joymap-${EMU}.vjm +0 2 0 1 0 1 +0 2 1 1 0 2 +0 2 2 1 0 4 +0 2 3 1 0 8 +EOF + fi +fi + +@EMU@ -joymenucontrol "${GAME}" diff --git a/projects/ArchR/packages/emulators/standalone/vita3k-sa/package.mk b/projects/ArchR/packages/emulators/standalone/vita3k-sa/package.mk new file mode 100644 index 0000000000..3a1fdc02df --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/vita3k-sa/package.mk @@ -0,0 +1,66 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="vita3k-sa" +PKG_VERSION="f02851437d8bce2ebf54cd6d4922cd4b0faba654" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/Vita3K/Vita3K" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain SDL2 SDL2_image zlib libogg libvorbis gtk3 openssl ffmpeg" +PKG_LONGDESC="vita3k" +PKG_TOOLCHAIN="cmake" +PKG_PATCH_DIRS+="${DEVICE}" + +if [ ! "${OPENGL}" = "no" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" +fi + +if [ "${OPENGLES_SUPPORT}" = yes ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" +fi + +if [ "${VULKAN_SUPPORT}" = "yes" ] +then + PKG_DEPENDS_TARGET+=" ${VULKAN}" +fi + + pre_configure_target() { + mkdir -p ${PKG_BUILD}/external + [ -d "nativefiledialog-cmake" ] && rm -rf nativefiledialog-cmake + cd ${PKG_BUILD}/external && git clone https://github.com/Vita3K/nativefiledialog-cmake + [ -d "ffmpeg" ] && rm -rf ffmpeg + cd ${PKG_BUILD}/external && git clone https://github.com/Vita3K/ffmpeg-core.git ffmpeg + + case ${TARGET_ARCH} in + aarch64) + CMAKE_EXTRA_OPTS="-DXXHASH_BUILD_XXHSUM=ON \ + -DXXH_X86DISPATCH_ALLOW_AVX=OFF" + ;; + *) + CMAKE_EXTRA_OPTS="-DXXH_X86DISPATCH_ALLOW_AVX=ON" + ;; + esac + + PKG_CMAKE_OPTS_TARGET+=" -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_SHARED_LIBS=OFF \ + -DUSE_DISCORD_RICH_PRESENCE=OFF \ + -DUSE_VITA3K_UPDATE=OFF \ + ${CMAKE_EXTRA_OPTS}" +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + mkdir -p ${INSTALL}/usr/config/vita3k + cp -rf ${PKG_BUILD}/external/bin/Vita3K ${INSTALL}/usr/bin/ + cp -rf ${PKG_BUILD}/external/bin/* ${INSTALL}/usr/config/vita3k/ + rm -rf ${INSTALL}/usr/config/vita3k/Vita3K + cp ${PKG_DIR}/scripts/* ${INSTALL}/usr/bin + chmod 0755 ${INSTALL}/usr/bin/* + + mkdir -p ${INSTALL}/usr/config/vita3k/launcher + cp ${PKG_DIR}/scripts/start_vita3k.sh ${INSTALL}/usr/config/vita3k/launcher/_Start\ Vita3K.sh + cp ${PKG_DIR}/scripts/scan_vita3k.sh ${INSTALL}/usr/config/vita3k/launcher/_Scan\ Vita\ Games.sh + chmod 0755 ${INSTALL}/usr/config/vita3k/launcher/*sh + + cp ${PKG_DIR}/sources/vita-gamelist.txt ${INSTALL}/usr/config/vita3k +} diff --git a/projects/ArchR/packages/emulators/standalone/vita3k-sa/patches/001-base-path.patch b/projects/ArchR/packages/emulators/standalone/vita3k-sa/patches/001-base-path.patch new file mode 100644 index 0000000000..003bb01ea0 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/vita3k-sa/patches/001-base-path.patch @@ -0,0 +1,26 @@ +diff --git a/vita3k/app/src/app_init.cpp b/vita3k/app/src/app_init.cpp +index 8536b401..459e21f5 100644 +--- a/vita3k/app/src/app_init.cpp ++++ b/vita3k/app/src/app_init.cpp +@@ -103,9 +103,7 @@ void update_viewport(EmuEnvState &state) { + } + + void init_paths(Root &root_paths) { +- auto sdl_base_path = SDL_GetBasePath(); +- auto base_path = fs_utils::utf8_to_path(sdl_base_path); +- SDL_free(sdl_base_path); ++ auto base_path = fs_utils::utf8_to_path("/storage/.config/vita3k/"); + + root_paths.set_base_path(base_path); + root_paths.set_static_assets_path(base_path); +@@ -129,9 +127,7 @@ void init_paths(Root &root_paths) { + } else { + // SDL_GetPrefPath is deferred as it creates the directory. + // When using a portable directory, it is not needed. +- auto sdl_pref_path = SDL_GetPrefPath(org_name, app_name); +- auto pref_path = fs_utils::utf8_to_path(sdl_pref_path); +- SDL_free(sdl_pref_path); ++ auto pref_path = fs_utils::utf8_to_path("/storage/psvita/vita3k/"); + + #if defined(__APPLE__) + // Store other data in the user-wide path. Otherwise we may end up dumping diff --git a/projects/ArchR/packages/emulators/standalone/vita3k-sa/patches/004-fix-link-error.patch b/projects/ArchR/packages/emulators/standalone/vita3k-sa/patches/004-fix-link-error.patch new file mode 100644 index 0000000000..be1ff84d8c --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/vita3k-sa/patches/004-fix-link-error.patch @@ -0,0 +1,15 @@ +diff --git a/vita3k/CMakeLists.txt b/vita3k/CMakeLists.txt +index 04177f04..4adb1e0b 100644 +--- a/vita3k/CMakeLists.txt ++++ b/vita3k/CMakeLists.txt +@@ -136,10 +136,6 @@ if(USE_DISCORD_RICH_PRESENCE) + target_link_libraries(vita3k PRIVATE discord-rpc) + endif() + +-if(LINUX) +- target_link_libraries(vita3k PRIVATE -static-libgcc -static-libstdc++) +-endif() +- + set_target_properties(vita3k PROPERTIES OUTPUT_NAME Vita3K + ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" diff --git a/projects/ArchR/packages/emulators/standalone/vita3k-sa/patches/aarch64/005-no-XXHASH-dispatch.patch b/projects/ArchR/packages/emulators/standalone/vita3k-sa/patches/aarch64/005-no-XXHASH-dispatch.patch new file mode 100644 index 0000000000..6699f92367 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/vita3k-sa/patches/aarch64/005-no-XXHASH-dispatch.patch @@ -0,0 +1,17 @@ +diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt +index 72b4010b..9509832a 100644 +--- a/external/CMakeLists.txt ++++ b/external/CMakeLists.txt +@@ -331,9 +331,9 @@ target_include_directories(libatrac9 PUBLIC LibAtrac9/C/src) + option(BUILD_SHARED_LIBS "Build shared library" OFF) + option(XXHASH_BUILD_XXHSUM "Build the xxhsum binary" OFF) + option(XXH_X86DISPATCH_ALLOW_AVX "Allow building XXH3 with AVX even if it crashes on SSE2-Only CPUs" OFF) +-if(NOT APPLE) +- set(DISPATCH 1) +-endif() ++#if(NOT APPLE) ++# set(DISPATCH 1) ++#endif() + add_subdirectory(xxHash/cmake_unofficial EXCLUDE_FROM_ALL) + if(XXH_X86DISPATCH_ALLOW_AVX) + target_compile_definitions(xxhash PRIVATE XXH_X86DISPATCH_ALLOW_AVX) diff --git a/projects/ArchR/packages/emulators/standalone/vita3k-sa/scripts/scan_vita3k.sh b/projects/ArchR/packages/emulators/standalone/vita3k-sa/scripts/scan_vita3k.sh new file mode 100755 index 0000000000..2ce1036c7f --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/vita3k-sa/scripts/scan_vita3k.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +GAME_PATH="/storage/psvita/vita3k/ux0/app" +GAME_DATA="/storage/.config/vita3k/vita-gamelist.txt" +OUTPUT_PATH="/storage/.config/vita3k/launcher" + +cd ${GAME_PATH} +for GAME in PC* +do + FILENAME=$(grep ${GAME} ${GAME_DATA} | sed 's~'${GAME}'\t~~g') + if [ ! -e "${OUTPUT_PATH}/${FILENAME}.psvita" ] && \ + [ -n "${FILENAME}" ] + then + echo ${GAME} > ${OUTPUT_PATH}/"${FILENAME}.psvita" + fi +done diff --git a/projects/ArchR/packages/emulators/standalone/vita3k-sa/scripts/start_vita3k.sh b/projects/ArchR/packages/emulators/standalone/vita3k-sa/scripts/start_vita3k.sh new file mode 100755 index 0000000000..9781c1e097 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/vita3k-sa/scripts/start_vita3k.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile +set_kill set "-9 Vita3K" + +OUTPUT_PATH="/storage/.config/vita3k/launcher" +GAME="${1}" + +#Check if vita3k folder exists in /storage/.config/vita3k +if [ ! -d "/storage/.config/vita3k" ]; then + mkdir -p "/storage/.config/vita3k" +fi + +#Make sure we sync any changes from /storage/.config so new features will be enabled +#without overwriting existing settings. +rsync -ah --update /usr/config/vita3k/* /storage/.config/vita3k 2>/dev/null + +#Check if vita3k folder exists in /storage/roms/psvita +if [ ! -d "/storage/roms/psvita/vita3k" ]; then + mkdir -p "/storage/roms/psvita/vita3k" +fi + +if [ -n "${GAME}" ]; then + OPTIONS="-r $(cat "${GAME}")" +fi + +#Start Vita3K +/usr/bin/Vita3K ${OPTIONS} diff --git a/projects/ArchR/packages/emulators/standalone/vita3k-sa/sources/vita-gamelist.txt b/projects/ArchR/packages/emulators/standalone/vita3k-sa/sources/vita-gamelist.txt new file mode 100644 index 0000000000..4eb1d5bcb5 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/vita3k-sa/sources/vita-gamelist.txt @@ -0,0 +1,2055 @@ +PCSE00965 #KILLALLZOMBIES +PCSG00891 √Letter +PCSE00963 √Letter +PCSB01019 √Letter +PCSE00890 10 Second Ninja X +PCSB00963 10 Second Ninja X +PCSE00349 1001 Spikes +PCSE00634 2013: Infected Wars +PCSE00972 2064: Read Only Memories +PCSE01169 36 Fragments of Midnight +PCSG00590 5-nin no Koi Prince: Himitsu no Keiyaku Kekkon +PCSE01168 7'scarlet +PCSH10090 7'scarlet +PCSG00876 7'scarlet +PCSE00914 99Vidas +PCSE01167 99vidas - Demo +PCSE00726 A Boy and His Blob +PCSH10075 A Certain Magical Virtual-On +PCSG00505 A Good Librarian Like a Good Shepherd -Library Party- +PCSE01095 A Hole New World +PCSB01095 A Rose in the Twilight +PCSE01046 A Rose in the Twilight +PCSB00955 A Virus Named TOM +PCSE00501 A Virus Named TOM +PCSE01389 A Winter's Daydream +PCSE00232 A-men +PCSB00056 A-men +PCSE00324 A-men 2 +PCSB00222 A-men 2 +PCSB00154 A-men Demo +PCSB00898 A.O.T. Wings of Freedom +PCSB00960 A.W. : Phoenix Festa +PCSE00871 A.W. : Phoenix Festa +PCSE00278 Aabs Animals +PCSG00591 Abunai Koi no Sousashitsu: Eternal Happiness +PCSB00792 AC® Chronicles +PCSE00700 AC® Chronicles +PCSB01101 Accel World vs. Sword Art Online +PCSE01071 Accel World vs. Sword Art Online +PCSG01016 Accel World vs. Sword Art Online +PCSE01356 Access Denied +PCSE01448 Active Neurons +PCSB01008 Active Soccer 2 DX +PCSB00858 Actual Sunlight +PCSE00695 Actual Sunlight +PCSE00582 Adventure Time: the Secret of the Nameless Kingdom +PCSE00905 Adventures of Mana +PCSB00975 Adventures of Mana +PCSG90182 Aegis of Earth Demo +PCSE00844 Aegis of Earth: Protonovus Assault +PCSG00362 Aegis of Earth: Protonovus Assault +PCSG01296 Aerial Life +PCSE00628 AeternoBlade +PCSG00483 AeternoBlade +PCSB00732 AeternoBlade Demo +PCSE00636 AeternoBlade Demo +PCSB00412 Age of Zombies +PCSE00362 Age of Zombies +PCSG01325 Ai Kiss +PCSG00940 AIR +PCSE00980 Air Race Speed +PCSG00461 Airship Q +PCSG00338 Aiyoku no Eustia: Angel’s Blessing +PCSG00780 Akai Suna Ochiru Tsuki +PCSE00927 Akiba's Beat +PCSB01066 AKIBA'S BEAT +PCSG00159 AKIBA'S TRIP 2 +PCSH00057 AKIBA'S TRIP 2 +PCSE00428 AKIBA'S TRIP UNDEAD & UNDRESSED +PCSG90191 ALIA's CARNIVAL! Sacramento Trial +PCSE00210 Alien Breed +PCSE00445 Alien Shooter +PCSB00964 Alone With You +PCSE00887 Alone With You +PCSB01457 Alphaset by POWGI +PCSH10271 Alphaset by POWGI +PCSE01493 Alphaset by POWGI +PCSB01187 Alteric +PCSG01243 Alvastia Chronicles +PCSG01086 Amaekata wa Kanojo Nari ni. +PCSG01293 Amamane +PCSG00638 Amatsumi Sora ni! Kumo no Hatate ni +PCSG01138 Amenity's Life +PCSG90299 Amenity's Life -アメニティーズ ライフ- 体験版 +PCSG00403 AMNESIA LATER×CROWD V Edition +PCSB00740 Amnesia Memories +PCSG00203 AMNESIA V Edition +PCSG00276 AMNESIA World +PCSE00647 Amnesia: Memories +PCSG00696 Angelique Retour +PCSE00322 Angry Birds Trilogy +PCSB00397 Angry Birds™ Star Wars +PCSE00294 Angry Birds™ Star Wars +PCSG00342 Anoko wa Ore Kara Hanarenai +PCSE00472 Another World - 20th Anniversary Edition +PCSE01147 Antiquia Lost +PCSG00700 Ao no Kanata Four Rhythm +PCSG90180 Ao no Kanata no Four Rhythm Trial Version +PCSG01281 Aoki Tsubasa no Chevalier +PCSG01283 Aonatsu Line +PCSG00848 Aqua Kitty - Milk Mine Defender DX +PCSB00798 Ar nosurge Plus: Ode to an Unborn Star +PCSE00707 AR Nosurge Plus: Ode to an Unborn Star +PCSG00751 Arcana Famiglia -La storia della Arcana Famiglia- Ancora +PCSE00427 Arcana Heart 3 LOVE MAX!!!!! +PCSG00328 Arcana Heart 3: LOVE MAX!!!!! +PCSB00050 Army Corps of Hell +PCSE00006 ARMY CORPS OF HELL +PCSE01379 Asdivine Dios +PCSE00968 Asdivine Hearts +PCSE01335 Asdivine Hearts II +PCSE01419 Asdivine Menace +PCSE00007 Asphalt: Injection +PCSG00116 Assassin's Creed® III Lady Liberty +PCSB00074 Assassin's Creed® III Liberation +PCSE00053 Assassin's Creed® III Liberation +PCSG90030 Assault Army +PCSG90032 Assault Gunners Trial Version +PCSG00901 AstralAir no Shiroki Towa: White Eternity +PCSG90248 AstralAir no Shiroki Towa: White Eternity Trial Version +PCSE01333 Atari Flashback Classics +PCSE00584 Atelier Ayesha Plus ~The Alchemist of Dusk~ +PCSB00700 Atelier Ayesha Plus ~The Alchemist of Dusk~ +PCSG00347 Atelier Ayesha Plus: The Alchemist of Dusk +PCSB00906 Atelier Escha & Logy Plus ~Alchemists of the Dusk Sky~ +PCSG00522 Atelier Escha & Logy Plus: Alchemists of the Dusk Sky +PCSE00826 Atelier Escha & Logy Plus: Alchemists of the Dusk Sky +PCSB01087 Atelier Firis ~The Alchemist and the Mysterious Journey~ +PCSE01044 Atelier Firis ~The Alchemist and the Mysterious Journey~ +PCSH10026 Atelier Firis ~The Alchemist and the Mysterious Journey~ +PCSG00929 Atelier Firis: The Alchemist of the Mysterious Journey +PCSG01116 Atelier Lydie & Suelle: The Alchemists and the Mysterious Paintings +PCSE00296 Atelier Meruru Plus: The Apprentice of Arland +PCSB00377 Atelier Meruru Plus: The Apprentice of Arland +PCSG00171 Atelier Meruru Plus: The Apprentice of Arland +PCSG01223 Atelier Nelke: The Alchemists and the New Earth +PCSE00466 Atelier Rorona Plus ~The Alchemist of Arland~ +PCSB00582 Atelier Rorona Plus ~The Alchemist of Arland~ +PCSG00245 Atelier Rorona Plus: The Alchemist of Arland +PCSE00998 Atelier Shallie Plus - Alchemists of the Dusk Sea +PCSG00821 Atelier Shallie Plus ~Alchemists of the Dusk Sea~ +PCSB01043 Atelier Shallie Plus ~Alchemists of the Dusk Sea~ +PCSE00892 Atelier Sophie ~The Alchemist of the Mysterious Book~ +PCSB00973 Atelier Sophie ~The Alchemist of the Mysterious Book~ +PCSG00694 Atelier Sophie: The Alchemist of the Mysterious Book +PCSH00220 Atelier Sophie: The Alchemist of the Mysterious Book +PCSH00231 Atelier Sophie: The Alchemist of the Mysterious Book +PCSE00231 Atelier Totori Plus: The Adventurer of Arland +PCSG00127 Atelier Totori Plus: The Adventurer of Arland +PCSB00291 Atelier Totori Plus: The Adventurer of Arland +PCSB00274 Atomic Ninjas +PCSE00274 Atomic Ninjas +PCSG00762 Attack on Titan +PCSE00812 Attack on Titan +PCSG01102 Attack on Titan 2 +PCSE00780 Attractio +PCSE01367 Awesome Pea +PCSE01474 Awesome Pea 2 +PCSB00779 Axiom Verge +PCSG00666 Ayakashi Gohan: Oomori! +PCSG01175 Azayaka na Irodori no Naka de, Kimi Rashiku +PCSE00861 Azkend 2: The World Beneath +PCSG00711 Baboon! +PCSE01343 Back in 1995 +PCSE00706 Back to Bed +PCSB00468 Backgammon Blitz +PCSB01092 Bad Apple Wars +PCSE01042 Bad Apple Wars +PCSB00669 BADLAND: Game of the Year Edition +PCSG00425 Bakumatsu Rock: Ultra Soul +PCSB01406 Balthazar's Dream +PCSG01123 Banbutsu Otome * Dungeons +PCSG00708 Bara ni Kakusareshi Verite +PCSG01006 Bard's Gold +PCSB00911 Baseball Riot +PCSE00790 Bastion +PCSB00353 Batman: Arkham Origins Blackgate +PCSE00444 Battalion Commander +PCSE01478 Battle Rockets +PCSG00244 Beast Tamer and Prince +PCSG00604 Beast Tamer and Prince ~Flower & Snow~ +PCSG00539 Believer! +PCSE00024 Ben 10™ Galactic Racing +PCSG01221 Beniiro Tenjou Ayakashi Kitan Futaai +PCSF00251 Bentley's Hackpack™ +PCSB01085 BERSERK and the Band of the Hawk +PCSE00377 Best of Arcade Games +PCSB00648 Best Of Arcade Games (FULL) +PCSE01495 Big Dipper +PCSE00091 Big Sky Infinity +PCSF00351 BigFest™ +PCSG00389 Binary Star +PCSB01105 Bit Dungeon Plus +PCSE00302 BIT.TRIP Presents... Runner2: Future Legend of Rhythm Alien +PCSG90096 Bitter Smile Trial +PCSG00242 Bitter smile. +PCSG00468 black butterfly psychedelia +PCSG00935 BLACK WOLVES SAGA -Weiβ und Schwarz- +PCSB00420 Blast 'Em Bunnies +PCSG00180 BLAZBLUE CHRONOPHANTASMA +PCSG00582 BLAZBLUE CHRONOPHANTASMA EXTEND +PCSB00042 BlazBlue Continuum Shift Extend +PCSG00003 BLAZBLUE CONTINUUM SHIFT EXTEND +PCSE00279 BlazBlue: ChronoPhantasma +PCSE00677 BlazBlue: Chronophantasma Extend +PCSE00018 BlazBlue: Continuum Shift EXTEND +PCSE01457 Blind Men +PCSB01250 Bloodstained: Curse of the Moon +PCSE00663 Bloxiq +PCSG00987 BLUE REFLECTION(幻に舞う少女の剣) +PCSE00864 Blue-Collar Astronaut +PCSE01019 Bodycheck +PCSG01205 Boku to Nurse no Kenshuu Nisshi +PCSG00797 Boku wa Mori Sekai no Kami Tonaru +PCSB00741 Bombing Busters +PCSE01368 Bonds of the Skies +PCSG00259 BOOLINK +PCSF00570 Borderlands 2 +PCSE00383 Borderlands 2 +PCSE00604 Boss +PCSE01349 Bouncy Bullets +PCSE00641 Breach & Clear +PCSE00225 BreakQuest: Extra Evolution +PCSB00265 BreakQuest: Extra Evolution +PCSE01429 Breeder Homegrown +PCSE00869 Bridge Constructor +PCSE00657 Broken Age +PCSE01517 Brotherhood United +PCSG00755 BROTHERS CONFLICT Precious Baby +PCSE01455 Bucket Knight +PCSG00361 Bullet Girls +PCSG00568 Bullet Girls 2 +PCSH10099 Bullet Girls Phantasia +PCSB01110 Bunny Must Die! Chelsea and the 7 devils +PCSG90261 Bunny Must Die! Chelsea and the 7devils. Trial version +PCSH10053 BURIED STARS +PCSE01135 Burly Men At Sea +PCSE00117 Burn the Rope +PCSG01197 Cafe Cuillere +PCSB00213 Call of Duty: Black Ops: Declassified +PCSG00135 Call of Duty® Black Ops: Declassified +PCSE00097 Call of Duty® Black Ops: Declassified +PCSB00232 Call of Duty® Black Ops: Declassified +PCSG00450 Captain Earth: Mind Labyrinth +PCSE00946 Castle Invasion: Throne Out +PCSB00111 CastleStorm +PCSG01179 Catherine: Full Body +PCSG90323 Catherine: Full Body Trial Verison +PCSH00099 CatsBlock Vestival +PCSB00573 Cel Damage HD +PCSE00422 Cel Damage HD +PCSG00409 Chain Chronicle V +PCSG00497 Chaos Rings I +PCSG00498 Chaos Rings II +PCSG00500 Chaos Rings III +PCSG00457 Chaos Rings III Prequel Trilogy +PCSG00499 Chaos Rings Ω +PCSE01022 Chaos;Child +PCSG00555 Chaos;Child +PCSB01075 CHAOS;CHILD +PCSG90169 Chaos;Child Demo +PCSG00995 Chaos;Child: Love Chuchu!! +PCSG00411 Chaos;Head Dual +PCSG00435 Chaos;Head Love Chu*Chu! +PCSG00434 Chaos;Head Noah +PCSG01150 Charade Maniacs +PCSE01031 Chasm +PCSB01233 Chicken Range +PCSB00598 Child of Light +PCSE00480 Child of Light +PCSG00850 Chou Ezaru wa Akai Hana: Koi wa Tsuki ni Shirube Kareru +PCSG00644 Chou Jigen Taisen Neptune VS Sega Hard Girls: Yume no Gattai Special +PCSG00234 Chou Megami Shinkou Noire: Gekishin Black Heart +PCSG00274 Chou no Doku Hana no Kusari Taishou Tsuyakoi Ibun +PCSG01066 Chouchou Jiken Rhapsodic +PCSE00044 Chronovolt +PCSB00102 Chronovolt +PCSE01281 Chronus Arc +PCSG00540 ChuSingura46+1 -忠臣蔵46+1- V +PCSG00454 Ciel Nosurge: Ushinawareta Hoshi e Sasagu Uta +PCSG00705 Citizens of Earth +PCSB00686 Citizens of Earth Demo +PCSE00562 Citizens of Earth Demo +PCSG00729 ClaDun Returns: This is Sengoku! +PCSE00999 ClaDun Returns: This is Sengoku! +PCSE01017 Cladun Returns: This is Sengoku! Demo +PCSB01067 Cladun Returns: This is Sengoku! Demo +PCSG90212 Cladun Returns: This is Sengoku! Trial Version +PCSG00415 CLANNAD +PCSA00038 Cliff Diving +PCSG00469 Clock Zero ~Shuuen no Ichibyou~ ExTime +PCSG00716 Clover Day's ~Making for Happiness.~ +PCSB00303 Coconut Dodge Revitalised +PCSE00267 Coconut Dodge Revitalised +PCSB01099 Code: Realize ~Future Blessings~ +PCSE00763 Code: Realize ~Guardian of Rebirth~ +PCSG01110 Code: Realize ~Silver Miracle~ +PCSG00805 Code: Realize ~The Future of Blessings~ +PCSE01278 Code:Realize ~Wintertide Miracles~ +PCSE01011 Collar x Malice +PCSB01061 Collar×Malice +PCSB00768 Color Guardians +PCSE00612 Color Guardians +PCSE01423 Color Slayer +PCSE00123 Colors! +PCSE00376 CONCEPTION II: Children of the Seven Stars +PCSB00547 Conception II: Children of the Seven Stars Demo +PCSE00425 Conception II: Children of the Seven Stars Demo +PCSG90087 Conception II: Children of the Seven Stars Demo +PCSG90092 Conception II: Children of the Seven Stars Demo +PCSE01406 Conga Master Go +PCSB01445 Contraptions +PCSB00822 Corpse Party BLOOD DRIVE +PCSE00708 Corpse Party BLOOD DRIVE +PCSG00298 Corpse Party: Blood Drive +PCSB00840 Corridor Z +PCSE00854 Corridor Z +PCSE01232 CosmicStarHeroine +PCSB00734 Cosmophony +PCSA00116 Counterspy +PCSG01246 Coven and Labyrinth of Galleria +PCSE00222 CRACKLE +PCSG00941 Crank In +PCSG90290 Crank In Trial Version +PCSE00291 Crazy Market +PCSE00916 Criminal Girls 2 Party Favors +PCSB00984 Criminal Girls 2 Party Favors +PCSG00681 Criminal Girls 2: Party Favors +PCSE00516 Criminal Girls: Invite Only +PCSB00636 Criminal Girls: Invite Only +PCSE00453 Crimsonland +PCSG00537 Croixleur Sigma +PCSE00689 Croixleur Sigma +PCSG00597 Cross Ange: Rondo of Angels and Dragons tr. +PCSG00365 CROSS†CHANNEL ~For all people~ +PCSB01331 Crossovers by POWGI +PCSH10175 Crossovers by POWGI +PCSE01377 Crossovers by POWGI +PCSE00806 Crypt of the NecroDancer +PCSE01464 Crypto by POWGI +PCSB01432 Crypto by POWGI +PCSH10240 Crypto by POWGI +PCSG00169 Cure Mate Club +PCSE01152 Cursed Castilla (Maldita Castilla EX) +PCSB01160 Cursed Castilla (Maldita Castilla EX) +PCSB00853 Curses 'N Chaos +PCSG01122 D.S.-Dal Segno- +PCSE01348 Daggerhood +PCSG00264 Dai-3-Ji Super Robot Taisen Z Jigoku-hen +PCSG00494 Dai-3-Ji Super Robot Taisen Z Tengoku-hen +PCSG00372 Daisenryaku Exceed II +PCSG00779 Daisenryaku Perfect: Senjou no Hasha +PCSG00504 Daisenryaku: Dai Toua Kouboushi 3 +PCSG00842 Damascus Gear Saikyou Exodus +PCSE00518 Damascus Gear: Operation Tokyo +PCSG00292 Damascus Gear: Operation Tokyo +PCSG90109 Damascus Gear: Operation Tokyo +PCSG00077 Danball Senki W Release +PCSG00807 Dance with Devils +PCSG01152 Dance with Devils My Carol +PCSG00202 Danganronpa 1&2 Reload +PCSE00399 Danganronpa 2: Goodbye Despair +PCSB00514 Danganronpa 2: Goodbye Despair +PCSE00692 Danganronpa Another Episode: Ultra Despair Girls +PCSB00788 Danganronpa Another Episode: Ultra Despair Girls +PCSG00772 Danganronpa Another Episode: Ultra Despair Girls +PCSE01100 Danganronpa V3: Killing Harmony +PCSE01105 Danganronpa V3: Killing Harmony Demo +PCSH10052 Danganronpa V3: Killing Harmony Demo version +PCSB01130 Danganronpa V3: Killing Harmony Demo version +PCSE00261 Danganronpa: Trigger Happy Havoc +PCSB00346 Danganronpa: Trigger Happy Havoc +PCSG01002 Danjon ni Deai o Motomeru no wa Machigatteiru Darou ka? Infinite Combate +PCSG01017 Daredemo Shodan ni Nareru Igo Kyoushitsu +PCSE00792 DARIUSBURST Chronicle Saviours +PCSE00919 Darkest Dungeon +PCSG00599 Date-A-Live Twin Edition: Rio Reincarnation +PCSB00540 Day D Tower Rush +PCSB00747 Day of the Tentacle Remastered +PCSE01181 Dead Ahead: Zombie Warfare +PCSA00151 Dead Nation™ +PCSB00296 DEAD OR ALIVE 5 PLUS +PCSG00167 DEAD OR ALIVE 5 PLUS +PCSG00771 Dead Or Alive Xtreme 3 Venus +PCSH00250 DEAD OR ALIVE Xtreme 3 Venus +PCSH00281 DEAD OR ALIVE Xtreme 3 Venus Free-to-Play Version +PCSE00578 Deadman's Cross +PCSE01279 Death Mark +PCSE00248 Deathmatch Village +PCSE00401 Deception IV: Blood Ties +PCSB00499 Deception IV: Blood Ties +PCSE00743 Deception IV: The Nightmare Princess +PCSB00829 Deception IV: The Nightmare Princess +PCSG00685 DEEMO ~The Last Recital~ +PCSE01041 DEEMO The Last Recital +PCSE01219 Deep Ones +PCSB01359 Deep Space Rush +PCSB01223 Defender's Quest: Valley of the Forgotten DX +PCSE00889 Delta Strike : First Assault +PCSE01005 Demetrios - The BIG Cynical Adventure +PCSE00358 Demon Gaze +PCSG00043 DEMON GAZE +PCSG00849 DEMON GAZE 2 +PCSB01150 DEMON GAZE 2 +PCSB01437 Demon's Tier+ +PCSE00639 Dengeki Bunko Fighting Climax +PCSG00341 Dengeki Bunko: Fighting Climax +PCSB00763 Dengeki Bunko: Fighting Climax +PCSG00758 Dengeki Bunko: Fighting Climax Ignition +PCSE00542 Desert Ashes +PCSG00959 DESIRE remaster ver. +PCSF00352 Destiny of Spirits +PCSA00106 Destiny of Spirits™ +PCSE01249 Devious Dungeon +PCSB01342 Devious Dungeon 2 +PCSB00953 Dex +PCSG00272 Diabolik Lovers Limited V Edition +PCSG00530 Diabolik Lovers: Dark Fate +PCSG00910 Diabolik Lovers: Lost Eden +PCSG00826 Diabolik Lovers: Lunatic Parade +PCSG00476 Diabolik Lovers: More, Blood Limited V Edition +PCSG00472 Diabolik Lovers: Vandead Carnival +PCSB00389 Die! Die! Die! +PCSE00755 Digimon Story Cyber Sleuth +PCSG00516 Digimon Story: Cyber Sleuth +PCSH00261 Digimon World: Next Order +PCSG00792 Digimon World: Next Order +PCSE00820 Dino Dini's Kick Off +PCSB00895 Dino Dini's Kick Off +PCSE00022 Disgaea 3: Absence of Detention +PCSB00098 Disgaea 3: Absence of Detention +PCSG00005 Disgaea 3:Return(魔界戦記ディスガイア3 Return) +PCSE00360 Disgaea 4: A Promise Revisited +PCSF00309 Disney Epic Mickey : Disney Epic Mickey 2: The Power of Two +PCSF00308 Disney Epic Mickey 2: The Power of Two +PCSA00110 Disney's Epic Mickey 2: The Power of Two +PCSB01165 DISTRAINT: Deluxe Edition +PCSB00373 Divekick +PCSE00208 DJMax Technika Tune +PCSG90047 DJMax Technika Tune Demo +PCSH00025 DJMax Technika Tune Demo +PCSC80021 DMM.com +PCSE00103 Doctor Who: The Eternity Clock +PCSG00775 Dogimegi Inryoku-Chan: Love & Peace +PCSG90220 Dogimegi Inryoku-Chan: Love & Peace Trial Version +PCSA00117 Doki-Doki Universe™ +PCSE00124 Dokuro +PCSB00215 Dokuro +PCSB00639 Don't Die, Mr Robot +PCSE00450 Don't Starve: Giant Edition +PCSE00327 Doodle Devil +PCSE00133 Doodle God +PCSB00556 Doodle Kingdom +PCSG01100 Doukoku Soshite... Remastered +PCSB00952 Downwell +PCSE00873 Downwell +PCSE00305 Dragon Ball Z: Battle of Z +PCSB00424 Dragon Ball Z: Battle of Z Demo +PCSG90095 Dragon Ball Z: Battle of Z Demo +PCSE00330 Dragon Ball Z: Battle of Z Demo +PCSE00217 Dragon Fantasy Book 1 +PCSE00299 Dragon Fantasy Book 2 +PCSE00952 Dragon Fantasy: Black Tome of Ice +PCSE01086 Dragon Fantasy: Volumes of Westeria +PCSE00447 Dragon Fin Soup +PCSB00621 Dragon Fin Soup +PCSG00697 Dragon Quest Builders +PCSE00912 DRAGON QUEST BUILDERS +PCSE00934 Dragon Quest Builders Demo +PCSB00999 Dragon Quest Builders Demo +PCSG90213 Dragon Quest Builders Demo +PCSH00270 Dragon Quest Builders Demo +PCSH00298 Dragon Quest Heroes II +PCSG90245 Dragon Quest Heroes II Demo +PCSE01190 Dragon Sinker +PCSE00019 Dragon's Crown +PCSG00187 Dragon's Crown +PCSB00408 Dragon's Crown +PCSH00050 Dragon's Crown +PCSG00212 Dragon's Dogma Quest +PCSE01360 Dragonfly Chronicles +PCSE01193 Dragooned +PCSG00420 DRAMAtical Murder re:code +PCSE00224 Draw Slasher +PCSG00026 DREAM C CLUB ZERO PORTABLE +PCSE01365 Dreamwalker +PCSE00841 Dreii +PCSB01097 Drive Girls +PCSE01099 Drive Girls +PCSE01363 Drowning +PCSB01404 Duck Souls+ +PCSB00437 Duke Nukem 3D: Megaton Edition +PCSE00339 Duke Nukem 3D: Megaton Edition +PCSB01474 Dull Grey +PCSE00008 Dungeon Hunter: Alliance +PCSE00944 Dungeon Punks +PCSE00693 Dungeon Travelers 2 +PCSG00407 Dungeon Travelers 2 : The Royal Library & the Monster Seal +PCSE00718 Dungeon Travelers 2 Demo +PCSG90141 Dungeon Travelers 2 Demo +PCSG00841 Dungeon Travelers 2-2 +PCSG90278 Dungeon Travelers 2-2 Trial Version +PCSB00824 Dungeon Travelers 2: The Royal Library Demo +PCSG00482 Durarara!! Relay +PCSE00332 Dustforce +PCSB01051 DYING: Reborn +PCSE00984 Dying:Reborn +PCSG00860 DYNAMIC CHORD feat.[reve parfait] V edition +PCSG00915 DYNAMIC CHORD feat.apple-polisher V edition +PCSG00862 DYNAMIC CHORD feat.KYOHSO V edition +PCSG00861 DYNAMIC CHORD feat.Liar-S V edition +PCSG90136 Dynasty Warriors 8 Empires Edit Mode Trial Version +PCSE00405 Dynasty Warriors 8: Xtreme Legends Complete Edition +PCSH00058 Dynasty Warriors Gundam Reborn +PCSE00014 Dynasty Warriors Next +PCSG00002 Dynasty Warriors Next +PCSB00108 Dynasty Warriors Next Demo Version +PCSE00069 Dynasty Warriors Next Demo Version +PCSG90006 Dynasty Warriors Next Trial Version +PCSG90018 Dynasty Warriors Next Trial Version +PCSH00004 Dynasty Warriors Next Trial Version +PCSE00995 DYNASTY WARRIORS: Godseekers +PCSH10007 Dynasty Warriors: Godseekers Trial Version +PCSG90243 Dynasty Warriors: Godseekers Trial Version +PCSB00084 EA SPORTS FIFA Football Demo +PCSB00082 EA SPORTS FIFA Football Demo +PCSB00086 EA SPORTS FIFA Football Demo +PCSE00059 EA SPORTS FIFA Football Demo +PCSB00083 EA SPORTS FIFA Football Démo +PCSE00060 EA SPORTS FIFA Football Démo +PCSE00055 EA SPORTS FIFA Soccer Demo +PCSG00039 EA SPORTS™ FIFA Football +PCSG00432 Earth Defense Force 2: PORTABLE V2 +PCSB00884 Earth Defense Force 2: Invaders from Planet Space +PCSE00710 Earth Defense Force 2: Invaders from Planet Space +PCSE00209 Earth Defense Force 2017 Portable +PCSG00291 EbiKore+ Amagami (エビコレ+ アマガミ) +PCSA00087 Ecolibrium™ +PCSG00753 Eikoku Tantei Mysteria: The Crown +PCSG01026 Eiyuu Densetsu: Akatsuki no Kiseki +PCSG00042 Eiyuu Densetsu: Zero no Kiseki Evolution +PCSG00316 Eiyuu*Senki +PCSH00246 Element4l +PCSB01325 Emerald Shores +PCSB01443 EMMA: Lost In Memories +PCSG00963 end sleep +PCSG90254 End Sleep Trail Version +PCSB00945 Energy Balance +PCSE01124 Energy Cycle +PCSE01192 Energy Invasion +PCSG01167 Enkan no Memoria: Kakera Tomoshi +PCSA00140 Entwined™ +PCSG01134 Ephemeral FANTASY ON DARK +PCSB01431 Epic Word Search Collection +PCSB01458 Epic Word Search Collection 2 +PCSF00023 Escape Plan +PCSA00004 Escape Plan™ +PCSE00095 escapeVektor +PCSE00395 Ethan: Meteor Hunter +PCSG00817 EVE burst error R +PCSG01249 EVE rebirth terror +PCSG01139 Evening Bell of Piofiore +PCSC00001 Everybody's Golf +PCSE00941 Exile's End +PCSG00679 Exist Archive +PCSB00995 Exist Archive +PCSE00883 Exist Archive: The Other Side of the Sky +PCSB01419 Explosive Jake +PCSG00196 Exstetra +PCSB00027 F1 2011 +PCSE00002 F1 2011 +PCSA00042 Facebook +PCSE01051 Factotum90 +PCSG00798 Fairune +PCSE00955 Fallen Legion +PCSH00157 Fantasy Hero ~unsigned legacy~ +PCSG00280 FANTASY HERO~unsigned legacy~ +PCSB00333 Farming Simulator +PCSE00285 Farming Simulator +PCSE00419 Farming Simulator 14 +PCSH00117 Farming Simulator 14 +PCSB00843 Farming Simulator 16 +PCSE01035 Farming Simulator 18 +PCSE01334 Fast Striker +PCSB00894 Fat City +PCSA00156 Fat Princess: Piece of Cake +PCSF00612 Fat Princess: Piece of Cake +PCSG00600 Fate/EXTELLA +PCSG01091 Fate/EXTELLA LINK +PCSE01254 Fate/EXTELLA LINK +PCSE00928 Fate/Extella: The Umbral Star +PCSG00386 Fate/hollow ataraxia +PCSG00122 Fate/Stay Night [Realta Nua] +PCSE01282 Fernz Gate +PCSE00404 Fez +PCSE00266 Fieldrunners 2 +PCSG00107 FIFA 13 WORLD CLASS SOCCER +PCSE00263 FIFA 14 +PCSG00201 FIFA 14 WORLD CLASS SOCCER +PCSG00404 FIFA 15 +PCSE00481 FIFA 15 +PCSE01431 Fifty Words by POWGI +PCSB01397 Fifty Words by POWGI +PCSH10211 Fifty Words by POWGI +PCSE01255 Fill-a-Pix: Phil's Epic Adventure +PCSB00395 FINAL FANTASY X HD Remaster +PCSG00219 FINAL FANTASY X HD Remaster +PCSB00394 Final Fantasy X-2 HD Remaster +PCSG00220 FINAL FANTASY X-2 HD Remaster +PCSE00504 Final Horizon +PCSA00037 Fireworks +PCSB00656 Flame Over +PCSE00566 Flame Over +PCSB00328 Floating Cloud God Saves the Pilgrims in HD! +PCSG01202 Floral flowlove +PCSA00114 Flower +PCSG00459 FLOWERS +PCSG00739 Flowers Le volume sur ete +PCSG01187 Flowers Le volume sur hiver +PCSB00382 Flyhunter Origins +PCSE00257 Flying Hamster HD +PCSE00039 Foosball 2012 +PCSB00160 Foosball 2012 +PCSE00797 Forma.8 +PCSE00321 Fort Defense +PCSB00472 Fort Defense North Menace +PCSG01131 Fortissimo +PCSH10065 Fortune Street: Dragon Quest & Final Fantasy 30th Anniversary +PCSB00522 Foul Play +PCSA00047 foursquare +PCSE01437 FoxyLand +PCSE01438 FoxyLand 2 +PCSE01380 Frane: Dragons' Odyssey +PCSA00147 Freedom Wars +PCSC00054 Freedom Wars +PCSD00087 FREEDOM WARS™ +PCSF00446 FREEDOM WARS™ +PCSG00519 Friend to Lover ~フレラバ~ +PCSA00050 FROBISHER SAYS!™ +PCSE00528 Frozen Synapse Prime +PCSE00229 Fruit Ninja +PCSB00273 Fruit Ninja +PCSG01260 Full Kiss +PCSB01053 Full Throttle Remastered +PCSE01261 FullBlast +PCSE00839 Funk of Titans +PCSB00421 Furmins +PCSE00111 Furmins +PCSG00227 Furuiro Meikyuu Rondo: La Roue de fortune +PCSG00922 Furuki Yoki Jidai no Boukentan +PCSB01333 Furwind +PCSG00569 Fushigi no Chronicle: Furikaerimasen Katsu Madewa +PCSG01085 Futagoza no Paradox +PCSE00495 Futuridium EP Deluxe +PCSG00493 Fuuraiki 3 +PCSG01065 Gakuen Club Himitsu no Nightclub +PCSG00654 Gakuen K -Wonderful School Days- V Edition +PCSH00249 Gakusen Toshi Asterisk Festa - Houka Kenran +PCSG00704 Gal Gunvolt +PCSE00881 Gal*Gun Double Peace +PCSG00699 Gal*Gun Double Peace +PCSB00956 Gal*Gun Double Peace +PCSG01029 Gal*Gun Double Peace Bilingual +PCSG01151 GALTIA V Edition +PCSE01440 Ganbare! Super Strikers +PCSE00958 GAROU: MARK OF THE WOLVES +PCSE00981 Geki Yaba Runner +PCSG00214 Gekijouban Madoka Magicka: The Battle Pentagram +PCSB00799 Gem Legends +PCSB00965 GemSmashers 3D +PCSG00373 Gendai Daisenryaku 2016 ~Chitsujo no Houkai·Haken Kokka Shittsui~ +PCSG00256 GENIMUS +PCSG00619 Genji Koi Emaki +PCSG00695 Genkai Tokki: Moero Crystal +PCSH00301 Genkai Tokki: Moero Crystal +PCSG00882 Genkai Tokki: Seven Pirates +PCSG01294 Gensou Rougoku no Kaleidoscope +PCSB00769 Geometry Wars 3: Dimensions +PCSB00610 Get Off My Lawn! +PCSE00421 Get Off My Lawn! +PCSG00921 Geten no Hana with Yume Akari - Aizouban +PCSG90098 Getsuei Gakuen -kou- +PCSG00991 Getsuei no Kusari: Kouran Moratorium +PCSG00794 Getsuei no Kusari: Sakuran Paranoia +PCSB01378 Ghoulboy +PCSE01340 Ghoulboy +PCSG00419 Ginsei Igo: Next Generation +PCSG01073 Gintama Rumble +PCSG00670 Girlfriend (Kari) - Kimi to Sugosu Natsuyasumi +PCSG00339 Girls und Panzer: Senshado, Kiwamemasu! +PCSG01277 Gnosia +PCSG00786 Gochuumon wa Usagi Desu ka?? +PCSG00240 GOD EATER 2 +PCSE00789 GOD EATER 2 RAGE BURST +PCSG00532 GOD EATER 2 RAGE BURST +PCSH00133 GOD EATER 2 RAGE BURST +PCSG00719 GOD EATER RESURRECTION +PCSH00199 GOD EATER RESURRECTION +PCSE00801 GOD EATER RESURRECTION +PCSF00438 God of War® Collection +PCSA00126 God of War® Collection +PCSG00831 God Wars: Future Past +PCSG00367 Goes! +PCSG00218 Golden Time Vivid Memories +PCSE00879 Grand Kingdom +PCSB01372 Grass Cutter +PCSE00487 Gravity Badgers +PCSB00525 Gravity Crash Ultra +PCSC00002 GRAVITY DAZE™ +PCSE01384 Gravity Duck +PCSB01338 Gravity Duck +PCSD00035 GRAVITY RUSH +PCSF00024 GRAVITY RUSH™ +PCSA00011 GRAVITY RUSH™ +PCSF00067 GRAVITY RUSH™ (DEMO) +PCSB00949 Green Game: Timeswapper +PCSE00547 Grim Fandango Remastered +PCSG00206 Grisaia no Kajitsu Le Fruit de la Grisaia +PCSG00620 Grisaia no kajitsu spinout +PCSG00421 Grisaia no Meikyuu Le Labyrinthe de la Grisaia +PCSG01149 Grisaia Phantom Trigger 01 & 02 +PCSG01218 Grisaia Phantom Trigger 03 & 04 +PCSE00033 Guacamelee! +PCSB00189 Guacamelee! +PCSB01416 Guard Duty +PCSG00131 GUILTY GEAR XX ΛCORE PLUS R +PCSG01013 Gun Gun Pixies +PCSG00126 Gundam Breaker +PCSG00412 Gundam Breaker 2 +PCSH00208 Gundam Breaker 3 +PCSH10042 Gundam Breaker 3 BREAK EDITION +PCSH10041 GUNDAM BREAKER 3 BREAK EDITION +PCSG00657 Gundam Conquest V +PCSE01283 GUNDEMONIUMS +PCSG01289 Gunka o Haita Neko +PCSE00340 Gunslugs +PCSB01365 Habroxia +PCSE01504 Habroxia 2 +PCSG00162 Haiyore! Nyaruko-San +PCSG00577 Hakuisei Aijou Izonshou +PCSG01275 Hakuisei Renai Shoukougun Re:Therapy +PCSE01001 Hakuoki Edo Blossoms +PCSG00217 Hakuouki Kyouka Roku +PCSG00605 Hakuouki Reimeiroku +PCSG00297 Hakuouki SSL: Sweet School Life +PCSG00930 Hakuouki Yugiroku The Great Banquet of the Members +PCSG00811 Hakuouki: Shinkai - Hana no Shou +PCSG00485 Hakuouki's Memoirs Omokagegehana +PCSE01258 Halloween Forever +PCSG00855 Hana Oboro ~Sengoku-den Ranki~ +PCSG01024 Hanasaki Work Spring! +PCSG00576 Hanayaka Nari, Wa ga Ichizoku: Gentou Nostalgie +PCSG00470 Hanayaka Nari, Wa ga Ichizoku: Modern Nostalgie +PCSG00451 Hanayamata: Yosakoi Live! +PCSE00681 Handball 16 +PCSG00992 Harukanaru Toki no Naka de 3 Ultimate +PCSG00542 Harukanaru Toki no Naka De 6 +PCSG00975 Harukanaru Toki no Naka de 6: Gentou Rondo +PCSG01157 Harukanaru Toki no Naka de Ultimate +PCSG01252 Haruoto Alice Gram: Snow Drop +PCSG00559 Harvest OverRay +PCSE00653 Hatoful Boyfriend +PCSE00776 Hatoful Boyfriend: Holiday Star +PCSG01229 Hatsujou Sprinkle +PCSE00867 Hatsune Miku Project DIVA X +PCSE00886 Hatsune Miku Project DIVA X Demo +PCSE00326 Hatsune Miku: Project DIVA f +PCSB00419 Hatsune Miku: Project DIVA f +PCSG00074 Hatsune Miku: Project DIVA f +PCSB00506 Hatsune Miku: Project DIVA f (DEMO) +PCSG00205 Hatsune Miku: Project DIVA F 2nd +PCSB00554 Hatsune Miku: Project DIVA F 2nd +PCSE00434 Hatsune Miku: Project DIVA F 2nd +PCSH00115 Hatsune Miku: Project DIVA F 2nd (DEMO) +PCSG00683 Hatsune Miku: Project Diva X +PCSB01007 Hatsune Miku: Project DIVA X +PCSH00239 Hatsune Miku: Project Diva X (DEMO) +PCSH00176 Hatsune Miku: Project DIVA X (初音未來 -Project DIVA- X) +PCSB01009 Hatsune Miku: Project DIVA X Demo +PCSG90214 Hatsune Miku: Project DIVA X Trial (DEMO) +PCSG00988 Hatsuru Kotonaki Mirai Yori +PCSG00997 Hatsuyuki Sakura +PCSA00134 HELLDIVERS™ +PCSE00666 Heroes of Loot +PCSE01256 Heroes Trials +PCSG00388 Hideboh: Tap Dance Hero +PCSG00406 High School DxD: New Fight +PCSG00517 Higurashi no Naku Koro ni Sui +PCSG00639 Himawari Pebble in the Sky +PCSH10186 Himno +PCSG00688 Himouto! Umaru-chan: Umaru Training Plan +PCSE00254 HISTORY: Legends of War: Patton +PCSB00922 Hitman GO: Definitive Edition +PCSE00846 Hitman GO: Definitive Edition +PCSG00506 Hitotsu Tobashi Ren’ai V +PCSB01340 Hoggy2 +PCSA00123 Hohokum +PCSE00533 Home - A Unique Horror Adventure +PCSB00687 Home - A Unique Horror Adventure +PCSG00926 Hoshi ori yume mirai +PCSA00009 Hot Shots Golf™: World Invitational +PCSG00200 Hotchkiss +PCSE00249 Hotline Miami +PCSB00318 Hotline Miami +PCSE00402 Hotline Miami 2: Wrong Number +PCSB00511 Hotline Miami 2: Wrong Number +PCSB00641 htoL#NiQ -The Firefly Diary- +PCSE00527 htoL#NiQ -The Firefly Diary- +PCSE00551 HTR+ Slot Car Simulation +PCSB00938 HTR+ Slot Car Simulation +PCSE00996 Hue +PCSB00246 Hungry Giraffe +PCSA00007 Hustle Kings +PCSG00518 Hyakka Ryouran Elixir: Record of Torenia Revival +PCSG00477 Hyakka Yakou +PCSE00568 Hyperdevotion Noire Goddess Black Heart +PCSE00400 Hyperdimension Neptunia PP +PCSB00515 Hyperdimension Neptunia PP +PCSG00226 Hyperdimension Neptunia Re;Birth 1 +PCSE00443 Hyperdimension Neptunia Re;Birth 1 +PCSB00626 Hyperdimension Neptunia Re;Birth2 +PCSE00661 Hyperdimension Neptunia Re;Birth3 V GENERATION +PCSG00486 Hyperdimension Neptunia Re;Birth3: V Century +PCSG00394 Hyperdimension Neptunia U: Action Unleashed +PCSB00710 HYPERDIMENSION NEPTUNIA U: Action Unleashed +PCSE00588 HYPERDIMENSION NEPTUNIA U: Action Unleashed +PCSG90077 Hyperdimension Neptunia: Producing Perfection Demo +PCSE01188 I Am The Hero +PCSG01257 I Am The Hero +PCSE01358 I and Me +PCSG00592 I DOLL U - +PCSG00337 I wanna say that I'm not your brother right now!! +PCSG00355 IA/VT -COLORFUL- +PCSE01245 Ice Cream Surfer +PCSE01177 Iconoclasts +PCSG00965 id: RebirthSession +PCSG00865 Idol Death Game TV +PCSG01094 IDOLiSH7 Twelve Fantasia! +PCSG00357 If my Heart Had Wings +PCSG01063 Ikemen Sengoku: Toki o Kakeru Koi - Aratanaru Deai +PCSG00756 Ikenie to Yuki no Setsuna +PCSE01418 Illusion of L'Phalcia +PCSA00113 Imaginstruments +PCSF00210 Imaginstruments +PCSG00602 Incognito, Falling in Love ― Snow Moon Flower Love Emaki ― +PCSE00041 INDOOR SPORTS WORLD +PCSH00278 Infinita Strada Hana +PCSG00270 Infinite Stratos 2: Ignition Hearts +PCSG00584 Infinite Stratos 2: Love and Purge +PCSB00356 Injustice: Gods Among Us Ultimate Edition +PCSE00271 Injustice: Gods Among Us Ultimate Edition +PCSE01237 InkSplosion +PCSB00157 International Snooker 2012 +PCSA00137 Invizimals: The Alliance +PCSF00415 Invizimals™ Hidden Challenges +PCSF00510 Invizimals™: The Resistance +PCSA00552 Invizimals™: The Resistance +PCSE00876 iO +PCSB01029 Iron Sea Defenders +PCSE01369 Iron Snout +PCSG01186 IS IT WRONG TO TRY TO PICK UP GIRLS IN A DUNGEON? SHOOTING +PCSG01000 ISLAND +PCSB01132 It's Spring Again +PCSG00932 Itadaki Street: Dragon Quest & Final Fantasy 30th Anniversary +PCSG01083 Iwaihime Matsuri +PCSG01297 IxSHE Tell +PCSG00300 J-Stars Victory VS +PCSE00595 J-Stars Victory Vs+ +PCSH00136 J-STARS Victory VS+ +PCSB00713 J-STARS Victory VS+ +PCSE01287 Jack N' Jill DX +PCSB01268 Jack N' Jill DX +PCSF00250 Jak 3 +PCSA00080 Jak and Daxter Collection +PCSF00248 Jak and Daxter: The Precursor Legacy +PCSF00249 Jak II +PCSB00236 JAZZ Trump's Journey +PCSE00393 Jet Car Stunts +PCSB00136 Jet Set Radio +PCSE00088 Jet Set Radio +PCSE00213 Jetpack Joyride +PCSB00244 Jetpack Joyride +PCSB00664 Jetpack Joyride Deluxe +PCSE00537 Jetpack Joyride Deluxe +PCSG00064 Jikkyou Powerful Pro Yakyuu 2012 +PCSG00134 Jikkyou Powerful Pro Yakyuu 2012 Kettei Ban +PCSG00207 Jikkyou Powerful Pro Yakyuu 2013 +PCSG00416 Jikkyou Powerful Pro Yakyuu 2014 +PCSG00748 Jikkyou Powerful Pro Yakyuu 2016 +PCSG01164 Jikkyou Powerful Pro Yakyuu 2018 +PCSG01045 Jikkyou Powerful Pro Yakyuu Championship 2017 +PCSG01219 Jikkyou Powerful Pro Yakyuu Championship 2018 +PCSG00596 Jinro Game +PCSE00478 Joe Danger +PCSE00477 Joe Danger 2: The Movie +PCSG00390 JUDAS CODE(ジューダス コード) +PCSE00594 Jungle Rumble: Freedom, Happiness, and Bananas +PCSB01400 Just a Phrase by POWGI +PCSH10213 Just a Phrase by POWGI +PCSE01436 Just a Phrase by POWGI +PCSB01362 Just Ignore Them +PCSG00529 Justy x Nasty: Maou Hajime Mashita +PCSG00635 Jyuzaengi: Engetsu Sangokuden 1+2 +PCSG00381 Kadenz fermata Akkord:fortissimo +PCSG00501 Kaeru Batake de Tsukamaete +PCSG00304 Kagero: Darkside Princess +PCSG00360 Kaihou Shoujo SIN +PCSG00172 Kajiri Kamui Kagura: Akebono no Hikari +PCSG01007 Kamaitachi no Yoru: Rinne Saisei +PCSG00675 Kamen Rider: Battride War Genesis +PCSG01106 Kamidanomi Shisugite Ore no Mirai ga Yabai. +PCSG00595 Kamigami no Asobi InFinite +PCSG00684 KanColle Kai +PCSG01268 Kannagi no Mori Satsukiame Tsuzuri +PCSG01182 Kanojo * Step +PCSG01253 Karigurashi Ren'ai +PCSG01044 Karumaruka Circle +PCSG01332 Kawaii Deathu Desu +PCSG00553 Ken Ga Kimi For V +PCSG00960 Ken ga Kimi: Momoyo Tsuzuri +PCSG00829 Kenka Bancho Otome +PCSG01042 Kenka Bancho Otome : Kanzenmuketsu no My Honey +PCSG01241 Kenka Bancho Otome 2nd Rumble!! +PCSE00485 Kick and Fennick +PCSE00113 KickBeat +PCSB01354 Kid Tripp +PCSG00040 Kidou Senshi Gundam Seed: Battle Destiny +PCSE00473 Kilka Card Gods +PCSB01477 Killer Dolls United +PCSG01132 Killers and Strawberries +PCSD00071 Killzone Mercenary +PCSC00045 Killzone®: Mercenary +PCSF00403 Killzone™ Mercenary +PCSA00107 Killzone™ Mercenary +PCSF00243 Killzone™ Mercenary +PCSG01087 Kimi no Hitomi ni Hit Me +PCSG00913 Kimi o Aogi Otome wa Hime ni +PCSG01318 Kin-iro Loveriche +PCSG01124 Kin'iro no Corda 2 ff +PCSG01212 Kin'iro no Corda 3: AnotherSky feat. Jinnan / Shiseikan / Amane Gakuen +PCSG01211 Kin'iro no Corda 3: Full Voice Special +PCSG00774 Kin'iro no Corda 4 +PCSH00275 Kin'iro no Corda 4 +PCSG01245 Kin'iro no Corda: Octave +PCSE00315 King Oddball +PCSG00742 Kiss Ato +PCSG00413 KissBell +PCSG00478 KLAP!! ~Kind Love And Punish~ +PCSG00970 KLAP!! ~Kind Love And Punish~ Fun Party +PCSB01409 Knightin'+ +PCSB00929 Knock-knock +PCSB00169 Knytt Underground +PCSE00092 Knytt Underground +PCSE01040 KOI +PCSG01299 Koisuru Otome to Shugo no Tate: Bara no Seibo +PCSG00761 Kono Aozora ni Yakusoku o +PCSG00345 Kono Uta ga Owattara: When This Song is Over +PCSG00996 Kono Yo no Hate de Koi wo Utau Shoujo YU-NO Original +PCSG01093 Konosuba - Attack of the Destroyer +PCSG01265 KonoSuba: Give Education to this Useless Goddess! +PCSG01028 KonoSuba: Judgment on this Greedy Game! +PCSG01258 Konosuba: Labyrinth of Hope and the Gathering Adventurers +PCSG01213 Koshotengai no Hashihime Noma +PCSG00273 Kud Wafter: Converted Edition +PCSG00894 Kujiragami no Tearstilla +PCSE00256 Kung Fu Rabbit +PCSE01036 Kung Fury: Street Rage +PCSG01158 Kurenai no Homura Sanada Ninpou Chou +PCSG00609 Kurogane Kaikijong +PCSG00641 Kurogane Kaikitan: Ichigoichie +PCSG90129 Kurogane Kaikitan: Senya Ichiya +PCSG01288 L'Phalcia no Genei +PCSE00567 LA-MULANA EX +PCSE00985 Lara Croft GO +PCSE00856 Last Wings +PCSE01085 League of Evil +PCSH10082 Legend of Heroes: Trails in the Sky 3rd Evolution +PCSH00178 Legend of Heroes: Trails in the Sky FC Evolution +PCSE01426 Legend of the Skyfish +PCSB01392 Legend of the Skyfish +PCSE00061 LEGO Batman 2: DC Super Heroes +PCSE00442 Lego Batman 3 Beyond Gotham +PCSE00057 Lego Harry Potter Years 5-7 +PCSE00587 Lego Jurassic World +PCSE00237 Lego Legends of Chima Laval’s Journey +PCSB00764 Lego Marvel's Avengers +PCSE00384 Lego Ninjago Nindroids +PCSE00534 Lego Ninjago Shadow Of Ronin +PCSE00791 Lego Star Wars The Force Awakens +PCSE00390 Lego The Hobbit +PCSE00067 Lego The Lord Of The Rings +PCSB00315 LEGO® MARVEL Super Heroes: Universe in Peril +PCSE00670 LEGO® MARVEL's Avengers +PCSA00138 Lemmings™ Touch +PCSG00405 Lend fleur +PCSE00216 Let's Fish ! Hooked On +PCSB00230 Let's Fish! Hooked On +PCSG00028 Let's Try Bass Fishing FISH ON NEXT +PCSB00879 Letter Quest Remastered +PCSB00845 LEVEL 22 +PCSE01010 Lichtspeer +PCSB01154 Licky The Lucky Lizard Lives Again +PCSB00336 Limbo +PCSE00268 Limbo +PCSE01285 Link-a-Pix Deluxe +PCSG01319 Link-a-Pix Deluxe +PCSE01231 Little Adventure on the Prairie +PCSG00007 Little Busters! Converted Edition (リトルバスターズ! Converted Edition) +PCSF00017 Little Deviants +PCSA00010 Little Deviants™ +PCSB01215 Little Red Lie +PCSE01218 Little Red Lie +PCSF00021 LittleBigPlanet™ PlayStation®Vita +PCSA00017 LittleBigPlanet™ PlayStation®Vita +PCSA00549 LittleBigPlanet™ PlayStation®Vita Marvel Super Hero Edition +PCSB00494 Llamasoft TxK +PCSE01187 London Detective Mysteria +PCSB00361 Lone Survivor +PCSE00301 Lone Survivor +PCSF00441 Looney Tunes™ Galactic Sports +PCSG00008 Lord of Apocalypse +PCSG90001 Lord Of Apocalypse ロードの誘い +PCSE00673 Lost Dimension +PCSG01314 LOVE CLEAR +PCSG00422 Love Live! School idol paradise Vol.1 Printemps +PCSG00423 Love Live! School idol paradise Vol.2 BiBi +PCSG00424 Love Live! School idol paradise Vol.3 lily white +PCSG01004 Love of Ren'ai Koutei of LOVE! +PCSG00667 LOVE:QUIZ - Koisuru Shoujo no Final Answer +PCSG00336 LOVELY QUEST Unlimited +PCSG00556 LOVELY×CATION 1&2 +PCSH10290 Luckslinger +PCSG01165 Lucky Dog 1 +PCSE00247 LUFTRAUSERS +PCSE00009 Lumines Electronic Symphony +PCSG00444 Luminous Arc Infinity +PCSE00857 Lumo +PCSG00475 M3: Sono Kuroki Hagane /// Mission Memento Mori +PCSE00212 Machinarium +PCSG00947 Macross Delta: Scramble +PCSE00084 Madden NFL 13 +PCSG00221 Magical Beat +PCSE00464 Magical Beat (DEMO) +PCSE00749 Mahjong Carnival +PCSG00029 Mahjong Fight Club: Shinsei Zenkoku Taisen Han +PCSG00368 Mahou Shoujo Taisen Zanbatsu +PCSG00456 Mahouka Koukou no Rettousei: Out of Order +PCSG00856 Maison de Maou +PCSG00852 Maji-Kyun! Renaissance +PCSG00652 Majin Shoujo - Chronicle 2D ACT (Japan) (En,Ja,Zh) (PSN) +PCSG00770 Majo Koi Nikki: Dragon x Caravan +PCSG01284 Making*Lovers +PCSG00130 MALICIOUS REBIRTH +PCSA00127 MALICIOUS™ REBIRTH +PCSE00736 Maliya +PCSG00340 MANGA-KA-KERU +PCSG00448 MARGINAL#4 IDOL OF SUPERNOVA +PCSG01008 MARGINAL#4 ROAD TO GALAXY +PCSG00662 Maru Goukaku! Takken Shiken - Heisei 27 Nendohan +PCSG00898 Mary Skelter: Nightmares +PCSB01059 Mary Skelter: Nightmares +PCSE01158 Mecho Tales +PCSE01264 Mecho Wars: Desert Ashes +PCSH10177 Mecho Wars: Desert Ashes +PCSB00921 MegaTagmension Blanc Neptune VS Zombies +PCSG00578 MegaTagmension Blanc + Neptune VS Zombies +PCSH00236 MegaTagmension Blanc + Neptune VS Zombies (Asia) +PCSE00832 MegaTagmension Blanc Neptune VS Zombies +PCSG00398 Meikyuu Cross Blood: Infinity Ultimate +PCSG00258 MeiQ +PCSE00918 MeiQ: Labyrinth of Death +PCSB00990 MeiQ: Labyrinth of Death +PCSG00606 MeiQ: Labyrinth of Death +PCSE01428 Mekabolt +PCSB01348 MEKORAMA +PCSG01285 MELLKISS +PCSG00733 Melty Moment +PCSG00176 Memories Off 6 Complete +PCSH10133 Memories Off Innocent Fille +PCSG01264 Memories Off Innocent Fille for Dearest +PCSB00313 Men's Room Mayhem +PCSE00252 Men's Room Mayhem +PCSE00956 Mercenary Kings +PCSH10097 METAGAL +PCSE01080 METAGAL +PCSE00078 Metal Gear Solid 2: Sons of Liberty HD Edition +PCSG00081 Metal Gear Solid 3 HD Edition +PCSE00079 Metal Gear Solid 3: Snake Eater HD Edition +PCSB00118 Metal Gear Solid HD Collection +PCSG00972 METAL MAX Xeno +PCSE00665 METAL SLUG 3 +PCSB00772 METAL SLUG 3 +PCSE00406 Metrico +PCSH10242 Metropolis: Lux Obscura +PCSE00010 Michael Jackson The Experience HD +PCSG00198 Midnight Deluxe +PCSE01194 Midnight Deluxe +PCSG01193 Mikagami Sumika no Seifuku Katsudou +PCSC00052 Miku Miku Hockey +PCSC00081 Miku Miku Hockey 2.0 +PCSB01393 Miles & Kilo +PCSE01425 Miles & Kilo +PCSB01414 Milo's Quest +PCSE01501 Mind Maze +PCSG00184 MIND≒0 +PCSE00491 Minecraft: Playstation Vita Edition +PCSG00302 Minecraft: Playstation Vita Edition +PCSB00560 Minecraft: PlayStation Vita Edition +PCSG00581 Minna de Spelunker Z +PCSC00055 Minna to Issho +PCSB00544 Minutes™ +PCSG00610 Miracle Girls Festival +PCSH10169 Mixups by POWGI +PCSB01332 Mixups by POWGI +PCSE01378 Mixups by POWGI +PCSA00002 MLB 12 The Show +PCSA00065 MLB 13: The Show +PCSA00511 MLB15 THE SHOW +PCSB00983 Mobile Suit Gundam Extreme Versus Force +PCSG00579 Mobile Suit Gundam: Battle Fortress +PCSG00738 Mobile Suit Gundam: Extreme VS Force +PCSE00915 Mobile Suit Gundam: Extreme VS-Force +PCSE01414 Mochi Mochi Boy +PCSA00001 ModNation™ Racers: Road Trip +PCSF00002 ModNation™ Racers: Road Trip +PCSG00989 Moe Moe 2-Ji Daisenryaku 3 +PCSG00065 Moe Moe Daisensou Gendai Ban Plus Plus +PCSG00378 Monobeno -pure smile- +PCSB00473 Monster Monpiece +PCSG00148 Monster Monpiece +PCSF00651 MonsterBag - +PCSE00838 MOP: Operation Cleanup +PCSB00106 Mortal Kombat +PCSE00023 Mortal Kombat +PCSG00706 Moshi, Kono Sekai ni Kami-sama ga Iru to suru Naraba. +PCSB00498 MotoGP 14 +PCSB00316 MotoGP™13 +PCSC00014 MOTORSTORM® RC +PCSF00046 MotorStorm®RC - +PCSG00247 Motto Nee, Chanto Shouyo! +Plus +PCSG00854 Moujuu-tachi to Ohime-sama +PCSB00530 MouseCraft +PCSE01002 Mr.Pumpkin Adventure +PCSB00367 Ms. Germinator +PCSB00182 MUD - FIM Motocross World Championship™ +PCSB00685 Multiplayer.it +PCSE00240 Muramasa Rebirth +PCSB00404 Muramasa Rebirth +PCSA00153 Murasaki Baby +PCSF00435 Murasaki Baby™ +PCSC00043 Muryou-ban E-Channel NEW Paint Park +PCSE01479 Mushroom Heroes +PCSH10037 Musou Stars +PCSE01184 Musynx +PCSB00979 Mutant Mudds Super Challenge +PCSB01234 Muv-Luv +PCSE01259 Muv-Luv +PCSG00776 Muv-Luv +PCSG00777 Muv-Luv Alternative +PCSG90203 Muv-Luv Alternative Total Eclipse: Teito Moyu +PCSE00530 MXGP - The Official Motocross Videogame +PCSB01463 My Aunt is a Witch +PCSE01386 My Big Sister +PCSE00982 My Name Is Mayo +PCSE00459 My Singing Monsters +PCSB00958 Mystery Chronicle: One Way Heroics +PCSG01178 NadeRevo! Nadeshiko Revolution +PCSG00664 Nanairo Reincarnation +PCSG01185 Natsuiro Kokoro Log +PCSG00650 Natsumegu +PCSB00594 NAtURAL DOCtRINE +PCSE00460 NAtURAL DOCtRINE +PCSG00030 NAX Music Player +PCSB01321 Necrosphere +PCSE01413 Need a packet? +PCSE00089 Need For Speed™ Most Wanted +PCSG00106 Need For Speed™ Most Wanted +PCSB00183 Need For Speed™ Most Wanted +PCSG00410 Nekketsu Inou Bukatsu: Trigger Kiss +PCSG01068 Neo Angelique: Tenshi no Namida +PCSG00877 Neo ATLAS 1469 +PCSB00910 Neon Chrome +PCSE01398 Neon Junctions +PCSG00951 Nep-Nep Connect: Chaos Chanpuru +PCSG00656 Net High +PCSE00070 Netflix +PCSE01236 NeuroVoider +PCSE01137 NeverEnd +PCSE00847 Neverending Nightmares +PCSB00940 Neverending Nightmares +PCSG00903 New Game! -The Challenge Stage!- +PCSH10101 New Game! -The Challenge Stage!- Chinese Version +PCSB00109 New Little King's Story +PCSE00066 New Little King's Story +PCSG01204 NG +PCSG80001 niconico +PCSE00514 Nidhogg +PCSH00254 Night of Azure / Yoru no Nai Kuni (無夜國度) +PCSG00986 Night of Azure 2 / Yoru no Nai Kuni 2 +PCSE01149 Night Trap - 25th Anniversary Edition +PCSE00895 NightCry +PCSG00557 Nights of Azure / Yoru no Nai Kuni +PCSB00705 Nihilumbra +PCSE00620 Nihilumbra +PCSG00586 Nihilumbra +PCSG00082 Nikoli no Puzzle V: Akari +PCSG00095 Nikoli no Puzzle V: Hashi o Kakero +PCSG00067 Nikoli no Puzzle V: Heyawake +PCSG00098 Nikoli no Puzzle V: Hitori ni Shitekure +PCSG00060 Nikoli no Puzzle V: Kakuro +PCSG00083 Nikoli no Puzzle V: Masyu +PCSG00097 Nikoli no Puzzle V: Number Link +PCSG00068 Nikoli no Puzzle V: Nurikabe +PCSG00096 Nikoli no Puzzle V: Shikaku ni Kire +PCSG00061 Nikoli no Puzzle V: Slither Link +PCSG00094 Nikoli no Puzzle V: Yajilin +PCSG00044 Nikoli no Sudoku V: Shugyoku no 12 Puzzle +PCSG01014 Nil Admirari's Balance Kuroyuri Enyoutan +PCSG00766 Nil Admirari's Balance Teito Illusion Kitan +PCSE00021 Ninja Gaiden Sigma Plus +PCSB00097 NINJA GAIDEN Σ PLUS +PCSG00157 NINJA GAIDEN Σ2 PLUS +PCSB00294 NINJA GAIDEN Σ2 PLUS +PCSB00903 Ninja Senki DX +PCSG01099 Ninja Usagimaru: Two Tails of Adventure +PCSG01111 Ninki Seiyuu no Tsukurikata +PCSG00397 Nisekoi: Yomeiri! +PCSA00150 No Heroes Allowed: No Puzzles Either!™ +PCSG00803 Nobunaga no Yabou 201X +PCSG00374 Nobunaga no Yabou: Souzou +PCSG00607 Nobunaga no Yabou: Souzou with Power-Up Kit +PCSG00741 Nobunaga no Yabou: Tenshouki with Power-Up Kit HD Version +PCSH00291 Nobunaga's Ambition: Souzou Sengoku Risshiden +PCSH00171 Nobunaga's Ambition: Sphere of Influence with Power-Up Kit +PCSG01107 Nora to Oujo to Noraneko Heart +PCSE01496 Norman's Great Illusion +PCSG00833 NORN9 ACT TUNE +PCSG00429 NORN9 LAST ERA +PCSB00847 NORN9 VAR COMMONS +PCSE00762 NORN9 VAR COMMONS +PCSE01173 NORTH +PCSE00686 Nova-111 +PCSE00828 Nuclear Throne +PCSE00220 Nun Attack +PCSE01004 Nurse Love Addiction +PCSB01054 Nurse Love Addiction +PCSE01318 Nurse Love Syndrome +PCSG00150 Oboro Muramasa +PCSG01021 Occultic;Nine +PCSE01097 Oceanhorn +PCSB00825 Octodad: Dadliest Catch +PCSE00623 Octodad: Dadliest Catch +PCSE00369 Oddworld: Munch's Oddysee HD +PCSE00899 Odin Sphere Leifthrasir +PCSH00218 Odin Sphere Leifthrasir +PCSB00986 Odin Sphere Leifthrasir +PCSE00341 OlliOlli +PCSE00479 OlliOlli2: Welcome to Olliwood +PCSG00550 Omega Labyrinth +PCSG00939 Omega Labyrinth Z +PCSH10044 Omega Labyrinth Z +PCSE00275 OMG HD Zombies! +PCSB01213 One Eyed Kutkh +PCSH10094 One More Dungeon +PCSG00358 ONE PIECE UNLIMITED WORLD R +PCSB00557 ONE PIECE Unlimited World Red +PCSH00034 ONE PIECE 海賊無雙2 +PCSG00743 One Piece: Burning Blood +PCSE00808 One Piece: Burning Blood +PCSG00142 One Piece: Pirate Warriors 2 +PCSG00544 One Piece: Pirate Warriors 3 +PCSE00638 ONE PIECE: PIRATE WARRIORS 3 +PCSH00205 One Tap Hero +PCSB01306 One Word by POWGI +PCSH10167 One Word by POWGI +PCSE01338 One Word by POWGI +PCSG00377 Ooedo Blacksmith +PCSA00118 OPEN ME!™ +PCSE00579 Operation Abyss: New Tokyo Legacy +PCSG00387 Operation Abyss: New Tokyo Legacy +PCSE01047 Operation Babel: New Tokyo Legacy +PCSG00514 Operation Babel: New Tokyo Legacy +PCSG00289 Ore ni Hatarakette Iwaretemo Otsu HD +PCSG00623 Ore ni Hatarakette Iwaretemo Tori +PCSF00536 Oreshika: Tainted Bloodlines +PCSC00060 Oreshika: Tainted Bloodlines +PCSA00155 Oreshika™: Tainted Bloodlines +PCSG00299 Oretachi ni Tsubasa wa Nai +PCSG01076 Oretachi no Sekai wa Owatteiru +PCSG00919 Orfleurs: Koufuku no Hanataba +PCSB00924 Organ Trail Complete Edition +PCSG00057 orgarhythm +PCSE00116 Orgarhythm +PCSG00427 Othello +PCSG00487 Otoko Yuukaku +PCSG00942 Otome Riron to Sono Shuuhen: Bon Voyage +PCSG01105 Ouka Sabaki Zan +PCSG00254 Oukaranman +PCSG00769 Ouma ga Toki: Kakuriyo no Enishi +PCSG90304 Our World is Ended +PCSG00728 Owari no Seraph: Unmei no Hajimari +PCSG00967 Owaru sekai to birthday +PCSG00496 OZMAFIA!! -vivace- +PCSB01462 Pachi Pachi +PCSA00059 Paint Park +PCSF00137 Paint Park +PCSA00111 Paint Park Plus +PCSE00489 Panda Run +PCSG01247 Panic Palette +PCSE01056 Papers, Please +PCSB01084 Papers, Please +PCSE01401 Paradox Soul +PCSE00821 Paranautical Activity +PCSG00549 Parfait +PCSE01082 Peasant Knight +PCSE01143 Penny-Punching Princess +PCSB01060 Period Cube ~Shackle of Amadeus~ +PCSG00853 Period Cube ~Shackle of Amadeus~ +PCSE01012 Period Cube ~Shackles of Amadeus~ +PCSG01031 Persona 3 Dancing in Moonlight +PCSE01274 Persona 3: Dancing in Moonlight +PCSB00245 Persona 4 Golden +PCSE00120 Persona 4 Golden +PCSG00563 Persona 4 Golden +PCSG00004 Persona 4 Golden +PCSH00021 Persona 4 The GOLDEN +PCSE00764 Persona 4: Dancing All Night +PCSB00867 Persona 4: Dancing All Night +PCSG00364 Persona 4: Dancing All Night +PCSG01030 Persona 5: Dancing in Starlight +PCSE01275 Persona 5: Dancing in Starlight +PCSB01257 Persona 5: Dancing in Starlight +PCSG00351 Phantasy Star Nova +PCSH00143 Phantasy Star Nova +PCSG90131 Phantasy Star Nova (DEMO) +PCSG90130 Phantasy Star Nova Battle (DEMO) +PCSG00141 Phantasy Star Online 2 +PCSF00718 Phineas and Ferb: Day of Doofenshmirtz +PCSG00139 PhotoKano Kiss +PCSG01071 Photon3 +PCSE01376 Pic-a-Pix Classic +PCSE01435 Pic-a-Pix Classic 2 +PCSE01253 Pic-a-Pix Color +PCSE01422 Pic-a-Pix Color 2 +PCSE01357 Pic-a-Pix Pieces +PCSE01466 Pic-a-Pix Pieces 2 +PCSE00065 Pinball Arcade +PCSA00109 Pinball Heroes: Complete +PCSF00167 Pinball Heroes: Complete +PCSE00751 Pirate Solitaire +PCSB00645 Pix The Cat +PCSE00553 Pix The Cat +PCSE00874 Pixel Hunter +PCSG00269 PixelJunk™ Monsters Ultimate HD +PCSE00307 PixelJunk™ Monsters Ultimate HD +PCSG00384 PixelJunk™ Shooter Ultimate +PCSE00064 Plants vs Zombies +PCSG00931 Plastic Memories +PCSA00069 PlayStation All-Stars Battle Royale +PCSC00032 PlayStation® All-Stars Battle Royale +PCSF00228 PlayStation® Home Arcade +PCSA00083 PlayStation® Home Arcade +PCSA00139 PlayStation®Vita Pets +PCSE00682 Pocket God vs Desert Ashes +PCSE00558 Pocket RPG +PCSG00672 POLARA +PCSE01050 POLARA +PCSG00509 Possession Magenta +PCSG00262 Power Pro Stadium +PCSG00006 Power Smash 4 +PCSE00961 Pox Nora +PCSG00905 Priministar +PCSG00491 Prince of Stride +PCSG00271 Princess Arthur +PCSG00188 Princess Strike! +PCSG00031 Pro Yakyuu Spirits 2012 +PCSG00151 Pro Yakyuu Spirits 2013 +PCSG00288 Pro Yakyuu Spirits 2014 +PCSG00541 Pro Yakyuu Spirits 2015 +PCSG01248 Pro Yakyuu Spirits 2019 +PCSG00572 Project Discovery +PCSE00311 Proteus +PCSH10091 Psychedelica of the Ashen Hawk +PCSE01166 Psychedelica of the Ashen Hawk +PCSE01164 Psychedelica of the black butterfly +PCSG00815 PsychicEmotion6 +PCSE00904 PSYCHO-PASS MANDATORY HAPPINESS +PCSB00985 PSYCHO-PASS MANDATORY HAPPINESS +PCSE00042 Puddle +PCSC00021 Puls-AR +PCSE00702 Pumped BMX + +PCSG00904 Puramai Wars V +PCSE00389 Putty Squad +PCSG00224 Puyo Puyo Tetris +PCSE00108 Puzzle by Nikoli V Slitherlink +PCSE00101 Puzzle by Nikoli V Sudoku +PCSG00045 Puzzle by Nikoli V: Sudoku +PCSE00561 Q*bert Rebooted +PCSE00143 Quell Memento +PCSG01037 Rabi Laby: Puzzle Out Stories +PCSE01111 Rabi-Ribi +PCSB00643 Race The Sun +PCSG01209 Radio Hammer Station +PCSG00958 Raging Loop +PCSG00025 Ragnarok Odyssey +PCSE00300 Ragnarok Odyssey ACE +PCSG00140 Ragnarok Odyssey ACE +PCSE00273 Rainbow Moon +PCSE00318 Rainbow Skies +PCSE01351 Random Heroes: Gold Edition +PCSF00484 Ratchet & Clank +PCSF00485 Ratchet & Clank 2 +PCSF00486 Ratchet & Clank 3 +PCSF00482 Ratchet & Clank Trilogy +PCSA00086 Ratchet & Clank: Full Frontal Assault +PCSF00191 Ratchet and Clank : QForce +PCSE00843 Ray Gigant +PCSB00928 RAYGIGANT +PCSE00277 Rayman Legends +PCSE00052 Rayman® Origins +PCSG00382 RE:VICE[D] +PCSG00933 Re:Zero - kara Hajimeru Isekai Seikatsu - Death or Kiss +PCSE00325 Real Boxing™ +PCSA00012 Reality Fighters™ +PCSG00663 Rear Pheles: Red of Another +PCSG00782 Reco Love: Gold Beach +PCSG00781 RecoLove: Blue Ocean +PCSE01434 Red Bow +PCSG90210 Red Sand Falling Moon Trial Version +PCSE01471 Reed 2 +PCSE01456 Reed Remastered +PCSG00795 Refrain no Chika Meikyuu to Majo no Ryodan +PCSG00426 Ren’ai 0 Kilometer V +PCSG00718 Renai Revenge +PCSG00990 RepKiss +PCSE00608 Resident Evil: Revelations 2 +PCSF00728 Resident Evil: Revelations 2 +PCSA00008 Resistance: Burning Skies +PCSF00142 Resistance: Burning Skies™ +PCSA00103 RESOGUN +PCSF00262 RESOGUN™ +PCSE00075 Retro City Rampage +PCSE00546 Retro City Rampage DX +PCSE01322 Revenant Dogma +PCSE01065 Revenant Saga +PCSE01229 Reverie +PCSG00414 Rewrite +PCSG01043 Rewrite Harvest festa! +PCSE01251 Riddled Corpses EX +PCSE00001 Ridge Racer +PCSG00001 RIDGE RACER +PCSB00048 RIDGE RACER +PCSG90003 Ridge Racer 2011 E3 Interactive Demo +PCSE00548 Ring Run Circus +PCSG00257 RisingStar +PCSE00850 Risk of Rain +PCSG00287 Ro-Kyu-Bu! Naisho no Shutter Chance +PCSG00352 Robotics;Notes Elite +PCSH00165 Robotics;Notes Elite +PCSG90115 Robotics;Notes Elite Demo +PCSE00761 Rocketbirds 2: Evolution +PCSE00112 Rocketbirds HBC +PCSB00571 Rogue Legacy +PCSE00449 Rogue Legacy +PCSG00616 Rollers of the Realm +PCSH00308 Romance of the Three Kingdoms XIII: Fame and Strategy +PCSG00870 Romancing SaGa 2 +PCSE01094 Romancing SaGa 2 +PCSE01337 Romancing SaGa 3 +PCSE01055 Root Double -Before Crime After Days Xtend Edition +PCSG01238 Root Letter Last Answer +PCSG90224 Rosé and the Old Castle of Twilight +PCSE00699 Roundabout +PCSE00750 Royal Defense +PCSE00753 Royal Defense Invisible Threat +PCSG00229 Rozen Maiden -Wechseln sie welt ab- +PCSG00216 Rui wa Tomo o Yobu +PCSA00490 Run Sackboy! Run! +PCSF00562 Run Sackboy! Run! +PCSE01387 Rush Rover +PCSB01464 Russian Subway Dogs +PCSG00503 Ryū ga Gotoku 0 Free app for PlayStation®Vita +PCSG00275 Ryū ga Gotoku: Ishin! Free app for PlayStation®Vita +PCSG00732 Ryuuyoku no Melodia: Diva with the Blessed Dragonol +PCSG00640 SA7 - Silent Ability Seven - +PCSG00543 Saenai Heroine no Sodatekata: 〜blessing flowers〜 +PCSG00802 SaGa: Scarlet Grace +PCSG00906 Saka Agari Hurricane Portable +PCSG90088 Saka-Ban +PCSG00646 Saki Zenkoku Hen +PCSG00908 Saki: Zenkoku-hen Plus +PCSG01231 Sakura Sakura +PCSG00129 Sakura-Sou no Pet na Kanojo +PCSB01072 Salt and Sanctuary +PCSE01023 Salt and Sanctuary +PCSG00041 Samurai & Dragons +PCSE01113 SAMURAI SHODOWN V SPECIAL +PCSG00279 Samurai Warriors 4 +PCSE00503 Samurai Warriors 4 +PCSE00827 SAMURAI WARRIORS 4 Empires +PCSE00737 SAMURAI WARRIORS 4-Ⅱ +PCSE00714 Samurai Warriors: Chronicles 3 +PCSH00152 Samurai Warriors: Chronicles 3 +PCSG00211 San Goku Shi 12 Taisenban +PCSG00210 San Goku Shi 12 with Power-Up Kit +PCSG00949 San Goku Shi 13 with Power-Up Kit +PCSG00863 Sangoku Hime 4: Tenka Ryouran - Tenmei no Koi Emaki +PCSG00183 Sangoku Rensenki: Otome no Heihou! +PCSG00785 Sangoku Rensenki: Otome no Heihou! Omoide Gaeshi - CS Edition +PCSG01194 Sanzen Sekai Yuugi: Re Multi Universe Myself +PCSC00007 Sawari Makuru! +PCSG00554 Sayonara UmiharaKawase + +PCSB00782 Sayonara UmiharaKawase + +PCSG00745 Scared Rider Xechs Rev. +PCSG01036 Scarlet Fragments ~Omoiiro no Memories~ +PCSE01355 Scintillatron4096 +PCSE01505 ScourgeBringer +PCSE00642 Scram Kitty DX +PCSG00793 SD Gundam G Generation Genesis +PCSH00241 SD GUNDAM G GENERATION GENESIS +PCSH00242 SD GUNDAM G GENERATION GENESIS +PCSE01153 Secret of Mana +PCSB01163 Secret of Mana +PCSG00168 Sei Madou Monogatari +PCSG00460 Seiken Densetsu: Rise of Mana (聖剣伝説RISE of MANA) +PCSG01127 Sen no Hatou, Tsukisome no Kouki +PCSG01104 Sengo Muramasa DX: Guren no Kettou +PCSG00132 Sengoku Hime 3: Tenka o Kirisaku Hikari to Kage +PCSG00232 Sengoku Hime 4: Souha Hyakkei, Hana Mamoru Chikai +PCSG00466 Sengoku Hime 5: Senkatatsu Haoh no Keifu +PCSG01034 Sengoku Hime 7: Sen'un Tsuranuku Guren no Ishi +PCSG00233 Sengoku Musou 2 with Moushouden & Empires HD Version +PCSG00471 Sengoku Musou Chronicle 3 +PCSG00867 Sengoku Otome: Legend Battle +PCSG00428 Senjou no Waltz +PCSB00602 SENRAN KAGURA Bon Appetit! (Hanzo x Crimson Squad) +PCSB00882 SENRAN KAGURA ESTIVAL VERSUS +PCSB00601 SENRAN KAGURA SHINOVI VERSUS +PCSG00133 Senran Kagura: Shinovi Versus +PCSE01480 Sense - A Cyberpunk Ghost Story +PCSG01210 Seven Days: Anata to Sugosu Nanokakan +PCSE00589 Severed +PCSE01125 Shakedown Hawaii +PCSE00950 Shantae: Half-Genie Hero +PCSG90111 She (That Girl) Can't Leave Me Trial Version +PCSG01177 Shikihime no Niwa +PCSG00278 Shin Gundam Musou +PCSG00380 Shin Hayarigami +PCSG00897 Shin Hayarigami 2 +PCSG00010 Shin Kamaitachi no Yoru 11 Hitome no Suspect +PCSG00452 Shin Sangoku Musou 7 Empires +PCSH00052 Shin Sangoku Musou 7 with Moushouden +PCSG00893 Shin Sangoku Musou Eiketsuden +PCSG00764 Shin Sangoku Musou Online Z +PCSG01282 Shinigami to Shoujo +PCSG00255 ShinobiAshi +PCSE00015 Shinobido 2: Revenge of Zen +PCSG00019 Shinobido 2: Revenge of Zen +PCSH00001 Shinobido 2: Revenge of Zen +PCSB00049 Shinobido 2: Revenge of Zen +PCSG00580 Shinsou-ban Mahou-tsukai to Goshujin-sama +PCSE00845 Shiren the Wanderer: The Tower of Fortune and the Dice of Fate +PCSG00944 Shiro to Kuro no Alice +PCSG01192 Shiro to Kuro no Alice -Twilight line- +PCSG00846 Shirogane x Spirits! +PCSG00822 Shitsuji ga Aruji o Erabu Toki +PCSB00743 Shovel Knight +PCSE00640 Shovel Knight +PCSE00923 Shu +PCSE00705 Shütshimi +PCSG00588 Sid Meier's Civilization Revolution 2+ +PCSG01001 Side Kicks! +PCSE00011 Silent Hill: Book of Memories +PCSB00115 Silent Hill: Book of Memories +PCSG01259 Silverio Trinity: Beyond the Horizon +PCSG00329 Simple V Series Vol.2: The Tousou Highway Full Boost: Nagoya +PCSB00161 Sine Mora +PCSE00090 Sine Mora +PCSE01240 Sir Eatsalot +PCSE00773 Siralim +PCSB00588 Skeleton Rider +PCSG00583 Skullgirls 2nd Encore +PCSE00865 Sky Force Anniversary +PCSE01054 Skylight Freerange +PCSE00862 Skylight Freerange 2: Gachduine +PCSC80009 Skype +PCSG00048 Slotter Mania V: Black Lagoon +PCSF00338 Sly 1 & 2 +PCSA00098 Sly 3: Honor Among Thieves™ +PCSF00209 Sly Cooper: Thieves in Time +PCSF00269 Sly Raccoon™ +PCSF00216 Smart as +PCSG00787 Snow White in the Mirror Realm +PCSG01254 Soi Kano: Gyutto Dakishimete +PCSG01070 Song of Heiligenstadt +PCSE00056 Sonic & All-Stars Racing Transformed +PCSB00190 Sonic & All-Stars Racing Transformed™ +PCSE00221 Sonic & All-Stars Racing Transformed™ Demo +PCSE00314 Sorcery Saga: Curse of the Great Curry God +PCSG90074 Sorcery Saga: Curse of the Great Curry God +PCSG00296 Soukai Buccaneers! +PCSC00039 SOUL SACRIFICE +PCSC00049 SOUL SACRIFICE DELTA +PCSD00079 SOUL SACRIFICE DELTA™ +PCSA00152 Soul Sacrifice™ Delta +PCSF00532 Soul Sacrifice™ Delta +PCSA00003 Sound Shapes +PCSF00076 Sound Shapes™ +PCSG00993 Sousei no Onmyouji +PCSE00295 Sparkle +PCSE01089 Spellspire +PCSG00145 Spelunker Collection +PCSE00288 Spelunky +PCSB00359 Spelunky +PCSB00789 Spider: Rite of the Shrouded Moon +PCSE00577 SpongeBob HeroPants +PCSE00068 Spy Hunter +PCSG00128 Spy Hunter™ +PCSG00714 Star Ocean Second Evolution +PCSC00008 STAR STRIKE DELTA +PCSB00254 Star Wars Pinball +PCSE01235 Stardew Valley +PCSB01226 Stardew Valley +PCSE00029 StarDrone Extreme +PCSG00917 Starry☆Sky ~Autumn Stories~ +PCSG00510 Starry☆Sky ~Spring Stories~ +PCSG00916 Starry☆Sky ~Summer Stories~ +PCSG00918 Starry☆Sky ~Winter Stories~ +PCSE01277 STAY +PCSB01254 STAY +PCSG01237 STAY +PCSB00690 Stealth Inc 2: A Game of Clones +PCSE00575 Stealth Inc 2: A Game of Clones +PCSB00317 Stealth Inc: A Clone in the Dark +PCSE00280 Stealth Inc: A Clone in the Dark +PCSG01062 Steam Prison: Nanatsu no Bitoku +PCSE01391 Steam Tactics +PCSB00542 SteamWorld Dig +PCSE00430 SteamWorld Dig +PCSE01101 SteamWorld Dig 2 +PCSE00583 SteamWorld Heist +PCSB00693 SteamWorld Heist +PCSE00644 Steins;Gate +PCSG00147 STEINS;GATE +PCSE00949 Steins;Gate 0 +PCSB01012 STEINS;GATE 0 +PCSG00673 STEINS;GATE 0 +PCSG01166 STEINS;GATE ELITE +PCSG00250 Steins;Gate Senkei Kousoku no Phenogram +PCSG00146 Steins;Gate: My Darling's Embrace(比翼恋理のだーりん) +PCSE00290 Stick it to the Man +PCSE01098 Still Time +PCSG00736 STORM LOVER 2nd V +PCSG00735 STORM LOVER V +PCSB00908 Stranger of Sword City +PCSE00818 Stranger of Sword City +PCSG00878 Stranger of Sword City +PCSG00907 Strawberry Nauts +PCSE00005 STREET FIGHTER X TEKKEN +PCSB00144 STREET FIGHTER X TEKKEN +PCSE00688 Strike Solitaire +PCSE01514 SturmFront - The Mutant War +PCSH00006 Sudoku by Nikoli V +PCSG01250 Suki to Suki to de Sankaku Ren’ai +PCSG90008 Sumioni Trial Version +PCSE00062 SUMIONI:DEMON ARTS +PCSB01013 Summon Night 6: Lost borders +PCSG00827 Summon Night 6: Lost borders +PCSH00225 Summon Night 6: Lost borders +PCSE00951 Summon Night 6: Lost Borders +PCSE00047 SunFlowers +PCSE00784 Super Blackout +PCSE01433 Super Box Land Demake +PCSG01240 Super Destronaut DX: Intruders Edition +PCSE01460 Super Destronaut: Land Wars +PCSB00362 Super Exploding Zoo +PCSE00734 Super Exploding Zoo +PCSG00069 Super Hero Generation +PCSB01193 Super Hydorah +PCSB01152 Super Life of Pixel +PCSE01077 Super Life of Pixel +PCSE00942 Super Magical +PCSE00769 Super Meat Boy! +PCSE00017 Super Monkey Ball Banana Splitz +PCSG00032 Super Monkey Ball Banana Splitz +PCSB01100 Super Mutant Alien Assault +PCSE01072 Super Mutant Alien Assault +PCSG00260 Super Robot Taisen +PCSG01128 Super Robot Taisen X +PCSH10001 Super Robot Wars V +PCSH10089 Super Robot Wars X +PCSH10088 SUPER ROBOT WARS X +PCSG00495 Super Robot Wars3 Z Jigoku Hen +PCSB01271 Super Skull Smash Go! 2 Turbo +PCSE00802 Super Star Wars +PCSA00006 Super Stardust Delta +PCSF00019 Super Stardust™ Delta +PCSE00698 Super Time Force ULTRA +PCSE01374 Super Weekend Mode +PCSE01415 Super Wiloo Demake +PCSE00717 SUPERBEAT XONiC +PCSE00898 Superdimension Neptune vs Sega Hard Girls +PCSB00305 Superfrog HD +PCSG01207 SuperZangyura +PCSE00012 Supremacy MMA: Unrestricted +PCSG00948 Suran digit +PCSB00439 Surge Deluxe +PCSE00860 Swap Quest +PCSB00923 SwapQuest +PCSG01196 sweet pool +PCSB00507 Switch Galaxy Ultra +PCSE00493 Switch Galaxy Ultra +PCSE00465 Sword Art Online -Hollow Fragment- +PCSG00868 Sword Art Online : Hollow Realization +PCSB00618 Sword Art Online Hollow Fragment +PCSE00740 Sword Art Online Lost Song +PCSH00134 SWORD ART ONLINE Lost Song +PCSG00294 Sword Art Online: Hollow Fragment +PCSB00972 SWORD ART ONLINE: HOLLOW REALIZATION +PCSE00903 SWORD ART ONLINE: HOLLOW REALIZATION +PCSB00830 Sword Art Online: Lost Song +PCSE01484 Swordbreaker The Game +PCSE01508 Synergia +PCSE01451 Syrup and the Ultimate Sweet +PCSF00064 t@g +PCSF00062 Table Football +PCSA00064 Table Ice Hockey +PCSD00047 Table Ice Hockey™ +PCSC00028 Table Play Golf +PCSB00416 Table Top Racing +PCSB00912 Tachyon Project +PCSE00836 Tachyon Project +PCSE00771 Taco Master +PCSB00458 Tadeo Jones: The game +PCSG00945 Taiheiyou no Arashi: Koukoku no Kouhai Koko ni Ari, 1942 Senkan Yamato Hankou no Gouhou +PCSG00637 Taiheiyou no Arashi: Shijousaidai no Gekisen Normandy Koubousen +PCSG00551 Taiko no Tatsujin V (太鼓の達人 Vバージョン) +PCSG00726 Taishou Mebiusline: Vitable +PCSG00869 Taishou x Alice: All in One +PCSG01141 Taishou x Alice: Heads & Tails +PCSE00034 Tales From Space: Mutant Blobs Attack +PCSB00096 Tales from Space: Mutant Blobs Attack!!! +PCSE00429 Tales of Hearts R +PCSG00125 Tales of Hearts R +PCSB00550 TALES OF HEARTS R +PCSG00163 Tales of Hearts R: Infinite Evolve +PCSG00009 Tales Of Innocence R +PCSE01468 Task Force Kampas +PCSG01203 Tayutama2 -you're the only one- +PCSA00099 Tearaway™ +PCSF00476 Tearaway™ +PCSG00547 Teikoku Kaigun Koi Bojou: Meiji Yokosuka Koushinkyoku +PCSG01064 Teikoku Kaleido: Kakumei no Rondo +PCSG01180 Tengai ni Mau, Iki na Hana +PCSG00137 Tenshi Tsuki no Shoujo +PCSE00317 Terraria +PCSB00722 Teslagrad +PCSE00814 Teslagrad +PCSE01238 TETRA's Escape +PCSB00642 Tetris® Ultimate +PCSE00521 Tetris® Ultimate +PCSE00333 The Amazing Spider-Man +PCSB00428 The Amazing Spider-Man™ +PCSB00676 The Binding of Isaac: Rebirth +PCSE00507 The Binding of Isaac: Rebirth +PCSE00735 THE BIT.TRIP +PCSE01037 The Caligula Effect +PCSG00687 The Caligula Effect +PCSE01112 The Count Lucanor +PCSE01021 The Deer God +PCSE01344 The Demon Rush: Legends Corrupt +PCSE01241 The Dreamlands: Aisling's Quest +PCSG01095 The Fruit of Grisaia: Side Episode +PCSE01305 The House in Fata Morgana +PCSG00677 The IdolM@ster Must Songs - Aka-Ban +PCSG00678 The IdolM@ster Must Songs - Ao-Ban +PCSE00441 The Keeper of 4 Elements +PCSE01224 THE KING OF FIGHTERS '97 GLOBAL MATCH +PCSG00508 The Labyrinth of Grisaia -LE EDEN DE LA GRISAIA- +PCSH10113 The Legend of Heroes AO NO KISEKI Evolution +PCSH10111 The Legend of Heroes ZERO NO KISEKI Evolution +PCSG00490 The Legend of Heroes: Trails in the Sky the Third Evolution +PCSG00195 The Legend of Heroes: Trails of Cold Steel +PCSE00786 THE LEGEND OF HEROES: TRAILS OF COLD STEEL +PCSB00866 THE LEGEND OF HEROES: TRAILS OF COLD STEEL +PCSG00354 The Legend of Heroes: Trails of Cold Steel II +PCSE00896 THE LEGEND OF HEROES: TRAILS OF COLD STEEL II +PCSG00246 The Legend of Heroes: Trails to Azure Evolution +PCSG90069 The Legend of Heroes: Zero no Kiseki Evolution Free Version +PCSE00353 The Lego Movie Videogame +PCSE01162 The Long Reach +PCSE00993 The Longest Five Minutes +PCSE01179 The Lost Child +PCSF00558 The Muppets Movie Adventures +PCSG01163 The Princess Guide +PCSG01235 The Princess, the Stray Cat, and Matters of the Heart 2 +PCSE00775 The Quiet Collection +PCSE00631 The Sun and Moon +PCSB00489 The Swapper +PCSE01388 The Tower of Beatrice +PCSB01347 The Tower of Beatrice +PCSE00436 The Treasures of Montezuma 4 +PCSE00027 The Treasures of Montezuma Blitz +PCSA00158 The Unfinished Swan +PCSE00316 The Walking Dead +PCSB00411 The Walking Dead +PCSE00556 The Walking Dead Season 2 +PCSE00352 The Wolf Among Us +PCSE00258 Thomas Was Alone +PCSE00774 Three Fourths Home (Extended Edition) +PCSE01463 Thunder Paw +PCSE01416 Thy Sword +PCSB01396 Tic-Tac-Letters by POWGI +PCSE01430 Tic-Tac-Letters by POWGI +PCSH10212 Tic-Tac-Letters by POWGI +PCSG90164 Time Avengers Demo +PCSE01186 Time Recoil +PCSG00062 TIME TRAVELERS +PCSG00966 Timepiece Ensemble +PCSE01246 Timespinner +PCSB00552 Tiny Troopers Joint Ops +PCSE00388 Titan Attacks! +PCSE00597 Titan Souls +PCSG00575 To Heart 2: Dungeon Travelers +PCSG00330 To Love-Ru Trouble Darkness: Battle Ecstasy +PCSG00689 To Love-Ru Trouble Darkness: True Princess +PCSG01089 Toaru Majutsu no Virtual-On +PCSG01015 Tokeijikake no Ley Line: Kagerou ni Samayou Majo +PCSG00087 Tokushu Houdoubu +PCSG01103 Tokyo Clanpool +PCSG90298 Tokyo Clanpool Trial +PCSG00615 Tokyo Ghoul: Jail +PCSG00631 Tokyo Onmyouji: Tengen Jibashi - Rei no Baai - V Edition +PCSE01150 TOKYO TATTOO GIRLS +PCSB01161 TOKYO TATTOO GIRLS +PCSE00924 Tokyo Twilight Ghost Hunters Daybreak: Special Gigs +PCSG00634 Tokyo Twilight Ghost Hunters: Daybreak Special Gigs +PCSE00893 Tokyo Xanadu +PCSG00608 Tokyo Xanadu +PCSB01062 Tokyo Xanadu +PCSG01048 TOKYO YAMANOTE BOYS for V MAIN DISC +PCSG01049 Tokyo Yamanote Boys for V: Fan Disc +PCSG01135 Tonari ni Kanojo no Iru Shiawase: Two Farce +PCSG01201 Tonari ni Kanojo no Iru Shiawase: Winter Guest +PCSF00011 Top Darts +PCSB00791 Top Trumps Turbo +PCSG00902 Torikago no Marriage: Hatsukoi no Tsubasa +PCSA00112 Toro's Friend Network +PCSE00671 TorqueL +PCSB00355 Total Recoil +PCSG00113 Tottemo E Mahjong +PCSG00593 Touch Battle Sensha SP +PCSE00016 Touch My Katamari +PCSB00047 Touch My Katamari +PCSE01015 TOUHOU DOUBLE FOCUS +PCSG00977 Touhou Genso Maroku W: The Devil of Decline +PCSE00990 TOUHOU Genso Wanderer +PCSG00985 Touhou Genso Wanderer TOD -RELOADED- +PCSE01104 Touhou Kobuto V: Burst Battle +PCSG00999 Touhou Koubuto V: Burst Battle +PCSG00752 Touhou Soujinengi V +PCSE00940 Toukiden 2 +PCSG00834 Toukiden 2 co-op version +PCSG00379 Toukiden: Kiwami +PCSB00574 Toukiden: Kiwami +PCSE00467 Toukiden: Kiwami +PCSG00193 Toukiden: The Age of Demons +PCSE00381 Toukiden: The Age of Demons +PCSB00918 Towerfall Ascension +PCSG00488 Trails in the Sky FC Evolution +PCSG00489 Trails In the Sky SC Evolution +PCSA00060 Treasure Park +PCSC80006 Treasure Park +PCSB00422 Treasures of Montezuma Arena +PCSG00515 Trillion : God Of Destruction +PCSB00904 Trillion: God of Destruction +PCSE00813 Trillion: God of Destruction +PCSG01023 Tsuihou Senkyo +PCSG00648 Tsuki ni Yorisou Otome no Sahou: Hidamari no Hibi +PCSG00152 Tsukiei Academy -kou- +PCSG01025 Tsukitomo. Tsukiuta 12 Memories +PCSG01019 Tsumikui: Sen no Noroi, Sen no Inori for V +PCSE01452 Twin Breaker: A Sacred Symbols Adventure +PCSE01081 Twin Robots +PCSE00397 TxK +PCSE00837 Type:Rider +PCSC00080 U-NEXT +PCSG00480 Ukiyo no Roushi +PCSB00070 ULTIMATE MARVEL VS. CAPCOM 3 +PCSG00011 ULTIMATE MARVEL VS. CAPCOM 3 +PCSE00004 ULTIMATE MARVEL VS. CAPCOM 3 +PCSE01487 Ultracore +PCSE00414 Ultratron +PCSG00912 Un:BIRTHDAY SONG: Ai o Utau Shinigami - Another Record +PCSE00822 Uncanny Valley +PCSF00220 Uncharted: Fight for Fortune™ +PCSC00005 UNCHARTED: Golden Abyss +PCSF00001 Uncharted: Golden Abyss™ +PCSF00012 Uncharted: Golden Abyss™ +PCSA00029 Uncharted: Golden Abyss™ +PCSD00001 UNCHARTED: Golden Abyss™ +PCSA00088 Uncharted™ Fight for Fortune +PCSE01144 Under Night In-Birth Exe:Late(st) +PCSG00964 UNDER NIGHT IN-BIRTH Exe:Late[st] +PCSB01157 Undertale +PCSE01116 Undertale +PCSG01112 UNDERTALE +PCSE00840 Unepic +PCSB00841 Unepic +PCSF00034 Unit 13 +PCSA00014 Unit 13™ +PCSH10310 UnMetal +PCSG00633 Uppers +PCSB00038 Urban Trial Freestyle +PCSE00051 Urban Trial Freestyle +PCSG01191 Usotsuki Hime to Moumoku Ouji +PCSG01046 Usotsuki Shangri-La +PCSG00199 Uta Kumi 575 +PCSG00651 Uta no * Prince-Sama: Music 3 +PCSG00914 Uta no * Prince-Sama: Repeat LOVE +PCSG00617 Utawarerumono: Mask of Deception +PCSG00838 Utawarerumono: Mask of Truth (うたわれるもの 二人の白皇) +PCSE01409 Utawarerumono: Prelude to the Fallen +PCSG01011 Utsusemi no Meguri +PCSE00756 VA-11 HALL-A +PCSB01166 VA-11 HALL-A +PCSE01223 VA-11 HALL-A +PCSG01072 VA-11 HALL-A +PCSE00244 Valhalla Knights 3 +PCSG00307 Valhalla Knights 3 Gold +PCSE01003 Valkyria Revolution +PCSB01011 VALKYRIE DRIVE -BHIKKHUNI- +PCSE00948 VALKYRIE DRIVE -BHIKKHUNI- +PCSG00467 Vamwolf Cross† +PCSG01159 Variable Barricade +PCSE01314 VASARA Collection +PCSB01133 Vegas Party +PCSE00712 Velocibox +PCSB00302 Velocity Ultra +PCSE00038 Velocity Ultra +PCSB00410 Velocity®2X +PCSE00374 Velocity®2X +PCSG00531 VENUS PROJECT +PCSE00621 Vertical Drop Heroes HD +PCSB00031 Virtua Tennis 4 +PCSE00003 Virtua Tennis 4 +PCSB00205 Virtue's Last Reward +PCSE00506 Vitamin Z +PCSG01115 VitaminX Destination +PCSE00913 Volgarr the Viking +PCSE00760 Volume +PCSB00810 VVVVVV +PCSG01084 Wagamama High Spec (ワガママハイスペック) +PCSE01266 Waking Violet +PCSG00768 Walpurgis no Uta +PCSG00790 Wand of Fortune R +PCSG00938 Wand of Fortune R2 +PCSE00938 Wanderjahr TryAgainOrWalkAway +PCSE01248 War Theatre +PCSE01045 Warlock's Tower +PCSG01018 Warriors All-Stars +PCSG00209 Warriors Orochi 2 Ultimate +PCSB00873 WE ARE DOOMED +NPXS10007 Welcome Park +PCSC00047 What Did I Do to Deserve This, My Lord? +PCSB00727 Whispering Willows +PCSG00249 White Album 2: Shiawase no Mukougawa +PCSE01032 Windjammers +PCSG00194 Winning Post 7 2013 +PCSG00545 Winning Post 8 2015 +PCSG00804 Winning Post 8 2016 +PCSG01174 Winning Post 8 2018 +PCSF00007 WipEout® 2048 +PCSA00015 WipEout® 2048 +PCSD00005 WipEout® 2048 +PCSE01516 Witchcrafty +PCSE01445 Without Escape +PCSG00511 Wizardry: Torawareshi Bourei no Machi +PCSG00512 Wizardry: Torawareshi Tomashii no Meikyuu +PCSE01432 Wizards of Brandel +PCSE00519 Woah Dave! +PCSE01453 Word Maze by POWGI +PCSH10228 Word Maze by POWGI +PCSB01418 Word Maze by POWGI +PCSE01286 Word Search by POWGI +PCSH10166 Word Search by POWGI +PCSB01267 Word Search by POWGI +PCSH10168 Word Sudoku by POWGI +PCSE01339 Word Sudoku by POWGI +PCSB01307 Word Sudoku by POWGI +PCSH10179 Word Wheel by POWGI +PCSB01367 Word Wheel by POWGI +PCSE01394 Word Wheel by POWGI +PCSH10180 Wordsweeper by POWGI +PCSB01366 Wordsweeper by POWGI +PCSE01395 Wordsweeper by POWGI +PCSG01088 World Election +PCSG01114 World End Syndrome +PCSG00709 World of Final Fantasy +PCSE00880 WORLD OF FINAL FANTASY +PCSG00647 World Trigger Borderless Mission +PCSG00832 World Trigger: Smash Borders +PCSB00332 WORMS REVOLUTION EXTREME +PCSE00286 WORMS REVOLUTION EXTREME +PCSB00204 WRC 3: FIA World Rally Championship +PCSB00345 WRC 4 FIA WORLD RALLY CHAMPIONSHIP +PCSE00667 WRC 5 FIA World Rally Championship +PCSE01477 Wurroom +PCSE00346 XBLAZE CODE : EMBRYO +PCSG00463 XBLAZE LOST : MEMORIES +PCSG00589 XCOM: Enemy Unknown Plus +PCSE01481 Xeno Crisis +PCSE01191 Xenon Valkyrie+ +PCSE00897 Xenoraid +PCSE00694 Xeodrifter™ +PCSG00215 Yahari Game Demo Ore no Seishun Love-Kome wa Machigatteiru. +PCSG00895 Yahari Game Demo Ore no Seishun Love-Kome wa Machigatteiru. Zoku +PCSG00800 Yaken no Rodem +PCSH00147 Yakuza 0! Companion App +PCSG01080 Yomawari: Midnight Shadows +PCSB01144 YOMAWARI: MIDNIGHT SHADOWS +PCSG01120 Yoshiwara Higanbana Kuon no Chigiri +PCSG01267 your diary + +PCSC80010 YouTube +PCSE01033 Ys Origin +PCSH10049 Ys Origins +PCSE01103 Ys VIII -Lacrimosa of DANA- +PCSH00297 Ys VIII -Lacrimosa of DANA- +PCSG00105 Ys: Memories of Celceta +PCSH00181 Ys: Memories of Celceta +PCSG00567 YU-NO: Konoyo no Hate de Koi o Utau Shoujo +PCSE01462 Yumeutsutsu Re:After +PCSG01317 Yumeutsutsu Re:After +PCSG00393 Yumeutsutsu Re:After +PCSE01461 Yumeutsutsu Re:Master +PCSG00653 Yunohana SpRING! +PCSG00909 Yunohana SpRING! ~Cherising Time~ +PCSG00502 Yuuki Yuuna wa Yuusha de Aru: Jukai no Kioku +PCSG01075 Yuukyuu no Tierblade: Fragments of Memory +PCSG00808 Yuukyuu no Tierblade: Lost Chronicle +PCSG00693 Yuusha Shisu +PCSB00390 Z-Run +PCSG90316 Zanki Zero trial version +PCSG01113 Zanki Zero: Last Beginning +PCSB00094 Zen Pinball 2 +PCSE00050 Zen Pinball 2 +PCSG00883 Zero Escape: 9 Jikan 9 nin 9 no Tobira Zennin Shibo Dos Double Pack +PCSE01006 Zero Escape: The Nonary Games +PCSE00085 Zero Escape: Virtue's Last Reward +PCSE00781 Zero Escape: Zero Time Dilemma +PCSE01088 Zero Zero Zero Zero +PCSE01371 Zeroptian Invasion +PCSG00880 Zettai Kaikyuu Gakuen: Eden with Roses and Phantasm +PCSG00611 Zettai Meikyuu: Himitsu no Oyayubi Hime +PCSE00102 Zombie Tycoon 2 : Brainhov's Revenge diff --git a/projects/ArchR/packages/emulators/standalone/yabasanshiro-sa/config/config b/projects/ArchR/packages/emulators/standalone/yabasanshiro-sa/config/config new file mode 100644 index 0000000000..da873a3208 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/yabasanshiro-sa/config/config @@ -0,0 +1,7 @@ +{ + "Aspect rate": 1, + "Resolution": 3, + "Rotate screen": false, + "Rotate screen resolution": 0, + "Use compute shader": false +} diff --git a/projects/ArchR/packages/emulators/standalone/yabasanshiro-sa/config/devices/keymapv2_rg_arc_joypad.json b/projects/ArchR/packages/emulators/standalone/yabasanshiro-sa/config/devices/keymapv2_rg_arc_joypad.json new file mode 100644 index 0000000000..a449d90785 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/yabasanshiro-sa/config/devices/keymapv2_rg_arc_joypad.json @@ -0,0 +1,100 @@ +{ + "0_rg_arc_joypad_1900d632010000002c0a000000010000": { + "a": { + "id": 1, + "type": "button", + "value": 1 + }, + "analogleft": { + "id": 4, + "type": "axis", + "value": 0 + }, + "analogright": { + "id": 5, + "type": "axis", + "value": 0 + }, + "analogx": { + "id": 0, + "type": "axis", + "value": 0 + }, + "analogy": { + "id": 1, + "type": "axis", + "value": 0 + }, + "b": { + "id": 0, + "type": "button", + "value": 1 + }, + "c": { + "id": 2, + "type": "button", + "value": 1 + }, + "down": { + "id": 13, + "type": "button", + "value": 1 + }, + "l": { + "id": 6, + "type": "button", + "value": 1 + }, + "left": { + "id": 14, + "type": "button", + "value": 1 + }, + "r": { + "id": 7, + "type": "button", + "value": 1 + }, + "right": { + "id": 15, + "type": "button", + "value": 1 + }, + "select": { + "id": 10, + "type": "button", + "value": 1 + }, + "start": { + "id": 11, + "type": "button", + "value": 1 + }, + "up": { + "id": 12, + "type": "button", + "value": 1 + }, + "x": { + "id": 3, + "type": "button", + "value": 1 + }, + "y": { + "id": 4, + "type": "button", + "value": 1 + }, + "z": { + "id": 5, + "type": "button", + "value": 1 + } + }, + "player1": { + "DeviceID": 0, + "deviceGUID": "1900d632010000002c0a000000010000", + "deviceName": "rg_arc_joypad", + "padmode": 0 + } +} diff --git a/projects/ArchR/packages/emulators/standalone/yabasanshiro-sa/package.mk b/projects/ArchR/packages/emulators/standalone/yabasanshiro-sa/package.mk new file mode 100644 index 0000000000..09f6525de3 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/yabasanshiro-sa/package.mk @@ -0,0 +1,85 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2022-present 351ELEC +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="yabasanshiro-sa" +PKG_LICENSE="GPLv2" +PKG_SITE="https://github.com/sydarn/yabause" +PKG_URL="${PKG_SITE}.git" +PKG_VERSION="a40dace1ae0af3ebd45848549fdf396f40e3930f" +PKG_GIT_CLONE_BRANCH="pi4-update" +PKG_ARCH="aarch64" +PKG_DEPENDS_TARGET="toolchain SDL2 boost openal-soft zlib" +PKG_LONGDESC="Yabause is a Sega Saturn emulator and took over as Yaba Sanshiro" +PKG_TOOLCHAIN="cmake-make" +GET_HANDLER_SUPPORT="git" +PKG_BUILD_FLAGS="+speed" + +if [ ! "${OPENGL}" = "no" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" +fi + +if [ "${OPENGLES_SUPPORT}" = yes ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" +fi + +if [ "${VULKAN_SUPPORT}" = "yes" ] +then + PKG_DEPENDS_TARGET+=" ${VULKAN}" +fi + +post_unpack() { + # use host versions + sed -i "s|COMMAND m68kmake|COMMAND ${PKG_BUILD}/m68kmake_host|" ${PKG_BUILD}/yabause/src/musashi/CMakeLists.txt + sed -i "s|COMMAND ./bin2c|COMMAND ${PKG_BUILD}/bin2c_host|" ${PKG_BUILD}/yabause/src/retro_arena/nanogui-sdl/CMakeLists.txt + find ${PKG_BUILD} -type f -name "CMakeLists.txt" -exec sed -i 's/^\s*cmake_minimum_required.*$/cmake_minimum_required(VERSION 3.5)/' {} + +} + +pre_make_target() { + # runs on host so make them manually if package is not crosscompile friendly + ${HOST_CC} ${PKG_BUILD}/yabause/src/retro_arena/nanogui-sdl/resources/bin2c.c -o ${PKG_BUILD}/bin2c_host + ${HOST_CC} ${PKG_BUILD}/yabause/src/musashi/m68kmake.c -o ${PKG_BUILD}/m68kmake_host +} + +pre_configure_target() { + PKG_CMAKE_OPTS_TARGET="${PKG_BUILD}/yabause " + + if [ ! "${OPENGL}" = "no" ]; then + PKG_CMAKE_OPTS_TARGET+=" -DUSE_EGL=ON -DUSE_OPENGL=ON" + fi + + if [ "${OPENGLES_SUPPORT}" = yes ]; then + PKG_CMAKE_OPTS_TARGET+=" -DUSE_EGL=ON -DUSE_OPENGL=OFF" + fi + + case ${ARCH} in + aarch64) + PKG_CMAKE_OPTS_TARGET+=" -DYAB_WANT_ARM7=ON \ + -DYAB_WANT_DYNAREC_DEVMIYAX=ON \ + -DYAB_PORTS=retro_arena" + + PKG_CMAKE_OPTS_TARGET+=" -DCMAKE_PROJECT_INCLUDE=${PKG_BUILD}/yabause/src/retro_arena/n2.cmake" + ;; + esac + + PKG_CMAKE_OPTS_TARGET+=" -DCMAKE_SYSTEM_PROCESSOR=x86_64" + + PKG_CMAKE_OPTS_TARGET+=" -DOPENGL_INCLUDE_DIR=${SYSROOT_PREFIX}/usr/include \ + -DOPENGL_opengl_LIBRARY=${SYSROOT_PREFIX}/usr/lib \ + -DOPENGL_glx_LIBRARY=${SYSROOT_PREFIX}/usr/lib \ + -DLIBPNG_LIB_DIR=${SYSROOT_PREFIX}/usr/lib \ + -Dpng_STATIC_LIBRARIES=${SYSROOT_PREFIX}/usr/lib/libpng16.so \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON" +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp -a ${PKG_BUILD}/src/retro_arena/yabasanshiro ${INSTALL}/usr/bin/yabasanshiro + cp -a ${PKG_DIR}/scripts/start_yabasanshiro.sh ${INSTALL}/usr/bin + chmod 0755 ${INSTALL}/usr/bin/start_yabasanshiro.sh + mkdir -p ${INSTALL}/usr/config/yabasanshiro + cp ${PKG_DIR}/config/config ${INSTALL}/usr/config/yabasanshiro/.config + cp -r ${PKG_DIR}/config/devices ${INSTALL}/usr/config/yabasanshiro/ +} diff --git a/projects/ArchR/packages/emulators/standalone/yabasanshiro-sa/patches/02-yabasanshiroSA-use-system-libpng.patch b/projects/ArchR/packages/emulators/standalone/yabasanshiro-sa/patches/02-yabasanshiroSA-use-system-libpng.patch new file mode 100644 index 0000000000..f0e83e2630 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/yabasanshiro-sa/patches/02-yabasanshiroSA-use-system-libpng.patch @@ -0,0 +1,11 @@ +--- a/yabause/src/retro_arena/CMakeLists.txt 2022-01-05 15:44:20.891135756 -0600 ++++ b/yabause/src/retro_arena/CMakeLists.txt 2022-01-05 15:44:41.738849860 -0600 +@@ -22,7 +22,7 @@ + add_subdirectory(nanogui-sdl) + + #include( ../glfw/external_zlib.cmake ) +-include( ${CMAKE_SOURCE_DIR}/CMake/Packages/external_libpng.cmake ) ++#include( ${CMAKE_SOURCE_DIR}/CMake/Packages/external_libpng.cmake ) + + #------------------------------------------------------------------------------ + # nlohmann/json diff --git a/projects/ArchR/packages/emulators/standalone/yabasanshiro-sa/patches/04-yabasanshiroSA-use-paths.patch b/projects/ArchR/packages/emulators/standalone/yabasanshiro-sa/patches/04-yabasanshiroSA-use-paths.patch new file mode 100644 index 0000000000..045abed6d4 --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/yabasanshiro-sa/patches/04-yabasanshiroSA-use-paths.patch @@ -0,0 +1,93 @@ +diff --git a/yabause/src/retro_arena/InputManager.cpp b/yabause/src/retro_arena/InputManager.cpp +index bd806736..c32af4a7 100644 +--- a/yabause/src/retro_arena/InputManager.cpp ++++ b/yabause/src/retro_arena/InputManager.cpp +@@ -213,7 +213,7 @@ int mapKeys( const json & configs ){ + + if( SDL_NumJoysticks() == 0 ){ + +- PADLOG("No joy stic is found force to keyboard\n"); ++ PADLOG("No joystick is found force to keyboard\n"); + padbits = PerPadAdd(&PORTDATA1); + if( configs.find("player1") == configs.end() ){ + return setDefalutSettings(padbits); +@@ -460,22 +460,22 @@ int getPlayerJsonFromInputConfig( int joy, InputConfig * inputconfig, json & pla + } + + Input result; +- inputconfig->getInputByName("a", &result); ++ inputconfig->getInputByName("y", &result); + player[guid]["a"] ={ { "type", input_types[result.type] },{ "id", result.id },{ "value", result.value } }; + + inputconfig->getInputByName("b", &result); + player[guid]["b"] = { { "type", input_types[result.type] },{ "id", result.id },{ "value", result.value } }; + +- inputconfig->getInputByName("rightshoulder", &result); ++ inputconfig->getInputByName("a", &result); + player[guid]["c"] = { { "type", input_types[result.type] },{ "id", result.id },{ "value", result.value } } ; + + inputconfig->getInputByName("x", &result); + player[guid]["x"] = { { "type", input_types[result.type] },{ "id", result.id },{ "value", result.value } }; + +- inputconfig->getInputByName("y", &result); ++ inputconfig->getInputByName("leftshoulder", &result); + player[guid]["y"] = { { "type", input_types[result.type] },{ "id", result.id },{ "value", result.value } }; + +- inputconfig->getInputByName("leftshoulder", &result); ++ inputconfig->getInputByName("rightshoulder", &result); + player[guid]["z"] = { { "type", input_types[result.type] },{ "id", result.id },{ "value", result.value } }; + + inputconfig->getInputByName("lefttrigger", &result); +@@ -1209,7 +1209,7 @@ void InputManager::writeDeviceConfig(InputConfig* config) + std::string InputManager::getConfigPath() + { + std::string path = getenv("HOME"); +- path += "/.emulationstation/es_temporaryinput.cfg"; ++ path = "/storage/.config/yabasanshiro/input.cfg"; + return path; + } + +diff --git a/yabause/src/retro_arena/Preference.cpp b/yabause/src/retro_arena/Preference.cpp +index 1108c843..49815002 100644 +--- a/yabause/src/retro_arena/Preference.cpp ++++ b/yabause/src/retro_arena/Preference.cpp +@@ -17,7 +17,7 @@ Preference::Preference( const std::string & filename ){ + } + + std::string home_dir = getenv("HOME"); +- home_dir += "/.yabasanshiro/"; ++ home_dir = "/storage/.config/yabasanshiro/"; + + this->filename = home_dir + input_trace_filename + ".config"; + +diff --git a/yabause/src/retro_arena/main.cpp b/yabause/src/retro_arena/main.cpp +index 3b3b581c..dacfee8e 100644 +--- a/yabause/src/retro_arena/main.cpp ++++ b/yabause/src/retro_arena/main.cpp +@@ -290,14 +290,14 @@ int main(int argc, char** argv) + + // Inisialize home directory + std::string home_dir = getenv("HOME"); +- home_dir += "/.yabasanshiro/"; ++ home_dir = "/storage/.config/yabasanshiro/"; + struct stat st = {0}; + if (stat(home_dir.c_str(), &st) == -1) { + mkdir(home_dir.c_str(), 0700); + } +- std::string bckup_dir = home_dir + "backup.bin"; ++ std::string bckup_dir = "/storage/roms/bios/yabasanshiro/backup.bin"; + strcpy( buppath, bckup_dir.c_str() ); +- strcpy( s_savepath, home_dir.c_str() ); ++ strcpy( s_savepath, "/storage/roms/savestates/saturn/yabasanshiro/" ); + g_keymap_filename = home_dir + "keymapv2.json"; + + std::string current_exec_name = argv[0]; // Name of the current exec program +@@ -601,7 +601,7 @@ int main(int argc, char** argv) + if( ret == 0 ){ + char pngname[256]; + snprintf(pngname,256,"%s/%s_%d.png", s_savepath, cdip->itemnum, e.user.code); +- fs::copy(tmpfilename, pngname, fs::copy_options::overwrite_existing ); ++ system((std::string("cp -f ") + tmpfilename + " " + pngname).c_str()); + } + hideMenuScreen(); + } diff --git a/projects/ArchR/packages/emulators/standalone/yabasanshiro-sa/patches/05-cmake-fixes.patch b/projects/ArchR/packages/emulators/standalone/yabasanshiro-sa/patches/05-cmake-fixes.patch new file mode 100644 index 0000000000..666fa1426f --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/yabasanshiro-sa/patches/05-cmake-fixes.patch @@ -0,0 +1,49 @@ +--- a/yabause/src/retro_arena/CMakeLists.txt ++++ b/yabause/src/retro_arena/CMakeLists.txt +@@ -1,4 +1,5 @@ + project(yabause-retro-arena) ++cmake_minimum_required(VERSION 3.5) + + add_definitions( -D__RETORO_ARENA__ ) + +@@ -62,7 +63,7 @@ + target_link_libraries(yabause-retro-arena yabause ${Boost_LIBRARIES} pugixml ${YABAUSE_LIBRARIES} ${PORT_LIBRARIES} nanogui stdc++fs ${LIBCHDR_LIBRARIES} ) + target_link_libraries( yabause-retro-arena ${LIBCHDR_LIBRARIES} ) + target_link_libraries( yabause-retro-arena ${zlib_STATIC_LIBRARIES} ) +-add_dependencies(yabause-retro-arena Json png zlib libchd ) ++add_dependencies(yabause-retro-arena Json zlib ) + yab_port_success(yabause-retro-arena) + set_target_properties(yabause-retro-arena PROPERTIES OUTPUT_NAME yabasanshiro) + +--- a/yabause/CMake/Packages/external_zlib.cmake ++++ b/yabause/CMake/Packages/external_zlib.cmake +@@ -69,6 +69,7 @@ + -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON + -DCMAKE_BUILD_TYPE:STRING=Release + -DCMAKE_INSTALL_PREFIX:STRING=${ZLIB_INSTALL} ++ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 + ${ADDITIONAL_CMAKE_ARGS} + ) + +--- a/yabause/CMake/Packages/external_libchdr.cmake ++++ b/yabause/CMake/Packages/external_libchdr.cmake +@@ -36,6 +36,7 @@ + -DCMAKE_BUILD_TYPE:STRING=Release + -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} + -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} ++ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 + ${ADDITIONAL_CMAKE_ARGS} + ) + +--- a/yabause/src/retro_arena/CMakeLists.txt ++++ b/yabause/src/retro_arena/CMakeLists.txt +@@ -33,7 +33,8 @@ + ExternalProject_Add( + Json + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/Json +- URL https://github.com/nlohmann/json/archive/v3.2.0.zip ++ GIT_REPOSITORY "https://github.com/nlohmann/json.git" ++ GIT_TAG "359f98d14065bf4e53eeb274f5987fd08f16e5bf" + #disable following + CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_DIR "" INSTALL_COMMAND "" + ) diff --git a/projects/ArchR/packages/emulators/standalone/yabasanshiro-sa/scripts/start_yabasanshiro.sh b/projects/ArchR/packages/emulators/standalone/yabasanshiro-sa/scripts/start_yabasanshiro.sh new file mode 100644 index 0000000000..193b477dfc --- /dev/null +++ b/projects/ArchR/packages/emulators/standalone/yabasanshiro-sa/scripts/start_yabasanshiro.sh @@ -0,0 +1,112 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2021-present Shanti Gilbert (https://github.com/shantigilbert) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Source predefined functions and variables +. /etc/profile +set_kill set "-9 yabasanshiro" + +ROM_DIR="/storage/roms/saturn/yabasanshiro" +CONFIG_DIR="/storage/.config/yabasanshiro" +SOURCE_DIR="/usr/config/yabasanshiro" +BIOS_BACKUP="/storage/roms/bios/yabasanshiro" +SAVESTATE_DIR="/storage/roms/savestates/saturn/yabasanshiro/" + +if [ ! -d "${ROM_DIR}" ] +then + mkdir -p "${ROM_DIR}" +fi + +if [ ! -d "${BIOS_BACKUP}" ] +then + mkdir -p "${BIOS_BACKUP}" +fi + +if [ ! -d "${CONFIG_DIR}" ] +then + mkdir -p "${CONFIG_DIR}" +fi + +if [ ! -d "${SAVESTATE_DIR}" ] +then + mkdir -p "${SAVESTATE_DIR}" +fi + +if [ ! -e "${CONFIG_DIR}/input.cfg" ] +then + rm -f ${CONFIG_DIR}/keymapv2.json + + # Handle inputplumber platforms first + if [[ "${HW_DEVICE}" =~ SM8550|SM8650 ]]; then + GAMEPAD="'InputPlumber GameController'" + else + # Check for js0, else fall back to joypad + if grep -q "js0" /proc/bus/input/devices; then + GAMEPAD="'$(grep -b4 js0 /proc/bus/input/devices | awk 'BEGIN {FS="\""}; /Name/ {printf $2}')'" + else + GAMEPAD="'$(grep -b4 joypad /proc/bus/input/devices | awk 'BEGIN {FS="\""}; /Name/ {printf $2}')'" + fi + fi + + GAMEPADCONFIG=$(xmlstarlet sel -t -c "//inputList/inputConfig[@deviceName=${GAMEPAD}]" -n /storage/.emulationstation/es_input.cfg) + + MAPPING_FILE="/usr/config/yabasanshiro/devices/keymapv2_$(eval echo $GAMEPAD).json" + if [ -e "${MAPPING_FILE}" ]; then + cp ${MAPPING_FILE} ${CONFIG_DIR}/keymapv2.json + fi + + if [ ! -z "${GAMEPADCONFIG}" ] + then + cat <${CONFIG_DIR}/input.cfg + + +${GAMEPADCONFIG} + +EOF + fi +fi + +BIOS="" +GAME=$(echo "${1}"| sed "s#^/.*/##") +PLATFORM=$(echo "${2}"| sed "s#^/.*/##") +USE_BIOS=$(get_setting use_hlebios "${PLATFORM}" "${GAME}") +if [ ! "${USE_BIOS}" = 1 ] +then + USE_BIOS=$(get_setting use_hlebios "${PLATFORM}") +fi + +if [ "$USE_BIOS" = 1 ] +then + for BIOS in saturn_bios.bin sega_101.bin mpr-17933.bin mpr-18811-mx.ic1 mpr-19367-mx.ic1 stvbios.zip + do + BIOS=$(find /storage/roms/bios -name ${BIOS} -print 2>/dev/null) + if [ ! -z "${BIOS}" ] + then + BIOS="-b ${BIOS}" + break + fi + done +fi + +if [ ! -e "${CONFIG_DIR}/${GAME}.config" ] +then + cp -f ${SOURCE_DIR}/.config "${CONFIG_DIR}/${GAME}.config" +fi + +#Set the cores to use +CORES=$(get_setting "cores" "${PLATFORM}" "${GAME}") +if [ "${CORES}" = "little" ] +then + EMUPERF="${SLOW_CORES}" +elif [ "${CORES}" = "big" ] +then + EMUPERF="${FAST_CORES}" +else + ### All.. + unset EMUPERF +fi + +echo "Command: yabasanshiro -r 2 -i "${1}" ${BIOS}" >>/var/log/exec.log 2>&1 +${EMUPERF} yabasanshiro -r 2 -i "${1}" ${BIOS} >>/var/log/exec.log 2>&1 ||: diff --git a/projects/ArchR/packages/fonts/dejavu/package.mk b/projects/ArchR/packages/fonts/dejavu/package.mk new file mode 100644 index 0000000000..8ad673df39 --- /dev/null +++ b/projects/ArchR/packages/fonts/dejavu/package.mk @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2025-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="dejavu" +PKG_VERSION="2.37" +PKG_LICENSE="Bitstream" +PKG_SITE="https://sourceforge.net/projects/dejavu/files/dejavu/${PKG_VERSION}" +PKG_URL="${PKG_SITE}/${PKG_NAME}-fonts-ttf-${PKG_VERSION}.tar.bz2" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="The DejaVu fonts are a font family based upon Bitstream Vera v1.10." +PKG_TOOLCHAIN="manual" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/share/fonts/truetype/dejavu/ + cp -rf ${PKG_BUILD}/ttf/DejaVuSansCondensed.ttf ${INSTALL}/usr/share/fonts/truetype/dejavu/ +} diff --git a/projects/ArchR/packages/fonts/spleen-font/package.mk b/projects/ArchR/packages/fonts/spleen-font/package.mk new file mode 100644 index 0000000000..e61fd604bd --- /dev/null +++ b/projects/ArchR/packages/fonts/spleen-font/package.mk @@ -0,0 +1,58 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="spleen-font" +PKG_VERSION="2.0.0" +PKG_LICENSE="BSD-2-Clause" +PKG_SITE="https://github.com/fcambus/spleen" +PKG_URL="${PKG_SITE}/releases/download/${PKG_VERSION}/spleen-${PKG_VERSION}.tar.gz" + +PKG_DEPENDS_INIT="toolchain bdf2psf:host" +PKG_DEPENDS_TARGET="toolchain bdf2psf:host" +PKG_LONGDESC="This package contains the Spleen Font" +PKG_TOOLCHAIN="manual" + +pre_configure_init() { + cd ${PKG_BUILD} + rm -rf .${TARGET_NAME}-${TARGET} +} + +pre_configure_target() { + cd ${PKG_BUILD} + rm -rf .${TARGET_NAME}-${TARGET} +} + +configure_init() { + : +} + +configure_target() { + : +} + +make_init() { + for font in spleen-5x8 spleen-6x12 + do + ${TOOLCHAIN}/usr/bin/bdf2psf --fb \ + ${font}.bdf \ + ${TOOLCHAIN}/usr/share/bdf2psf/standard.equivalents \ + ${TOOLCHAIN}/usr/share/bdf2psf/ascii.set+${TOOLCHAIN}/usr/share/bdf2psf/linux.set+${TOOLCHAIN}/usr/share/bdf2psf/useful.set 512 \ + ${font}.psfu + done +} + +make_target() { + make_init +} + +makeinstall_init() { + mkdir -p ${INSTALL}/usr/share/consolefonts + cp -rf *.bdf ${INSTALL}/usr/share/consolefonts + cp -rf *.psfu ${INSTALL}/usr/share/consolefonts +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/share/consolefonts + cp -rf ${PKG_BUILD}/*.bdf ${INSTALL}/usr/share/consolefonts + cp -rf ${PKG_BUILD}/*.psfu ${INSTALL}/usr/share/consolefonts +} diff --git a/projects/ArchR/packages/fonts/spleen-font/patches/001-add-block.patch b/projects/ArchR/packages/fonts/spleen-font/patches/001-add-block.patch new file mode 100644 index 0000000000..9ec92a559c --- /dev/null +++ b/projects/ArchR/packages/fonts/spleen-font/patches/001-add-block.patch @@ -0,0 +1,59 @@ +diff -rupN spleen-2.0.0.orig/spleen-5x8.bdf spleen-2.0.0/spleen-5x8.bdf +--- spleen-2.0.0.orig/spleen-5x8.bdf 2023-10-17 11:29:44.898274937 +0000 ++++ spleen-2.0.0/spleen-5x8.bdf 2023-10-17 12:21:00.033250208 +0000 +@@ -37,7 +37,7 @@ COPYRIGHT "Copyright (c) 2018-2023, Fred + DEFAULT_CHAR 32 + _GBDFED_INFO "Edited with gbdfed 1.6." + ENDPROPERTIES +-CHARS 472 ++CHARS 473 + STARTCHAR SPACE + ENCODING 32 + SWIDTH 625 0 +@@ -7118,4 +7118,19 @@ BITMAP + 20 + 10 + ENDCHAR ++STARTCHAR FULL BLOCK ++ENCODING 9608 ++SWIDTH 625 0 ++DWIDTH 5 0 ++BBX 5 8 0 -1 ++BITMAP ++FF ++FF ++FF ++FF ++FF ++FF ++FF ++FF ++ENDCHAR + ENDFONT +diff -rupN spleen-2.0.0.orig/spleen-6x12.bdf spleen-2.0.0/spleen-6x12.bdf +--- spleen-2.0.0.orig/spleen-6x12.bdf 2023-10-17 11:29:44.898274937 +0000 ++++ spleen-2.0.0/spleen-6x12.bdf 2023-10-17 12:22:31.486063337 +0000 +@@ -9006,4 +9006,23 @@ BITMAP + 08 + 04 + ENDCHAR ++STARTCHAR FULL BLOCK ++ENCODING 9608 ++SWIDTH 500 0 ++DWIDTH 6 0 ++BBX 6 12 0 -3 ++BITMAP ++FF ++FF ++FF ++FF ++FF ++FF ++FF ++FF ++FF ++FF ++FF ++FF ++ENDCHAR + ENDFONT diff --git a/projects/ArchR/packages/graphics/SDL2/package.mk b/projects/ArchR/packages/graphics/SDL2/package.mk new file mode 100644 index 0000000000..88660fbc57 --- /dev/null +++ b/projects/ArchR/packages/graphics/SDL2/package.mk @@ -0,0 +1,153 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2018-present 5schatten (https://github.com/5schatten) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="SDL2" +PKG_VERSION="2.32.10" +PKG_LICENSE="GPL" +PKG_SITE="https://www.libsdl.org/" +PKG_URL="https://www.libsdl.org/release/SDL2-${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain alsa-lib systemd dbus pulseaudio libdrm SDL2:host" +PKG_LONGDESC="Simple DirectMedia Layer is a cross-platform development library designed to provide low level access to audio, keyboard, mouse, joystick, and graphics hardware." +PKG_DEPENDS_HOST="toolchain:host distutilscross:host" + +if [ ! "${OPENGL_SUPPORT}" = "no" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL} glu" + PKG_CMAKE_OPTS_TARGET+=" -DSDL_OPENGL=ON \ + -DVIDEO_OPENGL=ON \ + -DVIDEO_KMSDRM=OFF" + if [ "${PREFER_GLES}" = "yes" ] && [ "${OPENGLES_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" SDL2_glesonly " + fi +else + PKG_CMAKE_OPTS_TARGET+=" -DSDL_OPENGL=OFF \ + -DVIDEO_OPENGL=OFF \ + -DVIDEO_KMSDRM=OFF" +fi + +if [ "${OPENGLES_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" + PKG_CMAKE_OPTS_TARGET+=" -DSDL_OPENGLES=ON \ + -DVIDEO_OPENGLES=ON \ + -DVIDEO_KMSDRM=ON" +else + PKG_CMAKE_OPTS_TARGET+=" -DSDL_OPENGLES=OFF \ + -DVIDEO_OPENGLES=OFF \ + -DVIDEO_KMSDRM=OFF" +fi + +if [ "${VULKAN_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${VULKAN}" + PKG_CMAKE_OPTS_TARGET+=" -DSDL_VULKAN=ON \ + -DVIDEO_OPENGL=OFF \ + -DVIDEO_VULKAN=ON" +else + PKG_CMAKE_OPTS_TARGET+=" -DSDL_VULKAN=OFF \ + -DVIDEO_VULKAN=OFF" +fi + +if [ "${DISPLAYSERVER}" = "wl" ] +then + PKG_DEPENDS_TARGET+=" wayland " + case ${ARCH} in + arm) + true + ;; + *) + PKG_DEPENDS_TARGET+=" ${WINDOWMANAGER}" + ;; + esac + PKG_CMAKE_OPTS_TARGET+=" -DSDL_WAYLAND=ON \ + -DVIDEO_WAYLAND=ON \ + -DVIDEO_WAYLAND_QT_TOUCH=ON \ + -DWAYLAND_SHARED=ON \ + -DVIDEO_X11=OFF \ + -DSDL_X11=OFF" +else + PKG_CMAKE_OPTS_TARGET+=" -DVIDEO_WAYLAND=OFF \ + -DVIDEO_WAYLAND_QT_TOUCH=ON \ + -DWAYLAND_SHARED=OFF \ + -DVIDEO_X11=OFF \ + -DSDL_X11=OFF" +fi + +case ${DEVICE} in + RK*) + PKG_DEPENDS_TARGET+=" librga" + PKG_PATCH_DIRS_TARGET+="${DEVICE}" + ;; +esac + +pre_configure_target(){ + + if [ -n "${PKG_PATCH_DIRS_TARGET}" ] + then + ### + ### Patching here is necessary to allow SDL2 to be built for + ### use by host builds without requiring additional unnecessary + ### packages to also be built (and break) during the build. + ### + ### It may be better served as a hook in scripts/build. + ### + + if [ -d "${PKG_DIR}/patches/${PKG_PATCH_DIRS_TARGET}" ] + then + cd $(get_build_dir SDL2) + for PATCH in ${PKG_DIR}/patches/${PKG_PATCH_DIRS_TARGET}/* + do + patch -p1 <${PATCH} + done + cd - + fi + + ### End + fi + + export LDFLAGS="${LDFLAGS} -ludev" + PKG_CMAKE_OPTS_TARGET+="-DSDL_STATIC=OFF \ + -DLIBC=ON \ + -DGCC_ATOMICS=ON \ + -DALTIVEC=OFF \ + -DOSS=OFF \ + -DALSA=ON \ + -DALSA_SHARED=ON \ + -DJACK=OFF \ + -DJACK_SHARED=OFF \ + -DESD=OFF \ + -DESD_SHARED=OFF \ + -DARTS=OFF \ + -DARTS_SHARED=OFF \ + -DNAS=OFF \ + -DNAS_SHARED=OFF \ + -DLIBSAMPLERATE=OFF \ + -DLIBSAMPLERATE_SHARED=OFF \ + -DSNDIO=OFF \ + -DDISKAUDIO=OFF \ + -DDUMMYAUDIO=OFF \ + -DVIDEO_X11=OFF \ + -DVIDEO_MIR=OFF \ + -DMIR_SHARED=OFF \ + -DVIDEO_COCOA=OFF \ + -DVIDEO_DIRECTFB=OFF \ + -DVIDEO_VIVANTE=OFF \ + -DDIRECTFB_SHARED=OFF \ + -DFUSIONSOUND=OFF \ + -DFUSIONSOUND_SHARED=OFF \ + -DVIDEO_DUMMY=OFF \ + -DINPUT_TSLIB=ON \ + -DSDL_HIDAPI_JOYSTICK=ON \ + -DPTHREADS=ON \ + -DPTHREADS_SEM=ON \ + -DDIRECTX=OFF \ + -DSDL_DLOPEN=ON \ + -DCLOCK_GETTIME=OFF \ + -DSDL_RPATH=OFF \ + -DRENDER_D3D=OFF \ + -DPIPEWIRE=ON \ + -DPULSEAUDIO=ON" +} + +post_makeinstall_target() { + sed -e "s:\(['=LI]\)/usr:\\1${SYSROOT_PREFIX}/usr:g" -i ${SYSROOT_PREFIX}/usr/bin/sdl2-config + rm -rf ${INSTALL}/usr/bin +} diff --git a/projects/ArchR/packages/graphics/SDL2/patches/0006-drm-resolution.patch b/projects/ArchR/packages/graphics/SDL2/patches/0006-drm-resolution.patch new file mode 100644 index 0000000000..f6243af65e --- /dev/null +++ b/projects/ArchR/packages/graphics/SDL2/patches/0006-drm-resolution.patch @@ -0,0 +1,70 @@ +From 2b837f662b12330e2d5afa867f1b6c1476b93102 Mon Sep 17 00:00:00 2001 +From: JohnnyonFlame +Date: Tue, 8 Aug 2023 04:01:53 -0300 +Subject: [PATCH 6/7] drm resolution + +--- + src/video/kmsdrm/SDL_kmsdrmvideo.c | 39 +++++++++++++++++++++++++++++- + 1 file changed, 38 insertions(+), 1 deletion(-) + +diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.c b/src/video/kmsdrm/SDL_kmsdrmvideo.c +index 663c4707c..39eff8c1d 100644 +--- a/src/video/kmsdrm/SDL_kmsdrmvideo.c ++++ b/src/video/kmsdrm/SDL_kmsdrmvideo.c +@@ -842,6 +842,24 @@ static void KMSDRM_AddDisplay(_THIS, drmModeConnector *connector, drmModeRes *re + goto cleanup; + } + ++ // batocera - set resolution ++ { ++ FILE* fdDrmMode; ++ int drmMode; ++ if((fdDrmMode = fopen("/var/run/drmMode", "r")) != NULL) { ++ if(fscanf(fdDrmMode, "%i", &drmMode) == 1) { ++ if(drmMode>=0 && drmModecount_modes) { ++ drmModeCrtc *pcrtc = KMSDRM_drmModeGetCrtc(viddata->drm_fd, encoder->crtc_id); ++ if(pcrtc != NULL) { ++ KMSDRM_drmModeSetCrtc(viddata->drm_fd, pcrtc->crtc_id, pcrtc->buffer_id, 0, 0, &connector->connector_id, 1, &connector->modes[drmMode]); ++ } ++ } ++ } ++ fclose(fdDrmMode); ++ } ++ } ++ // ++ + /* Try to find a CRTC connected to this encoder */ + crtc = KMSDRM_drmModeGetCrtc(viddata->drm_fd, encoder->crtc_id); + +@@ -1383,8 +1401,27 @@ void KMSDRM_GetDisplayModes(_THIS, SDL_VideoDisplay *display) + SDL_DisplayMode mode; + int i; + ++ // batocera ++ int wantedMode = 0; ++ { ++ FILE* fdDrmMode; ++ int drmMode; ++ if((fdDrmMode = fopen("/var/run/drmMode", "r")) != NULL) { ++ if(fscanf(fdDrmMode, "%i", &drmMode) == 1) { ++ if(drmMode>=0 && drmModecount_modes) { ++ wantedMode = drmMode; ++ } ++ } ++ fclose(fdDrmMode); ++ } ++ } ++ // ++ + for (i = 0; i < conn->count_modes; i++) { +- SDL_DisplayModeData *modedata = SDL_calloc(1, sizeof(SDL_DisplayModeData)); ++ SDL_DisplayModeData *modedata; ++ if(i != wantedMode) continue; // batocera ++ ++ modedata = SDL_calloc(1, sizeof(SDL_DisplayModeData)); + + if (modedata) { + modedata->mode_index = i; +-- +2.20.1 + diff --git a/projects/ArchR/packages/graphics/SDL2/patches/0007-Support-building-without-hacky-libmali-headers.patch b/projects/ArchR/packages/graphics/SDL2/patches/0007-Support-building-without-hacky-libmali-headers.patch new file mode 100644 index 0000000000..239a3db4aa --- /dev/null +++ b/projects/ArchR/packages/graphics/SDL2/patches/0007-Support-building-without-hacky-libmali-headers.patch @@ -0,0 +1,30 @@ +From 35a4dd0e48a82d90157e92c49dc87202a31d4c1c Mon Sep 17 00:00:00 2001 +From: JohnnyonFlame +Date: Tue, 8 Aug 2023 23:40:52 -0300 +Subject: [PATCH 7/7] Support building without hacky libmali headers. + +--- + src/video/kmsdrm/SDL_kmsdrmmouse.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/src/video/kmsdrm/SDL_kmsdrmmouse.c b/src/video/kmsdrm/SDL_kmsdrmmouse.c +index 5dcaaaab6..fe17964a9 100644 +--- a/src/video/kmsdrm/SDL_kmsdrmmouse.c ++++ b/src/video/kmsdrm/SDL_kmsdrmmouse.c +@@ -109,6 +109,13 @@ void KMSDRM_CreateCursorBO(SDL_VideoDisplay *display) + dispdata->cursor_w, dispdata->cursor_h, + GBM_FORMAT_ARGB8888, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE | GBM_BO_USE_LINEAR); + ++ // GBM_BO_USE_LINEAR not supported on mali... retry when this fails. ++ if (!dispdata->cursor_bo) { ++ dispdata->cursor_bo = KMSDRM_gbm_bo_create(viddata->gbm_dev, ++ dispdata->cursor_w, dispdata->cursor_h, ++ GBM_FORMAT_ARGB8888, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE); ++ } ++ + if (!dispdata->cursor_bo) { + SDL_SetError("Could not create GBM cursor BO"); + return; +-- +2.20.1 + diff --git a/projects/ArchR/packages/graphics/SDL2/patches/0008-shutdown-audio-streams-immediately.patch b/projects/ArchR/packages/graphics/SDL2/patches/0008-shutdown-audio-streams-immediately.patch new file mode 100644 index 0000000000..a00e338beb --- /dev/null +++ b/projects/ArchR/packages/graphics/SDL2/patches/0008-shutdown-audio-streams-immediately.patch @@ -0,0 +1,36 @@ +diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c +index 96586fe..2996b37 100644 +--- a/src/audio/SDL_audio.c ++++ b/src/audio/SDL_audio.c +@@ -791,7 +791,7 @@ static int SDLCALL SDL_RunAudio(void *userdata) + } + + /* Wait for the audio to drain. */ +- SDL_Delay(((device->spec.samples * 1000) / device->spec.freq) * 2); ++// SDL_Delay(((device->spec.samples * 1000) / device->spec.freq) * 2); + + current_audio.impl.ThreadDeinit(device); + +diff --git a/src/audio/alsa/SDL_alsa_audio.c b/src/audio/alsa/SDL_alsa_audio.c +index 3ed66f2..b57fe66 100644 +--- a/src/audio/alsa/SDL_alsa_audio.c ++++ b/src/audio/alsa/SDL_alsa_audio.c +@@ -454,12 +454,12 @@ static void ALSA_FlushCapture(_THIS) + static void ALSA_CloseDevice(_THIS) + { + if (this->hidden->pcm_handle) { +- /* Wait for the submitted audio to drain +- ALSA_snd_pcm_drop() can hang, so don't use that. +- */ +- Uint32 delay = ((this->spec.samples * 1000) / this->spec.freq) * 2; +- SDL_Delay(delay); +- ++// /* Wait for the submitted audio to drain ++// ALSA_snd_pcm_drop() can hang, so don't use that. ++// */ ++// Uint32 delay = ((this->spec.samples * 1000) / this->spec.freq) * 2; ++// SDL_Delay(delay); ++// + ALSA_snd_pcm_close(this->hidden->pcm_handle); + } + SDL_free(this->hidden->mixbuf); diff --git a/projects/ArchR/packages/graphics/SDL2/patches/0009-fix-snd-pcm-build.patch b/projects/ArchR/packages/graphics/SDL2/patches/0009-fix-snd-pcm-build.patch new file mode 100644 index 0000000000..f33055976a --- /dev/null +++ b/projects/ArchR/packages/graphics/SDL2/patches/0009-fix-snd-pcm-build.patch @@ -0,0 +1,12 @@ +diff -rupbN SDL2.orig/src/audio/alsa/SDL_alsa_audio.c SDL2/src/audio/alsa/SDL_alsa_audio.c +--- SDL2.orig/src/audio/alsa/SDL_alsa_audio.c 2025-09-03 13:22:21.517704691 +0000 ++++ SDL2/src/audio/alsa/SDL_alsa_audio.c 2025-09-03 13:23:53.115252598 +0000 +@@ -88,7 +88,7 @@ static const char *(*ALSA_snd_pcm_info_g + static int (*ALSA_snd_pcm_info_get_card)(const snd_pcm_info_t *); + static int (*ALSA_snd_card_get_name)(int, char **); + static int (*ALSA_snd_pcm_info_malloc)(snd_pcm_info_t **); +-static int (*ALSA_snd_pcm_info_free)(snd_pcm_info_t *); ++static void (*ALSA_snd_pcm_info_free)(snd_pcm_info_t *); + #ifdef SND_CHMAP_API_VERSION + static snd_pcm_chmap_t *(*ALSA_snd_pcm_get_chmap)(snd_pcm_t *); + static int (*ALSA_snd_pcm_chmap_print)(const snd_pcm_chmap_t *map, size_t maxlen, char *buf); diff --git a/projects/ArchR/packages/graphics/SDL2_glesonly/package.mk b/projects/ArchR/packages/graphics/SDL2_glesonly/package.mk new file mode 100644 index 0000000000..e4b9395d9a --- /dev/null +++ b/projects/ArchR/packages/graphics/SDL2_glesonly/package.mk @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Inherit nearly everything +OPENGL_SUPPORT=no +. $(get_pkg_directory SDL2)/package.mk + +PKG_NAME="SDL2_glesonly" +PKG_DEPENDS_UNPACK+=" SDL2" + +makeinstall_target() { + mkdir -p "${INSTALL}/usr/lib/glesonly" + cp -a libSDL2-2.0.so.0.* "${INSTALL}/usr/lib/glesonly/" +} + +post_makeinstall_target() { + : +} diff --git a/projects/ArchR/packages/graphics/SDL2_glesonly/patches b/projects/ArchR/packages/graphics/SDL2_glesonly/patches new file mode 120000 index 0000000000..f42cfa14ca --- /dev/null +++ b/projects/ArchR/packages/graphics/SDL2_glesonly/patches @@ -0,0 +1 @@ +../SDL2/patches/ \ No newline at end of file diff --git a/projects/ArchR/packages/graphics/cairo/package.mk b/projects/ArchR/packages/graphics/cairo/package.mk new file mode 100644 index 0000000000..32f4462de0 --- /dev/null +++ b/projects/ArchR/packages/graphics/cairo/package.mk @@ -0,0 +1,60 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2019-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="cairo" +PKG_VERSION="1.17.8" +PKG_SHA256="5b10c8892d1b58d70d3f0ba5b47863a061262fa56b9dc7944161f8c8b783bc64" +PKG_LICENSE="LGPL" +PKG_SITE="https://cairographics.org/" +PKG_URL="https://cairographics.org/snapshots/${PKG_NAME}-${PKG_VERSION}.tar.xz" +PKG_DEPENDS_TARGET="toolchain zlib freetype fontconfig glib libpng pixman" +PKG_LONGDESC="Cairo is a vector graphics library with cross-device output support." + +configure_package() { + if [ "${OPENGL}" != "no" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL}" + fi + + if [ "${OPENGLES}" != "no" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" + fi + + case ${DISPLAYSERVER} in + "x11"|"wl") + PKG_DEPENDS_TARGET+=" libxcb libXrender libX11 mesa" + ;; + esac + +} + +pre_configure_target() { + PKG_MESON_OPTS_TARGET="-Ddwrite=disabled \ + -Dfontconfig=enabled \ + -Dfreetype=enabled \ + -Dpng=enabled \ + -Dquartz=disabled \ + -Dtee=disabled \ + -Dtests=disabled \ + -Dxml=disabled \ + -Dzlib=enabled \ + -Dgtk2-utils=disabled \ + -Dglib=enabled \ + -Dspectre=disabled \ + -Dsymbol-lookup=disabled \ + -Dgtk_doc=false" + + case ${DISPLAYSERVER} in + "x11"|"wl") + PKG_MESON_OPTS_TARGET+=" -Dxlib=enabled \ + -Dxcb=enabled \ + -Dxlib-xcb=enabled" + ;; + *) + PKG_MESON_OPTS_TARGET+=" -Dxlib=disabled \ + -Dxcb=disabled \ + -Dxlib-xcb=disabled" + ;; + esac + sed -i "s~'ipc_rmid_deferred_release', 'auto'~'ipc_rmid_deferred_release', 'true'~g" ${PKG_BUILD}/meson.build +} diff --git a/projects/ArchR/packages/graphics/capsimg/package.mk b/projects/ArchR/packages/graphics/capsimg/package.mk new file mode 100644 index 0000000000..dadd7e4806 --- /dev/null +++ b/projects/ArchR/packages/graphics/capsimg/package.mk @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2018-present Frank Hartung (supervisedthinking (@) gmail.com) + +PKG_NAME="capsimg" +PKG_VERSION="ed4cb0912fb1a2a0d5203111c6f6abd50d411b56" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/FrodeSolheim/capsimg" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="SPS Decoder Library 5.1 (formerly IPF Decoder Lib)" +PKG_TOOLCHAIN="make" +PKG_PATCH_DIRS+="${DEVICE}" + +PKG_MAKE_OPTS_TARGET="-C CAPSImg" + +pre_configure_target() { + cd .. + ./bootstrap + ./configure --host=${TARGET_NAME} +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib + cp -v CAPSImg/libcapsimage.so.5.1 ${INSTALL}/usr/lib/ + ln -sf libcapsimage.so.5.1 ${INSTALL}/usr/lib/libcapsimage.so.5 + ln -sf libcapsimage.so.5.1 ${INSTALL}/usr/lib/libcapsimage.so + mkdir -p ${INSTALL}/usr/include/caps5 + cp -v LibIPF/* ${INSTALL}/usr/include/caps5 +} diff --git a/projects/ArchR/packages/graphics/fbgrab/package.mk b/projects/ArchR/packages/graphics/fbgrab/package.mk new file mode 100644 index 0000000000..41c86cd40c --- /dev/null +++ b/projects/ArchR/packages/graphics/fbgrab/package.mk @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="fbgrab" +PKG_VERSION="5c2481d2b67b634e4e611610c33d30ef796afe5d" +PKG_LICENSE="GPL2.0" +PKG_SITE="https://github.com/GunnarMonell/fbgrab" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="A utility to grab/screenshot the framebuffer." +GET_HANDLER_SUPPORT="git" diff --git a/projects/ArchR/packages/graphics/gdk-pixbuf/config/loaders.cache b/projects/ArchR/packages/graphics/gdk-pixbuf/config/loaders.cache new file mode 100644 index 0000000000..129bdba2ce --- /dev/null +++ b/projects/ArchR/packages/graphics/gdk-pixbuf/config/loaders.cache @@ -0,0 +1,107 @@ +# GdkPixbuf Image Loader Modules file +# Automatically generated file, do not edit +# Created by gdk-pixbuf-query-loaders from gdk-pixbuf-2.42.4 +# +# LoaderDir = /usr/lib/gdk-pixbuf-2.0/2.10.0/loaders +# +"/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-ani.so" +"ani" 4 "gdk-pixbuf" "Windows animated cursor" "LGPL" +"application/x-navi-animation" "" +"ani" "" +"RIFF ACON" " xxxx " 100 + +"/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-bmp.so" +"bmp" 5 "gdk-pixbuf" "BMP" "LGPL" +"image/bmp" "image/x-bmp" "image/x-MS-bmp" "" +"bmp" "" +"BM" "" 100 + +"/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-gif.so" +"gif" 4 "gdk-pixbuf" "GIF" "LGPL" +"image/gif" "" +"gif" "" +"GIF8" "" 100 + +"/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-icns.so" +"icns" 4 "gdk-pixbuf" "MacOS X icon" "GPL" +"image/x-icns" "" +"icns" "" +"icns" "" 100 + +"/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-ico.so" +"ico" 5 "gdk-pixbuf" "Windows icon" "LGPL" +"image/x-icon" "image/x-ico" "image/x-win-bitmap" "image/vnd.microsoft.icon" "application/ico" "image/ico" "image/icon" "text/ico" "" +"ico" "cur" "" +" \001 " "zz znz" 100 +" \002 " "zz znz" 100 + +"/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-jpeg.so" +"jpeg" 5 "gdk-pixbuf" "JPEG" "LGPL" +"image/jpeg" "" +"jpeg" "jpe" "jpg" "" +"\377\330" "" 100 + +"/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-png.so" +"png" 5 "gdk-pixbuf" "PNG" "LGPL" +"image/png" "" +"png" "" +"\211PNG\r\n\032\n" "" 100 + +"/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-pnm.so" +"pnm" 4 "gdk-pixbuf" "PNM/PBM/PGM/PPM" "LGPL" +"image/x-portable-anymap" "image/x-portable-bitmap" "image/x-portable-graymap" "image/x-portable-pixmap" "" +"pnm" "pbm" "pgm" "ppm" "" +"P1" "" 100 +"P2" "" 100 +"P3" "" 100 +"P4" "" 100 +"P5" "" 100 +"P6" "" 100 + +"/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-qtif.so" +"qtif" 4 "gdk-pixbuf" "QuickTime" "LGPL" +"image/x-quicktime" "image/qtif" "" +"qtif" "qif" "" +"abcdidsc" "xxxx " 100 +"abcdidat" "xxxx " 100 + +"/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-svg.so" +"svg" 6 "gdk-pixbuf" "Scalable Vector Graphics" "LGPL" +"image/svg+xml" "image/svg" "image/svg-xml" "image/vnd.adobe.svg+xml" "text/xml-svg" "image/svg+xml-compressed" "" +"svg" "svgz" "svg.gz" "" +" &2 + echo "Usage:" >&2 + echo " List available drivers: $0 --options" >&2 + echo " Load configured driver and set libs: $0 --start" >&2 + echo " Get current driver: $0" >&2 + echo " Configure driver to load on next boot: $0 " >&2 + exit 1 + ;; +esac diff --git a/projects/ArchR/packages/graphics/grim/package.mk b/projects/ArchR/packages/graphics/grim/package.mk new file mode 100644 index 0000000000..99546f7bc2 --- /dev/null +++ b/projects/ArchR/packages/graphics/grim/package.mk @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="grim" +PKG_VERSION="1.4.1" +PKG_LICENSE="MIT" +PKG_SITE="https://wayland.emersion.fr/grim/" +PKG_URL="https://git.sr.ht/~emersion/grim/archive/v${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain wayland pixman libpng" +PKG_LONGDESC="Grab images from a Wayland compositor" diff --git a/projects/ArchR/packages/graphics/grim/patches/001-fix-warning.patch b/projects/ArchR/packages/graphics/grim/patches/001-fix-warning.patch new file mode 100644 index 0000000000..a59a0881fd --- /dev/null +++ b/projects/ArchR/packages/graphics/grim/patches/001-fix-warning.patch @@ -0,0 +1,14 @@ +--- grim-1.4.1/write_ppm.c.orig 2024-12-20 20:21:19.335943763 +0000 ++++ grim-1.4.1/write_ppm.c 2024-12-20 20:25:18.726959907 +0000 +@@ -30,7 +30,10 @@ + buffer += header_len; + + pixman_format_code_t format = pixman_image_get_format(image); +- assert(format == PIXMAN_a8r8g8b8 || format == PIXMAN_x8r8g8b8); ++ if ((format != PIXMAN_a8r8g8b8) && (format != PIXMAN_x8r8g8b8)) { ++ fprintf(stderr, "Unsupported format %x\n", format); ++ return -1; ++ } + + // Both formats are native-endian 32-bit ints + uint32_t *pixels = pixman_image_get_data(image); diff --git a/projects/ArchR/packages/graphics/gtk2/files/settings.ini b/projects/ArchR/packages/graphics/gtk2/files/settings.ini new file mode 100644 index 0000000000..c6bdb7fa46 --- /dev/null +++ b/projects/ArchR/packages/graphics/gtk2/files/settings.ini @@ -0,0 +1,4 @@ +[Settings] +gtk-icon-theme-name = Adwaita +gtk-theme-name = Adwaita +gtk-font-name = Liberation Sans 12 diff --git a/projects/ArchR/packages/graphics/gtk2/package.mk b/projects/ArchR/packages/graphics/gtk2/package.mk new file mode 100644 index 0000000000..76e810fb83 --- /dev/null +++ b/projects/ArchR/packages/graphics/gtk2/package.mk @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2017 Escalade +# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="gtk2" +PKG_VERSION="2.24.33" +PKG_LICENSE="LGPL" +PKG_SITE="http://www.gtk.org/" +PKG_URL="https://ftp.gnome.org/pub/gnome/sources/gtk+/${PKG_VERSION:0:4}/gtk+-${PKG_VERSION}.tar.xz" +PKG_DEPENDS_TARGET="toolchain at-spi2-atk atk cairo gdk-pixbuf glib libX11 libXi libXrandr libepoxy pango libxkbcommon wayland wayland-protocols libepoxy libpng tiff libjpeg-turbo libffi glew" +PKG_DEPENDS_CONFIG="libXft pango gdk-pixbuf shared-mime-info" +PKG_LONGDESC="A library for creating graphical user interfaces for the X Window System." +PKG_BUILD_FLAGS="-sysroot" + +PKG_CONFIGURE_OPTS_TARGET="--with-x \ + --enable-introspection=no \ + --disable-cups \ + --disable-glibtest \ + --enable-xinerama=no \ + --disable-maintainer-mode " + +pre_configure_target() { + # ${TOOLCHAIN}/bin/glib-compile-resources requires ${TOOLCHAIN}/lib/libffi.so.6 + export LD_LIBRARY_PATH="${TOOLCHAIN}/lib:${LD_LIBRARY_PATH}" + export GLIB_COMPILE_RESOURCES=glib-compile-resources GLIB_MKENUMS=glib-mkenums GLIB_GENMARSHAL=glib-genmarshal +} + diff --git a/projects/ArchR/packages/graphics/gtk2/patches/001-no-demos.patch b/projects/ArchR/packages/graphics/gtk2/patches/001-no-demos.patch new file mode 100644 index 0000000000..0121b86bd8 --- /dev/null +++ b/projects/ArchR/packages/graphics/gtk2/patches/001-no-demos.patch @@ -0,0 +1,35 @@ +--- a/Makefile.am.orig 2024-04-28 12:51:38.866216202 +0300 ++++ b/Makefile.am 2024-04-28 12:51:54.426096874 +0300 +@@ -1,7 +1,7 @@ + ## Makefile.am for GTK+ + include $(top_srcdir)/Makefile.decl + +-SRC_SUBDIRS = gdk gtk modules demos tests perf ++SRC_SUBDIRS = gdk gtk modules perf + SUBDIRS = po po-properties $(SRC_SUBDIRS) docs m4macros build + + # require automake 1.4 +--- a/Makefile.in.orig 2024-04-28 12:59:09.599008260 +0300 ++++ b/Makefile.in 2024-04-28 12:59:26.447165380 +0300 +@@ -565,7 +565,7 @@ + || { echo "Gtk+Tests:ERROR: Failed to start Xvfb environment for X11 target tests."; exit 1; } \ + && DISPLAY=:$$XID && export DISPLAY + +-SRC_SUBDIRS = gdk gtk modules demos tests perf ++SRC_SUBDIRS = gdk gtk modules perf + SUBDIRS = po po-properties $(SRC_SUBDIRS) docs m4macros build + + # require automake 1.4 +--- a/gtk/Makefile.in.orig 2024-04-28 12:59:09.599008260 +0300 ++++ b/gtk/Makefile.in 2024-04-28 12:59:26.447165380 +0300 +@@ -2010,8 +2010,8 @@ + + @USE_QUARTZ_FALSE@GTK_PRINT_PREVIEW_COMMAND = "evince --unlink-tempfile --preview --print-settings %s %f" + @USE_QUARTZ_TRUE@GTK_PRINT_PREVIEW_COMMAND = "open -b com.apple.Preview %f" +-SUBDIRS = theme-bits . tests +-DIST_SUBDIRS = theme-bits tests ++SUBDIRS = theme-bits . ++DIST_SUBDIRS = theme-bits + @HAVE_CUPS_FALSE@@HAVE_PAPI_CUPS_FALSE@@HAVE_PAPI_FALSE@GTK_PRINT_BACKENDS = file,lpr + @HAVE_CUPS_FALSE@@HAVE_PAPI_CUPS_FALSE@@HAVE_PAPI_TRUE@GTK_PRINT_BACKENDS = file,papi + @HAVE_CUPS_TRUE@@HAVE_PAPI_CUPS_FALSE@GTK_PRINT_BACKENDS = file,cups diff --git a/projects/ArchR/packages/graphics/gtk2/patches/002-gentoo-fix-casts.patch b/projects/ArchR/packages/graphics/gtk2/patches/002-gentoo-fix-casts.patch new file mode 100644 index 0000000000..4ee55d277f --- /dev/null +++ b/projects/ArchR/packages/graphics/gtk2/patches/002-gentoo-fix-casts.patch @@ -0,0 +1,167 @@ +https://bugs.gentoo.org/880617 + +From 81c42586e6d9db7434e9b3f657fbd238294dd9d9 Mon Sep 17 00:00:00 2001 +From: Matt Turner +Date: Sat, 13 May 2023 11:35:28 -0400 +Subject: [PATCH] Fix casts + +--- + gtk/gtkcellrendererspin.c | 2 +- + gtk/gtkcomboboxtext.c | 2 +- + gtk/gtkimmodule.c | 2 +- + gtk/gtklabel.c | 2 +- + gtk/gtkscale.c | 2 +- + gtk/gtktoolpalette.c | 2 +- + gtk/gtktreeview.c | 2 +- + gtk/gtkuimanager.c | 2 +- + gtk/gtkwidget.c | 2 +- + modules/other/gail/gailtreeview.c | 2 +- + modules/printbackends/cups/gtkprintbackendcups.c | 2 +- + 11 files changed, 11 insertions(+), 11 deletions(-) + +diff --git a/gtk/gtkcellrendererspin.c b/gtk/gtkcellrendererspin.c +index 2a3961bf20..68e5b9aaae 100644 +--- a/gtk/gtkcellrendererspin.c ++++ b/gtk/gtkcellrendererspin.c +@@ -207,7 +207,7 @@ gtk_cell_renderer_spin_set_property (GObject *object, + } + + if (obj) +- priv->adjustment = g_object_ref_sink (obj); ++ priv->adjustment = GTK_ADJUSTMENT (g_object_ref_sink (obj)); + break; + case PROP_CLIMB_RATE: + priv->climb_rate = g_value_get_double (value); +diff --git a/gtk/gtkcomboboxtext.c b/gtk/gtkcomboboxtext.c +index 9ffba68766..42c51abebc 100644 +--- a/gtk/gtkcomboboxtext.c ++++ b/gtk/gtkcomboboxtext.c +@@ -275,7 +275,7 @@ gtk_combo_box_text_buildable_custom_tag_start (GtkBuildable *buildable, + + parser_data = g_slice_new0 (ItemParserData); + parser_data->builder = g_object_ref (builder); +- parser_data->object = g_object_ref (buildable); ++ parser_data->object = G_OBJECT (g_object_ref (buildable)); + parser_data->domain = gtk_builder_get_translation_domain (builder); + *parser = item_parser; + *data = parser_data; +diff --git a/gtk/gtkimmodule.c b/gtk/gtkimmodule.c +index 1fcb17a7d8..445b2be87f 100644 +--- a/gtk/gtkimmodule.c ++++ b/gtk/gtkimmodule.c +@@ -662,7 +662,7 @@ lookup_immodule (gchar **immodules_list) + gboolean found; + gchar *context_id; + found = g_hash_table_lookup_extended (contexts_hash, *immodules_list, +- &context_id, NULL); ++ (gpointer *) &context_id, NULL); + if (found) + return context_id; + } +diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c +index c47de5924f..cf68685536 100644 +--- a/gtk/gtklabel.c ++++ b/gtk/gtklabel.c +@@ -1336,7 +1336,7 @@ gtk_label_buildable_custom_tag_start (GtkBuildable *buildable, + + parser_data = g_slice_new0 (PangoParserData); + parser_data->builder = g_object_ref (builder); +- parser_data->object = g_object_ref (buildable); ++ parser_data->object = G_OBJECT (g_object_ref (buildable)); + *parser = pango_parser; + *data = parser_data; + return TRUE; +diff --git a/gtk/gtkscale.c b/gtk/gtkscale.c +index 4317523fb8..a573b2f6ba 100644 +--- a/gtk/gtkscale.c ++++ b/gtk/gtkscale.c +@@ -1471,7 +1471,7 @@ gtk_scale_add_mark (GtkScale *scale, + mark->position = position; + + priv->marks = g_slist_insert_sorted_with_data (priv->marks, mark, +- (GCompareFunc) compare_marks, ++ compare_marks, + GINT_TO_POINTER ( + gtk_range_get_inverted (GTK_RANGE (scale)) + )); +diff --git a/gtk/gtktoolpalette.c b/gtk/gtktoolpalette.c +index b984193ca3..f64b552fb0 100644 +--- a/gtk/gtktoolpalette.c ++++ b/gtk/gtktoolpalette.c +@@ -734,7 +734,7 @@ gtk_tool_palette_add (GtkContainer *container, + + g_ptr_array_add (palette->priv->groups, info); + info->pos = palette->priv->groups->len - 1; +- info->widget = g_object_ref_sink (child); ++ info->widget = (GtkToolItemGroup *) g_object_ref_sink (child); + + gtk_widget_set_parent (child, GTK_WIDGET (palette)); + } +diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c +index 89301eb91d..0d2d15b488 100644 +--- a/gtk/gtktreeview.c ++++ b/gtk/gtktreeview.c +@@ -14147,7 +14147,7 @@ gtk_tree_view_set_search_entry (GtkTreeView *tree_view, + + if (entry) + { +- tree_view->priv->search_entry = g_object_ref (entry); ++ tree_view->priv->search_entry = GTK_WIDGET (g_object_ref (entry)); + tree_view->priv->search_custom_entry_set = TRUE; + + if (tree_view->priv->search_entry_changed_id == 0) +diff --git a/gtk/gtkuimanager.c b/gtk/gtkuimanager.c +index d004cf1ed3..8cbeda9e85 100644 +--- a/gtk/gtkuimanager.c ++++ b/gtk/gtkuimanager.c +@@ -503,7 +503,7 @@ gtk_ui_manager_buildable_construct_child (GtkBuildable *buildable, + g_signal_connect (widget, "hierarchy-changed", + G_CALLBACK (child_hierarchy_changed_cb), + GTK_UI_MANAGER (buildable)); +- return g_object_ref (widget); ++ return G_OBJECT (g_object_ref (widget)); + } + + static void +diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c +index 1d1f6bb60e..a2ae2b430f 100644 +--- a/gtk/gtkwidget.c ++++ b/gtk/gtkwidget.c +@@ -10679,7 +10679,7 @@ gtk_widget_buildable_custom_tag_start (GtkBuildable *buildable, + AccelGroupParserData *parser_data; + + parser_data = g_slice_new0 (AccelGroupParserData); +- parser_data->object = g_object_ref (buildable); ++ parser_data->object = G_OBJECT (g_object_ref (buildable)); + *parser = accel_group_parser; + *data = parser_data; + return TRUE; +diff --git a/modules/other/gail/gailtreeview.c b/modules/other/gail/gailtreeview.c +index 23923c59a1..ac6ff0a1c4 100644 +--- a/modules/other/gail/gailtreeview.c ++++ b/modules/other/gail/gailtreeview.c +@@ -995,7 +995,7 @@ gail_tree_view_ref_child (AtkObject *obj, + gail_cell_add_state (cell, ATK_STATE_FOCUSABLE, FALSE); + if (focus_index == i) + { +- gailview->focus_cell = g_object_ref (cell); ++ gailview->focus_cell = ATK_OBJECT (g_object_ref (cell)); + gail_cell_add_state (cell, ATK_STATE_FOCUSED, FALSE); + g_signal_emit_by_name (gailview, + "active-descendant-changed", +diff --git a/modules/printbackends/cups/gtkprintbackendcups.c b/modules/printbackends/cups/gtkprintbackendcups.c +index 2a000dc16f..753c53cb89 100644 +--- a/modules/printbackends/cups/gtkprintbackendcups.c ++++ b/modules/printbackends/cups/gtkprintbackendcups.c +@@ -3479,7 +3479,7 @@ cups_request_ppd (GtkPrinter *printer) + g_io_channel_set_encoding (data->ppd_io, NULL, NULL); + g_io_channel_set_close_on_unref (data->ppd_io, TRUE); + +- data->printer = g_object_ref (printer); ++ data->printer = GTK_PRINTER_CUPS (g_object_ref (printer)); + + resource = g_strdup_printf ("/printers/%s.ppd", + gtk_printer_cups_get_ppd_name (GTK_PRINTER_CUPS (printer))); +-- +2.39.3 + diff --git a/projects/ArchR/packages/graphics/gtk2/patches/003-fix-building-with-gcc15.patch b/projects/ArchR/packages/graphics/gtk2/patches/003-fix-building-with-gcc15.patch new file mode 100644 index 0000000000..7c95975bf1 --- /dev/null +++ b/projects/ArchR/packages/graphics/gtk2/patches/003-fix-building-with-gcc15.patch @@ -0,0 +1,11 @@ +--- a/gtk/gtkitemfactory.c ++++ b/gtk/gtkitemfactory.c +@@ -1184,7 +1184,7 @@ + + entry.path = path; + entry.accelerator = entries[i].accelerator; +- entry.callback = entries[i].callback; ++ entry.callback = (GtkItemFactoryCallback) entries[i].callback; + entry.callback_action = 0; + if (g_pattern_match_string (pspec_separator, path)) + entry.item_type = ""; diff --git a/projects/ArchR/packages/graphics/gtk3/files/settings.ini b/projects/ArchR/packages/graphics/gtk3/files/settings.ini new file mode 100644 index 0000000000..c6bdb7fa46 --- /dev/null +++ b/projects/ArchR/packages/graphics/gtk3/files/settings.ini @@ -0,0 +1,4 @@ +[Settings] +gtk-icon-theme-name = Adwaita +gtk-theme-name = Adwaita +gtk-font-name = Liberation Sans 12 diff --git a/projects/ArchR/packages/graphics/gtk3/package.mk b/projects/ArchR/packages/graphics/gtk3/package.mk new file mode 100644 index 0000000000..d8fe044868 --- /dev/null +++ b/projects/ArchR/packages/graphics/gtk3/package.mk @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +. ${ROOT}/packages/addons/addon-depends/chrome-depends/gtk3/package.mk + +PKG_DEPENDS_TARGET="toolchain at-spi2-atk atk cairo gdk-pixbuf glib libX11 libXi libXrandr libepoxy pango libxkbcommon wayland wayland-protocols libepoxy libpng tiff libjpeg-turbo libffi glew" + +unset PKG_BUILD_FLAGS + +PKG_MESON_OPTS_TARGET="${PKG_MESON_OPTS_TARGET/-Dwayland_backend=false/-Dwayland_backend=true}" + +post_makeinstall_target() { + ${TOOLCHAIN}/bin/glib-compile-schemas ${INSTALL}/usr/share/glib-2.0/schemas +} diff --git a/projects/ArchR/packages/graphics/gtk3/patches/disable-to-pixdata-build.patch b/projects/ArchR/packages/graphics/gtk3/patches/disable-to-pixdata-build.patch new file mode 100644 index 0000000000..c42f8a854c --- /dev/null +++ b/projects/ArchR/packages/graphics/gtk3/patches/disable-to-pixdata-build.patch @@ -0,0 +1,26 @@ +--- a/gtk/gen-gtk-gresources-xml.py 2021-02-24 19:13:19.000000000 +0000 ++++ b/gtk/gen-gtk-gresources-xml.py 2021-04-03 23:52:35.000000000 +0000 +@@ -23,11 +23,6 @@ + theme/Adwaita/gtk-contained-dark.css + ''' + +-for f in get_files('theme/Adwaita/assets', '.png'): +- xml += ' theme/Adwaita/assets/{0}\n'.format(f) +- +-xml += '\n' +- + for f in get_files('theme/Adwaita/assets', '.svg'): + xml += ' theme/Adwaita/assets/{0}\n'.format(f) + +@@ -38,11 +33,6 @@ + theme/HighContrast/gtk-contained-inverse.css + ''' + +-for f in get_files('theme/HighContrast/assets', '.png'): +- xml += ' theme/HighContrast/assets/{0}\n'.format(f) +- +-xml += '\n' +- + for f in get_files('theme/HighContrast/assets', '.svg'): + xml += ' theme/HighContrast/assets/{0}\n'.format(f) + diff --git a/projects/ArchR/packages/graphics/imagemagick/package.mk b/projects/ArchR/packages/graphics/imagemagick/package.mk new file mode 100644 index 0000000000..e919f545c2 --- /dev/null +++ b/projects/ArchR/packages/graphics/imagemagick/package.mk @@ -0,0 +1,36 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="imagemagick" +PKG_VERSION="f65eba252e3aa387bd99297a750a2ee250664f8c" +PKG_LICENSE="http://www.imagemagick.org/script/license.php" +PKG_SITE="https://github.com/ImageMagick/ImageMagick" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain libpng libjpeg-turbo fontconfig libraw lcms2 libtool libxml2 libzip libwebp" +PKG_LONGDESC="Software suite to create, edit, compose, or convert bitmap images" + +if [ "${DISPLAYSERVER}" = "wl" ]; then + PKG_DEPENDS_TARGET+=" libXext pango" +fi + +pre_configure_target() { + PKG_CONFIGURE_OPTS_TARGET="--disable-openmp \ + --disable-static \ + --enable-shared \ + --with-pango=no \ + --with-utilities=yes \ + --with-x=no" + + if [ "${DISPLAYSERVER}" = "wl" ]; then + PKG_CONFIGURE_OPTS_TARGET+=" --with-x=yes" + else + PKG_CONFIGURE_OPTS_TARGET+=" --with-x=no" + fi + export LDFLAGS+=" -lsharpyuv -lwebp" +} + +makeinstall_target() { + make install DESTDIR=${INSTALL} ${PKG_MAKEINSTALL_OPTS_TARGET} + rm ${INSTALL}/usr/bin/*config +} diff --git a/projects/ArchR/packages/graphics/libdrm/package.mk b/projects/ArchR/packages/graphics/libdrm/package.mk new file mode 100644 index 0000000000..1ea529959f --- /dev/null +++ b/projects/ArchR/packages/graphics/libdrm/package.mk @@ -0,0 +1,52 @@ + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="libdrm" +PKG_VERSION="2.4.128" +PKG_LICENSE="GPL" +PKG_SITE="http://dri.freedesktop.org" +PKG_URL="http://dri.freedesktop.org/libdrm/libdrm-${PKG_VERSION}.tar.xz" +PKG_DEPENDS_HOST="toolchain libpciaccess libdisplay-info" +PKG_DEPENDS_TARGET="toolchain libpciaccess libdisplay-info" +PKG_LONGDESC="The userspace interface library to kernel DRM services." +PKG_TOOLCHAIN="meson" + +get_graphicdrivers + +PKG_MESON_OPTS_TARGET="-Dnouveau=disabled \ + -Domap=disabled \ + -Dexynos=disabled \ + -Dtegra=disabled \ + -Dcairo-tests=disabled \ + -Dman-pages=disabled \ + -Dvalgrind=disabled \ + -Dfreedreno-kgsl=false \ + -Dinstall-test-programs=false \ + -Dudev=false" + +listcontains "${GRAPHIC_DRIVERS}" "(iris|i915|i965)" && + PKG_MESON_OPTS_TARGET+=" -Dintel=enabled" || PKG_MESON_OPTS_TARGET+=" -Dintel=disabled" + +listcontains "${GRAPHIC_DRIVERS}" "(r200|r300|r600|radeonsi)" && + PKG_MESON_OPTS_TARGET+=" -Dradeon=enabled" || PKG_MESON_OPTS_TARGET+=" -Dradeon=disabled" + +listcontains "${GRAPHIC_DRIVERS}" "radeonsi" && + PKG_MESON_OPTS_TARGET+=" -Damdgpu=enabled" || PKG_MESON_OPTS_TARGET+=" -Damdgpu=disabled" + +listcontains "${GRAPHIC_DRIVERS}" "freedreno" && + PKG_MESON_OPTS_TARGET+=" -Dfreedreno=enabled" || PKG_MESON_OPTS_TARGET+=" -Dfreedreno=disabled" + +listcontains "${GRAPHIC_DRIVERS}" "etnaviv" && + PKG_MESON_OPTS_TARGET+=" -Detnaviv=enabled" || PKG_MESON_OPTS_TARGET+=" -Detnaviv=disabled" + +post_makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp -a ${PKG_BUILD}/.${TARGET_NAME}/tests/modetest/modetest ${INSTALL}/usr/bin/ + for header in xf86drm.h xf86drmMode.h + do + sed -i "s###g" ${SYSROOT_PREFIX}/usr/include/${header} + sed -i "s##g" ${SYSROOT_PREFIX}/usr/include/${header} + done +} diff --git a/projects/ArchR/packages/graphics/libegl/package.mk b/projects/ArchR/packages/graphics/libegl/package.mk new file mode 100644 index 0000000000..89ad2c2dc2 --- /dev/null +++ b/projects/ArchR/packages/graphics/libegl/package.mk @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="libegl" +PKG_VERSION="1.0" +PKG_LICENSE="GPLv2" +PKG_ARCH="arm aarch64" +PKG_DEPENDS_TARGET="toolchain" +PKG_TOOLCHAIN="manual" +PKG_LONGDESC="Libraries needed to run OpenGL applications on devices that dont have native OpenGL support." + +makeinstall_target() { + export STRIP=true + mkdir -p ${INSTALL}/usr/lib/egl + tar -xvf ${PKG_DIR}/sources/libegl.tar.gz -C ${INSTALL}/usr/lib/egl +} diff --git a/projects/ArchR/packages/graphics/libegl/sources/libegl.tar.gz b/projects/ArchR/packages/graphics/libegl/sources/libegl.tar.gz new file mode 100755 index 0000000000..fc83c94415 Binary files /dev/null and b/projects/ArchR/packages/graphics/libegl/sources/libegl.tar.gz differ diff --git a/projects/ArchR/packages/graphics/libepoxy/package.mk b/projects/ArchR/packages/graphics/libepoxy/package.mk new file mode 100644 index 0000000000..99e9c5a295 --- /dev/null +++ b/projects/ArchR/packages/graphics/libepoxy/package.mk @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2018 Team LibreELEC (https://libreelec.tv) +# Copyright (C) 2018-present Team CoreELEC (https://coreelec.org) + +# libepoxy (actually) needs to be built shared, to avoid +# (EE) Failed to load /usr/lib/xorg/modules/libglamoregl.so: +# /usr/lib/xorg/modules/libglamoregl.so: undefined symbol: epoxy_eglCreateImageKHR +# in Xorg.log + +PKG_NAME="libepoxy" +PKG_VERSION="1.5.10" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/anholt/libepoxy" +PKG_URL="${PKG_SITE}/archive/refs/tags/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Epoxy is a library for handling OpenGL function pointer management for you." + +if [ "${OPENGL}" != "no" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL}" +fi + +if [ "${OPENGLES}" != "no" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" +fi + +if [ "${DISPLAYSERVER}" != "x11" ] && \ + [ "${DISPLAYSERVER}" != "wl" ]; then + PKG_CONFIGURE_OPTS_TARGET="--disable-glx" +fi diff --git a/projects/ArchR/packages/graphics/libglvnd/package.mk b/projects/ArchR/packages/graphics/libglvnd/package.mk new file mode 100644 index 0000000000..e962478670 --- /dev/null +++ b/projects/ArchR/packages/graphics/libglvnd/package.mk @@ -0,0 +1,32 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2019-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="libglvnd" +PKG_VERSION="1.7.0" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/NVIDIA/libglvnd" +PKG_URL="https://github.com/NVIDIA/libglvnd/archive/v${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="libglvnd is a vendor-neutral dispatch layer for arbitrating OpenGL API calls between multiple vendors." + +configure_package() { + if [ "${DISPLAYSERVER}" = "x11" ] || \ + [ "${DISPLAYSERVER}" = "wl" ]; then + PKG_DEPENDS_TARGET+=" libX11 libXext xorgproto" + fi +} + +pre_configure_target(){ + if [ "${OPENGL_SUPPORT}" = "yes" ] + then + PKG_MESON_OPTS_TARGET+=" -Degl=true -Dglx=enabled -Dheaders=true" + fi + + if [ "${OPENGLES_SUPPORT}" = "yes" ] + then + PKG_MESON_OPTS_TARGET+=" -Dgles1=true -Dgles2=true -Dheaders=true" + else + PKG_MESON_OPTS_TARGET+=" -Dgles1=false -Dgles2=false" + fi +} + diff --git a/projects/ArchR/packages/graphics/libjpeg-turbo/package.mk b/projects/ArchR/packages/graphics/libjpeg-turbo/package.mk new file mode 100644 index 0000000000..623bb7dfc4 --- /dev/null +++ b/projects/ArchR/packages/graphics/libjpeg-turbo/package.mk @@ -0,0 +1,39 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="libjpeg-turbo" +PKG_VERSION="3.0.1" +PKG_LICENSE="GPL" +PKG_SITE="https://libjpeg-turbo.org/" +PKG_URL="https://github.com/libjpeg-turbo/libjpeg-turbo/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_HOST="toolchain:host" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="A high-speed version of libjpeg for x86 and x86-64 processors which uses SIMD." +PKG_BUILD_FLAGS="+pic +pic:host" + +PKG_CMAKE_OPTS_HOST="-DENABLE_STATIC=ON \ + -DENABLE_SHARED=OFF \ + -DWITH_JPEG8=ON \ + -DWITH_SIMD=OFF" + +PKG_CMAKE_OPTS_TARGET="-DCMAKE_POLICY_VERSION_MINIMUM=3.5 \ + -DENABLE_STATIC=ON \ + -DENABLE_SHARED=ON \ + -DWITH_JPEG8=ON" + +if target_has_feature "(neon|sse)"; then + PKG_CMAKE_OPTS_TARGET+=" -DWITH_SIMD=ON" +else + PKG_CMAKE_OPTS_TARGET+=" -DWITH_SIMD=OFF" +fi + +if [[ ${TARGET_ARCH} =~ i*86|x86_64 ]]; then + PKG_DEPENDS_HOST+=" nasm:host" + PKG_DEPENDS_TARGET+=" nasm:host" +fi + +post_makeinstall_target() { + rm -rf ${INSTALL}/usr/bin +} diff --git a/projects/ArchR/packages/graphics/libmali/package.mk b/projects/ArchR/packages/graphics/libmali/package.mk new file mode 100644 index 0000000000..2554ce6d2c --- /dev/null +++ b/projects/ArchR/packages/graphics/libmali/package.mk @@ -0,0 +1,83 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2019-present Team LibreELEC (https://libreelec.tv) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="libmali" +PKG_LICENSE="nonfree" +PKG_SITE="https://github.com/archr-linux/libmali" +PKG_VERSION="0fe30426b822699f0a660268a6040fdafce229d1" +# zip format makes extract very fast (<1s). tgz takes 20 seconds to scan the whole file +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.zip" +PKG_DEPENDS_TARGET="toolchain libdrm patchelf:host gpudriver" +PKG_LONGDESC="OpenGL ES user-space binary for the ARM Mali GPU family" +PKG_TOOLCHAIN="meson" +PKG_PATCH_DIRS+=" ${DEVICE}" + +# patchelf is incompatible with strip, but is needed to ensure apps call wrapped functions +PKG_BUILD_FLAGS="-strip" + +case "${DEVICE}" in + S922X) + DRIVER_VERSION="r51p0" + PKG_DEPENDS_TARGET+=" vulkan-wsi-layer vulkan-tools" + ;; + RK3588) + DRIVER_VERSION="g13p0" + ;; + *) # RK3326 and RK3566 + DRIVER_VERSION="g24p0" + ;; +esac + +case "${DISPLAYSERVER}" in + wl) + PLATFORM="wayland-gbm" + PKG_DEPENDS_TARGET+=" wayland" + ;; + x11) + PLATFORM="x11-gbm" + ;; + *) + PLATFORM="gbm" + ;; +esac + +PKG_MESON_OPTS_TARGET+=" -Darch=${ARCH} -Dgpu=${MALI_FAMILY} -Dversion=${DRIVER_VERSION} -Dplatform=${PLATFORM} \ + -Dkhr-header=false -Dvendor-package=true -Dwrappers=enabled -Dhooks=true" + + +unpack() { + mkdir -p "${PKG_BUILD}" + cd "${PKG_BUILD}" + pwd + # Extract only what is needed + LIBNAME="libmali-${MALI_FAMILY}-${DRIVER_VERSION}-${PLATFORM}.so" + unzip -q "${SOURCES}/${PKG_NAME}/${PKG_SOURCE_NAME}" "*/hook/*" "*/include/*" "*/scripts/*" "*/meson*" "*/data/*" "*/${LIBNAME}" + mv libmali*/* . + rmdir libmali-* + if [ "${MALI_FAMILY}" = "meson" ]; then + mv data/vulkan/mali_meson.json.in data/vulkan/mali.json.in + fi + ln -s lib optimize_3 +} + +post_makeinstall_target() { + rm -rf "${SYSROOT_PREFIX}/usr/include" # all needed headers are installed by glvnd, mesa and wayland + rm -rf "${INSTALL}/etc/ld.so.conf.d" "${SYSROOT_PREFIX}/etc/ld.so.conf.d" # upstream installs ld.so config and we don't need it + + # IDK how libs in ubuntu package get these dependencies. Need to specify them manually here. + for lib in "${INSTALL}"/usr/lib*/mali/lib*.so.*; do + patchelf --add-needed libmali-hook.so.1 "${lib}" + done + patchelf --add-needed libmali.so.1 "${INSTALL}"/usr/lib*/libmali-hook.so.1 + + # x11 lib needed for some applications on the RK3588 + if [ ${DEVICE} = "RK3588" ] && [ ${TARGET_ARCH} = "aarch64" ]; then + curl -Lo ${INSTALL}/usr/lib/libmali-${MALI_FAMILY}-${DRIVER_VERSION}-x11-gbm.so ${PKG_SITE}/raw/master/lib/aarch64-linux-gnu/libmali-${MALI_FAMILY}-${DRIVER_VERSION}-x11-gbm.so + fi + # S922X - mali vulkan libs need moving + if [ "${DEVICE}" = "S922X" ] && [ "${ARCH}" = "aarch64" ]; then + mv "${INSTALL}"/usr/lib/mali/libMaliVulkan.* "${INSTALL}"/usr/lib/ + fi +} diff --git a/projects/ArchR/packages/graphics/libmali/patches/RK3588/000-dont-install-firmware.patch b/projects/ArchR/packages/graphics/libmali/patches/RK3588/000-dont-install-firmware.patch new file mode 100644 index 0000000000..3f7def1a5a --- /dev/null +++ b/projects/ArchR/packages/graphics/libmali/patches/RK3588/000-dont-install-firmware.patch @@ -0,0 +1,18 @@ +diff -rupN libmali.orig/meson.build libmali/meson.build +--- libmali.orig/meson.build 2024-06-26 18:37:20.569979221 +0000 ++++ libmali/meson.build 2024-06-26 18:38:04.922988416 +0000 +@@ -332,10 +332,10 @@ if get_option('with-overlay') + endif + + # Install firmwares +-if gpu == 'valhall-g610' +- install_data('firmware/g610/mali_csffw.bin', +- install_dir : get_option('firmware-dir')) +-endif ++#if gpu == 'valhall-g610' ++# install_data('firmware/g610/mali_csffw.bin', ++# install_dir : get_option('firmware-dir')) ++#endif + + if vendor_package + # Install vendor ld config diff --git a/projects/ArchR/packages/graphics/libpng/package.mk b/projects/ArchR/packages/graphics/libpng/package.mk new file mode 100644 index 0000000000..192822987a --- /dev/null +++ b/projects/ArchR/packages/graphics/libpng/package.mk @@ -0,0 +1,35 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) + +PKG_NAME="libpng" +PKG_VERSION="1.6.40" +PKG_LICENSE="LibPNG2" +PKG_SITE="http://www.libpng.org/" +PKG_URL="${SOURCEFORGE_SRC}/libpng/${PKG_NAME}-${PKG_VERSION}.tar.xz" +PKG_DEPENDS_HOST="zlib:host" +PKG_DEPENDS_TARGET="toolchain zlib" +PKG_LONGDESC="An extensible file format for the lossless, portable, well-compressed storage of raster images." +PKG_TOOLCHAIN="configure" +PKG_BUILD_FLAGS="+pic +pic:host" + +PKG_CONFIGURE_OPTS_TARGET="ac_cv_lib_z_zlibVersion=yes \ + --enable-static \ + --enable-shared" + +PKG_CONFIGURE_OPTS_HOST="--enable-static --disable-shared" + +pre_configure_host() { + export CPPFLAGS="$CPPFLAGS -I${TOOLCHAIN}/include" +} + +pre_configure_target() { + export CPPFLAGS="${CPPFLAGS} -I${SYSROOT_PREFIX}/usr/include" +} + +post_makeinstall_target() { + sed -e "s:\([\"'= ]\)/usr:\\1${SYSROOT_PREFIX}/usr:g" \ + -e "s:libs=\"-lpng16\":libs=\"-lpng16 -lz\":g" \ + -i ${SYSROOT_PREFIX}/usr/bin/libpng*-config + + rm -rf ${INSTALL}/usr/bin +} diff --git a/projects/ArchR/packages/graphics/librga/package.mk b/projects/ArchR/packages/graphics/librga/package.mk new file mode 100644 index 0000000000..cd144958a8 --- /dev/null +++ b/projects/ArchR/packages/graphics/librga/package.mk @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="librga" +PKG_VERSION="ccfec13d6c48e3f0c7f24810b3dac162c40cdda8" +PKG_ARCH="arm aarch64" +PKG_LICENSE="Apache-2.0" +PKG_DEPENDS_TARGET="toolchain libdrm" +PKG_SITE="https://github.com/varphone/rockchip-linux-rga" +PKG_URL="${PKG_SITE}.git" +PKG_LONGDESC="RGA is an independent 2D hardware acceleration userspace driver" +PKG_TOOLCHAIN="meson" diff --git a/projects/ArchR/packages/graphics/libwebp/package.mk b/projects/ArchR/packages/graphics/libwebp/package.mk new file mode 100644 index 0000000000..d745cc933d --- /dev/null +++ b/projects/ArchR/packages/graphics/libwebp/package.mk @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2023-present JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="libwebp" +PKG_VERSION="e78e924f84ddcd41fc5d55583bc32f4ddc4100a3" +PKG_LICENSE="BSD" +PKG_SITE="https://github.com/webmproject/libwebp" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_HOST="toolchain:host" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="WebP codec is a library to encode and decode images in WebP format." +PKG_TOOLCHAIN="cmake" diff --git a/projects/ArchR/packages/graphics/mesa-demos/package.mk b/projects/ArchR/packages/graphics/mesa-demos/package.mk new file mode 100644 index 0000000000..dd4871838f --- /dev/null +++ b/projects/ArchR/packages/graphics/mesa-demos/package.mk @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="mesa-demos" +PKG_VERSION="9.0.0" +PKG_LICENSE="OSS" +PKG_SITE="https://www.mesa3d.org/" +PKG_URL="https://archive.mesa3d.org/demos/${PKG_NAME}-${PKG_VERSION}.tar.xz" +PKG_DEPENDS_TARGET="toolchain libX11 mesa glu glew gtk3 libXcomposite libdecor" +PKG_LONGDESC="Mesa 3D demos - installed are the well known glxinfo and glxgears." +PKG_BUILD_FLAGS="-sysroot" + +if [ "${VULKAN_SUPPORT}" = "yes" ]; then + PKG_MESON_OPTS_TARGET=" -Dvulkan=enabled" +else + PKG_MESON_OPTS_TARGET=" -Dvulkan=disabled" +fi + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp -P src/xdemos/glxdemo ${INSTALL}/usr/bin + cp -P src/xdemos/glxgears ${INSTALL}/usr/bin + cp -P src/xdemos/glxinfo ${INSTALL}/usr/bin + + if [ "${VULKAN_SUPPORT}" = "yes" ]; then + cp -P src/vulkan/vkgears ${INSTALL}/usr/bin + fi +} diff --git a/projects/ArchR/packages/graphics/mesa-demos/patches/vkcube.patch b/projects/ArchR/packages/graphics/mesa-demos/patches/vkcube.patch new file mode 100644 index 0000000000..8ffff23168 --- /dev/null +++ b/projects/ArchR/packages/graphics/mesa-demos/patches/vkcube.patch @@ -0,0 +1,69 @@ +From c14abaa36d10d104e0e9179e5215f8caff4ca096 Mon Sep 17 00:00:00 2001 +From: Erik Faye-Lund +Date: Tue, 3 Sep 2024 20:08:20 +0200 +Subject: [PATCH] vkgears: do not require vulkan 1.1 + +We're passing zero as the flags to vkGetDeviceQueue2, meaning we might +as well use vkGetDeviceQueue from Vulkan 1.0 instead. And this seems to +be the only reason we depended on Vulkan 1.1 to start with. + +This makes it easier to use vkgears to test early bootstrapped Vulkan +implementations. We still use Vulkan 1.1 if available, because GPU +assisted validation requires it to function. + +While we're at it, switch away from VK_MAKE_VERSION(), which is +deprecated. We don't really need it anyway, because we have dedicated +defines for each version. + +Reviewed-by: Hoe Hao Cheng +Reviewed-by: Antonino Maniscalco +--- + src/vulkan/vkgears.c | 21 +++++++++++---------- + 1 file changed, 11 insertions(+), 10 deletions(-) + +diff --git a/src/vulkan/vkgears.c b/src/vulkan/vkgears.c +index bb8f00640..b603e76b6 100644 +--- a/src/vulkan/vkgears.c ++++ b/src/vulkan/vkgears.c +@@ -132,13 +132,21 @@ current_time(void) + static void + init_vk(const char *extension) + { +- VkResult res = vkCreateInstance( ++ uint32_t api_version = VK_API_VERSION_1_0; ++ ++ // use Vulkan 1.1 if supported ++ uint32_t instance_version = api_version; ++ VkResult res = vkEnumerateInstanceVersion(&instance_version); ++ if (res == VK_SUCCESS && instance_version >= VK_API_VERSION_1_1) ++ api_version = VK_API_VERSION_1_1; ++ ++ res = vkCreateInstance( + &(VkInstanceCreateInfo) { + .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, + .pApplicationInfo = &(VkApplicationInfo) { + .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, + .pApplicationName = "vkgears", +- .apiVersion = VK_MAKE_VERSION(1, 1, 0), ++ .apiVersion = api_version, + }, + .enabledExtensionCount = extension ? 2 : 0, + .ppEnabledExtensionNames = (const char *[2]) { +@@ -192,14 +200,7 @@ init_vk(const char *extension) + if (res != VK_SUCCESS) + error("Failed to create Vulkan device.\n"); + +- vkGetDeviceQueue2(device, +- &(VkDeviceQueueInfo2) { +- .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2, +- .flags = 0, +- .queueFamilyIndex = 0, +- .queueIndex = 0, +- }, +- &queue); ++ vkGetDeviceQueue(device, 0, 0, &queue); + + vkCreateCommandPool(device, + &(const VkCommandPoolCreateInfo) { +-- +GitLab diff --git a/projects/ArchR/packages/graphics/mesa/package.mk b/projects/ArchR/packages/graphics/mesa/package.mk new file mode 100644 index 0000000000..f4a4940f36 --- /dev/null +++ b/projects/ArchR/packages/graphics/mesa/package.mk @@ -0,0 +1,106 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="mesa" +PKG_LICENSE="OSS" +PKG_SITE="http://www.mesa3d.org/" +PKG_DEPENDS_HOST="toolchain:host llvm:host libclc:host spirv-tools:host libdrm:host \ + spirv-llvm-translator:host wayland-protocols:host libX11:host libXext:host \ + libXfixes:host libxshmfence:host libXxf86vm:host xrandr:host glslang:host" +PKG_DEPENDS_TARGET="toolchain expat libdrm Mako:host pyyaml:host" +PKG_LONGDESC="Mesa is a 3-D graphics library with an API." +PKG_TOOLCHAIN="meson" +PKG_PATCH_DIRS+=" ${DEVICE}" +PKG_VERSION="26.0.2" +PKG_URL="https://gitlab.freedesktop.org/mesa/mesa/-/archive/mesa-${PKG_VERSION}/mesa-mesa-${PKG_VERSION}.tar.gz" + +if listcontains "${GRAPHIC_DRIVERS}" "panfrost"; then + PKG_DEPENDS_TARGET+=" mesa:host" +fi + +get_graphicdrivers + +pre_configure_host() { +# Host only gets built for panfrost. +PKG_MESON_OPTS_HOST+=" ${MESA_LIBS_PATH_OPTS} \ + -Dgallium-drivers=${GALLIUM_DRIVERS// /,} \ + -Dvulkan-drivers=${VULKAN_DRIVERS_MESA// /,} \ + -Dmesa-clc=enabled \ + -Dinstall-mesa-clc=true \ + -Dprecomp-compiler=enabled \ + -Dinstall-precomp-compiler=true" +} + +PKG_MESON_OPTS_TARGET=" ${MESA_LIBS_PATH_OPTS} \ + -Dgallium-drivers=${GALLIUM_DRIVERS// /,} \ + -Dgallium-extra-hud=false \ + -Dshader-cache=enabled \ + -Dshared-glapi=enabled \ + -Dopengl=true \ + -Dgbm=enabled \ + -Degl=enabled \ + -Dlibunwind=disabled \ + -Dlmsensors=disabled \ + -Dbuild-tests=false" + +if listcontains "${GRAPHIC_DRIVERS}" "panfrost"; then + # These options require that we have built mesa host as specified above + PKG_MESON_OPTS_TARGET+=" -Dmesa-clc=system \ + -Dprecomp-compiler=system" +fi + +if [ "${DISPLAYSERVER}" = "x11" ]; then + PKG_DEPENDS_TARGET+=" xorgproto libXext libXdamage libXfixes libXxf86vm libxcb libX11 libxshmfence libXrandr libglvnd glfw" + export X11_INCLUDES= + PKG_MESON_OPTS_TARGET+=" -Dplatforms=x11 \ + -Dglx=dri \ + -Dglvnd=enabled" +elif [ "${DISPLAYSERVER}" = "wl" ]; then + PKG_DEPENDS_TARGET+=" wayland wayland-protocols libglvnd glfw" + PKG_MESON_OPTS_TARGET+=" -Dplatforms=wayland,x11 \ + -Dglx=dri \ + -Dglvnd=enabled" + PKG_DEPENDS_TARGET+=" xorgproto libXext libXdamage libXfixes libXxf86vm libxcb libX11 libxshmfence libXrandr libglvnd" + export X11_INCLUDES= +else + PKG_MESON_OPTS_TARGET+=" -Dplatforms="" \ + -Dgallium-nine=false \ + -Dglx=disabled \ + -Dglvnd=disabled" +fi + +if [ "${LLVM_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" elfutils llvm" + PKG_MESON_OPTS_TARGET+=" -Dllvm=enabled" +else + PKG_MESON_OPTS_TARGET+=" -Dllvm=disabled" +fi + +if [ "${VAAPI_SUPPORT}" = "yes" ] && listcontains "${GRAPHIC_DRIVERS}" "(r600|radeonsi)"; then + PKG_DEPENDS_TARGET+=" libva" + PKG_MESON_OPTS_TARGET+=" -Dgallium-va=enabled \ + -Dvideo-codecs=vc1dec,h264dec,h264enc,h265dec,h265enc" +else + PKG_MESON_OPTS_TARGET+=" -Dgallium-va=disabled" +fi + +if [ "${OPENGLES_SUPPORT}" = "yes" ]; then + PKG_MESON_OPTS_TARGET+=" -Dgles1=enabled -Dgles2=enabled" +else + PKG_MESON_OPTS_TARGET+=" -Dgles1=disabled -Dgles2=disabled" +fi + +if [ "${VULKAN_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${VULKAN} vulkan-tools" + PKG_MESON_OPTS_TARGET+=" -Dvulkan-drivers=${VULKAN_DRIVERS_MESA// /,}" +else + PKG_MESON_OPTS_TARGET+=" -Dvulkan-drivers=" +fi + +post_makeinstall_target() { + # While this likely breaks panfrost vulkan, it does fix vulkaninfo on libmali-vulkan + if [ "${DEVICE}" = "S922X" ]; then + rm -f ${INSTALL}/usr/lib/libvulkan_panfrost.so ${INSTALL}/usr/share/vulkan/icd.d/panfrost_icd.*.json + fi +} diff --git a/projects/ArchR/packages/graphics/mesa/patches/000-fix-a740-vulkan.patch b/projects/ArchR/packages/graphics/mesa/patches/000-fix-a740-vulkan.patch new file mode 100644 index 0000000000..89bda7e086 --- /dev/null +++ b/projects/ArchR/packages/graphics/mesa/patches/000-fix-a740-vulkan.patch @@ -0,0 +1,18 @@ +diff --git a/src/freedreno/vulkan/tu_knl_drm_msm.cc b/src/freedreno/vulkan/tu_knl_drm_msm.cc +index e3a6916..d60db42 100644 +--- a/src/freedreno/vulkan/tu_knl_drm_msm.cc ++++ b/src/freedreno/vulkan/tu_knl_drm_msm.cc +@@ -1257,11 +1257,8 @@ msm_queue_submit(struct tu_queue *queue, void *_submit, + uint64_t other_timepoint = + submit->binds.size != 0 ? queue->gfx_timepoint : + queue->sparse_timepoint; +- uint32_t extra_wait_count = +- (queue->type == TU_QUEUE_GFX && other_timepoint != 0) ? 1 : 0; +- uint32_t extra_signal_count = +- (queue->type == TU_QUEUE_GFX && has_vm_bind) ? 1 : 0; +- ++ uint32_t extra_wait_count = 0; ++ uint32_t extra_signal_count = 0; + /* Allocate without wait timeline semaphores */ + in_syncobjs = (struct drm_msm_syncobj *) vk_zalloc( + &queue->device->vk.alloc, diff --git a/projects/ArchR/packages/graphics/qt6/package.mk b/projects/ArchR/packages/graphics/qt6/package.mk new file mode 100644 index 0000000000..0283d914aa --- /dev/null +++ b/projects/ArchR/packages/graphics/qt6/package.mk @@ -0,0 +1,134 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="qt6" +PKG_VERSION_MAJOR="6.8" +PKG_VERSION="${PKG_VERSION_MAJOR}.3" +PKG_LICENSE="GPL" +PKG_SITE="https://download.qt.io" +PKG_URL="${PKG_SITE}/archive/qt/${PKG_VERSION_MAJOR}/${PKG_VERSION}/single/qt-everywhere-src-${PKG_VERSION}.tar.xz" +PKG_DEPENDS_TARGET="toolchain qt6:host openssl libjpeg-turbo libpng pcre2 sqlite zlib freetype SDL2 gstreamer gst-plugins-base gst-plugins-good gst-libav" +PKG_DEPENDS_HOST="gcc:host llvm:host mesa:host" +PKG_LONGDESC="A cross-platform application and UI framework" + +# Apply project-specific patches +PKG_PATCH_DIRS="${PROJECT}" + +# Set OpenGL or OpenGLES support for CMake +if [ "${OPENGL_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_HOST+=" ${OPENGL}" + PKG_DEPENDS_TARGET+=" ${OPENGL}" + PKG_CMAKE_OPTS_TARGET+=" -DQT_FEATURE_opengl=ON -DQT_FEATURE_opengles2=OFF" +elif [ "${OPENGLES_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_HOST+=" ${OPENGLES}" + PKG_DEPENDS_TARGET+=" ${OPENGLES}" + PKG_CMAKE_OPTS_TARGET+=" -DQT_FEATURE_opengles2=ON -DQT_FEATURE_opengl=OFF" +else + PKG_CMAKE_OPTS_TARGET+=" -DQT_FEATURE_opengl=OFF -DQT_FEATURE_opengles2=OFF" +fi + +# XCB support for X11 +if [ "${DISPLAYSERVER}" = "x11" ]; then + PKG_DEPENDS_TARGET+=" xcb-util xcb-util-image xcb-util-keysyms xcb-util-renderutil xcb-util-wm libxcb-cursor libxkbcommon" +fi + +# Wayland support +if [ "${DISPLAYSERVER}" = "wl" ]; then + PKG_DEPENDS_TARGET+=" wayland xcb-util xcb-util-image xcb-util-keysyms xcb-util-renderutil xcb-util-wm libxcb-cursor libxkbcommon" + PKG_CMAKE_OPTS_TARGET+=" -DBUILD_qtwayland=ON" +else + PKG_CMAKE_OPTS_TARGET+=" -DBUILD_qtwayland=OFF" +fi + +# Vulkan support +if [ "${VULKAN_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" ${VULKAN}" + PKG_CMAKE_OPTS_TARGET+=" -DQT_FEATURE_vulkan=ON" +else + PKG_CMAKE_OPTS_TARGET+=" -DQT_FEATURE_vulkan=OFF" +fi + + +pre_configure_host() { + export LDFLAGS="${LDFLAGS} -lgio-2.0 -lgobject-2.0 -lglib-2.0" + echo "LDFLAGS are $LDFLAGS" + + unset HOST_CMAKE_OPTS + # Disable unneeded modules + MODULES_TO_DISABLE=("qt3d" "qt5compat" "qtactiveqt" "qtcharts" "qtcoap" "qtconnectivity" "qtdatavis3d" + "qtdoc" "qtgraphs" "qtgrpc" "qthttpserver" "qtlocation" "qtlottie" "qtmqtt" + "qtmultimedia" "qtnetworkauth" "qtopcua" "qtpositioning" "qtquick3d" "qtquick3dphysics" + "qtquickeffectmaker" "qtquicktimeline" "qtremoteobjects" "qtscxml" "qtsensors" "qtserialbus" + "qtserialport" "qtspeech" "qttranslations" "qtvirtualkeyboard" "qtwebchannel" + "qtwebengine" "qtwebsockets" "qtwebview") + for module in "${MODULES_TO_DISABLE[@]}"; do + PKG_CMAKE_OPTS_HOST+=" -DBUILD_${module}=OFF" + done + + # Enable required modules + # > qtbase qtshadertools qtdeclarative qtsvg qtlanguageserver qttools qtwayland + MODULES_TO_ENABLE=("qtbase" "qtshadertools" "qtdeclarative" "qtsvg" "qtlanguageserver" "qtimageformats" "qttools" "qtwayland") + for module in "${MODULES_TO_ENABLE[@]}"; do + PKG_CMAKE_OPTS_HOST+=" -DBUILD_${module}=ON" + done + + # Set Host Install path + PKG_CMAKE_OPTS_HOST+=" -DCMAKE_INSTALL_PREFIX=${TOOLCHAIN}/usr/local/qt6 \ + -DCMAKE_BUILD_TYPE=Release \ + -DQT_BUILD_EXAMPLES=OFF \ + -DQT_BUILD_TESTS=OFF \ + -DQT_USE_CCACHE=ON \ + -DQT_GENERATE_SBOM=OFF \ + -DQT_FEATURE_icu=OFF \ + -DQT_FEATURE_wayland=ON \ + -DBUILD_WITH_PCH=OFF" +} + +pre_configure_target(){ + unset TARGET_CMAKE_OPTS + # Disable unneeded modules + MODULES_TO_DISABLE=("qt3d" "qt5compat" "qtactiveqt" "qtcharts" "qtcoap" "qtconnectivity" "qtdatavis3d" + "qtdoc" "qtgraphs" "qtgrpc" "qthttpserver" "qtimageformats" + "qtlocation" "qtlottie" "qtmqtt" "qtnetworkauth" "qtopcua" "qtpositioning" + "qtquick3d" "qtquick3dphysics" "qtquickeffectmaker" "qtquicktimeline" "qtremoteobjects" + "qtscxml" "qtsensors" "qtspeech" "qttranslations" "qtvirtualkeyboard" + "qtwebchannel" "qtwebengine" "qtwebview") + for module in "${MODULES_TO_DISABLE[@]}"; do + PKG_CMAKE_OPTS_TARGET+=" -DBUILD_${module}=OFF" + done + + # Enable required modules: qtbase qtmultimedia qtshadertools qtdeclarative qtserialbus qtserialport qtsvg qttools qtwebsockets qtlanguageserver + # Conditionals: qtwayland + MODULES_TO_ENABLE=("qtbase" "qtmultimedia" "qtshadertools" "qtdeclarative" "qtserialbus" + "qtserialport" "qtsvg" "qttools" "qtwebsockets" "qtlanguageserver") + for module in "${MODULES_TO_ENABLE[@]}"; do + PKG_CMAKE_OPTS_TARGET+=" -DBUILD_${module}=ON" + done + + PKG_CMAKE_OPTS_TARGET+=" -DCMAKE_INSTALL_PREFIX=/usr \ + -DCMAKE_SYSROOT=${SYSROOT_PREFIX} \ + -DCMAKE_TOOLCHAIN_FILE=${CMAKE_CONF} \ + -DQT_HOST_PATH=${TOOLCHAIN}/usr/local/qt6 \ + -DCMAKE_BUILD_TYPE=Release \ + -DQT_DEBUG_FIND_PACKAGE=ON \ + -DBUILD_SHARED_LIBS=ON \ + -DQT_BUILD_EXAMPLES=OFF \ + -DQT_BUILD_TESTS=OFF \ + -DQT_FEATURE_printer=OFF \ + -DQT_USE_CCACHE=ON \ + -DQT_FEATURE_xcb=ON \ + -DQT_GENERATE_SBOM=OFF \ + -DBUILD_WITH_PCH=OFF" +} + +post_makeinstall_target() { + rm -rf ${INSTALL}/usr + + mkdir -p ${INSTALL}/usr/lib + mkdir -p ${INSTALL}/usr/plugins + mkdir -p ${INSTALL}/usr/qml + + cp -rf ${PKG_BUILD}/.${TARGET_NAME}/qtbase/lib/*.so* ${INSTALL}/usr/lib/ + cp -rf ${PKG_BUILD}/.${TARGET_NAME}/qtbase/plugins/* ${INSTALL}/usr/plugins/ + cp -rf ${PKG_BUILD}/.${TARGET_NAME}/qtbase/qml/* ${INSTALL}/usr/qml/ +} diff --git a/projects/ArchR/packages/graphics/spirv-headers/package.mk b/projects/ArchR/packages/graphics/spirv-headers/package.mk new file mode 100644 index 0000000000..43b925291b --- /dev/null +++ b/projects/ArchR/packages/graphics/spirv-headers/package.mk @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2021-present Frank Hartung (supervisedthinking (@) gmail.com) +# Copyright (C) 2021-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="spirv-headers" +# The SPIRV-Headers pkg_version needs to match the compatible (known_good) glslang pkg_version. +# https://raw.githubusercontent.com/KhronosGroup/glslang/${PKG_VERSION}/known_good.json +# When updating glslang pkg_version please update to the known_good spirv-headers pkg_version. +PKG_VERSION="3f17b2af6784bfa2c5aa5dbb8e0e74a607dd8b3b" +PKG_LICENSE="Apache-2.0" +PKG_SITE="https://github.com/KhronosGroup/SPIRV-headers" +PKG_URL="https://github.com/KhronosGroup/SPIRV-headers/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_HOST="" +PKG_LONGDESC="SPIRV-Headers" +PKG_TOOLCHAIN="manual" diff --git a/projects/ArchR/packages/graphics/spirv-llvm-translator/package.mk b/projects/ArchR/packages/graphics/spirv-llvm-translator/package.mk new file mode 100644 index 0000000000..1710669755 --- /dev/null +++ b/projects/ArchR/packages/graphics/spirv-llvm-translator/package.mk @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (C) 2024-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="spirv-llvm-translator" +PKG_VERSION="20.1.5" +PKG_SHA256="83048509774d865dab7631c887b0673753f59f337256bb56829ea32f30d7584b" +PKG_LICENSE="LLVM" +PKG_SITE="https://github.com/KhronosGroup/SPIRV-LLVM-Translator" +PKG_DEPENDS_HOST="toolchain:host llvm:host" +PKG_URL="https://github.com/KhronosGroup/SPIRV-LLVM-Translator/archive/v${PKG_VERSION}.tar.gz" +PKG_LONGDESC="SPIRV-LLVM-Translator" +PKG_TOOLCHAIN="cmake" diff --git a/projects/ArchR/packages/graphics/spirv-tools/package.mk b/projects/ArchR/packages/graphics/spirv-tools/package.mk new file mode 100644 index 0000000000..ec6fe99d1a --- /dev/null +++ b/projects/ArchR/packages/graphics/spirv-tools/package.mk @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2021-present Frank Hartung (supervisedthinking (@) gmail.com) +# Copyright (C) 2021-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="spirv-tools" +# The SPIRV-Tools pkg_version needs to match the compatible (known_good) glslang pkg_version. +# https://raw.githubusercontent.com/KhronosGroup/glslang/${PKG_VERSION}/known_good.json +# When updating glslang pkg_version please update to the known_good spirv-tools pkg_version. +PKG_VERSION="4d2f0b40bfe290dea6c6904dafdf7fd8328ba346" +PKG_LICENSE="Apache-2.0" +PKG_SITE="https://github.com/KhronosGroup/SPIRV-Tools" +PKG_URL="https://github.com/KhronosGroup/SPIRV-Tools/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_HOST="toolchain:host" +PKG_DEPENDS_TARGET="toolchain" +PKG_DEPENDS_UNPACK="spirv-headers" +PKG_LONGDESC="The SPIR-V Tools project provides an API and commands for processing SPIR-V modules." + +PKG_CMAKE_OPTS_HOST="-DSPIRV_SKIP_TESTS=ON" + +pre_configure_host() { + export CXXFLAGS="${CXXFLAGS//-std=gnu17/-std=gnu++17}" +} + +post_unpack() { + mkdir -p ${PKG_BUILD}/external/spirv-headers + tar --strip-components=1 \ + -xf "${SOURCES}/spirv-headers/spirv-headers-$(get_pkg_version spirv-headers).tar.gz" \ + -C "${PKG_BUILD}/external/spirv-headers" +} diff --git a/projects/ArchR/packages/graphics/vulkan/vulkan-headers/package.mk b/projects/ArchR/packages/graphics/vulkan/vulkan-headers/package.mk new file mode 100755 index 0000000000..8892284e74 --- /dev/null +++ b/projects/ArchR/packages/graphics/vulkan/vulkan-headers/package.mk @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2018-present Frank Hartung (supervisedthinking (@) gmail.com) +# Copyright (C) 2021-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="vulkan-headers" +PKG_VERSION="1.4.332" +PKG_LICENSE="Apache-2.0" +PKG_SITE="https://github.com/KhronosGroup/Vulkan-Headers" +PKG_URL="https://github.com/KhronosGroup/Vulkan-Headers/archive/v${PKG_VERSION}.tar.gz" +PKG_DEPENDS_HOST="toolchain:host" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Vulkan Header files and API registry" + +pre_configure_target() { + PKG_CMAKE_OPTS_TARGET="-DCMAKE_BUILD_TYPE=Release" +} diff --git a/projects/ArchR/packages/graphics/vulkan/vulkan-loader/package.mk b/projects/ArchR/packages/graphics/vulkan/vulkan-loader/package.mk new file mode 100755 index 0000000000..21200af0a9 --- /dev/null +++ b/projects/ArchR/packages/graphics/vulkan/vulkan-loader/package.mk @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2018-present Frank Hartung (supervisedthinking (@) gmail.com) +# Copyright (C) 2021-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="vulkan-loader" +PKG_VERSION="1.4.332" +PKG_LICENSE="Apache-2.0" +PKG_SITE="https://github.com/KhronosGroup/Vulkan-Loader" +PKG_URL="https://github.com/KhronosGroup/Vulkan-Loader/archive/v${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain Python3:host vulkan-headers libxcb libX11 libXrandr wayland" +PKG_LONGDESC="Vulkan Installable Client Driver (ICD) Loader." + +pre_configure_target() { + PKG_CMAKE_OPTS_TARGET="-DBUILD_TESTS=OFF \ + -DCMAKE_BUILD_TYPE=Release" + + # GAS / GNU Assembler is only supported by aarch64 & x86_64 + HOST_ARCH=$(uname -m) + case ${HOST_ARCH} in + arm|aarch64) + PKG_CMAKE_OPTS_TARGET+=" -DUSE_GAS=OFF" + ;; + esac + + if [ "${DISPLAYSERVER}" = "x11" ]; then + PKG_CMAKE_OPTS_TARGET+=" -DBUILD_WSI_XCB_SUPPORT=ON \ + -DBUILD_WSI_XLIB_SUPPORT=ON \ + -DBUILD_WSI_WAYLAND_SUPPORT=OFF" + elif [ "${DISPLAYSERVER}" = "wl" ]; then + PKG_CMAKE_OPTS_TARGET+=" -DBUILD_WSI_XCB_SUPPORT=ON \ + -DBUILD_WSI_XLIB_SUPPORT=ON \ + -DBUILD_WSI_WAYLAND_SUPPORT=ON" + else + PKG_CMAKE_OPTS_TARGET+=" -DBUILD_WSI_XCB_SUPPORT=OFF \ + -DBUILD_WSI_XLIB_SUPPORT=OFF \ + -DBUILD_WSI_WAYLAND_SUPPORT=OFF" + fi +} diff --git a/projects/ArchR/packages/graphics/vulkan/vulkan-tools/package.mk b/projects/ArchR/packages/graphics/vulkan/vulkan-tools/package.mk new file mode 100755 index 0000000000..805d00c19c --- /dev/null +++ b/projects/ArchR/packages/graphics/vulkan/vulkan-tools/package.mk @@ -0,0 +1,62 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2018-present Frank Hartung (supervisedthinking (@) gmail.com) +# Copyright (C) 2021-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="vulkan-tools" +PKG_VERSION="1.4.332" +PKG_LICENSE="Apache-2.0" +PKG_SITE="https://github.com/KhronosGroup/Vulkan-Tools" +PKG_URL="https://github.com/KhronosGroup/Vulkan-tools/archive/v${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain vulkan-loader glslang:host Python3:host volk wayland" +PKG_LONGDESC="This project provides Khronos official Vulkan Tools and Utilities." + +configure_package() { + # Displayserver Support + if [ "${DISPLAYSERVER}" = "x11" ]; then + PKG_DEPENDS_TARGET+=" libxcb libX11" + elif [ "${DISPLAYSERVER}" = "wl" ]; then + PKG_DEPENDS_TARGET+=" wayland" + fi +} + +pre_configure_target() { + PKG_CMAKE_OPTS_TARGET="-DVULKAN_HEADERS_INSTALL_DIR=${SYSROOT_PREFIX}/usr \ + -DBUILD_VULKANINFO=ON \ + -DBUILD_ICD=OFF \ + -DINSTALL_ICD=OFF \ + -DBUILD_WSI_DIRECTFB_SUPPORT=OFF \ + -DPython3_EXECUTABLE=${TOOLCHAIN}/bin/python3 \ + -DCMAKE_BUILD_TYPE=Release \ + -Wno-dev" + + if [ "${DISPLAYSERVER}" = "x11" ]; then + PKG_CMAKE_OPTS_TARGET+=" -DBUILD_CUBE=ON \ + -DBUILD_WSI_XCB_SUPPORT=ON \ + -DBUILD_WSI_XLIB_SUPPORT=ON \ + -DBUILD_WSI_WAYLAND_SUPPORT=OFF \ + -DCUBE_WSI_SELECTION=XCB" + elif [ "${DISPLAYSERVER}" = "wl" ]; then + PKG_CMAKE_OPTS_TARGET+=" -DBUILD_CUBE=ON \ + -DBUILD_WSI_XCB_SUPPORT=ON \ + -DBUILD_WSI_XLIB_SUPPORT=ON \ + -DBUILD_WSI_WAYLAND_SUPPORT=ON \ + -DCUBE_WSI_SELECTION=WAYLAND" + else + PKG_CMAKE_OPTS_TARGET+=" -DBUILD_CUBE=ON \ + -DBUILD_WSI_XCB_SUPPORT=OFF \ + -DBUILD_WSI_XLIB_SUPPORT=OFF \ + -DBUILD_WSI_WAYLAND_SUPPORT=OFF \ + -DCUBE_WSI_SELECTION=DISPLAY" + fi +} + +pre_make_target() { + # Fix cross compiling + find ${PKG_BUILD} -name flags.make -exec sed -i "s:isystem :I:g" \{} \; + find ${PKG_BUILD} -name build.ninja -exec sed -i "s:isystem :I:g" \{} \; +} + +post_makeinstall_target() { + # Clean up - two graphic test tools are superflous + safe_remove ${INSTALL}/usr/bin/vkcubepp +} diff --git a/projects/ArchR/packages/graphics/waffle/package.mk b/projects/ArchR/packages/graphics/waffle/package.mk new file mode 100644 index 0000000000..76aeb1fc28 --- /dev/null +++ b/projects/ArchR/packages/graphics/waffle/package.mk @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present ArchR (https://arch-r.io) +PKG_NAME="waffle" +PKG_LICENSE="BSD" +PKG_VERSION="5f1f48287e806544d745e9a8f5aed47234c61292" +PKG_SITE="https://waffle.freedesktop.org/" +PKG_URL="https://gitlab.freedesktop.org/mesa/waffle/-/archive/${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain wayland mesa Python3" +PKG_LONGDESC="Waffle - a library for selecting an OpenGL API and window system at runtime" +PKG_TOOLCHAIN="meson" + +PKG_MESON_OPTS_TARGET+=" -Dwayland=enabled \ + -Dgbm=enabled \ + -Dx11_egl=enabled \ + -Dsurfaceless_egl=enabled \ + -Dglx=enabled \ + -Dbuild-examples=false" diff --git a/projects/ArchR/packages/graphics/wxwidgets/package.mk b/projects/ArchR/packages/graphics/wxwidgets/package.mk new file mode 100644 index 0000000000..ff193ce441 --- /dev/null +++ b/projects/ArchR/packages/graphics/wxwidgets/package.mk @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="wxwidgets" +PKG_VERSION="b97aee4" +PKG_LICENSE="wxWindows Library Licence" +PKG_SITE="https://github.com/wxWidgets/wxWidgets" +PKG_URL="${PKG_SITE}.git" +PKG_GIT_CLONE_BRANCH="3.2" +PKG_DEPENDS_TARGET="toolchain zlib libpng libjpeg-turbo gdk-pixbuf gtk3 libaio" +PKG_LONGDESC="wxWidgets is a free and open source cross-platform C++ framework for writing advanced GUI applications using native controls." + +pre_configure_target(){ + PKG_CMAKE_OPTS_TARGET+=" -DCMAKE_SYSROOT=${SYSROOT_PREFIX}" + +} \ No newline at end of file diff --git a/projects/ArchR/packages/graphics/yasm/package.mk b/projects/ArchR/packages/graphics/yasm/package.mk new file mode 100644 index 0000000000..a1487f30b2 --- /dev/null +++ b/projects/ArchR/packages/graphics/yasm/package.mk @@ -0,0 +1,44 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# +# OpenELEC is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# OpenELEC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC. If not, see . +################################################################################ + +PKG_NAME="yasm" +PKG_VERSION="1.3.0" +PKG_SHA256="3dce6601b495f5b3d45b59f7d2492a340ee7e84b5beca17e48f862502bd5603f" +PKG_LICENSE="BSD" +PKG_SITE="http://www.tortall.net/projects/yasm/" +PKG_URL="http://www.tortall.net/projects/yasm/releases/${PKG_NAME}-${PKG_VERSION}.tar.gz" +PKG_DEPENDS_HOST="toolchain" +PKG_LONGDESC="yasm: A complete rewrite of the NASM assembler" +PKG_TOOLCHAIN="configure" + +PKG_CONFIGURE_OPTS_HOST="--disable-debug \ + --disable-warnerror \ + --disable-profiling \ + --disable-gcov \ + --disable-python \ + --disable-python-bindings \ + --enable-nls \ + --disable-rpath \ + --without-dmalloc \ + --with-gnu-ld \ + --without-libiconv-prefix \ + --without-libintl-prefix" + +pre_configure_host() { + CFLAGS="${CFLAGS} -std=gnu17" +} diff --git a/projects/ArchR/packages/hardware/quirks/autostart/002-device-switch b/projects/ArchR/packages/hardware/quirks/autostart/002-device-switch new file mode 100644 index 0000000000..0fb21b9208 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/autostart/002-device-switch @@ -0,0 +1,5 @@ +#!/bin/sh + +if [ -f /sys/firmware/devicetree/base/archr,device_switch/this ]; then + echo 'DEVICE_DTB_SWITCH="true"' >>/storage/.config/profile.d/002-device_switch +fi diff --git a/projects/ArchR/packages/hardware/quirks/autostart/020-configs b/projects/ArchR/packages/hardware/quirks/autostart/020-configs new file mode 100755 index 0000000000..8828322eab --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/autostart/020-configs @@ -0,0 +1,25 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +( + + if [ -d "/usr/lib/autostart/quirks/platforms/${HW_DEVICE}/config" ] && \ + [ ! -f ".quirk-platform-configs" ] + then + tocon "Applying ${HW_DEVICE} specific configuration..." + rsync -a --exclude={es_features.cfg,es_systems.cfg} /usr/lib/autostart/quirks/platforms/"${HW_DEVICE}"/config/* /storage/.config/ 2>/dev/null + touch /storage/.quirk-platform-configs + fi + + if [ -d "/usr/lib/autostart/quirks/devices/${QUIRK_DEVICE}/config" ] && \ + [ ! -f ".quirk-device-configs" ] + then + tocon "Applying ${QUIRK_DEVICE} specific configuration..." + rsync -a --exclude={es_features.cfg,es_systems.cfg} /usr/lib/autostart/quirks/devices/"${QUIRK_DEVICE}"/config/* /storage/.config/ 2>/dev/null + touch /storage/.quirk-device-configs + fi +) & diff --git a/projects/ArchR/packages/hardware/quirks/autostart/020-rumble b/projects/ArchR/packages/hardware/quirks/autostart/020-rumble new file mode 100755 index 0000000000..a9139dc6c8 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/autostart/020-rumble @@ -0,0 +1,11 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile.d/001-functions + +RUMBLE_PATH=$(find /sys/devices/platform -type f -name rumble_enable) +if [ -f "${RUMBLE_PATH}" ]; then + RUMBLE_ENABLED=$(get_setting rumble.enabled) + [ -z "${RUMBLE_ENABLED}" ] && set_setting rumble.enabled 1 || echo "${RUMBLE_ENABLED}" > "${RUMBLE_PATH}" +fi diff --git a/projects/ArchR/packages/hardware/quirks/autostart/020-set_audio_latency b/projects/ArchR/packages/hardware/quirks/autostart/020-set_audio_latency new file mode 100644 index 0000000000..7287bb4fcd --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/autostart/020-set_audio_latency @@ -0,0 +1,11 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile.d/001-functions + +AUDIO_LATENCY=$(get_setting audiolatency) +if [ -z "${AUDIO_LATENCY}" ] +then + set_setting global.audiolatency 32 +fi diff --git a/projects/ArchR/packages/hardware/quirks/autostart/080-dual_screen_mode b/projects/ArchR/packages/hardware/quirks/autostart/080-dual_screen_mode new file mode 100644 index 0000000000..5c0e385800 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/autostart/080-dual_screen_mode @@ -0,0 +1,15 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +count=$(modetest | awk '$3 == "connected" {print $0}' | wc -l) + +if [ "$count" -eq 2 ]; then + dual_screen=true +else + dual_screen=false +fi + +cat </storage/.config/profile.d/080-dual_screen_mode +DEVICE_HAS_DUAL_SCREEN=$dual_screen +EOF diff --git a/projects/ArchR/packages/hardware/quirks/autostart/095-turbo-mode b/projects/ArchR/packages/hardware/quirks/autostart/095-turbo-mode new file mode 100755 index 0000000000..2d063b7ddd --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/autostart/095-turbo-mode @@ -0,0 +1,16 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile.d/001-functions + +# Get Turbo Mode state. +TURBO_MODE_STATE=$(get_setting "enable.turbo-mode") +if [ ! -n "${TURBO_MODE_STATE}" ]; then + TURBO_MODE_STATE=0 + set_setting "enable.turbo-mode" "0" +fi + +# Set turbo-mode at boot +echo ${TURBO_MODE_STATE} > /sys/devices/system/cpu/cpufreq/boost diff --git a/projects/ArchR/packages/hardware/quirks/autostart/999-export b/projects/ArchR/packages/hardware/quirks/autostart/999-export new file mode 100755 index 0000000000..63d7d6b3d2 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/autostart/999-export @@ -0,0 +1,5 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +ln -sf /etc/profile.d/999-export /storage/.config/profile.d diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket ACE/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket ACE/001-device_config new file mode 100755 index 0000000000..c1f42ee5b5 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket ACE/001-device_config @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: Apache-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/400-device_config +DEVICE_GPU_OVERCLOCK="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket ACE/020-set-xbox-gamepad b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket ACE/020-set-xbox-gamepad new file mode 100755 index 0000000000..ff500c740c --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket ACE/020-set-xbox-gamepad @@ -0,0 +1,16 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2025 ArchR + +# Serial device +SERIAL_DEVICE="/dev/ttyHS0" + +# Open serial device +stty -F $SERIAL_DEVICE 115200 -clocal -opost -isig -icanon -echo + +# Send frame to switch gamepad to fake xbox 360 controller +printf "\xe7\x55\x05\x01\x00\x00\x00\x00\x00\x5b\xed" >$SERIAL_DEVICE +sleep 0.1 +printf "\x35\x35\x30\x35\x30\x31\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30" >$SERIAL_DEVICE +sleep 0.1 diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket ACE/400-set_gpu_overclock b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket ACE/400-set_gpu_overclock new file mode 100755 index 0000000000..d2759642e0 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket ACE/400-set_gpu_overclock @@ -0,0 +1,22 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +# Get GPU overclock state +GPU_OC_STATE=$(get_setting "enable.gpu-overclock") +if [ ! -n "${GPU_OC_STATE}" ]; then + GPU_OC_STATE="disable" + set_setting "enable.gpu-overclock" "0" +elif [ "${GPU_OC_STATE}" = 1 ]; then + GPU_OC_STATE="enable" +else + GPU_OC_STATE="disable" + set_setting "enable.gpu-overclock" "0" +fi + +# Set GPU OC state +/usr/lib/autostart/quirks/platforms/SM8550/bin/gpu_overclock ${GPU_OC_STATE} diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket ACE/bin/battery_led_status b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket ACE/bin/battery_led_status new file mode 100644 index 0000000000..240448a475 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket ACE/bin/battery_led_status @@ -0,0 +1,108 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Simple script to watch the battery capacity and +# turn the power LED orange when it reaches 30%, red at 20%, and blinking red at 10% + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +LED_PATH="/sys/class/leds" + +function led_brightness() { + echo ${2} >${LED_PATH}/${1}/brightness +} + +function led_rgb() { + echo ${2} ${3} ${4} >${LED_PATH}/${1}/multi_intensity +} + +function bat_led_off() { + led_brightness power-led 0 + led_rgb power-led 0 0 0 +} + +function bat_led_green() { + led_brightness power-led 255 + led_rgb power-led 0 255 0 +} + +function bat_led_red() { + led_brightness power-led 255 + led_rgb power-led 255 0 0 +} + +function bat_led_orange() { + led_brightness power-led 255 + led_rgb power-led 255 20 0 +} + +function bat_led_yellow() { + led_brightness power-led 255 + led_rgb power-led 255 125 0 +} + +PREV_BATCAP="null" +while true + do + BAT_LED_STATE=$(get_setting led.color) + if [ ! ${BAT_LED_STATE} == "battery" ]; then + break + fi + + CAP=$(cat /sys/class/power_supply/battery/capacity) + STAT=$(cat /sys/class/power_supply/battery/status) + + if [ ${STAT} == "Discharging" ]; then + if (( ${CAP} <= 10 )) + then + for ctr in $(seq 1 1 5) + do + bat_led_red + sleep .5 + bat_led_off + sleep .5 + done + continue + elif (( ${CAP} <= 20 )) + then + BATCAP="D_RED" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_red + fi + elif (( ${CAP} <= 30 )) + then + BATCAP="D_ORANGE" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_orange + fi + elif (( ${CAP} <= 40 )) + then + BATCAP="D_YELLOW" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_yellow + fi + else + BATCAP="D_GREEN" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_green + fi + fi + elif (( ${CAP} <= 94 )) + then + BATCAP="C_ORANGE" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_orange + fi + elif (( ${CAP} >= 95 )) + then + BATCAP="C_GREEN" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_green + fi + fi + PREV_BATCAP=${BATCAP} + sleep 15 +done diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket ACE/bin/ledcontrol b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket ACE/bin/ledcontrol new file mode 100644 index 0000000000..3f2da3849a --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket ACE/bin/ledcontrol @@ -0,0 +1,113 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +LED_PATH="/sys/class/leds" + +function led_brightness() { + echo ${2} >${LED_PATH}/${1}/brightness +} + +function led_rgb() { + echo ${2} ${3} ${4} >${LED_PATH}/${1}/multi_intensity +} + +function led_off() { + led_brightness power-led 0 + led_rgb power-led 0 0 0 +} + +function led_red() { + led_brightness power-led 255 + led_rgb power-led 255 0 0 +} + +function led_green() { + led_brightness power-led 255 + led_rgb power-led 0 255 0 +} + +function led_blue() { + led_brightness power-led 255 + led_rgb power-led 0 0 255 +} + +function led_white() { + led_brightness power-led 255 + led_rgb power-led 255 255 255 +} + +function led_orange() { + led_brightness power-led 255 + led_rgb power-led 255 20 0 +} + +function led_yellow() { + led_brightness power-led 255 + led_rgb power-led 255 125 0 +} + +function led_purple() { + led_brightness power-led 255 + led_rgb power-led 255 0 255 +} + +case ${1} in + red) + led_red + set_setting led.color ${1} + ;; + green) + led_green + set_setting led.color ${1} + ;; + blue) + led_blue + set_setting led.color ${1} + ;; + white) + led_white + set_setting led.color ${1} + ;; + orange) + led_orange + set_setting led.color ${1} + ;; + yellow) + led_yellow + set_setting led.color ${1} + ;; + purple) + led_purple + set_setting led.color ${1} + ;; + off) + led_off + set_setting led.color ${1} + ;; + battery) + led_off + set_setting led.color ${1} + systemctl restart batteryledstatus.service + ;; + poweroff) + led_off + ;; + list) +cat </storage/.config/profile.d/010-analog_sticks_led_control +DEVICE_ANALOG_STICKS_LED_CONTROL="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket DMG/020-set-xbox-gamepad b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket DMG/020-set-xbox-gamepad new file mode 120000 index 0000000000..4a6b5a7a79 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket DMG/020-set-xbox-gamepad @@ -0,0 +1 @@ +../AYANEO Pocket ACE/020-set-xbox-gamepad \ No newline at end of file diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket DMG/400-set_gpu_overclock b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket DMG/400-set_gpu_overclock new file mode 120000 index 0000000000..d44c8918d9 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket DMG/400-set_gpu_overclock @@ -0,0 +1 @@ +../AYANEO Pocket ACE/400-set_gpu_overclock \ No newline at end of file diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket DMG/bin/achievements b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket DMG/bin/achievements new file mode 120000 index 0000000000..48d72fd830 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket DMG/bin/achievements @@ -0,0 +1 @@ +../../AYN Odin 2/bin/achievements \ No newline at end of file diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket DMG/bin/analog_sticks_ledcontrol b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket DMG/bin/analog_sticks_ledcontrol new file mode 100755 index 0000000000..84ca3eb577 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket DMG/bin/analog_sticks_ledcontrol @@ -0,0 +1,69 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2025 ArchR + +# Serial device +SERIAL_DEVICE="/dev/ttyHS0" + +# Display usage if wrong parameters +if [ $# -lt 4 ]; then + echo "Usage: $0 " + echo "Example: $0 255 255 0 0" + exit 1 +fi + +BRIGHTNESS=$1 +R=$2 +G=$3 +B=$4 + +# Validate range +for val in "$R" "$G" "$B"; do + if ! [ "$val" -ge 0 ] || ! [ "$val" -le 255 ]; then + echo "RGB values must be 0-255" + exit 1 + fi +done + +# Convert to hex +BRIGHTNESS_HEX=$(printf "%02X" $BRIGHTNESS) +R_HEX=$(printf "%02X" $R) +G_HEX=$(printf "%02X" $G) +B_HEX=$(printf "%02X" $B) + +# Function to calculate checksum +calculate_checksum() { + local sum=0 + for byte in "$@"; do + sum=$((sum + byte)) + done + echo $((sum & 0xFF)) +} + +# Open serial device +exec 20<>$SERIAL_DEVICE +stty -F $SERIAL_DEVICE 115200 -opost -isig -icanon -echo + +# Construct payload (without STX and checksum) +payload=(0x00 0x1C 0x20 0x01 0x80 0x00 0x81 0x00 0x8B 0x0F 0x88 0x$R_HEX 0x89 0x$G_HEX 0x8A 0x$B_HEX 0x86 0xFF 0x87 0x$BRIGHTNESS_HEX 0x58 0x02 0x45 0x00) + +# Calculate checksum +CHECKSUM=$(calculate_checksum "${payload[@]}") + +# Construct full frame: STX + payload + checksum + ETX +STX=0xF7 +ETX=0xED +FRAME=($STX "${payload[@]}" $CHECKSUM $ETX) + +# Convert to \x.. string +CMD="" +for b in "${FRAME[@]}"; do + CMD+="\\x$(printf '%02X' $b)" +done + +# Send frame +echo -ne "$CMD" > $SERIAL_DEVICE + +# Close serial device +exec 20>&- diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket DMG/bin/battery_led_status b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket DMG/bin/battery_led_status new file mode 120000 index 0000000000..a065c33d0c --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket DMG/bin/battery_led_status @@ -0,0 +1 @@ +../../AYANEO Pocket ACE/bin/battery_led_status \ No newline at end of file diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket DMG/bin/ledcontrol b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket DMG/bin/ledcontrol new file mode 120000 index 0000000000..982f897c47 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket DMG/bin/ledcontrol @@ -0,0 +1 @@ +../../AYANEO Pocket ACE/bin/ledcontrol \ No newline at end of file diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket DS/020-fan_control b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket DS/020-fan_control new file mode 100644 index 0000000000..6a2e58cdaf --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket DS/020-fan_control @@ -0,0 +1,12 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/020-fan_control + +FANPATH="\$(ls /sys/class/hwmon/hwmon*/pwm1 | grep hwmon | cut -c 18-24)" + +DEVICE_HAS_FAN="true" +DEVICE_PWM_FAN="/sys/class/hwmon/\${FANPATH}/pwm1" +DEVICE_FAN_INPUT="/sys/class/hwmon/\${FANPATH}/pwm1" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket DS/020-set-xbox-gamepad b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket DS/020-set-xbox-gamepad new file mode 120000 index 0000000000..4a6b5a7a79 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket DS/020-set-xbox-gamepad @@ -0,0 +1 @@ +../AYANEO Pocket ACE/020-set-xbox-gamepad \ No newline at end of file diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket DS/bin/battery_led_status b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket DS/bin/battery_led_status new file mode 100644 index 0000000000..240448a475 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket DS/bin/battery_led_status @@ -0,0 +1,108 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Simple script to watch the battery capacity and +# turn the power LED orange when it reaches 30%, red at 20%, and blinking red at 10% + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +LED_PATH="/sys/class/leds" + +function led_brightness() { + echo ${2} >${LED_PATH}/${1}/brightness +} + +function led_rgb() { + echo ${2} ${3} ${4} >${LED_PATH}/${1}/multi_intensity +} + +function bat_led_off() { + led_brightness power-led 0 + led_rgb power-led 0 0 0 +} + +function bat_led_green() { + led_brightness power-led 255 + led_rgb power-led 0 255 0 +} + +function bat_led_red() { + led_brightness power-led 255 + led_rgb power-led 255 0 0 +} + +function bat_led_orange() { + led_brightness power-led 255 + led_rgb power-led 255 20 0 +} + +function bat_led_yellow() { + led_brightness power-led 255 + led_rgb power-led 255 125 0 +} + +PREV_BATCAP="null" +while true + do + BAT_LED_STATE=$(get_setting led.color) + if [ ! ${BAT_LED_STATE} == "battery" ]; then + break + fi + + CAP=$(cat /sys/class/power_supply/battery/capacity) + STAT=$(cat /sys/class/power_supply/battery/status) + + if [ ${STAT} == "Discharging" ]; then + if (( ${CAP} <= 10 )) + then + for ctr in $(seq 1 1 5) + do + bat_led_red + sleep .5 + bat_led_off + sleep .5 + done + continue + elif (( ${CAP} <= 20 )) + then + BATCAP="D_RED" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_red + fi + elif (( ${CAP} <= 30 )) + then + BATCAP="D_ORANGE" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_orange + fi + elif (( ${CAP} <= 40 )) + then + BATCAP="D_YELLOW" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_yellow + fi + else + BATCAP="D_GREEN" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_green + fi + fi + elif (( ${CAP} <= 94 )) + then + BATCAP="C_ORANGE" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_orange + fi + elif (( ${CAP} >= 95 )) + then + BATCAP="C_GREEN" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_green + fi + fi + PREV_BATCAP=${BATCAP} + sleep 15 +done diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket DS/bin/ledcontrol b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket DS/bin/ledcontrol new file mode 100644 index 0000000000..3f2da3849a --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket DS/bin/ledcontrol @@ -0,0 +1,113 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +LED_PATH="/sys/class/leds" + +function led_brightness() { + echo ${2} >${LED_PATH}/${1}/brightness +} + +function led_rgb() { + echo ${2} ${3} ${4} >${LED_PATH}/${1}/multi_intensity +} + +function led_off() { + led_brightness power-led 0 + led_rgb power-led 0 0 0 +} + +function led_red() { + led_brightness power-led 255 + led_rgb power-led 255 0 0 +} + +function led_green() { + led_brightness power-led 255 + led_rgb power-led 0 255 0 +} + +function led_blue() { + led_brightness power-led 255 + led_rgb power-led 0 0 255 +} + +function led_white() { + led_brightness power-led 255 + led_rgb power-led 255 255 255 +} + +function led_orange() { + led_brightness power-led 255 + led_rgb power-led 255 20 0 +} + +function led_yellow() { + led_brightness power-led 255 + led_rgb power-led 255 125 0 +} + +function led_purple() { + led_brightness power-led 255 + led_rgb power-led 255 0 255 +} + +case ${1} in + red) + led_red + set_setting led.color ${1} + ;; + green) + led_green + set_setting led.color ${1} + ;; + blue) + led_blue + set_setting led.color ${1} + ;; + white) + led_white + set_setting led.color ${1} + ;; + orange) + led_orange + set_setting led.color ${1} + ;; + yellow) + led_yellow + set_setting led.color ${1} + ;; + purple) + led_purple + set_setting led.color ${1} + ;; + off) + led_off + set_setting led.color ${1} + ;; + battery) + led_off + set_setting led.color ${1} + systemctl restart batteryledstatus.service + ;; + poweroff) + led_off + ;; + list) +cat </storage/.config/profile.d/010-analog_sticks_led_control +DEVICE_ANALOG_STICKS_LED_CONTROL="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket EVO/020-set-xbox-gamepad b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket EVO/020-set-xbox-gamepad new file mode 120000 index 0000000000..4a6b5a7a79 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket EVO/020-set-xbox-gamepad @@ -0,0 +1 @@ +../AYANEO Pocket ACE/020-set-xbox-gamepad \ No newline at end of file diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket EVO/400-set_gpu_overclock b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket EVO/400-set_gpu_overclock new file mode 120000 index 0000000000..d44c8918d9 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket EVO/400-set_gpu_overclock @@ -0,0 +1 @@ +../AYANEO Pocket ACE/400-set_gpu_overclock \ No newline at end of file diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket EVO/bin/achievements b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket EVO/bin/achievements new file mode 120000 index 0000000000..48d72fd830 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket EVO/bin/achievements @@ -0,0 +1 @@ +../../AYN Odin 2/bin/achievements \ No newline at end of file diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket EVO/bin/analog_sticks_ledcontrol b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket EVO/bin/analog_sticks_ledcontrol new file mode 100755 index 0000000000..84ca3eb577 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket EVO/bin/analog_sticks_ledcontrol @@ -0,0 +1,69 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2025 ArchR + +# Serial device +SERIAL_DEVICE="/dev/ttyHS0" + +# Display usage if wrong parameters +if [ $# -lt 4 ]; then + echo "Usage: $0 " + echo "Example: $0 255 255 0 0" + exit 1 +fi + +BRIGHTNESS=$1 +R=$2 +G=$3 +B=$4 + +# Validate range +for val in "$R" "$G" "$B"; do + if ! [ "$val" -ge 0 ] || ! [ "$val" -le 255 ]; then + echo "RGB values must be 0-255" + exit 1 + fi +done + +# Convert to hex +BRIGHTNESS_HEX=$(printf "%02X" $BRIGHTNESS) +R_HEX=$(printf "%02X" $R) +G_HEX=$(printf "%02X" $G) +B_HEX=$(printf "%02X" $B) + +# Function to calculate checksum +calculate_checksum() { + local sum=0 + for byte in "$@"; do + sum=$((sum + byte)) + done + echo $((sum & 0xFF)) +} + +# Open serial device +exec 20<>$SERIAL_DEVICE +stty -F $SERIAL_DEVICE 115200 -opost -isig -icanon -echo + +# Construct payload (without STX and checksum) +payload=(0x00 0x1C 0x20 0x01 0x80 0x00 0x81 0x00 0x8B 0x0F 0x88 0x$R_HEX 0x89 0x$G_HEX 0x8A 0x$B_HEX 0x86 0xFF 0x87 0x$BRIGHTNESS_HEX 0x58 0x02 0x45 0x00) + +# Calculate checksum +CHECKSUM=$(calculate_checksum "${payload[@]}") + +# Construct full frame: STX + payload + checksum + ETX +STX=0xF7 +ETX=0xED +FRAME=($STX "${payload[@]}" $CHECKSUM $ETX) + +# Convert to \x.. string +CMD="" +for b in "${FRAME[@]}"; do + CMD+="\\x$(printf '%02X' $b)" +done + +# Send frame +echo -ne "$CMD" > $SERIAL_DEVICE + +# Close serial device +exec 20>&- diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket EVO/bin/battery_led_status b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket EVO/bin/battery_led_status new file mode 100644 index 0000000000..7c23846c99 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket EVO/bin/battery_led_status @@ -0,0 +1,113 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Simple script to watch the battery capacity and +# turn the power LED orange when it reaches 30%, red at 20%, and blinking red at 10% + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +LED_PATH="/sys/class/leds" + +function led_brightness() { + echo ${2} >${LED_PATH}/${1}/brightness +} + +function led_rgb() { + echo ${2} ${3} ${4} >${LED_PATH}/${1}/multi_intensity +} + +function bat_led_off() { + led_brightness power-led 0 + led_rgb power-led 0 0 0 + /usr/bin/analog_sticks_ledcontrol 0 0 0 0 +} + +function bat_led_green() { + led_brightness power-led 255 + led_rgb power-led 0 255 0 + /usr/bin/analog_sticks_ledcontrol 255 0 255 0 +} + +function bat_led_red() { + led_brightness power-led 255 + led_rgb power-led 255 0 0 + /usr/bin/analog_sticks_ledcontrol 255 255 0 0 +} + +function bat_led_orange() { + led_brightness power-led 255 + led_rgb power-led 255 20 0 + /usr/bin/analog_sticks_ledcontrol 255 255 20 0 +} + +function bat_led_yellow() { + led_brightness power-led 255 + led_rgb power-led 255 125 0 + /usr/bin/analog_sticks_ledcontrol 255 255 125 0 +} + +PREV_BATCAP="null" +while true + do + BAT_LED_STATE=$(get_setting led.color) + if [ ! ${BAT_LED_STATE} == "battery" ]; then + break + fi + + CAP=$(cat /sys/class/power_supply/battery/capacity) + STAT=$(cat /sys/class/power_supply/battery/status) + + if [ ${STAT} == "Discharging" ]; then + if (( ${CAP} <= 10 )) + then + for ctr in $(seq 1 1 5) + do + bat_led_red + sleep .5 + bat_led_off + sleep .5 + done + continue + elif (( ${CAP} <= 20 )) + then + BATCAP="D_RED" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_red + fi + elif (( ${CAP} <= 30 )) + then + BATCAP="D_ORANGE" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_orange + fi + elif (( ${CAP} <= 40 )) + then + BATCAP="D_YELLOW" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_yellow + fi + else + BATCAP="D_GREEN" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_green + fi + fi + elif (( ${CAP} <= 94 )) + then + BATCAP="C_ORANGE" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_orange + fi + elif (( ${CAP} >= 95 )) + then + BATCAP="C_GREEN" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_green + fi + fi + PREV_BATCAP=${BATCAP} + sleep 15 +done diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket EVO/bin/ledcontrol b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket EVO/bin/ledcontrol new file mode 100644 index 0000000000..0809d9d193 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket EVO/bin/ledcontrol @@ -0,0 +1,126 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +LED_PATH="/sys/class/leds" + +function led_brightness() { + echo ${2} >${LED_PATH}/${1}/brightness +} + +function led_rgb() { + echo ${2} ${3} ${4} >${LED_PATH}/${1}/multi_intensity +} + +function led_off() { + led_brightness power-led 0 + led_rgb power-led 0 0 0 + /usr/bin/analog_sticks_ledcontrol 0 0 0 0 +} + +function led_red() { + led_brightness power-led 255 + led_rgb power-led 255 0 0 + /usr/bin/analog_sticks_ledcontrol 255 255 0 0 +} + +function led_green() { + led_brightness power-led 255 + led_rgb power-led 0 255 0 + /usr/bin/analog_sticks_ledcontrol 255 0 255 0 +} + +function led_blue() { + led_brightness power-led 255 + led_rgb power-led 0 0 255 + /usr/bin/analog_sticks_ledcontrol 255 0 0 255 +} + +function led_white() { + led_brightness power-led 255 + led_rgb power-led 255 255 255 + /usr/bin/analog_sticks_ledcontrol 255 255 255 255 +} + +function led_orange() { + led_brightness power-led 255 + led_rgb power-led 255 20 0 + /usr/bin/analog_sticks_ledcontrol 255 255 20 0 +} + +function led_yellow() { + led_brightness power-led 255 + led_rgb power-led 255 125 0 + /usr/bin/analog_sticks_ledcontrol 255 255 125 0 +} + +function led_purple() { + led_brightness power-led 255 + led_rgb power-led 255 0 255 + /usr/bin/analog_sticks_ledcontrol 255 255 0 255 +} + +case ${1} in + red) + led_red + set_setting led.color ${1} + ;; + green) + led_green + set_setting led.color ${1} + ;; + blue) + led_blue + set_setting led.color ${1} + ;; + white) + led_white + set_setting led.color ${1} + ;; + orange) + led_orange + set_setting led.color ${1} + ;; + yellow) + led_yellow + set_setting led.color ${1} + ;; + purple) + led_purple + set_setting led.color ${1} + ;; + off) + led_off + set_setting led.color ${1} + ;; + rgb) + LEDS_CONFIG=$(get_setting analogsticks.led) + /usr/bin/analog_sticks_ledcontrol ${LEDS_CONFIG} + set_setting led.color ${1} + ;; + battery) + led_off + set_setting led.color ${1} + systemctl restart batteryledstatus.service + ;; + poweroff) + led_off + ;; + list) +cat </storage/.config/profile.d/400-device_config +DEVICE_GPU_OVERCLOCK="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket S 2K/020-set-xbox-gamepad b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket S 2K/020-set-xbox-gamepad new file mode 100755 index 0000000000..ff500c740c --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket S 2K/020-set-xbox-gamepad @@ -0,0 +1,16 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2025 ArchR + +# Serial device +SERIAL_DEVICE="/dev/ttyHS0" + +# Open serial device +stty -F $SERIAL_DEVICE 115200 -clocal -opost -isig -icanon -echo + +# Send frame to switch gamepad to fake xbox 360 controller +printf "\xe7\x55\x05\x01\x00\x00\x00\x00\x00\x5b\xed" >$SERIAL_DEVICE +sleep 0.1 +printf "\x35\x35\x30\x35\x30\x31\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30" >$SERIAL_DEVICE +sleep 0.1 diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket S 2K/050-game-configs b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket S 2K/050-game-configs new file mode 100755 index 0000000000..909e82fcab --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket S 2K/050-game-configs @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +#Disable retroarch microphone and set default audio driver to pulse +sed -i '/^microphone_enable =/c\microphone_enable = "false"' /storage/.config/retroarch/retroarch.cfg +sed -i '/^audio_driver =/c\audio_driver = "pulse"' /storage/.config/retroarch/retroarch.cfg diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket S 2K/400-set_gpu_overclock b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket S 2K/400-set_gpu_overclock new file mode 100755 index 0000000000..d2759642e0 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket S 2K/400-set_gpu_overclock @@ -0,0 +1,22 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +# Get GPU overclock state +GPU_OC_STATE=$(get_setting "enable.gpu-overclock") +if [ ! -n "${GPU_OC_STATE}" ]; then + GPU_OC_STATE="disable" + set_setting "enable.gpu-overclock" "0" +elif [ "${GPU_OC_STATE}" = 1 ]; then + GPU_OC_STATE="enable" +else + GPU_OC_STATE="disable" + set_setting "enable.gpu-overclock" "0" +fi + +# Set GPU OC state +/usr/lib/autostart/quirks/platforms/SM8550/bin/gpu_overclock ${GPU_OC_STATE} diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket S 2K/bin/battery_led_status b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket S 2K/bin/battery_led_status new file mode 100644 index 0000000000..240448a475 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket S 2K/bin/battery_led_status @@ -0,0 +1,108 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Simple script to watch the battery capacity and +# turn the power LED orange when it reaches 30%, red at 20%, and blinking red at 10% + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +LED_PATH="/sys/class/leds" + +function led_brightness() { + echo ${2} >${LED_PATH}/${1}/brightness +} + +function led_rgb() { + echo ${2} ${3} ${4} >${LED_PATH}/${1}/multi_intensity +} + +function bat_led_off() { + led_brightness power-led 0 + led_rgb power-led 0 0 0 +} + +function bat_led_green() { + led_brightness power-led 255 + led_rgb power-led 0 255 0 +} + +function bat_led_red() { + led_brightness power-led 255 + led_rgb power-led 255 0 0 +} + +function bat_led_orange() { + led_brightness power-led 255 + led_rgb power-led 255 20 0 +} + +function bat_led_yellow() { + led_brightness power-led 255 + led_rgb power-led 255 125 0 +} + +PREV_BATCAP="null" +while true + do + BAT_LED_STATE=$(get_setting led.color) + if [ ! ${BAT_LED_STATE} == "battery" ]; then + break + fi + + CAP=$(cat /sys/class/power_supply/battery/capacity) + STAT=$(cat /sys/class/power_supply/battery/status) + + if [ ${STAT} == "Discharging" ]; then + if (( ${CAP} <= 10 )) + then + for ctr in $(seq 1 1 5) + do + bat_led_red + sleep .5 + bat_led_off + sleep .5 + done + continue + elif (( ${CAP} <= 20 )) + then + BATCAP="D_RED" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_red + fi + elif (( ${CAP} <= 30 )) + then + BATCAP="D_ORANGE" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_orange + fi + elif (( ${CAP} <= 40 )) + then + BATCAP="D_YELLOW" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_yellow + fi + else + BATCAP="D_GREEN" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_green + fi + fi + elif (( ${CAP} <= 94 )) + then + BATCAP="C_ORANGE" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_orange + fi + elif (( ${CAP} >= 95 )) + then + BATCAP="C_GREEN" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_green + fi + fi + PREV_BATCAP=${BATCAP} + sleep 15 +done diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket S 2K/bin/ledcontrol b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket S 2K/bin/ledcontrol new file mode 100644 index 0000000000..3f2da3849a --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket S 2K/bin/ledcontrol @@ -0,0 +1,113 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +LED_PATH="/sys/class/leds" + +function led_brightness() { + echo ${2} >${LED_PATH}/${1}/brightness +} + +function led_rgb() { + echo ${2} ${3} ${4} >${LED_PATH}/${1}/multi_intensity +} + +function led_off() { + led_brightness power-led 0 + led_rgb power-led 0 0 0 +} + +function led_red() { + led_brightness power-led 255 + led_rgb power-led 255 0 0 +} + +function led_green() { + led_brightness power-led 255 + led_rgb power-led 0 255 0 +} + +function led_blue() { + led_brightness power-led 255 + led_rgb power-led 0 0 255 +} + +function led_white() { + led_brightness power-led 255 + led_rgb power-led 255 255 255 +} + +function led_orange() { + led_brightness power-led 255 + led_rgb power-led 255 20 0 +} + +function led_yellow() { + led_brightness power-led 255 + led_rgb power-led 255 125 0 +} + +function led_purple() { + led_brightness power-led 255 + led_rgb power-led 255 0 255 +} + +case ${1} in + red) + led_red + set_setting led.color ${1} + ;; + green) + led_green + set_setting led.color ${1} + ;; + blue) + led_blue + set_setting led.color ${1} + ;; + white) + led_white + set_setting led.color ${1} + ;; + orange) + led_orange + set_setting led.color ${1} + ;; + yellow) + led_yellow + set_setting led.color ${1} + ;; + purple) + led_purple + set_setting led.color ${1} + ;; + off) + led_off + set_setting led.color ${1} + ;; + battery) + led_off + set_setting led.color ${1} + systemctl restart batteryledstatus.service + ;; + poweroff) + led_off + ;; + list) +cat </storage/.config/profile.d/400-device_config +DEVICE_GPU_OVERCLOCK="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket S2/020-set-xbox-gamepad b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket S2/020-set-xbox-gamepad new file mode 100755 index 0000000000..ff500c740c --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket S2/020-set-xbox-gamepad @@ -0,0 +1,16 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2025 ArchR + +# Serial device +SERIAL_DEVICE="/dev/ttyHS0" + +# Open serial device +stty -F $SERIAL_DEVICE 115200 -clocal -opost -isig -icanon -echo + +# Send frame to switch gamepad to fake xbox 360 controller +printf "\xe7\x55\x05\x01\x00\x00\x00\x00\x00\x5b\xed" >$SERIAL_DEVICE +sleep 0.1 +printf "\x35\x35\x30\x35\x30\x31\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30" >$SERIAL_DEVICE +sleep 0.1 diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket S2/050-game-configs b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket S2/050-game-configs new file mode 100755 index 0000000000..909e82fcab --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket S2/050-game-configs @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +#Disable retroarch microphone and set default audio driver to pulse +sed -i '/^microphone_enable =/c\microphone_enable = "false"' /storage/.config/retroarch/retroarch.cfg +sed -i '/^audio_driver =/c\audio_driver = "pulse"' /storage/.config/retroarch/retroarch.cfg diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket S2/400-set_gpu_overclock b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket S2/400-set_gpu_overclock new file mode 100755 index 0000000000..9a7f55dcf9 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket S2/400-set_gpu_overclock @@ -0,0 +1,22 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +# Get GPU overclock state +GPU_OC_STATE=$(get_setting "enable.gpu-overclock") +if [ ! -n "${GPU_OC_STATE}" ]; then + GPU_OC_STATE="disable" + set_setting "enable.gpu-overclock" "0" +elif [ "${GPU_OC_STATE}" = 1 ]; then + GPU_OC_STATE="enable" +else + GPU_OC_STATE="disable" + set_setting "enable.gpu-overclock" "0" +fi + +# Set GPU OC state +/usr/lib/autostart/quirks/platforms/SM8650/bin/gpu_overclock ${GPU_OC_STATE} diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket S2/bin/battery_led_status b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket S2/bin/battery_led_status new file mode 100644 index 0000000000..240448a475 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket S2/bin/battery_led_status @@ -0,0 +1,108 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Simple script to watch the battery capacity and +# turn the power LED orange when it reaches 30%, red at 20%, and blinking red at 10% + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +LED_PATH="/sys/class/leds" + +function led_brightness() { + echo ${2} >${LED_PATH}/${1}/brightness +} + +function led_rgb() { + echo ${2} ${3} ${4} >${LED_PATH}/${1}/multi_intensity +} + +function bat_led_off() { + led_brightness power-led 0 + led_rgb power-led 0 0 0 +} + +function bat_led_green() { + led_brightness power-led 255 + led_rgb power-led 0 255 0 +} + +function bat_led_red() { + led_brightness power-led 255 + led_rgb power-led 255 0 0 +} + +function bat_led_orange() { + led_brightness power-led 255 + led_rgb power-led 255 20 0 +} + +function bat_led_yellow() { + led_brightness power-led 255 + led_rgb power-led 255 125 0 +} + +PREV_BATCAP="null" +while true + do + BAT_LED_STATE=$(get_setting led.color) + if [ ! ${BAT_LED_STATE} == "battery" ]; then + break + fi + + CAP=$(cat /sys/class/power_supply/battery/capacity) + STAT=$(cat /sys/class/power_supply/battery/status) + + if [ ${STAT} == "Discharging" ]; then + if (( ${CAP} <= 10 )) + then + for ctr in $(seq 1 1 5) + do + bat_led_red + sleep .5 + bat_led_off + sleep .5 + done + continue + elif (( ${CAP} <= 20 )) + then + BATCAP="D_RED" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_red + fi + elif (( ${CAP} <= 30 )) + then + BATCAP="D_ORANGE" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_orange + fi + elif (( ${CAP} <= 40 )) + then + BATCAP="D_YELLOW" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_yellow + fi + else + BATCAP="D_GREEN" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_green + fi + fi + elif (( ${CAP} <= 94 )) + then + BATCAP="C_ORANGE" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_orange + fi + elif (( ${CAP} >= 95 )) + then + BATCAP="C_GREEN" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_green + fi + fi + PREV_BATCAP=${BATCAP} + sleep 15 +done diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket S2/bin/ledcontrol b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket S2/bin/ledcontrol new file mode 100644 index 0000000000..3f2da3849a --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYANEO Pocket S2/bin/ledcontrol @@ -0,0 +1,113 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +LED_PATH="/sys/class/leds" + +function led_brightness() { + echo ${2} >${LED_PATH}/${1}/brightness +} + +function led_rgb() { + echo ${2} ${3} ${4} >${LED_PATH}/${1}/multi_intensity +} + +function led_off() { + led_brightness power-led 0 + led_rgb power-led 0 0 0 +} + +function led_red() { + led_brightness power-led 255 + led_rgb power-led 255 0 0 +} + +function led_green() { + led_brightness power-led 255 + led_rgb power-led 0 255 0 +} + +function led_blue() { + led_brightness power-led 255 + led_rgb power-led 0 0 255 +} + +function led_white() { + led_brightness power-led 255 + led_rgb power-led 255 255 255 +} + +function led_orange() { + led_brightness power-led 255 + led_rgb power-led 255 20 0 +} + +function led_yellow() { + led_brightness power-led 255 + led_rgb power-led 255 125 0 +} + +function led_purple() { + led_brightness power-led 255 + led_rgb power-led 255 0 255 +} + +case ${1} in + red) + led_red + set_setting led.color ${1} + ;; + green) + led_green + set_setting led.color ${1} + ;; + blue) + led_blue + set_setting led.color ${1} + ;; + white) + led_white + set_setting led.color ${1} + ;; + orange) + led_orange + set_setting led.color ${1} + ;; + yellow) + led_yellow + set_setting led.color ${1} + ;; + purple) + led_purple + set_setting led.color ${1} + ;; + off) + led_off + set_setting led.color ${1} + ;; + battery) + led_off + set_setting led.color ${1} + systemctl restart batteryledstatus.service + ;; + poweroff) + led_off + ;; + list) +cat </storage/.config/profile.d/010-analog_sticks_led_control +DEVICE_ANALOG_STICKS_LED_CONTROL="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYN Odin 2 Portal/050-game-configs b/projects/ArchR/packages/hardware/quirks/devices/AYN Odin 2 Portal/050-game-configs new file mode 100644 index 0000000000..909e82fcab --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYN Odin 2 Portal/050-game-configs @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +#Disable retroarch microphone and set default audio driver to pulse +sed -i '/^microphone_enable =/c\microphone_enable = "false"' /storage/.config/retroarch/retroarch.cfg +sed -i '/^audio_driver =/c\audio_driver = "pulse"' /storage/.config/retroarch/retroarch.cfg diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYN Odin 2 Portal/bin/analog_sticks_ledcontrol b/projects/ArchR/packages/hardware/quirks/devices/AYN Odin 2 Portal/bin/analog_sticks_ledcontrol new file mode 100644 index 0000000000..d848333528 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYN Odin 2 Portal/bin/analog_sticks_ledcontrol @@ -0,0 +1,45 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +# Simple script to set led brightness and rgb color based on +# brightness and rgb values from emulation station + +LED_PATH="/sys/devices/platform/" + +function led_brightness() { + n=1 + while [ "$n" -lt 4 ]; do + echo ${2} > ${LED_PATH}/multi-led${1}${n}/leds/rgb:${1}${n}/brightness + n=$(( n + 1 )) + done +} + +function led_rgb() { + n=1 + while [ "$n" -lt 4 ]; do + echo ${2} ${3} ${4} > ${LED_PATH}/multi-led${1}${n}/leds/rgb:${1}${n}/multi_intensity + n=$(( n + 1 )) + done +} + +# Display usage if no parameters are provided +if [ $# -ne 7 ]; then + echo "Usage: $0 " + echo "Example: $0 255 255 0 0 0 0 255" + exit 1 +fi + +BRIGHTNESS=$1 +RIGHT_RED=$2 +RIGHT_GREEN=$3 +RIGHT_BLUE=$4 +LEFT_RED=$5 +LEFT_GREEN=$6 +LEFT_BLUE=$7 + +led_brightness l $BRIGHTNESS +led_rgb l $LEFT_BLUE $LEFT_GREEN $LEFT_RED +led_brightness r $BRIGHTNESS +led_rgb r $RIGHT_BLUE $RIGHT_GREEN $RIGHT_RED diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYN Odin 2 Portal/bin/battery_led_status b/projects/ArchR/packages/hardware/quirks/devices/AYN Odin 2 Portal/bin/battery_led_status new file mode 100644 index 0000000000..09f5a20f73 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYN Odin 2 Portal/bin/battery_led_status @@ -0,0 +1,128 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Simple script to watch the battery capacity and +# turn the power LED orange when it reaches 30%, red at 20%, and blinking red at 10% + +. /etc/profile + +LED_PATH="/sys/devices/platform/" + +function bat_led_off() { + n=1 + while [ "$n" -lt 4 ]; do + echo 0 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/brightness + echo 0 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/brightness + echo 0 0 0 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/multi_intensity + echo 0 0 0 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/multi_intensity + n=$(( n + 1 )) + done +} + +function bat_led_red() { + n=1 + while [ "$n" -lt 4 ]; do + echo 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/brightness + echo 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/brightness + echo 0 0 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/multi_intensity + echo 0 0 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/multi_intensity + n=$(( n + 1 )) + done +} + +function bat_led_green() { + n=1 + while [ "$n" -lt 4 ]; do + echo 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/brightness + echo 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/brightness + echo 0 255 0 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/multi_intensity + echo 0 255 0 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/multi_intensity + n=$(( n + 1 )) + done +} + +function bat_led_orange() { + n=1 + while [ "$n" -lt 4 ]; do + echo 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/brightness + echo 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/brightness + echo 0 20 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/multi_intensity + echo 0 20 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/multi_intensity + n=$(( n + 1 )) + done +} + +function bat_led_yellow() { + n=1 + while [ "$n" -lt 4 ]; do + echo 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/brightness + echo 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/brightness + echo 0 125 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/multi_intensity + echo 0 125 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/multi_intensity + n=$(( n + 1 )) + done +} + +PREV_BATCAP="null" +while true + do + BAT_LED_STATE=$(get_setting led.color) + if [ ! ${BAT_LED_STATE} == "battery" ]; then + break + else + CAP=$(cat /sys/class/power_supply/battery/capacity) + STAT=$(cat /sys/class/power_supply/battery/status) + if [ ${STAT} == "Discharging" ]; then + if (( ${CAP} <= 10 )) + then + for ctr in $(seq 1 1 5) + do + bat_led_red + sleep .5 + bat_led_off + sleep .5 + done + continue + elif (( ${CAP} <= 20 )) + then + BATCAP="D_RED" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_red + fi + elif (( ${CAP} <= 30 )) + then + BATCAP="D_ORANGE" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_orange + fi + elif (( ${CAP} <= 40 )) + then + BATCAP="D_YELLOW" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_yellow + fi + else + BATCAP="D_GREEN" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_green + fi + fi + elif (( ${CAP} <= 94 )) + then + BATCAP="C_ORANGE" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_orange + fi + elif (( ${CAP} >= 95 )) + then + BATCAP="C_GREEN" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_green + fi + fi + PREV_BATCAP=${BATCAP} + sleep 15 + fi +done diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYN Odin 2 Portal/bin/ledcontrol b/projects/ArchR/packages/hardware/quirks/devices/AYN Odin 2 Portal/bin/ledcontrol new file mode 100644 index 0000000000..8726843fc9 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYN Odin 2 Portal/bin/ledcontrol @@ -0,0 +1,45 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile + +LED_PATH="/sys/devices/platform/" + +function led_off() { + n=1 + while [ "$n" -lt 4 ]; do + echo 0 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/brightness + echo 0 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/brightness + echo 0 0 0 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/multi_intensity + echo 0 0 0 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/multi_intensity + n=$(( n + 1 )) + done +} + +case ${1} in + off) + led_off + set_setting led.color ${1} + ;; + rgb) + LEDS_CONFIG=$(get_setting analogsticks.led) + /usr/bin/analog_sticks_ledcontrol ${LEDS_CONFIG} + set_setting led.color ${1} + ;; + battery) + led_off + set_setting led.color ${1} + systemctl restart batteryledstatus.service + ;; + poweroff) + led_off + ;; + list) +cat </storage/.config/commander.cfg +disp_ppu_x=4 +disp_ppu_y=4 +EOF +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYN Odin 2/010-analog_sticks_led_control b/projects/ArchR/packages/hardware/quirks/devices/AYN Odin 2/010-analog_sticks_led_control new file mode 100755 index 0000000000..8a21241d44 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYN Odin 2/010-analog_sticks_led_control @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/010-analog_sticks_led_control +DEVICE_ANALOG_STICKS_LED_CONTROL="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYN Odin 2/050-game-configs b/projects/ArchR/packages/hardware/quirks/devices/AYN Odin 2/050-game-configs new file mode 100644 index 0000000000..909e82fcab --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYN Odin 2/050-game-configs @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +#Disable retroarch microphone and set default audio driver to pulse +sed -i '/^microphone_enable =/c\microphone_enable = "false"' /storage/.config/retroarch/retroarch.cfg +sed -i '/^audio_driver =/c\audio_driver = "pulse"' /storage/.config/retroarch/retroarch.cfg diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYN Odin 2/bin/achievements b/projects/ArchR/packages/hardware/quirks/devices/AYN Odin 2/bin/achievements new file mode 100755 index 0000000000..998b929d2d --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYN Odin 2/bin/achievements @@ -0,0 +1,100 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + + # Rainbow effect configuration + STEPS=30 # Fewer steps for faster transitions + DURATION=0.5 # Shorter duration (half a second per cycle) + SLEEP_TIME=$(echo "scale=4; $DURATION/$STEPS" | bc) + CYCLES=2 # Number of cycles to run + +function calculate_rainbow_color() { + local position=$1 + local h=$(echo "scale=2; 360*$position/$STEPS" | bc) + + # Convert HSV (with S=1, V=1) to RGB + # Calculate region and fractional part + local region=$(echo "scale=0; $h/60" | bc) + local remainder=$(echo "scale=2; $h-$region*60" | bc) + local fractional=$(echo "scale=2; $remainder/60" | bc) + + # Initialize RGB values + local r=0 + local g=0 + local b=0 + + # Calculate RGB based on hue region (0-5) + case $region in + 0) + # 0-60: Red to Yellow + r=255 + g=$(echo "scale=0; 255*$fractional" | bc) + b=0 + ;; + 1) + # 60-120: Yellow to Green + r=$(echo "scale=0; 255*(1-$fractional)" | bc) + g=255 + b=0 + ;; + 2) + # 120-180: Green to Cyan + r=0 + g=255 + b=$(echo "scale=0; 255*$fractional" | bc) + ;; + 3) + # 180-240: Cyan to Blue + r=0 + g=$(echo "scale=0; 255*(1-$fractional)" | bc) + b=255 + ;; + 4) + # 240-300: Blue to Magenta + r=$(echo "scale=0; 255*$fractional" | bc) + g=0 + b=255 + ;; + 5|6) + # 300-360: Magenta to Red + r=255 + g=0 + b=$(echo "scale=0; 255*(1-$fractional)" | bc) + ;; + esac + + # Ensure values are integers + r=${r%.*} + g=${g%.*} + b=${b%.*} + + # Ensure values are not negative or exceed 255 + r=$(( r < 0 ? 0 : r > 255 ? 255 : r )) + g=$(( g < 0 ? 0 : g > 255 ? 255 : g )) + b=$(( b < 0 ? 0 : b > 255 ? 255 : b )) + + echo "$r $g $b" +} + +# Main rainbow effect loop +# Loop several times to create a continuous effect +for ((cycle=0; cycle${LED_PATH}/${1}/brightness +} + +function led_rgb() { + echo ${2} ${3} ${4} >${LED_PATH}/${1}/multi_intensity +} + +# Display usage if no parameters are provided +if [ $# -ne 7 ]; then + echo "Usage: $0 " + echo "Example: $0 255 255 0 0 0 0 255" + exit 1 +fi + +BRIGHTNESS=$1 +RIGHT_RED=$2 +RIGHT_GREEN=$3 +RIGHT_BLUE=$4 +LEFT_RED=$5 +LEFT_GREEN=$6 +LEFT_BLUE=$7 + +led_brightness left-joystick $BRIGHTNESS +led_rgb left-joystick $LEFT_RED $LEFT_GREEN $LEFT_BLUE +led_brightness left-side $BRIGHTNESS +led_rgb left-side $LEFT_RED $LEFT_GREEN $LEFT_BLUE + +led_brightness right-joystick $BRIGHTNESS +led_rgb right-joystick $RIGHT_RED $RIGHT_GREEN $RIGHT_BLUE +led_brightness right-side $BRIGHTNESS +led_rgb right-side $RIGHT_RED $RIGHT_GREEN $RIGHT_BLUE diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYN Odin 2/bin/battery_led_status b/projects/ArchR/packages/hardware/quirks/devices/AYN Odin 2/bin/battery_led_status new file mode 100644 index 0000000000..240448a475 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYN Odin 2/bin/battery_led_status @@ -0,0 +1,108 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Simple script to watch the battery capacity and +# turn the power LED orange when it reaches 30%, red at 20%, and blinking red at 10% + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +LED_PATH="/sys/class/leds" + +function led_brightness() { + echo ${2} >${LED_PATH}/${1}/brightness +} + +function led_rgb() { + echo ${2} ${3} ${4} >${LED_PATH}/${1}/multi_intensity +} + +function bat_led_off() { + led_brightness power-led 0 + led_rgb power-led 0 0 0 +} + +function bat_led_green() { + led_brightness power-led 255 + led_rgb power-led 0 255 0 +} + +function bat_led_red() { + led_brightness power-led 255 + led_rgb power-led 255 0 0 +} + +function bat_led_orange() { + led_brightness power-led 255 + led_rgb power-led 255 20 0 +} + +function bat_led_yellow() { + led_brightness power-led 255 + led_rgb power-led 255 125 0 +} + +PREV_BATCAP="null" +while true + do + BAT_LED_STATE=$(get_setting led.color) + if [ ! ${BAT_LED_STATE} == "battery" ]; then + break + fi + + CAP=$(cat /sys/class/power_supply/battery/capacity) + STAT=$(cat /sys/class/power_supply/battery/status) + + if [ ${STAT} == "Discharging" ]; then + if (( ${CAP} <= 10 )) + then + for ctr in $(seq 1 1 5) + do + bat_led_red + sleep .5 + bat_led_off + sleep .5 + done + continue + elif (( ${CAP} <= 20 )) + then + BATCAP="D_RED" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_red + fi + elif (( ${CAP} <= 30 )) + then + BATCAP="D_ORANGE" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_orange + fi + elif (( ${CAP} <= 40 )) + then + BATCAP="D_YELLOW" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_yellow + fi + else + BATCAP="D_GREEN" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_green + fi + fi + elif (( ${CAP} <= 94 )) + then + BATCAP="C_ORANGE" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_orange + fi + elif (( ${CAP} >= 95 )) + then + BATCAP="C_GREEN" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_green + fi + fi + PREV_BATCAP=${BATCAP} + sleep 15 +done diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYN Odin 2/bin/ledcontrol b/projects/ArchR/packages/hardware/quirks/devices/AYN Odin 2/bin/ledcontrol new file mode 100644 index 0000000000..3f2da3849a --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYN Odin 2/bin/ledcontrol @@ -0,0 +1,113 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +LED_PATH="/sys/class/leds" + +function led_brightness() { + echo ${2} >${LED_PATH}/${1}/brightness +} + +function led_rgb() { + echo ${2} ${3} ${4} >${LED_PATH}/${1}/multi_intensity +} + +function led_off() { + led_brightness power-led 0 + led_rgb power-led 0 0 0 +} + +function led_red() { + led_brightness power-led 255 + led_rgb power-led 255 0 0 +} + +function led_green() { + led_brightness power-led 255 + led_rgb power-led 0 255 0 +} + +function led_blue() { + led_brightness power-led 255 + led_rgb power-led 0 0 255 +} + +function led_white() { + led_brightness power-led 255 + led_rgb power-led 255 255 255 +} + +function led_orange() { + led_brightness power-led 255 + led_rgb power-led 255 20 0 +} + +function led_yellow() { + led_brightness power-led 255 + led_rgb power-led 255 125 0 +} + +function led_purple() { + led_brightness power-led 255 + led_rgb power-led 255 0 255 +} + +case ${1} in + red) + led_red + set_setting led.color ${1} + ;; + green) + led_green + set_setting led.color ${1} + ;; + blue) + led_blue + set_setting led.color ${1} + ;; + white) + led_white + set_setting led.color ${1} + ;; + orange) + led_orange + set_setting led.color ${1} + ;; + yellow) + led_yellow + set_setting led.color ${1} + ;; + purple) + led_purple + set_setting led.color ${1} + ;; + off) + led_off + set_setting led.color ${1} + ;; + battery) + led_off + set_setting led.color ${1} + systemctl restart batteryledstatus.service + ;; + poweroff) + led_off + ;; + list) +cat </storage/.config/profile.d/010-analog_sticks_led_control +DEVICE_ANALOG_STICKS_LED_CONTROL="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYN Odin/050-game-configs b/projects/ArchR/packages/hardware/quirks/devices/AYN Odin/050-game-configs new file mode 100755 index 0000000000..909e82fcab --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYN Odin/050-game-configs @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +#Disable retroarch microphone and set default audio driver to pulse +sed -i '/^microphone_enable =/c\microphone_enable = "false"' /storage/.config/retroarch/retroarch.cfg +sed -i '/^audio_driver =/c\audio_driver = "pulse"' /storage/.config/retroarch/retroarch.cfg diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYN Thor/009-commander-cfg b/projects/ArchR/packages/hardware/quirks/devices/AYN Thor/009-commander-cfg new file mode 100644 index 0000000000..044bb46732 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYN Thor/009-commander-cfg @@ -0,0 +1,11 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +if [ ! -f "/storage/.config/commander.cfg" ]; then +cat </storage/.config/commander.cfg +disp_ppu_x=4 +disp_ppu_y=4 +EOF +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYN Thor/010-analog_sticks_led_control b/projects/ArchR/packages/hardware/quirks/devices/AYN Thor/010-analog_sticks_led_control new file mode 100755 index 0000000000..8a21241d44 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYN Thor/010-analog_sticks_led_control @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/010-analog_sticks_led_control +DEVICE_ANALOG_STICKS_LED_CONTROL="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYN Thor/050-game-configs b/projects/ArchR/packages/hardware/quirks/devices/AYN Thor/050-game-configs new file mode 100644 index 0000000000..50babf7b79 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYN Thor/050-game-configs @@ -0,0 +1,21 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025-present ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile.d/001-functions + +#Disable retroarch microphone and set default audio driver to pulse +sed -i '/^microphone_enable =/c\microphone_enable = "false"' /storage/.config/retroarch/retroarch.cfg +sed -i '/^audio_driver =/c\audio_driver = "pulse"' /storage/.config/retroarch/retroarch.cfg + +#Set default layouts for 3DS +THREE_DS_SCREEN_LAYOUT=$(get_setting "3ds.screen_layout") +if [ ! -n "${THREE_DS_SCREEN_LAYOUT}" ]; then + set_setting "3ds.screen_layout" "5" +fi + +#Set default layouts for NDS +NDS_SCREEN_LAYOUT=$(get_setting "nds.screen_layout") +if [ ! -n "${NDS_SCREEN_LAYOUT}" ]; then + set_setting "nds.screen_layout" "6" +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYN Thor/bin/analog_sticks_ledcontrol b/projects/ArchR/packages/hardware/quirks/devices/AYN Thor/bin/analog_sticks_ledcontrol new file mode 100644 index 0000000000..d848333528 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYN Thor/bin/analog_sticks_ledcontrol @@ -0,0 +1,45 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +# Simple script to set led brightness and rgb color based on +# brightness and rgb values from emulation station + +LED_PATH="/sys/devices/platform/" + +function led_brightness() { + n=1 + while [ "$n" -lt 4 ]; do + echo ${2} > ${LED_PATH}/multi-led${1}${n}/leds/rgb:${1}${n}/brightness + n=$(( n + 1 )) + done +} + +function led_rgb() { + n=1 + while [ "$n" -lt 4 ]; do + echo ${2} ${3} ${4} > ${LED_PATH}/multi-led${1}${n}/leds/rgb:${1}${n}/multi_intensity + n=$(( n + 1 )) + done +} + +# Display usage if no parameters are provided +if [ $# -ne 7 ]; then + echo "Usage: $0 " + echo "Example: $0 255 255 0 0 0 0 255" + exit 1 +fi + +BRIGHTNESS=$1 +RIGHT_RED=$2 +RIGHT_GREEN=$3 +RIGHT_BLUE=$4 +LEFT_RED=$5 +LEFT_GREEN=$6 +LEFT_BLUE=$7 + +led_brightness l $BRIGHTNESS +led_rgb l $LEFT_BLUE $LEFT_GREEN $LEFT_RED +led_brightness r $BRIGHTNESS +led_rgb r $RIGHT_BLUE $RIGHT_GREEN $RIGHT_RED diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYN Thor/bin/battery_led_status b/projects/ArchR/packages/hardware/quirks/devices/AYN Thor/bin/battery_led_status new file mode 100644 index 0000000000..09f5a20f73 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYN Thor/bin/battery_led_status @@ -0,0 +1,128 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Simple script to watch the battery capacity and +# turn the power LED orange when it reaches 30%, red at 20%, and blinking red at 10% + +. /etc/profile + +LED_PATH="/sys/devices/platform/" + +function bat_led_off() { + n=1 + while [ "$n" -lt 4 ]; do + echo 0 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/brightness + echo 0 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/brightness + echo 0 0 0 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/multi_intensity + echo 0 0 0 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/multi_intensity + n=$(( n + 1 )) + done +} + +function bat_led_red() { + n=1 + while [ "$n" -lt 4 ]; do + echo 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/brightness + echo 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/brightness + echo 0 0 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/multi_intensity + echo 0 0 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/multi_intensity + n=$(( n + 1 )) + done +} + +function bat_led_green() { + n=1 + while [ "$n" -lt 4 ]; do + echo 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/brightness + echo 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/brightness + echo 0 255 0 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/multi_intensity + echo 0 255 0 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/multi_intensity + n=$(( n + 1 )) + done +} + +function bat_led_orange() { + n=1 + while [ "$n" -lt 4 ]; do + echo 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/brightness + echo 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/brightness + echo 0 20 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/multi_intensity + echo 0 20 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/multi_intensity + n=$(( n + 1 )) + done +} + +function bat_led_yellow() { + n=1 + while [ "$n" -lt 4 ]; do + echo 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/brightness + echo 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/brightness + echo 0 125 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/multi_intensity + echo 0 125 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/multi_intensity + n=$(( n + 1 )) + done +} + +PREV_BATCAP="null" +while true + do + BAT_LED_STATE=$(get_setting led.color) + if [ ! ${BAT_LED_STATE} == "battery" ]; then + break + else + CAP=$(cat /sys/class/power_supply/battery/capacity) + STAT=$(cat /sys/class/power_supply/battery/status) + if [ ${STAT} == "Discharging" ]; then + if (( ${CAP} <= 10 )) + then + for ctr in $(seq 1 1 5) + do + bat_led_red + sleep .5 + bat_led_off + sleep .5 + done + continue + elif (( ${CAP} <= 20 )) + then + BATCAP="D_RED" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_red + fi + elif (( ${CAP} <= 30 )) + then + BATCAP="D_ORANGE" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_orange + fi + elif (( ${CAP} <= 40 )) + then + BATCAP="D_YELLOW" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_yellow + fi + else + BATCAP="D_GREEN" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_green + fi + fi + elif (( ${CAP} <= 94 )) + then + BATCAP="C_ORANGE" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_orange + fi + elif (( ${CAP} >= 95 )) + then + BATCAP="C_GREEN" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_green + fi + fi + PREV_BATCAP=${BATCAP} + sleep 15 + fi +done diff --git a/projects/ArchR/packages/hardware/quirks/devices/AYN Thor/bin/ledcontrol b/projects/ArchR/packages/hardware/quirks/devices/AYN Thor/bin/ledcontrol new file mode 100644 index 0000000000..8726843fc9 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/AYN Thor/bin/ledcontrol @@ -0,0 +1,45 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile + +LED_PATH="/sys/devices/platform/" + +function led_off() { + n=1 + while [ "$n" -lt 4 ]; do + echo 0 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/brightness + echo 0 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/brightness + echo 0 0 0 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/multi_intensity + echo 0 0 0 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/multi_intensity + n=$(( n + 1 )) + done +} + +case ${1} in + off) + led_off + set_setting led.color ${1} + ;; + rgb) + LEDS_CONFIG=$(get_setting analogsticks.led) + /usr/bin/analog_sticks_ledcontrol ${LEDS_CONFIG} + set_setting led.color ${1} + ;; + battery) + led_off + set_setting led.color ${1} + systemctl restart batteryledstatus.service + ;; + poweroff) + led_off + ;; + list) +cat </run/udev/rules.d/99-touchscreen-calibration.rules +# left panel (ID_PATH=platform-a90000.i2c) -> (0 .. 1920) x (0 .. 1080) +SUBSYSTEM=="input", KERNEL=="event*", ENV{ID_INPUT_TOUCHSCREEN}=="1", \ + ENV{ID_PATH}=="platform-a90000.i2c", \ + ENV{LIBINPUT_CALIBRATION_MATRIX}="0.607595 0 0 0 1 0" + +# right panel (ID_PATH=platform-98c000.i2c) -> (1920 .. 3160) x (0 .. 1080) +SUBSYSTEM=="input", KERNEL=="event*", ENV{ID_INPUT_TOUCHSCREEN}=="1", \ + ENV{ID_PATH}=="platform-98c000.i2c", \ + ENV{LIBINPUT_CALIBRATION_MATRIX}="0.392405 0 0.607595 0 1 0" +EOF +udevadm control --reload +udevadm trigger -s input \ No newline at end of file diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-D/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-D/001-device_config new file mode 100755 index 0000000000..e544be2b09 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-D/001-device_config @@ -0,0 +1,9 @@ +#!/bin/sh +# SPDX-License-Identifier: Apache-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/001-device_config +DEVICE_FAKE_JACKSENSE="false" +DEVICE_BATTERY_LED_STATUS="true" +DEVICE_HAS_TOUCHSCREEN="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-D/020-gpios b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-D/020-gpios new file mode 100755 index 0000000000..357fcb1087 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-D/020-gpios @@ -0,0 +1,15 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/020-gpios +DEVICE_WIFI="0" +DEVICE_PWM_MOTOR="pwmchip1" +EOF + +. /storage/.config/profile.d/020-gpios +# Enable PWM for rumble and turn rumble off during startup. +echo 0 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/export +echo 1000000 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/period +echo 1 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/enable +echo 1000000 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/duty_cycle diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-D/050-game-configs b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-D/050-game-configs new file mode 100755 index 0000000000..876f8dce0e --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-D/050-game-configs @@ -0,0 +1,154 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +#Set mupen64-plus-sa config for R33S +if [ ! -d "/storage/.config/mupen64plus" ]; then + mkdir -p "/storage/.config/mupen64plus/" + cp -r /usr/local/share/mupen64plus/mupen64plus.cfg* /storage/.config/mupen64plus/ +fi +if [ -f "/storage/.config/mupen64plus/mupen64plus.cfg.rgarc" ]; then + rm /storage/.config/mupen64plus/mupen64plus.cfg + mv /storage/.config/mupen64plus/mupen64plus.cfg.rgarc /storage/.config/mupen64plus/mupen64plus.cfg +fi +if [ ! -f "/storage/.config/mupen64plus/custominput.ini" ]; then +cat </storage/.config/mupen64plus/custominput.ini +[rg_arc_joypad] +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = button(15) +DPad L = button(14) +DPad D = button(13) +DPad U = button(12) +Start = button(11) +Z Trig = button(8) +B Button = button(3) +A Button = button(1) +C Button R = button(2) +C Button L = button(4) +C Button D = button(0) +C Button U = button(5) +R Trig = button(7) +L Trig = button(6) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = +Y Axis = +EOF +fi + +#Set drastic-sa config +if [ ! -d "/storage/.config/drastic" ]; then + mkdir -p "/storage/.config/drastic" + cp -r "/usr/config/drastic" "/storage/.config/" +fi +if [ -f "/storage/.config/drastic/config/drastic.cfg.arc" ]; then + mv /storage/.config/drastic/config/drastic.cfg.arc /storage/.config/drastic/config/drastic.cfg +fi + +# Copy over device specific retroarch remappings unless they already exist +REMAP_DIR="/usr/lib/autostart/quirks/devices/${QUIRK_DEVICE}/remappings" +if [ -d "${REMAP_DIR}" ]; then + for dir in "${REMAP_DIR}"/*/; do + CORE_NAME=$(basename "${dir}") + if [ ! -d "/storage/remappings/${CORE_NAME}" ]; then + cp -r "${dir}" "/storage/remappings/" + fi + done +fi + +# hypseus aka daphne +if [ ! -d "/storage/.config/game/configs/hypseus/" ]; then + mkdir -p /storage/.config/game/configs/hypseus/ +fi +if [ ! -f "/storage/.config/game/configs/hypseus/hypinput.ini" ]; then +cat </storage/.config/game/configs/hypseus/hypinput.ini +# Sample hypinput.ini +# All key options listed +# Arcade layout by OzFalcon +# Hypseus uses SDL2 Keycodes +# KEY_BUTTON3 Turns scoreboard on/off +# SWITCH = Key1 Key2 Joy +# Start + Select will exit game +################################## +#Button Info for ARC-D running ArchR by Morfious +# +#Controller Button ID# Game Function +#Dpad Up 13 Dpad Up 1073741906 SDLK_UP BUTTON_DPAD_UP +#Dpad Down 14 Dpad Down 1073741905 SDLK_DOWN BUTTON_DPAD_DOWN +#Dpad Left 15 Dpad Left 1073741904 SDLK_LEFT BUTTON_DPAD_LEFT +#Dpad Right 16 Dpad Right 1073741903 SDLK_RIGHT BUTTON_DPAD_RIGHT +#Select 11 Insert Coin +#Start 12 Start Game +#A Button 2 Button 1 +#B Button 1 Button 2 +#C Button 3 Toggle Scoreboard +#X Button 4 Skill 1 +#Y Button 5 Skill 2 +#Z Button 6 Skill 3 +#L1 7 Pause +#R1 8 Test Mode +#L2 9 Reset +#R2 10 Service Mode + +[KEYBOARD] +KEY_UP = 1073741906 SDLK_UP 13 +KEY_DOWN = 1073741905 SDLK_DOWN 14 +KEY_LEFT = 1073741904 SDLK_LEFT 15 +KEY_RIGHT = 1073741903 SDLK_RIGHT 16 +KEY_COIN1 = SDLK_5 0 11 +KEY_COIN2 = SDLK_6 0 0 +KEY_START1 = SDLK_1 0 12 +KEY_START2 = SDLK_2 0 0 +KEY_BUTTON1 = SDLK_LCTRL 0 2 +KEY_BUTTON2 = SDLK_LALT 0 1 +KEY_BUTTON3 = SDLK_SPACE 0 3 +KEY_SKILL1 = SDLK_LSHIFT 0 4 +KEY_SKILL2 = SDLK_z 0 5 +KEY_SKILL3 = SDLK_x 0 6 +KEY_SERVICE = SDLK_9 0 10 +KEY_TEST = SDLK_F2 SDLK_F4 8 +KEY_RESET = SDLK_0 0 9 +KEY_SCREENSHOT = SDLK_F12 0 0 +KEY_QUIT = SDLK_ESCAPE 0 0 +KEY_PAUSE = SDLK_p 0 7 +KEY_CONSOLE = SDLK_BACKSLASH 0 0 +KEY_TILT = SDLK_t 0 0 +END +EOF +fi + +# PPSSPP controls +SOURCE_DIR="/usr/config/ppsspp" +CONF_DIR="/storage/.config/ppsspp" +# Check if conf dir exists +if [ ! -d "${CONF_DIR}" ] +then + cp -rf ${SOURCE_DIR} ${CONF_DIR} + CONTROLS_INI="${CONF_DIR}/PSP/SYSTEM/controls.ini" + cat <${CONTROLS_INI} +[ControlMapping] +Up = 10-19 +Down = 10-20 +Left = 10-21 +Right = 10-22 +Cross = 10-190 +Circle = 10-189 +Square = 10-188 +Triangle = 10-191 +Start = 10-197 +Select = 10-196 +L = 10-193 +R = 10-192 +An.Up = 10-4003 +An.Down = 10-4002 +An.Left = 10-4001 +An.Right = 10-4000 +Pause = 10-4,10-106 +Save State = 10-4010 +Load State = 10-4008 +EOF +fi + diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-D/remappings/Beetle PC-FX/Beetle PC-FX.rmp b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-D/remappings/Beetle PC-FX/Beetle PC-FX.rmp new file mode 100644 index 0000000000..9e2a9d5037 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-D/remappings/Beetle PC-FX/Beetle PC-FX.rmp @@ -0,0 +1,22 @@ +input_libretro_device_p1 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_player1_analog_dpad_mode = "1" +input_player1_btn_a = "0" +input_player1_btn_b = "9" +input_player1_btn_l = "-1" +input_player1_btn_l3 = "11" +input_player1_btn_r = "-1" +input_player1_btn_r3 = "8" +input_player1_btn_x = "10" +input_player2_analog_dpad_mode = "0" +input_player3_analog_dpad_mode = "0" +input_player4_analog_dpad_mode = "0" +input_player5_analog_dpad_mode = "0" +input_remap_port_p1 = "0" +input_remap_port_p2 = "1" +input_remap_port_p3 = "2" +input_remap_port_p4 = "3" +input_remap_port_p5 = "4" diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-D/remappings/Flycast/Flycast.rmp b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-D/remappings/Flycast/Flycast.rmp new file mode 100644 index 0000000000..0fd5df11c6 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-D/remappings/Flycast/Flycast.rmp @@ -0,0 +1,19 @@ +input_libretro_device_p1 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_player1_analog_dpad_mode = "0" +input_player1_stk_l_x+ = "-1" +input_player1_stk_l_x- = "-1" +input_player1_stk_l_y+ = "-1" +input_player1_stk_l_y- = "-1" +input_player2_analog_dpad_mode = "0" +input_player3_analog_dpad_mode = "0" +input_player4_analog_dpad_mode = "0" +input_player5_analog_dpad_mode = "0" +input_remap_port_p1 = "0" +input_remap_port_p2 = "1" +input_remap_port_p3 = "2" +input_remap_port_p4 = "3" +input_remap_port_p5 = "4" diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-D/remappings/Genesis Plus GX/Genesis Plus GX.rmp b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-D/remappings/Genesis Plus GX/Genesis Plus GX.rmp new file mode 100644 index 0000000000..83420fa59b --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-D/remappings/Genesis Plus GX/Genesis Plus GX.rmp @@ -0,0 +1,22 @@ +input_libretro_device_p1 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_player1_analog_dpad_mode = "1" +input_player1_btn_a = "0" +input_player1_btn_b = "1" +input_player1_btn_l = "-1" +input_player1_btn_l3 = "11" +input_player1_btn_r = "-1" +input_player1_btn_r3 = "8" +input_player1_btn_y = "10" +input_player2_analog_dpad_mode = "0" +input_player3_analog_dpad_mode = "0" +input_player4_analog_dpad_mode = "0" +input_player5_analog_dpad_mode = "0" +input_remap_port_p1 = "0" +input_remap_port_p2 = "1" +input_remap_port_p3 = "2" +input_remap_port_p4 = "3" +input_remap_port_p5 = "4" diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-D/remappings/Mupen64Plus GLES2/Mupen64Plus GLES2.rmp b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-D/remappings/Mupen64Plus GLES2/Mupen64Plus GLES2.rmp new file mode 100644 index 0000000000..b682320c97 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-D/remappings/Mupen64Plus GLES2/Mupen64Plus GLES2.rmp @@ -0,0 +1,33 @@ +#R33S +input_libretro_device_p1 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_player1_analog_dpad_mode = "0" +input_player1_btn_a = "22" +input_player1_btn_down = "18" +input_player1_btn_l = "12" +input_player1_btn_l2 = "21" +input_player1_btn_left = "17" +input_player1_btn_r2 = "20" +input_player1_btn_right = "16" +input_player1_btn_up = "19" +input_player1_btn_x = "23" +input_player1_stk_l_x+ = "-1" +input_player1_stk_l_x- = "-1" +input_player1_stk_l_y+ = "-1" +input_player1_stk_l_y- = "-1" +input_player1_stk_r_x+ = "-1" +input_player1_stk_r_x- = "-1" +input_player1_stk_r_y+ = "-1" +input_player1_stk_r_y- = "-1" +input_player2_analog_dpad_mode = "0" +input_player3_analog_dpad_mode = "0" +input_player4_analog_dpad_mode = "0" +input_player5_analog_dpad_mode = "0" +input_remap_port_p1 = "0" +input_remap_port_p2 = "1" +input_remap_port_p3 = "2" +input_remap_port_p4 = "3" +input_remap_port_p5 = "4" diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-D/remappings/Opera/Opera.rmp b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-D/remappings/Opera/Opera.rmp new file mode 100644 index 0000000000..0db3b832a3 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-D/remappings/Opera/Opera.rmp @@ -0,0 +1,19 @@ +input_libretro_device_p1 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_player1_analog_dpad_mode = "1" +input_player1_btn_a = "0" +input_player1_btn_b = "1" +input_player1_btn_r3 = "8" +input_player1_btn_y = "-1" +input_player2_analog_dpad_mode = "0" +input_player3_analog_dpad_mode = "0" +input_player4_analog_dpad_mode = "0" +input_player5_analog_dpad_mode = "0" +input_remap_port_p1 = "0" +input_remap_port_p2 = "1" +input_remap_port_p3 = "2" +input_remap_port_p4 = "3" +input_remap_port_p5 = "4" diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-D/remappings/PicoDrive/PicoDrive.rmp b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-D/remappings/PicoDrive/PicoDrive.rmp new file mode 100644 index 0000000000..83420fa59b --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-D/remappings/PicoDrive/PicoDrive.rmp @@ -0,0 +1,22 @@ +input_libretro_device_p1 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_player1_analog_dpad_mode = "1" +input_player1_btn_a = "0" +input_player1_btn_b = "1" +input_player1_btn_l = "-1" +input_player1_btn_l3 = "11" +input_player1_btn_r = "-1" +input_player1_btn_r3 = "8" +input_player1_btn_y = "10" +input_player2_analog_dpad_mode = "0" +input_player3_analog_dpad_mode = "0" +input_player4_analog_dpad_mode = "0" +input_player5_analog_dpad_mode = "0" +input_remap_port_p1 = "0" +input_remap_port_p2 = "1" +input_remap_port_p3 = "2" +input_remap_port_p4 = "3" +input_remap_port_p5 = "4" diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-D/remappings/YabaSanshiro/YabaSanshiro.rmp b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-D/remappings/YabaSanshiro/YabaSanshiro.rmp new file mode 100644 index 0000000000..8c68e14c65 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-D/remappings/YabaSanshiro/YabaSanshiro.rmp @@ -0,0 +1,28 @@ +input_libretro_device_p1 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_player1_analog_dpad_mode = "1" +input_player1_btn_l = "12" +input_player1_btn_l2 = "-1" +input_player1_btn_l3 = "11" +input_player1_btn_r = "13" +input_player1_btn_r2 = "-1" +input_player1_btn_r3 = "10" +input_player2_analog_dpad_mode = "0" +input_player3_analog_dpad_mode = "0" +input_player4_analog_dpad_mode = "0" +input_player5_analog_dpad_mode = "0" +input_remap_port_p1 = "0" +input_remap_port_p2 = "1" +input_remap_port_p3 = "2" +input_remap_port_p4 = "3" +input_remap_port_p5 = "4" +input_turbo_allow_dpad = "false" +input_turbo_bind = "-1" +input_turbo_button = "0" +input_turbo_duty_cycle = "0" +input_turbo_enable = "true" +input_turbo_mode = "0" +input_turbo_period = "6" diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-S/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-S/001-device_config new file mode 100755 index 0000000000..fb9818eec8 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-S/001-device_config @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/001-device_config +DEVICE_FAKE_JACKSENSE="false" +DEVICE_BATTERY_LED_STATUS="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-S/020-gpios b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-S/020-gpios new file mode 120000 index 0000000000..f892ec22a6 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-S/020-gpios @@ -0,0 +1 @@ +../Anbernic RG ARC-D/020-gpios \ No newline at end of file diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-S/050-game-configs b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-S/050-game-configs new file mode 120000 index 0000000000..940a8a6388 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-S/050-game-configs @@ -0,0 +1 @@ +../Anbernic RG ARC-D/050-game-configs \ No newline at end of file diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-S/remappings b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-S/remappings new file mode 120000 index 0000000000..aece2cf044 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG ARC-S/remappings @@ -0,0 +1 @@ +../Anbernic RG ARC-D/remappings \ No newline at end of file diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG CubeXX/010-analog_sticks_led_control b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG CubeXX/010-analog_sticks_led_control new file mode 100755 index 0000000000..8a21241d44 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG CubeXX/010-analog_sticks_led_control @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/010-analog_sticks_led_control +DEVICE_ANALOG_STICKS_LED_CONTROL="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG CubeXX/bin/achievements b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG CubeXX/bin/achievements new file mode 100755 index 0000000000..998b929d2d --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG CubeXX/bin/achievements @@ -0,0 +1,100 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + + # Rainbow effect configuration + STEPS=30 # Fewer steps for faster transitions + DURATION=0.5 # Shorter duration (half a second per cycle) + SLEEP_TIME=$(echo "scale=4; $DURATION/$STEPS" | bc) + CYCLES=2 # Number of cycles to run + +function calculate_rainbow_color() { + local position=$1 + local h=$(echo "scale=2; 360*$position/$STEPS" | bc) + + # Convert HSV (with S=1, V=1) to RGB + # Calculate region and fractional part + local region=$(echo "scale=0; $h/60" | bc) + local remainder=$(echo "scale=2; $h-$region*60" | bc) + local fractional=$(echo "scale=2; $remainder/60" | bc) + + # Initialize RGB values + local r=0 + local g=0 + local b=0 + + # Calculate RGB based on hue region (0-5) + case $region in + 0) + # 0-60: Red to Yellow + r=255 + g=$(echo "scale=0; 255*$fractional" | bc) + b=0 + ;; + 1) + # 60-120: Yellow to Green + r=$(echo "scale=0; 255*(1-$fractional)" | bc) + g=255 + b=0 + ;; + 2) + # 120-180: Green to Cyan + r=0 + g=255 + b=$(echo "scale=0; 255*$fractional" | bc) + ;; + 3) + # 180-240: Cyan to Blue + r=0 + g=$(echo "scale=0; 255*(1-$fractional)" | bc) + b=255 + ;; + 4) + # 240-300: Blue to Magenta + r=$(echo "scale=0; 255*$fractional" | bc) + g=0 + b=255 + ;; + 5|6) + # 300-360: Magenta to Red + r=255 + g=0 + b=$(echo "scale=0; 255*(1-$fractional)" | bc) + ;; + esac + + # Ensure values are integers + r=${r%.*} + g=${g%.*} + b=${b%.*} + + # Ensure values are not negative or exceed 255 + r=$(( r < 0 ? 0 : r > 255 ? 255 : r )) + g=$(( g < 0 ? 0 : g > 255 ? 255 : g )) + b=$(( b < 0 ? 0 : b > 255 ? 255 : b )) + + echo "$r $g $b" +} + +# Main rainbow effect loop +# Loop several times to create a continuous effect +for ((cycle=0; cycle/storage/.config/profile.d/001-device_config +DEVICE_FAKE_JACKSENSE="false" +DEVICE_BATTERY_LED_STATUS="true" +DEVICE_HAS_TOUCHSCREEN="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG DS/050-audio_path b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG DS/050-audio_path new file mode 100755 index 0000000000..fcfee70701 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG DS/050-audio_path @@ -0,0 +1,10 @@ +#!/bin/sh +# SPDX-License-Identifier: Apache-2.0 +# Copyright (C) 2021-present Fewtarius (https://github.com/fewtarius) + +cat </storage/.config/profile.d/002-audio_path +ALSA_PRIMARY_CARD=0 +DEVICE_PLAYBACK_PATH_SPK="HP" +DEVICE_PLAYBACK_PATH_HP="HP" +DEVICE_PLAYBACK_PATH="Playback Mux" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG DS/050-game_configs b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG DS/050-game_configs new file mode 100755 index 0000000000..850ce5d300 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG DS/050-game_configs @@ -0,0 +1,12 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +#Set drastic-sa config for RG DS +if [ ! -d "/storage/.config/drastic" ]; then + mkdir -p "/storage/.config/drastic" + cp -r "/usr/config/drastic" "/storage/.config/" +fi +if [ -f "/storage/.config/drastic/config/drastic.cfg.rgds" ]; then + mv /storage/.config/drastic/config/drastic.cfg.rgds /storage/.config/drastic/config/drastic.cfg +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG DS/050-modifiers b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG DS/050-modifiers new file mode 100755 index 0000000000..390873af44 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG DS/050-modifiers @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: Apache-2.0 +# Copyright (C) 2026-present ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/050-modifiers +DEVICE_FUNC_KEYA_MODIFIER="BTN_MODE" +DEVICE_FUNC_KEYB_MODIFIER="BTN_START" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG DS/110-retroarch-joypad b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG DS/110-retroarch-joypad new file mode 100755 index 0000000000..dfcc381de1 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG DS/110-retroarch-joypad @@ -0,0 +1,11 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +# Adapt retroarch joypad config for RG DS + +if [ ! -f "/storage/joypads/retrogame_joypad.cfg" ]; then + cp /usr/share/libretro/autoconfig/retrogame_joypad.cfg /storage/joypads/ + sed -i -r 's/input_enable_hotkey_btn.*/input_enable_hotkey_btn = "10"/' /storage/joypads/retrogame_joypad.cfg +fi + diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG DS/sleep.d/post/99-drastic-cont b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG DS/sleep.d/post/99-drastic-cont new file mode 100755 index 0000000000..1402b67572 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG DS/sleep.d/post/99-drastic-cont @@ -0,0 +1,6 @@ +#!/bin/sh + +# Resume DraStic if it's still there +if pgrep drastic; then + kill -CONT $(pidof drastic) +fi \ No newline at end of file diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG DS/sleep.d/pre/99-drastic-stop b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG DS/sleep.d/pre/99-drastic-stop new file mode 100755 index 0000000000..add3d0f9db --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG DS/sleep.d/pre/99-drastic-stop @@ -0,0 +1,7 @@ +#!/bin/sh + +# DraStic specifically needs to be told to stop so it doesn't backlog dynarec +# instructions while the cpu is clocking down before sleep fully completes +if pgrep drastic; then + kill -STOP $(pidof drastic) +fi \ No newline at end of file diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG DS/touchcontrol b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG DS/touchcontrol new file mode 100755 index 0000000000..efd998e0dc --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG DS/touchcontrol @@ -0,0 +1,17 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025-present ArchR (https://github.com/archr-linux/Arch-R) + +mkdir -p /run/udev/rules.d/ +cat </run/udev/rules.d/99-touchscreen-calibration.rules +SUBSYSTEM=="input", KERNEL=="event*", ENV{ID_INPUT_TOUCHSCREEN}=="1", \ + ENV{ID_PATH}=="platform-fe5c0000.i2c", \ + ENV{LIBINPUT_CALIBRATION_MATRIX}="0.5 0 0 0 1 0" + +SUBSYSTEM=="input", KERNEL=="event*", ENV{ID_INPUT_TOUCHSCREEN}=="1", \ + ENV{ID_PATH}=="platform-fe5e0000.i2c", \ + ENV{LIBINPUT_CALIBRATION_MATRIX}="0.5 0 0.5 0 1 0" +EOF + +udevadm control --reload +udevadm trigger -s input diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG351M/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG351M/001-device_config new file mode 100755 index 0000000000..f4da1b9ee1 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG351M/001-device_config @@ -0,0 +1,14 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/001-device_config +# Device Features +DEVICE_PLAYBACK_PATH_SPK="HP" +DEVICE_PLAYBACK_PATH_HP="SPK" +DEVICE_VOLUME="100" +DEVICE_BATTERY_LED_STATUS="true" +DEVICE_PWR_LED_GPIO="77" +DEVICE_TEMP_SENSOR="/sys/devices/virtual/thermal/thermal_zone0/temp" +DEVICE_MMC_EJECT="false" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG351M/009-commander-cfg b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG351M/009-commander-cfg new file mode 100644 index 0000000000..a9c4b8bd72 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG351M/009-commander-cfg @@ -0,0 +1,11 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +if [ ! -f "/storage/.config/commander.cfg" ]; then +cat </storage/.config/commander.cfg +disp_ppu_x=1.5 +disp_ppu_y=1.5 +EOF +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG351M/050-game_configs b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG351M/050-game_configs new file mode 100755 index 0000000000..8c16e46ea8 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG351M/050-game_configs @@ -0,0 +1,48 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +#Set up gzdoom +if [ ! -d "/storage/.config/gzdoom/" ]; then + cp -rf /usr/config/gzdoom /storage/.config/ + sed -i '/Joy7=/c\Joy7=togglemap' /storage/.config/gzdoom/gzdoom.ini + sed -i '/Joy8=/c\Joy8=menu_main' /storage/.config/gzdoom/gzdoom.ini + sed -i '/Axis0scale=/c\Axis0scale=-0.8' /storage/.config/gzdoom/gzdoom.ini + sed -i '/Axis1scale=/c\Axis1scale=-0.6' /storage/.config/gzdoom/gzdoom.ini + sed -i '/vid_defheight=/c\vid_defheight=320' /storage/.config/gzdoom/gzdoom.ini + sed -i '/vid_defwidth=/c\vid_defwidth=480' /storage/.config/gzdoom/gzdoom.ini +fi + +#Map ppsspp controls +if grep RG351M -q "/stprage/.config/ppsspp/PSP/SYSTEM/controls.ini" +then + exit 1 +else +cat </storage/.config/ppsspp/PSP/SYSTEM/controls.ini +#RG351M +[ControlMapping] +Up = 10-19 +Down = 10-20 +Left = 10-21 +Right = 10-22 +Circle = 10-189 +Cross = 10-190 +Square = 10-188 +Triangle = 10-191 +Start = 10-197 +Select = 10-196 +L = 10-193 +R = 10-192 +An.Up = 10-4002 +An.Down = 10-4003 +An.Left = 10-4000 +An.Right = 10-4001 +Fast-forward = 1-61 +Pause = 10-106 +Save State = 10-4010 +Load State = 10-4008 +RightAn.Up = 10-4007 +RightAn.Down = 10-4006 +RightAn.Left = 10-4005 +RightAn.Right = 10-4004 +EOF +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG351M/050-volume b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG351M/050-volume new file mode 100755 index 0000000000..b2c9c28a68 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG351M/050-volume @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /storage/.config/profile.d/001-device_config + +### RG351P/M has a volume rocker, so the internal volume should always be 100%. +amixer -c 0 set "Master" "${DEVICE_VOLUME}%" diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG351M/075-dpad-volbright b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG351M/075-dpad-volbright new file mode 100755 index 0000000000..287366f2f7 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG351M/075-dpad-volbright @@ -0,0 +1,47 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +DPAD_EVENTS=$(get_setting key.dpad.events) +if [ -z "${DPAD_EVENTS}" ] +then + set_setting key.dpad.events 1 +fi + +KEY_FUNC_A=$(get_setting key.function.a) +if [ -z "${KEY_FUNC_A}" ] +then + set_setting key.function.a BTN_WEST +fi + +KEY_FUNC_B=$(get_setting key.function.b) +if [ -z "${KEY_FUNC_B}" ] +then + set_setting key.function.b BTN_TR +fi + +KEY_HOT_A=$(get_setting key.hotkey.a) +if [ -z "${KEY_HOT_A}" ] +then + set_setting key.hotkey.a BTN_WEST +fi + +KEY_HOT_B=$(get_setting key.hotkey.b) +if [ -z "${KEY_HOT_B}" ] +then + set_setting key.hotkey.b BTN_TR +fi + +KEY_HOT_C=$(get_setting key.hotkey.c) +if [ -z "${KEY_HOT_C}" ] +then + set_setting key.hotkey.c BTN_TL +fi + +if [ "$(systemctl is-active input)" = "active" ] +then + systemctl restart input +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG351V/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG351V/001-device_config new file mode 100755 index 0000000000..d5dde3f33f --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG351V/001-device_config @@ -0,0 +1,12 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/001-device_config +# Device Features +DEVICE_PLAYBACK_PATH_SPK="SPK" +DEVICE_PLAYBACK_PATH_HP="HP" +DEVICE_BATTERY_LED_STATUS="true" +DEVICE_PWR_LED_GPIO="77" +DEVICE_TEMP_SENSOR="/sys/devices/virtual/thermal/thermal_zone0/temp" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG351V/004-game-configs b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG351V/004-game-configs new file mode 100755 index 0000000000..aed35c84df --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG351V/004-game-configs @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +#Set up gzdoom +if [ ! -d "/storage/.config/gzdoom/" ]; then + cp -rf /usr/config/gzdoom /storage/.config/ + sed -i '/Joy7=/c\Joy7=togglemap' /storage/.config/gzdoom/gzdoom.ini + sed -i '/Joy8=/c\Joy8=menu_main' /storage/.config/gzdoom/gzdoom.ini + sed -i '/Axis0scale=/c\Axis0scale=-0.8' /storage/.config/gzdoom/gzdoom.ini + sed -i '/Axis1scale=/c\Axis1scale=-0.6' /storage/.config/gzdoom/gzdoom.ini + sed -i '/vid_defheight=/c\vid_defheight=320' /storage/.config/gzdoom/gzdoom.ini + sed -i '/vid_defwidth=/c\vid_defwidth=480' /storage/.config/gzdoom/gzdoom.ini +fi + +#Map ppsspp controls +if grep RG351V -q "/stprage/.config/ppsspp/PSP/SYSTEM/controls.ini" +then + exit 1 +else +cat </storage/.config/ppsspp/PSP/SYSTEM/controls.ini +#RG351V +[ControlMapping] +Up = 10-19 +Down = 10-20 +Left = 10-21 +Right = 10-22 +Circle = 10-189 +Cross = 10-190 +Square = 10-188 +Triangle = 10-191 +Start = 10-197 +Select = 10-196 +L = 10-193 +R = 10-192 +An.Up = 10-4002 +An.Down = 10-4003 +An.Left = 10-4000 +An.Right = 10-4001 +Fast-forward = 1-61 +Pause = 10-106 +Save State = 10-4010 +Load State = 10-4008 +EOF +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG351V/075-dpad-volbright b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG351V/075-dpad-volbright new file mode 100755 index 0000000000..287366f2f7 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG351V/075-dpad-volbright @@ -0,0 +1,47 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +DPAD_EVENTS=$(get_setting key.dpad.events) +if [ -z "${DPAD_EVENTS}" ] +then + set_setting key.dpad.events 1 +fi + +KEY_FUNC_A=$(get_setting key.function.a) +if [ -z "${KEY_FUNC_A}" ] +then + set_setting key.function.a BTN_WEST +fi + +KEY_FUNC_B=$(get_setting key.function.b) +if [ -z "${KEY_FUNC_B}" ] +then + set_setting key.function.b BTN_TR +fi + +KEY_HOT_A=$(get_setting key.hotkey.a) +if [ -z "${KEY_HOT_A}" ] +then + set_setting key.hotkey.a BTN_WEST +fi + +KEY_HOT_B=$(get_setting key.hotkey.b) +if [ -z "${KEY_HOT_B}" ] +then + set_setting key.hotkey.b BTN_TR +fi + +KEY_HOT_C=$(get_setting key.hotkey.c) +if [ -z "${KEY_HOT_C}" ] +then + set_setting key.hotkey.c BTN_TL +fi + +if [ "$(systemctl is-active input)" = "active" ] +then + systemctl restart input +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353M b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353M new file mode 120000 index 0000000000..58afc9983f --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353M @@ -0,0 +1 @@ +Anbernic RG353P \ No newline at end of file diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353P/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353P/001-device_config new file mode 100644 index 0000000000..23e3b7e4f4 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353P/001-device_config @@ -0,0 +1,9 @@ +#!/bin/sh +# SPDX-License-Identifier: Apache-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/001-device_config +DEVICE_FAKE_JACKSENSE="false" +DEVICE_BATTERY_LED_STATUS="false" +DEVICE_HAS_TOUCHSCREEN="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353P/020-gpios b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353P/020-gpios new file mode 100755 index 0000000000..357fcb1087 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353P/020-gpios @@ -0,0 +1,15 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/020-gpios +DEVICE_WIFI="0" +DEVICE_PWM_MOTOR="pwmchip1" +EOF + +. /storage/.config/profile.d/020-gpios +# Enable PWM for rumble and turn rumble off during startup. +echo 0 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/export +echo 1000000 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/period +echo 1 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/enable +echo 1000000 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/duty_cycle diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353P/040-display b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353P/040-display new file mode 100755 index 0000000000..efb4451642 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353P/040-display @@ -0,0 +1,17 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +# Configure default contrast saturation and hue values +for PROPERTY in brightness contrast saturation hue +do + MYVAL=$(get_setting display.${PROPERTY}) + if [ -z "${MYVAL}" ] + then + MYVAL=$(drm_tool list | sed -n '/Connector: 133/,$p' | awk '/'${PROPERTY}'/ {print $5}') + fi + paneladj ${PROPERTY} ${MYVAL} +done diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353P/info.d/001-panel b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353P/info.d/001-panel new file mode 100755 index 0000000000..da49dae9de --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353P/info.d/001-panel @@ -0,0 +1,18 @@ +#!/bin/sh +ID=$(dmesg | grep "panel") +case ${ID} in + *newvision*) + ID="v1" + ;; + *sitronix*) + ID="v2" + ;; + *) + ID="Unknown" + ;; +esac + +if [ -n "${ID}" ] +then + echo "PANEL VERSION: ${ID}" +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353PS/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353PS/001-device_config new file mode 100644 index 0000000000..711360f081 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353PS/001-device_config @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: Apache-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/001-device_config +DEVICE_FAKE_JACKSENSE="false" +DEVICE_BATTERY_LED_STATUS="false" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353PS/020-gpios b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353PS/020-gpios new file mode 100755 index 0000000000..357fcb1087 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353PS/020-gpios @@ -0,0 +1,15 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/020-gpios +DEVICE_WIFI="0" +DEVICE_PWM_MOTOR="pwmchip1" +EOF + +. /storage/.config/profile.d/020-gpios +# Enable PWM for rumble and turn rumble off during startup. +echo 0 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/export +echo 1000000 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/period +echo 1 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/enable +echo 1000000 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/duty_cycle diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353PS/040-display b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353PS/040-display new file mode 100755 index 0000000000..efb4451642 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353PS/040-display @@ -0,0 +1,17 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +# Configure default contrast saturation and hue values +for PROPERTY in brightness contrast saturation hue +do + MYVAL=$(get_setting display.${PROPERTY}) + if [ -z "${MYVAL}" ] + then + MYVAL=$(drm_tool list | sed -n '/Connector: 133/,$p' | awk '/'${PROPERTY}'/ {print $5}') + fi + paneladj ${PROPERTY} ${MYVAL} +done diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353PS/info.d/001-panel b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353PS/info.d/001-panel new file mode 100755 index 0000000000..da49dae9de --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353PS/info.d/001-panel @@ -0,0 +1,18 @@ +#!/bin/sh +ID=$(dmesg | grep "panel") +case ${ID} in + *newvision*) + ID="v1" + ;; + *sitronix*) + ID="v2" + ;; + *) + ID="Unknown" + ;; +esac + +if [ -n "${ID}" ] +then + echo "PANEL VERSION: ${ID}" +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353V/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353V/001-device_config new file mode 100755 index 0000000000..56822b0507 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353V/001-device_config @@ -0,0 +1,9 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/001-device_config +DEVICE_FAKE_JACKSENSE="true" +DEVICE_HEADPHONE_DEV="/dev/input/by-path/platform-rk817-sound-event" +DEVICE_HAS_TOUCHSCREEN="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353V/020-gpios b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353V/020-gpios new file mode 100755 index 0000000000..6085323127 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353V/020-gpios @@ -0,0 +1,17 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/020-gpios +DEVICE_WIFI="5" +DEVICE_LED="77" +DEVICE_PWM_MOTOR="pwmchip1" +DEVICE_JACK="86" +EOF + +. /storage/.config/profile.d/020-gpios +# Enable PWM for rumble and turn rumble off during startup. +echo 0 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/export +echo 1000000 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/period +echo 1 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/enable +echo 1000000 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/duty_cycle diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353V/040-display b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353V/040-display new file mode 100755 index 0000000000..efb4451642 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353V/040-display @@ -0,0 +1,17 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +# Configure default contrast saturation and hue values +for PROPERTY in brightness contrast saturation hue +do + MYVAL=$(get_setting display.${PROPERTY}) + if [ -z "${MYVAL}" ] + then + MYVAL=$(drm_tool list | sed -n '/Connector: 133/,$p' | awk '/'${PROPERTY}'/ {print $5}') + fi + paneladj ${PROPERTY} ${MYVAL} +done diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353V/050-audio_path b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353V/050-audio_path new file mode 100755 index 0000000000..c81d27781f --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353V/050-audio_path @@ -0,0 +1,10 @@ +#!/bin/sh +# SPDX-License-Identifier: Apache-2.0 +# Copyright (C) 2026-present ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/002-audio_path +ALSA_PRIMARY_CARD=1 +DEVICE_PLAYBACK_PATH_SPK="SPK" +DEVICE_PLAYBACK_PATH_HP="HP" +DEVICE_PLAYBACK_PATH="Playback Mux" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353V/info.d/001-panel b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353V/info.d/001-panel new file mode 100755 index 0000000000..da49dae9de --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353V/info.d/001-panel @@ -0,0 +1,18 @@ +#!/bin/sh +ID=$(dmesg | grep "panel") +case ${ID} in + *newvision*) + ID="v1" + ;; + *sitronix*) + ID="v2" + ;; + *) + ID="Unknown" + ;; +esac + +if [ -n "${ID}" ] +then + echo "PANEL VERSION: ${ID}" +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353VS/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353VS/001-device_config new file mode 100755 index 0000000000..8b0c1e05d8 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353VS/001-device_config @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/001-device_config +DEVICE_FAKE_JACKSENSE="true" +DEVICE_HEADPHONE_DEV="/dev/input/by-path/platform-rk817-sound-event" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353VS/020-gpios b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353VS/020-gpios new file mode 100755 index 0000000000..6085323127 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353VS/020-gpios @@ -0,0 +1,17 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/020-gpios +DEVICE_WIFI="5" +DEVICE_LED="77" +DEVICE_PWM_MOTOR="pwmchip1" +DEVICE_JACK="86" +EOF + +. /storage/.config/profile.d/020-gpios +# Enable PWM for rumble and turn rumble off during startup. +echo 0 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/export +echo 1000000 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/period +echo 1 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/enable +echo 1000000 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/duty_cycle diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353VS/040-display b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353VS/040-display new file mode 100755 index 0000000000..efb4451642 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353VS/040-display @@ -0,0 +1,17 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +# Configure default contrast saturation and hue values +for PROPERTY in brightness contrast saturation hue +do + MYVAL=$(get_setting display.${PROPERTY}) + if [ -z "${MYVAL}" ] + then + MYVAL=$(drm_tool list | sed -n '/Connector: 133/,$p' | awk '/'${PROPERTY}'/ {print $5}') + fi + paneladj ${PROPERTY} ${MYVAL} +done diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353VS/050-audio_path b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353VS/050-audio_path new file mode 100755 index 0000000000..c81d27781f --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353VS/050-audio_path @@ -0,0 +1,10 @@ +#!/bin/sh +# SPDX-License-Identifier: Apache-2.0 +# Copyright (C) 2026-present ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/002-audio_path +ALSA_PRIMARY_CARD=1 +DEVICE_PLAYBACK_PATH_SPK="SPK" +DEVICE_PLAYBACK_PATH_HP="HP" +DEVICE_PLAYBACK_PATH="Playback Mux" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353VS/info.d/001-panel b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353VS/info.d/001-panel new file mode 100755 index 0000000000..da49dae9de --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG353VS/info.d/001-panel @@ -0,0 +1,18 @@ +#!/bin/sh +ID=$(dmesg | grep "panel") +case ${ID} in + *newvision*) + ID="v1" + ;; + *sitronix*) + ID="v2" + ;; + *) + ID="Unknown" + ;; +esac + +if [ -n "${ID}" ] +then + echo "PANEL VERSION: ${ID}" +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG40XX H/010-analog_sticks_led_control b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG40XX H/010-analog_sticks_led_control new file mode 100755 index 0000000000..8a21241d44 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG40XX H/010-analog_sticks_led_control @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/010-analog_sticks_led_control +DEVICE_ANALOG_STICKS_LED_CONTROL="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG40XX H/bin/achievements b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG40XX H/bin/achievements new file mode 120000 index 0000000000..6dbb204a10 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG40XX H/bin/achievements @@ -0,0 +1 @@ +../../Anbernic RG CubeXX/bin/achievements \ No newline at end of file diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG40XX V/010-analog_sticks_led_control b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG40XX V/010-analog_sticks_led_control new file mode 100755 index 0000000000..8a21241d44 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG40XX V/010-analog_sticks_led_control @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/010-analog_sticks_led_control +DEVICE_ANALOG_STICKS_LED_CONTROL="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG40XX V/bin/achievements b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG40XX V/bin/achievements new file mode 120000 index 0000000000..6dbb204a10 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG40XX V/bin/achievements @@ -0,0 +1 @@ +../../Anbernic RG CubeXX/bin/achievements \ No newline at end of file diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG40XX V/bin/analog_sticks_ledcontrol b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG40XX V/bin/analog_sticks_ledcontrol new file mode 100755 index 0000000000..c25d209157 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG40XX V/bin/analog_sticks_ledcontrol @@ -0,0 +1,67 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Simple script to watch the battery capacity and +# turn the power LED orange when it reaches 30%, red at 20%, and blinking red at 10% + +# Define the serial device +SERIAL_DEVICE="/dev/ttyS2" +LED_PATH="/sys/class/leds" + +function led_state() { + echo ${2} >${LED_PATH}/${1}/brightness +} + +# Display usage if no parameters are provided +if [ $# -ne 7 ]; then + echo "Usage: $0 " + echo "Example: $0 255 255 0 0 0 0 255" + exit 1 +fi + +LED_MODE=1 +BRIGHTNESS=$1 +RIGHT_RED=$2 +RIGHT_GREEN=$3 +RIGHT_BLUE=$4 +LEFT_RED=$5 +LEFT_GREEN=$6 +LEFT_BLUE=$7 + +# Function to calculate checksum +calculate_checksum() { + local sum=0 + for byte in "$@"; do + sum=$((sum + byte)) + done + echo $((sum & 0xFF)) +} + +# Open the serial device +exec 20<>$SERIAL_DEVICE +stty -F $SERIAL_DEVICE 115200 -opost -isig -icanon -echo + +# Enable RGB LEDs +led_state rgb:kbd_backlight 1 + +# Construct the payload +PAYLOAD=$(printf '\\x%02X\\x%02X' $LED_MODE $BRIGHTNESS) +for ((i = 0; i < 16; i++)); do + PAYLOAD+=$(printf '\\x%02X\\x%02X\\x%02X' $LEFT_RED $LEFT_GREEN $LEFT_BLUE) +done + +# Calculate checksum for the payload +PAYLOAD_BYTES=($LED_MODE $BRIGHTNESS) +for ((i = 0; i < 16; i++)); do + PAYLOAD_BYTES+=($LEFT_RED $LEFT_GREEN $LEFT_BLUE) +done +CHECKSUM=$(calculate_checksum "${PAYLOAD_BYTES[@]}") +PAYLOAD+=$(printf '\\x%02X' $CHECKSUM) + +# Send the payload +echo -e -n "$PAYLOAD" > $SERIAL_DEVICE + +# Close the serial device +exec 20>&- diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG503/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG503/001-device_config new file mode 100755 index 0000000000..127677e36d --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG503/001-device_config @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/001-device_config +DEVICE_FAKE_JACKSENSE="false" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG503/020-gpios b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG503/020-gpios new file mode 100755 index 0000000000..357fcb1087 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG503/020-gpios @@ -0,0 +1,15 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/020-gpios +DEVICE_WIFI="0" +DEVICE_PWM_MOTOR="pwmchip1" +EOF + +. /storage/.config/profile.d/020-gpios +# Enable PWM for rumble and turn rumble off during startup. +echo 0 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/export +echo 1000000 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/period +echo 1 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/enable +echo 1000000 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/duty_cycle diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG503/040-display b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG503/040-display new file mode 100755 index 0000000000..efb4451642 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG503/040-display @@ -0,0 +1,17 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +# Configure default contrast saturation and hue values +for PROPERTY in brightness contrast saturation hue +do + MYVAL=$(get_setting display.${PROPERTY}) + if [ -z "${MYVAL}" ] + then + MYVAL=$(drm_tool list | sed -n '/Connector: 133/,$p' | awk '/'${PROPERTY}'/ {print $5}') + fi + paneladj ${PROPERTY} ${MYVAL} +done diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/001-device_config new file mode 100755 index 0000000000..d2500c0f50 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/001-device_config @@ -0,0 +1,18 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/001-device_config +# Device Features +DEVICE_FAKE_JACKSENSE="true" +DEVICE_AUDIO_MIXER="DAC" +DEVICE_PLAYBACK_PATH_SPK="1*" +DEVICE_PLAYBACK_PATH_HP="0*" +DEVICE_HEADPHONE_DEV="/dev/input/by-path/platform-es8316-sound-event" +DEVICE_HAS_HDMI="true" +DEVICE_BATTERY_LED_STATUS="true" +DEVICE_PWR_LED_CONTROL="true" +DEVICE_HAS_TOUCHSCREEN="true" + +DEVICE_TEMP_SENSOR=("/sys/devices/virtual/thermal/thermal_zone0/temp" "/sys/devices/virtual/thermal/thermal_zone1/temp") +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/009-commander-cfg b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/009-commander-cfg new file mode 100644 index 0000000000..e6dcf766af --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/009-commander-cfg @@ -0,0 +1,11 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +if [ ! -f "/storage/.config/commander.cfg" ]; then +cat </storage/.config/commander.cfg +disp_ppu_x=5 +disp_ppu_y=5 +EOF +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/010-governors b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/010-governors new file mode 100755 index 0000000000..607c6c1c87 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/010-governors @@ -0,0 +1,14 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/010-governors +CPU_FREQ=("/sys/devices/system/cpu/cpufreq/policy0" "/sys/devices/system/cpu/cpufreq/policy4") +GPU_FREQ="/sys/devices/platform/ff9a0000.gpu/devfreq/ff9a0000.gpu" +DMC_FREQ="/sys/devices/platform/memory-controller/devfreq/memory-controller" +EOF + +### Lock in lowest freq we want to use +echo 1008000 > /sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq +echo 1008000 > /sys/devices/system/cpu/cpufreq/policy4/scaling_min_freq +echo 600000000 > /sys/devices/platform/ff9a0000.gpu/devfreq/ff9a0000.gpu/min_freq diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/020-fan_control b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/020-fan_control new file mode 100755 index 0000000000..810e1d7147 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/020-fan_control @@ -0,0 +1,9 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/020-fan_control +DEVICE_HAS_FAN="true" +DEVICE_PWM_FAN="/sys/class/hwmon/hwmon1/pwm1" +DEVICE_FAN_INPUT="/sys/class/hwmon/hwmon1/pwm1" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/020-gpios b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/020-gpios new file mode 100755 index 0000000000..6250e3e37d --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/020-gpios @@ -0,0 +1,16 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/020-gpios +DEVICE_JACK="8" +DEVICE_HDMI_GPIO="54" +DEVICE_WIFI="113" +EOF + +. /storage/.config/profile.d/020-gpios +# Enable PWM for rumble and turn rumble off during startup. +echo 0 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/export +echo 1000000 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/period +echo 1 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/enable +echo 1000000 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/duty_cycle diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/030-enable_wifi b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/030-enable_wifi new file mode 100755 index 0000000000..5552ff87c5 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/030-enable_wifi @@ -0,0 +1,20 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile.d/001-functions + +# Get Internal Wifi State +INTERNAL_WIFI_STATE=$(get_setting "internal.wifi") +if [ ! -n "${INTERNAL_WIFI_STATE}" ]; then + INTERNAL_WIFI_STATE=1 + set_setting "internal.wifi" "1" +fi + +# Set export GPIO for Wifi and set state +if [ ! -d "/sys/class/gpio/gpio${DEVICE_WIFI}" ]; then + echo ${DEVICE_WIFI} > /sys/class/gpio/export + echo out > /sys/class/gpio/gpio${DEVICE_WIFI}/direction + echo ${INTERNAL_WIFI_STATE} > /sys/class/gpio/gpio${DEVICE_WIFI}/value +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/050-audio_path b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/050-audio_path new file mode 100755 index 0000000000..14042766d4 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/050-audio_path @@ -0,0 +1,9 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/002-audio_path +DEVICE_AUDIO_MIXER="DAC" +DEVICE_PLAYBACK_PATH_SPK="1*" +DEVICE_PLAYBACK_PATH_HP="0*" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/050-game-configs b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/050-game-configs new file mode 100755 index 0000000000..1bb6f687b3 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/050-game-configs @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present JELOS (https://github.com/JustEnoughLinuxOS) + +#Remap joypad name to rg552_joypad +sed -i '/^mapping_name = retrogame_joypad/c\mapping_name = rg552_joypad' /storage/.config/flycast/mappings/SDL_retrogame_joypad.cfg +sed -i '/retrogame_joypad/c\[rg552_joypad]' /storage/.config/mupen64plus/custominput.ini +sed -i '/name = "retrogame_joypad"/c\name = "rg552_joypad"' /storage/.config/mupen64plus/mupen64plus.cfg + +#Fix ES input +for config in "/storage/.config/emulationstation/es_input.cfg"; do + if ! grep -q rg552_joypad "$config"; then + cp -r /usr/config/emulationstation/es_input.cfg /storage/.config/emulationstation/es_input.cfg + fi +done; diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/bin/fancontrol b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/bin/fancontrol new file mode 100755 index 0000000000..9a4749c3e0 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/bin/fancontrol @@ -0,0 +1,83 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +DEBUG=false +COOLING_PROFILE=$(get_setting "cooling.profile") +FAN_PWM="${DEVICE_PWM_FAN}" + +log $0 "Setting profile to ${COOLING_PROFILE}" + +function set_control() { + log $0 "Set fan control to ${1}" + if [ -e "${DEVICE_PWM_FAN}_enable" ] + then + echo ${1} >${DEVICE_PWM_FAN}_enable + fi +} + +trap "set_control 0 && exit 0" SIGHUP SIGINT SIGQUIT SIGABRT + +if [ -e "/storage/.config/fancontrol.conf" ] && [ "${COOLING_PROFILE}" = "custom" ] +then + log $0 "Loading configuration file" 2>/dev/null + source /storage/.config/fancontrol.conf + if [ ! $? = 0 ] + then + WARN="Custom fan profile could not be loaded, defaulting to auto." + log $0 "${WARN}" + COOLING_PROFILE="auto" + set_setting cooling.profile auto + fi +fi + + +if [ ! "${COOLING_PROFILE}" = "custom" ] +then + if [ "${COOLING_PROFILE}" = "aggressive" ] + then + SPEEDS=(255 225 195) + TEMPS=(55000 45000 0) + elif [ "${COOLING_PROFILE}" = "moderate" ] + then + SPEEDS=(255 192 128 96) + TEMPS=(65000 55000 45000 0) + elif [ "${COOLING_PROFILE}" = "quiet" ] + then + # Quiet. + SPEEDS=(255 192 128 96 64 48 32) + TEMPS=(70000 60000 55000 50000 49000 47000 0) + else + # auto + set_control 0 >/dev/null 2>&1 + exit 0 + fi +fi + +log $0 "Enabling fan control." +set_control 1 >/dev/null 2>&1 + +while true +do + INDEX=0 + CPU_TEMP=$(awk '{total += $1; count++} END {printf "%d", total/count}' ${DEVICE_TEMP_SENSOR}) + $DEBUG && log $0 "CPU TEMP: ${CPU_TEMP}" 2>/dev/null + for TEMP in "${TEMPS[@]}" + do + if (( "${CPU_TEMP}" > "${TEMP}" )) && \ + [ ! "${LASTSPEED}" = "${SPEEDS[${INDEX}]}" ] + then + $DEBUG && log $0 "Setting PWM FAN to ${SPEEDS[${INDEX}]} (${TEMP})" 2>/dev/null + echo ${SPEEDS[${INDEX}]} >${FAN_PWM} + LASTSPEED=${SPEEDS[${INDEX}]} + break + fi + INDEX=$(( $INDEX + 1 )) + done + sleep 2 +done + +log $0 "Disabling fan control." +set_control 0 >/dev/null 2>&1 diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/sleep.d/post/001-audio b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/sleep.d/post/001-audio new file mode 100755 index 0000000000..cf473483dd --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/sleep.d/post/001-audio @@ -0,0 +1,30 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Workaround for no audio on wake from sleep. + +. /etc/profile + +HDMI=$(pactl list sinks short | grep hdmi | cut -c 0-2) +SPEAKER=$(pactl list sinks short | grep es8316 | cut -c 0-2) + +#Set sink to one we aren't currently using +pactl set-default-sink ${SPEAKER} + +#Then check if HDMI is plugged and switch to HDMI + +# Set export GPIO for HDMI +if [ ! -d "/sys/class/gpio/gpio${DEVICE_HDMI_GPIO}" ]; then + echo ${DEVICE_HDMI_GPIO} > /sys/class/gpio/export + echo in > /sys/class/gpio/gpio${DEVICE_HDMI_GPIO}/direction +fi + +# Check HDMI plug state and switch to HDMI audo if true +HDMI_VALUE=$(cat /sys/class/gpio/gpio${DEVICE_HDMI_GPIO}/value) + case ${HDMI_VALUE} in + "0") + sleep 11 + pactl set-default-sink ${HDMI} + ;; + esac diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/sleep.d/post/002-freq b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/sleep.d/post/002-freq new file mode 100755 index 0000000000..7ba581fc1b --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/sleep.d/post/002-freq @@ -0,0 +1,32 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +### Restore previous governors before going to sleep + +. /etc/profile + +### Set max/min freq to lowest available value +echo 1008000 > /sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq +echo 1008000 > /sys/devices/system/cpu/cpufreq/policy4/scaling_min_freq +echo 600000000 > /sys/devices/platform/ff9a0000.gpu/devfreq/ff9a0000.gpu/min_freq + +echo 1608000 > /sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq +echo 2088000 > /sys/devices/system/cpu/cpufreq/policy4/scaling_max_freq +echo 900000000 > /sys/devices/platform/ff9a0000.gpu/devfreq/ff9a0000.gpu/max_freq + +### Grab the old governors. +OLD_CPU_FREQ=$(get_setting "sleep.cpugovernor") +if [ ! -n "${OLD_CPU_FREQ}" ]; then + OLD_CPU_FREQ="schedutil" +fi + +OLD_GPU_FREQ=$(get_setting "sleep.gpugovernor") +if [ ! -n "${OLD_GPU_FREQ}" ]; then + OLD_GPU_FREQ="simple_ondemand" +fi + +# Restore old governors. +set_cpu_gov "${OLD_CPU_FREQ}" +set_dmc_gov "${OLD_CPU_FREQ}" +set_gpu_gov "${OLD_GPU_FREQ}" diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/sleep.d/pre/001-audio b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/sleep.d/pre/001-audio new file mode 100755 index 0000000000..2dc5fd014a --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/sleep.d/pre/001-audio @@ -0,0 +1,16 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Workaround for no audio on wake from sleep. + +. /etc/profile + +HDMI=$(pactl list sinks short | grep hdmi | cut -c 0-2) +SPEAKER=$(pactl list sinks short | grep es8316 | cut -c 0-2) + +#Set sink to one we aren't currently using +pactl set-default-sink ${HDMI} + +#Suspend the sink we are using +pactl suspend-sink ${SPEAKER} 1 diff --git a/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/sleep.d/pre/002-freq b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/sleep.d/pre/002-freq new file mode 100755 index 0000000000..64d15b20ed --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Anbernic RG552/sleep.d/pre/002-freq @@ -0,0 +1,28 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Store current freq governors and set governors to powersave. + +. /etc/profile + +### Get the current cpu and gpu governor, save for when the device wakes from sleep. +CUR_CPU_FREQ="$(cat ${CPU_FREQ}/scaling_governor)" +CUR_GPU_FREQ="$(cat ${GPU_FREQ}/governor)" + +set_setting sleep.cpugovernor "${CUR_CPU_FREQ}" +set_setting sleep.gpugovernor "${CUR_GPU_FREQ}" + +### Set all governors to powersave +set_cpu_gov powersave +set_dmc_gov powersave +set_gpu_gov powersave + +### Set max/min freq to lowest available value +echo 600000 > /sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq +echo 600000 > /sys/devices/system/cpu/cpufreq/policy4/scaling_min_freq +echo 200000000 > /sys/devices/platform/ff9a0000.gpu/devfreq/ff9a0000.gpu/min_freq + +echo 600000 > /sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq +echo 600000 > /sys/devices/system/cpu/cpufreq/policy4/scaling_max_freq +echo 200000000 > /sys/devices/platform/ff9a0000.gpu/devfreq/ff9a0000.gpu/max_freq diff --git a/projects/ArchR/packages/hardware/quirks/devices/Game Console R33S/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/Game Console R33S/001-device_config new file mode 100755 index 0000000000..243906cf13 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Game Console R33S/001-device_config @@ -0,0 +1,11 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/001-device_config +# Device Features +DEVICE_PLAYBACK_PATH_SPK="HP" +DEVICE_PLAYBACK_PATH_HP="SPK" +DEVICE_PWR_LED_GPIO="77" +DEVICE_TEMP_SENSOR="/sys/devices/virtual/thermal/thermal_zone0/temp" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Game Console R33S/002-disable-led b/projects/ArchR/packages/hardware/quirks/devices/Game Console R33S/002-disable-led new file mode 100755 index 0000000000..7e5ed7a899 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Game Console R33S/002-disable-led @@ -0,0 +1,13 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Set export GPIO for Power LED +if [ ! -d "/sys/class/gpio/gpio${DEVICE_PWR_LED_GPIO}" ]; then + echo ${DEVICE_PWR_LED_GPIO} > /sys/class/gpio/export +fi + +#Disable blue led on R33S +echo out >/sys/class/gpio/gpio${DEVICE_PWR_LED_GPIO}/direction +echo 1 >/sys/class/gpio/gpio${DEVICE_PWR_LED_GPIO}/value diff --git a/projects/ArchR/packages/hardware/quirks/devices/Game Console R33S/050-game-configs b/projects/ArchR/packages/hardware/quirks/devices/Game Console R33S/050-game-configs new file mode 100755 index 0000000000..9ab95ceaf2 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Game Console R33S/050-game-configs @@ -0,0 +1,260 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +#Set mupen64-plus-sa config for R33S +if [ ! -d "/storage/.config/mupen64plus" ]; then + mkdir -p "/storage/.config/mupen64plus/" + cp -r /usr/local/share/mupen64plus/mupen64plus.cfg* /storage/.config/mupen64plus/ +fi +if [ -f "/storage/.config/mupen64plus/mupen64plus.cfg.r33s" ]; then + rm /storage/.config/mupen64plus/mupen64plus.cfg + mv /storage/.config/mupen64plus/mupen64plus.cfg.r33s /storage/.config/mupen64plus/mupen64plus.cfg +fi + +#Set drastic-sa config for OGA +if [ ! -d "/storage/.config/drastic" ]; then + mkdir -p "/storage/.config/drastic" + cp -r "/usr/config/drastic" "/storage/.config/" +fi +if [ -f "/storage/.config/drastic/config/drastic.cfg.r33s" ]; then + mv /storage/.config/drastic/config/drastic.cfg.r33s /storage/.config/drastic/config/drastic.cfg +fi + + +#Set gzoom config for R33S +if [ ! -d "/storage/.config/gzdoom" ]; then + cp -r "/usr/config/gzdoom" "/storage/.config/" +fi + +#Set gzdoom settings +if grep R33S -q "/storage/.config/gzdoom/gzdoom.ini" +then + exit 1 +else +sed -i '/^[Doom.Bindings]/c\[Doom.Bindings] #R33S' /storage/.config/gzdoom/gzdoom.ini +sed -i '/^vid_defheight=/c\vid_defheight=480' /storage/.config/gzdoom/gzdoom.ini +sed -i '/^vid_defwidth=/c\vid_defwidth=640' /storage/.config/gzdoom/gzdoom.ini +sed -i '/^Joy1=/c\Joy1=+use' /storage/.config/gzdoom/gzdoom.ini +sed -i '/^Joy5=/c\Joy5=+speed' /storage/.config/gzdoom/gzdoom.ini +sed -i '/^Joy6=/c\Joy6=+attack' /storage/.config/gzdoom/gzdoom.ini +sed -i '/^Joy7=/c\Joy7=+moveleft' /storage/.config/gzdoom/gzdoom.ini +sed -i '/^Joy8=/c\Joy8=+moveright' /storage/.config/gzdoom/gzdoom.ini +sed -i '/^Joy9=/c\Joy9=menu_main' /storage/.config/gzdoom/gzdoom.ini +sed -i '/^Joy11=/c\Joy11=+forward' /storage/.config/gzdoom/gzdoom.ini +sed -i '/^Joy12=/c\Joy12=+back' /storage/.config/gzdoom/gzdoom.ini +sed -i '/^Joy13=/c\Joy13=+left' /storage/.config/gzdoom/gzdoom.ini +sed -i '/^Joy14=/c\Joy14=+right' /storage/.config/gzdoom/gzdoom.ini +sed -i '/^Joy2=/c\Joy2=+attack' /storage/.config/gzdoom/gzdoom.ini +fi + +#Set ppsspp config for R33S +if [ ! -d "/storage/.config/ppsspp" ]; then + mkdir -p "/storage/.config/ppsspp" + cp -r "/usr/config/ppsspp" "/storage/.config/" +fi + +#Map ppsspp controls +if grep R33S -q "/storage/.config/ppsspp/PSP/SYSTEM/controls.ini" +then + exit 1 +else +cat </storage/.config/ppsspp/PSP/SYSTEM/controls.ini +#R33S +[ControlMapping] +Up = 10-19 +Down = 10-20 +Left = 10-21 +Right = 10-22 +Circle = 10-189 +Cross = 10-190 +Square = 10-188 +Triangle = 10-191 +Start = 10-197 +Select = 10-196 +L = 10-193 +R = 10-192 +Fast-forward = 1-61 +Pause = 10-106 +Save State = 10-4010 +Load State = 10-4008 +EOF +fi + +#Set flycast ra config for R33S +if [ ! -d "/storage/remappings/Flycast" ]; then + mkdir -p "/storage/remappings/Flycast" +fi + +#Map flycast ra controls for R33S +if grep R33S -q "/storage/remappings/Flycast/Flycast.rmp" +then + exit 1 +else +cat </storage/remappings/Flycast/Flycast.rmp +#R33S +input_libretro_device_p1 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_player1_analog_dpad_mode = "0" +input_player1_btn_down = "18" +input_player1_btn_left = "17" +input_player1_btn_right = "16" +input_player1_btn_up = "19" +input_player1_stk_l_x+ = "-1" +input_player1_stk_l_x- = "-1" +input_player1_stk_l_y+ = "-1" +input_player1_stk_l_y- = "-1" +input_player2_analog_dpad_mode = "0" +input_player3_analog_dpad_mode = "0" +input_player4_analog_dpad_mode = "0" +input_player5_analog_dpad_mode = "0" +input_remap_port_p1 = "0" +input_remap_port_p2 = "1" +input_remap_port_p3 = "2" +input_remap_port_p4 = "3" +input_remap_port_p5 = "4" +EOF +fi + +#Set Mupen64Plus GLES2 ra config for R33S +if [ ! -d "/storage/remappings/Mupen64Plus GLES2" ]; then + mkdir -p "/storage/remappings/Mupen64Plus GLES2" +fi + +#Map Mupen64Plus GLES2 ra controls for R33S +if grep R33S -q "/storage/remappings/Mupen64Plus GLES2/Mupen64Plus GLES2.rmp" +then + exit 1 +else +cat <"/storage/remappings/Mupen64Plus GLES2/Mupen64Plus GLES2.rmp" +#R33S +input_libretro_device_p1 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_player1_analog_dpad_mode = "0" +input_player1_btn_a = "22" +input_player1_btn_down = "18" +input_player1_btn_l = "12" +input_player1_btn_l2 = "21" +input_player1_btn_left = "17" +input_player1_btn_r2 = "20" +input_player1_btn_right = "16" +input_player1_btn_up = "19" +input_player1_btn_x = "23" +input_player1_stk_l_x+ = "-1" +input_player1_stk_l_x- = "-1" +input_player1_stk_l_y+ = "-1" +input_player1_stk_l_y- = "-1" +input_player1_stk_r_x+ = "-1" +input_player1_stk_r_x- = "-1" +input_player1_stk_r_y+ = "-1" +input_player1_stk_r_y- = "-1" +input_player2_analog_dpad_mode = "0" +input_player3_analog_dpad_mode = "0" +input_player4_analog_dpad_mode = "0" +input_player5_analog_dpad_mode = "0" +input_remap_port_p1 = "0" +input_remap_port_p2 = "1" +input_remap_port_p3 = "2" +input_remap_port_p4 = "3" +input_remap_port_p5 = "4" +EOF +fi + +#Set Mupen64Plus-Next ra config for R33S +if [ ! -d "/storage/remappings/Mupen64Plus-Next" ]; then + mkdir -p "/storage/remappings/Mupen64Plus-Next" +fi + +#Map Mupen64Plus-Next ra controls for R33S +if grep R33S -q "/storage/remappings/Mupen64Plus-Next/Mupen64Plus-Next.rmp" +then + exit 1 +else +cat </storage/remappings/Mupen64Plus-Next/Mupen64Plus-Next.rmp +#R33S +input_libretro_device_p1 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_player1_analog_dpad_mode = "0" +input_player1_btn_a = "22" +input_player1_btn_down = "18" +input_player1_btn_l = "12" +input_player1_btn_l2 = "21" +input_player1_btn_left = "17" +input_player1_btn_r2 = "20" +input_player1_btn_right = "16" +input_player1_btn_up = "19" +input_player1_btn_x = "23" +input_player1_stk_l_x+ = "-1" +input_player1_stk_l_x- = "-1" +input_player1_stk_l_y+ = "-1" +input_player1_stk_l_y- = "-1" +input_player1_stk_r_x+ = "-1" +input_player1_stk_r_x- = "-1" +input_player1_stk_r_y+ = "-1" +input_player1_stk_r_y- = "-1" +input_player2_analog_dpad_mode = "0" +input_player3_analog_dpad_mode = "0" +input_player4_analog_dpad_mode = "0" +input_player5_analog_dpad_mode = "0" +input_remap_port_p1 = "0" +input_remap_port_p2 = "1" +input_remap_port_p3 = "2" +input_remap_port_p4 = "3" +input_remap_port_p5 = "4" +EOF +fi + +#Set ParaLLEl N64 ra config for R33S +if [ ! -d "/storage/remappings/ParaLLEl N64" ]; then + mkdir -p "/storage/remappings/ParaLLEl N64" +fi + +#Map ParaLLEl N64 ra controls for R33S +if grep R33S -q "/storage/remappings/ParaLLEl N64/ParaLLEl N64.rmp" +then + exit 1 +else +cat <"/storage/remappings/ParaLLEl N64/ParaLLEl N64.rmp" +#R33S +input_libretro_device_p1 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_player1_analog_dpad_mode = "0" +input_player1_btn_a = "22" +input_player1_btn_down = "18" +input_player1_btn_l = "12" +input_player1_btn_l2 = "21" +input_player1_btn_left = "17" +input_player1_btn_r2 = "20" +input_player1_btn_right = "16" +input_player1_btn_up = "19" +input_player1_btn_x = "23" +input_player1_stk_l_x+ = "-1" +input_player1_stk_l_x- = "-1" +input_player1_stk_l_y+ = "-1" +input_player1_stk_l_y- = "-1" +input_player1_stk_r_x+ = "-1" +input_player1_stk_r_x- = "-1" +input_player1_stk_r_y+ = "-1" +input_player1_stk_r_y- = "-1" +input_player2_analog_dpad_mode = "0" +input_player3_analog_dpad_mode = "0" +input_player4_analog_dpad_mode = "0" +input_player5_analog_dpad_mode = "0" +input_remap_port_p1 = "0" +input_remap_port_p2 = "1" +input_remap_port_p3 = "2" +input_remap_port_p4 = "3" +input_remap_port_p5 = "4 +EOF +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/Game Console R33S/075-dpad-volbright b/projects/ArchR/packages/hardware/quirks/devices/Game Console R33S/075-dpad-volbright new file mode 100755 index 0000000000..649e8f810d --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Game Console R33S/075-dpad-volbright @@ -0,0 +1,17 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +DPAD_EVENTS=$(get_setting key.dpad.events) +if [ -z "${DPAD_EVENTS}" ] +then + set_setting key.dpad.events 1 +fi + +if [ "$(systemctl is-active input)" = "active" ] +then + systemctl restart input +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/Game Console R36S/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/Game Console R36S/001-device_config new file mode 100755 index 0000000000..243906cf13 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Game Console R36S/001-device_config @@ -0,0 +1,11 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/001-device_config +# Device Features +DEVICE_PLAYBACK_PATH_SPK="HP" +DEVICE_PLAYBACK_PATH_HP="SPK" +DEVICE_PWR_LED_GPIO="77" +DEVICE_TEMP_SENSOR="/sys/devices/virtual/thermal/thermal_zone0/temp" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Game Console R36S/002-disable-led b/projects/ArchR/packages/hardware/quirks/devices/Game Console R36S/002-disable-led new file mode 100755 index 0000000000..7e5ed7a899 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Game Console R36S/002-disable-led @@ -0,0 +1,13 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Set export GPIO for Power LED +if [ ! -d "/sys/class/gpio/gpio${DEVICE_PWR_LED_GPIO}" ]; then + echo ${DEVICE_PWR_LED_GPIO} > /sys/class/gpio/export +fi + +#Disable blue led on R33S +echo out >/sys/class/gpio/gpio${DEVICE_PWR_LED_GPIO}/direction +echo 1 >/sys/class/gpio/gpio${DEVICE_PWR_LED_GPIO}/value diff --git a/projects/ArchR/packages/hardware/quirks/devices/Game Console R36S/050-game-configs b/projects/ArchR/packages/hardware/quirks/devices/Game Console R36S/050-game-configs new file mode 100755 index 0000000000..f0b56405fa --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Game Console R36S/050-game-configs @@ -0,0 +1,57 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +#Set mupen64-plus-sa config for R36S, can use same profile as OGS +if [ ! -d "/storage/.config/mupen64plus" ]; then + mkdir -p "/storage/.config/mupen64plus/" + cp -r /usr/local/share/mupen64plus/mupen64plus.cfg* /storage/.config/mupen64plus/ +fi +if [ -f "/storage/.config/mupen64plus/mupen64plus.cfg.ogs" ]; then + rm /storage/.config/mupen64plus/mupen64plus.cfg + mv /storage/.config/mupen64plus/mupen64plus.cfg.ogs /storage/.config/mupen64plus/mupen64plus.cfg +fi + +#Set drastic-sa config for R36S (think it can use the same as RG20S) +if [ ! -d "/storage/.config/drastic" ]; then + mkdir -p "/storage/.config/drastic" + cp -r "/usr/config/drastic" "/storage/.config/" +fi +if [ -f "/storage/.config/drastic/config/drastic.cfg.r36s" ]; then + rm /storage/.config/drastic/config/drastic.cfg + mv /storage/.config/drastic/config/drastic.cfg.r36s /storage/.config/drastic/config/drastic.cfg +fi + +#Map ppsspp controls +if grep R36S -q "/storage/.config/ppsspp/PSP/SYSTEM/controls.ini" +then + exit 1 +else +cat </storage/.config/ppsspp/PSP/SYSTEM/controls.ini +#R36S +[ControlMapping] +Up = 10-19 +Down = 10-20 +Left = 10-21 +Right = 10-22 +Circle = 10-189 +Cross = 10-190 +Square = 10-188 +Triangle = 10-191 +Start = 10-197 +Select = 10-196 +L = 10-193 +R = 10-192 +An.Up = 10-4003 +An.Down = 10-4002 +An.Left = 10-4001 +An.Right = 10-4000 +Pause = 10-106 +Save State = 10-4010 +Load State = 10-4008 +RightAn.Up = 10-4007 +RightAn.Down = 10-4006 +RightAn.Left = 10-4005 +RightAn.Right = 10-4004 +EOF +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/GameForce ACE/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/GameForce ACE/001-device_config new file mode 100755 index 0000000000..290cdafa1a --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/GameForce ACE/001-device_config @@ -0,0 +1,17 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/001-device_config +# Device Features +#DEVICE_FAKE_JACKSENSE="true" +#DEVICE_AUDIO_MIXER="DAC" +#DEVICE_PLAYBACK_PATH_SPK="1*" +#DEVICE_PLAYBACK_PATH_HP="0*" +#DEVICE_HEADPHONE_DEV="/dev/input/by-path/platform-es8316-sound-event" +DEVICE_HAS_TOUCHSCREEN="true" +#DEVICE_BATTERY_LED_STATUS="true" +#DEVICE_PWR_LED_CONTROL="true" + +DEVICE_TEMP_SENSOR=("/sys/devices/virtual/thermal/thermal_zone0/temp" "/sys/devices/virtual/thermal/thermal_zone1/temp") +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/GameForce ACE/020-fan_control b/projects/ArchR/packages/hardware/quirks/devices/GameForce ACE/020-fan_control new file mode 100755 index 0000000000..2200d6e339 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/GameForce ACE/020-fan_control @@ -0,0 +1,9 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/020-fan_control +DEVICE_HAS_FAN="true" +DEVICE_PWM_FAN="/sys/class/hwmon/hwmon8/pwm1" +DEVICE_FAN_INPUT="/sys/class/hwmon/hwmon8/pwm1" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/GameForce ACE/030-suspend_mode b/projects/ArchR/packages/hardware/quirks/devices/GameForce ACE/030-suspend_mode new file mode 100755 index 0000000000..e2de620533 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/GameForce ACE/030-suspend_mode @@ -0,0 +1,11 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile.d/001-functions + +MYSLEEPMODE=$(get_setting system.suspendmode) +if [ -z "${MYSLEEPMODE}" ] +then + /usr/bin/suspendmode mem +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/GameForce ACE/050-modifiers b/projects/ArchR/packages/hardware/quirks/devices/GameForce ACE/050-modifiers new file mode 100644 index 0000000000..451df8c49a --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/GameForce ACE/050-modifiers @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/050-modifiers +DEVICE_FUNC_KEYA_MODIFIER="BTN_MODE" +DEVICE_FUNC_KEYB_MODIFIER="BTN_START" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/GameForce ACE/bin/fancontrol b/projects/ArchR/packages/hardware/quirks/devices/GameForce ACE/bin/fancontrol new file mode 100755 index 0000000000..3b34cb3efc --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/GameForce ACE/bin/fancontrol @@ -0,0 +1,111 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +### Enable logging +case $(get_setting system.loglevel) in + verbose) + DEBUG=true + ;; + *) + DEBUG=false + ;; +esac + +COOLING_PROFILE=$(get_setting "cooling.profile") +FAN_PWM="${DEVICE_PWM_FAN}" + +log $0 "Setting profile to ${COOLING_PROFILE}" + +function set_control() { + log $0 "Set fan control to ${1}" + if [ -e "${DEVICE_PWM_FAN}_enable" ] + then + echo ${1} >${DEVICE_PWM_FAN}_enable + fi +} + +trap "set_control 0 && exit 0" SIGHUP SIGINT SIGQUIT SIGABRT + +if [ -e "/storage/.config/fancontrol.conf" ] && [ "${COOLING_PROFILE}" = "custom" ] +then + log $0 "Loading configuration file" 2>/dev/null + source /storage/.config/fancontrol.conf + if [ ! $? = 0 ] + then + WARN="Custom fan profile could not be loaded, defaulting to auto." + log $0 "${WARN}" + COOLING_PROFILE="auto" + set_setting cooling.profile auto + fi +fi + + +if [ ! "${COOLING_PROFILE}" = "custom" ] +then + if [ "${COOLING_PROFILE}" = "aggressive" ] + then + SPEEDS=(195 225 255) + TEMPS=(45000 60000 80000) + elif [ "${COOLING_PROFILE}" = "moderate" ] + then + SPEEDS=(48 64 96 128 192 255) + TEMPS=(45000 55000 65000 75000 85000 90000) + elif [ "${COOLING_PROFILE}" = "quiet" ] + then + # Quiet. + SPEEDS=(24 32 48 64 96 128 192 255) + TEMPS=(35000 45000 50000 55000 65000 75000 85000 90000) + else + # auto + set_control 0 >/dev/null 2>&1 + exit 0 + fi +fi + +log $0 "Enabling fan control." +set_control 1 >/dev/null 2>&1 + +CURRENTSPEED=0 +TEMP=${TEMPS[0]} +declare -a HISTORY +while true +do + INDEX=0 + CPU_TEMP=$(awk '{total += $1; count++} END {printf "%d", total/count}' ${DEVICE_TEMP_SENSOR}) + + ### Keep a rolling history of CPU temps. + HISTORY+=(${CPU_TEMP}) + while (( ${#HISTORY[@]} > 10 )) + do + unset HISTORY[-0] + PRIOR_HISTORY=( ${HISTORY[*]} ) + HISTORY=( ${PRIOR_HISTORY[*]} ) + unset PRIOR_HISTORY + done + AVERAGE=$(echo $(IFS=+; echo "$((${HISTORY[*]}))") / ${#HISTORY[@]} | bc) + + $DEBUG && log $0 "Current/Average/Ceiling (Speed): ${CPU_TEMP}/${AVERAGE}/${TEMP} (${CURRENTSPEED})." + for TEMP in "${TEMPS[@]}" + do + if (( "${CPU_TEMP}" >= "90000" )) || \ + (( "${AVERAGE}" <= "${TEMP}" )) + then + if (( ${CURRENTSPEED} != ${SPEEDS[${INDEX}]} )) + then + CURRENTSPEED=${SPEEDS[${INDEX}]} + echo ${SPEEDS[${INDEX}]} >${FAN_PWM} + $DEBUG && log $0 "Set fan to ${CURRENTSPEED}." + fi + break + else + INDEX=$(( $INDEX + 1 )) + fi + done + sleep 2 +done + +log $0 "Disabling fan control." +set_control 0 >/dev/null 2>&1 diff --git a/projects/ArchR/packages/hardware/quirks/devices/GameForce ACE/sleep.d/post/001-audio b/projects/ArchR/packages/hardware/quirks/devices/GameForce ACE/sleep.d/post/001-audio new file mode 100755 index 0000000000..cf473483dd --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/GameForce ACE/sleep.d/post/001-audio @@ -0,0 +1,30 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Workaround for no audio on wake from sleep. + +. /etc/profile + +HDMI=$(pactl list sinks short | grep hdmi | cut -c 0-2) +SPEAKER=$(pactl list sinks short | grep es8316 | cut -c 0-2) + +#Set sink to one we aren't currently using +pactl set-default-sink ${SPEAKER} + +#Then check if HDMI is plugged and switch to HDMI + +# Set export GPIO for HDMI +if [ ! -d "/sys/class/gpio/gpio${DEVICE_HDMI_GPIO}" ]; then + echo ${DEVICE_HDMI_GPIO} > /sys/class/gpio/export + echo in > /sys/class/gpio/gpio${DEVICE_HDMI_GPIO}/direction +fi + +# Check HDMI plug state and switch to HDMI audo if true +HDMI_VALUE=$(cat /sys/class/gpio/gpio${DEVICE_HDMI_GPIO}/value) + case ${HDMI_VALUE} in + "0") + sleep 11 + pactl set-default-sink ${HDMI} + ;; + esac diff --git a/projects/ArchR/packages/hardware/quirks/devices/GameForce ACE/sleep.d/post/002-freq b/projects/ArchR/packages/hardware/quirks/devices/GameForce ACE/sleep.d/post/002-freq new file mode 100755 index 0000000000..4be1f2d5d7 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/GameForce ACE/sleep.d/post/002-freq @@ -0,0 +1,22 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +### Restore previous governors before going to sleep + +. /etc/profile + +### Grab the old governors. +OLD_CPU_FREQ=$(get_setting "sleep.cpugovernor") +if [ ! -n "${OLD_CPU_FREQ}" ]; then + OLD_CPU_FREQ="schedutil" +fi + +OLD_GPU_FREQ=$(get_setting "sleep.gpugovernor") +if [ ! -n "${OLD_GPU_FREQ}" ]; then + OLD_GPU_FREQ="simple_ondemand" +fi + +# Restore old governors. +set_cpu_gov "${OLD_CPU_FREQ}" +set_gpu_gov "${OLD_GPU_FREQ}" diff --git a/projects/ArchR/packages/hardware/quirks/devices/GameForce ACE/sleep.d/pre/002-freq b/projects/ArchR/packages/hardware/quirks/devices/GameForce ACE/sleep.d/pre/002-freq new file mode 100755 index 0000000000..a1c235ca32 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/GameForce ACE/sleep.d/pre/002-freq @@ -0,0 +1,18 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Store current freq governors and set governors to powersave. + +. /etc/profile + +### Get the current cpu and gpu governor, save for when the device wakes from sleep. +CUR_CPU_FREQ="$(cat ${CPU_FREQ}/scaling_governor)" +CUR_GPU_FREQ="$(cat ${GPU_FREQ}/governor)" + +set_setting sleep.cpugovernor "${CUR_CPU_FREQ}" +set_setting sleep.gpugovernor "${CUR_GPU_FREQ}" + +### Set all governors to powersave +set_cpu_gov powersave +set_gpu_gov powersave diff --git a/projects/ArchR/packages/hardware/quirks/devices/Gameforce CHI/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/Gameforce CHI/001-device_config new file mode 100755 index 0000000000..f4da1b9ee1 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Gameforce CHI/001-device_config @@ -0,0 +1,14 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/001-device_config +# Device Features +DEVICE_PLAYBACK_PATH_SPK="HP" +DEVICE_PLAYBACK_PATH_HP="SPK" +DEVICE_VOLUME="100" +DEVICE_BATTERY_LED_STATUS="true" +DEVICE_PWR_LED_GPIO="77" +DEVICE_TEMP_SENSOR="/sys/devices/virtual/thermal/thermal_zone0/temp" +DEVICE_MMC_EJECT="false" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Gameforce CHI/002-start-input b/projects/ArchR/packages/hardware/quirks/devices/Gameforce CHI/002-start-input new file mode 100755 index 0000000000..d061f6564f --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Gameforce CHI/002-start-input @@ -0,0 +1,5 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +/usr/bin/gameforce-chi-gamepad diff --git a/projects/ArchR/packages/hardware/quirks/devices/Gameforce CHI/050-game_configs b/projects/ArchR/packages/hardware/quirks/devices/Gameforce CHI/050-game_configs new file mode 100755 index 0000000000..8c16e46ea8 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Gameforce CHI/050-game_configs @@ -0,0 +1,48 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +#Set up gzdoom +if [ ! -d "/storage/.config/gzdoom/" ]; then + cp -rf /usr/config/gzdoom /storage/.config/ + sed -i '/Joy7=/c\Joy7=togglemap' /storage/.config/gzdoom/gzdoom.ini + sed -i '/Joy8=/c\Joy8=menu_main' /storage/.config/gzdoom/gzdoom.ini + sed -i '/Axis0scale=/c\Axis0scale=-0.8' /storage/.config/gzdoom/gzdoom.ini + sed -i '/Axis1scale=/c\Axis1scale=-0.6' /storage/.config/gzdoom/gzdoom.ini + sed -i '/vid_defheight=/c\vid_defheight=320' /storage/.config/gzdoom/gzdoom.ini + sed -i '/vid_defwidth=/c\vid_defwidth=480' /storage/.config/gzdoom/gzdoom.ini +fi + +#Map ppsspp controls +if grep RG351M -q "/stprage/.config/ppsspp/PSP/SYSTEM/controls.ini" +then + exit 1 +else +cat </storage/.config/ppsspp/PSP/SYSTEM/controls.ini +#RG351M +[ControlMapping] +Up = 10-19 +Down = 10-20 +Left = 10-21 +Right = 10-22 +Circle = 10-189 +Cross = 10-190 +Square = 10-188 +Triangle = 10-191 +Start = 10-197 +Select = 10-196 +L = 10-193 +R = 10-192 +An.Up = 10-4002 +An.Down = 10-4003 +An.Left = 10-4000 +An.Right = 10-4001 +Fast-forward = 1-61 +Pause = 10-106 +Save State = 10-4010 +Load State = 10-4008 +RightAn.Up = 10-4007 +RightAn.Down = 10-4006 +RightAn.Left = 10-4005 +RightAn.Right = 10-4004 +EOF +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/Gameforce CHI/050-modifiers b/projects/ArchR/packages/hardware/quirks/devices/Gameforce CHI/050-modifiers new file mode 100755 index 0000000000..36df82c365 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Gameforce CHI/050-modifiers @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/050-modifiers +DEVICE_FUNC_KEYA_MODIFIER="BTN_THUMBL" +DEVICE_FUNC_KEYB_MODIFIER="BTN_THUMBR" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Generic EE clone/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/Generic EE clone/001-device_config new file mode 100755 index 0000000000..7c27c554b0 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Generic EE clone/001-device_config @@ -0,0 +1,13 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/001-device_config +# Device Features +DEVICE_BATTERY_LED_STATUS="true" +DEVICE_TEMP_SENSOR="/sys/devices/virtual/thermal/thermal_zone0/temp" + +# disable legacy headphone script. ALSA UCM does that for us. +# See /usr/share/alsa/ucm2/Rockchip/rk817-sound/HiFi.conf +AUDIO_MANAGEMENT=UCM +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Generic EE clone/002-generate_dtbo b/projects/ArchR/packages/hardware/quirks/devices/Generic EE clone/002-generate_dtbo new file mode 100755 index 0000000000..ccceb1378f --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Generic EE clone/002-generate_dtbo @@ -0,0 +1,49 @@ +#!/bin/bash + +set -e + +STOCKPART="/dev/disk/by-label/EMUELEC" +DTBDIR="/flash/stock" +DTBOPATH="/flash/overlays/mipi-panel.dtbo" +TMPDIR="/tmp/flash_prepare" + +# no-op if dtbo already exists +[ -f "${DTBOPATH}" ] && exit 0 + +# Obtain stock dtb if needed and possible +if ! ls "${DTBDIR}"/*.dtb; then + if [ ! -L "${STOCKPART}" ]; then + echo "No stock dtb nor stock firmware partition found. Skipping dtbo generation" >&2 + exit 1 + fi + + # Prepare temporary destination + mkdir -p "${TMPDIR}/${DTBDIR}" + # Prepare source + mkdir -p /tmp/stock + mount "${STOCKPART}" /tmp/stock + # Copy all the dtbs (actually, there should be exactly one) + cp /tmp/stock/*.dtb "${TMPDIR}/${DTBDIR}" +fi + +STOCKDTB=$(ls "${DTBDIR}"/*.dtb "${TMPDIR}/${DTBDIR}"/*.dtb | head -1) +mkdir -p "${TMPDIR}/$(dirname ${DTBOPATH})" +echo "Preparing dtbo. This may take about a minute" +/usr/libexec/generic-dsi/archr_dtbo.py "${STOCKDTB}" -o "${TMPDIR}/${DTBOPATH}" + + +# Modifications to be made on firmaware partition +if [ -d "${TMPDIR}/flash" ]; then + mount -o remount,rw /flash + + rsync -av ${TMPDIR}/flash/ /flash || true + + # reinstall bootloader to switch console to UART5 + /usr/share/bootloader/update.sh + + # Cleanup and reboot + mount -o remount,ro /flash + sync +fi + +[ -f "${DTBOPATH}" ] && reboot diff --git a/projects/ArchR/packages/hardware/quirks/devices/Generic EE clone/010-led_control b/projects/ArchR/packages/hardware/quirks/devices/Generic EE clone/010-led_control new file mode 100755 index 0000000000..8ab918b534 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Generic EE clone/010-led_control @@ -0,0 +1,9 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/010-led_control +DEVICE_LED_CONTROL="false" +DEVICE_LED_BRIGHTNESS="false" +DEVICE_LED_CHARGING="false" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Generic EE clone/050-game_configs b/projects/ArchR/packages/hardware/quirks/devices/Generic EE clone/050-game_configs new file mode 100755 index 0000000000..ca19f23aed --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Generic EE clone/050-game_configs @@ -0,0 +1,58 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +#Set mupen64-plus-sa config for OGA +if [ ! -d "/storage/.config/mupen64plus" ]; then + mkdir -p "/storage/.config/mupen64plus/" + cp -r /usr/local/share/mupen64plus/mupen64plus.cfg* /storage/.config/mupen64plus/ +fi +if [ -f "/storage/.config/mupen64plus/mupen64plus.cfg.gen_2s" ]; then + rm /storage/.config/mupen64plus/mupen64plus.cfg + cp /storage/.config/mupen64plus/mupen64plus.cfg.gen_2s /storage/.config/mupen64plus/mupen64plus.cfg +fi + +#Set drastic-sa config for OGA +if [ ! -d "/storage/.config/drastic" ]; then + mkdir -p "/storage/.config/drastic" + cp -r "/usr/config/drastic" "/storage/.config/" +fi +if [ -f "/storage/.config/drastic/config/drastic.cfg.gen_2s" ]; then + cp /storage/.config/drastic/config/drastic.cfg.gen_2s /storage/.config/drastic/config/drastic.cfg +fi + +#Set ppsspp config for OGA +if [ ! -d "/storage/.config/ppsspp" ]; then + mkdir -p "/storage/.config/ppsspp" + cp -r "/usr/config/ppsspp" "/storage/.config/" +fi + +#Map ppsspp controls +if grep OGABE -q "/storage/.config/ppsspp/PSP/SYSTEM/controls.ini"; then + exit 1 +else + cat </storage/.config/ppsspp/PSP/SYSTEM/controls.ini +#OGABE +[ControlMapping] +Up = 10-19 +Down = 10-20 +Left = 10-21 +Right = 10-22 +Circle = 10-189 +Cross = 10-190 +Square = 10-188 +Triangle = 10-191 +Start = 10-197 +Select = 10-196 +L = 10-193 +R = 10-192 +An.Up = 10-4003 +An.Down = 10-4002 +An.Left = 10-4001 +An.Right = 10-4000 +Fast-forward = 1-61 +Pause = 10-106 +Save State = 10-4010 +Load State = 10-4008 +EOF +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/Generic EE clone/050-modifiers b/projects/ArchR/packages/hardware/quirks/devices/Generic EE clone/050-modifiers new file mode 100755 index 0000000000..a710ab7129 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Generic EE clone/050-modifiers @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/050-modifiers +DEVICE_FUNC_KEYA_MODIFIER="BTN_MODE" +DEVICE_FUNC_KEYB_MODIFIER="BTN_THUMBR" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Generic EE clone/bin/battery_led_status b/projects/ArchR/packages/hardware/quirks/devices/Generic EE clone/bin/battery_led_status new file mode 100755 index 0000000000..ed90ac61df --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Generic EE clone/bin/battery_led_status @@ -0,0 +1,54 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +# Simple script to watch the battery capacity and +# turn the power LED to different states: +# Blinking red when charge is less than 20% +# Blue turns off when charge is less than 10% + +RED_TRIGGER=/sys/class/leds/red\:charging/trigger +BLUE_TRIGGER=/sys/class/leds/blue\:status/trigger + +function red_led() { + case $1 in + none) echo none > ${RED_TRIGGER};; + blink) echo timer > ${RED_TRIGGER};; + steady) echo default-on > ${RED_TRIGGER};; + esac +} + +function blue_led() { + case $1 in + none) echo none > ${BLUE_TRIGGER};; + blink) echo timer > ${BLUE_TRIGGER};; + steady) echo default-on > ${BLUE_TRIGGER};; + esac +} + + +while true +do + CAP=$(cat /sys/class/power_supply/battery/capacity) + STAT=$(cat /sys/class/power_supply/battery/status) + if [[ ${STAT} == "Discharging" ]]; then + if (( ${CAP} <= 10 )); then + blue_led none + red_led blink + continue + elif (( ${CAP} <= 20 )); then + blue_led steady + red_led blink + else + blue_led steady + red_led none + fi + elif (( ${CAP} <= 95 )); then + blue_led steady + red_led steady + else + blue_led steady + red_led none + fi + sleep 15 +done diff --git a/projects/ArchR/packages/hardware/quirks/devices/Hardkernel ODROID-GO-Ultra/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/Hardkernel ODROID-GO-Ultra/001-device_config new file mode 100755 index 0000000000..39c6111a9a --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Hardkernel ODROID-GO-Ultra/001-device_config @@ -0,0 +1,9 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/001-device_config +DEVICE_FAKE_JACKSENSE="true" +DEVICE_HEADPHONE_DEV="/dev/input/by-path/platform-gpio-keys-event" +DEVICE_TEMP_SENSOR=("/sys/devices/virtual/thermal/thermal_zone0/temp" "/sys/devices/virtual/thermal/thermal_zone3/temp" "/sys/devices/virtual/thermal/thermal_zone2/temp") +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Hardkernel ODROID-GO-Ultra/002-turbo-mode_config b/projects/ArchR/packages/hardware/quirks/devices/Hardkernel ODROID-GO-Ultra/002-turbo-mode_config new file mode 100755 index 0000000000..f1b68db2fe --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Hardkernel ODROID-GO-Ultra/002-turbo-mode_config @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/002-turbo-mode_config +DEVICE_TURBO_MODE="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Hardkernel ODROID-GO-Ultra/050-audio_path b/projects/ArchR/packages/hardware/quirks/devices/Hardkernel ODROID-GO-Ultra/050-audio_path new file mode 100755 index 0000000000..f0a9c4d2ec --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Hardkernel ODROID-GO-Ultra/050-audio_path @@ -0,0 +1,18 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/002-audio_path +DEVICE_PLAYBACK_PATH_SPK="SPK" +DEVICE_PLAYBACK_PATH_HP="HP" +DEVICE_PLAYBACK_PATH="Playback Mux" +DEVICE_PIPEWIRE_PROFILE="pro-audio" +EOF + +### Set sound properties +amixer -c 0 -q sset 'FRDDR_A SINK 1 SEL' 'OUT 1' +amixer -c 0 -q sset 'FRDDR_A SRC 1 EN' 'on' + +### Required with kernels after 6.12 - restart pipewire so the +### source / sink get picked up correctly by wireplumber +systemctl restart pipewire diff --git a/projects/ArchR/packages/hardware/quirks/devices/Hardkernel ODROID-GO-Ultra/050-game_configs b/projects/ArchR/packages/hardware/quirks/devices/Hardkernel ODROID-GO-Ultra/050-game_configs new file mode 100755 index 0000000000..de8cffc1a2 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Hardkernel ODROID-GO-Ultra/050-game_configs @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +#Set up gzdoom +if [ ! -d "/storage/.config/gzdoom/" ]; then + cp -rf /usr/config/gzdoom /storage/.config/ + sed -i '/Joy18=/c\Joy18=togglemap' /storage/.config/gzdoom/gzdoom.ini + sed -i '/Joy13=/c\Joy13=menu_main' /storage/.config/gzdoom/gzdoom.ini + sed -i '/vid_defheight=/c\vid_defheight=480' /storage/.config/gzdoom/gzdoom.ini + sed -i '/vid_defwidth=/c\vid_defwidth=854' /storage/.config/gzdoom/gzdoom.ini +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/KONKR Pocket FIT b/projects/ArchR/packages/hardware/quirks/devices/KONKR Pocket FIT new file mode 120000 index 0000000000..ec802bb776 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/KONKR Pocket FIT @@ -0,0 +1 @@ +AYANEO Pocket S2 \ No newline at end of file diff --git a/projects/ArchR/packages/hardware/quirks/devices/MagicX XU Mini M/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/MagicX XU Mini M/001-device_config new file mode 100755 index 0000000000..e3b1984b95 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/MagicX XU Mini M/001-device_config @@ -0,0 +1,12 @@ + +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/001-device_config +# Device Features +DEVICE_PLAYBACK_PATH_SPK="HP" +DEVICE_PLAYBACK_PATH_HP="SPK" +DEVICE_BATTERY_LED_STATUS="true" +DEVICE_TEMP_SENSOR="/sys/devices/virtual/thermal/thermal_zone0/temp" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/MagicX XU Mini M/004-game-configs b/projects/ArchR/packages/hardware/quirks/devices/MagicX XU Mini M/004-game-configs new file mode 100755 index 0000000000..588565ef25 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/MagicX XU Mini M/004-game-configs @@ -0,0 +1,54 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +#Set mupen64-plus-sa config for XU Mini M +if [ ! -d "/storage/.config/mupen64plus" ]; then + mkdir -p /storage/.config/mupen64plus + cp -r /usr/local/share/mupen64plus/mupen64plus.cfg* /storage/.config/mupen64plus +fi +if [ -f "/storage/.config/mupen64plus/mupen64plus.cfg.xut" ]; then + rm /storage/.config/mupen64plus/mupen64plus.cfg + mv /storage/.config/mupen64plus/mupen64plus.cfg.xut /storage/.config/mupen64plus/mupen64plus.cfg +fi + +#Set drastic-sa config for XU Mini M +if [ ! -d "/storage/.config/drastic" ]; then + mkdir -p "/storage/.config/drastic" + cp -r /usr/config/drastic /storage/.config +fi +if [ -f "/storage/.config/drastic/config/drastic.cfg.xut" ]; then + rm /storage/.config/drastic/config/drastic.cfg + mv /storage/.config/drastic/config/drastic.cfg.xut /storage/.config/drastic/config/drastic.cfg +fi + +#Map ppsspp controls +if grep XUMiniM -q "/storage/.config/ppsspp/PSP/SYSTEM/controls.ini"; then + exit 1 +else +cat </storage/.config/ppsspp/PSP/SYSTEM/controls.ini +#XUMiniM +[ControlMapping] +Up = 10-19 +Down = 10-20 +Left = 10-21 +Right = 10-22 +Circle = 10-189 +Cross = 10-190 +Square = 10-188 +Triangle = 10-191 +Start = 10-197 +Select = 10-196 +L = 10-193 +R = 10-192 +An.Up = 10-4000 +An.Down = 10-4001 +An.Left = 10-4003 +An.Right = 10-4002 +Pause = 10-196:10-4008 +RightAn.Up = 10-4004 +RightAn.Down = 10-4005 +RightAn.Left = 10-4007 +RightAn.Right = 10-4006 +EOF +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/MagicX XU Mini M/010-led_control b/projects/ArchR/packages/hardware/quirks/devices/MagicX XU Mini M/010-led_control new file mode 100755 index 0000000000..8ab918b534 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/MagicX XU Mini M/010-led_control @@ -0,0 +1,9 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/010-led_control +DEVICE_LED_CONTROL="false" +DEVICE_LED_BRIGHTNESS="false" +DEVICE_LED_CHARGING="false" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/MagicX XU Mini M/bin/battery_led_status b/projects/ArchR/packages/hardware/quirks/devices/MagicX XU Mini M/bin/battery_led_status new file mode 100755 index 0000000000..9667e06d26 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/MagicX XU Mini M/bin/battery_led_status @@ -0,0 +1,59 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +# Simple script to watch the battery capacity and +# turn the power LED to different states: +# 0-10% flashing blue and teal +# 11-20% teal +# 21+% blue +# charging purple +# fully charged white + +function set_led() { + case $1 in + white) + echo 1 > /sys/class/leds/red\:charging/brightness + echo 1 > /sys/class/leds/green\:status/brightness + ;; + purple) + echo 1 > /sys/class/leds/red\:charging/brightness + echo 0 > /sys/class/leds/green\:status/brightness + ;; + blue) + echo 0 > /sys/class/leds/red\:charging/brightness + echo 0 > /sys/class/leds/green\:status/brightness + ;; + teal) + echo 0 > /sys/class/leds/red\:charging/brightness + echo 1 > /sys/class/leds/green\:status/brightness + ;; + esac +} + +while true +do + CAP=$(cat /sys/class/power_supply/battery/capacity) + STAT=$(cat /sys/class/power_supply/battery/status) + if [[ ${STAT} == "Discharging" ]]; then + if (( ${CAP} <= 10 )); then + for ctr in $(seq 1 1 5) + do + set_led teal + sleep .5 + set_led blue + sleep .5 + done + continue + elif (( ${CAP} <= 20 )); then + set_led teal + else + set_led blue + fi + elif (( ${CAP} <= 95 )); then + set_led purple + else + set_led white + fi + sleep 15 +done diff --git a/projects/ArchR/packages/hardware/quirks/devices/MagicX XU10/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/MagicX XU10/001-device_config new file mode 100755 index 0000000000..be8c1c57b9 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/MagicX XU10/001-device_config @@ -0,0 +1,11 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/001-device_config +# Device Features +DEVICE_PLAYBACK_PATH_SPK="SPK" +DEVICE_PLAYBACK_PATH_HP="HP" +DEVICE_BATTERY_LED_STATUS="true" +DEVICE_TEMP_SENSOR="/sys/devices/virtual/thermal/thermal_zone0/temp" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/MagicX XU10/004-game-configs b/projects/ArchR/packages/hardware/quirks/devices/MagicX XU10/004-game-configs new file mode 100755 index 0000000000..130dce137d --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/MagicX XU10/004-game-configs @@ -0,0 +1,55 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +#Set mupen64-plus-sa config for XU10 +if [ ! -d "/storage/.config/mupen64plus" ]; then + mkdir -p "/storage/.config/mupen64plus/" + cp -r /usr/local/share/mupen64plus/mupen64plus.cfg* /storage/.config/mupen64plus/ +fi +if [ -f "/storage/.config/mupen64plus/mupen64plus.cfg.xut" ]; then + rm /storage/.config/mupen64plus/mupen64plus.cfg + mv /storage/.config/mupen64plus/mupen64plus.cfg.xut /storage/.config/mupen64plus/mupen64plus.cfg +fi + +#Set drastic-sa config for XU10 +if [ ! -d "/storage/.config/drastic" ]; then + mkdir -p "/storage/.config/drastic" + cp -r "/usr/config/drastic" "/storage/.config/" +fi +if [ -f "/storage/.config/drastic/config/drastic.cfg.xut" ]; then + rm /storage/.config/drastic/config/drastic.cfg + mv /storage/.config/drastic/config/drastic.cfg.xut /storage/.config/drastic/config/drastic.cfg +fi + +#Map ppsspp controls +if grep XU10 -q "/storage/.config/ppsspp/PSP/SYSTEM/controls.ini" +then + exit 1 +else +cat </storage/.config/ppsspp/PSP/SYSTEM/controls.ini +#XU10 +[ControlMapping] +Up = 10-19 +Down = 10-20 +Left = 10-21 +Right = 10-22 +Circle = 10-190 +Cross = 10-189 +Square = 10-191 +Triangle = 10-188 +Start = 10-197 +Select = 10-196 +L = 10-193 +R = 10-192 +An.Up = 10-4003 +An.Down = 10-4002 +An.Left = 10-4001 +An.Right = 10-4000 +Pause = 10-109,10-104,1-111 +RightAn.Up = 10-4007 +RightAn.Down = 10-4006 +RightAn.Left = 10-4005 +RightAn.Right = 10-4004 +EOF +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/MagicX XU10/bin/battery_led_status b/projects/ArchR/packages/hardware/quirks/devices/MagicX XU10/bin/battery_led_status new file mode 100755 index 0000000000..089ce1370a --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/MagicX XU10/bin/battery_led_status @@ -0,0 +1,65 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2020-present Fewtarius + +# Simple script to watch the battery capacity and +# turn the power LED to different states: +# 0-10% flashing blue and teal +# 11-20% teal +# 21+% blue +# charging purple +# fully charged white + +function set_led() { + case $1 in + white) + echo 1 > /sys/class/leds/red\:charging/brightness + echo 1 > /sys/class/leds/green\:status/brightness + ;; + purple) + echo 1 > /sys/class/leds/red\:charging/brightness + echo 0 > /sys/class/leds/green\:status/brightness + ;; + blue) + echo 0 > /sys/class/leds/red\:charging/brightness + echo 0 > /sys/class/leds/green\:status/brightness + ;; + teal) + echo 0 > /sys/class/leds/red\:charging/brightness + echo 1 > /sys/class/leds/green\:status/brightness + ;; + esac +} + + +while true +do + CAP=$(cat /sys/class/power_supply/battery/capacity) + STAT=$(cat /sys/class/power_supply/battery/status) + if [[ ${STAT} == "Discharging" ]] + then + if (( ${CAP} <= 10 )) + then + for ctr in $(seq 1 1 5) + do + set_led teal + sleep .5 + set_led blue + sleep .5 + done + continue + elif (( ${CAP} <= 20 )) + then + set_led teal + else + set_led blue + fi + elif (( ${CAP} <= 95 )) + then + set_led purple + else + set_led white + fi + sleep 15 +done diff --git a/projects/ArchR/packages/hardware/quirks/devices/ODROID-GO Advance Black Edition/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/ODROID-GO Advance Black Edition/001-device_config new file mode 100755 index 0000000000..894b320b32 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/ODROID-GO Advance Black Edition/001-device_config @@ -0,0 +1,11 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/001-device_config +# Device Features +DEVICE_SW_HP_SWITCH="true" +DEVICE_PLAYBACK_PATH_SPK="SPK" +DEVICE_PLAYBACK_PATH_HP="HP" +DEVICE_MMC_EJECT="false" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/ODROID-GO Advance Black Edition/009-commander-cfg b/projects/ArchR/packages/hardware/quirks/devices/ODROID-GO Advance Black Edition/009-commander-cfg new file mode 100644 index 0000000000..a9c4b8bd72 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/ODROID-GO Advance Black Edition/009-commander-cfg @@ -0,0 +1,11 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +if [ ! -f "/storage/.config/commander.cfg" ]; then +cat </storage/.config/commander.cfg +disp_ppu_x=1.5 +disp_ppu_y=1.5 +EOF +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/ODROID-GO Advance Black Edition/050-game_configs b/projects/ArchR/packages/hardware/quirks/devices/ODROID-GO Advance Black Edition/050-game_configs new file mode 100755 index 0000000000..8289182285 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/ODROID-GO Advance Black Edition/050-game_configs @@ -0,0 +1,59 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +#Set mupen64-plus-sa config for OGA +if [ ! -d "/storage/.config/mupen64plus" ]; then + mkdir -p "/storage/.config/mupen64plus/" + cp -r /usr/local/share/mupen64plus/mupen64plus.cfg* /storage/.config/mupen64plus/ +fi +if [ -f "/storage/.config/mupen64plus/mupen64plus.cfg.ogabe" ]; then + rm /storage/.config/mupen64plus/mupen64plus.cfg + cp /storage/.config/mupen64plus/mupen64plus.cfg.ogabe /storage/.config/mupen64plus/mupen64plus.cfg +fi + +#Set drastic-sa config for OGA +if [ ! -d "/storage/.config/drastic" ]; then + mkdir -p "/storage/.config/drastic" + cp -r "/usr/config/drastic" "/storage/.config/" +fi +if [ -f "/storage/.config/drastic/config/drastic.cfg.ogabe" ]; then + cp /storage/.config/drastic/config/drastic.cfg.ogabe /storage/.config/drastic/config/drastic.cfg +fi + +#Set ppsspp config for OGA +if [ ! -d "/storage/.config/ppsspp" ]; then + mkdir -p "/storage/.config/ppsspp" + cp -r "/usr/config/ppsspp" "/storage/.config/" +fi + +#Map ppsspp controls +if grep OGABE -q "/storage/.config/ppsspp/PSP/SYSTEM/controls.ini" +then + exit 1 +else +cat </storage/.config/ppsspp/PSP/SYSTEM/controls.ini +#OGABE +[ControlMapping] +Up = 10-19 +Down = 10-20 +Left = 10-21 +Right = 10-22 +Circle = 10-189 +Cross = 10-190 +Square = 10-188 +Triangle = 10-191 +Start = 10-197 +Select = 10-196 +L = 10-193 +R = 10-192 +An.Up = 10-4003 +An.Down = 10-4002 +An.Left = 10-4001 +An.Right = 10-4000 +Fast-forward = 1-61 +Pause = 10-106 +Save State = 10-4010 +Load State = 10-4008 +EOF +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/ODROID-GO Advance/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/ODROID-GO Advance/001-device_config new file mode 100755 index 0000000000..e19e45f1b9 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/ODROID-GO Advance/001-device_config @@ -0,0 +1,15 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/001-device_config +# Device Features +DEVICE_PLAYBACK_PATH_SPK="SPK" +DEVICE_PLAYBACK_PATH_HP="HP" +DEVICE_SW_HP_SWITCH="true" +DEVICE_VOLUME="100" +DEVICE_BATTERY_LED_STATUS="true" +DEVICE_PWR_LED_GPIO="77" +DEVICE_TEMP_SENSOR="/sys/devices/virtual/thermal/thermal_zone0/temp" +DEVICE_MMC_EJECT="false" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/ODROID-GO Advance/009-commander-cfg b/projects/ArchR/packages/hardware/quirks/devices/ODROID-GO Advance/009-commander-cfg new file mode 100644 index 0000000000..a9c4b8bd72 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/ODROID-GO Advance/009-commander-cfg @@ -0,0 +1,11 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +if [ ! -f "/storage/.config/commander.cfg" ]; then +cat </storage/.config/commander.cfg +disp_ppu_x=1.5 +disp_ppu_y=1.5 +EOF +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/ODROID-GO Advance/050-game_configs b/projects/ArchR/packages/hardware/quirks/devices/ODROID-GO Advance/050-game_configs new file mode 100755 index 0000000000..1d0b5f1460 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/ODROID-GO Advance/050-game_configs @@ -0,0 +1,52 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +#Set mupen64-plus-sa config for OGA +if [ ! -d "/storage/.config/mupen64plus" ]; then + mkdir -p "/storage/.config/mupen64plus/" + cp -r /usr/local/share/mupen64plus/mupen64plus.cfg* /storage/.config/mupen64plus/ +fi +if [ -f "/storage/.config/mupen64plus/mupen64plus.cfg.oga" ]; then + rm /storage/.config/mupen64plus/mupen64plus.cfg + mv /storage/.config/mupen64plus/mupen64plus.cfg.oga /storage/.config/mupen64plus/mupen64plus.cfg +fi + +#Set drastic-sa config for OGA +if [ ! -d "/storage/.config/drastic" ]; then + mkdir -p "/storage/.config/drastic" + cp -r "/usr/config/drastic" "/storage/.config/" +fi +if [ -f "/storage/.config/drastic/config/drastic.cfg.oga" ]; then + rm /storage/.config/drastic/config/drastic.cfg + mv /storage/.config/drastic/config/drastic.cfg.oga /storage/.config/drastic/config/drastic.cfg +fi + +#Map ppsspp controls +if grep OGA-1.0 -q "/storage/.config/ppsspp/PSP/SYSTEM/controls.ini" +then + exit 1 +else +cat </storage/.config/ppsspp/PSP/SYSTEM/controls.ini +#OGA-1.0 +[ControlMapping] +Up = 10-19 +Down = 10-20 +Left = 10-21 +Right = 10-22 +Circle = 10-189 +Cross = 10-190 +Square = 10-188 +Triangle = 10-191 +Start = 10-107 +Select = 10-4008 +L = 10-193 +R = 10-192 +An.Up = 10-4002 +An.Down = 10-4003 +An.Left = 10-4000 +An.Right = 10-4001 +Fast-forward = 1-61 +Save State = 10-106 +EOF +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/ODROID-GO Super/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/ODROID-GO Super/001-device_config new file mode 100755 index 0000000000..17bd55e1e3 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/ODROID-GO Super/001-device_config @@ -0,0 +1,10 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/001-device_config +# Device Features +DEVICE_PLAYBACK_PATH_SPK="SPK" +DEVICE_PLAYBACK_PATH_HP="HP" +DEVICE_MMC_EJECT="false" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/ODROID-GO Super/050-game_configs b/projects/ArchR/packages/hardware/quirks/devices/ODROID-GO Super/050-game_configs new file mode 100755 index 0000000000..e7beaa7073 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/ODROID-GO Super/050-game_configs @@ -0,0 +1,57 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +#Set mupen64-plus-sa config for OGS +if [ ! -d "/storage/.config/mupen64plus" ]; then + mkdir -p "/storage/.config/mupen64plus/" + cp -r /usr/local/share/mupen64plus/mupen64plus.cfg* /storage/.config/mupen64plus/ +fi +if [ -f "/storage/.config/mupen64plus/mupen64plus.cfg.ogs" ]; then + rm /storage/.config/mupen64plus/mupen64plus.cfg + mv /storage/.config/mupen64plus/mupen64plus.cfg.ogs /storage/.config/mupen64plus/mupen64plus.cfg +fi + +#Set drastic-sa config for OGS +if [ ! -d "/storage/.config/drastic" ]; then + mkdir -p "/storage/.config/drastic" + cp -r "/usr/config/drastic" "/storage/.config/" +fi +if [ -f "/storage/.config/drastic/config/drastic.cfg.ogs" ]; then + rm /storage/.config/drastic/config/drastic.cfg + mv /storage/.config/drastic/config/drastic.cfg.ogs /storage/.config/drastic/config/drastic.cfg +fi + +#Map ppsspp controls +if grep OGS -q "/storage/.config/ppsspp/PSP/SYSTEM/controls.ini" +then + exit 1 +else +cat </storage/.config/ppsspp/PSP/SYSTEM/controls.ini +#OGS +[ControlMapping] +Up = 10-19 +Down = 10-20 +Left = 10-21 +Right = 10-22 +Circle = 10-189 +Cross = 10-190 +Square = 10-188 +Triangle = 10-191 +Start = 10-197 +Select = 10-196 +L = 10-193 +R = 10-192 +An.Up = 10-4003 +An.Down = 10-4002 +An.Left = 10-4001 +An.Right = 10-4000 +Pause = 10-106 +Save State = 10-4010 +Load State = 10-4008 +RightAn.Up = 10-4007 +RightAn.Down = 10-4006 +RightAn.Left = 10-4005 +RightAn.Right = 10-4004 +EOF +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10 MAX 3 Pro/050-audio_path b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10 MAX 3 Pro/050-audio_path new file mode 100755 index 0000000000..091625192e --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10 MAX 3 Pro/050-audio_path @@ -0,0 +1,18 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/002-audio_path +DEVICE_PLAYBACK_PATH_SPK="HP" +DEVICE_PLAYBACK_PATH_HP="SPK" +DEVICE_PLAYBACK_PATH="Playback Path" +DEVICE_PIPEWIRE_PROFILE="pro-audio" +EOF + +### Set sound properties +amixer -c 0 -q sset 'FRDDR_A SINK 1 SEL' 'OUT 1' +amixer -c 0 -q sset 'FRDDR_A SRC 1 EN' 'on' + +### Required with kernels after 6.12 - restart pipewire so the +### source / sink get picked up correctly by wireplumber +systemctl restart pipewire diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10 MAX 3 Pro/050-game_configs b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10 MAX 3 Pro/050-game_configs new file mode 100755 index 0000000000..de8cffc1a2 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10 MAX 3 Pro/050-game_configs @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +#Set up gzdoom +if [ ! -d "/storage/.config/gzdoom/" ]; then + cp -rf /usr/config/gzdoom /storage/.config/ + sed -i '/Joy18=/c\Joy18=togglemap' /storage/.config/gzdoom/gzdoom.ini + sed -i '/Joy13=/c\Joy13=menu_main' /storage/.config/gzdoom/gzdoom.ini + sed -i '/vid_defheight=/c\vid_defheight=480' /storage/.config/gzdoom/gzdoom.ini + sed -i '/vid_defwidth=/c\vid_defwidth=854' /storage/.config/gzdoom/gzdoom.ini +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10 Max 3/020-gpios b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10 Max 3/020-gpios new file mode 100755 index 0000000000..357fcb1087 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10 Max 3/020-gpios @@ -0,0 +1,15 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/020-gpios +DEVICE_WIFI="0" +DEVICE_PWM_MOTOR="pwmchip1" +EOF + +. /storage/.config/profile.d/020-gpios +# Enable PWM for rumble and turn rumble off during startup. +echo 0 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/export +echo 1000000 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/period +echo 1 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/enable +echo 1000000 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/duty_cycle diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10 Max 3/040-display b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10 Max 3/040-display new file mode 100755 index 0000000000..efb4451642 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10 Max 3/040-display @@ -0,0 +1,17 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +# Configure default contrast saturation and hue values +for PROPERTY in brightness contrast saturation hue +do + MYVAL=$(get_setting display.${PROPERTY}) + if [ -z "${MYVAL}" ] + then + MYVAL=$(drm_tool list | sed -n '/Connector: 133/,$p' | awk '/'${PROPERTY}'/ {print $5}') + fi + paneladj ${PROPERTY} ${MYVAL} +done diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10 Max 3/050-audio_path b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10 Max 3/050-audio_path new file mode 100755 index 0000000000..f5860cdb57 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10 Max 3/050-audio_path @@ -0,0 +1,9 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/002-audio_path +DEVICE_PLAYBACK_PATH_SPK="HP" +DEVICE_PLAYBACK_PATH_HP="SPK" +DEVICE_PLAYBACK_PATH="Playback Path" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10/001-device_config new file mode 120000 index 0000000000..5ce9862c95 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10/001-device_config @@ -0,0 +1 @@ +../ODROID-GO Advance Black Edition/001-device_config \ No newline at end of file diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10/009-commander-cfg b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10/009-commander-cfg new file mode 100644 index 0000000000..a9c4b8bd72 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10/009-commander-cfg @@ -0,0 +1,11 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +if [ ! -f "/storage/.config/commander.cfg" ]; then +cat </storage/.config/commander.cfg +disp_ppu_x=1.5 +disp_ppu_y=1.5 +EOF +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10/050-game_configs b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10/050-game_configs new file mode 120000 index 0000000000..0a41c8be26 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10/050-game_configs @@ -0,0 +1 @@ +../ODROID-GO Advance Black Edition/050-game_configs \ No newline at end of file diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10/050-modifiers b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10/050-modifiers new file mode 100755 index 0000000000..36df82c365 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10/050-modifiers @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/050-modifiers +DEVICE_FUNC_KEYA_MODIFIER="BTN_THUMBL" +DEVICE_FUNC_KEYB_MODIFIER="BTN_THUMBR" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10/075-dpad-volbright b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10/075-dpad-volbright new file mode 100755 index 0000000000..c542993977 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10/075-dpad-volbright @@ -0,0 +1,23 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +DPAD_EVENTS=$(get_setting key.dpad.events) +if [ -z "${DPAD_EVENTS}" ] +then + set_setting key.dpad.events 1 +fi + +KEY_FUNC_A=$(get_setting key.function.a) +if [ -z "${KEY_FUNC_A}" ] +then + set_setting key.function.a BTN_SELECT +fi + +if [ "$(systemctl is-active input)" = "active" ] +then + systemctl restart input +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10/110-retroarch-joypad b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10/110-retroarch-joypad new file mode 100755 index 0000000000..00af09392b --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10/110-retroarch-joypad @@ -0,0 +1,11 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +# Adapt retroarch joypad config for rgb10 + +if [ ! -f "/storage/joypads/odroidgo2_v11_joypad.cfg" ]; then + cp /usr/share/libretro/autoconfig/odroidgo2_v11_joypad.cfg /storage/joypads/ + sed -i -r 's/input_enable_hotkey_btn.*/input_enable_hotkey_btn = "10"/' /storage/joypads/odroidgo2_v11_joypad.cfg +fi + diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10X/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10X/001-device_config new file mode 100755 index 0000000000..bbc01b57c4 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10X/001-device_config @@ -0,0 +1,11 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/001-device_config +# Device Features +DEVICE_PLAYBACK_PATH_SPK="HP" +DEVICE_PLAYBACK_PATH_HP="SPK" +DEVICE_BATTERY_LED_STATUS="true" +DEVICE_TEMP_SENSOR="/sys/devices/virtual/thermal/thermal_zone0/temp" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10X/010-led_control b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10X/010-led_control new file mode 100755 index 0000000000..8ab918b534 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10X/010-led_control @@ -0,0 +1,9 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/010-led_control +DEVICE_LED_CONTROL="false" +DEVICE_LED_BRIGHTNESS="false" +DEVICE_LED_CHARGING="false" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10X/050-game_configs b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10X/050-game_configs new file mode 100755 index 0000000000..9bd6fef780 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10X/050-game_configs @@ -0,0 +1,58 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +#Set mupen64-plus-sa config for OGA +if [ ! -d "/storage/.config/mupen64plus" ]; then + mkdir -p "/storage/.config/mupen64plus/" + cp -r /usr/local/share/mupen64plus/mupen64plus.cfg* /storage/.config/mupen64plus/ +fi +if [ -f "/storage/.config/mupen64plus/mupen64plus.cfg.s1_f2" ]; then + rm /storage/.config/mupen64plus/mupen64plus.cfg + cp /storage/.config/mupen64plus/mupen64plus.cfg.s1_f2 /storage/.config/mupen64plus/mupen64plus.cfg +fi + +#Set drastic-sa config for OGA +if [ ! -d "/storage/.config/drastic" ]; then + mkdir -p "/storage/.config/drastic" + cp -r "/usr/config/drastic" "/storage/.config/" +fi +if [ -f "/storage/.config/drastic/config/drastic.cfg.s1_f2" ]; then + cp /storage/.config/drastic/config/drastic.cfg.s1_f2 /storage/.config/drastic/config/drastic.cfg +fi + +#Set ppsspp config for OGA +if [ ! -d "/storage/.config/ppsspp" ]; then + mkdir -p "/storage/.config/ppsspp" + cp -r "/usr/config/ppsspp" "/storage/.config/" +fi + +#Map ppsspp controls +if grep OGABE -q "/storage/.config/ppsspp/PSP/SYSTEM/controls.ini"; then + exit 1 +else + cat </storage/.config/ppsspp/PSP/SYSTEM/controls.ini +#OGABE +[ControlMapping] +Up = 10-19 +Down = 10-20 +Left = 10-21 +Right = 10-22 +Circle = 10-189 +Cross = 10-190 +Square = 10-188 +Triangle = 10-191 +Start = 10-197 +Select = 10-196 +L = 10-193 +R = 10-192 +An.Up = 10-4003 +An.Down = 10-4002 +An.Left = 10-4001 +An.Right = 10-4000 +Fast-forward = 1-61 +Pause = 10-106 +Save State = 10-4010 +Load State = 10-4008 +EOF +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10X/050-modifiers b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10X/050-modifiers new file mode 100755 index 0000000000..a710ab7129 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10X/050-modifiers @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/050-modifiers +DEVICE_FUNC_KEYA_MODIFIER="BTN_MODE" +DEVICE_FUNC_KEYB_MODIFIER="BTN_THUMBR" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10X/bin/battery_led_status b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10X/bin/battery_led_status new file mode 100755 index 0000000000..280c23a000 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB10X/bin/battery_led_status @@ -0,0 +1,45 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +# Simple script to watch the battery capacity and +# turn the power LED to different states: +# 0-10% flashing green and red +# 11-20% red +# 21+% green +# charging red +# 95+% charging green + +function set_led() { + case $1 in + green) echo 0 > /sys/class/leds/red\:charging/brightness;; + red) echo 1 > /sys/class/leds/red\:charging/brightness;; + esac +} + + +while true +do + CAP=$(cat /sys/class/power_supply/battery/capacity) + STAT=$(cat /sys/class/power_supply/battery/status) + if [[ ${STAT} == "Discharging" ]]; then + if (( ${CAP} <= 10 )); then + for ctr in $(seq 1 1 5); do + set_led green + sleep .5 + set_led red + sleep .5 + done + continue + elif (( ${CAP} <= 20 )); then + set_led red + else + set_led green + fi + elif (( ${CAP} <= 95 )); then + set_led red + else + set_led green + fi + sleep 15 +done diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB20 Pro/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB20 Pro/001-device_config new file mode 100755 index 0000000000..f712421662 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB20 Pro/001-device_config @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/001-device_config +# Device Features +DEVICE_BATTERY_LED_STATUS="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB20 Pro/010-led_control b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB20 Pro/010-led_control new file mode 100755 index 0000000000..8ab918b534 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB20 Pro/010-led_control @@ -0,0 +1,9 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/010-led_control +DEVICE_LED_CONTROL="false" +DEVICE_LED_BRIGHTNESS="false" +DEVICE_LED_CHARGING="false" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB20 Pro/bin/battery_led_status b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB20 Pro/bin/battery_led_status new file mode 100755 index 0000000000..c78d287e95 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB20 Pro/bin/battery_led_status @@ -0,0 +1,57 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +# Simple script to watch the battery capacity and +# turn the power LED to different states: +# 0-10% flashing red +# 11-20% red +# 21+% green +# <95% charging green+red +# 95+% charging green + +function set_led() { + case $1 in + green) + echo 25 > /sys/class/leds/green:status/brightness + ;; + red) + echo 255 > /sys/class/leds/red:charging/brightness + ;; + off) + echo 0 > /sys/class/leds/green:status/brightness + echo 0 > /sys/class/leds/red:charging/brightness + ;; + esac +} + + +while true +do + CAP=$(cat /sys/class/power_supply/battery/capacity) + STAT=$(cat /sys/class/power_supply/battery/status) + if [[ ${STAT} == "Discharging" ]]; then + if (( ${CAP} <= 10 )); then + for ctr in $(seq 1 1 5); do + set_led off + sleep .5 + set_led red + sleep .5 + done + continue + elif (( ${CAP} <= 20 )); then + set_led off + set_led red + else + set_led off + set_led green + fi + elif (( ${CAP} <= 95 )); then + set_led red + set_led green + else + set_led off + set_led green + fi + sleep 15 +done diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB20S/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB20S/001-device_config new file mode 100755 index 0000000000..243906cf13 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB20S/001-device_config @@ -0,0 +1,11 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/001-device_config +# Device Features +DEVICE_PLAYBACK_PATH_SPK="HP" +DEVICE_PLAYBACK_PATH_HP="SPK" +DEVICE_PWR_LED_GPIO="77" +DEVICE_TEMP_SENSOR="/sys/devices/virtual/thermal/thermal_zone0/temp" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB20S/002-disable-led b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB20S/002-disable-led new file mode 100755 index 0000000000..7e5ed7a899 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB20S/002-disable-led @@ -0,0 +1,13 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Set export GPIO for Power LED +if [ ! -d "/sys/class/gpio/gpio${DEVICE_PWR_LED_GPIO}" ]; then + echo ${DEVICE_PWR_LED_GPIO} > /sys/class/gpio/export +fi + +#Disable blue led on R33S +echo out >/sys/class/gpio/gpio${DEVICE_PWR_LED_GPIO}/direction +echo 1 >/sys/class/gpio/gpio${DEVICE_PWR_LED_GPIO}/value diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB20S/050-game-configs b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB20S/050-game-configs new file mode 100755 index 0000000000..e839f4e896 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB20S/050-game-configs @@ -0,0 +1,57 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +#Set mupen64-plus-sa config for RGB20S, can use same profile as OGS +if [ ! -d "/storage/.config/mupen64plus" ]; then + mkdir -p "/storage/.config/mupen64plus/" + cp -r /usr/local/share/mupen64plus/mupen64plus.cfg* /storage/.config/mupen64plus/ +fi +if [ -f "/storage/.config/mupen64plus/mupen64plus.cfg.ogs" ]; then + rm /storage/.config/mupen64plus/mupen64plus.cfg + mv /storage/.config/mupen64plus/mupen64plus.cfg.ogs /storage/.config/mupen64plus/mupen64plus.cfg +fi + +#Set drastic-sa config for RGB20S +if [ ! -d "/storage/.config/drastic" ]; then + mkdir -p "/storage/.config/drastic" + cp -r "/usr/config/drastic" "/storage/.config/" +fi +if [ -f "/storage/.config/drastic/config/drastic.cfg.rgb20s" ]; then + rm /storage/.config/drastic/config/drastic.cfg + mv /storage/.config/drastic/config/drastic.cfg.rgb20s /storage/.config/drastic/config/drastic.cfg +fi + +#Map ppsspp controls +if grep RGB20S -q "/storage/.config/ppsspp/PSP/SYSTEM/controls.ini" +then + exit 1 +else +cat </storage/.config/ppsspp/PSP/SYSTEM/controls.ini +#RGB20S +[ControlMapping] +Up = 10-19 +Down = 10-20 +Left = 10-21 +Right = 10-22 +Circle = 10-189 +Cross = 10-190 +Square = 10-188 +Triangle = 10-191 +Start = 10-197 +Select = 10-196 +L = 10-193 +R = 10-192 +An.Up = 10-4003 +An.Down = 10-4002 +An.Left = 10-4001 +An.Right = 10-4000 +Pause = 10-106 +Save State = 10-4010 +Load State = 10-4008 +RightAn.Up = 10-4007 +RightAn.Down = 10-4006 +RightAn.Left = 10-4005 +RightAn.Right = 10-4004 +EOF +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB20SX/010-led_control b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB20SX/010-led_control new file mode 100644 index 0000000000..e54be4fc32 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB20SX/010-led_control @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/010-led_control +echo 0 > /sys/class/leds/red\:charging/brightness +echo 1 > /sys/class/leds/green\:status/brightness +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB20SX/020-gpios b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB20SX/020-gpios new file mode 100755 index 0000000000..357fcb1087 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB20SX/020-gpios @@ -0,0 +1,15 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/020-gpios +DEVICE_WIFI="0" +DEVICE_PWM_MOTOR="pwmchip1" +EOF + +. /storage/.config/profile.d/020-gpios +# Enable PWM for rumble and turn rumble off during startup. +echo 0 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/export +echo 1000000 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/period +echo 1 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/enable +echo 1000000 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/duty_cycle diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB20SX/040-display b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB20SX/040-display new file mode 100755 index 0000000000..c0d7d0d670 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB20SX/040-display @@ -0,0 +1,14 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Configure default contrast saturation and hue values +for PROPERTY in brightness contrast saturation hue +do + MYVAL=$(get_setting display.${PROPERTY}) + if [ -z "${MYVAL}" ] + then + MYVAL=$(drm_tool list | sed -n '/Connector: 133/,$p' | awk '/'${PROPERTY}'/ {print $5}') + fi + paneladj ${PROPERTY} ${MYVAL} +done diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB20SX/060-game_settings b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB20SX/060-game_settings new file mode 100755 index 0000000000..d058f2fb42 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB20SX/060-game_settings @@ -0,0 +1,12 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile.d/001-functions + +SETTING=$(get_setting pico-8.integerscale) +if [ -z ${SETTING} ] +then + set_setting pico-8.integerscale 1 +fi + diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB30/001-detect-device b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB30/001-detect-device new file mode 100755 index 0000000000..6481d02817 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB30/001-detect-device @@ -0,0 +1,9 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +if grep -q "024C:D723" "/sys/devices/platform/fe000000.mmc/mmc_host/mmc3/mmc3:0001/mmc3:0001:1/uevent"; then + mount -o rw,remount /flash + sed -i "/FDT/c\ FDT /device_trees/rk3566-powkiddy-rgb20sx.dtb" /flash/extlinux/extlinux.conf + reboot +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB30/010-led_control b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB30/010-led_control new file mode 100644 index 0000000000..e54be4fc32 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB30/010-led_control @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/010-led_control +echo 0 > /sys/class/leds/red\:charging/brightness +echo 1 > /sys/class/leds/green\:status/brightness +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB30/020-gpios b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB30/020-gpios new file mode 100755 index 0000000000..357fcb1087 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB30/020-gpios @@ -0,0 +1,15 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/020-gpios +DEVICE_WIFI="0" +DEVICE_PWM_MOTOR="pwmchip1" +EOF + +. /storage/.config/profile.d/020-gpios +# Enable PWM for rumble and turn rumble off during startup. +echo 0 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/export +echo 1000000 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/period +echo 1 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/enable +echo 1000000 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/duty_cycle diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB30/040-display b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB30/040-display new file mode 100755 index 0000000000..efb4451642 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB30/040-display @@ -0,0 +1,17 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +# Configure default contrast saturation and hue values +for PROPERTY in brightness contrast saturation hue +do + MYVAL=$(get_setting display.${PROPERTY}) + if [ -z "${MYVAL}" ] + then + MYVAL=$(drm_tool list | sed -n '/Connector: 133/,$p' | awk '/'${PROPERTY}'/ {print $5}') + fi + paneladj ${PROPERTY} ${MYVAL} +done diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB30/060-game_settings b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB30/060-game_settings new file mode 100755 index 0000000000..d058f2fb42 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RGB30/060-game_settings @@ -0,0 +1,12 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile.d/001-functions + +SETTING=$(get_setting pico-8.integerscale) +if [ -z ${SETTING} ] +then + set_setting pico-8.integerscale 1 +fi + diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RK2023/001-detect-device b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RK2023/001-detect-device new file mode 100755 index 0000000000..2ca2c9c811 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RK2023/001-detect-device @@ -0,0 +1,15 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# this quirk is for the powkiddy rgb20 pro which pk have +# shipped using the rk2023 device tree + +if grep -q "024C:D723" "/sys/devices/platform/fe000000.mmc/mmc_host/mmc3/mmc3:0001/mmc3:0001:1/uevent"; then + if ! grep -q "FDTDIR" /flash/extlinux/extlinux.conf; then + mount -o rw,remount /flash + sed -i '/FDT \/rk3566-powkiddy-rk2023.dtb/c\ FDTDIR /' /flash/extlinux/extlinux.conf + sync + reboot + fi +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RK2023/020-gpios b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RK2023/020-gpios new file mode 100755 index 0000000000..357fcb1087 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RK2023/020-gpios @@ -0,0 +1,15 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/020-gpios +DEVICE_WIFI="0" +DEVICE_PWM_MOTOR="pwmchip1" +EOF + +. /storage/.config/profile.d/020-gpios +# Enable PWM for rumble and turn rumble off during startup. +echo 0 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/export +echo 1000000 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/period +echo 1 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/enable +echo 1000000 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/duty_cycle diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RK2023/040-display b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RK2023/040-display new file mode 100755 index 0000000000..efb4451642 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy RK2023/040-display @@ -0,0 +1,17 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +# Configure default contrast saturation and hue values +for PROPERTY in brightness contrast saturation hue +do + MYVAL=$(get_setting display.${PROPERTY}) + if [ -z "${MYVAL}" ] + then + MYVAL=$(drm_tool list | sed -n '/Connector: 133/,$p' | awk '/'${PROPERTY}'/ {print $5}') + fi + paneladj ${PROPERTY} ${MYVAL} +done diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy x35s b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy x35s new file mode 120000 index 0000000000..11e0fe3199 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy x35s @@ -0,0 +1 @@ +Powkiddy x55 \ No newline at end of file diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy x55/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy x55/001-device_config new file mode 100755 index 0000000000..66857e6df5 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy x55/001-device_config @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/001-device_config +DEVICE_FAKE_JACKSENSE="true" +DEVICE_BATTERY_LED_STATUS="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy x55/010-governors b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy x55/010-governors new file mode 100755 index 0000000000..e1a4622419 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy x55/010-governors @@ -0,0 +1,9 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/010-governors +CPU_FREQ=("/sys/devices/system/cpu/cpufreq/policy0") +GPU_FREQ="/sys/devices/platform/fde60000.gpu/devfreq/fde60000.gpu" +DMC_FREQ="/sys/devices/platform/dmc/devfreq/dmc" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy x55/020-gpios b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy x55/020-gpios new file mode 100755 index 0000000000..357fcb1087 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy x55/020-gpios @@ -0,0 +1,15 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/020-gpios +DEVICE_WIFI="0" +DEVICE_PWM_MOTOR="pwmchip1" +EOF + +. /storage/.config/profile.d/020-gpios +# Enable PWM for rumble and turn rumble off during startup. +echo 0 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/export +echo 1000000 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/period +echo 1 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/enable +echo 1000000 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/duty_cycle diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy x55/040-display b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy x55/040-display new file mode 100755 index 0000000000..75d6f4d1f0 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy x55/040-display @@ -0,0 +1,17 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +# Configure default contrast saturation and hue values +for PROPERTY in brightness contrast saturation hue +do + MYVAL=$(get_setting display.${PROPERTY}) + if [ -z "${MYVAL}" ] + then + MYVAL=$(drm_tool list | sed -n '/Connector: 206/,$p' | awk '/'${PROPERTY}'/ {print $5}') + fi + paneladj ${PROPERTY} ${MYVAL} +done diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy x55/040-hdmi b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy x55/040-hdmi new file mode 100755 index 0000000000..035c9899dd --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy x55/040-hdmi @@ -0,0 +1,20 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +hdmi_con() { + if [ -f "/sys/class/extcon/hdmi/state" ] + then + HDMI="$(cat /sys/class/extcon/hdmi/state)" + if [ "${HDMI}" = "HDMI=1" ] + then + if [ -f "/sys/devices/virtual/graphics/fbcon/rotate" ] + then + echo 0 >/sys/devices/virtual/graphics/fbcon/rotate + fi + fi + fi +} + +### If hdmi is connected, set the framebuffer rotation back to normal. +hdmi_con diff --git a/projects/ArchR/packages/hardware/quirks/devices/Powkiddy x55/sleep.d/README b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy x55/sleep.d/README new file mode 100755 index 0000000000..d4ea16ddf9 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Powkiddy x55/sleep.d/README @@ -0,0 +1 @@ +Sleep quirks are executed before (pre) and after (post) a sleep event occurs. diff --git a/projects/ArchR/packages/hardware/quirks/devices/RetrOLED CM5/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/RetrOLED CM5/001-device_config new file mode 100755 index 0000000000..ea1481fd7c --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/RetrOLED CM5/001-device_config @@ -0,0 +1,17 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/001-device_config +# Device Features +#DEVICE_FAKE_JACKSENSE="true" +#DEVICE_AUDIO_MIXER="DAC" +#DEVICE_PLAYBACK_PATH_SPK="1*" +#DEVICE_PLAYBACK_PATH_HP="0*" +#DEVICE_HEADPHONE_DEV="/dev/input/by-path/platform-wm8960-sound-event" +DEVICE_HAS_TOUCHSCREEN="true" +#DEVICE_BATTERY_LED_STATUS="true" +#DEVICE_PWR_LED_CONTROL="true" + +DEVICE_TEMP_SENSOR=("/sys/devices/virtual/thermal/thermal_zone0/temp" "/sys/devices/virtual/thermal/thermal_zone1/temp") +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/RetrOLED CM5/020-fan_control b/projects/ArchR/packages/hardware/quirks/devices/RetrOLED CM5/020-fan_control new file mode 100644 index 0000000000..1bf812a2ce --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/RetrOLED CM5/020-fan_control @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Enable kernel PWM fan control +echo step_wise > /sys/class/thermal/thermal_zone0/policy + diff --git a/projects/ArchR/packages/hardware/quirks/devices/RetrOLED CM5/020-suspend_mode b/projects/ArchR/packages/hardware/quirks/devices/RetrOLED CM5/020-suspend_mode new file mode 100755 index 0000000000..7bda7aae31 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/RetrOLED CM5/020-suspend_mode @@ -0,0 +1,19 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile.d/001-functions + +MYSLEEPMODE=$(get_setting system.suspendmode) +if [ -z "${MYSLEEPMODE}" ] +then + /usr/bin/suspendmode mem +fi + +# Handle lid key as a signal to shutdown +cat <~/.config/logind.conf.d/login.conf +[Login] +HandlePowerKey=suspend +HandleLidSwitch=poweroff +EOF + diff --git a/projects/ArchR/packages/hardware/quirks/devices/RetrOLED CM5/030-modifiers b/projects/ArchR/packages/hardware/quirks/devices/RetrOLED CM5/030-modifiers new file mode 100644 index 0000000000..4b439b7e6a --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/RetrOLED CM5/030-modifiers @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/050-modifiers +DEVICE_FUNC_KEYA_MODIFIER="BTN_MODE" +DEVICE_FUNC_KEYB_MODIFIER="BTN_START" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/RetrOLED CM5/050-audio_path b/projects/ArchR/packages/hardware/quirks/devices/RetrOLED CM5/050-audio_path new file mode 100755 index 0000000000..aeb8f0df94 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/RetrOLED CM5/050-audio_path @@ -0,0 +1,21 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +SPEAKER=$(pactl list sinks short | grep wm8960 | cut -c 0-2) +pactl set-default-sink ${SPEAKER} + +cat </storage/.config/profile.d/002-audio_path +DEVICE_PLAYBACK_PATH="Playback Mux" +DEFAULT_SINK=${SPEAKER} +EOF + +### Set sound properties +amixer -c 0 -q cset name='Playback Volume' 243,243 +amixer -c 0 -q cset name='Speaker Playback Volume' 127,127 +amixer -c 0 -q cset name='Speaker DC Volume' 5 +amixer -c 0 -q cset name='Speaker AC Volume' 5 +amixer -c 0 -q cset name='Left Output Mixer PCM Playback Switch' on +amixer -c 0 -q cset name='Right Output Mixer PCM Playback Switch' on +amixer -c 0 -q cset name='DAC Polarity' 'Left Inverted' + diff --git a/projects/ArchR/packages/hardware/quirks/devices/RetrOLED CM5/sleep.d/post/001-audio b/projects/ArchR/packages/hardware/quirks/devices/RetrOLED CM5/sleep.d/post/001-audio new file mode 100755 index 0000000000..15101c8584 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/RetrOLED CM5/sleep.d/post/001-audio @@ -0,0 +1,30 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Workaround for no audio on wake from sleep. + +. /etc/profile + +HDMI=$(pactl list sinks short | grep hdmi | cut -c 0-2) +SPEAKER=$(pactl list sinks short | grep wm8960 | cut -c 0-2) + +#Set sink to one we aren't currently using +pactl set-default-sink ${SPEAKER} + +#Then check if HDMI is plugged and switch to HDMI + +# Set export GPIO for HDMI +if [ ! -d "/sys/class/gpio/gpio${DEVICE_HDMI_GPIO}" ]; then + echo ${DEVICE_HDMI_GPIO} > /sys/class/gpio/export + echo in > /sys/class/gpio/gpio${DEVICE_HDMI_GPIO}/direction +fi + +# Check HDMI plug state and switch to HDMI audo if true +HDMI_VALUE=$(cat /sys/class/gpio/gpio${DEVICE_HDMI_GPIO}/value) + case ${HDMI_VALUE} in + "0") + sleep 11 + pactl set-default-sink ${HDMI} + ;; + esac diff --git a/projects/ArchR/packages/hardware/quirks/devices/RetrOLED CM5/sleep.d/post/002-freq b/projects/ArchR/packages/hardware/quirks/devices/RetrOLED CM5/sleep.d/post/002-freq new file mode 100755 index 0000000000..3d94601970 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/RetrOLED CM5/sleep.d/post/002-freq @@ -0,0 +1,22 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +### Restore previous governors before going to sleep + +. /etc/profile + +### Grab the old governors. +OLD_CPU_FREQ=$(get_setting "sleep.cpugovernor") +if [ ! -n "${OLD_CPU_FREQ}" ]; then + OLD_CPU_FREQ="schedutil" +fi + +OLD_GPU_FREQ=$(get_setting "sleep.gpugovernor") +if [ ! -n "${OLD_GPU_FREQ}" ]; then + OLD_GPU_FREQ="simple_ondemand" +fi + +# Restore old governors. +set_cpu_gov "${OLD_CPU_FREQ}" +set_gpu_gov "${OLD_GPU_FREQ}" diff --git a/projects/ArchR/packages/hardware/quirks/devices/RetrOLED CM5/sleep.d/pre/002-freq b/projects/ArchR/packages/hardware/quirks/devices/RetrOLED CM5/sleep.d/pre/002-freq new file mode 100755 index 0000000000..6d0fc291dc --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/RetrOLED CM5/sleep.d/pre/002-freq @@ -0,0 +1,18 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Store current freq governors and set governors to powersave. + +. /etc/profile + +### Get the current cpu and gpu governor, save for when the device wakes from sleep. +CUR_CPU_FREQ="$(cat ${CPU_FREQ}/scaling_governor)" +CUR_GPU_FREQ="$(cat ${GPU_FREQ}/governor)" + +set_setting sleep.cpugovernor "${CUR_CPU_FREQ}" +set_setting sleep.gpugovernor "${CUR_GPU_FREQ}" + +### Set all governors to powersave +set_cpu_gov powersave +set_gpu_gov powersave diff --git a/projects/ArchR/packages/hardware/quirks/devices/Retro Lite CM5/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/Retro Lite CM5/001-device_config new file mode 100755 index 0000000000..ea1481fd7c --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Retro Lite CM5/001-device_config @@ -0,0 +1,17 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/001-device_config +# Device Features +#DEVICE_FAKE_JACKSENSE="true" +#DEVICE_AUDIO_MIXER="DAC" +#DEVICE_PLAYBACK_PATH_SPK="1*" +#DEVICE_PLAYBACK_PATH_HP="0*" +#DEVICE_HEADPHONE_DEV="/dev/input/by-path/platform-wm8960-sound-event" +DEVICE_HAS_TOUCHSCREEN="true" +#DEVICE_BATTERY_LED_STATUS="true" +#DEVICE_PWR_LED_CONTROL="true" + +DEVICE_TEMP_SENSOR=("/sys/devices/virtual/thermal/thermal_zone0/temp" "/sys/devices/virtual/thermal/thermal_zone1/temp") +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Retro Lite CM5/020-fan_control b/projects/ArchR/packages/hardware/quirks/devices/Retro Lite CM5/020-fan_control new file mode 100644 index 0000000000..1bf812a2ce --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Retro Lite CM5/020-fan_control @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Enable kernel PWM fan control +echo step_wise > /sys/class/thermal/thermal_zone0/policy + diff --git a/projects/ArchR/packages/hardware/quirks/devices/Retro Lite CM5/020-suspend_mode b/projects/ArchR/packages/hardware/quirks/devices/Retro Lite CM5/020-suspend_mode new file mode 100755 index 0000000000..7bda7aae31 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Retro Lite CM5/020-suspend_mode @@ -0,0 +1,19 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile.d/001-functions + +MYSLEEPMODE=$(get_setting system.suspendmode) +if [ -z "${MYSLEEPMODE}" ] +then + /usr/bin/suspendmode mem +fi + +# Handle lid key as a signal to shutdown +cat <~/.config/logind.conf.d/login.conf +[Login] +HandlePowerKey=suspend +HandleLidSwitch=poweroff +EOF + diff --git a/projects/ArchR/packages/hardware/quirks/devices/Retro Lite CM5/030-modifiers b/projects/ArchR/packages/hardware/quirks/devices/Retro Lite CM5/030-modifiers new file mode 100644 index 0000000000..adf2be4df1 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Retro Lite CM5/030-modifiers @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/050-modifiers +DEVICE_FUNC_KEYA_MODIFIER="BTN_MODE" +DEVICE_FUNC_KEYB_MODIFIER="BTN_START" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Retro Lite CM5/050-audio_path b/projects/ArchR/packages/hardware/quirks/devices/Retro Lite CM5/050-audio_path new file mode 100755 index 0000000000..aeb8f0df94 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Retro Lite CM5/050-audio_path @@ -0,0 +1,21 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +SPEAKER=$(pactl list sinks short | grep wm8960 | cut -c 0-2) +pactl set-default-sink ${SPEAKER} + +cat </storage/.config/profile.d/002-audio_path +DEVICE_PLAYBACK_PATH="Playback Mux" +DEFAULT_SINK=${SPEAKER} +EOF + +### Set sound properties +amixer -c 0 -q cset name='Playback Volume' 243,243 +amixer -c 0 -q cset name='Speaker Playback Volume' 127,127 +amixer -c 0 -q cset name='Speaker DC Volume' 5 +amixer -c 0 -q cset name='Speaker AC Volume' 5 +amixer -c 0 -q cset name='Left Output Mixer PCM Playback Switch' on +amixer -c 0 -q cset name='Right Output Mixer PCM Playback Switch' on +amixer -c 0 -q cset name='DAC Polarity' 'Left Inverted' + diff --git a/projects/ArchR/packages/hardware/quirks/devices/Retro Lite CM5/sleep.d/post/001-audio b/projects/ArchR/packages/hardware/quirks/devices/Retro Lite CM5/sleep.d/post/001-audio new file mode 100755 index 0000000000..15101c8584 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Retro Lite CM5/sleep.d/post/001-audio @@ -0,0 +1,30 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Workaround for no audio on wake from sleep. + +. /etc/profile + +HDMI=$(pactl list sinks short | grep hdmi | cut -c 0-2) +SPEAKER=$(pactl list sinks short | grep wm8960 | cut -c 0-2) + +#Set sink to one we aren't currently using +pactl set-default-sink ${SPEAKER} + +#Then check if HDMI is plugged and switch to HDMI + +# Set export GPIO for HDMI +if [ ! -d "/sys/class/gpio/gpio${DEVICE_HDMI_GPIO}" ]; then + echo ${DEVICE_HDMI_GPIO} > /sys/class/gpio/export + echo in > /sys/class/gpio/gpio${DEVICE_HDMI_GPIO}/direction +fi + +# Check HDMI plug state and switch to HDMI audo if true +HDMI_VALUE=$(cat /sys/class/gpio/gpio${DEVICE_HDMI_GPIO}/value) + case ${HDMI_VALUE} in + "0") + sleep 11 + pactl set-default-sink ${HDMI} + ;; + esac diff --git a/projects/ArchR/packages/hardware/quirks/devices/Retro Lite CM5/sleep.d/post/002-freq b/projects/ArchR/packages/hardware/quirks/devices/Retro Lite CM5/sleep.d/post/002-freq new file mode 100755 index 0000000000..3d94601970 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Retro Lite CM5/sleep.d/post/002-freq @@ -0,0 +1,22 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +### Restore previous governors before going to sleep + +. /etc/profile + +### Grab the old governors. +OLD_CPU_FREQ=$(get_setting "sleep.cpugovernor") +if [ ! -n "${OLD_CPU_FREQ}" ]; then + OLD_CPU_FREQ="schedutil" +fi + +OLD_GPU_FREQ=$(get_setting "sleep.gpugovernor") +if [ ! -n "${OLD_GPU_FREQ}" ]; then + OLD_GPU_FREQ="simple_ondemand" +fi + +# Restore old governors. +set_cpu_gov "${OLD_CPU_FREQ}" +set_gpu_gov "${OLD_GPU_FREQ}" diff --git a/projects/ArchR/packages/hardware/quirks/devices/Retro Lite CM5/sleep.d/pre/002-freq b/projects/ArchR/packages/hardware/quirks/devices/Retro Lite CM5/sleep.d/pre/002-freq new file mode 100755 index 0000000000..6d0fc291dc --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Retro Lite CM5/sleep.d/pre/002-freq @@ -0,0 +1,18 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Store current freq governors and set governors to powersave. + +. /etc/profile + +### Get the current cpu and gpu governor, save for when the device wakes from sleep. +CUR_CPU_FREQ="$(cat ${CPU_FREQ}/scaling_governor)" +CUR_GPU_FREQ="$(cat ${GPU_FREQ}/governor)" + +set_setting sleep.cpugovernor "${CUR_CPU_FREQ}" +set_setting sleep.gpugovernor "${CUR_GPU_FREQ}" + +### Set all governors to powersave +set_cpu_gov powersave +set_gpu_gov powersave diff --git a/projects/ArchR/packages/hardware/quirks/devices/Retroid Pocket 5/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/Retroid Pocket 5/001-device_config new file mode 100644 index 0000000000..7ffbe1730f --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Retroid Pocket 5/001-device_config @@ -0,0 +1,10 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/001-device_config +# Device Features +DEVICE_HAS_TOUCHSCREEN="true" +DEVICE_GPU_OVERCLOCK="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Retroid Pocket 5/050-game-configs b/projects/ArchR/packages/hardware/quirks/devices/Retroid Pocket 5/050-game-configs new file mode 100644 index 0000000000..cdec8122e9 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Retroid Pocket 5/050-game-configs @@ -0,0 +1,11 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +#Set Supermodel resolution for the mini +sed -i '/^XResolution =/c\XResolution = 1920' /storage/.config/supermodel/Config/Supermodel.ini +sed -i '/^YResolution =/c\YResolution = 1080' /storage/.config/supermodel/Config/Supermodel.ini + +#Disable retroarch microphone and set default audio driver to pulse +sed -i '/^microphone_enable =/c\microphone_enable = "false"' /storage/.config/retroarch/retroarch.cfg +sed -i '/^audio_driver =/c\audio_driver = "pulse"' /storage/.config/retroarch/retroarch.cfg diff --git a/projects/ArchR/packages/hardware/quirks/devices/Retroid Pocket 6 TOP-DPAD b/projects/ArchR/packages/hardware/quirks/devices/Retroid Pocket 6 TOP-DPAD new file mode 120000 index 0000000000..d756c7a30a --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Retroid Pocket 6 TOP-DPAD @@ -0,0 +1 @@ +Retroid Pocket 6 \ No newline at end of file diff --git a/projects/ArchR/packages/hardware/quirks/devices/Retroid Pocket 6/009-commander-cfg b/projects/ArchR/packages/hardware/quirks/devices/Retroid Pocket 6/009-commander-cfg new file mode 100644 index 0000000000..044bb46732 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Retroid Pocket 6/009-commander-cfg @@ -0,0 +1,11 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +if [ ! -f "/storage/.config/commander.cfg" ]; then +cat </storage/.config/commander.cfg +disp_ppu_x=4 +disp_ppu_y=4 +EOF +fi diff --git a/projects/ArchR/packages/hardware/quirks/devices/Retroid Pocket 6/bin/analog_sticks_ledcontrol b/projects/ArchR/packages/hardware/quirks/devices/Retroid Pocket 6/bin/analog_sticks_ledcontrol new file mode 100644 index 0000000000..d848333528 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Retroid Pocket 6/bin/analog_sticks_ledcontrol @@ -0,0 +1,45 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +# Simple script to set led brightness and rgb color based on +# brightness and rgb values from emulation station + +LED_PATH="/sys/devices/platform/" + +function led_brightness() { + n=1 + while [ "$n" -lt 4 ]; do + echo ${2} > ${LED_PATH}/multi-led${1}${n}/leds/rgb:${1}${n}/brightness + n=$(( n + 1 )) + done +} + +function led_rgb() { + n=1 + while [ "$n" -lt 4 ]; do + echo ${2} ${3} ${4} > ${LED_PATH}/multi-led${1}${n}/leds/rgb:${1}${n}/multi_intensity + n=$(( n + 1 )) + done +} + +# Display usage if no parameters are provided +if [ $# -ne 7 ]; then + echo "Usage: $0 " + echo "Example: $0 255 255 0 0 0 0 255" + exit 1 +fi + +BRIGHTNESS=$1 +RIGHT_RED=$2 +RIGHT_GREEN=$3 +RIGHT_BLUE=$4 +LEFT_RED=$5 +LEFT_GREEN=$6 +LEFT_BLUE=$7 + +led_brightness l $BRIGHTNESS +led_rgb l $LEFT_BLUE $LEFT_GREEN $LEFT_RED +led_brightness r $BRIGHTNESS +led_rgb r $RIGHT_BLUE $RIGHT_GREEN $RIGHT_RED diff --git a/projects/ArchR/packages/hardware/quirks/devices/Retroid Pocket 6/bin/battery_led_status b/projects/ArchR/packages/hardware/quirks/devices/Retroid Pocket 6/bin/battery_led_status new file mode 100644 index 0000000000..09f5a20f73 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Retroid Pocket 6/bin/battery_led_status @@ -0,0 +1,128 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Simple script to watch the battery capacity and +# turn the power LED orange when it reaches 30%, red at 20%, and blinking red at 10% + +. /etc/profile + +LED_PATH="/sys/devices/platform/" + +function bat_led_off() { + n=1 + while [ "$n" -lt 4 ]; do + echo 0 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/brightness + echo 0 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/brightness + echo 0 0 0 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/multi_intensity + echo 0 0 0 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/multi_intensity + n=$(( n + 1 )) + done +} + +function bat_led_red() { + n=1 + while [ "$n" -lt 4 ]; do + echo 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/brightness + echo 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/brightness + echo 0 0 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/multi_intensity + echo 0 0 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/multi_intensity + n=$(( n + 1 )) + done +} + +function bat_led_green() { + n=1 + while [ "$n" -lt 4 ]; do + echo 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/brightness + echo 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/brightness + echo 0 255 0 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/multi_intensity + echo 0 255 0 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/multi_intensity + n=$(( n + 1 )) + done +} + +function bat_led_orange() { + n=1 + while [ "$n" -lt 4 ]; do + echo 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/brightness + echo 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/brightness + echo 0 20 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/multi_intensity + echo 0 20 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/multi_intensity + n=$(( n + 1 )) + done +} + +function bat_led_yellow() { + n=1 + while [ "$n" -lt 4 ]; do + echo 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/brightness + echo 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/brightness + echo 0 125 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/multi_intensity + echo 0 125 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/multi_intensity + n=$(( n + 1 )) + done +} + +PREV_BATCAP="null" +while true + do + BAT_LED_STATE=$(get_setting led.color) + if [ ! ${BAT_LED_STATE} == "battery" ]; then + break + else + CAP=$(cat /sys/class/power_supply/battery/capacity) + STAT=$(cat /sys/class/power_supply/battery/status) + if [ ${STAT} == "Discharging" ]; then + if (( ${CAP} <= 10 )) + then + for ctr in $(seq 1 1 5) + do + bat_led_red + sleep .5 + bat_led_off + sleep .5 + done + continue + elif (( ${CAP} <= 20 )) + then + BATCAP="D_RED" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_red + fi + elif (( ${CAP} <= 30 )) + then + BATCAP="D_ORANGE" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_orange + fi + elif (( ${CAP} <= 40 )) + then + BATCAP="D_YELLOW" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_yellow + fi + else + BATCAP="D_GREEN" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_green + fi + fi + elif (( ${CAP} <= 94 )) + then + BATCAP="C_ORANGE" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_orange + fi + elif (( ${CAP} >= 95 )) + then + BATCAP="C_GREEN" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_green + fi + fi + PREV_BATCAP=${BATCAP} + sleep 15 + fi +done diff --git a/projects/ArchR/packages/hardware/quirks/devices/Retroid Pocket 6/bin/ledcontrol b/projects/ArchR/packages/hardware/quirks/devices/Retroid Pocket 6/bin/ledcontrol new file mode 100644 index 0000000000..8726843fc9 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Retroid Pocket 6/bin/ledcontrol @@ -0,0 +1,45 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile + +LED_PATH="/sys/devices/platform/" + +function led_off() { + n=1 + while [ "$n" -lt 4 ]; do + echo 0 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/brightness + echo 0 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/brightness + echo 0 0 0 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/multi_intensity + echo 0 0 0 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/multi_intensity + n=$(( n + 1 )) + done +} + +case ${1} in + off) + led_off + set_setting led.color ${1} + ;; + rgb) + LEDS_CONFIG=$(get_setting analogsticks.led) + /usr/bin/analog_sticks_ledcontrol ${LEDS_CONFIG} + set_setting led.color ${1} + ;; + battery) + led_off + set_setting led.color ${1} + systemctl restart batteryledstatus.service + ;; + poweroff) + led_off + ;; + list) +cat </storage/.config/profile.d/001-device_config +# Device Features +DEVICE_HAS_TOUCHSCREEN="true" +DEVICE_ASPECT_RATIO="4:3" +DEVICE_GPU_OVERCLOCK="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/devices/Retroid Pocket Mini/050-game-configs b/projects/ArchR/packages/hardware/quirks/devices/Retroid Pocket Mini/050-game-configs new file mode 100644 index 0000000000..182573be62 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/devices/Retroid Pocket Mini/050-game-configs @@ -0,0 +1,11 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +#Set Supermodel resolution for the mini +sed -i '/^XResolution =/c\XResolution = 1280' /storage/.config/supermodel/Config/Supermodel.ini +sed -i '/^YResolution =/c\YResolution = 960' /storage/.config/supermodel/Config/Supermodel.ini + +#Disable retroarch microphone and set default audio driver to pulse +sed -i '/^microphone_enable =/c\microphone_enable = "false"' /storage/.config/retroarch/retroarch.cfg +sed -i '/^audio_driver =/c\audio_driver = "pulse"' /storage/.config/retroarch/retroarch.cfg diff --git a/projects/ArchR/packages/hardware/quirks/package.mk b/projects/ArchR/packages/hardware/quirks/package.mk new file mode 100644 index 0000000000..61919ea673 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/package.mk @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="quirks" +PKG_VERSION="" +PKG_LICENSE="GPLv2" +PKG_SITE="" +PKG_URL="" +PKG_DEPENDS_TARGET="toolchain autostart" +PKG_LONGDESC="Quirks is a simple package that provides device quirks." +PKG_TOOLCHAIN="manual" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/autostart/quirks/{platforms,devices} + cp -r ${PKG_DIR}/devices/* ${INSTALL}/usr/lib/autostart/quirks/devices + if [ -d "${PKG_DIR}/platforms/${DEVICE}" ] + then + cp -r ${PKG_DIR}/platforms/* ${INSTALL}/usr/lib/autostart/quirks/platforms + fi + chmod -R 0755 ${INSTALL}/usr/lib/autostart/quirks +} + +post_install() { + enable_service led-poweroff.service + if [ "${DEVICE}" = "RK3566" ] + then + enable_service volume-fixup.service + fi +} diff --git a/projects/ArchR/packages/hardware/quirks/platforms/H700/001-device_config b/projects/ArchR/packages/hardware/quirks/platforms/H700/001-device_config new file mode 100755 index 0000000000..a578b05dbd --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/H700/001-device_config @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: Apache-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/001-device_config +DEVICE_TEMP_SENSOR="/sys/devices/virtual/thermal/thermal_zone2/temp" +DEVICE_GPU_OVERCLOCK="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/H700/002-turbo-mode_config b/projects/ArchR/packages/hardware/quirks/platforms/H700/002-turbo-mode_config new file mode 100755 index 0000000000..f1b68db2fe --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/H700/002-turbo-mode_config @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/002-turbo-mode_config +DEVICE_TURBO_MODE="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/H700/010-governors b/projects/ArchR/packages/hardware/quirks/platforms/H700/010-governors new file mode 100755 index 0000000000..45631b7be2 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/H700/010-governors @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/010-governors +CPU_FREQ=("/sys/devices/system/cpu/cpufreq/policy0") +GPU_FREQ=("/sys/devices/platform/soc/1800000.gpu/devfreq/1800000.gpu") +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/H700/010-led_control b/projects/ArchR/packages/hardware/quirks/platforms/H700/010-led_control new file mode 100755 index 0000000000..9196367dd3 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/H700/010-led_control @@ -0,0 +1,9 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/010-led_control +DEVICE_LED_CONTROL="true" +DEVICE_LED_BRIGHTNESS="false" +DEVICE_LED_CHARGING="false" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/H700/020-fan_control b/projects/ArchR/packages/hardware/quirks/platforms/H700/020-fan_control new file mode 100755 index 0000000000..eb4ddf9a9c --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/H700/020-fan_control @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/020-fan_control +DEVICE_HAS_FAN="false" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/H700/020-set_audio_latency b/projects/ArchR/packages/hardware/quirks/platforms/H700/020-set_audio_latency new file mode 100755 index 0000000000..c116a85f79 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/H700/020-set_audio_latency @@ -0,0 +1,11 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile.d/001-functions + +AUDIO_LATENCY=$(get_setting audiolatency) +if [ -z "${AUDIO_LATENCY}" ] +then + set_setting global.audiolatency 64 +fi diff --git a/projects/ArchR/packages/hardware/quirks/platforms/H700/030-analog_leds b/projects/ArchR/packages/hardware/quirks/platforms/H700/030-analog_leds new file mode 100755 index 0000000000..786cf5eff3 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/H700/030-analog_leds @@ -0,0 +1,13 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile.d/001-functions + +if [ $DEVICE_ANALOG_STICKS_LED_CONTROL == "true" ]; then + LEDS_CONFIG=$(get_setting analogsticks.led) + + if [ ! -z "${LEDS_CONFIG}" ]; then + /usr/bin/analog_sticks_ledcontrol $LEDS_CONFIG + fi +fi diff --git a/projects/ArchR/packages/hardware/quirks/platforms/H700/030-suspend_mode b/projects/ArchR/packages/hardware/quirks/platforms/H700/030-suspend_mode new file mode 100755 index 0000000000..4f773ea554 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/H700/030-suspend_mode @@ -0,0 +1,14 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +### Sleep is currently broken, so we'll disable it. + +/usr/bin/suspendmode off + +### Ignore power button presses for now, until we can finish up fixing sleep. +cat <~/.config/logind.conf.d/login.conf +[Login] +HandlePowerKey=ignore +HandleSuspendKey=ignore +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/H700/050-modifiers b/projects/ArchR/packages/hardware/quirks/platforms/H700/050-modifiers new file mode 100755 index 0000000000..922b60300d --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/H700/050-modifiers @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/050-modifiers +DEVICE_FUNC_KEYA_MODIFIER="BTN_MODE" +DEVICE_FUNC_KEYB_MODIFIER="BTN_START" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/H700/060-game_settings b/projects/ArchR/packages/hardware/quirks/platforms/H700/060-game_settings new file mode 100755 index 0000000000..f34ca69bd1 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/H700/060-game_settings @@ -0,0 +1,34 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile.d/001-functions + +### Set the default performance scaling mode for a few systems. +for SYSTEM in dreamcast n64 ports psp psx saturn gba pcfx cdi neogeo fbneo snes sfc +do + CPU_SETTING=$(get_setting ${SYSTEM}.cpugovernor) + if [ -z "${CPU_SETTING}" ] + then + set_setting ${SYSTEM}.cpugovernor performance + fi + GPU_SETTING=$(get_setting ${SYSTEM}.gpuperf) + if [ -z "${GPU_SETTING}" ] + then + set_setting ${SYSTEM}.gpuperf profile_peak + fi +done + +for SYSTEM in gb gbc nes famicom sms gamegear genesis mastersystem sega32x megadrive segacd megacd +do + CPU_SETTING=$(get_setting ${SYSTEM}.cpugovernor) + if [ -z ${CPU_SETTING} ] + then + set_setting ${SYSTEM}.cpugovernor powersave + fi + GPU_SETTING=$(get_setting ${SYSTEM}.gpuperf) + if [ -z ${GPU_SETTING} ] + then + set_setting ${SYSTEM}.gpuperf low + fi +done diff --git a/projects/ArchR/packages/hardware/quirks/platforms/H700/090-ui_service b/projects/ArchR/packages/hardware/quirks/platforms/H700/090-ui_service new file mode 100755 index 0000000000..b2f472a2ee --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/H700/090-ui_service @@ -0,0 +1,9 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +### Set the default device configuration +cat </storage/.config/profile.d/090-ui_service +UI_SERVICE="sway.service essway.service" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/H700/091-ui_shader b/projects/ArchR/packages/hardware/quirks/platforms/H700/091-ui_shader new file mode 100755 index 0000000000..d087007a42 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/H700/091-ui_shader @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +### Set the default device configuration +cat </storage/.config/profile.d/091-ui_shader +UI_SHADER="slangp" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/H700/400-set_gpu_overclock b/projects/ArchR/packages/hardware/quirks/platforms/H700/400-set_gpu_overclock new file mode 100755 index 0000000000..fcc70362ee --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/H700/400-set_gpu_overclock @@ -0,0 +1,22 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +# Get GPU overclock state +GPU_OC_STATE=$(get_setting "enable.gpu-overclock") +if [ ! -n "${GPU_OC_STATE}" ]; then + GPU_OC_STATE="disable" + set_setting "enable.gpu-overclock" "0" +elif [ "${GPU_OC_STATE}" = 1 ]; then + GPU_OC_STATE="enable" +else + GPU_OC_STATE="disable" + set_setting "enable.gpu-overclock" "0" +fi + +# Set GPU OC state +/usr/lib/autostart/quirks/platforms/H700/bin/gpu_overclock ${GPU_OC_STATE} diff --git a/projects/ArchR/packages/hardware/quirks/platforms/H700/bin/analog_sticks_ledcontrol b/projects/ArchR/packages/hardware/quirks/platforms/H700/bin/analog_sticks_ledcontrol new file mode 100755 index 0000000000..26e1ca511a --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/H700/bin/analog_sticks_ledcontrol @@ -0,0 +1,73 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Simple script to watch the battery capacity and +# turn the power LED orange when it reaches 30%, red at 20%, and blinking red at 10% + +# Define the serial device +SERIAL_DEVICE="/dev/ttyS2" +LED_PATH="/sys/class/leds" + +function led_state() { + echo ${2} >${LED_PATH}/${1}/brightness +} + +# Display usage if no parameters are provided +if [ $# -ne 7 ]; then + echo "Usage: $0 " + echo "Example: $0 255 255 0 0 0 0 255" + exit 1 +fi + +LED_MODE=1 +BRIGHTNESS=$1 +RIGHT_RED=$2 +RIGHT_GREEN=$3 +RIGHT_BLUE=$4 +LEFT_RED=$5 +LEFT_GREEN=$6 +LEFT_BLUE=$7 + +# Function to calculate checksum +calculate_checksum() { + local sum=0 + for byte in "$@"; do + sum=$((sum + byte)) + done + echo $((sum & 0xFF)) +} + +# Open the serial device +exec 20<>$SERIAL_DEVICE +stty -F $SERIAL_DEVICE 115200 -opost -isig -icanon -echo + +# Enable RGB LEDs +led_state rgb:kbd_backlight 1 + +# Construct the payload +PAYLOAD=$(printf '\\x%02X\\x%02X' $LED_MODE $BRIGHTNESS) +for ((i = 0; i < 8; i++)); do + PAYLOAD+=$(printf '\\x%02X\\x%02X\\x%02X' $RIGHT_RED $RIGHT_GREEN $RIGHT_BLUE) +done +for ((i = 0; i < 8; i++)); do + PAYLOAD+=$(printf '\\x%02X\\x%02X\\x%02X' $LEFT_RED $LEFT_GREEN $LEFT_BLUE) +done + +# Calculate checksum for the payload +PAYLOAD_BYTES=($LED_MODE $BRIGHTNESS) +for ((i = 0; i < 8; i++)); do + PAYLOAD_BYTES+=($RIGHT_RED $RIGHT_GREEN $RIGHT_BLUE) +done +for ((i = 0; i < 8; i++)); do + PAYLOAD_BYTES+=($LEFT_RED $LEFT_GREEN $LEFT_BLUE) +done +CHECKSUM=$(calculate_checksum "${PAYLOAD_BYTES[@]}") +PAYLOAD+=$(printf '\\x%02X' $CHECKSUM) + +# Send the payload +echo -e -n "$PAYLOAD" > $SERIAL_DEVICE + +# Close the serial device +exec 20>&- diff --git a/projects/ArchR/packages/hardware/quirks/platforms/H700/bin/gpu_overclock b/projects/ArchR/packages/hardware/quirks/platforms/H700/bin/gpu_overclock new file mode 100755 index 0000000000..16fc152d52 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/H700/bin/gpu_overclock @@ -0,0 +1,22 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +if [ -z "${GPU_FREQ}" ]; then + . /etc/profile +fi + +# Set max gpu freq +case $1 in + disable) + echo 600000000 > $GPU_FREQ/max_freq + set_setting enable.gpu-overclock 0 + ;; + enable) + echo 648000000 > $GPU_FREQ/max_freq + set_setting enable.gpu-overclock 1 + ;; +esac diff --git a/projects/ArchR/packages/hardware/quirks/platforms/H700/bin/ledcontrol b/projects/ArchR/packages/hardware/quirks/platforms/H700/bin/ledcontrol new file mode 100755 index 0000000000..3a55583605 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/H700/bin/ledcontrol @@ -0,0 +1,68 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 JELOS (https://github.com/JustEnoughLinuxOS) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +LED_PATH="/sys/class/leds" + +function led_state() { + echo ${2} >${LED_PATH}/${1}/brightness +} + +function led_off() { + led_state green\:power 0 + led_state red\:status 0 +} + +function led_red() { + led_off + led_state red\:status 1 +} + +function led_green() { + led_off + led_state green\:power 1 +} + +case ${1} in + green) + led_green + set_setting led.color ${1} + ;; + red) + led_red + set_setting led.color ${1} + ;; + off) + led_off + set_setting led.color ${1} + ;; + default) + del_setting led.color + led_green + ;; + brightness) + set_setting led.brightness ${2} + ledcontrol $(get_setting led.color) + ;; + poweroff) + led_off + ;; + list) +cat < /sys/devices/system/cpu/cpu1/online +echo 1 > /sys/devices/system/cpu/cpu2/online +echo 1 > /sys/devices/system/cpu/cpu3/online diff --git a/projects/ArchR/packages/hardware/quirks/platforms/H700/sleep.d/post/002-freq b/projects/ArchR/packages/hardware/quirks/platforms/H700/sleep.d/post/002-freq new file mode 100755 index 0000000000..cfd244ad7e --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/H700/sleep.d/post/002-freq @@ -0,0 +1,22 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +### Restore previous governors before going to sleep + +. /etc/profile + +### Grab the old governors. +OLD_CPU_FREQ=$(get_setting "sleep.cpugovernor") +if [ ! -n "${OLD_CPU_FREQ}" ]; then + OLD_CPU_FREQ="ondemand" +fi + +OLD_GPU_FREQ=$(get_setting "sleep.gpugovernor") +if [ ! -n "${OLD_GPU_FREQ}" ]; then + OLD_GPU_FREQ="simple_ondemand" +fi + +# Restore old governors. +set_cpu_gov "${OLD_CPU_FREQ}" +set_gpu_gov "${OLD_GPU_FREQ}" diff --git a/projects/ArchR/packages/hardware/quirks/platforms/H700/sleep.d/post/003-codec b/projects/ArchR/packages/hardware/quirks/platforms/H700/sleep.d/post/003-codec new file mode 100755 index 0000000000..f4d32bd153 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/H700/sleep.d/post/003-codec @@ -0,0 +1,9 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Unmute DAC + +. /etc/profile + +amixer -c0 sset DAC on diff --git a/projects/ArchR/packages/hardware/quirks/platforms/H700/sleep.d/pre/001-cpu b/projects/ArchR/packages/hardware/quirks/platforms/H700/sleep.d/pre/001-cpu new file mode 100755 index 0000000000..262c4028e2 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/H700/sleep.d/pre/001-cpu @@ -0,0 +1,11 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Keep only one cpu online + +. /etc/profile + +echo 0 > /sys/devices/system/cpu/cpu1/online +echo 0 > /sys/devices/system/cpu/cpu2/online +echo 0 > /sys/devices/system/cpu/cpu3/online diff --git a/projects/ArchR/packages/hardware/quirks/platforms/H700/sleep.d/pre/002-freq b/projects/ArchR/packages/hardware/quirks/platforms/H700/sleep.d/pre/002-freq new file mode 100755 index 0000000000..a1c235ca32 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/H700/sleep.d/pre/002-freq @@ -0,0 +1,18 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Store current freq governors and set governors to powersave. + +. /etc/profile + +### Get the current cpu and gpu governor, save for when the device wakes from sleep. +CUR_CPU_FREQ="$(cat ${CPU_FREQ}/scaling_governor)" +CUR_GPU_FREQ="$(cat ${GPU_FREQ}/governor)" + +set_setting sleep.cpugovernor "${CUR_CPU_FREQ}" +set_setting sleep.gpugovernor "${CUR_GPU_FREQ}" + +### Set all governors to powersave +set_cpu_gov powersave +set_gpu_gov powersave diff --git a/projects/ArchR/packages/hardware/quirks/platforms/H700/sleep.d/pre/003-codec b/projects/ArchR/packages/hardware/quirks/platforms/H700/sleep.d/pre/003-codec new file mode 100755 index 0000000000..171624b888 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/H700/sleep.d/pre/003-codec @@ -0,0 +1,9 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Mute DAC + +. /etc/profile + +amixer -c0 sset DAC off diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3326/002-turbo-mode_config b/projects/ArchR/packages/hardware/quirks/platforms/RK3326/002-turbo-mode_config new file mode 100755 index 0000000000..f1b68db2fe --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3326/002-turbo-mode_config @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/002-turbo-mode_config +DEVICE_TURBO_MODE="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3326/010-governors b/projects/ArchR/packages/hardware/quirks/platforms/RK3326/010-governors new file mode 100755 index 0000000000..0686b336a4 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3326/010-governors @@ -0,0 +1,9 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/010-governors +CPU_FREQ=("/sys/devices/system/cpu/cpufreq/policy0") +GPU_FREQ=("/sys/devices/platform/ff400000.gpu/devfreq/ff400000.gpu") +DMC_FREQ=("/sys/devices/platform/dmc/devfreq/dmc") +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3326/050-audio_path b/projects/ArchR/packages/hardware/quirks/platforms/RK3326/050-audio_path new file mode 100755 index 0000000000..0e619c4e52 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3326/050-audio_path @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/002-audio_path +DEVICE_PLAYBACK_PATH="Playback Mux" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3326/050-modifiers b/projects/ArchR/packages/hardware/quirks/platforms/RK3326/050-modifiers new file mode 100755 index 0000000000..8c0961439c --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3326/050-modifiers @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/050-modifiers +DEVICE_FUNC_KEYA_MODIFIER="BTN_SELECT" +DEVICE_FUNC_KEYB_MODIFIER="BTN_START" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3326/060-game_settings b/projects/ArchR/packages/hardware/quirks/platforms/RK3326/060-game_settings new file mode 100755 index 0000000000..0a4c09c431 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3326/060-game_settings @@ -0,0 +1,23 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile.d/001-functions + +### Set the default performance scaling mode for a few systems. +for SYSTEM in dreamcast n64 ports psp psx saturn gba pcfx cdi +do + CPU_SETTING=$(get_setting ${SYSTEM}.cpugovernor) + if [ -z "${CPU_SETTING}" ] + then + set_setting ${SYSTEM}.cpugovernor performance + fi + GPU_SETTING=$(get_setting ${SYSTEM}.gpuperf) + if [ -z "${GPU_SETTING}" ] + then + set_setting ${SYSTEM}.gpuperf profile_peak + fi +done + +# Need to set RA video driver to GL for libmali driver. +sed -i '/video_driver =/c\video_driver = "gl"' /storage/.config/retroarch/retroarch.cfg diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3326/075-mangohud-supported b/projects/ArchR/packages/hardware/quirks/platforms/RK3326/075-mangohud-supported new file mode 100644 index 0000000000..99363338f8 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3326/075-mangohud-supported @@ -0,0 +1,25 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile + +GPUDRIVER=$(/usr/bin/gpudriver) +MANGOHUD_ENABLED=$(get_setting "archr.mangohud.enabled") + +# Init setting to 'disabled' +if [ ! -n "${MANGOHUD_ENABLED}" ]; then + set_setting "archr.mangohud.enabled" "0" +fi + +# Enable / disable MangoHud support (panfrost / libmali) +if [ "${GPUDRIVER}" == "panfrost" ]; then + cat </storage/.config/profile.d/075-mangohud-supported +DEVICE_MANGOHUD_SUPPORT="true" +EOF +else + cat </storage/.config/profile.d/075-mangohud-supported +DEVICE_MANGOHUD_SUPPORT="false" +EOF +fi diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3326/090-ui_service b/projects/ArchR/packages/hardware/quirks/platforms/RK3326/090-ui_service new file mode 100755 index 0000000000..0abc282854 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3326/090-ui_service @@ -0,0 +1,10 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +### Set the default device configuration +cat </storage/.config/profile.d/090-ui_service +UI_SERVICE="sway.service essway.service" +MALI_WAYLAND_AFBC=0 +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3326/091-ui_shader b/projects/ArchR/packages/hardware/quirks/platforms/RK3326/091-ui_shader new file mode 100755 index 0000000000..7eab4389f5 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3326/091-ui_shader @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +### Set the default device configuration +cat </storage/.config/profile.d/091-ui_shader +UI_SHADER="glslp" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3326/bin/battery_led_status b/projects/ArchR/packages/hardware/quirks/platforms/RK3326/bin/battery_led_status new file mode 100644 index 0000000000..059c1870d1 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3326/bin/battery_led_status @@ -0,0 +1,70 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Simple script to watch the battery capacity and +# turn the power LED orange when it reaches 30%, red at 20%, and blinking red & orange at 10% + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +function set_led() { + case $1 in + red|off) + echo out >/sys/class/gpio/gpio${DEVICE_PWR_LED_GPIO}/direction + echo 1 >/sys/class/gpio/gpio${DEVICE_PWR_LED_GPIO}/value + ;; + green) + echo out >/sys/class/gpio/gpio${DEVICE_PWR_LED_GPIO}/direction + echo 0 >/sys/class/gpio/gpio${DEVICE_PWR_LED_GPIO}/value + ;; + orange) + echo in >/sys/class/gpio/gpio${DEVICE_PWR_LED_GPIO}/direction + ;; + esac +} + +# Set export GPIO for Power LED +if [ ! -d "/sys/class/gpio/gpio${DEVICE_PWR_LED_GPIO}" ]; then + echo ${DEVICE_PWR_LED_GPIO} > /sys/class/gpio/export +fi + +while true +do + CAP=$(cat /sys/class/power_supply/battery/capacity) + STAT=$(cat /sys/class/power_supply/battery/status) + ISDISABLED=$(get_setting powerled.disabled) + if [ "${ISDISABLED}" == "1" ] + then + set_led off + else + if [[ ${STAT} == "Discharging" ]] + then + #if (( ${CAP} <= 50 )) + #then + # for ctr in $(seq 1 1 5) + # do + # set_led orange + # sleep .5 + # set_led red + # sleep .5 + # done + # continue + #elif (( ${CAP} <= 20 )) + if (( ${CAP} <= 20 )) + then + set_led red + elif (( ${CAP} <= 30 )) + then + set_led orange + else + set_led green + fi + elif (( ${CAP} >= 95 )) + then + set_led green + fi + sleep 15 + fi +done diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3326/sleep.d/post/002-freq b/projects/ArchR/packages/hardware/quirks/platforms/RK3326/sleep.d/post/002-freq new file mode 100755 index 0000000000..d5c06cc41f --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3326/sleep.d/post/002-freq @@ -0,0 +1,23 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +### Restore previous governors before going to sleep + +. /etc/profile + +### Grab the old governors. +OLD_CPU_FREQ=$(get_setting "sleep.cpugovernor") +if [ ! -n "${OLD_CPU_FREQ}" ]; then + OLD_CPU_FREQ="schedutil" +fi + +OLD_GPU_FREQ=$(get_setting "sleep.gpugovernor") +if [ ! -n "${OLD_GPU_FREQ}" ]; then + OLD_GPU_FREQ="simple_ondemand" +fi + +# Restore old governors. +set_cpu_gov "${OLD_CPU_FREQ}" +set_dmc_gov "${OLD_CPU_FREQ}" +set_gpu_gov "${OLD_GPU_FREQ}" diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3326/sleep.d/pre/002-freq b/projects/ArchR/packages/hardware/quirks/platforms/RK3326/sleep.d/pre/002-freq new file mode 100755 index 0000000000..4fbe8c64f0 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3326/sleep.d/pre/002-freq @@ -0,0 +1,19 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Store current freq governors and set governors to powersave. + +. /etc/profile + +### Get the current cpu and gpu governor, save for when the device wakes from sleep. +CUR_CPU_FREQ="$(cat ${CPU_FREQ}/scaling_governor)" +CUR_GPU_FREQ="$(cat ${GPU_FREQ}/governor)" + +set_setting sleep.cpugovernor "${CUR_CPU_FREQ}" +set_setting sleep.gpugovernor "${CUR_GPU_FREQ}" + +### Set all governors to powersave +set_cpu_gov powersave +set_dmc_gov powersave +set_gpu_gov powersave diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3399/002-turbo-mode_config b/projects/ArchR/packages/hardware/quirks/platforms/RK3399/002-turbo-mode_config new file mode 100755 index 0000000000..f1b68db2fe --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3399/002-turbo-mode_config @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/002-turbo-mode_config +DEVICE_TURBO_MODE="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3399/040-affinity b/projects/ArchR/packages/hardware/quirks/platforms/RK3399/040-affinity new file mode 100755 index 0000000000..2896dabc8e --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3399/040-affinity @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/040-affinity +SLOW_CORES="taskset -c 0-3" +FAST_CORES="taskset -c 4-5" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3399/050-modifiers b/projects/ArchR/packages/hardware/quirks/platforms/RK3399/050-modifiers new file mode 100755 index 0000000000..e135998332 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3399/050-modifiers @@ -0,0 +1,10 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/050-modifiers +DEVICE_KEY_VOLUMEDOWN=114 +DEVICE_KEY_VOLUMEUP=115 +DEVICE_FUNC_KEYA_MODIFIER="BTN_SELECT" +DEVICE_FUNC_KEYB_MODIFIER="BTN_MODE" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3399/060-game_settings b/projects/ArchR/packages/hardware/quirks/platforms/RK3399/060-game_settings new file mode 100755 index 0000000000..f718e077d4 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3399/060-game_settings @@ -0,0 +1,34 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile.d/001-functions + +### Set the default performance scaling mode for a few systems. +for SYSTEM in dreamcast n64 ports psp psx saturn pcfx cdi ps2 gamecube +do + CPU_SETTING=$(get_setting ${SYSTEM}.cpugovernor) + if [ -z "${CPU_SETTING}" ] + then + set_setting ${SYSTEM}.cpugovernor performance + fi + GPU_SETTING=$(get_setting ${SYSTEM}.gpuperf) + if [ -z "${GPU_SETTING}" ] + then + set_setting ${SYSTEM}.gpuperf profile_peak + fi +done + +for SYSTEM in gb gbc gba snes nes sms gamegear genesis mastersystem sega32x megadrive segacd megacd +do + CPU_SETTING=$(get_setting ${SYSTEM}.cpugovernor) + if [ -z ${CPU_SETTING} ] + then + set_setting ${SYSTEM}.cpugovernor powersave + fi + GPU_SETTING=$(get_setting ${SYSTEM}.gpuperf) + if [ -z ${GPU_SETTING} ] + then + set_setting ${SYSTEM}.gpuperf low + fi +done diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3399/065-Touchscreen-events b/projects/ArchR/packages/hardware/quirks/platforms/RK3399/065-Touchscreen-events new file mode 100644 index 0000000000..2c43fc027b --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3399/065-Touchscreen-events @@ -0,0 +1,12 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +TOUCHSCREEN_EVENTS=$(get_setting key.touchscreen.events) +if [ -z "${TOUCHSCREEN_EVENTS}" ] +then + set_setting key.touchscreen.events 1 +fi diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3399/090-ui_service b/projects/ArchR/packages/hardware/quirks/platforms/RK3399/090-ui_service new file mode 100755 index 0000000000..5da8b376c7 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3399/090-ui_service @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +### Set the default device configuration +cat </storage/.config/profile.d/090-ui_service +UI_SERVICE="sway.service essway.service" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3399/091-ui_shader b/projects/ArchR/packages/hardware/quirks/platforms/RK3399/091-ui_shader new file mode 100755 index 0000000000..d087007a42 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3399/091-ui_shader @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +### Set the default device configuration +cat </storage/.config/profile.d/091-ui_shader +UI_SHADER="slangp" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3399/bin/battery_led_status b/projects/ArchR/packages/hardware/quirks/platforms/RK3399/bin/battery_led_status new file mode 100644 index 0000000000..c3de3aab6c --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3399/bin/battery_led_status @@ -0,0 +1,70 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Simple script to watch the battery capacity and +# turn the power LED orange when it reaches 30%, red at 20%, and blinking red at 10% + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +function set_led() { + case $1 in + red) + echo 0 > /sys/class/leds/battery_green/brightness + echo 1 > /sys/class/leds/battery_red/brightness + ;; + green) + echo 1 > /sys/class/leds/battery_green/brightness + echo 0 > /sys/class/leds/battery_red/brightness + ;; + orange) + echo 1 > /sys/class/leds/battery_green/brightness + echo 1 > /sys/class/leds/battery_red/brightness + ;; + off) + echo 0 > /sys/class/leds/battery_green/brightness + echo 0 > /sys/class/leds/battery_red/brightness + ;; + esac +} + + +while true +do + CAP=$(cat /sys/class/power_supply/battery/capacity) + STAT=$(cat /sys/class/power_supply/battery/status) + ISDISABLED=$(get_setting powerled.disabled) + if [ "${ISDISABLED}" == "1" ] + then + set_led off + else + if [ ${STAT} == "Discharging" ] + then + if (( ${CAP} <= 5 )) + then + for ctr in $(seq 1 1 5) + do + set_led red + sleep .5 + set_led off + sleep .5 + done + continue + elif (( ${CAP} <= 10 )) + then + set_led red + elif (( ${CAP} <= 20 )) + then + set_led orange + else + set_led green + fi + elif (( ${CAP} >= 95 )) + then + set_led green + fi + sleep 15 + fi +done diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3566/001-device_config b/projects/ArchR/packages/hardware/quirks/platforms/RK3566/001-device_config new file mode 100755 index 0000000000..5af9a2c160 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3566/001-device_config @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: Apache-2.0 +# Copyright (C) 2021-present Fewtarius (https://github.com/fewtarius) + +cat </storage/.config/profile.d/001-device_config +DEVICE_FAKE_JACKSENSE="false" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3566/002-turbo-mode_config b/projects/ArchR/packages/hardware/quirks/platforms/RK3566/002-turbo-mode_config new file mode 100755 index 0000000000..f1b68db2fe --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3566/002-turbo-mode_config @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/002-turbo-mode_config +DEVICE_TURBO_MODE="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3566/010-governors b/projects/ArchR/packages/hardware/quirks/platforms/RK3566/010-governors new file mode 100755 index 0000000000..3ac5684a8a --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3566/010-governors @@ -0,0 +1,9 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/010-governors +# FREQ governors +CPU_FREQ=("/sys/devices/system/cpu/cpufreq/policy0") +GPU_FREQ=("/sys/devices/platform/fde60000.gpu/devfreq/fde60000.gpu") +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3566/010-led_control b/projects/ArchR/packages/hardware/quirks/platforms/RK3566/010-led_control new file mode 100755 index 0000000000..e94be54ee4 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3566/010-led_control @@ -0,0 +1,9 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/010-led_control +DEVICE_LED_CONTROL="true" +DEVICE_LED_BRIGHTNESS="true" +DEVICE_LED_CHARGING="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3566/030-suspend_mode b/projects/ArchR/packages/hardware/quirks/platforms/RK3566/030-suspend_mode new file mode 100755 index 0000000000..a5b3d79e5d --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3566/030-suspend_mode @@ -0,0 +1,12 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile.d/001-functions + +MYSLEEPMODE=$(get_setting system.suspendmode) +if [ -z "${MYSLEEPMODE}" ] +then + /usr/bin/suspendmode mem +fi + diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3566/050-audio_path b/projects/ArchR/packages/hardware/quirks/platforms/RK3566/050-audio_path new file mode 100755 index 0000000000..b93c7a7507 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3566/050-audio_path @@ -0,0 +1,10 @@ +#!/bin/sh +# SPDX-License-Identifier: Apache-2.0 +# Copyright (C) 2021-present Fewtarius (https://github.com/fewtarius) + +cat </storage/.config/profile.d/002-audio_path +ALSA_PRIMARY_CARD=1 +DEVICE_PLAYBACK_PATH_SPK="HP" +DEVICE_PLAYBACK_PATH_HP="HP" +DEVICE_PLAYBACK_PATH="Playback Mux" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3566/050-modifiers b/projects/ArchR/packages/hardware/quirks/platforms/RK3566/050-modifiers new file mode 100755 index 0000000000..0796f20fb4 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3566/050-modifiers @@ -0,0 +1,10 @@ +#!/bin/sh +# SPDX-License-Identifier: Apache-2.0 +# Copyright (C) 2022-present Fewtarius + +cat </storage/.config/profile.d/050-modifiers +DEVICE_KEY_VOLUMEDOWN=114 +DEVICE_KEY_VOLUMEUP=115 +DEVICE_FUNC_KEYA_MODIFIER="BTN_SELECT" +DEVICE_FUNC_KEYB_MODIFIER="BTN_START" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3566/055-thermal-trips b/projects/ArchR/packages/hardware/quirks/platforms/RK3566/055-thermal-trips new file mode 100755 index 0000000000..47e9770523 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3566/055-thermal-trips @@ -0,0 +1,11 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# CPU thermal trips +echo "83000" > /sys/devices/virtual/thermal/thermal_zone0/trip_point_0_temp +echo "88000" > /sys/devices/virtual/thermal/thermal_zone0/trip_point_1_temp + +# GPU thermal trips +echo "80000" > /sys/devices/virtual/thermal/thermal_zone1/trip_point_0_temp +echo "88000" > /sys/devices/virtual/thermal/thermal_zone1/trip_point_1_temp diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3566/060-game_settings b/projects/ArchR/packages/hardware/quirks/platforms/RK3566/060-game_settings new file mode 100755 index 0000000000..3e5395a1d9 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3566/060-game_settings @@ -0,0 +1,25 @@ +#!/bin/sh +# SPDX-License-Identifier: Apache-2.0 +# Copyright (C) 2023-present Fewtarius (https://github.com/fewtarius) + +. /etc/profile.d/001-functions +. /storage/.config/profile.d/010-governors + +### Set the minimum GPU frequency to reduce UI latency. +echo 400000000 >${GPU_FREQ}/min_freq + +### Set the default performance scaling mode for a few systems. +for SYSTEM in dreamcast n64 ports psp psx saturn gba pcfx cdi +do + CPU_SETTING=$(get_setting ${SYSTEM}.cpugovernor) + if [ -z "${CPU_SETTING}" ] + then + set_setting ${SYSTEM}.cpugovernor performance + fi + GPU_SETTING=$(get_setting ${SYSTEM}.gpuperf) + if [ -z "${GPU_SETTING}" ] + then + set_setting ${SYSTEM}.gpuperf profile_peak + fi +done + diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3566/065-Touchscreen-events b/projects/ArchR/packages/hardware/quirks/platforms/RK3566/065-Touchscreen-events new file mode 100644 index 0000000000..2c43fc027b --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3566/065-Touchscreen-events @@ -0,0 +1,12 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +TOUCHSCREEN_EVENTS=$(get_setting key.touchscreen.events) +if [ -z "${TOUCHSCREEN_EVENTS}" ] +then + set_setting key.touchscreen.events 1 +fi diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3566/090-ui_service b/projects/ArchR/packages/hardware/quirks/platforms/RK3566/090-ui_service new file mode 100755 index 0000000000..8d02ef41e6 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3566/090-ui_service @@ -0,0 +1,14 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +### Set the default device configuration +cat </storage/.config/profile.d/090-ui_service +UI_SERVICE="sway.service essway.service" +if [ "$(gpudriver)" = "libmali" ]; then +MALI_WAYLAND_AFBC=0 +# libmali has no working Xorg +unset DISPLAY +fi +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3566/091-ui_shader b/projects/ArchR/packages/hardware/quirks/platforms/RK3566/091-ui_shader new file mode 100755 index 0000000000..7eab4389f5 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3566/091-ui_shader @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +### Set the default device configuration +cat </storage/.config/profile.d/091-ui_shader +UI_SHADER="glslp" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3566/bin/ledcontrol b/projects/ArchR/packages/hardware/quirks/platforms/RK3566/bin/ledcontrol new file mode 100755 index 0000000000..f0d29c92b4 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3566/bin/ledcontrol @@ -0,0 +1,96 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 JELOS (https://github.com/JustEnoughLinuxOS) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +LED_PATH="/sys/class/leds" +LED_STATUS=$(get_setting led.color) +DEFAULT=green + +function led_state() { + echo ${2} >${LED_PATH}/${1}/brightness +} + +function led_off() { + led_state green:power 0 + led_state red:status 0 + led_state amber:charging 0 +} + +function brightness() { + led_off + case ${1} in + green) + led_state green:power $2 + ;; + red) + led_state red:status $2 + ;; + amber) + led_state amber:charging $2 + ;; + esac +} + +GETBRIGHTNESS=$(get_setting led.brightness) +if [ ! -z "${2}" ] +then + LEDBRIGHTNESS=${2} +else + LEDBRIGHTNESS=${GETBRIGHTNESS:-max} +fi + +# on first run (no setting) or on new brightness update settings +if [[ ${LEDBRIGHTNESS} != ${GETBRIGHTNESS} ]]; then + set_setting led.brightness ${LEDBRIGHTNESS} +fi + +# expand aliases +case ${LEDBRIGHTNESS} in + max) + LEDBRIGHTNESS=255 + ;; + mid) + LEDBRIGHTNESS=63 + ;; + min) + LEDBRIGHTNESS=15 + ;; +esac + +case ${1} in + default) + del_setting led.color + brightness ${DEFAULT} ${LEDBRIGHTNESS} + ;; + green|red|amber|off) + brightness ${1} ${LEDBRIGHTNESS} + set_setting led.color ${1} + ;; + discharging) + brightness ${LED_STATUS:-${DEFAULT}} ${LEDBRIGHTNESS} + ;; + charging) + if [ ! "${LED_STATUS}" = "off" ] + then + brightness red ${LEDBRIGHTNESS} + fi + ;; + poweroff) + led_off + ;; + brightness) + brightness ${LED_STATUS:-${DEFAULT}} ${LEDBRIGHTNESS} + ;; + list) +cat </storage/.config/profile.d/001-device_config +DEVICE_TEMP_SENSOR="/sys/devices/virtual/thermal/thermal_zone*/temp" + +# Affinity +SLOW_CORES="taskset -c 0-3" +FAST_CORES="taskset -c 4-7" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3588/009-commander-cfg b/projects/ArchR/packages/hardware/quirks/platforms/RK3588/009-commander-cfg new file mode 100644 index 0000000000..044bb46732 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3588/009-commander-cfg @@ -0,0 +1,11 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +if [ ! -f "/storage/.config/commander.cfg" ]; then +cat </storage/.config/commander.cfg +disp_ppu_x=4 +disp_ppu_y=4 +EOF +fi diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3588/010-governors b/projects/ArchR/packages/hardware/quirks/platforms/RK3588/010-governors new file mode 100755 index 0000000000..05d7ad518b --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3588/010-governors @@ -0,0 +1,9 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/010-governors +CPU_FREQ=("/sys/devices/system/cpu/cpufreq/policy0" "/sys/devices/system/cpu/cpufreq/policy4" "/sys/devices/system/cpu/cpufreq/policy6") +GPU_FREQ=("/sys/devices/platform/fb000000.gpu/devfreq/fb000000.gpu") +DMC_FREQ=("/sys/devices/platform/dmc/devfreq/dmc") +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3588/010-led_control b/projects/ArchR/packages/hardware/quirks/platforms/RK3588/010-led_control new file mode 100755 index 0000000000..4f53c130ed --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3588/010-led_control @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/010-led_control +DEVICE_LED_CONTROL="true" +DEVICE_LED_CHARGING="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3588/040-affinity b/projects/ArchR/packages/hardware/quirks/platforms/RK3588/040-affinity new file mode 100755 index 0000000000..9d5b403e0a --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3588/040-affinity @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/040-affinity +SLOW_CORES="taskset -c 0-3" +FAST_CORES="taskset -c 4-7" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3588/041-panfrost b/projects/ArchR/packages/hardware/quirks/platforms/RK3588/041-panfrost new file mode 100755 index 0000000000..5a04561f5a --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3588/041-panfrost @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/041-panfrost +export PAN_MESA_DEBUG=gofaster +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3588/050-audio_path b/projects/ArchR/packages/hardware/quirks/platforms/RK3588/050-audio_path new file mode 100755 index 0000000000..3e31680b01 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3588/050-audio_path @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/002-audio_path +DEVICE_PLAYBACK_PATH="Playback Path" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3588/050-modifiers b/projects/ArchR/packages/hardware/quirks/platforms/RK3588/050-modifiers new file mode 100755 index 0000000000..8c0961439c --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3588/050-modifiers @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/050-modifiers +DEVICE_FUNC_KEYA_MODIFIER="BTN_SELECT" +DEVICE_FUNC_KEYB_MODIFIER="BTN_START" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3588/060-game_settings b/projects/ArchR/packages/hardware/quirks/platforms/RK3588/060-game_settings new file mode 100755 index 0000000000..5f060285d7 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3588/060-game_settings @@ -0,0 +1,44 @@ + +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile.d/001-functions + +### Set the default performance scaling mode for a few systems. +for SYSTEM in dreamcast n64 ports psp saturn ps2 gamecube wii +do + CPU_SETTING=$(get_setting ${SYSTEM}.cpugovernor) + if [ -z "${CPU_SETTING}" ] + then + set_setting ${SYSTEM}.cpugovernor performance + fi + GPU_SETTING=$(get_setting ${SYSTEM}.gpuperf) + if [ -z "${GPU_SETTING}" ] + then + set_setting ${SYSTEM}.gpuperf profile_peak + fi +done + +for SYSTEM in saturn st-v +do + CORES=$(get_setting ${SYSTEM}.cores) + if [ -z "${CORES}" ] + then + set_setting ${SYSTEM}.cores big + fi +done + +for SYSTEM in gb gbc gba snes nes sms gamegear genesis mastersystem sega32x megadrive segacd megacd +do + CPU_SETTING=$(get_setting ${SYSTEM}.cpugovernor) + if [ -z ${CPU_SETTING} ] + then + set_setting ${SYSTEM}.cpugovernor powersave + fi + GPU_SETTING=$(get_setting ${SYSTEM}.gpuperf) + if [ -z ${GPU_SETTING} ] + then + set_setting ${SYSTEM}.gpuperf low + fi +done diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3588/065-Touchscreen-events b/projects/ArchR/packages/hardware/quirks/platforms/RK3588/065-Touchscreen-events new file mode 100644 index 0000000000..2c43fc027b --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3588/065-Touchscreen-events @@ -0,0 +1,12 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +TOUCHSCREEN_EVENTS=$(get_setting key.touchscreen.events) +if [ -z "${TOUCHSCREEN_EVENTS}" ] +then + set_setting key.touchscreen.events 1 +fi diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3588/090-ui_service b/projects/ArchR/packages/hardware/quirks/platforms/RK3588/090-ui_service new file mode 100755 index 0000000000..ca14b6a938 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3588/090-ui_service @@ -0,0 +1,17 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +### Set the default device configuration +cat </storage/.config/profile.d/090-ui_service +GPUDRIVER=$(/usr/bin/gpudriver) + +case \${GPUDRIVER} in + "libmali") + UI_SERVICE="weston.service" + ;; + "panfrost") + UI_SERVICE="sway.service essway.service" + ;; +esac +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3588/091-ui_shader b/projects/ArchR/packages/hardware/quirks/platforms/RK3588/091-ui_shader new file mode 100755 index 0000000000..7eab4389f5 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3588/091-ui_shader @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +### Set the default device configuration +cat </storage/.config/profile.d/091-ui_shader +UI_SHADER="glslp" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/RK3588/bin/ledcontrol b/projects/ArchR/packages/hardware/quirks/platforms/RK3588/bin/ledcontrol new file mode 100755 index 0000000000..99881b2b2a --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/RK3588/bin/ledcontrol @@ -0,0 +1,70 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 JELOS (https://github.com/JustEnoughLinuxOS) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +LED_PATH="/sys/class/leds" +LED_STATUS=$(get_setting led.color) + +function led_state() { + echo ${2} >${LED_PATH}/${1}/brightness +} + +function led_off() { + led_state green_led 0 + led_state red_led 0 +} + +function led_red() { + led_off + led_state red_led 1 +} + +function led_green() { + led_off + led_state green_led 1 +} + +case ${1} in + green) + led_green + set_setting led.color ${1} + ;; + red) + led_red + set_setting led.color ${1} + ;; + off) + led_off + set_setting led.color ${1} + ;; + discharging) + if [ -n "${LED_STATUS}" ]; then + ledcontrol ${LED_STATUS} + else + led_green + fi + ;; + charging) + if [ ! "${LED_STATUS}" = "off" ]; then + led_red + fi + ;; + default) + del_setting led.color + led_green + ;; + poweroff) + led_off + ;; + list) +cat </storage/.config/profile.d/001-device_config +# Device Features +DEVICE_TEMP_SENSOR=("/sys/devices/virtual/thermal/thermal_zone0/temp" "/sys/devices/virtual/thermal/thermal_zone3/temp" "/sys/devices/virtual/thermal/thermal_zone2/temp") +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/S922X/010-governors b/projects/ArchR/packages/hardware/quirks/platforms/S922X/010-governors new file mode 100755 index 0000000000..233c565a4e --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/S922X/010-governors @@ -0,0 +1,18 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/010-governors +CPU_FREQ=("/sys/devices/system/cpu/cpufreq/policy0" "/sys/devices/system/cpu/cpufreq/policy2") + +GPUDRIVER=$(/usr/bin/gpudriver) + +case \${GPUDRIVER} in + "libmali") + GPU_FREQ=("/sys/devices/platform/soc/ffe40000.gpu_mali_vulkan/devfreq/ffe40000.gpu_mali_vulkan") + ;; + "panfrost") + GPU_FREQ=("/sys/devices/platform/soc/ffe40000.gpu/devfreq/ffe40000.gpu") + ;; +esac +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/S922X/030-suspend_mode b/projects/ArchR/packages/hardware/quirks/platforms/S922X/030-suspend_mode new file mode 100755 index 0000000000..96388b0f53 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/S922X/030-suspend_mode @@ -0,0 +1,14 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +### Sleep is currently broken, so we'll disable it. + +suspendmode off + +### Ignore power button presses for now, until we can finish up fixing sleep. +cat <~/.config/logind.conf.d/login.conf +[Login] +HandlePowerKey=ignore +HandleSuspendKey=ignore +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/S922X/040-affinity b/projects/ArchR/packages/hardware/quirks/platforms/S922X/040-affinity new file mode 100755 index 0000000000..852c85e327 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/S922X/040-affinity @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/040-affinity +SLOW_CORES="taskset -c 0-1" +FAST_CORES="taskset -c 2-5" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/S922X/041-panfrost b/projects/ArchR/packages/hardware/quirks/platforms/S922X/041-panfrost new file mode 100755 index 0000000000..a74f345fa7 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/S922X/041-panfrost @@ -0,0 +1,5 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +export PAN_MESA_DEBUG=forcepack diff --git a/projects/ArchR/packages/hardware/quirks/platforms/S922X/050-modifiers b/projects/ArchR/packages/hardware/quirks/platforms/S922X/050-modifiers new file mode 100755 index 0000000000..922b60300d --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/S922X/050-modifiers @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/050-modifiers +DEVICE_FUNC_KEYA_MODIFIER="BTN_MODE" +DEVICE_FUNC_KEYB_MODIFIER="BTN_START" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/S922X/075-mangohud-supported b/projects/ArchR/packages/hardware/quirks/platforms/S922X/075-mangohud-supported new file mode 100644 index 0000000000..99363338f8 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/S922X/075-mangohud-supported @@ -0,0 +1,25 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile + +GPUDRIVER=$(/usr/bin/gpudriver) +MANGOHUD_ENABLED=$(get_setting "archr.mangohud.enabled") + +# Init setting to 'disabled' +if [ ! -n "${MANGOHUD_ENABLED}" ]; then + set_setting "archr.mangohud.enabled" "0" +fi + +# Enable / disable MangoHud support (panfrost / libmali) +if [ "${GPUDRIVER}" == "panfrost" ]; then + cat </storage/.config/profile.d/075-mangohud-supported +DEVICE_MANGOHUD_SUPPORT="true" +EOF +else + cat </storage/.config/profile.d/075-mangohud-supported +DEVICE_MANGOHUD_SUPPORT="false" +EOF +fi diff --git a/projects/ArchR/packages/hardware/quirks/platforms/S922X/090-ui_service b/projects/ArchR/packages/hardware/quirks/platforms/S922X/090-ui_service new file mode 100755 index 0000000000..5da8b376c7 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/S922X/090-ui_service @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +### Set the default device configuration +cat </storage/.config/profile.d/090-ui_service +UI_SERVICE="sway.service essway.service" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/S922X/091-ui_shader b/projects/ArchR/packages/hardware/quirks/platforms/S922X/091-ui_shader new file mode 100755 index 0000000000..7eab4389f5 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/S922X/091-ui_shader @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +### Set the default device configuration +cat </storage/.config/profile.d/091-ui_shader +UI_SHADER="glslp" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/S922X/bin/battery_led_status b/projects/ArchR/packages/hardware/quirks/platforms/S922X/bin/battery_led_status new file mode 100644 index 0000000000..bfd4ad3551 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/S922X/bin/battery_led_status @@ -0,0 +1,53 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Simple script to watch the battery capacity and +# turn the power LED orange when it reaches 20% and blinking green & orange at 10% + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +function set_led() { + case $1 in + green) + echo 0 > /sys/class/leds/red\:status/brightness + ;; + orange) + echo 1 > /sys/class/leds/red\:status/brightness + ;; + esac +} + + +while true +do + CAP=$(cat /sys/class/power_supply/battery/capacity) + STAT=$(cat /sys/class/power_supply/battery/status) + if [[ ${STAT} == "Discharging" ]] + then + if (( ${CAP} <= 10 )) + then + for ctr in $(seq 1 1 5) + do + set_led orange + sleep .5 + set_led green + sleep .5 + done + continue + elif (( ${CAP} <= 20 )) + then + set_led orange + else + set_led green + fi + elif (( ${CAP} <= 95 )) + then + set_led orange + else + set_led green + fi + sleep 15 +done diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SDM845/001-device_config b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/001-device_config new file mode 100755 index 0000000000..3f012752cf --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/001-device_config @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/001-device_config +# Device Features +DEVICE_HAS_TOUCHSCREEN="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SDM845/002-audio_path b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/002-audio_path new file mode 100755 index 0000000000..567efcfbf9 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/002-audio_path @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/002-audio_path +DEVICE_PLAYBACK_PATH_SPK="Speakers" +DEVICE_PLAYBACK_PATH_HP="HP" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SDM845/005-thermal_path b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/005-thermal_path new file mode 100755 index 0000000000..279d52a50c --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/005-thermal_path @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/005-thermal_path +DEVICE_TEMP_SENSOR=("/sys/devices/virtual/thermal/thermal_zone10/temp") +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SDM845/010-governors b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/010-governors new file mode 100755 index 0000000000..af711f9f74 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/010-governors @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/010-governors +CPU_FREQ=("/sys/devices/system/cpu/cpufreq/policy0" "/sys/devices/system/cpu/cpufreq/policy4") +GPU_FREQ=("/sys/devices/platform/soc@0/5000000.gpu/devfreq/5000000.gpu") +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SDM845/020-set_audio_latency b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/020-set_audio_latency new file mode 100755 index 0000000000..c116a85f79 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/020-set_audio_latency @@ -0,0 +1,11 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile.d/001-functions + +AUDIO_LATENCY=$(get_setting audiolatency) +if [ -z "${AUDIO_LATENCY}" ] +then + set_setting global.audiolatency 64 +fi diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SDM845/040-affinity b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/040-affinity new file mode 100755 index 0000000000..45851cfebe --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/040-affinity @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/040-affinity +SLOW_CORES="taskset -c 0-3" +FAST_CORES="taskset -c 4-7" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SDM845/065-Touchscreen-events b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/065-Touchscreen-events new file mode 100644 index 0000000000..2c43fc027b --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/065-Touchscreen-events @@ -0,0 +1,12 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +TOUCHSCREEN_EVENTS=$(get_setting key.touchscreen.events) +if [ -z "${TOUCHSCREEN_EVENTS}" ] +then + set_setting key.touchscreen.events 1 +fi diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SDM845/070-modifiers b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/070-modifiers new file mode 100755 index 0000000000..adf2be4df1 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/070-modifiers @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/050-modifiers +DEVICE_FUNC_KEYA_MODIFIER="BTN_MODE" +DEVICE_FUNC_KEYB_MODIFIER="BTN_START" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SDM845/075-mangohud-supported b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/075-mangohud-supported new file mode 100644 index 0000000000..ff795efd72 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/075-mangohud-supported @@ -0,0 +1,18 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile + +# Enable MangoHud support +MANGOHUD_SUPPORTED=$(get_setting "archr.mangohud.enabled") +if [ ! -n "${MANGOHUD_SUPPORTED}" ]; then + MANGOHUD_SUPPORTED="0" + set_setting "archr.mangohud.enabled" "${MANGOHUD_SUPPORTED}" +fi + +cat </storage/.config/profile.d/075-mangohud-supported +# Device Features +DEVICE_MANGOHUD_SUPPORT="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SDM845/090-ui_service b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/090-ui_service new file mode 100755 index 0000000000..4ae841806e --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/090-ui_service @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +### Set the default device configuration +cat </storage/.config/profile.d/090-ui_service +UI_SERVICE="sway.service essway.service" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SDM845/091-ui_shader b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/091-ui_shader new file mode 100755 index 0000000000..0b1a8b79d9 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/091-ui_shader @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +### Set the default device configuration +cat </storage/.config/profile.d/091-ui_shader +UI_SHADER="slangp" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SDM845/bin/achievements b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/bin/achievements new file mode 100755 index 0000000000..b0938417ad --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/bin/achievements @@ -0,0 +1,5 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +/usr/bin/ledcontrol rainbow diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SDM845/bin/analog_sticks_ledcontrol b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/bin/analog_sticks_ledcontrol new file mode 100755 index 0000000000..bc517cd61b --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/bin/analog_sticks_ledcontrol @@ -0,0 +1,45 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +# Simple script to set led brightness and rgb color based on +# brightness and rgb values from emulation station + +LED_PATH="/sys/devices/platform/" + +function led_brightness() { + n=1 + while [ "$n" -lt 4 ]; do + echo ${2} > ${LED_PATH}/multi-led${1}${n}/leds/rgb:${1}${n}/brightness + n=$(( n + 1 )) + done +} + +function led_rgb() { + n=1 + while [ "$n" -lt 4 ]; do + echo ${2} ${3} ${4} > ${LED_PATH}/multi-led${1}${n}/leds/rgb:${1}${n}/multi_intensity + n=$(( n + 1 )) + done +} + +# Display usage if no parameters are provided +if [ $# -ne 7 ]; then + echo "Usage: $0 " + echo "Example: $0 255 255 0 0 0 0 255" + exit 1 +fi + +BRIGHTNESS=$1 +RIGHT_RED=$2 +RIGHT_GREEN=$3 +RIGHT_BLUE=$4 +LEFT_RED=$5 +LEFT_GREEN=$6 +LEFT_BLUE=$7 + +led_brightness l $BRIGHTNESS +led_rgb l $LEFT_BLUE $LEFT_GREEN $LEFT_RED +led_brightness r $BRIGHTNESS +led_rgb r $RIGHT_BLUE $RIGHT_GREEN $RIGHT_RED diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SDM845/bin/battery_led_status b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/bin/battery_led_status new file mode 100755 index 0000000000..b3e83e2d6f --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/bin/battery_led_status @@ -0,0 +1,129 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Simple script to watch the battery capacity and +# turn the power LED orange when it reaches 30%, red at 20%, and blinking red at 10% + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +LED_PATH="/sys/devices/platform/" + +function bat_led_off() { + n=1 + while [ "$n" -lt 4 ]; do + echo 0 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/brightness + echo 0 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/brightness + echo 0 0 0 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/multi_intensity + echo 0 0 0 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/multi_intensity + n=$(( n + 1 )) + done +} + +function bat_led_red() { + n=1 + while [ "$n" -lt 4 ]; do + echo 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/brightness + echo 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/brightness + echo 0 0 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/multi_intensity + echo 0 0 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/multi_intensity + n=$(( n + 1 )) + done +} + +function bat_led_green() { + n=1 + while [ "$n" -lt 4 ]; do + echo 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/brightness + echo 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/brightness + echo 0 255 0 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/multi_intensity + echo 0 255 0 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/multi_intensity + n=$(( n + 1 )) + done +} + +function bat_led_orange() { + n=1 + while [ "$n" -lt 4 ]; do + echo 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/brightness + echo 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/brightness + echo 0 20 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/multi_intensity + echo 0 20 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/multi_intensity + n=$(( n + 1 )) + done +} + +function bat_led_yellow() { + n=1 + while [ "$n" -lt 4 ]; do + echo 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/brightness + echo 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/brightness + echo 0 125 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/multi_intensity + echo 0 125 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/multi_intensity + n=$(( n + 1 )) + done +} + +PREV_BATCAP="null" +while true + do + BAT_LED_STATE=$(get_setting led.color) + if [ ! ${BAT_LED_STATE} == "battery" ]; then + break + else + CAP=$(cat /sys/class/power_supply/battery/capacity) + STAT=$(cat /sys/class/power_supply/battery/status) + if [ ${STAT} == "Discharging" ]; then + if (( ${CAP} <= 10 )) + then + for ctr in $(seq 1 1 5) + do + bat_led_red + sleep .5 + bat_led_off + sleep .5 + done + continue + elif (( ${CAP} <= 20 )) + then + BATCAP="D_RED" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_red + fi + elif (( ${CAP} <= 30 )) + then + BATCAP="D_ORANGE" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_orange + fi + elif (( ${CAP} <= 40 )) + then + BATCAP="D_YELLOW" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_yellow + fi + else + BATCAP="D_GREEN" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_green + fi + fi + elif (( ${CAP} <= 94 )) + then + BATCAP="C_ORANGE" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_orange + fi + elif (( ${CAP} >= 95 )) + then + BATCAP="C_GREEN" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_green + fi + fi + PREV_BATCAP=${BATCAP} + sleep 15 + fi +done diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SDM845/bin/fancontrol b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/bin/fancontrol new file mode 100755 index 0000000000..972e68e7b7 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/bin/fancontrol @@ -0,0 +1,103 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +DEBUG=false +COOLING_PROFILE=$(get_setting "cooling.profile") +FAN_PWM="${DEVICE_PWM_FAN}" + +log $0 "Setting profile to ${COOLING_PROFILE}" + +function set_control() { + log $0 "Set fan control to ${1}" + if [ -e "${DEVICE_PWM_FAN}_enable" ] + then + echo ${1} >${DEVICE_PWM_FAN}_enable + fi +} + +trap "set_control 0 && exit 0" SIGHUP SIGINT SIGQUIT SIGABRT + +if [ -e "/storage/.config/fancontrol.conf" ] && [ "${COOLING_PROFILE}" = "custom" ] +then + log $0 "Loading configuration file" 2>/dev/null + source /storage/.config/fancontrol.conf + if [ ! $? = 0 ] + then + WARN="Custom fan profile could not be loaded, defaulting to auto." + log $0 "${WARN}" + COOLING_PROFILE="auto" + set_setting cooling.profile auto + fi +fi + + +if [ ! "${COOLING_PROFILE}" = "custom" ] +then + if [ "${COOLING_PROFILE}" = "aggressive" ]; then + MAXTEMP="75000" + HIGHTEMP="65000" + MIDTEMP="55000" + LOWTEMP="45000" + MINTEMP="35000" + elif [ "${COOLING_PROFILE}" = "moderate" ]; then + MAXTEMP="80000" + HIGHTEMP="70000" + MIDTEMP="60000" + LOWTEMP="50000" + MINTEMP="40000" + elif [ "${COOLING_PROFILE}" = "quiet" ]; then + # Quiet. + MAXTEMP="85000" + HIGHTEMP="75000" + MIDTEMP="65000" + LOWTEMP="55000" + MINTEMP="45000" + else + # auto + set_control 0 >/dev/null 2>&1 + exit 0 + fi +fi + +CTEMP="1" + +log $0 "Enabling fan control." +set_control 1 >/dev/null 2>&1 + +while true + do + INDEX=0 + CPU_TEMP=$(awk '{total += $1; count++} END {printf "%d", total/count}' ${DEVICE_TEMP_SENSOR}) + $DEBUG && log $0 "CPU TEMP: ${CPU_TEMP}" 2>/dev/null + if (( "${CPU_TEMP}" > "${MAXTEMP}" )); then + FSPEED="255" + TEMP="${MAXTEMP}" + elif (( "${CPU_TEMP}" > "${HIGHTEMP}" )); then + FSPEED="196" + TEMP="${HIGHTEMP}" + elif (( "${CPU_TEMP}" > "${MIDTEMP}" )); then + FSPEED="128" + TEMP="${MIDTEMP}" + elif (( "${CPU_TEMP}" > "${LOWTEMP}" )); then + FSPEED="96" + TEMP="${LOWTEMP}" + elif (( "${CPU_TEMP}" > "${MINTEMP}" )); then + FSPEED="64" + TEMP="${MINTEMP}" + else + FSPEED="32" + TEMP=0 + fi + if (( ${TEMP} != ${CTEMP} )); then + echo ${FSPEED} > ${FAN_PWM} + CTEMP=${TEMP} + $DEBUG && log $0 "Setting PWM FAN to ${FSPEED} at CPU Temp: ${CPU_TEMP}" 2>/dev/null + fi + sleep 3 +done + +log $0 "Disabling fan control." +set_control 0 >/dev/null 2>&1 diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SDM845/bin/gpu_overclock b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/bin/gpu_overclock new file mode 100755 index 0000000000..5d88686b03 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/bin/gpu_overclock @@ -0,0 +1,18 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +# Set max gpu freq +case $1 in + disable) + echo 587000000 > $GPU_FREQ/max_freq + set_setting enable.gpu-overclock 0 + ;; + enable) + echo 650000000 > $GPU_FREQ/max_freq + set_setting enable.gpu-overclock 1 + ;; +esac diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SDM845/bin/ledcontrol b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/bin/ledcontrol new file mode 100755 index 0000000000..e9013d4a14 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SDM845/bin/ledcontrol @@ -0,0 +1,153 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +LED_PATH="/sys/devices/platform/" + +function led_off() { + n=1 + while [ "$n" -lt 4 ]; do + echo 0 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/brightness + echo 0 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/brightness + echo 0 0 0 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/multi_intensity + echo 0 0 0 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/multi_intensity + n=$(( n + 1 )) + done +} + +function led_rainbow() { + # Rainbow effect configuration + STEPS=30 # Fewer steps for faster transitions + DURATION=0.5 # Shorter duration (half a second per cycle) + SLEEP_TIME=$(echo "scale=4; $DURATION/$STEPS" | bc) + CYCLES=2 # Number of cycles to run + + calculate_rainbow_color() { + local position=$1 + local h=$(echo "scale=2; 360*$position/$STEPS" | bc) + + # Convert HSV (with S=1, V=1) to RGB + # Calculate region and fractional part + local region=$(echo "scale=0; $h/60" | bc) + local remainder=$(echo "scale=2; $h-$region*60" | bc) + local fractional=$(echo "scale=2; $remainder/60" | bc) + + # Initialize RGB values + local r=0 + local g=0 + local b=0 + + # Calculate RGB based on hue region (0-5) + case $region in + 0) + # 0-60: Red to Yellow + r=255 + g=$(echo "scale=0; 255*$fractional" | bc) + b=0 + ;; + 1) + # 60-120: Yellow to Green + r=$(echo "scale=0; 255*(1-$fractional)" | bc) + g=255 + b=0 + ;; + 2) + # 120-180: Green to Cyan + r=0 + g=255 + b=$(echo "scale=0; 255*$fractional" | bc) + ;; + 3) + # 180-240: Cyan to Blue + r=0 + g=$(echo "scale=0; 255*(1-$fractional)" | bc) + b=255 + ;; + 4) + # 240-300: Blue to Magenta + r=$(echo "scale=0; 255*$fractional" | bc) + g=0 + b=255 + ;; + 5|6) + # 300-360: Magenta to Red + r=255 + g=0 + b=$(echo "scale=0; 255*(1-$fractional)" | bc) + ;; + esac + + # Ensure values are integers + r=${r%.*} + g=${g%.*} + b=${b%.*} + + # Ensure values are not negative or exceed 255 + r=$(( r < 0 ? 0 : r > 255 ? 255 : r )) + g=$(( g < 0 ? 0 : g > 255 ? 255 : g )) + b=$(( b < 0 ? 0 : b > 255 ? 255 : b )) + + echo "$r $g $b" + } + + # Main rainbow effect loop + # Loop several times to create a continuous effect + for ((cycle=0; cycle/storage/.config/profile.d/001-device_config +# Device Features +DEVICE_HAS_TOUCHSCREEN="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8250/002-audio_path b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/002-audio_path new file mode 100644 index 0000000000..567efcfbf9 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/002-audio_path @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/002-audio_path +DEVICE_PLAYBACK_PATH_SPK="Speakers" +DEVICE_PLAYBACK_PATH_HP="HP" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8250/005-thermal_path b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/005-thermal_path new file mode 100644 index 0000000000..a8249224ba --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/005-thermal_path @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/005-thermal_path +DEVICE_TEMP_SENSOR=("/sys/devices/virtual/thermal/thermal_zone10/temp") +DEVICE_GPU_TEMP_SENSOR=("/sys/devices/virtual/thermal/thermal_zone15/temp") +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8250/009-commander-cfg b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/009-commander-cfg new file mode 100644 index 0000000000..044bb46732 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/009-commander-cfg @@ -0,0 +1,11 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +if [ ! -f "/storage/.config/commander.cfg" ]; then +cat </storage/.config/commander.cfg +disp_ppu_x=4 +disp_ppu_y=4 +EOF +fi diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8250/009-serial-number-path b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/009-serial-number-path new file mode 100644 index 0000000000..868efa3397 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/009-serial-number-path @@ -0,0 +1,8 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/009-serial-number-path +DEVICE_SERIAL_NUMBER_PATH=("/sys/devices/soc0/serial_number") +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8250/010-governors b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/010-governors new file mode 100644 index 0000000000..c197729c35 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/010-governors @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/010-governors +CPU_FREQ=("/sys/devices/system/cpu/cpufreq/policy0" "/sys/devices/system/cpu/cpufreq/policy4" "/sys/devices/system/cpu/cpufreq/policy7") +GPU_FREQ=("/sys/devices/platform/soc@0/3d00000.gpu/devfreq/3d00000.gpu") +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8250/020-fan_control b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/020-fan_control new file mode 100755 index 0000000000..318d3caa36 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/020-fan_control @@ -0,0 +1,12 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/020-fan_control + +FANPATH="\$(ls /sys/class/hwmon/hwmon*/pwm1 | grep hwmon | cut -c 18-24)" + +DEVICE_HAS_FAN="true" +DEVICE_PWM_FAN="/sys/class/hwmon/\${FANPATH}/pwm1" +DEVICE_FAN_INPUT="/sys/class/hwmon/\${FANPATH}/pwm1" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8250/020-set_audio_latency b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/020-set_audio_latency new file mode 100644 index 0000000000..c116a85f79 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/020-set_audio_latency @@ -0,0 +1,11 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile.d/001-functions + +AUDIO_LATENCY=$(get_setting audiolatency) +if [ -z "${AUDIO_LATENCY}" ] +then + set_setting global.audiolatency 64 +fi diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8250/030-led-control b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/030-led-control new file mode 100644 index 0000000000..f0a31c9c83 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/030-led-control @@ -0,0 +1,9 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/010-led_control +DEVICE_LED_CONTROL="true" +DEVICE_BATTERY_LED_STATUS="true" +DEVICE_ANALOG_STICKS_LED_CONTROL="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8250/031-analog_leds b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/031-analog_leds new file mode 100644 index 0000000000..786cf5eff3 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/031-analog_leds @@ -0,0 +1,13 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile.d/001-functions + +if [ $DEVICE_ANALOG_STICKS_LED_CONTROL == "true" ]; then + LEDS_CONFIG=$(get_setting analogsticks.led) + + if [ ! -z "${LEDS_CONFIG}" ]; then + /usr/bin/analog_sticks_ledcontrol $LEDS_CONFIG + fi +fi diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8250/040-affinity b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/040-affinity new file mode 100755 index 0000000000..45851cfebe --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/040-affinity @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/040-affinity +SLOW_CORES="taskset -c 0-3" +FAST_CORES="taskset -c 4-7" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8250/060-game_settings b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/060-game_settings new file mode 100755 index 0000000000..595cac4d55 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/060-game_settings @@ -0,0 +1,43 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile.d/001-functions + +### Set the default performance scaling mode for a few systems. +for SYSTEM in saturn ps2 gamecube wii 3ds ps3 xbox +do + CPU_SETTING=$(get_setting ${SYSTEM}.cpugovernor) + if [ -z "${CPU_SETTING}" ] + then + set_setting ${SYSTEM}.cpugovernor performance + fi + GPU_SETTING=$(get_setting ${SYSTEM}.gpuperf) + if [ -z "${GPU_SETTING}" ] + then + set_setting ${SYSTEM}.gpuperf profile_peak + fi +done + +for SYSTEM in saturn st-v +do + CORES=$(get_setting ${SYSTEM}.cores) + if [ -z "${CORES}" ] + then + set_setting ${SYSTEM}.cores big + fi +done + +for SYSTEM in gb gbc gba nes sms gamegear genesis mastersystem sega32x megadrive segacd megacd +do + CPU_SETTING=$(get_setting ${SYSTEM}.cpugovernor) + if [ -z ${CPU_SETTING} ] + then + set_setting ${SYSTEM}.cpugovernor powersave + fi + GPU_SETTING=$(get_setting ${SYSTEM}.gpuperf) + if [ -z ${GPU_SETTING} ] + then + set_setting ${SYSTEM}.gpuperf low + fi +done diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8250/061-yabasanshiro_config b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/061-yabasanshiro_config new file mode 100644 index 0000000000..5bf099d847 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/061-yabasanshiro_config @@ -0,0 +1,26 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +DEVICE_NAME="Retroid Pocket Gamepad" +CONFIG_DIR="/storage/.config/yabasanshiro" +CONFIG_FILE="input.cfg" + +if [ ! -d "${CONFIG_DIR}" ] +then + mkdir -p "${CONFIG_DIR}" +fi + +if [ ! -e "${CONFIG_DIR}/${CONFIG_FILE}" ]; then + GAMEPADCONFIG=$(xmlstarlet sel -t -c "//inputList/inputConfig[@deviceName='${DEVICE_NAME}']" -n /storage/.emulationstation/es_input.cfg) + + if [ ! -z "${GAMEPADCONFIG}" ]; then + cat <${CONFIG_DIR}/${CONFIG_FILE} + + +${GAMEPADCONFIG} + +EOF + fi +fi diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8250/065-Touchscreen-events b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/065-Touchscreen-events new file mode 100644 index 0000000000..2c43fc027b --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/065-Touchscreen-events @@ -0,0 +1,12 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +TOUCHSCREEN_EVENTS=$(get_setting key.touchscreen.events) +if [ -z "${TOUCHSCREEN_EVENTS}" ] +then + set_setting key.touchscreen.events 1 +fi diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8250/070-modifiers b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/070-modifiers new file mode 100644 index 0000000000..adf2be4df1 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/070-modifiers @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/050-modifiers +DEVICE_FUNC_KEYA_MODIFIER="BTN_MODE" +DEVICE_FUNC_KEYB_MODIFIER="BTN_START" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8250/075-mangohud-supported b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/075-mangohud-supported new file mode 100644 index 0000000000..ff795efd72 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/075-mangohud-supported @@ -0,0 +1,18 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile + +# Enable MangoHud support +MANGOHUD_SUPPORTED=$(get_setting "archr.mangohud.enabled") +if [ ! -n "${MANGOHUD_SUPPORTED}" ]; then + MANGOHUD_SUPPORTED="0" + set_setting "archr.mangohud.enabled" "${MANGOHUD_SUPPORTED}" +fi + +cat </storage/.config/profile.d/075-mangohud-supported +# Device Features +DEVICE_MANGOHUD_SUPPORT="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8250/090-ui_service b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/090-ui_service new file mode 100755 index 0000000000..4ae841806e --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/090-ui_service @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +### Set the default device configuration +cat </storage/.config/profile.d/090-ui_service +UI_SERVICE="sway.service essway.service" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8250/091-ui_shader b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/091-ui_shader new file mode 100755 index 0000000000..0b1a8b79d9 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/091-ui_shader @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +### Set the default device configuration +cat </storage/.config/profile.d/091-ui_shader +UI_SHADER="slangp" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8250/400-set_gpu_overclock b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/400-set_gpu_overclock new file mode 100644 index 0000000000..1a22d0e557 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/400-set_gpu_overclock @@ -0,0 +1,16 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile + +# Get GPU overclock state +GPU_OC_SPEED=$(get_setting "gpu-overclock-speed") +if [ ! -n "${GPU_OC_STATE}" ]; then + GPU_OC_STATE="0" + set_setting "gpu-overclock-speed" "${GPU_OC_SPEED}" +fi + +# Set GPU OC state +/usr/lib/autostart/quirks/platforms/SM8250/bin/gpu_overclock "${GPU_OC_SPEED}" diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8250/500-enable-led b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/500-enable-led new file mode 100755 index 0000000000..92d7589dca --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/500-enable-led @@ -0,0 +1,16 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile + +# Get Internal LED State +LED_STATE=$(get_setting "led.color") +if [ ! -n "${LED_STATE}" ]; then + LED_STATE="battery" + set_setting "led.color" "battery" +fi + +# Run LED control at boot +/usr/bin/ledcontrol ${LED_STATE} diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8250/bin/achievements b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/bin/achievements new file mode 100644 index 0000000000..b0938417ad --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/bin/achievements @@ -0,0 +1,5 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +/usr/bin/ledcontrol rainbow diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8250/bin/analog_sticks_ledcontrol b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/bin/analog_sticks_ledcontrol new file mode 100644 index 0000000000..bc517cd61b --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/bin/analog_sticks_ledcontrol @@ -0,0 +1,45 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +# Simple script to set led brightness and rgb color based on +# brightness and rgb values from emulation station + +LED_PATH="/sys/devices/platform/" + +function led_brightness() { + n=1 + while [ "$n" -lt 4 ]; do + echo ${2} > ${LED_PATH}/multi-led${1}${n}/leds/rgb:${1}${n}/brightness + n=$(( n + 1 )) + done +} + +function led_rgb() { + n=1 + while [ "$n" -lt 4 ]; do + echo ${2} ${3} ${4} > ${LED_PATH}/multi-led${1}${n}/leds/rgb:${1}${n}/multi_intensity + n=$(( n + 1 )) + done +} + +# Display usage if no parameters are provided +if [ $# -ne 7 ]; then + echo "Usage: $0 " + echo "Example: $0 255 255 0 0 0 0 255" + exit 1 +fi + +BRIGHTNESS=$1 +RIGHT_RED=$2 +RIGHT_GREEN=$3 +RIGHT_BLUE=$4 +LEFT_RED=$5 +LEFT_GREEN=$6 +LEFT_BLUE=$7 + +led_brightness l $BRIGHTNESS +led_rgb l $LEFT_BLUE $LEFT_GREEN $LEFT_RED +led_brightness r $BRIGHTNESS +led_rgb r $RIGHT_BLUE $RIGHT_GREEN $RIGHT_RED diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8250/bin/battery_led_status b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/bin/battery_led_status new file mode 100644 index 0000000000..b3e83e2d6f --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/bin/battery_led_status @@ -0,0 +1,129 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Simple script to watch the battery capacity and +# turn the power LED orange when it reaches 30%, red at 20%, and blinking red at 10% + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +LED_PATH="/sys/devices/platform/" + +function bat_led_off() { + n=1 + while [ "$n" -lt 4 ]; do + echo 0 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/brightness + echo 0 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/brightness + echo 0 0 0 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/multi_intensity + echo 0 0 0 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/multi_intensity + n=$(( n + 1 )) + done +} + +function bat_led_red() { + n=1 + while [ "$n" -lt 4 ]; do + echo 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/brightness + echo 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/brightness + echo 0 0 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/multi_intensity + echo 0 0 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/multi_intensity + n=$(( n + 1 )) + done +} + +function bat_led_green() { + n=1 + while [ "$n" -lt 4 ]; do + echo 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/brightness + echo 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/brightness + echo 0 255 0 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/multi_intensity + echo 0 255 0 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/multi_intensity + n=$(( n + 1 )) + done +} + +function bat_led_orange() { + n=1 + while [ "$n" -lt 4 ]; do + echo 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/brightness + echo 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/brightness + echo 0 20 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/multi_intensity + echo 0 20 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/multi_intensity + n=$(( n + 1 )) + done +} + +function bat_led_yellow() { + n=1 + while [ "$n" -lt 4 ]; do + echo 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/brightness + echo 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/brightness + echo 0 125 255 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/multi_intensity + echo 0 125 255 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/multi_intensity + n=$(( n + 1 )) + done +} + +PREV_BATCAP="null" +while true + do + BAT_LED_STATE=$(get_setting led.color) + if [ ! ${BAT_LED_STATE} == "battery" ]; then + break + else + CAP=$(cat /sys/class/power_supply/battery/capacity) + STAT=$(cat /sys/class/power_supply/battery/status) + if [ ${STAT} == "Discharging" ]; then + if (( ${CAP} <= 10 )) + then + for ctr in $(seq 1 1 5) + do + bat_led_red + sleep .5 + bat_led_off + sleep .5 + done + continue + elif (( ${CAP} <= 20 )) + then + BATCAP="D_RED" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_red + fi + elif (( ${CAP} <= 30 )) + then + BATCAP="D_ORANGE" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_orange + fi + elif (( ${CAP} <= 40 )) + then + BATCAP="D_YELLOW" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_yellow + fi + else + BATCAP="D_GREEN" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_green + fi + fi + elif (( ${CAP} <= 94 )) + then + BATCAP="C_ORANGE" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_orange + fi + elif (( ${CAP} >= 95 )) + then + BATCAP="C_GREEN" + if [ ! ${BATCAP} = ${PREV_BATCAP} ]; then + bat_led_green + fi + fi + PREV_BATCAP=${BATCAP} + sleep 15 + fi +done diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8250/bin/fancontrol b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/bin/fancontrol new file mode 100755 index 0000000000..972e68e7b7 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/bin/fancontrol @@ -0,0 +1,103 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +DEBUG=false +COOLING_PROFILE=$(get_setting "cooling.profile") +FAN_PWM="${DEVICE_PWM_FAN}" + +log $0 "Setting profile to ${COOLING_PROFILE}" + +function set_control() { + log $0 "Set fan control to ${1}" + if [ -e "${DEVICE_PWM_FAN}_enable" ] + then + echo ${1} >${DEVICE_PWM_FAN}_enable + fi +} + +trap "set_control 0 && exit 0" SIGHUP SIGINT SIGQUIT SIGABRT + +if [ -e "/storage/.config/fancontrol.conf" ] && [ "${COOLING_PROFILE}" = "custom" ] +then + log $0 "Loading configuration file" 2>/dev/null + source /storage/.config/fancontrol.conf + if [ ! $? = 0 ] + then + WARN="Custom fan profile could not be loaded, defaulting to auto." + log $0 "${WARN}" + COOLING_PROFILE="auto" + set_setting cooling.profile auto + fi +fi + + +if [ ! "${COOLING_PROFILE}" = "custom" ] +then + if [ "${COOLING_PROFILE}" = "aggressive" ]; then + MAXTEMP="75000" + HIGHTEMP="65000" + MIDTEMP="55000" + LOWTEMP="45000" + MINTEMP="35000" + elif [ "${COOLING_PROFILE}" = "moderate" ]; then + MAXTEMP="80000" + HIGHTEMP="70000" + MIDTEMP="60000" + LOWTEMP="50000" + MINTEMP="40000" + elif [ "${COOLING_PROFILE}" = "quiet" ]; then + # Quiet. + MAXTEMP="85000" + HIGHTEMP="75000" + MIDTEMP="65000" + LOWTEMP="55000" + MINTEMP="45000" + else + # auto + set_control 0 >/dev/null 2>&1 + exit 0 + fi +fi + +CTEMP="1" + +log $0 "Enabling fan control." +set_control 1 >/dev/null 2>&1 + +while true + do + INDEX=0 + CPU_TEMP=$(awk '{total += $1; count++} END {printf "%d", total/count}' ${DEVICE_TEMP_SENSOR}) + $DEBUG && log $0 "CPU TEMP: ${CPU_TEMP}" 2>/dev/null + if (( "${CPU_TEMP}" > "${MAXTEMP}" )); then + FSPEED="255" + TEMP="${MAXTEMP}" + elif (( "${CPU_TEMP}" > "${HIGHTEMP}" )); then + FSPEED="196" + TEMP="${HIGHTEMP}" + elif (( "${CPU_TEMP}" > "${MIDTEMP}" )); then + FSPEED="128" + TEMP="${MIDTEMP}" + elif (( "${CPU_TEMP}" > "${LOWTEMP}" )); then + FSPEED="96" + TEMP="${LOWTEMP}" + elif (( "${CPU_TEMP}" > "${MINTEMP}" )); then + FSPEED="64" + TEMP="${MINTEMP}" + else + FSPEED="32" + TEMP=0 + fi + if (( ${TEMP} != ${CTEMP} )); then + echo ${FSPEED} > ${FAN_PWM} + CTEMP=${TEMP} + $DEBUG && log $0 "Setting PWM FAN to ${FSPEED} at CPU Temp: ${CPU_TEMP}" 2>/dev/null + fi + sleep 3 +done + +log $0 "Disabling fan control." +set_control 0 >/dev/null 2>&1 diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8250/bin/gpu_overclock b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/bin/gpu_overclock new file mode 100644 index 0000000000..3c0b2703d6 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/bin/gpu_overclock @@ -0,0 +1,35 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +if [ -z "${GPU_FREQ}" ]; then + . /etc/profile +fi + +# Set max gpu freq +case $1 in + 0) + echo 587000000 > $GPU_FREQ/max_freq + set_setting gpu-overclock-speed 0 + ;; + 650) + echo 650000000 > $GPU_FREQ/max_freq + set_setting gpu-overclock-speed 650 + ;; + 700) + echo 700000000 > $GPU_FREQ/max_freq + set_setting gpu-overclock-speed 700 + ;; + 750) + echo 750000000 > $GPU_FREQ/max_freq + set_setting gpu-overclock-speed 750 + ;; + 800) + echo 800000000 > $GPU_FREQ/max_freq + set_setting gpu-overclock-speed 800 + ;; +esac diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8250/bin/ledcontrol b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/bin/ledcontrol new file mode 100644 index 0000000000..e9013d4a14 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8250/bin/ledcontrol @@ -0,0 +1,153 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +LED_PATH="/sys/devices/platform/" + +function led_off() { + n=1 + while [ "$n" -lt 4 ]; do + echo 0 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/brightness + echo 0 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/brightness + echo 0 0 0 > ${LED_PATH}/multi-ledl${n}/leds/rgb:l${n}/multi_intensity + echo 0 0 0 > ${LED_PATH}/multi-ledr${n}/leds/rgb:r${n}/multi_intensity + n=$(( n + 1 )) + done +} + +function led_rainbow() { + # Rainbow effect configuration + STEPS=30 # Fewer steps for faster transitions + DURATION=0.5 # Shorter duration (half a second per cycle) + SLEEP_TIME=$(echo "scale=4; $DURATION/$STEPS" | bc) + CYCLES=2 # Number of cycles to run + + calculate_rainbow_color() { + local position=$1 + local h=$(echo "scale=2; 360*$position/$STEPS" | bc) + + # Convert HSV (with S=1, V=1) to RGB + # Calculate region and fractional part + local region=$(echo "scale=0; $h/60" | bc) + local remainder=$(echo "scale=2; $h-$region*60" | bc) + local fractional=$(echo "scale=2; $remainder/60" | bc) + + # Initialize RGB values + local r=0 + local g=0 + local b=0 + + # Calculate RGB based on hue region (0-5) + case $region in + 0) + # 0-60: Red to Yellow + r=255 + g=$(echo "scale=0; 255*$fractional" | bc) + b=0 + ;; + 1) + # 60-120: Yellow to Green + r=$(echo "scale=0; 255*(1-$fractional)" | bc) + g=255 + b=0 + ;; + 2) + # 120-180: Green to Cyan + r=0 + g=255 + b=$(echo "scale=0; 255*$fractional" | bc) + ;; + 3) + # 180-240: Cyan to Blue + r=0 + g=$(echo "scale=0; 255*(1-$fractional)" | bc) + b=255 + ;; + 4) + # 240-300: Blue to Magenta + r=$(echo "scale=0; 255*$fractional" | bc) + g=0 + b=255 + ;; + 5|6) + # 300-360: Magenta to Red + r=255 + g=0 + b=$(echo "scale=0; 255*(1-$fractional)" | bc) + ;; + esac + + # Ensure values are integers + r=${r%.*} + g=${g%.*} + b=${b%.*} + + # Ensure values are not negative or exceed 255 + r=$(( r < 0 ? 0 : r > 255 ? 255 : r )) + g=$(( g < 0 ? 0 : g > 255 ? 255 : g )) + b=$(( b < 0 ? 0 : b > 255 ? 255 : b )) + + echo "$r $g $b" + } + + # Main rainbow effect loop + # Loop several times to create a continuous effect + for ((cycle=0; cycle/storage/.config/profile.d/001-device_config +# Device Features +DEVICE_HAS_TOUCHSCREEN="true" +DEVICE_NO_MAC="true" +DEVICE_MANGOHUD_SUPPORT="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8550/002-audio_path b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/002-audio_path new file mode 100644 index 0000000000..567efcfbf9 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/002-audio_path @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/002-audio_path +DEVICE_PLAYBACK_PATH_SPK="Speakers" +DEVICE_PLAYBACK_PATH_HP="HP" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8550/005-thermal_path b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/005-thermal_path new file mode 100644 index 0000000000..8a897fe4e8 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/005-thermal_path @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/005-thermal_path +DEVICE_TEMP_SENSOR=("/sys/devices/virtual/thermal/thermal_zone3/temp") +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8550/010-governors b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/010-governors new file mode 100644 index 0000000000..c197729c35 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/010-governors @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/010-governors +CPU_FREQ=("/sys/devices/system/cpu/cpufreq/policy0" "/sys/devices/system/cpu/cpufreq/policy4" "/sys/devices/system/cpu/cpufreq/policy7") +GPU_FREQ=("/sys/devices/platform/soc@0/3d00000.gpu/devfreq/3d00000.gpu") +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8550/020-fan_control b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/020-fan_control new file mode 100755 index 0000000000..a34d268d12 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/020-fan_control @@ -0,0 +1,6 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# fan is controlled by kernel +rm -f /storage/.config/profile.d/020-fan_control diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8550/030-analog_leds b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/030-analog_leds new file mode 100755 index 0000000000..786cf5eff3 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/030-analog_leds @@ -0,0 +1,13 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile.d/001-functions + +if [ $DEVICE_ANALOG_STICKS_LED_CONTROL == "true" ]; then + LEDS_CONFIG=$(get_setting analogsticks.led) + + if [ ! -z "${LEDS_CONFIG}" ]; then + /usr/bin/analog_sticks_ledcontrol $LEDS_CONFIG + fi +fi diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8550/030-led-control b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/030-led-control new file mode 100644 index 0000000000..c9494ba1bf --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/030-led-control @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/010-led_control +DEVICE_LED_CONTROL="true" +DEVICE_BATTERY_LED_STATUS="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8550/030-suspend_mode b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/030-suspend_mode new file mode 100755 index 0000000000..4f773ea554 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/030-suspend_mode @@ -0,0 +1,14 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +### Sleep is currently broken, so we'll disable it. + +/usr/bin/suspendmode off + +### Ignore power button presses for now, until we can finish up fixing sleep. +cat <~/.config/logind.conf.d/login.conf +[Login] +HandlePowerKey=ignore +HandleSuspendKey=ignore +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8550/040-affinity b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/040-affinity new file mode 100755 index 0000000000..45851cfebe --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/040-affinity @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/040-affinity +SLOW_CORES="taskset -c 0-3" +FAST_CORES="taskset -c 4-7" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8550/060-game_settings b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/060-game_settings new file mode 100755 index 0000000000..595cac4d55 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/060-game_settings @@ -0,0 +1,43 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile.d/001-functions + +### Set the default performance scaling mode for a few systems. +for SYSTEM in saturn ps2 gamecube wii 3ds ps3 xbox +do + CPU_SETTING=$(get_setting ${SYSTEM}.cpugovernor) + if [ -z "${CPU_SETTING}" ] + then + set_setting ${SYSTEM}.cpugovernor performance + fi + GPU_SETTING=$(get_setting ${SYSTEM}.gpuperf) + if [ -z "${GPU_SETTING}" ] + then + set_setting ${SYSTEM}.gpuperf profile_peak + fi +done + +for SYSTEM in saturn st-v +do + CORES=$(get_setting ${SYSTEM}.cores) + if [ -z "${CORES}" ] + then + set_setting ${SYSTEM}.cores big + fi +done + +for SYSTEM in gb gbc gba nes sms gamegear genesis mastersystem sega32x megadrive segacd megacd +do + CPU_SETTING=$(get_setting ${SYSTEM}.cpugovernor) + if [ -z ${CPU_SETTING} ] + then + set_setting ${SYSTEM}.cpugovernor powersave + fi + GPU_SETTING=$(get_setting ${SYSTEM}.gpuperf) + if [ -z ${GPU_SETTING} ] + then + set_setting ${SYSTEM}.gpuperf low + fi +done diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8550/061-yabasanshiro_config b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/061-yabasanshiro_config new file mode 100644 index 0000000000..c16d7d17ae --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/061-yabasanshiro_config @@ -0,0 +1,26 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +DEVICE_NAME="AYN Odin2 Gamepad" +CONFIG_DIR="/storage/.config/yabasanshiro" +CONFIG_FILE="input.cfg" + +if [ ! -d "${CONFIG_DIR}" ] +then + mkdir -p "${CONFIG_DIR}" +fi + +if [ ! -e "${CONFIG_DIR}/${CONFIG_FILE}" ]; then + GAMEPADCONFIG=$(xmlstarlet sel -t -c "//inputList/inputConfig[@deviceName='${DEVICE_NAME}']" -n /storage/.emulationstation/es_input.cfg) + + if [ ! -z "${GAMEPADCONFIG}" ]; then + cat <${CONFIG_DIR}/${CONFIG_FILE} + + +${GAMEPADCONFIG} + +EOF + fi +fi diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8550/065-Touchscreen-events b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/065-Touchscreen-events new file mode 100644 index 0000000000..2c43fc027b --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/065-Touchscreen-events @@ -0,0 +1,12 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +TOUCHSCREEN_EVENTS=$(get_setting key.touchscreen.events) +if [ -z "${TOUCHSCREEN_EVENTS}" ] +then + set_setting key.touchscreen.events 1 +fi diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8550/070-modifiers b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/070-modifiers new file mode 100644 index 0000000000..adf2be4df1 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/070-modifiers @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/050-modifiers +DEVICE_FUNC_KEYA_MODIFIER="BTN_MODE" +DEVICE_FUNC_KEYB_MODIFIER="BTN_START" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8550/075-mangohud-supported b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/075-mangohud-supported new file mode 100644 index 0000000000..a7ab35d25b --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/075-mangohud-supported @@ -0,0 +1,13 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile + +# Enable MangoHud support +MANGOHUD_ENABLED=$(get_setting "archr.mangohud.enabled") +if [ ! -n "${MANGOHUD_ENABLED}" ]; then + MANGOHUD_ENABLED="0" + set_setting "archr.mangohud.enabled" "${MANGOHUD_ENABLED}" +fi diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8550/090-ui_service b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/090-ui_service new file mode 100755 index 0000000000..4ae841806e --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/090-ui_service @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +### Set the default device configuration +cat </storage/.config/profile.d/090-ui_service +UI_SERVICE="sway.service essway.service" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8550/091-ui_shader b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/091-ui_shader new file mode 100755 index 0000000000..0b1a8b79d9 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/091-ui_shader @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +### Set the default device configuration +cat </storage/.config/profile.d/091-ui_shader +UI_SHADER="slangp" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8550/500-enable-led b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/500-enable-led new file mode 100755 index 0000000000..1c2c659550 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/500-enable-led @@ -0,0 +1,17 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +# Get Internal LED State +LED_STATE=$(get_setting "led.color") +if [ ! -n "${LED_STATE}" ]; then + LED_STATE="battery" + set_setting "led.color" "battery" +fi + +# Run LED control at boot +/usr/bin/ledcontrol ${LED_STATE} diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8550/bin/gpu_overclock b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/bin/gpu_overclock new file mode 100755 index 0000000000..d3916232d5 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/bin/gpu_overclock @@ -0,0 +1,22 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +if [ -z "${GPU_FREQ}" ]; then + . /etc/profile +fi + +# Set max gpu freq +case $1 in + disable) + echo 680000000 > $GPU_FREQ/max_freq + set_setting enable.gpu-overclock 0 + ;; + enable) + echo 1000000000 > $GPU_FREQ/max_freq + set_setting enable.gpu-overclock 1 + ;; +esac diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8550/sleep.d/post/001-led b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/sleep.d/post/001-led new file mode 100644 index 0000000000..62d88f2412 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/sleep.d/post/001-led @@ -0,0 +1,17 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ROCNIX (https://github.com/archr-linux/Arch-R) + +# Restore LED state that was saved prior to device sleep + +. /etc/profile + +### Get the current LED state and store it +SLEEP_LED_STATE=$(get_setting "sleep.led.color") +if [ ! -n "${SLEEP_LED_STATE}" ]; then + SLEEP_LED_STATE="battery" + set_setting "sleep.led.color" "battery" +fi + +### Turn on LEDS +/usr/bin/ledcontrol ${SLEEP_LED_STATE} diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8550/sleep.d/post/002-freq b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/sleep.d/post/002-freq new file mode 100644 index 0000000000..3d94601970 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/sleep.d/post/002-freq @@ -0,0 +1,22 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +### Restore previous governors before going to sleep + +. /etc/profile + +### Grab the old governors. +OLD_CPU_FREQ=$(get_setting "sleep.cpugovernor") +if [ ! -n "${OLD_CPU_FREQ}" ]; then + OLD_CPU_FREQ="schedutil" +fi + +OLD_GPU_FREQ=$(get_setting "sleep.gpugovernor") +if [ ! -n "${OLD_GPU_FREQ}" ]; then + OLD_GPU_FREQ="simple_ondemand" +fi + +# Restore old governors. +set_cpu_gov "${OLD_CPU_FREQ}" +set_gpu_gov "${OLD_GPU_FREQ}" diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8550/sleep.d/pre/001-led b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/sleep.d/pre/001-led new file mode 100644 index 0000000000..71c9878f7e --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/sleep.d/pre/001-led @@ -0,0 +1,19 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ROCNIX (https://github.com/archr-linux/Arch-R) + +# Store current LED state and turn of LEDS as they prevent the device from sleeping while on + +. /etc/profile + +### Get the current LED state and store it +PRE_SLEEP_LED_STATE=$(get_setting "led.color") +if [ ! -n "${PRE_SLEEP_LED_STATE}" ]; then + PRE_SLEEP_LED_STATE="battery" + set_setting "led.color" "battery" +fi + +set_setting sleep.led.color "${PRE_SLEEP_LED_STATE}" + +### Turn off LEDS +/usr/bin/ledcontrol "off" diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8550/sleep.d/pre/002-freq b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/sleep.d/pre/002-freq new file mode 100644 index 0000000000..6d0fc291dc --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8550/sleep.d/pre/002-freq @@ -0,0 +1,18 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Store current freq governors and set governors to powersave. + +. /etc/profile + +### Get the current cpu and gpu governor, save for when the device wakes from sleep. +CUR_CPU_FREQ="$(cat ${CPU_FREQ}/scaling_governor)" +CUR_GPU_FREQ="$(cat ${GPU_FREQ}/governor)" + +set_setting sleep.cpugovernor "${CUR_CPU_FREQ}" +set_setting sleep.gpugovernor "${CUR_GPU_FREQ}" + +### Set all governors to powersave +set_cpu_gov powersave +set_gpu_gov powersave diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8650/001-device_config b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/001-device_config new file mode 100644 index 0000000000..aa0f140b77 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/001-device_config @@ -0,0 +1,10 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/001-device_config +# Device Features +DEVICE_HAS_TOUCHSCREEN="true" +DEVICE_NO_MAC="true" +DEVICE_MANGOHUD_SUPPORT="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8650/002-audio_path b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/002-audio_path new file mode 100644 index 0000000000..567efcfbf9 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/002-audio_path @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/002-audio_path +DEVICE_PLAYBACK_PATH_SPK="Speakers" +DEVICE_PLAYBACK_PATH_HP="HP" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8650/005-thermal_path b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/005-thermal_path new file mode 100644 index 0000000000..8a897fe4e8 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/005-thermal_path @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/005-thermal_path +DEVICE_TEMP_SENSOR=("/sys/devices/virtual/thermal/thermal_zone3/temp") +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8650/010-governors b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/010-governors new file mode 100644 index 0000000000..9ec6d19c9f --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/010-governors @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/010-governors +CPU_FREQ=("/sys/devices/system/cpu/cpufreq/policy0" "/sys/devices/system/cpu/cpufreq/policy2" "/sys/devices/system/cpu/cpufreq/policy5" "/sys/devices/system/cpu/cpufreq/policy7") +GPU_FREQ=("/sys/devices/platform/soc@0/3d00000.gpu/devfreq/3d00000.gpu") +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8650/030-analog_leds b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/030-analog_leds new file mode 100755 index 0000000000..786cf5eff3 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/030-analog_leds @@ -0,0 +1,13 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile.d/001-functions + +if [ $DEVICE_ANALOG_STICKS_LED_CONTROL == "true" ]; then + LEDS_CONFIG=$(get_setting analogsticks.led) + + if [ ! -z "${LEDS_CONFIG}" ]; then + /usr/bin/analog_sticks_ledcontrol $LEDS_CONFIG + fi +fi diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8650/030-led-control b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/030-led-control new file mode 100644 index 0000000000..c9494ba1bf --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/030-led-control @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/010-led_control +DEVICE_LED_CONTROL="true" +DEVICE_BATTERY_LED_STATUS="true" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8650/030-suspend_mode b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/030-suspend_mode new file mode 100755 index 0000000000..4f773ea554 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/030-suspend_mode @@ -0,0 +1,14 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +### Sleep is currently broken, so we'll disable it. + +/usr/bin/suspendmode off + +### Ignore power button presses for now, until we can finish up fixing sleep. +cat <~/.config/logind.conf.d/login.conf +[Login] +HandlePowerKey=ignore +HandleSuspendKey=ignore +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8650/040-affinity b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/040-affinity new file mode 100755 index 0000000000..2c563f030f --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/040-affinity @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/040-affinity +SLOW_CORES="taskset -c 0-4" +FAST_CORES="taskset -c 5-7" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8650/050-retroarch-configs b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/050-retroarch-configs new file mode 100755 index 0000000000..909e82fcab --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/050-retroarch-configs @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +#Disable retroarch microphone and set default audio driver to pulse +sed -i '/^microphone_enable =/c\microphone_enable = "false"' /storage/.config/retroarch/retroarch.cfg +sed -i '/^audio_driver =/c\audio_driver = "pulse"' /storage/.config/retroarch/retroarch.cfg diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8650/060-game_settings b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/060-game_settings new file mode 100755 index 0000000000..595cac4d55 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/060-game_settings @@ -0,0 +1,43 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile.d/001-functions + +### Set the default performance scaling mode for a few systems. +for SYSTEM in saturn ps2 gamecube wii 3ds ps3 xbox +do + CPU_SETTING=$(get_setting ${SYSTEM}.cpugovernor) + if [ -z "${CPU_SETTING}" ] + then + set_setting ${SYSTEM}.cpugovernor performance + fi + GPU_SETTING=$(get_setting ${SYSTEM}.gpuperf) + if [ -z "${GPU_SETTING}" ] + then + set_setting ${SYSTEM}.gpuperf profile_peak + fi +done + +for SYSTEM in saturn st-v +do + CORES=$(get_setting ${SYSTEM}.cores) + if [ -z "${CORES}" ] + then + set_setting ${SYSTEM}.cores big + fi +done + +for SYSTEM in gb gbc gba nes sms gamegear genesis mastersystem sega32x megadrive segacd megacd +do + CPU_SETTING=$(get_setting ${SYSTEM}.cpugovernor) + if [ -z ${CPU_SETTING} ] + then + set_setting ${SYSTEM}.cpugovernor powersave + fi + GPU_SETTING=$(get_setting ${SYSTEM}.gpuperf) + if [ -z ${GPU_SETTING} ] + then + set_setting ${SYSTEM}.gpuperf low + fi +done diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8650/061-yabasanshiro_config b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/061-yabasanshiro_config new file mode 100644 index 0000000000..c16d7d17ae --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/061-yabasanshiro_config @@ -0,0 +1,26 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +DEVICE_NAME="AYN Odin2 Gamepad" +CONFIG_DIR="/storage/.config/yabasanshiro" +CONFIG_FILE="input.cfg" + +if [ ! -d "${CONFIG_DIR}" ] +then + mkdir -p "${CONFIG_DIR}" +fi + +if [ ! -e "${CONFIG_DIR}/${CONFIG_FILE}" ]; then + GAMEPADCONFIG=$(xmlstarlet sel -t -c "//inputList/inputConfig[@deviceName='${DEVICE_NAME}']" -n /storage/.emulationstation/es_input.cfg) + + if [ ! -z "${GAMEPADCONFIG}" ]; then + cat <${CONFIG_DIR}/${CONFIG_FILE} + + +${GAMEPADCONFIG} + +EOF + fi +fi diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8650/065-Touchscreen-events b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/065-Touchscreen-events new file mode 100644 index 0000000000..2c43fc027b --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/065-Touchscreen-events @@ -0,0 +1,12 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +TOUCHSCREEN_EVENTS=$(get_setting key.touchscreen.events) +if [ -z "${TOUCHSCREEN_EVENTS}" ] +then + set_setting key.touchscreen.events 1 +fi diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8650/070-modifiers b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/070-modifiers new file mode 100644 index 0000000000..adf2be4df1 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/070-modifiers @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +cat </storage/.config/profile.d/050-modifiers +DEVICE_FUNC_KEYA_MODIFIER="BTN_MODE" +DEVICE_FUNC_KEYB_MODIFIER="BTN_START" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8650/075-mangohud-supported b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/075-mangohud-supported new file mode 100644 index 0000000000..a7ab35d25b --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/075-mangohud-supported @@ -0,0 +1,13 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 ArchR (https://github.com/archr-linux/Arch-R) + +. /etc/profile + +# Enable MangoHud support +MANGOHUD_ENABLED=$(get_setting "archr.mangohud.enabled") +if [ ! -n "${MANGOHUD_ENABLED}" ]; then + MANGOHUD_ENABLED="0" + set_setting "archr.mangohud.enabled" "${MANGOHUD_ENABLED}" +fi diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8650/090-ui_service b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/090-ui_service new file mode 100755 index 0000000000..4ae841806e --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/090-ui_service @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +### Set the default device configuration +cat </storage/.config/profile.d/090-ui_service +UI_SERVICE="sway.service essway.service" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8650/091-ui_shader b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/091-ui_shader new file mode 100755 index 0000000000..0b1a8b79d9 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/091-ui_shader @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +### Set the default device configuration +cat </storage/.config/profile.d/091-ui_shader +UI_SHADER="slangp" +EOF diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8650/500-enable-led b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/500-enable-led new file mode 100755 index 0000000000..1c2c659550 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/500-enable-led @@ -0,0 +1,17 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +# Get Internal LED State +LED_STATE=$(get_setting "led.color") +if [ ! -n "${LED_STATE}" ]; then + LED_STATE="battery" + set_setting "led.color" "battery" +fi + +# Run LED control at boot +/usr/bin/ledcontrol ${LED_STATE} diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8650/bin/gpu_overclock b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/bin/gpu_overclock new file mode 100755 index 0000000000..cbbe4ae9f1 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/bin/gpu_overclock @@ -0,0 +1,22 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Minimal OS variable loading for performance +. /etc/profile.d/001-functions + +if [ -z "${GPU_FREQ}" ]; then + . /etc/profile +fi + +# Set max gpu freq +case $1 in + disable) + echo 834000000 > $GPU_FREQ/max_freq + set_setting enable.gpu-overclock 0 + ;; + enable) + echo 1050000000 > $GPU_FREQ/max_freq + set_setting enable.gpu-overclock 1 + ;; +esac diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8650/sleep.d/post/001-led b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/sleep.d/post/001-led new file mode 100644 index 0000000000..62d88f2412 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/sleep.d/post/001-led @@ -0,0 +1,17 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ROCNIX (https://github.com/archr-linux/Arch-R) + +# Restore LED state that was saved prior to device sleep + +. /etc/profile + +### Get the current LED state and store it +SLEEP_LED_STATE=$(get_setting "sleep.led.color") +if [ ! -n "${SLEEP_LED_STATE}" ]; then + SLEEP_LED_STATE="battery" + set_setting "sleep.led.color" "battery" +fi + +### Turn on LEDS +/usr/bin/ledcontrol ${SLEEP_LED_STATE} diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8650/sleep.d/post/002-freq b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/sleep.d/post/002-freq new file mode 100644 index 0000000000..3d94601970 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/sleep.d/post/002-freq @@ -0,0 +1,22 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +### Restore previous governors before going to sleep + +. /etc/profile + +### Grab the old governors. +OLD_CPU_FREQ=$(get_setting "sleep.cpugovernor") +if [ ! -n "${OLD_CPU_FREQ}" ]; then + OLD_CPU_FREQ="schedutil" +fi + +OLD_GPU_FREQ=$(get_setting "sleep.gpugovernor") +if [ ! -n "${OLD_GPU_FREQ}" ]; then + OLD_GPU_FREQ="simple_ondemand" +fi + +# Restore old governors. +set_cpu_gov "${OLD_CPU_FREQ}" +set_gpu_gov "${OLD_GPU_FREQ}" diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8650/sleep.d/pre/001-led b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/sleep.d/pre/001-led new file mode 100644 index 0000000000..71c9878f7e --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/sleep.d/pre/001-led @@ -0,0 +1,19 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ROCNIX (https://github.com/archr-linux/Arch-R) + +# Store current LED state and turn of LEDS as they prevent the device from sleeping while on + +. /etc/profile + +### Get the current LED state and store it +PRE_SLEEP_LED_STATE=$(get_setting "led.color") +if [ ! -n "${PRE_SLEEP_LED_STATE}" ]; then + PRE_SLEEP_LED_STATE="battery" + set_setting "led.color" "battery" +fi + +set_setting sleep.led.color "${PRE_SLEEP_LED_STATE}" + +### Turn off LEDS +/usr/bin/ledcontrol "off" diff --git a/projects/ArchR/packages/hardware/quirks/platforms/SM8650/sleep.d/pre/002-freq b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/sleep.d/pre/002-freq new file mode 100644 index 0000000000..6d0fc291dc --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/platforms/SM8650/sleep.d/pre/002-freq @@ -0,0 +1,18 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +# Store current freq governors and set governors to powersave. + +. /etc/profile + +### Get the current cpu and gpu governor, save for when the device wakes from sleep. +CUR_CPU_FREQ="$(cat ${CPU_FREQ}/scaling_governor)" +CUR_GPU_FREQ="$(cat ${GPU_FREQ}/governor)" + +set_setting sleep.cpugovernor "${CUR_CPU_FREQ}" +set_setting sleep.gpugovernor "${CUR_GPU_FREQ}" + +### Set all governors to powersave +set_cpu_gov powersave +set_gpu_gov powersave diff --git a/projects/ArchR/packages/hardware/quirks/profile.d/999-export b/projects/ArchR/packages/hardware/quirks/profile.d/999-export new file mode 100755 index 0000000000..18eb66d58e --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/profile.d/999-export @@ -0,0 +1,62 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +### If you add a variable that should persist across processes, +### remember to export it here. + +export OS_VERSION \ + OS_BUILD \ + SLOW_CORES \ + FAST_CORES \ + CPU_FREQ \ + DMC_FREQ \ + GPU_FREQ \ + HW_DEVICE\ + DEVICE_ASPECT_RATIO \ + DEVICE_AUDIO_MIXER \ + DEVICE_BATTERY_LED_STATUS \ + DEVICE_DTB_SWITCH \ + DEVICE_FAKE_JACKSENSE \ + DEVICE_FUNC_KEYA_MODIFIER \ + DEVICE_FUNC_KEYB_MODIFIER \ + DEVICE_HAS_FAN \ + DEVICE_GPU_OVERCLOCK \ + DEVICE_GPU_TEMP_SENSOR \ + DEVICE_HAS_HDMI \ + DEVICE_HAS_TOUCHSCREEN \ + DEVICE_HDMI_GPIO \ + DEVICE_HAS_DUAL_SCREEN \ + DEVICE_HEADPHONE_DEV \ + DEVICE_JACK \ + DEVICE_KEY_VOLUMEDOWN \ + DEVICE_KEY_VOLUMEUP \ + DEVICE_LED_BRIGHTNESS \ + DEVICE_LED_CHARGING \ + DEVICE_LED_CONTROL \ + DEVICE_ANALOG_STICKS_LED_CONTROL \ + DEVICE_MANGOHUD_SUPPORT \ + DEVICE_MMC_EJECT \ + DEVICE_PIPEWIRE_PROFILE \ + DEVICE_PWR_LED_CONTROL \ + DEVICE_PWR_LED_GPIO \ + DEVICE_PLAYBACK_PATH \ + DEVICE_PLAYBACK_PATH_HP \ + DEVICE_PLAYBACK_PATH_SPK \ + DEVICE_PWM_FAN \ + DEVICE_PWM_MOTOR \ + DEVICE_SERIAL_NUMBER_PATH \ + DEVICE_SW_HP_SWITCH \ + DEVICE_TEMP_SENSOR \ + DEVICE_TURBO_MODE \ + DEVICE_VOLUME \ + DEVICE_WIFI \ + HDMI_STATE \ + QUIRK_DEVICE \ + UI_SERVICE \ + PAN_MESA_DEBUG \ + WLR_DRM_DEVICES \ + WLR_BACKENDS \ + WLR_CON \ + MALI_WAYLAND_AFBC \ + ALSA_PRIMARY_CARD diff --git a/projects/ArchR/packages/hardware/quirks/system.d/led-poweroff.service b/projects/ArchR/packages/hardware/quirks/system.d/led-poweroff.service new file mode 100644 index 0000000000..e32d6c84e1 --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/system.d/led-poweroff.service @@ -0,0 +1,12 @@ +[Unit] +Description=Power LEDs off before shutting down. +After=multi-user.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/bin/true +ExecStop=/usr/bin/ledcontrol poweroff + +[Install] +WantedBy=multi-user.target diff --git a/projects/ArchR/packages/hardware/quirks/system.d/volume-fixup.service b/projects/ArchR/packages/hardware/quirks/system.d/volume-fixup.service new file mode 100644 index 0000000000..d948dfc43a --- /dev/null +++ b/projects/ArchR/packages/hardware/quirks/system.d/volume-fixup.service @@ -0,0 +1,12 @@ +[Unit] +Description=Fix unset volumes on RK3566 devices +After=archr.target +Before=essway.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/lib/autostart/quirks/platforms/RK3566/bin/volumealign + +[Install] +WantedBy=archr.target diff --git a/projects/ArchR/packages/kernel-drivers/device-tree-overlays/package.mk b/projects/ArchR/packages/kernel-drivers/device-tree-overlays/package.mk new file mode 100644 index 0000000000..77718bf4a9 --- /dev/null +++ b/projects/ArchR/packages/kernel-drivers/device-tree-overlays/package.mk @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="device-tree-overlays" +PKG_LICENSE="GPL2" +PKG_LONGDESC="device-tree-overlays: ArchR linux device tree overlays" +PKG_TOOLCHAIN="manual" +PKG_IS_KERNEL_PKG="yes" + +make_target() { + for dts in ${PKG_BUILD}/${DEVICE}/*.dts; do + $(kernel_path)/scripts/dtc/dtc -@ -I dts -O dtb -o ${dts%.dts}.dtbo ${dts} + done +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/share/bootloader/overlays + cp ${PKG_BUILD}/${DEVICE}/*.dtbo ${INSTALL}/usr/share/bootloader/overlays + + if [ ${DEVICE} != "RK3326" ]; then + mkdir -p ${INSTALL}/usr/bin + cp ${PKG_BUILD}/dtb_overlay ${INSTALL}/usr/bin + fi +} diff --git a/projects/ArchR/packages/kernel-drivers/device-tree-overlays/sources/RK3566/rk3566-undervolt-cpu-l1.dts b/projects/ArchR/packages/kernel-drivers/device-tree-overlays/sources/RK3566/rk3566-undervolt-cpu-l1.dts new file mode 100644 index 0000000000..0c5c504ee5 --- /dev/null +++ b/projects/ArchR/packages/kernel-drivers/device-tree-overlays/sources/RK3566/rk3566-undervolt-cpu-l1.dts @@ -0,0 +1,35 @@ +/dts-v1/; +/plugin/; + +/ { +fragment@0 { +//target = <&cpu0_opp_table>; + target-path = "/opp-table-0"; +__overlay__ { +opp-408000000 { +opp-microvolt = <800000 800000 1150000>; +}; +opp-600000000 { +opp-microvolt = <800000 800000 1150000>; +}; +opp-816000000 { +opp-microvolt = <800000 800000 1150000>; +}; +opp-1104000000 { +opp-microvolt = <800000 800000 1150000>; +}; +opp-1416000000 { +opp-microvolt = <850000 850000 1150000>; +}; +opp-1608000000 { +opp-microvolt = <900000 900000 1150000>; +}; +opp-1800000000 { +opp-microvolt = <950000 950000 1150000>; +}; +opp-1992000000 { +opp-microvolt = <1000000 1000000 1150000>; +}; +}; +}; +}; diff --git a/projects/ArchR/packages/kernel-drivers/device-tree-overlays/sources/RK3566/rk3566-undervolt-cpu-l2.dts b/projects/ArchR/packages/kernel-drivers/device-tree-overlays/sources/RK3566/rk3566-undervolt-cpu-l2.dts new file mode 100644 index 0000000000..60036cedee --- /dev/null +++ b/projects/ArchR/packages/kernel-drivers/device-tree-overlays/sources/RK3566/rk3566-undervolt-cpu-l2.dts @@ -0,0 +1,35 @@ +/dts-v1/; +/plugin/; + +/ { +fragment@0 { +//target = <&cpu0_opp_table>; + target-path = "/opp-table-0"; +__overlay__ { +opp-408000000 { +opp-microvolt = <775000 775000 1150000>; +}; +opp-600000000 { +opp-microvolt = <800000 800000 1150000>; +}; +opp-816000000 { +opp-microvolt = <800000 800000 1150000>; +}; +opp-1104000000 { +opp-microvolt = <800000 800000 1150000>; +}; +opp-1416000000 { +opp-microvolt = <850000 850000 1150000>; +}; +opp-1608000000 { +opp-microvolt = <900000 900000 1150000>; +}; +opp-1800000000 { +opp-microvolt = <925000 925000 1150000>; +}; +opp-1992000000 { +opp-microvolt = <950000 950000 1150000>; +}; +}; +}; +}; diff --git a/projects/ArchR/packages/kernel-drivers/device-tree-overlays/sources/RK3566/rk3566-undervolt-cpu-l3.dts b/projects/ArchR/packages/kernel-drivers/device-tree-overlays/sources/RK3566/rk3566-undervolt-cpu-l3.dts new file mode 100644 index 0000000000..2fb176bfbf --- /dev/null +++ b/projects/ArchR/packages/kernel-drivers/device-tree-overlays/sources/RK3566/rk3566-undervolt-cpu-l3.dts @@ -0,0 +1,35 @@ +/dts-v1/; +/plugin/; + +/ { +fragment@0 { +//target = <&cpu0_opp_table>; + target-path = "/opp-table-0"; +__overlay__ { +opp-408000000 { +opp-microvolt = <760000 760000 1150000>; +}; +opp-600000000 { +opp-microvolt = <775000 775000 1150000>; +}; +opp-816000000 { +opp-microvolt = <790000 790000 1150000>; +}; +opp-1104000000 { +opp-microvolt = <800000 800000 1150000>; +}; +opp-1416000000 { +opp-microvolt = <825000 825000 1150000>; +}; +opp-1608000000 { +opp-microvolt = <850000 850000 1150000>; +}; +opp-1800000000 { +opp-microvolt = <875000 875000 1150000>; +}; +opp-1992000000 { +opp-microvolt = <900000 900000 1150000>; +}; +}; +}; +}; diff --git a/projects/ArchR/packages/kernel-drivers/device-tree-overlays/sources/RK3588/driver-gpu-panthor.dts b/projects/ArchR/packages/kernel-drivers/device-tree-overlays/sources/RK3588/driver-gpu-panthor.dts new file mode 100644 index 0000000000..2da62dbb4a --- /dev/null +++ b/projects/ArchR/packages/kernel-drivers/device-tree-overlays/sources/RK3588/driver-gpu-panthor.dts @@ -0,0 +1,19 @@ +/dts-v1/; +/plugin/; + +/ { + fragment@0 { + target = <&gpu>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@1 { + target = <&gpu_panthor>; + __overlay__ { + status = "okay"; + mali-supply = <&vdd_gpu_s0>; + }; + }; +}; diff --git a/projects/ArchR/packages/kernel-drivers/device-tree-overlays/sources/S922X/driver-gpu-panfrost.dts b/projects/ArchR/packages/kernel-drivers/device-tree-overlays/sources/S922X/driver-gpu-panfrost.dts new file mode 100644 index 0000000000..1bc4b9c0fc --- /dev/null +++ b/projects/ArchR/packages/kernel-drivers/device-tree-overlays/sources/S922X/driver-gpu-panfrost.dts @@ -0,0 +1,18 @@ +/dts-v1/; +/plugin/; + +/ { + fragment@0 { + target = <&mali>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&mali_vulkan>; + __overlay__ { + status = "disabled"; + }; + }; +}; diff --git a/projects/ArchR/packages/kernel-drivers/device-tree-overlays/sources/S922X/gpu-underclock.dts b/projects/ArchR/packages/kernel-drivers/device-tree-overlays/sources/S922X/gpu-underclock.dts new file mode 100644 index 0000000000..2b5ed1b33f --- /dev/null +++ b/projects/ArchR/packages/kernel-drivers/device-tree-overlays/sources/S922X/gpu-underclock.dts @@ -0,0 +1,14 @@ +/dts-v1/; +/plugin/; + +/ { + fragment@0 { + target = <&gpu_opp_table>; + __overlay__ { + // Disable 800 Mhz frequency + opp-799999987 { + status = "disabled"; + }; + }; + }; +}; diff --git a/projects/ArchR/packages/kernel-drivers/device-tree-overlays/sources/dtb_overlay b/projects/ArchR/packages/kernel-drivers/device-tree-overlays/sources/dtb_overlay new file mode 100755 index 0000000000..e0738c0e7b --- /dev/null +++ b/projects/ArchR/packages/kernel-drivers/device-tree-overlays/sources/dtb_overlay @@ -0,0 +1,163 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) +. /etc/profile.d/001-functions +SPECIALIZATIONS="undervolt-cpu undervolt-gpu driver-gpu" + +check_valid_specialization() { + for spec in $SPECIALIZATIONS; do + if [ "$spec" = "${1}" ]; then + return + fi + done + echo "Unknown specialization: ${1}" + echo "Valid specializations are: ${SPECIALIZATIONS}" + exit 1 +} + +get_current_custom_overlay() { + fdtoverlaysline=$(grep FDTOVERLAYS /flash/extlinux/extlinux.conf) + overlays=${fdtoverlaysline## FDTOVERLAYS} + for ol in $overlays; do + match=0 + for spec in $SPECIALIZATIONS; do + if [[ $ol == *"$spec"* ]]; then + match=1 + break + fi + done + if [ $match = 0 ]; then + custom=$ol + break + fi + done + if [ $custom ]; then + echo $custom | cut -d '/' -f 3 + else + echo "None" + fi +} + +get_current_specialized_overlay() { + fdtoverlaysline=$(grep FDTOVERLAYS /flash/extlinux/extlinux.conf) + overlays=${fdtoverlaysline## FDTOVERLAYS} + for ol in $overlays; do + if [[ $ol == *"$1"* ]]; then + specialized="${ol} " + break + fi + done + if [ $specialized ]; then + echo $specialized | cut -d '/' -f 3 + else + echo "None" + fi + +} + +list_custom_overlays() { + for ol in /flash/overlays/*.dtbo; do + for spec in $SPECIALIZATIONS; do + if [[ $ol == *"$spec"* ]]; then + ol="" + break + fi + done + if [ $ol ]; then + echo -n $ol | cut -d '/' -f 4 | tr -d '\n' + echo -n " " + fi + done + echo +} + +list_specialized_overlays() { + for ol in /flash/overlays/*.dtbo; do + if [[ $ol == *"$1"* ]]; then + echo -n $ol | cut -d '/' -f 4 | tr -d '\n' + echo -n " " + fi + done + echo +} + +write_dtbo() { + PRE=/overlays/ + for spec in $SPECIALIZATIONS custom_dtbo; do + ol=$(get_setting system.$spec) + if [ "$ol" != "None" ] && [[ ! -z $ol ]]; then + dtbos+="${PRE}${ol} " + fi + done + mount -o remount,rw /flash + if [ "$dtbos" ]; then + if grep --quiet FDTOVERLAYS /flash/extlinux/extlinux.conf; then + sed -i "/FDTOVERLAYS/c \ \ FDTOVERLAYS ${dtbos}" /flash/extlinux/extlinux.conf + else + sed -i "/FDT/a \ \ FDTOVERLAYS ${dtbos}" /flash/extlinux/extlinux.conf + fi + else + sed -i "/FDTOVERLAYS/d" /flash/extlinux/extlinux.conf + fi + mount -o remount,ro /flash +} + +case "$1" in + "ls") + case "$2" in + "custom") + list_custom_overlays + exit 0 + ;; + *) + check_valid_specialization $2 + list_specialized_overlays $2 + exit 0 + ;; + esac + ;; + "get") + case "$2" in + "custom") + get_current_custom_overlay + exit 0 + ;; + *) + check_valid_specialization $2 + get_current_specialized_overlay $2 + exit 0 + ;; + esac + ;; + "set") + case "$2" in + "custom") + for ol in $(list_custom_overlays); do + if [ "$3" = "$ol" ] || [ $3 = None ]; then + set_setting system.custom_dtbo $3 + write_dtbo + exit 0 + fi + done + echo "dtbo doesn't exist: $3" + exit 1 + ;; + *) + check_valid_specialization $2 + for ol in $(list_specialized_overlays $2); do + if [ "$3" = "$ol" ] || [ $3 = None ]; then + set_setting system.$2 $3 + write_dtbo + exit 0 + fi + done + echo "dtbo doesn't exist: $3" + exit 1 + ;; + esac + ;; + *) + echo "Unknown operation: ${1}" + exit 1 + ;; +esac diff --git a/projects/ArchR/packages/lang/gcc-linaro-aarch64-elf/package.mk b/projects/ArchR/packages/lang/gcc-linaro-aarch64-elf/package.mk new file mode 100644 index 0000000000..0e6934356a --- /dev/null +++ b/projects/ArchR/packages/lang/gcc-linaro-aarch64-elf/package.mk @@ -0,0 +1,13 @@ +PKG_NAME="gcc-linaro-aarch64-elf" +PKG_VERSION="4.9.4-2017.01" +PKG_LICENSE="GPL" +PKG_SITE="" +PKG_URL="https://releases.linaro.org/components/toolchain/binaries/4.9-2017.01/aarch64-elf/gcc-linaro-${PKG_VERSION}-x86_64_aarch64-elf.tar.xz" +PKG_DEPENDS_HOST="ccache:host" +PKG_LONGDESC="Linaro Aarch64 GNU Linux Binary Toolchain" +PKG_TOOLCHAIN="manual" + +makeinstall_host() { + mkdir -p $TOOLCHAIN/lib/gcc-linaro-aarch64-elf/ + cp -a * $TOOLCHAIN/lib/gcc-linaro-aarch64-elf +} diff --git a/projects/ArchR/packages/lang/gcc-linaro-arm-eabi/package.mk b/projects/ArchR/packages/lang/gcc-linaro-arm-eabi/package.mk new file mode 100644 index 0000000000..e51bed521a --- /dev/null +++ b/projects/ArchR/packages/lang/gcc-linaro-arm-eabi/package.mk @@ -0,0 +1,13 @@ +PKG_NAME="gcc-linaro-arm-eabi" +PKG_VERSION="4.9.4-2017.01" +PKG_LICENSE="GPL" +PKG_SITE="" +PKG_URL="https://releases.linaro.org/components/toolchain/binaries/4.9-2017.01/arm-eabi/gcc-linaro-${PKG_VERSION}-x86_64_arm-eabi.tar.xz" +PKG_DEPENDS_HOST="ccache:host" +PKG_LONGDESC="Linaro ARM GNU Linux Binary Toolchain" +PKG_TOOLCHAIN="manual" + +makeinstall_host() { + mkdir -p $TOOLCHAIN/lib/gcc-linaro-arm-eabi/ + cp -a * $TOOLCHAIN/lib/gcc-linaro-arm-eabi +} diff --git a/projects/ArchR/packages/lang/gcc/package.mk b/projects/ArchR/packages/lang/gcc/package.mk new file mode 100644 index 0000000000..2060ee480d --- /dev/null +++ b/projects/ArchR/packages/lang/gcc/package.mk @@ -0,0 +1,193 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="gcc" +PKG_VERSION="14.2.0" +PKG_LICENSE="GPL-2.0-or-later" +PKG_SITE="https://gcc.gnu.org/" +PKG_URL="https://mirrors.kernel.org/gnu/gcc/${PKG_NAME}-${PKG_VERSION}/${PKG_NAME}-${PKG_VERSION}.tar.xz" +PKG_DEPENDS_BOOTSTRAP="ccache:host autoconf:host binutils:host gmp:host mpfr:host mpc:host zstd:host" +PKG_DEPENDS_TARGET="toolchain" +PKG_DEPENDS_HOST="ccache:host autoconf:host binutils:host gmp:host mpfr:host mpc:host zstd:host glibc libxcrypt" +PKG_DEPENDS_INIT="toolchain" +PKG_LONGDESC="This package contains the GNU Compiler Collection." + +if [ "${MOLD_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_HOST+=" mold:host" +fi + +case ${TARGET_ARCH} in + arm|aarch64|riscv64) + OPTS_LIBATOMIC="--enable-libatomic" + ;; + *) + OPTS_LIBATOMIC="--disable-libatomic" + ;; +esac + +GCC_COMMON_CONFIGURE_OPTS="--target=${TARGET_NAME} \ + --with-sysroot=${SYSROOT_PREFIX} \ + --with-gmp=${TOOLCHAIN} \ + --with-mpfr=${TOOLCHAIN} \ + --with-mpc=${TOOLCHAIN} \ + --with-zstd=${TOOLCHAIN} \ + --with-gnu-as \ + --with-gnu-ld \ + --enable-plugin \ + --enable-lto \ + --enable-gold \ + --enable-ld=default \ + --with-linker-hash-style=gnu \ + --disable-multilib \ + --disable-nls \ + --enable-checking=release \ + --without-ppl \ + --without-cloog \ + --disable-libada \ + --disable-libmudflap \ + --disable-libitm \ + --disable-libquadmath \ + --enable-libgomp \ + --disable-libmpx \ + --disable-libssp \ + --disable-static \ + --enable-shared \ + --disable-werror \ + --enable-__cxa_atexit" + +PKG_CONFIGURE_OPTS_BOOTSTRAP="${GCC_COMMON_CONFIGURE_OPTS} \ + --enable-cloog-backend=isl \ + --disable-decimal-float \ + --disable-gcov \ + --enable-languages=c \ + --disable-libatomic \ + --disable-libgomp \ + --disable-libsanitizer \ + --disable-shared \ + --disable-threads \ + --without-headers \ + --with-newlib \ + ${TARGET_ARCH_GCC_OPTS}" + +PKG_CONFIGURE_OPTS_HOST="${GCC_COMMON_CONFIGURE_OPTS} \ + --enable-languages=c,c++ \ + ${OPTS_LIBATOMIC} \ + --enable-decimal-float \ + --enable-tls \ + --enable-shared \ + --disable-static \ + --enable-long-long \ + --enable-threads=posix \ + --disable-libstdcxx-pch \ + --enable-libstdcxx-time \ + --enable-clocale=gnu \ + ${TARGET_ARCH_GCC_OPTS}" + +post_makeinstall_bootstrap() { + GCC_VERSION=$(${TOOLCHAIN}/bin/${TARGET_NAME}-gcc -dumpversion) + DATE="0401$(echo ${GCC_VERSION} | sed 's/\./0/g')" + CROSS_CC=${TARGET_PREFIX}gcc-${GCC_VERSION} + + rm -f ${TARGET_PREFIX}gcc + +cat > ${TARGET_PREFIX}gcc < ${TARGET_PREFIX}gcc < ${TARGET_PREFIX}g++ < +Date: Fri, 16 Aug 2024 07:53:01 +0100 +Subject: [PATCH] aarch64: Fix invalid nested subregs [PR115464] + +The testcase extracts one arm_neon.h vector from a pair (one subreg) +and then reinterprets the result as an SVE vector (another subreg). +Each subreg makes sense individually, but we can't fold them together +into a single subreg: it's 32 bytes -> 16 bytes -> 16*N bytes, +but the interpretation of 32 bytes -> 16*N bytes depends on +whether N==1 or N>1. + +Since the second subreg makes sense individually, simplify_subreg +should bail out rather than ICE on it. simplify_gen_subreg will +then do the same (because it already checks validate_subreg). +This leaves simplify_gen_subreg returning null, requiring the +caller to take appropriate action. + +I think this is relatively likely to occur elsewhere, so the patch +adds a helper for forcing a subreg, allowing a temporary pseudo to +be created where necessary. + +I'll follow up by using force_subreg in more places. This patch +is intended to be a minimal backportable fix for the PR. + +gcc/ + PR target/115464 + * simplify-rtx.cc (simplify_context::simplify_subreg): Don't try + to fold two subregs together if their relationship isn't known + at compile time. + * explow.h (force_subreg): Declare. + * explow.cc (force_subreg): New function. + * config/aarch64/aarch64-sve-builtins-base.cc + (svset_neonq_impl::expand): Use it instead of simplify_gen_subreg. + +gcc/testsuite/ + PR target/115464 + * gcc.target/aarch64/sve/acle/general/pr115464.c: New test. + +(cherry picked from commit 0970ff46ba6330fc80e8736fc05b2eaeeae0b6a0) +--- + gcc/config/aarch64/aarch64-sve-builtins-base.cc | 2 +- + gcc/explow.cc | 15 +++++++++++++++ + gcc/explow.h | 2 ++ + gcc/simplify-rtx.cc | 5 +++++ + .../aarch64/sve/acle/general/pr115464.c | 13 +++++++++++++ + 5 files changed, 36 insertions(+), 1 deletion(-) + create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr115464.c + +diff --git a/gcc/config/aarch64/aarch64-sve-builtins-base.cc b/gcc/config/aarch64/aarch64-sve-builtins-base.cc +index 0d2edf3f19e..c9182594bc1 100644 +--- a/gcc/config/aarch64/aarch64-sve-builtins-base.cc ++++ b/gcc/config/aarch64/aarch64-sve-builtins-base.cc +@@ -1174,7 +1174,7 @@ public: + Advanced SIMD argument as an SVE vector. */ + if (!BYTES_BIG_ENDIAN + && is_undef (CALL_EXPR_ARG (e.call_expr, 0))) +- return simplify_gen_subreg (mode, e.args[1], GET_MODE (e.args[1]), 0); ++ return force_subreg (mode, e.args[1], GET_MODE (e.args[1]), 0); + + rtx_vector_builder builder (VNx16BImode, 16, 2); + for (unsigned int i = 0; i < 16; i++) +diff --git a/gcc/explow.cc b/gcc/explow.cc +index 8e5f6b8e680..f6843398c4b 100644 +--- a/gcc/explow.cc ++++ b/gcc/explow.cc +@@ -745,6 +745,21 @@ force_reg (machine_mode mode, rtx x) + return temp; + } + ++/* Like simplify_gen_subreg, but force OP into a new register if the ++ subreg cannot be formed directly. */ ++ ++rtx ++force_subreg (machine_mode outermode, rtx op, ++ machine_mode innermode, poly_uint64 byte) ++{ ++ rtx x = simplify_gen_subreg (outermode, op, innermode, byte); ++ if (x) ++ return x; ++ ++ op = copy_to_mode_reg (innermode, op); ++ return simplify_gen_subreg (outermode, op, innermode, byte); ++} ++ + /* If X is a memory ref, copy its contents to a new temp reg and return + that reg. Otherwise, return X. */ + +diff --git a/gcc/explow.h b/gcc/explow.h +index 16aa02cfb68..cbd1fcb7eb3 100644 +--- a/gcc/explow.h ++++ b/gcc/explow.h +@@ -42,6 +42,8 @@ extern rtx copy_to_suggested_reg (rtx, rtx, machine_mode); + Args are mode (in case value is a constant) and the value. */ + extern rtx force_reg (machine_mode, rtx); + ++extern rtx force_subreg (machine_mode, rtx, machine_mode, poly_uint64); ++ + /* Return given rtx, copied into a new temp reg if it was in memory. */ + extern rtx force_not_mem (rtx); + +diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc +index dceaa13333c..729d408aa55 100644 +--- a/gcc/simplify-rtx.cc ++++ b/gcc/simplify-rtx.cc +@@ -7612,6 +7612,11 @@ simplify_context::simplify_subreg (machine_mode outermode, rtx op, + poly_uint64 innermostsize = GET_MODE_SIZE (innermostmode); + rtx newx; + ++ /* Make sure that the relationship between the two subregs is ++ known at compile time. */ ++ if (!ordered_p (outersize, innermostsize)) ++ return NULL_RTX; ++ + if (outermode == innermostmode + && known_eq (byte, 0U) + && known_eq (SUBREG_BYTE (op), 0)) +diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr115464.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr115464.c +new file mode 100644 +index 00000000000..d728d1325ed +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr115464.c +@@ -0,0 +1,13 @@ ++/* { dg-options "-O2" } */ ++ ++#include ++#include ++#include ++ ++svuint16_t ++convolve4_4_x (uint16x8x2_t permute_tbl) ++{ ++ return svset_neonq_u16 (svundef_u16 (), permute_tbl.val[1]); ++} ++ ++/* { dg-final { scan-assembler {\tmov\tz0\.d, z1\.d\n} } } */ +-- +2.43.5 + +From 86dacfb06b90371458d58872f461d358a0834305 Mon Sep 17 00:00:00 2001 +From: Richard Sandiford +Date: Fri, 16 Aug 2024 07:53:02 +0100 +Subject: [PATCH] aarch64: Add another use of force_subreg [PR115464] + +This patch includes the testcase from r15-1399 plus a miminal +fix for it, without the other proactive uses of force_subreg. +We can backport other force_subreg calls later if they're shown +to be needed. + +gcc/ + PR target/115464 + * config/aarch64/aarch64-sve-builtins-base.cc + (svset_neonq_impl::expand): Use force_subreg instead of + lowpart_subreg. + +gcc/testsuite/ + PR target/115464 + * gcc.target/aarch64/sve/acle/general/pr115464_2.c: New test. +--- + gcc/config/aarch64/aarch64-sve-builtins-base.cc | 4 +++- + .../gcc.target/aarch64/sve/acle/general/pr115464_2.c | 11 +++++++++++ + 2 files changed, 14 insertions(+), 1 deletion(-) + create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr115464_2.c + +diff --git a/gcc/config/aarch64/aarch64-sve-builtins-base.cc b/gcc/config/aarch64/aarch64-sve-builtins-base.cc +index c9182594bc1..241a249503f 100644 +--- a/gcc/config/aarch64/aarch64-sve-builtins-base.cc ++++ b/gcc/config/aarch64/aarch64-sve-builtins-base.cc +@@ -1185,7 +1185,9 @@ public: + if (BYTES_BIG_ENDIAN) + return e.use_exact_insn (code_for_aarch64_sve_set_neonq (mode)); + insn_code icode = code_for_vcond_mask (mode, mode); +- e.args[1] = lowpart_subreg (mode, e.args[1], GET_MODE (e.args[1])); ++ e.args[1] = force_subreg (mode, e.args[1], GET_MODE (e.args[1]), ++ subreg_lowpart_offset (mode, ++ GET_MODE (e.args[1]))); + e.add_output_operand (icode); + e.add_input_operand (icode, e.args[1]); + e.add_input_operand (icode, e.args[0]); +diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr115464_2.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr115464_2.c +new file mode 100644 +index 00000000000..f561c34f732 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr115464_2.c +@@ -0,0 +1,11 @@ ++/* { dg-options "-O2" } */ ++ ++#include ++#include ++#include ++ ++svuint16_t ++convolve4_4_x (uint16x8x2_t permute_tbl, svuint16_t a) ++{ ++ return svset_neonq_u16 (a, permute_tbl.val[1]); ++} +-- +2.43.5 diff --git a/projects/ArchR/packages/lang/gcc/patches/gcc-crosscompile-badness.patch b/projects/ArchR/packages/lang/gcc/patches/gcc-crosscompile-badness.patch new file mode 100644 index 0000000000..fc01ece219 --- /dev/null +++ b/projects/ArchR/packages/lang/gcc/patches/gcc-crosscompile-badness.patch @@ -0,0 +1,31 @@ +Index: gcc-4.4+svnr145550/gcc/incpath.cc +=================================================================== +--- gcc-4.4+svnr145550.orig/gcc/incpath.cc 2009-04-04 13:48:31.000000000 -0700 ++++ gcc-4.4+svnr145550/gcc/incpath.cc 2009-04-04 14:49:29.000000000 -0700 +@@ -417,6 +417,26 @@ + p->construct = 0; + p->user_supplied_p = user_supplied_p; + ++ /* A common error when cross compiling is including ++ host headers. This code below will try to fail fast ++ for cross compiling. Currently we consider /usr/include, ++ /opt/include and /sw/include as harmful. */ ++ ++ { ++ /* printf("Adding Path: %s\n", p->name ); */ ++ if( strstr(p->name, "/usr/include" ) == p->name ) { ++ fprintf(stderr, _("CROSS COMPILE Badness: /usr/include in INCLUDEPATH: %s\n"), p->name); ++ abort(); ++ } else if( strstr(p->name, "/sw/include") == p->name ) { ++ fprintf(stderr, _("CROSS COMPILE Badness: /sw/include in INCLUDEPATH: %s\n"), p->name); ++ abort(); ++ } else if( strstr(p->name, "/opt/include") == p->name ) { ++ fprintf(stderr, _("CROSS COMPILE Badness: /opt/include in INCLUDEPATH: %s\n"), p->name); ++ abort(); ++ } ++ } ++ ++ + add_cpp_dir_path (p, chain); + } + diff --git a/projects/ArchR/packages/lang/go/package.mk b/projects/ArchR/packages/lang/go/package.mk new file mode 100644 index 0000000000..d8dc9fc9c6 --- /dev/null +++ b/projects/ArchR/packages/lang/go/package.mk @@ -0,0 +1,56 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Lukas Rusak (lrusak@libreelec.tv) +# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="go" +PKG_VERSION="1.21.4" +PKG_LICENSE="BSD" +PKG_SITE="https://golang.org" +PKG_URL="https://github.com/golang/go/archive/${PKG_NAME}${PKG_VERSION}.tar.gz" +PKG_DEPENDS_HOST="toolchain" +PKG_LONGDESC="An programming language that makes it easy to build simple, reliable, and efficient software." +PKG_TOOLCHAIN="manual" + +configure_host() { + export HOME=${ROOT} + export GOOS=linux + export GOROOT_FINAL=${TOOLCHAIN}/lib/golang + export GOCACHE=${HOME}/.cache/go-build + if [ -x /usr/lib/go/bin/go ]; then + export GOROOT_BOOTSTRAP=/usr/lib/go + else + export GOROOT_BOOTSTRAP=/usr/lib/golang + fi + case ${TARGET_ARCH} in + aarch64|arm) + export GOARCH=amd64 + ;; + esac + + if [ ! -d ${GOROOT_BOOTSTRAP} ]; then + cat < +Date: Tue, 17 Jan 2023 13:05:55 -0800 +Subject: [PATCH] Make: handle warning files while building in a directory + +The dependency on the warning files breaks when we are building in a +directory *and* the files already exist from being shipped with the +distribution tarballs. The make VPATH simply isn't sophisticated +enough to deal with it, so let the C compiler handle it by #including +the generated file from a dummy C file. + +Reported-by: Rudi Heitbaum +Signed-off-by: H. Peter Anvin +--- + Makefile.in | 38 ++++++++++++++++++++------------------ + Mkfiles/msvc.mak | 14 +++++++------- + Mkfiles/openwcom.mak | 14 +++++++------- + doc/Makefile.in | 2 +- + 6 files changed, 37 insertions(+), 34 deletions(-) + +diff --git a/Makefile.in b/Makefile.in +index 148fcb50..95268fd2 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -37,8 +37,10 @@ AR = @AR@ + RANLIB = @RANLIB@ + STRIP = @STRIP@ + ++tools = $(top_srcdir)/tools ++ + PERL = perl +-PERLFLAGS = -I$(srcdir)/perllib -I$(srcdir) ++PERLFLAGS = -I$(top_srcdir)/perllib -I$(srcdir) + RUNPERL = $(PERL) $(PERLFLAGS) + + PYTHON3 = python3 +@@ -65,8 +67,8 @@ LN_S = @LN_S@ + FIND = find + + # Binary suffixes +-O = @OBJEXT@ +-X = @EXEEXT@ ++O = @OBJEXT@ ++X = @EXEEXT@ + A = @LIBEXT@ + + # Debug stuff +@@ -194,14 +196,14 @@ PERLREQ = config/unconfig.h \ + x86/iflag.c x86/iflaggen.h \ + macros/macros.c \ + asm/pptok.ph asm/directbl.c asm/directiv.h \ +- asm/warnings.c include/warnings.h doc/warnings.src \ ++ $(WARNFILES) \ + misc/nasmtok.el \ + version.h version.mac version.mak nsis/version.nsh + + INSDEP = x86/insns.dat x86/insns.pl x86/insns-iflags.ph x86/iflags.ph + + config/unconfig.h: config/config.h.in +- $(RUNPERL) $(srcdir)/tools/unconfig.pl \ ++ $(RUNPERL) $(tools)/unconfig.pl \ + '$(srcdir)' config/config.h.in config/unconfig.h + + x86/iflag.c: $(INSDEP) +@@ -273,7 +275,7 @@ x86/regs.h: x86/regs.dat x86/regs.pl + # reasonable, but doesn't update the time stamp if the files aren't + # changed, to avoid rebuilding everything every time. Track the actual + # dependency by the empty file asm/warnings.time. +-WARNFILES = asm/warnings.c include/warnings.h doc/warnings.src ++WARNFILES = asm/warnings_c.h include/warnings.h doc/warnings.src + + warnings: + $(RM_F) $(WARNFILES) $(WARNFILES:=.time) +@@ -283,11 +285,11 @@ asm/warnings.time: $(ALLOBJ_NW:.$(O)=.c) + : > asm/warnings.time + $(MAKE) $(WARNFILES:=.time) + +-asm/warnings.c.time: asm/warnings.pl asm/warnings.time +- $(RUNPERL) $(srcdir)/asm/warnings.pl c asm/warnings.c $(srcdir) +- : > asm/warnings.c.time ++asm/warnings_c.h.time: asm/warnings.pl asm/warnings.time ++ $(RUNPERL) $(srcdir)/asm/warnings.pl c asm/warnings_c.h $(srcdir) ++ : > asm/warnings_c.h.time + +-asm/warnings.c: asm/warnings.c.time ++asm/warnings_c.h: asm/warnings_c.h.time + @: Side effect + + include/warnings.h.time: asm/warnings.pl asm/warnings.time +@@ -506,8 +508,8 @@ EXTERNAL_DEPENDENCIES = 1 + # the dependency information will remain external, so it doesn't + # pollute the git logs. + # +-Makefile.dep: $(PERLREQ) tools/mkdep.pl config.status +- $(RUNPERL) tools/mkdep.pl -M Makefile.in -- $(DEPDIRS) ++Makefile.dep: $(PERLREQ) $(tools)/mkdep.pl config.status ++ $(RUNPERL) $(tools)/mkdep.pl -M Makefile.in -- $(DEPDIRS) + + dep: Makefile.dep + +@@ -517,9 +519,9 @@ dep: Makefile.dep + # be invoked manually or via "make dist". It should be run before + # creating release archives. + # +-alldeps: $(PERLREQ) tools/syncfiles.pl tools/mkdep.pl +- $(RUNPERL) tools/syncfiles.pl Makefile.in Mkfiles/*.mak +- $(RUNPERL) tools/mkdep.pl -i -M Makefile.in Mkfiles/*.mak -- \ ++alldeps: $(PERLREQ) $(tools)/syncfiles.pl $(tools)/mkdep.pl ++ $(RUNPERL) $(tools)/syncfiles.pl Makefile.in Mkfiles/*.mak ++ $(RUNPERL) $(tools)/mkdep.pl -i -M Makefile.in Mkfiles/*.mak -- \ + $(DEPDIRS) + $(RM_F) *.dep + if [ -f config.status ]; then \ +@@ -528,9 +530,9 @@ alldeps: $(PERLREQ) tools/syncfiles.pl tools/mkdep.pl + + # Strip internal dependency information from all Makefiles; this makes + # the output good for git checkin +-cleandeps: $(PERLREQ) tools/syncfiles.pl tools/mkdep.pl +- $(RUNPERL) tools/syncfiles.pl Makefile.in Mkfiles/*.mak +- $(RUNPERL) tools/mkdep.pl -e -M Makefile.in Mkfiles/*.mak -- \ ++cleandeps: $(PERLREQ) $(tools)/syncfiles.pl $(tools)/mkdep.pl ++ $(RUNPERL) $(tools)/syncfiles.pl Makefile.in Mkfiles/*.mak ++ $(RUNPERL) $(tools)/mkdep.pl -e -M Makefile.in Mkfiles/*.mak -- \ + $(DEPDIRS) + $(RM_F) *.dep + if [ -f config.status ]; then \ +diff --git a/Mkfiles/msvc.mak b/Mkfiles/msvc.mak +index cf71fffc..da71c5c6 100644 +--- a/Mkfiles/msvc.mak ++++ b/Mkfiles/msvc.mak +@@ -153,14 +153,14 @@ PERLREQ = config\unconfig.h \ + x86\iflag.c x86\iflaggen.h \ + macros\macros.c \ + asm\pptok.ph asm\directbl.c asm\directiv.h \ +- asm\warnings.c include\warnings.h doc\warnings.src \ ++ $(WARNFILES) \ + misc\nasmtok.el \ + version.h version.mac version.mak nsis\version.nsh + + INSDEP = x86\insns.dat x86\insns.pl x86\insns-iflags.ph x86\iflags.ph + + config\unconfig.h: config\config.h.in +- $(RUNPERL) $(srcdir)\tools\unconfig.pl \ ++ $(RUNPERL) $(tools)\unconfig.pl \ + '$(srcdir)' config\config.h.in config\unconfig.h + + x86\iflag.c: $(INSDEP) +@@ -232,7 +232,7 @@ x86\regs.h: x86\regs.dat x86\regs.pl + # reasonable, but doesn't update the time stamp if the files aren't + # changed, to avoid rebuilding everything every time. Track the actual + # dependency by the empty file asm\warnings.time. +-WARNFILES = asm\warnings.c include\warnings.h doc\warnings.src ++WARNFILES = asm\warnings_c.h include\warnings.h doc\warnings.src + + warnings: + $(RM_F) $(WARNFILES) $(WARNFILES:=.time) +@@ -242,11 +242,11 @@ asm\warnings.time: $(ALLOBJ_NW:.$(O)=.c) + : > asm\warnings.time + $(MAKE) $(WARNFILES:=.time) + +-asm\warnings.c.time: asm\warnings.pl asm\warnings.time +- $(RUNPERL) $(srcdir)\asm\warnings.pl c asm\warnings.c $(srcdir) +- : > asm\warnings.c.time ++asm\warnings_c.h.time: asm\warnings.pl asm\warnings.time ++ $(RUNPERL) $(srcdir)\asm\warnings.pl c asm\warnings_c.h $(srcdir) ++ : > asm\warnings_c.h.time + +-asm\warnings.c: asm\warnings.c.time ++asm\warnings_c.h: asm\warnings_c.h.time + @: Side effect + + include\warnings.h.time: asm\warnings.pl asm\warnings.time +diff --git a/Mkfiles/openwcom.mak b/Mkfiles/openwcom.mak +index 5394d85d..605f9afe 100644 +--- a/Mkfiles/openwcom.mak ++++ b/Mkfiles/openwcom.mak +@@ -166,14 +166,14 @@ PERLREQ = config\unconfig.h & + x86\iflag.c x86\iflaggen.h & + macros\macros.c & + asm\pptok.ph asm\directbl.c asm\directiv.h & +- asm\warnings.c include\warnings.h doc\warnings.src & ++ $(WARNFILES) & + misc\nasmtok.el & + version.h version.mac version.mak nsis\version.nsh + + INSDEP = x86\insns.dat x86\insns.pl x86\insns-iflags.ph x86\iflags.ph + + config\unconfig.h: config\config.h.in +- $(RUNPERL) $(srcdir)\tools\unconfig.pl & ++ $(RUNPERL) $(tools)\unconfig.pl & + '$(srcdir)' config\config.h.in config\unconfig.h + + x86\iflag.c: $(INSDEP) +@@ -245,7 +245,7 @@ x86\regs.h: x86\regs.dat x86\regs.pl + # reasonable, but doesn't update the time stamp if the files aren't + # changed, to avoid rebuilding everything every time. Track the actual + # dependency by the empty file asm\warnings.time. +-WARNFILES = asm\warnings.c include\warnings.h doc\warnings.src ++WARNFILES = asm\warnings_c.h include\warnings.h doc\warnings.src + + warnings: + $(RM_F) $(WARNFILES) $(WARNFILES:=.time) +@@ -255,11 +255,11 @@ asm\warnings.time: $(ALLOBJ_NW:.$(O)=.c) + : > asm\warnings.time + $(MAKE) $(WARNFILES:=.time) + +-asm\warnings.c.time: asm\warnings.pl asm\warnings.time +- $(RUNPERL) $(srcdir)\asm\warnings.pl c asm\warnings.c $(srcdir) +- : > asm\warnings.c.time ++asm\warnings_c.h.time: asm\warnings.pl asm\warnings.time ++ $(RUNPERL) $(srcdir)\asm\warnings.pl c asm\warnings_c.h $(srcdir) ++ : > asm\warnings_c.h.time + +-asm\warnings.c: asm\warnings.c.time ++asm\warnings_c.h: asm\warnings_c.h.time + @: Side effect + + include\warnings.h.time: asm\warnings.pl asm\warnings.time +diff --git a/doc/Makefile.in b/doc/Makefile.in +index e92437a0..1c8393c5 100644 +--- a/doc/Makefile.in ++++ b/doc/Makefile.in +@@ -20,7 +20,7 @@ INSTALL = @INSTALL@ + INSTALL_PROGRAM = @INSTALL_PROGRAM@ + INSTALL_DATA = @INSTALL_DATA@ + +-PERL = perl -I$(srcdir) ++PERL = perl -I$(top_srcdir)/perllib -I$(srcdir) + + PDFOPT = @PDFOPT@ + diff --git a/projects/ArchR/packages/linux-drivers/RTL8733BU/package.mk b/projects/ArchR/packages/linux-drivers/RTL8733BU/package.mk new file mode 100644 index 0000000000..ee09bcc103 --- /dev/null +++ b/projects/ArchR/packages/linux-drivers/RTL8733BU/package.mk @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="RTL8733BU" +PKG_VERSION="308919f005f439de433aac977f925bb57f59acf4" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/wirenboard/rtl8733bu" +PKG_URL="https://github.com/archr-linux/RTL8733BU/archive/${PKG_VERSION}.tar.gz" +PKG_LONGDESC="RTL8733BU driver" +PKG_TOOLCHAIN="make" +PKG_IS_KERNEL_PKG="yes" + +pre_make_target() { + unset LDFLAGS +} + +make_target() { + make V=1 \ + ARCH=${TARGET_KERNEL_ARCH} \ + KSRC=$(kernel_path) \ + CROSS_COMPILE=${TARGET_KERNEL_PREFIX} \ + CONFIG_POWER_SAVING=y +} + +makeinstall_target() { + mkdir -p ${INSTALL}/$(get_full_module_dir)/kernel/drivers/net/wireless + cp *.ko ${INSTALL}/$(get_full_module_dir)/kernel/drivers/net/wireless +} diff --git a/projects/ArchR/packages/linux-drivers/RTL8812AU/modprobe.d/8812au.conf b/projects/ArchR/packages/linux-drivers/RTL8812AU/modprobe.d/8812au.conf new file mode 100644 index 0000000000..abfc21fd60 --- /dev/null +++ b/projects/ArchR/packages/linux-drivers/RTL8812AU/modprobe.d/8812au.conf @@ -0,0 +1,155 @@ +# /etc/modprobe.d/8812au.conf +# +# Purpose: Allow easy access to specific driver options. +# +# Edit the following line to change, add or delete options: +options 8812au rtw_drv_log_level=0 rtw_led_ctrl=1 rtw_vht_enable=1 rtw_power_mgnt=1 rtw_beamform_cap=0 rtw_dfs_region_domain=0 rtw_switch_usb_mode=0 +# +# After editing is complete, save this file (if using nano: Ctrl + x, y, Enter) +# and reboot to activate the changes. +# +# Documentation: +# +# ----- +# +# Log options ( rtw_drv_log_level ) +# +# 0 = NONE (default) +# 1 = ALWAYS +# 2 = ERROR +# 3 = WARNING +# 4 = INFO +# 5 = DEBUG +# 6 = MAX +# +# Note: You can save a log file that only includes RTW log entries by running +# the following in a terminal: +# +# sudo ./save-log.sh +# +# Note: The name of the log file will be ```rtw.log```. +# +# ----- +# +# LED options ( rtw_led_ctrl ) +# +# 0 = Always off +# 1 = Normal blink (default) +# 2 = Always on +# +# ----- +# +# VHT options ( rtw_vht_enable ) +# +# 0 = Disable +# 1 = Enable (default) +# 2 = Force auto enable (use only for 5 GHz AP mode) +# +# Notes: +# - A non-default setting can degrade performance greatly in managed mode. +# - Option 2 allows 80 MHz channel width for 5GHz AP mode, such as when +# you are using hostapd. +# +# ----- +# +# Power options ( rtw_power_mgnt ) +# +# 0 = Disable power saving +# 1 = Power saving on, minPS (default) +# 2 = Power saving on, maxPS (not recommended for AP mode) +# +# ----- +# +# Beamforming options ( rtw_beamform_cap ) +# +# 0 = Disable (default) +# 1 = SU Beamformer +# 2 = SU Beamformee +# 3 = SU Beamformer and SU Beamformee +# 10= SU Beamformee and MU Beamformee +# 11= SU Beamformer and SU Beamformee and MU Beamformee +# +# Note: MU Beamformer is not supported. +# +# ----- +# +# Country Code options ( rtw_country_code ) +# +# Note: Allows the Country Code to be set in cases where it is unable to +# be obtained from the operating system. +# +# Example for the US: rtw_country_code=US +# Example for Panama: rtw_country_code=PA +# Example for Norway: rtw_country_code=NO +# Example for Kuwait: rtw_country_code=KW +# Example for Taiwan: rtw_country_code=TW +# +# ----- +# +# DFS Options ( rtw_dfs_region_domain ) +# +# 0 = NONE (default) +# 1 = FCC +# 2 = MKK +# 3 = ETSI +# +# Notes: +# - Activates DFS channels in AP mode. +# - DFS FCC 80 MHz channels for hostapd: 52(58), 100(106), 116(122) and 132(138) +# - For more information: https://en.wikipedia.org/wiki/List_of_WLAN_channels +# +# Note: An AP needs to listen on a DFS channel for a period of 60 seconds +# before transmitting on the channel. If any radar pulses are detected, +# the AP cannot use that channel and will have to try a different channel. +# +# ----- +# +# Select P2P interface in concurrent mode ( rtw_sel_p2p_iface ) +# +# 0 = Sets interface 0 to be p2p interface +# 1 = Sets interface 1 to be p2p interface (default) +# +# ----- +# +# USB options: ( rtw_switch_usb_mode ) +# +# 0 = No switch (default) +# 1 = Switch from usb 2.0 to usb 3.0 +# 2 = Switch from usb 3.0 to usb 2.0 +# +# ----- +# +# To see all options that are available: +# +# $ ls /sys/module/8812au/parameters/ +# +# ----- +# +# To see the values that are in use: +# +# $ grep [[:alnum:]] /sys/module/8812au/parameters/* +# +# ----- +# +# hostapd setup information for rtl8812au +# Note: The best settings can vary but the following may be a good place to start. +# +# /etc/modprobe.d/8812au.conf +# options 8812au rtw_drv_log_level=0 rtw_led_ctrl=0 rtw_vht_enable=2 rtw_power_mgnt=1 rtw_beamform_cap=0 rtw_dfs_region_domain=1 rtw_switch_usb_mode=1 +# +# Note: The best setting for `rtw_dfs_region_domain=` will depend on your location. +# +# /etc/hostapd/hostapd.conf +# +# hw ht capab: 0x862 +# ht_capab=[HT40+][HT40-][SHORT-GI-20][SHORT-GI-40][MAX-AMSDU-7935] +# +# hw vht capab: 0x03c001a2 +# vht_capab=[MAX-MPDU-11454][SHORT-GI-80][TX-STBC-2BY1][RX-STBC-1][HTC-VHT][MAX-A-MPDU-LEN-EXP7] +# +# ----- + + + + + diff --git a/projects/ArchR/packages/linux-drivers/RTL8812AU/package.mk b/projects/ArchR/packages/linux-drivers/RTL8812AU/package.mk new file mode 100644 index 0000000000..ebf9865ec1 --- /dev/null +++ b/projects/ArchR/packages/linux-drivers/RTL8812AU/package.mk @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="RTL8812AU" +PKG_VERSION="3e8c73224cede1097c49fcd1ecd2e3e181f4540d" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/morrownr/8812au-20210820" +PKG_URL="${PKG_SITE}.git" +PKG_LONGDESC="Realtek 8812AU driver for 4.4-5.x" +PKG_TOOLCHAIN="make" +PKG_IS_KERNEL_PKG="yes" + +pre_make_target() { + unset LDFLAGS +} + +make_target() { + make V=1 \ + ARCH=${TARGET_KERNEL_ARCH} \ + KSRC=$(kernel_path) \ + CROSS_COMPILE=${TARGET_KERNEL_PREFIX} \ + CONFIG_POWER_SAVING=y +} + +makeinstall_target() { + mkdir -p ${INSTALL}/$(get_full_module_dir)/kernel/drivers/net/wireless/ + cp *.ko ${INSTALL}/$(get_full_module_dir)/kernel/drivers/net/wireless/ +} diff --git a/projects/ArchR/packages/linux-drivers/RTL8814AU/modprobe.d/8812au.conf b/projects/ArchR/packages/linux-drivers/RTL8814AU/modprobe.d/8812au.conf new file mode 100644 index 0000000000..abfc21fd60 --- /dev/null +++ b/projects/ArchR/packages/linux-drivers/RTL8814AU/modprobe.d/8812au.conf @@ -0,0 +1,155 @@ +# /etc/modprobe.d/8812au.conf +# +# Purpose: Allow easy access to specific driver options. +# +# Edit the following line to change, add or delete options: +options 8812au rtw_drv_log_level=0 rtw_led_ctrl=1 rtw_vht_enable=1 rtw_power_mgnt=1 rtw_beamform_cap=0 rtw_dfs_region_domain=0 rtw_switch_usb_mode=0 +# +# After editing is complete, save this file (if using nano: Ctrl + x, y, Enter) +# and reboot to activate the changes. +# +# Documentation: +# +# ----- +# +# Log options ( rtw_drv_log_level ) +# +# 0 = NONE (default) +# 1 = ALWAYS +# 2 = ERROR +# 3 = WARNING +# 4 = INFO +# 5 = DEBUG +# 6 = MAX +# +# Note: You can save a log file that only includes RTW log entries by running +# the following in a terminal: +# +# sudo ./save-log.sh +# +# Note: The name of the log file will be ```rtw.log```. +# +# ----- +# +# LED options ( rtw_led_ctrl ) +# +# 0 = Always off +# 1 = Normal blink (default) +# 2 = Always on +# +# ----- +# +# VHT options ( rtw_vht_enable ) +# +# 0 = Disable +# 1 = Enable (default) +# 2 = Force auto enable (use only for 5 GHz AP mode) +# +# Notes: +# - A non-default setting can degrade performance greatly in managed mode. +# - Option 2 allows 80 MHz channel width for 5GHz AP mode, such as when +# you are using hostapd. +# +# ----- +# +# Power options ( rtw_power_mgnt ) +# +# 0 = Disable power saving +# 1 = Power saving on, minPS (default) +# 2 = Power saving on, maxPS (not recommended for AP mode) +# +# ----- +# +# Beamforming options ( rtw_beamform_cap ) +# +# 0 = Disable (default) +# 1 = SU Beamformer +# 2 = SU Beamformee +# 3 = SU Beamformer and SU Beamformee +# 10= SU Beamformee and MU Beamformee +# 11= SU Beamformer and SU Beamformee and MU Beamformee +# +# Note: MU Beamformer is not supported. +# +# ----- +# +# Country Code options ( rtw_country_code ) +# +# Note: Allows the Country Code to be set in cases where it is unable to +# be obtained from the operating system. +# +# Example for the US: rtw_country_code=US +# Example for Panama: rtw_country_code=PA +# Example for Norway: rtw_country_code=NO +# Example for Kuwait: rtw_country_code=KW +# Example for Taiwan: rtw_country_code=TW +# +# ----- +# +# DFS Options ( rtw_dfs_region_domain ) +# +# 0 = NONE (default) +# 1 = FCC +# 2 = MKK +# 3 = ETSI +# +# Notes: +# - Activates DFS channels in AP mode. +# - DFS FCC 80 MHz channels for hostapd: 52(58), 100(106), 116(122) and 132(138) +# - For more information: https://en.wikipedia.org/wiki/List_of_WLAN_channels +# +# Note: An AP needs to listen on a DFS channel for a period of 60 seconds +# before transmitting on the channel. If any radar pulses are detected, +# the AP cannot use that channel and will have to try a different channel. +# +# ----- +# +# Select P2P interface in concurrent mode ( rtw_sel_p2p_iface ) +# +# 0 = Sets interface 0 to be p2p interface +# 1 = Sets interface 1 to be p2p interface (default) +# +# ----- +# +# USB options: ( rtw_switch_usb_mode ) +# +# 0 = No switch (default) +# 1 = Switch from usb 2.0 to usb 3.0 +# 2 = Switch from usb 3.0 to usb 2.0 +# +# ----- +# +# To see all options that are available: +# +# $ ls /sys/module/8812au/parameters/ +# +# ----- +# +# To see the values that are in use: +# +# $ grep [[:alnum:]] /sys/module/8812au/parameters/* +# +# ----- +# +# hostapd setup information for rtl8812au +# Note: The best settings can vary but the following may be a good place to start. +# +# /etc/modprobe.d/8812au.conf +# options 8812au rtw_drv_log_level=0 rtw_led_ctrl=0 rtw_vht_enable=2 rtw_power_mgnt=1 rtw_beamform_cap=0 rtw_dfs_region_domain=1 rtw_switch_usb_mode=1 +# +# Note: The best setting for `rtw_dfs_region_domain=` will depend on your location. +# +# /etc/hostapd/hostapd.conf +# +# hw ht capab: 0x862 +# ht_capab=[HT40+][HT40-][SHORT-GI-20][SHORT-GI-40][MAX-AMSDU-7935] +# +# hw vht capab: 0x03c001a2 +# vht_capab=[MAX-MPDU-11454][SHORT-GI-80][TX-STBC-2BY1][RX-STBC-1][HTC-VHT][MAX-A-MPDU-LEN-EXP7] +# +# ----- + + + + + diff --git a/projects/ArchR/packages/linux-drivers/RTL8814AU/package.mk b/projects/ArchR/packages/linux-drivers/RTL8814AU/package.mk new file mode 100644 index 0000000000..78b1ec6dba --- /dev/null +++ b/projects/ArchR/packages/linux-drivers/RTL8814AU/package.mk @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="RTL8814AU" +PKG_VERSION="b5a6f96cd20a1c6a35ccb000f2f4924dd19704a3" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/morrownr/8814au" +PKG_URL="${PKG_SITE}.git" +PKG_LONGDESC="Realtek 8814AU driver for 4.4-5.x" +PKG_TOOLCHAIN="make" +PKG_IS_KERNEL_PKG="yes" + +pre_make_target() { + unset LDFLAGS +} + +make_target() { + make V=1 \ + ARCH=${TARGET_KERNEL_ARCH} \ + KSRC=$(kernel_path) \ + CROSS_COMPILE=${TARGET_KERNEL_PREFIX} \ + CONFIG_POWER_SAVING=y +} + +makeinstall_target() { + mkdir -p ${INSTALL}/$(get_full_module_dir)/kernel/drivers/net/wireless/ + cp *.ko ${INSTALL}/$(get_full_module_dir)/kernel/drivers/net/wireless/ +} diff --git a/projects/ArchR/packages/linux-drivers/RTL8821AU/modprobe.d/8812au.conf b/projects/ArchR/packages/linux-drivers/RTL8821AU/modprobe.d/8812au.conf new file mode 100644 index 0000000000..abfc21fd60 --- /dev/null +++ b/projects/ArchR/packages/linux-drivers/RTL8821AU/modprobe.d/8812au.conf @@ -0,0 +1,155 @@ +# /etc/modprobe.d/8812au.conf +# +# Purpose: Allow easy access to specific driver options. +# +# Edit the following line to change, add or delete options: +options 8812au rtw_drv_log_level=0 rtw_led_ctrl=1 rtw_vht_enable=1 rtw_power_mgnt=1 rtw_beamform_cap=0 rtw_dfs_region_domain=0 rtw_switch_usb_mode=0 +# +# After editing is complete, save this file (if using nano: Ctrl + x, y, Enter) +# and reboot to activate the changes. +# +# Documentation: +# +# ----- +# +# Log options ( rtw_drv_log_level ) +# +# 0 = NONE (default) +# 1 = ALWAYS +# 2 = ERROR +# 3 = WARNING +# 4 = INFO +# 5 = DEBUG +# 6 = MAX +# +# Note: You can save a log file that only includes RTW log entries by running +# the following in a terminal: +# +# sudo ./save-log.sh +# +# Note: The name of the log file will be ```rtw.log```. +# +# ----- +# +# LED options ( rtw_led_ctrl ) +# +# 0 = Always off +# 1 = Normal blink (default) +# 2 = Always on +# +# ----- +# +# VHT options ( rtw_vht_enable ) +# +# 0 = Disable +# 1 = Enable (default) +# 2 = Force auto enable (use only for 5 GHz AP mode) +# +# Notes: +# - A non-default setting can degrade performance greatly in managed mode. +# - Option 2 allows 80 MHz channel width for 5GHz AP mode, such as when +# you are using hostapd. +# +# ----- +# +# Power options ( rtw_power_mgnt ) +# +# 0 = Disable power saving +# 1 = Power saving on, minPS (default) +# 2 = Power saving on, maxPS (not recommended for AP mode) +# +# ----- +# +# Beamforming options ( rtw_beamform_cap ) +# +# 0 = Disable (default) +# 1 = SU Beamformer +# 2 = SU Beamformee +# 3 = SU Beamformer and SU Beamformee +# 10= SU Beamformee and MU Beamformee +# 11= SU Beamformer and SU Beamformee and MU Beamformee +# +# Note: MU Beamformer is not supported. +# +# ----- +# +# Country Code options ( rtw_country_code ) +# +# Note: Allows the Country Code to be set in cases where it is unable to +# be obtained from the operating system. +# +# Example for the US: rtw_country_code=US +# Example for Panama: rtw_country_code=PA +# Example for Norway: rtw_country_code=NO +# Example for Kuwait: rtw_country_code=KW +# Example for Taiwan: rtw_country_code=TW +# +# ----- +# +# DFS Options ( rtw_dfs_region_domain ) +# +# 0 = NONE (default) +# 1 = FCC +# 2 = MKK +# 3 = ETSI +# +# Notes: +# - Activates DFS channels in AP mode. +# - DFS FCC 80 MHz channels for hostapd: 52(58), 100(106), 116(122) and 132(138) +# - For more information: https://en.wikipedia.org/wiki/List_of_WLAN_channels +# +# Note: An AP needs to listen on a DFS channel for a period of 60 seconds +# before transmitting on the channel. If any radar pulses are detected, +# the AP cannot use that channel and will have to try a different channel. +# +# ----- +# +# Select P2P interface in concurrent mode ( rtw_sel_p2p_iface ) +# +# 0 = Sets interface 0 to be p2p interface +# 1 = Sets interface 1 to be p2p interface (default) +# +# ----- +# +# USB options: ( rtw_switch_usb_mode ) +# +# 0 = No switch (default) +# 1 = Switch from usb 2.0 to usb 3.0 +# 2 = Switch from usb 3.0 to usb 2.0 +# +# ----- +# +# To see all options that are available: +# +# $ ls /sys/module/8812au/parameters/ +# +# ----- +# +# To see the values that are in use: +# +# $ grep [[:alnum:]] /sys/module/8812au/parameters/* +# +# ----- +# +# hostapd setup information for rtl8812au +# Note: The best settings can vary but the following may be a good place to start. +# +# /etc/modprobe.d/8812au.conf +# options 8812au rtw_drv_log_level=0 rtw_led_ctrl=0 rtw_vht_enable=2 rtw_power_mgnt=1 rtw_beamform_cap=0 rtw_dfs_region_domain=1 rtw_switch_usb_mode=1 +# +# Note: The best setting for `rtw_dfs_region_domain=` will depend on your location. +# +# /etc/hostapd/hostapd.conf +# +# hw ht capab: 0x862 +# ht_capab=[HT40+][HT40-][SHORT-GI-20][SHORT-GI-40][MAX-AMSDU-7935] +# +# hw vht capab: 0x03c001a2 +# vht_capab=[MAX-MPDU-11454][SHORT-GI-80][TX-STBC-2BY1][RX-STBC-1][HTC-VHT][MAX-A-MPDU-LEN-EXP7] +# +# ----- + + + + + diff --git a/projects/ArchR/packages/linux-drivers/RTL8821AU/package.mk b/projects/ArchR/packages/linux-drivers/RTL8821AU/package.mk new file mode 100644 index 0000000000..17914d0652 --- /dev/null +++ b/projects/ArchR/packages/linux-drivers/RTL8821AU/package.mk @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="RTL8821AU" +PKG_VERSION="847c74b1c272466f89c77947f7a9703222f0093b" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/morrownr/8821au-20210708" +PKG_URL="${PKG_SITE}.git" +PKG_LONGDESC="Realtek 8821AU driver for 4.4-5.x" +PKG_TOOLCHAIN="make" +PKG_IS_KERNEL_PKG="yes" + +pre_make_target() { + unset LDFLAGS +} + +make_target() { + make V=1 \ + ARCH=${TARGET_KERNEL_ARCH} \ + KSRC=$(kernel_path) \ + CROSS_COMPILE=${TARGET_KERNEL_PREFIX} \ + CONFIG_POWER_SAVING=y +} + +makeinstall_target() { + mkdir -p ${INSTALL}/$(get_full_module_dir)/kernel/drivers/net/wireless/ + cp *.ko ${INSTALL}/$(get_full_module_dir)/kernel/drivers/net/wireless/ +} diff --git a/projects/ArchR/packages/linux-drivers/RTL8821CU/modprobe.d/8821cu.conf b/projects/ArchR/packages/linux-drivers/RTL8821CU/modprobe.d/8821cu.conf new file mode 100644 index 0000000000..0512d38594 --- /dev/null +++ b/projects/ArchR/packages/linux-drivers/RTL8821CU/modprobe.d/8821cu.conf @@ -0,0 +1,145 @@ +# /etc/modprobe.d/8821cu.conf +# +# Purpose: Allow easy access to specific driver options. +# +# Edit the following line to change, add or delete options: +#options 8821cu rtw_drv_log_level=0 rtw_led_ctrl=1 rtw_vht_enable=1 rtw_power_mgnt=1 rtw_beamform_cap=0 rtw_dfs_region_domain=0 +# +# After editing is complete, save this file (if using nano: Ctrl + x, y, Enter) +# and reboot to activate the changes. +# +# Documentation: +# +# ----- +# +# Log options ( rtw_drv_log_level ) +# +# 0 = NONE (default) +# 1 = ALWAYS +# 2 = ERROR +# 3 = WARNING +# 4 = INFO +# 5 = DEBUG +# 6 = MAX +# +# Note: You can save a log file that only includes RTW log entries by running +# the following in a terminal: +# +# sudo ./save-log.sh +# +# Note: The name of the log file will be ```rtw.log```. +# +# ----- +# +# LED options ( rtw_led_ctrl ) +# +# 0 = Always off +# 1 = Normal blink (default) +# 2 = Always on +# +# ----- +# +# VHT options ( rtw_vht_enable ) +# +# 0 = Disable +# 1 = Enable (default) +# 2 = Force auto enable (use only for 5 GHz AP mode) +# +# Notes: +# - A non-default setting can degrade performance greatly in managed mode. +# - Option 2 allows 80 MHz channel width for 5GHz AP mode, such as when +# you are using hostapd. +# +# ----- +# +# Power options ( rtw_power_mgnt ) +# +# 0 = Disable power saving +# 1 = Power saving on, minPS (default) +# 2 = Power saving on, maxPS (not recommended for AP mode) +# +# ----- +# +# Beamforming options ( rtw_beamform_cap ) +# +# 0 = Disable (default) +# 1 = SU Beamformer +# 2 = SU Beamformee +# 10= SU Beamformee and MU Beamformee +# +# Note: MU Beamformer is not supported. +# +# ----- +# +# Country Code options ( rtw_country_code ) +# +# Note: Allows the Country Code to be set in cases where it is unable to +# be obtained from the operating system. +# +# Example for the US: rtw_country_code=US +# Example for Panama: rtw_country_code=PA +# Example for Norway: rtw_country_code=NO +# Example for Kuwait: rtw_country_code=KW +# Example for Taiwan: rtw_country_code=TW +# +# ----- +# +# DFS Options ( rtw_dfs_region_domain ) +# +# 0 = NONE (default) +# 1 = FCC +# 2 = MKK +# 3 = ETSI +# +# Notes: +# - Activates DFS channels in AP mode. +# - DFS FCC 80 MHz channels for hostapd: 52(58), 100(106), 116(122) and 132(138) +# - For more information: https://en.wikipedia.org/wiki/List_of_WLAN_channels +# +# Note: An AP needs to listen on a DFS channel for a period of 60 seconds +# before transmitting on the channel. If any radar pulses are detected, +# the AP cannot use that channel and will have to try a different channel. +# +# ----- +# +# Select P2P interface in concurrent mode ( rtw_sel_p2p_iface ) +# +# 0 = Sets interface 0 to be p2p interface +# 1 = Sets interface 1 to be p2p interface (default) +# +# ----- +# +# To see all options that are available: +# +# $ ls /sys/module/8821cu/parameters/ +# +# ----- +# +# To see the values that are in use: +# +# $ grep [[:alnum:]] /sys/module/8821cu/parameters/* +# +# ----- +# +# hostapd setup information for rtl8821cu +# Note: The best settings can vary but the following may be a good place to start. +# +# /etc/modprobe.d/8821cu.conf +# options 8821cu rtw_drv_log_level=0 rtw_led_ctrl=0 rtw_vht_enable=2 rtw_power_mgnt=1 rtw_beamform_cap=0 rtw_dfs_region_domain=1 +# +# Note: The best setting for `rtw_dfs_region_domain=` will depend on your location. +# +# /etc/hostapd/hostapd.conf +# +# hw ht capab: 0x862 +# ht_capab=[HT40+][HT40-][SHORT-GI-20][SHORT-GI-40][MAX-AMSDU-7935] +# +# hw vht capab: 0x03c00022 +# vht_capab=[MAX-MPDU-11454][SHORT-GI-80][HTC-VHT][MAX-A-MPDU-LEN-EXP7] +# +# ----- + + + + + diff --git a/projects/ArchR/packages/linux-drivers/RTL8821CU/package.mk b/projects/ArchR/packages/linux-drivers/RTL8821CU/package.mk new file mode 100644 index 0000000000..e5cd746cd5 --- /dev/null +++ b/projects/ArchR/packages/linux-drivers/RTL8821CU/package.mk @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="RTL8821CU" +PKG_VERSION="3d1fcf4bc838542ceb03b0b4e9e40600720cf6ae" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/morrownr/8821cu-20210916" +PKG_URL="${PKG_SITE}.git" +PKG_LONGDESC="Realtek 8821CU driver for 4.4-5.x" +PKG_TOOLCHAIN="make" +PKG_IS_KERNEL_PKG="yes" + +pre_make_target() { + unset LDFLAGS +} + +make_target() { + make V=1 \ + ARCH=${TARGET_KERNEL_ARCH} \ + KSRC=$(kernel_path) \ + CROSS_COMPILE=${TARGET_KERNEL_PREFIX} \ + CONFIG_POWER_SAVING=y +} + +makeinstall_target() { + mkdir -p ${INSTALL}/$(get_full_module_dir)/kernel/drivers/net/wireless/ + cp *.ko ${INSTALL}/$(get_full_module_dir)/kernel/drivers/net/wireless/ +} diff --git a/projects/ArchR/packages/linux-drivers/RTL8821CU/patches/001-fix_btcoex.patch b/projects/ArchR/packages/linux-drivers/RTL8821CU/patches/001-fix_btcoex.patch new file mode 100644 index 0000000000..3862fe411b --- /dev/null +++ b/projects/ArchR/packages/linux-drivers/RTL8821CU/patches/001-fix_btcoex.patch @@ -0,0 +1,22 @@ +diff --git a/hal/rtl8821c/rtl8821c_ops.c b/hal/rtl8821c/rtl8821c_ops.c +index 7461142..fffd472 100755 +--- a/hal/rtl8821c/rtl8821c_ops.c ++++ b/hal/rtl8821c/rtl8821c_ops.c +@@ -524,7 +524,7 @@ u8 rtl8821c_read_efuse(PADAPTER adapter) + + if (hal_read_mac_hidden_rpt(adapter) != _SUCCESS) + goto exit; +- { ++ /*{ + struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); + + if (hal_spec->hci_type <= 3 && hal_spec->hci_type >= 1) { +@@ -532,7 +532,7 @@ u8 rtl8821c_read_efuse(PADAPTER adapter) + RTW_INFO("EEPROM Disable BT-coex by hal_spec\n"); + rtw_btcoex_wifionly_AntInfoSetting(adapter); + } +- } ++ }*/ + + rtw_phydm_read_efuse(adapter); + diff --git a/projects/ArchR/packages/linux-drivers/RTL8851BU/package.mk b/projects/ArchR/packages/linux-drivers/RTL8851BU/package.mk new file mode 100644 index 0000000000..72f13ed181 --- /dev/null +++ b/projects/ArchR/packages/linux-drivers/RTL8851BU/package.mk @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="RTL8851BU" +PKG_VERSION="f94ea820634d3bd050009e861952d3b8eeef869a" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/neatojones/RTL8851bu" +PKG_URL="${PKG_SITE}.git" +PKG_LONGDESC="Realtek 8851BU Linux driver" +PKG_TOOLCHAIN="make" +PKG_IS_KERNEL_PKG="yes" + +pre_make_target() { + unset LDFLAGS +} + +make_target() { + make V=1 \ + ARCH=${TARGET_KERNEL_ARCH} \ + KSRC=$(kernel_path) \ + CROSS_COMPILE=${TARGET_KERNEL_PREFIX} \ + CONFIG_RTW_DEBUG=n +} + +makeinstall_target() { + mkdir -p ${INSTALL}/$(get_full_module_dir)/kernel/drivers/net/wireless/ + cp *.ko ${INSTALL}/$(get_full_module_dir)/kernel/drivers/net/wireless/ +} diff --git a/projects/ArchR/packages/linux-drivers/RTL8851BU/patches/001-fix-building-on-6-12.patch b/projects/ArchR/packages/linux-drivers/RTL8851BU/patches/001-fix-building-on-6-12.patch new file mode 100644 index 0000000000..7840acffb9 --- /dev/null +++ b/projects/ArchR/packages/linux-drivers/RTL8851BU/patches/001-fix-building-on-6-12.patch @@ -0,0 +1,21 @@ +--- a/Makefile ++++ b/Makefile +@@ -14,6 +14,7 @@ + #EXTRA_CFLAGS += -Wno-unused-function + EXTRA_CFLAGS += -Wno-unused + #EXTRA_CFLAGS += -Wno-uninitialized ++EXTRA_CFLAGS += -w + + ############ ANDROID COMMON KERNEL ############ + # clang +--- a/os_dep/linux/ioctl_cfg80211.h ++++ b/os_dep/linux/ioctl_cfg80211.h +@@ -90,7 +90,7 @@ + + #if defined(CONFIG_DFS_MASTER) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)) + #ifndef CONFIG_RTW_CFG80211_CAC_EVENT +-#define CONFIG_RTW_CFG80211_CAC_EVENT 1 ++#define CONFIG_RTW_CFG80211_CAC_EVENT 0 + #endif + #else + #ifdef CONFIG_RTW_CFG80211_CAC_EVENT diff --git a/projects/ArchR/packages/linux-drivers/RTL88x2BU/modprobe.d/8812bu.conf b/projects/ArchR/packages/linux-drivers/RTL88x2BU/modprobe.d/8812bu.conf new file mode 100644 index 0000000000..aadea8748a --- /dev/null +++ b/projects/ArchR/packages/linux-drivers/RTL88x2BU/modprobe.d/8812bu.conf @@ -0,0 +1 @@ +options 88x2bu rtw_power_mgnt=0 rtw_ips_mode=0 rtw_enusbss=0 diff --git a/projects/ArchR/packages/linux-drivers/RTL88x2BU/package.mk b/projects/ArchR/packages/linux-drivers/RTL88x2BU/package.mk new file mode 100644 index 0000000000..80857d711c --- /dev/null +++ b/projects/ArchR/packages/linux-drivers/RTL88x2BU/package.mk @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="RTL88x2BU" +PKG_VERSION="6e4c5ccfd6607e9f4b1c1befd165ce56e7d6a653" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/morrownr/88x2bu-20210702" +PKG_URL="${PKG_SITE}.git" +PKG_LONGDESC="Realtek 88x2BU driver for 4.4-5.x" +PKG_TOOLCHAIN="make" +PKG_IS_KERNEL_PKG="yes" + +pre_make_target() { + unset LDFLAGS +} + +make_target() { + make V=1 \ + ARCH=${TARGET_KERNEL_ARCH} \ + KSRC=$(kernel_path) \ + CROSS_COMPILE=${TARGET_KERNEL_PREFIX} \ + CONFIG_POWER_SAVING=y +} + +makeinstall_target() { + mkdir -p ${INSTALL}/$(get_full_module_dir)/kernel/drivers/net/wireless/ + cp *.ko ${INSTALL}/$(get_full_module_dir)/kernel/drivers/net/wireless/ +} diff --git a/projects/ArchR/packages/linux-drivers/RTW88/package.mk b/projects/ArchR/packages/linux-drivers/RTW88/package.mk new file mode 100644 index 0000000000..0747f77813 --- /dev/null +++ b/projects/ArchR/packages/linux-drivers/RTW88/package.mk @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="RTW88" +PKG_VERSION="9bc8fecb61d4ad59e46b4dbd003d60ef2d8437a8" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/lwfinger/rtw88" +PKG_URL="https://github.com/lwfinger/rtw88/archive/${PKG_VERSION}.tar.gz" +PKG_LONGDESC="RTW88 downstream driver" +PKG_TOOLCHAIN="make" +PKG_IS_KERNEL_PKG="yes" + +pre_make_target() { + unset LDFLAGS +} + +make_target() { + make V=1 \ + ARCH=${TARGET_KERNEL_ARCH} \ + KSRC=$(kernel_path) \ + CROSS_COMPILE=${TARGET_KERNEL_PREFIX} \ + CONFIG_POWER_SAVING=y +} + +makeinstall_target() { + mkdir -p ${INSTALL}/$(get_full_module_dir)/kernel/drivers/net/wireless + cp *.ko ${INSTALL}/$(get_full_module_dir)/kernel/drivers/net/wireless +} diff --git a/projects/ArchR/packages/linux-drivers/archr-joypad/package.mk b/projects/ArchR/packages/linux-drivers/archr-joypad/package.mk new file mode 100644 index 0000000000..7053f25f11 --- /dev/null +++ b/projects/ArchR/packages/linux-drivers/archr-joypad/package.mk @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="archr-joypad" +PKG_VERSION="7647fdb0fc89cd69b284903bf7707e861df5dc7e" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/archr-linux/archr-joypad" +PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz" +PKG_LONGDESC="archr-joypad: ArchR joypad driver" +PKG_TOOLCHAIN="manual" +PKG_IS_KERNEL_PKG="yes" + +pre_make_target() { + unset LDFLAGS +} + +make_target() { + kernel_make -C $(kernel_path) M=${PKG_BUILD} +} + +makeinstall_target() { + mkdir -p ${INSTALL}/$(get_full_module_dir)/${PKG_NAME} + cp *.ko ${INSTALL}/$(get_full_module_dir)/${PKG_NAME} +} diff --git a/projects/ArchR/packages/linux-drivers/dtbocfg/package.mk b/projects/ArchR/packages/linux-drivers/dtbocfg/package.mk new file mode 100644 index 0000000000..070942c4ee --- /dev/null +++ b/projects/ArchR/packages/linux-drivers/dtbocfg/package.mk @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="dtbocfg" +PKG_VERSION="0.1.0" +PKG_LICENSE="BSD" +PKG_SITE="https://github.com/ikwzm/dtbocfg" +PKG_URL="${PKG_SITE}/archive/refs/tags/v${PKG_VERSION}.tar.gz" +PKG_LONGDESC="Device Tree Blob Overlay Configuration File System" +PKG_DEPENDS_TARGET="toolchain linux" +PKG_NEED_UNPACK="${LINUX_DEPENDS}" +PKG_TOOLCHAIN="manual" +PKG_IS_KERNEL_PKG="yes" + +make_target() { + kernel_make KERNEL_SRC=$(kernel_path) -C ${PKG_BUILD} +} + +makeinstall_target() { + mkdir -p ${INSTALL}/$(get_full_module_dir)/${PKG_NAME} + cp dtbocfg.ko ${INSTALL}/$(get_full_module_dir)/${PKG_NAME}/ +} diff --git a/projects/ArchR/packages/linux-drivers/generic-dsi/package.mk b/projects/ArchR/packages/linux-drivers/generic-dsi/package.mk new file mode 100644 index 0000000000..378cdac938 --- /dev/null +++ b/projects/ArchR/packages/linux-drivers/generic-dsi/package.mk @@ -0,0 +1,47 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 ArchR (https://github.com/archr-linux/Arch-R) + +PKG_NAME="generic-dsi" +PKG_VERSION="de7b15ea0668d6fcc07c9b7a6bf20adf34c9d6de" +PKG_LICENSE="GPL" +PKG_LONGDESC="generic DSI panel driver and stock DTB import scripts" +PKG_DEPENDS_TARGET="pyFDT" +PKG_URL="https://github.com/stolen/overlay_server/archive/${PKG_VERSION}.zip" +PKG_TOOLCHAIN="manual" + +unpack() { + mkdir -p "${PKG_BUILD}" + cd "${PKG_BUILD}" + unzip "${SOURCES}/${PKG_NAME}/${PKG_SOURCE_NAME}" +} + +### For development. Easier to check if code compiles and works. +### No need for a long build-transfer-reboot-wait-reboot-check loop +make_target() { + if [ "${I_AM_DEVELOPER}" == "yes" ]; then + # rename the driver to not conflict with built-in one + sed 's|define DRIVER_NAME .*$|define DRIVER_NAME "panel-generic-dsi-test"|' panel-generic-dsi.c > panel-generic-dsi-test.c + echo 'obj-m += panel-generic-dsi-test.o' > ${PKG_BUILD}/Makefile + kernel_make -C $(kernel_path) M=${PKG_BUILD} + fi +} + +makeinstall_target() { + mkdir -p "${INSTALL}/usr/libexec/generic-dsi" + # dtbo.py is a better script handling not just panel, but also joypad, headphones, etc. + cp -v "${PKG_BUILD}/"overlay_server*"/rocknix_dtbo.py" "${INSTALL}/usr/libexec/generic-dsi/archr_dtbo.py" + # importpanel.py still here because it's simple, documented in wiki and performs just one task well + cp -v "${PKG_DIR}/scripts/importpanel.py" "${INSTALL}/usr/libexec/generic-dsi/" +} + + +### For possible future use. The driver can use files in /lib/firmware to initialize a panel, +### thus no need in dtbo, just parameter in cmdline (if base dtb already uses generic driver) +make_init() { + : +} + +makeinstall_init() { + mkdir -p ${INSTALL}/lib + cp -av ${PKG_DIR}/firmware ${INSTALL}/lib/ +} diff --git a/projects/ArchR/packages/linux-drivers/generic-dsi/scripts/importpanel.py b/projects/ArchR/packages/linux-drivers/generic-dsi/scripts/importpanel.py new file mode 100755 index 0000000000..2de3e79aef --- /dev/null +++ b/projects/ArchR/packages/linux-drivers/generic-dsi/scripts/importpanel.py @@ -0,0 +1,274 @@ +#!/usr/bin/env python + +# https://pypi.org/project/fdt/ +# pip install fdt + +import sys, argparse +import fdt +import math + +parser = argparse.ArgumentParser(description="Extract MIPI panel description from stock dtb to use with panel-mipi-generic driver") +parser.add_argument("-n", "--name", help="human readable panel name") +parser.add_argument("-O", "--out-format", help="output format", choices=['dts', 'dtbo', 'pdesc'], default='pdesc', dest='outfmt') +parser.add_argument("-o", "--out", help="output file") +parser.add_argument("-D", "--diagonal", help="panel size (diagonal), inches; used to calculate physical size when dtb lacks it", type=float) +parser.add_argument(metavar="/path/to/vendor.dtb", dest="source_dtb", help="dtb file from stock firmware") +args = parser.parse_args() +comment = (args.outfmt == 'pdesc') + +with open(args.source_dtb, "rb") as f: + dtb_data = f.read() + +acc = [] + +g_name = f"name='{args.name}' " if args.name else "" + +dt = fdt.parse_dtb(dtb_data) +for target in ["dsi@ff450000/panel@0", "dsi@fe060000/panel@0"]: + try: + panel = dt.get_node(target) + break + except: + pass + + +def prop_default(prop, default): + try: + return panel.get_property(prop).value + except: + return default + +delays = [ + prop_default("prepare-delay-ms", 50), + prop_default("reset-delay-ms", 50), + prop_default("init-delay-ms", 50), + prop_default("enable-delay-ms", 50), + 20 # ready -- no such timeout in legacy dtbs + ] +delays_str = ','.join(map(str, delays)) + +fmt = ['rgb888', 'rgb666', 'rgb666_packed', 'rgb565'] [panel.get_property("dsi,format").value] +lanes = panel.get_property("dsi,lanes").value +flags = panel.get_property("dsi,flags").value +flags |= 0x0400 + + +timings = panel.get_subnode("display-timings") +native = timings.get_property("native-mode").value + +# Collect vendor modes +modes = {} +orig_def_fps = None +for m in timings.nodes: + clock = round(m.get_property("clock-frequency").value/1000) + hor = [ + m.get_property("hactive").value, + m.get_property("hfront-porch").value, + m.get_property("hsync-len").value, + m.get_property("hback-porch").value, + ] + ver = [ + m.get_property("vactive").value, + m.get_property("vfront-porch").value, + m.get_property("vsync-len").value, + m.get_property("vback-porch").value, + ] + + mode = {'clock': clock, 'hor': hor, 'ver': ver} + if (m.get_property("phandle").value == native): + mode['default'] = True + + htotal = sum(hor) + vtotal = sum(ver) + fps = clock*1000/(htotal*vtotal) + + if fps not in modes: + modes[fps] = mode + if (m.get_property("phandle").value == native): + modes[fps]['default'] = True + orig_def_fps = fps + + +try: + w = panel.get_property("width-mm").value + h = panel.get_property("height-mm").value +except: + if not args.diagonal: + sys.stderr.buffer.write(b'width-mm or height-mm not set, specify diagonal with -D option\n') + exit(1) + randmode = list(modes.values())[0] + hactive = randmode['hor'][0] + vactive = randmode['ver'][0] + pxdiag = math.sqrt(hactive*hactive + vactive*vactive) + diag_mm = args.diagonal * 25.4 + w = round(diag_mm * hactive/pxdiag) + h = round(diag_mm * vactive/pxdiag) + +# G size=52,70 delays=2,1,20,120,50,20 format=rgb888 lanes=4 flags=0xe03 +acc += [f"G {g_name}size={w},{h} delays={delays_str} format={fmt} lanes={lanes} flags=0x{flags:x}", ""] + +def absfrac(x): + return abs(x - round(x)) + +# Based on vendor modes construct a better set of modes +# https://tasvideos.org/PlatformFramerates +# 50, 60 -- generic +# */1.001 -- NTSC hack with 1001 divisor +# 50.0070 -- PAL NES https://www.nesdev.org/wiki/Cycle_reference_chart +# 60.0988 -- NTSC NES +# 54.8766 -- src/mame/toaplan/twincobr.cpp +# 57.5 -- src/mame/kaneko/snowbros.cpp +# 59.7275 -- https://en.wikipedia.org/wiki/Game_Boy +# 75.47 -- https://ws.nesdev.org/wiki/Display +def_fps = 60 +if orig_def_fps: + def_fps = orig_def_fps +common_fpss = [50/1.001, 50, 50.0070, 57.5, 59.7275, 60/1.001, 60, 60.0988, 75.47, 90, 120]; +common_fpss = [ fps for fps in common_fpss if fps != orig_def_fps] +for targetfps in [orig_def_fps] + common_fpss: + if not targetfps: + continue + warn = "" + # nearest fps to base on + greaterfps = [fps for fps in modes.keys() if fps >= targetfps] + if greaterfps == []: + basefps = max(modes.keys()) + basemode = modes[basefps] + clock = None + else: + # Trust original clock. If real clock differs, maybe make a whitelist or blacklist here + basefps = min(greaterfps) + basemode = modes[basefps] + clock = basemode['clock'] + hor = basemode['hor'].copy() + ver = basemode['ver'].copy() + # Assume original totals are minimal for the panel at this clock + htotal = sum(hor) + vtotal = sum(ver) + perfectclock = targetfps*htotal*vtotal/1000 + if not clock: + warn = "(CAN FAIL) " + # This may fail, but worth trying. Round up to 10kHz + clock = math.ceil(perfectclock/10)*10 + elif clock > 1.25*perfectclock: + # Too much deviation may cause no image + clock = math.ceil(perfectclock/10)*10 + + maxvtotal = round(vtotal*1.25) + # A little bruteforce to find a best totals for target fps + # TODO: maybe iterate over some clock values too + options = [(absfrac(c*1000/targetfps/vt), c, vt) + for vt in range(vtotal, maxvtotal+1) + for c in range(clock, round(1.25*perfectclock), 10) + if ((c*1000/targetfps/vt) >= htotal) and ((c*1000/targetfps/vt) < htotal*1.05) ] + if options == []: + acc += [f"# failed to find mode for fps={targetfps:.6f} c={clock} h={htotal} v={vtotal}"] + continue + (mindev, newclock, newvtotal) = min(options) + # construct a new mode with chosen vtotal + newhtotal = round(newclock*1000/targetfps/newvtotal) + addhtotal = newhtotal - htotal + addvtotal = newvtotal - vtotal + expectedfps = newclock*1000/newvtotal/newhtotal + hor[2] += addhtotal + ver[2] += addvtotal + hor_str = ','.join(map(str, hor)) + ver_str = ','.join(map(str, ver)) + maybe_default = " default=1" if targetfps == def_fps else "" + maybe_comment = f" # {warn}fps={expectedfps:.6f} (target={targetfps:.6f})" if comment else "" + acc += [f"M clock={newclock} horizontal={hor_str} vertical={ver_str}{maybe_default}{maybe_comment}"] + +acc += [""] + +iseq0 = panel.get_property("panel-init-sequence") +if (hasattr(iseq0, 'value')) and (isinstance(iseq0.value, (int))): + iseq = b''.join(map(lambda w : w.to_bytes(4, "big"), list(iseq0))) +else: + iseq = bytearray(iseq0) + +while iseq: + cmd = iseq[0] + wait = iseq[1] + datalen = iseq[2] + iseq = iseq[3:] + + data = iseq[0:datalen] + iseq = iseq[datalen:] + + maybe_wait = f" wait={wait}" if (wait) else "" + maybe_comment = f" # orig_cmd=0x{cmd:x}" if comment else "" + acc += [f"I seq={data.hex()}{maybe_wait}{maybe_comment}"] + + +# pre-formatted dts parts +dts_header = f"""/dts-v1/; +// version: 17 +// last_comp_version: 16 + +/ {{ + fragment@0 {{ + target-path = "/{target}"; + __overlay__ {{ + compatible = "archr,generic-dsi"; + panel_description =""" +dts_footer = """; + }; + }; +}; +""" + +# choose where to output +if args.out: + f = open(args.out, "wb") +else: + f = sys.stdout.buffer + +# Helper for short cmd grouping +def cmd_prefix(line): + if len(line) != 10: + return None + if line[0:6] != 'I seq=': + return None + # "I seq=0320" -> "0l" + return line[6:7] + ('l' if line[7] < '8' else 'H') + +if args.outfmt == 'dts': + # For fancy multi-line format we do not use fdt.FDT.to_dts(), but craft custom dts + f.write(dts_header.encode()) + prevpfx = None; + nocomma = True + for l in acc: + comma = '' if nocomma else ',' + + curpfx = cmd_prefix(l) + if curpfx and curpfx == prevpfx: + delimiter = ' ' + else: + delimiter = '\n ' + prevpfx = curpfx + + if l == '': + f.write((comma + '\n').encode()) + nocomma = True + else: + f.write((comma + delimiter + '"' + l + '"').encode()) + nocomma = False + + f.write(dts_footer.encode()) +elif args.outfmt == 'dtbo': + # remove empty lines as pyfdt does not like them + acc = [ l for l in acc if l != ''] + # create an overlay tree + overlay = fdt.FDT() + overlay.header.version = 17 + overlay.set_property('target-path', '/'+target, path='fragment@0') + overlay.set_property('compatible', 'archr,generic-dsi', path='fragment@0/__overlay__') + overlay.set_property('panel_description', acc, path='fragment@0/__overlay__') + # send the overlay to output + f.write(overlay.to_dtb()) +else: + for l in acc: + f.write((l + "\n").encode()) + +if args.out: + f.close() diff --git a/projects/ArchR/packages/linux-drivers/generic-dsi/sources/panel-generic-dsi.c b/projects/ArchR/packages/linux-drivers/generic-dsi/sources/panel-generic-dsi.c new file mode 100644 index 0000000000..e22c13384a --- /dev/null +++ b/projects/ArchR/packages/linux-drivers/generic-dsi/sources/panel-generic-dsi.c @@ -0,0 +1,689 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Generic MIPI-DSI panel driver + * Copyright (C) 2024 ArchR + * + * based on + * + * Rockteck jh057n00900 5.5" MIPI-DSI panel driver + * Copyright (C) Purism SPC 2019 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include